diff --git a/.gitee/ISSUE_TEMPLATE/001_bug_report.yml b/.gitee/ISSUE_TEMPLATE/001_bug_report.yml new file mode 100644 index 0000000000000000000000000000000000000000..7107bc233c838b0738b53c3960912b09710fc480 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE/001_bug_report.yml @@ -0,0 +1,40 @@ +name: 缺陷反馈 | Bug +description: 当您发现了一个缺陷,需要向社区反馈时,请使用此模板。 +title: "[BUG] <标题>" +labels: [👀 needs triage, "Type: Bug"] +body: + - type: markdown + attributes: + value: | + 感谢您对 openvela 社区的支持与关注,欢迎反馈缺陷。 + + - type: textarea + attributes: + label: "重现问题的步骤" + description: "简洁地描述错误是什么,为什么您认为它是一个错误,以及如何重现它的步骤" + placeholder: | + 重现问题的步骤,可能包括日志和截图。 + 1. 步骤 1 + 2. 步骤 2 + validations: + required: true + + - type: dropdown + id: architecture + attributes: + label: Issue Architecture + multiple: true + options: + - "Arch: arm" + - "Arch: arm64" + - "Arch: x86_64" + validations: + required: true + + - type: markdown + attributes: + value: | + 提交前请确认您已遵循以下步骤: + - 确认问题在 [**dev**](../) 上可重现。 + - 遇到构建问题时运行 `make distclean`。 + - 搜索 [现有问题](./) diff --git a/.gitee/ISSUE_TEMPLATE/002_feature_request.yml b/.gitee/ISSUE_TEMPLATE/002_feature_request.yml new file mode 100644 index 0000000000000000000000000000000000000000..8b500152e7f080e30baa628bdc8c079b93be3d25 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE/002_feature_request.yml @@ -0,0 +1,34 @@ +name: 新需求 | Feature +description: 当您需要反馈或实现一个新需求时,使用此模板。 +title: "[FEATURE] <标题>" +body: + - type: markdown + attributes: + value: | + 感谢您对 openvela 社区的支持与关注。 + + - type: textarea + id: question-description + attributes: + label: 您的需求是否和问题相关? + description: 请简单描述问题,并提供issue链接。 + validations: + required: true + + - type: textarea + id: solution + attributes: + label: 请描述您想要的解决方案 + validations: + required: true + + - type: textarea + id: 替代方案 + attributes: + label: 请描述您考虑过的替代解决方案 + + - type: markdown + attributes: + value: | + 提交前请搜索 [现有功能需求](./) + diff --git a/.gitee/ISSUE_TEMPLATE/003_help.yml b/.gitee/ISSUE_TEMPLATE/003_help.yml new file mode 100644 index 0000000000000000000000000000000000000000..bde95adf3d07da0e687eef3d960a10b26b2a97a9 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE/003_help.yml @@ -0,0 +1,22 @@ +name: 问题咨询 +title: "[问题咨询]" +body: + - type: markdown + attributes: + value: | + 感谢您对 openvela 社区的支持与关注。 + + - type: textarea + id: question-description + attributes: + label: 描述 + description: 请解释您的问题的背景或上下文,这有助于其他人更好地理解您的问题或疑问。 + validations: + required: true + + - type: markdown + attributes: + value: | + 提交前请确认您已遵循以下步骤: + - 我已搜索 [openvela 文档](../),但未找到问题的答案。 + - 已搜索 [现有问题](./) diff --git a/.gitee/ISSUE_TEMPLATE/config.yml b/.gitee/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..3ba13e0cec6cbbfd462e9ebf529dd2093148cd69 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.gitee/PULL_REQUEST_TEMPLATE.md b/.gitee/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..cd8b2bc3a7690b37298e12d71c7b12189d26fae8 --- /dev/null +++ b/.gitee/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## 概要 + +*在此部分更新信息,说明更改的必要性、具体做了什么以及如何实现的,如果有新功能出现,请提供参考资料(依赖关系、类似问题和解决方案等)。* + +## 影响 + +*在此部分更新信息(如适用),说明更改如何影响用户、构建过程、硬件、文档、安全性、兼容性等。* + +## 测试 + +*在此部分更新信息,详细说明如何验证更改,使用什么主机进行构建(操作系统、CPU、编译器等),使用什么目标进行验证(架构、板子:配置等)。提供更改前后的构建和运行日志将非常有帮助。* \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000000000000000000000000000000000..99ea0de3c436dbab51e3599c804dfc16aa373762 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @xiaoxiang781216 @GUIDINGLI @terry0012 @jianglianfang diff --git a/.github/ISSUE_TEMPLATE/001_bug_report.yml b/.github/ISSUE_TEMPLATE/001_bug_report.yml new file mode 100644 index 0000000000000000000000000000000000000000..48e823db004f97019d883d13fd419084b650b4df --- /dev/null +++ b/.github/ISSUE_TEMPLATE/001_bug_report.yml @@ -0,0 +1,60 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +name: Bug report +description: Report a bug to improve openvela stability +title: "[BUG] " +labels: [👀 needs triage, "Type: Bug"] +body: + - type: markdown + attributes: + value: | + Hello openvela Community member! Please keep things tidy by putting your post in the proper place: + + Reporting a bug: use this form. + Asking a question or getting help: use the [General Help](./new?assignees=&labels=Community%3A+Question&projects=&template=003_help.yml&title=%5BHELP%5D+%3Ctitle%3E) form. + Requesting a new feature: use the [Feature request](./new?assignees=&labels=Type%3A+Enhancement&projects=&template=002_feature_request.yml&title=%5BFEATURE%5D+%3Ctitle%3E) form. + - type: textarea + attributes: + label: "Description / Steps to reproduce the issue" + description: "A clear and concise description of what the bug is, and why you consider it to be a bug, and steps for how to reproduce it" + placeholder: | + A description with steps to reproduce the issue. + May include logs, images, or videos. + 1. Step 1 + 2. Step 2 + validations: + required: true + + - type: dropdown + id: architecture + attributes: + label: Issue Architecture + description: What architecture(s) are you seeing the problem on? + multiple: true + options: + - "[Arch: arm]" + - "[Arch: arm64]" + - "[Arch: x86_64]" + validations: + required: true + + - type: markdown + attributes: + value: | + ### Before You Submit + + Please verify that you've followed these steps: + - Confirm the problem is reproducible on [**dev**](../). + - Run `make distclean` when encountering build issues. + - Search [existing issues](./) (including [closed](./?q=is%3Aissue+is%3Aclosed)) + diff --git a/.github/ISSUE_TEMPLATE/002_feature_request.yml b/.github/ISSUE_TEMPLATE/002_feature_request.yml new file mode 100644 index 0000000000000000000000000000000000000000..d5f410895687730a42836aa65c321c13e59100c5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/002_feature_request.yml @@ -0,0 +1,55 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +name: Feature request +description: Request an enhancement for openvela +title: "[FEATURE] <title>" +labels: ["Type: Enhancement"] +body: + - type: markdown + attributes: + value: | + Hello openvela Community member! Please keep things tidy by putting your post in the proper place: + + Requesting a new feature: use this form. + Asking a question or getting help: use the [General Help](./new?assignees=&labels=Community%3A+Question&projects=&template=003_help.yml&title=%5BHELP%5D+%3Ctitle%3E) form. + Reporting a bug: use the [Bug report](./new?assignees=&labels=%F0%9F%91%80+needs+triage%2CType%3A+Bug&projects=&template=001_bug_report.yml&title=%5BBUG%5D+%3Ctitle%3E) form. + + - type: textarea + id: question-description + attributes: + label: Is your feature request related to a problem? Please describe. + description: Please provide a clear and concise description of what the problem is. Add relevant issue link. + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Describe the solution you'd like + description: Please provide a clear and concise description of what you want to happen. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you've considered + description: Please provide a clear and concise description of any alternative solutions or features you've considered. + + - type: markdown + attributes: + value: | + ### Before You Submit + + Please verify that you've followed these steps: + - Search [existing feature requests](./) (including [closed](./?q=is%3Aissue+is%3Aclosed)) diff --git a/.github/ISSUE_TEMPLATE/003_help.yml b/.github/ISSUE_TEMPLATE/003_help.yml new file mode 100644 index 0000000000000000000000000000000000000000..ff1e1bf627ad1674eef3a4e20ed808e416beb0ec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/003_help.yml @@ -0,0 +1,47 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +name: General Help +description: Get general support regarding openvela +title: "[HELP] <title>" +labels: ["Community: Question"] +body: + - type: markdown + attributes: + value: | + Hello openvela Community member! Please keep things tidy by putting your post in the proper place: + + Asking a question or getting help: use this form. + Reporting a bug: use the [Bug report](./new?assignees=&labels=%F0%9F%91%80+needs+triage%2CType%3A+Bug&projects=&template=001_bug_report.yml&title=%5BBUG%5D+%3Ctitle%3E) form. + Requesting a new feature: use the [Feature request](./new?assignees=&labels=Type%3A+Enhancement&projects=&template=002_feature_request.yml&title=%5BFEATURE%5D+%3Ctitle%3E) form + + - type: markdown + attributes: + value: | + ### Whether you're a beginner or an experienced developer, openvela Help is here to assist you with all your openvela questions and concerns. + + - type: textarea + id: question-description + attributes: + label: Description + description: Explain the background or context of your question. This helps others understand your problem or inquiry better. + validations: + required: true + + - type: markdown + attributes: + value: | + ### Before You Submit + + Please verify that you've followed these steps: + - I have searched [openvela Documentation](../) and didn't find an answer to my question. + - Search [existing issues](./) (including [closed](./?q=is%3Aissue+is%3Aclosed)) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..3ba13e0cec6cbbfd462e9ebf529dd2093148cd69 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000000000000000000000000000000000..cfe55eb61d3334245c04325ee92abc7fdd1ebc07 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,20 @@ +*Note: Please adhere to [Contributing Guidelines](https://github.com/open-vela/docs/blob/dev/CONTRIBUTING.md).* + +## Summary + +*Update this section with information on why change is necessary, + what it exactly does and how, if new feature shows up, provide + references (dependencies, similar problems and solutions), etc.* + +## Impact + +*Update this section, where applicable, on how change affects users, + build process, hardware, documentation, security, compatibility, etc.* + +## Testing + +*Update this section with details on how did you verify the change, + what Host was used for build (OS, CPU, compiler, ..), what Target was + used for verification (arch, board:config, ..), etc. Providing build + and runtime logs from before and after change is highly appreciated.* + diff --git a/.github/workflows/checkpatch.yml b/.github/workflows/checkpatch.yml new file mode 100644 index 0000000000000000000000000000000000000000..1cfe702b8cccf06491eaeef1267b63eb1cfbbdd6 --- /dev/null +++ b/.github/workflows/checkpatch.yml @@ -0,0 +1,14 @@ +# This is a basic workflow to help you get started with Actions + +name: checkpatch + +# Controls when the workflow will run +on: + pull_request: + types: [opened, reopened, synchronize] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + checkpatch: + uses: open-vela/public-actions/.github/workflows/checkpatch.yml@dev + secrets: inherit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..75b6797a9cd6459908bccdb8f514677a3cd48207 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,14 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the workflow will run +on: + pull_request_target: + types: [opened, reopened, synchronize] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + ci: + uses: open-vela/public-actions/.github/workflows/ci.yml@dev + secrets: inherit diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000000000000000000000000000000000..95183d91cbbf10895cd8656388e75020ac95fa7c --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,11 @@ +name: 'Close stale issues and PR' +on: + schedule: + - cron: '30 1 * * *' + workflow_dispatch: # 允许手动触发 + +jobs: + stale: + uses: open-vela/public-actions/.github/workflows/stale.yml@dev + secrets: inherit + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a52a2693e9c604f6b374e62d2948a313bb78f9e1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +.built +.depend +.kconfig +/Kconfig +Make.dep \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..bbe81b91d4736f0e27422b1f19acdd99606d3161 --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +Copyright (C) 2024 Xiaomi Corporation +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Make.defs b/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..5ea525a1ca8d0611085a3bc2aaff928a3183f569 --- /dev/null +++ b/Make.defs @@ -0,0 +1,36 @@ +############################################################################ +# packages/Make.defs +# Adds selected frameworks to apps/ build +# +# Copyright (C) 2019 Xiaomi Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +include $(wildcard $(APPDIR)/packages/demos/*/Make.defs) \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..949c23fb3090746f69b966fd700eb2984b31e320 --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +############################################################################ +# packages/Makefile +# +# Copyright (C) 2019 Xiaomi Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +MENUDESC = "Demos" + +include $(APPDIR)/Directory.mk diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d70508ff1c44a67c029ccadb90cde82da8376a9d --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Demo + +\[ English | [简体中文](README_zh-cn.md) \] + +## Overview + +This repository implements examples of openvela native application code. Developers can quickly get started with development based on our documentation and examples. + +## Usage Instructions + +- [Music Player](../../../docs/blob/dev/en/demo/Music_Player_Example.md) +- [Smart Band](../../../docs/blob/dev/en/demo/Smart_Band_Example.md) +- [Bicycle Computer](../../../docs/blob/dev/en/demo/X_Track.md) +- [Calculator](calculator/Readme.md) +- [Relation Calculator](relation_calculator/Readme.md) +- [Whackmole](Whackmole/README.md) +- [Music Player 2](music_player2/README-en.md) diff --git a/README_zh-cn.md b/README_zh-cn.md new file mode 100644 index 0000000000000000000000000000000000000000..e8d134624d892b99f67b1e4a3d1886db14790496 --- /dev/null +++ b/README_zh-cn.md @@ -0,0 +1,17 @@ +# Demo + +\[ [English](README.md) | 简体中文 \] + +## 简介 + +该仓库实现了 openvela native应用代码示例,开发者可以根据我们的文档和示例,快速上手开发。 + +## 使用说明 + +- [音乐播放器](../../../docs/blob/dev/zh-cn/demo/Music_Player_Example_zh-cn.md) +- [智能手环](../../../docs/blob/dev/zh-cn/demo/Smart_Band_Example_zh-cn.md) +- [自行车码表](../../../docs/blob/dev/zh-cn/demo/X_Track_zh-cn.md) +- [计算器](calculator/Readme.md) +- [亲戚计算器](relation_calculator/Readme.md) +- [打地鼠](Whackmole/README_zh-cn.md) +- [音乐播放器2](music_player2/README.md) diff --git a/Whackmole/Kconfig b/Whackmole/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..8b7413aadc0255907702b9001f5476b64c34a3f2 --- /dev/null +++ b/Whackmole/Kconfig @@ -0,0 +1,14 @@ + +config LVX_USE_DEMO_WHACKMOLE + bool "Whackmole" + default n + help + Enable the demo Whackmole application. + +if LVX_USE_DEMO_WHACKMOLE +config LVX_WHACKMOLE_DATA_ROOT + string "Whackmole Data Root" + default "/sdcard" + help + Specify the data storage path for the Whackmole application. +endif diff --git a/Whackmole/Make.defs b/Whackmole/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..f53ccdb4037e12345703ad8bfa3bcdf7c1c5208c --- /dev/null +++ b/Whackmole/Make.defs @@ -0,0 +1,4 @@ + # Make.defs +ifneq ($(CONFIG_LVX_USE_DEMO_WHACKMOLE),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/Whackmole +endif diff --git a/Whackmole/Makefile b/Whackmole/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9143db95c96d1afb70252c7f4164120114c67d5c --- /dev/null +++ b/Whackmole/Makefile @@ -0,0 +1,18 @@ +# Makefile + + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_WHACKMOLE), y) +PROGNAME = Whackmole +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_WHACKMOLE) +CSRCS = Whackmole.c pic/MiSans_Normal.c pic/grassland.c pic/hammer_image.c pic/mole_image.c + +MAINSRC = Whackmole_main.c +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/packages/demos/Whackmole/pic + +endif + +include $(APPDIR)/Application.mk diff --git a/Whackmole/README.md b/Whackmole/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3ecdf8bb33af9002a4a8dc4ef2ed0d3cae2d131e --- /dev/null +++ b/Whackmole/README.md @@ -0,0 +1,168 @@ +# Whack-a-Mole Demo Quick Start + +\[ English | [简体中文](./README_zh-cn.md) \] + +This document provides a detailed guide on how to build, deploy, and run the Whack-a-Mole demo application on the openvela system for both the QEMU emulator and the ESP32-S3-BOX development board. You will learn how to configure the project, compile the firmware, run the application, and customize game features. + +## I. Demonstration + +![img](img/whackmole.gif) + +## II. Build and Run + +This section guides you through the entire process, from project configuration to running the application on your target platform. + +### Prerequisites + +Before you begin, ensure you are in the root directory of the `openvela` repository. All commands in this document are executed from this location. + +### Step 1: Configure the Project + +You need to use the `menuconfig` utility to enable the Whack-a-Mole application and its related settings. + +1. Start `menuconfig`. Select the command corresponding to your target platform: + + - QEMU emulator: + + ```bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + + - ESP32-S3-BOX: + + ```bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 menuconfig + ``` + +2. In the `menuconfig` interface, press the `/` key to open the search function, then find and enable the following configuration options: + + ```kconfig + LVX_USE_DEMO_WHACKMOLE=y + LVX_WHACKMOLE_DATA_ROOT="/data" + ``` + +3. **(Optional)** If you experience UI lag or display issues at runtime, you can increase the cache size for LVGL (Light and Versatile Graphics Library). Search for `lv_cache_def_size` and set its value to `20000000`. + +4. Save the configuration and exit `menuconfig`. + +### Step 2: Compile the Project + +Before compilation, it is recommended to clean the previous build artifacts to prevent potential build errors. + +1. Clean build artifacts (distclean): + + - QEMU emulator: + + ```bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 + ``` + + - ESP32-S3-BOX: + + ```bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 distclean + ``` + +2. Execute the build: + + - QEMU emulator: + + ```bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 + ``` + + - ESP32-S3-BOX: + + ```bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 -j8 + ``` + +### Step 3: Deploy and Run + +After a successful compilation, you can deploy the firmware to the target platform and launch the application. + +#### Option A: Run on the QEMU Emulator + +1. From the `openvela` root directory, execute the following command to start the emulator: + + ```bash + ./emulator.sh vela + ``` + +2. After the openvela terminal (`openvela-ap>`) appears, enter the following command to start the game: + + ```bash + Whackmole + ``` + +#### Option B: Run on the ESP32-S3-BOX Board + +1. Flash the firmware: + + Ensure your ESP32-S3-BOX is connected to your computer via USB. Execute the following command to begin flashing. Replace `/dev/ttyACM0` with the actual serial port of your device. + + ```bash + pushd nuttx && make -j8 flash ESPTOOL_PORT=/dev/ttyACM0 ESPTOOL_BINDIR=./ && popd + ``` + +2. Open a serial monitor: + + Use `minicom` or another serial terminal tool to view the device output and interact with it. + + ```bash + sudo minicom -D /dev/ttyACM0 -b 115200 + ``` + +3. Start the game: + + In the `minicom` terminal, enter the following command: + + ```bash + Whackmole + ``` + +## III. Application Customization + +You can modify the core features of the game, such as replacing resources or adjusting the difficulty, to suit your needs. + +### Core File Structure + +- `Whackmole.c`: Contains the core game logic. All feature development and modifications should be done in this file. + +- `Whackmole_main.c`: Serves as the application entry point, responsible for creating and starting the openvela task that runs the game logic. You typically do not need to modify this file. + +### Modify Resource Images + +The image and font resources used by the game are converted into C arrays and compiled directly into the firmware. + +- **Resource Path**: Resource files are located in the `pic/` directory. + +- **Conversion Tool**: You can use the [official LVGL online converter](https://lvgl.io/tools/imageconverter) to convert your own image or font files into the required C format. + +- **Replacement**: After generating the new C files, replace the old files in the `pic/` directory and recompile the project. + +### Adjust Game Difficulty + +The game's difficulty is determined by the frequency at which the moles appear, which is controlled by a timer. + +In the `pop_random_mole` function, the game dynamically adjusts the timer's period based on the remaining `game_time`. A shorter period results in moles appearing more frequently, increasing the difficulty. + +```c +// Gophers appear randomly +static void pop_random_mole(lv_timer_t *timer) { + // ... (code omitted) ... + + // Adjust the frequency of gophers + if (game_time < 40) { + lv_timer_set_period(timer, 800); // Set the period to 800 ms + } + if (game_time < 20) { + lv_timer_set_period(timer, 600); // Set the period to 600 ms + } +} +``` + +To adjust the game difficulty, you can modify the second argument of the `lv_timer_set_period` function. + +- **Decrease Difficulty**: Increase the period value (e.g., to `1000` ms). +- **Increase Difficulty**: Decrease the period value (e.g., to `500` ms). diff --git a/Whackmole/README_zh-cn.md b/Whackmole/README_zh-cn.md new file mode 100644 index 0000000000000000000000000000000000000000..8105f0ca09d71fce1471cd855f4abaeac753926f --- /dev/null +++ b/Whackmole/README_zh-cn.md @@ -0,0 +1,165 @@ +# 打地鼠 Demo 快速上手 + +\[ [English](./README.md) | 简体中文 \] + +本文档详细介绍如何在 openvela 系统上为 QEMU 模拟器和 ESP32-S3-BOX 开发板构建、部署和运行 Whack-a-Mole(打地鼠)演示应用程序。您将学习如何配置项目、编译固件、运行应用,并对游戏功能进行自定义修改。 + +## 一、运行效果 + +![img](img/whackmole.gif) + +## 二、构建与运行 + +本节将指导您完成从项目配置到在目标平台上运行应用程序的完整流程。 + +### 准备工作 + +在开始之前,请确保您已位于 `openvela` 仓库的根目录下。本文中的所有命令均以此为起点。 + +### 步骤 1:配置项目 + +您需要通过 `menuconfig` 工具来启用 Whack-a-Mole 应用并进行相关设置。 + +1. 启动 `menuconfig`。请根据您的目标平台选择对应的命令: + + - QEMU 模拟器: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + + - ESP32-S3-BOX: + + ```Bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 menuconfig + ``` + +2. 在 `menuconfig` 界面中,按 `/` 键打开搜索功能,查找并启用以下配置项: + + ```Bash + LVX_USE_DEMO_WHACKMOLE=y + LVX_WHACKMOLE_DATA_ROOT="/data" + ``` + +3. **(可选)** 如果您在运行时遇到界面卡顿或显示不流畅的问题,可以尝试增加 LVGL (Light and Versatile Graphics Library) 的缓存大小。搜索 `lv_cache_def_size` 并将其值设置为 `20000000`。 + +4. 保存配置并退出 `menuconfig`。 + +### 步骤 2:编译项目 + +编译前,建议先清理旧的构建产物以避免潜在的构建错误。 + +1. 清理构建产物 (distclean): + + - QEMU 模拟器: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 + ``` + + - ESP32-S3-BOX: + + ```Bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 distclean + ``` + +2. 执行构建: + + - QEMU 模拟器: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 + ``` + + - ESP32-S3-BOX: + + ```Bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 -j8 + ``` + +### 步骤 3:部署与运行 + +编译成功后,您可以将固件部署到目标平台并启动应用。 + +#### 选项 A:在 QEMU 模拟器中运行 + +1. 在 `openvela` 根目录,执行以下命令启动模拟器: + + ```Bash + ./emulator.sh vela + ``` + +2. 等待 openvela 终端(`openvela-ap>`)出现后,输入以下命令启动游戏: + + ```Bash + Whackmole + ``` + +#### 选项 B:在 ESP32-S3-BOX 开发板上运行 + +1. 烧录固件: + + 确保您的 ESP32-S3-BOX 已通过 USB 连接到计算机。执行以下命令开始烧录。请将 `/dev/ttyACM0` 替换为您的设备实际的串口端口号。 + + ```Bash + pushd nuttx && make -j8 flash ESPTOOL_PORT=/dev/ttyACM0 ESPTOOL_BINDIR=./ && popd + ``` + +2. 打开串口监视器: + + 使用 `minicom` 或其他串口工具来查看设备输出并与之交互。 + + ```Bash + sudo minicom -D /dev/ttyACM0 -b 115200 + ``` + +3. 启动游戏: + + 在 `minicom` 的终端中,输入以下命令: + + ```Bash + Whackmole + ``` + +## 三、应用定制 + +您可以根据需求修改游戏的核心功能,例如替换资源或调整难度。 + +### 核心文件结构 + +- `Whackmole.c`: 包含游戏的核心逻辑。所有功能开发和修改都应在此文件中进行。 +- `Whackmole_main.c`: 作为应用程序的入口,负责创建并启动运行游戏逻辑的任务。通常情况下,您无需修改此文件。 + +### 修改资源图片 + +游戏使用的图片和字体资源被转换为 C 数组,并直接编译到固件中。 + +- **资源路径**: 资源文件位于 `pic/` 目录下。 +- **转换工具**: 您可以使用 [LVGL 官方在线转换器](https://lvgl.io/tools/imageconverter) 将您自己的图片或字体文件转换为所需的 C 格式。 +- **替换**: 生成新的 C 文件后,替换 `pic/` 目录下的旧文件并重新编译项目。 + +### 调整游戏难度 + +游戏难度由地鼠出现的频率决定,该频率由一个定时器控制。 + +在 `pop_random_mole` 函数中,游戏会根据剩余时间 `game_time` 动态调整定时器的周期。周期越短,地鼠出现越快,难度越高。 + +```C +// Gophers appear randomly +static void pop_random_mole(lv_timer_t *timer) { + // ... (代码省略) ... + + // Adjust the frequency of gophers + if (game_time < 40) { + lv_timer_set_period(timer, 800); // 周期设置为 800 毫秒 + } + if (game_time < 20) { + lv_timer_set_period(timer, 600); // 周期设置为 600 毫秒 + } +} +``` + +要调整游戏难度,您可以修改 `lv_timer_set_period` 函数的第二个参数值。 + +- **降低难度**: 增大周期值(例如,`1000` 毫秒)。 +- **增加难度**: 减小周期值(例如,`500` 毫秒)。 diff --git a/Whackmole/Whackmole.c b/Whackmole/Whackmole.c new file mode 100644 index 0000000000000000000000000000000000000000..b091a243ebb599dcc93d104193f97f5b54d961d7 --- /dev/null +++ b/Whackmole/Whackmole.c @@ -0,0 +1,356 @@ +#include <stdbool.h> +#include <stdio.h> // for snprintf +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "Whackmole.h" + +#include "MiSans_Normal.h" +#include "MiSans_Semibold.h" +#include "grassland.h" +#include "hammer_image.h" +#include "mole_image.h" +#define GAME_TIME 30 +#define MOLE_COUNT 9 +static lv_obj_t* game_screen = NULL; +static lv_obj_t* game_screen_bg = NULL; +static lv_obj_t* moles[MOLE_COUNT]; +static lv_obj_t* score_label; +static lv_obj_t* time_label; +static lv_obj_t* hit_effect = NULL; +static lv_obj_t* hammer_cursor = NULL; +typedef struct { + int x_pct; // X position in percentage (0-100) + int y_pct; // Y position in percentage (0-100) +} hole_pos_t; +// Percentage positions for holes (relative to parent size) +static const hole_pos_t hole_positions[MOLE_COUNT] = { + { 17, 25 }, { 40, 23 }, { 67, 26 }, // Top row + { 15, 46 }, { 43, 48 }, { 68, 46 }, // Middle row + { 15, 68 }, { 40, 68 }, { 70, 68 } // Bottom row +}; +static int score = 0; +static int game_time = GAME_TIME; +static lv_timer_t* game_timer = NULL; +static lv_timer_t* mole_timer = NULL; +static void start_game(lv_event_t* e); +static void delete_effect_cb(lv_timer_t* timer); +static void mole_click_event(lv_event_t* e); +static void update_game_timer(lv_timer_t* timer); +static void pop_random_mole(lv_timer_t* timer); +static void pointer_event_cb(lv_event_t* e); +struct resource_s R; + +static void end_msg_event_cb(lv_event_t* e) +{ + lv_obj_t* btn = lv_event_get_target(e); + lv_obj_t* footer = lv_obj_get_parent(btn); + lv_obj_t* mbox = lv_obj_get_parent(footer); + lv_obj_delete(mbox); + const char* txt = (const char*)lv_event_get_user_data(e); + if (strcmp(txt, "Again") == 0) { + start_game(NULL); + } +} + +static bool init_resource(void) +{ + // Styles + lv_style_init(&R.styles.button_default); + lv_style_init(&R.styles.button_pressed); + lv_style_set_opa(&R.styles.button_default, LV_OPA_COVER); + lv_style_set_opa(&R.styles.button_pressed, LV_OPA_70); + + return true; +} +// INIT +void init_whack_a_mole_game(lv_obj_t* parent) +{ + // Set random number seed + srand(time(NULL)); + + game_screen_bg = lv_image_create(parent); + lv_image_set_src(game_screen_bg, &grassland); + lv_obj_set_size(game_screen_bg, LV_PCT(100), LV_PCT(100)); + lv_obj_align(game_screen_bg, LV_ALIGN_CENTER, 0, 0); + lv_image_set_inner_align(game_screen_bg, LV_IMAGE_ALIGN_STRETCH); + lv_obj_move_background(game_screen_bg); + lv_image_set_antialias(game_screen_bg, false); + + game_screen = lv_obj_create(parent); + lv_obj_remove_style_all(game_screen); + + // lv_obj_set_align(game_screen, LV_ALIGN_CENTER); + lv_obj_set_size(game_screen, lv_display_get_horizontal_resolution(NULL), lv_display_get_vertical_resolution(NULL)); + + lv_obj_align(game_screen, LV_ALIGN_CENTER, 0, 0); + lv_coord_t parent_w = lv_obj_get_style_width(game_screen, LV_PART_MAIN); + lv_coord_t parent_h = lv_obj_get_style_height(game_screen, LV_PART_MAIN); + + // Disable scroll and click attributes + lv_obj_remove_flag(game_screen, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_remove_flag(game_screen, LV_OBJ_FLAG_CLICKABLE); + lv_obj_remove_flag(game_screen, LV_OBJ_FLAG_SCROLL_ELASTIC); + lv_obj_remove_flag(game_screen, LV_OBJ_FLAG_SCROLL_MOMENTUM); + lv_obj_move_foreground(game_screen); + // Add pointer events to track mouse position + lv_obj_add_event_cb(game_screen, pointer_event_cb, LV_EVENT_PRESSED, NULL); + lv_obj_add_event_cb(game_screen, pointer_event_cb, LV_EVENT_PRESSING, NULL); + static const lv_style_prop_t props[] = { LV_STYLE_TRANSFORM_ROTATION, 0 }; + /* A special transition when going to pressed state + * Make it slow (500 ms) but start without delay*/ + static lv_style_transition_dsc_t trans_pr; + lv_style_transition_dsc_init(&trans_pr, props, lv_anim_path_linear, 150, 0, + NULL); + + // // hammer cursor + hammer_cursor = lv_image_create(game_screen); + lv_img_set_src(hammer_cursor, &hammer_image); + lv_obj_add_flag(hammer_cursor, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_style_image_recolor(hammer_cursor, lv_color_black(), 0); + lv_obj_set_style_image_recolor_opa(hammer_cursor, LV_OPA_30, 0); + lv_obj_set_size(hammer_cursor, parent_w / 7, parent_w / 7); + lv_obj_get_width(hammer_cursor); + lv_obj_get_height(hammer_cursor); + lv_image_set_inner_align(hammer_cursor, LV_IMAGE_ALIGN_STRETCH); + lv_image_set_antialias(hammer_cursor, false); + + lv_obj_set_style_transform_rotation(hammer_cursor, 0, LV_STATE_DEFAULT); + lv_obj_set_style_transform_rotation(hammer_cursor, 300, LV_STATE_PRESSED); + lv_obj_set_style_transition(hammer_cursor, &trans_pr, LV_STATE_DEFAULT); + lv_obj_set_style_transition(hammer_cursor, &trans_pr, LV_STATE_PRESSED); + lv_obj_add_flag(hammer_cursor, LV_OBJ_FLAG_CLICKABLE); + lv_obj_remove_flag(hammer_cursor, LV_OBJ_FLAG_IGNORE_LAYOUT); + + lv_image_set_antialias(game_screen_bg, false); + + // title + lv_obj_t* title = lv_label_create(game_screen); + lv_label_set_text(title, "Whackmole"); + lv_obj_set_style_text_font(title, &MiSans_Normal, 0); + lv_obj_set_style_text_color(title, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_align(title, LV_ALIGN_TOP_MID); + lv_obj_set_pos(title, 0, 10); + + // score display + score_label = lv_label_create(game_screen); + lv_label_set_text_fmt(score_label, "score: %d", score); + lv_obj_set_style_text_font(score_label, &MiSans_Normal, 0); + lv_obj_set_style_text_color(score_label, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_align(score_label, LV_ALIGN_TOP_LEFT); + + lv_obj_set_pos(score_label, 20, 10); + // Time display + time_label = lv_label_create(game_screen); + lv_label_set_text_fmt(time_label, "time: %d", game_time); + lv_obj_set_style_text_font(time_label, &MiSans_Normal, 0); + lv_obj_set_style_text_color(time_label, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_align(time_label, LV_ALIGN_TOP_RIGHT); + lv_obj_set_pos(time_label, -20, 10); + + for (int i = 0; i < 9; i++) { + lv_obj_t* hole = lv_obj_create(game_screen); + lv_obj_set_size(hole, LV_PCT(12), LV_PCT(20)); + // lv_obj_set_size(hole, 0.5 *parent_w, 0.5 * parent_h); + lv_coord_t x = (hole_positions[i].x_pct * parent_w) / 100; + lv_coord_t y = (hole_positions[i].y_pct * parent_h) / 100; + lv_obj_set_pos(hole, x, y); + lv_obj_set_style_border_width(hole, 0, 0); + lv_obj_set_style_margin_all(hole, 0, 0); + lv_obj_set_style_pad_all(hole, 0, 0); + lv_obj_set_style_bg_opa(hole, LV_OPA_TRANSP, 0); // Set background to transparent + + lv_obj_move_background(hole); + lv_obj_move_to_index(hole, 0); + // create moles + moles[i] = lv_image_create(hole); + lv_image_set_src(moles[i], &mole_image); + lv_obj_set_size(moles[i], LV_PCT(100), LV_PCT(100)); + lv_image_set_inner_align(moles[i], LV_IMAGE_ALIGN_STRETCH); + // lv_obj_set_style_border_width(moles[i], 5, 0); + lv_obj_set_style_margin_all(moles[i], 0, 0); + lv_obj_set_style_pad_all(moles[i], 0, 0); + // lv_image_set_scale(moles[i], 200); + lv_obj_set_align(moles[i], LV_ALIGN_CENTER); + + lv_obj_add_flag(moles[i], LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(moles[i], LV_OBJ_FLAG_CLICKABLE); + lv_obj_move_foreground(moles[i]); + + // click event + lv_obj_add_event_cb(moles[i], mole_click_event, LV_EVENT_CLICKED, NULL); + // Hover event + lv_obj_add_event_cb(moles[i], pointer_event_cb, LV_EVENT_PRESSED, NULL); + lv_obj_add_event_cb(moles[i], pointer_event_cb, LV_EVENT_PRESSING, NULL); + lv_obj_add_event_cb(moles[i], pointer_event_cb, LV_EVENT_RELEASED, NULL); + } + // Update hole positions based on current screen size + // start button + lv_obj_t* start_btn = lv_btn_create(game_screen); + lv_obj_set_size(start_btn, 120, 40); + lv_obj_set_align(start_btn, LV_ALIGN_BOTTOM_MID); + lv_obj_set_pos(start_btn, 0, -20); + lv_obj_add_event_cb(start_btn, start_game, LV_EVENT_CLICKED, start_btn); + lv_obj_set_style_bg_color(start_btn, lv_color_hex(0x228B22), 0); + lv_obj_t* btn_label = lv_label_create(start_btn); + lv_label_set_text(btn_label, "START"); + lv_obj_set_style_text_font(btn_label, &MiSans_Normal, 0); + lv_obj_set_style_text_color(start_btn, lv_color_hex(0xFFFFFF), 0); + lv_obj_center(btn_label); + lv_obj_move_foreground(hammer_cursor); + lv_obj_move_foreground(start_btn); + lv_obj_move_foreground(score_label); + lv_obj_move_foreground(time_label); + lv_obj_move_foreground(title); +} +static void pointer_event_cb(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_point_t pos; + lv_indev_t* indev = lv_indev_active(); + if (indev == NULL) + return; + lv_indev_get_point(indev, &pos); + lv_obj_remove_flag(hammer_cursor, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_pos(hammer_cursor, pos.x - 25, pos.y - 25); + + if (code == LV_EVENT_PRESSED) { + lv_obj_set_state(hammer_cursor, LV_STATE_PRESSED, true); + } else if (code == LV_EVENT_PRESSING) { + } else { + lv_obj_set_state(hammer_cursor, LV_STATE_PRESSED, false); + } +} + +// start game +static void start_game(lv_event_t* e) +{ + score = 0; + game_time = GAME_TIME; + if (e != NULL) { + lv_obj_t* start_btn = lv_event_get_user_data(e); + lv_obj_delete(start_btn); + } + + printf("Game started! Score: %d, Time: %d\n", score, game_time); + lv_label_set_text_fmt(score_label, "score: %d", score); + lv_label_set_text_fmt(time_label, "time: %d", game_time); + lv_obj_set_style_text_font(score_label, &MiSans_Normal, 0); + lv_obj_set_style_text_color(game_screen, lv_color_hex(0xFFFFFF), 0); + lv_obj_set_style_text_font(time_label, &MiSans_Normal, 0); + lv_obj_set_style_text_color(game_screen, lv_color_hex(0xFFFFFF), 0); + + for (int i = 0; i < 9; i++) { + lv_obj_add_flag(moles[i], LV_OBJ_FLAG_HIDDEN); + } + if (game_timer) { + lv_timer_delete(game_timer); + game_timer = NULL; + } + game_timer = lv_timer_create(update_game_timer, 1000, NULL); + + if (mole_timer) { + lv_timer_delete(mole_timer); + mole_timer = NULL; + } + mole_timer = lv_timer_create(pop_random_mole, 1000, NULL); +} + +// Update the game timer +static void update_game_timer(lv_timer_t* timer) +{ + game_time--; + lv_label_set_text_fmt(time_label, "time: %d", game_time); + if (game_time <= 0) { + lv_timer_delete(game_timer); + game_timer = NULL; + + if (mole_timer) { + lv_timer_delete(mole_timer); + mole_timer = NULL; + } + for (int i = 0; i < 9; i++) { + lv_obj_add_flag(moles[i], LV_OBJ_FLAG_HIDDEN); + } + lv_obj_t* end_msg = lv_msgbox_create(lv_screen_active()); + lv_msgbox_add_title(end_msg, "Game over!"); + lv_msgbox_add_text(end_msg, "Congratulations on completing game!"); + lv_obj_set_size(end_msg, 300, 120); + lv_msgbox_add_close_button(end_msg); + const char* btns[] = { "Again", NULL }; + for (int i = 0; btns[i]; i++) { + lv_obj_t* btn = lv_msgbox_add_footer_button(end_msg, btns[i]); + lv_obj_set_style_text_font(btn, &MiSans_Normal, 0); + + lv_obj_add_event_cb(btn, end_msg_event_cb, LV_EVENT_CLICKED, + (char*)btns[i]); + } + return; + } +} + +// Gophers appear randomly +static void pop_random_mole(lv_timer_t* timer) +{ + for (int i = 0; i < 9; i++) { + lv_obj_add_flag(moles[i], LV_OBJ_FLAG_HIDDEN); + } + int show_count = rand() % 2 + 1; + for (int i = 0; i < show_count; i++) { + int mole_idx = rand() % 9; + lv_obj_remove_flag(moles[mole_idx], LV_OBJ_FLAG_HIDDEN); + } + + // Adjust the frequency of gophers + if (game_time < 40) { + lv_timer_set_period(timer, 800); + } + if (game_time < 20) { + lv_timer_set_period(timer, 600); + } +} + +// Gopher click events +static void mole_click_event(lv_event_t* e) +{ + lv_obj_t* mole = lv_event_get_target(e); + LV_LOG_USER("clicked %d", lv_obj_has_flag(mole, LV_OBJ_FLAG_HIDDEN)); + // Bonus points when the gopher is visible + if (!lv_obj_has_flag(mole, LV_OBJ_FLAG_HIDDEN)) { + score++; + lv_label_set_text_fmt(score_label, "score: %d", score); + lv_obj_add_flag(mole, LV_OBJ_FLAG_HIDDEN); + if (hit_effect != NULL) { + lv_obj_delete(hit_effect); + hit_effect = NULL; + } + hit_effect = lv_obj_create(lv_obj_get_parent(mole)); + lv_obj_set_size(hit_effect, LV_PCT(100), LV_PCT(100)); + lv_obj_set_align(hit_effect, LV_ALIGN_CENTER); + lv_obj_set_pos(hit_effect, 0, 0); + lv_obj_set_style_bg_color(hit_effect, lv_color_hex(0xFFFF00), 0); + lv_obj_set_style_bg_opa(hit_effect, LV_OPA_50, 0); + lv_timer_create(delete_effect_cb, 300, hit_effect); + } +} + +// Delete click effects +static void delete_effect_cb(lv_timer_t* timer) +{ + lv_obj_t* effect = timer->user_data; + if (effect) { + lv_obj_delete(effect); + hit_effect = NULL; + } + lv_timer_delete(timer); +} + +// create app +void app_create(void) +{ + LV_FONT_DECLARE(MiSans_Normal); + lv_obj_t* scr = lv_screen_active(); + init_resource(); + init_whack_a_mole_game(scr); +} diff --git a/Whackmole/Whackmole.h b/Whackmole/Whackmole.h new file mode 100644 index 0000000000000000000000000000000000000000..5a4562bb20a160f1e57e418431093acd0ee43786 --- /dev/null +++ b/Whackmole/Whackmole.h @@ -0,0 +1,68 @@ +#ifndef WHACKMOLE_H +#define WHACKMOLE_H +#include <lvgl/lvgl.h> +#define RES_ROOT CONFIG_LVX_WHACKMOLE_DATA_ROOT "/pic" +#define ICONS_ROOT RES_ROOT "/icons" +#define FONTS_ROOT RES_ROOT "/fonts" +void init_whack_a_mole_game(lv_obj_t* parent); +void app_create(void); +struct resource_s { + struct { + lv_obj_t* time; + lv_obj_t* date; + + lv_obj_t* player_group; + + lv_obj_t* volume_bar; + lv_obj_t* volume_bar_indic; + lv_obj_t* audio; + lv_obj_t* playlist_base; + + lv_obj_t* album_cover; + lv_obj_t* album_name; + lv_obj_t* album_artist; + + lv_obj_t* play_btn; + lv_obj_t* playback_group; + lv_obj_t* playback_progress; + lv_span_t* playback_current_time; + lv_span_t* playback_total_time; + + lv_obj_t* playlist; + } ui; + + struct { + struct { + lv_font_t* normal; + } size_14; + struct { + lv_font_t* bold; + } size_22; + struct { + lv_font_t* normal; + } size_24; + struct { + lv_font_t* normal; + } size_28; + struct { + lv_font_t* bold; + } size_60; + } fonts; + + struct { + lv_style_t button_default; + lv_style_t button_pressed; + lv_style_transition_dsc_t button_transition_dsc; + lv_style_transition_dsc_t transition_dsc; + } styles; + + struct { + const char* hammer; + const char* mole; + const char* grassland; + } images; +}; +struct ctx_s { + bool resource_healthy_check; +}; +#endif // WHACKMOLE_H diff --git a/Whackmole/Whackmole_main.c b/Whackmole/Whackmole_main.c new file mode 100644 index 0000000000000000000000000000000000000000..49d89e8b36149ecb9b6ded05da4d0b68d09613ef --- /dev/null +++ b/Whackmole/Whackmole_main.c @@ -0,0 +1,90 @@ +// include NuttX headers +#include <nuttx/config.h> +#include <unistd.h> + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +#include <uv.h> +#endif + +// include lvgl headers +#include <lvgl/lvgl.h> + +#include "Whackmole.h" + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +#endif + +int main(int argc, FAR char* argv[]) +{ + // init lvgl + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); +#endif + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + lv_nuttx_dsc_init(&info); + +#ifdef CONFIG_LV_USE_NUTTX_LCD + info.fb_path = "/dev/lcd0"; +#endif + + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + app_create(); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + // refresh lvgl ui + lv_nuttx_uv_loop(&ui_loop, &result); +#endif + + while (1) { + uint32_t idle; + idle = lv_timer_handler(); + + /* Minimum sleep of 1ms */ + + idle = idle ? idle : 1; + usleep(idle * 1000); + } + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/Whackmole/img/whackmole.gif b/Whackmole/img/whackmole.gif new file mode 100644 index 0000000000000000000000000000000000000000..72526e4bfa41ef0ebc6b36785d23b07463c9a4dd Binary files /dev/null and b/Whackmole/img/whackmole.gif differ diff --git a/Whackmole/pic/MiSans_Normal.c b/Whackmole/pic/MiSans_Normal.c new file mode 100644 index 0000000000000000000000000000000000000000..fdcabd19d2aec2a553d782144eaf2123d1947656 --- /dev/null +++ b/Whackmole/pic/MiSans_Normal.c @@ -0,0 +1,905 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 1 + * Opts: --bpp 1 --size 16 --no-compress --font MiSans-Normal.ttf --symbols 0,1,2,3,4,5,6,7,8,9,~,开,始,游,戏,再,来,一,局,w,h,a,c,k,m,o,l,e,s,c,o,r,e,t,i,m,e,: + --range 32-127 --format lvgl -o MiSans-Normal.c + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef MISANS_NORMAL +#define MISANS_NORMAL 1 +#endif + +#if MISANS_NORMAL + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xff, 0x88, + + /* U+0022 "\"" */ + 0xb6, 0xd0, + + /* U+0023 "#" */ + 0x9, 0x2, 0x41, 0x90, 0x44, 0x7f, 0xc4, 0x81, + 0x20, 0x48, 0xff, 0x88, 0x82, 0x60, 0x90, 0x24, + 0x0, + + /* U+0024 "$" */ + 0x8, 0x8, 0x7e, 0xcb, 0x88, 0x88, 0x68, 0x3c, + 0xe, 0x9, 0x9, 0x89, 0xea, 0x3e, 0x8, 0x8, + + /* U+0025 "%" */ + 0x70, 0x24, 0xc3, 0x22, 0x31, 0x11, 0xd, 0x98, + 0x39, 0x80, 0x8, 0x0, 0x9e, 0xd, 0x98, 0x48, + 0x44, 0x42, 0x63, 0x32, 0xf, 0x0, + + /* U+0026 "&" */ + 0x1c, 0xc, 0x82, 0x20, 0x88, 0x26, 0x7, 0x3, + 0x81, 0x22, 0x85, 0xa0, 0xc8, 0x31, 0x1e, 0x38, + 0x80, + + /* U+0027 "'" */ + 0xf0, + + /* U+0028 "(" */ + 0x69, 0x69, 0x24, 0x92, 0x64, 0x98, + + /* U+0029 ")" */ + 0xc9, 0x32, 0x49, 0x24, 0xb4, 0xb0, + + /* U+002A "*" */ + 0x27, 0xc9, 0xf2, 0x0, + + /* U+002B "+" */ + 0x10, 0x20, 0x47, 0xf1, 0x2, 0x4, 0x0, + + /* U+002C "," */ + 0xe0, + + /* U+002D "-" */ + 0xf8, + + /* U+002E "." */ + 0x80, + + /* U+002F "/" */ + 0x10, 0x84, 0x62, 0x11, 0x88, 0x42, 0x31, 0x8, + 0x0, + + /* U+0030 "0" */ + 0x3c, 0x66, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x42, 0x66, 0x3c, + + /* U+0031 "1" */ + 0x37, 0x91, 0x11, 0x11, 0x11, 0x11, 0x10, + + /* U+0032 "2" */ + 0x39, 0x8a, 0x8, 0x10, 0x20, 0xc1, 0x4, 0x18, + 0x61, 0x86, 0xf, 0xe0, + + /* U+0033 "3" */ + 0xfe, 0x8, 0x30, 0xc3, 0xf, 0x1, 0x1, 0x2, + 0x6, 0xe, 0x27, 0x80, + + /* U+0034 "4" */ + 0x6, 0x6, 0xa, 0x1a, 0x12, 0x32, 0x22, 0x42, + 0xc2, 0xff, 0x2, 0x2, 0x2, + + /* U+0035 "5" */ + 0x7e, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x62, 0x1, + 0x1, 0x1, 0xc1, 0x62, 0x3c, + + /* U+0036 "6" */ + 0x8, 0x18, 0x30, 0x20, 0x60, 0x7c, 0xc2, 0x81, + 0x81, 0x81, 0x81, 0x42, 0x3c, + + /* U+0037 "7" */ + 0xfe, 0xc, 0x10, 0x20, 0xc1, 0x6, 0x8, 0x10, + 0x60, 0x81, 0x6, 0x0, + + /* U+0038 "8" */ + 0x3c, 0x64, 0x42, 0x42, 0x42, 0x24, 0x18, 0x66, + 0x81, 0x81, 0x81, 0x42, 0x3c, + + /* U+0039 "9" */ + 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x43, 0x3e, + 0x6, 0x4, 0xc, 0x18, 0x10, + + /* U+003A ":" */ + 0x80, 0x80, + + /* U+003B ";" */ + 0x80, 0xe0, + + /* U+003C "<" */ + 0x2, 0xc, 0x63, 0xc, 0xc, 0xe, 0x6, 0x2, + + /* U+003D "=" */ + 0xfe, 0x0, 0x0, 0xf, 0xe0, + + /* U+003E ">" */ + 0x81, 0x80, 0xc0, 0x60, 0x61, 0x8e, 0x30, 0x80, + + /* U+003F "?" */ + 0x3c, 0x8e, 0x8, 0x10, 0x60, 0x82, 0x8, 0x10, + 0x20, 0x0, 0x1, 0x0, + + /* U+0040 "@" */ + 0xf, 0x83, 0xc, 0x60, 0x24, 0x3, 0x8e, 0x99, + 0x99, 0x90, 0x99, 0x19, 0x8f, 0x64, 0x0, 0x40, + 0x3, 0x8, 0xf, 0x80, + + /* U+0041 "A" */ + 0xc, 0x3, 0x0, 0xe0, 0x68, 0x1a, 0x4, 0xc3, + 0x10, 0xc4, 0x3f, 0x98, 0x24, 0x9, 0x3, 0xc0, + 0x40, + + /* U+0042 "B" */ + 0xfc, 0x82, 0x81, 0x81, 0x81, 0x82, 0xfc, 0x82, + 0x81, 0x81, 0x81, 0x82, 0xfc, + + /* U+0043 "C" */ + 0x1f, 0x10, 0xd0, 0x18, 0x8, 0x4, 0x2, 0x1, + 0x0, 0x80, 0x60, 0x10, 0x24, 0x31, 0xe0, + + /* U+0044 "D" */ + 0xfe, 0x20, 0xc8, 0xa, 0x2, 0x80, 0x60, 0x18, + 0x6, 0x1, 0x80, 0x60, 0x28, 0xa, 0xc, 0xfc, + 0x0, + + /* U+0045 "E" */ + 0xff, 0x2, 0x4, 0x8, 0x10, 0x3f, 0xc0, 0x81, + 0x2, 0x4, 0xf, 0xe0, + + /* U+0046 "F" */ + 0xff, 0x2, 0x4, 0x8, 0x10, 0x3f, 0x40, 0x81, + 0x2, 0x4, 0x8, 0x0, + + /* U+0047 "G" */ + 0x1f, 0xc, 0x24, 0x3, 0x0, 0x80, 0x20, 0x8, + 0x3e, 0x1, 0x80, 0x70, 0x14, 0x4, 0x86, 0x1f, + 0x0, + + /* U+0048 "H" */ + 0x80, 0xc0, 0x60, 0x30, 0x18, 0xc, 0x7, 0xff, + 0x1, 0x80, 0xc0, 0x60, 0x30, 0x18, 0x8, + + /* U+0049 "I" */ + 0xff, 0xf8, + + /* U+004A "J" */ + 0x4, 0x10, 0x41, 0x4, 0x10, 0x41, 0x4, 0x14, + 0x53, 0x38, + + /* U+004B "K" */ + 0x83, 0x43, 0x23, 0x13, 0xb, 0x7, 0x3, 0x81, + 0x60, 0x98, 0x46, 0x21, 0x10, 0x48, 0x30, + + /* U+004C "L" */ + 0x81, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x81, + 0x2, 0x4, 0xf, 0xe0, + + /* U+004D "M" */ + 0x80, 0x38, 0xf, 0x1, 0xf0, 0x5a, 0xb, 0x22, + 0x66, 0xcc, 0x51, 0x8e, 0x30, 0x86, 0x0, 0xc0, + 0x18, 0x2, + + /* U+004E "N" */ + 0x80, 0xe0, 0x78, 0x34, 0x1b, 0xc, 0xc6, 0x23, + 0x19, 0x86, 0xc1, 0x60, 0xf0, 0x38, 0x8, + + /* U+004F "O" */ + 0x1f, 0x4, 0x11, 0x1, 0x60, 0x28, 0x3, 0x0, + 0x60, 0xc, 0x1, 0x80, 0x38, 0x9, 0x1, 0x10, + 0x41, 0xf0, + + /* U+0050 "P" */ + 0xfc, 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0xfc, + 0x80, 0x80, 0x80, 0x80, 0x80, + + /* U+0051 "Q" */ + 0x1f, 0x4, 0x11, 0x1, 0x60, 0x28, 0x3, 0x0, + 0x60, 0xc, 0x1, 0x80, 0x38, 0x2d, 0x7, 0x10, + 0x61, 0xf4, 0x0, 0x40, + + /* U+0052 "R" */ + 0xfc, 0x82, 0x81, 0x81, 0x81, 0x82, 0xfc, 0x8c, + 0x84, 0x86, 0x82, 0x83, 0x81, + + /* U+0053 "S" */ + 0x3c, 0x43, 0x80, 0x80, 0x80, 0x60, 0x3c, 0x6, + 0x1, 0x1, 0x81, 0xc2, 0x3c, + + /* U+0054 "T" */ + 0xff, 0x84, 0x2, 0x1, 0x0, 0x80, 0x40, 0x20, + 0x10, 0x8, 0x4, 0x2, 0x1, 0x0, 0x80, + + /* U+0055 "U" */ + 0x80, 0xc0, 0x60, 0x30, 0x18, 0xc, 0x6, 0x3, + 0x1, 0x80, 0xc0, 0x70, 0x6c, 0x63, 0xe0, + + /* U+0056 "V" */ + 0xc0, 0x50, 0x34, 0x9, 0x82, 0x21, 0x88, 0x43, + 0x10, 0x4c, 0x12, 0x6, 0x80, 0xe0, 0x30, 0xc, + 0x0, + + /* U+0057 "W" */ + 0xc1, 0x2, 0x83, 0xd, 0xe, 0x1a, 0x14, 0x26, + 0x28, 0x44, 0x49, 0x89, 0x92, 0x12, 0x24, 0x34, + 0x68, 0x28, 0x70, 0x60, 0xc0, 0xc1, 0x81, 0x83, + 0x0, + + /* U+0058 "X" */ + 0x40, 0x98, 0x63, 0x10, 0x48, 0x1e, 0x3, 0x0, + 0xc0, 0x70, 0x12, 0xc, 0xc2, 0x11, 0x86, 0x40, + 0x80, + + /* U+0059 "Y" */ + 0xc1, 0xa0, 0x98, 0xc4, 0x43, 0x60, 0xa0, 0x70, + 0x10, 0x8, 0x4, 0x2, 0x1, 0x0, 0x80, + + /* U+005A "Z" */ + 0xff, 0x3, 0x2, 0x4, 0xc, 0x8, 0x18, 0x10, + 0x30, 0x20, 0x40, 0xc0, 0xff, + + /* U+005B "[" */ + 0xf2, 0x49, 0x24, 0x92, 0x49, 0x38, + + /* U+005C "\\" */ + 0xc2, 0x10, 0x82, 0x10, 0x86, 0x10, 0x86, 0x10, + 0x80, + + /* U+005D "]" */ + 0xe4, 0x92, 0x49, 0x24, 0x92, 0x78, + + /* U+005E "^" */ + 0x10, 0x70, 0xa2, 0x24, 0x40, + + /* U+005F "_" */ + 0xfe, + + /* U+0060 "`" */ + 0xb4, + + /* U+0061 "a" */ + 0x7c, 0x8c, 0x8, 0x13, 0xf8, 0x60, 0xc3, 0x7a, + + /* U+0062 "b" */ + 0x80, 0x80, 0x80, 0x80, 0xbc, 0xc2, 0x83, 0x81, + 0x81, 0x81, 0x83, 0xc2, 0xbc, + + /* U+0063 "c" */ + 0x3c, 0x8e, 0x4, 0x8, 0x10, 0x20, 0x23, 0x3c, + + /* U+0064 "d" */ + 0x1, 0x1, 0x1, 0x1, 0x3d, 0x43, 0xc3, 0x81, + 0x81, 0x81, 0x81, 0x43, 0x3d, + + /* U+0065 "e" */ + 0x38, 0x8a, 0xc, 0x1f, 0xf0, 0x20, 0x23, 0x3c, + + /* U+0066 "f" */ + 0x3a, 0x10, 0x8f, 0xa1, 0x8, 0x42, 0x10, 0x84, + 0x0, + + /* U+0067 "g" */ + 0x3d, 0x43, 0xc1, 0x81, 0x81, 0x81, 0x81, 0x43, + 0x3d, 0x1, 0x1, 0xc2, 0x3c, + + /* U+0068 "h" */ + 0x81, 0x2, 0x4, 0xb, 0xd8, 0xe0, 0xc1, 0x83, + 0x6, 0xc, 0x18, 0x20, + + /* U+0069 "i" */ + 0x8f, 0xf8, + + /* U+006A "j" */ + 0x20, 0x2, 0x49, 0x24, 0x92, 0x49, 0xc0, + + /* U+006B "k" */ + 0x81, 0x2, 0x4, 0x8, 0xd3, 0x2c, 0x70, 0xe1, + 0x62, 0x64, 0x48, 0x40, + + /* U+006C "l" */ + 0xaa, 0xaa, 0xaa, 0xc0, + + /* U+006D "m" */ + 0xb9, 0xd9, 0xce, 0x10, 0xc2, 0x18, 0x43, 0x8, + 0x61, 0xc, 0x21, 0x84, 0x20, + + /* U+006E "n" */ + 0xbd, 0x8e, 0xc, 0x18, 0x30, 0x60, 0xc1, 0x82, + + /* U+006F "o" */ + 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, + 0x3c, + + /* U+0070 "p" */ + 0xbc, 0xc2, 0xc3, 0x81, 0x81, 0x81, 0x83, 0xc2, + 0xbc, 0x80, 0x80, 0x80, 0x80, + + /* U+0071 "q" */ + 0x3d, 0x43, 0xc3, 0x81, 0x81, 0x81, 0xc1, 0x43, + 0x3d, 0x1, 0x1, 0x1, 0x1, + + /* U+0072 "r" */ + 0xbc, 0x88, 0x88, 0x88, 0x80, + + /* U+0073 "s" */ + 0x7a, 0x38, 0x30, 0x78, 0x30, 0x61, 0x78, + + /* U+0074 "t" */ + 0x42, 0x11, 0xf4, 0x21, 0x8, 0x42, 0x10, 0x70, + + /* U+0075 "u" */ + 0x83, 0x6, 0xc, 0x18, 0x30, 0x60, 0xe3, 0x7a, + + /* U+0076 "v" */ + 0xc3, 0x42, 0x42, 0x66, 0x24, 0x24, 0x3c, 0x18, + 0x18, + + /* U+0077 "w" */ + 0xc6, 0x14, 0x61, 0x45, 0x34, 0x52, 0x69, 0x22, + 0x9a, 0x28, 0xc3, 0x8c, 0x10, 0xc0, + + /* U+0078 "x" */ + 0x42, 0x64, 0x24, 0x18, 0x18, 0x38, 0x24, 0x66, + 0xc2, + + /* U+0079 "y" */ + 0xc1, 0x42, 0x42, 0x66, 0x24, 0x24, 0x3c, 0x18, + 0x18, 0x18, 0x10, 0x30, 0x20, + + /* U+007A "z" */ + 0xfe, 0xc, 0x30, 0xc1, 0x6, 0x18, 0x60, 0xfe, + + /* U+007B "{" */ + 0x19, 0x8, 0x42, 0x11, 0x98, 0x61, 0x8, 0x42, + 0x10, 0x60, + + /* U+007C "|" */ + 0xff, 0xfe, + + /* U+007D "}" */ + 0xc1, 0x8, 0x42, 0x10, 0xc3, 0x31, 0x8, 0x42, + 0x13, 0x0, + + /* U+007E "~" */ + 0x67, 0x38, + + /* U+007F "" */ + 0x0, + + /* U+4E00 "一" */ + 0xff, 0xfc, + + /* U+518D "再" */ + 0xff, 0xfc, 0xc, 0x3, 0xff, 0x8, 0xc4, 0x23, + 0x10, 0xff, 0xc2, 0x31, 0x8, 0xc4, 0xff, 0xfc, + 0x80, 0x42, 0x1, 0x8, 0x4, 0x20, 0xf0, + + /* U+59CB "始" */ + 0x0, 0x0, 0x82, 0x4, 0x1b, 0x3e, 0x44, 0x4a, + 0x9, 0x2f, 0xe4, 0x80, 0x52, 0x0, 0x50, 0x3, + 0x4f, 0xe7, 0x20, 0x8c, 0x82, 0x3a, 0x9, 0xf, + 0xe8, 0x20, 0x80, + + /* U+5C40 "局" */ + 0x3f, 0xf8, 0x80, 0x22, 0x0, 0x8f, 0xfe, 0x20, + 0x0, 0x80, 0x3, 0xff, 0xc8, 0x1, 0x2f, 0xc4, + 0xa1, 0x12, 0x84, 0x53, 0xf1, 0x40, 0xf, 0x3, + 0xe0, + + /* U+5F00 "开" */ + 0x7f, 0xf8, 0x21, 0x80, 0x86, 0x2, 0x18, 0x8, + 0x63, 0xff, 0xf0, 0x86, 0x2, 0x18, 0x18, 0x60, + 0x41, 0x83, 0x6, 0x18, 0x18, 0x40, 0x60, + + /* U+620F "戏" */ + 0x1, 0x0, 0xb, 0x3e, 0x4c, 0x12, 0x0, 0x9f, + 0xe7, 0xc1, 0x44, 0x46, 0x22, 0x30, 0xa1, 0x87, + 0xc, 0x30, 0x93, 0x14, 0xb4, 0xc3, 0x26, 0x0, + 0xc0, + + /* U+6765 "来" */ + 0x3, 0x1, 0xff, 0xe0, 0x30, 0x8, 0xc4, 0x13, + 0x20, 0x6d, 0x80, 0x30, 0x3f, 0xff, 0x3, 0x0, + 0x3f, 0x1, 0xb6, 0x18, 0xc6, 0xc3, 0xc, 0xc, + 0x0, + + /* U+6E38 "游" */ + 0x4, 0x44, 0x22, 0x19, 0x1e, 0x3f, 0xf0, 0x88, + 0x64, 0x3d, 0x38, 0x41, 0x44, 0xa, 0x22, 0x57, + 0xd2, 0x88, 0xa4, 0x4d, 0x22, 0x49, 0x12, 0xbb, + 0x80, + + /* U+FF5E "~" */ + 0xe6, 0x70 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 91, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 67, .box_w = 1, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3, .adv_w = 85, .box_w = 3, .box_h = 4, .ofs_x = 1, .ofs_y = 10}, + {.bitmap_index = 5, .adv_w = 181, .box_w = 10, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 22, .adv_w = 147, .box_w = 8, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 38, .adv_w = 210, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 60, .adv_w = 179, .box_w = 10, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 77, .adv_w = 49, .box_w = 1, .box_h = 4, .ofs_x = 1, .ofs_y = 10}, + {.bitmap_index = 78, .adv_w = 77, .box_w = 3, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 84, .adv_w = 77, .box_w = 3, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90, .adv_w = 113, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 94, .adv_w = 154, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 101, .adv_w = 65, .box_w = 1, .box_h = 3, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102, .adv_w = 100, .box_w = 5, .box_h = 1, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 103, .adv_w = 62, .box_w = 1, .box_h = 1, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 104, .adv_w = 100, .box_w = 5, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 113, .adv_w = 161, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 126, .adv_w = 101, .box_w = 4, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 133, .adv_w = 144, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 145, .adv_w = 151, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 157, .adv_w = 150, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 170, .adv_w = 153, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 183, .adv_w = 154, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 196, .adv_w = 133, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 208, .adv_w = 159, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 221, .adv_w = 152, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 234, .adv_w = 62, .box_w = 1, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 236, .adv_w = 65, .box_w = 1, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 238, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 246, .adv_w = 154, .box_w = 7, .box_h = 5, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 251, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 259, .adv_w = 125, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 271, .adv_w = 211, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 291, .adv_w = 168, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 308, .adv_w = 169, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 321, .adv_w = 178, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 336, .adv_w = 190, .box_w = 10, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 353, .adv_w = 152, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 365, .adv_w = 146, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 377, .adv_w = 188, .box_w = 10, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 394, .adv_w = 183, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 409, .adv_w = 61, .box_w = 1, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 411, .adv_w = 120, .box_w = 6, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 421, .adv_w = 164, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 436, .adv_w = 144, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 448, .adv_w = 223, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 466, .adv_w = 187, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 481, .adv_w = 200, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 499, .adv_w = 158, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 512, .adv_w = 200, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 532, .adv_w = 161, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 545, .adv_w = 154, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 558, .adv_w = 153, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 573, .adv_w = 179, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 588, .adv_w = 168, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 605, .adv_w = 245, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 630, .adv_w = 159, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 647, .adv_w = 158, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 662, .adv_w = 151, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 675, .adv_w = 89, .box_w = 3, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 681, .adv_w = 87, .box_w = 5, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 690, .adv_w = 89, .box_w = 3, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 696, .adv_w = 112, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 9}, + {.bitmap_index = 701, .adv_w = 116, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 702, .adv_w = 66, .box_w = 2, .box_h = 3, .ofs_x = 1, .ofs_y = 10}, + {.bitmap_index = 703, .adv_w = 136, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 711, .adv_w = 153, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 724, .adv_w = 136, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 732, .adv_w = 153, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 745, .adv_w = 143, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 753, .adv_w = 88, .box_w = 5, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 762, .adv_w = 153, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 775, .adv_w = 148, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 787, .adv_w = 62, .box_w = 1, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 789, .adv_w = 62, .box_w = 3, .box_h = 17, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 796, .adv_w = 129, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 808, .adv_w = 62, .box_w = 2, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 812, .adv_w = 226, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 825, .adv_w = 148, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 833, .adv_w = 147, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 842, .adv_w = 153, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 855, .adv_w = 153, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 868, .adv_w = 95, .box_w = 4, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 873, .adv_w = 120, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 880, .adv_w = 89, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 888, .adv_w = 148, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 896, .adv_w = 129, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 905, .adv_w = 201, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 919, .adv_w = 123, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 928, .adv_w = 130, .box_w = 8, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 941, .adv_w = 125, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 949, .adv_w = 89, .box_w = 5, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 959, .adv_w = 56, .box_w = 1, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 961, .adv_w = 89, .box_w = 5, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 971, .adv_w = 133, .box_w = 7, .box_h = 2, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 973, .adv_w = 0, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 974, .adv_w = 256, .box_w = 14, .box_h = 1, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 976, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 999, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1026, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1051, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1074, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1099, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1124, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1149, .adv_w = 256, .box_w = 6, .box_h = 2, .ofs_x = 5, .ofs_y = 5} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x38d, 0xbcb, 0xe40, 0x1100, 0x140f, 0x1965, 0x2038, + 0xb15e +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 96, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 19968, .range_length = 45407, .glyph_id_start = 97, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 9, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = +{ + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 2, 0, 2, + 3, 4, 0, 5, 6, 7, 0, 8, + 9, 10, 11, 0, 0, 0, 0, 0, + 0, 0, 12, 13, 14, 15, 16, 17, + 18, 0, 0, 19, 20, 21, 0, 0, + 15, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, + 33, 0, 34, 35, 36, 0, 37, 38, + 39, 34, 0, 0, 40, 41, 34, 34, + 35, 35, 39, 42, 43, 44, 39, 45, + 46, 47, 45, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = +{ + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 2, 0, 2, + 3, 4, 5, 6, 7, 8, 0, 9, + 10, 11, 12, 0, 0, 0, 0, 0, + 0, 0, 13, 0, 14, 0, 0, 0, + 14, 0, 0, 15, 0, 0, 0, 0, + 14, 0, 14, 0, 16, 17, 18, 19, + 20, 21, 22, 23, 0, 0, 0, 0, + 0, 0, 24, 0, 25, 25, 25, 26, + 25, 0, 0, 27, 0, 28, 29, 29, + 25, 29, 25, 29, 30, 31, 32, 33, + 34, 35, 33, 36, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -2, -7, 0, + -20, -5, -18, -10, 0, -26, 0, -4, + -2, 1, 0, -5, 0, 0, -2, 0, + -9, -7, 0, 0, 0, 0, 0, 0, + -15, 0, 0, -12, 0, 0, 0, -15, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -18, + -13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, 0, -7, -9, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, 0, 0, 0, -3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -5, 0, + 0, -7, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, -10, 0, -3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -36, -24, -5, 0, 0, 0, -19, + -17, 0, -5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -5, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -28, -13, 0, 0, 0, 0, -6, + -3, 0, -5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -7, 0, 0, -34, -4, -27, -19, + 0, -30, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, -12, -6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + -6, 0, -6, -5, -5, -9, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -3, 0, -1, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, -3, 0, 0, 0, + -5, -3, -3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, -5, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, -15, 0, + -8, 0, -9, -4, -13, -13, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -3, -6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, -3, 0, 0, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -16, 0, -27, -3, + 0, 0, 0, 0, -5, 0, 0, -16, + -7, 0, 0, 0, 0, 0, 0, -5, + -3, -3, -10, -3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, 0, 0, 0, -8, 0, -10, -4, + -7, -16, -3, 0, 0, 0, 0, 0, + 0, -2, 0, 0, -7, -8, -5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -16, -11, -8, 0, -13, 0, 0, + 0, 0, 0, -8, -14, 0, 0, 0, + 0, -3, -13, -13, -20, -16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -10, 0, 0, + -35, -5, -31, -21, 0, -35, 0, 0, + 0, -6, 0, 0, 0, 0, -9, -6, + -20, -13, 0, 0, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -22, 0, -41, 0, -5, 0, -6, -5, + -10, -8, -5, -14, -13, 0, 0, 0, + 0, -10, 0, -10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -7, 0, 0, 0, + -8, 0, -6, -6, -11, -13, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, -7, 0, -5, 0, -5, -3, + 0, -8, 0, -4, -5, 0, 0, 0, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, 0, -3, 0, -7, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, -5, -3, -4, -15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -34, -8, -40, -7, 0, 0, 0, 0, + -7, 0, 0, -26, -26, -13, 0, 0, + -23, -33, -5, -26, -28, -26, -28, -29, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, -7, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -27, -9, -40, -3, 0, 0, 0, 0, + 0, 0, 0, -22, -20, -9, 0, 0, + -20, -19, -5, -19, -8, -8, -10, -11, + -10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -19, -4, -24, -2, + 0, 0, 0, 0, 0, 0, 0, -13, + -11, -5, 0, 0, -12, -12, -3, -11, + -8, -8, -10, -10, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 0, -3, -7, -4, 0, 0, + 0, 0, 0, -2, -10, -5, 0, -2, + -4, -8, -13, -11, -21, -18, 0, 0, + -20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -30, -13, -44, -8, + 0, 0, 0, 0, 0, 0, 0, -39, + -36, -13, 0, 0, -38, -33, -15, -36, + -26, -25, -26, -28, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, -7, -8, -11, -10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -25, 0, -22, -13, + -5, -40, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, -2, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + -26, 0, -20, -11, -10, -36, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -3, -3, -8, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -26, 0, -12, -9, + -5, -31, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, -5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -26, 0, -16, -9, -8, -29, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, -1, -4, 0, -8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -15, 0, -18, 0, 0, 0, 0, 0, + 0, 0, 0, -5, -4, 0, 0, 0, + 0, -4, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -23, 0, -20, -14, 0, -36, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, -38, -3, -12, -8, + 0, -20, 0, -2, -4, 0, 0, -1, + 0, -3, -2, -4, 0, 0, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -2, + -2, -2, 0, 0, -13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -23, 0, 0, 0, + -20, -18, -13, -3, -3, 0, 0, 0, + 0, -2, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32, 0, -13, -10, -8, -30, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, -6, -3, + 0, -13, 0, 0, -2, 0, 0, 0, + 0, -2, 0, -1, 0, 0, 0, 0, + -10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -12, 0, -23, 0, + -28, 0, -8, -8, -21, -26, -13, -2, + -3, 0, 0, 0, 0, -2, 0, 0, + 0, 0, 0, 0, -6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, 0, -19, 0, -26, 0, -8, -8, + -18, -25, -10, -2, -3, 0, 0, 0, + 0, -2, 0, 0, 0, 0, 0, 0, + -3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, 0, + -28, 0, -10, -10, 0, -26, 0, -4, + -9, 0, 0, -3, 0, -6, 0, -3, + 0, 0, 0, 0, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, -28, 0, -8, -12, + 0, -28, 0, -1, -4, 0, 0, 0, + 0, -2, 0, -2, 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = +{ + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 48, + .right_class_cnt = 36, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_classes, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 1, + .kern_classes = 1, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t MiSans_Normal = { +#else +lv_font_t MiSans_Normal = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 18, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if MISANS-NORMAL*/ + diff --git a/Whackmole/pic/MiSans_Normal.h b/Whackmole/pic/MiSans_Normal.h new file mode 100644 index 0000000000000000000000000000000000000000..3762f2f2c6d2cd3dba8b63381a90776d6e3b067b --- /dev/null +++ b/Whackmole/pic/MiSans_Normal.h @@ -0,0 +1,16 @@ +#ifndef NORMAL_H +#define NORMAL_H + +#include "lvgl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_font_t MiSans_Normal; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Whackmole/pic/MiSans_Semibold.c b/Whackmole/pic/MiSans_Semibold.c new file mode 100644 index 0000000000000000000000000000000000000000..e46a3be4ddc33d4bff9d39ab4e08bf25140d7df0 --- /dev/null +++ b/Whackmole/pic/MiSans_Semibold.c @@ -0,0 +1,916 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 1 + * Opts: --bpp 1 --size 16 --no-compress --font MiSans-Semibold.ttf --symbols 0,1,2,3,4,5,6,7,8,9,~,开,始,游,戏,再,来,一,局,w,h,a,c,k,m,o,l,e,s,c,o,r,e,t,i,m,e,: + --range 32-127 --format lvgl -o MiSans-Semibold.c + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef MISANS-SEMIBOLD +#define MISANS-SEMIBOLD 1 +#endif + +#if MISANS-SEMIBOLD + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xff, 0xff, 0xf, + + /* U+0022 "\"" */ + 0xde, 0xf7, 0xbd, 0x80, + + /* U+0023 "#" */ + 0x19, 0x86, 0x61, 0x9b, 0xff, 0xff, 0xcc, 0xc3, + 0x33, 0xff, 0xff, 0xd9, 0x86, 0x61, 0x98, + + /* U+0024 "$" */ + 0x18, 0x1e, 0x1f, 0xdc, 0x7c, 0x17, 0x3, 0xf0, + 0xfe, 0x1f, 0x81, 0xd0, 0x7c, 0x77, 0xf1, 0xe0, + 0x60, + + /* U+0025 "%" */ + 0x78, 0x33, 0xf1, 0x8c, 0xc6, 0x33, 0x30, 0xfd, + 0x81, 0xec, 0x0, 0x37, 0x81, 0xbf, 0xc, 0xcc, + 0x63, 0x31, 0x8f, 0xcc, 0x1e, + + /* U+0026 "&" */ + 0x1e, 0x3, 0xf0, 0x33, 0x83, 0x10, 0x38, 0x3, + 0xc0, 0x7e, 0xee, 0x7c, 0xc3, 0xce, 0x3c, 0x7f, + 0xc3, 0xee, + + /* U+0027 "'" */ + 0xff, 0xc0, + + /* U+0028 "(" */ + 0x76, 0x6c, 0xcc, 0xcc, 0xcc, 0xe6, 0x67, + + /* U+0029 ")" */ + 0xe6, 0x67, 0x33, 0x33, 0x33, 0x76, 0x6e, + + /* U+002A "*" */ + 0x2f, 0xcd, 0xf2, 0x0, + + /* U+002B "+" */ + 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, + + /* U+002C "," */ + 0xf5, 0x80, + + /* U+002D "-" */ + 0xff, 0xc0, + + /* U+002E "." */ + 0xf0, + + /* U+002F "/" */ + 0x18, 0x61, 0x8e, 0x30, 0xc7, 0x18, 0x63, 0x8c, + 0x30, + + /* U+0030 "0" */ + 0x3e, 0x3f, 0x98, 0xd8, 0x3c, 0x1e, 0xf, 0x7, + 0x83, 0xc1, 0xb1, 0x9f, 0xc7, 0xc0, + + /* U+0031 "1" */ + 0x3b, 0xff, 0x31, 0x8c, 0x63, 0x18, 0xc6, 0x30, + + /* U+0032 "2" */ + 0x3c, 0x7e, 0xe3, 0x43, 0x3, 0x6, 0xe, 0x1c, + 0x38, 0x70, 0xff, 0xff, + + /* U+0033 "3" */ + 0x7f, 0xbf, 0xc1, 0xc1, 0x83, 0xe0, 0xf8, 0xe, + 0x3, 0x21, 0xb9, 0xdf, 0xc7, 0xc0, + + /* U+0034 "4" */ + 0x7, 0x7, 0x83, 0xc3, 0xe3, 0xb1, 0x99, 0xcc, + 0xc6, 0xff, 0xff, 0xc0, 0xc0, 0x60, + + /* U+0035 "5" */ + 0x7e, 0xfe, 0xe0, 0xe0, 0xfc, 0xfe, 0xe7, 0x3, + 0x3, 0xe7, 0xfe, 0x3c, + + /* U+0036 "6" */ + 0x1e, 0xe, 0xe, 0x6, 0x7, 0xe7, 0xfb, 0x8f, + 0x83, 0xc1, 0xf1, 0xdf, 0xc7, 0xc0, + + /* U+0037 "7" */ + 0xff, 0xff, 0x7, 0xe, 0xe, 0xc, 0x1c, 0x18, + 0x38, 0x30, 0x70, 0x70, + + /* U+0038 "8" */ + 0x3e, 0x3f, 0x98, 0xcc, 0x67, 0xf3, 0xfb, 0x8f, + 0x83, 0xc1, 0xf1, 0xdf, 0xc7, 0xc0, + + /* U+0039 "9" */ + 0x3e, 0x3f, 0xb8, 0xf8, 0x3c, 0x1f, 0x1d, 0xfc, + 0x7e, 0x6, 0x7, 0x7, 0x7, 0x80, + + /* U+003A ":" */ + 0xf0, 0x3, 0xc0, + + /* U+003B ";" */ + 0xf0, 0x3, 0xd6, + + /* U+003C "<" */ + 0x1, 0x7, 0x1f, 0x7c, 0xf0, 0xf0, 0x7c, 0x1f, + 0x7, 0x1, + + /* U+003D "=" */ + 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, + + /* U+003E ">" */ + 0x80, 0xe0, 0xf8, 0x3e, 0xf, 0xf, 0x3e, 0xf8, + 0xe0, 0x80, + + /* U+003F "?" */ + 0x3c, 0x7f, 0xe3, 0x3, 0x7, 0xe, 0x1c, 0x18, + 0x18, 0x0, 0x18, 0x18, + + /* U+0040 "@" */ + 0xf, 0x81, 0xff, 0x1c, 0x1c, 0xdd, 0xfd, 0xfd, + 0xec, 0x6f, 0x63, 0x7b, 0xef, 0xef, 0x73, 0x80, + 0xf, 0xf0, 0x1f, 0x0, + + /* U+0041 "A" */ + 0x6, 0x0, 0xf0, 0xf, 0x1, 0xf8, 0x19, 0x81, + 0x98, 0x39, 0xc3, 0xfc, 0x7f, 0xe7, 0xe, 0x60, + 0x6e, 0x7, + + /* U+0042 "B" */ + 0xfe, 0x7f, 0xb0, 0xf8, 0x3c, 0x3f, 0xfb, 0xfd, + 0x87, 0xc1, 0xe1, 0xff, 0xdf, 0xc0, + + /* U+0043 "C" */ + 0x1f, 0xf, 0xe7, 0x1f, 0x80, 0xc0, 0x30, 0xc, + 0x3, 0x0, 0xe0, 0x1c, 0x73, 0xf8, 0x7c, + + /* U+0044 "D" */ + 0xfe, 0x3f, 0xcc, 0x3b, 0x7, 0xc0, 0xf0, 0x3c, + 0xf, 0x3, 0xc1, 0xf0, 0xef, 0xf3, 0xf8, + + /* U+0045 "E" */ + 0xff, 0xff, 0xf0, 0x18, 0xc, 0x7, 0xfb, 0xfd, + 0x80, 0xc0, 0x60, 0x3f, 0xff, 0xf0, + + /* U+0046 "F" */ + 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, + + /* U+0047 "G" */ + 0x1f, 0xf, 0xe7, 0x1f, 0x80, 0xc0, 0x31, 0xfc, + 0x7f, 0x3, 0xe0, 0xdc, 0x73, 0xf8, 0x7c, + + /* U+0048 "H" */ + 0xc0, 0xf0, 0x3c, 0xf, 0x3, 0xc0, 0xff, 0xff, + 0xff, 0x3, 0xc0, 0xf0, 0x3c, 0xf, 0x3, + + /* U+0049 "I" */ + 0xff, 0xff, 0xff, + + /* U+004A "J" */ + 0x6, 0xc, 0x18, 0x30, 0x60, 0xc1, 0x83, 0x7, + 0xcf, 0xf3, 0xc0, + + /* U+004B "K" */ + 0xc3, 0xb1, 0xcc, 0xe3, 0x70, 0xf8, 0x3e, 0xf, + 0xc3, 0x78, 0xce, 0x31, 0xcc, 0x3b, 0x7, + + /* U+004C "L" */ + 0xc0, 0x60, 0x30, 0x18, 0xc, 0x6, 0x3, 0x1, + 0x80, 0xc0, 0x60, 0x3f, 0xff, 0xf0, + + /* U+004D "M" */ + 0xc0, 0x1f, 0x1, 0xfc, 0x1f, 0xe1, 0xff, 0x8f, + 0xee, 0xef, 0x3e, 0x79, 0xe3, 0xc7, 0x1e, 0x0, + 0xf0, 0x7, 0x80, 0x30, + + /* U+004E "N" */ + 0xc0, 0xf8, 0x3f, 0xf, 0xe3, 0xf8, 0xf7, 0x3c, + 0xef, 0x1f, 0xc7, 0xf0, 0xfc, 0x1f, 0x3, + + /* U+004F "O" */ + 0x1f, 0x7, 0xf1, 0xc7, 0x70, 0x7c, 0x7, 0x80, + 0xf0, 0x1e, 0x3, 0xe0, 0xee, 0x38, 0xfe, 0xf, + 0x80, + + /* U+0050 "P" */ + 0xfe, 0x7f, 0xb0, 0xf8, 0x3c, 0x1e, 0x1f, 0xfd, + 0xfc, 0xc0, 0x60, 0x30, 0x18, 0x0, + + /* U+0051 "Q" */ + 0x1f, 0x7, 0xf1, 0xc7, 0x70, 0x7c, 0x7, 0x80, + 0xf0, 0x1e, 0x3, 0xe0, 0xee, 0x38, 0xff, 0xf, + 0xf0, 0x6, + + /* U+0052 "R" */ + 0xfe, 0x3f, 0xcc, 0x3b, 0x6, 0xc3, 0xbf, 0xcf, + 0xe3, 0x1c, 0xc7, 0x30, 0xcc, 0x3b, 0x6, + + /* U+0053 "S" */ + 0x3e, 0x3f, 0xb8, 0xf8, 0xe, 0x3, 0xe0, 0x7c, + 0x7, 0x1, 0xe1, 0xff, 0xc7, 0xc0, + + /* U+0054 "T" */ + 0xff, 0xff, 0xf0, 0xc0, 0x30, 0xc, 0x3, 0x0, + 0xc0, 0x30, 0xc, 0x3, 0x0, 0xc0, 0x30, + + /* U+0055 "U" */ + 0xc0, 0xf0, 0x3c, 0xf, 0x3, 0xc0, 0xf0, 0x3c, + 0xf, 0x3, 0xc0, 0xf8, 0x77, 0xf8, 0x78, + + /* U+0056 "V" */ + 0xe0, 0x76, 0x6, 0x70, 0xe3, 0xe, 0x30, 0xc3, + 0x9c, 0x19, 0x81, 0xd8, 0x1f, 0x80, 0xf0, 0xf, + 0x0, 0x70, + + /* U+0057 "W" */ + 0xe1, 0xc1, 0xb0, 0xe1, 0xd8, 0x78, 0xee, 0x7c, + 0x67, 0x36, 0x31, 0x9b, 0xb8, 0xcc, 0xdc, 0x7c, + 0x6c, 0x1e, 0x3e, 0xf, 0xf, 0x7, 0x7, 0x3, + 0x83, 0x80, + + /* U+0058 "X" */ + 0x70, 0xe3, 0xc, 0x39, 0xc1, 0xf8, 0xf, 0x0, + 0xf0, 0xf, 0x1, 0xf8, 0x19, 0x83, 0x9c, 0x70, + 0xe7, 0xe, + + /* U+0059 "Y" */ + 0xe1, 0xf8, 0x77, 0x38, 0xcc, 0x3f, 0x7, 0x80, + 0xc0, 0x30, 0xc, 0x3, 0x0, 0xc0, 0x30, + + /* U+005A "Z" */ + 0xff, 0xbf, 0xe0, 0x30, 0x1c, 0xe, 0x7, 0x1, + 0xc0, 0xe0, 0x70, 0x1c, 0xf, 0xff, 0xff, + + /* U+005B "[" */ + 0xff, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xff, + + /* U+005C "\\" */ + 0xe1, 0x86, 0x18, 0x70, 0xc3, 0xe, 0x18, 0x61, + 0xc3, + + /* U+005D "]" */ + 0xff, 0x33, 0x33, 0x33, 0x33, 0x33, 0xff, + + /* U+005E "^" */ + 0x18, 0x78, 0xf3, 0x36, 0x60, + + /* U+005F "_" */ + 0xff, 0xff, + + /* U+0060 "`" */ + 0xdd, 0x80, + + /* U+0061 "a" */ + 0x3c, 0x7e, 0x43, 0x3, 0x3f, 0xff, 0xc3, 0xff, + 0x7b, + + /* U+0062 "b" */ + 0xc0, 0x60, 0x30, 0x1b, 0xcf, 0xf7, 0x1f, 0x7, + 0x83, 0xc1, 0xf1, 0xff, 0xdb, 0xc0, + + /* U+0063 "c" */ + 0x3c, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e, + 0x3c, + + /* U+0064 "d" */ + 0x1, 0x80, 0xc0, 0x67, 0xb7, 0xff, 0x1f, 0x7, + 0x83, 0xc1, 0xf1, 0xdf, 0xe7, 0xb0, + + /* U+0065 "e" */ + 0x3c, 0x7e, 0xe3, 0xff, 0xff, 0xc0, 0xe3, 0x7e, + 0x3c, + + /* U+0066 "f" */ + 0x0, 0xf7, 0xd8, 0xff, 0xf6, 0x18, 0x61, 0x86, + 0x18, 0x60, + + /* U+0067 "g" */ + 0x3d, 0xbf, 0xf8, 0xf8, 0x3c, 0x1e, 0xf, 0x8e, + 0xff, 0x3d, 0x80, 0xf8, 0xef, 0xe3, 0xe0, + + /* U+0068 "h" */ + 0xc0, 0xc0, 0xc0, 0xde, 0xff, 0xe3, 0xc3, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, + + /* U+0069 "i" */ + 0x5c, 0xf, 0xff, 0xff, 0xfe, + + /* U+006A "j" */ + 0x11, 0xc0, 0x1, 0x8c, 0x63, 0x18, 0xc6, 0x31, + 0x8c, 0x7f, 0xf0, + + /* U+006B "k" */ + 0xc0, 0xc0, 0xc0, 0xce, 0xdc, 0xf8, 0xf0, 0xf8, + 0xd8, 0xdc, 0xce, 0xc7, + + /* U+006C "l" */ + 0xdb, 0x6d, 0xb6, 0xdb, 0xb0, + + /* U+006D "m" */ + 0xde, 0x7b, 0xff, 0xfe, 0x38, 0xf0, 0xc3, 0xc3, + 0xf, 0xc, 0x3c, 0x30, 0xf0, 0xc3, 0xc3, 0xc, + + /* U+006E "n" */ + 0xde, 0xff, 0xe3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, + + /* U+006F "o" */ + 0x3e, 0x3f, 0xb8, 0xf8, 0x3c, 0x1e, 0xf, 0x8e, + 0xfe, 0x3e, 0x0, + + /* U+0070 "p" */ + 0xde, 0x7f, 0xb8, 0xf8, 0x3c, 0x1e, 0xf, 0x8f, + 0xfe, 0xde, 0x60, 0x30, 0x18, 0xc, 0x0, + + /* U+0071 "q" */ + 0x3d, 0xbf, 0xf8, 0xf8, 0x3c, 0x1e, 0xf, 0x8e, + 0xff, 0x3d, 0x80, 0xc0, 0x60, 0x30, 0x18, + + /* U+0072 "r" */ + 0xdf, 0xfe, 0x30, 0xc3, 0xc, 0x30, 0xc0, + + /* U+0073 "s" */ + 0x79, 0xff, 0x1f, 0x7, 0xc1, 0xf1, 0xff, 0x7c, + + /* U+0074 "t" */ + 0x30, 0xc3, 0x3f, 0xfc, 0xc3, 0xc, 0x30, 0xc3, + 0xc7, + + /* U+0075 "u" */ + 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xff, + 0x7b, + + /* U+0076 "v" */ + 0xe1, 0x98, 0x66, 0x39, 0xcc, 0x33, 0xf, 0x81, + 0xe0, 0x78, 0x1c, 0x0, + + /* U+0077 "w" */ + 0xe3, 0x8d, 0x8e, 0x76, 0x79, 0xdd, 0xe6, 0x36, + 0xd8, 0xd3, 0xe3, 0xcf, 0x7, 0x1c, 0x1c, 0x70, + + /* U+0078 "x" */ + 0x63, 0x9c, 0xc3, 0xf0, 0x78, 0x1c, 0x7, 0x83, + 0xf1, 0xcc, 0xe3, 0x80, + + /* U+0079 "y" */ + 0xe1, 0xd8, 0x67, 0x39, 0xcc, 0x33, 0xf, 0xc1, + 0xe0, 0x78, 0x1c, 0x3, 0x1, 0xc0, 0x60, 0x38, + 0x0, + + /* U+007A "z" */ + 0xff, 0xff, 0xe, 0x1c, 0x3c, 0x38, 0x70, 0xff, + 0xff, + + /* U+007B "{" */ + 0x0, 0x73, 0xcc, 0x30, 0xc3, 0x38, 0xe0, 0xc3, + 0xc, 0x30, 0xf1, 0xc0, + + /* U+007C "|" */ + 0xff, 0xff, 0xff, 0xf0, + + /* U+007D "}" */ + 0x83, 0x8f, 0xc, 0x30, 0xc3, 0x7, 0x1c, 0xc3, + 0xc, 0x33, 0xce, 0x0, + + /* U+007E "~" */ + 0x39, 0xbf, 0xd9, 0xc0, + + /* U+007F "" */ + 0x0, + + /* U+4E00 "一" */ + 0xff, 0xff, 0xff, 0xf0, + + /* U+518D "再" */ + 0xff, 0xfc, 0xc, 0x0, 0x30, 0x1f, 0xfe, 0x63, + 0x19, 0x8c, 0x67, 0xff, 0x98, 0xc6, 0x63, 0x1b, + 0xff, 0xff, 0xff, 0xd8, 0x6, 0x60, 0xf9, 0x83, + 0xc0, + + /* U+59CB "始" */ + 0x20, 0x60, 0xc1, 0x83, 0xf7, 0x67, 0xec, 0xe6, + 0xff, 0xcd, 0xff, 0xdb, 0x1, 0x6c, 0xfe, 0xf9, + 0xfc, 0xf3, 0x18, 0xf6, 0x33, 0x6f, 0xee, 0x1f, + 0xc8, 0x31, 0x80, + + /* U+5C40 "局" */ + 0x7f, 0xf9, 0x80, 0x66, 0x1, 0x9f, 0xfe, 0x60, + 0x1, 0xff, 0xf7, 0xff, 0xd8, 0x3, 0x6f, 0xcd, + 0xa3, 0x36, 0x8c, 0xf3, 0xf3, 0xc0, 0x1a, 0x3, + 0xe0, + + /* U+5F00 "开" */ + 0x7f, 0xf9, 0xff, 0xe1, 0x86, 0x6, 0x18, 0x18, + 0x60, 0x61, 0x8f, 0xff, 0xff, 0xff, 0x18, 0x60, + 0x61, 0x81, 0x86, 0xc, 0x18, 0x70, 0x61, 0x81, + 0x80, + + /* U+620F "戏" */ + 0x1, 0xa0, 0x6, 0xcf, 0xdb, 0x3f, 0x66, 0xd, + 0xff, 0x3f, 0xf7, 0xb8, 0x1e, 0x66, 0x38, 0xf8, + 0xe3, 0xc7, 0xce, 0x9b, 0x73, 0xeb, 0xef, 0x9, + 0xf0, 0x3, 0x80, + + /* U+6765 "来" */ + 0x3, 0x0, 0xc, 0x7, 0xff, 0x9f, 0xfe, 0x23, + 0x10, 0xcc, 0xc1, 0x36, 0x3f, 0xff, 0xff, 0xfc, + 0x1e, 0x1, 0xfe, 0xe, 0xdc, 0xf3, 0x3f, 0xc, + 0x30, 0x30, 0x0, + + /* U+6E38 "游" */ + 0x2, 0x0, 0xcc, 0x61, 0xcc, 0xf9, 0x7f, 0xf0, + 0xfe, 0xd, 0x8f, 0xdf, 0xef, 0x97, 0xc7, 0xd, + 0x9c, 0x5b, 0xfc, 0xf7, 0xfb, 0x6c, 0xc6, 0xd9, + 0x8f, 0xb3, 0x37, 0xee, 0x0, + + /* U+FF5E "~" */ + 0x39, 0x9f, 0xe6, 0x70 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 92, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 82, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4, .adv_w = 109, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 9}, + {.bitmap_index = 8, .adv_w = 191, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 23, .adv_w = 158, .box_w = 9, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40, .adv_w = 228, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 61, .adv_w = 197, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 79, .adv_w = 58, .box_w = 2, .box_h = 5, .ofs_x = 1, .ofs_y = 9}, + {.bitmap_index = 81, .adv_w = 93, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 88, .adv_w = 93, .box_w = 4, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95, .adv_w = 115, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 99, .adv_w = 165, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 107, .adv_w = 77, .box_w = 2, .box_h = 5, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 109, .adv_w = 104, .box_w = 5, .box_h = 2, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 111, .adv_w = 74, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 112, .adv_w = 115, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 121, .adv_w = 171, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 135, .adv_w = 124, .box_w = 5, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 143, .adv_w = 157, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 155, .adv_w = 160, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 169, .adv_w = 164, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 183, .adv_w = 162, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 195, .adv_w = 167, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 209, .adv_w = 146, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 221, .adv_w = 172, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 235, .adv_w = 166, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 249, .adv_w = 74, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 252, .adv_w = 77, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 255, .adv_w = 165, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 265, .adv_w = 165, .box_w = 8, .box_h = 6, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 271, .adv_w = 165, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 281, .adv_w = 140, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 293, .adv_w = 223, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 313, .adv_w = 193, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 331, .adv_w = 184, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 345, .adv_w = 190, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 360, .adv_w = 201, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 375, .adv_w = 162, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 389, .adv_w = 156, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 401, .adv_w = 196, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 416, .adv_w = 200, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 431, .adv_w = 74, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 434, .adv_w = 143, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 445, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 460, .adv_w = 157, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 474, .adv_w = 240, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 494, .adv_w = 198, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 509, .adv_w = 209, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 526, .adv_w = 176, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 540, .adv_w = 209, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 558, .adv_w = 176, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 573, .adv_w = 169, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 587, .adv_w = 167, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 602, .adv_w = 193, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 617, .adv_w = 194, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 635, .adv_w = 281, .box_w = 17, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 661, .adv_w = 193, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 679, .adv_w = 187, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 694, .adv_w = 169, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 709, .adv_w = 95, .box_w = 4, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 716, .adv_w = 100, .box_w = 6, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 725, .adv_w = 95, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 732, .adv_w = 124, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 9}, + {.bitmap_index = 737, .adv_w = 121, .box_w = 8, .box_h = 2, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 739, .adv_w = 82, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 10}, + {.bitmap_index = 741, .adv_w = 148, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 750, .adv_w = 165, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 764, .adv_w = 151, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 773, .adv_w = 165, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 787, .adv_w = 157, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 796, .adv_w = 105, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 806, .adv_w = 165, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 821, .adv_w = 159, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 833, .adv_w = 74, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 838, .adv_w = 75, .box_w = 5, .box_h = 17, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 849, .adv_w = 155, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 861, .adv_w = 74, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 866, .adv_w = 239, .box_w = 14, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 882, .adv_w = 159, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 891, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 902, .adv_w = 165, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 917, .adv_w = 165, .box_w = 9, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 932, .adv_w = 116, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 939, .adv_w = 137, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 947, .adv_w = 109, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 956, .adv_w = 159, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 965, .adv_w = 155, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 977, .adv_w = 230, .box_w = 14, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 993, .adv_w = 155, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1005, .adv_w = 158, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 1022, .adv_w = 138, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1031, .adv_w = 101, .box_w = 6, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1043, .adv_w = 67, .box_w = 2, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1047, .adv_w = 101, .box_w = 6, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1059, .adv_w = 156, .box_w = 9, .box_h = 3, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 1063, .adv_w = 0, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1064, .adv_w = 256, .box_w = 14, .box_h = 2, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 1068, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1093, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1120, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1145, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1170, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1197, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1224, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1253, .adv_w = 256, .box_w = 10, .box_h = 3, .ofs_x = 3, .ofs_y = 5} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x38d, 0xbcb, 0xe40, 0x1100, 0x140f, 0x1965, 0x2038, + 0xb15e +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 96, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 19968, .range_length = 45407, .glyph_id_start = 97, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 9, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = +{ + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 2, 0, 2, + 3, 4, 0, 5, 6, 7, 0, 8, + 9, 10, 11, 0, 0, 0, 0, 0, + 0, 0, 12, 13, 14, 15, 16, 17, + 18, 0, 0, 19, 20, 21, 0, 0, + 15, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, + 33, 0, 34, 35, 36, 0, 37, 38, + 39, 34, 0, 0, 40, 41, 34, 34, + 35, 35, 39, 42, 43, 44, 39, 45, + 46, 47, 45, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = +{ + 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 2, 0, 2, + 3, 4, 5, 6, 7, 8, 0, 9, + 10, 11, 12, 0, 0, 0, 0, 0, + 0, 0, 13, 0, 14, 0, 0, 0, + 14, 0, 0, 15, 0, 0, 0, 0, + 14, 0, 14, 0, 16, 17, 18, 19, + 20, 21, 22, 23, 0, 0, 0, 0, + 0, 0, 24, 0, 25, 25, 25, 26, + 25, 0, 0, 27, 0, 28, 29, 29, + 25, 29, 25, 29, 30, 31, 32, 33, + 34, 35, 33, 36, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, -9, 0, + -20, -5, -18, -10, 0, -26, 0, -7, + -6, -4, 0, -6, 0, 0, -7, 0, + -17, -10, 0, 0, 0, 0, 0, 0, + -19, 0, 0, -8, 0, 0, 0, -14, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -19, + -13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -3, 0, 0, -5, -6, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, 0, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -5, 0, + 0, -7, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, -9, 0, -3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -33, -20, -4, 0, 0, 0, -18, + -16, 0, -5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -22, -13, 0, 0, 0, 0, -6, + -3, 0, -5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, -34, -4, -29, -19, + 0, -30, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, -12, -6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + -6, 0, -6, -5, -5, -9, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, -1, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, -4, 0, 0, 0, + -8, -3, -3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, -5, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, -10, 0, + -8, 0, -9, -4, -13, -13, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -3, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, -3, 0, 0, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -16, 0, -35, -3, + 0, 0, 0, 0, -5, 0, 0, -14, + -4, 0, 0, 0, 0, 0, 0, -5, + -3, -3, -10, -3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, 0, 0, 0, -8, 0, -10, -4, + -7, -16, -3, 0, 0, 0, 0, 0, + 0, -2, 0, 0, -7, -8, -5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -16, -16, -8, 0, -13, 0, 0, + 0, 0, 0, -8, -14, 0, 0, 0, + 0, -3, -13, -13, -20, -16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -10, 0, 0, + -35, -5, -31, -21, 0, -35, 0, 0, + 0, -5, 0, 0, 0, 0, -15, -4, + -22, -13, 0, 0, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -22, 0, -48, 0, -5, 0, -9, -7, + -15, -13, -5, -14, -13, 0, 0, 0, + 0, -10, 0, -10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -7, 0, 0, 0, + -8, 0, -6, -6, -11, -13, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, -8, 0, -5, 0, -5, -3, + 0, -8, 0, -4, -5, 0, 0, 0, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, 0, -3, 0, -7, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, -5, -3, -4, -15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -34, -9, -46, -7, 0, 0, 0, 0, + -9, 0, 0, -26, -26, -13, 0, 0, + -23, -33, -5, -26, -28, -26, -28, -29, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, -4, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -29, -9, -39, -3, 0, 0, 0, 0, + 0, 0, 0, -22, -20, -9, 0, 0, + -20, -19, -5, -19, -8, -8, -10, -11, + -10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -19, -4, -22, -2, + 0, 0, 0, 0, 0, 0, 0, -13, + -11, -5, 0, 0, -12, -12, -3, -11, + -8, -8, -10, -10, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 0, -3, -9, -5, 0, 0, + 0, 0, 0, -2, -10, -5, 0, -2, + -4, -8, -13, -11, -21, -18, 0, 0, + -20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -30, -13, -42, -8, + 0, 0, 0, 0, 0, 0, 0, -39, + -36, -13, 0, 0, -38, -33, -15, -36, + -26, -25, -26, -28, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, -7, -8, -11, -10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 22, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -24, 0, -22, -13, + -5, -40, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, -3, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + -26, 0, -20, -11, -10, -36, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, -3, -11, -3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -26, 0, -12, -9, + -5, -31, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -7, 0, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -26, 0, -16, -9, -8, -29, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, -1, -3, 0, -6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -15, 0, -16, 0, 0, 0, 0, 0, + 0, 0, 0, -6, -5, 0, 0, 0, + 0, -4, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -23, 0, -20, -14, 0, -36, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, 0, -38, -3, -12, -8, + 0, -20, 0, -4, -10, 0, 0, -2, + 0, -4, -4, -6, 0, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -3, + -2, -2, 0, 0, -13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -23, 0, 0, 0, + -22, -18, -13, -6, -5, 0, 0, 0, + 0, -4, 0, -6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32, 0, -13, -10, -8, -30, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, -6, -3, + 0, -13, 0, 0, -3, 0, 0, 0, + 0, -2, 0, -1, 0, 0, 0, 0, + -10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -12, 0, -25, 0, + -28, 0, -8, -8, -21, -26, -13, -4, + -6, 0, 0, 0, 0, -3, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -6, 0, -16, 0, -26, 0, -8, -8, + -18, -25, -10, -3, -3, 0, 0, 0, + 0, -3, 0, 0, 0, 0, 0, 0, + -3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, 0, + -28, 0, -10, -10, 0, -26, 0, -4, + -11, 0, 0, -3, 0, -6, 0, -3, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 0, 0, -28, 0, -8, -12, + 0, -28, 0, 0, -6, 0, 0, 0, + 0, -3, 0, -2, 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = +{ + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 48, + .right_class_cnt = 36, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_classes, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 1, + .kern_classes = 1, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t MiSans_Semibold = { +#else +lv_font_t MiSans_Semibold = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 18, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if MISANS-SEMIBOLD*/ + diff --git a/Whackmole/pic/MiSans_Semibold.h b/Whackmole/pic/MiSans_Semibold.h new file mode 100644 index 0000000000000000000000000000000000000000..e773feddc0bf86e69be4735c867a2e43bd9363af --- /dev/null +++ b/Whackmole/pic/MiSans_Semibold.h @@ -0,0 +1,16 @@ +#ifndef SEM_H +#define SEM_H + +#include "lvgl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_font_t MiSans_Semibold; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Whackmole/pic/fonts/MiSans-Normal.ttf b/Whackmole/pic/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/Whackmole/pic/fonts/MiSans-Normal.ttf differ diff --git a/Whackmole/pic/fonts/MiSans-Semibold.ttf b/Whackmole/pic/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/Whackmole/pic/fonts/MiSans-Semibold.ttf differ diff --git a/Whackmole/pic/grassland.c b/Whackmole/pic/grassland.c new file mode 100644 index 0000000000000000000000000000000000000000..1354f9ad51bdf878a6bfeb4d6d70394acbd18370 --- /dev/null +++ b/Whackmole/pic/grassland.c @@ -0,0 +1,274 @@ +#ifdef __has_include + #if __has_include("lvgl.h") + #ifndef LV_LVGL_H_INCLUDE_SIMPLE + #define LV_LVGL_H_INCLUDE_SIMPLE + #endif + #endif +#endif + +#if defined(LV_LVGL_H_INCLUDE_SIMPLE) + #include "lvgl.h" +#else + #include "lvgl/lvgl.h" +#endif + + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMAGE_GRASSLAND +#define LV_ATTRIBUTE_IMAGE_GRASSLAND +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_GRASSLAND uint8_t grassland_map[] = { + 0x03, 0x36, 0x19, 0xff, 0x06, 0x4c, 0x23, 0xff, 0x0a, 0x56, 0x29, 0xff, 0x09, 0x52, 0x27, 0xff, 0x01, 0x3a, 0x19, 0xff, 0x02, 0x29, 0x15, 0xff, 0x02, 0x25, 0x13, 0xff, 0x03, 0x25, 0x11, 0xff, 0x06, 0x27, 0x11, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x08, 0x3e, 0x24, 0xff, 0x0d, 0x41, 0x27, 0xff, 0x03, 0x2d, 0x14, 0xff, 0x01, 0x27, 0x10, 0xff, 0x03, 0x39, 0x1b, 0xff, 0x08, 0x57, 0x2c, 0xff, 0x09, 0x56, 0x2d, 0xff, 0x0c, 0x52, 0x2e, 0xff, 0x03, 0x3e, 0x1f, 0xff, 0x02, 0x30, 0x16, 0xff, 0x02, 0x2b, 0x12, 0xff, 0x03, 0x29, 0x12, 0xff, 0x02, 0x29, 0x12, 0xff, 0x01, 0x27, 0x0f, 0xff, 0x03, 0x28, 0x12, 0xff, 0x00, 0x38, 0x17, 0xff, 0x04, 0x50, 0x27, 0xff, 0x09, 0x49, 0x28, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x03, 0x34, 0x18, 0xff, 0x06, 0x48, 0x24, 0xff, 0x08, 0x54, 0x2a, 0xff, 0x04, 0x59, 0x29, 0xff, 0x01, 0x5c, 0x29, 0xff, 0x09, 0x5c, 0x2d, 0xff, 0x06, 0x47, 0x24, 0xff, 0x00, 0x2e, 0x13, 0xff, 0x00, 0x24, 0x10, 0xff, 0x00, 0x26, 0x11, 0xff, 0x00, 0x28, 0x0e, 0xff, 0x01, 0x27, 0x11, 0xff, 0x04, 0x26, 0x13, 0xff, 0x03, 0x25, 0x15, 0xff, 0x01, 0x24, 0x12, 0xff, 0x00, 0x27, 0x10, 0xff, 0x00, 0x2b, 0x0e, 0xff, 0x05, 0x36, 0x19, 0xff, 0x04, 0x32, 0x19, 0xff, 0x00, 0x2a, 0x14, 0xff, 0x01, 0x27, 0x16, 0xff, 0x03, 0x27, 0x16, 0xff, 0x00, 0x26, 0x14, 0xff, 0x00, 0x28, 0x13, 0xff, 0x00, 0x2d, 0x11, 0xff, 0x00, 0x31, 0x14, 0xff, 0x01, 0x3b, 0x1a, 0xff, 0x02, 0x3d, 0x1c, 0xff, 0x02, 0x3e, 0x1d, 0xff, 0x02, 0x3d, 0x1a, 0xff, 0x02, 0x3b, 0x18, 0xff, 0x01, 0x36, 0x14, 0xff, 0x02, 0x35, 0x13, 0xff, 0x04, 0x39, 0x17, 0xff, 0x09, 0x41, 0x1c, 0xff, 0x09, 0x3c, 0x19, 0xff, 0x05, 0x30, 0x13, 0xff, 0x09, 0x31, 0x18, 0xff, 0x0d, 0x35, 0x1d, 0xff, 0x19, 0x43, 0x33, 0xff, 0x1a, 0x3b, 0x52, 0xff, 0x43, 0x5b, 0x96, 0xff, 0x5b, 0x6e, 0xbf, 0xff, 0x47, 0x5d, 0xac, 0xff, 0x51, 0x65, 0xb4, 0xff, 0x63, 0x72, 0xc2, 0xff, 0x60, 0x6c, 0xb8, 0xff, 0x55, 0x65, 0xa2, 0xff, 0x2e, 0x4c, 0x6a, 0xff, 0x0e, 0x34, 0x3b, 0xff, 0x05, 0x46, 0x2e, 0xff, 0x0f, 0x66, 0x3a, 0xff, 0x04, 0x66, 0x2e, 0xff, 0x06, 0x63, 0x32, 0xff, 0x0b, 0x5f, 0x37, 0xff, 0x08, 0x57, 0x2f, 0xff, 0x03, 0x37, 0x15, 0xff, 0x06, 0x22, 0x08, 0xff, 0x04, 0x22, 0x08, 0xff, 0x06, 0x20, 0x05, 0xff, 0x08, 0x1f, 0x04, 0xff, 0x07, 0x2a, 0x0c, 0xff, 0x0d, 0x47, 0x24, 0xff, 0x07, 0x4d, 0x29, 0xff, 0x10, 0x55, 0x31, 0xff, 0x0c, 0x49, 0x28, 0xff, 0x10, 0x32, 0x1e, 0xff, 0x0f, 0x28, 0x15, 0xff, 0x05, 0x18, 0x05, 0xff, 0x05, 0x18, 0x05, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x1d, 0x07, 0xff, 0x00, 0x1c, 0x05, 0xff, 0x02, 0x1d, 0x06, 0xff, 0x02, 0x22, 0x08, 0xff, 0x02, 0x28, 0x0d, 0xff, 0x08, 0x35, 0x18, 0xff, 0x18, 0x4a, 0x2c, 0xff, 0x16, 0x4c, 0x2c, 0xff, 0x14, 0x4a, 0x28, 0xff, 0x0f, 0x45, 0x23, 0xff, 0x0a, 0x41, 0x1f, 0xff, 0x09, 0x3e, 0x20, 0xff, 0x03, 0x34, 0x17, 0xff, 0x01, 0x30, 0x14, 0xff, 0x03, 0x35, 0x19, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x0b, 0x46, 0x28, 0xff, 0x05, 0x3c, 0x1f, 0xff, 0x01, 0x30, 0x14, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x0e, 0x47, 0x29, 0xff, 0x0c, 0x3b, 0x1e, 0xff, 0x03, 0x2f, 0x12, 0xff, 0x00, 0x2e, 0x10, 0xff, 0x01, 0x39, 0x1b, 0xff, 0x0b, 0x48, 0x29, 0xff, 0x0d, 0x49, 0x2a, 0xff, 0x07, 0x3f, 0x21, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x00, 0x2b, 0x14, 0xff, 0x02, 0x2e, 0x18, 0xff, 0x00, 0x2b, 0x10, 0xff, 0x03, 0x3e, 0x1d, 0xff, 0x0a, 0x54, 0x27, 0xff, 0x06, 0x56, 0x24, 0xff, 0x05, 0x42, 0x1e, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x08, 0x27, 0x15, 0xff, 0x07, 0x25, 0x13, 0xff, 0x01, 0x31, 0x14, 0xff, 0x09, 0x4e, 0x29, 0xff, 0x03, 0x54, 0x2a, 0xff, 0x02, 0x4e, 0x26, 0xff, 0x03, 0x3b, 0x1c, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x00, 0x29, 0x14, 0xff, 0x00, 0x29, 0x16, 0xff, 0x02, 0x28, 0x15, 0xff, 0x03, 0x2c, 0x16, 0xff, 0x0c, 0x44, 0x26, 0xff, 0x0c, 0x53, 0x2e, 0xff, 0x0a, 0x5c, 0x34, 0xff, 0x0b, 0x5d, 0x35, 0xff, 0x08, 0x5c, 0x32, 0xff, 0x09, 0x5f, 0x33, 0xff, 0x08, 0x5e, 0x31, 0xff, 0x07, 0x5d, 0x2e, 0xff, 0x06, 0x5a, 0x2a, 0xff, 0x05, 0x58, 0x27, 0xff, 0x04, 0x58, 0x27, 0xff, 0x05, 0x59, 0x26, 0xff, 0x06, 0x59, 0x26, 0xff, 0x05, 0x57, 0x25, 0xff, 0x05, 0x57, 0x25, 0xff, 0x05, 0x57, 0x25, 0xff, 0x06, 0x57, 0x24, 0xff, 0x05, 0x56, 0x24, 0xff, 0x06, 0x56, 0x24, 0xff, 0x09, 0x56, 0x26, 0xff, 0x09, 0x54, 0x27, 0xff, 0x0c, 0x54, 0x29, 0xff, 0x0f, 0x53, 0x2a, 0xff, 0x0c, 0x4b, 0x26, 0xff, 0x05, 0x41, 0x1f, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x05, 0x3a, 0x20, 0xff, 0x07, 0x35, 0x1f, 0xff, 0x01, 0x27, 0x12, 0xff, 0x03, 0x29, 0x15, 0xff, 0x0a, 0x36, 0x21, 0xff, 0x02, 0x2a, 0x15, 0xff, 0x03, 0x23, 0x10, 0xff, 0x01, 0x24, 0x0f, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x04, 0x37, 0x1c, 0xff, 0x02, 0x25, 0x0f, 0xff, 0x04, 0x21, 0x0d, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x02, 0x42, 0x24, 0xff, 0x0a, 0x5c, 0x36, 0xff, 0x0e, 0x66, 0x39, 0xff, 0x0c, 0x62, 0x36, 0xff, 0x07, 0x5b, 0x36, 0xff, 0x05, 0x58, 0x38, 0xff, 0x05, 0x57, 0x37, 0xff, 0x01, 0x57, 0x30, 0xff, 0x0c, 0x80, 0x4d, 0xff, 0x02, 0x8e, 0x50, 0xff, 0x00, 0x8d, 0x48, 0xff, 0x05, 0x89, 0x47, 0xff, 0x07, 0x86, 0x48, 0xff, 0x03, 0x88, 0x4a, 0xff, 0x05, 0x87, 0x49, 0xff, 0x03, 0x83, 0x46, 0xff, 0x05, 0x7d, 0x47, 0xff, 0x01, 0x45, 0x22, 0xff, 0x02, 0x22, 0x10, 0xff, 0x05, 0x1e, 0x12, 0xff, 0x00, 0x22, 0x0f, 0xff, 0x02, 0x2f, 0x18, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x05, 0x46, 0x28, 0xff, 0x07, 0x45, 0x25, 0xff, 0x07, 0x49, 0x29, 0xff, 0x0b, 0x50, 0x30, 0xff, 0x00, 0x2c, 0x0f, 0xff, 0x06, 0x3c, 0x1f, 0xff, 0x0f, 0x49, 0x2f, 0xff, 0x05, 0x2f, 0x1a, 0xff, 0x00, 0x1f, 0x0a, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x0c, 0x3a, 0x22, 0xff, 0x09, 0x2d, 0x1a, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x01, 0x21, 0x10, 0xff, 0x01, 0x20, 0x0d, 0xff, 0x00, 0x25, 0x0e, 0xff, 0x04, 0x3e, 0x23, 0xff, 0x08, 0x46, 0x2a, 0xff, 0x01, 0x2d, 0x15, 0xff, 0x01, 0x22, 0x0f, 0xff, 0x01, 0x20, 0x0f, 0xff, 0x02, 0x27, 0x12, 0xff, 0x08, 0x42, 0x28, 0xff, 0x03, 0x37, 0x1c, 0xff, 0x05, 0x36, 0x1b, 0xff, 0x08, 0x4a, 0x28, 0xff, 0x0b, 0x5b, 0x34, 0xff, 0x0d, 0x62, 0x37, 0xff, 0x04, 0x5f, 0x32, 0xff, 0x07, 0x67, 0x35, 0xff, 0x0d, 0x68, 0x39, 0xff, 0x0c, 0x5f, 0x33, 0xff, 0x02, 0x45, 0x1e, 0xff, 0x04, 0x3e, 0x1c, 0xff, 0x12, 0x44, 0x2a, 0xff, 0x07, 0x32, 0x1c, 0xff, 0x00, 0x25, 0x13, 0xff, 0x02, 0x31, 0x1b, 0xff, 0x07, 0x3c, 0x24, 0xff, 0x03, 0x35, 0x1d, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x01, 0x29, 0x12, 0xff, 0x03, 0x37, 0x1f, 0xff, 0x06, 0x3c, 0x23, 0xff, 0x08, 0x36, 0x1f, 0xff, 0x02, 0x32, 0x1a, 0xff, 0x09, 0x38, 0x20, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x05, 0x34, 0x1e, 0xff, 0x05, 0x3a, 0x22, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x03, 0x41, 0x21, 0xff, 0x0d, 0x4a, 0x29, 0xff, 0x09, 0x40, 0x21, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x03, 0x35, 0x1d, 0xff, 0x00, 0x29, 0x16, 0xff, 0x02, 0x2e, 0x1a, 0xff, 0x06, 0x3c, 0x24, 0xff, 0x02, 0x33, 0x1d, 0xff, 0x00, 0x21, 0x10, 0xff, 0x01, 0x22, 0x0f, 0xff, 0x08, 0x33, 0x1e, 0xff, 0x0c, 0x3a, 0x24, 0xff, 0x02, 0x25, 0x11, 0xff, 0x03, 0x26, 0x10, 0xff, 0x05, 0x36, 0x1c, 0xff, 0x0d, 0x4d, 0x2d, 0xff, 0x05, 0x4b, 0x29, 0xff, 0x03, 0x50, 0x2b, 0xff, 0x07, 0x40, 0x22, 0xff, 0x05, 0x27, 0x12, 0xff, 0x06, 0x23, 0x13, 0xff, 0x02, 0x25, 0x13, 0xff, 0x00, 0x26, 0x10, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x00, 0x28, 0x10, 0xff, 0x00, 0x31, 0x11, 0xff, 0x08, 0x52, 0x2a, 0xff, 0x0e, 0x66, 0x39, 0xff, 0x09, 0x69, 0x37, 0xff, 0x03, 0x63, 0x32, 0xff, 0x0a, 0x5d, 0x32, 0xff, 0x0c, 0x53, 0x30, 0xff, 0x05, 0x3e, 0x23, 0xff, 0x01, 0x32, 0x2a, 0xff, 0x1d, 0x4b, 0x66, 0xff, 0x35, 0x5c, 0x8f, 0xff, 0x2f, 0x57, 0x93, 0xff, 0x1b, 0x48, 0x77, 0xff, 0x0f, 0x42, 0x58, 0xff, 0x17, 0x49, 0x49, 0xff, 0x04, 0x2f, 0x1b, 0xff, 0x04, 0x2f, 0x12, 0xff, 0x17, 0x4d, 0x2f, 0xff, 0x15, 0x51, 0x34, 0xff, 0x03, 0x27, 0x17, 0xff, 0x04, 0x24, 0x16, 0xff, 0x06, 0x40, 0x28, 0xff, 0x12, 0x4c, 0x30, 0xff, 0x08, 0x3b, 0x28, 0xff, 0x02, 0x2f, 0x1f, 0xff, 0x05, 0x31, 0x1b, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x02, 0x29, 0x15, 0xff, 0x02, 0x26, 0x16, 0xff, 0x02, 0x2e, 0x15, 0xff, 0x0d, 0x4a, 0x2c, 0xff, 0x67, 0x91, 0x7f, 0xff, + 0x03, 0x33, 0x17, 0xff, 0x06, 0x4d, 0x23, 0xff, 0x08, 0x56, 0x27, 0xff, 0x0a, 0x50, 0x26, 0xff, 0x01, 0x37, 0x16, 0xff, 0x04, 0x27, 0x15, 0xff, 0x03, 0x24, 0x13, 0xff, 0x04, 0x24, 0x11, 0xff, 0x07, 0x25, 0x11, 0xff, 0x02, 0x2d, 0x15, 0xff, 0x09, 0x40, 0x25, 0xff, 0x0e, 0x42, 0x28, 0xff, 0x03, 0x2c, 0x13, 0xff, 0x02, 0x27, 0x11, 0xff, 0x02, 0x36, 0x18, 0xff, 0x09, 0x56, 0x2a, 0xff, 0x0b, 0x55, 0x2d, 0xff, 0x0b, 0x4e, 0x2b, 0xff, 0x02, 0x39, 0x1b, 0xff, 0x03, 0x2e, 0x15, 0xff, 0x04, 0x28, 0x11, 0xff, 0x07, 0x28, 0x12, 0xff, 0x04, 0x28, 0x12, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x28, 0x11, 0xff, 0x00, 0x3e, 0x1c, 0xff, 0x05, 0x55, 0x2b, 0xff, 0x07, 0x44, 0x23, 0xff, 0x00, 0x24, 0x0d, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x06, 0x4a, 0x25, 0xff, 0x07, 0x54, 0x29, 0xff, 0x03, 0x5a, 0x29, 0xff, 0x03, 0x5d, 0x29, 0xff, 0x0a, 0x5b, 0x2c, 0xff, 0x04, 0x3e, 0x1c, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x02, 0x22, 0x11, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x28, 0x0e, 0xff, 0x01, 0x27, 0x10, 0xff, 0x04, 0x25, 0x12, 0xff, 0x03, 0x25, 0x14, 0xff, 0x00, 0x27, 0x12, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x06, 0x34, 0x18, 0xff, 0x0c, 0x3e, 0x21, 0xff, 0x01, 0x2d, 0x15, 0xff, 0x00, 0x28, 0x13, 0xff, 0x02, 0x27, 0x17, 0xff, 0x02, 0x26, 0x16, 0xff, 0x02, 0x28, 0x15, 0xff, 0x00, 0x2b, 0x14, 0xff, 0x01, 0x30, 0x14, 0xff, 0x01, 0x38, 0x1a, 0xff, 0x01, 0x3c, 0x1d, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x04, 0x3c, 0x1d, 0xff, 0x04, 0x39, 0x19, 0xff, 0x01, 0x30, 0x11, 0xff, 0x07, 0x33, 0x13, 0xff, 0x1d, 0x4a, 0x29, 0xff, 0x1b, 0x4a, 0x29, 0xff, 0x0d, 0x3f, 0x1d, 0xff, 0x05, 0x34, 0x12, 0xff, 0x01, 0x2a, 0x0f, 0xff, 0x04, 0x2c, 0x14, 0xff, 0x09, 0x34, 0x1c, 0xff, 0x15, 0x42, 0x33, 0xff, 0x12, 0x3a, 0x52, 0xff, 0x38, 0x56, 0x92, 0xff, 0x54, 0x66, 0xb9, 0xff, 0x40, 0x53, 0xa6, 0xff, 0x6f, 0x80, 0xd5, 0xff, 0x70, 0x7d, 0xd9, 0xff, 0x75, 0x7b, 0xdc, 0xff, 0x7f, 0x87, 0xe1, 0xff, 0x63, 0x7a, 0xb9, 0xff, 0x3c, 0x5d, 0x85, 0xff, 0x0c, 0x3c, 0x39, 0xff, 0x0c, 0x55, 0x38, 0xff, 0x08, 0x65, 0x33, 0xff, 0x07, 0x62, 0x32, 0xff, 0x0b, 0x5f, 0x38, 0xff, 0x09, 0x58, 0x31, 0xff, 0x03, 0x35, 0x15, 0xff, 0x08, 0x21, 0x08, 0xff, 0x06, 0x20, 0x07, 0xff, 0x06, 0x1f, 0x05, 0xff, 0x07, 0x22, 0x06, 0xff, 0x0e, 0x38, 0x18, 0xff, 0x09, 0x4d, 0x29, 0xff, 0x04, 0x53, 0x2c, 0xff, 0x12, 0x5b, 0x36, 0xff, 0x0a, 0x48, 0x26, 0xff, 0x0e, 0x34, 0x1e, 0xff, 0x10, 0x2b, 0x17, 0xff, 0x06, 0x19, 0x07, 0xff, 0x03, 0x17, 0x04, 0xff, 0x02, 0x1b, 0x07, 0xff, 0x06, 0x27, 0x10, 0xff, 0x06, 0x26, 0x10, 0xff, 0x07, 0x24, 0x0e, 0xff, 0x02, 0x23, 0x09, 0xff, 0x03, 0x2b, 0x0f, 0xff, 0x04, 0x30, 0x13, 0xff, 0x0f, 0x3f, 0x21, 0xff, 0x14, 0x46, 0x26, 0xff, 0x17, 0x46, 0x26, 0xff, 0x13, 0x43, 0x21, 0xff, 0x10, 0x42, 0x20, 0xff, 0x0e, 0x43, 0x24, 0xff, 0x0e, 0x41, 0x23, 0xff, 0x07, 0x35, 0x19, 0xff, 0x01, 0x30, 0x14, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x07, 0x44, 0x25, 0xff, 0x0c, 0x43, 0x27, 0xff, 0x06, 0x37, 0x1c, 0xff, 0x01, 0x30, 0x14, 0xff, 0x0b, 0x3f, 0x23, 0xff, 0x11, 0x42, 0x27, 0xff, 0x08, 0x35, 0x1a, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x07, 0x3c, 0x20, 0xff, 0x0d, 0x48, 0x2c, 0xff, 0x0b, 0x48, 0x29, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x02, 0x2e, 0x15, 0xff, 0x06, 0x2c, 0x17, 0xff, 0x04, 0x2b, 0x13, 0xff, 0x01, 0x30, 0x13, 0xff, 0x0b, 0x4e, 0x23, 0xff, 0x08, 0x57, 0x25, 0xff, 0x07, 0x4a, 0x23, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x09, 0x24, 0x14, 0xff, 0x05, 0x24, 0x11, 0xff, 0x02, 0x3a, 0x1c, 0xff, 0x07, 0x54, 0x2c, 0xff, 0x05, 0x51, 0x28, 0xff, 0x07, 0x44, 0x21, 0xff, 0x04, 0x2b, 0x14, 0xff, 0x04, 0x25, 0x12, 0xff, 0x01, 0x28, 0x12, 0xff, 0x00, 0x29, 0x10, 0xff, 0x06, 0x36, 0x19, 0xff, 0x13, 0x4d, 0x2d, 0xff, 0x14, 0x58, 0x37, 0xff, 0x0e, 0x5a, 0x37, 0xff, 0x0a, 0x5c, 0x35, 0xff, 0x0b, 0x5e, 0x34, 0xff, 0x0a, 0x5d, 0x33, 0xff, 0x0a, 0x5d, 0x32, 0xff, 0x08, 0x5b, 0x30, 0xff, 0x07, 0x5a, 0x2c, 0xff, 0x08, 0x59, 0x2a, 0xff, 0x07, 0x57, 0x28, 0xff, 0x08, 0x58, 0x28, 0xff, 0x08, 0x59, 0x27, 0xff, 0x08, 0x59, 0x27, 0xff, 0x08, 0x58, 0x25, 0xff, 0x07, 0x57, 0x25, 0xff, 0x08, 0x58, 0x25, 0xff, 0x09, 0x57, 0x25, 0xff, 0x09, 0x56, 0x25, 0xff, 0x09, 0x57, 0x25, 0xff, 0x07, 0x58, 0x25, 0xff, 0x08, 0x56, 0x25, 0xff, 0x09, 0x54, 0x27, 0xff, 0x0d, 0x53, 0x29, 0xff, 0x0e, 0x51, 0x2a, 0xff, 0x0c, 0x4c, 0x27, 0xff, 0x06, 0x44, 0x21, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x04, 0x36, 0x1e, 0xff, 0x02, 0x29, 0x14, 0xff, 0x01, 0x27, 0x12, 0xff, 0x0a, 0x35, 0x22, 0xff, 0x05, 0x2b, 0x18, 0xff, 0x03, 0x23, 0x11, 0xff, 0x01, 0x26, 0x11, 0xff, 0x05, 0x34, 0x1d, 0xff, 0x07, 0x35, 0x1e, 0xff, 0x01, 0x23, 0x0f, 0xff, 0x01, 0x26, 0x10, 0xff, 0x02, 0x3b, 0x1f, 0xff, 0x07, 0x55, 0x30, 0xff, 0x0a, 0x67, 0x39, 0xff, 0x0c, 0x6a, 0x36, 0xff, 0x0c, 0x65, 0x33, 0xff, 0x0a, 0x60, 0x37, 0xff, 0x0a, 0x5d, 0x39, 0xff, 0x0a, 0x5a, 0x38, 0xff, 0x01, 0x56, 0x2f, 0xff, 0x0e, 0x7f, 0x4e, 0xff, 0x04, 0x8f, 0x52, 0xff, 0x01, 0x8c, 0x4a, 0xff, 0x08, 0x87, 0x48, 0xff, 0x0b, 0x85, 0x49, 0xff, 0x03, 0x87, 0x4a, 0xff, 0x06, 0x88, 0x4a, 0xff, 0x03, 0x85, 0x48, 0xff, 0x05, 0x83, 0x4b, 0xff, 0x05, 0x54, 0x30, 0xff, 0x01, 0x25, 0x14, 0xff, 0x04, 0x1c, 0x15, 0xff, 0x00, 0x21, 0x10, 0xff, 0x01, 0x2f, 0x18, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x05, 0x46, 0x27, 0xff, 0x05, 0x45, 0x24, 0xff, 0x07, 0x4f, 0x2e, 0xff, 0x0d, 0x58, 0x36, 0xff, 0x00, 0x2c, 0x0f, 0xff, 0x06, 0x3a, 0x1e, 0xff, 0x0f, 0x48, 0x2f, 0xff, 0x05, 0x2f, 0x19, 0xff, 0x00, 0x20, 0x0b, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x0b, 0x3d, 0x23, 0xff, 0x0c, 0x32, 0x1e, 0xff, 0x01, 0x1d, 0x0d, 0xff, 0x02, 0x1f, 0x10, 0xff, 0x02, 0x1f, 0x0d, 0xff, 0x00, 0x26, 0x10, 0xff, 0x03, 0x3f, 0x23, 0xff, 0x07, 0x45, 0x29, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x02, 0x21, 0x0f, 0xff, 0x01, 0x1f, 0x0e, 0xff, 0x01, 0x26, 0x11, 0xff, 0x0d, 0x42, 0x2a, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x05, 0x32, 0x18, 0xff, 0x07, 0x43, 0x23, 0xff, 0x0b, 0x59, 0x31, 0xff, 0x0e, 0x62, 0x37, 0xff, 0x03, 0x5e, 0x2f, 0xff, 0x03, 0x62, 0x30, 0xff, 0x0e, 0x6a, 0x3a, 0xff, 0x11, 0x66, 0x39, 0xff, 0x08, 0x52, 0x29, 0xff, 0x02, 0x3c, 0x18, 0xff, 0x0e, 0x3f, 0x24, 0xff, 0x0e, 0x38, 0x22, 0xff, 0x02, 0x25, 0x14, 0xff, 0x02, 0x2f, 0x19, 0xff, 0x09, 0x3c, 0x25, 0xff, 0x07, 0x36, 0x1f, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x04, 0x2c, 0x16, 0xff, 0x05, 0x38, 0x20, 0xff, 0x07, 0x3b, 0x24, 0xff, 0x08, 0x33, 0x1d, 0xff, 0x02, 0x31, 0x19, 0xff, 0x0a, 0x37, 0x20, 0xff, 0x06, 0x2f, 0x19, 0xff, 0x05, 0x2f, 0x1a, 0xff, 0x07, 0x39, 0x21, 0xff, 0x03, 0x3c, 0x20, 0xff, 0x05, 0x44, 0x23, 0xff, 0x0d, 0x4c, 0x29, 0xff, 0x0d, 0x49, 0x27, 0xff, 0x04, 0x3b, 0x1d, 0xff, 0x04, 0x37, 0x1f, 0xff, 0x00, 0x26, 0x15, 0xff, 0x01, 0x2b, 0x18, 0xff, 0x05, 0x3c, 0x25, 0xff, 0x05, 0x38, 0x21, 0xff, 0x01, 0x23, 0x11, 0xff, 0x01, 0x20, 0x0f, 0xff, 0x07, 0x30, 0x1d, 0xff, 0x10, 0x3b, 0x28, 0xff, 0x02, 0x25, 0x12, 0xff, 0x03, 0x26, 0x11, 0xff, 0x05, 0x38, 0x1d, 0xff, 0x0e, 0x4f, 0x2f, 0xff, 0x05, 0x4c, 0x28, 0xff, 0x03, 0x51, 0x2b, 0xff, 0x05, 0x3f, 0x21, 0xff, 0x02, 0x27, 0x12, 0xff, 0x04, 0x23, 0x13, 0xff, 0x04, 0x26, 0x13, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x00, 0x27, 0x0d, 0xff, 0x01, 0x2f, 0x13, 0xff, 0x08, 0x49, 0x24, 0xff, 0x0f, 0x64, 0x37, 0xff, 0x0c, 0x69, 0x38, 0xff, 0x07, 0x67, 0x36, 0xff, 0x07, 0x60, 0x33, 0xff, 0x0a, 0x53, 0x2f, 0xff, 0x04, 0x3c, 0x21, 0xff, 0x01, 0x2c, 0x1c, 0xff, 0x13, 0x39, 0x4c, 0xff, 0x53, 0x71, 0xb8, 0xff, 0x5c, 0x74, 0xd7, 0xff, 0x45, 0x5e, 0xcf, 0xff, 0x3c, 0x5d, 0xc2, 0xff, 0x2b, 0x52, 0x9e, 0xff, 0x24, 0x4e, 0x7c, 0xff, 0x0d, 0x38, 0x3e, 0xff, 0x00, 0x27, 0x18, 0xff, 0x06, 0x37, 0x1b, 0xff, 0x13, 0x4f, 0x2f, 0xff, 0x0d, 0x3b, 0x25, 0xff, 0x01, 0x28, 0x16, 0xff, 0x0d, 0x50, 0x35, 0xff, 0x0b, 0x47, 0x2a, 0xff, 0x10, 0x3f, 0x2e, 0xff, 0x02, 0x28, 0x1b, 0xff, 0x0d, 0x39, 0x23, 0xff, 0x04, 0x30, 0x17, 0xff, 0x01, 0x27, 0x15, 0xff, 0x02, 0x26, 0x15, 0xff, 0x02, 0x2e, 0x15, 0xff, 0x0b, 0x49, 0x2b, 0xff, 0x67, 0x92, 0x81, 0xff, + 0x01, 0x32, 0x18, 0xff, 0x06, 0x4d, 0x25, 0xff, 0x09, 0x55, 0x29, 0xff, 0x07, 0x4b, 0x24, 0xff, 0x00, 0x33, 0x15, 0xff, 0x05, 0x25, 0x14, 0xff, 0x04, 0x23, 0x15, 0xff, 0x04, 0x24, 0x13, 0xff, 0x05, 0x24, 0x11, 0xff, 0x01, 0x2e, 0x17, 0xff, 0x08, 0x42, 0x27, 0xff, 0x0d, 0x44, 0x29, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x02, 0x26, 0x12, 0xff, 0x01, 0x32, 0x16, 0xff, 0x0c, 0x54, 0x2b, 0xff, 0x0e, 0x53, 0x2d, 0xff, 0x08, 0x47, 0x27, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x04, 0x2b, 0x14, 0xff, 0x05, 0x27, 0x12, 0xff, 0x07, 0x26, 0x12, 0xff, 0x05, 0x26, 0x11, 0xff, 0x02, 0x26, 0x11, 0xff, 0x01, 0x29, 0x13, 0xff, 0x03, 0x47, 0x22, 0xff, 0x09, 0x58, 0x2d, 0xff, 0x05, 0x3c, 0x1f, 0xff, 0x00, 0x21, 0x0e, 0xff, 0x06, 0x39, 0x1d, 0xff, 0x08, 0x4d, 0x27, 0xff, 0x06, 0x56, 0x29, 0xff, 0x02, 0x59, 0x29, 0xff, 0x05, 0x5d, 0x2b, 0xff, 0x0a, 0x56, 0x2b, 0xff, 0x02, 0x34, 0x17, 0xff, 0x00, 0x23, 0x0e, 0xff, 0x04, 0x21, 0x13, 0xff, 0x03, 0x24, 0x13, 0xff, 0x00, 0x27, 0x11, 0xff, 0x03, 0x26, 0x10, 0xff, 0x04, 0x24, 0x12, 0xff, 0x03, 0x26, 0x13, 0xff, 0x01, 0x26, 0x10, 0xff, 0x02, 0x2b, 0x13, 0xff, 0x15, 0x44, 0x29, 0xff, 0x0c, 0x39, 0x1f, 0xff, 0x00, 0x28, 0x13, 0xff, 0x00, 0x27, 0x14, 0xff, 0x03, 0x27, 0x17, 0xff, 0x03, 0x27, 0x16, 0xff, 0x01, 0x28, 0x13, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x06, 0x38, 0x1c, 0xff, 0x04, 0x3a, 0x1d, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x06, 0x3b, 0x1f, 0xff, 0x04, 0x34, 0x19, 0xff, 0x02, 0x2d, 0x11, 0xff, 0x07, 0x2c, 0x10, 0xff, 0x28, 0x4c, 0x31, 0xff, 0x2a, 0x4d, 0x30, 0xff, 0x1e, 0x43, 0x25, 0xff, 0x19, 0x42, 0x22, 0xff, 0x12, 0x3b, 0x1b, 0xff, 0x04, 0x29, 0x0f, 0xff, 0x01, 0x28, 0x11, 0xff, 0x03, 0x2f, 0x17, 0xff, 0x07, 0x38, 0x27, 0xff, 0x11, 0x40, 0x50, 0xff, 0x37, 0x5e, 0x8d, 0xff, 0x4d, 0x6c, 0xa8, 0xff, 0x3e, 0x5e, 0x99, 0xff, 0x6e, 0x8d, 0xca, 0xff, 0x5f, 0x7a, 0xbe, 0xff, 0x80, 0x92, 0xe3, 0xff, 0x85, 0x95, 0xec, 0xff, 0x7a, 0x90, 0xe6, 0xff, 0x63, 0x7e, 0xca, 0xff, 0x31, 0x4e, 0x6b, 0xff, 0x09, 0x41, 0x37, 0xff, 0x11, 0x66, 0x3b, 0xff, 0x0b, 0x65, 0x37, 0xff, 0x09, 0x60, 0x3b, 0xff, 0x0b, 0x59, 0x35, 0xff, 0x01, 0x33, 0x15, 0xff, 0x06, 0x20, 0x08, 0xff, 0x05, 0x20, 0x07, 0xff, 0x04, 0x20, 0x06, 0xff, 0x05, 0x29, 0x0c, 0xff, 0x0e, 0x45, 0x24, 0xff, 0x03, 0x50, 0x2a, 0xff, 0x07, 0x5b, 0x35, 0xff, 0x1b, 0x67, 0x43, 0xff, 0x0c, 0x4c, 0x2b, 0xff, 0x06, 0x35, 0x1e, 0xff, 0x0b, 0x2f, 0x1c, 0xff, 0x04, 0x1f, 0x0d, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x09, 0x2f, 0x1a, 0xff, 0x11, 0x3b, 0x25, 0xff, 0x13, 0x39, 0x23, 0xff, 0x0e, 0x2f, 0x18, 0xff, 0x06, 0x2a, 0x0f, 0xff, 0x0d, 0x37, 0x1b, 0xff, 0x02, 0x2f, 0x12, 0xff, 0x01, 0x27, 0x0b, 0xff, 0x03, 0x29, 0x0c, 0xff, 0x05, 0x29, 0x0c, 0xff, 0x03, 0x27, 0x08, 0xff, 0x02, 0x27, 0x08, 0xff, 0x09, 0x3a, 0x1b, 0xff, 0x18, 0x4b, 0x2c, 0xff, 0x0f, 0x44, 0x25, 0xff, 0x06, 0x39, 0x1c, 0xff, 0x00, 0x30, 0x13, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x0d, 0x45, 0x29, 0xff, 0x0d, 0x42, 0x27, 0xff, 0x03, 0x31, 0x17, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x0c, 0x41, 0x28, 0xff, 0x0d, 0x40, 0x27, 0xff, 0x02, 0x2b, 0x15, 0xff, 0x02, 0x29, 0x13, 0xff, 0x01, 0x2e, 0x18, 0xff, 0x05, 0x3c, 0x24, 0xff, 0x09, 0x4a, 0x2d, 0xff, 0x0a, 0x48, 0x2b, 0xff, 0x06, 0x37, 0x1d, 0xff, 0x05, 0x2a, 0x15, 0xff, 0x0a, 0x29, 0x16, 0xff, 0x04, 0x2b, 0x12, 0xff, 0x06, 0x3f, 0x1a, 0xff, 0x09, 0x53, 0x25, 0xff, 0x06, 0x52, 0x28, 0xff, 0x04, 0x3a, 0x1c, 0xff, 0x06, 0x25, 0x13, 0xff, 0x03, 0x25, 0x13, 0xff, 0x00, 0x44, 0x24, 0xff, 0x01, 0x55, 0x2c, 0xff, 0x05, 0x4a, 0x25, 0xff, 0x06, 0x33, 0x17, 0xff, 0x09, 0x20, 0x11, 0xff, 0x08, 0x21, 0x13, 0xff, 0x00, 0x28, 0x0e, 0xff, 0x03, 0x37, 0x14, 0xff, 0x20, 0x6d, 0x41, 0xff, 0x17, 0x6a, 0x3f, 0xff, 0x09, 0x5c, 0x35, 0xff, 0x09, 0x5b, 0x38, 0xff, 0x0a, 0x5d, 0x37, 0xff, 0x0a, 0x5e, 0x34, 0xff, 0x08, 0x5d, 0x33, 0xff, 0x0a, 0x5d, 0x33, 0xff, 0x0b, 0x5d, 0x32, 0xff, 0x09, 0x59, 0x2e, 0xff, 0x09, 0x57, 0x2b, 0xff, 0x09, 0x56, 0x29, 0xff, 0x0a, 0x57, 0x29, 0xff, 0x0a, 0x58, 0x29, 0xff, 0x08, 0x57, 0x28, 0xff, 0x08, 0x56, 0x27, 0xff, 0x08, 0x55, 0x28, 0xff, 0x0a, 0x55, 0x28, 0xff, 0x09, 0x55, 0x28, 0xff, 0x0b, 0x55, 0x28, 0xff, 0x07, 0x56, 0x26, 0xff, 0x04, 0x57, 0x25, 0xff, 0x06, 0x57, 0x27, 0xff, 0x07, 0x56, 0x28, 0xff, 0x07, 0x55, 0x29, 0xff, 0x09, 0x53, 0x2a, 0xff, 0x0b, 0x52, 0x2b, 0xff, 0x0a, 0x50, 0x2a, 0xff, 0x04, 0x45, 0x23, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x02, 0x2d, 0x15, 0xff, 0x01, 0x28, 0x12, 0xff, 0x0d, 0x36, 0x23, 0xff, 0x09, 0x2e, 0x1c, 0xff, 0x02, 0x22, 0x10, 0xff, 0x02, 0x2a, 0x14, 0xff, 0x0e, 0x3c, 0x27, 0xff, 0x0a, 0x31, 0x20, 0xff, 0x00, 0x23, 0x0f, 0xff, 0x02, 0x31, 0x19, 0xff, 0x09, 0x53, 0x2f, 0xff, 0x0b, 0x67, 0x3a, 0xff, 0x09, 0x6d, 0x37, 0xff, 0x0b, 0x6b, 0x32, 0xff, 0x0f, 0x69, 0x31, 0xff, 0x0c, 0x68, 0x36, 0xff, 0x0e, 0x64, 0x39, 0xff, 0x0e, 0x5d, 0x37, 0xff, 0x02, 0x55, 0x2a, 0xff, 0x0e, 0x7b, 0x49, 0xff, 0x08, 0x90, 0x53, 0xff, 0x04, 0x8b, 0x4b, 0xff, 0x0b, 0x87, 0x48, 0xff, 0x0a, 0x86, 0x47, 0xff, 0x02, 0x87, 0x49, 0xff, 0x05, 0x88, 0x4b, 0xff, 0x04, 0x88, 0x49, 0xff, 0x05, 0x86, 0x4a, 0xff, 0x0d, 0x68, 0x3f, 0xff, 0x03, 0x32, 0x1d, 0xff, 0x03, 0x1a, 0x13, 0xff, 0x01, 0x21, 0x10, 0xff, 0x01, 0x2f, 0x19, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x0a, 0x45, 0x27, 0xff, 0x06, 0x43, 0x24, 0xff, 0x07, 0x54, 0x32, 0xff, 0x0f, 0x5f, 0x3d, 0xff, 0x01, 0x2c, 0x0f, 0xff, 0x04, 0x36, 0x1c, 0xff, 0x0c, 0x47, 0x2f, 0xff, 0x03, 0x2d, 0x18, 0xff, 0x00, 0x1f, 0x0c, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x08, 0x42, 0x27, 0xff, 0x0d, 0x3a, 0x23, 0xff, 0x01, 0x1f, 0x0f, 0xff, 0x02, 0x1e, 0x0f, 0xff, 0x04, 0x1e, 0x0e, 0xff, 0x01, 0x26, 0x11, 0xff, 0x06, 0x40, 0x26, 0xff, 0x0a, 0x46, 0x2b, 0xff, 0x02, 0x2b, 0x16, 0xff, 0x03, 0x20, 0x10, 0xff, 0x03, 0x1e, 0x0f, 0xff, 0x01, 0x24, 0x11, 0xff, 0x0e, 0x42, 0x2a, 0xff, 0x05, 0x32, 0x1a, 0xff, 0x05, 0x2d, 0x16, 0xff, 0x04, 0x3c, 0x1f, 0xff, 0x09, 0x55, 0x30, 0xff, 0x0c, 0x60, 0x36, 0xff, 0x04, 0x60, 0x32, 0xff, 0x01, 0x5b, 0x2c, 0xff, 0x0f, 0x6c, 0x3d, 0xff, 0x11, 0x6b, 0x3d, 0xff, 0x10, 0x62, 0x36, 0xff, 0x05, 0x49, 0x24, 0xff, 0x04, 0x38, 0x1b, 0xff, 0x0f, 0x3a, 0x24, 0xff, 0x06, 0x2a, 0x19, 0xff, 0x01, 0x2a, 0x16, 0xff, 0x07, 0x3b, 0x25, 0xff, 0x07, 0x37, 0x22, 0xff, 0x01, 0x24, 0x11, 0xff, 0x04, 0x2c, 0x19, 0xff, 0x04, 0x38, 0x22, 0xff, 0x05, 0x3b, 0x24, 0xff, 0x05, 0x31, 0x1c, 0xff, 0x02, 0x30, 0x19, 0xff, 0x0b, 0x36, 0x20, 0xff, 0x08, 0x2e, 0x1a, 0xff, 0x04, 0x2b, 0x17, 0xff, 0x09, 0x38, 0x22, 0xff, 0x04, 0x3f, 0x23, 0xff, 0x08, 0x49, 0x27, 0xff, 0x09, 0x4f, 0x29, 0xff, 0x0e, 0x51, 0x2b, 0xff, 0x03, 0x3b, 0x1d, 0xff, 0x07, 0x37, 0x21, 0xff, 0x01, 0x24, 0x14, 0xff, 0x01, 0x27, 0x16, 0xff, 0x08, 0x3c, 0x27, 0xff, 0x09, 0x3c, 0x25, 0xff, 0x03, 0x25, 0x14, 0xff, 0x02, 0x20, 0x10, 0xff, 0x05, 0x2d, 0x1c, 0xff, 0x10, 0x3d, 0x2a, 0xff, 0x03, 0x2a, 0x16, 0xff, 0x01, 0x26, 0x11, 0xff, 0x05, 0x3a, 0x1e, 0xff, 0x0d, 0x50, 0x31, 0xff, 0x04, 0x4c, 0x29, 0xff, 0x07, 0x50, 0x2b, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x02, 0x26, 0x12, 0xff, 0x01, 0x22, 0x13, 0xff, 0x01, 0x25, 0x12, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x01, 0x2d, 0x0f, 0xff, 0x08, 0x48, 0x27, 0xff, 0x12, 0x64, 0x3a, 0xff, 0x0e, 0x6a, 0x39, 0xff, 0x0b, 0x68, 0x38, 0xff, 0x08, 0x60, 0x34, 0xff, 0x10, 0x59, 0x34, 0xff, 0x04, 0x3b, 0x20, 0xff, 0x03, 0x2b, 0x1a, 0xff, 0x04, 0x27, 0x21, 0xff, 0x39, 0x59, 0x86, 0xff, 0x64, 0x78, 0xe8, 0xff, 0x49, 0x58, 0xe3, 0xff, 0x37, 0x49, 0xe2, 0xff, 0x30, 0x4b, 0xdd, 0xff, 0x31, 0x50, 0xd1, 0xff, 0x36, 0x59, 0xbf, 0xff, 0x1c, 0x43, 0x7c, 0xff, 0x00, 0x1c, 0x2f, 0xff, 0x00, 0x27, 0x15, 0xff, 0x09, 0x44, 0x21, 0xff, 0x1c, 0x55, 0x33, 0xff, 0x04, 0x3c, 0x20, 0xff, 0x12, 0x5b, 0x3b, 0xff, 0x07, 0x46, 0x24, 0xff, 0x19, 0x44, 0x31, 0xff, 0x02, 0x23, 0x16, 0xff, 0x14, 0x3f, 0x29, 0xff, 0x0b, 0x3a, 0x21, 0xff, 0x01, 0x26, 0x13, 0xff, 0x05, 0x24, 0x16, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x0d, 0x4a, 0x2e, 0xff, 0x68, 0x90, 0x82, 0xff, + 0x00, 0x33, 0x1a, 0xff, 0x04, 0x4e, 0x27, 0xff, 0x07, 0x55, 0x2a, 0xff, 0x04, 0x47, 0x22, 0xff, 0x00, 0x31, 0x14, 0xff, 0x02, 0x26, 0x14, 0xff, 0x02, 0x24, 0x15, 0xff, 0x01, 0x24, 0x14, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x32, 0x19, 0xff, 0x06, 0x46, 0x29, 0xff, 0x0a, 0x46, 0x2b, 0xff, 0x01, 0x2d, 0x16, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x0d, 0x53, 0x2d, 0xff, 0x0e, 0x52, 0x30, 0xff, 0x04, 0x3e, 0x22, 0xff, 0x00, 0x31, 0x19, 0xff, 0x01, 0x29, 0x14, 0xff, 0x03, 0x25, 0x13, 0xff, 0x02, 0x25, 0x13, 0xff, 0x02, 0x25, 0x11, 0xff, 0x04, 0x27, 0x13, 0xff, 0x01, 0x2e, 0x16, 0xff, 0x08, 0x4f, 0x27, 0xff, 0x0e, 0x59, 0x2d, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x00, 0x20, 0x0e, 0xff, 0x09, 0x3d, 0x21, 0xff, 0x0a, 0x51, 0x28, 0xff, 0x04, 0x58, 0x29, 0xff, 0x00, 0x5a, 0x29, 0xff, 0x05, 0x5c, 0x2e, 0xff, 0x07, 0x4f, 0x29, 0xff, 0x00, 0x2c, 0x13, 0xff, 0x01, 0x21, 0x10, 0xff, 0x02, 0x22, 0x14, 0xff, 0x00, 0x25, 0x14, 0xff, 0x00, 0x24, 0x10, 0xff, 0x05, 0x25, 0x12, 0xff, 0x05, 0x26, 0x11, 0xff, 0x02, 0x27, 0x11, 0xff, 0x01, 0x2e, 0x15, 0xff, 0x0d, 0x41, 0x27, 0xff, 0x16, 0x44, 0x2a, 0xff, 0x05, 0x2d, 0x16, 0xff, 0x02, 0x26, 0x15, 0xff, 0x02, 0x27, 0x15, 0xff, 0x02, 0x28, 0x15, 0xff, 0x01, 0x28, 0x12, 0xff, 0x03, 0x2c, 0x14, 0xff, 0x07, 0x36, 0x1a, 0xff, 0x0a, 0x3b, 0x1e, 0xff, 0x09, 0x3a, 0x1e, 0xff, 0x0a, 0x39, 0x1f, 0xff, 0x05, 0x31, 0x17, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x03, 0x25, 0x0c, 0xff, 0x1e, 0x3e, 0x24, 0xff, 0x21, 0x40, 0x26, 0xff, 0x05, 0x22, 0x07, 0xff, 0x02, 0x22, 0x05, 0xff, 0x04, 0x24, 0x06, 0xff, 0x0b, 0x30, 0x0f, 0xff, 0x06, 0x30, 0x12, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x02, 0x2f, 0x11, 0xff, 0x04, 0x3a, 0x1e, 0xff, 0x15, 0x4c, 0x48, 0xff, 0x29, 0x5c, 0x6c, 0xff, 0x27, 0x60, 0x6b, 0xff, 0x1a, 0x56, 0x5d, 0xff, 0x28, 0x62, 0x6b, 0xff, 0x2b, 0x5e, 0x71, 0xff, 0x48, 0x6e, 0x9a, 0xff, 0x55, 0x75, 0xb5, 0xff, 0x73, 0x90, 0xe7, 0xff, 0x74, 0x8f, 0xeb, 0xff, 0x4f, 0x65, 0x95, 0xff, 0x17, 0x46, 0x49, 0xff, 0x13, 0x63, 0x3a, 0xff, 0x0d, 0x6b, 0x39, 0xff, 0x06, 0x64, 0x39, 0xff, 0x09, 0x5a, 0x36, 0xff, 0x01, 0x34, 0x16, 0xff, 0x02, 0x21, 0x09, 0xff, 0x01, 0x21, 0x09, 0xff, 0x01, 0x22, 0x08, 0xff, 0x08, 0x34, 0x18, 0xff, 0x13, 0x4f, 0x2f, 0xff, 0x0e, 0x59, 0x34, 0xff, 0x1d, 0x6e, 0x4a, 0xff, 0x1a, 0x66, 0x44, 0xff, 0x04, 0x49, 0x29, 0xff, 0x01, 0x37, 0x1e, 0xff, 0x04, 0x32, 0x1c, 0xff, 0x03, 0x28, 0x13, 0xff, 0x04, 0x2d, 0x16, 0xff, 0x0c, 0x3f, 0x26, 0xff, 0x09, 0x3f, 0x26, 0xff, 0x15, 0x42, 0x2a, 0xff, 0x0a, 0x2d, 0x15, 0xff, 0x09, 0x2f, 0x15, 0xff, 0x13, 0x40, 0x25, 0xff, 0x09, 0x3b, 0x1f, 0xff, 0x04, 0x31, 0x15, 0xff, 0x01, 0x24, 0x0b, 0xff, 0x02, 0x20, 0x06, 0xff, 0x02, 0x20, 0x05, 0xff, 0x01, 0x22, 0x06, 0xff, 0x0a, 0x37, 0x18, 0xff, 0x15, 0x4c, 0x2b, 0xff, 0x0d, 0x4b, 0x2b, 0xff, 0x0b, 0x49, 0x2a, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x01, 0x2f, 0x14, 0xff, 0x05, 0x3a, 0x1f, 0xff, 0x0a, 0x45, 0x2a, 0xff, 0x0c, 0x41, 0x2a, 0xff, 0x01, 0x31, 0x19, 0xff, 0x02, 0x34, 0x1d, 0xff, 0x0a, 0x40, 0x29, 0xff, 0x0b, 0x37, 0x24, 0xff, 0x01, 0x29, 0x16, 0xff, 0x00, 0x28, 0x15, 0xff, 0x00, 0x2e, 0x18, 0xff, 0x02, 0x41, 0x26, 0xff, 0x0b, 0x4b, 0x2e, 0xff, 0x0e, 0x44, 0x29, 0xff, 0x06, 0x32, 0x1b, 0xff, 0x04, 0x27, 0x14, 0xff, 0x04, 0x2a, 0x16, 0xff, 0x01, 0x32, 0x14, 0xff, 0x06, 0x4a, 0x22, 0xff, 0x03, 0x56, 0x2a, 0xff, 0x03, 0x47, 0x24, 0xff, 0x01, 0x27, 0x12, 0xff, 0x00, 0x2c, 0x18, 0xff, 0x01, 0x4b, 0x2a, 0xff, 0x03, 0x55, 0x2c, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x03, 0x26, 0x12, 0xff, 0x0b, 0x22, 0x15, 0xff, 0x03, 0x23, 0x10, 0xff, 0x06, 0x3f, 0x1e, 0xff, 0x1d, 0x75, 0x47, 0xff, 0x14, 0x79, 0x43, 0xff, 0x04, 0x66, 0x32, 0xff, 0x06, 0x62, 0x34, 0xff, 0x05, 0x5d, 0x35, 0xff, 0x04, 0x5e, 0x34, 0xff, 0x05, 0x60, 0x34, 0xff, 0x08, 0x62, 0x36, 0xff, 0x0b, 0x64, 0x38, 0xff, 0x0c, 0x60, 0x36, 0xff, 0x07, 0x59, 0x2f, 0xff, 0x07, 0x57, 0x2c, 0xff, 0x07, 0x56, 0x2b, 0xff, 0x06, 0x56, 0x2a, 0xff, 0x06, 0x56, 0x29, 0xff, 0x05, 0x55, 0x29, 0xff, 0x06, 0x56, 0x29, 0xff, 0x06, 0x56, 0x2a, 0xff, 0x07, 0x55, 0x2a, 0xff, 0x07, 0x55, 0x2a, 0xff, 0x07, 0x55, 0x2a, 0xff, 0x05, 0x56, 0x29, 0xff, 0x03, 0x57, 0x28, 0xff, 0x06, 0x59, 0x2b, 0xff, 0x06, 0x58, 0x2b, 0xff, 0x04, 0x57, 0x2a, 0xff, 0x04, 0x55, 0x2a, 0xff, 0x04, 0x53, 0x2a, 0xff, 0x05, 0x54, 0x2a, 0xff, 0x08, 0x53, 0x2c, 0xff, 0x08, 0x48, 0x24, 0xff, 0x06, 0x37, 0x1a, 0xff, 0x01, 0x2a, 0x12, 0xff, 0x09, 0x35, 0x20, 0xff, 0x0a, 0x31, 0x1e, 0xff, 0x01, 0x22, 0x0e, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x13, 0x42, 0x2b, 0xff, 0x08, 0x2e, 0x1c, 0xff, 0x00, 0x2d, 0x14, 0xff, 0x07, 0x49, 0x29, 0xff, 0x0f, 0x67, 0x3b, 0xff, 0x0b, 0x6f, 0x3a, 0xff, 0x06, 0x6d, 0x33, 0xff, 0x0c, 0x6d, 0x31, 0xff, 0x0d, 0x6b, 0x30, 0xff, 0x0a, 0x6c, 0x32, 0xff, 0x0c, 0x65, 0x34, 0xff, 0x0d, 0x5d, 0x31, 0xff, 0x01, 0x54, 0x27, 0xff, 0x0b, 0x79, 0x42, 0xff, 0x07, 0x91, 0x50, 0xff, 0x03, 0x89, 0x46, 0xff, 0x09, 0x87, 0x43, 0xff, 0x02, 0x88, 0x43, 0xff, 0x00, 0x86, 0x46, 0xff, 0x01, 0x88, 0x49, 0xff, 0x02, 0x89, 0x47, 0xff, 0x03, 0x87, 0x45, 0xff, 0x14, 0x7a, 0x47, 0xff, 0x09, 0x46, 0x26, 0xff, 0x04, 0x1f, 0x10, 0xff, 0x01, 0x20, 0x11, 0xff, 0x03, 0x2f, 0x1a, 0xff, 0x05, 0x33, 0x1b, 0xff, 0x0f, 0x43, 0x27, 0xff, 0x07, 0x42, 0x23, 0xff, 0x07, 0x58, 0x35, 0xff, 0x11, 0x66, 0x42, 0xff, 0x02, 0x2c, 0x0f, 0xff, 0x02, 0x32, 0x18, 0xff, 0x09, 0x47, 0x2f, 0xff, 0x02, 0x2d, 0x19, 0xff, 0x00, 0x1f, 0x0b, 0xff, 0x05, 0x3b, 0x22, 0xff, 0x04, 0x48, 0x2b, 0xff, 0x0a, 0x40, 0x28, 0xff, 0x00, 0x21, 0x0f, 0xff, 0x01, 0x1d, 0x0f, 0xff, 0x05, 0x1e, 0x0e, 0xff, 0x03, 0x26, 0x13, 0xff, 0x0a, 0x41, 0x27, 0xff, 0x0c, 0x46, 0x2d, 0xff, 0x04, 0x2c, 0x18, 0xff, 0x02, 0x1e, 0x0f, 0xff, 0x03, 0x1d, 0x10, 0xff, 0x01, 0x24, 0x11, 0xff, 0x0a, 0x41, 0x29, 0xff, 0x03, 0x30, 0x1a, 0xff, 0x02, 0x29, 0x14, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x05, 0x4f, 0x2d, 0xff, 0x0b, 0x5e, 0x36, 0xff, 0x07, 0x63, 0x36, 0xff, 0x02, 0x5b, 0x2e, 0xff, 0x0a, 0x67, 0x3a, 0xff, 0x0c, 0x6a, 0x3d, 0xff, 0x0e, 0x69, 0x3d, 0xff, 0x0b, 0x5d, 0x35, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x06, 0x37, 0x1e, 0xff, 0x09, 0x33, 0x1f, 0xff, 0x00, 0x28, 0x14, 0xff, 0x04, 0x39, 0x24, 0xff, 0x06, 0x38, 0x24, 0xff, 0x00, 0x24, 0x12, 0xff, 0x04, 0x2f, 0x1c, 0xff, 0x01, 0x37, 0x22, 0xff, 0x03, 0x3a, 0x24, 0xff, 0x03, 0x2f, 0x1b, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x08, 0x36, 0x20, 0xff, 0x06, 0x2f, 0x1c, 0xff, 0x01, 0x28, 0x14, 0xff, 0x06, 0x39, 0x22, 0xff, 0x05, 0x44, 0x27, 0xff, 0x08, 0x50, 0x2c, 0xff, 0x06, 0x53, 0x2a, 0xff, 0x0c, 0x57, 0x2d, 0xff, 0x03, 0x40, 0x1f, 0xff, 0x07, 0x34, 0x1d, 0xff, 0x05, 0x25, 0x16, 0xff, 0x02, 0x25, 0x15, 0xff, 0x0a, 0x3d, 0x28, 0xff, 0x0d, 0x40, 0x2a, 0xff, 0x04, 0x2a, 0x16, 0xff, 0x00, 0x1f, 0x10, 0xff, 0x02, 0x2a, 0x19, 0xff, 0x0d, 0x3e, 0x2c, 0xff, 0x04, 0x2e, 0x1c, 0xff, 0x00, 0x26, 0x11, 0xff, 0x05, 0x3d, 0x21, 0xff, 0x0c, 0x54, 0x33, 0xff, 0x02, 0x4e, 0x2a, 0xff, 0x08, 0x50, 0x2d, 0xff, 0x08, 0x3b, 0x1f, 0xff, 0x02, 0x26, 0x12, 0xff, 0x01, 0x25, 0x14, 0xff, 0x00, 0x27, 0x12, 0xff, 0x01, 0x2f, 0x11, 0xff, 0x0b, 0x46, 0x23, 0xff, 0x15, 0x65, 0x3c, 0xff, 0x08, 0x67, 0x38, 0xff, 0x07, 0x6a, 0x38, 0xff, 0x06, 0x63, 0x35, 0xff, 0x10, 0x5b, 0x35, 0xff, 0x11, 0x49, 0x2c, 0xff, 0x03, 0x28, 0x15, 0xff, 0x03, 0x26, 0x19, 0xff, 0x04, 0x2a, 0x23, 0xff, 0x42, 0x65, 0x99, 0xff, 0x4e, 0x66, 0xe1, 0xff, 0x34, 0x49, 0xdb, 0xff, 0x2c, 0x47, 0xdf, 0xff, 0x25, 0x47, 0xda, 0xff, 0x24, 0x47, 0xda, 0xff, 0x27, 0x49, 0xd3, 0xff, 0x2c, 0x50, 0xbd, 0xff, 0x13, 0x34, 0x73, 0xff, 0x01, 0x1f, 0x20, 0xff, 0x04, 0x35, 0x17, 0xff, 0x17, 0x59, 0x2f, 0xff, 0x0c, 0x51, 0x2c, 0xff, 0x13, 0x5a, 0x36, 0xff, 0x08, 0x46, 0x20, 0xff, 0x1b, 0x48, 0x31, 0xff, 0x03, 0x23, 0x13, 0xff, 0x15, 0x41, 0x2a, 0xff, 0x17, 0x49, 0x2f, 0xff, 0x01, 0x25, 0x13, 0xff, 0x07, 0x24, 0x16, 0xff, 0x05, 0x32, 0x1a, 0xff, 0x0e, 0x4e, 0x30, 0xff, 0x69, 0x8f, 0x83, 0xff, + 0x00, 0x34, 0x1a, 0xff, 0x05, 0x4f, 0x2a, 0xff, 0x07, 0x54, 0x2c, 0xff, 0x03, 0x44, 0x1f, 0xff, 0x00, 0x30, 0x14, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x25, 0x14, 0xff, 0x00, 0x24, 0x13, 0xff, 0x00, 0x25, 0x12, 0xff, 0x00, 0x33, 0x1a, 0xff, 0x06, 0x48, 0x2b, 0xff, 0x0a, 0x49, 0x2a, 0xff, 0x01, 0x30, 0x15, 0xff, 0x00, 0x26, 0x11, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x0e, 0x51, 0x2d, 0xff, 0x10, 0x4f, 0x30, 0xff, 0x02, 0x38, 0x1d, 0xff, 0x00, 0x2c, 0x17, 0xff, 0x00, 0x26, 0x15, 0xff, 0x01, 0x25, 0x15, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x24, 0x10, 0xff, 0x03, 0x29, 0x13, 0xff, 0x01, 0x35, 0x19, 0xff, 0x0b, 0x56, 0x29, 0xff, 0x11, 0x58, 0x2a, 0xff, 0x03, 0x30, 0x13, 0xff, 0x02, 0x22, 0x0f, 0xff, 0x0a, 0x42, 0x24, 0xff, 0x0a, 0x53, 0x29, 0xff, 0x02, 0x59, 0x28, 0xff, 0x00, 0x5c, 0x2b, 0xff, 0x05, 0x5a, 0x30, 0xff, 0x03, 0x46, 0x24, 0xff, 0x00, 0x26, 0x12, 0xff, 0x04, 0x22, 0x13, 0xff, 0x02, 0x24, 0x14, 0xff, 0x00, 0x25, 0x14, 0xff, 0x01, 0x24, 0x13, 0xff, 0x04, 0x25, 0x11, 0xff, 0x01, 0x26, 0x0d, 0xff, 0x00, 0x2c, 0x11, 0xff, 0x0a, 0x44, 0x26, 0xff, 0x14, 0x50, 0x33, 0xff, 0x07, 0x37, 0x1d, 0xff, 0x01, 0x28, 0x14, 0xff, 0x04, 0x25, 0x16, 0xff, 0x02, 0x27, 0x15, 0xff, 0x00, 0x29, 0x11, 0xff, 0x00, 0x2c, 0x10, 0xff, 0x07, 0x38, 0x19, 0xff, 0x09, 0x3c, 0x1d, 0xff, 0x08, 0x3a, 0x1c, 0xff, 0x07, 0x37, 0x1b, 0xff, 0x07, 0x2e, 0x14, 0xff, 0x00, 0x24, 0x0a, 0xff, 0x01, 0x20, 0x06, 0xff, 0x05, 0x25, 0x0a, 0xff, 0x0c, 0x2c, 0x0e, 0xff, 0x02, 0x23, 0x05, 0xff, 0x00, 0x20, 0x01, 0xff, 0x00, 0x21, 0x02, 0xff, 0x01, 0x29, 0x07, 0xff, 0x04, 0x33, 0x0a, 0xff, 0x0b, 0x43, 0x1b, 0xff, 0x0e, 0x4a, 0x27, 0xff, 0x0e, 0x50, 0x2a, 0xff, 0x10, 0x56, 0x2d, 0xff, 0x11, 0x57, 0x39, 0xff, 0x11, 0x55, 0x41, 0xff, 0x09, 0x5a, 0x3a, 0xff, 0x0b, 0x5e, 0x3a, 0xff, 0x0f, 0x5c, 0x42, 0xff, 0x18, 0x58, 0x58, 0xff, 0x3c, 0x65, 0x94, 0xff, 0x65, 0x81, 0xce, 0xff, 0x75, 0x8e, 0xec, 0xff, 0x75, 0x8f, 0xec, 0xff, 0x4f, 0x64, 0x9b, 0xff, 0x24, 0x4e, 0x55, 0xff, 0x0c, 0x5c, 0x2e, 0xff, 0x0d, 0x72, 0x35, 0xff, 0x07, 0x6b, 0x39, 0xff, 0x08, 0x5b, 0x33, 0xff, 0x01, 0x33, 0x15, 0xff, 0x00, 0x21, 0x08, 0xff, 0x00, 0x21, 0x0a, 0xff, 0x00, 0x24, 0x0b, 0xff, 0x09, 0x35, 0x1a, 0xff, 0x0e, 0x40, 0x22, 0xff, 0x0b, 0x42, 0x24, 0xff, 0x1a, 0x5a, 0x3a, 0xff, 0x1f, 0x65, 0x44, 0xff, 0x05, 0x4a, 0x2a, 0xff, 0x00, 0x35, 0x19, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x06, 0x30, 0x18, 0xff, 0x08, 0x37, 0x1d, 0xff, 0x08, 0x42, 0x25, 0xff, 0x06, 0x42, 0x25, 0xff, 0x10, 0x3d, 0x22, 0xff, 0x04, 0x25, 0x0b, 0xff, 0x0b, 0x33, 0x19, 0xff, 0x11, 0x43, 0x27, 0xff, 0x09, 0x41, 0x24, 0xff, 0x0c, 0x40, 0x24, 0xff, 0x0b, 0x32, 0x17, 0xff, 0x01, 0x1f, 0x06, 0xff, 0x02, 0x22, 0x08, 0xff, 0x06, 0x2a, 0x10, 0xff, 0x02, 0x2f, 0x0f, 0xff, 0x0d, 0x45, 0x21, 0xff, 0x0d, 0x4b, 0x28, 0xff, 0x0d, 0x4c, 0x2a, 0xff, 0x11, 0x49, 0x2a, 0xff, 0x06, 0x3a, 0x1d, 0xff, 0x00, 0x33, 0x17, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x0c, 0x44, 0x2a, 0xff, 0x09, 0x40, 0x26, 0xff, 0x01, 0x30, 0x16, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x0e, 0x40, 0x2a, 0xff, 0x09, 0x39, 0x23, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x00, 0x2a, 0x13, 0xff, 0x00, 0x2e, 0x15, 0xff, 0x04, 0x3c, 0x20, 0xff, 0x0f, 0x48, 0x2b, 0xff, 0x0b, 0x41, 0x26, 0xff, 0x01, 0x2c, 0x17, 0xff, 0x00, 0x27, 0x15, 0xff, 0x00, 0x2b, 0x12, 0xff, 0x04, 0x3c, 0x1b, 0xff, 0x05, 0x56, 0x29, 0xff, 0x06, 0x4f, 0x27, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x02, 0x32, 0x1c, 0xff, 0x0b, 0x4f, 0x2f, 0xff, 0x07, 0x49, 0x23, 0xff, 0x00, 0x2b, 0x0f, 0xff, 0x02, 0x21, 0x13, 0xff, 0x02, 0x24, 0x0f, 0xff, 0x03, 0x35, 0x15, 0xff, 0x1e, 0x7e, 0x52, 0xff, 0x15, 0x81, 0x4d, 0xff, 0x01, 0x68, 0x30, 0xff, 0x04, 0x65, 0x2d, 0xff, 0x08, 0x64, 0x31, 0xff, 0x04, 0x66, 0x34, 0xff, 0x03, 0x67, 0x35, 0xff, 0x08, 0x68, 0x38, 0xff, 0x0a, 0x68, 0x38, 0xff, 0x0b, 0x67, 0x39, 0xff, 0x07, 0x5f, 0x32, 0xff, 0x04, 0x5a, 0x2d, 0xff, 0x06, 0x59, 0x2d, 0xff, 0x06, 0x58, 0x2b, 0xff, 0x07, 0x58, 0x2a, 0xff, 0x04, 0x58, 0x2a, 0xff, 0x06, 0x58, 0x2b, 0xff, 0x06, 0x58, 0x2b, 0xff, 0x05, 0x57, 0x2b, 0xff, 0x05, 0x55, 0x2b, 0xff, 0x06, 0x56, 0x2b, 0xff, 0x06, 0x56, 0x2b, 0xff, 0x07, 0x58, 0x2d, 0xff, 0x08, 0x58, 0x2d, 0xff, 0x08, 0x58, 0x2d, 0xff, 0x06, 0x58, 0x2c, 0xff, 0x05, 0x58, 0x2b, 0xff, 0x04, 0x58, 0x2a, 0xff, 0x03, 0x56, 0x29, 0xff, 0x01, 0x55, 0x27, 0xff, 0x03, 0x56, 0x28, 0xff, 0x09, 0x54, 0x28, 0xff, 0x0e, 0x47, 0x24, 0xff, 0x04, 0x34, 0x16, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x0a, 0x37, 0x1f, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x02, 0x32, 0x16, 0xff, 0x12, 0x4a, 0x2e, 0xff, 0x04, 0x2d, 0x12, 0xff, 0x04, 0x41, 0x1d, 0xff, 0x0f, 0x62, 0x35, 0xff, 0x0c, 0x6f, 0x38, 0xff, 0x06, 0x6f, 0x35, 0xff, 0x06, 0x6d, 0x32, 0xff, 0x0a, 0x6e, 0x35, 0xff, 0x09, 0x6c, 0x34, 0xff, 0x08, 0x6b, 0x33, 0xff, 0x09, 0x60, 0x31, 0xff, 0x0b, 0x5a, 0x31, 0xff, 0x02, 0x58, 0x2b, 0xff, 0x0a, 0x78, 0x43, 0xff, 0x06, 0x91, 0x4f, 0xff, 0x02, 0x88, 0x42, 0xff, 0x06, 0x86, 0x41, 0xff, 0x01, 0x89, 0x43, 0xff, 0x00, 0x86, 0x47, 0xff, 0x00, 0x86, 0x48, 0xff, 0x02, 0x87, 0x46, 0xff, 0x00, 0x83, 0x40, 0xff, 0x0f, 0x81, 0x46, 0xff, 0x0a, 0x59, 0x2f, 0xff, 0x00, 0x22, 0x0b, 0xff, 0x01, 0x21, 0x11, 0xff, 0x02, 0x30, 0x1b, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x11, 0x43, 0x26, 0xff, 0x07, 0x40, 0x20, 0xff, 0x05, 0x5c, 0x35, 0xff, 0x0f, 0x6a, 0x42, 0xff, 0x04, 0x2f, 0x10, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x0b, 0x46, 0x2f, 0xff, 0x03, 0x2f, 0x1a, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x08, 0x41, 0x26, 0xff, 0x04, 0x4c, 0x2c, 0xff, 0x07, 0x45, 0x27, 0xff, 0x01, 0x25, 0x11, 0xff, 0x01, 0x1d, 0x0f, 0xff, 0x03, 0x1e, 0x0e, 0xff, 0x03, 0x26, 0x12, 0xff, 0x09, 0x42, 0x26, 0xff, 0x0e, 0x47, 0x2c, 0xff, 0x05, 0x2f, 0x19, 0xff, 0x01, 0x1f, 0x0f, 0xff, 0x01, 0x1e, 0x10, 0xff, 0x01, 0x25, 0x10, 0xff, 0x0a, 0x40, 0x27, 0xff, 0x03, 0x2e, 0x19, 0xff, 0x01, 0x25, 0x11, 0xff, 0x00, 0x31, 0x17, 0xff, 0x02, 0x49, 0x28, 0xff, 0x0a, 0x5c, 0x34, 0xff, 0x08, 0x63, 0x37, 0xff, 0x08, 0x5e, 0x33, 0xff, 0x06, 0x60, 0x35, 0xff, 0x09, 0x6a, 0x3c, 0xff, 0x08, 0x6b, 0x3d, 0xff, 0x0c, 0x68, 0x3e, 0xff, 0x05, 0x4d, 0x29, 0xff, 0x01, 0x37, 0x19, 0xff, 0x08, 0x37, 0x1e, 0xff, 0x01, 0x2c, 0x16, 0xff, 0x03, 0x37, 0x20, 0xff, 0x07, 0x39, 0x22, 0xff, 0x01, 0x25, 0x10, 0xff, 0x06, 0x32, 0x1d, 0xff, 0x01, 0x38, 0x20, 0xff, 0x03, 0x39, 0x21, 0xff, 0x02, 0x2e, 0x17, 0xff, 0x01, 0x32, 0x18, 0xff, 0x06, 0x37, 0x1f, 0xff, 0x06, 0x31, 0x1c, 0xff, 0x00, 0x26, 0x10, 0xff, 0x05, 0x39, 0x21, 0xff, 0x06, 0x48, 0x28, 0xff, 0x06, 0x54, 0x2d, 0xff, 0x04, 0x59, 0x2c, 0xff, 0x06, 0x59, 0x2b, 0xff, 0x08, 0x4d, 0x27, 0xff, 0x04, 0x33, 0x18, 0xff, 0x0c, 0x28, 0x18, 0xff, 0x02, 0x24, 0x14, 0xff, 0x08, 0x3c, 0x26, 0xff, 0x0d, 0x44, 0x2c, 0xff, 0x06, 0x30, 0x19, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x01, 0x26, 0x16, 0xff, 0x0b, 0x3c, 0x2a, 0xff, 0x05, 0x31, 0x1e, 0xff, 0x00, 0x28, 0x12, 0xff, 0x05, 0x40, 0x23, 0xff, 0x0e, 0x56, 0x34, 0xff, 0x05, 0x4f, 0x2a, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x07, 0x3b, 0x1f, 0xff, 0x05, 0x27, 0x12, 0xff, 0x02, 0x24, 0x13, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x07, 0x4a, 0x25, 0xff, 0x14, 0x63, 0x38, 0xff, 0x0a, 0x66, 0x38, 0xff, 0x06, 0x6b, 0x38, 0xff, 0x04, 0x67, 0x38, 0xff, 0x07, 0x5e, 0x35, 0xff, 0x0d, 0x4d, 0x2d, 0xff, 0x04, 0x30, 0x16, 0xff, 0x05, 0x29, 0x16, 0xff, 0x01, 0x29, 0x16, 0xff, 0x00, 0x2d, 0x1b, 0xff, 0x20, 0x54, 0x7a, 0xff, 0x43, 0x68, 0xd7, 0xff, 0x2e, 0x4b, 0xd6, 0xff, 0x27, 0x4a, 0xd5, 0xff, 0x24, 0x4d, 0xd1, 0xff, 0x23, 0x4b, 0xd8, 0xff, 0x22, 0x45, 0xd9, 0xff, 0x2a, 0x49, 0xd3, 0xff, 0x2f, 0x4f, 0xb4, 0xff, 0x0a, 0x26, 0x48, 0xff, 0x01, 0x27, 0x18, 0xff, 0x0e, 0x55, 0x2c, 0xff, 0x0c, 0x56, 0x32, 0xff, 0x13, 0x54, 0x33, 0xff, 0x0a, 0x48, 0x24, 0xff, 0x15, 0x4a, 0x30, 0xff, 0x02, 0x25, 0x11, 0xff, 0x0f, 0x3f, 0x25, 0xff, 0x1d, 0x54, 0x37, 0xff, 0x01, 0x27, 0x13, 0xff, 0x04, 0x24, 0x13, 0xff, 0x06, 0x36, 0x1c, 0xff, 0x0d, 0x50, 0x32, 0xff, 0x6b, 0x93, 0x84, 0xff, + 0x01, 0x35, 0x1a, 0xff, 0x09, 0x4f, 0x2c, 0xff, 0x0a, 0x52, 0x2d, 0xff, 0x03, 0x3f, 0x1c, 0xff, 0x00, 0x2f, 0x14, 0xff, 0x01, 0x26, 0x10, 0xff, 0x02, 0x25, 0x12, 0xff, 0x04, 0x24, 0x13, 0xff, 0x03, 0x26, 0x11, 0xff, 0x02, 0x35, 0x19, 0xff, 0x09, 0x49, 0x2a, 0xff, 0x0e, 0x4a, 0x2b, 0xff, 0x02, 0x30, 0x15, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x01, 0x2a, 0x0f, 0xff, 0x12, 0x4e, 0x2b, 0xff, 0x12, 0x4c, 0x2d, 0xff, 0x02, 0x34, 0x1b, 0xff, 0x00, 0x29, 0x15, 0xff, 0x02, 0x26, 0x15, 0xff, 0x03, 0x25, 0x15, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x26, 0x11, 0xff, 0x01, 0x2a, 0x14, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x0b, 0x5a, 0x2c, 0xff, 0x0f, 0x56, 0x27, 0xff, 0x02, 0x2c, 0x0d, 0xff, 0x02, 0x26, 0x11, 0xff, 0x0b, 0x45, 0x26, 0xff, 0x0b, 0x54, 0x28, 0xff, 0x05, 0x59, 0x28, 0xff, 0x03, 0x5d, 0x2c, 0xff, 0x06, 0x56, 0x2e, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x01, 0x22, 0x11, 0xff, 0x07, 0x21, 0x13, 0xff, 0x03, 0x24, 0x13, 0xff, 0x00, 0x26, 0x12, 0xff, 0x00, 0x24, 0x14, 0xff, 0x01, 0x26, 0x11, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x05, 0x3b, 0x1a, 0xff, 0x0e, 0x52, 0x2f, 0xff, 0x0b, 0x4c, 0x2c, 0xff, 0x01, 0x2f, 0x14, 0xff, 0x02, 0x28, 0x14, 0xff, 0x04, 0x25, 0x16, 0xff, 0x01, 0x27, 0x14, 0xff, 0x00, 0x2c, 0x10, 0xff, 0x03, 0x35, 0x14, 0xff, 0x06, 0x3f, 0x19, 0xff, 0x04, 0x3c, 0x18, 0xff, 0x05, 0x38, 0x18, 0xff, 0x02, 0x2f, 0x12, 0xff, 0x02, 0x25, 0x08, 0xff, 0x01, 0x20, 0x05, 0xff, 0x02, 0x21, 0x04, 0xff, 0x02, 0x21, 0x04, 0xff, 0x01, 0x23, 0x03, 0xff, 0x00, 0x22, 0x01, 0xff, 0x03, 0x2c, 0x09, 0xff, 0x08, 0x38, 0x14, 0xff, 0x0a, 0x4a, 0x22, 0xff, 0x10, 0x59, 0x28, 0xff, 0x10, 0x60, 0x2e, 0xff, 0x0e, 0x61, 0x34, 0xff, 0x09, 0x61, 0x32, 0xff, 0x08, 0x62, 0x2e, 0xff, 0x0a, 0x64, 0x30, 0xff, 0x0d, 0x65, 0x37, 0xff, 0x0f, 0x69, 0x3f, 0xff, 0x12, 0x68, 0x49, 0xff, 0x1d, 0x64, 0x62, 0xff, 0x2e, 0x62, 0x83, 0xff, 0x5a, 0x77, 0xc2, 0xff, 0x73, 0x85, 0xe3, 0xff, 0x6b, 0x7e, 0xde, 0xff, 0x62, 0x79, 0xd1, 0xff, 0x3f, 0x55, 0x8c, 0xff, 0x14, 0x3c, 0x42, 0xff, 0x06, 0x52, 0x1d, 0xff, 0x0c, 0x75, 0x30, 0xff, 0x0c, 0x73, 0x3a, 0xff, 0x0f, 0x5f, 0x32, 0xff, 0x02, 0x31, 0x12, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x02, 0x27, 0x0d, 0xff, 0x02, 0x26, 0x0a, 0xff, 0x01, 0x24, 0x08, 0xff, 0x04, 0x2e, 0x11, 0xff, 0x22, 0x5c, 0x3e, 0xff, 0x0f, 0x51, 0x32, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x09, 0x37, 0x1c, 0xff, 0x09, 0x32, 0x17, 0xff, 0x09, 0x37, 0x1b, 0xff, 0x08, 0x40, 0x23, 0xff, 0x09, 0x43, 0x24, 0xff, 0x06, 0x2f, 0x12, 0xff, 0x05, 0x1f, 0x05, 0xff, 0x07, 0x30, 0x14, 0xff, 0x0f, 0x44, 0x27, 0xff, 0x08, 0x44, 0x26, 0xff, 0x0a, 0x43, 0x26, 0xff, 0x0b, 0x34, 0x19, 0xff, 0x00, 0x1f, 0x05, 0xff, 0x04, 0x27, 0x0e, 0xff, 0x0c, 0x36, 0x1d, 0xff, 0x03, 0x34, 0x11, 0xff, 0x01, 0x31, 0x0c, 0xff, 0x0b, 0x40, 0x1d, 0xff, 0x14, 0x4a, 0x28, 0xff, 0x14, 0x4a, 0x2a, 0xff, 0x12, 0x4a, 0x2b, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x02, 0x34, 0x18, 0xff, 0x06, 0x3e, 0x21, 0xff, 0x0d, 0x45, 0x28, 0xff, 0x08, 0x39, 0x1e, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x05, 0x38, 0x1e, 0xff, 0x0c, 0x41, 0x26, 0xff, 0x07, 0x35, 0x1d, 0xff, 0x05, 0x2d, 0x16, 0xff, 0x04, 0x28, 0x11, 0xff, 0x04, 0x2f, 0x16, 0xff, 0x09, 0x40, 0x22, 0xff, 0x0e, 0x49, 0x2b, 0xff, 0x07, 0x3b, 0x24, 0xff, 0x00, 0x2a, 0x18, 0xff, 0x00, 0x27, 0x11, 0xff, 0x03, 0x31, 0x14, 0xff, 0x06, 0x52, 0x23, 0xff, 0x0b, 0x54, 0x28, 0xff, 0x03, 0x33, 0x17, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x12, 0x4a, 0x2a, 0xff, 0x06, 0x36, 0x12, 0xff, 0x03, 0x25, 0x0c, 0xff, 0x01, 0x21, 0x15, 0xff, 0x01, 0x38, 0x1a, 0xff, 0x18, 0x73, 0x44, 0xff, 0x18, 0x82, 0x4f, 0xff, 0x05, 0x6e, 0x39, 0xff, 0x06, 0x6a, 0x32, 0xff, 0x0d, 0x6a, 0x33, 0xff, 0x0f, 0x6d, 0x34, 0xff, 0x0b, 0x6f, 0x34, 0xff, 0x09, 0x70, 0x37, 0xff, 0x0c, 0x6f, 0x39, 0xff, 0x0a, 0x69, 0x36, 0xff, 0x09, 0x65, 0x34, 0xff, 0x06, 0x5f, 0x30, 0xff, 0x08, 0x5d, 0x2f, 0xff, 0x0a, 0x5d, 0x2f, 0xff, 0x09, 0x5b, 0x2c, 0xff, 0x0b, 0x5c, 0x2d, 0xff, 0x09, 0x5c, 0x2d, 0xff, 0x0b, 0x5d, 0x2f, 0xff, 0x0a, 0x5c, 0x2e, 0xff, 0x09, 0x5a, 0x2c, 0xff, 0x08, 0x58, 0x2d, 0xff, 0x08, 0x57, 0x2c, 0xff, 0x07, 0x57, 0x2b, 0xff, 0x09, 0x57, 0x2c, 0xff, 0x0d, 0x57, 0x2d, 0xff, 0x0c, 0x57, 0x2c, 0xff, 0x0b, 0x58, 0x2d, 0xff, 0x0a, 0x5a, 0x2c, 0xff, 0x08, 0x59, 0x2a, 0xff, 0x09, 0x5b, 0x2d, 0xff, 0x08, 0x5c, 0x2c, 0xff, 0x02, 0x58, 0x25, 0xff, 0x04, 0x56, 0x23, 0xff, 0x11, 0x52, 0x28, 0xff, 0x0c, 0x44, 0x23, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x07, 0x39, 0x1f, 0xff, 0x01, 0x29, 0x0e, 0xff, 0x04, 0x3a, 0x1b, 0xff, 0x12, 0x53, 0x32, 0xff, 0x01, 0x34, 0x10, 0xff, 0x0a, 0x58, 0x2a, 0xff, 0x0f, 0x6e, 0x38, 0xff, 0x0a, 0x72, 0x34, 0xff, 0x08, 0x71, 0x32, 0xff, 0x08, 0x70, 0x35, 0xff, 0x07, 0x6e, 0x37, 0xff, 0x05, 0x6b, 0x37, 0xff, 0x08, 0x66, 0x37, 0xff, 0x0a, 0x5c, 0x35, 0xff, 0x0d, 0x58, 0x36, 0xff, 0x05, 0x59, 0x32, 0xff, 0x09, 0x78, 0x47, 0xff, 0x06, 0x91, 0x52, 0xff, 0x02, 0x88, 0x45, 0xff, 0x06, 0x84, 0x41, 0xff, 0x06, 0x87, 0x45, 0xff, 0x06, 0x82, 0x4b, 0xff, 0x03, 0x83, 0x4d, 0xff, 0x05, 0x84, 0x49, 0xff, 0x02, 0x80, 0x40, 0xff, 0x07, 0x82, 0x46, 0xff, 0x0b, 0x69, 0x3b, 0xff, 0x00, 0x27, 0x0d, 0xff, 0x00, 0x23, 0x10, 0xff, 0x01, 0x31, 0x1b, 0xff, 0x03, 0x33, 0x19, 0xff, 0x10, 0x42, 0x24, 0xff, 0x07, 0x40, 0x1d, 0xff, 0x04, 0x60, 0x35, 0xff, 0x0b, 0x6b, 0x40, 0xff, 0x05, 0x34, 0x12, 0xff, 0x04, 0x2d, 0x14, 0xff, 0x0e, 0x45, 0x2f, 0xff, 0x05, 0x2e, 0x19, 0xff, 0x02, 0x21, 0x0c, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x08, 0x53, 0x30, 0xff, 0x08, 0x46, 0x25, 0xff, 0x05, 0x2b, 0x14, 0xff, 0x00, 0x1e, 0x0f, 0xff, 0x01, 0x1f, 0x0e, 0xff, 0x01, 0x27, 0x11, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0e, 0x48, 0x2c, 0xff, 0x07, 0x32, 0x1a, 0xff, 0x00, 0x21, 0x10, 0xff, 0x00, 0x1f, 0x10, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x0d, 0x40, 0x26, 0xff, 0x04, 0x2e, 0x17, 0xff, 0x04, 0x23, 0x0f, 0xff, 0x03, 0x31, 0x18, 0xff, 0x02, 0x43, 0x22, 0xff, 0x0c, 0x58, 0x31, 0xff, 0x0c, 0x62, 0x37, 0xff, 0x10, 0x60, 0x37, 0xff, 0x05, 0x5b, 0x30, 0xff, 0x0a, 0x69, 0x3c, 0xff, 0x09, 0x6d, 0x3d, 0xff, 0x0b, 0x6c, 0x3d, 0xff, 0x10, 0x5f, 0x37, 0xff, 0x05, 0x42, 0x20, 0xff, 0x06, 0x35, 0x19, 0xff, 0x05, 0x30, 0x18, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x09, 0x38, 0x21, 0xff, 0x01, 0x25, 0x10, 0xff, 0x0a, 0x33, 0x1d, 0xff, 0x03, 0x36, 0x1e, 0xff, 0x06, 0x38, 0x20, 0xff, 0x05, 0x2d, 0x16, 0xff, 0x02, 0x33, 0x18, 0xff, 0x07, 0x37, 0x1d, 0xff, 0x07, 0x32, 0x1b, 0xff, 0x01, 0x25, 0x0f, 0xff, 0x07, 0x39, 0x20, 0xff, 0x08, 0x4b, 0x2a, 0xff, 0x07, 0x56, 0x2c, 0xff, 0x05, 0x5c, 0x2c, 0xff, 0x02, 0x5d, 0x2a, 0xff, 0x0b, 0x57, 0x2e, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x0e, 0x2c, 0x1a, 0xff, 0x02, 0x23, 0x10, 0xff, 0x04, 0x3a, 0x21, 0xff, 0x0a, 0x46, 0x2a, 0xff, 0x07, 0x35, 0x1c, 0xff, 0x02, 0x1f, 0x0e, 0xff, 0x02, 0x25, 0x13, 0xff, 0x0d, 0x3a, 0x28, 0xff, 0x09, 0x35, 0x21, 0xff, 0x00, 0x2a, 0x12, 0xff, 0x08, 0x43, 0x24, 0xff, 0x11, 0x56, 0x32, 0xff, 0x09, 0x50, 0x28, 0xff, 0x08, 0x53, 0x2d, 0xff, 0x05, 0x39, 0x1c, 0xff, 0x06, 0x25, 0x10, 0xff, 0x02, 0x26, 0x12, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x0b, 0x61, 0x37, 0xff, 0x0a, 0x69, 0x38, 0xff, 0x08, 0x6b, 0x36, 0xff, 0x08, 0x69, 0x36, 0xff, 0x08, 0x60, 0x33, 0xff, 0x0c, 0x59, 0x32, 0xff, 0x04, 0x3a, 0x1c, 0xff, 0x01, 0x27, 0x0e, 0xff, 0x02, 0x29, 0x11, 0xff, 0x02, 0x3b, 0x1f, 0xff, 0x03, 0x5a, 0x38, 0xff, 0x15, 0x60, 0x70, 0xff, 0x42, 0x6f, 0xce, 0xff, 0x30, 0x4f, 0xd7, 0xff, 0x26, 0x45, 0xd8, 0xff, 0x23, 0x49, 0xd2, 0xff, 0x22, 0x47, 0xd5, 0xff, 0x27, 0x47, 0xdc, 0xff, 0x26, 0x44, 0xd0, 0xff, 0x29, 0x49, 0xc3, 0xff, 0x1b, 0x37, 0x76, 0xff, 0x03, 0x20, 0x24, 0xff, 0x08, 0x4f, 0x2d, 0xff, 0x0a, 0x54, 0x38, 0xff, 0x10, 0x4c, 0x33, 0xff, 0x0b, 0x4b, 0x2d, 0xff, 0x0f, 0x49, 0x31, 0xff, 0x00, 0x26, 0x12, 0xff, 0x0b, 0x3f, 0x22, 0xff, 0x1d, 0x5a, 0x39, 0xff, 0x01, 0x2a, 0x12, 0xff, 0x04, 0x26, 0x13, 0xff, 0x07, 0x3a, 0x1e, 0xff, 0x0a, 0x52, 0x31, 0xff, 0x6b, 0x97, 0x85, 0xff, + 0x04, 0x36, 0x19, 0xff, 0x0b, 0x51, 0x2b, 0xff, 0x0b, 0x52, 0x2c, 0xff, 0x03, 0x3a, 0x1b, 0xff, 0x04, 0x2d, 0x15, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x26, 0x11, 0xff, 0x05, 0x24, 0x12, 0xff, 0x04, 0x26, 0x11, 0xff, 0x01, 0x36, 0x19, 0xff, 0x07, 0x4b, 0x29, 0xff, 0x0d, 0x4d, 0x2b, 0xff, 0x02, 0x31, 0x15, 0xff, 0x02, 0x26, 0x0f, 0xff, 0x01, 0x28, 0x0e, 0xff, 0x13, 0x47, 0x28, 0xff, 0x14, 0x46, 0x2b, 0xff, 0x02, 0x30, 0x18, 0xff, 0x00, 0x28, 0x14, 0xff, 0x03, 0x25, 0x14, 0xff, 0x05, 0x26, 0x14, 0xff, 0x00, 0x25, 0x12, 0xff, 0x02, 0x26, 0x13, 0xff, 0x01, 0x2d, 0x15, 0xff, 0x02, 0x45, 0x23, 0xff, 0x08, 0x5b, 0x2e, 0xff, 0x0f, 0x52, 0x27, 0xff, 0x02, 0x28, 0x0c, 0xff, 0x02, 0x29, 0x14, 0xff, 0x09, 0x49, 0x27, 0xff, 0x0b, 0x57, 0x27, 0xff, 0x05, 0x5a, 0x26, 0xff, 0x06, 0x5d, 0x2d, 0xff, 0x08, 0x51, 0x2c, 0xff, 0x02, 0x32, 0x18, 0xff, 0x02, 0x20, 0x0f, 0xff, 0x06, 0x22, 0x12, 0xff, 0x03, 0x25, 0x11, 0xff, 0x02, 0x25, 0x11, 0xff, 0x01, 0x25, 0x14, 0xff, 0x00, 0x27, 0x10, 0xff, 0x03, 0x37, 0x17, 0xff, 0x0d, 0x4d, 0x28, 0xff, 0x0f, 0x51, 0x2d, 0xff, 0x06, 0x41, 0x22, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x03, 0x28, 0x13, 0xff, 0x04, 0x28, 0x14, 0xff, 0x00, 0x29, 0x11, 0xff, 0x02, 0x32, 0x15, 0xff, 0x06, 0x3c, 0x1b, 0xff, 0x08, 0x3d, 0x1a, 0xff, 0x05, 0x36, 0x15, 0xff, 0x00, 0x2b, 0x0e, 0xff, 0x00, 0x23, 0x08, 0xff, 0x03, 0x21, 0x02, 0xff, 0x01, 0x21, 0x01, 0xff, 0x00, 0x20, 0x01, 0xff, 0x01, 0x24, 0x02, 0xff, 0x03, 0x32, 0x0d, 0xff, 0x0a, 0x45, 0x1d, 0xff, 0x14, 0x58, 0x2c, 0xff, 0x16, 0x5e, 0x31, 0xff, 0x0e, 0x63, 0x32, 0xff, 0x0d, 0x66, 0x30, 0xff, 0x06, 0x64, 0x2d, 0xff, 0x01, 0x62, 0x2f, 0xff, 0x01, 0x66, 0x32, 0xff, 0x04, 0x6c, 0x33, 0xff, 0x12, 0x75, 0x3f, 0xff, 0x16, 0x71, 0x45, 0xff, 0x1b, 0x61, 0x56, 0xff, 0x1e, 0x5b, 0x69, 0xff, 0x4b, 0x77, 0xad, 0xff, 0x4e, 0x6b, 0xbf, 0xff, 0x61, 0x72, 0xd8, 0xff, 0x6b, 0x79, 0xdc, 0xff, 0x57, 0x6a, 0xb9, 0xff, 0x48, 0x61, 0xa1, 0xff, 0x26, 0x43, 0x61, 0xff, 0x06, 0x28, 0x23, 0xff, 0x02, 0x43, 0x13, 0xff, 0x0c, 0x70, 0x30, 0xff, 0x0d, 0x76, 0x3c, 0xff, 0x12, 0x62, 0x33, 0xff, 0x02, 0x32, 0x12, 0xff, 0x03, 0x2c, 0x10, 0xff, 0x04, 0x2e, 0x13, 0xff, 0x08, 0x2f, 0x13, 0xff, 0x06, 0x2b, 0x0f, 0xff, 0x04, 0x26, 0x0a, 0xff, 0x02, 0x21, 0x06, 0xff, 0x01, 0x1e, 0x03, 0xff, 0x15, 0x3f, 0x23, 0xff, 0x20, 0x57, 0x39, 0xff, 0x0a, 0x41, 0x23, 0xff, 0x09, 0x39, 0x1b, 0xff, 0x08, 0x32, 0x15, 0xff, 0x0e, 0x39, 0x1d, 0xff, 0x0d, 0x40, 0x24, 0xff, 0x04, 0x35, 0x18, 0xff, 0x02, 0x20, 0x04, 0xff, 0x0a, 0x1f, 0x04, 0xff, 0x05, 0x27, 0x0c, 0xff, 0x11, 0x45, 0x27, 0xff, 0x07, 0x44, 0x26, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x05, 0x2c, 0x11, 0xff, 0x01, 0x20, 0x06, 0xff, 0x09, 0x36, 0x1b, 0xff, 0x0b, 0x3e, 0x23, 0xff, 0x07, 0x40, 0x1c, 0xff, 0x05, 0x37, 0x12, 0xff, 0x03, 0x2b, 0x0c, 0xff, 0x0a, 0x32, 0x14, 0xff, 0x13, 0x44, 0x24, 0xff, 0x15, 0x4c, 0x2a, 0xff, 0x13, 0x46, 0x27, 0xff, 0x0e, 0x3c, 0x1e, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x06, 0x38, 0x1d, 0xff, 0x10, 0x43, 0x25, 0xff, 0x0b, 0x3f, 0x21, 0xff, 0x01, 0x31, 0x15, 0xff, 0x03, 0x36, 0x1b, 0xff, 0x0f, 0x3e, 0x24, 0xff, 0x13, 0x37, 0x1f, 0xff, 0x0a, 0x2a, 0x19, 0xff, 0x03, 0x28, 0x15, 0xff, 0x01, 0x30, 0x14, 0xff, 0x06, 0x3d, 0x1e, 0xff, 0x10, 0x45, 0x2a, 0xff, 0x09, 0x38, 0x21, 0xff, 0x01, 0x29, 0x13, 0xff, 0x01, 0x2a, 0x12, 0xff, 0x04, 0x47, 0x1d, 0xff, 0x0b, 0x54, 0x2a, 0xff, 0x06, 0x3c, 0x1b, 0xff, 0x03, 0x2f, 0x13, 0xff, 0x0b, 0x39, 0x1f, 0xff, 0x02, 0x25, 0x0f, 0xff, 0x09, 0x22, 0x0f, 0xff, 0x02, 0x2b, 0x11, 0xff, 0x18, 0x7b, 0x4a, 0xff, 0x1c, 0x91, 0x56, 0xff, 0x03, 0x71, 0x38, 0xff, 0x07, 0x70, 0x36, 0xff, 0x0e, 0x6f, 0x36, 0xff, 0x12, 0x71, 0x37, 0xff, 0x11, 0x72, 0x36, 0xff, 0x0c, 0x73, 0x35, 0xff, 0x0c, 0x74, 0x38, 0xff, 0x08, 0x6e, 0x35, 0xff, 0x08, 0x68, 0x33, 0xff, 0x09, 0x65, 0x33, 0xff, 0x09, 0x60, 0x31, 0xff, 0x0d, 0x61, 0x33, 0xff, 0x0e, 0x60, 0x32, 0xff, 0x0c, 0x5e, 0x30, 0xff, 0x0c, 0x5f, 0x30, 0xff, 0x0d, 0x5f, 0x30, 0xff, 0x10, 0x5f, 0x34, 0xff, 0x10, 0x5d, 0x32, 0xff, 0x10, 0x59, 0x31, 0xff, 0x10, 0x56, 0x2e, 0xff, 0x0d, 0x51, 0x2b, 0xff, 0x0c, 0x4f, 0x29, 0xff, 0x0c, 0x4e, 0x2a, 0xff, 0x0d, 0x4d, 0x2b, 0xff, 0x0d, 0x4e, 0x2a, 0xff, 0x10, 0x53, 0x2e, 0xff, 0x12, 0x59, 0x30, 0xff, 0x10, 0x5a, 0x31, 0xff, 0x11, 0x5f, 0x34, 0xff, 0x10, 0x61, 0x34, 0xff, 0x06, 0x5e, 0x2d, 0xff, 0x03, 0x5a, 0x28, 0xff, 0x09, 0x55, 0x28, 0xff, 0x0f, 0x52, 0x29, 0xff, 0x07, 0x41, 0x1f, 0xff, 0x03, 0x3b, 0x1b, 0xff, 0x02, 0x2f, 0x12, 0xff, 0x06, 0x39, 0x1c, 0xff, 0x10, 0x55, 0x31, 0xff, 0x02, 0x4a, 0x1d, 0xff, 0x0d, 0x6e, 0x34, 0xff, 0x09, 0x74, 0x32, 0xff, 0x07, 0x74, 0x30, 0xff, 0x0b, 0x71, 0x33, 0xff, 0x0d, 0x6f, 0x38, 0xff, 0x07, 0x6e, 0x37, 0xff, 0x02, 0x6a, 0x36, 0xff, 0x05, 0x63, 0x36, 0xff, 0x10, 0x59, 0x38, 0xff, 0x13, 0x54, 0x39, 0xff, 0x09, 0x53, 0x32, 0xff, 0x0c, 0x72, 0x44, 0xff, 0x06, 0x90, 0x53, 0xff, 0x02, 0x85, 0x47, 0xff, 0x06, 0x81, 0x43, 0xff, 0x07, 0x82, 0x45, 0xff, 0x09, 0x81, 0x4b, 0xff, 0x04, 0x81, 0x4b, 0xff, 0x06, 0x83, 0x49, 0xff, 0x05, 0x7f, 0x43, 0xff, 0x04, 0x7f, 0x45, 0xff, 0x0c, 0x75, 0x44, 0xff, 0x02, 0x36, 0x14, 0xff, 0x02, 0x23, 0x0e, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x0e, 0x40, 0x22, 0xff, 0x06, 0x3f, 0x1c, 0xff, 0x04, 0x63, 0x36, 0xff, 0x0a, 0x6d, 0x3f, 0xff, 0x06, 0x39, 0x15, 0xff, 0x04, 0x29, 0x11, 0xff, 0x0d, 0x46, 0x2d, 0xff, 0x05, 0x2e, 0x19, 0xff, 0x05, 0x21, 0x0d, 0xff, 0x0c, 0x46, 0x28, 0xff, 0x09, 0x60, 0x36, 0xff, 0x08, 0x48, 0x24, 0xff, 0x09, 0x33, 0x1c, 0xff, 0x00, 0x1e, 0x0e, 0xff, 0x01, 0x1f, 0x0d, 0xff, 0x01, 0x28, 0x10, 0xff, 0x08, 0x43, 0x26, 0xff, 0x0d, 0x4a, 0x2c, 0xff, 0x08, 0x34, 0x1b, 0xff, 0x01, 0x22, 0x10, 0xff, 0x00, 0x1f, 0x10, 0xff, 0x02, 0x26, 0x10, 0xff, 0x0d, 0x40, 0x26, 0xff, 0x06, 0x2e, 0x18, 0xff, 0x04, 0x23, 0x0e, 0xff, 0x05, 0x33, 0x1b, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x0a, 0x53, 0x2e, 0xff, 0x12, 0x61, 0x38, 0xff, 0x11, 0x60, 0x36, 0xff, 0x07, 0x59, 0x2f, 0xff, 0x09, 0x64, 0x37, 0xff, 0x09, 0x6c, 0x3c, 0xff, 0x07, 0x6b, 0x3c, 0xff, 0x11, 0x69, 0x3e, 0xff, 0x0b, 0x53, 0x2d, 0xff, 0x01, 0x35, 0x16, 0xff, 0x06, 0x30, 0x17, 0xff, 0x04, 0x2c, 0x17, 0xff, 0x0d, 0x33, 0x20, 0xff, 0x02, 0x25, 0x10, 0xff, 0x0a, 0x35, 0x1b, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x06, 0x38, 0x1e, 0xff, 0x04, 0x2b, 0x17, 0xff, 0x03, 0x32, 0x19, 0xff, 0x06, 0x36, 0x1c, 0xff, 0x07, 0x33, 0x1a, 0xff, 0x01, 0x24, 0x10, 0xff, 0x08, 0x36, 0x1f, 0xff, 0x0a, 0x4f, 0x2a, 0xff, 0x06, 0x59, 0x2b, 0xff, 0x06, 0x5e, 0x2d, 0xff, 0x02, 0x5f, 0x2d, 0xff, 0x0c, 0x60, 0x30, 0xff, 0x05, 0x42, 0x1e, 0xff, 0x0d, 0x2f, 0x1a, 0xff, 0x02, 0x23, 0x12, 0xff, 0x04, 0x37, 0x1e, 0xff, 0x0a, 0x48, 0x2a, 0xff, 0x08, 0x3a, 0x20, 0xff, 0x02, 0x20, 0x0f, 0xff, 0x02, 0x23, 0x13, 0xff, 0x0b, 0x3a, 0x26, 0xff, 0x0a, 0x3a, 0x23, 0xff, 0x00, 0x2c, 0x12, 0xff, 0x09, 0x44, 0x25, 0xff, 0x0f, 0x56, 0x31, 0xff, 0x09, 0x51, 0x29, 0xff, 0x09, 0x53, 0x2f, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x04, 0x25, 0x0c, 0xff, 0x01, 0x33, 0x15, 0xff, 0x08, 0x59, 0x34, 0xff, 0x08, 0x6a, 0x3b, 0xff, 0x08, 0x6a, 0x37, 0xff, 0x07, 0x6c, 0x36, 0xff, 0x0c, 0x68, 0x35, 0xff, 0x0f, 0x5e, 0x34, 0xff, 0x09, 0x49, 0x26, 0xff, 0x00, 0x29, 0x0f, 0xff, 0x00, 0x2a, 0x0b, 0xff, 0x05, 0x51, 0x28, 0xff, 0x16, 0x89, 0x58, 0xff, 0x1e, 0xa4, 0x76, 0xff, 0x30, 0x8c, 0x9e, 0xff, 0x43, 0x6f, 0xd3, 0xff, 0x33, 0x54, 0xdb, 0xff, 0x2a, 0x46, 0xdd, 0xff, 0x25, 0x47, 0xd8, 0xff, 0x24, 0x46, 0xd4, 0xff, 0x28, 0x47, 0xd7, 0xff, 0x2a, 0x47, 0xd3, 0xff, 0x21, 0x40, 0xca, 0xff, 0x28, 0x45, 0xa7, 0xff, 0x0a, 0x28, 0x45, 0xff, 0x03, 0x44, 0x2a, 0xff, 0x0d, 0x55, 0x3e, 0xff, 0x0c, 0x45, 0x2f, 0xff, 0x0b, 0x4c, 0x34, 0xff, 0x0b, 0x4b, 0x34, 0xff, 0x01, 0x27, 0x10, 0xff, 0x0a, 0x41, 0x25, 0xff, 0x1d, 0x5c, 0x3b, 0xff, 0x02, 0x2a, 0x12, 0xff, 0x03, 0x28, 0x15, 0xff, 0x08, 0x3e, 0x22, 0xff, 0x0a, 0x53, 0x32, 0xff, 0x6d, 0x9a, 0x85, 0xff, + 0x08, 0x38, 0x19, 0xff, 0x0b, 0x53, 0x2a, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x08, 0x2c, 0x17, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x26, 0x11, 0xff, 0x01, 0x25, 0x11, 0xff, 0x02, 0x27, 0x11, 0xff, 0x00, 0x38, 0x1a, 0xff, 0x05, 0x4f, 0x29, 0xff, 0x0a, 0x52, 0x2c, 0xff, 0x02, 0x35, 0x15, 0xff, 0x03, 0x26, 0x12, 0xff, 0x01, 0x25, 0x10, 0xff, 0x0e, 0x3d, 0x22, 0xff, 0x10, 0x40, 0x26, 0xff, 0x00, 0x2b, 0x15, 0xff, 0x00, 0x27, 0x13, 0xff, 0x03, 0x25, 0x14, 0xff, 0x03, 0x25, 0x14, 0xff, 0x00, 0x24, 0x13, 0xff, 0x01, 0x26, 0x15, 0xff, 0x01, 0x30, 0x18, 0xff, 0x04, 0x4e, 0x28, 0xff, 0x06, 0x5b, 0x2f, 0xff, 0x0c, 0x4c, 0x28, 0xff, 0x01, 0x24, 0x0e, 0xff, 0x01, 0x2d, 0x16, 0xff, 0x07, 0x4e, 0x27, 0xff, 0x09, 0x58, 0x27, 0xff, 0x02, 0x5a, 0x27, 0xff, 0x05, 0x5c, 0x2f, 0xff, 0x07, 0x49, 0x26, 0xff, 0x02, 0x2a, 0x13, 0xff, 0x02, 0x22, 0x0f, 0xff, 0x00, 0x25, 0x11, 0xff, 0x03, 0x27, 0x11, 0xff, 0x07, 0x24, 0x10, 0xff, 0x02, 0x24, 0x12, 0xff, 0x00, 0x2b, 0x10, 0xff, 0x08, 0x49, 0x24, 0xff, 0x0d, 0x53, 0x2e, 0xff, 0x0f, 0x4a, 0x2a, 0xff, 0x02, 0x30, 0x15, 0xff, 0x03, 0x28, 0x12, 0xff, 0x05, 0x28, 0x13, 0xff, 0x01, 0x27, 0x0e, 0xff, 0x00, 0x2a, 0x0f, 0xff, 0x08, 0x39, 0x1c, 0xff, 0x09, 0x39, 0x1d, 0xff, 0x07, 0x31, 0x15, 0xff, 0x03, 0x26, 0x0b, 0xff, 0x03, 0x21, 0x07, 0xff, 0x02, 0x1f, 0x04, 0xff, 0x02, 0x22, 0x01, 0xff, 0x02, 0x26, 0x04, 0xff, 0x05, 0x38, 0x10, 0xff, 0x0c, 0x4f, 0x21, 0xff, 0x0f, 0x64, 0x33, 0xff, 0x0f, 0x69, 0x35, 0xff, 0x0c, 0x67, 0x32, 0xff, 0x0b, 0x64, 0x2f, 0xff, 0x05, 0x63, 0x2c, 0xff, 0x06, 0x63, 0x2e, 0xff, 0x06, 0x66, 0x32, 0xff, 0x09, 0x6e, 0x38, 0xff, 0x12, 0x78, 0x43, 0xff, 0x17, 0x77, 0x46, 0xff, 0x0e, 0x5c, 0x36, 0xff, 0x11, 0x53, 0x3d, 0xff, 0x3a, 0x5f, 0x80, 0xff, 0x4b, 0x65, 0xa1, 0xff, 0x63, 0x75, 0xd2, 0xff, 0x4c, 0x59, 0xc6, 0xff, 0x6e, 0x7c, 0xe5, 0xff, 0x6e, 0x80, 0xd3, 0xff, 0x56, 0x71, 0xa2, 0xff, 0x2f, 0x50, 0x6b, 0xff, 0x0a, 0x30, 0x29, 0xff, 0x05, 0x25, 0x12, 0xff, 0x03, 0x38, 0x15, 0xff, 0x08, 0x61, 0x30, 0xff, 0x0b, 0x76, 0x41, 0xff, 0x0a, 0x60, 0x30, 0xff, 0x01, 0x36, 0x14, 0xff, 0x02, 0x36, 0x19, 0xff, 0x02, 0x39, 0x1a, 0xff, 0x06, 0x39, 0x19, 0xff, 0x08, 0x38, 0x18, 0xff, 0x06, 0x36, 0x15, 0xff, 0x06, 0x2d, 0x0f, 0xff, 0x04, 0x23, 0x06, 0xff, 0x04, 0x22, 0x07, 0xff, 0x1d, 0x45, 0x29, 0xff, 0x16, 0x50, 0x2e, 0xff, 0x05, 0x3c, 0x1a, 0xff, 0x05, 0x36, 0x18, 0xff, 0x12, 0x3e, 0x22, 0xff, 0x0d, 0x38, 0x1d, 0xff, 0x00, 0x23, 0x08, 0xff, 0x01, 0x20, 0x05, 0xff, 0x07, 0x21, 0x05, 0xff, 0x05, 0x22, 0x08, 0xff, 0x10, 0x3d, 0x23, 0xff, 0x0c, 0x47, 0x29, 0xff, 0x0c, 0x40, 0x24, 0xff, 0x03, 0x25, 0x0b, 0xff, 0x04, 0x28, 0x0e, 0xff, 0x0c, 0x41, 0x25, 0xff, 0x08, 0x43, 0x25, 0xff, 0x09, 0x44, 0x20, 0xff, 0x0e, 0x3e, 0x1f, 0xff, 0x03, 0x25, 0x0c, 0xff, 0x00, 0x20, 0x07, 0xff, 0x03, 0x2b, 0x0b, 0xff, 0x06, 0x39, 0x13, 0xff, 0x10, 0x44, 0x1e, 0xff, 0x16, 0x44, 0x24, 0xff, 0x0e, 0x33, 0x1d, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x05, 0x3a, 0x1b, 0xff, 0x0c, 0x43, 0x23, 0xff, 0x08, 0x3c, 0x21, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x07, 0x34, 0x19, 0xff, 0x14, 0x3c, 0x22, 0xff, 0x0c, 0x34, 0x25, 0xff, 0x04, 0x2c, 0x1d, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x01, 0x2f, 0x12, 0xff, 0x08, 0x39, 0x1c, 0xff, 0x0f, 0x3e, 0x24, 0xff, 0x04, 0x2e, 0x18, 0xff, 0x00, 0x28, 0x12, 0xff, 0x00, 0x35, 0x16, 0xff, 0x06, 0x4f, 0x29, 0xff, 0x09, 0x45, 0x1f, 0xff, 0x01, 0x2d, 0x0b, 0xff, 0x01, 0x28, 0x15, 0xff, 0x01, 0x21, 0x19, 0xff, 0x04, 0x24, 0x13, 0xff, 0x0c, 0x5b, 0x2b, 0xff, 0x21, 0x9d, 0x5b, 0xff, 0x04, 0x7b, 0x3a, 0xff, 0x03, 0x76, 0x33, 0xff, 0x04, 0x75, 0x32, 0xff, 0x0c, 0x78, 0x35, 0xff, 0x0f, 0x77, 0x36, 0xff, 0x0d, 0x74, 0x37, 0xff, 0x0a, 0x71, 0x37, 0xff, 0x07, 0x6d, 0x34, 0xff, 0x03, 0x67, 0x2e, 0xff, 0x04, 0x65, 0x30, 0xff, 0x06, 0x63, 0x32, 0xff, 0x0a, 0x63, 0x35, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x0d, 0x5f, 0x34, 0xff, 0x0f, 0x5f, 0x36, 0xff, 0x0f, 0x5d, 0x34, 0xff, 0x0e, 0x59, 0x31, 0xff, 0x0b, 0x52, 0x2c, 0xff, 0x0a, 0x4a, 0x28, 0xff, 0x07, 0x3f, 0x21, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x03, 0x31, 0x16, 0xff, 0x03, 0x30, 0x15, 0xff, 0x02, 0x30, 0x16, 0xff, 0x01, 0x30, 0x17, 0xff, 0x02, 0x31, 0x17, 0xff, 0x04, 0x37, 0x1c, 0xff, 0x07, 0x40, 0x21, 0xff, 0x0a, 0x47, 0x27, 0xff, 0x0d, 0x52, 0x30, 0xff, 0x11, 0x5a, 0x36, 0xff, 0x13, 0x60, 0x39, 0xff, 0x10, 0x60, 0x37, 0xff, 0x05, 0x59, 0x2d, 0xff, 0x08, 0x55, 0x29, 0xff, 0x10, 0x4f, 0x27, 0xff, 0x03, 0x45, 0x1f, 0xff, 0x02, 0x33, 0x16, 0xff, 0x05, 0x31, 0x18, 0xff, 0x06, 0x4f, 0x2a, 0xff, 0x09, 0x67, 0x31, 0xff, 0x0a, 0x78, 0x34, 0xff, 0x04, 0x77, 0x2e, 0xff, 0x08, 0x74, 0x31, 0xff, 0x0f, 0x70, 0x37, 0xff, 0x0d, 0x6c, 0x36, 0xff, 0x07, 0x6b, 0x34, 0xff, 0x01, 0x6c, 0x33, 0xff, 0x03, 0x65, 0x33, 0xff, 0x16, 0x57, 0x37, 0xff, 0x16, 0x4d, 0x35, 0xff, 0x04, 0x40, 0x21, 0xff, 0x0c, 0x62, 0x35, 0xff, 0x05, 0x8e, 0x4e, 0xff, 0x02, 0x7f, 0x43, 0xff, 0x05, 0x7c, 0x43, 0xff, 0x03, 0x7e, 0x42, 0xff, 0x05, 0x82, 0x46, 0xff, 0x01, 0x81, 0x43, 0xff, 0x02, 0x81, 0x43, 0xff, 0x03, 0x7e, 0x42, 0xff, 0x09, 0x7d, 0x45, 0xff, 0x10, 0x7d, 0x48, 0xff, 0x03, 0x48, 0x1e, 0xff, 0x04, 0x24, 0x0c, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x00, 0x34, 0x1c, 0xff, 0x0a, 0x3c, 0x20, 0xff, 0x06, 0x3e, 0x1b, 0xff, 0x05, 0x63, 0x35, 0xff, 0x0a, 0x6e, 0x3e, 0xff, 0x08, 0x43, 0x1c, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x07, 0x46, 0x2b, 0xff, 0x04, 0x2c, 0x17, 0xff, 0x05, 0x1e, 0x0d, 0xff, 0x07, 0x46, 0x26, 0xff, 0x07, 0x6d, 0x3d, 0xff, 0x05, 0x49, 0x23, 0xff, 0x0a, 0x3c, 0x26, 0xff, 0x01, 0x21, 0x10, 0xff, 0x03, 0x1f, 0x0e, 0xff, 0x01, 0x26, 0x10, 0xff, 0x05, 0x43, 0x25, 0xff, 0x0c, 0x4a, 0x2b, 0xff, 0x0b, 0x36, 0x1c, 0xff, 0x02, 0x22, 0x10, 0xff, 0x00, 0x1e, 0x11, 0xff, 0x04, 0x25, 0x10, 0xff, 0x0b, 0x40, 0x28, 0xff, 0x06, 0x2e, 0x19, 0xff, 0x01, 0x24, 0x0f, 0xff, 0x08, 0x3a, 0x21, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x04, 0x4d, 0x28, 0xff, 0x10, 0x5f, 0x35, 0xff, 0x0c, 0x62, 0x36, 0xff, 0x09, 0x5d, 0x31, 0xff, 0x08, 0x5e, 0x32, 0xff, 0x0c, 0x6a, 0x3d, 0xff, 0x06, 0x6d, 0x3e, 0xff, 0x07, 0x6b, 0x3e, 0xff, 0x0d, 0x64, 0x39, 0xff, 0x02, 0x44, 0x1e, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x03, 0x26, 0x16, 0xff, 0x0d, 0x2c, 0x1f, 0xff, 0x01, 0x24, 0x11, 0xff, 0x05, 0x36, 0x19, 0xff, 0x02, 0x3a, 0x18, 0xff, 0x05, 0x38, 0x1d, 0xff, 0x01, 0x29, 0x18, 0xff, 0x02, 0x2f, 0x1c, 0xff, 0x04, 0x38, 0x1c, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x00, 0x22, 0x11, 0xff, 0x07, 0x33, 0x20, 0xff, 0x09, 0x52, 0x2c, 0xff, 0x04, 0x5e, 0x2c, 0xff, 0x06, 0x5f, 0x2f, 0xff, 0x03, 0x5e, 0x2f, 0xff, 0x0b, 0x66, 0x31, 0xff, 0x07, 0x51, 0x22, 0xff, 0x07, 0x2e, 0x18, 0xff, 0x05, 0x25, 0x18, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x0b, 0x46, 0x29, 0xff, 0x08, 0x3b, 0x23, 0xff, 0x00, 0x22, 0x10, 0xff, 0x01, 0x23, 0x12, 0xff, 0x05, 0x3a, 0x25, 0xff, 0x07, 0x3e, 0x24, 0xff, 0x00, 0x2c, 0x11, 0xff, 0x06, 0x45, 0x26, 0xff, 0x0a, 0x57, 0x33, 0xff, 0x04, 0x52, 0x2c, 0xff, 0x0b, 0x53, 0x33, 0xff, 0x03, 0x33, 0x17, 0xff, 0x00, 0x29, 0x0b, 0xff, 0x05, 0x4f, 0x27, 0xff, 0x05, 0x6a, 0x39, 0xff, 0x07, 0x69, 0x37, 0xff, 0x0e, 0x69, 0x38, 0xff, 0x06, 0x69, 0x36, 0xff, 0x0c, 0x66, 0x34, 0xff, 0x0c, 0x54, 0x30, 0xff, 0x01, 0x33, 0x18, 0xff, 0x00, 0x27, 0x14, 0xff, 0x03, 0x41, 0x1d, 0xff, 0x1d, 0xa2, 0x67, 0xff, 0x1b, 0xc3, 0x7f, 0xff, 0x19, 0xb3, 0x86, 0xff, 0x2e, 0x84, 0xb4, 0xff, 0x3c, 0x60, 0xd9, 0xff, 0x2f, 0x50, 0xd6, 0xff, 0x27, 0x47, 0xd7, 0xff, 0x26, 0x45, 0xd5, 0xff, 0x25, 0x46, 0xd1, 0xff, 0x23, 0x44, 0xce, 0xff, 0x28, 0x46, 0xd3, 0xff, 0x24, 0x41, 0xd1, 0xff, 0x23, 0x3f, 0xbd, 0xff, 0x12, 0x36, 0x6d, 0xff, 0x02, 0x3b, 0x26, 0xff, 0x0d, 0x56, 0x3b, 0xff, 0x09, 0x43, 0x29, 0xff, 0x0b, 0x4f, 0x3a, 0xff, 0x11, 0x57, 0x3c, 0xff, 0x02, 0x28, 0x0d, 0xff, 0x0c, 0x44, 0x29, 0xff, 0x1f, 0x5e, 0x3e, 0xff, 0x03, 0x29, 0x12, 0xff, 0x01, 0x27, 0x16, 0xff, 0x09, 0x40, 0x26, 0xff, 0x0b, 0x52, 0x34, 0xff, 0x6c, 0x98, 0x86, 0xff, + 0x08, 0x39, 0x1a, 0xff, 0x0b, 0x53, 0x2a, 0xff, 0x06, 0x50, 0x28, 0xff, 0x02, 0x33, 0x17, 0xff, 0x07, 0x2a, 0x16, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x25, 0x11, 0xff, 0x02, 0x27, 0x11, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x07, 0x52, 0x2b, 0xff, 0x0b, 0x56, 0x2d, 0xff, 0x02, 0x37, 0x17, 0xff, 0x02, 0x26, 0x12, 0xff, 0x01, 0x24, 0x11, 0xff, 0x07, 0x34, 0x1a, 0xff, 0x08, 0x37, 0x1e, 0xff, 0x00, 0x29, 0x13, 0xff, 0x00, 0x25, 0x12, 0xff, 0x04, 0x25, 0x14, 0xff, 0x04, 0x24, 0x13, 0xff, 0x00, 0x24, 0x13, 0xff, 0x01, 0x28, 0x14, 0xff, 0x02, 0x38, 0x1d, 0xff, 0x08, 0x56, 0x2d, 0xff, 0x05, 0x5d, 0x2f, 0xff, 0x08, 0x48, 0x24, 0xff, 0x00, 0x22, 0x0d, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x07, 0x50, 0x28, 0xff, 0x07, 0x57, 0x27, 0xff, 0x05, 0x5d, 0x2b, 0xff, 0x06, 0x5c, 0x30, 0xff, 0x03, 0x40, 0x21, 0xff, 0x01, 0x25, 0x0f, 0xff, 0x03, 0x22, 0x11, 0xff, 0x01, 0x25, 0x12, 0xff, 0x02, 0x27, 0x12, 0xff, 0x06, 0x26, 0x12, 0xff, 0x01, 0x26, 0x11, 0xff, 0x06, 0x3b, 0x1e, 0xff, 0x0d, 0x53, 0x2d, 0xff, 0x0c, 0x52, 0x2d, 0xff, 0x06, 0x3f, 0x21, 0xff, 0x00, 0x28, 0x10, 0xff, 0x03, 0x28, 0x14, 0xff, 0x03, 0x27, 0x14, 0xff, 0x01, 0x29, 0x10, 0xff, 0x04, 0x2e, 0x13, 0xff, 0x0a, 0x35, 0x19, 0xff, 0x05, 0x2e, 0x10, 0xff, 0x01, 0x24, 0x07, 0xff, 0x01, 0x22, 0x05, 0xff, 0x01, 0x21, 0x02, 0xff, 0x02, 0x27, 0x06, 0xff, 0x06, 0x3d, 0x18, 0xff, 0x10, 0x56, 0x2b, 0xff, 0x12, 0x6b, 0x33, 0xff, 0x0b, 0x72, 0x33, 0xff, 0x08, 0x75, 0x32, 0xff, 0x05, 0x70, 0x31, 0xff, 0x02, 0x66, 0x2e, 0xff, 0x03, 0x64, 0x2f, 0xff, 0x07, 0x6a, 0x35, 0xff, 0x0c, 0x74, 0x3f, 0xff, 0x12, 0x7b, 0x47, 0xff, 0x10, 0x71, 0x3e, 0xff, 0x0f, 0x5f, 0x2e, 0xff, 0x07, 0x46, 0x1c, 0xff, 0x02, 0x33, 0x13, 0xff, 0x14, 0x40, 0x32, 0xff, 0x49, 0x62, 0x91, 0xff, 0x55, 0x67, 0xac, 0xff, 0x5f, 0x6c, 0xc8, 0xff, 0x48, 0x54, 0xb5, 0xff, 0x63, 0x73, 0xc5, 0xff, 0x63, 0x7a, 0xb3, 0xff, 0x31, 0x52, 0x68, 0xff, 0x0d, 0x30, 0x34, 0xff, 0x01, 0x26, 0x13, 0xff, 0x08, 0x2c, 0x12, 0xff, 0x06, 0x3a, 0x13, 0xff, 0x06, 0x59, 0x27, 0xff, 0x0e, 0x76, 0x3f, 0xff, 0x08, 0x5c, 0x2c, 0xff, 0x02, 0x3f, 0x19, 0xff, 0x05, 0x41, 0x20, 0xff, 0x02, 0x42, 0x21, 0xff, 0x05, 0x41, 0x1f, 0xff, 0x06, 0x40, 0x1d, 0xff, 0x03, 0x3e, 0x1a, 0xff, 0x06, 0x36, 0x16, 0xff, 0x05, 0x28, 0x0a, 0xff, 0x02, 0x1d, 0x04, 0xff, 0x07, 0x28, 0x0d, 0xff, 0x1d, 0x53, 0x33, 0xff, 0x09, 0x42, 0x21, 0xff, 0x07, 0x3b, 0x1d, 0xff, 0x11, 0x3c, 0x21, 0xff, 0x04, 0x26, 0x0c, 0xff, 0x00, 0x1f, 0x04, 0xff, 0x01, 0x28, 0x0b, 0xff, 0x03, 0x31, 0x12, 0xff, 0x04, 0x28, 0x0c, 0xff, 0x06, 0x33, 0x16, 0xff, 0x11, 0x4c, 0x2d, 0xff, 0x0b, 0x3e, 0x21, 0xff, 0x02, 0x23, 0x07, 0xff, 0x0b, 0x38, 0x1c, 0xff, 0x0a, 0x44, 0x27, 0xff, 0x08, 0x46, 0x27, 0xff, 0x0e, 0x42, 0x22, 0xff, 0x0c, 0x37, 0x1a, 0xff, 0x01, 0x22, 0x09, 0xff, 0x01, 0x21, 0x07, 0xff, 0x04, 0x31, 0x0e, 0xff, 0x01, 0x33, 0x0c, 0xff, 0x02, 0x30, 0x0a, 0xff, 0x06, 0x32, 0x10, 0xff, 0x0b, 0x30, 0x0d, 0xff, 0x01, 0x2a, 0x0b, 0xff, 0x06, 0x34, 0x18, 0xff, 0x0b, 0x36, 0x17, 0xff, 0x09, 0x37, 0x1b, 0xff, 0x0c, 0x38, 0x21, 0xff, 0x03, 0x2d, 0x12, 0xff, 0x03, 0x2e, 0x11, 0xff, 0x03, 0x33, 0x16, 0xff, 0x05, 0x36, 0x1a, 0xff, 0x07, 0x38, 0x1b, 0xff, 0x04, 0x33, 0x19, 0xff, 0x02, 0x2f, 0x1b, 0xff, 0x05, 0x2f, 0x1f, 0xff, 0x04, 0x2b, 0x1c, 0xff, 0x02, 0x27, 0x16, 0xff, 0x00, 0x2a, 0x12, 0xff, 0x04, 0x45, 0x22, 0xff, 0x0b, 0x4c, 0x23, 0xff, 0x01, 0x30, 0x0e, 0xff, 0x00, 0x23, 0x12, 0xff, 0x02, 0x22, 0x13, 0xff, 0x07, 0x48, 0x25, 0xff, 0x25, 0x93, 0x58, 0xff, 0x0e, 0x82, 0x3e, 0xff, 0x04, 0x76, 0x33, 0xff, 0x04, 0x7a, 0x35, 0xff, 0x03, 0x7b, 0x35, 0xff, 0x04, 0x7a, 0x35, 0xff, 0x06, 0x78, 0x36, 0xff, 0x09, 0x72, 0x35, 0xff, 0x08, 0x6c, 0x33, 0xff, 0x09, 0x67, 0x30, 0xff, 0x09, 0x65, 0x31, 0xff, 0x07, 0x64, 0x33, 0xff, 0x05, 0x62, 0x34, 0xff, 0x07, 0x63, 0x38, 0xff, 0x0b, 0x60, 0x38, 0xff, 0x0e, 0x5a, 0x35, 0xff, 0x0b, 0x52, 0x2f, 0xff, 0x08, 0x43, 0x21, 0xff, 0x06, 0x3a, 0x1a, 0xff, 0x02, 0x30, 0x13, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x01, 0x27, 0x10, 0xff, 0x00, 0x25, 0x10, 0xff, 0x02, 0x24, 0x0f, 0xff, 0x02, 0x25, 0x0f, 0xff, 0x02, 0x26, 0x10, 0xff, 0x01, 0x25, 0x11, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x00, 0x26, 0x11, 0xff, 0x00, 0x28, 0x10, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x02, 0x33, 0x18, 0xff, 0x07, 0x3c, 0x20, 0xff, 0x0e, 0x46, 0x29, 0xff, 0x14, 0x51, 0x30, 0xff, 0x11, 0x5b, 0x34, 0xff, 0x0e, 0x5a, 0x31, 0xff, 0x0e, 0x53, 0x2c, 0xff, 0x09, 0x52, 0x2c, 0xff, 0x03, 0x3f, 0x1e, 0xff, 0x02, 0x32, 0x14, 0xff, 0x06, 0x5a, 0x2d, 0xff, 0x0e, 0x7b, 0x3b, 0xff, 0x08, 0x7a, 0x35, 0xff, 0x04, 0x74, 0x30, 0xff, 0x09, 0x73, 0x35, 0xff, 0x0a, 0x6e, 0x34, 0xff, 0x09, 0x6f, 0x34, 0xff, 0x06, 0x71, 0x32, 0xff, 0x07, 0x72, 0x36, 0xff, 0x0d, 0x66, 0x39, 0xff, 0x13, 0x4c, 0x30, 0xff, 0x09, 0x39, 0x22, 0xff, 0x00, 0x2e, 0x10, 0xff, 0x06, 0x57, 0x2b, 0xff, 0x05, 0x89, 0x4b, 0xff, 0x02, 0x7c, 0x40, 0xff, 0x06, 0x7b, 0x42, 0xff, 0x02, 0x7c, 0x40, 0xff, 0x02, 0x80, 0x43, 0xff, 0x01, 0x7f, 0x41, 0xff, 0x01, 0x7f, 0x42, 0xff, 0x04, 0x7f, 0x43, 0xff, 0x07, 0x7a, 0x42, 0xff, 0x0e, 0x7d, 0x47, 0xff, 0x05, 0x57, 0x2c, 0xff, 0x02, 0x29, 0x10, 0xff, 0x05, 0x31, 0x1b, 0xff, 0x01, 0x33, 0x1c, 0xff, 0x08, 0x38, 0x1e, 0xff, 0x04, 0x3d, 0x1b, 0xff, 0x04, 0x62, 0x35, 0xff, 0x08, 0x6d, 0x3d, 0xff, 0x0a, 0x4f, 0x28, 0xff, 0x00, 0x25, 0x0e, 0xff, 0x07, 0x44, 0x28, 0xff, 0x04, 0x2d, 0x18, 0xff, 0x04, 0x1e, 0x0e, 0xff, 0x03, 0x41, 0x21, 0xff, 0x0d, 0x75, 0x44, 0xff, 0x04, 0x4a, 0x23, 0xff, 0x11, 0x44, 0x2c, 0xff, 0x02, 0x27, 0x13, 0xff, 0x02, 0x1e, 0x0e, 0xff, 0x01, 0x24, 0x0f, 0xff, 0x07, 0x42, 0x26, 0xff, 0x0b, 0x4b, 0x2b, 0xff, 0x0b, 0x3a, 0x20, 0xff, 0x02, 0x24, 0x12, 0xff, 0x01, 0x1e, 0x11, 0xff, 0x04, 0x24, 0x10, 0xff, 0x0a, 0x41, 0x28, 0xff, 0x06, 0x30, 0x1a, 0xff, 0x01, 0x23, 0x0e, 0xff, 0x0b, 0x3c, 0x24, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x02, 0x45, 0x22, 0xff, 0x10, 0x5e, 0x35, 0xff, 0x0c, 0x62, 0x36, 0xff, 0x0a, 0x5f, 0x33, 0xff, 0x09, 0x5c, 0x31, 0xff, 0x0c, 0x68, 0x3c, 0xff, 0x09, 0x6d, 0x3e, 0xff, 0x08, 0x6c, 0x3e, 0xff, 0x0e, 0x6a, 0x3d, 0xff, 0x0c, 0x58, 0x2f, 0xff, 0x03, 0x3c, 0x1d, 0xff, 0x01, 0x26, 0x14, 0xff, 0x06, 0x25, 0x18, 0xff, 0x01, 0x23, 0x12, 0xff, 0x05, 0x35, 0x19, 0xff, 0x02, 0x3a, 0x18, 0xff, 0x05, 0x38, 0x1d, 0xff, 0x02, 0x2a, 0x18, 0xff, 0x03, 0x31, 0x1c, 0xff, 0x04, 0x38, 0x1c, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x00, 0x22, 0x11, 0xff, 0x05, 0x31, 0x1e, 0xff, 0x0a, 0x53, 0x2c, 0xff, 0x05, 0x5f, 0x2d, 0xff, 0x07, 0x60, 0x30, 0xff, 0x06, 0x60, 0x32, 0xff, 0x0a, 0x67, 0x31, 0xff, 0x0e, 0x5d, 0x2c, 0xff, 0x03, 0x31, 0x18, 0xff, 0x05, 0x28, 0x1a, 0xff, 0x03, 0x2f, 0x19, 0xff, 0x0c, 0x45, 0x28, 0xff, 0x09, 0x3e, 0x24, 0xff, 0x00, 0x23, 0x10, 0xff, 0x02, 0x22, 0x12, 0xff, 0x06, 0x3a, 0x25, 0xff, 0x08, 0x41, 0x27, 0xff, 0x00, 0x2d, 0x12, 0xff, 0x06, 0x46, 0x27, 0xff, 0x0b, 0x56, 0x33, 0xff, 0x05, 0x51, 0x2b, 0xff, 0x0d, 0x52, 0x31, 0xff, 0x02, 0x31, 0x13, 0xff, 0x04, 0x39, 0x17, 0xff, 0x0e, 0x63, 0x37, 0xff, 0x05, 0x6a, 0x38, 0xff, 0x0a, 0x69, 0x37, 0xff, 0x0f, 0x69, 0x38, 0xff, 0x05, 0x67, 0x37, 0xff, 0x0c, 0x5e, 0x37, 0xff, 0x08, 0x3e, 0x25, 0xff, 0x02, 0x26, 0x16, 0xff, 0x00, 0x2b, 0x1c, 0xff, 0x18, 0x71, 0x4f, 0xff, 0x29, 0xbb, 0x86, 0xff, 0x1a, 0xc0, 0x7d, 0xff, 0x24, 0xb0, 0x9b, 0xff, 0x24, 0x70, 0xb7, 0xff, 0x2b, 0x4b, 0xcd, 0xff, 0x23, 0x42, 0xcc, 0xff, 0x1d, 0x3b, 0xcb, 0xff, 0x1e, 0x3c, 0xcb, 0xff, 0x1e, 0x3e, 0xc5, 0xff, 0x21, 0x40, 0xc5, 0xff, 0x1f, 0x3d, 0xc3, 0xff, 0x22, 0x41, 0xc1, 0xff, 0x1d, 0x38, 0xb9, 0xff, 0x1f, 0x3d, 0x91, 0xff, 0x03, 0x3a, 0x30, 0xff, 0x0d, 0x56, 0x34, 0xff, 0x08, 0x42, 0x28, 0xff, 0x0c, 0x50, 0x3d, 0xff, 0x19, 0x61, 0x45, 0xff, 0x02, 0x2d, 0x12, 0xff, 0x0e, 0x48, 0x2d, 0xff, 0x20, 0x5e, 0x3f, 0xff, 0x02, 0x29, 0x12, 0xff, 0x01, 0x27, 0x15, 0xff, 0x0d, 0x45, 0x2b, 0xff, 0x0b, 0x54, 0x34, 0xff, 0x6a, 0x97, 0x85, 0xff, + 0x07, 0x3b, 0x1b, 0xff, 0x0b, 0x54, 0x2a, 0xff, 0x05, 0x4e, 0x26, 0xff, 0x01, 0x32, 0x15, 0xff, 0x06, 0x29, 0x15, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x27, 0x13, 0xff, 0x01, 0x25, 0x12, 0xff, 0x02, 0x27, 0x10, 0xff, 0x02, 0x3c, 0x1c, 0xff, 0x08, 0x55, 0x2c, 0xff, 0x0c, 0x58, 0x2e, 0xff, 0x02, 0x39, 0x17, 0xff, 0x02, 0x26, 0x12, 0xff, 0x01, 0x25, 0x12, 0xff, 0x03, 0x2e, 0x14, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x00, 0x28, 0x13, 0xff, 0x00, 0x25, 0x12, 0xff, 0x04, 0x25, 0x14, 0xff, 0x04, 0x24, 0x13, 0xff, 0x01, 0x25, 0x13, 0xff, 0x00, 0x29, 0x13, 0xff, 0x04, 0x40, 0x20, 0xff, 0x0a, 0x5b, 0x30, 0xff, 0x05, 0x5d, 0x2d, 0xff, 0x05, 0x45, 0x21, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x07, 0x52, 0x29, 0xff, 0x06, 0x58, 0x27, 0xff, 0x06, 0x5e, 0x2c, 0xff, 0x08, 0x5c, 0x30, 0xff, 0x02, 0x3a, 0x1b, 0xff, 0x01, 0x22, 0x0e, 0xff, 0x04, 0x22, 0x12, 0xff, 0x02, 0x26, 0x15, 0xff, 0x01, 0x26, 0x12, 0xff, 0x02, 0x25, 0x10, 0xff, 0x03, 0x2f, 0x16, 0xff, 0x0e, 0x4a, 0x2b, 0xff, 0x0d, 0x54, 0x2f, 0xff, 0x0b, 0x51, 0x2c, 0xff, 0x02, 0x35, 0x19, 0xff, 0x00, 0x27, 0x11, 0xff, 0x01, 0x29, 0x16, 0xff, 0x01, 0x27, 0x13, 0xff, 0x04, 0x29, 0x11, 0xff, 0x06, 0x2b, 0x10, 0xff, 0x05, 0x2a, 0x0e, 0xff, 0x02, 0x25, 0x06, 0xff, 0x01, 0x22, 0x02, 0xff, 0x00, 0x23, 0x01, 0xff, 0x03, 0x31, 0x0a, 0xff, 0x0c, 0x4b, 0x1f, 0xff, 0x12, 0x68, 0x36, 0xff, 0x0f, 0x73, 0x3b, 0xff, 0x07, 0x78, 0x36, 0xff, 0x02, 0x77, 0x31, 0xff, 0x04, 0x75, 0x2d, 0xff, 0x04, 0x71, 0x2d, 0xff, 0x01, 0x6f, 0x30, 0xff, 0x06, 0x74, 0x3b, 0xff, 0x1a, 0x81, 0x4d, 0xff, 0x19, 0x80, 0x4d, 0xff, 0x0a, 0x61, 0x32, 0xff, 0x02, 0x49, 0x1c, 0xff, 0x01, 0x37, 0x0e, 0xff, 0x05, 0x30, 0x0b, 0xff, 0x03, 0x31, 0x13, 0xff, 0x16, 0x40, 0x33, 0xff, 0x44, 0x5c, 0x86, 0xff, 0x54, 0x66, 0xa1, 0xff, 0x5e, 0x6d, 0xb6, 0xff, 0x51, 0x61, 0xaa, 0xff, 0x49, 0x60, 0x95, 0xff, 0x2b, 0x49, 0x66, 0xff, 0x07, 0x28, 0x28, 0xff, 0x00, 0x23, 0x14, 0xff, 0x03, 0x31, 0x15, 0xff, 0x0d, 0x37, 0x18, 0xff, 0x07, 0x3e, 0x14, 0xff, 0x05, 0x56, 0x21, 0xff, 0x11, 0x76, 0x3e, 0xff, 0x06, 0x58, 0x27, 0xff, 0x05, 0x45, 0x1d, 0xff, 0x08, 0x4a, 0x26, 0xff, 0x03, 0x4b, 0x27, 0xff, 0x08, 0x4b, 0x27, 0xff, 0x06, 0x4a, 0x25, 0xff, 0x02, 0x46, 0x21, 0xff, 0x03, 0x3c, 0x1b, 0xff, 0x05, 0x2b, 0x0e, 0xff, 0x02, 0x1f, 0x05, 0xff, 0x01, 0x20, 0x06, 0xff, 0x11, 0x46, 0x26, 0xff, 0x0c, 0x43, 0x24, 0xff, 0x09, 0x3c, 0x1e, 0xff, 0x0a, 0x33, 0x17, 0xff, 0x00, 0x1f, 0x05, 0xff, 0x01, 0x25, 0x0a, 0xff, 0x07, 0x3b, 0x1b, 0xff, 0x07, 0x45, 0x24, 0xff, 0x05, 0x35, 0x16, 0xff, 0x02, 0x2e, 0x10, 0xff, 0x0d, 0x47, 0x27, 0xff, 0x0a, 0x3c, 0x1e, 0xff, 0x03, 0x2b, 0x0d, 0xff, 0x0e, 0x46, 0x28, 0xff, 0x09, 0x47, 0x29, 0xff, 0x07, 0x43, 0x25, 0xff, 0x11, 0x3f, 0x21, 0xff, 0x05, 0x2a, 0x0f, 0xff, 0x01, 0x22, 0x09, 0xff, 0x04, 0x2a, 0x0d, 0xff, 0x0e, 0x41, 0x1a, 0xff, 0x03, 0x3d, 0x14, 0xff, 0x01, 0x34, 0x0d, 0xff, 0x02, 0x2e, 0x0b, 0xff, 0x04, 0x2c, 0x02, 0xff, 0x00, 0x29, 0x08, 0xff, 0x06, 0x33, 0x17, 0xff, 0x07, 0x2d, 0x0c, 0xff, 0x02, 0x28, 0x0b, 0xff, 0x05, 0x2a, 0x11, 0xff, 0x03, 0x2c, 0x10, 0xff, 0x00, 0x30, 0x11, 0xff, 0x04, 0x36, 0x18, 0xff, 0x04, 0x35, 0x18, 0xff, 0x04, 0x35, 0x18, 0xff, 0x06, 0x35, 0x1d, 0xff, 0x05, 0x31, 0x21, 0xff, 0x07, 0x30, 0x24, 0xff, 0x07, 0x2c, 0x20, 0xff, 0x05, 0x2a, 0x1b, 0xff, 0x00, 0x28, 0x14, 0xff, 0x02, 0x37, 0x19, 0xff, 0x0e, 0x4e, 0x27, 0xff, 0x03, 0x34, 0x16, 0xff, 0x01, 0x23, 0x0f, 0xff, 0x01, 0x2d, 0x0f, 0xff, 0x16, 0x7e, 0x48, 0xff, 0x1f, 0x9c, 0x5b, 0xff, 0x06, 0x76, 0x32, 0xff, 0x0c, 0x7a, 0x35, 0xff, 0x06, 0x7b, 0x35, 0xff, 0x02, 0x7e, 0x36, 0xff, 0x00, 0x7b, 0x35, 0xff, 0x02, 0x77, 0x35, 0xff, 0x06, 0x6f, 0x34, 0xff, 0x07, 0x69, 0x31, 0xff, 0x09, 0x65, 0x31, 0xff, 0x0a, 0x63, 0x33, 0xff, 0x0a, 0x63, 0x37, 0xff, 0x0b, 0x62, 0x39, 0xff, 0x0d, 0x5f, 0x39, 0xff, 0x0b, 0x55, 0x33, 0xff, 0x06, 0x43, 0x24, 0xff, 0x02, 0x35, 0x18, 0xff, 0x01, 0x28, 0x0e, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x01, 0x22, 0x0c, 0xff, 0x02, 0x21, 0x0d, 0xff, 0x03, 0x22, 0x10, 0xff, 0x03, 0x22, 0x11, 0xff, 0x04, 0x22, 0x11, 0xff, 0x05, 0x24, 0x11, 0xff, 0x04, 0x24, 0x12, 0xff, 0x04, 0x23, 0x12, 0xff, 0x02, 0x23, 0x12, 0xff, 0x03, 0x23, 0x12, 0xff, 0x02, 0x24, 0x12, 0xff, 0x01, 0x24, 0x11, 0xff, 0x00, 0x23, 0x10, 0xff, 0x01, 0x26, 0x11, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x05, 0x32, 0x18, 0xff, 0x09, 0x46, 0x26, 0xff, 0x0f, 0x54, 0x30, 0xff, 0x12, 0x57, 0x33, 0xff, 0x0d, 0x56, 0x34, 0xff, 0x07, 0x4c, 0x29, 0xff, 0x02, 0x3f, 0x1b, 0xff, 0x0a, 0x6d, 0x36, 0xff, 0x0c, 0x84, 0x3a, 0xff, 0x05, 0x78, 0x33, 0xff, 0x06, 0x73, 0x34, 0xff, 0x08, 0x72, 0x36, 0xff, 0x05, 0x6e, 0x33, 0xff, 0x09, 0x75, 0x35, 0xff, 0x07, 0x77, 0x33, 0xff, 0x0a, 0x72, 0x35, 0xff, 0x10, 0x5d, 0x35, 0xff, 0x09, 0x3a, 0x20, 0xff, 0x01, 0x28, 0x14, 0xff, 0x00, 0x2a, 0x0d, 0xff, 0x04, 0x51, 0x26, 0xff, 0x09, 0x88, 0x4c, 0xff, 0x02, 0x7a, 0x3e, 0xff, 0x08, 0x7a, 0x40, 0xff, 0x03, 0x7a, 0x3f, 0xff, 0x02, 0x7d, 0x41, 0xff, 0x01, 0x7d, 0x40, 0xff, 0x01, 0x7e, 0x42, 0xff, 0x03, 0x7d, 0x41, 0xff, 0x05, 0x78, 0x3f, 0xff, 0x0b, 0x7a, 0x44, 0xff, 0x0b, 0x65, 0x39, 0xff, 0x01, 0x30, 0x14, 0xff, 0x09, 0x32, 0x1b, 0xff, 0x02, 0x33, 0x1d, 0xff, 0x05, 0x35, 0x1b, 0xff, 0x03, 0x3c, 0x1b, 0xff, 0x05, 0x62, 0x35, 0xff, 0x06, 0x6c, 0x3b, 0xff, 0x0d, 0x5d, 0x33, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x09, 0x43, 0x27, 0xff, 0x05, 0x2f, 0x19, 0xff, 0x03, 0x1f, 0x0e, 0xff, 0x02, 0x3e, 0x1e, 0xff, 0x11, 0x77, 0x46, 0xff, 0x03, 0x4b, 0x22, 0xff, 0x12, 0x47, 0x2e, 0xff, 0x06, 0x2f, 0x1a, 0xff, 0x01, 0x1e, 0x0c, 0xff, 0x01, 0x22, 0x0e, 0xff, 0x0b, 0x41, 0x26, 0xff, 0x0c, 0x4b, 0x2c, 0xff, 0x0c, 0x3e, 0x24, 0xff, 0x03, 0x27, 0x14, 0xff, 0x03, 0x1f, 0x11, 0xff, 0x03, 0x23, 0x0f, 0xff, 0x0a, 0x40, 0x28, 0xff, 0x07, 0x32, 0x1c, 0xff, 0x01, 0x23, 0x0e, 0xff, 0x0c, 0x3e, 0x25, 0xff, 0x04, 0x3a, 0x1c, 0xff, 0x02, 0x40, 0x1e, 0xff, 0x10, 0x5c, 0x34, 0xff, 0x0b, 0x62, 0x36, 0xff, 0x0b, 0x61, 0x35, 0xff, 0x08, 0x5c, 0x30, 0xff, 0x0a, 0x64, 0x37, 0xff, 0x0a, 0x6c, 0x3d, 0xff, 0x08, 0x6c, 0x3d, 0xff, 0x0c, 0x6c, 0x3d, 0xff, 0x11, 0x65, 0x39, 0xff, 0x09, 0x4d, 0x28, 0xff, 0x01, 0x2d, 0x16, 0xff, 0x02, 0x21, 0x12, 0xff, 0x01, 0x22, 0x12, 0xff, 0x06, 0x34, 0x1b, 0xff, 0x01, 0x3a, 0x1a, 0xff, 0x03, 0x38, 0x1d, 0xff, 0x03, 0x2b, 0x17, 0xff, 0x03, 0x32, 0x1c, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x05, 0x35, 0x1b, 0xff, 0x00, 0x22, 0x11, 0xff, 0x03, 0x2e, 0x1b, 0xff, 0x0b, 0x54, 0x2d, 0xff, 0x07, 0x60, 0x2e, 0xff, 0x08, 0x61, 0x31, 0xff, 0x08, 0x62, 0x31, 0xff, 0x08, 0x66, 0x30, 0xff, 0x10, 0x66, 0x33, 0xff, 0x01, 0x36, 0x19, 0xff, 0x04, 0x29, 0x19, 0xff, 0x03, 0x2c, 0x16, 0xff, 0x0d, 0x43, 0x26, 0xff, 0x08, 0x40, 0x25, 0xff, 0x01, 0x25, 0x11, 0xff, 0x03, 0x22, 0x12, 0xff, 0x06, 0x3a, 0x25, 0xff, 0x09, 0x44, 0x2a, 0xff, 0x01, 0x30, 0x16, 0xff, 0x07, 0x48, 0x28, 0xff, 0x0b, 0x55, 0x32, 0xff, 0x09, 0x51, 0x2b, 0xff, 0x0f, 0x51, 0x2e, 0xff, 0x01, 0x37, 0x13, 0xff, 0x0a, 0x50, 0x29, 0xff, 0x0e, 0x69, 0x3b, 0xff, 0x08, 0x69, 0x38, 0xff, 0x0e, 0x68, 0x39, 0xff, 0x0f, 0x67, 0x38, 0xff, 0x05, 0x64, 0x37, 0xff, 0x0b, 0x55, 0x34, 0xff, 0x04, 0x2f, 0x19, 0xff, 0x04, 0x28, 0x15, 0xff, 0x05, 0x42, 0x25, 0xff, 0x2b, 0x9b, 0x71, 0xff, 0x25, 0xb1, 0x8a, 0xff, 0x16, 0xa5, 0x7b, 0xff, 0x1d, 0x93, 0xa1, 0xff, 0x0d, 0x4e, 0xaa, 0xff, 0x17, 0x35, 0xbb, 0xff, 0x14, 0x31, 0xbd, 0xff, 0x13, 0x2f, 0xc0, 0xff, 0x13, 0x31, 0xbe, 0xff, 0x0e, 0x2d, 0xb1, 0xff, 0x10, 0x30, 0xb0, 0xff, 0x16, 0x34, 0xb3, 0xff, 0x1d, 0x3d, 0xb2, 0xff, 0x1c, 0x35, 0xb5, 0xff, 0x20, 0x38, 0xa0, 0xff, 0x0e, 0x42, 0x49, 0xff, 0x0e, 0x56, 0x33, 0xff, 0x09, 0x42, 0x27, 0xff, 0x0b, 0x50, 0x3b, 0xff, 0x1b, 0x65, 0x4a, 0xff, 0x03, 0x30, 0x16, 0xff, 0x0e, 0x4a, 0x2e, 0xff, 0x1f, 0x5d, 0x3d, 0xff, 0x02, 0x29, 0x12, 0xff, 0x01, 0x28, 0x15, 0xff, 0x0f, 0x4a, 0x2e, 0xff, 0x0d, 0x57, 0x37, 0xff, 0x67, 0x97, 0x82, 0xff, + 0x05, 0x3d, 0x1d, 0xff, 0x0c, 0x55, 0x2b, 0xff, 0x06, 0x4c, 0x26, 0xff, 0x01, 0x31, 0x15, 0xff, 0x04, 0x29, 0x14, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x25, 0x13, 0xff, 0x01, 0x27, 0x11, 0xff, 0x02, 0x3f, 0x1e, 0xff, 0x08, 0x57, 0x2e, 0xff, 0x0c, 0x5a, 0x2f, 0xff, 0x03, 0x3c, 0x19, 0xff, 0x01, 0x27, 0x11, 0xff, 0x01, 0x26, 0x13, 0xff, 0x01, 0x28, 0x10, 0xff, 0x00, 0x29, 0x13, 0xff, 0x00, 0x27, 0x13, 0xff, 0x01, 0x25, 0x13, 0xff, 0x04, 0x24, 0x13, 0xff, 0x04, 0x24, 0x12, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x2c, 0x13, 0xff, 0x07, 0x4c, 0x25, 0xff, 0x09, 0x5d, 0x2f, 0xff, 0x04, 0x5b, 0x2c, 0xff, 0x03, 0x41, 0x1d, 0xff, 0x00, 0x23, 0x0b, 0xff, 0x05, 0x39, 0x1d, 0xff, 0x08, 0x55, 0x2a, 0xff, 0x07, 0x59, 0x28, 0xff, 0x05, 0x5d, 0x2c, 0xff, 0x0b, 0x58, 0x2f, 0xff, 0x01, 0x31, 0x15, 0xff, 0x01, 0x22, 0x10, 0xff, 0x05, 0x22, 0x14, 0xff, 0x03, 0x26, 0x16, 0xff, 0x01, 0x26, 0x12, 0xff, 0x01, 0x29, 0x12, 0xff, 0x09, 0x44, 0x25, 0xff, 0x10, 0x53, 0x30, 0xff, 0x0b, 0x53, 0x2d, 0xff, 0x0a, 0x4a, 0x29, 0xff, 0x00, 0x2c, 0x13, 0xff, 0x01, 0x27, 0x13, 0xff, 0x02, 0x28, 0x16, 0xff, 0x06, 0x28, 0x15, 0xff, 0x0a, 0x25, 0x0d, 0xff, 0x05, 0x24, 0x0a, 0xff, 0x00, 0x22, 0x03, 0xff, 0x00, 0x24, 0x02, 0xff, 0x02, 0x2f, 0x06, 0xff, 0x09, 0x4a, 0x1a, 0xff, 0x13, 0x69, 0x31, 0xff, 0x12, 0x74, 0x38, 0xff, 0x08, 0x7a, 0x35, 0xff, 0x04, 0x7b, 0x34, 0xff, 0x04, 0x7a, 0x33, 0xff, 0x03, 0x78, 0x32, 0xff, 0x05, 0x78, 0x32, 0xff, 0x10, 0x81, 0x3e, 0xff, 0x1a, 0x8e, 0x4c, 0xff, 0x17, 0x88, 0x4a, 0xff, 0x0d, 0x64, 0x35, 0xff, 0x02, 0x46, 0x1c, 0xff, 0x03, 0x34, 0x0f, 0xff, 0x05, 0x30, 0x0c, 0xff, 0x06, 0x2f, 0x0a, 0xff, 0x05, 0x31, 0x0e, 0xff, 0x11, 0x46, 0x27, 0xff, 0x19, 0x4e, 0x39, 0xff, 0x2a, 0x48, 0x55, 0xff, 0x3f, 0x59, 0x6e, 0xff, 0x46, 0x5e, 0x7b, 0xff, 0x39, 0x53, 0x6d, 0xff, 0x12, 0x2f, 0x3a, 0xff, 0x01, 0x1f, 0x1a, 0xff, 0x01, 0x29, 0x12, 0xff, 0x04, 0x34, 0x15, 0xff, 0x04, 0x3d, 0x1a, 0xff, 0x0a, 0x3e, 0x18, 0xff, 0x04, 0x40, 0x13, 0xff, 0x03, 0x50, 0x1c, 0xff, 0x13, 0x74, 0x3d, 0xff, 0x02, 0x52, 0x21, 0xff, 0x04, 0x4b, 0x22, 0xff, 0x03, 0x4d, 0x27, 0xff, 0x00, 0x50, 0x28, 0xff, 0x01, 0x4e, 0x26, 0xff, 0x01, 0x4f, 0x27, 0xff, 0x00, 0x4f, 0x27, 0xff, 0x05, 0x47, 0x23, 0xff, 0x0a, 0x36, 0x19, 0xff, 0x03, 0x20, 0x06, 0xff, 0x01, 0x1e, 0x06, 0xff, 0x07, 0x34, 0x16, 0xff, 0x0e, 0x40, 0x22, 0xff, 0x08, 0x31, 0x14, 0xff, 0x01, 0x22, 0x07, 0xff, 0x00, 0x25, 0x08, 0xff, 0x07, 0x38, 0x19, 0xff, 0x0b, 0x4f, 0x2b, 0xff, 0x06, 0x51, 0x2c, 0xff, 0x0f, 0x4b, 0x28, 0xff, 0x03, 0x36, 0x13, 0xff, 0x05, 0x3c, 0x1a, 0xff, 0x06, 0x35, 0x15, 0xff, 0x0f, 0x43, 0x24, 0xff, 0x15, 0x55, 0x34, 0xff, 0x0b, 0x4d, 0x2d, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x09, 0x30, 0x16, 0xff, 0x01, 0x20, 0x07, 0xff, 0x01, 0x27, 0x0b, 0xff, 0x0a, 0x38, 0x18, 0xff, 0x12, 0x4e, 0x26, 0xff, 0x04, 0x46, 0x1c, 0xff, 0x03, 0x40, 0x18, 0xff, 0x05, 0x39, 0x14, 0xff, 0x09, 0x34, 0x07, 0xff, 0x01, 0x2a, 0x08, 0xff, 0x01, 0x37, 0x13, 0xff, 0x01, 0x30, 0x09, 0xff, 0x07, 0x27, 0x0e, 0xff, 0x07, 0x2a, 0x10, 0xff, 0x01, 0x32, 0x13, 0xff, 0x0a, 0x40, 0x27, 0xff, 0x18, 0x42, 0x39, 0xff, 0x0f, 0x35, 0x2c, 0xff, 0x05, 0x31, 0x1f, 0xff, 0x04, 0x33, 0x1f, 0xff, 0x06, 0x34, 0x20, 0xff, 0x07, 0x33, 0x21, 0xff, 0x06, 0x31, 0x21, 0xff, 0x07, 0x31, 0x20, 0xff, 0x01, 0x2d, 0x1a, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x0e, 0x47, 0x26, 0xff, 0x06, 0x39, 0x1c, 0xff, 0x00, 0x28, 0x09, 0xff, 0x07, 0x67, 0x30, 0xff, 0x21, 0xaa, 0x61, 0xff, 0x05, 0x83, 0x3c, 0xff, 0x05, 0x7d, 0x36, 0xff, 0x0b, 0x7f, 0x35, 0xff, 0x07, 0x7e, 0x34, 0xff, 0x05, 0x7d, 0x35, 0xff, 0x05, 0x7b, 0x36, 0xff, 0x06, 0x77, 0x37, 0xff, 0x05, 0x6d, 0x34, 0xff, 0x06, 0x67, 0x33, 0xff, 0x09, 0x63, 0x35, 0xff, 0x0d, 0x62, 0x38, 0xff, 0x0f, 0x5b, 0x36, 0xff, 0x0c, 0x4e, 0x2e, 0xff, 0x03, 0x39, 0x1e, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x00, 0x22, 0x0d, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x01, 0x21, 0x0e, 0xff, 0x00, 0x21, 0x0f, 0xff, 0x02, 0x22, 0x12, 0xff, 0x02, 0x22, 0x13, 0xff, 0x02, 0x22, 0x12, 0xff, 0x02, 0x22, 0x13, 0xff, 0x01, 0x22, 0x11, 0xff, 0x01, 0x23, 0x11, 0xff, 0x02, 0x24, 0x13, 0xff, 0x02, 0x23, 0x13, 0xff, 0x03, 0x23, 0x13, 0xff, 0x04, 0x24, 0x14, 0xff, 0x03, 0x23, 0x14, 0xff, 0x03, 0x23, 0x14, 0xff, 0x01, 0x23, 0x15, 0xff, 0x01, 0x23, 0x15, 0xff, 0x01, 0x23, 0x13, 0xff, 0x00, 0x24, 0x11, 0xff, 0x00, 0x27, 0x0e, 0xff, 0x01, 0x2d, 0x12, 0xff, 0x0c, 0x41, 0x25, 0xff, 0x15, 0x52, 0x34, 0xff, 0x0e, 0x58, 0x33, 0xff, 0x04, 0x5a, 0x2d, 0xff, 0x0c, 0x83, 0x41, 0xff, 0x05, 0x86, 0x35, 0xff, 0x05, 0x78, 0x33, 0xff, 0x06, 0x73, 0x35, 0xff, 0x05, 0x73, 0x35, 0xff, 0x03, 0x75, 0x33, 0xff, 0x0a, 0x7b, 0x35, 0xff, 0x0e, 0x7a, 0x37, 0xff, 0x0c, 0x64, 0x2e, 0xff, 0x05, 0x3e, 0x1c, 0xff, 0x01, 0x25, 0x10, 0xff, 0x01, 0x25, 0x14, 0xff, 0x00, 0x29, 0x11, 0xff, 0x04, 0x4a, 0x23, 0xff, 0x0f, 0x85, 0x4f, 0xff, 0x03, 0x7a, 0x3f, 0xff, 0x09, 0x78, 0x3f, 0xff, 0x04, 0x79, 0x3f, 0xff, 0x04, 0x7c, 0x41, 0xff, 0x02, 0x7c, 0x40, 0xff, 0x03, 0x7d, 0x41, 0xff, 0x02, 0x7b, 0x3f, 0xff, 0x04, 0x78, 0x40, 0xff, 0x07, 0x78, 0x42, 0xff, 0x0e, 0x72, 0x43, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x08, 0x2e, 0x18, 0xff, 0x03, 0x33, 0x1d, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x02, 0x3c, 0x1c, 0xff, 0x06, 0x61, 0x34, 0xff, 0x05, 0x68, 0x37, 0xff, 0x11, 0x6f, 0x41, 0xff, 0x01, 0x28, 0x0d, 0xff, 0x0a, 0x3d, 0x22, 0xff, 0x06, 0x2f, 0x1a, 0xff, 0x01, 0x1e, 0x0d, 0xff, 0x01, 0x39, 0x1b, 0xff, 0x12, 0x76, 0x45, 0xff, 0x06, 0x51, 0x27, 0xff, 0x0d, 0x44, 0x2a, 0xff, 0x0b, 0x3e, 0x26, 0xff, 0x01, 0x22, 0x0d, 0xff, 0x01, 0x1f, 0x0c, 0xff, 0x0c, 0x3b, 0x22, 0xff, 0x0d, 0x4b, 0x2d, 0xff, 0x09, 0x42, 0x29, 0xff, 0x02, 0x2b, 0x18, 0xff, 0x03, 0x1e, 0x10, 0xff, 0x02, 0x22, 0x0d, 0xff, 0x0a, 0x3f, 0x28, 0xff, 0x07, 0x34, 0x1e, 0xff, 0x01, 0x23, 0x0e, 0xff, 0x0d, 0x3d, 0x25, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x0d, 0x57, 0x31, 0xff, 0x09, 0x63, 0x37, 0xff, 0x0b, 0x61, 0x36, 0xff, 0x0a, 0x5c, 0x31, 0xff, 0x05, 0x5a, 0x2e, 0xff, 0x0b, 0x6a, 0x3b, 0xff, 0x0a, 0x6e, 0x3d, 0xff, 0x09, 0x6e, 0x3b, 0xff, 0x0f, 0x6f, 0x3c, 0xff, 0x0d, 0x61, 0x33, 0xff, 0x05, 0x3f, 0x20, 0xff, 0x01, 0x27, 0x13, 0xff, 0x01, 0x21, 0x10, 0xff, 0x04, 0x30, 0x1b, 0xff, 0x02, 0x38, 0x1d, 0xff, 0x04, 0x37, 0x1c, 0xff, 0x03, 0x2a, 0x13, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x06, 0x35, 0x1b, 0xff, 0x01, 0x23, 0x13, 0xff, 0x02, 0x29, 0x17, 0xff, 0x0c, 0x55, 0x2e, 0xff, 0x08, 0x61, 0x2f, 0xff, 0x08, 0x61, 0x31, 0xff, 0x09, 0x61, 0x30, 0xff, 0x05, 0x66, 0x2f, 0xff, 0x0d, 0x6b, 0x38, 0xff, 0x04, 0x45, 0x22, 0xff, 0x02, 0x2b, 0x16, 0xff, 0x03, 0x2a, 0x13, 0xff, 0x0e, 0x3f, 0x24, 0xff, 0x06, 0x42, 0x26, 0xff, 0x01, 0x28, 0x13, 0xff, 0x03, 0x21, 0x10, 0xff, 0x04, 0x39, 0x23, 0xff, 0x0a, 0x46, 0x2c, 0xff, 0x03, 0x35, 0x19, 0xff, 0x0a, 0x4b, 0x2b, 0xff, 0x0b, 0x53, 0x30, 0xff, 0x0a, 0x4e, 0x2a, 0xff, 0x0a, 0x4c, 0x26, 0xff, 0x03, 0x4b, 0x21, 0xff, 0x0d, 0x66, 0x38, 0xff, 0x08, 0x68, 0x37, 0xff, 0x0a, 0x68, 0x36, 0xff, 0x0e, 0x68, 0x39, 0xff, 0x0d, 0x64, 0x39, 0xff, 0x0a, 0x5e, 0x35, 0xff, 0x07, 0x45, 0x26, 0xff, 0x01, 0x26, 0x12, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x1b, 0x77, 0x52, 0xff, 0x2a, 0x9d, 0x84, 0xff, 0x19, 0x7e, 0x90, 0xff, 0x21, 0x76, 0x9f, 0xff, 0x1c, 0x66, 0xbb, 0xff, 0x1b, 0x4c, 0xc7, 0xff, 0x2c, 0x4a, 0xd6, 0xff, 0x29, 0x46, 0xd6, 0xff, 0x28, 0x45, 0xd6, 0xff, 0x25, 0x42, 0xcf, 0xff, 0x1c, 0x3a, 0xc1, 0xff, 0x13, 0x32, 0xb3, 0xff, 0x0a, 0x28, 0xa4, 0xff, 0x09, 0x26, 0x9b, 0xff, 0x14, 0x2c, 0xa6, 0xff, 0x17, 0x2c, 0x9c, 0xff, 0x16, 0x3f, 0x63, 0xff, 0x0d, 0x50, 0x3a, 0xff, 0x09, 0x45, 0x26, 0xff, 0x08, 0x4b, 0x32, 0xff, 0x15, 0x61, 0x46, 0xff, 0x05, 0x38, 0x20, 0xff, 0x0f, 0x4e, 0x31, 0xff, 0x1f, 0x5d, 0x3e, 0xff, 0x01, 0x28, 0x12, 0xff, 0x01, 0x29, 0x15, 0xff, 0x0f, 0x4e, 0x30, 0xff, 0x11, 0x5b, 0x39, 0xff, 0x64, 0x94, 0x80, 0xff, + 0x05, 0x3f, 0x1e, 0xff, 0x0c, 0x55, 0x2b, 0xff, 0x07, 0x4a, 0x24, 0xff, 0x01, 0x31, 0x14, 0xff, 0x03, 0x29, 0x15, 0xff, 0x02, 0x25, 0x12, 0xff, 0x00, 0x25, 0x12, 0xff, 0x01, 0x25, 0x12, 0xff, 0x01, 0x28, 0x11, 0xff, 0x03, 0x41, 0x1e, 0xff, 0x08, 0x59, 0x2e, 0xff, 0x0d, 0x5c, 0x30, 0xff, 0x03, 0x3e, 0x19, 0xff, 0x00, 0x28, 0x11, 0xff, 0x02, 0x27, 0x13, 0xff, 0x00, 0x26, 0x10, 0xff, 0x00, 0x27, 0x11, 0xff, 0x00, 0x26, 0x12, 0xff, 0x02, 0x24, 0x13, 0xff, 0x04, 0x24, 0x12, 0xff, 0x03, 0x25, 0x11, 0xff, 0x00, 0x27, 0x12, 0xff, 0x00, 0x31, 0x13, 0xff, 0x09, 0x54, 0x28, 0xff, 0x07, 0x5d, 0x2d, 0xff, 0x04, 0x5b, 0x2c, 0xff, 0x02, 0x3e, 0x1b, 0xff, 0x00, 0x24, 0x0b, 0xff, 0x06, 0x3e, 0x20, 0xff, 0x07, 0x56, 0x2a, 0xff, 0x06, 0x5a, 0x29, 0xff, 0x05, 0x5c, 0x2b, 0xff, 0x0c, 0x54, 0x2d, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x01, 0x22, 0x10, 0xff, 0x04, 0x22, 0x14, 0xff, 0x02, 0x25, 0x14, 0xff, 0x00, 0x27, 0x11, 0xff, 0x02, 0x32, 0x17, 0xff, 0x0c, 0x51, 0x2d, 0xff, 0x0a, 0x54, 0x2e, 0xff, 0x0b, 0x52, 0x2e, 0xff, 0x06, 0x41, 0x23, 0xff, 0x00, 0x28, 0x12, 0xff, 0x05, 0x28, 0x16, 0xff, 0x05, 0x27, 0x14, 0xff, 0x06, 0x26, 0x10, 0xff, 0x07, 0x22, 0x08, 0xff, 0x02, 0x23, 0x07, 0xff, 0x00, 0x2a, 0x07, 0xff, 0x03, 0x36, 0x0d, 0xff, 0x0d, 0x54, 0x22, 0xff, 0x14, 0x6c, 0x33, 0xff, 0x0d, 0x76, 0x37, 0xff, 0x05, 0x79, 0x35, 0xff, 0x03, 0x7d, 0x31, 0xff, 0x07, 0x7c, 0x30, 0xff, 0x08, 0x7a, 0x31, 0xff, 0x06, 0x7a, 0x33, 0xff, 0x0e, 0x88, 0x43, 0xff, 0x1e, 0x93, 0x52, 0xff, 0x1a, 0x7e, 0x45, 0xff, 0x09, 0x5e, 0x2b, 0xff, 0x01, 0x40, 0x16, 0xff, 0x02, 0x36, 0x12, 0xff, 0x07, 0x2e, 0x0f, 0xff, 0x09, 0x2c, 0x0d, 0xff, 0x09, 0x33, 0x10, 0xff, 0x0c, 0x3d, 0x1b, 0xff, 0x11, 0x48, 0x29, 0xff, 0x0b, 0x3e, 0x24, 0xff, 0x0e, 0x33, 0x22, 0xff, 0x14, 0x35, 0x2b, 0xff, 0x14, 0x34, 0x30, 0xff, 0x0d, 0x2c, 0x28, 0xff, 0x02, 0x23, 0x17, 0xff, 0x02, 0x29, 0x14, 0xff, 0x04, 0x33, 0x16, 0xff, 0x06, 0x39, 0x18, 0xff, 0x02, 0x3f, 0x19, 0xff, 0x07, 0x42, 0x1a, 0xff, 0x04, 0x44, 0x17, 0xff, 0x05, 0x50, 0x1f, 0xff, 0x13, 0x6e, 0x3a, 0xff, 0x01, 0x50, 0x21, 0xff, 0x06, 0x51, 0x29, 0xff, 0x02, 0x50, 0x2b, 0xff, 0x00, 0x52, 0x2a, 0xff, 0x01, 0x53, 0x29, 0xff, 0x02, 0x55, 0x2b, 0xff, 0x02, 0x56, 0x2c, 0xff, 0x08, 0x4d, 0x29, 0xff, 0x0b, 0x38, 0x1b, 0xff, 0x06, 0x22, 0x09, 0xff, 0x02, 0x1d, 0x05, 0xff, 0x0a, 0x33, 0x17, 0xff, 0x14, 0x40, 0x23, 0xff, 0x04, 0x27, 0x0b, 0xff, 0x01, 0x23, 0x07, 0xff, 0x05, 0x38, 0x17, 0xff, 0x07, 0x4a, 0x26, 0xff, 0x08, 0x54, 0x2e, 0xff, 0x06, 0x53, 0x2c, 0xff, 0x0f, 0x50, 0x2a, 0xff, 0x08, 0x46, 0x21, 0xff, 0x02, 0x39, 0x16, 0xff, 0x03, 0x33, 0x12, 0xff, 0x17, 0x4f, 0x2e, 0xff, 0x15, 0x57, 0x36, 0xff, 0x0b, 0x4c, 0x2c, 0xff, 0x0b, 0x40, 0x22, 0xff, 0x02, 0x23, 0x0b, 0xff, 0x03, 0x25, 0x0b, 0xff, 0x02, 0x2c, 0x0e, 0xff, 0x0b, 0x3f, 0x1c, 0xff, 0x11, 0x52, 0x2a, 0xff, 0x09, 0x4f, 0x24, 0xff, 0x06, 0x4a, 0x20, 0xff, 0x03, 0x3f, 0x16, 0xff, 0x0a, 0x3a, 0x10, 0xff, 0x04, 0x3a, 0x16, 0xff, 0x0a, 0x56, 0x2a, 0xff, 0x0c, 0x49, 0x25, 0xff, 0x16, 0x2e, 0x26, 0xff, 0x0c, 0x30, 0x1d, 0xff, 0x07, 0x45, 0x24, 0xff, 0x1e, 0x51, 0x3d, 0xff, 0x27, 0x42, 0x4e, 0xff, 0x18, 0x33, 0x40, 0xff, 0x0d, 0x31, 0x2d, 0xff, 0x05, 0x31, 0x21, 0xff, 0x06, 0x38, 0x21, 0xff, 0x04, 0x37, 0x1f, 0xff, 0x04, 0x37, 0x20, 0xff, 0x04, 0x36, 0x20, 0xff, 0x03, 0x38, 0x21, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x0a, 0x3d, 0x22, 0xff, 0x06, 0x3e, 0x1d, 0xff, 0x04, 0x4d, 0x1d, 0xff, 0x1b, 0xa4, 0x5f, 0xff, 0x0c, 0x98, 0x49, 0xff, 0x02, 0x7e, 0x34, 0xff, 0x04, 0x81, 0x36, 0xff, 0x05, 0x80, 0x34, 0xff, 0x07, 0x7e, 0x34, 0xff, 0x09, 0x7d, 0x36, 0xff, 0x0b, 0x78, 0x37, 0xff, 0x0a, 0x71, 0x35, 0xff, 0x08, 0x69, 0x34, 0xff, 0x09, 0x66, 0x35, 0xff, 0x0f, 0x61, 0x39, 0xff, 0x0f, 0x58, 0x33, 0xff, 0x07, 0x42, 0x23, 0xff, 0x03, 0x31, 0x17, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x01, 0x22, 0x0f, 0xff, 0x03, 0x25, 0x14, 0xff, 0x04, 0x28, 0x17, 0xff, 0x06, 0x2e, 0x1d, 0xff, 0x06, 0x2f, 0x1e, 0xff, 0x05, 0x2e, 0x1c, 0xff, 0x05, 0x2c, 0x1b, 0xff, 0x05, 0x2b, 0x1a, 0xff, 0x04, 0x2a, 0x18, 0xff, 0x01, 0x28, 0x15, 0xff, 0x00, 0x26, 0x14, 0xff, 0x00, 0x27, 0x14, 0xff, 0x00, 0x26, 0x13, 0xff, 0x00, 0x26, 0x13, 0xff, 0x01, 0x25, 0x14, 0xff, 0x01, 0x24, 0x14, 0xff, 0x01, 0x24, 0x14, 0xff, 0x01, 0x25, 0x15, 0xff, 0x00, 0x24, 0x15, 0xff, 0x02, 0x24, 0x16, 0xff, 0x01, 0x24, 0x15, 0xff, 0x00, 0x25, 0x11, 0xff, 0x01, 0x25, 0x0e, 0xff, 0x03, 0x28, 0x13, 0xff, 0x0b, 0x3a, 0x21, 0xff, 0x09, 0x51, 0x2b, 0xff, 0x0a, 0x6c, 0x39, 0xff, 0x0a, 0x89, 0x40, 0xff, 0x04, 0x82, 0x32, 0xff, 0x05, 0x78, 0x33, 0xff, 0x04, 0x73, 0x33, 0xff, 0x03, 0x76, 0x33, 0xff, 0x04, 0x7c, 0x33, 0xff, 0x0d, 0x7c, 0x36, 0xff, 0x10, 0x70, 0x34, 0xff, 0x05, 0x48, 0x1e, 0xff, 0x01, 0x2b, 0x0f, 0xff, 0x05, 0x24, 0x12, 0xff, 0x03, 0x25, 0x15, 0xff, 0x00, 0x29, 0x12, 0xff, 0x03, 0x43, 0x1f, 0xff, 0x13, 0x83, 0x4f, 0xff, 0x04, 0x7a, 0x40, 0xff, 0x09, 0x78, 0x3e, 0xff, 0x05, 0x78, 0x3f, 0xff, 0x04, 0x7a, 0x40, 0xff, 0x04, 0x7b, 0x40, 0xff, 0x03, 0x7c, 0x40, 0xff, 0x01, 0x79, 0x3f, 0xff, 0x03, 0x77, 0x3f, 0xff, 0x05, 0x77, 0x41, 0xff, 0x0c, 0x75, 0x45, 0xff, 0x03, 0x4b, 0x25, 0xff, 0x07, 0x2e, 0x16, 0xff, 0x03, 0x33, 0x1d, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x02, 0x3c, 0x1c, 0xff, 0x07, 0x60, 0x33, 0xff, 0x05, 0x66, 0x35, 0xff, 0x12, 0x77, 0x48, 0xff, 0x01, 0x2e, 0x13, 0xff, 0x0a, 0x38, 0x1d, 0xff, 0x06, 0x30, 0x1b, 0xff, 0x00, 0x1e, 0x0e, 0xff, 0x01, 0x36, 0x19, 0xff, 0x15, 0x76, 0x45, 0xff, 0x0b, 0x59, 0x2c, 0xff, 0x0a, 0x43, 0x26, 0xff, 0x0d, 0x47, 0x2b, 0xff, 0x02, 0x26, 0x10, 0xff, 0x01, 0x1f, 0x0c, 0xff, 0x09, 0x34, 0x1d, 0xff, 0x0e, 0x4b, 0x2e, 0xff, 0x08, 0x45, 0x29, 0xff, 0x02, 0x30, 0x1a, 0xff, 0x04, 0x1d, 0x0f, 0xff, 0x02, 0x21, 0x0d, 0xff, 0x0a, 0x3f, 0x28, 0xff, 0x06, 0x35, 0x1f, 0xff, 0x01, 0x23, 0x0d, 0xff, 0x0d, 0x3d, 0x25, 0xff, 0x07, 0x3e, 0x22, 0xff, 0x01, 0x37, 0x18, 0xff, 0x0c, 0x52, 0x2f, 0xff, 0x09, 0x62, 0x37, 0xff, 0x0b, 0x61, 0x37, 0xff, 0x0c, 0x5d, 0x33, 0xff, 0x03, 0x54, 0x28, 0xff, 0x0b, 0x67, 0x39, 0xff, 0x0a, 0x6e, 0x3b, 0xff, 0x09, 0x70, 0x3b, 0xff, 0x09, 0x71, 0x3a, 0xff, 0x0c, 0x6c, 0x39, 0xff, 0x0a, 0x51, 0x2a, 0xff, 0x03, 0x33, 0x19, 0xff, 0x00, 0x21, 0x10, 0xff, 0x03, 0x2d, 0x1b, 0xff, 0x04, 0x37, 0x1f, 0xff, 0x06, 0x36, 0x1c, 0xff, 0x02, 0x29, 0x12, 0xff, 0x03, 0x31, 0x1b, 0xff, 0x04, 0x38, 0x1b, 0xff, 0x07, 0x36, 0x1c, 0xff, 0x02, 0x24, 0x14, 0xff, 0x01, 0x26, 0x14, 0xff, 0x0c, 0x54, 0x2d, 0xff, 0x08, 0x62, 0x30, 0xff, 0x08, 0x61, 0x30, 0xff, 0x0b, 0x61, 0x2f, 0xff, 0x05, 0x67, 0x30, 0xff, 0x09, 0x6b, 0x37, 0xff, 0x06, 0x52, 0x2b, 0xff, 0x01, 0x2e, 0x13, 0xff, 0x03, 0x28, 0x12, 0xff, 0x10, 0x3d, 0x24, 0xff, 0x07, 0x45, 0x27, 0xff, 0x02, 0x2a, 0x14, 0xff, 0x02, 0x20, 0x10, 0xff, 0x03, 0x38, 0x22, 0xff, 0x0a, 0x47, 0x2c, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x0b, 0x4c, 0x2c, 0xff, 0x0b, 0x53, 0x2f, 0xff, 0x09, 0x4d, 0x27, 0xff, 0x06, 0x4c, 0x24, 0xff, 0x07, 0x5c, 0x2f, 0xff, 0x09, 0x69, 0x38, 0xff, 0x09, 0x69, 0x37, 0xff, 0x0b, 0x68, 0x37, 0xff, 0x0a, 0x68, 0x3a, 0xff, 0x09, 0x62, 0x38, 0xff, 0x0d, 0x55, 0x32, 0xff, 0x05, 0x37, 0x1d, 0xff, 0x01, 0x26, 0x11, 0xff, 0x06, 0x39, 0x23, 0xff, 0x2f, 0x89, 0x83, 0xff, 0x26, 0x81, 0x9d, 0xff, 0x31, 0x6e, 0xbf, 0xff, 0x33, 0x5f, 0xc9, 0xff, 0x20, 0x4d, 0xd0, 0xff, 0x23, 0x4b, 0xd6, 0xff, 0x27, 0x48, 0xd5, 0xff, 0x27, 0x47, 0xd8, 0xff, 0x27, 0x46, 0xd9, 0xff, 0x26, 0x45, 0xd4, 0xff, 0x27, 0x45, 0xd0, 0xff, 0x25, 0x44, 0xca, 0xff, 0x1e, 0x3d, 0xbd, 0xff, 0x13, 0x2e, 0xac, 0xff, 0x07, 0x1e, 0x94, 0xff, 0x0e, 0x25, 0x91, 0xff, 0x12, 0x35, 0x6b, 0xff, 0x0c, 0x47, 0x41, 0xff, 0x09, 0x45, 0x27, 0xff, 0x08, 0x47, 0x2b, 0xff, 0x13, 0x5f, 0x43, 0xff, 0x06, 0x42, 0x29, 0xff, 0x13, 0x56, 0x35, 0xff, 0x1c, 0x5a, 0x3a, 0xff, 0x01, 0x28, 0x12, 0xff, 0x02, 0x2e, 0x1a, 0xff, 0x0e, 0x51, 0x31, 0xff, 0x12, 0x5d, 0x3a, 0xff, 0x62, 0x90, 0x7d, 0xff, + 0x05, 0x43, 0x22, 0xff, 0x0d, 0x55, 0x2c, 0xff, 0x07, 0x48, 0x22, 0xff, 0x01, 0x30, 0x14, 0xff, 0x04, 0x2c, 0x17, 0xff, 0x01, 0x26, 0x13, 0xff, 0x00, 0x25, 0x12, 0xff, 0x01, 0x25, 0x12, 0xff, 0x01, 0x29, 0x12, 0xff, 0x04, 0x44, 0x1f, 0xff, 0x06, 0x5b, 0x2e, 0xff, 0x0a, 0x5d, 0x2f, 0xff, 0x05, 0x44, 0x1d, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x26, 0x10, 0xff, 0x00, 0x26, 0x11, 0xff, 0x01, 0x26, 0x13, 0xff, 0x03, 0x25, 0x14, 0xff, 0x05, 0x24, 0x12, 0xff, 0x02, 0x26, 0x11, 0xff, 0x00, 0x28, 0x11, 0xff, 0x01, 0x39, 0x19, 0xff, 0x09, 0x5a, 0x2a, 0xff, 0x05, 0x5e, 0x2d, 0xff, 0x06, 0x5b, 0x2e, 0xff, 0x02, 0x3c, 0x18, 0xff, 0x00, 0x25, 0x0b, 0xff, 0x09, 0x43, 0x24, 0xff, 0x06, 0x55, 0x29, 0xff, 0x05, 0x5a, 0x29, 0xff, 0x07, 0x5c, 0x2d, 0xff, 0x0b, 0x4c, 0x26, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x02, 0x22, 0x10, 0xff, 0x02, 0x22, 0x14, 0xff, 0x02, 0x25, 0x14, 0xff, 0x01, 0x29, 0x10, 0xff, 0x07, 0x40, 0x22, 0xff, 0x08, 0x54, 0x2c, 0xff, 0x07, 0x55, 0x2c, 0xff, 0x0c, 0x51, 0x2e, 0xff, 0x04, 0x3a, 0x1d, 0xff, 0x04, 0x27, 0x13, 0xff, 0x0e, 0x29, 0x18, 0xff, 0x07, 0x27, 0x11, 0xff, 0x01, 0x24, 0x09, 0xff, 0x01, 0x24, 0x03, 0xff, 0x00, 0x2d, 0x08, 0xff, 0x06, 0x47, 0x1b, 0xff, 0x0e, 0x61, 0x2e, 0xff, 0x12, 0x74, 0x39, 0xff, 0x0c, 0x77, 0x37, 0xff, 0x05, 0x7b, 0x34, 0xff, 0x01, 0x7c, 0x33, 0xff, 0x07, 0x7c, 0x33, 0xff, 0x07, 0x7a, 0x2e, 0xff, 0x07, 0x7f, 0x32, 0xff, 0x15, 0x92, 0x46, 0xff, 0x1e, 0x96, 0x53, 0xff, 0x10, 0x72, 0x3a, 0xff, 0x02, 0x43, 0x1c, 0xff, 0x03, 0x35, 0x15, 0xff, 0x01, 0x33, 0x0d, 0xff, 0x02, 0x2f, 0x0d, 0xff, 0x06, 0x30, 0x13, 0xff, 0x08, 0x33, 0x16, 0xff, 0x0f, 0x42, 0x20, 0xff, 0x0a, 0x3c, 0x1a, 0xff, 0x02, 0x2a, 0x0c, 0xff, 0x01, 0x26, 0x08, 0xff, 0x00, 0x27, 0x02, 0xff, 0x00, 0x25, 0x04, 0xff, 0x01, 0x27, 0x0c, 0xff, 0x05, 0x2b, 0x13, 0xff, 0x09, 0x32, 0x18, 0xff, 0x07, 0x34, 0x19, 0xff, 0x05, 0x36, 0x1a, 0xff, 0x04, 0x39, 0x1d, 0xff, 0x01, 0x44, 0x1e, 0xff, 0x0b, 0x4e, 0x24, 0xff, 0x07, 0x4d, 0x21, 0xff, 0x06, 0x52, 0x23, 0xff, 0x11, 0x66, 0x38, 0xff, 0x01, 0x4f, 0x23, 0xff, 0x05, 0x54, 0x2d, 0xff, 0x01, 0x53, 0x2d, 0xff, 0x01, 0x56, 0x2d, 0xff, 0x04, 0x58, 0x2e, 0xff, 0x04, 0x5a, 0x2f, 0xff, 0x03, 0x5b, 0x31, 0xff, 0x0d, 0x54, 0x2f, 0xff, 0x10, 0x3d, 0x20, 0xff, 0x08, 0x21, 0x09, 0xff, 0x05, 0x1e, 0x07, 0xff, 0x0a, 0x2d, 0x12, 0xff, 0x0f, 0x33, 0x16, 0xff, 0x01, 0x23, 0x05, 0xff, 0x04, 0x35, 0x14, 0xff, 0x0b, 0x4f, 0x2a, 0xff, 0x0a, 0x5a, 0x32, 0xff, 0x06, 0x5b, 0x31, 0xff, 0x01, 0x52, 0x29, 0xff, 0x08, 0x50, 0x27, 0xff, 0x0c, 0x50, 0x28, 0xff, 0x07, 0x40, 0x1b, 0xff, 0x03, 0x34, 0x12, 0xff, 0x11, 0x4a, 0x28, 0xff, 0x14, 0x57, 0x36, 0xff, 0x0e, 0x4d, 0x2d, 0xff, 0x06, 0x36, 0x19, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x0a, 0x32, 0x18, 0xff, 0x03, 0x34, 0x14, 0xff, 0x0b, 0x45, 0x20, 0xff, 0x19, 0x5f, 0x36, 0xff, 0x1f, 0x6a, 0x3f, 0xff, 0x1e, 0x69, 0x3d, 0xff, 0x0f, 0x55, 0x29, 0xff, 0x07, 0x44, 0x1c, 0xff, 0x0b, 0x5d, 0x31, 0xff, 0x1e, 0x80, 0x4e, 0xff, 0x21, 0x5d, 0x4d, 0xff, 0x30, 0x39, 0x52, 0xff, 0x0f, 0x31, 0x2f, 0xff, 0x17, 0x5b, 0x3d, 0xff, 0x1f, 0x50, 0x3e, 0xff, 0x30, 0x41, 0x58, 0xff, 0x20, 0x31, 0x4c, 0xff, 0x15, 0x33, 0x3a, 0xff, 0x0a, 0x36, 0x2c, 0xff, 0x0c, 0x43, 0x2d, 0xff, 0x0d, 0x48, 0x2f, 0xff, 0x0c, 0x49, 0x2f, 0xff, 0x0e, 0x4b, 0x31, 0xff, 0x11, 0x50, 0x35, 0xff, 0x0c, 0x46, 0x2e, 0xff, 0x08, 0x3e, 0x27, 0xff, 0x02, 0x4b, 0x23, 0xff, 0x13, 0x9a, 0x54, 0xff, 0x18, 0xb1, 0x60, 0xff, 0x00, 0x83, 0x34, 0xff, 0x04, 0x81, 0x34, 0xff, 0x04, 0x82, 0x35, 0xff, 0x01, 0x7f, 0x34, 0xff, 0x08, 0x7e, 0x37, 0xff, 0x0b, 0x7a, 0x37, 0xff, 0x0c, 0x70, 0x36, 0xff, 0x0a, 0x68, 0x33, 0xff, 0x0e, 0x65, 0x37, 0xff, 0x0e, 0x61, 0x37, 0xff, 0x0d, 0x4e, 0x2e, 0xff, 0x05, 0x34, 0x18, 0xff, 0x00, 0x26, 0x0d, 0xff, 0x02, 0x27, 0x12, 0xff, 0x08, 0x2d, 0x1c, 0xff, 0x0f, 0x37, 0x27, 0xff, 0x12, 0x41, 0x31, 0xff, 0x13, 0x48, 0x37, 0xff, 0x12, 0x49, 0x36, 0xff, 0x0e, 0x42, 0x2f, 0xff, 0x06, 0x38, 0x23, 0xff, 0x06, 0x35, 0x20, 0xff, 0x08, 0x35, 0x20, 0xff, 0x09, 0x35, 0x1f, 0xff, 0x06, 0x32, 0x1d, 0xff, 0x03, 0x2f, 0x1a, 0xff, 0x01, 0x2d, 0x17, 0xff, 0x02, 0x2e, 0x18, 0xff, 0x01, 0x2a, 0x15, 0xff, 0x01, 0x29, 0x14, 0xff, 0x00, 0x27, 0x13, 0xff, 0x00, 0x26, 0x14, 0xff, 0x00, 0x24, 0x13, 0xff, 0x00, 0x24, 0x14, 0xff, 0x03, 0x23, 0x16, 0xff, 0x03, 0x23, 0x17, 0xff, 0x02, 0x25, 0x13, 0xff, 0x04, 0x25, 0x12, 0xff, 0x06, 0x23, 0x13, 0xff, 0x04, 0x25, 0x12, 0xff, 0x01, 0x3c, 0x16, 0xff, 0x10, 0x75, 0x3a, 0xff, 0x09, 0x86, 0x3b, 0xff, 0x07, 0x7d, 0x31, 0xff, 0x04, 0x75, 0x30, 0xff, 0x03, 0x76, 0x30, 0xff, 0x02, 0x7b, 0x2f, 0xff, 0x06, 0x80, 0x32, 0xff, 0x12, 0x76, 0x35, 0xff, 0x0a, 0x55, 0x25, 0xff, 0x00, 0x2b, 0x0d, 0xff, 0x02, 0x25, 0x10, 0xff, 0x0a, 0x27, 0x17, 0xff, 0x07, 0x26, 0x17, 0xff, 0x01, 0x29, 0x13, 0xff, 0x01, 0x3a, 0x19, 0xff, 0x14, 0x7d, 0x4c, 0xff, 0x05, 0x79, 0x40, 0xff, 0x09, 0x77, 0x3e, 0xff, 0x06, 0x77, 0x40, 0xff, 0x06, 0x79, 0x40, 0xff, 0x05, 0x7b, 0x41, 0xff, 0x03, 0x7b, 0x40, 0xff, 0x01, 0x79, 0x3f, 0xff, 0x03, 0x77, 0x3f, 0xff, 0x05, 0x76, 0x41, 0xff, 0x09, 0x76, 0x45, 0xff, 0x04, 0x5e, 0x34, 0xff, 0x02, 0x2d, 0x12, 0xff, 0x04, 0x33, 0x1d, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x02, 0x3a, 0x1d, 0xff, 0x0a, 0x60, 0x35, 0xff, 0x06, 0x65, 0x33, 0xff, 0x13, 0x7c, 0x4b, 0xff, 0x05, 0x38, 0x1a, 0xff, 0x07, 0x31, 0x18, 0xff, 0x06, 0x30, 0x1d, 0xff, 0x00, 0x1e, 0x0f, 0xff, 0x01, 0x34, 0x18, 0xff, 0x13, 0x73, 0x42, 0xff, 0x0f, 0x64, 0x35, 0xff, 0x05, 0x40, 0x20, 0xff, 0x0e, 0x4c, 0x2f, 0xff, 0x04, 0x2f, 0x18, 0xff, 0x00, 0x1f, 0x0b, 0xff, 0x04, 0x2b, 0x14, 0xff, 0x10, 0x49, 0x2d, 0xff, 0x08, 0x48, 0x2b, 0xff, 0x05, 0x36, 0x1f, 0xff, 0x04, 0x1e, 0x0e, 0xff, 0x01, 0x21, 0x0d, 0xff, 0x09, 0x3d, 0x27, 0xff, 0x08, 0x38, 0x21, 0xff, 0x01, 0x23, 0x0c, 0xff, 0x0a, 0x3a, 0x23, 0xff, 0x09, 0x42, 0x26, 0xff, 0x01, 0x35, 0x17, 0xff, 0x0b, 0x4c, 0x2b, 0xff, 0x0a, 0x62, 0x37, 0xff, 0x0b, 0x62, 0x37, 0xff, 0x0d, 0x5f, 0x35, 0xff, 0x05, 0x52, 0x26, 0xff, 0x0a, 0x62, 0x34, 0xff, 0x0b, 0x6c, 0x3a, 0xff, 0x08, 0x70, 0x3a, 0xff, 0x04, 0x73, 0x39, 0xff, 0x08, 0x73, 0x3a, 0xff, 0x12, 0x64, 0x36, 0xff, 0x08, 0x44, 0x23, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x00, 0x26, 0x13, 0xff, 0x05, 0x35, 0x1e, 0xff, 0x07, 0x35, 0x1e, 0xff, 0x02, 0x28, 0x10, 0xff, 0x04, 0x31, 0x1b, 0xff, 0x05, 0x39, 0x1c, 0xff, 0x07, 0x36, 0x1c, 0xff, 0x03, 0x25, 0x15, 0xff, 0x00, 0x24, 0x12, 0xff, 0x0c, 0x53, 0x2c, 0xff, 0x0a, 0x63, 0x31, 0xff, 0x07, 0x60, 0x2f, 0xff, 0x07, 0x5e, 0x2c, 0xff, 0x04, 0x64, 0x30, 0xff, 0x05, 0x6a, 0x36, 0xff, 0x0a, 0x5f, 0x33, 0xff, 0x02, 0x37, 0x16, 0xff, 0x02, 0x27, 0x11, 0xff, 0x0d, 0x38, 0x21, 0xff, 0x07, 0x46, 0x28, 0xff, 0x02, 0x2a, 0x13, 0xff, 0x02, 0x20, 0x10, 0xff, 0x03, 0x38, 0x22, 0xff, 0x0a, 0x46, 0x2c, 0xff, 0x07, 0x3a, 0x1e, 0xff, 0x09, 0x4c, 0x2b, 0xff, 0x08, 0x52, 0x2e, 0xff, 0x05, 0x4b, 0x26, 0xff, 0x06, 0x55, 0x29, 0xff, 0x0a, 0x68, 0x37, 0xff, 0x07, 0x69, 0x37, 0xff, 0x0c, 0x69, 0x37, 0xff, 0x0c, 0x68, 0x38, 0xff, 0x04, 0x66, 0x39, 0xff, 0x06, 0x5e, 0x37, 0xff, 0x10, 0x4a, 0x2c, 0xff, 0x04, 0x29, 0x15, 0xff, 0x01, 0x27, 0x10, 0xff, 0x14, 0x49, 0x46, 0xff, 0x40, 0x7c, 0xb7, 0xff, 0x41, 0x72, 0xda, 0xff, 0x3a, 0x58, 0xdd, 0xff, 0x30, 0x46, 0xd8, 0xff, 0x27, 0x46, 0xdb, 0xff, 0x24, 0x48, 0xd7, 0xff, 0x24, 0x47, 0xd5, 0xff, 0x24, 0x47, 0xd7, 0xff, 0x22, 0x44, 0xd7, 0xff, 0x20, 0x41, 0xd5, 0xff, 0x21, 0x3f, 0xd2, 0xff, 0x24, 0x42, 0xd1, 0xff, 0x2a, 0x48, 0xd0, 0xff, 0x2d, 0x45, 0xcf, 0xff, 0x13, 0x2a, 0xa1, 0xff, 0x04, 0x17, 0x81, 0xff, 0x0d, 0x2b, 0x6e, 0xff, 0x09, 0x3d, 0x46, 0xff, 0x0b, 0x46, 0x2d, 0xff, 0x07, 0x43, 0x25, 0xff, 0x12, 0x5d, 0x3e, 0xff, 0x0b, 0x4f, 0x32, 0xff, 0x1d, 0x63, 0x40, 0xff, 0x14, 0x52, 0x33, 0xff, 0x00, 0x25, 0x11, 0xff, 0x06, 0x37, 0x22, 0xff, 0x0d, 0x54, 0x32, 0xff, 0x17, 0x62, 0x3e, 0xff, 0x5f, 0x88, 0x77, 0xff, + 0x04, 0x43, 0x23, 0xff, 0x0d, 0x55, 0x2b, 0xff, 0x06, 0x45, 0x1f, 0xff, 0x02, 0x32, 0x16, 0xff, 0x05, 0x30, 0x1b, 0xff, 0x00, 0x27, 0x14, 0xff, 0x00, 0x26, 0x13, 0xff, 0x01, 0x25, 0x12, 0xff, 0x01, 0x29, 0x11, 0xff, 0x05, 0x46, 0x20, 0xff, 0x05, 0x5c, 0x2d, 0xff, 0x09, 0x5f, 0x2e, 0xff, 0x06, 0x46, 0x1f, 0xff, 0x00, 0x28, 0x0e, 0xff, 0x01, 0x27, 0x12, 0xff, 0x00, 0x26, 0x11, 0xff, 0x00, 0x26, 0x11, 0xff, 0x02, 0x25, 0x14, 0xff, 0x03, 0x25, 0x13, 0xff, 0x04, 0x25, 0x12, 0xff, 0x01, 0x26, 0x11, 0xff, 0x00, 0x2a, 0x12, 0xff, 0x03, 0x40, 0x1e, 0xff, 0x08, 0x5e, 0x2c, 0xff, 0x05, 0x5e, 0x2d, 0xff, 0x06, 0x58, 0x2d, 0xff, 0x02, 0x37, 0x15, 0xff, 0x01, 0x28, 0x0d, 0xff, 0x0a, 0x47, 0x25, 0xff, 0x04, 0x56, 0x2a, 0xff, 0x03, 0x5b, 0x29, 0xff, 0x08, 0x5d, 0x2e, 0xff, 0x09, 0x43, 0x1f, 0xff, 0x00, 0x23, 0x0c, 0xff, 0x02, 0x22, 0x11, 0xff, 0x00, 0x24, 0x14, 0xff, 0x00, 0x25, 0x10, 0xff, 0x03, 0x34, 0x18, 0xff, 0x0c, 0x4e, 0x2a, 0xff, 0x05, 0x55, 0x2a, 0xff, 0x09, 0x56, 0x2d, 0xff, 0x0a, 0x4d, 0x2a, 0xff, 0x03, 0x33, 0x18, 0xff, 0x07, 0x27, 0x14, 0xff, 0x0b, 0x28, 0x14, 0xff, 0x02, 0x25, 0x09, 0xff, 0x00, 0x28, 0x04, 0xff, 0x02, 0x3b, 0x0e, 0xff, 0x09, 0x56, 0x26, 0xff, 0x0f, 0x6f, 0x39, 0xff, 0x0b, 0x75, 0x3a, 0xff, 0x06, 0x78, 0x36, 0xff, 0x05, 0x79, 0x33, 0xff, 0x05, 0x7c, 0x33, 0xff, 0x06, 0x7d, 0x32, 0xff, 0x04, 0x7b, 0x31, 0xff, 0x05, 0x81, 0x36, 0xff, 0x1b, 0x9e, 0x55, 0xff, 0x19, 0x90, 0x4e, 0xff, 0x06, 0x5c, 0x26, 0xff, 0x00, 0x3b, 0x11, 0xff, 0x00, 0x2f, 0x11, 0xff, 0x03, 0x2e, 0x12, 0xff, 0x06, 0x33, 0x0e, 0xff, 0x07, 0x36, 0x13, 0xff, 0x08, 0x3b, 0x1d, 0xff, 0x0f, 0x44, 0x24, 0xff, 0x07, 0x3a, 0x17, 0xff, 0x03, 0x31, 0x0d, 0xff, 0x0d, 0x38, 0x17, 0xff, 0x09, 0x32, 0x12, 0xff, 0x03, 0x2f, 0x0b, 0xff, 0x04, 0x30, 0x0f, 0xff, 0x0a, 0x33, 0x19, 0xff, 0x0b, 0x33, 0x1c, 0xff, 0x09, 0x35, 0x1b, 0xff, 0x05, 0x36, 0x1b, 0xff, 0x02, 0x36, 0x1e, 0xff, 0x02, 0x3b, 0x21, 0xff, 0x07, 0x51, 0x29, 0xff, 0x0d, 0x57, 0x2d, 0xff, 0x06, 0x51, 0x27, 0xff, 0x06, 0x53, 0x28, 0xff, 0x0c, 0x5e, 0x33, 0xff, 0x02, 0x52, 0x2a, 0xff, 0x07, 0x59, 0x32, 0xff, 0x05, 0x5a, 0x34, 0xff, 0x04, 0x5a, 0x31, 0xff, 0x07, 0x5b, 0x30, 0xff, 0x07, 0x5e, 0x34, 0xff, 0x03, 0x5c, 0x31, 0xff, 0x0c, 0x53, 0x2f, 0xff, 0x11, 0x40, 0x20, 0xff, 0x04, 0x20, 0x06, 0xff, 0x06, 0x1e, 0x06, 0xff, 0x08, 0x21, 0x08, 0xff, 0x03, 0x24, 0x07, 0xff, 0x01, 0x34, 0x12, 0xff, 0x08, 0x4d, 0x26, 0xff, 0x12, 0x64, 0x39, 0xff, 0x0c, 0x63, 0x37, 0xff, 0x01, 0x59, 0x2c, 0xff, 0x00, 0x58, 0x2b, 0xff, 0x01, 0x50, 0x22, 0xff, 0x03, 0x50, 0x25, 0xff, 0x0c, 0x4e, 0x26, 0xff, 0x06, 0x3e, 0x19, 0xff, 0x04, 0x3c, 0x19, 0xff, 0x11, 0x53, 0x31, 0xff, 0x0c, 0x47, 0x27, 0xff, 0x02, 0x2b, 0x0f, 0xff, 0x08, 0x33, 0x1a, 0xff, 0x0a, 0x3a, 0x1d, 0xff, 0x06, 0x3b, 0x19, 0xff, 0x0e, 0x4a, 0x25, 0xff, 0x0b, 0x4d, 0x26, 0xff, 0x0f, 0x5a, 0x30, 0xff, 0x12, 0x66, 0x37, 0xff, 0x16, 0x6d, 0x3a, 0xff, 0x0c, 0x5e, 0x2d, 0xff, 0x11, 0x81, 0x49, 0xff, 0x16, 0x7b, 0x51, 0xff, 0x2f, 0x4c, 0x62, 0xff, 0x50, 0x42, 0x84, 0xff, 0x20, 0x3a, 0x4d, 0xff, 0x0f, 0x45, 0x36, 0xff, 0x0b, 0x33, 0x2d, 0xff, 0x1f, 0x32, 0x43, 0xff, 0x21, 0x34, 0x47, 0xff, 0x25, 0x45, 0x4a, 0xff, 0x18, 0x45, 0x3f, 0xff, 0x18, 0x51, 0x43, 0xff, 0x14, 0x52, 0x41, 0xff, 0x14, 0x58, 0x41, 0xff, 0x14, 0x59, 0x3e, 0xff, 0x19, 0x5b, 0x3e, 0xff, 0x19, 0x5b, 0x43, 0xff, 0x0f, 0x55, 0x3a, 0xff, 0x07, 0x73, 0x3f, 0xff, 0x1d, 0xbe, 0x6c, 0xff, 0x04, 0x8e, 0x3c, 0xff, 0x05, 0x81, 0x36, 0xff, 0x09, 0x83, 0x37, 0xff, 0x09, 0x80, 0x36, 0xff, 0x05, 0x7d, 0x35, 0xff, 0x06, 0x7a, 0x36, 0xff, 0x06, 0x71, 0x34, 0xff, 0x05, 0x66, 0x31, 0xff, 0x0d, 0x64, 0x36, 0xff, 0x11, 0x5c, 0x35, 0xff, 0x06, 0x42, 0x21, 0xff, 0x00, 0x2a, 0x0f, 0xff, 0x03, 0x2d, 0x14, 0xff, 0x0a, 0x3c, 0x25, 0xff, 0x10, 0x46, 0x32, 0xff, 0x16, 0x50, 0x3d, 0xff, 0x17, 0x53, 0x40, 0xff, 0x17, 0x54, 0x41, 0xff, 0x12, 0x4e, 0x3b, 0xff, 0x05, 0x3f, 0x29, 0xff, 0x02, 0x38, 0x22, 0xff, 0x01, 0x34, 0x1c, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x05, 0x33, 0x1b, 0xff, 0x07, 0x32, 0x1a, 0xff, 0x08, 0x32, 0x1c, 0xff, 0x08, 0x32, 0x1c, 0xff, 0x07, 0x33, 0x1b, 0xff, 0x07, 0x34, 0x1b, 0xff, 0x06, 0x32, 0x19, 0xff, 0x06, 0x31, 0x19, 0xff, 0x02, 0x2c, 0x16, 0xff, 0x01, 0x2a, 0x14, 0xff, 0x02, 0x27, 0x12, 0xff, 0x02, 0x25, 0x12, 0xff, 0x05, 0x23, 0x15, 0xff, 0x06, 0x23, 0x16, 0xff, 0x02, 0x25, 0x13, 0xff, 0x02, 0x25, 0x12, 0xff, 0x04, 0x24, 0x15, 0xff, 0x05, 0x23, 0x12, 0xff, 0x01, 0x32, 0x0b, 0xff, 0x12, 0x75, 0x35, 0xff, 0x0d, 0x84, 0x37, 0xff, 0x09, 0x79, 0x31, 0xff, 0x07, 0x78, 0x30, 0xff, 0x05, 0x7c, 0x2f, 0xff, 0x07, 0x80, 0x31, 0xff, 0x0f, 0x7f, 0x34, 0xff, 0x0b, 0x5c, 0x26, 0xff, 0x02, 0x33, 0x10, 0xff, 0x02, 0x26, 0x12, 0xff, 0x04, 0x29, 0x14, 0xff, 0x09, 0x28, 0x17, 0xff, 0x05, 0x25, 0x15, 0xff, 0x03, 0x2a, 0x15, 0xff, 0x00, 0x32, 0x14, 0xff, 0x11, 0x72, 0x44, 0xff, 0x05, 0x7c, 0x43, 0xff, 0x07, 0x77, 0x3e, 0xff, 0x07, 0x77, 0x41, 0xff, 0x07, 0x79, 0x41, 0xff, 0x06, 0x7a, 0x41, 0xff, 0x04, 0x7a, 0x41, 0xff, 0x04, 0x79, 0x40, 0xff, 0x04, 0x77, 0x3f, 0xff, 0x04, 0x75, 0x40, 0xff, 0x05, 0x76, 0x43, 0xff, 0x07, 0x6a, 0x3c, 0xff, 0x02, 0x32, 0x14, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x05, 0x33, 0x1c, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x0b, 0x5e, 0x34, 0xff, 0x07, 0x63, 0x33, 0xff, 0x0f, 0x76, 0x47, 0xff, 0x0a, 0x46, 0x25, 0xff, 0x06, 0x2e, 0x13, 0xff, 0x04, 0x2e, 0x1a, 0xff, 0x00, 0x1e, 0x0f, 0xff, 0x01, 0x31, 0x16, 0xff, 0x10, 0x6e, 0x3d, 0xff, 0x10, 0x6f, 0x3d, 0xff, 0x02, 0x3e, 0x1a, 0xff, 0x0a, 0x4b, 0x2c, 0xff, 0x0b, 0x3c, 0x24, 0xff, 0x01, 0x23, 0x0f, 0xff, 0x01, 0x24, 0x0f, 0xff, 0x0d, 0x3f, 0x24, 0xff, 0x0b, 0x48, 0x2c, 0xff, 0x07, 0x3a, 0x22, 0xff, 0x02, 0x21, 0x0e, 0xff, 0x01, 0x1f, 0x0c, 0xff, 0x0a, 0x3c, 0x26, 0xff, 0x08, 0x3a, 0x23, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x09, 0x37, 0x20, 0xff, 0x0b, 0x44, 0x28, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x05, 0x45, 0x24, 0xff, 0x0b, 0x60, 0x35, 0xff, 0x0b, 0x61, 0x37, 0xff, 0x0e, 0x61, 0x36, 0xff, 0x07, 0x58, 0x2d, 0xff, 0x07, 0x5a, 0x2e, 0xff, 0x0d, 0x6c, 0x3c, 0xff, 0x09, 0x70, 0x3a, 0xff, 0x04, 0x73, 0x39, 0xff, 0x05, 0x73, 0x38, 0xff, 0x10, 0x6e, 0x3b, 0xff, 0x0c, 0x57, 0x2f, 0xff, 0x00, 0x2f, 0x13, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x04, 0x2b, 0x18, 0xff, 0x0c, 0x33, 0x1e, 0xff, 0x02, 0x28, 0x12, 0xff, 0x03, 0x30, 0x19, 0xff, 0x06, 0x38, 0x1c, 0xff, 0x07, 0x36, 0x1c, 0xff, 0x05, 0x26, 0x16, 0xff, 0x00, 0x22, 0x10, 0xff, 0x0b, 0x52, 0x2c, 0xff, 0x0b, 0x63, 0x31, 0xff, 0x07, 0x5f, 0x2f, 0xff, 0x07, 0x5e, 0x2a, 0xff, 0x05, 0x62, 0x31, 0xff, 0x06, 0x67, 0x37, 0xff, 0x0c, 0x65, 0x36, 0xff, 0x03, 0x41, 0x1d, 0xff, 0x02, 0x26, 0x10, 0xff, 0x0a, 0x32, 0x1f, 0xff, 0x08, 0x46, 0x28, 0xff, 0x01, 0x2b, 0x15, 0xff, 0x02, 0x20, 0x10, 0xff, 0x01, 0x37, 0x20, 0xff, 0x08, 0x42, 0x28, 0xff, 0x09, 0x3b, 0x1f, 0xff, 0x08, 0x4b, 0x2b, 0xff, 0x06, 0x52, 0x2e, 0xff, 0x06, 0x51, 0x2b, 0xff, 0x0b, 0x62, 0x35, 0xff, 0x08, 0x6a, 0x38, 0xff, 0x07, 0x69, 0x36, 0xff, 0x0d, 0x68, 0x37, 0xff, 0x0c, 0x69, 0x39, 0xff, 0x02, 0x63, 0x38, 0xff, 0x08, 0x5b, 0x37, 0xff, 0x0b, 0x3a, 0x21, 0xff, 0x05, 0x22, 0x16, 0xff, 0x03, 0x26, 0x18, 0xff, 0x32, 0x57, 0x76, 0xff, 0x58, 0x72, 0xdf, 0xff, 0x46, 0x5b, 0xe5, 0xff, 0x2b, 0x46, 0xd9, 0xff, 0x28, 0x48, 0xd8, 0xff, 0x28, 0x4b, 0xd6, 0xff, 0x27, 0x4a, 0xd6, 0xff, 0x25, 0x4a, 0xd8, 0xff, 0x25, 0x4a, 0xd9, 0xff, 0x23, 0x47, 0xd8, 0xff, 0x20, 0x42, 0xd9, 0xff, 0x21, 0x41, 0xd9, 0xff, 0x21, 0x41, 0xd6, 0xff, 0x20, 0x3f, 0xcf, 0xff, 0x27, 0x40, 0xcc, 0xff, 0x24, 0x3d, 0xbc, 0xff, 0x10, 0x25, 0x98, 0xff, 0x08, 0x21, 0x65, 0xff, 0x0a, 0x3b, 0x46, 0xff, 0x0e, 0x45, 0x34, 0xff, 0x06, 0x3c, 0x22, 0xff, 0x10, 0x5b, 0x38, 0xff, 0x0e, 0x58, 0x36, 0xff, 0x20, 0x67, 0x43, 0xff, 0x0e, 0x49, 0x2b, 0xff, 0x01, 0x26, 0x12, 0xff, 0x0b, 0x43, 0x2b, 0xff, 0x0d, 0x58, 0x34, 0xff, 0x1b, 0x63, 0x3f, 0xff, 0x60, 0x7d, 0x70, 0xff, + 0x04, 0x43, 0x22, 0xff, 0x0c, 0x54, 0x2b, 0xff, 0x06, 0x41, 0x1b, 0xff, 0x04, 0x35, 0x19, 0xff, 0x08, 0x36, 0x20, 0xff, 0x00, 0x28, 0x15, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x25, 0x14, 0xff, 0x01, 0x29, 0x12, 0xff, 0x04, 0x49, 0x22, 0xff, 0x04, 0x5e, 0x2d, 0xff, 0x08, 0x5e, 0x2e, 0xff, 0x08, 0x4b, 0x22, 0xff, 0x00, 0x29, 0x0f, 0xff, 0x01, 0x27, 0x13, 0xff, 0x01, 0x26, 0x13, 0xff, 0x00, 0x25, 0x12, 0xff, 0x02, 0x25, 0x14, 0xff, 0x03, 0x25, 0x13, 0xff, 0x04, 0x26, 0x12, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x07, 0x49, 0x24, 0xff, 0x07, 0x5f, 0x2c, 0xff, 0x05, 0x5e, 0x2e, 0xff, 0x06, 0x54, 0x2e, 0xff, 0x02, 0x32, 0x13, 0xff, 0x02, 0x2a, 0x0f, 0xff, 0x0b, 0x4a, 0x28, 0xff, 0x02, 0x58, 0x2b, 0xff, 0x02, 0x5d, 0x2b, 0xff, 0x09, 0x5a, 0x2f, 0xff, 0x05, 0x3a, 0x19, 0xff, 0x02, 0x22, 0x0d, 0xff, 0x02, 0x23, 0x12, 0xff, 0x00, 0x25, 0x13, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x07, 0x41, 0x21, 0xff, 0x0b, 0x52, 0x2a, 0xff, 0x06, 0x56, 0x29, 0xff, 0x0b, 0x57, 0x2e, 0xff, 0x09, 0x46, 0x24, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x06, 0x2a, 0x15, 0xff, 0x03, 0x28, 0x0f, 0xff, 0x00, 0x2a, 0x06, 0xff, 0x04, 0x42, 0x15, 0xff, 0x0d, 0x68, 0x31, 0xff, 0x11, 0x76, 0x3c, 0xff, 0x04, 0x75, 0x37, 0xff, 0x02, 0x76, 0x34, 0xff, 0x03, 0x79, 0x34, 0xff, 0x05, 0x7b, 0x33, 0xff, 0x06, 0x7e, 0x34, 0xff, 0x03, 0x7b, 0x30, 0xff, 0x09, 0x89, 0x3c, 0xff, 0x20, 0x9f, 0x58, 0xff, 0x12, 0x80, 0x46, 0xff, 0x02, 0x4e, 0x21, 0xff, 0x00, 0x33, 0x10, 0xff, 0x00, 0x2f, 0x0f, 0xff, 0x02, 0x32, 0x10, 0xff, 0x04, 0x38, 0x12, 0xff, 0x0d, 0x3f, 0x17, 0xff, 0x0a, 0x40, 0x1c, 0xff, 0x17, 0x50, 0x30, 0xff, 0x15, 0x4b, 0x2b, 0xff, 0x03, 0x32, 0x0e, 0xff, 0x10, 0x42, 0x1b, 0xff, 0x10, 0x48, 0x22, 0xff, 0x0e, 0x49, 0x24, 0xff, 0x0b, 0x3e, 0x1f, 0xff, 0x07, 0x36, 0x1b, 0xff, 0x09, 0x34, 0x21, 0xff, 0x06, 0x31, 0x1e, 0xff, 0x03, 0x34, 0x1d, 0xff, 0x02, 0x37, 0x1e, 0xff, 0x00, 0x39, 0x20, 0xff, 0x05, 0x47, 0x2b, 0xff, 0x0f, 0x5d, 0x33, 0xff, 0x07, 0x57, 0x2b, 0xff, 0x00, 0x4f, 0x23, 0xff, 0x08, 0x58, 0x2e, 0xff, 0x05, 0x57, 0x2d, 0xff, 0x03, 0x55, 0x2d, 0xff, 0x05, 0x58, 0x30, 0xff, 0x04, 0x59, 0x32, 0xff, 0x07, 0x5d, 0x35, 0xff, 0x0a, 0x5e, 0x35, 0xff, 0x09, 0x5e, 0x34, 0xff, 0x03, 0x5a, 0x2f, 0xff, 0x06, 0x4d, 0x27, 0xff, 0x04, 0x31, 0x0f, 0xff, 0x04, 0x22, 0x06, 0xff, 0x07, 0x25, 0x0b, 0xff, 0x0c, 0x25, 0x0a, 0xff, 0x03, 0x2b, 0x0c, 0xff, 0x05, 0x49, 0x22, 0xff, 0x11, 0x65, 0x39, 0xff, 0x0e, 0x6b, 0x3c, 0xff, 0x02, 0x5e, 0x2d, 0xff, 0x03, 0x65, 0x33, 0xff, 0x04, 0x6a, 0x38, 0xff, 0x03, 0x5e, 0x2c, 0xff, 0x00, 0x55, 0x25, 0xff, 0x06, 0x55, 0x29, 0xff, 0x09, 0x4c, 0x24, 0xff, 0x01, 0x3d, 0x18, 0xff, 0x05, 0x45, 0x22, 0xff, 0x06, 0x3c, 0x1d, 0xff, 0x02, 0x2a, 0x0e, 0xff, 0x0b, 0x3d, 0x21, 0xff, 0x04, 0x39, 0x1b, 0xff, 0x11, 0x47, 0x24, 0xff, 0x0f, 0x47, 0x25, 0xff, 0x00, 0x31, 0x0f, 0xff, 0x02, 0x43, 0x1c, 0xff, 0x05, 0x5c, 0x2a, 0xff, 0x03, 0x63, 0x28, 0xff, 0x02, 0x5c, 0x21, 0xff, 0x17, 0x94, 0x55, 0xff, 0x10, 0x64, 0x4b, 0xff, 0x50, 0x4c, 0x84, 0xff, 0x5c, 0x3f, 0x9a, 0xff, 0x31, 0x41, 0x63, 0xff, 0x1b, 0x36, 0x43, 0xff, 0x2d, 0x43, 0x59, 0xff, 0x11, 0x28, 0x36, 0xff, 0x17, 0x33, 0x37, 0xff, 0x20, 0x48, 0x44, 0xff, 0x1e, 0x4f, 0x47, 0xff, 0x1f, 0x5b, 0x50, 0xff, 0x10, 0x52, 0x45, 0xff, 0x0d, 0x54, 0x40, 0xff, 0x10, 0x59, 0x41, 0xff, 0x15, 0x5b, 0x40, 0xff, 0x11, 0x5b, 0x40, 0xff, 0x07, 0x66, 0x3d, 0xff, 0x14, 0xa0, 0x60, 0xff, 0x0a, 0xa5, 0x51, 0xff, 0x05, 0x81, 0x31, 0xff, 0x0a, 0x82, 0x39, 0xff, 0x0a, 0x82, 0x3a, 0xff, 0x0c, 0x7d, 0x38, 0xff, 0x09, 0x77, 0x35, 0xff, 0x05, 0x6e, 0x32, 0xff, 0x06, 0x6a, 0x33, 0xff, 0x0f, 0x68, 0x3a, 0xff, 0x0d, 0x5a, 0x34, 0xff, 0x04, 0x39, 0x1b, 0xff, 0x02, 0x2c, 0x10, 0xff, 0x0a, 0x40, 0x27, 0xff, 0x14, 0x51, 0x38, 0xff, 0x17, 0x5b, 0x44, 0xff, 0x10, 0x5a, 0x43, 0xff, 0x0d, 0x58, 0x42, 0xff, 0x0e, 0x56, 0x40, 0xff, 0x0c, 0x4c, 0x36, 0xff, 0x07, 0x3e, 0x29, 0xff, 0x01, 0x32, 0x1c, 0xff, 0x00, 0x33, 0x1b, 0xff, 0x03, 0x34, 0x1b, 0xff, 0x04, 0x33, 0x1a, 0xff, 0x08, 0x33, 0x1a, 0xff, 0x09, 0x33, 0x1a, 0xff, 0x0a, 0x32, 0x1b, 0xff, 0x0a, 0x32, 0x1c, 0xff, 0x09, 0x34, 0x1b, 0xff, 0x08, 0x33, 0x19, 0xff, 0x07, 0x33, 0x19, 0xff, 0x09, 0x35, 0x1b, 0xff, 0x09, 0x34, 0x1b, 0xff, 0x05, 0x2f, 0x18, 0xff, 0x03, 0x2a, 0x14, 0xff, 0x01, 0x27, 0x11, 0xff, 0x04, 0x23, 0x13, 0xff, 0x04, 0x23, 0x14, 0xff, 0x00, 0x25, 0x10, 0xff, 0x00, 0x25, 0x10, 0xff, 0x01, 0x21, 0x13, 0xff, 0x05, 0x24, 0x14, 0xff, 0x04, 0x3b, 0x13, 0xff, 0x16, 0x81, 0x3c, 0xff, 0x0c, 0x84, 0x33, 0xff, 0x08, 0x7c, 0x32, 0xff, 0x05, 0x7b, 0x2f, 0xff, 0x07, 0x7e, 0x2f, 0xff, 0x12, 0x80, 0x37, 0xff, 0x11, 0x6f, 0x31, 0xff, 0x02, 0x3a, 0x12, 0xff, 0x03, 0x28, 0x11, 0xff, 0x07, 0x28, 0x18, 0xff, 0x02, 0x27, 0x11, 0xff, 0x01, 0x22, 0x0e, 0xff, 0x04, 0x26, 0x14, 0xff, 0x07, 0x2c, 0x18, 0xff, 0x00, 0x2f, 0x13, 0xff, 0x0f, 0x69, 0x3e, 0xff, 0x06, 0x80, 0x48, 0xff, 0x05, 0x76, 0x3c, 0xff, 0x06, 0x76, 0x40, 0xff, 0x07, 0x77, 0x41, 0xff, 0x06, 0x7a, 0x41, 0xff, 0x06, 0x7a, 0x41, 0xff, 0x05, 0x79, 0x40, 0xff, 0x04, 0x76, 0x3e, 0xff, 0x04, 0x74, 0x3e, 0xff, 0x02, 0x75, 0x40, 0xff, 0x0b, 0x75, 0x41, 0xff, 0x04, 0x3b, 0x18, 0xff, 0x01, 0x2e, 0x16, 0xff, 0x04, 0x32, 0x1c, 0xff, 0x01, 0x34, 0x19, 0xff, 0x0d, 0x5b, 0x34, 0xff, 0x07, 0x60, 0x33, 0xff, 0x0c, 0x6d, 0x40, 0xff, 0x0c, 0x56, 0x33, 0xff, 0x02, 0x29, 0x0e, 0xff, 0x02, 0x2b, 0x18, 0xff, 0x01, 0x1f, 0x11, 0xff, 0x01, 0x30, 0x16, 0xff, 0x0a, 0x65, 0x34, 0xff, 0x10, 0x76, 0x41, 0xff, 0x01, 0x40, 0x19, 0xff, 0x05, 0x46, 0x25, 0xff, 0x0e, 0x46, 0x2b, 0xff, 0x04, 0x2e, 0x18, 0xff, 0x00, 0x20, 0x0c, 0xff, 0x06, 0x30, 0x18, 0xff, 0x0f, 0x4a, 0x2e, 0xff, 0x09, 0x3f, 0x26, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x01, 0x1e, 0x0b, 0xff, 0x0a, 0x38, 0x23, 0xff, 0x09, 0x3d, 0x26, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x06, 0x35, 0x1e, 0xff, 0x0e, 0x46, 0x2b, 0xff, 0x07, 0x38, 0x1d, 0xff, 0x01, 0x3e, 0x1f, 0xff, 0x0b, 0x5e, 0x34, 0xff, 0x0b, 0x61, 0x37, 0xff, 0x0d, 0x60, 0x37, 0xff, 0x0a, 0x5c, 0x33, 0xff, 0x02, 0x54, 0x29, 0xff, 0x0d, 0x69, 0x3b, 0xff, 0x08, 0x6e, 0x3b, 0xff, 0x05, 0x73, 0x39, 0xff, 0x02, 0x72, 0x36, 0xff, 0x0b, 0x72, 0x3a, 0xff, 0x0b, 0x66, 0x36, 0xff, 0x01, 0x3c, 0x1a, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x04, 0x24, 0x13, 0xff, 0x0a, 0x2c, 0x1a, 0xff, 0x01, 0x25, 0x11, 0xff, 0x02, 0x2e, 0x17, 0xff, 0x06, 0x38, 0x1b, 0xff, 0x07, 0x35, 0x1b, 0xff, 0x06, 0x27, 0x17, 0xff, 0x00, 0x1f, 0x0d, 0xff, 0x0a, 0x50, 0x2a, 0xff, 0x0b, 0x63, 0x32, 0xff, 0x08, 0x5e, 0x2d, 0xff, 0x05, 0x5e, 0x2a, 0xff, 0x06, 0x60, 0x30, 0xff, 0x06, 0x62, 0x34, 0xff, 0x0c, 0x65, 0x36, 0xff, 0x07, 0x4e, 0x26, 0xff, 0x01, 0x28, 0x12, 0xff, 0x06, 0x2e, 0x1c, 0xff, 0x0a, 0x46, 0x29, 0xff, 0x01, 0x2d, 0x16, 0xff, 0x01, 0x21, 0x10, 0xff, 0x01, 0x36, 0x1f, 0xff, 0x08, 0x40, 0x27, 0xff, 0x0a, 0x3b, 0x1f, 0xff, 0x08, 0x4b, 0x2a, 0xff, 0x03, 0x51, 0x2c, 0xff, 0x09, 0x5a, 0x32, 0xff, 0x0e, 0x68, 0x3a, 0xff, 0x07, 0x69, 0x37, 0xff, 0x08, 0x69, 0x38, 0xff, 0x0c, 0x6a, 0x39, 0xff, 0x0b, 0x68, 0x3b, 0xff, 0x04, 0x5e, 0x37, 0xff, 0x0c, 0x57, 0x37, 0xff, 0x04, 0x2c, 0x16, 0xff, 0x05, 0x1f, 0x1a, 0xff, 0x0a, 0x28, 0x2a, 0xff, 0x4e, 0x62, 0xa0, 0xff, 0x6c, 0x72, 0xf3, 0xff, 0x3c, 0x4a, 0xd9, 0xff, 0x28, 0x49, 0xdc, 0xff, 0x23, 0x4d, 0xdd, 0xff, 0x27, 0x4d, 0xd7, 0xff, 0x26, 0x49, 0xd5, 0xff, 0x24, 0x47, 0xd6, 0xff, 0x21, 0x46, 0xd3, 0xff, 0x20, 0x44, 0xd6, 0xff, 0x1f, 0x41, 0xd8, 0xff, 0x1e, 0x3e, 0xd9, 0xff, 0x20, 0x3f, 0xd8, 0xff, 0x1f, 0x3d, 0xd1, 0xff, 0x20, 0x3c, 0xc6, 0xff, 0x1c, 0x36, 0xbb, 0xff, 0x1f, 0x3c, 0xb9, 0xff, 0x07, 0x23, 0x69, 0xff, 0x0a, 0x39, 0x45, 0xff, 0x0e, 0x44, 0x35, 0xff, 0x04, 0x36, 0x20, 0xff, 0x0e, 0x55, 0x32, 0xff, 0x11, 0x5f, 0x38, 0xff, 0x1c, 0x64, 0x3f, 0xff, 0x07, 0x3e, 0x1f, 0xff, 0x05, 0x36, 0x21, 0xff, 0x11, 0x4f, 0x36, 0xff, 0x0c, 0x5c, 0x36, 0xff, 0x18, 0x5e, 0x39, 0xff, 0x60, 0x74, 0x68, 0xff, + 0x04, 0x43, 0x22, 0xff, 0x0c, 0x53, 0x2a, 0xff, 0x04, 0x3f, 0x19, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x0a, 0x3a, 0x24, 0xff, 0x01, 0x29, 0x15, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x25, 0x14, 0xff, 0x01, 0x29, 0x12, 0xff, 0x05, 0x4a, 0x23, 0xff, 0x04, 0x5e, 0x2c, 0xff, 0x07, 0x5f, 0x2c, 0xff, 0x0c, 0x50, 0x27, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x00, 0x27, 0x13, 0xff, 0x01, 0x26, 0x14, 0xff, 0x00, 0x25, 0x13, 0xff, 0x01, 0x25, 0x13, 0xff, 0x03, 0x25, 0x13, 0xff, 0x03, 0x26, 0x11, 0xff, 0x00, 0x26, 0x0f, 0xff, 0x02, 0x32, 0x17, 0xff, 0x0a, 0x4d, 0x28, 0xff, 0x06, 0x5e, 0x2b, 0xff, 0x06, 0x5c, 0x2f, 0xff, 0x08, 0x53, 0x2e, 0xff, 0x02, 0x2f, 0x12, 0xff, 0x04, 0x2c, 0x12, 0xff, 0x0e, 0x4d, 0x2a, 0xff, 0x02, 0x5a, 0x2b, 0xff, 0x02, 0x5e, 0x2c, 0xff, 0x06, 0x57, 0x2c, 0xff, 0x02, 0x34, 0x13, 0xff, 0x05, 0x22, 0x0e, 0xff, 0x03, 0x24, 0x13, 0xff, 0x00, 0x25, 0x12, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x0c, 0x4b, 0x27, 0xff, 0x0a, 0x55, 0x2a, 0xff, 0x09, 0x56, 0x2a, 0xff, 0x0e, 0x55, 0x2d, 0xff, 0x06, 0x40, 0x20, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x02, 0x28, 0x11, 0xff, 0x00, 0x29, 0x0b, 0xff, 0x05, 0x44, 0x18, 0xff, 0x11, 0x66, 0x30, 0xff, 0x11, 0x77, 0x38, 0xff, 0x08, 0x75, 0x32, 0xff, 0x03, 0x75, 0x32, 0xff, 0x03, 0x76, 0x31, 0xff, 0x05, 0x7a, 0x33, 0xff, 0x08, 0x7f, 0x35, 0xff, 0x03, 0x7c, 0x32, 0xff, 0x08, 0x88, 0x3b, 0xff, 0x1d, 0xa0, 0x55, 0xff, 0x15, 0x84, 0x45, 0xff, 0x02, 0x44, 0x19, 0xff, 0x00, 0x30, 0x12, 0xff, 0x02, 0x2d, 0x14, 0xff, 0x04, 0x33, 0x15, 0xff, 0x08, 0x3f, 0x17, 0xff, 0x07, 0x42, 0x15, 0xff, 0x0b, 0x44, 0x1a, 0xff, 0x14, 0x4d, 0x28, 0xff, 0x19, 0x4f, 0x30, 0xff, 0x07, 0x36, 0x17, 0xff, 0x08, 0x3d, 0x18, 0xff, 0x0a, 0x46, 0x1d, 0xff, 0x05, 0x4c, 0x20, 0xff, 0x06, 0x50, 0x26, 0xff, 0x0b, 0x44, 0x24, 0xff, 0x02, 0x35, 0x1b, 0xff, 0x05, 0x33, 0x21, 0xff, 0x04, 0x33, 0x21, 0xff, 0x02, 0x36, 0x21, 0xff, 0x01, 0x3b, 0x21, 0xff, 0x02, 0x42, 0x25, 0xff, 0x0e, 0x58, 0x37, 0xff, 0x09, 0x5a, 0x2e, 0xff, 0x01, 0x55, 0x28, 0xff, 0x02, 0x57, 0x2b, 0xff, 0x04, 0x58, 0x2e, 0xff, 0x04, 0x56, 0x2c, 0xff, 0x03, 0x57, 0x2d, 0xff, 0x04, 0x58, 0x2e, 0xff, 0x01, 0x55, 0x2c, 0xff, 0x01, 0x56, 0x2e, 0xff, 0x06, 0x59, 0x32, 0xff, 0x05, 0x5a, 0x30, 0xff, 0x04, 0x59, 0x2e, 0xff, 0x05, 0x4d, 0x25, 0xff, 0x01, 0x2b, 0x09, 0xff, 0x06, 0x29, 0x0b, 0xff, 0x0a, 0x2f, 0x12, 0xff, 0x08, 0x2d, 0x10, 0xff, 0x02, 0x2f, 0x0e, 0xff, 0x0c, 0x55, 0x2d, 0xff, 0x16, 0x70, 0x42, 0xff, 0x03, 0x67, 0x34, 0xff, 0x02, 0x6a, 0x36, 0xff, 0x0c, 0x7b, 0x45, 0xff, 0x0e, 0x7e, 0x48, 0xff, 0x0f, 0x72, 0x3f, 0xff, 0x02, 0x62, 0x2f, 0xff, 0x06, 0x5f, 0x30, 0xff, 0x0d, 0x5a, 0x2f, 0xff, 0x05, 0x45, 0x1f, 0xff, 0x01, 0x3f, 0x1b, 0xff, 0x01, 0x35, 0x16, 0xff, 0x06, 0x34, 0x18, 0xff, 0x07, 0x3f, 0x20, 0xff, 0x04, 0x3d, 0x1d, 0xff, 0x0e, 0x43, 0x21, 0xff, 0x07, 0x3a, 0x1a, 0xff, 0x00, 0x32, 0x15, 0xff, 0x00, 0x35, 0x11, 0xff, 0x07, 0x61, 0x2c, 0xff, 0x12, 0x7e, 0x3c, 0xff, 0x05, 0x6a, 0x29, 0xff, 0x1c, 0x91, 0x54, 0xff, 0x18, 0x55, 0x4c, 0xff, 0x66, 0x4d, 0x9a, 0xff, 0x68, 0x49, 0xa7, 0xff, 0x2d, 0x36, 0x5b, 0xff, 0x57, 0x58, 0x82, 0xff, 0x57, 0x54, 0x8f, 0xff, 0x22, 0x38, 0x4d, 0xff, 0x0e, 0x31, 0x2f, 0xff, 0x0d, 0x3c, 0x32, 0xff, 0x13, 0x4c, 0x3b, 0xff, 0x19, 0x5b, 0x48, 0xff, 0x0d, 0x53, 0x41, 0xff, 0x0a, 0x53, 0x3f, 0xff, 0x0f, 0x58, 0x42, 0xff, 0x13, 0x5c, 0x44, 0xff, 0x0b, 0x5c, 0x3d, 0xff, 0x07, 0x7c, 0x46, 0xff, 0x1a, 0xb5, 0x6c, 0xff, 0x02, 0x8d, 0x3c, 0xff, 0x08, 0x83, 0x35, 0xff, 0x07, 0x82, 0x38, 0xff, 0x08, 0x7e, 0x38, 0xff, 0x0c, 0x79, 0x38, 0xff, 0x09, 0x71, 0x35, 0xff, 0x09, 0x69, 0x32, 0xff, 0x10, 0x66, 0x36, 0xff, 0x0f, 0x5b, 0x34, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x02, 0x30, 0x16, 0xff, 0x0e, 0x47, 0x30, 0xff, 0x1a, 0x5e, 0x45, 0xff, 0x15, 0x60, 0x46, 0xff, 0x0e, 0x5d, 0x43, 0xff, 0x0b, 0x5c, 0x43, 0xff, 0x0b, 0x59, 0x41, 0xff, 0x0c, 0x53, 0x3b, 0xff, 0x04, 0x3d, 0x26, 0xff, 0x02, 0x31, 0x1b, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x04, 0x33, 0x19, 0xff, 0x06, 0x33, 0x19, 0xff, 0x07, 0x33, 0x1a, 0xff, 0x07, 0x32, 0x1b, 0xff, 0x06, 0x33, 0x1c, 0xff, 0x06, 0x33, 0x1c, 0xff, 0x06, 0x34, 0x1a, 0xff, 0x05, 0x34, 0x1a, 0xff, 0x03, 0x33, 0x19, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x06, 0x35, 0x1d, 0xff, 0x07, 0x33, 0x1c, 0xff, 0x03, 0x2d, 0x16, 0xff, 0x01, 0x26, 0x13, 0xff, 0x01, 0x25, 0x13, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x00, 0x25, 0x10, 0xff, 0x02, 0x21, 0x12, 0xff, 0x08, 0x23, 0x14, 0xff, 0x0b, 0x4b, 0x21, 0xff, 0x15, 0x8d, 0x43, 0xff, 0x09, 0x88, 0x33, 0xff, 0x06, 0x80, 0x33, 0xff, 0x05, 0x81, 0x31, 0xff, 0x0b, 0x81, 0x33, 0xff, 0x18, 0x79, 0x38, 0xff, 0x09, 0x51, 0x22, 0xff, 0x02, 0x2b, 0x0f, 0xff, 0x04, 0x27, 0x15, 0xff, 0x02, 0x22, 0x11, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x07, 0x2d, 0x19, 0xff, 0x06, 0x2b, 0x16, 0xff, 0x00, 0x2c, 0x11, 0xff, 0x0c, 0x62, 0x39, 0xff, 0x06, 0x81, 0x49, 0xff, 0x05, 0x76, 0x3c, 0xff, 0x04, 0x74, 0x3f, 0xff, 0x05, 0x76, 0x40, 0xff, 0x05, 0x78, 0x41, 0xff, 0x06, 0x79, 0x40, 0xff, 0x05, 0x79, 0x40, 0xff, 0x04, 0x76, 0x3e, 0xff, 0x04, 0x74, 0x3e, 0xff, 0x02, 0x75, 0x3e, 0xff, 0x09, 0x77, 0x41, 0xff, 0x08, 0x47, 0x21, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x01, 0x32, 0x18, 0xff, 0x0d, 0x57, 0x32, 0xff, 0x06, 0x5e, 0x32, 0xff, 0x08, 0x66, 0x39, 0xff, 0x0c, 0x60, 0x3c, 0xff, 0x00, 0x27, 0x0c, 0xff, 0x00, 0x29, 0x16, 0xff, 0x03, 0x1e, 0x13, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x08, 0x62, 0x31, 0xff, 0x0d, 0x79, 0x44, 0xff, 0x03, 0x48, 0x1f, 0xff, 0x05, 0x43, 0x22, 0xff, 0x0c, 0x49, 0x2d, 0xff, 0x08, 0x38, 0x22, 0xff, 0x00, 0x1f, 0x0b, 0xff, 0x02, 0x27, 0x10, 0xff, 0x0e, 0x46, 0x2a, 0xff, 0x0b, 0x43, 0x28, 0xff, 0x00, 0x27, 0x11, 0xff, 0x01, 0x1e, 0x0c, 0xff, 0x09, 0x36, 0x20, 0xff, 0x0b, 0x3f, 0x28, 0xff, 0x00, 0x23, 0x0c, 0xff, 0x05, 0x33, 0x1b, 0xff, 0x0d, 0x47, 0x2b, 0xff, 0x0a, 0x3a, 0x20, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x0a, 0x5a, 0x31, 0xff, 0x0d, 0x62, 0x38, 0xff, 0x0d, 0x61, 0x39, 0xff, 0x0b, 0x5e, 0x36, 0xff, 0x01, 0x52, 0x29, 0xff, 0x0b, 0x66, 0x39, 0xff, 0x09, 0x6c, 0x3b, 0xff, 0x06, 0x71, 0x39, 0xff, 0x06, 0x73, 0x38, 0xff, 0x06, 0x74, 0x38, 0xff, 0x08, 0x6e, 0x39, 0xff, 0x02, 0x4c, 0x24, 0xff, 0x00, 0x2a, 0x0f, 0xff, 0x05, 0x21, 0x10, 0xff, 0x08, 0x26, 0x17, 0xff, 0x01, 0x24, 0x12, 0xff, 0x02, 0x2d, 0x17, 0xff, 0x05, 0x38, 0x1b, 0xff, 0x07, 0x35, 0x1b, 0xff, 0x06, 0x29, 0x18, 0xff, 0x00, 0x20, 0x0e, 0xff, 0x08, 0x4e, 0x27, 0xff, 0x0b, 0x63, 0x32, 0xff, 0x07, 0x5d, 0x2d, 0xff, 0x04, 0x5e, 0x29, 0xff, 0x07, 0x5c, 0x2f, 0xff, 0x06, 0x5e, 0x31, 0xff, 0x08, 0x62, 0x31, 0xff, 0x09, 0x54, 0x2a, 0xff, 0x00, 0x2a, 0x15, 0xff, 0x03, 0x2a, 0x1a, 0xff, 0x0b, 0x44, 0x28, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x00, 0x22, 0x11, 0xff, 0x03, 0x37, 0x21, 0xff, 0x0a, 0x41, 0x27, 0xff, 0x0b, 0x3a, 0x1f, 0xff, 0x08, 0x4a, 0x2b, 0xff, 0x02, 0x52, 0x2d, 0xff, 0x09, 0x5f, 0x37, 0xff, 0x0f, 0x68, 0x3b, 0xff, 0x07, 0x68, 0x36, 0xff, 0x07, 0x6b, 0x38, 0xff, 0x07, 0x69, 0x39, 0xff, 0x0a, 0x66, 0x3a, 0xff, 0x0b, 0x5c, 0x38, 0xff, 0x0e, 0x4e, 0x31, 0xff, 0x02, 0x25, 0x11, 0xff, 0x05, 0x23, 0x19, 0xff, 0x08, 0x27, 0x2b, 0xff, 0x44, 0x59, 0x98, 0xff, 0x72, 0x7c, 0xf6, 0xff, 0x3a, 0x4b, 0xd6, 0xff, 0x2a, 0x4b, 0xdf, 0xff, 0x21, 0x49, 0xdd, 0xff, 0x25, 0x48, 0xda, 0xff, 0x22, 0x43, 0xd5, 0xff, 0x25, 0x46, 0xd7, 0xff, 0x25, 0x48, 0xd5, 0xff, 0x22, 0x45, 0xd6, 0xff, 0x20, 0x40, 0xd8, 0xff, 0x1e, 0x3c, 0xd8, 0xff, 0x1e, 0x3d, 0xd6, 0xff, 0x1e, 0x3e, 0xce, 0xff, 0x20, 0x3e, 0xc5, 0xff, 0x1a, 0x37, 0xbd, 0xff, 0x16, 0x34, 0xb7, 0xff, 0x13, 0x2f, 0x7e, 0xff, 0x09, 0x37, 0x43, 0xff, 0x0c, 0x42, 0x2f, 0xff, 0x04, 0x34, 0x1f, 0xff, 0x0c, 0x50, 0x2f, 0xff, 0x16, 0x65, 0x3c, 0xff, 0x15, 0x5c, 0x35, 0xff, 0x02, 0x35, 0x15, 0xff, 0x0c, 0x44, 0x2e, 0xff, 0x11, 0x53, 0x3a, 0xff, 0x11, 0x63, 0x3c, 0xff, 0x14, 0x58, 0x32, 0xff, 0x64, 0x73, 0x67, 0xff, + 0x04, 0x43, 0x22, 0xff, 0x0c, 0x52, 0x2a, 0xff, 0x03, 0x3c, 0x18, 0xff, 0x07, 0x3b, 0x1e, 0xff, 0x0a, 0x3d, 0x27, 0xff, 0x01, 0x29, 0x14, 0xff, 0x00, 0x25, 0x13, 0xff, 0x01, 0x24, 0x13, 0xff, 0x01, 0x29, 0x12, 0xff, 0x05, 0x4c, 0x24, 0xff, 0x04, 0x5f, 0x2c, 0xff, 0x06, 0x5e, 0x2a, 0xff, 0x10, 0x55, 0x2b, 0xff, 0x01, 0x30, 0x15, 0xff, 0x00, 0x27, 0x13, 0xff, 0x01, 0x26, 0x14, 0xff, 0x00, 0x26, 0x14, 0xff, 0x01, 0x25, 0x13, 0xff, 0x02, 0x24, 0x13, 0xff, 0x02, 0x26, 0x11, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x03, 0x37, 0x1a, 0xff, 0x0b, 0x50, 0x2a, 0xff, 0x05, 0x5c, 0x2b, 0xff, 0x07, 0x5c, 0x30, 0xff, 0x09, 0x50, 0x2d, 0xff, 0x02, 0x2c, 0x11, 0xff, 0x08, 0x30, 0x15, 0xff, 0x0f, 0x50, 0x2b, 0xff, 0x02, 0x5a, 0x2a, 0xff, 0x03, 0x5e, 0x2c, 0xff, 0x03, 0x52, 0x28, 0xff, 0x01, 0x2d, 0x0e, 0xff, 0x06, 0x22, 0x0f, 0xff, 0x04, 0x24, 0x13, 0xff, 0x00, 0x28, 0x12, 0xff, 0x06, 0x37, 0x1b, 0xff, 0x0e, 0x53, 0x2b, 0xff, 0x08, 0x56, 0x2a, 0xff, 0x0c, 0x56, 0x2b, 0xff, 0x0f, 0x54, 0x2d, 0xff, 0x05, 0x3b, 0x1c, 0xff, 0x00, 0x2c, 0x12, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x07, 0x41, 0x1e, 0xff, 0x13, 0x67, 0x34, 0xff, 0x12, 0x75, 0x37, 0xff, 0x0d, 0x76, 0x30, 0xff, 0x0c, 0x76, 0x30, 0xff, 0x0a, 0x77, 0x31, 0xff, 0x0c, 0x7a, 0x32, 0xff, 0x0b, 0x7e, 0x35, 0xff, 0x03, 0x7b, 0x31, 0xff, 0x08, 0x89, 0x3d, 0xff, 0x1a, 0x9c, 0x54, 0xff, 0x12, 0x77, 0x3e, 0xff, 0x01, 0x45, 0x15, 0xff, 0x01, 0x34, 0x0e, 0xff, 0x07, 0x30, 0x12, 0xff, 0x0e, 0x35, 0x18, 0xff, 0x0e, 0x3d, 0x1b, 0xff, 0x0a, 0x46, 0x1c, 0xff, 0x0a, 0x4a, 0x1d, 0xff, 0x0b, 0x4c, 0x21, 0xff, 0x09, 0x42, 0x1c, 0xff, 0x04, 0x34, 0x14, 0xff, 0x07, 0x3d, 0x1c, 0xff, 0x0b, 0x4d, 0x25, 0xff, 0x06, 0x4d, 0x22, 0xff, 0x09, 0x52, 0x24, 0xff, 0x0a, 0x52, 0x25, 0xff, 0x09, 0x47, 0x1f, 0xff, 0x01, 0x38, 0x19, 0xff, 0x02, 0x36, 0x1f, 0xff, 0x02, 0x35, 0x21, 0xff, 0x05, 0x3b, 0x25, 0xff, 0x07, 0x47, 0x2a, 0xff, 0x0a, 0x55, 0x32, 0xff, 0x10, 0x61, 0x39, 0xff, 0x04, 0x58, 0x29, 0xff, 0x09, 0x62, 0x32, 0xff, 0x04, 0x5d, 0x2e, 0xff, 0x02, 0x58, 0x2c, 0xff, 0x0d, 0x61, 0x35, 0xff, 0x05, 0x59, 0x2e, 0xff, 0x05, 0x5a, 0x2e, 0xff, 0x06, 0x5b, 0x2f, 0xff, 0x01, 0x57, 0x2d, 0xff, 0x03, 0x56, 0x2f, 0xff, 0x01, 0x55, 0x2a, 0xff, 0x0b, 0x62, 0x37, 0xff, 0x12, 0x5d, 0x35, 0xff, 0x0e, 0x44, 0x21, 0xff, 0x07, 0x31, 0x11, 0xff, 0x08, 0x35, 0x15, 0xff, 0x04, 0x3a, 0x19, 0xff, 0x01, 0x39, 0x17, 0xff, 0x13, 0x5c, 0x33, 0xff, 0x12, 0x6c, 0x3e, 0xff, 0x02, 0x70, 0x39, 0xff, 0x09, 0x81, 0x47, 0xff, 0x0d, 0x88, 0x4d, 0xff, 0x10, 0x88, 0x4e, 0xff, 0x14, 0x7d, 0x47, 0xff, 0x09, 0x74, 0x3f, 0xff, 0x0b, 0x6e, 0x3c, 0xff, 0x15, 0x69, 0x3d, 0xff, 0x0c, 0x50, 0x29, 0xff, 0x06, 0x46, 0x23, 0xff, 0x02, 0x3b, 0x1b, 0xff, 0x0b, 0x3e, 0x22, 0xff, 0x06, 0x41, 0x1f, 0xff, 0x01, 0x3b, 0x19, 0xff, 0x05, 0x37, 0x18, 0xff, 0x05, 0x34, 0x17, 0xff, 0x02, 0x30, 0x14, 0xff, 0x02, 0x39, 0x16, 0xff, 0x23, 0x7f, 0x4b, 0xff, 0x1b, 0x85, 0x46, 0xff, 0x0e, 0x6b, 0x2f, 0xff, 0x20, 0x7d, 0x4a, 0xff, 0x21, 0x43, 0x4d, 0xff, 0x72, 0x52, 0xa6, 0xff, 0x69, 0x52, 0xa1, 0xff, 0x1c, 0x22, 0x40, 0xff, 0x72, 0x60, 0x9f, 0xff, 0x6d, 0x52, 0xae, 0xff, 0x3d, 0x4c, 0x71, 0xff, 0x0b, 0x35, 0x33, 0xff, 0x0b, 0x42, 0x32, 0xff, 0x0d, 0x4e, 0x33, 0xff, 0x12, 0x5b, 0x3c, 0xff, 0x0e, 0x59, 0x3c, 0xff, 0x0f, 0x58, 0x3f, 0xff, 0x11, 0x59, 0x43, 0xff, 0x0f, 0x5c, 0x46, 0xff, 0x06, 0x5f, 0x3b, 0xff, 0x15, 0xa1, 0x5f, 0xff, 0x13, 0xac, 0x5e, 0xff, 0x07, 0x81, 0x36, 0xff, 0x0c, 0x86, 0x3b, 0xff, 0x02, 0x83, 0x38, 0xff, 0x05, 0x7b, 0x38, 0xff, 0x06, 0x72, 0x37, 0xff, 0x04, 0x68, 0x31, 0xff, 0x11, 0x66, 0x36, 0xff, 0x12, 0x59, 0x30, 0xff, 0x03, 0x39, 0x18, 0xff, 0x05, 0x3a, 0x1e, 0xff, 0x16, 0x55, 0x3e, 0xff, 0x1a, 0x5e, 0x49, 0xff, 0x16, 0x61, 0x49, 0xff, 0x14, 0x62, 0x46, 0xff, 0x14, 0x60, 0x46, 0xff, 0x16, 0x5f, 0x46, 0xff, 0x10, 0x54, 0x3c, 0xff, 0x04, 0x40, 0x27, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x03, 0x33, 0x1a, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x01, 0x33, 0x1c, 0xff, 0x02, 0x33, 0x1c, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x03, 0x33, 0x19, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x01, 0x33, 0x1d, 0xff, 0x01, 0x33, 0x1f, 0xff, 0x01, 0x34, 0x1e, 0xff, 0x01, 0x34, 0x1b, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x01, 0x33, 0x19, 0xff, 0x05, 0x3c, 0x23, 0xff, 0x0b, 0x43, 0x2a, 0xff, 0x11, 0x47, 0x2e, 0xff, 0x0b, 0x3f, 0x26, 0xff, 0x02, 0x34, 0x1c, 0xff, 0x01, 0x31, 0x18, 0xff, 0x01, 0x2d, 0x12, 0xff, 0x01, 0x28, 0x10, 0xff, 0x07, 0x23, 0x15, 0xff, 0x0b, 0x22, 0x13, 0xff, 0x10, 0x5e, 0x31, 0xff, 0x0c, 0x8e, 0x40, 0xff, 0x01, 0x8a, 0x31, 0xff, 0x02, 0x83, 0x32, 0xff, 0x04, 0x84, 0x32, 0xff, 0x0d, 0x82, 0x36, 0xff, 0x0c, 0x5f, 0x2a, 0xff, 0x01, 0x33, 0x13, 0xff, 0x05, 0x29, 0x17, 0xff, 0x02, 0x23, 0x11, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x0b, 0x3e, 0x25, 0xff, 0x0e, 0x3f, 0x27, 0xff, 0x05, 0x2e, 0x18, 0xff, 0x02, 0x29, 0x12, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x08, 0x59, 0x32, 0xff, 0x07, 0x82, 0x4b, 0xff, 0x04, 0x77, 0x3d, 0xff, 0x04, 0x73, 0x3e, 0xff, 0x02, 0x74, 0x3e, 0xff, 0x04, 0x76, 0x40, 0xff, 0x06, 0x79, 0x40, 0xff, 0x05, 0x78, 0x3f, 0xff, 0x04, 0x75, 0x3d, 0xff, 0x04, 0x74, 0x3e, 0xff, 0x04, 0x75, 0x3e, 0xff, 0x06, 0x76, 0x3e, 0xff, 0x0d, 0x56, 0x2d, 0xff, 0x01, 0x2f, 0x13, 0xff, 0x02, 0x30, 0x1a, 0xff, 0x02, 0x30, 0x16, 0xff, 0x0a, 0x53, 0x30, 0xff, 0x05, 0x5b, 0x31, 0xff, 0x06, 0x5e, 0x32, 0xff, 0x0e, 0x67, 0x42, 0xff, 0x01, 0x28, 0x0d, 0xff, 0x00, 0x27, 0x15, 0xff, 0x04, 0x1d, 0x12, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x06, 0x5f, 0x2d, 0xff, 0x0a, 0x77, 0x41, 0xff, 0x0a, 0x5b, 0x30, 0xff, 0x02, 0x3d, 0x1b, 0xff, 0x09, 0x4b, 0x2e, 0xff, 0x0c, 0x42, 0x2b, 0xff, 0x03, 0x25, 0x11, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x08, 0x3b, 0x20, 0xff, 0x0e, 0x46, 0x2b, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x01, 0x1f, 0x0d, 0xff, 0x08, 0x33, 0x1d, 0xff, 0x0c, 0x40, 0x29, 0xff, 0x01, 0x24, 0x0d, 0xff, 0x03, 0x30, 0x18, 0xff, 0x0c, 0x46, 0x2b, 0xff, 0x0b, 0x3b, 0x22, 0xff, 0x00, 0x37, 0x19, 0xff, 0x06, 0x54, 0x2c, 0xff, 0x0d, 0x62, 0x38, 0xff, 0x0d, 0x62, 0x3a, 0xff, 0x0d, 0x61, 0x3a, 0xff, 0x04, 0x55, 0x2e, 0xff, 0x09, 0x62, 0x36, 0xff, 0x0a, 0x6c, 0x3b, 0xff, 0x06, 0x70, 0x39, 0xff, 0x09, 0x74, 0x38, 0xff, 0x03, 0x75, 0x37, 0xff, 0x04, 0x73, 0x3a, 0xff, 0x08, 0x5e, 0x31, 0xff, 0x01, 0x35, 0x17, 0xff, 0x05, 0x1f, 0x0e, 0xff, 0x06, 0x21, 0x13, 0xff, 0x01, 0x23, 0x11, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x05, 0x37, 0x1b, 0xff, 0x07, 0x35, 0x1b, 0xff, 0x06, 0x29, 0x19, 0xff, 0x00, 0x20, 0x0e, 0xff, 0x06, 0x4a, 0x24, 0xff, 0x0b, 0x63, 0x32, 0xff, 0x06, 0x5e, 0x2d, 0xff, 0x04, 0x5d, 0x2b, 0xff, 0x07, 0x5b, 0x2f, 0xff, 0x08, 0x5b, 0x30, 0xff, 0x06, 0x5e, 0x2e, 0xff, 0x0a, 0x56, 0x2c, 0xff, 0x01, 0x2d, 0x17, 0xff, 0x03, 0x28, 0x18, 0xff, 0x0b, 0x41, 0x26, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x00, 0x23, 0x12, 0xff, 0x04, 0x37, 0x22, 0xff, 0x0a, 0x3f, 0x26, 0xff, 0x0d, 0x3a, 0x1f, 0xff, 0x07, 0x4a, 0x29, 0xff, 0x03, 0x55, 0x2f, 0xff, 0x0c, 0x65, 0x3c, 0xff, 0x0e, 0x68, 0x3a, 0xff, 0x08, 0x68, 0x39, 0xff, 0x04, 0x6b, 0x3a, 0xff, 0x03, 0x69, 0x39, 0xff, 0x06, 0x62, 0x37, 0xff, 0x11, 0x59, 0x36, 0xff, 0x09, 0x41, 0x25, 0xff, 0x00, 0x25, 0x10, 0xff, 0x03, 0x2a, 0x10, 0xff, 0x01, 0x29, 0x13, 0xff, 0x19, 0x41, 0x59, 0xff, 0x55, 0x72, 0xcf, 0xff, 0x46, 0x5c, 0xe4, 0xff, 0x2d, 0x49, 0xdb, 0xff, 0x28, 0x48, 0xd9, 0xff, 0x27, 0x47, 0xdb, 0xff, 0x26, 0x45, 0xda, 0xff, 0x2c, 0x49, 0xdb, 0xff, 0x2a, 0x4b, 0xd9, 0xff, 0x24, 0x46, 0xd6, 0xff, 0x22, 0x43, 0xd8, 0xff, 0x21, 0x3f, 0xd8, 0xff, 0x20, 0x3d, 0xd4, 0xff, 0x1d, 0x3c, 0xca, 0xff, 0x1c, 0x39, 0xc2, 0xff, 0x16, 0x34, 0xb9, 0xff, 0x0e, 0x2e, 0xb0, 0xff, 0x18, 0x31, 0x8a, 0xff, 0x09, 0x35, 0x45, 0xff, 0x0f, 0x48, 0x2b, 0xff, 0x07, 0x36, 0x20, 0xff, 0x0f, 0x51, 0x32, 0xff, 0x1b, 0x6a, 0x3f, 0xff, 0x0d, 0x53, 0x2d, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x14, 0x50, 0x39, 0xff, 0x0f, 0x54, 0x3a, 0xff, 0x14, 0x66, 0x3e, 0xff, 0x09, 0x46, 0x21, 0xff, 0x66, 0x72, 0x68, 0xff, + 0x04, 0x41, 0x21, 0xff, 0x0c, 0x50, 0x2a, 0xff, 0x02, 0x39, 0x17, 0xff, 0x05, 0x3f, 0x1e, 0xff, 0x09, 0x42, 0x23, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x00, 0x24, 0x14, 0xff, 0x01, 0x24, 0x13, 0xff, 0x00, 0x29, 0x11, 0xff, 0x04, 0x4f, 0x26, 0xff, 0x04, 0x5f, 0x2c, 0xff, 0x04, 0x5e, 0x2a, 0xff, 0x0b, 0x57, 0x2c, 0xff, 0x01, 0x32, 0x16, 0xff, 0x00, 0x26, 0x12, 0xff, 0x00, 0x26, 0x13, 0xff, 0x00, 0x26, 0x12, 0xff, 0x01, 0x24, 0x13, 0xff, 0x04, 0x23, 0x14, 0xff, 0x01, 0x25, 0x13, 0xff, 0x00, 0x28, 0x11, 0xff, 0x04, 0x3c, 0x1d, 0xff, 0x0c, 0x51, 0x2a, 0xff, 0x07, 0x5a, 0x2a, 0xff, 0x06, 0x5d, 0x2e, 0xff, 0x0a, 0x4e, 0x2b, 0xff, 0x02, 0x29, 0x12, 0xff, 0x05, 0x33, 0x15, 0xff, 0x0b, 0x54, 0x2a, 0xff, 0x03, 0x5a, 0x29, 0xff, 0x05, 0x5c, 0x2d, 0xff, 0x07, 0x4b, 0x25, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x07, 0x1f, 0x14, 0xff, 0x03, 0x23, 0x15, 0xff, 0x00, 0x2d, 0x13, 0xff, 0x0a, 0x46, 0x23, 0xff, 0x0a, 0x54, 0x2b, 0xff, 0x03, 0x56, 0x2b, 0xff, 0x08, 0x54, 0x2d, 0xff, 0x10, 0x50, 0x2d, 0xff, 0x06, 0x39, 0x1a, 0xff, 0x01, 0x33, 0x11, 0xff, 0x07, 0x4b, 0x23, 0xff, 0x11, 0x68, 0x35, 0xff, 0x0b, 0x73, 0x36, 0xff, 0x09, 0x76, 0x34, 0xff, 0x09, 0x73, 0x2e, 0xff, 0x0b, 0x74, 0x2e, 0xff, 0x0b, 0x7b, 0x33, 0xff, 0x09, 0x7d, 0x34, 0xff, 0x05, 0x7a, 0x33, 0xff, 0x07, 0x80, 0x3a, 0xff, 0x20, 0x9b, 0x58, 0xff, 0x12, 0x79, 0x3f, 0xff, 0x01, 0x3d, 0x18, 0xff, 0x00, 0x31, 0x0d, 0xff, 0x04, 0x32, 0x0e, 0xff, 0x10, 0x3b, 0x17, 0xff, 0x13, 0x40, 0x1b, 0xff, 0x0f, 0x42, 0x1d, 0xff, 0x0a, 0x46, 0x1f, 0xff, 0x07, 0x44, 0x1f, 0xff, 0x01, 0x36, 0x17, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x0b, 0x3b, 0x20, 0xff, 0x0d, 0x44, 0x26, 0xff, 0x0a, 0x4b, 0x28, 0xff, 0x09, 0x4d, 0x29, 0xff, 0x0f, 0x52, 0x2d, 0xff, 0x12, 0x54, 0x2e, 0xff, 0x08, 0x45, 0x1f, 0xff, 0x02, 0x3a, 0x1b, 0xff, 0x02, 0x36, 0x1f, 0xff, 0x09, 0x3b, 0x28, 0xff, 0x13, 0x4b, 0x36, 0xff, 0x0d, 0x50, 0x32, 0xff, 0x09, 0x5f, 0x32, 0xff, 0x0c, 0x6b, 0x37, 0xff, 0x0e, 0x68, 0x38, 0xff, 0x0c, 0x67, 0x37, 0xff, 0x02, 0x5a, 0x28, 0xff, 0x07, 0x63, 0x31, 0xff, 0x19, 0x76, 0x46, 0xff, 0x0f, 0x6a, 0x3d, 0xff, 0x02, 0x5a, 0x2d, 0xff, 0x04, 0x5b, 0x2e, 0xff, 0x05, 0x5c, 0x32, 0xff, 0x05, 0x5d, 0x33, 0xff, 0x01, 0x57, 0x2c, 0xff, 0x08, 0x63, 0x39, 0xff, 0x10, 0x61, 0x39, 0xff, 0x0e, 0x50, 0x2b, 0xff, 0x02, 0x37, 0x15, 0xff, 0x08, 0x3c, 0x1a, 0xff, 0x04, 0x48, 0x24, 0xff, 0x03, 0x47, 0x22, 0xff, 0x0a, 0x53, 0x2a, 0xff, 0x12, 0x6c, 0x3e, 0xff, 0x08, 0x7a, 0x44, 0xff, 0x08, 0x87, 0x4c, 0xff, 0x05, 0x88, 0x4b, 0xff, 0x08, 0x87, 0x4a, 0xff, 0x0c, 0x81, 0x48, 0xff, 0x0d, 0x7c, 0x47, 0xff, 0x0e, 0x75, 0x42, 0xff, 0x14, 0x6f, 0x42, 0xff, 0x08, 0x59, 0x30, 0xff, 0x04, 0x51, 0x29, 0xff, 0x04, 0x48, 0x26, 0xff, 0x05, 0x3f, 0x20, 0xff, 0x08, 0x3e, 0x18, 0xff, 0x02, 0x38, 0x13, 0xff, 0x05, 0x34, 0x1f, 0xff, 0x06, 0x31, 0x1b, 0xff, 0x03, 0x3c, 0x17, 0xff, 0x13, 0x63, 0x3c, 0xff, 0x1f, 0x75, 0x50, 0xff, 0x15, 0x5b, 0x43, 0xff, 0x2a, 0x5e, 0x47, 0xff, 0x16, 0x52, 0x32, 0xff, 0x2f, 0x3a, 0x5e, 0xff, 0x53, 0x40, 0x8f, 0xff, 0x39, 0x38, 0x58, 0xff, 0x0c, 0x1f, 0x21, 0xff, 0x42, 0x4b, 0x6e, 0xff, 0x68, 0x5b, 0xa0, 0xff, 0x4a, 0x55, 0x79, 0xff, 0x08, 0x3b, 0x2e, 0xff, 0x0e, 0x56, 0x31, 0xff, 0x0e, 0x5b, 0x34, 0xff, 0x13, 0x66, 0x41, 0xff, 0x11, 0x5c, 0x3f, 0xff, 0x15, 0x5d, 0x42, 0xff, 0x14, 0x61, 0x44, 0xff, 0x08, 0x62, 0x42, 0xff, 0x06, 0x71, 0x44, 0xff, 0x21, 0xb1, 0x6a, 0xff, 0x05, 0x94, 0x45, 0xff, 0x0e, 0x87, 0x3b, 0xff, 0x0f, 0x88, 0x3e, 0xff, 0x01, 0x7e, 0x38, 0xff, 0x03, 0x75, 0x37, 0xff, 0x06, 0x69, 0x36, 0xff, 0x0a, 0x63, 0x35, 0xff, 0x10, 0x54, 0x2d, 0xff, 0x05, 0x38, 0x18, 0xff, 0x08, 0x40, 0x22, 0xff, 0x16, 0x5d, 0x3f, 0xff, 0x15, 0x65, 0x48, 0xff, 0x15, 0x66, 0x4b, 0xff, 0x12, 0x68, 0x48, 0xff, 0x12, 0x67, 0x47, 0xff, 0x16, 0x65, 0x47, 0xff, 0x18, 0x5f, 0x43, 0xff, 0x07, 0x40, 0x27, 0xff, 0x00, 0x35, 0x1c, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x02, 0x34, 0x1a, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x03, 0x31, 0x1f, 0xff, 0x03, 0x32, 0x1c, 0xff, 0x07, 0x35, 0x17, 0xff, 0x05, 0x34, 0x18, 0xff, 0x00, 0x33, 0x1f, 0xff, 0x03, 0x33, 0x20, 0xff, 0x02, 0x36, 0x18, 0xff, 0x00, 0x39, 0x14, 0xff, 0x03, 0x3b, 0x17, 0xff, 0x0a, 0x48, 0x25, 0xff, 0x11, 0x50, 0x2f, 0xff, 0x0c, 0x4b, 0x2a, 0xff, 0x06, 0x46, 0x25, 0xff, 0x03, 0x46, 0x24, 0xff, 0x04, 0x42, 0x21, 0xff, 0x04, 0x40, 0x20, 0xff, 0x02, 0x3b, 0x1b, 0xff, 0x03, 0x34, 0x17, 0xff, 0x05, 0x2a, 0x18, 0xff, 0x03, 0x25, 0x10, 0xff, 0x11, 0x72, 0x37, 0xff, 0x08, 0x8e, 0x3a, 0xff, 0x06, 0x88, 0x32, 0xff, 0x05, 0x83, 0x30, 0xff, 0x09, 0x82, 0x35, 0xff, 0x0d, 0x76, 0x36, 0xff, 0x02, 0x3e, 0x17, 0xff, 0x02, 0x28, 0x12, 0xff, 0x05, 0x26, 0x12, 0xff, 0x01, 0x27, 0x0c, 0xff, 0x0d, 0x47, 0x23, 0xff, 0x19, 0x56, 0x34, 0xff, 0x08, 0x37, 0x1e, 0xff, 0x01, 0x27, 0x0f, 0xff, 0x00, 0x31, 0x15, 0xff, 0x05, 0x33, 0x1d, 0xff, 0x06, 0x4d, 0x2f, 0xff, 0x0b, 0x81, 0x4e, 0xff, 0x03, 0x76, 0x39, 0xff, 0x04, 0x70, 0x3e, 0xff, 0x03, 0x73, 0x3f, 0xff, 0x03, 0x76, 0x40, 0xff, 0x05, 0x77, 0x41, 0xff, 0x07, 0x76, 0x40, 0xff, 0x06, 0x76, 0x3f, 0xff, 0x05, 0x75, 0x3f, 0xff, 0x03, 0x75, 0x3e, 0xff, 0x06, 0x76, 0x3f, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x01, 0x36, 0x16, 0xff, 0x07, 0x2f, 0x19, 0xff, 0x03, 0x2e, 0x17, 0xff, 0x07, 0x4e, 0x30, 0xff, 0x06, 0x58, 0x31, 0xff, 0x07, 0x59, 0x2e, 0xff, 0x0f, 0x6b, 0x41, 0xff, 0x01, 0x2d, 0x10, 0xff, 0x01, 0x24, 0x12, 0xff, 0x05, 0x1d, 0x10, 0xff, 0x01, 0x2c, 0x17, 0xff, 0x08, 0x55, 0x2d, 0xff, 0x0f, 0x71, 0x3e, 0xff, 0x0a, 0x70, 0x3d, 0xff, 0x01, 0x3a, 0x17, 0xff, 0x05, 0x4a, 0x2c, 0xff, 0x0a, 0x49, 0x2e, 0xff, 0x07, 0x31, 0x1a, 0xff, 0x01, 0x21, 0x0b, 0xff, 0x05, 0x2c, 0x14, 0xff, 0x10, 0x44, 0x2b, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x01, 0x20, 0x0d, 0xff, 0x08, 0x2f, 0x1a, 0xff, 0x10, 0x41, 0x2b, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x03, 0x2d, 0x16, 0xff, 0x0c, 0x45, 0x2a, 0xff, 0x07, 0x3f, 0x24, 0xff, 0x00, 0x34, 0x17, 0xff, 0x07, 0x4d, 0x27, 0xff, 0x0d, 0x62, 0x37, 0xff, 0x0e, 0x63, 0x38, 0xff, 0x0b, 0x62, 0x39, 0xff, 0x06, 0x59, 0x32, 0xff, 0x0a, 0x5b, 0x31, 0xff, 0x09, 0x6a, 0x3a, 0xff, 0x08, 0x70, 0x3a, 0xff, 0x08, 0x72, 0x3a, 0xff, 0x05, 0x73, 0x37, 0xff, 0x05, 0x74, 0x3a, 0xff, 0x06, 0x69, 0x38, 0xff, 0x01, 0x45, 0x22, 0xff, 0x03, 0x22, 0x10, 0xff, 0x06, 0x1d, 0x11, 0xff, 0x01, 0x21, 0x11, 0xff, 0x00, 0x29, 0x13, 0xff, 0x07, 0x37, 0x1d, 0xff, 0x06, 0x35, 0x1d, 0xff, 0x05, 0x2c, 0x18, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x07, 0x46, 0x23, 0xff, 0x0b, 0x63, 0x35, 0xff, 0x05, 0x5d, 0x2d, 0xff, 0x03, 0x5c, 0x2c, 0xff, 0x04, 0x5b, 0x2e, 0xff, 0x06, 0x5b, 0x2f, 0xff, 0x09, 0x5b, 0x2e, 0xff, 0x0c, 0x56, 0x2e, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x02, 0x28, 0x12, 0xff, 0x0c, 0x3d, 0x25, 0xff, 0x02, 0x29, 0x15, 0xff, 0x02, 0x24, 0x13, 0xff, 0x09, 0x36, 0x24, 0xff, 0x0c, 0x3e, 0x27, 0xff, 0x07, 0x3a, 0x1f, 0xff, 0x04, 0x47, 0x25, 0xff, 0x08, 0x5a, 0x30, 0xff, 0x0d, 0x69, 0x39, 0xff, 0x09, 0x68, 0x38, 0xff, 0x06, 0x69, 0x39, 0xff, 0x03, 0x69, 0x39, 0xff, 0x07, 0x68, 0x3a, 0xff, 0x08, 0x5e, 0x35, 0xff, 0x12, 0x54, 0x34, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x02, 0x26, 0x15, 0xff, 0x01, 0x23, 0x13, 0xff, 0x00, 0x2a, 0x11, 0xff, 0x01, 0x29, 0x1f, 0xff, 0x22, 0x41, 0x6e, 0xff, 0x48, 0x62, 0xcf, 0xff, 0x31, 0x48, 0xd8, 0xff, 0x2e, 0x46, 0xd6, 0xff, 0x2d, 0x48, 0xdd, 0xff, 0x27, 0x46, 0xda, 0xff, 0x29, 0x48, 0xd9, 0xff, 0x24, 0x45, 0xd4, 0xff, 0x1e, 0x3f, 0xd2, 0xff, 0x1e, 0x3d, 0xd5, 0xff, 0x1f, 0x3c, 0xd5, 0xff, 0x1f, 0x3b, 0xd1, 0xff, 0x1c, 0x39, 0xc6, 0xff, 0x19, 0x35, 0xc2, 0xff, 0x12, 0x31, 0xb8, 0xff, 0x0d, 0x2c, 0xac, 0xff, 0x14, 0x31, 0x8d, 0xff, 0x06, 0x30, 0x46, 0xff, 0x16, 0x4b, 0x30, 0xff, 0x0e, 0x40, 0x24, 0xff, 0x13, 0x5a, 0x35, 0xff, 0x1e, 0x6a, 0x41, 0xff, 0x0e, 0x57, 0x31, 0xff, 0x0a, 0x57, 0x33, 0xff, 0x0d, 0x56, 0x39, 0xff, 0x0e, 0x54, 0x37, 0xff, 0x1a, 0x5e, 0x3e, 0xff, 0x04, 0x31, 0x16, 0xff, 0x65, 0x70, 0x6a, 0xff, + 0x06, 0x41, 0x1f, 0xff, 0x0b, 0x4d, 0x2a, 0xff, 0x01, 0x38, 0x18, 0xff, 0x05, 0x44, 0x20, 0xff, 0x0b, 0x47, 0x23, 0xff, 0x01, 0x2b, 0x14, 0xff, 0x00, 0x25, 0x15, 0xff, 0x02, 0x24, 0x12, 0xff, 0x00, 0x29, 0x10, 0xff, 0x04, 0x50, 0x26, 0xff, 0x04, 0x5f, 0x2c, 0xff, 0x04, 0x5f, 0x2a, 0xff, 0x08, 0x5b, 0x2d, 0xff, 0x01, 0x36, 0x18, 0xff, 0x00, 0x27, 0x11, 0xff, 0x00, 0x26, 0x13, 0xff, 0x00, 0x26, 0x11, 0xff, 0x02, 0x25, 0x12, 0xff, 0x04, 0x23, 0x13, 0xff, 0x01, 0x25, 0x15, 0xff, 0x00, 0x29, 0x12, 0xff, 0x06, 0x42, 0x20, 0xff, 0x0b, 0x51, 0x29, 0xff, 0x07, 0x58, 0x29, 0xff, 0x05, 0x5d, 0x2b, 0xff, 0x09, 0x4c, 0x29, 0xff, 0x02, 0x26, 0x10, 0xff, 0x03, 0x33, 0x16, 0xff, 0x09, 0x55, 0x2a, 0xff, 0x04, 0x5b, 0x2a, 0xff, 0x07, 0x5b, 0x2e, 0xff, 0x07, 0x43, 0x21, 0xff, 0x02, 0x22, 0x0e, 0xff, 0x07, 0x20, 0x17, 0xff, 0x02, 0x25, 0x15, 0xff, 0x04, 0x39, 0x19, 0xff, 0x0f, 0x50, 0x28, 0xff, 0x08, 0x54, 0x2b, 0xff, 0x03, 0x55, 0x2e, 0xff, 0x08, 0x54, 0x2e, 0xff, 0x0e, 0x4d, 0x2c, 0xff, 0x04, 0x3c, 0x1a, 0xff, 0x0c, 0x4d, 0x25, 0xff, 0x0f, 0x67, 0x32, 0xff, 0x0a, 0x71, 0x34, 0xff, 0x06, 0x75, 0x33, 0xff, 0x06, 0x73, 0x32, 0xff, 0x08, 0x72, 0x2f, 0xff, 0x09, 0x78, 0x33, 0xff, 0x07, 0x7c, 0x32, 0xff, 0x03, 0x7d, 0x32, 0xff, 0x09, 0x88, 0x40, 0xff, 0x20, 0x99, 0x58, 0xff, 0x12, 0x6f, 0x39, 0xff, 0x02, 0x44, 0x18, 0xff, 0x03, 0x2f, 0x12, 0xff, 0x03, 0x30, 0x12, 0xff, 0x08, 0x3e, 0x18, 0xff, 0x08, 0x42, 0x1a, 0xff, 0x07, 0x43, 0x19, 0xff, 0x08, 0x42, 0x1c, 0xff, 0x06, 0x3c, 0x1a, 0xff, 0x06, 0x37, 0x1a, 0xff, 0x07, 0x32, 0x1a, 0xff, 0x06, 0x34, 0x1b, 0xff, 0x08, 0x39, 0x1f, 0xff, 0x06, 0x3b, 0x21, 0xff, 0x02, 0x3c, 0x20, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x05, 0x43, 0x23, 0xff, 0x07, 0x42, 0x23, 0xff, 0x03, 0x3b, 0x1f, 0xff, 0x01, 0x38, 0x1d, 0xff, 0x05, 0x3e, 0x28, 0xff, 0x0f, 0x48, 0x35, 0xff, 0x11, 0x4f, 0x3b, 0xff, 0x0a, 0x53, 0x36, 0xff, 0x12, 0x6f, 0x41, 0xff, 0x0f, 0x76, 0x3f, 0xff, 0x09, 0x65, 0x38, 0xff, 0x03, 0x5e, 0x2d, 0xff, 0x07, 0x64, 0x30, 0xff, 0x0e, 0x6e, 0x39, 0xff, 0x0f, 0x74, 0x42, 0xff, 0x0f, 0x71, 0x43, 0xff, 0x0b, 0x6a, 0x3c, 0xff, 0x04, 0x5e, 0x32, 0xff, 0x03, 0x5a, 0x30, 0xff, 0x02, 0x5b, 0x30, 0xff, 0x01, 0x58, 0x2e, 0xff, 0x03, 0x5a, 0x32, 0xff, 0x0f, 0x5f, 0x38, 0xff, 0x04, 0x4a, 0x23, 0xff, 0x05, 0x45, 0x20, 0xff, 0x09, 0x49, 0x23, 0xff, 0x04, 0x50, 0x28, 0xff, 0x08, 0x51, 0x29, 0xff, 0x04, 0x4c, 0x23, 0xff, 0x13, 0x67, 0x3c, 0xff, 0x13, 0x7e, 0x4c, 0xff, 0x07, 0x81, 0x48, 0xff, 0x07, 0x85, 0x49, 0xff, 0x04, 0x81, 0x44, 0xff, 0x04, 0x78, 0x41, 0xff, 0x0d, 0x7d, 0x49, 0xff, 0x19, 0x7e, 0x4d, 0xff, 0x1f, 0x7e, 0x51, 0xff, 0x19, 0x76, 0x4c, 0xff, 0x0b, 0x65, 0x3c, 0xff, 0x0b, 0x53, 0x30, 0xff, 0x02, 0x3d, 0x1d, 0xff, 0x06, 0x3a, 0x17, 0xff, 0x03, 0x37, 0x16, 0xff, 0x01, 0x31, 0x1d, 0xff, 0x05, 0x3f, 0x22, 0xff, 0x16, 0x64, 0x37, 0xff, 0x1b, 0x6b, 0x49, 0xff, 0x1f, 0x53, 0x55, 0xff, 0x34, 0x46, 0x6f, 0xff, 0x39, 0x4b, 0x5f, 0xff, 0x07, 0x30, 0x20, 0xff, 0x45, 0x4e, 0x6e, 0xff, 0x4a, 0x4e, 0x7e, 0xff, 0x12, 0x26, 0x22, 0xff, 0x10, 0x46, 0x27, 0xff, 0x14, 0x53, 0x3f, 0xff, 0x21, 0x3c, 0x48, 0xff, 0x20, 0x38, 0x44, 0xff, 0x05, 0x49, 0x29, 0xff, 0x1b, 0x6c, 0x3e, 0xff, 0x0f, 0x5c, 0x37, 0xff, 0x10, 0x66, 0x41, 0xff, 0x15, 0x63, 0x46, 0xff, 0x1d, 0x64, 0x4c, 0xff, 0x16, 0x61, 0x47, 0xff, 0x04, 0x68, 0x3f, 0xff, 0x10, 0x90, 0x57, 0xff, 0x16, 0xa1, 0x5a, 0xff, 0x02, 0x85, 0x36, 0xff, 0x0c, 0x8e, 0x3f, 0xff, 0x0c, 0x84, 0x3d, 0xff, 0x03, 0x77, 0x38, 0xff, 0x03, 0x6c, 0x33, 0xff, 0x09, 0x63, 0x35, 0xff, 0x0b, 0x59, 0x32, 0xff, 0x03, 0x3a, 0x19, 0xff, 0x0a, 0x42, 0x23, 0xff, 0x1a, 0x5e, 0x41, 0xff, 0x17, 0x68, 0x48, 0xff, 0x0f, 0x69, 0x47, 0xff, 0x13, 0x6b, 0x4a, 0xff, 0x11, 0x6b, 0x48, 0xff, 0x12, 0x6b, 0x48, 0xff, 0x19, 0x67, 0x47, 0xff, 0x11, 0x56, 0x37, 0xff, 0x01, 0x36, 0x1b, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x04, 0x32, 0x1c, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x05, 0x30, 0x1e, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x06, 0x35, 0x17, 0xff, 0x04, 0x34, 0x19, 0xff, 0x03, 0x32, 0x1d, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x03, 0x3d, 0x15, 0xff, 0x0d, 0x53, 0x24, 0xff, 0x16, 0x60, 0x35, 0xff, 0x0c, 0x53, 0x2b, 0xff, 0x08, 0x4d, 0x27, 0xff, 0x05, 0x4a, 0x24, 0xff, 0x04, 0x4b, 0x25, 0xff, 0x03, 0x4d, 0x25, 0xff, 0x06, 0x4a, 0x22, 0xff, 0x05, 0x47, 0x21, 0xff, 0x03, 0x44, 0x20, 0xff, 0x07, 0x41, 0x20, 0xff, 0x09, 0x39, 0x24, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x12, 0x82, 0x3d, 0xff, 0x07, 0x8e, 0x36, 0xff, 0x0a, 0x87, 0x33, 0xff, 0x08, 0x85, 0x32, 0xff, 0x0f, 0x7c, 0x37, 0xff, 0x0a, 0x5f, 0x2a, 0xff, 0x00, 0x2b, 0x0d, 0xff, 0x02, 0x27, 0x14, 0xff, 0x05, 0x2d, 0x15, 0xff, 0x07, 0x3d, 0x19, 0xff, 0x17, 0x5a, 0x2f, 0xff, 0x0a, 0x43, 0x1e, 0xff, 0x01, 0x29, 0x0f, 0xff, 0x01, 0x2c, 0x11, 0xff, 0x07, 0x43, 0x24, 0xff, 0x07, 0x36, 0x1e, 0xff, 0x03, 0x44, 0x2a, 0xff, 0x0d, 0x7e, 0x4d, 0xff, 0x03, 0x7a, 0x3b, 0xff, 0x06, 0x70, 0x3e, 0xff, 0x04, 0x71, 0x3f, 0xff, 0x03, 0x74, 0x3f, 0xff, 0x06, 0x75, 0x41, 0xff, 0x06, 0x75, 0x3f, 0xff, 0x06, 0x75, 0x3f, 0xff, 0x05, 0x75, 0x3f, 0xff, 0x02, 0x74, 0x3e, 0xff, 0x06, 0x74, 0x3f, 0xff, 0x0d, 0x6a, 0x3b, 0xff, 0x03, 0x41, 0x1d, 0xff, 0x05, 0x2b, 0x15, 0xff, 0x03, 0x2d, 0x18, 0xff, 0x06, 0x4a, 0x2e, 0xff, 0x07, 0x55, 0x30, 0xff, 0x05, 0x56, 0x2c, 0xff, 0x0e, 0x68, 0x3f, 0xff, 0x03, 0x35, 0x16, 0xff, 0x03, 0x23, 0x0f, 0xff, 0x04, 0x1e, 0x0f, 0xff, 0x00, 0x2c, 0x16, 0xff, 0x0b, 0x50, 0x2c, 0xff, 0x12, 0x6b, 0x3b, 0xff, 0x09, 0x7b, 0x44, 0xff, 0x03, 0x44, 0x20, 0xff, 0x02, 0x44, 0x25, 0xff, 0x07, 0x49, 0x2c, 0xff, 0x0e, 0x40, 0x27, 0xff, 0x02, 0x27, 0x11, 0xff, 0x01, 0x25, 0x0f, 0xff, 0x0b, 0x39, 0x22, 0xff, 0x08, 0x3a, 0x22, 0xff, 0x01, 0x23, 0x0e, 0xff, 0x05, 0x2a, 0x16, 0xff, 0x12, 0x41, 0x2b, 0xff, 0x01, 0x29, 0x12, 0xff, 0x03, 0x2c, 0x15, 0xff, 0x0c, 0x45, 0x29, 0xff, 0x04, 0x41, 0x25, 0xff, 0x02, 0x34, 0x17, 0xff, 0x06, 0x47, 0x22, 0xff, 0x0c, 0x61, 0x36, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x0a, 0x63, 0x38, 0xff, 0x08, 0x5c, 0x34, 0xff, 0x08, 0x55, 0x2c, 0xff, 0x09, 0x69, 0x38, 0xff, 0x08, 0x6f, 0x39, 0xff, 0x07, 0x72, 0x3a, 0xff, 0x06, 0x72, 0x37, 0xff, 0x05, 0x74, 0x37, 0xff, 0x05, 0x70, 0x3a, 0xff, 0x04, 0x56, 0x2e, 0xff, 0x02, 0x2a, 0x16, 0xff, 0x06, 0x1f, 0x12, 0xff, 0x01, 0x20, 0x10, 0xff, 0x00, 0x27, 0x11, 0xff, 0x08, 0x36, 0x1f, 0xff, 0x05, 0x34, 0x1e, 0xff, 0x04, 0x2d, 0x17, 0xff, 0x00, 0x21, 0x0b, 0xff, 0x07, 0x41, 0x21, 0xff, 0x0b, 0x60, 0x36, 0xff, 0x06, 0x5d, 0x2e, 0xff, 0x05, 0x5c, 0x2e, 0xff, 0x04, 0x5d, 0x2f, 0xff, 0x06, 0x5b, 0x2e, 0xff, 0x0a, 0x59, 0x2e, 0xff, 0x0b, 0x54, 0x2d, 0xff, 0x04, 0x3d, 0x1e, 0xff, 0x00, 0x29, 0x10, 0xff, 0x0a, 0x36, 0x23, 0xff, 0x03, 0x27, 0x14, 0xff, 0x02, 0x25, 0x14, 0xff, 0x0a, 0x37, 0x25, 0xff, 0x0a, 0x3e, 0x27, 0xff, 0x02, 0x39, 0x1f, 0xff, 0x06, 0x49, 0x27, 0xff, 0x10, 0x60, 0x36, 0xff, 0x0c, 0x68, 0x37, 0xff, 0x0a, 0x68, 0x39, 0xff, 0x09, 0x68, 0x39, 0xff, 0x0a, 0x68, 0x39, 0xff, 0x0c, 0x63, 0x37, 0xff, 0x0e, 0x5b, 0x34, 0xff, 0x0e, 0x49, 0x2b, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x06, 0x25, 0x16, 0xff, 0x04, 0x23, 0x18, 0xff, 0x01, 0x27, 0x13, 0xff, 0x01, 0x26, 0x17, 0xff, 0x04, 0x1e, 0x31, 0xff, 0x2a, 0x47, 0xa0, 0xff, 0x31, 0x4b, 0xdc, 0xff, 0x2a, 0x44, 0xd8, 0xff, 0x28, 0x48, 0xd9, 0xff, 0x27, 0x49, 0xd8, 0xff, 0x26, 0x48, 0xd6, 0xff, 0x24, 0x46, 0xd6, 0xff, 0x21, 0x42, 0xd5, 0xff, 0x20, 0x40, 0xd6, 0xff, 0x1f, 0x3d, 0xd5, 0xff, 0x1f, 0x3c, 0xd2, 0xff, 0x1e, 0x3b, 0xcb, 0xff, 0x1d, 0x3a, 0xc7, 0xff, 0x15, 0x32, 0xba, 0xff, 0x12, 0x2f, 0xae, 0xff, 0x1a, 0x3b, 0x91, 0xff, 0x09, 0x36, 0x47, 0xff, 0x11, 0x48, 0x2d, 0xff, 0x13, 0x4e, 0x2f, 0xff, 0x19, 0x63, 0x3a, 0xff, 0x1a, 0x65, 0x3b, 0xff, 0x0f, 0x5a, 0x34, 0xff, 0x09, 0x5d, 0x38, 0xff, 0x05, 0x54, 0x33, 0xff, 0x19, 0x5f, 0x3f, 0xff, 0x13, 0x4a, 0x30, 0xff, 0x01, 0x25, 0x12, 0xff, 0x62, 0x71, 0x6a, 0xff, + 0x08, 0x42, 0x20, 0xff, 0x0a, 0x4b, 0x28, 0xff, 0x01, 0x38, 0x18, 0xff, 0x06, 0x47, 0x23, 0xff, 0x0c, 0x4a, 0x25, 0xff, 0x02, 0x2c, 0x14, 0xff, 0x00, 0x25, 0x14, 0xff, 0x02, 0x24, 0x12, 0xff, 0x01, 0x2a, 0x10, 0xff, 0x05, 0x50, 0x27, 0xff, 0x05, 0x5f, 0x2c, 0xff, 0x05, 0x60, 0x2b, 0xff, 0x08, 0x5d, 0x2e, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x00, 0x28, 0x12, 0xff, 0x00, 0x26, 0x13, 0xff, 0x00, 0x26, 0x11, 0xff, 0x02, 0x25, 0x12, 0xff, 0x03, 0x24, 0x13, 0xff, 0x01, 0x26, 0x15, 0xff, 0x00, 0x2a, 0x12, 0xff, 0x0a, 0x47, 0x25, 0xff, 0x0a, 0x52, 0x29, 0xff, 0x07, 0x59, 0x29, 0xff, 0x06, 0x5d, 0x2b, 0xff, 0x06, 0x48, 0x26, 0xff, 0x01, 0x24, 0x0e, 0xff, 0x03, 0x33, 0x16, 0xff, 0x08, 0x55, 0x2a, 0xff, 0x05, 0x5c, 0x2a, 0xff, 0x08, 0x5a, 0x2f, 0xff, 0x04, 0x3c, 0x1d, 0xff, 0x02, 0x21, 0x0d, 0xff, 0x07, 0x22, 0x15, 0xff, 0x01, 0x27, 0x13, 0xff, 0x0a, 0x43, 0x21, 0xff, 0x12, 0x54, 0x2c, 0xff, 0x09, 0x54, 0x2c, 0xff, 0x06, 0x54, 0x2e, 0xff, 0x07, 0x50, 0x28, 0xff, 0x05, 0x49, 0x24, 0xff, 0x0a, 0x4e, 0x28, 0xff, 0x13, 0x61, 0x34, 0xff, 0x0d, 0x6e, 0x36, 0xff, 0x07, 0x70, 0x31, 0xff, 0x08, 0x74, 0x32, 0xff, 0x07, 0x70, 0x2f, 0xff, 0x08, 0x73, 0x31, 0xff, 0x07, 0x7a, 0x34, 0xff, 0x04, 0x7d, 0x32, 0xff, 0x04, 0x84, 0x37, 0xff, 0x19, 0x9f, 0x56, 0xff, 0x16, 0x7f, 0x45, 0xff, 0x02, 0x40, 0x16, 0xff, 0x01, 0x32, 0x11, 0xff, 0x06, 0x2f, 0x12, 0xff, 0x09, 0x39, 0x19, 0xff, 0x04, 0x43, 0x1b, 0xff, 0x01, 0x46, 0x1b, 0xff, 0x01, 0x43, 0x19, 0xff, 0x02, 0x3e, 0x19, 0xff, 0x04, 0x37, 0x18, 0xff, 0x0b, 0x35, 0x1a, 0xff, 0x09, 0x35, 0x1a, 0xff, 0x07, 0x3b, 0x1c, 0xff, 0x09, 0x41, 0x23, 0xff, 0x08, 0x3d, 0x26, 0xff, 0x05, 0x3f, 0x27, 0xff, 0x03, 0x41, 0x22, 0xff, 0x03, 0x40, 0x21, 0xff, 0x04, 0x3b, 0x21, 0xff, 0x04, 0x3a, 0x27, 0xff, 0x05, 0x3f, 0x2b, 0xff, 0x0a, 0x49, 0x33, 0xff, 0x0d, 0x4f, 0x39, 0xff, 0x09, 0x4f, 0x39, 0xff, 0x0c, 0x5a, 0x3d, 0xff, 0x16, 0x73, 0x4a, 0xff, 0x09, 0x6c, 0x3c, 0xff, 0x02, 0x5b, 0x2e, 0xff, 0x07, 0x62, 0x31, 0xff, 0x0b, 0x69, 0x34, 0xff, 0x0c, 0x6e, 0x38, 0xff, 0x08, 0x6d, 0x3a, 0xff, 0x05, 0x66, 0x37, 0xff, 0x13, 0x78, 0x49, 0xff, 0x0e, 0x6f, 0x41, 0xff, 0x00, 0x59, 0x2e, 0xff, 0x02, 0x5d, 0x32, 0xff, 0x05, 0x5b, 0x33, 0xff, 0x0a, 0x59, 0x32, 0xff, 0x13, 0x5c, 0x35, 0xff, 0x02, 0x48, 0x20, 0xff, 0x0c, 0x56, 0x2d, 0xff, 0x05, 0x52, 0x28, 0xff, 0x08, 0x59, 0x2d, 0xff, 0x0a, 0x55, 0x2b, 0xff, 0x01, 0x4a, 0x20, 0xff, 0x05, 0x51, 0x26, 0xff, 0x1c, 0x7e, 0x4e, 0xff, 0x1b, 0x8a, 0x55, 0xff, 0x05, 0x7a, 0x41, 0xff, 0x03, 0x74, 0x3b, 0xff, 0x0f, 0x7c, 0x49, 0xff, 0x29, 0x93, 0x63, 0xff, 0x26, 0x84, 0x57, 0xff, 0x26, 0x83, 0x57, 0xff, 0x2a, 0x8b, 0x62, 0xff, 0x1e, 0x7d, 0x55, 0xff, 0x0e, 0x59, 0x37, 0xff, 0x05, 0x3f, 0x20, 0xff, 0x01, 0x35, 0x19, 0xff, 0x01, 0x32, 0x18, 0xff, 0x03, 0x3d, 0x1f, 0xff, 0x0d, 0x5f, 0x32, 0xff, 0x14, 0x71, 0x3d, 0xff, 0x13, 0x54, 0x3c, 0xff, 0x46, 0x53, 0x7d, 0xff, 0x54, 0x44, 0x9f, 0xff, 0x30, 0x37, 0x61, 0xff, 0x02, 0x24, 0x1e, 0xff, 0x31, 0x3f, 0x4f, 0xff, 0x2b, 0x45, 0x50, 0xff, 0x0a, 0x2d, 0x18, 0xff, 0x0c, 0x62, 0x34, 0xff, 0x10, 0x7b, 0x40, 0xff, 0x0e, 0x47, 0x2b, 0xff, 0x06, 0x32, 0x24, 0xff, 0x0b, 0x5e, 0x30, 0xff, 0x23, 0x74, 0x4a, 0xff, 0x0c, 0x50, 0x36, 0xff, 0x0f, 0x62, 0x40, 0xff, 0x13, 0x66, 0x45, 0xff, 0x19, 0x62, 0x4e, 0xff, 0x14, 0x5d, 0x4c, 0xff, 0x06, 0x72, 0x47, 0xff, 0x1f, 0xac, 0x6b, 0xff, 0x08, 0x8f, 0x44, 0xff, 0x06, 0x85, 0x37, 0xff, 0x0b, 0x90, 0x43, 0xff, 0x06, 0x80, 0x3b, 0xff, 0x02, 0x6d, 0x34, 0xff, 0x07, 0x67, 0x34, 0xff, 0x0b, 0x5c, 0x31, 0xff, 0x02, 0x40, 0x1b, 0xff, 0x08, 0x45, 0x24, 0xff, 0x1b, 0x60, 0x40, 0xff, 0x1c, 0x69, 0x4a, 0xff, 0x14, 0x6a, 0x48, 0xff, 0x12, 0x6c, 0x49, 0xff, 0x13, 0x6b, 0x49, 0xff, 0x12, 0x6a, 0x48, 0xff, 0x14, 0x6a, 0x48, 0xff, 0x17, 0x63, 0x43, 0xff, 0x07, 0x45, 0x27, 0xff, 0x01, 0x34, 0x19, 0xff, 0x03, 0x34, 0x1b, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x01, 0x33, 0x1c, 0xff, 0x02, 0x33, 0x1c, 0xff, 0x08, 0x32, 0x1b, 0xff, 0x07, 0x33, 0x19, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x05, 0x34, 0x1a, 0xff, 0x01, 0x3a, 0x15, 0xff, 0x10, 0x62, 0x30, 0xff, 0x28, 0x84, 0x51, 0xff, 0x13, 0x67, 0x38, 0xff, 0x03, 0x51, 0x25, 0xff, 0x04, 0x50, 0x26, 0xff, 0x07, 0x51, 0x28, 0xff, 0x06, 0x51, 0x28, 0xff, 0x04, 0x4f, 0x26, 0xff, 0x07, 0x4e, 0x25, 0xff, 0x05, 0x4b, 0x23, 0xff, 0x03, 0x49, 0x23, 0xff, 0x07, 0x44, 0x22, 0xff, 0x09, 0x3e, 0x26, 0xff, 0x05, 0x42, 0x21, 0xff, 0x12, 0x8a, 0x41, 0xff, 0x05, 0x8d, 0x34, 0xff, 0x06, 0x86, 0x32, 0xff, 0x07, 0x85, 0x35, 0xff, 0x10, 0x70, 0x33, 0xff, 0x05, 0x43, 0x17, 0xff, 0x02, 0x2c, 0x12, 0xff, 0x03, 0x2e, 0x18, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x15, 0x54, 0x30, 0xff, 0x0d, 0x4c, 0x24, 0xff, 0x01, 0x2f, 0x0d, 0xff, 0x00, 0x29, 0x0f, 0xff, 0x03, 0x35, 0x18, 0xff, 0x0e, 0x4f, 0x2e, 0xff, 0x02, 0x32, 0x17, 0xff, 0x01, 0x42, 0x26, 0xff, 0x0d, 0x7d, 0x4b, 0xff, 0x03, 0x7c, 0x3d, 0xff, 0x06, 0x71, 0x3e, 0xff, 0x03, 0x70, 0x3e, 0xff, 0x03, 0x71, 0x3e, 0xff, 0x06, 0x74, 0x40, 0xff, 0x06, 0x75, 0x3f, 0xff, 0x06, 0x75, 0x3f, 0xff, 0x05, 0x75, 0x3f, 0xff, 0x02, 0x74, 0x3e, 0xff, 0x07, 0x74, 0x3f, 0xff, 0x0d, 0x6d, 0x3e, 0xff, 0x07, 0x4c, 0x27, 0xff, 0x04, 0x2c, 0x15, 0xff, 0x04, 0x2c, 0x18, 0xff, 0x06, 0x45, 0x2b, 0xff, 0x07, 0x53, 0x30, 0xff, 0x02, 0x55, 0x2a, 0xff, 0x0d, 0x66, 0x3d, 0xff, 0x05, 0x3c, 0x1e, 0xff, 0x03, 0x22, 0x0e, 0xff, 0x04, 0x1e, 0x0f, 0xff, 0x00, 0x2b, 0x16, 0xff, 0x0a, 0x4c, 0x2a, 0xff, 0x10, 0x68, 0x3a, 0xff, 0x0b, 0x7d, 0x47, 0xff, 0x0a, 0x55, 0x2e, 0xff, 0x02, 0x3e, 0x1e, 0xff, 0x0a, 0x49, 0x2a, 0xff, 0x0e, 0x48, 0x2c, 0xff, 0x05, 0x33, 0x1b, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x05, 0x2d, 0x16, 0xff, 0x0d, 0x3e, 0x26, 0xff, 0x01, 0x26, 0x12, 0xff, 0x02, 0x27, 0x13, 0xff, 0x10, 0x3f, 0x29, 0xff, 0x03, 0x2b, 0x14, 0xff, 0x03, 0x2b, 0x14, 0xff, 0x0b, 0x44, 0x29, 0xff, 0x05, 0x43, 0x26, 0xff, 0x04, 0x34, 0x19, 0xff, 0x05, 0x43, 0x1f, 0xff, 0x0c, 0x61, 0x35, 0xff, 0x0c, 0x61, 0x35, 0xff, 0x0a, 0x63, 0x37, 0xff, 0x0b, 0x5f, 0x37, 0xff, 0x03, 0x51, 0x28, 0xff, 0x09, 0x67, 0x38, 0xff, 0x06, 0x6d, 0x37, 0xff, 0x06, 0x71, 0x3a, 0xff, 0x07, 0x71, 0x38, 0xff, 0x05, 0x73, 0x36, 0xff, 0x07, 0x73, 0x3a, 0xff, 0x0a, 0x63, 0x37, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x03, 0x22, 0x12, 0xff, 0x02, 0x20, 0x10, 0xff, 0x00, 0x25, 0x10, 0xff, 0x09, 0x36, 0x20, 0xff, 0x04, 0x34, 0x1e, 0xff, 0x03, 0x2c, 0x17, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x06, 0x3f, 0x1f, 0xff, 0x0b, 0x5f, 0x36, 0xff, 0x06, 0x5d, 0x2f, 0xff, 0x05, 0x5b, 0x2e, 0xff, 0x06, 0x5c, 0x2f, 0xff, 0x06, 0x5b, 0x2e, 0xff, 0x07, 0x56, 0x2b, 0xff, 0x07, 0x50, 0x2a, 0xff, 0x06, 0x40, 0x22, 0xff, 0x01, 0x2a, 0x12, 0xff, 0x09, 0x30, 0x1e, 0xff, 0x04, 0x26, 0x13, 0xff, 0x02, 0x27, 0x15, 0xff, 0x0a, 0x38, 0x25, 0xff, 0x06, 0x3e, 0x27, 0xff, 0x01, 0x3a, 0x1f, 0xff, 0x0b, 0x4f, 0x2e, 0xff, 0x12, 0x63, 0x3b, 0xff, 0x09, 0x66, 0x38, 0xff, 0x0d, 0x68, 0x3a, 0xff, 0x0d, 0x66, 0x39, 0xff, 0x0f, 0x67, 0x3a, 0xff, 0x0e, 0x61, 0x35, 0xff, 0x11, 0x5b, 0x33, 0xff, 0x09, 0x41, 0x21, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x05, 0x25, 0x14, 0xff, 0x04, 0x25, 0x14, 0xff, 0x03, 0x28, 0x11, 0xff, 0x02, 0x23, 0x18, 0xff, 0x00, 0x1a, 0x27, 0xff, 0x21, 0x3e, 0x94, 0xff, 0x31, 0x4c, 0xdf, 0xff, 0x26, 0x45, 0xda, 0xff, 0x25, 0x49, 0xd6, 0xff, 0x28, 0x4b, 0xd6, 0xff, 0x27, 0x49, 0xd5, 0xff, 0x26, 0x48, 0xd6, 0xff, 0x22, 0x45, 0xd5, 0xff, 0x1f, 0x40, 0xd4, 0xff, 0x1d, 0x3e, 0xd3, 0xff, 0x1d, 0x3d, 0xd2, 0xff, 0x1b, 0x3d, 0xcc, 0xff, 0x1c, 0x3c, 0xc5, 0xff, 0x14, 0x30, 0xb5, 0xff, 0x1a, 0x32, 0xb1, 0xff, 0x19, 0x3b, 0x86, 0xff, 0x06, 0x39, 0x3e, 0xff, 0x0f, 0x4b, 0x2e, 0xff, 0x1c, 0x5c, 0x3f, 0xff, 0x1e, 0x6b, 0x41, 0xff, 0x12, 0x5f, 0x32, 0xff, 0x10, 0x5e, 0x36, 0xff, 0x0a, 0x5d, 0x38, 0xff, 0x0a, 0x54, 0x34, 0xff, 0x24, 0x64, 0x47, 0xff, 0x08, 0x38, 0x1f, 0xff, 0x01, 0x22, 0x11, 0xff, 0x63, 0x72, 0x6a, 0xff, + 0x09, 0x43, 0x20, 0xff, 0x08, 0x48, 0x25, 0xff, 0x01, 0x36, 0x17, 0xff, 0x08, 0x4a, 0x27, 0xff, 0x0d, 0x4c, 0x27, 0xff, 0x02, 0x2b, 0x13, 0xff, 0x00, 0x24, 0x13, 0xff, 0x02, 0x25, 0x12, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x05, 0x51, 0x28, 0xff, 0x05, 0x5f, 0x2c, 0xff, 0x03, 0x5f, 0x29, 0xff, 0x08, 0x5d, 0x2f, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x00, 0x29, 0x12, 0xff, 0x00, 0x27, 0x14, 0xff, 0x00, 0x26, 0x11, 0xff, 0x02, 0x25, 0x12, 0xff, 0x03, 0x25, 0x14, 0xff, 0x01, 0x25, 0x14, 0xff, 0x01, 0x2d, 0x16, 0xff, 0x0c, 0x4d, 0x29, 0xff, 0x08, 0x52, 0x28, 0xff, 0x08, 0x5b, 0x2b, 0xff, 0x07, 0x5e, 0x2e, 0xff, 0x04, 0x45, 0x22, 0xff, 0x00, 0x24, 0x0d, 0xff, 0x02, 0x34, 0x17, 0xff, 0x07, 0x56, 0x2a, 0xff, 0x05, 0x5c, 0x2c, 0xff, 0x0a, 0x58, 0x2f, 0xff, 0x03, 0x32, 0x18, 0xff, 0x03, 0x22, 0x0f, 0xff, 0x04, 0x24, 0x13, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x0f, 0x4e, 0x28, 0xff, 0x11, 0x54, 0x2a, 0xff, 0x0b, 0x54, 0x2d, 0xff, 0x05, 0x50, 0x29, 0xff, 0x04, 0x4c, 0x20, 0xff, 0x09, 0x55, 0x2b, 0xff, 0x0d, 0x65, 0x37, 0xff, 0x08, 0x67, 0x35, 0xff, 0x06, 0x6e, 0x32, 0xff, 0x08, 0x71, 0x31, 0xff, 0x09, 0x71, 0x31, 0xff, 0x08, 0x72, 0x32, 0xff, 0x05, 0x76, 0x34, 0xff, 0x06, 0x79, 0x34, 0xff, 0x06, 0x84, 0x3a, 0xff, 0x15, 0x99, 0x50, 0xff, 0x0c, 0x71, 0x34, 0xff, 0x01, 0x3d, 0x10, 0xff, 0x04, 0x35, 0x17, 0xff, 0x01, 0x33, 0x19, 0xff, 0x07, 0x3e, 0x1a, 0xff, 0x0a, 0x45, 0x20, 0xff, 0x04, 0x45, 0x1c, 0xff, 0x01, 0x45, 0x1b, 0xff, 0x01, 0x42, 0x1a, 0xff, 0x01, 0x39, 0x18, 0xff, 0x03, 0x35, 0x19, 0xff, 0x06, 0x34, 0x1c, 0xff, 0x0a, 0x3c, 0x25, 0xff, 0x0b, 0x47, 0x29, 0xff, 0x07, 0x42, 0x24, 0xff, 0x07, 0x3d, 0x26, 0xff, 0x0f, 0x48, 0x32, 0xff, 0x0e, 0x51, 0x34, 0xff, 0x0c, 0x4e, 0x36, 0xff, 0x11, 0x4c, 0x3a, 0xff, 0x11, 0x4a, 0x3c, 0xff, 0x10, 0x4e, 0x3c, 0xff, 0x0c, 0x51, 0x3a, 0xff, 0x08, 0x50, 0x37, 0xff, 0x08, 0x50, 0x37, 0xff, 0x0a, 0x57, 0x3a, 0xff, 0x05, 0x54, 0x32, 0xff, 0x05, 0x5b, 0x34, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x0a, 0x63, 0x31, 0xff, 0x02, 0x60, 0x29, 0xff, 0x0e, 0x72, 0x3b, 0xff, 0x02, 0x67, 0x34, 0xff, 0x01, 0x67, 0x38, 0xff, 0x03, 0x65, 0x38, 0xff, 0x13, 0x78, 0x4c, 0xff, 0x08, 0x66, 0x3c, 0xff, 0x03, 0x5c, 0x34, 0xff, 0x13, 0x64, 0x3b, 0xff, 0x26, 0x6d, 0x45, 0xff, 0x16, 0x59, 0x31, 0xff, 0x06, 0x4e, 0x24, 0xff, 0x13, 0x6a, 0x3e, 0xff, 0x08, 0x69, 0x3b, 0xff, 0x10, 0x6e, 0x3e, 0xff, 0x08, 0x5e, 0x30, 0xff, 0x03, 0x4f, 0x23, 0xff, 0x00, 0x49, 0x1e, 0xff, 0x06, 0x53, 0x27, 0xff, 0x21, 0x81, 0x52, 0xff, 0x28, 0x8e, 0x5c, 0xff, 0x2c, 0x91, 0x5f, 0xff, 0x37, 0x94, 0x68, 0xff, 0x1b, 0x67, 0x3f, 0xff, 0x04, 0x44, 0x20, 0xff, 0x02, 0x43, 0x1f, 0xff, 0x05, 0x4b, 0x28, 0xff, 0x0c, 0x5b, 0x38, 0xff, 0x03, 0x40, 0x22, 0xff, 0x0a, 0x36, 0x1b, 0xff, 0x01, 0x30, 0x1b, 0xff, 0x02, 0x39, 0x23, 0xff, 0x0f, 0x5e, 0x34, 0xff, 0x10, 0x7c, 0x40, 0xff, 0x0b, 0x75, 0x39, 0xff, 0x1e, 0x5a, 0x43, 0xff, 0x5d, 0x55, 0x93, 0xff, 0x62, 0x41, 0xb1, 0xff, 0x23, 0x2a, 0x53, 0xff, 0x15, 0x28, 0x36, 0xff, 0x22, 0x2a, 0x40, 0xff, 0x18, 0x48, 0x30, 0xff, 0x06, 0x3e, 0x18, 0xff, 0x12, 0x83, 0x57, 0xff, 0x0e, 0x8b, 0x52, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x09, 0x46, 0x26, 0xff, 0x27, 0x89, 0x51, 0xff, 0x17, 0x62, 0x44, 0xff, 0x1a, 0x4f, 0x49, 0xff, 0x0e, 0x5f, 0x3f, 0xff, 0x0b, 0x65, 0x3d, 0xff, 0x10, 0x5f, 0x47, 0xff, 0x13, 0x64, 0x4f, 0xff, 0x10, 0x90, 0x5b, 0xff, 0x1e, 0xae, 0x65, 0xff, 0x04, 0x84, 0x36, 0xff, 0x0b, 0x8c, 0x3d, 0xff, 0x07, 0x85, 0x3d, 0xff, 0x01, 0x70, 0x32, 0xff, 0x08, 0x67, 0x35, 0xff, 0x0d, 0x5e, 0x33, 0xff, 0x02, 0x40, 0x1b, 0xff, 0x08, 0x49, 0x27, 0xff, 0x19, 0x67, 0x44, 0xff, 0x18, 0x6c, 0x4a, 0xff, 0x10, 0x6b, 0x48, 0xff, 0x0f, 0x6b, 0x48, 0xff, 0x11, 0x6c, 0x48, 0xff, 0x13, 0x6b, 0x47, 0xff, 0x16, 0x6c, 0x49, 0xff, 0x1c, 0x6c, 0x4b, 0xff, 0x09, 0x4a, 0x2c, 0xff, 0x01, 0x34, 0x19, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x01, 0x33, 0x1c, 0xff, 0x02, 0x32, 0x1e, 0xff, 0x05, 0x32, 0x1d, 0xff, 0x07, 0x34, 0x17, 0xff, 0x06, 0x34, 0x19, 0xff, 0x01, 0x33, 0x1d, 0xff, 0x02, 0x35, 0x1d, 0xff, 0x03, 0x3d, 0x15, 0xff, 0x11, 0x6f, 0x37, 0xff, 0x26, 0x9c, 0x5e, 0xff, 0x0e, 0x76, 0x3e, 0xff, 0x02, 0x62, 0x2c, 0xff, 0x02, 0x60, 0x2d, 0xff, 0x07, 0x5e, 0x2f, 0xff, 0x09, 0x5b, 0x2e, 0xff, 0x09, 0x59, 0x2e, 0xff, 0x08, 0x57, 0x2c, 0xff, 0x09, 0x55, 0x2a, 0xff, 0x04, 0x52, 0x27, 0xff, 0x03, 0x4f, 0x26, 0xff, 0x07, 0x4b, 0x24, 0xff, 0x05, 0x43, 0x25, 0xff, 0x02, 0x46, 0x1e, 0xff, 0x0d, 0x8d, 0x3d, 0xff, 0x03, 0x8c, 0x30, 0xff, 0x06, 0x85, 0x33, 0xff, 0x0b, 0x81, 0x39, 0xff, 0x08, 0x51, 0x21, 0xff, 0x05, 0x30, 0x11, 0xff, 0x0a, 0x30, 0x19, 0xff, 0x02, 0x32, 0x17, 0xff, 0x09, 0x48, 0x26, 0xff, 0x11, 0x54, 0x31, 0xff, 0x01, 0x33, 0x14, 0xff, 0x03, 0x2f, 0x14, 0xff, 0x02, 0x33, 0x17, 0xff, 0x10, 0x50, 0x2e, 0xff, 0x06, 0x44, 0x1f, 0xff, 0x03, 0x34, 0x15, 0xff, 0x02, 0x42, 0x21, 0xff, 0x0c, 0x74, 0x44, 0xff, 0x03, 0x7f, 0x41, 0xff, 0x05, 0x71, 0x3d, 0xff, 0x04, 0x6f, 0x3c, 0xff, 0x04, 0x71, 0x3d, 0xff, 0x08, 0x74, 0x41, 0xff, 0x07, 0x76, 0x41, 0xff, 0x07, 0x76, 0x40, 0xff, 0x05, 0x75, 0x3f, 0xff, 0x02, 0x73, 0x3d, 0xff, 0x06, 0x74, 0x3e, 0xff, 0x0b, 0x70, 0x40, 0xff, 0x0b, 0x5a, 0x32, 0xff, 0x02, 0x2e, 0x13, 0xff, 0x05, 0x2d, 0x18, 0xff, 0x08, 0x40, 0x24, 0xff, 0x09, 0x51, 0x2f, 0xff, 0x01, 0x54, 0x2a, 0xff, 0x0a, 0x60, 0x37, 0xff, 0x08, 0x47, 0x28, 0xff, 0x02, 0x22, 0x0d, 0xff, 0x03, 0x1f, 0x10, 0xff, 0x01, 0x2b, 0x16, 0xff, 0x09, 0x48, 0x28, 0xff, 0x10, 0x67, 0x39, 0xff, 0x07, 0x76, 0x40, 0xff, 0x10, 0x6c, 0x41, 0xff, 0x02, 0x3a, 0x17, 0xff, 0x0d, 0x44, 0x26, 0xff, 0x07, 0x49, 0x2c, 0xff, 0x06, 0x45, 0x2a, 0xff, 0x01, 0x25, 0x10, 0xff, 0x01, 0x22, 0x0e, 0xff, 0x0b, 0x3a, 0x24, 0xff, 0x07, 0x2e, 0x1a, 0xff, 0x01, 0x25, 0x11, 0xff, 0x0b, 0x3b, 0x25, 0xff, 0x05, 0x2f, 0x17, 0xff, 0x02, 0x29, 0x13, 0xff, 0x0a, 0x43, 0x27, 0xff, 0x06, 0x44, 0x27, 0xff, 0x04, 0x35, 0x19, 0xff, 0x03, 0x3f, 0x1e, 0xff, 0x0d, 0x5f, 0x35, 0xff, 0x0c, 0x61, 0x35, 0xff, 0x09, 0x62, 0x36, 0xff, 0x0e, 0x62, 0x38, 0xff, 0x04, 0x50, 0x27, 0xff, 0x08, 0x62, 0x34, 0xff, 0x08, 0x6c, 0x39, 0xff, 0x04, 0x6f, 0x3a, 0xff, 0x09, 0x71, 0x39, 0xff, 0x09, 0x73, 0x36, 0xff, 0x06, 0x73, 0x36, 0xff, 0x0b, 0x6e, 0x3b, 0xff, 0x03, 0x45, 0x24, 0xff, 0x00, 0x28, 0x12, 0xff, 0x02, 0x20, 0x10, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x08, 0x34, 0x1e, 0xff, 0x05, 0x34, 0x20, 0xff, 0x03, 0x2c, 0x18, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x06, 0x3f, 0x1f, 0xff, 0x0c, 0x5f, 0x37, 0xff, 0x07, 0x5c, 0x2f, 0xff, 0x08, 0x59, 0x2d, 0xff, 0x09, 0x5b, 0x30, 0xff, 0x08, 0x5b, 0x30, 0xff, 0x04, 0x54, 0x29, 0xff, 0x02, 0x4c, 0x26, 0xff, 0x08, 0x43, 0x25, 0xff, 0x02, 0x2c, 0x14, 0xff, 0x07, 0x2a, 0x19, 0xff, 0x03, 0x23, 0x10, 0xff, 0x03, 0x2b, 0x19, 0xff, 0x0c, 0x3b, 0x28, 0xff, 0x05, 0x3c, 0x24, 0xff, 0x01, 0x3a, 0x1f, 0xff, 0x0f, 0x58, 0x36, 0xff, 0x0d, 0x65, 0x3c, 0xff, 0x04, 0x67, 0x39, 0xff, 0x07, 0x68, 0x38, 0xff, 0x06, 0x66, 0x35, 0xff, 0x05, 0x67, 0x36, 0xff, 0x03, 0x62, 0x32, 0xff, 0x06, 0x5f, 0x32, 0xff, 0x03, 0x48, 0x20, 0xff, 0x01, 0x37, 0x14, 0xff, 0x02, 0x35, 0x18, 0xff, 0x02, 0x34, 0x17, 0xff, 0x02, 0x38, 0x16, 0xff, 0x05, 0x38, 0x1b, 0xff, 0x08, 0x39, 0x3e, 0xff, 0x3c, 0x5b, 0xb1, 0xff, 0x33, 0x4b, 0xdf, 0xff, 0x25, 0x47, 0xd5, 0xff, 0x27, 0x47, 0xd7, 0xff, 0x26, 0x43, 0xd7, 0xff, 0x27, 0x46, 0xd7, 0xff, 0x24, 0x45, 0xd5, 0xff, 0x1f, 0x41, 0xd3, 0xff, 0x1d, 0x3f, 0xd4, 0xff, 0x1c, 0x3f, 0xd5, 0xff, 0x1c, 0x3f, 0xd2, 0xff, 0x16, 0x3a, 0xc8, 0xff, 0x16, 0x37, 0xbc, 0xff, 0x1f, 0x39, 0xb5, 0xff, 0x22, 0x35, 0xac, 0xff, 0x04, 0x1f, 0x58, 0xff, 0x06, 0x3e, 0x31, 0xff, 0x0a, 0x50, 0x2e, 0xff, 0x0c, 0x54, 0x37, 0xff, 0x1a, 0x67, 0x40, 0xff, 0x0e, 0x5c, 0x2f, 0xff, 0x13, 0x63, 0x3b, 0xff, 0x0c, 0x5c, 0x38, 0xff, 0x15, 0x57, 0x39, 0xff, 0x19, 0x4f, 0x34, 0xff, 0x01, 0x29, 0x12, 0xff, 0x02, 0x22, 0x11, 0xff, 0x64, 0x71, 0x69, 0xff, + 0x09, 0x43, 0x21, 0xff, 0x08, 0x46, 0x23, 0xff, 0x01, 0x36, 0x17, 0xff, 0x09, 0x4d, 0x28, 0xff, 0x0b, 0x4d, 0x27, 0xff, 0x01, 0x2b, 0x13, 0xff, 0x00, 0x25, 0x13, 0xff, 0x02, 0x24, 0x11, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x06, 0x52, 0x29, 0xff, 0x05, 0x5f, 0x2c, 0xff, 0x02, 0x5e, 0x28, 0xff, 0x06, 0x5d, 0x2d, 0xff, 0x03, 0x41, 0x20, 0xff, 0x00, 0x2b, 0x12, 0xff, 0x00, 0x26, 0x14, 0xff, 0x00, 0x27, 0x12, 0xff, 0x02, 0x25, 0x13, 0xff, 0x03, 0x25, 0x15, 0xff, 0x01, 0x25, 0x13, 0xff, 0x02, 0x31, 0x19, 0xff, 0x0c, 0x4e, 0x29, 0xff, 0x06, 0x52, 0x28, 0xff, 0x07, 0x5c, 0x2c, 0xff, 0x07, 0x5e, 0x2e, 0xff, 0x03, 0x43, 0x20, 0xff, 0x00, 0x23, 0x0d, 0xff, 0x02, 0x35, 0x19, 0xff, 0x05, 0x56, 0x2a, 0xff, 0x05, 0x5c, 0x2c, 0xff, 0x0a, 0x56, 0x2e, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x03, 0x23, 0x10, 0xff, 0x01, 0x26, 0x11, 0xff, 0x03, 0x37, 0x19, 0xff, 0x0f, 0x52, 0x2a, 0xff, 0x0f, 0x54, 0x29, 0xff, 0x09, 0x52, 0x2a, 0xff, 0x03, 0x4d, 0x24, 0xff, 0x0c, 0x57, 0x26, 0xff, 0x0e, 0x63, 0x33, 0xff, 0x06, 0x67, 0x34, 0xff, 0x03, 0x69, 0x33, 0xff, 0x06, 0x70, 0x32, 0xff, 0x08, 0x71, 0x30, 0xff, 0x07, 0x70, 0x2f, 0xff, 0x06, 0x73, 0x32, 0xff, 0x03, 0x79, 0x34, 0xff, 0x05, 0x7d, 0x38, 0xff, 0x19, 0x94, 0x50, 0xff, 0x12, 0x7c, 0x40, 0xff, 0x01, 0x41, 0x13, 0xff, 0x02, 0x36, 0x13, 0xff, 0x07, 0x3b, 0x22, 0xff, 0x07, 0x39, 0x21, 0xff, 0x06, 0x46, 0x1f, 0xff, 0x07, 0x47, 0x1f, 0xff, 0x07, 0x46, 0x1e, 0xff, 0x04, 0x42, 0x19, 0xff, 0x0d, 0x48, 0x23, 0xff, 0x08, 0x3f, 0x1f, 0xff, 0x02, 0x36, 0x1d, 0xff, 0x02, 0x35, 0x20, 0xff, 0x04, 0x3b, 0x26, 0xff, 0x04, 0x3e, 0x25, 0xff, 0x03, 0x3c, 0x24, 0xff, 0x0c, 0x43, 0x2f, 0xff, 0x12, 0x4b, 0x37, 0xff, 0x0e, 0x50, 0x38, 0xff, 0x07, 0x50, 0x39, 0xff, 0x08, 0x4f, 0x3b, 0xff, 0x0e, 0x4e, 0x3c, 0xff, 0x0e, 0x50, 0x3a, 0xff, 0x0c, 0x51, 0x37, 0xff, 0x0b, 0x51, 0x36, 0xff, 0x0e, 0x50, 0x37, 0xff, 0x0c, 0x50, 0x35, 0xff, 0x01, 0x42, 0x22, 0xff, 0x06, 0x51, 0x2c, 0xff, 0x0d, 0x60, 0x33, 0xff, 0x04, 0x5c, 0x2a, 0xff, 0x03, 0x60, 0x29, 0xff, 0x0f, 0x74, 0x3d, 0xff, 0x01, 0x63, 0x32, 0xff, 0x01, 0x66, 0x38, 0xff, 0x02, 0x63, 0x36, 0xff, 0x0f, 0x73, 0x46, 0xff, 0x15, 0x74, 0x4b, 0xff, 0x0f, 0x67, 0x3f, 0xff, 0x18, 0x67, 0x3d, 0xff, 0x17, 0x5d, 0x34, 0xff, 0x07, 0x4b, 0x21, 0xff, 0x05, 0x51, 0x26, 0xff, 0x12, 0x70, 0x41, 0xff, 0x09, 0x72, 0x42, 0xff, 0x0a, 0x73, 0x40, 0xff, 0x09, 0x69, 0x38, 0xff, 0x02, 0x54, 0x27, 0xff, 0x01, 0x4d, 0x22, 0xff, 0x01, 0x4a, 0x20, 0xff, 0x08, 0x58, 0x2c, 0xff, 0x24, 0x7c, 0x4f, 0xff, 0x29, 0x80, 0x54, 0xff, 0x10, 0x56, 0x32, 0xff, 0x03, 0x3b, 0x1b, 0xff, 0x04, 0x38, 0x19, 0xff, 0x05, 0x39, 0x1b, 0xff, 0x04, 0x3d, 0x1e, 0xff, 0x01, 0x3b, 0x1c, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x0a, 0x36, 0x1c, 0xff, 0x06, 0x39, 0x1f, 0xff, 0x0b, 0x4a, 0x30, 0xff, 0x15, 0x70, 0x40, 0xff, 0x0e, 0x7f, 0x40, 0xff, 0x0c, 0x78, 0x3b, 0xff, 0x15, 0x5f, 0x3c, 0xff, 0x44, 0x51, 0x78, 0xff, 0x53, 0x43, 0x93, 0xff, 0x21, 0x2b, 0x51, 0xff, 0x4a, 0x4e, 0x7a, 0xff, 0x48, 0x47, 0x7b, 0xff, 0x28, 0x5d, 0x46, 0xff, 0x05, 0x49, 0x17, 0xff, 0x25, 0x9e, 0x6f, 0xff, 0x0b, 0x78, 0x43, 0xff, 0x01, 0x3e, 0x19, 0xff, 0x1a, 0x5e, 0x3b, 0xff, 0x1f, 0x82, 0x4c, 0xff, 0x17, 0x5b, 0x47, 0xff, 0x2d, 0x5c, 0x5f, 0xff, 0x16, 0x66, 0x48, 0xff, 0x0e, 0x67, 0x3d, 0xff, 0x13, 0x64, 0x45, 0xff, 0x0e, 0x6c, 0x4a, 0xff, 0x17, 0xa6, 0x66, 0xff, 0x0f, 0x9d, 0x4f, 0xff, 0x07, 0x87, 0x38, 0xff, 0x0b, 0x8d, 0x3f, 0xff, 0x07, 0x7a, 0x37, 0xff, 0x02, 0x69, 0x32, 0xff, 0x0e, 0x61, 0x35, 0xff, 0x07, 0x4b, 0x26, 0xff, 0x06, 0x48, 0x25, 0xff, 0x19, 0x64, 0x41, 0xff, 0x17, 0x6c, 0x48, 0xff, 0x10, 0x6d, 0x48, 0xff, 0x0e, 0x6d, 0x49, 0xff, 0x11, 0x6e, 0x4a, 0xff, 0x11, 0x6c, 0x48, 0xff, 0x12, 0x6d, 0x48, 0xff, 0x19, 0x6c, 0x4a, 0xff, 0x17, 0x60, 0x42, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x02, 0x34, 0x19, 0xff, 0x06, 0x32, 0x1a, 0xff, 0x07, 0x32, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x01, 0x34, 0x1b, 0xff, 0x03, 0x32, 0x1e, 0xff, 0x06, 0x32, 0x1c, 0xff, 0x04, 0x35, 0x16, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x03, 0x31, 0x1e, 0xff, 0x00, 0x36, 0x18, 0xff, 0x0f, 0x69, 0x31, 0xff, 0x28, 0xa1, 0x5d, 0xff, 0x0c, 0x86, 0x43, 0xff, 0x01, 0x6e, 0x33, 0xff, 0x02, 0x6d, 0x34, 0xff, 0x03, 0x69, 0x32, 0xff, 0x08, 0x65, 0x32, 0xff, 0x09, 0x62, 0x32, 0xff, 0x0c, 0x5f, 0x33, 0xff, 0x0a, 0x5d, 0x31, 0xff, 0x08, 0x5a, 0x2c, 0xff, 0x05, 0x58, 0x2a, 0xff, 0x03, 0x51, 0x27, 0xff, 0x05, 0x4d, 0x24, 0xff, 0x04, 0x46, 0x24, 0xff, 0x01, 0x4b, 0x1e, 0xff, 0x0c, 0x90, 0x3d, 0xff, 0x03, 0x8c, 0x30, 0xff, 0x0b, 0x84, 0x36, 0xff, 0x0b, 0x75, 0x34, 0xff, 0x02, 0x3d, 0x17, 0xff, 0x0a, 0x2f, 0x19, 0xff, 0x08, 0x2e, 0x19, 0xff, 0x01, 0x35, 0x16, 0xff, 0x0c, 0x50, 0x2a, 0xff, 0x06, 0x43, 0x21, 0xff, 0x02, 0x33, 0x18, 0xff, 0x09, 0x31, 0x1a, 0xff, 0x02, 0x38, 0x1a, 0xff, 0x0b, 0x54, 0x2f, 0xff, 0x02, 0x3f, 0x18, 0xff, 0x0b, 0x41, 0x1f, 0xff, 0x02, 0x43, 0x1f, 0xff, 0x07, 0x6c, 0x3b, 0xff, 0x05, 0x84, 0x46, 0xff, 0x04, 0x73, 0x3d, 0xff, 0x04, 0x6f, 0x3b, 0xff, 0x05, 0x6e, 0x3b, 0xff, 0x07, 0x71, 0x3e, 0xff, 0x07, 0x74, 0x3f, 0xff, 0x06, 0x74, 0x3f, 0xff, 0x04, 0x74, 0x3e, 0xff, 0x04, 0x74, 0x3e, 0xff, 0x04, 0x72, 0x3d, 0xff, 0x09, 0x71, 0x40, 0xff, 0x0c, 0x62, 0x38, 0xff, 0x02, 0x32, 0x15, 0xff, 0x05, 0x2d, 0x17, 0xff, 0x09, 0x3b, 0x21, 0xff, 0x0b, 0x50, 0x2e, 0xff, 0x00, 0x54, 0x2a, 0xff, 0x07, 0x5b, 0x32, 0xff, 0x0d, 0x51, 0x30, 0xff, 0x02, 0x26, 0x11, 0xff, 0x01, 0x20, 0x10, 0xff, 0x01, 0x2a, 0x15, 0xff, 0x08, 0x45, 0x26, 0xff, 0x0c, 0x62, 0x36, 0xff, 0x06, 0x72, 0x3d, 0xff, 0x12, 0x76, 0x47, 0xff, 0x03, 0x42, 0x1b, 0xff, 0x07, 0x3e, 0x1e, 0xff, 0x06, 0x4a, 0x2c, 0xff, 0x06, 0x49, 0x2e, 0xff, 0x06, 0x2f, 0x1a, 0xff, 0x01, 0x21, 0x0d, 0xff, 0x07, 0x30, 0x1b, 0xff, 0x0b, 0x31, 0x1f, 0xff, 0x00, 0x24, 0x10, 0xff, 0x09, 0x39, 0x23, 0xff, 0x06, 0x32, 0x1b, 0xff, 0x02, 0x28, 0x12, 0xff, 0x09, 0x41, 0x27, 0xff, 0x06, 0x43, 0x28, 0xff, 0x03, 0x34, 0x18, 0xff, 0x01, 0x3c, 0x1c, 0xff, 0x0d, 0x5c, 0x34, 0xff, 0x0b, 0x62, 0x35, 0xff, 0x08, 0x62, 0x36, 0xff, 0x0d, 0x62, 0x37, 0xff, 0x07, 0x52, 0x28, 0xff, 0x06, 0x5c, 0x30, 0xff, 0x09, 0x6c, 0x3a, 0xff, 0x03, 0x6d, 0x39, 0xff, 0x09, 0x70, 0x38, 0xff, 0x0b, 0x73, 0x35, 0xff, 0x06, 0x73, 0x34, 0xff, 0x0a, 0x73, 0x3a, 0xff, 0x06, 0x56, 0x2e, 0xff, 0x00, 0x31, 0x16, 0xff, 0x01, 0x20, 0x0f, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x07, 0x32, 0x1d, 0xff, 0x07, 0x34, 0x21, 0xff, 0x03, 0x2b, 0x18, 0xff, 0x00, 0x21, 0x0b, 0xff, 0x05, 0x3e, 0x1e, 0xff, 0x0b, 0x5c, 0x34, 0xff, 0x08, 0x5a, 0x2e, 0xff, 0x08, 0x58, 0x2c, 0xff, 0x07, 0x57, 0x2d, 0xff, 0x07, 0x58, 0x2d, 0xff, 0x03, 0x53, 0x29, 0xff, 0x02, 0x4b, 0x25, 0xff, 0x09, 0x44, 0x25, 0xff, 0x02, 0x2e, 0x16, 0xff, 0x05, 0x26, 0x15, 0xff, 0x02, 0x21, 0x11, 0xff, 0x04, 0x2c, 0x1a, 0xff, 0x0e, 0x3b, 0x28, 0xff, 0x05, 0x3b, 0x23, 0xff, 0x03, 0x41, 0x24, 0xff, 0x0e, 0x5d, 0x38, 0xff, 0x05, 0x65, 0x39, 0xff, 0x01, 0x6b, 0x38, 0xff, 0x02, 0x6e, 0x39, 0xff, 0x05, 0x74, 0x3e, 0xff, 0x08, 0x7c, 0x46, 0xff, 0x0b, 0x7e, 0x48, 0xff, 0x14, 0x85, 0x50, 0xff, 0x18, 0x7d, 0x4c, 0xff, 0x18, 0x75, 0x48, 0xff, 0x20, 0x78, 0x4f, 0xff, 0x1a, 0x77, 0x4d, 0xff, 0x19, 0x79, 0x4a, 0xff, 0x20, 0x7f, 0x4a, 0xff, 0x21, 0x7a, 0x6e, 0xff, 0x43, 0x72, 0xc4, 0xff, 0x31, 0x4c, 0xde, 0xff, 0x22, 0x48, 0xd5, 0xff, 0x26, 0x49, 0xda, 0xff, 0x25, 0x44, 0xdc, 0xff, 0x26, 0x44, 0xda, 0xff, 0x25, 0x44, 0xd8, 0xff, 0x21, 0x42, 0xd6, 0xff, 0x1f, 0x3f, 0xd5, 0xff, 0x1d, 0x3d, 0xd3, 0xff, 0x1c, 0x3c, 0xcf, 0xff, 0x18, 0x3a, 0xc8, 0xff, 0x1c, 0x3b, 0xbd, 0xff, 0x1e, 0x33, 0xa8, 0xff, 0x0c, 0x18, 0x86, 0xff, 0x01, 0x1b, 0x45, 0xff, 0x03, 0x3e, 0x29, 0xff, 0x05, 0x50, 0x2a, 0xff, 0x05, 0x50, 0x30, 0xff, 0x17, 0x61, 0x3c, 0xff, 0x0d, 0x5b, 0x2f, 0xff, 0x13, 0x64, 0x3c, 0xff, 0x0d, 0x5a, 0x37, 0xff, 0x19, 0x53, 0x38, 0xff, 0x0b, 0x38, 0x20, 0xff, 0x00, 0x25, 0x10, 0xff, 0x02, 0x21, 0x11, 0xff, 0x63, 0x6f, 0x68, 0xff, + 0x0b, 0x41, 0x22, 0xff, 0x07, 0x44, 0x22, 0xff, 0x01, 0x37, 0x18, 0xff, 0x09, 0x50, 0x2a, 0xff, 0x0b, 0x4e, 0x28, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x00, 0x25, 0x13, 0xff, 0x02, 0x24, 0x11, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x04, 0x5f, 0x2c, 0xff, 0x02, 0x5f, 0x28, 0xff, 0x06, 0x5e, 0x2d, 0xff, 0x04, 0x46, 0x22, 0xff, 0x00, 0x2c, 0x13, 0xff, 0x01, 0x26, 0x14, 0xff, 0x00, 0x27, 0x12, 0xff, 0x01, 0x25, 0x12, 0xff, 0x02, 0x24, 0x14, 0xff, 0x00, 0x25, 0x12, 0xff, 0x04, 0x35, 0x1b, 0xff, 0x0a, 0x4f, 0x29, 0xff, 0x04, 0x52, 0x27, 0xff, 0x07, 0x5c, 0x2d, 0xff, 0x08, 0x5d, 0x2e, 0xff, 0x03, 0x40, 0x1e, 0xff, 0x00, 0x22, 0x0d, 0xff, 0x02, 0x36, 0x19, 0xff, 0x04, 0x57, 0x2b, 0xff, 0x06, 0x5b, 0x2d, 0xff, 0x0a, 0x53, 0x2d, 0xff, 0x02, 0x27, 0x12, 0xff, 0x02, 0x23, 0x10, 0xff, 0x00, 0x2a, 0x10, 0xff, 0x06, 0x42, 0x20, 0xff, 0x0c, 0x54, 0x28, 0xff, 0x0d, 0x55, 0x28, 0xff, 0x04, 0x4e, 0x24, 0xff, 0x05, 0x53, 0x26, 0xff, 0x11, 0x65, 0x30, 0xff, 0x09, 0x67, 0x31, 0xff, 0x02, 0x69, 0x32, 0xff, 0x03, 0x6b, 0x31, 0xff, 0x07, 0x6f, 0x30, 0xff, 0x08, 0x70, 0x2e, 0xff, 0x05, 0x72, 0x30, 0xff, 0x03, 0x75, 0x32, 0xff, 0x02, 0x7d, 0x33, 0xff, 0x19, 0x96, 0x51, 0xff, 0x18, 0x76, 0x42, 0xff, 0x03, 0x42, 0x1a, 0xff, 0x00, 0x30, 0x14, 0xff, 0x08, 0x43, 0x28, 0xff, 0x07, 0x3f, 0x26, 0xff, 0x0a, 0x3d, 0x22, 0xff, 0x05, 0x48, 0x21, 0xff, 0x06, 0x48, 0x1f, 0xff, 0x03, 0x42, 0x1a, 0xff, 0x0a, 0x45, 0x1f, 0xff, 0x1a, 0x51, 0x2f, 0xff, 0x0d, 0x40, 0x23, 0xff, 0x00, 0x34, 0x1d, 0xff, 0x00, 0x35, 0x1f, 0xff, 0x00, 0x36, 0x1f, 0xff, 0x03, 0x3b, 0x27, 0xff, 0x0b, 0x47, 0x36, 0xff, 0x0e, 0x4c, 0x3a, 0xff, 0x12, 0x50, 0x3d, 0xff, 0x13, 0x57, 0x42, 0xff, 0x0f, 0x5f, 0x44, 0xff, 0x06, 0x5d, 0x3c, 0xff, 0x04, 0x54, 0x34, 0xff, 0x04, 0x51, 0x30, 0xff, 0x0a, 0x52, 0x33, 0xff, 0x0f, 0x50, 0x35, 0xff, 0x18, 0x51, 0x3a, 0xff, 0x0e, 0x48, 0x2f, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x09, 0x51, 0x2b, 0xff, 0x07, 0x59, 0x2d, 0xff, 0x01, 0x5a, 0x28, 0xff, 0x06, 0x67, 0x30, 0xff, 0x10, 0x76, 0x3f, 0xff, 0x01, 0x5f, 0x2f, 0xff, 0x01, 0x5f, 0x32, 0xff, 0x04, 0x60, 0x35, 0xff, 0x08, 0x65, 0x39, 0xff, 0x17, 0x71, 0x48, 0xff, 0x1a, 0x70, 0x47, 0xff, 0x07, 0x52, 0x27, 0xff, 0x04, 0x4c, 0x21, 0xff, 0x09, 0x55, 0x28, 0xff, 0x05, 0x58, 0x2b, 0xff, 0x0f, 0x6f, 0x3f, 0xff, 0x08, 0x72, 0x41, 0xff, 0x05, 0x72, 0x3e, 0xff, 0x09, 0x6d, 0x3a, 0xff, 0x06, 0x5b, 0x2d, 0xff, 0x07, 0x52, 0x28, 0xff, 0x03, 0x4a, 0x23, 0xff, 0x01, 0x48, 0x20, 0xff, 0x02, 0x40, 0x19, 0xff, 0x02, 0x41, 0x1c, 0xff, 0x06, 0x41, 0x22, 0xff, 0x04, 0x39, 0x1e, 0xff, 0x07, 0x38, 0x1c, 0xff, 0x0c, 0x3a, 0x1f, 0xff, 0x07, 0x38, 0x1d, 0xff, 0x02, 0x35, 0x1b, 0xff, 0x01, 0x38, 0x1d, 0xff, 0x03, 0x3e, 0x21, 0xff, 0x12, 0x51, 0x2d, 0xff, 0x13, 0x60, 0x3e, 0xff, 0x13, 0x79, 0x45, 0xff, 0x0e, 0x7c, 0x42, 0xff, 0x06, 0x71, 0x36, 0xff, 0x08, 0x67, 0x34, 0xff, 0x14, 0x49, 0x45, 0xff, 0x27, 0x3c, 0x52, 0xff, 0x20, 0x3b, 0x48, 0xff, 0x5b, 0x67, 0x91, 0xff, 0x58, 0x63, 0x98, 0xff, 0x29, 0x65, 0x4e, 0xff, 0x09, 0x5e, 0x28, 0xff, 0x34, 0xa7, 0x73, 0xff, 0x05, 0x4e, 0x29, 0xff, 0x0d, 0x38, 0x2a, 0xff, 0x13, 0x54, 0x3a, 0xff, 0x07, 0x62, 0x32, 0xff, 0x24, 0x64, 0x56, 0xff, 0x2e, 0x60, 0x64, 0xff, 0x17, 0x6a, 0x4d, 0xff, 0x19, 0x6d, 0x46, 0xff, 0x19, 0x6c, 0x47, 0xff, 0x09, 0x78, 0x46, 0xff, 0x17, 0xad, 0x64, 0xff, 0x03, 0x87, 0x38, 0xff, 0x09, 0x8b, 0x3b, 0xff, 0x0b, 0x89, 0x3e, 0xff, 0x05, 0x6d, 0x30, 0xff, 0x05, 0x64, 0x34, 0xff, 0x0d, 0x50, 0x2c, 0xff, 0x03, 0x42, 0x22, 0xff, 0x14, 0x63, 0x41, 0xff, 0x1a, 0x6c, 0x49, 0xff, 0x10, 0x6d, 0x48, 0xff, 0x0d, 0x6e, 0x48, 0xff, 0x0e, 0x6d, 0x47, 0xff, 0x13, 0x6e, 0x48, 0xff, 0x12, 0x6d, 0x47, 0xff, 0x10, 0x6f, 0x47, 0xff, 0x18, 0x69, 0x47, 0xff, 0x08, 0x46, 0x28, 0xff, 0x01, 0x34, 0x19, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x0a, 0x32, 0x1b, 0xff, 0x08, 0x32, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x01, 0x34, 0x1b, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x06, 0x33, 0x1a, 0xff, 0x01, 0x35, 0x19, 0xff, 0x02, 0x32, 0x1c, 0xff, 0x04, 0x33, 0x1d, 0xff, 0x02, 0x44, 0x19, 0xff, 0x24, 0xa8, 0x60, 0xff, 0x14, 0x9f, 0x51, 0xff, 0x01, 0x77, 0x34, 0xff, 0x01, 0x73, 0x35, 0xff, 0x02, 0x70, 0x34, 0xff, 0x06, 0x6f, 0x36, 0xff, 0x07, 0x6a, 0x32, 0xff, 0x07, 0x66, 0x32, 0xff, 0x08, 0x62, 0x31, 0xff, 0x08, 0x62, 0x32, 0xff, 0x06, 0x5f, 0x2e, 0xff, 0x03, 0x5b, 0x2b, 0xff, 0x06, 0x56, 0x2c, 0xff, 0x07, 0x50, 0x27, 0xff, 0x05, 0x4a, 0x24, 0xff, 0x01, 0x54, 0x21, 0xff, 0x0c, 0x94, 0x3f, 0xff, 0x04, 0x8a, 0x30, 0xff, 0x14, 0x7f, 0x39, 0xff, 0x07, 0x5c, 0x26, 0xff, 0x02, 0x33, 0x16, 0xff, 0x09, 0x2e, 0x1e, 0xff, 0x07, 0x30, 0x1a, 0xff, 0x05, 0x3b, 0x1a, 0xff, 0x0a, 0x48, 0x22, 0xff, 0x01, 0x34, 0x16, 0xff, 0x06, 0x30, 0x1b, 0xff, 0x08, 0x2f, 0x18, 0xff, 0x03, 0x42, 0x21, 0xff, 0x06, 0x59, 0x2f, 0xff, 0x06, 0x44, 0x1e, 0xff, 0x10, 0x49, 0x27, 0xff, 0x01, 0x47, 0x20, 0xff, 0x05, 0x64, 0x32, 0xff, 0x08, 0x87, 0x4b, 0xff, 0x03, 0x74, 0x3e, 0xff, 0x05, 0x6f, 0x3b, 0xff, 0x06, 0x6c, 0x39, 0xff, 0x06, 0x6d, 0x3b, 0xff, 0x04, 0x6f, 0x3d, 0xff, 0x03, 0x71, 0x3d, 0xff, 0x05, 0x74, 0x3e, 0xff, 0x05, 0x73, 0x3e, 0xff, 0x05, 0x70, 0x3d, 0xff, 0x05, 0x70, 0x3d, 0xff, 0x0d, 0x6a, 0x3d, 0xff, 0x03, 0x3c, 0x1c, 0xff, 0x02, 0x2b, 0x13, 0xff, 0x09, 0x36, 0x1d, 0xff, 0x0c, 0x4d, 0x2c, 0xff, 0x01, 0x53, 0x2a, 0xff, 0x06, 0x57, 0x2e, 0xff, 0x11, 0x5a, 0x38, 0xff, 0x03, 0x2c, 0x14, 0xff, 0x00, 0x21, 0x10, 0xff, 0x01, 0x28, 0x13, 0xff, 0x09, 0x42, 0x24, 0xff, 0x07, 0x5a, 0x30, 0xff, 0x08, 0x70, 0x3d, 0xff, 0x0f, 0x78, 0x46, 0xff, 0x08, 0x52, 0x29, 0xff, 0x01, 0x38, 0x16, 0xff, 0x06, 0x48, 0x2a, 0xff, 0x05, 0x48, 0x2d, 0xff, 0x0b, 0x3d, 0x26, 0xff, 0x02, 0x25, 0x10, 0xff, 0x03, 0x26, 0x11, 0xff, 0x0c, 0x32, 0x20, 0xff, 0x01, 0x24, 0x12, 0xff, 0x09, 0x36, 0x21, 0xff, 0x08, 0x34, 0x1f, 0xff, 0x02, 0x27, 0x11, 0xff, 0x09, 0x40, 0x27, 0xff, 0x07, 0x44, 0x28, 0xff, 0x02, 0x32, 0x17, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x0e, 0x58, 0x33, 0xff, 0x0a, 0x61, 0x36, 0xff, 0x09, 0x63, 0x36, 0xff, 0x0e, 0x61, 0x37, 0xff, 0x08, 0x54, 0x2b, 0xff, 0x04, 0x54, 0x2a, 0xff, 0x0b, 0x6a, 0x3b, 0xff, 0x04, 0x6c, 0x38, 0xff, 0x08, 0x6e, 0x35, 0xff, 0x0c, 0x72, 0x35, 0xff, 0x09, 0x74, 0x33, 0xff, 0x05, 0x73, 0x36, 0xff, 0x0a, 0x67, 0x37, 0xff, 0x02, 0x3f, 0x1f, 0xff, 0x00, 0x21, 0x10, 0xff, 0x00, 0x22, 0x0e, 0xff, 0x08, 0x30, 0x1b, 0xff, 0x08, 0x34, 0x21, 0xff, 0x05, 0x2c, 0x18, 0xff, 0x00, 0x20, 0x0b, 0xff, 0x05, 0x3b, 0x1d, 0xff, 0x09, 0x59, 0x31, 0xff, 0x09, 0x58, 0x2c, 0xff, 0x07, 0x53, 0x2a, 0xff, 0x03, 0x52, 0x28, 0xff, 0x04, 0x54, 0x2a, 0xff, 0x02, 0x51, 0x28, 0xff, 0x03, 0x4c, 0x26, 0xff, 0x0a, 0x44, 0x26, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x02, 0x21, 0x11, 0xff, 0x02, 0x20, 0x13, 0xff, 0x06, 0x2c, 0x1d, 0xff, 0x0e, 0x3c, 0x29, 0xff, 0x02, 0x3c, 0x21, 0xff, 0x04, 0x4c, 0x29, 0xff, 0x06, 0x61, 0x34, 0xff, 0x05, 0x72, 0x3e, 0xff, 0x0f, 0x8a, 0x50, 0xff, 0x16, 0x9a, 0x5e, 0xff, 0x1b, 0xa2, 0x64, 0xff, 0x1f, 0xa7, 0x68, 0xff, 0x1e, 0xa8, 0x68, 0xff, 0x23, 0xab, 0x6c, 0xff, 0x20, 0xa4, 0x68, 0xff, 0x1b, 0x9c, 0x62, 0xff, 0x20, 0x9d, 0x65, 0xff, 0x19, 0x9c, 0x62, 0xff, 0x17, 0x9e, 0x61, 0xff, 0x1f, 0xa7, 0x60, 0xff, 0x2a, 0xa5, 0x83, 0xff, 0x47, 0x84, 0xcb, 0xff, 0x3d, 0x54, 0xe2, 0xff, 0x28, 0x45, 0xd8, 0xff, 0x24, 0x49, 0xda, 0xff, 0x24, 0x44, 0xdb, 0xff, 0x23, 0x42, 0xdb, 0xff, 0x25, 0x44, 0xda, 0xff, 0x22, 0x3f, 0xd3, 0xff, 0x21, 0x3e, 0xd0, 0xff, 0x20, 0x3b, 0xcc, 0xff, 0x21, 0x3c, 0xc9, 0xff, 0x1e, 0x3a, 0xc2, 0xff, 0x17, 0x2f, 0xaf, 0xff, 0x06, 0x0f, 0x7e, 0xff, 0x01, 0x09, 0x69, 0xff, 0x02, 0x20, 0x3c, 0xff, 0x07, 0x42, 0x28, 0xff, 0x04, 0x4e, 0x26, 0xff, 0x03, 0x4d, 0x29, 0xff, 0x13, 0x58, 0x36, 0xff, 0x0f, 0x5a, 0x33, 0xff, 0x14, 0x68, 0x3e, 0xff, 0x12, 0x5b, 0x38, 0xff, 0x10, 0x43, 0x29, 0xff, 0x02, 0x26, 0x11, 0xff, 0x00, 0x24, 0x11, 0xff, 0x02, 0x21, 0x12, 0xff, 0x64, 0x71, 0x6a, 0xff, + 0x0b, 0x40, 0x21, 0xff, 0x06, 0x42, 0x21, 0xff, 0x01, 0x38, 0x19, 0xff, 0x08, 0x52, 0x2b, 0xff, 0x09, 0x4f, 0x27, 0xff, 0x01, 0x2d, 0x12, 0xff, 0x01, 0x25, 0x13, 0xff, 0x01, 0x25, 0x11, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x03, 0x5e, 0x2c, 0xff, 0x01, 0x60, 0x29, 0xff, 0x05, 0x60, 0x2e, 0xff, 0x06, 0x4a, 0x24, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x01, 0x26, 0x14, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x25, 0x12, 0xff, 0x00, 0x24, 0x13, 0xff, 0x00, 0x26, 0x12, 0xff, 0x06, 0x39, 0x1e, 0xff, 0x0b, 0x50, 0x2a, 0xff, 0x03, 0x52, 0x27, 0xff, 0x07, 0x5c, 0x2e, 0xff, 0x08, 0x5d, 0x2e, 0xff, 0x02, 0x3e, 0x1d, 0xff, 0x00, 0x22, 0x0d, 0xff, 0x02, 0x36, 0x18, 0xff, 0x04, 0x58, 0x2b, 0xff, 0x07, 0x5c, 0x2d, 0xff, 0x0a, 0x4e, 0x2a, 0xff, 0x01, 0x24, 0x12, 0xff, 0x02, 0x25, 0x10, 0xff, 0x02, 0x31, 0x14, 0xff, 0x09, 0x4c, 0x26, 0xff, 0x0a, 0x55, 0x29, 0xff, 0x08, 0x52, 0x24, 0xff, 0x05, 0x53, 0x27, 0xff, 0x0b, 0x61, 0x31, 0xff, 0x0a, 0x68, 0x30, 0xff, 0x06, 0x68, 0x30, 0xff, 0x04, 0x6a, 0x31, 0xff, 0x06, 0x6c, 0x31, 0xff, 0x09, 0x70, 0x2f, 0xff, 0x08, 0x71, 0x2e, 0xff, 0x02, 0x72, 0x30, 0xff, 0x02, 0x77, 0x34, 0xff, 0x19, 0x96, 0x4d, 0xff, 0x1b, 0x83, 0x47, 0xff, 0x03, 0x3d, 0x18, 0xff, 0x00, 0x2d, 0x16, 0xff, 0x03, 0x3d, 0x2a, 0xff, 0x10, 0x50, 0x38, 0xff, 0x08, 0x40, 0x24, 0xff, 0x0d, 0x44, 0x23, 0xff, 0x07, 0x46, 0x1f, 0xff, 0x03, 0x42, 0x1a, 0xff, 0x0d, 0x49, 0x21, 0xff, 0x16, 0x50, 0x2c, 0xff, 0x0c, 0x43, 0x23, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x02, 0x34, 0x1d, 0xff, 0x04, 0x37, 0x21, 0xff, 0x0a, 0x43, 0x28, 0xff, 0x11, 0x4c, 0x38, 0xff, 0x0c, 0x4f, 0x3c, 0xff, 0x05, 0x50, 0x38, 0xff, 0x0c, 0x59, 0x3e, 0xff, 0x20, 0x69, 0x4e, 0xff, 0x1d, 0x72, 0x4c, 0xff, 0x18, 0x78, 0x4a, 0xff, 0x18, 0x76, 0x4d, 0xff, 0x0e, 0x65, 0x3f, 0xff, 0x07, 0x54, 0x33, 0xff, 0x0f, 0x51, 0x35, 0xff, 0x13, 0x4a, 0x33, 0xff, 0x04, 0x3b, 0x23, 0xff, 0x03, 0x44, 0x22, 0xff, 0x0a, 0x54, 0x2c, 0xff, 0x06, 0x59, 0x2d, 0xff, 0x01, 0x59, 0x28, 0xff, 0x0a, 0x6b, 0x34, 0xff, 0x10, 0x74, 0x3d, 0xff, 0x00, 0x5c, 0x2b, 0xff, 0x05, 0x5c, 0x2f, 0xff, 0x0c, 0x61, 0x36, 0xff, 0x0a, 0x5f, 0x34, 0xff, 0x0a, 0x5d, 0x32, 0xff, 0x06, 0x5b, 0x2e, 0xff, 0x04, 0x58, 0x29, 0xff, 0x09, 0x5f, 0x2f, 0xff, 0x0d, 0x62, 0x32, 0xff, 0x05, 0x5a, 0x2d, 0xff, 0x0f, 0x6a, 0x3c, 0xff, 0x11, 0x72, 0x44, 0xff, 0x12, 0x76, 0x45, 0xff, 0x0f, 0x6c, 0x3c, 0xff, 0x0d, 0x5c, 0x31, 0xff, 0x0c, 0x50, 0x29, 0xff, 0x07, 0x42, 0x1f, 0xff, 0x02, 0x3c, 0x1b, 0xff, 0x01, 0x3a, 0x19, 0xff, 0x01, 0x3b, 0x1a, 0xff, 0x07, 0x3f, 0x23, 0xff, 0x04, 0x3d, 0x22, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x06, 0x38, 0x1d, 0xff, 0x0b, 0x35, 0x1c, 0xff, 0x0a, 0x36, 0x1d, 0xff, 0x04, 0x43, 0x26, 0xff, 0x0a, 0x5a, 0x3a, 0xff, 0x0b, 0x63, 0x37, 0xff, 0x0e, 0x6e, 0x45, 0xff, 0x0e, 0x78, 0x47, 0xff, 0x0b, 0x74, 0x42, 0xff, 0x07, 0x72, 0x3c, 0xff, 0x07, 0x76, 0x3a, 0xff, 0x03, 0x57, 0x32, 0xff, 0x0e, 0x46, 0x2d, 0xff, 0x0c, 0x3f, 0x29, 0xff, 0x26, 0x59, 0x51, 0xff, 0x2c, 0x67, 0x6c, 0xff, 0x1d, 0x67, 0x47, 0xff, 0x0d, 0x6c, 0x3c, 0xff, 0x1c, 0x80, 0x53, 0xff, 0x1b, 0x4d, 0x44, 0xff, 0x38, 0x50, 0x69, 0xff, 0x0f, 0x46, 0x3c, 0xff, 0x12, 0x64, 0x39, 0xff, 0x28, 0x67, 0x55, 0xff, 0x29, 0x65, 0x5e, 0xff, 0x0e, 0x66, 0x4a, 0xff, 0x1a, 0x69, 0x4a, 0xff, 0x18, 0x6e, 0x48, 0xff, 0x0a, 0x89, 0x4d, 0xff, 0x0e, 0x9d, 0x50, 0xff, 0x03, 0x81, 0x34, 0xff, 0x0d, 0x8c, 0x41, 0xff, 0x07, 0x7b, 0x36, 0xff, 0x06, 0x67, 0x31, 0xff, 0x0c, 0x61, 0x36, 0xff, 0x09, 0x45, 0x26, 0xff, 0x14, 0x5a, 0x3b, 0xff, 0x12, 0x6d, 0x49, 0xff, 0x0f, 0x6c, 0x47, 0xff, 0x0d, 0x6e, 0x48, 0xff, 0x0d, 0x6e, 0x47, 0xff, 0x10, 0x6e, 0x46, 0xff, 0x13, 0x6d, 0x46, 0xff, 0x14, 0x6e, 0x47, 0xff, 0x0f, 0x6d, 0x45, 0xff, 0x0a, 0x56, 0x36, 0xff, 0x01, 0x37, 0x1b, 0xff, 0x03, 0x35, 0x1c, 0xff, 0x05, 0x33, 0x1c, 0xff, 0x09, 0x33, 0x1c, 0xff, 0x08, 0x32, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x03, 0x33, 0x18, 0xff, 0x05, 0x36, 0x18, 0xff, 0x00, 0x33, 0x1a, 0xff, 0x01, 0x33, 0x1e, 0xff, 0x01, 0x38, 0x18, 0xff, 0x1b, 0x80, 0x44, 0xff, 0x18, 0xac, 0x58, 0xff, 0x01, 0x87, 0x38, 0xff, 0x04, 0x79, 0x38, 0xff, 0x05, 0x76, 0x36, 0xff, 0x06, 0x74, 0x35, 0xff, 0x08, 0x71, 0x35, 0xff, 0x08, 0x6d, 0x34, 0xff, 0x08, 0x69, 0x33, 0xff, 0x06, 0x65, 0x32, 0xff, 0x05, 0x63, 0x31, 0xff, 0x05, 0x61, 0x2f, 0xff, 0x03, 0x5c, 0x2c, 0xff, 0x07, 0x55, 0x2c, 0xff, 0x0a, 0x53, 0x2a, 0xff, 0x04, 0x49, 0x21, 0xff, 0x00, 0x53, 0x1f, 0xff, 0x0c, 0x94, 0x40, 0xff, 0x09, 0x88, 0x34, 0xff, 0x15, 0x6e, 0x33, 0xff, 0x04, 0x42, 0x19, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x03, 0x2f, 0x1e, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x06, 0x3b, 0x1a, 0xff, 0x04, 0x38, 0x16, 0xff, 0x05, 0x32, 0x18, 0xff, 0x08, 0x2f, 0x1d, 0xff, 0x06, 0x32, 0x1a, 0xff, 0x05, 0x50, 0x28, 0xff, 0x06, 0x61, 0x33, 0xff, 0x11, 0x52, 0x2c, 0xff, 0x08, 0x42, 0x1f, 0xff, 0x01, 0x48, 0x1f, 0xff, 0x04, 0x5b, 0x2c, 0xff, 0x0d, 0x88, 0x50, 0xff, 0x03, 0x76, 0x40, 0xff, 0x04, 0x6e, 0x3a, 0xff, 0x06, 0x6b, 0x38, 0xff, 0x08, 0x6b, 0x3c, 0xff, 0x04, 0x6c, 0x3c, 0xff, 0x02, 0x70, 0x3c, 0xff, 0x06, 0x73, 0x3e, 0xff, 0x08, 0x72, 0x3d, 0xff, 0x05, 0x6f, 0x3c, 0xff, 0x06, 0x6f, 0x3c, 0xff, 0x0d, 0x6e, 0x40, 0xff, 0x04, 0x48, 0x25, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x07, 0x33, 0x1a, 0xff, 0x0c, 0x49, 0x29, 0xff, 0x02, 0x52, 0x2b, 0xff, 0x05, 0x54, 0x2b, 0xff, 0x13, 0x5e, 0x3d, 0xff, 0x05, 0x32, 0x1a, 0xff, 0x01, 0x20, 0x0e, 0xff, 0x01, 0x25, 0x11, 0xff, 0x0a, 0x41, 0x25, 0xff, 0x05, 0x53, 0x2b, 0xff, 0x0d, 0x6e, 0x3e, 0xff, 0x0b, 0x76, 0x41, 0xff, 0x0f, 0x65, 0x37, 0xff, 0x01, 0x3d, 0x17, 0xff, 0x05, 0x41, 0x23, 0xff, 0x0a, 0x48, 0x2d, 0xff, 0x0b, 0x46, 0x2c, 0xff, 0x04, 0x31, 0x1a, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x07, 0x2c, 0x19, 0xff, 0x02, 0x24, 0x12, 0xff, 0x06, 0x31, 0x1c, 0xff, 0x0c, 0x37, 0x21, 0xff, 0x01, 0x27, 0x11, 0xff, 0x09, 0x3f, 0x26, 0xff, 0x07, 0x45, 0x29, 0xff, 0x01, 0x30, 0x16, 0xff, 0x02, 0x34, 0x19, 0xff, 0x0f, 0x56, 0x32, 0xff, 0x09, 0x60, 0x35, 0xff, 0x09, 0x63, 0x36, 0xff, 0x0f, 0x62, 0x38, 0xff, 0x09, 0x57, 0x2f, 0xff, 0x03, 0x4f, 0x26, 0xff, 0x0c, 0x69, 0x3c, 0xff, 0x05, 0x6b, 0x38, 0xff, 0x07, 0x6c, 0x36, 0xff, 0x0c, 0x71, 0x36, 0xff, 0x0a, 0x74, 0x34, 0xff, 0x04, 0x72, 0x35, 0xff, 0x0a, 0x6f, 0x3a, 0xff, 0x05, 0x50, 0x2a, 0xff, 0x00, 0x28, 0x12, 0xff, 0x00, 0x22, 0x0d, 0xff, 0x06, 0x2d, 0x18, 0xff, 0x09, 0x33, 0x20, 0xff, 0x04, 0x2a, 0x18, 0xff, 0x00, 0x20, 0x0b, 0xff, 0x05, 0x3b, 0x1d, 0xff, 0x0a, 0x57, 0x30, 0xff, 0x09, 0x57, 0x2c, 0xff, 0x07, 0x51, 0x29, 0xff, 0x03, 0x50, 0x27, 0xff, 0x04, 0x52, 0x29, 0xff, 0x02, 0x4f, 0x26, 0xff, 0x03, 0x4a, 0x25, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x05, 0x30, 0x19, 0xff, 0x01, 0x21, 0x10, 0xff, 0x03, 0x1e, 0x11, 0xff, 0x0b, 0x31, 0x21, 0xff, 0x06, 0x3b, 0x24, 0xff, 0x01, 0x44, 0x21, 0xff, 0x0a, 0x66, 0x3a, 0xff, 0x1b, 0x8b, 0x53, 0xff, 0x20, 0x9a, 0x5d, 0xff, 0x23, 0xa6, 0x64, 0xff, 0x16, 0xa0, 0x5c, 0xff, 0x0c, 0x97, 0x54, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x05, 0x8f, 0x4a, 0xff, 0x04, 0x8f, 0x4a, 0xff, 0x01, 0x8c, 0x47, 0xff, 0x01, 0x8a, 0x47, 0xff, 0x02, 0x8a, 0x48, 0xff, 0x01, 0x8c, 0x47, 0xff, 0x01, 0x8d, 0x4a, 0xff, 0x02, 0x93, 0x4b, 0xff, 0x0e, 0x91, 0x6b, 0xff, 0x43, 0x7c, 0xc2, 0xff, 0x4f, 0x5b, 0xe7, 0xff, 0x33, 0x41, 0xde, 0xff, 0x26, 0x46, 0xd7, 0xff, 0x26, 0x4b, 0xd8, 0xff, 0x22, 0x43, 0xd6, 0xff, 0x20, 0x3f, 0xcd, 0xff, 0x22, 0x40, 0xc9, 0xff, 0x21, 0x3c, 0xc3, 0xff, 0x1e, 0x37, 0xbb, 0xff, 0x18, 0x2f, 0xb0, 0xff, 0x0b, 0x21, 0x9d, 0xff, 0x02, 0x10, 0x8a, 0xff, 0x07, 0x0f, 0x7a, 0xff, 0x04, 0x0d, 0x60, 0xff, 0x11, 0x33, 0x45, 0xff, 0x13, 0x4d, 0x32, 0xff, 0x08, 0x4e, 0x28, 0xff, 0x04, 0x4b, 0x25, 0xff, 0x08, 0x45, 0x26, 0xff, 0x10, 0x57, 0x34, 0xff, 0x16, 0x68, 0x3e, 0xff, 0x15, 0x5a, 0x39, 0xff, 0x03, 0x2e, 0x17, 0xff, 0x03, 0x24, 0x11, 0xff, 0x01, 0x24, 0x13, 0xff, 0x02, 0x21, 0x12, 0xff, 0x68, 0x76, 0x6c, 0xff, + 0x09, 0x3e, 0x1f, 0xff, 0x06, 0x40, 0x1f, 0xff, 0x02, 0x3a, 0x1a, 0xff, 0x09, 0x54, 0x2e, 0xff, 0x09, 0x51, 0x29, 0xff, 0x01, 0x2e, 0x13, 0xff, 0x01, 0x25, 0x12, 0xff, 0x02, 0x26, 0x11, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x03, 0x5e, 0x2d, 0xff, 0x02, 0x60, 0x2b, 0xff, 0x03, 0x60, 0x2d, 0xff, 0x06, 0x4e, 0x26, 0xff, 0x01, 0x31, 0x15, 0xff, 0x01, 0x26, 0x14, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x25, 0x12, 0xff, 0x00, 0x24, 0x13, 0xff, 0x00, 0x28, 0x13, 0xff, 0x08, 0x3e, 0x22, 0xff, 0x0a, 0x51, 0x29, 0xff, 0x02, 0x54, 0x27, 0xff, 0x07, 0x5d, 0x2e, 0xff, 0x09, 0x5c, 0x2d, 0xff, 0x02, 0x3c, 0x1c, 0xff, 0x01, 0x21, 0x0d, 0xff, 0x03, 0x36, 0x19, 0xff, 0x03, 0x57, 0x2c, 0xff, 0x07, 0x5b, 0x2d, 0xff, 0x07, 0x4a, 0x27, 0xff, 0x00, 0x23, 0x10, 0xff, 0x02, 0x27, 0x10, 0xff, 0x07, 0x3b, 0x1d, 0xff, 0x0c, 0x51, 0x2b, 0xff, 0x05, 0x52, 0x26, 0xff, 0x04, 0x4f, 0x20, 0xff, 0x0e, 0x60, 0x30, 0xff, 0x0b, 0x68, 0x33, 0xff, 0x04, 0x6a, 0x2f, 0xff, 0x06, 0x6a, 0x31, 0xff, 0x08, 0x69, 0x31, 0xff, 0x0c, 0x6d, 0x31, 0xff, 0x09, 0x70, 0x2e, 0xff, 0x06, 0x72, 0x2f, 0xff, 0x03, 0x75, 0x33, 0xff, 0x15, 0x8a, 0x49, 0xff, 0x1c, 0x84, 0x45, 0xff, 0x04, 0x45, 0x16, 0xff, 0x01, 0x30, 0x15, 0xff, 0x02, 0x38, 0x27, 0xff, 0x0b, 0x4c, 0x3b, 0xff, 0x12, 0x4e, 0x37, 0xff, 0x0d, 0x46, 0x25, 0xff, 0x08, 0x48, 0x20, 0xff, 0x04, 0x44, 0x1d, 0xff, 0x0c, 0x49, 0x22, 0xff, 0x15, 0x4d, 0x29, 0xff, 0x0b, 0x40, 0x1e, 0xff, 0x02, 0x36, 0x18, 0xff, 0x00, 0x35, 0x19, 0xff, 0x05, 0x3e, 0x24, 0xff, 0x0e, 0x46, 0x2f, 0xff, 0x17, 0x4c, 0x37, 0xff, 0x11, 0x50, 0x3a, 0xff, 0x04, 0x50, 0x36, 0xff, 0x09, 0x5a, 0x3c, 0xff, 0x06, 0x55, 0x34, 0xff, 0x05, 0x53, 0x2f, 0xff, 0x03, 0x54, 0x2c, 0xff, 0x03, 0x56, 0x2f, 0xff, 0x0e, 0x66, 0x45, 0xff, 0x21, 0x78, 0x57, 0xff, 0x11, 0x61, 0x40, 0xff, 0x0c, 0x53, 0x36, 0xff, 0x06, 0x43, 0x28, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x0f, 0x56, 0x33, 0xff, 0x0d, 0x5b, 0x31, 0xff, 0x05, 0x56, 0x2c, 0xff, 0x00, 0x59, 0x29, 0xff, 0x0c, 0x70, 0x3a, 0xff, 0x0d, 0x70, 0x39, 0xff, 0x04, 0x5f, 0x2d, 0xff, 0x0b, 0x5f, 0x33, 0xff, 0x0a, 0x5a, 0x2f, 0xff, 0x03, 0x56, 0x29, 0xff, 0x07, 0x59, 0x2a, 0xff, 0x0a, 0x61, 0x2f, 0xff, 0x09, 0x67, 0x34, 0xff, 0x09, 0x68, 0x35, 0xff, 0x09, 0x65, 0x33, 0xff, 0x07, 0x5b, 0x2f, 0xff, 0x0f, 0x62, 0x38, 0xff, 0x09, 0x5b, 0x32, 0xff, 0x15, 0x67, 0x3c, 0xff, 0x11, 0x5d, 0x34, 0xff, 0x04, 0x46, 0x21, 0xff, 0x06, 0x42, 0x20, 0xff, 0x06, 0x39, 0x1a, 0xff, 0x03, 0x36, 0x18, 0xff, 0x03, 0x38, 0x1a, 0xff, 0x02, 0x38, 0x1a, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x00, 0x35, 0x18, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x0e, 0x35, 0x1d, 0xff, 0x0c, 0x33, 0x1b, 0xff, 0x08, 0x46, 0x29, 0xff, 0x12, 0x66, 0x46, 0xff, 0x02, 0x6d, 0x40, 0xff, 0x0b, 0x79, 0x4e, 0xff, 0x0d, 0x79, 0x4a, 0xff, 0x0c, 0x77, 0x46, 0xff, 0x0e, 0x7c, 0x49, 0xff, 0x10, 0x7e, 0x47, 0xff, 0x0d, 0x6a, 0x3c, 0xff, 0x0d, 0x58, 0x2f, 0xff, 0x0a, 0x50, 0x29, 0xff, 0x19, 0x71, 0x47, 0xff, 0x19, 0x7f, 0x5c, 0xff, 0x0d, 0x68, 0x3d, 0xff, 0x07, 0x6a, 0x40, 0xff, 0x0c, 0x66, 0x47, 0xff, 0x38, 0x62, 0x6f, 0xff, 0x47, 0x5c, 0x86, 0xff, 0x1d, 0x52, 0x4b, 0xff, 0x0e, 0x5b, 0x33, 0xff, 0x17, 0x5c, 0x43, 0xff, 0x18, 0x64, 0x4d, 0xff, 0x0b, 0x67, 0x48, 0xff, 0x14, 0x63, 0x4b, 0xff, 0x0e, 0x70, 0x4b, 0xff, 0x11, 0x9a, 0x5b, 0xff, 0x04, 0x8a, 0x40, 0xff, 0x0a, 0x85, 0x3c, 0xff, 0x09, 0x7e, 0x3a, 0xff, 0x02, 0x6d, 0x2f, 0xff, 0x0b, 0x66, 0x37, 0xff, 0x04, 0x4e, 0x29, 0xff, 0x13, 0x5c, 0x3c, 0xff, 0x17, 0x6d, 0x4a, 0xff, 0x0b, 0x6e, 0x48, 0xff, 0x09, 0x6f, 0x48, 0xff, 0x0b, 0x6f, 0x47, 0xff, 0x0d, 0x6f, 0x47, 0xff, 0x10, 0x6f, 0x47, 0xff, 0x13, 0x6f, 0x48, 0xff, 0x16, 0x6e, 0x49, 0xff, 0x14, 0x69, 0x46, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x06, 0x32, 0x1b, 0xff, 0x06, 0x32, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x04, 0x35, 0x19, 0xff, 0x01, 0x34, 0x15, 0xff, 0x01, 0x34, 0x1d, 0xff, 0x01, 0x35, 0x1c, 0xff, 0x0b, 0x5f, 0x30, 0xff, 0x2e, 0xb2, 0x68, 0xff, 0x05, 0x92, 0x3c, 0xff, 0x00, 0x7e, 0x35, 0xff, 0x04, 0x7a, 0x3b, 0xff, 0x08, 0x78, 0x38, 0xff, 0x09, 0x76, 0x37, 0xff, 0x09, 0x74, 0x36, 0xff, 0x09, 0x70, 0x35, 0xff, 0x08, 0x6c, 0x34, 0xff, 0x05, 0x67, 0x32, 0xff, 0x03, 0x64, 0x31, 0xff, 0x03, 0x61, 0x2f, 0xff, 0x06, 0x5e, 0x2f, 0xff, 0x0a, 0x54, 0x2d, 0xff, 0x0c, 0x51, 0x2b, 0xff, 0x01, 0x40, 0x1b, 0xff, 0x03, 0x53, 0x20, 0xff, 0x0e, 0x91, 0x41, 0xff, 0x12, 0x83, 0x38, 0xff, 0x08, 0x50, 0x21, 0xff, 0x03, 0x34, 0x15, 0xff, 0x01, 0x31, 0x1b, 0xff, 0x00, 0x31, 0x1e, 0xff, 0x00, 0x32, 0x1a, 0xff, 0x02, 0x34, 0x17, 0xff, 0x07, 0x35, 0x17, 0xff, 0x07, 0x32, 0x18, 0xff, 0x05, 0x31, 0x1a, 0xff, 0x01, 0x35, 0x18, 0xff, 0x09, 0x61, 0x31, 0xff, 0x09, 0x67, 0x34, 0xff, 0x13, 0x52, 0x2d, 0xff, 0x02, 0x3d, 0x1c, 0xff, 0x02, 0x48, 0x1f, 0xff, 0x02, 0x51, 0x25, 0xff, 0x13, 0x86, 0x53, 0xff, 0x04, 0x79, 0x40, 0xff, 0x03, 0x6e, 0x39, 0xff, 0x08, 0x6b, 0x39, 0xff, 0x07, 0x6a, 0x3a, 0xff, 0x05, 0x6c, 0x3b, 0xff, 0x03, 0x6e, 0x3b, 0xff, 0x07, 0x71, 0x3d, 0xff, 0x0b, 0x72, 0x3e, 0xff, 0x05, 0x6e, 0x3b, 0xff, 0x07, 0x6e, 0x3b, 0xff, 0x0b, 0x6f, 0x3e, 0xff, 0x0a, 0x59, 0x32, 0xff, 0x01, 0x32, 0x15, 0xff, 0x04, 0x30, 0x16, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x05, 0x51, 0x2b, 0xff, 0x04, 0x50, 0x27, 0xff, 0x13, 0x60, 0x3d, 0xff, 0x09, 0x3d, 0x23, 0xff, 0x00, 0x1f, 0x0d, 0xff, 0x01, 0x24, 0x11, 0xff, 0x08, 0x3f, 0x23, 0xff, 0x04, 0x4b, 0x26, 0xff, 0x11, 0x6d, 0x3e, 0xff, 0x09, 0x71, 0x3c, 0xff, 0x12, 0x72, 0x42, 0xff, 0x04, 0x4b, 0x23, 0xff, 0x04, 0x37, 0x19, 0xff, 0x0d, 0x45, 0x29, 0xff, 0x09, 0x4b, 0x2e, 0xff, 0x09, 0x40, 0x25, 0xff, 0x01, 0x23, 0x0b, 0xff, 0x02, 0x23, 0x11, 0xff, 0x03, 0x24, 0x13, 0xff, 0x03, 0x29, 0x16, 0xff, 0x10, 0x39, 0x23, 0xff, 0x02, 0x26, 0x12, 0xff, 0x07, 0x3d, 0x24, 0xff, 0x07, 0x44, 0x2a, 0xff, 0x01, 0x2f, 0x17, 0xff, 0x01, 0x31, 0x18, 0xff, 0x0e, 0x51, 0x2f, 0xff, 0x08, 0x60, 0x35, 0xff, 0x06, 0x62, 0x33, 0xff, 0x0d, 0x61, 0x35, 0xff, 0x0a, 0x5b, 0x34, 0xff, 0x02, 0x4c, 0x25, 0xff, 0x0e, 0x66, 0x3b, 0xff, 0x08, 0x6a, 0x38, 0xff, 0x06, 0x6b, 0x36, 0xff, 0x09, 0x6f, 0x37, 0xff, 0x0a, 0x71, 0x35, 0xff, 0x07, 0x72, 0x35, 0xff, 0x09, 0x70, 0x3a, 0xff, 0x09, 0x5d, 0x33, 0xff, 0x00, 0x30, 0x15, 0xff, 0x00, 0x23, 0x0e, 0xff, 0x03, 0x28, 0x16, 0xff, 0x0a, 0x33, 0x22, 0xff, 0x03, 0x29, 0x17, 0xff, 0x00, 0x1f, 0x0c, 0xff, 0x05, 0x3a, 0x1e, 0xff, 0x0a, 0x56, 0x2f, 0xff, 0x08, 0x54, 0x29, 0xff, 0x06, 0x52, 0x29, 0xff, 0x04, 0x50, 0x27, 0xff, 0x05, 0x51, 0x28, 0xff, 0x03, 0x4d, 0x25, 0xff, 0x07, 0x4a, 0x26, 0xff, 0x0a, 0x43, 0x26, 0xff, 0x04, 0x31, 0x1a, 0xff, 0x00, 0x20, 0x0f, 0xff, 0x02, 0x21, 0x10, 0xff, 0x04, 0x35, 0x1f, 0xff, 0x03, 0x46, 0x26, 0xff, 0x12, 0x79, 0x49, 0xff, 0x24, 0xa0, 0x68, 0xff, 0x19, 0x9d, 0x5c, 0xff, 0x0f, 0x92, 0x4e, 0xff, 0x06, 0x8a, 0x43, 0xff, 0x04, 0x89, 0x43, 0xff, 0x03, 0x88, 0x43, 0xff, 0x04, 0x8a, 0x43, 0xff, 0x04, 0x8e, 0x46, 0xff, 0x03, 0x8f, 0x47, 0xff, 0x03, 0x91, 0x49, 0xff, 0x03, 0x91, 0x4a, 0xff, 0x06, 0x92, 0x4d, 0xff, 0x05, 0x95, 0x4d, 0xff, 0x02, 0x95, 0x4f, 0xff, 0x02, 0x92, 0x56, 0xff, 0x0b, 0x7e, 0x77, 0xff, 0x2d, 0x62, 0xb7, 0xff, 0x57, 0x66, 0xef, 0xff, 0x34, 0x45, 0xdd, 0xff, 0x25, 0x4a, 0xd8, 0xff, 0x21, 0x48, 0xce, 0xff, 0x24, 0x45, 0xcb, 0xff, 0x22, 0x43, 0xc3, 0xff, 0x10, 0x2c, 0xa8, 0xff, 0x07, 0x22, 0x9b, 0xff, 0x0a, 0x21, 0x99, 0xff, 0x09, 0x20, 0x95, 0xff, 0x05, 0x1b, 0x8c, 0xff, 0x0a, 0x17, 0x8c, 0xff, 0x15, 0x1e, 0x87, 0xff, 0x06, 0x13, 0x5c, 0xff, 0x1f, 0x47, 0x51, 0xff, 0x17, 0x51, 0x36, 0xff, 0x0a, 0x4a, 0x2a, 0xff, 0x08, 0x48, 0x25, 0xff, 0x02, 0x36, 0x18, 0xff, 0x13, 0x58, 0x36, 0xff, 0x17, 0x68, 0x3e, 0xff, 0x12, 0x54, 0x34, 0xff, 0x01, 0x25, 0x11, 0xff, 0x06, 0x23, 0x13, 0xff, 0x01, 0x23, 0x13, 0xff, 0x02, 0x22, 0x14, 0xff, 0x66, 0x77, 0x6d, 0xff, + 0x08, 0x3c, 0x1e, 0xff, 0x04, 0x3e, 0x1d, 0xff, 0x03, 0x3d, 0x1e, 0xff, 0x08, 0x55, 0x2e, 0xff, 0x09, 0x52, 0x29, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x00, 0x26, 0x11, 0xff, 0x02, 0x26, 0x11, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x03, 0x5f, 0x2e, 0xff, 0x02, 0x61, 0x2b, 0xff, 0x02, 0x5f, 0x2c, 0xff, 0x07, 0x51, 0x28, 0xff, 0x02, 0x33, 0x16, 0xff, 0x01, 0x26, 0x14, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x25, 0x12, 0xff, 0x00, 0x24, 0x13, 0xff, 0x00, 0x28, 0x13, 0xff, 0x0a, 0x41, 0x24, 0xff, 0x08, 0x51, 0x28, 0xff, 0x01, 0x53, 0x27, 0xff, 0x06, 0x5b, 0x2d, 0xff, 0x0a, 0x5b, 0x2e, 0xff, 0x03, 0x3a, 0x1a, 0xff, 0x01, 0x20, 0x0c, 0xff, 0x03, 0x36, 0x19, 0xff, 0x04, 0x57, 0x2c, 0xff, 0x09, 0x5c, 0x2d, 0xff, 0x04, 0x46, 0x22, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x01, 0x28, 0x10, 0xff, 0x0b, 0x43, 0x24, 0xff, 0x0c, 0x53, 0x2d, 0xff, 0x01, 0x4d, 0x22, 0xff, 0x07, 0x54, 0x26, 0xff, 0x10, 0x67, 0x33, 0xff, 0x06, 0x68, 0x2f, 0xff, 0x03, 0x69, 0x2f, 0xff, 0x07, 0x69, 0x2f, 0xff, 0x0b, 0x69, 0x30, 0xff, 0x0c, 0x6d, 0x2f, 0xff, 0x05, 0x71, 0x2e, 0xff, 0x03, 0x75, 0x30, 0xff, 0x11, 0x83, 0x41, 0xff, 0x26, 0x90, 0x55, 0xff, 0x07, 0x4e, 0x20, 0xff, 0x00, 0x31, 0x0c, 0xff, 0x01, 0x38, 0x20, 0xff, 0x0a, 0x4a, 0x36, 0xff, 0x12, 0x4f, 0x3b, 0xff, 0x0d, 0x4b, 0x30, 0xff, 0x07, 0x49, 0x25, 0xff, 0x07, 0x47, 0x1f, 0xff, 0x09, 0x48, 0x23, 0xff, 0x0e, 0x49, 0x26, 0xff, 0x04, 0x38, 0x16, 0xff, 0x04, 0x37, 0x17, 0xff, 0x02, 0x37, 0x19, 0xff, 0x05, 0x3e, 0x21, 0xff, 0x0d, 0x4c, 0x30, 0xff, 0x12, 0x50, 0x38, 0xff, 0x16, 0x4e, 0x3e, 0xff, 0x09, 0x52, 0x38, 0xff, 0x12, 0x60, 0x48, 0xff, 0x29, 0x6c, 0x5e, 0xff, 0x11, 0x4c, 0x3d, 0xff, 0x0b, 0x53, 0x34, 0xff, 0x08, 0x52, 0x31, 0xff, 0x08, 0x4b, 0x35, 0xff, 0x05, 0x46, 0x3b, 0xff, 0x0a, 0x51, 0x40, 0xff, 0x1c, 0x66, 0x4c, 0xff, 0x14, 0x5d, 0x3f, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x00, 0x40, 0x1f, 0xff, 0x0f, 0x55, 0x32, 0xff, 0x15, 0x5e, 0x38, 0xff, 0x15, 0x64, 0x3b, 0xff, 0x04, 0x5a, 0x2c, 0xff, 0x0c, 0x72, 0x3d, 0xff, 0x06, 0x69, 0x32, 0xff, 0x04, 0x5f, 0x2d, 0xff, 0x0a, 0x5e, 0x32, 0xff, 0x04, 0x58, 0x2b, 0xff, 0x04, 0x5a, 0x2b, 0xff, 0x0c, 0x63, 0x2f, 0xff, 0x0c, 0x68, 0x33, 0xff, 0x09, 0x6c, 0x34, 0xff, 0x06, 0x6a, 0x34, 0xff, 0x07, 0x65, 0x33, 0xff, 0x0b, 0x5f, 0x33, 0xff, 0x0d, 0x58, 0x32, 0xff, 0x09, 0x52, 0x2d, 0xff, 0x07, 0x4b, 0x25, 0xff, 0x02, 0x42, 0x1e, 0xff, 0x01, 0x3e, 0x1d, 0xff, 0x02, 0x3b, 0x1c, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x03, 0x3e, 0x20, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x01, 0x40, 0x20, 0xff, 0x02, 0x42, 0x22, 0xff, 0x02, 0x45, 0x26, 0xff, 0x02, 0x44, 0x24, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x06, 0x35, 0x1a, 0xff, 0x0b, 0x35, 0x1c, 0xff, 0x05, 0x3d, 0x21, 0xff, 0x15, 0x60, 0x41, 0xff, 0x08, 0x75, 0x4c, 0xff, 0x0e, 0x7e, 0x52, 0xff, 0x11, 0x7d, 0x4f, 0xff, 0x11, 0x7e, 0x4f, 0xff, 0x11, 0x7f, 0x4e, 0xff, 0x10, 0x78, 0x48, 0xff, 0x0b, 0x66, 0x3a, 0xff, 0x0c, 0x61, 0x38, 0xff, 0x10, 0x5f, 0x37, 0xff, 0x0e, 0x75, 0x45, 0xff, 0x0d, 0x7c, 0x4f, 0xff, 0x05, 0x65, 0x36, 0xff, 0x10, 0x77, 0x4a, 0xff, 0x10, 0x66, 0x4e, 0xff, 0x3c, 0x6a, 0x81, 0xff, 0x3e, 0x61, 0x83, 0xff, 0x1b, 0x56, 0x49, 0xff, 0x0d, 0x5c, 0x39, 0xff, 0x15, 0x63, 0x48, 0xff, 0x0c, 0x65, 0x44, 0xff, 0x09, 0x69, 0x44, 0xff, 0x0e, 0x68, 0x4c, 0xff, 0x08, 0x7a, 0x4d, 0xff, 0x19, 0xa2, 0x60, 0xff, 0x03, 0x81, 0x3b, 0xff, 0x0e, 0x83, 0x40, 0xff, 0x05, 0x71, 0x33, 0xff, 0x03, 0x69, 0x32, 0xff, 0x03, 0x58, 0x2d, 0xff, 0x08, 0x52, 0x30, 0xff, 0x11, 0x6f, 0x4b, 0xff, 0x0a, 0x6f, 0x48, 0xff, 0x0a, 0x71, 0x49, 0xff, 0x07, 0x70, 0x48, 0xff, 0x0a, 0x71, 0x47, 0xff, 0x0b, 0x71, 0x47, 0xff, 0x0b, 0x70, 0x46, 0xff, 0x11, 0x71, 0x49, 0xff, 0x17, 0x6d, 0x49, 0xff, 0x10, 0x5b, 0x3a, 0xff, 0x00, 0x34, 0x18, 0xff, 0x04, 0x34, 0x1c, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x04, 0x34, 0x18, 0xff, 0x01, 0x33, 0x17, 0xff, 0x01, 0x35, 0x1c, 0xff, 0x01, 0x39, 0x17, 0xff, 0x1f, 0x93, 0x55, 0xff, 0x19, 0xaa, 0x5a, 0xff, 0x01, 0x87, 0x37, 0xff, 0x01, 0x7e, 0x3a, 0xff, 0x04, 0x7b, 0x3d, 0xff, 0x06, 0x79, 0x37, 0xff, 0x06, 0x77, 0x36, 0xff, 0x07, 0x75, 0x35, 0xff, 0x08, 0x71, 0x35, 0xff, 0x08, 0x6d, 0x35, 0xff, 0x06, 0x68, 0x33, 0xff, 0x05, 0x65, 0x32, 0xff, 0x05, 0x62, 0x30, 0xff, 0x08, 0x5e, 0x31, 0xff, 0x10, 0x55, 0x31, 0xff, 0x08, 0x48, 0x25, 0xff, 0x00, 0x39, 0x15, 0xff, 0x06, 0x56, 0x26, 0xff, 0x12, 0x90, 0x45, 0xff, 0x10, 0x77, 0x34, 0xff, 0x01, 0x39, 0x14, 0xff, 0x05, 0x31, 0x19, 0xff, 0x02, 0x31, 0x1b, 0xff, 0x00, 0x32, 0x1c, 0xff, 0x00, 0x32, 0x18, 0xff, 0x02, 0x34, 0x18, 0xff, 0x08, 0x38, 0x1c, 0xff, 0x04, 0x35, 0x1a, 0xff, 0x01, 0x36, 0x1c, 0xff, 0x01, 0x47, 0x22, 0xff, 0x0d, 0x6f, 0x39, 0xff, 0x0b, 0x66, 0x33, 0xff, 0x0a, 0x46, 0x23, 0xff, 0x04, 0x3d, 0x20, 0xff, 0x03, 0x48, 0x20, 0xff, 0x02, 0x4a, 0x20, 0xff, 0x14, 0x7f, 0x4f, 0xff, 0x05, 0x7d, 0x43, 0xff, 0x03, 0x6e, 0x39, 0xff, 0x08, 0x6a, 0x38, 0xff, 0x07, 0x68, 0x39, 0xff, 0x04, 0x69, 0x3a, 0xff, 0x03, 0x6e, 0x3c, 0xff, 0x07, 0x6f, 0x3c, 0xff, 0x0a, 0x6f, 0x3c, 0xff, 0x05, 0x6c, 0x39, 0xff, 0x09, 0x6d, 0x3a, 0xff, 0x0b, 0x6d, 0x3d, 0xff, 0x0b, 0x62, 0x38, 0xff, 0x01, 0x3b, 0x1c, 0xff, 0x01, 0x2e, 0x13, 0xff, 0x08, 0x3f, 0x22, 0xff, 0x08, 0x4e, 0x2b, 0xff, 0x04, 0x4f, 0x27, 0xff, 0x0f, 0x5c, 0x39, 0xff, 0x0a, 0x45, 0x2a, 0xff, 0x00, 0x20, 0x0e, 0xff, 0x00, 0x24, 0x10, 0xff, 0x09, 0x41, 0x25, 0xff, 0x06, 0x46, 0x23, 0xff, 0x11, 0x69, 0x3d, 0xff, 0x08, 0x70, 0x3a, 0xff, 0x0e, 0x73, 0x43, 0xff, 0x06, 0x55, 0x2b, 0xff, 0x01, 0x32, 0x15, 0xff, 0x08, 0x3b, 0x21, 0xff, 0x07, 0x4a, 0x2d, 0xff, 0x0b, 0x4a, 0x2b, 0xff, 0x05, 0x2e, 0x13, 0xff, 0x01, 0x1f, 0x0d, 0xff, 0x04, 0x25, 0x13, 0xff, 0x02, 0x25, 0x13, 0xff, 0x10, 0x37, 0x22, 0xff, 0x03, 0x26, 0x12, 0xff, 0x06, 0x3b, 0x22, 0xff, 0x07, 0x43, 0x2a, 0xff, 0x01, 0x2f, 0x18, 0xff, 0x01, 0x31, 0x19, 0xff, 0x0d, 0x4d, 0x2c, 0xff, 0x09, 0x60, 0x36, 0xff, 0x06, 0x61, 0x33, 0xff, 0x0d, 0x61, 0x35, 0xff, 0x0c, 0x5d, 0x36, 0xff, 0x03, 0x4b, 0x26, 0xff, 0x0d, 0x62, 0x39, 0xff, 0x0d, 0x6c, 0x39, 0xff, 0x05, 0x6b, 0x36, 0xff, 0x07, 0x6e, 0x38, 0xff, 0x0b, 0x6f, 0x37, 0xff, 0x0a, 0x70, 0x35, 0xff, 0x09, 0x6f, 0x38, 0xff, 0x0e, 0x66, 0x38, 0xff, 0x01, 0x37, 0x18, 0xff, 0x00, 0x25, 0x0e, 0xff, 0x02, 0x24, 0x13, 0xff, 0x09, 0x31, 0x20, 0xff, 0x04, 0x2a, 0x18, 0xff, 0x01, 0x20, 0x0c, 0xff, 0x07, 0x3b, 0x1f, 0xff, 0x0a, 0x55, 0x30, 0xff, 0x08, 0x53, 0x29, 0xff, 0x05, 0x51, 0x28, 0xff, 0x03, 0x4e, 0x27, 0xff, 0x04, 0x4f, 0x26, 0xff, 0x05, 0x4b, 0x26, 0xff, 0x08, 0x4a, 0x26, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x04, 0x34, 0x1c, 0xff, 0x00, 0x22, 0x0e, 0xff, 0x00, 0x27, 0x0e, 0xff, 0x08, 0x4c, 0x2a, 0xff, 0x20, 0x80, 0x54, 0xff, 0x20, 0x9e, 0x66, 0xff, 0x0d, 0x96, 0x55, 0xff, 0x02, 0x89, 0x43, 0xff, 0x01, 0x8b, 0x44, 0xff, 0x05, 0x8d, 0x46, 0xff, 0x07, 0x90, 0x49, 0xff, 0x08, 0x91, 0x4c, 0xff, 0x08, 0x92, 0x4d, 0xff, 0x07, 0x92, 0x4d, 0xff, 0x06, 0x93, 0x4e, 0xff, 0x05, 0x93, 0x4d, 0xff, 0x05, 0x94, 0x4f, 0xff, 0x04, 0x96, 0x4f, 0xff, 0x06, 0x95, 0x4e, 0xff, 0x07, 0x94, 0x53, 0xff, 0x0b, 0x8a, 0x65, 0xff, 0x22, 0x71, 0x9c, 0xff, 0x24, 0x4a, 0xb7, 0xff, 0x50, 0x5d, 0xe7, 0xff, 0x4b, 0x58, 0xe8, 0xff, 0x2e, 0x4b, 0xd8, 0xff, 0x28, 0x49, 0xd0, 0xff, 0x1b, 0x3b, 0xbb, 0xff, 0x09, 0x27, 0xa1, 0xff, 0x07, 0x23, 0x99, 0xff, 0x0b, 0x25, 0x9b, 0xff, 0x10, 0x28, 0x9f, 0xff, 0x13, 0x2b, 0xa0, 0xff, 0x0e, 0x24, 0x99, 0xff, 0x1f, 0x2e, 0xa1, 0xff, 0x11, 0x1a, 0x80, 0xff, 0x06, 0x17, 0x5f, 0xff, 0x16, 0x47, 0x4d, 0xff, 0x11, 0x4e, 0x30, 0xff, 0x0b, 0x45, 0x2b, 0xff, 0x06, 0x3f, 0x22, 0xff, 0x02, 0x39, 0x1a, 0xff, 0x14, 0x5a, 0x38, 0xff, 0x18, 0x68, 0x3e, 0xff, 0x10, 0x4f, 0x2f, 0xff, 0x02, 0x26, 0x14, 0xff, 0x07, 0x24, 0x15, 0xff, 0x01, 0x24, 0x14, 0xff, 0x07, 0x28, 0x19, 0xff, 0x64, 0x73, 0x69, 0xff, + 0x07, 0x3a, 0x1c, 0xff, 0x02, 0x3b, 0x1b, 0xff, 0x06, 0x40, 0x22, 0xff, 0x06, 0x54, 0x2d, 0xff, 0x08, 0x53, 0x2a, 0xff, 0x02, 0x2f, 0x14, 0xff, 0x00, 0x26, 0x11, 0xff, 0x01, 0x25, 0x10, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x03, 0x5e, 0x2d, 0xff, 0x01, 0x61, 0x2b, 0xff, 0x01, 0x5e, 0x2b, 0xff, 0x09, 0x54, 0x2a, 0xff, 0x03, 0x35, 0x18, 0xff, 0x01, 0x26, 0x14, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x25, 0x12, 0xff, 0x00, 0x25, 0x13, 0xff, 0x01, 0x29, 0x13, 0xff, 0x0c, 0x45, 0x27, 0xff, 0x06, 0x50, 0x27, 0xff, 0x01, 0x53, 0x25, 0xff, 0x05, 0x58, 0x2b, 0xff, 0x0a, 0x59, 0x2d, 0xff, 0x03, 0x37, 0x18, 0xff, 0x01, 0x1f, 0x0a, 0xff, 0x03, 0x37, 0x1a, 0xff, 0x03, 0x56, 0x2c, 0xff, 0x0b, 0x5b, 0x2e, 0xff, 0x03, 0x41, 0x1d, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x02, 0x2b, 0x10, 0xff, 0x10, 0x49, 0x2a, 0xff, 0x07, 0x4e, 0x2a, 0xff, 0x02, 0x4e, 0x25, 0xff, 0x0c, 0x5a, 0x2c, 0xff, 0x09, 0x66, 0x2e, 0xff, 0x05, 0x6c, 0x2f, 0xff, 0x04, 0x69, 0x2f, 0xff, 0x0a, 0x68, 0x30, 0xff, 0x0d, 0x69, 0x30, 0xff, 0x09, 0x6d, 0x2f, 0xff, 0x01, 0x72, 0x2d, 0xff, 0x04, 0x7a, 0x35, 0xff, 0x21, 0x91, 0x50, 0xff, 0x10, 0x68, 0x32, 0xff, 0x00, 0x2e, 0x13, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x0b, 0x4a, 0x31, 0xff, 0x10, 0x51, 0x39, 0xff, 0x0f, 0x4f, 0x33, 0xff, 0x08, 0x4c, 0x2c, 0xff, 0x01, 0x44, 0x1f, 0xff, 0x08, 0x46, 0x1f, 0xff, 0x12, 0x45, 0x26, 0xff, 0x06, 0x3b, 0x1b, 0xff, 0x00, 0x37, 0x16, 0xff, 0x01, 0x3a, 0x18, 0xff, 0x04, 0x44, 0x24, 0xff, 0x0c, 0x4f, 0x30, 0xff, 0x11, 0x53, 0x35, 0xff, 0x13, 0x51, 0x38, 0xff, 0x0c, 0x4e, 0x3a, 0xff, 0x09, 0x61, 0x40, 0xff, 0x3b, 0x83, 0x7e, 0xff, 0x46, 0x60, 0x83, 0xff, 0x37, 0x48, 0x69, 0xff, 0x14, 0x4b, 0x44, 0xff, 0x0a, 0x53, 0x38, 0xff, 0x16, 0x4c, 0x44, 0xff, 0x2a, 0x48, 0x5e, 0xff, 0x1f, 0x48, 0x51, 0xff, 0x0e, 0x4a, 0x3a, 0xff, 0x11, 0x58, 0x39, 0xff, 0x04, 0x47, 0x22, 0xff, 0x01, 0x39, 0x16, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x03, 0x3e, 0x21, 0xff, 0x16, 0x5e, 0x39, 0xff, 0x13, 0x6a, 0x3d, 0xff, 0x0d, 0x72, 0x3e, 0xff, 0x02, 0x66, 0x2f, 0xff, 0x02, 0x62, 0x2f, 0xff, 0x05, 0x5c, 0x2f, 0xff, 0x08, 0x63, 0x32, 0xff, 0x08, 0x66, 0x34, 0xff, 0x0a, 0x69, 0x30, 0xff, 0x05, 0x68, 0x2e, 0xff, 0x07, 0x6e, 0x33, 0xff, 0x0a, 0x6e, 0x36, 0xff, 0x0d, 0x68, 0x34, 0xff, 0x0a, 0x5a, 0x2e, 0xff, 0x0c, 0x51, 0x2e, 0xff, 0x0e, 0x4f, 0x30, 0xff, 0x06, 0x40, 0x21, 0xff, 0x00, 0x39, 0x1a, 0xff, 0x00, 0x3c, 0x1d, 0xff, 0x02, 0x41, 0x22, 0xff, 0x07, 0x4e, 0x2f, 0xff, 0x0b, 0x58, 0x38, 0xff, 0x0b, 0x61, 0x3f, 0xff, 0x0e, 0x69, 0x45, 0xff, 0x19, 0x70, 0x4c, 0xff, 0x18, 0x75, 0x4f, 0xff, 0x16, 0x73, 0x50, 0xff, 0x13, 0x68, 0x45, 0xff, 0x0b, 0x4e, 0x2f, 0xff, 0x02, 0x39, 0x1d, 0xff, 0x01, 0x36, 0x1b, 0xff, 0x0c, 0x4d, 0x30, 0xff, 0x13, 0x70, 0x4e, 0xff, 0x17, 0x7f, 0x54, 0xff, 0x12, 0x7e, 0x53, 0xff, 0x0c, 0x7c, 0x4d, 0xff, 0x0a, 0x75, 0x46, 0xff, 0x10, 0x70, 0x49, 0xff, 0x0f, 0x6c, 0x42, 0xff, 0x0e, 0x6d, 0x44, 0xff, 0x0e, 0x66, 0x3e, 0xff, 0x07, 0x6b, 0x41, 0xff, 0x04, 0x65, 0x3e, 0xff, 0x0e, 0x72, 0x45, 0xff, 0x18, 0x86, 0x4f, 0xff, 0x11, 0x66, 0x4a, 0xff, 0x36, 0x6f, 0x7d, 0xff, 0x36, 0x6d, 0x78, 0xff, 0x14, 0x5a, 0x47, 0xff, 0x21, 0x72, 0x5d, 0xff, 0x1b, 0x71, 0x5d, 0xff, 0x10, 0x72, 0x4c, 0xff, 0x11, 0x76, 0x4a, 0xff, 0x0e, 0x77, 0x53, 0xff, 0x0b, 0x95, 0x57, 0xff, 0x14, 0x9e, 0x54, 0xff, 0x0a, 0x7d, 0x3c, 0xff, 0x06, 0x78, 0x39, 0xff, 0x04, 0x69, 0x32, 0xff, 0x04, 0x61, 0x30, 0xff, 0x0a, 0x60, 0x39, 0xff, 0x1a, 0x76, 0x53, 0xff, 0x0c, 0x7d, 0x56, 0xff, 0x0b, 0x7d, 0x51, 0xff, 0x0e, 0x79, 0x4e, 0xff, 0x10, 0x7a, 0x50, 0xff, 0x13, 0x7a, 0x50, 0xff, 0x11, 0x7b, 0x50, 0xff, 0x0d, 0x7b, 0x4f, 0xff, 0x0f, 0x78, 0x4e, 0xff, 0x17, 0x69, 0x47, 0xff, 0x07, 0x45, 0x27, 0xff, 0x03, 0x31, 0x18, 0xff, 0x05, 0x31, 0x1b, 0xff, 0x04, 0x32, 0x1c, 0xff, 0x04, 0x33, 0x1c, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x03, 0x32, 0x18, 0xff, 0x06, 0x34, 0x1c, 0xff, 0x01, 0x33, 0x18, 0xff, 0x05, 0x54, 0x24, 0xff, 0x23, 0xb0, 0x63, 0xff, 0x04, 0x93, 0x41, 0xff, 0x04, 0x84, 0x3e, 0xff, 0x07, 0x7e, 0x40, 0xff, 0x04, 0x7c, 0x3d, 0xff, 0x02, 0x7c, 0x38, 0xff, 0x03, 0x7a, 0x36, 0xff, 0x04, 0x77, 0x36, 0xff, 0x07, 0x73, 0x35, 0xff, 0x08, 0x6f, 0x36, 0xff, 0x08, 0x69, 0x35, 0xff, 0x07, 0x65, 0x34, 0xff, 0x06, 0x61, 0x32, 0xff, 0x09, 0x5b, 0x30, 0xff, 0x0c, 0x4c, 0x2b, 0xff, 0x02, 0x3b, 0x1b, 0xff, 0x00, 0x34, 0x14, 0xff, 0x0a, 0x5a, 0x2b, 0xff, 0x11, 0x87, 0x41, 0xff, 0x05, 0x5b, 0x1f, 0xff, 0x01, 0x31, 0x14, 0xff, 0x07, 0x31, 0x1f, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x03, 0x32, 0x18, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x09, 0x3d, 0x23, 0xff, 0x03, 0x37, 0x1e, 0xff, 0x02, 0x38, 0x1c, 0xff, 0x0f, 0x53, 0x33, 0xff, 0x0e, 0x67, 0x3a, 0xff, 0x0d, 0x79, 0x3d, 0xff, 0x09, 0x64, 0x2e, 0xff, 0x03, 0x3b, 0x1b, 0xff, 0x06, 0x40, 0x23, 0xff, 0x04, 0x48, 0x21, 0xff, 0x00, 0x46, 0x1e, 0xff, 0x0e, 0x71, 0x43, 0xff, 0x0a, 0x87, 0x4c, 0xff, 0x02, 0x6c, 0x35, 0xff, 0x07, 0x68, 0x37, 0xff, 0x0a, 0x69, 0x3b, 0xff, 0x05, 0x69, 0x3a, 0xff, 0x04, 0x6d, 0x3b, 0xff, 0x07, 0x6d, 0x3a, 0xff, 0x09, 0x6c, 0x38, 0xff, 0x05, 0x6a, 0x38, 0xff, 0x09, 0x6b, 0x37, 0xff, 0x0a, 0x6b, 0x39, 0xff, 0x08, 0x65, 0x3b, 0xff, 0x03, 0x4a, 0x27, 0xff, 0x00, 0x2e, 0x13, 0xff, 0x05, 0x37, 0x1b, 0xff, 0x08, 0x4a, 0x28, 0xff, 0x07, 0x4f, 0x28, 0xff, 0x08, 0x55, 0x32, 0xff, 0x07, 0x48, 0x2c, 0xff, 0x03, 0x23, 0x11, 0xff, 0x00, 0x22, 0x0f, 0xff, 0x0a, 0x41, 0x26, 0xff, 0x08, 0x46, 0x24, 0xff, 0x08, 0x5e, 0x32, 0xff, 0x09, 0x71, 0x3c, 0xff, 0x08, 0x70, 0x3f, 0xff, 0x09, 0x5c, 0x33, 0xff, 0x03, 0x36, 0x18, 0xff, 0x04, 0x32, 0x18, 0xff, 0x04, 0x44, 0x26, 0xff, 0x09, 0x4b, 0x2c, 0xff, 0x0e, 0x3f, 0x23, 0xff, 0x05, 0x24, 0x13, 0xff, 0x03, 0x21, 0x11, 0xff, 0x01, 0x22, 0x11, 0xff, 0x0c, 0x31, 0x1d, 0xff, 0x06, 0x27, 0x14, 0xff, 0x04, 0x38, 0x1f, 0xff, 0x06, 0x42, 0x28, 0xff, 0x02, 0x30, 0x19, 0xff, 0x01, 0x31, 0x1a, 0xff, 0x0a, 0x47, 0x28, 0xff, 0x08, 0x5f, 0x35, 0xff, 0x06, 0x61, 0x32, 0xff, 0x0c, 0x61, 0x35, 0xff, 0x0e, 0x5f, 0x38, 0xff, 0x06, 0x4d, 0x29, 0xff, 0x0a, 0x5c, 0x33, 0xff, 0x10, 0x6d, 0x38, 0xff, 0x04, 0x6a, 0x34, 0xff, 0x05, 0x6c, 0x38, 0xff, 0x0d, 0x6e, 0x39, 0xff, 0x0c, 0x6d, 0x35, 0xff, 0x08, 0x6e, 0x36, 0xff, 0x0e, 0x6a, 0x3b, 0xff, 0x03, 0x44, 0x22, 0xff, 0x01, 0x29, 0x12, 0xff, 0x00, 0x20, 0x0f, 0xff, 0x03, 0x29, 0x19, 0xff, 0x04, 0x28, 0x17, 0xff, 0x01, 0x20, 0x0c, 0xff, 0x07, 0x3b, 0x1f, 0xff, 0x0a, 0x53, 0x2f, 0xff, 0x07, 0x50, 0x27, 0xff, 0x02, 0x4e, 0x28, 0xff, 0x02, 0x4d, 0x27, 0xff, 0x04, 0x4d, 0x25, 0xff, 0x06, 0x4a, 0x25, 0xff, 0x09, 0x46, 0x23, 0xff, 0x0a, 0x42, 0x24, 0xff, 0x02, 0x32, 0x19, 0xff, 0x02, 0x2a, 0x15, 0xff, 0x08, 0x4f, 0x29, 0xff, 0x28, 0x93, 0x62, 0xff, 0x21, 0x9a, 0x61, 0xff, 0x05, 0x8c, 0x4a, 0xff, 0x00, 0x8a, 0x44, 0xff, 0x03, 0x93, 0x4b, 0xff, 0x02, 0x93, 0x4b, 0xff, 0x02, 0x96, 0x4e, 0xff, 0x02, 0x95, 0x4f, 0xff, 0x03, 0x96, 0x50, 0xff, 0x02, 0x96, 0x50, 0xff, 0x01, 0x97, 0x52, 0xff, 0x01, 0x96, 0x52, 0xff, 0x01, 0x9b, 0x55, 0xff, 0x04, 0xa0, 0x5b, 0xff, 0x01, 0x9f, 0x57, 0xff, 0x02, 0x9a, 0x50, 0xff, 0x08, 0x96, 0x57, 0xff, 0x15, 0x7f, 0x83, 0xff, 0x39, 0x67, 0xc8, 0xff, 0x27, 0x43, 0xc7, 0xff, 0x25, 0x36, 0xc3, 0xff, 0x3f, 0x4d, 0xd6, 0xff, 0x38, 0x4d, 0xd6, 0xff, 0x1b, 0x34, 0xbb, 0xff, 0x0c, 0x28, 0xa7, 0xff, 0x11, 0x2c, 0xa7, 0xff, 0x17, 0x30, 0xa8, 0xff, 0x15, 0x2c, 0xa7, 0xff, 0x18, 0x2f, 0xad, 0xff, 0x16, 0x2d, 0xaf, 0xff, 0x1a, 0x32, 0xb4, 0xff, 0x24, 0x36, 0xab, 0xff, 0x03, 0x0d, 0x74, 0xff, 0x03, 0x1f, 0x68, 0xff, 0x11, 0x4b, 0x4c, 0xff, 0x0d, 0x4f, 0x2c, 0xff, 0x09, 0x3f, 0x2a, 0xff, 0x02, 0x33, 0x20, 0xff, 0x08, 0x42, 0x23, 0xff, 0x16, 0x5d, 0x38, 0xff, 0x19, 0x67, 0x3d, 0xff, 0x0f, 0x4b, 0x2c, 0xff, 0x03, 0x25, 0x13, 0xff, 0x04, 0x21, 0x14, 0xff, 0x04, 0x29, 0x1a, 0xff, 0x09, 0x2c, 0x1d, 0xff, 0x62, 0x71, 0x66, 0xff, + 0x04, 0x37, 0x1b, 0xff, 0x01, 0x39, 0x19, 0xff, 0x06, 0x44, 0x23, 0xff, 0x07, 0x56, 0x2d, 0xff, 0x09, 0x55, 0x2c, 0xff, 0x02, 0x31, 0x16, 0xff, 0x01, 0x26, 0x11, 0xff, 0x01, 0x25, 0x10, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x07, 0x52, 0x2a, 0xff, 0x02, 0x5e, 0x2c, 0xff, 0x00, 0x60, 0x29, 0xff, 0x01, 0x5d, 0x2b, 0xff, 0x09, 0x56, 0x2c, 0xff, 0x03, 0x38, 0x1a, 0xff, 0x01, 0x26, 0x13, 0xff, 0x01, 0x26, 0x12, 0xff, 0x00, 0x24, 0x13, 0xff, 0x00, 0x26, 0x13, 0xff, 0x02, 0x2c, 0x14, 0xff, 0x0e, 0x48, 0x29, 0xff, 0x07, 0x51, 0x28, 0xff, 0x02, 0x54, 0x27, 0xff, 0x04, 0x56, 0x2a, 0xff, 0x09, 0x57, 0x2c, 0xff, 0x03, 0x35, 0x17, 0xff, 0x01, 0x20, 0x0c, 0xff, 0x04, 0x38, 0x1c, 0xff, 0x05, 0x56, 0x2b, 0xff, 0x0b, 0x58, 0x2d, 0xff, 0x03, 0x3c, 0x1a, 0xff, 0x00, 0x26, 0x0f, 0xff, 0x06, 0x30, 0x15, 0xff, 0x10, 0x49, 0x2a, 0xff, 0x03, 0x49, 0x25, 0xff, 0x06, 0x54, 0x2a, 0xff, 0x0b, 0x5c, 0x2d, 0xff, 0x0b, 0x68, 0x2f, 0xff, 0x05, 0x6a, 0x2d, 0xff, 0x08, 0x68, 0x30, 0xff, 0x0d, 0x68, 0x30, 0xff, 0x0e, 0x6b, 0x30, 0xff, 0x08, 0x6f, 0x2f, 0xff, 0x00, 0x76, 0x31, 0xff, 0x12, 0x8b, 0x48, 0xff, 0x12, 0x70, 0x37, 0xff, 0x01, 0x3d, 0x12, 0xff, 0x01, 0x2d, 0x1d, 0xff, 0x06, 0x3e, 0x2b, 0xff, 0x14, 0x50, 0x38, 0xff, 0x14, 0x54, 0x38, 0xff, 0x0a, 0x54, 0x31, 0xff, 0x05, 0x51, 0x28, 0xff, 0x01, 0x4c, 0x21, 0xff, 0x03, 0x46, 0x1c, 0xff, 0x09, 0x37, 0x14, 0xff, 0x01, 0x36, 0x16, 0xff, 0x02, 0x47, 0x22, 0xff, 0x0f, 0x6c, 0x40, 0xff, 0x1d, 0x80, 0x53, 0xff, 0x18, 0x63, 0x48, 0xff, 0x18, 0x45, 0x39, 0xff, 0x18, 0x4c, 0x37, 0xff, 0x08, 0x5b, 0x3b, 0xff, 0x28, 0x97, 0x6d, 0xff, 0x45, 0x74, 0x8e, 0xff, 0x6f, 0x5a, 0xb3, 0xff, 0x53, 0x3a, 0x8d, 0xff, 0x29, 0x43, 0x64, 0xff, 0x0c, 0x4e, 0x3e, 0xff, 0x1a, 0x4b, 0x43, 0xff, 0x48, 0x50, 0x74, 0xff, 0x3a, 0x4f, 0x67, 0xff, 0x10, 0x43, 0x37, 0xff, 0x03, 0x41, 0x23, 0xff, 0x10, 0x56, 0x32, 0xff, 0x0e, 0x51, 0x2e, 0xff, 0x0d, 0x46, 0x2c, 0xff, 0x09, 0x3d, 0x25, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x0a, 0x5b, 0x34, 0xff, 0x12, 0x77, 0x45, 0xff, 0x0a, 0x6f, 0x3c, 0xff, 0x0c, 0x6a, 0x3a, 0xff, 0x0f, 0x68, 0x3c, 0xff, 0x0b, 0x6a, 0x3a, 0xff, 0x04, 0x69, 0x34, 0xff, 0x04, 0x6e, 0x33, 0xff, 0x02, 0x6d, 0x33, 0xff, 0x09, 0x72, 0x38, 0xff, 0x10, 0x71, 0x3b, 0xff, 0x11, 0x66, 0x37, 0xff, 0x04, 0x4c, 0x24, 0xff, 0x02, 0x40, 0x1f, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x03, 0x42, 0x23, 0xff, 0x00, 0x3e, 0x1d, 0xff, 0x04, 0x4a, 0x29, 0xff, 0x12, 0x66, 0x44, 0xff, 0x1a, 0x74, 0x51, 0xff, 0x18, 0x79, 0x56, 0xff, 0x13, 0x7d, 0x56, 0xff, 0x11, 0x7f, 0x57, 0xff, 0x12, 0x7e, 0x54, 0xff, 0x12, 0x80, 0x55, 0xff, 0x0f, 0x80, 0x55, 0xff, 0x14, 0x80, 0x57, 0xff, 0x18, 0x76, 0x52, 0xff, 0x0b, 0x5b, 0x39, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x04, 0x4c, 0x2c, 0xff, 0x0d, 0x6d, 0x41, 0xff, 0x11, 0x7c, 0x52, 0xff, 0x0b, 0x7c, 0x4e, 0xff, 0x0f, 0x79, 0x4c, 0xff, 0x13, 0x73, 0x4f, 0xff, 0x14, 0x79, 0x4d, 0xff, 0x12, 0x7c, 0x4e, 0xff, 0x0e, 0x6d, 0x45, 0xff, 0x0e, 0x6e, 0x49, 0xff, 0x12, 0x6b, 0x48, 0xff, 0x1d, 0x84, 0x58, 0xff, 0x10, 0x81, 0x46, 0xff, 0x15, 0x70, 0x49, 0xff, 0x22, 0x6e, 0x62, 0xff, 0x23, 0x72, 0x61, 0xff, 0x17, 0x6b, 0x50, 0xff, 0x22, 0x7c, 0x69, 0xff, 0x1c, 0x7d, 0x6a, 0xff, 0x12, 0x7c, 0x55, 0xff, 0x1b, 0x88, 0x57, 0xff, 0x10, 0x86, 0x58, 0xff, 0x14, 0xa7, 0x5e, 0xff, 0x09, 0x8d, 0x3d, 0xff, 0x0e, 0x7a, 0x3d, 0xff, 0x03, 0x6f, 0x38, 0xff, 0x01, 0x65, 0x32, 0xff, 0x0b, 0x63, 0x36, 0xff, 0x22, 0x80, 0x59, 0xff, 0x18, 0x86, 0x5e, 0xff, 0x0d, 0x85, 0x5a, 0xff, 0x0c, 0x83, 0x55, 0xff, 0x14, 0x82, 0x54, 0xff, 0x17, 0x82, 0x57, 0xff, 0x18, 0x82, 0x57, 0xff, 0x15, 0x83, 0x57, 0xff, 0x12, 0x82, 0x58, 0xff, 0x17, 0x7f, 0x56, 0xff, 0x07, 0x4f, 0x30, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x08, 0x32, 0x1b, 0xff, 0x06, 0x31, 0x1c, 0xff, 0x04, 0x33, 0x1c, 0xff, 0x04, 0x33, 0x1c, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x06, 0x31, 0x1a, 0xff, 0x09, 0x34, 0x1d, 0xff, 0x01, 0x3d, 0x1a, 0xff, 0x0f, 0x81, 0x44, 0xff, 0x15, 0xa9, 0x55, 0xff, 0x00, 0x89, 0x3b, 0xff, 0x04, 0x82, 0x44, 0xff, 0x0a, 0x7e, 0x43, 0xff, 0x06, 0x7f, 0x3d, 0xff, 0x01, 0x7f, 0x3a, 0xff, 0x02, 0x7c, 0x38, 0xff, 0x04, 0x7a, 0x37, 0xff, 0x07, 0x75, 0x37, 0xff, 0x09, 0x72, 0x37, 0xff, 0x08, 0x6b, 0x36, 0xff, 0x07, 0x65, 0x34, 0xff, 0x05, 0x5f, 0x32, 0xff, 0x09, 0x56, 0x2e, 0xff, 0x03, 0x3d, 0x1e, 0xff, 0x01, 0x35, 0x17, 0xff, 0x03, 0x38, 0x18, 0xff, 0x21, 0x6d, 0x43, 0xff, 0x08, 0x6c, 0x30, 0xff, 0x00, 0x42, 0x0f, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x04, 0x30, 0x1f, 0xff, 0x05, 0x32, 0x1a, 0xff, 0x05, 0x33, 0x18, 0xff, 0x0f, 0x41, 0x25, 0xff, 0x0e, 0x44, 0x2b, 0xff, 0x01, 0x37, 0x1c, 0xff, 0x09, 0x4d, 0x2e, 0xff, 0x14, 0x66, 0x40, 0xff, 0x0a, 0x6d, 0x3c, 0xff, 0x09, 0x78, 0x3a, 0xff, 0x08, 0x60, 0x2c, 0xff, 0x01, 0x39, 0x1a, 0xff, 0x02, 0x3e, 0x22, 0xff, 0x06, 0x46, 0x23, 0xff, 0x04, 0x43, 0x1e, 0xff, 0x07, 0x60, 0x35, 0xff, 0x0f, 0x8b, 0x50, 0xff, 0x03, 0x6e, 0x38, 0xff, 0x08, 0x6a, 0x38, 0xff, 0x0a, 0x68, 0x3a, 0xff, 0x07, 0x69, 0x3b, 0xff, 0x04, 0x6a, 0x3a, 0xff, 0x07, 0x6a, 0x38, 0xff, 0x0a, 0x6a, 0x38, 0xff, 0x06, 0x6a, 0x37, 0xff, 0x08, 0x68, 0x35, 0xff, 0x07, 0x69, 0x37, 0xff, 0x07, 0x67, 0x3a, 0xff, 0x06, 0x55, 0x31, 0xff, 0x00, 0x31, 0x14, 0xff, 0x02, 0x31, 0x16, 0xff, 0x09, 0x47, 0x27, 0xff, 0x0a, 0x4f, 0x2a, 0xff, 0x03, 0x4e, 0x2c, 0xff, 0x05, 0x47, 0x2a, 0xff, 0x02, 0x25, 0x11, 0xff, 0x00, 0x20, 0x0d, 0xff, 0x08, 0x3e, 0x24, 0xff, 0x0a, 0x47, 0x28, 0xff, 0x02, 0x4e, 0x25, 0xff, 0x0b, 0x70, 0x3c, 0xff, 0x08, 0x70, 0x3e, 0xff, 0x0a, 0x62, 0x36, 0xff, 0x08, 0x42, 0x22, 0xff, 0x01, 0x31, 0x15, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x07, 0x47, 0x28, 0xff, 0x0f, 0x49, 0x29, 0xff, 0x0f, 0x36, 0x21, 0xff, 0x02, 0x23, 0x11, 0xff, 0x01, 0x22, 0x11, 0xff, 0x07, 0x2a, 0x17, 0xff, 0x07, 0x29, 0x16, 0xff, 0x02, 0x36, 0x1f, 0xff, 0x07, 0x42, 0x28, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x01, 0x31, 0x19, 0xff, 0x07, 0x43, 0x25, 0xff, 0x09, 0x5e, 0x35, 0xff, 0x06, 0x5f, 0x32, 0xff, 0x09, 0x5d, 0x32, 0xff, 0x0f, 0x60, 0x38, 0xff, 0x09, 0x52, 0x2d, 0xff, 0x07, 0x54, 0x2d, 0xff, 0x10, 0x6a, 0x37, 0xff, 0x02, 0x66, 0x31, 0xff, 0x01, 0x65, 0x33, 0xff, 0x07, 0x64, 0x34, 0xff, 0x09, 0x67, 0x33, 0xff, 0x07, 0x69, 0x33, 0xff, 0x0d, 0x6a, 0x39, 0xff, 0x07, 0x50, 0x2a, 0xff, 0x02, 0x2f, 0x17, 0xff, 0x00, 0x21, 0x0f, 0xff, 0x02, 0x24, 0x14, 0xff, 0x05, 0x26, 0x17, 0xff, 0x00, 0x1e, 0x0c, 0xff, 0x07, 0x3b, 0x1f, 0xff, 0x08, 0x52, 0x2d, 0xff, 0x05, 0x4e, 0x26, 0xff, 0x02, 0x4d, 0x26, 0xff, 0x03, 0x4d, 0x27, 0xff, 0x03, 0x4b, 0x27, 0xff, 0x03, 0x46, 0x23, 0xff, 0x06, 0x44, 0x23, 0xff, 0x08, 0x40, 0x22, 0xff, 0x02, 0x38, 0x19, 0xff, 0x13, 0x58, 0x38, 0xff, 0x1e, 0x8a, 0x58, 0xff, 0x0f, 0x91, 0x52, 0xff, 0x03, 0x89, 0x47, 0xff, 0x04, 0x8f, 0x49, 0xff, 0x02, 0x91, 0x49, 0xff, 0x01, 0x94, 0x4c, 0xff, 0x00, 0x97, 0x50, 0xff, 0x00, 0x9f, 0x59, 0xff, 0x00, 0xa2, 0x5c, 0xff, 0x01, 0xa5, 0x5f, 0xff, 0x03, 0xa8, 0x63, 0xff, 0x01, 0xa7, 0x62, 0xff, 0x01, 0xa7, 0x62, 0xff, 0x03, 0xac, 0x67, 0xff, 0x04, 0xae, 0x69, 0xff, 0x02, 0xae, 0x66, 0xff, 0x03, 0xad, 0x60, 0xff, 0x0a, 0xa5, 0x66, 0xff, 0x1d, 0x8a, 0x9f, 0xff, 0x41, 0x6d, 0xdf, 0xff, 0x23, 0x46, 0xcf, 0xff, 0x1d, 0x39, 0xc8, 0xff, 0x1b, 0x31, 0xbc, 0xff, 0x19, 0x30, 0xb8, 0xff, 0x1d, 0x35, 0xbf, 0xff, 0x1f, 0x38, 0xbe, 0xff, 0x1d, 0x37, 0xb9, 0xff, 0x18, 0x34, 0xb4, 0xff, 0x19, 0x33, 0xb9, 0xff, 0x18, 0x30, 0xbe, 0xff, 0x1c, 0x36, 0xbd, 0xff, 0x24, 0x40, 0xc1, 0xff, 0x0c, 0x19, 0x8b, 0xff, 0x02, 0x12, 0x7b, 0xff, 0x06, 0x25, 0x77, 0xff, 0x0a, 0x47, 0x4a, 0xff, 0x0a, 0x4a, 0x28, 0xff, 0x06, 0x38, 0x26, 0xff, 0x03, 0x32, 0x22, 0xff, 0x08, 0x43, 0x24, 0xff, 0x12, 0x5b, 0x34, 0xff, 0x1a, 0x66, 0x3c, 0xff, 0x13, 0x4e, 0x2f, 0xff, 0x01, 0x22, 0x10, 0xff, 0x03, 0x22, 0x14, 0xff, 0x07, 0x30, 0x21, 0xff, 0x07, 0x2a, 0x1b, 0xff, 0x62, 0x71, 0x68, 0xff, + 0x05, 0x34, 0x1d, 0xff, 0x02, 0x37, 0x17, 0xff, 0x05, 0x4a, 0x24, 0xff, 0x06, 0x56, 0x2b, 0xff, 0x08, 0x54, 0x2c, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x01, 0x24, 0x11, 0xff, 0x02, 0x25, 0x12, 0xff, 0x02, 0x2b, 0x10, 0xff, 0x08, 0x54, 0x29, 0xff, 0x02, 0x60, 0x2c, 0xff, 0x02, 0x5f, 0x29, 0xff, 0x03, 0x5e, 0x2b, 0xff, 0x09, 0x58, 0x2c, 0xff, 0x04, 0x3e, 0x1c, 0xff, 0x01, 0x25, 0x12, 0xff, 0x01, 0x24, 0x14, 0xff, 0x02, 0x24, 0x14, 0xff, 0x00, 0x25, 0x11, 0xff, 0x04, 0x32, 0x15, 0xff, 0x0d, 0x4a, 0x27, 0xff, 0x07, 0x50, 0x28, 0xff, 0x03, 0x51, 0x28, 0xff, 0x04, 0x53, 0x28, 0xff, 0x09, 0x54, 0x2a, 0xff, 0x03, 0x32, 0x17, 0xff, 0x00, 0x20, 0x0d, 0xff, 0x05, 0x39, 0x1b, 0xff, 0x07, 0x56, 0x2b, 0xff, 0x0d, 0x55, 0x2d, 0xff, 0x03, 0x37, 0x19, 0xff, 0x01, 0x27, 0x11, 0xff, 0x0c, 0x39, 0x1f, 0xff, 0x06, 0x40, 0x20, 0xff, 0x06, 0x4c, 0x26, 0xff, 0x07, 0x58, 0x2c, 0xff, 0x08, 0x5d, 0x2c, 0xff, 0x0b, 0x65, 0x2e, 0xff, 0x0b, 0x67, 0x30, 0xff, 0x09, 0x68, 0x31, 0xff, 0x0b, 0x6a, 0x2f, 0xff, 0x0c, 0x6d, 0x2d, 0xff, 0x06, 0x71, 0x2e, 0xff, 0x0c, 0x82, 0x42, 0xff, 0x10, 0x7d, 0x46, 0xff, 0x02, 0x40, 0x1a, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x07, 0x3c, 0x2a, 0xff, 0x0f, 0x4d, 0x36, 0xff, 0x0e, 0x4e, 0x36, 0xff, 0x0e, 0x53, 0x39, 0xff, 0x15, 0x65, 0x3e, 0xff, 0x11, 0x6c, 0x35, 0xff, 0x12, 0x76, 0x3a, 0xff, 0x0f, 0x6e, 0x35, 0xff, 0x0e, 0x52, 0x1f, 0xff, 0x05, 0x46, 0x1e, 0xff, 0x16, 0x7b, 0x46, 0xff, 0x21, 0xb0, 0x69, 0xff, 0x1e, 0x9f, 0x61, 0xff, 0x26, 0x5c, 0x60, 0xff, 0x43, 0x3a, 0x6b, 0xff, 0x17, 0x3c, 0x38, 0xff, 0x20, 0x7d, 0x51, 0xff, 0x1e, 0x88, 0x58, 0xff, 0x57, 0x60, 0x91, 0xff, 0x76, 0x4c, 0xb7, 0xff, 0x5a, 0x39, 0x97, 0xff, 0x48, 0x39, 0x90, 0xff, 0x1b, 0x42, 0x50, 0xff, 0x15, 0x42, 0x35, 0xff, 0x33, 0x49, 0x59, 0xff, 0x2b, 0x4c, 0x5a, 0xff, 0x15, 0x4a, 0x39, 0xff, 0x0a, 0x42, 0x26, 0xff, 0x08, 0x43, 0x29, 0xff, 0x10, 0x54, 0x37, 0xff, 0x16, 0x50, 0x3f, 0xff, 0x17, 0x4a, 0x38, 0xff, 0x04, 0x3e, 0x2b, 0xff, 0x01, 0x45, 0x28, 0xff, 0x19, 0x7b, 0x51, 0xff, 0x0f, 0x70, 0x44, 0xff, 0x09, 0x5d, 0x34, 0xff, 0x0a, 0x5c, 0x35, 0xff, 0x0d, 0x68, 0x3b, 0xff, 0x0b, 0x74, 0x41, 0xff, 0x09, 0x81, 0x48, 0xff, 0x16, 0x8d, 0x57, 0xff, 0x15, 0x7c, 0x4b, 0xff, 0x1b, 0x73, 0x48, 0xff, 0x0c, 0x56, 0x31, 0xff, 0x01, 0x3f, 0x1d, 0xff, 0x05, 0x47, 0x28, 0xff, 0x0f, 0x56, 0x36, 0xff, 0x15, 0x69, 0x44, 0xff, 0x07, 0x5b, 0x34, 0xff, 0x0b, 0x66, 0x3e, 0xff, 0x1b, 0x7f, 0x56, 0xff, 0x15, 0x80, 0x56, 0xff, 0x13, 0x81, 0x57, 0xff, 0x10, 0x81, 0x56, 0xff, 0x0f, 0x81, 0x56, 0xff, 0x12, 0x82, 0x53, 0xff, 0x11, 0x83, 0x53, 0xff, 0x0e, 0x82, 0x54, 0xff, 0x0e, 0x83, 0x56, 0xff, 0x13, 0x81, 0x58, 0xff, 0x16, 0x7b, 0x55, 0xff, 0x08, 0x5c, 0x39, 0xff, 0x08, 0x55, 0x33, 0xff, 0x06, 0x5f, 0x39, 0xff, 0x0a, 0x70, 0x46, 0xff, 0x12, 0x80, 0x55, 0xff, 0x11, 0x82, 0x56, 0xff, 0x13, 0x82, 0x56, 0xff, 0x11, 0x7d, 0x53, 0xff, 0x12, 0x7e, 0x52, 0xff, 0x14, 0x7f, 0x53, 0xff, 0x0f, 0x76, 0x4d, 0xff, 0x0f, 0x74, 0x4d, 0xff, 0x12, 0x77, 0x50, 0xff, 0x18, 0x83, 0x59, 0xff, 0x0d, 0x7b, 0x4c, 0xff, 0x0e, 0x76, 0x4d, 0xff, 0x10, 0x75, 0x52, 0xff, 0x12, 0x76, 0x51, 0xff, 0x14, 0x7a, 0x52, 0xff, 0x14, 0x7d, 0x58, 0xff, 0x11, 0x81, 0x5d, 0xff, 0x0d, 0x83, 0x5a, 0xff, 0x0f, 0x88, 0x59, 0xff, 0x15, 0x92, 0x5d, 0xff, 0x14, 0x96, 0x52, 0xff, 0x03, 0x7e, 0x35, 0xff, 0x05, 0x72, 0x38, 0xff, 0x01, 0x69, 0x38, 0xff, 0x0b, 0x73, 0x43, 0xff, 0x19, 0x81, 0x53, 0xff, 0x1b, 0x89, 0x5c, 0xff, 0x12, 0x88, 0x5a, 0xff, 0x0c, 0x86, 0x58, 0xff, 0x0d, 0x84, 0x57, 0xff, 0x14, 0x84, 0x56, 0xff, 0x13, 0x84, 0x57, 0xff, 0x0f, 0x86, 0x59, 0xff, 0x0e, 0x84, 0x59, 0xff, 0x1b, 0x80, 0x5a, 0xff, 0x10, 0x60, 0x3f, 0xff, 0x02, 0x37, 0x1e, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x06, 0x33, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x02, 0x32, 0x1b, 0xff, 0x01, 0x32, 0x1c, 0xff, 0x06, 0x32, 0x1a, 0xff, 0x06, 0x35, 0x19, 0xff, 0x03, 0x58, 0x28, 0xff, 0x1a, 0xa5, 0x5e, 0xff, 0x09, 0x96, 0x45, 0xff, 0x03, 0x85, 0x3f, 0xff, 0x02, 0x81, 0x48, 0xff, 0x07, 0x81, 0x43, 0xff, 0x04, 0x82, 0x3d, 0xff, 0x01, 0x7f, 0x3c, 0xff, 0x05, 0x7c, 0x39, 0xff, 0x07, 0x79, 0x37, 0xff, 0x07, 0x77, 0x38, 0xff, 0x05, 0x74, 0x38, 0xff, 0x03, 0x6b, 0x35, 0xff, 0x05, 0x65, 0x34, 0xff, 0x09, 0x5c, 0x33, 0xff, 0x07, 0x48, 0x29, 0xff, 0x01, 0x36, 0x18, 0xff, 0x03, 0x34, 0x16, 0xff, 0x10, 0x48, 0x27, 0xff, 0x29, 0x6c, 0x47, 0xff, 0x04, 0x45, 0x1e, 0xff, 0x01, 0x37, 0x14, 0xff, 0x06, 0x32, 0x18, 0xff, 0x04, 0x32, 0x1e, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x05, 0x36, 0x1c, 0xff, 0x14, 0x4b, 0x2e, 0xff, 0x05, 0x3d, 0x1f, 0xff, 0x05, 0x4a, 0x27, 0xff, 0x0e, 0x62, 0x3d, 0xff, 0x0a, 0x69, 0x3d, 0xff, 0x09, 0x6f, 0x3a, 0xff, 0x0d, 0x71, 0x3c, 0xff, 0x08, 0x56, 0x2a, 0xff, 0x00, 0x39, 0x1a, 0xff, 0x00, 0x3e, 0x21, 0xff, 0x08, 0x43, 0x25, 0xff, 0x09, 0x42, 0x21, 0xff, 0x03, 0x53, 0x27, 0xff, 0x12, 0x84, 0x4f, 0xff, 0x06, 0x72, 0x3d, 0xff, 0x06, 0x69, 0x36, 0xff, 0x09, 0x69, 0x3a, 0xff, 0x05, 0x6a, 0x3a, 0xff, 0x04, 0x68, 0x38, 0xff, 0x0a, 0x69, 0x3a, 0xff, 0x0b, 0x67, 0x38, 0xff, 0x09, 0x67, 0x37, 0xff, 0x04, 0x69, 0x37, 0xff, 0x02, 0x68, 0x36, 0xff, 0x05, 0x67, 0x37, 0xff, 0x0d, 0x5f, 0x37, 0xff, 0x02, 0x38, 0x18, 0xff, 0x02, 0x31, 0x14, 0xff, 0x0e, 0x43, 0x27, 0xff, 0x0a, 0x4c, 0x2a, 0xff, 0x05, 0x4d, 0x2a, 0xff, 0x04, 0x48, 0x28, 0xff, 0x00, 0x2b, 0x12, 0xff, 0x01, 0x21, 0x0e, 0xff, 0x08, 0x3b, 0x23, 0xff, 0x0a, 0x49, 0x2b, 0xff, 0x02, 0x40, 0x1b, 0xff, 0x0b, 0x64, 0x37, 0xff, 0x0c, 0x72, 0x3f, 0xff, 0x07, 0x68, 0x37, 0xff, 0x04, 0x4e, 0x27, 0xff, 0x05, 0x3a, 0x1e, 0xff, 0x02, 0x2f, 0x18, 0xff, 0x07, 0x3d, 0x21, 0xff, 0x09, 0x4a, 0x2a, 0xff, 0x08, 0x43, 0x28, 0xff, 0x01, 0x2b, 0x14, 0xff, 0x04, 0x23, 0x11, 0xff, 0x07, 0x26, 0x17, 0xff, 0x03, 0x2a, 0x19, 0xff, 0x01, 0x35, 0x20, 0xff, 0x08, 0x3e, 0x27, 0xff, 0x04, 0x31, 0x1a, 0xff, 0x03, 0x31, 0x19, 0xff, 0x04, 0x3f, 0x21, 0xff, 0x0d, 0x59, 0x35, 0xff, 0x09, 0x5e, 0x33, 0xff, 0x08, 0x5d, 0x30, 0xff, 0x11, 0x61, 0x36, 0xff, 0x0c, 0x55, 0x2f, 0xff, 0x06, 0x4c, 0x29, 0xff, 0x0f, 0x67, 0x3a, 0xff, 0x07, 0x63, 0x33, 0xff, 0x06, 0x60, 0x32, 0xff, 0x08, 0x5f, 0x33, 0xff, 0x07, 0x60, 0x32, 0xff, 0x08, 0x64, 0x34, 0xff, 0x0c, 0x67, 0x36, 0xff, 0x0a, 0x5b, 0x2f, 0xff, 0x00, 0x38, 0x19, 0xff, 0x00, 0x23, 0x10, 0xff, 0x03, 0x21, 0x12, 0xff, 0x05, 0x23, 0x15, 0xff, 0x00, 0x1e, 0x0d, 0xff, 0x09, 0x3c, 0x20, 0xff, 0x07, 0x4d, 0x2a, 0xff, 0x06, 0x4c, 0x26, 0xff, 0x08, 0x4d, 0x25, 0xff, 0x02, 0x49, 0x24, 0xff, 0x01, 0x48, 0x26, 0xff, 0x00, 0x44, 0x25, 0xff, 0x03, 0x42, 0x23, 0xff, 0x05, 0x43, 0x1e, 0xff, 0x0d, 0x5b, 0x2e, 0xff, 0x18, 0x85, 0x4d, 0xff, 0x0d, 0x8b, 0x4a, 0xff, 0x04, 0x89, 0x45, 0xff, 0x03, 0x8e, 0x4a, 0xff, 0x01, 0x93, 0x4c, 0xff, 0x01, 0x98, 0x51, 0xff, 0x02, 0xa2, 0x5a, 0xff, 0x03, 0xa9, 0x62, 0xff, 0x04, 0xb0, 0x68, 0xff, 0x05, 0xb3, 0x6e, 0xff, 0x06, 0xb6, 0x71, 0xff, 0x09, 0xb8, 0x74, 0xff, 0x08, 0xb8, 0x73, 0xff, 0x08, 0xb7, 0x72, 0xff, 0x09, 0xb7, 0x71, 0xff, 0x0a, 0xb7, 0x71, 0xff, 0x0c, 0xb7, 0x72, 0xff, 0x0b, 0xb7, 0x72, 0xff, 0x12, 0xb3, 0x72, 0xff, 0x1e, 0xa0, 0x8e, 0xff, 0x32, 0x7c, 0xca, 0xff, 0x1f, 0x4e, 0xcd, 0xff, 0x21, 0x41, 0xd3, 0xff, 0x24, 0x41, 0xd3, 0xff, 0x21, 0x40, 0xd2, 0xff, 0x1f, 0x3d, 0xd0, 0xff, 0x1e, 0x3d, 0xca, 0xff, 0x1b, 0x3e, 0xc6, 0xff, 0x1a, 0x3e, 0xc9, 0xff, 0x1a, 0x3b, 0xce, 0xff, 0x1c, 0x38, 0xce, 0xff, 0x26, 0x4c, 0xba, 0xff, 0x1d, 0x44, 0x99, 0xff, 0x03, 0x11, 0x6e, 0xff, 0x0b, 0x1a, 0x8b, 0xff, 0x0f, 0x27, 0x8e, 0xff, 0x03, 0x37, 0x46, 0xff, 0x0a, 0x43, 0x2a, 0xff, 0x06, 0x32, 0x1f, 0xff, 0x0b, 0x38, 0x25, 0xff, 0x03, 0x37, 0x19, 0xff, 0x0e, 0x56, 0x2e, 0xff, 0x1a, 0x66, 0x3e, 0xff, 0x14, 0x4e, 0x30, 0xff, 0x01, 0x24, 0x11, 0xff, 0x01, 0x26, 0x15, 0xff, 0x09, 0x3a, 0x28, 0xff, 0x08, 0x2b, 0x1c, 0xff, 0x62, 0x70, 0x67, 0xff, + 0x05, 0x34, 0x1d, 0xff, 0x02, 0x37, 0x18, 0xff, 0x06, 0x4d, 0x25, 0xff, 0x06, 0x56, 0x2a, 0xff, 0x08, 0x55, 0x2c, 0xff, 0x05, 0x39, 0x1d, 0xff, 0x02, 0x25, 0x12, 0xff, 0x03, 0x24, 0x11, 0xff, 0x03, 0x2a, 0x10, 0xff, 0x08, 0x54, 0x28, 0xff, 0x02, 0x60, 0x2b, 0xff, 0x02, 0x5f, 0x29, 0xff, 0x05, 0x5e, 0x2b, 0xff, 0x09, 0x5b, 0x2d, 0xff, 0x05, 0x43, 0x1f, 0xff, 0x01, 0x25, 0x12, 0xff, 0x02, 0x25, 0x14, 0xff, 0x03, 0x25, 0x15, 0xff, 0x00, 0x25, 0x10, 0xff, 0x04, 0x35, 0x17, 0xff, 0x0d, 0x4c, 0x27, 0xff, 0x07, 0x50, 0x29, 0xff, 0x05, 0x51, 0x2a, 0xff, 0x05, 0x52, 0x28, 0xff, 0x09, 0x51, 0x29, 0xff, 0x04, 0x31, 0x16, 0xff, 0x01, 0x21, 0x0d, 0xff, 0x05, 0x38, 0x1a, 0xff, 0x09, 0x57, 0x2d, 0xff, 0x0d, 0x53, 0x2b, 0xff, 0x03, 0x32, 0x16, 0xff, 0x04, 0x2c, 0x15, 0xff, 0x0a, 0x3a, 0x20, 0xff, 0x05, 0x41, 0x21, 0xff, 0x0b, 0x51, 0x2c, 0xff, 0x09, 0x5a, 0x2c, 0xff, 0x08, 0x5f, 0x2d, 0xff, 0x09, 0x63, 0x2d, 0xff, 0x0a, 0x67, 0x30, 0xff, 0x0a, 0x6b, 0x33, 0xff, 0x0a, 0x6a, 0x2e, 0xff, 0x0a, 0x6c, 0x2c, 0xff, 0x0b, 0x76, 0x35, 0xff, 0x17, 0x84, 0x49, 0xff, 0x04, 0x53, 0x25, 0xff, 0x00, 0x31, 0x13, 0xff, 0x04, 0x34, 0x1f, 0xff, 0x0d, 0x4a, 0x36, 0xff, 0x12, 0x52, 0x37, 0xff, 0x0e, 0x4f, 0x34, 0xff, 0x0a, 0x4e, 0x34, 0xff, 0x0e, 0x5e, 0x39, 0xff, 0x11, 0x6d, 0x38, 0xff, 0x15, 0x79, 0x3d, 0xff, 0x1d, 0x80, 0x46, 0xff, 0x27, 0x7e, 0x49, 0xff, 0x15, 0x69, 0x39, 0xff, 0x23, 0xa1, 0x63, 0xff, 0x1e, 0xb8, 0x6c, 0xff, 0x1c, 0x82, 0x5a, 0xff, 0x43, 0x4b, 0x87, 0xff, 0x73, 0x44, 0xac, 0xff, 0x2a, 0x39, 0x51, 0xff, 0x27, 0x7b, 0x49, 0xff, 0x10, 0x5e, 0x34, 0xff, 0x3f, 0x41, 0x6a, 0xff, 0x53, 0x36, 0x92, 0xff, 0x55, 0x37, 0x92, 0xff, 0x61, 0x3e, 0xaf, 0xff, 0x21, 0x2e, 0x55, 0xff, 0x15, 0x2c, 0x3a, 0xff, 0x1f, 0x34, 0x40, 0xff, 0x15, 0x3d, 0x38, 0xff, 0x18, 0x4d, 0x39, 0xff, 0x13, 0x42, 0x31, 0xff, 0x04, 0x30, 0x26, 0xff, 0x03, 0x3a, 0x27, 0xff, 0x1b, 0x4c, 0x4d, 0xff, 0x25, 0x4e, 0x53, 0xff, 0x11, 0x49, 0x3e, 0xff, 0x02, 0x43, 0x2c, 0xff, 0x13, 0x6e, 0x48, 0xff, 0x05, 0x5c, 0x33, 0xff, 0x01, 0x4a, 0x25, 0xff, 0x01, 0x48, 0x26, 0xff, 0x04, 0x53, 0x2b, 0xff, 0x18, 0x78, 0x4b, 0xff, 0x2c, 0xa7, 0x73, 0xff, 0x1b, 0x8b, 0x59, 0xff, 0x07, 0x5c, 0x30, 0xff, 0x0a, 0x53, 0x2e, 0xff, 0x05, 0x45, 0x25, 0xff, 0x04, 0x49, 0x28, 0xff, 0x10, 0x68, 0x45, 0xff, 0x17, 0x77, 0x53, 0xff, 0x1c, 0x7f, 0x56, 0xff, 0x13, 0x77, 0x4c, 0xff, 0x11, 0x79, 0x4e, 0xff, 0x14, 0x80, 0x55, 0xff, 0x0f, 0x81, 0x55, 0xff, 0x0e, 0x81, 0x55, 0xff, 0x0d, 0x82, 0x55, 0xff, 0x0e, 0x82, 0x55, 0xff, 0x12, 0x84, 0x54, 0xff, 0x11, 0x83, 0x54, 0xff, 0x0e, 0x84, 0x54, 0xff, 0x0d, 0x84, 0x56, 0xff, 0x10, 0x83, 0x57, 0xff, 0x16, 0x82, 0x5b, 0xff, 0x17, 0x7b, 0x56, 0xff, 0x1b, 0x7a, 0x55, 0xff, 0x16, 0x7d, 0x54, 0xff, 0x15, 0x81, 0x56, 0xff, 0x14, 0x84, 0x58, 0xff, 0x12, 0x83, 0x57, 0xff, 0x11, 0x84, 0x58, 0xff, 0x11, 0x82, 0x56, 0xff, 0x12, 0x81, 0x55, 0xff, 0x14, 0x81, 0x55, 0xff, 0x0f, 0x7b, 0x51, 0xff, 0x11, 0x7c, 0x53, 0xff, 0x12, 0x7e, 0x54, 0xff, 0x13, 0x81, 0x57, 0xff, 0x0e, 0x7c, 0x52, 0xff, 0x0e, 0x7c, 0x52, 0xff, 0x0f, 0x7d, 0x53, 0xff, 0x12, 0x7e, 0x54, 0xff, 0x13, 0x80, 0x56, 0xff, 0x13, 0x82, 0x56, 0xff, 0x0f, 0x84, 0x59, 0xff, 0x0b, 0x88, 0x59, 0xff, 0x0a, 0x8b, 0x56, 0xff, 0x1e, 0x9e, 0x64, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x00, 0x77, 0x34, 0xff, 0x02, 0x71, 0x3a, 0xff, 0x0a, 0x78, 0x4a, 0xff, 0x17, 0x8a, 0x5a, 0xff, 0x16, 0x8f, 0x5e, 0xff, 0x0e, 0x8e, 0x5d, 0xff, 0x0c, 0x8d, 0x5c, 0xff, 0x0e, 0x8a, 0x5a, 0xff, 0x13, 0x87, 0x59, 0xff, 0x14, 0x88, 0x59, 0xff, 0x0f, 0x8a, 0x5a, 0xff, 0x08, 0x89, 0x5a, 0xff, 0x0f, 0x88, 0x5c, 0xff, 0x15, 0x71, 0x4c, 0xff, 0x03, 0x40, 0x23, 0xff, 0x03, 0x35, 0x1c, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x02, 0x33, 0x1c, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x04, 0x33, 0x1b, 0xff, 0x02, 0x34, 0x1c, 0xff, 0x01, 0x34, 0x1c, 0xff, 0x03, 0x33, 0x1a, 0xff, 0x01, 0x37, 0x16, 0xff, 0x0c, 0x7b, 0x44, 0xff, 0x1d, 0xb1, 0x67, 0xff, 0x03, 0x8b, 0x3e, 0xff, 0x05, 0x84, 0x43, 0xff, 0x00, 0x81, 0x47, 0xff, 0x05, 0x83, 0x44, 0xff, 0x05, 0x83, 0x3f, 0xff, 0x02, 0x7f, 0x3d, 0xff, 0x06, 0x7b, 0x3a, 0xff, 0x08, 0x7a, 0x38, 0xff, 0x06, 0x78, 0x37, 0xff, 0x05, 0x76, 0x38, 0xff, 0x05, 0x6c, 0x36, 0xff, 0x07, 0x64, 0x34, 0xff, 0x0d, 0x55, 0x2f, 0xff, 0x04, 0x3b, 0x1f, 0xff, 0x01, 0x35, 0x18, 0xff, 0x02, 0x35, 0x17, 0xff, 0x0e, 0x47, 0x28, 0xff, 0x0f, 0x4a, 0x2a, 0xff, 0x01, 0x36, 0x16, 0xff, 0x01, 0x33, 0x16, 0xff, 0x05, 0x32, 0x19, 0xff, 0x05, 0x31, 0x1c, 0xff, 0x02, 0x31, 0x19, 0xff, 0x0b, 0x3f, 0x25, 0xff, 0x0e, 0x48, 0x2a, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x0f, 0x60, 0x3a, 0xff, 0x0e, 0x6a, 0x42, 0xff, 0x07, 0x6c, 0x3d, 0xff, 0x09, 0x71, 0x3c, 0xff, 0x0b, 0x6d, 0x3a, 0xff, 0x06, 0x50, 0x25, 0xff, 0x01, 0x38, 0x18, 0xff, 0x01, 0x3e, 0x21, 0xff, 0x06, 0x41, 0x24, 0xff, 0x08, 0x42, 0x22, 0xff, 0x01, 0x4a, 0x1f, 0xff, 0x0f, 0x7a, 0x46, 0xff, 0x0a, 0x79, 0x44, 0xff, 0x04, 0x68, 0x36, 0xff, 0x0b, 0x6a, 0x3b, 0xff, 0x03, 0x6a, 0x3a, 0xff, 0x05, 0x68, 0x38, 0xff, 0x0b, 0x68, 0x39, 0xff, 0x09, 0x67, 0x38, 0xff, 0x08, 0x67, 0x38, 0xff, 0x04, 0x6a, 0x38, 0xff, 0x01, 0x69, 0x35, 0xff, 0x04, 0x67, 0x36, 0xff, 0x10, 0x63, 0x39, 0xff, 0x04, 0x42, 0x20, 0xff, 0x01, 0x2f, 0x12, 0xff, 0x0d, 0x3f, 0x25, 0xff, 0x0a, 0x48, 0x29, 0xff, 0x07, 0x4b, 0x29, 0xff, 0x05, 0x48, 0x28, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x02, 0x21, 0x0e, 0xff, 0x08, 0x3a, 0x23, 0xff, 0x0b, 0x4a, 0x2c, 0xff, 0x03, 0x3e, 0x1b, 0xff, 0x07, 0x58, 0x2d, 0xff, 0x0f, 0x72, 0x40, 0xff, 0x09, 0x6e, 0x3b, 0xff, 0x03, 0x55, 0x2b, 0xff, 0x08, 0x44, 0x26, 0xff, 0x01, 0x2b, 0x14, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x08, 0x48, 0x2a, 0xff, 0x08, 0x49, 0x2a, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x04, 0x25, 0x12, 0xff, 0x04, 0x26, 0x16, 0xff, 0x02, 0x2b, 0x1a, 0xff, 0x02, 0x34, 0x20, 0xff, 0x0a, 0x3d, 0x26, 0xff, 0x04, 0x32, 0x19, 0xff, 0x06, 0x35, 0x1a, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x0c, 0x53, 0x31, 0xff, 0x0a, 0x5c, 0x33, 0xff, 0x09, 0x5c, 0x30, 0xff, 0x0f, 0x5f, 0x33, 0xff, 0x0e, 0x58, 0x31, 0xff, 0x03, 0x47, 0x24, 0xff, 0x0e, 0x64, 0x39, 0xff, 0x0a, 0x61, 0x34, 0xff, 0x09, 0x5f, 0x33, 0xff, 0x0a, 0x5e, 0x34, 0xff, 0x08, 0x5f, 0x33, 0xff, 0x08, 0x61, 0x35, 0xff, 0x0a, 0x63, 0x35, 0xff, 0x0d, 0x60, 0x32, 0xff, 0x01, 0x40, 0x1d, 0xff, 0x02, 0x27, 0x12, 0xff, 0x03, 0x20, 0x11, 0xff, 0x04, 0x21, 0x13, 0xff, 0x00, 0x1e, 0x0e, 0xff, 0x09, 0x3b, 0x20, 0xff, 0x06, 0x4a, 0x29, 0xff, 0x06, 0x49, 0x24, 0xff, 0x0b, 0x4a, 0x25, 0xff, 0x03, 0x47, 0x22, 0xff, 0x00, 0x46, 0x24, 0xff, 0x00, 0x43, 0x24, 0xff, 0x01, 0x43, 0x21, 0xff, 0x04, 0x54, 0x29, 0xff, 0x12, 0x7a, 0x44, 0xff, 0x09, 0x89, 0x47, 0xff, 0x02, 0x86, 0x41, 0xff, 0x01, 0x8c, 0x46, 0xff, 0x02, 0x93, 0x4d, 0xff, 0x07, 0xa0, 0x5b, 0xff, 0x09, 0xa9, 0x62, 0xff, 0x0b, 0xb1, 0x6b, 0xff, 0x0e, 0xb7, 0x71, 0xff, 0x10, 0xbb, 0x75, 0xff, 0x13, 0xbc, 0x78, 0xff, 0x11, 0xb7, 0x74, 0xff, 0x12, 0xb8, 0x75, 0xff, 0x12, 0xb7, 0x74, 0xff, 0x11, 0xb5, 0x72, 0xff, 0x0f, 0xaf, 0x6c, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x0f, 0xaa, 0x68, 0xff, 0x0f, 0xaa, 0x6a, 0xff, 0x11, 0xa7, 0x66, 0xff, 0x1a, 0x9b, 0x75, 0xff, 0x31, 0x84, 0xb3, 0xff, 0x2a, 0x5c, 0xcd, 0xff, 0x24, 0x40, 0xd6, 0xff, 0x26, 0x41, 0xda, 0xff, 0x22, 0x3f, 0xd8, 0xff, 0x1e, 0x3d, 0xd5, 0xff, 0x1e, 0x40, 0xd0, 0xff, 0x1e, 0x42, 0xcf, 0xff, 0x1d, 0x40, 0xd5, 0xff, 0x1f, 0x3e, 0xd7, 0xff, 0x28, 0x4b, 0xd0, 0xff, 0x27, 0x57, 0xa4, 0xff, 0x0f, 0x3e, 0x79, 0xff, 0x04, 0x1b, 0x71, 0xff, 0x10, 0x21, 0x91, 0xff, 0x18, 0x2e, 0x9d, 0xff, 0x03, 0x36, 0x4d, 0xff, 0x05, 0x3c, 0x26, 0xff, 0x09, 0x33, 0x20, 0xff, 0x0d, 0x38, 0x25, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x0d, 0x54, 0x2c, 0xff, 0x1a, 0x67, 0x3f, 0xff, 0x11, 0x4c, 0x2e, 0xff, 0x00, 0x23, 0x10, 0xff, 0x00, 0x2b, 0x19, 0xff, 0x11, 0x46, 0x33, 0xff, 0x0b, 0x2e, 0x1f, 0xff, 0x62, 0x70, 0x67, 0xff, + 0x03, 0x33, 0x1c, 0xff, 0x02, 0x39, 0x19, 0xff, 0x08, 0x4f, 0x27, 0xff, 0x06, 0x56, 0x29, 0xff, 0x08, 0x56, 0x2c, 0xff, 0x05, 0x3c, 0x1e, 0xff, 0x01, 0x26, 0x12, 0xff, 0x01, 0x24, 0x11, 0xff, 0x02, 0x2a, 0x10, 0xff, 0x08, 0x54, 0x28, 0xff, 0x01, 0x5f, 0x2b, 0xff, 0x03, 0x60, 0x2a, 0xff, 0x04, 0x5f, 0x2b, 0xff, 0x08, 0x5d, 0x2e, 0xff, 0x06, 0x48, 0x23, 0xff, 0x00, 0x26, 0x12, 0xff, 0x02, 0x25, 0x15, 0xff, 0x04, 0x25, 0x15, 0xff, 0x00, 0x25, 0x10, 0xff, 0x05, 0x37, 0x1a, 0xff, 0x0e, 0x4d, 0x29, 0xff, 0x06, 0x50, 0x28, 0xff, 0x06, 0x51, 0x29, 0xff, 0x06, 0x51, 0x28, 0xff, 0x09, 0x50, 0x28, 0xff, 0x04, 0x30, 0x15, 0xff, 0x02, 0x21, 0x0d, 0xff, 0x04, 0x37, 0x18, 0xff, 0x09, 0x57, 0x2c, 0xff, 0x0b, 0x4f, 0x27, 0xff, 0x02, 0x2f, 0x11, 0xff, 0x06, 0x35, 0x1a, 0xff, 0x03, 0x39, 0x1b, 0xff, 0x0c, 0x50, 0x2c, 0xff, 0x0c, 0x56, 0x2e, 0xff, 0x0a, 0x5a, 0x2d, 0xff, 0x0a, 0x5e, 0x2c, 0xff, 0x05, 0x62, 0x2b, 0xff, 0x05, 0x68, 0x2f, 0xff, 0x05, 0x6a, 0x30, 0xff, 0x07, 0x68, 0x2f, 0xff, 0x0d, 0x6f, 0x35, 0xff, 0x16, 0x78, 0x40, 0xff, 0x06, 0x50, 0x22, 0xff, 0x00, 0x34, 0x0f, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x0a, 0x45, 0x2f, 0xff, 0x0c, 0x53, 0x3a, 0xff, 0x10, 0x56, 0x35, 0xff, 0x11, 0x52, 0x33, 0xff, 0x0b, 0x4c, 0x32, 0xff, 0x02, 0x47, 0x27, 0xff, 0x0a, 0x5b, 0x2f, 0xff, 0x11, 0x68, 0x35, 0xff, 0x0f, 0x67, 0x35, 0xff, 0x09, 0x63, 0x30, 0xff, 0x05, 0x5e, 0x29, 0xff, 0x22, 0xb4, 0x6e, 0xff, 0x17, 0xa0, 0x5a, 0xff, 0x3a, 0x5f, 0x6f, 0xff, 0x6e, 0x3a, 0xbd, 0xff, 0x7f, 0x3e, 0xd0, 0xff, 0x45, 0x41, 0x78, 0xff, 0x08, 0x31, 0x1b, 0xff, 0x1f, 0x30, 0x39, 0xff, 0x13, 0x18, 0x37, 0xff, 0x0c, 0x0f, 0x3a, 0xff, 0x2d, 0x1e, 0x58, 0xff, 0x61, 0x47, 0x9b, 0xff, 0x27, 0x20, 0x4b, 0xff, 0x5a, 0x4c, 0x8b, 0xff, 0x37, 0x39, 0x68, 0xff, 0x10, 0x39, 0x25, 0xff, 0x04, 0x35, 0x18, 0xff, 0x07, 0x2e, 0x1f, 0xff, 0x1d, 0x33, 0x41, 0xff, 0x24, 0x3b, 0x4f, 0xff, 0x43, 0x5c, 0x7e, 0xff, 0x42, 0x5b, 0x84, 0xff, 0x22, 0x51, 0x51, 0xff, 0x0f, 0x51, 0x3f, 0xff, 0x05, 0x5b, 0x38, 0xff, 0x03, 0x57, 0x2f, 0xff, 0x0c, 0x58, 0x34, 0xff, 0x08, 0x4b, 0x2c, 0xff, 0x02, 0x41, 0x21, 0xff, 0x0a, 0x56, 0x32, 0xff, 0x1b, 0x7b, 0x4f, 0xff, 0x01, 0x4f, 0x23, 0xff, 0x01, 0x4b, 0x23, 0xff, 0x06, 0x54, 0x30, 0xff, 0x02, 0x53, 0x30, 0xff, 0x0e, 0x6d, 0x48, 0xff, 0x10, 0x7e, 0x57, 0xff, 0x0b, 0x81, 0x57, 0xff, 0x14, 0x80, 0x55, 0xff, 0x15, 0x80, 0x55, 0xff, 0x15, 0x83, 0x58, 0xff, 0x0f, 0x80, 0x54, 0xff, 0x0d, 0x81, 0x55, 0xff, 0x0e, 0x82, 0x56, 0xff, 0x0e, 0x83, 0x56, 0xff, 0x0f, 0x84, 0x56, 0xff, 0x0f, 0x83, 0x56, 0xff, 0x0f, 0x84, 0x56, 0xff, 0x0d, 0x85, 0x56, 0xff, 0x0f, 0x85, 0x58, 0xff, 0x10, 0x84, 0x57, 0xff, 0x11, 0x82, 0x58, 0xff, 0x17, 0x82, 0x5a, 0xff, 0x19, 0x81, 0x59, 0xff, 0x16, 0x82, 0x57, 0xff, 0x14, 0x82, 0x57, 0xff, 0x11, 0x82, 0x56, 0xff, 0x10, 0x83, 0x57, 0xff, 0x10, 0x84, 0x58, 0xff, 0x10, 0x84, 0x57, 0xff, 0x11, 0x82, 0x56, 0xff, 0x13, 0x83, 0x57, 0xff, 0x16, 0x85, 0x5b, 0xff, 0x14, 0x84, 0x5a, 0xff, 0x11, 0x82, 0x58, 0xff, 0x10, 0x83, 0x58, 0xff, 0x12, 0x86, 0x5b, 0xff, 0x12, 0x86, 0x5a, 0xff, 0x14, 0x87, 0x5c, 0xff, 0x16, 0x87, 0x5d, 0xff, 0x19, 0x89, 0x62, 0xff, 0x19, 0x8c, 0x64, 0xff, 0x0f, 0x8b, 0x59, 0xff, 0x0d, 0x90, 0x56, 0xff, 0x16, 0x9c, 0x5c, 0xff, 0x16, 0x99, 0x59, 0xff, 0x01, 0x7a, 0x3d, 0xff, 0x04, 0x7b, 0x41, 0xff, 0x12, 0x8b, 0x59, 0xff, 0x16, 0x90, 0x61, 0xff, 0x15, 0x91, 0x62, 0xff, 0x0f, 0x91, 0x60, 0xff, 0x0c, 0x92, 0x60, 0xff, 0x0b, 0x92, 0x60, 0xff, 0x0f, 0x90, 0x5e, 0xff, 0x15, 0x8e, 0x5e, 0xff, 0x11, 0x8d, 0x5e, 0xff, 0x10, 0x92, 0x61, 0xff, 0x13, 0x8e, 0x60, 0xff, 0x14, 0x7c, 0x53, 0xff, 0x03, 0x45, 0x23, 0xff, 0x05, 0x35, 0x18, 0xff, 0x06, 0x34, 0x1b, 0xff, 0x01, 0x34, 0x1b, 0xff, 0x02, 0x34, 0x1b, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x05, 0x34, 0x1b, 0xff, 0x07, 0x33, 0x1b, 0xff, 0x01, 0x34, 0x19, 0xff, 0x02, 0x56, 0x2e, 0xff, 0x1b, 0xa4, 0x64, 0xff, 0x0f, 0xa2, 0x58, 0xff, 0x01, 0x86, 0x3f, 0xff, 0x03, 0x85, 0x44, 0xff, 0x00, 0x84, 0x45, 0xff, 0x03, 0x83, 0x43, 0xff, 0x07, 0x81, 0x41, 0xff, 0x05, 0x7e, 0x3e, 0xff, 0x06, 0x7c, 0x39, 0xff, 0x07, 0x7b, 0x37, 0xff, 0x06, 0x7a, 0x37, 0xff, 0x09, 0x78, 0x39, 0xff, 0x09, 0x69, 0x35, 0xff, 0x11, 0x62, 0x37, 0xff, 0x07, 0x42, 0x22, 0xff, 0x03, 0x32, 0x18, 0xff, 0x00, 0x34, 0x18, 0xff, 0x00, 0x33, 0x17, 0xff, 0x01, 0x34, 0x17, 0xff, 0x00, 0x33, 0x15, 0xff, 0x00, 0x33, 0x17, 0xff, 0x01, 0x33, 0x18, 0xff, 0x03, 0x32, 0x19, 0xff, 0x06, 0x31, 0x1a, 0xff, 0x02, 0x35, 0x1a, 0xff, 0x0a, 0x45, 0x27, 0xff, 0x01, 0x3b, 0x1a, 0xff, 0x0a, 0x55, 0x31, 0xff, 0x15, 0x6e, 0x46, 0xff, 0x0c, 0x6e, 0x44, 0xff, 0x07, 0x70, 0x40, 0xff, 0x09, 0x76, 0x41, 0xff, 0x06, 0x6b, 0x38, 0xff, 0x05, 0x4e, 0x23, 0xff, 0x04, 0x37, 0x17, 0xff, 0x04, 0x3a, 0x1e, 0xff, 0x05, 0x41, 0x24, 0xff, 0x04, 0x44, 0x22, 0xff, 0x00, 0x44, 0x1a, 0xff, 0x07, 0x63, 0x33, 0xff, 0x0c, 0x80, 0x4b, 0xff, 0x03, 0x6a, 0x38, 0xff, 0x0a, 0x67, 0x38, 0xff, 0x02, 0x6a, 0x39, 0xff, 0x05, 0x68, 0x38, 0xff, 0x0a, 0x68, 0x39, 0xff, 0x03, 0x69, 0x39, 0xff, 0x03, 0x67, 0x37, 0xff, 0x06, 0x69, 0x39, 0xff, 0x06, 0x69, 0x36, 0xff, 0x04, 0x65, 0x35, 0xff, 0x0b, 0x64, 0x38, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x01, 0x32, 0x13, 0xff, 0x09, 0x3a, 0x1e, 0xff, 0x09, 0x46, 0x26, 0xff, 0x0a, 0x4a, 0x29, 0xff, 0x08, 0x48, 0x28, 0xff, 0x03, 0x33, 0x1a, 0xff, 0x02, 0x23, 0x0f, 0xff, 0x06, 0x38, 0x20, 0xff, 0x0a, 0x4a, 0x2c, 0xff, 0x06, 0x44, 0x21, 0xff, 0x02, 0x49, 0x23, 0xff, 0x10, 0x6e, 0x40, 0xff, 0x0b, 0x70, 0x3e, 0xff, 0x09, 0x64, 0x35, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x05, 0x36, 0x1b, 0xff, 0x00, 0x2d, 0x12, 0xff, 0x05, 0x3d, 0x21, 0xff, 0x0d, 0x4a, 0x2c, 0xff, 0x08, 0x3b, 0x21, 0xff, 0x04, 0x2e, 0x18, 0xff, 0x01, 0x28, 0x14, 0xff, 0x03, 0x2b, 0x18, 0xff, 0x04, 0x32, 0x1c, 0xff, 0x0a, 0x3b, 0x23, 0xff, 0x03, 0x32, 0x18, 0xff, 0x08, 0x39, 0x1d, 0xff, 0x02, 0x39, 0x1b, 0xff, 0x08, 0x4d, 0x2b, 0xff, 0x0c, 0x5b, 0x33, 0xff, 0x0a, 0x5d, 0x31, 0xff, 0x0e, 0x5e, 0x32, 0xff, 0x11, 0x5c, 0x34, 0xff, 0x01, 0x42, 0x20, 0xff, 0x0b, 0x5d, 0x34, 0xff, 0x0a, 0x61, 0x35, 0xff, 0x08, 0x5d, 0x32, 0xff, 0x09, 0x5d, 0x33, 0xff, 0x08, 0x5f, 0x33, 0xff, 0x08, 0x60, 0x34, 0xff, 0x09, 0x62, 0x34, 0xff, 0x0e, 0x61, 0x34, 0xff, 0x04, 0x47, 0x25, 0xff, 0x03, 0x2b, 0x15, 0xff, 0x02, 0x20, 0x11, 0xff, 0x01, 0x1f, 0x11, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x09, 0x3c, 0x20, 0xff, 0x04, 0x49, 0x27, 0xff, 0x04, 0x47, 0x23, 0xff, 0x08, 0x47, 0x26, 0xff, 0x05, 0x46, 0x24, 0xff, 0x05, 0x44, 0x23, 0xff, 0x02, 0x41, 0x1d, 0xff, 0x03, 0x4e, 0x25, 0xff, 0x08, 0x7a, 0x45, 0xff, 0x05, 0x86, 0x48, 0xff, 0x03, 0x8e, 0x4a, 0xff, 0x0c, 0xa0, 0x5a, 0xff, 0x16, 0xb2, 0x6c, 0xff, 0x22, 0xbd, 0x76, 0xff, 0x2b, 0xc0, 0x7d, 0xff, 0x2a, 0xba, 0x78, 0xff, 0x21, 0xa9, 0x6b, 0xff, 0x17, 0x9a, 0x5b, 0xff, 0x0c, 0x8a, 0x4e, 0xff, 0x09, 0x83, 0x47, 0xff, 0x06, 0x7d, 0x41, 0xff, 0x06, 0x7c, 0x40, 0xff, 0x04, 0x77, 0x3e, 0xff, 0x03, 0x73, 0x3a, 0xff, 0x02, 0x6e, 0x37, 0xff, 0x02, 0x6a, 0x34, 0xff, 0x02, 0x65, 0x32, 0xff, 0x02, 0x68, 0x37, 0xff, 0x02, 0x68, 0x36, 0xff, 0x03, 0x5f, 0x35, 0xff, 0x2b, 0x74, 0x83, 0xff, 0x46, 0x73, 0xce, 0xff, 0x2a, 0x43, 0xd9, 0xff, 0x26, 0x40, 0xdd, 0xff, 0x24, 0x43, 0xdc, 0xff, 0x25, 0x45, 0xde, 0xff, 0x25, 0x46, 0xda, 0xff, 0x24, 0x42, 0xd8, 0xff, 0x28, 0x43, 0xdd, 0xff, 0x2f, 0x50, 0xd4, 0xff, 0x24, 0x56, 0xa1, 0xff, 0x16, 0x59, 0x6b, 0xff, 0x0e, 0x42, 0x6d, 0xff, 0x05, 0x22, 0x7c, 0xff, 0x12, 0x29, 0x98, 0xff, 0x1c, 0x35, 0xa8, 0xff, 0x09, 0x39, 0x5b, 0xff, 0x00, 0x33, 0x1e, 0xff, 0x10, 0x3c, 0x26, 0xff, 0x09, 0x30, 0x1f, 0xff, 0x02, 0x29, 0x13, 0xff, 0x16, 0x5c, 0x37, 0xff, 0x17, 0x66, 0x3e, 0xff, 0x0b, 0x47, 0x28, 0xff, 0x01, 0x24, 0x0f, 0xff, 0x09, 0x39, 0x25, 0xff, 0x17, 0x50, 0x3b, 0xff, 0x0c, 0x30, 0x21, 0xff, 0x61, 0x70, 0x66, 0xff, + 0x03, 0x33, 0x1c, 0xff, 0x02, 0x3b, 0x1b, 0xff, 0x09, 0x51, 0x28, 0xff, 0x07, 0x56, 0x2a, 0xff, 0x07, 0x56, 0x2b, 0xff, 0x04, 0x3d, 0x1e, 0xff, 0x00, 0x27, 0x12, 0xff, 0x02, 0x24, 0x12, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x06, 0x52, 0x28, 0xff, 0x02, 0x5f, 0x2c, 0xff, 0x03, 0x60, 0x2a, 0xff, 0x03, 0x5f, 0x2b, 0xff, 0x07, 0x5d, 0x2e, 0xff, 0x08, 0x4c, 0x27, 0xff, 0x00, 0x28, 0x12, 0xff, 0x01, 0x24, 0x14, 0xff, 0x04, 0x25, 0x15, 0xff, 0x00, 0x24, 0x10, 0xff, 0x06, 0x38, 0x1b, 0xff, 0x0e, 0x4e, 0x29, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x07, 0x50, 0x29, 0xff, 0x08, 0x51, 0x29, 0xff, 0x0a, 0x50, 0x28, 0xff, 0x03, 0x2e, 0x14, 0xff, 0x02, 0x20, 0x0d, 0xff, 0x04, 0x36, 0x18, 0xff, 0x09, 0x56, 0x2c, 0xff, 0x09, 0x4c, 0x25, 0xff, 0x01, 0x2f, 0x11, 0xff, 0x03, 0x34, 0x16, 0xff, 0x04, 0x41, 0x20, 0xff, 0x0a, 0x54, 0x2e, 0xff, 0x08, 0x57, 0x2d, 0xff, 0x0b, 0x5a, 0x2d, 0xff, 0x0b, 0x5e, 0x2b, 0xff, 0x04, 0x62, 0x2b, 0xff, 0x03, 0x69, 0x2e, 0xff, 0x06, 0x6b, 0x30, 0xff, 0x05, 0x6a, 0x31, 0xff, 0x14, 0x73, 0x3f, 0xff, 0x0f, 0x5f, 0x31, 0xff, 0x01, 0x36, 0x12, 0xff, 0x01, 0x30, 0x13, 0xff, 0x08, 0x3e, 0x24, 0xff, 0x10, 0x50, 0x38, 0xff, 0x0b, 0x54, 0x39, 0xff, 0x0b, 0x57, 0x33, 0xff, 0x0f, 0x54, 0x34, 0xff, 0x0c, 0x4a, 0x32, 0xff, 0x08, 0x43, 0x2a, 0xff, 0x02, 0x44, 0x1d, 0xff, 0x08, 0x5b, 0x28, 0xff, 0x08, 0x65, 0x2e, 0xff, 0x0e, 0x74, 0x37, 0xff, 0x04, 0x66, 0x2d, 0xff, 0x20, 0xb2, 0x68, 0xff, 0x0e, 0x81, 0x41, 0xff, 0x53, 0x5c, 0x87, 0xff, 0x77, 0x32, 0xc9, 0xff, 0x7d, 0x40, 0xd0, 0xff, 0x43, 0x38, 0x75, 0xff, 0x32, 0x32, 0x4a, 0xff, 0x70, 0x57, 0x9d, 0xff, 0x38, 0x30, 0x69, 0xff, 0x0d, 0x15, 0x2c, 0xff, 0x14, 0x16, 0x2a, 0xff, 0x2b, 0x29, 0x49, 0xff, 0x20, 0x1d, 0x33, 0xff, 0x70, 0x5a, 0x9f, 0xff, 0x44, 0x46, 0x7e, 0xff, 0x0f, 0x3a, 0x22, 0xff, 0x01, 0x2d, 0x0c, 0xff, 0x0c, 0x2d, 0x1f, 0xff, 0x58, 0x5d, 0x84, 0xff, 0x4d, 0x50, 0x80, 0xff, 0x43, 0x51, 0x7d, 0xff, 0x41, 0x54, 0x83, 0xff, 0x1f, 0x4b, 0x53, 0xff, 0x1b, 0x5c, 0x50, 0xff, 0x0f, 0x66, 0x45, 0xff, 0x0b, 0x65, 0x3e, 0xff, 0x14, 0x66, 0x42, 0xff, 0x14, 0x5e, 0x3f, 0xff, 0x09, 0x50, 0x32, 0xff, 0x01, 0x47, 0x26, 0xff, 0x04, 0x50, 0x29, 0xff, 0x05, 0x54, 0x2c, 0xff, 0x0e, 0x67, 0x40, 0xff, 0x12, 0x73, 0x4b, 0xff, 0x0d, 0x75, 0x4e, 0xff, 0x0d, 0x7b, 0x53, 0xff, 0x0e, 0x80, 0x58, 0xff, 0x0d, 0x82, 0x58, 0xff, 0x12, 0x82, 0x56, 0xff, 0x10, 0x80, 0x54, 0xff, 0x11, 0x84, 0x58, 0xff, 0x0e, 0x82, 0x56, 0xff, 0x0e, 0x83, 0x56, 0xff, 0x0e, 0x83, 0x56, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x0f, 0x85, 0x58, 0xff, 0x0e, 0x85, 0x58, 0xff, 0x0d, 0x84, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x10, 0x83, 0x58, 0xff, 0x12, 0x83, 0x58, 0xff, 0x13, 0x83, 0x58, 0xff, 0x13, 0x83, 0x57, 0xff, 0x13, 0x84, 0x58, 0xff, 0x11, 0x84, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x0e, 0x85, 0x58, 0xff, 0x0f, 0x85, 0x58, 0xff, 0x10, 0x85, 0x58, 0xff, 0x11, 0x85, 0x58, 0xff, 0x13, 0x86, 0x5b, 0xff, 0x13, 0x87, 0x5c, 0xff, 0x12, 0x88, 0x5d, 0xff, 0x10, 0x88, 0x5c, 0xff, 0x12, 0x8a, 0x5e, 0xff, 0x12, 0x8a, 0x5e, 0xff, 0x13, 0x8b, 0x5e, 0xff, 0x15, 0x8b, 0x60, 0xff, 0x16, 0x8b, 0x66, 0xff, 0x16, 0x8e, 0x67, 0xff, 0x10, 0x91, 0x5c, 0xff, 0x17, 0x9e, 0x5f, 0xff, 0x14, 0x9d, 0x59, 0xff, 0x06, 0x8a, 0x48, 0xff, 0x06, 0x84, 0x4a, 0xff, 0x11, 0x8a, 0x57, 0xff, 0x13, 0x92, 0x62, 0xff, 0x11, 0x90, 0x62, 0xff, 0x15, 0x91, 0x63, 0xff, 0x14, 0x91, 0x63, 0xff, 0x11, 0x91, 0x61, 0xff, 0x0e, 0x92, 0x60, 0xff, 0x0e, 0x91, 0x60, 0xff, 0x11, 0x91, 0x60, 0xff, 0x10, 0x91, 0x62, 0xff, 0x14, 0x8f, 0x62, 0xff, 0x1a, 0x80, 0x58, 0xff, 0x0a, 0x57, 0x34, 0xff, 0x03, 0x35, 0x17, 0xff, 0x09, 0x34, 0x19, 0xff, 0x07, 0x33, 0x19, 0xff, 0x03, 0x33, 0x19, 0xff, 0x02, 0x33, 0x1c, 0xff, 0x03, 0x32, 0x1c, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x01, 0x34, 0x1b, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x00, 0x35, 0x1a, 0xff, 0x03, 0x33, 0x18, 0xff, 0x07, 0x39, 0x1d, 0xff, 0x0f, 0x51, 0x32, 0xff, 0x0a, 0x76, 0x47, 0xff, 0x19, 0xb0, 0x6b, 0xff, 0x07, 0x97, 0x4e, 0xff, 0x01, 0x85, 0x42, 0xff, 0x02, 0x85, 0x43, 0xff, 0x00, 0x85, 0x42, 0xff, 0x02, 0x84, 0x42, 0xff, 0x08, 0x80, 0x42, 0xff, 0x07, 0x7e, 0x3e, 0xff, 0x05, 0x7d, 0x39, 0xff, 0x03, 0x7c, 0x36, 0xff, 0x04, 0x79, 0x35, 0xff, 0x08, 0x76, 0x37, 0xff, 0x0d, 0x68, 0x36, 0xff, 0x10, 0x59, 0x32, 0xff, 0x02, 0x36, 0x19, 0xff, 0x07, 0x33, 0x1b, 0xff, 0x02, 0x31, 0x17, 0xff, 0x01, 0x33, 0x19, 0xff, 0x01, 0x33, 0x19, 0xff, 0x00, 0x32, 0x17, 0xff, 0x00, 0x32, 0x19, 0xff, 0x02, 0x32, 0x1a, 0xff, 0x03, 0x31, 0x18, 0xff, 0x05, 0x34, 0x19, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x04, 0x46, 0x25, 0xff, 0x05, 0x4a, 0x26, 0xff, 0x11, 0x65, 0x3e, 0xff, 0x13, 0x70, 0x47, 0xff, 0x0c, 0x72, 0x45, 0xff, 0x05, 0x71, 0x40, 0xff, 0x09, 0x78, 0x42, 0xff, 0x05, 0x69, 0x35, 0xff, 0x07, 0x52, 0x26, 0xff, 0x06, 0x3b, 0x1a, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x06, 0x40, 0x23, 0xff, 0x04, 0x45, 0x23, 0xff, 0x00, 0x43, 0x1a, 0xff, 0x02, 0x53, 0x26, 0xff, 0x0d, 0x81, 0x4e, 0xff, 0x03, 0x6d, 0x3b, 0xff, 0x0b, 0x68, 0x39, 0xff, 0x03, 0x69, 0x38, 0xff, 0x05, 0x68, 0x38, 0xff, 0x07, 0x68, 0x39, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x01, 0x68, 0x37, 0xff, 0x07, 0x68, 0x38, 0xff, 0x09, 0x68, 0x37, 0xff, 0x05, 0x64, 0x36, 0xff, 0x09, 0x64, 0x38, 0xff, 0x0d, 0x5a, 0x34, 0xff, 0x03, 0x3a, 0x1a, 0xff, 0x03, 0x32, 0x15, 0xff, 0x08, 0x42, 0x23, 0xff, 0x0b, 0x47, 0x28, 0xff, 0x0a, 0x47, 0x28, 0xff, 0x06, 0x36, 0x1d, 0xff, 0x02, 0x24, 0x10, 0xff, 0x05, 0x35, 0x1d, 0xff, 0x09, 0x49, 0x2b, 0xff, 0x0a, 0x48, 0x27, 0xff, 0x01, 0x42, 0x20, 0xff, 0x0f, 0x68, 0x3d, 0xff, 0x0d, 0x72, 0x40, 0xff, 0x0a, 0x6b, 0x39, 0xff, 0x08, 0x57, 0x2e, 0xff, 0x06, 0x3f, 0x21, 0xff, 0x01, 0x2d, 0x12, 0xff, 0x03, 0x33, 0x1a, 0xff, 0x0e, 0x47, 0x2b, 0xff, 0x0c, 0x42, 0x27, 0xff, 0x06, 0x38, 0x20, 0xff, 0x01, 0x2c, 0x16, 0xff, 0x01, 0x2a, 0x15, 0xff, 0x05, 0x30, 0x1a, 0xff, 0x0a, 0x3a, 0x22, 0xff, 0x02, 0x32, 0x18, 0xff, 0x0a, 0x3d, 0x21, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x07, 0x49, 0x29, 0xff, 0x0e, 0x5b, 0x34, 0xff, 0x0b, 0x5c, 0x32, 0xff, 0x0e, 0x5d, 0x32, 0xff, 0x12, 0x5c, 0x36, 0xff, 0x02, 0x42, 0x21, 0xff, 0x09, 0x57, 0x2e, 0xff, 0x0b, 0x60, 0x34, 0xff, 0x08, 0x5d, 0x32, 0xff, 0x08, 0x5d, 0x33, 0xff, 0x09, 0x5f, 0x33, 0xff, 0x08, 0x5f, 0x33, 0xff, 0x0b, 0x63, 0x35, 0xff, 0x0d, 0x60, 0x34, 0xff, 0x07, 0x4c, 0x29, 0xff, 0x03, 0x2e, 0x16, 0xff, 0x02, 0x22, 0x11, 0xff, 0x00, 0x1f, 0x10, 0xff, 0x00, 0x1f, 0x0d, 0xff, 0x0a, 0x3d, 0x21, 0xff, 0x04, 0x48, 0x27, 0xff, 0x04, 0x46, 0x23, 0xff, 0x02, 0x44, 0x25, 0xff, 0x05, 0x43, 0x24, 0xff, 0x05, 0x40, 0x1f, 0xff, 0x03, 0x48, 0x20, 0xff, 0x09, 0x68, 0x37, 0xff, 0x06, 0x88, 0x4c, 0xff, 0x0c, 0x98, 0x58, 0xff, 0x1e, 0xb0, 0x6c, 0xff, 0x26, 0xb8, 0x74, 0xff, 0x22, 0xb1, 0x6e, 0xff, 0x1d, 0xa5, 0x64, 0xff, 0x13, 0x8f, 0x51, 0xff, 0x0d, 0x7d, 0x42, 0xff, 0x0a, 0x6e, 0x36, 0xff, 0x05, 0x63, 0x2d, 0xff, 0x01, 0x5a, 0x27, 0xff, 0x01, 0x5a, 0x24, 0xff, 0x00, 0x58, 0x23, 0xff, 0x02, 0x57, 0x25, 0xff, 0x04, 0x55, 0x25, 0xff, 0x04, 0x51, 0x24, 0xff, 0x07, 0x4e, 0x24, 0xff, 0x06, 0x4b, 0x23, 0xff, 0x04, 0x46, 0x1f, 0xff, 0x03, 0x44, 0x23, 0xff, 0x01, 0x3f, 0x1e, 0xff, 0x00, 0x3b, 0x17, 0xff, 0x14, 0x4f, 0x4f, 0xff, 0x4e, 0x79, 0xc0, 0xff, 0x32, 0x4e, 0xdc, 0xff, 0x25, 0x42, 0xdf, 0xff, 0x22, 0x48, 0xdf, 0xff, 0x25, 0x48, 0xe0, 0xff, 0x2a, 0x48, 0xdd, 0xff, 0x2c, 0x46, 0xda, 0xff, 0x34, 0x4f, 0xd6, 0xff, 0x2f, 0x59, 0xb4, 0xff, 0x0f, 0x4f, 0x66, 0xff, 0x17, 0x65, 0x51, 0xff, 0x0a, 0x40, 0x65, 0xff, 0x09, 0x27, 0x8a, 0xff, 0x14, 0x30, 0xa2, 0xff, 0x19, 0x36, 0xae, 0xff, 0x0a, 0x38, 0x63, 0xff, 0x03, 0x34, 0x20, 0xff, 0x12, 0x3e, 0x26, 0xff, 0x03, 0x27, 0x16, 0xff, 0x04, 0x2f, 0x1a, 0xff, 0x1a, 0x60, 0x3c, 0xff, 0x15, 0x66, 0x3c, 0xff, 0x09, 0x44, 0x23, 0xff, 0x08, 0x2f, 0x1a, 0xff, 0x0e, 0x3f, 0x2c, 0xff, 0x15, 0x4e, 0x39, 0xff, 0x0d, 0x32, 0x22, 0xff, 0x61, 0x6f, 0x65, 0xff, + 0x02, 0x33, 0x1c, 0xff, 0x04, 0x3e, 0x1e, 0xff, 0x09, 0x51, 0x29, 0xff, 0x08, 0x56, 0x2a, 0xff, 0x07, 0x55, 0x2a, 0xff, 0x03, 0x3f, 0x1e, 0xff, 0x00, 0x28, 0x12, 0xff, 0x02, 0x25, 0x14, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x06, 0x50, 0x28, 0xff, 0x03, 0x5f, 0x2d, 0xff, 0x02, 0x5f, 0x29, 0xff, 0x02, 0x5f, 0x2a, 0xff, 0x05, 0x5e, 0x2c, 0xff, 0x09, 0x50, 0x29, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x01, 0x24, 0x11, 0xff, 0x03, 0x24, 0x14, 0xff, 0x00, 0x24, 0x10, 0xff, 0x06, 0x3a, 0x1d, 0xff, 0x0d, 0x4e, 0x2a, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x07, 0x4f, 0x28, 0xff, 0x09, 0x51, 0x29, 0xff, 0x0b, 0x50, 0x29, 0xff, 0x03, 0x2c, 0x12, 0xff, 0x02, 0x1e, 0x0b, 0xff, 0x05, 0x34, 0x16, 0xff, 0x0c, 0x56, 0x2d, 0xff, 0x09, 0x4a, 0x24, 0xff, 0x02, 0x31, 0x12, 0xff, 0x02, 0x36, 0x16, 0xff, 0x0b, 0x4f, 0x2b, 0xff, 0x05, 0x56, 0x2c, 0xff, 0x05, 0x58, 0x2c, 0xff, 0x0c, 0x5d, 0x2d, 0xff, 0x0b, 0x5f, 0x2b, 0xff, 0x05, 0x65, 0x2d, 0xff, 0x05, 0x6a, 0x30, 0xff, 0x08, 0x6a, 0x2f, 0xff, 0x08, 0x6e, 0x37, 0xff, 0x0d, 0x60, 0x34, 0xff, 0x03, 0x3a, 0x18, 0xff, 0x04, 0x30, 0x16, 0xff, 0x02, 0x32, 0x1b, 0xff, 0x11, 0x4e, 0x35, 0xff, 0x11, 0x52, 0x3b, 0xff, 0x0e, 0x53, 0x37, 0xff, 0x07, 0x54, 0x31, 0xff, 0x07, 0x50, 0x32, 0xff, 0x0b, 0x45, 0x32, 0xff, 0x0c, 0x3d, 0x27, 0xff, 0x02, 0x3b, 0x16, 0xff, 0x05, 0x5c, 0x22, 0xff, 0x17, 0x89, 0x45, 0xff, 0x0c, 0x87, 0x3b, 0xff, 0x02, 0x6d, 0x29, 0xff, 0x1d, 0xa6, 0x59, 0xff, 0x10, 0x67, 0x37, 0xff, 0x5c, 0x55, 0x93, 0xff, 0x83, 0x40, 0xcf, 0xff, 0x7b, 0x48, 0xbb, 0xff, 0x36, 0x26, 0x59, 0xff, 0x7b, 0x58, 0xa0, 0xff, 0x8f, 0x52, 0xd4, 0xff, 0x62, 0x38, 0xaa, 0xff, 0x2f, 0x28, 0x53, 0xff, 0x05, 0x19, 0x0b, 0xff, 0x05, 0x1f, 0x07, 0xff, 0x16, 0x24, 0x1d, 0xff, 0x38, 0x37, 0x5d, 0xff, 0x2b, 0x4b, 0x56, 0xff, 0x0a, 0x3e, 0x1c, 0xff, 0x08, 0x34, 0x17, 0xff, 0x1f, 0x38, 0x37, 0xff, 0x73, 0x6b, 0xab, 0xff, 0x4e, 0x49, 0x83, 0xff, 0x36, 0x3e, 0x65, 0xff, 0x33, 0x47, 0x67, 0xff, 0x21, 0x4e, 0x5b, 0xff, 0x26, 0x66, 0x61, 0xff, 0x13, 0x6d, 0x4f, 0xff, 0x0a, 0x6c, 0x46, 0xff, 0x0b, 0x69, 0x43, 0xff, 0x0f, 0x67, 0x45, 0xff, 0x0d, 0x64, 0x43, 0xff, 0x06, 0x5a, 0x38, 0xff, 0x08, 0x5f, 0x39, 0xff, 0x17, 0x75, 0x4e, 0xff, 0x18, 0x7c, 0x53, 0xff, 0x14, 0x7e, 0x55, 0xff, 0x11, 0x81, 0x56, 0xff, 0x0d, 0x80, 0x55, 0xff, 0x0e, 0x81, 0x56, 0xff, 0x0d, 0x81, 0x55, 0xff, 0x0f, 0x82, 0x56, 0xff, 0x0f, 0x83, 0x56, 0xff, 0x10, 0x85, 0x58, 0xff, 0x0e, 0x84, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x10, 0x83, 0x57, 0xff, 0x10, 0x83, 0x57, 0xff, 0x0c, 0x85, 0x57, 0xff, 0x0d, 0x84, 0x57, 0xff, 0x0e, 0x83, 0x56, 0xff, 0x10, 0x83, 0x57, 0xff, 0x10, 0x83, 0x57, 0xff, 0x0f, 0x84, 0x57, 0xff, 0x0e, 0x84, 0x58, 0xff, 0x0d, 0x85, 0x58, 0xff, 0x0f, 0x84, 0x58, 0xff, 0x10, 0x85, 0x58, 0xff, 0x0f, 0x86, 0x59, 0xff, 0x0e, 0x87, 0x59, 0xff, 0x0e, 0x89, 0x5b, 0xff, 0x0d, 0x88, 0x5a, 0xff, 0x11, 0x8a, 0x5c, 0xff, 0x11, 0x89, 0x5c, 0xff, 0x11, 0x89, 0x5d, 0xff, 0x11, 0x8c, 0x5e, 0xff, 0x12, 0x8e, 0x5f, 0xff, 0x0e, 0x8c, 0x5e, 0xff, 0x0e, 0x8d, 0x5e, 0xff, 0x0e, 0x8d, 0x5e, 0xff, 0x10, 0x8e, 0x60, 0xff, 0x12, 0x8e, 0x61, 0xff, 0x11, 0x8b, 0x65, 0xff, 0x10, 0x8e, 0x65, 0xff, 0x0f, 0x94, 0x5f, 0xff, 0x13, 0x9d, 0x60, 0xff, 0x06, 0x8f, 0x4d, 0xff, 0x07, 0x8d, 0x4f, 0xff, 0x13, 0x93, 0x5d, 0xff, 0x17, 0x92, 0x63, 0xff, 0x0e, 0x8f, 0x63, 0xff, 0x10, 0x92, 0x65, 0xff, 0x15, 0x91, 0x63, 0xff, 0x17, 0x91, 0x63, 0xff, 0x15, 0x92, 0x64, 0xff, 0x10, 0x93, 0x64, 0xff, 0x0e, 0x94, 0x63, 0xff, 0x0e, 0x96, 0x63, 0xff, 0x14, 0x94, 0x67, 0xff, 0x1a, 0x86, 0x60, 0xff, 0x0b, 0x53, 0x33, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x08, 0x34, 0x19, 0xff, 0x05, 0x34, 0x19, 0xff, 0x03, 0x32, 0x19, 0xff, 0x07, 0x32, 0x1b, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x00, 0x33, 0x1c, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x05, 0x33, 0x1a, 0xff, 0x02, 0x32, 0x18, 0xff, 0x00, 0x34, 0x18, 0xff, 0x01, 0x45, 0x24, 0xff, 0x0a, 0x61, 0x3e, 0xff, 0x1e, 0x7e, 0x58, 0xff, 0x0d, 0x8f, 0x59, 0xff, 0x10, 0xb2, 0x67, 0xff, 0x03, 0x8f, 0x47, 0xff, 0x03, 0x83, 0x46, 0xff, 0x03, 0x85, 0x44, 0xff, 0x00, 0x86, 0x40, 0xff, 0x03, 0x84, 0x41, 0xff, 0x0a, 0x80, 0x44, 0xff, 0x08, 0x7f, 0x40, 0xff, 0x04, 0x7f, 0x3b, 0xff, 0x01, 0x7c, 0x37, 0xff, 0x03, 0x7a, 0x36, 0xff, 0x08, 0x71, 0x36, 0xff, 0x0f, 0x63, 0x35, 0xff, 0x06, 0x45, 0x22, 0xff, 0x01, 0x32, 0x17, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x08, 0x31, 0x1a, 0xff, 0x06, 0x31, 0x1a, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x01, 0x31, 0x1b, 0xff, 0x05, 0x31, 0x1b, 0xff, 0x05, 0x31, 0x18, 0xff, 0x00, 0x34, 0x16, 0xff, 0x09, 0x4e, 0x2c, 0xff, 0x0f, 0x5e, 0x39, 0xff, 0x10, 0x68, 0x41, 0xff, 0x13, 0x6e, 0x46, 0xff, 0x0f, 0x70, 0x44, 0xff, 0x0b, 0x71, 0x44, 0xff, 0x06, 0x72, 0x42, 0xff, 0x0b, 0x78, 0x43, 0xff, 0x06, 0x65, 0x32, 0xff, 0x0b, 0x5a, 0x2e, 0xff, 0x07, 0x46, 0x23, 0xff, 0x00, 0x36, 0x18, 0xff, 0x06, 0x3b, 0x1e, 0xff, 0x07, 0x45, 0x23, 0xff, 0x01, 0x46, 0x1d, 0xff, 0x01, 0x45, 0x1b, 0xff, 0x0d, 0x7a, 0x4a, 0xff, 0x07, 0x74, 0x42, 0xff, 0x08, 0x68, 0x37, 0xff, 0x06, 0x68, 0x37, 0xff, 0x04, 0x68, 0x38, 0xff, 0x03, 0x69, 0x38, 0xff, 0x00, 0x6a, 0x39, 0xff, 0x01, 0x69, 0x37, 0xff, 0x07, 0x67, 0x38, 0xff, 0x0b, 0x66, 0x38, 0xff, 0x07, 0x64, 0x36, 0xff, 0x04, 0x64, 0x37, 0xff, 0x0d, 0x61, 0x38, 0xff, 0x08, 0x47, 0x25, 0xff, 0x01, 0x2b, 0x0d, 0xff, 0x04, 0x3b, 0x1d, 0xff, 0x0c, 0x42, 0x25, 0xff, 0x0b, 0x45, 0x27, 0xff, 0x08, 0x38, 0x20, 0xff, 0x02, 0x24, 0x10, 0xff, 0x05, 0x34, 0x1c, 0xff, 0x08, 0x47, 0x29, 0xff, 0x0a, 0x4b, 0x2a, 0xff, 0x03, 0x40, 0x20, 0xff, 0x0a, 0x5b, 0x33, 0xff, 0x0f, 0x72, 0x40, 0xff, 0x09, 0x6f, 0x3b, 0xff, 0x0b, 0x64, 0x35, 0xff, 0x08, 0x49, 0x27, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x01, 0x2a, 0x14, 0xff, 0x0b, 0x3f, 0x24, 0xff, 0x0f, 0x48, 0x2a, 0xff, 0x07, 0x40, 0x24, 0xff, 0x02, 0x34, 0x1c, 0xff, 0x01, 0x28, 0x13, 0xff, 0x07, 0x2d, 0x17, 0xff, 0x0b, 0x38, 0x1f, 0xff, 0x03, 0x33, 0x18, 0xff, 0x0b, 0x40, 0x23, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x06, 0x45, 0x26, 0xff, 0x0e, 0x58, 0x33, 0xff, 0x0b, 0x5b, 0x31, 0xff, 0x0c, 0x5c, 0x32, 0xff, 0x10, 0x5a, 0x35, 0xff, 0x03, 0x44, 0x24, 0xff, 0x08, 0x51, 0x2a, 0xff, 0x0c, 0x5e, 0x34, 0xff, 0x09, 0x5d, 0x33, 0xff, 0x08, 0x5c, 0x32, 0xff, 0x09, 0x5d, 0x33, 0xff, 0x0b, 0x5e, 0x32, 0xff, 0x0c, 0x61, 0x35, 0xff, 0x0c, 0x61, 0x36, 0xff, 0x0b, 0x54, 0x2f, 0xff, 0x03, 0x32, 0x18, 0xff, 0x02, 0x25, 0x14, 0xff, 0x00, 0x1f, 0x10, 0xff, 0x00, 0x1f, 0x0d, 0xff, 0x0a, 0x3c, 0x22, 0xff, 0x04, 0x47, 0x27, 0xff, 0x03, 0x45, 0x24, 0xff, 0x01, 0x42, 0x25, 0xff, 0x04, 0x40, 0x22, 0xff, 0x02, 0x43, 0x1f, 0xff, 0x07, 0x64, 0x34, 0xff, 0x0b, 0x84, 0x4a, 0xff, 0x20, 0xab, 0x6a, 0xff, 0x2c, 0xb6, 0x74, 0xff, 0x1e, 0x9e, 0x5e, 0xff, 0x14, 0x81, 0x45, 0xff, 0x08, 0x66, 0x2d, 0xff, 0x02, 0x5e, 0x25, 0xff, 0x00, 0x56, 0x1f, 0xff, 0x00, 0x53, 0x1f, 0xff, 0x01, 0x54, 0x20, 0xff, 0x01, 0x55, 0x23, 0xff, 0x01, 0x54, 0x24, 0xff, 0x00, 0x53, 0x22, 0xff, 0x03, 0x51, 0x24, 0xff, 0x09, 0x52, 0x29, 0xff, 0x08, 0x46, 0x21, 0xff, 0x04, 0x39, 0x18, 0xff, 0x04, 0x33, 0x16, 0xff, 0x02, 0x2f, 0x14, 0xff, 0x01, 0x2c, 0x11, 0xff, 0x03, 0x28, 0x12, 0xff, 0x02, 0x27, 0x11, 0xff, 0x00, 0x2a, 0x0c, 0xff, 0x06, 0x3a, 0x2d, 0xff, 0x3d, 0x6a, 0x99, 0xff, 0x46, 0x64, 0xe1, 0xff, 0x28, 0x44, 0xdc, 0xff, 0x26, 0x49, 0xdf, 0xff, 0x26, 0x4a, 0xdc, 0xff, 0x33, 0x53, 0xdc, 0xff, 0x40, 0x5d, 0xd8, 0xff, 0x3a, 0x5f, 0xb3, 0xff, 0x16, 0x4d, 0x6b, 0xff, 0x09, 0x56, 0x3c, 0xff, 0x11, 0x66, 0x3c, 0xff, 0x0c, 0x42, 0x6a, 0xff, 0x11, 0x30, 0x9e, 0xff, 0x15, 0x35, 0xaf, 0xff, 0x1a, 0x37, 0xb9, 0xff, 0x0c, 0x38, 0x6f, 0xff, 0x08, 0x3c, 0x2a, 0xff, 0x0b, 0x35, 0x1d, 0xff, 0x01, 0x22, 0x12, 0xff, 0x0b, 0x39, 0x24, 0xff, 0x1c, 0x63, 0x3f, 0xff, 0x13, 0x65, 0x3a, 0xff, 0x08, 0x47, 0x26, 0xff, 0x18, 0x47, 0x30, 0xff, 0x06, 0x36, 0x20, 0xff, 0x13, 0x4d, 0x38, 0xff, 0x0c, 0x32, 0x22, 0xff, 0x62, 0x70, 0x67, 0xff, + 0x02, 0x33, 0x1c, 0xff, 0x06, 0x40, 0x20, 0xff, 0x0b, 0x52, 0x2a, 0xff, 0x08, 0x55, 0x28, 0xff, 0x08, 0x55, 0x2b, 0xff, 0x06, 0x43, 0x22, 0xff, 0x01, 0x29, 0x12, 0xff, 0x04, 0x26, 0x16, 0xff, 0x02, 0x28, 0x10, 0xff, 0x06, 0x4d, 0x26, 0xff, 0x04, 0x5e, 0x2f, 0xff, 0x02, 0x5f, 0x2a, 0xff, 0x03, 0x5f, 0x2b, 0xff, 0x04, 0x5e, 0x2d, 0xff, 0x0a, 0x54, 0x2b, 0xff, 0x01, 0x2e, 0x13, 0xff, 0x01, 0x26, 0x11, 0xff, 0x05, 0x24, 0x14, 0xff, 0x01, 0x25, 0x11, 0xff, 0x07, 0x3d, 0x20, 0xff, 0x0c, 0x50, 0x2c, 0xff, 0x08, 0x4f, 0x27, 0xff, 0x08, 0x50, 0x29, 0xff, 0x09, 0x50, 0x28, 0xff, 0x0b, 0x4f, 0x29, 0xff, 0x03, 0x2b, 0x13, 0xff, 0x03, 0x1f, 0x0d, 0xff, 0x04, 0x32, 0x15, 0xff, 0x0e, 0x58, 0x2f, 0xff, 0x07, 0x49, 0x24, 0xff, 0x01, 0x2f, 0x11, 0xff, 0x07, 0x43, 0x20, 0xff, 0x0d, 0x55, 0x2f, 0xff, 0x04, 0x57, 0x2c, 0xff, 0x05, 0x59, 0x2b, 0xff, 0x0c, 0x5e, 0x2d, 0xff, 0x0a, 0x5e, 0x2a, 0xff, 0x07, 0x66, 0x2e, 0xff, 0x06, 0x6a, 0x30, 0xff, 0x0f, 0x6c, 0x36, 0xff, 0x10, 0x6b, 0x39, 0xff, 0x02, 0x3e, 0x1a, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x03, 0x2f, 0x1b, 0xff, 0x0a, 0x41, 0x2c, 0xff, 0x10, 0x53, 0x3b, 0xff, 0x0e, 0x50, 0x39, 0xff, 0x0d, 0x4e, 0x33, 0xff, 0x05, 0x4d, 0x2d, 0xff, 0x06, 0x49, 0x31, 0xff, 0x0a, 0x40, 0x2f, 0xff, 0x06, 0x34, 0x1d, 0xff, 0x01, 0x38, 0x0d, 0xff, 0x1b, 0x81, 0x41, 0xff, 0x1a, 0x94, 0x4e, 0xff, 0x10, 0x82, 0x3b, 0xff, 0x07, 0x6e, 0x2a, 0xff, 0x1a, 0x8c, 0x44, 0xff, 0x12, 0x45, 0x34, 0xff, 0x58, 0x42, 0x95, 0xff, 0x9c, 0x67, 0xe1, 0xff, 0x61, 0x43, 0x92, 0xff, 0x1f, 0x1b, 0x34, 0xff, 0x81, 0x66, 0xad, 0xff, 0xa2, 0x5e, 0xe4, 0xff, 0x82, 0x3a, 0xd4, 0xff, 0x52, 0x37, 0x91, 0xff, 0x05, 0x24, 0x0d, 0xff, 0x08, 0x30, 0x0b, 0xff, 0x0e, 0x34, 0x1d, 0xff, 0x0c, 0x33, 0x2c, 0xff, 0x0f, 0x57, 0x30, 0xff, 0x0a, 0x4a, 0x1d, 0xff, 0x16, 0x42, 0x1c, 0xff, 0x19, 0x32, 0x2a, 0xff, 0x39, 0x39, 0x6a, 0xff, 0x2d, 0x34, 0x51, 0xff, 0x53, 0x5a, 0x85, 0xff, 0x50, 0x5f, 0x84, 0xff, 0x2a, 0x53, 0x66, 0xff, 0x1e, 0x5c, 0x5c, 0xff, 0x09, 0x61, 0x48, 0xff, 0x03, 0x69, 0x43, 0xff, 0x05, 0x6e, 0x44, 0xff, 0x0c, 0x70, 0x4a, 0xff, 0x10, 0x74, 0x4d, 0xff, 0x13, 0x7a, 0x50, 0xff, 0x10, 0x7e, 0x56, 0xff, 0x10, 0x7f, 0x57, 0xff, 0x12, 0x7f, 0x55, 0xff, 0x14, 0x7f, 0x55, 0xff, 0x12, 0x7f, 0x55, 0xff, 0x12, 0x82, 0x57, 0xff, 0x11, 0x85, 0x59, 0xff, 0x10, 0x86, 0x5a, 0xff, 0x10, 0x86, 0x59, 0xff, 0x10, 0x86, 0x59, 0xff, 0x11, 0x86, 0x59, 0xff, 0x10, 0x84, 0x58, 0xff, 0x0f, 0x83, 0x57, 0xff, 0x0f, 0x83, 0x57, 0xff, 0x10, 0x83, 0x57, 0xff, 0x11, 0x83, 0x57, 0xff, 0x0c, 0x85, 0x57, 0xff, 0x0d, 0x84, 0x57, 0xff, 0x0f, 0x85, 0x58, 0xff, 0x12, 0x86, 0x59, 0xff, 0x11, 0x84, 0x59, 0xff, 0x10, 0x86, 0x57, 0xff, 0x0e, 0x87, 0x58, 0xff, 0x0c, 0x88, 0x58, 0xff, 0x0e, 0x89, 0x5b, 0xff, 0x0f, 0x89, 0x5b, 0xff, 0x0f, 0x8a, 0x5d, 0xff, 0x10, 0x8c, 0x5e, 0xff, 0x0e, 0x8b, 0x5d, 0xff, 0x0e, 0x8b, 0x5d, 0xff, 0x10, 0x8c, 0x5e, 0xff, 0x0f, 0x8b, 0x5d, 0xff, 0x10, 0x8d, 0x5e, 0xff, 0x0e, 0x8d, 0x5f, 0xff, 0x0d, 0x8e, 0x60, 0xff, 0x0c, 0x8f, 0x60, 0xff, 0x0d, 0x91, 0x62, 0xff, 0x0e, 0x92, 0x63, 0xff, 0x11, 0x92, 0x63, 0xff, 0x11, 0x93, 0x64, 0xff, 0x11, 0x92, 0x67, 0xff, 0x0f, 0x93, 0x66, 0xff, 0x0c, 0x93, 0x61, 0xff, 0x09, 0x92, 0x5d, 0xff, 0x0a, 0x93, 0x5c, 0xff, 0x0f, 0x96, 0x61, 0xff, 0x11, 0x93, 0x62, 0xff, 0x12, 0x90, 0x63, 0xff, 0x10, 0x94, 0x66, 0xff, 0x0f, 0x93, 0x66, 0xff, 0x11, 0x94, 0x65, 0xff, 0x13, 0x95, 0x67, 0xff, 0x11, 0x95, 0x66, 0xff, 0x13, 0x96, 0x67, 0xff, 0x19, 0x96, 0x68, 0xff, 0x1a, 0x93, 0x65, 0xff, 0x11, 0x7a, 0x54, 0xff, 0x07, 0x53, 0x33, 0xff, 0x03, 0x36, 0x1b, 0xff, 0x09, 0x31, 0x19, 0xff, 0x07, 0x33, 0x1b, 0xff, 0x02, 0x34, 0x1b, 0xff, 0x01, 0x34, 0x1c, 0xff, 0x05, 0x32, 0x1c, 0xff, 0x06, 0x33, 0x1b, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x04, 0x32, 0x19, 0xff, 0x02, 0x31, 0x17, 0xff, 0x04, 0x40, 0x22, 0xff, 0x0b, 0x5b, 0x38, 0xff, 0x10, 0x7e, 0x56, 0xff, 0x0b, 0x8e, 0x61, 0xff, 0x10, 0x8f, 0x5f, 0xff, 0x0b, 0x9c, 0x60, 0xff, 0x0a, 0xab, 0x5f, 0xff, 0x03, 0x87, 0x41, 0xff, 0x07, 0x81, 0x47, 0xff, 0x06, 0x83, 0x44, 0xff, 0x01, 0x85, 0x3e, 0xff, 0x04, 0x83, 0x41, 0xff, 0x09, 0x7f, 0x43, 0xff, 0x09, 0x82, 0x41, 0xff, 0x03, 0x7f, 0x3c, 0xff, 0x01, 0x7c, 0x38, 0xff, 0x04, 0x78, 0x37, 0xff, 0x0c, 0x70, 0x38, 0xff, 0x08, 0x52, 0x29, 0xff, 0x01, 0x38, 0x18, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x08, 0x31, 0x1b, 0xff, 0x09, 0x2f, 0x1a, 0xff, 0x04, 0x31, 0x1b, 0xff, 0x02, 0x32, 0x1c, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x06, 0x30, 0x1b, 0xff, 0x02, 0x31, 0x17, 0xff, 0x04, 0x49, 0x25, 0xff, 0x15, 0x6b, 0x44, 0xff, 0x14, 0x71, 0x49, 0xff, 0x0f, 0x71, 0x47, 0xff, 0x0c, 0x70, 0x46, 0xff, 0x0d, 0x71, 0x44, 0xff, 0x0a, 0x70, 0x43, 0xff, 0x08, 0x72, 0x43, 0xff, 0x10, 0x78, 0x45, 0xff, 0x08, 0x61, 0x31, 0xff, 0x0e, 0x63, 0x37, 0xff, 0x0b, 0x5d, 0x37, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x05, 0x36, 0x1a, 0xff, 0x09, 0x40, 0x20, 0xff, 0x03, 0x47, 0x22, 0xff, 0x02, 0x44, 0x1d, 0xff, 0x0a, 0x68, 0x3b, 0xff, 0x0f, 0x7d, 0x4c, 0xff, 0x03, 0x68, 0x37, 0xff, 0x09, 0x67, 0x36, 0xff, 0x05, 0x6a, 0x39, 0xff, 0x01, 0x69, 0x38, 0xff, 0x01, 0x69, 0x39, 0xff, 0x01, 0x69, 0x39, 0xff, 0x08, 0x67, 0x38, 0xff, 0x0c, 0x66, 0x38, 0xff, 0x08, 0x65, 0x37, 0xff, 0x02, 0x64, 0x36, 0xff, 0x0b, 0x64, 0x39, 0xff, 0x0e, 0x55, 0x30, 0xff, 0x01, 0x2d, 0x0e, 0xff, 0x03, 0x34, 0x17, 0xff, 0x0d, 0x3f, 0x23, 0xff, 0x0b, 0x42, 0x25, 0xff, 0x06, 0x39, 0x21, 0xff, 0x02, 0x28, 0x13, 0xff, 0x05, 0x33, 0x1b, 0xff, 0x08, 0x47, 0x29, 0xff, 0x08, 0x4b, 0x29, 0xff, 0x08, 0x44, 0x25, 0xff, 0x05, 0x4e, 0x28, 0xff, 0x10, 0x6d, 0x3f, 0xff, 0x0a, 0x71, 0x3d, 0xff, 0x0c, 0x6b, 0x3a, 0xff, 0x0a, 0x53, 0x2c, 0xff, 0x0a, 0x41, 0x24, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x02, 0x30, 0x15, 0xff, 0x0d, 0x47, 0x29, 0xff, 0x09, 0x46, 0x2a, 0xff, 0x04, 0x39, 0x20, 0xff, 0x00, 0x29, 0x13, 0xff, 0x05, 0x2a, 0x14, 0xff, 0x0a, 0x34, 0x1d, 0xff, 0x04, 0x32, 0x17, 0xff, 0x0c, 0x42, 0x25, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x04, 0x40, 0x22, 0xff, 0x0e, 0x55, 0x32, 0xff, 0x0c, 0x5b, 0x32, 0xff, 0x0a, 0x5a, 0x31, 0xff, 0x0e, 0x59, 0x34, 0xff, 0x06, 0x47, 0x27, 0xff, 0x06, 0x49, 0x25, 0xff, 0x10, 0x5e, 0x37, 0xff, 0x09, 0x5c, 0x32, 0xff, 0x08, 0x5c, 0x32, 0xff, 0x09, 0x5c, 0x32, 0xff, 0x0d, 0x5d, 0x34, 0xff, 0x0d, 0x60, 0x35, 0xff, 0x0c, 0x61, 0x37, 0xff, 0x0b, 0x5a, 0x34, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x03, 0x2a, 0x16, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x00, 0x20, 0x0d, 0xff, 0x0b, 0x3c, 0x22, 0xff, 0x06, 0x47, 0x27, 0xff, 0x04, 0x42, 0x23, 0xff, 0x05, 0x42, 0x26, 0xff, 0x01, 0x40, 0x20, 0xff, 0x03, 0x53, 0x29, 0xff, 0x17, 0x90, 0x56, 0xff, 0x22, 0xaf, 0x6d, 0xff, 0x1d, 0x9f, 0x5c, 0xff, 0x0e, 0x7a, 0x3c, 0xff, 0x01, 0x57, 0x1e, 0xff, 0x01, 0x50, 0x19, 0xff, 0x00, 0x4f, 0x1a, 0xff, 0x00, 0x52, 0x1e, 0xff, 0x02, 0x54, 0x22, 0xff, 0x04, 0x56, 0x26, 0xff, 0x02, 0x53, 0x24, 0xff, 0x01, 0x51, 0x24, 0xff, 0x02, 0x4f, 0x24, 0xff, 0x01, 0x4e, 0x24, 0xff, 0x06, 0x4d, 0x26, 0xff, 0x0d, 0x4c, 0x2a, 0xff, 0x03, 0x35, 0x18, 0xff, 0x00, 0x28, 0x10, 0xff, 0x02, 0x27, 0x12, 0xff, 0x00, 0x24, 0x11, 0xff, 0x01, 0x26, 0x13, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x02, 0x2d, 0x0f, 0xff, 0x06, 0x3b, 0x1a, 0xff, 0x0e, 0x49, 0x34, 0xff, 0x1f, 0x53, 0x63, 0xff, 0x60, 0x81, 0xda, 0xff, 0x52, 0x68, 0xe9, 0xff, 0x4a, 0x60, 0xe6, 0xff, 0x44, 0x65, 0xdf, 0xff, 0x37, 0x61, 0xc0, 0xff, 0x30, 0x5b, 0x9c, 0xff, 0x16, 0x4a, 0x60, 0xff, 0x02, 0x41, 0x2f, 0xff, 0x11, 0x65, 0x3d, 0xff, 0x07, 0x5a, 0x36, 0xff, 0x15, 0x48, 0x7e, 0xff, 0x1b, 0x39, 0xb6, 0xff, 0x1b, 0x3a, 0xbe, 0xff, 0x20, 0x3c, 0xc6, 0xff, 0x0e, 0x3a, 0x76, 0xff, 0x09, 0x40, 0x30, 0xff, 0x03, 0x2c, 0x15, 0xff, 0x00, 0x23, 0x12, 0xff, 0x13, 0x46, 0x2e, 0xff, 0x1c, 0x65, 0x3f, 0xff, 0x13, 0x63, 0x39, 0xff, 0x15, 0x56, 0x35, 0xff, 0x16, 0x46, 0x2f, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x15, 0x51, 0x3b, 0xff, 0x0a, 0x31, 0x20, 0xff, 0x62, 0x71, 0x67, 0xff, + 0x00, 0x32, 0x1b, 0xff, 0x06, 0x42, 0x22, 0xff, 0x0c, 0x52, 0x2a, 0xff, 0x09, 0x54, 0x27, 0xff, 0x07, 0x56, 0x2a, 0xff, 0x06, 0x46, 0x22, 0xff, 0x01, 0x2a, 0x12, 0xff, 0x03, 0x24, 0x14, 0xff, 0x02, 0x26, 0x0f, 0xff, 0x05, 0x4a, 0x24, 0xff, 0x04, 0x5d, 0x2e, 0xff, 0x03, 0x5e, 0x2c, 0xff, 0x03, 0x5f, 0x2b, 0xff, 0x03, 0x5e, 0x2d, 0xff, 0x09, 0x58, 0x2d, 0xff, 0x01, 0x32, 0x15, 0xff, 0x02, 0x26, 0x11, 0xff, 0x05, 0x24, 0x14, 0xff, 0x01, 0x25, 0x11, 0xff, 0x07, 0x3f, 0x22, 0xff, 0x0b, 0x50, 0x2c, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x09, 0x4f, 0x28, 0xff, 0x08, 0x4f, 0x29, 0xff, 0x0a, 0x4f, 0x28, 0xff, 0x03, 0x2c, 0x13, 0xff, 0x03, 0x1f, 0x0e, 0xff, 0x04, 0x32, 0x15, 0xff, 0x0d, 0x56, 0x2e, 0xff, 0x06, 0x45, 0x20, 0xff, 0x01, 0x33, 0x14, 0xff, 0x0b, 0x4e, 0x28, 0xff, 0x0c, 0x55, 0x2d, 0xff, 0x06, 0x56, 0x2b, 0xff, 0x06, 0x58, 0x2b, 0xff, 0x09, 0x5d, 0x2a, 0xff, 0x09, 0x60, 0x2b, 0xff, 0x08, 0x66, 0x2f, 0xff, 0x09, 0x67, 0x31, 0xff, 0x12, 0x64, 0x35, 0xff, 0x07, 0x4b, 0x23, 0xff, 0x00, 0x2f, 0x14, 0xff, 0x01, 0x30, 0x1b, 0xff, 0x03, 0x36, 0x24, 0xff, 0x0e, 0x4b, 0x37, 0xff, 0x0a, 0x4f, 0x38, 0xff, 0x07, 0x4d, 0x34, 0xff, 0x0b, 0x4a, 0x31, 0xff, 0x0b, 0x4a, 0x2f, 0xff, 0x08, 0x42, 0x2c, 0xff, 0x05, 0x3a, 0x28, 0xff, 0x01, 0x3a, 0x1a, 0xff, 0x0d, 0x53, 0x23, 0xff, 0x2a, 0x8e, 0x57, 0xff, 0x11, 0x73, 0x46, 0xff, 0x1a, 0x57, 0x40, 0xff, 0x20, 0x64, 0x44, 0xff, 0x0c, 0x5c, 0x22, 0xff, 0x18, 0x2d, 0x39, 0xff, 0x57, 0x2d, 0x9a, 0xff, 0x6d, 0x46, 0xaa, 0xff, 0x29, 0x2b, 0x4e, 0xff, 0x07, 0x1d, 0x18, 0xff, 0x3f, 0x4a, 0x6c, 0xff, 0x8a, 0x5f, 0xbb, 0xff, 0x9b, 0x57, 0xdf, 0xff, 0x5d, 0x43, 0x9f, 0xff, 0x02, 0x27, 0x11, 0xff, 0x0b, 0x42, 0x1c, 0xff, 0x06, 0x48, 0x24, 0xff, 0x0d, 0x53, 0x2c, 0xff, 0x15, 0x76, 0x35, 0xff, 0x05, 0x4c, 0x1b, 0xff, 0x1f, 0x40, 0x30, 0xff, 0x24, 0x35, 0x3c, 0xff, 0x34, 0x3c, 0x64, 0xff, 0x17, 0x29, 0x35, 0xff, 0x4d, 0x59, 0x83, 0xff, 0x4a, 0x5e, 0x80, 0xff, 0x2a, 0x53, 0x65, 0xff, 0x1e, 0x59, 0x5a, 0xff, 0x05, 0x5a, 0x41, 0xff, 0x03, 0x67, 0x40, 0xff, 0x07, 0x72, 0x47, 0xff, 0x10, 0x7a, 0x50, 0xff, 0x13, 0x7f, 0x53, 0xff, 0x13, 0x82, 0x53, 0xff, 0x0f, 0x82, 0x59, 0xff, 0x0d, 0x82, 0x58, 0xff, 0x0e, 0x84, 0x58, 0xff, 0x0f, 0x85, 0x59, 0xff, 0x11, 0x86, 0x5a, 0xff, 0x11, 0x87, 0x59, 0xff, 0x12, 0x88, 0x5b, 0xff, 0x12, 0x87, 0x5a, 0xff, 0x11, 0x87, 0x5a, 0xff, 0x10, 0x87, 0x5a, 0xff, 0x11, 0x86, 0x59, 0xff, 0x11, 0x86, 0x59, 0xff, 0x12, 0x85, 0x59, 0xff, 0x11, 0x84, 0x58, 0xff, 0x10, 0x84, 0x58, 0xff, 0x11, 0x84, 0x58, 0xff, 0x0e, 0x86, 0x58, 0xff, 0x0d, 0x87, 0x59, 0xff, 0x0f, 0x87, 0x59, 0xff, 0x11, 0x87, 0x5a, 0xff, 0x13, 0x89, 0x5b, 0xff, 0x11, 0x8a, 0x5b, 0xff, 0x11, 0x8d, 0x5c, 0xff, 0x0f, 0x8e, 0x5d, 0xff, 0x0f, 0x8d, 0x5e, 0xff, 0x0f, 0x8d, 0x5e, 0xff, 0x0e, 0x8d, 0x5e, 0xff, 0x0e, 0x8d, 0x5e, 0xff, 0x0b, 0x8d, 0x5e, 0xff, 0x0d, 0x8d, 0x5e, 0xff, 0x0e, 0x8f, 0x5f, 0xff, 0x0f, 0x90, 0x60, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x0f, 0x91, 0x62, 0xff, 0x0f, 0x94, 0x65, 0xff, 0x10, 0x96, 0x66, 0xff, 0x0e, 0x96, 0x66, 0xff, 0x0e, 0x96, 0x66, 0xff, 0x10, 0x96, 0x67, 0xff, 0x11, 0x97, 0x67, 0xff, 0x11, 0x97, 0x67, 0xff, 0x10, 0x98, 0x67, 0xff, 0x10, 0x96, 0x69, 0xff, 0x0f, 0x96, 0x69, 0xff, 0x11, 0x97, 0x6a, 0xff, 0x10, 0x97, 0x6a, 0xff, 0x11, 0x96, 0x68, 0xff, 0x12, 0x96, 0x67, 0xff, 0x0f, 0x96, 0x67, 0xff, 0x11, 0x98, 0x69, 0xff, 0x15, 0x96, 0x68, 0xff, 0x1a, 0x97, 0x6a, 0xff, 0x1f, 0x96, 0x6a, 0xff, 0x22, 0x93, 0x67, 0xff, 0x21, 0x86, 0x5c, 0xff, 0x0f, 0x69, 0x42, 0xff, 0x01, 0x41, 0x23, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x08, 0x31, 0x1c, 0xff, 0x09, 0x30, 0x1a, 0xff, 0x06, 0x34, 0x1c, 0xff, 0x00, 0x33, 0x1a, 0xff, 0x00, 0x34, 0x1b, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x02, 0x33, 0x18, 0xff, 0x01, 0x34, 0x17, 0xff, 0x03, 0x41, 0x22, 0xff, 0x09, 0x54, 0x33, 0xff, 0x1c, 0x7b, 0x55, 0xff, 0x1f, 0x8f, 0x66, 0xff, 0x15, 0x97, 0x69, 0xff, 0x0b, 0x98, 0x67, 0xff, 0x0a, 0x98, 0x60, 0xff, 0x13, 0xac, 0x69, 0xff, 0x06, 0x9e, 0x54, 0xff, 0x03, 0x85, 0x42, 0xff, 0x0a, 0x82, 0x47, 0xff, 0x07, 0x83, 0x43, 0xff, 0x04, 0x83, 0x3f, 0xff, 0x05, 0x82, 0x41, 0xff, 0x09, 0x80, 0x43, 0xff, 0x07, 0x82, 0x40, 0xff, 0x04, 0x80, 0x3e, 0xff, 0x02, 0x7b, 0x3a, 0xff, 0x08, 0x75, 0x3a, 0xff, 0x09, 0x64, 0x32, 0xff, 0x01, 0x3e, 0x1a, 0xff, 0x01, 0x34, 0x18, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x04, 0x31, 0x1a, 0xff, 0x04, 0x31, 0x1b, 0xff, 0x05, 0x30, 0x1b, 0xff, 0x06, 0x30, 0x1b, 0xff, 0x07, 0x31, 0x1c, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x02, 0x31, 0x19, 0xff, 0x03, 0x45, 0x26, 0xff, 0x09, 0x67, 0x3f, 0xff, 0x0f, 0x74, 0x4b, 0xff, 0x0a, 0x74, 0x49, 0xff, 0x08, 0x73, 0x48, 0xff, 0x09, 0x73, 0x48, 0xff, 0x0d, 0x75, 0x49, 0xff, 0x0d, 0x75, 0x48, 0xff, 0x0c, 0x75, 0x47, 0xff, 0x13, 0x78, 0x47, 0xff, 0x08, 0x5f, 0x30, 0xff, 0x0c, 0x69, 0x3c, 0xff, 0x0e, 0x6d, 0x45, 0xff, 0x04, 0x47, 0x28, 0xff, 0x06, 0x33, 0x19, 0xff, 0x08, 0x39, 0x1d, 0xff, 0x06, 0x46, 0x23, 0xff, 0x03, 0x43, 0x1e, 0xff, 0x05, 0x54, 0x2a, 0xff, 0x14, 0x7d, 0x4e, 0xff, 0x03, 0x6b, 0x39, 0xff, 0x0a, 0x67, 0x36, 0xff, 0x06, 0x6a, 0x37, 0xff, 0x01, 0x68, 0x37, 0xff, 0x04, 0x67, 0x37, 0xff, 0x01, 0x69, 0x38, 0xff, 0x08, 0x67, 0x38, 0xff, 0x0b, 0x66, 0x38, 0xff, 0x08, 0x65, 0x37, 0xff, 0x02, 0x64, 0x36, 0xff, 0x08, 0x62, 0x37, 0xff, 0x10, 0x5d, 0x36, 0xff, 0x03, 0x37, 0x15, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x0e, 0x3a, 0x20, 0xff, 0x08, 0x3d, 0x20, 0xff, 0x03, 0x39, 0x21, 0xff, 0x02, 0x2a, 0x15, 0xff, 0x03, 0x30, 0x18, 0xff, 0x0a, 0x48, 0x29, 0xff, 0x08, 0x4b, 0x29, 0xff, 0x0c, 0x48, 0x29, 0xff, 0x01, 0x44, 0x21, 0xff, 0x0d, 0x62, 0x37, 0xff, 0x0d, 0x71, 0x3e, 0xff, 0x0d, 0x6f, 0x3c, 0xff, 0x0c, 0x5e, 0x32, 0xff, 0x0b, 0x49, 0x28, 0xff, 0x09, 0x36, 0x1f, 0xff, 0x01, 0x2a, 0x0f, 0xff, 0x07, 0x3d, 0x21, 0xff, 0x0d, 0x49, 0x2d, 0xff, 0x07, 0x3c, 0x24, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x03, 0x28, 0x11, 0xff, 0x08, 0x30, 0x1a, 0xff, 0x03, 0x30, 0x16, 0xff, 0x09, 0x41, 0x24, 0xff, 0x03, 0x37, 0x1c, 0xff, 0x03, 0x3b, 0x1e, 0xff, 0x0f, 0x54, 0x31, 0xff, 0x0c, 0x5a, 0x33, 0xff, 0x0a, 0x5a, 0x31, 0xff, 0x0e, 0x59, 0x34, 0xff, 0x07, 0x48, 0x28, 0xff, 0x05, 0x44, 0x21, 0xff, 0x12, 0x5e, 0x38, 0xff, 0x09, 0x5c, 0x33, 0xff, 0x07, 0x5c, 0x32, 0xff, 0x0a, 0x5c, 0x32, 0xff, 0x0d, 0x5c, 0x33, 0xff, 0x0c, 0x5e, 0x34, 0xff, 0x0a, 0x61, 0x37, 0xff, 0x0c, 0x5f, 0x37, 0xff, 0x05, 0x3e, 0x21, 0xff, 0x02, 0x2e, 0x18, 0xff, 0x00, 0x20, 0x10, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x09, 0x3a, 0x20, 0xff, 0x04, 0x44, 0x25, 0xff, 0x04, 0x42, 0x23, 0xff, 0x04, 0x41, 0x24, 0xff, 0x01, 0x45, 0x22, 0xff, 0x10, 0x72, 0x43, 0xff, 0x2c, 0xa8, 0x6a, 0xff, 0x12, 0x90, 0x4f, 0xff, 0x01, 0x5f, 0x20, 0xff, 0x00, 0x4f, 0x16, 0xff, 0x04, 0x4b, 0x18, 0xff, 0x02, 0x52, 0x1f, 0xff, 0x00, 0x55, 0x22, 0xff, 0x01, 0x56, 0x25, 0xff, 0x05, 0x56, 0x27, 0xff, 0x04, 0x54, 0x27, 0xff, 0x03, 0x50, 0x25, 0xff, 0x03, 0x4e, 0x25, 0xff, 0x04, 0x4e, 0x26, 0xff, 0x06, 0x4d, 0x28, 0xff, 0x0a, 0x4c, 0x2b, 0xff, 0x0c, 0x43, 0x27, 0xff, 0x02, 0x2b, 0x17, 0xff, 0x03, 0x25, 0x14, 0xff, 0x02, 0x22, 0x14, 0xff, 0x03, 0x24, 0x15, 0xff, 0x01, 0x25, 0x14, 0xff, 0x00, 0x29, 0x10, 0xff, 0x06, 0x3f, 0x1c, 0xff, 0x0f, 0x4d, 0x2b, 0xff, 0x0d, 0x4e, 0x34, 0xff, 0x0c, 0x4b, 0x3d, 0xff, 0x42, 0x71, 0x94, 0xff, 0x5a, 0x7a, 0xc7, 0xff, 0x52, 0x6f, 0xc3, 0xff, 0x35, 0x61, 0xa2, 0xff, 0x15, 0x4d, 0x6d, 0xff, 0x13, 0x4b, 0x51, 0xff, 0x05, 0x40, 0x2e, 0xff, 0x05, 0x4b, 0x25, 0xff, 0x11, 0x6a, 0x3e, 0xff, 0x07, 0x5b, 0x3c, 0xff, 0x25, 0x55, 0x9c, 0xff, 0x24, 0x3e, 0xc7, 0xff, 0x20, 0x3d, 0xc8, 0xff, 0x27, 0x43, 0xce, 0xff, 0x16, 0x41, 0x79, 0xff, 0x04, 0x37, 0x2a, 0xff, 0x00, 0x26, 0x10, 0xff, 0x00, 0x26, 0x13, 0xff, 0x17, 0x52, 0x34, 0xff, 0x1c, 0x67, 0x3d, 0xff, 0x15, 0x63, 0x3a, 0xff, 0x1e, 0x5e, 0x3e, 0xff, 0x08, 0x34, 0x1d, 0xff, 0x01, 0x34, 0x1f, 0xff, 0x15, 0x54, 0x3e, 0xff, 0x09, 0x31, 0x20, 0xff, 0x61, 0x6e, 0x66, 0xff, + 0x00, 0x31, 0x1a, 0xff, 0x07, 0x43, 0x24, 0xff, 0x0b, 0x51, 0x2a, 0xff, 0x09, 0x54, 0x27, 0xff, 0x07, 0x56, 0x29, 0xff, 0x06, 0x49, 0x24, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x03, 0x23, 0x13, 0xff, 0x02, 0x25, 0x0f, 0xff, 0x04, 0x47, 0x22, 0xff, 0x06, 0x5b, 0x2e, 0xff, 0x05, 0x5d, 0x2c, 0xff, 0x03, 0x5f, 0x2c, 0xff, 0x03, 0x5f, 0x2c, 0xff, 0x08, 0x59, 0x2d, 0xff, 0x01, 0x36, 0x19, 0xff, 0x02, 0x26, 0x10, 0xff, 0x06, 0x25, 0x14, 0xff, 0x01, 0x25, 0x10, 0xff, 0x08, 0x40, 0x23, 0xff, 0x0a, 0x50, 0x2b, 0xff, 0x07, 0x50, 0x27, 0xff, 0x08, 0x4f, 0x28, 0xff, 0x08, 0x4f, 0x29, 0xff, 0x0b, 0x4f, 0x2a, 0xff, 0x03, 0x2c, 0x14, 0xff, 0x02, 0x1f, 0x0f, 0xff, 0x04, 0x32, 0x15, 0xff, 0x0d, 0x56, 0x2e, 0xff, 0x04, 0x42, 0x1d, 0xff, 0x04, 0x3a, 0x1a, 0xff, 0x0c, 0x54, 0x2d, 0xff, 0x0b, 0x52, 0x2b, 0xff, 0x0a, 0x55, 0x2a, 0xff, 0x04, 0x53, 0x27, 0xff, 0x05, 0x5a, 0x29, 0xff, 0x07, 0x60, 0x2c, 0xff, 0x0a, 0x65, 0x2f, 0xff, 0x0c, 0x65, 0x32, 0xff, 0x09, 0x50, 0x2a, 0xff, 0x01, 0x33, 0x13, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x00, 0x2d, 0x1a, 0xff, 0x05, 0x40, 0x2d, 0xff, 0x0d, 0x4a, 0x36, 0xff, 0x0a, 0x4b, 0x35, 0xff, 0x09, 0x4c, 0x33, 0xff, 0x08, 0x45, 0x2c, 0xff, 0x0d, 0x45, 0x2d, 0xff, 0x07, 0x3d, 0x26, 0xff, 0x02, 0x3f, 0x25, 0xff, 0x10, 0x5e, 0x33, 0xff, 0x31, 0x88, 0x56, 0xff, 0x14, 0x62, 0x42, 0xff, 0x0d, 0x42, 0x40, 0xff, 0x36, 0x3d, 0x66, 0xff, 0x35, 0x4a, 0x5e, 0xff, 0x05, 0x3e, 0x17, 0xff, 0x2a, 0x33, 0x4a, 0xff, 0x79, 0x45, 0xb9, 0xff, 0x40, 0x27, 0x71, 0xff, 0x09, 0x22, 0x1f, 0xff, 0x07, 0x34, 0x18, 0xff, 0x13, 0x46, 0x3d, 0xff, 0x2d, 0x29, 0x51, 0xff, 0x75, 0x51, 0x9f, 0xff, 0x37, 0x30, 0x60, 0xff, 0x02, 0x31, 0x19, 0xff, 0x0a, 0x5c, 0x2a, 0xff, 0x12, 0x65, 0x35, 0xff, 0x08, 0x49, 0x19, 0xff, 0x1e, 0x84, 0x42, 0xff, 0x07, 0x4a, 0x23, 0xff, 0x4a, 0x57, 0x77, 0xff, 0x48, 0x4a, 0x75, 0xff, 0x61, 0x67, 0x99, 0xff, 0x21, 0x34, 0x47, 0xff, 0x23, 0x37, 0x59, 0xff, 0x26, 0x46, 0x59, 0xff, 0x2a, 0x5a, 0x62, 0xff, 0x1c, 0x5c, 0x55, 0xff, 0x11, 0x67, 0x4a, 0xff, 0x0f, 0x72, 0x4a, 0xff, 0x11, 0x7c, 0x51, 0xff, 0x13, 0x82, 0x56, 0xff, 0x14, 0x84, 0x55, 0xff, 0x16, 0x87, 0x57, 0xff, 0x17, 0x86, 0x5c, 0xff, 0x13, 0x87, 0x5c, 0xff, 0x0d, 0x8a, 0x5c, 0xff, 0x0b, 0x8c, 0x5c, 0xff, 0x0b, 0x8c, 0x5c, 0xff, 0x0d, 0x8c, 0x5b, 0xff, 0x12, 0x8a, 0x5d, 0xff, 0x14, 0x88, 0x5c, 0xff, 0x10, 0x87, 0x5a, 0xff, 0x0f, 0x86, 0x59, 0xff, 0x12, 0x87, 0x5a, 0xff, 0x12, 0x87, 0x5a, 0xff, 0x12, 0x87, 0x5a, 0xff, 0x11, 0x86, 0x59, 0xff, 0x10, 0x86, 0x59, 0xff, 0x0f, 0x86, 0x59, 0xff, 0x0f, 0x88, 0x5b, 0xff, 0x0d, 0x8a, 0x5c, 0xff, 0x0f, 0x8a, 0x5c, 0xff, 0x10, 0x8b, 0x5d, 0xff, 0x11, 0x8d, 0x5c, 0xff, 0x10, 0x8e, 0x5d, 0xff, 0x0f, 0x8e, 0x5e, 0xff, 0x0f, 0x8e, 0x5e, 0xff, 0x0f, 0x90, 0x60, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x0e, 0x90, 0x61, 0xff, 0x0e, 0x90, 0x62, 0xff, 0x0f, 0x92, 0x63, 0xff, 0x0e, 0x92, 0x62, 0xff, 0x0f, 0x93, 0x64, 0xff, 0x10, 0x95, 0x66, 0xff, 0x12, 0x95, 0x66, 0xff, 0x11, 0x95, 0x66, 0xff, 0x10, 0x96, 0x66, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x11, 0x98, 0x68, 0xff, 0x10, 0x98, 0x65, 0xff, 0x0f, 0x98, 0x65, 0xff, 0x0f, 0x97, 0x69, 0xff, 0x10, 0x96, 0x6b, 0xff, 0x11, 0x96, 0x6d, 0xff, 0x10, 0x96, 0x6c, 0xff, 0x10, 0x97, 0x69, 0xff, 0x11, 0x98, 0x67, 0xff, 0x0f, 0x9b, 0x6a, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x18, 0x91, 0x64, 0xff, 0x15, 0x81, 0x57, 0xff, 0x15, 0x75, 0x4d, 0xff, 0x0e, 0x63, 0x3d, 0xff, 0x09, 0x51, 0x2e, 0xff, 0x02, 0x3e, 0x1d, 0xff, 0x03, 0x32, 0x19, 0xff, 0x08, 0x33, 0x1c, 0xff, 0x05, 0x31, 0x1b, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x01, 0x33, 0x19, 0xff, 0x00, 0x33, 0x18, 0xff, 0x00, 0x33, 0x17, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x05, 0x46, 0x27, 0xff, 0x0d, 0x5d, 0x38, 0xff, 0x1b, 0x7a, 0x53, 0xff, 0x1c, 0x89, 0x60, 0xff, 0x1a, 0x96, 0x69, 0xff, 0x14, 0x97, 0x68, 0xff, 0x12, 0x96, 0x67, 0xff, 0x13, 0x97, 0x67, 0xff, 0x0c, 0x9c, 0x60, 0xff, 0x1a, 0xb5, 0x6e, 0xff, 0x04, 0x8f, 0x49, 0xff, 0x03, 0x85, 0x43, 0xff, 0x09, 0x83, 0x45, 0xff, 0x07, 0x82, 0x42, 0xff, 0x06, 0x82, 0x41, 0xff, 0x06, 0x81, 0x41, 0xff, 0x08, 0x81, 0x41, 0xff, 0x07, 0x82, 0x40, 0xff, 0x01, 0x7b, 0x39, 0xff, 0x05, 0x76, 0x3a, 0xff, 0x0f, 0x6f, 0x3c, 0xff, 0x04, 0x51, 0x27, 0xff, 0x00, 0x35, 0x15, 0xff, 0x01, 0x34, 0x19, 0xff, 0x03, 0x31, 0x19, 0xff, 0x06, 0x31, 0x1a, 0xff, 0x01, 0x32, 0x1b, 0xff, 0x01, 0x32, 0x1b, 0xff, 0x06, 0x31, 0x1c, 0xff, 0x06, 0x30, 0x1a, 0xff, 0x03, 0x32, 0x18, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x13, 0x6d, 0x49, 0xff, 0x14, 0x80, 0x55, 0xff, 0x0e, 0x7f, 0x53, 0xff, 0x0a, 0x7d, 0x50, 0xff, 0x07, 0x78, 0x4c, 0xff, 0x09, 0x77, 0x4c, 0xff, 0x0b, 0x77, 0x4c, 0xff, 0x0c, 0x76, 0x4b, 0xff, 0x0d, 0x78, 0x4b, 0xff, 0x10, 0x76, 0x47, 0xff, 0x07, 0x60, 0x33, 0xff, 0x10, 0x73, 0x46, 0xff, 0x12, 0x70, 0x4a, 0xff, 0x04, 0x46, 0x28, 0xff, 0x04, 0x33, 0x1a, 0xff, 0x03, 0x34, 0x19, 0xff, 0x05, 0x41, 0x21, 0xff, 0x05, 0x45, 0x22, 0xff, 0x04, 0x46, 0x20, 0xff, 0x10, 0x71, 0x43, 0xff, 0x05, 0x74, 0x41, 0xff, 0x05, 0x67, 0x35, 0xff, 0x05, 0x68, 0x36, 0xff, 0x02, 0x67, 0x36, 0xff, 0x06, 0x66, 0x37, 0xff, 0x04, 0x67, 0x37, 0xff, 0x07, 0x66, 0x37, 0xff, 0x09, 0x66, 0x37, 0xff, 0x07, 0x65, 0x38, 0xff, 0x04, 0x65, 0x37, 0xff, 0x06, 0x61, 0x35, 0xff, 0x0e, 0x61, 0x37, 0xff, 0x06, 0x47, 0x22, 0xff, 0x00, 0x28, 0x0d, 0xff, 0x0c, 0x36, 0x1c, 0xff, 0x07, 0x3b, 0x20, 0xff, 0x03, 0x3a, 0x21, 0xff, 0x02, 0x2c, 0x17, 0xff, 0x02, 0x2d, 0x16, 0xff, 0x0a, 0x47, 0x29, 0xff, 0x07, 0x4b, 0x28, 0xff, 0x0d, 0x49, 0x2a, 0xff, 0x02, 0x41, 0x20, 0xff, 0x07, 0x53, 0x2c, 0xff, 0x10, 0x70, 0x3f, 0xff, 0x0d, 0x70, 0x3c, 0xff, 0x0e, 0x65, 0x36, 0xff, 0x0a, 0x50, 0x2b, 0xff, 0x0d, 0x3f, 0x25, 0xff, 0x04, 0x2f, 0x15, 0xff, 0x01, 0x31, 0x16, 0xff, 0x0b, 0x44, 0x29, 0xff, 0x0c, 0x42, 0x2a, 0xff, 0x02, 0x30, 0x18, 0xff, 0x00, 0x26, 0x11, 0xff, 0x05, 0x2c, 0x16, 0xff, 0x03, 0x30, 0x19, 0xff, 0x09, 0x41, 0x25, 0xff, 0x03, 0x38, 0x1d, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x0e, 0x51, 0x30, 0xff, 0x0d, 0x59, 0x34, 0xff, 0x0a, 0x5c, 0x32, 0xff, 0x0d, 0x59, 0x33, 0xff, 0x08, 0x49, 0x2a, 0xff, 0x02, 0x3f, 0x1d, 0xff, 0x12, 0x5c, 0x37, 0xff, 0x09, 0x5b, 0x34, 0xff, 0x07, 0x5c, 0x32, 0xff, 0x09, 0x5a, 0x30, 0xff, 0x0c, 0x5b, 0x32, 0xff, 0x0c, 0x5d, 0x33, 0xff, 0x0a, 0x61, 0x36, 0xff, 0x0a, 0x60, 0x37, 0xff, 0x07, 0x46, 0x25, 0xff, 0x01, 0x30, 0x19, 0xff, 0x00, 0x22, 0x11, 0xff, 0x00, 0x1f, 0x0c, 0xff, 0x08, 0x39, 0x20, 0xff, 0x03, 0x42, 0x23, 0xff, 0x03, 0x42, 0x22, 0xff, 0x02, 0x42, 0x1f, 0xff, 0x06, 0x55, 0x2c, 0xff, 0x1f, 0x87, 0x55, 0xff, 0x14, 0x79, 0x40, 0xff, 0x01, 0x58, 0x1d, 0xff, 0x00, 0x50, 0x17, 0xff, 0x01, 0x4e, 0x19, 0xff, 0x0b, 0x52, 0x20, 0xff, 0x04, 0x54, 0x24, 0xff, 0x02, 0x57, 0x26, 0xff, 0x05, 0x57, 0x28, 0xff, 0x05, 0x55, 0x29, 0xff, 0x02, 0x50, 0x25, 0xff, 0x05, 0x4e, 0x26, 0xff, 0x06, 0x50, 0x29, 0xff, 0x06, 0x4f, 0x2a, 0xff, 0x08, 0x4e, 0x2c, 0xff, 0x0e, 0x4c, 0x2f, 0xff, 0x09, 0x3c, 0x24, 0xff, 0x01, 0x27, 0x15, 0xff, 0x03, 0x24, 0x15, 0xff, 0x02, 0x23, 0x14, 0xff, 0x02, 0x25, 0x15, 0xff, 0x00, 0x26, 0x14, 0xff, 0x03, 0x34, 0x1b, 0xff, 0x0e, 0x4a, 0x2b, 0xff, 0x0f, 0x4f, 0x32, 0xff, 0x08, 0x4d, 0x2f, 0xff, 0x09, 0x52, 0x31, 0xff, 0x12, 0x54, 0x4a, 0xff, 0x1e, 0x55, 0x67, 0xff, 0x19, 0x4d, 0x64, 0xff, 0x0f, 0x4e, 0x54, 0xff, 0x10, 0x52, 0x40, 0xff, 0x10, 0x4c, 0x33, 0xff, 0x01, 0x3c, 0x20, 0xff, 0x10, 0x5b, 0x35, 0xff, 0x0d, 0x6a, 0x3c, 0xff, 0x12, 0x6c, 0x4b, 0xff, 0x2f, 0x5f, 0xaa, 0xff, 0x24, 0x3e, 0xc9, 0xff, 0x24, 0x40, 0xcb, 0xff, 0x2e, 0x49, 0xcf, 0xff, 0x1a, 0x47, 0x75, 0xff, 0x05, 0x39, 0x29, 0xff, 0x01, 0x26, 0x14, 0xff, 0x02, 0x28, 0x14, 0xff, 0x1c, 0x5d, 0x3a, 0xff, 0x19, 0x66, 0x3a, 0xff, 0x17, 0x62, 0x3b, 0xff, 0x19, 0x57, 0x39, 0xff, 0x01, 0x28, 0x13, 0xff, 0x05, 0x3b, 0x27, 0xff, 0x15, 0x54, 0x40, 0xff, 0x08, 0x30, 0x21, 0xff, 0x61, 0x6e, 0x68, 0xff, + 0x00, 0x30, 0x19, 0xff, 0x07, 0x44, 0x25, 0xff, 0x09, 0x4e, 0x28, 0xff, 0x09, 0x53, 0x26, 0xff, 0x08, 0x55, 0x28, 0xff, 0x07, 0x4d, 0x26, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x06, 0x24, 0x14, 0xff, 0x05, 0x24, 0x0f, 0xff, 0x03, 0x43, 0x20, 0xff, 0x06, 0x5a, 0x2e, 0xff, 0x06, 0x5c, 0x2c, 0xff, 0x04, 0x5d, 0x2b, 0xff, 0x02, 0x5f, 0x2c, 0xff, 0x07, 0x5b, 0x2e, 0xff, 0x04, 0x3c, 0x1e, 0xff, 0x02, 0x26, 0x10, 0xff, 0x06, 0x25, 0x14, 0xff, 0x01, 0x26, 0x12, 0xff, 0x08, 0x42, 0x25, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x07, 0x50, 0x27, 0xff, 0x09, 0x4f, 0x28, 0xff, 0x07, 0x4f, 0x29, 0xff, 0x09, 0x4e, 0x29, 0xff, 0x03, 0x2d, 0x15, 0xff, 0x02, 0x1f, 0x0f, 0xff, 0x03, 0x31, 0x14, 0xff, 0x0c, 0x57, 0x2f, 0xff, 0x02, 0x41, 0x1c, 0xff, 0x08, 0x43, 0x22, 0xff, 0x09, 0x55, 0x2c, 0xff, 0x0c, 0x53, 0x2a, 0xff, 0x0c, 0x52, 0x28, 0xff, 0x03, 0x4f, 0x23, 0xff, 0x03, 0x5b, 0x2a, 0xff, 0x06, 0x62, 0x2e, 0xff, 0x0f, 0x66, 0x31, 0xff, 0x0e, 0x5d, 0x2e, 0xff, 0x02, 0x36, 0x18, 0xff, 0x04, 0x2d, 0x15, 0xff, 0x03, 0x2a, 0x17, 0xff, 0x03, 0x34, 0x22, 0xff, 0x09, 0x46, 0x32, 0xff, 0x09, 0x44, 0x30, 0xff, 0x0a, 0x43, 0x2c, 0xff, 0x09, 0x43, 0x2b, 0xff, 0x0c, 0x43, 0x2c, 0xff, 0x09, 0x40, 0x26, 0xff, 0x03, 0x43, 0x22, 0xff, 0x0c, 0x5d, 0x31, 0xff, 0x12, 0x74, 0x3b, 0xff, 0x12, 0x64, 0x39, 0xff, 0x23, 0x4a, 0x55, 0xff, 0x4d, 0x4c, 0x8a, 0xff, 0x61, 0x40, 0xa9, 0xff, 0x36, 0x34, 0x6e, 0xff, 0x03, 0x2c, 0x18, 0xff, 0x28, 0x34, 0x44, 0xff, 0x7f, 0x5f, 0xb0, 0xff, 0x2e, 0x2f, 0x4d, 0xff, 0x0a, 0x2e, 0x0f, 0xff, 0x14, 0x51, 0x28, 0xff, 0x16, 0x76, 0x43, 0xff, 0x05, 0x34, 0x25, 0xff, 0x12, 0x1f, 0x27, 0xff, 0x0a, 0x20, 0x12, 0xff, 0x07, 0x4f, 0x23, 0xff, 0x0e, 0x81, 0x3b, 0xff, 0x19, 0x64, 0x30, 0xff, 0x03, 0x2c, 0x08, 0xff, 0x28, 0x80, 0x4a, 0xff, 0x25, 0x56, 0x4d, 0xff, 0x6a, 0x60, 0xb3, 0xff, 0x3e, 0x35, 0x78, 0xff, 0x54, 0x51, 0x8f, 0xff, 0x3e, 0x48, 0x6e, 0xff, 0x12, 0x2f, 0x49, 0xff, 0x0d, 0x42, 0x41, 0xff, 0x1c, 0x61, 0x56, 0xff, 0x13, 0x64, 0x4d, 0xff, 0x14, 0x74, 0x4d, 0xff, 0x14, 0x7e, 0x50, 0xff, 0x15, 0x86, 0x59, 0xff, 0x12, 0x86, 0x5b, 0xff, 0x10, 0x87, 0x58, 0xff, 0x12, 0x8a, 0x59, 0xff, 0x14, 0x8a, 0x5e, 0xff, 0x13, 0x8c, 0x5e, 0xff, 0x10, 0x8e, 0x5e, 0xff, 0x0e, 0x8f, 0x5d, 0xff, 0x0d, 0x8f, 0x5d, 0xff, 0x0d, 0x8d, 0x5c, 0xff, 0x0e, 0x8c, 0x5b, 0xff, 0x0e, 0x8a, 0x5b, 0xff, 0x0e, 0x89, 0x5b, 0xff, 0x0f, 0x89, 0x5b, 0xff, 0x10, 0x87, 0x5a, 0xff, 0x10, 0x87, 0x5a, 0xff, 0x0f, 0x87, 0x5a, 0xff, 0x0f, 0x87, 0x5a, 0xff, 0x0e, 0x89, 0x5b, 0xff, 0x0e, 0x8a, 0x5c, 0xff, 0x0f, 0x8d, 0x5c, 0xff, 0x0f, 0x8d, 0x5c, 0xff, 0x0e, 0x8f, 0x5e, 0xff, 0x0e, 0x91, 0x5f, 0xff, 0x0e, 0x92, 0x60, 0xff, 0x0e, 0x93, 0x61, 0xff, 0x10, 0x93, 0x63, 0xff, 0x10, 0x93, 0x64, 0xff, 0x12, 0x96, 0x67, 0xff, 0x13, 0x96, 0x67, 0xff, 0x13, 0x97, 0x68, 0xff, 0x12, 0x97, 0x68, 0xff, 0x12, 0x97, 0x68, 0xff, 0x11, 0x97, 0x68, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x10, 0x98, 0x68, 0xff, 0x13, 0x98, 0x68, 0xff, 0x12, 0x98, 0x68, 0xff, 0x10, 0x97, 0x67, 0xff, 0x0e, 0x97, 0x67, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x0f, 0x98, 0x68, 0xff, 0x10, 0x98, 0x68, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x98, 0x67, 0xff, 0x10, 0x97, 0x68, 0xff, 0x10, 0x97, 0x6a, 0xff, 0x0f, 0x97, 0x6a, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x0f, 0x99, 0x67, 0xff, 0x0a, 0x9a, 0x66, 0xff, 0x10, 0x9a, 0x69, 0xff, 0x10, 0x81, 0x54, 0xff, 0x02, 0x51, 0x28, 0xff, 0x01, 0x43, 0x1f, 0xff, 0x01, 0x3a, 0x18, 0xff, 0x01, 0x3a, 0x1a, 0xff, 0x01, 0x38, 0x18, 0xff, 0x01, 0x36, 0x19, 0xff, 0x02, 0x36, 0x1b, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x01, 0x3b, 0x1c, 0xff, 0x02, 0x41, 0x22, 0xff, 0x0a, 0x4e, 0x2c, 0xff, 0x11, 0x5f, 0x3b, 0xff, 0x1b, 0x76, 0x50, 0xff, 0x1f, 0x8d, 0x61, 0xff, 0x1b, 0x95, 0x67, 0xff, 0x1b, 0x99, 0x69, 0xff, 0x16, 0x97, 0x67, 0xff, 0x15, 0x98, 0x68, 0xff, 0x12, 0x98, 0x66, 0xff, 0x15, 0x99, 0x68, 0xff, 0x16, 0x98, 0x67, 0xff, 0x0c, 0xa2, 0x61, 0xff, 0x1a, 0xb4, 0x6a, 0xff, 0x03, 0x86, 0x46, 0xff, 0x02, 0x84, 0x45, 0xff, 0x06, 0x83, 0x42, 0xff, 0x06, 0x82, 0x42, 0xff, 0x06, 0x81, 0x43, 0xff, 0x05, 0x82, 0x42, 0xff, 0x05, 0x82, 0x3e, 0xff, 0x06, 0x81, 0x3d, 0xff, 0x05, 0x78, 0x3a, 0xff, 0x10, 0x76, 0x40, 0xff, 0x0b, 0x5a, 0x30, 0xff, 0x01, 0x3a, 0x19, 0xff, 0x03, 0x33, 0x18, 0xff, 0x02, 0x32, 0x1a, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x06, 0x31, 0x1a, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x03, 0x32, 0x18, 0xff, 0x04, 0x42, 0x23, 0xff, 0x15, 0x70, 0x4a, 0xff, 0x1c, 0x8d, 0x62, 0xff, 0x15, 0x8d, 0x5f, 0xff, 0x11, 0x8c, 0x5e, 0xff, 0x11, 0x8c, 0x5e, 0xff, 0x10, 0x87, 0x5a, 0xff, 0x10, 0x83, 0x57, 0xff, 0x0f, 0x80, 0x54, 0xff, 0x0e, 0x80, 0x53, 0xff, 0x0f, 0x7e, 0x53, 0xff, 0x08, 0x69, 0x3b, 0xff, 0x08, 0x6d, 0x3e, 0xff, 0x0f, 0x78, 0x4a, 0xff, 0x16, 0x6a, 0x46, 0xff, 0x04, 0x3d, 0x22, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x01, 0x34, 0x1a, 0xff, 0x02, 0x38, 0x1a, 0xff, 0x05, 0x44, 0x23, 0xff, 0x08, 0x43, 0x1f, 0xff, 0x05, 0x59, 0x2d, 0xff, 0x0f, 0x81, 0x4e, 0xff, 0x02, 0x6a, 0x36, 0xff, 0x06, 0x67, 0x35, 0xff, 0x06, 0x67, 0x37, 0xff, 0x08, 0x66, 0x37, 0xff, 0x07, 0x66, 0x37, 0xff, 0x06, 0x65, 0x37, 0xff, 0x06, 0x65, 0x38, 0xff, 0x06, 0x66, 0x39, 0xff, 0x06, 0x65, 0x38, 0xff, 0x07, 0x63, 0x36, 0xff, 0x08, 0x60, 0x34, 0xff, 0x0c, 0x59, 0x32, 0xff, 0x01, 0x30, 0x15, 0xff, 0x07, 0x2f, 0x16, 0xff, 0x09, 0x3a, 0x20, 0xff, 0x03, 0x3b, 0x23, 0xff, 0x05, 0x2e, 0x1b, 0xff, 0x02, 0x2a, 0x13, 0xff, 0x0a, 0x44, 0x26, 0xff, 0x07, 0x4c, 0x28, 0xff, 0x0c, 0x4c, 0x29, 0xff, 0x06, 0x44, 0x24, 0xff, 0x02, 0x43, 0x1f, 0xff, 0x14, 0x6c, 0x3f, 0xff, 0x0e, 0x71, 0x3d, 0xff, 0x0f, 0x6b, 0x3a, 0xff, 0x0b, 0x58, 0x30, 0xff, 0x07, 0x40, 0x23, 0xff, 0x0d, 0x3c, 0x23, 0xff, 0x01, 0x2a, 0x12, 0xff, 0x06, 0x36, 0x1e, 0xff, 0x11, 0x44, 0x2c, 0xff, 0x06, 0x36, 0x1e, 0xff, 0x00, 0x27, 0x12, 0xff, 0x02, 0x28, 0x12, 0xff, 0x05, 0x2f, 0x18, 0xff, 0x09, 0x42, 0x26, 0xff, 0x04, 0x3a, 0x1f, 0xff, 0x02, 0x36, 0x1b, 0xff, 0x0c, 0x4d, 0x2c, 0xff, 0x0c, 0x57, 0x32, 0xff, 0x09, 0x5b, 0x31, 0xff, 0x0a, 0x57, 0x32, 0xff, 0x08, 0x48, 0x29, 0xff, 0x01, 0x38, 0x19, 0xff, 0x12, 0x5a, 0x36, 0xff, 0x08, 0x5b, 0x34, 0xff, 0x06, 0x5a, 0x30, 0xff, 0x0a, 0x59, 0x30, 0xff, 0x0d, 0x59, 0x30, 0xff, 0x0c, 0x5b, 0x34, 0xff, 0x09, 0x60, 0x37, 0xff, 0x07, 0x60, 0x35, 0xff, 0x0a, 0x4b, 0x2a, 0xff, 0x03, 0x33, 0x1c, 0xff, 0x01, 0x25, 0x14, 0xff, 0x00, 0x20, 0x0c, 0xff, 0x09, 0x3a, 0x21, 0xff, 0x04, 0x41, 0x24, 0xff, 0x02, 0x40, 0x20, 0xff, 0x01, 0x42, 0x1b, 0xff, 0x1a, 0x73, 0x46, 0xff, 0x1a, 0x77, 0x44, 0xff, 0x01, 0x4e, 0x18, 0xff, 0x03, 0x4b, 0x15, 0xff, 0x02, 0x4d, 0x17, 0xff, 0x03, 0x54, 0x1f, 0xff, 0x05, 0x56, 0x25, 0xff, 0x04, 0x57, 0x27, 0xff, 0x08, 0x59, 0x2b, 0xff, 0x09, 0x57, 0x2b, 0xff, 0x06, 0x4f, 0x25, 0xff, 0x06, 0x4d, 0x26, 0xff, 0x09, 0x4e, 0x29, 0xff, 0x0b, 0x50, 0x2d, 0xff, 0x09, 0x4e, 0x2d, 0xff, 0x06, 0x4d, 0x2d, 0xff, 0x08, 0x4b, 0x2d, 0xff, 0x02, 0x35, 0x1d, 0xff, 0x00, 0x27, 0x14, 0xff, 0x00, 0x26, 0x15, 0xff, 0x00, 0x27, 0x13, 0xff, 0x00, 0x29, 0x12, 0xff, 0x02, 0x35, 0x1c, 0xff, 0x0e, 0x46, 0x2c, 0xff, 0x11, 0x4c, 0x32, 0xff, 0x0b, 0x49, 0x30, 0xff, 0x07, 0x4f, 0x2d, 0xff, 0x0b, 0x5a, 0x31, 0xff, 0x08, 0x5a, 0x33, 0xff, 0x06, 0x56, 0x38, 0xff, 0x07, 0x57, 0x39, 0xff, 0x0d, 0x5c, 0x36, 0xff, 0x11, 0x54, 0x2d, 0xff, 0x05, 0x39, 0x1a, 0xff, 0x09, 0x43, 0x2a, 0xff, 0x18, 0x67, 0x41, 0xff, 0x06, 0x66, 0x35, 0xff, 0x07, 0x68, 0x3e, 0xff, 0x30, 0x6a, 0x9e, 0xff, 0x2e, 0x4d, 0xc5, 0xff, 0x29, 0x45, 0xca, 0xff, 0x35, 0x51, 0xcb, 0xff, 0x1b, 0x4b, 0x67, 0xff, 0x0c, 0x40, 0x2b, 0xff, 0x08, 0x30, 0x1f, 0xff, 0x03, 0x2f, 0x1a, 0xff, 0x1d, 0x64, 0x3c, 0xff, 0x13, 0x63, 0x34, 0xff, 0x1a, 0x62, 0x3d, 0xff, 0x0c, 0x46, 0x2a, 0xff, 0x00, 0x28, 0x14, 0xff, 0x09, 0x41, 0x2e, 0xff, 0x15, 0x54, 0x41, 0xff, 0x08, 0x30, 0x22, 0xff, 0x63, 0x6d, 0x6a, 0xff, + 0x00, 0x31, 0x1a, 0xff, 0x06, 0x44, 0x26, 0xff, 0x06, 0x4c, 0x25, 0xff, 0x0a, 0x52, 0x26, 0xff, 0x08, 0x55, 0x27, 0xff, 0x08, 0x50, 0x27, 0xff, 0x01, 0x31, 0x17, 0xff, 0x07, 0x24, 0x15, 0xff, 0x05, 0x24, 0x0f, 0xff, 0x02, 0x3f, 0x1d, 0xff, 0x06, 0x57, 0x2c, 0xff, 0x06, 0x5c, 0x2c, 0xff, 0x03, 0x5d, 0x2b, 0xff, 0x02, 0x5f, 0x2c, 0xff, 0x08, 0x5c, 0x2e, 0xff, 0x06, 0x43, 0x23, 0xff, 0x01, 0x27, 0x10, 0xff, 0x05, 0x23, 0x13, 0xff, 0x02, 0x26, 0x14, 0xff, 0x09, 0x43, 0x26, 0xff, 0x08, 0x4f, 0x2a, 0xff, 0x07, 0x50, 0x27, 0xff, 0x09, 0x4f, 0x28, 0xff, 0x05, 0x4f, 0x29, 0xff, 0x09, 0x4e, 0x28, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x02, 0x1f, 0x0e, 0xff, 0x00, 0x2f, 0x13, 0xff, 0x08, 0x54, 0x2b, 0xff, 0x03, 0x41, 0x1c, 0xff, 0x0e, 0x4c, 0x2b, 0xff, 0x06, 0x55, 0x2b, 0xff, 0x0f, 0x53, 0x2b, 0xff, 0x0c, 0x4c, 0x23, 0xff, 0x08, 0x51, 0x26, 0xff, 0x04, 0x5e, 0x2d, 0xff, 0x08, 0x65, 0x32, 0xff, 0x0d, 0x62, 0x2f, 0xff, 0x06, 0x49, 0x1e, 0xff, 0x01, 0x2b, 0x13, 0xff, 0x03, 0x2c, 0x16, 0xff, 0x05, 0x30, 0x1d, 0xff, 0x11, 0x42, 0x30, 0xff, 0x0d, 0x46, 0x31, 0xff, 0x07, 0x42, 0x2d, 0xff, 0x0b, 0x3f, 0x28, 0xff, 0x0e, 0x3a, 0x24, 0xff, 0x0c, 0x3a, 0x24, 0xff, 0x03, 0x38, 0x1d, 0xff, 0x0b, 0x5c, 0x30, 0xff, 0x14, 0x7b, 0x3f, 0xff, 0x08, 0x72, 0x2f, 0xff, 0x05, 0x4d, 0x2a, 0xff, 0x57, 0x58, 0x8a, 0xff, 0x6b, 0x3b, 0xae, 0xff, 0x72, 0x3a, 0xbd, 0xff, 0x26, 0x22, 0x57, 0xff, 0x05, 0x20, 0x17, 0xff, 0x16, 0x27, 0x2a, 0xff, 0x2d, 0x3b, 0x4b, 0xff, 0x10, 0x3a, 0x2c, 0xff, 0x07, 0x30, 0x0e, 0xff, 0x19, 0x70, 0x40, 0xff, 0x12, 0x94, 0x48, 0xff, 0x11, 0x67, 0x34, 0xff, 0x03, 0x2f, 0x12, 0xff, 0x03, 0x2d, 0x0a, 0xff, 0x0e, 0x78, 0x3a, 0xff, 0x20, 0xa0, 0x59, 0xff, 0x0a, 0x3a, 0x19, 0xff, 0x06, 0x1d, 0x0d, 0xff, 0x20, 0x65, 0x40, 0xff, 0x2c, 0x4d, 0x5c, 0xff, 0x4b, 0x41, 0x86, 0xff, 0x23, 0x21, 0x47, 0xff, 0x60, 0x57, 0x96, 0xff, 0x60, 0x5d, 0x99, 0xff, 0x32, 0x52, 0x76, 0xff, 0x10, 0x58, 0x44, 0xff, 0x05, 0x61, 0x45, 0xff, 0x0b, 0x70, 0x4c, 0xff, 0x0e, 0x7d, 0x4e, 0xff, 0x15, 0x8a, 0x58, 0xff, 0x10, 0x8a, 0x5b, 0xff, 0x0e, 0x8a, 0x5e, 0xff, 0x0c, 0x8c, 0x5d, 0xff, 0x0c, 0x8d, 0x5c, 0xff, 0x10, 0x8f, 0x61, 0xff, 0x10, 0x91, 0x62, 0xff, 0x12, 0x93, 0x61, 0xff, 0x12, 0x93, 0x60, 0xff, 0x13, 0x93, 0x60, 0xff, 0x10, 0x8f, 0x5d, 0xff, 0x0f, 0x8c, 0x5b, 0xff, 0x0e, 0x8a, 0x5c, 0xff, 0x0f, 0x8c, 0x5e, 0xff, 0x0f, 0x8b, 0x5d, 0xff, 0x0f, 0x8a, 0x5c, 0xff, 0x0f, 0x89, 0x5b, 0xff, 0x0e, 0x8a, 0x5c, 0xff, 0x0f, 0x8c, 0x5d, 0xff, 0x0f, 0x8f, 0x60, 0xff, 0x0f, 0x91, 0x62, 0xff, 0x10, 0x92, 0x61, 0xff, 0x10, 0x94, 0x61, 0xff, 0x0f, 0x96, 0x63, 0xff, 0x0e, 0x98, 0x66, 0xff, 0x0e, 0x98, 0x65, 0xff, 0x0f, 0x98, 0x68, 0xff, 0x12, 0x9a, 0x69, 0xff, 0x13, 0x9a, 0x6a, 0xff, 0x14, 0x99, 0x6a, 0xff, 0x14, 0x99, 0x69, 0xff, 0x13, 0x99, 0x69, 0xff, 0x12, 0x99, 0x69, 0xff, 0x11, 0x98, 0x68, 0xff, 0x11, 0x98, 0x68, 0xff, 0x0f, 0x98, 0x68, 0xff, 0x0e, 0x97, 0x67, 0xff, 0x11, 0x98, 0x68, 0xff, 0x12, 0x99, 0x69, 0xff, 0x11, 0x99, 0x69, 0xff, 0x10, 0x9a, 0x6a, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x10, 0x98, 0x68, 0xff, 0x10, 0x98, 0x68, 0xff, 0x0f, 0x98, 0x67, 0xff, 0x10, 0x99, 0x65, 0xff, 0x10, 0x99, 0x65, 0xff, 0x10, 0x9a, 0x65, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x10, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x68, 0xff, 0x0d, 0x99, 0x68, 0xff, 0x0d, 0x9a, 0x68, 0xff, 0x0d, 0x98, 0x66, 0xff, 0x15, 0x91, 0x62, 0xff, 0x12, 0x81, 0x56, 0xff, 0x10, 0x75, 0x4e, 0xff, 0x0e, 0x6e, 0x49, 0xff, 0x11, 0x6a, 0x48, 0xff, 0x10, 0x64, 0x43, 0xff, 0x0a, 0x62, 0x3f, 0xff, 0x08, 0x62, 0x3f, 0xff, 0x0b, 0x65, 0x40, 0xff, 0x11, 0x71, 0x49, 0xff, 0x1a, 0x83, 0x5a, 0xff, 0x20, 0x92, 0x66, 0xff, 0x1d, 0x99, 0x6a, 0xff, 0x17, 0x99, 0x68, 0xff, 0x13, 0x99, 0x67, 0xff, 0x10, 0x99, 0x66, 0xff, 0x0f, 0x98, 0x65, 0xff, 0x0f, 0x9a, 0x66, 0xff, 0x0f, 0x9b, 0x67, 0xff, 0x0d, 0x99, 0x65, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0d, 0xad, 0x67, 0xff, 0x12, 0xac, 0x60, 0xff, 0x05, 0x84, 0x46, 0xff, 0x01, 0x84, 0x44, 0xff, 0x03, 0x83, 0x3f, 0xff, 0x05, 0x82, 0x41, 0xff, 0x04, 0x80, 0x44, 0xff, 0x03, 0x82, 0x42, 0xff, 0x02, 0x82, 0x3c, 0xff, 0x05, 0x7e, 0x39, 0xff, 0x0a, 0x76, 0x3b, 0xff, 0x0a, 0x64, 0x34, 0xff, 0x01, 0x3e, 0x1c, 0xff, 0x02, 0x30, 0x16, 0xff, 0x08, 0x31, 0x1a, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x04, 0x31, 0x1a, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x01, 0x32, 0x19, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x18, 0x73, 0x4e, 0xff, 0x1e, 0x8f, 0x63, 0xff, 0x0f, 0x8c, 0x5e, 0xff, 0x10, 0x8e, 0x5f, 0xff, 0x10, 0x8f, 0x60, 0xff, 0x11, 0x8e, 0x60, 0xff, 0x14, 0x8d, 0x60, 0xff, 0x17, 0x8c, 0x61, 0xff, 0x15, 0x8b, 0x5f, 0xff, 0x14, 0x8c, 0x60, 0xff, 0x0c, 0x7f, 0x53, 0xff, 0x04, 0x65, 0x38, 0xff, 0x15, 0x85, 0x56, 0xff, 0x17, 0x81, 0x54, 0xff, 0x0c, 0x51, 0x31, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x01, 0x34, 0x1c, 0xff, 0x02, 0x38, 0x1f, 0xff, 0x04, 0x35, 0x18, 0xff, 0x02, 0x3d, 0x1d, 0xff, 0x0c, 0x43, 0x20, 0xff, 0x03, 0x4b, 0x20, 0xff, 0x0e, 0x80, 0x4c, 0xff, 0x04, 0x74, 0x40, 0xff, 0x08, 0x66, 0x35, 0xff, 0x09, 0x62, 0x34, 0xff, 0x08, 0x63, 0x34, 0xff, 0x09, 0x64, 0x35, 0xff, 0x05, 0x64, 0x35, 0xff, 0x03, 0x65, 0x37, 0xff, 0x04, 0x65, 0x38, 0xff, 0x06, 0x62, 0x35, 0xff, 0x09, 0x63, 0x36, 0xff, 0x06, 0x61, 0x34, 0xff, 0x0c, 0x60, 0x38, 0xff, 0x09, 0x3f, 0x25, 0xff, 0x02, 0x29, 0x10, 0xff, 0x05, 0x36, 0x1c, 0xff, 0x03, 0x3b, 0x23, 0xff, 0x07, 0x31, 0x1f, 0xff, 0x01, 0x28, 0x12, 0xff, 0x08, 0x40, 0x23, 0xff, 0x07, 0x4c, 0x28, 0xff, 0x0b, 0x4d, 0x28, 0xff, 0x08, 0x47, 0x27, 0xff, 0x01, 0x3e, 0x1d, 0xff, 0x0a, 0x5b, 0x32, 0xff, 0x0e, 0x6e, 0x3d, 0xff, 0x0b, 0x6b, 0x38, 0xff, 0x09, 0x5b, 0x31, 0xff, 0x01, 0x40, 0x21, 0xff, 0x0c, 0x3c, 0x25, 0xff, 0x04, 0x30, 0x19, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x0c, 0x3c, 0x25, 0xff, 0x06, 0x36, 0x20, 0xff, 0x00, 0x2a, 0x15, 0xff, 0x01, 0x26, 0x13, 0xff, 0x04, 0x2a, 0x16, 0xff, 0x0a, 0x42, 0x26, 0xff, 0x06, 0x3e, 0x22, 0xff, 0x01, 0x35, 0x1a, 0xff, 0x0c, 0x4a, 0x2b, 0xff, 0x09, 0x53, 0x2e, 0xff, 0x08, 0x59, 0x31, 0xff, 0x09, 0x55, 0x31, 0xff, 0x07, 0x48, 0x29, 0xff, 0x01, 0x35, 0x17, 0xff, 0x12, 0x58, 0x34, 0xff, 0x07, 0x59, 0x32, 0xff, 0x04, 0x59, 0x2f, 0xff, 0x0a, 0x59, 0x30, 0xff, 0x0c, 0x59, 0x2f, 0xff, 0x0b, 0x59, 0x32, 0xff, 0x06, 0x5d, 0x36, 0xff, 0x05, 0x60, 0x35, 0xff, 0x0d, 0x50, 0x2e, 0xff, 0x06, 0x37, 0x1f, 0xff, 0x02, 0x2a, 0x17, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x09, 0x39, 0x20, 0xff, 0x03, 0x40, 0x23, 0xff, 0x01, 0x3d, 0x1d, 0xff, 0x0a, 0x4e, 0x26, 0xff, 0x1e, 0x6a, 0x3d, 0xff, 0x04, 0x4e, 0x1d, 0xff, 0x00, 0x4b, 0x16, 0xff, 0x02, 0x4d, 0x18, 0xff, 0x04, 0x4f, 0x1c, 0xff, 0x05, 0x55, 0x24, 0xff, 0x03, 0x57, 0x28, 0xff, 0x07, 0x5b, 0x2d, 0xff, 0x05, 0x57, 0x2a, 0xff, 0x03, 0x51, 0x27, 0xff, 0x02, 0x4d, 0x24, 0xff, 0x06, 0x4e, 0x28, 0xff, 0x0a, 0x4f, 0x2b, 0xff, 0x0b, 0x4f, 0x2e, 0xff, 0x08, 0x4d, 0x2d, 0xff, 0x09, 0x4d, 0x2d, 0xff, 0x09, 0x45, 0x28, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x01, 0x27, 0x13, 0xff, 0x03, 0x26, 0x13, 0xff, 0x01, 0x27, 0x11, 0xff, 0x05, 0x32, 0x17, 0xff, 0x11, 0x49, 0x2a, 0xff, 0x0f, 0x51, 0x2a, 0xff, 0x0a, 0x4f, 0x2d, 0xff, 0x08, 0x4f, 0x2e, 0xff, 0x09, 0x56, 0x2f, 0xff, 0x0b, 0x5b, 0x34, 0xff, 0x09, 0x5b, 0x35, 0xff, 0x07, 0x5c, 0x32, 0xff, 0x09, 0x5d, 0x34, 0xff, 0x0f, 0x58, 0x35, 0xff, 0x04, 0x3c, 0x1f, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x18, 0x57, 0x3a, 0xff, 0x12, 0x66, 0x3b, 0xff, 0x09, 0x6c, 0x42, 0xff, 0x06, 0x6c, 0x41, 0xff, 0x1a, 0x63, 0x70, 0xff, 0x40, 0x6b, 0xbf, 0xff, 0x42, 0x5e, 0xda, 0xff, 0x4a, 0x69, 0xd4, 0xff, 0x0b, 0x3d, 0x48, 0xff, 0x07, 0x3a, 0x21, 0xff, 0x0d, 0x36, 0x27, 0xff, 0x09, 0x3c, 0x27, 0xff, 0x18, 0x64, 0x3a, 0xff, 0x12, 0x62, 0x32, 0xff, 0x17, 0x5c, 0x37, 0xff, 0x04, 0x38, 0x1d, 0xff, 0x01, 0x2c, 0x1a, 0xff, 0x11, 0x49, 0x38, 0xff, 0x13, 0x52, 0x41, 0xff, 0x07, 0x2f, 0x23, 0xff, 0x63, 0x6d, 0x6b, 0xff, + 0x01, 0x31, 0x1a, 0xff, 0x08, 0x44, 0x24, 0xff, 0x05, 0x4a, 0x24, 0xff, 0x09, 0x51, 0x27, 0xff, 0x09, 0x54, 0x28, 0xff, 0x09, 0x51, 0x28, 0xff, 0x01, 0x34, 0x16, 0xff, 0x04, 0x24, 0x13, 0xff, 0x03, 0x24, 0x0f, 0xff, 0x03, 0x3b, 0x1b, 0xff, 0x09, 0x54, 0x2c, 0xff, 0x07, 0x5b, 0x2a, 0xff, 0x03, 0x5c, 0x2a, 0xff, 0x05, 0x5d, 0x2c, 0xff, 0x0a, 0x5b, 0x2f, 0xff, 0x08, 0x4a, 0x26, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x04, 0x23, 0x13, 0xff, 0x02, 0x26, 0x14, 0xff, 0x0a, 0x44, 0x26, 0xff, 0x08, 0x4f, 0x29, 0xff, 0x06, 0x50, 0x27, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x05, 0x50, 0x28, 0xff, 0x09, 0x4f, 0x28, 0xff, 0x03, 0x2e, 0x17, 0xff, 0x02, 0x1f, 0x10, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x08, 0x4a, 0x25, 0xff, 0x05, 0x45, 0x1e, 0xff, 0x0d, 0x52, 0x2d, 0xff, 0x08, 0x55, 0x2c, 0xff, 0x0e, 0x51, 0x2a, 0xff, 0x09, 0x4b, 0x21, 0xff, 0x0c, 0x58, 0x29, 0xff, 0x07, 0x64, 0x2d, 0xff, 0x0d, 0x66, 0x32, 0xff, 0x0a, 0x4f, 0x27, 0xff, 0x01, 0x33, 0x15, 0xff, 0x05, 0x2b, 0x17, 0xff, 0x00, 0x2b, 0x15, 0xff, 0x0b, 0x40, 0x2a, 0xff, 0x18, 0x4d, 0x37, 0xff, 0x10, 0x4d, 0x36, 0xff, 0x08, 0x48, 0x32, 0xff, 0x0a, 0x3e, 0x28, 0xff, 0x11, 0x35, 0x24, 0xff, 0x0a, 0x30, 0x1e, 0xff, 0x02, 0x3f, 0x1a, 0xff, 0x10, 0x80, 0x43, 0xff, 0x09, 0x89, 0x40, 0xff, 0x06, 0x7d, 0x33, 0xff, 0x0d, 0x59, 0x35, 0xff, 0x62, 0x57, 0x97, 0xff, 0x7b, 0x3b, 0xc3, 0xff, 0x73, 0x39, 0xbe, 0xff, 0x20, 0x1d, 0x49, 0xff, 0x1b, 0x1f, 0x37, 0xff, 0x23, 0x29, 0x42, 0xff, 0x0e, 0x37, 0x2d, 0xff, 0x12, 0x5c, 0x2d, 0xff, 0x06, 0x38, 0x12, 0xff, 0x13, 0x8c, 0x55, 0xff, 0x19, 0xa3, 0x57, 0xff, 0x14, 0x6a, 0x35, 0xff, 0x02, 0x28, 0x09, 0xff, 0x0b, 0x47, 0x1c, 0xff, 0x2e, 0xa4, 0x5e, 0xff, 0x14, 0x7b, 0x42, 0xff, 0x23, 0x33, 0x3e, 0xff, 0x31, 0x32, 0x4f, 0xff, 0x12, 0x47, 0x2f, 0xff, 0x13, 0x39, 0x3b, 0xff, 0x19, 0x29, 0x3f, 0xff, 0x27, 0x34, 0x44, 0xff, 0x77, 0x77, 0xac, 0xff, 0x59, 0x5d, 0x9c, 0xff, 0x3d, 0x60, 0x8c, 0xff, 0x1f, 0x6d, 0x5d, 0xff, 0x05, 0x6e, 0x48, 0xff, 0x0d, 0x7d, 0x52, 0xff, 0x10, 0x89, 0x57, 0xff, 0x13, 0x91, 0x5e, 0xff, 0x0d, 0x8e, 0x5e, 0xff, 0x0b, 0x8e, 0x60, 0xff, 0x0b, 0x8f, 0x61, 0xff, 0x0d, 0x91, 0x61, 0xff, 0x0f, 0x93, 0x62, 0xff, 0x10, 0x94, 0x62, 0xff, 0x11, 0x94, 0x61, 0xff, 0x10, 0x93, 0x61, 0xff, 0x13, 0x95, 0x63, 0xff, 0x12, 0x93, 0x61, 0xff, 0x11, 0x91, 0x60, 0xff, 0x0f, 0x8f, 0x5f, 0xff, 0x0e, 0x8d, 0x5e, 0xff, 0x0f, 0x8d, 0x5d, 0xff, 0x0e, 0x8e, 0x5e, 0xff, 0x0e, 0x8f, 0x5f, 0xff, 0x0f, 0x91, 0x61, 0xff, 0x0e, 0x93, 0x62, 0xff, 0x10, 0x96, 0x65, 0xff, 0x10, 0x98, 0x66, 0xff, 0x11, 0x99, 0x66, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x11, 0x9b, 0x68, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x0f, 0x9d, 0x69, 0xff, 0x0e, 0x9c, 0x6a, 0xff, 0x0f, 0x9b, 0x69, 0xff, 0x10, 0x9a, 0x68, 0xff, 0x10, 0x9b, 0x69, 0xff, 0x11, 0x9b, 0x69, 0xff, 0x11, 0x9b, 0x6a, 0xff, 0x11, 0x9a, 0x6a, 0xff, 0x10, 0x99, 0x69, 0xff, 0x0f, 0x9a, 0x69, 0xff, 0x0f, 0x9a, 0x69, 0xff, 0x0e, 0x99, 0x68, 0xff, 0x10, 0x99, 0x68, 0xff, 0x12, 0x9a, 0x69, 0xff, 0x11, 0x9a, 0x69, 0xff, 0x10, 0x9a, 0x69, 0xff, 0x0f, 0x99, 0x68, 0xff, 0x0e, 0x99, 0x68, 0xff, 0x0f, 0x99, 0x67, 0xff, 0x0f, 0x98, 0x67, 0xff, 0x10, 0x99, 0x68, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x9a, 0x64, 0xff, 0x11, 0x9b, 0x65, 0xff, 0x10, 0x9b, 0x65, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x13, 0x98, 0x67, 0xff, 0x17, 0x9a, 0x6a, 0xff, 0x18, 0x97, 0x6a, 0xff, 0x19, 0x96, 0x69, 0xff, 0x1b, 0x94, 0x6a, 0xff, 0x1c, 0x93, 0x69, 0xff, 0x19, 0x93, 0x68, 0xff, 0x16, 0x91, 0x65, 0xff, 0x1a, 0x94, 0x67, 0xff, 0x1a, 0x97, 0x68, 0xff, 0x18, 0x99, 0x68, 0xff, 0x14, 0x9a, 0x68, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0e, 0x99, 0x65, 0xff, 0x10, 0x99, 0x65, 0xff, 0x11, 0x98, 0x65, 0xff, 0x11, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x68, 0xff, 0x0b, 0x99, 0x66, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0a, 0x9c, 0x64, 0xff, 0x12, 0xb5, 0x6d, 0xff, 0x08, 0x9f, 0x52, 0xff, 0x03, 0x83, 0x43, 0xff, 0x01, 0x85, 0x42, 0xff, 0x01, 0x84, 0x3f, 0xff, 0x02, 0x83, 0x41, 0xff, 0x06, 0x80, 0x43, 0xff, 0x06, 0x81, 0x41, 0xff, 0x08, 0x7e, 0x3c, 0xff, 0x10, 0x77, 0x3d, 0xff, 0x07, 0x60, 0x2f, 0xff, 0x01, 0x43, 0x1d, 0xff, 0x02, 0x33, 0x17, 0xff, 0x09, 0x31, 0x1a, 0xff, 0x0a, 0x30, 0x1a, 0xff, 0x05, 0x32, 0x19, 0xff, 0x00, 0x32, 0x19, 0xff, 0x02, 0x32, 0x1b, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x03, 0x32, 0x19, 0xff, 0x05, 0x45, 0x27, 0xff, 0x15, 0x6a, 0x46, 0xff, 0x1d, 0x8c, 0x62, 0xff, 0x12, 0x90, 0x60, 0xff, 0x10, 0x90, 0x60, 0xff, 0x13, 0x8f, 0x61, 0xff, 0x12, 0x90, 0x61, 0xff, 0x10, 0x8f, 0x60, 0xff, 0x11, 0x8e, 0x60, 0xff, 0x13, 0x8c, 0x61, 0xff, 0x11, 0x84, 0x59, 0xff, 0x13, 0x81, 0x56, 0xff, 0x1b, 0x84, 0x5b, 0xff, 0x1c, 0x80, 0x58, 0xff, 0x20, 0x81, 0x59, 0xff, 0x18, 0x6d, 0x47, 0xff, 0x03, 0x3b, 0x1c, 0xff, 0x02, 0x32, 0x16, 0xff, 0x08, 0x47, 0x2a, 0xff, 0x16, 0x61, 0x42, 0xff, 0x03, 0x44, 0x24, 0xff, 0x01, 0x38, 0x1a, 0xff, 0x0a, 0x3e, 0x1e, 0xff, 0x06, 0x47, 0x1f, 0xff, 0x09, 0x6a, 0x38, 0xff, 0x10, 0x7e, 0x4a, 0xff, 0x05, 0x65, 0x33, 0xff, 0x05, 0x61, 0x31, 0xff, 0x03, 0x61, 0x32, 0xff, 0x07, 0x61, 0x34, 0xff, 0x05, 0x63, 0x35, 0xff, 0x03, 0x63, 0x36, 0xff, 0x04, 0x62, 0x35, 0xff, 0x06, 0x61, 0x35, 0xff, 0x07, 0x62, 0x36, 0xff, 0x05, 0x62, 0x36, 0xff, 0x06, 0x60, 0x37, 0xff, 0x0d, 0x51, 0x32, 0xff, 0x01, 0x2a, 0x10, 0xff, 0x03, 0x2f, 0x17, 0xff, 0x08, 0x3a, 0x24, 0xff, 0x07, 0x32, 0x20, 0xff, 0x00, 0x29, 0x11, 0xff, 0x05, 0x3d, 0x20, 0xff, 0x0c, 0x4c, 0x29, 0xff, 0x09, 0x4c, 0x27, 0xff, 0x0d, 0x4a, 0x29, 0xff, 0x07, 0x42, 0x22, 0xff, 0x02, 0x45, 0x20, 0xff, 0x0c, 0x68, 0x3c, 0xff, 0x0b, 0x6b, 0x3b, 0xff, 0x09, 0x5f, 0x32, 0xff, 0x04, 0x47, 0x23, 0xff, 0x05, 0x37, 0x1d, 0xff, 0x0a, 0x39, 0x21, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x03, 0x30, 0x1a, 0xff, 0x02, 0x2c, 0x17, 0xff, 0x01, 0x28, 0x15, 0xff, 0x02, 0x28, 0x14, 0xff, 0x0a, 0x41, 0x25, 0xff, 0x07, 0x43, 0x26, 0xff, 0x01, 0x35, 0x19, 0xff, 0x0f, 0x47, 0x29, 0xff, 0x08, 0x50, 0x2c, 0xff, 0x06, 0x56, 0x30, 0xff, 0x0b, 0x55, 0x30, 0xff, 0x08, 0x49, 0x28, 0xff, 0x01, 0x34, 0x18, 0xff, 0x11, 0x53, 0x32, 0xff, 0x07, 0x58, 0x30, 0xff, 0x04, 0x5a, 0x2f, 0xff, 0x0a, 0x59, 0x2f, 0xff, 0x0e, 0x57, 0x2f, 0xff, 0x0c, 0x58, 0x31, 0xff, 0x08, 0x5c, 0x34, 0xff, 0x08, 0x5e, 0x35, 0xff, 0x0f, 0x52, 0x31, 0xff, 0x05, 0x3b, 0x1f, 0xff, 0x02, 0x2b, 0x17, 0xff, 0x00, 0x21, 0x10, 0xff, 0x0a, 0x35, 0x21, 0xff, 0x04, 0x3b, 0x21, 0xff, 0x02, 0x3d, 0x1e, 0xff, 0x11, 0x54, 0x2c, 0xff, 0x0a, 0x51, 0x23, 0xff, 0x00, 0x48, 0x17, 0xff, 0x00, 0x4b, 0x17, 0xff, 0x00, 0x4f, 0x19, 0xff, 0x01, 0x56, 0x21, 0xff, 0x03, 0x58, 0x26, 0xff, 0x08, 0x59, 0x2c, 0xff, 0x08, 0x55, 0x2c, 0xff, 0x02, 0x4e, 0x25, 0xff, 0x02, 0x4c, 0x24, 0xff, 0x03, 0x4d, 0x26, 0xff, 0x05, 0x4e, 0x29, 0xff, 0x07, 0x4e, 0x2a, 0xff, 0x09, 0x4f, 0x2d, 0xff, 0x08, 0x4e, 0x2c, 0xff, 0x0b, 0x4c, 0x2d, 0xff, 0x09, 0x3e, 0x22, 0xff, 0x02, 0x29, 0x12, 0xff, 0x04, 0x25, 0x11, 0xff, 0x04, 0x25, 0x10, 0xff, 0x03, 0x2f, 0x16, 0xff, 0x0e, 0x45, 0x26, 0xff, 0x13, 0x51, 0x2d, 0xff, 0x0c, 0x51, 0x27, 0xff, 0x06, 0x51, 0x2c, 0xff, 0x05, 0x52, 0x2f, 0xff, 0x0c, 0x58, 0x32, 0xff, 0x0f, 0x5a, 0x36, 0xff, 0x0a, 0x5b, 0x36, 0xff, 0x06, 0x5a, 0x32, 0xff, 0x0b, 0x58, 0x36, 0xff, 0x0b, 0x49, 0x2f, 0xff, 0x00, 0x2b, 0x17, 0xff, 0x05, 0x33, 0x1e, 0xff, 0x19, 0x65, 0x42, 0xff, 0x0d, 0x6b, 0x3d, 0xff, 0x13, 0x7b, 0x50, 0xff, 0x06, 0x6f, 0x42, 0xff, 0x0d, 0x60, 0x4a, 0xff, 0x21, 0x61, 0x7b, 0xff, 0x3a, 0x68, 0xa9, 0xff, 0x38, 0x5f, 0x95, 0xff, 0x08, 0x38, 0x36, 0xff, 0x02, 0x2c, 0x17, 0xff, 0x0d, 0x39, 0x26, 0xff, 0x0e, 0x4a, 0x2f, 0xff, 0x14, 0x60, 0x38, 0xff, 0x17, 0x65, 0x39, 0xff, 0x0f, 0x51, 0x30, 0xff, 0x01, 0x2f, 0x18, 0xff, 0x05, 0x32, 0x24, 0xff, 0x15, 0x51, 0x42, 0xff, 0x14, 0x51, 0x3e, 0xff, 0x09, 0x30, 0x21, 0xff, 0x61, 0x70, 0x68, 0xff, + 0x04, 0x32, 0x19, 0xff, 0x09, 0x45, 0x23, 0xff, 0x06, 0x49, 0x24, 0xff, 0x0a, 0x4f, 0x28, 0xff, 0x0b, 0x52, 0x29, 0xff, 0x0b, 0x53, 0x28, 0xff, 0x02, 0x38, 0x17, 0xff, 0x01, 0x23, 0x12, 0xff, 0x01, 0x26, 0x11, 0xff, 0x06, 0x37, 0x1a, 0xff, 0x0d, 0x51, 0x2b, 0xff, 0x06, 0x59, 0x2a, 0xff, 0x02, 0x5a, 0x29, 0xff, 0x07, 0x59, 0x2b, 0xff, 0x0b, 0x59, 0x2e, 0xff, 0x0a, 0x50, 0x29, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x02, 0x24, 0x13, 0xff, 0x01, 0x26, 0x13, 0xff, 0x0b, 0x45, 0x25, 0xff, 0x09, 0x4f, 0x27, 0xff, 0x05, 0x51, 0x27, 0xff, 0x04, 0x50, 0x27, 0xff, 0x05, 0x51, 0x27, 0xff, 0x0a, 0x50, 0x28, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x03, 0x1e, 0x12, 0xff, 0x04, 0x28, 0x14, 0xff, 0x08, 0x40, 0x1e, 0xff, 0x06, 0x4e, 0x24, 0xff, 0x0a, 0x55, 0x2c, 0xff, 0x0a, 0x55, 0x2b, 0xff, 0x07, 0x4c, 0x25, 0xff, 0x07, 0x4f, 0x24, 0xff, 0x0b, 0x5d, 0x2a, 0xff, 0x0a, 0x66, 0x2d, 0xff, 0x0e, 0x60, 0x2e, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x03, 0x29, 0x17, 0xff, 0x02, 0x29, 0x15, 0xff, 0x01, 0x32, 0x1a, 0xff, 0x0e, 0x4c, 0x33, 0xff, 0x12, 0x4f, 0x37, 0xff, 0x0f, 0x51, 0x38, 0xff, 0x0b, 0x51, 0x3a, 0xff, 0x0b, 0x42, 0x2e, 0xff, 0x10, 0x35, 0x25, 0xff, 0x07, 0x2d, 0x1a, 0xff, 0x0a, 0x5c, 0x2d, 0xff, 0x0c, 0x8f, 0x49, 0xff, 0x05, 0x90, 0x43, 0xff, 0x06, 0x81, 0x36, 0xff, 0x0a, 0x5f, 0x33, 0xff, 0x4d, 0x4c, 0x81, 0xff, 0x7a, 0x44, 0xbd, 0xff, 0x5e, 0x34, 0xa4, 0xff, 0x1f, 0x1a, 0x45, 0xff, 0x50, 0x3c, 0x7e, 0xff, 0x53, 0x40, 0x83, 0xff, 0x22, 0x4c, 0x52, 0xff, 0x17, 0x6d, 0x31, 0xff, 0x04, 0x42, 0x16, 0xff, 0x18, 0xaa, 0x6d, 0xff, 0x1c, 0x9b, 0x5a, 0xff, 0x08, 0x45, 0x1f, 0xff, 0x01, 0x20, 0x08, 0xff, 0x21, 0x6b, 0x38, 0xff, 0x2b, 0x97, 0x53, 0xff, 0x09, 0x52, 0x2a, 0xff, 0x49, 0x46, 0x78, 0xff, 0x63, 0x53, 0x98, 0xff, 0x16, 0x45, 0x30, 0xff, 0x10, 0x41, 0x31, 0xff, 0x0e, 0x31, 0x32, 0xff, 0x29, 0x41, 0x52, 0xff, 0x65, 0x75, 0x9b, 0xff, 0x4e, 0x64, 0x94, 0xff, 0x36, 0x63, 0x88, 0xff, 0x26, 0x73, 0x6a, 0xff, 0x0a, 0x76, 0x4d, 0xff, 0x0e, 0x81, 0x55, 0xff, 0x11, 0x8d, 0x5d, 0xff, 0x11, 0x93, 0x61, 0xff, 0x0d, 0x92, 0x60, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0e, 0x92, 0x63, 0xff, 0x10, 0x92, 0x63, 0xff, 0x10, 0x93, 0x61, 0xff, 0x11, 0x93, 0x61, 0xff, 0x11, 0x95, 0x63, 0xff, 0x11, 0x95, 0x64, 0xff, 0x14, 0x98, 0x66, 0xff, 0x14, 0x98, 0x66, 0xff, 0x11, 0x96, 0x64, 0xff, 0x0e, 0x93, 0x61, 0xff, 0x0d, 0x91, 0x5f, 0xff, 0x0f, 0x91, 0x5f, 0xff, 0x0d, 0x91, 0x60, 0xff, 0x0e, 0x94, 0x62, 0xff, 0x0f, 0x98, 0x65, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x10, 0x9c, 0x68, 0xff, 0x10, 0x9d, 0x6a, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0d, 0x9b, 0x67, 0xff, 0x0e, 0x9b, 0x67, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9a, 0x69, 0xff, 0x0e, 0x9a, 0x69, 0xff, 0x0e, 0x9a, 0x68, 0xff, 0x0d, 0x9a, 0x67, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x11, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x10, 0x9a, 0x68, 0xff, 0x10, 0x99, 0x67, 0xff, 0x11, 0x99, 0x67, 0xff, 0x10, 0x99, 0x67, 0xff, 0x11, 0x99, 0x67, 0xff, 0x12, 0x99, 0x67, 0xff, 0x12, 0x99, 0x67, 0xff, 0x12, 0x9a, 0x67, 0xff, 0x10, 0x98, 0x66, 0xff, 0x10, 0x98, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x98, 0x65, 0xff, 0x10, 0x98, 0x64, 0xff, 0x12, 0x98, 0x65, 0xff, 0x12, 0x98, 0x67, 0xff, 0x12, 0x98, 0x6a, 0xff, 0x0e, 0x97, 0x68, 0xff, 0x0a, 0x9b, 0x64, 0xff, 0x09, 0x9f, 0x63, 0xff, 0x17, 0xb7, 0x6e, 0xff, 0x02, 0x93, 0x49, 0xff, 0x02, 0x85, 0x40, 0xff, 0x04, 0x86, 0x42, 0xff, 0x01, 0x83, 0x40, 0xff, 0x02, 0x84, 0x41, 0xff, 0x09, 0x82, 0x43, 0xff, 0x09, 0x7f, 0x41, 0xff, 0x11, 0x78, 0x40, 0xff, 0x12, 0x66, 0x38, 0xff, 0x01, 0x42, 0x1c, 0xff, 0x00, 0x35, 0x17, 0xff, 0x05, 0x33, 0x1c, 0xff, 0x09, 0x30, 0x1b, 0xff, 0x08, 0x31, 0x1a, 0xff, 0x03, 0x32, 0x18, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x01, 0x31, 0x1a, 0xff, 0x02, 0x32, 0x18, 0xff, 0x03, 0x3e, 0x20, 0xff, 0x15, 0x6e, 0x4a, 0xff, 0x1e, 0x8b, 0x61, 0xff, 0x13, 0x90, 0x61, 0xff, 0x0f, 0x91, 0x60, 0xff, 0x11, 0x90, 0x60, 0xff, 0x15, 0x8f, 0x61, 0xff, 0x13, 0x8f, 0x61, 0xff, 0x10, 0x90, 0x61, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x14, 0x90, 0x62, 0xff, 0x0f, 0x7e, 0x52, 0xff, 0x06, 0x65, 0x3b, 0xff, 0x15, 0x6f, 0x49, 0xff, 0x14, 0x6c, 0x48, 0xff, 0x10, 0x5a, 0x38, 0xff, 0x07, 0x44, 0x23, 0xff, 0x00, 0x35, 0x16, 0xff, 0x02, 0x3c, 0x1b, 0xff, 0x14, 0x67, 0x41, 0xff, 0x21, 0x81, 0x5a, 0xff, 0x0b, 0x67, 0x43, 0xff, 0x01, 0x42, 0x24, 0xff, 0x05, 0x39, 0x1a, 0xff, 0x07, 0x42, 0x1d, 0xff, 0x02, 0x54, 0x26, 0xff, 0x16, 0x7b, 0x49, 0xff, 0x06, 0x6a, 0x37, 0xff, 0x03, 0x64, 0x32, 0xff, 0x02, 0x60, 0x31, 0xff, 0x04, 0x5f, 0x32, 0xff, 0x06, 0x60, 0x34, 0xff, 0x07, 0x61, 0x35, 0xff, 0x07, 0x61, 0x35, 0xff, 0x08, 0x62, 0x37, 0xff, 0x05, 0x60, 0x35, 0xff, 0x05, 0x61, 0x36, 0xff, 0x05, 0x60, 0x37, 0xff, 0x0c, 0x5b, 0x38, 0xff, 0x02, 0x31, 0x16, 0xff, 0x01, 0x28, 0x12, 0xff, 0x0d, 0x37, 0x24, 0xff, 0x08, 0x32, 0x1f, 0xff, 0x00, 0x2a, 0x11, 0xff, 0x04, 0x3a, 0x1d, 0xff, 0x10, 0x4b, 0x2b, 0xff, 0x09, 0x4c, 0x28, 0xff, 0x0f, 0x4c, 0x2a, 0xff, 0x0b, 0x45, 0x26, 0xff, 0x00, 0x3b, 0x1a, 0xff, 0x05, 0x56, 0x30, 0xff, 0x0e, 0x6a, 0x3f, 0xff, 0x0a, 0x61, 0x34, 0xff, 0x08, 0x4f, 0x26, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x0a, 0x39, 0x20, 0xff, 0x06, 0x33, 0x1c, 0xff, 0x00, 0x28, 0x11, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x05, 0x2d, 0x17, 0xff, 0x03, 0x2a, 0x15, 0xff, 0x01, 0x28, 0x12, 0xff, 0x0b, 0x3f, 0x22, 0xff, 0x06, 0x47, 0x28, 0xff, 0x01, 0x37, 0x19, 0xff, 0x0f, 0x42, 0x25, 0xff, 0x0a, 0x4f, 0x2e, 0xff, 0x05, 0x53, 0x2e, 0xff, 0x0b, 0x54, 0x2e, 0xff, 0x0a, 0x49, 0x27, 0xff, 0x01, 0x33, 0x19, 0xff, 0x0f, 0x4e, 0x30, 0xff, 0x09, 0x58, 0x30, 0xff, 0x05, 0x5a, 0x2e, 0xff, 0x0a, 0x59, 0x2f, 0xff, 0x0d, 0x57, 0x2f, 0xff, 0x0d, 0x59, 0x30, 0xff, 0x0a, 0x5d, 0x32, 0xff, 0x0d, 0x5c, 0x36, 0xff, 0x0f, 0x54, 0x33, 0xff, 0x04, 0x3f, 0x20, 0xff, 0x03, 0x2e, 0x19, 0xff, 0x01, 0x23, 0x13, 0xff, 0x09, 0x31, 0x20, 0xff, 0x05, 0x38, 0x21, 0xff, 0x05, 0x43, 0x24, 0xff, 0x0f, 0x52, 0x29, 0xff, 0x01, 0x48, 0x18, 0xff, 0x00, 0x4a, 0x17, 0xff, 0x02, 0x4d, 0x17, 0xff, 0x02, 0x51, 0x1b, 0xff, 0x00, 0x5a, 0x24, 0xff, 0x01, 0x5a, 0x27, 0xff, 0x0c, 0x57, 0x2c, 0xff, 0x05, 0x4b, 0x24, 0xff, 0x04, 0x49, 0x26, 0xff, 0x06, 0x4d, 0x29, 0xff, 0x05, 0x4d, 0x29, 0xff, 0x06, 0x4e, 0x2a, 0xff, 0x06, 0x4e, 0x2b, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x09, 0x4e, 0x2b, 0xff, 0x0a, 0x4c, 0x2d, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x04, 0x28, 0x11, 0xff, 0x04, 0x23, 0x10, 0xff, 0x02, 0x27, 0x11, 0xff, 0x06, 0x3e, 0x22, 0xff, 0x0e, 0x4f, 0x2f, 0xff, 0x0b, 0x51, 0x2a, 0xff, 0x0c, 0x50, 0x2a, 0xff, 0x07, 0x51, 0x2f, 0xff, 0x05, 0x53, 0x33, 0xff, 0x0f, 0x58, 0x35, 0xff, 0x11, 0x5a, 0x34, 0xff, 0x09, 0x5b, 0x31, 0xff, 0x03, 0x56, 0x2f, 0xff, 0x0e, 0x54, 0x37, 0xff, 0x06, 0x3a, 0x23, 0xff, 0x01, 0x27, 0x12, 0xff, 0x0d, 0x44, 0x2c, 0xff, 0x0f, 0x6a, 0x45, 0xff, 0x0e, 0x76, 0x49, 0xff, 0x13, 0x7f, 0x4e, 0xff, 0x07, 0x71, 0x40, 0xff, 0x0f, 0x63, 0x3c, 0xff, 0x06, 0x55, 0x44, 0xff, 0x0e, 0x4e, 0x50, 0xff, 0x11, 0x40, 0x42, 0xff, 0x0b, 0x37, 0x2d, 0xff, 0x01, 0x27, 0x18, 0xff, 0x0a, 0x38, 0x22, 0xff, 0x0f, 0x52, 0x32, 0xff, 0x13, 0x60, 0x38, 0xff, 0x19, 0x66, 0x3d, 0xff, 0x0b, 0x4b, 0x2c, 0xff, 0x01, 0x2c, 0x19, 0xff, 0x08, 0x3c, 0x30, 0xff, 0x12, 0x53, 0x43, 0xff, 0x16, 0x51, 0x3e, 0xff, 0x0b, 0x2f, 0x1f, 0xff, 0x60, 0x70, 0x64, 0xff, + 0x05, 0x33, 0x1a, 0xff, 0x09, 0x45, 0x23, 0xff, 0x07, 0x48, 0x23, 0xff, 0x0b, 0x4f, 0x29, 0xff, 0x0a, 0x50, 0x29, 0xff, 0x0b, 0x53, 0x28, 0xff, 0x05, 0x3d, 0x1b, 0xff, 0x00, 0x25, 0x11, 0xff, 0x00, 0x26, 0x10, 0xff, 0x05, 0x34, 0x18, 0xff, 0x0d, 0x4f, 0x2a, 0xff, 0x05, 0x58, 0x2b, 0xff, 0x02, 0x58, 0x28, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x09, 0x59, 0x2d, 0xff, 0x0c, 0x54, 0x2d, 0xff, 0x02, 0x2f, 0x14, 0xff, 0x01, 0x23, 0x13, 0xff, 0x01, 0x27, 0x14, 0xff, 0x0c, 0x45, 0x25, 0xff, 0x08, 0x4f, 0x27, 0xff, 0x05, 0x51, 0x27, 0xff, 0x05, 0x50, 0x27, 0xff, 0x06, 0x50, 0x27, 0xff, 0x09, 0x50, 0x27, 0xff, 0x03, 0x2f, 0x17, 0xff, 0x02, 0x1e, 0x12, 0xff, 0x03, 0x26, 0x14, 0xff, 0x03, 0x3b, 0x1a, 0xff, 0x0a, 0x53, 0x2a, 0xff, 0x0a, 0x54, 0x2c, 0xff, 0x0a, 0x52, 0x2a, 0xff, 0x01, 0x47, 0x1e, 0xff, 0x0b, 0x59, 0x2b, 0xff, 0x0f, 0x62, 0x30, 0xff, 0x11, 0x63, 0x32, 0xff, 0x06, 0x4a, 0x22, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x04, 0x29, 0x18, 0xff, 0x01, 0x2b, 0x15, 0xff, 0x09, 0x44, 0x2c, 0xff, 0x11, 0x52, 0x39, 0xff, 0x13, 0x50, 0x38, 0xff, 0x0d, 0x4e, 0x36, 0xff, 0x06, 0x49, 0x30, 0xff, 0x07, 0x3c, 0x28, 0xff, 0x09, 0x34, 0x1e, 0xff, 0x04, 0x3f, 0x1a, 0xff, 0x1d, 0x88, 0x4d, 0xff, 0x13, 0x93, 0x4f, 0xff, 0x15, 0x8c, 0x4a, 0xff, 0x05, 0x73, 0x2e, 0xff, 0x06, 0x65, 0x2c, 0xff, 0x18, 0x38, 0x3e, 0xff, 0x43, 0x39, 0x6d, 0xff, 0x29, 0x25, 0x4f, 0xff, 0x32, 0x33, 0x48, 0xff, 0x92, 0x6c, 0xcb, 0xff, 0x8c, 0x59, 0xce, 0xff, 0x3b, 0x54, 0x7e, 0xff, 0x10, 0x5e, 0x2d, 0xff, 0x09, 0x5a, 0x27, 0xff, 0x30, 0xbe, 0x86, 0xff, 0x08, 0x5f, 0x30, 0xff, 0x01, 0x1f, 0x0c, 0xff, 0x09, 0x27, 0x17, 0xff, 0x1b, 0x5d, 0x32, 0xff, 0x08, 0x57, 0x1c, 0xff, 0x20, 0x52, 0x42, 0xff, 0x57, 0x44, 0x99, 0xff, 0x5a, 0x49, 0x9a, 0xff, 0x34, 0x6d, 0x56, 0xff, 0x2c, 0x5d, 0x5c, 0xff, 0x31, 0x4e, 0x71, 0xff, 0x24, 0x42, 0x59, 0xff, 0x24, 0x50, 0x4d, 0xff, 0x31, 0x65, 0x69, 0xff, 0x2c, 0x6f, 0x71, 0xff, 0x1a, 0x71, 0x5d, 0xff, 0x0b, 0x79, 0x50, 0xff, 0x0e, 0x83, 0x57, 0xff, 0x15, 0x91, 0x61, 0xff, 0x13, 0x95, 0x64, 0xff, 0x0e, 0x94, 0x62, 0xff, 0x0e, 0x95, 0x63, 0xff, 0x0f, 0x94, 0x64, 0xff, 0x10, 0x93, 0x64, 0xff, 0x11, 0x95, 0x63, 0xff, 0x11, 0x96, 0x64, 0xff, 0x12, 0x97, 0x65, 0xff, 0x13, 0x98, 0x66, 0xff, 0x13, 0x98, 0x66, 0xff, 0x12, 0x99, 0x67, 0xff, 0x11, 0x98, 0x66, 0xff, 0x0f, 0x96, 0x64, 0xff, 0x0e, 0x96, 0x63, 0xff, 0x10, 0x97, 0x64, 0xff, 0x10, 0x99, 0x66, 0xff, 0x11, 0x9b, 0x69, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0f, 0x9e, 0x6a, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x10, 0x9e, 0x6b, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0e, 0x9d, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x69, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0d, 0x9b, 0x67, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0d, 0x98, 0x65, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0d, 0x98, 0x65, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x65, 0xff, 0x10, 0x99, 0x64, 0xff, 0x10, 0x98, 0x65, 0xff, 0x0f, 0x97, 0x67, 0xff, 0x0c, 0x99, 0x67, 0xff, 0x07, 0x9b, 0x61, 0xff, 0x0d, 0xa7, 0x65, 0xff, 0x11, 0xa8, 0x62, 0xff, 0x00, 0x88, 0x41, 0xff, 0x06, 0x85, 0x41, 0xff, 0x0b, 0x82, 0x42, 0xff, 0x08, 0x81, 0x42, 0xff, 0x03, 0x81, 0x44, 0xff, 0x03, 0x7f, 0x42, 0xff, 0x08, 0x7a, 0x3f, 0xff, 0x0b, 0x61, 0x31, 0xff, 0x03, 0x40, 0x19, 0xff, 0x02, 0x36, 0x15, 0xff, 0x02, 0x31, 0x17, 0xff, 0x03, 0x31, 0x1c, 0xff, 0x02, 0x32, 0x1e, 0xff, 0x01, 0x33, 0x1a, 0xff, 0x02, 0x33, 0x19, 0xff, 0x03, 0x32, 0x17, 0xff, 0x02, 0x32, 0x17, 0xff, 0x07, 0x4d, 0x2d, 0xff, 0x17, 0x78, 0x54, 0xff, 0x18, 0x90, 0x66, 0xff, 0x12, 0x92, 0x65, 0xff, 0x0f, 0x90, 0x60, 0xff, 0x12, 0x90, 0x5f, 0xff, 0x13, 0x90, 0x60, 0xff, 0x12, 0x90, 0x61, 0xff, 0x12, 0x90, 0x61, 0xff, 0x10, 0x90, 0x61, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x11, 0x8f, 0x60, 0xff, 0x18, 0x8b, 0x5f, 0xff, 0x0f, 0x76, 0x4b, 0xff, 0x01, 0x46, 0x20, 0xff, 0x01, 0x39, 0x18, 0xff, 0x00, 0x35, 0x15, 0xff, 0x00, 0x37, 0x17, 0xff, 0x05, 0x4c, 0x29, 0xff, 0x12, 0x6e, 0x46, 0xff, 0x17, 0x87, 0x5c, 0xff, 0x0e, 0x89, 0x5d, 0xff, 0x13, 0x87, 0x5e, 0xff, 0x12, 0x6e, 0x4a, 0xff, 0x01, 0x3e, 0x1c, 0xff, 0x02, 0x3a, 0x17, 0xff, 0x02, 0x45, 0x1d, 0xff, 0x08, 0x5c, 0x2f, 0xff, 0x10, 0x76, 0x46, 0xff, 0x04, 0x64, 0x34, 0xff, 0x0a, 0x60, 0x33, 0xff, 0x06, 0x5d, 0x32, 0xff, 0x06, 0x5c, 0x32, 0xff, 0x08, 0x5d, 0x34, 0xff, 0x0a, 0x60, 0x35, 0xff, 0x0a, 0x5f, 0x35, 0xff, 0x09, 0x5f, 0x33, 0xff, 0x0a, 0x60, 0x35, 0xff, 0x0b, 0x60, 0x35, 0xff, 0x13, 0x5c, 0x35, 0xff, 0x0a, 0x44, 0x23, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x0a, 0x2f, 0x1b, 0xff, 0x0a, 0x32, 0x1c, 0xff, 0x01, 0x2b, 0x13, 0xff, 0x05, 0x35, 0x1a, 0xff, 0x0e, 0x49, 0x2a, 0xff, 0x06, 0x4c, 0x28, 0xff, 0x0b, 0x4a, 0x29, 0xff, 0x0f, 0x49, 0x2b, 0xff, 0x02, 0x3c, 0x1d, 0xff, 0x01, 0x3f, 0x1e, 0xff, 0x12, 0x65, 0x3d, 0xff, 0x0f, 0x65, 0x3a, 0xff, 0x04, 0x53, 0x29, 0xff, 0x07, 0x40, 0x21, 0xff, 0x03, 0x36, 0x1b, 0xff, 0x09, 0x39, 0x1f, 0xff, 0x03, 0x2c, 0x15, 0xff, 0x00, 0x26, 0x0f, 0xff, 0x04, 0x2b, 0x16, 0xff, 0x04, 0x2a, 0x16, 0xff, 0x01, 0x26, 0x13, 0xff, 0x07, 0x3b, 0x1e, 0xff, 0x09, 0x4b, 0x2c, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x07, 0x38, 0x1d, 0xff, 0x0a, 0x4e, 0x2e, 0xff, 0x04, 0x50, 0x2b, 0xff, 0x09, 0x50, 0x2b, 0xff, 0x0b, 0x4b, 0x28, 0xff, 0x02, 0x33, 0x1a, 0xff, 0x0d, 0x4a, 0x2c, 0xff, 0x0b, 0x57, 0x31, 0xff, 0x06, 0x59, 0x2e, 0xff, 0x09, 0x58, 0x2f, 0xff, 0x0b, 0x57, 0x31, 0xff, 0x0a, 0x59, 0x30, 0xff, 0x07, 0x5c, 0x31, 0xff, 0x09, 0x5b, 0x33, 0xff, 0x0e, 0x57, 0x32, 0xff, 0x04, 0x44, 0x23, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x01, 0x27, 0x15, 0xff, 0x08, 0x31, 0x1f, 0xff, 0x03, 0x38, 0x1d, 0xff, 0x09, 0x4d, 0x29, 0xff, 0x0a, 0x4c, 0x21, 0xff, 0x01, 0x47, 0x16, 0xff, 0x00, 0x4a, 0x16, 0xff, 0x04, 0x50, 0x1a, 0xff, 0x05, 0x55, 0x20, 0xff, 0x01, 0x5a, 0x26, 0xff, 0x04, 0x5a, 0x2a, 0xff, 0x07, 0x4b, 0x22, 0xff, 0x01, 0x3f, 0x1c, 0xff, 0x07, 0x4a, 0x2a, 0xff, 0x07, 0x4b, 0x2b, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x08, 0x4e, 0x2c, 0xff, 0x09, 0x4d, 0x2c, 0xff, 0x0c, 0x4b, 0x2d, 0xff, 0x02, 0x30, 0x15, 0xff, 0x03, 0x27, 0x10, 0xff, 0x01, 0x25, 0x11, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x0f, 0x4d, 0x30, 0xff, 0x09, 0x4e, 0x2d, 0xff, 0x0a, 0x51, 0x2b, 0xff, 0x0b, 0x4f, 0x2a, 0xff, 0x07, 0x51, 0x2e, 0xff, 0x06, 0x52, 0x31, 0xff, 0x0b, 0x54, 0x31, 0xff, 0x0c, 0x56, 0x2e, 0xff, 0x05, 0x56, 0x2d, 0xff, 0x06, 0x53, 0x2f, 0xff, 0x0d, 0x47, 0x2d, 0xff, 0x02, 0x29, 0x15, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x16, 0x5e, 0x42, 0xff, 0x0e, 0x78, 0x51, 0xff, 0x15, 0x85, 0x58, 0xff, 0x0d, 0x75, 0x45, 0xff, 0x0e, 0x6d, 0x3f, 0xff, 0x0c, 0x5d, 0x34, 0xff, 0x07, 0x5a, 0x3b, 0xff, 0x0b, 0x51, 0x3d, 0xff, 0x0c, 0x43, 0x31, 0xff, 0x0a, 0x39, 0x28, 0xff, 0x00, 0x27, 0x14, 0xff, 0x02, 0x36, 0x1c, 0xff, 0x0c, 0x54, 0x32, 0xff, 0x15, 0x65, 0x3b, 0xff, 0x15, 0x62, 0x39, 0xff, 0x07, 0x44, 0x26, 0xff, 0x01, 0x2e, 0x18, 0xff, 0x14, 0x4f, 0x3d, 0xff, 0x0f, 0x56, 0x41, 0xff, 0x15, 0x52, 0x3d, 0xff, 0x0b, 0x2f, 0x1f, 0xff, 0x60, 0x6f, 0x66, 0xff, + 0x05, 0x33, 0x1a, 0xff, 0x09, 0x45, 0x23, 0xff, 0x06, 0x47, 0x23, 0xff, 0x0a, 0x4e, 0x29, 0xff, 0x0a, 0x4f, 0x28, 0xff, 0x0b, 0x52, 0x28, 0xff, 0x07, 0x41, 0x1f, 0xff, 0x00, 0x25, 0x10, 0xff, 0x00, 0x26, 0x10, 0xff, 0x03, 0x31, 0x16, 0xff, 0x0c, 0x4c, 0x29, 0xff, 0x07, 0x57, 0x2b, 0xff, 0x04, 0x58, 0x28, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x08, 0x58, 0x2c, 0xff, 0x0e, 0x55, 0x2e, 0xff, 0x02, 0x33, 0x17, 0xff, 0x01, 0x23, 0x13, 0xff, 0x01, 0x28, 0x14, 0xff, 0x0c, 0x45, 0x26, 0xff, 0x09, 0x4e, 0x27, 0xff, 0x06, 0x51, 0x27, 0xff, 0x06, 0x4f, 0x27, 0xff, 0x08, 0x50, 0x27, 0xff, 0x0a, 0x4f, 0x27, 0xff, 0x03, 0x2f, 0x17, 0xff, 0x01, 0x1e, 0x11, 0xff, 0x01, 0x25, 0x11, 0xff, 0x05, 0x3f, 0x1d, 0xff, 0x0a, 0x53, 0x2b, 0xff, 0x0c, 0x54, 0x2d, 0xff, 0x07, 0x4a, 0x24, 0xff, 0x02, 0x49, 0x1f, 0xff, 0x0e, 0x60, 0x30, 0xff, 0x11, 0x63, 0x33, 0xff, 0x0d, 0x56, 0x2d, 0xff, 0x02, 0x37, 0x17, 0xff, 0x03, 0x2d, 0x16, 0xff, 0x03, 0x2a, 0x16, 0xff, 0x04, 0x36, 0x20, 0xff, 0x0f, 0x4d, 0x35, 0xff, 0x10, 0x4f, 0x39, 0xff, 0x11, 0x4e, 0x37, 0xff, 0x08, 0x45, 0x2d, 0xff, 0x01, 0x3c, 0x24, 0xff, 0x04, 0x36, 0x21, 0xff, 0x05, 0x33, 0x1a, 0xff, 0x10, 0x62, 0x32, 0xff, 0x1a, 0x97, 0x53, 0xff, 0x13, 0x94, 0x4f, 0xff, 0x10, 0x81, 0x41, 0xff, 0x08, 0x72, 0x2e, 0xff, 0x0d, 0x76, 0x30, 0xff, 0x0a, 0x46, 0x27, 0xff, 0x17, 0x2c, 0x30, 0xff, 0x14, 0x23, 0x29, 0xff, 0x20, 0x30, 0x2b, 0xff, 0x54, 0x4e, 0x89, 0xff, 0x6e, 0x58, 0xaa, 0xff, 0x37, 0x60, 0x7d, 0xff, 0x0f, 0x57, 0x29, 0xff, 0x15, 0x6c, 0x3b, 0xff, 0x2b, 0xa4, 0x78, 0xff, 0x04, 0x36, 0x22, 0xff, 0x1d, 0x29, 0x37, 0xff, 0x23, 0x30, 0x39, 0xff, 0x0a, 0x39, 0x1b, 0xff, 0x17, 0x60, 0x2a, 0xff, 0x35, 0x5c, 0x53, 0xff, 0x63, 0x50, 0xab, 0xff, 0x47, 0x42, 0x89, 0xff, 0x26, 0x69, 0x4d, 0xff, 0x37, 0x6b, 0x70, 0xff, 0x46, 0x61, 0x94, 0xff, 0x2b, 0x50, 0x64, 0xff, 0x14, 0x54, 0x37, 0xff, 0x17, 0x61, 0x49, 0xff, 0x17, 0x6d, 0x57, 0xff, 0x11, 0x72, 0x53, 0xff, 0x0d, 0x7e, 0x53, 0xff, 0x10, 0x87, 0x58, 0xff, 0x15, 0x93, 0x62, 0xff, 0x12, 0x95, 0x63, 0xff, 0x0d, 0x94, 0x61, 0xff, 0x0e, 0x96, 0x63, 0xff, 0x0f, 0x95, 0x64, 0xff, 0x11, 0x95, 0x66, 0xff, 0x13, 0x98, 0x67, 0xff, 0x12, 0x99, 0x67, 0xff, 0x13, 0x99, 0x67, 0xff, 0x12, 0x99, 0x66, 0xff, 0x12, 0x99, 0x67, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x12, 0x9a, 0x67, 0xff, 0x11, 0x99, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0e, 0x9c, 0x69, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0f, 0x9d, 0x6a, 0xff, 0x0f, 0x9c, 0x6a, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0f, 0x9c, 0x6b, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0e, 0x9b, 0x69, 0xff, 0x0d, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x10, 0x9a, 0x67, 0xff, 0x10, 0x99, 0x66, 0xff, 0x10, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x66, 0xff, 0x0f, 0x99, 0x65, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0b, 0x99, 0x64, 0xff, 0x07, 0x9d, 0x5f, 0xff, 0x12, 0xae, 0x69, 0xff, 0x08, 0x98, 0x52, 0xff, 0x01, 0x84, 0x40, 0xff, 0x09, 0x84, 0x43, 0xff, 0x0e, 0x7f, 0x42, 0xff, 0x0c, 0x7e, 0x44, 0xff, 0x02, 0x7e, 0x43, 0xff, 0x02, 0x7b, 0x43, 0xff, 0x08, 0x73, 0x3f, 0xff, 0x02, 0x49, 0x1f, 0xff, 0x00, 0x36, 0x14, 0xff, 0x05, 0x33, 0x17, 0xff, 0x06, 0x30, 0x19, 0xff, 0x05, 0x32, 0x1e, 0xff, 0x01, 0x33, 0x1e, 0xff, 0x00, 0x33, 0x19, 0xff, 0x02, 0x34, 0x18, 0xff, 0x02, 0x32, 0x15, 0xff, 0x06, 0x44, 0x24, 0xff, 0x1a, 0x7a, 0x54, 0xff, 0x17, 0x90, 0x65, 0xff, 0x0d, 0x96, 0x67, 0xff, 0x0c, 0x94, 0x64, 0xff, 0x11, 0x94, 0x64, 0xff, 0x13, 0x91, 0x60, 0xff, 0x12, 0x92, 0x61, 0xff, 0x10, 0x91, 0x62, 0xff, 0x10, 0x90, 0x61, 0xff, 0x10, 0x90, 0x61, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x10, 0x90, 0x61, 0xff, 0x15, 0x8d, 0x60, 0xff, 0x1a, 0x8a, 0x5d, 0xff, 0x11, 0x6a, 0x42, 0xff, 0x0c, 0x53, 0x31, 0xff, 0x06, 0x49, 0x26, 0xff, 0x09, 0x57, 0x33, 0xff, 0x17, 0x77, 0x50, 0xff, 0x19, 0x88, 0x5e, 0xff, 0x11, 0x8b, 0x5f, 0xff, 0x0c, 0x8b, 0x5e, 0xff, 0x10, 0x8a, 0x5d, 0xff, 0x1b, 0x84, 0x5c, 0xff, 0x0d, 0x60, 0x39, 0xff, 0x01, 0x3f, 0x1b, 0xff, 0x02, 0x3d, 0x19, 0xff, 0x02, 0x49, 0x22, 0xff, 0x0f, 0x6e, 0x42, 0xff, 0x0b, 0x68, 0x3a, 0xff, 0x0d, 0x5f, 0x34, 0xff, 0x06, 0x5d, 0x34, 0xff, 0x06, 0x5b, 0x32, 0xff, 0x07, 0x5a, 0x32, 0xff, 0x0c, 0x5f, 0x35, 0xff, 0x0b, 0x5e, 0x34, 0xff, 0x0b, 0x5e, 0x33, 0xff, 0x0b, 0x60, 0x34, 0xff, 0x0c, 0x5f, 0x34, 0xff, 0x12, 0x5d, 0x33, 0xff, 0x0b, 0x50, 0x2a, 0xff, 0x01, 0x2f, 0x10, 0xff, 0x04, 0x2a, 0x13, 0xff, 0x06, 0x31, 0x1b, 0xff, 0x02, 0x2a, 0x14, 0xff, 0x06, 0x2f, 0x17, 0xff, 0x0f, 0x48, 0x2b, 0xff, 0x04, 0x4c, 0x29, 0xff, 0x08, 0x4a, 0x2a, 0xff, 0x0e, 0x4a, 0x2b, 0xff, 0x09, 0x43, 0x26, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x0c, 0x56, 0x31, 0xff, 0x12, 0x64, 0x3b, 0xff, 0x02, 0x52, 0x28, 0xff, 0x09, 0x46, 0x26, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x05, 0x37, 0x1b, 0xff, 0x09, 0x35, 0x1c, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x02, 0x28, 0x13, 0xff, 0x06, 0x2b, 0x19, 0xff, 0x01, 0x27, 0x14, 0xff, 0x06, 0x38, 0x1d, 0xff, 0x0b, 0x4c, 0x2d, 0xff, 0x04, 0x3e, 0x20, 0xff, 0x03, 0x35, 0x19, 0xff, 0x0c, 0x4d, 0x2e, 0xff, 0x05, 0x4f, 0x2c, 0xff, 0x08, 0x4e, 0x2a, 0xff, 0x0c, 0x4c, 0x28, 0xff, 0x03, 0x33, 0x1a, 0xff, 0x0a, 0x44, 0x27, 0xff, 0x0b, 0x54, 0x2f, 0xff, 0x08, 0x59, 0x2f, 0xff, 0x08, 0x58, 0x30, 0xff, 0x0a, 0x57, 0x31, 0xff, 0x09, 0x59, 0x31, 0xff, 0x05, 0x5b, 0x31, 0xff, 0x06, 0x5b, 0x31, 0xff, 0x0c, 0x58, 0x31, 0xff, 0x06, 0x48, 0x26, 0xff, 0x01, 0x31, 0x18, 0xff, 0x01, 0x29, 0x16, 0xff, 0x08, 0x34, 0x1e, 0xff, 0x03, 0x3a, 0x1b, 0xff, 0x08, 0x4f, 0x25, 0xff, 0x06, 0x49, 0x1c, 0xff, 0x01, 0x48, 0x18, 0xff, 0x00, 0x4c, 0x17, 0xff, 0x03, 0x53, 0x1b, 0xff, 0x05, 0x57, 0x21, 0xff, 0x04, 0x5a, 0x28, 0xff, 0x07, 0x57, 0x2b, 0xff, 0x02, 0x3c, 0x18, 0xff, 0x03, 0x3f, 0x1e, 0xff, 0x08, 0x4b, 0x2b, 0xff, 0x06, 0x4a, 0x2a, 0xff, 0x06, 0x4e, 0x2d, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4c, 0x2c, 0xff, 0x0d, 0x4a, 0x2d, 0xff, 0x02, 0x2e, 0x15, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x29, 0x13, 0xff, 0x0b, 0x3e, 0x25, 0xff, 0x0d, 0x4e, 0x30, 0xff, 0x08, 0x4f, 0x2d, 0xff, 0x0a, 0x51, 0x2c, 0xff, 0x0a, 0x50, 0x2b, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x08, 0x52, 0x30, 0xff, 0x09, 0x52, 0x2e, 0xff, 0x07, 0x52, 0x2b, 0xff, 0x04, 0x53, 0x2c, 0xff, 0x0c, 0x53, 0x32, 0xff, 0x06, 0x35, 0x1e, 0xff, 0x03, 0x26, 0x13, 0xff, 0x06, 0x3b, 0x23, 0xff, 0x13, 0x6c, 0x4c, 0xff, 0x13, 0x86, 0x5d, 0xff, 0x12, 0x84, 0x57, 0xff, 0x0c, 0x6c, 0x3e, 0xff, 0x0d, 0x60, 0x36, 0xff, 0x09, 0x58, 0x2f, 0xff, 0x0f, 0x64, 0x3f, 0xff, 0x12, 0x5e, 0x3f, 0xff, 0x13, 0x50, 0x35, 0xff, 0x03, 0x38, 0x21, 0xff, 0x00, 0x28, 0x11, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x12, 0x5d, 0x39, 0xff, 0x15, 0x67, 0x3c, 0xff, 0x13, 0x5e, 0x37, 0xff, 0x09, 0x43, 0x27, 0xff, 0x03, 0x34, 0x1d, 0xff, 0x18, 0x56, 0x40, 0xff, 0x0c, 0x54, 0x3b, 0xff, 0x15, 0x54, 0x3c, 0xff, 0x0a, 0x2f, 0x1e, 0xff, 0x61, 0x6d, 0x68, 0xff, + 0x05, 0x33, 0x1a, 0xff, 0x09, 0x45, 0x23, 0xff, 0x05, 0x47, 0x23, 0xff, 0x09, 0x4c, 0x27, 0xff, 0x0a, 0x4d, 0x28, 0xff, 0x09, 0x50, 0x27, 0xff, 0x0a, 0x45, 0x23, 0xff, 0x00, 0x25, 0x11, 0xff, 0x00, 0x26, 0x10, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x0a, 0x47, 0x26, 0xff, 0x08, 0x55, 0x2a, 0xff, 0x06, 0x59, 0x2a, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x0e, 0x56, 0x2d, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x01, 0x25, 0x14, 0xff, 0x01, 0x28, 0x15, 0xff, 0x0d, 0x45, 0x27, 0xff, 0x09, 0x4d, 0x27, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x07, 0x4f, 0x28, 0xff, 0x09, 0x4f, 0x28, 0xff, 0x0c, 0x4e, 0x28, 0xff, 0x03, 0x2f, 0x16, 0xff, 0x00, 0x1e, 0x10, 0xff, 0x00, 0x26, 0x11, 0xff, 0x0a, 0x47, 0x25, 0xff, 0x0b, 0x54, 0x2d, 0xff, 0x0d, 0x51, 0x2e, 0xff, 0x03, 0x43, 0x1f, 0xff, 0x06, 0x52, 0x25, 0xff, 0x0e, 0x63, 0x30, 0xff, 0x0f, 0x60, 0x32, 0xff, 0x04, 0x3e, 0x1f, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x03, 0x2b, 0x17, 0xff, 0x01, 0x2b, 0x15, 0xff, 0x0b, 0x43, 0x2c, 0xff, 0x12, 0x51, 0x39, 0xff, 0x0e, 0x4c, 0x37, 0xff, 0x08, 0x42, 0x2d, 0xff, 0x02, 0x39, 0x22, 0xff, 0x01, 0x37, 0x1f, 0xff, 0x04, 0x34, 0x1d, 0xff, 0x02, 0x36, 0x19, 0xff, 0x20, 0x8f, 0x59, 0xff, 0x08, 0x95, 0x4d, 0xff, 0x0d, 0x96, 0x4b, 0xff, 0x05, 0x78, 0x34, 0xff, 0x11, 0x80, 0x38, 0xff, 0x0c, 0x7e, 0x31, 0xff, 0x0a, 0x5b, 0x23, 0xff, 0x11, 0x3c, 0x20, 0xff, 0x0f, 0x2a, 0x1e, 0xff, 0x03, 0x25, 0x09, 0xff, 0x1b, 0x53, 0x4a, 0xff, 0x28, 0x57, 0x55, 0xff, 0x23, 0x6c, 0x5e, 0xff, 0x08, 0x4c, 0x1c, 0xff, 0x1b, 0x74, 0x48, 0xff, 0x0e, 0x6b, 0x4a, 0xff, 0x1b, 0x35, 0x4b, 0xff, 0x53, 0x48, 0x89, 0xff, 0x47, 0x43, 0x74, 0xff, 0x0f, 0x35, 0x2b, 0xff, 0x21, 0x60, 0x31, 0xff, 0x34, 0x55, 0x4e, 0xff, 0x5e, 0x5a, 0xa1, 0xff, 0x38, 0x4b, 0x74, 0xff, 0x10, 0x5f, 0x3a, 0xff, 0x22, 0x60, 0x5b, 0xff, 0x4b, 0x6f, 0x97, 0xff, 0x2e, 0x61, 0x69, 0xff, 0x15, 0x6a, 0x3e, 0xff, 0x0a, 0x6a, 0x41, 0xff, 0x0b, 0x74, 0x4e, 0xff, 0x10, 0x7b, 0x52, 0xff, 0x11, 0x87, 0x5a, 0xff, 0x12, 0x8c, 0x5c, 0xff, 0x12, 0x92, 0x61, 0xff, 0x0f, 0x94, 0x61, 0xff, 0x10, 0x98, 0x64, 0xff, 0x10, 0x99, 0x66, 0xff, 0x11, 0x99, 0x67, 0xff, 0x12, 0x9a, 0x69, 0xff, 0x12, 0x9a, 0x67, 0xff, 0x12, 0x9a, 0x67, 0xff, 0x12, 0x9b, 0x68, 0xff, 0x12, 0x9b, 0x68, 0xff, 0x10, 0x9a, 0x67, 0xff, 0x10, 0x9a, 0x67, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0c, 0x9d, 0x68, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0d, 0x9f, 0x6b, 0xff, 0x0f, 0x9e, 0x6b, 0xff, 0x0f, 0x9c, 0x6b, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0d, 0x9a, 0x69, 0xff, 0x0f, 0x9c, 0x6b, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0f, 0x9c, 0x6b, 0xff, 0x0f, 0x9c, 0x6a, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x10, 0x9a, 0x67, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x69, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0f, 0x9c, 0x67, 0xff, 0x10, 0x9c, 0x67, 0xff, 0x0e, 0x9b, 0x66, 0xff, 0x09, 0x99, 0x62, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x14, 0xaf, 0x68, 0xff, 0x01, 0x8a, 0x44, 0xff, 0x06, 0x83, 0x43, 0xff, 0x08, 0x80, 0x44, 0xff, 0x08, 0x7a, 0x41, 0xff, 0x08, 0x7d, 0x46, 0xff, 0x03, 0x80, 0x4a, 0xff, 0x10, 0x86, 0x55, 0xff, 0x0f, 0x6d, 0x41, 0xff, 0x00, 0x3a, 0x18, 0xff, 0x02, 0x33, 0x17, 0xff, 0x04, 0x31, 0x19, 0xff, 0x06, 0x31, 0x1b, 0xff, 0x04, 0x2f, 0x1b, 0xff, 0x03, 0x31, 0x1b, 0xff, 0x01, 0x33, 0x19, 0xff, 0x00, 0x32, 0x15, 0xff, 0x04, 0x45, 0x23, 0xff, 0x1d, 0x79, 0x51, 0xff, 0x1d, 0x93, 0x66, 0xff, 0x0e, 0x96, 0x65, 0xff, 0x06, 0x95, 0x63, 0xff, 0x0a, 0x94, 0x63, 0xff, 0x0f, 0x94, 0x62, 0xff, 0x0f, 0x93, 0x61, 0xff, 0x0f, 0x95, 0x63, 0xff, 0x0d, 0x93, 0x63, 0xff, 0x0f, 0x92, 0x63, 0xff, 0x11, 0x91, 0x62, 0xff, 0x11, 0x91, 0x62, 0xff, 0x0c, 0x8e, 0x5f, 0xff, 0x13, 0x90, 0x62, 0xff, 0x14, 0x8d, 0x5f, 0xff, 0x1f, 0x8c, 0x61, 0xff, 0x23, 0x87, 0x60, 0xff, 0x1c, 0x83, 0x5a, 0xff, 0x1c, 0x88, 0x5e, 0xff, 0x18, 0x8d, 0x62, 0xff, 0x11, 0x8c, 0x5f, 0xff, 0x0f, 0x8b, 0x5e, 0xff, 0x12, 0x8b, 0x5f, 0xff, 0x15, 0x8a, 0x5d, 0xff, 0x14, 0x88, 0x59, 0xff, 0x19, 0x84, 0x5a, 0xff, 0x0b, 0x5f, 0x39, 0xff, 0x00, 0x37, 0x16, 0xff, 0x01, 0x3f, 0x1e, 0xff, 0x07, 0x56, 0x2f, 0xff, 0x14, 0x6a, 0x3f, 0xff, 0x0a, 0x5e, 0x34, 0xff, 0x06, 0x5d, 0x36, 0xff, 0x03, 0x58, 0x31, 0xff, 0x02, 0x55, 0x2e, 0xff, 0x09, 0x5b, 0x32, 0xff, 0x0b, 0x5e, 0x34, 0xff, 0x08, 0x5d, 0x32, 0xff, 0x07, 0x5e, 0x32, 0xff, 0x06, 0x5f, 0x32, 0xff, 0x06, 0x62, 0x33, 0xff, 0x08, 0x5a, 0x30, 0xff, 0x06, 0x3e, 0x1d, 0xff, 0x01, 0x26, 0x0d, 0xff, 0x04, 0x2d, 0x18, 0xff, 0x04, 0x2b, 0x16, 0xff, 0x03, 0x2b, 0x15, 0xff, 0x0d, 0x48, 0x2d, 0xff, 0x06, 0x4b, 0x29, 0xff, 0x07, 0x4b, 0x2a, 0xff, 0x0a, 0x49, 0x2a, 0xff, 0x10, 0x49, 0x2c, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x05, 0x44, 0x22, 0xff, 0x11, 0x5d, 0x38, 0xff, 0x07, 0x57, 0x31, 0xff, 0x0b, 0x4b, 0x29, 0xff, 0x05, 0x3e, 0x21, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x0a, 0x38, 0x1f, 0xff, 0x05, 0x2f, 0x18, 0xff, 0x01, 0x26, 0x12, 0xff, 0x05, 0x29, 0x18, 0xff, 0x02, 0x28, 0x15, 0xff, 0x06, 0x36, 0x1b, 0xff, 0x0d, 0x4c, 0x2d, 0xff, 0x07, 0x43, 0x25, 0xff, 0x01, 0x32, 0x16, 0xff, 0x0b, 0x49, 0x2a, 0xff, 0x08, 0x4f, 0x2e, 0xff, 0x09, 0x4e, 0x2b, 0xff, 0x0d, 0x4b, 0x28, 0xff, 0x03, 0x32, 0x19, 0xff, 0x07, 0x3f, 0x22, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x08, 0x56, 0x2f, 0xff, 0x09, 0x56, 0x30, 0xff, 0x0b, 0x56, 0x32, 0xff, 0x0a, 0x58, 0x32, 0xff, 0x06, 0x5a, 0x30, 0xff, 0x05, 0x5b, 0x2f, 0xff, 0x0a, 0x57, 0x2f, 0xff, 0x0a, 0x4d, 0x2b, 0xff, 0x01, 0x31, 0x19, 0xff, 0x01, 0x2b, 0x19, 0xff, 0x07, 0x35, 0x1b, 0xff, 0x05, 0x3f, 0x1c, 0xff, 0x04, 0x4b, 0x1c, 0xff, 0x02, 0x46, 0x16, 0xff, 0x01, 0x49, 0x16, 0xff, 0x00, 0x4f, 0x19, 0xff, 0x02, 0x56, 0x1f, 0xff, 0x04, 0x58, 0x23, 0xff, 0x07, 0x58, 0x2a, 0xff, 0x08, 0x4e, 0x27, 0xff, 0x00, 0x2f, 0x10, 0xff, 0x07, 0x42, 0x22, 0xff, 0x09, 0x4c, 0x2c, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x07, 0x4d, 0x2c, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4c, 0x2c, 0xff, 0x0d, 0x45, 0x2a, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x05, 0x35, 0x1d, 0xff, 0x11, 0x4b, 0x30, 0xff, 0x07, 0x4d, 0x2e, 0xff, 0x07, 0x50, 0x2c, 0xff, 0x09, 0x50, 0x2b, 0xff, 0x0b, 0x51, 0x2c, 0xff, 0x0a, 0x53, 0x2f, 0xff, 0x0b, 0x53, 0x2f, 0xff, 0x0a, 0x52, 0x2e, 0xff, 0x06, 0x51, 0x2c, 0xff, 0x07, 0x52, 0x2f, 0xff, 0x0c, 0x4c, 0x2e, 0xff, 0x03, 0x28, 0x14, 0xff, 0x04, 0x25, 0x14, 0xff, 0x09, 0x51, 0x36, 0xff, 0x10, 0x7d, 0x58, 0xff, 0x12, 0x8c, 0x60, 0xff, 0x0d, 0x7a, 0x4e, 0xff, 0x08, 0x5d, 0x34, 0xff, 0x05, 0x48, 0x21, 0xff, 0x09, 0x57, 0x2f, 0xff, 0x11, 0x6b, 0x3e, 0xff, 0x12, 0x65, 0x3a, 0xff, 0x18, 0x5f, 0x3a, 0xff, 0x03, 0x3a, 0x1d, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x0e, 0x4a, 0x2c, 0xff, 0x1b, 0x63, 0x40, 0xff, 0x15, 0x64, 0x3b, 0xff, 0x14, 0x57, 0x37, 0xff, 0x0d, 0x43, 0x2d, 0xff, 0x0b, 0x41, 0x2b, 0xff, 0x1a, 0x5c, 0x42, 0xff, 0x09, 0x55, 0x37, 0xff, 0x14, 0x57, 0x3c, 0xff, 0x07, 0x2f, 0x1e, 0xff, 0x62, 0x6e, 0x69, 0xff, + 0x05, 0x34, 0x1a, 0xff, 0x09, 0x45, 0x24, 0xff, 0x06, 0x46, 0x22, 0xff, 0x08, 0x4b, 0x26, 0xff, 0x09, 0x4c, 0x27, 0xff, 0x0a, 0x4f, 0x27, 0xff, 0x0c, 0x47, 0x26, 0xff, 0x01, 0x27, 0x11, 0xff, 0x00, 0x26, 0x11, 0xff, 0x01, 0x2b, 0x14, 0xff, 0x0a, 0x43, 0x24, 0xff, 0x09, 0x52, 0x2a, 0xff, 0x07, 0x58, 0x2b, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x07, 0x56, 0x29, 0xff, 0x0b, 0x55, 0x2c, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x01, 0x25, 0x14, 0xff, 0x01, 0x27, 0x14, 0xff, 0x0c, 0x45, 0x27, 0xff, 0x08, 0x4d, 0x27, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x08, 0x4e, 0x29, 0xff, 0x08, 0x4f, 0x28, 0xff, 0x0d, 0x4e, 0x27, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x00, 0x1e, 0x0f, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x0d, 0x4d, 0x29, 0xff, 0x0c, 0x54, 0x2d, 0xff, 0x0a, 0x4b, 0x29, 0xff, 0x04, 0x43, 0x1f, 0xff, 0x0b, 0x5a, 0x2b, 0xff, 0x0b, 0x62, 0x2f, 0xff, 0x09, 0x54, 0x2b, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x04, 0x2a, 0x19, 0xff, 0x02, 0x28, 0x16, 0xff, 0x02, 0x2f, 0x18, 0xff, 0x10, 0x4b, 0x33, 0xff, 0x12, 0x4e, 0x36, 0xff, 0x07, 0x41, 0x2b, 0xff, 0x04, 0x3a, 0x24, 0xff, 0x06, 0x37, 0x1f, 0xff, 0x04, 0x34, 0x1c, 0xff, 0x03, 0x33, 0x19, 0xff, 0x08, 0x48, 0x29, 0xff, 0x16, 0x98, 0x62, 0xff, 0x10, 0xa3, 0x5b, 0xff, 0x05, 0x8b, 0x3b, 0xff, 0x08, 0x83, 0x38, 0xff, 0x10, 0x82, 0x3b, 0xff, 0x12, 0x7e, 0x38, 0xff, 0x17, 0x68, 0x32, 0xff, 0x0f, 0x43, 0x21, 0xff, 0x09, 0x2f, 0x1a, 0xff, 0x02, 0x34, 0x11, 0xff, 0x1f, 0x79, 0x45, 0xff, 0x27, 0x8a, 0x4d, 0xff, 0x15, 0x71, 0x3e, 0xff, 0x04, 0x4f, 0x1b, 0xff, 0x0a, 0x64, 0x39, 0xff, 0x0e, 0x5e, 0x43, 0xff, 0x49, 0x51, 0x88, 0xff, 0x5e, 0x45, 0xab, 0xff, 0x58, 0x4f, 0x9f, 0xff, 0x18, 0x3d, 0x44, 0xff, 0x14, 0x4c, 0x2d, 0xff, 0x1d, 0x40, 0x3b, 0xff, 0x32, 0x4a, 0x6a, 0xff, 0x20, 0x52, 0x53, 0xff, 0x07, 0x62, 0x37, 0xff, 0x0a, 0x56, 0x3c, 0xff, 0x30, 0x68, 0x6a, 0xff, 0x1f, 0x61, 0x56, 0xff, 0x15, 0x76, 0x4d, 0xff, 0x0a, 0x78, 0x4f, 0xff, 0x0d, 0x7e, 0x57, 0xff, 0x12, 0x85, 0x55, 0xff, 0x10, 0x8b, 0x5c, 0xff, 0x11, 0x8f, 0x5e, 0xff, 0x0f, 0x93, 0x61, 0xff, 0x0f, 0x96, 0x62, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x12, 0x9b, 0x68, 0xff, 0x11, 0x9a, 0x68, 0xff, 0x12, 0x9b, 0x69, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x11, 0x9b, 0x67, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x10, 0x9c, 0x68, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x0d, 0x9f, 0x6b, 0xff, 0x0e, 0xa0, 0x6b, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0f, 0x9e, 0x6d, 0xff, 0x10, 0x9d, 0x6c, 0xff, 0x0f, 0x9b, 0x6a, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0e, 0x9c, 0x6b, 0xff, 0x0e, 0x9c, 0x6b, 0xff, 0x0f, 0x9c, 0x6b, 0xff, 0x0f, 0x9c, 0x6b, 0xff, 0x10, 0x9e, 0x6b, 0xff, 0x0e, 0x9c, 0x69, 0xff, 0x0d, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0d, 0x9b, 0x67, 0xff, 0x0d, 0x9b, 0x67, 0xff, 0x0d, 0x99, 0x67, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0e, 0x99, 0x67, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x11, 0x9c, 0x69, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x10, 0x9c, 0x69, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x6a, 0xff, 0x0f, 0x9b, 0x69, 0xff, 0x10, 0x9c, 0x67, 0xff, 0x11, 0x9c, 0x67, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x0c, 0x9b, 0x62, 0xff, 0x13, 0xa7, 0x67, 0xff, 0x0f, 0xa5, 0x5d, 0xff, 0x01, 0x86, 0x41, 0xff, 0x04, 0x80, 0x43, 0xff, 0x04, 0x7f, 0x44, 0xff, 0x09, 0x85, 0x4d, 0xff, 0x10, 0x91, 0x5d, 0xff, 0x14, 0x96, 0x63, 0xff, 0x20, 0x8a, 0x5f, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x01, 0x34, 0x19, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x01, 0x32, 0x1b, 0xff, 0x02, 0x31, 0x1b, 0xff, 0x09, 0x31, 0x1c, 0xff, 0x07, 0x31, 0x1a, 0xff, 0x01, 0x33, 0x18, 0xff, 0x05, 0x47, 0x26, 0xff, 0x19, 0x7c, 0x54, 0xff, 0x19, 0x94, 0x64, 0xff, 0x11, 0x94, 0x62, 0xff, 0x0d, 0x94, 0x61, 0xff, 0x0c, 0x94, 0x62, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0c, 0x93, 0x61, 0xff, 0x0b, 0x95, 0x62, 0xff, 0x08, 0x94, 0x62, 0xff, 0x0b, 0x95, 0x64, 0xff, 0x0e, 0x94, 0x64, 0xff, 0x11, 0x93, 0x63, 0xff, 0x11, 0x93, 0x64, 0xff, 0x0f, 0x91, 0x61, 0xff, 0x0f, 0x91, 0x61, 0xff, 0x10, 0x8f, 0x60, 0xff, 0x11, 0x8d, 0x5f, 0xff, 0x13, 0x8e, 0x61, 0xff, 0x13, 0x8d, 0x61, 0xff, 0x14, 0x8e, 0x62, 0xff, 0x11, 0x8d, 0x60, 0xff, 0x0f, 0x8d, 0x5f, 0xff, 0x12, 0x8e, 0x60, 0xff, 0x16, 0x8c, 0x5f, 0xff, 0x16, 0x8a, 0x5c, 0xff, 0x13, 0x8b, 0x5a, 0xff, 0x11, 0x89, 0x5a, 0xff, 0x15, 0x82, 0x59, 0xff, 0x07, 0x55, 0x34, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x03, 0x46, 0x22, 0xff, 0x0d, 0x5b, 0x32, 0xff, 0x08, 0x60, 0x36, 0xff, 0x08, 0x5d, 0x37, 0xff, 0x05, 0x57, 0x31, 0xff, 0x02, 0x53, 0x2c, 0xff, 0x07, 0x58, 0x31, 0xff, 0x0b, 0x5d, 0x34, 0xff, 0x07, 0x5c, 0x32, 0xff, 0x05, 0x5e, 0x32, 0xff, 0x01, 0x5f, 0x31, 0xff, 0x00, 0x63, 0x32, 0xff, 0x05, 0x5e, 0x34, 0xff, 0x0c, 0x4e, 0x2c, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x05, 0x28, 0x13, 0xff, 0x07, 0x2b, 0x17, 0xff, 0x01, 0x29, 0x13, 0xff, 0x09, 0x46, 0x2b, 0xff, 0x09, 0x4d, 0x29, 0xff, 0x07, 0x4d, 0x29, 0xff, 0x06, 0x4c, 0x29, 0xff, 0x0b, 0x4a, 0x2b, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x02, 0x3c, 0x1c, 0xff, 0x09, 0x4d, 0x2a, 0xff, 0x0d, 0x57, 0x33, 0xff, 0x0b, 0x4d, 0x2a, 0xff, 0x06, 0x42, 0x23, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x03, 0x31, 0x17, 0xff, 0x0b, 0x36, 0x20, 0xff, 0x02, 0x27, 0x13, 0xff, 0x02, 0x25, 0x14, 0xff, 0x04, 0x27, 0x16, 0xff, 0x04, 0x31, 0x17, 0xff, 0x0e, 0x49, 0x2c, 0xff, 0x0b, 0x46, 0x29, 0xff, 0x01, 0x32, 0x15, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0a, 0x4e, 0x2d, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x0d, 0x4b, 0x28, 0xff, 0x02, 0x30, 0x17, 0xff, 0x04, 0x3b, 0x1f, 0xff, 0x08, 0x4b, 0x29, 0xff, 0x08, 0x52, 0x2c, 0xff, 0x0c, 0x54, 0x30, 0xff, 0x0d, 0x55, 0x31, 0xff, 0x0d, 0x57, 0x32, 0xff, 0x0b, 0x58, 0x30, 0xff, 0x09, 0x5a, 0x2f, 0xff, 0x0a, 0x57, 0x30, 0xff, 0x0d, 0x51, 0x2f, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x03, 0x2e, 0x1b, 0xff, 0x05, 0x32, 0x19, 0xff, 0x0c, 0x44, 0x20, 0xff, 0x03, 0x48, 0x17, 0xff, 0x03, 0x49, 0x17, 0xff, 0x01, 0x4c, 0x17, 0xff, 0x01, 0x52, 0x1c, 0xff, 0x03, 0x58, 0x23, 0xff, 0x04, 0x59, 0x27, 0xff, 0x09, 0x53, 0x2a, 0xff, 0x07, 0x43, 0x20, 0xff, 0x05, 0x2d, 0x11, 0xff, 0x0c, 0x46, 0x28, 0xff, 0x09, 0x4c, 0x2c, 0xff, 0x08, 0x4b, 0x2b, 0xff, 0x07, 0x4c, 0x2b, 0xff, 0x07, 0x4e, 0x2d, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4c, 0x2b, 0xff, 0x0d, 0x43, 0x27, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x0e, 0x47, 0x2b, 0xff, 0x0d, 0x4f, 0x31, 0xff, 0x05, 0x50, 0x2e, 0xff, 0x05, 0x50, 0x2c, 0xff, 0x0b, 0x52, 0x2d, 0xff, 0x0a, 0x52, 0x2c, 0xff, 0x0b, 0x52, 0x2c, 0xff, 0x0c, 0x52, 0x2c, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x07, 0x51, 0x2d, 0xff, 0x0b, 0x51, 0x31, 0xff, 0x06, 0x3c, 0x21, 0xff, 0x04, 0x25, 0x11, 0xff, 0x03, 0x30, 0x1b, 0xff, 0x10, 0x6d, 0x4d, 0xff, 0x14, 0x8e, 0x64, 0xff, 0x0f, 0x86, 0x59, 0xff, 0x0e, 0x71, 0x47, 0xff, 0x07, 0x4a, 0x26, 0xff, 0x01, 0x32, 0x12, 0xff, 0x0e, 0x5e, 0x38, 0xff, 0x09, 0x69, 0x39, 0xff, 0x0e, 0x69, 0x37, 0xff, 0x14, 0x66, 0x3b, 0xff, 0x07, 0x44, 0x22, 0xff, 0x02, 0x36, 0x19, 0xff, 0x18, 0x55, 0x39, 0xff, 0x1a, 0x5a, 0x3b, 0xff, 0x15, 0x5a, 0x38, 0xff, 0x22, 0x5c, 0x46, 0xff, 0x1a, 0x4a, 0x40, 0xff, 0x11, 0x48, 0x39, 0xff, 0x12, 0x59, 0x3f, 0xff, 0x09, 0x56, 0x37, 0xff, 0x14, 0x57, 0x3c, 0xff, 0x06, 0x2f, 0x1d, 0xff, 0x63, 0x6f, 0x69, 0xff, + 0x06, 0x33, 0x1b, 0xff, 0x09, 0x44, 0x24, 0xff, 0x06, 0x45, 0x22, 0xff, 0x09, 0x48, 0x25, 0xff, 0x0a, 0x4b, 0x26, 0xff, 0x09, 0x4d, 0x26, 0xff, 0x0c, 0x49, 0x27, 0xff, 0x01, 0x28, 0x10, 0xff, 0x01, 0x27, 0x12, 0xff, 0x01, 0x28, 0x13, 0xff, 0x0a, 0x3e, 0x23, 0xff, 0x0b, 0x51, 0x2a, 0xff, 0x07, 0x56, 0x2a, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x07, 0x57, 0x2a, 0xff, 0x09, 0x53, 0x2a, 0xff, 0x05, 0x3a, 0x1d, 0xff, 0x00, 0x23, 0x12, 0xff, 0x01, 0x28, 0x15, 0xff, 0x0a, 0x44, 0x24, 0xff, 0x08, 0x4c, 0x26, 0xff, 0x07, 0x4d, 0x26, 0xff, 0x06, 0x4b, 0x28, 0xff, 0x06, 0x4b, 0x26, 0xff, 0x0d, 0x4e, 0x27, 0xff, 0x05, 0x2f, 0x15, 0xff, 0x00, 0x20, 0x0e, 0xff, 0x02, 0x2f, 0x17, 0xff, 0x0d, 0x50, 0x2b, 0xff, 0x0d, 0x52, 0x2c, 0xff, 0x04, 0x43, 0x22, 0xff, 0x0b, 0x4c, 0x26, 0xff, 0x0d, 0x5a, 0x2d, 0xff, 0x0a, 0x5b, 0x2d, 0xff, 0x03, 0x43, 0x20, 0xff, 0x02, 0x29, 0x18, 0xff, 0x08, 0x2a, 0x1c, 0xff, 0x01, 0x27, 0x14, 0xff, 0x08, 0x3a, 0x20, 0xff, 0x10, 0x49, 0x31, 0xff, 0x0a, 0x42, 0x2b, 0xff, 0x01, 0x37, 0x20, 0xff, 0x03, 0x36, 0x1f, 0xff, 0x05, 0x32, 0x1a, 0xff, 0x07, 0x33, 0x19, 0xff, 0x02, 0x33, 0x16, 0xff, 0x10, 0x5e, 0x3a, 0xff, 0x12, 0x9a, 0x64, 0xff, 0x15, 0x9e, 0x59, 0xff, 0x06, 0x80, 0x35, 0xff, 0x0f, 0x82, 0x3c, 0xff, 0x10, 0x75, 0x37, 0xff, 0x0f, 0x65, 0x30, 0xff, 0x0a, 0x4b, 0x24, 0xff, 0x03, 0x36, 0x17, 0xff, 0x0c, 0x3f, 0x1c, 0xff, 0x05, 0x40, 0x22, 0xff, 0x1f, 0x6c, 0x47, 0xff, 0x2e, 0x8c, 0x58, 0xff, 0x06, 0x51, 0x20, 0xff, 0x0d, 0x5e, 0x29, 0xff, 0x10, 0x73, 0x41, 0xff, 0x11, 0x61, 0x43, 0xff, 0x62, 0x68, 0xa1, 0xff, 0x62, 0x50, 0xb5, 0xff, 0x50, 0x51, 0xa0, 0xff, 0x13, 0x3f, 0x45, 0xff, 0x12, 0x45, 0x3e, 0xff, 0x29, 0x4e, 0x5c, 0xff, 0x10, 0x42, 0x42, 0xff, 0x09, 0x57, 0x39, 0xff, 0x04, 0x67, 0x39, 0xff, 0x0c, 0x66, 0x3b, 0xff, 0x13, 0x60, 0x3f, 0xff, 0x12, 0x63, 0x4a, 0xff, 0x13, 0x7b, 0x58, 0xff, 0x0c, 0x83, 0x5a, 0xff, 0x0b, 0x83, 0x5c, 0xff, 0x10, 0x89, 0x56, 0xff, 0x10, 0x91, 0x5f, 0xff, 0x10, 0x93, 0x61, 0xff, 0x11, 0x97, 0x63, 0xff, 0x11, 0x99, 0x65, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x0d, 0x9b, 0x66, 0xff, 0x0e, 0x9d, 0x68, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x12, 0xa1, 0x6c, 0xff, 0x11, 0xa1, 0x6c, 0xff, 0x0f, 0xa0, 0x6a, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x0f, 0xa0, 0x6b, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x10, 0xa0, 0x6a, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x10, 0x9f, 0x6e, 0xff, 0x0f, 0x9f, 0x6d, 0xff, 0x0e, 0x9d, 0x6c, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0f, 0x9e, 0x6d, 0xff, 0x0e, 0x9d, 0x6c, 0xff, 0x0f, 0x9e, 0x6d, 0xff, 0x0e, 0x9e, 0x6d, 0xff, 0x0e, 0x9d, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x0b, 0x9c, 0x68, 0xff, 0x0b, 0x9c, 0x68, 0xff, 0x0b, 0x9c, 0x68, 0xff, 0x0c, 0x9b, 0x68, 0xff, 0x0c, 0x9b, 0x68, 0xff, 0x0b, 0x9a, 0x67, 0xff, 0x0c, 0x9b, 0x67, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0d, 0x9c, 0x69, 0xff, 0x0d, 0x9c, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x10, 0x9f, 0x6b, 0xff, 0x11, 0x9f, 0x6b, 0xff, 0x0f, 0x9d, 0x6a, 0xff, 0x0f, 0x9d, 0x6a, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0e, 0x9b, 0x68, 0xff, 0x0f, 0x9a, 0x69, 0xff, 0x10, 0x9a, 0x69, 0xff, 0x12, 0x9b, 0x67, 0xff, 0x12, 0x9b, 0x66, 0xff, 0x12, 0x9c, 0x65, 0xff, 0x10, 0x9b, 0x63, 0xff, 0x17, 0xa6, 0x67, 0xff, 0x04, 0x90, 0x4b, 0xff, 0x01, 0x86, 0x44, 0xff, 0x08, 0x88, 0x4d, 0xff, 0x13, 0x95, 0x5c, 0xff, 0x11, 0x9a, 0x63, 0xff, 0x0b, 0x9a, 0x67, 0xff, 0x18, 0x99, 0x6b, 0xff, 0x16, 0x6d, 0x49, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x03, 0x31, 0x1c, 0xff, 0x03, 0x31, 0x1b, 0xff, 0x03, 0x31, 0x1b, 0xff, 0x04, 0x32, 0x19, 0xff, 0x03, 0x33, 0x17, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x19, 0x79, 0x53, 0xff, 0x18, 0x97, 0x68, 0xff, 0x0a, 0x99, 0x63, 0xff, 0x0f, 0x97, 0x62, 0xff, 0x14, 0x95, 0x62, 0xff, 0x14, 0x94, 0x63, 0xff, 0x0e, 0x95, 0x63, 0xff, 0x0a, 0x95, 0x62, 0xff, 0x09, 0x94, 0x62, 0xff, 0x0a, 0x94, 0x63, 0xff, 0x0b, 0x96, 0x63, 0xff, 0x10, 0x96, 0x64, 0xff, 0x13, 0x96, 0x63, 0xff, 0x10, 0x94, 0x62, 0xff, 0x0f, 0x94, 0x62, 0xff, 0x0c, 0x92, 0x60, 0xff, 0x0b, 0x91, 0x5f, 0xff, 0x0d, 0x90, 0x5f, 0xff, 0x0c, 0x8f, 0x60, 0xff, 0x11, 0x8e, 0x60, 0xff, 0x12, 0x8e, 0x60, 0xff, 0x12, 0x8e, 0x60, 0xff, 0x10, 0x8f, 0x60, 0xff, 0x0f, 0x8f, 0x60, 0xff, 0x0f, 0x8f, 0x60, 0xff, 0x11, 0x8e, 0x5e, 0xff, 0x12, 0x8e, 0x5c, 0xff, 0x10, 0x8d, 0x5d, 0xff, 0x11, 0x8a, 0x5f, 0xff, 0x17, 0x82, 0x5b, 0xff, 0x0c, 0x5c, 0x3a, 0xff, 0x01, 0x3d, 0x1a, 0xff, 0x03, 0x4a, 0x23, 0xff, 0x0f, 0x65, 0x3c, 0xff, 0x0b, 0x5a, 0x34, 0xff, 0x0c, 0x57, 0x33, 0xff, 0x06, 0x4f, 0x2b, 0xff, 0x07, 0x50, 0x2b, 0xff, 0x0a, 0x56, 0x30, 0xff, 0x07, 0x57, 0x2f, 0xff, 0x07, 0x5a, 0x31, 0xff, 0x04, 0x5c, 0x31, 0xff, 0x07, 0x5d, 0x31, 0xff, 0x08, 0x5e, 0x36, 0xff, 0x06, 0x59, 0x35, 0xff, 0x00, 0x38, 0x1c, 0xff, 0x02, 0x26, 0x10, 0xff, 0x08, 0x2b, 0x16, 0xff, 0x02, 0x2a, 0x14, 0xff, 0x08, 0x3f, 0x23, 0xff, 0x0a, 0x4d, 0x27, 0xff, 0x03, 0x4d, 0x25, 0xff, 0x00, 0x4d, 0x26, 0xff, 0x02, 0x4b, 0x29, 0xff, 0x07, 0x4a, 0x29, 0xff, 0x03, 0x3d, 0x1e, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x0d, 0x4f, 0x2c, 0xff, 0x0a, 0x4c, 0x29, 0xff, 0x08, 0x46, 0x26, 0xff, 0x04, 0x3d, 0x1e, 0xff, 0x05, 0x33, 0x19, 0xff, 0x06, 0x30, 0x1a, 0xff, 0x08, 0x2f, 0x1b, 0xff, 0x01, 0x23, 0x11, 0xff, 0x02, 0x27, 0x13, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x10, 0x49, 0x2c, 0xff, 0x0d, 0x48, 0x2c, 0xff, 0x01, 0x32, 0x17, 0xff, 0x06, 0x39, 0x1d, 0xff, 0x0c, 0x4d, 0x2c, 0xff, 0x08, 0x4e, 0x2b, 0xff, 0x0d, 0x4a, 0x28, 0xff, 0x03, 0x31, 0x19, 0xff, 0x03, 0x39, 0x1d, 0xff, 0x0b, 0x4b, 0x2a, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x0c, 0x53, 0x2e, 0xff, 0x0d, 0x55, 0x2f, 0xff, 0x0e, 0x58, 0x2f, 0xff, 0x0a, 0x57, 0x2e, 0xff, 0x0b, 0x57, 0x31, 0xff, 0x10, 0x55, 0x33, 0xff, 0x02, 0x3b, 0x1f, 0xff, 0x00, 0x30, 0x18, 0xff, 0x02, 0x30, 0x16, 0xff, 0x0e, 0x44, 0x20, 0xff, 0x04, 0x44, 0x15, 0xff, 0x03, 0x48, 0x16, 0xff, 0x01, 0x4d, 0x19, 0xff, 0x01, 0x53, 0x1e, 0xff, 0x00, 0x59, 0x23, 0xff, 0x04, 0x59, 0x27, 0xff, 0x0a, 0x4f, 0x27, 0xff, 0x03, 0x35, 0x16, 0xff, 0x06, 0x32, 0x19, 0xff, 0x0c, 0x47, 0x29, 0xff, 0x0b, 0x4c, 0x2c, 0xff, 0x09, 0x4c, 0x2c, 0xff, 0x07, 0x4c, 0x2b, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x4b, 0x2b, 0xff, 0x0b, 0x3e, 0x24, 0xff, 0x01, 0x28, 0x11, 0xff, 0x04, 0x33, 0x1a, 0xff, 0x11, 0x4f, 0x31, 0xff, 0x07, 0x4e, 0x2e, 0xff, 0x03, 0x50, 0x2d, 0xff, 0x05, 0x50, 0x2c, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x09, 0x52, 0x2d, 0xff, 0x0b, 0x53, 0x2c, 0xff, 0x0c, 0x53, 0x2b, 0xff, 0x08, 0x50, 0x2b, 0xff, 0x09, 0x4f, 0x2e, 0xff, 0x0d, 0x49, 0x2e, 0xff, 0x02, 0x2f, 0x17, 0xff, 0x00, 0x27, 0x11, 0xff, 0x0b, 0x4b, 0x32, 0xff, 0x16, 0x86, 0x60, 0xff, 0x15, 0x96, 0x68, 0xff, 0x0e, 0x7e, 0x4f, 0xff, 0x10, 0x65, 0x3d, 0xff, 0x08, 0x3b, 0x1d, 0xff, 0x01, 0x2a, 0x0f, 0xff, 0x0d, 0x5a, 0x38, 0xff, 0x09, 0x6b, 0x3b, 0xff, 0x09, 0x6c, 0x37, 0xff, 0x09, 0x63, 0x35, 0xff, 0x0c, 0x57, 0x33, 0xff, 0x08, 0x48, 0x2a, 0xff, 0x1a, 0x54, 0x3b, 0xff, 0x0c, 0x40, 0x26, 0xff, 0x10, 0x45, 0x2b, 0xff, 0x2c, 0x5c, 0x51, 0xff, 0x25, 0x52, 0x52, 0xff, 0x12, 0x4a, 0x41, 0xff, 0x0e, 0x54, 0x3c, 0xff, 0x0c, 0x58, 0x3a, 0xff, 0x13, 0x56, 0x3b, 0xff, 0x05, 0x2e, 0x1c, 0xff, 0x65, 0x72, 0x69, 0xff, + 0x06, 0x33, 0x1b, 0xff, 0x0a, 0x44, 0x24, 0xff, 0x06, 0x45, 0x22, 0xff, 0x08, 0x48, 0x25, 0xff, 0x0a, 0x4b, 0x27, 0xff, 0x0a, 0x4d, 0x27, 0xff, 0x0d, 0x4a, 0x28, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x01, 0x27, 0x11, 0xff, 0x01, 0x28, 0x13, 0xff, 0x08, 0x3a, 0x20, 0xff, 0x0c, 0x4f, 0x2b, 0xff, 0x09, 0x56, 0x2b, 0xff, 0x08, 0x57, 0x2b, 0xff, 0x07, 0x58, 0x2a, 0xff, 0x0b, 0x55, 0x2c, 0xff, 0x08, 0x3e, 0x22, 0xff, 0x00, 0x23, 0x12, 0xff, 0x01, 0x28, 0x14, 0xff, 0x09, 0x43, 0x24, 0xff, 0x08, 0x4b, 0x25, 0xff, 0x07, 0x4c, 0x26, 0xff, 0x05, 0x4a, 0x27, 0xff, 0x05, 0x4b, 0x28, 0xff, 0x0e, 0x4e, 0x28, 0xff, 0x04, 0x2f, 0x14, 0xff, 0x00, 0x20, 0x0e, 0xff, 0x04, 0x34, 0x1b, 0xff, 0x0a, 0x4e, 0x29, 0xff, 0x0a, 0x4d, 0x29, 0xff, 0x03, 0x3f, 0x1e, 0xff, 0x0f, 0x53, 0x2b, 0xff, 0x0d, 0x59, 0x2e, 0xff, 0x08, 0x51, 0x2a, 0xff, 0x01, 0x34, 0x16, 0xff, 0x03, 0x28, 0x18, 0xff, 0x07, 0x28, 0x1a, 0xff, 0x02, 0x2c, 0x18, 0xff, 0x0a, 0x3e, 0x25, 0xff, 0x07, 0x40, 0x26, 0xff, 0x04, 0x39, 0x21, 0xff, 0x02, 0x36, 0x1e, 0xff, 0x02, 0x34, 0x1c, 0xff, 0x07, 0x35, 0x1b, 0xff, 0x07, 0x34, 0x18, 0xff, 0x02, 0x3a, 0x18, 0xff, 0x15, 0x6d, 0x42, 0xff, 0x15, 0x9b, 0x5f, 0xff, 0x10, 0x87, 0x48, 0xff, 0x0f, 0x74, 0x36, 0xff, 0x0a, 0x65, 0x2d, 0xff, 0x03, 0x4f, 0x21, 0xff, 0x02, 0x3e, 0x18, 0xff, 0x01, 0x35, 0x17, 0xff, 0x05, 0x37, 0x1b, 0xff, 0x0f, 0x42, 0x1d, 0xff, 0x07, 0x38, 0x1d, 0xff, 0x17, 0x4e, 0x37, 0xff, 0x10, 0x53, 0x34, 0xff, 0x01, 0x44, 0x1c, 0xff, 0x16, 0x73, 0x3b, 0xff, 0x1a, 0x7e, 0x48, 0xff, 0x10, 0x5b, 0x3c, 0xff, 0x5e, 0x70, 0x95, 0xff, 0x63, 0x66, 0xa9, 0xff, 0x3d, 0x50, 0x82, 0xff, 0x10, 0x43, 0x3e, 0xff, 0x35, 0x65, 0x72, 0xff, 0x3c, 0x62, 0x81, 0xff, 0x1d, 0x5d, 0x53, 0xff, 0x09, 0x63, 0x3d, 0xff, 0x07, 0x70, 0x44, 0xff, 0x11, 0x74, 0x43, 0xff, 0x0f, 0x6d, 0x3c, 0xff, 0x12, 0x70, 0x50, 0xff, 0x0e, 0x7d, 0x59, 0xff, 0x0f, 0x8d, 0x5d, 0xff, 0x09, 0x87, 0x5b, 0xff, 0x12, 0x91, 0x5b, 0xff, 0x12, 0x96, 0x63, 0xff, 0x12, 0x97, 0x65, 0xff, 0x11, 0x99, 0x65, 0xff, 0x13, 0x9b, 0x67, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x0c, 0x99, 0x66, 0xff, 0x0b, 0x9c, 0x66, 0xff, 0x0d, 0x9e, 0x68, 0xff, 0x10, 0xa1, 0x6b, 0xff, 0x11, 0xa3, 0x6d, 0xff, 0x11, 0xa3, 0x6d, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x10, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x11, 0xa1, 0x6c, 0xff, 0x11, 0xa1, 0x6c, 0xff, 0x11, 0xa1, 0x6c, 0xff, 0x10, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa0, 0x6e, 0xff, 0x0f, 0xa0, 0x6d, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0f, 0xa0, 0x6d, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0e, 0x9f, 0x6d, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0d, 0x9e, 0x6b, 0xff, 0x0e, 0x9e, 0x6b, 0xff, 0x0e, 0xa0, 0x6b, 0xff, 0x0e, 0xa0, 0x6b, 0xff, 0x0e, 0xa0, 0x6b, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x10, 0xa1, 0x6d, 0xff, 0x10, 0xa1, 0x6d, 0xff, 0x10, 0xa0, 0x6d, 0xff, 0x0e, 0x9e, 0x6b, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0d, 0x9c, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x0f, 0x9a, 0x69, 0xff, 0x0f, 0x9a, 0x68, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x11, 0x9a, 0x65, 0xff, 0x13, 0x9d, 0x67, 0xff, 0x0b, 0x96, 0x5a, 0xff, 0x02, 0x8a, 0x4a, 0xff, 0x08, 0x92, 0x53, 0xff, 0x15, 0x9a, 0x62, 0xff, 0x13, 0x9b, 0x64, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x09, 0x99, 0x68, 0xff, 0x1f, 0x96, 0x6c, 0xff, 0x06, 0x4c, 0x2d, 0xff, 0x02, 0x31, 0x18, 0xff, 0x06, 0x31, 0x1b, 0xff, 0x04, 0x31, 0x1b, 0xff, 0x07, 0x31, 0x1a, 0xff, 0x05, 0x32, 0x19, 0xff, 0x00, 0x32, 0x15, 0xff, 0x02, 0x45, 0x24, 0xff, 0x16, 0x7f, 0x57, 0xff, 0x1d, 0x96, 0x6a, 0xff, 0x0d, 0x99, 0x67, 0xff, 0x08, 0x9b, 0x65, 0xff, 0x13, 0x99, 0x65, 0xff, 0x17, 0x97, 0x64, 0xff, 0x14, 0x97, 0x65, 0xff, 0x0d, 0x97, 0x65, 0xff, 0x0a, 0x96, 0x63, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0e, 0x95, 0x64, 0xff, 0x09, 0x95, 0x62, 0xff, 0x0f, 0x95, 0x63, 0xff, 0x11, 0x95, 0x63, 0xff, 0x0f, 0x95, 0x63, 0xff, 0x0d, 0x93, 0x61, 0xff, 0x0b, 0x93, 0x60, 0xff, 0x0b, 0x92, 0x60, 0xff, 0x0c, 0x91, 0x60, 0xff, 0x0b, 0x91, 0x5f, 0xff, 0x11, 0x8f, 0x5f, 0xff, 0x14, 0x8e, 0x5f, 0xff, 0x13, 0x8f, 0x60, 0xff, 0x12, 0x8f, 0x61, 0xff, 0x0e, 0x90, 0x61, 0xff, 0x0c, 0x90, 0x61, 0xff, 0x0d, 0x91, 0x5e, 0xff, 0x0f, 0x90, 0x5d, 0xff, 0x14, 0x8e, 0x5f, 0xff, 0x14, 0x8d, 0x61, 0xff, 0x13, 0x8b, 0x60, 0xff, 0x17, 0x81, 0x59, 0xff, 0x08, 0x57, 0x32, 0xff, 0x01, 0x47, 0x1f, 0xff, 0x0b, 0x60, 0x38, 0xff, 0x0b, 0x56, 0x32, 0xff, 0x06, 0x4d, 0x29, 0xff, 0x03, 0x48, 0x25, 0xff, 0x04, 0x47, 0x23, 0xff, 0x0b, 0x4e, 0x2a, 0xff, 0x0b, 0x52, 0x2e, 0xff, 0x0d, 0x57, 0x31, 0xff, 0x0c, 0x56, 0x30, 0xff, 0x12, 0x54, 0x2f, 0xff, 0x0e, 0x5b, 0x36, 0xff, 0x03, 0x5c, 0x38, 0xff, 0x03, 0x4b, 0x2c, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x07, 0x2a, 0x11, 0xff, 0x01, 0x2a, 0x0e, 0xff, 0x01, 0x3c, 0x1b, 0xff, 0x03, 0x50, 0x25, 0xff, 0x03, 0x54, 0x28, 0xff, 0x04, 0x54, 0x29, 0xff, 0x03, 0x56, 0x2e, 0xff, 0x03, 0x50, 0x2b, 0xff, 0x01, 0x43, 0x20, 0xff, 0x00, 0x38, 0x17, 0xff, 0x0b, 0x47, 0x25, 0xff, 0x0c, 0x4e, 0x2b, 0xff, 0x09, 0x47, 0x28, 0xff, 0x04, 0x3e, 0x20, 0xff, 0x0a, 0x3d, 0x21, 0xff, 0x02, 0x2d, 0x15, 0xff, 0x0b, 0x34, 0x1d, 0xff, 0x06, 0x2b, 0x17, 0xff, 0x01, 0x24, 0x11, 0xff, 0x01, 0x29, 0x0f, 0xff, 0x10, 0x47, 0x2b, 0xff, 0x0e, 0x49, 0x2d, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x04, 0x32, 0x17, 0xff, 0x0d, 0x4c, 0x2c, 0xff, 0x09, 0x4e, 0x2b, 0xff, 0x0d, 0x4a, 0x29, 0xff, 0x03, 0x31, 0x19, 0xff, 0x03, 0x36, 0x1c, 0xff, 0x0a, 0x48, 0x28, 0xff, 0x09, 0x4e, 0x2a, 0xff, 0x07, 0x4f, 0x2b, 0xff, 0x08, 0x53, 0x2d, 0xff, 0x08, 0x53, 0x2b, 0xff, 0x0c, 0x58, 0x2c, 0xff, 0x0a, 0x57, 0x2e, 0xff, 0x0b, 0x58, 0x31, 0xff, 0x0c, 0x57, 0x32, 0xff, 0x02, 0x41, 0x20, 0xff, 0x00, 0x33, 0x17, 0xff, 0x02, 0x35, 0x17, 0xff, 0x0a, 0x44, 0x1f, 0xff, 0x05, 0x44, 0x18, 0xff, 0x03, 0x48, 0x16, 0xff, 0x03, 0x4f, 0x1a, 0xff, 0x02, 0x55, 0x20, 0xff, 0x00, 0x59, 0x24, 0xff, 0x03, 0x58, 0x26, 0xff, 0x09, 0x49, 0x23, 0xff, 0x01, 0x2c, 0x0f, 0xff, 0x09, 0x35, 0x1e, 0xff, 0x0d, 0x48, 0x2b, 0xff, 0x0b, 0x4b, 0x2d, 0xff, 0x09, 0x4b, 0x2c, 0xff, 0x09, 0x4d, 0x2d, 0xff, 0x08, 0x4c, 0x2c, 0xff, 0x08, 0x4c, 0x2d, 0xff, 0x08, 0x4c, 0x2c, 0xff, 0x09, 0x4b, 0x2c, 0xff, 0x0a, 0x3c, 0x23, 0xff, 0x00, 0x2a, 0x13, 0xff, 0x08, 0x3d, 0x23, 0xff, 0x0d, 0x50, 0x30, 0xff, 0x06, 0x50, 0x2e, 0xff, 0x04, 0x51, 0x2c, 0xff, 0x05, 0x50, 0x2c, 0xff, 0x09, 0x51, 0x2e, 0xff, 0x08, 0x52, 0x2d, 0xff, 0x0b, 0x52, 0x2d, 0xff, 0x0b, 0x52, 0x2b, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0d, 0x50, 0x30, 0xff, 0x09, 0x3d, 0x24, 0xff, 0x00, 0x29, 0x12, 0xff, 0x02, 0x31, 0x18, 0xff, 0x13, 0x68, 0x49, 0xff, 0x1c, 0x96, 0x6c, 0xff, 0x13, 0x93, 0x62, 0xff, 0x0e, 0x74, 0x45, 0xff, 0x13, 0x59, 0x34, 0xff, 0x04, 0x2f, 0x16, 0xff, 0x02, 0x2a, 0x14, 0xff, 0x0b, 0x53, 0x35, 0xff, 0x0d, 0x69, 0x3e, 0xff, 0x08, 0x6c, 0x38, 0xff, 0x05, 0x64, 0x36, 0xff, 0x11, 0x60, 0x3a, 0xff, 0x09, 0x4d, 0x2e, 0xff, 0x13, 0x4a, 0x31, 0xff, 0x03, 0x2b, 0x17, 0xff, 0x03, 0x2b, 0x18, 0xff, 0x25, 0x4d, 0x48, 0xff, 0x1e, 0x4c, 0x4f, 0xff, 0x10, 0x4d, 0x43, 0xff, 0x0d, 0x55, 0x3d, 0xff, 0x0f, 0x58, 0x3c, 0xff, 0x14, 0x54, 0x3b, 0xff, 0x04, 0x2c, 0x1a, 0xff, 0x63, 0x72, 0x66, 0xff, + 0x06, 0x33, 0x1b, 0xff, 0x0a, 0x44, 0x24, 0xff, 0x07, 0x45, 0x22, 0xff, 0x08, 0x48, 0x25, 0xff, 0x09, 0x49, 0x26, 0xff, 0x0b, 0x4c, 0x28, 0xff, 0x0e, 0x4b, 0x29, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x01, 0x26, 0x11, 0xff, 0x00, 0x26, 0x13, 0xff, 0x06, 0x35, 0x1d, 0xff, 0x0d, 0x4d, 0x2b, 0xff, 0x0b, 0x55, 0x2c, 0xff, 0x08, 0x57, 0x2b, 0xff, 0x07, 0x57, 0x29, 0xff, 0x0c, 0x56, 0x2c, 0xff, 0x0b, 0x43, 0x26, 0xff, 0x00, 0x23, 0x11, 0xff, 0x01, 0x27, 0x14, 0xff, 0x09, 0x43, 0x24, 0xff, 0x07, 0x4a, 0x25, 0xff, 0x07, 0x4b, 0x25, 0xff, 0x05, 0x48, 0x25, 0xff, 0x03, 0x4a, 0x28, 0xff, 0x0d, 0x4e, 0x28, 0xff, 0x04, 0x2d, 0x13, 0xff, 0x00, 0x20, 0x0d, 0xff, 0x06, 0x38, 0x1e, 0xff, 0x0c, 0x4f, 0x2b, 0xff, 0x06, 0x46, 0x23, 0xff, 0x03, 0x3f, 0x1d, 0xff, 0x10, 0x58, 0x2d, 0xff, 0x10, 0x58, 0x31, 0xff, 0x06, 0x41, 0x22, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x07, 0x2c, 0x1a, 0xff, 0x03, 0x27, 0x15, 0xff, 0x02, 0x31, 0x1b, 0xff, 0x06, 0x3d, 0x25, 0xff, 0x02, 0x3c, 0x20, 0xff, 0x04, 0x39, 0x1f, 0xff, 0x04, 0x38, 0x1f, 0xff, 0x03, 0x38, 0x1d, 0xff, 0x05, 0x35, 0x19, 0xff, 0x07, 0x3a, 0x1a, 0xff, 0x03, 0x47, 0x1e, 0xff, 0x19, 0x7d, 0x4c, 0xff, 0x0f, 0x89, 0x4b, 0xff, 0x06, 0x69, 0x31, 0xff, 0x05, 0x51, 0x22, 0xff, 0x01, 0x45, 0x1c, 0xff, 0x02, 0x3f, 0x1b, 0xff, 0x01, 0x36, 0x16, 0xff, 0x05, 0x35, 0x1a, 0xff, 0x10, 0x3f, 0x27, 0xff, 0x0d, 0x3a, 0x20, 0xff, 0x0a, 0x2f, 0x14, 0xff, 0x09, 0x2d, 0x16, 0xff, 0x01, 0x31, 0x19, 0xff, 0x02, 0x45, 0x20, 0xff, 0x1a, 0x7d, 0x46, 0xff, 0x10, 0x66, 0x35, 0xff, 0x18, 0x54, 0x37, 0xff, 0x3a, 0x5d, 0x63, 0xff, 0x5b, 0x75, 0x8a, 0xff, 0x2c, 0x51, 0x5d, 0xff, 0x19, 0x52, 0x3f, 0xff, 0x49, 0x78, 0x8c, 0xff, 0x44, 0x6c, 0x8f, 0xff, 0x23, 0x68, 0x5b, 0xff, 0x0d, 0x6a, 0x44, 0xff, 0x13, 0x82, 0x56, 0xff, 0x0f, 0x80, 0x4a, 0xff, 0x12, 0x80, 0x4d, 0xff, 0x13, 0x80, 0x5b, 0xff, 0x0a, 0x83, 0x56, 0xff, 0x0e, 0x91, 0x59, 0xff, 0x10, 0x94, 0x63, 0xff, 0x16, 0x9c, 0x64, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x13, 0x9b, 0x68, 0xff, 0x12, 0x9b, 0x67, 0xff, 0x12, 0x9c, 0x67, 0xff, 0x10, 0x9b, 0x66, 0xff, 0x0e, 0x9a, 0x65, 0xff, 0x0c, 0x9b, 0x67, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0d, 0xa3, 0x70, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x10, 0xa4, 0x70, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0d, 0x9f, 0x6b, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0b, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0d, 0x9c, 0x6a, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x10, 0x9c, 0x68, 0xff, 0x10, 0x9c, 0x67, 0xff, 0x11, 0x9b, 0x67, 0xff, 0x0f, 0x98, 0x64, 0xff, 0x0b, 0x94, 0x5e, 0xff, 0x0e, 0x98, 0x5d, 0xff, 0x12, 0x9d, 0x63, 0xff, 0x12, 0x9c, 0x66, 0xff, 0x0e, 0x99, 0x65, 0xff, 0x0c, 0x9a, 0x68, 0xff, 0x19, 0x99, 0x6e, 0xff, 0x12, 0x73, 0x4f, 0xff, 0x01, 0x35, 0x1a, 0xff, 0x08, 0x32, 0x1b, 0xff, 0x06, 0x32, 0x1c, 0xff, 0x02, 0x30, 0x19, 0xff, 0x04, 0x32, 0x17, 0xff, 0x01, 0x33, 0x15, 0xff, 0x08, 0x55, 0x31, 0xff, 0x16, 0x81, 0x57, 0xff, 0x14, 0x97, 0x68, 0xff, 0x0e, 0x98, 0x67, 0xff, 0x0b, 0x9a, 0x66, 0xff, 0x0c, 0x99, 0x65, 0xff, 0x11, 0x97, 0x64, 0xff, 0x13, 0x97, 0x64, 0xff, 0x10, 0x98, 0x65, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x12, 0x95, 0x64, 0xff, 0x11, 0x95, 0x64, 0xff, 0x0b, 0x96, 0x63, 0xff, 0x0d, 0x93, 0x61, 0xff, 0x0e, 0x93, 0x61, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0c, 0x95, 0x62, 0xff, 0x0c, 0x94, 0x61, 0xff, 0x0d, 0x92, 0x60, 0xff, 0x0c, 0x92, 0x60, 0xff, 0x0a, 0x92, 0x5f, 0xff, 0x0f, 0x91, 0x5f, 0xff, 0x13, 0x90, 0x5f, 0xff, 0x13, 0x8f, 0x5f, 0xff, 0x11, 0x8f, 0x60, 0xff, 0x0e, 0x90, 0x61, 0xff, 0x0e, 0x90, 0x61, 0xff, 0x0d, 0x90, 0x61, 0xff, 0x0b, 0x90, 0x5e, 0xff, 0x13, 0x8d, 0x5d, 0xff, 0x13, 0x8d, 0x5e, 0xff, 0x0d, 0x8e, 0x5e, 0xff, 0x10, 0x8f, 0x5f, 0xff, 0x17, 0x84, 0x59, 0xff, 0x0c, 0x6a, 0x41, 0xff, 0x09, 0x63, 0x3b, 0xff, 0x09, 0x5e, 0x37, 0xff, 0x01, 0x49, 0x22, 0xff, 0x01, 0x44, 0x1f, 0xff, 0x02, 0x44, 0x20, 0xff, 0x06, 0x47, 0x24, 0xff, 0x0b, 0x4c, 0x2b, 0xff, 0x0d, 0x4f, 0x2d, 0xff, 0x0d, 0x4e, 0x2c, 0xff, 0x10, 0x4e, 0x2b, 0xff, 0x0b, 0x55, 0x30, 0xff, 0x06, 0x5c, 0x36, 0xff, 0x10, 0x5b, 0x38, 0xff, 0x05, 0x36, 0x15, 0xff, 0x01, 0x2e, 0x0c, 0xff, 0x04, 0x45, 0x1d, 0xff, 0x11, 0x6d, 0x3e, 0xff, 0x16, 0x79, 0x46, 0xff, 0x1c, 0x7d, 0x4b, 0xff, 0x1b, 0x7a, 0x4b, 0xff, 0x16, 0x72, 0x45, 0xff, 0x0f, 0x67, 0x3d, 0xff, 0x08, 0x55, 0x2d, 0xff, 0x03, 0x42, 0x1e, 0xff, 0x03, 0x3e, 0x1c, 0xff, 0x06, 0x48, 0x26, 0xff, 0x0d, 0x4c, 0x2c, 0xff, 0x0a, 0x44, 0x26, 0xff, 0x0a, 0x3e, 0x22, 0xff, 0x09, 0x37, 0x1d, 0xff, 0x04, 0x2c, 0x15, 0xff, 0x0a, 0x33, 0x1d, 0xff, 0x01, 0x28, 0x13, 0xff, 0x00, 0x26, 0x0c, 0xff, 0x0d, 0x40, 0x26, 0xff, 0x0f, 0x4a, 0x2e, 0xff, 0x05, 0x3c, 0x20, 0xff, 0x01, 0x2c, 0x10, 0xff, 0x0d, 0x48, 0x2a, 0xff, 0x0a, 0x4e, 0x2c, 0xff, 0x0f, 0x4a, 0x29, 0xff, 0x05, 0x32, 0x1b, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x0a, 0x45, 0x27, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x04, 0x51, 0x2b, 0xff, 0x01, 0x52, 0x2a, 0xff, 0x01, 0x55, 0x28, 0xff, 0x06, 0x5e, 0x2c, 0xff, 0x04, 0x56, 0x2b, 0xff, 0x06, 0x5a, 0x2f, 0xff, 0x05, 0x5d, 0x31, 0xff, 0x02, 0x55, 0x29, 0xff, 0x01, 0x47, 0x20, 0xff, 0x03, 0x44, 0x1f, 0xff, 0x03, 0x43, 0x1b, 0xff, 0x03, 0x45, 0x17, 0xff, 0x01, 0x4b, 0x19, 0xff, 0x04, 0x50, 0x1d, 0xff, 0x03, 0x57, 0x22, 0xff, 0x00, 0x59, 0x26, 0xff, 0x05, 0x58, 0x28, 0xff, 0x08, 0x44, 0x20, 0xff, 0x01, 0x27, 0x0b, 0xff, 0x0d, 0x3b, 0x25, 0xff, 0x0d, 0x48, 0x2c, 0xff, 0x0b, 0x4b, 0x2d, 0xff, 0x07, 0x4a, 0x2b, 0xff, 0x07, 0x4b, 0x2c, 0xff, 0x08, 0x4b, 0x2c, 0xff, 0x08, 0x4c, 0x2d, 0xff, 0x09, 0x4c, 0x2d, 0xff, 0x07, 0x49, 0x2b, 0xff, 0x0a, 0x3c, 0x23, 0xff, 0x02, 0x2f, 0x17, 0xff, 0x0e, 0x47, 0x2b, 0xff, 0x09, 0x4e, 0x2d, 0xff, 0x07, 0x51, 0x2d, 0xff, 0x07, 0x51, 0x2c, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x09, 0x50, 0x2f, 0xff, 0x09, 0x52, 0x2f, 0xff, 0x09, 0x52, 0x2d, 0xff, 0x09, 0x52, 0x2b, 0xff, 0x0a, 0x51, 0x2e, 0xff, 0x11, 0x4d, 0x30, 0xff, 0x04, 0x31, 0x1b, 0xff, 0x00, 0x29, 0x12, 0xff, 0x07, 0x4b, 0x2d, 0xff, 0x16, 0x82, 0x5d, 0xff, 0x1a, 0x99, 0x6b, 0xff, 0x0f, 0x89, 0x56, 0xff, 0x0f, 0x6c, 0x3d, 0xff, 0x0e, 0x4d, 0x2a, 0xff, 0x01, 0x25, 0x11, 0xff, 0x07, 0x2d, 0x1b, 0xff, 0x0d, 0x4a, 0x31, 0xff, 0x10, 0x5f, 0x3a, 0xff, 0x0b, 0x6c, 0x3c, 0xff, 0x07, 0x66, 0x39, 0xff, 0x0e, 0x5e, 0x36, 0xff, 0x11, 0x56, 0x35, 0xff, 0x0a, 0x3d, 0x23, 0xff, 0x03, 0x24, 0x11, 0xff, 0x03, 0x22, 0x14, 0xff, 0x11, 0x35, 0x32, 0xff, 0x10, 0x44, 0x43, 0xff, 0x0f, 0x52, 0x44, 0xff, 0x0c, 0x57, 0x3b, 0xff, 0x14, 0x5a, 0x3e, 0xff, 0x16, 0x51, 0x3b, 0xff, 0x03, 0x28, 0x19, 0xff, 0x63, 0x70, 0x65, 0xff, + 0x06, 0x33, 0x1b, 0xff, 0x0a, 0x44, 0x24, 0xff, 0x06, 0x45, 0x22, 0xff, 0x07, 0x46, 0x26, 0xff, 0x08, 0x48, 0x27, 0xff, 0x0b, 0x4b, 0x27, 0xff, 0x0e, 0x4b, 0x28, 0xff, 0x06, 0x35, 0x1a, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x26, 0x13, 0xff, 0x04, 0x31, 0x19, 0xff, 0x0c, 0x4b, 0x29, 0xff, 0x0a, 0x54, 0x2b, 0xff, 0x07, 0x56, 0x2a, 0xff, 0x06, 0x58, 0x28, 0xff, 0x09, 0x55, 0x2a, 0xff, 0x0d, 0x46, 0x29, 0xff, 0x01, 0x24, 0x12, 0xff, 0x01, 0x27, 0x14, 0xff, 0x08, 0x43, 0x24, 0xff, 0x06, 0x49, 0x24, 0xff, 0x08, 0x49, 0x25, 0xff, 0x06, 0x48, 0x26, 0xff, 0x03, 0x49, 0x27, 0xff, 0x0d, 0x4e, 0x28, 0xff, 0x04, 0x2f, 0x13, 0xff, 0x00, 0x21, 0x0d, 0xff, 0x08, 0x3c, 0x21, 0xff, 0x0e, 0x52, 0x2d, 0xff, 0x02, 0x3e, 0x1b, 0xff, 0x08, 0x45, 0x22, 0xff, 0x0e, 0x5b, 0x2c, 0xff, 0x0f, 0x54, 0x2e, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x05, 0x2b, 0x18, 0xff, 0x08, 0x2d, 0x18, 0xff, 0x01, 0x28, 0x12, 0xff, 0x04, 0x37, 0x20, 0xff, 0x02, 0x3d, 0x23, 0xff, 0x03, 0x3e, 0x21, 0xff, 0x08, 0x3d, 0x22, 0xff, 0x04, 0x3a, 0x1e, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x08, 0x3d, 0x1f, 0xff, 0x06, 0x3f, 0x1c, 0xff, 0x11, 0x66, 0x39, 0xff, 0x1e, 0x8b, 0x56, 0xff, 0x04, 0x68, 0x2c, 0xff, 0x03, 0x58, 0x25, 0xff, 0x0c, 0x54, 0x2b, 0xff, 0x0a, 0x50, 0x28, 0xff, 0x0d, 0x54, 0x2b, 0xff, 0x08, 0x4b, 0x23, 0xff, 0x04, 0x39, 0x1a, 0xff, 0x17, 0x47, 0x2e, 0xff, 0x0f, 0x3e, 0x27, 0xff, 0x08, 0x2f, 0x10, 0xff, 0x09, 0x31, 0x12, 0xff, 0x02, 0x2f, 0x14, 0xff, 0x0a, 0x4b, 0x26, 0xff, 0x17, 0x71, 0x47, 0xff, 0x02, 0x38, 0x14, 0xff, 0x08, 0x35, 0x19, 0xff, 0x08, 0x32, 0x21, 0xff, 0x18, 0x41, 0x36, 0xff, 0x0c, 0x38, 0x2d, 0xff, 0x10, 0x48, 0x2d, 0xff, 0x28, 0x58, 0x5d, 0xff, 0x30, 0x5e, 0x6b, 0xff, 0x1a, 0x5d, 0x4b, 0xff, 0x0f, 0x68, 0x44, 0xff, 0x16, 0x8b, 0x5a, 0xff, 0x14, 0x90, 0x58, 0xff, 0x11, 0x8c, 0x5d, 0xff, 0x10, 0x8a, 0x60, 0xff, 0x0d, 0x8c, 0x57, 0xff, 0x14, 0x99, 0x64, 0xff, 0x13, 0x9b, 0x69, 0xff, 0x0e, 0x9b, 0x65, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x10, 0x9b, 0x66, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x11, 0x9b, 0x65, 0xff, 0x0f, 0x9c, 0x66, 0xff, 0x0d, 0x9b, 0x66, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0f, 0xa3, 0x6c, 0xff, 0x0e, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0e, 0xa6, 0x6d, 0xff, 0x0f, 0xa6, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0e, 0xa3, 0x6e, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0e, 0x9d, 0x6b, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x0f, 0x9e, 0x69, 0xff, 0x0d, 0x9a, 0x68, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x11, 0x9a, 0x68, 0xff, 0x12, 0x9b, 0x65, 0xff, 0x11, 0x98, 0x63, 0xff, 0x0e, 0x98, 0x64, 0xff, 0x0d, 0x9b, 0x68, 0xff, 0x15, 0x99, 0x6b, 0xff, 0x20, 0x83, 0x5e, 0xff, 0x04, 0x46, 0x27, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x04, 0x31, 0x1a, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x00, 0x32, 0x18, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x0a, 0x5b, 0x35, 0xff, 0x20, 0x90, 0x62, 0xff, 0x17, 0x99, 0x68, 0xff, 0x0d, 0x99, 0x66, 0xff, 0x0c, 0x98, 0x65, 0xff, 0x10, 0x99, 0x66, 0xff, 0x11, 0x98, 0x66, 0xff, 0x0f, 0x97, 0x65, 0xff, 0x0e, 0x98, 0x65, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x10, 0x98, 0x65, 0xff, 0x12, 0x97, 0x66, 0xff, 0x11, 0x97, 0x66, 0xff, 0x0f, 0x97, 0x64, 0xff, 0x0f, 0x96, 0x64, 0xff, 0x0f, 0x95, 0x63, 0xff, 0x0d, 0x95, 0x62, 0xff, 0x0b, 0x95, 0x62, 0xff, 0x0b, 0x92, 0x60, 0xff, 0x0d, 0x91, 0x5e, 0xff, 0x0d, 0x91, 0x5f, 0xff, 0x0c, 0x93, 0x5f, 0xff, 0x0d, 0x92, 0x5f, 0xff, 0x10, 0x90, 0x5f, 0xff, 0x0f, 0x91, 0x5f, 0xff, 0x0d, 0x90, 0x5f, 0xff, 0x0e, 0x8f, 0x60, 0xff, 0x11, 0x8e, 0x60, 0xff, 0x12, 0x8f, 0x61, 0xff, 0x0e, 0x90, 0x60, 0xff, 0x0f, 0x8f, 0x5e, 0xff, 0x10, 0x8f, 0x5c, 0xff, 0x0c, 0x8f, 0x5c, 0xff, 0x0b, 0x91, 0x5d, 0xff, 0x0f, 0x8f, 0x5e, 0xff, 0x19, 0x8f, 0x62, 0xff, 0x1b, 0x86, 0x5d, 0xff, 0x19, 0x86, 0x5a, 0xff, 0x11, 0x75, 0x4b, 0xff, 0x09, 0x60, 0x37, 0xff, 0x03, 0x4b, 0x26, 0xff, 0x00, 0x43, 0x20, 0xff, 0x07, 0x49, 0x29, 0xff, 0x0a, 0x4c, 0x2c, 0xff, 0x0a, 0x4d, 0x2d, 0xff, 0x06, 0x4d, 0x28, 0xff, 0x06, 0x51, 0x2b, 0xff, 0x0c, 0x5a, 0x32, 0xff, 0x0a, 0x56, 0x2d, 0xff, 0x04, 0x4f, 0x23, 0xff, 0x16, 0x71, 0x3f, 0xff, 0x29, 0x9c, 0x63, 0xff, 0x1c, 0xa0, 0x63, 0xff, 0x11, 0x8d, 0x53, 0xff, 0x0f, 0x81, 0x48, 0xff, 0x0f, 0x77, 0x42, 0xff, 0x0e, 0x6f, 0x3f, 0xff, 0x0c, 0x6b, 0x3e, 0xff, 0x0c, 0x65, 0x3a, 0xff, 0x11, 0x5f, 0x38, 0xff, 0x0c, 0x4e, 0x2b, 0xff, 0x01, 0x42, 0x21, 0xff, 0x08, 0x46, 0x27, 0xff, 0x0e, 0x48, 0x2b, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x0f, 0x3f, 0x25, 0xff, 0x03, 0x2d, 0x15, 0xff, 0x04, 0x2f, 0x17, 0xff, 0x06, 0x32, 0x1a, 0xff, 0x00, 0x29, 0x10, 0xff, 0x07, 0x39, 0x1e, 0xff, 0x0d, 0x49, 0x2d, 0xff, 0x08, 0x42, 0x27, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x08, 0x42, 0x24, 0xff, 0x09, 0x4d, 0x2d, 0xff, 0x11, 0x4b, 0x2b, 0xff, 0x08, 0x34, 0x1d, 0xff, 0x02, 0x32, 0x1a, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x07, 0x50, 0x2c, 0xff, 0x01, 0x50, 0x29, 0xff, 0x03, 0x60, 0x34, 0xff, 0x08, 0x6d, 0x3b, 0xff, 0x0c, 0x72, 0x3b, 0xff, 0x07, 0x63, 0x34, 0xff, 0x0a, 0x6a, 0x3a, 0xff, 0x10, 0x79, 0x44, 0xff, 0x0d, 0x79, 0x42, 0xff, 0x0d, 0x70, 0x3e, 0xff, 0x0e, 0x65, 0x37, 0xff, 0x04, 0x50, 0x23, 0xff, 0x00, 0x47, 0x18, 0xff, 0x00, 0x4d, 0x1c, 0xff, 0x03, 0x51, 0x1f, 0xff, 0x04, 0x58, 0x23, 0xff, 0x00, 0x5a, 0x27, 0xff, 0x04, 0x55, 0x28, 0xff, 0x05, 0x3c, 0x19, 0xff, 0x00, 0x25, 0x0b, 0xff, 0x0c, 0x3e, 0x28, 0xff, 0x0b, 0x46, 0x2b, 0xff, 0x0a, 0x4a, 0x2c, 0xff, 0x05, 0x47, 0x29, 0xff, 0x04, 0x48, 0x29, 0xff, 0x06, 0x4a, 0x2b, 0xff, 0x07, 0x4b, 0x2c, 0xff, 0x08, 0x4b, 0x2c, 0xff, 0x06, 0x48, 0x2a, 0xff, 0x05, 0x39, 0x20, 0xff, 0x03, 0x31, 0x19, 0xff, 0x0e, 0x4a, 0x2d, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x0a, 0x52, 0x2d, 0xff, 0x0a, 0x52, 0x2c, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x50, 0x2f, 0xff, 0x08, 0x50, 0x2f, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x06, 0x52, 0x2a, 0xff, 0x07, 0x51, 0x2c, 0xff, 0x0f, 0x48, 0x2b, 0xff, 0x01, 0x27, 0x13, 0xff, 0x01, 0x2c, 0x15, 0xff, 0x11, 0x72, 0x4f, 0xff, 0x12, 0x91, 0x67, 0xff, 0x16, 0x95, 0x65, 0xff, 0x0e, 0x80, 0x4c, 0xff, 0x0b, 0x65, 0x34, 0xff, 0x04, 0x40, 0x1e, 0xff, 0x00, 0x24, 0x12, 0xff, 0x0a, 0x32, 0x23, 0xff, 0x0b, 0x38, 0x25, 0xff, 0x09, 0x46, 0x29, 0xff, 0x0e, 0x67, 0x3c, 0xff, 0x0c, 0x69, 0x3c, 0xff, 0x0a, 0x58, 0x2e, 0xff, 0x14, 0x5a, 0x34, 0xff, 0x04, 0x34, 0x17, 0xff, 0x03, 0x22, 0x0f, 0xff, 0x05, 0x20, 0x13, 0xff, 0x02, 0x28, 0x21, 0xff, 0x0b, 0x45, 0x3b, 0xff, 0x10, 0x5a, 0x42, 0xff, 0x0c, 0x58, 0x38, 0xff, 0x19, 0x5c, 0x3f, 0xff, 0x16, 0x4e, 0x3a, 0xff, 0x02, 0x25, 0x17, 0xff, 0x62, 0x6f, 0x66, 0xff, + 0x06, 0x33, 0x1b, 0xff, 0x0a, 0x44, 0x24, 0xff, 0x07, 0x45, 0x22, 0xff, 0x08, 0x46, 0x25, 0xff, 0x09, 0x47, 0x26, 0xff, 0x0b, 0x4b, 0x27, 0xff, 0x0e, 0x4b, 0x28, 0xff, 0x09, 0x3b, 0x1f, 0xff, 0x01, 0x27, 0x10, 0xff, 0x01, 0x24, 0x13, 0xff, 0x02, 0x2d, 0x16, 0xff, 0x0a, 0x47, 0x27, 0xff, 0x0b, 0x52, 0x2a, 0xff, 0x08, 0x56, 0x29, 0xff, 0x07, 0x58, 0x28, 0xff, 0x09, 0x55, 0x29, 0xff, 0x10, 0x4b, 0x2c, 0xff, 0x01, 0x27, 0x14, 0xff, 0x01, 0x27, 0x13, 0xff, 0x08, 0x42, 0x23, 0xff, 0x04, 0x46, 0x22, 0xff, 0x07, 0x48, 0x25, 0xff, 0x06, 0x48, 0x27, 0xff, 0x03, 0x48, 0x28, 0xff, 0x0e, 0x4d, 0x29, 0xff, 0x05, 0x30, 0x14, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x0c, 0x40, 0x24, 0xff, 0x0c, 0x4e, 0x29, 0xff, 0x02, 0x3b, 0x18, 0xff, 0x0e, 0x4e, 0x29, 0xff, 0x0d, 0x5b, 0x2b, 0xff, 0x0a, 0x49, 0x27, 0xff, 0x01, 0x28, 0x16, 0xff, 0x07, 0x2a, 0x1b, 0xff, 0x06, 0x2b, 0x16, 0xff, 0x02, 0x2f, 0x16, 0xff, 0x07, 0x3d, 0x25, 0xff, 0x02, 0x3d, 0x26, 0xff, 0x03, 0x40, 0x23, 0xff, 0x07, 0x3f, 0x20, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x0a, 0x46, 0x25, 0xff, 0x09, 0x4b, 0x25, 0xff, 0x18, 0x77, 0x48, 0xff, 0x09, 0x70, 0x3a, 0xff, 0x04, 0x5d, 0x25, 0xff, 0x08, 0x5f, 0x2f, 0xff, 0x0d, 0x5e, 0x34, 0xff, 0x0c, 0x5f, 0x30, 0xff, 0x0d, 0x66, 0x31, 0xff, 0x0a, 0x60, 0x2e, 0xff, 0x0b, 0x4d, 0x26, 0xff, 0x17, 0x4c, 0x2d, 0xff, 0x08, 0x42, 0x24, 0xff, 0x02, 0x33, 0x14, 0xff, 0x02, 0x30, 0x17, 0xff, 0x02, 0x2f, 0x1a, 0xff, 0x0e, 0x4a, 0x2d, 0xff, 0x07, 0x48, 0x2d, 0xff, 0x02, 0x31, 0x16, 0xff, 0x05, 0x33, 0x13, 0xff, 0x01, 0x32, 0x16, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x01, 0x2d, 0x1b, 0xff, 0x02, 0x39, 0x1d, 0xff, 0x05, 0x38, 0x26, 0xff, 0x07, 0x3f, 0x2a, 0xff, 0x06, 0x4c, 0x30, 0xff, 0x05, 0x5d, 0x38, 0xff, 0x0b, 0x85, 0x50, 0xff, 0x14, 0x98, 0x5d, 0xff, 0x0d, 0x91, 0x61, 0xff, 0x10, 0x95, 0x63, 0xff, 0x11, 0x96, 0x5d, 0xff, 0x13, 0x97, 0x69, 0xff, 0x10, 0x99, 0x6a, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0c, 0x9b, 0x67, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x10, 0x9c, 0x66, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x10, 0x9f, 0x69, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0e, 0xa8, 0x6f, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x11, 0xa1, 0x6d, 0xff, 0x10, 0xa1, 0x6d, 0xff, 0x10, 0xa0, 0x6c, 0xff, 0x10, 0xa0, 0x6c, 0xff, 0x10, 0xa0, 0x6c, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0e, 0x9f, 0x6c, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x0d, 0x9d, 0x6b, 0xff, 0x0b, 0x99, 0x6a, 0xff, 0x0d, 0x98, 0x68, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x13, 0x9a, 0x67, 0xff, 0x0f, 0x98, 0x66, 0xff, 0x0f, 0x98, 0x69, 0xff, 0x1c, 0x90, 0x66, 0xff, 0x0c, 0x53, 0x32, 0xff, 0x03, 0x33, 0x17, 0xff, 0x05, 0x31, 0x19, 0xff, 0x01, 0x31, 0x19, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x02, 0x42, 0x23, 0xff, 0x10, 0x6c, 0x45, 0xff, 0x1b, 0x8e, 0x62, 0xff, 0x15, 0x99, 0x67, 0xff, 0x11, 0x99, 0x66, 0xff, 0x11, 0x99, 0x66, 0xff, 0x11, 0x99, 0x66, 0xff, 0x12, 0x98, 0x64, 0xff, 0x12, 0x98, 0x64, 0xff, 0x0f, 0x98, 0x64, 0xff, 0x0f, 0x98, 0x64, 0xff, 0x12, 0x98, 0x65, 0xff, 0x13, 0x98, 0x66, 0xff, 0x13, 0x98, 0x66, 0xff, 0x10, 0x96, 0x64, 0xff, 0x0a, 0x91, 0x5f, 0xff, 0x10, 0x97, 0x65, 0xff, 0x10, 0x97, 0x65, 0xff, 0x11, 0x97, 0x65, 0xff, 0x10, 0x97, 0x65, 0xff, 0x0e, 0x96, 0x64, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0f, 0x94, 0x61, 0xff, 0x11, 0x93, 0x61, 0xff, 0x11, 0x92, 0x5f, 0xff, 0x10, 0x92, 0x5f, 0xff, 0x0e, 0x91, 0x5f, 0xff, 0x0a, 0x91, 0x5f, 0xff, 0x0a, 0x92, 0x5f, 0xff, 0x0c, 0x91, 0x60, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x14, 0x8f, 0x62, 0xff, 0x10, 0x8f, 0x62, 0xff, 0x0b, 0x91, 0x60, 0xff, 0x0b, 0x91, 0x5d, 0xff, 0x0e, 0x91, 0x5c, 0xff, 0x0c, 0x91, 0x5c, 0xff, 0x08, 0x8f, 0x5e, 0xff, 0x0c, 0x8f, 0x60, 0xff, 0x11, 0x8d, 0x61, 0xff, 0x0e, 0x8f, 0x5f, 0xff, 0x16, 0x8f, 0x61, 0xff, 0x1a, 0x89, 0x5d, 0xff, 0x18, 0x78, 0x50, 0xff, 0x0f, 0x66, 0x41, 0xff, 0x03, 0x4c, 0x29, 0xff, 0x02, 0x45, 0x24, 0xff, 0x04, 0x47, 0x26, 0xff, 0x08, 0x4a, 0x26, 0xff, 0x04, 0x4f, 0x26, 0xff, 0x03, 0x55, 0x27, 0xff, 0x0e, 0x79, 0x45, 0xff, 0x19, 0x9e, 0x62, 0xff, 0x1a, 0xa6, 0x66, 0xff, 0x14, 0x9b, 0x59, 0xff, 0x06, 0x8c, 0x4c, 0xff, 0x03, 0x87, 0x4a, 0xff, 0x07, 0x7d, 0x44, 0xff, 0x08, 0x6f, 0x3b, 0xff, 0x0d, 0x6b, 0x3a, 0xff, 0x0b, 0x69, 0x3a, 0xff, 0x0a, 0x65, 0x39, 0xff, 0x10, 0x63, 0x3a, 0xff, 0x11, 0x58, 0x34, 0xff, 0x0a, 0x4b, 0x2c, 0xff, 0x03, 0x41, 0x23, 0xff, 0x09, 0x43, 0x25, 0xff, 0x0a, 0x3d, 0x20, 0xff, 0x0c, 0x3c, 0x21, 0xff, 0x0e, 0x3c, 0x22, 0xff, 0x02, 0x2c, 0x13, 0xff, 0x06, 0x31, 0x1a, 0xff, 0x06, 0x2e, 0x16, 0xff, 0x04, 0x32, 0x18, 0xff, 0x0a, 0x47, 0x2b, 0xff, 0x0b, 0x47, 0x2b, 0xff, 0x04, 0x2f, 0x15, 0xff, 0x06, 0x3b, 0x1e, 0xff, 0x09, 0x4c, 0x2c, 0xff, 0x11, 0x4c, 0x2c, 0xff, 0x09, 0x33, 0x1d, 0xff, 0x03, 0x31, 0x19, 0xff, 0x0b, 0x44, 0x26, 0xff, 0x05, 0x51, 0x2a, 0xff, 0x02, 0x5f, 0x35, 0xff, 0x1f, 0x8c, 0x5b, 0xff, 0x29, 0x9d, 0x65, 0xff, 0x1e, 0x93, 0x57, 0xff, 0x0c, 0x72, 0x3d, 0xff, 0x13, 0x80, 0x48, 0xff, 0x21, 0x99, 0x5d, 0xff, 0x21, 0x9c, 0x5e, 0xff, 0x20, 0x93, 0x59, 0xff, 0x1d, 0x81, 0x4d, 0xff, 0x0e, 0x68, 0x36, 0xff, 0x02, 0x53, 0x21, 0xff, 0x00, 0x4f, 0x1d, 0xff, 0x01, 0x51, 0x20, 0xff, 0x03, 0x57, 0x23, 0xff, 0x01, 0x5a, 0x27, 0xff, 0x04, 0x53, 0x26, 0xff, 0x02, 0x33, 0x13, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x0d, 0x41, 0x2a, 0xff, 0x07, 0x43, 0x28, 0xff, 0x08, 0x48, 0x2a, 0xff, 0x04, 0x45, 0x27, 0xff, 0x02, 0x45, 0x26, 0xff, 0x04, 0x47, 0x28, 0xff, 0x06, 0x4a, 0x2b, 0xff, 0x08, 0x4b, 0x2c, 0xff, 0x06, 0x48, 0x29, 0xff, 0x03, 0x36, 0x1e, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x0e, 0x4c, 0x2e, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0b, 0x52, 0x2c, 0xff, 0x0b, 0x51, 0x2c, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x08, 0x51, 0x2f, 0xff, 0x07, 0x51, 0x30, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x06, 0x52, 0x2a, 0xff, 0x06, 0x4e, 0x2b, 0xff, 0x07, 0x3d, 0x22, 0xff, 0x01, 0x25, 0x12, 0xff, 0x08, 0x42, 0x29, 0xff, 0x16, 0x86, 0x5f, 0xff, 0x16, 0x9d, 0x72, 0xff, 0x10, 0x8c, 0x5b, 0xff, 0x0e, 0x77, 0x42, 0xff, 0x06, 0x5a, 0x2a, 0xff, 0x00, 0x36, 0x14, 0xff, 0x03, 0x26, 0x15, 0xff, 0x10, 0x39, 0x2c, 0xff, 0x06, 0x27, 0x17, 0xff, 0x03, 0x33, 0x19, 0xff, 0x0f, 0x63, 0x39, 0xff, 0x0f, 0x68, 0x3c, 0xff, 0x06, 0x52, 0x27, 0xff, 0x11, 0x57, 0x2f, 0xff, 0x03, 0x36, 0x16, 0xff, 0x04, 0x23, 0x0e, 0xff, 0x06, 0x22, 0x16, 0xff, 0x02, 0x2c, 0x1f, 0xff, 0x10, 0x4f, 0x3b, 0xff, 0x10, 0x5d, 0x3e, 0xff, 0x0b, 0x57, 0x33, 0xff, 0x18, 0x5a, 0x3d, 0xff, 0x14, 0x4a, 0x37, 0xff, 0x02, 0x22, 0x16, 0xff, 0x63, 0x71, 0x69, 0xff, + 0x06, 0x33, 0x1b, 0xff, 0x0b, 0x44, 0x24, 0xff, 0x08, 0x45, 0x23, 0xff, 0x08, 0x45, 0x25, 0xff, 0x0a, 0x47, 0x26, 0xff, 0x0c, 0x4a, 0x26, 0xff, 0x0d, 0x4a, 0x28, 0xff, 0x0b, 0x40, 0x22, 0xff, 0x02, 0x29, 0x11, 0xff, 0x02, 0x25, 0x12, 0xff, 0x02, 0x29, 0x16, 0xff, 0x0c, 0x44, 0x27, 0xff, 0x0d, 0x50, 0x2c, 0xff, 0x0a, 0x56, 0x2b, 0xff, 0x08, 0x57, 0x29, 0xff, 0x08, 0x55, 0x2b, 0xff, 0x0f, 0x50, 0x2d, 0xff, 0x02, 0x2c, 0x14, 0xff, 0x01, 0x28, 0x11, 0xff, 0x0a, 0x41, 0x24, 0xff, 0x03, 0x44, 0x24, 0xff, 0x08, 0x47, 0x25, 0xff, 0x09, 0x47, 0x28, 0xff, 0x07, 0x46, 0x2c, 0xff, 0x0e, 0x4a, 0x2d, 0xff, 0x04, 0x31, 0x16, 0xff, 0x00, 0x25, 0x0a, 0xff, 0x10, 0x43, 0x24, 0xff, 0x0d, 0x47, 0x24, 0xff, 0x04, 0x3d, 0x19, 0xff, 0x11, 0x54, 0x2d, 0xff, 0x0d, 0x56, 0x2a, 0xff, 0x04, 0x3c, 0x1e, 0xff, 0x03, 0x26, 0x17, 0xff, 0x09, 0x29, 0x1f, 0xff, 0x02, 0x27, 0x18, 0xff, 0x07, 0x34, 0x21, 0xff, 0x09, 0x3c, 0x29, 0xff, 0x06, 0x3b, 0x2a, 0xff, 0x04, 0x3f, 0x29, 0xff, 0x03, 0x41, 0x1d, 0xff, 0x01, 0x43, 0x1d, 0xff, 0x03, 0x47, 0x24, 0xff, 0x08, 0x4d, 0x29, 0xff, 0x0d, 0x55, 0x2e, 0xff, 0x0e, 0x63, 0x36, 0xff, 0x04, 0x5d, 0x28, 0xff, 0x08, 0x5f, 0x2a, 0xff, 0x07, 0x61, 0x2f, 0xff, 0x09, 0x61, 0x31, 0xff, 0x0a, 0x61, 0x2f, 0xff, 0x06, 0x63, 0x2d, 0xff, 0x06, 0x63, 0x2f, 0xff, 0x13, 0x5e, 0x31, 0xff, 0x14, 0x50, 0x2a, 0xff, 0x0a, 0x41, 0x25, 0xff, 0x01, 0x34, 0x18, 0xff, 0x00, 0x32, 0x19, 0xff, 0x02, 0x36, 0x1f, 0xff, 0x0a, 0x45, 0x29, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x03, 0x40, 0x1e, 0xff, 0x03, 0x46, 0x22, 0xff, 0x05, 0x4b, 0x2a, 0xff, 0x06, 0x4c, 0x2f, 0xff, 0x09, 0x54, 0x34, 0xff, 0x0b, 0x5a, 0x38, 0xff, 0x0c, 0x5f, 0x39, 0xff, 0x12, 0x6d, 0x48, 0xff, 0x13, 0x78, 0x4e, 0xff, 0x0e, 0x8d, 0x5a, 0xff, 0x12, 0x98, 0x61, 0xff, 0x0f, 0x95, 0x63, 0xff, 0x11, 0x99, 0x64, 0xff, 0x10, 0x99, 0x62, 0xff, 0x0f, 0x95, 0x66, 0xff, 0x0f, 0x99, 0x68, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0e, 0x9d, 0x67, 0xff, 0x0f, 0x9f, 0x69, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6d, 0xff, 0x0f, 0xa5, 0x6c, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6d, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0e, 0xa3, 0x70, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x10, 0x9f, 0x6c, 0xff, 0x11, 0x9f, 0x6c, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0d, 0x9f, 0x6a, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0a, 0x9b, 0x6a, 0xff, 0x0c, 0x9b, 0x69, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x0f, 0x9b, 0x69, 0xff, 0x12, 0x99, 0x6b, 0xff, 0x1f, 0x96, 0x6c, 0xff, 0x1b, 0x77, 0x53, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x05, 0x31, 0x16, 0xff, 0x01, 0x32, 0x16, 0xff, 0x00, 0x38, 0x19, 0xff, 0x03, 0x4e, 0x2b, 0xff, 0x0d, 0x71, 0x49, 0xff, 0x1c, 0x95, 0x66, 0xff, 0x15, 0x99, 0x68, 0xff, 0x10, 0x99, 0x66, 0xff, 0x13, 0x9a, 0x68, 0xff, 0x11, 0x99, 0x66, 0xff, 0x0e, 0x9b, 0x65, 0xff, 0x0a, 0x9d, 0x61, 0xff, 0x10, 0x9e, 0x61, 0xff, 0x10, 0x93, 0x59, 0xff, 0x0b, 0x8c, 0x53, 0xff, 0x10, 0x90, 0x5a, 0xff, 0x0f, 0x99, 0x62, 0xff, 0x12, 0x9a, 0x65, 0xff, 0x13, 0x92, 0x5f, 0xff, 0x0d, 0x8b, 0x59, 0xff, 0x13, 0x98, 0x67, 0xff, 0x0f, 0x97, 0x64, 0xff, 0x14, 0x97, 0x65, 0xff, 0x1a, 0x97, 0x67, 0xff, 0x16, 0x96, 0x67, 0xff, 0x0d, 0x97, 0x66, 0xff, 0x0c, 0x98, 0x65, 0xff, 0x0e, 0x96, 0x63, 0xff, 0x13, 0x94, 0x63, 0xff, 0x0f, 0x92, 0x61, 0xff, 0x0d, 0x91, 0x60, 0xff, 0x0a, 0x92, 0x5f, 0xff, 0x0a, 0x92, 0x5f, 0xff, 0x0a, 0x91, 0x5e, 0xff, 0x0c, 0x90, 0x5f, 0xff, 0x0f, 0x8e, 0x61, 0xff, 0x0f, 0x8d, 0x62, 0xff, 0x0d, 0x90, 0x62, 0xff, 0x0b, 0x90, 0x5e, 0xff, 0x0f, 0x93, 0x60, 0xff, 0x0a, 0x90, 0x5c, 0xff, 0x08, 0x90, 0x5e, 0xff, 0x0c, 0x90, 0x60, 0xff, 0x10, 0x8e, 0x60, 0xff, 0x0d, 0x90, 0x61, 0xff, 0x10, 0x8d, 0x5f, 0xff, 0x15, 0x8e, 0x60, 0xff, 0x19, 0x8d, 0x60, 0xff, 0x1a, 0x88, 0x5d, 0xff, 0x0b, 0x68, 0x41, 0xff, 0x03, 0x4e, 0x2a, 0xff, 0x03, 0x42, 0x21, 0xff, 0x06, 0x43, 0x1f, 0xff, 0x01, 0x4e, 0x1f, 0xff, 0x0a, 0x73, 0x3b, 0xff, 0x22, 0xaf, 0x6d, 0xff, 0x18, 0xb3, 0x6b, 0xff, 0x06, 0x98, 0x52, 0xff, 0x0a, 0x90, 0x4e, 0xff, 0x0e, 0x8a, 0x50, 0xff, 0x0b, 0x7e, 0x4a, 0xff, 0x08, 0x6c, 0x3c, 0xff, 0x05, 0x5a, 0x2d, 0xff, 0x08, 0x54, 0x2c, 0xff, 0x09, 0x53, 0x2b, 0xff, 0x0a, 0x55, 0x2e, 0xff, 0x0d, 0x56, 0x30, 0xff, 0x0d, 0x52, 0x2f, 0xff, 0x10, 0x4f, 0x30, 0xff, 0x08, 0x4a, 0x2a, 0xff, 0x03, 0x3f, 0x1f, 0xff, 0x0e, 0x3f, 0x22, 0xff, 0x0c, 0x39, 0x1d, 0xff, 0x14, 0x43, 0x29, 0xff, 0x05, 0x31, 0x1a, 0xff, 0x03, 0x2b, 0x15, 0xff, 0x0e, 0x31, 0x1c, 0xff, 0x03, 0x2e, 0x16, 0xff, 0x09, 0x44, 0x2a, 0xff, 0x07, 0x49, 0x2c, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x06, 0x33, 0x17, 0xff, 0x0f, 0x49, 0x2a, 0xff, 0x0b, 0x4c, 0x2d, 0xff, 0x0c, 0x32, 0x1e, 0xff, 0x02, 0x31, 0x17, 0xff, 0x07, 0x45, 0x23, 0xff, 0x02, 0x58, 0x2b, 0xff, 0x0a, 0x7e, 0x4a, 0xff, 0x37, 0xb0, 0x78, 0xff, 0x37, 0xb7, 0x79, 0xff, 0x32, 0xae, 0x6e, 0xff, 0x11, 0x77, 0x3e, 0xff, 0x16, 0x89, 0x4e, 0xff, 0x27, 0xa6, 0x6a, 0xff, 0x1c, 0x9b, 0x5f, 0xff, 0x1d, 0x97, 0x5b, 0xff, 0x20, 0x91, 0x59, 0xff, 0x11, 0x79, 0x43, 0xff, 0x07, 0x62, 0x2f, 0xff, 0x02, 0x54, 0x21, 0xff, 0x01, 0x51, 0x20, 0xff, 0x01, 0x58, 0x24, 0xff, 0x02, 0x5a, 0x26, 0xff, 0x0a, 0x51, 0x25, 0xff, 0x04, 0x2d, 0x14, 0xff, 0x01, 0x22, 0x10, 0xff, 0x0c, 0x42, 0x29, 0xff, 0x05, 0x43, 0x26, 0xff, 0x08, 0x47, 0x29, 0xff, 0x05, 0x44, 0x26, 0xff, 0x04, 0x45, 0x26, 0xff, 0x02, 0x46, 0x26, 0xff, 0x05, 0x48, 0x29, 0xff, 0x08, 0x4b, 0x2c, 0xff, 0x05, 0x47, 0x28, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x05, 0x35, 0x1b, 0xff, 0x0f, 0x4c, 0x2d, 0xff, 0x09, 0x50, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x08, 0x51, 0x2e, 0xff, 0x04, 0x52, 0x2e, 0xff, 0x0a, 0x52, 0x2e, 0xff, 0x0a, 0x51, 0x2b, 0xff, 0x0a, 0x4d, 0x2b, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x00, 0x29, 0x15, 0xff, 0x0d, 0x5b, 0x3e, 0xff, 0x14, 0x90, 0x64, 0xff, 0x1a, 0xa3, 0x76, 0xff, 0x0f, 0x84, 0x56, 0xff, 0x0f, 0x71, 0x40, 0xff, 0x06, 0x50, 0x24, 0xff, 0x00, 0x2e, 0x0f, 0xff, 0x05, 0x2b, 0x1c, 0xff, 0x13, 0x3a, 0x2e, 0xff, 0x05, 0x21, 0x11, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x11, 0x64, 0x37, 0xff, 0x0f, 0x68, 0x37, 0xff, 0x0b, 0x51, 0x29, 0xff, 0x10, 0x5b, 0x32, 0xff, 0x04, 0x3e, 0x1a, 0xff, 0x02, 0x23, 0x0b, 0xff, 0x04, 0x23, 0x15, 0xff, 0x05, 0x34, 0x25, 0xff, 0x12, 0x56, 0x3f, 0xff, 0x12, 0x5c, 0x3d, 0xff, 0x08, 0x52, 0x30, 0xff, 0x16, 0x5a, 0x3d, 0xff, 0x10, 0x47, 0x33, 0xff, 0x01, 0x20, 0x14, 0xff, 0x64, 0x6f, 0x6a, 0xff, + 0x07, 0x33, 0x1b, 0xff, 0x0b, 0x43, 0x25, 0xff, 0x07, 0x44, 0x23, 0xff, 0x0a, 0x46, 0x26, 0xff, 0x0b, 0x47, 0x27, 0xff, 0x0c, 0x49, 0x26, 0xff, 0x0b, 0x48, 0x26, 0xff, 0x0b, 0x41, 0x24, 0xff, 0x02, 0x2d, 0x14, 0xff, 0x03, 0x24, 0x12, 0xff, 0x01, 0x27, 0x14, 0xff, 0x09, 0x3f, 0x25, 0xff, 0x0c, 0x4d, 0x2c, 0xff, 0x0a, 0x55, 0x2a, 0xff, 0x09, 0x56, 0x2a, 0xff, 0x07, 0x54, 0x2a, 0xff, 0x0d, 0x51, 0x2c, 0xff, 0x02, 0x32, 0x15, 0xff, 0x01, 0x28, 0x10, 0xff, 0x0a, 0x3e, 0x25, 0xff, 0x01, 0x43, 0x24, 0xff, 0x06, 0x46, 0x26, 0xff, 0x0a, 0x46, 0x25, 0xff, 0x08, 0x46, 0x28, 0xff, 0x0c, 0x48, 0x2b, 0xff, 0x02, 0x32, 0x16, 0xff, 0x01, 0x25, 0x0a, 0xff, 0x14, 0x43, 0x27, 0xff, 0x08, 0x39, 0x1b, 0xff, 0x06, 0x42, 0x1f, 0xff, 0x0f, 0x54, 0x2d, 0xff, 0x0c, 0x4d, 0x25, 0xff, 0x02, 0x2f, 0x14, 0xff, 0x04, 0x26, 0x1d, 0xff, 0x04, 0x23, 0x22, 0xff, 0x09, 0x2f, 0x30, 0xff, 0x21, 0x4e, 0x50, 0xff, 0x18, 0x48, 0x49, 0xff, 0x0c, 0x3c, 0x40, 0xff, 0x09, 0x3f, 0x3a, 0xff, 0x09, 0x46, 0x26, 0xff, 0x0b, 0x44, 0x20, 0xff, 0x11, 0x49, 0x2b, 0xff, 0x11, 0x4d, 0x2e, 0xff, 0x0e, 0x52, 0x2f, 0xff, 0x09, 0x55, 0x2d, 0xff, 0x07, 0x5d, 0x2b, 0xff, 0x03, 0x61, 0x2d, 0xff, 0x0a, 0x61, 0x2e, 0xff, 0x0f, 0x62, 0x2e, 0xff, 0x0b, 0x63, 0x2d, 0xff, 0x06, 0x63, 0x2e, 0xff, 0x06, 0x62, 0x2e, 0xff, 0x10, 0x66, 0x33, 0xff, 0x0b, 0x5c, 0x2e, 0xff, 0x0e, 0x55, 0x35, 0xff, 0x14, 0x5d, 0x3e, 0xff, 0x10, 0x5c, 0x3c, 0xff, 0x0d, 0x5c, 0x3c, 0xff, 0x0f, 0x5f, 0x3f, 0xff, 0x13, 0x65, 0x43, 0xff, 0x20, 0x78, 0x54, 0xff, 0x19, 0x76, 0x4f, 0xff, 0x12, 0x75, 0x4a, 0xff, 0x13, 0x78, 0x4e, 0xff, 0x16, 0x7e, 0x53, 0xff, 0x1c, 0x87, 0x5d, 0xff, 0x1d, 0x8d, 0x62, 0xff, 0x15, 0x8a, 0x5d, 0xff, 0x15, 0x8c, 0x5f, 0xff, 0x14, 0x8f, 0x5e, 0xff, 0x0e, 0x93, 0x61, 0xff, 0x0f, 0x95, 0x63, 0xff, 0x0f, 0x96, 0x63, 0xff, 0x13, 0x9a, 0x67, 0xff, 0x10, 0x99, 0x65, 0xff, 0x0f, 0x99, 0x65, 0xff, 0x10, 0x9a, 0x65, 0xff, 0x10, 0x9c, 0x66, 0xff, 0x0e, 0x9d, 0x67, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0f, 0xa6, 0x6b, 0xff, 0x10, 0xa6, 0x6a, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0e, 0xa6, 0x6d, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa5, 0x70, 0xff, 0x08, 0xa5, 0x71, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa0, 0x6b, 0xff, 0x0f, 0xa0, 0x6a, 0xff, 0x11, 0x9f, 0x6c, 0xff, 0x10, 0x9f, 0x6c, 0xff, 0x0d, 0x9f, 0x6b, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0b, 0x9f, 0x6b, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x0d, 0x9b, 0x68, 0xff, 0x12, 0x9d, 0x6a, 0xff, 0x15, 0x9b, 0x6a, 0xff, 0x1e, 0x98, 0x6d, 0xff, 0x16, 0x71, 0x4c, 0xff, 0x03, 0x42, 0x21, 0xff, 0x01, 0x32, 0x15, 0xff, 0x02, 0x3a, 0x1b, 0xff, 0x04, 0x52, 0x2e, 0xff, 0x0c, 0x70, 0x47, 0xff, 0x18, 0x91, 0x64, 0xff, 0x17, 0x9a, 0x6a, 0xff, 0x0f, 0x9a, 0x65, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x0f, 0x99, 0x67, 0xff, 0x11, 0x98, 0x68, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0d, 0xaf, 0x6a, 0xff, 0x12, 0xaf, 0x67, 0xff, 0x07, 0x8a, 0x49, 0xff, 0x04, 0x79, 0x3d, 0xff, 0x0a, 0x78, 0x40, 0xff, 0x02, 0x7a, 0x42, 0xff, 0x10, 0x8d, 0x56, 0xff, 0x0b, 0x7d, 0x49, 0xff, 0x11, 0x8b, 0x57, 0xff, 0x0a, 0x8d, 0x58, 0xff, 0x03, 0x86, 0x4f, 0xff, 0x09, 0x85, 0x51, 0xff, 0x12, 0x81, 0x53, 0xff, 0x11, 0x81, 0x57, 0xff, 0x14, 0x8f, 0x64, 0xff, 0x18, 0x94, 0x67, 0xff, 0x1c, 0x92, 0x64, 0xff, 0x14, 0x8a, 0x5d, 0xff, 0x0d, 0x91, 0x62, 0xff, 0x09, 0x94, 0x64, 0xff, 0x08, 0x92, 0x61, 0xff, 0x0d, 0x91, 0x61, 0xff, 0x11, 0x91, 0x61, 0xff, 0x0e, 0x91, 0x60, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x16, 0x8f, 0x61, 0xff, 0x10, 0x91, 0x5f, 0xff, 0x0a, 0x91, 0x5d, 0xff, 0x0a, 0x91, 0x5b, 0xff, 0x0b, 0x91, 0x5b, 0xff, 0x0f, 0x92, 0x5c, 0xff, 0x0f, 0x91, 0x5d, 0xff, 0x0c, 0x90, 0x5d, 0xff, 0x0a, 0x90, 0x5f, 0xff, 0x12, 0x90, 0x60, 0xff, 0x15, 0x8f, 0x61, 0xff, 0x11, 0x8f, 0x60, 0xff, 0x0f, 0x91, 0x62, 0xff, 0x13, 0x8c, 0x60, 0xff, 0x17, 0x80, 0x56, 0xff, 0x0c, 0x65, 0x3c, 0xff, 0x02, 0x56, 0x29, 0xff, 0x12, 0x8a, 0x50, 0xff, 0x1f, 0xb6, 0x72, 0xff, 0x0d, 0xb1, 0x64, 0xff, 0x13, 0xab, 0x61, 0xff, 0x18, 0x94, 0x55, 0xff, 0x13, 0x7c, 0x45, 0xff, 0x07, 0x5d, 0x30, 0xff, 0x03, 0x45, 0x21, 0xff, 0x03, 0x3f, 0x1c, 0xff, 0x03, 0x3b, 0x19, 0xff, 0x01, 0x39, 0x18, 0xff, 0x03, 0x3a, 0x1a, 0xff, 0x03, 0x3b, 0x1c, 0xff, 0x03, 0x3b, 0x1d, 0xff, 0x03, 0x3a, 0x1c, 0xff, 0x03, 0x3c, 0x1f, 0xff, 0x09, 0x48, 0x29, 0xff, 0x0c, 0x4a, 0x2b, 0xff, 0x04, 0x3a, 0x1c, 0xff, 0x05, 0x35, 0x18, 0xff, 0x10, 0x40, 0x27, 0xff, 0x0f, 0x3e, 0x27, 0xff, 0x01, 0x27, 0x13, 0xff, 0x0a, 0x2b, 0x17, 0xff, 0x08, 0x2d, 0x17, 0xff, 0x06, 0x3b, 0x23, 0xff, 0x05, 0x4c, 0x2f, 0xff, 0x06, 0x44, 0x26, 0xff, 0x03, 0x2b, 0x10, 0xff, 0x10, 0x40, 0x23, 0xff, 0x06, 0x4e, 0x2d, 0xff, 0x08, 0x30, 0x1d, 0xff, 0x00, 0x32, 0x16, 0xff, 0x01, 0x48, 0x20, 0xff, 0x14, 0x7a, 0x46, 0xff, 0x24, 0xaa, 0x6d, 0xff, 0x1e, 0x9a, 0x5d, 0xff, 0x17, 0x96, 0x56, 0xff, 0x1d, 0x98, 0x56, 0xff, 0x0e, 0x77, 0x3a, 0xff, 0x17, 0x8a, 0x51, 0xff, 0x0e, 0x8a, 0x52, 0xff, 0x08, 0x7e, 0x47, 0xff, 0x0b, 0x7e, 0x45, 0xff, 0x0f, 0x84, 0x4a, 0xff, 0x0b, 0x7c, 0x45, 0xff, 0x0c, 0x6d, 0x3a, 0xff, 0x0f, 0x61, 0x30, 0xff, 0x01, 0x51, 0x23, 0xff, 0x00, 0x56, 0x24, 0xff, 0x02, 0x59, 0x23, 0xff, 0x09, 0x4a, 0x20, 0xff, 0x03, 0x26, 0x13, 0xff, 0x01, 0x20, 0x12, 0xff, 0x05, 0x3c, 0x20, 0xff, 0x03, 0x41, 0x23, 0xff, 0x07, 0x45, 0x27, 0xff, 0x05, 0x43, 0x25, 0xff, 0x05, 0x44, 0x26, 0xff, 0x04, 0x45, 0x27, 0xff, 0x05, 0x46, 0x28, 0xff, 0x07, 0x48, 0x2a, 0xff, 0x05, 0x46, 0x28, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x06, 0x37, 0x1b, 0xff, 0x10, 0x4e, 0x2f, 0xff, 0x0a, 0x52, 0x2e, 0xff, 0x07, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x03, 0x52, 0x2d, 0xff, 0x0a, 0x51, 0x2c, 0xff, 0x0d, 0x4f, 0x2b, 0xff, 0x0b, 0x47, 0x27, 0xff, 0x01, 0x2b, 0x14, 0xff, 0x03, 0x3a, 0x23, 0xff, 0x12, 0x75, 0x52, 0xff, 0x1c, 0xa1, 0x70, 0xff, 0x14, 0x9b, 0x6c, 0xff, 0x0d, 0x7b, 0x51, 0xff, 0x0e, 0x6a, 0x3c, 0xff, 0x06, 0x46, 0x1e, 0xff, 0x00, 0x27, 0x0c, 0xff, 0x0a, 0x34, 0x25, 0xff, 0x0d, 0x33, 0x27, 0xff, 0x04, 0x20, 0x10, 0xff, 0x02, 0x2a, 0x15, 0xff, 0x0e, 0x61, 0x37, 0xff, 0x0d, 0x66, 0x36, 0xff, 0x0b, 0x4d, 0x29, 0xff, 0x0a, 0x57, 0x30, 0xff, 0x0a, 0x4b, 0x27, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x21, 0x17, 0xff, 0x0b, 0x3e, 0x31, 0xff, 0x13, 0x5a, 0x43, 0xff, 0x11, 0x57, 0x3a, 0xff, 0x0a, 0x51, 0x32, 0xff, 0x17, 0x5c, 0x40, 0xff, 0x0b, 0x41, 0x2e, 0xff, 0x00, 0x1e, 0x11, 0xff, 0x66, 0x70, 0x69, 0xff, + 0x06, 0x32, 0x1a, 0xff, 0x0b, 0x43, 0x24, 0xff, 0x07, 0x44, 0x23, 0xff, 0x09, 0x45, 0x26, 0xff, 0x0b, 0x47, 0x27, 0xff, 0x0a, 0x48, 0x25, 0xff, 0x09, 0x46, 0x25, 0xff, 0x0b, 0x41, 0x23, 0xff, 0x05, 0x30, 0x17, 0xff, 0x02, 0x25, 0x10, 0xff, 0x01, 0x26, 0x13, 0xff, 0x06, 0x3b, 0x21, 0xff, 0x0a, 0x4a, 0x29, 0xff, 0x09, 0x53, 0x29, 0xff, 0x09, 0x56, 0x2a, 0xff, 0x07, 0x54, 0x2a, 0xff, 0x0d, 0x52, 0x2e, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x01, 0x29, 0x10, 0xff, 0x09, 0x3f, 0x24, 0xff, 0x02, 0x43, 0x25, 0xff, 0x07, 0x45, 0x26, 0xff, 0x09, 0x47, 0x24, 0xff, 0x06, 0x4a, 0x25, 0xff, 0x0a, 0x49, 0x28, 0xff, 0x03, 0x36, 0x1c, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x12, 0x41, 0x29, 0xff, 0x04, 0x31, 0x16, 0xff, 0x08, 0x47, 0x26, 0xff, 0x0f, 0x53, 0x2d, 0xff, 0x06, 0x40, 0x1c, 0xff, 0x00, 0x27, 0x12, 0xff, 0x08, 0x2a, 0x2a, 0xff, 0x1a, 0x3d, 0x48, 0xff, 0x37, 0x62, 0x73, 0xff, 0x44, 0x74, 0x8a, 0xff, 0x39, 0x69, 0x82, 0xff, 0x34, 0x64, 0x7d, 0xff, 0x29, 0x5b, 0x64, 0xff, 0x09, 0x3c, 0x29, 0xff, 0x0a, 0x36, 0x1c, 0xff, 0x0e, 0x37, 0x20, 0xff, 0x0e, 0x3d, 0x21, 0xff, 0x0b, 0x43, 0x25, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x06, 0x5c, 0x2e, 0xff, 0x04, 0x61, 0x30, 0xff, 0x0b, 0x5f, 0x2e, 0xff, 0x10, 0x62, 0x2e, 0xff, 0x0a, 0x63, 0x2d, 0xff, 0x07, 0x65, 0x2d, 0xff, 0x08, 0x64, 0x2d, 0xff, 0x0c, 0x69, 0x33, 0xff, 0x06, 0x66, 0x33, 0xff, 0x0b, 0x69, 0x3d, 0xff, 0x1c, 0x7e, 0x54, 0xff, 0x1e, 0x82, 0x5a, 0xff, 0x18, 0x7e, 0x58, 0xff, 0x1a, 0x7f, 0x5a, 0xff, 0x17, 0x7d, 0x59, 0xff, 0x1f, 0x8b, 0x63, 0xff, 0x16, 0x86, 0x5d, 0xff, 0x0d, 0x7f, 0x51, 0xff, 0x10, 0x83, 0x56, 0xff, 0x14, 0x89, 0x5c, 0xff, 0x19, 0x91, 0x65, 0xff, 0x17, 0x94, 0x67, 0xff, 0x0f, 0x90, 0x61, 0xff, 0x0d, 0x92, 0x62, 0xff, 0x0e, 0x93, 0x61, 0xff, 0x10, 0x97, 0x64, 0xff, 0x11, 0x98, 0x66, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x14, 0x9d, 0x69, 0xff, 0x11, 0x9c, 0x67, 0xff, 0x10, 0x9c, 0x67, 0xff, 0x10, 0x9d, 0x66, 0xff, 0x10, 0x9e, 0x67, 0xff, 0x0e, 0x9f, 0x68, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x0e, 0xa0, 0x69, 0xff, 0x0e, 0xa1, 0x6a, 0xff, 0x0f, 0xa1, 0x6a, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x08, 0xa5, 0x6d, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x07, 0xa4, 0x6e, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa0, 0x6b, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x0c, 0xa0, 0x6b, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0d, 0x9f, 0x6a, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x13, 0x9c, 0x6a, 0xff, 0x14, 0x9a, 0x68, 0xff, 0x17, 0x8d, 0x5e, 0xff, 0x12, 0x75, 0x4b, 0xff, 0x04, 0x4c, 0x25, 0xff, 0x00, 0x41, 0x1d, 0xff, 0x04, 0x4e, 0x2b, 0xff, 0x0e, 0x66, 0x42, 0xff, 0x16, 0x86, 0x5c, 0xff, 0x16, 0x96, 0x68, 0xff, 0x13, 0x9a, 0x69, 0xff, 0x15, 0x9b, 0x69, 0xff, 0x0d, 0x9b, 0x65, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0e, 0x99, 0x67, 0xff, 0x0f, 0x99, 0x67, 0xff, 0x0e, 0x9d, 0x65, 0xff, 0x0a, 0x9f, 0x62, 0xff, 0x17, 0xb7, 0x71, 0xff, 0x13, 0xb0, 0x66, 0xff, 0x06, 0x8d, 0x49, 0xff, 0x06, 0x7c, 0x3e, 0xff, 0x0d, 0x74, 0x3a, 0xff, 0x06, 0x6d, 0x36, 0xff, 0x06, 0x75, 0x3d, 0xff, 0x02, 0x72, 0x38, 0xff, 0x0b, 0x8d, 0x53, 0xff, 0x05, 0x8a, 0x4e, 0xff, 0x01, 0x7f, 0x44, 0xff, 0x06, 0x7c, 0x46, 0xff, 0x08, 0x71, 0x42, 0xff, 0x03, 0x65, 0x3d, 0xff, 0x08, 0x67, 0x42, 0xff, 0x15, 0x73, 0x4d, 0xff, 0x13, 0x6e, 0x45, 0xff, 0x07, 0x6d, 0x41, 0xff, 0x11, 0x91, 0x61, 0xff, 0x09, 0x95, 0x63, 0xff, 0x09, 0x94, 0x62, 0xff, 0x0f, 0x92, 0x62, 0xff, 0x14, 0x92, 0x62, 0xff, 0x0f, 0x92, 0x62, 0xff, 0x10, 0x93, 0x61, 0xff, 0x14, 0x92, 0x5d, 0xff, 0x09, 0x95, 0x5c, 0xff, 0x09, 0x9c, 0x60, 0xff, 0x12, 0xa3, 0x65, 0xff, 0x0e, 0x98, 0x5b, 0xff, 0x12, 0x99, 0x5d, 0xff, 0x0e, 0x9a, 0x5e, 0xff, 0x0b, 0x9b, 0x61, 0xff, 0x09, 0x95, 0x5d, 0xff, 0x11, 0x92, 0x5f, 0xff, 0x15, 0x91, 0x60, 0xff, 0x13, 0x8f, 0x61, 0xff, 0x0e, 0x90, 0x61, 0xff, 0x0f, 0x90, 0x62, 0xff, 0x12, 0x8d, 0x60, 0xff, 0x0f, 0x88, 0x57, 0xff, 0x0d, 0x92, 0x56, 0xff, 0x1f, 0xb5, 0x72, 0xff, 0x19, 0xb7, 0x70, 0xff, 0x17, 0xb0, 0x69, 0xff, 0x11, 0x94, 0x52, 0xff, 0x0a, 0x69, 0x32, 0xff, 0x06, 0x52, 0x25, 0xff, 0x01, 0x37, 0x12, 0xff, 0x01, 0x2d, 0x10, 0xff, 0x0a, 0x3b, 0x1e, 0xff, 0x09, 0x3d, 0x1f, 0xff, 0x06, 0x3c, 0x1f, 0xff, 0x05, 0x3d, 0x20, 0xff, 0x06, 0x3c, 0x20, 0xff, 0x07, 0x3a, 0x1e, 0xff, 0x08, 0x3a, 0x1e, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x0b, 0x43, 0x26, 0xff, 0x08, 0x44, 0x27, 0xff, 0x01, 0x35, 0x1a, 0xff, 0x07, 0x36, 0x1d, 0xff, 0x15, 0x44, 0x2d, 0xff, 0x05, 0x31, 0x1a, 0xff, 0x02, 0x28, 0x11, 0xff, 0x08, 0x2b, 0x16, 0xff, 0x03, 0x31, 0x1a, 0xff, 0x08, 0x4d, 0x30, 0xff, 0x0d, 0x4c, 0x2f, 0xff, 0x03, 0x2b, 0x0f, 0xff, 0x0d, 0x3a, 0x1e, 0xff, 0x07, 0x4d, 0x2d, 0xff, 0x05, 0x30, 0x1d, 0xff, 0x00, 0x34, 0x16, 0xff, 0x07, 0x5c, 0x31, 0xff, 0x2b, 0x9a, 0x63, 0xff, 0x1b, 0x9b, 0x5e, 0xff, 0x07, 0x7b, 0x40, 0xff, 0x07, 0x7c, 0x40, 0xff, 0x08, 0x78, 0x3b, 0xff, 0x08, 0x72, 0x38, 0xff, 0x11, 0x82, 0x49, 0xff, 0x0b, 0x7c, 0x45, 0xff, 0x0e, 0x76, 0x42, 0xff, 0x0d, 0x73, 0x3e, 0xff, 0x0b, 0x78, 0x41, 0xff, 0x0d, 0x79, 0x44, 0xff, 0x12, 0x70, 0x40, 0xff, 0x17, 0x64, 0x37, 0xff, 0x06, 0x50, 0x26, 0xff, 0x02, 0x55, 0x25, 0xff, 0x04, 0x5b, 0x25, 0xff, 0x06, 0x4a, 0x1e, 0xff, 0x01, 0x27, 0x11, 0xff, 0x02, 0x23, 0x13, 0xff, 0x02, 0x38, 0x1c, 0xff, 0x02, 0x3f, 0x21, 0xff, 0x05, 0x43, 0x25, 0xff, 0x04, 0x42, 0x24, 0xff, 0x04, 0x43, 0x25, 0xff, 0x06, 0x45, 0x27, 0xff, 0x05, 0x44, 0x26, 0xff, 0x06, 0x44, 0x26, 0xff, 0x06, 0x44, 0x26, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x07, 0x3a, 0x1e, 0xff, 0x11, 0x50, 0x30, 0xff, 0x09, 0x52, 0x2f, 0xff, 0x07, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x05, 0x52, 0x2d, 0xff, 0x09, 0x50, 0x2b, 0xff, 0x0c, 0x4f, 0x2b, 0xff, 0x08, 0x41, 0x22, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x07, 0x49, 0x2f, 0xff, 0x17, 0x82, 0x5e, 0xff, 0x1f, 0xa5, 0x74, 0xff, 0x0b, 0x8f, 0x5f, 0xff, 0x0c, 0x76, 0x4a, 0xff, 0x0b, 0x62, 0x36, 0xff, 0x04, 0x3f, 0x19, 0xff, 0x01, 0x25, 0x0c, 0xff, 0x0f, 0x39, 0x2a, 0xff, 0x0a, 0x2e, 0x21, 0xff, 0x04, 0x22, 0x12, 0xff, 0x02, 0x2c, 0x14, 0xff, 0x0f, 0x61, 0x3a, 0xff, 0x07, 0x5c, 0x33, 0xff, 0x04, 0x46, 0x27, 0xff, 0x06, 0x55, 0x31, 0xff, 0x12, 0x55, 0x34, 0xff, 0x02, 0x29, 0x17, 0xff, 0x02, 0x25, 0x1d, 0xff, 0x13, 0x49, 0x3b, 0xff, 0x12, 0x58, 0x41, 0xff, 0x0a, 0x50, 0x34, 0xff, 0x0a, 0x51, 0x31, 0xff, 0x18, 0x5c, 0x40, 0xff, 0x08, 0x3c, 0x27, 0xff, 0x01, 0x1d, 0x10, 0xff, 0x66, 0x72, 0x6a, 0xff, + 0x04, 0x30, 0x19, 0xff, 0x0b, 0x43, 0x24, 0xff, 0x08, 0x44, 0x23, 0xff, 0x09, 0x44, 0x25, 0xff, 0x0a, 0x45, 0x25, 0xff, 0x08, 0x45, 0x22, 0xff, 0x08, 0x45, 0x23, 0xff, 0x0a, 0x41, 0x23, 0xff, 0x08, 0x35, 0x1b, 0xff, 0x01, 0x25, 0x10, 0xff, 0x01, 0x25, 0x11, 0xff, 0x04, 0x37, 0x1d, 0xff, 0x09, 0x47, 0x26, 0xff, 0x08, 0x4f, 0x27, 0xff, 0x09, 0x55, 0x2a, 0xff, 0x09, 0x55, 0x2b, 0xff, 0x0d, 0x53, 0x2e, 0xff, 0x06, 0x3a, 0x1d, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x0a, 0x40, 0x24, 0xff, 0x04, 0x44, 0x26, 0xff, 0x06, 0x45, 0x25, 0xff, 0x08, 0x47, 0x24, 0xff, 0x04, 0x4c, 0x24, 0xff, 0x07, 0x48, 0x26, 0xff, 0x07, 0x3c, 0x23, 0xff, 0x03, 0x31, 0x1d, 0xff, 0x0a, 0x38, 0x22, 0xff, 0x00, 0x2d, 0x12, 0xff, 0x0b, 0x4c, 0x2b, 0xff, 0x0c, 0x51, 0x2f, 0xff, 0x01, 0x2e, 0x1c, 0xff, 0x07, 0x2c, 0x27, 0xff, 0x37, 0x5e, 0x6e, 0xff, 0x53, 0x7b, 0x96, 0xff, 0x5d, 0x8c, 0xaf, 0xff, 0x5a, 0x8d, 0xb5, 0xff, 0x51, 0x84, 0xb1, 0xff, 0x4b, 0x7b, 0xaa, 0xff, 0x45, 0x75, 0x8f, 0xff, 0x05, 0x2c, 0x25, 0xff, 0x01, 0x25, 0x12, 0xff, 0x01, 0x24, 0x12, 0xff, 0x01, 0x28, 0x0e, 0xff, 0x01, 0x28, 0x0e, 0xff, 0x02, 0x3a, 0x1c, 0xff, 0x0c, 0x56, 0x2f, 0xff, 0x10, 0x64, 0x37, 0xff, 0x09, 0x61, 0x31, 0xff, 0x07, 0x62, 0x2d, 0xff, 0x08, 0x63, 0x2b, 0xff, 0x0a, 0x66, 0x2d, 0xff, 0x08, 0x69, 0x2f, 0xff, 0x05, 0x6c, 0x33, 0xff, 0x04, 0x6d, 0x34, 0xff, 0x05, 0x74, 0x3b, 0xff, 0x08, 0x7a, 0x44, 0xff, 0x12, 0x85, 0x55, 0xff, 0x16, 0x88, 0x5e, 0xff, 0x19, 0x8a, 0x63, 0xff, 0x15, 0x86, 0x60, 0xff, 0x14, 0x89, 0x62, 0xff, 0x0f, 0x89, 0x5e, 0xff, 0x0c, 0x8b, 0x5b, 0xff, 0x10, 0x90, 0x5f, 0xff, 0x10, 0x92, 0x63, 0xff, 0x0f, 0x93, 0x64, 0xff, 0x0f, 0x98, 0x68, 0xff, 0x0c, 0x96, 0x66, 0xff, 0x09, 0x96, 0x63, 0xff, 0x0b, 0x98, 0x65, 0xff, 0x11, 0x9b, 0x67, 0xff, 0x13, 0x9c, 0x68, 0xff, 0x12, 0x9e, 0x69, 0xff, 0x12, 0x9e, 0x69, 0xff, 0x0f, 0x9d, 0x68, 0xff, 0x0f, 0x9e, 0x67, 0xff, 0x10, 0xa0, 0x68, 0xff, 0x10, 0xa1, 0x6a, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x10, 0xa1, 0x6a, 0xff, 0x10, 0xa1, 0x6a, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0e, 0xa1, 0x6a, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0a, 0xa0, 0x64, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x09, 0xa2, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x05, 0xa2, 0x67, 0xff, 0x06, 0xa4, 0x6b, 0xff, 0x07, 0xa6, 0x72, 0xff, 0x07, 0xa6, 0x75, 0xff, 0x07, 0xa1, 0x70, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x07, 0xa2, 0x6d, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x71, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x13, 0x9e, 0x6a, 0xff, 0x11, 0x96, 0x63, 0xff, 0x07, 0x81, 0x4e, 0xff, 0x03, 0x60, 0x32, 0xff, 0x03, 0x55, 0x2b, 0xff, 0x0e, 0x6c, 0x41, 0xff, 0x0d, 0x7e, 0x52, 0xff, 0x13, 0x91, 0x64, 0xff, 0x18, 0x9b, 0x6e, 0xff, 0x17, 0x9c, 0x6d, 0xff, 0x16, 0x9c, 0x6c, 0xff, 0x13, 0x9a, 0x69, 0xff, 0x13, 0x9e, 0x69, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0b, 0x9d, 0x66, 0xff, 0x0d, 0x9e, 0x69, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x0a, 0x9c, 0x63, 0xff, 0x09, 0xa0, 0x60, 0xff, 0x20, 0xb8, 0x70, 0xff, 0x0a, 0x99, 0x4f, 0xff, 0x01, 0x82, 0x3a, 0xff, 0x02, 0x7d, 0x3a, 0xff, 0x06, 0x73, 0x35, 0xff, 0x05, 0x6b, 0x30, 0xff, 0x04, 0x70, 0x34, 0xff, 0x07, 0x88, 0x47, 0xff, 0x17, 0xa7, 0x64, 0xff, 0x0f, 0x9a, 0x54, 0xff, 0x08, 0x84, 0x43, 0xff, 0x0a, 0x7b, 0x40, 0xff, 0x0b, 0x6f, 0x3f, 0xff, 0x09, 0x61, 0x3a, 0xff, 0x01, 0x44, 0x24, 0xff, 0x01, 0x42, 0x22, 0xff, 0x01, 0x49, 0x22, 0xff, 0x0d, 0x79, 0x49, 0xff, 0x18, 0x94, 0x61, 0xff, 0x12, 0x95, 0x61, 0xff, 0x0e, 0x95, 0x61, 0xff, 0x0d, 0x94, 0x60, 0xff, 0x0f, 0x95, 0x61, 0xff, 0x0d, 0x94, 0x61, 0xff, 0x0b, 0x95, 0x5e, 0xff, 0x0a, 0x9a, 0x59, 0xff, 0x0c, 0xa9, 0x65, 0xff, 0x0f, 0xb4, 0x6e, 0xff, 0x08, 0xa8, 0x62, 0xff, 0x05, 0x9d, 0x58, 0xff, 0x1b, 0xb4, 0x6f, 0xff, 0x17, 0xb5, 0x70, 0xff, 0x15, 0xb1, 0x6e, 0xff, 0x17, 0x9f, 0x63, 0xff, 0x0f, 0x95, 0x5d, 0xff, 0x0e, 0x91, 0x5f, 0xff, 0x12, 0x8e, 0x61, 0xff, 0x18, 0x8f, 0x64, 0xff, 0x09, 0x82, 0x54, 0xff, 0x0b, 0x8f, 0x5d, 0xff, 0x08, 0x9e, 0x61, 0xff, 0x1c, 0xc7, 0x7e, 0xff, 0x19, 0xbc, 0x72, 0xff, 0x1d, 0xb1, 0x6c, 0xff, 0x0a, 0x7f, 0x41, 0xff, 0x05, 0x68, 0x30, 0xff, 0x06, 0x54, 0x26, 0xff, 0x01, 0x45, 0x1e, 0xff, 0x01, 0x3a, 0x1a, 0xff, 0x00, 0x2a, 0x0d, 0xff, 0x06, 0x34, 0x18, 0xff, 0x09, 0x3b, 0x1f, 0xff, 0x08, 0x3b, 0x21, 0xff, 0x06, 0x3c, 0x21, 0xff, 0x04, 0x3c, 0x21, 0xff, 0x02, 0x3a, 0x1f, 0xff, 0x05, 0x3c, 0x20, 0xff, 0x0c, 0x3b, 0x20, 0xff, 0x0b, 0x33, 0x1a, 0xff, 0x03, 0x2d, 0x15, 0xff, 0x0a, 0x45, 0x2a, 0xff, 0x08, 0x43, 0x2a, 0xff, 0x01, 0x2e, 0x15, 0xff, 0x0c, 0x41, 0x26, 0xff, 0x09, 0x46, 0x2b, 0xff, 0x00, 0x2d, 0x15, 0xff, 0x07, 0x28, 0x13, 0xff, 0x05, 0x2a, 0x15, 0xff, 0x0a, 0x48, 0x2c, 0xff, 0x15, 0x54, 0x37, 0xff, 0x06, 0x2e, 0x14, 0xff, 0x05, 0x30, 0x15, 0xff, 0x09, 0x4b, 0x2d, 0xff, 0x02, 0x30, 0x1d, 0xff, 0x03, 0x3e, 0x1f, 0xff, 0x1b, 0x86, 0x54, 0xff, 0x2b, 0xa4, 0x68, 0xff, 0x07, 0x7f, 0x3f, 0xff, 0x09, 0x73, 0x3a, 0xff, 0x0a, 0x72, 0x3b, 0xff, 0x01, 0x64, 0x2e, 0xff, 0x07, 0x74, 0x3c, 0xff, 0x0e, 0x7b, 0x45, 0xff, 0x11, 0x74, 0x41, 0xff, 0x13, 0x6b, 0x3a, 0xff, 0x0e, 0x68, 0x36, 0xff, 0x09, 0x6e, 0x3a, 0xff, 0x0d, 0x72, 0x41, 0xff, 0x17, 0x6d, 0x43, 0xff, 0x0e, 0x50, 0x2c, 0xff, 0x09, 0x4b, 0x27, 0xff, 0x06, 0x54, 0x28, 0xff, 0x03, 0x59, 0x22, 0xff, 0x02, 0x4b, 0x1c, 0xff, 0x00, 0x29, 0x10, 0xff, 0x01, 0x23, 0x12, 0xff, 0x03, 0x37, 0x1c, 0xff, 0x03, 0x3f, 0x21, 0xff, 0x04, 0x42, 0x24, 0xff, 0x04, 0x42, 0x24, 0xff, 0x05, 0x42, 0x24, 0xff, 0x07, 0x44, 0x25, 0xff, 0x06, 0x42, 0x24, 0xff, 0x04, 0x41, 0x23, 0xff, 0x06, 0x42, 0x24, 0xff, 0x02, 0x34, 0x19, 0xff, 0x09, 0x3f, 0x23, 0xff, 0x10, 0x51, 0x32, 0xff, 0x07, 0x52, 0x2e, 0xff, 0x07, 0x52, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x09, 0x50, 0x2b, 0xff, 0x0c, 0x4f, 0x2b, 0xff, 0x05, 0x3a, 0x1c, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x0c, 0x5b, 0x3e, 0xff, 0x1b, 0x90, 0x69, 0xff, 0x1b, 0xa2, 0x72, 0xff, 0x08, 0x87, 0x57, 0xff, 0x0f, 0x73, 0x46, 0xff, 0x0a, 0x5a, 0x2f, 0xff, 0x01, 0x37, 0x13, 0xff, 0x01, 0x26, 0x0e, 0xff, 0x13, 0x39, 0x2b, 0xff, 0x06, 0x28, 0x1b, 0xff, 0x02, 0x22, 0x11, 0xff, 0x05, 0x38, 0x18, 0xff, 0x0f, 0x66, 0x3a, 0xff, 0x08, 0x5c, 0x34, 0xff, 0x0a, 0x51, 0x35, 0xff, 0x07, 0x57, 0x35, 0xff, 0x14, 0x5e, 0x3d, 0xff, 0x02, 0x30, 0x1c, 0xff, 0x05, 0x31, 0x1f, 0xff, 0x19, 0x55, 0x3f, 0xff, 0x10, 0x54, 0x3c, 0xff, 0x06, 0x4c, 0x2f, 0xff, 0x0a, 0x50, 0x31, 0xff, 0x18, 0x5c, 0x40, 0xff, 0x06, 0x34, 0x1f, 0xff, 0x01, 0x1d, 0x0f, 0xff, 0x66, 0x70, 0x69, 0xff, + 0x04, 0x2f, 0x18, 0xff, 0x0b, 0x42, 0x24, 0xff, 0x08, 0x44, 0x24, 0xff, 0x09, 0x44, 0x25, 0xff, 0x09, 0x44, 0x25, 0xff, 0x08, 0x44, 0x22, 0xff, 0x08, 0x45, 0x23, 0xff, 0x0b, 0x42, 0x24, 0xff, 0x0b, 0x3a, 0x20, 0xff, 0x01, 0x27, 0x12, 0xff, 0x00, 0x24, 0x10, 0xff, 0x04, 0x34, 0x1c, 0xff, 0x09, 0x43, 0x26, 0xff, 0x06, 0x4b, 0x25, 0xff, 0x09, 0x51, 0x28, 0xff, 0x0a, 0x55, 0x2b, 0xff, 0x0b, 0x53, 0x2e, 0xff, 0x05, 0x3c, 0x1e, 0xff, 0x02, 0x2d, 0x11, 0xff, 0x0b, 0x40, 0x25, 0xff, 0x04, 0x43, 0x26, 0xff, 0x05, 0x43, 0x24, 0xff, 0x05, 0x44, 0x24, 0xff, 0x02, 0x47, 0x27, 0xff, 0x05, 0x45, 0x27, 0xff, 0x0a, 0x3f, 0x26, 0xff, 0x05, 0x33, 0x1c, 0xff, 0x07, 0x33, 0x1d, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x0a, 0x4d, 0x2c, 0xff, 0x08, 0x49, 0x33, 0xff, 0x1c, 0x49, 0x51, 0xff, 0x51, 0x7d, 0x92, 0xff, 0x70, 0x9c, 0xbf, 0xff, 0x69, 0x98, 0xc2, 0xff, 0x63, 0x97, 0xc5, 0xff, 0x67, 0x9e, 0xcf, 0xff, 0x47, 0x7d, 0xb2, 0xff, 0x55, 0x88, 0xbd, 0xff, 0x55, 0x8a, 0xa8, 0xff, 0x07, 0x3d, 0x38, 0xff, 0x0a, 0x49, 0x32, 0xff, 0x0d, 0x49, 0x32, 0xff, 0x0a, 0x45, 0x29, 0xff, 0x08, 0x3e, 0x24, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x02, 0x33, 0x14, 0xff, 0x15, 0x56, 0x30, 0xff, 0x11, 0x6b, 0x3c, 0xff, 0x03, 0x66, 0x2f, 0xff, 0x05, 0x69, 0x2d, 0xff, 0x0b, 0x6a, 0x2e, 0xff, 0x08, 0x6e, 0x30, 0xff, 0x04, 0x6d, 0x30, 0xff, 0x05, 0x72, 0x34, 0xff, 0x0c, 0x80, 0x3b, 0xff, 0x0a, 0x80, 0x3f, 0xff, 0x0c, 0x83, 0x4b, 0xff, 0x11, 0x84, 0x55, 0xff, 0x14, 0x84, 0x5b, 0xff, 0x18, 0x89, 0x61, 0xff, 0x15, 0x88, 0x60, 0xff, 0x12, 0x89, 0x5e, 0xff, 0x0e, 0x8f, 0x5d, 0xff, 0x11, 0x93, 0x62, 0xff, 0x11, 0x95, 0x64, 0xff, 0x10, 0x95, 0x66, 0xff, 0x0f, 0x98, 0x68, 0xff, 0x0f, 0x98, 0x66, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0f, 0x9b, 0x67, 0xff, 0x0f, 0x9b, 0x67, 0xff, 0x10, 0x9c, 0x68, 0xff, 0x0f, 0x9d, 0x68, 0xff, 0x0f, 0x9e, 0x67, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x0f, 0x9f, 0x68, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x0f, 0xa2, 0x69, 0xff, 0x0f, 0xa1, 0x68, 0xff, 0x10, 0xa2, 0x69, 0xff, 0x0f, 0xa2, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa4, 0x6a, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0d, 0xa4, 0x67, 0xff, 0x0f, 0xa5, 0x67, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x09, 0x9f, 0x63, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x0a, 0xa5, 0x67, 0xff, 0x0a, 0xa6, 0x69, 0xff, 0x06, 0xa3, 0x6a, 0xff, 0x05, 0xa2, 0x6f, 0xff, 0x0b, 0xa7, 0x7d, 0xff, 0x15, 0xb0, 0x8b, 0xff, 0x07, 0xa1, 0x74, 0xff, 0x08, 0xa1, 0x70, 0xff, 0x0a, 0xa5, 0x70, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x74, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x71, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x10, 0xa2, 0x6d, 0xff, 0x14, 0xa2, 0x6d, 0xff, 0x10, 0x99, 0x65, 0xff, 0x0e, 0x8f, 0x5b, 0xff, 0x12, 0x8e, 0x5b, 0xff, 0x1a, 0x98, 0x67, 0xff, 0x1e, 0x9f, 0x6f, 0xff, 0x1c, 0xa1, 0x70, 0xff, 0x17, 0xa0, 0x70, 0xff, 0x15, 0xa0, 0x6e, 0xff, 0x13, 0x9f, 0x6d, 0xff, 0x0f, 0x9e, 0x6a, 0xff, 0x10, 0x9f, 0x6a, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x0e, 0xa1, 0x69, 0xff, 0x0d, 0xa0, 0x6a, 0xff, 0x0b, 0x9e, 0x69, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0b, 0xa0, 0x64, 0xff, 0x0c, 0xa5, 0x62, 0xff, 0x10, 0xa7, 0x5b, 0xff, 0x03, 0x93, 0x46, 0xff, 0x08, 0x96, 0x4c, 0xff, 0x08, 0x8c, 0x46, 0xff, 0x05, 0x7e, 0x3b, 0xff, 0x04, 0x74, 0x33, 0xff, 0x04, 0x7b, 0x37, 0xff, 0x17, 0xb2, 0x68, 0xff, 0x0d, 0xa9, 0x5f, 0xff, 0x0c, 0x96, 0x4d, 0xff, 0x11, 0x8a, 0x46, 0xff, 0x0a, 0x79, 0x3c, 0xff, 0x09, 0x6b, 0x39, 0xff, 0x0b, 0x5a, 0x32, 0xff, 0x03, 0x43, 0x22, 0xff, 0x01, 0x42, 0x1f, 0xff, 0x09, 0x6e, 0x3f, 0xff, 0x19, 0x9f, 0x67, 0xff, 0x0e, 0x90, 0x58, 0xff, 0x09, 0x88, 0x50, 0xff, 0x0c, 0x8d, 0x55, 0xff, 0x0a, 0x93, 0x59, 0xff, 0x04, 0x93, 0x58, 0xff, 0x07, 0x9a, 0x5e, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x08, 0xa3, 0x5c, 0xff, 0x14, 0xb1, 0x68, 0xff, 0x0b, 0xaa, 0x60, 0xff, 0x04, 0x9e, 0x54, 0xff, 0x11, 0xad, 0x64, 0xff, 0x1a, 0xb6, 0x6d, 0xff, 0x11, 0xac, 0x63, 0xff, 0x08, 0x9a, 0x56, 0xff, 0x0a, 0x8c, 0x51, 0xff, 0x07, 0x83, 0x4e, 0xff, 0x15, 0x88, 0x59, 0xff, 0x22, 0x87, 0x5e, 0xff, 0x0f, 0x6b, 0x42, 0xff, 0x05, 0x74, 0x44, 0xff, 0x05, 0x94, 0x59, 0xff, 0x17, 0xc4, 0x7e, 0xff, 0x12, 0xc9, 0x7a, 0xff, 0x0d, 0xa8, 0x60, 0xff, 0x07, 0x86, 0x45, 0xff, 0x10, 0x80, 0x48, 0xff, 0x1b, 0x8c, 0x5a, 0xff, 0x18, 0x87, 0x5b, 0xff, 0x12, 0x7a, 0x52, 0xff, 0x06, 0x5f, 0x3a, 0xff, 0x06, 0x4b, 0x2a, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x02, 0x3d, 0x1f, 0xff, 0x03, 0x3e, 0x20, 0xff, 0x03, 0x3d, 0x20, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x02, 0x3c, 0x20, 0xff, 0x02, 0x3c, 0x20, 0xff, 0x06, 0x3d, 0x21, 0xff, 0x0e, 0x3a, 0x20, 0xff, 0x08, 0x30, 0x1a, 0xff, 0x02, 0x2c, 0x15, 0xff, 0x0d, 0x41, 0x2a, 0xff, 0x05, 0x36, 0x1c, 0xff, 0x01, 0x35, 0x18, 0xff, 0x0b, 0x4f, 0x30, 0xff, 0x05, 0x41, 0x26, 0xff, 0x04, 0x28, 0x12, 0xff, 0x06, 0x28, 0x11, 0xff, 0x04, 0x39, 0x1d, 0xff, 0x15, 0x50, 0x34, 0xff, 0x0e, 0x38, 0x1e, 0xff, 0x02, 0x2a, 0x10, 0xff, 0x0d, 0x48, 0x2d, 0xff, 0x04, 0x2f, 0x1b, 0xff, 0x0b, 0x4d, 0x2c, 0xff, 0x2c, 0xa4, 0x6e, 0xff, 0x15, 0x95, 0x55, 0xff, 0x04, 0x75, 0x35, 0xff, 0x0e, 0x74, 0x3b, 0xff, 0x11, 0x6e, 0x3c, 0xff, 0x05, 0x64, 0x34, 0xff, 0x0b, 0x79, 0x42, 0xff, 0x0f, 0x77, 0x42, 0xff, 0x11, 0x6c, 0x3b, 0xff, 0x18, 0x67, 0x3a, 0xff, 0x11, 0x68, 0x38, 0xff, 0x0b, 0x6c, 0x3a, 0xff, 0x10, 0x6d, 0x40, 0xff, 0x0b, 0x57, 0x30, 0xff, 0x01, 0x32, 0x14, 0xff, 0x04, 0x3b, 0x1d, 0xff, 0x07, 0x4f, 0x26, 0xff, 0x03, 0x59, 0x22, 0xff, 0x02, 0x4e, 0x1c, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x01, 0x24, 0x12, 0xff, 0x07, 0x39, 0x1f, 0xff, 0x03, 0x40, 0x22, 0xff, 0x03, 0x41, 0x23, 0xff, 0x06, 0x43, 0x24, 0xff, 0x06, 0x41, 0x23, 0xff, 0x07, 0x42, 0x25, 0xff, 0x06, 0x41, 0x24, 0xff, 0x05, 0x40, 0x23, 0xff, 0x07, 0x42, 0x25, 0xff, 0x04, 0x39, 0x1e, 0xff, 0x06, 0x3f, 0x22, 0xff, 0x0c, 0x50, 0x30, 0xff, 0x08, 0x52, 0x2e, 0xff, 0x06, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0c, 0x51, 0x2d, 0xff, 0x09, 0x50, 0x2c, 0xff, 0x0b, 0x4d, 0x2c, 0xff, 0x01, 0x30, 0x15, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x10, 0x6d, 0x4b, 0xff, 0x1c, 0x99, 0x71, 0xff, 0x13, 0x98, 0x69, 0xff, 0x0b, 0x84, 0x53, 0xff, 0x0f, 0x6c, 0x3e, 0xff, 0x0a, 0x52, 0x28, 0xff, 0x00, 0x2d, 0x0e, 0xff, 0x05, 0x29, 0x13, 0xff, 0x13, 0x37, 0x28, 0xff, 0x02, 0x22, 0x15, 0xff, 0x01, 0x26, 0x11, 0xff, 0x10, 0x4b, 0x26, 0xff, 0x14, 0x6c, 0x3d, 0xff, 0x0a, 0x5f, 0x33, 0xff, 0x14, 0x5f, 0x3c, 0xff, 0x0c, 0x61, 0x37, 0xff, 0x11, 0x66, 0x39, 0xff, 0x03, 0x40, 0x24, 0xff, 0x0c, 0x42, 0x2a, 0xff, 0x18, 0x5a, 0x40, 0xff, 0x0c, 0x51, 0x38, 0xff, 0x08, 0x4e, 0x30, 0xff, 0x0b, 0x50, 0x30, 0xff, 0x19, 0x59, 0x3d, 0xff, 0x02, 0x2e, 0x19, 0xff, 0x02, 0x1d, 0x10, 0xff, 0x64, 0x6f, 0x69, 0xff, + 0x03, 0x2d, 0x16, 0xff, 0x0b, 0x42, 0x24, 0xff, 0x09, 0x44, 0x25, 0xff, 0x09, 0x44, 0x25, 0xff, 0x08, 0x43, 0x25, 0xff, 0x08, 0x44, 0x23, 0xff, 0x08, 0x45, 0x23, 0xff, 0x0a, 0x42, 0x24, 0xff, 0x0d, 0x3d, 0x22, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x00, 0x25, 0x11, 0xff, 0x03, 0x2f, 0x18, 0xff, 0x0c, 0x42, 0x25, 0xff, 0x05, 0x46, 0x23, 0xff, 0x07, 0x4d, 0x26, 0xff, 0x0b, 0x53, 0x2a, 0xff, 0x0a, 0x52, 0x2b, 0xff, 0x05, 0x3f, 0x1f, 0xff, 0x01, 0x2d, 0x12, 0xff, 0x0a, 0x40, 0x25, 0xff, 0x05, 0x43, 0x26, 0xff, 0x04, 0x42, 0x23, 0xff, 0x05, 0x41, 0x23, 0xff, 0x04, 0x46, 0x29, 0xff, 0x06, 0x45, 0x27, 0xff, 0x0a, 0x3f, 0x23, 0xff, 0x04, 0x33, 0x19, 0xff, 0x03, 0x2e, 0x17, 0xff, 0x01, 0x2e, 0x1a, 0xff, 0x14, 0x52, 0x40, 0xff, 0x33, 0x70, 0x6d, 0xff, 0x70, 0x9f, 0xc0, 0xff, 0x80, 0xaf, 0xd7, 0xff, 0x69, 0x9b, 0xcc, 0xff, 0x61, 0x95, 0xc9, 0xff, 0x5c, 0x93, 0xc6, 0xff, 0x51, 0x88, 0xbb, 0xff, 0x59, 0x8e, 0xc3, 0xff, 0x70, 0xa5, 0xd7, 0xff, 0x55, 0x90, 0xa9, 0xff, 0x16, 0x62, 0x56, 0xff, 0x16, 0x6e, 0x50, 0xff, 0x18, 0x71, 0x51, 0xff, 0x18, 0x6f, 0x4b, 0xff, 0x1b, 0x66, 0x48, 0xff, 0x17, 0x55, 0x3d, 0xff, 0x0c, 0x45, 0x29, 0xff, 0x02, 0x36, 0x12, 0xff, 0x07, 0x51, 0x26, 0xff, 0x0c, 0x73, 0x3d, 0xff, 0x04, 0x6e, 0x32, 0xff, 0x07, 0x6d, 0x2e, 0xff, 0x0a, 0x6f, 0x2f, 0xff, 0x05, 0x6e, 0x2f, 0xff, 0x07, 0x78, 0x35, 0xff, 0x0d, 0x8b, 0x3a, 0xff, 0x0d, 0x8b, 0x40, 0xff, 0x06, 0x85, 0x43, 0xff, 0x0e, 0x88, 0x50, 0xff, 0x13, 0x87, 0x58, 0xff, 0x13, 0x86, 0x5a, 0xff, 0x13, 0x88, 0x5e, 0xff, 0x13, 0x8c, 0x60, 0xff, 0x11, 0x91, 0x5f, 0xff, 0x12, 0x93, 0x61, 0xff, 0x12, 0x95, 0x63, 0xff, 0x13, 0x96, 0x66, 0xff, 0x13, 0x98, 0x67, 0xff, 0x11, 0x96, 0x65, 0xff, 0x12, 0x99, 0x66, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x0d, 0x9c, 0x66, 0xff, 0x0c, 0x9d, 0x67, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x0e, 0xa0, 0x67, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x0e, 0xa0, 0x68, 0xff, 0x0d, 0xa1, 0x67, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x10, 0xa2, 0x68, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x11, 0xa4, 0x6a, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x67, 0xff, 0x10, 0xa6, 0x67, 0xff, 0x0d, 0xa3, 0x64, 0xff, 0x0a, 0xa1, 0x63, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa1, 0x65, 0xff, 0x08, 0xa0, 0x64, 0xff, 0x0a, 0xa5, 0x66, 0xff, 0x0c, 0xa7, 0x6a, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0b, 0xa4, 0x76, 0xff, 0x2a, 0xc0, 0xa1, 0xff, 0x40, 0xd5, 0xbc, 0xff, 0x22, 0xbb, 0x92, 0xff, 0x06, 0xa0, 0x71, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x09, 0xa3, 0x6e, 0xff, 0x08, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x70, 0xff, 0x0d, 0xa4, 0x77, 0xff, 0x0d, 0xa4, 0x78, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0e, 0xa4, 0x6d, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x16, 0xa4, 0x6f, 0xff, 0x16, 0xa5, 0x70, 0xff, 0x13, 0xa2, 0x6d, 0xff, 0x14, 0xa3, 0x6f, 0xff, 0x12, 0xa2, 0x6d, 0xff, 0x13, 0xa2, 0x6e, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0c, 0xa1, 0x6c, 0xff, 0x0e, 0xa4, 0x6d, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0e, 0xa1, 0x6e, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x08, 0xa2, 0x5c, 0xff, 0x03, 0xa0, 0x52, 0xff, 0x11, 0xb7, 0x65, 0xff, 0x0f, 0xa7, 0x5a, 0xff, 0x05, 0x87, 0x41, 0xff, 0x05, 0x7f, 0x3b, 0xff, 0x06, 0x7a, 0x36, 0xff, 0x0c, 0x92, 0x49, 0xff, 0x17, 0xbb, 0x6c, 0xff, 0x03, 0xa1, 0x53, 0xff, 0x0b, 0x92, 0x4a, 0xff, 0x0d, 0x86, 0x41, 0xff, 0x07, 0x77, 0x38, 0xff, 0x0a, 0x6b, 0x38, 0xff, 0x0a, 0x58, 0x2e, 0xff, 0x02, 0x46, 0x1e, 0xff, 0x04, 0x57, 0x2b, 0xff, 0x1d, 0xa2, 0x69, 0xff, 0x13, 0xaa, 0x67, 0xff, 0x05, 0x93, 0x52, 0xff, 0x15, 0x9f, 0x5e, 0xff, 0x11, 0x97, 0x57, 0xff, 0x03, 0x8b, 0x4a, 0xff, 0x01, 0x8d, 0x4b, 0xff, 0x0d, 0xa8, 0x64, 0xff, 0x13, 0xb2, 0x6c, 0xff, 0x0d, 0xa5, 0x5c, 0xff, 0x02, 0x91, 0x4b, 0xff, 0x04, 0x90, 0x4a, 0xff, 0x0f, 0x9b, 0x55, 0xff, 0x12, 0x9e, 0x5a, 0xff, 0x0a, 0x95, 0x52, 0xff, 0x09, 0x8f, 0x4c, 0xff, 0x06, 0x82, 0x44, 0xff, 0x06, 0x75, 0x41, 0xff, 0x04, 0x63, 0x38, 0xff, 0x0a, 0x5c, 0x36, 0xff, 0x0a, 0x5a, 0x34, 0xff, 0x02, 0x5b, 0x31, 0xff, 0x07, 0x8b, 0x54, 0xff, 0x0b, 0xae, 0x6b, 0xff, 0x18, 0xcf, 0x82, 0xff, 0x07, 0xaf, 0x65, 0xff, 0x04, 0x8d, 0x4c, 0xff, 0x12, 0x90, 0x55, 0xff, 0x1a, 0x94, 0x60, 0xff, 0x14, 0x90, 0x61, 0xff, 0x11, 0x91, 0x63, 0xff, 0x17, 0x90, 0x64, 0xff, 0x1f, 0x8c, 0x62, 0xff, 0x1e, 0x84, 0x5d, 0xff, 0x17, 0x79, 0x53, 0xff, 0x0b, 0x6a, 0x45, 0xff, 0x05, 0x5e, 0x39, 0xff, 0x03, 0x54, 0x32, 0xff, 0x02, 0x48, 0x27, 0xff, 0x02, 0x41, 0x22, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x05, 0x3d, 0x22, 0xff, 0x07, 0x38, 0x21, 0xff, 0x01, 0x28, 0x12, 0xff, 0x04, 0x2e, 0x16, 0xff, 0x0a, 0x3e, 0x22, 0xff, 0x01, 0x31, 0x13, 0xff, 0x09, 0x45, 0x25, 0xff, 0x12, 0x51, 0x35, 0xff, 0x06, 0x33, 0x1b, 0xff, 0x03, 0x27, 0x0f, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x09, 0x3a, 0x21, 0xff, 0x0b, 0x39, 0x21, 0xff, 0x01, 0x27, 0x0f, 0xff, 0x0d, 0x3e, 0x26, 0xff, 0x07, 0x2f, 0x1b, 0xff, 0x12, 0x58, 0x34, 0xff, 0x28, 0xa6, 0x6e, 0xff, 0x0f, 0x8f, 0x4e, 0xff, 0x08, 0x74, 0x35, 0xff, 0x0e, 0x72, 0x3a, 0xff, 0x12, 0x6c, 0x3c, 0xff, 0x07, 0x65, 0x37, 0xff, 0x0d, 0x7a, 0x44, 0xff, 0x0b, 0x6e, 0x3b, 0xff, 0x11, 0x67, 0x39, 0xff, 0x13, 0x68, 0x3a, 0xff, 0x0b, 0x69, 0x38, 0xff, 0x0a, 0x69, 0x3a, 0xff, 0x11, 0x66, 0x3d, 0xff, 0x02, 0x3f, 0x1d, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x05, 0x46, 0x21, 0xff, 0x03, 0x56, 0x21, 0xff, 0x04, 0x4f, 0x1d, 0xff, 0x00, 0x28, 0x0d, 0xff, 0x05, 0x2a, 0x17, 0xff, 0x0a, 0x3b, 0x20, 0xff, 0x02, 0x40, 0x21, 0xff, 0x03, 0x41, 0x23, 0xff, 0x06, 0x43, 0x25, 0xff, 0x06, 0x40, 0x23, 0xff, 0x08, 0x41, 0x24, 0xff, 0x08, 0x42, 0x25, 0xff, 0x07, 0x41, 0x24, 0xff, 0x07, 0x41, 0x24, 0xff, 0x05, 0x3c, 0x20, 0xff, 0x03, 0x3f, 0x21, 0xff, 0x0a, 0x4f, 0x2e, 0xff, 0x07, 0x51, 0x2e, 0xff, 0x06, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x09, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0c, 0x50, 0x2c, 0xff, 0x09, 0x4f, 0x2c, 0xff, 0x0a, 0x4b, 0x2b, 0xff, 0x00, 0x2b, 0x10, 0xff, 0x02, 0x32, 0x16, 0xff, 0x14, 0x7c, 0x58, 0xff, 0x1c, 0xa1, 0x76, 0xff, 0x0a, 0x8f, 0x60, 0xff, 0x0d, 0x80, 0x4f, 0xff, 0x0e, 0x64, 0x36, 0xff, 0x0c, 0x4b, 0x24, 0xff, 0x00, 0x28, 0x0c, 0xff, 0x09, 0x2e, 0x1b, 0xff, 0x12, 0x32, 0x24, 0xff, 0x01, 0x20, 0x11, 0xff, 0x03, 0x2d, 0x17, 0xff, 0x19, 0x5a, 0x35, 0xff, 0x09, 0x5e, 0x34, 0xff, 0x03, 0x53, 0x26, 0xff, 0x13, 0x63, 0x39, 0xff, 0x0d, 0x65, 0x33, 0xff, 0x0e, 0x6b, 0x33, 0xff, 0x06, 0x51, 0x2f, 0xff, 0x12, 0x51, 0x3b, 0xff, 0x15, 0x5a, 0x42, 0xff, 0x0b, 0x4e, 0x35, 0xff, 0x09, 0x4f, 0x31, 0xff, 0x08, 0x4e, 0x2e, 0xff, 0x16, 0x54, 0x36, 0xff, 0x01, 0x28, 0x14, 0xff, 0x03, 0x1d, 0x10, 0xff, 0x64, 0x70, 0x68, 0xff, + 0x03, 0x2d, 0x16, 0xff, 0x0a, 0x41, 0x24, 0xff, 0x09, 0x43, 0x24, 0xff, 0x08, 0x43, 0x25, 0xff, 0x08, 0x43, 0x25, 0xff, 0x08, 0x44, 0x23, 0xff, 0x09, 0x44, 0x23, 0xff, 0x09, 0x43, 0x24, 0xff, 0x0c, 0x40, 0x24, 0xff, 0x01, 0x2c, 0x14, 0xff, 0x00, 0x26, 0x11, 0xff, 0x03, 0x2b, 0x14, 0xff, 0x0e, 0x41, 0x26, 0xff, 0x06, 0x44, 0x23, 0xff, 0x07, 0x4a, 0x26, 0xff, 0x0b, 0x52, 0x29, 0xff, 0x08, 0x51, 0x2b, 0xff, 0x03, 0x40, 0x1f, 0xff, 0x01, 0x2e, 0x12, 0xff, 0x0b, 0x3f, 0x25, 0xff, 0x06, 0x42, 0x26, 0xff, 0x05, 0x42, 0x24, 0xff, 0x06, 0x42, 0x24, 0xff, 0x05, 0x44, 0x25, 0xff, 0x07, 0x44, 0x24, 0xff, 0x09, 0x40, 0x21, 0xff, 0x03, 0x30, 0x17, 0xff, 0x00, 0x28, 0x17, 0xff, 0x07, 0x31, 0x2b, 0xff, 0x45, 0x7c, 0x80, 0xff, 0x73, 0xab, 0xbc, 0xff, 0x7f, 0xb1, 0xdb, 0xff, 0x77, 0xac, 0xdb, 0xff, 0x55, 0x8d, 0xc2, 0xff, 0x54, 0x8c, 0xc2, 0xff, 0x54, 0x8c, 0xbf, 0xff, 0x65, 0x9a, 0xce, 0xff, 0x67, 0x9b, 0xd1, 0xff, 0x6e, 0xa1, 0xd3, 0xff, 0x57, 0x95, 0xa7, 0xff, 0x1e, 0x6f, 0x5c, 0xff, 0x19, 0x7a, 0x53, 0xff, 0x10, 0x77, 0x4f, 0xff, 0x0f, 0x76, 0x4c, 0xff, 0x12, 0x70, 0x4c, 0xff, 0x19, 0x6b, 0x4f, 0xff, 0x1a, 0x69, 0x49, 0xff, 0x11, 0x5f, 0x3a, 0xff, 0x03, 0x46, 0x1d, 0xff, 0x09, 0x5e, 0x2c, 0xff, 0x13, 0x7b, 0x42, 0xff, 0x04, 0x6e, 0x30, 0xff, 0x08, 0x6f, 0x2e, 0xff, 0x07, 0x72, 0x31, 0xff, 0x08, 0x7f, 0x37, 0xff, 0x08, 0x91, 0x38, 0xff, 0x0b, 0x93, 0x40, 0xff, 0x02, 0x8a, 0x40, 0xff, 0x05, 0x88, 0x47, 0xff, 0x0f, 0x8b, 0x53, 0xff, 0x11, 0x8b, 0x59, 0xff, 0x11, 0x8d, 0x5e, 0xff, 0x10, 0x8f, 0x60, 0xff, 0x11, 0x93, 0x60, 0xff, 0x13, 0x95, 0x63, 0xff, 0x13, 0x97, 0x65, 0xff, 0x13, 0x97, 0x65, 0xff, 0x12, 0x98, 0x66, 0xff, 0x12, 0x98, 0x66, 0xff, 0x12, 0x9a, 0x66, 0xff, 0x12, 0x9b, 0x67, 0xff, 0x0e, 0x9e, 0x67, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x0d, 0x9f, 0x68, 0xff, 0x0e, 0xa0, 0x69, 0xff, 0x0d, 0xa0, 0x66, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa5, 0x66, 0xff, 0x0f, 0xa5, 0x65, 0xff, 0x0e, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x06, 0xa1, 0x65, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x08, 0xa1, 0x65, 0xff, 0x07, 0xa0, 0x61, 0xff, 0x09, 0xa3, 0x64, 0xff, 0x0c, 0xa6, 0x6a, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0c, 0xa1, 0x79, 0xff, 0x3f, 0xce, 0xb6, 0xff, 0x52, 0xe0, 0xce, 0xff, 0x1f, 0xb6, 0x8f, 0xff, 0x07, 0xa1, 0x73, 0xff, 0x09, 0xa3, 0x73, 0xff, 0x0a, 0xa2, 0x70, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x0b, 0xa3, 0x71, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0d, 0xa4, 0x77, 0xff, 0x0f, 0xa5, 0x76, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x13, 0xa3, 0x6e, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x0a, 0xa0, 0x6c, 0xff, 0x0f, 0xa7, 0x69, 0xff, 0x0b, 0xa4, 0x5d, 0xff, 0x0b, 0xb0, 0x60, 0xff, 0x0e, 0xbf, 0x6b, 0xff, 0x03, 0x95, 0x49, 0xff, 0x07, 0x7f, 0x3b, 0xff, 0x0b, 0x7d, 0x3a, 0xff, 0x05, 0x76, 0x34, 0xff, 0x16, 0x9e, 0x55, 0xff, 0x1a, 0xba, 0x6a, 0xff, 0x08, 0xa0, 0x52, 0xff, 0x11, 0x95, 0x4f, 0xff, 0x08, 0x83, 0x40, 0xff, 0x03, 0x75, 0x37, 0xff, 0x08, 0x68, 0x36, 0xff, 0x07, 0x55, 0x2b, 0xff, 0x02, 0x4b, 0x1f, 0xff, 0x15, 0x88, 0x54, 0xff, 0x15, 0xad, 0x6e, 0xff, 0x04, 0x98, 0x52, 0xff, 0x10, 0xa7, 0x60, 0xff, 0x1f, 0xb3, 0x6d, 0xff, 0x15, 0xa3, 0x5e, 0xff, 0x03, 0x88, 0x42, 0xff, 0x0e, 0x9d, 0x56, 0xff, 0x18, 0xb3, 0x69, 0xff, 0x0e, 0xaa, 0x61, 0xff, 0x0d, 0x99, 0x54, 0xff, 0x02, 0x82, 0x40, 0xff, 0x0d, 0x8d, 0x4b, 0xff, 0x06, 0x81, 0x43, 0xff, 0x08, 0x80, 0x42, 0xff, 0x0b, 0x7e, 0x42, 0xff, 0x0c, 0x7d, 0x42, 0xff, 0x08, 0x72, 0x3b, 0xff, 0x06, 0x5f, 0x33, 0xff, 0x01, 0x42, 0x1e, 0xff, 0x02, 0x45, 0x23, 0xff, 0x0a, 0x63, 0x3c, 0xff, 0x0d, 0x84, 0x56, 0xff, 0x11, 0xac, 0x6e, 0xff, 0x1b, 0xc7, 0x80, 0xff, 0x0a, 0xb6, 0x6c, 0xff, 0x06, 0x9b, 0x5a, 0xff, 0x0e, 0x93, 0x59, 0xff, 0x18, 0x94, 0x60, 0xff, 0x0e, 0x90, 0x5f, 0xff, 0x08, 0x92, 0x61, 0xff, 0x07, 0x91, 0x5f, 0xff, 0x12, 0x8f, 0x5f, 0xff, 0x1d, 0x8f, 0x61, 0xff, 0x14, 0x8f, 0x62, 0xff, 0x14, 0x90, 0x64, 0xff, 0x15, 0x8e, 0x62, 0xff, 0x17, 0x88, 0x5e, 0xff, 0x1a, 0x81, 0x58, 0xff, 0x1b, 0x6f, 0x4c, 0xff, 0x18, 0x5f, 0x3e, 0xff, 0x0a, 0x49, 0x2a, 0xff, 0x03, 0x44, 0x25, 0xff, 0x02, 0x43, 0x26, 0xff, 0x05, 0x41, 0x26, 0xff, 0x03, 0x32, 0x18, 0xff, 0x00, 0x29, 0x0c, 0xff, 0x06, 0x40, 0x21, 0xff, 0x04, 0x3d, 0x1d, 0xff, 0x03, 0x34, 0x15, 0xff, 0x11, 0x4c, 0x2f, 0xff, 0x10, 0x46, 0x2b, 0xff, 0x02, 0x2d, 0x14, 0xff, 0x02, 0x29, 0x10, 0xff, 0x01, 0x2c, 0x16, 0xff, 0x06, 0x37, 0x1f, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x0a, 0x32, 0x1d, 0xff, 0x07, 0x2a, 0x15, 0xff, 0x14, 0x60, 0x3b, 0xff, 0x1c, 0x98, 0x61, 0xff, 0x15, 0x91, 0x50, 0xff, 0x0c, 0x74, 0x36, 0xff, 0x0e, 0x72, 0x3b, 0xff, 0x10, 0x6b, 0x3a, 0xff, 0x09, 0x68, 0x3a, 0xff, 0x0e, 0x77, 0x42, 0xff, 0x0c, 0x6b, 0x39, 0xff, 0x12, 0x68, 0x3a, 0xff, 0x0c, 0x69, 0x3a, 0xff, 0x07, 0x6c, 0x38, 0xff, 0x0c, 0x69, 0x3b, 0xff, 0x0f, 0x5d, 0x37, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x03, 0x2e, 0x19, 0xff, 0x01, 0x2a, 0x15, 0xff, 0x06, 0x43, 0x21, 0xff, 0x05, 0x54, 0x20, 0xff, 0x08, 0x51, 0x20, 0xff, 0x00, 0x2d, 0x11, 0xff, 0x07, 0x30, 0x1c, 0xff, 0x09, 0x3c, 0x20, 0xff, 0x02, 0x40, 0x22, 0xff, 0x03, 0x41, 0x23, 0xff, 0x06, 0x43, 0x25, 0xff, 0x07, 0x42, 0x24, 0xff, 0x09, 0x42, 0x25, 0xff, 0x08, 0x41, 0x24, 0xff, 0x08, 0x42, 0x25, 0xff, 0x05, 0x40, 0x22, 0xff, 0x07, 0x3f, 0x24, 0xff, 0x03, 0x41, 0x23, 0xff, 0x0b, 0x50, 0x30, 0xff, 0x06, 0x51, 0x2d, 0xff, 0x06, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0b, 0x4f, 0x2b, 0xff, 0x09, 0x4f, 0x2d, 0xff, 0x0a, 0x47, 0x2a, 0xff, 0x00, 0x29, 0x0f, 0xff, 0x02, 0x3a, 0x1d, 0xff, 0x13, 0x86, 0x5e, 0xff, 0x1c, 0xa4, 0x76, 0xff, 0x08, 0x88, 0x5b, 0xff, 0x10, 0x7c, 0x4d, 0xff, 0x0c, 0x5e, 0x30, 0xff, 0x0c, 0x45, 0x22, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x0b, 0x33, 0x23, 0xff, 0x0e, 0x2c, 0x1f, 0xff, 0x01, 0x22, 0x11, 0xff, 0x07, 0x3a, 0x1f, 0xff, 0x18, 0x5d, 0x3a, 0xff, 0x0b, 0x58, 0x35, 0xff, 0x02, 0x4b, 0x23, 0xff, 0x0e, 0x5a, 0x38, 0xff, 0x0e, 0x62, 0x39, 0xff, 0x0c, 0x6a, 0x34, 0xff, 0x0a, 0x5d, 0x37, 0xff, 0x12, 0x56, 0x40, 0xff, 0x13, 0x59, 0x42, 0xff, 0x08, 0x4a, 0x30, 0xff, 0x09, 0x50, 0x31, 0xff, 0x06, 0x4c, 0x2b, 0xff, 0x13, 0x4f, 0x31, 0xff, 0x01, 0x24, 0x11, 0xff, 0x04, 0x1d, 0x11, 0xff, 0x65, 0x71, 0x69, 0xff, + 0x02, 0x2b, 0x16, 0xff, 0x0a, 0x40, 0x23, 0xff, 0x08, 0x43, 0x25, 0xff, 0x08, 0x42, 0x25, 0xff, 0x08, 0x43, 0x25, 0xff, 0x08, 0x44, 0x23, 0xff, 0x09, 0x45, 0x23, 0xff, 0x09, 0x43, 0x24, 0xff, 0x0c, 0x42, 0x25, 0xff, 0x03, 0x31, 0x18, 0xff, 0x00, 0x27, 0x11, 0xff, 0x01, 0x27, 0x12, 0xff, 0x0c, 0x3b, 0x21, 0xff, 0x07, 0x42, 0x24, 0xff, 0x06, 0x46, 0x23, 0xff, 0x0a, 0x4e, 0x28, 0xff, 0x07, 0x51, 0x2c, 0xff, 0x04, 0x43, 0x21, 0xff, 0x01, 0x30, 0x12, 0xff, 0x0b, 0x40, 0x24, 0xff, 0x06, 0x42, 0x24, 0xff, 0x05, 0x42, 0x24, 0xff, 0x07, 0x43, 0x24, 0xff, 0x05, 0x43, 0x20, 0xff, 0x08, 0x45, 0x22, 0xff, 0x05, 0x3d, 0x21, 0xff, 0x01, 0x30, 0x20, 0xff, 0x1c, 0x46, 0x47, 0xff, 0x4f, 0x7d, 0x8d, 0xff, 0x7f, 0xaf, 0xd0, 0xff, 0x80, 0xb3, 0xda, 0xff, 0x7a, 0xb2, 0xdc, 0xff, 0x6e, 0xa8, 0xd7, 0xff, 0x49, 0x84, 0xb8, 0xff, 0x4c, 0x85, 0xbb, 0xff, 0x6b, 0xa0, 0xd4, 0xff, 0x6a, 0x9b, 0xd1, 0xff, 0x66, 0x96, 0xcf, 0xff, 0x75, 0xa6, 0xd9, 0xff, 0x60, 0x9d, 0xaa, 0xff, 0x14, 0x60, 0x48, 0xff, 0x13, 0x6c, 0x43, 0xff, 0x12, 0x71, 0x48, 0xff, 0x12, 0x76, 0x4d, 0xff, 0x0c, 0x75, 0x4e, 0xff, 0x0c, 0x76, 0x54, 0xff, 0x12, 0x7d, 0x58, 0xff, 0x1e, 0x85, 0x5c, 0xff, 0x1d, 0x79, 0x4f, 0xff, 0x06, 0x4e, 0x21, 0xff, 0x0f, 0x60, 0x2d, 0xff, 0x18, 0x7e, 0x44, 0xff, 0x03, 0x6e, 0x2f, 0xff, 0x03, 0x76, 0x32, 0xff, 0x08, 0x84, 0x39, 0xff, 0x05, 0x94, 0x39, 0xff, 0x06, 0x97, 0x3f, 0xff, 0x04, 0x94, 0x42, 0xff, 0x02, 0x8d, 0x42, 0xff, 0x04, 0x87, 0x46, 0xff, 0x10, 0x90, 0x56, 0xff, 0x11, 0x8f, 0x5c, 0xff, 0x11, 0x94, 0x61, 0xff, 0x0f, 0x99, 0x63, 0xff, 0x0e, 0x98, 0x64, 0xff, 0x0f, 0x99, 0x64, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x0e, 0x9b, 0x66, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0e, 0x9e, 0x67, 0xff, 0x0e, 0x9f, 0x68, 0xff, 0x0d, 0x9f, 0x68, 0xff, 0x0d, 0xa0, 0x67, 0xff, 0x0d, 0xa2, 0x67, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x10, 0xa5, 0x6b, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa3, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x67, 0xff, 0x0e, 0xa3, 0x66, 0xff, 0x0e, 0xa3, 0x65, 0xff, 0x0e, 0xa3, 0x64, 0xff, 0x0d, 0xa2, 0x66, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa6, 0x6a, 0xff, 0x0e, 0xa7, 0x6b, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x07, 0xa3, 0x66, 0xff, 0x07, 0xa2, 0x66, 0xff, 0x0b, 0xa7, 0x68, 0xff, 0x07, 0xa3, 0x64, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x10, 0xaa, 0x70, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x19, 0xac, 0x87, 0xff, 0x34, 0xc1, 0xa9, 0xff, 0x2e, 0xb8, 0xa5, 0xff, 0x07, 0x9c, 0x76, 0xff, 0x1d, 0xb7, 0x89, 0xff, 0x16, 0xae, 0x80, 0xff, 0x21, 0xb7, 0x8a, 0xff, 0x16, 0xac, 0x7d, 0xff, 0x0c, 0xa2, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0e, 0xa5, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x07, 0xa4, 0x6e, 0xff, 0x07, 0xa4, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x10, 0xa5, 0x71, 0xff, 0x11, 0xa4, 0x73, 0xff, 0x0f, 0xa2, 0x73, 0xff, 0x0e, 0xa2, 0x72, 0xff, 0x10, 0xa7, 0x6b, 0xff, 0x14, 0xab, 0x65, 0xff, 0x23, 0xbf, 0x72, 0xff, 0x14, 0xaf, 0x61, 0xff, 0x0c, 0x8d, 0x46, 0xff, 0x12, 0x7f, 0x3e, 0xff, 0x0b, 0x78, 0x38, 0xff, 0x03, 0x77, 0x34, 0xff, 0x25, 0xaf, 0x66, 0xff, 0x1f, 0xb6, 0x67, 0xff, 0x10, 0x9e, 0x52, 0xff, 0x0b, 0x89, 0x45, 0xff, 0x02, 0x79, 0x38, 0xff, 0x01, 0x70, 0x34, 0xff, 0x0a, 0x68, 0x37, 0xff, 0x02, 0x51, 0x25, 0xff, 0x10, 0x6d, 0x3f, 0xff, 0x1d, 0xa0, 0x68, 0xff, 0x05, 0x9e, 0x5d, 0xff, 0x12, 0x9e, 0x5c, 0xff, 0x18, 0xa4, 0x62, 0xff, 0x0f, 0x9b, 0x59, 0xff, 0x07, 0x93, 0x50, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x1b, 0xaa, 0x63, 0xff, 0x15, 0xa3, 0x5a, 0xff, 0x08, 0x8d, 0x49, 0xff, 0x04, 0x7b, 0x3d, 0xff, 0x08, 0x7e, 0x42, 0xff, 0x15, 0x8c, 0x52, 0xff, 0x06, 0x70, 0x3b, 0xff, 0x0a, 0x6a, 0x38, 0xff, 0x10, 0x6c, 0x3b, 0xff, 0x0a, 0x68, 0x36, 0xff, 0x01, 0x58, 0x29, 0xff, 0x03, 0x51, 0x2a, 0xff, 0x09, 0x58, 0x32, 0xff, 0x11, 0x72, 0x4c, 0xff, 0x15, 0x8f, 0x64, 0xff, 0x17, 0xa5, 0x73, 0xff, 0x1c, 0xb8, 0x7b, 0xff, 0x12, 0xaf, 0x6c, 0xff, 0x05, 0x9a, 0x58, 0xff, 0x0b, 0x95, 0x5f, 0xff, 0x13, 0x93, 0x61, 0xff, 0x14, 0x93, 0x63, 0xff, 0x0c, 0x93, 0x64, 0xff, 0x04, 0x94, 0x62, 0xff, 0x05, 0x95, 0x61, 0xff, 0x0d, 0x92, 0x5f, 0xff, 0x16, 0x92, 0x60, 0xff, 0x0f, 0x91, 0x63, 0xff, 0x14, 0x92, 0x64, 0xff, 0x16, 0x8e, 0x61, 0xff, 0x1c, 0x87, 0x5c, 0xff, 0x1c, 0x7b, 0x53, 0xff, 0x1c, 0x6e, 0x48, 0xff, 0x19, 0x62, 0x3e, 0xff, 0x10, 0x4f, 0x2e, 0xff, 0x0f, 0x46, 0x29, 0xff, 0x06, 0x45, 0x26, 0xff, 0x02, 0x42, 0x22, 0xff, 0x02, 0x42, 0x20, 0xff, 0x0e, 0x54, 0x30, 0xff, 0x15, 0x6a, 0x44, 0xff, 0x14, 0x61, 0x3c, 0xff, 0x03, 0x37, 0x17, 0xff, 0x03, 0x34, 0x17, 0xff, 0x0f, 0x4a, 0x2e, 0xff, 0x0c, 0x40, 0x25, 0xff, 0x02, 0x28, 0x11, 0xff, 0x00, 0x26, 0x10, 0xff, 0x01, 0x31, 0x19, 0xff, 0x00, 0x2d, 0x16, 0xff, 0x03, 0x25, 0x12, 0xff, 0x06, 0x26, 0x10, 0xff, 0x15, 0x6c, 0x43, 0xff, 0x12, 0x89, 0x52, 0xff, 0x1c, 0x90, 0x53, 0xff, 0x0e, 0x74, 0x39, 0xff, 0x0a, 0x70, 0x3c, 0xff, 0x0c, 0x67, 0x37, 0xff, 0x0a, 0x6c, 0x3d, 0xff, 0x0f, 0x74, 0x3f, 0xff, 0x0e, 0x69, 0x37, 0xff, 0x0e, 0x68, 0x3a, 0xff, 0x06, 0x6a, 0x3a, 0xff, 0x04, 0x6c, 0x39, 0xff, 0x0f, 0x67, 0x3b, 0xff, 0x0b, 0x51, 0x2e, 0xff, 0x03, 0x37, 0x1e, 0xff, 0x06, 0x2f, 0x1d, 0xff, 0x01, 0x29, 0x15, 0xff, 0x06, 0x3e, 0x1f, 0xff, 0x07, 0x52, 0x22, 0xff, 0x09, 0x51, 0x24, 0xff, 0x03, 0x36, 0x1b, 0xff, 0x09, 0x34, 0x20, 0xff, 0x07, 0x3e, 0x20, 0xff, 0x04, 0x43, 0x23, 0xff, 0x04, 0x42, 0x24, 0xff, 0x07, 0x42, 0x24, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0b, 0x43, 0x26, 0xff, 0x07, 0x41, 0x24, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x07, 0x44, 0x26, 0xff, 0x0e, 0x48, 0x2c, 0xff, 0x03, 0x3d, 0x1f, 0xff, 0x0d, 0x4f, 0x30, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x09, 0x50, 0x2c, 0xff, 0x07, 0x4f, 0x2b, 0xff, 0x08, 0x4f, 0x2b, 0xff, 0x09, 0x4f, 0x2e, 0xff, 0x0a, 0x43, 0x27, 0xff, 0x00, 0x26, 0x0d, 0xff, 0x04, 0x47, 0x28, 0xff, 0x18, 0x90, 0x64, 0xff, 0x19, 0x9f, 0x71, 0xff, 0x09, 0x84, 0x59, 0xff, 0x0f, 0x78, 0x48, 0xff, 0x0b, 0x57, 0x2b, 0xff, 0x0a, 0x3e, 0x1d, 0xff, 0x01, 0x23, 0x11, 0xff, 0x10, 0x3b, 0x2c, 0xff, 0x0a, 0x28, 0x1b, 0xff, 0x01, 0x22, 0x0e, 0xff, 0x0d, 0x4a, 0x2c, 0xff, 0x16, 0x62, 0x3b, 0xff, 0x09, 0x4d, 0x2c, 0xff, 0x07, 0x45, 0x26, 0xff, 0x35, 0x73, 0x70, 0xff, 0x23, 0x66, 0x61, 0xff, 0x09, 0x63, 0x3e, 0xff, 0x10, 0x65, 0x42, 0xff, 0x0f, 0x5a, 0x3d, 0xff, 0x14, 0x5b, 0x3f, 0xff, 0x07, 0x4a, 0x2e, 0xff, 0x0a, 0x51, 0x31, 0xff, 0x07, 0x4d, 0x2b, 0xff, 0x0d, 0x45, 0x28, 0xff, 0x01, 0x22, 0x0f, 0xff, 0x06, 0x1c, 0x11, 0xff, 0x65, 0x71, 0x69, 0xff, + 0x01, 0x29, 0x15, 0xff, 0x0a, 0x3e, 0x22, 0xff, 0x09, 0x43, 0x25, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x09, 0x44, 0x23, 0xff, 0x08, 0x44, 0x23, 0xff, 0x08, 0x44, 0x23, 0xff, 0x0b, 0x43, 0x25, 0xff, 0x06, 0x36, 0x1d, 0xff, 0x00, 0x28, 0x13, 0xff, 0x00, 0x26, 0x11, 0xff, 0x08, 0x34, 0x1c, 0xff, 0x09, 0x42, 0x25, 0xff, 0x06, 0x44, 0x22, 0xff, 0x07, 0x4b, 0x25, 0xff, 0x07, 0x51, 0x2c, 0xff, 0x06, 0x47, 0x25, 0xff, 0x01, 0x32, 0x14, 0xff, 0x0c, 0x3f, 0x23, 0xff, 0x07, 0x42, 0x24, 0xff, 0x05, 0x42, 0x24, 0xff, 0x08, 0x43, 0x23, 0xff, 0x07, 0x44, 0x22, 0xff, 0x03, 0x3f, 0x25, 0xff, 0x08, 0x40, 0x34, 0xff, 0x28, 0x5c, 0x5f, 0xff, 0x70, 0x9e, 0xb5, 0xff, 0x87, 0xb5, 0xd9, 0xff, 0x7f, 0xb0, 0xe0, 0xff, 0x7b, 0xae, 0xde, 0xff, 0x68, 0xa0, 0xca, 0xff, 0x4f, 0x8b, 0xb9, 0xff, 0x55, 0x91, 0xc2, 0xff, 0x6d, 0xa5, 0xd8, 0xff, 0x6c, 0x9d, 0xd0, 0xff, 0x6b, 0x99, 0xce, 0xff, 0x76, 0xa5, 0xdd, 0xff, 0x81, 0xb3, 0xe6, 0xff, 0x3c, 0x72, 0x81, 0xff, 0x01, 0x38, 0x23, 0xff, 0x01, 0x3e, 0x1b, 0xff, 0x03, 0x47, 0x25, 0xff, 0x0a, 0x5b, 0x35, 0xff, 0x15, 0x73, 0x4e, 0xff, 0x16, 0x81, 0x5c, 0xff, 0x12, 0x86, 0x5c, 0xff, 0x0d, 0x83, 0x56, 0xff, 0x18, 0x87, 0x5c, 0xff, 0x19, 0x77, 0x4c, 0xff, 0x08, 0x51, 0x25, 0xff, 0x19, 0x74, 0x40, 0xff, 0x11, 0x7e, 0x41, 0xff, 0x03, 0x77, 0x30, 0xff, 0x08, 0x88, 0x3a, 0xff, 0x04, 0x96, 0x3b, 0xff, 0x04, 0x9a, 0x3d, 0xff, 0x05, 0x9a, 0x41, 0xff, 0x07, 0x96, 0x43, 0xff, 0x03, 0x89, 0x40, 0xff, 0x05, 0x85, 0x46, 0xff, 0x15, 0x94, 0x5c, 0xff, 0x14, 0x97, 0x62, 0xff, 0x0c, 0x99, 0x62, 0xff, 0x0c, 0x9a, 0x63, 0xff, 0x0c, 0x9a, 0x65, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0b, 0x9c, 0x66, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0b, 0x9e, 0x66, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x0c, 0xa1, 0x67, 0xff, 0x0c, 0xa1, 0x67, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x10, 0xa6, 0x6b, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x0e, 0xa3, 0x66, 0xff, 0x0e, 0xa3, 0x67, 0xff, 0x0d, 0xa6, 0x6a, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0f, 0xa7, 0x6c, 0xff, 0x0e, 0xa6, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x07, 0xa0, 0x67, 0xff, 0x07, 0xa2, 0x67, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x0b, 0xa8, 0x6a, 0xff, 0x0a, 0xab, 0x6d, 0xff, 0x0d, 0xad, 0x71, 0xff, 0x0e, 0xac, 0x70, 0xff, 0x11, 0xae, 0x75, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x25, 0xbb, 0x8f, 0xff, 0x43, 0xd2, 0xb1, 0xff, 0x13, 0x9e, 0x82, 0xff, 0x11, 0xa8, 0x80, 0xff, 0x1f, 0xb8, 0x8c, 0xff, 0x1f, 0xb6, 0x8b, 0xff, 0x3c, 0xd1, 0xa8, 0xff, 0x2f, 0xc2, 0x98, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x12, 0xaa, 0x76, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x6d, 0xff, 0x0d, 0xa7, 0x6d, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0b, 0xa2, 0x6f, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0a, 0xa5, 0x71, 0xff, 0x07, 0xa3, 0x70, 0xff, 0x07, 0xa3, 0x6f, 0xff, 0x05, 0xa4, 0x6e, 0xff, 0x06, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x15, 0xa8, 0x78, 0xff, 0x17, 0xa6, 0x79, 0xff, 0x13, 0xa4, 0x79, 0xff, 0x10, 0xa4, 0x75, 0xff, 0x12, 0xa7, 0x6e, 0xff, 0x11, 0xa4, 0x60, 0xff, 0x0c, 0x96, 0x4c, 0xff, 0x04, 0x7e, 0x37, 0xff, 0x06, 0x71, 0x30, 0xff, 0x0a, 0x72, 0x34, 0xff, 0x07, 0x75, 0x37, 0xff, 0x05, 0x82, 0x3f, 0xff, 0x17, 0x9f, 0x56, 0xff, 0x0a, 0x8e, 0x41, 0xff, 0x03, 0x7d, 0x32, 0xff, 0x05, 0x7f, 0x3a, 0xff, 0x08, 0x81, 0x40, 0xff, 0x0b, 0x77, 0x3d, 0xff, 0x0c, 0x68, 0x38, 0xff, 0x03, 0x54, 0x29, 0xff, 0x18, 0x7e, 0x50, 0xff, 0x13, 0x8b, 0x57, 0xff, 0x10, 0x8e, 0x56, 0xff, 0x12, 0x84, 0x51, 0xff, 0x07, 0x73, 0x3f, 0xff, 0x06, 0x73, 0x3d, 0xff, 0x08, 0x83, 0x47, 0xff, 0x14, 0x9a, 0x5b, 0xff, 0x0c, 0x90, 0x50, 0xff, 0x0c, 0x85, 0x44, 0xff, 0x0a, 0x76, 0x3a, 0xff, 0x0a, 0x71, 0x39, 0xff, 0x11, 0x7d, 0x47, 0xff, 0x0a, 0x73, 0x40, 0xff, 0x03, 0x5b, 0x2c, 0xff, 0x03, 0x4c, 0x21, 0xff, 0x03, 0x49, 0x1e, 0xff, 0x02, 0x51, 0x24, 0xff, 0x0c, 0x6b, 0x3e, 0xff, 0x17, 0x81, 0x56, 0xff, 0x16, 0x8c, 0x5f, 0xff, 0x13, 0x92, 0x65, 0xff, 0x0f, 0x93, 0x65, 0xff, 0x12, 0x94, 0x64, 0xff, 0x17, 0x99, 0x65, 0xff, 0x10, 0x94, 0x5c, 0xff, 0x0d, 0x95, 0x5f, 0xff, 0x09, 0x95, 0x64, 0xff, 0x0f, 0x95, 0x65, 0xff, 0x0f, 0x93, 0x65, 0xff, 0x0d, 0x94, 0x64, 0xff, 0x06, 0x95, 0x64, 0xff, 0x06, 0x96, 0x62, 0xff, 0x0c, 0x98, 0x64, 0xff, 0x15, 0x94, 0x63, 0xff, 0x1f, 0x8a, 0x60, 0xff, 0x18, 0x77, 0x4e, 0xff, 0x0f, 0x63, 0x3c, 0xff, 0x06, 0x4c, 0x2a, 0xff, 0x03, 0x42, 0x22, 0xff, 0x01, 0x3d, 0x1d, 0xff, 0x01, 0x3d, 0x1c, 0xff, 0x00, 0x39, 0x18, 0xff, 0x04, 0x3b, 0x1c, 0xff, 0x01, 0x3b, 0x19, 0xff, 0x03, 0x45, 0x1d, 0xff, 0x16, 0x6f, 0x42, 0xff, 0x1e, 0x86, 0x57, 0xff, 0x15, 0x7f, 0x52, 0xff, 0x18, 0x74, 0x4b, 0xff, 0x06, 0x46, 0x24, 0xff, 0x01, 0x31, 0x13, 0xff, 0x03, 0x3d, 0x21, 0xff, 0x0b, 0x44, 0x29, 0xff, 0x05, 0x34, 0x1c, 0xff, 0x00, 0x2a, 0x12, 0xff, 0x00, 0x2a, 0x14, 0xff, 0x02, 0x2c, 0x17, 0xff, 0x01, 0x22, 0x10, 0xff, 0x04, 0x24, 0x0b, 0xff, 0x14, 0x78, 0x4c, 0xff, 0x0d, 0x80, 0x4a, 0xff, 0x1c, 0x85, 0x4b, 0xff, 0x0f, 0x74, 0x3d, 0xff, 0x09, 0x71, 0x3d, 0xff, 0x09, 0x65, 0x34, 0xff, 0x0c, 0x6f, 0x3e, 0xff, 0x10, 0x71, 0x3d, 0xff, 0x0e, 0x69, 0x36, 0xff, 0x0d, 0x69, 0x38, 0xff, 0x04, 0x6a, 0x38, 0xff, 0x06, 0x6a, 0x38, 0xff, 0x15, 0x63, 0x38, 0xff, 0x09, 0x46, 0x24, 0xff, 0x09, 0x3e, 0x25, 0xff, 0x04, 0x31, 0x1c, 0xff, 0x01, 0x29, 0x16, 0xff, 0x07, 0x3a, 0x1e, 0xff, 0x09, 0x50, 0x25, 0xff, 0x04, 0x49, 0x21, 0xff, 0x03, 0x36, 0x1d, 0xff, 0x0b, 0x39, 0x24, 0xff, 0x04, 0x3e, 0x1e, 0xff, 0x04, 0x43, 0x22, 0xff, 0x03, 0x41, 0x24, 0xff, 0x07, 0x42, 0x25, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x08, 0x41, 0x24, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x04, 0x40, 0x21, 0xff, 0x0b, 0x4b, 0x2d, 0xff, 0x0c, 0x46, 0x2a, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x0e, 0x4f, 0x30, 0xff, 0x08, 0x4f, 0x2b, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x09, 0x50, 0x2c, 0xff, 0x07, 0x50, 0x2c, 0xff, 0x06, 0x51, 0x2c, 0xff, 0x0b, 0x50, 0x2f, 0xff, 0x0a, 0x3c, 0x23, 0xff, 0x00, 0x26, 0x0e, 0xff, 0x06, 0x53, 0x31, 0xff, 0x19, 0x97, 0x69, 0xff, 0x15, 0x99, 0x6b, 0xff, 0x0c, 0x82, 0x59, 0xff, 0x0e, 0x73, 0x44, 0xff, 0x09, 0x52, 0x27, 0xff, 0x07, 0x36, 0x19, 0xff, 0x02, 0x27, 0x17, 0xff, 0x11, 0x3d, 0x32, 0xff, 0x05, 0x24, 0x17, 0xff, 0x02, 0x26, 0x0f, 0xff, 0x1b, 0x64, 0x40, 0xff, 0x1c, 0x6e, 0x42, 0xff, 0x09, 0x48, 0x27, 0xff, 0x0a, 0x47, 0x2b, 0xff, 0x68, 0x9b, 0xae, 0xff, 0x38, 0x6f, 0x87, 0xff, 0x08, 0x5e, 0x45, 0xff, 0x11, 0x69, 0x43, 0xff, 0x0f, 0x5f, 0x3a, 0xff, 0x10, 0x59, 0x39, 0xff, 0x0b, 0x4d, 0x31, 0xff, 0x09, 0x50, 0x30, 0xff, 0x09, 0x4d, 0x2c, 0xff, 0x06, 0x3a, 0x1d, 0xff, 0x03, 0x22, 0x10, 0xff, 0x09, 0x1c, 0x11, 0xff, 0x65, 0x71, 0x69, 0xff, + 0x01, 0x28, 0x14, 0xff, 0x09, 0x3e, 0x21, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x09, 0x44, 0x23, 0xff, 0x08, 0x44, 0x22, 0xff, 0x08, 0x44, 0x23, 0xff, 0x08, 0x42, 0x24, 0xff, 0x08, 0x3a, 0x21, 0xff, 0x02, 0x2b, 0x15, 0xff, 0x01, 0x26, 0x10, 0xff, 0x05, 0x31, 0x18, 0xff, 0x0a, 0x41, 0x25, 0xff, 0x07, 0x43, 0x23, 0xff, 0x05, 0x48, 0x21, 0xff, 0x05, 0x4f, 0x29, 0xff, 0x08, 0x4a, 0x28, 0xff, 0x02, 0x35, 0x17, 0xff, 0x0c, 0x3e, 0x22, 0xff, 0x08, 0x42, 0x25, 0xff, 0x05, 0x42, 0x24, 0xff, 0x06, 0x40, 0x24, 0xff, 0x04, 0x3d, 0x28, 0xff, 0x12, 0x4b, 0x42, 0xff, 0x47, 0x7f, 0x89, 0xff, 0x70, 0xa5, 0xbe, 0xff, 0x81, 0xb2, 0xd8, 0xff, 0x7d, 0xaf, 0xdd, 0xff, 0x79, 0xaf, 0xde, 0xff, 0x6d, 0xa3, 0xd3, 0xff, 0x62, 0x96, 0xc6, 0xff, 0x66, 0x9e, 0xd1, 0xff, 0x71, 0xaa, 0xdd, 0xff, 0x6e, 0xa3, 0xd5, 0xff, 0x70, 0x9f, 0xce, 0xff, 0x81, 0xb1, 0xdf, 0xff, 0x7d, 0xb1, 0xe2, 0xff, 0x6c, 0xa1, 0xcf, 0xff, 0x2c, 0x5d, 0x72, 0xff, 0x01, 0x31, 0x22, 0xff, 0x05, 0x34, 0x19, 0xff, 0x05, 0x33, 0x18, 0xff, 0x03, 0x3b, 0x1a, 0xff, 0x04, 0x49, 0x28, 0xff, 0x0c, 0x65, 0x41, 0xff, 0x18, 0x81, 0x54, 0xff, 0x10, 0x88, 0x59, 0xff, 0x0f, 0x89, 0x5c, 0xff, 0x15, 0x8a, 0x5e, 0xff, 0x15, 0x77, 0x4d, 0xff, 0x07, 0x52, 0x23, 0xff, 0x1b, 0x7c, 0x42, 0xff, 0x0d, 0x84, 0x3c, 0xff, 0x03, 0x89, 0x39, 0xff, 0x02, 0x99, 0x3f, 0xff, 0x02, 0x9c, 0x40, 0xff, 0x03, 0x9e, 0x41, 0xff, 0x05, 0x9c, 0x42, 0xff, 0x08, 0x96, 0x45, 0xff, 0x04, 0x8a, 0x44, 0xff, 0x08, 0x8a, 0x4e, 0xff, 0x0f, 0x95, 0x5e, 0xff, 0x0e, 0x99, 0x63, 0xff, 0x0f, 0x9a, 0x64, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x0d, 0x9d, 0x67, 0xff, 0x0c, 0x9f, 0x67, 0xff, 0x0d, 0x9f, 0x68, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x11, 0xa6, 0x6a, 0xff, 0x10, 0xa5, 0x69, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x0f, 0xa2, 0x69, 0xff, 0x10, 0xa3, 0x6a, 0xff, 0x10, 0xa3, 0x6b, 0xff, 0x0f, 0xa2, 0x6a, 0xff, 0x10, 0xa2, 0x6a, 0xff, 0x10, 0xa3, 0x6a, 0xff, 0x0f, 0xa2, 0x69, 0xff, 0x0f, 0xa2, 0x6a, 0xff, 0x0f, 0xa3, 0x6a, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0f, 0xa3, 0x68, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0f, 0xa4, 0x68, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x08, 0xa0, 0x69, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x0b, 0xa8, 0x6b, 0xff, 0x0e, 0xad, 0x6e, 0xff, 0x0b, 0xae, 0x73, 0xff, 0x0f, 0xb4, 0x79, 0xff, 0x0d, 0xb0, 0x75, 0xff, 0x09, 0xac, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x29, 0xba, 0x8d, 0xff, 0x10, 0xa0, 0x75, 0xff, 0x1c, 0xb4, 0x88, 0xff, 0x1a, 0xb2, 0x87, 0xff, 0x15, 0xaa, 0x83, 0xff, 0x28, 0xba, 0x96, 0xff, 0x28, 0xb8, 0x93, 0xff, 0x0f, 0xa0, 0x77, 0xff, 0x0d, 0xa3, 0x73, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0f, 0xa9, 0x75, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x17, 0xa7, 0x7a, 0xff, 0x19, 0xa6, 0x7c, 0xff, 0x16, 0xa4, 0x7c, 0xff, 0x14, 0xa6, 0x79, 0xff, 0x11, 0xa4, 0x6c, 0xff, 0x05, 0x93, 0x50, 0xff, 0x04, 0x89, 0x41, 0xff, 0x06, 0x7d, 0x3a, 0xff, 0x05, 0x71, 0x33, 0xff, 0x02, 0x68, 0x2e, 0xff, 0x01, 0x6b, 0x30, 0xff, 0x06, 0x80, 0x40, 0xff, 0x0c, 0x8a, 0x43, 0xff, 0x11, 0x90, 0x45, 0xff, 0x12, 0x9a, 0x4f, 0xff, 0x18, 0x9e, 0x56, 0xff, 0x13, 0x8f, 0x4c, 0xff, 0x11, 0x7a, 0x40, 0xff, 0x0b, 0x63, 0x35, 0xff, 0x03, 0x5a, 0x31, 0xff, 0x1b, 0x7c, 0x52, 0xff, 0x0b, 0x67, 0x3b, 0xff, 0x03, 0x55, 0x29, 0xff, 0x02, 0x4d, 0x28, 0xff, 0x01, 0x48, 0x22, 0xff, 0x01, 0x4b, 0x23, 0xff, 0x05, 0x5e, 0x31, 0xff, 0x06, 0x6f, 0x3d, 0xff, 0x04, 0x71, 0x3b, 0xff, 0x06, 0x6e, 0x37, 0xff, 0x06, 0x6c, 0x35, 0xff, 0x06, 0x71, 0x3b, 0xff, 0x06, 0x71, 0x3e, 0xff, 0x08, 0x72, 0x41, 0xff, 0x0e, 0x6f, 0x43, 0xff, 0x0a, 0x64, 0x39, 0xff, 0x07, 0x62, 0x38, 0xff, 0x14, 0x7a, 0x4f, 0xff, 0x1f, 0x91, 0x63, 0xff, 0x17, 0x94, 0x63, 0xff, 0x0f, 0x96, 0x64, 0xff, 0x0c, 0x96, 0x64, 0xff, 0x12, 0x92, 0x62, 0xff, 0x06, 0x74, 0x48, 0xff, 0x10, 0x77, 0x4c, 0xff, 0x18, 0x86, 0x5b, 0xff, 0x17, 0x91, 0x64, 0xff, 0x13, 0x92, 0x65, 0xff, 0x15, 0x92, 0x65, 0xff, 0x18, 0x92, 0x66, 0xff, 0x19, 0x92, 0x64, 0xff, 0x16, 0x8f, 0x61, 0xff, 0x18, 0x8a, 0x5e, 0xff, 0x13, 0x7e, 0x53, 0xff, 0x08, 0x65, 0x3c, 0xff, 0x08, 0x50, 0x2d, 0xff, 0x03, 0x42, 0x21, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x01, 0x3b, 0x1c, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x02, 0x40, 0x21, 0xff, 0x03, 0x45, 0x26, 0xff, 0x03, 0x4a, 0x29, 0xff, 0x03, 0x4e, 0x2a, 0xff, 0x13, 0x63, 0x3b, 0xff, 0x1d, 0x76, 0x48, 0xff, 0x13, 0x7d, 0x47, 0xff, 0x0b, 0x7b, 0x43, 0xff, 0x07, 0x70, 0x3f, 0xff, 0x07, 0x61, 0x38, 0xff, 0x03, 0x49, 0x27, 0xff, 0x08, 0x44, 0x27, 0xff, 0x08, 0x43, 0x26, 0xff, 0x05, 0x40, 0x24, 0xff, 0x01, 0x37, 0x1e, 0xff, 0x00, 0x2d, 0x16, 0xff, 0x01, 0x26, 0x12, 0xff, 0x05, 0x2a, 0x16, 0xff, 0x01, 0x27, 0x13, 0xff, 0x01, 0x23, 0x08, 0xff, 0x16, 0x83, 0x56, 0xff, 0x09, 0x76, 0x42, 0xff, 0x17, 0x78, 0x41, 0xff, 0x0e, 0x73, 0x3e, 0xff, 0x08, 0x70, 0x3d, 0xff, 0x09, 0x64, 0x33, 0xff, 0x10, 0x72, 0x3e, 0xff, 0x0e, 0x70, 0x3a, 0xff, 0x0e, 0x69, 0x36, 0xff, 0x0e, 0x69, 0x38, 0xff, 0x07, 0x6a, 0x37, 0xff, 0x0d, 0x6a, 0x38, 0xff, 0x15, 0x58, 0x2f, 0xff, 0x04, 0x38, 0x17, 0xff, 0x09, 0x42, 0x28, 0xff, 0x02, 0x32, 0x1b, 0xff, 0x02, 0x2b, 0x16, 0xff, 0x06, 0x37, 0x1c, 0xff, 0x09, 0x4b, 0x24, 0xff, 0x01, 0x3f, 0x1b, 0xff, 0x06, 0x37, 0x21, 0xff, 0x0b, 0x39, 0x25, 0xff, 0x02, 0x3e, 0x1c, 0xff, 0x04, 0x43, 0x22, 0xff, 0x06, 0x42, 0x25, 0xff, 0x08, 0x42, 0x25, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x06, 0x41, 0x24, 0xff, 0x0a, 0x48, 0x2a, 0xff, 0x08, 0x4a, 0x2b, 0xff, 0x0b, 0x44, 0x28, 0xff, 0x03, 0x39, 0x1c, 0xff, 0x0e, 0x4d, 0x2e, 0xff, 0x0a, 0x50, 0x2d, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x09, 0x50, 0x2c, 0xff, 0x06, 0x50, 0x2c, 0xff, 0x04, 0x51, 0x2c, 0xff, 0x0b, 0x4f, 0x2e, 0xff, 0x07, 0x35, 0x1d, 0xff, 0x00, 0x28, 0x11, 0xff, 0x06, 0x59, 0x36, 0xff, 0x1a, 0x9a, 0x6b, 0xff, 0x14, 0x94, 0x65, 0xff, 0x0e, 0x80, 0x57, 0xff, 0x09, 0x6c, 0x3e, 0xff, 0x07, 0x4e, 0x24, 0xff, 0x04, 0x31, 0x17, 0xff, 0x06, 0x2d, 0x21, 0xff, 0x0f, 0x3e, 0x33, 0xff, 0x03, 0x22, 0x13, 0xff, 0x05, 0x2f, 0x16, 0xff, 0x1e, 0x6d, 0x45, 0xff, 0x0e, 0x60, 0x36, 0xff, 0x05, 0x3e, 0x21, 0xff, 0x0a, 0x46, 0x28, 0xff, 0x52, 0x82, 0x93, 0xff, 0x30, 0x64, 0x7c, 0xff, 0x08, 0x61, 0x40, 0xff, 0x0f, 0x6a, 0x3c, 0xff, 0x12, 0x62, 0x40, 0xff, 0x08, 0x4f, 0x33, 0xff, 0x0c, 0x4e, 0x32, 0xff, 0x08, 0x50, 0x2f, 0xff, 0x0a, 0x4d, 0x2c, 0xff, 0x05, 0x38, 0x1b, 0xff, 0x03, 0x21, 0x0f, 0xff, 0x09, 0x1d, 0x11, 0xff, 0x63, 0x71, 0x69, 0xff, + 0x01, 0x27, 0x13, 0xff, 0x08, 0x3c, 0x21, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x09, 0x43, 0x24, 0xff, 0x07, 0x43, 0x23, 0xff, 0x08, 0x43, 0x23, 0xff, 0x08, 0x40, 0x23, 0xff, 0x0a, 0x3c, 0x22, 0xff, 0x03, 0x2e, 0x16, 0xff, 0x01, 0x26, 0x0f, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x0a, 0x40, 0x25, 0xff, 0x07, 0x42, 0x23, 0xff, 0x03, 0x45, 0x20, 0xff, 0x05, 0x4c, 0x27, 0xff, 0x0a, 0x4b, 0x29, 0xff, 0x03, 0x37, 0x19, 0xff, 0x0c, 0x3d, 0x22, 0xff, 0x09, 0x42, 0x26, 0xff, 0x04, 0x41, 0x26, 0xff, 0x05, 0x3f, 0x2b, 0xff, 0x1d, 0x53, 0x51, 0xff, 0x4d, 0x83, 0x8c, 0xff, 0x78, 0xaf, 0xca, 0xff, 0x7d, 0xb2, 0xd9, 0xff, 0x7c, 0xaf, 0xde, 0xff, 0x7a, 0xaf, 0xe0, 0xff, 0x6d, 0xa7, 0xd5, 0xff, 0x60, 0x99, 0xc7, 0xff, 0x71, 0xa3, 0xd7, 0xff, 0x74, 0xaa, 0xde, 0xff, 0x6d, 0xa4, 0xd7, 0xff, 0x71, 0xa3, 0xd5, 0xff, 0x86, 0xb2, 0xe1, 0xff, 0x81, 0xb0, 0xdc, 0xff, 0x75, 0xaa, 0xd6, 0xff, 0x6a, 0xa0, 0xca, 0xff, 0x39, 0x69, 0x7d, 0xff, 0x02, 0x2f, 0x23, 0xff, 0x09, 0x33, 0x1c, 0xff, 0x0d, 0x31, 0x1a, 0xff, 0x07, 0x33, 0x18, 0xff, 0x01, 0x35, 0x17, 0xff, 0x02, 0x42, 0x22, 0xff, 0x0d, 0x61, 0x3a, 0xff, 0x13, 0x82, 0x56, 0xff, 0x10, 0x88, 0x5d, 0xff, 0x0d, 0x8b, 0x60, 0xff, 0x14, 0x88, 0x5e, 0xff, 0x0f, 0x68, 0x3a, 0xff, 0x09, 0x58, 0x22, 0xff, 0x1d, 0x91, 0x4e, 0xff, 0x0b, 0x91, 0x43, 0xff, 0x01, 0x99, 0x3e, 0xff, 0x02, 0x9e, 0x41, 0xff, 0x04, 0xa3, 0x44, 0xff, 0x04, 0xa0, 0x42, 0xff, 0x05, 0x9a, 0x44, 0xff, 0x06, 0x96, 0x49, 0xff, 0x02, 0x8a, 0x48, 0xff, 0x07, 0x92, 0x53, 0xff, 0x10, 0x9b, 0x61, 0xff, 0x11, 0x9d, 0x64, 0xff, 0x11, 0x9d, 0x66, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x0f, 0x9e, 0x68, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x0e, 0xa0, 0x69, 0xff, 0x0e, 0xa1, 0x69, 0xff, 0x0f, 0xa4, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x10, 0xa5, 0x69, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x10, 0xa2, 0x6a, 0xff, 0x12, 0xa4, 0x6d, 0xff, 0x12, 0xa4, 0x6d, 0xff, 0x11, 0xa3, 0x6c, 0xff, 0x10, 0xa2, 0x6b, 0xff, 0x10, 0xa3, 0x6b, 0xff, 0x0f, 0xa2, 0x6a, 0xff, 0x0f, 0xa2, 0x6a, 0xff, 0x10, 0xa2, 0x6a, 0xff, 0x0f, 0xa3, 0x68, 0xff, 0x0f, 0xa3, 0x68, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa9, 0x6d, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x0b, 0xb1, 0x77, 0xff, 0x0c, 0xb3, 0x78, 0xff, 0x09, 0xaf, 0x73, 0xff, 0x04, 0xa6, 0x6b, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x13, 0xa7, 0x74, 0xff, 0x0f, 0xa1, 0x70, 0xff, 0x20, 0xb8, 0x8a, 0xff, 0x22, 0xb8, 0x8f, 0xff, 0x27, 0xb7, 0x95, 0xff, 0x1a, 0xa7, 0x88, 0xff, 0x0e, 0x9d, 0x7a, 0xff, 0x0d, 0xa0, 0x76, 0xff, 0x0a, 0xa2, 0x70, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x12, 0xa7, 0x76, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x0f, 0xa3, 0x70, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x13, 0xab, 0x78, 0xff, 0x13, 0xa9, 0x79, 0xff, 0x19, 0xa7, 0x7b, 0xff, 0x1c, 0xa7, 0x7c, 0xff, 0x17, 0xa7, 0x7b, 0xff, 0x14, 0xaa, 0x79, 0xff, 0x0c, 0xa6, 0x69, 0xff, 0x0f, 0xa6, 0x60, 0xff, 0x09, 0x9b, 0x53, 0xff, 0x0d, 0x8f, 0x4d, 0xff, 0x0f, 0x81, 0x43, 0xff, 0x07, 0x73, 0x39, 0xff, 0x03, 0x6c, 0x30, 0xff, 0x16, 0x8f, 0x4f, 0xff, 0x21, 0xa5, 0x5f, 0xff, 0x1c, 0xa1, 0x57, 0xff, 0x0e, 0x97, 0x4d, 0xff, 0x09, 0x8d, 0x46, 0xff, 0x08, 0x7e, 0x3e, 0xff, 0x0c, 0x70, 0x38, 0xff, 0x06, 0x5a, 0x2f, 0xff, 0x02, 0x5b, 0x33, 0xff, 0x0b, 0x67, 0x40, 0xff, 0x02, 0x4b, 0x25, 0xff, 0x02, 0x44, 0x20, 0xff, 0x06, 0x4f, 0x2f, 0xff, 0x09, 0x53, 0x32, 0xff, 0x03, 0x4b, 0x28, 0xff, 0x01, 0x4b, 0x23, 0xff, 0x02, 0x58, 0x2d, 0xff, 0x03, 0x62, 0x33, 0xff, 0x03, 0x62, 0x31, 0xff, 0x03, 0x73, 0x3f, 0xff, 0x03, 0x7f, 0x48, 0xff, 0x0e, 0x87, 0x53, 0xff, 0x19, 0x8f, 0x5e, 0xff, 0x1e, 0x95, 0x67, 0xff, 0x1a, 0x92, 0x65, 0xff, 0x14, 0x90, 0x62, 0xff, 0x18, 0x97, 0x68, 0xff, 0x17, 0x96, 0x65, 0xff, 0x13, 0x97, 0x64, 0xff, 0x0e, 0x99, 0x64, 0xff, 0x0d, 0x98, 0x64, 0xff, 0x15, 0x95, 0x64, 0xff, 0x0f, 0x7d, 0x51, 0xff, 0x02, 0x5a, 0x33, 0xff, 0x07, 0x5c, 0x36, 0xff, 0x0c, 0x6d, 0x48, 0xff, 0x11, 0x74, 0x4d, 0xff, 0x17, 0x7a, 0x52, 0xff, 0x19, 0x7c, 0x54, 0xff, 0x16, 0x76, 0x4d, 0xff, 0x10, 0x6b, 0x43, 0xff, 0x0c, 0x5a, 0x36, 0xff, 0x07, 0x49, 0x25, 0xff, 0x00, 0x38, 0x17, 0xff, 0x00, 0x35, 0x16, 0xff, 0x00, 0x3c, 0x1d, 0xff, 0x01, 0x42, 0x21, 0xff, 0x04, 0x4e, 0x2d, 0xff, 0x0b, 0x5c, 0x3a, 0xff, 0x13, 0x6b, 0x49, 0xff, 0x16, 0x75, 0x51, 0xff, 0x15, 0x7b, 0x56, 0xff, 0x11, 0x7d, 0x52, 0xff, 0x1f, 0x85, 0x59, 0xff, 0x15, 0x78, 0x48, 0xff, 0x05, 0x72, 0x3b, 0xff, 0x0b, 0x7a, 0x44, 0xff, 0x10, 0x71, 0x42, 0xff, 0x07, 0x57, 0x30, 0xff, 0x06, 0x4b, 0x2a, 0xff, 0x08, 0x49, 0x2a, 0xff, 0x07, 0x49, 0x2b, 0xff, 0x05, 0x49, 0x2c, 0xff, 0x04, 0x49, 0x2c, 0xff, 0x08, 0x45, 0x2a, 0xff, 0x04, 0x32, 0x1a, 0xff, 0x03, 0x2a, 0x15, 0xff, 0x01, 0x2a, 0x15, 0xff, 0x01, 0x29, 0x0a, 0xff, 0x17, 0x87, 0x58, 0xff, 0x09, 0x72, 0x3f, 0xff, 0x15, 0x72, 0x3c, 0xff, 0x0c, 0x72, 0x3d, 0xff, 0x08, 0x6e, 0x3b, 0xff, 0x08, 0x64, 0x32, 0xff, 0x12, 0x73, 0x3f, 0xff, 0x0a, 0x6e, 0x38, 0xff, 0x0f, 0x69, 0x36, 0xff, 0x10, 0x6a, 0x39, 0xff, 0x0a, 0x6b, 0x39, 0xff, 0x12, 0x6a, 0x3a, 0xff, 0x13, 0x4e, 0x28, 0xff, 0x01, 0x2d, 0x0e, 0xff, 0x05, 0x3f, 0x26, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x02, 0x2c, 0x17, 0xff, 0x07, 0x34, 0x1a, 0xff, 0x08, 0x46, 0x21, 0xff, 0x00, 0x37, 0x17, 0xff, 0x09, 0x3b, 0x25, 0xff, 0x08, 0x37, 0x22, 0xff, 0x01, 0x3b, 0x1b, 0xff, 0x07, 0x43, 0x24, 0xff, 0x09, 0x43, 0x26, 0xff, 0x06, 0x3e, 0x21, 0xff, 0x01, 0x35, 0x18, 0xff, 0x04, 0x3c, 0x1f, 0xff, 0x0c, 0x4a, 0x2c, 0xff, 0x09, 0x4a, 0x2a, 0xff, 0x06, 0x4a, 0x29, 0xff, 0x0d, 0x47, 0x2a, 0xff, 0x03, 0x37, 0x1c, 0xff, 0x0c, 0x4a, 0x2b, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x0b, 0x50, 0x2d, 0xff, 0x0b, 0x51, 0x2d, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x07, 0x50, 0x2c, 0xff, 0x03, 0x51, 0x2b, 0xff, 0x0a, 0x4e, 0x2e, 0xff, 0x05, 0x30, 0x1a, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x08, 0x5c, 0x39, 0xff, 0x1b, 0x9c, 0x6d, 0xff, 0x12, 0x91, 0x63, 0xff, 0x0e, 0x7f, 0x55, 0xff, 0x06, 0x66, 0x38, 0xff, 0x06, 0x4b, 0x22, 0xff, 0x02, 0x2d, 0x14, 0xff, 0x0b, 0x33, 0x27, 0xff, 0x11, 0x3e, 0x33, 0xff, 0x03, 0x21, 0x11, 0xff, 0x0a, 0x36, 0x1d, 0xff, 0x17, 0x66, 0x3d, 0xff, 0x0c, 0x5a, 0x36, 0xff, 0x09, 0x3d, 0x27, 0xff, 0x0c, 0x48, 0x28, 0xff, 0x27, 0x61, 0x5d, 0xff, 0x1f, 0x5b, 0x5b, 0xff, 0x09, 0x64, 0x37, 0xff, 0x0d, 0x6a, 0x3b, 0xff, 0x13, 0x63, 0x45, 0xff, 0x04, 0x49, 0x31, 0xff, 0x0c, 0x4f, 0x32, 0xff, 0x09, 0x51, 0x30, 0xff, 0x0a, 0x50, 0x2d, 0xff, 0x08, 0x3e, 0x21, 0xff, 0x04, 0x21, 0x0f, 0xff, 0x09, 0x1d, 0x10, 0xff, 0x61, 0x6f, 0x67, 0xff, + 0x00, 0x25, 0x14, 0xff, 0x08, 0x38, 0x1f, 0xff, 0x0b, 0x41, 0x24, 0xff, 0x0a, 0x43, 0x24, 0xff, 0x08, 0x43, 0x24, 0xff, 0x09, 0x43, 0x25, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0b, 0x41, 0x24, 0xff, 0x0b, 0x40, 0x23, 0xff, 0x0b, 0x3d, 0x21, 0xff, 0x08, 0x35, 0x1a, 0xff, 0x00, 0x27, 0x0c, 0xff, 0x00, 0x2c, 0x11, 0xff, 0x0c, 0x3e, 0x22, 0xff, 0x08, 0x43, 0x24, 0xff, 0x02, 0x43, 0x22, 0xff, 0x09, 0x48, 0x26, 0xff, 0x11, 0x4a, 0x28, 0xff, 0x06, 0x37, 0x1a, 0xff, 0x07, 0x3a, 0x23, 0xff, 0x06, 0x3d, 0x2b, 0xff, 0x10, 0x4b, 0x3e, 0xff, 0x35, 0x6f, 0x73, 0xff, 0x6b, 0xa0, 0xbe, 0xff, 0x7b, 0xb0, 0xd1, 0xff, 0x7c, 0xb0, 0xd9, 0xff, 0x7a, 0xae, 0xdd, 0xff, 0x76, 0xab, 0xdd, 0xff, 0x69, 0xa0, 0xd3, 0xff, 0x60, 0x99, 0xcd, 0xff, 0x6a, 0xa3, 0xd4, 0xff, 0x6f, 0xa7, 0xd5, 0xff, 0x6c, 0xa3, 0xd2, 0xff, 0x78, 0xab, 0xda, 0xff, 0x84, 0xb1, 0xe1, 0xff, 0x77, 0x9f, 0xd1, 0xff, 0x2a, 0x54, 0x87, 0xff, 0x5b, 0x8d, 0xbe, 0xff, 0x79, 0xac, 0xd7, 0xff, 0x36, 0x6c, 0x75, 0xff, 0x00, 0x37, 0x21, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x0b, 0x32, 0x1a, 0xff, 0x06, 0x32, 0x19, 0xff, 0x01, 0x35, 0x1d, 0xff, 0x01, 0x34, 0x19, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x03, 0x4f, 0x2d, 0xff, 0x0d, 0x6a, 0x45, 0xff, 0x16, 0x83, 0x5c, 0xff, 0x16, 0x88, 0x5e, 0xff, 0x18, 0x8a, 0x5b, 0xff, 0x0e, 0x72, 0x40, 0xff, 0x09, 0x62, 0x2c, 0xff, 0x1f, 0x8f, 0x50, 0xff, 0x0c, 0x9f, 0x44, 0xff, 0x04, 0x9c, 0x3e, 0xff, 0x09, 0xa4, 0x46, 0xff, 0x06, 0xa3, 0x44, 0xff, 0x01, 0x9d, 0x41, 0xff, 0x01, 0x9b, 0x42, 0xff, 0x03, 0x9a, 0x46, 0xff, 0x03, 0x98, 0x48, 0xff, 0x06, 0x99, 0x53, 0xff, 0x0b, 0x9f, 0x5b, 0xff, 0x0f, 0xa3, 0x63, 0xff, 0x0f, 0xa4, 0x66, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0d, 0xa5, 0x6d, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa6, 0x6a, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0d, 0xa4, 0x65, 0xff, 0x0f, 0xa3, 0x65, 0xff, 0x11, 0xa4, 0x65, 0xff, 0x0e, 0xa2, 0x64, 0xff, 0x0e, 0xa3, 0x67, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0f, 0xa4, 0x6b, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x70, 0xff, 0x08, 0xac, 0x71, 0xff, 0x07, 0xad, 0x6f, 0xff, 0x04, 0xa8, 0x69, 0xff, 0x01, 0xa1, 0x63, 0xff, 0x04, 0xa0, 0x65, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x1c, 0xb1, 0x7f, 0xff, 0x1a, 0xac, 0x7e, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x3e, 0xca, 0xa7, 0xff, 0x44, 0xc3, 0xab, 0xff, 0x18, 0x97, 0x81, 0xff, 0x0b, 0x99, 0x75, 0xff, 0x0a, 0xa3, 0x73, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x70, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x72, 0xff, 0x10, 0xa3, 0x74, 0xff, 0x10, 0xa3, 0x75, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x15, 0xa6, 0x7e, 0xff, 0x18, 0xa6, 0x7f, 0xff, 0x18, 0xa8, 0x7f, 0xff, 0x14, 0xa6, 0x7a, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x15, 0xae, 0x76, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x15, 0xaa, 0x7b, 0xff, 0x18, 0xa7, 0x7a, 0xff, 0x0f, 0x96, 0x67, 0xff, 0x12, 0x98, 0x65, 0xff, 0x19, 0xaf, 0x72, 0xff, 0x0c, 0xaf, 0x6a, 0xff, 0x10, 0xba, 0x6c, 0xff, 0x16, 0xc0, 0x6e, 0xff, 0x0b, 0xa4, 0x59, 0xff, 0x0a, 0x8c, 0x4b, 0xff, 0x0e, 0x7d, 0x3e, 0xff, 0x0b, 0x74, 0x35, 0xff, 0x0b, 0x80, 0x3e, 0xff, 0x23, 0xa9, 0x64, 0xff, 0x0b, 0x98, 0x51, 0xff, 0x04, 0x89, 0x45, 0xff, 0x07, 0x82, 0x3e, 0xff, 0x06, 0x7b, 0x3a, 0xff, 0x09, 0x70, 0x38, 0xff, 0x0a, 0x66, 0x36, 0xff, 0x01, 0x55, 0x2e, 0xff, 0x13, 0x7e, 0x57, 0xff, 0x16, 0x90, 0x69, 0xff, 0x12, 0x86, 0x5f, 0xff, 0x1b, 0x8a, 0x63, 0xff, 0x20, 0x99, 0x71, 0xff, 0x22, 0x9d, 0x73, 0xff, 0x18, 0x94, 0x69, 0xff, 0x12, 0x8e, 0x61, 0xff, 0x0e, 0x8b, 0x5d, 0xff, 0x13, 0x92, 0x62, 0xff, 0x15, 0x94, 0x64, 0xff, 0x16, 0x9c, 0x69, 0xff, 0x0f, 0x9d, 0x68, 0xff, 0x10, 0x9e, 0x69, 0xff, 0x10, 0x9c, 0x68, 0xff, 0x0e, 0x9b, 0x67, 0xff, 0x0f, 0x9b, 0x67, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x0d, 0x99, 0x64, 0xff, 0x10, 0x99, 0x65, 0xff, 0x0d, 0x99, 0x65, 0xff, 0x0b, 0x98, 0x65, 0xff, 0x0f, 0x97, 0x65, 0xff, 0x17, 0x95, 0x66, 0xff, 0x12, 0x7e, 0x53, 0xff, 0x08, 0x5c, 0x33, 0xff, 0x03, 0x4b, 0x25, 0xff, 0x02, 0x41, 0x1f, 0xff, 0x01, 0x3f, 0x1e, 0xff, 0x01, 0x3d, 0x1c, 0xff, 0x01, 0x3c, 0x1b, 0xff, 0x00, 0x39, 0x19, 0xff, 0x00, 0x37, 0x17, 0xff, 0x01, 0x3b, 0x19, 0xff, 0x04, 0x4a, 0x28, 0xff, 0x0a, 0x5f, 0x3b, 0xff, 0x10, 0x73, 0x4d, 0xff, 0x14, 0x7f, 0x56, 0xff, 0x18, 0x8c, 0x61, 0xff, 0x18, 0x92, 0x65, 0xff, 0x15, 0x92, 0x63, 0xff, 0x13, 0x90, 0x5f, 0xff, 0x0d, 0x85, 0x54, 0xff, 0x0b, 0x79, 0x49, 0xff, 0x0a, 0x75, 0x48, 0xff, 0x13, 0x7e, 0x53, 0xff, 0x1d, 0x88, 0x5f, 0xff, 0x16, 0x7b, 0x54, 0xff, 0x05, 0x56, 0x32, 0xff, 0x02, 0x49, 0x28, 0xff, 0x0a, 0x4f, 0x2e, 0xff, 0x07, 0x5a, 0x39, 0xff, 0x0c, 0x69, 0x47, 0xff, 0x12, 0x77, 0x53, 0xff, 0x1d, 0x87, 0x61, 0xff, 0x24, 0x89, 0x65, 0xff, 0x1a, 0x70, 0x4f, 0xff, 0x09, 0x4f, 0x2f, 0xff, 0x00, 0x35, 0x16, 0xff, 0x01, 0x39, 0x10, 0xff, 0x1e, 0x89, 0x56, 0xff, 0x0e, 0x6f, 0x3d, 0xff, 0x0f, 0x6f, 0x39, 0xff, 0x09, 0x73, 0x3b, 0xff, 0x0c, 0x6d, 0x39, 0xff, 0x08, 0x66, 0x34, 0xff, 0x0f, 0x71, 0x40, 0xff, 0x07, 0x6c, 0x39, 0xff, 0x12, 0x69, 0x37, 0xff, 0x14, 0x69, 0x37, 0xff, 0x09, 0x6a, 0x39, 0xff, 0x11, 0x68, 0x3c, 0xff, 0x0a, 0x40, 0x1e, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x05, 0x3d, 0x25, 0xff, 0x01, 0x35, 0x1e, 0xff, 0x03, 0x2c, 0x16, 0xff, 0x0a, 0x31, 0x19, 0xff, 0x05, 0x36, 0x1b, 0xff, 0x00, 0x38, 0x1b, 0xff, 0x07, 0x3f, 0x24, 0xff, 0x04, 0x35, 0x1d, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x0d, 0x3f, 0x26, 0xff, 0x0a, 0x3c, 0x20, 0xff, 0x02, 0x33, 0x15, 0xff, 0x07, 0x40, 0x21, 0xff, 0x0b, 0x4a, 0x2c, 0xff, 0x08, 0x4d, 0x2d, 0xff, 0x05, 0x4e, 0x29, 0xff, 0x02, 0x4c, 0x23, 0xff, 0x0b, 0x47, 0x28, 0xff, 0x05, 0x3c, 0x21, 0xff, 0x0e, 0x4c, 0x2e, 0xff, 0x0c, 0x52, 0x2e, 0xff, 0x0a, 0x52, 0x2d, 0xff, 0x0a, 0x54, 0x2d, 0xff, 0x0b, 0x52, 0x2d, 0xff, 0x0c, 0x52, 0x2f, 0xff, 0x0a, 0x54, 0x2b, 0xff, 0x12, 0x4f, 0x31, 0xff, 0x04, 0x2d, 0x1b, 0xff, 0x00, 0x2d, 0x16, 0xff, 0x0d, 0x61, 0x3c, 0xff, 0x1a, 0x9b, 0x6c, 0xff, 0x0a, 0x90, 0x62, 0xff, 0x0f, 0x7b, 0x4f, 0xff, 0x06, 0x62, 0x32, 0xff, 0x05, 0x45, 0x1d, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x0e, 0x3a, 0x2b, 0xff, 0x0e, 0x37, 0x2d, 0xff, 0x01, 0x20, 0x11, 0xff, 0x0e, 0x3d, 0x26, 0xff, 0x06, 0x4e, 0x2b, 0xff, 0x0c, 0x4c, 0x2e, 0xff, 0x04, 0x34, 0x20, 0xff, 0x0a, 0x48, 0x2d, 0xff, 0x10, 0x65, 0x3d, 0xff, 0x0e, 0x60, 0x31, 0xff, 0x0d, 0x62, 0x35, 0xff, 0x0a, 0x67, 0x42, 0xff, 0x0d, 0x62, 0x41, 0xff, 0x02, 0x4a, 0x2c, 0xff, 0x0d, 0x51, 0x34, 0xff, 0x08, 0x4e, 0x2f, 0xff, 0x08, 0x52, 0x30, 0xff, 0x0d, 0x46, 0x29, 0xff, 0x03, 0x23, 0x0e, 0xff, 0x05, 0x1d, 0x0e, 0xff, 0x64, 0x6f, 0x68, 0xff, + 0x00, 0x25, 0x14, 0xff, 0x08, 0x36, 0x1e, 0xff, 0x0d, 0x42, 0x25, 0xff, 0x09, 0x43, 0x24, 0xff, 0x08, 0x43, 0x24, 0xff, 0x08, 0x42, 0x24, 0xff, 0x08, 0x42, 0x24, 0xff, 0x0a, 0x42, 0x23, 0xff, 0x0a, 0x41, 0x23, 0xff, 0x0a, 0x3d, 0x21, 0xff, 0x0a, 0x38, 0x1d, 0xff, 0x01, 0x29, 0x0f, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x0a, 0x3b, 0x21, 0xff, 0x08, 0x40, 0x27, 0xff, 0x05, 0x41, 0x27, 0xff, 0x08, 0x43, 0x23, 0xff, 0x0e, 0x47, 0x22, 0xff, 0x03, 0x36, 0x14, 0xff, 0x04, 0x3a, 0x26, 0xff, 0x16, 0x4e, 0x49, 0xff, 0x45, 0x7e, 0x89, 0xff, 0x66, 0x9d, 0xb7, 0xff, 0x77, 0xab, 0xd3, 0xff, 0x75, 0xab, 0xd4, 0xff, 0x78, 0xae, 0xdc, 0xff, 0x73, 0xa9, 0xda, 0xff, 0x66, 0x9c, 0xcf, 0xff, 0x60, 0x97, 0xcc, 0xff, 0x6a, 0xa0, 0xd5, 0xff, 0x6b, 0xa2, 0xd4, 0xff, 0x6c, 0xa3, 0xd0, 0xff, 0x78, 0xac, 0xd9, 0xff, 0x80, 0xb0, 0xe0, 0xff, 0x85, 0xb0, 0xe2, 0xff, 0x59, 0x80, 0xb4, 0xff, 0x06, 0x2c, 0x61, 0xff, 0x42, 0x70, 0xa5, 0xff, 0x74, 0xa7, 0xd4, 0xff, 0x32, 0x74, 0x79, 0xff, 0x06, 0x52, 0x37, 0xff, 0x04, 0x46, 0x2b, 0xff, 0x05, 0x3d, 0x20, 0xff, 0x01, 0x36, 0x19, 0xff, 0x00, 0x33, 0x1b, 0xff, 0x03, 0x34, 0x19, 0xff, 0x08, 0x33, 0x1a, 0xff, 0x02, 0x37, 0x1c, 0xff, 0x02, 0x42, 0x23, 0xff, 0x0d, 0x61, 0x3e, 0xff, 0x17, 0x79, 0x53, 0xff, 0x1b, 0x88, 0x5c, 0xff, 0x1d, 0x8a, 0x5b, 0xff, 0x0d, 0x6d, 0x3b, 0xff, 0x0b, 0x71, 0x38, 0xff, 0x0f, 0x9f, 0x4f, 0xff, 0x09, 0xa0, 0x49, 0xff, 0x05, 0xa2, 0x45, 0xff, 0x03, 0xa8, 0x46, 0xff, 0x00, 0xa1, 0x3f, 0xff, 0x00, 0x9c, 0x3e, 0xff, 0x02, 0x9c, 0x41, 0xff, 0x02, 0x9a, 0x45, 0xff, 0x04, 0x97, 0x4b, 0xff, 0x09, 0x9c, 0x53, 0xff, 0x0d, 0xa1, 0x5d, 0xff, 0x0e, 0xa2, 0x63, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x0d, 0xa6, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x11, 0xa4, 0x6a, 0xff, 0x10, 0xa4, 0x69, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0e, 0xa3, 0x64, 0xff, 0x0f, 0xa3, 0x64, 0xff, 0x0f, 0xa2, 0x64, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x10, 0xa4, 0x6c, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x06, 0xa8, 0x6d, 0xff, 0x04, 0xa7, 0x6a, 0xff, 0x03, 0xa4, 0x65, 0xff, 0x02, 0xa1, 0x63, 0xff, 0x05, 0x9f, 0x63, 0xff, 0x1d, 0xb3, 0x7c, 0xff, 0x30, 0xc2, 0x90, 0xff, 0x25, 0xb5, 0x87, 0xff, 0x08, 0x98, 0x6a, 0xff, 0x27, 0xaf, 0x89, 0xff, 0x31, 0xac, 0x93, 0xff, 0x25, 0xa1, 0x88, 0xff, 0x1a, 0xa6, 0x80, 0xff, 0x14, 0xae, 0x7c, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0f, 0xa4, 0x75, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x15, 0xa6, 0x7a, 0xff, 0x14, 0xa8, 0x7c, 0xff, 0x15, 0xa9, 0x7e, 0xff, 0x17, 0xa8, 0x81, 0xff, 0x19, 0xa8, 0x83, 0xff, 0x1d, 0xaa, 0x85, 0xff, 0x25, 0xb3, 0x8d, 0xff, 0x18, 0xa9, 0x7e, 0xff, 0x14, 0xa7, 0x79, 0xff, 0x10, 0xa3, 0x70, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x0f, 0xa4, 0x74, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x11, 0xa7, 0x78, 0xff, 0x14, 0xa9, 0x7d, 0xff, 0x18, 0xa9, 0x7d, 0xff, 0x10, 0x97, 0x68, 0xff, 0x05, 0x83, 0x50, 0xff, 0x0d, 0x90, 0x54, 0xff, 0x0f, 0x9f, 0x5c, 0xff, 0x1f, 0xb6, 0x6b, 0xff, 0x18, 0xb1, 0x62, 0xff, 0x0a, 0x99, 0x4e, 0xff, 0x03, 0x7f, 0x3e, 0xff, 0x0a, 0x79, 0x37, 0xff, 0x05, 0x70, 0x2c, 0xff, 0x10, 0x93, 0x4d, 0xff, 0x0d, 0x9f, 0x56, 0xff, 0x06, 0x92, 0x4b, 0xff, 0x0a, 0x82, 0x41, 0xff, 0x0b, 0x79, 0x3a, 0xff, 0x04, 0x73, 0x37, 0xff, 0x0e, 0x68, 0x36, 0xff, 0x0d, 0x5e, 0x33, 0xff, 0x03, 0x59, 0x32, 0xff, 0x1d, 0x93, 0x6c, 0xff, 0x1d, 0xa4, 0x7a, 0xff, 0x1c, 0xa2, 0x79, 0xff, 0x1e, 0xa4, 0x79, 0xff, 0x15, 0xa6, 0x79, 0xff, 0x14, 0xa6, 0x78, 0xff, 0x13, 0xa5, 0x76, 0xff, 0x12, 0xa4, 0x73, 0xff, 0x10, 0xa2, 0x71, 0xff, 0x11, 0xa4, 0x71, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x0d, 0x9e, 0x69, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x0f, 0x9d, 0x67, 0xff, 0x10, 0x9a, 0x66, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x0a, 0x99, 0x66, 0xff, 0x0b, 0x98, 0x65, 0xff, 0x12, 0x97, 0x65, 0xff, 0x1b, 0x92, 0x63, 0xff, 0x1b, 0x86, 0x5a, 0xff, 0x18, 0x78, 0x4f, 0xff, 0x13, 0x6b, 0x45, 0xff, 0x08, 0x5b, 0x36, 0xff, 0x05, 0x53, 0x2e, 0xff, 0x05, 0x52, 0x2e, 0xff, 0x05, 0x50, 0x2c, 0xff, 0x08, 0x59, 0x34, 0xff, 0x0f, 0x67, 0x40, 0xff, 0x18, 0x7a, 0x53, 0xff, 0x1c, 0x88, 0x5f, 0xff, 0x1d, 0x8f, 0x65, 0xff, 0x19, 0x91, 0x66, 0xff, 0x14, 0x93, 0x65, 0xff, 0x12, 0x94, 0x65, 0xff, 0x0d, 0x8f, 0x5e, 0xff, 0x0a, 0x89, 0x58, 0xff, 0x08, 0x83, 0x52, 0xff, 0x10, 0x84, 0x54, 0xff, 0x1c, 0x89, 0x5e, 0xff, 0x21, 0x84, 0x5b, 0xff, 0x12, 0x6a, 0x46, 0xff, 0x05, 0x57, 0x34, 0xff, 0x01, 0x4f, 0x2c, 0xff, 0x04, 0x5b, 0x37, 0xff, 0x0f, 0x71, 0x4b, 0xff, 0x14, 0x80, 0x58, 0xff, 0x14, 0x8b, 0x62, 0xff, 0x14, 0x91, 0x66, 0xff, 0x12, 0x94, 0x68, 0xff, 0x15, 0x93, 0x69, 0xff, 0x1c, 0x8e, 0x65, 0xff, 0x19, 0x7f, 0x57, 0xff, 0x09, 0x60, 0x3a, 0xff, 0x08, 0x61, 0x33, 0xff, 0x1d, 0x8e, 0x59, 0xff, 0x09, 0x6d, 0x39, 0xff, 0x0d, 0x6d, 0x37, 0xff, 0x07, 0x71, 0x39, 0xff, 0x0d, 0x6d, 0x39, 0xff, 0x09, 0x68, 0x36, 0xff, 0x0d, 0x6f, 0x3f, 0xff, 0x06, 0x6b, 0x39, 0xff, 0x11, 0x69, 0x37, 0xff, 0x14, 0x69, 0x37, 0xff, 0x09, 0x6a, 0x39, 0xff, 0x0f, 0x67, 0x3b, 0xff, 0x05, 0x39, 0x19, 0xff, 0x03, 0x2d, 0x14, 0xff, 0x05, 0x3c, 0x25, 0xff, 0x01, 0x36, 0x20, 0xff, 0x03, 0x2d, 0x17, 0xff, 0x07, 0x2f, 0x17, 0xff, 0x04, 0x38, 0x1d, 0xff, 0x01, 0x3d, 0x21, 0xff, 0x06, 0x3d, 0x22, 0xff, 0x04, 0x33, 0x1a, 0xff, 0x03, 0x31, 0x1b, 0xff, 0x09, 0x3d, 0x24, 0xff, 0x04, 0x35, 0x18, 0xff, 0x04, 0x37, 0x19, 0xff, 0x0d, 0x49, 0x29, 0xff, 0x05, 0x47, 0x28, 0xff, 0x0b, 0x56, 0x34, 0xff, 0x0e, 0x5c, 0x34, 0xff, 0x01, 0x50, 0x22, 0xff, 0x04, 0x46, 0x22, 0xff, 0x04, 0x41, 0x23, 0xff, 0x0a, 0x4b, 0x2a, 0xff, 0x0b, 0x4f, 0x2c, 0xff, 0x08, 0x4f, 0x2a, 0xff, 0x09, 0x50, 0x2a, 0xff, 0x0a, 0x4f, 0x2a, 0xff, 0x09, 0x4e, 0x2a, 0xff, 0x09, 0x52, 0x29, 0xff, 0x11, 0x4d, 0x30, 0xff, 0x04, 0x2c, 0x1b, 0xff, 0x01, 0x2e, 0x16, 0xff, 0x0f, 0x63, 0x3d, 0xff, 0x1a, 0x9a, 0x6c, 0xff, 0x09, 0x8e, 0x60, 0xff, 0x0e, 0x78, 0x4b, 0xff, 0x0a, 0x66, 0x36, 0xff, 0x08, 0x4b, 0x21, 0xff, 0x02, 0x2e, 0x10, 0xff, 0x0e, 0x3e, 0x2c, 0xff, 0x0a, 0x32, 0x26, 0xff, 0x01, 0x23, 0x13, 0xff, 0x11, 0x43, 0x2b, 0xff, 0x03, 0x48, 0x25, 0xff, 0x06, 0x44, 0x26, 0xff, 0x01, 0x30, 0x19, 0xff, 0x0d, 0x4e, 0x31, 0xff, 0x0f, 0x62, 0x3e, 0xff, 0x0e, 0x5d, 0x36, 0xff, 0x10, 0x61, 0x3a, 0xff, 0x0a, 0x67, 0x40, 0xff, 0x0e, 0x62, 0x3e, 0xff, 0x06, 0x4e, 0x2e, 0xff, 0x0d, 0x50, 0x33, 0xff, 0x08, 0x4e, 0x2f, 0xff, 0x07, 0x51, 0x30, 0xff, 0x0e, 0x48, 0x2a, 0xff, 0x03, 0x24, 0x0e, 0xff, 0x05, 0x1d, 0x0e, 0xff, 0x64, 0x70, 0x67, 0xff, + 0x01, 0x25, 0x14, 0xff, 0x06, 0x33, 0x1b, 0xff, 0x0c, 0x40, 0x24, 0xff, 0x09, 0x42, 0x24, 0xff, 0x09, 0x43, 0x24, 0xff, 0x09, 0x43, 0x25, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x0a, 0x43, 0x23, 0xff, 0x08, 0x41, 0x23, 0xff, 0x08, 0x3d, 0x21, 0xff, 0x0b, 0x3b, 0x21, 0xff, 0x03, 0x2e, 0x16, 0xff, 0x00, 0x25, 0x0f, 0xff, 0x07, 0x37, 0x1f, 0xff, 0x0a, 0x3f, 0x27, 0xff, 0x06, 0x3f, 0x25, 0xff, 0x08, 0x43, 0x26, 0xff, 0x04, 0x3f, 0x22, 0xff, 0x01, 0x33, 0x1c, 0xff, 0x21, 0x5b, 0x58, 0xff, 0x54, 0x8e, 0x9d, 0xff, 0x6f, 0xa6, 0xca, 0xff, 0x6c, 0xa1, 0xce, 0xff, 0x76, 0xa9, 0xd8, 0xff, 0x7b, 0xae, 0xdf, 0xff, 0x70, 0xa7, 0xd9, 0xff, 0x5e, 0x97, 0xca, 0xff, 0x5f, 0x96, 0xca, 0xff, 0x6b, 0xa1, 0xd5, 0xff, 0x68, 0x9c, 0xd0, 0xff, 0x68, 0x9b, 0xce, 0xff, 0x7d, 0xaf, 0xde, 0xff, 0x85, 0xb6, 0xe5, 0xff, 0x56, 0x84, 0xb6, 0xff, 0x7a, 0xa2, 0xd7, 0xff, 0x4b, 0x70, 0xa7, 0xff, 0x02, 0x26, 0x5f, 0xff, 0x31, 0x5f, 0x96, 0xff, 0x6d, 0xa4, 0xd1, 0xff, 0x39, 0x8a, 0x8b, 0xff, 0x1b, 0x7d, 0x5c, 0xff, 0x18, 0x76, 0x54, 0xff, 0x13, 0x67, 0x45, 0xff, 0x05, 0x4e, 0x2c, 0xff, 0x00, 0x3c, 0x1f, 0xff, 0x03, 0x34, 0x17, 0xff, 0x0b, 0x33, 0x1a, 0xff, 0x08, 0x32, 0x19, 0xff, 0x03, 0x34, 0x19, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x05, 0x4e, 0x2d, 0xff, 0x11, 0x6a, 0x45, 0xff, 0x1b, 0x7b, 0x52, 0xff, 0x22, 0x87, 0x5b, 0xff, 0x0d, 0x6a, 0x3b, 0xff, 0x08, 0x74, 0x38, 0xff, 0x19, 0xa2, 0x59, 0xff, 0x05, 0xa5, 0x4a, 0xff, 0x03, 0xa9, 0x45, 0xff, 0x07, 0xa8, 0x40, 0xff, 0x04, 0xa0, 0x3c, 0xff, 0x05, 0x9d, 0x40, 0xff, 0x04, 0x9b, 0x43, 0xff, 0x05, 0x98, 0x45, 0xff, 0x06, 0x99, 0x4a, 0xff, 0x07, 0x99, 0x4f, 0xff, 0x07, 0x99, 0x54, 0xff, 0x08, 0x99, 0x5a, 0xff, 0x0c, 0x9e, 0x63, 0xff, 0x13, 0xa6, 0x6d, 0xff, 0x13, 0xa8, 0x70, 0xff, 0x10, 0xa8, 0x6c, 0xff, 0x11, 0xa7, 0x6c, 0xff, 0x13, 0xa5, 0x6d, 0xff, 0x17, 0xa6, 0x70, 0xff, 0x17, 0xa7, 0x71, 0xff, 0x15, 0xa3, 0x6d, 0xff, 0x11, 0xa3, 0x6b, 0xff, 0x11, 0xa4, 0x6b, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0f, 0xa4, 0x6b, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0e, 0xa3, 0x64, 0xff, 0x0f, 0xa3, 0x65, 0xff, 0x10, 0xa4, 0x65, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x10, 0xa5, 0x6c, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x07, 0xa6, 0x6c, 0xff, 0x06, 0xa4, 0x69, 0xff, 0x04, 0xa1, 0x63, 0xff, 0x03, 0x9e, 0x61, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x2d, 0xc0, 0x88, 0xff, 0x25, 0xb4, 0x81, 0xff, 0x17, 0xa3, 0x74, 0xff, 0x08, 0x8f, 0x5d, 0xff, 0x0e, 0x93, 0x69, 0xff, 0x28, 0xa2, 0x84, 0xff, 0x43, 0xbf, 0xa1, 0xff, 0x31, 0xbf, 0x96, 0xff, 0x1a, 0xb3, 0x80, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa3, 0x70, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x13, 0xa6, 0x78, 0xff, 0x13, 0xa5, 0x79, 0xff, 0x16, 0xa6, 0x7c, 0xff, 0x19, 0xa8, 0x7f, 0xff, 0x18, 0xa9, 0x80, 0xff, 0x17, 0xa9, 0x80, 0xff, 0x1a, 0xa9, 0x84, 0xff, 0x1a, 0xa8, 0x83, 0xff, 0x1d, 0xa9, 0x86, 0xff, 0x22, 0xae, 0x89, 0xff, 0x16, 0xa5, 0x7c, 0xff, 0x16, 0xa7, 0x7b, 0xff, 0x14, 0xa4, 0x75, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x0f, 0x9f, 0x6e, 0xff, 0x10, 0xa2, 0x71, 0xff, 0x1a, 0xad, 0x7e, 0xff, 0x15, 0xa8, 0x7b, 0xff, 0x15, 0xa8, 0x7c, 0xff, 0x15, 0xa8, 0x7d, 0xff, 0x12, 0xa8, 0x7e, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x20, 0xaa, 0x7d, 0xff, 0x11, 0x8c, 0x5c, 0xff, 0x00, 0x65, 0x2e, 0xff, 0x05, 0x74, 0x39, 0xff, 0x1a, 0x94, 0x52, 0xff, 0x0d, 0x8c, 0x45, 0xff, 0x01, 0x78, 0x30, 0xff, 0x00, 0x73, 0x2e, 0xff, 0x01, 0x6d, 0x27, 0xff, 0x0b, 0x85, 0x3d, 0xff, 0x1c, 0xaa, 0x61, 0xff, 0x04, 0x95, 0x4c, 0xff, 0x09, 0x8b, 0x47, 0xff, 0x16, 0x86, 0x47, 0xff, 0x06, 0x6c, 0x32, 0xff, 0x05, 0x6a, 0x33, 0xff, 0x13, 0x61, 0x35, 0xff, 0x0b, 0x54, 0x2d, 0xff, 0x0e, 0x70, 0x4a, 0xff, 0x22, 0xa3, 0x7a, 0xff, 0x15, 0xa5, 0x7a, 0xff, 0x11, 0xa7, 0x78, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x0b, 0xa8, 0x77, 0xff, 0x0a, 0xa8, 0x75, 0xff, 0x09, 0xa6, 0x74, 0xff, 0x06, 0xa4, 0x71, 0xff, 0x08, 0xa6, 0x70, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x11, 0xa0, 0x6b, 0xff, 0x12, 0x9f, 0x6a, 0xff, 0x10, 0x9f, 0x69, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0b, 0x9b, 0x67, 0xff, 0x0c, 0x99, 0x66, 0xff, 0x15, 0x9a, 0x68, 0xff, 0x19, 0x96, 0x67, 0xff, 0x21, 0x98, 0x6b, 0xff, 0x1f, 0x96, 0x6a, 0xff, 0x1b, 0x8f, 0x63, 0xff, 0x1a, 0x8b, 0x60, 0xff, 0x1b, 0x8b, 0x5f, 0xff, 0x1b, 0x8b, 0x60, 0xff, 0x1c, 0x90, 0x64, 0xff, 0x1e, 0x95, 0x68, 0xff, 0x1a, 0x95, 0x68, 0xff, 0x18, 0x95, 0x68, 0xff, 0x11, 0x91, 0x64, 0xff, 0x0f, 0x92, 0x64, 0xff, 0x0e, 0x94, 0x65, 0xff, 0x11, 0x95, 0x66, 0xff, 0x14, 0x94, 0x63, 0xff, 0x16, 0x93, 0x62, 0xff, 0x14, 0x8e, 0x5e, 0xff, 0x0f, 0x85, 0x57, 0xff, 0x0c, 0x70, 0x46, 0xff, 0x07, 0x5b, 0x34, 0xff, 0x01, 0x4c, 0x28, 0xff, 0x01, 0x4e, 0x2b, 0xff, 0x09, 0x69, 0x43, 0xff, 0x12, 0x86, 0x5c, 0xff, 0x10, 0x93, 0x65, 0xff, 0x11, 0x95, 0x64, 0xff, 0x0d, 0x96, 0x65, 0xff, 0x08, 0x97, 0x65, 0xff, 0x07, 0x99, 0x66, 0xff, 0x0a, 0x98, 0x66, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x17, 0x92, 0x63, 0xff, 0x15, 0x89, 0x5c, 0xff, 0x18, 0x8d, 0x5b, 0xff, 0x17, 0x91, 0x5b, 0xff, 0x04, 0x6d, 0x38, 0xff, 0x0a, 0x6d, 0x36, 0xff, 0x08, 0x70, 0x39, 0xff, 0x0c, 0x6a, 0x36, 0xff, 0x0b, 0x69, 0x37, 0xff, 0x0d, 0x6e, 0x3e, 0xff, 0x07, 0x6a, 0x39, 0xff, 0x11, 0x69, 0x38, 0xff, 0x12, 0x68, 0x38, 0xff, 0x09, 0x69, 0x3a, 0xff, 0x10, 0x68, 0x3d, 0xff, 0x03, 0x34, 0x15, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x03, 0x39, 0x24, 0xff, 0x02, 0x38, 0x22, 0xff, 0x05, 0x30, 0x19, 0xff, 0x05, 0x2f, 0x17, 0xff, 0x06, 0x3d, 0x22, 0xff, 0x02, 0x3f, 0x22, 0xff, 0x05, 0x3b, 0x21, 0xff, 0x02, 0x2d, 0x15, 0xff, 0x04, 0x31, 0x1b, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x02, 0x33, 0x16, 0xff, 0x0c, 0x47, 0x28, 0xff, 0x05, 0x45, 0x26, 0xff, 0x03, 0x48, 0x28, 0xff, 0x0b, 0x59, 0x35, 0xff, 0x15, 0x69, 0x3f, 0xff, 0x08, 0x60, 0x2d, 0xff, 0x02, 0x4f, 0x23, 0xff, 0x01, 0x48, 0x23, 0xff, 0x03, 0x49, 0x24, 0xff, 0x09, 0x4a, 0x28, 0xff, 0x0a, 0x4b, 0x28, 0xff, 0x0a, 0x4d, 0x28, 0xff, 0x09, 0x4b, 0x27, 0xff, 0x06, 0x4c, 0x24, 0xff, 0x04, 0x4d, 0x23, 0xff, 0x08, 0x46, 0x28, 0xff, 0x01, 0x2b, 0x17, 0xff, 0x02, 0x33, 0x19, 0xff, 0x11, 0x65, 0x3f, 0xff, 0x1a, 0x97, 0x69, 0xff, 0x06, 0x88, 0x5b, 0xff, 0x0d, 0x74, 0x46, 0xff, 0x11, 0x6f, 0x3d, 0xff, 0x14, 0x5d, 0x32, 0xff, 0x0e, 0x44, 0x24, 0xff, 0x0d, 0x41, 0x2d, 0xff, 0x05, 0x2f, 0x1f, 0xff, 0x02, 0x25, 0x13, 0xff, 0x14, 0x49, 0x2f, 0xff, 0x04, 0x4b, 0x28, 0xff, 0x0b, 0x47, 0x2a, 0xff, 0x03, 0x36, 0x18, 0xff, 0x0f, 0x52, 0x30, 0xff, 0x1c, 0x66, 0x51, 0xff, 0x26, 0x69, 0x5d, 0xff, 0x10, 0x5d, 0x40, 0xff, 0x0a, 0x66, 0x3a, 0xff, 0x12, 0x65, 0x3c, 0xff, 0x0f, 0x58, 0x38, 0xff, 0x0a, 0x4d, 0x30, 0xff, 0x06, 0x4d, 0x2d, 0xff, 0x07, 0x51, 0x2f, 0xff, 0x0e, 0x4a, 0x2c, 0xff, 0x02, 0x24, 0x0e, 0xff, 0x05, 0x1d, 0x0e, 0xff, 0x63, 0x70, 0x67, 0xff, + 0x01, 0x25, 0x14, 0xff, 0x04, 0x30, 0x19, 0xff, 0x0c, 0x3e, 0x23, 0xff, 0x0a, 0x41, 0x23, 0xff, 0x0a, 0x43, 0x24, 0xff, 0x0a, 0x42, 0x25, 0xff, 0x0a, 0x42, 0x24, 0xff, 0x09, 0x43, 0x22, 0xff, 0x07, 0x41, 0x23, 0xff, 0x08, 0x3d, 0x21, 0xff, 0x0c, 0x3b, 0x22, 0xff, 0x08, 0x34, 0x1e, 0xff, 0x00, 0x26, 0x10, 0xff, 0x04, 0x32, 0x1d, 0xff, 0x0b, 0x41, 0x27, 0xff, 0x05, 0x41, 0x24, 0xff, 0x03, 0x3c, 0x28, 0xff, 0x0d, 0x45, 0x42, 0xff, 0x2e, 0x65, 0x70, 0xff, 0x5c, 0x93, 0xaf, 0xff, 0x69, 0xa1, 0xc8, 0xff, 0x66, 0x9e, 0xcd, 0xff, 0x72, 0xa8, 0xdb, 0xff, 0x7b, 0xab, 0xe1, 0xff, 0x6d, 0xa1, 0xd6, 0xff, 0x5b, 0x94, 0xc8, 0xff, 0x5f, 0x99, 0xcd, 0xff, 0x67, 0xa0, 0xd4, 0xff, 0x6c, 0xa1, 0xd5, 0xff, 0x70, 0xa1, 0xd4, 0xff, 0x82, 0xb1, 0xe5, 0xff, 0x88, 0xb6, 0xe6, 0xff, 0x41, 0x6e, 0x9f, 0xff, 0x14, 0x3c, 0x71, 0xff, 0x5e, 0x84, 0xba, 0xff, 0x34, 0x57, 0x91, 0xff, 0x15, 0x3b, 0x75, 0xff, 0x2f, 0x5a, 0x95, 0xff, 0x6c, 0xa3, 0xd1, 0xff, 0x38, 0x8e, 0x8b, 0xff, 0x13, 0x82, 0x5d, 0xff, 0x15, 0x86, 0x5f, 0xff, 0x1a, 0x86, 0x5d, 0xff, 0x1b, 0x80, 0x56, 0xff, 0x12, 0x6c, 0x48, 0xff, 0x06, 0x4d, 0x2a, 0xff, 0x03, 0x39, 0x1a, 0xff, 0x03, 0x33, 0x17, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x00, 0x32, 0x16, 0xff, 0x00, 0x35, 0x19, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x05, 0x46, 0x24, 0xff, 0x07, 0x50, 0x2a, 0xff, 0x05, 0x53, 0x2c, 0xff, 0x01, 0x47, 0x1b, 0xff, 0x09, 0x6f, 0x34, 0xff, 0x15, 0xaa, 0x59, 0xff, 0x0e, 0xae, 0x50, 0xff, 0x09, 0xa8, 0x43, 0xff, 0x06, 0xa0, 0x3d, 0xff, 0x06, 0x9c, 0x3f, 0xff, 0x08, 0x9c, 0x42, 0xff, 0x04, 0x9e, 0x40, 0xff, 0x03, 0x9c, 0x40, 0xff, 0x04, 0x99, 0x43, 0xff, 0x04, 0x96, 0x46, 0xff, 0x03, 0x8f, 0x46, 0xff, 0x02, 0x8d, 0x48, 0xff, 0x06, 0x91, 0x50, 0xff, 0x09, 0x93, 0x53, 0xff, 0x0b, 0x97, 0x5a, 0xff, 0x18, 0x9e, 0x64, 0xff, 0x16, 0x95, 0x5e, 0xff, 0x16, 0x90, 0x5c, 0xff, 0x0f, 0x87, 0x55, 0xff, 0x0f, 0x92, 0x5e, 0xff, 0x10, 0xa4, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0f, 0xa4, 0x66, 0xff, 0x0f, 0xa4, 0x65, 0xff, 0x0f, 0xa4, 0x65, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x05, 0x9f, 0x64, 0xff, 0x03, 0x9c, 0x60, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x21, 0xb4, 0x7c, 0xff, 0x14, 0xa4, 0x6f, 0xff, 0x07, 0x94, 0x62, 0xff, 0x10, 0x99, 0x64, 0xff, 0x26, 0xaa, 0x7b, 0xff, 0x1e, 0x9c, 0x77, 0xff, 0x27, 0xa9, 0x84, 0xff, 0x29, 0xb7, 0x8b, 0xff, 0x13, 0xab, 0x78, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x71, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0e, 0xaa, 0x73, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0f, 0xa3, 0x72, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x12, 0xa6, 0x78, 0xff, 0x15, 0xa6, 0x7b, 0xff, 0x17, 0xa7, 0x7d, 0xff, 0x1c, 0xa9, 0x82, 0xff, 0x20, 0xac, 0x87, 0xff, 0x1c, 0xab, 0x85, 0xff, 0x19, 0xa8, 0x81, 0xff, 0x19, 0xa7, 0x82, 0xff, 0x1c, 0xa8, 0x85, 0xff, 0x1d, 0xa8, 0x86, 0xff, 0x19, 0xa4, 0x81, 0xff, 0x1b, 0xa8, 0x81, 0xff, 0x1b, 0xaa, 0x81, 0xff, 0x1b, 0xa7, 0x7c, 0xff, 0x0e, 0x99, 0x6d, 0xff, 0x11, 0x9e, 0x71, 0xff, 0x18, 0xa6, 0x79, 0xff, 0x1d, 0xac, 0x80, 0xff, 0x19, 0xa9, 0x7f, 0xff, 0x18, 0xa8, 0x7f, 0xff, 0x17, 0xa8, 0x80, 0xff, 0x14, 0xaa, 0x82, 0xff, 0x13, 0xa9, 0x82, 0xff, 0x1d, 0xaa, 0x80, 0xff, 0x20, 0xa0, 0x74, 0xff, 0x04, 0x6f, 0x3e, 0xff, 0x00, 0x5f, 0x2a, 0xff, 0x06, 0x69, 0x2d, 0xff, 0x14, 0x83, 0x43, 0xff, 0x0c, 0x7b, 0x38, 0xff, 0x04, 0x78, 0x32, 0xff, 0x17, 0x95, 0x4d, 0xff, 0x20, 0xa9, 0x61, 0xff, 0x0f, 0x98, 0x51, 0xff, 0x02, 0x83, 0x3e, 0xff, 0x05, 0x79, 0x3b, 0xff, 0x0a, 0x78, 0x3d, 0xff, 0x0c, 0x6f, 0x3a, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x07, 0x4f, 0x27, 0xff, 0x07, 0x5a, 0x34, 0xff, 0x1f, 0x9c, 0x73, 0xff, 0x19, 0xa5, 0x7b, 0xff, 0x15, 0xa9, 0x7b, 0xff, 0x0b, 0xa9, 0x76, 0xff, 0x07, 0xaa, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa6, 0x73, 0xff, 0x0b, 0xa5, 0x71, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x12, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0d, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x10, 0x99, 0x67, 0xff, 0x10, 0x9a, 0x6a, 0xff, 0x11, 0x99, 0x69, 0xff, 0x14, 0x99, 0x69, 0xff, 0x15, 0x98, 0x68, 0xff, 0x14, 0x98, 0x68, 0xff, 0x11, 0x98, 0x68, 0xff, 0x0f, 0x99, 0x68, 0xff, 0x0c, 0x98, 0x67, 0xff, 0x0d, 0x98, 0x66, 0xff, 0x0a, 0x96, 0x64, 0xff, 0x0a, 0x96, 0x65, 0xff, 0x0b, 0x94, 0x64, 0xff, 0x0d, 0x94, 0x64, 0xff, 0x11, 0x94, 0x63, 0xff, 0x0f, 0x8c, 0x5c, 0xff, 0x05, 0x78, 0x48, 0xff, 0x05, 0x66, 0x3b, 0xff, 0x04, 0x58, 0x2e, 0xff, 0x02, 0x55, 0x2d, 0xff, 0x09, 0x66, 0x3e, 0xff, 0x15, 0x7b, 0x52, 0xff, 0x1a, 0x90, 0x63, 0xff, 0x11, 0x96, 0x66, 0xff, 0x0a, 0x98, 0x66, 0xff, 0x0d, 0x99, 0x65, 0xff, 0x0c, 0x98, 0x64, 0xff, 0x08, 0x97, 0x62, 0xff, 0x07, 0x96, 0x62, 0xff, 0x09, 0x97, 0x62, 0xff, 0x0e, 0x96, 0x63, 0xff, 0x12, 0x94, 0x62, 0xff, 0x10, 0x8e, 0x5c, 0xff, 0x0f, 0x91, 0x5d, 0xff, 0x0f, 0x8e, 0x57, 0xff, 0x03, 0x6e, 0x39, 0xff, 0x09, 0x6b, 0x36, 0xff, 0x0b, 0x71, 0x3a, 0xff, 0x0a, 0x67, 0x35, 0xff, 0x0c, 0x6c, 0x3a, 0xff, 0x0d, 0x6c, 0x3d, 0xff, 0x09, 0x6a, 0x39, 0xff, 0x12, 0x69, 0x38, 0xff, 0x12, 0x68, 0x39, 0xff, 0x0b, 0x68, 0x3b, 0xff, 0x0e, 0x63, 0x3b, 0xff, 0x01, 0x30, 0x13, 0xff, 0x02, 0x2b, 0x13, 0xff, 0x03, 0x33, 0x1f, 0xff, 0x04, 0x38, 0x21, 0xff, 0x03, 0x30, 0x19, 0xff, 0x02, 0x2f, 0x16, 0xff, 0x06, 0x40, 0x24, 0xff, 0x03, 0x40, 0x24, 0xff, 0x02, 0x35, 0x1b, 0xff, 0x01, 0x2a, 0x13, 0xff, 0x02, 0x2d, 0x16, 0xff, 0x00, 0x2c, 0x11, 0xff, 0x08, 0x45, 0x25, 0xff, 0x0d, 0x4d, 0x2d, 0xff, 0x06, 0x48, 0x28, 0xff, 0x05, 0x4d, 0x2b, 0xff, 0x02, 0x53, 0x2c, 0xff, 0x0e, 0x68, 0x3a, 0xff, 0x0d, 0x70, 0x39, 0xff, 0x10, 0x6e, 0x39, 0xff, 0x02, 0x57, 0x28, 0xff, 0x04, 0x50, 0x25, 0xff, 0x0e, 0x4e, 0x2a, 0xff, 0x12, 0x4d, 0x2c, 0xff, 0x11, 0x4e, 0x2c, 0xff, 0x10, 0x4f, 0x2a, 0xff, 0x0b, 0x50, 0x27, 0xff, 0x09, 0x53, 0x28, 0xff, 0x08, 0x49, 0x29, 0xff, 0x03, 0x34, 0x1d, 0xff, 0x07, 0x3f, 0x21, 0xff, 0x0a, 0x5e, 0x36, 0xff, 0x17, 0x93, 0x65, 0xff, 0x0a, 0x88, 0x5c, 0xff, 0x0c, 0x72, 0x44, 0xff, 0x0c, 0x6a, 0x39, 0xff, 0x11, 0x5f, 0x34, 0xff, 0x19, 0x59, 0x37, 0xff, 0x14, 0x4d, 0x35, 0xff, 0x01, 0x2b, 0x19, 0xff, 0x04, 0x27, 0x12, 0xff, 0x16, 0x4e, 0x32, 0xff, 0x06, 0x4f, 0x2a, 0xff, 0x03, 0x3f, 0x21, 0xff, 0x03, 0x37, 0x14, 0xff, 0x0e, 0x55, 0x2e, 0xff, 0x2e, 0x73, 0x68, 0xff, 0x42, 0x7f, 0x84, 0xff, 0x13, 0x5d, 0x47, 0xff, 0x0d, 0x68, 0x38, 0xff, 0x14, 0x68, 0x3d, 0xff, 0x16, 0x5d, 0x3d, 0xff, 0x08, 0x4a, 0x2c, 0xff, 0x06, 0x4c, 0x2c, 0xff, 0x08, 0x53, 0x31, 0xff, 0x0f, 0x4c, 0x2d, 0xff, 0x02, 0x26, 0x0f, 0xff, 0x03, 0x1d, 0x0e, 0xff, 0x62, 0x6f, 0x68, 0xff, + 0x01, 0x25, 0x14, 0xff, 0x02, 0x2c, 0x16, 0xff, 0x0a, 0x3a, 0x21, 0xff, 0x09, 0x3e, 0x22, 0xff, 0x09, 0x3f, 0x22, 0xff, 0x08, 0x3f, 0x22, 0xff, 0x09, 0x3f, 0x22, 0xff, 0x09, 0x3f, 0x21, 0xff, 0x08, 0x40, 0x23, 0xff, 0x08, 0x3e, 0x22, 0xff, 0x0a, 0x3b, 0x21, 0xff, 0x0b, 0x38, 0x21, 0xff, 0x01, 0x28, 0x11, 0xff, 0x03, 0x30, 0x19, 0xff, 0x0a, 0x41, 0x27, 0xff, 0x02, 0x3d, 0x28, 0xff, 0x0e, 0x49, 0x46, 0xff, 0x44, 0x7a, 0x93, 0xff, 0x5c, 0x91, 0xbb, 0xff, 0x5f, 0x92, 0xc8, 0xff, 0x63, 0x99, 0xce, 0xff, 0x71, 0xaa, 0xdb, 0xff, 0x75, 0xab, 0xdc, 0xff, 0x68, 0x97, 0xd1, 0xff, 0x65, 0x98, 0xd0, 0xff, 0x65, 0x9d, 0xd3, 0xff, 0x66, 0xa1, 0xd4, 0xff, 0x6a, 0xa4, 0xd5, 0xff, 0x71, 0xa6, 0xd7, 0xff, 0x86, 0xb3, 0xe4, 0xff, 0x7b, 0xa5, 0xd8, 0xff, 0x6d, 0x97, 0xca, 0xff, 0x17, 0x3d, 0x71, 0xff, 0x0b, 0x31, 0x67, 0xff, 0x4e, 0x73, 0xaa, 0xff, 0x33, 0x54, 0x90, 0xff, 0x35, 0x59, 0x95, 0xff, 0x2d, 0x56, 0x91, 0xff, 0x5a, 0x8f, 0xbd, 0xff, 0x26, 0x7c, 0x76, 0xff, 0x14, 0x85, 0x5e, 0xff, 0x0d, 0x87, 0x5b, 0xff, 0x0f, 0x87, 0x59, 0xff, 0x12, 0x88, 0x59, 0xff, 0x17, 0x88, 0x5f, 0xff, 0x1c, 0x81, 0x56, 0xff, 0x13, 0x68, 0x43, 0xff, 0x03, 0x46, 0x23, 0xff, 0x01, 0x3d, 0x1c, 0xff, 0x01, 0x39, 0x1a, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x01, 0x40, 0x1f, 0xff, 0x04, 0x4a, 0x25, 0xff, 0x07, 0x5b, 0x33, 0xff, 0x0c, 0x71, 0x47, 0xff, 0x0e, 0x6a, 0x36, 0xff, 0x0a, 0x77, 0x34, 0xff, 0x14, 0xa1, 0x51, 0xff, 0x10, 0xaf, 0x54, 0xff, 0x09, 0xa6, 0x4b, 0xff, 0x03, 0x99, 0x41, 0xff, 0x03, 0x99, 0x40, 0xff, 0x00, 0x9e, 0x3b, 0xff, 0x00, 0x9d, 0x3c, 0xff, 0x02, 0x9b, 0x3d, 0xff, 0x04, 0x98, 0x3e, 0xff, 0x0b, 0x99, 0x45, 0xff, 0x0c, 0x94, 0x45, 0xff, 0x0b, 0x90, 0x43, 0xff, 0x07, 0x88, 0x3f, 0xff, 0x02, 0x7d, 0x40, 0xff, 0x04, 0x78, 0x3e, 0xff, 0x0d, 0x78, 0x44, 0xff, 0x04, 0x62, 0x30, 0xff, 0x03, 0x5f, 0x2f, 0xff, 0x0f, 0x8d, 0x59, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x04, 0xa6, 0x6e, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0f, 0xa7, 0x6c, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x06, 0xa0, 0x66, 0xff, 0x07, 0xa0, 0x65, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x1d, 0xb1, 0x79, 0xff, 0x34, 0xc5, 0x8f, 0xff, 0x13, 0xa3, 0x6f, 0xff, 0x25, 0xb5, 0x7b, 0xff, 0x2d, 0xba, 0x82, 0xff, 0x13, 0x9a, 0x6c, 0xff, 0x0c, 0x95, 0x6a, 0xff, 0x17, 0xa7, 0x79, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x75, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0d, 0xa9, 0x74, 0xff, 0x0d, 0xa9, 0x74, 0xff, 0x0d, 0xa9, 0x74, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x11, 0xa4, 0x75, 0xff, 0x14, 0xa5, 0x77, 0xff, 0x14, 0xa5, 0x79, 0xff, 0x16, 0xa6, 0x7b, 0xff, 0x19, 0xa6, 0x7e, 0xff, 0x1b, 0xa8, 0x82, 0xff, 0x1d, 0xa8, 0x84, 0xff, 0x1f, 0xa9, 0x87, 0xff, 0x1c, 0xa8, 0x85, 0xff, 0x1b, 0xa8, 0x83, 0xff, 0x1d, 0xa7, 0x85, 0xff, 0x1c, 0xa6, 0x85, 0xff, 0x1f, 0xa8, 0x87, 0xff, 0x1d, 0xa8, 0x84, 0xff, 0x1c, 0xa8, 0x83, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x1c, 0xa4, 0x7d, 0xff, 0x18, 0x9f, 0x76, 0xff, 0x20, 0xa9, 0x81, 0xff, 0x24, 0xae, 0x86, 0xff, 0x1c, 0xa8, 0x80, 0xff, 0x1c, 0xa8, 0x82, 0xff, 0x19, 0xa7, 0x82, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x17, 0xa8, 0x82, 0xff, 0x18, 0xa8, 0x84, 0xff, 0x1a, 0xa9, 0x82, 0xff, 0x20, 0xa7, 0x7d, 0xff, 0x0e, 0x83, 0x55, 0xff, 0x00, 0x62, 0x31, 0xff, 0x01, 0x5f, 0x28, 0xff, 0x03, 0x62, 0x28, 0xff, 0x1d, 0x91, 0x52, 0xff, 0x18, 0x94, 0x50, 0xff, 0x14, 0x94, 0x50, 0xff, 0x0b, 0x89, 0x45, 0xff, 0x02, 0x79, 0x3a, 0xff, 0x01, 0x70, 0x35, 0xff, 0x05, 0x6a, 0x34, 0xff, 0x06, 0x63, 0x31, 0xff, 0x0b, 0x5b, 0x30, 0xff, 0x07, 0x4b, 0x27, 0xff, 0x04, 0x56, 0x31, 0xff, 0x18, 0x92, 0x6a, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x15, 0xa8, 0x78, 0xff, 0x09, 0xa7, 0x72, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x11, 0xa5, 0x70, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x11, 0xa4, 0x6f, 0xff, 0x11, 0xa5, 0x6f, 0xff, 0x11, 0xa4, 0x6f, 0xff, 0x11, 0xa5, 0x6f, 0xff, 0x10, 0xa6, 0x6e, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x09, 0x9c, 0x68, 0xff, 0x09, 0x9a, 0x66, 0xff, 0x0a, 0x9b, 0x67, 0xff, 0x0c, 0x99, 0x66, 0xff, 0x10, 0x9b, 0x68, 0xff, 0x13, 0x9b, 0x68, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x10, 0x9b, 0x67, 0xff, 0x0e, 0x9a, 0x66, 0xff, 0x0a, 0x9a, 0x66, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x09, 0x9a, 0x64, 0xff, 0x08, 0x97, 0x62, 0xff, 0x0b, 0x96, 0x63, 0xff, 0x0e, 0x97, 0x64, 0xff, 0x11, 0x95, 0x66, 0xff, 0x14, 0x92, 0x64, 0xff, 0x13, 0x8b, 0x5d, 0xff, 0x1f, 0x88, 0x5d, 0xff, 0x1b, 0x86, 0x5b, 0xff, 0x16, 0x87, 0x5b, 0xff, 0x1a, 0x93, 0x64, 0xff, 0x16, 0x96, 0x66, 0xff, 0x11, 0x98, 0x65, 0xff, 0x0c, 0x97, 0x63, 0xff, 0x0d, 0x99, 0x64, 0xff, 0x10, 0x99, 0x64, 0xff, 0x10, 0x99, 0x63, 0xff, 0x10, 0x99, 0x65, 0xff, 0x11, 0x98, 0x64, 0xff, 0x10, 0x96, 0x62, 0xff, 0x12, 0x96, 0x63, 0xff, 0x14, 0x95, 0x62, 0xff, 0x11, 0x91, 0x5e, 0xff, 0x0d, 0x96, 0x60, 0xff, 0x0f, 0x8d, 0x57, 0xff, 0x03, 0x6c, 0x38, 0xff, 0x0c, 0x6c, 0x39, 0xff, 0x0e, 0x6e, 0x3b, 0xff, 0x0b, 0x66, 0x35, 0xff, 0x0d, 0x6f, 0x3c, 0xff, 0x0b, 0x6a, 0x3b, 0xff, 0x0d, 0x69, 0x38, 0xff, 0x13, 0x67, 0x3a, 0xff, 0x13, 0x67, 0x3a, 0xff, 0x0f, 0x68, 0x3d, 0xff, 0x0f, 0x5d, 0x37, 0xff, 0x01, 0x31, 0x15, 0xff, 0x02, 0x28, 0x12, 0xff, 0x02, 0x2e, 0x1b, 0xff, 0x07, 0x39, 0x22, 0xff, 0x03, 0x30, 0x19, 0xff, 0x01, 0x2e, 0x17, 0xff, 0x04, 0x3e, 0x25, 0xff, 0x02, 0x3f, 0x25, 0xff, 0x06, 0x36, 0x1e, 0xff, 0x03, 0x2b, 0x15, 0xff, 0x00, 0x2b, 0x13, 0xff, 0x02, 0x39, 0x1d, 0xff, 0x0b, 0x4d, 0x2d, 0xff, 0x0a, 0x4c, 0x2c, 0xff, 0x0a, 0x4d, 0x2d, 0xff, 0x05, 0x4c, 0x2a, 0xff, 0x01, 0x53, 0x2a, 0xff, 0x09, 0x66, 0x35, 0xff, 0x08, 0x75, 0x38, 0xff, 0x11, 0x7d, 0x40, 0xff, 0x0f, 0x72, 0x3a, 0xff, 0x06, 0x5a, 0x2a, 0xff, 0x0d, 0x4e, 0x2a, 0xff, 0x12, 0x4a, 0x2a, 0xff, 0x12, 0x49, 0x29, 0xff, 0x0f, 0x4c, 0x27, 0xff, 0x0b, 0x4f, 0x25, 0xff, 0x0b, 0x54, 0x29, 0xff, 0x0a, 0x4c, 0x2a, 0xff, 0x0b, 0x42, 0x25, 0xff, 0x10, 0x4c, 0x29, 0xff, 0x05, 0x5a, 0x30, 0xff, 0x16, 0x8e, 0x62, 0xff, 0x0c, 0x86, 0x5c, 0xff, 0x0c, 0x6f, 0x41, 0xff, 0x07, 0x63, 0x31, 0xff, 0x0f, 0x60, 0x35, 0xff, 0x0e, 0x55, 0x31, 0xff, 0x19, 0x58, 0x3c, 0xff, 0x01, 0x2b, 0x15, 0xff, 0x04, 0x2a, 0x12, 0xff, 0x18, 0x52, 0x34, 0xff, 0x0c, 0x56, 0x31, 0xff, 0x06, 0x44, 0x25, 0xff, 0x03, 0x39, 0x14, 0xff, 0x0f, 0x59, 0x31, 0xff, 0x12, 0x58, 0x4c, 0xff, 0x20, 0x60, 0x62, 0xff, 0x13, 0x5f, 0x46, 0xff, 0x0d, 0x69, 0x37, 0xff, 0x12, 0x66, 0x3b, 0xff, 0x12, 0x5a, 0x3a, 0xff, 0x09, 0x4b, 0x2d, 0xff, 0x07, 0x4d, 0x2c, 0xff, 0x08, 0x54, 0x32, 0xff, 0x0d, 0x4c, 0x2d, 0xff, 0x02, 0x26, 0x0f, 0xff, 0x03, 0x1d, 0x0e, 0xff, 0x62, 0x6f, 0x67, 0xff, + 0x03, 0x27, 0x16, 0xff, 0x01, 0x2a, 0x14, 0xff, 0x09, 0x38, 0x20, 0xff, 0x0b, 0x3e, 0x23, 0xff, 0x0a, 0x3e, 0x23, 0xff, 0x07, 0x3d, 0x20, 0xff, 0x08, 0x3c, 0x20, 0xff, 0x0c, 0x3c, 0x22, 0xff, 0x0b, 0x3f, 0x23, 0xff, 0x07, 0x3d, 0x20, 0xff, 0x08, 0x3b, 0x1f, 0xff, 0x0c, 0x3b, 0x23, 0xff, 0x02, 0x2b, 0x16, 0xff, 0x01, 0x2b, 0x18, 0xff, 0x03, 0x35, 0x29, 0xff, 0x16, 0x51, 0x53, 0xff, 0x43, 0x7e, 0x8d, 0xff, 0x60, 0x98, 0xbc, 0xff, 0x5b, 0x90, 0xc2, 0xff, 0x6b, 0x9f, 0xd8, 0xff, 0x73, 0xa9, 0xe1, 0xff, 0x6d, 0xa3, 0xd5, 0xff, 0x5b, 0x8e, 0xc1, 0xff, 0x69, 0x99, 0xd2, 0xff, 0x6f, 0xa4, 0xdb, 0xff, 0x6e, 0xa8, 0xda, 0xff, 0x69, 0xa4, 0xd6, 0xff, 0x71, 0xab, 0xda, 0xff, 0x7f, 0xb3, 0xe2, 0xff, 0x6f, 0x9d, 0xcb, 0xff, 0x2c, 0x56, 0x86, 0xff, 0x1e, 0x44, 0x7a, 0xff, 0x0e, 0x33, 0x69, 0xff, 0x09, 0x30, 0x67, 0xff, 0x3c, 0x61, 0x99, 0xff, 0x34, 0x55, 0x90, 0xff, 0x42, 0x66, 0xa1, 0xff, 0x21, 0x4b, 0x86, 0xff, 0x2f, 0x64, 0x92, 0xff, 0x1d, 0x76, 0x6f, 0xff, 0x14, 0x88, 0x5e, 0xff, 0x0d, 0x8a, 0x5c, 0xff, 0x0e, 0x8a, 0x59, 0xff, 0x0d, 0x89, 0x58, 0xff, 0x0d, 0x8a, 0x5d, 0xff, 0x12, 0x8b, 0x5c, 0xff, 0x17, 0x87, 0x5b, 0xff, 0x10, 0x77, 0x4d, 0xff, 0x0d, 0x6d, 0x43, 0xff, 0x0b, 0x66, 0x3f, 0xff, 0x0a, 0x64, 0x3e, 0xff, 0x0e, 0x6f, 0x48, 0xff, 0x0f, 0x78, 0x4f, 0xff, 0x16, 0x89, 0x5c, 0xff, 0x18, 0x95, 0x65, 0xff, 0x17, 0x9f, 0x6c, 0xff, 0x21, 0x9f, 0x6b, 0xff, 0x10, 0x75, 0x3e, 0xff, 0x05, 0x67, 0x2a, 0xff, 0x16, 0x91, 0x4a, 0xff, 0x1a, 0xa8, 0x5c, 0xff, 0x0a, 0xa3, 0x52, 0xff, 0x05, 0x9d, 0x49, 0xff, 0x03, 0x9d, 0x43, 0xff, 0x03, 0x9c, 0x42, 0xff, 0x04, 0x9b, 0x41, 0xff, 0x04, 0x97, 0x3f, 0xff, 0x08, 0x95, 0x42, 0xff, 0x0a, 0x94, 0x42, 0xff, 0x0c, 0x94, 0x42, 0xff, 0x05, 0x89, 0x3c, 0xff, 0x04, 0x7b, 0x3d, 0xff, 0x05, 0x75, 0x3c, 0xff, 0x07, 0x6f, 0x3a, 0xff, 0x09, 0x70, 0x3c, 0xff, 0x1c, 0x93, 0x60, 0xff, 0x1e, 0xa4, 0x71, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x05, 0xa8, 0x6f, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa2, 0x67, 0xff, 0x0e, 0xa2, 0x67, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x0e, 0xa3, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x07, 0xa4, 0x6a, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x17, 0xad, 0x75, 0xff, 0x18, 0xac, 0x75, 0xff, 0x08, 0x9b, 0x65, 0xff, 0x14, 0xac, 0x70, 0xff, 0x1c, 0xb2, 0x78, 0xff, 0x11, 0xa1, 0x6e, 0xff, 0x11, 0xa1, 0x71, 0xff, 0x1a, 0xad, 0x7b, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x0f, 0xa5, 0x72, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x14, 0xa9, 0x79, 0xff, 0x14, 0xa9, 0x7a, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x14, 0xa9, 0x7a, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x14, 0xa6, 0x79, 0xff, 0x18, 0xa6, 0x7b, 0xff, 0x18, 0xa6, 0x7d, 0xff, 0x19, 0xa6, 0x7f, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x1d, 0xa8, 0x85, 0xff, 0x1d, 0xa6, 0x85, 0xff, 0x1e, 0xa7, 0x87, 0xff, 0x1d, 0xa8, 0x86, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1d, 0xa7, 0x86, 0xff, 0x1d, 0xa6, 0x86, 0xff, 0x21, 0xaa, 0x89, 0xff, 0x1b, 0xa5, 0x82, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1c, 0xa4, 0x80, 0xff, 0x1f, 0xa4, 0x7f, 0xff, 0x2b, 0xb2, 0x8c, 0xff, 0x2b, 0xb3, 0x8e, 0xff, 0x1d, 0xa7, 0x83, 0xff, 0x1b, 0xa7, 0x81, 0xff, 0x1b, 0xa8, 0x83, 0xff, 0x18, 0xa6, 0x83, 0xff, 0x1b, 0xa5, 0x84, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x16, 0xa6, 0x81, 0xff, 0x19, 0xa7, 0x7f, 0xff, 0x1b, 0x99, 0x6d, 0xff, 0x06, 0x6f, 0x42, 0xff, 0x02, 0x60, 0x31, 0xff, 0x01, 0x5c, 0x2a, 0xff, 0x06, 0x6a, 0x33, 0xff, 0x19, 0x8c, 0x51, 0xff, 0x11, 0x87, 0x4b, 0xff, 0x03, 0x74, 0x39, 0xff, 0x03, 0x6c, 0x36, 0xff, 0x09, 0x67, 0x36, 0xff, 0x0d, 0x5e, 0x32, 0xff, 0x08, 0x50, 0x29, 0xff, 0x01, 0x3d, 0x1a, 0xff, 0x02, 0x4b, 0x2a, 0xff, 0x15, 0x89, 0x63, 0xff, 0x18, 0xa5, 0x7c, 0xff, 0x12, 0xa7, 0x7c, 0xff, 0x14, 0xa8, 0x7b, 0xff, 0x13, 0xa7, 0x77, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x09, 0x9d, 0x68, 0xff, 0x08, 0x9c, 0x66, 0xff, 0x0b, 0x9c, 0x66, 0xff, 0x0d, 0x9b, 0x66, 0xff, 0x0f, 0x9a, 0x65, 0xff, 0x12, 0x9b, 0x65, 0xff, 0x11, 0x9a, 0x65, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x10, 0x9b, 0x67, 0xff, 0x0f, 0x9e, 0x67, 0xff, 0x0c, 0x9c, 0x65, 0xff, 0x0b, 0x9b, 0x64, 0xff, 0x0d, 0x9a, 0x65, 0xff, 0x0d, 0x99, 0x65, 0xff, 0x10, 0x98, 0x66, 0xff, 0x10, 0x96, 0x65, 0xff, 0x11, 0x95, 0x66, 0xff, 0x16, 0x95, 0x67, 0xff, 0x1c, 0x94, 0x66, 0xff, 0x1a, 0x95, 0x65, 0xff, 0x18, 0x97, 0x67, 0xff, 0x11, 0x98, 0x65, 0xff, 0x0f, 0x99, 0x65, 0xff, 0x0e, 0x9c, 0x66, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0d, 0x9b, 0x65, 0xff, 0x0e, 0x9a, 0x65, 0xff, 0x10, 0x9b, 0x66, 0xff, 0x11, 0x9a, 0x66, 0xff, 0x10, 0x98, 0x65, 0xff, 0x11, 0x97, 0x64, 0xff, 0x10, 0x95, 0x63, 0xff, 0x11, 0x95, 0x63, 0xff, 0x0d, 0x92, 0x61, 0xff, 0x0d, 0x96, 0x62, 0xff, 0x11, 0x8d, 0x56, 0xff, 0x06, 0x6b, 0x38, 0xff, 0x0e, 0x6a, 0x38, 0xff, 0x11, 0x6d, 0x3b, 0xff, 0x0b, 0x66, 0x35, 0xff, 0x0d, 0x72, 0x3f, 0xff, 0x0b, 0x6a, 0x3a, 0xff, 0x0c, 0x67, 0x35, 0xff, 0x0d, 0x60, 0x33, 0xff, 0x0e, 0x61, 0x35, 0xff, 0x0e, 0x61, 0x39, 0xff, 0x0e, 0x58, 0x35, 0xff, 0x08, 0x39, 0x1e, 0xff, 0x05, 0x2a, 0x15, 0xff, 0x03, 0x2a, 0x18, 0xff, 0x09, 0x38, 0x22, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x01, 0x2e, 0x16, 0xff, 0x04, 0x3e, 0x25, 0xff, 0x03, 0x3e, 0x25, 0xff, 0x0d, 0x3c, 0x24, 0xff, 0x03, 0x2b, 0x15, 0xff, 0x01, 0x2f, 0x17, 0xff, 0x0b, 0x46, 0x2a, 0xff, 0x0b, 0x4b, 0x2d, 0xff, 0x0a, 0x4b, 0x2c, 0xff, 0x0a, 0x4b, 0x2c, 0xff, 0x09, 0x4c, 0x2c, 0xff, 0x02, 0x51, 0x2a, 0xff, 0x05, 0x63, 0x31, 0xff, 0x09, 0x7b, 0x3a, 0xff, 0x0b, 0x81, 0x3c, 0xff, 0x14, 0x7e, 0x40, 0xff, 0x10, 0x6b, 0x36, 0xff, 0x08, 0x4d, 0x26, 0xff, 0x10, 0x4a, 0x27, 0xff, 0x11, 0x49, 0x28, 0xff, 0x0f, 0x4c, 0x27, 0xff, 0x0c, 0x4d, 0x24, 0xff, 0x09, 0x50, 0x25, 0xff, 0x0c, 0x4e, 0x2a, 0xff, 0x0f, 0x48, 0x2a, 0xff, 0x0f, 0x4d, 0x28, 0xff, 0x05, 0x5c, 0x30, 0xff, 0x16, 0x8c, 0x61, 0xff, 0x0d, 0x85, 0x5c, 0xff, 0x0b, 0x6c, 0x3e, 0xff, 0x04, 0x5a, 0x2a, 0xff, 0x10, 0x60, 0x35, 0xff, 0x0d, 0x58, 0x33, 0xff, 0x12, 0x55, 0x36, 0xff, 0x02, 0x2f, 0x16, 0xff, 0x05, 0x2e, 0x13, 0xff, 0x18, 0x55, 0x36, 0xff, 0x14, 0x5e, 0x39, 0xff, 0x08, 0x47, 0x28, 0xff, 0x04, 0x40, 0x1d, 0xff, 0x10, 0x5e, 0x36, 0xff, 0x0b, 0x55, 0x3f, 0xff, 0x10, 0x55, 0x4a, 0xff, 0x0e, 0x5f, 0x3f, 0xff, 0x0b, 0x66, 0x35, 0xff, 0x0f, 0x64, 0x39, 0xff, 0x0c, 0x56, 0x35, 0xff, 0x0b, 0x4d, 0x2e, 0xff, 0x08, 0x4e, 0x2d, 0xff, 0x07, 0x53, 0x30, 0xff, 0x0f, 0x4e, 0x2e, 0xff, 0x02, 0x28, 0x10, 0xff, 0x03, 0x1d, 0x0e, 0xff, 0x62, 0x6f, 0x68, 0xff, + 0x05, 0x29, 0x17, 0xff, 0x01, 0x29, 0x14, 0xff, 0x09, 0x36, 0x1f, 0xff, 0x0c, 0x3d, 0x22, 0xff, 0x0b, 0x3d, 0x23, 0xff, 0x09, 0x3d, 0x21, 0xff, 0x0b, 0x3c, 0x22, 0xff, 0x0d, 0x3b, 0x23, 0xff, 0x09, 0x3d, 0x21, 0xff, 0x06, 0x3d, 0x1f, 0xff, 0x06, 0x3c, 0x1f, 0xff, 0x10, 0x42, 0x2b, 0xff, 0x07, 0x34, 0x25, 0xff, 0x03, 0x2b, 0x24, 0xff, 0x21, 0x52, 0x5c, 0xff, 0x56, 0x8f, 0xaf, 0xff, 0x68, 0xa1, 0xc5, 0xff, 0x70, 0xa9, 0xd5, 0xff, 0x74, 0xac, 0xdc, 0xff, 0x76, 0xac, 0xe0, 0xff, 0x6c, 0x9f, 0xd5, 0xff, 0x63, 0x94, 0xc8, 0xff, 0x6c, 0x9c, 0xd1, 0xff, 0x78, 0xaa, 0xdf, 0xff, 0x74, 0xa9, 0xdc, 0xff, 0x70, 0xa9, 0xd9, 0xff, 0x77, 0xb0, 0xde, 0xff, 0x7f, 0xb4, 0xe2, 0xff, 0x85, 0xb7, 0xe5, 0xff, 0x35, 0x63, 0x90, 0xff, 0x1a, 0x44, 0x74, 0xff, 0x0b, 0x30, 0x66, 0xff, 0x0e, 0x34, 0x6a, 0xff, 0x22, 0x49, 0x7f, 0xff, 0x28, 0x4c, 0x84, 0xff, 0x2a, 0x4b, 0x83, 0xff, 0x39, 0x5d, 0x95, 0xff, 0x24, 0x4d, 0x86, 0xff, 0x5b, 0x92, 0xbd, 0xff, 0x33, 0x94, 0x8a, 0xff, 0x11, 0x8b, 0x5e, 0xff, 0x0e, 0x8e, 0x5d, 0xff, 0x12, 0x8c, 0x5a, 0xff, 0x12, 0x8d, 0x5a, 0xff, 0x0d, 0x8e, 0x5e, 0xff, 0x09, 0x8e, 0x5b, 0xff, 0x0e, 0x8e, 0x5d, 0xff, 0x14, 0x8f, 0x5d, 0xff, 0x18, 0x90, 0x60, 0xff, 0x17, 0x8f, 0x60, 0xff, 0x17, 0x91, 0x62, 0xff, 0x17, 0x98, 0x69, 0xff, 0x14, 0xa0, 0x6c, 0xff, 0x0e, 0xa3, 0x6e, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x11, 0xad, 0x71, 0xff, 0x15, 0xac, 0x74, 0xff, 0x1d, 0xa3, 0x6f, 0xff, 0x11, 0x85, 0x52, 0xff, 0x04, 0x61, 0x2d, 0xff, 0x05, 0x67, 0x2d, 0xff, 0x0c, 0x7d, 0x3a, 0xff, 0x0f, 0x88, 0x41, 0xff, 0x13, 0x8e, 0x49, 0xff, 0x14, 0x90, 0x4a, 0xff, 0x11, 0x8f, 0x47, 0xff, 0x0d, 0x8c, 0x44, 0xff, 0x0b, 0x8b, 0x42, 0xff, 0x08, 0x87, 0x3d, 0xff, 0x05, 0x82, 0x39, 0xff, 0x02, 0x80, 0x38, 0xff, 0x07, 0x85, 0x46, 0xff, 0x0b, 0x89, 0x4d, 0xff, 0x14, 0x97, 0x5e, 0xff, 0x1b, 0xa4, 0x6b, 0xff, 0x1b, 0xa8, 0x72, 0xff, 0x17, 0xa7, 0x71, 0xff, 0x11, 0xa8, 0x71, 0xff, 0x0f, 0xa8, 0x70, 0xff, 0x0f, 0xa7, 0x6f, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0d, 0xa6, 0x6b, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0e, 0xa3, 0x68, 0xff, 0x0e, 0xa2, 0x68, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x0e, 0xa3, 0x68, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0c, 0xa7, 0x6d, 0xff, 0x0c, 0xa7, 0x6d, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0a, 0xa6, 0x6b, 0xff, 0x0a, 0xa7, 0x6c, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x12, 0xa8, 0x74, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x11, 0xa5, 0x76, 0xff, 0x13, 0xa8, 0x7a, 0xff, 0x13, 0xa9, 0x7b, 0xff, 0x12, 0xa7, 0x79, 0xff, 0x13, 0xa8, 0x7a, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x14, 0xa7, 0x7a, 0xff, 0x14, 0xa7, 0x7a, 0xff, 0x14, 0xa6, 0x7b, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x12, 0xa9, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x0f, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x12, 0xa8, 0x79, 0xff, 0x12, 0xa8, 0x78, 0xff, 0x15, 0xa5, 0x7c, 0xff, 0x18, 0xa5, 0x7d, 0xff, 0x19, 0xa6, 0x7f, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x1c, 0xa8, 0x84, 0xff, 0x1d, 0xa8, 0x85, 0xff, 0x1d, 0xa7, 0x86, 0xff, 0x1d, 0xa7, 0x86, 0xff, 0x1c, 0xa6, 0x86, 0xff, 0x1c, 0xa6, 0x85, 0xff, 0x1d, 0xa7, 0x86, 0xff, 0x1e, 0xa7, 0x86, 0xff, 0x1d, 0xa7, 0x85, 0xff, 0x16, 0xa1, 0x7f, 0xff, 0x1c, 0xa7, 0x83, 0xff, 0x1b, 0xa8, 0x83, 0xff, 0x1c, 0xa5, 0x82, 0xff, 0x1f, 0xa6, 0x83, 0xff, 0x22, 0xa9, 0x86, 0xff, 0x20, 0xa7, 0x85, 0xff, 0x1b, 0xa5, 0x81, 0xff, 0x1b, 0xa6, 0x82, 0xff, 0x1a, 0xa7, 0x83, 0xff, 0x18, 0xa6, 0x82, 0xff, 0x1e, 0xa6, 0x84, 0xff, 0x1e, 0xa5, 0x84, 0xff, 0x16, 0xa7, 0x82, 0xff, 0x17, 0xa8, 0x80, 0xff, 0x22, 0xa5, 0x7c, 0xff, 0x13, 0x83, 0x5a, 0xff, 0x04, 0x5c, 0x32, 0xff, 0x0c, 0x5d, 0x33, 0xff, 0x0a, 0x58, 0x2d, 0xff, 0x07, 0x61, 0x32, 0xff, 0x16, 0x76, 0x46, 0xff, 0x12, 0x72, 0x43, 0xff, 0x0e, 0x62, 0x38, 0xff, 0x0b, 0x54, 0x2e, 0xff, 0x04, 0x41, 0x1e, 0xff, 0x01, 0x3d, 0x1d, 0xff, 0x09, 0x59, 0x39, 0xff, 0x19, 0x86, 0x64, 0xff, 0x1b, 0xa4, 0x7d, 0xff, 0x13, 0xa6, 0x7d, 0xff, 0x15, 0xa5, 0x7c, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0b, 0x9f, 0x68, 0xff, 0x0e, 0xa1, 0x69, 0xff, 0x0f, 0x9f, 0x68, 0xff, 0x0e, 0x9d, 0x66, 0xff, 0x10, 0x9c, 0x66, 0xff, 0x11, 0x9c, 0x66, 0xff, 0x11, 0x9c, 0x66, 0xff, 0x11, 0x9d, 0x66, 0xff, 0x10, 0x9e, 0x67, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x10, 0x9b, 0x65, 0xff, 0x11, 0x9c, 0x66, 0xff, 0x10, 0x9a, 0x66, 0xff, 0x11, 0x9b, 0x67, 0xff, 0x10, 0x9a, 0x67, 0xff, 0x0f, 0x98, 0x67, 0xff, 0x0f, 0x99, 0x67, 0xff, 0x0c, 0x99, 0x66, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x0c, 0x9c, 0x65, 0xff, 0x0c, 0x9e, 0x66, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0c, 0x9d, 0x65, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0d, 0x9a, 0x65, 0xff, 0x0d, 0x98, 0x65, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x0e, 0x96, 0x64, 0xff, 0x0d, 0x95, 0x65, 0xff, 0x09, 0x93, 0x61, 0xff, 0x10, 0x99, 0x64, 0xff, 0x13, 0x8b, 0x56, 0xff, 0x09, 0x6a, 0x38, 0xff, 0x10, 0x69, 0x38, 0xff, 0x13, 0x6a, 0x3a, 0xff, 0x0d, 0x68, 0x37, 0xff, 0x0a, 0x71, 0x3f, 0xff, 0x0c, 0x69, 0x3a, 0xff, 0x11, 0x68, 0x38, 0xff, 0x0b, 0x5e, 0x31, 0xff, 0x04, 0x58, 0x2c, 0xff, 0x01, 0x4a, 0x24, 0xff, 0x04, 0x49, 0x27, 0xff, 0x0e, 0x3f, 0x25, 0xff, 0x07, 0x2d, 0x18, 0xff, 0x05, 0x2a, 0x17, 0xff, 0x08, 0x38, 0x20, 0xff, 0x03, 0x32, 0x1a, 0xff, 0x01, 0x2e, 0x16, 0xff, 0x06, 0x3d, 0x25, 0xff, 0x06, 0x3c, 0x24, 0xff, 0x05, 0x31, 0x1a, 0xff, 0x01, 0x29, 0x11, 0xff, 0x06, 0x3a, 0x21, 0xff, 0x0d, 0x49, 0x2c, 0xff, 0x06, 0x45, 0x27, 0xff, 0x03, 0x42, 0x24, 0xff, 0x02, 0x41, 0x24, 0xff, 0x05, 0x45, 0x27, 0xff, 0x05, 0x51, 0x2a, 0xff, 0x08, 0x66, 0x31, 0xff, 0x0b, 0x81, 0x3d, 0xff, 0x05, 0x80, 0x39, 0xff, 0x0a, 0x7b, 0x39, 0xff, 0x19, 0x7a, 0x42, 0xff, 0x05, 0x52, 0x26, 0xff, 0x0a, 0x4a, 0x25, 0xff, 0x0d, 0x48, 0x26, 0xff, 0x0e, 0x4a, 0x24, 0xff, 0x0d, 0x4c, 0x22, 0xff, 0x0a, 0x4f, 0x24, 0xff, 0x0c, 0x4e, 0x29, 0xff, 0x0f, 0x4b, 0x28, 0xff, 0x0b, 0x4e, 0x25, 0xff, 0x05, 0x5e, 0x2f, 0xff, 0x15, 0x8a, 0x5f, 0xff, 0x0e, 0x84, 0x5b, 0xff, 0x0b, 0x6b, 0x3e, 0xff, 0x02, 0x50, 0x22, 0xff, 0x07, 0x51, 0x28, 0xff, 0x08, 0x56, 0x31, 0xff, 0x0f, 0x58, 0x36, 0xff, 0x06, 0x3a, 0x1d, 0xff, 0x04, 0x30, 0x13, 0xff, 0x13, 0x53, 0x31, 0xff, 0x0c, 0x55, 0x30, 0xff, 0x05, 0x41, 0x22, 0xff, 0x0a, 0x4f, 0x2e, 0xff, 0x10, 0x63, 0x3c, 0xff, 0x07, 0x55, 0x33, 0xff, 0x0f, 0x5b, 0x3c, 0xff, 0x09, 0x61, 0x38, 0xff, 0x09, 0x64, 0x36, 0xff, 0x0c, 0x62, 0x39, 0xff, 0x06, 0x54, 0x30, 0xff, 0x0a, 0x4c, 0x2c, 0xff, 0x08, 0x4e, 0x2c, 0xff, 0x07, 0x55, 0x30, 0xff, 0x10, 0x50, 0x2f, 0xff, 0x02, 0x28, 0x11, 0xff, 0x02, 0x1e, 0x0d, 0xff, 0x63, 0x6f, 0x69, 0xff, + 0x06, 0x2a, 0x19, 0xff, 0x00, 0x27, 0x13, 0xff, 0x08, 0x33, 0x1d, 0xff, 0x0b, 0x3a, 0x22, 0xff, 0x0b, 0x3a, 0x21, 0xff, 0x0a, 0x3d, 0x22, 0xff, 0x0d, 0x3b, 0x22, 0xff, 0x0e, 0x3b, 0x23, 0xff, 0x06, 0x3b, 0x1e, 0xff, 0x04, 0x40, 0x20, 0xff, 0x08, 0x44, 0x27, 0xff, 0x12, 0x49, 0x39, 0xff, 0x0b, 0x3c, 0x3a, 0xff, 0x33, 0x63, 0x71, 0xff, 0x63, 0x95, 0xb4, 0xff, 0x6b, 0xa2, 0xd4, 0xff, 0x75, 0xac, 0xde, 0xff, 0x79, 0xaf, 0xe0, 0xff, 0x70, 0xa5, 0xd7, 0xff, 0x55, 0x89, 0xbb, 0xff, 0x59, 0x8b, 0xbd, 0xff, 0x73, 0xa3, 0xd6, 0xff, 0x79, 0xab, 0xdd, 0xff, 0x77, 0xaa, 0xdc, 0xff, 0x78, 0xac, 0xdc, 0xff, 0x7d, 0xb0, 0xdf, 0xff, 0x7e, 0xb1, 0xdf, 0xff, 0x80, 0xb3, 0xe0, 0xff, 0x76, 0xa5, 0xd4, 0xff, 0x30, 0x5d, 0x8e, 0xff, 0x64, 0x8d, 0xbf, 0xff, 0x2e, 0x53, 0x89, 0xff, 0x26, 0x4c, 0x82, 0xff, 0x4a, 0x73, 0xa8, 0xff, 0x0f, 0x35, 0x6a, 0xff, 0x29, 0x4c, 0x81, 0xff, 0x39, 0x5e, 0x93, 0xff, 0x38, 0x61, 0x96, 0xff, 0x7e, 0xb7, 0xe0, 0xff, 0x31, 0x9a, 0x8d, 0xff, 0x0f, 0x90, 0x60, 0xff, 0x0c, 0x90, 0x5e, 0xff, 0x15, 0x91, 0x5e, 0xff, 0x18, 0x93, 0x5d, 0xff, 0x12, 0x91, 0x60, 0xff, 0x0c, 0x92, 0x5e, 0xff, 0x0d, 0x91, 0x5e, 0xff, 0x11, 0x93, 0x5f, 0xff, 0x11, 0x93, 0x5f, 0xff, 0x11, 0x95, 0x62, 0xff, 0x15, 0x9c, 0x69, 0xff, 0x18, 0xa4, 0x71, 0xff, 0x11, 0xa6, 0x70, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0d, 0xab, 0x70, 0xff, 0x19, 0xb1, 0x75, 0xff, 0x1b, 0xb9, 0x7e, 0xff, 0x06, 0xa9, 0x72, 0xff, 0x13, 0xab, 0x78, 0xff, 0x1c, 0x95, 0x65, 0xff, 0x0d, 0x6b, 0x3b, 0xff, 0x03, 0x5a, 0x23, 0xff, 0x02, 0x59, 0x21, 0xff, 0x05, 0x5b, 0x29, 0xff, 0x06, 0x63, 0x2f, 0xff, 0x06, 0x6a, 0x34, 0xff, 0x06, 0x70, 0x37, 0xff, 0x05, 0x79, 0x3d, 0xff, 0x04, 0x7b, 0x3e, 0xff, 0x09, 0x86, 0x49, 0xff, 0x16, 0x96, 0x58, 0xff, 0x1a, 0xa7, 0x68, 0xff, 0x18, 0xac, 0x6d, 0xff, 0x10, 0xac, 0x6f, 0xff, 0x0a, 0xac, 0x6f, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x15, 0xa8, 0x71, 0xff, 0x17, 0xa7, 0x70, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x0e, 0xa7, 0x6e, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa6, 0x6c, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x10, 0xa2, 0x6b, 0xff, 0x10, 0xa3, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x08, 0xa5, 0x6d, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0e, 0xa4, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa3, 0x6f, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0e, 0xa2, 0x71, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x12, 0xa4, 0x79, 0xff, 0x1f, 0xb2, 0x8a, 0xff, 0x22, 0xb4, 0x8c, 0xff, 0x14, 0xa6, 0x7c, 0xff, 0x14, 0xa5, 0x7b, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x14, 0xa6, 0x7a, 0xff, 0x15, 0xa5, 0x7b, 0xff, 0x15, 0xa5, 0x7c, 0xff, 0x15, 0xa8, 0x7c, 0xff, 0x14, 0xa8, 0x7b, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x11, 0xa7, 0x7a, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x14, 0xa8, 0x7b, 0xff, 0x16, 0xa4, 0x7d, 0xff, 0x19, 0xa4, 0x81, 0xff, 0x19, 0xa4, 0x81, 0xff, 0x19, 0xa5, 0x82, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1d, 0xa9, 0x86, 0xff, 0x1b, 0xa7, 0x85, 0xff, 0x1c, 0xa7, 0x86, 0xff, 0x1c, 0xa7, 0x87, 0xff, 0x1e, 0xa8, 0x86, 0xff, 0x1f, 0xa9, 0x87, 0xff, 0x23, 0xad, 0x8b, 0xff, 0x1d, 0xa8, 0x86, 0xff, 0x1b, 0xa7, 0x83, 0xff, 0x19, 0xa7, 0x82, 0xff, 0x1a, 0xa5, 0x82, 0xff, 0x1d, 0xa6, 0x84, 0xff, 0x1b, 0xa4, 0x82, 0xff, 0x1b, 0xa4, 0x82, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1a, 0xa6, 0x83, 0xff, 0x1a, 0xa7, 0x82, 0xff, 0x18, 0xa7, 0x81, 0xff, 0x1d, 0xa7, 0x83, 0xff, 0x1d, 0xa6, 0x84, 0xff, 0x17, 0xa7, 0x82, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x21, 0xa7, 0x81, 0xff, 0x23, 0x99, 0x72, 0xff, 0x07, 0x5b, 0x37, 0xff, 0x04, 0x45, 0x22, 0xff, 0x07, 0x46, 0x25, 0xff, 0x03, 0x46, 0x24, 0xff, 0x03, 0x47, 0x22, 0xff, 0x04, 0x48, 0x25, 0xff, 0x03, 0x40, 0x1e, 0xff, 0x01, 0x3b, 0x1c, 0xff, 0x04, 0x4e, 0x2e, 0xff, 0x12, 0x6f, 0x4e, 0xff, 0x24, 0x9b, 0x78, 0xff, 0x1a, 0xa5, 0x7f, 0xff, 0x15, 0xa5, 0x7d, 0xff, 0x18, 0xa5, 0x7d, 0xff, 0x1a, 0xa5, 0x7a, 0xff, 0x14, 0xa8, 0x78, 0xff, 0x0a, 0xa9, 0x75, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x12, 0xa6, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x08, 0xa6, 0x70, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x11, 0xa4, 0x6c, 0xff, 0x0e, 0xa2, 0x6a, 0xff, 0x0f, 0xa7, 0x6f, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x0b, 0x9e, 0x67, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0e, 0x9d, 0x66, 0xff, 0x0e, 0x9e, 0x67, 0xff, 0x0e, 0x9f, 0x68, 0xff, 0x11, 0x9e, 0x68, 0xff, 0x11, 0x9d, 0x67, 0xff, 0x10, 0x9c, 0x66, 0xff, 0x0f, 0x9a, 0x66, 0xff, 0x0e, 0x9b, 0x66, 0xff, 0x0d, 0x9b, 0x67, 0xff, 0x0b, 0x9a, 0x66, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x05, 0x9c, 0x67, 0xff, 0x06, 0x9e, 0x67, 0xff, 0x08, 0x9e, 0x66, 0xff, 0x09, 0x9f, 0x66, 0xff, 0x0b, 0x9f, 0x64, 0xff, 0x0c, 0x9e, 0x65, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0d, 0x9d, 0x67, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0c, 0x9a, 0x65, 0xff, 0x0c, 0x98, 0x65, 0xff, 0x0e, 0x99, 0x66, 0xff, 0x0d, 0x97, 0x66, 0xff, 0x0d, 0x97, 0x67, 0xff, 0x0b, 0x95, 0x63, 0xff, 0x0e, 0x9a, 0x64, 0xff, 0x12, 0x88, 0x54, 0xff, 0x0d, 0x6b, 0x3a, 0xff, 0x11, 0x6a, 0x3a, 0xff, 0x0c, 0x61, 0x32, 0xff, 0x0d, 0x69, 0x38, 0xff, 0x06, 0x6d, 0x3c, 0xff, 0x0e, 0x68, 0x3a, 0xff, 0x12, 0x68, 0x38, 0xff, 0x12, 0x6b, 0x3a, 0xff, 0x0f, 0x69, 0x3b, 0xff, 0x03, 0x50, 0x28, 0xff, 0x03, 0x47, 0x25, 0xff, 0x0d, 0x41, 0x26, 0xff, 0x06, 0x30, 0x19, 0xff, 0x02, 0x26, 0x13, 0xff, 0x07, 0x37, 0x1e, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x02, 0x30, 0x17, 0xff, 0x0a, 0x3d, 0x25, 0xff, 0x04, 0x36, 0x1e, 0xff, 0x00, 0x28, 0x11, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x06, 0x42, 0x26, 0xff, 0x07, 0x47, 0x2a, 0xff, 0x04, 0x44, 0x26, 0xff, 0x02, 0x42, 0x25, 0xff, 0x03, 0x3e, 0x24, 0xff, 0x02, 0x3c, 0x21, 0xff, 0x04, 0x4c, 0x25, 0xff, 0x0b, 0x69, 0x34, 0xff, 0x0d, 0x87, 0x40, 0xff, 0x05, 0x83, 0x3a, 0xff, 0x04, 0x78, 0x35, 0xff, 0x0d, 0x74, 0x3a, 0xff, 0x12, 0x67, 0x39, 0xff, 0x02, 0x4a, 0x22, 0xff, 0x09, 0x49, 0x25, 0xff, 0x0e, 0x49, 0x24, 0xff, 0x0f, 0x49, 0x22, 0xff, 0x0c, 0x4d, 0x23, 0xff, 0x0c, 0x4e, 0x27, 0xff, 0x0e, 0x4c, 0x26, 0xff, 0x0a, 0x4f, 0x23, 0xff, 0x03, 0x5c, 0x2c, 0xff, 0x14, 0x87, 0x5e, 0xff, 0x0f, 0x82, 0x5b, 0xff, 0x0c, 0x6a, 0x3c, 0xff, 0x04, 0x4d, 0x22, 0xff, 0x06, 0x47, 0x21, 0xff, 0x09, 0x57, 0x31, 0xff, 0x0a, 0x57, 0x34, 0xff, 0x0c, 0x45, 0x27, 0xff, 0x05, 0x35, 0x17, 0xff, 0x15, 0x58, 0x36, 0xff, 0x05, 0x4c, 0x28, 0xff, 0x03, 0x3f, 0x21, 0xff, 0x0f, 0x56, 0x37, 0xff, 0x0b, 0x60, 0x39, 0xff, 0x08, 0x56, 0x2d, 0xff, 0x10, 0x61, 0x35, 0xff, 0x08, 0x62, 0x34, 0xff, 0x08, 0x62, 0x35, 0xff, 0x0b, 0x61, 0x38, 0xff, 0x04, 0x52, 0x2f, 0xff, 0x0a, 0x4c, 0x2b, 0xff, 0x08, 0x4e, 0x2b, 0xff, 0x06, 0x54, 0x2f, 0xff, 0x0f, 0x50, 0x2f, 0xff, 0x02, 0x2a, 0x13, 0xff, 0x01, 0x1e, 0x0d, 0xff, 0x63, 0x6f, 0x6a, 0xff, + 0x08, 0x2d, 0x1b, 0xff, 0x00, 0x25, 0x11, 0xff, 0x04, 0x2f, 0x19, 0xff, 0x0c, 0x3a, 0x22, 0xff, 0x0b, 0x3a, 0x21, 0xff, 0x0b, 0x3c, 0x22, 0xff, 0x0c, 0x3a, 0x22, 0xff, 0x0c, 0x3b, 0x21, 0xff, 0x03, 0x3c, 0x1d, 0xff, 0x06, 0x48, 0x27, 0xff, 0x0b, 0x4e, 0x32, 0xff, 0x16, 0x53, 0x4d, 0xff, 0x3e, 0x75, 0x85, 0xff, 0x66, 0x99, 0xc0, 0xff, 0x67, 0x98, 0xc9, 0xff, 0x6f, 0xa3, 0xd7, 0xff, 0x77, 0xab, 0xdf, 0xff, 0x5c, 0x8d, 0xc1, 0xff, 0x45, 0x76, 0xa9, 0xff, 0x58, 0x8a, 0xbb, 0xff, 0x71, 0xa2, 0xd4, 0xff, 0x7a, 0xac, 0xdc, 0xff, 0x77, 0xab, 0xdb, 0xff, 0x76, 0xac, 0xdb, 0xff, 0x80, 0xb2, 0xe1, 0xff, 0x6e, 0x9e, 0xcd, 0xff, 0x38, 0x64, 0x93, 0xff, 0x43, 0x6f, 0x9f, 0xff, 0x6e, 0x9b, 0xce, 0xff, 0x41, 0x6e, 0xa3, 0xff, 0x72, 0x9c, 0xd1, 0xff, 0x4c, 0x71, 0xa7, 0xff, 0x37, 0x5e, 0x93, 0xff, 0x2c, 0x54, 0x89, 0xff, 0x0c, 0x32, 0x66, 0xff, 0x3f, 0x63, 0x97, 0xff, 0x53, 0x78, 0xab, 0xff, 0x3b, 0x64, 0x96, 0xff, 0x66, 0x9e, 0xc4, 0xff, 0x28, 0x8f, 0x82, 0xff, 0x0c, 0x90, 0x61, 0xff, 0x0b, 0x95, 0x62, 0xff, 0x12, 0x94, 0x5f, 0xff, 0x16, 0x94, 0x5f, 0xff, 0x11, 0x93, 0x61, 0xff, 0x0e, 0x95, 0x60, 0xff, 0x0e, 0x94, 0x60, 0xff, 0x08, 0x95, 0x5f, 0xff, 0x0b, 0x99, 0x64, 0xff, 0x0e, 0x9d, 0x6a, 0xff, 0x15, 0xa7, 0x73, 0xff, 0x1e, 0xb2, 0x7d, 0xff, 0x14, 0xaa, 0x74, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x15, 0xa8, 0x71, 0xff, 0x2c, 0xba, 0x82, 0xff, 0x21, 0xb7, 0x7f, 0xff, 0x11, 0xae, 0x76, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x18, 0xac, 0x75, 0xff, 0x15, 0xa5, 0x6e, 0xff, 0x11, 0x9c, 0x64, 0xff, 0x14, 0x99, 0x62, 0xff, 0x18, 0x94, 0x62, 0xff, 0x16, 0x95, 0x62, 0xff, 0x17, 0x9a, 0x64, 0xff, 0x16, 0x9d, 0x65, 0xff, 0x15, 0xa0, 0x67, 0xff, 0x12, 0xa1, 0x69, 0xff, 0x10, 0xa3, 0x6a, 0xff, 0x13, 0xa8, 0x6e, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x0c, 0xab, 0x6a, 0xff, 0x08, 0xaa, 0x6c, 0xff, 0x07, 0xac, 0x6f, 0xff, 0x0a, 0xaa, 0x71, 0xff, 0x0d, 0xa8, 0x70, 0xff, 0x13, 0xa7, 0x6f, 0xff, 0x15, 0xa8, 0x70, 0xff, 0x11, 0xa9, 0x72, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x0c, 0xa5, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x67, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0d, 0xa4, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x11, 0xa5, 0x76, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x18, 0xaa, 0x81, 0xff, 0x25, 0xb6, 0x91, 0xff, 0x27, 0xb7, 0x94, 0xff, 0x16, 0xa7, 0x81, 0xff, 0x13, 0xa5, 0x7e, 0xff, 0x16, 0xa6, 0x7d, 0xff, 0x17, 0xa7, 0x7c, 0xff, 0x17, 0xa6, 0x7e, 0xff, 0x17, 0xa5, 0x7e, 0xff, 0x17, 0xa7, 0x7d, 0xff, 0x16, 0xa7, 0x7c, 0xff, 0x14, 0xa7, 0x7c, 0xff, 0x12, 0xa6, 0x7b, 0xff, 0x12, 0xa6, 0x7b, 0xff, 0x12, 0xa6, 0x7b, 0xff, 0x14, 0xa6, 0x7c, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x19, 0xa5, 0x82, 0xff, 0x1d, 0xa8, 0x86, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1a, 0xa5, 0x83, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1d, 0xa8, 0x87, 0xff, 0x1c, 0xa7, 0x84, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1c, 0xa6, 0x84, 0xff, 0x1e, 0xaa, 0x85, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x19, 0xa8, 0x83, 0xff, 0x1b, 0xa9, 0x85, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1b, 0xa5, 0x83, 0xff, 0x1b, 0xa7, 0x83, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x19, 0xa8, 0x82, 0xff, 0x18, 0xa8, 0x81, 0xff, 0x1a, 0xa8, 0x82, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1b, 0xa6, 0x80, 0xff, 0x23, 0xa5, 0x7f, 0xff, 0x22, 0x8f, 0x6c, 0xff, 0x13, 0x6a, 0x49, 0xff, 0x05, 0x49, 0x2b, 0xff, 0x02, 0x40, 0x23, 0xff, 0x00, 0x3b, 0x1e, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x08, 0x4f, 0x2f, 0xff, 0x12, 0x6e, 0x4c, 0xff, 0x1a, 0x8f, 0x6c, 0xff, 0x20, 0xa0, 0x7c, 0xff, 0x19, 0xa6, 0x7f, 0xff, 0x0e, 0xa6, 0x7b, 0xff, 0x16, 0xa6, 0x7d, 0xff, 0x18, 0xa5, 0x7b, 0xff, 0x16, 0xa7, 0x7b, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x0a, 0xa8, 0x74, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x07, 0x9e, 0x66, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x09, 0x9d, 0x65, 0xff, 0x0b, 0x9c, 0x65, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x0d, 0x9e, 0x67, 0xff, 0x0e, 0x9e, 0x67, 0xff, 0x0e, 0x9d, 0x66, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0f, 0x9d, 0x68, 0xff, 0x0c, 0x9e, 0x69, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x09, 0xa0, 0x64, 0xff, 0x0a, 0xa1, 0x64, 0xff, 0x0b, 0x9f, 0x65, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0e, 0x9e, 0x67, 0xff, 0x0e, 0x9f, 0x66, 0xff, 0x0d, 0x9d, 0x66, 0xff, 0x0d, 0x9c, 0x66, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x0f, 0x9b, 0x67, 0xff, 0x11, 0x9b, 0x68, 0xff, 0x11, 0x9a, 0x68, 0xff, 0x12, 0xa1, 0x6b, 0xff, 0x0b, 0x83, 0x50, 0xff, 0x0c, 0x6d, 0x3e, 0xff, 0x06, 0x61, 0x32, 0xff, 0x06, 0x5d, 0x2f, 0xff, 0x10, 0x6b, 0x3c, 0xff, 0x07, 0x6c, 0x3c, 0xff, 0x12, 0x66, 0x39, 0xff, 0x10, 0x68, 0x37, 0xff, 0x0a, 0x69, 0x38, 0xff, 0x12, 0x73, 0x43, 0xff, 0x14, 0x6e, 0x44, 0xff, 0x0b, 0x58, 0x35, 0xff, 0x07, 0x42, 0x26, 0xff, 0x05, 0x35, 0x1c, 0xff, 0x00, 0x27, 0x11, 0xff, 0x05, 0x35, 0x1c, 0xff, 0x05, 0x34, 0x1a, 0xff, 0x03, 0x30, 0x18, 0xff, 0x0b, 0x3a, 0x23, 0xff, 0x01, 0x2d, 0x18, 0xff, 0x01, 0x29, 0x12, 0xff, 0x06, 0x36, 0x1c, 0xff, 0x04, 0x47, 0x2a, 0xff, 0x04, 0x47, 0x29, 0xff, 0x06, 0x47, 0x2a, 0xff, 0x04, 0x45, 0x2a, 0xff, 0x06, 0x41, 0x28, 0xff, 0x07, 0x41, 0x27, 0xff, 0x04, 0x4b, 0x25, 0xff, 0x11, 0x70, 0x3a, 0xff, 0x0b, 0x89, 0x41, 0xff, 0x07, 0x84, 0x3b, 0xff, 0x05, 0x77, 0x36, 0xff, 0x05, 0x70, 0x35, 0xff, 0x12, 0x70, 0x3e, 0xff, 0x05, 0x56, 0x2a, 0xff, 0x05, 0x4a, 0x22, 0xff, 0x0c, 0x49, 0x23, 0xff, 0x12, 0x48, 0x23, 0xff, 0x0e, 0x4c, 0x23, 0xff, 0x0e, 0x4f, 0x27, 0xff, 0x0e, 0x4f, 0x26, 0xff, 0x09, 0x51, 0x22, 0xff, 0x01, 0x59, 0x28, 0xff, 0x13, 0x84, 0x5b, 0xff, 0x11, 0x83, 0x5b, 0xff, 0x0b, 0x69, 0x3b, 0xff, 0x07, 0x49, 0x1f, 0xff, 0x05, 0x3c, 0x19, 0xff, 0x09, 0x56, 0x32, 0xff, 0x06, 0x55, 0x32, 0xff, 0x12, 0x4e, 0x2f, 0xff, 0x06, 0x3a, 0x1b, 0xff, 0x1a, 0x5e, 0x3d, 0xff, 0x0e, 0x52, 0x30, 0xff, 0x04, 0x3d, 0x20, 0xff, 0x06, 0x4d, 0x2d, 0xff, 0x02, 0x53, 0x2b, 0xff, 0x0a, 0x57, 0x2d, 0xff, 0x14, 0x62, 0x37, 0xff, 0x08, 0x61, 0x31, 0xff, 0x0a, 0x60, 0x32, 0xff, 0x0d, 0x60, 0x37, 0xff, 0x07, 0x53, 0x2f, 0xff, 0x08, 0x4a, 0x28, 0xff, 0x09, 0x50, 0x2b, 0xff, 0x05, 0x54, 0x2e, 0xff, 0x0f, 0x52, 0x30, 0xff, 0x03, 0x2d, 0x15, 0xff, 0x00, 0x1d, 0x0d, 0xff, 0x63, 0x6f, 0x6a, 0xff, + 0x09, 0x2f, 0x1d, 0xff, 0x01, 0x25, 0x13, 0xff, 0x03, 0x2b, 0x17, 0xff, 0x0d, 0x39, 0x23, 0xff, 0x0b, 0x39, 0x22, 0xff, 0x0c, 0x3c, 0x22, 0xff, 0x0c, 0x3b, 0x21, 0xff, 0x0b, 0x3c, 0x21, 0xff, 0x02, 0x3e, 0x1d, 0xff, 0x06, 0x4c, 0x29, 0xff, 0x09, 0x51, 0x37, 0xff, 0x34, 0x75, 0x76, 0xff, 0x67, 0xa0, 0xbd, 0xff, 0x5d, 0x90, 0xca, 0xff, 0x57, 0x88, 0xc6, 0xff, 0x6a, 0x9a, 0xcf, 0xff, 0x53, 0x84, 0xb7, 0xff, 0x3a, 0x69, 0x9b, 0xff, 0x58, 0x86, 0xb7, 0xff, 0x77, 0xa8, 0xd9, 0xff, 0x7c, 0xad, 0xdf, 0xff, 0x75, 0xaa, 0xdc, 0xff, 0x76, 0xad, 0xdd, 0xff, 0x7f, 0xb5, 0xe2, 0xff, 0x82, 0xb4, 0xe2, 0xff, 0x3c, 0x68, 0x98, 0xff, 0x0d, 0x34, 0x65, 0xff, 0x20, 0x48, 0x7b, 0xff, 0x70, 0x9a, 0xcf, 0xff, 0x46, 0x71, 0xaa, 0xff, 0x71, 0x9b, 0xd4, 0xff, 0x38, 0x5f, 0x94, 0xff, 0x27, 0x4f, 0x84, 0xff, 0x2c, 0x55, 0x88, 0xff, 0x18, 0x3f, 0x72, 0xff, 0x5f, 0x84, 0xb6, 0xff, 0x67, 0x8d, 0xbd, 0xff, 0x44, 0x6f, 0x9d, 0xff, 0x4f, 0x86, 0xa9, 0xff, 0x2c, 0x8c, 0x80, 0xff, 0x11, 0x93, 0x62, 0xff, 0x09, 0x96, 0x62, 0xff, 0x0e, 0x96, 0x61, 0xff, 0x12, 0x96, 0x5f, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0e, 0x97, 0x62, 0xff, 0x0f, 0x97, 0x63, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0c, 0x9f, 0x6d, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x17, 0xae, 0x7a, 0xff, 0x14, 0xaa, 0x75, 0xff, 0x11, 0xa3, 0x6d, 0xff, 0x16, 0xa5, 0x70, 0xff, 0x2f, 0xbb, 0x87, 0xff, 0x1f, 0xb1, 0x7a, 0xff, 0x19, 0xb4, 0x79, 0xff, 0x10, 0xaf, 0x71, 0xff, 0x0e, 0xaf, 0x71, 0xff, 0x10, 0xae, 0x73, 0xff, 0x13, 0xac, 0x74, 0xff, 0x18, 0xac, 0x76, 0xff, 0x15, 0xab, 0x72, 0xff, 0x14, 0xac, 0x72, 0xff, 0x18, 0xaf, 0x74, 0xff, 0x14, 0xac, 0x70, 0xff, 0x12, 0xaa, 0x6d, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x0b, 0xab, 0x6a, 0xff, 0x05, 0xa4, 0x64, 0xff, 0x0d, 0xa8, 0x6b, 0xff, 0x0d, 0xa6, 0x6a, 0xff, 0x10, 0xa6, 0x6c, 0xff, 0x0f, 0xa7, 0x6d, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x67, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa7, 0x6b, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x14, 0xa6, 0x75, 0xff, 0x11, 0xa5, 0x73, 0xff, 0x0f, 0xa7, 0x71, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x78, 0xff, 0x12, 0xa6, 0x79, 0xff, 0x13, 0xa4, 0x7b, 0xff, 0x18, 0xaa, 0x82, 0xff, 0x1d, 0xac, 0x8b, 0xff, 0x1b, 0xaa, 0x89, 0xff, 0x14, 0xa4, 0x81, 0xff, 0x13, 0xa5, 0x7f, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x18, 0xa7, 0x7f, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x18, 0xa6, 0x7f, 0xff, 0x17, 0xa6, 0x7e, 0xff, 0x15, 0xa6, 0x7e, 0xff, 0x14, 0xa5, 0x7d, 0xff, 0x14, 0xa6, 0x7e, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x14, 0xa5, 0x7d, 0xff, 0x18, 0xa6, 0x7f, 0xff, 0x19, 0xa5, 0x83, 0xff, 0x1c, 0xa7, 0x86, 0xff, 0x1b, 0xa6, 0x85, 0xff, 0x1a, 0xa5, 0x84, 0xff, 0x20, 0xab, 0x89, 0xff, 0x23, 0xae, 0x8b, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x1a, 0xa6, 0x83, 0xff, 0x1b, 0xa5, 0x84, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x1a, 0xa8, 0x83, 0xff, 0x1a, 0xaa, 0x84, 0xff, 0x1b, 0xab, 0x87, 0xff, 0x1c, 0xa9, 0x87, 0xff, 0x1a, 0xa7, 0x84, 0xff, 0x19, 0xa6, 0x83, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x19, 0xa9, 0x82, 0xff, 0x17, 0xa8, 0x81, 0xff, 0x18, 0xa8, 0x82, 0xff, 0x18, 0xa8, 0x81, 0xff, 0x1b, 0xa7, 0x81, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x15, 0xa5, 0x7f, 0xff, 0x23, 0xa7, 0x82, 0xff, 0x27, 0x9d, 0x7a, 0xff, 0x1f, 0x84, 0x65, 0xff, 0x13, 0x68, 0x4c, 0xff, 0x08, 0x5a, 0x3e, 0xff, 0x0b, 0x63, 0x44, 0xff, 0x20, 0x8c, 0x69, 0xff, 0x26, 0xa1, 0x7b, 0xff, 0x1e, 0xa6, 0x80, 0xff, 0x1a, 0xa6, 0x80, 0xff, 0x15, 0xa7, 0x7f, 0xff, 0x12, 0xa7, 0x7d, 0xff, 0x15, 0xa4, 0x7a, 0xff, 0x15, 0xa7, 0x7c, 0xff, 0x0c, 0xa8, 0x7a, 0xff, 0x0c, 0xa8, 0x78, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x05, 0xa1, 0x68, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0b, 0x9e, 0x67, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x09, 0x9d, 0x67, 0xff, 0x0c, 0x9f, 0x69, 0xff, 0x0d, 0x9f, 0x67, 0xff, 0x0d, 0x9f, 0x68, 0xff, 0x10, 0xa1, 0x6a, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0e, 0xa2, 0x67, 0xff, 0x0f, 0xa1, 0x65, 0xff, 0x0d, 0xa0, 0x65, 0xff, 0x0c, 0x9f, 0x65, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x08, 0x9f, 0x68, 0xff, 0x0c, 0xa1, 0x66, 0xff, 0x0a, 0xa0, 0x65, 0xff, 0x09, 0xa0, 0x66, 0xff, 0x0a, 0xa0, 0x67, 0xff, 0x0a, 0x9e, 0x67, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x12, 0x9f, 0x6a, 0xff, 0x11, 0x9f, 0x6a, 0xff, 0x0e, 0xa2, 0x6a, 0xff, 0x10, 0x8c, 0x58, 0xff, 0x06, 0x69, 0x39, 0xff, 0x02, 0x60, 0x31, 0xff, 0x08, 0x61, 0x33, 0xff, 0x11, 0x6d, 0x3e, 0xff, 0x08, 0x6b, 0x3b, 0xff, 0x14, 0x66, 0x37, 0xff, 0x0f, 0x69, 0x36, 0xff, 0x0c, 0x70, 0x3d, 0xff, 0x0f, 0x75, 0x45, 0xff, 0x14, 0x73, 0x48, 0xff, 0x0d, 0x5e, 0x39, 0xff, 0x05, 0x46, 0x28, 0xff, 0x03, 0x38, 0x1f, 0xff, 0x00, 0x28, 0x11, 0xff, 0x04, 0x32, 0x18, 0xff, 0x05, 0x34, 0x1a, 0xff, 0x04, 0x30, 0x19, 0xff, 0x08, 0x34, 0x1e, 0xff, 0x00, 0x29, 0x14, 0xff, 0x04, 0x2c, 0x16, 0xff, 0x0b, 0x3e, 0x24, 0xff, 0x03, 0x4a, 0x2c, 0xff, 0x03, 0x47, 0x2b, 0xff, 0x04, 0x46, 0x2b, 0xff, 0x02, 0x44, 0x2a, 0xff, 0x05, 0x41, 0x29, 0xff, 0x08, 0x42, 0x29, 0xff, 0x05, 0x4c, 0x25, 0xff, 0x14, 0x76, 0x40, 0xff, 0x07, 0x89, 0x40, 0xff, 0x07, 0x83, 0x3b, 0xff, 0x04, 0x76, 0x36, 0xff, 0x05, 0x73, 0x37, 0xff, 0x09, 0x6e, 0x38, 0xff, 0x0d, 0x67, 0x37, 0xff, 0x05, 0x50, 0x25, 0xff, 0x0b, 0x4a, 0x23, 0xff, 0x13, 0x48, 0x24, 0xff, 0x0f, 0x4b, 0x24, 0xff, 0x0f, 0x50, 0x28, 0xff, 0x0f, 0x50, 0x26, 0xff, 0x0a, 0x53, 0x22, 0xff, 0x01, 0x58, 0x26, 0xff, 0x10, 0x82, 0x58, 0xff, 0x11, 0x82, 0x5c, 0xff, 0x0c, 0x69, 0x3b, 0xff, 0x0a, 0x47, 0x1f, 0xff, 0x04, 0x35, 0x13, 0xff, 0x09, 0x55, 0x30, 0xff, 0x04, 0x54, 0x30, 0xff, 0x13, 0x53, 0x32, 0xff, 0x06, 0x3e, 0x1f, 0xff, 0x1a, 0x5e, 0x3e, 0xff, 0x15, 0x56, 0x35, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x07, 0x4d, 0x2b, 0xff, 0x02, 0x52, 0x28, 0xff, 0x0b, 0x55, 0x2d, 0xff, 0x17, 0x62, 0x3a, 0xff, 0x07, 0x5e, 0x2f, 0xff, 0x0a, 0x5e, 0x2f, 0xff, 0x0e, 0x5f, 0x36, 0xff, 0x09, 0x55, 0x31, 0xff, 0x07, 0x49, 0x26, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x03, 0x53, 0x2d, 0xff, 0x10, 0x53, 0x31, 0xff, 0x04, 0x2e, 0x16, 0xff, 0x00, 0x1d, 0x0d, 0xff, 0x63, 0x6f, 0x6a, 0xff, + 0x08, 0x32, 0x20, 0xff, 0x00, 0x26, 0x15, 0xff, 0x02, 0x26, 0x17, 0xff, 0x0c, 0x35, 0x23, 0xff, 0x0d, 0x3c, 0x20, 0xff, 0x0e, 0x3b, 0x1f, 0xff, 0x0e, 0x3a, 0x21, 0xff, 0x08, 0x3d, 0x22, 0xff, 0x01, 0x44, 0x21, 0xff, 0x0c, 0x67, 0x43, 0xff, 0x15, 0x6e, 0x57, 0xff, 0x2a, 0x6d, 0x7b, 0xff, 0x40, 0x7a, 0x9d, 0xff, 0x49, 0x7a, 0xb1, 0xff, 0x49, 0x75, 0xb3, 0xff, 0x29, 0x57, 0x89, 0xff, 0x3f, 0x6e, 0x9e, 0xff, 0x71, 0xa2, 0xcf, 0xff, 0x80, 0xb1, 0xde, 0xff, 0x7c, 0xae, 0xdc, 0xff, 0x7b, 0xac, 0xdd, 0xff, 0x7c, 0xaf, 0xe1, 0xff, 0x77, 0xa8, 0xd9, 0xff, 0x68, 0x97, 0xc6, 0xff, 0x76, 0xa4, 0xd3, 0xff, 0x30, 0x5a, 0x8b, 0xff, 0x5f, 0x88, 0xbb, 0xff, 0x42, 0x6c, 0xa0, 0xff, 0x53, 0x7e, 0xb5, 0xff, 0x41, 0x6d, 0xa5, 0xff, 0x59, 0x84, 0xbb, 0xff, 0x1d, 0x44, 0x78, 0xff, 0x22, 0x48, 0x7f, 0xff, 0x62, 0x8e, 0xc4, 0xff, 0x34, 0x62, 0x95, 0xff, 0x65, 0x8f, 0xbe, 0xff, 0x6b, 0x93, 0xc0, 0xff, 0x77, 0xa5, 0xd1, 0xff, 0x78, 0xb3, 0xd6, 0xff, 0x39, 0x97, 0x90, 0xff, 0x10, 0x92, 0x60, 0xff, 0x08, 0x99, 0x62, 0xff, 0x0a, 0x96, 0x65, 0xff, 0x0e, 0x97, 0x62, 0xff, 0x0c, 0x97, 0x62, 0xff, 0x0e, 0x9a, 0x66, 0xff, 0x0f, 0x9c, 0x68, 0xff, 0x11, 0xa4, 0x72, 0xff, 0x15, 0xa6, 0x76, 0xff, 0x0b, 0x9d, 0x6a, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x12, 0xac, 0x74, 0xff, 0x12, 0xad, 0x74, 0xff, 0x10, 0xa8, 0x6e, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x26, 0xbd, 0x88, 0xff, 0x13, 0xac, 0x75, 0xff, 0x1a, 0xb9, 0x7b, 0xff, 0x13, 0xb7, 0x75, 0xff, 0x0a, 0xaf, 0x6c, 0xff, 0x0b, 0xae, 0x6f, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x10, 0xb2, 0x75, 0xff, 0x0d, 0xb6, 0x74, 0xff, 0x0f, 0xb6, 0x73, 0xff, 0x0d, 0xb1, 0x6e, 0xff, 0x0a, 0xab, 0x68, 0xff, 0x0e, 0xae, 0x6d, 0xff, 0x10, 0xaf, 0x70, 0xff, 0x0b, 0xab, 0x6b, 0xff, 0x0b, 0xad, 0x6b, 0xff, 0x0c, 0xad, 0x69, 0xff, 0x0c, 0xac, 0x67, 0xff, 0x10, 0xae, 0x68, 0xff, 0x0a, 0xa2, 0x60, 0xff, 0x0c, 0xa0, 0x5f, 0xff, 0x0b, 0x9f, 0x61, 0xff, 0x05, 0xa0, 0x61, 0xff, 0x02, 0xa0, 0x61, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0e, 0xa4, 0x6b, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0d, 0xa5, 0x69, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6a, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0c, 0xa5, 0x6c, 0xff, 0x0d, 0xa5, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0e, 0xa5, 0x6f, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x13, 0xa5, 0x71, 0xff, 0x14, 0xa6, 0x73, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x13, 0xa5, 0x79, 0xff, 0x14, 0xa5, 0x7a, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x1e, 0xab, 0x86, 0xff, 0x1b, 0xa6, 0x85, 0xff, 0x16, 0xa2, 0x80, 0xff, 0x17, 0xa4, 0x80, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x19, 0xa6, 0x7e, 0xff, 0x19, 0xa6, 0x7f, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x1a, 0xa6, 0x80, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x17, 0xa6, 0x80, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x19, 0xaa, 0x83, 0xff, 0x17, 0xa8, 0x82, 0xff, 0x15, 0xa5, 0x80, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x83, 0xff, 0x1a, 0xa6, 0x84, 0xff, 0x19, 0xa6, 0x83, 0xff, 0x1a, 0xa7, 0x84, 0xff, 0x20, 0xac, 0x8a, 0xff, 0x20, 0xac, 0x89, 0xff, 0x16, 0xa3, 0x7e, 0xff, 0x16, 0xa5, 0x7f, 0xff, 0x19, 0xa5, 0x82, 0xff, 0x1e, 0xa9, 0x87, 0xff, 0x24, 0xaf, 0x8d, 0xff, 0x1e, 0xa9, 0x86, 0xff, 0x18, 0xa5, 0x80, 0xff, 0x19, 0xa7, 0x82, 0xff, 0x1b, 0xa9, 0x85, 0xff, 0x1b, 0xaa, 0x87, 0xff, 0x1b, 0xaa, 0x88, 0xff, 0x19, 0xa8, 0x87, 0xff, 0x18, 0xa6, 0x85, 0xff, 0x19, 0xa6, 0x85, 0xff, 0x1a, 0xa6, 0x83, 0xff, 0x1a, 0xa6, 0x83, 0xff, 0x19, 0xa8, 0x83, 0xff, 0x18, 0xa8, 0x83, 0xff, 0x17, 0xa8, 0x82, 0xff, 0x18, 0xa8, 0x81, 0xff, 0x1b, 0xa8, 0x81, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x16, 0xa7, 0x80, 0xff, 0x14, 0xa8, 0x81, 0xff, 0x16, 0xa7, 0x80, 0xff, 0x1c, 0xa7, 0x81, 0xff, 0x25, 0xa6, 0x83, 0xff, 0x27, 0xa4, 0x82, 0xff, 0x24, 0xa2, 0x80, 0xff, 0x21, 0xa4, 0x80, 0xff, 0x1e, 0xa7, 0x81, 0xff, 0x18, 0xa5, 0x7e, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x14, 0xa5, 0x7d, 0xff, 0x16, 0xa6, 0x7e, 0xff, 0x17, 0xa8, 0x7d, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x0c, 0xa9, 0x79, 0xff, 0x0c, 0xa7, 0x77, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x09, 0xa6, 0x6b, 0xff, 0x07, 0xa2, 0x68, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x0b, 0x9f, 0x66, 0xff, 0x0d, 0x9f, 0x66, 0xff, 0x0b, 0x9d, 0x65, 0xff, 0x07, 0x9e, 0x65, 0xff, 0x08, 0xa0, 0x68, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0e, 0xa3, 0x68, 0xff, 0x10, 0xa0, 0x66, 0xff, 0x0f, 0xa1, 0x65, 0xff, 0x0c, 0x9f, 0x64, 0xff, 0x09, 0x9f, 0x64, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x0a, 0xa1, 0x66, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0c, 0xa2, 0x69, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x0d, 0xa1, 0x6a, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x12, 0x8e, 0x5a, 0xff, 0x08, 0x6b, 0x3b, 0xff, 0x0b, 0x69, 0x39, 0xff, 0x07, 0x64, 0x34, 0xff, 0x0e, 0x6d, 0x3c, 0xff, 0x08, 0x6a, 0x39, 0xff, 0x0f, 0x69, 0x38, 0xff, 0x10, 0x71, 0x3d, 0xff, 0x0c, 0x78, 0x42, 0xff, 0x09, 0x7b, 0x46, 0xff, 0x07, 0x6c, 0x3d, 0xff, 0x02, 0x58, 0x30, 0xff, 0x06, 0x44, 0x25, 0xff, 0x06, 0x38, 0x1e, 0xff, 0x00, 0x29, 0x12, 0xff, 0x04, 0x2f, 0x17, 0xff, 0x03, 0x33, 0x1b, 0xff, 0x02, 0x2e, 0x18, 0xff, 0x07, 0x2d, 0x19, 0xff, 0x05, 0x28, 0x15, 0xff, 0x09, 0x34, 0x1f, 0xff, 0x0c, 0x44, 0x2e, 0xff, 0x01, 0x46, 0x2f, 0xff, 0x01, 0x46, 0x2b, 0xff, 0x02, 0x46, 0x2a, 0xff, 0x01, 0x43, 0x29, 0xff, 0x06, 0x42, 0x2a, 0xff, 0x07, 0x45, 0x29, 0xff, 0x07, 0x55, 0x29, 0xff, 0x15, 0x7e, 0x42, 0xff, 0x04, 0x87, 0x3b, 0xff, 0x07, 0x82, 0x3c, 0xff, 0x06, 0x77, 0x37, 0xff, 0x02, 0x72, 0x35, 0xff, 0x05, 0x72, 0x38, 0xff, 0x0d, 0x73, 0x3c, 0xff, 0x0b, 0x66, 0x32, 0xff, 0x08, 0x56, 0x28, 0xff, 0x0b, 0x4b, 0x22, 0xff, 0x0c, 0x4c, 0x23, 0xff, 0x13, 0x51, 0x28, 0xff, 0x13, 0x50, 0x26, 0xff, 0x0b, 0x51, 0x24, 0xff, 0x01, 0x54, 0x26, 0xff, 0x11, 0x7f, 0x55, 0xff, 0x10, 0x83, 0x5a, 0xff, 0x0d, 0x66, 0x3b, 0xff, 0x08, 0x46, 0x21, 0xff, 0x03, 0x2d, 0x12, 0xff, 0x0c, 0x4f, 0x30, 0xff, 0x03, 0x55, 0x2d, 0xff, 0x0d, 0x57, 0x31, 0xff, 0x06, 0x47, 0x24, 0xff, 0x19, 0x61, 0x3b, 0xff, 0x15, 0x4f, 0x31, 0xff, 0x04, 0x33, 0x18, 0xff, 0x10, 0x55, 0x32, 0xff, 0x0d, 0x5b, 0x33, 0xff, 0x07, 0x53, 0x2c, 0xff, 0x14, 0x60, 0x3b, 0xff, 0x09, 0x5a, 0x30, 0xff, 0x0b, 0x5b, 0x2f, 0xff, 0x0c, 0x5d, 0x34, 0xff, 0x0d, 0x59, 0x34, 0xff, 0x05, 0x48, 0x26, 0xff, 0x0c, 0x53, 0x2e, 0xff, 0x06, 0x51, 0x2b, 0xff, 0x0e, 0x50, 0x2f, 0xff, 0x03, 0x2f, 0x16, 0xff, 0x01, 0x1c, 0x0d, 0xff, 0x63, 0x6f, 0x69, 0xff, + 0x06, 0x34, 0x22, 0xff, 0x00, 0x2a, 0x14, 0xff, 0x01, 0x27, 0x16, 0xff, 0x08, 0x31, 0x21, 0xff, 0x0d, 0x3f, 0x21, 0xff, 0x0c, 0x3c, 0x1e, 0xff, 0x0d, 0x3b, 0x23, 0xff, 0x07, 0x3f, 0x26, 0xff, 0x02, 0x4a, 0x2a, 0xff, 0x19, 0x82, 0x5b, 0xff, 0x24, 0x87, 0x70, 0xff, 0x24, 0x67, 0x7b, 0xff, 0x20, 0x59, 0x7b, 0xff, 0x26, 0x55, 0x83, 0xff, 0x2d, 0x55, 0x8c, 0xff, 0x49, 0x77, 0xa4, 0xff, 0x78, 0xa9, 0xd6, 0xff, 0x80, 0xb3, 0xdf, 0xff, 0x7d, 0xb1, 0xdd, 0xff, 0x79, 0xac, 0xda, 0xff, 0x7b, 0xac, 0xdc, 0xff, 0x6f, 0x9e, 0xcf, 0xff, 0x46, 0x72, 0xa2, 0xff, 0x53, 0x7e, 0xae, 0xff, 0x71, 0x9c, 0xcc, 0xff, 0x47, 0x71, 0xa3, 0xff, 0x85, 0xaf, 0xe3, 0xff, 0x59, 0x84, 0xb8, 0xff, 0x35, 0x60, 0x95, 0xff, 0x34, 0x5f, 0x96, 0xff, 0x44, 0x70, 0xa5, 0xff, 0x13, 0x3b, 0x6e, 0xff, 0x14, 0x39, 0x71, 0xff, 0x63, 0x90, 0xc7, 0xff, 0x56, 0x89, 0xbb, 0xff, 0x6d, 0x9d, 0xc9, 0xff, 0x7f, 0xa8, 0xd4, 0xff, 0x82, 0xb2, 0xe0, 0xff, 0x75, 0xb4, 0xda, 0xff, 0x34, 0x94, 0x8f, 0xff, 0x11, 0x96, 0x63, 0xff, 0x07, 0x9a, 0x61, 0xff, 0x0c, 0x97, 0x6b, 0xff, 0x0f, 0x99, 0x64, 0xff, 0x0b, 0x9b, 0x63, 0xff, 0x0d, 0x9e, 0x69, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x08, 0xa1, 0x6f, 0xff, 0x15, 0xa8, 0x76, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x12, 0xa8, 0x6f, 0xff, 0x0f, 0xad, 0x71, 0xff, 0x0f, 0xb0, 0x71, 0xff, 0x0f, 0xad, 0x6f, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x17, 0xb7, 0x7d, 0xff, 0x14, 0xb4, 0x79, 0xff, 0x18, 0xba, 0x7a, 0xff, 0x19, 0xbb, 0x79, 0xff, 0x05, 0xa9, 0x65, 0xff, 0x0e, 0xb4, 0x71, 0xff, 0x08, 0xae, 0x6b, 0xff, 0x0d, 0xb5, 0x72, 0xff, 0x0f, 0xbb, 0x78, 0xff, 0x0d, 0xb7, 0x72, 0xff, 0x08, 0xb0, 0x6a, 0xff, 0x0b, 0xb0, 0x6b, 0xff, 0x0d, 0xb1, 0x6f, 0xff, 0x13, 0xb7, 0x74, 0xff, 0x0e, 0xb6, 0x70, 0xff, 0x08, 0xb0, 0x67, 0xff, 0x0c, 0xae, 0x66, 0xff, 0x19, 0xbc, 0x71, 0xff, 0x0e, 0xb2, 0x65, 0xff, 0x06, 0xa5, 0x5b, 0xff, 0x08, 0xa1, 0x5a, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x07, 0x9f, 0x5d, 0xff, 0x04, 0x9e, 0x5d, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0f, 0xa6, 0x6c, 0xff, 0x0f, 0xa7, 0x6d, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0f, 0xa6, 0x72, 0xff, 0x0f, 0xa7, 0x70, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0e, 0xa4, 0x6b, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0a, 0xa6, 0x69, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x09, 0xa8, 0x6a, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x12, 0xa6, 0x70, 0xff, 0x12, 0xa6, 0x71, 0xff, 0x12, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x14, 0xa5, 0x7a, 0xff, 0x15, 0xa4, 0x7b, 0xff, 0x18, 0xa5, 0x7f, 0xff, 0x1c, 0xa8, 0x85, 0xff, 0x1b, 0xa6, 0x83, 0xff, 0x1a, 0xa5, 0x81, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x1a, 0xa7, 0x7f, 0xff, 0x1a, 0xa7, 0x7f, 0xff, 0x1a, 0xa7, 0x7f, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x1a, 0xa6, 0x82, 0xff, 0x1a, 0xa5, 0x81, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x17, 0xa5, 0x7f, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x1b, 0xab, 0x85, 0xff, 0x19, 0xa9, 0x85, 0xff, 0x18, 0xa6, 0x82, 0xff, 0x19, 0xa6, 0x82, 0xff, 0x19, 0xa6, 0x82, 0xff, 0x19, 0xa6, 0x82, 0xff, 0x19, 0xa6, 0x82, 0xff, 0x19, 0xa6, 0x83, 0xff, 0x1a, 0xa7, 0x85, 0xff, 0x19, 0xa7, 0x83, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1d, 0xa8, 0x87, 0xff, 0x22, 0xac, 0x8b, 0xff, 0x1c, 0xa7, 0x84, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1a, 0xa7, 0x83, 0xff, 0x1a, 0xa7, 0x84, 0xff, 0x1c, 0xa9, 0x87, 0xff, 0x1e, 0xac, 0x8b, 0xff, 0x1a, 0xa8, 0x87, 0xff, 0x18, 0xa5, 0x85, 0xff, 0x1a, 0xa6, 0x85, 0xff, 0x1a, 0xa5, 0x84, 0xff, 0x1a, 0xa5, 0x83, 0xff, 0x1a, 0xa7, 0x83, 0xff, 0x18, 0xa7, 0x83, 0xff, 0x18, 0xa7, 0x81, 0xff, 0x19, 0xa7, 0x81, 0xff, 0x19, 0xa7, 0x81, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x1a, 0xa7, 0x82, 0xff, 0x19, 0xa7, 0x82, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x15, 0xa6, 0x7f, 0xff, 0x15, 0xa7, 0x7f, 0xff, 0x15, 0xa7, 0x7d, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x10, 0xa8, 0x7a, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x0a, 0xa8, 0x6d, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0d, 0xa7, 0x6c, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0d, 0xa0, 0x66, 0xff, 0x0c, 0x9e, 0x65, 0xff, 0x09, 0xa0, 0x65, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6c, 0xff, 0x07, 0xa4, 0x68, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0d, 0xa2, 0x67, 0xff, 0x0d, 0xa1, 0x66, 0xff, 0x0c, 0xa0, 0x63, 0xff, 0x0b, 0xa0, 0x64, 0xff, 0x0c, 0xa1, 0x65, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x0f, 0x8b, 0x57, 0xff, 0x0a, 0x6c, 0x3c, 0xff, 0x0c, 0x67, 0x36, 0xff, 0x09, 0x67, 0x35, 0xff, 0x0d, 0x6d, 0x3b, 0xff, 0x09, 0x6b, 0x39, 0xff, 0x0b, 0x6f, 0x3b, 0xff, 0x0c, 0x77, 0x42, 0xff, 0x0a, 0x7d, 0x47, 0xff, 0x18, 0x93, 0x5c, 0xff, 0x0b, 0x76, 0x45, 0xff, 0x03, 0x5f, 0x33, 0xff, 0x07, 0x47, 0x26, 0xff, 0x09, 0x39, 0x1f, 0xff, 0x01, 0x29, 0x12, 0xff, 0x04, 0x2e, 0x17, 0xff, 0x04, 0x34, 0x1d, 0xff, 0x01, 0x2b, 0x16, 0xff, 0x05, 0x2d, 0x17, 0xff, 0x06, 0x2c, 0x15, 0xff, 0x0f, 0x40, 0x26, 0xff, 0x09, 0x45, 0x2d, 0xff, 0x00, 0x44, 0x2d, 0xff, 0x00, 0x43, 0x28, 0xff, 0x03, 0x45, 0x2a, 0xff, 0x05, 0x45, 0x2c, 0xff, 0x07, 0x44, 0x2a, 0xff, 0x03, 0x45, 0x25, 0xff, 0x07, 0x59, 0x29, 0xff, 0x13, 0x7e, 0x40, 0xff, 0x02, 0x85, 0x38, 0xff, 0x08, 0x82, 0x3a, 0xff, 0x07, 0x78, 0x37, 0xff, 0x02, 0x72, 0x35, 0xff, 0x03, 0x73, 0x38, 0xff, 0x07, 0x75, 0x3a, 0xff, 0x0c, 0x71, 0x39, 0xff, 0x0f, 0x69, 0x36, 0xff, 0x08, 0x54, 0x26, 0xff, 0x07, 0x4d, 0x23, 0xff, 0x10, 0x4e, 0x25, 0xff, 0x15, 0x51, 0x26, 0xff, 0x0c, 0x4f, 0x25, 0xff, 0x02, 0x50, 0x26, 0xff, 0x10, 0x7c, 0x52, 0xff, 0x10, 0x84, 0x58, 0xff, 0x0e, 0x66, 0x3b, 0xff, 0x08, 0x47, 0x22, 0xff, 0x02, 0x29, 0x12, 0xff, 0x0e, 0x4b, 0x2f, 0xff, 0x04, 0x55, 0x2b, 0xff, 0x0a, 0x5a, 0x32, 0xff, 0x05, 0x51, 0x2a, 0xff, 0x18, 0x62, 0x39, 0xff, 0x12, 0x47, 0x2b, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x0e, 0x52, 0x2f, 0xff, 0x0e, 0x58, 0x33, 0xff, 0x05, 0x53, 0x2d, 0xff, 0x11, 0x5e, 0x38, 0xff, 0x0a, 0x59, 0x30, 0xff, 0x0b, 0x5a, 0x30, 0xff, 0x0a, 0x5b, 0x32, 0xff, 0x0e, 0x5a, 0x35, 0xff, 0x04, 0x4a, 0x27, 0xff, 0x0c, 0x52, 0x2e, 0xff, 0x0a, 0x50, 0x2b, 0xff, 0x0d, 0x4f, 0x2d, 0xff, 0x02, 0x30, 0x17, 0xff, 0x02, 0x1e, 0x0d, 0xff, 0x65, 0x6f, 0x69, 0xff, + 0x06, 0x38, 0x29, 0xff, 0x01, 0x2f, 0x13, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x01, 0x2f, 0x18, 0xff, 0x02, 0x3d, 0x1d, 0xff, 0x02, 0x40, 0x20, 0xff, 0x07, 0x41, 0x2a, 0xff, 0x0b, 0x44, 0x32, 0xff, 0x04, 0x51, 0x34, 0xff, 0x1f, 0x89, 0x5e, 0xff, 0x27, 0x89, 0x6e, 0xff, 0x35, 0x72, 0x89, 0xff, 0x2e, 0x61, 0x87, 0xff, 0x23, 0x4e, 0x7b, 0xff, 0x29, 0x4f, 0x82, 0xff, 0x85, 0xb3, 0xdf, 0xff, 0x85, 0xb6, 0xe3, 0xff, 0x81, 0xb4, 0xe0, 0xff, 0x78, 0xac, 0xda, 0xff, 0x7d, 0xaf, 0xde, 0xff, 0x6d, 0x9d, 0xcd, 0xff, 0x28, 0x54, 0x85, 0xff, 0x18, 0x42, 0x75, 0xff, 0x73, 0x9f, 0xd1, 0xff, 0x71, 0x9c, 0xce, 0xff, 0x58, 0x83, 0xb6, 0xff, 0x87, 0xb2, 0xe4, 0xff, 0x3e, 0x68, 0x9b, 0xff, 0x1c, 0x45, 0x79, 0xff, 0x39, 0x62, 0x97, 0xff, 0x59, 0x83, 0xb8, 0xff, 0x12, 0x3c, 0x70, 0xff, 0x17, 0x3e, 0x74, 0xff, 0x6d, 0x9b, 0xce, 0xff, 0x77, 0xad, 0xda, 0xff, 0x7d, 0xb0, 0xda, 0xff, 0x85, 0xb1, 0xde, 0xff, 0x81, 0xb0, 0xe4, 0xff, 0x74, 0xb0, 0xdd, 0xff, 0x34, 0x93, 0x8f, 0xff, 0x16, 0x98, 0x68, 0xff, 0x0a, 0x9b, 0x64, 0xff, 0x0b, 0x97, 0x69, 0xff, 0x0e, 0x9b, 0x66, 0xff, 0x09, 0xa0, 0x63, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x06, 0xa0, 0x69, 0xff, 0x09, 0x9f, 0x68, 0xff, 0x13, 0xa6, 0x6c, 0xff, 0x13, 0xab, 0x6e, 0xff, 0x09, 0xa8, 0x68, 0xff, 0x0f, 0xb3, 0x72, 0xff, 0x0f, 0xaf, 0x6e, 0xff, 0x0c, 0xaa, 0x6b, 0xff, 0x0a, 0xac, 0x6d, 0xff, 0x16, 0xb8, 0x78, 0xff, 0x11, 0xb4, 0x71, 0xff, 0x1a, 0xbc, 0x77, 0xff, 0x0a, 0xab, 0x65, 0xff, 0x0f, 0xaf, 0x6a, 0xff, 0x13, 0xb2, 0x6e, 0xff, 0x0b, 0xaa, 0x68, 0xff, 0x0d, 0xb5, 0x75, 0xff, 0x0d, 0xb4, 0x73, 0xff, 0x08, 0xb2, 0x6d, 0xff, 0x10, 0xb9, 0x73, 0xff, 0x0e, 0xb4, 0x71, 0xff, 0x10, 0xb5, 0x72, 0xff, 0x0c, 0xb3, 0x6c, 0xff, 0x08, 0xb0, 0x65, 0xff, 0x12, 0xb7, 0x6c, 0xff, 0x1c, 0xc1, 0x73, 0xff, 0x0a, 0xac, 0x5c, 0xff, 0x08, 0xa6, 0x59, 0xff, 0x0b, 0xa3, 0x5c, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x07, 0x9d, 0x5b, 0xff, 0x08, 0xa0, 0x5f, 0xff, 0x06, 0xa0, 0x62, 0xff, 0x0c, 0xa5, 0x67, 0xff, 0x10, 0xa9, 0x6c, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x11, 0xa6, 0x73, 0xff, 0x11, 0xa8, 0x71, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0c, 0xa2, 0x68, 0xff, 0x0c, 0xa1, 0x67, 0xff, 0x0c, 0xa2, 0x68, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x08, 0xa7, 0x6a, 0xff, 0x09, 0xa6, 0x69, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0f, 0xa3, 0x6c, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x13, 0xa6, 0x71, 0xff, 0x12, 0xa7, 0x72, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x0f, 0xa7, 0x70, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x10, 0xa5, 0x74, 0xff, 0x12, 0xa4, 0x76, 0xff, 0x13, 0xa6, 0x79, 0xff, 0x14, 0xa6, 0x79, 0xff, 0x14, 0xa4, 0x7b, 0xff, 0x16, 0xa4, 0x7c, 0xff, 0x18, 0xa5, 0x7f, 0xff, 0x1a, 0xa5, 0x82, 0xff, 0x1b, 0xa6, 0x84, 0xff, 0x1d, 0xa7, 0x83, 0xff, 0x1c, 0xa9, 0x83, 0xff, 0x1b, 0xa8, 0x81, 0xff, 0x1a, 0xa8, 0x80, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x83, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x16, 0xa5, 0x7f, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x19, 0xa8, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x1a, 0xa5, 0x80, 0xff, 0x1b, 0xa4, 0x80, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x83, 0xff, 0x1a, 0xa5, 0x84, 0xff, 0x19, 0xa5, 0x81, 0xff, 0x19, 0xa5, 0x80, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1c, 0xa7, 0x84, 0xff, 0x1b, 0xa5, 0x83, 0xff, 0x1c, 0xa6, 0x82, 0xff, 0x1a, 0xa5, 0x80, 0xff, 0x1d, 0xa8, 0x83, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1a, 0xa5, 0x81, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1f, 0xab, 0x8a, 0xff, 0x1c, 0xa7, 0x86, 0xff, 0x1a, 0xa4, 0x83, 0xff, 0x1b, 0xa5, 0x83, 0xff, 0x1a, 0xa5, 0x82, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x17, 0xa7, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa6, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x15, 0xa7, 0x7f, 0xff, 0x15, 0xa7, 0x7d, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x07, 0xa3, 0x67, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x10, 0xa5, 0x6d, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0e, 0xa2, 0x68, 0xff, 0x0d, 0xa1, 0x67, 0xff, 0x08, 0xa2, 0x65, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x06, 0xa0, 0x65, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x08, 0xa6, 0x6a, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0d, 0xa1, 0x66, 0xff, 0x0c, 0xa1, 0x66, 0xff, 0x0c, 0xa1, 0x65, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x07, 0xa4, 0x69, 0xff, 0x19, 0x94, 0x5f, 0xff, 0x0f, 0x71, 0x3f, 0xff, 0x0c, 0x66, 0x35, 0xff, 0x0c, 0x6a, 0x39, 0xff, 0x0b, 0x6b, 0x39, 0xff, 0x12, 0x73, 0x42, 0xff, 0x10, 0x76, 0x44, 0xff, 0x0d, 0x80, 0x4a, 0xff, 0x07, 0x80, 0x49, 0xff, 0x11, 0x8d, 0x56, 0xff, 0x15, 0x8c, 0x5a, 0xff, 0x03, 0x60, 0x34, 0xff, 0x07, 0x50, 0x2c, 0xff, 0x04, 0x39, 0x1d, 0xff, 0x05, 0x2a, 0x14, 0xff, 0x03, 0x2e, 0x17, 0xff, 0x06, 0x33, 0x1c, 0xff, 0x01, 0x2a, 0x14, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x02, 0x39, 0x19, 0xff, 0x0c, 0x47, 0x24, 0xff, 0x06, 0x44, 0x22, 0xff, 0x01, 0x43, 0x23, 0xff, 0x04, 0x44, 0x27, 0xff, 0x07, 0x42, 0x29, 0xff, 0x06, 0x41, 0x29, 0xff, 0x07, 0x45, 0x2a, 0xff, 0x02, 0x45, 0x24, 0xff, 0x09, 0x60, 0x2e, 0xff, 0x12, 0x7f, 0x42, 0xff, 0x02, 0x83, 0x38, 0xff, 0x07, 0x83, 0x3a, 0xff, 0x05, 0x78, 0x36, 0xff, 0x03, 0x72, 0x35, 0xff, 0x02, 0x74, 0x37, 0xff, 0x07, 0x77, 0x3a, 0xff, 0x0b, 0x74, 0x39, 0xff, 0x14, 0x74, 0x3d, 0xff, 0x12, 0x67, 0x36, 0xff, 0x05, 0x52, 0x27, 0xff, 0x0a, 0x4e, 0x23, 0xff, 0x0e, 0x50, 0x23, 0xff, 0x0f, 0x51, 0x26, 0xff, 0x04, 0x4e, 0x25, 0xff, 0x0e, 0x76, 0x4c, 0xff, 0x10, 0x85, 0x58, 0xff, 0x0f, 0x69, 0x3d, 0xff, 0x08, 0x48, 0x24, 0xff, 0x01, 0x27, 0x10, 0xff, 0x0b, 0x46, 0x2b, 0xff, 0x05, 0x55, 0x2b, 0xff, 0x08, 0x5a, 0x31, 0xff, 0x0a, 0x5c, 0x34, 0xff, 0x18, 0x64, 0x3a, 0xff, 0x0b, 0x40, 0x24, 0xff, 0x05, 0x37, 0x1c, 0xff, 0x11, 0x55, 0x32, 0xff, 0x0a, 0x54, 0x2f, 0xff, 0x06, 0x55, 0x2e, 0xff, 0x0e, 0x5b, 0x35, 0xff, 0x08, 0x56, 0x2e, 0xff, 0x0a, 0x59, 0x2f, 0xff, 0x08, 0x59, 0x30, 0xff, 0x0d, 0x5a, 0x35, 0xff, 0x05, 0x4b, 0x29, 0xff, 0x0b, 0x51, 0x2c, 0xff, 0x0b, 0x4f, 0x2b, 0xff, 0x0d, 0x4e, 0x2d, 0xff, 0x02, 0x31, 0x18, 0xff, 0x02, 0x1f, 0x0d, 0xff, 0x65, 0x70, 0x6a, 0xff, + 0x0a, 0x33, 0x47, 0xff, 0x01, 0x25, 0x28, 0xff, 0x00, 0x23, 0x18, 0xff, 0x01, 0x31, 0x17, 0xff, 0x03, 0x4a, 0x23, 0xff, 0x03, 0x4f, 0x2c, 0xff, 0x08, 0x4c, 0x36, 0xff, 0x15, 0x51, 0x40, 0xff, 0x17, 0x63, 0x4a, 0xff, 0x1d, 0x7e, 0x55, 0xff, 0x15, 0x6c, 0x4c, 0xff, 0x27, 0x5d, 0x73, 0xff, 0x31, 0x5d, 0x89, 0xff, 0x3a, 0x62, 0x90, 0xff, 0x34, 0x59, 0x8a, 0xff, 0x8a, 0xb8, 0xe7, 0xff, 0x85, 0xb5, 0xe3, 0xff, 0x7c, 0xae, 0xdc, 0xff, 0x7b, 0xad, 0xdc, 0xff, 0x7e, 0xad, 0xdf, 0xff, 0x3e, 0x6c, 0x9e, 0xff, 0x26, 0x50, 0x83, 0xff, 0x58, 0x84, 0xb7, 0xff, 0x87, 0xb5, 0xe9, 0xff, 0x5a, 0x85, 0xba, 0xff, 0x53, 0x7c, 0xb1, 0xff, 0x72, 0x9a, 0xce, 0xff, 0x18, 0x40, 0x74, 0xff, 0x14, 0x3a, 0x6e, 0xff, 0x27, 0x4c, 0x81, 0xff, 0x30, 0x59, 0x8d, 0xff, 0x4a, 0x77, 0xac, 0xff, 0x69, 0x92, 0xc5, 0xff, 0x7a, 0xab, 0xd7, 0xff, 0x79, 0xb2, 0xdb, 0xff, 0x7a, 0xb1, 0xdc, 0xff, 0x80, 0xb0, 0xe0, 0xff, 0x79, 0xa9, 0xe1, 0xff, 0x71, 0xac, 0xdb, 0xff, 0x33, 0x93, 0x8e, 0xff, 0x15, 0x95, 0x69, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x0d, 0x9a, 0x6a, 0xff, 0x0d, 0x9e, 0x67, 0xff, 0x08, 0xa5, 0x64, 0xff, 0x06, 0xa7, 0x66, 0xff, 0x05, 0xa4, 0x65, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x08, 0x9f, 0x63, 0xff, 0x11, 0xa5, 0x68, 0xff, 0x15, 0xaf, 0x6f, 0xff, 0x0d, 0xaf, 0x6d, 0xff, 0x12, 0xb8, 0x75, 0xff, 0x15, 0xb9, 0x78, 0xff, 0x0b, 0xae, 0x6d, 0xff, 0x04, 0xa5, 0x62, 0xff, 0x13, 0xb5, 0x71, 0xff, 0x09, 0xae, 0x69, 0xff, 0x0b, 0xb1, 0x6a, 0xff, 0x08, 0xac, 0x64, 0xff, 0x08, 0xa9, 0x62, 0xff, 0x19, 0xb4, 0x71, 0xff, 0x17, 0xb0, 0x70, 0xff, 0x0c, 0xac, 0x71, 0xff, 0x12, 0xb5, 0x77, 0xff, 0x08, 0xaf, 0x6d, 0xff, 0x0a, 0xb2, 0x6f, 0xff, 0x0a, 0xb2, 0x6f, 0xff, 0x0d, 0xb3, 0x70, 0xff, 0x09, 0xad, 0x68, 0xff, 0x0a, 0xb0, 0x67, 0xff, 0x11, 0xbe, 0x6f, 0xff, 0x09, 0xb4, 0x63, 0xff, 0x06, 0xa8, 0x58, 0xff, 0x06, 0xa1, 0x55, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0e, 0xa2, 0x61, 0xff, 0x0f, 0xa5, 0x65, 0xff, 0x0e, 0xa8, 0x67, 0xff, 0x02, 0x9d, 0x5c, 0xff, 0x07, 0xa1, 0x60, 0xff, 0x08, 0xa2, 0x62, 0xff, 0x09, 0xa2, 0x65, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x12, 0xa6, 0x73, 0xff, 0x12, 0xa5, 0x71, 0xff, 0x11, 0xa4, 0x6d, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x0a, 0xa6, 0x6b, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x12, 0xa5, 0x71, 0xff, 0x12, 0xa6, 0x72, 0xff, 0x12, 0xa7, 0x72, 0xff, 0x12, 0xa7, 0x74, 0xff, 0x12, 0xa7, 0x74, 0xff, 0x11, 0xa7, 0x74, 0xff, 0x11, 0xa7, 0x73, 0xff, 0x11, 0xa6, 0x71, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x11, 0xa6, 0x71, 0xff, 0x12, 0xa7, 0x71, 0xff, 0x13, 0xa5, 0x77, 0xff, 0x15, 0xa5, 0x7a, 0xff, 0x18, 0xa7, 0x7d, 0xff, 0x1a, 0xa7, 0x7e, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1c, 0xa8, 0x83, 0xff, 0x1d, 0xa9, 0x85, 0xff, 0x1f, 0xa9, 0x87, 0xff, 0x20, 0xaa, 0x88, 0xff, 0x1f, 0xaa, 0x86, 0xff, 0x1c, 0xa8, 0x83, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x1a, 0xa6, 0x82, 0xff, 0x19, 0xa5, 0x83, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x17, 0xa7, 0x7e, 0xff, 0x17, 0xa7, 0x7e, 0xff, 0x17, 0xa7, 0x7f, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x1a, 0xa6, 0x80, 0xff, 0x1d, 0xa7, 0x81, 0xff, 0x1f, 0xa7, 0x81, 0xff, 0x1c, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa5, 0x81, 0xff, 0x1a, 0xa5, 0x80, 0xff, 0x1a, 0xa5, 0x80, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa5, 0x81, 0xff, 0x1b, 0xa8, 0x82, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x1a, 0xa6, 0x7f, 0xff, 0x1b, 0xa6, 0x80, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x1b, 0xa6, 0x82, 0xff, 0x1c, 0xa6, 0x82, 0xff, 0x1d, 0xa5, 0x81, 0xff, 0x1d, 0xa6, 0x82, 0xff, 0x1d, 0xa6, 0x83, 0xff, 0x1c, 0xa6, 0x81, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x19, 0xa8, 0x81, 0xff, 0x17, 0xa8, 0x81, 0xff, 0x18, 0xa7, 0x81, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1a, 0xa7, 0x82, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x16, 0xa4, 0x7f, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7e, 0xff, 0x14, 0xa7, 0x7d, 0xff, 0x13, 0xa7, 0x7c, 0xff, 0x11, 0xa7, 0x7a, 0xff, 0x10, 0xa9, 0x77, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0c, 0xac, 0x74, 0xff, 0x0b, 0xab, 0x73, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0b, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0d, 0xa8, 0x6e, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x12, 0xa5, 0x6e, 0xff, 0x11, 0xa5, 0x6d, 0xff, 0x10, 0xa5, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x06, 0xa1, 0x62, 0xff, 0x07, 0xa3, 0x64, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6c, 0xff, 0x08, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x07, 0xa5, 0x68, 0xff, 0x1a, 0x96, 0x5f, 0xff, 0x0c, 0x6f, 0x3b, 0xff, 0x0b, 0x65, 0x34, 0xff, 0x0e, 0x6e, 0x3c, 0xff, 0x16, 0x78, 0x48, 0xff, 0x18, 0x7d, 0x4c, 0xff, 0x05, 0x6f, 0x3d, 0xff, 0x13, 0x7e, 0x4a, 0xff, 0x1c, 0x85, 0x51, 0xff, 0x09, 0x72, 0x3f, 0xff, 0x15, 0x8a, 0x58, 0xff, 0x04, 0x5d, 0x33, 0xff, 0x0e, 0x5c, 0x38, 0xff, 0x04, 0x3f, 0x21, 0xff, 0x06, 0x2c, 0x14, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x07, 0x33, 0x1b, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x05, 0x45, 0x26, 0xff, 0x0c, 0x54, 0x31, 0xff, 0x02, 0x41, 0x1d, 0xff, 0x05, 0x42, 0x1e, 0xff, 0x08, 0x48, 0x25, 0xff, 0x0b, 0x46, 0x28, 0xff, 0x07, 0x41, 0x27, 0xff, 0x07, 0x43, 0x29, 0xff, 0x02, 0x41, 0x26, 0xff, 0x00, 0x42, 0x1f, 0xff, 0x0a, 0x66, 0x34, 0xff, 0x12, 0x80, 0x42, 0xff, 0x05, 0x83, 0x39, 0xff, 0x09, 0x84, 0x3c, 0xff, 0x05, 0x78, 0x36, 0xff, 0x03, 0x72, 0x36, 0xff, 0x04, 0x72, 0x37, 0xff, 0x06, 0x75, 0x37, 0xff, 0x09, 0x76, 0x37, 0xff, 0x0b, 0x73, 0x38, 0xff, 0x13, 0x73, 0x3d, 0xff, 0x16, 0x6d, 0x3e, 0xff, 0x04, 0x52, 0x24, 0xff, 0x07, 0x50, 0x21, 0xff, 0x0f, 0x51, 0x26, 0xff, 0x0b, 0x4e, 0x25, 0xff, 0x0f, 0x72, 0x47, 0xff, 0x12, 0x87, 0x5a, 0xff, 0x0e, 0x6b, 0x3e, 0xff, 0x07, 0x4a, 0x25, 0xff, 0x00, 0x26, 0x0f, 0xff, 0x08, 0x42, 0x27, 0xff, 0x07, 0x56, 0x2d, 0xff, 0x06, 0x57, 0x2e, 0xff, 0x12, 0x63, 0x3c, 0xff, 0x1a, 0x67, 0x3d, 0xff, 0x09, 0x3f, 0x23, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x12, 0x58, 0x33, 0xff, 0x09, 0x53, 0x2d, 0xff, 0x07, 0x56, 0x2f, 0xff, 0x0c, 0x5a, 0x34, 0xff, 0x07, 0x54, 0x2e, 0xff, 0x09, 0x56, 0x2f, 0xff, 0x08, 0x58, 0x2f, 0xff, 0x0b, 0x58, 0x32, 0xff, 0x05, 0x4e, 0x2a, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x0a, 0x4f, 0x2b, 0xff, 0x0d, 0x4d, 0x2d, 0xff, 0x03, 0x33, 0x1a, 0xff, 0x02, 0x1f, 0x0e, 0xff, 0x65, 0x71, 0x6b, 0xff, + 0x1b, 0x39, 0x81, 0xff, 0x14, 0x30, 0x6c, 0xff, 0x1b, 0x3d, 0x5e, 0xff, 0x1c, 0x56, 0x4e, 0xff, 0x1e, 0x6d, 0x4a, 0xff, 0x1d, 0x74, 0x50, 0xff, 0x22, 0x6d, 0x52, 0xff, 0x21, 0x5f, 0x48, 0xff, 0x10, 0x51, 0x39, 0xff, 0x01, 0x48, 0x22, 0xff, 0x01, 0x42, 0x23, 0xff, 0x26, 0x55, 0x69, 0xff, 0x3c, 0x63, 0x92, 0xff, 0x3a, 0x61, 0x90, 0xff, 0x2d, 0x53, 0x83, 0xff, 0x84, 0xb3, 0xe1, 0xff, 0x7a, 0xac, 0xda, 0xff, 0x73, 0xa4, 0xd4, 0xff, 0x59, 0x88, 0xbb, 0xff, 0x7f, 0xab, 0xe0, 0xff, 0x31, 0x5b, 0x8f, 0xff, 0x73, 0x9b, 0xcf, 0xff, 0x64, 0x8c, 0xc1, 0xff, 0x68, 0x93, 0xca, 0xff, 0x36, 0x5f, 0x95, 0xff, 0x40, 0x69, 0x9e, 0xff, 0x53, 0x7a, 0xaf, 0xff, 0x1e, 0x45, 0x79, 0xff, 0x4c, 0x72, 0xa5, 0xff, 0x07, 0x2a, 0x5c, 0xff, 0x26, 0x50, 0x83, 0xff, 0x78, 0xa8, 0xdd, 0xff, 0x7d, 0xa8, 0xd9, 0xff, 0x77, 0xa9, 0xd5, 0xff, 0x6a, 0xa4, 0xce, 0xff, 0x72, 0xab, 0xd8, 0xff, 0x7b, 0xae, 0xdf, 0xff, 0x75, 0xa8, 0xdb, 0xff, 0x5c, 0x9c, 0xc2, 0xff, 0x13, 0x78, 0x6b, 0xff, 0x13, 0x97, 0x6a, 0xff, 0x0c, 0x9c, 0x65, 0xff, 0x10, 0x9c, 0x6c, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x08, 0xa8, 0x67, 0xff, 0x04, 0xa9, 0x67, 0xff, 0x05, 0xa5, 0x65, 0xff, 0x07, 0xa0, 0x62, 0xff, 0x0d, 0xa5, 0x67, 0xff, 0x07, 0xa0, 0x61, 0xff, 0x0e, 0xab, 0x6a, 0xff, 0x17, 0xb9, 0x78, 0xff, 0x13, 0xb9, 0x77, 0xff, 0x15, 0xbb, 0x7b, 0xff, 0x10, 0xb5, 0x74, 0xff, 0x05, 0xa7, 0x62, 0xff, 0x0d, 0xb0, 0x6a, 0xff, 0x09, 0xb1, 0x6a, 0xff, 0x01, 0xa9, 0x62, 0xff, 0x08, 0xaf, 0x69, 0xff, 0x03, 0xa2, 0x5e, 0xff, 0x0f, 0xaa, 0x68, 0xff, 0x1e, 0xb3, 0x76, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x14, 0xae, 0x75, 0xff, 0x0e, 0xaf, 0x70, 0xff, 0x07, 0xae, 0x6c, 0xff, 0x09, 0xb2, 0x71, 0xff, 0x0d, 0xb3, 0x72, 0xff, 0x07, 0xac, 0x68, 0xff, 0x05, 0xaa, 0x61, 0xff, 0x04, 0xb1, 0x62, 0xff, 0x01, 0xaa, 0x5a, 0xff, 0x02, 0xa2, 0x52, 0xff, 0x0b, 0xa0, 0x55, 0xff, 0x23, 0xab, 0x6b, 0xff, 0x2a, 0xae, 0x73, 0xff, 0x2a, 0xb4, 0x79, 0xff, 0x18, 0xab, 0x6c, 0xff, 0x09, 0xa4, 0x61, 0xff, 0x07, 0xa3, 0x5e, 0xff, 0x05, 0xa1, 0x5d, 0xff, 0x06, 0xa0, 0x61, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x12, 0xa5, 0x72, 0xff, 0x11, 0xa2, 0x6f, 0xff, 0x10, 0xa2, 0x6d, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0f, 0xa4, 0x70, 0xff, 0x13, 0xa5, 0x72, 0xff, 0x14, 0xa6, 0x73, 0xff, 0x14, 0xa6, 0x74, 0xff, 0x13, 0xa6, 0x73, 0xff, 0x12, 0xa7, 0x74, 0xff, 0x12, 0xa8, 0x75, 0xff, 0x12, 0xa8, 0x75, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x74, 0xff, 0x13, 0xa7, 0x74, 0xff, 0x16, 0xa7, 0x74, 0xff, 0x16, 0xa7, 0x74, 0xff, 0x17, 0xa7, 0x74, 0xff, 0x19, 0xa6, 0x7c, 0xff, 0x1a, 0xa4, 0x7f, 0xff, 0x1d, 0xa8, 0x83, 0xff, 0x20, 0xaa, 0x85, 0xff, 0x1f, 0xab, 0x85, 0xff, 0x1f, 0xaa, 0x87, 0xff, 0x20, 0xab, 0x87, 0xff, 0x20, 0xab, 0x88, 0xff, 0x22, 0xab, 0x8a, 0xff, 0x22, 0xab, 0x8a, 0xff, 0x20, 0xa9, 0x88, 0xff, 0x1d, 0xa8, 0x85, 0xff, 0x1b, 0xa7, 0x83, 0xff, 0x1c, 0xa7, 0x83, 0xff, 0x1c, 0xa7, 0x84, 0xff, 0x19, 0xa5, 0x83, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x18, 0xa7, 0x7e, 0xff, 0x17, 0xa7, 0x7e, 0xff, 0x17, 0xa7, 0x7f, 0xff, 0x17, 0xa5, 0x7e, 0xff, 0x17, 0xa5, 0x7e, 0xff, 0x1b, 0xa6, 0x7f, 0xff, 0x1d, 0xa5, 0x80, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x17, 0xa6, 0x80, 0xff, 0x16, 0xa5, 0x7f, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x18, 0xa6, 0x7f, 0xff, 0x19, 0xa7, 0x7f, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x19, 0xa5, 0x7f, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x15, 0xa6, 0x7d, 0xff, 0x17, 0xa7, 0x7d, 0xff, 0x19, 0xa8, 0x7e, 0xff, 0x18, 0xa7, 0x7e, 0xff, 0x17, 0xa5, 0x7d, 0xff, 0x18, 0xa5, 0x7f, 0xff, 0x1b, 0xa6, 0x80, 0xff, 0x1d, 0xa6, 0x82, 0xff, 0x1e, 0xa7, 0x82, 0xff, 0x1c, 0xa7, 0x81, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x19, 0xa8, 0x81, 0xff, 0x18, 0xa8, 0x81, 0xff, 0x1a, 0xa7, 0x82, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa5, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x16, 0xa5, 0x7e, 0xff, 0x15, 0xa5, 0x7d, 0xff, 0x13, 0xa6, 0x7b, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xaa, 0x71, 0xff, 0x11, 0xae, 0x77, 0xff, 0x14, 0xb1, 0x7a, 0xff, 0x12, 0xb0, 0x78, 0xff, 0x0e, 0xab, 0x74, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0d, 0xaa, 0x73, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x09, 0xa7, 0x6a, 0xff, 0x09, 0xa6, 0x6a, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x06, 0xa1, 0x64, 0xff, 0x05, 0xa1, 0x60, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x08, 0xa5, 0x6b, 0xff, 0x08, 0xa5, 0x69, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x14, 0x90, 0x58, 0xff, 0x07, 0x6a, 0x36, 0xff, 0x0b, 0x69, 0x37, 0xff, 0x0f, 0x74, 0x43, 0xff, 0x0d, 0x77, 0x46, 0xff, 0x0d, 0x7b, 0x4a, 0xff, 0x08, 0x7b, 0x49, 0xff, 0x01, 0x62, 0x2f, 0xff, 0x14, 0x66, 0x36, 0xff, 0x17, 0x6c, 0x3d, 0xff, 0x03, 0x63, 0x34, 0xff, 0x02, 0x4f, 0x26, 0xff, 0x0f, 0x5c, 0x37, 0xff, 0x0b, 0x4f, 0x2d, 0xff, 0x03, 0x2b, 0x11, 0xff, 0x05, 0x2b, 0x13, 0xff, 0x07, 0x33, 0x18, 0xff, 0x04, 0x36, 0x19, 0xff, 0x13, 0x55, 0x37, 0xff, 0x08, 0x4a, 0x2b, 0xff, 0x02, 0x40, 0x23, 0xff, 0x0a, 0x49, 0x2c, 0xff, 0x0a, 0x45, 0x29, 0xff, 0x07, 0x43, 0x26, 0xff, 0x03, 0x44, 0x26, 0xff, 0x00, 0x42, 0x23, 0xff, 0x02, 0x4c, 0x2a, 0xff, 0x07, 0x5c, 0x33, 0xff, 0x0d, 0x71, 0x3d, 0xff, 0x11, 0x81, 0x41, 0xff, 0x06, 0x82, 0x39, 0xff, 0x08, 0x82, 0x3a, 0xff, 0x03, 0x77, 0x35, 0xff, 0x03, 0x72, 0x36, 0xff, 0x07, 0x74, 0x38, 0xff, 0x04, 0x74, 0x35, 0xff, 0x05, 0x77, 0x36, 0xff, 0x07, 0x77, 0x38, 0xff, 0x08, 0x72, 0x38, 0xff, 0x12, 0x73, 0x3f, 0xff, 0x13, 0x6c, 0x3b, 0xff, 0x04, 0x55, 0x23, 0xff, 0x10, 0x52, 0x25, 0xff, 0x0f, 0x4d, 0x25, 0xff, 0x0d, 0x69, 0x3f, 0xff, 0x11, 0x86, 0x58, 0xff, 0x0c, 0x6c, 0x3f, 0xff, 0x07, 0x4c, 0x26, 0xff, 0x01, 0x27, 0x0e, 0xff, 0x09, 0x43, 0x27, 0xff, 0x09, 0x58, 0x2e, 0xff, 0x06, 0x56, 0x2d, 0xff, 0x12, 0x63, 0x3c, 0xff, 0x1c, 0x69, 0x40, 0xff, 0x07, 0x40, 0x22, 0xff, 0x02, 0x36, 0x18, 0xff, 0x0e, 0x56, 0x31, 0xff, 0x06, 0x52, 0x2c, 0xff, 0x06, 0x54, 0x2e, 0xff, 0x0c, 0x5a, 0x33, 0xff, 0x07, 0x52, 0x2c, 0xff, 0x09, 0x56, 0x2f, 0xff, 0x09, 0x58, 0x30, 0xff, 0x0a, 0x57, 0x31, 0xff, 0x05, 0x4e, 0x2b, 0xff, 0x09, 0x51, 0x2c, 0xff, 0x09, 0x4c, 0x2b, 0xff, 0x0b, 0x49, 0x2b, 0xff, 0x03, 0x32, 0x19, 0xff, 0x01, 0x1e, 0x0e, 0xff, 0x64, 0x71, 0x6b, 0xff, + 0x21, 0x35, 0xa8, 0xff, 0x2c, 0x41, 0xae, 0xff, 0x56, 0x72, 0xc0, 0xff, 0x41, 0x76, 0x8e, 0xff, 0x2a, 0x74, 0x66, 0xff, 0x1d, 0x6d, 0x4e, 0xff, 0x11, 0x57, 0x36, 0xff, 0x06, 0x3d, 0x1c, 0xff, 0x01, 0x34, 0x1d, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x01, 0x3d, 0x21, 0xff, 0x2b, 0x54, 0x66, 0xff, 0x3c, 0x60, 0x90, 0xff, 0x36, 0x5c, 0x8b, 0xff, 0x2a, 0x51, 0x7e, 0xff, 0x77, 0xa7, 0xd6, 0xff, 0x75, 0xa6, 0xd4, 0xff, 0x65, 0x93, 0xc5, 0xff, 0x27, 0x54, 0x88, 0xff, 0x7c, 0xa7, 0xdc, 0xff, 0x22, 0x4a, 0x7f, 0xff, 0x49, 0x6f, 0xa5, 0xff, 0x1a, 0x3f, 0x76, 0xff, 0x1d, 0x42, 0x7a, 0xff, 0x1c, 0x41, 0x79, 0xff, 0x40, 0x67, 0x9d, 0xff, 0x5f, 0x87, 0xbc, 0xff, 0x28, 0x52, 0x85, 0xff, 0x75, 0x9f, 0xd1, 0xff, 0x42, 0x6b, 0x9c, 0xff, 0x69, 0x97, 0xca, 0xff, 0x72, 0xa6, 0xdb, 0xff, 0x74, 0xa1, 0xd3, 0xff, 0x64, 0x96, 0xc5, 0xff, 0x5c, 0x94, 0xc2, 0xff, 0x70, 0xa7, 0xd9, 0xff, 0x7a, 0xae, 0xdd, 0xff, 0x60, 0x9b, 0xc0, 0xff, 0x28, 0x74, 0x87, 0xff, 0x0c, 0x7c, 0x64, 0xff, 0x12, 0x9b, 0x6a, 0xff, 0x0d, 0x9f, 0x65, 0xff, 0x11, 0xa0, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x06, 0xa7, 0x68, 0xff, 0x04, 0xa7, 0x66, 0xff, 0x05, 0xa2, 0x65, 0xff, 0x08, 0xa1, 0x63, 0xff, 0x09, 0xa2, 0x64, 0xff, 0x04, 0xa0, 0x60, 0xff, 0x08, 0xa6, 0x66, 0xff, 0x15, 0xb6, 0x77, 0xff, 0x14, 0xb9, 0x7a, 0xff, 0x10, 0xb6, 0x7a, 0xff, 0x14, 0xba, 0x7c, 0xff, 0x06, 0xa9, 0x65, 0xff, 0x04, 0xa6, 0x61, 0xff, 0x09, 0xae, 0x6a, 0xff, 0x03, 0xa9, 0x66, 0xff, 0x0a, 0xac, 0x6a, 0xff, 0x0f, 0xa9, 0x69, 0xff, 0x10, 0xa3, 0x66, 0xff, 0x1c, 0xa9, 0x70, 0xff, 0x23, 0xad, 0x7b, 0xff, 0x1c, 0xad, 0x77, 0xff, 0x15, 0xb1, 0x74, 0xff, 0x0a, 0xae, 0x6e, 0xff, 0x10, 0xb8, 0x79, 0xff, 0x09, 0xb0, 0x72, 0xff, 0x07, 0xae, 0x6b, 0xff, 0x08, 0xac, 0x66, 0xff, 0x07, 0xac, 0x60, 0xff, 0x07, 0xab, 0x5f, 0xff, 0x0a, 0xa8, 0x5d, 0xff, 0x1e, 0xab, 0x67, 0xff, 0x4d, 0xc1, 0x88, 0xff, 0x68, 0xd4, 0xa2, 0xff, 0x4c, 0xc3, 0x8f, 0xff, 0x21, 0xa7, 0x6f, 0xff, 0x17, 0xb1, 0x6d, 0xff, 0x0c, 0xaa, 0x64, 0xff, 0x0b, 0xa9, 0x63, 0xff, 0x08, 0xa5, 0x63, 0xff, 0x06, 0xa0, 0x67, 0xff, 0x0e, 0xa4, 0x70, 0xff, 0x0f, 0xa3, 0x70, 0xff, 0x10, 0xa2, 0x6d, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa7, 0x69, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x12, 0xa7, 0x73, 0xff, 0x13, 0xa5, 0x74, 0xff, 0x16, 0xa6, 0x76, 0xff, 0x19, 0xa8, 0x78, 0xff, 0x18, 0xa7, 0x79, 0xff, 0x15, 0xa7, 0x76, 0xff, 0x14, 0xa7, 0x76, 0xff, 0x12, 0xa8, 0x74, 0xff, 0x12, 0xa9, 0x73, 0xff, 0x12, 0xa8, 0x75, 0xff, 0x14, 0xa7, 0x75, 0xff, 0x17, 0xa7, 0x78, 0xff, 0x19, 0xa7, 0x79, 0xff, 0x1a, 0xa6, 0x79, 0xff, 0x1b, 0xa6, 0x7b, 0xff, 0x21, 0xa9, 0x83, 0xff, 0x21, 0xa6, 0x84, 0xff, 0x21, 0xa8, 0x85, 0xff, 0x22, 0xa9, 0x86, 0xff, 0x21, 0xaa, 0x88, 0xff, 0x20, 0xa9, 0x88, 0xff, 0x1f, 0xa9, 0x88, 0xff, 0x21, 0xab, 0x89, 0xff, 0x22, 0xaa, 0x89, 0xff, 0x22, 0xa9, 0x89, 0xff, 0x21, 0xa9, 0x89, 0xff, 0x20, 0xa8, 0x88, 0xff, 0x1e, 0xa7, 0x86, 0xff, 0x1e, 0xa8, 0x86, 0xff, 0x1d, 0xa8, 0x86, 0xff, 0x1c, 0xa7, 0x85, 0xff, 0x1b, 0xa7, 0x82, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x18, 0xa7, 0x81, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x15, 0xa6, 0x7f, 0xff, 0x17, 0xa5, 0x7f, 0xff, 0x18, 0xa5, 0x80, 0xff, 0x15, 0xa6, 0x7e, 0xff, 0x15, 0xa6, 0x7d, 0xff, 0x14, 0xa6, 0x7c, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x15, 0xa7, 0x7c, 0xff, 0x17, 0xa8, 0x7d, 0xff, 0x17, 0xa8, 0x7d, 0xff, 0x17, 0xa7, 0x7e, 0xff, 0x14, 0xa7, 0x7e, 0xff, 0x13, 0xa8, 0x7d, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x13, 0xa8, 0x7a, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x15, 0xa9, 0x7b, 0xff, 0x15, 0xa8, 0x7c, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x16, 0xa5, 0x7e, 0xff, 0x18, 0xa6, 0x7f, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x19, 0xa6, 0x82, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x19, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7e, 0xff, 0x16, 0xa5, 0x7e, 0xff, 0x16, 0xa5, 0x7e, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x79, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0a, 0xaa, 0x70, 0xff, 0x0e, 0xaa, 0x73, 0xff, 0x10, 0xac, 0x75, 0xff, 0x12, 0xae, 0x78, 0xff, 0x15, 0xb0, 0x7a, 0xff, 0x10, 0xac, 0x75, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x07, 0xa7, 0x6e, 0xff, 0x03, 0xa5, 0x6b, 0xff, 0x06, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x0f, 0xab, 0x69, 0xff, 0x0e, 0xa9, 0x68, 0xff, 0x0c, 0xa8, 0x69, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x08, 0xa6, 0x6a, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0d, 0xa6, 0x67, 0xff, 0x12, 0x8c, 0x52, 0xff, 0x04, 0x68, 0x33, 0xff, 0x0c, 0x6f, 0x3d, 0xff, 0x0c, 0x79, 0x47, 0xff, 0x08, 0x7c, 0x49, 0xff, 0x19, 0x93, 0x61, 0xff, 0x16, 0x95, 0x62, 0xff, 0x04, 0x75, 0x42, 0xff, 0x03, 0x51, 0x21, 0xff, 0x10, 0x5d, 0x30, 0xff, 0x08, 0x5a, 0x2f, 0xff, 0x00, 0x42, 0x1c, 0xff, 0x0a, 0x52, 0x2e, 0xff, 0x12, 0x5d, 0x3a, 0xff, 0x01, 0x2f, 0x12, 0xff, 0x09, 0x2c, 0x14, 0xff, 0x05, 0x35, 0x19, 0xff, 0x0b, 0x46, 0x28, 0xff, 0x0c, 0x46, 0x2a, 0xff, 0x02, 0x35, 0x1c, 0xff, 0x0a, 0x44, 0x2e, 0xff, 0x06, 0x46, 0x2f, 0xff, 0x05, 0x43, 0x2a, 0xff, 0x01, 0x46, 0x25, 0xff, 0x01, 0x4a, 0x25, 0xff, 0x07, 0x5d, 0x37, 0xff, 0x12, 0x73, 0x49, 0xff, 0x12, 0x78, 0x49, 0xff, 0x0a, 0x77, 0x3e, 0xff, 0x0e, 0x81, 0x3f, 0xff, 0x09, 0x84, 0x3b, 0xff, 0x07, 0x82, 0x3a, 0xff, 0x02, 0x77, 0x36, 0xff, 0x04, 0x73, 0x35, 0xff, 0x09, 0x77, 0x38, 0xff, 0x05, 0x75, 0x35, 0xff, 0x03, 0x77, 0x34, 0xff, 0x04, 0x77, 0x35, 0xff, 0x04, 0x75, 0x37, 0xff, 0x08, 0x6e, 0x38, 0xff, 0x14, 0x74, 0x41, 0xff, 0x11, 0x6b, 0x36, 0xff, 0x09, 0x4e, 0x1f, 0xff, 0x13, 0x4e, 0x25, 0xff, 0x08, 0x60, 0x36, 0xff, 0x0f, 0x81, 0x52, 0xff, 0x0a, 0x6e, 0x3f, 0xff, 0x08, 0x4f, 0x28, 0xff, 0x00, 0x27, 0x0e, 0xff, 0x0b, 0x44, 0x28, 0xff, 0x0c, 0x59, 0x30, 0xff, 0x06, 0x56, 0x2d, 0xff, 0x0e, 0x5f, 0x38, 0xff, 0x1a, 0x6a, 0x40, 0xff, 0x08, 0x40, 0x21, 0xff, 0x02, 0x38, 0x19, 0xff, 0x0c, 0x56, 0x31, 0xff, 0x05, 0x52, 0x2c, 0xff, 0x05, 0x53, 0x2c, 0xff, 0x0d, 0x5a, 0x34, 0xff, 0x08, 0x52, 0x2c, 0xff, 0x09, 0x55, 0x2f, 0xff, 0x09, 0x58, 0x31, 0xff, 0x0a, 0x58, 0x32, 0xff, 0x06, 0x4f, 0x2c, 0xff, 0x09, 0x4f, 0x2b, 0xff, 0x09, 0x4a, 0x29, 0xff, 0x0a, 0x46, 0x29, 0xff, 0x03, 0x2f, 0x19, 0xff, 0x01, 0x1d, 0x0e, 0xff, 0x64, 0x74, 0x6b, 0xff, + 0x1e, 0x30, 0xbb, 0xff, 0x22, 0x37, 0xc1, 0xff, 0x55, 0x71, 0xe2, 0xff, 0x64, 0x8f, 0xd5, 0xff, 0x37, 0x72, 0x8e, 0xff, 0x04, 0x37, 0x2f, 0xff, 0x00, 0x34, 0x18, 0xff, 0x03, 0x37, 0x11, 0xff, 0x03, 0x32, 0x1b, 0xff, 0x00, 0x34, 0x20, 0xff, 0x02, 0x37, 0x21, 0xff, 0x23, 0x47, 0x57, 0xff, 0x2b, 0x50, 0x7c, 0xff, 0x34, 0x5d, 0x89, 0xff, 0x20, 0x48, 0x75, 0xff, 0x74, 0xa2, 0xd1, 0xff, 0x84, 0xb2, 0xe2, 0xff, 0x4a, 0x76, 0xaa, 0xff, 0x18, 0x43, 0x78, 0xff, 0x7d, 0xa6, 0xdb, 0xff, 0x1a, 0x41, 0x76, 0xff, 0x1d, 0x43, 0x78, 0xff, 0x1d, 0x40, 0x76, 0xff, 0x10, 0x30, 0x69, 0xff, 0x12, 0x34, 0x6c, 0xff, 0x37, 0x5d, 0x94, 0xff, 0x45, 0x6e, 0xa2, 0xff, 0x49, 0x76, 0xa9, 0xff, 0x85, 0xb4, 0xe7, 0xff, 0x7b, 0xac, 0xdf, 0xff, 0x72, 0xa8, 0xda, 0xff, 0x65, 0x9b, 0xcf, 0xff, 0x5e, 0x8e, 0xc0, 0xff, 0x61, 0x93, 0xc6, 0xff, 0x6d, 0xa2, 0xd8, 0xff, 0x7b, 0xad, 0xe3, 0xff, 0x65, 0x99, 0xc3, 0xff, 0x2b, 0x73, 0x83, 0xff, 0x1a, 0x7b, 0x74, 0xff, 0x17, 0x97, 0x6e, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x0c, 0xa2, 0x64, 0xff, 0x10, 0xa1, 0x69, 0xff, 0x0d, 0xa0, 0x6d, 0xff, 0x05, 0xa3, 0x69, 0xff, 0x06, 0xa4, 0x68, 0xff, 0x07, 0xa0, 0x67, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x02, 0xa1, 0x63, 0xff, 0x01, 0xa1, 0x64, 0xff, 0x10, 0xb0, 0x74, 0xff, 0x10, 0xb3, 0x77, 0xff, 0x05, 0xa8, 0x6f, 0xff, 0x10, 0xb6, 0x7c, 0xff, 0x07, 0xac, 0x6a, 0xff, 0x06, 0xa8, 0x66, 0xff, 0x0b, 0xa8, 0x6a, 0xff, 0x10, 0xa6, 0x6c, 0xff, 0x18, 0xa4, 0x6c, 0xff, 0x27, 0xab, 0x75, 0xff, 0x32, 0xad, 0x7a, 0xff, 0x36, 0xad, 0x7d, 0xff, 0x2c, 0xaa, 0x7e, 0xff, 0x2b, 0xb3, 0x80, 0xff, 0x1a, 0xb0, 0x75, 0xff, 0x11, 0xb1, 0x73, 0xff, 0x09, 0xb0, 0x71, 0xff, 0x0e, 0xb5, 0x76, 0xff, 0x0d, 0xb1, 0x70, 0xff, 0x14, 0xb5, 0x71, 0xff, 0x14, 0xaa, 0x66, 0xff, 0x0b, 0xa8, 0x61, 0xff, 0x12, 0xaa, 0x66, 0xff, 0x31, 0xb3, 0x76, 0xff, 0x83, 0xe1, 0xb2, 0xff, 0x87, 0xda, 0xaf, 0xff, 0x5a, 0xba, 0x8d, 0xff, 0x2c, 0xa2, 0x6f, 0xff, 0x1a, 0xb0, 0x6d, 0xff, 0x10, 0xad, 0x66, 0xff, 0x17, 0xb5, 0x6e, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x10, 0xa3, 0x6a, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0f, 0xa4, 0x6a, 0xff, 0x10, 0xa4, 0x6a, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x70, 0xff, 0x11, 0xa5, 0x71, 0xff, 0x11, 0xa5, 0x72, 0xff, 0x12, 0xa5, 0x74, 0xff, 0x16, 0xa8, 0x78, 0xff, 0x17, 0xa8, 0x78, 0xff, 0x19, 0xa8, 0x7b, 0xff, 0x1c, 0xa8, 0x7c, 0xff, 0x1d, 0xa9, 0x7d, 0xff, 0x1b, 0xa8, 0x7c, 0xff, 0x19, 0xa7, 0x7a, 0xff, 0x18, 0xa7, 0x79, 0xff, 0x13, 0xa8, 0x74, 0xff, 0x14, 0xa8, 0x72, 0xff, 0x15, 0xa8, 0x74, 0xff, 0x17, 0xa7, 0x77, 0xff, 0x1b, 0xa7, 0x7b, 0xff, 0x1f, 0xa7, 0x7f, 0xff, 0x22, 0xa8, 0x84, 0xff, 0x25, 0xa9, 0x87, 0xff, 0x27, 0xaa, 0x89, 0xff, 0x26, 0xa8, 0x89, 0xff, 0x25, 0xa8, 0x88, 0xff, 0x24, 0xa8, 0x88, 0xff, 0x23, 0xa8, 0x88, 0xff, 0x22, 0xa7, 0x88, 0xff, 0x21, 0xa7, 0x88, 0xff, 0x22, 0xa8, 0x89, 0xff, 0x24, 0xa8, 0x8a, 0xff, 0x25, 0xa8, 0x8a, 0xff, 0x25, 0xa9, 0x8b, 0xff, 0x24, 0xa9, 0x8c, 0xff, 0x22, 0xa8, 0x8a, 0xff, 0x21, 0xa9, 0x8a, 0xff, 0x20, 0xa9, 0x89, 0xff, 0x1f, 0xa9, 0x89, 0xff, 0x1f, 0xa9, 0x87, 0xff, 0x1e, 0xa7, 0x85, 0xff, 0x1a, 0xa7, 0x83, 0xff, 0x18, 0xa7, 0x82, 0xff, 0x15, 0xa6, 0x80, 0xff, 0x14, 0xa7, 0x80, 0xff, 0x15, 0xa7, 0x80, 0xff, 0x14, 0xa6, 0x7e, 0xff, 0x13, 0xa6, 0x7c, 0xff, 0x13, 0xa6, 0x7a, 0xff, 0x11, 0xa6, 0x79, 0xff, 0x12, 0xa7, 0x78, 0xff, 0x14, 0xa8, 0x79, 0xff, 0x14, 0xa7, 0x78, 0xff, 0x14, 0xa6, 0x79, 0xff, 0x15, 0xa6, 0x7b, 0xff, 0x13, 0xa7, 0x7a, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x12, 0xa8, 0x79, 0xff, 0x12, 0xa6, 0x78, 0xff, 0x13, 0xa7, 0x7c, 0xff, 0x13, 0xa7, 0x7e, 0xff, 0x15, 0xa7, 0x7f, 0xff, 0x16, 0xa7, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x1a, 0xa6, 0x82, 0xff, 0x1a, 0xa5, 0x83, 0xff, 0x1a, 0xa6, 0x82, 0xff, 0x19, 0xa5, 0x80, 0xff, 0x19, 0xa5, 0x80, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x17, 0xa7, 0x7e, 0xff, 0x16, 0xa6, 0x7d, 0xff, 0x15, 0xa5, 0x7c, 0xff, 0x15, 0xa5, 0x7b, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0e, 0xaa, 0x74, 0xff, 0x0e, 0xaa, 0x74, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x06, 0xa7, 0x6c, 0xff, 0x05, 0xa5, 0x6c, 0xff, 0x06, 0xa4, 0x6b, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0c, 0xa6, 0x6a, 0xff, 0x0f, 0xa4, 0x6a, 0xff, 0x11, 0xa3, 0x6a, 0xff, 0x12, 0xa4, 0x69, 0xff, 0x11, 0xab, 0x69, 0xff, 0x0a, 0xa4, 0x63, 0xff, 0x06, 0xa1, 0x61, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x08, 0xa5, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x10, 0xa7, 0x68, 0xff, 0x0f, 0x89, 0x4f, 0xff, 0x02, 0x68, 0x33, 0xff, 0x11, 0x7e, 0x4b, 0xff, 0x06, 0x80, 0x4c, 0xff, 0x16, 0x99, 0x65, 0xff, 0x1a, 0xa1, 0x6d, 0xff, 0x12, 0xa0, 0x6b, 0xff, 0x07, 0x8f, 0x5a, 0xff, 0x05, 0x67, 0x37, 0xff, 0x02, 0x51, 0x24, 0xff, 0x15, 0x65, 0x3c, 0xff, 0x0a, 0x4a, 0x25, 0xff, 0x06, 0x46, 0x21, 0xff, 0x12, 0x60, 0x3b, 0xff, 0x04, 0x3d, 0x1c, 0xff, 0x04, 0x2b, 0x12, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x0c, 0x4a, 0x2b, 0xff, 0x02, 0x36, 0x19, 0xff, 0x0a, 0x39, 0x21, 0xff, 0x10, 0x44, 0x2f, 0xff, 0x04, 0x42, 0x2a, 0xff, 0x01, 0x48, 0x29, 0xff, 0x02, 0x58, 0x2e, 0xff, 0x10, 0x79, 0x4a, 0xff, 0x18, 0x8a, 0x5a, 0xff, 0x11, 0x88, 0x56, 0xff, 0x0c, 0x81, 0x4b, 0xff, 0x04, 0x76, 0x3a, 0xff, 0x0c, 0x81, 0x3c, 0xff, 0x0b, 0x82, 0x39, 0xff, 0x09, 0x81, 0x3b, 0xff, 0x04, 0x78, 0x37, 0xff, 0x04, 0x74, 0x35, 0xff, 0x09, 0x77, 0x39, 0xff, 0x05, 0x76, 0x35, 0xff, 0x02, 0x77, 0x33, 0xff, 0x02, 0x78, 0x36, 0xff, 0x02, 0x77, 0x38, 0xff, 0x04, 0x71, 0x38, 0xff, 0x04, 0x67, 0x32, 0xff, 0x17, 0x75, 0x3f, 0xff, 0x0e, 0x59, 0x28, 0xff, 0x10, 0x4e, 0x23, 0xff, 0x06, 0x58, 0x2c, 0xff, 0x10, 0x7b, 0x4c, 0xff, 0x0a, 0x6e, 0x3f, 0xff, 0x09, 0x52, 0x2a, 0xff, 0x00, 0x28, 0x0e, 0xff, 0x0b, 0x44, 0x28, 0xff, 0x0d, 0x5a, 0x32, 0xff, 0x06, 0x54, 0x2c, 0xff, 0x0b, 0x5d, 0x35, 0xff, 0x14, 0x64, 0x3a, 0xff, 0x0f, 0x4f, 0x2e, 0xff, 0x02, 0x39, 0x19, 0xff, 0x0d, 0x58, 0x33, 0xff, 0x06, 0x54, 0x2e, 0xff, 0x06, 0x54, 0x2e, 0xff, 0x0e, 0x59, 0x33, 0xff, 0x08, 0x51, 0x2b, 0xff, 0x09, 0x54, 0x2e, 0xff, 0x09, 0x57, 0x30, 0xff, 0x0a, 0x58, 0x32, 0xff, 0x08, 0x50, 0x2c, 0xff, 0x09, 0x4d, 0x2b, 0xff, 0x08, 0x46, 0x28, 0xff, 0x0a, 0x44, 0x28, 0xff, 0x02, 0x2c, 0x17, 0xff, 0x01, 0x1d, 0x0f, 0xff, 0x63, 0x72, 0x69, 0xff, + 0x22, 0x35, 0xc4, 0xff, 0x16, 0x2f, 0xc0, 0xff, 0x42, 0x60, 0xde, 0xff, 0x68, 0x8e, 0xed, 0xff, 0x69, 0x95, 0xd5, 0xff, 0x2a, 0x51, 0x74, 0xff, 0x06, 0x2f, 0x32, 0xff, 0x08, 0x35, 0x17, 0xff, 0x08, 0x30, 0x1c, 0xff, 0x02, 0x30, 0x20, 0xff, 0x05, 0x33, 0x21, 0xff, 0x18, 0x3c, 0x4a, 0xff, 0x28, 0x4c, 0x76, 0xff, 0x2e, 0x57, 0x84, 0xff, 0x1d, 0x47, 0x72, 0xff, 0x7f, 0xac, 0xda, 0xff, 0x87, 0xb4, 0xe4, 0xff, 0x22, 0x4a, 0x7e, 0xff, 0x17, 0x3c, 0x72, 0xff, 0x85, 0xac, 0xe3, 0xff, 0x36, 0x5c, 0x91, 0xff, 0x4c, 0x72, 0xa7, 0xff, 0x40, 0x62, 0x97, 0xff, 0x20, 0x3f, 0x76, 0xff, 0x3c, 0x5e, 0x95, 0xff, 0x07, 0x2d, 0x63, 0xff, 0x1c, 0x47, 0x7c, 0xff, 0x74, 0xa5, 0xd8, 0xff, 0x75, 0xaa, 0xdd, 0xff, 0x6d, 0xa4, 0xd7, 0xff, 0x65, 0x9e, 0xd1, 0xff, 0x53, 0x8b, 0xbe, 0xff, 0x5f, 0x92, 0xc4, 0xff, 0x74, 0xa9, 0xdc, 0xff, 0x7a, 0xab, 0xe3, 0xff, 0x60, 0x89, 0xc1, 0xff, 0x20, 0x51, 0x73, 0xff, 0x26, 0x7c, 0x78, 0xff, 0x20, 0x96, 0x76, 0xff, 0x12, 0x9d, 0x69, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x10, 0xa0, 0x67, 0xff, 0x0d, 0x9e, 0x6d, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0b, 0x9f, 0x6b, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x08, 0xab, 0x6f, 0xff, 0x05, 0xa7, 0x6c, 0xff, 0x0a, 0xaa, 0x70, 0xff, 0x0c, 0xac, 0x74, 0xff, 0x02, 0xa4, 0x6e, 0xff, 0x09, 0xad, 0x76, 0xff, 0x08, 0xad, 0x70, 0xff, 0x0e, 0xaa, 0x6f, 0xff, 0x11, 0x9d, 0x67, 0xff, 0x29, 0xa6, 0x74, 0xff, 0x31, 0xa0, 0x71, 0xff, 0x43, 0xa7, 0x7d, 0xff, 0x42, 0xa0, 0x77, 0xff, 0x38, 0x99, 0x71, 0xff, 0x3f, 0xb8, 0x8d, 0xff, 0x24, 0xa7, 0x75, 0xff, 0x15, 0xa6, 0x6b, 0xff, 0x17, 0xb1, 0x73, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0e, 0xb0, 0x73, 0xff, 0x09, 0xaa, 0x6b, 0xff, 0x10, 0xad, 0x6d, 0xff, 0x12, 0xa7, 0x67, 0xff, 0x0a, 0xa7, 0x65, 0xff, 0x0c, 0xa6, 0x67, 0xff, 0x34, 0xb7, 0x7f, 0xff, 0x68, 0xc7, 0x9b, 0xff, 0x6f, 0xc1, 0x99, 0xff, 0x32, 0x93, 0x68, 0xff, 0x13, 0x88, 0x56, 0xff, 0x04, 0x93, 0x53, 0xff, 0x0d, 0xa3, 0x5f, 0xff, 0x18, 0xb1, 0x6d, 0xff, 0x13, 0xae, 0x6c, 0xff, 0x0e, 0xa8, 0x6e, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x11, 0xa3, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0e, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x11, 0xa5, 0x71, 0xff, 0x13, 0xa5, 0x72, 0xff, 0x14, 0xa5, 0x74, 0xff, 0x16, 0xa6, 0x76, 0xff, 0x17, 0xa6, 0x78, 0xff, 0x18, 0xa6, 0x79, 0xff, 0x1b, 0xa8, 0x7d, 0xff, 0x1c, 0xa8, 0x7e, 0xff, 0x1f, 0xa9, 0x80, 0xff, 0x21, 0xa9, 0x81, 0xff, 0x21, 0xa9, 0x82, 0xff, 0x1f, 0xa7, 0x80, 0xff, 0x1b, 0xa6, 0x7c, 0xff, 0x19, 0xa5, 0x7a, 0xff, 0x17, 0xa8, 0x76, 0xff, 0x16, 0xa7, 0x74, 0xff, 0x18, 0xa7, 0x78, 0xff, 0x1b, 0xa8, 0x7c, 0xff, 0x22, 0xa9, 0x83, 0xff, 0x27, 0xaa, 0x89, 0xff, 0x29, 0xa9, 0x8d, 0xff, 0x2a, 0xa9, 0x8e, 0xff, 0x2b, 0xaa, 0x8d, 0xff, 0x2b, 0xaa, 0x8c, 0xff, 0x29, 0xa9, 0x8b, 0xff, 0x28, 0xa9, 0x8c, 0xff, 0x27, 0xa7, 0x8b, 0xff, 0x25, 0xa7, 0x8a, 0xff, 0x25, 0xa8, 0x8b, 0xff, 0x25, 0xa8, 0x8b, 0xff, 0x28, 0xa9, 0x8e, 0xff, 0x27, 0xa8, 0x8d, 0xff, 0x27, 0xa9, 0x8d, 0xff, 0x27, 0xa8, 0x8e, 0xff, 0x24, 0xa8, 0x8c, 0xff, 0x23, 0xa9, 0x8a, 0xff, 0x22, 0xa9, 0x89, 0xff, 0x20, 0xa9, 0x89, 0xff, 0x20, 0xa8, 0x87, 0xff, 0x1f, 0xa8, 0x86, 0xff, 0x1c, 0xa7, 0x83, 0xff, 0x19, 0xa7, 0x81, 0xff, 0x17, 0xa8, 0x80, 0xff, 0x15, 0xa7, 0x7d, 0xff, 0x13, 0xa6, 0x7a, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x14, 0xa5, 0x77, 0xff, 0x12, 0xa4, 0x73, 0xff, 0x10, 0xa2, 0x6f, 0xff, 0x10, 0xa2, 0x6e, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x10, 0xa0, 0x6c, 0xff, 0x0f, 0x9f, 0x6d, 0xff, 0x10, 0x9e, 0x6e, 0xff, 0x0f, 0x9f, 0x6f, 0xff, 0x0e, 0xa1, 0x6f, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x11, 0xa4, 0x70, 0xff, 0x11, 0xa5, 0x70, 0xff, 0x10, 0xa3, 0x70, 0xff, 0x12, 0xa6, 0x73, 0xff, 0x11, 0xa5, 0x74, 0xff, 0x12, 0xa7, 0x77, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x13, 0xa8, 0x7c, 0xff, 0x14, 0xa7, 0x7d, 0xff, 0x15, 0xa7, 0x7e, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x19, 0xa6, 0x80, 0xff, 0x1a, 0xa6, 0x81, 0xff, 0x1a, 0xa7, 0x81, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x19, 0xa7, 0x81, 0xff, 0x19, 0xa7, 0x81, 0xff, 0x19, 0xa7, 0x81, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x18, 0xa6, 0x80, 0xff, 0x16, 0xa5, 0x7e, 0xff, 0x14, 0xa5, 0x7c, 0xff, 0x15, 0xa6, 0x7d, 0xff, 0x15, 0xa6, 0x7d, 0xff, 0x15, 0xa7, 0x7c, 0xff, 0x15, 0xa7, 0x7c, 0xff, 0x14, 0xa6, 0x7b, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x12, 0xa7, 0x79, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa9, 0x73, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x0d, 0xa9, 0x6f, 0xff, 0x0a, 0xa6, 0x6b, 0xff, 0x0b, 0xa8, 0x6b, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x10, 0xa4, 0x6b, 0xff, 0x12, 0xa1, 0x6a, 0xff, 0x1e, 0xa5, 0x6f, 0xff, 0x1c, 0xa0, 0x6b, 0xff, 0x15, 0x9b, 0x64, 0xff, 0x08, 0x9f, 0x5e, 0xff, 0x02, 0x9a, 0x5b, 0xff, 0x03, 0x9c, 0x5f, 0xff, 0x07, 0xa0, 0x65, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x10, 0xa6, 0x67, 0xff, 0x10, 0x89, 0x4e, 0xff, 0x04, 0x6e, 0x37, 0xff, 0x14, 0x8d, 0x57, 0xff, 0x11, 0x9a, 0x64, 0xff, 0x11, 0xa1, 0x6b, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x16, 0xa2, 0x6d, 0xff, 0x1a, 0x81, 0x52, 0xff, 0x0a, 0x62, 0x36, 0xff, 0x0e, 0x55, 0x2f, 0xff, 0x21, 0x62, 0x3d, 0xff, 0x04, 0x3c, 0x19, 0xff, 0x09, 0x57, 0x31, 0xff, 0x0c, 0x51, 0x2d, 0xff, 0x00, 0x2c, 0x12, 0xff, 0x06, 0x38, 0x1d, 0xff, 0x04, 0x3c, 0x1c, 0xff, 0x02, 0x38, 0x18, 0xff, 0x0e, 0x41, 0x27, 0xff, 0x0f, 0x44, 0x2a, 0xff, 0x08, 0x4c, 0x2d, 0xff, 0x0e, 0x70, 0x43, 0xff, 0x11, 0x88, 0x54, 0xff, 0x14, 0x96, 0x60, 0xff, 0x0b, 0x91, 0x59, 0xff, 0x09, 0x8f, 0x55, 0xff, 0x08, 0x89, 0x4e, 0xff, 0x03, 0x75, 0x37, 0xff, 0x0b, 0x7e, 0x3b, 0xff, 0x0c, 0x80, 0x39, 0xff, 0x0b, 0x81, 0x3c, 0xff, 0x05, 0x7a, 0x38, 0xff, 0x05, 0x74, 0x36, 0xff, 0x06, 0x75, 0x37, 0xff, 0x04, 0x76, 0x35, 0xff, 0x01, 0x78, 0x33, 0xff, 0x01, 0x77, 0x36, 0xff, 0x02, 0x76, 0x37, 0xff, 0x03, 0x70, 0x37, 0xff, 0x02, 0x66, 0x2f, 0xff, 0x08, 0x68, 0x30, 0xff, 0x1c, 0x71, 0x3c, 0xff, 0x0c, 0x53, 0x25, 0xff, 0x04, 0x50, 0x25, 0xff, 0x12, 0x74, 0x46, 0xff, 0x0f, 0x72, 0x43, 0xff, 0x0b, 0x56, 0x2c, 0xff, 0x01, 0x28, 0x0c, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x0e, 0x5a, 0x32, 0xff, 0x04, 0x51, 0x2a, 0xff, 0x0b, 0x5c, 0x36, 0xff, 0x0b, 0x5c, 0x31, 0xff, 0x17, 0x5b, 0x3a, 0xff, 0x03, 0x41, 0x20, 0xff, 0x0f, 0x5c, 0x34, 0xff, 0x07, 0x55, 0x2e, 0xff, 0x08, 0x56, 0x30, 0xff, 0x0e, 0x59, 0x33, 0xff, 0x08, 0x50, 0x2b, 0xff, 0x0a, 0x54, 0x2e, 0xff, 0x08, 0x56, 0x30, 0xff, 0x0a, 0x57, 0x32, 0xff, 0x0a, 0x53, 0x2f, 0xff, 0x09, 0x4c, 0x2a, 0xff, 0x09, 0x45, 0x27, 0xff, 0x0a, 0x40, 0x23, 0xff, 0x01, 0x29, 0x15, 0xff, 0x01, 0x1c, 0x0e, 0xff, 0x63, 0x72, 0x69, 0xff, + 0x1c, 0x30, 0xbf, 0xff, 0x16, 0x30, 0xc2, 0xff, 0x2e, 0x4c, 0xcd, 0xff, 0x5f, 0x81, 0xee, 0xff, 0x71, 0x95, 0xf1, 0xff, 0x6b, 0x89, 0xd6, 0xff, 0x37, 0x56, 0x84, 0xff, 0x05, 0x2b, 0x25, 0xff, 0x08, 0x30, 0x1e, 0xff, 0x03, 0x32, 0x1c, 0xff, 0x04, 0x32, 0x1d, 0xff, 0x0f, 0x34, 0x40, 0xff, 0x25, 0x4b, 0x75, 0xff, 0x2a, 0x54, 0x80, 0xff, 0x1f, 0x49, 0x73, 0xff, 0x7b, 0xa6, 0xd3, 0xff, 0x75, 0xa0, 0xcf, 0xff, 0x13, 0x3b, 0x6f, 0xff, 0x19, 0x40, 0x76, 0xff, 0x89, 0xaf, 0xe5, 0xff, 0x49, 0x70, 0xa5, 0xff, 0x39, 0x60, 0x94, 0xff, 0x33, 0x58, 0x8b, 0xff, 0x34, 0x57, 0x8c, 0xff, 0x74, 0x99, 0xce, 0xff, 0x38, 0x61, 0x96, 0xff, 0x59, 0x86, 0xbb, 0xff, 0x74, 0xa7, 0xdb, 0xff, 0x6e, 0xa4, 0xd9, 0xff, 0x5c, 0x96, 0xcb, 0xff, 0x53, 0x8b, 0xc1, 0xff, 0x61, 0x97, 0xcc, 0xff, 0x71, 0xaa, 0xd8, 0xff, 0x6d, 0xa6, 0xd3, 0xff, 0x53, 0x81, 0xb5, 0xff, 0x1b, 0x3c, 0x6e, 0xff, 0x02, 0x28, 0x43, 0xff, 0x24, 0x86, 0x73, 0xff, 0x16, 0x9c, 0x6d, 0xff, 0x0f, 0x9f, 0x67, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x0c, 0xa0, 0x65, 0xff, 0x0f, 0x9f, 0x66, 0xff, 0x0c, 0x9e, 0x6d, 0xff, 0x06, 0xa1, 0x6c, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x08, 0xab, 0x71, 0xff, 0x0f, 0xb5, 0x79, 0xff, 0x0e, 0xb3, 0x77, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x08, 0xa7, 0x71, 0xff, 0x05, 0xa6, 0x6f, 0xff, 0x14, 0xb0, 0x76, 0xff, 0x15, 0xa5, 0x6f, 0xff, 0x26, 0x9e, 0x6f, 0xff, 0x56, 0xbc, 0x92, 0xff, 0x75, 0xce, 0xa7, 0xff, 0x77, 0xcc, 0xa8, 0xff, 0x54, 0xab, 0x85, 0xff, 0x47, 0xa6, 0x7f, 0xff, 0x2d, 0xaa, 0x7d, 0xff, 0x1d, 0xa2, 0x70, 0xff, 0x11, 0xa0, 0x65, 0xff, 0x13, 0xa8, 0x6a, 0xff, 0x10, 0xa8, 0x6c, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x07, 0x9f, 0x62, 0xff, 0x06, 0x9c, 0x60, 0xff, 0x05, 0x9e, 0x60, 0xff, 0x05, 0x9c, 0x5f, 0xff, 0x17, 0xa0, 0x69, 0xff, 0x31, 0xa0, 0x72, 0xff, 0x32, 0x96, 0x6b, 0xff, 0x14, 0x81, 0x53, 0xff, 0x07, 0x7e, 0x4c, 0xff, 0x01, 0x83, 0x48, 0xff, 0x03, 0x8d, 0x4e, 0xff, 0x14, 0xa5, 0x65, 0xff, 0x15, 0xa9, 0x69, 0xff, 0x10, 0xa5, 0x6a, 0xff, 0x0f, 0xa5, 0x6e, 0xff, 0x12, 0xa6, 0x70, 0xff, 0x12, 0xa4, 0x6e, 0xff, 0x11, 0xa2, 0x6d, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x11, 0xa3, 0x6f, 0xff, 0x12, 0xa3, 0x70, 0xff, 0x12, 0xa4, 0x72, 0xff, 0x14, 0xa4, 0x74, 0xff, 0x16, 0xa5, 0x75, 0xff, 0x18, 0xa5, 0x78, 0xff, 0x1a, 0xa6, 0x7b, 0xff, 0x1c, 0xa8, 0x7e, 0xff, 0x20, 0xa9, 0x80, 0xff, 0x21, 0xaa, 0x83, 0xff, 0x23, 0xa9, 0x84, 0xff, 0x24, 0xa9, 0x85, 0xff, 0x25, 0xa9, 0x86, 0xff, 0x24, 0xa8, 0x86, 0xff, 0x22, 0xa6, 0x83, 0xff, 0x1e, 0xa4, 0x7e, 0xff, 0x1c, 0xa3, 0x7d, 0xff, 0x19, 0xa5, 0x79, 0xff, 0x19, 0xa5, 0x79, 0xff, 0x1d, 0xa6, 0x7e, 0xff, 0x1f, 0xa7, 0x81, 0xff, 0x26, 0xa8, 0x89, 0xff, 0x2a, 0xaa, 0x8d, 0xff, 0x2e, 0xaa, 0x92, 0xff, 0x2e, 0xa8, 0x92, 0xff, 0x2d, 0xaa, 0x90, 0xff, 0x2d, 0xaa, 0x8f, 0xff, 0x2b, 0xa9, 0x8e, 0xff, 0x2b, 0xa9, 0x8f, 0xff, 0x2c, 0xaa, 0x91, 0xff, 0x2b, 0xaa, 0x90, 0xff, 0x2b, 0xaa, 0x90, 0xff, 0x2c, 0xab, 0x92, 0xff, 0x2d, 0xab, 0x92, 0xff, 0x2e, 0xaa, 0x91, 0xff, 0x2c, 0xa9, 0x92, 0xff, 0x2a, 0xa9, 0x91, 0xff, 0x28, 0xa9, 0x8f, 0xff, 0x26, 0xa9, 0x8d, 0xff, 0x23, 0xa8, 0x8a, 0xff, 0x22, 0xa8, 0x89, 0xff, 0x1f, 0xa8, 0x86, 0xff, 0x1e, 0xa8, 0x85, 0xff, 0x1c, 0xa8, 0x82, 0xff, 0x1c, 0xa9, 0x80, 0xff, 0x1a, 0xa9, 0x7c, 0xff, 0x18, 0xa6, 0x78, 0xff, 0x17, 0xa4, 0x73, 0xff, 0x15, 0xa1, 0x70, 0xff, 0x13, 0x9d, 0x6a, 0xff, 0x0c, 0x96, 0x63, 0xff, 0x09, 0x92, 0x5c, 0xff, 0x07, 0x90, 0x58, 0xff, 0x06, 0x8e, 0x55, 0xff, 0x08, 0x8f, 0x57, 0xff, 0x07, 0x8c, 0x57, 0xff, 0x08, 0x8c, 0x59, 0xff, 0x09, 0x8f, 0x5c, 0xff, 0x06, 0x8f, 0x5a, 0xff, 0x08, 0x91, 0x5b, 0xff, 0x0b, 0x95, 0x5e, 0xff, 0x0c, 0x98, 0x61, 0xff, 0x0d, 0x99, 0x61, 0xff, 0x11, 0x9e, 0x68, 0xff, 0x11, 0x9e, 0x69, 0xff, 0x11, 0x9f, 0x6c, 0xff, 0x13, 0xa2, 0x71, 0xff, 0x15, 0xa6, 0x75, 0xff, 0x13, 0xa5, 0x77, 0xff, 0x13, 0xa5, 0x78, 0xff, 0x15, 0xa7, 0x7b, 0xff, 0x17, 0xa8, 0x7d, 0xff, 0x18, 0xa7, 0x7d, 0xff, 0x19, 0xa8, 0x7f, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x17, 0xa7, 0x80, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x14, 0xa5, 0x7d, 0xff, 0x12, 0xa6, 0x7b, 0xff, 0x13, 0xa7, 0x7b, 0xff, 0x13, 0xa7, 0x7b, 0xff, 0x13, 0xa8, 0x7b, 0xff, 0x12, 0xa7, 0x7a, 0xff, 0x12, 0xa7, 0x7a, 0xff, 0x11, 0xa7, 0x78, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x09, 0xa9, 0x70, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0d, 0xa8, 0x6d, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0d, 0xa6, 0x68, 0xff, 0x0e, 0xa5, 0x68, 0xff, 0x10, 0xa4, 0x69, 0xff, 0x13, 0xa3, 0x6a, 0xff, 0x1a, 0xa4, 0x6e, 0xff, 0x26, 0xaa, 0x76, 0xff, 0x19, 0x98, 0x66, 0xff, 0x14, 0x96, 0x62, 0xff, 0x08, 0x9c, 0x5f, 0xff, 0x0c, 0xa2, 0x65, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0c, 0xa7, 0x6b, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x09, 0xa6, 0x69, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x10, 0xa6, 0x67, 0xff, 0x10, 0x8b, 0x51, 0xff, 0x06, 0x77, 0x3f, 0xff, 0x15, 0x98, 0x61, 0xff, 0x0f, 0xa0, 0x67, 0xff, 0x0e, 0xa2, 0x6a, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x08, 0x92, 0x5d, 0xff, 0x0b, 0x8b, 0x58, 0xff, 0x13, 0x7b, 0x4c, 0xff, 0x0b, 0x6a, 0x3e, 0xff, 0x05, 0x52, 0x2b, 0xff, 0x1b, 0x5f, 0x3b, 0xff, 0x0c, 0x4b, 0x26, 0xff, 0x05, 0x50, 0x28, 0xff, 0x13, 0x63, 0x3c, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x05, 0x3c, 0x1d, 0xff, 0x03, 0x38, 0x16, 0xff, 0x03, 0x3d, 0x1e, 0xff, 0x04, 0x40, 0x29, 0xff, 0x08, 0x4a, 0x36, 0xff, 0x0c, 0x5b, 0x42, 0xff, 0x18, 0x81, 0x5a, 0xff, 0x13, 0x96, 0x61, 0xff, 0x07, 0x96, 0x5b, 0xff, 0x06, 0x95, 0x5a, 0xff, 0x07, 0x92, 0x56, 0xff, 0x09, 0x8c, 0x50, 0xff, 0x05, 0x7a, 0x3d, 0xff, 0x04, 0x72, 0x33, 0xff, 0x0c, 0x7d, 0x3a, 0xff, 0x09, 0x7d, 0x39, 0xff, 0x05, 0x79, 0x37, 0xff, 0x06, 0x75, 0x37, 0xff, 0x05, 0x76, 0x37, 0xff, 0x04, 0x77, 0x37, 0xff, 0x02, 0x78, 0x36, 0xff, 0x03, 0x78, 0x37, 0xff, 0x04, 0x73, 0x38, 0xff, 0x03, 0x6d, 0x34, 0xff, 0x04, 0x65, 0x2d, 0xff, 0x05, 0x64, 0x2c, 0xff, 0x13, 0x71, 0x3a, 0xff, 0x10, 0x61, 0x31, 0xff, 0x03, 0x50, 0x25, 0xff, 0x0c, 0x67, 0x3a, 0xff, 0x14, 0x74, 0x45, 0xff, 0x0a, 0x58, 0x2c, 0xff, 0x01, 0x29, 0x0c, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x0f, 0x5a, 0x32, 0xff, 0x07, 0x53, 0x2d, 0xff, 0x0a, 0x5b, 0x34, 0xff, 0x09, 0x5b, 0x2f, 0xff, 0x12, 0x56, 0x34, 0xff, 0x0f, 0x53, 0x31, 0xff, 0x11, 0x5f, 0x36, 0xff, 0x09, 0x58, 0x2f, 0xff, 0x08, 0x56, 0x2f, 0xff, 0x10, 0x59, 0x33, 0xff, 0x08, 0x4f, 0x2a, 0xff, 0x0b, 0x53, 0x2e, 0xff, 0x08, 0x55, 0x30, 0xff, 0x07, 0x55, 0x2f, 0xff, 0x0a, 0x51, 0x2d, 0xff, 0x09, 0x4a, 0x28, 0xff, 0x0b, 0x44, 0x27, 0xff, 0x09, 0x3c, 0x22, 0xff, 0x01, 0x27, 0x14, 0xff, 0x03, 0x1d, 0x10, 0xff, 0x63, 0x71, 0x69, 0xff, + 0x1b, 0x30, 0xbf, 0xff, 0x17, 0x2f, 0xc1, 0xff, 0x23, 0x3c, 0xc1, 0xff, 0x49, 0x67, 0xe2, 0xff, 0x6b, 0x8d, 0xfb, 0xff, 0x77, 0x92, 0xf9, 0xff, 0x6a, 0x85, 0xd4, 0xff, 0x16, 0x3a, 0x4d, 0xff, 0x04, 0x2e, 0x1f, 0xff, 0x01, 0x35, 0x18, 0xff, 0x02, 0x33, 0x1b, 0xff, 0x08, 0x2f, 0x3d, 0xff, 0x1c, 0x42, 0x6f, 0xff, 0x28, 0x51, 0x7e, 0xff, 0x24, 0x4c, 0x76, 0xff, 0x71, 0x9b, 0xc7, 0xff, 0x5e, 0x87, 0xb6, 0xff, 0x3b, 0x62, 0x96, 0xff, 0x21, 0x46, 0x7c, 0xff, 0x59, 0x7f, 0xb5, 0xff, 0x32, 0x58, 0x8e, 0xff, 0x57, 0x7f, 0xb1, 0xff, 0x41, 0x69, 0x99, 0xff, 0x54, 0x7d, 0xaf, 0xff, 0x8b, 0xb6, 0xe8, 0xff, 0x78, 0xa6, 0xd9, 0xff, 0x74, 0xa4, 0xd9, 0xff, 0x6e, 0xa2, 0xd7, 0xff, 0x61, 0x98, 0xce, 0xff, 0x4b, 0x84, 0xbc, 0xff, 0x5b, 0x92, 0xcb, 0xff, 0x73, 0xa8, 0xde, 0xff, 0x74, 0xb1, 0xdb, 0xff, 0x50, 0x8e, 0xb3, 0xff, 0x21, 0x4f, 0x7b, 0xff, 0x04, 0x1f, 0x4c, 0xff, 0x01, 0x26, 0x3d, 0xff, 0x1b, 0x85, 0x6c, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x0d, 0x9f, 0x67, 0xff, 0x0b, 0x9e, 0x6c, 0xff, 0x0d, 0x9e, 0x66, 0xff, 0x11, 0x9f, 0x67, 0xff, 0x0b, 0x9e, 0x6e, 0xff, 0x05, 0xa3, 0x6c, 0xff, 0x08, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xac, 0x72, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x0e, 0xb9, 0x7b, 0xff, 0x0e, 0xb6, 0x78, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x0d, 0xa8, 0x70, 0xff, 0x12, 0xae, 0x78, 0xff, 0x0d, 0xaa, 0x73, 0xff, 0x1a, 0xab, 0x74, 0xff, 0x22, 0xa4, 0x71, 0xff, 0x5c, 0xc6, 0x9b, 0xff, 0x80, 0xd9, 0xb3, 0xff, 0x8c, 0xdc, 0xba, 0xff, 0x77, 0xcc, 0xa9, 0xff, 0x4b, 0xac, 0x85, 0xff, 0x31, 0x9d, 0x74, 0xff, 0x12, 0x96, 0x67, 0xff, 0x10, 0x99, 0x65, 0xff, 0x0d, 0x9d, 0x61, 0xff, 0x0e, 0x9f, 0x61, 0xff, 0x0f, 0xa0, 0x65, 0xff, 0x0c, 0x9d, 0x63, 0xff, 0x08, 0x96, 0x5c, 0xff, 0x03, 0x92, 0x58, 0xff, 0x00, 0x91, 0x56, 0xff, 0x01, 0x8e, 0x53, 0xff, 0x02, 0x8e, 0x53, 0xff, 0x06, 0x8a, 0x54, 0xff, 0x0f, 0x88, 0x58, 0xff, 0x13, 0x86, 0x58, 0xff, 0x08, 0x7d, 0x4a, 0xff, 0x04, 0x7b, 0x46, 0xff, 0x03, 0x7e, 0x48, 0xff, 0x04, 0x86, 0x4c, 0xff, 0x0f, 0x98, 0x5a, 0xff, 0x11, 0xa0, 0x61, 0xff, 0x0d, 0x9e, 0x64, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x12, 0xa3, 0x6d, 0xff, 0x14, 0xa5, 0x6f, 0xff, 0x14, 0xa4, 0x71, 0xff, 0x12, 0xa4, 0x72, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x14, 0xa6, 0x74, 0xff, 0x17, 0xa6, 0x75, 0xff, 0x16, 0xa6, 0x75, 0xff, 0x16, 0xa6, 0x76, 0xff, 0x16, 0xa5, 0x76, 0xff, 0x18, 0xa6, 0x78, 0xff, 0x1c, 0xa7, 0x7c, 0xff, 0x1e, 0xa7, 0x7e, 0xff, 0x20, 0xa8, 0x80, 0xff, 0x22, 0xa9, 0x83, 0xff, 0x25, 0xa9, 0x86, 0xff, 0x26, 0xa9, 0x87, 0xff, 0x27, 0xa9, 0x88, 0xff, 0x27, 0xa8, 0x89, 0xff, 0x26, 0xa7, 0x87, 0xff, 0x24, 0xa6, 0x85, 0xff, 0x21, 0xa4, 0x81, 0xff, 0x1f, 0xa3, 0x80, 0xff, 0x1e, 0xa5, 0x80, 0xff, 0x1f, 0xa6, 0x81, 0xff, 0x22, 0xa8, 0x85, 0xff, 0x24, 0xa7, 0x87, 0xff, 0x29, 0xa9, 0x8c, 0xff, 0x2e, 0xab, 0x90, 0xff, 0x31, 0xab, 0x93, 0xff, 0x31, 0xaa, 0x94, 0xff, 0x2f, 0xac, 0x92, 0xff, 0x2f, 0xab, 0x91, 0xff, 0x2e, 0xab, 0x91, 0xff, 0x2f, 0xab, 0x92, 0xff, 0x2f, 0xaa, 0x92, 0xff, 0x2f, 0xaa, 0x93, 0xff, 0x2f, 0xab, 0x94, 0xff, 0x30, 0xac, 0x96, 0xff, 0x31, 0xac, 0x95, 0xff, 0x33, 0xac, 0x94, 0xff, 0x30, 0xab, 0x95, 0xff, 0x2e, 0xab, 0x95, 0xff, 0x2b, 0xaa, 0x91, 0xff, 0x29, 0xa9, 0x8f, 0xff, 0x25, 0xa8, 0x8b, 0xff, 0x24, 0xa8, 0x89, 0xff, 0x1f, 0xaa, 0x86, 0xff, 0x1d, 0xaa, 0x83, 0xff, 0x1d, 0xa9, 0x81, 0xff, 0x1b, 0xa8, 0x7c, 0xff, 0x19, 0xa4, 0x74, 0xff, 0x17, 0xa0, 0x6d, 0xff, 0x16, 0x9b, 0x67, 0xff, 0x11, 0x94, 0x5e, 0xff, 0x07, 0x87, 0x52, 0xff, 0x02, 0x80, 0x4c, 0xff, 0x02, 0x81, 0x48, 0xff, 0x03, 0x83, 0x48, 0xff, 0x03, 0x81, 0x46, 0xff, 0x02, 0x7f, 0x45, 0xff, 0x01, 0x79, 0x42, 0xff, 0x01, 0x79, 0x46, 0xff, 0x02, 0x7c, 0x49, 0xff, 0x01, 0x7b, 0x46, 0xff, 0x01, 0x7c, 0x46, 0xff, 0x02, 0x81, 0x49, 0xff, 0x03, 0x86, 0x4c, 0xff, 0x04, 0x87, 0x4e, 0xff, 0x08, 0x8c, 0x55, 0xff, 0x08, 0x8c, 0x55, 0xff, 0x09, 0x8e, 0x59, 0xff, 0x0e, 0x94, 0x60, 0xff, 0x13, 0x9d, 0x69, 0xff, 0x14, 0xa2, 0x6e, 0xff, 0x15, 0xa6, 0x74, 0xff, 0x14, 0xa8, 0x77, 0xff, 0x14, 0xa8, 0x78, 0xff, 0x14, 0xa9, 0x79, 0xff, 0x16, 0xa9, 0x7d, 0xff, 0x15, 0xa7, 0x80, 0xff, 0x15, 0xa6, 0x7f, 0xff, 0x15, 0xa6, 0x7f, 0xff, 0x15, 0xa6, 0x7f, 0xff, 0x15, 0xa7, 0x7f, 0xff, 0x15, 0xa6, 0x7f, 0xff, 0x14, 0xa6, 0x7e, 0xff, 0x13, 0xa6, 0x7c, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0c, 0xa6, 0x72, 0xff, 0x0c, 0xa6, 0x72, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0e, 0xaa, 0x73, 0xff, 0x0c, 0xac, 0x73, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0c, 0xa9, 0x70, 0xff, 0x0c, 0xaa, 0x70, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x70, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x07, 0xa1, 0x66, 0xff, 0x08, 0xa1, 0x65, 0xff, 0x0a, 0xa2, 0x63, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x10, 0xa6, 0x6a, 0xff, 0x11, 0xa3, 0x6a, 0xff, 0x13, 0xa1, 0x6a, 0xff, 0x16, 0x9c, 0x69, 0xff, 0x10, 0x93, 0x62, 0xff, 0x17, 0x9c, 0x68, 0xff, 0x10, 0xa1, 0x68, 0xff, 0x12, 0xa7, 0x6b, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0e, 0xa8, 0x6f, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0e, 0xa9, 0x6e, 0xff, 0x0e, 0xa8, 0x6d, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0d, 0xa4, 0x66, 0xff, 0x0e, 0x8f, 0x56, 0xff, 0x08, 0x81, 0x49, 0xff, 0x15, 0x9e, 0x66, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x08, 0x9c, 0x64, 0xff, 0x03, 0x8e, 0x59, 0xff, 0x04, 0x81, 0x4d, 0xff, 0x04, 0x7b, 0x49, 0xff, 0x04, 0x73, 0x42, 0xff, 0x03, 0x69, 0x3c, 0xff, 0x01, 0x58, 0x2f, 0xff, 0x09, 0x56, 0x2f, 0xff, 0x0e, 0x57, 0x30, 0xff, 0x04, 0x52, 0x29, 0xff, 0x14, 0x69, 0x3e, 0xff, 0x07, 0x52, 0x2f, 0xff, 0x02, 0x40, 0x1e, 0xff, 0x04, 0x3b, 0x18, 0xff, 0x02, 0x39, 0x1e, 0xff, 0x00, 0x3f, 0x30, 0xff, 0x0d, 0x5f, 0x58, 0xff, 0x24, 0x80, 0x76, 0xff, 0x0c, 0x6e, 0x58, 0xff, 0x11, 0x95, 0x65, 0xff, 0x05, 0x98, 0x5c, 0xff, 0x04, 0x96, 0x5a, 0xff, 0x06, 0x92, 0x56, 0xff, 0x0c, 0x8e, 0x53, 0xff, 0x0b, 0x81, 0x46, 0xff, 0x02, 0x6b, 0x31, 0xff, 0x0b, 0x77, 0x3a, 0xff, 0x07, 0x79, 0x36, 0xff, 0x05, 0x77, 0x36, 0xff, 0x06, 0x76, 0x39, 0xff, 0x05, 0x76, 0x38, 0xff, 0x03, 0x78, 0x38, 0xff, 0x03, 0x78, 0x37, 0xff, 0x05, 0x77, 0x38, 0xff, 0x07, 0x72, 0x38, 0xff, 0x04, 0x6d, 0x34, 0xff, 0x07, 0x65, 0x2d, 0xff, 0x07, 0x65, 0x2c, 0xff, 0x05, 0x69, 0x30, 0xff, 0x10, 0x6b, 0x38, 0xff, 0x03, 0x50, 0x25, 0xff, 0x06, 0x59, 0x2d, 0xff, 0x18, 0x77, 0x46, 0xff, 0x09, 0x58, 0x2c, 0xff, 0x00, 0x2b, 0x0d, 0xff, 0x07, 0x40, 0x22, 0xff, 0x0f, 0x5a, 0x32, 0xff, 0x06, 0x52, 0x2c, 0xff, 0x0a, 0x5a, 0x33, 0xff, 0x0a, 0x5b, 0x2f, 0xff, 0x0c, 0x50, 0x2e, 0xff, 0x12, 0x59, 0x37, 0xff, 0x10, 0x5f, 0x36, 0xff, 0x0a, 0x59, 0x30, 0xff, 0x08, 0x56, 0x2f, 0xff, 0x0f, 0x59, 0x33, 0xff, 0x09, 0x4f, 0x2a, 0xff, 0x0a, 0x52, 0x2e, 0xff, 0x07, 0x54, 0x2f, 0xff, 0x07, 0x54, 0x2f, 0xff, 0x07, 0x4e, 0x29, 0xff, 0x07, 0x48, 0x25, 0xff, 0x0a, 0x43, 0x25, 0xff, 0x08, 0x38, 0x1f, 0xff, 0x01, 0x26, 0x13, 0xff, 0x05, 0x1e, 0x12, 0xff, 0x65, 0x70, 0x6a, 0xff, + 0x19, 0x30, 0xc0, 0xff, 0x1b, 0x30, 0xc3, 0xff, 0x26, 0x38, 0xc7, 0xff, 0x29, 0x3d, 0xce, 0xff, 0x3c, 0x59, 0xe0, 0xff, 0x56, 0x78, 0xea, 0xff, 0x5e, 0x7d, 0xe5, 0xff, 0x26, 0x47, 0x7a, 0xff, 0x00, 0x2c, 0x23, 0xff, 0x00, 0x37, 0x14, 0xff, 0x02, 0x37, 0x19, 0xff, 0x04, 0x2b, 0x38, 0xff, 0x16, 0x3c, 0x69, 0xff, 0x2b, 0x52, 0x81, 0xff, 0x22, 0x47, 0x71, 0xff, 0x63, 0x8d, 0xb8, 0xff, 0x75, 0x9e, 0xcd, 0xff, 0x6b, 0x92, 0xc6, 0xff, 0x2e, 0x53, 0x89, 0xff, 0x39, 0x5f, 0x95, 0xff, 0x4c, 0x72, 0xa7, 0xff, 0x67, 0x8f, 0xc2, 0xff, 0x2c, 0x57, 0x87, 0xff, 0x7e, 0xae, 0xdc, 0xff, 0x84, 0xb5, 0xe4, 0xff, 0x6c, 0x9e, 0xd2, 0xff, 0x6c, 0x9f, 0xd4, 0xff, 0x59, 0x8c, 0xc3, 0xff, 0x4b, 0x80, 0xb9, 0xff, 0x67, 0x9e, 0xd7, 0xff, 0x73, 0xa9, 0xe1, 0xff, 0x72, 0xaa, 0xda, 0xff, 0x4c, 0x93, 0xb0, 0xff, 0x2d, 0x78, 0x8a, 0xff, 0x13, 0x49, 0x65, 0xff, 0x08, 0x20, 0x49, 0xff, 0x02, 0x2c, 0x41, 0xff, 0x18, 0x87, 0x6c, 0xff, 0x0c, 0xa0, 0x6b, 0xff, 0x10, 0x9f, 0x6a, 0xff, 0x0e, 0x9c, 0x70, 0xff, 0x0f, 0x9f, 0x69, 0xff, 0x12, 0xa0, 0x68, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x04, 0xa5, 0x6c, 0xff, 0x08, 0xa8, 0x69, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x08, 0xab, 0x70, 0xff, 0x07, 0xb0, 0x73, 0xff, 0x05, 0xb1, 0x73, 0xff, 0x07, 0xb0, 0x70, 0xff, 0x03, 0xa1, 0x64, 0xff, 0x04, 0x9f, 0x65, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x16, 0xae, 0x78, 0xff, 0x1c, 0x9e, 0x6d, 0xff, 0x5f, 0xd1, 0xa2, 0xff, 0x77, 0xd5, 0xac, 0xff, 0x70, 0xc8, 0xa1, 0xff, 0x63, 0xc0, 0x9a, 0xff, 0x47, 0xb0, 0x88, 0xff, 0x1c, 0x9a, 0x6c, 0xff, 0x0e, 0x96, 0x67, 0xff, 0x13, 0x9e, 0x6b, 0xff, 0x11, 0x9d, 0x66, 0xff, 0x0b, 0x98, 0x5d, 0xff, 0x0c, 0x96, 0x59, 0xff, 0x08, 0x8e, 0x55, 0xff, 0x03, 0x83, 0x4c, 0xff, 0x01, 0x82, 0x4a, 0xff, 0x03, 0x86, 0x4e, 0xff, 0x04, 0x86, 0x4f, 0xff, 0x04, 0x7f, 0x49, 0xff, 0x04, 0x77, 0x40, 0xff, 0x03, 0x74, 0x3f, 0xff, 0x01, 0x75, 0x42, 0xff, 0x01, 0x73, 0x41, 0xff, 0x05, 0x74, 0x3f, 0xff, 0x0a, 0x74, 0x3e, 0xff, 0x05, 0x76, 0x44, 0xff, 0x03, 0x7b, 0x45, 0xff, 0x02, 0x7f, 0x45, 0xff, 0x02, 0x83, 0x47, 0xff, 0x02, 0x86, 0x4d, 0xff, 0x01, 0x87, 0x50, 0xff, 0x05, 0x8e, 0x58, 0xff, 0x0e, 0x99, 0x62, 0xff, 0x15, 0xa1, 0x70, 0xff, 0x17, 0xa5, 0x75, 0xff, 0x14, 0xa6, 0x76, 0xff, 0x11, 0xa6, 0x76, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x17, 0xa7, 0x79, 0xff, 0x1a, 0xa8, 0x7b, 0xff, 0x1a, 0xa9, 0x7a, 0xff, 0x1a, 0xa8, 0x7b, 0xff, 0x1b, 0xa9, 0x7c, 0xff, 0x1e, 0xa9, 0x7f, 0xff, 0x21, 0xa7, 0x7f, 0xff, 0x22, 0xa7, 0x81, 0xff, 0x23, 0xa7, 0x83, 0xff, 0x24, 0xa8, 0x84, 0xff, 0x27, 0xa8, 0x88, 0xff, 0x27, 0xa9, 0x8a, 0xff, 0x2b, 0xa9, 0x8c, 0xff, 0x2c, 0xaa, 0x8d, 0xff, 0x2e, 0xac, 0x8f, 0xff, 0x2d, 0xac, 0x8e, 0xff, 0x2c, 0xac, 0x8d, 0xff, 0x2c, 0xad, 0x8d, 0xff, 0x2b, 0xac, 0x8f, 0xff, 0x2b, 0xab, 0x8f, 0xff, 0x2b, 0xab, 0x8f, 0xff, 0x2d, 0xab, 0x91, 0xff, 0x30, 0xac, 0x92, 0xff, 0x32, 0xad, 0x94, 0xff, 0x32, 0xac, 0x92, 0xff, 0x33, 0xab, 0x93, 0xff, 0x30, 0xac, 0x92, 0xff, 0x30, 0xac, 0x92, 0xff, 0x31, 0xab, 0x92, 0xff, 0x31, 0xab, 0x93, 0xff, 0x31, 0xaa, 0x95, 0xff, 0x31, 0xaa, 0x95, 0xff, 0x32, 0xab, 0x97, 0xff, 0x33, 0xac, 0x98, 0xff, 0x34, 0xac, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x32, 0xab, 0x96, 0xff, 0x31, 0xac, 0x96, 0xff, 0x2b, 0xa9, 0x93, 0xff, 0x29, 0xaa, 0x8f, 0xff, 0x26, 0xaa, 0x8a, 0xff, 0x23, 0xa9, 0x87, 0xff, 0x1c, 0xa9, 0x80, 0xff, 0x17, 0xa6, 0x7a, 0xff, 0x14, 0x9f, 0x70, 0xff, 0x0a, 0x92, 0x61, 0xff, 0x05, 0x84, 0x50, 0xff, 0x04, 0x7d, 0x47, 0xff, 0x03, 0x76, 0x3f, 0xff, 0x01, 0x74, 0x3c, 0xff, 0x00, 0x6f, 0x3a, 0xff, 0x00, 0x6e, 0x39, 0xff, 0x00, 0x6d, 0x36, 0xff, 0x01, 0x70, 0x37, 0xff, 0x01, 0x72, 0x39, 0xff, 0x03, 0x73, 0x39, 0xff, 0x06, 0x72, 0x3d, 0xff, 0x04, 0x70, 0x3d, 0xff, 0x01, 0x6e, 0x3b, 0xff, 0x00, 0x6d, 0x3a, 0xff, 0x01, 0x6f, 0x3a, 0xff, 0x01, 0x72, 0x3b, 0xff, 0x02, 0x75, 0x3d, 0xff, 0x01, 0x73, 0x3b, 0xff, 0x00, 0x73, 0x3c, 0xff, 0x00, 0x74, 0x3e, 0xff, 0x00, 0x78, 0x42, 0xff, 0x02, 0x7b, 0x44, 0xff, 0x03, 0x81, 0x4a, 0xff, 0x05, 0x89, 0x52, 0xff, 0x09, 0x94, 0x5d, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x12, 0xa7, 0x72, 0xff, 0x12, 0xaa, 0x76, 0xff, 0x13, 0xa8, 0x79, 0xff, 0x15, 0xa7, 0x7d, 0xff, 0x13, 0xa6, 0x7d, 0xff, 0x13, 0xa6, 0x7c, 0xff, 0x14, 0xa6, 0x7d, 0xff, 0x16, 0xa7, 0x7d, 0xff, 0x15, 0xa7, 0x7d, 0xff, 0x13, 0xa7, 0x7c, 0xff, 0x12, 0xa6, 0x7b, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x12, 0xa8, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa7, 0x72, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x11, 0xad, 0x77, 0xff, 0x0e, 0xaf, 0x75, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0c, 0xaa, 0x70, 0xff, 0x0c, 0xab, 0x71, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x0c, 0xac, 0x70, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0e, 0xa9, 0x6f, 0xff, 0x08, 0x9f, 0x66, 0xff, 0x01, 0x97, 0x5b, 0xff, 0x03, 0x9c, 0x5f, 0xff, 0x04, 0x9f, 0x5f, 0xff, 0x05, 0xa1, 0x60, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x0a, 0xa1, 0x67, 0xff, 0x09, 0x9e, 0x66, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x10, 0xa0, 0x6c, 0xff, 0x0c, 0x9a, 0x66, 0xff, 0x06, 0x99, 0x5f, 0xff, 0x06, 0x96, 0x5c, 0xff, 0x05, 0x94, 0x5c, 0xff, 0x04, 0x96, 0x5f, 0xff, 0x07, 0x98, 0x62, 0xff, 0x06, 0x99, 0x61, 0xff, 0x07, 0x9a, 0x62, 0xff, 0x09, 0x9d, 0x64, 0xff, 0x08, 0x9d, 0x66, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0d, 0xa7, 0x6d, 0xff, 0x0d, 0xa7, 0x6d, 0xff, 0x0e, 0xa7, 0x6c, 0xff, 0x0f, 0xa7, 0x6b, 0xff, 0x0f, 0xa7, 0x6c, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x0d, 0x97, 0x5c, 0xff, 0x0c, 0x8f, 0x56, 0xff, 0x14, 0xa2, 0x68, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0b, 0x9f, 0x66, 0xff, 0x11, 0x9b, 0x65, 0xff, 0x1c, 0x9c, 0x68, 0xff, 0x1e, 0x9e, 0x6b, 0xff, 0x1a, 0xa1, 0x6f, 0xff, 0x1d, 0x9a, 0x6d, 0xff, 0x14, 0x85, 0x5b, 0xff, 0x05, 0x60, 0x38, 0xff, 0x01, 0x52, 0x2c, 0xff, 0x03, 0x54, 0x2b, 0xff, 0x06, 0x60, 0x32, 0xff, 0x0c, 0x66, 0x3b, 0xff, 0x04, 0x51, 0x27, 0xff, 0x02, 0x43, 0x1d, 0xff, 0x0a, 0x4c, 0x38, 0xff, 0x0b, 0x5d, 0x60, 0xff, 0x43, 0xb0, 0xc4, 0xff, 0x67, 0xd5, 0xeb, 0xff, 0x24, 0x7f, 0x8e, 0xff, 0x09, 0x7e, 0x60, 0xff, 0x0b, 0x98, 0x5d, 0xff, 0x07, 0x97, 0x5c, 0xff, 0x09, 0x93, 0x58, 0xff, 0x0d, 0x8e, 0x55, 0xff, 0x0d, 0x81, 0x48, 0xff, 0x04, 0x71, 0x38, 0xff, 0x05, 0x6a, 0x33, 0xff, 0x07, 0x75, 0x37, 0xff, 0x05, 0x76, 0x36, 0xff, 0x06, 0x76, 0x39, 0xff, 0x04, 0x74, 0x38, 0xff, 0x03, 0x76, 0x37, 0xff, 0x03, 0x77, 0x36, 0xff, 0x06, 0x76, 0x38, 0xff, 0x09, 0x71, 0x38, 0xff, 0x04, 0x6b, 0x32, 0xff, 0x09, 0x65, 0x2d, 0xff, 0x06, 0x64, 0x2a, 0xff, 0x00, 0x66, 0x2c, 0xff, 0x08, 0x69, 0x34, 0xff, 0x0b, 0x59, 0x2d, 0xff, 0x03, 0x51, 0x25, 0xff, 0x17, 0x72, 0x41, 0xff, 0x0c, 0x5d, 0x31, 0xff, 0x01, 0x2d, 0x10, 0xff, 0x03, 0x39, 0x1a, 0xff, 0x0f, 0x5b, 0x33, 0xff, 0x06, 0x50, 0x2a, 0xff, 0x08, 0x57, 0x30, 0xff, 0x10, 0x61, 0x35, 0xff, 0x04, 0x49, 0x25, 0xff, 0x05, 0x4b, 0x28, 0xff, 0x10, 0x5f, 0x37, 0xff, 0x08, 0x58, 0x30, 0xff, 0x09, 0x55, 0x2f, 0xff, 0x0c, 0x56, 0x30, 0xff, 0x09, 0x50, 0x2b, 0xff, 0x08, 0x50, 0x2d, 0xff, 0x04, 0x50, 0x30, 0xff, 0x04, 0x4f, 0x35, 0xff, 0x01, 0x42, 0x2d, 0xff, 0x03, 0x41, 0x29, 0xff, 0x09, 0x41, 0x25, 0xff, 0x09, 0x36, 0x1e, 0xff, 0x01, 0x24, 0x14, 0xff, 0x05, 0x1d, 0x11, 0xff, 0x64, 0x71, 0x68, 0xff, + 0x13, 0x2f, 0xbd, 0xff, 0x16, 0x2f, 0xc3, 0xff, 0x24, 0x34, 0xc5, 0xff, 0x2b, 0x3e, 0xca, 0xff, 0x26, 0x44, 0xc6, 0xff, 0x28, 0x4b, 0xc9, 0xff, 0x2f, 0x4b, 0xcc, 0xff, 0x21, 0x41, 0x88, 0xff, 0x01, 0x2d, 0x2c, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x05, 0x35, 0x1a, 0xff, 0x05, 0x2f, 0x32, 0xff, 0x12, 0x37, 0x5e, 0xff, 0x22, 0x48, 0x73, 0xff, 0x19, 0x40, 0x66, 0xff, 0x48, 0x71, 0x9d, 0xff, 0x5a, 0x86, 0xb6, 0xff, 0x42, 0x6e, 0xa3, 0xff, 0x2a, 0x53, 0x8a, 0xff, 0x60, 0x85, 0xbc, 0xff, 0x27, 0x4d, 0x83, 0xff, 0x3c, 0x65, 0x9a, 0xff, 0x50, 0x7d, 0xaf, 0xff, 0x7f, 0xaf, 0xde, 0xff, 0x73, 0xa5, 0xd8, 0xff, 0x6c, 0xa2, 0xd8, 0xff, 0x69, 0xa0, 0xd6, 0xff, 0x55, 0x86, 0xc1, 0xff, 0x65, 0x98, 0xd3, 0xff, 0x6a, 0xa6, 0xd8, 0xff, 0x61, 0xa3, 0xca, 0xff, 0x45, 0x8e, 0xa2, 0xff, 0x23, 0x7f, 0x7e, 0xff, 0x22, 0x89, 0x7b, 0xff, 0x14, 0x60, 0x68, 0xff, 0x03, 0x23, 0x49, 0xff, 0x06, 0x37, 0x4d, 0xff, 0x1b, 0x8c, 0x6e, 0xff, 0x10, 0xa0, 0x6a, 0xff, 0x0f, 0xa0, 0x69, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0e, 0xa1, 0x6a, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x07, 0xaa, 0x72, 0xff, 0x07, 0xac, 0x71, 0xff, 0x04, 0xab, 0x6d, 0xff, 0x04, 0xa9, 0x69, 0xff, 0x05, 0xa4, 0x66, 0xff, 0x06, 0xa2, 0x67, 0xff, 0x07, 0xa2, 0x6c, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x2f, 0xac, 0x82, 0xff, 0x72, 0xdb, 0xb1, 0xff, 0x5d, 0xbd, 0x93, 0xff, 0x41, 0xab, 0x7e, 0xff, 0x30, 0xab, 0x79, 0xff, 0x20, 0xa3, 0x71, 0xff, 0x12, 0x9b, 0x68, 0xff, 0x0d, 0x98, 0x64, 0xff, 0x12, 0x90, 0x5e, 0xff, 0x08, 0x84, 0x50, 0xff, 0x05, 0x7f, 0x49, 0xff, 0x07, 0x7f, 0x49, 0xff, 0x03, 0x78, 0x44, 0xff, 0x00, 0x73, 0x40, 0xff, 0x00, 0x75, 0x41, 0xff, 0x03, 0x7b, 0x47, 0xff, 0x06, 0x7f, 0x48, 0xff, 0x06, 0x7c, 0x45, 0xff, 0x07, 0x77, 0x40, 0xff, 0x07, 0x76, 0x41, 0xff, 0x05, 0x73, 0x40, 0xff, 0x02, 0x6f, 0x3e, 0xff, 0x05, 0x6e, 0x3c, 0xff, 0x06, 0x6d, 0x3a, 0xff, 0x04, 0x71, 0x3e, 0xff, 0x03, 0x72, 0x3e, 0xff, 0x02, 0x72, 0x3d, 0xff, 0x01, 0x72, 0x3c, 0xff, 0x00, 0x74, 0x3d, 0xff, 0x00, 0x77, 0x40, 0xff, 0x01, 0x7b, 0x45, 0xff, 0x07, 0x83, 0x4c, 0xff, 0x0d, 0x8d, 0x5a, 0xff, 0x12, 0x96, 0x64, 0xff, 0x15, 0xa0, 0x6e, 0xff, 0x15, 0xa4, 0x74, 0xff, 0x15, 0xa6, 0x77, 0xff, 0x15, 0xa6, 0x79, 0xff, 0x18, 0xa7, 0x7d, 0xff, 0x1b, 0xa9, 0x7e, 0xff, 0x1c, 0xab, 0x7d, 0xff, 0x1c, 0xa9, 0x7d, 0xff, 0x1e, 0xab, 0x7f, 0xff, 0x20, 0xa9, 0x80, 0xff, 0x23, 0xa7, 0x81, 0xff, 0x25, 0xa7, 0x82, 0xff, 0x25, 0xa8, 0x84, 0xff, 0x25, 0xa9, 0x85, 0xff, 0x27, 0xa9, 0x88, 0xff, 0x29, 0xaa, 0x8b, 0xff, 0x2b, 0xa9, 0x8c, 0xff, 0x2c, 0xa9, 0x8e, 0xff, 0x2f, 0xab, 0x90, 0xff, 0x2f, 0xaa, 0x90, 0xff, 0x30, 0xab, 0x90, 0xff, 0x30, 0xac, 0x8f, 0xff, 0x30, 0xab, 0x93, 0xff, 0x30, 0xab, 0x93, 0xff, 0x30, 0xa9, 0x93, 0xff, 0x30, 0xaa, 0x93, 0xff, 0x30, 0xa9, 0x92, 0xff, 0x32, 0xaa, 0x94, 0xff, 0x33, 0xab, 0x94, 0xff, 0x33, 0xab, 0x94, 0xff, 0x31, 0xab, 0x93, 0xff, 0x31, 0xab, 0x93, 0xff, 0x31, 0xac, 0x92, 0xff, 0x31, 0xac, 0x92, 0xff, 0x31, 0xac, 0x95, 0xff, 0x30, 0xac, 0x96, 0xff, 0x31, 0xac, 0x98, 0xff, 0x32, 0xac, 0x98, 0xff, 0x33, 0xac, 0x98, 0xff, 0x33, 0xac, 0x98, 0xff, 0x33, 0xac, 0x98, 0xff, 0x30, 0xab, 0x96, 0xff, 0x2c, 0xab, 0x92, 0xff, 0x28, 0xac, 0x8c, 0xff, 0x21, 0xaa, 0x83, 0xff, 0x1b, 0xa8, 0x7c, 0xff, 0x13, 0x9f, 0x6f, 0xff, 0x10, 0x97, 0x65, 0xff, 0x09, 0x87, 0x56, 0xff, 0x02, 0x78, 0x47, 0xff, 0x00, 0x6a, 0x3a, 0xff, 0x00, 0x65, 0x34, 0xff, 0x00, 0x62, 0x31, 0xff, 0x01, 0x65, 0x33, 0xff, 0x01, 0x65, 0x35, 0xff, 0x02, 0x64, 0x36, 0xff, 0x01, 0x63, 0x34, 0xff, 0x00, 0x62, 0x32, 0xff, 0x01, 0x62, 0x31, 0xff, 0x04, 0x66, 0x35, 0xff, 0x07, 0x68, 0x3a, 0xff, 0x05, 0x65, 0x37, 0xff, 0x02, 0x63, 0x35, 0xff, 0x00, 0x61, 0x34, 0xff, 0x02, 0x64, 0x35, 0xff, 0x02, 0x66, 0x37, 0xff, 0x03, 0x68, 0x37, 0xff, 0x03, 0x69, 0x38, 0xff, 0x02, 0x68, 0x36, 0xff, 0x01, 0x68, 0x37, 0xff, 0x03, 0x6b, 0x3a, 0xff, 0x03, 0x6b, 0x3a, 0xff, 0x00, 0x6e, 0x3b, 0xff, 0x00, 0x74, 0x3f, 0xff, 0x01, 0x7b, 0x45, 0xff, 0x03, 0x83, 0x4d, 0xff, 0x0b, 0x94, 0x5e, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x12, 0xa5, 0x73, 0xff, 0x14, 0xa6, 0x7a, 0xff, 0x11, 0xa6, 0x7b, 0xff, 0x11, 0xa6, 0x7c, 0xff, 0x16, 0xa7, 0x7d, 0xff, 0x19, 0xa6, 0x7d, 0xff, 0x15, 0xa7, 0x7c, 0xff, 0x11, 0xa7, 0x7a, 0xff, 0x0f, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0e, 0xa7, 0x78, 0xff, 0x0b, 0xa5, 0x73, 0xff, 0x0a, 0xa5, 0x71, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x72, 0xff, 0x0b, 0xa5, 0x71, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x12, 0xac, 0x78, 0xff, 0x0f, 0xae, 0x76, 0xff, 0x0f, 0xa9, 0x71, 0xff, 0x10, 0xa7, 0x70, 0xff, 0x11, 0xa8, 0x71, 0xff, 0x0f, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x70, 0xff, 0x0b, 0xad, 0x73, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x0c, 0xad, 0x73, 0xff, 0x08, 0xa9, 0x6e, 0xff, 0x0a, 0xaa, 0x6f, 0xff, 0x0a, 0xa8, 0x6d, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x04, 0x99, 0x5e, 0xff, 0x08, 0xa1, 0x64, 0xff, 0x05, 0xa2, 0x5f, 0xff, 0x06, 0xa1, 0x5f, 0xff, 0x0d, 0xa5, 0x67, 0xff, 0x0c, 0xa0, 0x64, 0xff, 0x0d, 0x9e, 0x64, 0xff, 0x0f, 0x9f, 0x66, 0xff, 0x08, 0x99, 0x5f, 0xff, 0x02, 0x91, 0x57, 0xff, 0x02, 0x90, 0x52, 0xff, 0x01, 0x8b, 0x4f, 0xff, 0x01, 0x89, 0x4e, 0xff, 0x01, 0x88, 0x4f, 0xff, 0x02, 0x85, 0x4c, 0xff, 0x02, 0x86, 0x4e, 0xff, 0x03, 0x88, 0x50, 0xff, 0x04, 0x87, 0x50, 0xff, 0x02, 0x88, 0x4f, 0xff, 0x04, 0x8f, 0x55, 0xff, 0x06, 0x91, 0x58, 0xff, 0x08, 0x96, 0x5b, 0xff, 0x0a, 0x99, 0x5e, 0xff, 0x0a, 0x9a, 0x5e, 0xff, 0x0b, 0x9b, 0x60, 0xff, 0x0f, 0xa1, 0x65, 0xff, 0x0e, 0xa2, 0x67, 0xff, 0x0c, 0xa6, 0x69, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0c, 0x9c, 0x61, 0xff, 0x0d, 0x96, 0x5c, 0xff, 0x13, 0xa2, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x10, 0xa2, 0x69, 0xff, 0x16, 0x9d, 0x68, 0xff, 0x18, 0x98, 0x62, 0xff, 0x15, 0x8f, 0x60, 0xff, 0x18, 0x85, 0x5f, 0xff, 0x0e, 0x6e, 0x4d, 0xff, 0x03, 0x54, 0x32, 0xff, 0x00, 0x52, 0x2d, 0xff, 0x01, 0x5b, 0x2e, 0xff, 0x07, 0x72, 0x3e, 0xff, 0x0f, 0x7e, 0x4d, 0xff, 0x0b, 0x76, 0x45, 0xff, 0x06, 0x6e, 0x41, 0xff, 0x0d, 0x6b, 0x59, 0xff, 0x16, 0x7f, 0x96, 0xff, 0x43, 0xbe, 0xef, 0xff, 0x3f, 0xbd, 0xf1, 0xff, 0x2d, 0x97, 0xc5, 0xff, 0x06, 0x66, 0x66, 0xff, 0x10, 0x93, 0x5e, 0xff, 0x06, 0x98, 0x5b, 0xff, 0x04, 0x92, 0x52, 0xff, 0x05, 0x8b, 0x4d, 0xff, 0x09, 0x87, 0x45, 0xff, 0x0a, 0x80, 0x3f, 0xff, 0x04, 0x6e, 0x37, 0xff, 0x06, 0x72, 0x38, 0xff, 0x08, 0x74, 0x39, 0xff, 0x08, 0x74, 0x39, 0xff, 0x09, 0x76, 0x3b, 0xff, 0x03, 0x75, 0x37, 0xff, 0x03, 0x76, 0x37, 0xff, 0x05, 0x76, 0x37, 0xff, 0x07, 0x72, 0x36, 0xff, 0x05, 0x6c, 0x32, 0xff, 0x03, 0x65, 0x2c, 0xff, 0x03, 0x64, 0x2b, 0xff, 0x02, 0x65, 0x2b, 0xff, 0x06, 0x65, 0x2f, 0xff, 0x0c, 0x61, 0x2f, 0xff, 0x02, 0x54, 0x23, 0xff, 0x11, 0x66, 0x37, 0xff, 0x13, 0x63, 0x39, 0xff, 0x03, 0x32, 0x14, 0xff, 0x03, 0x34, 0x16, 0xff, 0x0f, 0x59, 0x36, 0xff, 0x0b, 0x4f, 0x2c, 0xff, 0x07, 0x53, 0x2c, 0xff, 0x0f, 0x61, 0x39, 0xff, 0x03, 0x47, 0x25, 0xff, 0x06, 0x48, 0x24, 0xff, 0x0c, 0x5a, 0x34, 0xff, 0x05, 0x57, 0x31, 0xff, 0x08, 0x53, 0x30, 0xff, 0x0a, 0x56, 0x2f, 0xff, 0x08, 0x50, 0x2c, 0xff, 0x05, 0x4a, 0x30, 0xff, 0x06, 0x4c, 0x42, 0xff, 0x16, 0x5c, 0x6d, 0xff, 0x0e, 0x47, 0x60, 0xff, 0x10, 0x4e, 0x56, 0xff, 0x06, 0x43, 0x2c, 0xff, 0x0d, 0x39, 0x1d, 0xff, 0x02, 0x22, 0x17, 0xff, 0x02, 0x1c, 0x11, 0xff, 0x65, 0x73, 0x65, 0xff, + 0x1e, 0x34, 0xb7, 0xff, 0x1b, 0x33, 0xb6, 0xff, 0x27, 0x37, 0xb9, 0xff, 0x2e, 0x3e, 0xc3, 0xff, 0x29, 0x42, 0xc6, 0xff, 0x1f, 0x3e, 0xc9, 0xff, 0x26, 0x3d, 0xd1, 0xff, 0x25, 0x46, 0x98, 0xff, 0x03, 0x30, 0x30, 0xff, 0x04, 0x33, 0x1f, 0xff, 0x08, 0x37, 0x1e, 0xff, 0x07, 0x35, 0x2e, 0xff, 0x0c, 0x32, 0x50, 0xff, 0x10, 0x35, 0x5f, 0xff, 0x0c, 0x34, 0x5b, 0xff, 0x1f, 0x48, 0x75, 0xff, 0x3d, 0x6b, 0x9c, 0xff, 0x55, 0x84, 0xb8, 0xff, 0x27, 0x53, 0x89, 0xff, 0x76, 0x9e, 0xd1, 0xff, 0x4b, 0x72, 0xa6, 0xff, 0x60, 0x8d, 0xc2, 0xff, 0x78, 0xa9, 0xda, 0xff, 0x72, 0xa7, 0xd6, 0xff, 0x72, 0xa7, 0xde, 0xff, 0x6e, 0xa6, 0xdc, 0xff, 0x6c, 0xa4, 0xd7, 0xff, 0x6e, 0x9f, 0xdb, 0xff, 0x6b, 0x9d, 0xdd, 0xff, 0x46, 0x89, 0xb1, 0xff, 0x30, 0x82, 0x91, 0xff, 0x22, 0x84, 0x7b, 0xff, 0x1a, 0x91, 0x73, 0xff, 0x17, 0x98, 0x72, 0xff, 0x11, 0x6e, 0x67, 0xff, 0x0d, 0x35, 0x5c, 0xff, 0x1e, 0x55, 0x6e, 0xff, 0x1b, 0x8f, 0x6f, 0xff, 0x10, 0xa0, 0x68, 0xff, 0x0c, 0xa0, 0x69, 0xff, 0x0d, 0xa1, 0x69, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0a, 0xa6, 0x6c, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x73, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x05, 0xa7, 0x69, 0xff, 0x04, 0xa4, 0x65, 0xff, 0x05, 0xa2, 0x65, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x0a, 0xa1, 0x6d, 0xff, 0x13, 0xa3, 0x75, 0xff, 0x2c, 0xa6, 0x7e, 0xff, 0x57, 0xc2, 0x99, 0xff, 0x48, 0xb3, 0x85, 0xff, 0x24, 0xa1, 0x6d, 0xff, 0x10, 0xa1, 0x66, 0xff, 0x0b, 0x9b, 0x61, 0xff, 0x09, 0x90, 0x59, 0xff, 0x05, 0x85, 0x50, 0xff, 0x04, 0x72, 0x41, 0xff, 0x01, 0x69, 0x38, 0xff, 0x00, 0x62, 0x33, 0xff, 0x00, 0x61, 0x32, 0xff, 0x00, 0x62, 0x33, 0xff, 0x01, 0x66, 0x37, 0xff, 0x01, 0x6a, 0x3b, 0xff, 0x01, 0x6c, 0x3b, 0xff, 0x03, 0x6f, 0x3b, 0xff, 0x03, 0x6f, 0x3a, 0xff, 0x05, 0x6f, 0x3b, 0xff, 0x07, 0x6f, 0x3e, 0xff, 0x06, 0x6c, 0x3c, 0xff, 0x04, 0x67, 0x39, 0xff, 0x03, 0x64, 0x38, 0xff, 0x03, 0x63, 0x36, 0xff, 0x02, 0x65, 0x36, 0xff, 0x03, 0x66, 0x37, 0xff, 0x03, 0x66, 0x37, 0xff, 0x03, 0x65, 0x35, 0xff, 0x00, 0x66, 0x34, 0xff, 0x02, 0x69, 0x37, 0xff, 0x00, 0x69, 0x36, 0xff, 0x01, 0x6a, 0x38, 0xff, 0x01, 0x70, 0x3e, 0xff, 0x03, 0x77, 0x44, 0xff, 0x08, 0x86, 0x54, 0xff, 0x0f, 0x93, 0x62, 0xff, 0x14, 0x9e, 0x70, 0xff, 0x19, 0xa5, 0x78, 0xff, 0x1b, 0xa8, 0x7e, 0xff, 0x1a, 0xa8, 0x7e, 0xff, 0x1c, 0xaa, 0x7e, 0xff, 0x1c, 0xa9, 0x7e, 0xff, 0x1d, 0xaa, 0x80, 0xff, 0x1f, 0xa8, 0x81, 0xff, 0x25, 0xa7, 0x84, 0xff, 0x28, 0xa7, 0x84, 0xff, 0x27, 0xa8, 0x86, 0xff, 0x27, 0xaa, 0x87, 0xff, 0x28, 0xaa, 0x8a, 0xff, 0x2a, 0xaa, 0x8b, 0xff, 0x2b, 0xa8, 0x8d, 0xff, 0x2c, 0xa9, 0x8f, 0xff, 0x2f, 0xa9, 0x91, 0xff, 0x30, 0xa9, 0x91, 0xff, 0x32, 0xaa, 0x92, 0xff, 0x33, 0xab, 0x92, 0xff, 0x32, 0xa9, 0x93, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x32, 0xab, 0x94, 0xff, 0x32, 0xac, 0x94, 0xff, 0x32, 0xad, 0x93, 0xff, 0x32, 0xad, 0x93, 0xff, 0x31, 0xac, 0x94, 0xff, 0x30, 0xac, 0x95, 0xff, 0x31, 0xac, 0x98, 0xff, 0x31, 0xac, 0x99, 0xff, 0x35, 0xad, 0x99, 0xff, 0x33, 0xac, 0x97, 0xff, 0x2e, 0xab, 0x96, 0xff, 0x2a, 0xab, 0x93, 0xff, 0x28, 0xac, 0x8f, 0xff, 0x24, 0xaa, 0x85, 0xff, 0x1a, 0xa3, 0x77, 0xff, 0x0f, 0x9b, 0x68, 0xff, 0x0b, 0x8f, 0x5b, 0xff, 0x06, 0x80, 0x4d, 0xff, 0x01, 0x6d, 0x3b, 0xff, 0x00, 0x64, 0x34, 0xff, 0x00, 0x5e, 0x31, 0xff, 0x00, 0x5a, 0x2e, 0xff, 0x02, 0x5b, 0x30, 0xff, 0x05, 0x5c, 0x30, 0xff, 0x04, 0x5a, 0x30, 0xff, 0x05, 0x5b, 0x32, 0xff, 0x02, 0x59, 0x30, 0xff, 0x00, 0x55, 0x2c, 0xff, 0x00, 0x53, 0x2b, 0xff, 0x01, 0x55, 0x2d, 0xff, 0x01, 0x56, 0x2e, 0xff, 0x01, 0x55, 0x2d, 0xff, 0x00, 0x54, 0x2d, 0xff, 0x00, 0x53, 0x2d, 0xff, 0x00, 0x54, 0x2c, 0xff, 0x01, 0x55, 0x2c, 0xff, 0x02, 0x57, 0x2e, 0xff, 0x02, 0x5a, 0x31, 0xff, 0x02, 0x59, 0x2e, 0xff, 0x03, 0x5a, 0x2f, 0xff, 0x07, 0x5e, 0x34, 0xff, 0x05, 0x5e, 0x33, 0xff, 0x01, 0x5f, 0x32, 0xff, 0x00, 0x62, 0x33, 0xff, 0x00, 0x68, 0x36, 0xff, 0x00, 0x6d, 0x3a, 0xff, 0x03, 0x7b, 0x48, 0xff, 0x09, 0x8b, 0x58, 0xff, 0x0d, 0x98, 0x66, 0xff, 0x13, 0xa2, 0x73, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x10, 0xa6, 0x7a, 0xff, 0x15, 0xa7, 0x7b, 0xff, 0x18, 0xa6, 0x7b, 0xff, 0x16, 0xa7, 0x7b, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0f, 0xa7, 0x7a, 0xff, 0x0a, 0xa4, 0x76, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa5, 0x70, 0xff, 0x0b, 0xa5, 0x73, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x10, 0xa7, 0x73, 0xff, 0x0e, 0xa3, 0x72, 0xff, 0x14, 0xab, 0x79, 0xff, 0x14, 0xb0, 0x79, 0xff, 0x18, 0xae, 0x78, 0xff, 0x19, 0xab, 0x76, 0xff, 0x17, 0xab, 0x76, 0xff, 0x15, 0xad, 0x77, 0xff, 0x0b, 0xaa, 0x71, 0xff, 0x0c, 0xae, 0x75, 0xff, 0x06, 0xa8, 0x6f, 0xff, 0x0d, 0xae, 0x73, 0xff, 0x09, 0xa9, 0x6d, 0xff, 0x0f, 0xae, 0x71, 0xff, 0x0f, 0xad, 0x6f, 0xff, 0x04, 0x9d, 0x60, 0xff, 0x10, 0xa9, 0x6c, 0xff, 0x06, 0x9c, 0x61, 0xff, 0x10, 0xa5, 0x69, 0xff, 0x0c, 0xa4, 0x64, 0xff, 0x0d, 0xa0, 0x61, 0xff, 0x0c, 0x9a, 0x5e, 0xff, 0x0d, 0x93, 0x5a, 0xff, 0x10, 0x95, 0x5c, 0xff, 0x0e, 0x95, 0x5b, 0xff, 0x06, 0x90, 0x55, 0xff, 0x02, 0x89, 0x4d, 0xff, 0x05, 0x88, 0x4c, 0xff, 0x04, 0x86, 0x49, 0xff, 0x02, 0x80, 0x46, 0xff, 0x00, 0x79, 0x40, 0xff, 0x00, 0x75, 0x3d, 0xff, 0x00, 0x74, 0x3e, 0xff, 0x00, 0x73, 0x3f, 0xff, 0x00, 0x72, 0x3d, 0xff, 0x00, 0x74, 0x3c, 0xff, 0x01, 0x7a, 0x42, 0xff, 0x00, 0x7b, 0x43, 0xff, 0x01, 0x7c, 0x44, 0xff, 0x01, 0x7e, 0x45, 0xff, 0x01, 0x80, 0x47, 0xff, 0x02, 0x85, 0x4b, 0xff, 0x06, 0x8b, 0x52, 0xff, 0x08, 0x92, 0x58, 0xff, 0x0b, 0x9c, 0x62, 0xff, 0x0c, 0xa1, 0x66, 0xff, 0x0f, 0xa7, 0x6b, 0xff, 0x10, 0xa7, 0x6b, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0d, 0xa1, 0x66, 0xff, 0x0e, 0x9e, 0x63, 0xff, 0x12, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0a, 0x99, 0x63, 0xff, 0x03, 0x88, 0x53, 0xff, 0x02, 0x76, 0x46, 0xff, 0x02, 0x66, 0x3e, 0xff, 0x01, 0x58, 0x33, 0xff, 0x00, 0x56, 0x2f, 0xff, 0x02, 0x63, 0x3a, 0xff, 0x09, 0x79, 0x4a, 0xff, 0x15, 0x95, 0x61, 0xff, 0x16, 0x9d, 0x69, 0xff, 0x12, 0x9c, 0x64, 0xff, 0x13, 0x9f, 0x6c, 0xff, 0x0b, 0x82, 0x73, 0xff, 0x26, 0x9e, 0xc3, 0xff, 0x25, 0xa0, 0xef, 0xff, 0x1a, 0x98, 0xf0, 0xff, 0x2c, 0x97, 0xed, 0xff, 0x11, 0x5a, 0x8e, 0xff, 0x0c, 0x7f, 0x5e, 0xff, 0x08, 0x98, 0x5a, 0xff, 0x02, 0x92, 0x4b, 0xff, 0x08, 0x91, 0x4c, 0xff, 0x0d, 0x90, 0x44, 0xff, 0x10, 0x8d, 0x40, 0xff, 0x0d, 0x7d, 0x3d, 0xff, 0x03, 0x6d, 0x33, 0xff, 0x0d, 0x75, 0x3c, 0xff, 0x0b, 0x72, 0x38, 0xff, 0x05, 0x6c, 0x31, 0xff, 0x01, 0x6c, 0x2f, 0xff, 0x02, 0x74, 0x35, 0xff, 0x06, 0x77, 0x38, 0xff, 0x03, 0x71, 0x32, 0xff, 0x03, 0x6b, 0x30, 0xff, 0x01, 0x66, 0x2d, 0xff, 0x02, 0x66, 0x2d, 0xff, 0x06, 0x64, 0x2d, 0xff, 0x07, 0x62, 0x2d, 0xff, 0x0a, 0x61, 0x2e, 0xff, 0x04, 0x57, 0x27, 0xff, 0x0a, 0x5a, 0x2e, 0xff, 0x17, 0x66, 0x3d, 0xff, 0x06, 0x38, 0x18, 0xff, 0x02, 0x2e, 0x12, 0xff, 0x10, 0x58, 0x38, 0xff, 0x0d, 0x4f, 0x2d, 0xff, 0x04, 0x4e, 0x29, 0xff, 0x0c, 0x5f, 0x38, 0xff, 0x07, 0x4b, 0x2a, 0xff, 0x06, 0x47, 0x22, 0xff, 0x08, 0x57, 0x2e, 0xff, 0x03, 0x57, 0x2e, 0xff, 0x09, 0x53, 0x30, 0xff, 0x0c, 0x57, 0x2f, 0xff, 0x05, 0x50, 0x2b, 0xff, 0x05, 0x44, 0x3a, 0xff, 0x22, 0x60, 0x83, 0xff, 0x48, 0x83, 0xcf, 0xff, 0x3e, 0x70, 0xc7, 0xff, 0x41, 0x7a, 0xb6, 0xff, 0x07, 0x47, 0x3d, 0xff, 0x0e, 0x3e, 0x1b, 0xff, 0x01, 0x25, 0x17, 0xff, 0x02, 0x1e, 0x13, 0xff, 0x62, 0x70, 0x67, 0xff, + 0x37, 0x3e, 0xa3, 0xff, 0x34, 0x43, 0x9e, 0xff, 0x32, 0x42, 0x9e, 0xff, 0x30, 0x3f, 0xae, 0xff, 0x2e, 0x41, 0xbe, 0xff, 0x28, 0x3e, 0xca, 0xff, 0x27, 0x3a, 0xcf, 0xff, 0x28, 0x4d, 0x9e, 0xff, 0x08, 0x44, 0x3f, 0xff, 0x01, 0x38, 0x1d, 0xff, 0x03, 0x3b, 0x1f, 0xff, 0x09, 0x3f, 0x30, 0xff, 0x16, 0x40, 0x53, 0xff, 0x23, 0x47, 0x73, 0xff, 0x11, 0x36, 0x63, 0xff, 0x48, 0x72, 0xa0, 0xff, 0x8b, 0xb9, 0xe9, 0xff, 0x55, 0x84, 0xb7, 0xff, 0x39, 0x66, 0x97, 0xff, 0x89, 0xb3, 0xe2, 0xff, 0x81, 0xad, 0xdc, 0xff, 0x79, 0xab, 0xdc, 0xff, 0x72, 0xa9, 0xd8, 0xff, 0x6d, 0xa8, 0xd8, 0xff, 0x6c, 0xa3, 0xdb, 0xff, 0x6c, 0xa3, 0xd7, 0xff, 0x6e, 0xa5, 0xd6, 0xff, 0x66, 0x9c, 0xd3, 0xff, 0x4a, 0x85, 0xbb, 0xff, 0x28, 0x7c, 0x8e, 0xff, 0x19, 0x82, 0x76, 0xff, 0x16, 0x92, 0x77, 0xff, 0x10, 0x9a, 0x6f, 0xff, 0x11, 0x9b, 0x6e, 0xff, 0x11, 0x72, 0x69, 0xff, 0x23, 0x4c, 0x76, 0xff, 0x40, 0x79, 0x94, 0xff, 0x20, 0x98, 0x7c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x04, 0xa3, 0x64, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa1, 0x69, 0xff, 0x23, 0xb3, 0x80, 0xff, 0x26, 0xb1, 0x81, 0xff, 0x22, 0x9e, 0x6f, 0xff, 0x26, 0x9e, 0x6d, 0xff, 0x25, 0xa1, 0x6d, 0xff, 0x19, 0x9f, 0x66, 0xff, 0x0b, 0x99, 0x5d, 0xff, 0x06, 0x90, 0x56, 0xff, 0x03, 0x7c, 0x46, 0xff, 0x01, 0x6c, 0x3a, 0xff, 0x02, 0x63, 0x36, 0xff, 0x00, 0x5c, 0x2f, 0xff, 0x00, 0x58, 0x2b, 0xff, 0x00, 0x55, 0x28, 0xff, 0x00, 0x56, 0x2a, 0xff, 0x00, 0x56, 0x2b, 0xff, 0x01, 0x5c, 0x2f, 0xff, 0x01, 0x5d, 0x30, 0xff, 0x01, 0x5d, 0x30, 0xff, 0x00, 0x5a, 0x2d, 0xff, 0x00, 0x56, 0x2b, 0xff, 0x01, 0x56, 0x2b, 0xff, 0x01, 0x55, 0x2c, 0xff, 0x01, 0x54, 0x2c, 0xff, 0x01, 0x54, 0x2e, 0xff, 0x01, 0x53, 0x2d, 0xff, 0x00, 0x55, 0x2d, 0xff, 0x01, 0x55, 0x2e, 0xff, 0x01, 0x56, 0x2e, 0xff, 0x01, 0x56, 0x2e, 0xff, 0x01, 0x59, 0x2e, 0xff, 0x02, 0x5c, 0x31, 0xff, 0x00, 0x5c, 0x31, 0xff, 0x00, 0x5d, 0x31, 0xff, 0x00, 0x61, 0x31, 0xff, 0x00, 0x64, 0x34, 0xff, 0x00, 0x6a, 0x3a, 0xff, 0x02, 0x71, 0x41, 0xff, 0x07, 0x84, 0x54, 0xff, 0x0f, 0x94, 0x65, 0xff, 0x17, 0xa3, 0x72, 0xff, 0x1a, 0xa7, 0x78, 0xff, 0x1a, 0xa7, 0x7b, 0xff, 0x1a, 0xa7, 0x7f, 0xff, 0x1c, 0xa9, 0x80, 0xff, 0x20, 0xaa, 0x84, 0xff, 0x27, 0xaa, 0x87, 0xff, 0x2a, 0xa9, 0x89, 0xff, 0x28, 0xa9, 0x89, 0xff, 0x28, 0xa9, 0x8a, 0xff, 0x2a, 0xa9, 0x8a, 0xff, 0x2c, 0xa8, 0x8d, 0xff, 0x2d, 0xa9, 0x8f, 0xff, 0x30, 0xa9, 0x92, 0xff, 0x30, 0xa9, 0x92, 0xff, 0x30, 0xa8, 0x91, 0xff, 0x33, 0xab, 0x94, 0xff, 0x33, 0xab, 0x94, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x33, 0xad, 0x95, 0xff, 0x33, 0xad, 0x95, 0xff, 0x33, 0xae, 0x95, 0xff, 0x33, 0xae, 0x94, 0xff, 0x31, 0xad, 0x94, 0xff, 0x30, 0xac, 0x94, 0xff, 0x31, 0xac, 0x97, 0xff, 0x30, 0xac, 0x97, 0xff, 0x34, 0xab, 0x97, 0xff, 0x31, 0xab, 0x95, 0xff, 0x27, 0xac, 0x91, 0xff, 0x22, 0xad, 0x8d, 0xff, 0x1e, 0xab, 0x85, 0xff, 0x1a, 0xa3, 0x79, 0xff, 0x0d, 0x8e, 0x60, 0xff, 0x07, 0x84, 0x54, 0xff, 0x04, 0x79, 0x48, 0xff, 0x01, 0x6a, 0x3a, 0xff, 0x00, 0x5d, 0x30, 0xff, 0x02, 0x59, 0x2f, 0xff, 0x01, 0x54, 0x2a, 0xff, 0x00, 0x50, 0x27, 0xff, 0x03, 0x51, 0x2a, 0xff, 0x05, 0x51, 0x2a, 0xff, 0x01, 0x4d, 0x28, 0xff, 0x01, 0x4c, 0x29, 0xff, 0x00, 0x4c, 0x28, 0xff, 0x00, 0x4a, 0x27, 0xff, 0x00, 0x4a, 0x26, 0xff, 0x00, 0x4b, 0x28, 0xff, 0x00, 0x4a, 0x27, 0xff, 0x00, 0x4a, 0x26, 0xff, 0x00, 0x48, 0x27, 0xff, 0x00, 0x47, 0x25, 0xff, 0x00, 0x47, 0x24, 0xff, 0x00, 0x46, 0x24, 0xff, 0x00, 0x47, 0x24, 0xff, 0x00, 0x4a, 0x26, 0xff, 0x00, 0x4a, 0x25, 0xff, 0x00, 0x4c, 0x27, 0xff, 0x04, 0x50, 0x2b, 0xff, 0x04, 0x53, 0x2d, 0xff, 0x02, 0x56, 0x2d, 0xff, 0x01, 0x5a, 0x2d, 0xff, 0x01, 0x5d, 0x30, 0xff, 0x00, 0x60, 0x33, 0xff, 0x05, 0x6f, 0x40, 0xff, 0x10, 0x83, 0x53, 0xff, 0x15, 0x93, 0x63, 0xff, 0x0f, 0x96, 0x67, 0xff, 0x0f, 0x9f, 0x70, 0xff, 0x13, 0xa7, 0x78, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x15, 0xa7, 0x7a, 0xff, 0x14, 0xa7, 0x7a, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x16, 0xae, 0x81, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x0c, 0xa6, 0x76, 0xff, 0x0c, 0xa7, 0x75, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x70, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0b, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x15, 0xae, 0x78, 0xff, 0x13, 0xaa, 0x75, 0xff, 0x13, 0xab, 0x76, 0xff, 0x1c, 0xb3, 0x7e, 0xff, 0x1a, 0xad, 0x79, 0xff, 0x27, 0xb7, 0x83, 0xff, 0x1a, 0xad, 0x78, 0xff, 0x16, 0xae, 0x78, 0xff, 0x10, 0xac, 0x75, 0xff, 0x12, 0xae, 0x77, 0xff, 0x0f, 0xac, 0x73, 0xff, 0x12, 0xb0, 0x74, 0xff, 0x09, 0xa7, 0x6a, 0xff, 0x14, 0xb3, 0x75, 0xff, 0x0d, 0xab, 0x6d, 0xff, 0x04, 0x9f, 0x62, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x06, 0x9a, 0x5f, 0xff, 0x0d, 0x9c, 0x62, 0xff, 0x0f, 0x97, 0x5c, 0xff, 0x05, 0x85, 0x4c, 0xff, 0x01, 0x79, 0x42, 0xff, 0x01, 0x71, 0x3c, 0xff, 0x03, 0x72, 0x3f, 0xff, 0x04, 0x78, 0x44, 0xff, 0x06, 0x7d, 0x47, 0xff, 0x06, 0x7e, 0x47, 0xff, 0x06, 0x7c, 0x45, 0xff, 0x08, 0x7d, 0x46, 0xff, 0x08, 0x7a, 0x45, 0xff, 0x08, 0x76, 0x42, 0xff, 0x09, 0x75, 0x43, 0xff, 0x08, 0x72, 0x41, 0xff, 0x05, 0x6d, 0x3d, 0xff, 0x03, 0x6b, 0x3a, 0xff, 0x02, 0x6a, 0x39, 0xff, 0x03, 0x6d, 0x3c, 0xff, 0x02, 0x6d, 0x3c, 0xff, 0x01, 0x6e, 0x3c, 0xff, 0x01, 0x6e, 0x3c, 0xff, 0x00, 0x6d, 0x3b, 0xff, 0x01, 0x71, 0x3f, 0xff, 0x00, 0x74, 0x41, 0xff, 0x01, 0x78, 0x43, 0xff, 0x02, 0x7f, 0x49, 0xff, 0x03, 0x87, 0x50, 0xff, 0x0b, 0x95, 0x5c, 0xff, 0x12, 0x9e, 0x65, 0xff, 0x13, 0xa5, 0x69, 0xff, 0x0e, 0xa7, 0x6a, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x09, 0x9c, 0x67, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0f, 0x97, 0x62, 0xff, 0x0e, 0x8b, 0x55, 0xff, 0x0c, 0x86, 0x51, 0xff, 0x0f, 0x8d, 0x5a, 0xff, 0x13, 0x98, 0x66, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x06, 0xa1, 0x63, 0xff, 0x05, 0x9f, 0x6a, 0xff, 0x0b, 0x87, 0x88, 0xff, 0x2b, 0x9c, 0xd3, 0xff, 0x1f, 0x83, 0xf0, 0xff, 0x1a, 0x7c, 0xf4, 0xff, 0x26, 0x77, 0xf2, 0xff, 0x2a, 0x60, 0xc9, 0xff, 0x08, 0x6d, 0x61, 0xff, 0x0f, 0x97, 0x59, 0xff, 0x0b, 0x91, 0x48, 0xff, 0x08, 0x8a, 0x43, 0xff, 0x09, 0x87, 0x39, 0xff, 0x0e, 0x85, 0x33, 0xff, 0x0c, 0x77, 0x33, 0xff, 0x02, 0x68, 0x2d, 0xff, 0x04, 0x67, 0x2d, 0xff, 0x02, 0x61, 0x27, 0xff, 0x02, 0x63, 0x29, 0xff, 0x05, 0x6f, 0x33, 0xff, 0x06, 0x77, 0x38, 0xff, 0x07, 0x76, 0x38, 0xff, 0x04, 0x71, 0x32, 0xff, 0x03, 0x6b, 0x30, 0xff, 0x02, 0x65, 0x2d, 0xff, 0x04, 0x65, 0x2d, 0xff, 0x06, 0x64, 0x2d, 0xff, 0x08, 0x60, 0x2d, 0xff, 0x0a, 0x5e, 0x2e, 0xff, 0x09, 0x59, 0x2d, 0xff, 0x04, 0x52, 0x29, 0xff, 0x13, 0x63, 0x39, 0xff, 0x06, 0x41, 0x1e, 0xff, 0x02, 0x2d, 0x0e, 0xff, 0x12, 0x54, 0x36, 0xff, 0x0b, 0x4f, 0x2f, 0xff, 0x05, 0x4d, 0x28, 0xff, 0x08, 0x57, 0x30, 0xff, 0x10, 0x5b, 0x36, 0xff, 0x02, 0x46, 0x21, 0xff, 0x0a, 0x57, 0x2d, 0xff, 0x06, 0x58, 0x2c, 0xff, 0x0c, 0x52, 0x31, 0xff, 0x11, 0x58, 0x32, 0xff, 0x06, 0x51, 0x27, 0xff, 0x0e, 0x4a, 0x4f, 0xff, 0x49, 0x7b, 0xcf, 0xff, 0x39, 0x6b, 0xe1, 0xff, 0x47, 0x76, 0xf3, 0xff, 0x4a, 0x7c, 0xe6, 0xff, 0x0a, 0x4a, 0x55, 0xff, 0x07, 0x41, 0x1a, 0xff, 0x05, 0x34, 0x1e, 0xff, 0x02, 0x24, 0x17, 0xff, 0x60, 0x6e, 0x6d, 0xff, + 0x57, 0x55, 0x89, 0xff, 0x50, 0x5a, 0x82, 0xff, 0x49, 0x58, 0x84, 0xff, 0x40, 0x50, 0x92, 0xff, 0x2f, 0x3e, 0x95, 0xff, 0x32, 0x41, 0xba, 0xff, 0x2f, 0x41, 0xc9, 0xff, 0x1f, 0x4d, 0x92, 0xff, 0x17, 0x62, 0x57, 0xff, 0x06, 0x50, 0x2f, 0xff, 0x01, 0x44, 0x23, 0xff, 0x12, 0x51, 0x3b, 0xff, 0x21, 0x50, 0x5a, 0xff, 0x31, 0x55, 0x80, 0xff, 0x1f, 0x45, 0x74, 0xff, 0x5f, 0x8b, 0xb9, 0xff, 0x74, 0xa2, 0xd2, 0xff, 0x55, 0x84, 0xb3, 0xff, 0x62, 0x8f, 0xbd, 0xff, 0x83, 0xb1, 0xdd, 0xff, 0x78, 0xa9, 0xd5, 0xff, 0x72, 0xab, 0xda, 0xff, 0x6e, 0xa7, 0xda, 0xff, 0x6b, 0xa0, 0xd8, 0xff, 0x69, 0xa1, 0xda, 0xff, 0x69, 0xa2, 0xd7, 0xff, 0x62, 0x9b, 0xca, 0xff, 0x4e, 0x90, 0xb4, 0xff, 0x2f, 0x83, 0x93, 0xff, 0x1e, 0x8e, 0x7e, 0xff, 0x14, 0x94, 0x71, 0xff, 0x10, 0x9a, 0x6e, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x11, 0x75, 0x6b, 0xff, 0x3d, 0x68, 0x94, 0xff, 0x57, 0x93, 0xb2, 0xff, 0x20, 0x9d, 0x83, 0xff, 0x08, 0xa1, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x03, 0xa2, 0x64, 0xff, 0x07, 0xa1, 0x65, 0xff, 0x0a, 0x9c, 0x66, 0xff, 0x1e, 0xaa, 0x77, 0xff, 0x14, 0x99, 0x68, 0xff, 0x24, 0xa2, 0x6f, 0xff, 0x1e, 0xa2, 0x6c, 0xff, 0x12, 0x9c, 0x62, 0xff, 0x09, 0x91, 0x55, 0xff, 0x02, 0x84, 0x4a, 0xff, 0x00, 0x7a, 0x42, 0xff, 0x02, 0x6a, 0x38, 0xff, 0x06, 0x60, 0x33, 0xff, 0x04, 0x56, 0x2d, 0xff, 0x01, 0x50, 0x27, 0xff, 0x00, 0x4c, 0x24, 0xff, 0x01, 0x4b, 0x23, 0xff, 0x01, 0x4a, 0x22, 0xff, 0x01, 0x4a, 0x22, 0xff, 0x00, 0x4d, 0x24, 0xff, 0x01, 0x4d, 0x26, 0xff, 0x00, 0x4b, 0x26, 0xff, 0x00, 0x49, 0x24, 0xff, 0x00, 0x47, 0x24, 0xff, 0x00, 0x47, 0x24, 0xff, 0x00, 0x44, 0x22, 0xff, 0x00, 0x45, 0x24, 0xff, 0x00, 0x45, 0x24, 0xff, 0x00, 0x45, 0x24, 0xff, 0x00, 0x45, 0x25, 0xff, 0x00, 0x45, 0x25, 0xff, 0x00, 0x47, 0x25, 0xff, 0x00, 0x47, 0x25, 0xff, 0x00, 0x49, 0x26, 0xff, 0x00, 0x4c, 0x28, 0xff, 0x01, 0x4f, 0x2b, 0xff, 0x02, 0x53, 0x2e, 0xff, 0x04, 0x57, 0x2d, 0xff, 0x04, 0x5b, 0x2f, 0xff, 0x01, 0x5c, 0x2f, 0xff, 0x00, 0x5e, 0x30, 0xff, 0x00, 0x6b, 0x3b, 0xff, 0x04, 0x7d, 0x4c, 0xff, 0x0f, 0x92, 0x60, 0xff, 0x16, 0x9f, 0x6c, 0xff, 0x19, 0xa4, 0x77, 0xff, 0x1b, 0xa7, 0x7e, 0xff, 0x18, 0xa7, 0x7d, 0xff, 0x1c, 0xa8, 0x81, 0xff, 0x27, 0xaa, 0x89, 0xff, 0x2a, 0xab, 0x8b, 0xff, 0x29, 0xa8, 0x8a, 0xff, 0x28, 0xa7, 0x8b, 0xff, 0x2d, 0xa7, 0x8b, 0xff, 0x30, 0xa9, 0x90, 0xff, 0x31, 0xa9, 0x91, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x31, 0xa8, 0x93, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xae, 0x96, 0xff, 0x34, 0xae, 0x96, 0xff, 0x33, 0xad, 0x95, 0xff, 0x32, 0xae, 0x94, 0xff, 0x32, 0xae, 0x95, 0xff, 0x30, 0xad, 0x95, 0xff, 0x30, 0xac, 0x95, 0xff, 0x2e, 0xab, 0x95, 0xff, 0x30, 0xa9, 0x93, 0xff, 0x2e, 0xaa, 0x92, 0xff, 0x22, 0xae, 0x8d, 0xff, 0x19, 0xac, 0x84, 0xff, 0x14, 0xa4, 0x77, 0xff, 0x0c, 0x91, 0x62, 0xff, 0x00, 0x73, 0x44, 0xff, 0x00, 0x6c, 0x3e, 0xff, 0x00, 0x5e, 0x32, 0xff, 0x00, 0x56, 0x2d, 0xff, 0x00, 0x50, 0x28, 0xff, 0x01, 0x4b, 0x25, 0xff, 0x02, 0x47, 0x23, 0xff, 0x01, 0x46, 0x23, 0xff, 0x02, 0x45, 0x21, 0xff, 0x02, 0x43, 0x20, 0xff, 0x01, 0x41, 0x22, 0xff, 0x00, 0x41, 0x23, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x41, 0x22, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x40, 0x22, 0xff, 0x01, 0x40, 0x23, 0xff, 0x01, 0x40, 0x22, 0xff, 0x01, 0x3f, 0x22, 0xff, 0x02, 0x40, 0x22, 0xff, 0x01, 0x40, 0x21, 0xff, 0x00, 0x40, 0x21, 0xff, 0x01, 0x41, 0x22, 0xff, 0x01, 0x41, 0x22, 0xff, 0x01, 0x43, 0x22, 0xff, 0x02, 0x47, 0x24, 0xff, 0x03, 0x4c, 0x27, 0xff, 0x04, 0x50, 0x28, 0xff, 0x05, 0x54, 0x2b, 0xff, 0x03, 0x55, 0x2b, 0xff, 0x01, 0x56, 0x2c, 0xff, 0x06, 0x66, 0x3b, 0xff, 0x13, 0x82, 0x54, 0xff, 0x10, 0x8b, 0x5c, 0xff, 0x09, 0x90, 0x5f, 0xff, 0x0d, 0x9a, 0x6a, 0xff, 0x13, 0xa6, 0x77, 0xff, 0x13, 0xa7, 0x79, 0xff, 0x12, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x0e, 0xa5, 0x79, 0xff, 0x19, 0xaf, 0x85, 0xff, 0x27, 0xbe, 0x94, 0xff, 0x1d, 0xb6, 0x8a, 0xff, 0x0b, 0xa5, 0x76, 0xff, 0x0e, 0xa8, 0x77, 0xff, 0x0b, 0xa6, 0x72, 0xff, 0x09, 0xa5, 0x70, 0xff, 0x09, 0xa4, 0x71, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0a, 0xa4, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0f, 0xa8, 0x70, 0xff, 0x0f, 0xa8, 0x70, 0xff, 0x1a, 0xb3, 0x7c, 0xff, 0x17, 0xb0, 0x79, 0xff, 0x12, 0xab, 0x75, 0xff, 0x1e, 0xb2, 0x7c, 0xff, 0x22, 0xb4, 0x7f, 0xff, 0x27, 0xb8, 0x83, 0xff, 0x1e, 0xb4, 0x7d, 0xff, 0x17, 0xb1, 0x79, 0xff, 0x18, 0xb4, 0x7c, 0xff, 0x18, 0xb1, 0x7a, 0xff, 0x17, 0xb0, 0x76, 0xff, 0x16, 0xb1, 0x75, 0xff, 0x09, 0xa7, 0x69, 0xff, 0x0a, 0xa9, 0x69, 0xff, 0x08, 0xa5, 0x65, 0xff, 0x12, 0xac, 0x6d, 0xff, 0x0f, 0xa3, 0x65, 0xff, 0x0a, 0x98, 0x5d, 0xff, 0x02, 0x85, 0x4e, 0xff, 0x04, 0x79, 0x43, 0xff, 0x01, 0x69, 0x37, 0xff, 0x00, 0x63, 0x33, 0xff, 0x00, 0x5e, 0x30, 0xff, 0x00, 0x5c, 0x2e, 0xff, 0x00, 0x5f, 0x31, 0xff, 0x01, 0x64, 0x34, 0xff, 0x01, 0x65, 0x36, 0xff, 0x01, 0x64, 0x35, 0xff, 0x02, 0x65, 0x34, 0xff, 0x03, 0x65, 0x36, 0xff, 0x06, 0x65, 0x37, 0xff, 0x08, 0x66, 0x38, 0xff, 0x06, 0x63, 0x37, 0xff, 0x05, 0x5f, 0x35, 0xff, 0x06, 0x5f, 0x35, 0xff, 0x06, 0x5f, 0x34, 0xff, 0x04, 0x5e, 0x33, 0xff, 0x04, 0x5e, 0x34, 0xff, 0x05, 0x60, 0x35, 0xff, 0x03, 0x60, 0x34, 0xff, 0x02, 0x61, 0x35, 0xff, 0x03, 0x63, 0x37, 0xff, 0x03, 0x63, 0x37, 0xff, 0x01, 0x66, 0x37, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x00, 0x6e, 0x3c, 0xff, 0x01, 0x77, 0x42, 0xff, 0x03, 0x80, 0x4a, 0xff, 0x05, 0x8d, 0x54, 0xff, 0x07, 0x9a, 0x5e, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x0f, 0xa8, 0x6d, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x08, 0xa6, 0x68, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0f, 0xa2, 0x6b, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x0a, 0xa3, 0x71, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x12, 0xa4, 0x68, 0xff, 0x13, 0xa1, 0x66, 0xff, 0x0f, 0x9f, 0x63, 0xff, 0x0a, 0x9f, 0x64, 0xff, 0x04, 0xa0, 0x66, 0xff, 0x05, 0xa0, 0x66, 0xff, 0x04, 0xa4, 0x63, 0xff, 0x03, 0xa2, 0x6c, 0xff, 0x15, 0x8a, 0xa3, 0xff, 0x29, 0x85, 0xdf, 0xff, 0x23, 0x66, 0xf5, 0xff, 0x23, 0x60, 0xf4, 0xff, 0x2a, 0x5a, 0xf1, 0xff, 0x34, 0x56, 0xde, 0xff, 0x0a, 0x69, 0x62, 0xff, 0x10, 0x90, 0x4f, 0xff, 0x0f, 0x88, 0x43, 0xff, 0x09, 0x81, 0x40, 0xff, 0x02, 0x77, 0x2e, 0xff, 0x04, 0x70, 0x24, 0xff, 0x04, 0x67, 0x2a, 0xff, 0x06, 0x69, 0x30, 0xff, 0x07, 0x64, 0x2b, 0xff, 0x06, 0x61, 0x28, 0xff, 0x0b, 0x6c, 0x30, 0xff, 0x09, 0x70, 0x33, 0xff, 0x08, 0x75, 0x38, 0xff, 0x08, 0x75, 0x37, 0xff, 0x04, 0x70, 0x32, 0xff, 0x03, 0x6a, 0x30, 0xff, 0x04, 0x63, 0x2c, 0xff, 0x06, 0x63, 0x2c, 0xff, 0x06, 0x62, 0x2c, 0xff, 0x07, 0x5f, 0x2c, 0xff, 0x0b, 0x5d, 0x2d, 0xff, 0x0b, 0x5b, 0x2e, 0xff, 0x05, 0x52, 0x2a, 0xff, 0x0e, 0x5f, 0x33, 0xff, 0x05, 0x4b, 0x22, 0xff, 0x01, 0x2d, 0x0c, 0xff, 0x12, 0x4f, 0x32, 0xff, 0x0b, 0x53, 0x33, 0xff, 0x07, 0x4f, 0x2a, 0xff, 0x05, 0x4f, 0x28, 0xff, 0x18, 0x6a, 0x40, 0xff, 0x03, 0x4d, 0x2a, 0xff, 0x0c, 0x57, 0x34, 0xff, 0x0a, 0x58, 0x31, 0xff, 0x0f, 0x51, 0x36, 0xff, 0x14, 0x58, 0x35, 0xff, 0x06, 0x52, 0x23, 0xff, 0x0d, 0x48, 0x54, 0xff, 0x36, 0x62, 0xd0, 0xff, 0x19, 0x4b, 0xcb, 0xff, 0x3b, 0x71, 0xf6, 0xff, 0x41, 0x71, 0xf6, 0xff, 0x15, 0x55, 0x72, 0xff, 0x01, 0x42, 0x21, 0xff, 0x11, 0x49, 0x33, 0xff, 0x05, 0x2a, 0x19, 0xff, 0x62, 0x72, 0x6c, 0xff, + 0x70, 0x71, 0x82, 0xff, 0x76, 0x7e, 0x8b, 0xff, 0x73, 0x80, 0x92, 0xff, 0x79, 0x84, 0x9d, 0xff, 0x4a, 0x55, 0x7f, 0xff, 0x31, 0x3e, 0x9c, 0xff, 0x2e, 0x44, 0xb6, 0xff, 0x13, 0x4d, 0x7d, 0xff, 0x1a, 0x72, 0x5e, 0xff, 0x12, 0x71, 0x4c, 0xff, 0x08, 0x5e, 0x39, 0xff, 0x06, 0x4d, 0x31, 0xff, 0x14, 0x48, 0x4e, 0xff, 0x28, 0x4e, 0x77, 0xff, 0x25, 0x4c, 0x79, 0xff, 0x3a, 0x68, 0x93, 0xff, 0x69, 0x98, 0xc6, 0xff, 0x7e, 0xad, 0xdc, 0xff, 0x7b, 0xac, 0xd9, 0xff, 0x7c, 0xad, 0xd9, 0xff, 0x7a, 0xaf, 0xdc, 0xff, 0x68, 0xa1, 0xd4, 0xff, 0x62, 0x98, 0xd1, 0xff, 0x73, 0xa1, 0xe0, 0xff, 0x6e, 0xa2, 0xdf, 0xff, 0x5d, 0x96, 0xcb, 0xff, 0x4d, 0x90, 0xb4, 0xff, 0x37, 0x92, 0x94, 0xff, 0x21, 0x94, 0x7b, 0xff, 0x13, 0x95, 0x6b, 0xff, 0x18, 0x9b, 0x6e, 0xff, 0x17, 0x9a, 0x69, 0xff, 0x10, 0xa0, 0x67, 0xff, 0x0f, 0x9f, 0x6c, 0xff, 0x11, 0x77, 0x6f, 0xff, 0x4d, 0x7b, 0xa9, 0xff, 0x62, 0xa2, 0xc3, 0xff, 0x1f, 0x9e, 0x84, 0xff, 0x08, 0xa2, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x04, 0xa3, 0x67, 0xff, 0x07, 0xa2, 0x67, 0xff, 0x10, 0xa3, 0x6c, 0xff, 0x0e, 0x97, 0x63, 0xff, 0x11, 0x93, 0x61, 0xff, 0x10, 0x90, 0x5a, 0xff, 0x12, 0x9c, 0x62, 0xff, 0x07, 0x91, 0x56, 0xff, 0x05, 0x84, 0x4a, 0xff, 0x01, 0x74, 0x3e, 0xff, 0x00, 0x67, 0x35, 0xff, 0x01, 0x5b, 0x2c, 0xff, 0x05, 0x53, 0x29, 0xff, 0x03, 0x4b, 0x25, 0xff, 0x02, 0x48, 0x23, 0xff, 0x03, 0x47, 0x22, 0xff, 0x04, 0x45, 0x21, 0xff, 0x02, 0x42, 0x1e, 0xff, 0x02, 0x44, 0x20, 0xff, 0x00, 0x44, 0x20, 0xff, 0x01, 0x43, 0x20, 0xff, 0x03, 0x43, 0x23, 0xff, 0x03, 0x42, 0x22, 0xff, 0x01, 0x40, 0x21, 0xff, 0x01, 0x40, 0x21, 0xff, 0x02, 0x40, 0x23, 0xff, 0x02, 0x41, 0x24, 0xff, 0x01, 0x3f, 0x21, 0xff, 0x01, 0x3f, 0x22, 0xff, 0x00, 0x40, 0x23, 0xff, 0x00, 0x40, 0x23, 0xff, 0x00, 0x40, 0x22, 0xff, 0x00, 0x41, 0x22, 0xff, 0x00, 0x41, 0x22, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x47, 0x26, 0xff, 0x01, 0x49, 0x28, 0xff, 0x06, 0x50, 0x2a, 0xff, 0x07, 0x54, 0x2c, 0xff, 0x04, 0x54, 0x2b, 0xff, 0x01, 0x57, 0x2c, 0xff, 0x00, 0x5c, 0x30, 0xff, 0x01, 0x6a, 0x3a, 0xff, 0x04, 0x7d, 0x4a, 0xff, 0x09, 0x8a, 0x56, 0xff, 0x12, 0x9a, 0x6b, 0xff, 0x1a, 0xa5, 0x79, 0xff, 0x18, 0xa7, 0x7c, 0xff, 0x18, 0xa7, 0x7e, 0xff, 0x21, 0xa8, 0x84, 0xff, 0x28, 0xab, 0x8a, 0xff, 0x2a, 0xa8, 0x8b, 0xff, 0x2a, 0xa8, 0x8d, 0xff, 0x31, 0xa9, 0x8f, 0xff, 0x34, 0xaa, 0x91, 0xff, 0x32, 0xaa, 0x92, 0xff, 0x33, 0xaa, 0x94, 0xff, 0x32, 0xa9, 0x95, 0xff, 0x32, 0xa8, 0x95, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xaa, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xae, 0x96, 0xff, 0x34, 0xae, 0x96, 0xff, 0x33, 0xad, 0x95, 0xff, 0x32, 0xad, 0x95, 0xff, 0x31, 0xad, 0x95, 0xff, 0x2e, 0xac, 0x94, 0xff, 0x2e, 0xac, 0x93, 0xff, 0x2d, 0xab, 0x93, 0xff, 0x2c, 0xaa, 0x91, 0xff, 0x29, 0xac, 0x8f, 0xff, 0x1d, 0xad, 0x87, 0xff, 0x14, 0xa9, 0x7b, 0xff, 0x0d, 0x99, 0x67, 0xff, 0x03, 0x7b, 0x49, 0xff, 0x01, 0x67, 0x39, 0xff, 0x02, 0x60, 0x34, 0xff, 0x00, 0x54, 0x2c, 0xff, 0x00, 0x4f, 0x29, 0xff, 0x01, 0x47, 0x23, 0xff, 0x03, 0x43, 0x20, 0xff, 0x05, 0x42, 0x22, 0xff, 0x03, 0x40, 0x20, 0xff, 0x02, 0x3e, 0x1e, 0xff, 0x04, 0x3e, 0x1f, 0xff, 0x02, 0x3d, 0x20, 0xff, 0x02, 0x3d, 0x20, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x02, 0x3b, 0x1f, 0xff, 0x03, 0x3a, 0x1f, 0xff, 0x03, 0x3b, 0x1f, 0xff, 0x03, 0x3c, 0x20, 0xff, 0x02, 0x3d, 0x20, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x02, 0x3c, 0x20, 0xff, 0x03, 0x3d, 0x21, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x02, 0x41, 0x1f, 0xff, 0x00, 0x42, 0x21, 0xff, 0x01, 0x45, 0x21, 0xff, 0x03, 0x49, 0x24, 0xff, 0x07, 0x4e, 0x29, 0xff, 0x03, 0x4f, 0x29, 0xff, 0x01, 0x51, 0x2c, 0xff, 0x04, 0x63, 0x38, 0xff, 0x0a, 0x79, 0x4a, 0xff, 0x0a, 0x86, 0x56, 0xff, 0x06, 0x8d, 0x5c, 0xff, 0x0c, 0x9d, 0x6c, 0xff, 0x10, 0xa5, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0b, 0xa4, 0x72, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x1b, 0xb0, 0x88, 0xff, 0x27, 0xbd, 0x94, 0xff, 0x1a, 0xb0, 0x84, 0xff, 0x0e, 0xa6, 0x79, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0b, 0xa4, 0x72, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x15, 0xae, 0x76, 0xff, 0x11, 0xac, 0x72, 0xff, 0x13, 0xac, 0x74, 0xff, 0x14, 0xa9, 0x71, 0xff, 0x26, 0xba, 0x84, 0xff, 0x1f, 0xb3, 0x7c, 0xff, 0x1c, 0xb6, 0x7d, 0xff, 0x1b, 0xb8, 0x7e, 0xff, 0x19, 0xb7, 0x7c, 0xff, 0x16, 0xb1, 0x77, 0xff, 0x15, 0xaf, 0x74, 0xff, 0x14, 0xb3, 0x74, 0xff, 0x08, 0xa7, 0x67, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x14, 0xb0, 0x6f, 0xff, 0x16, 0xaa, 0x6c, 0xff, 0x0c, 0x96, 0x5c, 0xff, 0x07, 0x8a, 0x52, 0xff, 0x03, 0x79, 0x44, 0xff, 0x06, 0x6b, 0x3b, 0xff, 0x05, 0x61, 0x34, 0xff, 0x02, 0x5a, 0x2f, 0xff, 0x02, 0x55, 0x2b, 0xff, 0x01, 0x52, 0x29, 0xff, 0x01, 0x52, 0x29, 0xff, 0x00, 0x54, 0x2a, 0xff, 0x01, 0x56, 0x2c, 0xff, 0x03, 0x5a, 0x30, 0xff, 0x01, 0x58, 0x2d, 0xff, 0x01, 0x56, 0x2c, 0xff, 0x01, 0x54, 0x2d, 0xff, 0x01, 0x51, 0x29, 0xff, 0x01, 0x50, 0x29, 0xff, 0x01, 0x50, 0x2a, 0xff, 0x02, 0x50, 0x2b, 0xff, 0x03, 0x51, 0x2b, 0xff, 0x02, 0x50, 0x2a, 0xff, 0x02, 0x50, 0x2b, 0xff, 0x02, 0x52, 0x2c, 0xff, 0x01, 0x51, 0x2b, 0xff, 0x02, 0x55, 0x2e, 0xff, 0x05, 0x57, 0x30, 0xff, 0x06, 0x59, 0x32, 0xff, 0x02, 0x5a, 0x2f, 0xff, 0x01, 0x5e, 0x31, 0xff, 0x02, 0x64, 0x35, 0xff, 0x01, 0x67, 0x37, 0xff, 0x00, 0x6c, 0x3a, 0xff, 0x00, 0x78, 0x42, 0xff, 0x01, 0x85, 0x4c, 0xff, 0x06, 0x9a, 0x5e, 0xff, 0x0f, 0xa3, 0x69, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x07, 0xa7, 0x6a, 0xff, 0x06, 0xa6, 0x69, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x0b, 0xa0, 0x72, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0c, 0xa0, 0x69, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x0d, 0xa0, 0x63, 0xff, 0x0b, 0xa1, 0x61, 0xff, 0x06, 0xa0, 0x64, 0xff, 0x09, 0x9b, 0x69, 0xff, 0x0d, 0xa2, 0x68, 0xff, 0x09, 0x9d, 0x6c, 0xff, 0x20, 0x8a, 0xac, 0xff, 0x2d, 0x6f, 0xe6, 0xff, 0x29, 0x4a, 0xf6, 0xff, 0x2b, 0x45, 0xf2, 0xff, 0x31, 0x40, 0xf3, 0xff, 0x34, 0x49, 0xdd, 0xff, 0x0a, 0x69, 0x60, 0xff, 0x0d, 0x88, 0x43, 0xff, 0x10, 0x82, 0x37, 0xff, 0x05, 0x75, 0x2f, 0xff, 0x03, 0x71, 0x33, 0xff, 0x0d, 0x71, 0x35, 0xff, 0x12, 0x75, 0x39, 0xff, 0x12, 0x76, 0x39, 0xff, 0x15, 0x75, 0x3a, 0xff, 0x14, 0x73, 0x38, 0xff, 0x0d, 0x6c, 0x33, 0xff, 0x04, 0x69, 0x2e, 0xff, 0x09, 0x73, 0x39, 0xff, 0x09, 0x76, 0x39, 0xff, 0x04, 0x71, 0x32, 0xff, 0x05, 0x6b, 0x31, 0xff, 0x04, 0x64, 0x2c, 0xff, 0x05, 0x63, 0x2c, 0xff, 0x06, 0x62, 0x2b, 0xff, 0x07, 0x60, 0x2a, 0xff, 0x0a, 0x5e, 0x2b, 0xff, 0x0b, 0x5d, 0x2c, 0xff, 0x05, 0x55, 0x27, 0xff, 0x0a, 0x5d, 0x2c, 0xff, 0x07, 0x54, 0x27, 0xff, 0x00, 0x30, 0x0e, 0xff, 0x10, 0x48, 0x2c, 0xff, 0x0b, 0x54, 0x35, 0xff, 0x07, 0x4e, 0x2b, 0xff, 0x08, 0x4f, 0x28, 0xff, 0x11, 0x67, 0x3b, 0xff, 0x09, 0x5a, 0x34, 0xff, 0x0a, 0x57, 0x33, 0xff, 0x0b, 0x58, 0x34, 0xff, 0x0d, 0x51, 0x38, 0xff, 0x0f, 0x54, 0x34, 0xff, 0x08, 0x54, 0x27, 0xff, 0x0d, 0x48, 0x5d, 0xff, 0x23, 0x50, 0xc4, 0xff, 0x0b, 0x3e, 0xbb, 0xff, 0x2f, 0x67, 0xf0, 0xff, 0x38, 0x69, 0xf3, 0xff, 0x1e, 0x5d, 0x84, 0xff, 0x03, 0x4a, 0x30, 0xff, 0x16, 0x52, 0x3d, 0xff, 0x04, 0x2b, 0x18, 0xff, 0x62, 0x73, 0x65, 0xff, + 0x82, 0x8a, 0x92, 0xff, 0x7f, 0x8b, 0x94, 0xff, 0x89, 0x92, 0x9d, 0xff, 0x90, 0x90, 0x96, 0xff, 0x8d, 0x8d, 0x9a, 0xff, 0x45, 0x51, 0x91, 0xff, 0x28, 0x4a, 0x96, 0xff, 0x14, 0x5f, 0x6d, 0xff, 0x14, 0x7a, 0x5c, 0xff, 0x12, 0x80, 0x56, 0xff, 0x15, 0x7d, 0x52, 0xff, 0x0b, 0x5e, 0x3e, 0xff, 0x0a, 0x47, 0x4b, 0xff, 0x25, 0x4f, 0x72, 0xff, 0x21, 0x4b, 0x71, 0xff, 0x36, 0x65, 0x8f, 0xff, 0x83, 0xb1, 0xdd, 0xff, 0x83, 0xb2, 0xe1, 0xff, 0x7f, 0xb0, 0xe0, 0xff, 0x79, 0xad, 0xdd, 0xff, 0x63, 0x99, 0xcd, 0xff, 0x5e, 0x95, 0xcf, 0xff, 0x6a, 0x9e, 0xdb, 0xff, 0x6d, 0x9e, 0xda, 0xff, 0x57, 0x8e, 0xc5, 0xff, 0x43, 0x85, 0xa8, 0xff, 0x29, 0x7e, 0x85, 0xff, 0x13, 0x8b, 0x6b, 0xff, 0x0f, 0x9a, 0x66, 0xff, 0x19, 0x99, 0x64, 0xff, 0x16, 0x85, 0x56, 0xff, 0x09, 0x6c, 0x40, 0xff, 0x08, 0x84, 0x4e, 0xff, 0x13, 0x9c, 0x6d, 0xff, 0x0e, 0x73, 0x6f, 0xff, 0x4c, 0x7f, 0xaf, 0xff, 0x64, 0xa5, 0xc8, 0xff, 0x23, 0xa1, 0x87, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x06, 0xa7, 0x6c, 0xff, 0x07, 0xa9, 0x6e, 0xff, 0x0c, 0xa9, 0x6f, 0xff, 0x11, 0xa6, 0x6f, 0xff, 0x0b, 0x95, 0x61, 0xff, 0x07, 0x8b, 0x57, 0xff, 0x08, 0x8a, 0x53, 0xff, 0x06, 0x91, 0x57, 0xff, 0x01, 0x80, 0x49, 0xff, 0x02, 0x6e, 0x3c, 0xff, 0x05, 0x62, 0x34, 0xff, 0x01, 0x59, 0x2e, 0xff, 0x00, 0x4e, 0x27, 0xff, 0x02, 0x46, 0x23, 0xff, 0x01, 0x41, 0x20, 0xff, 0x03, 0x41, 0x21, 0xff, 0x04, 0x40, 0x21, 0xff, 0x02, 0x3d, 0x1e, 0xff, 0x04, 0x3f, 0x1f, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x00, 0x3c, 0x1c, 0xff, 0x02, 0x3c, 0x1d, 0xff, 0x03, 0x3d, 0x20, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x01, 0x3a, 0x1e, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x01, 0x3d, 0x21, 0xff, 0x01, 0x3c, 0x20, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3d, 0x1f, 0xff, 0x02, 0x3e, 0x21, 0xff, 0x01, 0x3f, 0x21, 0xff, 0x00, 0x3f, 0x21, 0xff, 0x00, 0x40, 0x20, 0xff, 0x01, 0x43, 0x22, 0xff, 0x03, 0x47, 0x25, 0xff, 0x05, 0x4b, 0x28, 0xff, 0x04, 0x4e, 0x29, 0xff, 0x01, 0x50, 0x29, 0xff, 0x01, 0x5b, 0x30, 0xff, 0x02, 0x69, 0x3a, 0xff, 0x02, 0x73, 0x41, 0xff, 0x05, 0x85, 0x56, 0xff, 0x10, 0x98, 0x69, 0xff, 0x17, 0xa7, 0x77, 0xff, 0x16, 0xa7, 0x7a, 0xff, 0x1b, 0xa7, 0x7e, 0xff, 0x25, 0xaa, 0x86, 0xff, 0x2a, 0xaa, 0x8b, 0xff, 0x2c, 0xa9, 0x8d, 0xff, 0x33, 0xaa, 0x91, 0xff, 0x35, 0xaa, 0x92, 0xff, 0x33, 0xaa, 0x93, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x32, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xae, 0x96, 0xff, 0x34, 0xae, 0x96, 0xff, 0x33, 0xad, 0x95, 0xff, 0x32, 0xad, 0x95, 0xff, 0x30, 0xad, 0x94, 0xff, 0x2e, 0xad, 0x94, 0xff, 0x2d, 0xac, 0x93, 0xff, 0x2c, 0xad, 0x93, 0xff, 0x27, 0xac, 0x8e, 0xff, 0x20, 0xad, 0x8a, 0xff, 0x15, 0xab, 0x7d, 0xff, 0x12, 0xa4, 0x70, 0xff, 0x08, 0x89, 0x53, 0xff, 0x00, 0x69, 0x36, 0xff, 0x01, 0x58, 0x2c, 0xff, 0x00, 0x4e, 0x26, 0xff, 0x00, 0x49, 0x26, 0xff, 0x01, 0x43, 0x23, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x04, 0x3c, 0x1e, 0xff, 0x04, 0x3c, 0x1e, 0xff, 0x00, 0x38, 0x19, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x03, 0x39, 0x1d, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x03, 0x39, 0x1b, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x01, 0x37, 0x19, 0xff, 0x01, 0x37, 0x19, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x02, 0x36, 0x1b, 0xff, 0x02, 0x37, 0x1c, 0xff, 0x04, 0x39, 0x1e, 0xff, 0x03, 0x39, 0x1e, 0xff, 0x03, 0x3a, 0x1e, 0xff, 0x04, 0x3b, 0x1f, 0xff, 0x04, 0x3d, 0x1f, 0xff, 0x02, 0x3d, 0x1f, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x03, 0x41, 0x20, 0xff, 0x04, 0x43, 0x22, 0xff, 0x03, 0x46, 0x24, 0xff, 0x01, 0x48, 0x24, 0xff, 0x00, 0x4d, 0x26, 0xff, 0x02, 0x5e, 0x30, 0xff, 0x11, 0x80, 0x51, 0xff, 0x0e, 0x8b, 0x5a, 0xff, 0x04, 0x8c, 0x5b, 0xff, 0x0c, 0xa0, 0x6e, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x12, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x15, 0xab, 0x80, 0xff, 0x1d, 0xb2, 0x8b, 0xff, 0x16, 0xab, 0x83, 0xff, 0x0f, 0xa6, 0x7a, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x15, 0xad, 0x7c, 0xff, 0x14, 0xac, 0x7b, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x11, 0xa9, 0x74, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x13, 0xae, 0x74, 0xff, 0x13, 0xb0, 0x74, 0xff, 0x18, 0xb3, 0x77, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x1e, 0xb6, 0x7b, 0xff, 0x1e, 0xb6, 0x7b, 0xff, 0x17, 0xb4, 0x77, 0xff, 0x19, 0xbc, 0x7e, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa6, 0x68, 0xff, 0x0a, 0xae, 0x6d, 0xff, 0x11, 0xb3, 0x72, 0xff, 0x1c, 0xb9, 0x79, 0xff, 0x12, 0xa6, 0x67, 0xff, 0x06, 0x8f, 0x54, 0xff, 0x04, 0x7f, 0x48, 0xff, 0x02, 0x73, 0x3f, 0xff, 0x01, 0x64, 0x35, 0xff, 0x06, 0x5b, 0x31, 0xff, 0x03, 0x53, 0x2b, 0xff, 0x02, 0x4d, 0x26, 0xff, 0x01, 0x49, 0x24, 0xff, 0x03, 0x49, 0x25, 0xff, 0x01, 0x47, 0x24, 0xff, 0x00, 0x48, 0x24, 0xff, 0x00, 0x4b, 0x25, 0xff, 0x01, 0x4a, 0x25, 0xff, 0x00, 0x48, 0x24, 0xff, 0x00, 0x47, 0x23, 0xff, 0x00, 0x46, 0x23, 0xff, 0x00, 0x45, 0x22, 0xff, 0x00, 0x44, 0x22, 0xff, 0x01, 0x43, 0x23, 0xff, 0x00, 0x43, 0x23, 0xff, 0x00, 0x44, 0x23, 0xff, 0x00, 0x44, 0x22, 0xff, 0x00, 0x45, 0x23, 0xff, 0x00, 0x45, 0x23, 0xff, 0x00, 0x45, 0x23, 0xff, 0x01, 0x48, 0x27, 0xff, 0x03, 0x4a, 0x29, 0xff, 0x04, 0x4e, 0x2b, 0xff, 0x05, 0x53, 0x2c, 0xff, 0x04, 0x55, 0x2d, 0xff, 0x05, 0x59, 0x2f, 0xff, 0x02, 0x5b, 0x2e, 0xff, 0x01, 0x5d, 0x2f, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x02, 0x78, 0x44, 0xff, 0x04, 0x88, 0x52, 0xff, 0x07, 0x92, 0x5b, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x0f, 0xa1, 0x6e, 0xff, 0x0a, 0xa2, 0x6f, 0xff, 0x0f, 0xa0, 0x71, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0c, 0x9e, 0x6c, 0xff, 0x0d, 0x9c, 0x6a, 0xff, 0x0d, 0x9e, 0x65, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x0a, 0x96, 0x70, 0xff, 0x0f, 0x8b, 0x7a, 0xff, 0x12, 0x8c, 0x77, 0xff, 0x1a, 0x94, 0x7d, 0xff, 0x23, 0x81, 0x9e, 0xff, 0x2c, 0x57, 0xdd, 0xff, 0x30, 0x32, 0xf7, 0xff, 0x2f, 0x28, 0xf3, 0xff, 0x31, 0x26, 0xf6, 0xff, 0x25, 0x2f, 0xcb, 0xff, 0x0a, 0x64, 0x58, 0xff, 0x0f, 0x84, 0x3c, 0xff, 0x0b, 0x74, 0x2c, 0xff, 0x0e, 0x77, 0x39, 0xff, 0x0a, 0x74, 0x42, 0xff, 0x0d, 0x70, 0x3e, 0xff, 0x0d, 0x73, 0x35, 0xff, 0x0b, 0x71, 0x32, 0xff, 0x0e, 0x6e, 0x31, 0xff, 0x0e, 0x6b, 0x2f, 0xff, 0x0b, 0x67, 0x2f, 0xff, 0x05, 0x66, 0x2e, 0xff, 0x06, 0x6d, 0x34, 0xff, 0x08, 0x72, 0x36, 0xff, 0x04, 0x6f, 0x33, 0xff, 0x06, 0x6b, 0x31, 0xff, 0x05, 0x66, 0x2e, 0xff, 0x05, 0x65, 0x2d, 0xff, 0x04, 0x62, 0x28, 0xff, 0x05, 0x61, 0x28, 0xff, 0x07, 0x61, 0x27, 0xff, 0x09, 0x61, 0x28, 0xff, 0x06, 0x5c, 0x25, 0xff, 0x05, 0x5a, 0x25, 0xff, 0x09, 0x5d, 0x2f, 0xff, 0x01, 0x38, 0x16, 0xff, 0x09, 0x3c, 0x21, 0xff, 0x0e, 0x56, 0x37, 0xff, 0x06, 0x4c, 0x29, 0xff, 0x0c, 0x52, 0x2b, 0xff, 0x07, 0x5b, 0x30, 0xff, 0x10, 0x68, 0x3a, 0xff, 0x07, 0x58, 0x2b, 0xff, 0x09, 0x5a, 0x30, 0xff, 0x0c, 0x55, 0x36, 0xff, 0x0a, 0x52, 0x31, 0xff, 0x07, 0x4f, 0x35, 0xff, 0x16, 0x4f, 0x7e, 0xff, 0x2b, 0x56, 0xd7, 0xff, 0x30, 0x61, 0xe9, 0xff, 0x1c, 0x4d, 0xe3, 0xff, 0x30, 0x5f, 0xe6, 0xff, 0x15, 0x51, 0x75, 0xff, 0x06, 0x51, 0x36, 0xff, 0x13, 0x54, 0x3a, 0xff, 0x03, 0x2b, 0x14, 0xff, 0x64, 0x74, 0x65, 0xff, + 0x65, 0x74, 0x8b, 0xff, 0x67, 0x79, 0x8f, 0xff, 0x7b, 0x84, 0x99, 0xff, 0x97, 0x8c, 0x99, 0xff, 0x9d, 0x97, 0x9f, 0xff, 0x53, 0x67, 0x8a, 0xff, 0x20, 0x55, 0x73, 0xff, 0x16, 0x74, 0x61, 0xff, 0x11, 0x7f, 0x59, 0xff, 0x0a, 0x82, 0x56, 0xff, 0x0e, 0x83, 0x55, 0xff, 0x1b, 0x7f, 0x5d, 0xff, 0x13, 0x5a, 0x5c, 0xff, 0x28, 0x56, 0x74, 0xff, 0x1f, 0x4d, 0x6b, 0xff, 0x36, 0x67, 0x8e, 0xff, 0x80, 0xaf, 0xdc, 0xff, 0x82, 0xb2, 0xe4, 0xff, 0x74, 0xa6, 0xdb, 0xff, 0x5d, 0x93, 0xc9, 0xff, 0x5e, 0x93, 0xcc, 0xff, 0x69, 0x9c, 0xdb, 0xff, 0x69, 0x9b, 0xd7, 0xff, 0x4a, 0x87, 0xb4, 0xff, 0x2d, 0x78, 0x98, 0xff, 0x1f, 0x7a, 0x7b, 0xff, 0x20, 0x89, 0x6f, 0xff, 0x19, 0x98, 0x6a, 0xff, 0x0e, 0x92, 0x5f, 0xff, 0x08, 0x70, 0x43, 0xff, 0x03, 0x54, 0x2c, 0xff, 0x00, 0x45, 0x22, 0xff, 0x03, 0x64, 0x36, 0xff, 0x17, 0x98, 0x6d, 0xff, 0x0f, 0x75, 0x73, 0xff, 0x4a, 0x81, 0xb3, 0xff, 0x61, 0xa4, 0xc6, 0xff, 0x24, 0xa1, 0x86, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x70, 0xff, 0x0f, 0xac, 0x74, 0xff, 0x10, 0xa7, 0x70, 0xff, 0x18, 0xa7, 0x72, 0xff, 0x0e, 0x97, 0x62, 0xff, 0x0a, 0x90, 0x58, 0xff, 0x04, 0x88, 0x51, 0xff, 0x01, 0x70, 0x3e, 0xff, 0x04, 0x5d, 0x30, 0xff, 0x05, 0x4f, 0x28, 0xff, 0x01, 0x4a, 0x26, 0xff, 0x00, 0x44, 0x23, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x02, 0x3d, 0x1f, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x00, 0x36, 0x19, 0xff, 0x01, 0x38, 0x1b, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x03, 0x39, 0x1b, 0xff, 0x03, 0x39, 0x1c, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x02, 0x35, 0x19, 0xff, 0x00, 0x34, 0x18, 0xff, 0x01, 0x34, 0x18, 0xff, 0x01, 0x36, 0x19, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x00, 0x36, 0x1b, 0xff, 0x01, 0x37, 0x1c, 0xff, 0x00, 0x37, 0x1b, 0xff, 0x00, 0x38, 0x1c, 0xff, 0x01, 0x39, 0x1e, 0xff, 0x02, 0x3a, 0x1e, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x00, 0x3f, 0x22, 0xff, 0x01, 0x3f, 0x23, 0xff, 0x04, 0x42, 0x25, 0xff, 0x03, 0x45, 0x26, 0xff, 0x02, 0x49, 0x27, 0xff, 0x01, 0x4d, 0x27, 0xff, 0x05, 0x5f, 0x36, 0xff, 0x08, 0x69, 0x3f, 0xff, 0x01, 0x78, 0x48, 0xff, 0x02, 0x83, 0x52, 0xff, 0x12, 0xa1, 0x6f, 0xff, 0x16, 0xa9, 0x77, 0xff, 0x18, 0xa8, 0x7c, 0xff, 0x1e, 0xa8, 0x80, 0xff, 0x28, 0xab, 0x89, 0xff, 0x2c, 0xab, 0x8d, 0xff, 0x32, 0xaa, 0x91, 0xff, 0x34, 0xaa, 0x92, 0xff, 0x33, 0xaa, 0x94, 0xff, 0x32, 0xa9, 0x95, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xab, 0x96, 0xff, 0x36, 0xad, 0x98, 0xff, 0x36, 0xad, 0x98, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xae, 0x97, 0xff, 0x34, 0xae, 0x96, 0xff, 0x33, 0xad, 0x96, 0xff, 0x32, 0xad, 0x95, 0xff, 0x2f, 0xad, 0x94, 0xff, 0x2d, 0xad, 0x93, 0xff, 0x2b, 0xad, 0x91, 0xff, 0x2b, 0xae, 0x90, 0xff, 0x21, 0xae, 0x8a, 0xff, 0x18, 0xae, 0x82, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x10, 0x9f, 0x67, 0xff, 0x03, 0x79, 0x41, 0xff, 0x01, 0x5e, 0x2c, 0xff, 0x01, 0x4d, 0x23, 0xff, 0x01, 0x47, 0x22, 0xff, 0x01, 0x41, 0x22, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x05, 0x3b, 0x1e, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x01, 0x34, 0x18, 0xff, 0x00, 0x32, 0x17, 0xff, 0x00, 0x32, 0x17, 0xff, 0x01, 0x33, 0x18, 0xff, 0x03, 0x33, 0x18, 0xff, 0x04, 0x34, 0x16, 0xff, 0x03, 0x34, 0x16, 0xff, 0x02, 0x32, 0x15, 0xff, 0x00, 0x30, 0x13, 0xff, 0x01, 0x31, 0x14, 0xff, 0x02, 0x32, 0x15, 0xff, 0x03, 0x33, 0x15, 0xff, 0x03, 0x34, 0x17, 0xff, 0x03, 0x34, 0x18, 0xff, 0x03, 0x34, 0x18, 0xff, 0x04, 0x35, 0x19, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x03, 0x36, 0x19, 0xff, 0x03, 0x37, 0x1a, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x02, 0x3a, 0x1d, 0xff, 0x01, 0x3d, 0x20, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x02, 0x3b, 0x1f, 0xff, 0x04, 0x3e, 0x21, 0xff, 0x02, 0x3f, 0x21, 0xff, 0x00, 0x41, 0x22, 0xff, 0x00, 0x46, 0x22, 0xff, 0x00, 0x4b, 0x23, 0xff, 0x0c, 0x6c, 0x40, 0xff, 0x18, 0x88, 0x5a, 0xff, 0x05, 0x85, 0x55, 0xff, 0x06, 0x97, 0x65, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa7, 0x7a, 0xff, 0x16, 0xad, 0x81, 0xff, 0x23, 0xb9, 0x90, 0xff, 0x10, 0xa5, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x17, 0xaf, 0x80, 0xff, 0x17, 0xaf, 0x7e, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x0e, 0xa7, 0x77, 0xff, 0x0d, 0xa8, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x12, 0xaa, 0x77, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x11, 0xad, 0x71, 0xff, 0x13, 0xb1, 0x75, 0xff, 0x12, 0xb1, 0x73, 0xff, 0x0c, 0xa9, 0x6c, 0xff, 0x12, 0xad, 0x70, 0xff, 0x13, 0xaf, 0x72, 0xff, 0x13, 0xb5, 0x74, 0xff, 0x11, 0xb7, 0x76, 0xff, 0x06, 0xaa, 0x69, 0xff, 0x05, 0xa5, 0x64, 0xff, 0x10, 0xb0, 0x6f, 0xff, 0x08, 0xb1, 0x70, 0xff, 0x12, 0xb5, 0x74, 0xff, 0x13, 0xac, 0x6d, 0xff, 0x01, 0x89, 0x4d, 0xff, 0x00, 0x78, 0x42, 0xff, 0x02, 0x6b, 0x39, 0xff, 0x02, 0x60, 0x32, 0xff, 0x01, 0x54, 0x29, 0xff, 0x03, 0x4e, 0x27, 0xff, 0x00, 0x45, 0x21, 0xff, 0x01, 0x45, 0x23, 0xff, 0x01, 0x43, 0x22, 0xff, 0x02, 0x41, 0x21, 0xff, 0x00, 0x3f, 0x1f, 0xff, 0x00, 0x41, 0x20, 0xff, 0x00, 0x41, 0x1f, 0xff, 0x00, 0x40, 0x20, 0xff, 0x01, 0x41, 0x21, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x3e, 0x1f, 0xff, 0x00, 0x3f, 0x1f, 0xff, 0x00, 0x3f, 0x21, 0xff, 0x01, 0x3e, 0x21, 0xff, 0x00, 0x3e, 0x20, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x00, 0x3f, 0x21, 0xff, 0x00, 0x3f, 0x21, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x00, 0x41, 0x22, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x44, 0x25, 0xff, 0x00, 0x47, 0x24, 0xff, 0x03, 0x4d, 0x27, 0xff, 0x05, 0x50, 0x2a, 0xff, 0x07, 0x52, 0x2b, 0xff, 0x04, 0x52, 0x29, 0xff, 0x02, 0x5b, 0x2f, 0xff, 0x04, 0x69, 0x3a, 0xff, 0x0a, 0x7d, 0x4c, 0xff, 0x02, 0x81, 0x4e, 0xff, 0x05, 0x93, 0x5d, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x0e, 0xa1, 0x6f, 0xff, 0x0a, 0xa1, 0x6f, 0xff, 0x11, 0xa1, 0x6f, 0xff, 0x10, 0xa2, 0x6a, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0b, 0x9e, 0x69, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x0d, 0x9b, 0x69, 0xff, 0x0a, 0x91, 0x74, 0xff, 0x07, 0x80, 0x8b, 0xff, 0x0c, 0x6b, 0x94, 0xff, 0x08, 0x5a, 0x8b, 0xff, 0x0c, 0x5f, 0x82, 0xff, 0x25, 0x73, 0x93, 0xff, 0x2d, 0x4a, 0xd0, 0xff, 0x27, 0x1c, 0xe9, 0xff, 0x2a, 0x12, 0xea, 0xff, 0x28, 0x15, 0xe5, 0xff, 0x0f, 0x1e, 0xa2, 0xff, 0x11, 0x65, 0x56, 0xff, 0x0a, 0x6d, 0x40, 0xff, 0x11, 0x62, 0x54, 0xff, 0x10, 0x5f, 0x5f, 0xff, 0x05, 0x60, 0x54, 0xff, 0x05, 0x66, 0x45, 0xff, 0x0a, 0x72, 0x38, 0xff, 0x09, 0x71, 0x32, 0xff, 0x0b, 0x6d, 0x2f, 0xff, 0x0b, 0x67, 0x2e, 0xff, 0x06, 0x5f, 0x28, 0xff, 0x02, 0x5f, 0x28, 0xff, 0x02, 0x63, 0x2b, 0xff, 0x08, 0x6d, 0x34, 0xff, 0x08, 0x6e, 0x34, 0xff, 0x08, 0x69, 0x32, 0xff, 0x05, 0x65, 0x2e, 0xff, 0x04, 0x64, 0x2b, 0xff, 0x03, 0x62, 0x27, 0xff, 0x04, 0x63, 0x27, 0xff, 0x06, 0x63, 0x26, 0xff, 0x07, 0x62, 0x26, 0xff, 0x07, 0x60, 0x26, 0xff, 0x03, 0x59, 0x22, 0xff, 0x0b, 0x60, 0x32, 0xff, 0x08, 0x48, 0x25, 0xff, 0x03, 0x32, 0x17, 0xff, 0x10, 0x53, 0x36, 0xff, 0x04, 0x4c, 0x29, 0xff, 0x09, 0x50, 0x2a, 0xff, 0x02, 0x54, 0x2b, 0xff, 0x12, 0x6d, 0x3a, 0xff, 0x05, 0x5a, 0x25, 0xff, 0x0b, 0x5d, 0x2e, 0xff, 0x0c, 0x5d, 0x31, 0xff, 0x06, 0x51, 0x2e, 0xff, 0x0b, 0x50, 0x4c, 0xff, 0x22, 0x57, 0xa2, 0xff, 0x27, 0x4e, 0xd8, 0xff, 0x3a, 0x61, 0xf1, 0xff, 0x19, 0x44, 0xd6, 0xff, 0x1c, 0x4b, 0xb7, 0xff, 0x08, 0x44, 0x54, 0xff, 0x08, 0x5a, 0x33, 0xff, 0x11, 0x56, 0x32, 0xff, 0x04, 0x2a, 0x13, 0xff, 0x67, 0x72, 0x6a, 0xff, + 0x67, 0x7e, 0xa2, 0xff, 0x7c, 0x98, 0xb3, 0xff, 0x74, 0x83, 0x9a, 0xff, 0x90, 0x8d, 0xa0, 0xff, 0x84, 0x8a, 0x93, 0xff, 0x46, 0x70, 0x73, 0xff, 0x1e, 0x6c, 0x5e, 0xff, 0x13, 0x7f, 0x57, 0xff, 0x0d, 0x80, 0x56, 0xff, 0x08, 0x83, 0x56, 0xff, 0x09, 0x87, 0x56, 0xff, 0x19, 0x8b, 0x63, 0xff, 0x16, 0x6a, 0x66, 0xff, 0x24, 0x58, 0x71, 0xff, 0x25, 0x53, 0x6e, 0xff, 0x2c, 0x5b, 0x81, 0xff, 0x7d, 0xab, 0xd9, 0xff, 0x66, 0x96, 0xcc, 0xff, 0x57, 0x8b, 0xc2, 0xff, 0x5e, 0x95, 0xce, 0xff, 0x62, 0x96, 0xd1, 0xff, 0x5d, 0x8a, 0xc7, 0xff, 0x44, 0x6e, 0xa8, 0xff, 0x22, 0x63, 0x80, 0xff, 0x1b, 0x85, 0x7f, 0xff, 0x14, 0x8f, 0x6a, 0xff, 0x22, 0x92, 0x69, 0xff, 0x16, 0x7a, 0x54, 0xff, 0x05, 0x5e, 0x3b, 0xff, 0x01, 0x47, 0x27, 0xff, 0x02, 0x3f, 0x23, 0xff, 0x02, 0x42, 0x24, 0xff, 0x09, 0x66, 0x3d, 0xff, 0x1c, 0x99, 0x72, 0xff, 0x0f, 0x74, 0x73, 0xff, 0x4b, 0x85, 0xb5, 0xff, 0x5f, 0xa4, 0xc5, 0xff, 0x24, 0xa1, 0x85, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x09, 0xa6, 0x6b, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x16, 0xaa, 0x74, 0xff, 0x11, 0xa2, 0x6b, 0xff, 0x0d, 0x99, 0x62, 0xff, 0x02, 0x7f, 0x4b, 0xff, 0x06, 0x67, 0x39, 0xff, 0x03, 0x4e, 0x26, 0xff, 0x05, 0x44, 0x22, 0xff, 0x01, 0x40, 0x21, 0xff, 0x02, 0x3e, 0x22, 0xff, 0x01, 0x3a, 0x1e, 0xff, 0x01, 0x34, 0x18, 0xff, 0x01, 0x34, 0x18, 0xff, 0x01, 0x33, 0x17, 0xff, 0x01, 0x32, 0x16, 0xff, 0x01, 0x32, 0x17, 0xff, 0x00, 0x32, 0x16, 0xff, 0x02, 0x33, 0x17, 0xff, 0x02, 0x33, 0x17, 0xff, 0x02, 0x31, 0x16, 0xff, 0x01, 0x30, 0x14, 0xff, 0x01, 0x30, 0x14, 0xff, 0x01, 0x30, 0x15, 0xff, 0x02, 0x31, 0x16, 0xff, 0x02, 0x33, 0x17, 0xff, 0x02, 0x33, 0x17, 0xff, 0x03, 0x34, 0x18, 0xff, 0x03, 0x34, 0x19, 0xff, 0x01, 0x35, 0x19, 0xff, 0x02, 0x35, 0x19, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x03, 0x37, 0x1a, 0xff, 0x04, 0x39, 0x1b, 0xff, 0x03, 0x3b, 0x1c, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x01, 0x3c, 0x21, 0xff, 0x02, 0x3c, 0x22, 0xff, 0x03, 0x3c, 0x22, 0xff, 0x03, 0x3d, 0x21, 0xff, 0x02, 0x41, 0x22, 0xff, 0x01, 0x43, 0x23, 0xff, 0x02, 0x4b, 0x28, 0xff, 0x0e, 0x61, 0x3c, 0xff, 0x10, 0x7e, 0x51, 0xff, 0x03, 0x7c, 0x4a, 0xff, 0x09, 0x93, 0x60, 0xff, 0x14, 0xa6, 0x73, 0xff, 0x17, 0xa8, 0x7a, 0xff, 0x1b, 0xa7, 0x7e, 0xff, 0x24, 0xa9, 0x85, 0xff, 0x28, 0xa9, 0x8a, 0xff, 0x2f, 0xa9, 0x8f, 0xff, 0x31, 0xa9, 0x90, 0xff, 0x32, 0xaa, 0x92, 0xff, 0x32, 0xa9, 0x94, 0xff, 0x33, 0xaa, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xa9, 0x96, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x36, 0xad, 0x98, 0xff, 0x36, 0xad, 0x98, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xae, 0x96, 0xff, 0x34, 0xad, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x32, 0xad, 0x96, 0xff, 0x2f, 0xad, 0x95, 0xff, 0x2c, 0xad, 0x92, 0xff, 0x2b, 0xad, 0x8f, 0xff, 0x2a, 0xad, 0x8e, 0xff, 0x1c, 0xaf, 0x84, 0xff, 0x12, 0xae, 0x7c, 0xff, 0x0d, 0xab, 0x73, 0xff, 0x0d, 0x9f, 0x64, 0xff, 0x01, 0x72, 0x3a, 0xff, 0x03, 0x5a, 0x2a, 0xff, 0x04, 0x48, 0x21, 0xff, 0x04, 0x42, 0x20, 0xff, 0x04, 0x3e, 0x20, 0xff, 0x06, 0x3b, 0x1f, 0xff, 0x03, 0x31, 0x16, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x00, 0x2e, 0x16, 0xff, 0x00, 0x2c, 0x14, 0xff, 0x02, 0x2b, 0x11, 0xff, 0x02, 0x2c, 0x10, 0xff, 0x02, 0x2b, 0x10, 0xff, 0x01, 0x2b, 0x0f, 0xff, 0x01, 0x2b, 0x0f, 0xff, 0x01, 0x2a, 0x0f, 0xff, 0x02, 0x2c, 0x10, 0xff, 0x03, 0x2d, 0x11, 0xff, 0x04, 0x2f, 0x12, 0xff, 0x02, 0x30, 0x13, 0xff, 0x02, 0x30, 0x13, 0xff, 0x03, 0x30, 0x13, 0xff, 0x03, 0x30, 0x14, 0xff, 0x01, 0x30, 0x14, 0xff, 0x01, 0x2f, 0x14, 0xff, 0x02, 0x31, 0x15, 0xff, 0x03, 0x32, 0x17, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x02, 0x37, 0x1c, 0xff, 0x01, 0x37, 0x1c, 0xff, 0x02, 0x37, 0x1c, 0xff, 0x03, 0x38, 0x1e, 0xff, 0x02, 0x3a, 0x1d, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x40, 0x20, 0xff, 0x01, 0x43, 0x21, 0xff, 0x02, 0x50, 0x2a, 0xff, 0x0c, 0x6f, 0x45, 0xff, 0x07, 0x81, 0x54, 0xff, 0x07, 0x93, 0x62, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x10, 0xa5, 0x75, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x16, 0xac, 0x81, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x0e, 0xaa, 0x70, 0xff, 0x10, 0xaf, 0x72, 0xff, 0x11, 0xb2, 0x74, 0xff, 0x0c, 0xac, 0x6e, 0xff, 0x0c, 0xa9, 0x6c, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x11, 0xb1, 0x72, 0xff, 0x0c, 0xaf, 0x70, 0xff, 0x0c, 0xb0, 0x70, 0xff, 0x0d, 0xb0, 0x6f, 0xff, 0x11, 0xb5, 0x76, 0xff, 0x08, 0xb4, 0x74, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x07, 0x96, 0x5b, 0xff, 0x00, 0x77, 0x42, 0xff, 0x00, 0x65, 0x35, 0xff, 0x04, 0x5b, 0x2f, 0xff, 0x05, 0x52, 0x29, 0xff, 0x01, 0x48, 0x23, 0xff, 0x00, 0x43, 0x1f, 0xff, 0x00, 0x3f, 0x1f, 0xff, 0x02, 0x3f, 0x21, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x00, 0x3c, 0x1d, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x03, 0x3d, 0x1f, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x00, 0x3b, 0x1d, 0xff, 0x00, 0x3c, 0x1e, 0xff, 0x00, 0x3c, 0x1e, 0xff, 0x00, 0x3c, 0x1e, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x00, 0x3f, 0x21, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x42, 0x21, 0xff, 0x02, 0x45, 0x22, 0xff, 0x06, 0x49, 0x26, 0xff, 0x07, 0x4b, 0x27, 0xff, 0x03, 0x4d, 0x27, 0xff, 0x03, 0x57, 0x2e, 0xff, 0x11, 0x71, 0x47, 0xff, 0x04, 0x76, 0x47, 0xff, 0x02, 0x82, 0x50, 0xff, 0x08, 0x92, 0x5e, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0d, 0xa1, 0x6f, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x0e, 0xa1, 0x6e, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0a, 0xa5, 0x65, 0xff, 0x08, 0xa1, 0x66, 0xff, 0x0a, 0xa1, 0x65, 0xff, 0x0a, 0x9a, 0x6d, 0xff, 0x15, 0x98, 0x95, 0xff, 0x27, 0x90, 0xd5, 0xff, 0x28, 0x70, 0xd9, 0xff, 0x24, 0x52, 0xd2, 0xff, 0x12, 0x37, 0xad, 0xff, 0x11, 0x4a, 0x8a, 0xff, 0x27, 0x40, 0xbf, 0xff, 0x1e, 0x19, 0xcf, 0xff, 0x21, 0x13, 0xd0, 0xff, 0x18, 0x1b, 0xb2, 0xff, 0x08, 0x2f, 0x6c, 0xff, 0x14, 0x5b, 0x57, 0xff, 0x0a, 0x48, 0x6b, 0xff, 0x1c, 0x41, 0xa7, 0xff, 0x1e, 0x42, 0xb2, 0xff, 0x1e, 0x5d, 0x9f, 0xff, 0x0d, 0x62, 0x75, 0xff, 0x05, 0x6a, 0x42, 0xff, 0x08, 0x6f, 0x33, 0xff, 0x08, 0x68, 0x2c, 0xff, 0x0b, 0x64, 0x2b, 0xff, 0x0a, 0x5e, 0x29, 0xff, 0x05, 0x5a, 0x26, 0xff, 0x01, 0x58, 0x24, 0xff, 0x05, 0x61, 0x2c, 0xff, 0x0d, 0x6b, 0x34, 0xff, 0x0b, 0x68, 0x32, 0xff, 0x08, 0x65, 0x2f, 0xff, 0x06, 0x64, 0x2d, 0xff, 0x03, 0x61, 0x28, 0xff, 0x05, 0x60, 0x29, 0xff, 0x06, 0x61, 0x29, 0xff, 0x07, 0x5f, 0x29, 0xff, 0x0a, 0x60, 0x2c, 0xff, 0x0b, 0x5d, 0x2b, 0xff, 0x09, 0x5b, 0x2e, 0xff, 0x10, 0x54, 0x2f, 0xff, 0x01, 0x2d, 0x11, 0xff, 0x0d, 0x49, 0x2c, 0xff, 0x08, 0x51, 0x2e, 0xff, 0x04, 0x4e, 0x29, 0xff, 0x05, 0x51, 0x2b, 0xff, 0x0e, 0x65, 0x39, 0xff, 0x07, 0x59, 0x2e, 0xff, 0x0c, 0x5d, 0x32, 0xff, 0x0b, 0x60, 0x2f, 0xff, 0x02, 0x50, 0x29, 0xff, 0x17, 0x5a, 0x5e, 0xff, 0x36, 0x6a, 0xb3, 0xff, 0x22, 0x4a, 0xbf, 0xff, 0x21, 0x47, 0xb9, 0xff, 0x21, 0x52, 0xb0, 0xff, 0x18, 0x4e, 0x81, 0xff, 0x02, 0x3e, 0x31, 0xff, 0x07, 0x5d, 0x2b, 0xff, 0x0e, 0x57, 0x2f, 0xff, 0x05, 0x29, 0x13, 0xff, 0x65, 0x71, 0x6c, 0xff, + 0x67, 0x84, 0xac, 0xff, 0x86, 0xaa, 0xc6, 0xff, 0x7a, 0x93, 0xa6, 0xff, 0x6c, 0x7a, 0x89, 0xff, 0x5f, 0x7f, 0x7c, 0xff, 0x33, 0x77, 0x61, 0xff, 0x1b, 0x7c, 0x56, 0xff, 0x0e, 0x81, 0x53, 0xff, 0x0d, 0x80, 0x55, 0xff, 0x0b, 0x85, 0x58, 0xff, 0x0a, 0x8c, 0x5b, 0xff, 0x15, 0x92, 0x64, 0xff, 0x14, 0x75, 0x68, 0xff, 0x21, 0x59, 0x70, 0xff, 0x29, 0x56, 0x72, 0xff, 0x26, 0x53, 0x7b, 0xff, 0x5c, 0x88, 0xb9, 0xff, 0x4e, 0x7e, 0xb7, 0xff, 0x5a, 0x8f, 0xca, 0xff, 0x5a, 0x92, 0xca, 0xff, 0x5b, 0x8e, 0xc5, 0xff, 0x43, 0x6b, 0xa2, 0xff, 0x19, 0x3a, 0x6e, 0xff, 0x0b, 0x49, 0x5b, 0xff, 0x16, 0x90, 0x70, 0xff, 0x13, 0x9c, 0x64, 0xff, 0x1d, 0x87, 0x5d, 0xff, 0x08, 0x51, 0x37, 0xff, 0x01, 0x3f, 0x23, 0xff, 0x03, 0x3f, 0x27, 0xff, 0x04, 0x3e, 0x28, 0xff, 0x02, 0x48, 0x29, 0xff, 0x13, 0x7b, 0x50, 0xff, 0x1a, 0x9c, 0x72, 0xff, 0x0c, 0x73, 0x70, 0xff, 0x4c, 0x86, 0xb5, 0xff, 0x61, 0xa6, 0xc7, 0xff, 0x24, 0x9f, 0x85, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0d, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6c, 0xff, 0x0c, 0xa6, 0x6a, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x10, 0xa5, 0x6e, 0xff, 0x0c, 0x9e, 0x65, 0xff, 0x02, 0x7a, 0x46, 0xff, 0x09, 0x63, 0x36, 0xff, 0x03, 0x4b, 0x25, 0xff, 0x02, 0x3f, 0x1d, 0xff, 0x03, 0x3c, 0x1f, 0xff, 0x07, 0x3c, 0x21, 0xff, 0x02, 0x34, 0x19, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x04, 0x2f, 0x16, 0xff, 0x04, 0x30, 0x16, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x02, 0x2d, 0x13, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x02, 0x2b, 0x11, 0xff, 0x01, 0x2a, 0x10, 0xff, 0x01, 0x2a, 0x10, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x03, 0x2b, 0x11, 0xff, 0x04, 0x2d, 0x13, 0xff, 0x05, 0x2d, 0x14, 0xff, 0x05, 0x2e, 0x14, 0xff, 0x06, 0x31, 0x18, 0xff, 0x04, 0x2f, 0x16, 0xff, 0x03, 0x2e, 0x14, 0xff, 0x04, 0x30, 0x16, 0xff, 0x05, 0x32, 0x17, 0xff, 0x06, 0x35, 0x18, 0xff, 0x04, 0x36, 0x19, 0xff, 0x05, 0x38, 0x1b, 0xff, 0x03, 0x37, 0x1c, 0xff, 0x03, 0x38, 0x1d, 0xff, 0x03, 0x37, 0x1d, 0xff, 0x04, 0x39, 0x1e, 0xff, 0x03, 0x3c, 0x1f, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x41, 0x22, 0xff, 0x09, 0x50, 0x2f, 0xff, 0x18, 0x7d, 0x53, 0xff, 0x0f, 0x83, 0x56, 0xff, 0x08, 0x8e, 0x5d, 0xff, 0x12, 0xa3, 0x71, 0xff, 0x16, 0xa8, 0x79, 0xff, 0x1a, 0xa8, 0x7d, 0xff, 0x22, 0xa8, 0x84, 0xff, 0x26, 0xa7, 0x88, 0xff, 0x2b, 0xa9, 0x8d, 0xff, 0x2e, 0xaa, 0x8f, 0xff, 0x2f, 0xaa, 0x92, 0xff, 0x30, 0xa9, 0x94, 0xff, 0x31, 0xa9, 0x95, 0xff, 0x33, 0xaa, 0x96, 0xff, 0x33, 0xaa, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xab, 0x96, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x36, 0xad, 0x98, 0xff, 0x36, 0xad, 0x98, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x34, 0xad, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x32, 0xad, 0x97, 0xff, 0x2f, 0xae, 0x95, 0xff, 0x2c, 0xac, 0x92, 0xff, 0x2a, 0xad, 0x8f, 0xff, 0x29, 0xad, 0x8d, 0xff, 0x19, 0xad, 0x7e, 0xff, 0x10, 0xaf, 0x79, 0xff, 0x0a, 0xae, 0x73, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x01, 0x74, 0x3d, 0xff, 0x02, 0x56, 0x29, 0xff, 0x06, 0x44, 0x21, 0xff, 0x06, 0x3c, 0x1d, 0xff, 0x07, 0x39, 0x1e, 0xff, 0x07, 0x34, 0x1a, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x03, 0x28, 0x0f, 0xff, 0x02, 0x29, 0x10, 0xff, 0x01, 0x29, 0x10, 0xff, 0x00, 0x27, 0x11, 0xff, 0x00, 0x25, 0x0f, 0xff, 0x02, 0x25, 0x0d, 0xff, 0x02, 0x26, 0x0c, 0xff, 0x02, 0x25, 0x0b, 0xff, 0x02, 0x25, 0x0c, 0xff, 0x01, 0x25, 0x0b, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x01, 0x24, 0x0b, 0xff, 0x01, 0x25, 0x0b, 0xff, 0x01, 0x26, 0x0c, 0xff, 0x01, 0x28, 0x0d, 0xff, 0x01, 0x27, 0x0d, 0xff, 0x01, 0x27, 0x0d, 0xff, 0x01, 0x26, 0x0c, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x00, 0x27, 0x0e, 0xff, 0x00, 0x29, 0x0f, 0xff, 0x03, 0x2b, 0x11, 0xff, 0x03, 0x2d, 0x14, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x00, 0x2f, 0x17, 0xff, 0x02, 0x32, 0x1a, 0xff, 0x04, 0x34, 0x1a, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x03, 0x3b, 0x1d, 0xff, 0x03, 0x3d, 0x1f, 0xff, 0x01, 0x44, 0x23, 0xff, 0x03, 0x5a, 0x33, 0xff, 0x0a, 0x7d, 0x52, 0xff, 0x09, 0x90, 0x61, 0xff, 0x11, 0xa4, 0x74, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x12, 0xa9, 0x79, 0xff, 0x14, 0xac, 0x7b, 0xff, 0x14, 0xac, 0x7c, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x11, 0xa9, 0x75, 0xff, 0x10, 0xaa, 0x73, 0xff, 0x11, 0xb0, 0x75, 0xff, 0x0f, 0xb1, 0x74, 0xff, 0x0c, 0xac, 0x70, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0f, 0xa9, 0x6e, 0xff, 0x0f, 0xab, 0x6f, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0b, 0xac, 0x6f, 0xff, 0x0f, 0xb0, 0x73, 0xff, 0x0d, 0xb1, 0x74, 0xff, 0x09, 0xb2, 0x75, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x02, 0x86, 0x50, 0xff, 0x01, 0x6d, 0x3c, 0xff, 0x00, 0x55, 0x2a, 0xff, 0x01, 0x4b, 0x24, 0xff, 0x03, 0x46, 0x23, 0xff, 0x01, 0x41, 0x21, 0xff, 0x01, 0x3d, 0x1d, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x03, 0x3a, 0x1d, 0xff, 0x00, 0x33, 0x18, 0xff, 0x01, 0x33, 0x18, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x01, 0x35, 0x19, 0xff, 0x01, 0x34, 0x18, 0xff, 0x02, 0x35, 0x19, 0xff, 0x02, 0x35, 0x19, 0xff, 0x02, 0x35, 0x19, 0xff, 0x01, 0x35, 0x19, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x00, 0x37, 0x19, 0xff, 0x00, 0x38, 0x1a, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x40, 0x21, 0xff, 0x03, 0x41, 0x22, 0xff, 0x04, 0x43, 0x24, 0xff, 0x03, 0x45, 0x24, 0xff, 0x02, 0x4a, 0x27, 0xff, 0x10, 0x66, 0x41, 0xff, 0x07, 0x6f, 0x45, 0xff, 0x01, 0x72, 0x45, 0xff, 0x05, 0x80, 0x50, 0xff, 0x16, 0x9f, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0e, 0xa1, 0x6f, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x07, 0xa4, 0x65, 0xff, 0x06, 0xa1, 0x66, 0xff, 0x08, 0xa1, 0x63, 0xff, 0x0c, 0x9f, 0x72, 0xff, 0x21, 0xa3, 0xaf, 0xff, 0x24, 0x86, 0xed, 0xff, 0x2a, 0x61, 0xf1, 0xff, 0x2a, 0x3f, 0xf0, 0xff, 0x29, 0x2e, 0xde, 0xff, 0x0b, 0x2d, 0x91, 0xff, 0x1c, 0x31, 0xa6, 0xff, 0x0e, 0x14, 0xa4, 0xff, 0x1a, 0x1a, 0xac, 0xff, 0x0a, 0x20, 0x7e, 0xff, 0x15, 0x49, 0x62, 0xff, 0x18, 0x47, 0x6e, 0xff, 0x17, 0x34, 0xa2, 0xff, 0x1a, 0x26, 0xce, 0xff, 0x2b, 0x34, 0xdd, 0xff, 0x32, 0x5a, 0xdb, 0xff, 0x27, 0x6e, 0xc1, 0xff, 0x13, 0x6e, 0x6e, 0xff, 0x03, 0x64, 0x34, 0xff, 0x08, 0x66, 0x2a, 0xff, 0x0b, 0x60, 0x29, 0xff, 0x0d, 0x5b, 0x28, 0xff, 0x0b, 0x58, 0x28, 0xff, 0x04, 0x54, 0x24, 0xff, 0x03, 0x56, 0x24, 0xff, 0x0c, 0x61, 0x2d, 0xff, 0x0c, 0x65, 0x31, 0xff, 0x09, 0x63, 0x2e, 0xff, 0x08, 0x63, 0x2e, 0xff, 0x05, 0x5f, 0x2c, 0xff, 0x07, 0x5e, 0x2e, 0xff, 0x09, 0x5d, 0x30, 0xff, 0x07, 0x5a, 0x30, 0xff, 0x0b, 0x5b, 0x33, 0xff, 0x0f, 0x5a, 0x30, 0xff, 0x07, 0x54, 0x2a, 0xff, 0x0e, 0x55, 0x31, 0xff, 0x03, 0x31, 0x14, 0xff, 0x09, 0x3e, 0x1f, 0xff, 0x0c, 0x56, 0x32, 0xff, 0x03, 0x4e, 0x2a, 0xff, 0x09, 0x4d, 0x2c, 0xff, 0x0c, 0x5a, 0x37, 0xff, 0x0b, 0x5a, 0x38, 0xff, 0x0a, 0x58, 0x32, 0xff, 0x0a, 0x60, 0x31, 0xff, 0x02, 0x52, 0x27, 0xff, 0x0d, 0x52, 0x4c, 0xff, 0x1f, 0x5a, 0x84, 0xff, 0x1a, 0x4b, 0x90, 0xff, 0x0d, 0x3a, 0x77, 0xff, 0x18, 0x55, 0x74, 0xff, 0x1a, 0x59, 0x5a, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x08, 0x5e, 0x2a, 0xff, 0x0d, 0x57, 0x30, 0xff, 0x05, 0x27, 0x14, 0xff, 0x61, 0x70, 0x6b, 0xff, + 0x5d, 0x7e, 0xa4, 0xff, 0x7b, 0xa3, 0xc1, 0xff, 0x8b, 0xb1, 0xc3, 0xff, 0x41, 0x71, 0x6f, 0xff, 0x2c, 0x76, 0x5c, 0xff, 0x1c, 0x7d, 0x57, 0xff, 0x10, 0x80, 0x55, 0xff, 0x0a, 0x80, 0x54, 0xff, 0x11, 0x85, 0x58, 0xff, 0x13, 0x8c, 0x5e, 0xff, 0x0e, 0x93, 0x62, 0xff, 0x0f, 0x98, 0x60, 0xff, 0x12, 0x81, 0x66, 0xff, 0x1e, 0x59, 0x71, 0xff, 0x29, 0x55, 0x77, 0xff, 0x13, 0x3d, 0x68, 0xff, 0x38, 0x63, 0x97, 0xff, 0x64, 0x93, 0xd0, 0xff, 0x50, 0x87, 0xc3, 0xff, 0x4a, 0x84, 0xb9, 0xff, 0x3d, 0x70, 0xa0, 0xff, 0x0a, 0x2d, 0x59, 0xff, 0x02, 0x1e, 0x47, 0xff, 0x0c, 0x48, 0x53, 0xff, 0x23, 0x91, 0x70, 0xff, 0x0e, 0x84, 0x4f, 0xff, 0x06, 0x59, 0x33, 0xff, 0x02, 0x3e, 0x27, 0xff, 0x02, 0x3e, 0x25, 0xff, 0x06, 0x3f, 0x26, 0xff, 0x05, 0x3e, 0x26, 0xff, 0x07, 0x5f, 0x3a, 0xff, 0x1e, 0x98, 0x65, 0xff, 0x15, 0xa0, 0x70, 0xff, 0x0c, 0x78, 0x70, 0xff, 0x4e, 0x87, 0xb2, 0xff, 0x62, 0xa7, 0xc8, 0xff, 0x22, 0x9e, 0x86, 0xff, 0x0e, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x10, 0xa6, 0x6e, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x07, 0x80, 0x4c, 0xff, 0x03, 0x59, 0x2d, 0xff, 0x02, 0x49, 0x21, 0xff, 0x00, 0x3e, 0x1c, 0xff, 0x05, 0x39, 0x1c, 0xff, 0x05, 0x2f, 0x15, 0xff, 0x02, 0x27, 0x0d, 0xff, 0x04, 0x28, 0x0f, 0xff, 0x04, 0x27, 0x0f, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x00, 0x23, 0x0b, 0xff, 0x00, 0x22, 0x0a, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x01, 0x22, 0x0b, 0xff, 0x02, 0x22, 0x0c, 0xff, 0x02, 0x22, 0x0d, 0xff, 0x01, 0x21, 0x0c, 0xff, 0x01, 0x21, 0x0b, 0xff, 0x03, 0x21, 0x0b, 0xff, 0x04, 0x24, 0x0d, 0xff, 0x05, 0x23, 0x0d, 0xff, 0x03, 0x23, 0x0d, 0xff, 0x02, 0x23, 0x0d, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x00, 0x23, 0x0c, 0xff, 0x01, 0x24, 0x0d, 0xff, 0x02, 0x25, 0x0e, 0xff, 0x03, 0x28, 0x10, 0xff, 0x02, 0x2b, 0x11, 0xff, 0x03, 0x2d, 0x13, 0xff, 0x04, 0x2f, 0x14, 0xff, 0x05, 0x32, 0x16, 0xff, 0x03, 0x32, 0x16, 0xff, 0x03, 0x34, 0x18, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x40, 0x22, 0xff, 0x0a, 0x64, 0x3e, 0xff, 0x1a, 0x88, 0x5e, 0xff, 0x0c, 0x8c, 0x5f, 0xff, 0x0e, 0x9c, 0x6d, 0xff, 0x12, 0xa6, 0x78, 0xff, 0x17, 0xa6, 0x7d, 0xff, 0x20, 0xa7, 0x85, 0xff, 0x25, 0xa9, 0x8a, 0xff, 0x29, 0xa9, 0x8c, 0xff, 0x2b, 0xaa, 0x8e, 0xff, 0x2e, 0xaa, 0x92, 0xff, 0x2f, 0xaa, 0x94, 0xff, 0x30, 0xa9, 0x94, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x36, 0xad, 0x98, 0xff, 0x36, 0xad, 0x98, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x34, 0xac, 0x97, 0xff, 0x33, 0xae, 0x98, 0xff, 0x31, 0xb0, 0x97, 0xff, 0x2d, 0xad, 0x92, 0xff, 0x2a, 0xae, 0x8f, 0xff, 0x28, 0xae, 0x8c, 0xff, 0x1c, 0xb0, 0x7c, 0xff, 0x0e, 0xb1, 0x75, 0xff, 0x04, 0xb0, 0x72, 0xff, 0x0a, 0xae, 0x70, 0xff, 0x0a, 0x89, 0x53, 0xff, 0x00, 0x52, 0x27, 0xff, 0x02, 0x39, 0x1a, 0xff, 0x04, 0x32, 0x17, 0xff, 0x04, 0x2d, 0x13, 0xff, 0x00, 0x22, 0x0a, 0xff, 0x06, 0x25, 0x0d, 0xff, 0x04, 0x21, 0x0a, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x01, 0x1f, 0x0a, 0xff, 0x00, 0x1d, 0x09, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x03, 0x1d, 0x0a, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x02, 0x1c, 0x09, 0xff, 0x01, 0x1c, 0x07, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x01, 0x1c, 0x06, 0xff, 0x02, 0x1e, 0x06, 0xff, 0x01, 0x1d, 0x05, 0xff, 0x01, 0x1c, 0x05, 0xff, 0x00, 0x1c, 0x06, 0xff, 0x00, 0x1d, 0x07, 0xff, 0x01, 0x1e, 0x09, 0xff, 0x02, 0x1f, 0x0a, 0xff, 0x02, 0x20, 0x0a, 0xff, 0x02, 0x22, 0x0a, 0xff, 0x00, 0x23, 0x0c, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x01, 0x26, 0x10, 0xff, 0x01, 0x28, 0x10, 0xff, 0x02, 0x2d, 0x13, 0xff, 0x02, 0x31, 0x15, 0xff, 0x03, 0x32, 0x18, 0xff, 0x04, 0x35, 0x1c, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x05, 0x50, 0x2e, 0xff, 0x11, 0x7c, 0x53, 0xff, 0x0c, 0x8e, 0x61, 0xff, 0x16, 0xa8, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x13, 0xaa, 0x7b, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x14, 0xac, 0x7b, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0a, 0xa6, 0x73, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xab, 0x76, 0xff, 0x10, 0xaf, 0x76, 0xff, 0x0b, 0xad, 0x73, 0xff, 0x0b, 0xab, 0x74, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x11, 0xa4, 0x6f, 0xff, 0x12, 0xa6, 0x71, 0xff, 0x0f, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x09, 0xab, 0x72, 0xff, 0x0a, 0xad, 0x74, 0xff, 0x0f, 0xa0, 0x6a, 0xff, 0x06, 0x80, 0x4e, 0xff, 0x02, 0x62, 0x35, 0xff, 0x00, 0x49, 0x23, 0xff, 0x00, 0x40, 0x1e, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x04, 0x3e, 0x20, 0xff, 0x04, 0x39, 0x1b, 0xff, 0x01, 0x32, 0x16, 0xff, 0x02, 0x32, 0x16, 0xff, 0x04, 0x32, 0x18, 0xff, 0x03, 0x31, 0x17, 0xff, 0x02, 0x2f, 0x16, 0xff, 0x02, 0x30, 0x16, 0xff, 0x02, 0x31, 0x14, 0xff, 0x02, 0x30, 0x14, 0xff, 0x01, 0x2f, 0x13, 0xff, 0x01, 0x2f, 0x13, 0xff, 0x02, 0x31, 0x14, 0xff, 0x00, 0x2f, 0x12, 0xff, 0x01, 0x31, 0x14, 0xff, 0x02, 0x32, 0x16, 0xff, 0x03, 0x32, 0x16, 0xff, 0x04, 0x32, 0x17, 0xff, 0x03, 0x33, 0x18, 0xff, 0x03, 0x34, 0x18, 0xff, 0x03, 0x35, 0x18, 0xff, 0x02, 0x35, 0x18, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x04, 0x3a, 0x1d, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x00, 0x3c, 0x1f, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x01, 0x3e, 0x22, 0xff, 0x00, 0x41, 0x22, 0xff, 0x05, 0x50, 0x30, 0xff, 0x15, 0x73, 0x4d, 0xff, 0x06, 0x6b, 0x42, 0xff, 0x01, 0x6b, 0x3f, 0xff, 0x10, 0x90, 0x5f, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x11, 0xa2, 0x6e, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x6e, 0xff, 0x0a, 0x9e, 0x6e, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa0, 0x70, 0xff, 0x1e, 0x9f, 0xad, 0xff, 0x1f, 0x7d, 0xf2, 0xff, 0x29, 0x56, 0xf9, 0xff, 0x30, 0x31, 0xf3, 0xff, 0x31, 0x1a, 0xe2, 0xff, 0x16, 0x1d, 0x9d, 0xff, 0x0a, 0x1a, 0x79, 0xff, 0x17, 0x2a, 0x80, 0xff, 0x11, 0x1d, 0x79, 0xff, 0x07, 0x23, 0x5b, 0xff, 0x0f, 0x3b, 0x64, 0xff, 0x0f, 0x20, 0x82, 0xff, 0x0b, 0x0e, 0xab, 0xff, 0x16, 0x16, 0xdc, 0xff, 0x28, 0x1e, 0xee, 0xff, 0x31, 0x45, 0xf7, 0xff, 0x2f, 0x6a, 0xf0, 0xff, 0x23, 0x74, 0x96, 0xff, 0x03, 0x5e, 0x38, 0xff, 0x09, 0x63, 0x28, 0xff, 0x0c, 0x5b, 0x26, 0xff, 0x10, 0x56, 0x27, 0xff, 0x0f, 0x52, 0x26, 0xff, 0x0d, 0x54, 0x27, 0xff, 0x09, 0x52, 0x24, 0xff, 0x08, 0x51, 0x21, 0xff, 0x04, 0x56, 0x22, 0xff, 0x07, 0x5d, 0x2a, 0xff, 0x0e, 0x61, 0x31, 0xff, 0x0b, 0x5b, 0x31, 0xff, 0x0a, 0x58, 0x34, 0xff, 0x0c, 0x57, 0x3b, 0xff, 0x0d, 0x56, 0x3f, 0xff, 0x10, 0x55, 0x45, 0xff, 0x11, 0x54, 0x36, 0xff, 0x0d, 0x53, 0x2e, 0xff, 0x09, 0x51, 0x2f, 0xff, 0x0a, 0x3d, 0x1e, 0xff, 0x02, 0x2e, 0x0e, 0xff, 0x0a, 0x54, 0x30, 0xff, 0x04, 0x53, 0x30, 0xff, 0x09, 0x45, 0x28, 0xff, 0x06, 0x4c, 0x29, 0xff, 0x11, 0x60, 0x3b, 0xff, 0x08, 0x54, 0x2d, 0xff, 0x0d, 0x60, 0x37, 0xff, 0x05, 0x55, 0x28, 0xff, 0x0a, 0x52, 0x35, 0xff, 0x02, 0x45, 0x37, 0xff, 0x06, 0x45, 0x40, 0xff, 0x07, 0x3e, 0x3c, 0xff, 0x14, 0x56, 0x3f, 0xff, 0x16, 0x57, 0x39, 0xff, 0x04, 0x3b, 0x1e, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x0a, 0x55, 0x33, 0xff, 0x04, 0x25, 0x16, 0xff, 0x5f, 0x70, 0x68, 0xff, + 0x54, 0x78, 0x97, 0xff, 0x79, 0x9e, 0xc0, 0xff, 0x8c, 0xb6, 0xcb, 0xff, 0x3a, 0x7f, 0x75, 0xff, 0x1c, 0x7a, 0x59, 0xff, 0x12, 0x80, 0x56, 0xff, 0x0b, 0x80, 0x55, 0xff, 0x0b, 0x82, 0x57, 0xff, 0x14, 0x89, 0x5e, 0xff, 0x14, 0x91, 0x62, 0xff, 0x0d, 0x96, 0x65, 0xff, 0x0d, 0x99, 0x60, 0xff, 0x14, 0x85, 0x66, 0xff, 0x23, 0x5f, 0x71, 0xff, 0x2d, 0x57, 0x78, 0xff, 0x14, 0x3d, 0x6a, 0xff, 0x4a, 0x74, 0xab, 0xff, 0x53, 0x87, 0xc1, 0xff, 0x3f, 0x7d, 0xb0, 0xff, 0x34, 0x79, 0x9d, 0xff, 0x19, 0x53, 0x72, 0xff, 0x02, 0x21, 0x46, 0xff, 0x04, 0x21, 0x44, 0xff, 0x12, 0x4c, 0x56, 0xff, 0x21, 0x7d, 0x62, 0xff, 0x04, 0x59, 0x31, 0xff, 0x00, 0x45, 0x24, 0xff, 0x02, 0x3e, 0x26, 0xff, 0x02, 0x3f, 0x25, 0xff, 0x04, 0x3e, 0x22, 0xff, 0x03, 0x40, 0x22, 0xff, 0x0b, 0x76, 0x4c, 0xff, 0x1a, 0xa0, 0x6c, 0xff, 0x11, 0xa1, 0x6e, 0xff, 0x0f, 0x7c, 0x72, 0xff, 0x4d, 0x85, 0xb4, 0xff, 0x63, 0xa5, 0xc8, 0xff, 0x23, 0x9e, 0x86, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0f, 0xa3, 0x6a, 0xff, 0x11, 0xa4, 0x6e, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0a, 0xa7, 0x6c, 0xff, 0x0d, 0xaa, 0x6d, 0xff, 0x13, 0x91, 0x5b, 0xff, 0x02, 0x55, 0x28, 0xff, 0x00, 0x40, 0x18, 0xff, 0x00, 0x36, 0x14, 0xff, 0x03, 0x32, 0x16, 0xff, 0x02, 0x24, 0x0c, 0xff, 0x05, 0x24, 0x0e, 0xff, 0x03, 0x23, 0x0c, 0xff, 0x02, 0x22, 0x0a, 0xff, 0x01, 0x20, 0x09, 0xff, 0x01, 0x1f, 0x09, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x00, 0x1e, 0x07, 0xff, 0x01, 0x1f, 0x07, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x02, 0x1c, 0x09, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x01, 0x1b, 0x08, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x01, 0x1b, 0x06, 0xff, 0x02, 0x1d, 0x08, 0xff, 0x02, 0x1d, 0x08, 0xff, 0x01, 0x1c, 0x08, 0xff, 0x00, 0x1b, 0x08, 0xff, 0x00, 0x1c, 0x09, 0xff, 0x00, 0x1c, 0x09, 0xff, 0x00, 0x1c, 0x09, 0xff, 0x01, 0x1f, 0x0b, 0xff, 0x01, 0x22, 0x0c, 0xff, 0x00, 0x23, 0x0b, 0xff, 0x01, 0x25, 0x0c, 0xff, 0x01, 0x26, 0x0b, 0xff, 0x02, 0x29, 0x0e, 0xff, 0x02, 0x2a, 0x0e, 0xff, 0x04, 0x2e, 0x12, 0xff, 0x04, 0x32, 0x17, 0xff, 0x02, 0x34, 0x18, 0xff, 0x01, 0x36, 0x19, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x06, 0x53, 0x32, 0xff, 0x19, 0x7f, 0x59, 0xff, 0x0c, 0x8a, 0x5f, 0xff, 0x10, 0x9f, 0x72, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x1d, 0xa7, 0x84, 0xff, 0x23, 0xa9, 0x89, 0xff, 0x29, 0xaa, 0x8d, 0xff, 0x2b, 0xaa, 0x8e, 0xff, 0x2e, 0xaa, 0x93, 0xff, 0x30, 0xab, 0x95, 0xff, 0x32, 0xaa, 0x96, 0xff, 0x32, 0xaa, 0x95, 0xff, 0x33, 0xab, 0x96, 0xff, 0x33, 0xab, 0x96, 0xff, 0x34, 0xab, 0x96, 0xff, 0x33, 0xaa, 0x95, 0xff, 0x34, 0xac, 0x97, 0xff, 0x35, 0xad, 0x98, 0xff, 0x35, 0xad, 0x98, 0xff, 0x35, 0xad, 0x98, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x35, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x34, 0xac, 0x97, 0xff, 0x33, 0xae, 0x98, 0xff, 0x32, 0xaf, 0x97, 0xff, 0x2d, 0xae, 0x93, 0xff, 0x2a, 0xaf, 0x8f, 0xff, 0x28, 0xaf, 0x8b, 0xff, 0x1c, 0xb0, 0x7c, 0xff, 0x0f, 0xb0, 0x75, 0xff, 0x06, 0xb2, 0x74, 0xff, 0x08, 0xb0, 0x72, 0xff, 0x13, 0x9f, 0x68, 0xff, 0x08, 0x6c, 0x3e, 0xff, 0x00, 0x35, 0x14, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x03, 0x23, 0x0b, 0xff, 0x01, 0x1b, 0x05, 0xff, 0x06, 0x1f, 0x09, 0xff, 0x03, 0x1b, 0x05, 0xff, 0x03, 0x1c, 0x08, 0xff, 0x01, 0x1c, 0x08, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x03, 0x1a, 0x07, 0xff, 0x06, 0x1b, 0x09, 0xff, 0x05, 0x1b, 0x09, 0xff, 0x05, 0x1b, 0x08, 0xff, 0x04, 0x19, 0x07, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x17, 0x05, 0xff, 0x00, 0x18, 0x05, 0xff, 0x03, 0x1a, 0x05, 0xff, 0x03, 0x1b, 0x05, 0xff, 0x02, 0x19, 0x05, 0xff, 0x02, 0x19, 0x05, 0xff, 0x02, 0x19, 0x06, 0xff, 0x01, 0x19, 0x06, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x03, 0x1a, 0x08, 0xff, 0x05, 0x1d, 0x08, 0xff, 0x05, 0x20, 0x08, 0xff, 0x01, 0x20, 0x09, 0xff, 0x01, 0x20, 0x09, 0xff, 0x00, 0x20, 0x09, 0xff, 0x00, 0x20, 0x09, 0xff, 0x01, 0x27, 0x0d, 0xff, 0x01, 0x2c, 0x11, 0xff, 0x02, 0x2d, 0x14, 0xff, 0x03, 0x2e, 0x17, 0xff, 0x01, 0x33, 0x18, 0xff, 0x09, 0x50, 0x31, 0xff, 0x10, 0x7c, 0x55, 0xff, 0x0f, 0x94, 0x67, 0xff, 0x15, 0xa9, 0x7b, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x18, 0xb0, 0x7f, 0xff, 0x13, 0xab, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x10, 0xaa, 0x75, 0xff, 0x0c, 0xaa, 0x73, 0xff, 0x0b, 0xaa, 0x73, 0xff, 0x0c, 0xa9, 0x75, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x11, 0xa4, 0x72, 0xff, 0x12, 0xa5, 0x71, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x13, 0xa1, 0x6c, 0xff, 0x0e, 0x85, 0x54, 0xff, 0x03, 0x5d, 0x32, 0xff, 0x01, 0x49, 0x24, 0xff, 0x02, 0x3f, 0x1f, 0xff, 0x02, 0x3d, 0x1e, 0xff, 0x03, 0x39, 0x1b, 0xff, 0x03, 0x30, 0x12, 0xff, 0x02, 0x2e, 0x11, 0xff, 0x02, 0x2e, 0x12, 0xff, 0x04, 0x2e, 0x14, 0xff, 0x02, 0x2d, 0x13, 0xff, 0x00, 0x29, 0x10, 0xff, 0x00, 0x29, 0x10, 0xff, 0x00, 0x29, 0x10, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x00, 0x28, 0x0e, 0xff, 0x00, 0x29, 0x0f, 0xff, 0x01, 0x2a, 0x10, 0xff, 0x00, 0x2a, 0x0f, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x03, 0x2d, 0x12, 0xff, 0x03, 0x2e, 0x13, 0xff, 0x02, 0x2d, 0x12, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x00, 0x2d, 0x12, 0xff, 0x01, 0x30, 0x14, 0xff, 0x02, 0x31, 0x16, 0xff, 0x04, 0x33, 0x18, 0xff, 0x06, 0x36, 0x1a, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x00, 0x37, 0x1c, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x00, 0x3a, 0x1e, 0xff, 0x00, 0x3c, 0x1f, 0xff, 0x01, 0x43, 0x26, 0xff, 0x14, 0x69, 0x47, 0xff, 0x13, 0x72, 0x4c, 0xff, 0x01, 0x60, 0x37, 0xff, 0x0a, 0x81, 0x53, 0xff, 0x10, 0x9d, 0x69, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0b, 0xa1, 0x6d, 0xff, 0x0b, 0x9f, 0x70, 0xff, 0x10, 0x9e, 0x72, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x14, 0x9b, 0x9b, 0xff, 0x1f, 0x7b, 0xeb, 0xff, 0x2b, 0x52, 0xf7, 0xff, 0x2d, 0x2d, 0xe9, 0xff, 0x2d, 0x18, 0xd9, 0xff, 0x1d, 0x20, 0xa0, 0xff, 0x0e, 0x23, 0x71, 0xff, 0x26, 0x47, 0x80, 0xff, 0x13, 0x24, 0x68, 0xff, 0x06, 0x1e, 0x57, 0xff, 0x02, 0x19, 0x61, 0xff, 0x08, 0x0f, 0x8b, 0xff, 0x0d, 0x0f, 0xb0, 0xff, 0x16, 0x10, 0xdc, 0xff, 0x27, 0x15, 0xf1, 0xff, 0x2e, 0x3b, 0xf6, 0xff, 0x2b, 0x63, 0xe8, 0xff, 0x0f, 0x62, 0x77, 0xff, 0x04, 0x5f, 0x34, 0xff, 0x0a, 0x5f, 0x27, 0xff, 0x0d, 0x57, 0x25, 0xff, 0x11, 0x53, 0x28, 0xff, 0x10, 0x50, 0x26, 0xff, 0x0e, 0x52, 0x27, 0xff, 0x0d, 0x52, 0x25, 0xff, 0x0c, 0x51, 0x23, 0xff, 0x06, 0x51, 0x23, 0xff, 0x03, 0x52, 0x28, 0xff, 0x0a, 0x57, 0x35, 0xff, 0x1a, 0x63, 0x4a, 0xff, 0x21, 0x67, 0x55, 0xff, 0x17, 0x58, 0x4f, 0xff, 0x12, 0x52, 0x4e, 0xff, 0x14, 0x51, 0x52, 0xff, 0x10, 0x4c, 0x3f, 0xff, 0x0a, 0x4a, 0x31, 0xff, 0x05, 0x48, 0x2e, 0xff, 0x14, 0x45, 0x2e, 0xff, 0x03, 0x2a, 0x10, 0xff, 0x05, 0x4a, 0x28, 0xff, 0x07, 0x55, 0x31, 0xff, 0x08, 0x45, 0x27, 0xff, 0x05, 0x48, 0x24, 0xff, 0x13, 0x60, 0x37, 0xff, 0x08, 0x56, 0x2d, 0xff, 0x0d, 0x62, 0x39, 0xff, 0x05, 0x59, 0x2d, 0xff, 0x11, 0x5d, 0x33, 0xff, 0x03, 0x4e, 0x27, 0xff, 0x04, 0x46, 0x27, 0xff, 0x06, 0x3d, 0x27, 0xff, 0x18, 0x59, 0x38, 0xff, 0x12, 0x4f, 0x37, 0xff, 0x04, 0x3d, 0x2c, 0xff, 0x10, 0x65, 0x40, 0xff, 0x0a, 0x53, 0x33, 0xff, 0x02, 0x24, 0x19, 0xff, 0x61, 0x71, 0x67, 0xff, + 0x48, 0x73, 0x85, 0xff, 0x7b, 0xa0, 0xbe, 0xff, 0x8a, 0xb8, 0xcc, 0xff, 0x30, 0x82, 0x78, 0xff, 0x0f, 0x7b, 0x5a, 0xff, 0x0b, 0x81, 0x53, 0xff, 0x0a, 0x83, 0x52, 0xff, 0x0f, 0x89, 0x5c, 0xff, 0x14, 0x8f, 0x65, 0xff, 0x0f, 0x95, 0x67, 0xff, 0x09, 0x99, 0x65, 0xff, 0x0d, 0x96, 0x65, 0xff, 0x1b, 0x88, 0x69, 0xff, 0x14, 0x53, 0x56, 0xff, 0x1f, 0x4b, 0x62, 0xff, 0x19, 0x41, 0x6e, 0xff, 0x3b, 0x66, 0x9d, 0xff, 0x3b, 0x7d, 0xa9, 0xff, 0x2c, 0x7d, 0x96, 0xff, 0x25, 0x84, 0x83, 0xff, 0x1d, 0x6c, 0x6b, 0xff, 0x03, 0x23, 0x44, 0xff, 0x07, 0x23, 0x4a, 0xff, 0x12, 0x49, 0x52, 0xff, 0x0b, 0x54, 0x38, 0xff, 0x00, 0x42, 0x22, 0xff, 0x01, 0x40, 0x25, 0xff, 0x07, 0x3f, 0x26, 0xff, 0x07, 0x3f, 0x24, 0xff, 0x02, 0x3f, 0x23, 0xff, 0x02, 0x4a, 0x2b, 0xff, 0x18, 0x8f, 0x61, 0xff, 0x16, 0xa1, 0x72, 0xff, 0x13, 0xa3, 0x6f, 0xff, 0x15, 0x81, 0x75, 0xff, 0x4b, 0x81, 0xb7, 0xff, 0x65, 0xa3, 0xcd, 0xff, 0x26, 0x9c, 0x86, 0xff, 0x0d, 0xa0, 0x6f, 0xff, 0x0f, 0xa0, 0x6f, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x09, 0xa5, 0x6b, 0xff, 0x09, 0xa5, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0a, 0xa1, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x10, 0xa2, 0x6d, 0xff, 0x11, 0xa4, 0x6d, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x1c, 0xa5, 0x6c, 0xff, 0x0a, 0x6b, 0x3c, 0xff, 0x00, 0x3b, 0x12, 0xff, 0x01, 0x29, 0x0a, 0xff, 0x03, 0x23, 0x0b, 0xff, 0x04, 0x1c, 0x0b, 0xff, 0x04, 0x1d, 0x0d, 0xff, 0x01, 0x1a, 0x07, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x02, 0x1c, 0x08, 0xff, 0x02, 0x1b, 0x07, 0xff, 0x03, 0x1b, 0x07, 0xff, 0x03, 0x1b, 0x08, 0xff, 0x01, 0x1c, 0x06, 0xff, 0x01, 0x1b, 0x06, 0xff, 0x05, 0x18, 0x07, 0xff, 0x04, 0x18, 0x05, 0xff, 0x02, 0x17, 0x04, 0xff, 0x01, 0x18, 0x04, 0xff, 0x00, 0x19, 0x02, 0xff, 0x00, 0x1b, 0x04, 0xff, 0x00, 0x1c, 0x04, 0xff, 0x00, 0x1b, 0x05, 0xff, 0x00, 0x17, 0x07, 0xff, 0x00, 0x18, 0x08, 0xff, 0x00, 0x19, 0x07, 0xff, 0x00, 0x18, 0x07, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x02, 0x1e, 0x0a, 0xff, 0x02, 0x21, 0x0b, 0xff, 0x00, 0x22, 0x07, 0xff, 0x00, 0x22, 0x08, 0xff, 0x02, 0x21, 0x07, 0xff, 0x05, 0x25, 0x0c, 0xff, 0x05, 0x29, 0x10, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x03, 0x2d, 0x13, 0xff, 0x05, 0x30, 0x16, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x13, 0x6f, 0x4b, 0xff, 0x11, 0x8f, 0x66, 0xff, 0x18, 0xaa, 0x7e, 0xff, 0x16, 0xad, 0x82, 0xff, 0x1a, 0xab, 0x84, 0xff, 0x1e, 0xaa, 0x84, 0xff, 0x20, 0xaa, 0x86, 0xff, 0x28, 0xab, 0x8e, 0xff, 0x2c, 0xac, 0x92, 0xff, 0x2f, 0xaa, 0x95, 0xff, 0x34, 0xac, 0x98, 0xff, 0x34, 0xaa, 0x98, 0xff, 0x31, 0xaa, 0x96, 0xff, 0x31, 0xac, 0x97, 0xff, 0x30, 0xae, 0x96, 0xff, 0x32, 0xac, 0x96, 0xff, 0x32, 0xab, 0x96, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xae, 0x96, 0xff, 0x33, 0xad, 0x95, 0xff, 0x34, 0xad, 0x97, 0xff, 0x34, 0xad, 0x98, 0xff, 0x31, 0xae, 0x96, 0xff, 0x2f, 0xaf, 0x94, 0xff, 0x2b, 0xaf, 0x8f, 0xff, 0x26, 0xae, 0x8a, 0xff, 0x1a, 0xaf, 0x7e, 0xff, 0x10, 0xaf, 0x77, 0xff, 0x0c, 0xb1, 0x74, 0xff, 0x0a, 0xb3, 0x72, 0xff, 0x10, 0xaf, 0x70, 0xff, 0x1a, 0x9d, 0x66, 0xff, 0x07, 0x4f, 0x28, 0xff, 0x01, 0x23, 0x07, 0xff, 0x03, 0x1c, 0x04, 0xff, 0x03, 0x18, 0x03, 0xff, 0x03, 0x15, 0x02, 0xff, 0x04, 0x16, 0x04, 0xff, 0x03, 0x17, 0x05, 0xff, 0x01, 0x1a, 0x08, 0xff, 0x01, 0x18, 0x06, 0xff, 0x02, 0x19, 0x05, 0xff, 0x05, 0x18, 0x05, 0xff, 0x05, 0x17, 0x04, 0xff, 0x05, 0x16, 0x03, 0xff, 0x05, 0x15, 0x02, 0xff, 0x03, 0x15, 0x02, 0xff, 0x03, 0x17, 0x02, 0xff, 0x03, 0x18, 0x04, 0xff, 0x02, 0x17, 0x03, 0xff, 0x02, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x04, 0x19, 0x06, 0xff, 0x04, 0x19, 0x06, 0xff, 0x06, 0x1b, 0x05, 0xff, 0x05, 0x1c, 0x04, 0xff, 0x04, 0x1c, 0x04, 0xff, 0x03, 0x1c, 0x04, 0xff, 0x02, 0x1d, 0x05, 0xff, 0x02, 0x1d, 0x06, 0xff, 0x02, 0x24, 0x0c, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x04, 0x28, 0x10, 0xff, 0x05, 0x28, 0x10, 0xff, 0x02, 0x30, 0x16, 0xff, 0x10, 0x58, 0x39, 0xff, 0x11, 0x84, 0x5c, 0xff, 0x15, 0xa2, 0x76, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x13, 0xa6, 0x77, 0xff, 0x16, 0xa5, 0x77, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x0f, 0xa7, 0x79, 0xff, 0x0d, 0xa6, 0x79, 0xff, 0x0d, 0xa6, 0x78, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa9, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xaa, 0x70, 0xff, 0x0a, 0xac, 0x6f, 0xff, 0x13, 0xa5, 0x6c, 0xff, 0x11, 0x8d, 0x5a, 0xff, 0x02, 0x5a, 0x30, 0xff, 0x01, 0x45, 0x1f, 0xff, 0x03, 0x3a, 0x19, 0xff, 0x04, 0x39, 0x18, 0xff, 0x01, 0x2d, 0x0d, 0xff, 0x03, 0x28, 0x09, 0xff, 0x05, 0x2a, 0x0c, 0xff, 0x01, 0x27, 0x0a, 0xff, 0x00, 0x27, 0x0b, 0xff, 0x00, 0x26, 0x0b, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x01, 0x22, 0x0c, 0xff, 0x01, 0x23, 0x0d, 0xff, 0x01, 0x23, 0x0c, 0xff, 0x00, 0x21, 0x0b, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x01, 0x21, 0x0d, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x00, 0x20, 0x0c, 0xff, 0x00, 0x20, 0x0d, 0xff, 0x00, 0x21, 0x0d, 0xff, 0x01, 0x23, 0x0b, 0xff, 0x00, 0x22, 0x0a, 0xff, 0x00, 0x21, 0x09, 0xff, 0x00, 0x21, 0x09, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x00, 0x27, 0x0e, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x03, 0x2b, 0x13, 0xff, 0x05, 0x2d, 0x14, 0xff, 0x03, 0x2e, 0x14, 0xff, 0x01, 0x30, 0x17, 0xff, 0x00, 0x34, 0x1a, 0xff, 0x00, 0x37, 0x1c, 0xff, 0x00, 0x37, 0x1c, 0xff, 0x01, 0x3a, 0x1e, 0xff, 0x09, 0x4e, 0x32, 0xff, 0x20, 0x77, 0x57, 0xff, 0x07, 0x60, 0x3c, 0xff, 0x03, 0x6c, 0x42, 0xff, 0x0f, 0x98, 0x67, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0c, 0xa1, 0x6e, 0xff, 0x0a, 0xa1, 0x72, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x16, 0xa0, 0x6f, 0xff, 0x11, 0xa1, 0x70, 0xff, 0x06, 0xa3, 0x6a, 0xff, 0x0c, 0x9c, 0x85, 0xff, 0x25, 0x79, 0xdd, 0xff, 0x2c, 0x4d, 0xf1, 0xff, 0x24, 0x28, 0xe4, 0xff, 0x22, 0x1d, 0xd6, 0xff, 0x29, 0x34, 0xa6, 0xff, 0x33, 0x59, 0x9a, 0xff, 0x1b, 0x4d, 0x79, 0xff, 0x18, 0x34, 0x6c, 0xff, 0x03, 0x16, 0x5a, 0xff, 0x00, 0x0f, 0x6a, 0xff, 0x0e, 0x15, 0x9e, 0xff, 0x14, 0x19, 0xbc, 0xff, 0x17, 0x0e, 0xdd, 0xff, 0x26, 0x11, 0xe9, 0xff, 0x35, 0x3a, 0xf0, 0xff, 0x26, 0x59, 0xc6, 0xff, 0x06, 0x61, 0x4f, 0xff, 0x08, 0x65, 0x2c, 0xff, 0x0b, 0x59, 0x26, 0xff, 0x0e, 0x55, 0x28, 0xff, 0x0f, 0x50, 0x28, 0xff, 0x0c, 0x4f, 0x25, 0xff, 0x0b, 0x52, 0x25, 0xff, 0x0b, 0x51, 0x25, 0xff, 0x0b, 0x50, 0x25, 0xff, 0x09, 0x4c, 0x2b, 0xff, 0x14, 0x56, 0x41, 0xff, 0x29, 0x6b, 0x61, 0xff, 0x41, 0x7f, 0x84, 0xff, 0x3b, 0x75, 0x82, 0xff, 0x26, 0x5b, 0x6c, 0xff, 0x20, 0x55, 0x67, 0xff, 0x1e, 0x52, 0x66, 0xff, 0x1c, 0x50, 0x5f, 0xff, 0x10, 0x46, 0x48, 0xff, 0x06, 0x3c, 0x37, 0xff, 0x11, 0x3b, 0x36, 0xff, 0x05, 0x2b, 0x22, 0xff, 0x03, 0x3b, 0x20, 0xff, 0x0c, 0x54, 0x2f, 0xff, 0x09, 0x4a, 0x2a, 0xff, 0x0a, 0x48, 0x26, 0xff, 0x0d, 0x58, 0x32, 0xff, 0x0a, 0x5b, 0x34, 0xff, 0x09, 0x62, 0x39, 0xff, 0x05, 0x5f, 0x32, 0xff, 0x15, 0x67, 0x37, 0xff, 0x04, 0x52, 0x25, 0xff, 0x05, 0x47, 0x27, 0xff, 0x08, 0x40, 0x26, 0xff, 0x1d, 0x5b, 0x3d, 0xff, 0x0d, 0x48, 0x45, 0xff, 0x13, 0x57, 0x5d, 0xff, 0x10, 0x68, 0x48, 0xff, 0x09, 0x53, 0x31, 0xff, 0x01, 0x25, 0x18, 0xff, 0x63, 0x71, 0x67, 0xff, + 0x47, 0x75, 0x86, 0xff, 0x79, 0x9d, 0xbd, 0xff, 0x87, 0xb6, 0xcb, 0xff, 0x2b, 0x80, 0x73, 0xff, 0x0b, 0x7c, 0x58, 0xff, 0x0c, 0x84, 0x54, 0xff, 0x0f, 0x8a, 0x58, 0xff, 0x11, 0x92, 0x61, 0xff, 0x15, 0x95, 0x68, 0xff, 0x0e, 0x96, 0x66, 0xff, 0x09, 0x99, 0x65, 0xff, 0x0d, 0x97, 0x64, 0xff, 0x1b, 0x8e, 0x6a, 0xff, 0x04, 0x4b, 0x3f, 0xff, 0x0a, 0x40, 0x48, 0xff, 0x22, 0x50, 0x6e, 0xff, 0x2b, 0x60, 0x85, 0xff, 0x2b, 0x81, 0x91, 0xff, 0x1b, 0x87, 0x81, 0xff, 0x17, 0x94, 0x76, 0xff, 0x1b, 0x80, 0x6d, 0xff, 0x04, 0x26, 0x46, 0xff, 0x11, 0x2a, 0x55, 0xff, 0x10, 0x3d, 0x45, 0xff, 0x04, 0x40, 0x22, 0xff, 0x03, 0x40, 0x22, 0xff, 0x03, 0x3e, 0x25, 0xff, 0x07, 0x3e, 0x26, 0xff, 0x04, 0x3d, 0x23, 0xff, 0x01, 0x3f, 0x25, 0xff, 0x02, 0x4a, 0x2e, 0xff, 0x11, 0x7a, 0x51, 0xff, 0x11, 0x8e, 0x65, 0xff, 0x1a, 0xa2, 0x71, 0xff, 0x15, 0x84, 0x76, 0xff, 0x3f, 0x83, 0xb6, 0xff, 0x59, 0xa5, 0xca, 0xff, 0x20, 0x9d, 0x85, 0xff, 0x0a, 0xa2, 0x6f, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x08, 0xa6, 0x6a, 0xff, 0x09, 0xa5, 0x6b, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x10, 0xa5, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa8, 0x6d, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x11, 0xa9, 0x6e, 0xff, 0x1a, 0x99, 0x65, 0xff, 0x0a, 0x62, 0x36, 0xff, 0x00, 0x26, 0x05, 0xff, 0x05, 0x1c, 0x06, 0xff, 0x05, 0x15, 0x05, 0xff, 0x04, 0x14, 0x06, 0xff, 0x0a, 0x14, 0x04, 0xff, 0x0a, 0x15, 0x04, 0xff, 0x07, 0x17, 0x06, 0xff, 0x02, 0x16, 0x04, 0xff, 0x04, 0x17, 0x06, 0xff, 0x05, 0x17, 0x06, 0xff, 0x05, 0x16, 0x04, 0xff, 0x04, 0x15, 0x04, 0xff, 0x01, 0x15, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x01, 0x16, 0x04, 0xff, 0x03, 0x17, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x04, 0x18, 0x05, 0xff, 0x04, 0x19, 0x05, 0xff, 0x04, 0x19, 0x05, 0xff, 0x01, 0x17, 0x06, 0xff, 0x02, 0x18, 0x07, 0xff, 0x02, 0x19, 0x07, 0xff, 0x02, 0x19, 0x06, 0xff, 0x03, 0x1a, 0x06, 0xff, 0x03, 0x1c, 0x07, 0xff, 0x03, 0x1c, 0x06, 0xff, 0x04, 0x1c, 0x06, 0xff, 0x06, 0x1c, 0x07, 0xff, 0x03, 0x1b, 0x04, 0xff, 0x01, 0x1b, 0x04, 0xff, 0x02, 0x21, 0x09, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x00, 0x27, 0x0d, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x03, 0x2d, 0x13, 0xff, 0x00, 0x40, 0x20, 0xff, 0x0c, 0x6e, 0x48, 0xff, 0x21, 0xa3, 0x7a, 0xff, 0x21, 0xb6, 0x8a, 0xff, 0x1a, 0xb1, 0x86, 0xff, 0x1a, 0xad, 0x83, 0xff, 0x1b, 0xa8, 0x80, 0xff, 0x1c, 0xa8, 0x82, 0xff, 0x24, 0xa9, 0x8a, 0xff, 0x2a, 0xab, 0x90, 0xff, 0x2e, 0xaa, 0x94, 0xff, 0x33, 0xac, 0x98, 0xff, 0x34, 0xaa, 0x98, 0xff, 0x32, 0xab, 0x97, 0xff, 0x31, 0xad, 0x97, 0xff, 0x31, 0xad, 0x96, 0xff, 0x32, 0xac, 0x96, 0xff, 0x32, 0xab, 0x96, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xae, 0x98, 0xff, 0x33, 0xaf, 0x96, 0xff, 0x32, 0xaf, 0x96, 0xff, 0x33, 0xae, 0x98, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x31, 0xae, 0x96, 0xff, 0x2e, 0xaf, 0x94, 0xff, 0x2b, 0xb0, 0x90, 0xff, 0x27, 0xae, 0x8b, 0xff, 0x19, 0xb0, 0x80, 0xff, 0x11, 0xaf, 0x78, 0xff, 0x0e, 0xb1, 0x74, 0xff, 0x0b, 0xb3, 0x73, 0xff, 0x0a, 0xb3, 0x71, 0xff, 0x17, 0xb0, 0x74, 0xff, 0x1b, 0x90, 0x61, 0xff, 0x09, 0x57, 0x32, 0xff, 0x00, 0x20, 0x06, 0xff, 0x02, 0x18, 0x02, 0xff, 0x02, 0x15, 0x01, 0xff, 0x02, 0x14, 0x02, 0xff, 0x02, 0x14, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x13, 0x01, 0xff, 0x02, 0x13, 0x01, 0xff, 0x01, 0x15, 0x02, 0xff, 0x01, 0x15, 0x02, 0xff, 0x01, 0x13, 0x01, 0xff, 0x01, 0x13, 0x01, 0xff, 0x01, 0x13, 0x01, 0xff, 0x02, 0x14, 0x02, 0xff, 0x02, 0x14, 0x03, 0xff, 0x02, 0x15, 0x03, 0xff, 0x01, 0x16, 0x04, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x17, 0x05, 0xff, 0x02, 0x19, 0x06, 0xff, 0x03, 0x19, 0x07, 0xff, 0x03, 0x19, 0x06, 0xff, 0x02, 0x19, 0x04, 0xff, 0x03, 0x19, 0x03, 0xff, 0x04, 0x19, 0x04, 0xff, 0x03, 0x17, 0x03, 0xff, 0x04, 0x19, 0x05, 0xff, 0x04, 0x1b, 0x08, 0xff, 0x04, 0x1b, 0x08, 0xff, 0x07, 0x1d, 0x09, 0xff, 0x08, 0x25, 0x0d, 0xff, 0x02, 0x33, 0x16, 0xff, 0x0c, 0x64, 0x41, 0xff, 0x18, 0x98, 0x6f, 0xff, 0x1a, 0xae, 0x80, 0xff, 0x13, 0xb0, 0x80, 0xff, 0x13, 0xaf, 0x7e, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x11, 0xa5, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0e, 0xa7, 0x7a, 0xff, 0x0f, 0xa7, 0x7a, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x14, 0xac, 0x79, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x08, 0xaa, 0x6e, 0xff, 0x0c, 0xa9, 0x6e, 0xff, 0x11, 0x9c, 0x66, 0xff, 0x01, 0x58, 0x2b, 0xff, 0x01, 0x3a, 0x16, 0xff, 0x07, 0x30, 0x13, 0xff, 0x06, 0x2a, 0x10, 0xff, 0x00, 0x22, 0x09, 0xff, 0x01, 0x24, 0x0a, 0xff, 0x01, 0x21, 0x07, 0xff, 0x00, 0x20, 0x07, 0xff, 0x02, 0x20, 0x08, 0xff, 0x02, 0x1d, 0x05, 0xff, 0x06, 0x1c, 0x06, 0xff, 0x0a, 0x1d, 0x08, 0xff, 0x09, 0x1c, 0x08, 0xff, 0x03, 0x1d, 0x09, 0xff, 0x02, 0x1b, 0x07, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x03, 0x1a, 0x07, 0xff, 0x02, 0x19, 0x06, 0xff, 0x02, 0x19, 0x06, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x03, 0x1c, 0x09, 0xff, 0x01, 0x1b, 0x04, 0xff, 0x01, 0x1b, 0x04, 0xff, 0x02, 0x1c, 0x05, 0xff, 0x03, 0x1d, 0x05, 0xff, 0x02, 0x1c, 0x05, 0xff, 0x03, 0x1e, 0x07, 0xff, 0x02, 0x20, 0x09, 0xff, 0x01, 0x22, 0x0a, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x01, 0x24, 0x0b, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x02, 0x27, 0x0e, 0xff, 0x02, 0x2b, 0x12, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x03, 0x32, 0x18, 0xff, 0x02, 0x32, 0x18, 0xff, 0x01, 0x38, 0x1e, 0xff, 0x1e, 0x6e, 0x51, 0xff, 0x0c, 0x67, 0x44, 0xff, 0x04, 0x6a, 0x41, 0xff, 0x10, 0x9a, 0x6a, 0xff, 0x0e, 0xa3, 0x6e, 0xff, 0x10, 0xa1, 0x6d, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x09, 0xa0, 0x71, 0xff, 0x10, 0xa0, 0x6d, 0xff, 0x19, 0xa5, 0x72, 0xff, 0x1b, 0xa7, 0x73, 0xff, 0x11, 0x9f, 0x70, 0xff, 0x15, 0xa3, 0x71, 0xff, 0x17, 0x92, 0x76, 0xff, 0x32, 0x7d, 0xbe, 0xff, 0x26, 0x4b, 0xda, 0xff, 0x20, 0x23, 0xe0, 0xff, 0x28, 0x1b, 0xd0, 0xff, 0x0f, 0x18, 0x80, 0xff, 0x2c, 0x5a, 0x8e, 0xff, 0x2a, 0x63, 0x89, 0xff, 0x28, 0x4c, 0x84, 0xff, 0x16, 0x27, 0x67, 0xff, 0x08, 0x11, 0x67, 0xff, 0x19, 0x17, 0x95, 0xff, 0x19, 0x17, 0xb5, 0xff, 0x16, 0x11, 0xd7, 0xff, 0x21, 0x12, 0xe3, 0xff, 0x32, 0x35, 0xd7, 0xff, 0x21, 0x4e, 0x91, 0xff, 0x16, 0x6a, 0x45, 0xff, 0x0b, 0x64, 0x2f, 0xff, 0x06, 0x59, 0x29, 0xff, 0x09, 0x56, 0x27, 0xff, 0x0a, 0x51, 0x20, 0xff, 0x0c, 0x53, 0x21, 0xff, 0x0a, 0x52, 0x21, 0xff, 0x0c, 0x51, 0x28, 0xff, 0x09, 0x4a, 0x2c, 0xff, 0x21, 0x5f, 0x4d, 0xff, 0x4b, 0x88, 0x83, 0xff, 0x42, 0x7f, 0x85, 0xff, 0x2f, 0x6b, 0x7b, 0xff, 0x2a, 0x62, 0x77, 0xff, 0x2a, 0x5d, 0x74, 0xff, 0x26, 0x57, 0x6e, 0xff, 0x23, 0x55, 0x6d, 0xff, 0x28, 0x5a, 0x6f, 0xff, 0x28, 0x5c, 0x68, 0xff, 0x1c, 0x4f, 0x56, 0xff, 0x0c, 0x38, 0x3e, 0xff, 0x07, 0x32, 0x30, 0xff, 0x0e, 0x4b, 0x33, 0xff, 0x0d, 0x55, 0x30, 0xff, 0x0c, 0x4e, 0x2f, 0xff, 0x0c, 0x47, 0x2a, 0xff, 0x0c, 0x4f, 0x2c, 0xff, 0x13, 0x5e, 0x39, 0xff, 0x09, 0x60, 0x38, 0xff, 0x08, 0x61, 0x36, 0xff, 0x15, 0x67, 0x37, 0xff, 0x0a, 0x5d, 0x2e, 0xff, 0x04, 0x48, 0x25, 0xff, 0x09, 0x44, 0x26, 0xff, 0x1e, 0x5c, 0x42, 0xff, 0x12, 0x4d, 0x5e, 0xff, 0x29, 0x6b, 0x88, 0xff, 0x10, 0x66, 0x4c, 0xff, 0x0b, 0x56, 0x30, 0xff, 0x01, 0x27, 0x17, 0xff, 0x64, 0x6e, 0x6b, 0xff, + 0x48, 0x79, 0x8c, 0xff, 0x77, 0x9c, 0xc0, 0xff, 0x88, 0xb7, 0xcd, 0xff, 0x2b, 0x80, 0x71, 0xff, 0x0b, 0x7d, 0x55, 0xff, 0x0f, 0x8c, 0x5b, 0xff, 0x12, 0x93, 0x60, 0xff, 0x10, 0x97, 0x63, 0xff, 0x13, 0x97, 0x67, 0xff, 0x0f, 0x97, 0x65, 0xff, 0x0b, 0x98, 0x63, 0xff, 0x0e, 0x9b, 0x64, 0xff, 0x16, 0x95, 0x67, 0xff, 0x13, 0x7a, 0x5e, 0xff, 0x0a, 0x60, 0x52, 0xff, 0x0a, 0x4f, 0x52, 0xff, 0x15, 0x63, 0x6a, 0xff, 0x18, 0x87, 0x7a, 0xff, 0x14, 0x95, 0x74, 0xff, 0x11, 0x9a, 0x6b, 0xff, 0x12, 0x7d, 0x61, 0xff, 0x05, 0x2d, 0x4c, 0xff, 0x19, 0x36, 0x61, 0xff, 0x11, 0x3e, 0x45, 0xff, 0x07, 0x3f, 0x20, 0xff, 0x07, 0x3d, 0x21, 0xff, 0x09, 0x3d, 0x26, 0xff, 0x07, 0x3e, 0x26, 0xff, 0x05, 0x3f, 0x26, 0xff, 0x03, 0x3f, 0x26, 0xff, 0x03, 0x40, 0x29, 0xff, 0x01, 0x4c, 0x2c, 0xff, 0x05, 0x61, 0x41, 0xff, 0x1c, 0x89, 0x60, 0xff, 0x1d, 0x7d, 0x71, 0xff, 0x3f, 0x86, 0xb1, 0xff, 0x52, 0xa5, 0xc5, 0xff, 0x21, 0xa0, 0x86, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x06, 0xa7, 0x6a, 0xff, 0x07, 0xa7, 0x6a, 0xff, 0x07, 0xa6, 0x6a, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x0c, 0xa7, 0x6d, 0xff, 0x0a, 0xa8, 0x6b, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x16, 0xab, 0x72, 0xff, 0x1d, 0x9a, 0x67, 0xff, 0x08, 0x52, 0x2b, 0xff, 0x01, 0x22, 0x07, 0xff, 0x05, 0x18, 0x03, 0xff, 0x06, 0x14, 0x02, 0xff, 0x07, 0x11, 0x01, 0xff, 0x07, 0x14, 0x04, 0xff, 0x04, 0x14, 0x03, 0xff, 0x02, 0x14, 0x04, 0xff, 0x01, 0x13, 0x03, 0xff, 0x03, 0x13, 0x04, 0xff, 0x05, 0x11, 0x04, 0xff, 0x05, 0x11, 0x04, 0xff, 0x00, 0x12, 0x04, 0xff, 0x00, 0x13, 0x03, 0xff, 0x00, 0x14, 0x03, 0xff, 0x01, 0x14, 0x04, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x15, 0x03, 0xff, 0x03, 0x15, 0x04, 0xff, 0x04, 0x16, 0x04, 0xff, 0x02, 0x17, 0x04, 0xff, 0x02, 0x17, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x03, 0x19, 0x06, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x1a, 0x04, 0xff, 0x03, 0x19, 0x04, 0xff, 0x04, 0x19, 0x04, 0xff, 0x08, 0x17, 0x06, 0xff, 0x04, 0x16, 0x04, 0xff, 0x01, 0x19, 0x04, 0xff, 0x01, 0x1c, 0x07, 0xff, 0x01, 0x1c, 0x06, 0xff, 0x01, 0x1c, 0x06, 0xff, 0x01, 0x26, 0x0e, 0xff, 0x00, 0x2a, 0x0f, 0xff, 0x02, 0x52, 0x2f, 0xff, 0x19, 0x8a, 0x63, 0xff, 0x2d, 0xb6, 0x8c, 0xff, 0x24, 0xba, 0x8e, 0xff, 0x1c, 0xb4, 0x88, 0xff, 0x1b, 0xaf, 0x83, 0xff, 0x18, 0xa9, 0x7e, 0xff, 0x17, 0xa6, 0x7c, 0xff, 0x1f, 0xa6, 0x86, 0xff, 0x26, 0xaa, 0x8c, 0xff, 0x2a, 0xaa, 0x90, 0xff, 0x2f, 0xab, 0x95, 0xff, 0x34, 0xab, 0x98, 0xff, 0x33, 0xac, 0x98, 0xff, 0x32, 0xad, 0x97, 0xff, 0x31, 0xad, 0x97, 0xff, 0x32, 0xac, 0x96, 0xff, 0x32, 0xab, 0x96, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x35, 0xae, 0x99, 0xff, 0x33, 0xae, 0x97, 0xff, 0x32, 0xae, 0x96, 0xff, 0x32, 0xae, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x30, 0xae, 0x96, 0xff, 0x2f, 0xaf, 0x95, 0xff, 0x2b, 0xb0, 0x90, 0xff, 0x27, 0xaf, 0x8c, 0xff, 0x1a, 0xb0, 0x83, 0xff, 0x13, 0xb0, 0x7c, 0xff, 0x10, 0xb0, 0x76, 0xff, 0x0c, 0xb2, 0x74, 0xff, 0x07, 0xb4, 0x72, 0xff, 0x07, 0xb0, 0x72, 0xff, 0x17, 0xad, 0x77, 0xff, 0x19, 0x9e, 0x6e, 0xff, 0x0c, 0x62, 0x3d, 0xff, 0x02, 0x30, 0x14, 0xff, 0x00, 0x1a, 0x03, 0xff, 0x00, 0x13, 0x02, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x02, 0x13, 0x02, 0xff, 0x01, 0x13, 0x01, 0xff, 0x01, 0x13, 0x01, 0xff, 0x01, 0x13, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x03, 0xff, 0x00, 0x11, 0x03, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x13, 0x03, 0xff, 0x00, 0x14, 0x04, 0xff, 0x00, 0x15, 0x05, 0xff, 0x01, 0x16, 0x04, 0xff, 0x02, 0x16, 0x05, 0xff, 0x02, 0x15, 0x04, 0xff, 0x03, 0x16, 0x05, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x12, 0x01, 0xff, 0x01, 0x17, 0x02, 0xff, 0x05, 0x47, 0x26, 0xff, 0x13, 0x84, 0x5e, 0xff, 0x1e, 0xac, 0x80, 0xff, 0x19, 0xb0, 0x81, 0xff, 0x13, 0xb0, 0x7f, 0xff, 0x0f, 0xb1, 0x7e, 0xff, 0x0d, 0xab, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0d, 0xa6, 0x7a, 0xff, 0x0e, 0xa7, 0x7a, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x14, 0xab, 0x7a, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x14, 0xab, 0x7a, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x19, 0xae, 0x81, 0xff, 0x14, 0xa9, 0x7b, 0xff, 0x0b, 0xa4, 0x73, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x08, 0xac, 0x70, 0xff, 0x0e, 0xa8, 0x6e, 0xff, 0x0a, 0x77, 0x46, 0xff, 0x01, 0x3a, 0x14, 0xff, 0x06, 0x25, 0x0c, 0xff, 0x07, 0x1c, 0x0a, 0xff, 0x02, 0x19, 0x09, 0xff, 0x00, 0x1a, 0x08, 0xff, 0x00, 0x17, 0x05, 0xff, 0x04, 0x18, 0x06, 0xff, 0x08, 0x18, 0x05, 0xff, 0x09, 0x17, 0x03, 0xff, 0x09, 0x1a, 0x06, 0xff, 0x07, 0x1c, 0x06, 0xff, 0x05, 0x1b, 0x06, 0xff, 0x01, 0x1a, 0x07, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x02, 0x18, 0x04, 0xff, 0x03, 0x17, 0x04, 0xff, 0x03, 0x18, 0x04, 0xff, 0x03, 0x19, 0x04, 0xff, 0x04, 0x19, 0x05, 0xff, 0x02, 0x19, 0x04, 0xff, 0x02, 0x19, 0x04, 0xff, 0x02, 0x18, 0x04, 0xff, 0x02, 0x19, 0x04, 0xff, 0x02, 0x19, 0x05, 0xff, 0x03, 0x1c, 0x06, 0xff, 0x02, 0x1e, 0x07, 0xff, 0x02, 0x1f, 0x09, 0xff, 0x00, 0x1f, 0x08, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x00, 0x1f, 0x07, 0xff, 0x01, 0x20, 0x08, 0xff, 0x04, 0x25, 0x0d, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x02, 0x2a, 0x11, 0xff, 0x03, 0x2d, 0x15, 0xff, 0x01, 0x2f, 0x1b, 0xff, 0x15, 0x61, 0x47, 0xff, 0x0e, 0x6e, 0x4d, 0xff, 0x0c, 0x7e, 0x57, 0xff, 0x11, 0x9e, 0x6e, 0xff, 0x0e, 0xa0, 0x6e, 0xff, 0x0f, 0xa0, 0x6d, 0xff, 0x08, 0xa3, 0x6e, 0xff, 0x0a, 0xa0, 0x6f, 0xff, 0x1a, 0xa4, 0x71, 0xff, 0x1c, 0xa2, 0x73, 0xff, 0x12, 0xa2, 0x6f, 0xff, 0x13, 0xa2, 0x73, 0xff, 0x0e, 0x85, 0x5d, 0xff, 0x04, 0x62, 0x42, 0xff, 0x17, 0x5a, 0x6b, 0xff, 0x2a, 0x5e, 0xaa, 0xff, 0x19, 0x28, 0xbb, 0xff, 0x18, 0x10, 0xa6, 0xff, 0x14, 0x23, 0x74, 0xff, 0x3a, 0x61, 0x8e, 0xff, 0x1e, 0x45, 0x69, 0xff, 0x24, 0x43, 0x7a, 0xff, 0x09, 0x12, 0x4c, 0xff, 0x0a, 0x13, 0x55, 0xff, 0x18, 0x18, 0x7a, 0xff, 0x1b, 0x1e, 0xa2, 0xff, 0x17, 0x1b, 0xc8, 0xff, 0x1c, 0x1a, 0xce, 0xff, 0x14, 0x29, 0x94, 0xff, 0x07, 0x41, 0x4d, 0xff, 0x05, 0x57, 0x2c, 0xff, 0x03, 0x5e, 0x2f, 0xff, 0x03, 0x60, 0x30, 0xff, 0x05, 0x59, 0x29, 0xff, 0x08, 0x53, 0x1f, 0xff, 0x08, 0x51, 0x1e, 0xff, 0x0a, 0x50, 0x24, 0xff, 0x0c, 0x4e, 0x2c, 0xff, 0x16, 0x53, 0x3f, 0xff, 0x46, 0x7d, 0x7c, 0xff, 0x47, 0x7d, 0x88, 0xff, 0x2a, 0x63, 0x75, 0xff, 0x27, 0x61, 0x78, 0xff, 0x27, 0x60, 0x76, 0xff, 0x25, 0x5a, 0x6f, 0xff, 0x20, 0x52, 0x68, 0xff, 0x21, 0x55, 0x6c, 0xff, 0x28, 0x59, 0x70, 0xff, 0x2a, 0x5e, 0x6e, 0xff, 0x2a, 0x5e, 0x6e, 0xff, 0x1e, 0x4b, 0x5a, 0xff, 0x0b, 0x3a, 0x3e, 0xff, 0x1d, 0x5f, 0x48, 0xff, 0x0d, 0x59, 0x36, 0xff, 0x0d, 0x50, 0x34, 0xff, 0x07, 0x44, 0x29, 0xff, 0x09, 0x44, 0x24, 0xff, 0x15, 0x57, 0x36, 0xff, 0x0c, 0x60, 0x39, 0xff, 0x0c, 0x63, 0x38, 0xff, 0x11, 0x65, 0x39, 0xff, 0x0e, 0x61, 0x36, 0xff, 0x07, 0x50, 0x28, 0xff, 0x04, 0x44, 0x22, 0xff, 0x1c, 0x5d, 0x46, 0xff, 0x16, 0x51, 0x68, 0xff, 0x2b, 0x6a, 0x8e, 0xff, 0x0b, 0x61, 0x47, 0xff, 0x0d, 0x58, 0x2d, 0xff, 0x02, 0x28, 0x13, 0xff, 0x64, 0x6c, 0x6d, 0xff, + 0x48, 0x79, 0x8f, 0xff, 0x76, 0x9d, 0xc2, 0xff, 0x85, 0xb5, 0xc9, 0xff, 0x2a, 0x82, 0x6d, 0xff, 0x10, 0x85, 0x59, 0xff, 0x10, 0x93, 0x61, 0xff, 0x0e, 0x97, 0x62, 0xff, 0x0e, 0x9a, 0x64, 0xff, 0x11, 0x98, 0x67, 0xff, 0x11, 0x98, 0x67, 0xff, 0x0f, 0x9a, 0x65, 0xff, 0x0c, 0x9c, 0x62, 0xff, 0x0f, 0x99, 0x64, 0xff, 0x18, 0x94, 0x6b, 0xff, 0x1e, 0x8e, 0x6d, 0xff, 0x14, 0x77, 0x60, 0xff, 0x19, 0x85, 0x71, 0xff, 0x12, 0x91, 0x71, 0xff, 0x16, 0x96, 0x6b, 0xff, 0x10, 0x8c, 0x5c, 0xff, 0x05, 0x65, 0x48, 0xff, 0x10, 0x3e, 0x5c, 0xff, 0x2b, 0x54, 0x7d, 0xff, 0x10, 0x42, 0x49, 0xff, 0x04, 0x3e, 0x20, 0xff, 0x09, 0x3d, 0x21, 0xff, 0x09, 0x3d, 0x26, 0xff, 0x05, 0x40, 0x26, 0xff, 0x03, 0x40, 0x26, 0xff, 0x02, 0x3d, 0x23, 0xff, 0x03, 0x3b, 0x24, 0xff, 0x01, 0x3e, 0x23, 0xff, 0x01, 0x43, 0x29, 0xff, 0x06, 0x53, 0x32, 0xff, 0x0e, 0x57, 0x4d, 0xff, 0x44, 0x84, 0xa7, 0xff, 0x56, 0xa6, 0xbe, 0xff, 0x1f, 0x9a, 0x7e, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x05, 0xa7, 0x6a, 0xff, 0x06, 0xa5, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x08, 0xa6, 0x6a, 0xff, 0x07, 0xa9, 0x6d, 0xff, 0x0a, 0xac, 0x70, 0xff, 0x19, 0xae, 0x76, 0xff, 0x1d, 0x96, 0x66, 0xff, 0x0e, 0x62, 0x3b, 0xff, 0x02, 0x26, 0x0b, 0xff, 0x02, 0x15, 0x01, 0xff, 0x02, 0x11, 0x01, 0xff, 0x01, 0x13, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x11, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x03, 0x10, 0x04, 0xff, 0x04, 0x10, 0x04, 0xff, 0x03, 0x10, 0x04, 0xff, 0x01, 0x11, 0x04, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x11, 0x03, 0xff, 0x00, 0x11, 0x02, 0xff, 0x00, 0x11, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x13, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x15, 0x02, 0xff, 0x02, 0x16, 0x02, 0xff, 0x01, 0x15, 0x02, 0xff, 0x02, 0x16, 0x03, 0xff, 0x07, 0x14, 0x06, 0xff, 0x03, 0x15, 0x05, 0xff, 0x01, 0x16, 0x04, 0xff, 0x03, 0x15, 0x04, 0xff, 0x06, 0x14, 0x03, 0xff, 0x04, 0x17, 0x04, 0xff, 0x00, 0x19, 0x04, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x10, 0x78, 0x53, 0xff, 0x2a, 0xa8, 0x80, 0xff, 0x2a, 0xba, 0x8f, 0xff, 0x23, 0xbc, 0x8f, 0xff, 0x20, 0xb8, 0x8b, 0xff, 0x1e, 0xb3, 0x87, 0xff, 0x1a, 0xac, 0x80, 0xff, 0x16, 0xa8, 0x7d, 0xff, 0x1b, 0xa6, 0x82, 0xff, 0x21, 0xaa, 0x89, 0xff, 0x28, 0xaa, 0x8e, 0xff, 0x2d, 0xab, 0x93, 0xff, 0x32, 0xac, 0x97, 0xff, 0x34, 0xad, 0x99, 0xff, 0x33, 0xac, 0x98, 0xff, 0x32, 0xad, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x33, 0xac, 0x97, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x32, 0xae, 0x97, 0xff, 0x31, 0xae, 0x96, 0xff, 0x31, 0xad, 0x97, 0xff, 0x31, 0xad, 0x97, 0xff, 0x30, 0xaf, 0x96, 0xff, 0x2f, 0xb0, 0x95, 0xff, 0x2b, 0xaf, 0x91, 0xff, 0x27, 0xae, 0x8d, 0xff, 0x1a, 0xb1, 0x85, 0xff, 0x16, 0xb1, 0x81, 0xff, 0x14, 0xb0, 0x79, 0xff, 0x0f, 0xb0, 0x74, 0xff, 0x09, 0xb3, 0x73, 0xff, 0x05, 0xb1, 0x73, 0xff, 0x0a, 0xaf, 0x75, 0xff, 0x11, 0xac, 0x76, 0xff, 0x21, 0xa1, 0x73, 0xff, 0x1a, 0x81, 0x59, 0xff, 0x09, 0x55, 0x34, 0xff, 0x05, 0x3b, 0x1e, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x00, 0x1a, 0x04, 0xff, 0x01, 0x14, 0x01, 0xff, 0x01, 0x13, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x0f, 0x00, 0xff, 0x04, 0x0f, 0x02, 0xff, 0x04, 0x10, 0x03, 0xff, 0x02, 0x0f, 0x03, 0xff, 0x01, 0x0f, 0x02, 0xff, 0x01, 0x0f, 0x03, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x02, 0x0f, 0x01, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x11, 0x02, 0xff, 0x01, 0x12, 0x02, 0xff, 0x01, 0x12, 0x03, 0xff, 0x01, 0x12, 0x03, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x10, 0x01, 0xff, 0x01, 0x18, 0x04, 0xff, 0x04, 0x31, 0x16, 0xff, 0x17, 0x79, 0x55, 0xff, 0x1d, 0xa5, 0x7a, 0xff, 0x17, 0xaf, 0x80, 0xff, 0x15, 0xab, 0x7b, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x0d, 0xac, 0x7a, 0xff, 0x0d, 0xac, 0x79, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0d, 0xa6, 0x79, 0xff, 0x0e, 0xa6, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x14, 0xa8, 0x7d, 0xff, 0x1d, 0xaf, 0x87, 0xff, 0x1a, 0xab, 0x84, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x06, 0xab, 0x71, 0xff, 0x0a, 0xac, 0x70, 0xff, 0x17, 0x9e, 0x68, 0xff, 0x0a, 0x64, 0x38, 0xff, 0x01, 0x22, 0x06, 0xff, 0x04, 0x19, 0x08, 0xff, 0x07, 0x14, 0x08, 0xff, 0x01, 0x14, 0x07, 0xff, 0x02, 0x14, 0x06, 0xff, 0x07, 0x16, 0x07, 0xff, 0x09, 0x15, 0x05, 0xff, 0x06, 0x15, 0x04, 0xff, 0x02, 0x17, 0x04, 0xff, 0x01, 0x18, 0x03, 0xff, 0x00, 0x17, 0x02, 0xff, 0x00, 0x16, 0x03, 0xff, 0x00, 0x16, 0x03, 0xff, 0x00, 0x16, 0x03, 0xff, 0x01, 0x16, 0x04, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x03, 0xff, 0x02, 0x18, 0x03, 0xff, 0x03, 0x19, 0x03, 0xff, 0x01, 0x19, 0x05, 0xff, 0x00, 0x19, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x03, 0x19, 0x06, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x01, 0x1a, 0x07, 0xff, 0x00, 0x19, 0x06, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x1a, 0x05, 0xff, 0x00, 0x1b, 0x04, 0xff, 0x00, 0x1c, 0x05, 0xff, 0x02, 0x21, 0x0a, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x00, 0x24, 0x0d, 0xff, 0x06, 0x2b, 0x15, 0xff, 0x02, 0x2e, 0x1c, 0xff, 0x0e, 0x5a, 0x43, 0xff, 0x12, 0x78, 0x58, 0xff, 0x18, 0x96, 0x6f, 0xff, 0x11, 0xa0, 0x72, 0xff, 0x0e, 0xa0, 0x6f, 0xff, 0x0f, 0xa0, 0x6d, 0xff, 0x08, 0xa2, 0x6d, 0xff, 0x0d, 0xa1, 0x6f, 0xff, 0x34, 0xbb, 0x89, 0xff, 0x30, 0xb4, 0x88, 0xff, 0x14, 0xa5, 0x74, 0xff, 0x17, 0xa4, 0x76, 0xff, 0x06, 0x6d, 0x48, 0xff, 0x01, 0x4e, 0x2b, 0xff, 0x03, 0x47, 0x35, 0xff, 0x0a, 0x48, 0x5b, 0xff, 0x19, 0x36, 0xa7, 0xff, 0x17, 0x1c, 0x9c, 0xff, 0x14, 0x2a, 0x72, 0xff, 0x18, 0x35, 0x67, 0xff, 0x08, 0x1b, 0x41, 0xff, 0x1f, 0x3c, 0x76, 0xff, 0x05, 0x11, 0x4d, 0xff, 0x0b, 0x18, 0x4d, 0xff, 0x0b, 0x17, 0x5b, 0xff, 0x0d, 0x1b, 0x7a, 0xff, 0x0f, 0x1b, 0xa0, 0xff, 0x12, 0x1e, 0xa2, 0xff, 0x05, 0x39, 0x60, 0xff, 0x06, 0x62, 0x44, 0xff, 0x11, 0x74, 0x4a, 0xff, 0x12, 0x7d, 0x4e, 0xff, 0x13, 0x7c, 0x4a, 0xff, 0x10, 0x6c, 0x3f, 0xff, 0x03, 0x4f, 0x26, 0xff, 0x0a, 0x50, 0x2b, 0xff, 0x0d, 0x4d, 0x2f, 0xff, 0x0c, 0x49, 0x32, 0xff, 0x1c, 0x55, 0x47, 0xff, 0x50, 0x84, 0x8b, 0xff, 0x38, 0x6b, 0x81, 0xff, 0x2b, 0x62, 0x7c, 0xff, 0x25, 0x5f, 0x79, 0xff, 0x29, 0x62, 0x79, 0xff, 0x22, 0x59, 0x6d, 0xff, 0x1f, 0x55, 0x69, 0xff, 0x23, 0x57, 0x6d, 0xff, 0x25, 0x58, 0x6e, 0xff, 0x25, 0x5b, 0x70, 0xff, 0x25, 0x5b, 0x70, 0xff, 0x27, 0x56, 0x6c, 0xff, 0x10, 0x43, 0x4c, 0xff, 0x16, 0x5d, 0x47, 0xff, 0x10, 0x5f, 0x3b, 0xff, 0x06, 0x48, 0x2f, 0xff, 0x06, 0x46, 0x2d, 0xff, 0x07, 0x41, 0x24, 0xff, 0x0f, 0x4e, 0x2e, 0xff, 0x0f, 0x62, 0x39, 0xff, 0x0c, 0x63, 0x37, 0xff, 0x0f, 0x66, 0x3c, 0xff, 0x12, 0x62, 0x3c, 0xff, 0x0a, 0x54, 0x30, 0xff, 0x03, 0x47, 0x25, 0xff, 0x17, 0x5d, 0x43, 0xff, 0x1a, 0x5c, 0x69, 0xff, 0x26, 0x6b, 0x81, 0xff, 0x0a, 0x5f, 0x44, 0xff, 0x0c, 0x57, 0x2a, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x63, 0x6d, 0x69, 0xff, + 0x4a, 0x7b, 0x90, 0xff, 0x74, 0x9b, 0xbe, 0xff, 0x83, 0xb5, 0xc5, 0xff, 0x2e, 0x88, 0x70, 0xff, 0x15, 0x90, 0x60, 0xff, 0x0c, 0x97, 0x63, 0xff, 0x09, 0x98, 0x65, 0xff, 0x09, 0x9a, 0x64, 0xff, 0x0e, 0x98, 0x67, 0xff, 0x11, 0x98, 0x68, 0xff, 0x11, 0x9b, 0x68, 0xff, 0x0a, 0x9a, 0x63, 0xff, 0x09, 0x9b, 0x63, 0xff, 0x0d, 0x9a, 0x67, 0xff, 0x0f, 0x9a, 0x66, 0xff, 0x14, 0x99, 0x69, 0xff, 0x10, 0x97, 0x6f, 0xff, 0x10, 0x95, 0x6c, 0xff, 0x16, 0x83, 0x5b, 0xff, 0x09, 0x5e, 0x37, 0xff, 0x02, 0x47, 0x33, 0xff, 0x2c, 0x5e, 0x7c, 0xff, 0x4e, 0x83, 0xaa, 0xff, 0x18, 0x4d, 0x57, 0xff, 0x05, 0x40, 0x24, 0xff, 0x07, 0x3e, 0x22, 0xff, 0x03, 0x3f, 0x25, 0xff, 0x00, 0x45, 0x26, 0xff, 0x00, 0x4b, 0x29, 0xff, 0x01, 0x49, 0x27, 0xff, 0x01, 0x43, 0x25, 0xff, 0x02, 0x40, 0x24, 0xff, 0x02, 0x3e, 0x25, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x03, 0x3c, 0x2e, 0xff, 0x35, 0x71, 0x86, 0xff, 0x45, 0x97, 0xa4, 0xff, 0x1f, 0x9a, 0x7a, 0xff, 0x11, 0xa4, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa0, 0x6e, 0xff, 0x0d, 0x9a, 0x6d, 0xff, 0x11, 0x9d, 0x70, 0xff, 0x11, 0xa0, 0x70, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x08, 0xa5, 0x6b, 0xff, 0x06, 0xa7, 0x6a, 0xff, 0x03, 0xa6, 0x69, 0xff, 0x06, 0xac, 0x6f, 0xff, 0x0c, 0xb1, 0x75, 0xff, 0x13, 0xae, 0x76, 0xff, 0x1d, 0xa3, 0x72, 0xff, 0x19, 0x81, 0x57, 0xff, 0x0e, 0x59, 0x34, 0xff, 0x04, 0x33, 0x17, 0xff, 0x01, 0x1f, 0x06, 0xff, 0x00, 0x14, 0x01, 0xff, 0x02, 0x11, 0x00, 0xff, 0x06, 0x11, 0x01, 0xff, 0x06, 0x11, 0x03, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x10, 0x03, 0xff, 0x06, 0x0f, 0x03, 0xff, 0x07, 0x0f, 0x03, 0xff, 0x05, 0x0f, 0x02, 0xff, 0x05, 0x10, 0x02, 0xff, 0x03, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x11, 0x02, 0xff, 0x00, 0x11, 0x02, 0xff, 0x03, 0x10, 0x00, 0xff, 0x03, 0x0f, 0x01, 0xff, 0x04, 0x10, 0x00, 0xff, 0x05, 0x11, 0x01, 0xff, 0x03, 0x11, 0x01, 0xff, 0x03, 0x12, 0x01, 0xff, 0x02, 0x11, 0x00, 0xff, 0x02, 0x11, 0x01, 0xff, 0x02, 0x10, 0x04, 0xff, 0x01, 0x11, 0x04, 0xff, 0x01, 0x11, 0x03, 0xff, 0x04, 0x0f, 0x01, 0xff, 0x06, 0x0e, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x02, 0x27, 0x10, 0xff, 0x17, 0x66, 0x47, 0xff, 0x2d, 0xaa, 0x82, 0xff, 0x2c, 0xb8, 0x8d, 0xff, 0x24, 0xba, 0x8d, 0xff, 0x20, 0xba, 0x8d, 0xff, 0x20, 0xb9, 0x8c, 0xff, 0x20, 0xb6, 0x88, 0xff, 0x1b, 0xaf, 0x81, 0xff, 0x15, 0xaa, 0x7c, 0xff, 0x1a, 0xa8, 0x81, 0xff, 0x1f, 0xaa, 0x87, 0xff, 0x29, 0xac, 0x8f, 0xff, 0x2d, 0xac, 0x93, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x33, 0xab, 0x97, 0xff, 0x33, 0xac, 0x98, 0xff, 0x35, 0xac, 0x99, 0xff, 0x34, 0xac, 0x98, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x98, 0xff, 0x34, 0xad, 0x98, 0xff, 0x33, 0xad, 0x98, 0xff, 0x32, 0xaf, 0x97, 0xff, 0x30, 0xaf, 0x98, 0xff, 0x30, 0xae, 0x98, 0xff, 0x30, 0xae, 0x98, 0xff, 0x30, 0xae, 0x98, 0xff, 0x30, 0xaf, 0x96, 0xff, 0x2c, 0xb0, 0x93, 0xff, 0x27, 0xad, 0x8e, 0xff, 0x1d, 0xae, 0x87, 0xff, 0x1b, 0xb0, 0x84, 0xff, 0x18, 0xaf, 0x7c, 0xff, 0x15, 0xae, 0x77, 0xff, 0x0e, 0xb0, 0x75, 0xff, 0x0c, 0xb1, 0x74, 0xff, 0x0d, 0xaf, 0x75, 0xff, 0x13, 0xb0, 0x77, 0xff, 0x17, 0xab, 0x75, 0xff, 0x21, 0xad, 0x7c, 0xff, 0x25, 0xa6, 0x77, 0xff, 0x24, 0x9a, 0x6f, 0xff, 0x1c, 0x81, 0x5a, 0xff, 0x12, 0x66, 0x43, 0xff, 0x08, 0x42, 0x22, 0xff, 0x03, 0x30, 0x14, 0xff, 0x01, 0x21, 0x09, 0xff, 0x01, 0x1a, 0x04, 0xff, 0x01, 0x13, 0x01, 0xff, 0x02, 0x10, 0x00, 0xff, 0x03, 0x11, 0x02, 0xff, 0x02, 0x10, 0x01, 0xff, 0x02, 0x0f, 0x01, 0xff, 0x03, 0x0f, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x02, 0x11, 0x02, 0xff, 0x03, 0x11, 0x02, 0xff, 0x03, 0x10, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x03, 0x11, 0x02, 0xff, 0x02, 0x10, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x02, 0x16, 0x05, 0xff, 0x11, 0x48, 0x2c, 0xff, 0x27, 0x87, 0x62, 0xff, 0x24, 0xa8, 0x7d, 0xff, 0x14, 0xae, 0x7f, 0xff, 0x10, 0xac, 0x7a, 0xff, 0x13, 0xa6, 0x75, 0xff, 0x13, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0a, 0xa6, 0x73, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x0d, 0xa8, 0x77, 0xff, 0x0e, 0xa7, 0x77, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x12, 0xa6, 0x7c, 0xff, 0x1a, 0xab, 0x84, 0xff, 0x22, 0xaf, 0x8c, 0xff, 0x20, 0xad, 0x8b, 0xff, 0x1d, 0xaa, 0x85, 0xff, 0x14, 0xa9, 0x7a, 0xff, 0x0c, 0xaa, 0x75, 0xff, 0x0c, 0xaf, 0x75, 0xff, 0x10, 0xac, 0x71, 0xff, 0x1a, 0x9e, 0x6a, 0xff, 0x0b, 0x57, 0x31, 0xff, 0x02, 0x25, 0x0b, 0xff, 0x04, 0x14, 0x04, 0xff, 0x02, 0x13, 0x03, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x15, 0x05, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x12, 0x02, 0xff, 0x00, 0x13, 0x01, 0xff, 0x00, 0x13, 0x02, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x02, 0x13, 0x02, 0xff, 0x02, 0x14, 0x02, 0xff, 0x02, 0x14, 0x02, 0xff, 0x02, 0x14, 0x02, 0xff, 0x02, 0x16, 0x04, 0xff, 0x01, 0x16, 0x04, 0xff, 0x01, 0x16, 0x04, 0xff, 0x01, 0x16, 0x04, 0xff, 0x03, 0x16, 0x05, 0xff, 0x04, 0x17, 0x06, 0xff, 0x04, 0x17, 0x06, 0xff, 0x03, 0x18, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x07, 0x17, 0x05, 0xff, 0x04, 0x18, 0x05, 0xff, 0x01, 0x18, 0x04, 0xff, 0x00, 0x19, 0x04, 0xff, 0x00, 0x1c, 0x07, 0xff, 0x00, 0x1b, 0x06, 0xff, 0x01, 0x1d, 0x08, 0xff, 0x04, 0x20, 0x0d, 0xff, 0x01, 0x29, 0x18, 0xff, 0x12, 0x68, 0x50, 0xff, 0x1a, 0x8e, 0x6d, 0xff, 0x1a, 0xa3, 0x7a, 0xff, 0x0e, 0xa2, 0x73, 0xff, 0x0f, 0xa1, 0x6f, 0xff, 0x11, 0xa1, 0x6e, 0xff, 0x09, 0xa1, 0x6d, 0xff, 0x12, 0xa4, 0x72, 0xff, 0x2e, 0xb7, 0x84, 0xff, 0x21, 0xa8, 0x7d, 0xff, 0x0d, 0x9a, 0x6d, 0xff, 0x1d, 0xa9, 0x79, 0xff, 0x14, 0x84, 0x5b, 0xff, 0x03, 0x5b, 0x31, 0xff, 0x00, 0x46, 0x28, 0xff, 0x0d, 0x52, 0x63, 0xff, 0x2f, 0x4c, 0xd2, 0xff, 0x1f, 0x24, 0xbf, 0xff, 0x0b, 0x1c, 0x83, 0xff, 0x03, 0x10, 0x5f, 0xff, 0x0e, 0x25, 0x54, 0xff, 0x0a, 0x26, 0x69, 0xff, 0x05, 0x12, 0x63, 0xff, 0x0d, 0x19, 0x5a, 0xff, 0x03, 0x21, 0x45, 0xff, 0x01, 0x20, 0x47, 0xff, 0x04, 0x18, 0x5d, 0xff, 0x0c, 0x27, 0x5e, 0xff, 0x1c, 0x79, 0x62, 0xff, 0x0e, 0x95, 0x5d, 0xff, 0x0b, 0x8e, 0x61, 0xff, 0x0f, 0x8b, 0x58, 0xff, 0x17, 0x87, 0x58, 0xff, 0x1d, 0x79, 0x5b, 0xff, 0x19, 0x5e, 0x51, 0xff, 0x1c, 0x58, 0x52, 0xff, 0x14, 0x4d, 0x45, 0xff, 0x10, 0x48, 0x3e, 0xff, 0x14, 0x4a, 0x3e, 0xff, 0x3f, 0x70, 0x7b, 0xff, 0x3b, 0x6c, 0x88, 0xff, 0x29, 0x5f, 0x7b, 0xff, 0x27, 0x61, 0x7c, 0xff, 0x27, 0x61, 0x77, 0xff, 0x23, 0x5b, 0x6f, 0xff, 0x20, 0x55, 0x6a, 0xff, 0x21, 0x57, 0x6e, 0xff, 0x23, 0x56, 0x6d, 0xff, 0x21, 0x59, 0x6f, 0xff, 0x21, 0x59, 0x73, 0xff, 0x26, 0x58, 0x74, 0xff, 0x1c, 0x53, 0x5f, 0xff, 0x15, 0x62, 0x4b, 0xff, 0x15, 0x69, 0x44, 0xff, 0x04, 0x49, 0x2d, 0xff, 0x05, 0x47, 0x2e, 0xff, 0x06, 0x43, 0x27, 0xff, 0x06, 0x47, 0x26, 0xff, 0x0c, 0x5e, 0x31, 0xff, 0x0c, 0x65, 0x35, 0xff, 0x0f, 0x61, 0x3e, 0xff, 0x2d, 0x6b, 0x54, 0xff, 0x27, 0x67, 0x4f, 0xff, 0x10, 0x5d, 0x3d, 0xff, 0x14, 0x61, 0x40, 0xff, 0x1c, 0x69, 0x5b, 0xff, 0x27, 0x77, 0x6e, 0xff, 0x09, 0x60, 0x3d, 0xff, 0x0b, 0x54, 0x29, 0xff, 0x01, 0x27, 0x0e, 0xff, 0x64, 0x72, 0x63, 0xff, + 0x49, 0x77, 0x87, 0xff, 0x6e, 0x96, 0xb0, 0xff, 0x68, 0x9b, 0xa2, 0xff, 0x25, 0x82, 0x64, 0xff, 0x16, 0x94, 0x62, 0xff, 0x09, 0x97, 0x64, 0xff, 0x08, 0x99, 0x67, 0xff, 0x08, 0x99, 0x65, 0xff, 0x0c, 0x97, 0x67, 0xff, 0x11, 0x97, 0x69, 0xff, 0x11, 0x99, 0x68, 0xff, 0x0b, 0x9a, 0x65, 0xff, 0x08, 0x9a, 0x64, 0xff, 0x08, 0x9c, 0x64, 0xff, 0x09, 0x9c, 0x61, 0xff, 0x10, 0x9c, 0x65, 0xff, 0x0e, 0x95, 0x6a, 0xff, 0x08, 0x7d, 0x54, 0xff, 0x05, 0x59, 0x38, 0xff, 0x07, 0x40, 0x25, 0xff, 0x08, 0x3a, 0x32, 0xff, 0x32, 0x64, 0x89, 0xff, 0x5c, 0x95, 0xc0, 0xff, 0x30, 0x61, 0x70, 0xff, 0x03, 0x3d, 0x24, 0xff, 0x02, 0x3e, 0x22, 0xff, 0x00, 0x45, 0x28, 0xff, 0x02, 0x5b, 0x36, 0xff, 0x09, 0x76, 0x4b, 0xff, 0x14, 0x85, 0x56, 0xff, 0x0f, 0x7a, 0x50, 0xff, 0x06, 0x67, 0x43, 0xff, 0x05, 0x59, 0x39, 0xff, 0x04, 0x51, 0x2e, 0xff, 0x03, 0x4a, 0x32, 0xff, 0x09, 0x59, 0x5a, 0xff, 0x1b, 0x81, 0x7c, 0xff, 0x19, 0x9f, 0x78, 0xff, 0x13, 0xa6, 0x70, 0xff, 0x16, 0xa6, 0x79, 0xff, 0x1b, 0xa1, 0x7c, 0xff, 0x2c, 0xac, 0x8c, 0xff, 0x23, 0xa6, 0x83, 0xff, 0x12, 0x9e, 0x71, 0xff, 0x0a, 0xa0, 0x69, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x05, 0xa5, 0x6b, 0xff, 0x04, 0xa7, 0x6a, 0xff, 0x05, 0xa9, 0x6c, 0xff, 0x0e, 0xb0, 0x74, 0xff, 0x13, 0xb0, 0x76, 0xff, 0x13, 0xad, 0x75, 0xff, 0x18, 0xaf, 0x7a, 0xff, 0x1c, 0xb1, 0x7e, 0xff, 0x24, 0x9e, 0x71, 0xff, 0x1a, 0x80, 0x56, 0xff, 0x0c, 0x52, 0x2e, 0xff, 0x06, 0x2e, 0x12, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x00, 0xff, 0x00, 0x11, 0x01, 0xff, 0x02, 0x10, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x03, 0x11, 0x01, 0xff, 0x03, 0x10, 0x01, 0xff, 0x04, 0x11, 0x01, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x01, 0x11, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x04, 0x10, 0x02, 0xff, 0x06, 0x10, 0x02, 0xff, 0x04, 0x11, 0x02, 0xff, 0x03, 0x10, 0x02, 0xff, 0x02, 0x0f, 0x02, 0xff, 0x00, 0x0e, 0x01, 0xff, 0x01, 0x10, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x00, 0x0e, 0x02, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x02, 0x15, 0x05, 0xff, 0x06, 0x2e, 0x17, 0xff, 0x21, 0x7c, 0x5c, 0xff, 0x32, 0xac, 0x86, 0xff, 0x2b, 0xba, 0x8f, 0xff, 0x24, 0xb9, 0x8d, 0xff, 0x21, 0xbb, 0x8d, 0xff, 0x1f, 0xba, 0x8c, 0xff, 0x21, 0xb9, 0x8c, 0xff, 0x20, 0xb5, 0x89, 0xff, 0x1c, 0xb1, 0x84, 0xff, 0x19, 0xae, 0x82, 0xff, 0x1a, 0xaa, 0x81, 0xff, 0x21, 0xac, 0x89, 0xff, 0x28, 0xac, 0x8e, 0xff, 0x2e, 0xad, 0x94, 0xff, 0x33, 0xac, 0x98, 0xff, 0x35, 0xab, 0x99, 0xff, 0x34, 0xab, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x35, 0xac, 0x99, 0xff, 0x35, 0xab, 0x99, 0xff, 0x35, 0xad, 0x99, 0xff, 0x35, 0xae, 0x9a, 0xff, 0x35, 0xae, 0x9a, 0xff, 0x34, 0xad, 0x98, 0xff, 0x33, 0xae, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xaf, 0x98, 0xff, 0x32, 0xaf, 0x99, 0xff, 0x30, 0xae, 0x98, 0xff, 0x31, 0xaf, 0x99, 0xff, 0x30, 0xae, 0x98, 0xff, 0x2e, 0xad, 0x95, 0xff, 0x2c, 0xae, 0x93, 0xff, 0x29, 0xae, 0x91, 0xff, 0x24, 0xad, 0x8a, 0xff, 0x22, 0xad, 0x86, 0xff, 0x1f, 0xae, 0x82, 0xff, 0x19, 0xae, 0x7c, 0xff, 0x10, 0xad, 0x76, 0xff, 0x0e, 0xae, 0x74, 0xff, 0x11, 0xae, 0x75, 0xff, 0x13, 0xac, 0x74, 0xff, 0x12, 0xae, 0x75, 0xff, 0x10, 0xac, 0x74, 0xff, 0x14, 0xad, 0x76, 0xff, 0x17, 0xae, 0x79, 0xff, 0x1f, 0xaf, 0x7b, 0xff, 0x22, 0xa9, 0x79, 0xff, 0x25, 0x9b, 0x70, 0xff, 0x1d, 0x86, 0x5d, 0xff, 0x13, 0x6a, 0x45, 0xff, 0x0c, 0x59, 0x36, 0xff, 0x06, 0x42, 0x22, 0xff, 0x02, 0x2f, 0x11, 0xff, 0x00, 0x1e, 0x06, 0xff, 0x00, 0x17, 0x04, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x00, 0x0e, 0x00, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x02, 0x0f, 0x00, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x03, 0x0f, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x17, 0x04, 0xff, 0x04, 0x24, 0x0c, 0xff, 0x06, 0x32, 0x17, 0xff, 0x08, 0x49, 0x29, 0xff, 0x1b, 0x6d, 0x4b, 0xff, 0x35, 0x9f, 0x7a, 0xff, 0x2a, 0xae, 0x83, 0xff, 0x19, 0xae, 0x7e, 0xff, 0x11, 0xaf, 0x7e, 0xff, 0x12, 0xac, 0x7a, 0xff, 0x13, 0xa6, 0x74, 0xff, 0x11, 0xa1, 0x6e, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x10, 0xa6, 0x7a, 0xff, 0x16, 0xa9, 0x80, 0xff, 0x1b, 0xad, 0x86, 0xff, 0x22, 0xaf, 0x8e, 0xff, 0x22, 0xac, 0x8d, 0xff, 0x22, 0xac, 0x8b, 0xff, 0x1e, 0xac, 0x84, 0xff, 0x12, 0xaa, 0x7b, 0xff, 0x0d, 0xae, 0x77, 0xff, 0x0c, 0xb1, 0x74, 0xff, 0x15, 0xb1, 0x74, 0xff, 0x23, 0xa1, 0x6d, 0xff, 0x18, 0x75, 0x49, 0xff, 0x05, 0x31, 0x12, 0xff, 0x01, 0x1e, 0x06, 0xff, 0x00, 0x16, 0x01, 0xff, 0x00, 0x12, 0x00, 0xff, 0x02, 0x11, 0x00, 0xff, 0x03, 0x0f, 0x00, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x01, 0xff, 0x02, 0x11, 0x02, 0xff, 0x02, 0x11, 0x02, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x14, 0x02, 0xff, 0x00, 0x14, 0x02, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x11, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x02, 0x15, 0x04, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x14, 0x02, 0xff, 0x02, 0x14, 0x02, 0xff, 0x03, 0x16, 0x04, 0xff, 0x02, 0x17, 0x04, 0xff, 0x01, 0x15, 0x02, 0xff, 0x02, 0x14, 0x02, 0xff, 0x01, 0x13, 0x01, 0xff, 0x02, 0x15, 0x02, 0xff, 0x00, 0x14, 0x02, 0xff, 0x05, 0x36, 0x23, 0xff, 0x26, 0x8d, 0x73, 0xff, 0x22, 0xa4, 0x82, 0xff, 0x13, 0xa6, 0x7b, 0xff, 0x09, 0xa2, 0x73, 0xff, 0x0e, 0xa1, 0x6e, 0xff, 0x14, 0xa1, 0x6e, 0xff, 0x0b, 0xa2, 0x6f, 0xff, 0x0f, 0x9f, 0x70, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x0d, 0x9b, 0x6f, 0xff, 0x16, 0x9e, 0x77, 0xff, 0x1c, 0xa5, 0x75, 0xff, 0x1b, 0xa0, 0x6d, 0xff, 0x14, 0x8d, 0x5d, 0xff, 0x07, 0x61, 0x51, 0xff, 0x27, 0x80, 0xbf, 0xff, 0x14, 0x2c, 0xe2, 0xff, 0x19, 0x18, 0xde, 0xff, 0x19, 0x1c, 0xb1, 0xff, 0x0c, 0x17, 0x78, 0xff, 0x0c, 0x2e, 0x5d, 0xff, 0x02, 0x1a, 0x73, 0xff, 0x0b, 0x0d, 0x89, 0xff, 0x0f, 0x11, 0x81, 0xff, 0x0c, 0x2d, 0x51, 0xff, 0x03, 0x31, 0x34, 0xff, 0x09, 0x30, 0x34, 0xff, 0x05, 0x32, 0x2c, 0xff, 0x0e, 0x71, 0x48, 0xff, 0x0b, 0x9b, 0x5f, 0xff, 0x02, 0x94, 0x5a, 0xff, 0x0a, 0x8d, 0x57, 0xff, 0x17, 0x84, 0x5f, 0xff, 0x1e, 0x74, 0x68, 0xff, 0x2f, 0x6b, 0x79, 0xff, 0x2f, 0x63, 0x77, 0xff, 0x18, 0x49, 0x57, 0xff, 0x18, 0x4a, 0x4d, 0xff, 0x10, 0x43, 0x3d, 0xff, 0x2d, 0x5c, 0x67, 0xff, 0x45, 0x75, 0x8f, 0xff, 0x2a, 0x60, 0x79, 0xff, 0x25, 0x60, 0x78, 0xff, 0x27, 0x62, 0x77, 0xff, 0x26, 0x5f, 0x72, 0xff, 0x21, 0x57, 0x6b, 0xff, 0x23, 0x56, 0x71, 0xff, 0x24, 0x55, 0x6e, 0xff, 0x21, 0x59, 0x6d, 0xff, 0x1e, 0x56, 0x70, 0xff, 0x1e, 0x51, 0x6e, 0xff, 0x1b, 0x54, 0x62, 0xff, 0x1a, 0x67, 0x52, 0xff, 0x11, 0x68, 0x43, 0xff, 0x0f, 0x59, 0x39, 0xff, 0x04, 0x47, 0x2d, 0xff, 0x04, 0x42, 0x26, 0xff, 0x06, 0x46, 0x24, 0xff, 0x08, 0x54, 0x24, 0xff, 0x0e, 0x5f, 0x31, 0xff, 0x2d, 0x6b, 0x56, 0xff, 0x8d, 0xa9, 0xa8, 0xff, 0x74, 0x9e, 0x98, 0xff, 0x1a, 0x65, 0x4a, 0xff, 0x1c, 0x6f, 0x47, 0xff, 0x0c, 0x63, 0x3f, 0xff, 0x11, 0x6a, 0x47, 0xff, 0x0b, 0x63, 0x39, 0xff, 0x0a, 0x4e, 0x2a, 0xff, 0x00, 0x24, 0x0f, 0xff, 0x62, 0x73, 0x63, 0xff, + 0x27, 0x55, 0x5b, 0xff, 0x3a, 0x65, 0x73, 0xff, 0x1d, 0x51, 0x4f, 0xff, 0x08, 0x5a, 0x38, 0xff, 0x12, 0x8b, 0x5a, 0xff, 0x0d, 0x98, 0x66, 0xff, 0x0b, 0x99, 0x69, 0xff, 0x0b, 0x99, 0x67, 0xff, 0x0e, 0x99, 0x69, 0xff, 0x0f, 0x98, 0x69, 0xff, 0x0e, 0x98, 0x69, 0xff, 0x0e, 0x99, 0x67, 0xff, 0x0e, 0x9a, 0x66, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x13, 0x9b, 0x66, 0xff, 0x15, 0x8c, 0x61, 0xff, 0x08, 0x74, 0x4f, 0xff, 0x01, 0x57, 0x31, 0xff, 0x03, 0x46, 0x25, 0xff, 0x05, 0x3c, 0x24, 0xff, 0x07, 0x3a, 0x37, 0xff, 0x33, 0x63, 0x8f, 0xff, 0x61, 0x96, 0xc8, 0xff, 0x36, 0x6c, 0x7a, 0xff, 0x01, 0x3d, 0x22, 0xff, 0x01, 0x4a, 0x2a, 0xff, 0x04, 0x62, 0x3e, 0xff, 0x0e, 0x89, 0x5c, 0xff, 0x14, 0x9d, 0x6a, 0xff, 0x18, 0xa4, 0x6c, 0xff, 0x18, 0xa1, 0x6f, 0xff, 0x16, 0x9c, 0x6f, 0xff, 0x18, 0x94, 0x6c, 0xff, 0x18, 0x8d, 0x63, 0xff, 0x16, 0x88, 0x64, 0xff, 0x17, 0x8b, 0x79, 0xff, 0x1d, 0x99, 0x86, 0xff, 0x19, 0xa5, 0x7b, 0xff, 0x18, 0xa9, 0x76, 0xff, 0x22, 0xa7, 0x83, 0xff, 0x26, 0xa0, 0x85, 0xff, 0x4f, 0xc3, 0xae, 0xff, 0x32, 0xac, 0x91, 0xff, 0x10, 0x9a, 0x6f, 0xff, 0x0c, 0x9f, 0x6a, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0e, 0xa1, 0x69, 0xff, 0x13, 0x9d, 0x6d, 0xff, 0x1b, 0xa7, 0x76, 0xff, 0x10, 0xa2, 0x6f, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x08, 0xa7, 0x6b, 0xff, 0x10, 0xae, 0x72, 0xff, 0x14, 0xb2, 0x76, 0xff, 0x10, 0xaf, 0x75, 0xff, 0x0c, 0xaf, 0x76, 0xff, 0x0d, 0xb0, 0x79, 0xff, 0x18, 0xb4, 0x7d, 0xff, 0x21, 0xb3, 0x7e, 0xff, 0x27, 0xa6, 0x75, 0xff, 0x22, 0x8e, 0x62, 0xff, 0x15, 0x6e, 0x49, 0xff, 0x0c, 0x54, 0x33, 0xff, 0x05, 0x3f, 0x21, 0xff, 0x04, 0x32, 0x16, 0xff, 0x02, 0x1f, 0x09, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x17, 0x04, 0xff, 0x00, 0x15, 0x03, 0xff, 0x01, 0x13, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x11, 0x01, 0xff, 0x03, 0x10, 0x02, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x00, 0x11, 0x02, 0xff, 0x01, 0x14, 0x04, 0xff, 0x03, 0x18, 0x08, 0xff, 0x04, 0x20, 0x0e, 0xff, 0x05, 0x28, 0x14, 0xff, 0x06, 0x35, 0x1e, 0xff, 0x0a, 0x46, 0x2c, 0xff, 0x1a, 0x66, 0x4a, 0xff, 0x2c, 0x8c, 0x6b, 0xff, 0x33, 0xb4, 0x8c, 0xff, 0x27, 0xbc, 0x90, 0xff, 0x20, 0xba, 0x8d, 0xff, 0x21, 0xbb, 0x8e, 0xff, 0x23, 0xbc, 0x90, 0xff, 0x22, 0xbb, 0x8f, 0xff, 0x23, 0xb9, 0x8d, 0xff, 0x22, 0xb7, 0x8b, 0xff, 0x1e, 0xb2, 0x87, 0xff, 0x1d, 0xaf, 0x85, 0xff, 0x1b, 0xa9, 0x82, 0xff, 0x21, 0xab, 0x89, 0xff, 0x28, 0xab, 0x8e, 0xff, 0x2f, 0xad, 0x95, 0xff, 0x33, 0xab, 0x98, 0xff, 0x35, 0xab, 0x99, 0xff, 0x35, 0xab, 0x99, 0xff, 0x34, 0xac, 0x99, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x35, 0xab, 0x99, 0xff, 0x35, 0xad, 0x9a, 0xff, 0x35, 0xae, 0x9a, 0xff, 0x35, 0xae, 0x9b, 0xff, 0x35, 0xae, 0x99, 0xff, 0x33, 0xae, 0x99, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xaf, 0x9a, 0xff, 0x33, 0xaf, 0x9a, 0xff, 0x31, 0xae, 0x98, 0xff, 0x31, 0xae, 0x98, 0xff, 0x30, 0xad, 0x97, 0xff, 0x2e, 0xad, 0x95, 0xff, 0x2d, 0xae, 0x94, 0xff, 0x2c, 0xae, 0x93, 0xff, 0x2c, 0xac, 0x8e, 0xff, 0x2a, 0xac, 0x8a, 0xff, 0x22, 0xae, 0x87, 0xff, 0x1a, 0xae, 0x82, 0xff, 0x10, 0xad, 0x7b, 0xff, 0x0c, 0xad, 0x77, 0xff, 0x0e, 0xad, 0x76, 0xff, 0x10, 0xad, 0x75, 0xff, 0x08, 0xaf, 0x74, 0xff, 0x06, 0xad, 0x73, 0xff, 0x0d, 0xac, 0x72, 0xff, 0x11, 0xab, 0x73, 0xff, 0x13, 0xab, 0x74, 0xff, 0x13, 0xab, 0x74, 0xff, 0x15, 0xad, 0x77, 0xff, 0x17, 0xab, 0x77, 0xff, 0x1a, 0xa5, 0x74, 0xff, 0x1e, 0xa2, 0x72, 0xff, 0x1f, 0x97, 0x6b, 0xff, 0x18, 0x85, 0x5a, 0xff, 0x16, 0x6e, 0x48, 0xff, 0x16, 0x62, 0x3f, 0xff, 0x14, 0x53, 0x33, 0xff, 0x11, 0x49, 0x2b, 0xff, 0x0b, 0x3f, 0x24, 0xff, 0x06, 0x38, 0x1d, 0xff, 0x05, 0x36, 0x1b, 0xff, 0x06, 0x38, 0x1d, 0xff, 0x07, 0x3b, 0x20, 0xff, 0x0a, 0x3e, 0x23, 0xff, 0x09, 0x3f, 0x24, 0xff, 0x09, 0x40, 0x25, 0xff, 0x0b, 0x48, 0x2a, 0xff, 0x0d, 0x51, 0x31, 0xff, 0x0f, 0x58, 0x37, 0xff, 0x10, 0x62, 0x40, 0xff, 0x1d, 0x7f, 0x5a, 0xff, 0x1f, 0x8d, 0x65, 0xff, 0x1e, 0x9b, 0x70, 0xff, 0x25, 0xa9, 0x7c, 0xff, 0x21, 0xb0, 0x82, 0xff, 0x17, 0xad, 0x7e, 0xff, 0x13, 0xab, 0x7a, 0xff, 0x14, 0xab, 0x7a, 0xff, 0x14, 0xab, 0x78, 0xff, 0x10, 0xa7, 0x73, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x1a, 0xab, 0x82, 0xff, 0x1d, 0xac, 0x87, 0xff, 0x21, 0xad, 0x8c, 0xff, 0x23, 0xad, 0x8e, 0xff, 0x24, 0xad, 0x8e, 0xff, 0x22, 0xad, 0x8b, 0xff, 0x19, 0xad, 0x82, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x0c, 0xad, 0x72, 0xff, 0x11, 0xaf, 0x71, 0xff, 0x1a, 0xad, 0x70, 0xff, 0x1c, 0xa6, 0x6e, 0xff, 0x17, 0x91, 0x5e, 0xff, 0x12, 0x75, 0x4a, 0xff, 0x09, 0x53, 0x2d, 0xff, 0x05, 0x3b, 0x1b, 0xff, 0x03, 0x1f, 0x08, 0xff, 0x02, 0x15, 0x02, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x02, 0xff, 0x00, 0x10, 0x01, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x01, 0x0f, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x11, 0x02, 0xff, 0x00, 0x11, 0x02, 0xff, 0x01, 0x11, 0x01, 0xff, 0x03, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, 0xff, 0x03, 0x11, 0x01, 0xff, 0x02, 0x11, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x00, 0xff, 0x02, 0x12, 0x01, 0xff, 0x06, 0x11, 0x01, 0xff, 0x05, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x19, 0x06, 0xff, 0x0a, 0x3e, 0x26, 0xff, 0x23, 0x7a, 0x61, 0xff, 0x2b, 0xa7, 0x87, 0xff, 0x1f, 0xac, 0x86, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x06, 0xa4, 0x71, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x13, 0xa1, 0x6d, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x0f, 0x9f, 0x71, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0e, 0xa3, 0x73, 0xff, 0x17, 0x9f, 0x78, 0xff, 0x17, 0xa0, 0x70, 0xff, 0x12, 0xa7, 0x6c, 0xff, 0x12, 0xa5, 0x73, 0xff, 0x21, 0x99, 0xa0, 0xff, 0x1f, 0x81, 0xe2, 0xff, 0x0b, 0x2e, 0xeb, 0xff, 0x11, 0x1a, 0xea, 0xff, 0x1d, 0x1b, 0xc5, 0xff, 0x10, 0x1f, 0x7b, 0xff, 0x07, 0x2f, 0x58, 0xff, 0x08, 0x18, 0x8c, 0xff, 0x12, 0x0f, 0xb0, 0xff, 0x0d, 0x11, 0xa9, 0xff, 0x10, 0x29, 0x79, 0xff, 0x05, 0x39, 0x3f, 0xff, 0x04, 0x49, 0x29, 0xff, 0x02, 0x51, 0x2c, 0xff, 0x07, 0x70, 0x45, 0xff, 0x0e, 0x97, 0x5f, 0xff, 0x07, 0x98, 0x57, 0xff, 0x0c, 0x87, 0x5a, 0xff, 0x13, 0x73, 0x62, 0xff, 0x24, 0x70, 0x73, 0xff, 0x3c, 0x74, 0x8d, 0xff, 0x46, 0x76, 0x94, 0xff, 0x25, 0x52, 0x69, 0xff, 0x1a, 0x48, 0x54, 0xff, 0x10, 0x3e, 0x43, 0xff, 0x21, 0x4e, 0x59, 0xff, 0x4b, 0x7b, 0x8f, 0xff, 0x2e, 0x65, 0x79, 0xff, 0x26, 0x62, 0x76, 0xff, 0x26, 0x62, 0x75, 0xff, 0x2b, 0x64, 0x77, 0xff, 0x29, 0x5d, 0x73, 0xff, 0x28, 0x59, 0x74, 0xff, 0x28, 0x58, 0x71, 0xff, 0x24, 0x59, 0x6e, 0xff, 0x21, 0x58, 0x6f, 0xff, 0x16, 0x46, 0x62, 0xff, 0x12, 0x48, 0x58, 0xff, 0x10, 0x5c, 0x4b, 0xff, 0x0e, 0x65, 0x40, 0xff, 0x14, 0x64, 0x3f, 0xff, 0x0d, 0x54, 0x33, 0xff, 0x06, 0x44, 0x28, 0xff, 0x06, 0x45, 0x25, 0xff, 0x0d, 0x56, 0x2b, 0xff, 0x0e, 0x55, 0x31, 0xff, 0x78, 0x97, 0x96, 0xff, 0xcb, 0xc3, 0xd7, 0xff, 0x9e, 0xb4, 0xba, 0xff, 0x25, 0x6b, 0x53, 0xff, 0x17, 0x6e, 0x42, 0xff, 0x0b, 0x66, 0x39, 0xff, 0x06, 0x60, 0x36, 0xff, 0x0c, 0x62, 0x37, 0xff, 0x08, 0x49, 0x2d, 0xff, 0x00, 0x23, 0x14, 0xff, 0x63, 0x73, 0x68, 0xff, + 0x07, 0x36, 0x31, 0xff, 0x09, 0x3a, 0x39, 0xff, 0x02, 0x39, 0x2c, 0xff, 0x00, 0x45, 0x22, 0xff, 0x0d, 0x7d, 0x4e, 0xff, 0x16, 0x99, 0x69, 0xff, 0x11, 0x98, 0x69, 0xff, 0x0e, 0x97, 0x67, 0xff, 0x0d, 0x99, 0x68, 0xff, 0x0b, 0x99, 0x68, 0xff, 0x0d, 0x9a, 0x6a, 0xff, 0x10, 0x97, 0x68, 0xff, 0x16, 0x99, 0x69, 0xff, 0x19, 0x98, 0x67, 0xff, 0x17, 0x8c, 0x5f, 0xff, 0x0c, 0x6a, 0x4a, 0xff, 0x03, 0x54, 0x36, 0xff, 0x00, 0x46, 0x22, 0xff, 0x04, 0x42, 0x1f, 0xff, 0x01, 0x3d, 0x23, 0xff, 0x02, 0x3b, 0x37, 0xff, 0x35, 0x65, 0x92, 0xff, 0x65, 0x9b, 0xcb, 0xff, 0x2a, 0x6a, 0x72, 0xff, 0x00, 0x46, 0x25, 0xff, 0x08, 0x6b, 0x46, 0xff, 0x13, 0x89, 0x61, 0xff, 0x16, 0x9f, 0x6e, 0xff, 0x11, 0xa3, 0x6c, 0xff, 0x0e, 0xa4, 0x6b, 0xff, 0x10, 0xa4, 0x70, 0xff, 0x11, 0xa4, 0x73, 0xff, 0x13, 0xa2, 0x76, 0xff, 0x18, 0xa4, 0x75, 0xff, 0x19, 0xa5, 0x78, 0xff, 0x23, 0xaa, 0x8a, 0xff, 0x26, 0xaa, 0x8f, 0xff, 0x1b, 0xa5, 0x7b, 0xff, 0x1d, 0xa8, 0x78, 0xff, 0x1f, 0xa0, 0x7f, 0xff, 0x26, 0x9c, 0x84, 0xff, 0x2e, 0x9f, 0x8c, 0xff, 0x1d, 0x95, 0x7d, 0xff, 0x17, 0xa0, 0x76, 0xff, 0x18, 0xa7, 0x74, 0xff, 0x13, 0x9f, 0x6b, 0xff, 0x12, 0x9a, 0x69, 0xff, 0x1b, 0x9a, 0x70, 0xff, 0x2f, 0xb4, 0x87, 0xff, 0x1a, 0xa7, 0x76, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x67, 0xff, 0x0f, 0xa1, 0x69, 0xff, 0x11, 0xa3, 0x69, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x0e, 0xb2, 0x75, 0xff, 0x0d, 0xb0, 0x73, 0xff, 0x12, 0xac, 0x74, 0xff, 0x15, 0xab, 0x75, 0xff, 0x12, 0xad, 0x75, 0xff, 0x14, 0xaf, 0x77, 0xff, 0x17, 0xae, 0x78, 0xff, 0x19, 0xaa, 0x77, 0xff, 0x1d, 0xa6, 0x76, 0xff, 0x1c, 0x9c, 0x6f, 0xff, 0x1b, 0x90, 0x65, 0xff, 0x1a, 0x82, 0x5a, 0xff, 0x15, 0x62, 0x40, 0xff, 0x0b, 0x50, 0x2f, 0xff, 0x0c, 0x48, 0x2a, 0xff, 0x07, 0x3d, 0x21, 0xff, 0x07, 0x34, 0x19, 0xff, 0x06, 0x2f, 0x16, 0xff, 0x03, 0x25, 0x0e, 0xff, 0x02, 0x23, 0x0c, 0xff, 0x01, 0x21, 0x0c, 0xff, 0x02, 0x24, 0x0f, 0xff, 0x03, 0x2c, 0x15, 0xff, 0x03, 0x2b, 0x15, 0xff, 0x04, 0x2d, 0x16, 0xff, 0x05, 0x32, 0x1c, 0xff, 0x0d, 0x41, 0x2a, 0xff, 0x17, 0x50, 0x38, 0xff, 0x1b, 0x61, 0x46, 0xff, 0x1f, 0x73, 0x55, 0xff, 0x22, 0x86, 0x65, 0xff, 0x28, 0x96, 0x74, 0xff, 0x32, 0xaa, 0x84, 0xff, 0x31, 0xb4, 0x8c, 0xff, 0x28, 0xba, 0x8f, 0xff, 0x1f, 0xbb, 0x8e, 0xff, 0x1d, 0xb8, 0x8b, 0xff, 0x20, 0xb8, 0x8d, 0xff, 0x23, 0xba, 0x8f, 0xff, 0x25, 0xba, 0x90, 0xff, 0x24, 0xb8, 0x8e, 0xff, 0x21, 0xb5, 0x8b, 0xff, 0x1c, 0xae, 0x85, 0xff, 0x1b, 0xab, 0x83, 0xff, 0x1b, 0xa7, 0x83, 0xff, 0x21, 0xaa, 0x88, 0xff, 0x28, 0xaa, 0x8f, 0xff, 0x30, 0xad, 0x96, 0xff, 0x34, 0xaa, 0x98, 0xff, 0x35, 0xab, 0x99, 0xff, 0x35, 0xab, 0x99, 0xff, 0x34, 0xac, 0x99, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x35, 0xad, 0x9a, 0xff, 0x36, 0xaf, 0x9b, 0xff, 0x34, 0xb0, 0x9a, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x32, 0xae, 0x98, 0xff, 0x32, 0xae, 0x9a, 0xff, 0x33, 0xae, 0x9b, 0xff, 0x33, 0xae, 0x99, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xad, 0x97, 0xff, 0x30, 0xad, 0x97, 0xff, 0x2f, 0xae, 0x95, 0xff, 0x2f, 0xae, 0x95, 0xff, 0x31, 0xac, 0x91, 0xff, 0x2f, 0xac, 0x8f, 0xff, 0x26, 0xae, 0x8c, 0xff, 0x1d, 0xaf, 0x88, 0xff, 0x13, 0xae, 0x81, 0xff, 0x0d, 0xac, 0x7b, 0xff, 0x0a, 0xac, 0x77, 0xff, 0x0b, 0xad, 0x76, 0xff, 0x04, 0xae, 0x75, 0xff, 0x03, 0xae, 0x74, 0xff, 0x0d, 0xab, 0x73, 0xff, 0x13, 0xaa, 0x72, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x09, 0xab, 0x73, 0xff, 0x09, 0xad, 0x75, 0xff, 0x0e, 0xae, 0x77, 0xff, 0x15, 0xad, 0x78, 0xff, 0x1c, 0xab, 0x77, 0xff, 0x28, 0xa9, 0x78, 0xff, 0x2d, 0xa5, 0x76, 0xff, 0x2d, 0x9d, 0x72, 0xff, 0x2d, 0x98, 0x6e, 0xff, 0x28, 0x90, 0x69, 0xff, 0x20, 0x87, 0x61, 0xff, 0x1d, 0x84, 0x5e, 0xff, 0x21, 0x89, 0x63, 0xff, 0x24, 0x8f, 0x68, 0xff, 0x27, 0x92, 0x6a, 0xff, 0x25, 0x91, 0x6b, 0xff, 0x26, 0x93, 0x6c, 0xff, 0x23, 0x9a, 0x70, 0xff, 0x1f, 0x9f, 0x72, 0xff, 0x21, 0xa1, 0x75, 0xff, 0x1e, 0xa0, 0x73, 0xff, 0x21, 0xa8, 0x7a, 0xff, 0x1d, 0xa8, 0x79, 0xff, 0x17, 0xaa, 0x79, 0xff, 0x18, 0xae, 0x7c, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x12, 0xa7, 0x76, 0xff, 0x14, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x73, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x04, 0xa3, 0x6d, 0xff, 0x04, 0xa6, 0x6d, 0xff, 0x06, 0xa8, 0x70, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x14, 0xa8, 0x7c, 0xff, 0x1c, 0xae, 0x84, 0xff, 0x1e, 0xac, 0x87, 0xff, 0x22, 0xad, 0x8b, 0xff, 0x25, 0xaf, 0x8f, 0xff, 0x25, 0xae, 0x8f, 0xff, 0x24, 0xae, 0x8d, 0xff, 0x1d, 0xae, 0x87, 0xff, 0x16, 0xac, 0x7e, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x11, 0xa9, 0x6e, 0xff, 0x11, 0xab, 0x6e, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0b, 0xad, 0x71, 0xff, 0x18, 0xab, 0x73, 0xff, 0x1b, 0x9d, 0x69, 0xff, 0x1c, 0x88, 0x5a, 0xff, 0x12, 0x5e, 0x38, 0xff, 0x06, 0x3c, 0x1e, 0xff, 0x02, 0x22, 0x0b, 0xff, 0x01, 0x16, 0x04, 0xff, 0x00, 0x13, 0x00, 0xff, 0x00, 0x14, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x01, 0x10, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x01, 0x10, 0x02, 0xff, 0x03, 0x10, 0x00, 0xff, 0x04, 0x0f, 0x00, 0xff, 0x04, 0x0f, 0x00, 0xff, 0x04, 0x0f, 0x00, 0xff, 0x03, 0x0f, 0x00, 0xff, 0x02, 0x11, 0x01, 0xff, 0x03, 0x12, 0x02, 0xff, 0x02, 0x13, 0x02, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x12, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x02, 0x13, 0x03, 0xff, 0x02, 0x19, 0x07, 0xff, 0x04, 0x2a, 0x15, 0xff, 0x0a, 0x49, 0x2f, 0xff, 0x27, 0x87, 0x69, 0xff, 0x33, 0xa4, 0x84, 0xff, 0x23, 0xac, 0x87, 0xff, 0x18, 0xaa, 0x81, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x05, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa1, 0x70, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x09, 0xa1, 0x6f, 0xff, 0x12, 0x9e, 0x75, 0xff, 0x15, 0xa3, 0x72, 0xff, 0x0d, 0xab, 0x6c, 0xff, 0x07, 0xa6, 0x73, 0xff, 0x21, 0xa4, 0xbc, 0xff, 0x13, 0x7c, 0xe6, 0xff, 0x0c, 0x42, 0xed, 0xff, 0x0e, 0x27, 0xe9, 0xff, 0x18, 0x1d, 0xc2, 0xff, 0x0e, 0x23, 0x6e, 0xff, 0x06, 0x2c, 0x53, 0xff, 0x10, 0x17, 0x9f, 0xff, 0x10, 0x0e, 0xc3, 0xff, 0x06, 0x11, 0xbf, 0xff, 0x11, 0x1f, 0xa2, 0xff, 0x11, 0x46, 0x64, 0xff, 0x11, 0x7a, 0x53, 0xff, 0x0d, 0x85, 0x56, 0xff, 0x14, 0x8d, 0x5e, 0xff, 0x16, 0x97, 0x60, 0xff, 0x10, 0x96, 0x5a, 0xff, 0x08, 0x73, 0x57, 0xff, 0x18, 0x68, 0x69, 0xff, 0x34, 0x77, 0x85, 0xff, 0x46, 0x7a, 0x94, 0xff, 0x4c, 0x7b, 0x96, 0xff, 0x27, 0x54, 0x6a, 0xff, 0x11, 0x3d, 0x4d, 0xff, 0x11, 0x39, 0x47, 0xff, 0x17, 0x42, 0x4e, 0xff, 0x4d, 0x7d, 0x8c, 0xff, 0x31, 0x68, 0x7a, 0xff, 0x29, 0x64, 0x78, 0xff, 0x27, 0x62, 0x74, 0xff, 0x2b, 0x62, 0x75, 0xff, 0x2e, 0x62, 0x77, 0xff, 0x2b, 0x5c, 0x75, 0xff, 0x2c, 0x5b, 0x75, 0xff, 0x2d, 0x61, 0x75, 0xff, 0x1d, 0x53, 0x66, 0xff, 0x13, 0x42, 0x5b, 0xff, 0x13, 0x44, 0x56, 0xff, 0x0c, 0x55, 0x4a, 0xff, 0x0c, 0x64, 0x41, 0xff, 0x13, 0x68, 0x3c, 0xff, 0x14, 0x5f, 0x37, 0xff, 0x08, 0x49, 0x2b, 0xff, 0x06, 0x46, 0x2a, 0xff, 0x0e, 0x57, 0x36, 0xff, 0x11, 0x52, 0x3e, 0xff, 0xa8, 0xae, 0xc2, 0xff, 0xdc, 0xbf, 0xe2, 0xff, 0x9c, 0xac, 0xb3, 0xff, 0x1f, 0x64, 0x4b, 0xff, 0x11, 0x68, 0x3c, 0xff, 0x0e, 0x68, 0x3c, 0xff, 0x05, 0x5d, 0x34, 0xff, 0x0f, 0x63, 0x39, 0xff, 0x07, 0x46, 0x2d, 0xff, 0x00, 0x23, 0x17, 0xff, 0x64, 0x73, 0x6b, 0xff, + 0x05, 0x3b, 0x29, 0xff, 0x04, 0x3c, 0x29, 0xff, 0x05, 0x3f, 0x26, 0xff, 0x02, 0x48, 0x25, 0xff, 0x20, 0x81, 0x59, 0xff, 0x1e, 0x90, 0x65, 0xff, 0x10, 0x87, 0x5b, 0xff, 0x14, 0x97, 0x66, 0xff, 0x0e, 0x9a, 0x66, 0xff, 0x08, 0x9b, 0x65, 0xff, 0x09, 0x9a, 0x66, 0xff, 0x14, 0x99, 0x6a, 0xff, 0x1f, 0x95, 0x6a, 0xff, 0x13, 0x7d, 0x53, 0xff, 0x06, 0x64, 0x3d, 0xff, 0x02, 0x4a, 0x2d, 0xff, 0x01, 0x3f, 0x26, 0xff, 0x03, 0x3f, 0x1f, 0xff, 0x07, 0x3f, 0x21, 0xff, 0x01, 0x3f, 0x24, 0xff, 0x01, 0x3c, 0x32, 0xff, 0x38, 0x6b, 0x8d, 0xff, 0x67, 0xa1, 0xc6, 0xff, 0x2c, 0x7c, 0x79, 0xff, 0x13, 0x7c, 0x51, 0xff, 0x1a, 0x9b, 0x6c, 0xff, 0x14, 0x9e, 0x6f, 0xff, 0x11, 0xa1, 0x70, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x0d, 0xa2, 0x6f, 0xff, 0x0e, 0xa2, 0x74, 0xff, 0x10, 0xa4, 0x75, 0xff, 0x16, 0xa6, 0x76, 0xff, 0x27, 0xae, 0x87, 0xff, 0x29, 0xaa, 0x8c, 0xff, 0x1b, 0x9e, 0x79, 0xff, 0x1b, 0xa1, 0x74, 0xff, 0x20, 0xa5, 0x7f, 0xff, 0x27, 0xa2, 0x86, 0xff, 0x23, 0x98, 0x82, 0xff, 0x1f, 0x99, 0x7e, 0xff, 0x1f, 0xa6, 0x7d, 0xff, 0x1b, 0xa4, 0x77, 0xff, 0x1a, 0x99, 0x70, 0xff, 0x1e, 0x95, 0x71, 0xff, 0x31, 0xa7, 0x81, 0xff, 0x27, 0xa1, 0x7a, 0xff, 0x1c, 0xa1, 0x76, 0xff, 0x15, 0xa2, 0x71, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x11, 0xa7, 0x6b, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0c, 0x9e, 0x66, 0xff, 0x11, 0xa0, 0x66, 0xff, 0x10, 0xa2, 0x68, 0xff, 0x09, 0xa6, 0x6b, 0xff, 0x09, 0xb2, 0x74, 0xff, 0x0a, 0xb0, 0x75, 0xff, 0x14, 0xa6, 0x71, 0xff, 0x1e, 0xa7, 0x73, 0xff, 0x15, 0xa9, 0x72, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x0f, 0xaa, 0x72, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x10, 0xa5, 0x72, 0xff, 0x16, 0xa6, 0x75, 0xff, 0x1b, 0xaa, 0x79, 0xff, 0x1c, 0xab, 0x7a, 0xff, 0x1c, 0xa8, 0x78, 0xff, 0x25, 0xa6, 0x79, 0xff, 0x26, 0xa1, 0x76, 0xff, 0x29, 0x9d, 0x72, 0xff, 0x27, 0x96, 0x6d, 0xff, 0x1d, 0x8b, 0x63, 0xff, 0x1a, 0x87, 0x5f, 0xff, 0x1b, 0x87, 0x5f, 0xff, 0x1c, 0x89, 0x62, 0xff, 0x22, 0x91, 0x6b, 0xff, 0x22, 0x95, 0x6e, 0xff, 0x20, 0x98, 0x71, 0xff, 0x21, 0x9b, 0x75, 0xff, 0x24, 0xa1, 0x7b, 0xff, 0x24, 0xa4, 0x7c, 0xff, 0x25, 0xa7, 0x7f, 0xff, 0x25, 0xab, 0x82, 0xff, 0x25, 0xb2, 0x87, 0xff, 0x23, 0xb6, 0x8a, 0xff, 0x22, 0xba, 0x8d, 0xff, 0x1e, 0xb7, 0x8a, 0xff, 0x1f, 0xb4, 0x88, 0xff, 0x1d, 0xb2, 0x86, 0xff, 0x1c, 0xb3, 0x86, 0xff, 0x21, 0xb6, 0x8b, 0xff, 0x22, 0xb5, 0x8b, 0xff, 0x20, 0xb3, 0x89, 0xff, 0x20, 0xb4, 0x8c, 0xff, 0x1e, 0xb1, 0x89, 0xff, 0x1b, 0xaa, 0x84, 0xff, 0x1d, 0xaa, 0x84, 0xff, 0x1e, 0xa8, 0x85, 0xff, 0x24, 0xa9, 0x8b, 0xff, 0x29, 0xa9, 0x8f, 0xff, 0x30, 0xab, 0x96, 0xff, 0x34, 0xab, 0x99, 0xff, 0x35, 0xab, 0x99, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x35, 0xad, 0x99, 0xff, 0x38, 0xac, 0x9c, 0xff, 0x37, 0xab, 0x9c, 0xff, 0x36, 0xac, 0x9b, 0xff, 0x35, 0xac, 0x9a, 0xff, 0x36, 0xae, 0x9b, 0xff, 0x34, 0xb0, 0x9a, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x31, 0xae, 0x98, 0xff, 0x32, 0xad, 0x9a, 0xff, 0x32, 0xad, 0x99, 0xff, 0x35, 0xae, 0x9a, 0xff, 0x35, 0xae, 0x99, 0xff, 0x35, 0xaf, 0x9a, 0xff, 0x33, 0xae, 0x99, 0xff, 0x32, 0xaf, 0x99, 0xff, 0x30, 0xae, 0x98, 0xff, 0x31, 0xae, 0x96, 0xff, 0x2f, 0xae, 0x94, 0xff, 0x2a, 0xae, 0x92, 0xff, 0x25, 0xaf, 0x8e, 0xff, 0x21, 0xaf, 0x89, 0xff, 0x1b, 0xae, 0x83, 0xff, 0x14, 0xad, 0x7e, 0xff, 0x0f, 0xaf, 0x7c, 0xff, 0x0c, 0xad, 0x79, 0xff, 0x0d, 0xab, 0x77, 0xff, 0x0f, 0xa9, 0x75, 0xff, 0x0f, 0xa9, 0x73, 0xff, 0x0d, 0xaa, 0x73, 0xff, 0x0c, 0xaa, 0x73, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x11, 0xa5, 0x71, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x11, 0xa0, 0x6d, 0xff, 0x16, 0xa1, 0x70, 0xff, 0x19, 0xa4, 0x73, 0xff, 0x18, 0xa5, 0x74, 0xff, 0x18, 0xa6, 0x75, 0xff, 0x17, 0xa6, 0x75, 0xff, 0x18, 0xa8, 0x76, 0xff, 0x17, 0xa8, 0x77, 0xff, 0x15, 0xaa, 0x77, 0xff, 0x13, 0xaa, 0x77, 0xff, 0x18, 0xae, 0x7b, 0xff, 0x1a, 0xad, 0x7c, 0xff, 0x17, 0xa9, 0x77, 0xff, 0x16, 0xa8, 0x76, 0xff, 0x15, 0xa7, 0x75, 0xff, 0x12, 0xa6, 0x74, 0xff, 0x0e, 0xa2, 0x70, 0xff, 0x0d, 0xa2, 0x6f, 0xff, 0x0d, 0xa0, 0x6e, 0xff, 0x0c, 0xa1, 0x6e, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x07, 0xa5, 0x6f, 0xff, 0x05, 0xa7, 0x6f, 0xff, 0x04, 0xa8, 0x6f, 0xff, 0x05, 0xa7, 0x6d, 0xff, 0x06, 0xa7, 0x6d, 0xff, 0x09, 0xa6, 0x6f, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x14, 0xa9, 0x7c, 0xff, 0x17, 0xaa, 0x7f, 0xff, 0x1b, 0xad, 0x83, 0xff, 0x1d, 0xab, 0x85, 0xff, 0x21, 0xad, 0x89, 0xff, 0x24, 0xaf, 0x8c, 0xff, 0x23, 0xad, 0x8c, 0xff, 0x25, 0xae, 0x8d, 0xff, 0x23, 0xae, 0x8b, 0xff, 0x1f, 0xad, 0x86, 0xff, 0x1a, 0xab, 0x7c, 0xff, 0x14, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x08, 0xa7, 0x6d, 0xff, 0x08, 0xa9, 0x6c, 0xff, 0x11, 0xaa, 0x6e, 0xff, 0x10, 0xa9, 0x6e, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x19, 0xa8, 0x73, 0xff, 0x1f, 0x9f, 0x6e, 0xff, 0x1d, 0x88, 0x5c, 0xff, 0x19, 0x72, 0x4b, 0xff, 0x15, 0x5c, 0x38, 0xff, 0x12, 0x4e, 0x2b, 0xff, 0x07, 0x3a, 0x1b, 0xff, 0x03, 0x32, 0x13, 0xff, 0x03, 0x27, 0x0c, 0xff, 0x03, 0x20, 0x08, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x16, 0x03, 0xff, 0x02, 0x12, 0x02, 0xff, 0x02, 0x11, 0x01, 0xff, 0x02, 0x11, 0x01, 0xff, 0x02, 0x11, 0x01, 0xff, 0x02, 0x13, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x14, 0x02, 0xff, 0x01, 0x16, 0x05, 0xff, 0x02, 0x20, 0x0b, 0xff, 0x03, 0x26, 0x11, 0xff, 0x05, 0x34, 0x1e, 0xff, 0x0a, 0x48, 0x2f, 0xff, 0x15, 0x60, 0x45, 0xff, 0x20, 0x73, 0x58, 0xff, 0x2f, 0x8f, 0x72, 0xff, 0x2f, 0xa3, 0x82, 0xff, 0x25, 0xab, 0x87, 0xff, 0x21, 0xaa, 0x85, 0xff, 0x14, 0xa7, 0x7d, 0xff, 0x12, 0xa3, 0x76, 0xff, 0x0e, 0xa1, 0x6f, 0xff, 0x07, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x6f, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x0b, 0xa2, 0x72, 0xff, 0x0f, 0xa4, 0x74, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x09, 0xa4, 0x76, 0xff, 0x1e, 0xa2, 0xc2, 0xff, 0x17, 0x83, 0xed, 0xff, 0x12, 0x60, 0xf5, 0xff, 0x1a, 0x47, 0xec, 0xff, 0x13, 0x27, 0xa3, 0xff, 0x0b, 0x2c, 0x56, 0xff, 0x0d, 0x2c, 0x50, 0xff, 0x18, 0x16, 0xa9, 0xff, 0x0d, 0x0f, 0xcb, 0xff, 0x09, 0x11, 0xcd, 0xff, 0x19, 0x14, 0xcc, 0xff, 0x0e, 0x40, 0x7c, 0xff, 0x17, 0x99, 0x76, 0xff, 0x09, 0x9e, 0x6b, 0xff, 0x13, 0x9a, 0x62, 0xff, 0x0e, 0x8c, 0x56, 0xff, 0x15, 0x8a, 0x62, 0xff, 0x16, 0x6a, 0x65, 0xff, 0x2b, 0x68, 0x7a, 0xff, 0x3e, 0x75, 0x89, 0xff, 0x55, 0x85, 0x9b, 0xff, 0x50, 0x80, 0x92, 0xff, 0x19, 0x46, 0x55, 0xff, 0x0e, 0x38, 0x46, 0xff, 0x0e, 0x34, 0x45, 0xff, 0x0e, 0x36, 0x43, 0xff, 0x48, 0x77, 0x85, 0xff, 0x3b, 0x6f, 0x82, 0xff, 0x27, 0x61, 0x77, 0xff, 0x29, 0x62, 0x78, 0xff, 0x2c, 0x61, 0x75, 0xff, 0x2d, 0x61, 0x75, 0xff, 0x34, 0x65, 0x7b, 0xff, 0x36, 0x63, 0x7d, 0xff, 0x1a, 0x4a, 0x60, 0xff, 0x13, 0x45, 0x56, 0xff, 0x1b, 0x43, 0x5b, 0xff, 0x19, 0x43, 0x5c, 0xff, 0x0d, 0x4f, 0x4f, 0xff, 0x0d, 0x62, 0x46, 0xff, 0x0e, 0x68, 0x38, 0xff, 0x13, 0x6b, 0x39, 0xff, 0x0c, 0x58, 0x36, 0xff, 0x05, 0x49, 0x34, 0xff, 0x0a, 0x61, 0x52, 0xff, 0x30, 0x74, 0x79, 0xff, 0xbc, 0xaf, 0xdd, 0xff, 0xdb, 0xbb, 0xea, 0xff, 0x77, 0x95, 0x91, 0xff, 0x0f, 0x5c, 0x3a, 0xff, 0x0d, 0x63, 0x3c, 0xff, 0x0e, 0x68, 0x3c, 0xff, 0x0a, 0x60, 0x36, 0xff, 0x10, 0x61, 0x38, 0xff, 0x06, 0x43, 0x27, 0xff, 0x03, 0x28, 0x17, 0xff, 0x63, 0x72, 0x6c, 0xff, + 0x04, 0x3e, 0x25, 0xff, 0x03, 0x3f, 0x22, 0xff, 0x06, 0x41, 0x22, 0xff, 0x04, 0x49, 0x28, 0xff, 0x20, 0x78, 0x54, 0xff, 0x0d, 0x6d, 0x44, 0xff, 0x05, 0x68, 0x3e, 0xff, 0x17, 0x96, 0x65, 0xff, 0x0e, 0x9a, 0x64, 0xff, 0x07, 0x9d, 0x63, 0xff, 0x09, 0x9c, 0x64, 0xff, 0x17, 0x98, 0x68, 0xff, 0x13, 0x81, 0x58, 0xff, 0x04, 0x5d, 0x36, 0xff, 0x01, 0x51, 0x2a, 0xff, 0x01, 0x44, 0x22, 0xff, 0x01, 0x3d, 0x23, 0xff, 0x05, 0x41, 0x25, 0xff, 0x08, 0x3d, 0x23, 0xff, 0x03, 0x3c, 0x24, 0xff, 0x02, 0x3d, 0x2e, 0xff, 0x31, 0x69, 0x7b, 0xff, 0x52, 0x91, 0xa5, 0xff, 0x33, 0x86, 0x7c, 0xff, 0x20, 0x92, 0x61, 0xff, 0x18, 0xa0, 0x6c, 0xff, 0x0f, 0xa0, 0x6e, 0xff, 0x0d, 0xa0, 0x6e, 0xff, 0x0b, 0xa1, 0x6f, 0xff, 0x06, 0xa1, 0x6e, 0xff, 0x06, 0xa1, 0x71, 0xff, 0x0d, 0xa2, 0x70, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x11, 0xa3, 0x76, 0xff, 0x18, 0xa4, 0x74, 0xff, 0x21, 0xa3, 0x7b, 0xff, 0x21, 0xa0, 0x81, 0xff, 0x1b, 0xa1, 0x7e, 0xff, 0x19, 0xa5, 0x79, 0xff, 0x1a, 0xa5, 0x7b, 0xff, 0x22, 0xa3, 0x83, 0xff, 0x27, 0xa1, 0x87, 0xff, 0x1d, 0x9b, 0x7d, 0xff, 0x1d, 0xa4, 0x7c, 0xff, 0x1c, 0xa3, 0x78, 0xff, 0x22, 0x9a, 0x77, 0xff, 0x3c, 0xab, 0x8d, 0xff, 0x65, 0xd5, 0xb3, 0xff, 0x33, 0xa9, 0x84, 0xff, 0x22, 0xa3, 0x79, 0xff, 0x18, 0xa2, 0x72, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x0e, 0xa3, 0x6a, 0xff, 0x11, 0xa6, 0x6a, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x05, 0x9f, 0x65, 0xff, 0x08, 0x9f, 0x64, 0xff, 0x0d, 0xa0, 0x66, 0xff, 0x0b, 0xa1, 0x67, 0xff, 0x0e, 0xac, 0x70, 0xff, 0x0e, 0xac, 0x73, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0f, 0xa7, 0x71, 0xff, 0x11, 0xa9, 0x74, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x13, 0xab, 0x79, 0xff, 0x13, 0xab, 0x77, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x11, 0xa8, 0x73, 0xff, 0x17, 0xa8, 0x75, 0xff, 0x19, 0xa8, 0x76, 0xff, 0x1c, 0xa7, 0x76, 0xff, 0x1c, 0xa6, 0x76, 0xff, 0x19, 0xa4, 0x74, 0xff, 0x17, 0xa2, 0x73, 0xff, 0x1d, 0x9d, 0x6f, 0xff, 0x1b, 0x9c, 0x6f, 0xff, 0x1b, 0xa0, 0x72, 0xff, 0x1b, 0xa3, 0x76, 0xff, 0x1d, 0xaa, 0x7d, 0xff, 0x1c, 0xad, 0x7f, 0xff, 0x1a, 0xae, 0x80, 0xff, 0x1c, 0xb1, 0x83, 0xff, 0x1c, 0xb4, 0x85, 0xff, 0x21, 0xb6, 0x88, 0xff, 0x25, 0xba, 0x8c, 0xff, 0x22, 0xba, 0x8c, 0xff, 0x1b, 0xb7, 0x89, 0xff, 0x16, 0xb4, 0x85, 0xff, 0x17, 0xaf, 0x82, 0xff, 0x19, 0xae, 0x80, 0xff, 0x1b, 0xae, 0x82, 0xff, 0x1e, 0xb0, 0x86, 0xff, 0x1f, 0xae, 0x85, 0xff, 0x1c, 0xac, 0x84, 0xff, 0x1c, 0xae, 0x87, 0xff, 0x1e, 0xaf, 0x89, 0xff, 0x1e, 0xab, 0x88, 0xff, 0x22, 0xab, 0x89, 0xff, 0x22, 0xaa, 0x89, 0xff, 0x27, 0xab, 0x8e, 0xff, 0x2b, 0xa9, 0x91, 0xff, 0x31, 0xab, 0x97, 0xff, 0x35, 0xab, 0x9a, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x35, 0xad, 0x9a, 0xff, 0x39, 0xac, 0x9d, 0xff, 0x37, 0xac, 0x9d, 0xff, 0x36, 0xac, 0x9a, 0xff, 0x35, 0xac, 0x9a, 0xff, 0x34, 0xad, 0x9a, 0xff, 0x33, 0xae, 0x99, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x31, 0xaf, 0x99, 0xff, 0x33, 0xae, 0x9a, 0xff, 0x33, 0xad, 0x99, 0xff, 0x35, 0xae, 0x9a, 0xff, 0x35, 0xae, 0x99, 0xff, 0x35, 0xae, 0x99, 0xff, 0x34, 0xae, 0x99, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x31, 0xaf, 0x99, 0xff, 0x2f, 0xb0, 0x98, 0xff, 0x2d, 0xaf, 0x97, 0xff, 0x2d, 0xaf, 0x95, 0xff, 0x2c, 0xae, 0x92, 0xff, 0x2c, 0xaf, 0x8e, 0xff, 0x28, 0xae, 0x88, 0xff, 0x1f, 0xae, 0x83, 0xff, 0x18, 0xaf, 0x7f, 0xff, 0x17, 0xad, 0x7e, 0xff, 0x18, 0xab, 0x7d, 0xff, 0x17, 0xaa, 0x7a, 0xff, 0x13, 0xaa, 0x77, 0xff, 0x0c, 0xaa, 0x73, 0xff, 0x0b, 0xaa, 0x74, 0xff, 0x0c, 0xa8, 0x74, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x10, 0xa7, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x09, 0x9e, 0x69, 0xff, 0x0c, 0x9e, 0x69, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x11, 0xa2, 0x6e, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x11, 0xa6, 0x71, 0xff, 0x14, 0xaa, 0x75, 0xff, 0x13, 0xaa, 0x75, 0xff, 0x13, 0xaa, 0x75, 0xff, 0x16, 0xaa, 0x77, 0xff, 0x18, 0xac, 0x79, 0xff, 0x17, 0xa8, 0x77, 0xff, 0x12, 0xa3, 0x71, 0xff, 0x11, 0xa1, 0x70, 0xff, 0x0e, 0x9d, 0x6e, 0xff, 0x0b, 0x9b, 0x6b, 0xff, 0x09, 0x99, 0x69, 0xff, 0x0a, 0x9b, 0x6a, 0xff, 0x0b, 0xa0, 0x6e, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x08, 0xa7, 0x6d, 0xff, 0x06, 0xa7, 0x6c, 0xff, 0x08, 0xa6, 0x6d, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x11, 0xa6, 0x78, 0xff, 0x14, 0xa9, 0x7b, 0xff, 0x17, 0xaa, 0x7e, 0xff, 0x19, 0xab, 0x80, 0xff, 0x1b, 0xab, 0x81, 0xff, 0x1e, 0xab, 0x84, 0xff, 0x20, 0xad, 0x86, 0xff, 0x22, 0xad, 0x88, 0xff, 0x25, 0xae, 0x8b, 0xff, 0x28, 0xad, 0x8b, 0xff, 0x26, 0xad, 0x88, 0xff, 0x1d, 0xac, 0x82, 0xff, 0x15, 0xa9, 0x7c, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x15, 0xa6, 0x73, 0xff, 0x14, 0xa4, 0x6e, 0xff, 0x0d, 0xa5, 0x6b, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6b, 0xff, 0x11, 0xa6, 0x6f, 0xff, 0x13, 0xa5, 0x6e, 0xff, 0x18, 0xa5, 0x6f, 0xff, 0x1a, 0xa1, 0x6c, 0xff, 0x19, 0x9a, 0x67, 0xff, 0x1e, 0x92, 0x62, 0xff, 0x18, 0x85, 0x58, 0xff, 0x17, 0x7c, 0x51, 0xff, 0x19, 0x71, 0x4b, 0xff, 0x18, 0x67, 0x43, 0xff, 0x14, 0x5a, 0x3a, 0xff, 0x0e, 0x4e, 0x30, 0xff, 0x09, 0x3e, 0x24, 0xff, 0x09, 0x3a, 0x21, 0xff, 0x0a, 0x3b, 0x22, 0xff, 0x0b, 0x3f, 0x25, 0xff, 0x0d, 0x45, 0x2b, 0xff, 0x0c, 0x45, 0x2b, 0xff, 0x0d, 0x4c, 0x31, 0xff, 0x14, 0x56, 0x3b, 0xff, 0x1e, 0x66, 0x4a, 0xff, 0x21, 0x6e, 0x54, 0xff, 0x22, 0x81, 0x65, 0xff, 0x20, 0x91, 0x72, 0xff, 0x24, 0xa0, 0x7f, 0xff, 0x29, 0xa6, 0x85, 0xff, 0x2c, 0xaa, 0x88, 0xff, 0x28, 0xaa, 0x88, 0xff, 0x1f, 0xa9, 0x84, 0xff, 0x16, 0xa6, 0x7d, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x10, 0xa0, 0x71, 0xff, 0x13, 0xa1, 0x6e, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x05, 0xa3, 0x6d, 0xff, 0x08, 0xa3, 0x74, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0f, 0xa0, 0x75, 0xff, 0x20, 0x9f, 0xbc, 0xff, 0x20, 0x8f, 0xed, 0xff, 0x1c, 0x72, 0xf6, 0xff, 0x22, 0x53, 0xd9, 0xff, 0x0b, 0x29, 0x74, 0xff, 0x0a, 0x38, 0x40, 0xff, 0x0c, 0x2d, 0x4b, 0xff, 0x1e, 0x1d, 0xac, 0xff, 0x1d, 0x16, 0xd8, 0xff, 0x1e, 0x16, 0xdc, 0xff, 0x2c, 0x1c, 0xdf, 0xff, 0x13, 0x41, 0x81, 0xff, 0x19, 0x98, 0x72, 0xff, 0x03, 0x95, 0x5b, 0xff, 0x0b, 0x91, 0x5b, 0xff, 0x06, 0x7e, 0x4c, 0xff, 0x11, 0x79, 0x5d, 0xff, 0x1e, 0x65, 0x6a, 0xff, 0x41, 0x74, 0x8a, 0xff, 0x51, 0x80, 0x96, 0xff, 0x61, 0x8f, 0xa2, 0xff, 0x40, 0x6f, 0x7d, 0xff, 0x0e, 0x3d, 0x47, 0xff, 0x11, 0x3c, 0x45, 0xff, 0x0e, 0x33, 0x40, 0xff, 0x05, 0x2a, 0x36, 0xff, 0x3d, 0x6a, 0x78, 0xff, 0x3e, 0x71, 0x86, 0xff, 0x2a, 0x63, 0x7b, 0xff, 0x2a, 0x62, 0x79, 0xff, 0x38, 0x6d, 0x81, 0xff, 0x43, 0x76, 0x8a, 0xff, 0x3c, 0x6c, 0x81, 0xff, 0x26, 0x51, 0x6c, 0xff, 0x14, 0x42, 0x59, 0xff, 0x17, 0x47, 0x57, 0xff, 0x1d, 0x43, 0x5a, 0xff, 0x1b, 0x43, 0x5d, 0xff, 0x0c, 0x4b, 0x50, 0xff, 0x0d, 0x5f, 0x48, 0xff, 0x0c, 0x67, 0x36, 0xff, 0x08, 0x69, 0x30, 0xff, 0x0e, 0x65, 0x3f, 0xff, 0x12, 0x66, 0x55, 0xff, 0x44, 0xb5, 0xb3, 0xff, 0x5e, 0xb0, 0xc4, 0xff, 0xb1, 0xa2, 0xdc, 0xff, 0xc9, 0xb1, 0xe2, 0xff, 0x49, 0x7a, 0x6b, 0xff, 0x0a, 0x60, 0x35, 0xff, 0x0c, 0x62, 0x3d, 0xff, 0x0e, 0x68, 0x39, 0xff, 0x0c, 0x64, 0x33, 0xff, 0x0f, 0x60, 0x37, 0xff, 0x05, 0x40, 0x20, 0xff, 0x08, 0x2e, 0x18, 0xff, 0x62, 0x71, 0x68, 0xff, + 0x06, 0x3d, 0x23, 0xff, 0x04, 0x3e, 0x20, 0xff, 0x03, 0x40, 0x21, 0xff, 0x03, 0x45, 0x29, 0xff, 0x09, 0x51, 0x32, 0xff, 0x01, 0x47, 0x24, 0xff, 0x06, 0x5a, 0x33, 0xff, 0x1d, 0x92, 0x63, 0xff, 0x10, 0x9b, 0x66, 0xff, 0x05, 0x9c, 0x67, 0xff, 0x10, 0x9a, 0x68, 0xff, 0x12, 0x7c, 0x53, 0xff, 0x08, 0x5c, 0x38, 0xff, 0x00, 0x42, 0x21, 0xff, 0x00, 0x41, 0x1a, 0xff, 0x02, 0x43, 0x19, 0xff, 0x03, 0x40, 0x1f, 0xff, 0x07, 0x3e, 0x22, 0xff, 0x0b, 0x3d, 0x25, 0xff, 0x08, 0x3f, 0x25, 0xff, 0x02, 0x42, 0x28, 0xff, 0x12, 0x57, 0x4a, 0xff, 0x18, 0x66, 0x59, 0xff, 0x0a, 0x65, 0x44, 0xff, 0x06, 0x6c, 0x35, 0xff, 0x0a, 0x86, 0x4c, 0xff, 0x14, 0x9e, 0x68, 0xff, 0x0d, 0x9e, 0x6b, 0xff, 0x0b, 0xa0, 0x6e, 0xff, 0x05, 0x9f, 0x6b, 0xff, 0x08, 0xa1, 0x6e, 0xff, 0x16, 0xa3, 0x72, 0xff, 0x12, 0x9c, 0x6e, 0xff, 0x13, 0xa5, 0x76, 0xff, 0x17, 0xa7, 0x78, 0xff, 0x19, 0xa3, 0x78, 0xff, 0x18, 0x9e, 0x78, 0xff, 0x1b, 0xa4, 0x7b, 0xff, 0x12, 0xa6, 0x78, 0xff, 0x18, 0xa6, 0x7e, 0xff, 0x1a, 0x9f, 0x7d, 0xff, 0x1b, 0x9a, 0x7b, 0xff, 0x1a, 0x9c, 0x7a, 0xff, 0x1f, 0xa7, 0x81, 0xff, 0x1d, 0xa1, 0x7b, 0xff, 0x28, 0x9d, 0x7d, 0xff, 0x4e, 0xb9, 0x9d, 0xff, 0x5e, 0xcc, 0xac, 0xff, 0x1f, 0x97, 0x6f, 0xff, 0x1a, 0x9d, 0x6b, 0xff, 0x20, 0xab, 0x75, 0xff, 0x14, 0xa7, 0x6f, 0xff, 0x0f, 0xa2, 0x6b, 0xff, 0x12, 0xa2, 0x6b, 0xff, 0x10, 0xa3, 0x6b, 0xff, 0x03, 0x9f, 0x66, 0xff, 0x05, 0x9e, 0x63, 0xff, 0x09, 0x9e, 0x62, 0xff, 0x0a, 0x9b, 0x61, 0xff, 0x0d, 0x9f, 0x68, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x0e, 0xaa, 0x72, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0a, 0xa6, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x11, 0xaa, 0x74, 0xff, 0x1a, 0xb2, 0x7f, 0xff, 0x1c, 0xb6, 0x84, 0xff, 0x1a, 0xb4, 0x80, 0xff, 0x17, 0xb0, 0x7a, 0xff, 0x17, 0xb0, 0x79, 0xff, 0x1c, 0xb3, 0x7e, 0xff, 0x1d, 0xb4, 0x7e, 0xff, 0x17, 0xad, 0x78, 0xff, 0x14, 0xab, 0x77, 0xff, 0x12, 0xa9, 0x77, 0xff, 0x11, 0xa8, 0x75, 0xff, 0x17, 0xa6, 0x73, 0xff, 0x18, 0xa8, 0x75, 0xff, 0x18, 0xab, 0x78, 0xff, 0x18, 0xac, 0x7a, 0xff, 0x1b, 0xb3, 0x81, 0xff, 0x1d, 0xb7, 0x85, 0xff, 0x1c, 0xb8, 0x86, 0xff, 0x1d, 0xbb, 0x88, 0xff, 0x21, 0xbd, 0x8c, 0xff, 0x22, 0xbb, 0x8b, 0xff, 0x21, 0xb8, 0x89, 0xff, 0x1f, 0xb7, 0x88, 0xff, 0x16, 0xb1, 0x82, 0xff, 0x12, 0xad, 0x7e, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x15, 0xa9, 0x7c, 0xff, 0x1b, 0xaa, 0x80, 0xff, 0x1c, 0xa8, 0x82, 0xff, 0x1c, 0xa7, 0x81, 0xff, 0x1e, 0xa9, 0x84, 0xff, 0x20, 0xaa, 0x88, 0xff, 0x23, 0xad, 0x8c, 0xff, 0x25, 0xab, 0x8d, 0xff, 0x27, 0xac, 0x8e, 0xff, 0x29, 0xaa, 0x8e, 0xff, 0x2b, 0xab, 0x92, 0xff, 0x2d, 0xaa, 0x95, 0xff, 0x33, 0xad, 0x99, 0xff, 0x35, 0xac, 0x9a, 0xff, 0x35, 0xac, 0x9a, 0xff, 0x37, 0xad, 0x9b, 0xff, 0x37, 0xae, 0x9a, 0xff, 0x37, 0xad, 0x9b, 0xff, 0x36, 0xad, 0x9b, 0xff, 0x35, 0xad, 0x9a, 0xff, 0x34, 0xac, 0x99, 0xff, 0x33, 0xad, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x33, 0xaf, 0x98, 0xff, 0x33, 0xb0, 0x99, 0xff, 0x34, 0xaf, 0x9a, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x33, 0xad, 0x99, 0xff, 0x33, 0xad, 0x98, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x32, 0xaf, 0x99, 0xff, 0x30, 0xb0, 0x99, 0xff, 0x2e, 0xaf, 0x97, 0xff, 0x2f, 0xaf, 0x95, 0xff, 0x2e, 0xad, 0x92, 0xff, 0x2e, 0xad, 0x8f, 0xff, 0x2a, 0xad, 0x8b, 0xff, 0x22, 0xaa, 0x85, 0xff, 0x1e, 0xac, 0x83, 0xff, 0x1e, 0xac, 0x81, 0xff, 0x1d, 0xab, 0x80, 0xff, 0x1b, 0xaa, 0x7e, 0xff, 0x17, 0xa9, 0x7b, 0xff, 0x12, 0xaa, 0x77, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x11, 0xa8, 0x73, 0xff, 0x10, 0xa6, 0x72, 0xff, 0x11, 0xa5, 0x72, 0xff, 0x12, 0xa5, 0x71, 0xff, 0x12, 0xa2, 0x70, 0xff, 0x0d, 0x9d, 0x6b, 0xff, 0x0d, 0x9d, 0x6a, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x10, 0xa0, 0x6c, 0xff, 0x13, 0xa3, 0x6f, 0xff, 0x10, 0xa2, 0x6e, 0xff, 0x13, 0xa4, 0x71, 0xff, 0x14, 0xa7, 0x73, 0xff, 0x11, 0xa4, 0x70, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x0f, 0x9f, 0x6d, 0xff, 0x10, 0x9e, 0x6f, 0xff, 0x0f, 0x9c, 0x6c, 0xff, 0x0c, 0x99, 0x69, 0xff, 0x0b, 0x98, 0x69, 0xff, 0x0b, 0x99, 0x6a, 0xff, 0x0a, 0x97, 0x68, 0xff, 0x0a, 0x98, 0x68, 0xff, 0x0a, 0x9b, 0x68, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x07, 0xa8, 0x71, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x07, 0xaa, 0x6d, 0xff, 0x08, 0xa6, 0x6d, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x11, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0e, 0xa7, 0x77, 0xff, 0x0e, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x13, 0xa9, 0x79, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x15, 0xa6, 0x79, 0xff, 0x14, 0xa6, 0x79, 0xff, 0x14, 0xa6, 0x79, 0xff, 0x1c, 0xaa, 0x7e, 0xff, 0x24, 0xae, 0x87, 0xff, 0x29, 0xaf, 0x88, 0xff, 0x27, 0xae, 0x87, 0xff, 0x22, 0xad, 0x85, 0xff, 0x1e, 0xad, 0x84, 0xff, 0x1e, 0xac, 0x81, 0xff, 0x22, 0xa9, 0x7f, 0xff, 0x23, 0xa8, 0x7b, 0xff, 0x15, 0xa8, 0x75, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x12, 0xa2, 0x6c, 0xff, 0x15, 0xa1, 0x6c, 0xff, 0x1a, 0xa0, 0x6d, 0xff, 0x1f, 0x9f, 0x6f, 0xff, 0x23, 0x9e, 0x6f, 0xff, 0x23, 0x9b, 0x6e, 0xff, 0x20, 0x95, 0x6a, 0xff, 0x21, 0x92, 0x69, 0xff, 0x25, 0x95, 0x6d, 0xff, 0x27, 0x98, 0x70, 0xff, 0x2a, 0x9b, 0x75, 0xff, 0x28, 0x99, 0x75, 0xff, 0x2a, 0x9e, 0x7a, 0xff, 0x2e, 0xa3, 0x7f, 0xff, 0x31, 0xa6, 0x83, 0xff, 0x31, 0xa6, 0x88, 0xff, 0x2b, 0xab, 0x8b, 0xff, 0x21, 0xad, 0x89, 0xff, 0x1c, 0xaf, 0x89, 0xff, 0x1e, 0xb0, 0x8a, 0xff, 0x1c, 0xab, 0x83, 0xff, 0x19, 0xa7, 0x7f, 0xff, 0x14, 0xa2, 0x79, 0xff, 0x0d, 0xa1, 0x71, 0xff, 0x0a, 0xa1, 0x6e, 0xff, 0x0f, 0xa1, 0x6e, 0xff, 0x12, 0xa2, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0b, 0xa1, 0x6e, 0xff, 0x05, 0xa4, 0x6b, 0xff, 0x04, 0xa3, 0x6d, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x12, 0x98, 0x6e, 0xff, 0x21, 0x8f, 0x98, 0xff, 0x30, 0x87, 0xc8, 0xff, 0x13, 0x57, 0xb1, 0xff, 0x0a, 0x37, 0x81, 0xff, 0x06, 0x2f, 0x40, 0xff, 0x09, 0x41, 0x2a, 0xff, 0x09, 0x31, 0x3e, 0xff, 0x1e, 0x29, 0x90, 0xff, 0x3b, 0x30, 0xdb, 0xff, 0x38, 0x27, 0xe2, 0xff, 0x31, 0x31, 0xde, 0xff, 0x13, 0x58, 0x85, 0xff, 0x18, 0x9a, 0x6d, 0xff, 0x0c, 0x96, 0x5d, 0xff, 0x07, 0x85, 0x53, 0xff, 0x08, 0x79, 0x4e, 0xff, 0x09, 0x68, 0x4f, 0xff, 0x18, 0x5c, 0x62, 0xff, 0x3c, 0x69, 0x7f, 0xff, 0x4b, 0x71, 0x88, 0xff, 0x41, 0x66, 0x79, 0xff, 0x18, 0x44, 0x51, 0xff, 0x0e, 0x3e, 0x45, 0xff, 0x14, 0x3e, 0x43, 0xff, 0x12, 0x31, 0x37, 0xff, 0x03, 0x1e, 0x23, 0xff, 0x29, 0x53, 0x5b, 0xff, 0x3c, 0x6c, 0x7e, 0xff, 0x32, 0x67, 0x80, 0xff, 0x2e, 0x64, 0x7b, 0xff, 0x33, 0x65, 0x79, 0xff, 0x3a, 0x68, 0x7b, 0xff, 0x23, 0x4e, 0x65, 0xff, 0x14, 0x3e, 0x57, 0xff, 0x16, 0x44, 0x5b, 0xff, 0x18, 0x44, 0x58, 0xff, 0x1c, 0x44, 0x5b, 0xff, 0x1b, 0x45, 0x5c, 0xff, 0x0c, 0x47, 0x4e, 0xff, 0x0e, 0x5a, 0x49, 0xff, 0x0a, 0x64, 0x35, 0xff, 0x06, 0x67, 0x2d, 0xff, 0x08, 0x66, 0x3e, 0xff, 0x37, 0xaa, 0x9e, 0xff, 0x57, 0xe7, 0xf7, 0xff, 0x61, 0xc0, 0xe5, 0xff, 0x9d, 0x92, 0xd0, 0xff, 0xb4, 0x9e, 0xcd, 0xff, 0x2e, 0x67, 0x55, 0xff, 0x0a, 0x67, 0x39, 0xff, 0x0b, 0x62, 0x39, 0xff, 0x0b, 0x68, 0x35, 0xff, 0x07, 0x64, 0x34, 0xff, 0x11, 0x5e, 0x3a, 0xff, 0x04, 0x3d, 0x1c, 0xff, 0x09, 0x34, 0x19, 0xff, 0x62, 0x70, 0x64, 0xff, + 0x0a, 0x3c, 0x24, 0xff, 0x07, 0x3d, 0x24, 0xff, 0x01, 0x3e, 0x24, 0xff, 0x01, 0x41, 0x27, 0xff, 0x07, 0x42, 0x28, 0xff, 0x07, 0x42, 0x23, 0xff, 0x03, 0x4b, 0x25, 0xff, 0x10, 0x82, 0x55, 0xff, 0x13, 0x9a, 0x6a, 0xff, 0x0d, 0x97, 0x69, 0xff, 0x0c, 0x82, 0x58, 0xff, 0x08, 0x5a, 0x37, 0xff, 0x0e, 0x4d, 0x2d, 0xff, 0x03, 0x3f, 0x20, 0xff, 0x03, 0x41, 0x1c, 0xff, 0x05, 0x42, 0x18, 0xff, 0x03, 0x3d, 0x19, 0xff, 0x0a, 0x3f, 0x22, 0xff, 0x06, 0x3f, 0x1e, 0xff, 0x03, 0x48, 0x1c, 0xff, 0x0b, 0x5c, 0x2a, 0xff, 0x0f, 0x6c, 0x39, 0xff, 0x18, 0x7c, 0x47, 0xff, 0x19, 0x86, 0x45, 0xff, 0x15, 0x84, 0x3f, 0xff, 0x07, 0x71, 0x2c, 0xff, 0x08, 0x82, 0x43, 0xff, 0x13, 0x9e, 0x69, 0xff, 0x10, 0xa0, 0x6f, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x11, 0xa1, 0x6d, 0xff, 0x16, 0x95, 0x64, 0xff, 0x06, 0x7d, 0x4c, 0xff, 0x10, 0xa2, 0x71, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x12, 0xa6, 0x7a, 0xff, 0x15, 0xa2, 0x77, 0xff, 0x19, 0xa3, 0x75, 0xff, 0x11, 0xa6, 0x79, 0xff, 0x15, 0xa2, 0x7f, 0xff, 0x1d, 0xa3, 0x80, 0xff, 0x1d, 0x9f, 0x7c, 0xff, 0x1a, 0xa1, 0x7c, 0xff, 0x19, 0xa5, 0x7f, 0xff, 0x18, 0xa0, 0x7a, 0xff, 0x2a, 0xa3, 0x81, 0xff, 0x21, 0x93, 0x72, 0xff, 0x19, 0x92, 0x6c, 0xff, 0x17, 0x99, 0x6b, 0xff, 0x17, 0xa5, 0x6d, 0xff, 0x13, 0xa7, 0x6d, 0xff, 0x12, 0xa7, 0x6f, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x09, 0xa1, 0x68, 0xff, 0x09, 0xa0, 0x64, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x08, 0x9a, 0x60, 0xff, 0x08, 0x98, 0x63, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x10, 0xa4, 0x6b, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x0c, 0xa6, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x11, 0xab, 0x74, 0xff, 0x14, 0xac, 0x77, 0xff, 0x13, 0xac, 0x78, 0xff, 0x15, 0xae, 0x7a, 0xff, 0x1a, 0xb3, 0x7c, 0xff, 0x1b, 0xb4, 0x7d, 0xff, 0x1a, 0xb3, 0x7d, 0xff, 0x1b, 0xb3, 0x7e, 0xff, 0x1b, 0xb3, 0x7e, 0xff, 0x19, 0xb2, 0x7c, 0xff, 0x1a, 0xb1, 0x7f, 0xff, 0x1b, 0xb3, 0x80, 0xff, 0x1c, 0xb4, 0x7f, 0xff, 0x1c, 0xb4, 0x7f, 0xff, 0x1e, 0xb7, 0x82, 0xff, 0x1e, 0xb7, 0x84, 0xff, 0x1d, 0xb7, 0x84, 0xff, 0x1d, 0xb8, 0x85, 0xff, 0x1c, 0xb8, 0x85, 0xff, 0x1d, 0xb9, 0x87, 0xff, 0x21, 0xba, 0x87, 0xff, 0x21, 0xb8, 0x86, 0xff, 0x1e, 0xb6, 0x85, 0xff, 0x19, 0xb1, 0x80, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x13, 0xa7, 0x79, 0xff, 0x15, 0xa8, 0x7a, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x1f, 0xa8, 0x85, 0xff, 0x23, 0xab, 0x89, 0xff, 0x27, 0xad, 0x8c, 0xff, 0x27, 0xac, 0x8d, 0xff, 0x2a, 0xab, 0x90, 0xff, 0x2a, 0xab, 0x91, 0xff, 0x2b, 0xab, 0x92, 0xff, 0x2d, 0xaa, 0x92, 0xff, 0x2f, 0xac, 0x95, 0xff, 0x31, 0xac, 0x98, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x37, 0xad, 0x9b, 0xff, 0x37, 0xad, 0x9a, 0xff, 0x35, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xad, 0x97, 0xff, 0x32, 0xae, 0x96, 0xff, 0x32, 0xae, 0x97, 0xff, 0x34, 0xae, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x33, 0xad, 0x99, 0xff, 0x32, 0xad, 0x99, 0xff, 0x31, 0xad, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xae, 0x97, 0xff, 0x2f, 0xad, 0x95, 0xff, 0x2e, 0xae, 0x94, 0xff, 0x2c, 0xae, 0x91, 0xff, 0x28, 0xad, 0x8d, 0xff, 0x25, 0xac, 0x8b, 0xff, 0x21, 0xab, 0x86, 0xff, 0x20, 0xab, 0x86, 0xff, 0x1f, 0xac, 0x83, 0xff, 0x1e, 0xac, 0x81, 0xff, 0x1d, 0xab, 0x80, 0xff, 0x1a, 0xab, 0x7e, 0xff, 0x17, 0xa9, 0x7a, 0xff, 0x13, 0xa7, 0x77, 0xff, 0x12, 0xa7, 0x76, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x12, 0xa6, 0x75, 0xff, 0x14, 0xa5, 0x75, 0xff, 0x0f, 0x9e, 0x6e, 0xff, 0x0b, 0x99, 0x69, 0xff, 0x0c, 0x98, 0x69, 0xff, 0x0b, 0x98, 0x68, 0xff, 0x0c, 0x99, 0x68, 0xff, 0x0d, 0x9b, 0x6a, 0xff, 0x0d, 0x9b, 0x6a, 0xff, 0x0c, 0x9a, 0x69, 0xff, 0x0d, 0x9b, 0x6a, 0xff, 0x10, 0x9e, 0x6c, 0xff, 0x0e, 0x9b, 0x6b, 0xff, 0x0b, 0x98, 0x68, 0xff, 0x09, 0x96, 0x66, 0xff, 0x0b, 0x97, 0x68, 0xff, 0x0a, 0x96, 0x67, 0xff, 0x0a, 0x97, 0x68, 0xff, 0x0c, 0x98, 0x69, 0xff, 0x0c, 0x98, 0x69, 0xff, 0x0a, 0x97, 0x68, 0xff, 0x09, 0x98, 0x68, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x07, 0xa9, 0x71, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x03, 0xa6, 0x6e, 0xff, 0x04, 0xa7, 0x6e, 0xff, 0x06, 0xa9, 0x6e, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x09, 0xa6, 0x6f, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x78, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0e, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x14, 0xa7, 0x75, 0xff, 0x19, 0xa8, 0x79, 0xff, 0x1c, 0xa9, 0x7b, 0xff, 0x1d, 0xa9, 0x7d, 0xff, 0x21, 0xab, 0x7f, 0xff, 0x22, 0xaa, 0x81, 0xff, 0x21, 0xab, 0x81, 0xff, 0x22, 0xac, 0x83, 0xff, 0x21, 0xab, 0x83, 0xff, 0x1e, 0xac, 0x7f, 0xff, 0x18, 0xa9, 0x78, 0xff, 0x15, 0xa7, 0x76, 0xff, 0x11, 0xa6, 0x72, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0b, 0xa1, 0x68, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x11, 0xa4, 0x6f, 0xff, 0x14, 0xa4, 0x71, 0xff, 0x17, 0xa6, 0x75, 0xff, 0x18, 0xa6, 0x75, 0xff, 0x17, 0xa4, 0x76, 0xff, 0x19, 0xa5, 0x7a, 0xff, 0x1d, 0xa9, 0x80, 0xff, 0x1f, 0xab, 0x82, 0xff, 0x21, 0xad, 0x85, 0xff, 0x20, 0xab, 0x86, 0xff, 0x1e, 0xa9, 0x84, 0xff, 0x1c, 0xa8, 0x81, 0xff, 0x18, 0xa7, 0x7e, 0xff, 0x16, 0xa6, 0x7c, 0xff, 0x10, 0xa3, 0x76, 0xff, 0x0c, 0xa1, 0x71, 0xff, 0x0c, 0xa0, 0x71, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0d, 0xa1, 0x70, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x06, 0xa5, 0x66, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x12, 0x93, 0x69, 0xff, 0x0b, 0x67, 0x57, 0xff, 0x0c, 0x49, 0x5a, 0xff, 0x01, 0x31, 0x4b, 0xff, 0x01, 0x33, 0x3d, 0xff, 0x05, 0x40, 0x29, 0xff, 0x06, 0x47, 0x1f, 0xff, 0x02, 0x3d, 0x2e, 0xff, 0x07, 0x29, 0x4d, 0xff, 0x37, 0x41, 0xa6, 0xff, 0x49, 0x48, 0xce, 0xff, 0x30, 0x54, 0xce, 0xff, 0x0e, 0x77, 0x81, 0xff, 0x12, 0x9f, 0x6a, 0xff, 0x16, 0x9e, 0x6a, 0xff, 0x10, 0x85, 0x59, 0xff, 0x13, 0x7a, 0x57, 0xff, 0x08, 0x5b, 0x42, 0xff, 0x1a, 0x57, 0x58, 0xff, 0x13, 0x3c, 0x4e, 0xff, 0x18, 0x36, 0x49, 0xff, 0x17, 0x34, 0x45, 0xff, 0x15, 0x3d, 0x4a, 0xff, 0x0f, 0x3f, 0x44, 0xff, 0x0f, 0x39, 0x3a, 0xff, 0x0b, 0x27, 0x27, 0xff, 0x08, 0x24, 0x1e, 0xff, 0x0a, 0x2f, 0x2e, 0xff, 0x2c, 0x58, 0x64, 0xff, 0x33, 0x65, 0x7a, 0xff, 0x31, 0x64, 0x79, 0xff, 0x1f, 0x50, 0x61, 0xff, 0x12, 0x3f, 0x52, 0xff, 0x18, 0x3f, 0x58, 0xff, 0x18, 0x45, 0x5b, 0xff, 0x16, 0x45, 0x5c, 0xff, 0x18, 0x43, 0x5e, 0xff, 0x1b, 0x46, 0x5b, 0xff, 0x18, 0x46, 0x55, 0xff, 0x0b, 0x44, 0x4a, 0xff, 0x11, 0x56, 0x4b, 0xff, 0x0c, 0x65, 0x38, 0xff, 0x09, 0x66, 0x2d, 0xff, 0x0e, 0x6e, 0x4a, 0xff, 0x48, 0xc5, 0xc2, 0xff, 0x4c, 0xd3, 0xf9, 0xff, 0x5b, 0xa5, 0xdc, 0xff, 0xa3, 0x94, 0xcf, 0xff, 0xc6, 0xb0, 0xd9, 0xff, 0x44, 0x78, 0x68, 0xff, 0x08, 0x66, 0x3a, 0xff, 0x0b, 0x64, 0x34, 0xff, 0x09, 0x69, 0x36, 0xff, 0x02, 0x61, 0x39, 0xff, 0x11, 0x5b, 0x3b, 0xff, 0x03, 0x39, 0x1a, 0xff, 0x09, 0x37, 0x1b, 0xff, 0x62, 0x70, 0x66, 0xff, + 0x06, 0x3b, 0x23, 0xff, 0x07, 0x3c, 0x24, 0xff, 0x02, 0x3f, 0x25, 0xff, 0x00, 0x40, 0x25, 0xff, 0x04, 0x41, 0x24, 0xff, 0x02, 0x45, 0x23, 0xff, 0x03, 0x58, 0x2f, 0xff, 0x13, 0x90, 0x5f, 0xff, 0x1d, 0x99, 0x69, 0xff, 0x0e, 0x7b, 0x50, 0xff, 0x03, 0x5e, 0x37, 0xff, 0x02, 0x4b, 0x26, 0xff, 0x04, 0x45, 0x22, 0xff, 0x02, 0x40, 0x1f, 0xff, 0x05, 0x44, 0x1f, 0xff, 0x09, 0x45, 0x1e, 0xff, 0x03, 0x3e, 0x1d, 0xff, 0x03, 0x41, 0x21, 0xff, 0x02, 0x45, 0x19, 0xff, 0x0d, 0x65, 0x23, 0xff, 0x11, 0x75, 0x29, 0xff, 0x09, 0x74, 0x29, 0xff, 0x05, 0x74, 0x28, 0xff, 0x14, 0x8b, 0x35, 0xff, 0x1b, 0x94, 0x3d, 0xff, 0x1d, 0x9d, 0x4b, 0xff, 0x10, 0x92, 0x49, 0xff, 0x06, 0x8f, 0x54, 0xff, 0x09, 0x93, 0x5f, 0xff, 0x05, 0x92, 0x5f, 0xff, 0x0a, 0x90, 0x5b, 0xff, 0x04, 0x70, 0x3d, 0xff, 0x04, 0x67, 0x37, 0xff, 0x18, 0xa2, 0x76, 0xff, 0x17, 0xa4, 0x79, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x15, 0xa5, 0x79, 0xff, 0x19, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x12, 0xa0, 0x7c, 0xff, 0x21, 0xa9, 0x84, 0xff, 0x1e, 0xa5, 0x7e, 0xff, 0x12, 0xa0, 0x77, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x17, 0xaa, 0x7f, 0xff, 0x16, 0x9e, 0x76, 0xff, 0x16, 0x98, 0x6f, 0xff, 0x14, 0xa0, 0x70, 0xff, 0x19, 0xa9, 0x7a, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0e, 0xa6, 0x7a, 0xff, 0x0b, 0xa4, 0x75, 0xff, 0x09, 0xa3, 0x6f, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x0c, 0xa6, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0a, 0x9f, 0x63, 0xff, 0x07, 0x9a, 0x61, 0xff, 0x07, 0x98, 0x62, 0xff, 0x07, 0x98, 0x62, 0xff, 0x0b, 0x9e, 0x66, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x10, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x11, 0xaa, 0x75, 0xff, 0x1d, 0xb6, 0x81, 0xff, 0x20, 0xb9, 0x86, 0xff, 0x20, 0xb8, 0x85, 0xff, 0x1f, 0xb8, 0x85, 0xff, 0x1d, 0xb7, 0x84, 0xff, 0x1e, 0xb8, 0x85, 0xff, 0x1f, 0xb6, 0x84, 0xff, 0x1b, 0xb2, 0x80, 0xff, 0x15, 0xad, 0x7c, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x13, 0xa7, 0x79, 0xff, 0x15, 0xa7, 0x7a, 0xff, 0x1d, 0xa8, 0x85, 0xff, 0x23, 0xac, 0x8a, 0xff, 0x27, 0xaf, 0x8d, 0xff, 0x2a, 0xb0, 0x8f, 0xff, 0x28, 0xac, 0x8e, 0xff, 0x2b, 0xac, 0x91, 0xff, 0x2a, 0xaa, 0x91, 0xff, 0x2b, 0xab, 0x92, 0xff, 0x2f, 0xab, 0x94, 0xff, 0x31, 0xae, 0x97, 0xff, 0x32, 0xad, 0x99, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x35, 0xad, 0x9b, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x37, 0xad, 0x9b, 0xff, 0x37, 0xad, 0x9a, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xad, 0x97, 0xff, 0x31, 0xad, 0x96, 0xff, 0x33, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x32, 0xac, 0x98, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xad, 0x97, 0xff, 0x32, 0xae, 0x98, 0xff, 0x31, 0xad, 0x97, 0xff, 0x2d, 0xac, 0x93, 0xff, 0x2c, 0xab, 0x92, 0xff, 0x2b, 0xad, 0x91, 0xff, 0x29, 0xad, 0x8f, 0xff, 0x25, 0xac, 0x8c, 0xff, 0x23, 0xab, 0x89, 0xff, 0x20, 0xab, 0x86, 0xff, 0x20, 0xab, 0x86, 0xff, 0x1f, 0xab, 0x82, 0xff, 0x1d, 0xaa, 0x80, 0xff, 0x1b, 0xac, 0x7f, 0xff, 0x1a, 0xab, 0x7e, 0xff, 0x16, 0xaa, 0x7a, 0xff, 0x13, 0xa8, 0x77, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x14, 0xa8, 0x77, 0xff, 0x11, 0xa3, 0x71, 0xff, 0x0d, 0x9e, 0x6c, 0xff, 0x0d, 0x9d, 0x6c, 0xff, 0x0b, 0x9a, 0x6a, 0xff, 0x0b, 0x9b, 0x6a, 0xff, 0x0b, 0x9b, 0x6a, 0xff, 0x0b, 0x9a, 0x69, 0xff, 0x09, 0x98, 0x67, 0xff, 0x08, 0x97, 0x66, 0xff, 0x0b, 0x99, 0x68, 0xff, 0x0d, 0x9a, 0x69, 0xff, 0x0b, 0x99, 0x69, 0xff, 0x09, 0x98, 0x69, 0xff, 0x09, 0x97, 0x68, 0xff, 0x08, 0x97, 0x68, 0xff, 0x0a, 0x97, 0x68, 0xff, 0x0b, 0x97, 0x68, 0xff, 0x0c, 0x98, 0x69, 0xff, 0x0b, 0x97, 0x68, 0xff, 0x0a, 0x99, 0x68, 0xff, 0x08, 0x99, 0x65, 0xff, 0x0a, 0xa1, 0x6c, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x05, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa7, 0x72, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0d, 0xa7, 0x77, 0xff, 0x0e, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa4, 0x71, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x12, 0xa4, 0x70, 0xff, 0x11, 0xa3, 0x70, 0xff, 0x13, 0xa3, 0x71, 0xff, 0x17, 0xa5, 0x74, 0xff, 0x17, 0xa4, 0x76, 0xff, 0x16, 0xa5, 0x76, 0xff, 0x17, 0xa8, 0x78, 0xff, 0x1a, 0xa8, 0x7b, 0xff, 0x1c, 0xa9, 0x79, 0xff, 0x18, 0xa7, 0x75, 0xff, 0x16, 0xa8, 0x76, 0xff, 0x17, 0xaa, 0x76, 0xff, 0x15, 0xa8, 0x73, 0xff, 0x13, 0xa6, 0x70, 0xff, 0x13, 0xa5, 0x6e, 0xff, 0x11, 0xa5, 0x6d, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x12, 0xa4, 0x70, 0xff, 0x14, 0xa4, 0x73, 0xff, 0x15, 0xa6, 0x75, 0xff, 0x17, 0xa7, 0x77, 0xff, 0x1b, 0xaa, 0x7c, 0xff, 0x1a, 0xa9, 0x7d, 0xff, 0x18, 0xa7, 0x7a, 0xff, 0x17, 0xa5, 0x7a, 0xff, 0x17, 0xa4, 0x7b, 0xff, 0x16, 0xa3, 0x78, 0xff, 0x14, 0xa2, 0x77, 0xff, 0x10, 0xa2, 0x72, 0xff, 0x0d, 0xa0, 0x71, 0xff, 0x0b, 0xa0, 0x6e, 0xff, 0x0a, 0xa1, 0x6f, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0e, 0xa1, 0x70, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa6, 0x68, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0f, 0x95, 0x68, 0xff, 0x01, 0x58, 0x3c, 0xff, 0x01, 0x4c, 0x31, 0xff, 0x00, 0x45, 0x2c, 0xff, 0x01, 0x44, 0x2c, 0xff, 0x02, 0x4c, 0x28, 0xff, 0x05, 0x5e, 0x2e, 0xff, 0x10, 0x71, 0x47, 0xff, 0x01, 0x42, 0x32, 0xff, 0x05, 0x2c, 0x42, 0xff, 0x18, 0x33, 0x6e, 0xff, 0x19, 0x55, 0x94, 0xff, 0x0f, 0x89, 0x77, 0xff, 0x0a, 0x9f, 0x66, 0xff, 0x0b, 0x93, 0x62, 0xff, 0x04, 0x6f, 0x4b, 0xff, 0x0f, 0x68, 0x4c, 0xff, 0x09, 0x4b, 0x39, 0xff, 0x14, 0x41, 0x41, 0xff, 0x14, 0x35, 0x3f, 0xff, 0x18, 0x34, 0x3f, 0xff, 0x16, 0x36, 0x3f, 0xff, 0x13, 0x3b, 0x41, 0xff, 0x06, 0x37, 0x36, 0xff, 0x01, 0x2d, 0x2a, 0xff, 0x06, 0x2b, 0x25, 0xff, 0x0d, 0x30, 0x26, 0xff, 0x08, 0x2b, 0x25, 0xff, 0x10, 0x3b, 0x3d, 0xff, 0x39, 0x69, 0x75, 0xff, 0x27, 0x59, 0x68, 0xff, 0x26, 0x57, 0x67, 0xff, 0x27, 0x56, 0x6a, 0xff, 0x14, 0x43, 0x59, 0xff, 0x14, 0x45, 0x59, 0xff, 0x14, 0x44, 0x5b, 0xff, 0x18, 0x43, 0x5e, 0xff, 0x19, 0x44, 0x59, 0xff, 0x11, 0x3f, 0x4e, 0xff, 0x07, 0x3e, 0x45, 0xff, 0x0e, 0x50, 0x46, 0xff, 0x0b, 0x64, 0x37, 0xff, 0x07, 0x64, 0x2f, 0xff, 0x10, 0x63, 0x4c, 0xff, 0x51, 0xa5, 0xb3, 0xff, 0x60, 0xa4, 0xd8, 0xff, 0x80, 0x8d, 0xd1, 0xff, 0xc3, 0xa0, 0xde, 0xff, 0xcf, 0xbd, 0xe1, 0xff, 0x44, 0x7a, 0x64, 0xff, 0x09, 0x65, 0x37, 0xff, 0x0a, 0x63, 0x33, 0xff, 0x0b, 0x68, 0x37, 0xff, 0x05, 0x5e, 0x37, 0xff, 0x11, 0x56, 0x39, 0xff, 0x04, 0x35, 0x18, 0xff, 0x0c, 0x3a, 0x1e, 0xff, 0x63, 0x72, 0x68, 0xff, + 0x02, 0x3d, 0x23, 0xff, 0x01, 0x3c, 0x20, 0xff, 0x00, 0x43, 0x25, 0xff, 0x02, 0x4c, 0x2d, 0xff, 0x05, 0x55, 0x34, 0xff, 0x12, 0x6d, 0x47, 0xff, 0x13, 0x85, 0x59, 0xff, 0x1a, 0x97, 0x69, 0xff, 0x17, 0x84, 0x57, 0xff, 0x08, 0x5e, 0x34, 0xff, 0x05, 0x50, 0x29, 0xff, 0x01, 0x46, 0x20, 0xff, 0x00, 0x42, 0x1c, 0xff, 0x01, 0x3f, 0x1a, 0xff, 0x03, 0x41, 0x18, 0xff, 0x05, 0x43, 0x14, 0xff, 0x05, 0x43, 0x1b, 0xff, 0x00, 0x42, 0x19, 0xff, 0x04, 0x4f, 0x1c, 0xff, 0x13, 0x6c, 0x2a, 0xff, 0x0b, 0x6a, 0x22, 0xff, 0x07, 0x69, 0x23, 0xff, 0x01, 0x66, 0x1f, 0xff, 0x05, 0x73, 0x26, 0xff, 0x14, 0x8c, 0x3c, 0xff, 0x17, 0x9a, 0x4c, 0xff, 0x1a, 0xa7, 0x5d, 0xff, 0x0a, 0x99, 0x57, 0xff, 0x03, 0x86, 0x47, 0xff, 0x0f, 0x97, 0x58, 0xff, 0x1f, 0x9c, 0x5d, 0xff, 0x0f, 0x6e, 0x36, 0xff, 0x0e, 0x76, 0x46, 0xff, 0x2c, 0xaf, 0x86, 0xff, 0x1d, 0xa3, 0x7b, 0xff, 0x10, 0x9e, 0x73, 0xff, 0x11, 0xa4, 0x77, 0xff, 0x16, 0xa1, 0x78, 0xff, 0x11, 0x9f, 0x79, 0xff, 0x13, 0xa0, 0x7b, 0xff, 0x15, 0x9f, 0x79, 0xff, 0x13, 0x9e, 0x75, 0xff, 0x12, 0xa4, 0x79, 0xff, 0x0e, 0xa7, 0x79, 0xff, 0x17, 0xb1, 0x83, 0xff, 0x1a, 0xaa, 0x7e, 0xff, 0x14, 0xa3, 0x73, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa2, 0x76, 0xff, 0x16, 0xad, 0x8c, 0xff, 0x2d, 0xc4, 0xa6, 0xff, 0x18, 0xb3, 0x8b, 0xff, 0x06, 0xa2, 0x70, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x08, 0xa5, 0x68, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x08, 0x9d, 0x63, 0xff, 0x08, 0x99, 0x62, 0xff, 0x05, 0x97, 0x61, 0xff, 0x08, 0x9a, 0x63, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0d, 0xa1, 0x69, 0xff, 0x0d, 0xa3, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x1a, 0xb2, 0x7d, 0xff, 0x1b, 0xb4, 0x7f, 0xff, 0x17, 0xaf, 0x7d, 0xff, 0x14, 0xac, 0x7a, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x15, 0xad, 0x7b, 0xff, 0x18, 0xaf, 0x7d, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x17, 0xa8, 0x7d, 0xff, 0x20, 0xab, 0x87, 0xff, 0x25, 0xae, 0x8c, 0xff, 0x27, 0xaf, 0x8d, 0xff, 0x28, 0xad, 0x8d, 0xff, 0x28, 0xac, 0x8e, 0xff, 0x2b, 0xac, 0x91, 0xff, 0x2a, 0xab, 0x90, 0xff, 0x2b, 0xab, 0x91, 0xff, 0x30, 0xad, 0x96, 0xff, 0x33, 0xad, 0x99, 0xff, 0x33, 0xac, 0x98, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x35, 0xad, 0x9b, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x37, 0xad, 0x9b, 0xff, 0x37, 0xad, 0x9a, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x33, 0xac, 0x98, 0xff, 0x32, 0xab, 0x97, 0xff, 0x32, 0xab, 0x96, 0xff, 0x32, 0xae, 0x98, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x31, 0xad, 0x97, 0xff, 0x32, 0xab, 0x97, 0xff, 0x33, 0xab, 0x98, 0xff, 0x32, 0xad, 0x97, 0xff, 0x32, 0xae, 0x98, 0xff, 0x33, 0xaf, 0x99, 0xff, 0x31, 0xaf, 0x97, 0xff, 0x30, 0xae, 0x96, 0xff, 0x2f, 0xad, 0x95, 0xff, 0x2b, 0xab, 0x90, 0xff, 0x2a, 0xab, 0x8f, 0xff, 0x28, 0xab, 0x8e, 0xff, 0x26, 0xab, 0x8b, 0xff, 0x23, 0xab, 0x89, 0xff, 0x21, 0xac, 0x86, 0xff, 0x20, 0xab, 0x85, 0xff, 0x1f, 0xab, 0x84, 0xff, 0x1d, 0xac, 0x81, 0xff, 0x1b, 0xab, 0x7e, 0xff, 0x18, 0xac, 0x7e, 0xff, 0x18, 0xab, 0x7c, 0xff, 0x15, 0xa9, 0x79, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x74, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x10, 0xa6, 0x72, 0xff, 0x12, 0xa6, 0x72, 0xff, 0x12, 0xa5, 0x72, 0xff, 0x10, 0xa3, 0x70, 0xff, 0x0e, 0x9f, 0x6e, 0xff, 0x0c, 0x9c, 0x6b, 0xff, 0x0b, 0x9b, 0x6a, 0xff, 0x0b, 0x9b, 0x6a, 0xff, 0x09, 0x99, 0x68, 0xff, 0x0a, 0x99, 0x68, 0xff, 0x0b, 0x9a, 0x69, 0xff, 0x0a, 0x99, 0x69, 0xff, 0x09, 0x9a, 0x6a, 0xff, 0x0a, 0x9a, 0x6a, 0xff, 0x09, 0x99, 0x69, 0xff, 0x08, 0x96, 0x67, 0xff, 0x09, 0x96, 0x67, 0xff, 0x0a, 0x96, 0x67, 0xff, 0x0a, 0x96, 0x67, 0xff, 0x0a, 0x98, 0x67, 0xff, 0x07, 0x98, 0x65, 0xff, 0x0a, 0xa0, 0x6b, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x08, 0xa8, 0x71, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0a, 0xa7, 0x72, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x0f, 0xa9, 0x77, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x11, 0xa6, 0x6e, 0xff, 0x12, 0xa5, 0x6f, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0e, 0xa3, 0x6e, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x13, 0xa3, 0x6e, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x11, 0xa3, 0x6d, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x12, 0xa4, 0x6e, 0xff, 0x11, 0xa5, 0x6d, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x11, 0xa3, 0x6f, 0xff, 0x11, 0xa4, 0x72, 0xff, 0x13, 0xa5, 0x74, 0xff, 0x13, 0xa5, 0x74, 0xff, 0x12, 0xa4, 0x74, 0xff, 0x0f, 0xa1, 0x71, 0xff, 0x10, 0xa1, 0x72, 0xff, 0x0f, 0xa0, 0x70, 0xff, 0x0f, 0xa1, 0x70, 0xff, 0x0f, 0xa1, 0x70, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0b, 0xa1, 0x6d, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0f, 0xa1, 0x70, 0xff, 0x0c, 0xa1, 0x6c, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x12, 0x9d, 0x6d, 0xff, 0x0d, 0x85, 0x60, 0xff, 0x0e, 0x7f, 0x56, 0xff, 0x09, 0x70, 0x49, 0xff, 0x0b, 0x6c, 0x49, 0xff, 0x13, 0x7e, 0x55, 0xff, 0x17, 0x92, 0x61, 0xff, 0x1c, 0x93, 0x63, 0xff, 0x07, 0x5e, 0x3d, 0xff, 0x04, 0x37, 0x2b, 0xff, 0x03, 0x2e, 0x36, 0xff, 0x03, 0x42, 0x50, 0xff, 0x0f, 0x90, 0x68, 0xff, 0x05, 0x9e, 0x63, 0xff, 0x01, 0x8d, 0x5c, 0xff, 0x02, 0x6d, 0x4a, 0xff, 0x03, 0x5b, 0x3b, 0xff, 0x05, 0x42, 0x2e, 0xff, 0x0d, 0x39, 0x32, 0xff, 0x0c, 0x33, 0x30, 0xff, 0x08, 0x2f, 0x2e, 0xff, 0x10, 0x37, 0x37, 0xff, 0x08, 0x36, 0x32, 0xff, 0x06, 0x35, 0x2f, 0xff, 0x06, 0x33, 0x2a, 0xff, 0x08, 0x34, 0x27, 0xff, 0x12, 0x36, 0x29, 0xff, 0x13, 0x38, 0x2b, 0xff, 0x0b, 0x36, 0x2e, 0xff, 0x23, 0x53, 0x55, 0xff, 0x26, 0x56, 0x5f, 0xff, 0x21, 0x51, 0x62, 0xff, 0x24, 0x55, 0x69, 0xff, 0x1e, 0x52, 0x65, 0xff, 0x14, 0x46, 0x5a, 0xff, 0x15, 0x42, 0x5c, 0xff, 0x16, 0x43, 0x5e, 0xff, 0x14, 0x41, 0x54, 0xff, 0x0d, 0x3c, 0x4b, 0xff, 0x08, 0x3e, 0x45, 0xff, 0x0f, 0x50, 0x46, 0xff, 0x0c, 0x63, 0x36, 0xff, 0x06, 0x5f, 0x2f, 0xff, 0x2c, 0x67, 0x5d, 0xff, 0x6e, 0x94, 0xaf, 0xff, 0x85, 0x90, 0xca, 0xff, 0xac, 0x8f, 0xd6, 0xff, 0xdb, 0xb1, 0xed, 0xff, 0xc5, 0xbe, 0xd8, 0xff, 0x30, 0x6e, 0x50, 0xff, 0x0a, 0x66, 0x37, 0xff, 0x0b, 0x63, 0x35, 0xff, 0x0c, 0x66, 0x37, 0xff, 0x09, 0x5d, 0x37, 0xff, 0x14, 0x51, 0x35, 0xff, 0x04, 0x33, 0x17, 0xff, 0x0e, 0x3c, 0x21, 0xff, 0x61, 0x71, 0x68, 0xff, + 0x02, 0x4b, 0x2e, 0xff, 0x0a, 0x5e, 0x3a, 0xff, 0x10, 0x71, 0x4c, 0xff, 0x12, 0x83, 0x5c, 0xff, 0x19, 0x8c, 0x63, 0xff, 0x1e, 0x97, 0x69, 0xff, 0x1b, 0x98, 0x6a, 0xff, 0x11, 0x7e, 0x56, 0xff, 0x05, 0x5f, 0x37, 0xff, 0x03, 0x4a, 0x21, 0xff, 0x02, 0x46, 0x1c, 0xff, 0x06, 0x51, 0x24, 0xff, 0x0d, 0x55, 0x29, 0xff, 0x12, 0x51, 0x27, 0xff, 0x0d, 0x48, 0x1c, 0xff, 0x04, 0x40, 0x12, 0xff, 0x03, 0x41, 0x15, 0xff, 0x03, 0x48, 0x16, 0xff, 0x0b, 0x57, 0x21, 0xff, 0x04, 0x55, 0x1d, 0xff, 0x02, 0x58, 0x1f, 0xff, 0x02, 0x5e, 0x1c, 0xff, 0x03, 0x60, 0x1a, 0xff, 0x02, 0x63, 0x1c, 0xff, 0x04, 0x70, 0x25, 0xff, 0x0d, 0x87, 0x3a, 0xff, 0x13, 0x98, 0x4a, 0xff, 0x1e, 0xa8, 0x5c, 0xff, 0x1c, 0xa3, 0x57, 0xff, 0x22, 0xa1, 0x56, 0xff, 0x1c, 0x8f, 0x46, 0xff, 0x0a, 0x6a, 0x2d, 0xff, 0x29, 0x99, 0x68, 0xff, 0x39, 0xbc, 0x93, 0xff, 0x1c, 0xa0, 0x78, 0xff, 0x0d, 0x9d, 0x6f, 0xff, 0x0c, 0xa2, 0x73, 0xff, 0x14, 0xa1, 0x7a, 0xff, 0x21, 0xac, 0x89, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x11, 0x9c, 0x73, 0xff, 0x15, 0xa1, 0x77, 0xff, 0x13, 0xa6, 0x7a, 0xff, 0x11, 0xab, 0x7d, 0xff, 0x15, 0xaf, 0x82, 0xff, 0x1b, 0xae, 0x83, 0xff, 0x14, 0xa7, 0x76, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x06, 0x9b, 0x74, 0xff, 0x3a, 0xca, 0xb5, 0xff, 0x52, 0xe1, 0xcd, 0xff, 0x2f, 0xc4, 0xa1, 0xff, 0x07, 0xa0, 0x6f, 0xff, 0x08, 0xa5, 0x6b, 0xff, 0x05, 0xa1, 0x67, 0xff, 0x07, 0xa0, 0x6b, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0a, 0x9c, 0x65, 0xff, 0x07, 0x99, 0x63, 0xff, 0x07, 0x99, 0x61, 0xff, 0x07, 0x9a, 0x60, 0xff, 0x08, 0x9a, 0x63, 0xff, 0x09, 0x9b, 0x64, 0xff, 0x0d, 0xa1, 0x69, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa4, 0x71, 0xff, 0x0b, 0xa1, 0x6f, 0xff, 0x0b, 0xa0, 0x6e, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0a, 0xa1, 0x6f, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x16, 0xa8, 0x7c, 0xff, 0x1b, 0xa9, 0x80, 0xff, 0x20, 0xab, 0x87, 0xff, 0x24, 0xad, 0x8b, 0xff, 0x26, 0xae, 0x8c, 0xff, 0x26, 0xac, 0x8b, 0xff, 0x26, 0xaa, 0x8c, 0xff, 0x2a, 0xab, 0x8f, 0xff, 0x2a, 0xab, 0x90, 0xff, 0x2b, 0xac, 0x91, 0xff, 0x31, 0xad, 0x97, 0xff, 0x33, 0xad, 0x98, 0xff, 0x33, 0xac, 0x99, 0xff, 0x36, 0xad, 0x9b, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x34, 0xab, 0x9a, 0xff, 0x35, 0xad, 0x9a, 0xff, 0x35, 0xac, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xad, 0x99, 0xff, 0x33, 0xac, 0x98, 0xff, 0x32, 0xac, 0x96, 0xff, 0x30, 0xab, 0x95, 0xff, 0x30, 0xac, 0x96, 0xff, 0x31, 0xad, 0x96, 0xff, 0x2f, 0xab, 0x94, 0xff, 0x31, 0xab, 0x96, 0xff, 0x32, 0xac, 0x97, 0xff, 0x31, 0xad, 0x97, 0xff, 0x30, 0xad, 0x96, 0xff, 0x31, 0xaf, 0x97, 0xff, 0x2e, 0xae, 0x94, 0xff, 0x2d, 0xad, 0x93, 0xff, 0x2b, 0xab, 0x91, 0xff, 0x27, 0xab, 0x8c, 0xff, 0x25, 0xab, 0x8a, 0xff, 0x24, 0xab, 0x8a, 0xff, 0x22, 0xab, 0x87, 0xff, 0x20, 0xab, 0x85, 0xff, 0x1f, 0xab, 0x84, 0xff, 0x1e, 0xab, 0x83, 0xff, 0x1c, 0xab, 0x81, 0xff, 0x1a, 0xac, 0x7f, 0xff, 0x17, 0xac, 0x7d, 0xff, 0x16, 0xac, 0x7c, 0xff, 0x15, 0xab, 0x7b, 0xff, 0x12, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0f, 0xa9, 0x76, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x12, 0xaa, 0x75, 0xff, 0x12, 0xa9, 0x74, 0xff, 0x13, 0xa9, 0x76, 0xff, 0x14, 0xa8, 0x76, 0xff, 0x12, 0xa6, 0x75, 0xff, 0x0f, 0xa2, 0x70, 0xff, 0x0d, 0x9f, 0x6d, 0xff, 0x0e, 0x9f, 0x6e, 0xff, 0x0b, 0x9b, 0x6a, 0xff, 0x0a, 0x99, 0x68, 0xff, 0x0a, 0x9b, 0x6a, 0xff, 0x0d, 0x9f, 0x6f, 0xff, 0x10, 0xa0, 0x70, 0xff, 0x0e, 0x9f, 0x6f, 0xff, 0x08, 0x98, 0x68, 0xff, 0x08, 0x97, 0x68, 0xff, 0x09, 0x96, 0x67, 0xff, 0x0a, 0x97, 0x68, 0xff, 0x0b, 0x98, 0x68, 0xff, 0x0b, 0x9b, 0x68, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0c, 0xa5, 0x76, 0xff, 0x0f, 0xa7, 0x79, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0e, 0xa8, 0x78, 0xff, 0x12, 0xac, 0x7c, 0xff, 0x14, 0xad, 0x7d, 0xff, 0x1d, 0xb5, 0x83, 0xff, 0x16, 0xaf, 0x7d, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0a, 0xa2, 0x69, 0xff, 0x0d, 0xa5, 0x69, 0xff, 0x10, 0xa8, 0x6c, 0xff, 0x11, 0xa7, 0x6d, 0xff, 0x11, 0xa7, 0x6c, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0e, 0xa2, 0x67, 0xff, 0x0d, 0xa0, 0x68, 0xff, 0x0d, 0xa1, 0x6a, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0d, 0xa0, 0x6a, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0e, 0xa2, 0x6f, 0xff, 0x0e, 0xa2, 0x6f, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x0c, 0xa0, 0x6d, 0xff, 0x0c, 0xa1, 0x6d, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x10, 0xa0, 0x70, 0xff, 0x0f, 0xa0, 0x6e, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x17, 0xa0, 0x73, 0xff, 0x15, 0xa0, 0x74, 0xff, 0x16, 0x9b, 0x6f, 0xff, 0x18, 0x9a, 0x6c, 0xff, 0x17, 0xa1, 0x6c, 0xff, 0x10, 0xa3, 0x6b, 0xff, 0x10, 0x98, 0x64, 0xff, 0x18, 0x84, 0x5a, 0xff, 0x02, 0x40, 0x23, 0xff, 0x04, 0x3e, 0x21, 0xff, 0x0a, 0x5e, 0x47, 0xff, 0x18, 0x9b, 0x69, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x0a, 0x9d, 0x69, 0xff, 0x11, 0x91, 0x68, 0xff, 0x16, 0x83, 0x57, 0xff, 0x09, 0x5b, 0x39, 0xff, 0x03, 0x45, 0x2f, 0xff, 0x02, 0x40, 0x2d, 0xff, 0x02, 0x44, 0x32, 0xff, 0x08, 0x47, 0x37, 0xff, 0x06, 0x3f, 0x2f, 0xff, 0x0b, 0x3b, 0x2c, 0xff, 0x0f, 0x3d, 0x2c, 0xff, 0x11, 0x3f, 0x2b, 0xff, 0x15, 0x3e, 0x2b, 0xff, 0x15, 0x3f, 0x2c, 0xff, 0x10, 0x40, 0x2d, 0xff, 0x0b, 0x3d, 0x33, 0xff, 0x1a, 0x4a, 0x4e, 0xff, 0x21, 0x4e, 0x60, 0xff, 0x24, 0x54, 0x6a, 0xff, 0x1f, 0x54, 0x66, 0xff, 0x1a, 0x4c, 0x5f, 0xff, 0x17, 0x44, 0x5d, 0xff, 0x16, 0x43, 0x5e, 0xff, 0x11, 0x40, 0x52, 0xff, 0x0d, 0x3c, 0x48, 0xff, 0x0c, 0x3f, 0x46, 0xff, 0x12, 0x50, 0x46, 0xff, 0x0d, 0x61, 0x37, 0xff, 0x0d, 0x58, 0x31, 0xff, 0x7f, 0x96, 0x9b, 0xff, 0xbe, 0xb7, 0xdb, 0xff, 0xb7, 0xa5, 0xd6, 0xff, 0xc9, 0xa9, 0xe0, 0xff, 0xd6, 0xbf, 0xea, 0xff, 0x92, 0xa0, 0xa7, 0xff, 0x1e, 0x69, 0x43, 0xff, 0x09, 0x6a, 0x3a, 0xff, 0x0b, 0x63, 0x36, 0xff, 0x10, 0x68, 0x3b, 0xff, 0x10, 0x5d, 0x3a, 0xff, 0x0d, 0x40, 0x27, 0xff, 0x04, 0x33, 0x18, 0xff, 0x0f, 0x3f, 0x23, 0xff, 0x62, 0x71, 0x68, 0xff, + 0x19, 0x81, 0x5c, 0xff, 0x1b, 0x91, 0x64, 0xff, 0x19, 0x97, 0x68, 0xff, 0x11, 0x9a, 0x6b, 0xff, 0x10, 0x99, 0x69, 0xff, 0x13, 0x99, 0x67, 0xff, 0x0e, 0x84, 0x57, 0xff, 0x02, 0x54, 0x32, 0xff, 0x01, 0x48, 0x25, 0xff, 0x01, 0x43, 0x1a, 0xff, 0x0a, 0x53, 0x24, 0xff, 0x11, 0x64, 0x2f, 0xff, 0x12, 0x61, 0x2c, 0xff, 0x1a, 0x5b, 0x29, 0xff, 0x10, 0x4b, 0x1d, 0xff, 0x02, 0x3d, 0x14, 0xff, 0x01, 0x3e, 0x11, 0xff, 0x06, 0x4a, 0x14, 0xff, 0x06, 0x4c, 0x16, 0xff, 0x06, 0x52, 0x23, 0xff, 0x0c, 0x63, 0x31, 0xff, 0x07, 0x6d, 0x27, 0xff, 0x08, 0x74, 0x24, 0xff, 0x0d, 0x74, 0x28, 0xff, 0x09, 0x71, 0x23, 0xff, 0x04, 0x6d, 0x1b, 0xff, 0x04, 0x74, 0x21, 0xff, 0x08, 0x83, 0x30, 0xff, 0x0c, 0x87, 0x34, 0xff, 0x05, 0x77, 0x26, 0xff, 0x09, 0x77, 0x2a, 0xff, 0x05, 0x70, 0x30, 0xff, 0x20, 0x9f, 0x6a, 0xff, 0x1a, 0xa2, 0x78, 0xff, 0x0f, 0x99, 0x6e, 0xff, 0x0e, 0xa1, 0x6f, 0xff, 0x0a, 0xa4, 0x72, 0xff, 0x16, 0xa7, 0x7e, 0xff, 0x36, 0xbf, 0x9b, 0xff, 0x1c, 0xaa, 0x7e, 0xff, 0x0f, 0x9c, 0x71, 0xff, 0x12, 0x9f, 0x74, 0xff, 0x15, 0xa5, 0x79, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x1a, 0xac, 0x85, 0xff, 0x1f, 0xaa, 0x86, 0xff, 0x17, 0xa4, 0x79, 0xff, 0x10, 0xa3, 0x6e, 0xff, 0x12, 0xa0, 0x7e, 0xff, 0x36, 0xbe, 0xad, 0xff, 0x44, 0xcd, 0xba, 0xff, 0x13, 0xa3, 0x80, 0xff, 0x1b, 0xb0, 0x80, 0xff, 0x12, 0xaa, 0x75, 0xff, 0x11, 0xa9, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0c, 0xa6, 0x69, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x09, 0x9b, 0x63, 0xff, 0x09, 0x9b, 0x61, 0xff, 0x07, 0x98, 0x61, 0xff, 0x07, 0x98, 0x61, 0xff, 0x0a, 0x9d, 0x66, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0xa2, 0x69, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x71, 0xff, 0x11, 0xa5, 0x72, 0xff, 0x12, 0xa6, 0x74, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x14, 0xa8, 0x7a, 0xff, 0x18, 0xaa, 0x7d, 0xff, 0x1b, 0xa8, 0x80, 0xff, 0x20, 0xaa, 0x87, 0xff, 0x22, 0xab, 0x89, 0xff, 0x23, 0xab, 0x89, 0xff, 0x24, 0xaa, 0x8a, 0xff, 0x25, 0xa9, 0x8b, 0xff, 0x28, 0xaa, 0x8c, 0xff, 0x2a, 0xab, 0x8f, 0xff, 0x2c, 0xac, 0x91, 0xff, 0x30, 0xab, 0x95, 0xff, 0x33, 0xad, 0x98, 0xff, 0x34, 0xad, 0x99, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x34, 0xac, 0x9a, 0xff, 0x32, 0xab, 0x98, 0xff, 0x33, 0xac, 0x98, 0xff, 0x32, 0xac, 0x97, 0xff, 0x31, 0xab, 0x97, 0xff, 0x32, 0xac, 0x98, 0xff, 0x32, 0xac, 0x97, 0xff, 0x31, 0xad, 0x97, 0xff, 0x31, 0xae, 0x97, 0xff, 0x30, 0xad, 0x97, 0xff, 0x30, 0xac, 0x95, 0xff, 0x30, 0xac, 0x94, 0xff, 0x31, 0xad, 0x96, 0xff, 0x31, 0xad, 0x97, 0xff, 0x2f, 0xac, 0x95, 0xff, 0x2d, 0xac, 0x93, 0xff, 0x2d, 0xad, 0x93, 0xff, 0x2b, 0xac, 0x91, 0xff, 0x28, 0xab, 0x8e, 0xff, 0x26, 0xa9, 0x8d, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x20, 0xaa, 0x87, 0xff, 0x20, 0xab, 0x86, 0xff, 0x20, 0xab, 0x84, 0xff, 0x1e, 0xab, 0x83, 0xff, 0x1d, 0xab, 0x83, 0xff, 0x1b, 0xab, 0x80, 0xff, 0x19, 0xab, 0x7e, 0xff, 0x15, 0xab, 0x7b, 0xff, 0x13, 0xab, 0x79, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0f, 0xa9, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x11, 0xa8, 0x74, 0xff, 0x12, 0xa9, 0x76, 0xff, 0x13, 0xa9, 0x77, 0xff, 0x13, 0xa9, 0x77, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa5, 0x73, 0xff, 0x15, 0xa8, 0x76, 0xff, 0x11, 0xa3, 0x71, 0xff, 0x0d, 0x9e, 0x6d, 0xff, 0x0d, 0x9f, 0x6e, 0xff, 0x10, 0xa5, 0x74, 0xff, 0x15, 0xa8, 0x78, 0xff, 0x13, 0xa6, 0x76, 0xff, 0x0b, 0x9c, 0x6c, 0xff, 0x09, 0x99, 0x69, 0xff, 0x09, 0x98, 0x69, 0xff, 0x0a, 0x99, 0x6a, 0xff, 0x0b, 0x9a, 0x6a, 0xff, 0x0f, 0x9e, 0x6d, 0xff, 0x11, 0xa4, 0x72, 0xff, 0x0d, 0xa3, 0x70, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x13, 0xa9, 0x7d, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x14, 0xac, 0x7e, 0xff, 0x24, 0xbb, 0x8b, 0xff, 0x1a, 0xb2, 0x81, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa1, 0x67, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x10, 0xa6, 0x6a, 0xff, 0x13, 0xa7, 0x6b, 0xff, 0x12, 0xa7, 0x6b, 0xff, 0x0f, 0xa6, 0x6a, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x66, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x10, 0xa0, 0x6f, 0xff, 0x0f, 0xa0, 0x6e, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0a, 0xa2, 0x69, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0a, 0xa0, 0x6e, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0b, 0xa6, 0x66, 0xff, 0x09, 0xa5, 0x67, 0xff, 0x0d, 0xa0, 0x69, 0xff, 0x1a, 0x99, 0x69, 0xff, 0x0b, 0x6f, 0x44, 0xff, 0x01, 0x47, 0x1c, 0xff, 0x0d, 0x6c, 0x45, 0xff, 0x19, 0x9c, 0x6a, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x15, 0x9d, 0x62, 0xff, 0x16, 0x8a, 0x5b, 0xff, 0x0d, 0x71, 0x4b, 0xff, 0x10, 0x74, 0x4f, 0xff, 0x15, 0x7c, 0x58, 0xff, 0x15, 0x73, 0x52, 0xff, 0x06, 0x53, 0x36, 0xff, 0x0d, 0x47, 0x2e, 0xff, 0x12, 0x47, 0x2d, 0xff, 0x10, 0x46, 0x2b, 0xff, 0x10, 0x44, 0x2b, 0xff, 0x14, 0x4b, 0x30, 0xff, 0x0d, 0x48, 0x2b, 0xff, 0x0a, 0x42, 0x30, 0xff, 0x0a, 0x3c, 0x3a, 0xff, 0x1a, 0x45, 0x57, 0xff, 0x21, 0x4d, 0x64, 0xff, 0x21, 0x54, 0x66, 0xff, 0x21, 0x51, 0x63, 0xff, 0x19, 0x46, 0x5e, 0xff, 0x15, 0x44, 0x5d, 0xff, 0x12, 0x42, 0x54, 0xff, 0x0e, 0x3c, 0x48, 0xff, 0x09, 0x39, 0x3f, 0xff, 0x09, 0x43, 0x3b, 0xff, 0x0b, 0x5a, 0x34, 0xff, 0x1b, 0x5c, 0x3b, 0xff, 0xb0, 0xb3, 0xbf, 0xff, 0xd6, 0xc3, 0xe1, 0xff, 0xa9, 0xa4, 0xbd, 0xff, 0xc0, 0xbe, 0xd6, 0xff, 0x99, 0xa5, 0xb6, 0xff, 0x46, 0x6e, 0x62, 0xff, 0x1c, 0x73, 0x46, 0xff, 0x08, 0x6d, 0x3c, 0xff, 0x08, 0x62, 0x34, 0xff, 0x11, 0x68, 0x3b, 0xff, 0x0f, 0x53, 0x33, 0xff, 0x02, 0x2b, 0x14, 0xff, 0x06, 0x35, 0x1b, 0xff, 0x0e, 0x41, 0x24, 0xff, 0x5e, 0x73, 0x67, 0xff, + 0x14, 0x96, 0x68, 0xff, 0x0f, 0x9b, 0x66, 0xff, 0x0d, 0x9b, 0x65, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x14, 0x98, 0x66, 0xff, 0x0e, 0x82, 0x51, 0xff, 0x02, 0x59, 0x32, 0xff, 0x02, 0x43, 0x27, 0xff, 0x01, 0x40, 0x1f, 0xff, 0x0a, 0x50, 0x25, 0xff, 0x13, 0x61, 0x2d, 0xff, 0x09, 0x5c, 0x22, 0xff, 0x04, 0x53, 0x17, 0xff, 0x08, 0x53, 0x18, 0xff, 0x0b, 0x52, 0x1a, 0xff, 0x09, 0x4b, 0x1e, 0xff, 0x05, 0x44, 0x1a, 0xff, 0x05, 0x46, 0x16, 0xff, 0x08, 0x4e, 0x17, 0xff, 0x0e, 0x5c, 0x28, 0xff, 0x0e, 0x67, 0x32, 0xff, 0x05, 0x6f, 0x26, 0xff, 0x03, 0x75, 0x22, 0xff, 0x06, 0x76, 0x29, 0xff, 0x0b, 0x78, 0x2a, 0xff, 0x0f, 0x7c, 0x29, 0xff, 0x10, 0x81, 0x2b, 0xff, 0x09, 0x82, 0x2b, 0xff, 0x08, 0x82, 0x2f, 0xff, 0x0b, 0x8a, 0x3c, 0xff, 0x14, 0x91, 0x4a, 0xff, 0x07, 0x7e, 0x42, 0xff, 0x13, 0x9f, 0x6a, 0xff, 0x0c, 0x9d, 0x70, 0xff, 0x0b, 0x9c, 0x6e, 0xff, 0x0d, 0xa2, 0x70, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x11, 0xa5, 0x78, 0xff, 0x19, 0xa4, 0x7b, 0xff, 0x13, 0xa2, 0x73, 0xff, 0x13, 0xa0, 0x73, 0xff, 0x15, 0xa0, 0x74, 0xff, 0x10, 0x9b, 0x72, 0xff, 0x16, 0x9f, 0x7a, 0xff, 0x2b, 0xb0, 0x8f, 0xff, 0x2e, 0xaf, 0x92, 0xff, 0x16, 0x98, 0x76, 0xff, 0x10, 0x9c, 0x6f, 0xff, 0x30, 0xb9, 0x97, 0xff, 0x4a, 0xd0, 0xba, 0xff, 0x1d, 0xa6, 0x8b, 0xff, 0x10, 0xa1, 0x78, 0xff, 0x20, 0xb7, 0x86, 0xff, 0x1f, 0xb7, 0x8a, 0xff, 0x38, 0xce, 0xa5, 0xff, 0x2f, 0xc7, 0x99, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0x9c, 0x64, 0xff, 0x0b, 0x9d, 0x63, 0xff, 0x09, 0x9a, 0x64, 0xff, 0x08, 0x99, 0x62, 0xff, 0x08, 0x9b, 0x63, 0xff, 0x07, 0x9c, 0x64, 0xff, 0x07, 0x9f, 0x66, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x12, 0xa6, 0x73, 0xff, 0x11, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x15, 0xa8, 0x7b, 0xff, 0x19, 0xa9, 0x7f, 0xff, 0x1c, 0xa9, 0x82, 0xff, 0x1f, 0xa9, 0x87, 0xff, 0x21, 0xa9, 0x87, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x24, 0xaa, 0x89, 0xff, 0x26, 0xab, 0x8b, 0xff, 0x29, 0xab, 0x8d, 0xff, 0x2a, 0xac, 0x8e, 0xff, 0x2b, 0xad, 0x90, 0xff, 0x2e, 0xab, 0x94, 0xff, 0x30, 0xac, 0x96, 0xff, 0x31, 0xad, 0x98, 0xff, 0x31, 0xac, 0x98, 0xff, 0x30, 0xab, 0x97, 0xff, 0x30, 0xac, 0x98, 0xff, 0x31, 0xad, 0x97, 0xff, 0x2f, 0xac, 0x94, 0xff, 0x2e, 0xaa, 0x94, 0xff, 0x2e, 0xab, 0x94, 0xff, 0x2f, 0xab, 0x94, 0xff, 0x30, 0xac, 0x94, 0xff, 0x2e, 0xad, 0x94, 0xff, 0x2d, 0xad, 0x93, 0xff, 0x2c, 0xac, 0x92, 0xff, 0x2c, 0xac, 0x91, 0xff, 0x2d, 0xab, 0x92, 0xff, 0x2d, 0xac, 0x93, 0xff, 0x2e, 0xae, 0x92, 0xff, 0x2b, 0xac, 0x91, 0xff, 0x27, 0xaa, 0x8d, 0xff, 0x25, 0xaa, 0x8b, 0xff, 0x23, 0xa9, 0x89, 0xff, 0x22, 0xa9, 0x89, 0xff, 0x1f, 0xab, 0x85, 0xff, 0x1e, 0xab, 0x84, 0xff, 0x1e, 0xac, 0x83, 0xff, 0x1c, 0xac, 0x81, 0xff, 0x1a, 0xac, 0x81, 0xff, 0x19, 0xac, 0x7f, 0xff, 0x16, 0xab, 0x7b, 0xff, 0x15, 0xa9, 0x79, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0e, 0xa9, 0x76, 0xff, 0x0f, 0xaa, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0f, 0xa9, 0x73, 0xff, 0x12, 0xab, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x13, 0xa7, 0x76, 0xff, 0x13, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x12, 0xa9, 0x77, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x13, 0xa8, 0x76, 0xff, 0x13, 0xa7, 0x75, 0xff, 0x13, 0xa7, 0x75, 0xff, 0x13, 0xa5, 0x73, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x12, 0xa7, 0x77, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x10, 0xa3, 0x73, 0xff, 0x0c, 0x9e, 0x6e, 0xff, 0x0d, 0x9d, 0x6d, 0xff, 0x0d, 0x9d, 0x6e, 0xff, 0x0d, 0x9d, 0x6d, 0xff, 0x11, 0xa1, 0x70, 0xff, 0x0c, 0xa0, 0x6e, 0xff, 0x07, 0x9d, 0x6b, 0xff, 0x0a, 0xa2, 0x6f, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x14, 0xa9, 0x7f, 0xff, 0x1b, 0xb0, 0x85, 0xff, 0x16, 0xac, 0x80, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x15, 0xab, 0x7d, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x18, 0xac, 0x7f, 0xff, 0x14, 0xaa, 0x7b, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa1, 0x68, 0xff, 0x0e, 0xa1, 0x67, 0xff, 0x10, 0xa2, 0x68, 0xff, 0x12, 0xa2, 0x69, 0xff, 0x12, 0xa3, 0x6a, 0xff, 0x13, 0xa4, 0x6b, 0xff, 0x0f, 0xa2, 0x68, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0a, 0xa5, 0x66, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x0a, 0xa3, 0x64, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0b, 0xa1, 0x6d, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x0f, 0xa1, 0x6f, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0f, 0xa4, 0x6a, 0xff, 0x0e, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa1, 0x6d, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0d, 0x9b, 0x64, 0xff, 0x0b, 0x76, 0x42, 0xff, 0x0a, 0x76, 0x48, 0xff, 0x15, 0x9e, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0a, 0xa0, 0x65, 0xff, 0x06, 0xa0, 0x66, 0xff, 0x05, 0xa0, 0x60, 0xff, 0x0d, 0x9a, 0x66, 0xff, 0x16, 0x95, 0x66, 0xff, 0x14, 0x94, 0x64, 0xff, 0x0e, 0x91, 0x61, 0xff, 0x11, 0x8a, 0x5c, 0xff, 0x0b, 0x71, 0x48, 0xff, 0x0e, 0x5e, 0x39, 0xff, 0x11, 0x59, 0x36, 0xff, 0x0d, 0x55, 0x31, 0xff, 0x0b, 0x52, 0x32, 0xff, 0x0b, 0x53, 0x32, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x09, 0x4b, 0x31, 0xff, 0x06, 0x3c, 0x34, 0xff, 0x13, 0x3e, 0x4b, 0xff, 0x20, 0x49, 0x5e, 0xff, 0x23, 0x4e, 0x64, 0xff, 0x22, 0x4d, 0x61, 0xff, 0x1d, 0x4a, 0x60, 0xff, 0x14, 0x44, 0x5b, 0xff, 0x12, 0x43, 0x52, 0xff, 0x0f, 0x3c, 0x46, 0xff, 0x0a, 0x36, 0x3c, 0xff, 0x05, 0x3a, 0x34, 0xff, 0x0d, 0x57, 0x35, 0xff, 0x1d, 0x5b, 0x3f, 0xff, 0xa1, 0xb1, 0xb7, 0xff, 0xa1, 0xab, 0xb7, 0xff, 0x41, 0x61, 0x5b, 0xff, 0x4e, 0x73, 0x68, 0xff, 0x2e, 0x5c, 0x4f, 0xff, 0x0e, 0x4f, 0x32, 0xff, 0x14, 0x72, 0x43, 0xff, 0x07, 0x6c, 0x3d, 0xff, 0x0a, 0x63, 0x36, 0xff, 0x0f, 0x67, 0x3a, 0xff, 0x04, 0x41, 0x22, 0xff, 0x00, 0x25, 0x10, 0xff, 0x08, 0x39, 0x1f, 0xff, 0x0b, 0x42, 0x26, 0xff, 0x60, 0x74, 0x67, 0xff, + 0x0b, 0x9b, 0x67, 0xff, 0x07, 0x9c, 0x63, 0xff, 0x0f, 0x9b, 0x64, 0xff, 0x19, 0x9c, 0x69, 0xff, 0x1c, 0x8d, 0x5f, 0xff, 0x06, 0x5e, 0x34, 0xff, 0x02, 0x46, 0x23, 0xff, 0x04, 0x41, 0x24, 0xff, 0x04, 0x45, 0x21, 0xff, 0x14, 0x5d, 0x2d, 0xff, 0x13, 0x60, 0x2a, 0xff, 0x03, 0x53, 0x15, 0xff, 0x05, 0x58, 0x18, 0xff, 0x0c, 0x62, 0x23, 0xff, 0x0f, 0x65, 0x28, 0xff, 0x15, 0x67, 0x36, 0xff, 0x0a, 0x4f, 0x31, 0xff, 0x03, 0x43, 0x23, 0xff, 0x08, 0x4b, 0x1b, 0xff, 0x0c, 0x57, 0x20, 0xff, 0x13, 0x64, 0x2e, 0xff, 0x0f, 0x6e, 0x29, 0xff, 0x0a, 0x71, 0x24, 0xff, 0x07, 0x75, 0x29, 0xff, 0x09, 0x77, 0x2a, 0xff, 0x09, 0x7d, 0x28, 0xff, 0x12, 0x8c, 0x33, 0xff, 0x13, 0x95, 0x3d, 0xff, 0x0b, 0x91, 0x41, 0xff, 0x1c, 0xa0, 0x5c, 0xff, 0x0c, 0x87, 0x4d, 0xff, 0x0f, 0x93, 0x61, 0xff, 0x0e, 0xa1, 0x70, 0xff, 0x0a, 0xa1, 0x71, 0xff, 0x0b, 0xa3, 0x71, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa5, 0x76, 0xff, 0x10, 0x9f, 0x72, 0xff, 0x10, 0x9f, 0x6f, 0xff, 0x14, 0xa1, 0x73, 0xff, 0x12, 0x9d, 0x71, 0xff, 0x15, 0x9d, 0x75, 0xff, 0x19, 0x9d, 0x7a, 0xff, 0x22, 0xa1, 0x82, 0xff, 0x22, 0x9e, 0x84, 0xff, 0x13, 0x90, 0x73, 0xff, 0x11, 0x9a, 0x71, 0xff, 0x1e, 0xa7, 0x84, 0xff, 0x46, 0xd3, 0xb3, 0xff, 0x16, 0xa6, 0x82, 0xff, 0x18, 0xaf, 0x81, 0xff, 0x1c, 0xb5, 0x86, 0xff, 0x14, 0xad, 0x85, 0xff, 0x35, 0xcb, 0xa8, 0xff, 0x39, 0xd1, 0xa4, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0b, 0xa6, 0x68, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x08, 0x9d, 0x66, 0xff, 0x08, 0x9b, 0x64, 0xff, 0x0b, 0x9d, 0x66, 0xff, 0x0d, 0x9e, 0x67, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0a, 0x9c, 0x65, 0xff, 0x06, 0x9b, 0x63, 0xff, 0x07, 0x9f, 0x64, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa2, 0x68, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x11, 0xa6, 0x72, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x77, 0xff, 0x15, 0xa7, 0x7b, 0xff, 0x1a, 0xa7, 0x7f, 0xff, 0x1c, 0xa8, 0x82, 0xff, 0x1e, 0xa8, 0x86, 0xff, 0x21, 0xa9, 0x87, 0xff, 0x23, 0xab, 0x89, 0xff, 0x25, 0xaa, 0x8a, 0xff, 0x26, 0xab, 0x8b, 0xff, 0x28, 0xab, 0x8c, 0xff, 0x2a, 0xac, 0x8d, 0xff, 0x2b, 0xad, 0x90, 0xff, 0x2c, 0xaa, 0x92, 0xff, 0x2e, 0xac, 0x94, 0xff, 0x30, 0xad, 0x97, 0xff, 0x30, 0xad, 0x98, 0xff, 0x2e, 0xac, 0x96, 0xff, 0x2e, 0xac, 0x96, 0xff, 0x2e, 0xae, 0x94, 0xff, 0x2e, 0xac, 0x93, 0xff, 0x2c, 0xaa, 0x92, 0xff, 0x2e, 0xac, 0x93, 0xff, 0x2f, 0xad, 0x94, 0xff, 0x2f, 0xad, 0x93, 0xff, 0x2c, 0xad, 0x92, 0xff, 0x2b, 0xab, 0x91, 0xff, 0x2b, 0xac, 0x90, 0xff, 0x2b, 0xac, 0x8f, 0xff, 0x2b, 0xab, 0x8f, 0xff, 0x2b, 0xac, 0x90, 0xff, 0x29, 0xac, 0x8e, 0xff, 0x27, 0xab, 0x8c, 0xff, 0x24, 0xaa, 0x8a, 0xff, 0x23, 0xab, 0x89, 0xff, 0x21, 0xab, 0x88, 0xff, 0x20, 0xab, 0x87, 0xff, 0x1f, 0xac, 0x83, 0xff, 0x1d, 0xad, 0x82, 0xff, 0x1b, 0xac, 0x81, 0xff, 0x19, 0xab, 0x7e, 0xff, 0x17, 0xaa, 0x7c, 0xff, 0x15, 0xa9, 0x7a, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x12, 0xa8, 0x77, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x11, 0xaa, 0x75, 0xff, 0x12, 0xaa, 0x75, 0xff, 0x12, 0xa9, 0x75, 0xff, 0x14, 0xa8, 0x77, 0xff, 0x16, 0xa7, 0x79, 0xff, 0x16, 0xa8, 0x79, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x12, 0xa6, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x12, 0xa7, 0x77, 0xff, 0x11, 0xa4, 0x74, 0xff, 0x10, 0xa2, 0x72, 0xff, 0x10, 0xa2, 0x72, 0xff, 0x10, 0xa1, 0x71, 0xff, 0x10, 0xa2, 0x72, 0xff, 0x0b, 0x9e, 0x6e, 0xff, 0x08, 0x9e, 0x6c, 0xff, 0x0d, 0xa3, 0x71, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x18, 0xac, 0x83, 0xff, 0x21, 0xb6, 0x8a, 0xff, 0x1a, 0xb1, 0x83, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x13, 0xa9, 0x7b, 0xff, 0x15, 0xaa, 0x7c, 0xff, 0x23, 0xb7, 0x89, 0xff, 0x24, 0xb6, 0x8a, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0f, 0xa1, 0x69, 0xff, 0x0d, 0x9e, 0x66, 0xff, 0x0c, 0x9b, 0x64, 0xff, 0x09, 0x96, 0x5f, 0xff, 0x0b, 0x98, 0x61, 0xff, 0x11, 0x9f, 0x68, 0xff, 0x0e, 0x9d, 0x66, 0xff, 0x0f, 0xa1, 0x69, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x05, 0xa0, 0x63, 0xff, 0x05, 0x9d, 0x64, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x07, 0x9e, 0x65, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x09, 0xa2, 0x66, 0xff, 0x09, 0xa1, 0x62, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0e, 0xa1, 0x6f, 0xff, 0x0e, 0xa1, 0x6e, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0d, 0x9f, 0x70, 0xff, 0x0f, 0x9f, 0x72, 0xff, 0x09, 0xa0, 0x6e, 0xff, 0x06, 0xa3, 0x6d, 0xff, 0x11, 0x97, 0x61, 0xff, 0x06, 0x8d, 0x59, 0xff, 0x0b, 0x9f, 0x6b, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0b, 0x9f, 0x65, 0xff, 0x04, 0x9f, 0x65, 0xff, 0x01, 0x9f, 0x63, 0xff, 0x05, 0x9a, 0x69, 0xff, 0x0f, 0x9a, 0x67, 0xff, 0x0c, 0x99, 0x62, 0xff, 0x07, 0x97, 0x61, 0xff, 0x0b, 0x92, 0x5e, 0xff, 0x0e, 0x85, 0x54, 0xff, 0x11, 0x75, 0x48, 0xff, 0x0f, 0x6c, 0x41, 0xff, 0x0a, 0x66, 0x3b, 0xff, 0x0b, 0x63, 0x3c, 0xff, 0x0b, 0x62, 0x3a, 0xff, 0x09, 0x5f, 0x36, 0xff, 0x0c, 0x58, 0x37, 0xff, 0x08, 0x48, 0x37, 0xff, 0x0d, 0x3c, 0x40, 0xff, 0x1b, 0x43, 0x53, 0xff, 0x29, 0x4f, 0x64, 0xff, 0x23, 0x49, 0x5d, 0xff, 0x1f, 0x4a, 0x5f, 0xff, 0x15, 0x46, 0x5b, 0xff, 0x0e, 0x3f, 0x4d, 0xff, 0x10, 0x3c, 0x46, 0xff, 0x0d, 0x35, 0x3d, 0xff, 0x07, 0x38, 0x35, 0xff, 0x10, 0x55, 0x37, 0xff, 0x13, 0x55, 0x39, 0xff, 0x4d, 0x77, 0x71, 0xff, 0x3d, 0x6b, 0x63, 0xff, 0x10, 0x4d, 0x33, 0xff, 0x08, 0x40, 0x20, 0xff, 0x12, 0x52, 0x33, 0xff, 0x04, 0x51, 0x2b, 0xff, 0x12, 0x71, 0x41, 0xff, 0x0d, 0x6f, 0x40, 0xff, 0x0a, 0x65, 0x37, 0xff, 0x0e, 0x66, 0x39, 0xff, 0x05, 0x41, 0x22, 0xff, 0x01, 0x23, 0x0e, 0xff, 0x0a, 0x3d, 0x23, 0xff, 0x0a, 0x45, 0x28, 0xff, 0x62, 0x75, 0x67, 0xff, + 0x07, 0x9b, 0x65, 0xff, 0x0f, 0x9c, 0x63, 0xff, 0x16, 0x92, 0x5c, 0xff, 0x14, 0x7f, 0x52, 0xff, 0x09, 0x5f, 0x39, 0xff, 0x06, 0x44, 0x26, 0xff, 0x0c, 0x4a, 0x2a, 0xff, 0x06, 0x4d, 0x26, 0xff, 0x0b, 0x55, 0x27, 0xff, 0x11, 0x5e, 0x28, 0xff, 0x0b, 0x59, 0x1d, 0xff, 0x12, 0x65, 0x28, 0xff, 0x10, 0x68, 0x2c, 0xff, 0x09, 0x69, 0x2d, 0xff, 0x0e, 0x71, 0x3f, 0xff, 0x08, 0x63, 0x55, 0xff, 0x03, 0x50, 0x60, 0xff, 0x03, 0x4a, 0x5b, 0xff, 0x02, 0x45, 0x3c, 0xff, 0x01, 0x44, 0x25, 0xff, 0x03, 0x4c, 0x29, 0xff, 0x07, 0x50, 0x25, 0xff, 0x09, 0x5d, 0x25, 0xff, 0x0c, 0x68, 0x25, 0xff, 0x11, 0x73, 0x2c, 0xff, 0x08, 0x76, 0x2a, 0xff, 0x0e, 0x87, 0x38, 0xff, 0x16, 0x95, 0x4e, 0xff, 0x1d, 0x98, 0x62, 0xff, 0x0f, 0x7b, 0x5f, 0xff, 0x14, 0x83, 0x70, 0xff, 0x12, 0x9d, 0x7f, 0xff, 0x0e, 0xa1, 0x79, 0xff, 0x0f, 0xa4, 0x73, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x12, 0xa4, 0x77, 0xff, 0x16, 0xa3, 0x79, 0xff, 0x0d, 0xa2, 0x74, 0xff, 0x13, 0xa4, 0x76, 0xff, 0x13, 0xa1, 0x75, 0xff, 0x12, 0xa0, 0x74, 0xff, 0x14, 0xa1, 0x76, 0xff, 0x16, 0xa0, 0x77, 0xff, 0x1c, 0x9e, 0x7a, 0xff, 0x1c, 0x9b, 0x79, 0xff, 0x18, 0x95, 0x77, 0xff, 0x17, 0x99, 0x78, 0xff, 0x0e, 0x98, 0x6e, 0xff, 0x08, 0x96, 0x6b, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x09, 0xa1, 0x72, 0xff, 0x1d, 0xb7, 0x87, 0xff, 0x1e, 0xb7, 0x8c, 0xff, 0x1e, 0xb2, 0x91, 0xff, 0x1a, 0xad, 0x8e, 0xff, 0x12, 0xa7, 0x7f, 0xff, 0x0a, 0xa2, 0x72, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x0a, 0xa6, 0x68, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x07, 0x9f, 0x65, 0xff, 0x06, 0x9c, 0x64, 0xff, 0x08, 0x9b, 0x64, 0xff, 0x09, 0x9e, 0x64, 0xff, 0x0c, 0xa0, 0x66, 0xff, 0x0d, 0xa2, 0x68, 0xff, 0x0a, 0xa0, 0x67, 0xff, 0x08, 0xa0, 0x65, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x08, 0xa1, 0x68, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x13, 0xa7, 0x77, 0xff, 0x17, 0xa7, 0x7c, 0xff, 0x1b, 0xa8, 0x82, 0xff, 0x1e, 0xa8, 0x85, 0xff, 0x1e, 0xa8, 0x86, 0xff, 0x20, 0xa9, 0x87, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x24, 0xaa, 0x89, 0xff, 0x25, 0xaa, 0x8a, 0xff, 0x27, 0xa9, 0x8a, 0xff, 0x28, 0xaa, 0x8b, 0xff, 0x29, 0xab, 0x8d, 0xff, 0x2a, 0xaa, 0x8f, 0xff, 0x2b, 0xab, 0x91, 0xff, 0x2c, 0xab, 0x92, 0xff, 0x2c, 0xab, 0x93, 0xff, 0x2c, 0xad, 0x94, 0xff, 0x2b, 0xad, 0x92, 0xff, 0x2b, 0xae, 0x92, 0xff, 0x2b, 0xad, 0x90, 0xff, 0x2a, 0xab, 0x8f, 0xff, 0x2b, 0xac, 0x90, 0xff, 0x2b, 0xad, 0x90, 0xff, 0x29, 0xac, 0x8f, 0xff, 0x29, 0xab, 0x8f, 0xff, 0x28, 0xab, 0x8d, 0xff, 0x27, 0xac, 0x8d, 0xff, 0x27, 0xac, 0x8d, 0xff, 0x27, 0xaa, 0x8b, 0xff, 0x26, 0xab, 0x8b, 0xff, 0x25, 0xac, 0x8b, 0xff, 0x23, 0xab, 0x8a, 0xff, 0x22, 0xac, 0x88, 0xff, 0x20, 0xad, 0x86, 0xff, 0x1d, 0xad, 0x85, 0xff, 0x1b, 0xac, 0x83, 0xff, 0x18, 0xab, 0x7d, 0xff, 0x17, 0xaa, 0x7c, 0xff, 0x14, 0xaa, 0x7a, 0xff, 0x13, 0xa9, 0x79, 0xff, 0x12, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x12, 0xa8, 0x75, 0xff, 0x13, 0xa6, 0x75, 0xff, 0x14, 0xa1, 0x75, 0xff, 0x19, 0xa1, 0x78, 0xff, 0x0f, 0x9d, 0x6f, 0xff, 0x0e, 0xa2, 0x70, 0xff, 0x12, 0xa6, 0x74, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa5, 0x75, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x12, 0xa5, 0x75, 0xff, 0x11, 0xa4, 0x74, 0xff, 0x0e, 0xa2, 0x72, 0xff, 0x0d, 0xa3, 0x72, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x13, 0xa7, 0x79, 0xff, 0x21, 0xb2, 0x89, 0xff, 0x18, 0xad, 0x80, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x11, 0xa9, 0x7b, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x13, 0xa9, 0x7c, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x13, 0xa7, 0x7b, 0xff, 0x18, 0xac, 0x7e, 0xff, 0x17, 0xa9, 0x7c, 0xff, 0x13, 0xa4, 0x76, 0xff, 0x27, 0xb8, 0x89, 0xff, 0x20, 0xad, 0x83, 0xff, 0x15, 0xa0, 0x7c, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0d, 0x9f, 0x67, 0xff, 0x07, 0x97, 0x60, 0xff, 0x08, 0x95, 0x5e, 0xff, 0x04, 0x8f, 0x59, 0xff, 0x05, 0x8e, 0x59, 0xff, 0x0a, 0x93, 0x5f, 0xff, 0x09, 0x92, 0x5e, 0xff, 0x07, 0x96, 0x60, 0xff, 0x08, 0xa0, 0x64, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x0b, 0xa0, 0x69, 0xff, 0x10, 0xa2, 0x6d, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x05, 0x99, 0x5f, 0xff, 0x05, 0x9a, 0x5d, 0xff, 0x09, 0xa1, 0x61, 0xff, 0x07, 0xa0, 0x5f, 0xff, 0x0a, 0xa3, 0x65, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0c, 0xa1, 0x6d, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x08, 0xa4, 0x6a, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x07, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0f, 0xa0, 0x6c, 0xff, 0x12, 0xa2, 0x70, 0xff, 0x0e, 0xa0, 0x6f, 0xff, 0x07, 0x9e, 0x6f, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x05, 0xa3, 0x6a, 0xff, 0x03, 0xa2, 0x69, 0xff, 0x0a, 0x9f, 0x6a, 0xff, 0x0d, 0x9f, 0x68, 0xff, 0x06, 0x9e, 0x66, 0xff, 0x02, 0x9c, 0x67, 0xff, 0x05, 0x99, 0x69, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0a, 0x9b, 0x63, 0xff, 0x07, 0x99, 0x61, 0xff, 0x06, 0x95, 0x5d, 0xff, 0x0b, 0x90, 0x59, 0xff, 0x08, 0x80, 0x4c, 0xff, 0x08, 0x79, 0x46, 0xff, 0x0b, 0x78, 0x46, 0xff, 0x0d, 0x76, 0x45, 0xff, 0x0e, 0x74, 0x44, 0xff, 0x0c, 0x70, 0x41, 0xff, 0x0f, 0x69, 0x40, 0xff, 0x11, 0x5d, 0x3f, 0xff, 0x0a, 0x43, 0x37, 0xff, 0x10, 0x3d, 0x40, 0xff, 0x28, 0x4b, 0x5d, 0xff, 0x21, 0x43, 0x57, 0xff, 0x1e, 0x47, 0x5b, 0xff, 0x19, 0x49, 0x5c, 0xff, 0x0b, 0x3c, 0x48, 0xff, 0x13, 0x3d, 0x46, 0xff, 0x11, 0x33, 0x3e, 0xff, 0x09, 0x33, 0x34, 0xff, 0x12, 0x51, 0x39, 0xff, 0x08, 0x52, 0x31, 0xff, 0x07, 0x4d, 0x34, 0xff, 0x03, 0x50, 0x35, 0xff, 0x0c, 0x5a, 0x35, 0xff, 0x06, 0x44, 0x19, 0xff, 0x14, 0x59, 0x31, 0xff, 0x05, 0x57, 0x32, 0xff, 0x19, 0x74, 0x48, 0xff, 0x17, 0x74, 0x46, 0xff, 0x09, 0x65, 0x36, 0xff, 0x0d, 0x68, 0x3b, 0xff, 0x0e, 0x4e, 0x2f, 0xff, 0x01, 0x24, 0x0f, 0xff, 0x09, 0x41, 0x26, 0xff, 0x06, 0x48, 0x28, 0xff, 0x61, 0x75, 0x67, 0xff, + 0x0c, 0x9b, 0x66, 0xff, 0x0d, 0x8f, 0x59, 0xff, 0x07, 0x6c, 0x3c, 0xff, 0x05, 0x5d, 0x36, 0xff, 0x01, 0x4a, 0x2b, 0xff, 0x08, 0x47, 0x2e, 0xff, 0x0d, 0x50, 0x2f, 0xff, 0x0a, 0x5c, 0x2a, 0xff, 0x09, 0x5a, 0x24, 0xff, 0x0a, 0x5a, 0x1e, 0xff, 0x11, 0x63, 0x24, 0xff, 0x11, 0x69, 0x2b, 0xff, 0x0d, 0x68, 0x2f, 0xff, 0x13, 0x71, 0x3c, 0xff, 0x0c, 0x6a, 0x4b, 0xff, 0x05, 0x5e, 0x75, 0xff, 0x14, 0x69, 0xa3, 0xff, 0x1e, 0x76, 0xb1, 0xff, 0x1a, 0x7a, 0x99, 0xff, 0x15, 0x75, 0x7d, 0xff, 0x18, 0x75, 0x7a, 0xff, 0x08, 0x5c, 0x55, 0xff, 0x05, 0x58, 0x44, 0xff, 0x05, 0x54, 0x33, 0xff, 0x06, 0x58, 0x34, 0xff, 0x03, 0x5d, 0x31, 0xff, 0x07, 0x6d, 0x40, 0xff, 0x13, 0x80, 0x5b, 0xff, 0x0d, 0x76, 0x65, 0xff, 0x11, 0x78, 0x85, 0xff, 0x26, 0x96, 0xa6, 0xff, 0x12, 0x99, 0x8c, 0xff, 0x11, 0x9e, 0x7f, 0xff, 0x14, 0xa5, 0x77, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x14, 0xa1, 0x78, 0xff, 0x1a, 0x9f, 0x7a, 0xff, 0x11, 0xa4, 0x77, 0xff, 0x11, 0xa4, 0x75, 0xff, 0x18, 0xa4, 0x7b, 0xff, 0x18, 0xa6, 0x7c, 0xff, 0x15, 0xa3, 0x78, 0xff, 0x17, 0xa3, 0x78, 0xff, 0x1b, 0xa2, 0x79, 0xff, 0x1c, 0xa3, 0x79, 0xff, 0x1c, 0xa2, 0x7a, 0xff, 0x15, 0x9d, 0x75, 0xff, 0x07, 0x91, 0x65, 0xff, 0x09, 0x97, 0x67, 0xff, 0x17, 0xad, 0x79, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x32, 0xc4, 0x9f, 0xff, 0x41, 0xcc, 0xad, 0xff, 0x18, 0xa2, 0x85, 0xff, 0x05, 0x98, 0x71, 0xff, 0x09, 0x9f, 0x70, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x0a, 0xa7, 0x68, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x07, 0x9c, 0x64, 0xff, 0x06, 0x9d, 0x61, 0xff, 0x09, 0xa0, 0x65, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x05, 0x9e, 0x66, 0xff, 0x05, 0x9e, 0x66, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x15, 0xa9, 0x7a, 0xff, 0x19, 0xaa, 0x7f, 0xff, 0x1e, 0xab, 0x85, 0xff, 0x21, 0xab, 0x89, 0xff, 0x21, 0xab, 0x88, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x23, 0xab, 0x89, 0xff, 0x26, 0xab, 0x8a, 0xff, 0x26, 0xab, 0x8b, 0xff, 0x28, 0xaa, 0x8b, 0xff, 0x29, 0xab, 0x8c, 0xff, 0x2a, 0xac, 0x8d, 0xff, 0x2a, 0xac, 0x8f, 0xff, 0x2a, 0xab, 0x90, 0xff, 0x29, 0xaa, 0x90, 0xff, 0x28, 0xa9, 0x90, 0xff, 0x28, 0xab, 0x90, 0xff, 0x27, 0xab, 0x8f, 0xff, 0x27, 0xac, 0x8d, 0xff, 0x27, 0xac, 0x8c, 0xff, 0x28, 0xab, 0x8d, 0xff, 0x29, 0xab, 0x8d, 0xff, 0x28, 0xab, 0x8d, 0xff, 0x26, 0xab, 0x8c, 0xff, 0x27, 0xac, 0x8d, 0xff, 0x27, 0xab, 0x8c, 0xff, 0x24, 0xab, 0x8b, 0xff, 0x23, 0xaa, 0x8a, 0xff, 0x24, 0xaa, 0x89, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x21, 0xaa, 0x87, 0xff, 0x20, 0xab, 0x86, 0xff, 0x1e, 0xab, 0x84, 0xff, 0x1b, 0xab, 0x82, 0xff, 0x18, 0xaa, 0x80, 0xff, 0x16, 0xa9, 0x7d, 0xff, 0x14, 0xa8, 0x79, 0xff, 0x12, 0xa8, 0x78, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x11, 0xa8, 0x75, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x08, 0xa0, 0x6b, 0xff, 0x0f, 0xa4, 0x70, 0xff, 0x16, 0xa6, 0x77, 0xff, 0x12, 0x9a, 0x70, 0xff, 0x14, 0x97, 0x70, 0xff, 0x0c, 0x97, 0x6a, 0xff, 0x12, 0xa4, 0x72, 0xff, 0x13, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x74, 0xff, 0x0e, 0xa4, 0x74, 0xff, 0x0e, 0xa4, 0x74, 0xff, 0x0f, 0xa4, 0x74, 0xff, 0x0e, 0xa3, 0x73, 0xff, 0x0d, 0xa1, 0x71, 0xff, 0x0b, 0xa1, 0x70, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0a, 0xa1, 0x6f, 0xff, 0x0e, 0xa3, 0x73, 0xff, 0x2c, 0xbc, 0x92, 0xff, 0x15, 0xaa, 0x7d, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x14, 0xac, 0x7d, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x19, 0xb0, 0x83, 0xff, 0x12, 0xa8, 0x7c, 0xff, 0x12, 0xa9, 0x7d, 0xff, 0x0e, 0xa4, 0x78, 0xff, 0x16, 0xaa, 0x7e, 0xff, 0x1d, 0xaf, 0x82, 0xff, 0x19, 0xa9, 0x7c, 0xff, 0x0f, 0x9e, 0x70, 0xff, 0x15, 0xa3, 0x73, 0xff, 0x19, 0xa3, 0x7a, 0xff, 0x24, 0xac, 0x8b, 0xff, 0x1a, 0xa7, 0x84, 0xff, 0x15, 0xa7, 0x7f, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa1, 0x66, 0xff, 0x0b, 0x9c, 0x64, 0xff, 0x0a, 0x99, 0x61, 0xff, 0x07, 0x91, 0x5b, 0xff, 0x04, 0x8d, 0x59, 0xff, 0x05, 0x8d, 0x59, 0xff, 0x06, 0x8d, 0x5b, 0xff, 0x07, 0x92, 0x5e, 0xff, 0x07, 0x9a, 0x62, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0f, 0xa0, 0x6a, 0xff, 0x0c, 0x99, 0x65, 0xff, 0x0f, 0x9d, 0x68, 0xff, 0x0d, 0x9d, 0x63, 0xff, 0x08, 0x9b, 0x5c, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x08, 0xa0, 0x5f, 0xff, 0x09, 0xa2, 0x64, 0xff, 0x09, 0xa0, 0x66, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0c, 0xa0, 0x6b, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x10, 0xa0, 0x6f, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0e, 0x9f, 0x6f, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x04, 0xa2, 0x69, 0xff, 0x04, 0xa3, 0x69, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x07, 0x9f, 0x66, 0xff, 0x04, 0x9c, 0x67, 0xff, 0x08, 0x9b, 0x65, 0xff, 0x0b, 0x9b, 0x64, 0xff, 0x0a, 0x9b, 0x64, 0xff, 0x0a, 0x9a, 0x63, 0xff, 0x09, 0x97, 0x5e, 0xff, 0x09, 0x92, 0x5a, 0xff, 0x05, 0x83, 0x4c, 0xff, 0x04, 0x7a, 0x45, 0xff, 0x0b, 0x7a, 0x45, 0xff, 0x0a, 0x78, 0x41, 0xff, 0x0a, 0x78, 0x42, 0xff, 0x09, 0x74, 0x42, 0xff, 0x0c, 0x6e, 0x41, 0xff, 0x11, 0x67, 0x3f, 0xff, 0x0b, 0x4c, 0x34, 0xff, 0x09, 0x3b, 0x35, 0xff, 0x1b, 0x40, 0x4f, 0xff, 0x20, 0x41, 0x53, 0xff, 0x19, 0x42, 0x55, 0xff, 0x17, 0x48, 0x59, 0xff, 0x0c, 0x3e, 0x48, 0xff, 0x14, 0x3b, 0x45, 0xff, 0x12, 0x31, 0x3d, 0xff, 0x09, 0x2f, 0x33, 0xff, 0x0e, 0x4a, 0x35, 0xff, 0x0a, 0x56, 0x31, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x06, 0x50, 0x2e, 0xff, 0x17, 0x63, 0x40, 0xff, 0x05, 0x43, 0x1c, 0xff, 0x0d, 0x50, 0x2a, 0xff, 0x05, 0x53, 0x34, 0xff, 0x18, 0x70, 0x48, 0xff, 0x17, 0x74, 0x44, 0xff, 0x09, 0x65, 0x35, 0xff, 0x0a, 0x66, 0x38, 0xff, 0x15, 0x56, 0x37, 0xff, 0x02, 0x27, 0x12, 0xff, 0x09, 0x45, 0x28, 0xff, 0x05, 0x4b, 0x29, 0xff, 0x62, 0x7c, 0x69, 0xff, + 0x12, 0x9b, 0x69, 0xff, 0x0c, 0x86, 0x53, 0xff, 0x0c, 0x6d, 0x43, 0xff, 0x19, 0x71, 0x59, 0xff, 0x12, 0x64, 0x54, 0xff, 0x0a, 0x53, 0x47, 0xff, 0x06, 0x53, 0x3b, 0xff, 0x12, 0x6a, 0x39, 0xff, 0x10, 0x67, 0x30, 0xff, 0x0c, 0x65, 0x27, 0xff, 0x0e, 0x69, 0x2b, 0xff, 0x0c, 0x69, 0x31, 0xff, 0x12, 0x6f, 0x40, 0xff, 0x0f, 0x67, 0x45, 0xff, 0x04, 0x5c, 0x59, 0xff, 0x20, 0x7f, 0xb7, 0xff, 0x37, 0x97, 0xef, 0xff, 0x2c, 0x9a, 0xf5, 0xff, 0x28, 0xa4, 0xeb, 0xff, 0x2b, 0xac, 0xe6, 0xff, 0x3a, 0xb7, 0xf1, 0xff, 0x26, 0xa1, 0xce, 0xff, 0x20, 0x91, 0xb6, 0xff, 0x1a, 0x77, 0x99, 0xff, 0x0c, 0x5e, 0x7d, 0xff, 0x03, 0x52, 0x65, 0xff, 0x06, 0x5e, 0x6a, 0xff, 0x09, 0x6e, 0x7b, 0xff, 0x0c, 0x7c, 0x99, 0xff, 0x27, 0xa8, 0xdc, 0xff, 0x1e, 0x9f, 0xd0, 0xff, 0x1d, 0x9f, 0xa7, 0xff, 0x17, 0x9b, 0x8c, 0xff, 0x1a, 0xa3, 0x79, 0xff, 0x12, 0xa6, 0x77, 0xff, 0x16, 0x9f, 0x7b, 0xff, 0x1c, 0x9d, 0x7b, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x15, 0xa8, 0x7a, 0xff, 0x1d, 0xa8, 0x83, 0xff, 0x1a, 0xa8, 0x81, 0xff, 0x14, 0xa4, 0x7a, 0xff, 0x16, 0xa4, 0x79, 0xff, 0x18, 0xa5, 0x79, 0xff, 0x19, 0xa6, 0x77, 0xff, 0x19, 0xa8, 0x78, 0xff, 0x13, 0xa2, 0x72, 0xff, 0x0a, 0x92, 0x62, 0xff, 0x11, 0x9d, 0x69, 0xff, 0x2c, 0xbf, 0x88, 0xff, 0x21, 0xb4, 0x82, 0xff, 0x0d, 0x9b, 0x71, 0xff, 0x30, 0xb7, 0x95, 0xff, 0x41, 0xc0, 0xa3, 0xff, 0x19, 0x97, 0x7a, 0xff, 0x0f, 0x9d, 0x79, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0a, 0xa7, 0x69, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x06, 0x9f, 0x63, 0xff, 0x08, 0xa0, 0x64, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x05, 0x9c, 0x64, 0xff, 0x01, 0x98, 0x60, 0xff, 0x04, 0x9e, 0x62, 0xff, 0x04, 0x9e, 0x63, 0xff, 0x06, 0xa0, 0x65, 0xff, 0x07, 0xa1, 0x67, 0xff, 0x07, 0xa1, 0x68, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x14, 0xa9, 0x79, 0xff, 0x18, 0xaa, 0x7e, 0xff, 0x1f, 0xac, 0x84, 0xff, 0x22, 0xac, 0x89, 0xff, 0x22, 0xac, 0x89, 0xff, 0x23, 0xad, 0x89, 0xff, 0x23, 0xad, 0x89, 0xff, 0x24, 0xab, 0x89, 0xff, 0x25, 0xac, 0x8b, 0xff, 0x27, 0xab, 0x8b, 0xff, 0x28, 0xac, 0x8c, 0xff, 0x29, 0xac, 0x8c, 0xff, 0x2a, 0xae, 0x8f, 0xff, 0x29, 0xad, 0x8d, 0xff, 0x27, 0xab, 0x8e, 0xff, 0x27, 0xab, 0x8e, 0xff, 0x27, 0xab, 0x8f, 0xff, 0x24, 0xab, 0x8c, 0xff, 0x24, 0xab, 0x8c, 0xff, 0x24, 0xac, 0x8a, 0xff, 0x25, 0xab, 0x8b, 0xff, 0x26, 0xab, 0x8b, 0xff, 0x25, 0xab, 0x8b, 0xff, 0x25, 0xac, 0x8b, 0xff, 0x25, 0xac, 0x8c, 0xff, 0x25, 0xab, 0x8b, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x21, 0xa9, 0x88, 0xff, 0x21, 0xaa, 0x86, 0xff, 0x1f, 0xa9, 0x85, 0xff, 0x1d, 0xa8, 0x83, 0xff, 0x1b, 0xa8, 0x81, 0xff, 0x19, 0xa8, 0x7f, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x12, 0xa7, 0x79, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x09, 0x9e, 0x69, 0xff, 0x0c, 0x9b, 0x6b, 0xff, 0x19, 0xa0, 0x78, 0xff, 0x13, 0x95, 0x6f, 0xff, 0x10, 0x8f, 0x6a, 0xff, 0x11, 0x99, 0x6e, 0xff, 0x15, 0xa1, 0x74, 0xff, 0x14, 0xa2, 0x76, 0xff, 0x14, 0xa4, 0x77, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x74, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0b, 0xa2, 0x71, 0xff, 0x09, 0xa0, 0x6f, 0xff, 0x08, 0x9f, 0x6e, 0xff, 0x09, 0xa0, 0x6e, 0xff, 0x0a, 0xa0, 0x6e, 0xff, 0x0a, 0x9d, 0x6d, 0xff, 0x18, 0xaa, 0x7d, 0xff, 0x10, 0xa4, 0x77, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x17, 0xaf, 0x7e, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x17, 0xad, 0x81, 0xff, 0x11, 0xa7, 0x7d, 0xff, 0x1a, 0xb1, 0x88, 0xff, 0x1e, 0xb2, 0x88, 0xff, 0x14, 0xa9, 0x7d, 0xff, 0x10, 0xa2, 0x75, 0xff, 0x0c, 0x9a, 0x6d, 0xff, 0x0f, 0x9c, 0x6e, 0xff, 0x10, 0x9d, 0x6e, 0xff, 0x1f, 0xa7, 0x7f, 0xff, 0x31, 0xb7, 0x97, 0xff, 0x2a, 0xb5, 0x94, 0xff, 0x22, 0xb2, 0x8c, 0xff, 0x14, 0xaa, 0x7e, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0e, 0xa0, 0x66, 0xff, 0x0d, 0x9d, 0x64, 0xff, 0x0d, 0x99, 0x63, 0xff, 0x08, 0x93, 0x5d, 0xff, 0x02, 0x8a, 0x56, 0xff, 0x07, 0x8f, 0x5c, 0xff, 0x0a, 0x94, 0x61, 0xff, 0x07, 0x96, 0x62, 0xff, 0x0d, 0x9b, 0x67, 0xff, 0x09, 0x93, 0x60, 0xff, 0x01, 0x7f, 0x4b, 0xff, 0x02, 0x83, 0x4f, 0xff, 0x09, 0x93, 0x59, 0xff, 0x09, 0x98, 0x5a, 0xff, 0x0d, 0x9f, 0x5f, 0xff, 0x08, 0xa0, 0x60, 0xff, 0x08, 0xa1, 0x63, 0xff, 0x07, 0x9f, 0x64, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x09, 0x9c, 0x67, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0b, 0x9d, 0x69, 0xff, 0x0b, 0x9e, 0x69, 0xff, 0x0c, 0x9f, 0x69, 0xff, 0x0d, 0xa0, 0x6a, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0d, 0xa1, 0x6a, 0xff, 0x0e, 0xa2, 0x6a, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x10, 0xa0, 0x6f, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0e, 0xa1, 0x6e, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x11, 0xa0, 0x71, 0xff, 0x0e, 0xa1, 0x70, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x06, 0xa6, 0x67, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x06, 0xa2, 0x6a, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0d, 0x9f, 0x6b, 0xff, 0x07, 0xa0, 0x65, 0xff, 0x06, 0x9f, 0x66, 0xff, 0x0c, 0xa0, 0x61, 0xff, 0x0a, 0x9c, 0x62, 0xff, 0x0a, 0x99, 0x64, 0xff, 0x09, 0x98, 0x62, 0xff, 0x0a, 0x97, 0x5f, 0xff, 0x08, 0x92, 0x57, 0xff, 0x09, 0x87, 0x4f, 0xff, 0x06, 0x7c, 0x45, 0xff, 0x0e, 0x78, 0x42, 0xff, 0x0b, 0x79, 0x3d, 0xff, 0x07, 0x79, 0x3f, 0xff, 0x06, 0x75, 0x42, 0xff, 0x0a, 0x72, 0x41, 0xff, 0x0d, 0x6a, 0x3c, 0xff, 0x13, 0x5c, 0x3a, 0xff, 0x0d, 0x45, 0x36, 0xff, 0x09, 0x30, 0x39, 0xff, 0x1c, 0x3e, 0x4e, 0xff, 0x12, 0x3b, 0x4a, 0xff, 0x12, 0x43, 0x51, 0xff, 0x0f, 0x41, 0x48, 0xff, 0x13, 0x3a, 0x42, 0xff, 0x12, 0x2d, 0x3a, 0xff, 0x0a, 0x2d, 0x32, 0xff, 0x09, 0x41, 0x2f, 0xff, 0x10, 0x58, 0x33, 0xff, 0x10, 0x52, 0x29, 0xff, 0x0f, 0x4e, 0x2c, 0xff, 0x13, 0x57, 0x39, 0xff, 0x05, 0x42, 0x21, 0xff, 0x04, 0x43, 0x22, 0xff, 0x04, 0x44, 0x2a, 0xff, 0x17, 0x6d, 0x47, 0xff, 0x14, 0x73, 0x41, 0xff, 0x0a, 0x66, 0x35, 0xff, 0x08, 0x65, 0x36, 0xff, 0x19, 0x5d, 0x3d, 0xff, 0x03, 0x2d, 0x15, 0xff, 0x08, 0x47, 0x29, 0xff, 0x05, 0x4d, 0x2a, 0xff, 0x63, 0x82, 0x6c, 0xff, + 0x11, 0x99, 0x69, 0xff, 0x14, 0x97, 0x64, 0xff, 0x1b, 0x8c, 0x71, 0xff, 0x20, 0x72, 0x8e, 0xff, 0x19, 0x5f, 0x8a, 0xff, 0x08, 0x4d, 0x72, 0xff, 0x03, 0x4a, 0x65, 0xff, 0x05, 0x55, 0x56, 0xff, 0x10, 0x69, 0x52, 0xff, 0x11, 0x74, 0x49, 0xff, 0x11, 0x74, 0x4e, 0xff, 0x11, 0x6d, 0x53, 0xff, 0x08, 0x5e, 0x4e, 0xff, 0x0a, 0x5f, 0x76, 0xff, 0x1f, 0x82, 0xbb, 0xff, 0x2c, 0xa0, 0xf0, 0xff, 0x2d, 0xa0, 0xfa, 0xff, 0x24, 0x99, 0xf7, 0xff, 0x23, 0x9a, 0xf4, 0xff, 0x20, 0x9c, 0xf3, 0xff, 0x26, 0xa8, 0xfa, 0xff, 0x22, 0xae, 0xf5, 0xff, 0x20, 0xa5, 0xea, 0xff, 0x35, 0xa1, 0xee, 0xff, 0x2c, 0x95, 0xe1, 0xff, 0x15, 0x7e, 0xc3, 0xff, 0x16, 0x8b, 0xc7, 0xff, 0x21, 0xb2, 0xe3, 0xff, 0x1d, 0xb7, 0xe9, 0xff, 0x1f, 0xba, 0xf5, 0xff, 0x18, 0xad, 0xe7, 0xff, 0x19, 0x9c, 0xc3, 0xff, 0x1d, 0x9a, 0xad, 0xff, 0x1c, 0xa1, 0x81, 0xff, 0x19, 0xa5, 0x7a, 0xff, 0x1c, 0xa2, 0x81, 0xff, 0x1e, 0xa5, 0x7b, 0xff, 0x19, 0xa3, 0x80, 0xff, 0x1c, 0xa5, 0x80, 0xff, 0x1d, 0xa5, 0x81, 0xff, 0x1c, 0xa4, 0x81, 0xff, 0x1c, 0xa4, 0x80, 0xff, 0x1b, 0xa3, 0x7f, 0xff, 0x1d, 0xa5, 0x80, 0xff, 0x1f, 0xa8, 0x81, 0xff, 0x1b, 0xa6, 0x7d, 0xff, 0x18, 0xa2, 0x78, 0xff, 0x07, 0x92, 0x62, 0xff, 0x22, 0xaa, 0x7d, 0xff, 0x40, 0xc7, 0x9b, 0xff, 0x26, 0xb0, 0x81, 0xff, 0x0e, 0x94, 0x66, 0xff, 0x12, 0x93, 0x6a, 0xff, 0x29, 0x9c, 0x83, 0xff, 0x43, 0xb3, 0xa0, 0xff, 0x39, 0xba, 0x9f, 0xff, 0x22, 0xab, 0x86, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x05, 0xa2, 0x69, 0xff, 0x06, 0xa2, 0x69, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0b, 0xa1, 0x68, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0c, 0xa0, 0x69, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x08, 0x9d, 0x65, 0xff, 0x07, 0x9f, 0x66, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x09, 0xa1, 0x68, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x10, 0xa5, 0x72, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x13, 0xa6, 0x77, 0xff, 0x16, 0xa8, 0x7a, 0xff, 0x18, 0xa7, 0x7b, 0xff, 0x1a, 0xa7, 0x7e, 0xff, 0x1c, 0xa9, 0x80, 0xff, 0x1b, 0xa9, 0x81, 0xff, 0x1b, 0xa9, 0x83, 0xff, 0x1c, 0xa9, 0x85, 0xff, 0x1e, 0xaa, 0x85, 0xff, 0x20, 0xab, 0x86, 0xff, 0x22, 0xaa, 0x86, 0xff, 0x24, 0xac, 0x89, 0xff, 0x24, 0xac, 0x8a, 0xff, 0x24, 0xac, 0x8a, 0xff, 0x23, 0xab, 0x89, 0xff, 0x22, 0xaa, 0x88, 0xff, 0x23, 0xab, 0x89, 0xff, 0x23, 0xac, 0x89, 0xff, 0x25, 0xae, 0x8a, 0xff, 0x23, 0xad, 0x8a, 0xff, 0x22, 0xac, 0x89, 0xff, 0x22, 0xac, 0x89, 0xff, 0x20, 0xab, 0x87, 0xff, 0x1f, 0xaa, 0x86, 0xff, 0x1f, 0xaa, 0x85, 0xff, 0x1d, 0xa9, 0x84, 0xff, 0x1d, 0xa9, 0x85, 0xff, 0x1b, 0xa9, 0x82, 0xff, 0x18, 0xa9, 0x80, 0xff, 0x15, 0xa8, 0x7d, 0xff, 0x12, 0xa6, 0x7a, 0xff, 0x12, 0xa6, 0x77, 0xff, 0x13, 0xa6, 0x76, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x10, 0xa7, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0f, 0xa9, 0x75, 0xff, 0x11, 0xa6, 0x78, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x13, 0xa9, 0x70, 0xff, 0x14, 0xa0, 0x6e, 0xff, 0x0f, 0x89, 0x67, 0xff, 0x1c, 0x89, 0x77, 0xff, 0x14, 0x87, 0x6b, 0xff, 0x0f, 0x8e, 0x62, 0xff, 0x1b, 0x98, 0x71, 0xff, 0x16, 0x8c, 0x74, 0xff, 0x14, 0x8e, 0x7c, 0xff, 0x19, 0x9c, 0x80, 0xff, 0x13, 0xa4, 0x75, 0xff, 0x0f, 0xa6, 0x72, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa4, 0x73, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0c, 0xa2, 0x70, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0f, 0xa4, 0x73, 0xff, 0x13, 0xa5, 0x73, 0xff, 0x0d, 0x9e, 0x6c, 0xff, 0x13, 0xa7, 0x74, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x17, 0xa8, 0x7b, 0xff, 0x20, 0xb2, 0x85, 0xff, 0x28, 0xba, 0x8e, 0xff, 0x16, 0xac, 0x7f, 0xff, 0x0b, 0xa3, 0x75, 0xff, 0x12, 0xa8, 0x80, 0xff, 0x2a, 0xbc, 0x9b, 0xff, 0x24, 0xb6, 0x8d, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x16, 0xa7, 0x7a, 0xff, 0x13, 0x9b, 0x72, 0xff, 0x16, 0xa3, 0x7a, 0xff, 0x21, 0xb2, 0x85, 0xff, 0x0d, 0x95, 0x6e, 0xff, 0x13, 0x95, 0x79, 0xff, 0x35, 0xbd, 0xa2, 0xff, 0x2d, 0xbe, 0x9a, 0xff, 0x10, 0xaa, 0x7a, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0e, 0xa4, 0x78, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x13, 0xa6, 0x73, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x0b, 0x9c, 0x66, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x08, 0x98, 0x64, 0xff, 0x08, 0x96, 0x65, 0xff, 0x09, 0x99, 0x67, 0xff, 0x06, 0x99, 0x65, 0xff, 0x09, 0x97, 0x62, 0xff, 0x0b, 0x93, 0x5f, 0xff, 0x03, 0x82, 0x4e, 0xff, 0x01, 0x77, 0x42, 0xff, 0x01, 0x82, 0x4a, 0xff, 0x06, 0x90, 0x56, 0xff, 0x0a, 0x9b, 0x5d, 0xff, 0x09, 0xa0, 0x64, 0xff, 0x07, 0x9f, 0x64, 0xff, 0x06, 0x9d, 0x65, 0xff, 0x07, 0x9d, 0x67, 0xff, 0x06, 0x9e, 0x69, 0xff, 0x08, 0x9f, 0x6a, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x08, 0xa0, 0x6a, 0xff, 0x0b, 0x9f, 0x69, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0c, 0x9d, 0x68, 0xff, 0x0a, 0x9a, 0x65, 0xff, 0x0c, 0x9a, 0x66, 0xff, 0x0d, 0x9c, 0x67, 0xff, 0x08, 0x97, 0x63, 0xff, 0x05, 0x94, 0x5f, 0xff, 0x04, 0x93, 0x5e, 0xff, 0x05, 0x93, 0x5e, 0xff, 0x05, 0x92, 0x5d, 0xff, 0x08, 0x95, 0x60, 0xff, 0x0b, 0x97, 0x62, 0xff, 0x0d, 0x99, 0x65, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x0c, 0x9f, 0x69, 0xff, 0x0d, 0xa0, 0x6a, 0xff, 0x0f, 0xa1, 0x6b, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0f, 0xa2, 0x6f, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0a, 0xa0, 0x69, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x08, 0xa0, 0x66, 0xff, 0x06, 0x9e, 0x65, 0xff, 0x08, 0x9e, 0x64, 0xff, 0x07, 0x9b, 0x68, 0xff, 0x0a, 0x99, 0x64, 0xff, 0x07, 0x97, 0x62, 0xff, 0x04, 0x97, 0x5c, 0xff, 0x0d, 0x91, 0x59, 0xff, 0x0f, 0x85, 0x57, 0xff, 0x06, 0x79, 0x4a, 0xff, 0x0c, 0x74, 0x45, 0xff, 0x0e, 0x79, 0x40, 0xff, 0x0b, 0x77, 0x3f, 0xff, 0x0b, 0x74, 0x40, 0xff, 0x0a, 0x74, 0x3f, 0xff, 0x09, 0x6e, 0x3e, 0xff, 0x0d, 0x63, 0x3c, 0xff, 0x14, 0x57, 0x3b, 0xff, 0x09, 0x35, 0x2e, 0xff, 0x0f, 0x33, 0x37, 0xff, 0x11, 0x3c, 0x3e, 0xff, 0x0c, 0x3e, 0x3c, 0xff, 0x0c, 0x40, 0x3b, 0xff, 0x0c, 0x36, 0x38, 0xff, 0x0c, 0x2b, 0x33, 0xff, 0x0a, 0x2c, 0x2e, 0xff, 0x05, 0x33, 0x27, 0xff, 0x17, 0x56, 0x38, 0xff, 0x0e, 0x51, 0x2e, 0xff, 0x0e, 0x4b, 0x30, 0xff, 0x05, 0x44, 0x27, 0xff, 0x06, 0x41, 0x1e, 0xff, 0x05, 0x38, 0x19, 0xff, 0x01, 0x30, 0x15, 0xff, 0x15, 0x64, 0x40, 0xff, 0x13, 0x6e, 0x41, 0xff, 0x08, 0x65, 0x35, 0xff, 0x08, 0x64, 0x36, 0xff, 0x18, 0x66, 0x3e, 0xff, 0x03, 0x38, 0x1a, 0xff, 0x08, 0x47, 0x28, 0xff, 0x06, 0x4e, 0x28, 0xff, 0x64, 0x84, 0x72, 0xff, + 0x0f, 0x97, 0x66, 0xff, 0x14, 0x97, 0x6e, 0xff, 0x17, 0x86, 0x82, 0xff, 0x10, 0x5d, 0x95, 0xff, 0x06, 0x46, 0x8c, 0xff, 0x01, 0x42, 0x86, 0xff, 0x02, 0x49, 0x89, 0xff, 0x00, 0x49, 0x7d, 0xff, 0x02, 0x4b, 0x72, 0xff, 0x03, 0x55, 0x6a, 0xff, 0x03, 0x57, 0x6e, 0xff, 0x03, 0x57, 0x78, 0xff, 0x09, 0x5e, 0x84, 0xff, 0x24, 0x86, 0xcd, 0xff, 0x2e, 0x9c, 0xf8, 0xff, 0x25, 0xa0, 0xf9, 0xff, 0x21, 0x9d, 0xf5, 0xff, 0x22, 0x9b, 0xf6, 0xff, 0x25, 0x98, 0xf7, 0xff, 0x26, 0x9a, 0xf8, 0xff, 0x1f, 0x9c, 0xf5, 0xff, 0x20, 0xae, 0xfd, 0xff, 0x16, 0xa4, 0xf3, 0xff, 0x23, 0x9b, 0xf5, 0xff, 0x29, 0x9d, 0xf8, 0xff, 0x23, 0x9c, 0xf3, 0xff, 0x23, 0xa4, 0xf4, 0xff, 0x20, 0xba, 0xfd, 0xff, 0x15, 0xba, 0xf7, 0xff, 0x14, 0xba, 0xf8, 0xff, 0x1d, 0xba, 0xf8, 0xff, 0x1a, 0xa0, 0xd8, 0xff, 0x1c, 0x98, 0xc2, 0xff, 0x1c, 0x9e, 0x91, 0xff, 0x1f, 0xa5, 0x80, 0xff, 0x20, 0xa4, 0x82, 0xff, 0x1f, 0xa8, 0x7d, 0xff, 0x1e, 0xa4, 0x83, 0xff, 0x1f, 0xa6, 0x81, 0xff, 0x20, 0xa5, 0x83, 0xff, 0x21, 0xa5, 0x85, 0xff, 0x21, 0xa6, 0x86, 0xff, 0x21, 0xa6, 0x86, 0xff, 0x23, 0xa8, 0x87, 0xff, 0x21, 0xa6, 0x84, 0xff, 0x1e, 0xa4, 0x80, 0xff, 0x0e, 0x98, 0x6e, 0xff, 0x03, 0x8f, 0x5d, 0xff, 0x1b, 0xa4, 0x79, 0xff, 0x15, 0x9a, 0x70, 0xff, 0x06, 0x8d, 0x5d, 0xff, 0x0a, 0x91, 0x5d, 0xff, 0x1e, 0x9f, 0x70, 0xff, 0x27, 0x9b, 0x7d, 0xff, 0x43, 0xb2, 0x9f, 0xff, 0x4c, 0xcb, 0xb0, 0xff, 0x1d, 0xa4, 0x7f, 0xff, 0x07, 0x96, 0x66, 0xff, 0x07, 0x9f, 0x69, 0xff, 0x06, 0xa0, 0x69, 0xff, 0x06, 0xa0, 0x68, 0xff, 0x09, 0xa2, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x07, 0x9c, 0x66, 0xff, 0x04, 0x9a, 0x64, 0xff, 0x06, 0x9b, 0x65, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0b, 0xa1, 0x6d, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x72, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x13, 0xa5, 0x76, 0xff, 0x14, 0xa5, 0x77, 0xff, 0x16, 0xa4, 0x79, 0xff, 0x15, 0xa6, 0x7a, 0xff, 0x14, 0xa4, 0x7a, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x14, 0xa6, 0x7d, 0xff, 0x16, 0xa6, 0x7d, 0xff, 0x18, 0xa6, 0x7e, 0xff, 0x19, 0xa6, 0x7e, 0xff, 0x1a, 0xa6, 0x7f, 0xff, 0x1b, 0xa7, 0x80, 0xff, 0x1b, 0xa7, 0x80, 0xff, 0x1a, 0xa7, 0x80, 0xff, 0x1b, 0xa8, 0x80, 0xff, 0x1d, 0xa8, 0x82, 0xff, 0x1d, 0xa9, 0x83, 0xff, 0x20, 0xac, 0x85, 0xff, 0x1b, 0xaa, 0x83, 0xff, 0x1b, 0xa9, 0x82, 0xff, 0x1b, 0xa9, 0x82, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x19, 0xa7, 0x80, 0xff, 0x1a, 0xa8, 0x80, 0xff, 0x17, 0xa6, 0x7e, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x15, 0xa5, 0x7b, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x0e, 0xa6, 0x79, 0xff, 0x0e, 0xa6, 0x78, 0xff, 0x11, 0xa5, 0x76, 0xff, 0x14, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa5, 0x76, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x09, 0x9c, 0x63, 0xff, 0x11, 0x9a, 0x68, 0xff, 0x10, 0x82, 0x61, 0xff, 0x17, 0x79, 0x6b, 0xff, 0x12, 0x80, 0x62, 0xff, 0x0d, 0x8d, 0x5b, 0xff, 0x13, 0x8e, 0x64, 0xff, 0x14, 0x85, 0x6e, 0xff, 0x15, 0x8a, 0x7b, 0xff, 0x15, 0x95, 0x7c, 0xff, 0x13, 0xa3, 0x73, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x11, 0xa1, 0x70, 0xff, 0x0a, 0x9c, 0x6a, 0xff, 0x15, 0xab, 0x78, 0xff, 0x1c, 0xae, 0x7c, 0xff, 0x17, 0xa6, 0x77, 0xff, 0x23, 0xb1, 0x85, 0xff, 0x43, 0xd1, 0xa5, 0xff, 0x16, 0xa6, 0x7b, 0xff, 0x0a, 0x9b, 0x70, 0xff, 0x16, 0xa8, 0x83, 0xff, 0x22, 0xaf, 0x91, 0xff, 0x15, 0xa7, 0x7e, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x1c, 0xb3, 0x85, 0xff, 0x1e, 0xa9, 0x82, 0xff, 0x2e, 0xbe, 0x94, 0xff, 0x2e, 0xc2, 0x92, 0xff, 0x04, 0x8f, 0x63, 0xff, 0x18, 0x9d, 0x7f, 0xff, 0x2c, 0xb5, 0x9a, 0xff, 0x1f, 0xb1, 0x8d, 0xff, 0x0b, 0xa6, 0x74, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x17, 0xab, 0x7d, 0xff, 0x11, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x07, 0x9e, 0x66, 0xff, 0x08, 0x9e, 0x67, 0xff, 0x08, 0x9d, 0x68, 0xff, 0x08, 0x9d, 0x69, 0xff, 0x08, 0x9b, 0x67, 0xff, 0x09, 0x9b, 0x69, 0xff, 0x08, 0x9c, 0x69, 0xff, 0x06, 0x9d, 0x67, 0xff, 0x09, 0x9a, 0x65, 0xff, 0x09, 0x94, 0x60, 0xff, 0x09, 0x8e, 0x5a, 0xff, 0x0c, 0x90, 0x5a, 0xff, 0x04, 0x89, 0x52, 0xff, 0x03, 0x8e, 0x56, 0xff, 0x0b, 0x9c, 0x62, 0xff, 0x0b, 0x9f, 0x67, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x08, 0x9c, 0x66, 0xff, 0x07, 0x9d, 0x68, 0xff, 0x08, 0x9e, 0x6a, 0xff, 0x09, 0x9f, 0x6c, 0xff, 0x08, 0x9d, 0x6a, 0xff, 0x0a, 0x9d, 0x68, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0d, 0x9e, 0x69, 0xff, 0x0a, 0x98, 0x63, 0xff, 0x05, 0x91, 0x5c, 0xff, 0x0a, 0x98, 0x63, 0xff, 0x06, 0x94, 0x5f, 0xff, 0x05, 0x93, 0x5e, 0xff, 0x06, 0x95, 0x60, 0xff, 0x07, 0x95, 0x60, 0xff, 0x04, 0x90, 0x5b, 0xff, 0x03, 0x8d, 0x59, 0xff, 0x04, 0x8d, 0x59, 0xff, 0x06, 0x8f, 0x5b, 0xff, 0x07, 0x90, 0x5c, 0xff, 0x04, 0x93, 0x5e, 0xff, 0x05, 0x95, 0x60, 0xff, 0x06, 0x96, 0x61, 0xff, 0x0a, 0x9a, 0x65, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x08, 0x9a, 0x64, 0xff, 0x05, 0x97, 0x61, 0xff, 0x09, 0x9c, 0x66, 0xff, 0x0c, 0xa1, 0x6c, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x06, 0x9e, 0x66, 0xff, 0x06, 0x9d, 0x65, 0xff, 0x07, 0x9e, 0x65, 0xff, 0x0c, 0x9f, 0x5d, 0xff, 0x08, 0x9a, 0x5f, 0xff, 0x05, 0x94, 0x61, 0xff, 0x0d, 0x87, 0x6f, 0xff, 0x0a, 0x6e, 0x77, 0xff, 0x06, 0x63, 0x7c, 0xff, 0x0a, 0x62, 0x75, 0xff, 0x0b, 0x6a, 0x5e, 0xff, 0x0a, 0x73, 0x47, 0xff, 0x0a, 0x73, 0x3e, 0xff, 0x0b, 0x74, 0x3f, 0xff, 0x09, 0x73, 0x3e, 0xff, 0x0b, 0x6a, 0x3c, 0xff, 0x11, 0x5d, 0x3d, 0xff, 0x11, 0x46, 0x35, 0xff, 0x03, 0x2c, 0x25, 0xff, 0x10, 0x3c, 0x36, 0xff, 0x0a, 0x3e, 0x30, 0xff, 0x06, 0x3b, 0x2a, 0xff, 0x0a, 0x38, 0x2d, 0xff, 0x06, 0x2d, 0x2a, 0xff, 0x04, 0x2c, 0x28, 0xff, 0x0f, 0x3f, 0x34, 0xff, 0x14, 0x52, 0x3b, 0xff, 0x07, 0x49, 0x31, 0xff, 0x04, 0x40, 0x30, 0xff, 0x11, 0x4d, 0x37, 0xff, 0x07, 0x42, 0x24, 0xff, 0x0b, 0x3b, 0x1f, 0xff, 0x07, 0x3b, 0x1f, 0xff, 0x16, 0x65, 0x3e, 0xff, 0x0e, 0x68, 0x39, 0xff, 0x08, 0x65, 0x36, 0xff, 0x08, 0x65, 0x38, 0xff, 0x15, 0x67, 0x3c, 0xff, 0x04, 0x43, 0x23, 0xff, 0x09, 0x47, 0x29, 0xff, 0x09, 0x4e, 0x29, 0xff, 0x65, 0x89, 0x75, 0xff, + 0x12, 0x99, 0x68, 0xff, 0x17, 0x8f, 0x7a, 0xff, 0x10, 0x72, 0x89, 0xff, 0x02, 0x48, 0x85, 0xff, 0x00, 0x42, 0x8a, 0xff, 0x0a, 0x51, 0xa2, 0xff, 0x12, 0x5f, 0xaf, 0xff, 0x02, 0x4f, 0xa2, 0xff, 0x12, 0x5e, 0xb3, 0xff, 0x1a, 0x68, 0xb4, 0xff, 0x19, 0x6d, 0xb7, 0xff, 0x18, 0x75, 0xc2, 0xff, 0x27, 0x85, 0xd2, 0xff, 0x2a, 0x93, 0xec, 0xff, 0x29, 0x9c, 0xfd, 0xff, 0x27, 0x9f, 0xf8, 0xff, 0x20, 0x9b, 0xf4, 0xff, 0x20, 0x9b, 0xf5, 0xff, 0x24, 0x98, 0xf7, 0xff, 0x29, 0x99, 0xf8, 0xff, 0x21, 0x98, 0xf2, 0xff, 0x23, 0xac, 0xfb, 0xff, 0x1b, 0xab, 0xf8, 0xff, 0x1d, 0x9c, 0xf5, 0xff, 0x27, 0x9d, 0xf8, 0xff, 0x23, 0x9e, 0xf6, 0xff, 0x21, 0xa0, 0xf2, 0xff, 0x22, 0xb7, 0xfe, 0xff, 0x14, 0xb3, 0xf7, 0xff, 0x15, 0xb7, 0xfa, 0xff, 0x1d, 0xb9, 0xfb, 0xff, 0x1f, 0xac, 0xe9, 0xff, 0x1b, 0x9b, 0xcf, 0xff, 0x1b, 0x99, 0xa1, 0xff, 0x22, 0xa4, 0x89, 0xff, 0x22, 0xa5, 0x83, 0xff, 0x20, 0xa7, 0x82, 0xff, 0x20, 0xa6, 0x84, 0xff, 0x22, 0xa9, 0x81, 0xff, 0x23, 0xa7, 0x86, 0xff, 0x23, 0xa8, 0x87, 0xff, 0x24, 0xa8, 0x89, 0xff, 0x24, 0xa9, 0x89, 0xff, 0x25, 0xaa, 0x8a, 0xff, 0x23, 0xa8, 0x87, 0xff, 0x23, 0xa8, 0x85, 0xff, 0x15, 0x9d, 0x75, 0xff, 0x03, 0x8f, 0x5b, 0xff, 0x11, 0x9e, 0x6e, 0xff, 0x33, 0xbb, 0x8c, 0xff, 0x19, 0xa3, 0x6f, 0xff, 0x1f, 0xab, 0x71, 0xff, 0x3c, 0xc3, 0x8e, 0xff, 0x16, 0x90, 0x6c, 0xff, 0x0f, 0x85, 0x69, 0xff, 0x29, 0xac, 0x8b, 0xff, 0x13, 0x9c, 0x72, 0xff, 0x01, 0x90, 0x5d, 0xff, 0x06, 0x9f, 0x65, 0xff, 0x05, 0xa1, 0x66, 0xff, 0x04, 0x9f, 0x66, 0xff, 0x06, 0x9f, 0x64, 0xff, 0x05, 0x9d, 0x62, 0xff, 0x05, 0x9c, 0x66, 0xff, 0x03, 0x99, 0x63, 0xff, 0x02, 0x99, 0x63, 0xff, 0x05, 0x9b, 0x65, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x0a, 0xa0, 0x6b, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x15, 0xa5, 0x79, 0xff, 0x15, 0xa6, 0x79, 0xff, 0x14, 0xa4, 0x79, 0xff, 0x15, 0xa6, 0x7a, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x15, 0xa5, 0x7b, 0xff, 0x14, 0xa5, 0x7b, 0xff, 0x15, 0xa3, 0x7a, 0xff, 0x13, 0xa4, 0x79, 0xff, 0x12, 0xa3, 0x78, 0xff, 0x11, 0xa2, 0x77, 0xff, 0x10, 0xa1, 0x76, 0xff, 0x14, 0xa5, 0x7a, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x16, 0xa7, 0x7c, 0xff, 0x18, 0xa9, 0x7f, 0xff, 0x16, 0xa9, 0x7d, 0xff, 0x15, 0xa8, 0x7c, 0xff, 0x14, 0xa8, 0x7c, 0xff, 0x14, 0xa7, 0x7c, 0xff, 0x13, 0xa6, 0x7b, 0xff, 0x14, 0xa7, 0x7d, 0xff, 0x11, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x7b, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x10, 0xa4, 0x79, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x12, 0xa6, 0x77, 0xff, 0x14, 0xa6, 0x77, 0xff, 0x13, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa9, 0x75, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x0c, 0xa0, 0x68, 0xff, 0x02, 0x93, 0x5a, 0xff, 0x07, 0x8f, 0x5c, 0xff, 0x0d, 0x82, 0x5a, 0xff, 0x0d, 0x76, 0x5c, 0xff, 0x0b, 0x7d, 0x58, 0xff, 0x07, 0x86, 0x54, 0xff, 0x0b, 0x8a, 0x5a, 0xff, 0x10, 0x89, 0x65, 0xff, 0x0c, 0x89, 0x6f, 0xff, 0x0b, 0x90, 0x6f, 0xff, 0x12, 0xa4, 0x71, 0xff, 0x10, 0xa8, 0x70, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x11, 0xa1, 0x70, 0xff, 0x0d, 0xa0, 0x6e, 0xff, 0x32, 0xc9, 0x97, 0xff, 0x2b, 0xb9, 0x89, 0xff, 0x1c, 0xa8, 0x79, 0xff, 0x12, 0xa0, 0x73, 0xff, 0x2a, 0xb3, 0x8a, 0xff, 0x20, 0xa4, 0x7e, 0xff, 0x21, 0xa9, 0x84, 0xff, 0x1c, 0xa8, 0x85, 0xff, 0x1b, 0xa5, 0x83, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x13, 0xb2, 0x82, 0xff, 0x16, 0xb3, 0x86, 0xff, 0x2e, 0xbf, 0x97, 0xff, 0x3d, 0xd0, 0xa6, 0xff, 0x1c, 0xaf, 0x7f, 0xff, 0x02, 0x8d, 0x5c, 0xff, 0x33, 0xbe, 0x99, 0xff, 0x3a, 0xc7, 0xa7, 0xff, 0x0e, 0xa1, 0x7a, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x13, 0xae, 0x7d, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x1b, 0xb1, 0x83, 0xff, 0x15, 0xad, 0x7a, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x07, 0x9e, 0x66, 0xff, 0x06, 0x9c, 0x66, 0xff, 0x07, 0x9d, 0x67, 0xff, 0x07, 0x9d, 0x68, 0xff, 0x08, 0x9d, 0x68, 0xff, 0x08, 0x9c, 0x6a, 0xff, 0x07, 0x9c, 0x69, 0xff, 0x04, 0x9c, 0x67, 0xff, 0x08, 0x9c, 0x68, 0xff, 0x0a, 0x9a, 0x66, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x14, 0xa0, 0x6a, 0xff, 0x12, 0xa0, 0x69, 0xff, 0x0d, 0x9e, 0x66, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0e, 0xa0, 0x69, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x0a, 0x9d, 0x68, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x08, 0x9a, 0x66, 0xff, 0x08, 0x9a, 0x66, 0xff, 0x0a, 0x9b, 0x68, 0xff, 0x07, 0x98, 0x63, 0xff, 0x07, 0x99, 0x63, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x04, 0x93, 0x5e, 0xff, 0x07, 0x95, 0x60, 0xff, 0x0a, 0x99, 0x64, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0b, 0x9a, 0x66, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x0f, 0x9e, 0x69, 0xff, 0x0c, 0x9a, 0x65, 0xff, 0x06, 0x92, 0x5e, 0xff, 0x04, 0x8e, 0x5a, 0xff, 0x05, 0x8f, 0x5b, 0xff, 0x02, 0x8d, 0x59, 0xff, 0x01, 0x8e, 0x59, 0xff, 0x01, 0x8e, 0x5a, 0xff, 0x02, 0x8f, 0x5a, 0xff, 0x04, 0x92, 0x5d, 0xff, 0x08, 0x96, 0x61, 0xff, 0x06, 0x95, 0x60, 0xff, 0x05, 0x94, 0x5f, 0xff, 0x08, 0x98, 0x62, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0b, 0xa1, 0x69, 0xff, 0x0b, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x09, 0x9f, 0x67, 0xff, 0x08, 0x9e, 0x66, 0xff, 0x07, 0x9e, 0x65, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x0c, 0xa0, 0x5a, 0xff, 0x0b, 0x9a, 0x5f, 0xff, 0x0b, 0x8d, 0x6d, 0xff, 0x0f, 0x7a, 0x8c, 0xff, 0x20, 0x75, 0xb6, 0xff, 0x2d, 0x78, 0xd3, 0xff, 0x2f, 0x79, 0xcd, 0xff, 0x13, 0x68, 0x91, 0xff, 0x06, 0x68, 0x5b, 0xff, 0x08, 0x71, 0x47, 0xff, 0x0b, 0x77, 0x3e, 0xff, 0x0a, 0x75, 0x3b, 0xff, 0x0b, 0x6d, 0x3f, 0xff, 0x0c, 0x5f, 0x40, 0xff, 0x10, 0x54, 0x3b, 0xff, 0x02, 0x31, 0x24, 0xff, 0x0e, 0x3c, 0x32, 0xff, 0x08, 0x3d, 0x2a, 0xff, 0x06, 0x3c, 0x24, 0xff, 0x08, 0x3b, 0x25, 0xff, 0x08, 0x37, 0x27, 0xff, 0x0b, 0x3c, 0x31, 0xff, 0x20, 0x57, 0x4e, 0xff, 0x06, 0x45, 0x37, 0xff, 0x07, 0x44, 0x3a, 0xff, 0x0d, 0x46, 0x42, 0xff, 0x11, 0x4e, 0x43, 0xff, 0x05, 0x41, 0x2d, 0xff, 0x0d, 0x40, 0x28, 0xff, 0x0e, 0x45, 0x2b, 0xff, 0x17, 0x67, 0x3d, 0xff, 0x10, 0x6a, 0x38, 0xff, 0x08, 0x64, 0x36, 0xff, 0x0a, 0x67, 0x39, 0xff, 0x12, 0x66, 0x3c, 0xff, 0x06, 0x4b, 0x2a, 0xff, 0x08, 0x49, 0x2a, 0xff, 0x09, 0x4f, 0x2a, 0xff, 0x65, 0x8d, 0x7a, 0xff, + 0x15, 0x98, 0x6d, 0xff, 0x11, 0x79, 0x81, 0xff, 0x04, 0x52, 0x89, 0xff, 0x04, 0x4a, 0x8e, 0xff, 0x03, 0x4b, 0x97, 0xff, 0x17, 0x62, 0xc3, 0xff, 0x1c, 0x6a, 0xcc, 0xff, 0x10, 0x6b, 0xcc, 0xff, 0x1e, 0x84, 0xea, 0xff, 0x27, 0x8a, 0xed, 0xff, 0x25, 0x8a, 0xe9, 0xff, 0x1c, 0x8a, 0xe5, 0xff, 0x21, 0x8d, 0xe4, 0xff, 0x29, 0x97, 0xf5, 0xff, 0x29, 0x9c, 0xfb, 0xff, 0x25, 0x9b, 0xf6, 0xff, 0x22, 0x9b, 0xf3, 0xff, 0x21, 0x9a, 0xf4, 0xff, 0x25, 0x99, 0xf7, 0xff, 0x27, 0x98, 0xf8, 0xff, 0x24, 0x9a, 0xf6, 0xff, 0x22, 0xa3, 0xf6, 0xff, 0x24, 0xac, 0xfc, 0xff, 0x1c, 0x9f, 0xf7, 0xff, 0x28, 0x9f, 0xfd, 0xff, 0x24, 0xa1, 0xfb, 0xff, 0x1f, 0xa1, 0xf5, 0xff, 0x1d, 0xb5, 0xfc, 0xff, 0x1d, 0xb4, 0xfa, 0xff, 0x19, 0xb5, 0xfb, 0xff, 0x19, 0xb6, 0xfb, 0xff, 0x21, 0xb9, 0xf8, 0xff, 0x1a, 0xa4, 0xe0, 0xff, 0x19, 0x94, 0xb7, 0xff, 0x23, 0xa0, 0x95, 0xff, 0x25, 0xa8, 0x86, 0xff, 0x23, 0xa5, 0x87, 0xff, 0x24, 0xa7, 0x87, 0xff, 0x25, 0xac, 0x83, 0xff, 0x26, 0xa8, 0x89, 0xff, 0x27, 0xa9, 0x8a, 0xff, 0x28, 0xaa, 0x8c, 0xff, 0x28, 0xaa, 0x8c, 0xff, 0x27, 0xa9, 0x8a, 0xff, 0x27, 0xaa, 0x8a, 0xff, 0x25, 0xa8, 0x87, 0xff, 0x22, 0xa9, 0x82, 0xff, 0x08, 0x97, 0x62, 0xff, 0x18, 0xa4, 0x72, 0xff, 0x2e, 0xb7, 0x84, 0xff, 0x0a, 0x91, 0x5a, 0xff, 0x24, 0xb2, 0x73, 0xff, 0x48, 0xd4, 0x9a, 0xff, 0x0b, 0x8d, 0x61, 0xff, 0x06, 0x83, 0x5e, 0xff, 0x1d, 0xa4, 0x7c, 0xff, 0x08, 0x92, 0x63, 0xff, 0x07, 0x9b, 0x63, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x07, 0xa0, 0x67, 0xff, 0x07, 0xa0, 0x68, 0xff, 0x06, 0x9d, 0x63, 0xff, 0x03, 0x9a, 0x5e, 0xff, 0x02, 0x99, 0x61, 0xff, 0x05, 0x9b, 0x65, 0xff, 0x07, 0x9d, 0x67, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x09, 0x9f, 0x69, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x06, 0x9c, 0x66, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa3, 0x73, 0xff, 0x0f, 0xa3, 0x73, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x12, 0xa3, 0x77, 0xff, 0x13, 0xa4, 0x77, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x0e, 0xa2, 0x76, 0xff, 0x0c, 0xa1, 0x74, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x13, 0xa5, 0x79, 0xff, 0x0f, 0xa4, 0x77, 0xff, 0x0c, 0xa2, 0x74, 0xff, 0x0a, 0x9f, 0x72, 0xff, 0x09, 0x9e, 0x71, 0xff, 0x0c, 0xa1, 0x73, 0xff, 0x0c, 0xa2, 0x75, 0xff, 0x0c, 0xa2, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x12, 0xa6, 0x7a, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x0d, 0xa5, 0x78, 0xff, 0x0e, 0xa6, 0x79, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x14, 0xa6, 0x78, 0xff, 0x12, 0xa7, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0d, 0xa1, 0x67, 0xff, 0x02, 0x93, 0x5d, 0xff, 0x01, 0x8a, 0x58, 0xff, 0x05, 0x7f, 0x50, 0xff, 0x04, 0x77, 0x4f, 0xff, 0x02, 0x75, 0x47, 0xff, 0x02, 0x81, 0x4e, 0xff, 0x03, 0x88, 0x53, 0xff, 0x02, 0x85, 0x54, 0xff, 0x03, 0x89, 0x62, 0xff, 0x0d, 0x98, 0x6d, 0xff, 0x13, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa3, 0x73, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0d, 0xa3, 0x71, 0xff, 0x08, 0x9a, 0x68, 0xff, 0x0c, 0xa2, 0x71, 0xff, 0x2a, 0xbf, 0x8f, 0xff, 0x17, 0x9e, 0x6f, 0xff, 0x11, 0x99, 0x69, 0xff, 0x0c, 0x9a, 0x6b, 0xff, 0x12, 0x97, 0x6c, 0xff, 0x3d, 0xb4, 0x92, 0xff, 0x47, 0xc2, 0xa4, 0xff, 0x25, 0xac, 0x8b, 0xff, 0x12, 0x9c, 0x75, 0xff, 0x16, 0xa9, 0x7c, 0xff, 0x15, 0xb7, 0x87, 0xff, 0x06, 0xa6, 0x7d, 0xff, 0x20, 0xb3, 0x8f, 0xff, 0x38, 0xcb, 0xa2, 0xff, 0x16, 0xa8, 0x78, 0xff, 0x07, 0x95, 0x61, 0xff, 0x12, 0xa3, 0x75, 0xff, 0x2a, 0xbc, 0x95, 0xff, 0x0f, 0xa3, 0x7a, 0xff, 0x19, 0xb0, 0x80, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x12, 0xa7, 0x7e, 0xff, 0x1a, 0xb1, 0x83, 0xff, 0x19, 0xb1, 0x7e, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x07, 0x9d, 0x67, 0xff, 0x06, 0x9c, 0x66, 0xff, 0x07, 0x9d, 0x68, 0xff, 0x06, 0x9c, 0x67, 0xff, 0x05, 0x9d, 0x69, 0xff, 0x06, 0x9c, 0x6b, 0xff, 0x06, 0x9d, 0x6b, 0xff, 0x04, 0x9d, 0x6a, 0xff, 0x03, 0x9b, 0x68, 0xff, 0x06, 0x9c, 0x68, 0xff, 0x09, 0x9e, 0x69, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x0d, 0xa0, 0x6a, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x0d, 0x9d, 0x68, 0xff, 0x0b, 0x9b, 0x67, 0xff, 0x0a, 0x9a, 0x66, 0xff, 0x08, 0x98, 0x64, 0xff, 0x06, 0x96, 0x62, 0xff, 0x04, 0x95, 0x61, 0xff, 0x06, 0x96, 0x62, 0xff, 0x0b, 0x9a, 0x66, 0xff, 0x07, 0x97, 0x63, 0xff, 0x08, 0x98, 0x64, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0e, 0x9e, 0x6a, 0xff, 0x0f, 0x9e, 0x6a, 0xff, 0x0d, 0x9b, 0x68, 0xff, 0x0a, 0x97, 0x63, 0xff, 0x09, 0x95, 0x62, 0xff, 0x08, 0x92, 0x5f, 0xff, 0x05, 0x90, 0x5d, 0xff, 0x06, 0x90, 0x5c, 0xff, 0x06, 0x8f, 0x5c, 0xff, 0x07, 0x92, 0x5f, 0xff, 0x09, 0x94, 0x62, 0xff, 0x09, 0x95, 0x61, 0xff, 0x08, 0x93, 0x60, 0xff, 0x0a, 0x97, 0x64, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x08, 0x9e, 0x65, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x0c, 0x9c, 0x64, 0xff, 0x0b, 0x97, 0x61, 0xff, 0x0f, 0x80, 0x7d, 0xff, 0x27, 0x83, 0xc0, 0xff, 0x39, 0x88, 0xec, 0xff, 0x38, 0x7f, 0xf1, 0xff, 0x41, 0x8b, 0xf9, 0xff, 0x33, 0x81, 0xe2, 0xff, 0x11, 0x66, 0x98, 0xff, 0x03, 0x64, 0x61, 0xff, 0x08, 0x75, 0x3c, 0xff, 0x0c, 0x78, 0x38, 0xff, 0x0a, 0x6d, 0x41, 0xff, 0x09, 0x64, 0x42, 0xff, 0x0c, 0x60, 0x3b, 0xff, 0x0d, 0x4d, 0x36, 0xff, 0x0f, 0x42, 0x33, 0xff, 0x06, 0x3c, 0x27, 0xff, 0x0e, 0x44, 0x29, 0xff, 0x12, 0x47, 0x2d, 0xff, 0x0f, 0x44, 0x31, 0xff, 0x24, 0x5b, 0x52, 0xff, 0x2b, 0x68, 0x69, 0xff, 0x11, 0x4f, 0x51, 0xff, 0x11, 0x49, 0x50, 0xff, 0x14, 0x48, 0x54, 0xff, 0x10, 0x4b, 0x4e, 0xff, 0x0c, 0x48, 0x41, 0xff, 0x0e, 0x42, 0x36, 0xff, 0x0e, 0x47, 0x32, 0xff, 0x0e, 0x5c, 0x33, 0xff, 0x12, 0x69, 0x38, 0xff, 0x06, 0x61, 0x33, 0xff, 0x09, 0x66, 0x38, 0xff, 0x11, 0x66, 0x3a, 0xff, 0x08, 0x50, 0x30, 0xff, 0x07, 0x4b, 0x2b, 0xff, 0x08, 0x51, 0x2a, 0xff, 0x69, 0x90, 0x79, 0xff, + 0x16, 0x90, 0x76, 0xff, 0x09, 0x61, 0x86, 0xff, 0x05, 0x4c, 0x97, 0xff, 0x07, 0x4f, 0x9a, 0xff, 0x0a, 0x56, 0xa8, 0xff, 0x12, 0x66, 0xcd, 0xff, 0x0c, 0x64, 0xcf, 0xff, 0x12, 0x81, 0xe6, 0xff, 0x0c, 0x8d, 0xee, 0xff, 0x1a, 0x89, 0xee, 0xff, 0x22, 0x85, 0xef, 0xff, 0x1d, 0x87, 0xe9, 0xff, 0x1f, 0x8e, 0xe6, 0xff, 0x27, 0x9c, 0xf7, 0xff, 0x1f, 0x9a, 0xf9, 0xff, 0x20, 0x99, 0xf4, 0xff, 0x24, 0x9b, 0xf6, 0xff, 0x24, 0x99, 0xf7, 0xff, 0x25, 0x99, 0xf9, 0xff, 0x22, 0x98, 0xf9, 0xff, 0x22, 0x9a, 0xf8, 0xff, 0x23, 0x9d, 0xf4, 0xff, 0x28, 0xac, 0xfc, 0xff, 0x1b, 0xa7, 0xf9, 0xff, 0x22, 0xa0, 0xfe, 0xff, 0x1c, 0xa1, 0xfc, 0xff, 0x15, 0xa6, 0xf4, 0xff, 0x28, 0xc0, 0xfb, 0xff, 0x2c, 0xb8, 0xf3, 0xff, 0x1a, 0xb5, 0xf7, 0xff, 0x15, 0xb6, 0xfc, 0xff, 0x19, 0xbd, 0xfb, 0xff, 0x19, 0xb3, 0xec, 0xff, 0x1c, 0x97, 0xcc, 0xff, 0x23, 0x9a, 0xa2, 0xff, 0x27, 0xa8, 0x89, 0xff, 0x27, 0xa7, 0x8a, 0xff, 0x27, 0xaa, 0x8a, 0xff, 0x25, 0xab, 0x86, 0xff, 0x28, 0xa9, 0x8b, 0xff, 0x28, 0xa8, 0x8c, 0xff, 0x29, 0xa9, 0x8e, 0xff, 0x29, 0xa9, 0x8e, 0xff, 0x2a, 0xaa, 0x8d, 0xff, 0x28, 0xa9, 0x8a, 0xff, 0x26, 0xa8, 0x88, 0xff, 0x24, 0xa9, 0x84, 0xff, 0x0d, 0x9c, 0x69, 0xff, 0x11, 0x9c, 0x6b, 0xff, 0x07, 0x8a, 0x56, 0xff, 0x00, 0x84, 0x4d, 0xff, 0x04, 0x8e, 0x50, 0xff, 0x0f, 0xa0, 0x64, 0xff, 0x02, 0x89, 0x57, 0xff, 0x05, 0x8a, 0x5e, 0xff, 0x13, 0x9e, 0x71, 0xff, 0x0d, 0x9c, 0x69, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0c, 0xa0, 0x69, 0xff, 0x09, 0x9f, 0x67, 0xff, 0x07, 0x9e, 0x66, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x09, 0x9f, 0x69, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x09, 0x9f, 0x69, 0xff, 0x0a, 0xa2, 0x6f, 0xff, 0x0a, 0xa1, 0x6f, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x0b, 0xa2, 0x71, 0xff, 0x0b, 0xa2, 0x71, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x0d, 0xa1, 0x74, 0xff, 0x0b, 0xa1, 0x72, 0xff, 0x0a, 0xa1, 0x71, 0xff, 0x0c, 0xa2, 0x73, 0xff, 0x0d, 0xa3, 0x74, 0xff, 0x0c, 0xa2, 0x73, 0xff, 0x0b, 0xa2, 0x74, 0xff, 0x0a, 0xa0, 0x72, 0xff, 0x0a, 0xa0, 0x72, 0xff, 0x0c, 0xa2, 0x74, 0xff, 0x0a, 0xa0, 0x6f, 0xff, 0x09, 0xa0, 0x6f, 0xff, 0x07, 0x9e, 0x6d, 0xff, 0x08, 0x9f, 0x6e, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0c, 0xa7, 0x72, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x09, 0xa5, 0x71, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0d, 0xa6, 0x78, 0xff, 0x0d, 0xa5, 0x78, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa9, 0x73, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x07, 0x9a, 0x67, 0xff, 0x07, 0x95, 0x62, 0xff, 0x0b, 0x90, 0x5b, 0xff, 0x05, 0x82, 0x4f, 0xff, 0x03, 0x7f, 0x4d, 0xff, 0x08, 0x8e, 0x5d, 0xff, 0x03, 0x8e, 0x59, 0xff, 0x07, 0x94, 0x5d, 0xff, 0x0b, 0x98, 0x68, 0xff, 0x11, 0xa2, 0x71, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0b, 0xa3, 0x70, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0b, 0xa1, 0x6f, 0xff, 0x03, 0x95, 0x64, 0xff, 0x07, 0x9d, 0x6b, 0xff, 0x1b, 0xae, 0x7c, 0xff, 0x17, 0x98, 0x67, 0xff, 0x12, 0x97, 0x65, 0xff, 0x1e, 0xae, 0x7b, 0xff, 0x1b, 0x9f, 0x72, 0xff, 0x26, 0x98, 0x75, 0xff, 0x33, 0xaa, 0x8c, 0xff, 0x26, 0xab, 0x8a, 0xff, 0x03, 0x8c, 0x62, 0xff, 0x16, 0xa5, 0x79, 0xff, 0x1d, 0xb7, 0x8c, 0xff, 0x24, 0xbc, 0x99, 0xff, 0x1e, 0xaa, 0x8c, 0xff, 0x13, 0xa3, 0x7e, 0xff, 0x0b, 0x9e, 0x6e, 0xff, 0x0d, 0x9e, 0x68, 0xff, 0x07, 0x9e, 0x68, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x0f, 0xa1, 0x76, 0xff, 0x1f, 0xb2, 0x84, 0xff, 0x23, 0xb5, 0x8b, 0xff, 0x1e, 0xae, 0x8b, 0xff, 0x13, 0xa6, 0x7e, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x06, 0x9c, 0x66, 0xff, 0x05, 0x9d, 0x68, 0xff, 0x05, 0x9c, 0x67, 0xff, 0x05, 0x9d, 0x68, 0xff, 0x04, 0x9d, 0x69, 0xff, 0x04, 0x9d, 0x69, 0xff, 0x04, 0x9d, 0x6a, 0xff, 0x02, 0x9c, 0x6a, 0xff, 0x03, 0x9d, 0x6a, 0xff, 0x04, 0x9e, 0x69, 0xff, 0x07, 0xa0, 0x6b, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0d, 0x9e, 0x6a, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0a, 0x9a, 0x66, 0xff, 0x08, 0x98, 0x64, 0xff, 0x08, 0x97, 0x63, 0xff, 0x0b, 0x9a, 0x65, 0xff, 0x0c, 0x99, 0x65, 0xff, 0x09, 0x97, 0x65, 0xff, 0x09, 0x97, 0x65, 0xff, 0x08, 0x98, 0x66, 0xff, 0x0a, 0x9a, 0x68, 0xff, 0x0c, 0x9c, 0x6a, 0xff, 0x0d, 0x9d, 0x6c, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0c, 0x9c, 0x6a, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x0b, 0x9d, 0x69, 0xff, 0x0b, 0x9c, 0x68, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x0b, 0x9b, 0x67, 0xff, 0x0b, 0x98, 0x65, 0xff, 0x0a, 0x95, 0x64, 0xff, 0x0b, 0x95, 0x65, 0xff, 0x0a, 0x95, 0x64, 0xff, 0x0c, 0x97, 0x66, 0xff, 0x0e, 0x98, 0x68, 0xff, 0x0b, 0x98, 0x66, 0xff, 0x0a, 0x97, 0x66, 0xff, 0x0e, 0x9c, 0x6a, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x08, 0x9d, 0x65, 0xff, 0x0b, 0x9e, 0x64, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x0b, 0x92, 0x63, 0xff, 0x14, 0x75, 0x94, 0xff, 0x27, 0x77, 0xd7, 0xff, 0x22, 0x6e, 0xe3, 0xff, 0x36, 0x83, 0xeb, 0xff, 0x2a, 0x79, 0xed, 0xff, 0x27, 0x76, 0xf4, 0xff, 0x2e, 0x7b, 0xe3, 0xff, 0x12, 0x68, 0x9c, 0xff, 0x04, 0x6b, 0x4c, 0xff, 0x0b, 0x75, 0x3d, 0xff, 0x0d, 0x70, 0x41, 0xff, 0x0a, 0x6a, 0x42, 0xff, 0x08, 0x64, 0x40, 0xff, 0x13, 0x5e, 0x44, 0xff, 0x12, 0x4e, 0x3b, 0xff, 0x08, 0x43, 0x2f, 0xff, 0x0b, 0x43, 0x2e, 0xff, 0x06, 0x3a, 0x27, 0xff, 0x19, 0x4f, 0x45, 0xff, 0x3a, 0x73, 0x75, 0xff, 0x33, 0x70, 0x80, 0xff, 0x27, 0x63, 0x74, 0xff, 0x23, 0x57, 0x69, 0xff, 0x1b, 0x4d, 0x65, 0xff, 0x11, 0x4b, 0x5a, 0xff, 0x12, 0x4e, 0x55, 0xff, 0x11, 0x45, 0x45, 0xff, 0x07, 0x3e, 0x32, 0xff, 0x0b, 0x57, 0x32, 0xff, 0x11, 0x65, 0x37, 0xff, 0x04, 0x5f, 0x32, 0xff, 0x06, 0x64, 0x35, 0xff, 0x0e, 0x64, 0x37, 0xff, 0x08, 0x52, 0x30, 0xff, 0x08, 0x4d, 0x2c, 0xff, 0x08, 0x52, 0x2b, 0xff, 0x6a, 0x91, 0x7c, 0xff, + 0x16, 0x85, 0x81, 0xff, 0x0a, 0x56, 0x92, 0xff, 0x08, 0x4b, 0x9d, 0xff, 0x09, 0x50, 0xa1, 0xff, 0x11, 0x60, 0xb8, 0xff, 0x0a, 0x65, 0xcb, 0xff, 0x0a, 0x6b, 0xd7, 0xff, 0x0c, 0x84, 0xea, 0xff, 0x09, 0x8f, 0xec, 0xff, 0x1d, 0x89, 0xee, 0xff, 0x2b, 0x87, 0xf4, 0xff, 0x24, 0x85, 0xed, 0xff, 0x25, 0x8f, 0xee, 0xff, 0x22, 0x99, 0xf4, 0xff, 0x1e, 0x99, 0xf5, 0xff, 0x21, 0x99, 0xf7, 0xff, 0x22, 0x99, 0xf7, 0xff, 0x24, 0x9a, 0xf8, 0xff, 0x24, 0x99, 0xfa, 0xff, 0x23, 0x99, 0xfb, 0xff, 0x22, 0x98, 0xf8, 0xff, 0x22, 0x9b, 0xf4, 0xff, 0x25, 0xab, 0xf9, 0xff, 0x1a, 0xab, 0xf6, 0xff, 0x1e, 0xa1, 0xfc, 0xff, 0x16, 0xa2, 0xfa, 0xff, 0x1c, 0xac, 0xf1, 0xff, 0x39, 0xab, 0xd9, 0xff, 0x18, 0x6e, 0x9b, 0xff, 0x1a, 0xac, 0xe6, 0xff, 0x17, 0xb7, 0xfd, 0xff, 0x11, 0xbf, 0xf9, 0xff, 0x16, 0xc0, 0xf0, 0xff, 0x1d, 0x9b, 0xd7, 0xff, 0x21, 0x92, 0xab, 0xff, 0x2a, 0xa8, 0x8c, 0xff, 0x29, 0xa9, 0x8b, 0xff, 0x29, 0xa9, 0x8b, 0xff, 0x27, 0xa9, 0x8a, 0xff, 0x29, 0xa8, 0x8b, 0xff, 0x2a, 0xa8, 0x8d, 0xff, 0x2b, 0xa8, 0x8f, 0xff, 0x2a, 0xa8, 0x8f, 0xff, 0x2a, 0xa8, 0x8e, 0xff, 0x29, 0xa8, 0x8c, 0xff, 0x28, 0xa8, 0x8a, 0xff, 0x23, 0xa6, 0x83, 0xff, 0x11, 0x9e, 0x70, 0xff, 0x09, 0x92, 0x64, 0xff, 0x04, 0x8a, 0x5a, 0xff, 0x08, 0x93, 0x5f, 0xff, 0x07, 0x96, 0x5e, 0xff, 0x08, 0x9a, 0x61, 0xff, 0x0b, 0x99, 0x67, 0xff, 0x0e, 0x99, 0x6b, 0xff, 0x0e, 0x9c, 0x6e, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x10, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x74, 0xff, 0x0c, 0xa2, 0x73, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa4, 0x75, 0xff, 0x0d, 0xa3, 0x74, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x11, 0xa2, 0x77, 0xff, 0x11, 0xa1, 0x78, 0xff, 0x10, 0xa2, 0x77, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x0f, 0xa3, 0x74, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x0b, 0xa2, 0x6f, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x08, 0xa0, 0x6e, 0xff, 0x0d, 0xa2, 0x74, 0xff, 0x0c, 0x9f, 0x72, 0xff, 0x0c, 0x9f, 0x72, 0xff, 0x11, 0xa4, 0x77, 0xff, 0x0d, 0xa0, 0x71, 0xff, 0x0c, 0xa0, 0x71, 0xff, 0x09, 0x9d, 0x6d, 0xff, 0x0a, 0x9e, 0x6e, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa6, 0x6c, 0xff, 0x0e, 0xa9, 0x71, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0c, 0xa6, 0x77, 0xff, 0x0d, 0xa5, 0x78, 0xff, 0x0e, 0xa4, 0x78, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x0e, 0xa3, 0x7a, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa2, 0x71, 0xff, 0x0f, 0xa3, 0x70, 0xff, 0x15, 0xa3, 0x6b, 0xff, 0x14, 0xa0, 0x66, 0xff, 0x12, 0x9d, 0x68, 0xff, 0x15, 0xa1, 0x72, 0xff, 0x0f, 0x9f, 0x6e, 0xff, 0x12, 0xa4, 0x6f, 0xff, 0x12, 0xa5, 0x72, 0xff, 0x11, 0xa5, 0x74, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0a, 0x9d, 0x6b, 0xff, 0x09, 0x9b, 0x68, 0xff, 0x35, 0xc3, 0x90, 0xff, 0x21, 0x9f, 0x6c, 0xff, 0x15, 0x9a, 0x63, 0xff, 0x3e, 0xd0, 0x99, 0xff, 0x22, 0xab, 0x79, 0xff, 0x0d, 0x82, 0x5b, 0xff, 0x1c, 0x97, 0x75, 0xff, 0x0f, 0x98, 0x73, 0xff, 0x0d, 0x95, 0x6a, 0xff, 0x16, 0xa0, 0x75, 0xff, 0x22, 0xb1, 0x8a, 0xff, 0x50, 0xd9, 0xbb, 0xff, 0x28, 0xa8, 0x8f, 0xff, 0x0c, 0x95, 0x75, 0xff, 0x0a, 0x9b, 0x70, 0xff, 0x02, 0x93, 0x5d, 0xff, 0x0a, 0x9e, 0x67, 0xff, 0x1a, 0xab, 0x7f, 0xff, 0x1a, 0xa7, 0x7d, 0xff, 0x17, 0xa3, 0x78, 0xff, 0x3b, 0xc5, 0x9d, 0xff, 0x32, 0xbb, 0x9b, 0xff, 0x12, 0x9e, 0x7b, 0xff, 0x0d, 0x9d, 0x71, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0f, 0xa7, 0x71, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x09, 0x9f, 0x69, 0xff, 0x06, 0x9c, 0x67, 0xff, 0x05, 0x9d, 0x67, 0xff, 0x05, 0x9e, 0x68, 0xff, 0x06, 0x9e, 0x68, 0xff, 0x04, 0x9e, 0x68, 0xff, 0x05, 0x9e, 0x69, 0xff, 0x06, 0x9e, 0x6a, 0xff, 0x04, 0x9d, 0x69, 0xff, 0x03, 0x9d, 0x69, 0xff, 0x04, 0xa0, 0x6a, 0xff, 0x06, 0xa0, 0x6a, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x0f, 0xa0, 0x6a, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x08, 0x96, 0x65, 0xff, 0x05, 0x93, 0x63, 0xff, 0x05, 0x94, 0x63, 0xff, 0x09, 0x98, 0x68, 0xff, 0x0a, 0x9a, 0x69, 0xff, 0x0a, 0x9b, 0x6a, 0xff, 0x0a, 0x9b, 0x69, 0xff, 0x0b, 0x9d, 0x6b, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0b, 0x9f, 0x6b, 0xff, 0x07, 0x9c, 0x68, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x09, 0x9c, 0x68, 0xff, 0x0a, 0x9b, 0x67, 0xff, 0x0b, 0x9b, 0x68, 0xff, 0x0b, 0x9a, 0x69, 0xff, 0x0b, 0x9a, 0x69, 0xff, 0x0b, 0x99, 0x68, 0xff, 0x0b, 0x99, 0x68, 0xff, 0x0a, 0x99, 0x67, 0xff, 0x0a, 0x99, 0x68, 0xff, 0x0b, 0x9a, 0x69, 0xff, 0x0f, 0x9e, 0x6c, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0e, 0xa1, 0x6a, 0xff, 0x0d, 0xa0, 0x68, 0xff, 0x0c, 0xa0, 0x67, 0xff, 0x0b, 0x9f, 0x66, 0xff, 0x0a, 0x9e, 0x65, 0xff, 0x0a, 0x9e, 0x66, 0xff, 0x0a, 0x9e, 0x65, 0xff, 0x09, 0x9d, 0x63, 0xff, 0x07, 0x9e, 0x5e, 0xff, 0x06, 0x9b, 0x65, 0xff, 0x0b, 0x8b, 0x71, 0xff, 0x17, 0x65, 0xb0, 0xff, 0x16, 0x5c, 0xd9, 0xff, 0x19, 0x63, 0xe6, 0xff, 0x44, 0x90, 0xf6, 0xff, 0x25, 0x76, 0xef, 0xff, 0x17, 0x6d, 0xf1, 0xff, 0x24, 0x77, 0xf1, 0xff, 0x27, 0x79, 0xd7, 0xff, 0x08, 0x5f, 0x7b, 0xff, 0x09, 0x69, 0x52, 0xff, 0x10, 0x73, 0x3f, 0xff, 0x0c, 0x6c, 0x3e, 0xff, 0x09, 0x63, 0x42, 0xff, 0x0c, 0x60, 0x40, 0xff, 0x0f, 0x5a, 0x3b, 0xff, 0x0e, 0x51, 0x39, 0xff, 0x0b, 0x44, 0x35, 0xff, 0x05, 0x35, 0x2d, 0xff, 0x34, 0x68, 0x6b, 0xff, 0x3e, 0x75, 0x83, 0xff, 0x3a, 0x74, 0x8e, 0xff, 0x32, 0x6b, 0x81, 0xff, 0x2d, 0x60, 0x77, 0xff, 0x2e, 0x5d, 0x79, 0xff, 0x20, 0x56, 0x6d, 0xff, 0x12, 0x4b, 0x5b, 0xff, 0x13, 0x46, 0x51, 0xff, 0x0a, 0x3f, 0x3e, 0xff, 0x0c, 0x53, 0x37, 0xff, 0x0d, 0x5e, 0x34, 0xff, 0x07, 0x5f, 0x34, 0xff, 0x06, 0x62, 0x35, 0xff, 0x0c, 0x62, 0x35, 0xff, 0x08, 0x52, 0x2e, 0xff, 0x08, 0x4e, 0x2c, 0xff, 0x05, 0x51, 0x29, 0xff, 0x67, 0x8e, 0x7c, 0xff, + 0x12, 0x77, 0x88, 0xff, 0x0a, 0x4f, 0x99, 0xff, 0x05, 0x48, 0x9b, 0xff, 0x0f, 0x58, 0xad, 0xff, 0x13, 0x64, 0xc2, 0xff, 0x08, 0x66, 0xc9, 0xff, 0x0e, 0x70, 0xdb, 0xff, 0x12, 0x85, 0xef, 0xff, 0x0f, 0x8d, 0xec, 0xff, 0x25, 0x89, 0xea, 0xff, 0x38, 0x8c, 0xf0, 0xff, 0x2d, 0x8b, 0xef, 0xff, 0x23, 0x8e, 0xf1, 0xff, 0x23, 0x97, 0xf4, 0xff, 0x23, 0x98, 0xf3, 0xff, 0x26, 0x9b, 0xfa, 0xff, 0x22, 0x9a, 0xf7, 0xff, 0x21, 0x9a, 0xf8, 0xff, 0x23, 0x97, 0xf8, 0xff, 0x26, 0x97, 0xfb, 0xff, 0x28, 0x9a, 0xfb, 0xff, 0x1f, 0x9a, 0xf3, 0xff, 0x1e, 0xa9, 0xf5, 0xff, 0x21, 0xb4, 0xf8, 0xff, 0x1f, 0xa2, 0xfa, 0xff, 0x17, 0xa7, 0xfb, 0xff, 0x29, 0xac, 0xe9, 0xff, 0x1b, 0x52, 0x77, 0xff, 0x03, 0x20, 0x40, 0xff, 0x23, 0xae, 0xe2, 0xff, 0x1a, 0xb6, 0xfb, 0xff, 0x0c, 0xbf, 0xf6, 0xff, 0x15, 0xca, 0xf0, 0xff, 0x1f, 0xa1, 0xdd, 0xff, 0x21, 0x8f, 0xb3, 0xff, 0x29, 0xa7, 0x8f, 0xff, 0x29, 0xab, 0x8c, 0xff, 0x29, 0xa7, 0x8b, 0xff, 0x27, 0xa8, 0x8d, 0xff, 0x2a, 0xa8, 0x8c, 0xff, 0x2b, 0xa8, 0x8e, 0xff, 0x2b, 0xa8, 0x8f, 0xff, 0x2b, 0xa7, 0x8f, 0xff, 0x29, 0xa6, 0x8c, 0xff, 0x2a, 0xa7, 0x8c, 0xff, 0x29, 0xa7, 0x8a, 0xff, 0x24, 0xa6, 0x85, 0xff, 0x19, 0xa4, 0x7b, 0xff, 0x15, 0x9d, 0x74, 0xff, 0x16, 0x9d, 0x71, 0xff, 0x17, 0xa1, 0x72, 0xff, 0x14, 0xa3, 0x71, 0xff, 0x13, 0xa4, 0x72, 0xff, 0x14, 0xa3, 0x73, 0xff, 0x16, 0xa3, 0x75, 0xff, 0x16, 0xa5, 0x77, 0xff, 0x15, 0xa5, 0x74, 0xff, 0x10, 0xa3, 0x6e, 0xff, 0x11, 0xa3, 0x70, 0xff, 0x11, 0xa3, 0x74, 0xff, 0x13, 0xa4, 0x76, 0xff, 0x13, 0xa6, 0x74, 0xff, 0x12, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x74, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x11, 0xa1, 0x78, 0xff, 0x0e, 0xa0, 0x74, 0xff, 0x0f, 0xa3, 0x74, 0xff, 0x0d, 0xa2, 0x71, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x05, 0x9e, 0x6b, 0xff, 0x13, 0xa6, 0x79, 0xff, 0x0e, 0x9e, 0x73, 0xff, 0x0f, 0x9f, 0x73, 0xff, 0x14, 0xa5, 0x78, 0xff, 0x10, 0xa1, 0x73, 0xff, 0x10, 0xa1, 0x73, 0xff, 0x0f, 0xa1, 0x71, 0xff, 0x0d, 0x9f, 0x6e, 0xff, 0x0f, 0xa6, 0x6b, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x12, 0xad, 0x73, 0xff, 0x10, 0xaa, 0x71, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0f, 0xa6, 0x6f, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x0a, 0xa4, 0x72, 0xff, 0x09, 0xa5, 0x74, 0xff, 0x0b, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa3, 0x7a, 0xff, 0x0e, 0xa2, 0x7a, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x14, 0xa9, 0x6e, 0xff, 0x14, 0xa8, 0x72, 0xff, 0x13, 0xa5, 0x77, 0xff, 0x13, 0xa6, 0x78, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0c, 0xa0, 0x6f, 0xff, 0x0c, 0x9d, 0x6a, 0xff, 0x22, 0xae, 0x79, 0xff, 0x07, 0x85, 0x50, 0xff, 0x08, 0x8d, 0x55, 0xff, 0x28, 0xba, 0x80, 0xff, 0x10, 0x9a, 0x65, 0xff, 0x08, 0x85, 0x59, 0xff, 0x17, 0x99, 0x72, 0xff, 0x19, 0xa8, 0x7e, 0xff, 0x24, 0xaf, 0x83, 0xff, 0x1e, 0xa4, 0x79, 0xff, 0x17, 0x9e, 0x77, 0xff, 0x49, 0xc6, 0xab, 0xff, 0x26, 0x9a, 0x84, 0xff, 0x18, 0x9a, 0x7f, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x06, 0x96, 0x63, 0xff, 0x1d, 0xaf, 0x78, 0xff, 0x2f, 0xbc, 0x90, 0xff, 0x29, 0xb3, 0x89, 0xff, 0x11, 0x99, 0x6d, 0xff, 0x31, 0xb6, 0x90, 0xff, 0x28, 0xac, 0x8e, 0xff, 0x17, 0x9c, 0x7d, 0xff, 0x15, 0xa0, 0x77, 0xff, 0x16, 0xa7, 0x78, 0xff, 0x10, 0xa5, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0f, 0xa8, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x07, 0x9e, 0x68, 0xff, 0x06, 0x9e, 0x67, 0xff, 0x05, 0x9e, 0x67, 0xff, 0x06, 0x9f, 0x68, 0xff, 0x06, 0xa0, 0x68, 0xff, 0x06, 0xa0, 0x68, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x05, 0x9d, 0x67, 0xff, 0x05, 0x9e, 0x68, 0xff, 0x07, 0xa1, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0a, 0x9a, 0x68, 0xff, 0x08, 0x97, 0x66, 0xff, 0x08, 0x98, 0x67, 0xff, 0x0b, 0x9b, 0x6a, 0xff, 0x0a, 0x9c, 0x6a, 0xff, 0x08, 0x9b, 0x68, 0xff, 0x09, 0x9c, 0x6a, 0xff, 0x0a, 0x9e, 0x6b, 0xff, 0x0c, 0xa1, 0x6c, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x09, 0xa0, 0x6b, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x0a, 0x9f, 0x6a, 0xff, 0x0b, 0x9f, 0x6a, 0xff, 0x0b, 0x9d, 0x6b, 0xff, 0x0a, 0x9d, 0x6b, 0xff, 0x0a, 0x9d, 0x6b, 0xff, 0x0a, 0x9c, 0x6a, 0xff, 0x09, 0x9c, 0x69, 0xff, 0x09, 0x9b, 0x69, 0xff, 0x09, 0x9b, 0x69, 0xff, 0x0d, 0x9e, 0x6c, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa2, 0x68, 0xff, 0x0d, 0xa0, 0x65, 0xff, 0x0c, 0x9f, 0x64, 0xff, 0x0b, 0x9e, 0x63, 0xff, 0x0a, 0x9d, 0x63, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0a, 0x9d, 0x61, 0xff, 0x07, 0xa1, 0x5a, 0xff, 0x05, 0x99, 0x66, 0xff, 0x10, 0x83, 0x89, 0xff, 0x1f, 0x61, 0xcf, 0xff, 0x22, 0x62, 0xef, 0xff, 0x13, 0x5a, 0xe8, 0xff, 0x20, 0x6b, 0xe7, 0xff, 0x17, 0x67, 0xe9, 0xff, 0x0f, 0x69, 0xeb, 0xff, 0x19, 0x75, 0xee, 0xff, 0x23, 0x76, 0xea, 0xff, 0x1e, 0x6c, 0xbe, 0xff, 0x06, 0x5b, 0x71, 0xff, 0x10, 0x70, 0x47, 0xff, 0x11, 0x70, 0x3c, 0xff, 0x0c, 0x68, 0x3f, 0xff, 0x08, 0x65, 0x3b, 0xff, 0x08, 0x60, 0x36, 0xff, 0x0d, 0x5a, 0x39, 0xff, 0x12, 0x50, 0x3f, 0xff, 0x15, 0x4c, 0x48, 0xff, 0x38, 0x6c, 0x76, 0xff, 0x2e, 0x62, 0x76, 0xff, 0x2f, 0x66, 0x81, 0xff, 0x33, 0x6d, 0x82, 0xff, 0x35, 0x68, 0x80, 0xff, 0x33, 0x60, 0x7d, 0xff, 0x26, 0x59, 0x71, 0xff, 0x13, 0x49, 0x5e, 0xff, 0x15, 0x46, 0x58, 0xff, 0x11, 0x44, 0x4b, 0xff, 0x0b, 0x4f, 0x3a, 0xff, 0x0c, 0x5a, 0x34, 0xff, 0x09, 0x5f, 0x35, 0xff, 0x06, 0x60, 0x34, 0xff, 0x0d, 0x61, 0x35, 0xff, 0x09, 0x53, 0x2f, 0xff, 0x07, 0x4e, 0x2b, 0xff, 0x05, 0x51, 0x29, 0xff, 0x65, 0x8c, 0x7a, 0xff, + 0x0a, 0x62, 0x8d, 0xff, 0x06, 0x49, 0x9b, 0xff, 0x04, 0x4b, 0x9b, 0xff, 0x12, 0x5e, 0xb9, 0xff, 0x13, 0x65, 0xca, 0xff, 0x08, 0x67, 0xc9, 0xff, 0x1b, 0x76, 0xe2, 0xff, 0x1d, 0x82, 0xf5, 0xff, 0x16, 0x8b, 0xf2, 0xff, 0x1d, 0x78, 0xcd, 0xff, 0x1f, 0x5d, 0xa4, 0xff, 0x3d, 0x93, 0xdd, 0xff, 0x23, 0x96, 0xf2, 0xff, 0x26, 0x97, 0xf7, 0xff, 0x2f, 0x97, 0xf3, 0xff, 0x26, 0x98, 0xf4, 0xff, 0x27, 0x9e, 0xf7, 0xff, 0x24, 0x9a, 0xf5, 0xff, 0x29, 0x9a, 0xf8, 0xff, 0x2b, 0x97, 0xf9, 0xff, 0x2a, 0x99, 0xf9, 0xff, 0x21, 0x9d, 0xf5, 0xff, 0x1b, 0xa9, 0xf2, 0xff, 0x29, 0xbb, 0xfb, 0xff, 0x1e, 0xa4, 0xf4, 0xff, 0x1a, 0xb3, 0xf9, 0xff, 0x25, 0x96, 0xc7, 0xff, 0x01, 0x07, 0x23, 0xff, 0x13, 0x45, 0x62, 0xff, 0x2b, 0xc1, 0xf0, 0xff, 0x19, 0xb8, 0xfb, 0xff, 0x0b, 0xbd, 0xf4, 0xff, 0x16, 0xd1, 0xf4, 0xff, 0x22, 0xa8, 0xdf, 0xff, 0x26, 0x91, 0xbc, 0xff, 0x25, 0xa3, 0x92, 0xff, 0x28, 0xaa, 0x8c, 0xff, 0x2b, 0xa7, 0x8d, 0xff, 0x28, 0xa6, 0x90, 0xff, 0x2b, 0xa8, 0x8e, 0xff, 0x2b, 0xa8, 0x8e, 0xff, 0x2b, 0xa8, 0x8e, 0xff, 0x2b, 0xa7, 0x8f, 0xff, 0x2a, 0xa7, 0x8d, 0xff, 0x29, 0xa7, 0x8b, 0xff, 0x2a, 0xa8, 0x8b, 0xff, 0x27, 0xa8, 0x89, 0xff, 0x22, 0xa8, 0x86, 0xff, 0x25, 0xa9, 0x85, 0xff, 0x28, 0xab, 0x85, 0xff, 0x22, 0xa7, 0x80, 0xff, 0x1c, 0xa6, 0x7e, 0xff, 0x19, 0xa7, 0x7c, 0xff, 0x17, 0xa6, 0x7a, 0xff, 0x19, 0xa7, 0x7a, 0xff, 0x19, 0xa7, 0x7b, 0xff, 0x18, 0xa7, 0x7a, 0xff, 0x16, 0xa5, 0x75, 0xff, 0x16, 0xa5, 0x76, 0xff, 0x15, 0xa5, 0x79, 0xff, 0x15, 0xa6, 0x7a, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa3, 0x75, 0xff, 0x0c, 0xa4, 0x75, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x74, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x12, 0xa1, 0x79, 0xff, 0x0c, 0xa0, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0a, 0xa0, 0x6b, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x11, 0xa7, 0x70, 0xff, 0x13, 0xab, 0x75, 0xff, 0x14, 0xad, 0x78, 0xff, 0x09, 0xa3, 0x70, 0xff, 0x14, 0xa4, 0x77, 0xff, 0x0e, 0x9c, 0x71, 0xff, 0x15, 0xa5, 0x77, 0xff, 0x1b, 0xab, 0x7d, 0xff, 0x17, 0xa6, 0x76, 0xff, 0x12, 0xa2, 0x72, 0xff, 0x14, 0xa4, 0x73, 0xff, 0x10, 0xa2, 0x70, 0xff, 0x16, 0xac, 0x71, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x12, 0xad, 0x70, 0xff, 0x12, 0xae, 0x71, 0xff, 0x10, 0xac, 0x70, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x10, 0xa8, 0x6f, 0xff, 0x10, 0xa6, 0x6e, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x07, 0xa2, 0x6d, 0xff, 0x08, 0xa5, 0x71, 0xff, 0x0b, 0xa5, 0x75, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa3, 0x7b, 0xff, 0x0e, 0xa2, 0x7b, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x08, 0xa7, 0x74, 0xff, 0x09, 0xa7, 0x73, 0xff, 0x0b, 0xa8, 0x72, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0c, 0xaa, 0x6f, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x11, 0xa9, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x06, 0x96, 0x63, 0xff, 0x02, 0x89, 0x55, 0xff, 0x07, 0x8a, 0x54, 0xff, 0x04, 0x8c, 0x55, 0xff, 0x01, 0x91, 0x58, 0xff, 0x06, 0x94, 0x5d, 0xff, 0x0b, 0x94, 0x61, 0xff, 0x09, 0x96, 0x66, 0xff, 0x29, 0xbd, 0x8e, 0xff, 0x1d, 0xa6, 0x78, 0xff, 0x11, 0x94, 0x68, 0xff, 0x12, 0x94, 0x6b, 0xff, 0x18, 0x8e, 0x70, 0xff, 0x42, 0xb0, 0x99, 0xff, 0x4c, 0xc8, 0xad, 0xff, 0x29, 0xb3, 0x8e, 0xff, 0x0b, 0x99, 0x67, 0xff, 0x25, 0xb4, 0x7e, 0xff, 0x27, 0xb2, 0x85, 0xff, 0x1b, 0xa4, 0x77, 0xff, 0x0d, 0x94, 0x62, 0xff, 0x0f, 0x93, 0x68, 0xff, 0x25, 0xa4, 0x86, 0xff, 0x40, 0xbd, 0xa1, 0xff, 0x36, 0xba, 0x94, 0xff, 0x1b, 0xa9, 0x7b, 0xff, 0x10, 0xa2, 0x70, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0xa0, 0x69, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x09, 0xa2, 0x68, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x08, 0x9f, 0x66, 0xff, 0x07, 0x9e, 0x66, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x0a, 0xa2, 0x69, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x10, 0xa3, 0x6c, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x0f, 0xa2, 0x6d, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x08, 0x9f, 0x69, 0xff, 0x0a, 0xa0, 0x6b, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0e, 0xa2, 0x64, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0a, 0x9e, 0x60, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x09, 0xa0, 0x5b, 0xff, 0x0f, 0x95, 0x75, 0xff, 0x0a, 0x64, 0x9f, 0xff, 0x22, 0x5b, 0xe8, 0xff, 0x23, 0x62, 0xf2, 0xff, 0x17, 0x61, 0xef, 0xff, 0x1e, 0x6a, 0xf6, 0xff, 0x17, 0x69, 0xed, 0xff, 0x1b, 0x77, 0xf9, 0xff, 0x20, 0x80, 0xfd, 0xff, 0x1d, 0x76, 0xf5, 0xff, 0x24, 0x70, 0xeb, 0xff, 0x0d, 0x56, 0xb0, 0xff, 0x09, 0x5d, 0x69, 0xff, 0x11, 0x6e, 0x47, 0xff, 0x0d, 0x6e, 0x35, 0xff, 0x06, 0x6d, 0x38, 0xff, 0x02, 0x64, 0x34, 0xff, 0x09, 0x5e, 0x34, 0xff, 0x13, 0x59, 0x40, 0xff, 0x1e, 0x5c, 0x55, 0xff, 0x2a, 0x62, 0x70, 0xff, 0x29, 0x60, 0x75, 0xff, 0x2b, 0x62, 0x75, 0xff, 0x26, 0x60, 0x71, 0xff, 0x2e, 0x62, 0x78, 0xff, 0x28, 0x53, 0x6d, 0xff, 0x1f, 0x4d, 0x63, 0xff, 0x15, 0x48, 0x5b, 0xff, 0x18, 0x47, 0x5b, 0xff, 0x15, 0x46, 0x52, 0xff, 0x0d, 0x4f, 0x3f, 0xff, 0x0f, 0x59, 0x36, 0xff, 0x0a, 0x5d, 0x35, 0xff, 0x05, 0x5d, 0x30, 0xff, 0x0b, 0x5f, 0x32, 0xff, 0x0a, 0x55, 0x30, 0xff, 0x07, 0x4c, 0x2a, 0xff, 0x06, 0x51, 0x28, 0xff, 0x64, 0x8c, 0x79, 0xff, + 0x05, 0x57, 0x8d, 0xff, 0x05, 0x47, 0x9a, 0xff, 0x06, 0x50, 0xa2, 0xff, 0x12, 0x61, 0xc0, 0xff, 0x10, 0x62, 0xcb, 0xff, 0x0c, 0x68, 0xcf, 0xff, 0x19, 0x76, 0xe5, 0xff, 0x19, 0x82, 0xfc, 0xff, 0x16, 0x89, 0xf9, 0xff, 0x22, 0x78, 0xcd, 0xff, 0x0b, 0x30, 0x6b, 0xff, 0x24, 0x5c, 0x93, 0xff, 0x2b, 0x8e, 0xdf, 0xff, 0x23, 0x94, 0xf7, 0xff, 0x2a, 0x97, 0xf6, 0xff, 0x28, 0x9b, 0xf2, 0xff, 0x30, 0x9e, 0xf4, 0xff, 0x34, 0x9d, 0xf5, 0xff, 0x2c, 0x97, 0xf0, 0xff, 0x28, 0x9b, 0xf6, 0xff, 0x27, 0x9f, 0xf8, 0xff, 0x29, 0xa4, 0xf8, 0xff, 0x25, 0xa8, 0xf2, 0xff, 0x32, 0xba, 0xfb, 0xff, 0x28, 0xb0, 0xf5, 0xff, 0x20, 0xbb, 0xf3, 0xff, 0x2e, 0x99, 0xc3, 0xff, 0x01, 0x0b, 0x29, 0xff, 0x26, 0x84, 0xa3, 0xff, 0x1e, 0xc7, 0xf7, 0xff, 0x12, 0xb7, 0xfb, 0xff, 0x0d, 0xbb, 0xf8, 0xff, 0x13, 0xce, 0xf7, 0xff, 0x21, 0xab, 0xdd, 0xff, 0x24, 0x8f, 0xbb, 0xff, 0x23, 0xa1, 0x95, 0xff, 0x29, 0xa9, 0x8f, 0xff, 0x2c, 0xa7, 0x8e, 0xff, 0x29, 0xa8, 0x8f, 0xff, 0x2c, 0xaa, 0x8e, 0xff, 0x2c, 0xa9, 0x8f, 0xff, 0x2c, 0xa9, 0x8f, 0xff, 0x2c, 0xa9, 0x8f, 0xff, 0x2c, 0xa9, 0x8e, 0xff, 0x2a, 0xa8, 0x8a, 0xff, 0x2a, 0xa9, 0x8a, 0xff, 0x28, 0xa8, 0x89, 0xff, 0x25, 0xa9, 0x89, 0xff, 0x28, 0xa9, 0x89, 0xff, 0x28, 0xa9, 0x87, 0xff, 0x25, 0xa8, 0x85, 0xff, 0x1f, 0xa7, 0x83, 0xff, 0x1b, 0xa6, 0x81, 0xff, 0x19, 0xa5, 0x7c, 0xff, 0x19, 0xa6, 0x7b, 0xff, 0x17, 0xa5, 0x7a, 0xff, 0x17, 0xa6, 0x79, 0xff, 0x18, 0xa6, 0x77, 0xff, 0x18, 0xa7, 0x79, 0xff, 0x17, 0xa6, 0x7a, 0xff, 0x14, 0xa6, 0x78, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x74, 0xff, 0x0c, 0xa4, 0x74, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x74, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x0b, 0xa0, 0x69, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x10, 0xa7, 0x6d, 0xff, 0x18, 0xb1, 0x7a, 0xff, 0x17, 0xb0, 0x7b, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x12, 0xa5, 0x75, 0xff, 0x10, 0xa0, 0x72, 0xff, 0x1a, 0xab, 0x7c, 0xff, 0x1e, 0xb0, 0x80, 0xff, 0x1b, 0xad, 0x7a, 0xff, 0x14, 0xa6, 0x74, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x13, 0xa6, 0x72, 0xff, 0x11, 0xa8, 0x6e, 0xff, 0x10, 0xa9, 0x6e, 0xff, 0x13, 0xae, 0x72, 0xff, 0x11, 0xad, 0x71, 0xff, 0x0d, 0xaa, 0x6e, 0xff, 0x0a, 0xa6, 0x6b, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x0f, 0xa7, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x06, 0xa5, 0x6f, 0xff, 0x09, 0xa5, 0x73, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x7b, 0xff, 0x0e, 0xa2, 0x7b, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x08, 0xa7, 0x71, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x0a, 0xa8, 0x74, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0d, 0xa6, 0x76, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0e, 0xa9, 0x70, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0d, 0xa4, 0x77, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x11, 0xa8, 0x75, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x08, 0x9a, 0x68, 0xff, 0x05, 0x92, 0x5f, 0xff, 0x0e, 0x9a, 0x65, 0xff, 0x0d, 0x9d, 0x68, 0xff, 0x08, 0x9d, 0x67, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0f, 0xa0, 0x6b, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x1d, 0xb1, 0x7e, 0xff, 0x0e, 0x96, 0x65, 0xff, 0x0e, 0x93, 0x61, 0xff, 0x1e, 0xa3, 0x74, 0xff, 0x1d, 0x97, 0x73, 0xff, 0x31, 0xa0, 0x85, 0xff, 0x43, 0xbd, 0xa0, 0xff, 0x2e, 0xb4, 0x8f, 0xff, 0x05, 0x8e, 0x5d, 0xff, 0x1a, 0xa6, 0x71, 0xff, 0x16, 0x9f, 0x71, 0xff, 0x0b, 0x94, 0x63, 0xff, 0x12, 0x9d, 0x64, 0xff, 0x20, 0xa7, 0x76, 0xff, 0x1e, 0x9d, 0x7b, 0xff, 0x30, 0xab, 0x8d, 0xff, 0x3d, 0xbd, 0x96, 0xff, 0x14, 0x9e, 0x72, 0xff, 0x0a, 0x9a, 0x69, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0c, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x0a, 0xa1, 0x66, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa1, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0f, 0xa3, 0x66, 0xff, 0x10, 0xa5, 0x66, 0xff, 0x0f, 0xa4, 0x64, 0xff, 0x0e, 0xa2, 0x63, 0xff, 0x0d, 0xa1, 0x61, 0xff, 0x0d, 0xa0, 0x61, 0xff, 0x0d, 0xa0, 0x61, 0xff, 0x0d, 0xa1, 0x61, 0xff, 0x0b, 0x9f, 0x60, 0xff, 0x0b, 0x9e, 0x5f, 0xff, 0x0b, 0x9f, 0x5f, 0xff, 0x0d, 0x9f, 0x5e, 0xff, 0x0f, 0x83, 0x7e, 0xff, 0x09, 0x54, 0xae, 0xff, 0x10, 0x48, 0xdb, 0xff, 0x13, 0x53, 0xe4, 0xff, 0x12, 0x5e, 0xef, 0xff, 0x16, 0x65, 0xfb, 0xff, 0x14, 0x69, 0xf1, 0xff, 0x0f, 0x68, 0xf1, 0xff, 0x0e, 0x6c, 0xf6, 0xff, 0x15, 0x73, 0xf8, 0xff, 0x11, 0x64, 0xea, 0xff, 0x08, 0x4e, 0xcc, 0xff, 0x03, 0x49, 0x90, 0xff, 0x09, 0x5c, 0x64, 0xff, 0x0b, 0x6a, 0x43, 0xff, 0x07, 0x6a, 0x45, 0xff, 0x04, 0x64, 0x3f, 0xff, 0x0b, 0x60, 0x37, 0xff, 0x10, 0x5b, 0x3d, 0xff, 0x1d, 0x60, 0x58, 0xff, 0x28, 0x63, 0x73, 0xff, 0x26, 0x5f, 0x76, 0xff, 0x2c, 0x63, 0x76, 0xff, 0x28, 0x63, 0x73, 0xff, 0x29, 0x5b, 0x72, 0xff, 0x21, 0x4a, 0x63, 0xff, 0x19, 0x44, 0x57, 0xff, 0x17, 0x47, 0x56, 0xff, 0x19, 0x45, 0x58, 0xff, 0x12, 0x43, 0x4d, 0xff, 0x0d, 0x4f, 0x3e, 0xff, 0x0e, 0x58, 0x35, 0xff, 0x0b, 0x5c, 0x35, 0xff, 0x05, 0x5c, 0x31, 0xff, 0x0c, 0x5e, 0x30, 0xff, 0x0d, 0x56, 0x31, 0xff, 0x08, 0x4d, 0x2a, 0xff, 0x06, 0x4f, 0x26, 0xff, 0x64, 0x8b, 0x79, 0xff, + 0x01, 0x4e, 0x8a, 0xff, 0x04, 0x49, 0x99, 0xff, 0x0b, 0x57, 0xae, 0xff, 0x12, 0x63, 0xc7, 0xff, 0x0d, 0x60, 0xcb, 0xff, 0x13, 0x69, 0xd8, 0xff, 0x11, 0x74, 0xe4, 0xff, 0x14, 0x87, 0xf9, 0xff, 0x15, 0x87, 0xf8, 0xff, 0x2c, 0x8f, 0xe9, 0xff, 0x1c, 0x51, 0x87, 0xff, 0x02, 0x0e, 0x2f, 0xff, 0x1f, 0x5b, 0x9a, 0xff, 0x2a, 0x96, 0xef, 0xff, 0x1e, 0x9a, 0xf3, 0xff, 0x2a, 0xa3, 0xf5, 0xff, 0x46, 0xa6, 0xf8, 0xff, 0x22, 0x74, 0xc9, 0xff, 0x1b, 0x7d, 0xd2, 0xff, 0x1f, 0x9f, 0xf2, 0xff, 0x1d, 0xa4, 0xf6, 0xff, 0x29, 0x9f, 0xef, 0xff, 0x13, 0x7a, 0xc7, 0xff, 0x2e, 0x93, 0xda, 0xff, 0x42, 0xb7, 0xf4, 0xff, 0x47, 0xcf, 0xfa, 0xff, 0x3d, 0x9a, 0xbf, 0xff, 0x06, 0x31, 0x54, 0xff, 0x2a, 0xc1, 0xe3, 0xff, 0x14, 0xc3, 0xfb, 0xff, 0x14, 0xb7, 0xfd, 0xff, 0x11, 0xb8, 0xfd, 0xff, 0x11, 0xca, 0xfc, 0xff, 0x17, 0xa3, 0xd2, 0xff, 0x1e, 0x8b, 0xb4, 0xff, 0x24, 0xa1, 0x98, 0xff, 0x27, 0xa6, 0x92, 0xff, 0x2c, 0xa7, 0x8f, 0xff, 0x29, 0xaa, 0x8c, 0xff, 0x2b, 0xaa, 0x8d, 0xff, 0x2b, 0xaa, 0x8e, 0xff, 0x2b, 0xa9, 0x8f, 0xff, 0x2c, 0xa9, 0x8f, 0xff, 0x2c, 0xaa, 0x8f, 0xff, 0x2a, 0xa9, 0x8c, 0xff, 0x29, 0xaa, 0x8b, 0xff, 0x28, 0xa9, 0x8a, 0xff, 0x27, 0xaa, 0x8c, 0xff, 0x2a, 0xab, 0x8c, 0xff, 0x2a, 0xa9, 0x89, 0xff, 0x29, 0xa9, 0x89, 0xff, 0x22, 0xa7, 0x87, 0xff, 0x1e, 0xa6, 0x84, 0xff, 0x19, 0xa5, 0x7e, 0xff, 0x19, 0xa6, 0x7c, 0xff, 0x18, 0xa6, 0x7b, 0xff, 0x17, 0xa7, 0x79, 0xff, 0x17, 0xa5, 0x76, 0xff, 0x17, 0xa5, 0x77, 0xff, 0x16, 0xa5, 0x78, 0xff, 0x11, 0xa4, 0x74, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x10, 0xa3, 0x75, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x10, 0xa5, 0x70, 0xff, 0x12, 0xa6, 0x6f, 0xff, 0x0e, 0xa2, 0x69, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x16, 0xaf, 0x7a, 0xff, 0x12, 0xac, 0x78, 0xff, 0x13, 0xa9, 0x76, 0xff, 0x0a, 0x9e, 0x6c, 0xff, 0x13, 0xa7, 0x74, 0xff, 0x17, 0xac, 0x78, 0xff, 0x17, 0xac, 0x76, 0xff, 0x18, 0xad, 0x77, 0xff, 0x0b, 0xa1, 0x69, 0xff, 0x17, 0xad, 0x75, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x15, 0xaf, 0x76, 0xff, 0x15, 0xb2, 0x77, 0xff, 0x0f, 0xaf, 0x73, 0xff, 0x07, 0xa6, 0x6a, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0c, 0xa8, 0x6d, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x07, 0xa8, 0x71, 0xff, 0x09, 0xa6, 0x72, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x0e, 0xa1, 0x7c, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0b, 0xac, 0x6d, 0xff, 0x09, 0xac, 0x6d, 0xff, 0x07, 0xa8, 0x74, 0xff, 0x06, 0xaa, 0x73, 0xff, 0x08, 0xa9, 0x75, 0xff, 0x0e, 0xa9, 0x73, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0e, 0xab, 0x6d, 0xff, 0x0e, 0xa9, 0x71, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x11, 0xaa, 0x74, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x11, 0xa6, 0x73, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x07, 0x9c, 0x66, 0xff, 0x07, 0x9a, 0x63, 0xff, 0x36, 0xc8, 0x92, 0xff, 0x26, 0xaf, 0x7b, 0xff, 0x1f, 0xa7, 0x6f, 0xff, 0x3b, 0xc7, 0x91, 0xff, 0x21, 0xa4, 0x79, 0xff, 0x0a, 0x7f, 0x5f, 0xff, 0x1b, 0x96, 0x75, 0xff, 0x1e, 0x9f, 0x7a, 0xff, 0x07, 0x8c, 0x5b, 0xff, 0x1d, 0xa8, 0x73, 0xff, 0x34, 0xc0, 0x8e, 0xff, 0x0f, 0x9a, 0x63, 0xff, 0x30, 0xbf, 0x80, 0xff, 0x3e, 0xc9, 0x90, 0xff, 0x0e, 0x8f, 0x68, 0xff, 0x09, 0x84, 0x62, 0xff, 0x28, 0xa6, 0x80, 0xff, 0x0a, 0x92, 0x66, 0xff, 0x0b, 0x99, 0x69, 0xff, 0x11, 0xa3, 0x6f, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0b, 0xa2, 0x69, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0a, 0xa1, 0x65, 0xff, 0x0b, 0xa1, 0x64, 0xff, 0x0c, 0xa2, 0x63, 0xff, 0x0b, 0xa3, 0x63, 0xff, 0x08, 0xa4, 0x65, 0xff, 0x0a, 0xa4, 0x65, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0e, 0xa3, 0x66, 0xff, 0x0d, 0xa2, 0x64, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0a, 0xa2, 0x64, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x0a, 0xa2, 0x64, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x08, 0xa1, 0x66, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa1, 0x6f, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0d, 0xa3, 0x6a, 0xff, 0x0d, 0xa3, 0x66, 0xff, 0x0d, 0xa2, 0x64, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x0d, 0xa3, 0x62, 0xff, 0x0d, 0xa2, 0x61, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0d, 0xa1, 0x60, 0xff, 0x0d, 0xa1, 0x60, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0x9f, 0x5f, 0xff, 0x10, 0x99, 0x69, 0xff, 0x09, 0x5e, 0x8b, 0xff, 0x0b, 0x41, 0xbc, 0xff, 0x06, 0x3d, 0xd5, 0xff, 0x0e, 0x4c, 0xe7, 0xff, 0x06, 0x52, 0xe8, 0xff, 0x05, 0x5b, 0xf2, 0xff, 0x0f, 0x68, 0xf3, 0xff, 0x0d, 0x65, 0xee, 0xff, 0x03, 0x60, 0xed, 0xff, 0x09, 0x68, 0xf4, 0xff, 0x08, 0x60, 0xef, 0xff, 0x04, 0x4d, 0xe0, 0xff, 0x02, 0x3c, 0xbc, 0xff, 0x01, 0x41, 0x95, 0xff, 0x07, 0x56, 0x6c, 0xff, 0x08, 0x60, 0x5e, 0xff, 0x09, 0x61, 0x4e, 0xff, 0x0e, 0x61, 0x40, 0xff, 0x13, 0x5f, 0x41, 0xff, 0x1f, 0x64, 0x5c, 0xff, 0x21, 0x61, 0x75, 0xff, 0x24, 0x5e, 0x7b, 0xff, 0x2c, 0x64, 0x79, 0xff, 0x27, 0x63, 0x75, 0xff, 0x25, 0x58, 0x6f, 0xff, 0x1e, 0x46, 0x5d, 0xff, 0x15, 0x3e, 0x4d, 0xff, 0x0c, 0x39, 0x45, 0xff, 0x0e, 0x39, 0x49, 0xff, 0x0c, 0x3c, 0x43, 0xff, 0x0f, 0x53, 0x3e, 0xff, 0x0c, 0x55, 0x32, 0xff, 0x0b, 0x59, 0x33, 0xff, 0x04, 0x59, 0x2f, 0xff, 0x0a, 0x5b, 0x2e, 0xff, 0x0f, 0x56, 0x32, 0xff, 0x09, 0x4f, 0x2a, 0xff, 0x06, 0x4f, 0x26, 0xff, 0x64, 0x8b, 0x79, 0xff, + 0x00, 0x48, 0x8c, 0xff, 0x0f, 0x51, 0xa0, 0xff, 0x15, 0x5c, 0xbb, 0xff, 0x13, 0x64, 0xcb, 0xff, 0x0c, 0x62, 0xca, 0xff, 0x14, 0x6e, 0xdc, 0xff, 0x0e, 0x76, 0xe1, 0xff, 0x13, 0x87, 0xf0, 0xff, 0x13, 0x89, 0xf3, 0xff, 0x21, 0x93, 0xf1, 0xff, 0x3c, 0x91, 0xd0, 0xff, 0x07, 0x15, 0x34, 0xff, 0x0b, 0x26, 0x4f, 0xff, 0x35, 0x97, 0xd8, 0xff, 0x2e, 0xae, 0xf2, 0xff, 0x2c, 0x91, 0xd7, 0xff, 0x1a, 0x59, 0xaa, 0xff, 0x06, 0x38, 0x8f, 0xff, 0x20, 0x80, 0xd7, 0xff, 0x24, 0xa3, 0xf5, 0xff, 0x24, 0xa6, 0xf5, 0xff, 0x2c, 0xa3, 0xf2, 0xff, 0x1a, 0x78, 0xc6, 0xff, 0x05, 0x36, 0x86, 0xff, 0x10, 0x4f, 0x9a, 0xff, 0x34, 0x81, 0xb8, 0xff, 0x18, 0x52, 0x80, 0xff, 0x1f, 0x8b, 0xb3, 0xff, 0x1b, 0xd2, 0xfb, 0xff, 0x12, 0xc4, 0xfa, 0xff, 0x16, 0xb7, 0xf9, 0xff, 0x13, 0xb6, 0xfe, 0xff, 0x17, 0xc3, 0xfe, 0xff, 0x0b, 0x8c, 0xbd, 0xff, 0x23, 0x8d, 0xba, 0xff, 0x26, 0xa0, 0x9e, 0xff, 0x2a, 0xa6, 0x95, 0xff, 0x2b, 0xa7, 0x90, 0xff, 0x29, 0xac, 0x8b, 0xff, 0x2c, 0xaa, 0x8e, 0xff, 0x2b, 0xaa, 0x8e, 0xff, 0x2a, 0xa9, 0x8f, 0xff, 0x2a, 0xa9, 0x8f, 0xff, 0x2a, 0xaa, 0x8e, 0xff, 0x29, 0xaa, 0x8c, 0xff, 0x29, 0xab, 0x8c, 0xff, 0x28, 0xa9, 0x8c, 0xff, 0x29, 0xa9, 0x8e, 0xff, 0x29, 0xa9, 0x8b, 0xff, 0x29, 0xa8, 0x88, 0xff, 0x25, 0xa7, 0x86, 0xff, 0x21, 0xa7, 0x85, 0xff, 0x1d, 0xa7, 0x84, 0xff, 0x1b, 0xa7, 0x7f, 0xff, 0x1b, 0xa8, 0x7d, 0xff, 0x18, 0xa7, 0x7a, 0xff, 0x16, 0xa7, 0x78, 0xff, 0x14, 0xa4, 0x73, 0xff, 0x12, 0xa3, 0x71, 0xff, 0x0f, 0xa2, 0x71, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x08, 0xa3, 0x69, 0xff, 0x08, 0xa5, 0x68, 0xff, 0x08, 0xa4, 0x69, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0e, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x73, 0xff, 0x0e, 0xa4, 0x73, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x12, 0xa3, 0x78, 0xff, 0x12, 0xa3, 0x77, 0xff, 0x12, 0xa4, 0x74, 0xff, 0x12, 0xa5, 0x72, 0xff, 0x11, 0xa3, 0x6c, 0xff, 0x0d, 0xa2, 0x68, 0xff, 0x11, 0xa9, 0x6d, 0xff, 0x0f, 0xa7, 0x6f, 0xff, 0x12, 0xab, 0x77, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x1a, 0xb2, 0x7c, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x11, 0xa7, 0x70, 0xff, 0x18, 0xb0, 0x77, 0xff, 0x0f, 0xa7, 0x6c, 0xff, 0x1b, 0xb5, 0x7a, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x1c, 0xb6, 0x79, 0xff, 0x13, 0xb0, 0x75, 0xff, 0x12, 0xb1, 0x75, 0xff, 0x19, 0xba, 0x7c, 0xff, 0x0a, 0xaa, 0x6c, 0xff, 0x04, 0xa3, 0x64, 0xff, 0x0f, 0xae, 0x71, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x09, 0xa6, 0x6b, 0xff, 0x0b, 0xab, 0x70, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x10, 0xa3, 0x7b, 0xff, 0x0f, 0xa2, 0x7b, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x0b, 0xaa, 0x6f, 0xff, 0x0c, 0xa9, 0x70, 0xff, 0x0d, 0xab, 0x6d, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0a, 0xa9, 0x73, 0xff, 0x09, 0xaa, 0x73, 0xff, 0x0c, 0xaa, 0x74, 0xff, 0x0f, 0xab, 0x74, 0xff, 0x0f, 0xab, 0x72, 0xff, 0x0d, 0xab, 0x71, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0e, 0xab, 0x71, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x12, 0xa9, 0x75, 0xff, 0x12, 0xa8, 0x77, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x12, 0xa7, 0x76, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0f, 0xa9, 0x76, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x13, 0xa9, 0x79, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x09, 0x9c, 0x66, 0xff, 0x25, 0xb1, 0x7c, 0xff, 0x09, 0x8c, 0x58, 0xff, 0x0d, 0x92, 0x5b, 0xff, 0x2e, 0xbc, 0x84, 0xff, 0x12, 0x9a, 0x69, 0xff, 0x02, 0x7f, 0x55, 0xff, 0x1b, 0x9e, 0x75, 0xff, 0x18, 0x9d, 0x71, 0xff, 0x0a, 0x90, 0x5e, 0xff, 0x1f, 0xaa, 0x76, 0xff, 0x15, 0x9d, 0x6a, 0xff, 0x02, 0x87, 0x50, 0xff, 0x20, 0xad, 0x70, 0xff, 0x30, 0xbc, 0x83, 0xff, 0x05, 0x89, 0x5c, 0xff, 0x0a, 0x89, 0x61, 0xff, 0x22, 0xa8, 0x7c, 0xff, 0x0a, 0x98, 0x69, 0xff, 0x10, 0xa2, 0x70, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0d, 0xa2, 0x66, 0xff, 0x0d, 0xa3, 0x64, 0xff, 0x0d, 0xa3, 0x64, 0xff, 0x0c, 0xa4, 0x63, 0xff, 0x08, 0xa4, 0x63, 0xff, 0x09, 0xa4, 0x63, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x0c, 0xa4, 0x64, 0xff, 0x0c, 0xa4, 0x65, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x0a, 0xa3, 0x64, 0xff, 0x0b, 0xa3, 0x65, 0xff, 0x0c, 0xa3, 0x66, 0xff, 0x0d, 0xa3, 0x66, 0xff, 0x0b, 0xa4, 0x66, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0c, 0xa3, 0x67, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0c, 0xa2, 0x5e, 0xff, 0x0c, 0xa2, 0x5d, 0xff, 0x0c, 0xa0, 0x60, 0xff, 0x0c, 0x9f, 0x60, 0xff, 0x0d, 0xa1, 0x60, 0xff, 0x0c, 0xa2, 0x5f, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0d, 0x9f, 0x60, 0xff, 0x0e, 0x9d, 0x61, 0xff, 0x13, 0x87, 0x7d, 0xff, 0x02, 0x3d, 0x9f, 0xff, 0x02, 0x2c, 0xc5, 0xff, 0x08, 0x3d, 0xdf, 0xff, 0x0e, 0x4b, 0xeb, 0xff, 0x01, 0x4b, 0xe5, 0xff, 0x02, 0x59, 0xed, 0xff, 0x0d, 0x65, 0xf1, 0xff, 0x0f, 0x67, 0xf2, 0xff, 0x09, 0x64, 0xf3, 0xff, 0x04, 0x64, 0xf4, 0xff, 0x11, 0x6e, 0xfb, 0xff, 0x0a, 0x5b, 0xee, 0xff, 0x07, 0x43, 0xdd, 0xff, 0x02, 0x35, 0xc4, 0xff, 0x02, 0x3e, 0x9f, 0xff, 0x08, 0x48, 0x91, 0xff, 0x09, 0x57, 0x67, 0xff, 0x0a, 0x60, 0x45, 0xff, 0x11, 0x61, 0x43, 0xff, 0x20, 0x67, 0x61, 0xff, 0x21, 0x5f, 0x76, 0xff, 0x26, 0x5e, 0x7c, 0xff, 0x2a, 0x63, 0x78, 0xff, 0x28, 0x63, 0x76, 0xff, 0x23, 0x57, 0x6e, 0xff, 0x1c, 0x45, 0x5c, 0xff, 0x1a, 0x43, 0x51, 0xff, 0x0a, 0x39, 0x42, 0xff, 0x0d, 0x39, 0x46, 0xff, 0x0c, 0x3b, 0x40, 0xff, 0x11, 0x56, 0x3f, 0xff, 0x08, 0x54, 0x2f, 0xff, 0x0a, 0x57, 0x32, 0xff, 0x03, 0x55, 0x2e, 0xff, 0x09, 0x59, 0x30, 0xff, 0x0b, 0x56, 0x31, 0xff, 0x08, 0x4f, 0x29, 0xff, 0x08, 0x4f, 0x29, 0xff, 0x65, 0x8b, 0x7a, 0xff, + 0x02, 0x44, 0x8e, 0xff, 0x19, 0x51, 0xa5, 0xff, 0x1f, 0x5c, 0xc3, 0xff, 0x14, 0x63, 0xc9, 0xff, 0x0a, 0x62, 0xc4, 0xff, 0x0f, 0x73, 0xda, 0xff, 0x13, 0x7a, 0xe3, 0xff, 0x12, 0x84, 0xef, 0xff, 0x0b, 0x8a, 0xf5, 0xff, 0x19, 0x8e, 0xf2, 0xff, 0x40, 0xa9, 0xf7, 0xff, 0x32, 0x6d, 0x99, 0xff, 0x03, 0x0d, 0x2d, 0xff, 0x37, 0x87, 0xb1, 0xff, 0x4e, 0xb2, 0xe2, 0xff, 0x09, 0x2f, 0x71, 0xff, 0x01, 0x18, 0x6e, 0xff, 0x1b, 0x5e, 0xbb, 0xff, 0x2e, 0x96, 0xf4, 0xff, 0x2b, 0x90, 0xe4, 0xff, 0x34, 0x92, 0xe1, 0xff, 0x2f, 0xab, 0xf8, 0xff, 0x35, 0xb1, 0xf9, 0xff, 0x1c, 0x60, 0xb3, 0xff, 0x03, 0x17, 0x76, 0xff, 0x02, 0x12, 0x64, 0xff, 0x0b, 0x3f, 0x7c, 0xff, 0x31, 0xc5, 0xf3, 0xff, 0x0c, 0xca, 0xfa, 0xff, 0x0d, 0xcc, 0xfa, 0xff, 0x10, 0xbf, 0xf5, 0xff, 0x18, 0xb7, 0xfc, 0xff, 0x23, 0xb8, 0xf4, 0xff, 0x0a, 0x79, 0xaf, 0xff, 0x27, 0x95, 0xc6, 0xff, 0x2b, 0x9d, 0xa3, 0xff, 0x2e, 0xa7, 0x93, 0xff, 0x29, 0xa8, 0x91, 0xff, 0x26, 0xab, 0x8c, 0xff, 0x2d, 0xa9, 0x8e, 0xff, 0x2c, 0xa9, 0x8f, 0xff, 0x2b, 0xa9, 0x8f, 0xff, 0x2a, 0xaa, 0x8f, 0xff, 0x29, 0xab, 0x8d, 0xff, 0x29, 0xab, 0x8d, 0xff, 0x28, 0xaa, 0x8c, 0xff, 0x28, 0xaa, 0x8c, 0xff, 0x28, 0xa8, 0x8c, 0xff, 0x28, 0xa8, 0x8a, 0xff, 0x24, 0xa8, 0x88, 0xff, 0x21, 0xa7, 0x85, 0xff, 0x1d, 0xa7, 0x81, 0xff, 0x18, 0xa7, 0x7d, 0xff, 0x15, 0xa5, 0x7a, 0xff, 0x14, 0xa4, 0x78, 0xff, 0x14, 0xa5, 0x75, 0xff, 0x11, 0xa5, 0x72, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x08, 0xa2, 0x69, 0xff, 0x07, 0xa2, 0x68, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x08, 0xa2, 0x6c, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x09, 0xa4, 0x6f, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x0e, 0xa2, 0x73, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x0f, 0xa3, 0x75, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0c, 0xa3, 0x75, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x0d, 0xa4, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x12, 0xa1, 0x79, 0xff, 0x12, 0xa3, 0x77, 0xff, 0x0e, 0xa2, 0x6f, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0e, 0xa8, 0x6e, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa4, 0x70, 0xff, 0x08, 0xa3, 0x71, 0xff, 0x11, 0xa9, 0x72, 0xff, 0x11, 0xa7, 0x6e, 0xff, 0x14, 0xaa, 0x6e, 0xff, 0x17, 0xb0, 0x72, 0xff, 0x0b, 0xa7, 0x66, 0xff, 0x1a, 0xb8, 0x78, 0xff, 0x0d, 0xac, 0x6a, 0xff, 0x14, 0xb2, 0x70, 0xff, 0x17, 0xbc, 0x7c, 0xff, 0x0d, 0xb4, 0x73, 0xff, 0x19, 0xbd, 0x7a, 0xff, 0x08, 0xa7, 0x65, 0xff, 0x0b, 0xa7, 0x66, 0xff, 0x13, 0xae, 0x6f, 0xff, 0x0f, 0xab, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa6, 0x70, 0xff, 0x08, 0xa3, 0x71, 0xff, 0x0d, 0xa4, 0x77, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa3, 0x7a, 0xff, 0x0c, 0xa4, 0x79, 0xff, 0x0c, 0xa5, 0x79, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x76, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0d, 0xa6, 0x77, 0xff, 0x0c, 0xa6, 0x77, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x09, 0xa9, 0x72, 0xff, 0x06, 0xa9, 0x72, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x0c, 0xa9, 0x6f, 0xff, 0x0f, 0xaa, 0x70, 0xff, 0x0f, 0xab, 0x70, 0xff, 0x0e, 0xab, 0x71, 0xff, 0x0c, 0xaa, 0x71, 0xff, 0x0c, 0xaa, 0x71, 0xff, 0x0d, 0xab, 0x73, 0xff, 0x0c, 0xad, 0x71, 0xff, 0x0c, 0xac, 0x71, 0xff, 0x0c, 0xac, 0x73, 0xff, 0x0d, 0xab, 0x74, 0xff, 0x0f, 0xaa, 0x74, 0xff, 0x12, 0xa9, 0x76, 0xff, 0x14, 0xa9, 0x77, 0xff, 0x14, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x0e, 0xa8, 0x78, 0xff, 0x0f, 0xa8, 0x7a, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0e, 0xa0, 0x6e, 0xff, 0x06, 0x95, 0x64, 0xff, 0x04, 0x8a, 0x5a, 0xff, 0x01, 0x84, 0x53, 0xff, 0x01, 0x87, 0x57, 0xff, 0x04, 0x8d, 0x5c, 0xff, 0x05, 0x8e, 0x5c, 0xff, 0x04, 0x8e, 0x5c, 0xff, 0x08, 0x97, 0x64, 0xff, 0x14, 0xa4, 0x6f, 0xff, 0x0c, 0x9a, 0x67, 0xff, 0x0b, 0x94, 0x63, 0xff, 0x01, 0x84, 0x54, 0xff, 0x01, 0x87, 0x55, 0xff, 0x02, 0x89, 0x55, 0xff, 0x03, 0x8f, 0x5c, 0xff, 0x04, 0x90, 0x5d, 0xff, 0x03, 0x8f, 0x5d, 0xff, 0x0b, 0x9d, 0x6a, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0e, 0xa1, 0x66, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x0e, 0xa4, 0x65, 0xff, 0x0a, 0xa2, 0x63, 0xff, 0x0b, 0xa5, 0x65, 0xff, 0x0c, 0xa6, 0x65, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0a, 0xa6, 0x65, 0xff, 0x08, 0xa5, 0x65, 0xff, 0x08, 0xa5, 0x65, 0xff, 0x0b, 0xa5, 0x66, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x07, 0xa3, 0x6a, 0xff, 0x06, 0xa3, 0x6a, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x06, 0xa5, 0x6c, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x08, 0xa6, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa6, 0x6f, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0a, 0xa4, 0x63, 0xff, 0x0a, 0xa3, 0x5f, 0xff, 0x0b, 0xa2, 0x5e, 0xff, 0x0c, 0xa2, 0x5e, 0xff, 0x0c, 0xa1, 0x5e, 0xff, 0x0b, 0xa3, 0x5b, 0xff, 0x0c, 0xa0, 0x61, 0xff, 0x0e, 0x9f, 0x63, 0xff, 0x0d, 0xa0, 0x60, 0xff, 0x0b, 0xa1, 0x5d, 0xff, 0x0d, 0xa3, 0x5c, 0xff, 0x0f, 0x9c, 0x60, 0xff, 0x14, 0x95, 0x6e, 0xff, 0x10, 0x65, 0x93, 0xff, 0x0a, 0x3a, 0xc1, 0xff, 0x01, 0x2a, 0xd1, 0xff, 0x05, 0x38, 0xe0, 0xff, 0x03, 0x40, 0xde, 0xff, 0x02, 0x49, 0xe5, 0xff, 0x08, 0x56, 0xf0, 0xff, 0x1c, 0x70, 0xfd, 0xff, 0x11, 0x68, 0xf8, 0xff, 0x06, 0x61, 0xf7, 0xff, 0x02, 0x63, 0xf3, 0xff, 0x06, 0x68, 0xf2, 0xff, 0x0b, 0x64, 0xf4, 0xff, 0x07, 0x4e, 0xec, 0xff, 0x06, 0x3d, 0xdf, 0xff, 0x03, 0x2f, 0xc9, 0xff, 0x0b, 0x32, 0xcf, 0xff, 0x07, 0x4e, 0x83, 0xff, 0x05, 0x64, 0x48, 0xff, 0x0e, 0x67, 0x44, 0xff, 0x23, 0x67, 0x64, 0xff, 0x29, 0x60, 0x75, 0xff, 0x2b, 0x60, 0x77, 0xff, 0x2b, 0x64, 0x76, 0xff, 0x2b, 0x63, 0x74, 0xff, 0x22, 0x54, 0x6a, 0xff, 0x19, 0x46, 0x5c, 0xff, 0x18, 0x43, 0x52, 0xff, 0x0b, 0x3b, 0x46, 0xff, 0x0b, 0x39, 0x46, 0xff, 0x10, 0x3d, 0x41, 0xff, 0x0f, 0x56, 0x3c, 0xff, 0x02, 0x53, 0x2a, 0xff, 0x0b, 0x58, 0x33, 0xff, 0x07, 0x51, 0x31, 0xff, 0x09, 0x57, 0x36, 0xff, 0x07, 0x57, 0x32, 0xff, 0x06, 0x4f, 0x27, 0xff, 0x07, 0x4a, 0x28, 0xff, 0x65, 0x89, 0x7a, 0xff, + 0x03, 0x45, 0x8a, 0xff, 0x0c, 0x44, 0x97, 0xff, 0x18, 0x58, 0xb8, 0xff, 0x10, 0x62, 0xc2, 0xff, 0x0c, 0x65, 0xc9, 0xff, 0x0f, 0x71, 0xde, 0xff, 0x15, 0x78, 0xe7, 0xff, 0x10, 0x85, 0xf6, 0xff, 0x05, 0x89, 0xfa, 0xff, 0x14, 0x8c, 0xf7, 0xff, 0x2a, 0x9a, 0xf4, 0xff, 0x4c, 0xaf, 0xe8, 0xff, 0x15, 0x49, 0x72, 0xff, 0x17, 0x3b, 0x67, 0xff, 0x29, 0x55, 0x8f, 0xff, 0x05, 0x0f, 0x68, 0xff, 0x08, 0x2b, 0x8e, 0xff, 0x35, 0x92, 0xf0, 0xff, 0x34, 0x98, 0xf8, 0xff, 0x1c, 0x52, 0xa7, 0xff, 0x14, 0x3d, 0x8c, 0xff, 0x3b, 0xab, 0xf2, 0xff, 0x2c, 0xb6, 0xf4, 0xff, 0x45, 0xae, 0xf2, 0xff, 0x1b, 0x51, 0xa5, 0xff, 0x08, 0x3d, 0x89, 0xff, 0x2d, 0x9c, 0xd4, 0xff, 0x2c, 0xc8, 0xfb, 0xff, 0x0b, 0xc1, 0xf7, 0xff, 0x0d, 0xca, 0xfe, 0xff, 0x0d, 0xbe, 0xf9, 0xff, 0x1e, 0xb6, 0xf9, 0xff, 0x2c, 0xac, 0xec, 0xff, 0x0f, 0x72, 0xae, 0xff, 0x2d, 0x97, 0xca, 0xff, 0x2a, 0x9f, 0xa4, 0xff, 0x32, 0xa8, 0x91, 0xff, 0x2d, 0xa8, 0x90, 0xff, 0x28, 0xaa, 0x8b, 0xff, 0x29, 0xa8, 0x8f, 0xff, 0x2a, 0xa8, 0x8e, 0xff, 0x2a, 0xa9, 0x8f, 0xff, 0x2a, 0xaa, 0x8f, 0xff, 0x2b, 0xab, 0x8e, 0xff, 0x2a, 0xaa, 0x8d, 0xff, 0x29, 0xa9, 0x8c, 0xff, 0x29, 0xaa, 0x8b, 0xff, 0x29, 0xa8, 0x8a, 0xff, 0x26, 0xa9, 0x89, 0xff, 0x20, 0xa8, 0x85, 0xff, 0x1c, 0xa7, 0x81, 0xff, 0x17, 0xa6, 0x7c, 0xff, 0x13, 0xa6, 0x78, 0xff, 0x0f, 0xa4, 0x75, 0xff, 0x0f, 0xa3, 0x74, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0b, 0xa1, 0x6a, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x74, 0xff, 0x0e, 0xa3, 0x75, 0xff, 0x0e, 0xa3, 0x75, 0xff, 0x0e, 0xa3, 0x76, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa4, 0x75, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x0b, 0xa0, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x03, 0x9f, 0x69, 0xff, 0x05, 0x9f, 0x68, 0xff, 0x10, 0xa8, 0x6e, 0xff, 0x14, 0xac, 0x70, 0xff, 0x13, 0xad, 0x6e, 0xff, 0x09, 0xa8, 0x67, 0xff, 0x17, 0xb9, 0x78, 0xff, 0x0b, 0xac, 0x6b, 0xff, 0x09, 0xa9, 0x68, 0xff, 0x15, 0xbc, 0x79, 0xff, 0x0a, 0xb1, 0x6f, 0xff, 0x17, 0xbc, 0x77, 0xff, 0x0d, 0xac, 0x69, 0xff, 0x0a, 0xa7, 0x65, 0xff, 0x14, 0xb0, 0x71, 0xff, 0x0e, 0xaa, 0x6f, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x07, 0xa3, 0x6e, 0xff, 0x0a, 0xa4, 0x72, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x0d, 0xa4, 0x79, 0xff, 0x0d, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x76, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x06, 0xa9, 0x71, 0xff, 0x06, 0xaa, 0x71, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x09, 0xab, 0x71, 0xff, 0x0c, 0xab, 0x71, 0xff, 0x0c, 0xac, 0x72, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x09, 0xab, 0x73, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x0c, 0xac, 0x72, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x0a, 0xaa, 0x73, 0xff, 0x0c, 0xaa, 0x75, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x13, 0xa9, 0x78, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x0f, 0xa9, 0x7a, 0xff, 0x0f, 0xa8, 0x7a, 0xff, 0x11, 0xa7, 0x7a, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x10, 0xa9, 0x79, 0xff, 0x12, 0xa8, 0x77, 0xff, 0x10, 0xa2, 0x71, 0xff, 0x07, 0x97, 0x65, 0xff, 0x02, 0x8b, 0x5b, 0xff, 0x09, 0x93, 0x64, 0xff, 0x0b, 0x96, 0x67, 0xff, 0x0b, 0x97, 0x67, 0xff, 0x0e, 0x9c, 0x6b, 0xff, 0x10, 0xa0, 0x6f, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x12, 0xa5, 0x71, 0xff, 0x0b, 0x9d, 0x6b, 0xff, 0x03, 0x90, 0x5f, 0xff, 0x05, 0x8f, 0x5e, 0xff, 0x0b, 0x97, 0x66, 0xff, 0x0a, 0x97, 0x65, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0d, 0xa7, 0x6a, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x0e, 0xa3, 0x67, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x0e, 0xa3, 0x65, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x09, 0xa5, 0x65, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x09, 0xa2, 0x68, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0b, 0xa1, 0x67, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x0f, 0xa2, 0x6a, 0xff, 0x11, 0xa3, 0x6c, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x0a, 0xaa, 0x71, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0c, 0xa6, 0x68, 0xff, 0x0c, 0xa5, 0x63, 0xff, 0x0c, 0xa4, 0x60, 0xff, 0x0b, 0xa2, 0x5d, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0c, 0xa2, 0x5e, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0d, 0xa3, 0x59, 0xff, 0x14, 0x9f, 0x60, 0xff, 0x0d, 0x78, 0x82, 0xff, 0x04, 0x40, 0xa2, 0xff, 0x0a, 0x33, 0xc7, 0xff, 0x03, 0x30, 0xcd, 0xff, 0x04, 0x3a, 0xd8, 0xff, 0x03, 0x42, 0xdf, 0xff, 0x01, 0x4a, 0xea, 0xff, 0x04, 0x53, 0xef, 0xff, 0x0b, 0x66, 0xf1, 0xff, 0x09, 0x65, 0xf2, 0xff, 0x06, 0x64, 0xf2, 0xff, 0x02, 0x64, 0xef, 0xff, 0x01, 0x63, 0xf2, 0xff, 0x06, 0x60, 0xf8, 0xff, 0x08, 0x51, 0xf3, 0xff, 0x08, 0x41, 0xea, 0xff, 0x04, 0x2f, 0xda, 0xff, 0x0c, 0x33, 0xd6, 0xff, 0x05, 0x50, 0x7e, 0xff, 0x07, 0x68, 0x49, 0xff, 0x0f, 0x66, 0x46, 0xff, 0x23, 0x66, 0x67, 0xff, 0x2a, 0x60, 0x75, 0xff, 0x2c, 0x61, 0x77, 0xff, 0x2a, 0x64, 0x75, 0xff, 0x2d, 0x64, 0x77, 0xff, 0x1b, 0x4d, 0x64, 0xff, 0x17, 0x44, 0x59, 0xff, 0x19, 0x44, 0x53, 0xff, 0x0b, 0x3b, 0x46, 0xff, 0x0c, 0x39, 0x46, 0xff, 0x12, 0x3e, 0x43, 0xff, 0x10, 0x57, 0x3d, 0xff, 0x02, 0x55, 0x2a, 0xff, 0x0a, 0x58, 0x30, 0xff, 0x07, 0x51, 0x30, 0xff, 0x09, 0x56, 0x37, 0xff, 0x09, 0x58, 0x32, 0xff, 0x06, 0x50, 0x26, 0xff, 0x04, 0x49, 0x23, 0xff, 0x63, 0x86, 0x73, 0xff, + 0x04, 0x46, 0x86, 0xff, 0x03, 0x3b, 0x8a, 0xff, 0x07, 0x40, 0x95, 0xff, 0x16, 0x65, 0xbd, 0xff, 0x09, 0x62, 0xc7, 0xff, 0x11, 0x70, 0xe5, 0xff, 0x13, 0x75, 0xe8, 0xff, 0x14, 0x85, 0xf9, 0xff, 0x0c, 0x88, 0xfb, 0xff, 0x10, 0x8a, 0xfa, 0xff, 0x1e, 0x8b, 0xf2, 0xff, 0x30, 0x9e, 0xee, 0xff, 0x40, 0xa0, 0xe1, 0xff, 0x0e, 0x3a, 0x71, 0xff, 0x04, 0x17, 0x5b, 0xff, 0x08, 0x19, 0x7b, 0xff, 0x24, 0x67, 0xca, 0xff, 0x33, 0xa3, 0xfd, 0xff, 0x36, 0x88, 0xeb, 0xff, 0x07, 0x18, 0x74, 0xff, 0x03, 0x0d, 0x61, 0xff, 0x24, 0x6d, 0xba, 0xff, 0x37, 0xb2, 0xf0, 0xff, 0x35, 0xbe, 0xf8, 0xff, 0x38, 0xb2, 0xf2, 0xff, 0x28, 0xaa, 0xea, 0xff, 0x2b, 0xc3, 0xf8, 0xff, 0x1d, 0xbd, 0xf3, 0xff, 0x12, 0xc3, 0xfc, 0xff, 0x12, 0xc8, 0xff, 0xff, 0x1c, 0xbb, 0xf6, 0xff, 0x30, 0xac, 0xed, 0xff, 0x20, 0x87, 0xc9, 0xff, 0x1f, 0x81, 0xc3, 0xff, 0x31, 0x9d, 0xd1, 0xff, 0x29, 0xa2, 0xa3, 0xff, 0x30, 0xa9, 0x8f, 0xff, 0x31, 0xa9, 0x8f, 0xff, 0x2c, 0xaa, 0x8c, 0xff, 0x27, 0xa8, 0x8f, 0xff, 0x29, 0xa9, 0x8f, 0xff, 0x29, 0xa8, 0x8e, 0xff, 0x2a, 0xa8, 0x8d, 0xff, 0x29, 0xa8, 0x8b, 0xff, 0x29, 0xa8, 0x8a, 0xff, 0x29, 0xa8, 0x8a, 0xff, 0x28, 0xaa, 0x89, 0xff, 0x26, 0xa8, 0x86, 0xff, 0x23, 0xaa, 0x84, 0xff, 0x1b, 0xa8, 0x80, 0xff, 0x14, 0xa6, 0x7b, 0xff, 0x0f, 0xa4, 0x75, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0b, 0xa3, 0x70, 0xff, 0x0a, 0xa1, 0x6d, 0xff, 0x08, 0xa1, 0x6b, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x07, 0xa0, 0x64, 0xff, 0x07, 0x9f, 0x61, 0xff, 0x09, 0x9c, 0x61, 0xff, 0x0d, 0x9d, 0x62, 0xff, 0x0f, 0x9e, 0x64, 0xff, 0x0d, 0x9c, 0x65, 0xff, 0x0d, 0x9d, 0x65, 0xff, 0x0e, 0x9f, 0x67, 0xff, 0x0e, 0xa1, 0x68, 0xff, 0x0e, 0xa2, 0x69, 0xff, 0x0e, 0xa3, 0x6a, 0xff, 0x0e, 0xa3, 0x6a, 0xff, 0x0f, 0xa4, 0x6b, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0b, 0xa4, 0x73, 0xff, 0x0a, 0xa4, 0x74, 0xff, 0x09, 0xa4, 0x75, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa3, 0x74, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0f, 0xa4, 0x75, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x0e, 0xa2, 0x76, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x11, 0xaf, 0x76, 0xff, 0x07, 0xa7, 0x6c, 0xff, 0x02, 0xa3, 0x67, 0xff, 0x05, 0xa1, 0x67, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x18, 0xb3, 0x76, 0xff, 0x10, 0xac, 0x6d, 0xff, 0x12, 0xb3, 0x72, 0xff, 0x14, 0xb9, 0x79, 0xff, 0x0b, 0xb0, 0x70, 0xff, 0x02, 0xa4, 0x65, 0xff, 0x0f, 0xb5, 0x73, 0xff, 0x0a, 0xb0, 0x6c, 0xff, 0x0e, 0xb0, 0x6c, 0xff, 0x11, 0xb0, 0x6b, 0xff, 0x0a, 0xa8, 0x64, 0xff, 0x14, 0xb0, 0x70, 0xff, 0x08, 0xa5, 0x67, 0xff, 0x0f, 0xab, 0x71, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x70, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0d, 0xa6, 0x76, 0xff, 0x10, 0xa5, 0x76, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0c, 0xaa, 0x71, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x70, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x07, 0xaa, 0x71, 0xff, 0x04, 0xaa, 0x71, 0xff, 0x05, 0xaa, 0x70, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x09, 0xab, 0x71, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x09, 0xab, 0x72, 0xff, 0x08, 0xaa, 0x73, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x0c, 0xab, 0x72, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0a, 0xaa, 0x72, 0xff, 0x09, 0xa9, 0x72, 0xff, 0x0a, 0xa9, 0x75, 0xff, 0x0e, 0xab, 0x79, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x11, 0xa7, 0x78, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x12, 0xa8, 0x7c, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0e, 0xa7, 0x78, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x12, 0xa6, 0x75, 0xff, 0x13, 0xa4, 0x74, 0xff, 0x12, 0xa3, 0x73, 0xff, 0x15, 0xa5, 0x77, 0xff, 0x14, 0xa6, 0x77, 0xff, 0x15, 0xa8, 0x78, 0xff, 0x12, 0xa6, 0x76, 0xff, 0x14, 0xa9, 0x77, 0xff, 0x11, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x10, 0xa5, 0x74, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x13, 0xa4, 0x74, 0xff, 0x13, 0xa5, 0x75, 0xff, 0x16, 0xa7, 0x75, 0xff, 0x12, 0xa5, 0x72, 0xff, 0x10, 0xa3, 0x70, 0xff, 0x0f, 0xa4, 0x71, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x11, 0xa8, 0x73, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0d, 0xa5, 0x6d, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0d, 0xa5, 0x6b, 0xff, 0x0f, 0xa5, 0x68, 0xff, 0x0f, 0xa5, 0x67, 0xff, 0x0e, 0xa3, 0x66, 0xff, 0x0d, 0xa2, 0x66, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x09, 0xa3, 0x65, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x07, 0xa4, 0x68, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0d, 0xa0, 0x68, 0xff, 0x08, 0x9a, 0x60, 0xff, 0x03, 0x95, 0x5a, 0xff, 0x05, 0x96, 0x5b, 0xff, 0x08, 0x97, 0x5c, 0xff, 0x07, 0x95, 0x5d, 0xff, 0x08, 0x94, 0x5f, 0xff, 0x09, 0x95, 0x60, 0xff, 0x0b, 0x97, 0x60, 0xff, 0x0c, 0x97, 0x60, 0xff, 0x0d, 0x9a, 0x62, 0xff, 0x0e, 0x9d, 0x65, 0xff, 0x0e, 0x9f, 0x67, 0xff, 0x10, 0xa2, 0x6a, 0xff, 0x10, 0xa3, 0x6b, 0xff, 0x0f, 0xa4, 0x6b, 0xff, 0x0f, 0xa6, 0x6c, 0xff, 0x0e, 0xa6, 0x6c, 0xff, 0x0d, 0xa7, 0x6d, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0c, 0xa6, 0x67, 0xff, 0x0d, 0xa5, 0x64, 0xff, 0x0e, 0xa5, 0x61, 0xff, 0x0c, 0xa2, 0x5d, 0xff, 0x0b, 0xa0, 0x5d, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0c, 0xa0, 0x5f, 0xff, 0x0c, 0xa1, 0x5c, 0xff, 0x0c, 0xa2, 0x5b, 0xff, 0x0b, 0xa4, 0x5a, 0xff, 0x0d, 0xa3, 0x5f, 0xff, 0x11, 0x9d, 0x66, 0xff, 0x15, 0x8e, 0x78, 0xff, 0x02, 0x4a, 0x97, 0xff, 0x02, 0x2d, 0xbc, 0xff, 0x06, 0x2e, 0xcf, 0xff, 0x08, 0x38, 0xd7, 0xff, 0x0d, 0x47, 0xe7, 0xff, 0x02, 0x44, 0xe6, 0xff, 0x00, 0x4a, 0xeb, 0xff, 0x00, 0x54, 0xeb, 0xff, 0x03, 0x64, 0xec, 0xff, 0x05, 0x68, 0xed, 0xff, 0x04, 0x66, 0xf1, 0xff, 0x01, 0x63, 0xf2, 0xff, 0x02, 0x61, 0xf8, 0xff, 0x05, 0x5e, 0xf8, 0xff, 0x08, 0x52, 0xf2, 0xff, 0x08, 0x45, 0xeb, 0xff, 0x01, 0x2c, 0xd9, 0xff, 0x04, 0x35, 0xc0, 0xff, 0x03, 0x54, 0x6b, 0xff, 0x0a, 0x6c, 0x47, 0xff, 0x10, 0x67, 0x4d, 0xff, 0x24, 0x67, 0x6b, 0xff, 0x29, 0x5f, 0x74, 0xff, 0x2b, 0x61, 0x76, 0xff, 0x2e, 0x67, 0x7c, 0xff, 0x2c, 0x62, 0x77, 0xff, 0x15, 0x46, 0x5e, 0xff, 0x17, 0x45, 0x5b, 0xff, 0x18, 0x43, 0x51, 0xff, 0x0a, 0x3c, 0x46, 0xff, 0x0c, 0x3a, 0x47, 0xff, 0x13, 0x3f, 0x43, 0xff, 0x12, 0x57, 0x3d, 0xff, 0x05, 0x57, 0x2a, 0xff, 0x0a, 0x59, 0x2b, 0xff, 0x07, 0x53, 0x2c, 0xff, 0x0a, 0x56, 0x33, 0xff, 0x0b, 0x59, 0x31, 0xff, 0x0a, 0x51, 0x29, 0xff, 0x05, 0x45, 0x22, 0xff, 0x65, 0x82, 0x72, 0xff, + 0x03, 0x43, 0x83, 0xff, 0x0d, 0x4a, 0x96, 0xff, 0x04, 0x34, 0x84, 0xff, 0x21, 0x62, 0xb3, 0xff, 0x13, 0x62, 0xc4, 0xff, 0x13, 0x74, 0xe4, 0xff, 0x14, 0x78, 0xe6, 0xff, 0x1b, 0x85, 0xf8, 0xff, 0x19, 0x87, 0xfc, 0xff, 0x1a, 0x88, 0xf9, 0xff, 0x20, 0x84, 0xf2, 0xff, 0x26, 0x8a, 0xf0, 0xff, 0x2c, 0x96, 0xf1, 0xff, 0x39, 0x97, 0xde, 0xff, 0x25, 0x6b, 0xaf, 0xff, 0x1b, 0x59, 0xac, 0xff, 0x3f, 0xa5, 0xf7, 0xff, 0x31, 0xa2, 0xfb, 0xff, 0x29, 0x60, 0xc5, 0xff, 0x06, 0x14, 0x72, 0xff, 0x07, 0x22, 0x79, 0xff, 0x07, 0x26, 0x7c, 0xff, 0x2d, 0x8d, 0xd2, 0xff, 0x1f, 0xbe, 0xf7, 0xff, 0x19, 0xc4, 0xfe, 0xff, 0x1a, 0xb9, 0xfb, 0xff, 0x1b, 0xb5, 0xf4, 0xff, 0x19, 0xb9, 0xf4, 0xff, 0x0f, 0xc0, 0xf8, 0xff, 0x1e, 0xcc, 0xfd, 0xff, 0x28, 0xa4, 0xdc, 0xff, 0x0a, 0x57, 0x97, 0xff, 0x04, 0x50, 0x94, 0xff, 0x33, 0x9e, 0xe4, 0xff, 0x2b, 0x9b, 0xcf, 0xff, 0x26, 0xa2, 0xa0, 0xff, 0x2a, 0xab, 0x8e, 0xff, 0x2e, 0xa9, 0x8e, 0xff, 0x2e, 0xa9, 0x8c, 0xff, 0x25, 0xa9, 0x8f, 0xff, 0x27, 0xa8, 0x8f, 0xff, 0x29, 0xa7, 0x8d, 0xff, 0x2a, 0xa7, 0x8c, 0xff, 0x2a, 0xa8, 0x8a, 0xff, 0x2a, 0xa9, 0x8a, 0xff, 0x28, 0xaa, 0x89, 0xff, 0x26, 0xaa, 0x88, 0xff, 0x21, 0xa9, 0x81, 0xff, 0x1d, 0xa9, 0x7e, 0xff, 0x14, 0xa7, 0x7a, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0a, 0x9f, 0x68, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x08, 0x9f, 0x65, 0xff, 0x03, 0x99, 0x5d, 0xff, 0x01, 0x94, 0x57, 0xff, 0x01, 0x92, 0x54, 0xff, 0x02, 0x8f, 0x52, 0xff, 0x05, 0x8c, 0x51, 0xff, 0x06, 0x8b, 0x51, 0xff, 0x05, 0x8a, 0x52, 0xff, 0x05, 0x8c, 0x53, 0xff, 0x05, 0x8c, 0x53, 0xff, 0x05, 0x8d, 0x55, 0xff, 0x07, 0x92, 0x59, 0xff, 0x09, 0x96, 0x5c, 0xff, 0x0b, 0x99, 0x5e, 0xff, 0x0d, 0x9c, 0x61, 0xff, 0x0b, 0x9c, 0x63, 0xff, 0x0d, 0x9e, 0x66, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0a, 0xa6, 0x73, 0xff, 0x0a, 0xa6, 0x74, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0e, 0xa4, 0x73, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x10, 0xa3, 0x74, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x13, 0xae, 0x78, 0xff, 0x14, 0xb1, 0x78, 0xff, 0x03, 0xa4, 0x67, 0xff, 0x01, 0xa4, 0x64, 0xff, 0x04, 0xa3, 0x64, 0xff, 0x05, 0xa1, 0x64, 0xff, 0x0e, 0xa9, 0x6a, 0xff, 0x0e, 0xaa, 0x6b, 0xff, 0x14, 0xb7, 0x76, 0xff, 0x0e, 0xb4, 0x75, 0xff, 0x10, 0xb6, 0x77, 0xff, 0x05, 0xa8, 0x6b, 0xff, 0x0a, 0xae, 0x6c, 0xff, 0x10, 0xb5, 0x71, 0xff, 0x05, 0xa7, 0x62, 0xff, 0x0d, 0xac, 0x67, 0xff, 0x12, 0xaf, 0x6c, 0xff, 0x08, 0xa4, 0x63, 0xff, 0x0c, 0xa7, 0x6a, 0xff, 0x10, 0xab, 0x71, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0a, 0xaa, 0x70, 0xff, 0x0b, 0xaa, 0x6f, 0xff, 0x0d, 0xa9, 0x6e, 0xff, 0x0d, 0xa9, 0x6e, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x0d, 0xa9, 0x70, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0a, 0xa9, 0x73, 0xff, 0x0d, 0xab, 0x77, 0xff, 0x0e, 0xab, 0x78, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x12, 0xa8, 0x79, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x12, 0xa8, 0x7c, 0xff, 0x13, 0xa8, 0x7b, 0xff, 0x13, 0xa9, 0x7c, 0xff, 0x11, 0xa9, 0x7c, 0xff, 0x0e, 0xa8, 0x7a, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x13, 0xaa, 0x7a, 0xff, 0x15, 0xaa, 0x7a, 0xff, 0x17, 0xab, 0x7d, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x13, 0xab, 0x7c, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x13, 0xaa, 0x7a, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x13, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x10, 0xa7, 0x73, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x10, 0xa5, 0x67, 0xff, 0x10, 0xa5, 0x67, 0xff, 0x0e, 0xa3, 0x66, 0xff, 0x0a, 0xa2, 0x66, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa6, 0x6a, 0xff, 0x08, 0xa6, 0x6d, 0xff, 0x09, 0xa5, 0x70, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x16, 0xa9, 0x75, 0xff, 0x19, 0xa8, 0x74, 0xff, 0x15, 0xa4, 0x70, 0xff, 0x11, 0xa3, 0x6d, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x08, 0x9d, 0x66, 0xff, 0x0e, 0x9b, 0x62, 0xff, 0x0b, 0x95, 0x5c, 0xff, 0x08, 0x92, 0x58, 0xff, 0x0a, 0x92, 0x57, 0xff, 0x07, 0x8d, 0x54, 0xff, 0x02, 0x85, 0x4e, 0xff, 0x02, 0x84, 0x4e, 0xff, 0x05, 0x85, 0x52, 0xff, 0x02, 0x80, 0x4a, 0xff, 0x01, 0x7f, 0x49, 0xff, 0x04, 0x86, 0x4f, 0xff, 0x03, 0x88, 0x50, 0xff, 0x06, 0x89, 0x53, 0xff, 0x08, 0x8e, 0x57, 0xff, 0x07, 0x8f, 0x58, 0xff, 0x08, 0x91, 0x58, 0xff, 0x0b, 0x99, 0x5f, 0xff, 0x0e, 0x9f, 0x65, 0xff, 0x0f, 0xa3, 0x69, 0xff, 0x0e, 0xa6, 0x6d, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0c, 0xa5, 0x66, 0xff, 0x0d, 0xa5, 0x63, 0xff, 0x0d, 0xa4, 0x60, 0xff, 0x0c, 0xa2, 0x5d, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0c, 0xa0, 0x5f, 0xff, 0x0b, 0x9f, 0x62, 0xff, 0x0b, 0xa2, 0x59, 0xff, 0x0b, 0xa4, 0x58, 0xff, 0x0a, 0xa4, 0x58, 0xff, 0x0c, 0xa4, 0x58, 0xff, 0x0e, 0x8e, 0x73, 0xff, 0x07, 0x65, 0x91, 0xff, 0x03, 0x36, 0xba, 0xff, 0x05, 0x30, 0xd4, 0xff, 0x0a, 0x39, 0xe0, 0xff, 0x0d, 0x43, 0xe9, 0xff, 0x0f, 0x4d, 0xf4, 0xff, 0x04, 0x4a, 0xee, 0xff, 0x01, 0x4f, 0xec, 0xff, 0x02, 0x58, 0xed, 0xff, 0x04, 0x62, 0xf0, 0xff, 0x03, 0x68, 0xec, 0xff, 0x02, 0x64, 0xf2, 0xff, 0x00, 0x5f, 0xf7, 0xff, 0x02, 0x62, 0xf7, 0xff, 0x06, 0x62, 0xf3, 0xff, 0x07, 0x53, 0xef, 0xff, 0x06, 0x44, 0xe8, 0xff, 0x06, 0x3b, 0xd6, 0xff, 0x05, 0x43, 0xa7, 0xff, 0x07, 0x61, 0x5c, 0xff, 0x0d, 0x70, 0x45, 0xff, 0x12, 0x65, 0x53, 0xff, 0x23, 0x63, 0x6f, 0xff, 0x2a, 0x60, 0x76, 0xff, 0x2c, 0x62, 0x77, 0xff, 0x2f, 0x69, 0x7f, 0xff, 0x1b, 0x50, 0x68, 0xff, 0x15, 0x46, 0x5d, 0xff, 0x1a, 0x46, 0x5b, 0xff, 0x13, 0x3f, 0x4b, 0xff, 0x0a, 0x3c, 0x44, 0xff, 0x0e, 0x3c, 0x47, 0xff, 0x12, 0x3d, 0x40, 0xff, 0x10, 0x54, 0x3a, 0xff, 0x08, 0x59, 0x2e, 0xff, 0x0b, 0x59, 0x2d, 0xff, 0x07, 0x53, 0x29, 0xff, 0x09, 0x54, 0x2c, 0xff, 0x0c, 0x57, 0x2e, 0xff, 0x0c, 0x50, 0x2a, 0xff, 0x05, 0x41, 0x27, 0xff, 0x65, 0x81, 0x7c, 0xff, + 0x02, 0x44, 0x89, 0xff, 0x0e, 0x4f, 0x98, 0xff, 0x16, 0x48, 0x99, 0xff, 0x13, 0x3d, 0x8d, 0xff, 0x23, 0x62, 0xb9, 0xff, 0x1f, 0x77, 0xd7, 0xff, 0x1b, 0x7a, 0xd9, 0xff, 0x19, 0x80, 0xec, 0xff, 0x19, 0x85, 0xf8, 0xff, 0x2a, 0x84, 0xf9, 0xff, 0x28, 0x82, 0xf2, 0xff, 0x26, 0x84, 0xf4, 0xff, 0x23, 0x88, 0xf1, 0xff, 0x2a, 0x9b, 0xef, 0xff, 0x37, 0xaa, 0xee, 0xff, 0x3e, 0xaf, 0xf3, 0xff, 0x29, 0xa8, 0xf2, 0xff, 0x2a, 0x97, 0xe7, 0xff, 0x10, 0x38, 0x95, 0xff, 0x18, 0x4a, 0x9c, 0xff, 0x3a, 0x86, 0xcf, 0xff, 0x1d, 0x4d, 0x9c, 0xff, 0x20, 0x80, 0xbf, 0xff, 0x21, 0xcc, 0xf9, 0xff, 0x12, 0xc1, 0xf9, 0xff, 0x16, 0xab, 0xf5, 0xff, 0x21, 0xac, 0xf8, 0xff, 0x1b, 0xb5, 0xfa, 0xff, 0x13, 0xc1, 0xfa, 0xff, 0x1c, 0xaf, 0xe2, 0xff, 0x0d, 0x51, 0x8b, 0xff, 0x0c, 0x3e, 0x7e, 0xff, 0x20, 0x80, 0xc5, 0xff, 0x2c, 0xa3, 0xec, 0xff, 0x21, 0x95, 0xc7, 0xff, 0x27, 0xa2, 0x9c, 0xff, 0x25, 0xab, 0x8e, 0xff, 0x29, 0xaa, 0x8e, 0xff, 0x2d, 0xa8, 0x8c, 0xff, 0x27, 0xa8, 0x8e, 0xff, 0x28, 0xa8, 0x8e, 0xff, 0x29, 0xa8, 0x8c, 0xff, 0x29, 0xa8, 0x8a, 0xff, 0x28, 0xa9, 0x89, 0xff, 0x26, 0xaa, 0x88, 0xff, 0x20, 0xa8, 0x84, 0xff, 0x1c, 0xa8, 0x80, 0xff, 0x17, 0xa8, 0x79, 0xff, 0x12, 0xa6, 0x75, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0d, 0x9c, 0x65, 0xff, 0x0e, 0x98, 0x60, 0xff, 0x0f, 0x97, 0x5f, 0xff, 0x0f, 0x99, 0x61, 0xff, 0x09, 0x94, 0x5b, 0xff, 0x02, 0x8c, 0x51, 0xff, 0x01, 0x8b, 0x4f, 0xff, 0x01, 0x89, 0x4c, 0xff, 0x01, 0x84, 0x48, 0xff, 0x00, 0x7d, 0x42, 0xff, 0x00, 0x78, 0x40, 0xff, 0x01, 0x76, 0x42, 0xff, 0x00, 0x79, 0x43, 0xff, 0x00, 0x78, 0x42, 0xff, 0x00, 0x79, 0x42, 0xff, 0x01, 0x7d, 0x45, 0xff, 0x01, 0x80, 0x48, 0xff, 0x01, 0x83, 0x48, 0xff, 0x02, 0x85, 0x4a, 0xff, 0x03, 0x87, 0x4e, 0xff, 0x03, 0x89, 0x4f, 0xff, 0x05, 0x8e, 0x56, 0xff, 0x08, 0x94, 0x5d, 0xff, 0x0b, 0x9b, 0x65, 0xff, 0x0e, 0xa0, 0x6b, 0xff, 0x10, 0xa5, 0x70, 0xff, 0x0f, 0xa6, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa6, 0x74, 0xff, 0x0b, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0f, 0xa4, 0x74, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x0e, 0xa2, 0x77, 0xff, 0x0e, 0xa2, 0x77, 0xff, 0x0f, 0xa3, 0x78, 0xff, 0x0e, 0xa4, 0x78, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x0f, 0xaa, 0x75, 0xff, 0x05, 0xa3, 0x67, 0xff, 0x01, 0xa1, 0x62, 0xff, 0x05, 0xa4, 0x63, 0xff, 0x03, 0x9e, 0x5f, 0xff, 0x09, 0xa3, 0x63, 0xff, 0x0d, 0xa8, 0x67, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x06, 0xa8, 0x68, 0xff, 0x13, 0xb5, 0x77, 0xff, 0x0d, 0xac, 0x70, 0xff, 0x08, 0xa8, 0x66, 0xff, 0x14, 0xb6, 0x72, 0xff, 0x07, 0xa6, 0x63, 0xff, 0x10, 0xad, 0x6b, 0xff, 0x0e, 0xaa, 0x6a, 0xff, 0x0a, 0xa6, 0x66, 0xff, 0x0f, 0xaa, 0x6e, 0xff, 0x0f, 0xa9, 0x70, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x11, 0xa5, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x13, 0xa3, 0x7a, 0xff, 0x10, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7a, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x08, 0xaa, 0x6e, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0a, 0xa0, 0x66, 0xff, 0x08, 0x9d, 0x63, 0xff, 0x09, 0x9c, 0x62, 0xff, 0x08, 0x9a, 0x60, 0xff, 0x0a, 0x99, 0x60, 0xff, 0x0d, 0x9a, 0x63, 0xff, 0x0a, 0x9a, 0x62, 0xff, 0x0a, 0x9c, 0x62, 0xff, 0x0a, 0x9e, 0x64, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x0f, 0xa9, 0x76, 0xff, 0x0f, 0xa8, 0x78, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x0e, 0xa8, 0x77, 0xff, 0x0e, 0xa8, 0x77, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x7a, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x15, 0xaa, 0x7e, 0xff, 0x15, 0xaa, 0x7e, 0xff, 0x14, 0xa9, 0x7e, 0xff, 0x14, 0xa9, 0x7e, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xaa, 0x7d, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x13, 0xab, 0x7e, 0xff, 0x12, 0xaa, 0x7d, 0xff, 0x11, 0xa9, 0x7d, 0xff, 0x11, 0xaa, 0x7c, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x11, 0xa9, 0x7b, 0xff, 0x11, 0xaa, 0x7b, 0xff, 0x10, 0xaa, 0x7a, 0xff, 0x12, 0xaa, 0x7a, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x11, 0xa8, 0x76, 0xff, 0x12, 0xa8, 0x76, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x11, 0xa5, 0x6c, 0xff, 0x0f, 0xa5, 0x6b, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x10, 0xab, 0x75, 0xff, 0x12, 0xab, 0x79, 0xff, 0x1a, 0xac, 0x7a, 0xff, 0x1d, 0xa8, 0x77, 0xff, 0x1b, 0x9e, 0x6e, 0xff, 0x16, 0x96, 0x65, 0xff, 0x0a, 0x8a, 0x58, 0xff, 0x08, 0x8a, 0x58, 0xff, 0x07, 0x8c, 0x58, 0xff, 0x08, 0x88, 0x52, 0xff, 0x08, 0x86, 0x4f, 0xff, 0x09, 0x87, 0x4f, 0xff, 0x06, 0x82, 0x4a, 0xff, 0x02, 0x7d, 0x46, 0xff, 0x02, 0x78, 0x43, 0xff, 0x02, 0x78, 0x45, 0xff, 0x02, 0x75, 0x45, 0xff, 0x01, 0x74, 0x41, 0xff, 0x00, 0x73, 0x41, 0xff, 0x03, 0x77, 0x45, 0xff, 0x04, 0x7a, 0x48, 0xff, 0x01, 0x78, 0x45, 0xff, 0x01, 0x79, 0x46, 0xff, 0x01, 0x78, 0x45, 0xff, 0x02, 0x7b, 0x47, 0xff, 0x01, 0x80, 0x4b, 0xff, 0x04, 0x88, 0x53, 0xff, 0x06, 0x8e, 0x59, 0xff, 0x0d, 0x99, 0x65, 0xff, 0x11, 0xa2, 0x6d, 0xff, 0x13, 0xa9, 0x75, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x0c, 0xa8, 0x74, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x08, 0xa9, 0x70, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x08, 0xaa, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0d, 0xa4, 0x65, 0xff, 0x0e, 0xa5, 0x65, 0xff, 0x0e, 0xa4, 0x62, 0xff, 0x0c, 0xa3, 0x5e, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0e, 0xa0, 0x5f, 0xff, 0x0b, 0x9f, 0x5f, 0xff, 0x0b, 0xa3, 0x59, 0xff, 0x0b, 0xa3, 0x59, 0xff, 0x0a, 0xa1, 0x5d, 0xff, 0x0c, 0xa4, 0x59, 0xff, 0x06, 0x80, 0x6f, 0xff, 0x02, 0x4d, 0xa0, 0xff, 0x0b, 0x34, 0xd0, 0xff, 0x0e, 0x40, 0xe1, 0xff, 0x09, 0x44, 0xe8, 0xff, 0x0c, 0x4a, 0xf0, 0xff, 0x09, 0x4f, 0xef, 0xff, 0x05, 0x53, 0xec, 0xff, 0x04, 0x57, 0xef, 0xff, 0x07, 0x5c, 0xf4, 0xff, 0x08, 0x5f, 0xf7, 0xff, 0x03, 0x66, 0xf0, 0xff, 0x00, 0x64, 0xf4, 0xff, 0x00, 0x61, 0xf8, 0xff, 0x04, 0x65, 0xee, 0xff, 0x06, 0x5f, 0xea, 0xff, 0x0a, 0x4f, 0xf0, 0xff, 0x05, 0x3f, 0xdf, 0xff, 0x04, 0x41, 0xb4, 0xff, 0x05, 0x50, 0x83, 0xff, 0x0b, 0x6d, 0x4f, 0xff, 0x0f, 0x73, 0x42, 0xff, 0x13, 0x63, 0x57, 0xff, 0x24, 0x61, 0x73, 0xff, 0x2a, 0x5f, 0x74, 0xff, 0x2a, 0x60, 0x73, 0xff, 0x1c, 0x54, 0x6c, 0xff, 0x11, 0x45, 0x5e, 0xff, 0x16, 0x46, 0x5d, 0xff, 0x18, 0x43, 0x58, 0xff, 0x10, 0x3c, 0x47, 0xff, 0x0a, 0x3c, 0x44, 0xff, 0x0e, 0x3b, 0x47, 0xff, 0x0f, 0x39, 0x3d, 0xff, 0x0e, 0x51, 0x38, 0xff, 0x0a, 0x59, 0x34, 0xff, 0x0a, 0x56, 0x33, 0xff, 0x08, 0x51, 0x2d, 0xff, 0x09, 0x54, 0x2c, 0xff, 0x0c, 0x56, 0x2c, 0xff, 0x09, 0x4c, 0x27, 0xff, 0x04, 0x3f, 0x26, 0xff, 0x68, 0x80, 0x80, 0xff, + 0x01, 0x43, 0x8a, 0xff, 0x0c, 0x4d, 0x94, 0xff, 0x23, 0x57, 0xac, 0xff, 0x06, 0x24, 0x72, 0xff, 0x14, 0x3d, 0x8a, 0xff, 0x25, 0x68, 0xba, 0xff, 0x1c, 0x63, 0xb4, 0xff, 0x19, 0x72, 0xd1, 0xff, 0x1e, 0x89, 0xf6, 0xff, 0x28, 0x86, 0xfb, 0xff, 0x26, 0x81, 0xf3, 0xff, 0x26, 0x80, 0xf3, 0xff, 0x29, 0x86, 0xf4, 0xff, 0x22, 0x8f, 0xe9, 0xff, 0x28, 0x9b, 0xe9, 0xff, 0x31, 0xaa, 0xf8, 0xff, 0x1d, 0xa6, 0xf1, 0xff, 0x1f, 0x9c, 0xe1, 0xff, 0x0d, 0x53, 0x9c, 0xff, 0x28, 0x8b, 0xc6, 0xff, 0x4f, 0xc7, 0xfb, 0xff, 0x4d, 0xa2, 0xe0, 0xff, 0x46, 0xb7, 0xe5, 0xff, 0x2d, 0xd8, 0xf7, 0xff, 0x15, 0xc2, 0xf2, 0xff, 0x16, 0xaa, 0xf4, 0xff, 0x1d, 0xaa, 0xfd, 0xff, 0x19, 0xb2, 0xfd, 0xff, 0x1c, 0xbf, 0xfd, 0xff, 0x15, 0x73, 0xaf, 0xff, 0x01, 0x1a, 0x5a, 0xff, 0x26, 0x6e, 0xaf, 0xff, 0x3c, 0xad, 0xf3, 0xff, 0x1f, 0x9c, 0xe4, 0xff, 0x20, 0x95, 0xc1, 0xff, 0x29, 0xa2, 0x9a, 0xff, 0x27, 0xaa, 0x8f, 0xff, 0x27, 0xa9, 0x8e, 0xff, 0x2a, 0xa7, 0x8c, 0xff, 0x27, 0xa7, 0x8b, 0xff, 0x29, 0xa8, 0x8b, 0xff, 0x29, 0xa9, 0x8b, 0xff, 0x28, 0xa9, 0x89, 0xff, 0x25, 0xab, 0x85, 0xff, 0x20, 0xaa, 0x83, 0xff, 0x18, 0xa8, 0x7e, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0c, 0x96, 0x60, 0xff, 0x06, 0x89, 0x54, 0xff, 0x05, 0x7f, 0x49, 0xff, 0x06, 0x7f, 0x49, 0xff, 0x09, 0x83, 0x4e, 0xff, 0x09, 0x86, 0x4f, 0xff, 0x08, 0x85, 0x4e, 0xff, 0x04, 0x82, 0x49, 0xff, 0x05, 0x83, 0x4b, 0xff, 0x04, 0x80, 0x47, 0xff, 0x02, 0x79, 0x42, 0xff, 0x02, 0x76, 0x40, 0xff, 0x05, 0x73, 0x41, 0xff, 0x02, 0x70, 0x3e, 0xff, 0x01, 0x6f, 0x3d, 0xff, 0x01, 0x70, 0x3c, 0xff, 0x00, 0x72, 0x3d, 0xff, 0x01, 0x74, 0x3f, 0xff, 0x00, 0x75, 0x3e, 0xff, 0x00, 0x74, 0x3c, 0xff, 0x00, 0x75, 0x3c, 0xff, 0x00, 0x77, 0x3e, 0xff, 0x00, 0x7c, 0x43, 0xff, 0x01, 0x81, 0x49, 0xff, 0x02, 0x86, 0x4f, 0xff, 0x04, 0x8c, 0x56, 0xff, 0x0b, 0x98, 0x62, 0xff, 0x13, 0xa3, 0x6d, 0xff, 0x12, 0xa7, 0x71, 0xff, 0x11, 0xa7, 0x73, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0b, 0xa7, 0x73, 0xff, 0x09, 0xa5, 0x72, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x11, 0xa1, 0x79, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x10, 0xa2, 0x7b, 0xff, 0x0e, 0xa2, 0x78, 0xff, 0x0c, 0xa3, 0x73, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x04, 0xa0, 0x65, 0xff, 0x08, 0xa4, 0x65, 0xff, 0x07, 0xa0, 0x5f, 0xff, 0x09, 0x9f, 0x5f, 0xff, 0x0e, 0xa5, 0x64, 0xff, 0x05, 0x9e, 0x5e, 0xff, 0x06, 0xa3, 0x63, 0xff, 0x10, 0xaf, 0x71, 0xff, 0x0f, 0xac, 0x70, 0xff, 0x0b, 0xa8, 0x69, 0xff, 0x12, 0xb0, 0x6e, 0xff, 0x0c, 0xa9, 0x69, 0xff, 0x14, 0xb0, 0x70, 0xff, 0x0f, 0xa9, 0x6a, 0xff, 0x10, 0xab, 0x6e, 0xff, 0x13, 0xad, 0x73, 0xff, 0x13, 0xad, 0x75, 0xff, 0x10, 0xa6, 0x74, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x09, 0xa9, 0x6d, 0xff, 0x0b, 0xa8, 0x6c, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0e, 0xa0, 0x67, 0xff, 0x0f, 0x9f, 0x65, 0xff, 0x0c, 0x9b, 0x62, 0xff, 0x05, 0x93, 0x58, 0xff, 0x03, 0x90, 0x55, 0xff, 0x02, 0x8e, 0x53, 0xff, 0x02, 0x8b, 0x51, 0xff, 0x04, 0x8a, 0x51, 0xff, 0x05, 0x88, 0x50, 0xff, 0x03, 0x87, 0x4f, 0xff, 0x03, 0x8c, 0x52, 0xff, 0x03, 0x8a, 0x51, 0xff, 0x03, 0x8b, 0x53, 0xff, 0x07, 0x96, 0x5d, 0xff, 0x0c, 0x9c, 0x65, 0xff, 0x0d, 0xa0, 0x69, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6e, 0xff, 0x0c, 0xa3, 0x73, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x10, 0xab, 0x7a, 0xff, 0x0e, 0xaa, 0x79, 0xff, 0x0e, 0xab, 0x79, 0xff, 0x0f, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x14, 0xab, 0x7c, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x16, 0xab, 0x80, 0xff, 0x16, 0xaa, 0x7f, 0xff, 0x15, 0xa9, 0x7f, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x12, 0xa9, 0x7e, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x12, 0xaa, 0x7e, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x13, 0xac, 0x7f, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x12, 0xa9, 0x7d, 0xff, 0x14, 0xa9, 0x7e, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x12, 0xaa, 0x7b, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xaa, 0x7b, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x13, 0xa8, 0x77, 0xff, 0x13, 0xa8, 0x78, 0xff, 0x14, 0xa8, 0x78, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x10, 0xa6, 0x72, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x0f, 0xa6, 0x6f, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x0d, 0xa5, 0x6b, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x07, 0xa4, 0x6f, 0xff, 0x0c, 0xa9, 0x74, 0xff, 0x13, 0xaf, 0x7a, 0xff, 0x15, 0xaf, 0x7a, 0xff, 0x15, 0xac, 0x79, 0xff, 0x16, 0xaa, 0x78, 0xff, 0x17, 0xa2, 0x71, 0xff, 0x13, 0x93, 0x64, 0xff, 0x0a, 0x7f, 0x51, 0xff, 0x06, 0x75, 0x46, 0xff, 0x01, 0x6b, 0x3b, 0xff, 0x01, 0x6e, 0x3e, 0xff, 0x03, 0x75, 0x44, 0xff, 0x04, 0x78, 0x45, 0xff, 0x04, 0x76, 0x43, 0xff, 0x05, 0x77, 0x42, 0xff, 0x06, 0x75, 0x41, 0xff, 0x07, 0x75, 0x43, 0xff, 0x09, 0x74, 0x43, 0xff, 0x08, 0x71, 0x42, 0xff, 0x04, 0x6b, 0x3e, 0xff, 0x03, 0x6a, 0x3a, 0xff, 0x03, 0x69, 0x3a, 0xff, 0x03, 0x6b, 0x3b, 0xff, 0x04, 0x6d, 0x3d, 0xff, 0x02, 0x6c, 0x3d, 0xff, 0x01, 0x6c, 0x3c, 0xff, 0x01, 0x6d, 0x3d, 0xff, 0x06, 0x73, 0x43, 0xff, 0x03, 0x77, 0x46, 0xff, 0x07, 0x7f, 0x4e, 0xff, 0x0b, 0x86, 0x56, 0xff, 0x10, 0x90, 0x61, 0xff, 0x10, 0x97, 0x67, 0xff, 0x17, 0xa3, 0x74, 0xff, 0x19, 0xaa, 0x7b, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x09, 0xa9, 0x70, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x06, 0xa8, 0x6d, 0xff, 0x07, 0xa8, 0x6d, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa4, 0x67, 0xff, 0x0d, 0xa3, 0x63, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x0e, 0xa4, 0x61, 0xff, 0x0d, 0xa3, 0x5f, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0c, 0xa1, 0x5c, 0xff, 0x0c, 0xa3, 0x59, 0xff, 0x0c, 0xa2, 0x5b, 0xff, 0x0a, 0x9e, 0x62, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0a, 0x88, 0x6d, 0xff, 0x02, 0x4f, 0x8f, 0xff, 0x0f, 0x38, 0xcb, 0xff, 0x12, 0x46, 0xe6, 0xff, 0x07, 0x44, 0xea, 0xff, 0x0b, 0x4b, 0xf2, 0xff, 0x08, 0x54, 0xeb, 0xff, 0x08, 0x5b, 0xe8, 0xff, 0x06, 0x5c, 0xf0, 0xff, 0x07, 0x5d, 0xf5, 0xff, 0x07, 0x62, 0xf3, 0xff, 0x03, 0x66, 0xf1, 0xff, 0x01, 0x64, 0xf4, 0xff, 0x02, 0x62, 0xf4, 0xff, 0x08, 0x66, 0xeb, 0xff, 0x07, 0x59, 0xe7, 0xff, 0x0a, 0x47, 0xed, 0xff, 0x0b, 0x43, 0xd6, 0xff, 0x01, 0x43, 0x8a, 0xff, 0x04, 0x5c, 0x64, 0xff, 0x0c, 0x74, 0x46, 0xff, 0x0f, 0x75, 0x40, 0xff, 0x14, 0x62, 0x59, 0xff, 0x24, 0x60, 0x75, 0xff, 0x29, 0x5e, 0x73, 0xff, 0x22, 0x57, 0x68, 0xff, 0x12, 0x48, 0x60, 0xff, 0x12, 0x44, 0x5d, 0xff, 0x16, 0x46, 0x5c, 0xff, 0x17, 0x42, 0x57, 0xff, 0x0f, 0x3b, 0x46, 0xff, 0x0c, 0x3e, 0x45, 0xff, 0x0f, 0x3b, 0x46, 0xff, 0x0c, 0x35, 0x39, 0xff, 0x0c, 0x4c, 0x34, 0xff, 0x0c, 0x58, 0x38, 0xff, 0x09, 0x53, 0x36, 0xff, 0x09, 0x50, 0x31, 0xff, 0x08, 0x50, 0x2b, 0xff, 0x0b, 0x53, 0x2b, 0xff, 0x07, 0x48, 0x23, 0xff, 0x05, 0x40, 0x22, 0xff, 0x65, 0x84, 0x75, 0xff, + 0x02, 0x4a, 0x8e, 0xff, 0x05, 0x45, 0x8b, 0xff, 0x18, 0x55, 0xac, 0xff, 0x0c, 0x39, 0x89, 0xff, 0x00, 0x0a, 0x4f, 0xff, 0x02, 0x11, 0x57, 0xff, 0x03, 0x17, 0x56, 0xff, 0x07, 0x2b, 0x70, 0xff, 0x27, 0x71, 0xc8, 0xff, 0x2c, 0x8f, 0xf7, 0xff, 0x22, 0x81, 0xf3, 0xff, 0x28, 0x7c, 0xf4, 0xff, 0x2c, 0x84, 0xf8, 0xff, 0x24, 0x89, 0xef, 0xff, 0x26, 0x8d, 0xef, 0xff, 0x1f, 0x91, 0xf6, 0xff, 0x19, 0xa5, 0xf7, 0xff, 0x29, 0xc5, 0xf8, 0xff, 0x34, 0xcf, 0xf7, 0xff, 0x3f, 0xd9, 0xf7, 0xff, 0x4d, 0xdd, 0xfc, 0xff, 0x43, 0xb8, 0xeb, 0xff, 0x66, 0xde, 0xfc, 0xff, 0x45, 0xd9, 0xf5, 0xff, 0x1a, 0xc8, 0xf2, 0xff, 0x0f, 0xaa, 0xf2, 0xff, 0x18, 0xa8, 0xfc, 0xff, 0x25, 0xb3, 0xfe, 0xff, 0x34, 0xb0, 0xef, 0xff, 0x06, 0x2a, 0x66, 0xff, 0x08, 0x35, 0x74, 0xff, 0x36, 0xad, 0xec, 0xff, 0x35, 0xb2, 0xf6, 0xff, 0x1d, 0x94, 0xd6, 0xff, 0x26, 0x99, 0xb9, 0xff, 0x2c, 0xa3, 0x95, 0xff, 0x2e, 0xa8, 0x90, 0xff, 0x29, 0xa7, 0x8e, 0xff, 0x28, 0xa7, 0x8b, 0xff, 0x29, 0xa6, 0x87, 0xff, 0x28, 0xa7, 0x86, 0xff, 0x25, 0xa9, 0x85, 0xff, 0x21, 0xaa, 0x84, 0xff, 0x1b, 0xa9, 0x7f, 0xff, 0x13, 0xa5, 0x77, 0xff, 0x0c, 0xa3, 0x73, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0a, 0x9b, 0x64, 0xff, 0x07, 0x92, 0x5d, 0xff, 0x05, 0x87, 0x52, 0xff, 0x01, 0x75, 0x43, 0xff, 0x00, 0x6a, 0x39, 0xff, 0x01, 0x61, 0x30, 0xff, 0x01, 0x60, 0x31, 0xff, 0x00, 0x62, 0x33, 0xff, 0x01, 0x67, 0x37, 0xff, 0x04, 0x6d, 0x3b, 0xff, 0x03, 0x6d, 0x3a, 0xff, 0x03, 0x6c, 0x39, 0xff, 0x03, 0x6c, 0x3a, 0xff, 0x03, 0x6d, 0x3b, 0xff, 0x05, 0x6d, 0x3d, 0xff, 0x0d, 0x6c, 0x3f, 0xff, 0x09, 0x68, 0x3b, 0xff, 0x03, 0x63, 0x36, 0xff, 0x04, 0x65, 0x38, 0xff, 0x02, 0x64, 0x35, 0xff, 0x02, 0x65, 0x37, 0xff, 0x02, 0x66, 0x36, 0xff, 0x02, 0x66, 0x35, 0xff, 0x01, 0x66, 0x32, 0xff, 0x02, 0x67, 0x33, 0xff, 0x00, 0x68, 0x34, 0xff, 0x00, 0x6a, 0x36, 0xff, 0x00, 0x6e, 0x39, 0xff, 0x00, 0x73, 0x3d, 0xff, 0x01, 0x79, 0x43, 0xff, 0x07, 0x85, 0x4f, 0xff, 0x0a, 0x92, 0x5e, 0xff, 0x10, 0x9c, 0x68, 0xff, 0x12, 0xa5, 0x70, 0xff, 0x0f, 0xa7, 0x71, 0xff, 0x0d, 0xa9, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0e, 0xa3, 0x78, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x13, 0xa1, 0x7a, 0xff, 0x14, 0xa1, 0x7b, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x12, 0xa1, 0x7e, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x0e, 0xa3, 0x74, 0xff, 0x0e, 0xa4, 0x71, 0xff, 0x06, 0xa1, 0x65, 0xff, 0x0b, 0xa1, 0x64, 0xff, 0x08, 0x9b, 0x5d, 0xff, 0x09, 0x9a, 0x5d, 0xff, 0x07, 0x9c, 0x5f, 0xff, 0x06, 0x9e, 0x61, 0xff, 0x08, 0xa1, 0x66, 0xff, 0x06, 0x9e, 0x65, 0xff, 0x05, 0x9e, 0x63, 0xff, 0x06, 0x9f, 0x63, 0xff, 0x15, 0xae, 0x72, 0xff, 0x0e, 0xa6, 0x6c, 0xff, 0x06, 0x9d, 0x65, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x12, 0xa4, 0x79, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x10, 0xa3, 0x7a, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x0e, 0xa2, 0x67, 0xff, 0x09, 0x97, 0x5e, 0xff, 0x0a, 0x92, 0x5b, 0xff, 0x0e, 0x92, 0x5d, 0xff, 0x10, 0x94, 0x5d, 0xff, 0x08, 0x8c, 0x55, 0xff, 0x04, 0x88, 0x50, 0xff, 0x04, 0x89, 0x4f, 0xff, 0x03, 0x86, 0x4c, 0xff, 0x01, 0x80, 0x47, 0xff, 0x00, 0x77, 0x3f, 0xff, 0x01, 0x73, 0x3d, 0xff, 0x01, 0x74, 0x3d, 0xff, 0x00, 0x76, 0x3f, 0xff, 0x00, 0x73, 0x3d, 0xff, 0x00, 0x74, 0x3e, 0xff, 0x02, 0x7d, 0x47, 0xff, 0x0b, 0x88, 0x54, 0xff, 0x0c, 0x8c, 0x58, 0xff, 0x0f, 0x90, 0x5b, 0xff, 0x10, 0x96, 0x65, 0xff, 0x10, 0x9a, 0x6c, 0xff, 0x15, 0xa2, 0x73, 0xff, 0x18, 0xa7, 0x78, 0xff, 0x19, 0xad, 0x7c, 0xff, 0x1a, 0xb0, 0x80, 0xff, 0x1a, 0xb3, 0x82, 0xff, 0x19, 0xb4, 0x83, 0xff, 0x19, 0xb2, 0x81, 0xff, 0x18, 0xb0, 0x7f, 0xff, 0x17, 0xaf, 0x80, 0xff, 0x18, 0xb0, 0x82, 0xff, 0x19, 0xb1, 0x84, 0xff, 0x17, 0xaf, 0x83, 0xff, 0x16, 0xad, 0x83, 0xff, 0x17, 0xac, 0x83, 0xff, 0x16, 0xab, 0x82, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x14, 0xaa, 0x81, 0xff, 0x14, 0xaa, 0x81, 0xff, 0x14, 0xab, 0x80, 0xff, 0x13, 0xaa, 0x7f, 0xff, 0x13, 0xaa, 0x7f, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x13, 0xaa, 0x7f, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x15, 0xa9, 0x81, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x16, 0xab, 0x82, 0xff, 0x17, 0xac, 0x82, 0xff, 0x16, 0xab, 0x80, 0xff, 0x14, 0xaa, 0x7d, 0xff, 0x13, 0xa9, 0x7c, 0xff, 0x14, 0xa9, 0x7d, 0xff, 0x14, 0xa9, 0x7c, 0xff, 0x14, 0xaa, 0x7b, 0xff, 0x15, 0xa9, 0x7a, 0xff, 0x15, 0xa7, 0x79, 0xff, 0x14, 0xa8, 0x77, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa6, 0x74, 0xff, 0x12, 0xa8, 0x74, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x11, 0xa4, 0x75, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x15, 0xb1, 0x7f, 0xff, 0x1a, 0xb6, 0x84, 0xff, 0x1a, 0xb0, 0x7e, 0xff, 0x13, 0xa3, 0x72, 0xff, 0x0d, 0x97, 0x66, 0xff, 0x05, 0x88, 0x56, 0xff, 0x01, 0x73, 0x44, 0xff, 0x01, 0x67, 0x3a, 0xff, 0x01, 0x60, 0x33, 0xff, 0x01, 0x5b, 0x2f, 0xff, 0x02, 0x59, 0x2c, 0xff, 0x02, 0x5a, 0x2d, 0xff, 0x00, 0x5b, 0x2e, 0xff, 0x00, 0x5f, 0x31, 0xff, 0x00, 0x60, 0x32, 0xff, 0x01, 0x5f, 0x32, 0xff, 0x01, 0x5e, 0x30, 0xff, 0x01, 0x5d, 0x30, 0xff, 0x03, 0x5c, 0x31, 0xff, 0x04, 0x5c, 0x32, 0xff, 0x04, 0x5c, 0x32, 0xff, 0x04, 0x5a, 0x2f, 0xff, 0x03, 0x59, 0x2f, 0xff, 0x04, 0x5a, 0x31, 0xff, 0x03, 0x5b, 0x31, 0xff, 0x03, 0x5c, 0x31, 0xff, 0x01, 0x5b, 0x31, 0xff, 0x02, 0x5c, 0x32, 0xff, 0x06, 0x61, 0x38, 0xff, 0x03, 0x63, 0x3a, 0xff, 0x0a, 0x6e, 0x45, 0xff, 0x12, 0x79, 0x50, 0xff, 0x14, 0x82, 0x5a, 0xff, 0x11, 0x85, 0x5c, 0xff, 0x12, 0x8b, 0x64, 0xff, 0x16, 0x95, 0x6d, 0xff, 0x14, 0x98, 0x6f, 0xff, 0x0b, 0x9d, 0x6c, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa9, 0x70, 0xff, 0x08, 0xa6, 0x6b, 0xff, 0x08, 0xa7, 0x6b, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0c, 0xa4, 0x64, 0xff, 0x0c, 0xa2, 0x60, 0xff, 0x0c, 0xa2, 0x5f, 0xff, 0x0d, 0xa3, 0x5f, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0d, 0xa2, 0x5a, 0xff, 0x0d, 0xa2, 0x5c, 0xff, 0x0b, 0x9f, 0x60, 0xff, 0x0d, 0xa1, 0x60, 0xff, 0x11, 0x9a, 0x67, 0xff, 0x12, 0x81, 0x7c, 0xff, 0x05, 0x4a, 0x96, 0xff, 0x03, 0x37, 0xab, 0xff, 0x0d, 0x47, 0xdd, 0xff, 0x0c, 0x47, 0xed, 0xff, 0x0d, 0x52, 0xed, 0xff, 0x0b, 0x5a, 0xea, 0xff, 0x07, 0x5b, 0xf1, 0xff, 0x09, 0x5f, 0xf6, 0xff, 0x08, 0x66, 0xef, 0xff, 0x08, 0x65, 0xf1, 0xff, 0x09, 0x61, 0xf6, 0xff, 0x0b, 0x60, 0xf4, 0xff, 0x0b, 0x59, 0xe8, 0xff, 0x10, 0x56, 0xe5, 0xff, 0x04, 0x3f, 0xc3, 0xff, 0x03, 0x44, 0x9b, 0xff, 0x09, 0x61, 0x66, 0xff, 0x09, 0x70, 0x4a, 0xff, 0x0b, 0x77, 0x3d, 0xff, 0x0e, 0x74, 0x3d, 0xff, 0x18, 0x63, 0x5c, 0xff, 0x25, 0x5f, 0x76, 0xff, 0x2c, 0x5e, 0x71, 0xff, 0x1c, 0x4e, 0x5d, 0xff, 0x13, 0x46, 0x5a, 0xff, 0x14, 0x46, 0x5c, 0xff, 0x15, 0x46, 0x5a, 0xff, 0x12, 0x3f, 0x51, 0xff, 0x0f, 0x3b, 0x44, 0xff, 0x0d, 0x3f, 0x45, 0xff, 0x0f, 0x3b, 0x46, 0xff, 0x0c, 0x33, 0x38, 0xff, 0x08, 0x45, 0x2f, 0xff, 0x0b, 0x5a, 0x33, 0xff, 0x06, 0x57, 0x2d, 0xff, 0x08, 0x53, 0x2b, 0xff, 0x07, 0x4e, 0x29, 0xff, 0x0a, 0x4f, 0x2c, 0xff, 0x06, 0x43, 0x24, 0xff, 0x06, 0x41, 0x23, 0xff, 0x65, 0x87, 0x6f, 0xff, + 0x05, 0x4a, 0x87, 0xff, 0x04, 0x43, 0x8a, 0xff, 0x0c, 0x51, 0xa5, 0xff, 0x15, 0x54, 0xa8, 0xff, 0x09, 0x2b, 0x75, 0xff, 0x05, 0x14, 0x5c, 0xff, 0x03, 0x0e, 0x4c, 0xff, 0x01, 0x0f, 0x44, 0xff, 0x0c, 0x2b, 0x70, 0xff, 0x2e, 0x78, 0xd3, 0xff, 0x30, 0x83, 0xee, 0xff, 0x2a, 0x7d, 0xf3, 0xff, 0x2d, 0x81, 0xf8, 0xff, 0x2a, 0x8a, 0xf7, 0xff, 0x23, 0x8d, 0xf6, 0xff, 0x1f, 0x96, 0xfc, 0xff, 0x18, 0xa4, 0xf6, 0xff, 0x2c, 0xc9, 0xf8, 0xff, 0x36, 0xdc, 0xfe, 0xff, 0x46, 0xe1, 0xfd, 0xff, 0x4b, 0xd3, 0xf9, 0xff, 0x2c, 0xad, 0xe8, 0xff, 0x42, 0xc3, 0xf5, 0xff, 0x38, 0xc7, 0xf0, 0xff, 0x1a, 0xc7, 0xf5, 0xff, 0x1a, 0xae, 0xf3, 0xff, 0x2c, 0xa8, 0xf9, 0xff, 0x38, 0xaa, 0xef, 0xff, 0x21, 0x69, 0xa6, 0xff, 0x04, 0x27, 0x5d, 0xff, 0x1a, 0x73, 0xac, 0xff, 0x2a, 0xb8, 0xf9, 0xff, 0x29, 0xa8, 0xea, 0xff, 0x23, 0x94, 0xcd, 0xff, 0x28, 0x9d, 0xae, 0xff, 0x2c, 0xa6, 0x8f, 0xff, 0x30, 0xa6, 0x8e, 0xff, 0x2b, 0xa7, 0x8b, 0xff, 0x26, 0xa7, 0x89, 0xff, 0x28, 0xa7, 0x84, 0xff, 0x25, 0xa8, 0x84, 0xff, 0x1e, 0xa8, 0x80, 0xff, 0x17, 0xa8, 0x7c, 0xff, 0x10, 0xa5, 0x75, 0xff, 0x0c, 0xa2, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0c, 0x9c, 0x62, 0xff, 0x09, 0x93, 0x5b, 0xff, 0x04, 0x81, 0x4e, 0xff, 0x01, 0x72, 0x3f, 0xff, 0x01, 0x65, 0x37, 0xff, 0x02, 0x5e, 0x32, 0xff, 0x02, 0x59, 0x2e, 0xff, 0x02, 0x57, 0x2d, 0xff, 0x01, 0x56, 0x2c, 0xff, 0x00, 0x56, 0x2c, 0xff, 0x02, 0x5b, 0x2f, 0xff, 0x02, 0x5d, 0x30, 0xff, 0x02, 0x5d, 0x30, 0xff, 0x01, 0x5b, 0x2e, 0xff, 0x00, 0x59, 0x2d, 0xff, 0x01, 0x58, 0x2d, 0xff, 0x03, 0x55, 0x2c, 0xff, 0x05, 0x58, 0x2f, 0xff, 0x04, 0x57, 0x2f, 0xff, 0x03, 0x56, 0x2e, 0xff, 0x01, 0x56, 0x2e, 0xff, 0x01, 0x56, 0x2e, 0xff, 0x02, 0x57, 0x2e, 0xff, 0x03, 0x58, 0x2e, 0xff, 0x03, 0x59, 0x2d, 0xff, 0x04, 0x5c, 0x2f, 0xff, 0x03, 0x5e, 0x30, 0xff, 0x02, 0x60, 0x31, 0xff, 0x00, 0x61, 0x31, 0xff, 0x00, 0x65, 0x34, 0xff, 0x00, 0x69, 0x36, 0xff, 0x01, 0x6e, 0x3d, 0xff, 0x01, 0x78, 0x46, 0xff, 0x06, 0x85, 0x52, 0xff, 0x0e, 0x98, 0x64, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0d, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x79, 0xff, 0x12, 0xa1, 0x79, 0xff, 0x14, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7d, 0xff, 0x13, 0xa2, 0x7d, 0xff, 0x12, 0xa2, 0x7c, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x03, 0x98, 0x5f, 0xff, 0x0a, 0x9b, 0x62, 0xff, 0x08, 0x97, 0x5e, 0xff, 0x09, 0x9b, 0x61, 0xff, 0x0f, 0xa2, 0x6a, 0xff, 0x05, 0x99, 0x63, 0xff, 0x04, 0x97, 0x62, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x07, 0x9d, 0x66, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0b, 0xa0, 0x6c, 0xff, 0x0a, 0x9f, 0x6d, 0xff, 0x0e, 0xa2, 0x71, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x12, 0xa6, 0x7a, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x12, 0xa4, 0x7b, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x10, 0xa3, 0x7a, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x0c, 0x9d, 0x66, 0xff, 0x0c, 0x97, 0x60, 0xff, 0x05, 0x87, 0x50, 0xff, 0x02, 0x79, 0x45, 0xff, 0x02, 0x73, 0x41, 0xff, 0x04, 0x75, 0x44, 0xff, 0x04, 0x79, 0x46, 0xff, 0x07, 0x7e, 0x4b, 0xff, 0x04, 0x7d, 0x48, 0xff, 0x02, 0x7b, 0x45, 0xff, 0x04, 0x7c, 0x47, 0xff, 0x03, 0x79, 0x44, 0xff, 0x04, 0x75, 0x42, 0xff, 0x04, 0x74, 0x42, 0xff, 0x05, 0x71, 0x3f, 0xff, 0x04, 0x6e, 0x3d, 0xff, 0x02, 0x6b, 0x3a, 0xff, 0x01, 0x6b, 0x3a, 0xff, 0x03, 0x6e, 0x3d, 0xff, 0x07, 0x74, 0x44, 0xff, 0x06, 0x75, 0x45, 0xff, 0x0b, 0x7c, 0x4c, 0xff, 0x12, 0x88, 0x5a, 0xff, 0x14, 0x8e, 0x62, 0xff, 0x18, 0x96, 0x6a, 0xff, 0x19, 0x9b, 0x6e, 0xff, 0x18, 0xa0, 0x72, 0xff, 0x1a, 0xa6, 0x77, 0xff, 0x1c, 0xae, 0x7e, 0xff, 0x1d, 0xb1, 0x81, 0xff, 0x1c, 0xb3, 0x82, 0xff, 0x1c, 0xb3, 0x83, 0xff, 0x1c, 0xb3, 0x85, 0xff, 0x1d, 0xb4, 0x87, 0xff, 0x1d, 0xb6, 0x8a, 0xff, 0x1c, 0xb5, 0x8a, 0xff, 0x1b, 0xb2, 0x89, 0xff, 0x1b, 0xb0, 0x89, 0xff, 0x18, 0xad, 0x85, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xaa, 0x82, 0xff, 0x14, 0xaa, 0x81, 0xff, 0x14, 0xaa, 0x80, 0xff, 0x14, 0xaa, 0x80, 0xff, 0x15, 0xab, 0x81, 0xff, 0x15, 0xab, 0x80, 0xff, 0x14, 0xaa, 0x80, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x15, 0xaa, 0x80, 0xff, 0x16, 0xab, 0x83, 0xff, 0x18, 0xac, 0x84, 0xff, 0x18, 0xac, 0x84, 0xff, 0x18, 0xac, 0x84, 0xff, 0x16, 0xaa, 0x82, 0xff, 0x16, 0xaa, 0x7f, 0xff, 0x14, 0xa9, 0x7e, 0xff, 0x14, 0xa9, 0x7e, 0xff, 0x13, 0xa9, 0x7c, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x15, 0xa9, 0x7b, 0xff, 0x16, 0xa7, 0x7a, 0xff, 0x16, 0xa7, 0x78, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x0e, 0xa4, 0x71, 0xff, 0x10, 0xa5, 0x74, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x13, 0xab, 0x7d, 0xff, 0x18, 0xb2, 0x83, 0xff, 0x1c, 0xb6, 0x85, 0xff, 0x1a, 0xb0, 0x7e, 0xff, 0x0f, 0x9c, 0x69, 0xff, 0x08, 0x8e, 0x5c, 0xff, 0x07, 0x83, 0x52, 0xff, 0x03, 0x74, 0x45, 0xff, 0x01, 0x66, 0x39, 0xff, 0x02, 0x5f, 0x34, 0xff, 0x02, 0x56, 0x2d, 0xff, 0x03, 0x51, 0x29, 0xff, 0x03, 0x4e, 0x25, 0xff, 0x03, 0x4e, 0x26, 0xff, 0x02, 0x4f, 0x26, 0xff, 0x01, 0x52, 0x2a, 0xff, 0x01, 0x53, 0x2b, 0xff, 0x02, 0x53, 0x2b, 0xff, 0x01, 0x52, 0x28, 0xff, 0x00, 0x4f, 0x27, 0xff, 0x00, 0x4c, 0x26, 0xff, 0x00, 0x4b, 0x25, 0xff, 0x00, 0x4b, 0x26, 0xff, 0x01, 0x4b, 0x26, 0xff, 0x01, 0x4a, 0x26, 0xff, 0x01, 0x4c, 0x27, 0xff, 0x01, 0x4c, 0x28, 0xff, 0x01, 0x4e, 0x28, 0xff, 0x00, 0x4d, 0x28, 0xff, 0x01, 0x4f, 0x2a, 0xff, 0x04, 0x53, 0x2e, 0xff, 0x01, 0x55, 0x30, 0xff, 0x02, 0x57, 0x33, 0xff, 0x05, 0x5d, 0x38, 0xff, 0x08, 0x69, 0x44, 0xff, 0x0c, 0x72, 0x4c, 0xff, 0x11, 0x7d, 0x57, 0xff, 0x17, 0x88, 0x62, 0xff, 0x19, 0x8f, 0x68, 0xff, 0x08, 0x90, 0x61, 0xff, 0x0b, 0x9b, 0x68, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x0d, 0xa6, 0x6b, 0xff, 0x0a, 0xa6, 0x69, 0xff, 0x0b, 0xa8, 0x6a, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0d, 0xa3, 0x6a, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0e, 0xa4, 0x64, 0xff, 0x0c, 0xa2, 0x5f, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5e, 0xff, 0x0c, 0x9f, 0x60, 0xff, 0x0d, 0xa2, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0c, 0xa0, 0x5b, 0xff, 0x10, 0x9f, 0x60, 0xff, 0x16, 0x97, 0x69, 0xff, 0x12, 0x79, 0x80, 0xff, 0x07, 0x56, 0x87, 0xff, 0x09, 0x50, 0xb2, 0xff, 0x04, 0x40, 0xc5, 0xff, 0x0d, 0x50, 0xdd, 0xff, 0x0c, 0x57, 0xe1, 0xff, 0x0c, 0x59, 0xec, 0xff, 0x10, 0x5f, 0xf5, 0xff, 0x0b, 0x5f, 0xea, 0xff, 0x16, 0x68, 0xf2, 0xff, 0x0d, 0x5a, 0xe9, 0xff, 0x15, 0x5e, 0xed, 0xff, 0x07, 0x4b, 0xd2, 0xff, 0x0b, 0x4e, 0xc1, 0xff, 0x03, 0x4b, 0x93, 0xff, 0x03, 0x55, 0x6d, 0xff, 0x0c, 0x70, 0x4e, 0xff, 0x09, 0x75, 0x3f, 0xff, 0x0b, 0x77, 0x3d, 0xff, 0x0f, 0x75, 0x3e, 0xff, 0x1a, 0x64, 0x5c, 0xff, 0x26, 0x5e, 0x75, 0xff, 0x2f, 0x5e, 0x71, 0xff, 0x1d, 0x4c, 0x59, 0xff, 0x17, 0x49, 0x5a, 0xff, 0x15, 0x46, 0x5a, 0xff, 0x16, 0x46, 0x5a, 0xff, 0x13, 0x40, 0x50, 0xff, 0x0f, 0x3c, 0x43, 0xff, 0x0b, 0x3e, 0x43, 0xff, 0x10, 0x3c, 0x47, 0xff, 0x11, 0x36, 0x3d, 0xff, 0x08, 0x43, 0x30, 0xff, 0x0a, 0x59, 0x32, 0xff, 0x05, 0x57, 0x2c, 0xff, 0x08, 0x55, 0x2b, 0xff, 0x07, 0x4e, 0x28, 0xff, 0x08, 0x4b, 0x2b, 0xff, 0x06, 0x41, 0x27, 0xff, 0x07, 0x40, 0x27, 0xff, 0x65, 0x88, 0x73, 0xff, + 0x0d, 0x49, 0x78, 0xff, 0x07, 0x42, 0x88, 0xff, 0x04, 0x4c, 0x9a, 0xff, 0x17, 0x5f, 0xb8, 0xff, 0x1e, 0x5b, 0xb1, 0xff, 0x22, 0x52, 0xa6, 0xff, 0x1e, 0x44, 0x92, 0xff, 0x09, 0x27, 0x62, 0xff, 0x00, 0x0e, 0x48, 0xff, 0x12, 0x28, 0x70, 0xff, 0x31, 0x66, 0xc0, 0xff, 0x34, 0x83, 0xed, 0xff, 0x34, 0x7b, 0xec, 0xff, 0x2a, 0x79, 0xe8, 0xff, 0x28, 0x93, 0xf9, 0xff, 0x1e, 0x9d, 0xfb, 0xff, 0x19, 0xa1, 0xf1, 0xff, 0x29, 0xb0, 0xec, 0xff, 0x2e, 0xb5, 0xef, 0xff, 0x2e, 0xaf, 0xe9, 0xff, 0x30, 0xa5, 0xe8, 0xff, 0x22, 0xa8, 0xf5, 0xff, 0x1b, 0xaf, 0xf3, 0xff, 0x2a, 0xbf, 0xf8, 0xff, 0x2e, 0xc7, 0xfc, 0xff, 0x34, 0xab, 0xee, 0xff, 0x3d, 0x8f, 0xda, 0xff, 0x1a, 0x50, 0x91, 0xff, 0x03, 0x13, 0x49, 0xff, 0x1a, 0x60, 0x90, 0xff, 0x2d, 0xb1, 0xe8, 0xff, 0x19, 0xa7, 0xec, 0xff, 0x1e, 0x98, 0xd7, 0xff, 0x28, 0x97, 0xc3, 0xff, 0x26, 0xa0, 0xa0, 0xff, 0x29, 0xa9, 0x88, 0xff, 0x2f, 0xa6, 0x8b, 0xff, 0x28, 0xa7, 0x88, 0xff, 0x22, 0xa8, 0x86, 0xff, 0x23, 0xa8, 0x81, 0xff, 0x1e, 0xa9, 0x7f, 0xff, 0x13, 0xa6, 0x79, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0f, 0xa3, 0x69, 0xff, 0x09, 0x97, 0x5e, 0xff, 0x06, 0x8a, 0x52, 0xff, 0x04, 0x7f, 0x49, 0xff, 0x01, 0x6d, 0x3d, 0xff, 0x04, 0x65, 0x37, 0xff, 0x05, 0x5a, 0x31, 0xff, 0x03, 0x51, 0x2c, 0xff, 0x01, 0x4d, 0x28, 0xff, 0x01, 0x4a, 0x27, 0xff, 0x02, 0x4a, 0x25, 0xff, 0x00, 0x49, 0x24, 0xff, 0x01, 0x4d, 0x26, 0xff, 0x04, 0x50, 0x28, 0xff, 0x03, 0x4f, 0x27, 0xff, 0x00, 0x4c, 0x24, 0xff, 0x00, 0x49, 0x24, 0xff, 0x00, 0x48, 0x24, 0xff, 0x00, 0x46, 0x22, 0xff, 0x00, 0x44, 0x20, 0xff, 0x00, 0x46, 0x24, 0xff, 0x00, 0x47, 0x24, 0xff, 0x00, 0x47, 0x25, 0xff, 0x00, 0x46, 0x25, 0xff, 0x00, 0x47, 0x25, 0xff, 0x01, 0x47, 0x26, 0xff, 0x02, 0x49, 0x26, 0xff, 0x03, 0x4d, 0x29, 0xff, 0x04, 0x51, 0x2a, 0xff, 0x03, 0x54, 0x2c, 0xff, 0x02, 0x56, 0x2d, 0xff, 0x02, 0x5a, 0x2f, 0xff, 0x02, 0x5f, 0x32, 0xff, 0x00, 0x5f, 0x32, 0xff, 0x01, 0x69, 0x39, 0xff, 0x02, 0x74, 0x42, 0xff, 0x07, 0x86, 0x52, 0xff, 0x08, 0x93, 0x5d, 0xff, 0x0e, 0xa1, 0x6d, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x7a, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x11, 0xa4, 0x7b, 0xff, 0x10, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0e, 0xa2, 0x7a, 0xff, 0x0c, 0xa4, 0x74, 0xff, 0x06, 0x9c, 0x6a, 0xff, 0x07, 0x97, 0x66, 0xff, 0x08, 0x96, 0x64, 0xff, 0x0e, 0x9d, 0x6a, 0xff, 0x0e, 0x9e, 0x6c, 0xff, 0x0d, 0x9d, 0x6e, 0xff, 0x0f, 0x9e, 0x6f, 0xff, 0x10, 0xa2, 0x70, 0xff, 0x0a, 0x9d, 0x6a, 0xff, 0x07, 0x9a, 0x69, 0xff, 0x0f, 0xa2, 0x73, 0xff, 0x13, 0xa6, 0x7a, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa4, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x10, 0xa2, 0x7c, 0xff, 0x0f, 0xa2, 0x7c, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7a, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0d, 0xa6, 0x76, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x0c, 0x9d, 0x67, 0xff, 0x0a, 0x95, 0x5f, 0xff, 0x05, 0x87, 0x52, 0xff, 0x03, 0x79, 0x45, 0xff, 0x00, 0x6b, 0x3a, 0xff, 0x00, 0x63, 0x34, 0xff, 0x00, 0x5d, 0x30, 0xff, 0x00, 0x5b, 0x30, 0xff, 0x00, 0x5c, 0x32, 0xff, 0x01, 0x60, 0x34, 0xff, 0x02, 0x66, 0x38, 0xff, 0x01, 0x67, 0x38, 0xff, 0x01, 0x66, 0x36, 0xff, 0x01, 0x65, 0x37, 0xff, 0x03, 0x64, 0x38, 0xff, 0x04, 0x64, 0x39, 0xff, 0x06, 0x63, 0x39, 0xff, 0x06, 0x61, 0x36, 0xff, 0x05, 0x5f, 0x34, 0xff, 0x05, 0x5e, 0x34, 0xff, 0x06, 0x5f, 0x35, 0xff, 0x04, 0x5f, 0x35, 0xff, 0x03, 0x5f, 0x35, 0xff, 0x04, 0x61, 0x38, 0xff, 0x06, 0x67, 0x3f, 0xff, 0x0a, 0x6f, 0x47, 0xff, 0x11, 0x7a, 0x51, 0xff, 0x10, 0x7f, 0x55, 0xff, 0x12, 0x89, 0x5e, 0xff, 0x19, 0x97, 0x6a, 0xff, 0x19, 0xa0, 0x71, 0xff, 0x1c, 0xa5, 0x76, 0xff, 0x19, 0xaa, 0x7a, 0xff, 0x19, 0xaf, 0x7f, 0xff, 0x1e, 0xb5, 0x87, 0xff, 0x20, 0xb7, 0x8a, 0xff, 0x1f, 0xb9, 0x8c, 0xff, 0x1d, 0xb8, 0x8d, 0xff, 0x1d, 0xb5, 0x8d, 0xff, 0x1c, 0xb3, 0x8c, 0xff, 0x1b, 0xb0, 0x89, 0xff, 0x1b, 0xb0, 0x88, 0xff, 0x19, 0xae, 0x86, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x82, 0xff, 0x16, 0xac, 0x81, 0xff, 0x16, 0xac, 0x81, 0xff, 0x16, 0xac, 0x81, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x86, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xaa, 0x81, 0xff, 0x16, 0xaa, 0x80, 0xff, 0x15, 0xaa, 0x7f, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x14, 0xa8, 0x7c, 0xff, 0x15, 0xa8, 0x7c, 0xff, 0x16, 0xa9, 0x7a, 0xff, 0x12, 0xa9, 0x77, 0xff, 0x12, 0xa9, 0x77, 0xff, 0x12, 0xa9, 0x77, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x14, 0xa9, 0x7a, 0xff, 0x1a, 0xad, 0x82, 0xff, 0x1d, 0xb3, 0x85, 0xff, 0x20, 0xb7, 0x88, 0xff, 0x1b, 0xb1, 0x7f, 0xff, 0x0c, 0x9b, 0x67, 0xff, 0x04, 0x86, 0x52, 0xff, 0x03, 0x7b, 0x47, 0xff, 0x01, 0x6b, 0x39, 0xff, 0x04, 0x5f, 0x35, 0xff, 0x01, 0x54, 0x2d, 0xff, 0x01, 0x50, 0x29, 0xff, 0x01, 0x49, 0x23, 0xff, 0x04, 0x49, 0x24, 0xff, 0x05, 0x46, 0x22, 0xff, 0x04, 0x45, 0x21, 0xff, 0x03, 0x45, 0x22, 0xff, 0x01, 0x45, 0x23, 0xff, 0x00, 0x46, 0x22, 0xff, 0x00, 0x45, 0x20, 0xff, 0x00, 0x42, 0x1e, 0xff, 0x00, 0x43, 0x1f, 0xff, 0x01, 0x43, 0x20, 0xff, 0x02, 0x43, 0x22, 0xff, 0x02, 0x42, 0x23, 0xff, 0x01, 0x41, 0x22, 0xff, 0x01, 0x40, 0x22, 0xff, 0x02, 0x42, 0x23, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x42, 0x23, 0xff, 0x00, 0x41, 0x23, 0xff, 0x01, 0x43, 0x24, 0xff, 0x02, 0x45, 0x26, 0xff, 0x01, 0x47, 0x26, 0xff, 0x03, 0x4c, 0x2b, 0xff, 0x04, 0x4f, 0x2e, 0xff, 0x03, 0x54, 0x31, 0xff, 0x01, 0x58, 0x34, 0xff, 0x05, 0x61, 0x3c, 0xff, 0x0d, 0x6e, 0x4a, 0xff, 0x1d, 0x86, 0x60, 0xff, 0x11, 0x8b, 0x60, 0xff, 0x05, 0x8a, 0x59, 0xff, 0x0c, 0x98, 0x63, 0xff, 0x13, 0xa6, 0x6b, 0xff, 0x0d, 0xa5, 0x67, 0xff, 0x0c, 0xa6, 0x67, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0c, 0xa2, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0e, 0xa3, 0x60, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0b, 0xa0, 0x5d, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5e, 0xff, 0x0b, 0x9f, 0x61, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0f, 0xa2, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0d, 0xa0, 0x5b, 0xff, 0x11, 0xa1, 0x5b, 0xff, 0x15, 0x9a, 0x65, 0xff, 0x1a, 0x90, 0x70, 0xff, 0x0c, 0x6f, 0x7c, 0xff, 0x02, 0x54, 0x8a, 0xff, 0x03, 0x4e, 0xa4, 0xff, 0x03, 0x49, 0xae, 0xff, 0x09, 0x4c, 0xc5, 0xff, 0x0f, 0x51, 0xd7, 0xff, 0x08, 0x48, 0xd0, 0xff, 0x18, 0x5b, 0xd9, 0xff, 0x0a, 0x4b, 0xc3, 0xff, 0x0c, 0x4d, 0xbe, 0xff, 0x03, 0x45, 0x9e, 0xff, 0x01, 0x4b, 0x7d, 0xff, 0x04, 0x62, 0x5f, 0xff, 0x09, 0x72, 0x4d, 0xff, 0x09, 0x78, 0x3e, 0xff, 0x09, 0x79, 0x3a, 0xff, 0x0c, 0x77, 0x3f, 0xff, 0x0f, 0x74, 0x40, 0xff, 0x15, 0x5f, 0x56, 0xff, 0x21, 0x56, 0x6c, 0xff, 0x2e, 0x5b, 0x6d, 0xff, 0x17, 0x43, 0x4f, 0xff, 0x16, 0x45, 0x51, 0xff, 0x19, 0x48, 0x58, 0xff, 0x18, 0x47, 0x59, 0xff, 0x12, 0x3f, 0x4d, 0xff, 0x10, 0x3e, 0x43, 0xff, 0x0b, 0x3e, 0x43, 0xff, 0x12, 0x3c, 0x48, 0xff, 0x15, 0x38, 0x41, 0xff, 0x06, 0x40, 0x2f, 0xff, 0x08, 0x51, 0x3b, 0xff, 0x06, 0x50, 0x3e, 0xff, 0x0a, 0x51, 0x38, 0xff, 0x05, 0x4b, 0x2a, 0xff, 0x08, 0x4b, 0x29, 0xff, 0x06, 0x42, 0x27, 0xff, 0x06, 0x40, 0x2a, 0xff, 0x65, 0x85, 0x79, 0xff, + 0x10, 0x42, 0x63, 0xff, 0x0d, 0x43, 0x88, 0xff, 0x05, 0x49, 0x8f, 0xff, 0x13, 0x5a, 0xb8, 0xff, 0x0f, 0x61, 0xc3, 0xff, 0x1b, 0x70, 0xd0, 0xff, 0x29, 0x71, 0xdc, 0xff, 0x2b, 0x71, 0xca, 0xff, 0x13, 0x4d, 0x8a, 0xff, 0x02, 0x0d, 0x47, 0xff, 0x06, 0x16, 0x5d, 0xff, 0x27, 0x51, 0xa8, 0xff, 0x46, 0x6e, 0xcd, 0xff, 0x1b, 0x49, 0xab, 0xff, 0x36, 0x7f, 0xdc, 0xff, 0x32, 0x97, 0xef, 0xff, 0x30, 0xa6, 0xf7, 0xff, 0x35, 0xa7, 0xf3, 0xff, 0x2e, 0x91, 0xe6, 0xff, 0x2e, 0x9c, 0xef, 0xff, 0x2e, 0x9c, 0xef, 0xff, 0x22, 0xa5, 0xf7, 0xff, 0x23, 0xb0, 0xf6, 0xff, 0x1f, 0x81, 0xc4, 0xff, 0x23, 0x72, 0xae, 0xff, 0x10, 0x54, 0x90, 0xff, 0x09, 0x2a, 0x6c, 0xff, 0x07, 0x2a, 0x60, 0xff, 0x0c, 0x5d, 0x88, 0xff, 0x32, 0xb4, 0xe4, 0xff, 0x22, 0xb8, 0xf6, 0xff, 0x21, 0x98, 0xe3, 0xff, 0x23, 0x93, 0xcf, 0xff, 0x25, 0x99, 0xb8, 0xff, 0x20, 0xa3, 0x95, 0xff, 0x24, 0xab, 0x83, 0xff, 0x27, 0xa9, 0x8a, 0xff, 0x21, 0xa9, 0x84, 0xff, 0x1d, 0xa9, 0x81, 0xff, 0x1d, 0xa8, 0x7d, 0xff, 0x14, 0xa5, 0x77, 0xff, 0x08, 0xa2, 0x71, 0xff, 0x04, 0xa3, 0x6d, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x0f, 0xa8, 0x6d, 0xff, 0x08, 0x97, 0x5b, 0xff, 0x01, 0x85, 0x4b, 0xff, 0x00, 0x75, 0x3f, 0xff, 0x00, 0x6a, 0x36, 0xff, 0x00, 0x5a, 0x2c, 0xff, 0x01, 0x53, 0x28, 0xff, 0x02, 0x4b, 0x26, 0xff, 0x02, 0x46, 0x24, 0xff, 0x02, 0x46, 0x26, 0xff, 0x01, 0x44, 0x25, 0xff, 0x02, 0x42, 0x23, 0xff, 0x02, 0x42, 0x22, 0xff, 0x01, 0x42, 0x20, 0xff, 0x01, 0x43, 0x20, 0xff, 0x01, 0x42, 0x1f, 0xff, 0x01, 0x41, 0x20, 0xff, 0x03, 0x40, 0x21, 0xff, 0x03, 0x41, 0x21, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x42, 0x22, 0xff, 0x02, 0x41, 0x23, 0xff, 0x01, 0x40, 0x22, 0xff, 0x02, 0x40, 0x23, 0xff, 0x02, 0x3f, 0x23, 0xff, 0x03, 0x3e, 0x23, 0xff, 0x02, 0x3e, 0x22, 0xff, 0x02, 0x40, 0x24, 0xff, 0x01, 0x42, 0x25, 0xff, 0x00, 0x45, 0x25, 0xff, 0x01, 0x48, 0x26, 0xff, 0x02, 0x4d, 0x2a, 0xff, 0x02, 0x51, 0x2b, 0xff, 0x01, 0x54, 0x2d, 0xff, 0x01, 0x54, 0x2c, 0xff, 0x01, 0x5b, 0x2d, 0xff, 0x01, 0x64, 0x35, 0xff, 0x02, 0x74, 0x42, 0xff, 0x01, 0x82, 0x4d, 0xff, 0x05, 0x92, 0x5e, 0xff, 0x0c, 0x9f, 0x6d, 0xff, 0x0f, 0xa4, 0x75, 0xff, 0x0e, 0xa3, 0x76, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x11, 0xa2, 0x7a, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x11, 0xa6, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa4, 0x7b, 0xff, 0x0d, 0xa2, 0x7b, 0xff, 0x0a, 0xa4, 0x7a, 0xff, 0x0c, 0xa3, 0x76, 0xff, 0x11, 0xa1, 0x75, 0xff, 0x13, 0xa1, 0x74, 0xff, 0x0f, 0x9e, 0x71, 0xff, 0x10, 0xa0, 0x73, 0xff, 0x17, 0xa6, 0x7b, 0xff, 0x17, 0xa4, 0x79, 0xff, 0x14, 0xa3, 0x75, 0xff, 0x12, 0xa1, 0x74, 0xff, 0x13, 0xa4, 0x77, 0xff, 0x14, 0xa4, 0x79, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x13, 0xa4, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa4, 0x7d, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7d, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x10, 0xa2, 0x7c, 0xff, 0x0f, 0xa2, 0x7c, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0e, 0xa4, 0x7a, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0c, 0xa5, 0x75, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x07, 0x99, 0x64, 0xff, 0x04, 0x8d, 0x58, 0xff, 0x05, 0x85, 0x50, 0xff, 0x00, 0x72, 0x3e, 0xff, 0x01, 0x66, 0x35, 0xff, 0x03, 0x5e, 0x31, 0xff, 0x03, 0x56, 0x2c, 0xff, 0x04, 0x51, 0x2a, 0xff, 0x03, 0x4f, 0x29, 0xff, 0x01, 0x4e, 0x29, 0xff, 0x02, 0x4e, 0x29, 0xff, 0x04, 0x53, 0x2c, 0xff, 0x04, 0x54, 0x2d, 0xff, 0x02, 0x54, 0x2a, 0xff, 0x01, 0x50, 0x28, 0xff, 0x01, 0x4d, 0x27, 0xff, 0x01, 0x4b, 0x27, 0xff, 0x00, 0x4b, 0x27, 0xff, 0x01, 0x4c, 0x28, 0xff, 0x01, 0x4a, 0x26, 0xff, 0x01, 0x4b, 0x27, 0xff, 0x02, 0x4d, 0x29, 0xff, 0x01, 0x4c, 0x28, 0xff, 0x01, 0x4e, 0x2b, 0xff, 0x00, 0x4d, 0x29, 0xff, 0x00, 0x50, 0x2b, 0xff, 0x01, 0x53, 0x2d, 0xff, 0x02, 0x59, 0x33, 0xff, 0x01, 0x5d, 0x35, 0xff, 0x02, 0x65, 0x3b, 0xff, 0x06, 0x74, 0x4a, 0xff, 0x0c, 0x85, 0x59, 0xff, 0x13, 0x8f, 0x63, 0xff, 0x12, 0x9b, 0x6d, 0xff, 0x11, 0xa4, 0x76, 0xff, 0x19, 0xaf, 0x81, 0xff, 0x1d, 0xb5, 0x88, 0xff, 0x20, 0xb9, 0x8d, 0xff, 0x20, 0xba, 0x8f, 0xff, 0x1f, 0xb9, 0x91, 0xff, 0x1e, 0xb7, 0x90, 0xff, 0x1e, 0xb5, 0x8e, 0xff, 0x20, 0xb6, 0x8e, 0xff, 0x1f, 0xb4, 0x8c, 0xff, 0x1c, 0xb1, 0x89, 0xff, 0x1b, 0xaf, 0x87, 0xff, 0x1a, 0xae, 0x86, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xab, 0x84, 0xff, 0x17, 0xab, 0x82, 0xff, 0x16, 0xac, 0x81, 0xff, 0x15, 0xab, 0x80, 0xff, 0x14, 0xab, 0x81, 0xff, 0x15, 0xac, 0x84, 0xff, 0x15, 0xac, 0x84, 0xff, 0x14, 0xad, 0x85, 0xff, 0x15, 0xad, 0x86, 0xff, 0x15, 0xab, 0x83, 0xff, 0x17, 0xaa, 0x80, 0xff, 0x17, 0xac, 0x81, 0xff, 0x15, 0xac, 0x81, 0xff, 0x11, 0xa9, 0x7d, 0xff, 0x11, 0xaa, 0x7c, 0xff, 0x13, 0xa9, 0x7c, 0xff, 0x15, 0xa9, 0x7d, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x14, 0xac, 0x7a, 0xff, 0x12, 0xab, 0x79, 0xff, 0x12, 0xaa, 0x78, 0xff, 0x13, 0xaa, 0x7a, 0xff, 0x14, 0xac, 0x7b, 0xff, 0x18, 0xaf, 0x81, 0xff, 0x19, 0xb0, 0x82, 0xff, 0x1d, 0xb3, 0x85, 0xff, 0x22, 0xb5, 0x8a, 0xff, 0x20, 0xb5, 0x88, 0xff, 0x1d, 0xb3, 0x82, 0xff, 0x10, 0xa2, 0x6f, 0xff, 0x02, 0x8a, 0x54, 0xff, 0x00, 0x76, 0x3f, 0xff, 0x00, 0x6b, 0x34, 0xff, 0x04, 0x60, 0x2e, 0xff, 0x08, 0x53, 0x2c, 0xff, 0x02, 0x47, 0x23, 0xff, 0x01, 0x43, 0x20, 0xff, 0x03, 0x43, 0x21, 0xff, 0x03, 0x42, 0x20, 0xff, 0x04, 0x3f, 0x21, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x00, 0x3b, 0x1e, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x03, 0x3f, 0x1f, 0xff, 0x02, 0x3e, 0x1e, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x01, 0x3c, 0x20, 0xff, 0x02, 0x3c, 0x21, 0xff, 0x02, 0x3d, 0x21, 0xff, 0x02, 0x3d, 0x21, 0xff, 0x02, 0x3d, 0x21, 0xff, 0x00, 0x3c, 0x21, 0xff, 0x01, 0x3e, 0x22, 0xff, 0x01, 0x3e, 0x21, 0xff, 0x02, 0x41, 0x20, 0xff, 0x02, 0x42, 0x20, 0xff, 0x03, 0x45, 0x22, 0xff, 0x05, 0x4c, 0x29, 0xff, 0x03, 0x4f, 0x2a, 0xff, 0x00, 0x50, 0x2b, 0xff, 0x01, 0x53, 0x2d, 0xff, 0x0d, 0x6b, 0x44, 0xff, 0x15, 0x84, 0x5b, 0xff, 0x05, 0x80, 0x53, 0xff, 0x04, 0x86, 0x53, 0xff, 0x0d, 0x9b, 0x61, 0xff, 0x10, 0xa4, 0x66, 0xff, 0x0e, 0xa3, 0x64, 0xff, 0x0c, 0xa2, 0x63, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0d, 0xa2, 0x65, 0xff, 0x0c, 0xa1, 0x64, 0xff, 0x0c, 0xa1, 0x64, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0d, 0xa1, 0x65, 0xff, 0x0d, 0xa1, 0x65, 0xff, 0x0d, 0xa2, 0x66, 0xff, 0x0f, 0xa4, 0x67, 0xff, 0x0d, 0xa2, 0x5f, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x0c, 0xa0, 0x5c, 0xff, 0x0d, 0xa0, 0x5c, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0d, 0xa0, 0x5d, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0d, 0xa0, 0x5e, 0xff, 0x0f, 0xa0, 0x5c, 0xff, 0x11, 0xa0, 0x5c, 0xff, 0x0e, 0x9f, 0x5f, 0xff, 0x0b, 0xa2, 0x56, 0xff, 0x09, 0xa1, 0x52, 0xff, 0x0d, 0x9f, 0x5b, 0xff, 0x13, 0x9a, 0x61, 0xff, 0x14, 0x96, 0x66, 0xff, 0x12, 0x8d, 0x6c, 0xff, 0x0e, 0x79, 0x75, 0xff, 0x07, 0x60, 0x79, 0xff, 0x07, 0x4b, 0x89, 0xff, 0x03, 0x3f, 0x94, 0xff, 0x07, 0x3c, 0x9d, 0xff, 0x0d, 0x46, 0xa5, 0xff, 0x0a, 0x4a, 0x99, 0xff, 0x05, 0x4d, 0x82, 0xff, 0x0b, 0x62, 0x6b, 0xff, 0x0a, 0x6b, 0x55, 0xff, 0x0a, 0x75, 0x47, 0xff, 0x07, 0x76, 0x40, 0xff, 0x06, 0x78, 0x3d, 0xff, 0x08, 0x79, 0x3c, 0xff, 0x0c, 0x76, 0x43, 0xff, 0x11, 0x75, 0x41, 0xff, 0x14, 0x5e, 0x53, 0xff, 0x15, 0x4a, 0x5e, 0xff, 0x1f, 0x4a, 0x5b, 0xff, 0x0c, 0x37, 0x42, 0xff, 0x0b, 0x39, 0x42, 0xff, 0x11, 0x3f, 0x4d, 0xff, 0x14, 0x44, 0x54, 0xff, 0x0f, 0x3d, 0x49, 0xff, 0x11, 0x3f, 0x44, 0xff, 0x0c, 0x3d, 0x42, 0xff, 0x11, 0x3b, 0x47, 0xff, 0x11, 0x33, 0x3c, 0xff, 0x06, 0x3d, 0x30, 0xff, 0x1b, 0x5a, 0x67, 0xff, 0x27, 0x60, 0x89, 0xff, 0x18, 0x54, 0x62, 0xff, 0x01, 0x43, 0x2e, 0xff, 0x09, 0x4c, 0x29, 0xff, 0x06, 0x44, 0x21, 0xff, 0x06, 0x42, 0x27, 0xff, 0x64, 0x87, 0x7c, 0xff, + 0x06, 0x37, 0x41, 0xff, 0x15, 0x47, 0x7c, 0xff, 0x07, 0x46, 0x88, 0xff, 0x10, 0x56, 0xb1, 0xff, 0x0b, 0x5e, 0xc6, 0xff, 0x08, 0x67, 0xce, 0xff, 0x15, 0x6f, 0xdd, 0xff, 0x22, 0x7e, 0xe3, 0xff, 0x31, 0x86, 0xd3, 0xff, 0x1d, 0x4a, 0x8b, 0xff, 0x03, 0x11, 0x51, 0xff, 0x02, 0x0a, 0x50, 0xff, 0x1a, 0x25, 0x6e, 0xff, 0x0a, 0x1a, 0x66, 0xff, 0x0d, 0x2a, 0x78, 0xff, 0x1d, 0x52, 0xa2, 0xff, 0x3f, 0x86, 0xcf, 0xff, 0x3a, 0x86, 0xc8, 0xff, 0x1d, 0x61, 0xa3, 0xff, 0x17, 0x6c, 0xaa, 0xff, 0x2f, 0x9a, 0xd6, 0xff, 0x22, 0xaa, 0xe3, 0xff, 0x22, 0xa9, 0xdd, 0xff, 0x03, 0x29, 0x63, 0xff, 0x06, 0x24, 0x5b, 0xff, 0x18, 0x71, 0x9b, 0xff, 0x1b, 0x69, 0x93, 0xff, 0x30, 0x99, 0xbd, 0xff, 0x30, 0xcc, 0xea, 0xff, 0x2b, 0xce, 0xfc, 0xff, 0x19, 0xae, 0xee, 0xff, 0x23, 0x8f, 0xd9, 0xff, 0x28, 0x98, 0xc7, 0xff, 0x23, 0x9c, 0xa5, 0xff, 0x23, 0xa4, 0x8d, 0xff, 0x26, 0xaa, 0x84, 0xff, 0x26, 0xa9, 0x88, 0xff, 0x1f, 0xa8, 0x82, 0xff, 0x1e, 0xa8, 0x7f, 0xff, 0x1b, 0xa6, 0x78, 0xff, 0x0e, 0xa2, 0x6f, 0xff, 0x02, 0xa2, 0x6b, 0xff, 0x02, 0xa5, 0x6c, 0xff, 0x0d, 0xa8, 0x6e, 0xff, 0x13, 0xa2, 0x6b, 0xff, 0x03, 0x83, 0x4d, 0xff, 0x00, 0x74, 0x3f, 0xff, 0x00, 0x64, 0x32, 0xff, 0x01, 0x5d, 0x2e, 0xff, 0x02, 0x51, 0x28, 0xff, 0x02, 0x46, 0x20, 0xff, 0x01, 0x3f, 0x1e, 0xff, 0x02, 0x41, 0x22, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x3d, 0x1e, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x03, 0x3d, 0x1e, 0xff, 0x04, 0x3d, 0x20, 0xff, 0x04, 0x3c, 0x1e, 0xff, 0x03, 0x3a, 0x1e, 0xff, 0x02, 0x3a, 0x1d, 0xff, 0x00, 0x3b, 0x1d, 0xff, 0x00, 0x3b, 0x1e, 0xff, 0x00, 0x3b, 0x1d, 0xff, 0x00, 0x3b, 0x1d, 0xff, 0x02, 0x3b, 0x1f, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3b, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x3e, 0x21, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x00, 0x41, 0x22, 0xff, 0x00, 0x41, 0x21, 0xff, 0x00, 0x45, 0x23, 0xff, 0x03, 0x4b, 0x29, 0xff, 0x05, 0x4e, 0x2a, 0xff, 0x04, 0x4d, 0x28, 0xff, 0x01, 0x51, 0x29, 0xff, 0x00, 0x5f, 0x32, 0xff, 0x00, 0x6f, 0x3e, 0xff, 0x02, 0x83, 0x4f, 0xff, 0x04, 0x8f, 0x5b, 0xff, 0x11, 0xa2, 0x70, 0xff, 0x10, 0xa2, 0x71, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x0f, 0xa3, 0x77, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x10, 0xa4, 0x79, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa4, 0x7a, 0xff, 0x0f, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0e, 0xa9, 0x75, 0xff, 0x0f, 0xaa, 0x76, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0d, 0xa3, 0x78, 0xff, 0x0b, 0xa5, 0x76, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x10, 0xa5, 0x76, 0xff, 0x12, 0xa7, 0x7a, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x13, 0xa4, 0x79, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x13, 0xa4, 0x7b, 0xff, 0x13, 0xa4, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7d, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7a, 0xff, 0x13, 0xa3, 0x7b, 0xff, 0x10, 0xa3, 0x7c, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa4, 0x7a, 0xff, 0x09, 0xa5, 0x78, 0xff, 0x0c, 0xa5, 0x78, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x10, 0xa4, 0x75, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x0a, 0x96, 0x60, 0xff, 0x06, 0x85, 0x52, 0xff, 0x02, 0x77, 0x44, 0xff, 0x00, 0x6c, 0x3a, 0xff, 0x00, 0x5f, 0x31, 0xff, 0x00, 0x57, 0x2d, 0xff, 0x02, 0x4f, 0x29, 0xff, 0x02, 0x4a, 0x25, 0xff, 0x04, 0x48, 0x25, 0xff, 0x04, 0x46, 0x25, 0xff, 0x02, 0x43, 0x23, 0xff, 0x01, 0x44, 0x23, 0xff, 0x02, 0x45, 0x23, 0xff, 0x02, 0x46, 0x24, 0xff, 0x01, 0x45, 0x23, 0xff, 0x01, 0x43, 0x22, 0xff, 0x01, 0x43, 0x22, 0xff, 0x00, 0x42, 0x22, 0xff, 0x01, 0x42, 0x23, 0xff, 0x00, 0x44, 0x24, 0xff, 0x00, 0x42, 0x22, 0xff, 0x00, 0x41, 0x23, 0xff, 0x01, 0x42, 0x23, 0xff, 0x00, 0x41, 0x21, 0xff, 0x00, 0x41, 0x23, 0xff, 0x00, 0x41, 0x23, 0xff, 0x00, 0x44, 0x24, 0xff, 0x00, 0x46, 0x23, 0xff, 0x01, 0x4b, 0x28, 0xff, 0x01, 0x4f, 0x2c, 0xff, 0x01, 0x52, 0x2e, 0xff, 0x00, 0x58, 0x33, 0xff, 0x01, 0x5d, 0x37, 0xff, 0x08, 0x6a, 0x43, 0xff, 0x14, 0x86, 0x5e, 0xff, 0x13, 0x95, 0x6b, 0xff, 0x16, 0xa2, 0x77, 0xff, 0x19, 0xac, 0x7f, 0xff, 0x20, 0xb5, 0x88, 0xff, 0x25, 0xb7, 0x8d, 0xff, 0x23, 0xb7, 0x90, 0xff, 0x22, 0xb8, 0x92, 0xff, 0x1d, 0xb6, 0x90, 0xff, 0x21, 0xb8, 0x90, 0xff, 0x21, 0xb7, 0x8f, 0xff, 0x1d, 0xb4, 0x8c, 0xff, 0x1b, 0xb0, 0x88, 0xff, 0x1a, 0xaf, 0x87, 0xff, 0x18, 0xad, 0x85, 0xff, 0x15, 0xab, 0x83, 0xff, 0x14, 0xab, 0x81, 0xff, 0x15, 0xac, 0x81, 0xff, 0x16, 0xad, 0x82, 0xff, 0x15, 0xad, 0x82, 0xff, 0x17, 0xae, 0x85, 0xff, 0x19, 0xb0, 0x88, 0xff, 0x19, 0xb0, 0x88, 0xff, 0x18, 0xaf, 0x88, 0xff, 0x17, 0xac, 0x83, 0xff, 0x16, 0xac, 0x80, 0xff, 0x15, 0xac, 0x80, 0xff, 0x14, 0xab, 0x80, 0xff, 0x13, 0xa9, 0x80, 0xff, 0x13, 0xaa, 0x7f, 0xff, 0x15, 0xaa, 0x7f, 0xff, 0x15, 0xaa, 0x7e, 0xff, 0x16, 0xaa, 0x7f, 0xff, 0x15, 0xab, 0x7e, 0xff, 0x14, 0xaa, 0x7d, 0xff, 0x13, 0xa9, 0x7d, 0xff, 0x15, 0xab, 0x7d, 0xff, 0x17, 0xae, 0x81, 0xff, 0x1b, 0xb2, 0x85, 0xff, 0x1e, 0xb5, 0x88, 0xff, 0x20, 0xb7, 0x8a, 0xff, 0x20, 0xb6, 0x89, 0xff, 0x1d, 0xb3, 0x83, 0xff, 0x14, 0xa9, 0x76, 0xff, 0x05, 0x90, 0x5b, 0xff, 0x01, 0x79, 0x44, 0xff, 0x01, 0x61, 0x30, 0xff, 0x01, 0x55, 0x27, 0xff, 0x02, 0x4f, 0x25, 0xff, 0x04, 0x46, 0x25, 0xff, 0x02, 0x40, 0x1f, 0xff, 0x04, 0x3d, 0x1f, 0xff, 0x06, 0x3b, 0x1f, 0xff, 0x04, 0x3a, 0x1e, 0xff, 0x00, 0x36, 0x1b, 0xff, 0x00, 0x37, 0x1c, 0xff, 0x01, 0x39, 0x1e, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x03, 0x3b, 0x1e, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x01, 0x39, 0x1b, 0xff, 0x01, 0x37, 0x19, 0xff, 0x00, 0x36, 0x1a, 0xff, 0x00, 0x37, 0x1b, 0xff, 0x01, 0x37, 0x1b, 0xff, 0x00, 0x37, 0x1b, 0xff, 0x01, 0x38, 0x1c, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x00, 0x3b, 0x1e, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x02, 0x3d, 0x20, 0xff, 0x02, 0x3f, 0x1f, 0xff, 0x02, 0x40, 0x1f, 0xff, 0x01, 0x40, 0x1e, 0xff, 0x01, 0x42, 0x21, 0xff, 0x03, 0x46, 0x24, 0xff, 0x02, 0x49, 0x27, 0xff, 0x00, 0x48, 0x25, 0xff, 0x01, 0x50, 0x2d, 0xff, 0x08, 0x6c, 0x47, 0xff, 0x12, 0x7e, 0x57, 0xff, 0x08, 0x7a, 0x4c, 0xff, 0x04, 0x8d, 0x54, 0xff, 0x0c, 0xa1, 0x63, 0xff, 0x0b, 0xa3, 0x63, 0xff, 0x0c, 0xa3, 0x61, 0xff, 0x0b, 0xa2, 0x61, 0xff, 0x0c, 0xa2, 0x61, 0xff, 0x0b, 0xa1, 0x5f, 0xff, 0x0b, 0xa1, 0x5f, 0xff, 0x0d, 0xa2, 0x5f, 0xff, 0x0c, 0xa2, 0x5f, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0e, 0xa3, 0x62, 0xff, 0x0c, 0xa2, 0x5d, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0d, 0xa0, 0x5c, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0c, 0xa0, 0x5b, 0xff, 0x0c, 0xa1, 0x58, 0xff, 0x0e, 0xa0, 0x5c, 0xff, 0x0f, 0xa0, 0x5a, 0xff, 0x0f, 0xa0, 0x5b, 0xff, 0x0d, 0x9f, 0x5d, 0xff, 0x0a, 0xa1, 0x55, 0xff, 0x0b, 0xa2, 0x55, 0xff, 0x0b, 0x9f, 0x5a, 0xff, 0x0d, 0x9a, 0x5c, 0xff, 0x11, 0x9f, 0x57, 0xff, 0x11, 0x9d, 0x58, 0xff, 0x11, 0x97, 0x67, 0xff, 0x13, 0x92, 0x6d, 0xff, 0x1c, 0x7c, 0x7c, 0xff, 0x0e, 0x53, 0x7b, 0xff, 0x21, 0x56, 0x97, 0xff, 0x35, 0x6b, 0xa9, 0xff, 0x39, 0x79, 0xa8, 0xff, 0x15, 0x6c, 0x75, 0xff, 0x10, 0x7f, 0x54, 0xff, 0x0a, 0x7b, 0x43, 0xff, 0x08, 0x79, 0x40, 0xff, 0x09, 0x77, 0x41, 0xff, 0x06, 0x7a, 0x3e, 0xff, 0x0c, 0x78, 0x3e, 0xff, 0x12, 0x74, 0x41, 0xff, 0x11, 0x6e, 0x3c, 0xff, 0x18, 0x5e, 0x4d, 0xff, 0x1a, 0x4d, 0x55, 0xff, 0x18, 0x42, 0x4c, 0xff, 0x0b, 0x37, 0x3d, 0xff, 0x0a, 0x38, 0x41, 0xff, 0x08, 0x36, 0x41, 0xff, 0x10, 0x40, 0x48, 0xff, 0x0e, 0x40, 0x47, 0xff, 0x12, 0x3d, 0x45, 0xff, 0x16, 0x3d, 0x42, 0xff, 0x13, 0x37, 0x3f, 0xff, 0x10, 0x2b, 0x36, 0xff, 0x0c, 0x37, 0x42, 0xff, 0x2f, 0x64, 0xa1, 0xff, 0x30, 0x61, 0xcf, 0xff, 0x1d, 0x56, 0x94, 0xff, 0x01, 0x42, 0x34, 0xff, 0x0c, 0x4a, 0x2d, 0xff, 0x09, 0x43, 0x1f, 0xff, 0x07, 0x46, 0x22, 0xff, 0x62, 0x84, 0x7a, 0xff, + 0x00, 0x32, 0x2a, 0xff, 0x11, 0x42, 0x63, 0xff, 0x0a, 0x46, 0x80, 0xff, 0x08, 0x50, 0xa1, 0xff, 0x0f, 0x5c, 0xc2, 0xff, 0x0b, 0x5e, 0xc9, 0xff, 0x10, 0x6b, 0xd5, 0xff, 0x16, 0x7c, 0xe2, 0xff, 0x1f, 0x82, 0xde, 0xff, 0x39, 0x89, 0xd6, 0xff, 0x26, 0x5a, 0x9c, 0xff, 0x03, 0x12, 0x49, 0xff, 0x01, 0x09, 0x38, 0xff, 0x02, 0x15, 0x3f, 0xff, 0x00, 0x17, 0x41, 0xff, 0x02, 0x1c, 0x48, 0xff, 0x0b, 0x3c, 0x5e, 0xff, 0x0a, 0x4a, 0x5f, 0xff, 0x04, 0x48, 0x55, 0xff, 0x04, 0x59, 0x60, 0xff, 0x18, 0x9a, 0xa1, 0xff, 0x0c, 0xad, 0xb4, 0xff, 0x0f, 0xad, 0xb2, 0xff, 0x08, 0x51, 0x5c, 0xff, 0x2b, 0x7b, 0x8e, 0xff, 0x43, 0xd9, 0xe3, 0xff, 0x50, 0xde, 0xe7, 0xff, 0x4b, 0xe3, 0xea, 0xff, 0x2d, 0xe8, 0xf4, 0xff, 0x25, 0xcc, 0xf5, 0xff, 0x1b, 0xaa, 0xe6, 0xff, 0x1f, 0x8f, 0xcc, 0xff, 0x27, 0x9d, 0xbb, 0xff, 0x24, 0xa1, 0x98, 0xff, 0x27, 0xa7, 0x8a, 0xff, 0x29, 0xab, 0x86, 0xff, 0x27, 0xaa, 0x86, 0xff, 0x1f, 0xa7, 0x81, 0xff, 0x1c, 0xa6, 0x7b, 0xff, 0x17, 0xa3, 0x70, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x02, 0xa5, 0x6a, 0xff, 0x04, 0xa7, 0x6b, 0xff, 0x10, 0xa9, 0x6e, 0xff, 0x0d, 0x95, 0x60, 0xff, 0x01, 0x75, 0x44, 0xff, 0x00, 0x64, 0x36, 0xff, 0x00, 0x52, 0x26, 0xff, 0x01, 0x4d, 0x24, 0xff, 0x02, 0x45, 0x21, 0xff, 0x02, 0x40, 0x1e, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x00, 0x3c, 0x1e, 0xff, 0x00, 0x39, 0x1a, 0xff, 0x00, 0x37, 0x19, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x04, 0x38, 0x1c, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x00, 0x36, 0x19, 0xff, 0x00, 0x36, 0x19, 0xff, 0x00, 0x38, 0x1b, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x02, 0x3f, 0x20, 0xff, 0x02, 0x40, 0x21, 0xff, 0x01, 0x40, 0x21, 0xff, 0x03, 0x44, 0x24, 0xff, 0x04, 0x45, 0x25, 0xff, 0x04, 0x46, 0x26, 0xff, 0x02, 0x49, 0x26, 0xff, 0x00, 0x52, 0x2b, 0xff, 0x00, 0x5f, 0x33, 0xff, 0x02, 0x75, 0x43, 0xff, 0x02, 0x82, 0x4f, 0xff, 0x10, 0x9d, 0x68, 0xff, 0x14, 0xa5, 0x70, 0xff, 0x0f, 0xa2, 0x75, 0xff, 0x0e, 0xa1, 0x75, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x11, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0d, 0xa5, 0x75, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x10, 0xa2, 0x7f, 0xff, 0x10, 0xa4, 0x7d, 0xff, 0x12, 0xa6, 0x79, 0xff, 0x13, 0xa5, 0x79, 0xff, 0x14, 0xa5, 0x7a, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x10, 0xa3, 0x7a, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x07, 0xa7, 0x77, 0xff, 0x0b, 0xa6, 0x77, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x13, 0xa5, 0x75, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x0e, 0xa2, 0x69, 0xff, 0x04, 0x84, 0x4f, 0xff, 0x05, 0x73, 0x42, 0xff, 0x03, 0x68, 0x38, 0xff, 0x01, 0x5f, 0x31, 0xff, 0x00, 0x51, 0x28, 0xff, 0x01, 0x4a, 0x24, 0xff, 0x00, 0x43, 0x22, 0xff, 0x02, 0x44, 0x23, 0xff, 0x03, 0x43, 0x23, 0xff, 0x01, 0x40, 0x20, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x40, 0x20, 0xff, 0x03, 0x3f, 0x20, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x01, 0x3d, 0x1f, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x01, 0x3e, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x00, 0x3e, 0x20, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x3f, 0x1f, 0xff, 0x00, 0x40, 0x20, 0xff, 0x01, 0x43, 0x23, 0xff, 0x01, 0x45, 0x24, 0xff, 0x01, 0x47, 0x26, 0xff, 0x00, 0x4a, 0x29, 0xff, 0x02, 0x50, 0x2e, 0xff, 0x03, 0x53, 0x31, 0xff, 0x0d, 0x6a, 0x46, 0xff, 0x15, 0x84, 0x5e, 0xff, 0x15, 0x96, 0x6c, 0xff, 0x15, 0xa3, 0x77, 0xff, 0x1b, 0xaa, 0x7f, 0xff, 0x25, 0xb2, 0x89, 0xff, 0x28, 0xb7, 0x90, 0xff, 0x23, 0xb8, 0x93, 0xff, 0x1e, 0xb7, 0x92, 0xff, 0x20, 0xb7, 0x90, 0xff, 0x1f, 0xb6, 0x8f, 0xff, 0x1c, 0xb4, 0x8c, 0xff, 0x1a, 0xb0, 0x88, 0xff, 0x17, 0xae, 0x86, 0xff, 0x15, 0xac, 0x83, 0xff, 0x14, 0xad, 0x81, 0xff, 0x15, 0xad, 0x82, 0xff, 0x16, 0xb1, 0x85, 0xff, 0x1b, 0xb3, 0x88, 0xff, 0x1b, 0xb4, 0x88, 0xff, 0x1d, 0xb5, 0x8b, 0xff, 0x1e, 0xb4, 0x8c, 0xff, 0x20, 0xb5, 0x8d, 0xff, 0x1f, 0xb4, 0x8c, 0xff, 0x1b, 0xb1, 0x86, 0xff, 0x17, 0xaf, 0x83, 0xff, 0x15, 0xad, 0x81, 0xff, 0x15, 0xac, 0x82, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x83, 0xff, 0x18, 0xac, 0x82, 0xff, 0x18, 0xac, 0x81, 0xff, 0x19, 0xac, 0x83, 0xff, 0x18, 0xaa, 0x82, 0xff, 0x15, 0xa9, 0x80, 0xff, 0x15, 0xa9, 0x80, 0xff, 0x16, 0xab, 0x80, 0xff, 0x18, 0xae, 0x83, 0xff, 0x1c, 0xb2, 0x87, 0xff, 0x1f, 0xb6, 0x8b, 0xff, 0x20, 0xb8, 0x8c, 0xff, 0x1c, 0xb6, 0x89, 0xff, 0x15, 0xad, 0x7d, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x02, 0x85, 0x50, 0xff, 0x02, 0x6f, 0x3d, 0xff, 0x02, 0x54, 0x28, 0xff, 0x03, 0x48, 0x21, 0xff, 0x01, 0x43, 0x20, 0xff, 0x01, 0x42, 0x22, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x05, 0x35, 0x1b, 0xff, 0x02, 0x33, 0x18, 0xff, 0x00, 0x32, 0x19, 0xff, 0x02, 0x34, 0x1b, 0xff, 0x02, 0x34, 0x1a, 0xff, 0x02, 0x36, 0x1b, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x02, 0x35, 0x19, 0xff, 0x00, 0x33, 0x17, 0xff, 0x00, 0x33, 0x16, 0xff, 0x00, 0x33, 0x17, 0xff, 0x01, 0x34, 0x18, 0xff, 0x01, 0x34, 0x18, 0xff, 0x01, 0x34, 0x18, 0xff, 0x02, 0x35, 0x19, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x02, 0x38, 0x1b, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x01, 0x39, 0x1b, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x00, 0x3b, 0x1c, 0xff, 0x02, 0x3f, 0x20, 0xff, 0x01, 0x3e, 0x1f, 0xff, 0x03, 0x3f, 0x20, 0xff, 0x04, 0x42, 0x22, 0xff, 0x02, 0x43, 0x23, 0xff, 0x01, 0x44, 0x24, 0xff, 0x01, 0x47, 0x27, 0xff, 0x01, 0x52, 0x31, 0xff, 0x14, 0x70, 0x4c, 0xff, 0x0d, 0x70, 0x47, 0xff, 0x00, 0x79, 0x44, 0xff, 0x07, 0x96, 0x59, 0xff, 0x0d, 0xa4, 0x63, 0xff, 0x0b, 0xa3, 0x5f, 0xff, 0x0a, 0xa2, 0x5e, 0xff, 0x0b, 0xa2, 0x5e, 0xff, 0x0c, 0xa3, 0x5c, 0xff, 0x0c, 0xa3, 0x5c, 0xff, 0x0b, 0xa4, 0x5b, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0d, 0xa3, 0x5d, 0xff, 0x0c, 0xa2, 0x5d, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0b, 0xa1, 0x5c, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0c, 0xa0, 0x5a, 0xff, 0x0d, 0xa0, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0c, 0x9f, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0b, 0xa0, 0x57, 0xff, 0x0b, 0x9f, 0x58, 0xff, 0x0d, 0x9c, 0x5c, 0xff, 0x10, 0xa0, 0x55, 0xff, 0x0f, 0xa0, 0x57, 0xff, 0x07, 0x9c, 0x61, 0xff, 0x0b, 0x9d, 0x60, 0xff, 0x19, 0x88, 0x6a, 0xff, 0x14, 0x60, 0x74, 0xff, 0x37, 0x6e, 0xa1, 0xff, 0x67, 0x9c, 0xc9, 0xff, 0x6e, 0xad, 0xcd, 0xff, 0x1c, 0x7e, 0x74, 0xff, 0x08, 0x85, 0x49, 0xff, 0x07, 0x7d, 0x42, 0xff, 0x09, 0x7a, 0x44, 0xff, 0x0f, 0x77, 0x45, 0xff, 0x10, 0x7b, 0x3f, 0xff, 0x13, 0x73, 0x3e, 0xff, 0x09, 0x5c, 0x2d, 0xff, 0x04, 0x4e, 0x24, 0xff, 0x14, 0x53, 0x43, 0xff, 0x21, 0x51, 0x56, 0xff, 0x19, 0x40, 0x4a, 0xff, 0x0e, 0x36, 0x3d, 0xff, 0x0c, 0x36, 0x41, 0xff, 0x09, 0x34, 0x3f, 0xff, 0x0c, 0x39, 0x40, 0xff, 0x0a, 0x3e, 0x44, 0xff, 0x10, 0x3d, 0x42, 0xff, 0x17, 0x39, 0x3d, 0xff, 0x13, 0x31, 0x38, 0xff, 0x0e, 0x25, 0x32, 0xff, 0x0b, 0x31, 0x54, 0xff, 0x21, 0x51, 0xb1, 0xff, 0x1e, 0x4c, 0xda, 0xff, 0x1d, 0x58, 0xa7, 0xff, 0x02, 0x43, 0x32, 0xff, 0x0f, 0x46, 0x2d, 0xff, 0x09, 0x3c, 0x1e, 0xff, 0x06, 0x42, 0x1f, 0xff, 0x63, 0x83, 0x77, 0xff, + 0x09, 0x56, 0x3d, 0xff, 0x03, 0x35, 0x3f, 0xff, 0x05, 0x41, 0x62, 0xff, 0x04, 0x4d, 0x8a, 0xff, 0x12, 0x5b, 0xb5, 0xff, 0x12, 0x59, 0xc2, 0xff, 0x11, 0x63, 0xd0, 0xff, 0x0b, 0x76, 0xe2, 0xff, 0x0d, 0x7c, 0xdb, 0xff, 0x26, 0x91, 0xd8, 0xff, 0x44, 0xa3, 0xd4, 0xff, 0x24, 0x73, 0x8b, 0xff, 0x05, 0x49, 0x4b, 0xff, 0x0b, 0x63, 0x55, 0xff, 0x16, 0x7b, 0x63, 0xff, 0x17, 0x82, 0x60, 0xff, 0x1e, 0x9f, 0x75, 0xff, 0x1a, 0xb6, 0x81, 0xff, 0x1d, 0xc5, 0x8a, 0xff, 0x1c, 0xcd, 0x91, 0xff, 0x16, 0xd1, 0x96, 0xff, 0x15, 0xde, 0xa5, 0xff, 0x0d, 0xdf, 0x9e, 0xff, 0x1c, 0xd9, 0x93, 0xff, 0x2a, 0xd4, 0xa1, 0xff, 0x22, 0xe0, 0xb9, 0xff, 0x2e, 0xde, 0xbb, 0xff, 0x2e, 0xdd, 0xbd, 0xff, 0x2a, 0xe9, 0xd7, 0xff, 0x1e, 0xc6, 0xdd, 0xff, 0x15, 0xa6, 0xd0, 0xff, 0x24, 0x99, 0xba, 0xff, 0x26, 0xa1, 0xaa, 0xff, 0x24, 0xa7, 0x91, 0xff, 0x24, 0xaa, 0x86, 0xff, 0x23, 0xab, 0x83, 0xff, 0x1f, 0xa9, 0x81, 0xff, 0x19, 0xa6, 0x7b, 0xff, 0x14, 0xa3, 0x75, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x05, 0xa6, 0x6b, 0xff, 0x07, 0xaa, 0x6c, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x06, 0x8a, 0x53, 0xff, 0x02, 0x6b, 0x3c, 0xff, 0x01, 0x54, 0x2a, 0xff, 0x03, 0x44, 0x1e, 0xff, 0x02, 0x41, 0x1d, 0xff, 0x02, 0x40, 0x1f, 0xff, 0x01, 0x3d, 0x1e, 0xff, 0x00, 0x38, 0x1b, 0xff, 0x00, 0x35, 0x18, 0xff, 0x02, 0x31, 0x16, 0xff, 0x04, 0x31, 0x16, 0xff, 0x03, 0x33, 0x17, 0xff, 0x03, 0x34, 0x18, 0xff, 0x04, 0x35, 0x19, 0xff, 0x03, 0x33, 0x18, 0xff, 0x01, 0x32, 0x16, 0xff, 0x01, 0x32, 0x16, 0xff, 0x01, 0x32, 0x16, 0xff, 0x01, 0x32, 0x16, 0xff, 0x02, 0x31, 0x16, 0xff, 0x02, 0x31, 0x16, 0xff, 0x02, 0x33, 0x17, 0xff, 0x02, 0x33, 0x17, 0xff, 0x03, 0x34, 0x19, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x02, 0x37, 0x1b, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x03, 0x3b, 0x1d, 0xff, 0x03, 0x3d, 0x1f, 0xff, 0x03, 0x3e, 0x20, 0xff, 0x01, 0x3d, 0x1f, 0xff, 0x02, 0x3f, 0x21, 0xff, 0x01, 0x3f, 0x22, 0xff, 0x00, 0x42, 0x22, 0xff, 0x01, 0x45, 0x23, 0xff, 0x00, 0x4a, 0x24, 0xff, 0x02, 0x52, 0x2a, 0xff, 0x01, 0x5f, 0x33, 0xff, 0x00, 0x6b, 0x3e, 0xff, 0x08, 0x8b, 0x5a, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x0e, 0xa1, 0x75, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0d, 0xa5, 0x75, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa5, 0x75, 0xff, 0x0d, 0xa4, 0x75, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x0e, 0xa4, 0x78, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x12, 0xa3, 0x7e, 0xff, 0x12, 0xa3, 0x7e, 0xff, 0x12, 0xa3, 0x7e, 0xff, 0x11, 0xa2, 0x7e, 0xff, 0x11, 0xa3, 0x80, 0xff, 0x10, 0xa3, 0x7e, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x10, 0xa3, 0x7b, 0xff, 0x0e, 0xa4, 0x7a, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x0f, 0xa5, 0x75, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x06, 0x91, 0x58, 0xff, 0x00, 0x73, 0x40, 0xff, 0x01, 0x61, 0x33, 0xff, 0x01, 0x54, 0x29, 0xff, 0x03, 0x4f, 0x26, 0xff, 0x03, 0x47, 0x21, 0xff, 0x04, 0x41, 0x20, 0xff, 0x03, 0x3d, 0x1e, 0xff, 0x03, 0x3e, 0x20, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x00, 0x38, 0x19, 0xff, 0x00, 0x3b, 0x1c, 0xff, 0x00, 0x3a, 0x1d, 0xff, 0x00, 0x3a, 0x1c, 0xff, 0x00, 0x3a, 0x1c, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x00, 0x38, 0x1b, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x01, 0x38, 0x1c, 0xff, 0x00, 0x38, 0x1c, 0xff, 0x00, 0x38, 0x1c, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x01, 0x39, 0x1d, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x01, 0x3e, 0x1e, 0xff, 0x02, 0x3f, 0x20, 0xff, 0x02, 0x40, 0x20, 0xff, 0x00, 0x41, 0x21, 0xff, 0x00, 0x41, 0x21, 0xff, 0x00, 0x48, 0x27, 0xff, 0x00, 0x49, 0x27, 0xff, 0x01, 0x4e, 0x2c, 0xff, 0x07, 0x62, 0x3e, 0xff, 0x17, 0x8b, 0x62, 0xff, 0x16, 0x9a, 0x70, 0xff, 0x13, 0xa1, 0x76, 0xff, 0x1d, 0xab, 0x82, 0xff, 0x25, 0xb6, 0x8f, 0xff, 0x23, 0xb7, 0x92, 0xff, 0x20, 0xb8, 0x92, 0xff, 0x1f, 0xb7, 0x8e, 0xff, 0x1d, 0xb4, 0x8c, 0xff, 0x1c, 0xb3, 0x8b, 0xff, 0x1c, 0xb3, 0x8b, 0xff, 0x1b, 0xb3, 0x89, 0xff, 0x18, 0xb0, 0x85, 0xff, 0x19, 0xb1, 0x86, 0xff, 0x1c, 0xb5, 0x8a, 0xff, 0x1c, 0xb8, 0x8b, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x1f, 0xb9, 0x8d, 0xff, 0x21, 0xb9, 0x8e, 0xff, 0x20, 0xb8, 0x8e, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x1f, 0xb7, 0x8d, 0xff, 0x1e, 0xb6, 0x8a, 0xff, 0x1e, 0xb3, 0x8a, 0xff, 0x1d, 0xb1, 0x8a, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x83, 0xff, 0x17, 0xad, 0x82, 0xff, 0x18, 0xae, 0x84, 0xff, 0x1a, 0xae, 0x85, 0xff, 0x19, 0xad, 0x82, 0xff, 0x19, 0xae, 0x83, 0xff, 0x1b, 0xb1, 0x86, 0xff, 0x1e, 0xb4, 0x89, 0xff, 0x20, 0xb7, 0x8c, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x1a, 0xb2, 0x86, 0xff, 0x0d, 0xa7, 0x77, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x03, 0x7a, 0x44, 0xff, 0x03, 0x69, 0x37, 0xff, 0x00, 0x4e, 0x23, 0xff, 0x01, 0x43, 0x1f, 0xff, 0x07, 0x3f, 0x20, 0xff, 0x01, 0x41, 0x21, 0xff, 0x00, 0x39, 0x1a, 0xff, 0x00, 0x33, 0x15, 0xff, 0x01, 0x32, 0x16, 0xff, 0x00, 0x31, 0x15, 0xff, 0x00, 0x2f, 0x14, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x02, 0x2e, 0x15, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x03, 0x2f, 0x16, 0xff, 0x04, 0x2f, 0x16, 0xff, 0x05, 0x31, 0x17, 0xff, 0x05, 0x33, 0x19, 0xff, 0x04, 0x31, 0x18, 0xff, 0x02, 0x32, 0x18, 0xff, 0x03, 0x33, 0x19, 0xff, 0x02, 0x34, 0x1a, 0xff, 0x03, 0x36, 0x1b, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x02, 0x39, 0x1d, 0xff, 0x03, 0x3a, 0x1d, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x40, 0x22, 0xff, 0x02, 0x41, 0x24, 0xff, 0x0d, 0x57, 0x37, 0xff, 0x0c, 0x5f, 0x3a, 0xff, 0x00, 0x61, 0x33, 0xff, 0x07, 0x81, 0x4a, 0xff, 0x14, 0xa2, 0x63, 0xff, 0x0b, 0xa1, 0x5d, 0xff, 0x0c, 0xa3, 0x5b, 0xff, 0x0c, 0xa3, 0x5c, 0xff, 0x0d, 0xa4, 0x5e, 0xff, 0x0e, 0xa6, 0x5d, 0xff, 0x0e, 0xa6, 0x5d, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0f, 0xa5, 0x5e, 0xff, 0x0e, 0xa3, 0x5e, 0xff, 0x0d, 0xa3, 0x5d, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0c, 0xa0, 0x5a, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0c, 0xa0, 0x5a, 0xff, 0x0e, 0xa0, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0a, 0x9e, 0x56, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x58, 0xff, 0x0b, 0x9d, 0x5b, 0xff, 0x0f, 0xa1, 0x54, 0xff, 0x0d, 0xa1, 0x56, 0xff, 0x06, 0x9e, 0x5c, 0xff, 0x09, 0x9d, 0x5a, 0xff, 0x18, 0x88, 0x69, 0xff, 0x22, 0x6d, 0x82, 0xff, 0x55, 0x8d, 0xb9, 0xff, 0x7e, 0xb4, 0xda, 0xff, 0x7f, 0xbc, 0xd7, 0xff, 0x26, 0x87, 0x77, 0xff, 0x0d, 0x89, 0x4b, 0xff, 0x0e, 0x81, 0x48, 0xff, 0x0e, 0x76, 0x48, 0xff, 0x17, 0x6e, 0x45, 0xff, 0x0e, 0x63, 0x31, 0xff, 0x07, 0x51, 0x25, 0xff, 0x01, 0x3c, 0x19, 0xff, 0x00, 0x3a, 0x1e, 0xff, 0x0c, 0x43, 0x41, 0xff, 0x24, 0x4f, 0x60, 0xff, 0x1c, 0x3f, 0x52, 0xff, 0x12, 0x33, 0x41, 0xff, 0x12, 0x31, 0x40, 0xff, 0x0e, 0x32, 0x3b, 0xff, 0x11, 0x37, 0x47, 0xff, 0x17, 0x4b, 0x4e, 0xff, 0x06, 0x3c, 0x34, 0xff, 0x05, 0x2f, 0x32, 0xff, 0x0f, 0x2c, 0x35, 0xff, 0x0e, 0x25, 0x32, 0xff, 0x11, 0x3a, 0x6e, 0xff, 0x26, 0x54, 0xc2, 0xff, 0x1f, 0x4c, 0xc9, 0xff, 0x16, 0x53, 0x8b, 0xff, 0x04, 0x48, 0x2e, 0xff, 0x11, 0x46, 0x2a, 0xff, 0x08, 0x37, 0x1f, 0xff, 0x08, 0x3d, 0x25, 0xff, 0x67, 0x83, 0x7a, 0xff, + 0x1b, 0x95, 0x67, 0xff, 0x0c, 0x61, 0x4e, 0xff, 0x02, 0x3e, 0x40, 0xff, 0x05, 0x44, 0x65, 0xff, 0x13, 0x57, 0x9a, 0xff, 0x15, 0x5a, 0xb4, 0xff, 0x12, 0x5d, 0xbf, 0xff, 0x13, 0x74, 0xd0, 0xff, 0x10, 0x85, 0xc3, 0xff, 0x08, 0x91, 0xa2, 0xff, 0x1d, 0xaf, 0x9e, 0xff, 0x21, 0xb7, 0x8b, 0xff, 0x1d, 0xbe, 0x88, 0xff, 0x1d, 0xcf, 0x95, 0xff, 0x24, 0xda, 0x9a, 0xff, 0x23, 0xdd, 0x8e, 0xff, 0x1f, 0xe2, 0x90, 0xff, 0x17, 0xe4, 0x8c, 0xff, 0x15, 0xdf, 0x88, 0xff, 0x12, 0xd5, 0x7f, 0xff, 0x0f, 0xd1, 0x7e, 0xff, 0x0a, 0xcb, 0x7a, 0xff, 0x03, 0xca, 0x79, 0xff, 0x07, 0xce, 0x7c, 0xff, 0x0d, 0xcd, 0x7f, 0xff, 0x0a, 0xcd, 0x7f, 0xff, 0x12, 0xd1, 0x86, 0xff, 0x19, 0xda, 0x95, 0xff, 0x16, 0xd7, 0xa1, 0xff, 0x1e, 0xd1, 0xb7, 0xff, 0x1f, 0xbc, 0xb4, 0xff, 0x29, 0xa5, 0xa4, 0xff, 0x23, 0xa5, 0x95, 0xff, 0x1f, 0xa9, 0x84, 0xff, 0x1e, 0xac, 0x80, 0xff, 0x1a, 0xa9, 0x7d, 0xff, 0x16, 0xa8, 0x7b, 0xff, 0x11, 0xa5, 0x75, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0a, 0xa8, 0x6b, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x02, 0x83, 0x4c, 0xff, 0x07, 0x66, 0x37, 0xff, 0x06, 0x50, 0x28, 0xff, 0x02, 0x40, 0x1d, 0xff, 0x03, 0x3e, 0x1d, 0xff, 0x09, 0x3c, 0x20, 0xff, 0x04, 0x34, 0x19, 0xff, 0x00, 0x2f, 0x14, 0xff, 0x00, 0x30, 0x16, 0xff, 0x05, 0x2f, 0x15, 0xff, 0x05, 0x2f, 0x14, 0xff, 0x02, 0x2d, 0x13, 0xff, 0x00, 0x2a, 0x11, 0xff, 0x02, 0x2c, 0x12, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x00, 0x2a, 0x10, 0xff, 0x00, 0x2a, 0x10, 0xff, 0x00, 0x2a, 0x10, 0xff, 0x00, 0x2a, 0x10, 0xff, 0x02, 0x29, 0x11, 0xff, 0x04, 0x2b, 0x13, 0xff, 0x05, 0x2d, 0x14, 0xff, 0x06, 0x2d, 0x14, 0xff, 0x06, 0x30, 0x16, 0xff, 0x05, 0x2f, 0x15, 0xff, 0x04, 0x2f, 0x15, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x02, 0x31, 0x16, 0xff, 0x03, 0x34, 0x18, 0xff, 0x04, 0x36, 0x1a, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x00, 0x38, 0x1b, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x00, 0x3c, 0x1f, 0xff, 0x00, 0x3f, 0x1f, 0xff, 0x00, 0x42, 0x20, 0xff, 0x04, 0x49, 0x24, 0xff, 0x0b, 0x57, 0x32, 0xff, 0x01, 0x59, 0x32, 0xff, 0x03, 0x78, 0x4b, 0xff, 0x0b, 0x95, 0x66, 0xff, 0x11, 0xa0, 0x76, 0xff, 0x12, 0xa1, 0x79, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0d, 0xa4, 0x75, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0b, 0xa5, 0x73, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x7d, 0xff, 0x10, 0xa2, 0x7e, 0xff, 0x12, 0xa1, 0x80, 0xff, 0x12, 0xa2, 0x80, 0xff, 0x11, 0xa4, 0x81, 0xff, 0x10, 0xa4, 0x7e, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x10, 0xa2, 0x7c, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0e, 0xa4, 0x7a, 0xff, 0x12, 0xa3, 0x78, 0xff, 0x13, 0xa4, 0x79, 0xff, 0x0c, 0xa7, 0x78, 0xff, 0x09, 0xa7, 0x74, 0xff, 0x0d, 0xa0, 0x69, 0xff, 0x03, 0x82, 0x4b, 0xff, 0x03, 0x69, 0x38, 0xff, 0x00, 0x4f, 0x27, 0xff, 0x00, 0x44, 0x1f, 0xff, 0x02, 0x43, 0x1e, 0xff, 0x05, 0x3f, 0x1e, 0xff, 0x06, 0x3b, 0x1d, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x00, 0x35, 0x18, 0xff, 0x01, 0x32, 0x15, 0xff, 0x01, 0x33, 0x15, 0xff, 0x01, 0x34, 0x17, 0xff, 0x01, 0x35, 0x19, 0xff, 0x02, 0x36, 0x1a, 0xff, 0x01, 0x34, 0x18, 0xff, 0x02, 0x34, 0x17, 0xff, 0x02, 0x33, 0x17, 0xff, 0x01, 0x32, 0x16, 0xff, 0x02, 0x33, 0x17, 0xff, 0x02, 0x32, 0x17, 0xff, 0x02, 0x33, 0x19, 0xff, 0x03, 0x33, 0x19, 0xff, 0x03, 0x33, 0x19, 0xff, 0x03, 0x34, 0x19, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x05, 0x35, 0x1b, 0xff, 0x05, 0x36, 0x1c, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x02, 0x3a, 0x1c, 0xff, 0x03, 0x3c, 0x1d, 0xff, 0x04, 0x3d, 0x1e, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x01, 0x3e, 0x1e, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x42, 0x21, 0xff, 0x00, 0x43, 0x22, 0xff, 0x01, 0x46, 0x24, 0xff, 0x0d, 0x6e, 0x48, 0xff, 0x1a, 0x91, 0x67, 0xff, 0x12, 0x9a, 0x6f, 0xff, 0x14, 0xa0, 0x76, 0xff, 0x20, 0xb1, 0x89, 0xff, 0x24, 0xb7, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x20, 0xba, 0x91, 0xff, 0x1f, 0xb9, 0x90, 0xff, 0x1e, 0xb8, 0x8f, 0xff, 0x1e, 0xb8, 0x8e, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x1e, 0xb8, 0x8d, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8d, 0xff, 0x1f, 0xba, 0x8d, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x1f, 0xb9, 0x8d, 0xff, 0x1f, 0xb9, 0x8d, 0xff, 0x1f, 0xb7, 0x8e, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x20, 0xb7, 0x8e, 0xff, 0x21, 0xb8, 0x8d, 0xff, 0x21, 0xb6, 0x8e, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x1b, 0xaf, 0x89, 0xff, 0x1b, 0xae, 0x88, 0xff, 0x17, 0xad, 0x85, 0xff, 0x17, 0xae, 0x85, 0xff, 0x1b, 0xb2, 0x87, 0xff, 0x1c, 0xb2, 0x87, 0xff, 0x1c, 0xb2, 0x87, 0xff, 0x1e, 0xb4, 0x89, 0xff, 0x21, 0xb7, 0x8c, 0xff, 0x20, 0xb7, 0x8c, 0xff, 0x20, 0xb8, 0x8d, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x20, 0xb5, 0x8d, 0xff, 0x19, 0xad, 0x85, 0xff, 0x0c, 0xa8, 0x76, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x03, 0x7a, 0x43, 0xff, 0x04, 0x66, 0x33, 0xff, 0x01, 0x4b, 0x22, 0xff, 0x02, 0x3f, 0x1d, 0xff, 0x0b, 0x3a, 0x1f, 0xff, 0x08, 0x38, 0x1b, 0xff, 0x00, 0x2c, 0x0f, 0xff, 0x02, 0x2a, 0x0e, 0xff, 0x02, 0x2b, 0x0f, 0xff, 0x01, 0x2b, 0x0f, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x00, 0x27, 0x0d, 0xff, 0x01, 0x24, 0x0a, 0xff, 0x02, 0x25, 0x0d, 0xff, 0x03, 0x25, 0x0d, 0xff, 0x02, 0x25, 0x0d, 0xff, 0x03, 0x25, 0x0d, 0xff, 0x03, 0x25, 0x0e, 0xff, 0x03, 0x25, 0x0d, 0xff, 0x03, 0x25, 0x0d, 0xff, 0x03, 0x26, 0x0e, 0xff, 0x04, 0x27, 0x0f, 0xff, 0x04, 0x28, 0x10, 0xff, 0x05, 0x2a, 0x11, 0xff, 0x03, 0x28, 0x0f, 0xff, 0x00, 0x26, 0x0d, 0xff, 0x01, 0x29, 0x10, 0xff, 0x02, 0x2a, 0x11, 0xff, 0x03, 0x2c, 0x13, 0xff, 0x01, 0x2f, 0x13, 0xff, 0x03, 0x32, 0x16, 0xff, 0x03, 0x32, 0x17, 0xff, 0x03, 0x34, 0x18, 0xff, 0x02, 0x35, 0x19, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x03, 0x3c, 0x1f, 0xff, 0x09, 0x3c, 0x22, 0xff, 0x05, 0x44, 0x26, 0xff, 0x06, 0x50, 0x2e, 0xff, 0x02, 0x54, 0x2c, 0xff, 0x06, 0x6c, 0x3c, 0xff, 0x16, 0x9c, 0x5e, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0e, 0xa2, 0x59, 0xff, 0x0c, 0xa3, 0x5c, 0xff, 0x0e, 0xa5, 0x5d, 0xff, 0x0f, 0xa7, 0x5e, 0xff, 0x0f, 0xa8, 0x5d, 0xff, 0x0e, 0xa7, 0x5c, 0xff, 0x10, 0xa7, 0x5d, 0xff, 0x10, 0xa7, 0x5f, 0xff, 0x0f, 0xa5, 0x5f, 0xff, 0x0e, 0xa4, 0x5d, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0b, 0x9f, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9e, 0x56, 0xff, 0x0a, 0x9e, 0x56, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0c, 0x9f, 0x57, 0xff, 0x0a, 0x9d, 0x5a, 0xff, 0x0d, 0xa0, 0x54, 0xff, 0x0c, 0xa0, 0x54, 0xff, 0x06, 0xa0, 0x57, 0xff, 0x08, 0x9c, 0x57, 0xff, 0x1b, 0x85, 0x6d, 0xff, 0x32, 0x78, 0x92, 0xff, 0x64, 0x9c, 0xc2, 0xff, 0x82, 0xb4, 0xd6, 0xff, 0x84, 0xbc, 0xd5, 0xff, 0x2f, 0x89, 0x7a, 0xff, 0x15, 0x88, 0x4e, 0xff, 0x14, 0x7e, 0x4b, 0xff, 0x0c, 0x64, 0x3f, 0xff, 0x09, 0x4d, 0x2e, 0xff, 0x02, 0x3c, 0x17, 0xff, 0x03, 0x39, 0x17, 0xff, 0x03, 0x37, 0x19, 0xff, 0x01, 0x38, 0x22, 0xff, 0x07, 0x3b, 0x3b, 0xff, 0x21, 0x50, 0x60, 0xff, 0x1d, 0x42, 0x54, 0xff, 0x12, 0x32, 0x3d, 0xff, 0x15, 0x31, 0x38, 0xff, 0x12, 0x37, 0x39, 0xff, 0x0d, 0x35, 0x42, 0xff, 0x1e, 0x55, 0x4b, 0xff, 0x0e, 0x4e, 0x33, 0xff, 0x03, 0x33, 0x30, 0xff, 0x0d, 0x2d, 0x33, 0xff, 0x14, 0x2a, 0x32, 0xff, 0x16, 0x41, 0x6f, 0xff, 0x17, 0x48, 0x9e, 0xff, 0x10, 0x48, 0x89, 0xff, 0x05, 0x49, 0x53, 0xff, 0x0a, 0x4c, 0x28, 0xff, 0x0e, 0x44, 0x25, 0xff, 0x09, 0x37, 0x1f, 0xff, 0x06, 0x3a, 0x22, 0xff, 0x65, 0x7f, 0x79, 0xff, + 0x0e, 0xa1, 0x68, 0xff, 0x17, 0x93, 0x69, 0xff, 0x0f, 0x6c, 0x51, 0xff, 0x01, 0x38, 0x3b, 0xff, 0x09, 0x45, 0x6a, 0xff, 0x0d, 0x60, 0x98, 0xff, 0x05, 0x67, 0x99, 0xff, 0x0b, 0x89, 0xa4, 0xff, 0x0f, 0xa0, 0x9e, 0xff, 0x13, 0xb9, 0x8e, 0xff, 0x14, 0xc2, 0x7d, 0xff, 0x13, 0xc3, 0x6f, 0xff, 0x11, 0xc6, 0x72, 0xff, 0x0b, 0xc9, 0x7b, 0xff, 0x07, 0xc7, 0x7a, 0xff, 0x06, 0xc5, 0x71, 0xff, 0x03, 0xc4, 0x6f, 0xff, 0x02, 0xc8, 0x73, 0xff, 0x04, 0xc5, 0x71, 0xff, 0x08, 0xc1, 0x6f, 0xff, 0x06, 0xbc, 0x6c, 0xff, 0x04, 0xbd, 0x6d, 0xff, 0x04, 0xbd, 0x70, 0xff, 0x01, 0xbd, 0x70, 0xff, 0x04, 0xbf, 0x72, 0xff, 0x0e, 0xbd, 0x70, 0xff, 0x0d, 0xbc, 0x72, 0xff, 0x09, 0xb2, 0x6f, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x11, 0xa1, 0x74, 0xff, 0x1e, 0xa3, 0x81, 0xff, 0x22, 0x9d, 0x83, 0xff, 0x1f, 0xa3, 0x7f, 0xff, 0x1e, 0xac, 0x7f, 0xff, 0x1a, 0xab, 0x7d, 0xff, 0x15, 0xa9, 0x7c, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x04, 0xa6, 0x6c, 0xff, 0x0b, 0xa8, 0x6c, 0xff, 0x0d, 0xaa, 0x6d, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0e, 0xa8, 0x6c, 0xff, 0x05, 0x8a, 0x52, 0xff, 0x05, 0x60, 0x32, 0xff, 0x05, 0x4b, 0x24, 0xff, 0x00, 0x3d, 0x1d, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x05, 0x33, 0x19, 0xff, 0x02, 0x2a, 0x13, 0xff, 0x01, 0x29, 0x11, 0xff, 0x02, 0x28, 0x11, 0xff, 0x02, 0x27, 0x10, 0xff, 0x02, 0x26, 0x0e, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x00, 0x23, 0x0b, 0xff, 0x01, 0x23, 0x0b, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x00, 0x24, 0x0b, 0xff, 0x00, 0x24, 0x0b, 0xff, 0x00, 0x24, 0x0b, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x02, 0x24, 0x0c, 0xff, 0x02, 0x24, 0x0c, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x00, 0x24, 0x0c, 0xff, 0x01, 0x28, 0x0e, 0xff, 0x01, 0x2a, 0x10, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x01, 0x30, 0x15, 0xff, 0x01, 0x31, 0x16, 0xff, 0x01, 0x33, 0x18, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x05, 0x37, 0x1c, 0xff, 0x02, 0x39, 0x1d, 0xff, 0x00, 0x3c, 0x1e, 0xff, 0x02, 0x41, 0x21, 0xff, 0x10, 0x54, 0x33, 0xff, 0x08, 0x57, 0x34, 0xff, 0x01, 0x63, 0x3c, 0xff, 0x0a, 0x86, 0x5c, 0xff, 0x12, 0x9f, 0x78, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x11, 0xa1, 0x79, 0xff, 0x10, 0xa2, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x09, 0xa8, 0x6d, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x09, 0xa8, 0x6d, 0xff, 0x0a, 0xa9, 0x6e, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0c, 0xa4, 0x74, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0f, 0xa3, 0x7a, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x11, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7e, 0xff, 0x11, 0xa3, 0x80, 0xff, 0x10, 0xa3, 0x7e, 0xff, 0x0f, 0xa3, 0x7a, 0xff, 0x11, 0xa4, 0x7a, 0xff, 0x10, 0xa3, 0x7c, 0xff, 0x0f, 0xa2, 0x7d, 0xff, 0x0f, 0xa2, 0x7c, 0xff, 0x0f, 0xa4, 0x7a, 0xff, 0x14, 0xa3, 0x79, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x09, 0xa6, 0x77, 0xff, 0x08, 0xa8, 0x73, 0xff, 0x09, 0x9d, 0x64, 0xff, 0x00, 0x79, 0x42, 0xff, 0x06, 0x61, 0x34, 0xff, 0x05, 0x48, 0x25, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x03, 0x40, 0x20, 0xff, 0x04, 0x3a, 0x1d, 0xff, 0x02, 0x33, 0x18, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x00, 0x2f, 0x14, 0xff, 0x04, 0x30, 0x16, 0xff, 0x04, 0x2f, 0x14, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x02, 0x2d, 0x13, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x02, 0x2b, 0x11, 0xff, 0x03, 0x2c, 0x13, 0xff, 0x03, 0x2d, 0x14, 0xff, 0x04, 0x2d, 0x14, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x06, 0x30, 0x16, 0xff, 0x05, 0x2f, 0x15, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x05, 0x2f, 0x16, 0xff, 0x04, 0x31, 0x17, 0xff, 0x03, 0x34, 0x17, 0xff, 0x04, 0x36, 0x19, 0xff, 0x05, 0x37, 0x1a, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x03, 0x39, 0x1c, 0xff, 0x02, 0x3b, 0x1d, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x03, 0x3f, 0x1f, 0xff, 0x02, 0x4d, 0x2a, 0xff, 0x13, 0x76, 0x51, 0xff, 0x18, 0x92, 0x6a, 0xff, 0x11, 0x96, 0x6e, 0xff, 0x1d, 0xab, 0x84, 0xff, 0x24, 0xb7, 0x92, 0xff, 0x23, 0xb9, 0x92, 0xff, 0x20, 0xba, 0x91, 0xff, 0x20, 0xba, 0x91, 0xff, 0x20, 0xba, 0x91, 0xff, 0x1e, 0xb9, 0x8f, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1e, 0xba, 0x8e, 0xff, 0x1d, 0xba, 0x8d, 0xff, 0x1e, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x20, 0xbb, 0x8f, 0xff, 0x20, 0xbb, 0x8f, 0xff, 0x20, 0xb9, 0x8e, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x1e, 0xb5, 0x8d, 0xff, 0x1e, 0xb3, 0x8a, 0xff, 0x20, 0xb4, 0x8e, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x20, 0xb4, 0x8e, 0xff, 0x1e, 0xb4, 0x8d, 0xff, 0x1c, 0xb2, 0x8a, 0xff, 0x1b, 0xb3, 0x8a, 0xff, 0x1d, 0xb7, 0x8c, 0xff, 0x1f, 0xb6, 0x8b, 0xff, 0x20, 0xb7, 0x8c, 0xff, 0x20, 0xb8, 0x8c, 0xff, 0x21, 0xb8, 0x8d, 0xff, 0x20, 0xb8, 0x8d, 0xff, 0x21, 0xb8, 0x8f, 0xff, 0x20, 0xb7, 0x8e, 0xff, 0x20, 0xb4, 0x8d, 0xff, 0x1e, 0xae, 0x88, 0xff, 0x10, 0xaa, 0x7a, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0a, 0x8d, 0x53, 0xff, 0x01, 0x60, 0x2c, 0xff, 0x01, 0x42, 0x1b, 0xff, 0x04, 0x36, 0x18, 0xff, 0x08, 0x31, 0x19, 0xff, 0x09, 0x2b, 0x12, 0xff, 0x05, 0x24, 0x0b, 0xff, 0x05, 0x24, 0x0b, 0xff, 0x03, 0x24, 0x0a, 0xff, 0x00, 0x22, 0x09, 0xff, 0x00, 0x21, 0x08, 0xff, 0x01, 0x20, 0x08, 0xff, 0x03, 0x20, 0x08, 0xff, 0x03, 0x1f, 0x08, 0xff, 0x04, 0x20, 0x09, 0xff, 0x03, 0x20, 0x09, 0xff, 0x03, 0x1f, 0x08, 0xff, 0x02, 0x1f, 0x08, 0xff, 0x01, 0x1d, 0x06, 0xff, 0x01, 0x1d, 0x06, 0xff, 0x01, 0x1e, 0x07, 0xff, 0x02, 0x1e, 0x07, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x01, 0x1f, 0x07, 0xff, 0x00, 0x1e, 0x06, 0xff, 0x00, 0x1f, 0x08, 0xff, 0x01, 0x20, 0x09, 0xff, 0x01, 0x23, 0x0b, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x01, 0x27, 0x0d, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x01, 0x2b, 0x11, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x02, 0x30, 0x15, 0xff, 0x02, 0x32, 0x17, 0xff, 0x03, 0x36, 0x1a, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x05, 0x48, 0x28, 0xff, 0x03, 0x50, 0x2b, 0xff, 0x01, 0x5f, 0x32, 0xff, 0x12, 0x98, 0x5b, 0xff, 0x0e, 0xa3, 0x5d, 0xff, 0x11, 0xa4, 0x5a, 0xff, 0x0b, 0xa2, 0x5a, 0xff, 0x0e, 0xa6, 0x5d, 0xff, 0x0f, 0xa7, 0x5e, 0xff, 0x0f, 0xa8, 0x5d, 0xff, 0x11, 0xa9, 0x5e, 0xff, 0x10, 0xa8, 0x5d, 0xff, 0x0f, 0xa7, 0x5c, 0xff, 0x0e, 0xa5, 0x5d, 0xff, 0x0f, 0xa5, 0x5d, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0a, 0x9e, 0x56, 0xff, 0x0c, 0x9f, 0x57, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x09, 0x9c, 0x57, 0xff, 0x0c, 0x9e, 0x54, 0xff, 0x0c, 0x9e, 0x54, 0xff, 0x07, 0x9f, 0x53, 0xff, 0x0b, 0x9a, 0x58, 0xff, 0x1a, 0x7d, 0x71, 0xff, 0x3f, 0x7d, 0xa1, 0xff, 0x69, 0x9d, 0xc5, 0xff, 0x84, 0xb5, 0xd5, 0xff, 0x93, 0xc4, 0xe0, 0xff, 0x4a, 0x96, 0x93, 0xff, 0x11, 0x72, 0x45, 0xff, 0x0a, 0x60, 0x33, 0xff, 0x01, 0x40, 0x23, 0xff, 0x02, 0x36, 0x20, 0xff, 0x03, 0x32, 0x1e, 0xff, 0x03, 0x33, 0x1f, 0xff, 0x04, 0x3a, 0x24, 0xff, 0x05, 0x3e, 0x2d, 0xff, 0x0e, 0x4a, 0x48, 0xff, 0x22, 0x57, 0x62, 0xff, 0x1a, 0x44, 0x52, 0xff, 0x0d, 0x32, 0x3a, 0xff, 0x10, 0x31, 0x35, 0xff, 0x09, 0x35, 0x3a, 0xff, 0x04, 0x39, 0x48, 0xff, 0x0d, 0x4b, 0x3b, 0xff, 0x19, 0x61, 0x3d, 0xff, 0x04, 0x3c, 0x30, 0xff, 0x0c, 0x2d, 0x33, 0xff, 0x17, 0x2c, 0x34, 0xff, 0x0e, 0x37, 0x4e, 0xff, 0x03, 0x37, 0x58, 0xff, 0x13, 0x57, 0x5f, 0xff, 0x0a, 0x51, 0x48, 0xff, 0x0a, 0x4a, 0x2c, 0xff, 0x0b, 0x42, 0x22, 0xff, 0x06, 0x37, 0x1d, 0xff, 0x03, 0x3a, 0x1f, 0xff, 0x64, 0x81, 0x78, 0xff, + 0x08, 0x9f, 0x63, 0xff, 0x0f, 0xa1, 0x6a, 0xff, 0x14, 0x93, 0x64, 0xff, 0x02, 0x4c, 0x35, 0xff, 0x01, 0x37, 0x3c, 0xff, 0x04, 0x65, 0x77, 0xff, 0x0a, 0x8b, 0x88, 0xff, 0x11, 0xaa, 0x87, 0xff, 0x14, 0xb9, 0x86, 0xff, 0x0c, 0xbc, 0x75, 0xff, 0x07, 0xb6, 0x62, 0xff, 0x05, 0xb0, 0x57, 0xff, 0x05, 0xb0, 0x5b, 0xff, 0x02, 0xaf, 0x5f, 0xff, 0x06, 0xb5, 0x68, 0xff, 0x05, 0xb7, 0x6a, 0xff, 0x05, 0xba, 0x6d, 0xff, 0x03, 0xba, 0x6e, 0xff, 0x05, 0xb9, 0x6d, 0xff, 0x09, 0xb9, 0x6e, 0xff, 0x08, 0xb8, 0x6d, 0xff, 0x06, 0xb9, 0x6d, 0xff, 0x06, 0xbc, 0x70, 0xff, 0x03, 0xbc, 0x6f, 0xff, 0x0b, 0xbd, 0x75, 0xff, 0x1c, 0xb5, 0x7c, 0xff, 0x10, 0xa0, 0x73, 0xff, 0x04, 0x82, 0x62, 0xff, 0x04, 0x72, 0x53, 0xff, 0x02, 0x65, 0x3e, 0xff, 0x04, 0x69, 0x40, 0xff, 0x06, 0x77, 0x50, 0xff, 0x09, 0x87, 0x5d, 0xff, 0x16, 0xa4, 0x77, 0xff, 0x18, 0xab, 0x7d, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x07, 0xa5, 0x69, 0xff, 0x03, 0xa7, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0d, 0xac, 0x6f, 0xff, 0x0e, 0x9a, 0x62, 0xff, 0x01, 0x5d, 0x2e, 0xff, 0x01, 0x44, 0x1c, 0xff, 0x00, 0x36, 0x18, 0xff, 0x01, 0x33, 0x17, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x01, 0x24, 0x0e, 0xff, 0x02, 0x24, 0x0f, 0xff, 0x02, 0x21, 0x0d, 0xff, 0x01, 0x1f, 0x0a, 0xff, 0x03, 0x1f, 0x08, 0xff, 0x01, 0x1e, 0x07, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x03, 0x21, 0x0a, 0xff, 0x02, 0x1f, 0x09, 0xff, 0x01, 0x1e, 0x08, 0xff, 0x00, 0x1e, 0x07, 0xff, 0x00, 0x1d, 0x07, 0xff, 0x00, 0x1e, 0x06, 0xff, 0x00, 0x1f, 0x08, 0xff, 0x00, 0x1f, 0x08, 0xff, 0x00, 0x1f, 0x08, 0xff, 0x01, 0x1e, 0x07, 0xff, 0x00, 0x1d, 0x07, 0xff, 0x00, 0x1d, 0x07, 0xff, 0x00, 0x1e, 0x07, 0xff, 0x00, 0x20, 0x09, 0xff, 0x01, 0x22, 0x0b, 0xff, 0x00, 0x24, 0x0c, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x00, 0x26, 0x0d, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x00, 0x2b, 0x12, 0xff, 0x03, 0x2e, 0x15, 0xff, 0x09, 0x30, 0x17, 0xff, 0x06, 0x34, 0x1a, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x00, 0x38, 0x1b, 0xff, 0x10, 0x51, 0x33, 0xff, 0x11, 0x5c, 0x3d, 0xff, 0x01, 0x57, 0x34, 0xff, 0x0e, 0x81, 0x5c, 0xff, 0x14, 0xa0, 0x7b, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x79, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x0f, 0xa3, 0x77, 0xff, 0x0f, 0xa5, 0x76, 0xff, 0x0f, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x74, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x09, 0xa9, 0x6d, 0xff, 0x09, 0xa9, 0x6c, 0xff, 0x09, 0xa9, 0x6b, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x76, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x12, 0xa6, 0x78, 0xff, 0x12, 0xa5, 0x7e, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x0f, 0xa1, 0x7d, 0xff, 0x0f, 0xa2, 0x7c, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x13, 0xa4, 0x7a, 0xff, 0x0f, 0xa4, 0x7a, 0xff, 0x0a, 0xa6, 0x78, 0xff, 0x0a, 0xa9, 0x74, 0xff, 0x0c, 0xa2, 0x68, 0xff, 0x01, 0x7a, 0x43, 0xff, 0x05, 0x5a, 0x2f, 0xff, 0x0b, 0x45, 0x25, 0xff, 0x03, 0x3a, 0x1d, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x01, 0x33, 0x18, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x00, 0x2a, 0x12, 0xff, 0x00, 0x29, 0x11, 0xff, 0x02, 0x28, 0x10, 0xff, 0x03, 0x27, 0x0d, 0xff, 0x00, 0x24, 0x0c, 0xff, 0x00, 0x24, 0x0d, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x00, 0x24, 0x0d, 0xff, 0x00, 0x24, 0x0d, 0xff, 0x01, 0x23, 0x0d, 0xff, 0x01, 0x23, 0x0c, 0xff, 0x02, 0x24, 0x0d, 0xff, 0x02, 0x24, 0x0c, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x02, 0x26, 0x0e, 0xff, 0x02, 0x26, 0x0e, 0xff, 0x03, 0x27, 0x0f, 0xff, 0x02, 0x25, 0x0d, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x01, 0x28, 0x0f, 0xff, 0x01, 0x2b, 0x10, 0xff, 0x03, 0x2e, 0x13, 0xff, 0x04, 0x30, 0x15, 0xff, 0x04, 0x31, 0x16, 0xff, 0x03, 0x32, 0x16, 0xff, 0x02, 0x34, 0x18, 0xff, 0x03, 0x36, 0x1b, 0xff, 0x03, 0x37, 0x1b, 0xff, 0x03, 0x3a, 0x1b, 0xff, 0x00, 0x3f, 0x1e, 0xff, 0x08, 0x59, 0x36, 0xff, 0x1e, 0x8a, 0x64, 0xff, 0x16, 0x92, 0x6b, 0xff, 0x1d, 0xa8, 0x82, 0xff, 0x23, 0xb5, 0x90, 0xff, 0x23, 0xb9, 0x94, 0xff, 0x20, 0xba, 0x91, 0xff, 0x20, 0xba, 0x91, 0xff, 0x20, 0xba, 0x91, 0xff, 0x20, 0xba, 0x90, 0xff, 0x20, 0xbb, 0x90, 0xff, 0x1f, 0xba, 0x8f, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x1e, 0xba, 0x8d, 0xff, 0x1d, 0xbb, 0x8e, 0xff, 0x1e, 0xbb, 0x8e, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8f, 0xff, 0x20, 0xba, 0x8f, 0xff, 0x20, 0xb9, 0x8f, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x1e, 0xb4, 0x8c, 0xff, 0x1f, 0xb3, 0x8c, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x21, 0xb6, 0x90, 0xff, 0x1f, 0xb6, 0x8f, 0xff, 0x1f, 0xb7, 0x8f, 0xff, 0x1f, 0xb7, 0x8e, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x20, 0xb8, 0x8d, 0xff, 0x21, 0xb9, 0x8e, 0xff, 0x20, 0xb8, 0x8d, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x21, 0xb8, 0x8e, 0xff, 0x21, 0xb8, 0x90, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x23, 0xb1, 0x8d, 0xff, 0x14, 0xaa, 0x7d, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0f, 0xa1, 0x66, 0xff, 0x04, 0x6d, 0x37, 0xff, 0x01, 0x3b, 0x14, 0xff, 0x02, 0x2c, 0x0f, 0xff, 0x03, 0x28, 0x12, 0xff, 0x03, 0x20, 0x0a, 0xff, 0x05, 0x21, 0x0a, 0xff, 0x04, 0x1e, 0x08, 0xff, 0x01, 0x1d, 0x07, 0xff, 0x01, 0x1e, 0x08, 0xff, 0x00, 0x1c, 0x07, 0xff, 0x02, 0x1b, 0x06, 0xff, 0x08, 0x1d, 0x08, 0xff, 0x04, 0x1c, 0x06, 0xff, 0x04, 0x1d, 0x07, 0xff, 0x04, 0x1c, 0x06, 0xff, 0x02, 0x1b, 0x05, 0xff, 0x01, 0x1a, 0x04, 0xff, 0x01, 0x18, 0x03, 0xff, 0x01, 0x19, 0x03, 0xff, 0x01, 0x1a, 0x04, 0xff, 0x01, 0x1b, 0x05, 0xff, 0x01, 0x1b, 0x05, 0xff, 0x01, 0x19, 0x03, 0xff, 0x00, 0x1a, 0x04, 0xff, 0x00, 0x1b, 0x05, 0xff, 0x01, 0x1c, 0x05, 0xff, 0x01, 0x1d, 0x06, 0xff, 0x01, 0x1d, 0x07, 0xff, 0x02, 0x21, 0x0a, 0xff, 0x01, 0x20, 0x09, 0xff, 0x01, 0x20, 0x09, 0xff, 0x01, 0x22, 0x0a, 0xff, 0x00, 0x23, 0x0b, 0xff, 0x02, 0x29, 0x10, 0xff, 0x02, 0x2b, 0x12, 0xff, 0x02, 0x2e, 0x15, 0xff, 0x00, 0x32, 0x16, 0xff, 0x01, 0x35, 0x18, 0xff, 0x05, 0x40, 0x23, 0xff, 0x02, 0x4e, 0x2a, 0xff, 0x01, 0x5f, 0x31, 0xff, 0x11, 0x9a, 0x5e, 0xff, 0x0e, 0xa4, 0x5e, 0xff, 0x10, 0xa5, 0x5b, 0xff, 0x0b, 0xa2, 0x5a, 0xff, 0x0e, 0xa6, 0x5d, 0xff, 0x10, 0xa8, 0x5f, 0xff, 0x0f, 0xa8, 0x5d, 0xff, 0x10, 0xa8, 0x5d, 0xff, 0x0f, 0xa7, 0x5c, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0f, 0xa6, 0x5d, 0xff, 0x0f, 0xa6, 0x5d, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0a, 0x9c, 0x56, 0xff, 0x0d, 0x9c, 0x54, 0xff, 0x0e, 0x9c, 0x54, 0xff, 0x0a, 0x9e, 0x52, 0xff, 0x0e, 0x98, 0x5a, 0xff, 0x1c, 0x78, 0x76, 0xff, 0x49, 0x81, 0xad, 0xff, 0x6a, 0x98, 0xc5, 0xff, 0x87, 0xb6, 0xd6, 0xff, 0x9e, 0xca, 0xe9, 0xff, 0x72, 0xaf, 0xb9, 0xff, 0x07, 0x51, 0x33, 0xff, 0x00, 0x40, 0x1b, 0xff, 0x00, 0x39, 0x1f, 0xff, 0x02, 0x32, 0x23, 0xff, 0x09, 0x35, 0x2f, 0xff, 0x0d, 0x41, 0x3c, 0xff, 0x19, 0x55, 0x4e, 0xff, 0x27, 0x67, 0x61, 0xff, 0x3e, 0x7d, 0x7f, 0xff, 0x32, 0x67, 0x73, 0xff, 0x16, 0x42, 0x51, 0xff, 0x0c, 0x32, 0x3d, 0xff, 0x0b, 0x31, 0x37, 0xff, 0x0c, 0x40, 0x52, 0xff, 0x15, 0x5c, 0x76, 0xff, 0x05, 0x4b, 0x48, 0xff, 0x17, 0x67, 0x46, 0xff, 0x08, 0x45, 0x32, 0xff, 0x0c, 0x2d, 0x34, 0xff, 0x18, 0x2e, 0x37, 0xff, 0x13, 0x3a, 0x3d, 0xff, 0x02, 0x3b, 0x32, 0xff, 0x18, 0x61, 0x51, 0xff, 0x15, 0x57, 0x59, 0xff, 0x09, 0x45, 0x37, 0xff, 0x08, 0x41, 0x22, 0xff, 0x06, 0x3a, 0x20, 0xff, 0x08, 0x44, 0x2a, 0xff, 0x64, 0x87, 0x76, 0xff, + 0x0c, 0x9e, 0x66, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x0b, 0xa1, 0x67, 0xff, 0x0d, 0x92, 0x5e, 0xff, 0x0c, 0x77, 0x52, 0xff, 0x1c, 0x98, 0x78, 0xff, 0x1d, 0xa8, 0x73, 0xff, 0x0c, 0xa4, 0x5b, 0xff, 0x06, 0xa6, 0x5c, 0xff, 0x02, 0xa5, 0x5e, 0xff, 0x02, 0xa3, 0x5d, 0xff, 0x05, 0xa3, 0x5d, 0xff, 0x07, 0xa5, 0x5e, 0xff, 0x08, 0xaa, 0x60, 0xff, 0x08, 0xaf, 0x65, 0xff, 0x03, 0xb5, 0x6c, 0xff, 0x04, 0xb8, 0x6f, 0xff, 0x03, 0xb8, 0x70, 0xff, 0x05, 0xb8, 0x6f, 0xff, 0x08, 0xb6, 0x6c, 0xff, 0x0b, 0xb6, 0x6b, 0xff, 0x0b, 0xb5, 0x69, 0xff, 0x07, 0xb7, 0x68, 0xff, 0x0f, 0xbf, 0x72, 0xff, 0x0f, 0xab, 0x71, 0xff, 0x0a, 0x8a, 0x75, 0xff, 0x0d, 0x7a, 0x81, 0xff, 0x22, 0x88, 0x9c, 0xff, 0x1a, 0x89, 0x8c, 0xff, 0x13, 0x8f, 0x6d, 0xff, 0x1c, 0x9d, 0x6c, 0xff, 0x21, 0xa0, 0x76, 0xff, 0x1b, 0x9e, 0x75, 0xff, 0x1d, 0xa7, 0x7e, 0xff, 0x1a, 0xab, 0x81, 0xff, 0x12, 0xaa, 0x7d, 0xff, 0x0f, 0xa9, 0x77, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x07, 0xa6, 0x68, 0xff, 0x06, 0xa9, 0x6c, 0xff, 0x0d, 0xa9, 0x6d, 0xff, 0x0d, 0xa9, 0x6b, 0xff, 0x0a, 0xac, 0x6e, 0xff, 0x08, 0xad, 0x70, 0xff, 0x0f, 0xa6, 0x6c, 0xff, 0x0d, 0x7d, 0x4c, 0xff, 0x01, 0x45, 0x1b, 0xff, 0x02, 0x28, 0x0d, 0xff, 0x03, 0x27, 0x0d, 0xff, 0x01, 0x1e, 0x07, 0xff, 0x02, 0x1d, 0x08, 0xff, 0x00, 0x1b, 0x08, 0xff, 0x01, 0x19, 0x07, 0xff, 0x05, 0x19, 0x07, 0xff, 0x07, 0x1a, 0x07, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x02, 0x1b, 0x07, 0xff, 0x03, 0x1b, 0x08, 0xff, 0x03, 0x1c, 0x09, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x01, 0x19, 0x06, 0xff, 0x00, 0x18, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x00, 0x18, 0x04, 0xff, 0x00, 0x19, 0x05, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x19, 0x05, 0xff, 0x00, 0x19, 0x05, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x01, 0x1a, 0x07, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x02, 0x1f, 0x0b, 0xff, 0x02, 0x1f, 0x0b, 0xff, 0x02, 0x20, 0x0c, 0xff, 0x01, 0x1f, 0x0a, 0xff, 0x00, 0x20, 0x0b, 0xff, 0x01, 0x22, 0x0d, 0xff, 0x07, 0x28, 0x10, 0xff, 0x05, 0x2c, 0x14, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x00, 0x30, 0x17, 0xff, 0x0f, 0x4d, 0x32, 0xff, 0x18, 0x64, 0x48, 0xff, 0x04, 0x5c, 0x3c, 0xff, 0x19, 0x8f, 0x6c, 0xff, 0x14, 0xa0, 0x7b, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x15, 0xa3, 0x7e, 0xff, 0x16, 0xa5, 0x7f, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa5, 0x78, 0xff, 0x10, 0xa4, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x0a, 0xa8, 0x6d, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0b, 0xa9, 0x6c, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x76, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x16, 0xac, 0x76, 0xff, 0x14, 0xab, 0x73, 0xff, 0x10, 0xa4, 0x75, 0xff, 0x12, 0xa6, 0x79, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x12, 0xa8, 0x79, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x0d, 0xa6, 0x79, 0xff, 0x0c, 0xa5, 0x7a, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0f, 0xa7, 0x70, 0xff, 0x0b, 0x92, 0x5c, 0xff, 0x01, 0x52, 0x27, 0xff, 0x06, 0x3a, 0x1a, 0xff, 0x05, 0x31, 0x15, 0xff, 0x03, 0x2e, 0x14, 0xff, 0x02, 0x23, 0x0d, 0xff, 0x05, 0x22, 0x0e, 0xff, 0x02, 0x21, 0x0c, 0xff, 0x01, 0x20, 0x0b, 0xff, 0x00, 0x1f, 0x09, 0xff, 0x01, 0x1f, 0x08, 0xff, 0x01, 0x1d, 0x08, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x00, 0x1d, 0x08, 0xff, 0x01, 0x1c, 0x08, 0xff, 0x02, 0x1c, 0x08, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x00, 0x1c, 0x08, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x00, 0x1c, 0x07, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x00, 0x1c, 0x07, 0xff, 0x00, 0x1c, 0x08, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x01, 0x20, 0x09, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x01, 0x23, 0x0a, 0xff, 0x01, 0x24, 0x0c, 0xff, 0x01, 0x26, 0x0e, 0xff, 0x00, 0x28, 0x0f, 0xff, 0x02, 0x2c, 0x13, 0xff, 0x02, 0x30, 0x15, 0xff, 0x01, 0x35, 0x19, 0xff, 0x00, 0x35, 0x19, 0xff, 0x02, 0x41, 0x23, 0xff, 0x1d, 0x77, 0x55, 0xff, 0x18, 0x8a, 0x66, 0xff, 0x1e, 0xa7, 0x81, 0xff, 0x26, 0xb8, 0x93, 0xff, 0x25, 0xba, 0x96, 0xff, 0x21, 0xba, 0x93, 0xff, 0x21, 0xba, 0x92, 0xff, 0x20, 0xba, 0x91, 0xff, 0x20, 0xba, 0x91, 0xff, 0x21, 0xbb, 0x92, 0xff, 0x20, 0xbb, 0x91, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x20, 0xbb, 0x8f, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1f, 0xba, 0x8f, 0xff, 0x1f, 0xb8, 0x90, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x21, 0xb6, 0x8f, 0xff, 0x22, 0xb6, 0x90, 0xff, 0x22, 0xb6, 0x90, 0xff, 0x22, 0xb7, 0x91, 0xff, 0x21, 0xb8, 0x93, 0xff, 0x21, 0xb8, 0x91, 0xff, 0x1f, 0xb8, 0x8f, 0xff, 0x1f, 0xba, 0x8e, 0xff, 0x1e, 0xb9, 0x8d, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x20, 0xb8, 0x8d, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x1f, 0xb7, 0x8d, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x20, 0xb8, 0x90, 0xff, 0x20, 0xb7, 0x8f, 0xff, 0x1f, 0xb5, 0x8f, 0xff, 0x21, 0xb4, 0x90, 0xff, 0x19, 0xaf, 0x82, 0xff, 0x0e, 0xa9, 0x74, 0xff, 0x0e, 0xa9, 0x6e, 0xff, 0x15, 0x9c, 0x64, 0xff, 0x05, 0x53, 0x29, 0xff, 0x00, 0x27, 0x08, 0xff, 0x02, 0x21, 0x0a, 0xff, 0x00, 0x1a, 0x05, 0xff, 0x00, 0x17, 0x04, 0xff, 0x02, 0x17, 0x04, 0xff, 0x01, 0x17, 0x05, 0xff, 0x02, 0x18, 0x07, 0xff, 0x01, 0x18, 0x05, 0xff, 0x05, 0x18, 0x07, 0xff, 0x08, 0x19, 0x09, 0xff, 0x04, 0x18, 0x06, 0xff, 0x04, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x02, 0x16, 0x04, 0xff, 0x02, 0x16, 0x04, 0xff, 0x03, 0x17, 0x04, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x02, 0x19, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x03, 0x1c, 0x08, 0xff, 0x03, 0x1c, 0x08, 0xff, 0x03, 0x1c, 0x08, 0xff, 0x03, 0x1c, 0x08, 0xff, 0x01, 0x1c, 0x08, 0xff, 0x00, 0x1c, 0x07, 0xff, 0x03, 0x20, 0x0c, 0xff, 0x03, 0x24, 0x0f, 0xff, 0x03, 0x27, 0x10, 0xff, 0x01, 0x2d, 0x11, 0xff, 0x05, 0x2e, 0x13, 0xff, 0x07, 0x36, 0x19, 0xff, 0x00, 0x4e, 0x27, 0xff, 0x06, 0x78, 0x47, 0xff, 0x11, 0xa1, 0x64, 0xff, 0x0e, 0xa5, 0x5f, 0xff, 0x0f, 0xa8, 0x5c, 0xff, 0x0f, 0xa6, 0x5e, 0xff, 0x10, 0xa7, 0x60, 0xff, 0x10, 0xa8, 0x5f, 0xff, 0x0f, 0xa8, 0x5d, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0c, 0x9f, 0x57, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0b, 0x9c, 0x54, 0xff, 0x10, 0x9a, 0x54, 0xff, 0x11, 0x99, 0x55, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x11, 0x92, 0x5b, 0xff, 0x27, 0x7c, 0x82, 0xff, 0x4d, 0x82, 0xb0, 0xff, 0x6e, 0x98, 0xcb, 0xff, 0x86, 0xb5, 0xd8, 0xff, 0x9a, 0xc3, 0xe7, 0xff, 0x99, 0xc7, 0xe2, 0xff, 0x27, 0x5d, 0x53, 0xff, 0x02, 0x35, 0x1b, 0xff, 0x04, 0x38, 0x25, 0xff, 0x29, 0x5e, 0x56, 0xff, 0x4e, 0x84, 0x8f, 0xff, 0x50, 0x8e, 0xa2, 0xff, 0x5b, 0x9c, 0xb0, 0xff, 0x4f, 0x8f, 0xa0, 0xff, 0x43, 0x7d, 0x8b, 0xff, 0x2c, 0x5c, 0x6b, 0xff, 0x1e, 0x43, 0x59, 0xff, 0x13, 0x33, 0x4b, 0xff, 0x09, 0x2b, 0x3e, 0xff, 0x1b, 0x53, 0x78, 0xff, 0x3c, 0xa0, 0xd4, 0xff, 0x29, 0x95, 0xbc, 0xff, 0x0d, 0x6c, 0x61, 0xff, 0x0e, 0x52, 0x3a, 0xff, 0x0f, 0x30, 0x33, 0xff, 0x14, 0x30, 0x36, 0xff, 0x17, 0x44, 0x3a, 0xff, 0x03, 0x3e, 0x23, 0xff, 0x1e, 0x66, 0x5c, 0xff, 0x25, 0x62, 0x7d, 0xff, 0x07, 0x44, 0x44, 0xff, 0x06, 0x48, 0x25, 0xff, 0x0f, 0x4a, 0x2f, 0xff, 0x0a, 0x4a, 0x30, 0xff, 0x61, 0x8a, 0x72, 0xff, + 0x07, 0x9f, 0x68, 0xff, 0x0a, 0x9e, 0x67, 0xff, 0x0a, 0xa1, 0x64, 0xff, 0x13, 0xae, 0x6d, 0xff, 0x12, 0xa9, 0x6d, 0xff, 0x16, 0xa1, 0x66, 0xff, 0x11, 0x9a, 0x58, 0xff, 0x05, 0x9a, 0x55, 0xff, 0x04, 0x9e, 0x58, 0xff, 0x04, 0xa2, 0x5b, 0xff, 0x06, 0xa3, 0x5d, 0xff, 0x09, 0xa3, 0x5e, 0xff, 0x0b, 0xa5, 0x5e, 0xff, 0x0b, 0xa8, 0x60, 0xff, 0x08, 0xad, 0x63, 0xff, 0x02, 0xb1, 0x67, 0xff, 0x06, 0xb4, 0x6b, 0xff, 0x07, 0xb6, 0x6d, 0xff, 0x08, 0xb6, 0x6c, 0xff, 0x08, 0xb7, 0x6c, 0xff, 0x08, 0xb6, 0x6a, 0xff, 0x05, 0xb4, 0x67, 0xff, 0x08, 0xb7, 0x6b, 0xff, 0x0d, 0xac, 0x71, 0xff, 0x06, 0x8e, 0x71, 0xff, 0x0f, 0x8a, 0x90, 0xff, 0x1b, 0x8a, 0x9c, 0xff, 0x23, 0x96, 0x9a, 0xff, 0x15, 0x99, 0x85, 0xff, 0x17, 0xa1, 0x74, 0xff, 0x21, 0xa9, 0x77, 0xff, 0x26, 0xa9, 0x7f, 0xff, 0x24, 0xaa, 0x81, 0xff, 0x1e, 0xaa, 0x83, 0xff, 0x19, 0xab, 0x81, 0xff, 0x12, 0xaa, 0x7b, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x08, 0xa5, 0x6b, 0xff, 0x08, 0xa7, 0x69, 0xff, 0x07, 0xa9, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x09, 0xab, 0x6e, 0xff, 0x05, 0xab, 0x70, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x18, 0x9b, 0x68, 0xff, 0x0b, 0x69, 0x3d, 0xff, 0x01, 0x27, 0x0a, 0xff, 0x01, 0x1f, 0x05, 0xff, 0x01, 0x19, 0x03, 0xff, 0x03, 0x18, 0x04, 0xff, 0x01, 0x16, 0x04, 0xff, 0x01, 0x17, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x17, 0x05, 0xff, 0x03, 0x18, 0x06, 0xff, 0x03, 0x18, 0x06, 0xff, 0x03, 0x18, 0x06, 0xff, 0x02, 0x17, 0x05, 0xff, 0x02, 0x17, 0x05, 0xff, 0x01, 0x15, 0x03, 0xff, 0x01, 0x16, 0x04, 0xff, 0x02, 0x17, 0x05, 0xff, 0x00, 0x18, 0x04, 0xff, 0x00, 0x19, 0x05, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x00, 0x19, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x04, 0x19, 0x07, 0xff, 0x03, 0x1a, 0x08, 0xff, 0x02, 0x1a, 0x08, 0xff, 0x01, 0x1a, 0x07, 0xff, 0x02, 0x1b, 0x09, 0xff, 0x00, 0x1b, 0x08, 0xff, 0x00, 0x1c, 0x08, 0xff, 0x02, 0x1f, 0x0b, 0xff, 0x04, 0x25, 0x0d, 0xff, 0x03, 0x26, 0x0e, 0xff, 0x04, 0x2a, 0x14, 0xff, 0x01, 0x2b, 0x16, 0xff, 0x0f, 0x4c, 0x34, 0xff, 0x18, 0x6c, 0x50, 0xff, 0x0c, 0x78, 0x57, 0xff, 0x1a, 0x98, 0x76, 0xff, 0x13, 0xa0, 0x7b, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x15, 0xa3, 0x7f, 0xff, 0x17, 0xa6, 0x7f, 0xff, 0x13, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa3, 0x7a, 0xff, 0x13, 0xa3, 0x7a, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x0b, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0d, 0xa0, 0x68, 0xff, 0x14, 0xa9, 0x6e, 0xff, 0x18, 0xad, 0x78, 0xff, 0x12, 0xa6, 0x73, 0xff, 0x0e, 0xa4, 0x6f, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x11, 0xa5, 0x78, 0xff, 0x11, 0xa4, 0x7a, 0xff, 0x14, 0xa5, 0x7a, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x0b, 0xa7, 0x78, 0xff, 0x0b, 0xa5, 0x78, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x13, 0xa3, 0x6d, 0xff, 0x08, 0x6b, 0x3e, 0xff, 0x02, 0x3a, 0x18, 0xff, 0x02, 0x29, 0x0d, 0xff, 0x04, 0x24, 0x0c, 0xff, 0x05, 0x1b, 0x07, 0xff, 0x0b, 0x1d, 0x0b, 0xff, 0x05, 0x17, 0x06, 0xff, 0x03, 0x1a, 0x08, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x00, 0x1b, 0x06, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x03, 0x1b, 0x09, 0xff, 0x03, 0x1b, 0x09, 0xff, 0x02, 0x1a, 0x08, 0xff, 0x02, 0x19, 0x07, 0xff, 0x02, 0x18, 0x06, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x17, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x01, 0x19, 0x05, 0xff, 0x00, 0x18, 0x04, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x01, 0x19, 0x06, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x00, 0x1f, 0x09, 0xff, 0x02, 0x1f, 0x0a, 0xff, 0x03, 0x1f, 0x0a, 0xff, 0x02, 0x1f, 0x0a, 0xff, 0x00, 0x1e, 0x09, 0xff, 0x00, 0x21, 0x0a, 0xff, 0x02, 0x25, 0x0e, 0xff, 0x01, 0x2a, 0x11, 0xff, 0x00, 0x2d, 0x13, 0xff, 0x01, 0x2e, 0x14, 0xff, 0x01, 0x35, 0x19, 0xff, 0x14, 0x69, 0x4a, 0xff, 0x17, 0x89, 0x67, 0xff, 0x20, 0xab, 0x87, 0xff, 0x27, 0xb9, 0x96, 0xff, 0x26, 0xb9, 0x96, 0xff, 0x23, 0xb9, 0x95, 0xff, 0x23, 0xba, 0x94, 0xff, 0x22, 0xba, 0x92, 0xff, 0x22, 0xba, 0x92, 0xff, 0x23, 0xba, 0x93, 0xff, 0x22, 0xba, 0x92, 0xff, 0x21, 0xb9, 0x90, 0xff, 0x21, 0xba, 0x90, 0xff, 0x20, 0xba, 0x90, 0xff, 0x20, 0xb9, 0x90, 0xff, 0x21, 0xb9, 0x90, 0xff, 0x21, 0xb9, 0x90, 0xff, 0x21, 0xb9, 0x91, 0xff, 0x21, 0xb8, 0x91, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x22, 0xb7, 0x91, 0xff, 0x21, 0xb8, 0x91, 0xff, 0x22, 0xb8, 0x91, 0xff, 0x22, 0xb8, 0x91, 0xff, 0x21, 0xb8, 0x92, 0xff, 0x21, 0xb8, 0x91, 0xff, 0x20, 0xb7, 0x8e, 0xff, 0x1f, 0xb8, 0x8c, 0xff, 0x1d, 0xb7, 0x8b, 0xff, 0x1d, 0xb6, 0x89, 0xff, 0x1d, 0xb6, 0x8a, 0xff, 0x1e, 0xb6, 0x8b, 0xff, 0x1d, 0xb5, 0x8a, 0xff, 0x20, 0xb6, 0x8e, 0xff, 0x21, 0xb6, 0x8e, 0xff, 0x20, 0xb5, 0x8e, 0xff, 0x1f, 0xb5, 0x8f, 0xff, 0x1f, 0xb5, 0x91, 0xff, 0x1d, 0xb2, 0x88, 0xff, 0x14, 0xac, 0x7a, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x14, 0xa7, 0x70, 0xff, 0x12, 0x84, 0x55, 0xff, 0x05, 0x45, 0x21, 0xff, 0x01, 0x1c, 0x04, 0xff, 0x01, 0x18, 0x03, 0xff, 0x03, 0x15, 0x02, 0xff, 0x05, 0x14, 0x02, 0xff, 0x06, 0x15, 0x04, 0xff, 0x04, 0x15, 0x06, 0xff, 0x03, 0x14, 0x05, 0xff, 0x04, 0x15, 0x07, 0xff, 0x03, 0x14, 0x06, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x14, 0x03, 0xff, 0x02, 0x15, 0x03, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x16, 0x04, 0xff, 0x03, 0x17, 0x05, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x17, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x03, 0x1a, 0x07, 0xff, 0x04, 0x1a, 0x08, 0xff, 0x03, 0x1a, 0x07, 0xff, 0x03, 0x19, 0x06, 0xff, 0x03, 0x18, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x05, 0x1d, 0x0a, 0xff, 0x03, 0x1d, 0x0b, 0xff, 0x03, 0x21, 0x0d, 0xff, 0x02, 0x28, 0x0e, 0xff, 0x09, 0x2a, 0x0f, 0xff, 0x05, 0x33, 0x13, 0xff, 0x08, 0x60, 0x35, 0xff, 0x12, 0x93, 0x5d, 0xff, 0x0f, 0xa3, 0x63, 0xff, 0x0f, 0xa6, 0x61, 0xff, 0x0f, 0xa9, 0x60, 0xff, 0x11, 0xa8, 0x62, 0xff, 0x11, 0xa8, 0x62, 0xff, 0x10, 0xa7, 0x5f, 0xff, 0x0e, 0xa6, 0x5c, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0xa1, 0x58, 0xff, 0x0b, 0xa1, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0b, 0x9f, 0x57, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0e, 0x9f, 0x57, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0c, 0x9b, 0x53, 0xff, 0x12, 0x98, 0x54, 0xff, 0x13, 0x98, 0x55, 0xff, 0x0d, 0x99, 0x52, 0xff, 0x11, 0x92, 0x5d, 0xff, 0x29, 0x7f, 0x7f, 0xff, 0x45, 0x7d, 0xa3, 0xff, 0x69, 0x97, 0xc6, 0xff, 0x81, 0xb5, 0xd7, 0xff, 0x98, 0xc3, 0xe4, 0xff, 0xa4, 0xcd, 0xea, 0xff, 0x41, 0x70, 0x6b, 0xff, 0x04, 0x32, 0x1e, 0xff, 0x1e, 0x55, 0x4b, 0xff, 0x5c, 0x96, 0x97, 0xff, 0x5b, 0x99, 0xaf, 0xff, 0x4f, 0x90, 0xaf, 0xff, 0x54, 0x95, 0xb2, 0xff, 0x3a, 0x78, 0x93, 0xff, 0x1c, 0x53, 0x67, 0xff, 0x20, 0x4e, 0x5f, 0xff, 0x28, 0x4a, 0x61, 0xff, 0x1e, 0x3d, 0x56, 0xff, 0x0d, 0x2f, 0x40, 0xff, 0x08, 0x3e, 0x5f, 0xff, 0x3c, 0xa9, 0xe4, 0xff, 0x43, 0xb7, 0xf3, 0xff, 0x1c, 0x7c, 0x85, 0xff, 0x11, 0x55, 0x3f, 0xff, 0x11, 0x35, 0x2e, 0xff, 0x0c, 0x31, 0x2c, 0xff, 0x11, 0x49, 0x3d, 0xff, 0x05, 0x47, 0x30, 0xff, 0x1c, 0x68, 0x5a, 0xff, 0x24, 0x6b, 0x74, 0xff, 0x06, 0x4d, 0x3f, 0xff, 0x10, 0x59, 0x32, 0xff, 0x10, 0x53, 0x35, 0xff, 0x0d, 0x51, 0x34, 0xff, 0x68, 0x90, 0x7d, 0xff, + 0x07, 0x9c, 0x66, 0xff, 0x0a, 0xa0, 0x68, 0xff, 0x10, 0xaa, 0x6b, 0xff, 0x0d, 0xaa, 0x64, 0xff, 0x03, 0x9c, 0x57, 0xff, 0x04, 0x96, 0x4c, 0xff, 0x08, 0x98, 0x4f, 0xff, 0x05, 0x9a, 0x59, 0xff, 0x08, 0x9f, 0x5b, 0xff, 0x08, 0xa1, 0x5c, 0xff, 0x0a, 0xa3, 0x5c, 0xff, 0x0c, 0xa5, 0x5c, 0xff, 0x0b, 0xa7, 0x5b, 0xff, 0x08, 0xa7, 0x59, 0xff, 0x05, 0xaa, 0x5a, 0xff, 0x03, 0xaf, 0x5f, 0xff, 0x0a, 0xb3, 0x64, 0xff, 0x0e, 0xb6, 0x67, 0xff, 0x0e, 0xb7, 0x68, 0xff, 0x0b, 0xb8, 0x6a, 0xff, 0x09, 0xb7, 0x69, 0xff, 0x06, 0xb7, 0x6a, 0xff, 0x08, 0xb0, 0x6d, 0xff, 0x0e, 0x96, 0x71, 0xff, 0x12, 0x8e, 0x80, 0xff, 0x15, 0x96, 0x99, 0xff, 0x14, 0x94, 0x92, 0xff, 0x10, 0x9b, 0x7e, 0xff, 0x08, 0xa1, 0x71, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x19, 0xa9, 0x75, 0xff, 0x1d, 0xa8, 0x7d, 0xff, 0x1e, 0xab, 0x81, 0xff, 0x1b, 0xac, 0x81, 0xff, 0x18, 0xad, 0x80, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x07, 0xa6, 0x6a, 0xff, 0x07, 0xa7, 0x6b, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0a, 0xaa, 0x6f, 0xff, 0x06, 0xa9, 0x70, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x15, 0xa7, 0x71, 0xff, 0x1f, 0x9b, 0x6a, 0xff, 0x0e, 0x54, 0x2f, 0xff, 0x00, 0x23, 0x05, 0xff, 0x01, 0x1a, 0x01, 0xff, 0x02, 0x16, 0x00, 0xff, 0x03, 0x14, 0x01, 0xff, 0x02, 0x15, 0x03, 0xff, 0x01, 0x15, 0x02, 0xff, 0x00, 0x16, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x03, 0x14, 0x05, 0xff, 0x02, 0x13, 0x04, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x01, 0x13, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x00, 0x17, 0x04, 0xff, 0x01, 0x17, 0x04, 0xff, 0x02, 0x18, 0x05, 0xff, 0x01, 0x17, 0x04, 0xff, 0x02, 0x17, 0x05, 0xff, 0x03, 0x17, 0x05, 0xff, 0x03, 0x17, 0x05, 0xff, 0x04, 0x17, 0x05, 0xff, 0x06, 0x18, 0x07, 0xff, 0x05, 0x18, 0x07, 0xff, 0x04, 0x18, 0x07, 0xff, 0x03, 0x18, 0x07, 0xff, 0x03, 0x18, 0x06, 0xff, 0x01, 0x18, 0x06, 0xff, 0x01, 0x17, 0x05, 0xff, 0x02, 0x1b, 0x07, 0xff, 0x00, 0x1f, 0x07, 0xff, 0x01, 0x1e, 0x07, 0xff, 0x07, 0x25, 0x10, 0xff, 0x02, 0x29, 0x14, 0xff, 0x0b, 0x52, 0x3a, 0xff, 0x1f, 0x83, 0x66, 0xff, 0x1e, 0x9c, 0x7b, 0xff, 0x14, 0x9c, 0x79, 0xff, 0x15, 0xa1, 0x7c, 0xff, 0x15, 0xa2, 0x7d, 0xff, 0x14, 0xa1, 0x7c, 0xff, 0x14, 0xa2, 0x7c, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x14, 0xa1, 0x7c, 0xff, 0x13, 0xa3, 0x7b, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0b, 0xa5, 0x71, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x76, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x14, 0xa8, 0x78, 0xff, 0x0b, 0x9c, 0x65, 0xff, 0x04, 0x94, 0x5b, 0xff, 0x14, 0xa6, 0x6d, 0xff, 0x1b, 0xb0, 0x75, 0xff, 0x0f, 0xa5, 0x6b, 0xff, 0x09, 0x9d, 0x66, 0xff, 0x15, 0xa9, 0x78, 0xff, 0x14, 0xa7, 0x79, 0xff, 0x13, 0xa4, 0x76, 0xff, 0x17, 0xa8, 0x78, 0xff, 0x0a, 0xa3, 0x71, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x12, 0xa6, 0x7a, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0c, 0xa9, 0x76, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x1d, 0x98, 0x68, 0xff, 0x0b, 0x64, 0x3c, 0xff, 0x00, 0x24, 0x06, 0xff, 0x01, 0x1d, 0x03, 0xff, 0x01, 0x15, 0x01, 0xff, 0x06, 0x13, 0x01, 0xff, 0x08, 0x14, 0x03, 0xff, 0x07, 0x16, 0x06, 0xff, 0x02, 0x18, 0x05, 0xff, 0x00, 0x17, 0x04, 0xff, 0x02, 0x19, 0x06, 0xff, 0x04, 0x18, 0x06, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x16, 0x04, 0xff, 0x01, 0x14, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x03, 0x15, 0x04, 0xff, 0x04, 0x17, 0x06, 0xff, 0x04, 0x17, 0x06, 0xff, 0x03, 0x17, 0x05, 0xff, 0x04, 0x18, 0x06, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x17, 0x05, 0xff, 0x04, 0x18, 0x07, 0xff, 0x05, 0x19, 0x08, 0xff, 0x04, 0x19, 0x07, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x03, 0x19, 0x06, 0xff, 0x02, 0x1a, 0x06, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x02, 0x1f, 0x0a, 0xff, 0x01, 0x23, 0x0d, 0xff, 0x01, 0x24, 0x0e, 0xff, 0x05, 0x2b, 0x13, 0xff, 0x01, 0x30, 0x17, 0xff, 0x0d, 0x64, 0x46, 0xff, 0x1c, 0x93, 0x72, 0xff, 0x24, 0xb3, 0x90, 0xff, 0x27, 0xb9, 0x97, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x25, 0xba, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xba, 0x95, 0xff, 0x24, 0xb9, 0x94, 0xff, 0x23, 0xb8, 0x92, 0xff, 0x23, 0xb9, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x23, 0xb8, 0x92, 0xff, 0x23, 0xb8, 0x92, 0xff, 0x23, 0xb7, 0x93, 0xff, 0x23, 0xb7, 0x93, 0xff, 0x24, 0xb6, 0x92, 0xff, 0x22, 0xb7, 0x91, 0xff, 0x1f, 0xb8, 0x90, 0xff, 0x21, 0xb9, 0x91, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x21, 0xb8, 0x91, 0xff, 0x20, 0xb7, 0x90, 0xff, 0x1d, 0xb5, 0x8b, 0xff, 0x1b, 0xb4, 0x88, 0xff, 0x19, 0xb3, 0x85, 0xff, 0x19, 0xb2, 0x85, 0xff, 0x1a, 0xb3, 0x86, 0xff, 0x1e, 0xb5, 0x89, 0xff, 0x1d, 0xb4, 0x89, 0xff, 0x20, 0xb4, 0x8c, 0xff, 0x21, 0xb5, 0x8d, 0xff, 0x21, 0xb4, 0x8e, 0xff, 0x20, 0xb4, 0x8f, 0xff, 0x1d, 0xb4, 0x90, 0xff, 0x1e, 0xb3, 0x8a, 0xff, 0x1b, 0xaf, 0x81, 0xff, 0x0f, 0xa5, 0x72, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x17, 0xa6, 0x73, 0xff, 0x1f, 0x8c, 0x61, 0xff, 0x0a, 0x45, 0x23, 0xff, 0x01, 0x1e, 0x06, 0xff, 0x03, 0x15, 0x01, 0xff, 0x03, 0x14, 0x00, 0xff, 0x03, 0x13, 0x01, 0xff, 0x02, 0x13, 0x02, 0xff, 0x01, 0x11, 0x02, 0xff, 0x00, 0x10, 0x03, 0xff, 0x01, 0x12, 0x04, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x14, 0x03, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x14, 0x03, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x16, 0x05, 0xff, 0x02, 0x15, 0x04, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x17, 0x05, 0xff, 0x04, 0x17, 0x06, 0xff, 0x04, 0x17, 0x06, 0xff, 0x03, 0x16, 0x05, 0xff, 0x04, 0x18, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x1c, 0x05, 0xff, 0x02, 0x23, 0x06, 0xff, 0x05, 0x42, 0x1c, 0xff, 0x1c, 0x8a, 0x57, 0xff, 0x16, 0xa0, 0x64, 0xff, 0x0e, 0xa4, 0x63, 0xff, 0x10, 0xa7, 0x63, 0xff, 0x0d, 0xa6, 0x60, 0xff, 0x11, 0xa7, 0x64, 0xff, 0x10, 0xa7, 0x61, 0xff, 0x0e, 0xa6, 0x5f, 0xff, 0x0d, 0xa5, 0x5c, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0d, 0xa5, 0x5b, 0xff, 0x0c, 0xa4, 0x5a, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0d, 0xa4, 0x5a, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0e, 0xa2, 0x59, 0xff, 0x0d, 0xa2, 0x58, 0xff, 0x0e, 0xa2, 0x59, 0xff, 0x0d, 0xa1, 0x58, 0xff, 0x0d, 0xa1, 0x58, 0xff, 0x0c, 0xa2, 0x59, 0xff, 0x0b, 0xa2, 0x59, 0xff, 0x0c, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0c, 0x9a, 0x52, 0xff, 0x12, 0x97, 0x53, 0xff, 0x12, 0x96, 0x54, 0xff, 0x0b, 0x97, 0x52, 0xff, 0x10, 0x92, 0x59, 0xff, 0x20, 0x7f, 0x6f, 0xff, 0x3a, 0x7e, 0x8e, 0xff, 0x56, 0x8d, 0xaf, 0xff, 0x7b, 0xb4, 0xd1, 0xff, 0x95, 0xc5, 0xe0, 0xff, 0x95, 0xc3, 0xd8, 0xff, 0x26, 0x55, 0x4e, 0xff, 0x01, 0x2e, 0x1e, 0xff, 0x41, 0x7c, 0x80, 0xff, 0x5f, 0x9e, 0xab, 0xff, 0x52, 0x95, 0xb5, 0xff, 0x40, 0x84, 0xa6, 0xff, 0x3e, 0x7f, 0x9f, 0xff, 0x40, 0x7e, 0xa1, 0xff, 0x2d, 0x67, 0x80, 0xff, 0x20, 0x51, 0x66, 0xff, 0x26, 0x4d, 0x65, 0xff, 0x26, 0x48, 0x5f, 0xff, 0x1a, 0x41, 0x48, 0xff, 0x0b, 0x48, 0x56, 0xff, 0x2f, 0x95, 0xcb, 0xff, 0x36, 0x95, 0xe9, 0xff, 0x25, 0x6c, 0x96, 0xff, 0x1a, 0x52, 0x4e, 0xff, 0x0f, 0x37, 0x2b, 0xff, 0x06, 0x35, 0x2a, 0xff, 0x13, 0x53, 0x46, 0xff, 0x09, 0x52, 0x3b, 0xff, 0x19, 0x70, 0x4f, 0xff, 0x1a, 0x76, 0x53, 0xff, 0x0d, 0x63, 0x3d, 0xff, 0x13, 0x62, 0x3a, 0xff, 0x14, 0x5c, 0x37, 0xff, 0x0e, 0x55, 0x30, 0xff, 0x61, 0x82, 0x77, 0xff, + 0x0e, 0xa1, 0x66, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x61, 0xff, 0x03, 0x94, 0x4d, 0xff, 0x07, 0x91, 0x50, 0xff, 0x03, 0x98, 0x51, 0xff, 0x03, 0x9a, 0x50, 0xff, 0x08, 0x9f, 0x59, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0a, 0xa0, 0x5b, 0xff, 0x0a, 0xa3, 0x5a, 0xff, 0x08, 0xa6, 0x5a, 0xff, 0x05, 0xa8, 0x59, 0xff, 0x04, 0xa8, 0x59, 0xff, 0x06, 0xaa, 0x5b, 0xff, 0x0a, 0xaf, 0x5f, 0xff, 0x0a, 0xb4, 0x63, 0xff, 0x09, 0xb6, 0x66, 0xff, 0x09, 0xb5, 0x69, 0xff, 0x10, 0xb7, 0x70, 0xff, 0x06, 0xa4, 0x63, 0xff, 0x07, 0x9c, 0x65, 0xff, 0x17, 0x9f, 0x7a, 0xff, 0x17, 0x9b, 0x7f, 0xff, 0x12, 0x9c, 0x80, 0xff, 0x0d, 0x9d, 0x78, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x06, 0xa6, 0x68, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x12, 0xa6, 0x75, 0xff, 0x13, 0xa8, 0x79, 0xff, 0x18, 0xad, 0x7f, 0xff, 0x18, 0xae, 0x7e, 0xff, 0x14, 0xac, 0x79, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6a, 0xff, 0x04, 0xa7, 0x6a, 0xff, 0x06, 0xa8, 0x6c, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0e, 0xac, 0x74, 0xff, 0x11, 0xac, 0x76, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x17, 0xa9, 0x74, 0xff, 0x20, 0x9c, 0x6b, 0xff, 0x12, 0x71, 0x46, 0xff, 0x03, 0x32, 0x13, 0xff, 0x00, 0x1b, 0x04, 0xff, 0x01, 0x13, 0x00, 0xff, 0x01, 0x13, 0x01, 0xff, 0x00, 0x13, 0x00, 0xff, 0x01, 0x13, 0x01, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x11, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x02, 0x13, 0x02, 0xff, 0x02, 0x14, 0x03, 0xff, 0x03, 0x14, 0x03, 0xff, 0x03, 0x14, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x03, 0x14, 0x03, 0xff, 0x03, 0x15, 0x04, 0xff, 0x03, 0x17, 0x05, 0xff, 0x04, 0x17, 0x05, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x16, 0x04, 0xff, 0x01, 0x18, 0x01, 0xff, 0x01, 0x16, 0x01, 0xff, 0x01, 0x16, 0x03, 0xff, 0x01, 0x26, 0x10, 0xff, 0x18, 0x70, 0x56, 0xff, 0x28, 0x9d, 0x7f, 0xff, 0x1e, 0xa5, 0x84, 0xff, 0x14, 0x9f, 0x7d, 0xff, 0x15, 0xa1, 0x7c, 0xff, 0x15, 0xa1, 0x7b, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x16, 0xa1, 0x7f, 0xff, 0x15, 0xa3, 0x7c, 0xff, 0x13, 0xa3, 0x7b, 0xff, 0x12, 0xa3, 0x7a, 0xff, 0x10, 0xa1, 0x7a, 0xff, 0x0e, 0xa1, 0x77, 0xff, 0x0c, 0xa2, 0x72, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa3, 0x72, 0xff, 0x0c, 0xa4, 0x73, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x12, 0xa3, 0x78, 0xff, 0x16, 0xa8, 0x78, 0xff, 0x10, 0xa0, 0x6e, 0xff, 0x05, 0x93, 0x57, 0xff, 0x11, 0xa5, 0x63, 0xff, 0x16, 0xac, 0x6c, 0xff, 0x07, 0x9c, 0x5f, 0xff, 0x16, 0xa9, 0x75, 0xff, 0x14, 0xa5, 0x76, 0xff, 0x16, 0xa6, 0x77, 0xff, 0x14, 0xa3, 0x72, 0xff, 0x04, 0x90, 0x5e, 0xff, 0x16, 0xa6, 0x76, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x11, 0xa6, 0x7b, 0xff, 0x0c, 0xa7, 0x78, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x19, 0xa9, 0x75, 0xff, 0x1a, 0x9c, 0x6b, 0xff, 0x0f, 0x5f, 0x38, 0xff, 0x03, 0x2e, 0x0f, 0xff, 0x00, 0x19, 0x01, 0xff, 0x01, 0x14, 0x01, 0xff, 0x04, 0x13, 0x02, 0xff, 0x05, 0x13, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x02, 0x13, 0x02, 0xff, 0x02, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x14, 0x04, 0xff, 0x03, 0x15, 0x05, 0xff, 0x03, 0x15, 0x05, 0xff, 0x02, 0x15, 0x04, 0xff, 0x03, 0x14, 0x04, 0xff, 0x04, 0x16, 0x05, 0xff, 0x04, 0x16, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x01, 0x18, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x03, 0x18, 0x05, 0xff, 0x05, 0x18, 0x06, 0xff, 0x03, 0x18, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x03, 0x1a, 0x07, 0xff, 0x04, 0x1b, 0x08, 0xff, 0x03, 0x1f, 0x0b, 0xff, 0x00, 0x28, 0x10, 0xff, 0x13, 0x70, 0x52, 0xff, 0x25, 0xa8, 0x86, 0xff, 0x25, 0xba, 0x97, 0xff, 0x27, 0xb9, 0x98, 0xff, 0x29, 0xb9, 0x98, 0xff, 0x27, 0xb9, 0x97, 0xff, 0x27, 0xba, 0x97, 0xff, 0x27, 0xba, 0x97, 0xff, 0x26, 0xb9, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x24, 0xb7, 0x93, 0xff, 0x24, 0xb8, 0x93, 0xff, 0x24, 0xb9, 0x93, 0xff, 0x24, 0xba, 0x94, 0xff, 0x24, 0xb9, 0x93, 0xff, 0x24, 0xb8, 0x93, 0xff, 0x24, 0xb8, 0x93, 0xff, 0x24, 0xb7, 0x94, 0xff, 0x24, 0xb7, 0x94, 0xff, 0x25, 0xb7, 0x94, 0xff, 0x23, 0xb8, 0x93, 0xff, 0x20, 0xb9, 0x91, 0xff, 0x22, 0xbb, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x1f, 0xb7, 0x8f, 0xff, 0x1d, 0xb5, 0x8b, 0xff, 0x1b, 0xb3, 0x87, 0xff, 0x19, 0xb2, 0x84, 0xff, 0x16, 0xaf, 0x81, 0xff, 0x16, 0xaf, 0x82, 0xff, 0x16, 0xae, 0x82, 0xff, 0x1a, 0xb1, 0x85, 0xff, 0x1d, 0xb3, 0x89, 0xff, 0x1f, 0xb3, 0x8c, 0xff, 0x20, 0xb4, 0x8d, 0xff, 0x21, 0xb4, 0x8e, 0xff, 0x21, 0xb4, 0x8e, 0xff, 0x1e, 0xb2, 0x8e, 0xff, 0x1c, 0xb0, 0x89, 0xff, 0x1c, 0xb0, 0x86, 0xff, 0x14, 0xab, 0x7b, 0xff, 0x09, 0xa5, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x1b, 0xa7, 0x74, 0xff, 0x20, 0x97, 0x68, 0xff, 0x17, 0x70, 0x48, 0xff, 0x06, 0x41, 0x20, 0xff, 0x01, 0x27, 0x0c, 0xff, 0x00, 0x17, 0x02, 0xff, 0x00, 0x13, 0x00, 0xff, 0x01, 0x11, 0x02, 0xff, 0x02, 0x11, 0x03, 0xff, 0x03, 0x10, 0x01, 0xff, 0x03, 0x12, 0x01, 0xff, 0x03, 0x12, 0x01, 0xff, 0x03, 0x12, 0x01, 0xff, 0x02, 0x10, 0x00, 0xff, 0x02, 0x11, 0x00, 0xff, 0x02, 0x11, 0x00, 0xff, 0x02, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x02, 0x12, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x02, 0x14, 0x03, 0xff, 0x02, 0x13, 0x03, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x16, 0x01, 0xff, 0x01, 0x37, 0x14, 0xff, 0x0f, 0x77, 0x47, 0xff, 0x14, 0x9e, 0x62, 0xff, 0x0f, 0xa2, 0x62, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0f, 0xa4, 0x62, 0xff, 0x0e, 0xa3, 0x62, 0xff, 0x0f, 0xa5, 0x63, 0xff, 0x0e, 0xa5, 0x61, 0xff, 0x0d, 0xa4, 0x5f, 0xff, 0x0c, 0xa4, 0x5d, 0xff, 0x0c, 0xa3, 0x5b, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0e, 0xa6, 0x5b, 0xff, 0x0e, 0xa6, 0x5a, 0xff, 0x0e, 0xa3, 0x59, 0xff, 0x0d, 0xa3, 0x58, 0xff, 0x0e, 0xa3, 0x59, 0xff, 0x0d, 0xa2, 0x58, 0xff, 0x0d, 0xa2, 0x58, 0xff, 0x0c, 0xa2, 0x59, 0xff, 0x0b, 0xa2, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0b, 0x9c, 0x53, 0xff, 0x0b, 0x9a, 0x51, 0xff, 0x10, 0x97, 0x51, 0xff, 0x10, 0x96, 0x52, 0xff, 0x09, 0x97, 0x4f, 0xff, 0x0b, 0x93, 0x53, 0xff, 0x15, 0x80, 0x5b, 0xff, 0x26, 0x78, 0x6e, 0xff, 0x38, 0x7a, 0x8d, 0xff, 0x55, 0x93, 0xac, 0xff, 0x69, 0x9e, 0xaf, 0xff, 0x43, 0x7b, 0x7f, 0xff, 0x03, 0x36, 0x22, 0xff, 0x08, 0x41, 0x31, 0xff, 0x4e, 0x8c, 0xa0, 0xff, 0x4f, 0x90, 0xad, 0xff, 0x45, 0x8a, 0xaf, 0xff, 0x45, 0x87, 0xa9, 0xff, 0x47, 0x87, 0xac, 0xff, 0x42, 0x83, 0xae, 0xff, 0x3f, 0x81, 0xa7, 0xff, 0x3f, 0x7e, 0x9d, 0xff, 0x1f, 0x52, 0x70, 0xff, 0x1a, 0x48, 0x5f, 0xff, 0x24, 0x54, 0x54, 0xff, 0x1a, 0x5c, 0x55, 0xff, 0x1c, 0x6b, 0x90, 0xff, 0x28, 0x59, 0xb4, 0xff, 0x38, 0x48, 0x9f, 0xff, 0x2b, 0x43, 0x6b, 0xff, 0x16, 0x3d, 0x3f, 0xff, 0x10, 0x42, 0x42, 0xff, 0x18, 0x56, 0x4c, 0xff, 0x0c, 0x55, 0x38, 0xff, 0x18, 0x78, 0x47, 0xff, 0x17, 0x7f, 0x42, 0xff, 0x0b, 0x68, 0x3a, 0xff, 0x0f, 0x60, 0x3c, 0xff, 0x11, 0x5a, 0x34, 0xff, 0x03, 0x48, 0x27, 0xff, 0x74, 0x90, 0x8b, 0xff, + 0x0f, 0xa0, 0x61, 0xff, 0x06, 0x98, 0x57, 0xff, 0x02, 0x93, 0x4e, 0xff, 0x0d, 0x93, 0x4e, 0xff, 0x11, 0x93, 0x55, 0xff, 0x06, 0x95, 0x54, 0xff, 0x04, 0x9a, 0x52, 0xff, 0x07, 0x9f, 0x55, 0xff, 0x08, 0x9f, 0x56, 0xff, 0x0d, 0xa2, 0x5a, 0xff, 0x0c, 0xa1, 0x5a, 0xff, 0x0b, 0xa3, 0x5d, 0xff, 0x07, 0xa3, 0x5d, 0xff, 0x04, 0xa4, 0x5f, 0xff, 0x06, 0xa5, 0x5f, 0xff, 0x07, 0xa5, 0x5d, 0xff, 0x04, 0xa9, 0x5f, 0xff, 0x01, 0xb1, 0x66, 0xff, 0x02, 0xb5, 0x6b, 0xff, 0x0b, 0xb6, 0x75, 0xff, 0x06, 0xa2, 0x69, 0xff, 0x0f, 0x98, 0x69, 0xff, 0x13, 0x9d, 0x6c, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa0, 0x71, 0xff, 0x10, 0xa0, 0x70, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0b, 0xa8, 0x66, 0xff, 0x0a, 0xa6, 0x66, 0xff, 0x0a, 0xa2, 0x6f, 0xff, 0x09, 0xa1, 0x73, 0xff, 0x0d, 0xaa, 0x78, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x12, 0xae, 0x79, 0xff, 0x0e, 0xac, 0x73, 0xff, 0x07, 0xa9, 0x6c, 0xff, 0x05, 0xa8, 0x6a, 0xff, 0x03, 0xa7, 0x6b, 0xff, 0x05, 0xa6, 0x6c, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x12, 0xab, 0x76, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xab, 0x74, 0xff, 0x1a, 0xaa, 0x75, 0xff, 0x1c, 0x8a, 0x5e, 0xff, 0x12, 0x62, 0x3e, 0xff, 0x05, 0x39, 0x1c, 0xff, 0x02, 0x20, 0x09, 0xff, 0x00, 0x16, 0x03, 0xff, 0x01, 0x12, 0x00, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x03, 0xff, 0x02, 0x10, 0x03, 0xff, 0x01, 0x10, 0x03, 0xff, 0x02, 0x10, 0x04, 0xff, 0x02, 0x11, 0x03, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x02, 0x11, 0x01, 0xff, 0x03, 0x11, 0x00, 0xff, 0x03, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x11, 0x01, 0xff, 0x03, 0x13, 0x02, 0xff, 0x02, 0x12, 0x02, 0xff, 0x02, 0x12, 0x01, 0xff, 0x01, 0x13, 0x00, 0xff, 0x02, 0x12, 0x00, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x14, 0x51, 0x3b, 0xff, 0x2e, 0x98, 0x7d, 0xff, 0x25, 0xa9, 0x88, 0xff, 0x1b, 0xa8, 0x85, 0xff, 0x16, 0xa1, 0x7e, 0xff, 0x16, 0xa2, 0x7b, 0xff, 0x15, 0xa3, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x12, 0xa2, 0x7c, 0xff, 0x12, 0xa2, 0x7c, 0xff, 0x17, 0xa2, 0x80, 0xff, 0x16, 0xa2, 0x7e, 0xff, 0x14, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x11, 0xa1, 0x7b, 0xff, 0x0f, 0xa1, 0x79, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x0f, 0xa5, 0x76, 0xff, 0x0f, 0xa5, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0f, 0xa4, 0x7a, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x12, 0xa2, 0x7d, 0xff, 0x15, 0xa4, 0x7e, 0xff, 0x16, 0xa3, 0x79, 0xff, 0x16, 0xa5, 0x78, 0xff, 0x10, 0xa3, 0x65, 0xff, 0x04, 0x93, 0x4f, 0xff, 0x13, 0xa6, 0x63, 0xff, 0x0f, 0x9f, 0x61, 0xff, 0x0f, 0xa0, 0x68, 0xff, 0x16, 0xa9, 0x74, 0xff, 0x17, 0xa8, 0x74, 0xff, 0x08, 0x8d, 0x58, 0xff, 0x0c, 0x90, 0x5c, 0xff, 0x0f, 0x97, 0x68, 0xff, 0x14, 0xa4, 0x79, 0xff, 0x0e, 0xa4, 0x7a, 0xff, 0x0c, 0xa8, 0x7a, 0xff, 0x0d, 0xaa, 0x78, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x11, 0xa9, 0x74, 0xff, 0x27, 0xa1, 0x73, 0xff, 0x1d, 0x7d, 0x56, 0xff, 0x07, 0x47, 0x25, 0xff, 0x02, 0x25, 0x0c, 0xff, 0x00, 0x16, 0x03, 0xff, 0x01, 0x14, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x00, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x03, 0x12, 0x02, 0xff, 0x02, 0x11, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x02, 0x13, 0x02, 0xff, 0x02, 0x14, 0x03, 0xff, 0x03, 0x14, 0x04, 0xff, 0x02, 0x14, 0x04, 0xff, 0x00, 0x14, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x02, 0x12, 0x01, 0xff, 0x02, 0x13, 0x01, 0xff, 0x00, 0x18, 0x04, 0xff, 0x06, 0x3b, 0x22, 0xff, 0x2e, 0x9a, 0x7d, 0xff, 0x2c, 0xb7, 0x96, 0xff, 0x21, 0xb9, 0x97, 0xff, 0x27, 0xb9, 0x99, 0xff, 0x29, 0xb8, 0x99, 0xff, 0x27, 0xb9, 0x98, 0xff, 0x27, 0xb9, 0x97, 0xff, 0x27, 0xb9, 0x97, 0xff, 0x27, 0xba, 0x97, 0xff, 0x27, 0xb9, 0x96, 0xff, 0x25, 0xb7, 0x94, 0xff, 0x26, 0xb8, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x25, 0xb7, 0x94, 0xff, 0x24, 0xb7, 0x94, 0xff, 0x25, 0xb8, 0x95, 0xff, 0x24, 0xb8, 0x93, 0xff, 0x21, 0xba, 0x91, 0xff, 0x20, 0xba, 0x91, 0xff, 0x1e, 0xb8, 0x8e, 0xff, 0x1b, 0xb3, 0x8a, 0xff, 0x18, 0xaf, 0x84, 0xff, 0x17, 0xaf, 0x82, 0xff, 0x17, 0xae, 0x81, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x1c, 0xb1, 0x86, 0xff, 0x1d, 0xb1, 0x88, 0xff, 0x1f, 0xb3, 0x8a, 0xff, 0x20, 0xb3, 0x8c, 0xff, 0x20, 0xb3, 0x8b, 0xff, 0x1e, 0xb0, 0x8b, 0xff, 0x1e, 0xb0, 0x89, 0xff, 0x1c, 0xb2, 0x88, 0xff, 0x16, 0xb1, 0x83, 0xff, 0x13, 0xaa, 0x7a, 0xff, 0x12, 0xa6, 0x73, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x07, 0xa9, 0x72, 0xff, 0x16, 0xa9, 0x75, 0xff, 0x19, 0x99, 0x6a, 0xff, 0x18, 0x82, 0x57, 0xff, 0x15, 0x5f, 0x3b, 0xff, 0x09, 0x40, 0x22, 0xff, 0x01, 0x1e, 0x09, 0xff, 0x01, 0x15, 0x03, 0xff, 0x04, 0x11, 0x01, 0xff, 0x02, 0x10, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x03, 0x11, 0x01, 0xff, 0x03, 0x10, 0x01, 0xff, 0x03, 0x10, 0x00, 0xff, 0x04, 0x10, 0x00, 0xff, 0x04, 0x10, 0x01, 0xff, 0x03, 0x10, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x13, 0x01, 0xff, 0x01, 0x1e, 0x07, 0xff, 0x07, 0x3e, 0x1f, 0xff, 0x13, 0x7c, 0x50, 0xff, 0x10, 0x9f, 0x66, 0xff, 0x08, 0xa5, 0x63, 0xff, 0x0c, 0xa6, 0x61, 0xff, 0x0d, 0xa4, 0x5f, 0xff, 0x10, 0xa4, 0x62, 0xff, 0x10, 0xa3, 0x63, 0xff, 0x10, 0xa5, 0x64, 0xff, 0x0e, 0xa4, 0x61, 0xff, 0x0c, 0xa3, 0x5f, 0xff, 0x0c, 0xa3, 0x5d, 0xff, 0x0c, 0xa3, 0x5b, 0xff, 0x0c, 0xa3, 0x5b, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x0e, 0xa5, 0x5c, 0xff, 0x0e, 0xa5, 0x5b, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0e, 0xa3, 0x59, 0xff, 0x0e, 0xa3, 0x59, 0xff, 0x0e, 0xa3, 0x59, 0xff, 0x0d, 0xa2, 0x59, 0xff, 0x0e, 0xa3, 0x59, 0xff, 0x0c, 0xa2, 0x59, 0xff, 0x0b, 0xa2, 0x59, 0xff, 0x0c, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0x9f, 0x57, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x0d, 0x9c, 0x54, 0xff, 0x0b, 0x9a, 0x50, 0xff, 0x0e, 0x97, 0x50, 0xff, 0x0d, 0x96, 0x50, 0xff, 0x08, 0x98, 0x4f, 0xff, 0x07, 0x94, 0x4f, 0xff, 0x17, 0x8c, 0x57, 0xff, 0x15, 0x78, 0x56, 0xff, 0x0b, 0x5b, 0x55, 0xff, 0x15, 0x60, 0x66, 0xff, 0x11, 0x54, 0x54, 0xff, 0x06, 0x43, 0x38, 0xff, 0x07, 0x46, 0x2c, 0xff, 0x2b, 0x67, 0x5b, 0xff, 0x4b, 0x89, 0xa6, 0xff, 0x33, 0x72, 0x99, 0xff, 0x34, 0x78, 0xa3, 0xff, 0x38, 0x7a, 0xa0, 0xff, 0x27, 0x66, 0x97, 0xff, 0x23, 0x6b, 0xa9, 0xff, 0x25, 0x71, 0xac, 0xff, 0x35, 0x7f, 0xb7, 0xff, 0x22, 0x5f, 0x94, 0xff, 0x12, 0x47, 0x6a, 0xff, 0x17, 0x4b, 0x4e, 0xff, 0x18, 0x51, 0x4d, 0xff, 0x20, 0x50, 0x75, 0xff, 0x30, 0x34, 0x94, 0xff, 0x62, 0x40, 0xc1, 0xff, 0x46, 0x3d, 0x97, 0xff, 0x2b, 0x41, 0x67, 0xff, 0x22, 0x41, 0x66, 0xff, 0x1b, 0x4d, 0x53, 0xff, 0x12, 0x5b, 0x3b, 0xff, 0x17, 0x79, 0x46, 0xff, 0x13, 0x7a, 0x40, 0xff, 0x0b, 0x64, 0x40, 0xff, 0x0d, 0x5c, 0x3c, 0xff, 0x0b, 0x54, 0x30, 0xff, 0x07, 0x4b, 0x32, 0xff, 0x91, 0xa9, 0xa3, 0xff, + 0x07, 0x8f, 0x50, 0xff, 0x05, 0x8f, 0x4c, 0xff, 0x05, 0x92, 0x4d, 0xff, 0x0c, 0x94, 0x51, 0xff, 0x0e, 0x94, 0x54, 0xff, 0x07, 0x95, 0x53, 0xff, 0x04, 0x96, 0x51, 0xff, 0x04, 0x9a, 0x53, 0xff, 0x09, 0x9e, 0x57, 0xff, 0x0e, 0xa2, 0x5c, 0xff, 0x0f, 0xa3, 0x5d, 0xff, 0x0d, 0xa3, 0x5d, 0xff, 0x08, 0xa2, 0x5b, 0xff, 0x06, 0xa3, 0x5c, 0xff, 0x06, 0xa5, 0x5c, 0xff, 0x03, 0xa5, 0x59, 0xff, 0x03, 0xac, 0x60, 0xff, 0x08, 0xb3, 0x6a, 0xff, 0x0c, 0xb2, 0x6e, 0xff, 0x05, 0x9e, 0x61, 0xff, 0x06, 0x96, 0x60, 0xff, 0x12, 0xa0, 0x6d, 0xff, 0x10, 0xa2, 0x6e, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x08, 0xa5, 0x6a, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x09, 0xa5, 0x73, 0xff, 0x1a, 0xb6, 0x88, 0xff, 0x0f, 0xae, 0x7c, 0xff, 0x0b, 0xab, 0x75, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x07, 0xaa, 0x6c, 0xff, 0x05, 0xa8, 0x6b, 0xff, 0x08, 0xa7, 0x6c, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x09, 0xa7, 0x6c, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x15, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x05, 0xad, 0x74, 0xff, 0x0b, 0xad, 0x75, 0xff, 0x19, 0xb0, 0x7a, 0xff, 0x20, 0xab, 0x77, 0xff, 0x20, 0x96, 0x67, 0xff, 0x19, 0x79, 0x4f, 0xff, 0x0a, 0x53, 0x2d, 0xff, 0x03, 0x2e, 0x10, 0xff, 0x00, 0x15, 0x02, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x0e, 0x02, 0xff, 0x00, 0x0e, 0x02, 0xff, 0x02, 0x0f, 0x04, 0xff, 0x01, 0x10, 0x04, 0xff, 0x00, 0x10, 0x04, 0xff, 0x01, 0x10, 0x03, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x03, 0x11, 0x02, 0xff, 0x04, 0x11, 0x02, 0xff, 0x05, 0x0f, 0x02, 0xff, 0x04, 0x10, 0x02, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x04, 0x0f, 0x02, 0xff, 0x04, 0x10, 0x02, 0xff, 0x03, 0x0f, 0x02, 0xff, 0x01, 0x10, 0x00, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x01, 0x19, 0x08, 0xff, 0x15, 0x50, 0x3b, 0xff, 0x32, 0x8c, 0x76, 0xff, 0x2b, 0xa5, 0x89, 0xff, 0x1d, 0xaa, 0x89, 0xff, 0x16, 0xa8, 0x84, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x14, 0xa4, 0x7b, 0xff, 0x14, 0xa3, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7b, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x14, 0xa3, 0x7b, 0xff, 0x17, 0xa3, 0x7e, 0xff, 0x17, 0xa2, 0x7d, 0xff, 0x14, 0xa0, 0x7b, 0xff, 0x15, 0xa1, 0x7c, 0xff, 0x14, 0xa1, 0x7c, 0xff, 0x13, 0xa0, 0x7c, 0xff, 0x13, 0xa1, 0x7b, 0xff, 0x13, 0xa2, 0x7a, 0xff, 0x11, 0xa1, 0x7b, 0xff, 0x12, 0xa2, 0x7a, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa2, 0x79, 0xff, 0x0e, 0xa3, 0x79, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa4, 0x7a, 0xff, 0x0f, 0xa3, 0x7d, 0xff, 0x10, 0xa4, 0x7d, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x16, 0xa5, 0x79, 0xff, 0x16, 0xa6, 0x76, 0xff, 0x19, 0xab, 0x70, 0xff, 0x0d, 0x9d, 0x5f, 0xff, 0x0a, 0x95, 0x56, 0xff, 0x14, 0x9d, 0x5f, 0xff, 0x0a, 0x98, 0x58, 0xff, 0x16, 0xb0, 0x6f, 0xff, 0x10, 0x9e, 0x5f, 0xff, 0x05, 0x76, 0x3c, 0xff, 0x0a, 0x83, 0x51, 0xff, 0x15, 0x97, 0x6a, 0xff, 0x18, 0xa4, 0x79, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x0d, 0xa8, 0x7b, 0xff, 0x0e, 0xa9, 0x7a, 0xff, 0x0e, 0xa9, 0x76, 0xff, 0x0e, 0xaa, 0x75, 0xff, 0x14, 0xa7, 0x73, 0xff, 0x1b, 0xa5, 0x75, 0xff, 0x1c, 0x97, 0x6a, 0xff, 0x14, 0x7c, 0x52, 0xff, 0x0b, 0x56, 0x32, 0xff, 0x07, 0x39, 0x1c, 0xff, 0x02, 0x1f, 0x07, 0xff, 0x00, 0x17, 0x02, 0xff, 0x01, 0x13, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x03, 0x11, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x02, 0x11, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x11, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x02, 0x11, 0x03, 0xff, 0x03, 0x11, 0x03, 0xff, 0x02, 0x0f, 0x01, 0xff, 0x02, 0x11, 0x02, 0xff, 0x02, 0x11, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x00, 0x11, 0x02, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x00, 0x14, 0x01, 0xff, 0x00, 0x16, 0x03, 0xff, 0x00, 0x20, 0x09, 0xff, 0x02, 0x28, 0x10, 0xff, 0x09, 0x45, 0x2b, 0xff, 0x25, 0x81, 0x67, 0xff, 0x39, 0xb5, 0x98, 0xff, 0x2b, 0xb9, 0x9a, 0xff, 0x24, 0xba, 0x98, 0xff, 0x26, 0xba, 0x98, 0xff, 0x27, 0xb9, 0x98, 0xff, 0x26, 0xb9, 0x98, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x27, 0xba, 0x97, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x26, 0xb9, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x26, 0xb8, 0x96, 0xff, 0x25, 0xb7, 0x95, 0xff, 0x24, 0xb7, 0x95, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x95, 0xff, 0x24, 0xba, 0x94, 0xff, 0x24, 0xba, 0x94, 0xff, 0x22, 0xb9, 0x91, 0xff, 0x22, 0xb8, 0x90, 0xff, 0x22, 0xb8, 0x90, 0xff, 0x1e, 0xb3, 0x8d, 0xff, 0x18, 0xae, 0x86, 0xff, 0x17, 0xad, 0x83, 0xff, 0x15, 0xac, 0x80, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x16, 0xad, 0x80, 0xff, 0x19, 0xb0, 0x84, 0xff, 0x1c, 0xb2, 0x87, 0xff, 0x1d, 0xb4, 0x89, 0xff, 0x1d, 0xb3, 0x89, 0xff, 0x1d, 0xb1, 0x88, 0xff, 0x1d, 0xb2, 0x86, 0xff, 0x1c, 0xb3, 0x86, 0xff, 0x1c, 0xb3, 0x86, 0xff, 0x1f, 0xb4, 0x86, 0xff, 0x18, 0xad, 0x7e, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x06, 0xa3, 0x71, 0xff, 0x08, 0xa3, 0x6f, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x16, 0xa5, 0x71, 0xff, 0x1e, 0xa0, 0x70, 0xff, 0x20, 0x93, 0x67, 0xff, 0x14, 0x6e, 0x49, 0xff, 0x09, 0x4e, 0x2e, 0xff, 0x04, 0x2c, 0x13, 0xff, 0x01, 0x1b, 0x0a, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x03, 0x0d, 0x00, 0xff, 0x04, 0x0e, 0x01, 0xff, 0x04, 0x0f, 0x01, 0xff, 0x04, 0x0e, 0x02, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x10, 0x01, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x0e, 0x00, 0xff, 0x01, 0x0f, 0x02, 0xff, 0x00, 0x0e, 0x01, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x02, 0x0e, 0x00, 0xff, 0x05, 0x10, 0x01, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x17, 0x02, 0xff, 0x02, 0x25, 0x09, 0xff, 0x05, 0x39, 0x18, 0xff, 0x11, 0x64, 0x3d, 0xff, 0x16, 0x8a, 0x59, 0xff, 0x16, 0x9f, 0x67, 0xff, 0x0c, 0xa1, 0x63, 0xff, 0x0a, 0xa4, 0x62, 0xff, 0x0d, 0xa6, 0x61, 0xff, 0x0e, 0xa5, 0x60, 0xff, 0x0e, 0xa4, 0x62, 0xff, 0x0d, 0xa5, 0x62, 0xff, 0x0e, 0xa5, 0x62, 0xff, 0x0e, 0xa5, 0x60, 0xff, 0x0d, 0xa2, 0x5f, 0xff, 0x0c, 0xa1, 0x5e, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0e, 0xa3, 0x5b, 0xff, 0x0f, 0xa4, 0x5a, 0xff, 0x10, 0xa4, 0x5c, 0xff, 0x0e, 0xa3, 0x5a, 0xff, 0x0e, 0xa3, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x10, 0xa0, 0x58, 0xff, 0x0f, 0x9e, 0x56, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0d, 0x99, 0x51, 0xff, 0x0c, 0x97, 0x4f, 0xff, 0x0c, 0x96, 0x4f, 0xff, 0x08, 0x96, 0x4e, 0xff, 0x09, 0x94, 0x50, 0xff, 0x10, 0x92, 0x52, 0xff, 0x12, 0x8c, 0x53, 0xff, 0x06, 0x78, 0x4a, 0xff, 0x05, 0x71, 0x49, 0xff, 0x05, 0x6a, 0x48, 0xff, 0x13, 0x6e, 0x53, 0xff, 0x31, 0x75, 0x65, 0xff, 0x3e, 0x6c, 0x6f, 0xff, 0x47, 0x75, 0x95, 0xff, 0x2d, 0x68, 0x94, 0xff, 0x25, 0x6b, 0xa1, 0xff, 0x0d, 0x4e, 0x78, 0xff, 0x0c, 0x44, 0x88, 0xff, 0x1d, 0x6c, 0xc8, 0xff, 0x0c, 0x5d, 0xb5, 0xff, 0x14, 0x65, 0xc0, 0xff, 0x1b, 0x5d, 0xb1, 0xff, 0x11, 0x44, 0x7a, 0xff, 0x11, 0x3b, 0x4b, 0xff, 0x0f, 0x2c, 0x4a, 0xff, 0x3f, 0x50, 0x94, 0xff, 0x45, 0x3b, 0xa5, 0xff, 0x59, 0x32, 0xbb, 0xff, 0x56, 0x3b, 0xb0, 0xff, 0x4c, 0x40, 0x93, 0xff, 0x4e, 0x44, 0x9b, 0xff, 0x26, 0x42, 0x6c, 0xff, 0x11, 0x5c, 0x44, 0xff, 0x18, 0x7c, 0x47, 0xff, 0x13, 0x74, 0x3d, 0xff, 0x16, 0x68, 0x43, 0xff, 0x11, 0x58, 0x3a, 0xff, 0x0b, 0x58, 0x33, 0xff, 0x0e, 0x57, 0x36, 0xff, 0x9b, 0xb8, 0xb0, 0xff, + 0x06, 0x8a, 0x4b, 0xff, 0x0a, 0x8f, 0x4c, 0xff, 0x06, 0x92, 0x4c, 0xff, 0x09, 0x94, 0x51, 0xff, 0x0a, 0x94, 0x52, 0xff, 0x06, 0x94, 0x52, 0xff, 0x06, 0x95, 0x51, 0xff, 0x08, 0x99, 0x53, 0xff, 0x0b, 0x9e, 0x58, 0xff, 0x0d, 0xa0, 0x5b, 0xff, 0x0c, 0xa1, 0x5b, 0xff, 0x0a, 0xa1, 0x5b, 0xff, 0x08, 0xa2, 0x5b, 0xff, 0x08, 0xa4, 0x5b, 0xff, 0x05, 0xa4, 0x5a, 0xff, 0x04, 0xa6, 0x5a, 0xff, 0x0b, 0xac, 0x63, 0xff, 0x13, 0xb0, 0x6b, 0xff, 0x07, 0x9c, 0x5c, 0xff, 0x07, 0x97, 0x5c, 0xff, 0x10, 0xa2, 0x69, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x09, 0xa6, 0x71, 0xff, 0x1c, 0xb6, 0x88, 0xff, 0x15, 0xb3, 0x80, 0xff, 0x07, 0xaa, 0x72, 0xff, 0x07, 0xac, 0x70, 0xff, 0x06, 0xaa, 0x6c, 0xff, 0x06, 0xa8, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0a, 0xa6, 0x6c, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x0a, 0xa8, 0x6b, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0e, 0xa8, 0x70, 0xff, 0x16, 0xad, 0x7a, 0xff, 0x1a, 0xb0, 0x7d, 0xff, 0x14, 0xad, 0x78, 0xff, 0x11, 0xae, 0x76, 0xff, 0x10, 0xb3, 0x78, 0xff, 0x11, 0xb4, 0x7a, 0xff, 0x1d, 0xb6, 0x7e, 0xff, 0x24, 0xb3, 0x7d, 0xff, 0x28, 0xa7, 0x75, 0xff, 0x21, 0x92, 0x64, 0xff, 0x18, 0x6b, 0x46, 0xff, 0x0b, 0x4c, 0x2b, 0xff, 0x03, 0x30, 0x15, 0xff, 0x03, 0x22, 0x09, 0xff, 0x01, 0x16, 0x03, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x01, 0x11, 0x01, 0xff, 0x01, 0x10, 0x01, 0xff, 0x03, 0x0f, 0x02, 0xff, 0x03, 0x10, 0x02, 0xff, 0x02, 0x0e, 0x00, 0xff, 0x02, 0x0f, 0x00, 0xff, 0x02, 0x0e, 0x01, 0xff, 0x01, 0x0e, 0x01, 0xff, 0x01, 0x10, 0x01, 0xff, 0x01, 0x14, 0x04, 0xff, 0x03, 0x22, 0x0d, 0xff, 0x05, 0x30, 0x19, 0xff, 0x0c, 0x4b, 0x31, 0xff, 0x1e, 0x70, 0x56, 0xff, 0x31, 0x99, 0x7f, 0xff, 0x2c, 0xa4, 0x89, 0xff, 0x1f, 0xa5, 0x88, 0xff, 0x1b, 0xa6, 0x87, 0xff, 0x18, 0xa4, 0x80, 0xff, 0x16, 0xa1, 0x7b, 0xff, 0x13, 0xa2, 0x7a, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x13, 0xa2, 0x7a, 0xff, 0x14, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x7d, 0xff, 0x14, 0xa1, 0x7c, 0xff, 0x13, 0xa0, 0x7b, 0xff, 0x15, 0xa1, 0x7c, 0xff, 0x15, 0xa1, 0x7d, 0xff, 0x15, 0xa1, 0x7e, 0xff, 0x14, 0xa1, 0x7e, 0xff, 0x12, 0xa1, 0x7c, 0xff, 0x12, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x11, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x0f, 0xa4, 0x7d, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa1, 0x73, 0xff, 0x0c, 0x9b, 0x6a, 0xff, 0x17, 0xa6, 0x6d, 0xff, 0x1c, 0xa9, 0x6d, 0xff, 0x08, 0x90, 0x4f, 0xff, 0x10, 0x94, 0x53, 0xff, 0x07, 0x87, 0x44, 0xff, 0x22, 0xb3, 0x6e, 0xff, 0x07, 0x86, 0x46, 0xff, 0x06, 0x71, 0x38, 0xff, 0x18, 0x8c, 0x5e, 0xff, 0x1f, 0xa1, 0x76, 0xff, 0x16, 0xa4, 0x7a, 0xff, 0x11, 0xa6, 0x7c, 0xff, 0x0d, 0xa6, 0x7c, 0xff, 0x0f, 0xa7, 0x7c, 0xff, 0x10, 0xa9, 0x79, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x0e, 0xaa, 0x76, 0xff, 0x0e, 0xa9, 0x75, 0xff, 0x13, 0xac, 0x78, 0xff, 0x1f, 0xb1, 0x80, 0xff, 0x28, 0xac, 0x7f, 0xff, 0x28, 0x9d, 0x74, 0xff, 0x1e, 0x7e, 0x59, 0xff, 0x0f, 0x61, 0x3f, 0xff, 0x08, 0x44, 0x26, 0xff, 0x05, 0x30, 0x15, 0xff, 0x01, 0x1b, 0x05, 0xff, 0x00, 0x15, 0x02, 0xff, 0x01, 0x12, 0x00, 0xff, 0x00, 0x0e, 0x00, 0xff, 0x02, 0x0f, 0x01, 0xff, 0x03, 0x0f, 0x01, 0xff, 0x01, 0x0f, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x02, 0x10, 0x02, 0xff, 0x04, 0x10, 0x01, 0xff, 0x05, 0x10, 0x01, 0xff, 0x04, 0x10, 0x01, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x01, 0x0f, 0x00, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x13, 0x01, 0xff, 0x00, 0x19, 0x04, 0xff, 0x01, 0x20, 0x09, 0xff, 0x01, 0x2f, 0x16, 0xff, 0x06, 0x3f, 0x25, 0xff, 0x0f, 0x5b, 0x3d, 0xff, 0x1b, 0x79, 0x58, 0xff, 0x30, 0x9f, 0x80, 0xff, 0x37, 0xb4, 0x95, 0xff, 0x2c, 0xb9, 0x9b, 0xff, 0x26, 0xb9, 0x9a, 0xff, 0x25, 0xba, 0x98, 0xff, 0x27, 0xba, 0x98, 0xff, 0x27, 0xb9, 0x97, 0xff, 0x26, 0xb9, 0x98, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x26, 0xba, 0x97, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x25, 0xb8, 0x95, 0xff, 0x25, 0xb7, 0x95, 0xff, 0x24, 0xb7, 0x95, 0xff, 0x24, 0xb7, 0x95, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb9, 0x94, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x23, 0xb9, 0x91, 0xff, 0x23, 0xb8, 0x90, 0xff, 0x21, 0xb6, 0x8e, 0xff, 0x1b, 0xaf, 0x8a, 0xff, 0x16, 0xab, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xac, 0x81, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x17, 0xaf, 0x81, 0xff, 0x1a, 0xb1, 0x83, 0xff, 0x1b, 0xb2, 0x84, 0xff, 0x1b, 0xb1, 0x85, 0xff, 0x1a, 0xb1, 0x83, 0xff, 0x1c, 0xb3, 0x85, 0xff, 0x1d, 0xb5, 0x85, 0xff, 0x1f, 0xb5, 0x85, 0xff, 0x1c, 0xb2, 0x83, 0xff, 0x16, 0xab, 0x7e, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x0e, 0xa2, 0x71, 0xff, 0x0a, 0xa0, 0x6d, 0xff, 0x08, 0xa1, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x1c, 0xa0, 0x6f, 0xff, 0x23, 0x9c, 0x6e, 0xff, 0x23, 0x8d, 0x65, 0xff, 0x1b, 0x7a, 0x57, 0xff, 0x13, 0x65, 0x42, 0xff, 0x0b, 0x4d, 0x2c, 0xff, 0x04, 0x37, 0x1a, 0xff, 0x05, 0x31, 0x18, 0xff, 0x04, 0x27, 0x0f, 0xff, 0x03, 0x20, 0x09, 0xff, 0x03, 0x1c, 0x07, 0xff, 0x02, 0x19, 0x05, 0xff, 0x01, 0x17, 0x04, 0xff, 0x01, 0x15, 0x03, 0xff, 0x01, 0x15, 0x03, 0xff, 0x02, 0x18, 0x06, 0xff, 0x02, 0x19, 0x07, 0xff, 0x02, 0x18, 0x07, 0xff, 0x03, 0x1f, 0x0a, 0xff, 0x03, 0x25, 0x0d, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x05, 0x35, 0x1a, 0xff, 0x13, 0x51, 0x30, 0xff, 0x18, 0x66, 0x41, 0xff, 0x1a, 0x7e, 0x53, 0xff, 0x19, 0x8d, 0x5e, 0xff, 0x1a, 0x9d, 0x69, 0xff, 0x0e, 0xa0, 0x66, 0xff, 0x0b, 0xa2, 0x62, 0xff, 0x0d, 0xa2, 0x62, 0xff, 0x0e, 0xa4, 0x62, 0xff, 0x0e, 0xa4, 0x61, 0xff, 0x0e, 0xa4, 0x61, 0xff, 0x0d, 0xa4, 0x62, 0xff, 0x0b, 0xa5, 0x62, 0xff, 0x0e, 0xa5, 0x61, 0xff, 0x0e, 0xa4, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5d, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0d, 0xa3, 0x5b, 0xff, 0x0f, 0xa3, 0x5a, 0xff, 0x10, 0xa4, 0x5c, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x10, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x10, 0xa0, 0x58, 0xff, 0x0e, 0x9d, 0x56, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0e, 0x99, 0x51, 0xff, 0x0c, 0x96, 0x4e, 0xff, 0x0b, 0x96, 0x4f, 0xff, 0x09, 0x95, 0x4e, 0xff, 0x09, 0x94, 0x4e, 0xff, 0x0c, 0x94, 0x4f, 0xff, 0x0e, 0x94, 0x50, 0xff, 0x0e, 0x91, 0x4e, 0xff, 0x0f, 0x8c, 0x4a, 0xff, 0x0e, 0x88, 0x4e, 0xff, 0x16, 0x84, 0x57, 0xff, 0x1f, 0x65, 0x4f, 0xff, 0x13, 0x3e, 0x3b, 0xff, 0x3d, 0x68, 0x7f, 0xff, 0x2b, 0x66, 0x92, 0xff, 0x21, 0x6c, 0xb0, 0xff, 0x15, 0x5d, 0xa0, 0xff, 0x0b, 0x43, 0x9b, 0xff, 0x1e, 0x68, 0xd3, 0xff, 0x13, 0x5f, 0xc6, 0xff, 0x0a, 0x63, 0xc3, 0xff, 0x1c, 0x7d, 0xcd, 0xff, 0x24, 0x77, 0xa7, 0xff, 0x09, 0x38, 0x45, 0xff, 0x0b, 0x26, 0x3d, 0xff, 0x44, 0x53, 0x94, 0xff, 0x71, 0x6e, 0xd4, 0xff, 0x45, 0x2f, 0xab, 0xff, 0x43, 0x2e, 0xa2, 0xff, 0x4f, 0x34, 0xa7, 0xff, 0x62, 0x3e, 0xbb, 0xff, 0x3a, 0x36, 0x8e, 0xff, 0x20, 0x43, 0x6a, 0xff, 0x24, 0x64, 0x61, 0xff, 0x15, 0x67, 0x45, 0xff, 0x13, 0x69, 0x40, 0xff, 0x0a, 0x55, 0x36, 0xff, 0x0c, 0x5c, 0x38, 0xff, 0x0f, 0x5f, 0x38, 0xff, 0x97, 0xbd, 0xad, 0xff, + 0x08, 0x8d, 0x4e, 0xff, 0x0b, 0x91, 0x4d, 0xff, 0x07, 0x92, 0x4c, 0xff, 0x08, 0x93, 0x4f, 0xff, 0x09, 0x92, 0x51, 0xff, 0x05, 0x93, 0x50, 0xff, 0x07, 0x94, 0x50, 0xff, 0x09, 0x96, 0x51, 0xff, 0x0b, 0x9a, 0x54, 0xff, 0x09, 0x9c, 0x56, 0xff, 0x08, 0x9d, 0x57, 0xff, 0x07, 0xa0, 0x59, 0xff, 0x08, 0xa3, 0x5a, 0xff, 0x06, 0xa3, 0x59, 0xff, 0x06, 0xa2, 0x5a, 0xff, 0x0b, 0xa2, 0x5e, 0xff, 0x17, 0xa8, 0x65, 0xff, 0x0a, 0x8f, 0x51, 0xff, 0x08, 0x8f, 0x53, 0xff, 0x11, 0xa5, 0x6a, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x0d, 0xa9, 0x74, 0xff, 0x27, 0xbe, 0x8d, 0xff, 0x1d, 0xb8, 0x84, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x06, 0xab, 0x6e, 0xff, 0x07, 0xac, 0x6d, 0xff, 0x07, 0xa9, 0x6b, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa7, 0x6c, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x13, 0xab, 0x76, 0xff, 0x19, 0xae, 0x7a, 0xff, 0x21, 0xad, 0x79, 0xff, 0x1b, 0xac, 0x76, 0xff, 0x15, 0xb0, 0x77, 0xff, 0x12, 0xb1, 0x77, 0xff, 0x11, 0xb3, 0x78, 0xff, 0x13, 0xb1, 0x78, 0xff, 0x19, 0xb2, 0x7b, 0xff, 0x1d, 0xb2, 0x7c, 0xff, 0x24, 0xb3, 0x7a, 0xff, 0x25, 0xac, 0x76, 0xff, 0x27, 0x9b, 0x6a, 0xff, 0x25, 0x87, 0x5a, 0xff, 0x17, 0x67, 0x3d, 0xff, 0x0b, 0x50, 0x28, 0xff, 0x0a, 0x49, 0x23, 0xff, 0x08, 0x40, 0x1c, 0xff, 0x08, 0x36, 0x18, 0xff, 0x07, 0x33, 0x16, 0xff, 0x05, 0x2f, 0x11, 0xff, 0x04, 0x2c, 0x0f, 0xff, 0x03, 0x2a, 0x0e, 0xff, 0x04, 0x29, 0x0f, 0xff, 0x05, 0x29, 0x0f, 0xff, 0x05, 0x29, 0x0f, 0xff, 0x04, 0x25, 0x0f, 0xff, 0x05, 0x27, 0x10, 0xff, 0x07, 0x31, 0x19, 0xff, 0x09, 0x3a, 0x22, 0xff, 0x09, 0x45, 0x2b, 0xff, 0x13, 0x60, 0x45, 0xff, 0x24, 0x7e, 0x61, 0xff, 0x2a, 0x8f, 0x6f, 0xff, 0x29, 0xa2, 0x7f, 0xff, 0x2a, 0xaa, 0x87, 0xff, 0x20, 0xa7, 0x86, 0xff, 0x1a, 0xa6, 0x85, 0xff, 0x15, 0xa4, 0x83, 0xff, 0x17, 0xa3, 0x81, 0xff, 0x1b, 0xa1, 0x7c, 0xff, 0x1c, 0x9f, 0x7a, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7d, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x13, 0xa2, 0x7e, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x10, 0xa3, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x15, 0xa5, 0x7c, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x0f, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x12, 0xa1, 0x75, 0xff, 0x09, 0x96, 0x67, 0xff, 0x05, 0x8f, 0x55, 0xff, 0x0f, 0x98, 0x58, 0xff, 0x14, 0x9b, 0x57, 0xff, 0x08, 0x89, 0x44, 0xff, 0x05, 0x80, 0x3b, 0xff, 0x24, 0x9e, 0x5d, 0xff, 0x09, 0x77, 0x3d, 0xff, 0x09, 0x6e, 0x3a, 0xff, 0x11, 0x85, 0x59, 0xff, 0x08, 0x8d, 0x64, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x0c, 0xa2, 0x7a, 0xff, 0x0e, 0xa6, 0x7e, 0xff, 0x10, 0xa6, 0x7d, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x13, 0xa9, 0x7a, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x12, 0xab, 0x78, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xac, 0x7a, 0xff, 0x13, 0xad, 0x7d, 0xff, 0x18, 0xae, 0x80, 0xff, 0x1d, 0xac, 0x81, 0xff, 0x1c, 0xa8, 0x7d, 0xff, 0x27, 0x9e, 0x76, 0xff, 0x28, 0x8e, 0x69, 0xff, 0x17, 0x6f, 0x4b, 0xff, 0x0e, 0x57, 0x37, 0xff, 0x07, 0x3a, 0x1e, 0xff, 0x05, 0x2e, 0x15, 0xff, 0x04, 0x28, 0x11, 0xff, 0x03, 0x20, 0x0d, 0xff, 0x01, 0x1b, 0x0a, 0xff, 0x01, 0x19, 0x08, 0xff, 0x01, 0x15, 0x05, 0xff, 0x01, 0x14, 0x03, 0xff, 0x02, 0x12, 0x03, 0xff, 0x01, 0x14, 0x04, 0xff, 0x01, 0x1a, 0x07, 0xff, 0x01, 0x1c, 0x09, 0xff, 0x01, 0x1e, 0x0a, 0xff, 0x03, 0x26, 0x10, 0xff, 0x07, 0x32, 0x1a, 0xff, 0x09, 0x3f, 0x26, 0xff, 0x0d, 0x53, 0x35, 0xff, 0x11, 0x64, 0x43, 0xff, 0x17, 0x79, 0x57, 0xff, 0x1e, 0x8a, 0x65, 0xff, 0x2b, 0xa4, 0x7d, 0xff, 0x2d, 0xb1, 0x8a, 0xff, 0x2d, 0xb9, 0x94, 0xff, 0x25, 0xb8, 0x95, 0xff, 0x21, 0xba, 0x98, 0xff, 0x21, 0xba, 0x99, 0xff, 0x24, 0xba, 0x98, 0xff, 0x27, 0xba, 0x98, 0xff, 0x28, 0xba, 0x97, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb7, 0x95, 0xff, 0x24, 0xb8, 0x96, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x24, 0xb9, 0x94, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x22, 0xb9, 0x91, 0xff, 0x23, 0xb9, 0x91, 0xff, 0x23, 0xb8, 0x90, 0xff, 0x1d, 0xb2, 0x8b, 0xff, 0x19, 0xae, 0x87, 0xff, 0x16, 0xab, 0x84, 0xff, 0x17, 0xad, 0x84, 0xff, 0x16, 0xac, 0x81, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x13, 0xaa, 0x7b, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x19, 0xb1, 0x81, 0xff, 0x19, 0xb2, 0x80, 0xff, 0x15, 0xae, 0x7b, 0xff, 0x17, 0xae, 0x7c, 0xff, 0x19, 0xb0, 0x7e, 0xff, 0x17, 0xad, 0x7e, 0xff, 0x16, 0xa9, 0x7b, 0xff, 0x1c, 0xa8, 0x7c, 0xff, 0x16, 0xa5, 0x76, 0xff, 0x0f, 0xa4, 0x70, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa0, 0x68, 0xff, 0x0b, 0x9e, 0x66, 0xff, 0x12, 0xa0, 0x69, 0xff, 0x16, 0xa4, 0x6d, 0xff, 0x13, 0xa6, 0x6f, 0xff, 0x1d, 0xa9, 0x75, 0xff, 0x22, 0xa4, 0x74, 0xff, 0x24, 0x99, 0x6d, 0xff, 0x29, 0x95, 0x6a, 0xff, 0x26, 0x88, 0x5f, 0xff, 0x23, 0x80, 0x58, 0xff, 0x20, 0x7a, 0x52, 0xff, 0x19, 0x6c, 0x49, 0xff, 0x14, 0x63, 0x42, 0xff, 0x12, 0x62, 0x40, 0xff, 0x15, 0x64, 0x42, 0xff, 0x1d, 0x6d, 0x4b, 0xff, 0x1f, 0x70, 0x4e, 0xff, 0x20, 0x71, 0x4f, 0xff, 0x24, 0x7a, 0x56, 0xff, 0x23, 0x86, 0x5f, 0xff, 0x21, 0x8f, 0x64, 0xff, 0x1e, 0x92, 0x66, 0xff, 0x21, 0x9e, 0x6e, 0xff, 0x1b, 0xa0, 0x6e, 0xff, 0x12, 0xa2, 0x6b, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x69, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x0c, 0xa2, 0x62, 0xff, 0x0d, 0xa3, 0x62, 0xff, 0x0c, 0xa2, 0x61, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0c, 0xa4, 0x62, 0xff, 0x0a, 0xa5, 0x62, 0xff, 0x0d, 0xa4, 0x60, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0c, 0xa2, 0x60, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5d, 0xff, 0x0c, 0xa1, 0x5c, 0xff, 0x0c, 0xa3, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x10, 0xa3, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x10, 0xa0, 0x58, 0xff, 0x0e, 0x9d, 0x56, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0d, 0x98, 0x51, 0xff, 0x0b, 0x95, 0x4e, 0xff, 0x0c, 0x95, 0x4e, 0xff, 0x09, 0x94, 0x4d, 0xff, 0x0b, 0x96, 0x4f, 0xff, 0x0c, 0x93, 0x4e, 0xff, 0x0c, 0x91, 0x4d, 0xff, 0x0d, 0x8f, 0x4b, 0xff, 0x0e, 0x8f, 0x48, 0xff, 0x0b, 0x8a, 0x46, 0xff, 0x0e, 0x83, 0x49, 0xff, 0x04, 0x5a, 0x2f, 0xff, 0x01, 0x3b, 0x23, 0xff, 0x1f, 0x52, 0x5b, 0xff, 0x35, 0x72, 0x9e, 0xff, 0x17, 0x67, 0xbb, 0xff, 0x26, 0x73, 0xd1, 0xff, 0x16, 0x52, 0xb3, 0xff, 0x10, 0x4e, 0xb0, 0xff, 0x09, 0x46, 0xa5, 0xff, 0x02, 0x4b, 0xa0, 0xff, 0x1e, 0x92, 0xcd, 0xff, 0x26, 0x85, 0xa5, 0xff, 0x05, 0x3d, 0x3b, 0xff, 0x0f, 0x3d, 0x33, 0xff, 0x27, 0x49, 0x6e, 0xff, 0x60, 0x6a, 0xc6, 0xff, 0x84, 0x82, 0xed, 0xff, 0x71, 0x71, 0xda, 0xff, 0x40, 0x2d, 0xa9, 0xff, 0x42, 0x1c, 0xa1, 0xff, 0x4e, 0x32, 0xa6, 0xff, 0x4e, 0x3e, 0xa9, 0xff, 0x37, 0x4a, 0x85, 0xff, 0x1b, 0x59, 0x52, 0xff, 0x12, 0x6c, 0x40, 0xff, 0x03, 0x56, 0x35, 0xff, 0x09, 0x5d, 0x3c, 0xff, 0x10, 0x64, 0x3b, 0xff, 0x89, 0xb4, 0xa4, 0xff, + 0x0a, 0x8d, 0x4f, 0xff, 0x0a, 0x8f, 0x4b, 0xff, 0x07, 0x91, 0x4c, 0xff, 0x09, 0x91, 0x4e, 0xff, 0x09, 0x91, 0x50, 0xff, 0x06, 0x92, 0x50, 0xff, 0x09, 0x93, 0x50, 0xff, 0x0d, 0x94, 0x51, 0xff, 0x0b, 0x97, 0x53, 0xff, 0x08, 0x99, 0x54, 0xff, 0x07, 0x9c, 0x54, 0xff, 0x07, 0x9f, 0x56, 0xff, 0x08, 0xa1, 0x58, 0xff, 0x08, 0xa1, 0x58, 0xff, 0x0d, 0x9f, 0x5b, 0xff, 0x14, 0x9b, 0x5d, 0xff, 0x0a, 0x88, 0x4b, 0xff, 0x08, 0x84, 0x4a, 0xff, 0x12, 0x9c, 0x63, 0xff, 0x0c, 0xa6, 0x6c, 0xff, 0x05, 0xa4, 0x6a, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x1d, 0xb4, 0x81, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x07, 0xaa, 0x6d, 0xff, 0x08, 0xab, 0x6d, 0xff, 0x08, 0xab, 0x6b, 0xff, 0x08, 0xa8, 0x6a, 0xff, 0x09, 0xa8, 0x6b, 0xff, 0x0b, 0xa9, 0x6e, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x07, 0xa8, 0x6a, 0xff, 0x09, 0xa9, 0x6b, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0c, 0xa9, 0x6f, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x14, 0xa9, 0x73, 0xff, 0x13, 0xad, 0x74, 0xff, 0x14, 0xb1, 0x76, 0xff, 0x12, 0xb2, 0x76, 0xff, 0x12, 0xb3, 0x77, 0xff, 0x11, 0xb0, 0x76, 0xff, 0x14, 0xb1, 0x78, 0xff, 0x12, 0xb0, 0x77, 0xff, 0x10, 0xb2, 0x75, 0xff, 0x13, 0xb2, 0x75, 0xff, 0x1b, 0xb1, 0x77, 0xff, 0x23, 0xb0, 0x7a, 0xff, 0x27, 0xab, 0x76, 0xff, 0x25, 0xa6, 0x70, 0xff, 0x25, 0xa4, 0x6d, 0xff, 0x24, 0x9f, 0x69, 0xff, 0x2a, 0x95, 0x68, 0xff, 0x27, 0x91, 0x64, 0xff, 0x21, 0x8b, 0x5d, 0xff, 0x1e, 0x86, 0x5a, 0xff, 0x1f, 0x87, 0x5b, 0xff, 0x22, 0x89, 0x5d, 0xff, 0x26, 0x8a, 0x5f, 0xff, 0x24, 0x8a, 0x5f, 0xff, 0x21, 0x88, 0x5f, 0xff, 0x22, 0x8b, 0x62, 0xff, 0x26, 0x91, 0x6b, 0xff, 0x26, 0x95, 0x70, 0xff, 0x21, 0x98, 0x73, 0xff, 0x23, 0xa2, 0x7c, 0xff, 0x20, 0xa5, 0x80, 0xff, 0x1e, 0xa7, 0x80, 0xff, 0x19, 0xa6, 0x7d, 0xff, 0x16, 0xa5, 0x7e, 0xff, 0x13, 0xa5, 0x7f, 0xff, 0x10, 0xa3, 0x7e, 0xff, 0x0f, 0xa1, 0x7d, 0xff, 0x11, 0xa1, 0x7c, 0xff, 0x15, 0xa1, 0x7b, 0xff, 0x17, 0xa2, 0x79, 0xff, 0x14, 0xa2, 0x7b, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x14, 0xa2, 0x7f, 0xff, 0x14, 0xa2, 0x7e, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x15, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa1, 0x7b, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa2, 0x7f, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x15, 0xa5, 0x7b, 0xff, 0x12, 0xa3, 0x79, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa3, 0x79, 0xff, 0x17, 0xa5, 0x79, 0xff, 0x17, 0xa3, 0x75, 0xff, 0x10, 0x99, 0x5f, 0xff, 0x03, 0x81, 0x42, 0xff, 0x12, 0x90, 0x4b, 0xff, 0x0b, 0x86, 0x40, 0xff, 0x05, 0x77, 0x32, 0xff, 0x0e, 0x74, 0x37, 0xff, 0x03, 0x5b, 0x28, 0xff, 0x03, 0x5f, 0x31, 0xff, 0x0f, 0x83, 0x59, 0xff, 0x16, 0x9d, 0x74, 0xff, 0x14, 0xa4, 0x7c, 0xff, 0x10, 0xa5, 0x7e, 0xff, 0x0e, 0xa2, 0x7c, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x14, 0xa6, 0x7c, 0xff, 0x14, 0xa9, 0x7a, 0xff, 0x13, 0xa8, 0x78, 0xff, 0x13, 0xaa, 0x7a, 0xff, 0x17, 0xae, 0x7f, 0xff, 0x16, 0xac, 0x7e, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x15, 0xab, 0x7e, 0xff, 0x15, 0xab, 0x7d, 0xff, 0x1a, 0xab, 0x7b, 0xff, 0x1f, 0xa8, 0x7c, 0xff, 0x25, 0xa4, 0x7a, 0xff, 0x25, 0x98, 0x71, 0xff, 0x24, 0x90, 0x6b, 0xff, 0x24, 0x8a, 0x66, 0xff, 0x1e, 0x81, 0x60, 0xff, 0x1f, 0x79, 0x59, 0xff, 0x1f, 0x71, 0x53, 0xff, 0x19, 0x65, 0x48, 0xff, 0x17, 0x60, 0x44, 0xff, 0x19, 0x60, 0x43, 0xff, 0x1c, 0x67, 0x4b, 0xff, 0x21, 0x72, 0x54, 0xff, 0x22, 0x74, 0x56, 0xff, 0x1b, 0x76, 0x57, 0xff, 0x1c, 0x81, 0x5e, 0xff, 0x23, 0x8e, 0x6a, 0xff, 0x24, 0x94, 0x6f, 0xff, 0x21, 0x9c, 0x75, 0xff, 0x22, 0xa4, 0x7b, 0xff, 0x22, 0xae, 0x83, 0xff, 0x21, 0xb2, 0x87, 0xff, 0x25, 0xba, 0x8e, 0xff, 0x21, 0xb9, 0x8e, 0xff, 0x20, 0xba, 0x91, 0xff, 0x1f, 0xbb, 0x95, 0xff, 0x20, 0xbc, 0x99, 0xff, 0x21, 0xbb, 0x99, 0xff, 0x24, 0xba, 0x98, 0xff, 0x27, 0xba, 0x98, 0xff, 0x28, 0xba, 0x97, 0xff, 0x27, 0xba, 0x98, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x26, 0xba, 0x96, 0xff, 0x27, 0xbb, 0x97, 0xff, 0x26, 0xb9, 0x96, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x94, 0xff, 0x24, 0xb9, 0x93, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x21, 0xb8, 0x90, 0xff, 0x21, 0xb7, 0x8f, 0xff, 0x20, 0xb5, 0x8d, 0xff, 0x1b, 0xb0, 0x88, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xad, 0x85, 0xff, 0x17, 0xad, 0x83, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x10, 0xa8, 0x7a, 0xff, 0x11, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x13, 0xac, 0x79, 0xff, 0x14, 0xad, 0x7a, 0xff, 0x12, 0xab, 0x78, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x10, 0xa5, 0x74, 0xff, 0x17, 0xa5, 0x7a, 0xff, 0x13, 0xa5, 0x76, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x06, 0xa1, 0x67, 0xff, 0x05, 0xa1, 0x65, 0xff, 0x06, 0xa3, 0x64, 0xff, 0x09, 0xa5, 0x66, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x12, 0xa4, 0x70, 0xff, 0x18, 0xa3, 0x74, 0xff, 0x19, 0xa2, 0x74, 0xff, 0x18, 0xa2, 0x73, 0xff, 0x18, 0xa4, 0x74, 0xff, 0x16, 0xa3, 0x70, 0xff, 0x17, 0xa2, 0x70, 0xff, 0x15, 0x9f, 0x6e, 0xff, 0x16, 0xa0, 0x6e, 0xff, 0x17, 0xa1, 0x6f, 0xff, 0x18, 0xa2, 0x70, 0xff, 0x18, 0xa2, 0x70, 0xff, 0x17, 0xa2, 0x70, 0xff, 0x17, 0xa1, 0x6f, 0xff, 0x18, 0xa1, 0x6d, 0xff, 0x14, 0xa1, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x04, 0xa4, 0x6a, 0xff, 0x04, 0xa4, 0x68, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0c, 0xa3, 0x61, 0xff, 0x0a, 0xa4, 0x62, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0c, 0xa3, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x10, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0f, 0xa0, 0x58, 0xff, 0x0e, 0x9c, 0x55, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0d, 0x97, 0x52, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x09, 0x93, 0x4d, 0xff, 0x0a, 0x94, 0x4e, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0c, 0x92, 0x4c, 0xff, 0x0c, 0x91, 0x4b, 0xff, 0x0b, 0x90, 0x47, 0xff, 0x0b, 0x8d, 0x46, 0xff, 0x0e, 0x88, 0x49, 0xff, 0x0f, 0x76, 0x3f, 0xff, 0x02, 0x4f, 0x26, 0xff, 0x14, 0x4e, 0x4c, 0xff, 0x33, 0x73, 0x9e, 0xff, 0x0a, 0x62, 0xc1, 0xff, 0x0c, 0x5b, 0xbf, 0xff, 0x07, 0x42, 0x9a, 0xff, 0x05, 0x47, 0x96, 0xff, 0x05, 0x47, 0x96, 0xff, 0x17, 0x76, 0xc2, 0xff, 0x08, 0x65, 0xa0, 0xff, 0x04, 0x3a, 0x59, 0xff, 0x08, 0x3f, 0x33, 0xff, 0x09, 0x4b, 0x2e, 0xff, 0x1c, 0x4b, 0x60, 0xff, 0x40, 0x4e, 0xac, 0xff, 0x90, 0x95, 0xfe, 0xff, 0x8d, 0x96, 0xfd, 0xff, 0x6e, 0x66, 0xe3, 0xff, 0x65, 0x4d, 0xc6, 0xff, 0x4d, 0x31, 0xa7, 0xff, 0x4c, 0x30, 0xae, 0xff, 0x3a, 0x38, 0x90, 0xff, 0x21, 0x4c, 0x60, 0xff, 0x19, 0x6b, 0x43, 0xff, 0x05, 0x56, 0x33, 0xff, 0x06, 0x5a, 0x3b, 0xff, 0x11, 0x66, 0x3d, 0xff, 0x85, 0xae, 0x9b, 0xff, + 0x0b, 0x8d, 0x50, 0xff, 0x0b, 0x90, 0x4c, 0xff, 0x08, 0x91, 0x4b, 0xff, 0x08, 0x90, 0x4d, 0xff, 0x09, 0x90, 0x4f, 0xff, 0x06, 0x92, 0x50, 0xff, 0x0a, 0x93, 0x51, 0xff, 0x0e, 0x94, 0x52, 0xff, 0x0a, 0x96, 0x53, 0xff, 0x07, 0x98, 0x53, 0xff, 0x06, 0x9a, 0x53, 0xff, 0x06, 0x9c, 0x55, 0xff, 0x08, 0x9c, 0x56, 0xff, 0x0c, 0x9d, 0x58, 0xff, 0x15, 0x9c, 0x5c, 0xff, 0x0b, 0x80, 0x48, 0xff, 0x04, 0x78, 0x41, 0xff, 0x15, 0x9c, 0x64, 0xff, 0x10, 0xa2, 0x6b, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x04, 0xa5, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x09, 0xa4, 0x6f, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x6b, 0xff, 0x09, 0xab, 0x6c, 0xff, 0x0a, 0xac, 0x6b, 0xff, 0x08, 0xaa, 0x6a, 0xff, 0x09, 0xa9, 0x6c, 0xff, 0x0c, 0xaa, 0x6e, 0xff, 0x0c, 0xaa, 0x6d, 0xff, 0x07, 0xa8, 0x6a, 0xff, 0x09, 0xaa, 0x6c, 0xff, 0x0b, 0xab, 0x6d, 0xff, 0x0d, 0xaa, 0x6f, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x09, 0xac, 0x70, 0xff, 0x0f, 0xb1, 0x74, 0xff, 0x12, 0xb2, 0x75, 0xff, 0x13, 0xb0, 0x73, 0xff, 0x14, 0xaf, 0x75, 0xff, 0x19, 0xb2, 0x78, 0xff, 0x18, 0xb2, 0x7a, 0xff, 0x14, 0xb2, 0x7a, 0xff, 0x15, 0xb2, 0x7a, 0xff, 0x18, 0xb0, 0x7b, 0xff, 0x19, 0xaf, 0x7a, 0xff, 0x1a, 0xad, 0x79, 0xff, 0x1d, 0xb0, 0x79, 0xff, 0x1b, 0xb0, 0x77, 0xff, 0x1d, 0xb0, 0x78, 0xff, 0x20, 0xae, 0x78, 0xff, 0x21, 0xae, 0x78, 0xff, 0x20, 0xac, 0x77, 0xff, 0x21, 0xab, 0x76, 0xff, 0x23, 0xad, 0x79, 0xff, 0x24, 0xae, 0x7a, 0xff, 0x26, 0xae, 0x7a, 0xff, 0x23, 0xad, 0x78, 0xff, 0x1d, 0xad, 0x7a, 0xff, 0x1e, 0xae, 0x7b, 0xff, 0x1f, 0xad, 0x7d, 0xff, 0x1d, 0xab, 0x7e, 0xff, 0x1b, 0xa8, 0x7d, 0xff, 0x1a, 0xa8, 0x7e, 0xff, 0x16, 0xa7, 0x7e, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x16, 0xa2, 0x78, 0xff, 0x14, 0xa2, 0x78, 0xff, 0x14, 0xa2, 0x7a, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x10, 0xa2, 0x7b, 0xff, 0x10, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x15, 0xa3, 0x7d, 0xff, 0x16, 0xa4, 0x81, 0xff, 0x18, 0xa6, 0x83, 0xff, 0x18, 0xa6, 0x81, 0xff, 0x15, 0xa3, 0x7d, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7e, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x15, 0xa4, 0x7d, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x7c, 0xff, 0x14, 0xa4, 0x7a, 0xff, 0x13, 0xa3, 0x7b, 0xff, 0x11, 0xa1, 0x7a, 0xff, 0x0f, 0xa0, 0x79, 0xff, 0x11, 0xa1, 0x7a, 0xff, 0x15, 0xa3, 0x7a, 0xff, 0x11, 0x9f, 0x74, 0xff, 0x0a, 0x95, 0x69, 0xff, 0x0a, 0x92, 0x5b, 0xff, 0x03, 0x7e, 0x42, 0xff, 0x04, 0x76, 0x35, 0xff, 0x07, 0x78, 0x34, 0xff, 0x0a, 0x77, 0x32, 0xff, 0x02, 0x60, 0x23, 0xff, 0x01, 0x54, 0x21, 0xff, 0x0e, 0x6e, 0x40, 0xff, 0x27, 0xa3, 0x77, 0xff, 0x1d, 0xa5, 0x7b, 0xff, 0x15, 0xa3, 0x79, 0xff, 0x14, 0xa6, 0x7e, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa6, 0x7c, 0xff, 0x10, 0xa9, 0x7a, 0xff, 0x0d, 0xa8, 0x78, 0xff, 0x12, 0xab, 0x7c, 0xff, 0x1a, 0xb0, 0x83, 0xff, 0x1b, 0xaf, 0x83, 0xff, 0x19, 0xaf, 0x82, 0xff, 0x1a, 0xb0, 0x83, 0xff, 0x1a, 0xb0, 0x83, 0xff, 0x16, 0xb0, 0x81, 0xff, 0x16, 0xb1, 0x7f, 0xff, 0x19, 0xb1, 0x81, 0xff, 0x1a, 0xae, 0x80, 0xff, 0x21, 0xae, 0x83, 0xff, 0x21, 0xae, 0x82, 0xff, 0x23, 0xae, 0x84, 0xff, 0x22, 0xac, 0x84, 0xff, 0x29, 0xae, 0x85, 0xff, 0x2d, 0xab, 0x84, 0xff, 0x2a, 0xa7, 0x80, 0xff, 0x2a, 0xa5, 0x7f, 0xff, 0x2b, 0xa5, 0x80, 0xff, 0x2f, 0xa9, 0x83, 0xff, 0x2f, 0xab, 0x86, 0xff, 0x2b, 0xa9, 0x83, 0xff, 0x23, 0xa8, 0x81, 0xff, 0x20, 0xac, 0x83, 0xff, 0x21, 0xaf, 0x85, 0xff, 0x22, 0xb1, 0x87, 0xff, 0x22, 0xb4, 0x89, 0xff, 0x20, 0xb4, 0x8a, 0xff, 0x21, 0xb7, 0x8c, 0xff, 0x1f, 0xb8, 0x8d, 0xff, 0x22, 0xba, 0x8e, 0xff, 0x21, 0xba, 0x8e, 0xff, 0x21, 0xb9, 0x90, 0xff, 0x24, 0xbb, 0x96, 0xff, 0x24, 0xbb, 0x98, 0xff, 0x25, 0xba, 0x99, 0xff, 0x25, 0xba, 0x99, 0xff, 0x26, 0xba, 0x98, 0xff, 0x26, 0xba, 0x97, 0xff, 0x26, 0xba, 0x96, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x27, 0xbb, 0x97, 0xff, 0x26, 0xba, 0x97, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x93, 0xff, 0x24, 0xb8, 0x92, 0xff, 0x23, 0xb8, 0x91, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x20, 0xb5, 0x8d, 0xff, 0x1d, 0xb3, 0x89, 0xff, 0x1a, 0xaf, 0x85, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xad, 0x84, 0xff, 0x17, 0xad, 0x82, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x14, 0xad, 0x78, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x09, 0xa0, 0x6c, 0xff, 0x0a, 0xa1, 0x72, 0xff, 0x0a, 0xa2, 0x71, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x06, 0xa1, 0x67, 0xff, 0x07, 0xa4, 0x66, 0xff, 0x06, 0xa3, 0x64, 0xff, 0x08, 0xa5, 0x66, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x10, 0xa5, 0x70, 0xff, 0x15, 0xa6, 0x78, 0xff, 0x1d, 0xab, 0x81, 0xff, 0x1d, 0xaa, 0x80, 0xff, 0x16, 0xa4, 0x7b, 0xff, 0x15, 0xa6, 0x79, 0xff, 0x12, 0xa7, 0x75, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x08, 0xa0, 0x68, 0xff, 0x0e, 0xa1, 0x69, 0xff, 0x0b, 0xa1, 0x68, 0xff, 0x05, 0xa1, 0x67, 0xff, 0x03, 0xa4, 0x69, 0xff, 0x03, 0xa4, 0x68, 0xff, 0x06, 0xa3, 0x67, 0xff, 0x0c, 0xa2, 0x68, 0xff, 0x0f, 0xa3, 0x69, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x0e, 0xa4, 0x62, 0xff, 0x0c, 0xa3, 0x62, 0xff, 0x0b, 0xa3, 0x62, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0d, 0xa3, 0x62, 0xff, 0x0d, 0xa2, 0x61, 0xff, 0x0d, 0xa2, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa3, 0x5d, 0xff, 0x0d, 0xa3, 0x5d, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0f, 0xa2, 0x5a, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0f, 0xa0, 0x58, 0xff, 0x0d, 0x9b, 0x54, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0d, 0x97, 0x52, 0xff, 0x0b, 0x93, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0a, 0x93, 0x4f, 0xff, 0x0b, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0c, 0x92, 0x4b, 0xff, 0x0b, 0x90, 0x49, 0xff, 0x09, 0x8f, 0x47, 0xff, 0x0b, 0x8c, 0x49, 0xff, 0x0d, 0x89, 0x4c, 0xff, 0x11, 0x81, 0x47, 0xff, 0x08, 0x62, 0x32, 0xff, 0x08, 0x4a, 0x3f, 0xff, 0x1a, 0x5f, 0x84, 0xff, 0x09, 0x6a, 0xc3, 0xff, 0x10, 0x73, 0xce, 0xff, 0x0a, 0x66, 0xb3, 0xff, 0x1a, 0x89, 0xc9, 0xff, 0x0d, 0x78, 0xb4, 0xff, 0x26, 0x9d, 0xe2, 0xff, 0x15, 0x77, 0xb7, 0xff, 0x07, 0x41, 0x62, 0xff, 0x0b, 0x4b, 0x39, 0xff, 0x0b, 0x57, 0x37, 0xff, 0x15, 0x48, 0x5e, 0xff, 0x3c, 0x49, 0xab, 0xff, 0x87, 0x8a, 0xfc, 0xff, 0x83, 0x8d, 0xfb, 0xff, 0x77, 0x78, 0xf3, 0xff, 0x92, 0x8a, 0xf6, 0xff, 0x73, 0x65, 0xd4, 0xff, 0x54, 0x43, 0xbc, 0xff, 0x52, 0x4c, 0xb2, 0xff, 0x2b, 0x46, 0x74, 0xff, 0x1f, 0x60, 0x47, 0xff, 0x0d, 0x55, 0x31, 0xff, 0x08, 0x5b, 0x3a, 0xff, 0x16, 0x6a, 0x41, 0xff, 0x94, 0xb6, 0xa2, 0xff, + 0x0b, 0x8d, 0x4f, 0xff, 0x0c, 0x90, 0x4d, 0xff, 0x08, 0x8f, 0x4b, 0xff, 0x09, 0x90, 0x4d, 0xff, 0x0a, 0x90, 0x4f, 0xff, 0x07, 0x91, 0x50, 0xff, 0x08, 0x93, 0x50, 0xff, 0x08, 0x94, 0x51, 0xff, 0x07, 0x95, 0x51, 0xff, 0x04, 0x96, 0x51, 0xff, 0x06, 0x98, 0x52, 0xff, 0x07, 0x97, 0x52, 0xff, 0x0c, 0x97, 0x54, 0xff, 0x13, 0x99, 0x59, 0xff, 0x0b, 0x82, 0x48, 0xff, 0x07, 0x78, 0x45, 0xff, 0x18, 0x9b, 0x66, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x05, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0f, 0xa0, 0x6f, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0a, 0xaa, 0x6b, 0xff, 0x0a, 0xac, 0x6b, 0xff, 0x08, 0xaa, 0x6a, 0xff, 0x09, 0xa9, 0x6a, 0xff, 0x0c, 0xa9, 0x6c, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0b, 0xab, 0x6b, 0xff, 0x0a, 0xac, 0x6c, 0xff, 0x0a, 0xab, 0x6d, 0xff, 0x0d, 0xab, 0x6e, 0xff, 0x0d, 0xaa, 0x6e, 0xff, 0x0d, 0xaa, 0x6f, 0xff, 0x0a, 0xac, 0x70, 0xff, 0x0b, 0xac, 0x6f, 0xff, 0x0f, 0xae, 0x6e, 0xff, 0x11, 0xae, 0x6f, 0xff, 0x12, 0xae, 0x6f, 0xff, 0x12, 0xad, 0x70, 0xff, 0x13, 0xae, 0x72, 0xff, 0x16, 0xb1, 0x78, 0xff, 0x1d, 0xb2, 0x7f, 0xff, 0x1f, 0xb2, 0x82, 0xff, 0x21, 0xb2, 0x82, 0xff, 0x21, 0xb1, 0x82, 0xff, 0x20, 0xb0, 0x7f, 0xff, 0x20, 0xb1, 0x7e, 0xff, 0x1f, 0xb1, 0x7c, 0xff, 0x1c, 0xb0, 0x79, 0xff, 0x16, 0xaf, 0x76, 0xff, 0x15, 0xaf, 0x76, 0xff, 0x16, 0xb0, 0x76, 0xff, 0x17, 0xb1, 0x76, 0xff, 0x18, 0xb1, 0x78, 0xff, 0x16, 0xb0, 0x76, 0xff, 0x16, 0xaf, 0x75, 0xff, 0x16, 0xae, 0x74, 0xff, 0x12, 0xae, 0x74, 0xff, 0x12, 0xac, 0x75, 0xff, 0x14, 0xaa, 0x74, 0xff, 0x14, 0xa9, 0x75, 0xff, 0x18, 0xa8, 0x78, 0xff, 0x16, 0xa6, 0x78, 0xff, 0x15, 0xa5, 0x79, 0xff, 0x15, 0xa4, 0x79, 0xff, 0x16, 0xa3, 0x77, 0xff, 0x16, 0xa3, 0x77, 0xff, 0x16, 0xa2, 0x78, 0xff, 0x15, 0xa1, 0x78, 0xff, 0x15, 0xa2, 0x7a, 0xff, 0x14, 0xa2, 0x7a, 0xff, 0x13, 0xa4, 0x79, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x18, 0xa8, 0x82, 0xff, 0x19, 0xa8, 0x85, 0xff, 0x1b, 0xab, 0x88, 0xff, 0x19, 0xa9, 0x84, 0xff, 0x14, 0xa4, 0x7d, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x11, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7d, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x15, 0xa4, 0x7d, 0xff, 0x0f, 0x9d, 0x76, 0xff, 0x0c, 0x99, 0x73, 0xff, 0x10, 0x9c, 0x76, 0xff, 0x0e, 0x9d, 0x74, 0xff, 0x0f, 0x9e, 0x76, 0xff, 0x0e, 0x9d, 0x76, 0xff, 0x0f, 0x9e, 0x77, 0xff, 0x12, 0xa0, 0x79, 0xff, 0x16, 0xa3, 0x7a, 0xff, 0x14, 0xa0, 0x76, 0xff, 0x14, 0x9e, 0x73, 0xff, 0x11, 0x99, 0x6a, 0xff, 0x19, 0x92, 0x5f, 0xff, 0x06, 0x6d, 0x35, 0xff, 0x02, 0x67, 0x28, 0xff, 0x0d, 0x7e, 0x3d, 0xff, 0x15, 0x7f, 0x41, 0xff, 0x06, 0x67, 0x31, 0xff, 0x13, 0x7f, 0x4d, 0xff, 0x10, 0x8a, 0x5d, 0xff, 0x0d, 0x8e, 0x64, 0xff, 0x0c, 0x95, 0x6a, 0xff, 0x0d, 0x9a, 0x70, 0xff, 0x13, 0xa2, 0x79, 0xff, 0x16, 0xa6, 0x7d, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x0e, 0xa9, 0x7c, 0xff, 0x0c, 0xa9, 0x7b, 0xff, 0x0e, 0xa8, 0x7b, 0xff, 0x12, 0xaa, 0x7d, 0xff, 0x17, 0xad, 0x81, 0xff, 0x1a, 0xb2, 0x85, 0xff, 0x1d, 0xb8, 0x8b, 0xff, 0x1c, 0xb9, 0x8b, 0xff, 0x1c, 0xb6, 0x88, 0xff, 0x1e, 0xb6, 0x87, 0xff, 0x1e, 0xb5, 0x88, 0xff, 0x1f, 0xb4, 0x87, 0xff, 0x21, 0xb5, 0x89, 0xff, 0x21, 0xb3, 0x89, 0xff, 0x20, 0xb2, 0x89, 0xff, 0x1e, 0xb1, 0x89, 0xff, 0x1d, 0xb5, 0x89, 0xff, 0x1c, 0xb6, 0x89, 0xff, 0x1e, 0xb7, 0x8a, 0xff, 0x1e, 0xb6, 0x8a, 0xff, 0x1f, 0xb6, 0x89, 0xff, 0x1e, 0xb5, 0x8a, 0xff, 0x1d, 0xb6, 0x8b, 0xff, 0x1c, 0xb5, 0x8a, 0xff, 0x1d, 0xb4, 0x89, 0xff, 0x20, 0xb3, 0x8a, 0xff, 0x22, 0xb5, 0x8d, 0xff, 0x23, 0xb6, 0x8f, 0xff, 0x23, 0xb6, 0x8f, 0xff, 0x23, 0xb7, 0x90, 0xff, 0x25, 0xb8, 0x90, 0xff, 0x25, 0xb7, 0x8f, 0xff, 0x25, 0xb7, 0x8e, 0xff, 0x26, 0xb8, 0x8e, 0xff, 0x26, 0xb8, 0x8f, 0xff, 0x29, 0xb9, 0x94, 0xff, 0x2a, 0xb9, 0x97, 0xff, 0x28, 0xb8, 0x98, 0xff, 0x27, 0xb9, 0x98, 0xff, 0x25, 0xb9, 0x97, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xba, 0x96, 0xff, 0x26, 0xb9, 0x96, 0xff, 0x26, 0xb9, 0x97, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x23, 0xb8, 0x91, 0xff, 0x21, 0xb6, 0x8e, 0xff, 0x1d, 0xb2, 0x8a, 0xff, 0x1a, 0xb0, 0x85, 0xff, 0x16, 0xac, 0x81, 0xff, 0x15, 0xab, 0x81, 0xff, 0x16, 0xac, 0x81, 0xff, 0x16, 0xac, 0x81, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x0d, 0xa5, 0x75, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x07, 0xa1, 0x69, 0xff, 0x01, 0xa0, 0x69, 0xff, 0x02, 0xa0, 0x6a, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x07, 0xa0, 0x68, 0xff, 0x08, 0xa0, 0x67, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x08, 0xa1, 0x65, 0xff, 0x05, 0xa1, 0x66, 0xff, 0x02, 0xa1, 0x68, 0xff, 0x06, 0x9f, 0x6c, 0xff, 0x0c, 0xa1, 0x74, 0xff, 0x1b, 0xa9, 0x83, 0xff, 0x24, 0xaf, 0x8b, 0xff, 0x28, 0xb0, 0x8b, 0xff, 0x24, 0xac, 0x85, 0xff, 0x18, 0xa5, 0x77, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x07, 0xa0, 0x68, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x07, 0xa2, 0x68, 0xff, 0x07, 0xa2, 0x68, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0c, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x62, 0xff, 0x0c, 0xa3, 0x62, 0xff, 0x0c, 0xa3, 0x62, 0xff, 0x0b, 0xa3, 0x63, 0xff, 0x0b, 0xa2, 0x61, 0xff, 0x0d, 0xa2, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0d, 0xa2, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa3, 0x5d, 0xff, 0x0e, 0xa2, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa2, 0x5a, 0xff, 0x0f, 0xa2, 0x5a, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0f, 0xa0, 0x58, 0xff, 0x0d, 0x9b, 0x54, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0c, 0x97, 0x53, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0a, 0x94, 0x50, 0xff, 0x0c, 0x94, 0x50, 0xff, 0x0d, 0x94, 0x4e, 0xff, 0x0d, 0x92, 0x4d, 0xff, 0x0d, 0x93, 0x4b, 0xff, 0x0c, 0x92, 0x4a, 0xff, 0x0a, 0x90, 0x49, 0xff, 0x0b, 0x8d, 0x4d, 0xff, 0x08, 0x87, 0x4d, 0xff, 0x0e, 0x89, 0x4f, 0xff, 0x14, 0x7c, 0x46, 0xff, 0x05, 0x54, 0x3a, 0xff, 0x07, 0x59, 0x63, 0xff, 0x19, 0x8a, 0xbf, 0xff, 0x2b, 0xa6, 0xe9, 0xff, 0x0d, 0x75, 0xbd, 0xff, 0x23, 0x9f, 0xde, 0xff, 0x0c, 0x86, 0xbd, 0xff, 0x09, 0x7b, 0xc2, 0xff, 0x0f, 0x67, 0xb6, 0xff, 0x14, 0x58, 0x83, 0xff, 0x09, 0x57, 0x3f, 0xff, 0x08, 0x5e, 0x37, 0xff, 0x14, 0x49, 0x66, 0xff, 0x37, 0x45, 0xae, 0xff, 0x4f, 0x53, 0xd7, 0xff, 0x42, 0x4d, 0xcf, 0xff, 0x43, 0x4a, 0xd0, 0xff, 0x81, 0x86, 0xf8, 0xff, 0x87, 0x8b, 0xf2, 0xff, 0x4f, 0x4e, 0xbf, 0xff, 0x6e, 0x6d, 0xdb, 0xff, 0x4f, 0x61, 0xa6, 0xff, 0x18, 0x4c, 0x44, 0xff, 0x11, 0x50, 0x30, 0xff, 0x0d, 0x5c, 0x38, 0xff, 0x14, 0x63, 0x3d, 0xff, 0xa6, 0xbe, 0xb4, 0xff, + 0x0b, 0x8d, 0x4f, 0xff, 0x0b, 0x8f, 0x4b, 0xff, 0x08, 0x8f, 0x4a, 0xff, 0x09, 0x8f, 0x4c, 0xff, 0x0a, 0x90, 0x4e, 0xff, 0x09, 0x92, 0x51, 0xff, 0x08, 0x93, 0x50, 0xff, 0x06, 0x95, 0x51, 0xff, 0x06, 0x95, 0x51, 0xff, 0x05, 0x95, 0x50, 0xff, 0x06, 0x95, 0x50, 0xff, 0x0d, 0x96, 0x53, 0xff, 0x0f, 0x94, 0x55, 0xff, 0x0b, 0x87, 0x4b, 0xff, 0x06, 0x7a, 0x43, 0xff, 0x13, 0x94, 0x61, 0xff, 0x14, 0xa2, 0x6e, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x06, 0xa3, 0x6c, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa6, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0x9a, 0x6c, 0xff, 0x0c, 0x9d, 0x6a, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0a, 0xaa, 0x6a, 0xff, 0x09, 0xaa, 0x6a, 0xff, 0x0a, 0xa9, 0x69, 0xff, 0x0d, 0xa9, 0x6b, 0xff, 0x0c, 0xa8, 0x6b, 0xff, 0x0c, 0xab, 0x6a, 0xff, 0x0b, 0xac, 0x6b, 0xff, 0x0a, 0xab, 0x6c, 0xff, 0x0d, 0xac, 0x6d, 0xff, 0x0d, 0xab, 0x6d, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x10, 0xaa, 0x6e, 0xff, 0x11, 0xac, 0x6e, 0xff, 0x13, 0xae, 0x6e, 0xff, 0x13, 0xae, 0x6e, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x11, 0xae, 0x6e, 0xff, 0x0f, 0xae, 0x70, 0xff, 0x10, 0xae, 0x73, 0xff, 0x19, 0xad, 0x79, 0xff, 0x1d, 0xb0, 0x7d, 0xff, 0x20, 0xb1, 0x7f, 0xff, 0x20, 0xb0, 0x7f, 0xff, 0x1f, 0xb1, 0x7d, 0xff, 0x1f, 0xb2, 0x7c, 0xff, 0x1e, 0xb2, 0x7a, 0xff, 0x1c, 0xb2, 0x79, 0xff, 0x17, 0xb1, 0x76, 0xff, 0x16, 0xb1, 0x75, 0xff, 0x16, 0xb0, 0x75, 0xff, 0x17, 0xb1, 0x76, 0xff, 0x16, 0xb0, 0x75, 0xff, 0x14, 0xaf, 0x74, 0xff, 0x14, 0xae, 0x72, 0xff, 0x15, 0xae, 0x72, 0xff, 0x14, 0xad, 0x72, 0xff, 0x15, 0xab, 0x71, 0xff, 0x14, 0xa9, 0x71, 0xff, 0x13, 0xa8, 0x72, 0xff, 0x15, 0xa8, 0x75, 0xff, 0x14, 0xa6, 0x76, 0xff, 0x13, 0xa6, 0x77, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x13, 0xa5, 0x77, 0xff, 0x14, 0xa4, 0x78, 0xff, 0x15, 0xa3, 0x78, 0xff, 0x15, 0xa3, 0x79, 0xff, 0x14, 0xa3, 0x79, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x14, 0xa5, 0x7e, 0xff, 0x14, 0xa5, 0x7f, 0xff, 0x14, 0xa5, 0x81, 0xff, 0x17, 0xa7, 0x83, 0xff, 0x15, 0xa6, 0x80, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x11, 0xa5, 0x7f, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x11, 0x9f, 0x78, 0xff, 0x0e, 0x9b, 0x74, 0xff, 0x0e, 0x9a, 0x74, 0xff, 0x0d, 0x9d, 0x74, 0xff, 0x0c, 0x9c, 0x74, 0xff, 0x10, 0x9f, 0x78, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x79, 0xff, 0x16, 0xa0, 0x78, 0xff, 0x13, 0x9d, 0x74, 0xff, 0x0d, 0x96, 0x6c, 0xff, 0x1f, 0x97, 0x6c, 0xff, 0x0e, 0x76, 0x46, 0xff, 0x04, 0x6f, 0x37, 0xff, 0x03, 0x74, 0x37, 0xff, 0x0e, 0x80, 0x44, 0xff, 0x07, 0x77, 0x40, 0xff, 0x0b, 0x81, 0x4e, 0xff, 0x0a, 0x85, 0x57, 0xff, 0x03, 0x81, 0x57, 0xff, 0x02, 0x88, 0x5c, 0xff, 0x04, 0x8d, 0x62, 0xff, 0x0f, 0x9c, 0x72, 0xff, 0x13, 0xa2, 0x78, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x10, 0xa6, 0x7a, 0xff, 0x0f, 0xa7, 0x7b, 0xff, 0x10, 0xa8, 0x7c, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x12, 0xa8, 0x7b, 0xff, 0x12, 0xa8, 0x7c, 0xff, 0x14, 0xac, 0x7f, 0xff, 0x17, 0xb4, 0x86, 0xff, 0x18, 0xb7, 0x89, 0xff, 0x18, 0xb5, 0x87, 0xff, 0x1d, 0xb6, 0x88, 0xff, 0x20, 0xb7, 0x8a, 0xff, 0x21, 0xb7, 0x8b, 0xff, 0x23, 0xb7, 0x8c, 0xff, 0x24, 0xb6, 0x8c, 0xff, 0x23, 0xb3, 0x8b, 0xff, 0x23, 0xb3, 0x8c, 0xff, 0x21, 0xb7, 0x8b, 0xff, 0x1e, 0xb8, 0x8a, 0xff, 0x1f, 0xb9, 0x8c, 0xff, 0x1f, 0xb7, 0x8b, 0xff, 0x20, 0xb8, 0x8b, 0xff, 0x1f, 0xb6, 0x8b, 0xff, 0x1f, 0xb8, 0x8c, 0xff, 0x1e, 0xb8, 0x8c, 0xff, 0x21, 0xb6, 0x8e, 0xff, 0x25, 0xb5, 0x8e, 0xff, 0x24, 0xb5, 0x8f, 0xff, 0x24, 0xb5, 0x8f, 0xff, 0x22, 0xb5, 0x8f, 0xff, 0x23, 0xb6, 0x90, 0xff, 0x23, 0xb6, 0x91, 0xff, 0x24, 0xb6, 0x91, 0xff, 0x23, 0xb7, 0x90, 0xff, 0x22, 0xb8, 0x8e, 0xff, 0x25, 0xb9, 0x90, 0xff, 0x28, 0xb9, 0x93, 0xff, 0x29, 0xb9, 0x96, 0xff, 0x27, 0xb8, 0x96, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x25, 0xb8, 0x96, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x25, 0xb9, 0x94, 0xff, 0x25, 0xb9, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x96, 0xff, 0x24, 0xb9, 0x95, 0xff, 0x23, 0xb8, 0x93, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x23, 0xb8, 0x91, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x1f, 0xb4, 0x8c, 0xff, 0x1b, 0xb1, 0x86, 0xff, 0x18, 0xae, 0x82, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x15, 0xab, 0x80, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x03, 0xa2, 0x66, 0xff, 0x04, 0xa1, 0x67, 0xff, 0x08, 0xa1, 0x68, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0c, 0xa1, 0x69, 0xff, 0x0a, 0xa0, 0x69, 0xff, 0x09, 0xa0, 0x69, 0xff, 0x07, 0xa1, 0x69, 0xff, 0x03, 0xa1, 0x68, 0xff, 0x04, 0x9f, 0x6a, 0xff, 0x06, 0x9d, 0x6d, 0xff, 0x0f, 0xa2, 0x78, 0xff, 0x18, 0xa7, 0x80, 0xff, 0x1f, 0xad, 0x83, 0xff, 0x17, 0xa5, 0x79, 0xff, 0x10, 0xa0, 0x70, 0xff, 0x08, 0xa0, 0x6a, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x06, 0xa2, 0x69, 0xff, 0x07, 0xa1, 0x69, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x09, 0xa0, 0x6a, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa3, 0x69, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x09, 0xa2, 0x65, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0c, 0xa2, 0x62, 0xff, 0x0b, 0xa3, 0x62, 0xff, 0x0b, 0xa3, 0x62, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x62, 0xff, 0x0b, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0e, 0xa3, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x0d, 0x9b, 0x55, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0c, 0x98, 0x53, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0a, 0x94, 0x50, 0xff, 0x0d, 0x94, 0x50, 0xff, 0x0d, 0x93, 0x4e, 0xff, 0x0d, 0x92, 0x4c, 0xff, 0x0d, 0x93, 0x4b, 0xff, 0x0b, 0x91, 0x49, 0xff, 0x0b, 0x91, 0x49, 0xff, 0x09, 0x8d, 0x4b, 0xff, 0x08, 0x8a, 0x4c, 0xff, 0x0c, 0x8a, 0x4d, 0xff, 0x12, 0x83, 0x48, 0xff, 0x0b, 0x68, 0x3e, 0xff, 0x04, 0x63, 0x52, 0xff, 0x1b, 0x94, 0xa1, 0xff, 0x1f, 0x9c, 0xc0, 0xff, 0x02, 0x58, 0x91, 0xff, 0x09, 0x6f, 0xab, 0xff, 0x05, 0x79, 0xb8, 0xff, 0x06, 0x76, 0xc4, 0xff, 0x0e, 0x67, 0xbf, 0xff, 0x17, 0x64, 0x9b, 0xff, 0x02, 0x54, 0x3a, 0xff, 0x02, 0x5e, 0x2a, 0xff, 0x0f, 0x47, 0x64, 0xff, 0x33, 0x43, 0xb6, 0xff, 0x3e, 0x47, 0xd9, 0xff, 0x38, 0x45, 0xd7, 0xff, 0x3b, 0x43, 0xd4, 0xff, 0x6b, 0x73, 0xeb, 0xff, 0x5c, 0x6a, 0xc4, 0xff, 0x27, 0x2e, 0x89, 0xff, 0x3f, 0x46, 0xa0, 0xff, 0x3c, 0x59, 0x8f, 0xff, 0x0a, 0x45, 0x3a, 0xff, 0x10, 0x50, 0x34, 0xff, 0x0b, 0x56, 0x36, 0xff, 0x0a, 0x56, 0x32, 0xff, 0xa4, 0xbb, 0xb2, 0xff, + 0x09, 0x8a, 0x4c, 0xff, 0x09, 0x8c, 0x49, 0xff, 0x07, 0x8e, 0x48, 0xff, 0x08, 0x8f, 0x4b, 0xff, 0x0b, 0x90, 0x4f, 0xff, 0x0a, 0x93, 0x52, 0xff, 0x08, 0x94, 0x51, 0xff, 0x04, 0x95, 0x51, 0xff, 0x05, 0x95, 0x51, 0xff, 0x08, 0x95, 0x50, 0xff, 0x0b, 0x93, 0x50, 0xff, 0x0e, 0x91, 0x52, 0xff, 0x11, 0x8f, 0x53, 0xff, 0x03, 0x70, 0x3a, 0xff, 0x11, 0x90, 0x5b, 0xff, 0x12, 0xa1, 0x6e, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x08, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x06, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0c, 0x9a, 0x6f, 0xff, 0x1b, 0xa9, 0x7b, 0xff, 0x12, 0xa4, 0x73, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0d, 0xa8, 0x6e, 0xff, 0x0d, 0xa9, 0x6c, 0xff, 0x0c, 0xac, 0x6b, 0xff, 0x0b, 0xab, 0x69, 0xff, 0x0e, 0xaa, 0x6a, 0xff, 0x0d, 0xa9, 0x69, 0xff, 0x0c, 0xa9, 0x69, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0c, 0xab, 0x6b, 0xff, 0x0d, 0xac, 0x6c, 0xff, 0x0f, 0xac, 0x6c, 0xff, 0x0f, 0xab, 0x6c, 0xff, 0x12, 0xaa, 0x6c, 0xff, 0x15, 0xab, 0x6d, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x10, 0xae, 0x6c, 0xff, 0x0f, 0xae, 0x6e, 0xff, 0x10, 0xad, 0x70, 0xff, 0x16, 0xaa, 0x71, 0xff, 0x17, 0xad, 0x72, 0xff, 0x19, 0xae, 0x74, 0xff, 0x19, 0xaf, 0x76, 0xff, 0x16, 0xb0, 0x75, 0xff, 0x14, 0xb0, 0x73, 0xff, 0x14, 0xb1, 0x71, 0xff, 0x15, 0xb1, 0x72, 0xff, 0x14, 0xae, 0x73, 0xff, 0x12, 0xae, 0x71, 0xff, 0x12, 0xad, 0x70, 0xff, 0x12, 0xad, 0x70, 0xff, 0x11, 0xad, 0x70, 0xff, 0x11, 0xad, 0x6f, 0xff, 0x11, 0xad, 0x6f, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xad, 0x70, 0xff, 0x12, 0xab, 0x70, 0xff, 0x11, 0xab, 0x70, 0xff, 0x10, 0xaa, 0x71, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x12, 0xa5, 0x77, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x10, 0xa4, 0x7e, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x14, 0xa1, 0x7a, 0xff, 0x16, 0xa3, 0x7c, 0xff, 0x18, 0xa4, 0x7d, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x10, 0x9f, 0x78, 0xff, 0x0f, 0x9d, 0x76, 0xff, 0x0e, 0x99, 0x73, 0xff, 0x0d, 0x98, 0x71, 0xff, 0x0b, 0x96, 0x6f, 0xff, 0x0b, 0x95, 0x6f, 0xff, 0x13, 0x91, 0x6a, 0xff, 0x07, 0x77, 0x4d, 0xff, 0x05, 0x76, 0x46, 0xff, 0x04, 0x7a, 0x44, 0xff, 0x05, 0x80, 0x4a, 0xff, 0x06, 0x87, 0x51, 0xff, 0x0d, 0x8e, 0x5a, 0xff, 0x16, 0x95, 0x68, 0xff, 0x0b, 0x8c, 0x63, 0xff, 0x0a, 0x93, 0x67, 0xff, 0x09, 0x94, 0x69, 0xff, 0x0c, 0x99, 0x6f, 0xff, 0x0d, 0x9d, 0x71, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x0e, 0xa6, 0x79, 0xff, 0x10, 0xa5, 0x7b, 0xff, 0x14, 0xa7, 0x7d, 0xff, 0x15, 0xa7, 0x7c, 0xff, 0x15, 0xa7, 0x7b, 0xff, 0x13, 0xa7, 0x7b, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x13, 0xac, 0x7e, 0xff, 0x10, 0xad, 0x7e, 0xff, 0x15, 0xb1, 0x81, 0xff, 0x1a, 0xb6, 0x88, 0xff, 0x1c, 0xb7, 0x89, 0xff, 0x1d, 0xb5, 0x8a, 0xff, 0x20, 0xb6, 0x8b, 0xff, 0x23, 0xb8, 0x8e, 0xff, 0x21, 0xb7, 0x8d, 0xff, 0x22, 0xb7, 0x8b, 0xff, 0x23, 0xb8, 0x8a, 0xff, 0x24, 0xb8, 0x8c, 0xff, 0x24, 0xb7, 0x8b, 0xff, 0x24, 0xb6, 0x8b, 0xff, 0x22, 0xb5, 0x8b, 0xff, 0x22, 0xb4, 0x8a, 0xff, 0x22, 0xb5, 0x8c, 0xff, 0x22, 0xb5, 0x8e, 0xff, 0x21, 0xb4, 0x8e, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x21, 0xb7, 0x90, 0xff, 0x21, 0xb7, 0x90, 0xff, 0x20, 0xb7, 0x91, 0xff, 0x20, 0xb6, 0x92, 0xff, 0x21, 0xb6, 0x92, 0xff, 0x1e, 0xb8, 0x91, 0xff, 0x1b, 0xb9, 0x90, 0xff, 0x1e, 0xb9, 0x91, 0xff, 0x22, 0xba, 0x93, 0xff, 0x24, 0xb9, 0x94, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x95, 0xff, 0x25, 0xb9, 0x94, 0xff, 0x25, 0xb9, 0x93, 0xff, 0x25, 0xb9, 0x93, 0xff, 0x25, 0xb9, 0x93, 0xff, 0x24, 0xb8, 0x93, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb9, 0x95, 0xff, 0x23, 0xba, 0x96, 0xff, 0x21, 0xb8, 0x94, 0xff, 0x22, 0xb7, 0x93, 0xff, 0x24, 0xb8, 0x92, 0xff, 0x23, 0xb8, 0x91, 0xff, 0x1f, 0xb4, 0x8c, 0xff, 0x1c, 0xb1, 0x88, 0xff, 0x18, 0xae, 0x83, 0xff, 0x15, 0xad, 0x7f, 0xff, 0x14, 0xaa, 0x7e, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x14, 0xaa, 0x7e, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x0e, 0xa1, 0x68, 0xff, 0x12, 0xa6, 0x6f, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x07, 0xa0, 0x6a, 0xff, 0x06, 0xa0, 0x69, 0xff, 0x09, 0xa0, 0x64, 0xff, 0x09, 0xa0, 0x67, 0xff, 0x08, 0x9e, 0x69, 0xff, 0x07, 0x9e, 0x6c, 0xff, 0x08, 0x9f, 0x6d, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x04, 0x9f, 0x69, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x05, 0xa2, 0x6a, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0b, 0x9f, 0x6b, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x04, 0xa2, 0x6c, 0xff, 0x02, 0xa5, 0x6d, 0xff, 0x07, 0xa3, 0x6b, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x66, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa3, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa2, 0x60, 0xff, 0x0c, 0xa3, 0x5f, 0xff, 0x0c, 0xa2, 0x5d, 0xff, 0x0f, 0xa3, 0x5c, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x0d, 0x9c, 0x55, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x0c, 0x97, 0x53, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0a, 0x94, 0x50, 0xff, 0x0d, 0x94, 0x4e, 0xff, 0x0d, 0x93, 0x4d, 0xff, 0x0d, 0x92, 0x4c, 0xff, 0x0d, 0x92, 0x4b, 0xff, 0x0a, 0x90, 0x4a, 0xff, 0x0b, 0x91, 0x48, 0xff, 0x09, 0x8f, 0x47, 0xff, 0x08, 0x8d, 0x49, 0xff, 0x0d, 0x8d, 0x49, 0xff, 0x0f, 0x85, 0x44, 0xff, 0x11, 0x7c, 0x43, 0xff, 0x06, 0x75, 0x46, 0xff, 0x05, 0x7f, 0x5e, 0xff, 0x06, 0x78, 0x70, 0xff, 0x06, 0x61, 0x6f, 0xff, 0x08, 0x5f, 0x83, 0xff, 0x0c, 0x76, 0xba, 0xff, 0x0c, 0x80, 0xd2, 0xff, 0x1d, 0x8d, 0xe6, 0xff, 0x1b, 0x76, 0xb4, 0xff, 0x03, 0x50, 0x32, 0xff, 0x0e, 0x75, 0x30, 0xff, 0x0c, 0x4a, 0x5d, 0xff, 0x2c, 0x41, 0xbc, 0xff, 0x39, 0x48, 0xec, 0xff, 0x3d, 0x4c, 0xec, 0xff, 0x3f, 0x49, 0xd9, 0xff, 0x3f, 0x52, 0xb6, 0xff, 0x17, 0x39, 0x68, 0xff, 0x16, 0x34, 0x5a, 0xff, 0x1a, 0x3d, 0x5c, 0xff, 0x0f, 0x49, 0x4c, 0xff, 0x03, 0x51, 0x34, 0xff, 0x09, 0x4f, 0x34, 0xff, 0x0a, 0x50, 0x39, 0xff, 0x07, 0x4e, 0x31, 0xff, 0x9b, 0xbb, 0xb1, 0xff, + 0x08, 0x88, 0x4a, 0xff, 0x0a, 0x8c, 0x49, 0xff, 0x09, 0x8e, 0x49, 0xff, 0x0b, 0x90, 0x4e, 0xff, 0x0d, 0x90, 0x50, 0xff, 0x0b, 0x92, 0x51, 0xff, 0x08, 0x92, 0x4f, 0xff, 0x04, 0x92, 0x4f, 0xff, 0x06, 0x93, 0x4e, 0xff, 0x0c, 0x92, 0x4f, 0xff, 0x0e, 0x91, 0x50, 0xff, 0x0d, 0x8c, 0x50, 0xff, 0x03, 0x74, 0x3d, 0xff, 0x10, 0x88, 0x56, 0xff, 0x16, 0x9d, 0x6a, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x30, 0xbb, 0x94, 0xff, 0x3c, 0xc9, 0xa0, 0xff, 0x18, 0xa7, 0x7a, 0xff, 0x16, 0xaa, 0x78, 0xff, 0x15, 0xad, 0x75, 0xff, 0x0d, 0xa8, 0x6b, 0xff, 0x0c, 0xab, 0x6a, 0xff, 0x0e, 0xad, 0x6b, 0xff, 0x10, 0xaa, 0x6a, 0xff, 0x0e, 0xa9, 0x6a, 0xff, 0x0d, 0xa9, 0x69, 0xff, 0x0d, 0xaa, 0x6a, 0xff, 0x0e, 0xab, 0x6b, 0xff, 0x0e, 0xac, 0x6b, 0xff, 0x0f, 0xad, 0x6b, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xab, 0x6b, 0xff, 0x10, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6a, 0xff, 0x11, 0xad, 0x6b, 0xff, 0x11, 0xaf, 0x6c, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x14, 0xad, 0x6e, 0xff, 0x15, 0xae, 0x6d, 0xff, 0x15, 0xae, 0x6c, 0xff, 0x15, 0xad, 0x6d, 0xff, 0x16, 0xad, 0x6d, 0xff, 0x17, 0xad, 0x6e, 0xff, 0x16, 0xac, 0x6c, 0xff, 0x17, 0xad, 0x6c, 0xff, 0x18, 0xad, 0x6c, 0xff, 0x16, 0xad, 0x6f, 0xff, 0x16, 0xad, 0x6f, 0xff, 0x15, 0xac, 0x6e, 0xff, 0x15, 0xac, 0x6d, 0xff, 0x15, 0xac, 0x6e, 0xff, 0x15, 0xad, 0x6d, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x13, 0xad, 0x6e, 0xff, 0x10, 0xac, 0x70, 0xff, 0x10, 0xac, 0x70, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xab, 0x70, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x14, 0xa8, 0x72, 0xff, 0x14, 0xa6, 0x74, 0xff, 0x14, 0xa5, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0c, 0xa5, 0x79, 0xff, 0x0c, 0xa5, 0x79, 0xff, 0x0f, 0xa3, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa4, 0x7b, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x13, 0xa2, 0x7d, 0xff, 0x15, 0xa4, 0x7c, 0xff, 0x14, 0xa1, 0x7a, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x17, 0xa4, 0x7d, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x0f, 0x9d, 0x76, 0xff, 0x0a, 0x99, 0x72, 0xff, 0x0a, 0x97, 0x70, 0xff, 0x0c, 0x98, 0x72, 0xff, 0x0c, 0x99, 0x72, 0xff, 0x0f, 0x9a, 0x74, 0xff, 0x13, 0x9d, 0x77, 0xff, 0x0c, 0x92, 0x6a, 0xff, 0x03, 0x82, 0x59, 0xff, 0x05, 0x82, 0x57, 0xff, 0x14, 0x90, 0x63, 0xff, 0x10, 0x92, 0x63, 0xff, 0x04, 0x8a, 0x5a, 0xff, 0x14, 0x9d, 0x6e, 0xff, 0x19, 0xa0, 0x77, 0xff, 0x19, 0xa2, 0x7a, 0xff, 0x15, 0xa3, 0x7a, 0xff, 0x14, 0xa4, 0x7a, 0xff, 0x14, 0xa2, 0x78, 0xff, 0x12, 0xa1, 0x78, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x10, 0xa7, 0x7c, 0xff, 0x0e, 0xa6, 0x7b, 0xff, 0x0f, 0xa8, 0x7d, 0xff, 0x0f, 0xa9, 0x7c, 0xff, 0x10, 0xa8, 0x7b, 0xff, 0x0f, 0xa8, 0x7a, 0xff, 0x0f, 0xa8, 0x79, 0xff, 0x12, 0xa9, 0x79, 0xff, 0x12, 0xa9, 0x78, 0xff, 0x13, 0xa9, 0x78, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x14, 0xab, 0x7a, 0xff, 0x13, 0xac, 0x7b, 0xff, 0x13, 0xac, 0x7d, 0xff, 0x17, 0xb1, 0x82, 0xff, 0x1c, 0xb5, 0x89, 0xff, 0x1d, 0xb7, 0x89, 0xff, 0x1f, 0xb6, 0x88, 0xff, 0x21, 0xb7, 0x89, 0xff, 0x21, 0xb7, 0x8a, 0xff, 0x22, 0xb7, 0x8b, 0xff, 0x22, 0xb7, 0x8c, 0xff, 0x22, 0xb6, 0x8b, 0xff, 0x21, 0xb5, 0x8b, 0xff, 0x21, 0xb5, 0x8d, 0xff, 0x21, 0xb5, 0x8d, 0xff, 0x1f, 0xb6, 0x8c, 0xff, 0x20, 0xb7, 0x8e, 0xff, 0x21, 0xb8, 0x8f, 0xff, 0x21, 0xb8, 0x90, 0xff, 0x23, 0xb7, 0x90, 0xff, 0x25, 0xb7, 0x91, 0xff, 0x27, 0xb6, 0x91, 0xff, 0x21, 0xb7, 0x91, 0xff, 0x1a, 0xb8, 0x90, 0xff, 0x1d, 0xb9, 0x91, 0xff, 0x1f, 0xb9, 0x92, 0xff, 0x21, 0xba, 0x94, 0xff, 0x23, 0xba, 0x94, 0xff, 0x24, 0xba, 0x94, 0xff, 0x23, 0xba, 0x94, 0xff, 0x24, 0xb9, 0x93, 0xff, 0x25, 0xb9, 0x93, 0xff, 0x25, 0xb9, 0x93, 0xff, 0x24, 0xb8, 0x92, 0xff, 0x23, 0xb7, 0x92, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x24, 0xb8, 0x94, 0xff, 0x22, 0xb8, 0x94, 0xff, 0x20, 0xb7, 0x92, 0xff, 0x20, 0xb7, 0x91, 0xff, 0x23, 0xb7, 0x90, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x1b, 0xb1, 0x88, 0xff, 0x17, 0xad, 0x83, 0xff, 0x16, 0xab, 0x80, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x10, 0xa2, 0x69, 0xff, 0x0f, 0xa3, 0x69, 0xff, 0x0e, 0xa1, 0x6a, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x11, 0xa5, 0x71, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x08, 0xa1, 0x6b, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x09, 0xa2, 0x66, 0xff, 0x09, 0xa1, 0x67, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x07, 0x9f, 0x67, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x10, 0xa7, 0x70, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x05, 0xa0, 0x69, 0xff, 0x05, 0xa1, 0x6a, 0xff, 0x05, 0xa1, 0x6a, 0xff, 0x05, 0xa0, 0x69, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x0d, 0xa0, 0x6a, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa2, 0x61, 0xff, 0x0c, 0xa2, 0x60, 0xff, 0x0c, 0xa3, 0x5e, 0xff, 0x0f, 0xa3, 0x5c, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa1, 0x59, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0x9f, 0x57, 0xff, 0x0e, 0x9d, 0x55, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0a, 0x97, 0x51, 0xff, 0x0a, 0x96, 0x50, 0xff, 0x0b, 0x95, 0x4f, 0xff, 0x0d, 0x94, 0x4e, 0xff, 0x0d, 0x93, 0x4d, 0xff, 0x0d, 0x91, 0x4d, 0xff, 0x0c, 0x90, 0x4d, 0xff, 0x0a, 0x90, 0x4c, 0xff, 0x0c, 0x8f, 0x4a, 0xff, 0x0a, 0x90, 0x48, 0xff, 0x07, 0x8f, 0x47, 0xff, 0x0d, 0x8e, 0x47, 0xff, 0x0f, 0x88, 0x45, 0xff, 0x09, 0x7d, 0x40, 0xff, 0x06, 0x7b, 0x42, 0xff, 0x03, 0x78, 0x42, 0xff, 0x05, 0x74, 0x47, 0xff, 0x04, 0x72, 0x4b, 0xff, 0x05, 0x68, 0x5c, 0xff, 0x0d, 0x62, 0x89, 0xff, 0x11, 0x78, 0xb3, 0xff, 0x1d, 0x9c, 0xdb, 0xff, 0x17, 0x7f, 0xaa, 0xff, 0x04, 0x4a, 0x27, 0xff, 0x23, 0x82, 0x39, 0xff, 0x0d, 0x51, 0x48, 0xff, 0x21, 0x3b, 0xa4, 0xff, 0x37, 0x47, 0xed, 0xff, 0x3e, 0x4f, 0xe4, 0xff, 0x30, 0x47, 0xab, 0xff, 0x10, 0x3e, 0x66, 0xff, 0x06, 0x4e, 0x3f, 0xff, 0x09, 0x52, 0x37, 0xff, 0x03, 0x52, 0x30, 0xff, 0x05, 0x66, 0x33, 0xff, 0x08, 0x6b, 0x34, 0xff, 0x05, 0x4f, 0x2c, 0xff, 0x0c, 0x50, 0x3c, 0xff, 0x09, 0x4d, 0x37, 0xff, 0x9b, 0xba, 0xb1, 0xff, + 0x08, 0x87, 0x4a, 0xff, 0x0b, 0x8c, 0x49, 0xff, 0x09, 0x8e, 0x4a, 0xff, 0x0a, 0x8f, 0x4c, 0xff, 0x0c, 0x8e, 0x4f, 0xff, 0x09, 0x90, 0x4f, 0xff, 0x06, 0x8f, 0x4d, 0xff, 0x04, 0x90, 0x4c, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0f, 0x90, 0x4e, 0xff, 0x10, 0x8e, 0x4f, 0xff, 0x03, 0x77, 0x3c, 0xff, 0x0b, 0x84, 0x51, 0xff, 0x18, 0x9a, 0x6b, 0xff, 0x0f, 0x9a, 0x6a, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x05, 0xa3, 0x6b, 0xff, 0x06, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x07, 0xa5, 0x6d, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x23, 0xad, 0x8a, 0xff, 0x32, 0xbe, 0x98, 0xff, 0x29, 0xb7, 0x8d, 0xff, 0x16, 0xa7, 0x78, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0f, 0xa9, 0x6e, 0xff, 0x0c, 0xaa, 0x6a, 0xff, 0x0e, 0xab, 0x6a, 0xff, 0x12, 0xab, 0x6a, 0xff, 0x10, 0xa9, 0x69, 0xff, 0x0e, 0xaa, 0x6a, 0xff, 0x0e, 0xab, 0x6b, 0xff, 0x0e, 0xab, 0x6b, 0xff, 0x0e, 0xac, 0x6a, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x0f, 0xac, 0x6c, 0xff, 0x0f, 0xac, 0x6a, 0xff, 0x0e, 0xad, 0x6a, 0xff, 0x0e, 0xae, 0x6b, 0xff, 0x10, 0xae, 0x6b, 0xff, 0x12, 0xae, 0x6c, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x12, 0xaf, 0x6d, 0xff, 0x13, 0xaf, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x13, 0xad, 0x6e, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x15, 0xad, 0x6d, 0xff, 0x15, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6d, 0xff, 0x14, 0xae, 0x6e, 0xff, 0x14, 0xae, 0x6e, 0xff, 0x13, 0xae, 0x6c, 0xff, 0x12, 0xae, 0x6c, 0xff, 0x13, 0xaf, 0x6d, 0xff, 0x12, 0xaf, 0x6c, 0xff, 0x12, 0xae, 0x6c, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xac, 0x70, 0xff, 0x12, 0xaa, 0x72, 0xff, 0x12, 0xa9, 0x72, 0xff, 0x12, 0xa7, 0x73, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x11, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x12, 0xa5, 0x78, 0xff, 0x12, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x79, 0xff, 0x11, 0xa5, 0x79, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa5, 0x7a, 0xff, 0x13, 0xa6, 0x7a, 0xff, 0x13, 0xa4, 0x7a, 0xff, 0x13, 0xa4, 0x7a, 0xff, 0x13, 0xa3, 0x7b, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x13, 0xa3, 0x7c, 0xff, 0x14, 0xa3, 0x7d, 0xff, 0x13, 0xa2, 0x7d, 0xff, 0x13, 0xa3, 0x7d, 0xff, 0x13, 0xa3, 0x7d, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x16, 0xa4, 0x7d, 0xff, 0x19, 0xa6, 0x7f, 0xff, 0x17, 0xa4, 0x7d, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x11, 0x9e, 0x77, 0xff, 0x13, 0xa1, 0x7a, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x15, 0xa1, 0x7b, 0xff, 0x1c, 0xa4, 0x7c, 0xff, 0x14, 0xa3, 0x79, 0xff, 0x0c, 0x9f, 0x75, 0xff, 0x0f, 0x96, 0x6f, 0xff, 0x1a, 0x95, 0x6f, 0xff, 0x1a, 0x9a, 0x74, 0xff, 0x08, 0x8f, 0x66, 0xff, 0x15, 0xa3, 0x79, 0xff, 0x14, 0xa3, 0x7d, 0xff, 0x13, 0xa5, 0x7f, 0xff, 0x0e, 0xa4, 0x7c, 0xff, 0x10, 0xa5, 0x7d, 0xff, 0x15, 0xa6, 0x7d, 0xff, 0x15, 0xa5, 0x7d, 0xff, 0x13, 0xa4, 0x7c, 0xff, 0x10, 0xa5, 0x7c, 0xff, 0x11, 0xa6, 0x7b, 0xff, 0x14, 0xa7, 0x7d, 0xff, 0x10, 0xa8, 0x7c, 0xff, 0x0f, 0xa8, 0x7b, 0xff, 0x0e, 0xaa, 0x7b, 0xff, 0x0f, 0xaa, 0x7a, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x78, 0xff, 0x13, 0xaa, 0x76, 0xff, 0x11, 0xaa, 0x75, 0xff, 0x10, 0xaa, 0x76, 0xff, 0x11, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x0f, 0xaa, 0x79, 0xff, 0x10, 0xad, 0x7b, 0xff, 0x13, 0xaf, 0x7f, 0xff, 0x18, 0xb2, 0x82, 0xff, 0x1a, 0xb3, 0x84, 0xff, 0x1b, 0xb4, 0x86, 0xff, 0x1c, 0xb6, 0x89, 0xff, 0x1c, 0xb5, 0x89, 0xff, 0x1d, 0xb6, 0x8b, 0xff, 0x1f, 0xb5, 0x8c, 0xff, 0x1f, 0xb5, 0x8d, 0xff, 0x21, 0xb7, 0x8c, 0xff, 0x20, 0xb8, 0x8c, 0xff, 0x1e, 0xb7, 0x8b, 0xff, 0x1e, 0xb7, 0x8c, 0xff, 0x1e, 0xb8, 0x8d, 0xff, 0x20, 0xb8, 0x8e, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x23, 0xb7, 0x8f, 0xff, 0x24, 0xb7, 0x90, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x22, 0xb7, 0x91, 0xff, 0x22, 0xb8, 0x92, 0xff, 0x21, 0xb9, 0x92, 0xff, 0x21, 0xba, 0x93, 0xff, 0x20, 0xb9, 0x92, 0xff, 0x22, 0xb9, 0x92, 0xff, 0x24, 0xb8, 0x91, 0xff, 0x23, 0xb7, 0x91, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x20, 0xb4, 0x8f, 0xff, 0x21, 0xb5, 0x91, 0xff, 0x22, 0xb6, 0x92, 0xff, 0x23, 0xb7, 0x93, 0xff, 0x23, 0xb8, 0x94, 0xff, 0x20, 0xb6, 0x92, 0xff, 0x1f, 0xb6, 0x91, 0xff, 0x1f, 0xb5, 0x8e, 0xff, 0x20, 0xb4, 0x8e, 0xff, 0x1d, 0xb2, 0x8a, 0xff, 0x17, 0xac, 0x83, 0xff, 0x15, 0xaa, 0x7f, 0xff, 0x16, 0xab, 0x80, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x11, 0xaa, 0x76, 0xff, 0x12, 0xab, 0x77, 0xff, 0x11, 0xa9, 0x76, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x07, 0xa1, 0x69, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x09, 0xa1, 0x68, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x0b, 0x9e, 0x69, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x08, 0xa0, 0x6a, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0b, 0xa1, 0x6a, 0xff, 0x0b, 0xa1, 0x6a, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0d, 0xa2, 0x62, 0xff, 0x0c, 0xa2, 0x61, 0xff, 0x0c, 0xa3, 0x5e, 0xff, 0x0e, 0xa3, 0x5c, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x10, 0x9e, 0x57, 0xff, 0x0d, 0x9b, 0x54, 0xff, 0x0a, 0x98, 0x50, 0xff, 0x0b, 0x98, 0x50, 0xff, 0x0c, 0x96, 0x4f, 0xff, 0x0d, 0x94, 0x4e, 0xff, 0x0d, 0x92, 0x4d, 0xff, 0x0d, 0x91, 0x4e, 0xff, 0x0c, 0x91, 0x4d, 0xff, 0x0a, 0x90, 0x4d, 0xff, 0x0d, 0x8c, 0x4e, 0xff, 0x0a, 0x8e, 0x4b, 0xff, 0x07, 0x8f, 0x46, 0xff, 0x0e, 0x8c, 0x46, 0xff, 0x0b, 0x83, 0x45, 0xff, 0x04, 0x7d, 0x46, 0xff, 0x04, 0x7c, 0x45, 0xff, 0x0a, 0x79, 0x3f, 0xff, 0x08, 0x7a, 0x41, 0xff, 0x0a, 0x8d, 0x4d, 0xff, 0x0b, 0x8a, 0x53, 0xff, 0x01, 0x53, 0x43, 0xff, 0x01, 0x48, 0x4f, 0xff, 0x08, 0x66, 0x76, 0xff, 0x08, 0x59, 0x5d, 0xff, 0x02, 0x4b, 0x1e, 0xff, 0x13, 0x72, 0x31, 0xff, 0x08, 0x50, 0x2b, 0xff, 0x17, 0x38, 0x77, 0xff, 0x39, 0x45, 0xdc, 0xff, 0x39, 0x4a, 0xbd, 0xff, 0x13, 0x3c, 0x5e, 0xff, 0x04, 0x52, 0x3b, 0xff, 0x06, 0x76, 0x3e, 0xff, 0x0e, 0x88, 0x4f, 0xff, 0x09, 0x89, 0x49, 0xff, 0x04, 0x7e, 0x39, 0xff, 0x0f, 0x77, 0x32, 0xff, 0x0b, 0x5b, 0x26, 0xff, 0x0c, 0x51, 0x36, 0xff, 0x09, 0x49, 0x39, 0xff, 0x9d, 0xba, 0xb3, 0xff, + 0x07, 0x85, 0x47, 0xff, 0x09, 0x89, 0x47, 0xff, 0x07, 0x8b, 0x47, 0xff, 0x0a, 0x8c, 0x49, 0xff, 0x0c, 0x8d, 0x4c, 0xff, 0x09, 0x8d, 0x4c, 0xff, 0x07, 0x8d, 0x4b, 0xff, 0x07, 0x8f, 0x4b, 0xff, 0x0c, 0x8f, 0x4d, 0xff, 0x12, 0x8d, 0x4e, 0xff, 0x0b, 0x81, 0x46, 0xff, 0x03, 0x77, 0x40, 0xff, 0x15, 0x9a, 0x65, 0xff, 0x14, 0x9b, 0x6b, 0xff, 0x0e, 0x9a, 0x6a, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x06, 0xa2, 0x6b, 0xff, 0x02, 0xa3, 0x6b, 0xff, 0x05, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x15, 0xa3, 0x7b, 0xff, 0x17, 0xa5, 0x7b, 0xff, 0x18, 0xa8, 0x7c, 0xff, 0x12, 0xa5, 0x75, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0d, 0xa8, 0x6d, 0xff, 0x0c, 0xa9, 0x6a, 0xff, 0x10, 0xad, 0x6b, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x0e, 0xaa, 0x6a, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0e, 0xab, 0x69, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x11, 0xac, 0x6b, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xaf, 0x6c, 0xff, 0x10, 0xae, 0x6b, 0xff, 0x10, 0xae, 0x6b, 0xff, 0x11, 0xae, 0x6b, 0xff, 0x13, 0xae, 0x6d, 0xff, 0x13, 0xaf, 0x6e, 0xff, 0x10, 0xaf, 0x6d, 0xff, 0x11, 0xaf, 0x6d, 0xff, 0x11, 0xae, 0x6e, 0xff, 0x10, 0xae, 0x6e, 0xff, 0x10, 0xae, 0x6f, 0xff, 0x12, 0xaf, 0x6f, 0xff, 0x12, 0xaf, 0x6e, 0xff, 0x11, 0xaf, 0x6d, 0xff, 0x11, 0xaf, 0x6d, 0xff, 0x12, 0xaf, 0x6e, 0xff, 0x11, 0xaf, 0x6d, 0xff, 0x10, 0xae, 0x6c, 0xff, 0x10, 0xae, 0x6d, 0xff, 0x10, 0xaf, 0x6d, 0xff, 0x0f, 0xaf, 0x6c, 0xff, 0x10, 0xad, 0x6c, 0xff, 0x12, 0xaa, 0x70, 0xff, 0x11, 0xaa, 0x70, 0xff, 0x11, 0xab, 0x70, 0xff, 0x10, 0xab, 0x70, 0xff, 0x11, 0xab, 0x71, 0xff, 0x10, 0xaa, 0x73, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x11, 0xa6, 0x76, 0xff, 0x12, 0xa5, 0x76, 0xff, 0x13, 0xa5, 0x78, 0xff, 0x14, 0xa3, 0x78, 0xff, 0x15, 0xa3, 0x78, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x79, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x12, 0xa3, 0x79, 0xff, 0x13, 0xa3, 0x79, 0xff, 0x13, 0xa3, 0x79, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x14, 0xa3, 0x7c, 0xff, 0x15, 0xa3, 0x7e, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x14, 0xa2, 0x7d, 0xff, 0x13, 0xa2, 0x7d, 0xff, 0x14, 0xa3, 0x7d, 0xff, 0x14, 0xa4, 0x7d, 0xff, 0x15, 0xa4, 0x7d, 0xff, 0x16, 0xa6, 0x7f, 0xff, 0x16, 0xa4, 0x7d, 0xff, 0x12, 0xa4, 0x7d, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x15, 0xa3, 0x7c, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x15, 0xa3, 0x7c, 0xff, 0x15, 0xa3, 0x7d, 0xff, 0x19, 0xa4, 0x7c, 0xff, 0x13, 0xa6, 0x7c, 0xff, 0x0c, 0xa4, 0x7b, 0xff, 0x10, 0x9e, 0x78, 0xff, 0x1b, 0x9b, 0x78, 0xff, 0x1e, 0xa1, 0x7d, 0xff, 0x10, 0x9c, 0x74, 0xff, 0x15, 0xa4, 0x7c, 0xff, 0x12, 0xa5, 0x7f, 0xff, 0x0e, 0xa4, 0x7d, 0xff, 0x10, 0xa6, 0x7f, 0xff, 0x0f, 0xa4, 0x7d, 0xff, 0x12, 0xa5, 0x7e, 0xff, 0x14, 0xa5, 0x7e, 0xff, 0x13, 0xa5, 0x7e, 0xff, 0x11, 0xa6, 0x7e, 0xff, 0x14, 0xa6, 0x7c, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x0f, 0xaa, 0x7b, 0xff, 0x0f, 0xa9, 0x7a, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x12, 0xab, 0x79, 0xff, 0x11, 0xac, 0x78, 0xff, 0x10, 0xad, 0x77, 0xff, 0x0f, 0xac, 0x77, 0xff, 0x0e, 0xac, 0x77, 0xff, 0x0f, 0xac, 0x79, 0xff, 0x0f, 0xac, 0x79, 0xff, 0x0f, 0xac, 0x7a, 0xff, 0x10, 0xab, 0x79, 0xff, 0x12, 0xad, 0x7c, 0xff, 0x14, 0xaf, 0x7f, 0xff, 0x16, 0xb0, 0x81, 0xff, 0x18, 0xb3, 0x85, 0xff, 0x18, 0xb2, 0x85, 0xff, 0x19, 0xb3, 0x87, 0xff, 0x1b, 0xb5, 0x89, 0xff, 0x1c, 0xb5, 0x8a, 0xff, 0x1f, 0xb6, 0x8a, 0xff, 0x1f, 0xb6, 0x89, 0xff, 0x1d, 0xb7, 0x8a, 0xff, 0x1d, 0xb7, 0x8a, 0xff, 0x1d, 0xb7, 0x8b, 0xff, 0x1d, 0xb8, 0x8c, 0xff, 0x1e, 0xb7, 0x8c, 0xff, 0x1f, 0xb7, 0x8c, 0xff, 0x25, 0xb7, 0x8f, 0xff, 0x28, 0xb5, 0x91, 0xff, 0x26, 0xb6, 0x91, 0xff, 0x25, 0xb7, 0x91, 0xff, 0x23, 0xb7, 0x90, 0xff, 0x21, 0xb8, 0x90, 0xff, 0x1f, 0xb9, 0x92, 0xff, 0x1f, 0xb8, 0x92, 0xff, 0x20, 0xb7, 0x91, 0xff, 0x21, 0xb5, 0x90, 0xff, 0x20, 0xb4, 0x8e, 0xff, 0x1f, 0xb3, 0x8e, 0xff, 0x1f, 0xb2, 0x8f, 0xff, 0x1e, 0xb2, 0x8e, 0xff, 0x1f, 0xb3, 0x90, 0xff, 0x21, 0xb5, 0x91, 0xff, 0x20, 0xb5, 0x91, 0xff, 0x1f, 0xb5, 0x91, 0xff, 0x1f, 0xb5, 0x90, 0xff, 0x1e, 0xb5, 0x8e, 0xff, 0x1e, 0xb2, 0x8b, 0xff, 0x19, 0xae, 0x87, 0xff, 0x15, 0xaa, 0x80, 0xff, 0x15, 0xa9, 0x7f, 0xff, 0x17, 0xac, 0x80, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x15, 0xae, 0x7b, 0xff, 0x12, 0xab, 0x78, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x09, 0xa3, 0x6e, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x09, 0xa2, 0x6f, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0xa0, 0x69, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0d, 0xa0, 0x69, 0xff, 0x0d, 0xa1, 0x6a, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x07, 0xa2, 0x6b, 0xff, 0x08, 0xa2, 0x6c, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x0b, 0xa0, 0x6c, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0e, 0x9f, 0x70, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6d, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0f, 0xa5, 0x67, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x07, 0xa3, 0x6b, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa1, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0d, 0xa2, 0x62, 0xff, 0x0d, 0xa3, 0x61, 0xff, 0x0c, 0xa2, 0x60, 0xff, 0x0e, 0xa3, 0x5d, 0xff, 0x0e, 0xa3, 0x5c, 0xff, 0x0e, 0xa2, 0x5b, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0d, 0xa0, 0x58, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x10, 0x9f, 0x58, 0xff, 0x0e, 0x9c, 0x55, 0xff, 0x0a, 0x99, 0x50, 0xff, 0x0b, 0x98, 0x4f, 0xff, 0x0c, 0x97, 0x4f, 0xff, 0x0d, 0x94, 0x4e, 0xff, 0x0d, 0x91, 0x4d, 0xff, 0x0c, 0x91, 0x4d, 0xff, 0x0b, 0x91, 0x4d, 0xff, 0x0a, 0x90, 0x4d, 0xff, 0x0c, 0x8d, 0x4e, 0xff, 0x0a, 0x8e, 0x4b, 0xff, 0x07, 0x8e, 0x47, 0xff, 0x0d, 0x8b, 0x48, 0xff, 0x0a, 0x83, 0x46, 0xff, 0x03, 0x7c, 0x47, 0xff, 0x04, 0x7a, 0x45, 0xff, 0x0e, 0x79, 0x41, 0xff, 0x06, 0x83, 0x4a, 0xff, 0x2f, 0xc7, 0x86, 0xff, 0x1c, 0xaa, 0x63, 0xff, 0x04, 0x6b, 0x35, 0xff, 0x01, 0x56, 0x35, 0xff, 0x00, 0x4b, 0x2e, 0xff, 0x00, 0x46, 0x25, 0xff, 0x09, 0x6d, 0x34, 0xff, 0x0a, 0x6f, 0x2e, 0xff, 0x05, 0x4d, 0x1b, 0xff, 0x0d, 0x35, 0x4c, 0xff, 0x27, 0x3e, 0xa2, 0xff, 0x1b, 0x3d, 0x79, 0xff, 0x04, 0x41, 0x2d, 0xff, 0x05, 0x67, 0x2b, 0xff, 0x1b, 0xa5, 0x62, 0xff, 0x3f, 0xe0, 0xa6, 0xff, 0x33, 0xd6, 0x95, 0xff, 0x0b, 0x96, 0x50, 0xff, 0x0b, 0x75, 0x2c, 0xff, 0x14, 0x66, 0x29, 0xff, 0x0c, 0x52, 0x30, 0xff, 0x0a, 0x4b, 0x3b, 0xff, 0xa4, 0xbc, 0xb7, 0xff, + 0x07, 0x83, 0x47, 0xff, 0x0a, 0x89, 0x45, 0xff, 0x08, 0x88, 0x44, 0xff, 0x0a, 0x87, 0x46, 0xff, 0x0b, 0x87, 0x47, 0xff, 0x09, 0x8a, 0x48, 0xff, 0x09, 0x8d, 0x49, 0xff, 0x0a, 0x90, 0x4d, 0xff, 0x10, 0x8e, 0x4e, 0xff, 0x0e, 0x82, 0x49, 0xff, 0x05, 0x75, 0x40, 0xff, 0x0f, 0x92, 0x5d, 0xff, 0x11, 0x9e, 0x69, 0xff, 0x0f, 0x9b, 0x69, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x08, 0xa0, 0x69, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x0d, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6a, 0xff, 0x0e, 0xac, 0x69, 0xff, 0x0d, 0xac, 0x68, 0xff, 0x0d, 0xac, 0x68, 0xff, 0x11, 0xad, 0x6a, 0xff, 0x12, 0xae, 0x6b, 0xff, 0x12, 0xae, 0x6b, 0xff, 0x12, 0xae, 0x6b, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xaf, 0x6d, 0xff, 0x12, 0xaf, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xaf, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xb0, 0x6c, 0xff, 0x12, 0xaf, 0x6d, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xab, 0x70, 0xff, 0x13, 0xaa, 0x72, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x72, 0xff, 0x13, 0xa9, 0x73, 0xff, 0x11, 0xa8, 0x71, 0xff, 0x11, 0xa8, 0x72, 0xff, 0x12, 0xa9, 0x74, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x11, 0xa9, 0x74, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x10, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x77, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa3, 0x7d, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x13, 0xa5, 0x7e, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x14, 0xa5, 0x7d, 0xff, 0x14, 0xa5, 0x7c, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x12, 0xa8, 0x7d, 0xff, 0x12, 0xa8, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x12, 0xad, 0x7b, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x12, 0xad, 0x7b, 0xff, 0x15, 0xaf, 0x7e, 0xff, 0x18, 0xb2, 0x82, 0xff, 0x18, 0xb2, 0x82, 0xff, 0x19, 0xb2, 0x84, 0xff, 0x1a, 0xb4, 0x85, 0xff, 0x1c, 0xb5, 0x88, 0xff, 0x1e, 0xb7, 0x8a, 0xff, 0x1e, 0xb7, 0x8a, 0xff, 0x1f, 0xb7, 0x8b, 0xff, 0x1f, 0xb8, 0x8b, 0xff, 0x1f, 0xb8, 0x8b, 0xff, 0x1f, 0xb8, 0x8b, 0xff, 0x20, 0xb9, 0x8c, 0xff, 0x22, 0xb8, 0x8e, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x22, 0xb6, 0x90, 0xff, 0x21, 0xb5, 0x8f, 0xff, 0x21, 0xb5, 0x91, 0xff, 0x20, 0xb4, 0x91, 0xff, 0x20, 0xb4, 0x91, 0xff, 0x20, 0xb3, 0x91, 0xff, 0x1f, 0xb1, 0x90, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1f, 0xb2, 0x8f, 0xff, 0x1f, 0xb3, 0x8f, 0xff, 0x1f, 0xb2, 0x8f, 0xff, 0x1d, 0xb1, 0x8d, 0xff, 0x1b, 0xaf, 0x89, 0xff, 0x18, 0xac, 0x86, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x15, 0xad, 0x7f, 0xff, 0x15, 0xac, 0x7e, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x0b, 0xa6, 0x72, 0xff, 0x0a, 0xa5, 0x74, 0xff, 0x0d, 0xa6, 0x78, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x15, 0xae, 0x7c, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x12, 0xa9, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0b, 0xa5, 0x73, 0xff, 0x08, 0xa1, 0x6e, 0xff, 0x0a, 0xa1, 0x6d, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa6, 0x6a, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0e, 0xa6, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x67, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x69, 0xff, 0x0b, 0xa1, 0x6a, 0xff, 0x09, 0xa0, 0x6c, 0xff, 0x09, 0xa0, 0x6b, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x09, 0x9b, 0x77, 0xff, 0x0f, 0x92, 0x83, 0xff, 0x10, 0x99, 0x75, 0xff, 0x09, 0xa0, 0x6f, 0xff, 0x07, 0xa4, 0x69, 0xff, 0x10, 0xa8, 0x60, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x07, 0xa3, 0x6d, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0d, 0xa3, 0x63, 0xff, 0x0c, 0xa2, 0x62, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0d, 0xa1, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0d, 0xa3, 0x5e, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0c, 0xa0, 0x5b, 0xff, 0x0e, 0xa2, 0x5b, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0c, 0xa1, 0x58, 0xff, 0x0e, 0xa1, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0x9f, 0x57, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x0a, 0x97, 0x51, 0xff, 0x0b, 0x96, 0x4f, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x09, 0x8f, 0x4b, 0xff, 0x09, 0x8e, 0x49, 0xff, 0x0a, 0x8e, 0x49, 0xff, 0x0c, 0x8d, 0x4b, 0xff, 0x0a, 0x86, 0x47, 0xff, 0x06, 0x7f, 0x43, 0xff, 0x08, 0x7c, 0x42, 0xff, 0x0a, 0x7a, 0x40, 0xff, 0x18, 0xa7, 0x69, 0xff, 0x40, 0xe5, 0xac, 0xff, 0x0d, 0x94, 0x52, 0xff, 0x0b, 0x88, 0x48, 0xff, 0x1e, 0xa0, 0x67, 0xff, 0x03, 0x73, 0x2e, 0xff, 0x18, 0x9d, 0x5b, 0xff, 0x13, 0x99, 0x58, 0xff, 0x10, 0x7f, 0x35, 0xff, 0x0a, 0x54, 0x1c, 0xff, 0x06, 0x3b, 0x27, 0xff, 0x05, 0x39, 0x40, 0xff, 0x03, 0x40, 0x33, 0xff, 0x01, 0x5d, 0x24, 0xff, 0x01, 0x6c, 0x24, 0xff, 0x10, 0x9e, 0x5f, 0xff, 0x38, 0xec, 0xb5, 0xff, 0x40, 0xf4, 0xb6, 0xff, 0x15, 0xa7, 0x5f, 0xff, 0x06, 0x6e, 0x25, 0xff, 0x19, 0x6f, 0x34, 0xff, 0x0a, 0x50, 0x2d, 0xff, 0x0b, 0x4c, 0x36, 0xff, 0x9d, 0xbd, 0xb6, 0xff, + 0x0a, 0x82, 0x45, 0xff, 0x0f, 0x86, 0x43, 0xff, 0x0a, 0x84, 0x41, 0xff, 0x09, 0x83, 0x43, 0xff, 0x06, 0x83, 0x43, 0xff, 0x06, 0x88, 0x46, 0xff, 0x06, 0x8e, 0x4b, 0xff, 0x09, 0x8f, 0x4d, 0xff, 0x11, 0x8a, 0x4d, 0xff, 0x04, 0x74, 0x3d, 0xff, 0x0c, 0x8c, 0x56, 0xff, 0x0f, 0x9f, 0x69, 0xff, 0x0a, 0x9d, 0x67, 0xff, 0x0b, 0x9d, 0x69, 0xff, 0x0a, 0x9c, 0x68, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0d, 0xa0, 0x6b, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x03, 0xa6, 0x6e, 0xff, 0x04, 0xa7, 0x6e, 0xff, 0x05, 0xa7, 0x6e, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x09, 0xa8, 0x6b, 0xff, 0x0a, 0xa9, 0x6a, 0xff, 0x0c, 0xaa, 0x6a, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6c, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x0f, 0xac, 0x6b, 0xff, 0x10, 0xac, 0x69, 0xff, 0x0f, 0xad, 0x6a, 0xff, 0x0e, 0xab, 0x68, 0xff, 0x10, 0xab, 0x68, 0xff, 0x10, 0xad, 0x6a, 0xff, 0x12, 0xae, 0x6b, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x13, 0xaf, 0x6e, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x13, 0xaf, 0x6e, 0xff, 0x12, 0xaf, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x11, 0xab, 0x70, 0xff, 0x11, 0xab, 0x70, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x13, 0xa9, 0x73, 0xff, 0x13, 0xa9, 0x73, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x11, 0xa9, 0x74, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x11, 0xa4, 0x7e, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x12, 0xa6, 0x7e, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x10, 0xa5, 0x7b, 0xff, 0x11, 0xa7, 0x7c, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x12, 0xac, 0x7a, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x13, 0xad, 0x7c, 0xff, 0x16, 0xb0, 0x7f, 0xff, 0x17, 0xb1, 0x80, 0xff, 0x19, 0xb3, 0x83, 0xff, 0x1d, 0xb7, 0x88, 0xff, 0x1e, 0xb8, 0x89, 0xff, 0x1d, 0xb7, 0x88, 0xff, 0x1c, 0xb6, 0x87, 0xff, 0x1d, 0xb7, 0x88, 0xff, 0x1d, 0xb7, 0x88, 0xff, 0x1c, 0xb6, 0x87, 0xff, 0x1c, 0xb4, 0x88, 0xff, 0x1d, 0xb3, 0x89, 0xff, 0x1e, 0xb3, 0x8a, 0xff, 0x1f, 0xb3, 0x8c, 0xff, 0x1f, 0xb3, 0x8d, 0xff, 0x1f, 0xb3, 0x8f, 0xff, 0x1e, 0xb2, 0x8f, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xb0, 0x8c, 0xff, 0x1c, 0xb0, 0x8d, 0xff, 0x1b, 0xae, 0x8c, 0xff, 0x1a, 0xae, 0x8a, 0xff, 0x18, 0xac, 0x86, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0d, 0xa8, 0x70, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x14, 0xac, 0x7d, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x15, 0xae, 0x7c, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x20, 0xb8, 0x8a, 0xff, 0x18, 0xb0, 0x80, 0xff, 0x08, 0xa1, 0x6f, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x0e, 0xa7, 0x6a, 0xff, 0x0d, 0xa6, 0x67, 0xff, 0x0e, 0xa6, 0x68, 0xff, 0x0d, 0xa6, 0x67, 0xff, 0x0d, 0xa6, 0x68, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x0b, 0xa1, 0x6a, 0xff, 0x0d, 0xa0, 0x6c, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x09, 0xa1, 0x68, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0e, 0x9f, 0x6d, 0xff, 0x0c, 0x98, 0x7b, 0xff, 0x0e, 0x87, 0x9b, 0xff, 0x23, 0x8e, 0xbd, 0xff, 0x11, 0x88, 0x97, 0xff, 0x0a, 0x9b, 0x76, 0xff, 0x08, 0xa1, 0x71, 0xff, 0x08, 0x9f, 0x6a, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x65, 0xff, 0x09, 0xa3, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0d, 0xa2, 0x5f, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0c, 0xa0, 0x59, 0xff, 0x0c, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x0b, 0x96, 0x4f, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x0a, 0x8f, 0x4b, 0xff, 0x0b, 0x8d, 0x4b, 0xff, 0x08, 0x87, 0x48, 0xff, 0x08, 0x81, 0x43, 0xff, 0x09, 0x7c, 0x41, 0xff, 0x0b, 0x7b, 0x41, 0xff, 0x1c, 0xa3, 0x6a, 0xff, 0x2d, 0xbb, 0x87, 0xff, 0x08, 0x7d, 0x3c, 0xff, 0x33, 0xc0, 0x76, 0xff, 0x35, 0xbc, 0x7d, 0xff, 0x10, 0x9a, 0x5a, 0xff, 0x3d, 0xed, 0xb0, 0xff, 0x1c, 0xb8, 0x78, 0xff, 0x0c, 0x8b, 0x3d, 0xff, 0x03, 0x62, 0x17, 0xff, 0x03, 0x51, 0x16, 0xff, 0x03, 0x47, 0x19, 0xff, 0x09, 0x57, 0x27, 0xff, 0x0f, 0x88, 0x48, 0xff, 0x0b, 0x93, 0x4c, 0xff, 0x04, 0x83, 0x45, 0xff, 0x13, 0xa7, 0x6e, 0xff, 0x1f, 0xbd, 0x7b, 0xff, 0x09, 0x8b, 0x44, 0xff, 0x06, 0x68, 0x22, 0xff, 0x14, 0x6a, 0x2f, 0xff, 0x05, 0x4c, 0x28, 0xff, 0x08, 0x4a, 0x32, 0xff, 0x9c, 0xbc, 0xb5, 0xff, + 0x0e, 0x80, 0x44, 0xff, 0x13, 0x81, 0x40, 0xff, 0x0d, 0x80, 0x3d, 0xff, 0x07, 0x82, 0x41, 0xff, 0x05, 0x82, 0x42, 0xff, 0x04, 0x87, 0x45, 0xff, 0x07, 0x8a, 0x4b, 0xff, 0x0b, 0x88, 0x4d, 0xff, 0x06, 0x77, 0x3f, 0xff, 0x0a, 0x83, 0x4f, 0xff, 0x0f, 0x9a, 0x64, 0xff, 0x0a, 0x9d, 0x67, 0xff, 0x0a, 0x9d, 0x67, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x07, 0x9d, 0x68, 0xff, 0x08, 0x9e, 0x6a, 0xff, 0x09, 0x9f, 0x6c, 0xff, 0x09, 0xa0, 0x6c, 0xff, 0x07, 0xa0, 0x6c, 0xff, 0x08, 0xa1, 0x6d, 0xff, 0x07, 0xa2, 0x6e, 0xff, 0x06, 0xa2, 0x6d, 0xff, 0x07, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa2, 0x6c, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x08, 0xa5, 0x6f, 0xff, 0x08, 0xa5, 0x6f, 0xff, 0x08, 0xa6, 0x6f, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x0c, 0xa9, 0x6b, 0xff, 0x0c, 0xaa, 0x6a, 0xff, 0x0d, 0xab, 0x6a, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x10, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xac, 0x6a, 0xff, 0x10, 0xab, 0x69, 0xff, 0x10, 0xac, 0x6a, 0xff, 0x0f, 0xab, 0x69, 0xff, 0x0f, 0xac, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xab, 0x70, 0xff, 0x10, 0xaa, 0x70, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x10, 0xa7, 0x74, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x11, 0xa7, 0x77, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x10, 0xa4, 0x78, 0xff, 0x11, 0xa3, 0x77, 0xff, 0x0f, 0xa3, 0x77, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x12, 0xa4, 0x7e, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x11, 0xa4, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x12, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x10, 0xa6, 0x7b, 0xff, 0x11, 0xa8, 0x7c, 0xff, 0x11, 0xa8, 0x7c, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x78, 0xff, 0x11, 0xad, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xab, 0x76, 0xff, 0x0f, 0xab, 0x77, 0xff, 0x0f, 0xab, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x12, 0xad, 0x7b, 0xff, 0x14, 0xaf, 0x7d, 0xff, 0x17, 0xb1, 0x80, 0xff, 0x19, 0xb3, 0x83, 0xff, 0x1a, 0xb4, 0x83, 0xff, 0x18, 0xb2, 0x81, 0xff, 0x16, 0xb0, 0x80, 0xff, 0x15, 0xaf, 0x80, 0xff, 0x15, 0xaf, 0x80, 0xff, 0x14, 0xae, 0x80, 0xff, 0x16, 0xaf, 0x81, 0xff, 0x18, 0xaf, 0x82, 0xff, 0x1a, 0xb0, 0x86, 0xff, 0x1c, 0xb0, 0x89, 0xff, 0x1c, 0xb0, 0x8b, 0xff, 0x1c, 0xb0, 0x8c, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1e, 0xb0, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1c, 0xaf, 0x8e, 0xff, 0x1d, 0xaf, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xb0, 0x8c, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1b, 0xaf, 0x8c, 0xff, 0x1a, 0xae, 0x8a, 0xff, 0x18, 0xac, 0x86, 0xff, 0x16, 0xab, 0x82, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xa9, 0x75, 0xff, 0x0e, 0xa8, 0x6f, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x19, 0xb1, 0x80, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x11, 0xac, 0x7c, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x29, 0xbe, 0x93, 0xff, 0x27, 0xbd, 0x90, 0xff, 0x0c, 0xa3, 0x74, 0xff, 0x0a, 0xa2, 0x70, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x12, 0xac, 0x74, 0xff, 0x0c, 0xa6, 0x69, 0xff, 0x0e, 0xa9, 0x69, 0xff, 0x0c, 0xa7, 0x67, 0xff, 0x0b, 0xa6, 0x66, 0xff, 0x0c, 0xa5, 0x67, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0d, 0xa1, 0x6a, 0xff, 0x0f, 0xa3, 0x6a, 0xff, 0x11, 0xa5, 0x6a, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0f, 0xa1, 0x6f, 0xff, 0x13, 0x9d, 0x73, 0xff, 0x0c, 0x7f, 0x96, 0xff, 0x14, 0x72, 0xc2, 0xff, 0x28, 0x83, 0xe1, 0xff, 0x1d, 0x84, 0xc8, 0xff, 0x0b, 0x8d, 0x87, 0xff, 0x0b, 0x9d, 0x75, 0xff, 0x07, 0xa1, 0x6e, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x08, 0xa4, 0x66, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0c, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0d, 0xa2, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5d, 0xff, 0x0d, 0xa0, 0x5c, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x5a, 0xff, 0x0c, 0xa0, 0x5a, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9e, 0x56, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0a, 0x99, 0x52, 0xff, 0x0a, 0x99, 0x52, 0xff, 0x0b, 0x97, 0x50, 0xff, 0x0c, 0x94, 0x4d, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x92, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x90, 0x4c, 0xff, 0x0b, 0x8f, 0x4c, 0xff, 0x08, 0x88, 0x47, 0xff, 0x08, 0x83, 0x45, 0xff, 0x0a, 0x7f, 0x43, 0xff, 0x09, 0x7b, 0x41, 0xff, 0x04, 0x7c, 0x45, 0xff, 0x06, 0x7a, 0x41, 0xff, 0x03, 0x80, 0x32, 0xff, 0x1a, 0xb2, 0x52, 0xff, 0x10, 0x8e, 0x3d, 0xff, 0x2f, 0xb9, 0x7f, 0xff, 0x47, 0xf1, 0xbe, 0xff, 0x25, 0xbc, 0x7b, 0xff, 0x09, 0x86, 0x3b, 0xff, 0x05, 0x76, 0x2d, 0xff, 0x0a, 0x7a, 0x33, 0xff, 0x0c, 0x63, 0x24, 0xff, 0x05, 0x5b, 0x20, 0xff, 0x1e, 0xae, 0x71, 0xff, 0x30, 0xdc, 0x9d, 0xff, 0x25, 0xc3, 0x8a, 0xff, 0x05, 0x82, 0x44, 0xff, 0x04, 0x7d, 0x37, 0xff, 0x07, 0x71, 0x2c, 0xff, 0x04, 0x5b, 0x1c, 0xff, 0x04, 0x58, 0x1f, 0xff, 0x02, 0x49, 0x1f, 0xff, 0x07, 0x4a, 0x2e, 0xff, 0xa2, 0xba, 0xb3, 0xff, + 0x0f, 0x7e, 0x42, 0xff, 0x15, 0x7e, 0x3c, 0xff, 0x0f, 0x7f, 0x3b, 0xff, 0x07, 0x82, 0x40, 0xff, 0x07, 0x84, 0x43, 0xff, 0x07, 0x86, 0x45, 0xff, 0x0e, 0x84, 0x4a, 0xff, 0x0a, 0x76, 0x41, 0xff, 0x02, 0x71, 0x3d, 0xff, 0x11, 0x97, 0x62, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0d, 0x9d, 0x67, 0xff, 0x0c, 0x9d, 0x67, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x07, 0x9e, 0x68, 0xff, 0x06, 0x9e, 0x69, 0xff, 0x07, 0x9f, 0x6b, 0xff, 0x06, 0xa0, 0x6b, 0xff, 0x05, 0xa0, 0x6b, 0xff, 0x04, 0xa1, 0x6c, 0xff, 0x04, 0xa2, 0x6d, 0xff, 0x04, 0xa3, 0x6d, 0xff, 0x04, 0xa3, 0x6d, 0xff, 0x06, 0xa5, 0x6c, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x0d, 0xa9, 0x6c, 0xff, 0x0d, 0xab, 0x6a, 0xff, 0x0e, 0xab, 0x69, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x0e, 0xa9, 0x69, 0xff, 0x10, 0xa9, 0x69, 0xff, 0x11, 0xaa, 0x6a, 0xff, 0x11, 0xaa, 0x6a, 0xff, 0x12, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x0f, 0xaa, 0x6a, 0xff, 0x0f, 0xaa, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x13, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xab, 0x71, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x16, 0xad, 0x7c, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x12, 0xa5, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa4, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x12, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa5, 0x7c, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa6, 0x7b, 0xff, 0x11, 0xa7, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xad, 0x79, 0xff, 0x11, 0xad, 0x78, 0xff, 0x11, 0xad, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x13, 0xad, 0x7b, 0xff, 0x14, 0xae, 0x7d, 0xff, 0x13, 0xae, 0x7c, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x13, 0xac, 0x7d, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x18, 0xae, 0x82, 0xff, 0x1a, 0xaf, 0x87, 0xff, 0x1c, 0xb0, 0x8b, 0xff, 0x1c, 0xb0, 0x8d, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1e, 0xb0, 0x90, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xb1, 0x8e, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1b, 0xaf, 0x8b, 0xff, 0x19, 0xad, 0x88, 0xff, 0x16, 0xac, 0x82, 0xff, 0x15, 0xab, 0x80, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xaa, 0x7b, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa9, 0x77, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x0e, 0xa9, 0x6d, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x13, 0xab, 0x7a, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x16, 0xaf, 0x7e, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x0f, 0xa5, 0x7b, 0xff, 0x1f, 0xb1, 0x8a, 0xff, 0x1c, 0xaf, 0x85, 0xff, 0x09, 0x9f, 0x71, 0xff, 0x07, 0x9f, 0x6d, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x10, 0xaa, 0x73, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0a, 0xa6, 0x66, 0xff, 0x0a, 0xa6, 0x66, 0xff, 0x0a, 0xa5, 0x66, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0d, 0xa6, 0x69, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x0e, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x10, 0xa3, 0x68, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x0f, 0xa3, 0x6b, 0xff, 0x10, 0xa3, 0x70, 0xff, 0x10, 0x9e, 0x74, 0xff, 0x12, 0x92, 0x80, 0xff, 0x05, 0x61, 0xa6, 0xff, 0x13, 0x61, 0xd5, 0xff, 0x19, 0x6f, 0xe4, 0xff, 0x1f, 0x7f, 0xe3, 0xff, 0x0b, 0x82, 0x9a, 0xff, 0x0e, 0x99, 0x79, 0xff, 0x08, 0xa2, 0x6e, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x07, 0xa3, 0x67, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0d, 0xa1, 0x61, 0xff, 0x0d, 0xa2, 0x61, 0xff, 0x0d, 0xa2, 0x60, 0xff, 0x0c, 0xa1, 0x5e, 0xff, 0x0c, 0xa0, 0x5c, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0f, 0xa1, 0x5a, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0c, 0x97, 0x50, 0xff, 0x0c, 0x94, 0x4d, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x09, 0x92, 0x4c, 0xff, 0x0a, 0x92, 0x4b, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x0b, 0x90, 0x4c, 0xff, 0x09, 0x8c, 0x4a, 0xff, 0x08, 0x84, 0x46, 0xff, 0x09, 0x80, 0x44, 0xff, 0x0b, 0x7e, 0x43, 0xff, 0x05, 0x78, 0x3f, 0xff, 0x03, 0x76, 0x34, 0xff, 0x07, 0x92, 0x3a, 0xff, 0x09, 0xac, 0x3a, 0xff, 0x05, 0x82, 0x20, 0xff, 0x22, 0x9a, 0x5e, 0xff, 0x27, 0xb8, 0x86, 0xff, 0x09, 0x8e, 0x4a, 0xff, 0x03, 0x79, 0x35, 0xff, 0x20, 0xad, 0x6f, 0xff, 0x0f, 0x9e, 0x5e, 0xff, 0x18, 0x83, 0x45, 0xff, 0x03, 0x59, 0x21, 0xff, 0x1c, 0xad, 0x77, 0xff, 0x3b, 0xf4, 0xbf, 0xff, 0x40, 0xf7, 0xc2, 0xff, 0x18, 0xa6, 0x63, 0xff, 0x0c, 0x76, 0x2b, 0xff, 0x0e, 0x69, 0x26, 0xff, 0x01, 0x4e, 0x14, 0xff, 0x00, 0x50, 0x1a, 0xff, 0x01, 0x48, 0x1c, 0xff, 0x07, 0x4a, 0x2a, 0xff, 0xa6, 0xb9, 0xb2, 0xff, + 0x0d, 0x7c, 0x3f, 0xff, 0x12, 0x7e, 0x3b, 0xff, 0x0d, 0x81, 0x3c, 0xff, 0x07, 0x81, 0x41, 0xff, 0x0a, 0x82, 0x43, 0xff, 0x11, 0x81, 0x46, 0xff, 0x15, 0x74, 0x41, 0xff, 0x04, 0x63, 0x34, 0xff, 0x0f, 0x91, 0x5e, 0xff, 0x0a, 0x9c, 0x67, 0xff, 0x10, 0x9c, 0x67, 0xff, 0x15, 0x9b, 0x66, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x07, 0x9e, 0x64, 0xff, 0x06, 0x9e, 0x64, 0xff, 0x09, 0x9e, 0x64, 0xff, 0x08, 0xa0, 0x65, 0xff, 0x06, 0xa1, 0x64, 0xff, 0x04, 0xa1, 0x64, 0xff, 0x03, 0xa2, 0x65, 0xff, 0x03, 0xa2, 0x67, 0xff, 0x05, 0xa4, 0x69, 0xff, 0x05, 0xa4, 0x69, 0xff, 0x05, 0xa5, 0x68, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x09, 0xa8, 0x6d, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x0d, 0xa9, 0x6d, 0xff, 0x0e, 0xab, 0x6b, 0xff, 0x0e, 0xaa, 0x6a, 0xff, 0x0e, 0xa9, 0x6c, 0xff, 0x0e, 0xa9, 0x6c, 0xff, 0x0d, 0xaa, 0x6a, 0xff, 0x0a, 0xa6, 0x66, 0xff, 0x05, 0x9e, 0x5f, 0xff, 0x0a, 0xa0, 0x62, 0xff, 0x15, 0xaa, 0x6d, 0xff, 0x12, 0xa9, 0x6c, 0xff, 0x0f, 0xac, 0x6b, 0xff, 0x0e, 0xac, 0x6a, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x11, 0xad, 0x6b, 0xff, 0x13, 0xad, 0x6b, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xab, 0x71, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x11, 0xa7, 0x73, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x13, 0xaa, 0x7a, 0xff, 0x16, 0xad, 0x7c, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x14, 0xa7, 0x7b, 0xff, 0x15, 0xa8, 0x7c, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x0f, 0xa2, 0x76, 0xff, 0x0e, 0xa3, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x14, 0xa5, 0x7e, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x14, 0xa5, 0x7e, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x10, 0xa6, 0x7b, 0xff, 0x11, 0xa7, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x78, 0xff, 0x10, 0xac, 0x76, 0xff, 0x11, 0xad, 0x77, 0xff, 0x11, 0xad, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xab, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x7a, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x12, 0xac, 0x7a, 0xff, 0x12, 0xac, 0x7a, 0xff, 0x13, 0xac, 0x7b, 0xff, 0x15, 0xad, 0x7d, 0xff, 0x16, 0xad, 0x80, 0xff, 0x1a, 0xaf, 0x86, 0xff, 0x1d, 0xb0, 0x8c, 0xff, 0x1d, 0xaf, 0x8e, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x91, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1e, 0xb0, 0x90, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1e, 0xb0, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1a, 0xae, 0x89, 0xff, 0x18, 0xac, 0x85, 0xff, 0x16, 0xac, 0x81, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x14, 0xa9, 0x79, 0xff, 0x16, 0xa8, 0x79, 0xff, 0x1c, 0xab, 0x7f, 0xff, 0x36, 0xc3, 0x9b, 0xff, 0x37, 0xc3, 0xa0, 0xff, 0x14, 0x9e, 0x7d, 0xff, 0x07, 0x95, 0x70, 0xff, 0x09, 0x9c, 0x71, 0xff, 0x06, 0x9e, 0x6d, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0d, 0xa8, 0x6b, 0xff, 0x04, 0x9f, 0x62, 0xff, 0x0a, 0xa7, 0x68, 0xff, 0x0d, 0xa9, 0x69, 0xff, 0x09, 0xa5, 0x65, 0xff, 0x0e, 0xa6, 0x69, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0b, 0xa2, 0x69, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0f, 0xa6, 0x69, 0xff, 0x0e, 0xa6, 0x68, 0xff, 0x0e, 0xa6, 0x6d, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x06, 0x8e, 0x77, 0xff, 0x03, 0x63, 0x97, 0xff, 0x00, 0x47, 0xbf, 0xff, 0x06, 0x54, 0xd5, 0xff, 0x0d, 0x69, 0xea, 0xff, 0x0b, 0x6f, 0xe9, 0xff, 0x06, 0x6b, 0xb0, 0xff, 0x0b, 0x80, 0x83, 0xff, 0x0c, 0x9b, 0x75, 0xff, 0x09, 0xa1, 0x6d, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0d, 0xa1, 0x61, 0xff, 0x0d, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa1, 0x5e, 0xff, 0x0d, 0xa1, 0x5d, 0xff, 0x0e, 0xa1, 0x5d, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0f, 0xa1, 0x5b, 0xff, 0x0f, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0b, 0x9a, 0x52, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0b, 0x97, 0x50, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x09, 0x92, 0x4b, 0xff, 0x08, 0x92, 0x4b, 0xff, 0x09, 0x91, 0x4b, 0xff, 0x0c, 0x91, 0x4d, 0xff, 0x09, 0x8c, 0x4a, 0xff, 0x0a, 0x87, 0x49, 0xff, 0x09, 0x82, 0x45, 0xff, 0x0a, 0x80, 0x44, 0xff, 0x0c, 0x79, 0x40, 0xff, 0x0a, 0x87, 0x42, 0xff, 0x27, 0xc6, 0x6d, 0xff, 0x16, 0xc6, 0x4f, 0xff, 0x11, 0x9f, 0x2d, 0xff, 0x03, 0x6a, 0x28, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x0e, 0x8b, 0x48, 0xff, 0x1c, 0xb4, 0x7c, 0xff, 0x41, 0xf6, 0xc9, 0xff, 0x21, 0xcd, 0x97, 0xff, 0x0a, 0x83, 0x4e, 0xff, 0x03, 0x57, 0x2c, 0xff, 0x06, 0x70, 0x4e, 0xff, 0x1b, 0xaf, 0x86, 0xff, 0x36, 0xe0, 0xa6, 0xff, 0x22, 0xb0, 0x61, 0xff, 0x0f, 0x73, 0x21, 0xff, 0x0e, 0x60, 0x1f, 0xff, 0x01, 0x48, 0x15, 0xff, 0x05, 0x4d, 0x1b, 0xff, 0x03, 0x47, 0x1a, 0xff, 0x09, 0x4a, 0x27, 0xff, 0xa6, 0xba, 0xb1, 0xff, + 0x0a, 0x7a, 0x3c, 0xff, 0x0d, 0x7d, 0x3a, 0xff, 0x08, 0x80, 0x3c, 0xff, 0x07, 0x80, 0x40, 0xff, 0x0d, 0x7e, 0x43, 0xff, 0x12, 0x78, 0x40, 0xff, 0x09, 0x61, 0x30, 0xff, 0x12, 0x7b, 0x4c, 0xff, 0x14, 0x9e, 0x69, 0xff, 0x04, 0x9e, 0x66, 0xff, 0x0a, 0x9d, 0x65, 0xff, 0x11, 0x9c, 0x63, 0xff, 0x0b, 0x9d, 0x62, 0xff, 0x03, 0xa0, 0x62, 0xff, 0x03, 0xa4, 0x64, 0xff, 0x05, 0xa8, 0x64, 0xff, 0x07, 0xac, 0x67, 0xff, 0x09, 0xb1, 0x6a, 0xff, 0x09, 0xb3, 0x6c, 0xff, 0x0e, 0xb9, 0x73, 0xff, 0x0e, 0xb8, 0x74, 0xff, 0x0d, 0xb6, 0x73, 0xff, 0x07, 0xaf, 0x6e, 0xff, 0x07, 0xae, 0x6d, 0xff, 0x07, 0xaa, 0x6b, 0xff, 0x07, 0xa5, 0x69, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa9, 0x6e, 0xff, 0x06, 0xa6, 0x70, 0xff, 0x06, 0xa6, 0x70, 0xff, 0x08, 0xa7, 0x71, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x0e, 0xaa, 0x6e, 0xff, 0x0d, 0xaa, 0x6b, 0xff, 0x0d, 0xaa, 0x6b, 0xff, 0x0d, 0xa9, 0x6d, 0xff, 0x0d, 0xa9, 0x6c, 0xff, 0x0d, 0xaa, 0x6a, 0xff, 0x0d, 0xa8, 0x68, 0xff, 0x06, 0x9f, 0x60, 0xff, 0x08, 0x9e, 0x61, 0xff, 0x11, 0xa3, 0x69, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x10, 0xac, 0x6c, 0xff, 0x10, 0xad, 0x6c, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xab, 0x6b, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xac, 0x6b, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x12, 0xad, 0x6a, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xab, 0x70, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xa9, 0x72, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x12, 0xa8, 0x71, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x10, 0xa6, 0x70, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x14, 0xaa, 0x7c, 0xff, 0x18, 0xae, 0x7f, 0xff, 0x0f, 0xa5, 0x76, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x13, 0xa9, 0x7b, 0xff, 0x15, 0xa8, 0x7d, 0xff, 0x18, 0xab, 0x80, 0xff, 0x0e, 0xa1, 0x76, 0xff, 0x0d, 0xa0, 0x74, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x14, 0xa5, 0x7e, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x12, 0xa6, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa6, 0x7b, 0xff, 0x10, 0xa7, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xac, 0x78, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xab, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x13, 0xac, 0x7a, 0xff, 0x15, 0xad, 0x7d, 0xff, 0x16, 0xad, 0x81, 0xff, 0x19, 0xae, 0x85, 0xff, 0x1c, 0xb0, 0x8c, 0xff, 0x1d, 0xaf, 0x8e, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x91, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1f, 0xb1, 0x90, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1d, 0xb0, 0x8d, 0xff, 0x1a, 0xae, 0x89, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xab, 0x83, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x13, 0xaa, 0x7d, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xaa, 0x76, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x13, 0xa9, 0x78, 0xff, 0x1e, 0xae, 0x81, 0xff, 0x21, 0xae, 0x81, 0xff, 0x18, 0x9f, 0x76, 0xff, 0x41, 0xc5, 0xa1, 0xff, 0x3f, 0xc0, 0xa1, 0xff, 0x15, 0x99, 0x7a, 0xff, 0x10, 0x9b, 0x76, 0xff, 0x11, 0xa2, 0x77, 0xff, 0x0b, 0xa2, 0x72, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0d, 0xa6, 0x6b, 0xff, 0x05, 0xa0, 0x64, 0xff, 0x09, 0xa5, 0x67, 0xff, 0x09, 0xa6, 0x66, 0xff, 0x08, 0xa4, 0x64, 0xff, 0x0d, 0xa6, 0x69, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x0f, 0xa3, 0x69, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0d, 0xa8, 0x6a, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0f, 0xa3, 0x73, 0xff, 0x03, 0x81, 0x74, 0xff, 0x04, 0x54, 0xac, 0xff, 0x07, 0x4f, 0xd5, 0xff, 0x08, 0x55, 0xde, 0xff, 0x08, 0x68, 0xea, 0xff, 0x03, 0x6d, 0xe8, 0xff, 0x06, 0x61, 0xcb, 0xff, 0x05, 0x64, 0x97, 0xff, 0x0b, 0x8e, 0x78, 0xff, 0x0a, 0xa0, 0x6e, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x07, 0xa0, 0x68, 0xff, 0x07, 0xa1, 0x66, 0xff, 0x06, 0xa1, 0x64, 0xff, 0x05, 0xa0, 0x63, 0xff, 0x06, 0xa2, 0x64, 0xff, 0x06, 0xa3, 0x66, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0b, 0xa0, 0x68, 0xff, 0x09, 0x9c, 0x64, 0xff, 0x0c, 0x9f, 0x67, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x0b, 0xa1, 0x65, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0d, 0xa1, 0x5e, 0xff, 0x0d, 0xa2, 0x5e, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0f, 0xa1, 0x5b, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0b, 0x9a, 0x53, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0b, 0x97, 0x50, 0xff, 0x0c, 0x94, 0x4d, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x09, 0x92, 0x4a, 0xff, 0x08, 0x91, 0x4a, 0xff, 0x09, 0x91, 0x4b, 0xff, 0x0c, 0x91, 0x4d, 0xff, 0x0a, 0x8d, 0x4b, 0xff, 0x0a, 0x88, 0x49, 0xff, 0x0a, 0x84, 0x46, 0xff, 0x09, 0x80, 0x44, 0xff, 0x0e, 0x7a, 0x42, 0xff, 0x10, 0x8e, 0x4e, 0xff, 0x28, 0xc1, 0x76, 0xff, 0x0a, 0xb6, 0x4b, 0xff, 0x07, 0xa4, 0x32, 0xff, 0x02, 0x71, 0x2b, 0xff, 0x02, 0x66, 0x32, 0xff, 0x11, 0x93, 0x54, 0xff, 0x39, 0xe0, 0xae, 0xff, 0x3a, 0xf0, 0xc3, 0xff, 0x1e, 0xbc, 0x82, 0xff, 0x03, 0x6d, 0x37, 0xff, 0x0a, 0x58, 0x34, 0xff, 0x05, 0x57, 0x3e, 0xff, 0x04, 0x6a, 0x44, 0xff, 0x1b, 0x9e, 0x5a, 0xff, 0x10, 0x8c, 0x35, 0xff, 0x0a, 0x72, 0x1f, 0xff, 0x06, 0x5a, 0x19, 0xff, 0x03, 0x48, 0x16, 0xff, 0x07, 0x4b, 0x1a, 0xff, 0x05, 0x46, 0x17, 0xff, 0x05, 0x43, 0x1e, 0xff, 0x92, 0xaf, 0xa0, 0xff, + 0x07, 0x79, 0x3b, 0xff, 0x07, 0x7d, 0x39, 0xff, 0x04, 0x7e, 0x39, 0xff, 0x09, 0x7e, 0x3f, 0xff, 0x11, 0x7b, 0x42, 0xff, 0x07, 0x63, 0x2f, 0xff, 0x07, 0x65, 0x33, 0xff, 0x1c, 0x99, 0x66, 0xff, 0x0b, 0x9c, 0x65, 0xff, 0x01, 0xa0, 0x63, 0xff, 0x01, 0x9d, 0x5e, 0xff, 0x06, 0xa3, 0x62, 0xff, 0x0c, 0xaa, 0x69, 0xff, 0x12, 0xb7, 0x75, 0xff, 0x14, 0xc4, 0x7d, 0xff, 0x15, 0xce, 0x81, 0xff, 0x1a, 0xd5, 0x86, 0xff, 0x19, 0xd7, 0x86, 0xff, 0x16, 0xd5, 0x84, 0xff, 0x17, 0xd7, 0x86, 0xff, 0x16, 0xd4, 0x87, 0xff, 0x19, 0xd3, 0x88, 0xff, 0x15, 0xce, 0x85, 0xff, 0x19, 0xd1, 0x8a, 0xff, 0x18, 0xcb, 0x87, 0xff, 0x17, 0xbf, 0x80, 0xff, 0x0f, 0xb0, 0x73, 0xff, 0x08, 0xa7, 0x6b, 0xff, 0x09, 0xa6, 0x6a, 0xff, 0x09, 0xa9, 0x6b, 0xff, 0x0a, 0xaa, 0x6d, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x0c, 0xaa, 0x6e, 0xff, 0x0c, 0xaa, 0x6c, 0xff, 0x0d, 0xaa, 0x6d, 0xff, 0x0c, 0xa9, 0x6d, 0xff, 0x0c, 0xaa, 0x6d, 0xff, 0x0c, 0xaa, 0x6b, 0xff, 0x0d, 0xab, 0x6b, 0xff, 0x0c, 0xa5, 0x66, 0xff, 0x06, 0x9c, 0x61, 0xff, 0x05, 0x96, 0x5e, 0xff, 0x06, 0x96, 0x5e, 0xff, 0x11, 0xa9, 0x6c, 0xff, 0x13, 0xac, 0x6e, 0xff, 0x11, 0xab, 0x6c, 0xff, 0x12, 0xab, 0x6c, 0xff, 0x12, 0xac, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x11, 0xac, 0x69, 0xff, 0x12, 0xad, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x0f, 0xa9, 0x68, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6c, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xab, 0x71, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x12, 0xa8, 0x7a, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x13, 0xa9, 0x7b, 0xff, 0x12, 0xa7, 0x7a, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x15, 0xa6, 0x7c, 0xff, 0x0c, 0x9e, 0x73, 0xff, 0x0d, 0xa0, 0x74, 0xff, 0x10, 0xa3, 0x76, 0xff, 0x0f, 0xa3, 0x76, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa6, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa9, 0x7a, 0xff, 0x11, 0xaa, 0x7a, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x13, 0xad, 0x7d, 0xff, 0x13, 0xad, 0x7d, 0xff, 0x13, 0xad, 0x7b, 0xff, 0x15, 0xad, 0x7c, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x18, 0xad, 0x85, 0xff, 0x1c, 0xb0, 0x8d, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x90, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1e, 0xb0, 0x90, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1c, 0xaf, 0x8e, 0xff, 0x1b, 0xad, 0x8c, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1a, 0xae, 0x89, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xab, 0x83, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xaa, 0x76, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x08, 0xa3, 0x6e, 0xff, 0x22, 0xb6, 0x87, 0xff, 0x32, 0xc1, 0x92, 0xff, 0x2a, 0xb3, 0x85, 0xff, 0x12, 0x94, 0x6a, 0xff, 0x1f, 0x9b, 0x77, 0xff, 0x27, 0xa1, 0x82, 0xff, 0x32, 0xb2, 0x93, 0xff, 0x2b, 0xb2, 0x8f, 0xff, 0x1f, 0xae, 0x84, 0xff, 0x0b, 0xa2, 0x72, 0xff, 0x04, 0x9e, 0x6a, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x10, 0xa6, 0x6e, 0xff, 0x0a, 0xa2, 0x68, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x08, 0xa4, 0x66, 0xff, 0x09, 0xa5, 0x67, 0xff, 0x0d, 0xa6, 0x69, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0e, 0xa9, 0x6d, 0xff, 0x10, 0xa9, 0x6d, 0xff, 0x12, 0xa5, 0x70, 0xff, 0x14, 0xa1, 0x73, 0xff, 0x0e, 0x86, 0x77, 0xff, 0x0a, 0x5d, 0xa6, 0xff, 0x0f, 0x5e, 0xd6, 0xff, 0x12, 0x61, 0xea, 0xff, 0x08, 0x68, 0xe6, 0xff, 0x01, 0x6d, 0xe7, 0xff, 0x07, 0x5e, 0xdd, 0xff, 0x02, 0x54, 0xa6, 0xff, 0x0a, 0x89, 0x77, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x08, 0xa1, 0x6a, 0xff, 0x07, 0xa0, 0x68, 0xff, 0x06, 0xa0, 0x65, 0xff, 0x07, 0xa1, 0x65, 0xff, 0x07, 0xa2, 0x66, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x06, 0xa3, 0x67, 0xff, 0x06, 0xa2, 0x68, 0xff, 0x07, 0xa2, 0x68, 0xff, 0x09, 0xa1, 0x68, 0xff, 0x0b, 0xa0, 0x69, 0xff, 0x0a, 0x9b, 0x64, 0xff, 0x08, 0x97, 0x60, 0xff, 0x0b, 0x9c, 0x64, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0b, 0xa1, 0x65, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0c, 0xa1, 0x5d, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x0f, 0xa1, 0x5b, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0c, 0x97, 0x50, 0xff, 0x0c, 0x94, 0x4e, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x09, 0x92, 0x4a, 0xff, 0x0a, 0x92, 0x4b, 0xff, 0x0b, 0x92, 0x4b, 0xff, 0x0c, 0x91, 0x4d, 0xff, 0x0b, 0x8e, 0x4c, 0xff, 0x0a, 0x89, 0x49, 0xff, 0x0a, 0x84, 0x46, 0xff, 0x0a, 0x81, 0x44, 0xff, 0x0e, 0x7d, 0x43, 0xff, 0x07, 0x83, 0x48, 0xff, 0x08, 0x8a, 0x4f, 0xff, 0x0d, 0xac, 0x53, 0xff, 0x14, 0xba, 0x4c, 0xff, 0x02, 0x79, 0x2a, 0xff, 0x03, 0x6b, 0x2d, 0xff, 0x0f, 0x8a, 0x4d, 0xff, 0x3b, 0xd3, 0xa1, 0xff, 0x17, 0xad, 0x78, 0xff, 0x09, 0x7f, 0x40, 0xff, 0x0c, 0x62, 0x2e, 0xff, 0x0e, 0x5b, 0x3a, 0xff, 0x08, 0x55, 0x39, 0xff, 0x02, 0x4d, 0x21, 0xff, 0x0a, 0x69, 0x22, 0xff, 0x0b, 0x76, 0x23, 0xff, 0x04, 0x6f, 0x21, 0xff, 0x00, 0x50, 0x13, 0xff, 0x04, 0x47, 0x18, 0xff, 0x0b, 0x4a, 0x1a, 0xff, 0x07, 0x44, 0x16, 0xff, 0x03, 0x3d, 0x16, 0xff, 0x7c, 0x9c, 0x8f, 0xff, + 0x05, 0x77, 0x3b, 0xff, 0x06, 0x7c, 0x38, 0xff, 0x07, 0x7c, 0x3a, 0xff, 0x0c, 0x77, 0x3b, 0xff, 0x0e, 0x73, 0x3d, 0xff, 0x03, 0x5d, 0x2a, 0xff, 0x10, 0x88, 0x53, 0xff, 0x0b, 0x9e, 0x64, 0xff, 0x09, 0x9e, 0x62, 0xff, 0x08, 0xa6, 0x65, 0xff, 0x0e, 0xb8, 0x73, 0xff, 0x15, 0xc0, 0x7a, 0xff, 0x19, 0xc0, 0x79, 0xff, 0x1b, 0xc7, 0x7f, 0xff, 0x14, 0xca, 0x7e, 0xff, 0x0a, 0xc9, 0x79, 0xff, 0x0a, 0xcc, 0x79, 0xff, 0x05, 0xca, 0x75, 0xff, 0x03, 0xc6, 0x70, 0xff, 0x02, 0xc3, 0x70, 0xff, 0x03, 0xc0, 0x71, 0xff, 0x05, 0xc1, 0x75, 0xff, 0x0c, 0xc1, 0x78, 0xff, 0x16, 0xc0, 0x7c, 0xff, 0x16, 0xb9, 0x78, 0xff, 0x20, 0xb5, 0x79, 0xff, 0x20, 0xb2, 0x79, 0xff, 0x0f, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa9, 0x6b, 0xff, 0x08, 0xa8, 0x6c, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa5, 0x6d, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x0b, 0xa9, 0x6e, 0xff, 0x0b, 0xaa, 0x6f, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0b, 0xaa, 0x6b, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0c, 0xa6, 0x69, 0xff, 0x0c, 0xa1, 0x67, 0xff, 0x07, 0x97, 0x61, 0xff, 0x02, 0x8f, 0x59, 0xff, 0x0e, 0xa3, 0x67, 0xff, 0x14, 0xa8, 0x6c, 0xff, 0x14, 0xa9, 0x6b, 0xff, 0x15, 0xab, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6a, 0xff, 0x11, 0xac, 0x69, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x11, 0xab, 0x6b, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x10, 0xaa, 0x6f, 0xff, 0x10, 0xa9, 0x70, 0xff, 0x10, 0xa9, 0x70, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x70, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa7, 0x74, 0xff, 0x10, 0xa7, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0c, 0xa2, 0x75, 0xff, 0x0e, 0x9e, 0x74, 0xff, 0x0f, 0x9f, 0x75, 0xff, 0x0a, 0x9b, 0x71, 0xff, 0x0d, 0x9f, 0x74, 0xff, 0x0f, 0xa2, 0x77, 0xff, 0x0f, 0xa2, 0x77, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x12, 0xa4, 0x7d, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x10, 0xa5, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xaa, 0x7a, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x77, 0xff, 0x11, 0xac, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xab, 0x79, 0xff, 0x13, 0xad, 0x7c, 0xff, 0x13, 0xad, 0x7e, 0xff, 0x13, 0xad, 0x7e, 0xff, 0x14, 0xad, 0x7d, 0xff, 0x15, 0xad, 0x7d, 0xff, 0x15, 0xac, 0x80, 0xff, 0x19, 0xae, 0x86, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1c, 0xaf, 0x8e, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xb0, 0x8f, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1d, 0xaf, 0x8e, 0xff, 0x1a, 0xad, 0x8c, 0xff, 0x1a, 0xad, 0x8b, 0xff, 0x19, 0xad, 0x89, 0xff, 0x18, 0xac, 0x86, 0xff, 0x17, 0xac, 0x83, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xa9, 0x77, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x06, 0xa2, 0x6a, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x23, 0xb8, 0x86, 0xff, 0x0f, 0x9b, 0x69, 0xff, 0x09, 0x91, 0x5f, 0xff, 0x0e, 0x92, 0x64, 0xff, 0x16, 0x94, 0x6b, 0xff, 0x27, 0xa2, 0x7f, 0xff, 0x49, 0xc4, 0xa6, 0xff, 0x44, 0xc5, 0xa3, 0xff, 0x1f, 0xaa, 0x80, 0xff, 0x0c, 0xa1, 0x70, 0xff, 0x05, 0x9e, 0x69, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x10, 0xa3, 0x70, 0xff, 0x12, 0xa3, 0x6e, 0xff, 0x0e, 0xa1, 0x6a, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x10, 0xa3, 0x68, 0xff, 0x11, 0xa4, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x10, 0xab, 0x72, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x18, 0xa1, 0x6e, 0xff, 0x24, 0xa1, 0x75, 0xff, 0x39, 0xa6, 0x8c, 0xff, 0x2a, 0x88, 0x96, 0xff, 0x07, 0x66, 0xac, 0xff, 0x0f, 0x62, 0xcd, 0xff, 0x12, 0x6c, 0xd8, 0xff, 0x03, 0x6c, 0xd8, 0xff, 0x01, 0x5f, 0xbb, 0xff, 0x05, 0x67, 0x9a, 0xff, 0x0e, 0x95, 0x76, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x08, 0xa1, 0x67, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x09, 0x9f, 0x67, 0xff, 0x05, 0x97, 0x60, 0xff, 0x03, 0x94, 0x5d, 0xff, 0x04, 0x94, 0x5d, 0xff, 0x0d, 0x9e, 0x66, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0b, 0xa1, 0x5c, 0xff, 0x0e, 0xa1, 0x5a, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0d, 0x9b, 0x54, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0d, 0x98, 0x51, 0xff, 0x0e, 0x95, 0x4f, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x92, 0x4a, 0xff, 0x0b, 0x93, 0x4b, 0xff, 0x0c, 0x93, 0x4c, 0xff, 0x0b, 0x90, 0x4b, 0xff, 0x0b, 0x8e, 0x4b, 0xff, 0x0b, 0x89, 0x48, 0xff, 0x0a, 0x85, 0x46, 0xff, 0x09, 0x81, 0x44, 0xff, 0x0c, 0x80, 0x40, 0xff, 0x04, 0x7f, 0x3e, 0xff, 0x0a, 0x77, 0x41, 0xff, 0x1c, 0xab, 0x5d, 0xff, 0x19, 0xb7, 0x52, 0xff, 0x0a, 0x85, 0x2e, 0xff, 0x06, 0x71, 0x27, 0xff, 0x04, 0x6a, 0x2b, 0xff, 0x0e, 0x84, 0x4d, 0xff, 0x09, 0x7d, 0x3f, 0xff, 0x0c, 0x6b, 0x2d, 0xff, 0x12, 0x60, 0x36, 0xff, 0x09, 0x5b, 0x3d, 0xff, 0x05, 0x57, 0x2d, 0xff, 0x05, 0x59, 0x1e, 0xff, 0x04, 0x57, 0x18, 0xff, 0x09, 0x63, 0x21, 0xff, 0x04, 0x61, 0x1c, 0xff, 0x00, 0x47, 0x0f, 0xff, 0x05, 0x46, 0x18, 0xff, 0x09, 0x47, 0x19, 0xff, 0x07, 0x42, 0x14, 0xff, 0x03, 0x3e, 0x17, 0xff, 0x7f, 0x9f, 0x8a, 0xff, + 0x05, 0x77, 0x3b, 0xff, 0x09, 0x7a, 0x38, 0xff, 0x0d, 0x77, 0x37, 0xff, 0x12, 0x73, 0x3a, 0xff, 0x04, 0x5d, 0x2a, 0xff, 0x0a, 0x7b, 0x49, 0xff, 0x11, 0x9d, 0x65, 0xff, 0x08, 0xa6, 0x67, 0xff, 0x0e, 0xa9, 0x68, 0xff, 0x18, 0xb8, 0x73, 0xff, 0x10, 0xb7, 0x6f, 0xff, 0x06, 0xac, 0x62, 0xff, 0x02, 0xa6, 0x5b, 0xff, 0x01, 0xad, 0x61, 0xff, 0x02, 0xb2, 0x65, 0xff, 0x02, 0xb8, 0x6a, 0xff, 0x02, 0xba, 0x6a, 0xff, 0x02, 0xbb, 0x6a, 0xff, 0x03, 0xbb, 0x69, 0xff, 0x04, 0xb9, 0x69, 0xff, 0x0c, 0xbb, 0x70, 0xff, 0x10, 0xba, 0x74, 0xff, 0x15, 0xb0, 0x6e, 0xff, 0x0d, 0x90, 0x54, 0xff, 0x03, 0x7d, 0x44, 0xff, 0x02, 0x70, 0x3b, 0xff, 0x03, 0x75, 0x43, 0xff, 0x04, 0x87, 0x54, 0xff, 0x0f, 0x9e, 0x69, 0xff, 0x0e, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa5, 0x6d, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x09, 0xa9, 0x6d, 0xff, 0x08, 0xaa, 0x6b, 0xff, 0x09, 0xaa, 0x69, 0xff, 0x0c, 0xa8, 0x6b, 0xff, 0x12, 0xa7, 0x6d, 0xff, 0x0b, 0x9a, 0x65, 0xff, 0x01, 0x89, 0x54, 0xff, 0x06, 0x99, 0x5d, 0xff, 0x10, 0xa2, 0x66, 0xff, 0x14, 0xa7, 0x6a, 0xff, 0x12, 0xa7, 0x68, 0xff, 0x12, 0xa9, 0x68, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x12, 0xae, 0x6a, 0xff, 0x12, 0xad, 0x6a, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x0f, 0xa9, 0x6d, 0xff, 0x0f, 0xa9, 0x6e, 0xff, 0x0f, 0xa9, 0x6f, 0xff, 0x0f, 0xa9, 0x70, 0xff, 0x11, 0xaa, 0x71, 0xff, 0x11, 0xaa, 0x71, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x6f, 0xff, 0x13, 0xaa, 0x72, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0b, 0xa2, 0x73, 0xff, 0x0c, 0xa1, 0x75, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x10, 0xa0, 0x76, 0xff, 0x10, 0xa0, 0x76, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x0f, 0xa1, 0x77, 0xff, 0x10, 0xa1, 0x79, 0xff, 0x10, 0xa2, 0x7a, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa5, 0x7e, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x10, 0xa6, 0x7b, 0xff, 0x11, 0xa7, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xaa, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7c, 0xff, 0x13, 0xad, 0x7e, 0xff, 0x13, 0xac, 0x7e, 0xff, 0x13, 0xac, 0x7d, 0xff, 0x15, 0xad, 0x7d, 0xff, 0x17, 0xae, 0x82, 0xff, 0x19, 0xae, 0x88, 0xff, 0x1c, 0xaf, 0x8e, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8d, 0xff, 0x1d, 0xb0, 0x8d, 0xff, 0x1d, 0xb0, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1d, 0xb0, 0x8d, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1e, 0xb1, 0x8f, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1a, 0xad, 0x8c, 0xff, 0x1a, 0xad, 0x8b, 0xff, 0x19, 0xad, 0x89, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x84, 0xff, 0x15, 0xac, 0x80, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x03, 0x9d, 0x64, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x17, 0xac, 0x77, 0xff, 0x26, 0xb7, 0x80, 0xff, 0x10, 0x9e, 0x66, 0xff, 0x1d, 0xa7, 0x72, 0xff, 0x2f, 0xb6, 0x85, 0xff, 0x0e, 0x8d, 0x66, 0xff, 0x10, 0x85, 0x68, 0xff, 0x32, 0xb0, 0x8d, 0xff, 0x1c, 0xa5, 0x7a, 0xff, 0x0a, 0x9f, 0x6c, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x10, 0xa1, 0x71, 0xff, 0x0d, 0x9b, 0x68, 0xff, 0x06, 0x96, 0x61, 0xff, 0x0a, 0xa0, 0x68, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0f, 0xa3, 0x67, 0xff, 0x0d, 0xa3, 0x64, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x19, 0xa9, 0x75, 0xff, 0x2b, 0xa6, 0x76, 0xff, 0x5a, 0xc3, 0x9a, 0xff, 0x7d, 0xd9, 0xb5, 0xff, 0x50, 0xb6, 0x96, 0xff, 0x15, 0x83, 0x91, 0xff, 0x06, 0x5e, 0x95, 0xff, 0x0f, 0x61, 0xa9, 0xff, 0x03, 0x68, 0xa7, 0xff, 0x03, 0x78, 0x8f, 0xff, 0x0d, 0x8c, 0x83, 0xff, 0x0b, 0xa3, 0x73, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x06, 0xa3, 0x6a, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0e, 0xa2, 0x6a, 0xff, 0x0b, 0x9d, 0x65, 0xff, 0x0a, 0x9c, 0x65, 0xff, 0x03, 0x96, 0x5e, 0xff, 0x00, 0x90, 0x59, 0xff, 0x00, 0x91, 0x5a, 0xff, 0x04, 0x95, 0x5e, 0xff, 0x0c, 0x9f, 0x68, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0b, 0xa5, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x09, 0x9f, 0x5d, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0b, 0xa0, 0x5b, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0d, 0x9b, 0x54, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0d, 0x98, 0x51, 0xff, 0x0e, 0x95, 0x4f, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x92, 0x4b, 0xff, 0x0c, 0x93, 0x4b, 0xff, 0x0d, 0x93, 0x4c, 0xff, 0x0a, 0x90, 0x48, 0xff, 0x0a, 0x8d, 0x48, 0xff, 0x0b, 0x89, 0x48, 0xff, 0x0a, 0x85, 0x46, 0xff, 0x09, 0x81, 0x43, 0xff, 0x09, 0x81, 0x3e, 0xff, 0x08, 0x82, 0x3e, 0xff, 0x12, 0x7a, 0x41, 0xff, 0x0b, 0x8a, 0x46, 0xff, 0x0e, 0x9a, 0x44, 0xff, 0x0a, 0x81, 0x2a, 0xff, 0x05, 0x6f, 0x23, 0xff, 0x06, 0x61, 0x24, 0xff, 0x0a, 0x67, 0x31, 0xff, 0x16, 0x83, 0x42, 0xff, 0x0a, 0x6d, 0x2f, 0xff, 0x0a, 0x5d, 0x39, 0xff, 0x06, 0x5c, 0x3d, 0xff, 0x06, 0x5f, 0x23, 0xff, 0x0d, 0x6b, 0x20, 0xff, 0x03, 0x53, 0x1c, 0xff, 0x04, 0x4a, 0x1a, 0xff, 0x04, 0x51, 0x1a, 0xff, 0x02, 0x43, 0x11, 0xff, 0x04, 0x44, 0x16, 0xff, 0x09, 0x47, 0x18, 0xff, 0x07, 0x42, 0x15, 0xff, 0x02, 0x40, 0x18, 0xff, 0x82, 0xa8, 0x8c, 0xff, + 0x05, 0x75, 0x3b, 0xff, 0x0c, 0x78, 0x37, 0xff, 0x11, 0x74, 0x35, 0xff, 0x0e, 0x67, 0x31, 0xff, 0x02, 0x5b, 0x28, 0xff, 0x10, 0x93, 0x60, 0xff, 0x12, 0xa4, 0x6a, 0xff, 0x10, 0xac, 0x6a, 0xff, 0x0a, 0xaa, 0x65, 0xff, 0x05, 0xa1, 0x5a, 0xff, 0x08, 0xa2, 0x59, 0xff, 0x09, 0xa3, 0x58, 0xff, 0x07, 0xa7, 0x5b, 0xff, 0x03, 0xab, 0x5f, 0xff, 0x04, 0xaf, 0x63, 0xff, 0x06, 0xb5, 0x6a, 0xff, 0x08, 0xb9, 0x6c, 0xff, 0x09, 0xba, 0x6c, 0xff, 0x0a, 0xba, 0x6c, 0xff, 0x08, 0xb3, 0x69, 0xff, 0x12, 0xb6, 0x71, 0xff, 0x0c, 0xa8, 0x67, 0xff, 0x04, 0x95, 0x57, 0xff, 0x08, 0x93, 0x58, 0xff, 0x12, 0x9a, 0x62, 0xff, 0x12, 0x97, 0x64, 0xff, 0x16, 0x9b, 0x6b, 0xff, 0x10, 0x9d, 0x6c, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x06, 0xa6, 0x6f, 0xff, 0x04, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa4, 0x6d, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x06, 0xa9, 0x6d, 0xff, 0x06, 0xa8, 0x6a, 0xff, 0x07, 0xa8, 0x6a, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x11, 0xa7, 0x6d, 0xff, 0x0d, 0x9d, 0x67, 0xff, 0x06, 0x92, 0x5d, 0xff, 0x0a, 0x9a, 0x5f, 0xff, 0x0d, 0x9c, 0x61, 0xff, 0x0f, 0xa2, 0x65, 0xff, 0x0f, 0xa3, 0x65, 0xff, 0x0e, 0xa5, 0x64, 0xff, 0x0f, 0xa7, 0x66, 0xff, 0x11, 0xac, 0x69, 0xff, 0x11, 0xad, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x0f, 0xab, 0x6d, 0xff, 0x10, 0xab, 0x6e, 0xff, 0x11, 0xab, 0x71, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xab, 0x71, 0xff, 0x11, 0xaa, 0x70, 0xff, 0x13, 0xaa, 0x71, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x72, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa3, 0x75, 0xff, 0x0d, 0xa3, 0x76, 0xff, 0x0e, 0xa3, 0x76, 0xff, 0x13, 0xa3, 0x79, 0xff, 0x11, 0xa2, 0x78, 0xff, 0x12, 0xa2, 0x78, 0xff, 0x11, 0xa1, 0x7a, 0xff, 0x11, 0xa2, 0x7a, 0xff, 0x10, 0xa1, 0x7a, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x7a, 0xff, 0x10, 0xa1, 0x7a, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x12, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x12, 0xa6, 0x7c, 0xff, 0x11, 0xa7, 0x7c, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x11, 0xaa, 0x7b, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xaa, 0x7a, 0xff, 0x10, 0xaa, 0x7c, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x12, 0xab, 0x7c, 0xff, 0x14, 0xab, 0x7b, 0xff, 0x16, 0xac, 0x81, 0xff, 0x18, 0xad, 0x87, 0xff, 0x1c, 0xaf, 0x8e, 0xff, 0x1d, 0xaf, 0x8f, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8e, 0xff, 0x1c, 0xae, 0x8e, 0xff, 0x1b, 0xad, 0x8d, 0xff, 0x1a, 0xac, 0x8c, 0xff, 0x1a, 0xad, 0x8c, 0xff, 0x18, 0xac, 0x88, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xad, 0x84, 0xff, 0x16, 0xac, 0x80, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x12, 0xaa, 0x78, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x06, 0xa0, 0x68, 0xff, 0x05, 0x9f, 0x65, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x1e, 0xb4, 0x7d, 0xff, 0x30, 0xc5, 0x89, 0xff, 0x0d, 0xa1, 0x62, 0xff, 0x2c, 0xbe, 0x82, 0xff, 0x3c, 0xca, 0x94, 0xff, 0x06, 0x8c, 0x5f, 0xff, 0x0b, 0x81, 0x61, 0xff, 0x26, 0xa4, 0x80, 0xff, 0x0e, 0x96, 0x6b, 0xff, 0x0d, 0xa2, 0x70, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x0a, 0xa1, 0x6d, 0xff, 0x0a, 0x9f, 0x6d, 0xff, 0x09, 0x98, 0x68, 0xff, 0x03, 0x8f, 0x5d, 0xff, 0x03, 0x91, 0x5e, 0xff, 0x0c, 0x9f, 0x68, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0e, 0xa2, 0x66, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x13, 0xac, 0x79, 0xff, 0x18, 0xa2, 0x72, 0xff, 0x61, 0xd1, 0xa3, 0xff, 0x7d, 0xd8, 0xb0, 0xff, 0x7f, 0xcd, 0xa7, 0xff, 0x4d, 0xaf, 0x86, 0xff, 0x1a, 0x8b, 0x81, 0xff, 0x28, 0x85, 0x98, 0xff, 0x40, 0x90, 0xaf, 0xff, 0x14, 0x87, 0x87, 0xff, 0x0c, 0x98, 0x7e, 0xff, 0x0e, 0x9f, 0x75, 0xff, 0x02, 0xa4, 0x6b, 0xff, 0x05, 0xa4, 0x6a, 0xff, 0x05, 0xa2, 0x69, 0xff, 0x06, 0xa3, 0x6a, 0xff, 0x07, 0xa3, 0x6a, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x07, 0x9e, 0x67, 0xff, 0x09, 0x94, 0x60, 0xff, 0x02, 0x86, 0x52, 0xff, 0x02, 0x8c, 0x57, 0xff, 0x05, 0x95, 0x5e, 0xff, 0x06, 0x98, 0x61, 0xff, 0x06, 0x9a, 0x62, 0xff, 0x09, 0x9e, 0x64, 0xff, 0x0b, 0xa2, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa2, 0x66, 0xff, 0x0c, 0xa2, 0x65, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0a, 0xa0, 0x5f, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x0a, 0xa1, 0x5c, 0xff, 0x0a, 0xa1, 0x5c, 0xff, 0x0a, 0xa0, 0x5b, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x0c, 0x97, 0x50, 0xff, 0x0d, 0x95, 0x4f, 0xff, 0x0c, 0x93, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0b, 0x92, 0x4b, 0xff, 0x0c, 0x92, 0x4a, 0xff, 0x0b, 0x91, 0x4a, 0xff, 0x0a, 0x8e, 0x47, 0xff, 0x09, 0x8c, 0x48, 0xff, 0x09, 0x87, 0x47, 0xff, 0x0a, 0x84, 0x46, 0xff, 0x09, 0x81, 0x43, 0xff, 0x0b, 0x7f, 0x3f, 0xff, 0x07, 0x7f, 0x40, 0xff, 0x0b, 0x7a, 0x42, 0xff, 0x06, 0x7f, 0x44, 0xff, 0x17, 0x9a, 0x53, 0xff, 0x04, 0x7b, 0x30, 0xff, 0x06, 0x73, 0x2c, 0xff, 0x06, 0x64, 0x2d, 0xff, 0x09, 0x61, 0x34, 0xff, 0x0b, 0x78, 0x3a, 0xff, 0x0a, 0x75, 0x31, 0xff, 0x0a, 0x5b, 0x31, 0xff, 0x0d, 0x5b, 0x39, 0xff, 0x09, 0x65, 0x22, 0xff, 0x06, 0x6f, 0x19, 0xff, 0x04, 0x59, 0x1c, 0xff, 0x05, 0x43, 0x18, 0xff, 0x05, 0x42, 0x15, 0xff, 0x04, 0x3e, 0x12, 0xff, 0x03, 0x40, 0x12, 0xff, 0x04, 0x45, 0x15, 0xff, 0x02, 0x40, 0x14, 0xff, 0x03, 0x43, 0x1a, 0xff, 0x7d, 0xa4, 0x85, 0xff, + 0x04, 0x74, 0x3a, 0xff, 0x0a, 0x76, 0x34, 0xff, 0x10, 0x6f, 0x34, 0xff, 0x03, 0x53, 0x20, 0xff, 0x0b, 0x79, 0x46, 0xff, 0x16, 0xa5, 0x6b, 0xff, 0x14, 0xa5, 0x64, 0xff, 0x07, 0x9c, 0x55, 0xff, 0x01, 0x98, 0x53, 0xff, 0x04, 0x9b, 0x58, 0xff, 0x0d, 0xa0, 0x5a, 0xff, 0x10, 0xa4, 0x59, 0xff, 0x0a, 0xa6, 0x5a, 0xff, 0x03, 0xa7, 0x5e, 0xff, 0x02, 0xab, 0x61, 0xff, 0x03, 0xaf, 0x64, 0xff, 0x08, 0xb6, 0x6a, 0xff, 0x08, 0xb6, 0x6c, 0xff, 0x0c, 0xb5, 0x6e, 0xff, 0x10, 0xb1, 0x6e, 0xff, 0x0c, 0xa9, 0x6a, 0xff, 0x03, 0x9b, 0x5f, 0xff, 0x09, 0x9f, 0x66, 0xff, 0x0e, 0xa3, 0x69, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x10, 0xa3, 0x6f, 0xff, 0x0e, 0xa3, 0x70, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x06, 0xa8, 0x6f, 0xff, 0x0a, 0xa9, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6e, 0xff, 0x06, 0xa5, 0x6c, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6e, 0xff, 0x06, 0xa8, 0x6d, 0xff, 0x08, 0xa8, 0x6c, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x10, 0xa4, 0x6c, 0xff, 0x12, 0xa4, 0x68, 0xff, 0x0e, 0xa1, 0x63, 0xff, 0x0e, 0xa5, 0x65, 0xff, 0x10, 0xa8, 0x68, 0xff, 0x0d, 0xa6, 0x65, 0xff, 0x0b, 0xa4, 0x63, 0xff, 0x10, 0xa9, 0x67, 0xff, 0x13, 0xac, 0x6b, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6e, 0xff, 0x12, 0xad, 0x6f, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xac, 0x71, 0xff, 0x10, 0xaa, 0x70, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xa9, 0x72, 0xff, 0x11, 0xa8, 0x72, 0xff, 0x11, 0xa9, 0x72, 0xff, 0x11, 0xa9, 0x72, 0xff, 0x12, 0xa9, 0x74, 0xff, 0x12, 0xa8, 0x74, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x11, 0xa7, 0x75, 0xff, 0x0f, 0xa6, 0x72, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa4, 0x77, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x12, 0xa1, 0x7c, 0xff, 0x12, 0xa1, 0x7c, 0xff, 0x12, 0xa1, 0x7c, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x12, 0xa3, 0x7a, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x12, 0xa4, 0x7c, 0xff, 0x11, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x11, 0xa5, 0x7c, 0xff, 0x12, 0xa6, 0x7d, 0xff, 0x12, 0xa6, 0x7d, 0xff, 0x12, 0xa5, 0x7e, 0xff, 0x13, 0xa5, 0x7e, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7d, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x12, 0xa5, 0x7b, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x11, 0xa7, 0x7c, 0xff, 0x12, 0xa7, 0x7b, 0xff, 0x11, 0xa7, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xaa, 0x7b, 0xff, 0x12, 0xaa, 0x7a, 0xff, 0x11, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x13, 0xab, 0x7a, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x16, 0xac, 0x83, 0xff, 0x1b, 0xaf, 0x8b, 0xff, 0x1d, 0xaf, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1d, 0xb0, 0x8e, 0xff, 0x1c, 0xb0, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xb0, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x19, 0xac, 0x8b, 0xff, 0x19, 0xab, 0x8b, 0xff, 0x1a, 0xad, 0x8b, 0xff, 0x19, 0xac, 0x8a, 0xff, 0x18, 0xac, 0x86, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x80, 0xff, 0x15, 0xab, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x0f, 0xaa, 0x76, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x06, 0x9d, 0x60, 0xff, 0x12, 0xa9, 0x6d, 0xff, 0x1c, 0xb1, 0x79, 0xff, 0x07, 0x97, 0x63, 0xff, 0x14, 0x9a, 0x6e, 0xff, 0x28, 0xb3, 0x85, 0xff, 0x0c, 0x9d, 0x6c, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0a, 0x9f, 0x6c, 0xff, 0x03, 0x95, 0x64, 0xff, 0x03, 0x90, 0x60, 0xff, 0x05, 0x8b, 0x5a, 0xff, 0x03, 0x89, 0x57, 0xff, 0x0a, 0x97, 0x63, 0xff, 0x0e, 0x9e, 0x68, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x0f, 0xa2, 0x6b, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x0e, 0xa0, 0x67, 0xff, 0x0f, 0xa3, 0x65, 0xff, 0x08, 0x9f, 0x66, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x12, 0xa6, 0x72, 0xff, 0x35, 0xb3, 0x84, 0xff, 0x77, 0xd8, 0xac, 0xff, 0x5b, 0xad, 0x88, 0xff, 0x54, 0xa6, 0x82, 0xff, 0x41, 0x9e, 0x7a, 0xff, 0x33, 0x93, 0x88, 0xff, 0x52, 0xa1, 0xaa, 0xff, 0x5a, 0xad, 0xb1, 0xff, 0x1a, 0x98, 0x7a, 0xff, 0x0a, 0xa1, 0x6e, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x05, 0xa5, 0x6f, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x06, 0xa3, 0x6c, 0xff, 0x03, 0xa4, 0x6c, 0xff, 0x04, 0xa3, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0d, 0x9b, 0x66, 0xff, 0x08, 0x91, 0x5c, 0xff, 0x01, 0x81, 0x4d, 0xff, 0x01, 0x80, 0x4b, 0xff, 0x02, 0x8a, 0x54, 0xff, 0x07, 0x98, 0x61, 0xff, 0x0c, 0xa2, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x0b, 0xa2, 0x62, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0a, 0xa0, 0x60, 0xff, 0x0a, 0xa0, 0x5f, 0xff, 0x09, 0x9f, 0x5d, 0xff, 0x0b, 0xa0, 0x5d, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0b, 0xa0, 0x5b, 0xff, 0x0c, 0xa0, 0x5b, 0xff, 0x0e, 0xa1, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0e, 0x9f, 0x57, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0e, 0x9d, 0x56, 0xff, 0x0e, 0x9d, 0x56, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0b, 0x9a, 0x52, 0xff, 0x09, 0x97, 0x50, 0xff, 0x0a, 0x97, 0x50, 0xff, 0x0a, 0x95, 0x4d, 0xff, 0x0b, 0x93, 0x4d, 0xff, 0x0b, 0x93, 0x4c, 0xff, 0x0a, 0x92, 0x4c, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0c, 0x91, 0x4b, 0xff, 0x0b, 0x90, 0x4a, 0xff, 0x0b, 0x8d, 0x48, 0xff, 0x0a, 0x8a, 0x47, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x09, 0x83, 0x44, 0xff, 0x09, 0x81, 0x43, 0xff, 0x0a, 0x80, 0x42, 0xff, 0x05, 0x7d, 0x42, 0xff, 0x06, 0x7b, 0x43, 0xff, 0x08, 0x7b, 0x45, 0xff, 0x17, 0x8f, 0x52, 0xff, 0x05, 0x77, 0x34, 0xff, 0x05, 0x6f, 0x30, 0xff, 0x08, 0x69, 0x37, 0xff, 0x08, 0x64, 0x37, 0xff, 0x02, 0x67, 0x2e, 0xff, 0x09, 0x69, 0x2d, 0xff, 0x0f, 0x5c, 0x31, 0xff, 0x0d, 0x5a, 0x30, 0xff, 0x0a, 0x64, 0x1f, 0xff, 0x03, 0x65, 0x14, 0xff, 0x03, 0x54, 0x17, 0xff, 0x07, 0x44, 0x18, 0xff, 0x04, 0x38, 0x11, 0xff, 0x07, 0x3b, 0x15, 0xff, 0x04, 0x3e, 0x16, 0xff, 0x02, 0x3f, 0x17, 0xff, 0x01, 0x43, 0x16, 0xff, 0x06, 0x4b, 0x1c, 0xff, 0x76, 0x9f, 0x80, 0xff, + 0x06, 0x71, 0x39, 0xff, 0x0c, 0x71, 0x34, 0xff, 0x07, 0x5c, 0x25, 0xff, 0x08, 0x65, 0x33, 0xff, 0x1d, 0x9b, 0x65, 0xff, 0x09, 0x9b, 0x5b, 0xff, 0x05, 0x95, 0x4f, 0xff, 0x06, 0x95, 0x50, 0xff, 0x06, 0x98, 0x56, 0xff, 0x08, 0x9c, 0x5b, 0xff, 0x0a, 0x9f, 0x5a, 0xff, 0x0d, 0xa2, 0x59, 0xff, 0x0a, 0xa5, 0x5a, 0xff, 0x05, 0xa6, 0x5e, 0xff, 0x02, 0xa8, 0x5e, 0xff, 0x02, 0xab, 0x5e, 0xff, 0x06, 0xb0, 0x65, 0xff, 0x0b, 0xb3, 0x6c, 0xff, 0x10, 0xb3, 0x71, 0xff, 0x06, 0xa1, 0x63, 0xff, 0x04, 0x9c, 0x61, 0xff, 0x0a, 0xa1, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0b, 0xa9, 0x6f, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x05, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0c, 0xa8, 0x6d, 0xff, 0x0e, 0xa8, 0x6d, 0xff, 0x11, 0xa8, 0x6b, 0xff, 0x12, 0xaa, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xab, 0x69, 0xff, 0x0c, 0xa6, 0x66, 0xff, 0x0e, 0xa4, 0x65, 0xff, 0x11, 0xa8, 0x69, 0xff, 0x0f, 0xa9, 0x68, 0xff, 0x0f, 0xa9, 0x68, 0xff, 0x0f, 0xa9, 0x68, 0xff, 0x0e, 0xa8, 0x67, 0xff, 0x0e, 0xa8, 0x67, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xac, 0x6c, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x12, 0xad, 0x70, 0xff, 0x11, 0xab, 0x70, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa3, 0x7d, 0xff, 0x10, 0xa3, 0x7c, 0xff, 0x11, 0xa5, 0x7d, 0xff, 0x11, 0xa5, 0x7b, 0xff, 0x13, 0xa5, 0x7d, 0xff, 0x13, 0xa4, 0x7e, 0xff, 0x12, 0xa4, 0x7d, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x13, 0xa4, 0x7d, 0xff, 0x11, 0xa4, 0x7a, 0xff, 0x12, 0xa4, 0x7a, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x11, 0xa8, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x12, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7a, 0xff, 0x13, 0xab, 0x79, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x15, 0xab, 0x80, 0xff, 0x19, 0xae, 0x86, 0xff, 0x1b, 0xae, 0x8b, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1b, 0xaf, 0x8c, 0xff, 0x1b, 0xaf, 0x8b, 0xff, 0x1b, 0xae, 0x8c, 0xff, 0x1b, 0xae, 0x8c, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1c, 0xaf, 0x8d, 0xff, 0x1b, 0xaf, 0x8c, 0xff, 0x1b, 0xaf, 0x8b, 0xff, 0x1a, 0xae, 0x8a, 0xff, 0x1a, 0xae, 0x8a, 0xff, 0x19, 0xad, 0x89, 0xff, 0x18, 0xac, 0x89, 0xff, 0x1a, 0xad, 0x8a, 0xff, 0x19, 0xad, 0x8a, 0xff, 0x17, 0xab, 0x86, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x16, 0xab, 0x80, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x10, 0xab, 0x7a, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0d, 0xa2, 0x6a, 0xff, 0x0b, 0xa2, 0x69, 0xff, 0x0e, 0xa7, 0x6c, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa5, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x08, 0x9e, 0x6c, 0xff, 0x07, 0x98, 0x67, 0xff, 0x0d, 0x9a, 0x69, 0xff, 0x16, 0x9d, 0x6b, 0xff, 0x04, 0x89, 0x57, 0xff, 0x02, 0x85, 0x53, 0xff, 0x0e, 0x95, 0x63, 0xff, 0x16, 0x9d, 0x6a, 0xff, 0x0c, 0x95, 0x61, 0xff, 0x0d, 0x95, 0x62, 0xff, 0x0d, 0x97, 0x62, 0xff, 0x0c, 0x9b, 0x5f, 0xff, 0x0d, 0xa2, 0x69, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x19, 0xa7, 0x74, 0xff, 0x35, 0xaa, 0x7c, 0xff, 0x55, 0xac, 0x85, 0xff, 0x43, 0x93, 0x71, 0xff, 0x37, 0x90, 0x70, 0xff, 0x33, 0x92, 0x74, 0xff, 0x39, 0x93, 0x88, 0xff, 0x5d, 0xa9, 0xad, 0xff, 0x60, 0xbb, 0xb4, 0xff, 0x18, 0x9a, 0x79, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x12, 0xa2, 0x6c, 0xff, 0x0e, 0x9e, 0x6f, 0xff, 0x10, 0x9e, 0x6c, 0xff, 0x08, 0x9d, 0x68, 0xff, 0x07, 0x9f, 0x69, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0b, 0x99, 0x64, 0xff, 0x03, 0x83, 0x50, 0xff, 0x02, 0x79, 0x46, 0xff, 0x05, 0x81, 0x4f, 0xff, 0x08, 0x96, 0x61, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa6, 0x6a, 0xff, 0x08, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0b, 0xa3, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0c, 0x9f, 0x5c, 0xff, 0x0c, 0xa0, 0x5b, 0xff, 0x0e, 0x9f, 0x5a, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0d, 0x9e, 0x55, 0xff, 0x0f, 0x9d, 0x56, 0xff, 0x0e, 0x9c, 0x55, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x09, 0x97, 0x50, 0xff, 0x09, 0x96, 0x4f, 0xff, 0x08, 0x94, 0x4d, 0xff, 0x09, 0x94, 0x4d, 0xff, 0x09, 0x93, 0x4c, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0c, 0x91, 0x4b, 0xff, 0x0b, 0x8f, 0x49, 0xff, 0x0a, 0x8c, 0x48, 0xff, 0x0b, 0x89, 0x47, 0xff, 0x0a, 0x84, 0x44, 0xff, 0x0a, 0x82, 0x42, 0xff, 0x09, 0x80, 0x42, 0xff, 0x07, 0x7f, 0x42, 0xff, 0x04, 0x7d, 0x41, 0xff, 0x04, 0x7a, 0x41, 0xff, 0x08, 0x7a, 0x41, 0xff, 0x07, 0x79, 0x3a, 0xff, 0x03, 0x72, 0x31, 0xff, 0x03, 0x6c, 0x2f, 0xff, 0x08, 0x6e, 0x38, 0xff, 0x09, 0x6b, 0x39, 0xff, 0x04, 0x5f, 0x2d, 0xff, 0x06, 0x59, 0x2a, 0xff, 0x0b, 0x56, 0x2d, 0xff, 0x0b, 0x5a, 0x2b, 0xff, 0x05, 0x5c, 0x19, 0xff, 0x04, 0x5a, 0x13, 0xff, 0x04, 0x4d, 0x16, 0xff, 0x07, 0x46, 0x19, 0xff, 0x03, 0x39, 0x12, 0xff, 0x08, 0x3a, 0x18, 0xff, 0x02, 0x3c, 0x18, 0xff, 0x02, 0x3c, 0x18, 0xff, 0x03, 0x48, 0x1a, 0xff, 0x03, 0x4b, 0x17, 0xff, 0x75, 0x97, 0x7b, 0xff, + 0x0b, 0x70, 0x38, 0xff, 0x0f, 0x64, 0x2f, 0xff, 0x04, 0x55, 0x24, 0xff, 0x13, 0x85, 0x51, 0xff, 0x0f, 0x92, 0x57, 0xff, 0x03, 0x94, 0x4d, 0xff, 0x04, 0x94, 0x4f, 0xff, 0x07, 0x93, 0x56, 0xff, 0x06, 0x96, 0x54, 0xff, 0x08, 0x9c, 0x56, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x0a, 0xa2, 0x5b, 0xff, 0x0a, 0xa3, 0x5b, 0xff, 0x08, 0xa6, 0x5b, 0xff, 0x08, 0xa6, 0x5b, 0xff, 0x08, 0xa7, 0x5f, 0xff, 0x0e, 0xaf, 0x68, 0xff, 0x0d, 0xad, 0x69, 0xff, 0x06, 0xa0, 0x60, 0xff, 0x07, 0x9d, 0x61, 0xff, 0x0b, 0x9e, 0x66, 0xff, 0x0c, 0x9f, 0x69, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa6, 0x6d, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x0e, 0xa8, 0x6d, 0xff, 0x12, 0xaa, 0x6d, 0xff, 0x12, 0xab, 0x6c, 0xff, 0x12, 0xac, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xac, 0x6b, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x0e, 0xa5, 0x66, 0xff, 0x10, 0xa6, 0x67, 0xff, 0x0f, 0xa9, 0x68, 0xff, 0x0f, 0xa9, 0x68, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x11, 0xab, 0x6a, 0xff, 0x10, 0xaa, 0x69, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x0e, 0xaa, 0x6a, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xaa, 0x6e, 0xff, 0x11, 0xab, 0x70, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0f, 0xa7, 0x71, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x0f, 0xa3, 0x7c, 0xff, 0x0f, 0xa3, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x79, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xa8, 0x7a, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xa9, 0x79, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x13, 0xab, 0x7b, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x14, 0xab, 0x80, 0xff, 0x17, 0xac, 0x85, 0xff, 0x19, 0xad, 0x87, 0xff, 0x1a, 0xae, 0x89, 0xff, 0x1a, 0xae, 0x89, 0xff, 0x19, 0xad, 0x89, 0xff, 0x1a, 0xae, 0x89, 0xff, 0x1a, 0xad, 0x8a, 0xff, 0x1a, 0xad, 0x8b, 0xff, 0x1b, 0xae, 0x8c, 0xff, 0x1b, 0xae, 0x8c, 0xff, 0x1a, 0xad, 0x8a, 0xff, 0x19, 0xad, 0x89, 0xff, 0x18, 0xac, 0x87, 0xff, 0x19, 0xad, 0x87, 0xff, 0x18, 0xac, 0x88, 0xff, 0x18, 0xac, 0x88, 0xff, 0x19, 0xad, 0x89, 0xff, 0x19, 0xad, 0x88, 0xff, 0x17, 0xab, 0x85, 0xff, 0x15, 0xaa, 0x83, 0xff, 0x16, 0xaa, 0x81, 0xff, 0x16, 0xaa, 0x80, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x13, 0xab, 0x7e, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0f, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0e, 0xa8, 0x6d, 0xff, 0x0d, 0xa7, 0x6d, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0f, 0xa8, 0x6f, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x0c, 0xa1, 0x6f, 0xff, 0x0f, 0xa1, 0x6f, 0xff, 0x12, 0xa1, 0x6e, 0xff, 0x06, 0x92, 0x5f, 0xff, 0x04, 0x8a, 0x57, 0xff, 0x06, 0x88, 0x56, 0xff, 0x08, 0x86, 0x54, 0xff, 0x03, 0x79, 0x49, 0xff, 0x02, 0x77, 0x47, 0xff, 0x03, 0x75, 0x44, 0xff, 0x02, 0x83, 0x4c, 0xff, 0x09, 0x9a, 0x65, 0xff, 0x13, 0xa5, 0x73, 0xff, 0x1e, 0xa1, 0x73, 0xff, 0x33, 0xa3, 0x78, 0xff, 0x33, 0x92, 0x6c, 0xff, 0x33, 0x88, 0x69, 0xff, 0x41, 0x96, 0x79, 0xff, 0x29, 0x92, 0x71, 0xff, 0x1e, 0x89, 0x72, 0xff, 0x35, 0x95, 0x88, 0xff, 0x3d, 0xa4, 0x90, 0xff, 0x12, 0x91, 0x6b, 0xff, 0x06, 0x88, 0x54, 0xff, 0x06, 0x85, 0x50, 0xff, 0x06, 0x83, 0x53, 0xff, 0x05, 0x83, 0x52, 0xff, 0x03, 0x7f, 0x4d, 0xff, 0x07, 0x86, 0x54, 0xff, 0x12, 0x93, 0x61, 0xff, 0x03, 0x7f, 0x4c, 0xff, 0x09, 0x85, 0x52, 0xff, 0x10, 0x93, 0x60, 0xff, 0x12, 0x9d, 0x68, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0b, 0x9f, 0x5d, 0xff, 0x0c, 0x9f, 0x5c, 0xff, 0x0c, 0x9f, 0x5a, 0xff, 0x0e, 0x9f, 0x5a, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0e, 0x9f, 0x57, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0f, 0x9d, 0x56, 0xff, 0x0e, 0x9c, 0x55, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x08, 0x97, 0x50, 0xff, 0x09, 0x95, 0x4e, 0xff, 0x08, 0x94, 0x4d, 0xff, 0x0a, 0x94, 0x4d, 0xff, 0x0a, 0x94, 0x4d, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x0c, 0x92, 0x4c, 0xff, 0x0b, 0x90, 0x4a, 0xff, 0x0a, 0x8e, 0x48, 0xff, 0x0a, 0x8b, 0x47, 0xff, 0x0b, 0x87, 0x46, 0xff, 0x09, 0x83, 0x43, 0xff, 0x09, 0x81, 0x41, 0xff, 0x09, 0x80, 0x42, 0xff, 0x09, 0x7f, 0x41, 0xff, 0x08, 0x7d, 0x40, 0xff, 0x07, 0x7b, 0x3f, 0xff, 0x06, 0x79, 0x3b, 0xff, 0x0f, 0x83, 0x3f, 0xff, 0x0c, 0x81, 0x37, 0xff, 0x0c, 0x80, 0x37, 0xff, 0x0a, 0x7a, 0x38, 0xff, 0x0a, 0x71, 0x36, 0xff, 0x0e, 0x67, 0x34, 0xff, 0x08, 0x57, 0x2b, 0xff, 0x07, 0x51, 0x28, 0xff, 0x08, 0x55, 0x26, 0xff, 0x03, 0x54, 0x18, 0xff, 0x03, 0x50, 0x13, 0xff, 0x06, 0x49, 0x16, 0xff, 0x08, 0x48, 0x19, 0xff, 0x03, 0x3c, 0x12, 0xff, 0x05, 0x3a, 0x15, 0xff, 0x01, 0x3c, 0x14, 0xff, 0x03, 0x3f, 0x19, 0xff, 0x06, 0x49, 0x1d, 0xff, 0x02, 0x47, 0x14, 0xff, 0x77, 0x95, 0x7c, 0xff, + 0x10, 0x6e, 0x38, 0xff, 0x0a, 0x54, 0x22, 0xff, 0x0a, 0x66, 0x35, 0xff, 0x0a, 0x89, 0x53, 0xff, 0x08, 0x8c, 0x4f, 0xff, 0x05, 0x94, 0x49, 0xff, 0x08, 0x98, 0x4f, 0xff, 0x08, 0x94, 0x53, 0xff, 0x07, 0x96, 0x4e, 0xff, 0x09, 0x9b, 0x52, 0xff, 0x09, 0xa0, 0x5a, 0xff, 0x06, 0x9f, 0x5f, 0xff, 0x08, 0xa1, 0x5f, 0xff, 0x0c, 0xa4, 0x5b, 0xff, 0x0d, 0xa3, 0x5a, 0xff, 0x12, 0xa7, 0x62, 0xff, 0x16, 0xad, 0x6a, 0xff, 0x05, 0x9b, 0x5b, 0xff, 0x05, 0x99, 0x5c, 0xff, 0x0d, 0x9f, 0x66, 0xff, 0x0d, 0x9d, 0x67, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0d, 0xa7, 0x6d, 0xff, 0x11, 0xaa, 0x6c, 0xff, 0x10, 0xaa, 0x6d, 0xff, 0x11, 0xac, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x11, 0xa9, 0x68, 0xff, 0x12, 0xa9, 0x6a, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x12, 0xac, 0x6b, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x14, 0xae, 0x6d, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x13, 0xad, 0x6c, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x10, 0xab, 0x6f, 0xff, 0x10, 0xaa, 0x6f, 0xff, 0x0f, 0xa8, 0x70, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x10, 0xa8, 0x71, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x0f, 0xa3, 0x7b, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7c, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x10, 0xa4, 0x7b, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x7a, 0xff, 0x10, 0xa4, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x11, 0xa9, 0x78, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x12, 0xaa, 0x7a, 0xff, 0x13, 0xaa, 0x7c, 0xff, 0x15, 0xac, 0x81, 0xff, 0x17, 0xab, 0x84, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x86, 0xff, 0x19, 0xad, 0x89, 0xff, 0x1a, 0xae, 0x8a, 0xff, 0x1b, 0xad, 0x8c, 0xff, 0x1a, 0xad, 0x8b, 0xff, 0x19, 0xac, 0x89, 0xff, 0x18, 0xac, 0x88, 0xff, 0x17, 0xab, 0x85, 0xff, 0x18, 0xad, 0x86, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x87, 0xff, 0x19, 0xad, 0x88, 0xff, 0x18, 0xac, 0x86, 0xff, 0x16, 0xab, 0x84, 0xff, 0x15, 0xaa, 0x82, 0xff, 0x15, 0xaa, 0x80, 0xff, 0x15, 0xa9, 0x7f, 0xff, 0x12, 0xaa, 0x7d, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x12, 0xac, 0x7b, 0xff, 0x0f, 0xaa, 0x78, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0d, 0xa6, 0x6d, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x0d, 0xa8, 0x6d, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x09, 0xa9, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0b, 0xa1, 0x6d, 0xff, 0x0c, 0xa1, 0x6d, 0xff, 0x0b, 0x9d, 0x69, 0xff, 0x0e, 0x9c, 0x68, 0xff, 0x02, 0x81, 0x50, 0xff, 0x02, 0x7c, 0x4d, 0xff, 0x0d, 0x86, 0x57, 0xff, 0x06, 0x78, 0x4a, 0xff, 0x05, 0x74, 0x45, 0xff, 0x05, 0x80, 0x4c, 0xff, 0x06, 0x92, 0x60, 0xff, 0x0c, 0x97, 0x6a, 0xff, 0x0d, 0x85, 0x5b, 0xff, 0x1c, 0x8c, 0x64, 0xff, 0x25, 0x8d, 0x67, 0xff, 0x2e, 0x8a, 0x6a, 0xff, 0x35, 0x88, 0x6d, 0xff, 0x19, 0x87, 0x63, 0xff, 0x15, 0x8d, 0x6b, 0xff, 0x19, 0x8c, 0x6f, 0xff, 0x0d, 0x83, 0x62, 0xff, 0x02, 0x7b, 0x50, 0xff, 0x03, 0x7c, 0x48, 0xff, 0x05, 0x7e, 0x4a, 0xff, 0x04, 0x7f, 0x4c, 0xff, 0x03, 0x7d, 0x4d, 0xff, 0x02, 0x78, 0x49, 0xff, 0x02, 0x78, 0x49, 0xff, 0x05, 0x79, 0x49, 0xff, 0x01, 0x74, 0x44, 0xff, 0x10, 0x8e, 0x5e, 0xff, 0x11, 0x9b, 0x68, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0c, 0x9f, 0x5c, 0xff, 0x0b, 0x9f, 0x5a, 0xff, 0x0e, 0x9f, 0x5a, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x10, 0xa0, 0x58, 0xff, 0x10, 0x9e, 0x57, 0xff, 0x0e, 0x9c, 0x55, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x08, 0x96, 0x4f, 0xff, 0x09, 0x95, 0x4e, 0xff, 0x09, 0x95, 0x4e, 0xff, 0x0b, 0x95, 0x4e, 0xff, 0x0a, 0x94, 0x4d, 0xff, 0x0b, 0x93, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0c, 0x92, 0x4c, 0xff, 0x0a, 0x90, 0x49, 0xff, 0x08, 0x8c, 0x48, 0xff, 0x09, 0x8a, 0x47, 0xff, 0x0a, 0x86, 0x46, 0xff, 0x09, 0x82, 0x42, 0xff, 0x09, 0x81, 0x42, 0xff, 0x0a, 0x80, 0x43, 0xff, 0x0b, 0x7e, 0x40, 0xff, 0x08, 0x7b, 0x3d, 0xff, 0x09, 0x7d, 0x3e, 0xff, 0x0a, 0x7e, 0x3c, 0xff, 0x16, 0x8c, 0x43, 0xff, 0x11, 0x8a, 0x39, 0xff, 0x0d, 0x86, 0x34, 0xff, 0x0c, 0x83, 0x34, 0xff, 0x08, 0x74, 0x2d, 0xff, 0x11, 0x69, 0x33, 0xff, 0x10, 0x5c, 0x31, 0xff, 0x03, 0x47, 0x21, 0xff, 0x03, 0x47, 0x1c, 0xff, 0x05, 0x4b, 0x19, 0xff, 0x05, 0x49, 0x15, 0xff, 0x07, 0x47, 0x15, 0xff, 0x09, 0x49, 0x17, 0xff, 0x02, 0x3d, 0x11, 0xff, 0x04, 0x3b, 0x13, 0xff, 0x02, 0x3d, 0x14, 0xff, 0x04, 0x3f, 0x18, 0xff, 0x03, 0x44, 0x17, 0xff, 0x01, 0x42, 0x0f, 0xff, 0x75, 0x95, 0x7d, 0xff, + 0x0b, 0x60, 0x33, 0xff, 0x07, 0x55, 0x26, 0xff, 0x12, 0x7f, 0x48, 0xff, 0x04, 0x8b, 0x4e, 0xff, 0x0b, 0x8b, 0x4f, 0xff, 0x0f, 0x8d, 0x53, 0xff, 0x0d, 0x8d, 0x56, 0xff, 0x0e, 0x8c, 0x57, 0xff, 0x10, 0x91, 0x52, 0xff, 0x0d, 0x98, 0x51, 0xff, 0x06, 0x9a, 0x53, 0xff, 0x01, 0x9c, 0x5b, 0xff, 0x05, 0x9e, 0x5d, 0xff, 0x0c, 0xa0, 0x5c, 0xff, 0x12, 0x9e, 0x5c, 0xff, 0x13, 0x9a, 0x5e, 0xff, 0x04, 0x88, 0x4b, 0xff, 0x09, 0x97, 0x5b, 0xff, 0x0e, 0x9e, 0x65, 0xff, 0x10, 0x9f, 0x68, 0xff, 0x0f, 0x9e, 0x68, 0xff, 0x0c, 0x9d, 0x69, 0xff, 0x0b, 0x9f, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0e, 0xa9, 0x6d, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x10, 0xac, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xac, 0x6b, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x13, 0xac, 0x6c, 0xff, 0x13, 0xac, 0x6d, 0xff, 0x13, 0xae, 0x6d, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x13, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x13, 0xae, 0x6f, 0xff, 0x10, 0xab, 0x6e, 0xff, 0x10, 0xab, 0x6e, 0xff, 0x10, 0xaa, 0x6f, 0xff, 0x11, 0xaa, 0x71, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x10, 0xa7, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x11, 0xa7, 0x7a, 0xff, 0x11, 0xa6, 0x7a, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7b, 0xff, 0x10, 0xa5, 0x7b, 0xff, 0x10, 0xa5, 0x7b, 0xff, 0x10, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0f, 0xa5, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa9, 0x77, 0xff, 0x10, 0xa9, 0x77, 0xff, 0x11, 0xaa, 0x78, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xab, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xab, 0x76, 0xff, 0x10, 0xab, 0x77, 0xff, 0x0f, 0xab, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x14, 0xab, 0x7c, 0xff, 0x15, 0xab, 0x7e, 0xff, 0x15, 0xac, 0x80, 0xff, 0x17, 0xac, 0x82, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xab, 0x84, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x18, 0xac, 0x87, 0xff, 0x19, 0xad, 0x89, 0xff, 0x1a, 0xad, 0x8a, 0xff, 0x19, 0xad, 0x89, 0xff, 0x18, 0xac, 0x88, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xad, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x82, 0xff, 0x15, 0xab, 0x80, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x14, 0xa9, 0x7e, 0xff, 0x12, 0xaa, 0x7d, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x0e, 0xa9, 0x75, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x0c, 0xa8, 0x6b, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x0c, 0xa7, 0x6b, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x0a, 0xa8, 0x6d, 0xff, 0x08, 0xa6, 0x6d, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x08, 0xa0, 0x6b, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x08, 0x99, 0x66, 0xff, 0x0c, 0x9b, 0x6a, 0xff, 0x13, 0x9f, 0x6f, 0xff, 0x11, 0x9c, 0x6c, 0xff, 0x13, 0x9c, 0x6c, 0xff, 0x14, 0x9e, 0x6a, 0xff, 0x11, 0x9b, 0x6c, 0xff, 0x07, 0x89, 0x5e, 0xff, 0x01, 0x6c, 0x43, 0xff, 0x0e, 0x84, 0x5a, 0xff, 0x0c, 0x82, 0x59, 0xff, 0x0f, 0x77, 0x54, 0xff, 0x17, 0x6e, 0x50, 0xff, 0x0e, 0x79, 0x54, 0xff, 0x13, 0x91, 0x65, 0xff, 0x07, 0x8c, 0x5c, 0xff, 0x02, 0x8b, 0x5a, 0xff, 0x0a, 0x95, 0x63, 0xff, 0x15, 0x9f, 0x6d, 0xff, 0x15, 0x9f, 0x6b, 0xff, 0x12, 0xa3, 0x6c, 0xff, 0x0d, 0x9c, 0x69, 0xff, 0x0f, 0x99, 0x69, 0xff, 0x0f, 0x94, 0x64, 0xff, 0x06, 0x83, 0x52, 0xff, 0x01, 0x7a, 0x49, 0xff, 0x02, 0x7d, 0x4b, 0xff, 0x03, 0x8e, 0x5a, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0x9f, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0c, 0x9f, 0x5b, 0xff, 0x0b, 0x9f, 0x5a, 0xff, 0x0d, 0x9f, 0x59, 0xff, 0x0e, 0xa0, 0x58, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x0f, 0x9f, 0x57, 0xff, 0x0e, 0x9d, 0x55, 0xff, 0x0d, 0x9b, 0x54, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x09, 0x97, 0x50, 0xff, 0x08, 0x96, 0x4f, 0xff, 0x09, 0x95, 0x4e, 0xff, 0x09, 0x95, 0x4e, 0xff, 0x0b, 0x95, 0x4e, 0xff, 0x0b, 0x95, 0x4e, 0xff, 0x0b, 0x93, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0c, 0x91, 0x4b, 0xff, 0x0b, 0x8e, 0x4a, 0xff, 0x09, 0x8b, 0x48, 0xff, 0x0a, 0x89, 0x46, 0xff, 0x0a, 0x86, 0x46, 0xff, 0x09, 0x82, 0x43, 0xff, 0x08, 0x80, 0x43, 0xff, 0x09, 0x7e, 0x41, 0xff, 0x0b, 0x7e, 0x41, 0xff, 0x0a, 0x7c, 0x3f, 0xff, 0x0a, 0x7d, 0x3d, 0xff, 0x13, 0x86, 0x40, 0xff, 0x03, 0x75, 0x29, 0xff, 0x0f, 0x85, 0x30, 0xff, 0x05, 0x7c, 0x22, 0xff, 0x05, 0x77, 0x1d, 0xff, 0x05, 0x73, 0x1c, 0xff, 0x05, 0x5d, 0x1e, 0xff, 0x12, 0x5a, 0x2f, 0xff, 0x0e, 0x46, 0x25, 0xff, 0x02, 0x36, 0x11, 0xff, 0x08, 0x3d, 0x18, 0xff, 0x06, 0x42, 0x18, 0xff, 0x03, 0x45, 0x0f, 0xff, 0x06, 0x4a, 0x14, 0xff, 0x01, 0x3a, 0x10, 0xff, 0x04, 0x3b, 0x13, 0xff, 0x03, 0x3e, 0x15, 0xff, 0x02, 0x3d, 0x15, 0xff, 0x00, 0x40, 0x0f, 0xff, 0x01, 0x44, 0x0d, 0xff, 0x74, 0x95, 0x79, 0xff, + 0x04, 0x51, 0x2c, 0xff, 0x0d, 0x68, 0x3b, 0xff, 0x0d, 0x86, 0x4b, 0xff, 0x08, 0x8d, 0x4f, 0xff, 0x11, 0x86, 0x58, 0xff, 0x11, 0x7a, 0x65, 0xff, 0x0f, 0x74, 0x6c, 0xff, 0x0e, 0x72, 0x6a, 0xff, 0x10, 0x7b, 0x64, 0xff, 0x0f, 0x8a, 0x5d, 0xff, 0x09, 0x93, 0x58, 0xff, 0x02, 0x99, 0x56, 0xff, 0x05, 0x9e, 0x58, 0xff, 0x0c, 0x9d, 0x5b, 0xff, 0x10, 0x97, 0x58, 0xff, 0x05, 0x82, 0x49, 0xff, 0x07, 0x8a, 0x52, 0xff, 0x11, 0x9e, 0x66, 0xff, 0x0c, 0x9b, 0x64, 0xff, 0x0f, 0x9e, 0x68, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x0b, 0x9e, 0x69, 0xff, 0x0a, 0x9f, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa6, 0x6c, 0xff, 0x0b, 0xa8, 0x6c, 0xff, 0x0e, 0xab, 0x6e, 0xff, 0x0f, 0xac, 0x6d, 0xff, 0x10, 0xac, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x12, 0xac, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x11, 0xac, 0x6e, 0xff, 0x12, 0xac, 0x70, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xab, 0x70, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x10, 0xaa, 0x71, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x0f, 0xa8, 0x72, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x10, 0xa7, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7d, 0xff, 0x13, 0xa1, 0x7d, 0xff, 0x12, 0xa2, 0x7c, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x0f, 0xa3, 0x79, 0xff, 0x0e, 0xa4, 0x79, 0xff, 0x10, 0xa7, 0x77, 0xff, 0x10, 0xa6, 0x77, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x11, 0xa7, 0x78, 0xff, 0x11, 0xa7, 0x79, 0xff, 0x10, 0xa6, 0x79, 0xff, 0x10, 0xa5, 0x79, 0xff, 0x0f, 0xa5, 0x79, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x11, 0xaa, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x76, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x12, 0xab, 0x7b, 0xff, 0x14, 0xab, 0x7d, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x15, 0xac, 0x7f, 0xff, 0x16, 0xac, 0x81, 0xff, 0x16, 0xac, 0x82, 0xff, 0x16, 0xac, 0x84, 0xff, 0x16, 0xac, 0x84, 0xff, 0x15, 0xaa, 0x83, 0xff, 0x15, 0xa9, 0x83, 0xff, 0x16, 0xaa, 0x85, 0xff, 0x18, 0xac, 0x87, 0xff, 0x19, 0xad, 0x89, 0xff, 0x19, 0xad, 0x89, 0xff, 0x18, 0xac, 0x87, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x83, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x13, 0xab, 0x7e, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x10, 0xab, 0x7a, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x07, 0xa3, 0x66, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x0a, 0xa6, 0x69, 0xff, 0x09, 0xa5, 0x68, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x0a, 0xa6, 0x6c, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x07, 0xa2, 0x6e, 0xff, 0x07, 0xa2, 0x6e, 0xff, 0x08, 0xa1, 0x6d, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x0a, 0x91, 0x60, 0xff, 0x03, 0x7c, 0x4f, 0xff, 0x03, 0x7a, 0x4e, 0xff, 0x12, 0x94, 0x66, 0xff, 0x0f, 0x8d, 0x61, 0xff, 0x05, 0x74, 0x4c, 0xff, 0x06, 0x66, 0x44, 0xff, 0x03, 0x6c, 0x47, 0xff, 0x06, 0x85, 0x56, 0xff, 0x05, 0x94, 0x5d, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x10, 0xa2, 0x6f, 0xff, 0x12, 0xa2, 0x71, 0xff, 0x0f, 0xa2, 0x6f, 0xff, 0x08, 0xa5, 0x6d, 0xff, 0x08, 0xa3, 0x6e, 0xff, 0x0b, 0xa3, 0x70, 0xff, 0x0f, 0xa2, 0x70, 0xff, 0x0c, 0x9b, 0x67, 0xff, 0x09, 0x92, 0x5f, 0xff, 0x0a, 0x94, 0x60, 0xff, 0x0b, 0x9d, 0x69, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0x9f, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0b, 0x9f, 0x5b, 0xff, 0x0b, 0x9e, 0x59, 0xff, 0x0c, 0x9d, 0x58, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0d, 0x9c, 0x54, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x09, 0x97, 0x50, 0xff, 0x07, 0x96, 0x4f, 0xff, 0x09, 0x95, 0x4f, 0xff, 0x09, 0x95, 0x4f, 0xff, 0x0b, 0x95, 0x4f, 0xff, 0x0b, 0x95, 0x4e, 0xff, 0x0b, 0x93, 0x4d, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x0b, 0x91, 0x4b, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x09, 0x8a, 0x48, 0xff, 0x0a, 0x89, 0x46, 0xff, 0x0a, 0x86, 0x46, 0xff, 0x08, 0x82, 0x44, 0xff, 0x07, 0x7f, 0x42, 0xff, 0x08, 0x7e, 0x40, 0xff, 0x09, 0x7c, 0x41, 0xff, 0x0a, 0x7b, 0x3f, 0xff, 0x0b, 0x7b, 0x3d, 0xff, 0x0c, 0x7c, 0x38, 0xff, 0x01, 0x6c, 0x23, 0xff, 0x14, 0x82, 0x30, 0xff, 0x0d, 0x7c, 0x23, 0xff, 0x00, 0x65, 0x08, 0xff, 0x01, 0x62, 0x0b, 0xff, 0x01, 0x54, 0x13, 0xff, 0x06, 0x49, 0x1b, 0xff, 0x12, 0x49, 0x23, 0xff, 0x04, 0x37, 0x0f, 0xff, 0x05, 0x38, 0x11, 0xff, 0x07, 0x40, 0x18, 0xff, 0x02, 0x44, 0x0e, 0xff, 0x06, 0x48, 0x14, 0xff, 0x02, 0x39, 0x12, 0xff, 0x04, 0x39, 0x14, 0xff, 0x05, 0x3f, 0x16, 0xff, 0x01, 0x3d, 0x13, 0xff, 0x02, 0x47, 0x12, 0xff, 0x04, 0x4e, 0x13, 0xff, 0x6f, 0x98, 0x76, 0xff, + 0x02, 0x4d, 0x29, 0xff, 0x10, 0x7c, 0x4e, 0xff, 0x08, 0x86, 0x4f, 0xff, 0x11, 0x85, 0x59, 0xff, 0x12, 0x71, 0x66, 0xff, 0x06, 0x4f, 0x75, 0xff, 0x07, 0x44, 0x85, 0xff, 0x0a, 0x47, 0x8b, 0xff, 0x0b, 0x55, 0x83, 0xff, 0x0a, 0x6b, 0x74, 0xff, 0x0b, 0x82, 0x68, 0xff, 0x0a, 0x95, 0x5b, 0xff, 0x07, 0x98, 0x52, 0xff, 0x0b, 0x98, 0x53, 0xff, 0x04, 0x83, 0x45, 0xff, 0x0a, 0x8c, 0x56, 0xff, 0x13, 0x9d, 0x67, 0xff, 0x0c, 0x9b, 0x65, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x0c, 0x9c, 0x68, 0xff, 0x08, 0x9e, 0x69, 0xff, 0x07, 0x9e, 0x69, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x0a, 0xa9, 0x6e, 0xff, 0x0d, 0xab, 0x6e, 0xff, 0x0f, 0xad, 0x6f, 0xff, 0x10, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x11, 0xad, 0x6e, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x11, 0xac, 0x6f, 0xff, 0x10, 0xab, 0x6f, 0xff, 0x11, 0xac, 0x72, 0xff, 0x12, 0xad, 0x74, 0xff, 0x13, 0xae, 0x74, 0xff, 0x14, 0xaf, 0x75, 0xff, 0x14, 0xaf, 0x76, 0xff, 0x13, 0xac, 0x75, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x11, 0xa1, 0x7b, 0xff, 0x12, 0xa1, 0x7d, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x14, 0xa2, 0x7e, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x0e, 0xa3, 0x78, 0xff, 0x0c, 0xa5, 0x78, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x7a, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0e, 0xaa, 0x75, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x76, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x13, 0xac, 0x7e, 0xff, 0x13, 0xad, 0x7f, 0xff, 0x13, 0xac, 0x7f, 0xff, 0x13, 0xac, 0x80, 0xff, 0x14, 0xac, 0x82, 0xff, 0x13, 0xaa, 0x82, 0xff, 0x15, 0xaa, 0x82, 0xff, 0x15, 0xaa, 0x83, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x16, 0xaa, 0x85, 0xff, 0x18, 0xac, 0x88, 0xff, 0x19, 0xad, 0x88, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xad, 0x84, 0xff, 0x17, 0xad, 0x83, 0xff, 0x15, 0xaa, 0x82, 0xff, 0x17, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x83, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x13, 0xa9, 0x7d, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x0e, 0xab, 0x7a, 0xff, 0x0d, 0xa9, 0x77, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa5, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x09, 0xa4, 0x6f, 0xff, 0x08, 0xa5, 0x70, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x04, 0xa4, 0x6e, 0xff, 0x01, 0xa3, 0x6c, 0xff, 0x01, 0xa3, 0x6b, 0xff, 0x07, 0xa2, 0x68, 0xff, 0x05, 0x8a, 0x57, 0xff, 0x07, 0x85, 0x54, 0xff, 0x0d, 0x98, 0x66, 0xff, 0x0d, 0x9d, 0x69, 0xff, 0x05, 0x83, 0x52, 0xff, 0x00, 0x72, 0x44, 0xff, 0x04, 0x75, 0x4d, 0xff, 0x0a, 0x81, 0x59, 0xff, 0x0e, 0x97, 0x64, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x07, 0xa7, 0x6c, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0d, 0xa2, 0x73, 0xff, 0x07, 0xa3, 0x72, 0xff, 0x02, 0xa5, 0x6e, 0xff, 0x06, 0xa3, 0x70, 0xff, 0x05, 0xa5, 0x71, 0xff, 0x06, 0xa5, 0x70, 0xff, 0x07, 0xa4, 0x6e, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0c, 0xa3, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9d, 0x5a, 0xff, 0x09, 0x9c, 0x57, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0e, 0x9e, 0x56, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0c, 0x9b, 0x53, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x09, 0x97, 0x50, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x09, 0x95, 0x51, 0xff, 0x09, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0b, 0x93, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0b, 0x90, 0x4d, 0xff, 0x09, 0x8c, 0x49, 0xff, 0x09, 0x8a, 0x48, 0xff, 0x09, 0x88, 0x46, 0xff, 0x0a, 0x86, 0x45, 0xff, 0x09, 0x81, 0x43, 0xff, 0x09, 0x7f, 0x42, 0xff, 0x09, 0x7e, 0x41, 0xff, 0x09, 0x7b, 0x43, 0xff, 0x09, 0x79, 0x40, 0xff, 0x0a, 0x79, 0x3d, 0xff, 0x0b, 0x76, 0x36, 0xff, 0x02, 0x64, 0x21, 0xff, 0x0c, 0x6f, 0x25, 0xff, 0x16, 0x78, 0x27, 0xff, 0x02, 0x61, 0x08, 0xff, 0x01, 0x50, 0x01, 0xff, 0x03, 0x4b, 0x0c, 0xff, 0x01, 0x40, 0x0b, 0xff, 0x02, 0x43, 0x0b, 0xff, 0x02, 0x44, 0x09, 0xff, 0x01, 0x3b, 0x08, 0xff, 0x02, 0x3e, 0x12, 0xff, 0x00, 0x3f, 0x0d, 0xff, 0x02, 0x43, 0x12, 0xff, 0x02, 0x37, 0x13, 0xff, 0x07, 0x3b, 0x17, 0xff, 0x04, 0x40, 0x14, 0xff, 0x02, 0x3f, 0x12, 0xff, 0x08, 0x51, 0x19, 0xff, 0x05, 0x52, 0x13, 0xff, 0x61, 0x90, 0x69, 0xff, + 0x0c, 0x68, 0x37, 0xff, 0x0e, 0x82, 0x52, 0xff, 0x09, 0x7b, 0x5c, 0xff, 0x0c, 0x5e, 0x68, 0xff, 0x06, 0x43, 0x77, 0xff, 0x07, 0x34, 0x90, 0xff, 0x0d, 0x2e, 0x9e, 0xff, 0x17, 0x39, 0xaf, 0xff, 0x19, 0x46, 0xb2, 0xff, 0x10, 0x51, 0x9d, 0xff, 0x0d, 0x62, 0x88, 0xff, 0x0f, 0x7b, 0x6e, 0xff, 0x11, 0x89, 0x5f, 0xff, 0x04, 0x80, 0x46, 0xff, 0x08, 0x89, 0x4f, 0xff, 0x15, 0x9d, 0x6a, 0xff, 0x10, 0x9c, 0x67, 0xff, 0x0a, 0x9c, 0x66, 0xff, 0x0a, 0x9c, 0x66, 0xff, 0x0b, 0x9d, 0x68, 0xff, 0x0a, 0x9d, 0x69, 0xff, 0x08, 0x9e, 0x69, 0xff, 0x07, 0x9e, 0x69, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa7, 0x6d, 0xff, 0x08, 0xa7, 0x6d, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x09, 0xab, 0x70, 0xff, 0x0b, 0xac, 0x71, 0xff, 0x0e, 0xad, 0x6f, 0xff, 0x10, 0xad, 0x6d, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x12, 0xae, 0x6e, 0xff, 0x13, 0xaf, 0x70, 0xff, 0x14, 0xaf, 0x75, 0xff, 0x16, 0xb2, 0x77, 0xff, 0x17, 0xb3, 0x78, 0xff, 0x18, 0xb4, 0x79, 0xff, 0x1a, 0xb5, 0x7c, 0xff, 0x18, 0xb2, 0x7b, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x12, 0xa1, 0x7d, 0xff, 0x14, 0xa0, 0x7e, 0xff, 0x15, 0xa0, 0x7f, 0xff, 0x14, 0xa1, 0x7e, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x0d, 0xa3, 0x78, 0xff, 0x0b, 0xa5, 0x77, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x12, 0xa9, 0x7b, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa8, 0x74, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x76, 0xff, 0x10, 0xab, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xaa, 0x7a, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xac, 0x7c, 0xff, 0x12, 0xac, 0x7e, 0xff, 0x13, 0xab, 0x7f, 0xff, 0x14, 0xab, 0x82, 0xff, 0x14, 0xab, 0x83, 0xff, 0x14, 0xaa, 0x83, 0xff, 0x16, 0xaa, 0x83, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xaa, 0x85, 0xff, 0x17, 0xab, 0x86, 0xff, 0x17, 0xab, 0x85, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x83, 0xff, 0x15, 0xaa, 0x81, 0xff, 0x14, 0xaa, 0x7e, 0xff, 0x14, 0xaa, 0x7e, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x13, 0xac, 0x7f, 0xff, 0x11, 0xab, 0x7e, 0xff, 0x0f, 0xac, 0x7a, 0xff, 0x0d, 0xaa, 0x77, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x06, 0xa3, 0x69, 0xff, 0x06, 0xa4, 0x68, 0xff, 0x10, 0x9d, 0x67, 0xff, 0x14, 0x9c, 0x69, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x09, 0xa1, 0x69, 0xff, 0x04, 0x89, 0x54, 0xff, 0x09, 0x8c, 0x59, 0xff, 0x10, 0x97, 0x68, 0xff, 0x10, 0x9c, 0x71, 0xff, 0x0e, 0xa1, 0x6e, 0xff, 0x05, 0xa6, 0x6d, 0xff, 0x02, 0xa6, 0x6d, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x08, 0xa4, 0x74, 0xff, 0x09, 0xa4, 0x72, 0xff, 0x10, 0xa4, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x06, 0xa4, 0x6f, 0xff, 0x05, 0xa5, 0x6d, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa5, 0x67, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa1, 0x61, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0x9f, 0x5a, 0xff, 0x09, 0x9c, 0x58, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0d, 0x9d, 0x55, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0c, 0x9a, 0x53, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x09, 0x97, 0x50, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x09, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0b, 0x90, 0x4c, 0xff, 0x09, 0x8c, 0x49, 0xff, 0x09, 0x8a, 0x47, 0xff, 0x09, 0x87, 0x46, 0xff, 0x09, 0x83, 0x45, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x08, 0x7e, 0x41, 0xff, 0x08, 0x7d, 0x41, 0xff, 0x06, 0x79, 0x42, 0xff, 0x07, 0x78, 0x40, 0xff, 0x0a, 0x79, 0x3e, 0xff, 0x11, 0x79, 0x3d, 0xff, 0x0b, 0x6a, 0x2e, 0xff, 0x02, 0x54, 0x14, 0xff, 0x15, 0x6a, 0x23, 0xff, 0x15, 0x6c, 0x1a, 0xff, 0x06, 0x4d, 0x06, 0xff, 0x01, 0x3c, 0x02, 0xff, 0x06, 0x4a, 0x0b, 0xff, 0x0c, 0x66, 0x19, 0xff, 0x08, 0x67, 0x14, 0xff, 0x07, 0x5d, 0x17, 0xff, 0x05, 0x50, 0x17, 0xff, 0x01, 0x42, 0x13, 0xff, 0x00, 0x3b, 0x0d, 0xff, 0x00, 0x36, 0x0f, 0xff, 0x02, 0x3a, 0x13, 0xff, 0x04, 0x42, 0x14, 0xff, 0x09, 0x49, 0x19, 0xff, 0x08, 0x54, 0x19, 0xff, 0x01, 0x4c, 0x0b, 0xff, 0x5e, 0x90, 0x66, 0xff, + 0x17, 0x7e, 0x4e, 0xff, 0x10, 0x79, 0x5a, 0xff, 0x07, 0x5e, 0x68, 0xff, 0x08, 0x39, 0x80, 0xff, 0x0a, 0x2b, 0x95, 0xff, 0x28, 0x45, 0xbe, 0xff, 0x37, 0x4c, 0xcc, 0xff, 0x1a, 0x33, 0xb8, 0xff, 0x29, 0x4c, 0xd0, 0xff, 0x33, 0x62, 0xd8, 0xff, 0x2f, 0x67, 0xc2, 0xff, 0x2c, 0x71, 0x9d, 0xff, 0x12, 0x67, 0x6c, 0xff, 0x12, 0x7b, 0x5f, 0xff, 0x1a, 0x98, 0x6c, 0xff, 0x0e, 0x9b, 0x67, 0xff, 0x0a, 0x9b, 0x66, 0xff, 0x08, 0x9d, 0x68, 0xff, 0x08, 0x9d, 0x67, 0xff, 0x0b, 0x9d, 0x68, 0xff, 0x0a, 0x9e, 0x69, 0xff, 0x09, 0x9e, 0x69, 0xff, 0x08, 0x9e, 0x69, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa9, 0x6d, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x0a, 0xad, 0x72, 0xff, 0x0d, 0xae, 0x70, 0xff, 0x0f, 0xae, 0x6e, 0xff, 0x10, 0xae, 0x6d, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x14, 0xb0, 0x70, 0xff, 0x17, 0xb3, 0x74, 0xff, 0x17, 0xb2, 0x77, 0xff, 0x19, 0xb5, 0x79, 0xff, 0x1a, 0xb6, 0x7a, 0xff, 0x1a, 0xb6, 0x7a, 0xff, 0x1c, 0xb7, 0x7c, 0xff, 0x19, 0xb4, 0x7c, 0xff, 0x11, 0xab, 0x74, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0f, 0xa5, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x11, 0xa1, 0x7d, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x15, 0xa0, 0x7f, 0xff, 0x15, 0xa0, 0x7f, 0xff, 0x14, 0xa1, 0x7e, 0xff, 0x11, 0xa2, 0x7d, 0xff, 0x0d, 0xa4, 0x78, 0xff, 0x0b, 0xa5, 0x76, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x10, 0xa7, 0x79, 0xff, 0x0f, 0xa7, 0x77, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0b, 0xa6, 0x72, 0xff, 0x0d, 0xa8, 0x74, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0f, 0xaa, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x74, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xab, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xac, 0x7a, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x14, 0xab, 0x82, 0xff, 0x14, 0xab, 0x84, 0xff, 0x14, 0xab, 0x83, 0xff, 0x16, 0xac, 0x82, 0xff, 0x16, 0xab, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xac, 0x83, 0xff, 0x16, 0xac, 0x82, 0xff, 0x16, 0xac, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x18, 0xac, 0x85, 0xff, 0x15, 0xab, 0x82, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x10, 0xaa, 0x7d, 0xff, 0x0e, 0xab, 0x79, 0xff, 0x0c, 0xa9, 0x76, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa3, 0x68, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0b, 0xa3, 0x71, 0xff, 0x0a, 0xa3, 0x70, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x15, 0xa9, 0x73, 0xff, 0x12, 0xa5, 0x6c, 0xff, 0x13, 0xa6, 0x6c, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x12, 0xa4, 0x6e, 0xff, 0x11, 0xa1, 0x6c, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0d, 0xa1, 0x69, 0xff, 0x13, 0xa4, 0x6e, 0xff, 0x0f, 0xa2, 0x6f, 0xff, 0x09, 0xa3, 0x72, 0xff, 0x09, 0xa2, 0x71, 0xff, 0x03, 0xa5, 0x70, 0xff, 0x04, 0xa6, 0x72, 0xff, 0x0e, 0xa4, 0x71, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x09, 0xa5, 0x73, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x14, 0xa4, 0x6f, 0xff, 0x0f, 0xa3, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0x9f, 0x5b, 0xff, 0x0a, 0x9d, 0x58, 0xff, 0x0b, 0x9d, 0x57, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x09, 0x97, 0x50, 0xff, 0x08, 0x96, 0x4f, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0a, 0x93, 0x4f, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0a, 0x8f, 0x4b, 0xff, 0x07, 0x8a, 0x47, 0xff, 0x08, 0x88, 0x46, 0xff, 0x08, 0x86, 0x45, 0xff, 0x09, 0x82, 0x44, 0xff, 0x07, 0x7f, 0x42, 0xff, 0x08, 0x7d, 0x41, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x08, 0x79, 0x42, 0xff, 0x07, 0x79, 0x40, 0xff, 0x08, 0x77, 0x3c, 0xff, 0x0f, 0x75, 0x3b, 0xff, 0x0f, 0x6d, 0x36, 0xff, 0x01, 0x4f, 0x16, 0xff, 0x04, 0x51, 0x12, 0xff, 0x1d, 0x6e, 0x24, 0xff, 0x0d, 0x52, 0x11, 0xff, 0x02, 0x3d, 0x03, 0xff, 0x18, 0x6e, 0x21, 0xff, 0x0f, 0x76, 0x1b, 0xff, 0x03, 0x6e, 0x10, 0xff, 0x06, 0x6e, 0x19, 0xff, 0x13, 0x75, 0x2a, 0xff, 0x12, 0x6d, 0x30, 0xff, 0x09, 0x59, 0x22, 0xff, 0x01, 0x3e, 0x0f, 0xff, 0x01, 0x3e, 0x10, 0xff, 0x07, 0x49, 0x17, 0xff, 0x07, 0x48, 0x17, 0xff, 0x04, 0x4d, 0x12, 0xff, 0x00, 0x49, 0x0a, 0xff, 0x69, 0x92, 0x6e, 0xff, + 0x0f, 0x79, 0x57, 0xff, 0x0a, 0x5d, 0x60, 0xff, 0x06, 0x40, 0x73, 0xff, 0x0f, 0x2d, 0x97, 0xff, 0x11, 0x25, 0xa4, 0xff, 0x34, 0x4b, 0xcb, 0xff, 0x45, 0x59, 0xdc, 0xff, 0x20, 0x38, 0xc0, 0xff, 0x30, 0x55, 0xd8, 0xff, 0x41, 0x6c, 0xe7, 0xff, 0x4a, 0x73, 0xdf, 0xff, 0x5c, 0x87, 0xd3, 0xff, 0x44, 0x7e, 0xa7, 0xff, 0x27, 0x7d, 0x80, 0xff, 0x1b, 0x8f, 0x75, 0xff, 0x0b, 0x9c, 0x68, 0xff, 0x0a, 0x9e, 0x69, 0xff, 0x06, 0x9c, 0x68, 0xff, 0x07, 0x9e, 0x69, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x09, 0x9e, 0x68, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0c, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x06, 0xa9, 0x6d, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x07, 0xa9, 0x71, 0xff, 0x07, 0xaa, 0x71, 0xff, 0x09, 0xad, 0x72, 0xff, 0x0e, 0xad, 0x71, 0xff, 0x0f, 0xae, 0x6f, 0xff, 0x10, 0xae, 0x6d, 0xff, 0x10, 0xae, 0x6c, 0xff, 0x10, 0xae, 0x6c, 0xff, 0x10, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6c, 0xff, 0x14, 0xb0, 0x70, 0xff, 0x17, 0xb3, 0x73, 0xff, 0x17, 0xb3, 0x77, 0xff, 0x19, 0xb5, 0x79, 0xff, 0x19, 0xb5, 0x79, 0xff, 0x1a, 0xb6, 0x7a, 0xff, 0x19, 0xb5, 0x79, 0xff, 0x17, 0xb2, 0x79, 0xff, 0x12, 0xac, 0x75, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x12, 0xa1, 0x7e, 0xff, 0x13, 0xa1, 0x7e, 0xff, 0x15, 0xa0, 0x7f, 0xff, 0x15, 0xa0, 0x7f, 0xff, 0x12, 0xa1, 0x7f, 0xff, 0x11, 0xa3, 0x7d, 0xff, 0x0d, 0xa4, 0x79, 0xff, 0x0a, 0xa5, 0x76, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0e, 0xa5, 0x78, 0xff, 0x0e, 0xa6, 0x77, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0e, 0xa9, 0x76, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x10, 0xab, 0x79, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x76, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x74, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xac, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x14, 0xab, 0x82, 0xff, 0x14, 0xab, 0x85, 0xff, 0x15, 0xab, 0x84, 0xff, 0x16, 0xac, 0x82, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x18, 0xad, 0x84, 0xff, 0x17, 0xad, 0x84, 0xff, 0x17, 0xad, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x18, 0xac, 0x86, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x15, 0xab, 0x81, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x11, 0xab, 0x7e, 0xff, 0x0e, 0xaa, 0x7c, 0xff, 0x0e, 0xaa, 0x79, 0xff, 0x0c, 0xa9, 0x76, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0d, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x72, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x15, 0xaa, 0x72, 0xff, 0x11, 0xa6, 0x6b, 0xff, 0x11, 0xa6, 0x6a, 0xff, 0x0d, 0xa2, 0x66, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0f, 0xa3, 0x6d, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0d, 0xa3, 0x6f, 0xff, 0x06, 0xa6, 0x70, 0xff, 0x0d, 0xa3, 0x72, 0xff, 0x08, 0xa4, 0x73, 0xff, 0x07, 0xa4, 0x72, 0xff, 0x10, 0xa4, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x08, 0xa5, 0x70, 0xff, 0x0e, 0xa3, 0x70, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x06, 0xa3, 0x6a, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa1, 0x63, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0x9f, 0x5d, 0xff, 0x0c, 0xa0, 0x5c, 0xff, 0x0a, 0x9d, 0x59, 0xff, 0x0b, 0x9d, 0x57, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0c, 0x9e, 0x56, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0b, 0x99, 0x52, 0xff, 0x09, 0x97, 0x50, 0xff, 0x08, 0x96, 0x4f, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0a, 0x93, 0x4f, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0a, 0x8f, 0x4b, 0xff, 0x07, 0x8a, 0x47, 0xff, 0x07, 0x88, 0x46, 0xff, 0x08, 0x85, 0x45, 0xff, 0x08, 0x81, 0x43, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x08, 0x7d, 0x41, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x08, 0x79, 0x40, 0xff, 0x09, 0x79, 0x3f, 0xff, 0x0a, 0x77, 0x3c, 0xff, 0x0f, 0x75, 0x3c, 0xff, 0x0f, 0x6d, 0x3a, 0xff, 0x0a, 0x5f, 0x2b, 0xff, 0x0d, 0x5f, 0x26, 0xff, 0x07, 0x56, 0x12, 0xff, 0x09, 0x50, 0x0e, 0xff, 0x03, 0x48, 0x05, 0xff, 0x19, 0x78, 0x22, 0xff, 0x02, 0x6b, 0x0f, 0xff, 0x01, 0x69, 0x0f, 0xff, 0x0f, 0x7d, 0x24, 0xff, 0x14, 0x86, 0x2f, 0xff, 0x13, 0x8c, 0x3c, 0xff, 0x20, 0x8c, 0x47, 0xff, 0x10, 0x61, 0x29, 0xff, 0x05, 0x4e, 0x19, 0xff, 0x03, 0x4a, 0x13, 0xff, 0x05, 0x4a, 0x16, 0xff, 0x01, 0x48, 0x0e, 0xff, 0x02, 0x4a, 0x0f, 0xff, 0x6c, 0x8c, 0x73, 0xff, + 0x07, 0x62, 0x61, 0xff, 0x0e, 0x43, 0x72, 0xff, 0x12, 0x32, 0x87, 0xff, 0x12, 0x29, 0x9e, 0xff, 0x15, 0x27, 0xa8, 0xff, 0x1a, 0x2f, 0xb1, 0xff, 0x1f, 0x31, 0xb8, 0xff, 0x25, 0x3e, 0xc9, 0xff, 0x31, 0x5a, 0xd8, 0xff, 0x49, 0x78, 0xe8, 0xff, 0x57, 0x7c, 0xe1, 0xff, 0x84, 0x9d, 0xf0, 0xff, 0x87, 0xa9, 0xe5, 0xff, 0x53, 0x90, 0xb1, 0xff, 0x24, 0x83, 0x84, 0xff, 0x0f, 0x98, 0x6e, 0xff, 0x09, 0x9c, 0x69, 0xff, 0x06, 0x9f, 0x69, 0xff, 0x06, 0x9e, 0x68, 0xff, 0x0b, 0x9e, 0x69, 0xff, 0x0e, 0x9f, 0x6a, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0a, 0x9e, 0x67, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x06, 0xa7, 0x6e, 0xff, 0x06, 0xa9, 0x6d, 0xff, 0x06, 0xa9, 0x6d, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x07, 0xa9, 0x71, 0xff, 0x08, 0xaa, 0x72, 0xff, 0x08, 0xaa, 0x73, 0xff, 0x07, 0xab, 0x72, 0xff, 0x09, 0xad, 0x73, 0xff, 0x0d, 0xad, 0x71, 0xff, 0x0d, 0xad, 0x6f, 0xff, 0x10, 0xae, 0x6e, 0xff, 0x11, 0xaf, 0x6d, 0xff, 0x11, 0xaf, 0x6d, 0xff, 0x12, 0xaf, 0x6e, 0xff, 0x11, 0xae, 0x6d, 0xff, 0x10, 0xad, 0x6d, 0xff, 0x10, 0xad, 0x6c, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x10, 0xac, 0x6c, 0xff, 0x10, 0xac, 0x6d, 0xff, 0x11, 0xad, 0x6d, 0xff, 0x11, 0xae, 0x6c, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x11, 0xae, 0x6d, 0xff, 0x12, 0xaf, 0x6e, 0xff, 0x11, 0xae, 0x6d, 0xff, 0x11, 0xad, 0x6c, 0xff, 0x12, 0xae, 0x6d, 0xff, 0x13, 0xb0, 0x70, 0xff, 0x16, 0xb3, 0x77, 0xff, 0x18, 0xb4, 0x78, 0xff, 0x19, 0xb4, 0x79, 0xff, 0x1b, 0xb6, 0x7a, 0xff, 0x18, 0xb4, 0x79, 0xff, 0x13, 0xaf, 0x76, 0xff, 0x13, 0xad, 0x76, 0xff, 0x10, 0xa9, 0x73, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa4, 0x78, 0xff, 0x11, 0xa4, 0x79, 0xff, 0x11, 0xa3, 0x7b, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x11, 0xa1, 0x7e, 0xff, 0x12, 0xa1, 0x7e, 0xff, 0x15, 0xa0, 0x7e, 0xff, 0x15, 0x9f, 0x7f, 0xff, 0x12, 0xa0, 0x7f, 0xff, 0x11, 0xa2, 0x7d, 0xff, 0x0e, 0xa5, 0x79, 0xff, 0x0a, 0xa5, 0x76, 0xff, 0x0c, 0xa5, 0x76, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x10, 0xa7, 0x7a, 0xff, 0x0f, 0xa7, 0x7a, 0xff, 0x0f, 0xa6, 0x79, 0xff, 0x0e, 0xa5, 0x79, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0c, 0xa8, 0x74, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xab, 0x79, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x10, 0xaa, 0x7b, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x12, 0xac, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x11, 0xab, 0x78, 0xff, 0x11, 0xab, 0x78, 0xff, 0x11, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x10, 0xac, 0x77, 0xff, 0x0f, 0xac, 0x77, 0xff, 0x0e, 0xab, 0x76, 0xff, 0x0e, 0xab, 0x75, 0xff, 0x0e, 0xab, 0x75, 0xff, 0x0e, 0xab, 0x75, 0xff, 0x0e, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xac, 0x78, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x13, 0xab, 0x81, 0xff, 0x14, 0xab, 0x85, 0xff, 0x15, 0xab, 0x84, 0xff, 0x16, 0xac, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x18, 0xac, 0x86, 0xff, 0x18, 0xac, 0x85, 0xff, 0x18, 0xad, 0x85, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x83, 0xff, 0x15, 0xab, 0x80, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x12, 0xac, 0x7f, 0xff, 0x0f, 0xaa, 0x7d, 0xff, 0x0e, 0xaa, 0x79, 0xff, 0x0c, 0xa9, 0x76, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x0e, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x09, 0xa4, 0x6f, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0f, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x12, 0xac, 0x74, 0xff, 0x0e, 0xa9, 0x6e, 0xff, 0x0a, 0xa6, 0x68, 0xff, 0x0c, 0xa8, 0x69, 0xff, 0x0f, 0xaa, 0x6b, 0xff, 0x10, 0xa6, 0x6c, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x70, 0xff, 0x10, 0xa4, 0x6e, 0xff, 0x13, 0xa5, 0x6f, 0xff, 0x0d, 0xa5, 0x6f, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0d, 0xa4, 0x71, 0xff, 0x08, 0xa6, 0x6f, 0xff, 0x10, 0xa3, 0x72, 0xff, 0x0e, 0xa3, 0x75, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x10, 0xa4, 0x6f, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x05, 0xa6, 0x6d, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x04, 0xa3, 0x6b, 0xff, 0x02, 0xa5, 0x6b, 0xff, 0x04, 0xa5, 0x6b, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x06, 0xa4, 0x69, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x08, 0xa3, 0x69, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa1, 0x63, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0d, 0xa0, 0x5c, 0xff, 0x0b, 0x9e, 0x5a, 0xff, 0x0c, 0x9d, 0x58, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0b, 0x9d, 0x55, 0xff, 0x0b, 0x9b, 0x54, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0b, 0x9a, 0x52, 0xff, 0x0a, 0x98, 0x51, 0xff, 0x08, 0x97, 0x4f, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x0a, 0x96, 0x52, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0a, 0x93, 0x4f, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x07, 0x89, 0x46, 0xff, 0x06, 0x87, 0x45, 0xff, 0x08, 0x84, 0x44, 0xff, 0x07, 0x81, 0x43, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x09, 0x7e, 0x42, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x06, 0x7a, 0x3e, 0xff, 0x07, 0x78, 0x3e, 0xff, 0x09, 0x75, 0x3d, 0xff, 0x0f, 0x72, 0x3c, 0xff, 0x0b, 0x66, 0x38, 0xff, 0x25, 0x78, 0x4b, 0xff, 0x27, 0x7a, 0x47, 0xff, 0x03, 0x53, 0x0f, 0xff, 0x04, 0x5b, 0x0b, 0xff, 0x0c, 0x6d, 0x15, 0xff, 0x18, 0x7e, 0x22, 0xff, 0x02, 0x64, 0x0d, 0xff, 0x05, 0x63, 0x14, 0xff, 0x0d, 0x74, 0x20, 0xff, 0x06, 0x7e, 0x21, 0xff, 0x0e, 0x9d, 0x3e, 0xff, 0x0f, 0x89, 0x3b, 0xff, 0x1a, 0x6f, 0x36, 0xff, 0x0b, 0x52, 0x1d, 0xff, 0x03, 0x4a, 0x16, 0xff, 0x02, 0x45, 0x11, 0xff, 0x02, 0x47, 0x10, 0xff, 0x05, 0x48, 0x13, 0xff, 0x69, 0x84, 0x6e, 0xff, + 0x33, 0x61, 0x84, 0xff, 0x40, 0x5e, 0xa1, 0xff, 0x1f, 0x37, 0x96, 0xff, 0x10, 0x29, 0xa3, 0xff, 0x0f, 0x26, 0xac, 0xff, 0x19, 0x2d, 0xb9, 0xff, 0x1c, 0x2f, 0xbb, 0xff, 0x26, 0x42, 0xcc, 0xff, 0x30, 0x5b, 0xdd, 0xff, 0x49, 0x79, 0xeb, 0xff, 0x61, 0x84, 0xe4, 0xff, 0x9e, 0xac, 0xf5, 0xff, 0xa6, 0xb3, 0xee, 0xff, 0x93, 0xb0, 0xe1, 0xff, 0x64, 0x97, 0xbb, 0xff, 0x26, 0x85, 0x85, 0xff, 0x16, 0x99, 0x75, 0xff, 0x06, 0xa3, 0x67, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x0c, 0x9e, 0x6b, 0xff, 0x0d, 0x9d, 0x6a, 0xff, 0x0c, 0x9e, 0x66, 0xff, 0x0d, 0xa0, 0x65, 0xff, 0x0c, 0xa2, 0x67, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x08, 0xa4, 0x6f, 0xff, 0x07, 0xa5, 0x6f, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x05, 0xa7, 0x6d, 0xff, 0x05, 0xa6, 0x6d, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x04, 0xa7, 0x70, 0xff, 0x07, 0xa9, 0x70, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x08, 0xac, 0x72, 0xff, 0x07, 0xac, 0x72, 0xff, 0x06, 0xab, 0x72, 0xff, 0x07, 0xab, 0x73, 0xff, 0x08, 0xab, 0x74, 0xff, 0x08, 0xac, 0x74, 0xff, 0x07, 0xab, 0x72, 0xff, 0x09, 0xad, 0x70, 0xff, 0x0a, 0xad, 0x6f, 0xff, 0x0c, 0xae, 0x6d, 0xff, 0x0f, 0xad, 0x6d, 0xff, 0x13, 0xae, 0x6f, 0xff, 0x12, 0xab, 0x6e, 0xff, 0x0f, 0xac, 0x6f, 0xff, 0x0e, 0xab, 0x70, 0xff, 0x0e, 0xab, 0x6f, 0xff, 0x10, 0xac, 0x71, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x0d, 0xa9, 0x6c, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x10, 0xab, 0x6c, 0xff, 0x0f, 0xac, 0x6c, 0xff, 0x0f, 0xac, 0x6e, 0xff, 0x0f, 0xad, 0x6e, 0xff, 0x0e, 0xad, 0x6e, 0xff, 0x0f, 0xad, 0x6e, 0xff, 0x0f, 0xab, 0x6d, 0xff, 0x10, 0xac, 0x6f, 0xff, 0x11, 0xb1, 0x76, 0xff, 0x15, 0xb2, 0x76, 0xff, 0x19, 0xb1, 0x76, 0xff, 0x19, 0xb2, 0x77, 0xff, 0x15, 0xb2, 0x79, 0xff, 0x11, 0xb1, 0x77, 0xff, 0x12, 0xae, 0x75, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x10, 0xa5, 0x77, 0xff, 0x11, 0xa5, 0x78, 0xff, 0x11, 0xa3, 0x79, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x0f, 0xa2, 0x7c, 0xff, 0x12, 0xa3, 0x7c, 0xff, 0x14, 0xa0, 0x7b, 0xff, 0x15, 0xa1, 0x7d, 0xff, 0x14, 0xa0, 0x7f, 0xff, 0x11, 0xa1, 0x7e, 0xff, 0x0e, 0xa4, 0x7a, 0xff, 0x0b, 0xa5, 0x77, 0xff, 0x0a, 0xa6, 0x77, 0xff, 0x0b, 0xa5, 0x78, 0xff, 0x0d, 0xa6, 0x79, 0xff, 0x0d, 0xa7, 0x7a, 0xff, 0x0d, 0xa6, 0x79, 0xff, 0x0c, 0xa7, 0x78, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0c, 0xa7, 0x75, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0d, 0xa9, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0b, 0xa7, 0x73, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x11, 0xac, 0x78, 0xff, 0x11, 0xab, 0x7c, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x11, 0xad, 0x7c, 0xff, 0x0f, 0xac, 0x7a, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x10, 0xab, 0x79, 0xff, 0x11, 0xab, 0x78, 0xff, 0x12, 0xab, 0x78, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x13, 0xaa, 0x78, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x0e, 0xaa, 0x78, 0xff, 0x0e, 0xab, 0x79, 0xff, 0x0d, 0xac, 0x79, 0xff, 0x0c, 0xac, 0x78, 0xff, 0x0c, 0xac, 0x78, 0xff, 0x0c, 0xac, 0x76, 0xff, 0x0c, 0xab, 0x76, 0xff, 0x0d, 0xac, 0x78, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x0e, 0xab, 0x79, 0xff, 0x0e, 0xac, 0x7a, 0xff, 0x0f, 0xad, 0x7a, 0xff, 0x0e, 0xae, 0x7b, 0xff, 0x0e, 0xad, 0x7a, 0xff, 0x0d, 0xad, 0x79, 0xff, 0x0c, 0xac, 0x78, 0xff, 0x0d, 0xad, 0x79, 0xff, 0x0c, 0xac, 0x78, 0xff, 0x0c, 0xab, 0x77, 0xff, 0x0d, 0xaa, 0x77, 0xff, 0x0e, 0xa9, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x10, 0xaa, 0x77, 0xff, 0x11, 0xab, 0x77, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0f, 0xab, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x11, 0xab, 0x79, 0xff, 0x12, 0xab, 0x7c, 0xff, 0x13, 0xab, 0x81, 0xff, 0x12, 0xab, 0x83, 0xff, 0x15, 0xaa, 0x84, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x19, 0xac, 0x86, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xac, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xac, 0x82, 0xff, 0x13, 0xac, 0x80, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x11, 0xab, 0x7d, 0xff, 0x0d, 0xab, 0x7a, 0xff, 0x0b, 0xa8, 0x75, 0xff, 0x0b, 0xa8, 0x73, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x08, 0xa3, 0x6e, 0xff, 0x07, 0xa5, 0x6f, 0xff, 0x04, 0xa2, 0x6c, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x13, 0xac, 0x76, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x0f, 0xac, 0x70, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x05, 0xa2, 0x62, 0xff, 0x0d, 0xa9, 0x68, 0xff, 0x0d, 0xa9, 0x68, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x0c, 0xa9, 0x6d, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x10, 0xa6, 0x72, 0xff, 0x10, 0xa4, 0x73, 0xff, 0x0e, 0xa3, 0x72, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa6, 0x72, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x08, 0xa1, 0x6c, 0xff, 0x05, 0xa3, 0x6a, 0xff, 0x06, 0xa6, 0x6a, 0xff, 0x05, 0xa4, 0x68, 0xff, 0x06, 0xa5, 0x68, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x08, 0xa5, 0x69, 0xff, 0x07, 0xa4, 0x68, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x07, 0xa3, 0x64, 0xff, 0x07, 0xa3, 0x64, 0xff, 0x08, 0xa5, 0x65, 0xff, 0x0a, 0xa3, 0x64, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x0d, 0xa6, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x09, 0xa2, 0x63, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x60, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0a, 0x9e, 0x5a, 0xff, 0x0a, 0x9e, 0x59, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x0a, 0x9c, 0x55, 0xff, 0x0b, 0x9c, 0x53, 0xff, 0x0b, 0x9c, 0x52, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x09, 0x98, 0x52, 0xff, 0x09, 0x97, 0x52, 0xff, 0x09, 0x97, 0x53, 0xff, 0x08, 0x96, 0x51, 0xff, 0x09, 0x96, 0x51, 0xff, 0x09, 0x95, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0d, 0x94, 0x50, 0xff, 0x0c, 0x93, 0x4f, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x0a, 0x8b, 0x49, 0xff, 0x0a, 0x88, 0x46, 0xff, 0x08, 0x86, 0x45, 0xff, 0x08, 0x84, 0x43, 0xff, 0x08, 0x82, 0x42, 0xff, 0x06, 0x7e, 0x40, 0xff, 0x09, 0x7e, 0x41, 0xff, 0x0a, 0x7b, 0x40, 0xff, 0x06, 0x7d, 0x3c, 0xff, 0x03, 0x76, 0x3f, 0xff, 0x07, 0x70, 0x42, 0xff, 0x0e, 0x68, 0x3e, 0xff, 0x18, 0x65, 0x45, 0xff, 0x32, 0x7d, 0x5d, 0xff, 0x3b, 0x8f, 0x64, 0xff, 0x03, 0x5c, 0x0f, 0xff, 0x17, 0x92, 0x2e, 0xff, 0x0f, 0x7a, 0x1d, 0xff, 0x14, 0x76, 0x21, 0xff, 0x01, 0x5b, 0x09, 0xff, 0x05, 0x53, 0x0b, 0xff, 0x03, 0x57, 0x10, 0xff, 0x0a, 0x79, 0x25, 0xff, 0x1e, 0xa0, 0x47, 0xff, 0x0a, 0x72, 0x37, 0xff, 0x27, 0x68, 0x49, 0xff, 0x0f, 0x46, 0x29, 0xff, 0x11, 0x4c, 0x2d, 0xff, 0x03, 0x41, 0x10, 0xff, 0x07, 0x4b, 0x15, 0xff, 0x04, 0x44, 0x14, 0xff, 0x66, 0x80, 0x6a, 0xff, + 0x86, 0x9e, 0xd0, 0xff, 0x7d, 0x93, 0xdb, 0xff, 0x33, 0x47, 0xab, 0xff, 0x10, 0x27, 0xa4, 0xff, 0x12, 0x2a, 0xaf, 0xff, 0x1a, 0x2e, 0xbb, 0xff, 0x1b, 0x2f, 0xb9, 0xff, 0x24, 0x41, 0xc9, 0xff, 0x31, 0x5d, 0xdf, 0xff, 0x48, 0x77, 0xea, 0xff, 0x65, 0x87, 0xe6, 0xff, 0xa3, 0xb0, 0xf4, 0xff, 0xac, 0xb2, 0xed, 0xff, 0xa7, 0xb4, 0xea, 0xff, 0x93, 0xae, 0xdf, 0xff, 0x5c, 0x98, 0xb2, 0xff, 0x2f, 0x90, 0x8a, 0xff, 0x0f, 0x9c, 0x70, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x0b, 0xa0, 0x6b, 0xff, 0x0e, 0x9d, 0x6b, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0e, 0xa5, 0x6b, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x05, 0xa8, 0x6f, 0xff, 0x07, 0xa9, 0x6e, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x08, 0xaa, 0x72, 0xff, 0x0a, 0xad, 0x74, 0xff, 0x0d, 0xb0, 0x78, 0xff, 0x0b, 0xae, 0x76, 0xff, 0x09, 0xac, 0x75, 0xff, 0x09, 0xac, 0x76, 0xff, 0x08, 0xab, 0x73, 0xff, 0x09, 0xac, 0x72, 0xff, 0x09, 0xad, 0x71, 0xff, 0x0b, 0xad, 0x70, 0xff, 0x0f, 0xae, 0x71, 0xff, 0x10, 0xac, 0x70, 0xff, 0x0f, 0xab, 0x6f, 0xff, 0x0f, 0xa9, 0x6f, 0xff, 0x0f, 0xa9, 0x6f, 0xff, 0x12, 0xab, 0x71, 0xff, 0x12, 0xaa, 0x70, 0xff, 0x0f, 0xa8, 0x6d, 0xff, 0x10, 0xa8, 0x6d, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0f, 0xa6, 0x6b, 0xff, 0x0f, 0xa8, 0x6c, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x0d, 0xab, 0x6e, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0e, 0xaa, 0x6d, 0xff, 0x0e, 0xab, 0x6e, 0xff, 0x0e, 0xb0, 0x75, 0xff, 0x14, 0xb1, 0x77, 0xff, 0x17, 0xb0, 0x77, 0xff, 0x16, 0xb0, 0x77, 0xff, 0x10, 0xaf, 0x76, 0xff, 0x0f, 0xb0, 0x77, 0xff, 0x12, 0xad, 0x75, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x77, 0xff, 0x10, 0xa3, 0x79, 0xff, 0x10, 0xa2, 0x7a, 0xff, 0x13, 0xa1, 0x7c, 0xff, 0x13, 0xa1, 0x7b, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x0f, 0xa1, 0x7b, 0xff, 0x12, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x7c, 0xff, 0x14, 0xa1, 0x7e, 0xff, 0x11, 0xa2, 0x7d, 0xff, 0x0f, 0xa4, 0x79, 0xff, 0x0c, 0xa6, 0x76, 0xff, 0x0b, 0xa7, 0x78, 0xff, 0x0a, 0xa6, 0x77, 0xff, 0x0a, 0xa6, 0x78, 0xff, 0x0b, 0xa7, 0x79, 0xff, 0x0b, 0xa7, 0x78, 0xff, 0x0b, 0xa8, 0x76, 0xff, 0x0b, 0xa7, 0x74, 0xff, 0x0c, 0xa9, 0x74, 0xff, 0x0c, 0xaa, 0x72, 0xff, 0x0c, 0xab, 0x71, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0b, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa8, 0x72, 0xff, 0x0c, 0xa9, 0x73, 0xff, 0x0d, 0xaa, 0x73, 0xff, 0x0e, 0xaa, 0x76, 0xff, 0x0e, 0xaa, 0x7a, 0xff, 0x10, 0xab, 0x7c, 0xff, 0x12, 0xad, 0x7c, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x0f, 0xaa, 0x79, 0xff, 0x0f, 0xaa, 0x79, 0xff, 0x10, 0xaa, 0x77, 0xff, 0x11, 0xab, 0x78, 0xff, 0x12, 0xab, 0x78, 0xff, 0x12, 0xab, 0x78, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x0e, 0xab, 0x79, 0xff, 0x0e, 0xac, 0x7a, 0xff, 0x0e, 0xac, 0x79, 0xff, 0x0d, 0xab, 0x78, 0xff, 0x0e, 0xab, 0x78, 0xff, 0x0d, 0xab, 0x77, 0xff, 0x0d, 0xab, 0x76, 0xff, 0x10, 0xaa, 0x77, 0xff, 0x11, 0xa8, 0x77, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x11, 0xac, 0x79, 0xff, 0x12, 0xad, 0x7a, 0xff, 0x11, 0xad, 0x7a, 0xff, 0x0f, 0xac, 0x79, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x0e, 0xac, 0x78, 0xff, 0x0e, 0xab, 0x77, 0xff, 0x0e, 0xab, 0x77, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x77, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x10, 0xab, 0x76, 0xff, 0x10, 0xac, 0x77, 0xff, 0x12, 0xab, 0x79, 0xff, 0x13, 0xab, 0x7c, 0xff, 0x13, 0xac, 0x81, 0xff, 0x13, 0xab, 0x83, 0xff, 0x16, 0xab, 0x84, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x16, 0xaa, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xab, 0x82, 0xff, 0x15, 0xab, 0x80, 0xff, 0x13, 0xab, 0x7f, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x10, 0xab, 0x7c, 0xff, 0x0c, 0xa8, 0x76, 0xff, 0x0a, 0xa7, 0x74, 0xff, 0x09, 0xa6, 0x72, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0e, 0xa8, 0x70, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0d, 0xa9, 0x71, 0xff, 0x0e, 0xac, 0x72, 0xff, 0x13, 0xb1, 0x77, 0xff, 0x0f, 0xad, 0x73, 0xff, 0x0f, 0xad, 0x73, 0xff, 0x0e, 0xac, 0x73, 0xff, 0x0f, 0xad, 0x73, 0xff, 0x0e, 0xac, 0x6e, 0xff, 0x13, 0xb0, 0x72, 0xff, 0x09, 0xa6, 0x66, 0xff, 0x0f, 0xab, 0x6a, 0xff, 0x0d, 0xa9, 0x68, 0xff, 0x09, 0xa6, 0x67, 0xff, 0x10, 0xac, 0x6f, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa5, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa2, 0x6c, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x07, 0xa2, 0x67, 0xff, 0x07, 0xa2, 0x66, 0xff, 0x07, 0xa2, 0x66, 0xff, 0x08, 0xa3, 0x67, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x08, 0xa1, 0x64, 0xff, 0x07, 0xa0, 0x61, 0xff, 0x06, 0xa1, 0x61, 0xff, 0x07, 0xa1, 0x62, 0xff, 0x08, 0xa2, 0x61, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x0e, 0xa6, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0a, 0xa2, 0x65, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0a, 0x9e, 0x5a, 0xff, 0x0b, 0x9d, 0x59, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x0b, 0x9c, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0c, 0x9c, 0x53, 0xff, 0x0a, 0x9a, 0x52, 0xff, 0x08, 0x98, 0x52, 0xff, 0x08, 0x96, 0x53, 0xff, 0x08, 0x97, 0x53, 0xff, 0x08, 0x96, 0x51, 0xff, 0x08, 0x96, 0x51, 0xff, 0x09, 0x94, 0x50, 0xff, 0x0a, 0x94, 0x50, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x09, 0x91, 0x4d, 0xff, 0x09, 0x8e, 0x4a, 0xff, 0x0a, 0x8b, 0x48, 0xff, 0x0a, 0x88, 0x46, 0xff, 0x09, 0x87, 0x45, 0xff, 0x08, 0x84, 0x43, 0xff, 0x08, 0x82, 0x42, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x0a, 0x7d, 0x41, 0xff, 0x0a, 0x7b, 0x3f, 0xff, 0x09, 0x78, 0x3e, 0xff, 0x0c, 0x76, 0x40, 0xff, 0x0b, 0x6e, 0x3c, 0xff, 0x14, 0x69, 0x42, 0xff, 0x26, 0x6e, 0x58, 0xff, 0x18, 0x60, 0x40, 0xff, 0x12, 0x6b, 0x3c, 0xff, 0x0f, 0x7d, 0x37, 0xff, 0x15, 0x8f, 0x3e, 0xff, 0x02, 0x5f, 0x1d, 0xff, 0x06, 0x58, 0x1b, 0xff, 0x02, 0x4a, 0x0b, 0xff, 0x05, 0x45, 0x09, 0xff, 0x06, 0x64, 0x20, 0xff, 0x10, 0x88, 0x39, 0xff, 0x13, 0x81, 0x37, 0xff, 0x10, 0x61, 0x3c, 0xff, 0x35, 0x66, 0x60, 0xff, 0x1e, 0x49, 0x46, 0xff, 0x16, 0x40, 0x35, 0xff, 0x0b, 0x3b, 0x19, 0xff, 0x04, 0x40, 0x17, 0xff, 0x01, 0x38, 0x12, 0xff, 0x68, 0x82, 0x6e, 0xff, + 0xa3, 0xb4, 0xe9, 0xff, 0x89, 0x99, 0xe6, 0xff, 0x39, 0x49, 0xb4, 0xff, 0x10, 0x25, 0xa6, 0xff, 0x17, 0x2e, 0xb1, 0xff, 0x21, 0x35, 0xbd, 0xff, 0x20, 0x34, 0xbb, 0xff, 0x23, 0x41, 0xc6, 0xff, 0x30, 0x5c, 0xdc, 0xff, 0x49, 0x78, 0xe8, 0xff, 0x66, 0x88, 0xe6, 0xff, 0xa3, 0xaf, 0xf7, 0xff, 0xaf, 0xb3, 0xee, 0xff, 0xac, 0xb3, 0xea, 0xff, 0xa4, 0xb5, 0xe7, 0xff, 0x8e, 0xb2, 0xd9, 0xff, 0x56, 0x95, 0xab, 0xff, 0x1b, 0x8e, 0x7d, 0xff, 0x0d, 0x9e, 0x71, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x0e, 0x9f, 0x6d, 0xff, 0x09, 0xa0, 0x6b, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x07, 0xa3, 0x6e, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x09, 0xab, 0x71, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x08, 0xaa, 0x72, 0xff, 0x06, 0xa9, 0x71, 0xff, 0x05, 0xa9, 0x70, 0xff, 0x05, 0xab, 0x71, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x0a, 0xaa, 0x73, 0xff, 0x11, 0xb2, 0x7a, 0xff, 0x17, 0xb7, 0x80, 0xff, 0x14, 0xb4, 0x7d, 0xff, 0x10, 0xb2, 0x7c, 0xff, 0x0e, 0xb1, 0x7c, 0xff, 0x0d, 0xb0, 0x79, 0xff, 0x0e, 0xb0, 0x78, 0xff, 0x0e, 0xae, 0x75, 0xff, 0x0f, 0xad, 0x73, 0xff, 0x12, 0xaf, 0x75, 0xff, 0x11, 0xae, 0x75, 0xff, 0x10, 0xac, 0x72, 0xff, 0x0f, 0xa5, 0x6a, 0xff, 0x10, 0xa5, 0x6a, 0xff, 0x1a, 0xad, 0x73, 0xff, 0x1c, 0xaf, 0x74, 0xff, 0x1a, 0xab, 0x71, 0xff, 0x15, 0xa7, 0x6d, 0xff, 0x14, 0xa4, 0x6b, 0xff, 0x12, 0xa2, 0x69, 0xff, 0x10, 0xa5, 0x69, 0xff, 0x10, 0xa7, 0x6b, 0xff, 0x0d, 0xa7, 0x6a, 0xff, 0x0e, 0xa9, 0x6d, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0d, 0xa7, 0x6b, 0xff, 0x0e, 0xaa, 0x6e, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x12, 0xad, 0x75, 0xff, 0x14, 0xad, 0x76, 0xff, 0x13, 0xae, 0x76, 0xff, 0x0e, 0xae, 0x76, 0xff, 0x0e, 0xae, 0x76, 0xff, 0x11, 0xaa, 0x75, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x0f, 0xa5, 0x75, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x77, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa1, 0x7a, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x12, 0xa0, 0x7b, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x12, 0xa1, 0x7a, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x15, 0xa2, 0x7c, 0xff, 0x14, 0xa1, 0x7d, 0xff, 0x12, 0xa2, 0x7c, 0xff, 0x0f, 0xa4, 0x78, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0d, 0xa8, 0x77, 0xff, 0x0b, 0xa6, 0x77, 0xff, 0x0b, 0xa6, 0x77, 0xff, 0x0b, 0xa6, 0x77, 0xff, 0x0b, 0xa7, 0x77, 0xff, 0x09, 0xa7, 0x75, 0xff, 0x0a, 0xa8, 0x74, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0c, 0xa9, 0x75, 0xff, 0x0b, 0xa9, 0x77, 0xff, 0x0d, 0xa9, 0x7a, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x12, 0xab, 0x7a, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x11, 0xac, 0x79, 0xff, 0x11, 0xad, 0x7a, 0xff, 0x12, 0xae, 0x7b, 0xff, 0x11, 0xae, 0x7b, 0xff, 0x10, 0xad, 0x7a, 0xff, 0x10, 0xac, 0x7b, 0xff, 0x12, 0xad, 0x7c, 0xff, 0x13, 0xad, 0x7c, 0xff, 0x12, 0xab, 0x79, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0f, 0xa5, 0x73, 0xff, 0x11, 0xa4, 0x71, 0xff, 0x10, 0xa2, 0x6f, 0xff, 0x0f, 0xa0, 0x6e, 0xff, 0x0e, 0xa2, 0x6e, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x0f, 0xa4, 0x70, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x10, 0xa8, 0x74, 0xff, 0x12, 0xaa, 0x75, 0xff, 0x11, 0xab, 0x75, 0xff, 0x10, 0xaa, 0x75, 0xff, 0x0f, 0xa9, 0x74, 0xff, 0x0f, 0xab, 0x76, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xab, 0x78, 0xff, 0x10, 0xac, 0x76, 0xff, 0x10, 0xad, 0x76, 0xff, 0x11, 0xad, 0x77, 0xff, 0x11, 0xad, 0x78, 0xff, 0x12, 0xab, 0x79, 0xff, 0x13, 0xab, 0x7c, 0xff, 0x15, 0xac, 0x80, 0xff, 0x15, 0xab, 0x83, 0xff, 0x16, 0xac, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x82, 0xff, 0x15, 0xab, 0x80, 0xff, 0x14, 0xab, 0x80, 0xff, 0x13, 0xab, 0x80, 0xff, 0x13, 0xab, 0x7f, 0xff, 0x12, 0xab, 0x7d, 0xff, 0x0e, 0xa9, 0x78, 0xff, 0x0b, 0xa7, 0x75, 0xff, 0x0a, 0xa7, 0x73, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0f, 0xa9, 0x72, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0f, 0xab, 0x72, 0xff, 0x0c, 0xa9, 0x6f, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x0f, 0xa8, 0x6e, 0xff, 0x0f, 0xa9, 0x6d, 0xff, 0x15, 0xb0, 0x74, 0xff, 0x0c, 0xac, 0x70, 0xff, 0x11, 0xb5, 0x78, 0xff, 0x10, 0xb6, 0x79, 0xff, 0x0a, 0xaf, 0x72, 0xff, 0x07, 0xab, 0x6e, 0xff, 0x0f, 0xb0, 0x74, 0xff, 0x0f, 0xaf, 0x71, 0xff, 0x1b, 0xb8, 0x79, 0xff, 0x13, 0xb0, 0x70, 0xff, 0x0e, 0xaa, 0x69, 0xff, 0x0f, 0xac, 0x6b, 0xff, 0x10, 0xad, 0x6f, 0xff, 0x13, 0xaf, 0x73, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0f, 0xa7, 0x6b, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x08, 0xa1, 0x66, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x09, 0xa1, 0x66, 0xff, 0x09, 0xa2, 0x66, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x08, 0xa2, 0x65, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x08, 0xa3, 0x66, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0a, 0xa1, 0x63, 0xff, 0x0a, 0xa0, 0x61, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x07, 0xa0, 0x60, 0xff, 0x09, 0xa2, 0x64, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0b, 0xa1, 0x65, 0xff, 0x0a, 0xa2, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0a, 0x9e, 0x5a, 0xff, 0x0c, 0x9d, 0x59, 0xff, 0x0c, 0x9c, 0x57, 0xff, 0x0c, 0x9c, 0x55, 0xff, 0x0b, 0x9b, 0x53, 0xff, 0x0c, 0x9c, 0x54, 0xff, 0x0a, 0x9a, 0x52, 0xff, 0x08, 0x98, 0x52, 0xff, 0x09, 0x97, 0x53, 0xff, 0x08, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x08, 0x96, 0x51, 0xff, 0x0a, 0x94, 0x50, 0xff, 0x0a, 0x94, 0x50, 0xff, 0x0a, 0x92, 0x4e, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x09, 0x8d, 0x4a, 0xff, 0x09, 0x8a, 0x48, 0xff, 0x09, 0x87, 0x45, 0xff, 0x08, 0x86, 0x44, 0xff, 0x07, 0x83, 0x43, 0xff, 0x07, 0x82, 0x41, 0xff, 0x08, 0x7e, 0x41, 0xff, 0x0a, 0x7d, 0x40, 0xff, 0x0a, 0x7b, 0x3f, 0xff, 0x0e, 0x76, 0x42, 0xff, 0x0f, 0x73, 0x3d, 0xff, 0x0d, 0x6d, 0x3c, 0xff, 0x10, 0x66, 0x46, 0xff, 0x21, 0x6c, 0x60, 0xff, 0x03, 0x3d, 0x29, 0xff, 0x05, 0x5d, 0x3a, 0xff, 0x1e, 0x9a, 0x6c, 0xff, 0x16, 0x89, 0x5e, 0xff, 0x16, 0x78, 0x57, 0xff, 0x0c, 0x5e, 0x39, 0xff, 0x01, 0x3e, 0x12, 0xff, 0x03, 0x3a, 0x0b, 0xff, 0x0b, 0x72, 0x2f, 0xff, 0x11, 0x8b, 0x3d, 0xff, 0x04, 0x5d, 0x20, 0xff, 0x0c, 0x4c, 0x34, 0xff, 0x43, 0x71, 0x7b, 0xff, 0x31, 0x5d, 0x6f, 0xff, 0x0d, 0x36, 0x3a, 0xff, 0x03, 0x30, 0x1f, 0xff, 0x01, 0x37, 0x23, 0xff, 0x01, 0x33, 0x1d, 0xff, 0x62, 0x7d, 0x75, 0xff, + 0xa9, 0xb1, 0xea, 0xff, 0x7a, 0x87, 0xd8, 0xff, 0x2d, 0x3a, 0xae, 0xff, 0x13, 0x27, 0xab, 0xff, 0x22, 0x3a, 0xb9, 0xff, 0x4f, 0x64, 0xe5, 0xff, 0x51, 0x66, 0xe8, 0xff, 0x1e, 0x3d, 0xbf, 0xff, 0x32, 0x5d, 0xda, 0xff, 0x45, 0x75, 0xe4, 0xff, 0x5f, 0x83, 0xe1, 0xff, 0x9f, 0xae, 0xf6, 0xff, 0xae, 0xb1, 0xee, 0xff, 0xb4, 0xb5, 0xec, 0xff, 0xb1, 0xb5, 0xeb, 0xff, 0xac, 0xb4, 0xed, 0xff, 0x96, 0xac, 0xe0, 0xff, 0x4d, 0x8f, 0xa3, 0xff, 0x1f, 0x8d, 0x7e, 0xff, 0x0c, 0xa0, 0x6f, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x09, 0xa4, 0x70, 0xff, 0x06, 0xa3, 0x71, 0xff, 0x07, 0xa3, 0x71, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x07, 0xaa, 0x6e, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x09, 0xab, 0x71, 0xff, 0x09, 0xab, 0x71, 0xff, 0x09, 0xab, 0x71, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x08, 0xab, 0x73, 0xff, 0x08, 0xad, 0x73, 0xff, 0x03, 0xac, 0x72, 0xff, 0x02, 0xa8, 0x6f, 0xff, 0x07, 0xaa, 0x72, 0xff, 0x0f, 0xaf, 0x78, 0xff, 0x19, 0xb7, 0x81, 0xff, 0x1c, 0xba, 0x84, 0xff, 0x1a, 0xb9, 0x83, 0xff, 0x17, 0xba, 0x83, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x18, 0xb7, 0x82, 0xff, 0x1c, 0xb5, 0x7f, 0xff, 0x1a, 0xaf, 0x79, 0xff, 0x18, 0xab, 0x76, 0xff, 0x18, 0xab, 0x75, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x05, 0x98, 0x61, 0xff, 0x04, 0x8f, 0x55, 0xff, 0x07, 0x91, 0x57, 0xff, 0x0d, 0x96, 0x5b, 0xff, 0x0c, 0x92, 0x59, 0xff, 0x08, 0x8a, 0x52, 0xff, 0x06, 0x86, 0x4f, 0xff, 0x09, 0x8a, 0x56, 0xff, 0x08, 0x89, 0x54, 0xff, 0x09, 0x92, 0x5b, 0xff, 0x12, 0x9d, 0x65, 0xff, 0x11, 0x9f, 0x66, 0xff, 0x15, 0xa4, 0x6b, 0xff, 0x16, 0xa6, 0x6d, 0xff, 0x10, 0xa2, 0x69, 0xff, 0x09, 0x9c, 0x62, 0xff, 0x0a, 0x9d, 0x63, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x10, 0xa6, 0x6e, 0xff, 0x12, 0xa9, 0x72, 0xff, 0x13, 0xac, 0x75, 0xff, 0x0f, 0xad, 0x77, 0xff, 0x0e, 0xac, 0x76, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x76, 0xff, 0x0f, 0xa6, 0x78, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0f, 0xa3, 0x77, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x77, 0xff, 0x0f, 0xa2, 0x78, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x12, 0xa1, 0x7b, 0xff, 0x11, 0xa0, 0x7a, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x10, 0xa1, 0x7b, 0xff, 0x12, 0xa0, 0x7b, 0xff, 0x15, 0xa2, 0x7b, 0xff, 0x14, 0xa2, 0x7a, 0xff, 0x14, 0xa1, 0x7c, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x0f, 0xa4, 0x77, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa7, 0x75, 0xff, 0x0b, 0xa8, 0x76, 0xff, 0x08, 0xa6, 0x73, 0xff, 0x08, 0xa9, 0x73, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xab, 0x75, 0xff, 0x0c, 0xaa, 0x74, 0xff, 0x0c, 0xaa, 0x74, 0xff, 0x0a, 0xaa, 0x74, 0xff, 0x0c, 0xac, 0x77, 0xff, 0x0e, 0xad, 0x7b, 0xff, 0x0f, 0xae, 0x7e, 0xff, 0x12, 0xae, 0x7d, 0xff, 0x13, 0xae, 0x7d, 0xff, 0x13, 0xb0, 0x7e, 0xff, 0x15, 0xb3, 0x80, 0xff, 0x17, 0xb4, 0x82, 0xff, 0x17, 0xb5, 0x82, 0xff, 0x17, 0xb6, 0x82, 0xff, 0x15, 0xb5, 0x81, 0xff, 0x15, 0xb1, 0x7e, 0xff, 0x17, 0xb0, 0x7e, 0xff, 0x18, 0xb0, 0x7d, 0xff, 0x15, 0xaa, 0x77, 0xff, 0x0e, 0x9f, 0x6d, 0xff, 0x09, 0x99, 0x66, 0xff, 0x06, 0x93, 0x62, 0xff, 0x05, 0x91, 0x5e, 0xff, 0x05, 0x8e, 0x5a, 0xff, 0x04, 0x8c, 0x58, 0xff, 0x04, 0x8c, 0x58, 0xff, 0x04, 0x8d, 0x59, 0xff, 0x03, 0x8d, 0x59, 0xff, 0x03, 0x8e, 0x59, 0xff, 0x04, 0x90, 0x5b, 0xff, 0x0a, 0x96, 0x61, 0xff, 0x0e, 0x9f, 0x67, 0xff, 0x10, 0xa3, 0x6a, 0xff, 0x10, 0xa5, 0x6d, 0xff, 0x10, 0xa7, 0x6f, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x0f, 0xaa, 0x74, 0xff, 0x0f, 0xac, 0x75, 0xff, 0x0e, 0xac, 0x76, 0xff, 0x0d, 0xac, 0x75, 0xff, 0x0d, 0xac, 0x74, 0xff, 0x0d, 0xad, 0x76, 0xff, 0x0e, 0xab, 0x76, 0xff, 0x0f, 0xab, 0x78, 0xff, 0x11, 0xab, 0x7a, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x15, 0xab, 0x81, 0xff, 0x15, 0xab, 0x83, 0xff, 0x14, 0xac, 0x84, 0xff, 0x15, 0xac, 0x84, 0xff, 0x16, 0xac, 0x84, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x17, 0xab, 0x85, 0xff, 0x18, 0xab, 0x85, 0xff, 0x18, 0xac, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x83, 0xff, 0x16, 0xac, 0x82, 0xff, 0x16, 0xac, 0x82, 0xff, 0x15, 0xab, 0x80, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x0f, 0xa9, 0x79, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x73, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x10, 0xab, 0x74, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x07, 0xa7, 0x6b, 0xff, 0x0b, 0xad, 0x70, 0xff, 0x13, 0xb2, 0x73, 0xff, 0x17, 0xb3, 0x73, 0xff, 0x0e, 0xa8, 0x67, 0xff, 0x13, 0xb0, 0x6e, 0xff, 0x08, 0xac, 0x6b, 0xff, 0x05, 0xae, 0x6e, 0xff, 0x0a, 0xb7, 0x79, 0xff, 0x09, 0xb4, 0x74, 0xff, 0x07, 0xae, 0x6f, 0xff, 0x0f, 0xb3, 0x74, 0xff, 0x11, 0xb2, 0x74, 0xff, 0x12, 0xaf, 0x73, 0xff, 0x0f, 0xad, 0x70, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0a, 0xaa, 0x6c, 0xff, 0x0e, 0xad, 0x71, 0xff, 0x0d, 0xa9, 0x70, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x06, 0xa2, 0x69, 0xff, 0x05, 0xa1, 0x67, 0xff, 0x08, 0xa0, 0x65, 0xff, 0x03, 0x99, 0x5d, 0xff, 0x03, 0x98, 0x5c, 0xff, 0x08, 0x9d, 0x61, 0xff, 0x0e, 0xa1, 0x67, 0xff, 0x15, 0xa5, 0x6e, 0xff, 0x16, 0xa5, 0x6f, 0xff, 0x12, 0x9f, 0x6a, 0xff, 0x0e, 0x9c, 0x62, 0xff, 0x0d, 0x9b, 0x60, 0xff, 0x0d, 0x9c, 0x61, 0xff, 0x0e, 0x9d, 0x62, 0xff, 0x0a, 0x9d, 0x61, 0xff, 0x0d, 0xa0, 0x64, 0xff, 0x0d, 0xa1, 0x65, 0xff, 0x0c, 0xa1, 0x65, 0xff, 0x0c, 0xa2, 0x65, 0xff, 0x0b, 0xa2, 0x65, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x08, 0xa3, 0x64, 0xff, 0x0a, 0xa2, 0x63, 0xff, 0x0d, 0xa1, 0x62, 0xff, 0x0f, 0xa2, 0x64, 0xff, 0x07, 0xa0, 0x61, 0xff, 0x06, 0xa2, 0x64, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x09, 0xa2, 0x67, 0xff, 0x0a, 0xa0, 0x64, 0xff, 0x0a, 0xa2, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0b, 0x9e, 0x5b, 0xff, 0x0d, 0x9d, 0x58, 0xff, 0x0d, 0x9c, 0x57, 0xff, 0x0c, 0x9c, 0x55, 0xff, 0x0c, 0x9c, 0x55, 0xff, 0x0c, 0x9c, 0x55, 0xff, 0x0b, 0x9a, 0x52, 0xff, 0x0a, 0x98, 0x52, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x08, 0x96, 0x51, 0xff, 0x09, 0x95, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0a, 0x91, 0x4e, 0xff, 0x0b, 0x90, 0x4d, 0xff, 0x0a, 0x8e, 0x4b, 0xff, 0x0a, 0x8a, 0x48, 0xff, 0x0a, 0x87, 0x45, 0xff, 0x09, 0x86, 0x44, 0xff, 0x08, 0x84, 0x43, 0xff, 0x07, 0x81, 0x41, 0xff, 0x08, 0x7e, 0x41, 0xff, 0x09, 0x7c, 0x40, 0xff, 0x09, 0x79, 0x3f, 0xff, 0x0d, 0x75, 0x40, 0xff, 0x0f, 0x73, 0x40, 0xff, 0x0f, 0x6e, 0x4f, 0xff, 0x1d, 0x76, 0x73, 0xff, 0x35, 0x8e, 0x9e, 0xff, 0x2a, 0x82, 0x9b, 0xff, 0x3b, 0xa8, 0xb9, 0xff, 0x52, 0xd5, 0xdf, 0xff, 0x57, 0xd9, 0xe1, 0xff, 0x60, 0xe5, 0xe8, 0xff, 0x5c, 0xe2, 0xd7, 0xff, 0x38, 0x9d, 0x85, 0xff, 0x06, 0x47, 0x27, 0xff, 0x15, 0x6d, 0x31, 0xff, 0x0c, 0x67, 0x1d, 0xff, 0x1d, 0x61, 0x32, 0xff, 0x31, 0x5f, 0x53, 0xff, 0x3b, 0x6b, 0x81, 0xff, 0x60, 0x9d, 0xc3, 0xff, 0x49, 0x8e, 0xab, 0xff, 0x46, 0x97, 0xa4, 0xff, 0x54, 0xb7, 0xc4, 0xff, 0x57, 0xb1, 0xba, 0xff, 0x8f, 0xba, 0xc0, 0xff, + 0xb0, 0xb6, 0xee, 0xff, 0x67, 0x75, 0xc8, 0xff, 0x1d, 0x2c, 0xa5, 0xff, 0x12, 0x27, 0xae, 0xff, 0x27, 0x41, 0xbf, 0xff, 0x63, 0x7a, 0xf6, 0xff, 0x60, 0x75, 0xf4, 0xff, 0x1e, 0x3c, 0xc1, 0xff, 0x2c, 0x54, 0xd5, 0xff, 0x44, 0x71, 0xe2, 0xff, 0x5b, 0x7f, 0xe0, 0xff, 0x9c, 0xad, 0xf9, 0xff, 0xab, 0xb1, 0xee, 0xff, 0xb5, 0xb4, 0xea, 0xff, 0xb5, 0xb4, 0xeb, 0xff, 0xb2, 0xb2, 0xef, 0xff, 0xa7, 0xaf, 0xe8, 0xff, 0x84, 0xa5, 0xce, 0xff, 0x47, 0x8f, 0x9d, 0xff, 0x13, 0x96, 0x76, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x08, 0xa4, 0x69, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x06, 0xa6, 0x70, 0xff, 0x07, 0xa5, 0x71, 0xff, 0x09, 0xa5, 0x72, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x08, 0xab, 0x6f, 0xff, 0x09, 0xab, 0x71, 0xff, 0x09, 0xab, 0x71, 0xff, 0x09, 0xab, 0x71, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x07, 0xaa, 0x71, 0xff, 0x09, 0xad, 0x74, 0xff, 0x08, 0xae, 0x74, 0xff, 0x04, 0xb0, 0x74, 0xff, 0x07, 0xae, 0x75, 0xff, 0x0d, 0xb1, 0x79, 0xff, 0x16, 0xb8, 0x81, 0xff, 0x1a, 0xba, 0x84, 0xff, 0x1b, 0xba, 0x84, 0xff, 0x18, 0xba, 0x83, 0xff, 0x17, 0xb9, 0x82, 0xff, 0x15, 0xb4, 0x7e, 0xff, 0x15, 0xae, 0x78, 0xff, 0x15, 0xa4, 0x6f, 0xff, 0x12, 0x9a, 0x66, 0xff, 0x0f, 0x92, 0x5f, 0xff, 0x0d, 0x8e, 0x5b, 0xff, 0x09, 0x8e, 0x5a, 0xff, 0x04, 0x89, 0x54, 0xff, 0x05, 0x85, 0x4c, 0xff, 0x07, 0x84, 0x4d, 0xff, 0x05, 0x83, 0x4b, 0xff, 0x03, 0x7b, 0x46, 0xff, 0x03, 0x77, 0x41, 0xff, 0x03, 0x75, 0x41, 0xff, 0x02, 0x74, 0x43, 0xff, 0x01, 0x74, 0x42, 0xff, 0x02, 0x7c, 0x48, 0xff, 0x0b, 0x87, 0x53, 0xff, 0x0f, 0x8d, 0x59, 0xff, 0x0f, 0x8f, 0x5a, 0xff, 0x0f, 0x90, 0x5b, 0xff, 0x0e, 0x91, 0x5c, 0xff, 0x0d, 0x92, 0x5d, 0xff, 0x08, 0x8e, 0x58, 0xff, 0x07, 0x91, 0x59, 0xff, 0x0d, 0x99, 0x61, 0xff, 0x11, 0xa2, 0x6b, 0xff, 0x12, 0xa7, 0x70, 0xff, 0x11, 0xac, 0x75, 0xff, 0x11, 0xad, 0x76, 0xff, 0x12, 0xac, 0x77, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0b, 0xa5, 0x72, 0xff, 0x0d, 0xa4, 0x74, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x10, 0xa3, 0x77, 0xff, 0x10, 0xa2, 0x77, 0xff, 0x10, 0xa1, 0x79, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x11, 0xa1, 0x7b, 0xff, 0x10, 0xa0, 0x7a, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x10, 0xa1, 0x7a, 0xff, 0x11, 0xa0, 0x79, 0xff, 0x13, 0xa3, 0x7a, 0xff, 0x14, 0xa3, 0x79, 0xff, 0x13, 0xa2, 0x7b, 0xff, 0x11, 0xa2, 0x79, 0xff, 0x0e, 0xa4, 0x75, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0e, 0xa7, 0x72, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa8, 0x75, 0xff, 0x0c, 0xa9, 0x76, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x09, 0xab, 0x72, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0c, 0xaa, 0x73, 0xff, 0x0e, 0xac, 0x76, 0xff, 0x0d, 0xab, 0x75, 0xff, 0x0d, 0xac, 0x76, 0xff, 0x10, 0xaf, 0x7a, 0xff, 0x11, 0xb2, 0x7e, 0xff, 0x13, 0xb4, 0x82, 0xff, 0x14, 0xb4, 0x83, 0xff, 0x15, 0xb5, 0x83, 0xff, 0x15, 0xb5, 0x83, 0xff, 0x16, 0xb5, 0x83, 0xff, 0x18, 0xb7, 0x84, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x19, 0xb7, 0x84, 0xff, 0x19, 0xb6, 0x83, 0xff, 0x16, 0xb3, 0x80, 0xff, 0x15, 0xae, 0x79, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x0d, 0x9f, 0x6b, 0xff, 0x0b, 0x99, 0x64, 0xff, 0x07, 0x91, 0x5d, 0xff, 0x03, 0x8a, 0x57, 0xff, 0x03, 0x87, 0x55, 0xff, 0x04, 0x87, 0x54, 0xff, 0x05, 0x85, 0x52, 0xff, 0x03, 0x83, 0x4f, 0xff, 0x03, 0x84, 0x50, 0xff, 0x04, 0x86, 0x51, 0xff, 0x02, 0x85, 0x51, 0xff, 0x02, 0x86, 0x51, 0xff, 0x02, 0x88, 0x51, 0xff, 0x04, 0x8b, 0x55, 0xff, 0x06, 0x91, 0x58, 0xff, 0x07, 0x94, 0x5b, 0xff, 0x07, 0x97, 0x5e, 0xff, 0x07, 0x9a, 0x61, 0xff, 0x07, 0x9e, 0x66, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0c, 0xac, 0x74, 0xff, 0x0c, 0xad, 0x75, 0xff, 0x0b, 0xad, 0x75, 0xff, 0x0c, 0xad, 0x76, 0xff, 0x0c, 0xac, 0x77, 0xff, 0x0c, 0xab, 0x78, 0xff, 0x0e, 0xab, 0x7a, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x12, 0xaa, 0x7e, 0xff, 0x11, 0xaa, 0x7f, 0xff, 0x11, 0xaa, 0x82, 0xff, 0x13, 0xab, 0x83, 0xff, 0x15, 0xab, 0x83, 0xff, 0x15, 0xac, 0x84, 0xff, 0x16, 0xac, 0x84, 0xff, 0x16, 0xac, 0x84, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x18, 0xac, 0x84, 0xff, 0x18, 0xac, 0x83, 0xff, 0x16, 0xaa, 0x82, 0xff, 0x13, 0xa9, 0x7e, 0xff, 0x12, 0xaa, 0x7c, 0xff, 0x10, 0xa8, 0x78, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0b, 0xa5, 0x72, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x09, 0xa1, 0x6d, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x12, 0xae, 0x77, 0xff, 0x0d, 0xaa, 0x71, 0xff, 0x0e, 0xae, 0x74, 0xff, 0x0b, 0xab, 0x6f, 0xff, 0x05, 0xa7, 0x6a, 0xff, 0x0b, 0xb1, 0x70, 0xff, 0x0d, 0xb0, 0x6d, 0xff, 0x13, 0xb4, 0x6f, 0xff, 0x0b, 0xab, 0x64, 0xff, 0x0b, 0xac, 0x66, 0xff, 0x0f, 0xb3, 0x71, 0xff, 0x05, 0xac, 0x6c, 0xff, 0x07, 0xb1, 0x74, 0xff, 0x0a, 0xb4, 0x77, 0xff, 0x08, 0xae, 0x72, 0xff, 0x0c, 0xaf, 0x72, 0xff, 0x0d, 0xac, 0x71, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x0a, 0xaa, 0x71, 0xff, 0x0c, 0xa9, 0x70, 0xff, 0x0e, 0xa8, 0x6f, 0xff, 0x0f, 0xa5, 0x6e, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0a, 0x9f, 0x65, 0xff, 0x0a, 0x9f, 0x65, 0xff, 0x09, 0x9d, 0x63, 0xff, 0x04, 0x95, 0x58, 0xff, 0x01, 0x8f, 0x52, 0xff, 0x03, 0x91, 0x53, 0xff, 0x0b, 0x99, 0x5b, 0xff, 0x0b, 0x96, 0x5c, 0xff, 0x0c, 0x93, 0x5c, 0xff, 0x0a, 0x8f, 0x5a, 0xff, 0x05, 0x88, 0x53, 0xff, 0x04, 0x86, 0x4e, 0xff, 0x03, 0x86, 0x4d, 0xff, 0x03, 0x88, 0x4e, 0xff, 0x08, 0x8f, 0x56, 0xff, 0x05, 0x8f, 0x55, 0xff, 0x06, 0x90, 0x56, 0xff, 0x09, 0x94, 0x59, 0xff, 0x0a, 0x95, 0x5b, 0xff, 0x09, 0x96, 0x5d, 0xff, 0x0c, 0x9c, 0x60, 0xff, 0x0d, 0xa0, 0x64, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x09, 0xa1, 0x64, 0xff, 0x0c, 0xa1, 0x63, 0xff, 0x0e, 0xa2, 0x63, 0xff, 0x0a, 0xa3, 0x65, 0xff, 0x06, 0xa2, 0x66, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa1, 0x65, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0c, 0x9e, 0x5b, 0xff, 0x0d, 0x9c, 0x58, 0xff, 0x0c, 0x9b, 0x56, 0xff, 0x0c, 0x9b, 0x56, 0xff, 0x0c, 0x9b, 0x56, 0xff, 0x0d, 0x9c, 0x57, 0xff, 0x0a, 0x99, 0x53, 0xff, 0x0a, 0x98, 0x53, 0xff, 0x0b, 0x96, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x09, 0x95, 0x51, 0xff, 0x09, 0x94, 0x50, 0xff, 0x0b, 0x94, 0x50, 0xff, 0x0c, 0x94, 0x50, 0xff, 0x0b, 0x90, 0x4d, 0xff, 0x0c, 0x90, 0x4d, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x0a, 0x89, 0x46, 0xff, 0x0a, 0x87, 0x44, 0xff, 0x0a, 0x85, 0x44, 0xff, 0x08, 0x83, 0x43, 0xff, 0x06, 0x80, 0x42, 0xff, 0x09, 0x7f, 0x41, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x08, 0x79, 0x3e, 0xff, 0x0e, 0x74, 0x40, 0xff, 0x0f, 0x71, 0x41, 0xff, 0x0e, 0x69, 0x57, 0xff, 0x34, 0x8a, 0x9e, 0xff, 0x38, 0x90, 0xba, 0xff, 0x3c, 0x9d, 0xd0, 0xff, 0x34, 0xa5, 0xce, 0xff, 0x32, 0xb1, 0xd7, 0xff, 0x39, 0xbe, 0xdf, 0xff, 0x47, 0xda, 0xeb, 0xff, 0x51, 0xe5, 0xe9, 0xff, 0x5d, 0xe9, 0xdf, 0xff, 0x2f, 0x9d, 0x8a, 0xff, 0x0e, 0x59, 0x29, 0xff, 0x0d, 0x56, 0x13, 0xff, 0x29, 0x65, 0x3a, 0xff, 0x3b, 0x5f, 0x5a, 0xff, 0x2a, 0x53, 0x74, 0xff, 0x40, 0x7f, 0xb4, 0xff, 0x52, 0xa3, 0xd8, 0xff, 0x63, 0xc6, 0xe9, 0xff, 0x6d, 0xe2, 0xfb, 0xff, 0x70, 0xe4, 0xf8, 0xff, 0xaf, 0xf0, 0xf3, 0xff, + 0xb2, 0xb7, 0xf0, 0xff, 0x56, 0x67, 0xbd, 0xff, 0x15, 0x27, 0xa5, 0xff, 0x12, 0x29, 0xb2, 0xff, 0x22, 0x3f, 0xbe, 0xff, 0x52, 0x6a, 0xeb, 0xff, 0x41, 0x56, 0xdd, 0xff, 0x1d, 0x38, 0xc2, 0xff, 0x26, 0x4b, 0xcf, 0xff, 0x3e, 0x67, 0xdf, 0xff, 0x52, 0x76, 0xdd, 0xff, 0x8e, 0xa2, 0xf4, 0xff, 0xa6, 0xb0, 0xf2, 0xff, 0xb5, 0xb6, 0xed, 0xff, 0xb4, 0xb2, 0xea, 0xff, 0xb2, 0xb2, 0xee, 0xff, 0xaf, 0xb1, 0xeb, 0xff, 0xa7, 0xaf, 0xe6, 0xff, 0x84, 0xa5, 0xce, 0xff, 0x2e, 0x8e, 0x8a, 0xff, 0x11, 0x9b, 0x73, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x08, 0xa7, 0x6b, 0xff, 0x05, 0xa7, 0x6c, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x0a, 0xa5, 0x73, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x09, 0xac, 0x70, 0xff, 0x09, 0xab, 0x71, 0xff, 0x09, 0xab, 0x71, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x07, 0xab, 0x71, 0xff, 0x09, 0xad, 0x73, 0xff, 0x0a, 0xae, 0x74, 0xff, 0x0a, 0xb0, 0x76, 0xff, 0x08, 0xb2, 0x76, 0xff, 0x0d, 0xb4, 0x7b, 0xff, 0x15, 0xba, 0x82, 0xff, 0x19, 0xbc, 0x86, 0xff, 0x19, 0xbb, 0x86, 0xff, 0x19, 0xbc, 0x85, 0xff, 0x16, 0xb9, 0x81, 0xff, 0x0f, 0xae, 0x77, 0xff, 0x0a, 0x9f, 0x68, 0xff, 0x07, 0x94, 0x5e, 0xff, 0x03, 0x82, 0x4e, 0xff, 0x01, 0x74, 0x42, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x01, 0x65, 0x35, 0xff, 0x01, 0x6e, 0x3c, 0xff, 0x03, 0x73, 0x41, 0xff, 0x05, 0x76, 0x41, 0xff, 0x05, 0x74, 0x40, 0xff, 0x05, 0x74, 0x40, 0xff, 0x07, 0x73, 0x40, 0xff, 0x0a, 0x73, 0x43, 0xff, 0x0c, 0x72, 0x43, 0xff, 0x06, 0x6c, 0x3e, 0xff, 0x02, 0x67, 0x39, 0xff, 0x03, 0x68, 0x39, 0xff, 0x07, 0x6e, 0x3e, 0xff, 0x08, 0x72, 0x42, 0xff, 0x02, 0x6d, 0x3d, 0xff, 0x01, 0x6c, 0x3b, 0xff, 0x02, 0x71, 0x40, 0xff, 0x05, 0x76, 0x44, 0xff, 0x02, 0x75, 0x42, 0xff, 0x05, 0x7d, 0x47, 0xff, 0x05, 0x81, 0x4a, 0xff, 0x05, 0x8a, 0x53, 0xff, 0x0b, 0x96, 0x5e, 0xff, 0x10, 0xa4, 0x6b, 0xff, 0x14, 0xac, 0x75, 0xff, 0x13, 0xae, 0x76, 0xff, 0x10, 0xaa, 0x74, 0xff, 0x0f, 0xa7, 0x72, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x0f, 0xa4, 0x77, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x0f, 0xa5, 0x77, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x10, 0xa2, 0x79, 0xff, 0x10, 0xa1, 0x7a, 0xff, 0x11, 0xa2, 0x7b, 0xff, 0x0f, 0xa0, 0x7a, 0xff, 0x12, 0xa2, 0x7a, 0xff, 0x0f, 0xa0, 0x77, 0xff, 0x11, 0xa1, 0x7a, 0xff, 0x0f, 0xa0, 0x76, 0xff, 0x12, 0xa4, 0x78, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x12, 0xa5, 0x79, 0xff, 0x0f, 0xa5, 0x74, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0e, 0xaa, 0x74, 0xff, 0x0e, 0xab, 0x76, 0xff, 0x09, 0xaa, 0x73, 0xff, 0x08, 0xaa, 0x71, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x0b, 0xab, 0x73, 0xff, 0x0d, 0xad, 0x75, 0xff, 0x0d, 0xab, 0x75, 0xff, 0x0e, 0xac, 0x76, 0xff, 0x11, 0xae, 0x79, 0xff, 0x13, 0xb2, 0x7e, 0xff, 0x17, 0xb7, 0x82, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x17, 0xb9, 0x86, 0xff, 0x15, 0xb7, 0x84, 0xff, 0x14, 0xb8, 0x84, 0xff, 0x13, 0xb8, 0x83, 0xff, 0x13, 0xb6, 0x83, 0xff, 0x16, 0xb7, 0x84, 0xff, 0x19, 0xb5, 0x81, 0xff, 0x1a, 0xb3, 0x7f, 0xff, 0x17, 0xaf, 0x7b, 0xff, 0x13, 0xa8, 0x74, 0xff, 0x0b, 0x9d, 0x66, 0xff, 0x05, 0x93, 0x5a, 0xff, 0x01, 0x89, 0x51, 0xff, 0x01, 0x85, 0x4e, 0xff, 0x02, 0x81, 0x4c, 0xff, 0x05, 0x80, 0x4b, 0xff, 0x04, 0x7d, 0x49, 0xff, 0x06, 0x7f, 0x4b, 0xff, 0x07, 0x7f, 0x4b, 0xff, 0x03, 0x7b, 0x48, 0xff, 0x03, 0x7b, 0x49, 0xff, 0x04, 0x7d, 0x49, 0xff, 0x02, 0x7e, 0x48, 0xff, 0x02, 0x7f, 0x49, 0xff, 0x00, 0x7f, 0x48, 0xff, 0x01, 0x81, 0x4a, 0xff, 0x01, 0x85, 0x4c, 0xff, 0x00, 0x87, 0x4d, 0xff, 0x04, 0x8f, 0x55, 0xff, 0x05, 0x94, 0x59, 0xff, 0x03, 0x98, 0x5d, 0xff, 0x05, 0x9d, 0x63, 0xff, 0x08, 0xa6, 0x6b, 0xff, 0x0f, 0xaf, 0x75, 0xff, 0x0e, 0xb1, 0x78, 0xff, 0x0d, 0xb1, 0x79, 0xff, 0x0f, 0xb3, 0x7b, 0xff, 0x0e, 0xb1, 0x7b, 0xff, 0x0c, 0xaf, 0x7b, 0xff, 0x0b, 0xac, 0x7b, 0xff, 0x0d, 0xac, 0x7d, 0xff, 0x0f, 0xac, 0x7e, 0xff, 0x0e, 0xa9, 0x7c, 0xff, 0x0e, 0xa9, 0x7d, 0xff, 0x13, 0xad, 0x82, 0xff, 0x15, 0xaf, 0x84, 0xff, 0x14, 0xad, 0x84, 0xff, 0x14, 0xad, 0x84, 0xff, 0x14, 0xab, 0x83, 0xff, 0x16, 0xab, 0x84, 0xff, 0x18, 0xad, 0x86, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xaa, 0x82, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x18, 0xac, 0x84, 0xff, 0x18, 0xac, 0x84, 0xff, 0x17, 0xab, 0x83, 0xff, 0x16, 0xaa, 0x82, 0xff, 0x12, 0xa9, 0x7d, 0xff, 0x14, 0xab, 0x7e, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0c, 0xa5, 0x73, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x05, 0xa0, 0x6b, 0xff, 0x0f, 0xa9, 0x73, 0xff, 0x13, 0xb0, 0x78, 0xff, 0x17, 0xb6, 0x7c, 0xff, 0x14, 0xb5, 0x7a, 0xff, 0x0d, 0xaf, 0x72, 0xff, 0x05, 0xa8, 0x6a, 0xff, 0x08, 0xaf, 0x6d, 0xff, 0x05, 0xac, 0x67, 0xff, 0x05, 0xab, 0x64, 0xff, 0x08, 0xad, 0x64, 0xff, 0x04, 0xa7, 0x61, 0xff, 0x16, 0xb7, 0x75, 0xff, 0x12, 0xb3, 0x75, 0xff, 0x0b, 0xac, 0x72, 0xff, 0x0c, 0xaf, 0x76, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x0b, 0xa9, 0x71, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0c, 0xac, 0x75, 0xff, 0x0b, 0xae, 0x76, 0xff, 0x0b, 0xae, 0x77, 0xff, 0x0e, 0xae, 0x76, 0xff, 0x11, 0xab, 0x73, 0xff, 0x16, 0xab, 0x73, 0xff, 0x11, 0x9f, 0x68, 0xff, 0x0c, 0x96, 0x5f, 0xff, 0x09, 0x8f, 0x58, 0xff, 0x0b, 0x91, 0x59, 0xff, 0x0d, 0x92, 0x5b, 0xff, 0x06, 0x8a, 0x50, 0xff, 0x04, 0x88, 0x4e, 0xff, 0x05, 0x88, 0x4c, 0xff, 0x03, 0x85, 0x4b, 0xff, 0x02, 0x7f, 0x47, 0xff, 0x01, 0x77, 0x42, 0xff, 0x01, 0x75, 0x43, 0xff, 0x00, 0x74, 0x41, 0xff, 0x00, 0x74, 0x40, 0xff, 0x00, 0x75, 0x40, 0xff, 0x00, 0x78, 0x43, 0xff, 0x05, 0x7f, 0x4a, 0xff, 0x03, 0x7f, 0x49, 0xff, 0x00, 0x7a, 0x44, 0xff, 0x00, 0x7a, 0x44, 0xff, 0x01, 0x7d, 0x47, 0xff, 0x02, 0x80, 0x4a, 0xff, 0x05, 0x89, 0x51, 0xff, 0x06, 0x91, 0x57, 0xff, 0x08, 0x9a, 0x5f, 0xff, 0x0a, 0x9f, 0x64, 0xff, 0x0a, 0xa3, 0x66, 0xff, 0x0b, 0xa3, 0x65, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x0d, 0xa9, 0x71, 0xff, 0x0f, 0xab, 0x73, 0xff, 0x0c, 0xa6, 0x6c, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0x9d, 0x59, 0xff, 0x0d, 0x9c, 0x57, 0xff, 0x0c, 0x9b, 0x56, 0xff, 0x0c, 0x9c, 0x57, 0xff, 0x0b, 0x9b, 0x56, 0xff, 0x0c, 0x9d, 0x58, 0xff, 0x0b, 0x9a, 0x55, 0xff, 0x0a, 0x98, 0x53, 0xff, 0x0a, 0x96, 0x51, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x08, 0x94, 0x4f, 0xff, 0x09, 0x93, 0x4f, 0xff, 0x0c, 0x93, 0x4f, 0xff, 0x0b, 0x93, 0x4f, 0xff, 0x0c, 0x90, 0x4d, 0xff, 0x0d, 0x90, 0x4d, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x0a, 0x88, 0x46, 0xff, 0x0a, 0x86, 0x45, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x09, 0x83, 0x43, 0xff, 0x08, 0x80, 0x42, 0xff, 0x09, 0x7e, 0x42, 0xff, 0x07, 0x7a, 0x3f, 0xff, 0x07, 0x77, 0x3d, 0xff, 0x09, 0x74, 0x40, 0xff, 0x09, 0x6f, 0x45, 0xff, 0x15, 0x73, 0x6b, 0xff, 0x3a, 0x95, 0xae, 0xff, 0x3b, 0x9a, 0xc2, 0xff, 0x4c, 0xb4, 0xe5, 0xff, 0x4e, 0xc3, 0xec, 0xff, 0x3a, 0xb6, 0xdf, 0xff, 0x34, 0xb6, 0xdd, 0xff, 0x33, 0xbc, 0xdb, 0xff, 0x3d, 0xc5, 0xdc, 0xff, 0x55, 0xe9, 0xf5, 0xff, 0x63, 0xf0, 0xf0, 0xff, 0x13, 0x67, 0x4b, 0xff, 0x0c, 0x56, 0x20, 0xff, 0x28, 0x60, 0x3a, 0xff, 0x35, 0x5c, 0x53, 0xff, 0x1b, 0x4c, 0x60, 0xff, 0x16, 0x56, 0x87, 0xff, 0x13, 0x63, 0xa9, 0xff, 0x32, 0x8b, 0xcb, 0xff, 0x53, 0xba, 0xee, 0xff, 0x62, 0xd4, 0xfc, 0xff, 0xab, 0xf5, 0xfd, 0xff, + 0xac, 0xb6, 0xf4, 0xff, 0x3a, 0x50, 0xac, 0xff, 0x10, 0x25, 0xa5, 0xff, 0x13, 0x2c, 0xb7, 0xff, 0x18, 0x35, 0xb6, 0xff, 0x20, 0x3a, 0xc0, 0xff, 0x1d, 0x35, 0xc0, 0xff, 0x1d, 0x36, 0xc5, 0xff, 0x34, 0x53, 0xde, 0xff, 0x37, 0x5a, 0xda, 0xff, 0x48, 0x6a, 0xdb, 0xff, 0x6a, 0x83, 0xdf, 0xff, 0x98, 0xa8, 0xf4, 0xff, 0xad, 0xb3, 0xf2, 0xff, 0xb1, 0xb5, 0xee, 0xff, 0xaf, 0xb4, 0xee, 0xff, 0xb0, 0xb3, 0xed, 0xff, 0xb0, 0xb2, 0xed, 0xff, 0xa5, 0xb2, 0xe9, 0xff, 0x71, 0xa3, 0xbd, 0xff, 0x30, 0x8c, 0x86, 0xff, 0x14, 0x9c, 0x71, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x09, 0xa9, 0x69, 0xff, 0x06, 0xaa, 0x6a, 0xff, 0x05, 0xa8, 0x6d, 0xff, 0x09, 0xa6, 0x72, 0xff, 0x0a, 0xa6, 0x74, 0xff, 0x0a, 0xab, 0x72, 0xff, 0x0a, 0xad, 0x71, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x09, 0xab, 0x71, 0xff, 0x07, 0xab, 0x71, 0xff, 0x07, 0xab, 0x71, 0xff, 0x09, 0xad, 0x72, 0xff, 0x09, 0xad, 0x72, 0xff, 0x0a, 0xaf, 0x74, 0xff, 0x0c, 0xb1, 0x76, 0xff, 0x0b, 0xb2, 0x76, 0xff, 0x10, 0xb7, 0x7c, 0xff, 0x18, 0xbd, 0x85, 0xff, 0x19, 0xbd, 0x86, 0xff, 0x19, 0xba, 0x85, 0xff, 0x1a, 0xb8, 0x82, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x03, 0x9a, 0x62, 0xff, 0x06, 0x8c, 0x54, 0xff, 0x01, 0x7a, 0x46, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x01, 0x60, 0x31, 0xff, 0x02, 0x5a, 0x2c, 0xff, 0x03, 0x57, 0x2b, 0xff, 0x03, 0x59, 0x2c, 0xff, 0x02, 0x5b, 0x2d, 0xff, 0x01, 0x5f, 0x30, 0xff, 0x01, 0x60, 0x31, 0xff, 0x01, 0x60, 0x31, 0xff, 0x01, 0x5e, 0x30, 0xff, 0x02, 0x5c, 0x2f, 0xff, 0x04, 0x5b, 0x31, 0xff, 0x04, 0x5a, 0x30, 0xff, 0x02, 0x58, 0x2f, 0xff, 0x02, 0x59, 0x2e, 0xff, 0x02, 0x58, 0x2e, 0xff, 0x05, 0x5b, 0x30, 0xff, 0x03, 0x5a, 0x2f, 0xff, 0x01, 0x59, 0x2e, 0xff, 0x01, 0x5c, 0x30, 0xff, 0x01, 0x5f, 0x33, 0xff, 0x01, 0x60, 0x33, 0xff, 0x03, 0x67, 0x33, 0xff, 0x02, 0x6d, 0x39, 0xff, 0x01, 0x73, 0x3e, 0xff, 0x01, 0x76, 0x40, 0xff, 0x02, 0x85, 0x4d, 0xff, 0x0a, 0x97, 0x5e, 0xff, 0x15, 0xab, 0x72, 0xff, 0x11, 0xab, 0x71, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x0b, 0xa1, 0x6f, 0xff, 0x0d, 0xa3, 0x73, 0xff, 0x0f, 0xa6, 0x77, 0xff, 0x11, 0xa6, 0x78, 0xff, 0x0e, 0xa4, 0x77, 0xff, 0x0e, 0xa4, 0x76, 0xff, 0x11, 0xa3, 0x77, 0xff, 0x12, 0xa2, 0x76, 0xff, 0x13, 0xa4, 0x79, 0xff, 0x12, 0xa3, 0x7b, 0xff, 0x10, 0xa1, 0x79, 0xff, 0x0f, 0xa1, 0x79, 0xff, 0x10, 0xa2, 0x78, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x10, 0xa3, 0x78, 0xff, 0x0f, 0xa4, 0x76, 0xff, 0x12, 0xa7, 0x77, 0xff, 0x10, 0xa5, 0x76, 0xff, 0x0f, 0xa4, 0x75, 0xff, 0x11, 0xa6, 0x77, 0xff, 0x0e, 0xa6, 0x73, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0d, 0xab, 0x75, 0xff, 0x0a, 0xaa, 0x73, 0xff, 0x09, 0xaa, 0x71, 0xff, 0x08, 0xab, 0x71, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x0b, 0xac, 0x72, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0b, 0xab, 0x73, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xab, 0x73, 0xff, 0x0b, 0xaa, 0x73, 0xff, 0x0a, 0xa9, 0x73, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0c, 0xad, 0x75, 0xff, 0x0d, 0xae, 0x76, 0xff, 0x0e, 0xaf, 0x77, 0xff, 0x0e, 0xb0, 0x78, 0xff, 0x10, 0xb0, 0x79, 0xff, 0x13, 0xb2, 0x7c, 0xff, 0x18, 0xb5, 0x81, 0xff, 0x19, 0xb7, 0x84, 0xff, 0x19, 0xb8, 0x85, 0xff, 0x1a, 0xb9, 0x85, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x15, 0xb6, 0x81, 0xff, 0x11, 0xb6, 0x81, 0xff, 0x0f, 0xb6, 0x80, 0xff, 0x11, 0xb3, 0x7e, 0xff, 0x16, 0xb3, 0x7e, 0xff, 0x15, 0xac, 0x76, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x0a, 0x96, 0x62, 0xff, 0x04, 0x8e, 0x5a, 0xff, 0x01, 0x88, 0x51, 0xff, 0x01, 0x84, 0x4b, 0xff, 0x00, 0x7d, 0x45, 0xff, 0x00, 0x79, 0x42, 0xff, 0x01, 0x74, 0x3f, 0xff, 0x04, 0x74, 0x3f, 0xff, 0x03, 0x6f, 0x3c, 0xff, 0x03, 0x70, 0x3c, 0xff, 0x02, 0x70, 0x3d, 0xff, 0x03, 0x71, 0x40, 0xff, 0x03, 0x73, 0x41, 0xff, 0x04, 0x76, 0x43, 0xff, 0x05, 0x78, 0x44, 0xff, 0x03, 0x78, 0x43, 0xff, 0x01, 0x78, 0x42, 0xff, 0x01, 0x7b, 0x43, 0xff, 0x02, 0x7d, 0x45, 0xff, 0x00, 0x7f, 0x46, 0xff, 0x05, 0x89, 0x4f, 0xff, 0x07, 0x8f, 0x55, 0xff, 0x09, 0x97, 0x5c, 0xff, 0x0d, 0xa0, 0x66, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0f, 0xab, 0x6f, 0xff, 0x10, 0xaf, 0x74, 0xff, 0x11, 0xb4, 0x7a, 0xff, 0x14, 0xb8, 0x7f, 0xff, 0x12, 0xb8, 0x81, 0xff, 0x0e, 0xb4, 0x80, 0xff, 0x0d, 0xb3, 0x80, 0xff, 0x10, 0xb4, 0x82, 0xff, 0x11, 0xb3, 0x82, 0xff, 0x0f, 0xad, 0x7f, 0xff, 0x10, 0xad, 0x80, 0xff, 0x16, 0xb3, 0x86, 0xff, 0x19, 0xb5, 0x89, 0xff, 0x19, 0xb4, 0x89, 0xff, 0x18, 0xb2, 0x88, 0xff, 0x15, 0xad, 0x84, 0xff, 0x13, 0xaa, 0x82, 0xff, 0x15, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xab, 0x83, 0xff, 0x16, 0xaa, 0x82, 0xff, 0x15, 0xaa, 0x80, 0xff, 0x12, 0xa9, 0x7d, 0xff, 0x10, 0xa8, 0x79, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x0d, 0xa7, 0x72, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x04, 0xa0, 0x69, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x15, 0xb3, 0x7a, 0xff, 0x1a, 0xba, 0x80, 0xff, 0x13, 0xb3, 0x79, 0xff, 0x11, 0xb4, 0x78, 0xff, 0x03, 0xa6, 0x68, 0xff, 0x05, 0xab, 0x67, 0xff, 0x06, 0xad, 0x69, 0xff, 0x01, 0xa7, 0x62, 0xff, 0x0c, 0xaf, 0x69, 0xff, 0x07, 0xa6, 0x63, 0xff, 0x0c, 0xa6, 0x6a, 0xff, 0x17, 0xae, 0x76, 0xff, 0x16, 0xad, 0x77, 0xff, 0x15, 0xaf, 0x7b, 0xff, 0x10, 0xab, 0x77, 0xff, 0x0e, 0xa9, 0x75, 0xff, 0x12, 0xae, 0x79, 0xff, 0x13, 0xb1, 0x7d, 0xff, 0x12, 0xb1, 0x7d, 0xff, 0x10, 0xb1, 0x7d, 0xff, 0x0e, 0xad, 0x78, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x0e, 0xa2, 0x6b, 0xff, 0x0e, 0x98, 0x62, 0xff, 0x04, 0x80, 0x4c, 0xff, 0x01, 0x73, 0x41, 0xff, 0x01, 0x6e, 0x3b, 0xff, 0x01, 0x71, 0x3e, 0xff, 0x03, 0x76, 0x42, 0xff, 0x07, 0x7d, 0x47, 0xff, 0x06, 0x7b, 0x45, 0xff, 0x06, 0x7b, 0x44, 0xff, 0x07, 0x7a, 0x44, 0xff, 0x09, 0x79, 0x44, 0xff, 0x09, 0x76, 0x45, 0xff, 0x0a, 0x75, 0x46, 0xff, 0x05, 0x6f, 0x40, 0xff, 0x03, 0x6b, 0x3c, 0xff, 0x01, 0x69, 0x39, 0xff, 0x01, 0x6a, 0x3b, 0xff, 0x03, 0x6e, 0x3e, 0xff, 0x03, 0x6e, 0x3e, 0xff, 0x01, 0x6d, 0x3c, 0xff, 0x00, 0x6b, 0x3b, 0xff, 0x01, 0x6d, 0x3d, 0xff, 0x01, 0x70, 0x3d, 0xff, 0x01, 0x75, 0x42, 0xff, 0x00, 0x78, 0x43, 0xff, 0x02, 0x85, 0x4f, 0xff, 0x02, 0x8e, 0x56, 0xff, 0x09, 0x9c, 0x62, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x11, 0xa8, 0x6c, 0xff, 0x0f, 0xa6, 0x6c, 0xff, 0x10, 0xa8, 0x6f, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xaa, 0x73, 0xff, 0x0e, 0xaa, 0x73, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0a, 0x9d, 0x59, 0xff, 0x0d, 0x9b, 0x57, 0xff, 0x0c, 0x9b, 0x56, 0xff, 0x0c, 0x9c, 0x57, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x0c, 0x9d, 0x59, 0xff, 0x0b, 0x9b, 0x56, 0xff, 0x0a, 0x99, 0x54, 0xff, 0x0b, 0x96, 0x52, 0xff, 0x0a, 0x95, 0x51, 0xff, 0x08, 0x92, 0x4e, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x0b, 0x91, 0x4d, 0xff, 0x0b, 0x8f, 0x4c, 0xff, 0x0c, 0x8f, 0x4c, 0xff, 0x09, 0x8b, 0x48, 0xff, 0x09, 0x87, 0x46, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x09, 0x83, 0x43, 0xff, 0x08, 0x80, 0x42, 0xff, 0x08, 0x7d, 0x42, 0xff, 0x07, 0x78, 0x3e, 0xff, 0x08, 0x76, 0x3c, 0xff, 0x0a, 0x75, 0x41, 0xff, 0x09, 0x6c, 0x48, 0xff, 0x1b, 0x74, 0x6f, 0xff, 0x14, 0x6c, 0x71, 0xff, 0x21, 0x81, 0x88, 0xff, 0x27, 0x8b, 0xa3, 0xff, 0x3d, 0xa6, 0xc6, 0xff, 0x21, 0x8d, 0xb0, 0xff, 0x1b, 0x82, 0xa8, 0xff, 0x35, 0x9e, 0xc8, 0xff, 0x43, 0xad, 0xd7, 0xff, 0x31, 0xab, 0xd3, 0xff, 0x45, 0xca, 0xeb, 0xff, 0x3d, 0xa8, 0xa7, 0xff, 0x0a, 0x5a, 0x3c, 0xff, 0x35, 0x67, 0x4d, 0xff, 0x42, 0x73, 0x5e, 0xff, 0x1d, 0x5b, 0x4b, 0xff, 0x19, 0x58, 0x6b, 0xff, 0x1a, 0x5f, 0xa3, 0xff, 0x1b, 0x5e, 0xac, 0xff, 0x0f, 0x54, 0xa2, 0xff, 0x1e, 0x75, 0xc0, 0xff, 0x93, 0xca, 0xeb, 0xff, + 0x8f, 0x9b, 0xe8, 0xff, 0x1d, 0x35, 0x9c, 0xff, 0x10, 0x27, 0xab, 0xff, 0x1c, 0x35, 0xc1, 0xff, 0x18, 0x32, 0xb9, 0xff, 0x18, 0x31, 0xbc, 0xff, 0x18, 0x30, 0xbd, 0xff, 0x1e, 0x37, 0xc6, 0xff, 0x2d, 0x48, 0xd5, 0xff, 0x2c, 0x4a, 0xd1, 0xff, 0x39, 0x59, 0xd4, 0xff, 0x4b, 0x68, 0xd2, 0xff, 0x72, 0x88, 0xe3, 0xff, 0x9e, 0xad, 0xf8, 0xff, 0xa8, 0xb4, 0xf4, 0xff, 0xab, 0xb4, 0xee, 0xff, 0xac, 0xb2, 0xef, 0xff, 0xad, 0xb4, 0xee, 0xff, 0xaa, 0xb3, 0xeb, 0xff, 0xa2, 0xb2, 0xe4, 0xff, 0x6f, 0x9c, 0xbc, 0xff, 0x1b, 0x88, 0x7d, 0xff, 0x0f, 0x9c, 0x78, 0xff, 0x0d, 0xa1, 0x6f, 0xff, 0x08, 0xa5, 0x6b, 0xff, 0x07, 0xab, 0x6b, 0xff, 0x05, 0xa9, 0x6b, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x09, 0xab, 0x72, 0xff, 0x09, 0xad, 0x73, 0xff, 0x09, 0xac, 0x72, 0xff, 0x09, 0xab, 0x71, 0xff, 0x08, 0xac, 0x72, 0xff, 0x09, 0xad, 0x72, 0xff, 0x09, 0xae, 0x71, 0xff, 0x09, 0xae, 0x71, 0xff, 0x0a, 0xb1, 0x73, 0xff, 0x0e, 0xb4, 0x76, 0xff, 0x0e, 0xb4, 0x75, 0xff, 0x11, 0xb7, 0x7b, 0xff, 0x17, 0xbd, 0x84, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x17, 0xb5, 0x7f, 0xff, 0x13, 0xa9, 0x74, 0xff, 0x04, 0x93, 0x5c, 0xff, 0x01, 0x86, 0x50, 0xff, 0x05, 0x76, 0x41, 0xff, 0x00, 0x69, 0x37, 0xff, 0x02, 0x5e, 0x30, 0xff, 0x03, 0x55, 0x2b, 0xff, 0x06, 0x4e, 0x27, 0xff, 0x07, 0x4c, 0x26, 0xff, 0x05, 0x4a, 0x22, 0xff, 0x03, 0x4c, 0x23, 0xff, 0x00, 0x51, 0x27, 0xff, 0x02, 0x52, 0x29, 0xff, 0x01, 0x4f, 0x27, 0xff, 0x00, 0x4c, 0x24, 0xff, 0x00, 0x4b, 0x24, 0xff, 0x00, 0x48, 0x24, 0xff, 0x00, 0x46, 0x22, 0xff, 0x00, 0x47, 0x23, 0xff, 0x01, 0x48, 0x23, 0xff, 0x01, 0x47, 0x22, 0xff, 0x01, 0x47, 0x22, 0xff, 0x02, 0x4a, 0x25, 0xff, 0x02, 0x4b, 0x26, 0xff, 0x02, 0x4e, 0x27, 0xff, 0x04, 0x52, 0x2c, 0xff, 0x06, 0x55, 0x2e, 0xff, 0x04, 0x58, 0x2c, 0xff, 0x02, 0x5e, 0x2f, 0xff, 0x01, 0x63, 0x32, 0xff, 0x00, 0x64, 0x33, 0xff, 0x00, 0x70, 0x3c, 0xff, 0x02, 0x7e, 0x48, 0xff, 0x0a, 0x95, 0x5c, 0xff, 0x12, 0xa5, 0x6b, 0xff, 0x11, 0xa5, 0x6d, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0b, 0x9f, 0x6c, 0xff, 0x0e, 0xa2, 0x72, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x12, 0xa8, 0x79, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x13, 0xa6, 0x78, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x19, 0xa9, 0x7d, 0xff, 0x16, 0xa8, 0x7d, 0xff, 0x13, 0xa5, 0x7b, 0xff, 0x0f, 0xa2, 0x77, 0xff, 0x11, 0xa3, 0x78, 0xff, 0x12, 0xa6, 0x79, 0xff, 0x11, 0xa7, 0x78, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x13, 0xab, 0x76, 0xff, 0x13, 0xab, 0x76, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x09, 0xaa, 0x73, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x0b, 0xaa, 0x73, 0xff, 0x0e, 0xac, 0x75, 0xff, 0x0e, 0xaf, 0x77, 0xff, 0x10, 0xb1, 0x7a, 0xff, 0x10, 0xb3, 0x7b, 0xff, 0x11, 0xb4, 0x7d, 0xff, 0x12, 0xb5, 0x7d, 0xff, 0x14, 0xb5, 0x7f, 0xff, 0x17, 0xb7, 0x81, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x1a, 0xb8, 0x85, 0xff, 0x1a, 0xb7, 0x85, 0xff, 0x1a, 0xb7, 0x84, 0xff, 0x18, 0xb5, 0x82, 0xff, 0x18, 0xb6, 0x80, 0xff, 0x15, 0xb6, 0x80, 0xff, 0x13, 0xb4, 0x7d, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x09, 0x97, 0x62, 0xff, 0x05, 0x8c, 0x58, 0xff, 0x07, 0x86, 0x53, 0xff, 0x03, 0x7e, 0x4c, 0xff, 0x02, 0x7c, 0x47, 0xff, 0x02, 0x79, 0x43, 0xff, 0x01, 0x72, 0x3e, 0xff, 0x02, 0x6d, 0x3a, 0xff, 0x03, 0x6a, 0x37, 0xff, 0x03, 0x67, 0x34, 0xff, 0x03, 0x65, 0x33, 0xff, 0x02, 0x63, 0x33, 0xff, 0x00, 0x63, 0x33, 0xff, 0x01, 0x65, 0x37, 0xff, 0x01, 0x66, 0x37, 0xff, 0x01, 0x69, 0x39, 0xff, 0x02, 0x6d, 0x3b, 0xff, 0x01, 0x6e, 0x3b, 0xff, 0x00, 0x6f, 0x39, 0xff, 0x01, 0x71, 0x3b, 0xff, 0x03, 0x75, 0x40, 0xff, 0x01, 0x77, 0x40, 0xff, 0x00, 0x7a, 0x43, 0xff, 0x00, 0x7d, 0x45, 0xff, 0x01, 0x83, 0x49, 0xff, 0x04, 0x8d, 0x53, 0xff, 0x05, 0x95, 0x59, 0xff, 0x0a, 0x9d, 0x61, 0xff, 0x0f, 0xa7, 0x6c, 0xff, 0x13, 0xaf, 0x76, 0xff, 0x17, 0xb7, 0x7e, 0xff, 0x16, 0xb9, 0x83, 0xff, 0x12, 0xb8, 0x84, 0xff, 0x0f, 0xb7, 0x84, 0xff, 0x12, 0xb8, 0x85, 0xff, 0x14, 0xb8, 0x85, 0xff, 0x16, 0xb7, 0x87, 0xff, 0x1a, 0xb9, 0x8a, 0xff, 0x1c, 0xbb, 0x8c, 0xff, 0x1d, 0xba, 0x8d, 0xff, 0x1b, 0xb8, 0x8c, 0xff, 0x1c, 0xb7, 0x8c, 0xff, 0x18, 0xb2, 0x89, 0xff, 0x15, 0xaf, 0x86, 0xff, 0x15, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x83, 0xff, 0x14, 0xaa, 0x80, 0xff, 0x13, 0xaa, 0x7e, 0xff, 0x12, 0xa9, 0x7c, 0xff, 0x12, 0xa9, 0x7a, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x04, 0xa2, 0x6a, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x01, 0x9c, 0x64, 0xff, 0x03, 0xa0, 0x67, 0xff, 0x14, 0xb5, 0x7a, 0xff, 0x16, 0xb6, 0x7c, 0xff, 0x0f, 0xaf, 0x75, 0xff, 0x15, 0xb6, 0x7c, 0xff, 0x05, 0xa8, 0x6a, 0xff, 0x04, 0xa7, 0x64, 0xff, 0x0b, 0xaa, 0x69, 0xff, 0x0c, 0xa7, 0x68, 0xff, 0x14, 0xa8, 0x6d, 0xff, 0x1c, 0xae, 0x75, 0xff, 0x18, 0xa8, 0x73, 0xff, 0x18, 0xa9, 0x74, 0xff, 0x1b, 0xad, 0x7a, 0xff, 0x18, 0xae, 0x7e, 0xff, 0x15, 0xad, 0x7d, 0xff, 0x12, 0xad, 0x7b, 0xff, 0x15, 0xb3, 0x80, 0xff, 0x13, 0xb0, 0x7c, 0xff, 0x14, 0xaf, 0x7b, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x05, 0x9b, 0x66, 0xff, 0x08, 0x95, 0x5f, 0xff, 0x02, 0x84, 0x4e, 0xff, 0x01, 0x76, 0x42, 0xff, 0x00, 0x67, 0x37, 0xff, 0x00, 0x61, 0x33, 0xff, 0x00, 0x5b, 0x2f, 0xff, 0x00, 0x5c, 0x30, 0xff, 0x00, 0x5e, 0x31, 0xff, 0x01, 0x64, 0x36, 0xff, 0x01, 0x66, 0x36, 0xff, 0x01, 0x65, 0x35, 0xff, 0x02, 0x65, 0x36, 0xff, 0x06, 0x65, 0x37, 0xff, 0x07, 0x65, 0x38, 0xff, 0x08, 0x63, 0x39, 0xff, 0x08, 0x63, 0x3a, 0xff, 0x07, 0x61, 0x37, 0xff, 0x05, 0x60, 0x35, 0xff, 0x04, 0x5f, 0x35, 0xff, 0x04, 0x5f, 0x35, 0xff, 0x03, 0x60, 0x36, 0xff, 0x04, 0x62, 0x36, 0xff, 0x01, 0x5f, 0x34, 0xff, 0x03, 0x61, 0x36, 0xff, 0x03, 0x63, 0x36, 0xff, 0x00, 0x64, 0x36, 0xff, 0x00, 0x68, 0x38, 0xff, 0x08, 0x7c, 0x4a, 0xff, 0x08, 0x86, 0x52, 0xff, 0x08, 0x8f, 0x59, 0xff, 0x08, 0x95, 0x5d, 0xff, 0x0c, 0x9e, 0x65, 0xff, 0x13, 0xa6, 0x6e, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x10, 0xab, 0x75, 0xff, 0x0f, 0xac, 0x75, 0xff, 0x0e, 0xa9, 0x70, 0xff, 0x0d, 0xa6, 0x6a, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x09, 0x9e, 0x5c, 0xff, 0x09, 0x9c, 0x58, 0xff, 0x0b, 0x9b, 0x56, 0xff, 0x0c, 0x9b, 0x56, 0xff, 0x0b, 0x9c, 0x58, 0xff, 0x0c, 0x9e, 0x5a, 0xff, 0x0a, 0x9e, 0x5a, 0xff, 0x0a, 0x9b, 0x57, 0xff, 0x0a, 0x99, 0x55, 0xff, 0x0b, 0x96, 0x52, 0xff, 0x09, 0x94, 0x50, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0a, 0x8f, 0x4c, 0xff, 0x0b, 0x8e, 0x4b, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x09, 0x8a, 0x46, 0xff, 0x0a, 0x86, 0x46, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x07, 0x82, 0x44, 0xff, 0x08, 0x80, 0x43, 0xff, 0x09, 0x7b, 0x41, 0xff, 0x07, 0x77, 0x3d, 0xff, 0x08, 0x77, 0x3d, 0xff, 0x0e, 0x73, 0x3f, 0xff, 0x0f, 0x67, 0x44, 0xff, 0x0a, 0x55, 0x48, 0xff, 0x0d, 0x5a, 0x46, 0xff, 0x09, 0x5d, 0x45, 0xff, 0x06, 0x5a, 0x59, 0xff, 0x0e, 0x5d, 0x76, 0xff, 0x1a, 0x64, 0x8e, 0xff, 0x22, 0x64, 0x92, 0xff, 0x0e, 0x55, 0x87, 0xff, 0x21, 0x72, 0xa9, 0xff, 0x3c, 0x95, 0xd3, 0xff, 0x21, 0x8a, 0xc7, 0xff, 0x4e, 0xc0, 0xdc, 0xff, 0x20, 0x74, 0x72, 0xff, 0x41, 0x69, 0x5d, 0xff, 0x23, 0x54, 0x35, 0xff, 0x1e, 0x5a, 0x2e, 0xff, 0x18, 0x51, 0x45, 0xff, 0x1d, 0x5a, 0x8d, 0xff, 0x27, 0x60, 0xa9, 0xff, 0x36, 0x69, 0xb9, 0xff, 0x21, 0x65, 0xbd, 0xff, 0x72, 0x9a, 0xd1, 0xff, + 0x5f, 0x6d, 0xc8, 0xff, 0x12, 0x29, 0x9c, 0xff, 0x19, 0x2f, 0xb7, 0xff, 0x2b, 0x41, 0xcf, 0xff, 0x19, 0x2f, 0xb9, 0xff, 0x1a, 0x2f, 0xbf, 0xff, 0x19, 0x31, 0xc0, 0xff, 0x1f, 0x39, 0xc5, 0xff, 0x24, 0x3d, 0xca, 0xff, 0x27, 0x41, 0xcc, 0xff, 0x2c, 0x49, 0xce, 0xff, 0x3e, 0x5d, 0xd5, 0xff, 0x53, 0x6e, 0xd8, 0xff, 0x7f, 0x94, 0xef, 0xff, 0x9e, 0xad, 0xfa, 0xff, 0xa8, 0xb4, 0xf4, 0xff, 0xaa, 0xb3, 0xf3, 0xff, 0xac, 0xb4, 0xee, 0xff, 0xac, 0xb2, 0xec, 0xff, 0xac, 0xaf, 0xef, 0xff, 0x93, 0xab, 0xe4, 0xff, 0x38, 0x89, 0xa3, 0xff, 0x13, 0x89, 0x85, 0xff, 0x11, 0x9e, 0x7b, 0xff, 0x0a, 0xa2, 0x70, 0xff, 0x07, 0xaa, 0x6c, 0xff, 0x06, 0xa9, 0x6b, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x09, 0xab, 0x72, 0xff, 0x09, 0xad, 0x72, 0xff, 0x08, 0xac, 0x72, 0xff, 0x09, 0xac, 0x72, 0xff, 0x09, 0xad, 0x72, 0xff, 0x09, 0xae, 0x71, 0xff, 0x0a, 0xaf, 0x72, 0xff, 0x09, 0xaf, 0x72, 0xff, 0x0a, 0xb0, 0x72, 0xff, 0x0c, 0xb3, 0x73, 0xff, 0x0f, 0xb5, 0x74, 0xff, 0x0f, 0xb6, 0x79, 0xff, 0x16, 0xbd, 0x83, 0xff, 0x19, 0xbc, 0x84, 0xff, 0x17, 0xaf, 0x79, 0xff, 0x0a, 0x94, 0x5f, 0xff, 0x03, 0x80, 0x4c, 0xff, 0x01, 0x73, 0x40, 0xff, 0x03, 0x62, 0x34, 0xff, 0x01, 0x59, 0x2d, 0xff, 0x00, 0x51, 0x28, 0xff, 0x01, 0x4a, 0x25, 0xff, 0x05, 0x48, 0x24, 0xff, 0x06, 0x46, 0x23, 0xff, 0x04, 0x43, 0x20, 0xff, 0x03, 0x44, 0x21, 0xff, 0x01, 0x44, 0x21, 0xff, 0x01, 0x45, 0x21, 0xff, 0x01, 0x43, 0x20, 0xff, 0x01, 0x42, 0x1f, 0xff, 0x00, 0x43, 0x20, 0xff, 0x02, 0x42, 0x21, 0xff, 0x02, 0x42, 0x22, 0xff, 0x01, 0x42, 0x22, 0xff, 0x01, 0x42, 0x21, 0xff, 0x02, 0x43, 0x22, 0xff, 0x01, 0x41, 0x1f, 0xff, 0x02, 0x42, 0x21, 0xff, 0x01, 0x42, 0x20, 0xff, 0x01, 0x44, 0x22, 0xff, 0x02, 0x48, 0x26, 0xff, 0x03, 0x4b, 0x28, 0xff, 0x06, 0x53, 0x2c, 0xff, 0x04, 0x56, 0x2d, 0xff, 0x01, 0x57, 0x2c, 0xff, 0x00, 0x58, 0x2c, 0xff, 0x02, 0x64, 0x35, 0xff, 0x08, 0x73, 0x42, 0xff, 0x05, 0x83, 0x4c, 0xff, 0x0a, 0x93, 0x5b, 0xff, 0x14, 0xa5, 0x6b, 0xff, 0x12, 0xa5, 0x6e, 0xff, 0x0c, 0xa0, 0x6b, 0xff, 0x10, 0xa4, 0x72, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x10, 0xa8, 0x77, 0xff, 0x0f, 0xa8, 0x77, 0xff, 0x10, 0xa9, 0x78, 0xff, 0x0e, 0xa1, 0x71, 0xff, 0x0f, 0xa0, 0x73, 0xff, 0x16, 0xa7, 0x7b, 0xff, 0x13, 0xa4, 0x78, 0xff, 0x17, 0xaa, 0x7e, 0xff, 0x0e, 0xa1, 0x74, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x12, 0xa6, 0x77, 0xff, 0x10, 0xa8, 0x75, 0xff, 0x11, 0xaa, 0x74, 0xff, 0x14, 0xaf, 0x75, 0xff, 0x10, 0xab, 0x72, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x0b, 0xaa, 0x70, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0b, 0xaa, 0x72, 0xff, 0x0c, 0xad, 0x73, 0xff, 0x0c, 0xad, 0x73, 0xff, 0x0b, 0xac, 0x72, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x09, 0xab, 0x72, 0xff, 0x0b, 0xac, 0x74, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x09, 0xaa, 0x73, 0xff, 0x0b, 0xab, 0x75, 0xff, 0x0f, 0xad, 0x76, 0xff, 0x0e, 0xad, 0x76, 0xff, 0x10, 0xae, 0x78, 0xff, 0x12, 0xb1, 0x7a, 0xff, 0x12, 0xb5, 0x7e, 0xff, 0x13, 0xb6, 0x7f, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x15, 0xb9, 0x82, 0xff, 0x17, 0xb8, 0x82, 0xff, 0x18, 0xb8, 0x83, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x1a, 0xb7, 0x85, 0xff, 0x1a, 0xb7, 0x85, 0xff, 0x1c, 0xb7, 0x85, 0xff, 0x19, 0xb5, 0x80, 0xff, 0x15, 0xb0, 0x7b, 0xff, 0x11, 0xa9, 0x73, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x04, 0x94, 0x5e, 0xff, 0x01, 0x8b, 0x55, 0xff, 0x02, 0x85, 0x51, 0xff, 0x05, 0x81, 0x4e, 0xff, 0x0c, 0x82, 0x4f, 0xff, 0x03, 0x76, 0x42, 0xff, 0x01, 0x70, 0x3d, 0xff, 0x03, 0x6f, 0x3c, 0xff, 0x04, 0x6a, 0x39, 0xff, 0x04, 0x65, 0x35, 0xff, 0x04, 0x61, 0x31, 0xff, 0x02, 0x5c, 0x2e, 0xff, 0x02, 0x5c, 0x2e, 0xff, 0x02, 0x5b, 0x2e, 0xff, 0x02, 0x5b, 0x2f, 0xff, 0x00, 0x5b, 0x2f, 0xff, 0x01, 0x5d, 0x31, 0xff, 0x01, 0x5f, 0x32, 0xff, 0x01, 0x62, 0x33, 0xff, 0x01, 0x64, 0x35, 0xff, 0x00, 0x66, 0x33, 0xff, 0x01, 0x67, 0x34, 0xff, 0x03, 0x6d, 0x39, 0xff, 0x03, 0x70, 0x3b, 0xff, 0x04, 0x74, 0x40, 0xff, 0x03, 0x76, 0x41, 0xff, 0x00, 0x7a, 0x42, 0xff, 0x00, 0x7d, 0x44, 0xff, 0x01, 0x85, 0x4a, 0xff, 0x07, 0x90, 0x54, 0xff, 0x0f, 0x9f, 0x65, 0xff, 0x16, 0xac, 0x72, 0xff, 0x16, 0xb1, 0x79, 0xff, 0x16, 0xb5, 0x7e, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x14, 0xb9, 0x85, 0xff, 0x12, 0xb7, 0x84, 0xff, 0x15, 0xba, 0x86, 0xff, 0x1b, 0xbd, 0x8b, 0xff, 0x1e, 0xbf, 0x8f, 0xff, 0x1c, 0xbd, 0x8e, 0xff, 0x1b, 0xba, 0x8c, 0xff, 0x1b, 0xb8, 0x8b, 0xff, 0x1c, 0xb9, 0x8d, 0xff, 0x1d, 0xb9, 0x8f, 0xff, 0x1a, 0xb5, 0x8c, 0xff, 0x19, 0xb1, 0x88, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x17, 0xac, 0x83, 0xff, 0x16, 0xac, 0x82, 0xff, 0x14, 0xaa, 0x7f, 0xff, 0x12, 0xaa, 0x7e, 0xff, 0x0f, 0xa9, 0x7b, 0xff, 0x0f, 0xa9, 0x78, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x05, 0xa5, 0x6b, 0xff, 0x08, 0xaa, 0x6f, 0xff, 0x05, 0xa5, 0x6b, 0xff, 0x02, 0xa2, 0x68, 0xff, 0x0d, 0xae, 0x74, 0xff, 0x10, 0xb0, 0x76, 0xff, 0x0f, 0xaf, 0x75, 0xff, 0x14, 0xb3, 0x7b, 0xff, 0x09, 0xa9, 0x6d, 0xff, 0x0e, 0xad, 0x6a, 0xff, 0x11, 0xa5, 0x67, 0xff, 0x1f, 0xa8, 0x70, 0xff, 0x17, 0x98, 0x65, 0xff, 0x28, 0xa6, 0x78, 0xff, 0x22, 0xa8, 0x78, 0xff, 0x18, 0xa5, 0x74, 0xff, 0x17, 0xab, 0x79, 0xff, 0x13, 0xaa, 0x79, 0xff, 0x15, 0xae, 0x7c, 0xff, 0x16, 0xb2, 0x7f, 0xff, 0x16, 0xb4, 0x7f, 0xff, 0x14, 0xb0, 0x7a, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0a, 0x9a, 0x64, 0xff, 0x09, 0x92, 0x5c, 0xff, 0x09, 0x88, 0x52, 0xff, 0x01, 0x73, 0x40, 0xff, 0x01, 0x68, 0x37, 0xff, 0x03, 0x5f, 0x33, 0xff, 0x03, 0x59, 0x2e, 0xff, 0x01, 0x54, 0x2b, 0xff, 0x00, 0x52, 0x2a, 0xff, 0x00, 0x51, 0x2a, 0xff, 0x00, 0x53, 0x2b, 0xff, 0x02, 0x58, 0x2f, 0xff, 0x03, 0x59, 0x2f, 0xff, 0x04, 0x59, 0x2f, 0xff, 0x02, 0x56, 0x2c, 0xff, 0x01, 0x53, 0x2a, 0xff, 0x01, 0x50, 0x29, 0xff, 0x01, 0x4f, 0x2b, 0xff, 0x03, 0x52, 0x2b, 0xff, 0x03, 0x52, 0x2c, 0xff, 0x03, 0x52, 0x2c, 0xff, 0x02, 0x51, 0x2c, 0xff, 0x01, 0x51, 0x2b, 0xff, 0x04, 0x54, 0x2e, 0xff, 0x02, 0x53, 0x2c, 0xff, 0x04, 0x56, 0x2f, 0xff, 0x03, 0x5a, 0x30, 0xff, 0x02, 0x5c, 0x30, 0xff, 0x00, 0x5c, 0x30, 0xff, 0x04, 0x69, 0x3a, 0xff, 0x09, 0x76, 0x46, 0xff, 0x0e, 0x87, 0x55, 0xff, 0x0a, 0x8c, 0x58, 0xff, 0x08, 0x90, 0x5b, 0xff, 0x0a, 0x98, 0x61, 0xff, 0x15, 0xa8, 0x72, 0xff, 0x17, 0xad, 0x78, 0xff, 0x10, 0xa9, 0x74, 0xff, 0x0f, 0xaa, 0x74, 0xff, 0x0e, 0xaa, 0x70, 0xff, 0x0d, 0xa7, 0x6a, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0xa0, 0x60, 0xff, 0x0a, 0x9f, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x08, 0x9d, 0x5b, 0xff, 0x08, 0x9b, 0x57, 0xff, 0x0a, 0x9a, 0x55, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x0a, 0x9c, 0x58, 0xff, 0x0c, 0x9f, 0x5d, 0xff, 0x08, 0x9c, 0x5b, 0xff, 0x08, 0x9a, 0x57, 0xff, 0x09, 0x99, 0x54, 0xff, 0x09, 0x96, 0x51, 0xff, 0x09, 0x93, 0x4f, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x09, 0x91, 0x4d, 0xff, 0x0a, 0x8f, 0x4c, 0xff, 0x0a, 0x8e, 0x4b, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x0a, 0x8c, 0x49, 0xff, 0x09, 0x89, 0x46, 0xff, 0x0b, 0x87, 0x46, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x0a, 0x84, 0x44, 0xff, 0x07, 0x80, 0x43, 0xff, 0x08, 0x80, 0x43, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x07, 0x78, 0x3e, 0xff, 0x09, 0x77, 0x3e, 0xff, 0x0c, 0x74, 0x40, 0xff, 0x0d, 0x6a, 0x3f, 0xff, 0x07, 0x59, 0x38, 0xff, 0x11, 0x5f, 0x3e, 0xff, 0x0e, 0x5d, 0x41, 0xff, 0x08, 0x5b, 0x49, 0xff, 0x1d, 0x67, 0x71, 0xff, 0x15, 0x51, 0x84, 0xff, 0x18, 0x4c, 0x81, 0xff, 0x22, 0x62, 0x93, 0xff, 0x0f, 0x5c, 0x92, 0xff, 0x1d, 0x66, 0xa7, 0xff, 0x33, 0x85, 0xcb, 0xff, 0x43, 0xae, 0xda, 0xff, 0x30, 0x84, 0x91, 0xff, 0x18, 0x41, 0x38, 0xff, 0x0a, 0x34, 0x19, 0xff, 0x0f, 0x3a, 0x11, 0xff, 0x11, 0x39, 0x25, 0xff, 0x16, 0x48, 0x68, 0xff, 0x14, 0x49, 0x80, 0xff, 0x27, 0x5a, 0x99, 0xff, 0x2b, 0x70, 0xb6, 0xff, 0x7c, 0xad, 0xda, 0xff, + 0x29, 0x33, 0x9f, 0xff, 0x11, 0x25, 0xa6, 0xff, 0x15, 0x29, 0xb7, 0xff, 0x1d, 0x30, 0xbe, 0xff, 0x1f, 0x30, 0xbe, 0xff, 0x1c, 0x2d, 0xc0, 0xff, 0x1a, 0x30, 0xbf, 0xff, 0x19, 0x34, 0xbd, 0xff, 0x26, 0x3d, 0xc8, 0xff, 0x24, 0x3c, 0xc9, 0xff, 0x24, 0x3f, 0xcc, 0xff, 0x28, 0x45, 0xcb, 0xff, 0x38, 0x56, 0xd0, 0xff, 0x54, 0x6d, 0xd9, 0xff, 0x7d, 0x8f, 0xeb, 0xff, 0x9e, 0xab, 0xf1, 0xff, 0xa6, 0xb2, 0xf0, 0xff, 0xb0, 0xb5, 0xf0, 0xff, 0xb4, 0xb4, 0xf3, 0xff, 0xaa, 0xb0, 0xf7, 0xff, 0x99, 0xb1, 0xf7, 0xff, 0x54, 0x87, 0xc8, 0xff, 0x14, 0x69, 0x8c, 0xff, 0x0d, 0x92, 0x7d, 0xff, 0x0e, 0xa0, 0x79, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x06, 0xa9, 0x6c, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x08, 0xac, 0x70, 0xff, 0x08, 0xad, 0x6f, 0xff, 0x09, 0xad, 0x73, 0xff, 0x0a, 0xae, 0x74, 0xff, 0x09, 0xad, 0x73, 0xff, 0x09, 0xae, 0x71, 0xff, 0x0a, 0xaf, 0x72, 0xff, 0x09, 0xaf, 0x72, 0xff, 0x0a, 0xb1, 0x73, 0xff, 0x0d, 0xb4, 0x74, 0xff, 0x10, 0xb6, 0x75, 0xff, 0x0f, 0xb6, 0x78, 0xff, 0x13, 0xba, 0x80, 0xff, 0x16, 0xb6, 0x7e, 0xff, 0x0e, 0x9e, 0x69, 0xff, 0x02, 0x7f, 0x4d, 0xff, 0x03, 0x6e, 0x3a, 0xff, 0x04, 0x63, 0x32, 0xff, 0x05, 0x56, 0x2d, 0xff, 0x00, 0x4c, 0x26, 0xff, 0x00, 0x44, 0x21, 0xff, 0x01, 0x42, 0x22, 0xff, 0x02, 0x42, 0x23, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x3d, 0x1f, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3d, 0x20, 0xff, 0x01, 0x3d, 0x20, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x00, 0x3e, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x01, 0x3e, 0x1f, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x42, 0x22, 0xff, 0x00, 0x44, 0x23, 0xff, 0x01, 0x4a, 0x27, 0xff, 0x01, 0x4e, 0x29, 0xff, 0x02, 0x4f, 0x29, 0xff, 0x02, 0x53, 0x2a, 0xff, 0x02, 0x5b, 0x2e, 0xff, 0x02, 0x70, 0x3e, 0xff, 0x02, 0x80, 0x4a, 0xff, 0x09, 0x98, 0x5f, 0xff, 0x14, 0xa6, 0x6d, 0xff, 0x0f, 0xa2, 0x6c, 0xff, 0x11, 0xa5, 0x71, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xa8, 0x76, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x14, 0xae, 0x7c, 0xff, 0x0e, 0xa1, 0x71, 0xff, 0x0d, 0x9e, 0x6f, 0xff, 0x15, 0xa6, 0x7a, 0xff, 0x12, 0xa3, 0x77, 0xff, 0x19, 0xac, 0x7f, 0xff, 0x0e, 0xa3, 0x75, 0xff, 0x15, 0xa9, 0x79, 0xff, 0x17, 0xad, 0x7c, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x16, 0xb2, 0x7a, 0xff, 0x12, 0xb0, 0x73, 0xff, 0x06, 0xa3, 0x66, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0b, 0xa9, 0x70, 0xff, 0x0c, 0xac, 0x72, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0e, 0xac, 0x74, 0xff, 0x0e, 0xac, 0x73, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x09, 0xab, 0x71, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x0b, 0xab, 0x74, 0xff, 0x0e, 0xae, 0x77, 0xff, 0x10, 0xb0, 0x7a, 0xff, 0x13, 0xb0, 0x7c, 0xff, 0x13, 0xb0, 0x7c, 0xff, 0x13, 0xb2, 0x7d, 0xff, 0x15, 0xb4, 0x80, 0xff, 0x17, 0xb9, 0x84, 0xff, 0x18, 0xba, 0x85, 0xff, 0x16, 0xba, 0x85, 0xff, 0x16, 0xb9, 0x84, 0xff, 0x18, 0xb9, 0x83, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x19, 0xb8, 0x84, 0xff, 0x1a, 0xb8, 0x85, 0xff, 0x1b, 0xb7, 0x86, 0xff, 0x1c, 0xb7, 0x84, 0xff, 0x15, 0xaf, 0x7a, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x0b, 0x98, 0x63, 0xff, 0x07, 0x8e, 0x59, 0xff, 0x03, 0x86, 0x51, 0xff, 0x06, 0x85, 0x50, 0xff, 0x05, 0x7e, 0x49, 0xff, 0x02, 0x76, 0x42, 0xff, 0x03, 0x70, 0x3c, 0xff, 0x01, 0x6c, 0x39, 0xff, 0x02, 0x68, 0x37, 0xff, 0x01, 0x63, 0x35, 0xff, 0x03, 0x5f, 0x33, 0xff, 0x05, 0x5d, 0x31, 0xff, 0x03, 0x58, 0x2d, 0xff, 0x02, 0x54, 0x2b, 0xff, 0x02, 0x54, 0x2b, 0xff, 0x01, 0x53, 0x2b, 0xff, 0x04, 0x57, 0x2f, 0xff, 0x05, 0x57, 0x2f, 0xff, 0x04, 0x59, 0x2f, 0xff, 0x04, 0x5b, 0x30, 0xff, 0x03, 0x5c, 0x30, 0xff, 0x03, 0x5f, 0x31, 0xff, 0x01, 0x5f, 0x2f, 0xff, 0x01, 0x60, 0x2f, 0xff, 0x03, 0x65, 0x35, 0xff, 0x03, 0x68, 0x37, 0xff, 0x03, 0x6b, 0x38, 0xff, 0x02, 0x6c, 0x38, 0xff, 0x02, 0x73, 0x3c, 0xff, 0x00, 0x76, 0x3e, 0xff, 0x00, 0x7b, 0x40, 0xff, 0x02, 0x7f, 0x43, 0xff, 0x07, 0x8d, 0x52, 0xff, 0x12, 0xa0, 0x68, 0xff, 0x16, 0xab, 0x74, 0xff, 0x19, 0xb2, 0x7d, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x16, 0xba, 0x86, 0xff, 0x18, 0xbb, 0x87, 0xff, 0x1b, 0xbd, 0x8a, 0xff, 0x1b, 0xbc, 0x8c, 0xff, 0x1b, 0xbc, 0x8c, 0xff, 0x1a, 0xba, 0x8b, 0xff, 0x1c, 0xbb, 0x8e, 0xff, 0x1f, 0xbc, 0x90, 0xff, 0x1e, 0xbb, 0x90, 0xff, 0x1c, 0xb8, 0x8f, 0xff, 0x1d, 0xb7, 0x8e, 0xff, 0x1c, 0xb1, 0x89, 0xff, 0x18, 0xad, 0x85, 0xff, 0x18, 0xad, 0x85, 0xff, 0x17, 0xac, 0x84, 0xff, 0x17, 0xac, 0x84, 0xff, 0x16, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xab, 0x81, 0xff, 0x14, 0xab, 0x7f, 0xff, 0x12, 0xaa, 0x7e, 0xff, 0x10, 0xaa, 0x7d, 0xff, 0x0e, 0xa8, 0x79, 0xff, 0x0c, 0xa8, 0x75, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x0c, 0xac, 0x71, 0xff, 0x0c, 0xb0, 0x73, 0xff, 0x0e, 0xb2, 0x76, 0xff, 0x0d, 0xb0, 0x75, 0xff, 0x0d, 0xae, 0x74, 0xff, 0x0d, 0xad, 0x74, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x12, 0xb0, 0x74, 0xff, 0x10, 0xa8, 0x68, 0xff, 0x15, 0x9d, 0x64, 0xff, 0x3c, 0xb2, 0x82, 0xff, 0x4f, 0xb8, 0x90, 0xff, 0x4f, 0xba, 0x94, 0xff, 0x24, 0x9f, 0x76, 0xff, 0x18, 0xa5, 0x77, 0xff, 0x1a, 0xb3, 0x81, 0xff, 0x1b, 0xb3, 0x82, 0xff, 0x16, 0xb2, 0x7f, 0xff, 0x14, 0xb5, 0x7f, 0xff, 0x0e, 0xae, 0x77, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x09, 0x98, 0x60, 0xff, 0x06, 0x8c, 0x54, 0xff, 0x04, 0x7e, 0x47, 0xff, 0x02, 0x71, 0x3c, 0xff, 0x01, 0x65, 0x34, 0xff, 0x03, 0x5e, 0x30, 0xff, 0x04, 0x54, 0x2a, 0xff, 0x04, 0x4d, 0x26, 0xff, 0x03, 0x4b, 0x26, 0xff, 0x00, 0x49, 0x26, 0xff, 0x00, 0x48, 0x25, 0xff, 0x00, 0x49, 0x27, 0xff, 0x02, 0x4b, 0x28, 0xff, 0x02, 0x4b, 0x27, 0xff, 0x01, 0x49, 0x23, 0xff, 0x00, 0x46, 0x21, 0xff, 0x00, 0x47, 0x23, 0xff, 0x00, 0x47, 0x24, 0xff, 0x00, 0x46, 0x23, 0xff, 0x00, 0x44, 0x22, 0xff, 0x00, 0x45, 0x23, 0xff, 0x00, 0x46, 0x24, 0xff, 0x00, 0x45, 0x24, 0xff, 0x00, 0x45, 0x23, 0xff, 0x01, 0x46, 0x25, 0xff, 0x01, 0x46, 0x25, 0xff, 0x03, 0x4b, 0x27, 0xff, 0x01, 0x4d, 0x26, 0xff, 0x03, 0x53, 0x2b, 0xff, 0x04, 0x55, 0x2c, 0xff, 0x03, 0x59, 0x2e, 0xff, 0x01, 0x5d, 0x31, 0xff, 0x0b, 0x75, 0x46, 0xff, 0x10, 0x84, 0x53, 0xff, 0x12, 0x8d, 0x5b, 0xff, 0x09, 0x92, 0x5e, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0d, 0xa2, 0x6e, 0xff, 0x12, 0xab, 0x76, 0xff, 0x0e, 0xa9, 0x73, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x0a, 0xa1, 0x62, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x0a, 0x9f, 0x5e, 0xff, 0x09, 0x9e, 0x5c, 0xff, 0x07, 0x9c, 0x5a, 0xff, 0x07, 0x9b, 0x57, 0xff, 0x08, 0x9a, 0x55, 0xff, 0x09, 0x9b, 0x56, 0xff, 0x08, 0x9b, 0x57, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x06, 0x9b, 0x5a, 0xff, 0x07, 0x9a, 0x56, 0xff, 0x09, 0x98, 0x54, 0xff, 0x07, 0x96, 0x50, 0xff, 0x08, 0x93, 0x4e, 0xff, 0x07, 0x91, 0x4d, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x0a, 0x8e, 0x4b, 0xff, 0x09, 0x8d, 0x4a, 0xff, 0x0a, 0x8d, 0x4a, 0xff, 0x09, 0x8b, 0x48, 0xff, 0x09, 0x89, 0x46, 0xff, 0x0c, 0x88, 0x47, 0xff, 0x0b, 0x85, 0x45, 0xff, 0x09, 0x84, 0x44, 0xff, 0x07, 0x80, 0x42, 0xff, 0x07, 0x7e, 0x42, 0xff, 0x08, 0x7a, 0x3f, 0xff, 0x08, 0x78, 0x3e, 0xff, 0x09, 0x77, 0x3e, 0xff, 0x08, 0x75, 0x40, 0xff, 0x0b, 0x6e, 0x40, 0xff, 0x0c, 0x63, 0x3a, 0xff, 0x13, 0x61, 0x3b, 0xff, 0x0f, 0x5c, 0x3c, 0xff, 0x04, 0x57, 0x35, 0xff, 0x0b, 0x57, 0x4e, 0xff, 0x29, 0x63, 0x8a, 0xff, 0x1c, 0x4f, 0x7b, 0xff, 0x0c, 0x4a, 0x77, 0xff, 0x13, 0x5c, 0x8e, 0xff, 0x1f, 0x62, 0x9b, 0xff, 0x15, 0x5d, 0x9e, 0xff, 0x3e, 0xa4, 0xd6, 0xff, 0x46, 0xa5, 0xb7, 0xff, 0x03, 0x35, 0x28, 0xff, 0x0d, 0x40, 0x24, 0xff, 0x08, 0x3c, 0x17, 0xff, 0x0a, 0x32, 0x17, 0xff, 0x11, 0x35, 0x3f, 0xff, 0x12, 0x39, 0x5d, 0xff, 0x17, 0x39, 0x67, 0xff, 0x0a, 0x3e, 0x72, 0xff, 0x75, 0x9f, 0xc6, 0xff, + 0x19, 0x24, 0xa1, 0xff, 0x10, 0x23, 0xac, 0xff, 0x12, 0x24, 0xb3, 0xff, 0x1c, 0x2f, 0xbb, 0xff, 0x1d, 0x31, 0xbe, 0xff, 0x1f, 0x31, 0xbe, 0xff, 0x26, 0x3e, 0xc3, 0xff, 0x2e, 0x4c, 0xcc, 0xff, 0x30, 0x49, 0xcf, 0xff, 0x28, 0x3e, 0xcb, 0xff, 0x26, 0x3d, 0xcd, 0xff, 0x22, 0x3d, 0xcc, 0xff, 0x26, 0x43, 0xca, 0xff, 0x30, 0x4c, 0xc9, 0xff, 0x4d, 0x65, 0xd5, 0xff, 0x76, 0x87, 0xe5, 0xff, 0x84, 0x94, 0xe7, 0xff, 0x90, 0x9c, 0xe7, 0xff, 0x95, 0x9e, 0xec, 0xff, 0x8e, 0x9b, 0xf4, 0xff, 0x75, 0x8b, 0xe9, 0xff, 0x4f, 0x6f, 0xd3, 0xff, 0x24, 0x5d, 0xab, 0xff, 0x08, 0x77, 0x80, 0xff, 0x10, 0x9c, 0x7b, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x09, 0xa9, 0x6c, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x07, 0xab, 0x6f, 0xff, 0x07, 0xad, 0x6d, 0xff, 0x0a, 0xae, 0x73, 0xff, 0x0b, 0xaf, 0x74, 0xff, 0x0a, 0xae, 0x73, 0xff, 0x08, 0xad, 0x70, 0xff, 0x09, 0xaf, 0x72, 0xff, 0x0a, 0xb0, 0x73, 0xff, 0x11, 0xb7, 0x7a, 0xff, 0x15, 0xbb, 0x7c, 0xff, 0x13, 0xb6, 0x78, 0xff, 0x0c, 0xb6, 0x77, 0xff, 0x0b, 0xb4, 0x77, 0xff, 0x0c, 0xab, 0x70, 0xff, 0x03, 0x8a, 0x53, 0xff, 0x01, 0x72, 0x40, 0xff, 0x00, 0x58, 0x2a, 0xff, 0x03, 0x4f, 0x26, 0xff, 0x04, 0x47, 0x24, 0xff, 0x02, 0x42, 0x22, 0xff, 0x02, 0x3d, 0x1f, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x00, 0x38, 0x1c, 0xff, 0x00, 0x36, 0x1b, 0xff, 0x01, 0x39, 0x1e, 0xff, 0x02, 0x38, 0x1c, 0xff, 0x02, 0x39, 0x1e, 0xff, 0x02, 0x38, 0x1d, 0xff, 0x02, 0x37, 0x1c, 0xff, 0x01, 0x36, 0x1b, 0xff, 0x01, 0x36, 0x19, 0xff, 0x01, 0x37, 0x19, 0xff, 0x01, 0x38, 0x1b, 0xff, 0x01, 0x38, 0x1b, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x00, 0x38, 0x1a, 0xff, 0x00, 0x3a, 0x1c, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x01, 0x3f, 0x21, 0xff, 0x00, 0x3f, 0x22, 0xff, 0x01, 0x40, 0x22, 0xff, 0x02, 0x45, 0x25, 0xff, 0x02, 0x46, 0x25, 0xff, 0x01, 0x48, 0x24, 0xff, 0x00, 0x4e, 0x27, 0xff, 0x00, 0x5d, 0x31, 0xff, 0x00, 0x6e, 0x3d, 0xff, 0x02, 0x8b, 0x52, 0xff, 0x13, 0xa4, 0x6c, 0xff, 0x12, 0xa4, 0x6d, 0xff, 0x11, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x07, 0xa4, 0x6e, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x14, 0xa9, 0x74, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x17, 0xab, 0x76, 0xff, 0x14, 0xa8, 0x75, 0xff, 0x16, 0xae, 0x7b, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x11, 0xa9, 0x76, 0xff, 0x17, 0xb1, 0x7b, 0xff, 0x0e, 0xad, 0x73, 0xff, 0x17, 0xb9, 0x7b, 0xff, 0x0f, 0xaf, 0x6f, 0xff, 0x03, 0xa1, 0x61, 0xff, 0x10, 0xad, 0x71, 0xff, 0x12, 0xae, 0x74, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x08, 0xa6, 0x70, 0xff, 0x0c, 0xab, 0x74, 0xff, 0x0d, 0xac, 0x74, 0xff, 0x0f, 0xac, 0x75, 0xff, 0x0e, 0xab, 0x73, 0xff, 0x0b, 0xaa, 0x73, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x0a, 0xaa, 0x73, 0xff, 0x0b, 0xab, 0x75, 0xff, 0x0e, 0xae, 0x77, 0xff, 0x0f, 0xaf, 0x79, 0xff, 0x12, 0xb2, 0x7c, 0xff, 0x12, 0xb2, 0x7d, 0xff, 0x13, 0xb3, 0x7f, 0xff, 0x15, 0xb3, 0x80, 0xff, 0x15, 0xb6, 0x82, 0xff, 0x17, 0xb8, 0x83, 0xff, 0x18, 0xba, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x17, 0xba, 0x85, 0xff, 0x16, 0xb9, 0x83, 0xff, 0x16, 0xb8, 0x83, 0xff, 0x18, 0xb7, 0x84, 0xff, 0x19, 0xb8, 0x85, 0xff, 0x1a, 0xb7, 0x84, 0xff, 0x1d, 0xb7, 0x86, 0xff, 0x19, 0xaf, 0x7d, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x07, 0x99, 0x63, 0xff, 0x09, 0x8d, 0x58, 0xff, 0x08, 0x84, 0x50, 0xff, 0x07, 0x7e, 0x4b, 0xff, 0x05, 0x77, 0x44, 0xff, 0x03, 0x6f, 0x3d, 0xff, 0x05, 0x6d, 0x3d, 0xff, 0x04, 0x67, 0x38, 0xff, 0x01, 0x61, 0x33, 0xff, 0x01, 0x59, 0x2f, 0xff, 0x01, 0x55, 0x2d, 0xff, 0x01, 0x54, 0x2c, 0xff, 0x02, 0x51, 0x2c, 0xff, 0x02, 0x50, 0x2b, 0xff, 0x02, 0x4f, 0x2a, 0xff, 0x01, 0x4d, 0x2b, 0xff, 0x01, 0x4d, 0x2b, 0xff, 0x04, 0x4e, 0x2c, 0xff, 0x05, 0x4e, 0x2b, 0xff, 0x03, 0x4e, 0x2a, 0xff, 0x02, 0x4f, 0x2a, 0xff, 0x04, 0x53, 0x2c, 0xff, 0x05, 0x58, 0x2e, 0xff, 0x04, 0x5a, 0x2f, 0xff, 0x04, 0x5a, 0x30, 0xff, 0x05, 0x5f, 0x32, 0xff, 0x03, 0x5f, 0x32, 0xff, 0x01, 0x60, 0x31, 0xff, 0x00, 0x61, 0x31, 0xff, 0x01, 0x66, 0x33, 0xff, 0x00, 0x6b, 0x35, 0xff, 0x02, 0x71, 0x3b, 0xff, 0x02, 0x74, 0x3c, 0xff, 0x01, 0x78, 0x40, 0xff, 0x02, 0x85, 0x4d, 0xff, 0x10, 0x9b, 0x64, 0xff, 0x1b, 0xae, 0x78, 0xff, 0x17, 0xb4, 0x7e, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x18, 0xbc, 0x88, 0xff, 0x1a, 0xbc, 0x89, 0xff, 0x1a, 0xbb, 0x89, 0xff, 0x1b, 0xbc, 0x8b, 0xff, 0x1c, 0xbd, 0x8c, 0xff, 0x1b, 0xbd, 0x8c, 0xff, 0x1d, 0xbd, 0x8e, 0xff, 0x1e, 0xbb, 0x8f, 0xff, 0x1c, 0xba, 0x8d, 0xff, 0x1d, 0xba, 0x8e, 0xff, 0x22, 0xbc, 0x91, 0xff, 0x20, 0xb6, 0x8e, 0xff, 0x18, 0xad, 0x85, 0xff, 0x15, 0xab, 0x82, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xab, 0x83, 0xff, 0x16, 0xab, 0x83, 0xff, 0x15, 0xac, 0x81, 0xff, 0x13, 0xab, 0x7f, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x10, 0xa9, 0x7b, 0xff, 0x10, 0xa8, 0x7a, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0a, 0xa6, 0x73, 0xff, 0x06, 0xa5, 0x6e, 0xff, 0x09, 0xab, 0x71, 0xff, 0x0d, 0xb3, 0x78, 0xff, 0x10, 0xb9, 0x7d, 0xff, 0x18, 0xbe, 0x80, 0xff, 0x16, 0xb9, 0x7c, 0xff, 0x06, 0xa7, 0x6a, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x09, 0xa7, 0x72, 0xff, 0x18, 0xae, 0x78, 0xff, 0x23, 0xa7, 0x6d, 0xff, 0x43, 0xba, 0x86, 0xff, 0x69, 0xd1, 0xa5, 0xff, 0x85, 0xe3, 0xbe, 0xff, 0x69, 0xcb, 0xa7, 0xff, 0x36, 0xae, 0x86, 0xff, 0x24, 0xb1, 0x84, 0xff, 0x0f, 0xac, 0x7b, 0xff, 0x17, 0xb1, 0x7f, 0xff, 0x14, 0xb0, 0x7c, 0xff, 0x11, 0xaf, 0x79, 0xff, 0x0e, 0xaa, 0x71, 0xff, 0x09, 0xa0, 0x65, 0xff, 0x02, 0x87, 0x4e, 0xff, 0x02, 0x7a, 0x44, 0xff, 0x02, 0x6b, 0x37, 0xff, 0x04, 0x62, 0x32, 0xff, 0x01, 0x54, 0x27, 0xff, 0x01, 0x4e, 0x24, 0xff, 0x01, 0x47, 0x20, 0xff, 0x04, 0x46, 0x23, 0xff, 0x03, 0x44, 0x24, 0xff, 0x02, 0x41, 0x22, 0xff, 0x02, 0x40, 0x22, 0xff, 0x01, 0x41, 0x22, 0xff, 0x01, 0x3f, 0x21, 0xff, 0x01, 0x41, 0x21, 0xff, 0x02, 0x40, 0x20, 0xff, 0x01, 0x42, 0x20, 0xff, 0x00, 0x40, 0x20, 0xff, 0x01, 0x41, 0x21, 0xff, 0x01, 0x41, 0x21, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x40, 0x21, 0xff, 0x01, 0x40, 0x21, 0xff, 0x02, 0x40, 0x21, 0xff, 0x00, 0x40, 0x20, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x01, 0x40, 0x21, 0xff, 0x00, 0x44, 0x22, 0xff, 0x01, 0x46, 0x23, 0xff, 0x02, 0x4a, 0x26, 0xff, 0x05, 0x4f, 0x2a, 0xff, 0x04, 0x54, 0x2d, 0xff, 0x01, 0x55, 0x2d, 0xff, 0x03, 0x62, 0x37, 0xff, 0x14, 0x7d, 0x51, 0xff, 0x13, 0x8e, 0x5c, 0xff, 0x08, 0x93, 0x5f, 0xff, 0x03, 0x97, 0x62, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x10, 0xa7, 0x72, 0xff, 0x0e, 0xa9, 0x70, 0xff, 0x0d, 0xa6, 0x6b, 0xff, 0x0f, 0xa2, 0x65, 0xff, 0x0c, 0xa2, 0x63, 0xff, 0x0b, 0xa1, 0x63, 0xff, 0x0a, 0xa0, 0x62, 0xff, 0x0a, 0x9f, 0x61, 0xff, 0x0b, 0x9e, 0x5e, 0xff, 0x09, 0x9d, 0x5c, 0xff, 0x09, 0x9b, 0x5a, 0xff, 0x08, 0x9a, 0x56, 0xff, 0x08, 0x99, 0x54, 0xff, 0x08, 0x9c, 0x56, 0xff, 0x07, 0x9c, 0x57, 0xff, 0x08, 0x9f, 0x5a, 0xff, 0x05, 0x9b, 0x58, 0xff, 0x07, 0x99, 0x55, 0xff, 0x09, 0x98, 0x53, 0xff, 0x07, 0x94, 0x50, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x09, 0x90, 0x4b, 0xff, 0x08, 0x8e, 0x49, 0xff, 0x09, 0x8e, 0x49, 0xff, 0x09, 0x8d, 0x48, 0xff, 0x08, 0x8a, 0x46, 0xff, 0x08, 0x89, 0x45, 0xff, 0x08, 0x89, 0x45, 0xff, 0x09, 0x86, 0x44, 0xff, 0x0a, 0x83, 0x44, 0xff, 0x09, 0x7f, 0x43, 0xff, 0x09, 0x7d, 0x42, 0xff, 0x08, 0x7a, 0x3f, 0xff, 0x08, 0x79, 0x3e, 0xff, 0x09, 0x77, 0x3d, 0xff, 0x0a, 0x73, 0x3f, 0xff, 0x0a, 0x69, 0x3d, 0xff, 0x0b, 0x63, 0x39, 0xff, 0x0d, 0x60, 0x39, 0xff, 0x0a, 0x5b, 0x38, 0xff, 0x03, 0x57, 0x30, 0xff, 0x02, 0x4f, 0x3b, 0xff, 0x0b, 0x45, 0x57, 0xff, 0x1c, 0x50, 0x70, 0xff, 0x1b, 0x56, 0x81, 0xff, 0x15, 0x57, 0x85, 0xff, 0x1d, 0x5e, 0x8d, 0xff, 0x1f, 0x6b, 0x9d, 0xff, 0x20, 0x88, 0xb0, 0xff, 0x56, 0xbf, 0xcf, 0xff, 0x2a, 0x7b, 0x71, 0xff, 0x0a, 0x52, 0x3d, 0xff, 0x01, 0x3f, 0x24, 0xff, 0x04, 0x34, 0x19, 0xff, 0x10, 0x30, 0x27, 0xff, 0x18, 0x34, 0x40, 0xff, 0x17, 0x34, 0x4b, 0xff, 0x23, 0x4b, 0x6e, 0xff, 0x70, 0x89, 0xab, 0xff, + 0x15, 0x24, 0xa9, 0xff, 0x13, 0x25, 0xaf, 0xff, 0x15, 0x26, 0xb1, 0xff, 0x17, 0x2c, 0xb8, 0xff, 0x18, 0x31, 0xbd, 0xff, 0x2d, 0x45, 0xc7, 0xff, 0x51, 0x6e, 0xe5, 0xff, 0x5c, 0x80, 0xf4, 0xff, 0x55, 0x74, 0xef, 0xff, 0x2e, 0x46, 0xcd, 0xff, 0x21, 0x36, 0xc4, 0xff, 0x23, 0x3a, 0xc7, 0xff, 0x23, 0x3d, 0xc5, 0xff, 0x25, 0x42, 0xc4, 0xff, 0x29, 0x48, 0xc1, 0xff, 0x44, 0x5e, 0xd1, 0xff, 0x52, 0x69, 0xdc, 0xff, 0x54, 0x71, 0xd9, 0xff, 0x52, 0x73, 0xd7, 0xff, 0x55, 0x6b, 0xde, 0xff, 0x4f, 0x62, 0xe0, 0xff, 0x42, 0x63, 0xdd, 0xff, 0x2f, 0x61, 0xcd, 0xff, 0x16, 0x6c, 0x9b, 0xff, 0x11, 0x99, 0x7b, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x0a, 0xa8, 0x6a, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x08, 0xa8, 0x75, 0xff, 0x07, 0xab, 0x70, 0xff, 0x0a, 0xae, 0x6f, 0xff, 0x0c, 0xae, 0x71, 0xff, 0x0b, 0xae, 0x71, 0xff, 0x0a, 0xae, 0x71, 0xff, 0x09, 0xae, 0x71, 0xff, 0x0b, 0xb0, 0x74, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x15, 0xbb, 0x80, 0xff, 0x17, 0xbb, 0x80, 0xff, 0x14, 0xb6, 0x7b, 0xff, 0x09, 0xb7, 0x77, 0xff, 0x08, 0xb4, 0x73, 0xff, 0x0b, 0xa7, 0x66, 0xff, 0x02, 0x7e, 0x46, 0xff, 0x01, 0x69, 0x37, 0xff, 0x01, 0x4b, 0x23, 0xff, 0x03, 0x43, 0x21, 0xff, 0x02, 0x40, 0x21, 0xff, 0x04, 0x3d, 0x20, 0xff, 0x05, 0x37, 0x1c, 0xff, 0x03, 0x34, 0x19, 0xff, 0x01, 0x32, 0x17, 0xff, 0x01, 0x31, 0x17, 0xff, 0x04, 0x32, 0x18, 0xff, 0x05, 0x32, 0x19, 0xff, 0x01, 0x34, 0x19, 0xff, 0x01, 0x32, 0x17, 0xff, 0x00, 0x31, 0x16, 0xff, 0x00, 0x31, 0x15, 0xff, 0x00, 0x30, 0x15, 0xff, 0x00, 0x32, 0x16, 0xff, 0x01, 0x34, 0x17, 0xff, 0x00, 0x33, 0x18, 0xff, 0x02, 0x35, 0x18, 0xff, 0x02, 0x35, 0x18, 0xff, 0x03, 0x36, 0x19, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x01, 0x37, 0x1b, 0xff, 0x01, 0x38, 0x1c, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x02, 0x3e, 0x21, 0xff, 0x02, 0x3f, 0x21, 0xff, 0x03, 0x41, 0x22, 0xff, 0x00, 0x45, 0x23, 0xff, 0x00, 0x50, 0x2a, 0xff, 0x02, 0x61, 0x37, 0xff, 0x03, 0x84, 0x51, 0xff, 0x11, 0x9c, 0x66, 0xff, 0x13, 0xa5, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x09, 0xaa, 0x71, 0xff, 0x05, 0xa3, 0x6a, 0xff, 0x05, 0xa1, 0x67, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x12, 0xab, 0x6c, 0xff, 0x13, 0xab, 0x6c, 0xff, 0x15, 0xb0, 0x72, 0xff, 0x10, 0xaf, 0x74, 0xff, 0x0e, 0xae, 0x75, 0xff, 0x08, 0xa7, 0x6d, 0xff, 0x0d, 0xac, 0x70, 0xff, 0x0d, 0xb2, 0x74, 0xff, 0x10, 0xb5, 0x75, 0xff, 0x13, 0xb4, 0x72, 0xff, 0x09, 0xa7, 0x65, 0xff, 0x0f, 0xac, 0x6b, 0xff, 0x13, 0xaf, 0x71, 0xff, 0x0d, 0xa9, 0x6f, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x0a, 0xa4, 0x70, 0xff, 0x07, 0xa2, 0x6e, 0xff, 0x09, 0xa5, 0x71, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x0d, 0xac, 0x74, 0xff, 0x0d, 0xac, 0x74, 0xff, 0x0e, 0xad, 0x74, 0xff, 0x0d, 0xab, 0x73, 0xff, 0x0a, 0xaa, 0x74, 0xff, 0x0b, 0xab, 0x76, 0xff, 0x0d, 0xad, 0x79, 0xff, 0x11, 0xb1, 0x7d, 0xff, 0x13, 0xb3, 0x7f, 0xff, 0x14, 0xb4, 0x7f, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x15, 0xb5, 0x81, 0xff, 0x15, 0xb6, 0x82, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x17, 0xba, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x17, 0xba, 0x83, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x17, 0xb9, 0x84, 0xff, 0x16, 0xb7, 0x85, 0xff, 0x17, 0xb8, 0x85, 0xff, 0x18, 0xb7, 0x84, 0xff, 0x16, 0xaf, 0x7b, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x0a, 0x93, 0x5e, 0xff, 0x06, 0x8a, 0x55, 0xff, 0x02, 0x7e, 0x4b, 0xff, 0x03, 0x79, 0x46, 0xff, 0x02, 0x70, 0x3e, 0xff, 0x03, 0x69, 0x39, 0xff, 0x02, 0x62, 0x35, 0xff, 0x03, 0x5f, 0x34, 0xff, 0x03, 0x59, 0x30, 0xff, 0x01, 0x53, 0x2c, 0xff, 0x02, 0x4d, 0x2a, 0xff, 0x02, 0x4b, 0x28, 0xff, 0x00, 0x49, 0x27, 0xff, 0x00, 0x47, 0x27, 0xff, 0x00, 0x47, 0x27, 0xff, 0x02, 0x49, 0x29, 0xff, 0x01, 0x47, 0x28, 0xff, 0x00, 0x46, 0x28, 0xff, 0x01, 0x42, 0x25, 0xff, 0x02, 0x40, 0x23, 0xff, 0x00, 0x3f, 0x22, 0xff, 0x00, 0x40, 0x22, 0xff, 0x01, 0x44, 0x24, 0xff, 0x02, 0x48, 0x27, 0xff, 0x03, 0x4d, 0x29, 0xff, 0x03, 0x4e, 0x2a, 0xff, 0x02, 0x4f, 0x2a, 0xff, 0x02, 0x53, 0x2b, 0xff, 0x01, 0x54, 0x2c, 0xff, 0x01, 0x55, 0x2b, 0xff, 0x01, 0x5b, 0x2f, 0xff, 0x02, 0x5f, 0x31, 0xff, 0x01, 0x63, 0x33, 0xff, 0x00, 0x64, 0x34, 0xff, 0x01, 0x6b, 0x38, 0xff, 0x00, 0x73, 0x3c, 0xff, 0x04, 0x81, 0x4a, 0xff, 0x13, 0x9b, 0x64, 0xff, 0x16, 0xad, 0x76, 0xff, 0x12, 0xb2, 0x7c, 0xff, 0x17, 0xba, 0x86, 0xff, 0x1a, 0xbd, 0x89, 0xff, 0x1a, 0xbb, 0x89, 0xff, 0x19, 0xbc, 0x89, 0xff, 0x1a, 0xbd, 0x8a, 0xff, 0x1a, 0xbd, 0x8a, 0xff, 0x19, 0xba, 0x8a, 0xff, 0x1a, 0xba, 0x8b, 0xff, 0x1a, 0xb9, 0x8b, 0xff, 0x1b, 0xb9, 0x8b, 0xff, 0x20, 0xba, 0x8d, 0xff, 0x1c, 0xb4, 0x88, 0xff, 0x13, 0xab, 0x80, 0xff, 0x12, 0xaa, 0x80, 0xff, 0x12, 0xa9, 0x81, 0xff, 0x13, 0xaa, 0x80, 0xff, 0x13, 0xac, 0x80, 0xff, 0x13, 0xac, 0x7e, 0xff, 0x10, 0xaa, 0x7c, 0xff, 0x0d, 0xa9, 0x7a, 0xff, 0x0f, 0xa8, 0x79, 0xff, 0x0f, 0xa7, 0x76, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x08, 0xa7, 0x71, 0xff, 0x07, 0xaa, 0x72, 0xff, 0x08, 0xb2, 0x78, 0xff, 0x0f, 0xbc, 0x82, 0xff, 0x14, 0xbc, 0x7e, 0xff, 0x12, 0xb6, 0x77, 0xff, 0x03, 0xa4, 0x65, 0xff, 0x06, 0xa6, 0x69, 0xff, 0x0d, 0xab, 0x75, 0xff, 0x12, 0xae, 0x7c, 0xff, 0x17, 0xa0, 0x72, 0xff, 0x5d, 0xc5, 0x97, 0xff, 0x72, 0xd4, 0xa7, 0xff, 0x74, 0xd3, 0xa9, 0xff, 0x6d, 0xca, 0xa2, 0xff, 0x55, 0xb7, 0x8f, 0xff, 0x2d, 0xa5, 0x7a, 0xff, 0x15, 0xa3, 0x73, 0xff, 0x0f, 0xaf, 0x7c, 0xff, 0x13, 0xaf, 0x7a, 0xff, 0x11, 0xac, 0x78, 0xff, 0x0d, 0xa8, 0x72, 0xff, 0x0e, 0xa5, 0x6d, 0xff, 0x06, 0x92, 0x58, 0xff, 0x01, 0x78, 0x42, 0xff, 0x03, 0x67, 0x37, 0xff, 0x07, 0x5b, 0x32, 0xff, 0x05, 0x55, 0x2c, 0xff, 0x02, 0x4a, 0x24, 0xff, 0x02, 0x44, 0x21, 0xff, 0x01, 0x40, 0x1f, 0xff, 0x03, 0x40, 0x22, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x04, 0x3c, 0x1e, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x02, 0x3b, 0x1e, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x02, 0x3d, 0x1f, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x01, 0x3a, 0x1d, 0xff, 0x00, 0x3a, 0x1d, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x00, 0x3b, 0x1e, 0xff, 0x00, 0x3a, 0x1d, 0xff, 0x00, 0x3b, 0x1e, 0xff, 0x01, 0x3c, 0x1f, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x3f, 0x21, 0xff, 0x01, 0x41, 0x22, 0xff, 0x02, 0x44, 0x23, 0xff, 0x03, 0x48, 0x26, 0xff, 0x04, 0x4d, 0x2a, 0xff, 0x01, 0x4d, 0x2a, 0xff, 0x06, 0x59, 0x33, 0xff, 0x0d, 0x6f, 0x44, 0xff, 0x11, 0x8e, 0x5e, 0xff, 0x07, 0x94, 0x61, 0xff, 0x0d, 0x9c, 0x68, 0xff, 0x14, 0xa6, 0x71, 0xff, 0x0e, 0xa8, 0x70, 0xff, 0x0d, 0xa7, 0x6c, 0xff, 0x14, 0xa4, 0x69, 0xff, 0x0e, 0xa2, 0x64, 0xff, 0x0c, 0xa0, 0x64, 0xff, 0x0b, 0x9f, 0x63, 0xff, 0x0b, 0x9e, 0x62, 0xff, 0x0b, 0x9d, 0x5f, 0xff, 0x0b, 0x9c, 0x5c, 0xff, 0x0c, 0x9d, 0x5b, 0xff, 0x0a, 0x99, 0x55, 0xff, 0x08, 0x99, 0x54, 0xff, 0x09, 0x9c, 0x57, 0xff, 0x08, 0x9d, 0x57, 0xff, 0x06, 0x9d, 0x57, 0xff, 0x07, 0x9b, 0x56, 0xff, 0x08, 0x99, 0x54, 0xff, 0x09, 0x96, 0x51, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x0b, 0x91, 0x4c, 0xff, 0x0b, 0x90, 0x4b, 0xff, 0x08, 0x8f, 0x49, 0xff, 0x07, 0x8e, 0x48, 0xff, 0x08, 0x8f, 0x49, 0xff, 0x08, 0x8d, 0x47, 0xff, 0x08, 0x8b, 0x45, 0xff, 0x09, 0x88, 0x44, 0xff, 0x06, 0x88, 0x42, 0xff, 0x08, 0x88, 0x43, 0xff, 0x0a, 0x83, 0x43, 0xff, 0x0b, 0x7f, 0x43, 0xff, 0x0b, 0x7e, 0x42, 0xff, 0x08, 0x7a, 0x3e, 0xff, 0x08, 0x79, 0x3d, 0xff, 0x0a, 0x76, 0x3d, 0xff, 0x0d, 0x71, 0x40, 0xff, 0x08, 0x67, 0x39, 0xff, 0x04, 0x64, 0x37, 0xff, 0x09, 0x6e, 0x46, 0xff, 0x0f, 0x76, 0x4e, 0xff, 0x11, 0x71, 0x4a, 0xff, 0x0f, 0x65, 0x4a, 0xff, 0x0d, 0x4e, 0x4e, 0xff, 0x0b, 0x41, 0x58, 0xff, 0x09, 0x41, 0x6b, 0xff, 0x0d, 0x48, 0x71, 0xff, 0x19, 0x55, 0x75, 0xff, 0x32, 0x7f, 0x96, 0xff, 0x37, 0x92, 0xa5, 0xff, 0x37, 0x8f, 0x9c, 0xff, 0x3e, 0x96, 0x92, 0xff, 0x49, 0xa0, 0x93, 0xff, 0x18, 0x5b, 0x4e, 0xff, 0x02, 0x33, 0x21, 0xff, 0x0c, 0x30, 0x1e, 0xff, 0x11, 0x33, 0x26, 0xff, 0x0e, 0x38, 0x34, 0xff, 0x14, 0x3b, 0x4f, 0xff, 0x71, 0x7f, 0x93, 0xff, + 0x22, 0x34, 0xb9, 0xff, 0x2e, 0x3f, 0xc4, 0xff, 0x1c, 0x28, 0xb3, 0xff, 0x18, 0x28, 0xba, 0xff, 0x13, 0x2c, 0xbd, 0xff, 0x3e, 0x5a, 0xda, 0xff, 0x69, 0x8a, 0xfb, 0xff, 0x68, 0x8a, 0xfb, 0xff, 0x59, 0x78, 0xef, 0xff, 0x2e, 0x4a, 0xc5, 0xff, 0x1d, 0x35, 0xb3, 0xff, 0x1d, 0x35, 0xb1, 0xff, 0x1f, 0x3a, 0xaf, 0xff, 0x25, 0x40, 0xb0, 0xff, 0x25, 0x43, 0xac, 0xff, 0x2c, 0x49, 0xb0, 0xff, 0x37, 0x51, 0xc3, 0xff, 0x3b, 0x5c, 0xd2, 0xff, 0x38, 0x60, 0xd6, 0xff, 0x39, 0x5d, 0xdb, 0xff, 0x3e, 0x60, 0xe4, 0xff, 0x3f, 0x6e, 0xe7, 0xff, 0x3b, 0x71, 0xe1, 0xff, 0x23, 0x71, 0xb1, 0xff, 0x11, 0x94, 0x80, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x0a, 0xaa, 0x6b, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x08, 0xa8, 0x73, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x0d, 0xae, 0x70, 0xff, 0x0a, 0xad, 0x70, 0xff, 0x09, 0xac, 0x6f, 0xff, 0x0a, 0xaf, 0x71, 0xff, 0x0a, 0xaf, 0x71, 0xff, 0x0b, 0xb0, 0x74, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x16, 0xbc, 0x81, 0xff, 0x16, 0xbb, 0x81, 0xff, 0x0f, 0xb7, 0x7b, 0xff, 0x08, 0xb7, 0x78, 0xff, 0x0b, 0xb6, 0x74, 0xff, 0x0c, 0xa5, 0x65, 0xff, 0x01, 0x78, 0x42, 0xff, 0x05, 0x62, 0x33, 0xff, 0x02, 0x46, 0x21, 0xff, 0x02, 0x40, 0x1f, 0xff, 0x00, 0x40, 0x21, 0xff, 0x01, 0x3a, 0x1c, 0xff, 0x01, 0x31, 0x15, 0xff, 0x01, 0x30, 0x15, 0xff, 0x02, 0x30, 0x15, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x03, 0x2d, 0x12, 0xff, 0x03, 0x2c, 0x13, 0xff, 0x00, 0x2d, 0x13, 0xff, 0x00, 0x2c, 0x12, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x01, 0x2b, 0x12, 0xff, 0x01, 0x2e, 0x15, 0xff, 0x00, 0x2f, 0x15, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x05, 0x32, 0x17, 0xff, 0x02, 0x30, 0x15, 0xff, 0x01, 0x30, 0x14, 0xff, 0x02, 0x32, 0x16, 0xff, 0x02, 0x33, 0x17, 0xff, 0x04, 0x35, 0x19, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x04, 0x38, 0x1b, 0xff, 0x03, 0x39, 0x1c, 0xff, 0x05, 0x3a, 0x1e, 0xff, 0x06, 0x3d, 0x20, 0xff, 0x02, 0x3f, 0x20, 0xff, 0x03, 0x4a, 0x27, 0xff, 0x0b, 0x60, 0x39, 0xff, 0x07, 0x81, 0x50, 0xff, 0x10, 0x94, 0x61, 0xff, 0x15, 0xa7, 0x71, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x0b, 0xac, 0x72, 0xff, 0x0d, 0xad, 0x73, 0xff, 0x05, 0xa3, 0x69, 0xff, 0x04, 0xa2, 0x67, 0xff, 0x07, 0xa3, 0x65, 0xff, 0x0f, 0xaa, 0x68, 0xff, 0x14, 0xaf, 0x6d, 0xff, 0x19, 0xb5, 0x74, 0xff, 0x11, 0xb0, 0x74, 0xff, 0x15, 0xb8, 0x7e, 0xff, 0x05, 0xa7, 0x6b, 0xff, 0x07, 0xa7, 0x6a, 0xff, 0x11, 0xb5, 0x76, 0xff, 0x07, 0xac, 0x6c, 0xff, 0x0e, 0xaf, 0x6d, 0xff, 0x0b, 0xa9, 0x66, 0xff, 0x14, 0xaf, 0x6e, 0xff, 0x0a, 0xa5, 0x67, 0xff, 0x0e, 0xa9, 0x6e, 0xff, 0x0d, 0xa8, 0x70, 0xff, 0x0a, 0xa4, 0x70, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x0b, 0xa6, 0x71, 0xff, 0x0b, 0xa8, 0x72, 0xff, 0x0c, 0xab, 0x75, 0xff, 0x0b, 0xab, 0x74, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x0d, 0xac, 0x74, 0xff, 0x0c, 0xac, 0x77, 0xff, 0x0e, 0xae, 0x7a, 0xff, 0x13, 0xb3, 0x7f, 0xff, 0x16, 0xb6, 0x82, 0xff, 0x17, 0xb7, 0x83, 0xff, 0x17, 0xb7, 0x83, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x16, 0xb7, 0x83, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x16, 0xb8, 0x85, 0xff, 0x18, 0xba, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x17, 0xba, 0x83, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x17, 0xb7, 0x82, 0xff, 0x19, 0xb9, 0x86, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x16, 0xb6, 0x83, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x06, 0x98, 0x63, 0xff, 0x05, 0x8b, 0x57, 0xff, 0x01, 0x7d, 0x4a, 0xff, 0x01, 0x76, 0x45, 0xff, 0x01, 0x6e, 0x3e, 0xff, 0x01, 0x64, 0x36, 0xff, 0x01, 0x5e, 0x32, 0xff, 0x01, 0x5a, 0x30, 0xff, 0x01, 0x55, 0x2e, 0xff, 0x01, 0x4d, 0x29, 0xff, 0x00, 0x47, 0x24, 0xff, 0x02, 0x45, 0x25, 0xff, 0x04, 0x44, 0x25, 0xff, 0x00, 0x40, 0x21, 0xff, 0x00, 0x3e, 0x20, 0xff, 0x01, 0x41, 0x24, 0xff, 0x02, 0x43, 0x26, 0xff, 0x01, 0x41, 0x26, 0xff, 0x00, 0x3e, 0x24, 0xff, 0x02, 0x3c, 0x22, 0xff, 0x03, 0x3b, 0x22, 0xff, 0x01, 0x3b, 0x21, 0xff, 0x01, 0x3c, 0x21, 0xff, 0x00, 0x3d, 0x21, 0xff, 0x01, 0x3f, 0x21, 0xff, 0x01, 0x41, 0x22, 0xff, 0x00, 0x42, 0x22, 0xff, 0x00, 0x43, 0x21, 0xff, 0x00, 0x46, 0x22, 0xff, 0x00, 0x49, 0x25, 0xff, 0x01, 0x4c, 0x26, 0xff, 0x02, 0x52, 0x29, 0xff, 0x02, 0x55, 0x2c, 0xff, 0x01, 0x5b, 0x2e, 0xff, 0x00, 0x5b, 0x2e, 0xff, 0x00, 0x62, 0x31, 0xff, 0x01, 0x69, 0x35, 0xff, 0x02, 0x71, 0x3e, 0xff, 0x0d, 0x88, 0x55, 0xff, 0x14, 0xa0, 0x6c, 0xff, 0x16, 0xad, 0x79, 0xff, 0x18, 0xb6, 0x83, 0xff, 0x1c, 0xbb, 0x89, 0xff, 0x1a, 0xbb, 0x89, 0xff, 0x18, 0xbb, 0x87, 0xff, 0x16, 0xba, 0x87, 0xff, 0x17, 0xb9, 0x87, 0xff, 0x18, 0xb9, 0x89, 0xff, 0x19, 0xb9, 0x8a, 0xff, 0x1b, 0xb9, 0x8b, 0xff, 0x1a, 0xb8, 0x8a, 0xff, 0x1c, 0xb6, 0x89, 0xff, 0x18, 0xb1, 0x84, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x12, 0xa9, 0x7f, 0xff, 0x11, 0xa9, 0x80, 0xff, 0x11, 0xa9, 0x7e, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x11, 0xaa, 0x7b, 0xff, 0x0d, 0xa8, 0x77, 0xff, 0x0b, 0xa7, 0x76, 0xff, 0x0d, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0a, 0xa9, 0x73, 0xff, 0x08, 0xaa, 0x73, 0xff, 0x06, 0xae, 0x75, 0xff, 0x0c, 0xb6, 0x7c, 0xff, 0x0e, 0xb3, 0x77, 0xff, 0x0b, 0xad, 0x6e, 0xff, 0x03, 0xa3, 0x63, 0xff, 0x02, 0xa2, 0x65, 0xff, 0x08, 0xa5, 0x6f, 0xff, 0x14, 0xac, 0x7c, 0xff, 0x25, 0xa9, 0x7d, 0xff, 0x85, 0xe4, 0xb7, 0xff, 0x66, 0xc1, 0x97, 0xff, 0x5e, 0xb7, 0x90, 0xff, 0x60, 0xb8, 0x92, 0xff, 0x46, 0xa3, 0x7d, 0xff, 0x36, 0xaa, 0x7f, 0xff, 0x13, 0x9e, 0x6e, 0xff, 0x0f, 0xae, 0x7a, 0xff, 0x10, 0xae, 0x77, 0xff, 0x09, 0xa8, 0x73, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x01, 0x85, 0x4d, 0xff, 0x00, 0x6a, 0x37, 0xff, 0x01, 0x57, 0x2a, 0xff, 0x07, 0x4f, 0x2a, 0xff, 0x01, 0x49, 0x23, 0xff, 0x01, 0x43, 0x1f, 0xff, 0x01, 0x3f, 0x1e, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x00, 0x37, 0x1a, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x01, 0x38, 0x1b, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x03, 0x38, 0x1c, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x00, 0x36, 0x19, 0xff, 0x00, 0x36, 0x19, 0xff, 0x00, 0x36, 0x19, 0xff, 0x02, 0x37, 0x1a, 0xff, 0x00, 0x37, 0x1b, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x00, 0x39, 0x1b, 0xff, 0x00, 0x39, 0x1c, 0xff, 0x01, 0x39, 0x1c, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x01, 0x3b, 0x1e, 0xff, 0x02, 0x3d, 0x20, 0xff, 0x01, 0x3d, 0x1f, 0xff, 0x01, 0x3e, 0x20, 0xff, 0x02, 0x3f, 0x21, 0xff, 0x01, 0x40, 0x22, 0xff, 0x01, 0x42, 0x21, 0xff, 0x02, 0x45, 0x25, 0xff, 0x01, 0x48, 0x27, 0xff, 0x00, 0x49, 0x26, 0xff, 0x02, 0x54, 0x2c, 0xff, 0x0e, 0x7c, 0x50, 0xff, 0x10, 0x92, 0x62, 0xff, 0x0f, 0x96, 0x65, 0xff, 0x11, 0x9f, 0x6b, 0xff, 0x0e, 0xa8, 0x70, 0xff, 0x0b, 0xa9, 0x6e, 0xff, 0x12, 0xa6, 0x6a, 0xff, 0x0d, 0xa2, 0x64, 0xff, 0x0b, 0xa0, 0x64, 0xff, 0x0c, 0xa0, 0x64, 0xff, 0x0b, 0x9e, 0x62, 0xff, 0x0b, 0x9d, 0x60, 0xff, 0x0b, 0x9d, 0x5d, 0xff, 0x0c, 0x9d, 0x5a, 0xff, 0x09, 0x99, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x09, 0x9d, 0x57, 0xff, 0x05, 0x9c, 0x56, 0xff, 0x06, 0x9b, 0x55, 0xff, 0x08, 0x98, 0x53, 0xff, 0x09, 0x95, 0x50, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x0c, 0x91, 0x4e, 0xff, 0x0a, 0x8e, 0x4a, 0xff, 0x06, 0x8c, 0x48, 0xff, 0x06, 0x8d, 0x49, 0xff, 0x08, 0x8d, 0x49, 0xff, 0x07, 0x8b, 0x47, 0xff, 0x08, 0x8a, 0x46, 0xff, 0x0a, 0x88, 0x45, 0xff, 0x0c, 0x87, 0x45, 0xff, 0x0b, 0x86, 0x45, 0xff, 0x08, 0x83, 0x42, 0xff, 0x06, 0x80, 0x41, 0xff, 0x05, 0x7d, 0x40, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x0a, 0x78, 0x40, 0xff, 0x0a, 0x75, 0x40, 0xff, 0x06, 0x72, 0x3c, 0xff, 0x06, 0x71, 0x3e, 0xff, 0x17, 0x8e, 0x5e, 0xff, 0x2e, 0xb0, 0x82, 0xff, 0x3b, 0xc2, 0x8f, 0xff, 0x3f, 0xbd, 0x8c, 0xff, 0x40, 0xae, 0x87, 0xff, 0x3a, 0x94, 0x7d, 0xff, 0x1f, 0x6a, 0x6e, 0xff, 0x0c, 0x4a, 0x6d, 0xff, 0x06, 0x3c, 0x60, 0xff, 0x0e, 0x45, 0x50, 0xff, 0x28, 0x6a, 0x63, 0xff, 0x31, 0x6e, 0x6f, 0xff, 0x1b, 0x50, 0x54, 0xff, 0x12, 0x50, 0x3e, 0xff, 0x46, 0x97, 0x7d, 0xff, 0x52, 0xa8, 0x99, 0xff, 0x13, 0x52, 0x40, 0xff, 0x07, 0x2f, 0x1c, 0xff, 0x06, 0x2e, 0x1b, 0xff, 0x0a, 0x32, 0x27, 0xff, 0x15, 0x32, 0x3d, 0xff, 0x96, 0x9c, 0xac, 0xff, + 0x3e, 0x54, 0xd5, 0xff, 0x44, 0x56, 0xd7, 0xff, 0x1e, 0x29, 0xb2, 0xff, 0x17, 0x24, 0xb7, 0xff, 0x15, 0x29, 0xb8, 0xff, 0x50, 0x6a, 0xe4, 0xff, 0x66, 0x7d, 0xe9, 0xff, 0x49, 0x5c, 0xc3, 0xff, 0x32, 0x45, 0xa9, 0xff, 0x2c, 0x41, 0x9c, 0xff, 0x2d, 0x42, 0x94, 0xff, 0x2d, 0x41, 0x89, 0xff, 0x35, 0x48, 0x88, 0xff, 0x3f, 0x4f, 0x88, 0xff, 0x44, 0x55, 0x8b, 0xff, 0x3d, 0x50, 0x8c, 0xff, 0x36, 0x49, 0x9a, 0xff, 0x30, 0x47, 0xad, 0xff, 0x34, 0x53, 0xc5, 0xff, 0x34, 0x58, 0xdb, 0xff, 0x31, 0x5b, 0xe2, 0xff, 0x3b, 0x6c, 0xe7, 0xff, 0x4c, 0x7b, 0xf2, 0xff, 0x31, 0x76, 0xc9, 0xff, 0x12, 0x8d, 0x8e, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x0a, 0xa9, 0x6e, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x0e, 0xab, 0x73, 0xff, 0x0f, 0xab, 0x71, 0xff, 0x07, 0xab, 0x70, 0xff, 0x09, 0xad, 0x73, 0xff, 0x0b, 0xb0, 0x75, 0xff, 0x09, 0xaf, 0x73, 0xff, 0x0b, 0xb0, 0x75, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x13, 0xb9, 0x7e, 0xff, 0x16, 0xbe, 0x82, 0xff, 0x0b, 0xb9, 0x7b, 0xff, 0x0b, 0xb6, 0x77, 0xff, 0x0d, 0xb8, 0x77, 0xff, 0x0e, 0xac, 0x6d, 0xff, 0x06, 0x7b, 0x46, 0xff, 0x09, 0x59, 0x2f, 0xff, 0x06, 0x40, 0x1f, 0xff, 0x04, 0x3a, 0x1c, 0xff, 0x08, 0x36, 0x1a, 0xff, 0x02, 0x2c, 0x11, 0xff, 0x01, 0x29, 0x0e, 0xff, 0x00, 0x29, 0x0e, 0xff, 0x00, 0x28, 0x0d, 0xff, 0x01, 0x28, 0x0d, 0xff, 0x00, 0x24, 0x09, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x01, 0x23, 0x0d, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x01, 0x22, 0x0c, 0xff, 0x01, 0x22, 0x0c, 0xff, 0x01, 0x21, 0x0b, 0xff, 0x00, 0x21, 0x0b, 0xff, 0x00, 0x22, 0x0c, 0xff, 0x00, 0x23, 0x0c, 0xff, 0x02, 0x25, 0x0c, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x00, 0x22, 0x09, 0xff, 0x00, 0x23, 0x0a, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x01, 0x28, 0x0e, 0xff, 0x01, 0x29, 0x10, 0xff, 0x02, 0x2c, 0x11, 0xff, 0x04, 0x2f, 0x13, 0xff, 0x04, 0x31, 0x15, 0xff, 0x02, 0x32, 0x17, 0xff, 0x04, 0x34, 0x19, 0xff, 0x06, 0x37, 0x1c, 0xff, 0x04, 0x3a, 0x1d, 0xff, 0x03, 0x42, 0x22, 0xff, 0x0d, 0x57, 0x33, 0xff, 0x0b, 0x73, 0x47, 0xff, 0x08, 0x84, 0x54, 0xff, 0x12, 0xa6, 0x71, 0xff, 0x0c, 0xab, 0x73, 0xff, 0x14, 0xb5, 0x7b, 0xff, 0x0e, 0xaa, 0x71, 0xff, 0x04, 0xa2, 0x66, 0xff, 0x04, 0xa2, 0x67, 0xff, 0x06, 0xa2, 0x63, 0xff, 0x03, 0x9f, 0x5d, 0xff, 0x15, 0xb0, 0x6d, 0xff, 0x10, 0xac, 0x6b, 0xff, 0x10, 0xb0, 0x73, 0xff, 0x18, 0xba, 0x80, 0xff, 0x0b, 0xac, 0x70, 0xff, 0x06, 0xa6, 0x68, 0xff, 0x15, 0xb6, 0x78, 0xff, 0x0b, 0xac, 0x6c, 0xff, 0x0b, 0xa8, 0x67, 0xff, 0x14, 0xb0, 0x6f, 0xff, 0x0d, 0xa8, 0x66, 0xff, 0x0b, 0xa5, 0x67, 0xff, 0x0f, 0xaa, 0x6e, 0xff, 0x10, 0xaa, 0x71, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0a, 0xaa, 0x74, 0xff, 0x0c, 0xad, 0x76, 0xff, 0x0f, 0xaf, 0x78, 0xff, 0x11, 0xb1, 0x7a, 0xff, 0x13, 0xb3, 0x7f, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x16, 0xb6, 0x82, 0xff, 0x17, 0xb7, 0x83, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x18, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x17, 0xba, 0x83, 0xff, 0x16, 0xb9, 0x81, 0xff, 0x19, 0xb8, 0x81, 0xff, 0x1d, 0xba, 0x85, 0xff, 0x17, 0xb9, 0x83, 0xff, 0x13, 0xb4, 0x7e, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x03, 0x90, 0x5d, 0xff, 0x01, 0x7a, 0x49, 0xff, 0x01, 0x71, 0x41, 0xff, 0x08, 0x6c, 0x3f, 0xff, 0x03, 0x61, 0x37, 0xff, 0x00, 0x55, 0x2c, 0xff, 0x00, 0x4d, 0x27, 0xff, 0x00, 0x4a, 0x27, 0xff, 0x00, 0x48, 0x26, 0xff, 0x01, 0x43, 0x25, 0xff, 0x04, 0x3f, 0x21, 0xff, 0x05, 0x3c, 0x21, 0xff, 0x04, 0x3a, 0x20, 0xff, 0x02, 0x37, 0x1e, 0xff, 0x01, 0x36, 0x1d, 0xff, 0x01, 0x36, 0x1d, 0xff, 0x02, 0x38, 0x20, 0xff, 0x03, 0x39, 0x21, 0xff, 0x02, 0x37, 0x20, 0xff, 0x04, 0x37, 0x21, 0xff, 0x07, 0x36, 0x22, 0xff, 0x05, 0x35, 0x1f, 0xff, 0x03, 0x35, 0x1e, 0xff, 0x02, 0x35, 0x1e, 0xff, 0x03, 0x36, 0x1e, 0xff, 0x01, 0x37, 0x1c, 0xff, 0x02, 0x38, 0x1e, 0xff, 0x01, 0x39, 0x1d, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x02, 0x3e, 0x1f, 0xff, 0x03, 0x40, 0x20, 0xff, 0x02, 0x45, 0x22, 0xff, 0x01, 0x47, 0x24, 0xff, 0x01, 0x4d, 0x27, 0xff, 0x00, 0x4f, 0x28, 0xff, 0x00, 0x56, 0x2c, 0xff, 0x02, 0x5e, 0x31, 0xff, 0x05, 0x65, 0x38, 0xff, 0x09, 0x72, 0x44, 0xff, 0x0d, 0x89, 0x59, 0xff, 0x14, 0x9f, 0x6f, 0xff, 0x19, 0xb1, 0x80, 0xff, 0x1c, 0xba, 0x88, 0xff, 0x18, 0xba, 0x87, 0xff, 0x15, 0xb8, 0x85, 0xff, 0x14, 0xb6, 0x84, 0xff, 0x16, 0xb8, 0x86, 0xff, 0x1a, 0xba, 0x8a, 0xff, 0x1c, 0xba, 0x8b, 0xff, 0x1e, 0xbb, 0x8d, 0xff, 0x1c, 0xb8, 0x8b, 0xff, 0x17, 0xb2, 0x85, 0xff, 0x14, 0xac, 0x81, 0xff, 0x11, 0xa9, 0x7e, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x11, 0xa9, 0x7f, 0xff, 0x10, 0xaa, 0x7d, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x0e, 0xa8, 0x78, 0xff, 0x0b, 0xa7, 0x74, 0xff, 0x0b, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0c, 0xaa, 0x76, 0xff, 0x0a, 0xab, 0x77, 0xff, 0x0d, 0xaf, 0x79, 0xff, 0x0f, 0xaf, 0x77, 0xff, 0x0c, 0xab, 0x71, 0xff, 0x07, 0xa5, 0x68, 0xff, 0x05, 0xa4, 0x66, 0xff, 0x06, 0xa4, 0x69, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x0c, 0x9f, 0x6e, 0xff, 0x39, 0xb6, 0x8a, 0xff, 0x7f, 0xda, 0xb0, 0xff, 0x5b, 0xb1, 0x8a, 0xff, 0x41, 0x92, 0x70, 0xff, 0x4d, 0x9a, 0x7b, 0xff, 0x2d, 0x82, 0x61, 0xff, 0x3d, 0xaa, 0x81, 0xff, 0x21, 0xa5, 0x76, 0xff, 0x13, 0xac, 0x75, 0xff, 0x0b, 0xad, 0x74, 0xff, 0x03, 0xa8, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x04, 0x96, 0x5d, 0xff, 0x00, 0x77, 0x41, 0xff, 0x01, 0x5e, 0x2f, 0xff, 0x00, 0x4a, 0x21, 0xff, 0x03, 0x44, 0x21, 0xff, 0x01, 0x41, 0x1e, 0xff, 0x03, 0x3f, 0x1d, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x01, 0x35, 0x19, 0xff, 0x01, 0x33, 0x18, 0xff, 0x00, 0x31, 0x16, 0xff, 0x02, 0x33, 0x18, 0xff, 0x05, 0x33, 0x17, 0xff, 0x04, 0x34, 0x19, 0xff, 0x03, 0x34, 0x19, 0xff, 0x02, 0x33, 0x19, 0xff, 0x01, 0x32, 0x17, 0xff, 0x00, 0x30, 0x16, 0xff, 0x00, 0x30, 0x16, 0xff, 0x00, 0x31, 0x16, 0xff, 0x01, 0x32, 0x17, 0xff, 0x03, 0x32, 0x18, 0xff, 0x04, 0x33, 0x19, 0xff, 0x03, 0x35, 0x1a, 0xff, 0x03, 0x34, 0x19, 0xff, 0x03, 0x34, 0x1a, 0xff, 0x04, 0x36, 0x1b, 0xff, 0x02, 0x36, 0x1b, 0xff, 0x04, 0x38, 0x1c, 0xff, 0x02, 0x39, 0x1d, 0xff, 0x03, 0x3c, 0x1e, 0xff, 0x04, 0x3c, 0x1f, 0xff, 0x02, 0x3c, 0x1f, 0xff, 0x03, 0x3e, 0x20, 0xff, 0x01, 0x3f, 0x20, 0xff, 0x00, 0x41, 0x20, 0xff, 0x00, 0x44, 0x23, 0xff, 0x00, 0x47, 0x23, 0xff, 0x01, 0x56, 0x2f, 0xff, 0x0b, 0x76, 0x4b, 0xff, 0x13, 0x8c, 0x5f, 0xff, 0x0a, 0x8e, 0x5e, 0xff, 0x12, 0xa8, 0x73, 0xff, 0x0b, 0xaa, 0x71, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x09, 0xa1, 0x64, 0xff, 0x09, 0xa0, 0x63, 0xff, 0x0a, 0xa0, 0x64, 0xff, 0x0c, 0xa0, 0x62, 0xff, 0x0b, 0x9f, 0x60, 0xff, 0x0a, 0x9d, 0x5d, 0xff, 0x0a, 0x9d, 0x59, 0xff, 0x08, 0x9b, 0x55, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x08, 0x9b, 0x55, 0xff, 0x06, 0x9a, 0x54, 0xff, 0x07, 0x9a, 0x54, 0xff, 0x09, 0x98, 0x53, 0xff, 0x09, 0x95, 0x50, 0xff, 0x0a, 0x92, 0x4e, 0xff, 0x0c, 0x90, 0x4d, 0xff, 0x07, 0x8c, 0x49, 0xff, 0x05, 0x8a, 0x47, 0xff, 0x08, 0x8d, 0x49, 0xff, 0x09, 0x8d, 0x4a, 0xff, 0x08, 0x8a, 0x47, 0xff, 0x08, 0x89, 0x46, 0xff, 0x08, 0x87, 0x45, 0xff, 0x11, 0x83, 0x49, 0xff, 0x10, 0x83, 0x48, 0xff, 0x05, 0x82, 0x41, 0xff, 0x01, 0x82, 0x3e, 0xff, 0x04, 0x7e, 0x3f, 0xff, 0x08, 0x79, 0x42, 0xff, 0x09, 0x77, 0x43, 0xff, 0x03, 0x73, 0x3e, 0xff, 0x0f, 0x8e, 0x55, 0xff, 0x35, 0xc5, 0x88, 0xff, 0x3c, 0xcf, 0x93, 0xff, 0x31, 0xcb, 0x8e, 0xff, 0x29, 0xc8, 0x86, 0xff, 0x28, 0xc6, 0x7c, 0xff, 0x38, 0xcd, 0x84, 0xff, 0x5d, 0xe0, 0xa7, 0xff, 0x60, 0xdd, 0xb8, 0xff, 0x4d, 0xbc, 0xb9, 0xff, 0x29, 0x86, 0x90, 0xff, 0x0a, 0x52, 0x4a, 0xff, 0x05, 0x41, 0x22, 0xff, 0x1d, 0x50, 0x2e, 0xff, 0x0e, 0x3e, 0x21, 0xff, 0x02, 0x36, 0x11, 0xff, 0x06, 0x43, 0x20, 0xff, 0x3d, 0x8c, 0x78, 0xff, 0x5b, 0xb1, 0x9d, 0xff, 0x09, 0x3e, 0x2d, 0xff, 0x08, 0x30, 0x1e, 0xff, 0x08, 0x2f, 0x1e, 0xff, 0x31, 0x48, 0x48, 0xff, 0x93, 0x9e, 0xa4, 0xff, + 0x23, 0x39, 0xba, 0xff, 0x1f, 0x34, 0xb5, 0xff, 0x17, 0x26, 0xaa, 0xff, 0x1b, 0x2b, 0xad, 0xff, 0x1a, 0x2e, 0xa7, 0xff, 0x39, 0x4b, 0xb2, 0xff, 0x3e, 0x4b, 0xa3, 0xff, 0x3d, 0x46, 0x91, 0xff, 0x3e, 0x47, 0x8c, 0xff, 0x55, 0x5f, 0x98, 0xff, 0x5c, 0x66, 0x96, 0xff, 0x56, 0x5e, 0x84, 0xff, 0x65, 0x6b, 0x8c, 0xff, 0x6d, 0x6f, 0x8d, 0xff, 0x69, 0x6c, 0x86, 0xff, 0x59, 0x5f, 0x7e, 0xff, 0x4f, 0x59, 0x86, 0xff, 0x43, 0x4e, 0x90, 0xff, 0x36, 0x46, 0x9e, 0xff, 0x31, 0x4c, 0xc1, 0xff, 0x2a, 0x4e, 0xcf, 0xff, 0x36, 0x59, 0xdc, 0xff, 0x4b, 0x6b, 0xed, 0xff, 0x37, 0x74, 0xd2, 0xff, 0x12, 0x85, 0x93, 0xff, 0x09, 0xa6, 0x72, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x08, 0xab, 0x6d, 0xff, 0x10, 0xad, 0x76, 0xff, 0x0e, 0xaa, 0x73, 0xff, 0x05, 0xa9, 0x70, 0xff, 0x09, 0xad, 0x73, 0xff, 0x09, 0xad, 0x73, 0xff, 0x08, 0xae, 0x73, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x0f, 0xb5, 0x7a, 0xff, 0x16, 0xbd, 0x81, 0xff, 0x10, 0xbc, 0x7e, 0xff, 0x0e, 0xb7, 0x78, 0xff, 0x0b, 0xb7, 0x77, 0xff, 0x0b, 0xb1, 0x72, 0xff, 0x09, 0x8a, 0x54, 0xff, 0x02, 0x55, 0x2b, 0xff, 0x04, 0x39, 0x18, 0xff, 0x06, 0x31, 0x16, 0xff, 0x08, 0x29, 0x10, 0xff, 0x05, 0x24, 0x0c, 0xff, 0x06, 0x23, 0x0b, 0xff, 0x03, 0x21, 0x09, 0xff, 0x02, 0x21, 0x08, 0xff, 0x01, 0x21, 0x08, 0xff, 0x00, 0x1f, 0x06, 0xff, 0x01, 0x1f, 0x07, 0xff, 0x02, 0x1e, 0x0a, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x01, 0x1c, 0x09, 0xff, 0x01, 0x1b, 0x08, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x00, 0x1a, 0x07, 0xff, 0x00, 0x1c, 0x09, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x00, 0x1c, 0x06, 0xff, 0x00, 0x1d, 0x06, 0xff, 0x00, 0x1c, 0x06, 0xff, 0x01, 0x1d, 0x07, 0xff, 0x00, 0x1f, 0x08, 0xff, 0x01, 0x21, 0x0a, 0xff, 0x01, 0x22, 0x0b, 0xff, 0x02, 0x23, 0x0c, 0xff, 0x02, 0x26, 0x0b, 0xff, 0x02, 0x29, 0x0e, 0xff, 0x01, 0x2a, 0x0f, 0xff, 0x01, 0x2d, 0x14, 0xff, 0x02, 0x31, 0x16, 0xff, 0x02, 0x35, 0x18, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x05, 0x48, 0x26, 0xff, 0x04, 0x62, 0x38, 0xff, 0x09, 0x80, 0x51, 0xff, 0x11, 0xa7, 0x72, 0xff, 0x0c, 0xaf, 0x77, 0xff, 0x0e, 0xaf, 0x75, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x02, 0x9f, 0x63, 0xff, 0x02, 0xa2, 0x65, 0xff, 0x03, 0x9d, 0x60, 0xff, 0x07, 0xa1, 0x61, 0xff, 0x0e, 0xa8, 0x66, 0xff, 0x0a, 0xa4, 0x64, 0xff, 0x0a, 0xa8, 0x6b, 0xff, 0x0f, 0xaf, 0x75, 0xff, 0x12, 0xb1, 0x75, 0xff, 0x07, 0xa5, 0x67, 0xff, 0x13, 0xb1, 0x74, 0xff, 0x0e, 0xac, 0x6c, 0xff, 0x0d, 0xa9, 0x68, 0xff, 0x15, 0xaf, 0x6e, 0xff, 0x0c, 0xa4, 0x65, 0xff, 0x0f, 0xa8, 0x6a, 0xff, 0x10, 0xaa, 0x6f, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0e, 0xab, 0x73, 0xff, 0x0b, 0xaa, 0x74, 0xff, 0x0a, 0xab, 0x75, 0xff, 0x10, 0xb0, 0x7b, 0xff, 0x12, 0xb3, 0x7e, 0xff, 0x13, 0xb4, 0x7e, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x16, 0xb6, 0x82, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x18, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x17, 0xba, 0x84, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x17, 0xba, 0x83, 0xff, 0x17, 0xba, 0x83, 0xff, 0x16, 0xb9, 0x81, 0xff, 0x1c, 0xbb, 0x84, 0xff, 0x1b, 0xb9, 0x82, 0xff, 0x14, 0xb6, 0x7f, 0xff, 0x12, 0xb2, 0x7c, 0xff, 0x08, 0x9f, 0x6a, 0xff, 0x01, 0x87, 0x55, 0xff, 0x02, 0x73, 0x44, 0xff, 0x06, 0x6a, 0x3e, 0xff, 0x09, 0x61, 0x38, 0xff, 0x02, 0x54, 0x2f, 0xff, 0x01, 0x4c, 0x28, 0xff, 0x00, 0x45, 0x23, 0xff, 0x01, 0x42, 0x24, 0xff, 0x02, 0x42, 0x25, 0xff, 0x04, 0x3d, 0x22, 0xff, 0x05, 0x36, 0x1e, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x03, 0x31, 0x1b, 0xff, 0x03, 0x31, 0x1c, 0xff, 0x01, 0x2f, 0x1a, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x04, 0x32, 0x1e, 0xff, 0x04, 0x33, 0x1e, 0xff, 0x05, 0x32, 0x1f, 0xff, 0x06, 0x30, 0x1e, 0xff, 0x04, 0x2e, 0x1c, 0xff, 0x02, 0x2e, 0x19, 0xff, 0x01, 0x2d, 0x18, 0xff, 0x01, 0x2c, 0x17, 0xff, 0x00, 0x2e, 0x17, 0xff, 0x02, 0x30, 0x19, 0xff, 0x04, 0x32, 0x1b, 0xff, 0x02, 0x34, 0x1a, 0xff, 0x05, 0x37, 0x1d, 0xff, 0x06, 0x3a, 0x1e, 0xff, 0x04, 0x3d, 0x20, 0xff, 0x02, 0x3e, 0x20, 0xff, 0x02, 0x44, 0x24, 0xff, 0x02, 0x46, 0x25, 0xff, 0x01, 0x4c, 0x27, 0xff, 0x01, 0x54, 0x2b, 0xff, 0x05, 0x5c, 0x33, 0xff, 0x05, 0x65, 0x3b, 0xff, 0x07, 0x7b, 0x4f, 0xff, 0x0f, 0x95, 0x67, 0xff, 0x16, 0xaf, 0x7e, 0xff, 0x17, 0xb9, 0x86, 0xff, 0x15, 0xba, 0x86, 0xff, 0x16, 0xb9, 0x86, 0xff, 0x16, 0xb8, 0x86, 0xff, 0x19, 0xba, 0x89, 0xff, 0x1c, 0xbc, 0x8c, 0xff, 0x1d, 0xba, 0x8b, 0xff, 0x1d, 0xba, 0x8d, 0xff, 0x1b, 0xb6, 0x89, 0xff, 0x14, 0xae, 0x82, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x12, 0xaa, 0x7f, 0xff, 0x12, 0xaa, 0x7e, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x12, 0xac, 0x7c, 0xff, 0x10, 0xaa, 0x79, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0b, 0xa7, 0x73, 0xff, 0x0b, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0a, 0xa8, 0x75, 0xff, 0x09, 0xa8, 0x75, 0xff, 0x09, 0xaa, 0x75, 0xff, 0x0e, 0xaa, 0x74, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x05, 0xa3, 0x66, 0xff, 0x08, 0xa3, 0x69, 0xff, 0x1c, 0xb0, 0x7b, 0xff, 0x1f, 0xab, 0x7a, 0xff, 0x2e, 0xa6, 0x7b, 0xff, 0x51, 0xad, 0x84, 0xff, 0x45, 0x98, 0x74, 0xff, 0x46, 0x92, 0x73, 0xff, 0x43, 0x8b, 0x72, 0xff, 0x39, 0x8a, 0x6e, 0xff, 0x37, 0xa1, 0x7a, 0xff, 0x20, 0xa1, 0x71, 0xff, 0x13, 0xa8, 0x70, 0xff, 0x0d, 0xac, 0x72, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x05, 0x90, 0x59, 0xff, 0x02, 0x72, 0x3d, 0xff, 0x04, 0x5a, 0x2c, 0xff, 0x00, 0x47, 0x20, 0xff, 0x00, 0x40, 0x20, 0xff, 0x02, 0x3e, 0x1d, 0xff, 0x04, 0x3a, 0x1b, 0xff, 0x02, 0x33, 0x16, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x03, 0x30, 0x17, 0xff, 0x02, 0x2f, 0x15, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x03, 0x2d, 0x13, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x00, 0x2c, 0x12, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x01, 0x2c, 0x12, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x01, 0x2c, 0x13, 0xff, 0x01, 0x2d, 0x13, 0xff, 0x04, 0x2e, 0x15, 0xff, 0x05, 0x2f, 0x15, 0xff, 0x05, 0x30, 0x17, 0xff, 0x05, 0x31, 0x17, 0xff, 0x04, 0x2f, 0x16, 0xff, 0x04, 0x31, 0x17, 0xff, 0x03, 0x31, 0x16, 0xff, 0x04, 0x32, 0x18, 0xff, 0x02, 0x34, 0x1a, 0xff, 0x04, 0x37, 0x1b, 0xff, 0x05, 0x38, 0x1c, 0xff, 0x04, 0x39, 0x1d, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x01, 0x3b, 0x1d, 0xff, 0x01, 0x3c, 0x1d, 0xff, 0x00, 0x3f, 0x20, 0xff, 0x01, 0x41, 0x20, 0xff, 0x00, 0x48, 0x24, 0xff, 0x05, 0x5f, 0x39, 0xff, 0x13, 0x81, 0x57, 0xff, 0x0a, 0x87, 0x5a, 0xff, 0x11, 0xa3, 0x6f, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x08, 0xa2, 0x65, 0xff, 0x09, 0xa0, 0x63, 0xff, 0x0a, 0xa1, 0x63, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x09, 0x9e, 0x5d, 0xff, 0x0a, 0x9d, 0x59, 0xff, 0x08, 0x9c, 0x57, 0xff, 0x0a, 0x9c, 0x57, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x08, 0x9a, 0x55, 0xff, 0x07, 0x9a, 0x54, 0xff, 0x08, 0x99, 0x54, 0xff, 0x09, 0x97, 0x52, 0xff, 0x08, 0x95, 0x50, 0xff, 0x0b, 0x92, 0x4e, 0xff, 0x0a, 0x8f, 0x4c, 0xff, 0x07, 0x8b, 0x48, 0xff, 0x07, 0x8b, 0x48, 0xff, 0x08, 0x8c, 0x49, 0xff, 0x08, 0x8b, 0x48, 0xff, 0x08, 0x89, 0x46, 0xff, 0x09, 0x88, 0x45, 0xff, 0x09, 0x86, 0x44, 0xff, 0x0f, 0x82, 0x49, 0xff, 0x0e, 0x82, 0x48, 0xff, 0x06, 0x82, 0x41, 0xff, 0x03, 0x80, 0x3c, 0xff, 0x08, 0x7d, 0x3f, 0xff, 0x07, 0x77, 0x40, 0xff, 0x05, 0x76, 0x40, 0xff, 0x16, 0x92, 0x59, 0xff, 0x34, 0xbf, 0x83, 0xff, 0x2f, 0xc0, 0x82, 0xff, 0x25, 0xb1, 0x76, 0xff, 0x23, 0xaa, 0x78, 0xff, 0x22, 0xab, 0x7a, 0xff, 0x20, 0xb3, 0x71, 0xff, 0x1d, 0xb5, 0x67, 0xff, 0x29, 0xc0, 0x73, 0xff, 0x3c, 0xce, 0x8d, 0xff, 0x5a, 0xe2, 0xb9, 0xff, 0x55, 0xd7, 0xbb, 0xff, 0x3d, 0xad, 0x92, 0xff, 0x17, 0x6c, 0x48, 0xff, 0x09, 0x42, 0x18, 0xff, 0x03, 0x34, 0x0c, 0xff, 0x01, 0x37, 0x10, 0xff, 0x03, 0x35, 0x15, 0xff, 0x0e, 0x45, 0x30, 0xff, 0x44, 0x98, 0x86, 0xff, 0x39, 0x84, 0x75, 0xff, 0x06, 0x32, 0x22, 0xff, 0x06, 0x32, 0x1d, 0xff, 0x29, 0x49, 0x3e, 0xff, 0x77, 0x85, 0x81, 0xff, + 0x11, 0x25, 0xa5, 0xff, 0x0d, 0x26, 0xa0, 0xff, 0x18, 0x2c, 0x9f, 0xff, 0x23, 0x38, 0x95, 0xff, 0x2a, 0x3e, 0x8a, 0xff, 0x41, 0x4a, 0x8a, 0xff, 0x59, 0x5c, 0x8e, 0xff, 0x6a, 0x6e, 0x91, 0xff, 0x68, 0x6b, 0x88, 0xff, 0x8a, 0x8a, 0xa1, 0xff, 0x90, 0x8d, 0xa0, 0xff, 0x79, 0x74, 0x85, 0xff, 0x8d, 0x86, 0x99, 0xff, 0x98, 0x8f, 0xa6, 0xff, 0x86, 0x7d, 0x91, 0xff, 0x78, 0x73, 0x80, 0xff, 0x78, 0x78, 0x85, 0xff, 0x6e, 0x6d, 0x85, 0xff, 0x56, 0x58, 0x84, 0xff, 0x32, 0x44, 0x94, 0xff, 0x2e, 0x4c, 0xb6, 0xff, 0x4a, 0x63, 0xe4, 0xff, 0x47, 0x5c, 0xe3, 0xff, 0x36, 0x6c, 0xd0, 0xff, 0x0d, 0x79, 0x90, 0xff, 0x0b, 0xa5, 0x73, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x06, 0xae, 0x6d, 0xff, 0x0d, 0xad, 0x77, 0xff, 0x0a, 0xa9, 0x73, 0xff, 0x07, 0xab, 0x73, 0xff, 0x08, 0xad, 0x74, 0xff, 0x07, 0xac, 0x73, 0xff, 0x09, 0xaf, 0x75, 0xff, 0x0c, 0xb2, 0x77, 0xff, 0x0c, 0xb2, 0x77, 0xff, 0x0e, 0xb4, 0x77, 0xff, 0x12, 0xb8, 0x7b, 0xff, 0x15, 0xbc, 0x7e, 0xff, 0x13, 0xba, 0x7a, 0xff, 0x0a, 0xb7, 0x78, 0xff, 0x06, 0xb4, 0x74, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x06, 0x6e, 0x40, 0xff, 0x00, 0x32, 0x11, 0xff, 0x02, 0x26, 0x0c, 0xff, 0x01, 0x1e, 0x08, 0xff, 0x03, 0x1b, 0x07, 0xff, 0x08, 0x19, 0x06, 0xff, 0x08, 0x18, 0x05, 0xff, 0x07, 0x1b, 0x07, 0xff, 0x03, 0x1a, 0x06, 0xff, 0x03, 0x1b, 0x07, 0xff, 0x02, 0x1b, 0x06, 0xff, 0x02, 0x1a, 0x08, 0xff, 0x04, 0x19, 0x07, 0xff, 0x02, 0x18, 0x06, 0xff, 0x02, 0x16, 0x05, 0xff, 0x03, 0x16, 0x05, 0xff, 0x01, 0x16, 0x04, 0xff, 0x02, 0x19, 0x07, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x02, 0x19, 0x06, 0xff, 0x02, 0x18, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x1a, 0x06, 0xff, 0x02, 0x1c, 0x08, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x03, 0x1e, 0x09, 0xff, 0x02, 0x20, 0x07, 0xff, 0x01, 0x20, 0x07, 0xff, 0x00, 0x20, 0x08, 0xff, 0x01, 0x27, 0x0e, 0xff, 0x00, 0x2a, 0x11, 0xff, 0x00, 0x2c, 0x13, 0xff, 0x00, 0x31, 0x13, 0xff, 0x00, 0x39, 0x19, 0xff, 0x01, 0x55, 0x2d, 0xff, 0x0f, 0x82, 0x55, 0xff, 0x12, 0xaa, 0x74, 0xff, 0x0d, 0xb3, 0x7a, 0xff, 0x0e, 0xae, 0x76, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x04, 0xa1, 0x65, 0xff, 0x01, 0xa1, 0x63, 0xff, 0x09, 0xa3, 0x66, 0xff, 0x06, 0x9d, 0x5f, 0xff, 0x0d, 0xa3, 0x64, 0xff, 0x0a, 0xa0, 0x62, 0xff, 0x07, 0xa1, 0x65, 0xff, 0x06, 0xa0, 0x67, 0xff, 0x14, 0xb0, 0x74, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x10, 0xac, 0x6e, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x15, 0xae, 0x6f, 0xff, 0x15, 0xad, 0x6e, 0xff, 0x11, 0xa9, 0x6b, 0xff, 0x15, 0xae, 0x71, 0xff, 0x16, 0xb1, 0x75, 0xff, 0x11, 0xac, 0x73, 0xff, 0x0e, 0xa9, 0x70, 0xff, 0x0d, 0xa9, 0x70, 0xff, 0x0e, 0xac, 0x75, 0xff, 0x0f, 0xb0, 0x78, 0xff, 0x0e, 0xb1, 0x7a, 0xff, 0x13, 0xb5, 0x80, 0xff, 0x13, 0xb5, 0x81, 0xff, 0x13, 0xb4, 0x81, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x15, 0xb6, 0x82, 0xff, 0x18, 0xb9, 0x85, 0xff, 0x1a, 0xba, 0x86, 0xff, 0x1a, 0xba, 0x86, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x18, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x17, 0xba, 0x83, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x17, 0xba, 0x83, 0xff, 0x17, 0xba, 0x83, 0xff, 0x17, 0xba, 0x82, 0xff, 0x1c, 0xba, 0x82, 0xff, 0x18, 0xb8, 0x80, 0xff, 0x15, 0xb9, 0x80, 0xff, 0x10, 0xb2, 0x7a, 0xff, 0x09, 0x9e, 0x67, 0xff, 0x00, 0x7d, 0x4b, 0xff, 0x05, 0x6c, 0x3e, 0xff, 0x0c, 0x62, 0x39, 0xff, 0x0c, 0x56, 0x33, 0xff, 0x02, 0x4a, 0x27, 0xff, 0x03, 0x45, 0x26, 0xff, 0x01, 0x3f, 0x22, 0xff, 0x01, 0x3c, 0x22, 0xff, 0x03, 0x39, 0x23, 0xff, 0x05, 0x33, 0x1d, 0xff, 0x03, 0x2b, 0x17, 0xff, 0x01, 0x28, 0x14, 0xff, 0x03, 0x2b, 0x19, 0xff, 0x04, 0x2c, 0x1a, 0xff, 0x04, 0x2b, 0x1a, 0xff, 0x04, 0x2b, 0x1a, 0xff, 0x03, 0x2a, 0x18, 0xff, 0x03, 0x2a, 0x18, 0xff, 0x02, 0x28, 0x16, 0xff, 0x04, 0x2a, 0x19, 0xff, 0x04, 0x29, 0x19, 0xff, 0x03, 0x29, 0x18, 0xff, 0x01, 0x27, 0x16, 0xff, 0x01, 0x26, 0x15, 0xff, 0x02, 0x26, 0x15, 0xff, 0x03, 0x28, 0x15, 0xff, 0x02, 0x28, 0x14, 0xff, 0x03, 0x29, 0x14, 0xff, 0x01, 0x2a, 0x14, 0xff, 0x04, 0x2c, 0x17, 0xff, 0x03, 0x2e, 0x18, 0xff, 0x03, 0x31, 0x18, 0xff, 0x02, 0x34, 0x1b, 0xff, 0x06, 0x3c, 0x22, 0xff, 0x06, 0x3e, 0x23, 0xff, 0x02, 0x43, 0x24, 0xff, 0x01, 0x48, 0x24, 0xff, 0x02, 0x50, 0x2c, 0xff, 0x02, 0x5a, 0x34, 0xff, 0x07, 0x76, 0x4b, 0xff, 0x0d, 0x92, 0x64, 0xff, 0x15, 0xb0, 0x7f, 0xff, 0x14, 0xba, 0x87, 0xff, 0x13, 0xbb, 0x86, 0xff, 0x17, 0xba, 0x87, 0xff, 0x18, 0xba, 0x88, 0xff, 0x1a, 0xba, 0x89, 0xff, 0x1b, 0xbb, 0x8b, 0xff, 0x1a, 0xb8, 0x8a, 0xff, 0x1a, 0xb7, 0x89, 0xff, 0x16, 0xb1, 0x84, 0xff, 0x10, 0xaa, 0x7d, 0xff, 0x11, 0xa9, 0x7e, 0xff, 0x11, 0xaa, 0x7e, 0xff, 0x11, 0xab, 0x7d, 0xff, 0x11, 0xab, 0x7b, 0xff, 0x10, 0xaa, 0x78, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x09, 0xa5, 0x70, 0xff, 0x0a, 0xa7, 0x73, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0b, 0xa5, 0x74, 0xff, 0x0a, 0xa7, 0x75, 0xff, 0x08, 0xa6, 0x75, 0xff, 0x07, 0xa5, 0x72, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x06, 0xa1, 0x67, 0xff, 0x03, 0x9f, 0x66, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x2d, 0xbb, 0x88, 0xff, 0x1f, 0xa2, 0x73, 0xff, 0x37, 0xa8, 0x7c, 0xff, 0x35, 0x93, 0x6a, 0xff, 0x2d, 0x81, 0x5f, 0xff, 0x3d, 0x88, 0x6c, 0xff, 0x41, 0x8b, 0x74, 0xff, 0x55, 0xa7, 0x8c, 0xff, 0x21, 0x8b, 0x64, 0xff, 0x17, 0x96, 0x65, 0xff, 0x11, 0xa2, 0x69, 0xff, 0x0e, 0xa8, 0x6d, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0e, 0xa9, 0x72, 0xff, 0x0c, 0x92, 0x5c, 0xff, 0x03, 0x6e, 0x3a, 0xff, 0x05, 0x56, 0x2a, 0xff, 0x00, 0x44, 0x1f, 0xff, 0x00, 0x3d, 0x1e, 0xff, 0x05, 0x3a, 0x1c, 0xff, 0x03, 0x30, 0x15, 0xff, 0x01, 0x29, 0x0e, 0xff, 0x04, 0x29, 0x12, 0xff, 0x02, 0x29, 0x13, 0xff, 0x02, 0x29, 0x10, 0xff, 0x01, 0x26, 0x0d, 0xff, 0x02, 0x25, 0x0d, 0xff, 0x01, 0x26, 0x0d, 0xff, 0x01, 0x25, 0x0c, 0xff, 0x01, 0x25, 0x0c, 0xff, 0x01, 0x26, 0x0d, 0xff, 0x00, 0x25, 0x0e, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x00, 0x25, 0x0d, 0xff, 0x02, 0x26, 0x0e, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x04, 0x27, 0x0f, 0xff, 0x04, 0x28, 0x11, 0xff, 0x01, 0x25, 0x0d, 0xff, 0x02, 0x26, 0x0e, 0xff, 0x02, 0x27, 0x0f, 0xff, 0x03, 0x29, 0x11, 0xff, 0x00, 0x2c, 0x13, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x03, 0x31, 0x17, 0xff, 0x04, 0x33, 0x17, 0xff, 0x03, 0x35, 0x19, 0xff, 0x03, 0x36, 0x19, 0xff, 0x03, 0x38, 0x1b, 0xff, 0x02, 0x3a, 0x1c, 0xff, 0x03, 0x3a, 0x1c, 0xff, 0x01, 0x3f, 0x1f, 0xff, 0x04, 0x51, 0x2f, 0xff, 0x13, 0x77, 0x51, 0xff, 0x05, 0x7c, 0x50, 0xff, 0x08, 0x96, 0x64, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x09, 0xa1, 0x65, 0xff, 0x0a, 0xa3, 0x65, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x07, 0x9e, 0x5f, 0xff, 0x09, 0x9e, 0x5d, 0xff, 0x09, 0x9e, 0x5c, 0xff, 0x0a, 0x9d, 0x59, 0xff, 0x09, 0x9c, 0x58, 0xff, 0x0a, 0x9c, 0x57, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x09, 0x99, 0x54, 0xff, 0x08, 0x99, 0x54, 0xff, 0x08, 0x98, 0x53, 0xff, 0x08, 0x95, 0x51, 0xff, 0x09, 0x93, 0x4f, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x09, 0x8e, 0x4b, 0xff, 0x08, 0x8c, 0x49, 0xff, 0x08, 0x8c, 0x49, 0xff, 0x08, 0x8b, 0x48, 0xff, 0x08, 0x89, 0x46, 0xff, 0x07, 0x88, 0x45, 0xff, 0x08, 0x87, 0x45, 0xff, 0x0b, 0x87, 0x45, 0xff, 0x08, 0x84, 0x47, 0xff, 0x08, 0x84, 0x46, 0xff, 0x08, 0x81, 0x40, 0xff, 0x09, 0x7d, 0x3d, 0xff, 0x0b, 0x7c, 0x3f, 0xff, 0x06, 0x79, 0x41, 0xff, 0x10, 0x8b, 0x50, 0xff, 0x38, 0xc1, 0x80, 0xff, 0x2b, 0xb3, 0x76, 0xff, 0x1a, 0x93, 0x63, 0xff, 0x28, 0x8d, 0x6c, 0xff, 0x53, 0xa4, 0x99, 0xff, 0x5f, 0xae, 0xad, 0xff, 0x3d, 0x9f, 0x91, 0xff, 0x25, 0xa0, 0x77, 0xff, 0x17, 0xaf, 0x63, 0xff, 0x16, 0xa7, 0x57, 0xff, 0x2d, 0xb2, 0x68, 0xff, 0x41, 0xd0, 0x8c, 0xff, 0x5d, 0xf4, 0xbe, 0xff, 0x60, 0xdd, 0xb5, 0xff, 0x26, 0x76, 0x56, 0xff, 0x0a, 0x48, 0x25, 0xff, 0x00, 0x36, 0x11, 0xff, 0x05, 0x30, 0x10, 0xff, 0x09, 0x2e, 0x18, 0xff, 0x0d, 0x45, 0x35, 0xff, 0x67, 0xc0, 0xb3, 0xff, 0x21, 0x63, 0x53, 0xff, 0x01, 0x31, 0x18, 0xff, 0x0f, 0x38, 0x23, 0xff, 0x6e, 0x81, 0x76, 0xff, + 0x16, 0x26, 0x9a, 0xff, 0x1b, 0x30, 0x91, 0xff, 0x2f, 0x40, 0x8f, 0xff, 0x44, 0x57, 0x89, 0xff, 0x5a, 0x6a, 0x88, 0xff, 0x7e, 0x7f, 0x99, 0xff, 0x8d, 0x8b, 0xa0, 0xff, 0x8d, 0x8f, 0x9e, 0xff, 0x7f, 0x7f, 0x8b, 0xff, 0x9b, 0x96, 0xa1, 0xff, 0x9f, 0x97, 0xa2, 0xff, 0x7f, 0x76, 0x83, 0xff, 0x8f, 0x87, 0x9a, 0xff, 0x95, 0x8f, 0xa7, 0xff, 0x7f, 0x7a, 0x90, 0xff, 0x8d, 0x8a, 0x9b, 0xff, 0x93, 0x92, 0x9d, 0xff, 0x8e, 0x87, 0x8f, 0xff, 0x76, 0x73, 0x7f, 0xff, 0x48, 0x58, 0x7b, 0xff, 0x39, 0x5a, 0x9c, 0xff, 0x54, 0x70, 0xe1, 0xff, 0x40, 0x57, 0xd9, 0xff, 0x30, 0x65, 0xc1, 0xff, 0x05, 0x6e, 0x82, 0xff, 0x0b, 0xa3, 0x71, 0xff, 0x08, 0xa5, 0x70, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x03, 0xad, 0x6c, 0xff, 0x07, 0xab, 0x75, 0xff, 0x07, 0xa8, 0x75, 0xff, 0x0d, 0xb0, 0x7a, 0xff, 0x0b, 0xae, 0x77, 0xff, 0x17, 0xbb, 0x83, 0xff, 0x0f, 0xb4, 0x7b, 0xff, 0x0c, 0xb1, 0x78, 0xff, 0x0c, 0xb2, 0x76, 0xff, 0x0d, 0xb3, 0x75, 0xff, 0x0f, 0xb5, 0x77, 0xff, 0x13, 0xbb, 0x7d, 0xff, 0x12, 0xb9, 0x7a, 0xff, 0x0f, 0xb7, 0x78, 0xff, 0x0a, 0xb5, 0x76, 0xff, 0x09, 0xaf, 0x73, 0xff, 0x14, 0xa0, 0x6c, 0xff, 0x06, 0x4f, 0x29, 0xff, 0x00, 0x23, 0x07, 0xff, 0x00, 0x1a, 0x05, 0xff, 0x00, 0x17, 0x04, 0xff, 0x02, 0x14, 0x03, 0xff, 0x05, 0x15, 0x05, 0xff, 0x04, 0x17, 0x06, 0xff, 0x03, 0x16, 0x05, 0xff, 0x04, 0x16, 0x06, 0xff, 0x04, 0x16, 0x06, 0xff, 0x00, 0x16, 0x04, 0xff, 0x01, 0x15, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x04, 0x16, 0x05, 0xff, 0x02, 0x16, 0x04, 0xff, 0x01, 0x17, 0x05, 0xff, 0x02, 0x18, 0x06, 0xff, 0x04, 0x17, 0x06, 0xff, 0x04, 0x17, 0x06, 0xff, 0x03, 0x18, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x02, 0x19, 0x07, 0xff, 0x04, 0x1b, 0x09, 0xff, 0x03, 0x19, 0x07, 0xff, 0x02, 0x19, 0x06, 0xff, 0x00, 0x1b, 0x05, 0xff, 0x00, 0x1b, 0x04, 0xff, 0x00, 0x1c, 0x06, 0xff, 0x03, 0x20, 0x0b, 0xff, 0x05, 0x23, 0x0e, 0xff, 0x04, 0x27, 0x0f, 0xff, 0x03, 0x2c, 0x11, 0xff, 0x00, 0x30, 0x12, 0xff, 0x04, 0x57, 0x31, 0xff, 0x17, 0x8e, 0x61, 0xff, 0x14, 0xac, 0x78, 0xff, 0x0e, 0xb3, 0x7b, 0xff, 0x16, 0xb7, 0x7e, 0xff, 0x17, 0xb0, 0x78, 0xff, 0x0c, 0xa9, 0x6d, 0xff, 0x03, 0xa4, 0x67, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x08, 0x9d, 0x61, 0xff, 0x0a, 0x9d, 0x5f, 0xff, 0x0b, 0x9e, 0x62, 0xff, 0x07, 0x9c, 0x63, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x07, 0xa0, 0x66, 0xff, 0x08, 0xa1, 0x64, 0xff, 0x07, 0xa0, 0x63, 0xff, 0x0d, 0xa6, 0x69, 0xff, 0x13, 0xac, 0x6e, 0xff, 0x09, 0xa2, 0x63, 0xff, 0x09, 0xa2, 0x65, 0xff, 0x10, 0xaa, 0x6d, 0xff, 0x11, 0xac, 0x70, 0xff, 0x11, 0xae, 0x72, 0xff, 0x10, 0xad, 0x74, 0xff, 0x10, 0xad, 0x74, 0xff, 0x0f, 0xaf, 0x77, 0xff, 0x10, 0xb2, 0x7a, 0xff, 0x12, 0xb5, 0x7e, 0xff, 0x14, 0xb6, 0x81, 0xff, 0x14, 0xb6, 0x83, 0xff, 0x14, 0xb5, 0x83, 0xff, 0x13, 0xb5, 0x81, 0xff, 0x14, 0xb5, 0x81, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x17, 0xb8, 0x84, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x17, 0xba, 0x83, 0xff, 0x17, 0xba, 0x83, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x17, 0xba, 0x83, 0xff, 0x16, 0xb9, 0x81, 0xff, 0x17, 0xba, 0x80, 0xff, 0x17, 0xbb, 0x81, 0xff, 0x14, 0xba, 0x80, 0xff, 0x10, 0xb3, 0x78, 0xff, 0x11, 0xa4, 0x6d, 0xff, 0x02, 0x7f, 0x4c, 0xff, 0x06, 0x66, 0x3a, 0xff, 0x0c, 0x5a, 0x32, 0xff, 0x09, 0x4d, 0x2c, 0xff, 0x04, 0x45, 0x26, 0xff, 0x05, 0x3f, 0x23, 0xff, 0x05, 0x3a, 0x21, 0xff, 0x02, 0x33, 0x1e, 0xff, 0x02, 0x2f, 0x1c, 0xff, 0x01, 0x28, 0x16, 0xff, 0x02, 0x24, 0x12, 0xff, 0x04, 0x24, 0x15, 0xff, 0x04, 0x27, 0x17, 0xff, 0x03, 0x26, 0x16, 0xff, 0x03, 0x26, 0x16, 0xff, 0x01, 0x24, 0x14, 0xff, 0x01, 0x21, 0x12, 0xff, 0x00, 0x20, 0x10, 0xff, 0x00, 0x21, 0x11, 0xff, 0x00, 0x22, 0x13, 0xff, 0x01, 0x23, 0x13, 0xff, 0x01, 0x23, 0x14, 0xff, 0x01, 0x23, 0x13, 0xff, 0x01, 0x23, 0x13, 0xff, 0x02, 0x23, 0x13, 0xff, 0x03, 0x25, 0x13, 0xff, 0x02, 0x24, 0x13, 0xff, 0x02, 0x24, 0x12, 0xff, 0x01, 0x25, 0x13, 0xff, 0x01, 0x24, 0x13, 0xff, 0x01, 0x25, 0x12, 0xff, 0x00, 0x26, 0x12, 0xff, 0x00, 0x2a, 0x15, 0xff, 0x02, 0x30, 0x1a, 0xff, 0x03, 0x33, 0x1d, 0xff, 0x02, 0x36, 0x1c, 0xff, 0x03, 0x3e, 0x1f, 0xff, 0x01, 0x42, 0x23, 0xff, 0x01, 0x4f, 0x2d, 0xff, 0x08, 0x72, 0x4b, 0xff, 0x0f, 0x90, 0x65, 0xff, 0x19, 0xb2, 0x81, 0xff, 0x18, 0xbb, 0x88, 0xff, 0x14, 0xbb, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x1a, 0xbc, 0x88, 0xff, 0x19, 0xba, 0x87, 0xff, 0x19, 0xb8, 0x87, 0xff, 0x17, 0xb6, 0x85, 0xff, 0x1d, 0xb9, 0x8a, 0xff, 0x16, 0xb2, 0x84, 0xff, 0x0e, 0xa9, 0x7b, 0xff, 0x11, 0xaa, 0x7d, 0xff, 0x11, 0xaa, 0x7c, 0xff, 0x0d, 0xa7, 0x78, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0a, 0xa6, 0x76, 0xff, 0x09, 0xa5, 0x76, 0xff, 0x09, 0xa6, 0x75, 0xff, 0x09, 0xa6, 0x72, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x05, 0xa1, 0x6a, 0xff, 0x03, 0x9f, 0x68, 0xff, 0x06, 0x9d, 0x67, 0xff, 0x12, 0x9d, 0x6b, 0xff, 0x1e, 0x9b, 0x6d, 0xff, 0x37, 0xa6, 0x7b, 0xff, 0x37, 0x9e, 0x73, 0xff, 0x2a, 0x87, 0x63, 0xff, 0x39, 0x8e, 0x70, 0xff, 0x34, 0x87, 0x6e, 0xff, 0x2d, 0x8a, 0x6c, 0xff, 0x17, 0x88, 0x5e, 0xff, 0x0e, 0x8f, 0x5c, 0xff, 0x06, 0x96, 0x5b, 0xff, 0x10, 0xa6, 0x6c, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0a, 0xaa, 0x70, 0xff, 0x13, 0xa0, 0x6a, 0xff, 0x04, 0x77, 0x41, 0xff, 0x01, 0x4d, 0x22, 0xff, 0x00, 0x3b, 0x19, 0xff, 0x05, 0x35, 0x19, 0xff, 0x06, 0x30, 0x16, 0xff, 0x01, 0x25, 0x0c, 0xff, 0x05, 0x26, 0x0e, 0xff, 0x04, 0x23, 0x0e, 0xff, 0x00, 0x21, 0x0c, 0xff, 0x00, 0x21, 0x0b, 0xff, 0x00, 0x1e, 0x0a, 0xff, 0x02, 0x1f, 0x08, 0xff, 0x01, 0x1f, 0x0b, 0xff, 0x01, 0x20, 0x0b, 0xff, 0x01, 0x20, 0x0b, 0xff, 0x01, 0x1e, 0x09, 0xff, 0x00, 0x1e, 0x0a, 0xff, 0x00, 0x1e, 0x0a, 0xff, 0x00, 0x1d, 0x09, 0xff, 0x00, 0x1d, 0x08, 0xff, 0x02, 0x1e, 0x0a, 0xff, 0x00, 0x1e, 0x09, 0xff, 0x01, 0x1e, 0x09, 0xff, 0x01, 0x1e, 0x08, 0xff, 0x00, 0x1d, 0x08, 0xff, 0x00, 0x1e, 0x09, 0xff, 0x00, 0x1e, 0x09, 0xff, 0x01, 0x21, 0x0c, 0xff, 0x00, 0x24, 0x0e, 0xff, 0x00, 0x25, 0x0c, 0xff, 0x00, 0x27, 0x0e, 0xff, 0x02, 0x29, 0x10, 0xff, 0x02, 0x2c, 0x12, 0xff, 0x02, 0x2e, 0x14, 0xff, 0x02, 0x31, 0x15, 0xff, 0x04, 0x34, 0x19, 0xff, 0x07, 0x38, 0x1c, 0xff, 0x02, 0x39, 0x1c, 0xff, 0x05, 0x49, 0x29, 0xff, 0x14, 0x74, 0x4f, 0xff, 0x08, 0x7c, 0x52, 0xff, 0x0c, 0x95, 0x64, 0xff, 0x13, 0xa4, 0x6f, 0xff, 0x11, 0xa7, 0x6e, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x10, 0xa9, 0x6b, 0xff, 0x0d, 0xa5, 0x66, 0xff, 0x07, 0xa0, 0x5f, 0xff, 0x0a, 0xa0, 0x5f, 0xff, 0x09, 0x9e, 0x5b, 0xff, 0x09, 0x9d, 0x59, 0xff, 0x09, 0x9c, 0x58, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x0b, 0x9a, 0x55, 0xff, 0x0a, 0x99, 0x54, 0xff, 0x08, 0x97, 0x52, 0xff, 0x08, 0x96, 0x51, 0xff, 0x08, 0x94, 0x50, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x09, 0x8d, 0x4a, 0xff, 0x09, 0x8d, 0x4a, 0xff, 0x09, 0x8c, 0x49, 0xff, 0x09, 0x8a, 0x47, 0xff, 0x08, 0x88, 0x45, 0xff, 0x08, 0x87, 0x44, 0xff, 0x09, 0x87, 0x44, 0xff, 0x0a, 0x86, 0x44, 0xff, 0x03, 0x85, 0x43, 0xff, 0x04, 0x83, 0x41, 0xff, 0x09, 0x7d, 0x3f, 0xff, 0x0c, 0x7b, 0x3f, 0xff, 0x07, 0x7b, 0x40, 0xff, 0x13, 0x93, 0x55, 0xff, 0x32, 0xb5, 0x76, 0xff, 0x22, 0xa5, 0x64, 0xff, 0x0c, 0x7c, 0x4c, 0xff, 0x26, 0x72, 0x68, 0xff, 0x6d, 0x9f, 0xac, 0xff, 0xa0, 0xba, 0xda, 0xff, 0x9e, 0xb6, 0xe5, 0xff, 0x32, 0x5b, 0x9b, 0xff, 0x15, 0x5c, 0x8a, 0xff, 0x29, 0x9e, 0x8f, 0xff, 0x1a, 0x9d, 0x64, 0xff, 0x1a, 0x8f, 0x44, 0xff, 0x22, 0x96, 0x49, 0xff, 0x30, 0xb3, 0x6c, 0xff, 0x54, 0xd8, 0xa1, 0xff, 0x70, 0xe7, 0xc2, 0xff, 0x5a, 0xc6, 0xa4, 0xff, 0x29, 0x79, 0x55, 0xff, 0x07, 0x40, 0x1b, 0xff, 0x04, 0x31, 0x13, 0xff, 0x03, 0x2c, 0x1b, 0xff, 0x29, 0x74, 0x67, 0xff, 0x55, 0xaf, 0x9d, 0xff, 0x07, 0x3e, 0x28, 0xff, 0x03, 0x2f, 0x17, 0xff, 0x64, 0x7e, 0x6e, 0xff, + 0x28, 0x39, 0x88, 0xff, 0x43, 0x54, 0x86, 0xff, 0x62, 0x6a, 0x90, 0xff, 0x6b, 0x70, 0x86, 0xff, 0x78, 0x80, 0x8b, 0xff, 0x96, 0x92, 0xa0, 0xff, 0x9a, 0x94, 0xa3, 0xff, 0x99, 0x94, 0xa3, 0xff, 0x86, 0x82, 0x8f, 0xff, 0x94, 0x8d, 0x99, 0xff, 0x98, 0x92, 0x9d, 0xff, 0x7d, 0x77, 0x81, 0xff, 0x8b, 0x87, 0x92, 0xff, 0x87, 0x87, 0x93, 0xff, 0x81, 0x83, 0x8f, 0xff, 0x90, 0x94, 0xa3, 0xff, 0x96, 0x94, 0xa6, 0xff, 0x96, 0x8b, 0x98, 0xff, 0x81, 0x79, 0x7d, 0xff, 0x6a, 0x76, 0x7e, 0xff, 0x41, 0x5e, 0x85, 0xff, 0x33, 0x4f, 0xb7, 0xff, 0x31, 0x4d, 0xc9, 0xff, 0x17, 0x54, 0x9d, 0xff, 0x06, 0x77, 0x7b, 0xff, 0x0a, 0xa3, 0x6f, 0xff, 0x09, 0xa6, 0x71, 0xff, 0x06, 0xa7, 0x6e, 0xff, 0x04, 0xad, 0x6f, 0xff, 0x05, 0xab, 0x74, 0xff, 0x0a, 0xac, 0x78, 0xff, 0x0d, 0xac, 0x7a, 0xff, 0x0e, 0xae, 0x7a, 0xff, 0x1f, 0xc2, 0x8b, 0xff, 0x15, 0xb9, 0x81, 0xff, 0x0b, 0xb0, 0x76, 0xff, 0x0b, 0xb1, 0x75, 0xff, 0x0d, 0xb3, 0x76, 0xff, 0x0d, 0xb6, 0x78, 0xff, 0x0a, 0xba, 0x7a, 0xff, 0x0e, 0xb9, 0x79, 0xff, 0x14, 0xb7, 0x78, 0xff, 0x13, 0xb6, 0x78, 0xff, 0x06, 0xb1, 0x73, 0xff, 0x0b, 0xad, 0x74, 0xff, 0x1a, 0x8f, 0x61, 0xff, 0x0a, 0x50, 0x2c, 0xff, 0x00, 0x1d, 0x05, 0xff, 0x00, 0x15, 0x02, 0xff, 0x02, 0x13, 0x01, 0xff, 0x05, 0x13, 0x02, 0xff, 0x04, 0x13, 0x03, 0xff, 0x02, 0x12, 0x04, 0xff, 0x00, 0x12, 0x04, 0xff, 0x01, 0x12, 0x03, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x14, 0x03, 0xff, 0x01, 0x16, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x16, 0x04, 0xff, 0x02, 0x16, 0x05, 0xff, 0x03, 0x17, 0x06, 0xff, 0x03, 0x17, 0x05, 0xff, 0x03, 0x17, 0x06, 0xff, 0x00, 0x1a, 0x05, 0xff, 0x00, 0x19, 0x04, 0xff, 0x01, 0x17, 0x04, 0xff, 0x07, 0x19, 0x07, 0xff, 0x0c, 0x1b, 0x09, 0xff, 0x06, 0x1b, 0x05, 0xff, 0x05, 0x24, 0x0b, 0xff, 0x01, 0x2d, 0x0f, 0xff, 0x0b, 0x6d, 0x44, 0xff, 0x22, 0xa1, 0x73, 0xff, 0x14, 0xae, 0x79, 0xff, 0x10, 0xb3, 0x7c, 0xff, 0x14, 0xb4, 0x7c, 0xff, 0x1b, 0xb6, 0x7d, 0xff, 0x15, 0xb2, 0x78, 0xff, 0x0a, 0xac, 0x71, 0xff, 0x03, 0x99, 0x62, 0xff, 0x08, 0x9b, 0x63, 0xff, 0x07, 0x98, 0x5c, 0xff, 0x07, 0x98, 0x5d, 0xff, 0x0e, 0xa1, 0x6b, 0xff, 0x08, 0x9e, 0x69, 0xff, 0x02, 0x99, 0x60, 0xff, 0x08, 0x9e, 0x63, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x06, 0x9f, 0x61, 0xff, 0x06, 0x9f, 0x62, 0xff, 0x03, 0x9c, 0x5e, 0xff, 0x0e, 0xa9, 0x6c, 0xff, 0x14, 0xb0, 0x73, 0xff, 0x16, 0xb3, 0x77, 0xff, 0x16, 0xb5, 0x79, 0xff, 0x15, 0xb4, 0x7a, 0xff, 0x14, 0xb4, 0x7a, 0xff, 0x12, 0xb4, 0x7c, 0xff, 0x13, 0xb6, 0x7e, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x15, 0xb7, 0x82, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x14, 0xb5, 0x82, 0xff, 0x14, 0xb6, 0x82, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x17, 0xb9, 0x83, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x14, 0xb7, 0x80, 0xff, 0x13, 0xb6, 0x7e, 0xff, 0x17, 0xba, 0x82, 0xff, 0x18, 0xbe, 0x83, 0xff, 0x0f, 0xb7, 0x7a, 0xff, 0x0e, 0xb2, 0x76, 0xff, 0x17, 0xac, 0x73, 0xff, 0x0b, 0x8c, 0x57, 0xff, 0x02, 0x66, 0x38, 0xff, 0x07, 0x59, 0x30, 0xff, 0x05, 0x4a, 0x28, 0xff, 0x03, 0x41, 0x22, 0xff, 0x03, 0x36, 0x1e, 0xff, 0x05, 0x32, 0x1c, 0xff, 0x01, 0x27, 0x15, 0xff, 0x00, 0x21, 0x11, 0xff, 0x01, 0x20, 0x0f, 0xff, 0x05, 0x23, 0x13, 0xff, 0x05, 0x22, 0x13, 0xff, 0x02, 0x20, 0x12, 0xff, 0x01, 0x1f, 0x11, 0xff, 0x01, 0x1f, 0x10, 0xff, 0x01, 0x1e, 0x0f, 0xff, 0x01, 0x1e, 0x0e, 0xff, 0x01, 0x1e, 0x0f, 0xff, 0x00, 0x1e, 0x0e, 0xff, 0x01, 0x1f, 0x0f, 0xff, 0x01, 0x1e, 0x0f, 0xff, 0x00, 0x1e, 0x0e, 0xff, 0x00, 0x1d, 0x0e, 0xff, 0x00, 0x1c, 0x0d, 0xff, 0x00, 0x1c, 0x0c, 0xff, 0x01, 0x1d, 0x0d, 0xff, 0x01, 0x1e, 0x0e, 0xff, 0x01, 0x1f, 0x0e, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x01, 0x1f, 0x0f, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x00, 0x1f, 0x0e, 0xff, 0x00, 0x21, 0x0f, 0xff, 0x00, 0x25, 0x12, 0xff, 0x00, 0x27, 0x14, 0xff, 0x03, 0x2b, 0x14, 0xff, 0x05, 0x2f, 0x16, 0xff, 0x01, 0x38, 0x1c, 0xff, 0x00, 0x43, 0x24, 0xff, 0x05, 0x6c, 0x45, 0xff, 0x17, 0x97, 0x6b, 0xff, 0x23, 0xb7, 0x86, 0xff, 0x20, 0xbc, 0x88, 0xff, 0x19, 0xba, 0x84, 0xff, 0x14, 0xb7, 0x81, 0xff, 0x18, 0xba, 0x83, 0xff, 0x17, 0xb8, 0x83, 0xff, 0x11, 0xb1, 0x7e, 0xff, 0x12, 0xb1, 0x7e, 0xff, 0x15, 0xb2, 0x81, 0xff, 0x13, 0xaf, 0x7e, 0xff, 0x0f, 0xa9, 0x79, 0xff, 0x0f, 0xa8, 0x7a, 0xff, 0x0e, 0xa8, 0x78, 0xff, 0x0b, 0xa5, 0x73, 0xff, 0x08, 0xa4, 0x6f, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0c, 0xa8, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa5, 0x76, 0xff, 0x0a, 0xa5, 0x76, 0xff, 0x09, 0xa6, 0x76, 0xff, 0x0a, 0xa9, 0x75, 0xff, 0x08, 0xa7, 0x72, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0a, 0x93, 0x61, 0xff, 0x25, 0xa4, 0x76, 0xff, 0x0b, 0x81, 0x54, 0xff, 0x12, 0x87, 0x5a, 0xff, 0x14, 0x80, 0x59, 0xff, 0x24, 0x89, 0x66, 0xff, 0x1e, 0x85, 0x64, 0xff, 0x15, 0x84, 0x60, 0xff, 0x1c, 0x9a, 0x6e, 0xff, 0x10, 0x98, 0x64, 0xff, 0x09, 0x99, 0x5f, 0xff, 0x0f, 0xa5, 0x6b, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x04, 0xac, 0x71, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x0c, 0x92, 0x5a, 0xff, 0x01, 0x4d, 0x20, 0xff, 0x01, 0x30, 0x0e, 0xff, 0x0c, 0x2a, 0x11, 0xff, 0x02, 0x23, 0x0b, 0xff, 0x05, 0x21, 0x0c, 0xff, 0x05, 0x1e, 0x0a, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x02, 0x1c, 0x09, 0xff, 0x00, 0x1c, 0x09, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x02, 0x1c, 0x08, 0xff, 0x02, 0x1c, 0x08, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x02, 0x1b, 0x08, 0xff, 0x01, 0x1b, 0x07, 0xff, 0x00, 0x19, 0x06, 0xff, 0x00, 0x18, 0x04, 0xff, 0x00, 0x18, 0x04, 0xff, 0x00, 0x19, 0x05, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x19, 0x05, 0xff, 0x00, 0x1a, 0x06, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x00, 0x1b, 0x07, 0xff, 0x01, 0x1d, 0x09, 0xff, 0x00, 0x20, 0x0a, 0xff, 0x00, 0x20, 0x0a, 0xff, 0x01, 0x21, 0x0b, 0xff, 0x00, 0x20, 0x0a, 0xff, 0x00, 0x22, 0x0a, 0xff, 0x01, 0x23, 0x0b, 0xff, 0x02, 0x29, 0x0f, 0xff, 0x03, 0x2d, 0x13, 0xff, 0x01, 0x2f, 0x15, 0xff, 0x03, 0x32, 0x16, 0xff, 0x02, 0x3d, 0x1f, 0xff, 0x11, 0x70, 0x4c, 0xff, 0x06, 0x7f, 0x53, 0xff, 0x11, 0x99, 0x68, 0xff, 0x1c, 0xaa, 0x76, 0xff, 0x1b, 0xae, 0x76, 0xff, 0x14, 0xac, 0x70, 0xff, 0x0e, 0xa5, 0x67, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x09, 0x9f, 0x5e, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x08, 0x9d, 0x59, 0xff, 0x08, 0x9c, 0x58, 0xff, 0x07, 0x9a, 0x56, 0xff, 0x0a, 0x9a, 0x55, 0xff, 0x0b, 0x9a, 0x55, 0xff, 0x0a, 0x9a, 0x55, 0xff, 0x08, 0x96, 0x51, 0xff, 0x07, 0x94, 0x50, 0xff, 0x09, 0x93, 0x4f, 0xff, 0x08, 0x92, 0x4e, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x09, 0x8f, 0x4c, 0xff, 0x0a, 0x8e, 0x4b, 0xff, 0x09, 0x8c, 0x4a, 0xff, 0x08, 0x88, 0x47, 0xff, 0x09, 0x86, 0x46, 0xff, 0x09, 0x85, 0x44, 0xff, 0x0a, 0x85, 0x44, 0xff, 0x0a, 0x85, 0x44, 0xff, 0x04, 0x86, 0x40, 0xff, 0x06, 0x81, 0x3f, 0xff, 0x0b, 0x7a, 0x40, 0xff, 0x0a, 0x7a, 0x41, 0xff, 0x08, 0x86, 0x49, 0xff, 0x2a, 0xb2, 0x73, 0xff, 0x20, 0x9d, 0x65, 0xff, 0x03, 0x6c, 0x3f, 0xff, 0x11, 0x58, 0x4c, 0xff, 0x70, 0x93, 0xaf, 0xff, 0xa0, 0xb2, 0xdc, 0xff, 0xb3, 0xb7, 0xed, 0xff, 0x8f, 0x91, 0xde, 0xff, 0x22, 0x2d, 0xa0, 0xff, 0x16, 0x36, 0xaa, 0xff, 0x42, 0x86, 0xcb, 0xff, 0x23, 0x84, 0x8c, 0xff, 0x17, 0x80, 0x56, 0xff, 0x15, 0x7c, 0x3f, 0xff, 0x16, 0x82, 0x38, 0xff, 0x1d, 0x8c, 0x47, 0xff, 0x45, 0xc2, 0x88, 0xff, 0x72, 0xf6, 0xc5, 0xff, 0x6c, 0xe9, 0xbd, 0xff, 0x41, 0xaa, 0x7c, 0xff, 0x09, 0x4e, 0x23, 0xff, 0x04, 0x32, 0x16, 0xff, 0x04, 0x32, 0x22, 0xff, 0x42, 0x93, 0x82, 0xff, 0x27, 0x70, 0x5c, 0xff, 0x02, 0x31, 0x19, 0xff, 0x64, 0x79, 0x69, 0xff, + 0x49, 0x5a, 0x84, 0xff, 0x6e, 0x78, 0x89, 0xff, 0x88, 0x85, 0x96, 0xff, 0x90, 0x8a, 0x98, 0xff, 0x81, 0x80, 0x8b, 0xff, 0x91, 0x8d, 0x9e, 0xff, 0x9d, 0x95, 0xa5, 0xff, 0x97, 0x90, 0x9a, 0xff, 0x82, 0x7f, 0x89, 0xff, 0x7a, 0x7b, 0x88, 0xff, 0x7d, 0x7e, 0x8a, 0xff, 0x71, 0x72, 0x7d, 0xff, 0x82, 0x81, 0x8a, 0xff, 0x86, 0x84, 0x89, 0xff, 0x8c, 0x8d, 0x91, 0xff, 0x93, 0x96, 0xa1, 0xff, 0x94, 0x90, 0xa3, 0xff, 0x8d, 0x7f, 0x95, 0xff, 0x93, 0x86, 0x91, 0xff, 0x87, 0x89, 0x8d, 0xff, 0x52, 0x62, 0x7f, 0xff, 0x2b, 0x45, 0xa4, 0xff, 0x24, 0x46, 0xb7, 0xff, 0x06, 0x53, 0x84, 0xff, 0x0d, 0x89, 0x7a, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x0a, 0xa5, 0x70, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x08, 0xad, 0x72, 0xff, 0x06, 0xab, 0x74, 0xff, 0x0f, 0xaf, 0x7a, 0xff, 0x0e, 0xaa, 0x79, 0xff, 0x0a, 0xa9, 0x76, 0xff, 0x18, 0xb9, 0x84, 0xff, 0x11, 0xb3, 0x7c, 0xff, 0x0b, 0xae, 0x75, 0xff, 0x0a, 0xb0, 0x75, 0xff, 0x0d, 0xb3, 0x76, 0xff, 0x0c, 0xb7, 0x79, 0xff, 0x05, 0xba, 0x78, 0xff, 0x0c, 0xb9, 0x79, 0xff, 0x15, 0xb6, 0x78, 0xff, 0x16, 0xb5, 0x78, 0xff, 0x0b, 0xb6, 0x78, 0xff, 0x06, 0xaf, 0x75, 0xff, 0x1c, 0xab, 0x76, 0xff, 0x24, 0x93, 0x65, 0xff, 0x09, 0x51, 0x30, 0xff, 0x00, 0x27, 0x0a, 0xff, 0x00, 0x15, 0x00, 0xff, 0x02, 0x13, 0x00, 0xff, 0x03, 0x10, 0x01, 0xff, 0x02, 0x10, 0x02, 0xff, 0x00, 0x11, 0x03, 0xff, 0x01, 0x14, 0x04, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x12, 0x01, 0xff, 0x01, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x13, 0x01, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x14, 0x03, 0xff, 0x02, 0x16, 0x05, 0xff, 0x00, 0x17, 0x04, 0xff, 0x00, 0x17, 0x05, 0xff, 0x05, 0x15, 0x04, 0xff, 0x08, 0x14, 0x04, 0xff, 0x05, 0x12, 0x02, 0xff, 0x04, 0x17, 0x02, 0xff, 0x01, 0x1a, 0x03, 0xff, 0x04, 0x3a, 0x1a, 0xff, 0x1a, 0x90, 0x63, 0xff, 0x1e, 0xa9, 0x78, 0xff, 0x16, 0xb1, 0x7c, 0xff, 0x13, 0xb4, 0x7d, 0xff, 0x15, 0xb4, 0x7c, 0xff, 0x1b, 0xb8, 0x7f, 0xff, 0x19, 0xb7, 0x7e, 0xff, 0x13, 0xb3, 0x7a, 0xff, 0x12, 0xab, 0x74, 0xff, 0x07, 0x9c, 0x65, 0xff, 0x04, 0x95, 0x5c, 0xff, 0x08, 0x99, 0x61, 0xff, 0x10, 0xa3, 0x6d, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x13, 0xa9, 0x72, 0xff, 0x18, 0xaf, 0x76, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x05, 0x9e, 0x62, 0xff, 0x06, 0xa0, 0x63, 0xff, 0x0f, 0xaa, 0x6e, 0xff, 0x15, 0xb2, 0x76, 0xff, 0x14, 0xb4, 0x76, 0xff, 0x12, 0xb3, 0x77, 0xff, 0x15, 0xb6, 0x79, 0xff, 0x14, 0xb6, 0x7c, 0xff, 0x12, 0xb5, 0x7b, 0xff, 0x12, 0xb6, 0x7e, 0xff, 0x14, 0xb7, 0x80, 0xff, 0x15, 0xb9, 0x82, 0xff, 0x16, 0xb9, 0x83, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x16, 0xb7, 0x83, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x15, 0xb7, 0x84, 0xff, 0x16, 0xb9, 0x83, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x13, 0xb6, 0x7f, 0xff, 0x11, 0xb4, 0x7d, 0xff, 0x13, 0xb6, 0x7e, 0xff, 0x17, 0xbc, 0x83, 0xff, 0x1a, 0xbf, 0x85, 0xff, 0x11, 0xba, 0x7c, 0xff, 0x0e, 0xb4, 0x76, 0xff, 0x14, 0xaf, 0x73, 0xff, 0x16, 0x9f, 0x68, 0xff, 0x05, 0x74, 0x44, 0xff, 0x01, 0x5d, 0x32, 0xff, 0x01, 0x45, 0x20, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x01, 0x2f, 0x17, 0xff, 0x02, 0x28, 0x14, 0xff, 0x00, 0x1d, 0x0e, 0xff, 0x00, 0x1c, 0x0d, 0xff, 0x03, 0x20, 0x10, 0xff, 0x05, 0x20, 0x10, 0xff, 0x02, 0x1d, 0x0e, 0xff, 0x02, 0x1d, 0x0e, 0xff, 0x02, 0x1c, 0x0e, 0xff, 0x02, 0x1c, 0x0d, 0xff, 0x02, 0x1d, 0x0d, 0xff, 0x03, 0x1e, 0x0e, 0xff, 0x03, 0x1e, 0x0d, 0xff, 0x01, 0x1c, 0x0c, 0xff, 0x01, 0x1c, 0x0c, 0xff, 0x01, 0x1b, 0x0b, 0xff, 0x00, 0x1b, 0x0a, 0xff, 0x00, 0x1b, 0x0b, 0xff, 0x00, 0x1b, 0x0b, 0xff, 0x00, 0x1a, 0x09, 0xff, 0x00, 0x1b, 0x0a, 0xff, 0x01, 0x1d, 0x0c, 0xff, 0x01, 0x1e, 0x0d, 0xff, 0x01, 0x1e, 0x0e, 0xff, 0x02, 0x1f, 0x0f, 0xff, 0x03, 0x1e, 0x0e, 0xff, 0x01, 0x1d, 0x0d, 0xff, 0x00, 0x1e, 0x0d, 0xff, 0x01, 0x20, 0x0f, 0xff, 0x01, 0x23, 0x12, 0xff, 0x07, 0x27, 0x14, 0xff, 0x04, 0x26, 0x11, 0xff, 0x00, 0x31, 0x18, 0xff, 0x00, 0x40, 0x20, 0xff, 0x0e, 0x7a, 0x54, 0xff, 0x23, 0xa6, 0x79, 0xff, 0x26, 0xba, 0x88, 0xff, 0x20, 0xb9, 0x85, 0xff, 0x14, 0xb2, 0x7a, 0xff, 0x0d, 0xb0, 0x77, 0xff, 0x0f, 0xb2, 0x7a, 0xff, 0x10, 0xb2, 0x7a, 0xff, 0x0c, 0xac, 0x78, 0xff, 0x0f, 0xae, 0x7a, 0xff, 0x10, 0xad, 0x7b, 0xff, 0x0f, 0xab, 0x79, 0xff, 0x0d, 0xa8, 0x76, 0xff, 0x0d, 0xa7, 0x77, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x09, 0xa5, 0x70, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x75, 0xff, 0x0c, 0xa7, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa5, 0x76, 0xff, 0x0b, 0xa5, 0x76, 0xff, 0x0a, 0xa6, 0x76, 0xff, 0x08, 0xa7, 0x75, 0xff, 0x09, 0xa6, 0x73, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0e, 0xaa, 0x74, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x10, 0xa0, 0x6d, 0xff, 0x14, 0x9a, 0x6a, 0xff, 0x17, 0x98, 0x69, 0xff, 0x16, 0x9a, 0x68, 0xff, 0x25, 0xa1, 0x75, 0xff, 0x14, 0x8a, 0x62, 0xff, 0x18, 0x8f, 0x69, 0xff, 0x10, 0x91, 0x67, 0xff, 0x10, 0x9c, 0x6b, 0xff, 0x10, 0xa0, 0x6b, 0xff, 0x0e, 0xa1, 0x68, 0xff, 0x0e, 0xa7, 0x6c, 0xff, 0x05, 0xa9, 0x70, 0xff, 0x01, 0xab, 0x71, 0xff, 0x07, 0xb0, 0x75, 0xff, 0x11, 0xa7, 0x6d, 0xff, 0x07, 0x6b, 0x3c, 0xff, 0x01, 0x34, 0x11, 0xff, 0x07, 0x24, 0x0b, 0xff, 0x01, 0x1c, 0x06, 0xff, 0x01, 0x18, 0x04, 0xff, 0x04, 0x19, 0x06, 0xff, 0x02, 0x16, 0x05, 0xff, 0x02, 0x18, 0x07, 0xff, 0x01, 0x19, 0x07, 0xff, 0x01, 0x19, 0x05, 0xff, 0x04, 0x1a, 0x07, 0xff, 0x05, 0x1a, 0x08, 0xff, 0x03, 0x19, 0x06, 0xff, 0x03, 0x19, 0x06, 0xff, 0x03, 0x18, 0x06, 0xff, 0x00, 0x16, 0x03, 0xff, 0x01, 0x17, 0x04, 0xff, 0x03, 0x18, 0x05, 0xff, 0x03, 0x18, 0x06, 0xff, 0x02, 0x17, 0x05, 0xff, 0x02, 0x17, 0x05, 0xff, 0x02, 0x18, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x1b, 0x08, 0xff, 0x00, 0x1b, 0x08, 0xff, 0x01, 0x1c, 0x08, 0xff, 0x02, 0x1d, 0x09, 0xff, 0x02, 0x1c, 0x08, 0xff, 0x01, 0x1d, 0x07, 0xff, 0x00, 0x1f, 0x07, 0xff, 0x03, 0x25, 0x0d, 0xff, 0x04, 0x29, 0x10, 0xff, 0x03, 0x2b, 0x12, 0xff, 0x02, 0x2d, 0x11, 0xff, 0x01, 0x35, 0x17, 0xff, 0x07, 0x66, 0x41, 0xff, 0x05, 0x83, 0x56, 0xff, 0x17, 0xa2, 0x71, 0xff, 0x1d, 0xac, 0x77, 0xff, 0x1a, 0xae, 0x75, 0xff, 0x11, 0xa8, 0x6c, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x08, 0xa0, 0x5f, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x09, 0x9e, 0x5a, 0xff, 0x07, 0x9c, 0x58, 0xff, 0x08, 0x9a, 0x56, 0xff, 0x07, 0x99, 0x55, 0xff, 0x0a, 0x99, 0x54, 0xff, 0x0a, 0x99, 0x54, 0xff, 0x09, 0x98, 0x53, 0xff, 0x07, 0x95, 0x50, 0xff, 0x08, 0x93, 0x4f, 0xff, 0x08, 0x92, 0x4e, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x09, 0x90, 0x4d, 0xff, 0x0a, 0x8e, 0x4c, 0xff, 0x09, 0x8b, 0x4a, 0xff, 0x09, 0x87, 0x46, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x09, 0x83, 0x44, 0xff, 0x09, 0x84, 0x44, 0xff, 0x09, 0x83, 0x43, 0xff, 0x06, 0x85, 0x3f, 0xff, 0x07, 0x7e, 0x3d, 0xff, 0x0d, 0x7b, 0x44, 0xff, 0x09, 0x7d, 0x45, 0xff, 0x1c, 0x9f, 0x60, 0xff, 0x17, 0x9a, 0x5e, 0xff, 0x05, 0x73, 0x4a, 0xff, 0x0c, 0x5a, 0x4e, 0xff, 0x46, 0x72, 0x87, 0xff, 0x98, 0xab, 0xd9, 0xff, 0xa8, 0xb5, 0xea, 0xff, 0xa3, 0xa9, 0xf2, 0xff, 0x50, 0x54, 0xb8, 0xff, 0x1f, 0x28, 0xae, 0xff, 0x1c, 0x30, 0xbb, 0xff, 0x2f, 0x53, 0xcb, 0xff, 0x1d, 0x5a, 0xa2, 0xff, 0x1e, 0x72, 0x79, 0xff, 0x17, 0x70, 0x51, 0xff, 0x1d, 0x79, 0x35, 0xff, 0x19, 0x79, 0x2e, 0xff, 0x13, 0x82, 0x3c, 0xff, 0x3c, 0xbd, 0x7d, 0xff, 0x5b, 0xe7, 0xaf, 0xff, 0x58, 0xdc, 0xa5, 0xff, 0x40, 0xab, 0x73, 0xff, 0x10, 0x57, 0x2b, 0xff, 0x03, 0x2f, 0x15, 0xff, 0x14, 0x53, 0x40, 0xff, 0x48, 0x98, 0x88, 0xff, 0x09, 0x3f, 0x27, 0xff, 0x6d, 0x7f, 0x6f, 0xff, + 0x67, 0x72, 0x82, 0xff, 0x85, 0x85, 0x8b, 0xff, 0x9c, 0x8f, 0x9c, 0xff, 0xa0, 0x95, 0xa1, 0xff, 0x90, 0x8e, 0x97, 0xff, 0x84, 0x80, 0x95, 0xff, 0x9a, 0x92, 0xa1, 0xff, 0x89, 0x86, 0x89, 0xff, 0x6f, 0x75, 0x7e, 0xff, 0x58, 0x6a, 0x7a, 0xff, 0x56, 0x6b, 0x7d, 0xff, 0x5a, 0x69, 0x7c, 0xff, 0x6b, 0x70, 0x7f, 0xff, 0x88, 0x80, 0x8c, 0xff, 0x9b, 0x93, 0x9c, 0xff, 0x98, 0x93, 0x9e, 0xff, 0x86, 0x80, 0x8f, 0xff, 0x8f, 0x86, 0x9b, 0xff, 0x9e, 0x93, 0xa3, 0xff, 0x90, 0x87, 0x92, 0xff, 0x64, 0x66, 0x80, 0xff, 0x37, 0x4c, 0x9a, 0xff, 0x19, 0x45, 0x9e, 0xff, 0x07, 0x68, 0x7c, 0xff, 0x10, 0x9c, 0x74, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0e, 0xa8, 0x6f, 0xff, 0x0c, 0xab, 0x74, 0xff, 0x0a, 0xab, 0x73, 0xff, 0x11, 0xae, 0x78, 0xff, 0x24, 0xbd, 0x8e, 0xff, 0x1f, 0xb9, 0x88, 0xff, 0x0b, 0xa8, 0x75, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x0b, 0xae, 0x75, 0xff, 0x0b, 0xb0, 0x76, 0xff, 0x0d, 0xb4, 0x76, 0xff, 0x0c, 0xb7, 0x79, 0xff, 0x07, 0xb9, 0x78, 0xff, 0x0b, 0xb8, 0x78, 0xff, 0x0f, 0xb7, 0x78, 0xff, 0x0f, 0xb7, 0x78, 0xff, 0x0c, 0xb5, 0x76, 0xff, 0x0a, 0xb3, 0x75, 0xff, 0x11, 0xb1, 0x75, 0xff, 0x16, 0xac, 0x74, 0xff, 0x1b, 0xa2, 0x6f, 0xff, 0x18, 0x84, 0x57, 0xff, 0x10, 0x55, 0x31, 0xff, 0x06, 0x33, 0x18, 0xff, 0x01, 0x1b, 0x05, 0xff, 0x03, 0x11, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x12, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x02, 0x11, 0x00, 0xff, 0x02, 0x11, 0x01, 0xff, 0x02, 0x12, 0x01, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x11, 0x03, 0xff, 0x01, 0x11, 0x02, 0xff, 0x02, 0x12, 0x03, 0xff, 0x02, 0x0f, 0x02, 0xff, 0x03, 0x0f, 0x01, 0xff, 0x01, 0x13, 0x01, 0xff, 0x00, 0x14, 0x02, 0xff, 0x05, 0x38, 0x1a, 0xff, 0x1d, 0x78, 0x52, 0xff, 0x1d, 0xa9, 0x78, 0xff, 0x19, 0xaf, 0x7a, 0xff, 0x18, 0xb4, 0x7e, 0xff, 0x17, 0xb4, 0x7e, 0xff, 0x17, 0xb6, 0x7e, 0xff, 0x18, 0xb5, 0x7e, 0xff, 0x17, 0xb6, 0x7e, 0xff, 0x16, 0xb6, 0x7f, 0xff, 0x1a, 0xb6, 0x82, 0xff, 0x11, 0xa9, 0x73, 0xff, 0x07, 0x9b, 0x64, 0xff, 0x0c, 0xa0, 0x68, 0xff, 0x13, 0xaa, 0x74, 0xff, 0x19, 0xb2, 0x7f, 0xff, 0x1e, 0xb9, 0x82, 0xff, 0x1b, 0xb7, 0x7d, 0xff, 0x13, 0xab, 0x70, 0xff, 0x12, 0xab, 0x70, 0xff, 0x12, 0xae, 0x72, 0xff, 0x12, 0xaf, 0x73, 0xff, 0x0d, 0xad, 0x71, 0xff, 0x0d, 0xaf, 0x73, 0xff, 0x0d, 0xb3, 0x74, 0xff, 0x10, 0xb6, 0x78, 0xff, 0x0f, 0xb3, 0x7a, 0xff, 0x10, 0xb3, 0x7b, 0xff, 0x12, 0xb6, 0x7e, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x18, 0xb8, 0x84, 0xff, 0x19, 0xb9, 0x85, 0xff, 0x18, 0xb9, 0x85, 0xff, 0x18, 0xba, 0x86, 0xff, 0x19, 0xbb, 0x87, 0xff, 0x18, 0xba, 0x86, 0xff, 0x19, 0xbb, 0x87, 0xff, 0x19, 0xbb, 0x87, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x16, 0xb8, 0x84, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x14, 0xb6, 0x82, 0xff, 0x15, 0xb7, 0x84, 0xff, 0x16, 0xb8, 0x83, 0xff, 0x14, 0xb7, 0x80, 0xff, 0x11, 0xb4, 0x7d, 0xff, 0x10, 0xb3, 0x7c, 0xff, 0x14, 0xb7, 0x80, 0xff, 0x11, 0xb4, 0x7c, 0xff, 0x12, 0xb6, 0x7d, 0xff, 0x15, 0xbe, 0x81, 0xff, 0x0f, 0xba, 0x7b, 0xff, 0x10, 0xb2, 0x74, 0xff, 0x19, 0xae, 0x73, 0xff, 0x18, 0x9b, 0x66, 0xff, 0x09, 0x7b, 0x4a, 0xff, 0x00, 0x45, 0x1f, 0xff, 0x00, 0x32, 0x14, 0xff, 0x00, 0x27, 0x0f, 0xff, 0x03, 0x21, 0x0f, 0xff, 0x02, 0x19, 0x0b, 0xff, 0x02, 0x18, 0x0a, 0xff, 0x03, 0x1b, 0x0c, 0xff, 0x03, 0x1b, 0x0a, 0xff, 0x00, 0x18, 0x08, 0xff, 0x02, 0x19, 0x0a, 0xff, 0x04, 0x1b, 0x0b, 0xff, 0x03, 0x1b, 0x0b, 0xff, 0x03, 0x1c, 0x0a, 0xff, 0x03, 0x1b, 0x09, 0xff, 0x01, 0x19, 0x07, 0xff, 0x01, 0x19, 0x06, 0xff, 0x02, 0x19, 0x07, 0xff, 0x02, 0x1a, 0x08, 0xff, 0x02, 0x19, 0x08, 0xff, 0x02, 0x1a, 0x08, 0xff, 0x04, 0x1c, 0x0a, 0xff, 0x02, 0x1b, 0x09, 0xff, 0x02, 0x1b, 0x09, 0xff, 0x02, 0x1c, 0x0a, 0xff, 0x02, 0x1c, 0x0c, 0xff, 0x03, 0x1e, 0x0e, 0xff, 0x04, 0x1e, 0x0e, 0xff, 0x05, 0x1d, 0x0d, 0xff, 0x03, 0x1b, 0x0c, 0xff, 0x03, 0x1b, 0x0b, 0xff, 0x02, 0x1b, 0x0c, 0xff, 0x03, 0x1c, 0x0d, 0xff, 0x04, 0x1f, 0x0e, 0xff, 0x05, 0x26, 0x12, 0xff, 0x00, 0x2c, 0x11, 0xff, 0x06, 0x54, 0x33, 0xff, 0x20, 0x9b, 0x72, 0xff, 0x23, 0xb3, 0x83, 0xff, 0x18, 0xb4, 0x80, 0xff, 0x14, 0xb0, 0x7a, 0xff, 0x0c, 0xab, 0x72, 0xff, 0x08, 0xad, 0x72, 0xff, 0x09, 0xac, 0x73, 0xff, 0x09, 0xaa, 0x72, 0xff, 0x0a, 0xaa, 0x72, 0xff, 0x0d, 0xab, 0x75, 0xff, 0x0e, 0xab, 0x77, 0xff, 0x0f, 0xaa, 0x77, 0xff, 0x0d, 0xa8, 0x76, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa5, 0x75, 0xff, 0x0c, 0xa5, 0x76, 0xff, 0x0c, 0xa5, 0x77, 0xff, 0x0c, 0xa7, 0x77, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa8, 0x74, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa9, 0x73, 0xff, 0x12, 0xab, 0x76, 0xff, 0x0f, 0xa3, 0x6f, 0xff, 0x16, 0xa7, 0x76, 0xff, 0x15, 0xaa, 0x75, 0xff, 0x20, 0xad, 0x7d, 0xff, 0x24, 0xaf, 0x7f, 0xff, 0x19, 0xa8, 0x78, 0xff, 0x0c, 0xa1, 0x70, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x08, 0xaa, 0x72, 0xff, 0x02, 0xa6, 0x6d, 0xff, 0x02, 0xaa, 0x6e, 0xff, 0x0d, 0xae, 0x71, 0xff, 0x1a, 0x99, 0x66, 0xff, 0x0b, 0x5e, 0x35, 0xff, 0x00, 0x1f, 0x05, 0xff, 0x02, 0x19, 0x05, 0xff, 0x03, 0x15, 0x04, 0xff, 0x04, 0x14, 0x04, 0xff, 0x04, 0x15, 0x06, 0xff, 0x02, 0x15, 0x06, 0xff, 0x01, 0x16, 0x04, 0xff, 0x01, 0x16, 0x03, 0xff, 0x04, 0x17, 0x04, 0xff, 0x04, 0x17, 0x05, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x13, 0x02, 0xff, 0x03, 0x16, 0x05, 0xff, 0x04, 0x17, 0x06, 0xff, 0x03, 0x16, 0x05, 0xff, 0x03, 0x16, 0x05, 0xff, 0x04, 0x17, 0x06, 0xff, 0x04, 0x17, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x02, 0x19, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x04, 0x1b, 0x09, 0xff, 0x02, 0x1a, 0x08, 0xff, 0x01, 0x19, 0x05, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x19, 0x05, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x01, 0x1d, 0x06, 0xff, 0x04, 0x20, 0x09, 0xff, 0x03, 0x22, 0x0a, 0xff, 0x02, 0x26, 0x0c, 0xff, 0x09, 0x2c, 0x12, 0xff, 0x02, 0x2e, 0x12, 0xff, 0x04, 0x64, 0x3f, 0xff, 0x0f, 0x93, 0x65, 0xff, 0x1b, 0xae, 0x7b, 0xff, 0x17, 0xab, 0x74, 0xff, 0x11, 0xa8, 0x6d, 0xff, 0x0d, 0xa2, 0x67, 0xff, 0x09, 0xa0, 0x61, 0xff, 0x0b, 0xa1, 0x61, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x07, 0x9c, 0x58, 0xff, 0x07, 0x9a, 0x56, 0xff, 0x08, 0x9a, 0x56, 0xff, 0x08, 0x99, 0x55, 0xff, 0x0a, 0x99, 0x54, 0xff, 0x09, 0x98, 0x53, 0xff, 0x08, 0x96, 0x51, 0xff, 0x07, 0x93, 0x4f, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x08, 0x90, 0x4c, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x0a, 0x90, 0x4e, 0xff, 0x09, 0x8e, 0x4c, 0xff, 0x09, 0x8b, 0x49, 0xff, 0x09, 0x87, 0x46, 0xff, 0x09, 0x84, 0x44, 0xff, 0x08, 0x83, 0x43, 0xff, 0x09, 0x83, 0x43, 0xff, 0x07, 0x82, 0x42, 0xff, 0x08, 0x82, 0x3e, 0xff, 0x0b, 0x7c, 0x41, 0xff, 0x0a, 0x77, 0x45, 0xff, 0x1b, 0x8e, 0x57, 0xff, 0x1d, 0x98, 0x59, 0xff, 0x04, 0x77, 0x41, 0xff, 0x09, 0x65, 0x51, 0xff, 0x14, 0x4a, 0x6b, 0xff, 0x65, 0x80, 0xb9, 0xff, 0x9d, 0xae, 0xeb, 0xff, 0x8e, 0xa0, 0xe5, 0xff, 0x45, 0x54, 0xbb, 0xff, 0x16, 0x24, 0xa5, 0xff, 0x20, 0x33, 0xbd, 0xff, 0x1e, 0x34, 0xbc, 0xff, 0x1a, 0x2f, 0xba, 0xff, 0x23, 0x40, 0xbc, 0xff, 0x37, 0x66, 0xb0, 0xff, 0x2f, 0x6b, 0x7f, 0xff, 0x1c, 0x6b, 0x3d, 0xff, 0x1a, 0x77, 0x2e, 0xff, 0x15, 0x74, 0x2f, 0xff, 0x14, 0x73, 0x36, 0xff, 0x3e, 0xb0, 0x70, 0xff, 0x42, 0xc2, 0x7f, 0xff, 0x44, 0xc5, 0x7f, 0xff, 0x48, 0xb5, 0x76, 0xff, 0x0a, 0x47, 0x1b, 0xff, 0x01, 0x30, 0x17, 0xff, 0x44, 0x8f, 0x82, 0xff, 0x23, 0x69, 0x4f, 0xff, 0x6f, 0x86, 0x73, 0xff, + 0x89, 0x89, 0x99, 0xff, 0x84, 0x7c, 0x8d, 0xff, 0x8d, 0x7d, 0x93, 0xff, 0x9c, 0x96, 0x9e, 0xff, 0x9b, 0x9e, 0x9d, 0xff, 0x83, 0x80, 0x8c, 0xff, 0x81, 0x7c, 0x89, 0xff, 0x75, 0x79, 0x85, 0xff, 0x51, 0x66, 0x79, 0xff, 0x47, 0x6f, 0x8b, 0xff, 0x40, 0x6d, 0x8b, 0xff, 0x41, 0x64, 0x81, 0xff, 0x50, 0x63, 0x7c, 0xff, 0x7a, 0x75, 0x87, 0xff, 0x8e, 0x80, 0x93, 0xff, 0x84, 0x78, 0x8c, 0xff, 0x86, 0x82, 0x8c, 0xff, 0x8e, 0x8f, 0x9a, 0xff, 0x87, 0x86, 0x93, 0xff, 0x81, 0x78, 0x85, 0xff, 0x6b, 0x6a, 0x81, 0xff, 0x38, 0x55, 0x87, 0xff, 0x10, 0x4e, 0x84, 0xff, 0x12, 0x87, 0x83, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x04, 0xa4, 0x6b, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x11, 0xa7, 0x6e, 0xff, 0x11, 0xa9, 0x76, 0xff, 0x0f, 0xaa, 0x72, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x2c, 0xc2, 0x93, 0xff, 0x1c, 0xb5, 0x85, 0xff, 0x08, 0xa3, 0x72, 0xff, 0x0a, 0xa8, 0x74, 0xff, 0x0a, 0xae, 0x75, 0xff, 0x0c, 0xb1, 0x76, 0xff, 0x0d, 0xb4, 0x76, 0xff, 0x0d, 0xb6, 0x77, 0xff, 0x0c, 0xb8, 0x78, 0xff, 0x0c, 0xb8, 0x78, 0xff, 0x08, 0xb9, 0x78, 0xff, 0x06, 0xba, 0x79, 0xff, 0x0c, 0xb7, 0x77, 0xff, 0x13, 0xb5, 0x77, 0xff, 0x0f, 0xb3, 0x75, 0xff, 0x0c, 0xb3, 0x75, 0xff, 0x12, 0xb1, 0x76, 0xff, 0x1e, 0xb6, 0x7d, 0xff, 0x26, 0xb3, 0x7f, 0xff, 0x24, 0xa3, 0x73, 0xff, 0x14, 0x77, 0x4f, 0xff, 0x0c, 0x49, 0x28, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x01, 0x18, 0x05, 0xff, 0x01, 0x13, 0x01, 0xff, 0x00, 0x10, 0x00, 0xff, 0x02, 0x0f, 0x00, 0xff, 0x02, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, 0xff, 0x02, 0x11, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x01, 0x10, 0x01, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x02, 0x0f, 0x01, 0xff, 0x04, 0x10, 0x03, 0xff, 0x03, 0x0e, 0x01, 0xff, 0x00, 0x11, 0x02, 0xff, 0x00, 0x16, 0x05, 0xff, 0x02, 0x24, 0x0f, 0xff, 0x09, 0x49, 0x29, 0xff, 0x1c, 0x8a, 0x61, 0xff, 0x22, 0xa7, 0x79, 0xff, 0x13, 0xb1, 0x7c, 0xff, 0x15, 0xb3, 0x7d, 0xff, 0x17, 0xb3, 0x7d, 0xff, 0x18, 0xb3, 0x7e, 0xff, 0x17, 0xb4, 0x7e, 0xff, 0x16, 0xb4, 0x7e, 0xff, 0x14, 0xb5, 0x7d, 0xff, 0x14, 0xb4, 0x7d, 0xff, 0x14, 0xb4, 0x80, 0xff, 0x17, 0xb4, 0x7e, 0xff, 0x14, 0xac, 0x75, 0xff, 0x16, 0xad, 0x77, 0xff, 0x1e, 0xb6, 0x82, 0xff, 0x1c, 0xb7, 0x84, 0xff, 0x15, 0xb4, 0x7d, 0xff, 0x13, 0xb1, 0x78, 0xff, 0x15, 0xaf, 0x74, 0xff, 0x12, 0xad, 0x72, 0xff, 0x0e, 0xab, 0x70, 0xff, 0x0e, 0xad, 0x71, 0xff, 0x0b, 0xaf, 0x72, 0xff, 0x0a, 0xb0, 0x73, 0xff, 0x0b, 0xb2, 0x73, 0xff, 0x0b, 0xb2, 0x74, 0xff, 0x0c, 0xb2, 0x77, 0xff, 0x0e, 0xb3, 0x7a, 0xff, 0x11, 0xb6, 0x7e, 0xff, 0x13, 0xb8, 0x80, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x18, 0xb8, 0x83, 0xff, 0x1a, 0xb9, 0x84, 0xff, 0x19, 0xba, 0x86, 0xff, 0x18, 0xba, 0x86, 0xff, 0x19, 0xbb, 0x87, 0xff, 0x19, 0xbb, 0x86, 0xff, 0x19, 0xbb, 0x87, 0xff, 0x19, 0xbb, 0x87, 0xff, 0x17, 0xb9, 0x85, 0xff, 0x16, 0xb8, 0x83, 0xff, 0x14, 0xb7, 0x82, 0xff, 0x14, 0xb6, 0x82, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x15, 0xb8, 0x82, 0xff, 0x13, 0xb6, 0x7f, 0xff, 0x10, 0xb3, 0x7c, 0xff, 0x10, 0xb3, 0x7c, 0xff, 0x11, 0xb4, 0x7d, 0xff, 0x0d, 0xae, 0x77, 0xff, 0x0b, 0xae, 0x75, 0xff, 0x11, 0xb9, 0x7c, 0xff, 0x10, 0xbc, 0x7d, 0xff, 0x0b, 0xb3, 0x74, 0xff, 0x10, 0xaf, 0x72, 0xff, 0x1d, 0xaf, 0x76, 0xff, 0x1b, 0xa5, 0x70, 0xff, 0x14, 0x6e, 0x45, 0xff, 0x04, 0x38, 0x19, 0xff, 0x00, 0x21, 0x08, 0xff, 0x01, 0x1b, 0x09, 0xff, 0x04, 0x16, 0x08, 0xff, 0x05, 0x17, 0x08, 0xff, 0x03, 0x17, 0x06, 0xff, 0x01, 0x16, 0x04, 0xff, 0x00, 0x15, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x03, 0x17, 0x05, 0xff, 0x02, 0x16, 0x05, 0xff, 0x02, 0x16, 0x04, 0xff, 0x01, 0x16, 0x03, 0xff, 0x00, 0x15, 0x02, 0xff, 0x01, 0x16, 0x03, 0xff, 0x02, 0x16, 0x04, 0xff, 0x03, 0x17, 0x04, 0xff, 0x02, 0x17, 0x04, 0xff, 0x02, 0x17, 0x05, 0xff, 0x03, 0x17, 0x06, 0xff, 0x02, 0x18, 0x06, 0xff, 0x04, 0x19, 0x07, 0xff, 0x03, 0x19, 0x07, 0xff, 0x01, 0x19, 0x06, 0xff, 0x01, 0x1a, 0x09, 0xff, 0x03, 0x1b, 0x0a, 0xff, 0x03, 0x1a, 0x08, 0xff, 0x04, 0x18, 0x07, 0xff, 0x04, 0x18, 0x09, 0xff, 0x03, 0x17, 0x08, 0xff, 0x02, 0x18, 0x08, 0xff, 0x00, 0x18, 0x06, 0xff, 0x00, 0x21, 0x0b, 0xff, 0x0f, 0x53, 0x36, 0xff, 0x26, 0x8f, 0x6a, 0xff, 0x24, 0xb1, 0x84, 0xff, 0x16, 0xb5, 0x82, 0xff, 0x06, 0xad, 0x76, 0xff, 0x07, 0xac, 0x73, 0xff, 0x09, 0xad, 0x73, 0xff, 0x09, 0xad, 0x71, 0xff, 0x08, 0xab, 0x72, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x09, 0xaa, 0x71, 0xff, 0x0d, 0xab, 0x74, 0xff, 0x0d, 0xaa, 0x74, 0xff, 0x0f, 0xab, 0x75, 0xff, 0x0e, 0xa9, 0x74, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0b, 0xa7, 0x71, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x08, 0xa5, 0x6d, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x75, 0xff, 0x0d, 0xa5, 0x75, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x75, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0d, 0xa9, 0x75, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x0a, 0xa9, 0x73, 0xff, 0x0d, 0xaa, 0x74, 0xff, 0x0c, 0xaa, 0x74, 0xff, 0x13, 0xad, 0x78, 0xff, 0x17, 0xaf, 0x7b, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x06, 0xa8, 0x72, 0xff, 0x03, 0xa6, 0x6d, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x04, 0xa8, 0x6f, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x01, 0x9e, 0x64, 0xff, 0x04, 0xa6, 0x69, 0xff, 0x19, 0xac, 0x74, 0xff, 0x1f, 0x9b, 0x6c, 0xff, 0x09, 0x51, 0x2f, 0xff, 0x01, 0x1f, 0x0a, 0xff, 0x01, 0x14, 0x02, 0xff, 0x05, 0x14, 0x05, 0xff, 0x03, 0x12, 0x03, 0xff, 0x01, 0x12, 0x03, 0xff, 0x00, 0x13, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x02, 0x13, 0x01, 0xff, 0x01, 0x12, 0x02, 0xff, 0x01, 0x12, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x00, 0x11, 0x01, 0xff, 0x01, 0x12, 0x02, 0xff, 0x00, 0x12, 0x02, 0xff, 0x01, 0x12, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x01, 0x13, 0x02, 0xff, 0x02, 0x15, 0x03, 0xff, 0x03, 0x15, 0x04, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x15, 0x03, 0xff, 0x01, 0x15, 0x03, 0xff, 0x01, 0x16, 0x04, 0xff, 0x03, 0x18, 0x06, 0xff, 0x04, 0x19, 0x07, 0xff, 0x03, 0x19, 0x07, 0xff, 0x04, 0x19, 0x06, 0xff, 0x05, 0x18, 0x06, 0xff, 0x03, 0x18, 0x05, 0xff, 0x02, 0x19, 0x05, 0xff, 0x01, 0x1a, 0x04, 0xff, 0x00, 0x19, 0x02, 0xff, 0x00, 0x1c, 0x04, 0xff, 0x06, 0x22, 0x0a, 0xff, 0x02, 0x30, 0x14, 0xff, 0x13, 0x7a, 0x53, 0xff, 0x1c, 0xa7, 0x78, 0xff, 0x15, 0xad, 0x79, 0xff, 0x10, 0xa8, 0x71, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x0a, 0xa1, 0x65, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x07, 0x9b, 0x59, 0xff, 0x07, 0x9a, 0x56, 0xff, 0x07, 0x98, 0x54, 0xff, 0x08, 0x99, 0x55, 0xff, 0x0b, 0x9a, 0x56, 0xff, 0x0a, 0x99, 0x55, 0xff, 0x08, 0x97, 0x52, 0xff, 0x07, 0x95, 0x50, 0xff, 0x07, 0x93, 0x4e, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x07, 0x90, 0x4c, 0xff, 0x08, 0x8f, 0x4b, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x09, 0x90, 0x4d, 0xff, 0x08, 0x8d, 0x4b, 0xff, 0x08, 0x8a, 0x48, 0xff, 0x09, 0x86, 0x45, 0xff, 0x0a, 0x84, 0x44, 0xff, 0x08, 0x82, 0x42, 0xff, 0x07, 0x81, 0x41, 0xff, 0x06, 0x80, 0x40, 0xff, 0x07, 0x7e, 0x3e, 0xff, 0x0a, 0x7c, 0x45, 0xff, 0x0c, 0x7b, 0x4b, 0xff, 0x1c, 0x8b, 0x55, 0xff, 0x09, 0x79, 0x38, 0xff, 0x0d, 0x6f, 0x42, 0xff, 0x0e, 0x58, 0x5a, 0xff, 0x14, 0x3a, 0x81, 0xff, 0x2f, 0x44, 0x9f, 0xff, 0x4a, 0x5a, 0xb5, 0xff, 0x2d, 0x41, 0xa4, 0xff, 0x10, 0x24, 0xa2, 0xff, 0x0c, 0x24, 0xaf, 0xff, 0x11, 0x2e, 0xb3, 0xff, 0x17, 0x32, 0xb5, 0xff, 0x1e, 0x2e, 0xc0, 0xff, 0x27, 0x38, 0xc3, 0xff, 0x2d, 0x4e, 0xc4, 0xff, 0x36, 0x65, 0xb6, 0xff, 0x1f, 0x61, 0x5a, 0xff, 0x1d, 0x73, 0x31, 0xff, 0x19, 0x70, 0x2b, 0xff, 0x19, 0x64, 0x31, 0xff, 0x0f, 0x63, 0x27, 0xff, 0x37, 0xa1, 0x5c, 0xff, 0x2b, 0xab, 0x5e, 0xff, 0x3b, 0xba, 0x6e, 0xff, 0x3a, 0x9b, 0x60, 0xff, 0x07, 0x3c, 0x1b, 0xff, 0x22, 0x5e, 0x52, 0xff, 0x3e, 0x85, 0x6b, 0xff, 0x62, 0x86, 0x71, 0xff, + 0x93, 0x93, 0xa1, 0xff, 0x95, 0x8b, 0x9f, 0xff, 0x8f, 0x80, 0x94, 0xff, 0x88, 0x84, 0x8e, 0xff, 0x90, 0x8d, 0x92, 0xff, 0x8d, 0x88, 0x94, 0xff, 0x76, 0x73, 0x7e, 0xff, 0x60, 0x69, 0x7a, 0xff, 0x3b, 0x5e, 0x7a, 0xff, 0x3b, 0x70, 0x92, 0xff, 0x3a, 0x71, 0x93, 0xff, 0x39, 0x6c, 0x8c, 0xff, 0x40, 0x66, 0x85, 0xff, 0x5d, 0x62, 0x78, 0xff, 0x75, 0x69, 0x7f, 0xff, 0x7c, 0x73, 0x81, 0xff, 0x88, 0x81, 0x85, 0xff, 0x81, 0x7d, 0x87, 0xff, 0x83, 0x81, 0x8c, 0xff, 0x88, 0x85, 0x92, 0xff, 0x6c, 0x72, 0x8f, 0xff, 0x21, 0x50, 0x77, 0xff, 0x13, 0x6e, 0x81, 0xff, 0x1c, 0xa3, 0x87, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x16, 0xab, 0x79, 0xff, 0x17, 0xac, 0x7c, 0xff, 0x14, 0xaa, 0x74, 0xff, 0x0d, 0xa0, 0x69, 0xff, 0x15, 0xa4, 0x72, 0xff, 0x16, 0xa7, 0x78, 0xff, 0x1c, 0xb0, 0x82, 0xff, 0x14, 0xaf, 0x7e, 0xff, 0x0c, 0xb0, 0x78, 0xff, 0x0b, 0xb2, 0x77, 0xff, 0x0d, 0xb4, 0x75, 0xff, 0x0d, 0xb5, 0x76, 0xff, 0x0b, 0xb5, 0x77, 0xff, 0x0a, 0xb7, 0x77, 0xff, 0x08, 0xb8, 0x78, 0xff, 0x08, 0xba, 0x7a, 0xff, 0x0c, 0xb7, 0x78, 0xff, 0x12, 0xb5, 0x78, 0xff, 0x11, 0xb3, 0x76, 0xff, 0x0e, 0xb2, 0x75, 0xff, 0x0f, 0xb1, 0x73, 0xff, 0x11, 0xb3, 0x75, 0xff, 0x13, 0xb4, 0x79, 0xff, 0x18, 0xb5, 0x7b, 0xff, 0x22, 0xb1, 0x7c, 0xff, 0x25, 0xa4, 0x73, 0xff, 0x1a, 0x86, 0x59, 0xff, 0x13, 0x6f, 0x46, 0xff, 0x0f, 0x54, 0x32, 0xff, 0x09, 0x42, 0x23, 0xff, 0x05, 0x2c, 0x11, 0xff, 0x04, 0x26, 0x0c, 0xff, 0x04, 0x20, 0x09, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x01, 0x1a, 0x05, 0xff, 0x00, 0x17, 0x03, 0xff, 0x00, 0x14, 0x01, 0xff, 0x00, 0x13, 0x01, 0xff, 0x00, 0x14, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x00, 0x15, 0x03, 0xff, 0x01, 0x16, 0x05, 0xff, 0x02, 0x1a, 0x07, 0xff, 0x03, 0x1f, 0x0a, 0xff, 0x03, 0x27, 0x0e, 0xff, 0x07, 0x36, 0x1c, 0xff, 0x0d, 0x4c, 0x30, 0xff, 0x10, 0x5d, 0x3d, 0xff, 0x16, 0x7a, 0x55, 0xff, 0x1b, 0x93, 0x68, 0xff, 0x1a, 0xa9, 0x76, 0xff, 0x16, 0xb0, 0x7a, 0xff, 0x14, 0xb4, 0x7d, 0xff, 0x15, 0xb3, 0x7d, 0xff, 0x17, 0xb3, 0x7d, 0xff, 0x18, 0xb3, 0x7d, 0xff, 0x16, 0xb2, 0x7c, 0xff, 0x16, 0xb3, 0x7d, 0xff, 0x15, 0xb3, 0x7d, 0xff, 0x15, 0xb3, 0x7d, 0xff, 0x16, 0xb4, 0x7f, 0xff, 0x17, 0xb4, 0x7e, 0xff, 0x19, 0xb3, 0x7c, 0xff, 0x19, 0xb4, 0x7c, 0xff, 0x15, 0xb1, 0x7a, 0xff, 0x12, 0xaf, 0x77, 0xff, 0x0f, 0xad, 0x72, 0xff, 0x0c, 0xab, 0x6f, 0xff, 0x0c, 0xab, 0x6e, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xac, 0x6f, 0xff, 0x0c, 0xaf, 0x71, 0xff, 0x0b, 0xb0, 0x72, 0xff, 0x0a, 0xb0, 0x72, 0xff, 0x09, 0xaf, 0x70, 0xff, 0x0a, 0xb0, 0x72, 0xff, 0x0c, 0xb2, 0x75, 0xff, 0x0f, 0xb4, 0x79, 0xff, 0x12, 0xb7, 0x7d, 0xff, 0x13, 0xb7, 0x7f, 0xff, 0x14, 0xb8, 0x80, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x16, 0xb8, 0x82, 0xff, 0x18, 0xba, 0x83, 0xff, 0x19, 0xbc, 0x86, 0xff, 0x18, 0xbc, 0x86, 0xff, 0x19, 0xbc, 0x87, 0xff, 0x18, 0xbc, 0x86, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x19, 0xbc, 0x85, 0xff, 0x17, 0xbb, 0x83, 0xff, 0x15, 0xb9, 0x80, 0xff, 0x13, 0xb7, 0x7f, 0xff, 0x13, 0xb6, 0x80, 0xff, 0x15, 0xb7, 0x81, 0xff, 0x14, 0xb6, 0x80, 0xff, 0x14, 0xb5, 0x7f, 0xff, 0x10, 0xb1, 0x7b, 0xff, 0x10, 0xb2, 0x7a, 0xff, 0x0e, 0xb0, 0x77, 0xff, 0x0c, 0xae, 0x76, 0xff, 0x0a, 0xae, 0x75, 0xff, 0x0e, 0xb5, 0x78, 0xff, 0x14, 0xbc, 0x7d, 0xff, 0x12, 0xb8, 0x78, 0xff, 0x0e, 0xb1, 0x71, 0xff, 0x12, 0xae, 0x70, 0xff, 0x17, 0xb0, 0x73, 0xff, 0x22, 0xa9, 0x74, 0xff, 0x19, 0x8a, 0x5b, 0xff, 0x09, 0x54, 0x2d, 0xff, 0x05, 0x31, 0x12, 0xff, 0x01, 0x1a, 0x04, 0xff, 0x05, 0x17, 0x03, 0xff, 0x05, 0x16, 0x03, 0xff, 0x01, 0x14, 0x01, 0xff, 0x01, 0x14, 0x01, 0xff, 0x01, 0x15, 0x01, 0xff, 0x01, 0x14, 0x01, 0xff, 0x01, 0x13, 0x02, 0xff, 0x02, 0x15, 0x03, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x15, 0x02, 0xff, 0x01, 0x15, 0x01, 0xff, 0x01, 0x15, 0x01, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x14, 0x02, 0xff, 0x03, 0x14, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x02, 0x16, 0x03, 0xff, 0x03, 0x17, 0x03, 0xff, 0x02, 0x15, 0x04, 0xff, 0x02, 0x15, 0x08, 0xff, 0x01, 0x16, 0x07, 0xff, 0x01, 0x16, 0x06, 0xff, 0x04, 0x14, 0x04, 0xff, 0x05, 0x13, 0x04, 0xff, 0x04, 0x17, 0x04, 0xff, 0x01, 0x18, 0x03, 0xff, 0x01, 0x2d, 0x10, 0xff, 0x0c, 0x5f, 0x3d, 0xff, 0x2d, 0xa0, 0x79, 0xff, 0x2d, 0xb3, 0x88, 0xff, 0x1e, 0xb7, 0x86, 0xff, 0x13, 0xb2, 0x7e, 0xff, 0x0c, 0xad, 0x78, 0xff, 0x0b, 0xac, 0x76, 0xff, 0x09, 0xac, 0x72, 0xff, 0x08, 0xac, 0x71, 0xff, 0x08, 0xac, 0x72, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x0a, 0xab, 0x72, 0xff, 0x0b, 0xaa, 0x73, 0xff, 0x0c, 0xa9, 0x73, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0d, 0xa8, 0x75, 0xff, 0x0c, 0xa7, 0x76, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa5, 0x74, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0e, 0xa5, 0x77, 0xff, 0x0f, 0xa6, 0x76, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0a, 0xa8, 0x74, 0xff, 0x09, 0xa8, 0x74, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x09, 0xa7, 0x73, 0xff, 0x09, 0xa7, 0x74, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0c, 0xa6, 0x74, 0xff, 0x09, 0xa6, 0x73, 0xff, 0x08, 0xa7, 0x73, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x09, 0xa7, 0x73, 0xff, 0x0b, 0xa7, 0x73, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x04, 0x9d, 0x65, 0xff, 0x03, 0xa0, 0x66, 0xff, 0x10, 0xac, 0x73, 0xff, 0x18, 0xac, 0x76, 0xff, 0x1a, 0x9b, 0x6b, 0xff, 0x11, 0x70, 0x47, 0xff, 0x05, 0x39, 0x16, 0xff, 0x01, 0x23, 0x07, 0xff, 0x01, 0x16, 0x01, 0xff, 0x02, 0x13, 0x01, 0xff, 0x01, 0x11, 0x00, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x01, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, 0xff, 0x04, 0x10, 0x00, 0xff, 0x05, 0x11, 0x02, 0xff, 0x02, 0x11, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x01, 0x12, 0x03, 0xff, 0x01, 0x12, 0x03, 0xff, 0x01, 0x11, 0x02, 0xff, 0x02, 0x11, 0x02, 0xff, 0x02, 0x12, 0x02, 0xff, 0x02, 0x12, 0x01, 0xff, 0x03, 0x13, 0x02, 0xff, 0x01, 0x12, 0x02, 0xff, 0x01, 0x13, 0x03, 0xff, 0x02, 0x14, 0x04, 0xff, 0x02, 0x13, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x01, 0x14, 0x02, 0xff, 0x00, 0x15, 0x02, 0xff, 0x00, 0x15, 0x01, 0xff, 0x01, 0x14, 0x00, 0xff, 0x01, 0x21, 0x07, 0xff, 0x08, 0x53, 0x30, 0xff, 0x1d, 0x9f, 0x6f, 0xff, 0x16, 0xaf, 0x7a, 0xff, 0x0c, 0xa9, 0x70, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0b, 0xa0, 0x65, 0xff, 0x0b, 0xa0, 0x62, 0xff, 0x0a, 0x9e, 0x5e, 0xff, 0x09, 0x9b, 0x5b, 0xff, 0x08, 0x99, 0x57, 0xff, 0x08, 0x99, 0x55, 0xff, 0x09, 0x99, 0x54, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x09, 0x99, 0x54, 0xff, 0x07, 0x96, 0x51, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x08, 0x93, 0x4e, 0xff, 0x0a, 0x92, 0x4e, 0xff, 0x09, 0x90, 0x4c, 0xff, 0x0a, 0x8f, 0x4a, 0xff, 0x0a, 0x90, 0x4b, 0xff, 0x0a, 0x90, 0x4b, 0xff, 0x09, 0x8c, 0x4a, 0xff, 0x08, 0x88, 0x46, 0xff, 0x09, 0x85, 0x44, 0xff, 0x09, 0x84, 0x43, 0xff, 0x09, 0x82, 0x41, 0xff, 0x08, 0x81, 0x41, 0xff, 0x07, 0x80, 0x40, 0xff, 0x07, 0x7f, 0x43, 0xff, 0x07, 0x7b, 0x44, 0xff, 0x0a, 0x7a, 0x46, 0xff, 0x0b, 0x76, 0x45, 0xff, 0x0b, 0x73, 0x3f, 0xff, 0x0d, 0x62, 0x50, 0xff, 0x0e, 0x4a, 0x6e, 0xff, 0x12, 0x30, 0x94, 0xff, 0x14, 0x27, 0x98, 0xff, 0x13, 0x29, 0x99, 0xff, 0x10, 0x27, 0x9e, 0xff, 0x2c, 0x41, 0xc1, 0xff, 0x23, 0x39, 0xbd, 0xff, 0x15, 0x2d, 0xaf, 0xff, 0x23, 0x3d, 0xbe, 0xff, 0x3d, 0x59, 0xd7, 0xff, 0x33, 0x52, 0xcd, 0xff, 0x22, 0x40, 0xc6, 0xff, 0x2f, 0x4d, 0xc9, 0xff, 0x37, 0x6a, 0x97, 0xff, 0x1b, 0x6b, 0x42, 0xff, 0x13, 0x6b, 0x22, 0xff, 0x17, 0x64, 0x27, 0xff, 0x0d, 0x55, 0x20, 0xff, 0x19, 0x6c, 0x31, 0xff, 0x27, 0x9e, 0x53, 0xff, 0x1b, 0x9b, 0x4f, 0xff, 0x36, 0xa4, 0x5f, 0xff, 0x25, 0x74, 0x40, 0xff, 0x0f, 0x41, 0x2c, 0xff, 0x42, 0x7b, 0x6b, 0xff, 0x6f, 0x90, 0x7e, 0xff, + 0x7e, 0x8a, 0x91, 0xff, 0x9a, 0x95, 0xa5, 0xff, 0x9c, 0x90, 0xa1, 0xff, 0x8b, 0x87, 0x93, 0xff, 0x86, 0x84, 0x8e, 0xff, 0x80, 0x7d, 0x89, 0xff, 0x72, 0x72, 0x7d, 0xff, 0x4c, 0x5e, 0x72, 0xff, 0x31, 0x5f, 0x80, 0xff, 0x34, 0x6e, 0x92, 0xff, 0x37, 0x6f, 0x8e, 0xff, 0x36, 0x70, 0x8e, 0xff, 0x3a, 0x6d, 0x8c, 0xff, 0x52, 0x64, 0x7f, 0xff, 0x62, 0x61, 0x78, 0xff, 0x7b, 0x75, 0x80, 0xff, 0x8c, 0x83, 0x89, 0xff, 0x90, 0x89, 0x9b, 0xff, 0x8f, 0x8f, 0x9f, 0xff, 0x79, 0x81, 0x94, 0xff, 0x48, 0x60, 0x82, 0xff, 0x0e, 0x56, 0x6f, 0xff, 0x17, 0x8b, 0x83, 0xff, 0x1a, 0xac, 0x82, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x15, 0xae, 0x79, 0xff, 0x14, 0xac, 0x79, 0xff, 0x11, 0xa8, 0x79, 0xff, 0x10, 0xa4, 0x74, 0xff, 0x0a, 0x9c, 0x69, 0xff, 0x0c, 0x9c, 0x66, 0xff, 0x0f, 0x99, 0x66, 0xff, 0x1f, 0xaa, 0x7c, 0xff, 0x30, 0xbf, 0x95, 0xff, 0x1f, 0xb7, 0x8b, 0xff, 0x15, 0xb6, 0x83, 0xff, 0x0c, 0xb3, 0x79, 0xff, 0x0d, 0xb4, 0x75, 0xff, 0x0e, 0xb4, 0x76, 0xff, 0x0a, 0xb5, 0x77, 0xff, 0x08, 0xb6, 0x78, 0xff, 0x0a, 0xb8, 0x78, 0xff, 0x0b, 0xb9, 0x78, 0xff, 0x0e, 0xb8, 0x77, 0xff, 0x10, 0xb6, 0x78, 0xff, 0x11, 0xb0, 0x78, 0xff, 0x11, 0xaf, 0x76, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x10, 0xb1, 0x74, 0xff, 0x12, 0xb2, 0x74, 0xff, 0x15, 0xb2, 0x77, 0xff, 0x19, 0xb2, 0x78, 0xff, 0x1e, 0xb3, 0x79, 0xff, 0x1f, 0xae, 0x77, 0xff, 0x25, 0xa4, 0x73, 0xff, 0x23, 0x96, 0x67, 0xff, 0x1c, 0x7b, 0x51, 0xff, 0x1b, 0x6e, 0x46, 0xff, 0x1b, 0x63, 0x40, 0xff, 0x14, 0x57, 0x36, 0xff, 0x0c, 0x4e, 0x2d, 0xff, 0x08, 0x43, 0x24, 0xff, 0x07, 0x39, 0x1c, 0xff, 0x09, 0x39, 0x1d, 0xff, 0x0c, 0x41, 0x25, 0xff, 0x0e, 0x45, 0x2a, 0xff, 0x0d, 0x45, 0x29, 0xff, 0x0e, 0x4a, 0x2e, 0xff, 0x13, 0x55, 0x37, 0xff, 0x18, 0x60, 0x3e, 0xff, 0x16, 0x6b, 0x46, 0xff, 0x21, 0x80, 0x5a, 0xff, 0x25, 0x93, 0x6b, 0xff, 0x20, 0x9b, 0x70, 0xff, 0x19, 0xa3, 0x74, 0xff, 0x16, 0xaa, 0x77, 0xff, 0x15, 0xb1, 0x7a, 0xff, 0x16, 0xb4, 0x7c, 0xff, 0x17, 0xb2, 0x7c, 0xff, 0x17, 0xb3, 0x7d, 0xff, 0x17, 0xb3, 0x7d, 0xff, 0x17, 0xb3, 0x7d, 0xff, 0x16, 0xb2, 0x7c, 0xff, 0x16, 0xb2, 0x7b, 0xff, 0x16, 0xb2, 0x7c, 0xff, 0x17, 0xb3, 0x7d, 0xff, 0x17, 0xb3, 0x7c, 0xff, 0x16, 0xb2, 0x7b, 0xff, 0x15, 0xb0, 0x79, 0xff, 0x13, 0xb0, 0x77, 0xff, 0x0f, 0xac, 0x71, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0a, 0xab, 0x6d, 0xff, 0x0b, 0xac, 0x6d, 0xff, 0x0b, 0xae, 0x70, 0xff, 0x0b, 0xb0, 0x71, 0xff, 0x0b, 0xb2, 0x73, 0xff, 0x0b, 0xb1, 0x72, 0xff, 0x0b, 0xaf, 0x71, 0xff, 0x0c, 0xb1, 0x72, 0xff, 0x0e, 0xb3, 0x76, 0xff, 0x10, 0xb5, 0x78, 0xff, 0x13, 0xb7, 0x7c, 0xff, 0x13, 0xb7, 0x7e, 0xff, 0x15, 0xb8, 0x80, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x19, 0xbd, 0x86, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x19, 0xbd, 0x86, 0xff, 0x18, 0xbd, 0x85, 0xff, 0x18, 0xbd, 0x84, 0xff, 0x18, 0xbd, 0x84, 0xff, 0x16, 0xbc, 0x82, 0xff, 0x14, 0xba, 0x7f, 0xff, 0x14, 0xb7, 0x7f, 0xff, 0x14, 0xb7, 0x7f, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x14, 0xb5, 0x7f, 0xff, 0x14, 0xb4, 0x7e, 0xff, 0x10, 0xb0, 0x7a, 0xff, 0x10, 0xb1, 0x79, 0xff, 0x0e, 0xaf, 0x76, 0xff, 0x0b, 0xae, 0x76, 0xff, 0x0a, 0xaf, 0x75, 0xff, 0x0e, 0xb3, 0x76, 0xff, 0x13, 0xb8, 0x78, 0xff, 0x13, 0xb7, 0x75, 0xff, 0x10, 0xb2, 0x6f, 0xff, 0x11, 0xb1, 0x6f, 0xff, 0x0f, 0xae, 0x6d, 0xff, 0x0f, 0xae, 0x70, 0xff, 0x18, 0xae, 0x73, 0xff, 0x21, 0x9a, 0x67, 0xff, 0x1c, 0x76, 0x49, 0xff, 0x09, 0x41, 0x1e, 0xff, 0x02, 0x27, 0x0a, 0xff, 0x01, 0x1a, 0x01, 0xff, 0x00, 0x17, 0x00, 0xff, 0x00, 0x15, 0x00, 0xff, 0x03, 0x15, 0x00, 0xff, 0x03, 0x15, 0x01, 0xff, 0x04, 0x14, 0x03, 0xff, 0x03, 0x14, 0x04, 0xff, 0x02, 0x13, 0x04, 0xff, 0x02, 0x13, 0x03, 0xff, 0x02, 0x13, 0x02, 0xff, 0x01, 0x14, 0x01, 0xff, 0x01, 0x15, 0x02, 0xff, 0x02, 0x15, 0x03, 0xff, 0x01, 0x14, 0x03, 0xff, 0x03, 0x12, 0x03, 0xff, 0x02, 0x14, 0x03, 0xff, 0x02, 0x16, 0x03, 0xff, 0x01, 0x16, 0x01, 0xff, 0x03, 0x14, 0x04, 0xff, 0x03, 0x12, 0x04, 0xff, 0x01, 0x13, 0x04, 0xff, 0x00, 0x14, 0x03, 0xff, 0x03, 0x14, 0x03, 0xff, 0x02, 0x13, 0x01, 0xff, 0x01, 0x1c, 0x04, 0xff, 0x02, 0x2e, 0x12, 0xff, 0x0f, 0x65, 0x40, 0xff, 0x1f, 0x9d, 0x71, 0xff, 0x27, 0xb5, 0x86, 0xff, 0x19, 0xb1, 0x80, 0xff, 0x12, 0xaf, 0x7c, 0xff, 0x12, 0xac, 0x79, 0xff, 0x12, 0xac, 0x79, 0xff, 0x0d, 0xa9, 0x76, 0xff, 0x09, 0xa9, 0x72, 0xff, 0x08, 0xab, 0x72, 0xff, 0x07, 0xab, 0x71, 0xff, 0x05, 0xaa, 0x6f, 0xff, 0x06, 0xaa, 0x6f, 0xff, 0x07, 0xaa, 0x71, 0xff, 0x0a, 0xa9, 0x72, 0xff, 0x0b, 0xa8, 0x72, 0xff, 0x0d, 0xa9, 0x73, 0xff, 0x0b, 0xa8, 0x70, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x0c, 0xa8, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x77, 0xff, 0x0d, 0xa7, 0x77, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x76, 0xff, 0x0d, 0xa6, 0x78, 0xff, 0x0d, 0xa6, 0x77, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0b, 0xa6, 0x74, 0xff, 0x0a, 0xa6, 0x74, 0xff, 0x0b, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa5, 0x74, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0b, 0xa6, 0x72, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x05, 0x9f, 0x68, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x0d, 0xab, 0x72, 0xff, 0x0e, 0xad, 0x73, 0xff, 0x11, 0xad, 0x75, 0xff, 0x18, 0xa7, 0x70, 0xff, 0x17, 0x88, 0x56, 0xff, 0x0d, 0x62, 0x36, 0xff, 0x05, 0x39, 0x17, 0xff, 0x01, 0x27, 0x0b, 0xff, 0x00, 0x16, 0x01, 0xff, 0x01, 0x10, 0x02, 0xff, 0x03, 0x0f, 0x02, 0xff, 0x01, 0x11, 0x01, 0xff, 0x02, 0x11, 0x00, 0xff, 0x04, 0x10, 0x00, 0xff, 0x05, 0x0f, 0x00, 0xff, 0x05, 0x10, 0x00, 0xff, 0x04, 0x11, 0x01, 0xff, 0x01, 0x12, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x10, 0x02, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x11, 0x03, 0xff, 0x02, 0x10, 0x03, 0xff, 0x01, 0x10, 0x02, 0xff, 0x01, 0x10, 0x01, 0xff, 0x02, 0x11, 0x00, 0xff, 0x03, 0x11, 0x00, 0xff, 0x01, 0x10, 0x01, 0xff, 0x02, 0x10, 0x02, 0xff, 0x01, 0x0f, 0x01, 0xff, 0x03, 0x11, 0x03, 0xff, 0x02, 0x10, 0x01, 0xff, 0x03, 0x10, 0x01, 0xff, 0x02, 0x11, 0x00, 0xff, 0x01, 0x12, 0x01, 0xff, 0x01, 0x14, 0x01, 0xff, 0x07, 0x3f, 0x21, 0xff, 0x1b, 0x85, 0x5b, 0xff, 0x19, 0xae, 0x79, 0xff, 0x0d, 0xad, 0x73, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0d, 0xa2, 0x66, 0xff, 0x0e, 0x9f, 0x62, 0xff, 0x0c, 0x9e, 0x5f, 0xff, 0x0a, 0x9c, 0x5b, 0xff, 0x09, 0x99, 0x59, 0xff, 0x09, 0x97, 0x55, 0xff, 0x0a, 0x98, 0x55, 0xff, 0x0b, 0x9a, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x08, 0x9a, 0x53, 0xff, 0x06, 0x99, 0x53, 0xff, 0x06, 0x96, 0x51, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x08, 0x93, 0x4e, 0xff, 0x0a, 0x91, 0x4d, 0xff, 0x0a, 0x90, 0x4a, 0xff, 0x0a, 0x8f, 0x49, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x0c, 0x90, 0x4b, 0xff, 0x0a, 0x8c, 0x48, 0xff, 0x08, 0x87, 0x45, 0xff, 0x09, 0x85, 0x43, 0xff, 0x09, 0x85, 0x43, 0xff, 0x09, 0x81, 0x41, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x07, 0x7f, 0x43, 0xff, 0x06, 0x7c, 0x42, 0xff, 0x08, 0x7a, 0x3f, 0xff, 0x09, 0x73, 0x42, 0xff, 0x0a, 0x6f, 0x45, 0xff, 0x0a, 0x57, 0x5f, 0xff, 0x0c, 0x3c, 0x7f, 0xff, 0x17, 0x2e, 0xa1, 0xff, 0x16, 0x28, 0xa4, 0xff, 0x10, 0x27, 0xa5, 0xff, 0x10, 0x26, 0xa7, 0xff, 0x29, 0x3e, 0xb9, 0xff, 0x24, 0x38, 0xb0, 0xff, 0x18, 0x2c, 0xa9, 0xff, 0x3b, 0x53, 0xcd, 0xff, 0x69, 0x87, 0xf3, 0xff, 0x50, 0x74, 0xde, 0xff, 0x26, 0x3f, 0xc0, 0xff, 0x2c, 0x3d, 0xc6, 0xff, 0x3a, 0x60, 0xb0, 0xff, 0x2c, 0x79, 0x6b, 0xff, 0x26, 0x8c, 0x45, 0xff, 0x0d, 0x6b, 0x27, 0xff, 0x0a, 0x54, 0x21, 0xff, 0x08, 0x50, 0x1b, 0xff, 0x22, 0x88, 0x43, 0xff, 0x20, 0x92, 0x4c, 0xff, 0x1e, 0x8f, 0x46, 0xff, 0x2d, 0x89, 0x4a, 0xff, 0x14, 0x44, 0x25, 0xff, 0x33, 0x61, 0x54, 0xff, 0x83, 0x9d, 0x8f, 0xff, + 0x43, 0x65, 0x60, 0xff, 0x82, 0x91, 0x96, 0xff, 0x95, 0x93, 0x9f, 0xff, 0x99, 0x95, 0xa2, 0xff, 0x85, 0x91, 0x99, 0xff, 0x71, 0x78, 0x7d, 0xff, 0x65, 0x6a, 0x76, 0xff, 0x35, 0x59, 0x76, 0xff, 0x30, 0x67, 0x8d, 0xff, 0x34, 0x6e, 0x91, 0xff, 0x3b, 0x70, 0x8b, 0xff, 0x36, 0x70, 0x87, 0xff, 0x31, 0x70, 0x8b, 0xff, 0x3e, 0x6d, 0x8a, 0xff, 0x4a, 0x62, 0x7c, 0xff, 0x6b, 0x6d, 0x81, 0xff, 0x7a, 0x7a, 0x8e, 0xff, 0x6e, 0x7a, 0x92, 0xff, 0x52, 0x6c, 0x85, 0xff, 0x2a, 0x56, 0x71, 0xff, 0x1b, 0x5d, 0x73, 0xff, 0x26, 0x97, 0x8e, 0xff, 0x17, 0xa5, 0x81, 0xff, 0x08, 0x9e, 0x72, 0xff, 0x0f, 0xa5, 0x7a, 0xff, 0x26, 0xbd, 0x90, 0xff, 0x1e, 0xb7, 0x88, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x09, 0x9a, 0x6b, 0xff, 0x13, 0xa2, 0x71, 0xff, 0x20, 0xab, 0x78, 0xff, 0x10, 0x99, 0x6d, 0xff, 0x19, 0xa4, 0x7f, 0xff, 0x31, 0xc4, 0x9d, 0xff, 0x24, 0xc1, 0x91, 0xff, 0x0f, 0xb2, 0x7c, 0xff, 0x0d, 0xb2, 0x77, 0xff, 0x0d, 0xb3, 0x76, 0xff, 0x0b, 0xb7, 0x77, 0xff, 0x08, 0xb5, 0x7b, 0xff, 0x0b, 0xb8, 0x79, 0xff, 0x0b, 0xba, 0x72, 0xff, 0x0f, 0xbb, 0x71, 0xff, 0x0f, 0xb6, 0x76, 0xff, 0x0e, 0xaf, 0x7a, 0xff, 0x0f, 0xae, 0x79, 0xff, 0x11, 0xb2, 0x72, 0xff, 0x10, 0xb0, 0x73, 0xff, 0x0f, 0xb0, 0x72, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x11, 0xb0, 0x72, 0xff, 0x14, 0xb0, 0x74, 0xff, 0x17, 0xb0, 0x75, 0xff, 0x15, 0xaf, 0x74, 0xff, 0x0f, 0xb2, 0x76, 0xff, 0x14, 0xb2, 0x79, 0xff, 0x1d, 0xb2, 0x7b, 0xff, 0x25, 0xb3, 0x7d, 0xff, 0x28, 0xaf, 0x7d, 0xff, 0x26, 0xab, 0x7a, 0xff, 0x25, 0xa9, 0x78, 0xff, 0x1f, 0xa3, 0x72, 0xff, 0x20, 0x9f, 0x6f, 0xff, 0x24, 0xa1, 0x74, 0xff, 0x2b, 0xa6, 0x79, 0xff, 0x2c, 0xa7, 0x7c, 0xff, 0x27, 0xa3, 0x78, 0xff, 0x27, 0xa7, 0x7a, 0xff, 0x24, 0xa6, 0x79, 0xff, 0x21, 0xa5, 0x77, 0xff, 0x1d, 0xa1, 0x72, 0xff, 0x19, 0xa2, 0x72, 0xff, 0x17, 0xa3, 0x73, 0xff, 0x15, 0xa8, 0x78, 0xff, 0x17, 0xaf, 0x7c, 0xff, 0x17, 0xb1, 0x7c, 0xff, 0x19, 0xb3, 0x7c, 0xff, 0x19, 0xb3, 0x7c, 0xff, 0x15, 0xb1, 0x7b, 0xff, 0x15, 0xb1, 0x7a, 0xff, 0x15, 0xb1, 0x7a, 0xff, 0x15, 0xb1, 0x79, 0xff, 0x13, 0xaf, 0x78, 0xff, 0x11, 0xad, 0x76, 0xff, 0x13, 0xaf, 0x78, 0xff, 0x14, 0xb0, 0x78, 0xff, 0x12, 0xae, 0x77, 0xff, 0x11, 0xad, 0x75, 0xff, 0x0f, 0xac, 0x72, 0xff, 0x0d, 0xaa, 0x70, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0a, 0xa9, 0x6c, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xab, 0x6d, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0c, 0xaf, 0x71, 0xff, 0x0b, 0xb1, 0x72, 0xff, 0x0b, 0xb2, 0x73, 0xff, 0x0b, 0xb1, 0x72, 0xff, 0x0b, 0xb2, 0x72, 0xff, 0x0d, 0xb4, 0x74, 0xff, 0x0e, 0xb3, 0x76, 0xff, 0x0f, 0xb4, 0x77, 0xff, 0x11, 0xb5, 0x7a, 0xff, 0x13, 0xb8, 0x7d, 0xff, 0x14, 0xb8, 0x7f, 0xff, 0x15, 0xb8, 0x80, 0xff, 0x16, 0xb9, 0x82, 0xff, 0x18, 0xbb, 0x84, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x1a, 0xbf, 0x86, 0xff, 0x19, 0xbe, 0x85, 0xff, 0x16, 0xbb, 0x82, 0xff, 0x15, 0xba, 0x81, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x15, 0xb8, 0x81, 0xff, 0x14, 0xb7, 0x83, 0xff, 0x13, 0xb4, 0x7e, 0xff, 0x10, 0xb0, 0x7a, 0xff, 0x0f, 0xb0, 0x79, 0xff, 0x0d, 0xaf, 0x76, 0xff, 0x0d, 0xb0, 0x77, 0xff, 0x0b, 0xb1, 0x76, 0xff, 0x0c, 0xb1, 0x73, 0xff, 0x0d, 0xb2, 0x72, 0xff, 0x0c, 0xaf, 0x6d, 0xff, 0x0f, 0xaf, 0x6d, 0xff, 0x14, 0xb4, 0x72, 0xff, 0x12, 0xb2, 0x70, 0xff, 0x10, 0xab, 0x6a, 0xff, 0x13, 0xaa, 0x6c, 0xff, 0x15, 0xaa, 0x6e, 0xff, 0x1d, 0xac, 0x71, 0xff, 0x22, 0xa0, 0x6b, 0xff, 0x1d, 0x87, 0x56, 0xff, 0x13, 0x5f, 0x33, 0xff, 0x0a, 0x46, 0x1e, 0xff, 0x07, 0x32, 0x12, 0xff, 0x03, 0x22, 0x0a, 0xff, 0x01, 0x19, 0x03, 0xff, 0x01, 0x15, 0x01, 0xff, 0x02, 0x12, 0x02, 0xff, 0x02, 0x12, 0x03, 0xff, 0x01, 0x12, 0x02, 0xff, 0x02, 0x12, 0x02, 0xff, 0x01, 0x14, 0x02, 0xff, 0x00, 0x14, 0x02, 0xff, 0x00, 0x14, 0x04, 0xff, 0x01, 0x14, 0x05, 0xff, 0x01, 0x14, 0x04, 0xff, 0x00, 0x13, 0x03, 0xff, 0x01, 0x14, 0x02, 0xff, 0x01, 0x14, 0x01, 0xff, 0x01, 0x16, 0x01, 0xff, 0x01, 0x15, 0x00, 0xff, 0x01, 0x1d, 0x04, 0xff, 0x00, 0x20, 0x07, 0xff, 0x03, 0x2f, 0x12, 0xff, 0x0b, 0x45, 0x25, 0xff, 0x15, 0x67, 0x42, 0xff, 0x1b, 0x87, 0x5e, 0xff, 0x26, 0xa4, 0x77, 0xff, 0x1e, 0xa3, 0x75, 0xff, 0x12, 0xa2, 0x73, 0xff, 0x0a, 0xa2, 0x70, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0f, 0xa7, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0e, 0xa8, 0x75, 0xff, 0x0d, 0xac, 0x77, 0xff, 0x0b, 0xac, 0x74, 0xff, 0x07, 0xab, 0x71, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x06, 0xa9, 0x70, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x6d, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x74, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0b, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0d, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x76, 0xff, 0x0d, 0xa7, 0x76, 0xff, 0x0d, 0xa6, 0x76, 0xff, 0x0c, 0xa6, 0x77, 0xff, 0x0c, 0xa6, 0x76, 0xff, 0x0c, 0xa7, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0b, 0xa6, 0x74, 0xff, 0x0b, 0xa5, 0x74, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x09, 0xa3, 0x6e, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x0d, 0xa8, 0x70, 0xff, 0x0e, 0xab, 0x72, 0xff, 0x0b, 0xaa, 0x71, 0xff, 0x0b, 0xac, 0x74, 0xff, 0x0e, 0xb2, 0x77, 0xff, 0x17, 0xb4, 0x7b, 0xff, 0x20, 0xb3, 0x7d, 0xff, 0x22, 0xa6, 0x73, 0xff, 0x1f, 0x92, 0x63, 0xff, 0x14, 0x61, 0x3c, 0xff, 0x0a, 0x3d, 0x21, 0xff, 0x04, 0x20, 0x09, 0xff, 0x00, 0x17, 0x02, 0xff, 0x00, 0x12, 0x01, 0xff, 0x00, 0x10, 0x00, 0xff, 0x00, 0x11, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x01, 0x10, 0x01, 0xff, 0x00, 0x10, 0x02, 0xff, 0x01, 0x10, 0x02, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x12, 0x03, 0xff, 0x00, 0x0f, 0x03, 0xff, 0x01, 0x0f, 0x02, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x10, 0x00, 0xff, 0x01, 0x11, 0x00, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x10, 0x01, 0xff, 0x01, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00, 0xff, 0x04, 0x13, 0x02, 0xff, 0x03, 0x16, 0x04, 0xff, 0x08, 0x29, 0x14, 0xff, 0x0b, 0x50, 0x30, 0xff, 0x26, 0x92, 0x6a, 0xff, 0x25, 0xaa, 0x7b, 0xff, 0x0f, 0xa7, 0x70, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0f, 0xa2, 0x66, 0xff, 0x10, 0x9f, 0x61, 0xff, 0x0e, 0x9d, 0x5e, 0xff, 0x0c, 0x9d, 0x5d, 0xff, 0x09, 0x9b, 0x59, 0xff, 0x08, 0x98, 0x56, 0xff, 0x09, 0x97, 0x54, 0xff, 0x0a, 0x98, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x06, 0x9a, 0x54, 0xff, 0x07, 0x99, 0x54, 0xff, 0x07, 0x96, 0x51, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x08, 0x92, 0x4e, 0xff, 0x08, 0x90, 0x4c, 0xff, 0x08, 0x8f, 0x4a, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x0d, 0x90, 0x4d, 0xff, 0x09, 0x8a, 0x48, 0xff, 0x07, 0x86, 0x44, 0xff, 0x0a, 0x85, 0x43, 0xff, 0x09, 0x84, 0x42, 0xff, 0x09, 0x81, 0x41, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x09, 0x81, 0x41, 0xff, 0x09, 0x7e, 0x40, 0xff, 0x09, 0x7b, 0x3d, 0xff, 0x09, 0x75, 0x3e, 0xff, 0x0b, 0x6d, 0x46, 0xff, 0x08, 0x48, 0x6b, 0xff, 0x0f, 0x2f, 0x8f, 0xff, 0x1f, 0x2d, 0xa1, 0xff, 0x1b, 0x2a, 0xa0, 0xff, 0x17, 0x26, 0xa0, 0xff, 0x1c, 0x29, 0x9e, 0xff, 0x1c, 0x2b, 0x90, 0xff, 0x20, 0x34, 0x90, 0xff, 0x26, 0x39, 0x97, 0xff, 0x3e, 0x4d, 0xac, 0xff, 0x50, 0x59, 0xae, 0xff, 0x45, 0x51, 0xa2, 0xff, 0x30, 0x3e, 0x9d, 0xff, 0x2e, 0x3b, 0xa6, 0xff, 0x2d, 0x4b, 0x9d, 0xff, 0x25, 0x70, 0x76, 0xff, 0x46, 0xc6, 0x8b, 0xff, 0x3f, 0xc3, 0x85, 0xff, 0x0e, 0x6f, 0x37, 0xff, 0x02, 0x48, 0x11, 0xff, 0x13, 0x5d, 0x26, 0xff, 0x24, 0x7e, 0x43, 0xff, 0x16, 0x87, 0x3e, 0xff, 0x17, 0x7f, 0x38, 0xff, 0x28, 0x64, 0x3a, 0xff, 0x1b, 0x46, 0x34, 0xff, 0x8f, 0xa1, 0x9d, 0xff, + 0x23, 0x50, 0x45, 0xff, 0x67, 0x84, 0x80, 0xff, 0x83, 0x88, 0x8c, 0xff, 0x89, 0x8c, 0x94, 0xff, 0x61, 0x7a, 0x7e, 0xff, 0x65, 0x71, 0x75, 0xff, 0x5e, 0x64, 0x74, 0xff, 0x2e, 0x5b, 0x7a, 0xff, 0x30, 0x6c, 0x90, 0xff, 0x34, 0x6d, 0x8e, 0xff, 0x39, 0x6a, 0x83, 0xff, 0x2d, 0x63, 0x7a, 0xff, 0x2e, 0x6e, 0x87, 0xff, 0x33, 0x70, 0x8d, 0xff, 0x3b, 0x67, 0x81, 0xff, 0x49, 0x5f, 0x79, 0xff, 0x48, 0x5d, 0x78, 0xff, 0x34, 0x58, 0x70, 0xff, 0x20, 0x58, 0x6c, 0xff, 0x18, 0x65, 0x74, 0xff, 0x2c, 0x8d, 0x8e, 0xff, 0x38, 0xbc, 0xa0, 0xff, 0x12, 0xa6, 0x7c, 0xff, 0x06, 0x9a, 0x6e, 0xff, 0x11, 0xa5, 0x7e, 0xff, 0x1d, 0xb4, 0x8c, 0xff, 0x12, 0xab, 0x7e, 0xff, 0x11, 0xab, 0x76, 0xff, 0x19, 0xb1, 0x7c, 0xff, 0x17, 0xaa, 0x7e, 0xff, 0x28, 0xb7, 0x8c, 0xff, 0x28, 0xb5, 0x83, 0xff, 0x05, 0x8e, 0x63, 0xff, 0x1f, 0xa8, 0x85, 0xff, 0x2e, 0xbd, 0x99, 0xff, 0x1c, 0xb6, 0x89, 0xff, 0x0b, 0xad, 0x7a, 0xff, 0x10, 0xb4, 0x7c, 0xff, 0x0e, 0xb5, 0x78, 0xff, 0x0f, 0xbb, 0x78, 0xff, 0x0b, 0xb5, 0x7a, 0xff, 0x0b, 0xb5, 0x78, 0xff, 0x0c, 0xb9, 0x73, 0xff, 0x0e, 0xb9, 0x72, 0xff, 0x0e, 0xb5, 0x76, 0xff, 0x0d, 0xb1, 0x78, 0xff, 0x0f, 0xb1, 0x76, 0xff, 0x11, 0xb1, 0x72, 0xff, 0x11, 0xb1, 0x73, 0xff, 0x10, 0xb0, 0x72, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x12, 0xb0, 0x72, 0xff, 0x12, 0xb0, 0x72, 0xff, 0x14, 0xb0, 0x73, 0xff, 0x13, 0xb0, 0x74, 0xff, 0x0e, 0xb1, 0x74, 0xff, 0x0f, 0xb1, 0x74, 0xff, 0x12, 0xb1, 0x75, 0xff, 0x15, 0xb2, 0x76, 0xff, 0x14, 0xb0, 0x75, 0xff, 0x13, 0xaf, 0x76, 0xff, 0x15, 0xb0, 0x77, 0xff, 0x14, 0xae, 0x76, 0xff, 0x14, 0xac, 0x74, 0xff, 0x16, 0xac, 0x76, 0xff, 0x18, 0xad, 0x77, 0xff, 0x18, 0xab, 0x77, 0xff, 0x15, 0xa8, 0x75, 0xff, 0x15, 0xa9, 0x75, 0xff, 0x11, 0xa6, 0x72, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa9, 0x75, 0xff, 0x10, 0xad, 0x7a, 0xff, 0x14, 0xb1, 0x7d, 0xff, 0x15, 0xb1, 0x7b, 0xff, 0x18, 0xb2, 0x7b, 0xff, 0x17, 0xb1, 0x7a, 0xff, 0x14, 0xb1, 0x78, 0xff, 0x14, 0xb1, 0x78, 0xff, 0x14, 0xb0, 0x77, 0xff, 0x13, 0xb0, 0x77, 0xff, 0x14, 0xb0, 0x77, 0xff, 0x11, 0xae, 0x75, 0xff, 0x13, 0xb0, 0x77, 0xff, 0x12, 0xaf, 0x76, 0xff, 0x0f, 0xac, 0x73, 0xff, 0x0e, 0xab, 0x72, 0xff, 0x0d, 0xaa, 0x70, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0b, 0xa9, 0x6c, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x0a, 0xa9, 0x6a, 0xff, 0x0c, 0xab, 0x6b, 0xff, 0x0b, 0xab, 0x6d, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0c, 0xaf, 0x71, 0xff, 0x0b, 0xb1, 0x72, 0xff, 0x0b, 0xb2, 0x73, 0xff, 0x0b, 0xb1, 0x72, 0xff, 0x0d, 0xb4, 0x75, 0xff, 0x0f, 0xb5, 0x76, 0xff, 0x0d, 0xb3, 0x76, 0xff, 0x0d, 0xb2, 0x75, 0xff, 0x0f, 0xb5, 0x78, 0xff, 0x12, 0xb8, 0x7c, 0xff, 0x14, 0xba, 0x7f, 0xff, 0x15, 0xba, 0x80, 0xff, 0x17, 0xbb, 0x83, 0xff, 0x18, 0xbd, 0x84, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x19, 0xbd, 0x86, 0xff, 0x1a, 0xbe, 0x87, 0xff, 0x19, 0xbe, 0x85, 0xff, 0x17, 0xbc, 0x83, 0xff, 0x15, 0xba, 0x81, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x14, 0xb7, 0x82, 0xff, 0x15, 0xb7, 0x83, 0xff, 0x12, 0xb4, 0x7e, 0xff, 0x0e, 0xb1, 0x7a, 0xff, 0x0f, 0xb0, 0x78, 0xff, 0x0d, 0xaf, 0x75, 0xff, 0x0e, 0xb1, 0x77, 0xff, 0x0c, 0xb1, 0x76, 0xff, 0x0c, 0xb0, 0x72, 0xff, 0x0d, 0xb1, 0x71, 0xff, 0x0c, 0xae, 0x6c, 0xff, 0x0c, 0xad, 0x6a, 0xff, 0x0f, 0xaf, 0x6d, 0xff, 0x12, 0xb0, 0x6e, 0xff, 0x14, 0xb2, 0x70, 0xff, 0x13, 0xb0, 0x6e, 0xff, 0x0b, 0xac, 0x6a, 0xff, 0x0a, 0xac, 0x6a, 0xff, 0x11, 0xaa, 0x6a, 0xff, 0x1b, 0xa5, 0x68, 0xff, 0x23, 0x98, 0x5f, 0xff, 0x24, 0x8d, 0x54, 0xff, 0x23, 0x7e, 0x4e, 0xff, 0x16, 0x68, 0x3d, 0xff, 0x0d, 0x55, 0x2d, 0xff, 0x0d, 0x48, 0x25, 0xff, 0x09, 0x39, 0x1a, 0xff, 0x07, 0x31, 0x14, 0xff, 0x05, 0x29, 0x0e, 0xff, 0x04, 0x25, 0x0b, 0xff, 0x02, 0x21, 0x08, 0xff, 0x01, 0x1c, 0x05, 0xff, 0x00, 0x18, 0x03, 0xff, 0x00, 0x17, 0x03, 0xff, 0x00, 0x18, 0x03, 0xff, 0x00, 0x1b, 0x04, 0xff, 0x01, 0x1f, 0x07, 0xff, 0x02, 0x23, 0x0a, 0xff, 0x03, 0x2c, 0x0d, 0xff, 0x08, 0x3d, 0x19, 0xff, 0x13, 0x5d, 0x35, 0xff, 0x11, 0x67, 0x3d, 0xff, 0x16, 0x77, 0x4c, 0xff, 0x1e, 0x87, 0x5c, 0xff, 0x22, 0x99, 0x6b, 0xff, 0x1b, 0xa0, 0x70, 0xff, 0x18, 0xa2, 0x70, 0xff, 0x14, 0x9e, 0x6d, 0xff, 0x0f, 0xa0, 0x6f, 0xff, 0x0d, 0xa1, 0x6f, 0xff, 0x0d, 0xa2, 0x70, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0f, 0xa8, 0x75, 0xff, 0x0d, 0xaa, 0x76, 0xff, 0x0a, 0xaa, 0x73, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x07, 0xa9, 0x70, 0xff, 0x07, 0xaa, 0x6f, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x0a, 0xa8, 0x70, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa7, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0c, 0xa6, 0x76, 0xff, 0x0c, 0xa6, 0x75, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0b, 0xa6, 0x74, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa5, 0x74, 0xff, 0x0d, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0e, 0xaa, 0x71, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0c, 0xaa, 0x73, 0xff, 0x0c, 0xae, 0x75, 0xff, 0x12, 0xb4, 0x7a, 0xff, 0x13, 0xb4, 0x7a, 0xff, 0x16, 0xb5, 0x7b, 0xff, 0x19, 0xb1, 0x78, 0xff, 0x1f, 0xa3, 0x6f, 0xff, 0x1f, 0x8f, 0x60, 0xff, 0x14, 0x6e, 0x44, 0xff, 0x11, 0x53, 0x2e, 0xff, 0x0b, 0x3d, 0x1d, 0xff, 0x05, 0x2f, 0x13, 0xff, 0x01, 0x1e, 0x06, 0xff, 0x01, 0x18, 0x04, 0xff, 0x01, 0x14, 0x03, 0xff, 0x00, 0x11, 0x01, 0xff, 0x02, 0x11, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x01, 0x11, 0x01, 0xff, 0x00, 0x0e, 0x01, 0xff, 0x01, 0x10, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x0f, 0x01, 0xff, 0x00, 0x11, 0x01, 0xff, 0x00, 0x10, 0x01, 0xff, 0x00, 0x14, 0x02, 0xff, 0x01, 0x16, 0x04, 0xff, 0x02, 0x21, 0x0a, 0xff, 0x04, 0x2e, 0x14, 0xff, 0x09, 0x42, 0x25, 0xff, 0x0d, 0x52, 0x34, 0xff, 0x20, 0x74, 0x53, 0xff, 0x20, 0x93, 0x6b, 0xff, 0x1e, 0xa6, 0x78, 0xff, 0x13, 0xa7, 0x74, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0c, 0xa2, 0x65, 0xff, 0x0f, 0xa0, 0x61, 0xff, 0x0e, 0x9e, 0x5d, 0xff, 0x0b, 0x9d, 0x5c, 0xff, 0x0a, 0x9c, 0x58, 0xff, 0x08, 0x9a, 0x55, 0xff, 0x07, 0x98, 0x54, 0xff, 0x09, 0x99, 0x54, 0xff, 0x0a, 0x9a, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x08, 0x9b, 0x55, 0xff, 0x06, 0x99, 0x54, 0xff, 0x08, 0x99, 0x54, 0xff, 0x08, 0x96, 0x51, 0xff, 0x06, 0x93, 0x4f, 0xff, 0x07, 0x91, 0x4d, 0xff, 0x08, 0x90, 0x4c, 0xff, 0x09, 0x90, 0x4b, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x0a, 0x90, 0x4a, 0xff, 0x0c, 0x8f, 0x4b, 0xff, 0x08, 0x89, 0x46, 0xff, 0x08, 0x86, 0x43, 0xff, 0x09, 0x84, 0x42, 0xff, 0x09, 0x82, 0x41, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x07, 0x80, 0x40, 0xff, 0x09, 0x81, 0x40, 0xff, 0x0a, 0x7d, 0x42, 0xff, 0x09, 0x7b, 0x3e, 0xff, 0x09, 0x75, 0x3b, 0xff, 0x09, 0x69, 0x45, 0xff, 0x0a, 0x42, 0x73, 0xff, 0x15, 0x2c, 0x97, 0xff, 0x21, 0x2a, 0x92, 0xff, 0x26, 0x35, 0x8d, 0xff, 0x31, 0x3a, 0x8f, 0xff, 0x3e, 0x41, 0x90, 0xff, 0x4b, 0x50, 0x8c, 0xff, 0x54, 0x5f, 0x91, 0xff, 0x57, 0x61, 0x97, 0xff, 0x66, 0x6a, 0xa3, 0xff, 0x69, 0x66, 0x98, 0xff, 0x64, 0x65, 0x94, 0xff, 0x54, 0x5d, 0x95, 0xff, 0x45, 0x52, 0x91, 0xff, 0x3a, 0x52, 0x8b, 0xff, 0x24, 0x65, 0x68, 0xff, 0x1e, 0xa2, 0x64, 0xff, 0x2f, 0xc2, 0x80, 0xff, 0x3f, 0xbd, 0x7a, 0xff, 0x1a, 0x6f, 0x33, 0xff, 0x06, 0x47, 0x17, 0xff, 0x12, 0x65, 0x30, 0xff, 0x18, 0x7e, 0x38, 0xff, 0x15, 0x7c, 0x33, 0xff, 0x1d, 0x6f, 0x3c, 0xff, 0x0f, 0x48, 0x2c, 0xff, 0x83, 0x98, 0x95, 0xff, + 0x13, 0x44, 0x34, 0xff, 0x4e, 0x75, 0x68, 0xff, 0x77, 0x86, 0x80, 0xff, 0x61, 0x7b, 0x73, 0xff, 0x3d, 0x66, 0x61, 0xff, 0x5f, 0x6d, 0x73, 0xff, 0x56, 0x5e, 0x76, 0xff, 0x32, 0x61, 0x83, 0xff, 0x30, 0x6f, 0x8a, 0xff, 0x2d, 0x6b, 0x79, 0xff, 0x25, 0x58, 0x62, 0xff, 0x21, 0x54, 0x66, 0xff, 0x31, 0x6d, 0x87, 0xff, 0x38, 0x77, 0x97, 0xff, 0x2b, 0x67, 0x85, 0xff, 0x1c, 0x56, 0x6c, 0xff, 0x1a, 0x55, 0x68, 0xff, 0x2f, 0x78, 0x84, 0xff, 0x2e, 0x8a, 0x8c, 0xff, 0x1f, 0x92, 0x7e, 0xff, 0x1e, 0x9c, 0x7b, 0xff, 0x28, 0xaf, 0x8b, 0xff, 0x14, 0xa0, 0x7b, 0xff, 0x17, 0xa6, 0x7d, 0xff, 0x1a, 0xa9, 0x84, 0xff, 0x10, 0xa3, 0x7f, 0xff, 0x08, 0x9f, 0x74, 0xff, 0x15, 0xb0, 0x7d, 0xff, 0x1d, 0xb7, 0x85, 0xff, 0x31, 0xc5, 0x9d, 0xff, 0x3a, 0xcc, 0xa3, 0xff, 0x11, 0xa0, 0x6d, 0xff, 0x02, 0x8b, 0x5f, 0xff, 0x3f, 0xca, 0xa5, 0xff, 0x3a, 0xc8, 0xa3, 0xff, 0x0c, 0xa5, 0x79, 0xff, 0x0b, 0xac, 0x7a, 0xff, 0x10, 0xb4, 0x7d, 0xff, 0x10, 0xb6, 0x7a, 0xff, 0x18, 0xc1, 0x7f, 0xff, 0x14, 0xba, 0x7d, 0xff, 0x0d, 0xb4, 0x77, 0xff, 0x0e, 0xb6, 0x74, 0xff, 0x0e, 0xb5, 0x75, 0xff, 0x0e, 0xb4, 0x77, 0xff, 0x0c, 0xb1, 0x73, 0xff, 0x0d, 0xb2, 0x71, 0xff, 0x11, 0xb0, 0x72, 0xff, 0x11, 0xb0, 0x72, 0xff, 0x11, 0xb1, 0x73, 0xff, 0x0f, 0xb0, 0x72, 0xff, 0x10, 0xb0, 0x72, 0xff, 0x11, 0xb2, 0x74, 0xff, 0x13, 0xb2, 0x74, 0xff, 0x13, 0xb1, 0x74, 0xff, 0x14, 0xb1, 0x73, 0xff, 0x12, 0xb0, 0x70, 0xff, 0x0f, 0xb0, 0x70, 0xff, 0x0c, 0xb0, 0x70, 0xff, 0x06, 0xad, 0x6c, 0xff, 0x07, 0xae, 0x6e, 0xff, 0x08, 0xae, 0x70, 0xff, 0x08, 0xae, 0x70, 0xff, 0x07, 0xad, 0x6f, 0xff, 0x08, 0xad, 0x70, 0xff, 0x0c, 0xad, 0x72, 0xff, 0x0c, 0xac, 0x73, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0f, 0xab, 0x73, 0xff, 0x10, 0xad, 0x77, 0xff, 0x12, 0xaf, 0x79, 0xff, 0x13, 0xaf, 0x79, 0xff, 0x13, 0xae, 0x78, 0xff, 0x12, 0xac, 0x75, 0xff, 0x10, 0xac, 0x71, 0xff, 0x10, 0xac, 0x71, 0xff, 0x10, 0xac, 0x71, 0xff, 0x0f, 0xab, 0x70, 0xff, 0x11, 0xae, 0x71, 0xff, 0x12, 0xae, 0x73, 0xff, 0x12, 0xaf, 0x73, 0xff, 0x11, 0xad, 0x72, 0xff, 0x0d, 0xab, 0x70, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xaa, 0x6d, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0a, 0xa9, 0x6a, 0xff, 0x0a, 0xa9, 0x69, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0c, 0xaf, 0x71, 0xff, 0x0c, 0xb2, 0x73, 0xff, 0x0c, 0xb3, 0x74, 0xff, 0x0b, 0xb3, 0x74, 0xff, 0x0d, 0xb6, 0x77, 0xff, 0x0f, 0xb6, 0x77, 0xff, 0x0d, 0xb3, 0x76, 0xff, 0x0d, 0xb3, 0x76, 0xff, 0x0e, 0xb5, 0x76, 0xff, 0x10, 0xb6, 0x78, 0xff, 0x12, 0xb9, 0x7c, 0xff, 0x14, 0xba, 0x7f, 0xff, 0x16, 0xbc, 0x81, 0xff, 0x18, 0xbd, 0x84, 0xff, 0x18, 0xbc, 0x84, 0xff, 0x17, 0xbb, 0x84, 0xff, 0x17, 0xbb, 0x84, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x19, 0xbd, 0x86, 0xff, 0x19, 0xbd, 0x85, 0xff, 0x17, 0xbb, 0x84, 0xff, 0x17, 0xbb, 0x84, 0xff, 0x14, 0xb8, 0x82, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x12, 0xb6, 0x80, 0xff, 0x13, 0xb6, 0x81, 0xff, 0x11, 0xb4, 0x7e, 0xff, 0x0f, 0xb2, 0x7b, 0xff, 0x0d, 0xaf, 0x77, 0xff, 0x0b, 0xae, 0x74, 0xff, 0x0d, 0xb0, 0x74, 0xff, 0x0d, 0xb0, 0x73, 0xff, 0x0e, 0xb1, 0x72, 0xff, 0x0d, 0xb0, 0x6f, 0xff, 0x0d, 0xaf, 0x6c, 0xff, 0x0b, 0xac, 0x68, 0xff, 0x0b, 0xaa, 0x67, 0xff, 0x0c, 0xaa, 0x67, 0xff, 0x0c, 0xae, 0x6a, 0xff, 0x0f, 0xb4, 0x6e, 0xff, 0x0e, 0xb2, 0x6c, 0xff, 0x0b, 0xad, 0x67, 0xff, 0x0b, 0xaa, 0x62, 0xff, 0x0b, 0xa4, 0x5e, 0xff, 0x12, 0xa5, 0x5d, 0xff, 0x14, 0xa4, 0x5c, 0xff, 0x19, 0xa4, 0x60, 0xff, 0x18, 0x9f, 0x5e, 0xff, 0x1e, 0x9e, 0x5f, 0xff, 0x21, 0x9b, 0x60, 0xff, 0x23, 0x93, 0x5d, 0xff, 0x24, 0x8c, 0x57, 0xff, 0x21, 0x82, 0x4f, 0xff, 0x1f, 0x7c, 0x4a, 0xff, 0x1c, 0x72, 0x44, 0xff, 0x13, 0x64, 0x39, 0xff, 0x06, 0x52, 0x28, 0xff, 0x04, 0x4e, 0x24, 0xff, 0x07, 0x55, 0x2a, 0xff, 0x0e, 0x5f, 0x35, 0xff, 0x15, 0x6d, 0x3f, 0xff, 0x1b, 0x75, 0x48, 0xff, 0x1b, 0x81, 0x50, 0xff, 0x21, 0x93, 0x5f, 0xff, 0x27, 0xa6, 0x6f, 0xff, 0x1f, 0xa4, 0x6e, 0xff, 0x19, 0xa0, 0x6b, 0xff, 0x17, 0x9f, 0x6b, 0xff, 0x13, 0xa1, 0x6c, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0e, 0xa1, 0x6c, 0xff, 0x12, 0xa2, 0x6e, 0xff, 0x10, 0xa1, 0x6d, 0xff, 0x10, 0xa1, 0x6e, 0xff, 0x10, 0xa1, 0x6f, 0xff, 0x11, 0xa2, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x07, 0xa3, 0x71, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x07, 0xa9, 0x6e, 0xff, 0x08, 0xaa, 0x6e, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0b, 0xa5, 0x74, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x0a, 0xa6, 0x72, 0xff, 0x0a, 0xa7, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0d, 0xa6, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x0e, 0xa6, 0x75, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xa9, 0x72, 0xff, 0x0c, 0xac, 0x74, 0xff, 0x0c, 0xad, 0x72, 0xff, 0x10, 0xb0, 0x74, 0xff, 0x10, 0xb4, 0x74, 0xff, 0x0d, 0xb2, 0x72, 0xff, 0x0c, 0xaf, 0x6f, 0xff, 0x12, 0xb1, 0x70, 0xff, 0x1a, 0xaf, 0x73, 0xff, 0x27, 0xa8, 0x71, 0xff, 0x27, 0x9d, 0x6a, 0xff, 0x25, 0x90, 0x60, 0xff, 0x1b, 0x71, 0x47, 0xff, 0x16, 0x61, 0x3b, 0xff, 0x15, 0x54, 0x33, 0xff, 0x0d, 0x45, 0x27, 0xff, 0x08, 0x3a, 0x20, 0xff, 0x05, 0x31, 0x16, 0xff, 0x03, 0x27, 0x0e, 0xff, 0x02, 0x25, 0x0d, 0xff, 0x03, 0x24, 0x0f, 0xff, 0x04, 0x28, 0x11, 0xff, 0x05, 0x2f, 0x18, 0xff, 0x05, 0x31, 0x19, 0xff, 0x06, 0x38, 0x1e, 0xff, 0x09, 0x42, 0x26, 0xff, 0x0f, 0x51, 0x32, 0xff, 0x12, 0x5b, 0x3a, 0xff, 0x1a, 0x73, 0x4f, 0xff, 0x1f, 0x88, 0x61, 0xff, 0x1d, 0x96, 0x6d, 0xff, 0x1c, 0xa0, 0x74, 0xff, 0x21, 0xab, 0x7d, 0xff, 0x14, 0xa6, 0x76, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x09, 0xa2, 0x66, 0xff, 0x0b, 0x9f, 0x60, 0xff, 0x0e, 0x9e, 0x5e, 0xff, 0x0a, 0x9d, 0x5b, 0xff, 0x03, 0x9d, 0x58, 0xff, 0x05, 0x99, 0x53, 0xff, 0x07, 0x99, 0x52, 0xff, 0x08, 0x99, 0x52, 0xff, 0x09, 0x99, 0x54, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x08, 0x9b, 0x55, 0xff, 0x06, 0x99, 0x54, 0xff, 0x0a, 0x98, 0x53, 0xff, 0x09, 0x95, 0x50, 0xff, 0x07, 0x92, 0x4e, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x0a, 0x91, 0x4a, 0xff, 0x09, 0x8c, 0x48, 0xff, 0x07, 0x87, 0x44, 0xff, 0x09, 0x85, 0x43, 0xff, 0x09, 0x83, 0x43, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x07, 0x80, 0x40, 0xff, 0x0a, 0x7e, 0x42, 0xff, 0x0b, 0x79, 0x45, 0xff, 0x0a, 0x79, 0x41, 0xff, 0x08, 0x72, 0x3c, 0xff, 0x0a, 0x67, 0x45, 0xff, 0x0e, 0x43, 0x72, 0xff, 0x18, 0x2d, 0x8b, 0xff, 0x37, 0x41, 0x8e, 0xff, 0x50, 0x5a, 0x8b, 0xff, 0x6c, 0x6a, 0x94, 0xff, 0x7a, 0x71, 0x96, 0xff, 0x83, 0x7c, 0x93, 0xff, 0x8e, 0x8d, 0x9c, 0xff, 0x88, 0x85, 0x9a, 0xff, 0x97, 0x91, 0xa9, 0xff, 0x92, 0x8b, 0x9d, 0xff, 0x8d, 0x8e, 0x9c, 0xff, 0x78, 0x84, 0x94, 0xff, 0x75, 0x87, 0x94, 0xff, 0x61, 0x7e, 0x8d, 0xff, 0x2f, 0x6d, 0x5e, 0xff, 0x23, 0x94, 0x53, 0xff, 0x0b, 0x8b, 0x46, 0xff, 0x3c, 0xb7, 0x78, 0xff, 0x3c, 0xa0, 0x66, 0xff, 0x06, 0x4a, 0x1d, 0xff, 0x03, 0x4b, 0x1c, 0xff, 0x16, 0x72, 0x33, 0xff, 0x10, 0x72, 0x2d, 0xff, 0x0f, 0x77, 0x3c, 0xff, 0x1f, 0x78, 0x4f, 0xff, 0x96, 0xb9, 0xb2, 0xff, + 0x0d, 0x3e, 0x2f, 0xff, 0x26, 0x55, 0x42, 0xff, 0x48, 0x6f, 0x58, 0xff, 0x38, 0x73, 0x58, 0xff, 0x2b, 0x68, 0x58, 0xff, 0x4b, 0x65, 0x6f, 0xff, 0x3f, 0x56, 0x75, 0xff, 0x33, 0x68, 0x87, 0xff, 0x29, 0x6d, 0x73, 0xff, 0x17, 0x5c, 0x4d, 0xff, 0x10, 0x49, 0x3e, 0xff, 0x28, 0x5c, 0x66, 0xff, 0x3c, 0x77, 0x91, 0xff, 0x46, 0x85, 0xa8, 0xff, 0x2e, 0x78, 0x98, 0xff, 0x13, 0x72, 0x7b, 0xff, 0x1e, 0x83, 0x79, 0xff, 0x39, 0xa5, 0x9a, 0xff, 0x23, 0x9b, 0x85, 0xff, 0x09, 0x93, 0x5c, 0xff, 0x12, 0x9e, 0x62, 0xff, 0x1c, 0x96, 0x75, 0xff, 0x3a, 0xb2, 0x99, 0xff, 0x3b, 0xc2, 0x9d, 0xff, 0x1e, 0xa8, 0x82, 0xff, 0x0c, 0x9d, 0x75, 0xff, 0x12, 0xa7, 0x7c, 0xff, 0x16, 0xae, 0x82, 0xff, 0x0d, 0xa7, 0x7c, 0xff, 0x26, 0xbd, 0x96, 0xff, 0x35, 0xcc, 0xa2, 0xff, 0x09, 0x9c, 0x68, 0xff, 0x06, 0x96, 0x68, 0xff, 0x22, 0xaf, 0x87, 0xff, 0x2f, 0xc0, 0x97, 0xff, 0x0a, 0xa3, 0x75, 0xff, 0x14, 0xb3, 0x82, 0xff, 0x0e, 0xb1, 0x7c, 0xff, 0x0e, 0xaf, 0x7a, 0xff, 0x20, 0xc0, 0x89, 0xff, 0x19, 0xb8, 0x83, 0xff, 0x12, 0xaf, 0x7d, 0xff, 0x12, 0xaf, 0x7d, 0xff, 0x11, 0xb0, 0x7a, 0xff, 0x0e, 0xb0, 0x73, 0xff, 0x09, 0xaf, 0x6f, 0xff, 0x0c, 0xaf, 0x70, 0xff, 0x10, 0xb0, 0x72, 0xff, 0x10, 0xaf, 0x72, 0xff, 0x10, 0xaf, 0x72, 0xff, 0x0e, 0xaf, 0x72, 0xff, 0x0f, 0xb0, 0x73, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x0e, 0xb0, 0x72, 0xff, 0x11, 0xb1, 0x73, 0xff, 0x15, 0xb0, 0x73, 0xff, 0x13, 0xb1, 0x72, 0xff, 0x0b, 0xb0, 0x6f, 0xff, 0x05, 0xae, 0x6c, 0xff, 0x03, 0xae, 0x6c, 0xff, 0x04, 0xaf, 0x6e, 0xff, 0x04, 0xae, 0x6f, 0xff, 0x05, 0xae, 0x6f, 0xff, 0x04, 0xae, 0x6d, 0xff, 0x07, 0xb0, 0x71, 0xff, 0x08, 0xae, 0x71, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x09, 0xa9, 0x70, 0xff, 0x0c, 0xa9, 0x70, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x0e, 0xa7, 0x6e, 0xff, 0x12, 0xa6, 0x6c, 0xff, 0x10, 0xa6, 0x6b, 0xff, 0x10, 0xa7, 0x6e, 0xff, 0x0f, 0xa8, 0x70, 0xff, 0x0e, 0xa9, 0x71, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0e, 0xa9, 0x72, 0xff, 0x0c, 0xa8, 0x6f, 0xff, 0x0c, 0xa8, 0x6a, 0xff, 0x0c, 0xa8, 0x69, 0xff, 0x0b, 0xa7, 0x68, 0xff, 0x0a, 0xa6, 0x68, 0xff, 0x09, 0xa6, 0x68, 0xff, 0x0d, 0xa9, 0x6b, 0xff, 0x0e, 0xaa, 0x6c, 0xff, 0x0e, 0xaa, 0x6c, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x0d, 0xac, 0x6f, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0c, 0xab, 0x6c, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0c, 0xab, 0x6b, 0xff, 0x0d, 0xac, 0x6d, 0xff, 0x0c, 0xad, 0x6f, 0xff, 0x0d, 0xb0, 0x72, 0xff, 0x0d, 0xb3, 0x74, 0xff, 0x0d, 0xb4, 0x75, 0xff, 0x0c, 0xb4, 0x75, 0xff, 0x0e, 0xb6, 0x77, 0xff, 0x0e, 0xb5, 0x76, 0xff, 0x0e, 0xb4, 0x77, 0xff, 0x0e, 0xb4, 0x76, 0xff, 0x0e, 0xb4, 0x75, 0xff, 0x0d, 0xb4, 0x74, 0xff, 0x0f, 0xb5, 0x76, 0xff, 0x10, 0xb6, 0x78, 0xff, 0x12, 0xb7, 0x7b, 0xff, 0x14, 0xb8, 0x7f, 0xff, 0x16, 0xbb, 0x83, 0xff, 0x16, 0xbb, 0x83, 0xff, 0x15, 0xba, 0x82, 0xff, 0x17, 0xbb, 0x83, 0xff, 0x18, 0xbd, 0x85, 0xff, 0x17, 0xbc, 0x84, 0xff, 0x17, 0xbc, 0x84, 0xff, 0x18, 0xbc, 0x85, 0xff, 0x16, 0xbb, 0x83, 0xff, 0x15, 0xb9, 0x82, 0xff, 0x11, 0xb5, 0x7d, 0xff, 0x11, 0xb4, 0x7e, 0xff, 0x11, 0xb4, 0x7d, 0xff, 0x0f, 0xb2, 0x7a, 0xff, 0x0c, 0xb0, 0x75, 0xff, 0x0a, 0xae, 0x71, 0xff, 0x0d, 0xaf, 0x72, 0xff, 0x0d, 0xb0, 0x70, 0xff, 0x0e, 0xb0, 0x6f, 0xff, 0x0c, 0xae, 0x6b, 0xff, 0x0b, 0xac, 0x68, 0xff, 0x0b, 0xab, 0x67, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x0c, 0xaa, 0x67, 0xff, 0x0b, 0xab, 0x68, 0xff, 0x0b, 0xab, 0x67, 0xff, 0x0e, 0xab, 0x66, 0xff, 0x10, 0xac, 0x66, 0xff, 0x13, 0xad, 0x64, 0xff, 0x12, 0xac, 0x61, 0xff, 0x11, 0xad, 0x5f, 0xff, 0x0b, 0xa7, 0x59, 0xff, 0x07, 0xa4, 0x54, 0xff, 0x09, 0xa5, 0x55, 0xff, 0x0a, 0xa4, 0x55, 0xff, 0x0a, 0xa3, 0x56, 0xff, 0x11, 0xa5, 0x5d, 0xff, 0x18, 0xa9, 0x62, 0xff, 0x1a, 0xa8, 0x63, 0xff, 0x1b, 0xa7, 0x63, 0xff, 0x1f, 0xa6, 0x67, 0xff, 0x1f, 0xa5, 0x67, 0xff, 0x1d, 0xa2, 0x65, 0xff, 0x1d, 0xa2, 0x65, 0xff, 0x1d, 0xa3, 0x66, 0xff, 0x1e, 0xa6, 0x68, 0xff, 0x1d, 0xa8, 0x69, 0xff, 0x20, 0xad, 0x6f, 0xff, 0x22, 0xb1, 0x74, 0xff, 0x1d, 0xb0, 0x74, 0xff, 0x16, 0xaa, 0x6f, 0xff, 0x11, 0xa6, 0x6c, 0xff, 0x0f, 0xa1, 0x69, 0xff, 0x10, 0xa1, 0x6a, 0xff, 0x0f, 0xa1, 0x6c, 0xff, 0x0c, 0xa1, 0x6c, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x10, 0xa3, 0x6c, 0xff, 0x11, 0xa2, 0x6d, 0xff, 0x13, 0xa4, 0x70, 0xff, 0x13, 0xa3, 0x70, 0xff, 0x14, 0xa4, 0x72, 0xff, 0x10, 0xa1, 0x6f, 0xff, 0x0d, 0xa2, 0x71, 0xff, 0x0a, 0xa3, 0x70, 0xff, 0x0b, 0xa5, 0x72, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x09, 0xaa, 0x6d, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x0a, 0xa9, 0x6e, 0xff, 0x0a, 0xaa, 0x6f, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0d, 0xa6, 0x72, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0a, 0xa6, 0x72, 0xff, 0x09, 0xa7, 0x72, 0xff, 0x0a, 0xa8, 0x71, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa7, 0x73, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0a, 0xaa, 0x71, 0xff, 0x0d, 0xac, 0x72, 0xff, 0x0f, 0xad, 0x71, 0xff, 0x0e, 0xae, 0x6c, 0xff, 0x0e, 0xaf, 0x6b, 0xff, 0x0a, 0xae, 0x67, 0xff, 0x06, 0xac, 0x65, 0xff, 0x05, 0xaa, 0x64, 0xff, 0x09, 0xaa, 0x64, 0xff, 0x0e, 0xa8, 0x65, 0xff, 0x17, 0xab, 0x6b, 0xff, 0x20, 0xaa, 0x6e, 0xff, 0x28, 0xaa, 0x72, 0xff, 0x2e, 0xa9, 0x76, 0xff, 0x2e, 0xa4, 0x73, 0xff, 0x2d, 0x9e, 0x71, 0xff, 0x2c, 0x93, 0x67, 0xff, 0x25, 0x88, 0x5f, 0xff, 0x23, 0x87, 0x5f, 0xff, 0x28, 0x8d, 0x67, 0xff, 0x2b, 0x92, 0x6c, 0xff, 0x2f, 0x96, 0x71, 0xff, 0x2c, 0x94, 0x6e, 0xff, 0x2d, 0x9a, 0x72, 0xff, 0x29, 0xa0, 0x75, 0xff, 0x27, 0xa4, 0x78, 0xff, 0x25, 0xa5, 0x79, 0xff, 0x1f, 0xa8, 0x78, 0xff, 0x1c, 0xa9, 0x79, 0xff, 0x14, 0xa8, 0x77, 0xff, 0x11, 0xab, 0x79, 0xff, 0x0c, 0xaa, 0x75, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x09, 0x9f, 0x61, 0xff, 0x09, 0x9d, 0x5d, 0xff, 0x0c, 0x9d, 0x5c, 0xff, 0x08, 0x9c, 0x58, 0xff, 0x01, 0x9a, 0x54, 0xff, 0x05, 0x99, 0x53, 0xff, 0x08, 0x9a, 0x52, 0xff, 0x09, 0x9b, 0x53, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x0a, 0x9b, 0x56, 0xff, 0x08, 0x9a, 0x55, 0xff, 0x07, 0x99, 0x53, 0xff, 0x09, 0x97, 0x52, 0xff, 0x09, 0x94, 0x50, 0xff, 0x07, 0x92, 0x4e, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x08, 0x8e, 0x48, 0xff, 0x07, 0x8a, 0x46, 0xff, 0x07, 0x85, 0x43, 0xff, 0x09, 0x84, 0x43, 0xff, 0x09, 0x83, 0x43, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x41, 0xff, 0x07, 0x80, 0x41, 0xff, 0x09, 0x7d, 0x44, 0xff, 0x0b, 0x79, 0x46, 0xff, 0x0a, 0x77, 0x41, 0xff, 0x09, 0x6f, 0x3f, 0xff, 0x07, 0x62, 0x41, 0xff, 0x13, 0x4c, 0x67, 0xff, 0x25, 0x42, 0x7f, 0xff, 0x57, 0x67, 0x95, 0xff, 0x72, 0x77, 0x8e, 0xff, 0x8f, 0x84, 0x98, 0xff, 0x9c, 0x8e, 0xa2, 0xff, 0x8d, 0x87, 0x92, 0xff, 0x91, 0x8f, 0x96, 0xff, 0x8f, 0x88, 0x95, 0xff, 0x91, 0x8b, 0x99, 0xff, 0x7d, 0x85, 0x86, 0xff, 0x67, 0x86, 0x78, 0xff, 0x50, 0x8b, 0x74, 0xff, 0x4b, 0x95, 0x6f, 0xff, 0x46, 0x91, 0x68, 0xff, 0x20, 0x72, 0x41, 0xff, 0x23, 0x97, 0x47, 0xff, 0x1d, 0x9a, 0x48, 0xff, 0x08, 0x6c, 0x2e, 0xff, 0x1a, 0x7d, 0x44, 0xff, 0x0d, 0x5e, 0x2e, 0xff, 0x01, 0x46, 0x1a, 0xff, 0x0b, 0x5e, 0x26, 0xff, 0x0a, 0x6c, 0x2f, 0xff, 0x32, 0xa7, 0x6c, 0xff, 0x43, 0xab, 0x7a, 0xff, 0x83, 0xae, 0x9c, 0xff, + 0x0f, 0x44, 0x37, 0xff, 0x0e, 0x49, 0x2f, 0xff, 0x15, 0x5d, 0x36, 0xff, 0x1d, 0x7c, 0x4e, 0xff, 0x0d, 0x60, 0x44, 0xff, 0x29, 0x5c, 0x63, 0xff, 0x1f, 0x53, 0x6c, 0xff, 0x24, 0x6b, 0x79, 0xff, 0x25, 0x75, 0x61, 0xff, 0x09, 0x53, 0x2d, 0xff, 0x0d, 0x4e, 0x34, 0xff, 0x38, 0x75, 0x78, 0xff, 0x41, 0x87, 0x9a, 0xff, 0x5a, 0xa6, 0xc1, 0xff, 0x46, 0x9e, 0xb9, 0xff, 0x0a, 0x7d, 0x77, 0xff, 0x16, 0x99, 0x6d, 0xff, 0x21, 0xa4, 0x80, 0xff, 0x0b, 0x91, 0x6b, 0xff, 0x09, 0x9c, 0x55, 0xff, 0x25, 0xb4, 0x6d, 0xff, 0x23, 0x98, 0x75, 0xff, 0x29, 0x98, 0x80, 0xff, 0x3b, 0xba, 0x99, 0xff, 0x25, 0xab, 0x82, 0xff, 0x06, 0x92, 0x62, 0xff, 0x14, 0xa7, 0x79, 0xff, 0x1d, 0xb1, 0x8c, 0xff, 0x26, 0xba, 0x97, 0xff, 0x14, 0xab, 0x86, 0xff, 0x0f, 0xa8, 0x7b, 0xff, 0x09, 0xa0, 0x6c, 0xff, 0x08, 0x9b, 0x6a, 0xff, 0x0c, 0x9d, 0x70, 0xff, 0x10, 0xa5, 0x78, 0xff, 0x0b, 0xa6, 0x73, 0xff, 0x19, 0xb7, 0x83, 0xff, 0x1b, 0xb9, 0x87, 0xff, 0x1d, 0xb6, 0x88, 0xff, 0x16, 0xaa, 0x82, 0xff, 0x12, 0xa2, 0x84, 0xff, 0x12, 0x9b, 0x8c, 0xff, 0x12, 0x9c, 0x8e, 0xff, 0x14, 0xa6, 0x85, 0xff, 0x0f, 0xa9, 0x76, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x0c, 0xac, 0x72, 0xff, 0x0c, 0xad, 0x71, 0xff, 0x0d, 0xad, 0x72, 0xff, 0x0e, 0xae, 0x72, 0xff, 0x0e, 0xae, 0x72, 0xff, 0x0e, 0xae, 0x72, 0xff, 0x0e, 0xb0, 0x72, 0xff, 0x0c, 0xaf, 0x72, 0xff, 0x0e, 0xae, 0x72, 0xff, 0x10, 0xad, 0x74, 0xff, 0x0c, 0xae, 0x72, 0xff, 0x04, 0xad, 0x6e, 0xff, 0x01, 0xaf, 0x6d, 0xff, 0x00, 0xaf, 0x6d, 0xff, 0x01, 0xad, 0x6d, 0xff, 0x03, 0xad, 0x6e, 0xff, 0x05, 0xad, 0x6f, 0xff, 0x04, 0xad, 0x6e, 0xff, 0x06, 0xaf, 0x70, 0xff, 0x08, 0xae, 0x71, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0d, 0xaa, 0x71, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0f, 0xa6, 0x6d, 0xff, 0x10, 0xa5, 0x68, 0xff, 0x0f, 0xa4, 0x67, 0xff, 0x0f, 0xa6, 0x6b, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x0d, 0xa8, 0x6e, 0xff, 0x0c, 0xa7, 0x6d, 0xff, 0x0c, 0xa9, 0x69, 0xff, 0x0b, 0xa9, 0x68, 0xff, 0x0a, 0xa8, 0x67, 0xff, 0x09, 0xa7, 0x66, 0xff, 0x08, 0xa5, 0x65, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0d, 0xaa, 0x6a, 0xff, 0x0d, 0xaa, 0x6a, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0a, 0xa9, 0x6a, 0xff, 0x0b, 0xaa, 0x6a, 0xff, 0x0d, 0xac, 0x6c, 0xff, 0x0c, 0xac, 0x6e, 0xff, 0x0d, 0xae, 0x70, 0xff, 0x0e, 0xb1, 0x73, 0xff, 0x0d, 0xb3, 0x74, 0xff, 0x0d, 0xb4, 0x75, 0xff, 0x0e, 0xb5, 0x76, 0xff, 0x0f, 0xb6, 0x77, 0xff, 0x0e, 0xb5, 0x76, 0xff, 0x0e, 0xb3, 0x76, 0xff, 0x0f, 0xb5, 0x76, 0xff, 0x0e, 0xb3, 0x74, 0xff, 0x0d, 0xb3, 0x72, 0xff, 0x0d, 0xb3, 0x72, 0xff, 0x0e, 0xb4, 0x75, 0xff, 0x0e, 0xb2, 0x75, 0xff, 0x10, 0xb3, 0x78, 0xff, 0x14, 0xb8, 0x7f, 0xff, 0x16, 0xbb, 0x81, 0xff, 0x16, 0xbb, 0x82, 0xff, 0x15, 0xba, 0x81, 0xff, 0x15, 0xb9, 0x80, 0xff, 0x14, 0xba, 0x80, 0xff, 0x17, 0xbc, 0x83, 0xff, 0x17, 0xbc, 0x83, 0xff, 0x15, 0xba, 0x81, 0xff, 0x14, 0xb8, 0x81, 0xff, 0x11, 0xb5, 0x7d, 0xff, 0x10, 0xb3, 0x7c, 0xff, 0x10, 0xb2, 0x7a, 0xff, 0x0e, 0xb2, 0x78, 0xff, 0x0d, 0xb0, 0x74, 0xff, 0x0c, 0xaf, 0x70, 0xff, 0x0e, 0xb0, 0x70, 0xff, 0x0e, 0xaf, 0x6e, 0xff, 0x0d, 0xad, 0x6b, 0xff, 0x0c, 0xac, 0x69, 0xff, 0x0c, 0xab, 0x67, 0xff, 0x0d, 0xac, 0x66, 0xff, 0x0c, 0xaa, 0x67, 0xff, 0x0d, 0xaa, 0x67, 0xff, 0x0e, 0xaa, 0x68, 0xff, 0x10, 0xa9, 0x67, 0xff, 0x0f, 0xa8, 0x64, 0xff, 0x0d, 0xa8, 0x62, 0xff, 0x0e, 0xaa, 0x5f, 0xff, 0x0f, 0xaa, 0x5e, 0xff, 0x16, 0xaf, 0x61, 0xff, 0x12, 0xac, 0x5c, 0xff, 0x0e, 0xa8, 0x57, 0xff, 0x0c, 0xa6, 0x56, 0xff, 0x0b, 0xa5, 0x54, 0xff, 0x08, 0xa5, 0x54, 0xff, 0x09, 0xa6, 0x56, 0xff, 0x0e, 0xa9, 0x5c, 0xff, 0x0e, 0xaa, 0x5f, 0xff, 0x0d, 0xa9, 0x5f, 0xff, 0x0f, 0xa9, 0x62, 0xff, 0x11, 0xa9, 0x64, 0xff, 0x13, 0xab, 0x66, 0xff, 0x15, 0xad, 0x68, 0xff, 0x15, 0xac, 0x6a, 0xff, 0x14, 0xad, 0x6a, 0xff, 0x13, 0xaf, 0x6d, 0xff, 0x15, 0xb1, 0x70, 0xff, 0x17, 0xae, 0x70, 0xff, 0x18, 0xab, 0x6f, 0xff, 0x12, 0xa7, 0x6c, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0f, 0xa4, 0x6b, 0xff, 0x12, 0xa3, 0x6d, 0xff, 0x10, 0xa0, 0x6d, 0xff, 0x12, 0xa0, 0x6d, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x11, 0xa2, 0x6c, 0xff, 0x12, 0xa2, 0x6d, 0xff, 0x0f, 0x9f, 0x6b, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0e, 0xa0, 0x6c, 0xff, 0x0d, 0xa0, 0x6e, 0xff, 0x0b, 0xa0, 0x6e, 0xff, 0x0a, 0xa1, 0x6e, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x08, 0xa8, 0x6b, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x0b, 0xaa, 0x6f, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x71, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0a, 0xa5, 0x72, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x0a, 0xaa, 0x71, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xab, 0x70, 0xff, 0x0b, 0xab, 0x6c, 0xff, 0x0a, 0xaa, 0x69, 0xff, 0x0e, 0xac, 0x68, 0xff, 0x0f, 0xa9, 0x64, 0xff, 0x0e, 0xa6, 0x60, 0xff, 0x0b, 0xa5, 0x5d, 0xff, 0x05, 0xa5, 0x58, 0xff, 0x06, 0xa5, 0x5a, 0xff, 0x06, 0xa4, 0x5a, 0xff, 0x07, 0xa3, 0x5d, 0xff, 0x08, 0xa3, 0x60, 0xff, 0x0c, 0xa6, 0x67, 0xff, 0x10, 0xa9, 0x6c, 0xff, 0x10, 0xaa, 0x6e, 0xff, 0x19, 0xa9, 0x72, 0xff, 0x1f, 0xac, 0x77, 0xff, 0x1e, 0xab, 0x78, 0xff, 0x1f, 0xae, 0x7c, 0xff, 0x1e, 0xad, 0x7c, 0xff, 0x1d, 0xac, 0x7b, 0xff, 0x1a, 0xaa, 0x78, 0xff, 0x18, 0xaa, 0x77, 0xff, 0x14, 0xab, 0x78, 0xff, 0x10, 0xa9, 0x76, 0xff, 0x11, 0xa9, 0x75, 0xff, 0x12, 0xac, 0x77, 0xff, 0x10, 0xab, 0x75, 0xff, 0x0f, 0xa8, 0x73, 0xff, 0x11, 0xaa, 0x74, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x08, 0x9e, 0x62, 0xff, 0x06, 0x9c, 0x5b, 0xff, 0x0a, 0x9d, 0x5c, 0xff, 0x0a, 0x9a, 0x57, 0xff, 0x08, 0x96, 0x53, 0xff, 0x07, 0x97, 0x53, 0xff, 0x07, 0x99, 0x53, 0xff, 0x09, 0x9b, 0x53, 0xff, 0x09, 0x9b, 0x54, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x0b, 0x9c, 0x57, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x09, 0x9a, 0x55, 0xff, 0x08, 0x98, 0x53, 0xff, 0x08, 0x96, 0x52, 0xff, 0x08, 0x93, 0x4f, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x07, 0x91, 0x4d, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x0a, 0x91, 0x4b, 0xff, 0x05, 0x8c, 0x45, 0xff, 0x06, 0x88, 0x44, 0xff, 0x09, 0x85, 0x44, 0xff, 0x09, 0x84, 0x43, 0xff, 0x07, 0x82, 0x42, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x80, 0x40, 0xff, 0x08, 0x7f, 0x41, 0xff, 0x06, 0x7e, 0x42, 0xff, 0x09, 0x7d, 0x44, 0xff, 0x0b, 0x7a, 0x41, 0xff, 0x0b, 0x78, 0x3e, 0xff, 0x08, 0x6a, 0x40, 0xff, 0x09, 0x62, 0x40, 0xff, 0x0d, 0x4c, 0x50, 0xff, 0x23, 0x4d, 0x67, 0xff, 0x56, 0x70, 0x87, 0xff, 0x7c, 0x84, 0x8f, 0xff, 0x8d, 0x82, 0x92, 0xff, 0x90, 0x86, 0x9a, 0xff, 0x91, 0x91, 0xa0, 0xff, 0x87, 0x88, 0x96, 0xff, 0x8a, 0x86, 0x97, 0xff, 0x73, 0x79, 0x85, 0xff, 0x44, 0x6e, 0x66, 0xff, 0x36, 0x87, 0x60, 0xff, 0x3f, 0xba, 0x80, 0xff, 0x36, 0xc6, 0x78, 0xff, 0x35, 0xb6, 0x62, 0xff, 0x27, 0x9c, 0x50, 0xff, 0x15, 0xa3, 0x48, 0xff, 0x2a, 0xbc, 0x5c, 0xff, 0x02, 0x5e, 0x19, 0xff, 0x09, 0x5e, 0x24, 0xff, 0x1d, 0x76, 0x40, 0xff, 0x08, 0x55, 0x24, 0xff, 0x08, 0x5f, 0x29, 0xff, 0x23, 0x8b, 0x54, 0xff, 0x26, 0x99, 0x62, 0xff, 0x09, 0x68, 0x33, 0xff, 0x58, 0x82, 0x69, 0xff, + 0x10, 0x51, 0x3e, 0xff, 0x07, 0x51, 0x30, 0xff, 0x08, 0x6c, 0x3b, 0xff, 0x0f, 0x7e, 0x4a, 0xff, 0x0a, 0x69, 0x45, 0xff, 0x1a, 0x69, 0x63, 0xff, 0x0f, 0x63, 0x66, 0xff, 0x19, 0x7a, 0x69, 0xff, 0x19, 0x72, 0x4c, 0xff, 0x03, 0x4d, 0x25, 0xff, 0x10, 0x54, 0x40, 0xff, 0x3c, 0x86, 0x8b, 0xff, 0x49, 0xa1, 0xaa, 0xff, 0x53, 0xb9, 0xbd, 0xff, 0x4a, 0xb1, 0xbd, 0xff, 0x0a, 0x7e, 0x71, 0xff, 0x13, 0x9f, 0x60, 0xff, 0x39, 0xc6, 0x8f, 0xff, 0x1d, 0xa5, 0x79, 0xff, 0x1f, 0xb0, 0x6e, 0xff, 0x40, 0xd0, 0x8c, 0xff, 0x20, 0x9c, 0x71, 0xff, 0x0d, 0x82, 0x60, 0xff, 0x1f, 0x9c, 0x79, 0xff, 0x18, 0x9e, 0x71, 0xff, 0x08, 0x94, 0x60, 0xff, 0x12, 0xa2, 0x72, 0xff, 0x2f, 0xbe, 0x9b, 0xff, 0x4b, 0xd9, 0xb9, 0xff, 0x17, 0xa6, 0x84, 0xff, 0x06, 0x98, 0x6e, 0xff, 0x05, 0x9a, 0x68, 0xff, 0x01, 0x8f, 0x5e, 0xff, 0x0f, 0xa2, 0x71, 0xff, 0x17, 0xad, 0x7b, 0xff, 0x10, 0xaa, 0x75, 0xff, 0x13, 0xac, 0x79, 0xff, 0x38, 0xcc, 0xa0, 0xff, 0x32, 0xc1, 0x9b, 0xff, 0x10, 0x98, 0x80, 0xff, 0x12, 0x8f, 0x95, 0xff, 0x0b, 0x7d, 0xa1, 0xff, 0x0a, 0x7b, 0xa0, 0xff, 0x0a, 0x88, 0x8e, 0xff, 0x0d, 0x9a, 0x81, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0d, 0xab, 0x71, 0xff, 0x09, 0xaa, 0x70, 0xff, 0x0a, 0xac, 0x72, 0xff, 0x0d, 0xad, 0x73, 0xff, 0x0e, 0xae, 0x73, 0xff, 0x0c, 0xac, 0x70, 0xff, 0x0c, 0xac, 0x70, 0xff, 0x0a, 0xad, 0x6f, 0xff, 0x0a, 0xac, 0x70, 0xff, 0x0b, 0xaa, 0x73, 0xff, 0x08, 0xac, 0x72, 0xff, 0x03, 0xac, 0x6e, 0xff, 0x01, 0xae, 0x6e, 0xff, 0x02, 0xae, 0x6e, 0xff, 0x02, 0xad, 0x6d, 0xff, 0x06, 0xac, 0x6f, 0xff, 0x07, 0xab, 0x70, 0xff, 0x06, 0xac, 0x6e, 0xff, 0x08, 0xae, 0x73, 0xff, 0x0c, 0xb0, 0x76, 0xff, 0x0c, 0xac, 0x75, 0xff, 0x10, 0xab, 0x73, 0xff, 0x11, 0xac, 0x73, 0xff, 0x10, 0xa8, 0x6d, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x07, 0xa7, 0x66, 0xff, 0x06, 0xa6, 0x66, 0xff, 0x08, 0xa8, 0x6a, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0d, 0xa8, 0x6b, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x09, 0xa7, 0x65, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x0b, 0xaa, 0x6b, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xac, 0x6e, 0xff, 0x0e, 0xaf, 0x71, 0xff, 0x0f, 0xb2, 0x74, 0xff, 0x0d, 0xb3, 0x74, 0xff, 0x0e, 0xb4, 0x75, 0xff, 0x0e, 0xb4, 0x75, 0xff, 0x0d, 0xb3, 0x74, 0xff, 0x0e, 0xb1, 0x73, 0xff, 0x0f, 0xb2, 0x75, 0xff, 0x0f, 0xb2, 0x74, 0xff, 0x0e, 0xb2, 0x71, 0xff, 0x0d, 0xb1, 0x70, 0xff, 0x0d, 0xb2, 0x70, 0xff, 0x0e, 0xb2, 0x70, 0xff, 0x0e, 0xb1, 0x73, 0xff, 0x0f, 0xb2, 0x75, 0xff, 0x10, 0xb4, 0x79, 0xff, 0x14, 0xb8, 0x7e, 0xff, 0x16, 0xba, 0x80, 0xff, 0x14, 0xb8, 0x7e, 0xff, 0x15, 0xb8, 0x7e, 0xff, 0x16, 0xb9, 0x81, 0xff, 0x17, 0xb9, 0x81, 0xff, 0x15, 0xb7, 0x80, 0xff, 0x14, 0xb7, 0x7f, 0xff, 0x14, 0xb7, 0x7f, 0xff, 0x11, 0xb4, 0x7d, 0xff, 0x11, 0xb3, 0x7b, 0xff, 0x11, 0xb3, 0x7a, 0xff, 0x10, 0xb3, 0x78, 0xff, 0x0f, 0xb2, 0x74, 0xff, 0x0e, 0xb1, 0x71, 0xff, 0x0d, 0xad, 0x6d, 0xff, 0x0d, 0xad, 0x6b, 0xff, 0x0d, 0xac, 0x6a, 0xff, 0x0d, 0xac, 0x68, 0xff, 0x0d, 0xac, 0x65, 0xff, 0x0d, 0xac, 0x66, 0xff, 0x0d, 0xab, 0x65, 0xff, 0x0d, 0xab, 0x67, 0xff, 0x0e, 0xaa, 0x67, 0xff, 0x0f, 0xaa, 0x67, 0xff, 0x0d, 0xa8, 0x64, 0xff, 0x0b, 0xa7, 0x60, 0xff, 0x09, 0xa6, 0x5c, 0xff, 0x09, 0xa5, 0x59, 0xff, 0x0e, 0xa7, 0x58, 0xff, 0x0b, 0xa4, 0x54, 0xff, 0x0d, 0xa2, 0x56, 0xff, 0x0e, 0xa3, 0x57, 0xff, 0x0e, 0xa3, 0x57, 0xff, 0x0d, 0xa3, 0x57, 0xff, 0x0c, 0xa2, 0x57, 0xff, 0x10, 0xa6, 0x5c, 0xff, 0x11, 0xa9, 0x60, 0xff, 0x11, 0xa7, 0x61, 0xff, 0x11, 0xa9, 0x64, 0xff, 0x10, 0xab, 0x68, 0xff, 0x11, 0xac, 0x68, 0xff, 0x12, 0xad, 0x6a, 0xff, 0x13, 0xac, 0x6b, 0xff, 0x14, 0xae, 0x6e, 0xff, 0x11, 0xad, 0x6f, 0xff, 0x0e, 0xab, 0x6e, 0xff, 0x0f, 0xa6, 0x6b, 0xff, 0x14, 0xa6, 0x6b, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x0a, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x11, 0xa0, 0x6e, 0xff, 0x15, 0x9f, 0x6e, 0xff, 0x13, 0xa1, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x0f, 0x9e, 0x69, 0xff, 0x0c, 0x9b, 0x67, 0xff, 0x0b, 0x9c, 0x67, 0xff, 0x0a, 0x9d, 0x69, 0xff, 0x0d, 0x9e, 0x6b, 0xff, 0x0c, 0x9f, 0x6c, 0xff, 0x09, 0x9f, 0x6c, 0xff, 0x0a, 0xa2, 0x6c, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x09, 0xa7, 0x6c, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x07, 0xa6, 0x6b, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0c, 0xaa, 0x71, 0xff, 0x0a, 0xaa, 0x70, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x09, 0xa6, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0d, 0xa8, 0x73, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0e, 0xa5, 0x73, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x0b, 0xa2, 0x71, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x0b, 0xa2, 0x6d, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x10, 0xa6, 0x6e, 0xff, 0x0c, 0xa8, 0x6d, 0xff, 0x09, 0xa7, 0x68, 0xff, 0x09, 0xa8, 0x67, 0xff, 0x0d, 0xab, 0x67, 0xff, 0x0e, 0xa7, 0x62, 0xff, 0x0c, 0xa4, 0x60, 0xff, 0x0b, 0xa4, 0x5e, 0xff, 0x0b, 0xa2, 0x56, 0xff, 0x0b, 0xa1, 0x56, 0xff, 0x0b, 0xa2, 0x57, 0xff, 0x0b, 0xa3, 0x5c, 0xff, 0x0a, 0xa1, 0x5e, 0xff, 0x09, 0xa2, 0x60, 0xff, 0x09, 0xa3, 0x63, 0xff, 0x07, 0xa3, 0x64, 0xff, 0x0c, 0xa4, 0x6a, 0xff, 0x11, 0xa9, 0x71, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x0e, 0xa5, 0x6f, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x13, 0xaa, 0x74, 0xff, 0x12, 0xaa, 0x74, 0xff, 0x12, 0xa9, 0x73, 0xff, 0x14, 0xaa, 0x75, 0xff, 0x11, 0xaa, 0x74, 0xff, 0x10, 0xaa, 0x74, 0xff, 0x10, 0xab, 0x74, 0xff, 0x0f, 0xaa, 0x73, 0xff, 0x0e, 0xa8, 0x72, 0xff, 0x10, 0xa9, 0x72, 0xff, 0x0e, 0xa9, 0x70, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x08, 0x9e, 0x60, 0xff, 0x04, 0x9a, 0x5a, 0xff, 0x06, 0x9a, 0x59, 0xff, 0x07, 0x9a, 0x57, 0xff, 0x08, 0x95, 0x52, 0xff, 0x0d, 0x94, 0x51, 0xff, 0x0f, 0x94, 0x54, 0xff, 0x09, 0x97, 0x53, 0xff, 0x07, 0x9a, 0x54, 0xff, 0x07, 0x9b, 0x55, 0xff, 0x09, 0x9c, 0x56, 0xff, 0x07, 0x9b, 0x55, 0xff, 0x09, 0x9b, 0x56, 0xff, 0x0a, 0x9a, 0x55, 0xff, 0x08, 0x97, 0x52, 0xff, 0x08, 0x95, 0x50, 0xff, 0x07, 0x92, 0x4e, 0xff, 0x05, 0x90, 0x4c, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x07, 0x91, 0x4d, 0xff, 0x0a, 0x91, 0x4c, 0xff, 0x0a, 0x8f, 0x49, 0xff, 0x05, 0x8a, 0x44, 0xff, 0x08, 0x88, 0x45, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x09, 0x83, 0x43, 0xff, 0x09, 0x81, 0x41, 0xff, 0x08, 0x80, 0x40, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x05, 0x7e, 0x41, 0xff, 0x09, 0x7e, 0x42, 0xff, 0x0a, 0x7d, 0x3b, 0xff, 0x0c, 0x79, 0x39, 0xff, 0x09, 0x69, 0x42, 0xff, 0x09, 0x61, 0x40, 0xff, 0x0a, 0x4f, 0x41, 0xff, 0x14, 0x48, 0x4c, 0xff, 0x36, 0x5a, 0x65, 0xff, 0x5a, 0x6f, 0x77, 0xff, 0x81, 0x84, 0x91, 0xff, 0x86, 0x82, 0x96, 0xff, 0x8e, 0x8b, 0x9e, 0xff, 0x91, 0x8e, 0x9f, 0xff, 0x7e, 0x7a, 0x8c, 0xff, 0x59, 0x6b, 0x74, 0xff, 0x28, 0x75, 0x60, 0xff, 0x3a, 0xb5, 0x81, 0xff, 0x3b, 0xc9, 0x8b, 0xff, 0x2e, 0xbd, 0x72, 0xff, 0x34, 0xbd, 0x69, 0xff, 0x31, 0xb6, 0x6e, 0xff, 0x11, 0xa4, 0x53, 0xff, 0x20, 0xae, 0x53, 0xff, 0x09, 0x67, 0x25, 0xff, 0x03, 0x4f, 0x17, 0xff, 0x1c, 0x74, 0x3b, 0xff, 0x27, 0x88, 0x50, 0xff, 0x28, 0x98, 0x58, 0xff, 0x14, 0x7b, 0x45, 0xff, 0x05, 0x61, 0x31, 0xff, 0x03, 0x5b, 0x26, 0xff, 0x6d, 0x95, 0x77, 0xff, + 0x04, 0x50, 0x32, 0xff, 0x05, 0x62, 0x36, 0xff, 0x13, 0x85, 0x52, 0xff, 0x04, 0x67, 0x37, 0xff, 0x13, 0x74, 0x4f, 0xff, 0x0a, 0x6f, 0x53, 0xff, 0x04, 0x70, 0x50, 0xff, 0x18, 0x86, 0x57, 0xff, 0x06, 0x5d, 0x2c, 0xff, 0x05, 0x4e, 0x2f, 0xff, 0x1a, 0x66, 0x5e, 0xff, 0x46, 0xa6, 0xa6, 0xff, 0x37, 0xa9, 0xa0, 0xff, 0x21, 0x9f, 0x88, 0xff, 0x41, 0xb1, 0xad, 0xff, 0x16, 0x82, 0x7a, 0xff, 0x11, 0x9c, 0x61, 0xff, 0x1d, 0xab, 0x6f, 0xff, 0x07, 0x88, 0x58, 0xff, 0x0f, 0x97, 0x61, 0xff, 0x32, 0xbf, 0x87, 0xff, 0x0d, 0x92, 0x5f, 0xff, 0x05, 0x85, 0x56, 0xff, 0x22, 0xa5, 0x7c, 0xff, 0x1f, 0xa6, 0x77, 0xff, 0x24, 0xaf, 0x7c, 0xff, 0x18, 0xa3, 0x75, 0xff, 0x27, 0xaf, 0x8a, 0xff, 0x45, 0xc9, 0xaa, 0xff, 0x1b, 0x9d, 0x80, 0xff, 0x19, 0x9e, 0x7d, 0xff, 0x10, 0xa0, 0x73, 0xff, 0x04, 0x92, 0x63, 0xff, 0x22, 0xb4, 0x80, 0xff, 0x2a, 0xbf, 0x89, 0xff, 0x1e, 0xb4, 0x7d, 0xff, 0x0c, 0x9d, 0x6c, 0xff, 0x39, 0xbf, 0x9c, 0xff, 0x2d, 0xac, 0x97, 0xff, 0x12, 0x86, 0x96, 0xff, 0x2c, 0x90, 0xca, 0xff, 0x30, 0x85, 0xe2, 0xff, 0x32, 0x89, 0xe2, 0xff, 0x25, 0x89, 0xc6, 0xff, 0x0b, 0x7f, 0x9a, 0xff, 0x11, 0x9e, 0x82, 0xff, 0x0d, 0xa8, 0x70, 0xff, 0x06, 0xa8, 0x70, 0xff, 0x07, 0xa9, 0x71, 0xff, 0x0a, 0xab, 0x72, 0xff, 0x0b, 0xab, 0x72, 0xff, 0x09, 0xa9, 0x6e, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x07, 0xaa, 0x6f, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x05, 0xac, 0x74, 0xff, 0x04, 0xaf, 0x73, 0xff, 0x01, 0xae, 0x6f, 0xff, 0x00, 0xaf, 0x6d, 0xff, 0x00, 0xaf, 0x6d, 0xff, 0x01, 0xae, 0x6c, 0xff, 0x03, 0xad, 0x6f, 0xff, 0x04, 0xad, 0x70, 0xff, 0x04, 0xad, 0x71, 0xff, 0x06, 0xaf, 0x74, 0xff, 0x0a, 0xb1, 0x77, 0xff, 0x0c, 0xb2, 0x78, 0xff, 0x0f, 0xb1, 0x77, 0xff, 0x0f, 0xb0, 0x75, 0xff, 0x0d, 0xaa, 0x6e, 0xff, 0x0a, 0xa8, 0x69, 0xff, 0x02, 0xa9, 0x66, 0xff, 0x02, 0xa9, 0x66, 0xff, 0x04, 0xa8, 0x69, 0xff, 0x05, 0xa7, 0x6a, 0xff, 0x07, 0xa7, 0x6a, 0xff, 0x0c, 0xaa, 0x6c, 0xff, 0x0b, 0xa9, 0x6a, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0b, 0xab, 0x6c, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0b, 0xaa, 0x6c, 0xff, 0x0c, 0xad, 0x6f, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x0f, 0xb2, 0x74, 0xff, 0x0e, 0xb2, 0x73, 0xff, 0x0d, 0xb1, 0x73, 0xff, 0x0d, 0xb0, 0x72, 0xff, 0x0d, 0xae, 0x70, 0xff, 0x0d, 0xad, 0x6f, 0xff, 0x0e, 0xaf, 0x72, 0xff, 0x0d, 0xaf, 0x71, 0xff, 0x0c, 0xaf, 0x6e, 0xff, 0x0c, 0xb0, 0x6d, 0xff, 0x0d, 0xb1, 0x6d, 0xff, 0x0e, 0xb1, 0x6f, 0xff, 0x10, 0xb2, 0x73, 0xff, 0x11, 0xb2, 0x75, 0xff, 0x10, 0xb3, 0x76, 0xff, 0x13, 0xb5, 0x79, 0xff, 0x15, 0xb7, 0x7c, 0xff, 0x15, 0xb7, 0x7b, 0xff, 0x16, 0xb8, 0x7c, 0xff, 0x18, 0xb9, 0x7f, 0xff, 0x16, 0xb6, 0x7d, 0xff, 0x13, 0xb5, 0x7b, 0xff, 0x13, 0xb6, 0x7d, 0xff, 0x13, 0xb6, 0x7c, 0xff, 0x12, 0xb4, 0x7b, 0xff, 0x12, 0xb3, 0x79, 0xff, 0x14, 0xb4, 0x78, 0xff, 0x12, 0xb3, 0x75, 0xff, 0x10, 0xb3, 0x72, 0xff, 0x0e, 0xb0, 0x6f, 0xff, 0x0c, 0xad, 0x69, 0xff, 0x0d, 0xac, 0x69, 0xff, 0x0d, 0xac, 0x68, 0xff, 0x0d, 0xac, 0x66, 0xff, 0x0e, 0xac, 0x66, 0xff, 0x0e, 0xac, 0x66, 0xff, 0x0e, 0xac, 0x66, 0xff, 0x0e, 0xac, 0x66, 0xff, 0x0c, 0xaa, 0x65, 0xff, 0x0c, 0xaa, 0x65, 0xff, 0x0d, 0xa9, 0x62, 0xff, 0x0c, 0xa6, 0x5f, 0xff, 0x0c, 0xa5, 0x5a, 0xff, 0x0c, 0xa5, 0x59, 0xff, 0x0b, 0xa4, 0x56, 0xff, 0x0a, 0xa4, 0x55, 0xff, 0x10, 0xa0, 0x56, 0xff, 0x12, 0x9f, 0x56, 0xff, 0x11, 0x9f, 0x57, 0xff, 0x0f, 0xa0, 0x57, 0xff, 0x0a, 0xa1, 0x56, 0xff, 0x0b, 0xa2, 0x58, 0xff, 0x08, 0xa2, 0x5a, 0xff, 0x06, 0xa2, 0x5a, 0xff, 0x08, 0xa4, 0x5d, 0xff, 0x0a, 0xa4, 0x5f, 0xff, 0x0b, 0xa4, 0x5f, 0xff, 0x0d, 0xa5, 0x61, 0xff, 0x0f, 0xa5, 0x64, 0xff, 0x0f, 0xa6, 0x68, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x07, 0xa5, 0x6a, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0b, 0xa2, 0x6b, 0xff, 0x0b, 0xa0, 0x6b, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0e, 0x9e, 0x6b, 0xff, 0x0c, 0x9e, 0x69, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0a, 0x9c, 0x67, 0xff, 0x08, 0x9d, 0x67, 0xff, 0x0a, 0x9d, 0x68, 0xff, 0x0e, 0x9d, 0x69, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x0b, 0x9f, 0x6b, 0xff, 0x0b, 0xa2, 0x6c, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x07, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x07, 0xa2, 0x6c, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa4, 0x72, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x73, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0x9e, 0x69, 0xff, 0x09, 0x9e, 0x68, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0b, 0xaa, 0x6d, 0xff, 0x09, 0xa9, 0x6a, 0xff, 0x0a, 0xa8, 0x67, 0xff, 0x10, 0xa8, 0x67, 0xff, 0x10, 0xa7, 0x66, 0xff, 0x0d, 0xa6, 0x64, 0xff, 0x07, 0xa4, 0x61, 0xff, 0x08, 0xa3, 0x5d, 0xff, 0x0a, 0xa3, 0x5e, 0xff, 0x0b, 0xa4, 0x61, 0xff, 0x0c, 0xa5, 0x62, 0xff, 0x0e, 0xa7, 0x64, 0xff, 0x0f, 0xa7, 0x67, 0xff, 0x10, 0xa7, 0x67, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0f, 0xa9, 0x71, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x13, 0xad, 0x74, 0xff, 0x12, 0xaa, 0x73, 0xff, 0x11, 0xab, 0x74, 0xff, 0x10, 0xab, 0x74, 0xff, 0x0f, 0xab, 0x73, 0xff, 0x0f, 0xaa, 0x72, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x11, 0xa9, 0x71, 0xff, 0x0a, 0xa3, 0x6a, 0xff, 0x07, 0x9f, 0x61, 0xff, 0x05, 0x9a, 0x5a, 0xff, 0x05, 0x98, 0x57, 0xff, 0x05, 0x96, 0x54, 0xff, 0x06, 0x95, 0x52, 0xff, 0x07, 0x94, 0x53, 0xff, 0x0b, 0x93, 0x52, 0xff, 0x10, 0x95, 0x56, 0xff, 0x0b, 0x99, 0x56, 0xff, 0x08, 0x9b, 0x57, 0xff, 0x07, 0x9b, 0x58, 0xff, 0x07, 0x9c, 0x57, 0xff, 0x08, 0x9b, 0x57, 0xff, 0x0b, 0x9b, 0x56, 0xff, 0x0b, 0x99, 0x54, 0xff, 0x07, 0x94, 0x50, 0xff, 0x08, 0x93, 0x4f, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x05, 0x90, 0x4c, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x08, 0x93, 0x4f, 0xff, 0x09, 0x90, 0x4a, 0xff, 0x08, 0x8d, 0x47, 0xff, 0x07, 0x8a, 0x44, 0xff, 0x09, 0x87, 0x46, 0xff, 0x0a, 0x85, 0x45, 0xff, 0x08, 0x83, 0x43, 0xff, 0x08, 0x80, 0x40, 0xff, 0x07, 0x7f, 0x40, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x06, 0x7e, 0x41, 0xff, 0x05, 0x7d, 0x40, 0xff, 0x08, 0x7d, 0x41, 0xff, 0x0a, 0x7c, 0x39, 0xff, 0x0c, 0x7a, 0x36, 0xff, 0x0c, 0x69, 0x43, 0xff, 0x0a, 0x61, 0x3e, 0xff, 0x09, 0x54, 0x3b, 0xff, 0x0f, 0x4c, 0x41, 0xff, 0x1a, 0x48, 0x48, 0xff, 0x26, 0x51, 0x54, 0xff, 0x49, 0x61, 0x6d, 0xff, 0x6c, 0x73, 0x86, 0xff, 0x76, 0x7c, 0x8d, 0xff, 0x7a, 0x7d, 0x8e, 0xff, 0x6b, 0x6f, 0x83, 0xff, 0x44, 0x63, 0x6f, 0xff, 0x31, 0x91, 0x82, 0xff, 0x3d, 0xcf, 0x99, 0xff, 0x19, 0xb2, 0x6b, 0xff, 0x13, 0x9e, 0x54, 0xff, 0x17, 0x9f, 0x4d, 0xff, 0x27, 0xb7, 0x69, 0xff, 0x0f, 0xa5, 0x53, 0xff, 0x0a, 0x99, 0x3c, 0xff, 0x0d, 0x82, 0x33, 0xff, 0x00, 0x50, 0x15, 0xff, 0x0e, 0x72, 0x37, 0xff, 0x3a, 0xbf, 0x7a, 0xff, 0x2e, 0xb1, 0x63, 0xff, 0x07, 0x68, 0x2e, 0xff, 0x06, 0x56, 0x29, 0xff, 0x03, 0x55, 0x1e, 0xff, 0x69, 0x8e, 0x70, 0xff, + 0x03, 0x56, 0x2b, 0xff, 0x0d, 0x7a, 0x44, 0xff, 0x1b, 0x87, 0x58, 0xff, 0x03, 0x51, 0x30, 0xff, 0x0e, 0x66, 0x43, 0xff, 0x06, 0x75, 0x42, 0xff, 0x14, 0x89, 0x4f, 0xff, 0x0a, 0x6e, 0x34, 0xff, 0x07, 0x54, 0x25, 0xff, 0x0e, 0x55, 0x3d, 0xff, 0x31, 0x89, 0x7e, 0xff, 0x2e, 0xa7, 0x96, 0xff, 0x11, 0x9b, 0x7b, 0xff, 0x1e, 0xa4, 0x82, 0xff, 0x60, 0xcf, 0xc8, 0xff, 0x18, 0x7c, 0x83, 0xff, 0x0b, 0x90, 0x6a, 0xff, 0x02, 0x8b, 0x53, 0xff, 0x03, 0x85, 0x53, 0xff, 0x05, 0x86, 0x58, 0xff, 0x04, 0x8c, 0x5e, 0xff, 0x04, 0x91, 0x5b, 0xff, 0x04, 0x93, 0x5b, 0xff, 0x0d, 0x97, 0x66, 0xff, 0x32, 0xbd, 0x8d, 0xff, 0x23, 0xac, 0x7c, 0xff, 0x13, 0x9a, 0x6c, 0xff, 0x11, 0x91, 0x68, 0xff, 0x1c, 0x95, 0x73, 0xff, 0x45, 0xb6, 0x9f, 0xff, 0x4b, 0xc2, 0xa9, 0xff, 0x25, 0xae, 0x88, 0xff, 0x0d, 0x97, 0x6d, 0xff, 0x35, 0xc4, 0x91, 0xff, 0x2e, 0xc0, 0x88, 0xff, 0x1b, 0xab, 0x75, 0xff, 0x0b, 0x93, 0x67, 0xff, 0x18, 0x91, 0x75, 0xff, 0x25, 0x91, 0x94, 0xff, 0x19, 0x72, 0xbf, 0xff, 0x2c, 0x78, 0xe8, 0xff, 0x2a, 0x6e, 0xe8, 0xff, 0x2e, 0x77, 0xe7, 0xff, 0x3b, 0x8c, 0xf4, 0xff, 0x22, 0x7e, 0xd3, 0xff, 0x0c, 0x89, 0x91, 0xff, 0x10, 0xa6, 0x78, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x06, 0xa8, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa9, 0x70, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x04, 0xa9, 0x6f, 0xff, 0x02, 0xab, 0x73, 0xff, 0x03, 0xae, 0x72, 0xff, 0x01, 0xae, 0x6e, 0xff, 0x02, 0xaf, 0x6b, 0xff, 0x02, 0xaf, 0x6c, 0xff, 0x01, 0xae, 0x6b, 0xff, 0x01, 0xae, 0x6e, 0xff, 0x02, 0xad, 0x6f, 0xff, 0x06, 0xaf, 0x73, 0xff, 0x05, 0xaf, 0x74, 0xff, 0x08, 0xb3, 0x77, 0xff, 0x0a, 0xb4, 0x78, 0xff, 0x0b, 0xb1, 0x74, 0xff, 0x09, 0xaf, 0x70, 0xff, 0x09, 0xab, 0x6a, 0xff, 0x07, 0xa9, 0x67, 0xff, 0x07, 0xa9, 0x67, 0xff, 0x07, 0xa9, 0x66, 0xff, 0x08, 0xa9, 0x68, 0xff, 0x08, 0xa8, 0x69, 0xff, 0x08, 0xa7, 0x69, 0xff, 0x0c, 0xab, 0x6b, 0xff, 0x0c, 0xac, 0x6a, 0xff, 0x09, 0xa9, 0x67, 0xff, 0x0b, 0xa8, 0x66, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x09, 0xa8, 0x6a, 0xff, 0x0c, 0xab, 0x6e, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0c, 0xab, 0x6d, 0xff, 0x0d, 0xab, 0x6e, 0xff, 0x0e, 0xaf, 0x71, 0xff, 0x10, 0xb1, 0x73, 0xff, 0x0f, 0xb2, 0x74, 0xff, 0x0e, 0xb1, 0x73, 0xff, 0x0b, 0xae, 0x70, 0xff, 0x0c, 0xad, 0x6f, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0d, 0xac, 0x70, 0xff, 0x0c, 0xae, 0x6f, 0xff, 0x0a, 0xac, 0x6b, 0xff, 0x0c, 0xae, 0x6b, 0xff, 0x0e, 0xb0, 0x6d, 0xff, 0x0e, 0xb0, 0x6e, 0xff, 0x10, 0xb2, 0x72, 0xff, 0x11, 0xb1, 0x74, 0xff, 0x11, 0xb2, 0x74, 0xff, 0x12, 0xb3, 0x75, 0xff, 0x13, 0xb2, 0x76, 0xff, 0x15, 0xb5, 0x78, 0xff, 0x17, 0xb7, 0x7b, 0xff, 0x17, 0xb8, 0x7d, 0xff, 0x14, 0xb4, 0x7a, 0xff, 0x14, 0xb4, 0x7a, 0xff, 0x14, 0xb6, 0x7c, 0xff, 0x13, 0xb4, 0x7a, 0xff, 0x11, 0xb4, 0x79, 0xff, 0x12, 0xb3, 0x78, 0xff, 0x12, 0xb2, 0x76, 0xff, 0x10, 0xb1, 0x71, 0xff, 0x0d, 0xae, 0x6c, 0xff, 0x0b, 0xad, 0x6a, 0xff, 0x0c, 0xab, 0x68, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x0d, 0xac, 0x67, 0xff, 0x0e, 0xac, 0x65, 0xff, 0x0e, 0xac, 0x65, 0xff, 0x0e, 0xac, 0x65, 0xff, 0x0e, 0xac, 0x66, 0xff, 0x0d, 0xac, 0x66, 0xff, 0x0d, 0xaa, 0x63, 0xff, 0x0e, 0xaa, 0x62, 0xff, 0x0e, 0xa8, 0x5f, 0xff, 0x0e, 0xa6, 0x5d, 0xff, 0x0e, 0xa4, 0x59, 0xff, 0x0e, 0xa5, 0x59, 0xff, 0x0c, 0xa3, 0x55, 0xff, 0x0b, 0xa2, 0x54, 0xff, 0x0e, 0xa0, 0x55, 0xff, 0x0e, 0xa0, 0x55, 0xff, 0x0e, 0xa0, 0x55, 0xff, 0x0c, 0xa1, 0x54, 0xff, 0x0a, 0xa2, 0x53, 0xff, 0x08, 0xa2, 0x53, 0xff, 0x07, 0xa2, 0x55, 0xff, 0x07, 0xa3, 0x56, 0xff, 0x06, 0xa4, 0x57, 0xff, 0x09, 0xa4, 0x58, 0xff, 0x0b, 0xa4, 0x58, 0xff, 0x0c, 0xa4, 0x59, 0xff, 0x0c, 0xa2, 0x5c, 0xff, 0x0e, 0xa3, 0x60, 0xff, 0x0f, 0xa3, 0x66, 0xff, 0x0e, 0xa2, 0x68, 0xff, 0x06, 0xa1, 0x66, 0xff, 0x06, 0xa3, 0x67, 0xff, 0x0b, 0xa1, 0x66, 0xff, 0x0f, 0xa0, 0x67, 0xff, 0x0f, 0x9f, 0x69, 0xff, 0x0d, 0x9f, 0x6a, 0xff, 0x0a, 0x9d, 0x69, 0xff, 0x09, 0x9e, 0x68, 0xff, 0x09, 0x9b, 0x67, 0xff, 0x0a, 0x9b, 0x65, 0xff, 0x0e, 0x9b, 0x66, 0xff, 0x0e, 0x9c, 0x67, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x0f, 0x9d, 0x68, 0xff, 0x11, 0x9e, 0x69, 0xff, 0x0e, 0x9f, 0x6b, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa6, 0x6d, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x08, 0xa9, 0x70, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x10, 0xa5, 0x73, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0f, 0xa4, 0x73, 0xff, 0x10, 0xa4, 0x76, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0b, 0x9e, 0x6a, 0xff, 0x07, 0x9a, 0x64, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0b, 0xa9, 0x6a, 0xff, 0x07, 0xaa, 0x68, 0xff, 0x0c, 0xaa, 0x6a, 0xff, 0x12, 0xaa, 0x69, 0xff, 0x13, 0xaa, 0x6c, 0xff, 0x0f, 0xaa, 0x6b, 0xff, 0x07, 0xa8, 0x6a, 0xff, 0x09, 0xa7, 0x69, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0c, 0xaa, 0x6e, 0xff, 0x0c, 0xa8, 0x6d, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0f, 0xa9, 0x6e, 0xff, 0x11, 0xaa, 0x6f, 0xff, 0x0e, 0xa7, 0x6e, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0a, 0xa5, 0x70, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x12, 0xaa, 0x73, 0xff, 0x11, 0xaa, 0x73, 0xff, 0x10, 0xaa, 0x73, 0xff, 0x10, 0xab, 0x73, 0xff, 0x10, 0xab, 0x72, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x10, 0xa9, 0x71, 0xff, 0x10, 0xa7, 0x6e, 0xff, 0x09, 0x9e, 0x64, 0xff, 0x07, 0x9b, 0x5c, 0xff, 0x09, 0x9b, 0x59, 0xff, 0x0a, 0x97, 0x56, 0xff, 0x08, 0x94, 0x51, 0xff, 0x06, 0x94, 0x51, 0xff, 0x03, 0x93, 0x52, 0xff, 0x02, 0x92, 0x51, 0xff, 0x0c, 0x9c, 0x5d, 0xff, 0x0b, 0x9d, 0x5d, 0xff, 0x08, 0x9a, 0x59, 0xff, 0x07, 0x9c, 0x5a, 0xff, 0x07, 0x9c, 0x59, 0xff, 0x08, 0x9c, 0x58, 0xff, 0x0a, 0x9a, 0x55, 0xff, 0x09, 0x97, 0x52, 0xff, 0x07, 0x92, 0x4e, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x05, 0x90, 0x4d, 0xff, 0x05, 0x90, 0x4c, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x08, 0x92, 0x4e, 0xff, 0x09, 0x8f, 0x49, 0xff, 0x07, 0x8b, 0x45, 0xff, 0x09, 0x89, 0x44, 0xff, 0x0a, 0x86, 0x45, 0xff, 0x09, 0x84, 0x44, 0xff, 0x07, 0x82, 0x42, 0xff, 0x07, 0x7f, 0x3f, 0xff, 0x07, 0x7f, 0x41, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x06, 0x7e, 0x41, 0xff, 0x04, 0x7d, 0x40, 0xff, 0x05, 0x7a, 0x43, 0xff, 0x09, 0x7a, 0x3d, 0xff, 0x0c, 0x78, 0x39, 0xff, 0x0d, 0x69, 0x43, 0xff, 0x08, 0x5f, 0x3b, 0xff, 0x06, 0x54, 0x37, 0xff, 0x0a, 0x50, 0x3b, 0xff, 0x0f, 0x4c, 0x3e, 0xff, 0x0b, 0x4a, 0x41, 0xff, 0x1c, 0x4a, 0x4e, 0xff, 0x33, 0x51, 0x5a, 0xff, 0x43, 0x66, 0x6a, 0xff, 0x48, 0x6e, 0x74, 0xff, 0x41, 0x5e, 0x70, 0xff, 0x3a, 0x65, 0x78, 0xff, 0x28, 0x84, 0x84, 0xff, 0x3a, 0xc7, 0x9a, 0xff, 0x24, 0xc3, 0x76, 0xff, 0x25, 0xb9, 0x6d, 0xff, 0x18, 0xab, 0x57, 0xff, 0x2b, 0xc5, 0x6a, 0xff, 0x0b, 0xa1, 0x45, 0xff, 0x02, 0x95, 0x33, 0xff, 0x14, 0x90, 0x38, 0xff, 0x02, 0x59, 0x1a, 0xff, 0x1c, 0x9a, 0x5c, 0xff, 0x24, 0xc3, 0x72, 0xff, 0x0e, 0x99, 0x3d, 0xff, 0x0f, 0x71, 0x2e, 0xff, 0x05, 0x4f, 0x21, 0xff, 0x03, 0x54, 0x1e, 0xff, 0x64, 0x89, 0x6c, 0xff, + 0x02, 0x59, 0x26, 0xff, 0x19, 0x8f, 0x54, 0xff, 0x10, 0x6b, 0x43, 0xff, 0x07, 0x4a, 0x34, 0xff, 0x05, 0x50, 0x30, 0xff, 0x0d, 0x7a, 0x3c, 0xff, 0x1b, 0x89, 0x4b, 0xff, 0x02, 0x4f, 0x1f, 0xff, 0x0e, 0x58, 0x29, 0xff, 0x1d, 0x6d, 0x4e, 0xff, 0x2d, 0x96, 0x7c, 0xff, 0x11, 0x9e, 0x77, 0xff, 0x0a, 0x9e, 0x71, 0xff, 0x31, 0xb1, 0x96, 0xff, 0x7a, 0xe0, 0xe5, 0xff, 0x2f, 0x8c, 0xa0, 0xff, 0x05, 0x7c, 0x6f, 0xff, 0x06, 0x93, 0x61, 0xff, 0x0d, 0x99, 0x62, 0xff, 0x11, 0x98, 0x6a, 0xff, 0x0d, 0x99, 0x6c, 0xff, 0x0e, 0xa0, 0x69, 0xff, 0x0c, 0x9f, 0x65, 0xff, 0x12, 0x9e, 0x67, 0xff, 0x14, 0x98, 0x69, 0xff, 0x0b, 0x8d, 0x60, 0xff, 0x0b, 0x92, 0x61, 0xff, 0x25, 0xa6, 0x74, 0xff, 0x1b, 0x96, 0x6a, 0xff, 0x3b, 0xa9, 0x90, 0xff, 0x4f, 0xbf, 0xaa, 0xff, 0x1f, 0xa6, 0x80, 0xff, 0x06, 0x8e, 0x60, 0xff, 0x1d, 0xaa, 0x75, 0xff, 0x10, 0x9e, 0x68, 0xff, 0x07, 0x94, 0x61, 0xff, 0x11, 0x96, 0x69, 0xff, 0x25, 0x92, 0x89, 0xff, 0x23, 0x7c, 0xa6, 0xff, 0x19, 0x5e, 0xdb, 0xff, 0x18, 0x57, 0xe3, 0xff, 0x2e, 0x72, 0xec, 0xff, 0x49, 0x92, 0xf5, 0xff, 0x26, 0x70, 0xea, 0xff, 0x36, 0x84, 0xf7, 0xff, 0x0e, 0x7a, 0xac, 0xff, 0x09, 0x93, 0x83, 0xff, 0x04, 0xa7, 0x71, 0xff, 0x06, 0xa8, 0x72, 0xff, 0x08, 0xa8, 0x71, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x08, 0xa8, 0x71, 0xff, 0x08, 0xa8, 0x71, 0xff, 0x07, 0xa9, 0x6e, 0xff, 0x05, 0xaa, 0x71, 0xff, 0x07, 0xad, 0x71, 0xff, 0x06, 0xae, 0x6e, 0xff, 0x05, 0xaf, 0x6c, 0xff, 0x04, 0xaf, 0x6a, 0xff, 0x03, 0xae, 0x6a, 0xff, 0x02, 0xae, 0x6c, 0xff, 0x04, 0xae, 0x6e, 0xff, 0x09, 0xaf, 0x72, 0xff, 0x0a, 0xb1, 0x74, 0xff, 0x0c, 0xb3, 0x76, 0xff, 0x0c, 0xb2, 0x75, 0xff, 0x0d, 0xb1, 0x73, 0xff, 0x09, 0xac, 0x6c, 0xff, 0x09, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0d, 0xa8, 0x67, 0xff, 0x0c, 0xa8, 0x67, 0xff, 0x0c, 0xa7, 0x68, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0a, 0xa7, 0x67, 0xff, 0x0c, 0xab, 0x6b, 0xff, 0x0d, 0xae, 0x6c, 0xff, 0x09, 0xaa, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa8, 0x66, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0a, 0xa9, 0x67, 0xff, 0x0c, 0xaa, 0x6c, 0xff, 0x10, 0xad, 0x70, 0xff, 0x0b, 0xa8, 0x6b, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0c, 0xaa, 0x6e, 0xff, 0x0c, 0xaa, 0x6e, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x10, 0xae, 0x72, 0xff, 0x10, 0xaf, 0x72, 0xff, 0x0e, 0xaf, 0x71, 0xff, 0x0d, 0xae, 0x71, 0xff, 0x0c, 0xae, 0x70, 0xff, 0x0c, 0xac, 0x6e, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0e, 0xac, 0x6e, 0xff, 0x0f, 0xac, 0x6f, 0xff, 0x0d, 0xab, 0x6e, 0xff, 0x0c, 0xac, 0x6d, 0xff, 0x0b, 0xab, 0x69, 0xff, 0x0d, 0xac, 0x69, 0xff, 0x0c, 0xab, 0x67, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x11, 0xb0, 0x6e, 0xff, 0x12, 0xb1, 0x70, 0xff, 0x12, 0xb2, 0x70, 0xff, 0x10, 0xb0, 0x70, 0xff, 0x10, 0xb0, 0x71, 0xff, 0x12, 0xb2, 0x74, 0xff, 0x15, 0xb5, 0x78, 0xff, 0x16, 0xb6, 0x7a, 0xff, 0x14, 0xb4, 0x77, 0xff, 0x15, 0xb5, 0x78, 0xff, 0x17, 0xb7, 0x7b, 0xff, 0x14, 0xb3, 0x77, 0xff, 0x12, 0xb2, 0x76, 0xff, 0x13, 0xb2, 0x76, 0xff, 0x13, 0xb3, 0x74, 0xff, 0x10, 0xaf, 0x6e, 0xff, 0x0c, 0xac, 0x69, 0xff, 0x0c, 0xac, 0x67, 0xff, 0x0c, 0xab, 0x67, 0xff, 0x0d, 0xab, 0x66, 0xff, 0x0d, 0xab, 0x65, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x0d, 0xaa, 0x64, 0xff, 0x0e, 0xaa, 0x64, 0xff, 0x11, 0xa8, 0x61, 0xff, 0x11, 0xa8, 0x5e, 0xff, 0x0f, 0xa7, 0x5c, 0xff, 0x0d, 0xa6, 0x5b, 0xff, 0x0c, 0xa5, 0x59, 0xff, 0x0f, 0xa7, 0x59, 0xff, 0x0f, 0xa4, 0x56, 0xff, 0x10, 0xa3, 0x54, 0xff, 0x07, 0xa0, 0x52, 0xff, 0x04, 0xa2, 0x51, 0xff, 0x06, 0xa3, 0x51, 0xff, 0x08, 0xa3, 0x50, 0xff, 0x09, 0xa3, 0x50, 0xff, 0x0b, 0xa3, 0x50, 0xff, 0x0e, 0xa4, 0x52, 0xff, 0x0f, 0xa3, 0x53, 0xff, 0x0a, 0xa4, 0x52, 0xff, 0x08, 0xa6, 0x53, 0xff, 0x08, 0xa3, 0x52, 0xff, 0x09, 0xa3, 0x53, 0xff, 0x0a, 0xa3, 0x58, 0xff, 0x0c, 0xa4, 0x5d, 0xff, 0x0e, 0xa4, 0x62, 0xff, 0x0d, 0xa4, 0x65, 0xff, 0x0e, 0xa2, 0x65, 0xff, 0x13, 0xa1, 0x67, 0xff, 0x13, 0xa0, 0x67, 0xff, 0x12, 0xa0, 0x67, 0xff, 0x0f, 0xa1, 0x68, 0xff, 0x0c, 0x9f, 0x67, 0xff, 0x0b, 0x9d, 0x67, 0xff, 0x0d, 0x9d, 0x67, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0b, 0x9a, 0x65, 0xff, 0x0c, 0x99, 0x65, 0xff, 0x0d, 0x9b, 0x66, 0xff, 0x0a, 0x9d, 0x68, 0xff, 0x07, 0x9e, 0x67, 0xff, 0x09, 0x9d, 0x66, 0xff, 0x0e, 0x9d, 0x66, 0xff, 0x0f, 0x9d, 0x67, 0xff, 0x0c, 0x9e, 0x69, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x09, 0xa0, 0x6a, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x08, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x08, 0xa7, 0x6c, 0xff, 0x08, 0xa7, 0x6d, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x0d, 0xa9, 0x74, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x06, 0xa2, 0x6b, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0a, 0xa4, 0x6f, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x11, 0xa5, 0x73, 0xff, 0x0e, 0xa4, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa3, 0x71, 0xff, 0x0e, 0xa4, 0x70, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x0e, 0xa3, 0x70, 0xff, 0x10, 0xa6, 0x73, 0xff, 0x0f, 0xa5, 0x75, 0xff, 0x0f, 0xa4, 0x72, 0xff, 0x0d, 0xa2, 0x6f, 0xff, 0x0f, 0xa4, 0x6f, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0d, 0xa1, 0x6c, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x06, 0x98, 0x63, 0xff, 0x0c, 0x99, 0x61, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0b, 0xa7, 0x68, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x0c, 0xa9, 0x68, 0xff, 0x0e, 0xaa, 0x6c, 0xff, 0x0c, 0xaa, 0x6e, 0xff, 0x09, 0xaa, 0x6f, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0d, 0xa6, 0x70, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0d, 0xa5, 0x72, 0xff, 0x0c, 0xa3, 0x6f, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x09, 0x9f, 0x69, 0xff, 0x0a, 0xa0, 0x67, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x12, 0xa9, 0x71, 0xff, 0x11, 0xa9, 0x70, 0xff, 0x10, 0xaa, 0x70, 0xff, 0x11, 0xaa, 0x70, 0xff, 0x0f, 0xa7, 0x6c, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x08, 0x9c, 0x60, 0xff, 0x09, 0x9d, 0x5d, 0xff, 0x0c, 0x9c, 0x59, 0xff, 0x0a, 0x96, 0x54, 0xff, 0x0b, 0x95, 0x54, 0xff, 0x07, 0x95, 0x54, 0xff, 0x02, 0x94, 0x54, 0xff, 0x02, 0x98, 0x58, 0xff, 0x08, 0xa3, 0x64, 0xff, 0x0a, 0xa1, 0x61, 0xff, 0x08, 0x9c, 0x5c, 0xff, 0x08, 0x9c, 0x5b, 0xff, 0x09, 0x9b, 0x5a, 0xff, 0x08, 0x9b, 0x57, 0xff, 0x07, 0x97, 0x52, 0xff, 0x07, 0x93, 0x4f, 0xff, 0x08, 0x92, 0x4c, 0xff, 0x07, 0x91, 0x4d, 0xff, 0x05, 0x91, 0x4c, 0xff, 0x04, 0x92, 0x4d, 0xff, 0x07, 0x92, 0x4e, 0xff, 0x07, 0x91, 0x4c, 0xff, 0x09, 0x8e, 0x49, 0xff, 0x09, 0x8c, 0x46, 0xff, 0x09, 0x88, 0x43, 0xff, 0x0a, 0x86, 0x45, 0xff, 0x07, 0x81, 0x41, 0xff, 0x05, 0x7f, 0x3f, 0xff, 0x07, 0x7f, 0x3f, 0xff, 0x07, 0x7f, 0x41, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x05, 0x78, 0x45, 0xff, 0x08, 0x76, 0x42, 0xff, 0x0d, 0x75, 0x3e, 0xff, 0x0d, 0x68, 0x42, 0xff, 0x09, 0x5e, 0x39, 0xff, 0x09, 0x55, 0x38, 0xff, 0x09, 0x50, 0x38, 0xff, 0x0e, 0x50, 0x37, 0xff, 0x0b, 0x51, 0x3c, 0xff, 0x0e, 0x4b, 0x3f, 0xff, 0x11, 0x4a, 0x42, 0xff, 0x1b, 0x69, 0x5d, 0xff, 0x2b, 0x92, 0x7b, 0xff, 0x13, 0x6f, 0x63, 0xff, 0x25, 0x78, 0x76, 0xff, 0x1b, 0x7e, 0x7e, 0xff, 0x21, 0xa4, 0x82, 0xff, 0x23, 0xbb, 0x7a, 0xff, 0x1b, 0xb1, 0x6c, 0xff, 0x16, 0xb1, 0x5f, 0xff, 0x2b, 0xcf, 0x6b, 0xff, 0x07, 0x9f, 0x3b, 0xff, 0x08, 0x90, 0x2f, 0xff, 0x19, 0x8a, 0x37, 0xff, 0x0d, 0x7d, 0x38, 0xff, 0x2e, 0xc8, 0x80, 0xff, 0x0e, 0xad, 0x56, 0xff, 0x04, 0x91, 0x2f, 0xff, 0x19, 0x84, 0x39, 0xff, 0x07, 0x50, 0x1f, 0xff, 0x02, 0x4d, 0x1a, 0xff, 0x61, 0x8c, 0x70, 0xff, + 0x07, 0x66, 0x2d, 0xff, 0x1e, 0x91, 0x58, 0xff, 0x06, 0x57, 0x34, 0xff, 0x07, 0x4c, 0x36, 0xff, 0x03, 0x4c, 0x2a, 0xff, 0x16, 0x82, 0x48, 0xff, 0x11, 0x73, 0x41, 0xff, 0x02, 0x45, 0x1e, 0xff, 0x08, 0x5e, 0x2c, 0xff, 0x16, 0x73, 0x4b, 0xff, 0x22, 0x97, 0x72, 0xff, 0x0e, 0x9e, 0x6d, 0xff, 0x0e, 0xa0, 0x6f, 0xff, 0x3e, 0xb9, 0xa8, 0xff, 0x7d, 0xde, 0xeb, 0xff, 0x4f, 0xa7, 0xc0, 0xff, 0x0d, 0x74, 0x74, 0xff, 0x0c, 0xa0, 0x6f, 0xff, 0x0a, 0xa6, 0x69, 0xff, 0x0b, 0xa0, 0x6f, 0xff, 0x0d, 0xa1, 0x6f, 0xff, 0x0d, 0xa1, 0x64, 0xff, 0x09, 0x9c, 0x5c, 0xff, 0x1b, 0xa3, 0x68, 0xff, 0x13, 0x8d, 0x5e, 0xff, 0x1d, 0x9e, 0x72, 0xff, 0x18, 0xa0, 0x6d, 0xff, 0x3d, 0xc9, 0x8c, 0xff, 0x19, 0xa3, 0x6b, 0xff, 0x0d, 0x84, 0x61, 0xff, 0x24, 0x98, 0x7d, 0xff, 0x15, 0xa0, 0x74, 0xff, 0x02, 0x8e, 0x54, 0xff, 0x1b, 0xa7, 0x6b, 0xff, 0x26, 0xb0, 0x80, 0xff, 0x0a, 0x97, 0x67, 0xff, 0x28, 0xb2, 0x7d, 0xff, 0x2d, 0x92, 0xa9, 0xff, 0x1f, 0x69, 0xc3, 0xff, 0x2b, 0x6a, 0xf3, 0xff, 0x19, 0x59, 0xe4, 0xff, 0x27, 0x72, 0xeb, 0xff, 0x3d, 0x8d, 0xf6, 0xff, 0x1f, 0x6c, 0xec, 0xff, 0x2e, 0x7b, 0xf8, 0xff, 0x1f, 0x7c, 0xd0, 0xff, 0x07, 0x7d, 0x98, 0xff, 0x03, 0xa4, 0x72, 0xff, 0x09, 0xa9, 0x72, 0xff, 0x09, 0xa8, 0x72, 0xff, 0x08, 0xac, 0x6b, 0xff, 0x06, 0xa9, 0x72, 0xff, 0x06, 0xa8, 0x74, 0xff, 0x07, 0xa7, 0x73, 0xff, 0x08, 0xaa, 0x6d, 0xff, 0x03, 0xaa, 0x70, 0xff, 0x04, 0xac, 0x70, 0xff, 0x05, 0xae, 0x6d, 0xff, 0x04, 0xb0, 0x6b, 0xff, 0x02, 0xaf, 0x68, 0xff, 0x02, 0xaf, 0x69, 0xff, 0x02, 0xaf, 0x6c, 0xff, 0x04, 0xb0, 0x6e, 0xff, 0x08, 0xb2, 0x72, 0xff, 0x0a, 0xb2, 0x73, 0xff, 0x0d, 0xb4, 0x75, 0xff, 0x0f, 0xb4, 0x76, 0xff, 0x10, 0xb2, 0x73, 0xff, 0x0c, 0xac, 0x6c, 0xff, 0x0a, 0xa8, 0x67, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0c, 0xa8, 0x68, 0xff, 0x0c, 0xa8, 0x68, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0b, 0xa8, 0x67, 0xff, 0x0c, 0xaa, 0x67, 0xff, 0x0c, 0xab, 0x68, 0xff, 0x0a, 0xa9, 0x66, 0xff, 0x0b, 0xa7, 0x66, 0xff, 0x09, 0xa6, 0x65, 0xff, 0x09, 0xa6, 0x65, 0xff, 0x0a, 0xa7, 0x66, 0xff, 0x0c, 0xa9, 0x68, 0xff, 0x0c, 0xa9, 0x68, 0xff, 0x0a, 0xa8, 0x66, 0xff, 0x0b, 0xa9, 0x68, 0xff, 0x10, 0xac, 0x6f, 0xff, 0x13, 0xac, 0x70, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0e, 0xaa, 0x71, 0xff, 0x0d, 0xaa, 0x70, 0xff, 0x0c, 0xac, 0x72, 0xff, 0x0f, 0xae, 0x72, 0xff, 0x0f, 0xad, 0x70, 0xff, 0x0f, 0xad, 0x71, 0xff, 0x0d, 0xab, 0x6f, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x0e, 0xac, 0x6f, 0xff, 0x0f, 0xad, 0x6f, 0xff, 0x0e, 0xad, 0x70, 0xff, 0x0d, 0xac, 0x70, 0xff, 0x0b, 0xac, 0x6d, 0xff, 0x0c, 0xac, 0x6b, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0d, 0xaa, 0x66, 0xff, 0x09, 0xa6, 0x61, 0xff, 0x09, 0xa7, 0x5f, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x10, 0xae, 0x67, 0xff, 0x11, 0xb0, 0x69, 0xff, 0x0e, 0xab, 0x67, 0xff, 0x10, 0xaf, 0x6d, 0xff, 0x11, 0xb0, 0x70, 0xff, 0x12, 0xb3, 0x75, 0xff, 0x14, 0xb4, 0x78, 0xff, 0x15, 0xb4, 0x77, 0xff, 0x16, 0xb5, 0x77, 0xff, 0x18, 0xb5, 0x79, 0xff, 0x16, 0xb3, 0x77, 0xff, 0x13, 0xb1, 0x73, 0xff, 0x14, 0xb1, 0x73, 0xff, 0x13, 0xb1, 0x70, 0xff, 0x0f, 0xad, 0x6b, 0xff, 0x0d, 0xab, 0x67, 0xff, 0x0d, 0xac, 0x66, 0xff, 0x0c, 0xab, 0x66, 0xff, 0x0c, 0xab, 0x65, 0xff, 0x0c, 0xaa, 0x64, 0xff, 0x0b, 0xaa, 0x64, 0xff, 0x0c, 0xab, 0x65, 0xff, 0x0c, 0xab, 0x64, 0xff, 0x0c, 0xa9, 0x62, 0xff, 0x0c, 0xa8, 0x61, 0xff, 0x0e, 0xa7, 0x5e, 0xff, 0x0e, 0xa7, 0x5c, 0xff, 0x0d, 0xa6, 0x5b, 0xff, 0x0c, 0xa6, 0x5a, 0xff, 0x0c, 0xa5, 0x58, 0xff, 0x0d, 0xa5, 0x58, 0xff, 0x0e, 0xa5, 0x55, 0xff, 0x0e, 0xa4, 0x54, 0xff, 0x08, 0xa1, 0x51, 0xff, 0x07, 0xa1, 0x50, 0xff, 0x09, 0xa3, 0x52, 0xff, 0x09, 0xa3, 0x52, 0xff, 0x09, 0xa1, 0x50, 0xff, 0x0a, 0xa1, 0x50, 0xff, 0x0c, 0xa3, 0x52, 0xff, 0x0e, 0xa2, 0x53, 0xff, 0x0a, 0xa1, 0x50, 0xff, 0x0b, 0xa3, 0x52, 0xff, 0x08, 0xa0, 0x51, 0xff, 0x09, 0xa2, 0x53, 0xff, 0x0a, 0xa2, 0x57, 0xff, 0x0b, 0xa3, 0x5b, 0xff, 0x0a, 0xa3, 0x60, 0xff, 0x0a, 0xa3, 0x63, 0xff, 0x0c, 0xa1, 0x65, 0xff, 0x10, 0xa1, 0x67, 0xff, 0x0e, 0xa0, 0x65, 0xff, 0x0e, 0xa1, 0x66, 0xff, 0x0d, 0xa1, 0x66, 0xff, 0x0d, 0x9f, 0x66, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x10, 0x9d, 0x69, 0xff, 0x0b, 0x9b, 0x65, 0xff, 0x09, 0x9b, 0x63, 0xff, 0x0a, 0x99, 0x63, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x0a, 0x9c, 0x67, 0xff, 0x09, 0x9c, 0x66, 0xff, 0x0a, 0x9e, 0x66, 0xff, 0x0c, 0x9e, 0x65, 0xff, 0x0c, 0x9e, 0x66, 0xff, 0x0b, 0x9d, 0x68, 0xff, 0x08, 0x9d, 0x67, 0xff, 0x08, 0x9d, 0x67, 0xff, 0x08, 0x9f, 0x69, 0xff, 0x09, 0xa0, 0x6a, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x06, 0xa5, 0x6c, 0xff, 0x07, 0xa6, 0x6c, 0xff, 0x09, 0xa7, 0x6c, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x08, 0xa9, 0x69, 0xff, 0x05, 0xaa, 0x67, 0xff, 0x05, 0xa7, 0x69, 0xff, 0x06, 0xa6, 0x71, 0xff, 0x06, 0xa2, 0x72, 0xff, 0x08, 0xa4, 0x71, 0xff, 0x07, 0xa3, 0x6b, 0xff, 0x0a, 0xa6, 0x6b, 0xff, 0x08, 0xa6, 0x6c, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x0a, 0xa5, 0x71, 0xff, 0x0d, 0xa3, 0x72, 0xff, 0x12, 0xa6, 0x74, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0f, 0xa2, 0x70, 0xff, 0x0f, 0xa3, 0x71, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa4, 0x6e, 0xff, 0x10, 0xa7, 0x73, 0xff, 0x0c, 0xa6, 0x72, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x10, 0xa2, 0x6e, 0xff, 0x13, 0xa3, 0x6f, 0xff, 0x11, 0xa0, 0x6c, 0xff, 0x0f, 0xa1, 0x6d, 0xff, 0x0d, 0xa4, 0x6d, 0xff, 0x05, 0x9b, 0x67, 0xff, 0x05, 0x95, 0x61, 0xff, 0x0c, 0x9e, 0x66, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0b, 0xa5, 0x65, 0xff, 0x0c, 0xa7, 0x67, 0xff, 0x0d, 0xa9, 0x6a, 0xff, 0x0d, 0xaa, 0x6e, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x09, 0xa0, 0x69, 0xff, 0x0a, 0xa0, 0x69, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0b, 0xa3, 0x6d, 0xff, 0x0a, 0xa2, 0x6d, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x08, 0x9f, 0x67, 0xff, 0x09, 0x9e, 0x64, 0xff, 0x0a, 0x9e, 0x62, 0xff, 0x0d, 0xa2, 0x63, 0xff, 0x13, 0xa7, 0x6b, 0xff, 0x12, 0xa6, 0x6a, 0xff, 0x11, 0xa5, 0x6a, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x09, 0xa0, 0x62, 0xff, 0x07, 0x9d, 0x5f, 0xff, 0x05, 0x9a, 0x5a, 0xff, 0x05, 0x9b, 0x58, 0xff, 0x07, 0x99, 0x58, 0xff, 0x08, 0x98, 0x57, 0xff, 0x0a, 0x98, 0x5b, 0xff, 0x07, 0x97, 0x5b, 0xff, 0x08, 0x9a, 0x60, 0xff, 0x08, 0x9d, 0x63, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x65, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0c, 0x9d, 0x5e, 0xff, 0x0b, 0x9a, 0x59, 0xff, 0x07, 0x97, 0x54, 0xff, 0x05, 0x94, 0x4f, 0xff, 0x05, 0x92, 0x4e, 0xff, 0x07, 0x91, 0x4c, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x06, 0x91, 0x4d, 0xff, 0x08, 0x92, 0x4c, 0xff, 0x08, 0x90, 0x4a, 0xff, 0x09, 0x8d, 0x47, 0xff, 0x0a, 0x8c, 0x47, 0xff, 0x0a, 0x89, 0x44, 0xff, 0x0b, 0x87, 0x44, 0xff, 0x06, 0x81, 0x40, 0xff, 0x04, 0x80, 0x3e, 0xff, 0x06, 0x81, 0x40, 0xff, 0x05, 0x7f, 0x3f, 0xff, 0x08, 0x7f, 0x41, 0xff, 0x0b, 0x7e, 0x42, 0xff, 0x0b, 0x7c, 0x40, 0xff, 0x07, 0x79, 0x40, 0xff, 0x08, 0x77, 0x40, 0xff, 0x0b, 0x73, 0x3f, 0xff, 0x0d, 0x6a, 0x41, 0xff, 0x0b, 0x5d, 0x3a, 0xff, 0x0e, 0x53, 0x38, 0xff, 0x0e, 0x50, 0x38, 0xff, 0x11, 0x50, 0x38, 0xff, 0x11, 0x50, 0x38, 0xff, 0x10, 0x4e, 0x3c, 0xff, 0x0b, 0x4d, 0x3f, 0xff, 0x0d, 0x6c, 0x5d, 0xff, 0x32, 0xd0, 0x99, 0xff, 0x1a, 0xbc, 0x7f, 0xff, 0x28, 0xb7, 0x88, 0xff, 0x15, 0x9d, 0x80, 0xff, 0x08, 0x8f, 0x6f, 0xff, 0x2b, 0xb5, 0x88, 0xff, 0x28, 0xaf, 0x77, 0xff, 0x1b, 0xb0, 0x63, 0xff, 0x1b, 0xc0, 0x5c, 0xff, 0x07, 0x9d, 0x34, 0xff, 0x0b, 0x8d, 0x2d, 0xff, 0x11, 0x82, 0x34, 0xff, 0x18, 0xa1, 0x50, 0xff, 0x21, 0xc9, 0x6b, 0xff, 0x04, 0x9a, 0x41, 0xff, 0x05, 0x89, 0x2e, 0xff, 0x19, 0x8c, 0x3d, 0xff, 0x07, 0x54, 0x22, 0xff, 0x02, 0x47, 0x1a, 0xff, 0x61, 0x8a, 0x71, 0xff, + 0x13, 0x7c, 0x3e, 0xff, 0x10, 0x77, 0x43, 0xff, 0x01, 0x4a, 0x2a, 0xff, 0x03, 0x4c, 0x2f, 0xff, 0x02, 0x54, 0x29, 0xff, 0x1e, 0x88, 0x51, 0xff, 0x07, 0x58, 0x2f, 0xff, 0x0a, 0x58, 0x2e, 0xff, 0x04, 0x68, 0x2b, 0xff, 0x03, 0x63, 0x33, 0xff, 0x10, 0x84, 0x59, 0xff, 0x11, 0xa2, 0x6b, 0xff, 0x11, 0x9e, 0x75, 0xff, 0x4d, 0xbc, 0xbc, 0xff, 0x73, 0xd4, 0xe5, 0xff, 0x78, 0xd1, 0xe8, 0xff, 0x1f, 0x7e, 0x8a, 0xff, 0x0c, 0x97, 0x74, 0xff, 0x09, 0xa3, 0x6a, 0xff, 0x0b, 0xa1, 0x6a, 0xff, 0x06, 0x9d, 0x62, 0xff, 0x04, 0x9a, 0x56, 0xff, 0x16, 0xa6, 0x65, 0xff, 0x07, 0x77, 0x3f, 0xff, 0x16, 0x8a, 0x59, 0xff, 0x0c, 0x8b, 0x5c, 0xff, 0x0f, 0x96, 0x62, 0xff, 0x3b, 0xcd, 0x91, 0xff, 0x0e, 0x99, 0x61, 0xff, 0x09, 0x87, 0x5a, 0xff, 0x17, 0x9c, 0x70, 0xff, 0x0c, 0x9a, 0x65, 0xff, 0x06, 0x94, 0x59, 0xff, 0x11, 0x9e, 0x60, 0xff, 0x14, 0x9b, 0x67, 0xff, 0x05, 0x84, 0x59, 0xff, 0x2a, 0xa0, 0x8d, 0xff, 0x15, 0x65, 0xb6, 0xff, 0x0e, 0x4b, 0xd2, 0xff, 0x1e, 0x5c, 0xef, 0xff, 0x1f, 0x65, 0xed, 0xff, 0x19, 0x69, 0xe9, 0xff, 0x0f, 0x62, 0xe4, 0xff, 0x19, 0x6b, 0xf2, 0xff, 0x18, 0x6d, 0xec, 0xff, 0x23, 0x7b, 0xe4, 0xff, 0x0e, 0x73, 0xb5, 0xff, 0x08, 0x99, 0x7f, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x07, 0xa7, 0x73, 0xff, 0x05, 0xab, 0x6d, 0xff, 0x06, 0xaa, 0x71, 0xff, 0x06, 0xa7, 0x74, 0xff, 0x07, 0xa8, 0x71, 0xff, 0x06, 0xa8, 0x70, 0xff, 0x03, 0xa8, 0x70, 0xff, 0x04, 0xaa, 0x70, 0xff, 0x05, 0xad, 0x6e, 0xff, 0x05, 0xaf, 0x6c, 0xff, 0x05, 0xaf, 0x6b, 0xff, 0x01, 0xad, 0x68, 0xff, 0x03, 0xaf, 0x6d, 0xff, 0x08, 0xb2, 0x71, 0xff, 0x0a, 0xb2, 0x73, 0xff, 0x0c, 0xb2, 0x74, 0xff, 0x0e, 0xb3, 0x74, 0xff, 0x10, 0xb3, 0x73, 0xff, 0x0d, 0xaf, 0x6e, 0xff, 0x0c, 0xab, 0x6b, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x0a, 0xa7, 0x67, 0xff, 0x0b, 0xa7, 0x68, 0xff, 0x0a, 0xa6, 0x67, 0xff, 0x0c, 0xa9, 0x69, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x66, 0xff, 0x0b, 0xa8, 0x65, 0xff, 0x0a, 0xa7, 0x62, 0xff, 0x08, 0xa3, 0x60, 0xff, 0x06, 0xa2, 0x5f, 0xff, 0x07, 0xa2, 0x5f, 0xff, 0x08, 0xa3, 0x62, 0xff, 0x0a, 0xa5, 0x64, 0xff, 0x0a, 0xa6, 0x65, 0xff, 0x07, 0xa3, 0x62, 0xff, 0x09, 0xa5, 0x64, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x09, 0x9b, 0x64, 0xff, 0x0c, 0x9f, 0x68, 0xff, 0x0e, 0xa7, 0x6f, 0xff, 0x0d, 0xa9, 0x71, 0xff, 0x0f, 0xad, 0x71, 0xff, 0x0f, 0xac, 0x70, 0xff, 0x0d, 0xa8, 0x6b, 0xff, 0x0f, 0xaa, 0x6d, 0xff, 0x0c, 0xa7, 0x6a, 0xff, 0x0d, 0xa9, 0x6a, 0xff, 0x0f, 0xab, 0x6e, 0xff, 0x10, 0xac, 0x70, 0xff, 0x0e, 0xac, 0x72, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0c, 0xac, 0x6d, 0xff, 0x0f, 0xad, 0x6d, 0xff, 0x0e, 0xac, 0x68, 0xff, 0x0c, 0xa9, 0x61, 0xff, 0x07, 0xa2, 0x58, 0xff, 0x08, 0xa3, 0x56, 0xff, 0x0a, 0xa5, 0x59, 0xff, 0x0b, 0xa6, 0x5b, 0xff, 0x08, 0xa3, 0x59, 0xff, 0x0b, 0xa7, 0x5e, 0xff, 0x10, 0xae, 0x69, 0xff, 0x10, 0xaf, 0x6d, 0xff, 0x12, 0xb1, 0x72, 0xff, 0x12, 0xb1, 0x74, 0xff, 0x15, 0xb4, 0x76, 0xff, 0x16, 0xb5, 0x77, 0xff, 0x16, 0xb3, 0x76, 0xff, 0x13, 0xaf, 0x72, 0xff, 0x14, 0xb1, 0x73, 0xff, 0x13, 0xb0, 0x6f, 0xff, 0x0f, 0xad, 0x6b, 0xff, 0x0e, 0xac, 0x69, 0xff, 0x0e, 0xac, 0x67, 0xff, 0x0e, 0xad, 0x67, 0xff, 0x0d, 0xab, 0x67, 0xff, 0x0c, 0xaa, 0x65, 0xff, 0x0c, 0xab, 0x65, 0xff, 0x0b, 0xaa, 0x64, 0xff, 0x0b, 0xaa, 0x62, 0xff, 0x0c, 0xa9, 0x62, 0xff, 0x0d, 0xa7, 0x60, 0xff, 0x0d, 0xa8, 0x5f, 0xff, 0x0d, 0xa7, 0x5c, 0xff, 0x0d, 0xa7, 0x5c, 0xff, 0x0c, 0xa5, 0x5a, 0xff, 0x0c, 0xa5, 0x59, 0xff, 0x0d, 0xa5, 0x57, 0xff, 0x0d, 0xa5, 0x55, 0xff, 0x0d, 0xa3, 0x53, 0xff, 0x0c, 0xa2, 0x52, 0xff, 0x0c, 0xa2, 0x52, 0xff, 0x0c, 0xa3, 0x53, 0xff, 0x0d, 0xa4, 0x54, 0xff, 0x0b, 0xa2, 0x52, 0xff, 0x0a, 0xa1, 0x51, 0xff, 0x09, 0xa0, 0x50, 0xff, 0x08, 0x9f, 0x50, 0xff, 0x07, 0x9e, 0x4e, 0xff, 0x07, 0x9d, 0x4d, 0xff, 0x0c, 0x9f, 0x4f, 0xff, 0x0b, 0xa1, 0x50, 0xff, 0x0b, 0xa2, 0x52, 0xff, 0x0b, 0xa3, 0x57, 0xff, 0x0b, 0xa3, 0x5a, 0xff, 0x0a, 0xa3, 0x5e, 0xff, 0x0a, 0xa2, 0x60, 0xff, 0x0b, 0xa1, 0x62, 0xff, 0x0d, 0xa1, 0x63, 0xff, 0x0c, 0xa1, 0x62, 0xff, 0x0c, 0xa3, 0x63, 0xff, 0x0c, 0xa2, 0x63, 0xff, 0x0e, 0xa2, 0x65, 0xff, 0x0d, 0x9f, 0x64, 0xff, 0x0b, 0x9a, 0x62, 0xff, 0x09, 0x9a, 0x5e, 0xff, 0x08, 0x9c, 0x5d, 0xff, 0x0a, 0x9c, 0x60, 0xff, 0x0a, 0x9c, 0x63, 0xff, 0x09, 0x9c, 0x65, 0xff, 0x09, 0x9c, 0x65, 0xff, 0x0a, 0x9d, 0x64, 0xff, 0x0b, 0x9f, 0x63, 0xff, 0x0b, 0x9e, 0x64, 0xff, 0x0a, 0x9d, 0x65, 0xff, 0x09, 0x9e, 0x66, 0xff, 0x09, 0x9e, 0x66, 0xff, 0x0a, 0x9e, 0x67, 0xff, 0x0a, 0x9f, 0x68, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x09, 0xa5, 0x6b, 0xff, 0x0a, 0xa7, 0x6b, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0d, 0xa8, 0x6d, 0xff, 0x0c, 0xa7, 0x6d, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x0a, 0xaa, 0x6b, 0xff, 0x08, 0xa9, 0x6b, 0xff, 0x09, 0xa6, 0x73, 0xff, 0x11, 0xac, 0x81, 0xff, 0x0b, 0xa3, 0x7a, 0xff, 0x07, 0xa1, 0x71, 0xff, 0x08, 0xa5, 0x6d, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x07, 0xa5, 0x70, 0xff, 0x09, 0xa4, 0x71, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x10, 0xa5, 0x71, 0xff, 0x11, 0xa4, 0x72, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x0e, 0xa5, 0x6f, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0d, 0xa4, 0x6f, 0xff, 0x0b, 0xa7, 0x73, 0xff, 0x0c, 0xa7, 0x73, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x0d, 0xa3, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x08, 0x9f, 0x69, 0xff, 0x06, 0x98, 0x64, 0xff, 0x05, 0x97, 0x60, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0c, 0xa4, 0x64, 0xff, 0x0b, 0xa4, 0x63, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x11, 0xa8, 0x70, 0xff, 0x11, 0xa7, 0x71, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0c, 0x9e, 0x67, 0xff, 0x0a, 0x9c, 0x66, 0xff, 0x0a, 0x9e, 0x67, 0xff, 0x0b, 0x9f, 0x69, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x08, 0xa0, 0x68, 0xff, 0x0a, 0xa0, 0x67, 0xff, 0x09, 0x9f, 0x64, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0a, 0x9c, 0x5f, 0xff, 0x0a, 0x9d, 0x61, 0xff, 0x09, 0x9c, 0x61, 0xff, 0x07, 0x9b, 0x61, 0xff, 0x06, 0x9a, 0x5f, 0xff, 0x06, 0x9b, 0x5d, 0xff, 0x09, 0x9c, 0x5e, 0xff, 0x09, 0x9d, 0x5e, 0xff, 0x09, 0x9e, 0x5d, 0xff, 0x08, 0x9c, 0x5d, 0xff, 0x09, 0x9b, 0x5e, 0xff, 0x0a, 0x9d, 0x62, 0xff, 0x0b, 0x9f, 0x64, 0xff, 0x0b, 0xa0, 0x66, 0xff, 0x0c, 0xa2, 0x68, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x09, 0xa1, 0x65, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x0a, 0x9a, 0x5b, 0xff, 0x08, 0x95, 0x54, 0xff, 0x08, 0x96, 0x53, 0xff, 0x06, 0x95, 0x50, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x07, 0x90, 0x4c, 0xff, 0x06, 0x90, 0x4c, 0xff, 0x08, 0x92, 0x4e, 0xff, 0x07, 0x90, 0x4c, 0xff, 0x06, 0x8e, 0x49, 0xff, 0x08, 0x8d, 0x47, 0xff, 0x0a, 0x8c, 0x46, 0xff, 0x0c, 0x8a, 0x45, 0xff, 0x0a, 0x85, 0x42, 0xff, 0x05, 0x80, 0x3e, 0xff, 0x05, 0x80, 0x3e, 0xff, 0x05, 0x80, 0x40, 0xff, 0x07, 0x80, 0x40, 0xff, 0x0a, 0x7f, 0x42, 0xff, 0x0b, 0x7e, 0x41, 0xff, 0x0b, 0x7b, 0x40, 0xff, 0x07, 0x7a, 0x3e, 0xff, 0x06, 0x79, 0x3f, 0xff, 0x08, 0x74, 0x42, 0xff, 0x08, 0x67, 0x3f, 0xff, 0x08, 0x5a, 0x39, 0xff, 0x0a, 0x52, 0x38, 0xff, 0x0b, 0x50, 0x38, 0xff, 0x0b, 0x50, 0x39, 0xff, 0x10, 0x50, 0x35, 0xff, 0x10, 0x50, 0x3d, 0xff, 0x0a, 0x4d, 0x3a, 0xff, 0x04, 0x59, 0x45, 0xff, 0x1f, 0xc4, 0x8b, 0xff, 0x16, 0xdb, 0x8f, 0xff, 0x0d, 0xbb, 0x65, 0xff, 0x23, 0xd7, 0x82, 0xff, 0x13, 0xb5, 0x7d, 0xff, 0x23, 0xaf, 0x86, 0xff, 0x3b, 0xb6, 0x82, 0xff, 0x17, 0x98, 0x4f, 0xff, 0x0b, 0xa6, 0x45, 0xff, 0x05, 0x99, 0x2d, 0xff, 0x02, 0x88, 0x25, 0xff, 0x02, 0x7c, 0x2a, 0xff, 0x14, 0xa8, 0x4b, 0xff, 0x08, 0xac, 0x42, 0xff, 0x07, 0x8f, 0x34, 0xff, 0x06, 0x84, 0x2e, 0xff, 0x0d, 0x89, 0x37, 0xff, 0x04, 0x59, 0x25, 0xff, 0x02, 0x43, 0x19, 0xff, 0x68, 0x89, 0x73, 0xff, + 0x16, 0x81, 0x43, 0xff, 0x07, 0x61, 0x30, 0xff, 0x02, 0x46, 0x27, 0xff, 0x00, 0x4a, 0x25, 0xff, 0x07, 0x64, 0x30, 0xff, 0x1f, 0x85, 0x4f, 0xff, 0x04, 0x4b, 0x25, 0xff, 0x0d, 0x66, 0x34, 0xff, 0x02, 0x6f, 0x2a, 0xff, 0x01, 0x61, 0x2e, 0xff, 0x06, 0x71, 0x42, 0xff, 0x11, 0xa0, 0x66, 0xff, 0x1b, 0xa3, 0x81, 0xff, 0x58, 0xbc, 0xc8, 0xff, 0x6d, 0xca, 0xe0, 0xff, 0x80, 0xdd, 0xf3, 0xff, 0x35, 0x96, 0xaa, 0xff, 0x0e, 0x8c, 0x79, 0xff, 0x12, 0xa0, 0x71, 0xff, 0x09, 0x98, 0x5b, 0xff, 0x02, 0x97, 0x52, 0xff, 0x0d, 0xa9, 0x62, 0xff, 0x17, 0xa2, 0x64, 0xff, 0x01, 0x62, 0x2e, 0xff, 0x0a, 0x83, 0x50, 0xff, 0x03, 0x85, 0x50, 0xff, 0x03, 0x8b, 0x56, 0xff, 0x0f, 0x9f, 0x6a, 0xff, 0x09, 0x8d, 0x5b, 0xff, 0x0a, 0x8b, 0x5a, 0xff, 0x11, 0xa0, 0x68, 0xff, 0x11, 0x9d, 0x62, 0xff, 0x07, 0x93, 0x5b, 0xff, 0x06, 0x91, 0x54, 0xff, 0x07, 0x85, 0x5a, 0xff, 0x08, 0x74, 0x64, 0xff, 0x09, 0x5e, 0x7f, 0xff, 0x08, 0x44, 0xc0, 0xff, 0x07, 0x3f, 0xda, 0xff, 0x11, 0x51, 0xea, 0xff, 0x1a, 0x63, 0xec, 0xff, 0x1b, 0x6d, 0xf0, 0xff, 0x11, 0x65, 0xee, 0xff, 0x18, 0x6c, 0xf8, 0xff, 0x24, 0x7c, 0xf8, 0xff, 0x1e, 0x79, 0xea, 0xff, 0x17, 0x77, 0xd0, 0xff, 0x09, 0x84, 0x8d, 0xff, 0x0f, 0xa9, 0x73, 0xff, 0x04, 0xa8, 0x70, 0xff, 0x04, 0xaa, 0x71, 0xff, 0x06, 0xa9, 0x70, 0xff, 0x08, 0xa7, 0x73, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x05, 0xa7, 0x73, 0xff, 0x05, 0xa8, 0x72, 0xff, 0x05, 0xa9, 0x6f, 0xff, 0x05, 0xaa, 0x6e, 0xff, 0x05, 0xac, 0x6b, 0xff, 0x04, 0xab, 0x68, 0xff, 0x02, 0xa9, 0x67, 0xff, 0x04, 0xaa, 0x6a, 0xff, 0x07, 0xad, 0x6e, 0xff, 0x07, 0xad, 0x6d, 0xff, 0x08, 0xad, 0x6d, 0xff, 0x0a, 0xad, 0x6d, 0xff, 0x0a, 0xad, 0x6c, 0xff, 0x09, 0xaa, 0x69, 0xff, 0x0a, 0xa9, 0x69, 0xff, 0x09, 0xa8, 0x68, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x0a, 0xa7, 0x67, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x10, 0xae, 0x6d, 0xff, 0x0e, 0xac, 0x6a, 0xff, 0x0b, 0xa8, 0x66, 0xff, 0x0a, 0xa7, 0x64, 0xff, 0x09, 0xa5, 0x61, 0xff, 0x08, 0xa3, 0x5e, 0xff, 0x07, 0xa2, 0x5e, 0xff, 0x07, 0xa0, 0x5e, 0xff, 0x07, 0xa1, 0x5e, 0xff, 0x08, 0xa2, 0x60, 0xff, 0x09, 0xa2, 0x61, 0xff, 0x09, 0xa2, 0x61, 0xff, 0x07, 0xa1, 0x60, 0xff, 0x09, 0xa2, 0x61, 0xff, 0x05, 0x9d, 0x60, 0xff, 0x03, 0x91, 0x56, 0xff, 0x02, 0x88, 0x51, 0xff, 0x0b, 0x9c, 0x64, 0xff, 0x0f, 0xa8, 0x6f, 0xff, 0x0d, 0xa9, 0x6e, 0xff, 0x0e, 0xab, 0x6e, 0xff, 0x0e, 0xa9, 0x6b, 0xff, 0x0c, 0xa7, 0x68, 0xff, 0x0c, 0xa5, 0x66, 0xff, 0x0b, 0xa4, 0x64, 0xff, 0x0c, 0xa6, 0x66, 0xff, 0x0f, 0xaa, 0x6c, 0xff, 0x10, 0xac, 0x70, 0xff, 0x0e, 0xab, 0x72, 0xff, 0x0a, 0xaa, 0x71, 0xff, 0x0b, 0xa9, 0x6d, 0xff, 0x0d, 0xa9, 0x6a, 0xff, 0x0b, 0xa8, 0x62, 0xff, 0x08, 0xa4, 0x59, 0xff, 0x04, 0x9f, 0x50, 0xff, 0x04, 0x9d, 0x4e, 0xff, 0x06, 0x9f, 0x50, 0xff, 0x06, 0x9f, 0x51, 0xff, 0x04, 0x9d, 0x51, 0xff, 0x09, 0xa2, 0x57, 0xff, 0x0f, 0xaa, 0x63, 0xff, 0x10, 0xad, 0x69, 0xff, 0x14, 0xb2, 0x70, 0xff, 0x12, 0xb1, 0x71, 0xff, 0x14, 0xb3, 0x74, 0xff, 0x15, 0xb3, 0x74, 0xff, 0x15, 0xb2, 0x74, 0xff, 0x14, 0xb0, 0x71, 0xff, 0x11, 0xae, 0x6e, 0xff, 0x0f, 0xac, 0x6b, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x0e, 0xac, 0x67, 0xff, 0x0d, 0xac, 0x67, 0xff, 0x0c, 0xaa, 0x67, 0xff, 0x0c, 0xab, 0x66, 0xff, 0x0c, 0xab, 0x65, 0xff, 0x0d, 0xaa, 0x64, 0xff, 0x0b, 0xa8, 0x5f, 0xff, 0x0b, 0xa7, 0x5f, 0xff, 0x0c, 0xa7, 0x5d, 0xff, 0x0d, 0xa7, 0x5c, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0d, 0xa5, 0x5a, 0xff, 0x0e, 0xa5, 0x59, 0xff, 0x0e, 0xa6, 0x58, 0xff, 0x0f, 0xa5, 0x56, 0xff, 0x0f, 0xa5, 0x55, 0xff, 0x0f, 0xa3, 0x53, 0xff, 0x0e, 0xa2, 0x52, 0xff, 0x0c, 0xa2, 0x52, 0xff, 0x0b, 0xa2, 0x52, 0xff, 0x0c, 0xa3, 0x53, 0xff, 0x0b, 0xa2, 0x51, 0xff, 0x09, 0xa0, 0x4f, 0xff, 0x07, 0x9f, 0x4d, 0xff, 0x06, 0x9e, 0x4c, 0xff, 0x06, 0x9c, 0x4b, 0xff, 0x05, 0x9a, 0x47, 0xff, 0x08, 0x9b, 0x47, 0xff, 0x09, 0x9d, 0x4a, 0xff, 0x0b, 0xa1, 0x4e, 0xff, 0x0d, 0xa4, 0x54, 0xff, 0x0d, 0xa4, 0x57, 0xff, 0x0b, 0xa3, 0x5b, 0xff, 0x0b, 0xa3, 0x5c, 0xff, 0x0c, 0xa2, 0x5f, 0xff, 0x0d, 0xa2, 0x5f, 0xff, 0x0b, 0xa1, 0x5e, 0xff, 0x0a, 0xa1, 0x5c, 0xff, 0x09, 0xa1, 0x5c, 0xff, 0x0b, 0xa2, 0x5e, 0xff, 0x09, 0x9d, 0x5d, 0xff, 0x07, 0x9a, 0x5a, 0xff, 0x07, 0x9b, 0x58, 0xff, 0x06, 0x9c, 0x57, 0xff, 0x08, 0x9c, 0x5a, 0xff, 0x08, 0x9c, 0x5e, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x09, 0x9d, 0x62, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x09, 0x9c, 0x62, 0xff, 0x09, 0x9e, 0x65, 0xff, 0x09, 0x9e, 0x66, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x0b, 0xa0, 0x6b, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x09, 0xa2, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0b, 0xa8, 0x6c, 0xff, 0x0c, 0xa8, 0x6e, 0xff, 0x0c, 0xa5, 0x71, 0xff, 0x12, 0xa6, 0x81, 0xff, 0x2e, 0xc1, 0xa2, 0xff, 0x28, 0xbd, 0x99, 0xff, 0x0b, 0xa4, 0x76, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x06, 0xa3, 0x6d, 0xff, 0x06, 0xa3, 0x6e, 0xff, 0x0b, 0xa6, 0x72, 0xff, 0x0a, 0xa4, 0x71, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0b, 0xa3, 0x70, 0xff, 0x0e, 0xa8, 0x70, 0xff, 0x10, 0xa5, 0x70, 0xff, 0x11, 0xa4, 0x71, 0xff, 0x0f, 0xa2, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x10, 0xa2, 0x6e, 0xff, 0x13, 0xa4, 0x73, 0xff, 0x13, 0xa5, 0x74, 0xff, 0x13, 0xa7, 0x75, 0xff, 0x0b, 0xa2, 0x6f, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0d, 0xa1, 0x6b, 0xff, 0x0c, 0x9e, 0x69, 0xff, 0x07, 0x99, 0x61, 0xff, 0x07, 0x9a, 0x60, 0xff, 0x0d, 0xa2, 0x64, 0xff, 0x0c, 0xa2, 0x64, 0xff, 0x0b, 0xa2, 0x64, 0xff, 0x0d, 0xa4, 0x67, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x0c, 0xa1, 0x6c, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0c, 0x9d, 0x67, 0xff, 0x0c, 0x9d, 0x68, 0xff, 0x0d, 0x9e, 0x68, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x09, 0x9e, 0x67, 0xff, 0x09, 0x9e, 0x67, 0xff, 0x07, 0x9d, 0x63, 0xff, 0x07, 0x9d, 0x61, 0xff, 0x04, 0x99, 0x5d, 0xff, 0x05, 0x97, 0x5c, 0xff, 0x08, 0x9b, 0x60, 0xff, 0x0a, 0x9d, 0x63, 0xff, 0x0b, 0x9e, 0x65, 0xff, 0x09, 0x9c, 0x64, 0xff, 0x0a, 0x9d, 0x63, 0xff, 0x0b, 0x9e, 0x62, 0xff, 0x0a, 0x9c, 0x60, 0xff, 0x09, 0x9c, 0x5f, 0xff, 0x0a, 0x9d, 0x61, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0b, 0xa0, 0x66, 0xff, 0x0a, 0xa1, 0x67, 0xff, 0x0a, 0xa2, 0x67, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0a, 0xa2, 0x66, 0xff, 0x09, 0x9e, 0x61, 0xff, 0x08, 0x99, 0x5b, 0xff, 0x08, 0x96, 0x56, 0xff, 0x0a, 0x96, 0x54, 0xff, 0x09, 0x97, 0x53, 0xff, 0x06, 0x95, 0x50, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x07, 0x90, 0x4c, 0xff, 0x06, 0x8f, 0x4b, 0xff, 0x09, 0x91, 0x4d, 0xff, 0x09, 0x91, 0x4d, 0xff, 0x06, 0x8f, 0x4b, 0xff, 0x07, 0x8d, 0x49, 0xff, 0x0a, 0x8d, 0x48, 0xff, 0x0b, 0x8b, 0x47, 0xff, 0x0b, 0x88, 0x44, 0xff, 0x07, 0x82, 0x40, 0xff, 0x06, 0x80, 0x3e, 0xff, 0x06, 0x80, 0x3e, 0xff, 0x06, 0x80, 0x3f, 0xff, 0x07, 0x7f, 0x40, 0xff, 0x0a, 0x7f, 0x42, 0xff, 0x0a, 0x7d, 0x41, 0xff, 0x09, 0x7a, 0x3f, 0xff, 0x08, 0x7b, 0x3d, 0xff, 0x07, 0x77, 0x3b, 0xff, 0x09, 0x73, 0x3e, 0xff, 0x08, 0x65, 0x3b, 0xff, 0x06, 0x5a, 0x37, 0xff, 0x08, 0x53, 0x38, 0xff, 0x08, 0x52, 0x39, 0xff, 0x06, 0x52, 0x39, 0xff, 0x0b, 0x52, 0x36, 0xff, 0x0c, 0x4e, 0x3c, 0xff, 0x0b, 0x4f, 0x38, 0xff, 0x08, 0x52, 0x37, 0xff, 0x0e, 0xa2, 0x71, 0xff, 0x20, 0xec, 0xa4, 0xff, 0x0f, 0xd1, 0x72, 0xff, 0x10, 0xd1, 0x63, 0xff, 0x21, 0xde, 0x8f, 0xff, 0x27, 0xcd, 0x98, 0xff, 0x27, 0xb5, 0x7a, 0xff, 0x08, 0x8f, 0x43, 0xff, 0x0d, 0xa5, 0x44, 0xff, 0x04, 0x93, 0x28, 0xff, 0x00, 0x86, 0x21, 0xff, 0x01, 0x78, 0x20, 0xff, 0x13, 0xa6, 0x46, 0xff, 0x06, 0xa1, 0x36, 0xff, 0x0c, 0x8a, 0x2f, 0xff, 0x03, 0x7e, 0x28, 0xff, 0x03, 0x82, 0x30, 0xff, 0x03, 0x67, 0x2e, 0xff, 0x01, 0x4b, 0x1d, 0xff, 0x69, 0x87, 0x73, 0xff, + 0x15, 0x7f, 0x44, 0xff, 0x03, 0x4b, 0x22, 0xff, 0x09, 0x45, 0x28, 0xff, 0x01, 0x51, 0x23, 0xff, 0x0f, 0x7b, 0x3d, 0xff, 0x15, 0x74, 0x43, 0xff, 0x01, 0x41, 0x22, 0xff, 0x0d, 0x6d, 0x36, 0xff, 0x06, 0x7f, 0x36, 0xff, 0x02, 0x67, 0x2e, 0xff, 0x01, 0x62, 0x2d, 0xff, 0x0a, 0x91, 0x55, 0xff, 0x2c, 0xac, 0x8e, 0xff, 0x5f, 0xb9, 0xce, 0xff, 0x68, 0xc1, 0xdc, 0xff, 0x7a, 0xd9, 0xf1, 0xff, 0x55, 0xb6, 0xd2, 0xff, 0x10, 0x7e, 0x78, 0xff, 0x14, 0x97, 0x6d, 0xff, 0x04, 0x90, 0x4b, 0xff, 0x0a, 0xa5, 0x57, 0xff, 0x18, 0xb6, 0x6d, 0xff, 0x0a, 0x82, 0x49, 0xff, 0x04, 0x66, 0x36, 0xff, 0x0a, 0x8b, 0x56, 0xff, 0x0b, 0x98, 0x5f, 0xff, 0x07, 0x99, 0x62, 0xff, 0x0a, 0x98, 0x67, 0xff, 0x0f, 0x92, 0x62, 0xff, 0x11, 0x99, 0x63, 0xff, 0x10, 0xa2, 0x62, 0xff, 0x0e, 0x99, 0x5a, 0xff, 0x08, 0x92, 0x58, 0xff, 0x08, 0x8d, 0x59, 0xff, 0x14, 0x81, 0x76, 0xff, 0x10, 0x5f, 0x8a, 0xff, 0x04, 0x3a, 0x9f, 0xff, 0x01, 0x2d, 0xcc, 0xff, 0x08, 0x3b, 0xe4, 0xff, 0x0a, 0x4c, 0xec, 0xff, 0x0b, 0x56, 0xe4, 0xff, 0x11, 0x64, 0xec, 0xff, 0x13, 0x68, 0xf8, 0xff, 0x0d, 0x66, 0xf6, 0xff, 0x1a, 0x75, 0xf7, 0xff, 0x1c, 0x79, 0xf5, 0xff, 0x1d, 0x76, 0xeb, 0xff, 0x0a, 0x6a, 0xa5, 0xff, 0x12, 0x9e, 0x7f, 0xff, 0x05, 0xaa, 0x6c, 0xff, 0x03, 0xa9, 0x72, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x05, 0xaa, 0x6e, 0xff, 0x05, 0xa8, 0x73, 0xff, 0x08, 0xa9, 0x72, 0xff, 0x06, 0xa8, 0x6f, 0xff, 0x06, 0xa8, 0x6b, 0xff, 0x06, 0xa9, 0x6a, 0xff, 0x07, 0xa8, 0x67, 0xff, 0x06, 0xa8, 0x67, 0xff, 0x07, 0xa7, 0x69, 0xff, 0x08, 0xa8, 0x6a, 0xff, 0x07, 0xa9, 0x68, 0xff, 0x07, 0xa8, 0x68, 0xff, 0x07, 0xa8, 0x67, 0xff, 0x08, 0xa8, 0x67, 0xff, 0x09, 0xa9, 0x67, 0xff, 0x09, 0xa9, 0x67, 0xff, 0x08, 0xa8, 0x66, 0xff, 0x08, 0xa8, 0x66, 0xff, 0x09, 0xa8, 0x68, 0xff, 0x0e, 0xab, 0x6b, 0xff, 0x13, 0xb0, 0x6f, 0xff, 0x11, 0xad, 0x6b, 0xff, 0x0b, 0xa5, 0x62, 0xff, 0x0a, 0xa4, 0x61, 0xff, 0x0a, 0xa3, 0x5e, 0xff, 0x0a, 0xa2, 0x5d, 0xff, 0x09, 0xa2, 0x5d, 0xff, 0x09, 0xa1, 0x5f, 0xff, 0x09, 0xa1, 0x5f, 0xff, 0x09, 0xa1, 0x5f, 0xff, 0x08, 0xa1, 0x5f, 0xff, 0x08, 0xa1, 0x5f, 0xff, 0x09, 0xa0, 0x5f, 0xff, 0x0a, 0xa0, 0x60, 0xff, 0x06, 0x9c, 0x61, 0xff, 0x02, 0x8c, 0x51, 0xff, 0x02, 0x83, 0x49, 0xff, 0x0a, 0x9b, 0x61, 0xff, 0x0f, 0xa6, 0x6b, 0xff, 0x0a, 0xa5, 0x68, 0xff, 0x0d, 0xa8, 0x68, 0xff, 0x0c, 0xa7, 0x67, 0xff, 0x0d, 0xa6, 0x63, 0xff, 0x08, 0xa0, 0x5d, 0xff, 0x0a, 0xa2, 0x60, 0xff, 0x0a, 0xa3, 0x62, 0xff, 0x0e, 0xa7, 0x67, 0xff, 0x0d, 0xa8, 0x6c, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x08, 0xa6, 0x6f, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x06, 0xa2, 0x64, 0xff, 0x07, 0xa2, 0x5c, 0xff, 0x05, 0xa0, 0x53, 0xff, 0x02, 0x9c, 0x49, 0xff, 0x03, 0x9a, 0x46, 0xff, 0x04, 0x99, 0x46, 0xff, 0x04, 0x99, 0x47, 0xff, 0x03, 0x99, 0x49, 0xff, 0x03, 0x9b, 0x4d, 0xff, 0x06, 0x9f, 0x55, 0xff, 0x0a, 0xa5, 0x5e, 0xff, 0x10, 0xac, 0x68, 0xff, 0x0f, 0xac, 0x6a, 0xff, 0x12, 0xb0, 0x6e, 0xff, 0x13, 0xb1, 0x70, 0xff, 0x12, 0xb1, 0x6e, 0xff, 0x13, 0xb1, 0x6f, 0xff, 0x0e, 0xac, 0x6a, 0xff, 0x0c, 0xab, 0x69, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x0c, 0xaa, 0x67, 0xff, 0x0a, 0xaa, 0x66, 0xff, 0x0b, 0xab, 0x66, 0xff, 0x0d, 0xab, 0x65, 0xff, 0x0d, 0xaa, 0x62, 0xff, 0x0c, 0xa7, 0x5c, 0xff, 0x0c, 0xa7, 0x5a, 0xff, 0x0c, 0xa5, 0x58, 0xff, 0x0c, 0xa5, 0x57, 0xff, 0x0c, 0xa3, 0x55, 0xff, 0x0d, 0xa4, 0x55, 0xff, 0x0e, 0xa4, 0x55, 0xff, 0x10, 0xa5, 0x56, 0xff, 0x10, 0xa5, 0x55, 0xff, 0x10, 0xa4, 0x54, 0xff, 0x11, 0xa4, 0x52, 0xff, 0x0f, 0xa2, 0x50, 0xff, 0x0d, 0xa2, 0x52, 0xff, 0x0a, 0xa1, 0x51, 0xff, 0x09, 0xa0, 0x4f, 0xff, 0x08, 0xa0, 0x4d, 0xff, 0x07, 0xa0, 0x4b, 0xff, 0x06, 0x9e, 0x49, 0xff, 0x06, 0x9c, 0x48, 0xff, 0x06, 0x9b, 0x47, 0xff, 0x07, 0x99, 0x42, 0xff, 0x05, 0x95, 0x3f, 0xff, 0x06, 0x97, 0x42, 0xff, 0x0b, 0x9e, 0x49, 0xff, 0x0f, 0xa2, 0x50, 0xff, 0x0d, 0xa2, 0x53, 0xff, 0x0c, 0xa3, 0x57, 0xff, 0x0c, 0xa2, 0x58, 0xff, 0x0c, 0xa1, 0x58, 0xff, 0x0b, 0x9f, 0x56, 0xff, 0x09, 0x9e, 0x54, 0xff, 0x05, 0x9d, 0x52, 0xff, 0x05, 0x9e, 0x51, 0xff, 0x05, 0x9f, 0x53, 0xff, 0x05, 0x9d, 0x54, 0xff, 0x05, 0x9c, 0x54, 0xff, 0x06, 0x9d, 0x53, 0xff, 0x05, 0x9d, 0x51, 0xff, 0x05, 0x9b, 0x54, 0xff, 0x06, 0x9b, 0x59, 0xff, 0x09, 0x9e, 0x5e, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x08, 0x9d, 0x5f, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x0a, 0x9e, 0x62, 0xff, 0x09, 0x9f, 0x64, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x0a, 0x9f, 0x67, 0xff, 0x09, 0x9d, 0x68, 0xff, 0x0a, 0x9e, 0x6a, 0xff, 0x0a, 0xa0, 0x6a, 0xff, 0x0b, 0xa1, 0x6b, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0b, 0xa4, 0x66, 0xff, 0x08, 0xa1, 0x64, 0xff, 0x08, 0xa1, 0x65, 0xff, 0x04, 0x9d, 0x62, 0xff, 0x07, 0xa2, 0x66, 0xff, 0x07, 0xa6, 0x68, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0e, 0xa2, 0x77, 0xff, 0x26, 0xb4, 0x99, 0xff, 0x51, 0xde, 0xc7, 0xff, 0x44, 0xd7, 0xb7, 0xff, 0x0f, 0xa8, 0x7a, 0xff, 0x06, 0xa6, 0x6f, 0xff, 0x05, 0xa4, 0x72, 0xff, 0x03, 0x9f, 0x70, 0xff, 0x04, 0x9e, 0x6d, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0b, 0xa4, 0x71, 0xff, 0x0d, 0xa5, 0x73, 0xff, 0x0a, 0xa4, 0x71, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x11, 0xa8, 0x72, 0xff, 0x13, 0xa8, 0x73, 0xff, 0x10, 0xa6, 0x6d, 0xff, 0x0e, 0xa7, 0x6b, 0xff, 0x0e, 0xa5, 0x68, 0xff, 0x12, 0xa4, 0x6b, 0xff, 0x1c, 0xa4, 0x70, 0xff, 0x43, 0xbb, 0x8f, 0xff, 0x40, 0xb9, 0x8d, 0xff, 0x32, 0xb2, 0x84, 0xff, 0x17, 0xa3, 0x73, 0xff, 0x12, 0xa7, 0x73, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x10, 0xa4, 0x6c, 0xff, 0x0f, 0xa2, 0x6b, 0xff, 0x11, 0xa4, 0x6c, 0xff, 0x0c, 0xa0, 0x67, 0xff, 0x0b, 0x9e, 0x66, 0xff, 0x0b, 0x9f, 0x65, 0xff, 0x0b, 0xa0, 0x65, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0c, 0xa3, 0x66, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0c, 0x9e, 0x68, 0xff, 0x0c, 0x9c, 0x67, 0xff, 0x0c, 0x9b, 0x66, 0xff, 0x0c, 0x9a, 0x65, 0xff, 0x09, 0x99, 0x64, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x0a, 0x9e, 0x68, 0xff, 0x08, 0x9d, 0x65, 0xff, 0x06, 0x9b, 0x63, 0xff, 0x03, 0x98, 0x5f, 0xff, 0x06, 0x99, 0x5f, 0xff, 0x07, 0x9c, 0x61, 0xff, 0x08, 0x9c, 0x65, 0xff, 0x09, 0x9c, 0x66, 0xff, 0x08, 0x9b, 0x65, 0xff, 0x09, 0x9a, 0x64, 0xff, 0x08, 0x9a, 0x62, 0xff, 0x08, 0x99, 0x61, 0xff, 0x09, 0x9b, 0x62, 0xff, 0x0b, 0x9f, 0x67, 0xff, 0x0b, 0xa2, 0x69, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x08, 0xa3, 0x69, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x07, 0xa2, 0x65, 0xff, 0x06, 0x9d, 0x5e, 0xff, 0x03, 0x97, 0x58, 0xff, 0x07, 0x94, 0x56, 0xff, 0x08, 0x92, 0x52, 0xff, 0x09, 0x93, 0x51, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x05, 0x93, 0x4e, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x08, 0x90, 0x4c, 0xff, 0x0a, 0x93, 0x4e, 0xff, 0x08, 0x8f, 0x4b, 0xff, 0x07, 0x8e, 0x4a, 0xff, 0x08, 0x8c, 0x49, 0xff, 0x0b, 0x8d, 0x4a, 0xff, 0x0b, 0x8a, 0x47, 0xff, 0x08, 0x83, 0x42, 0xff, 0x06, 0x80, 0x3f, 0xff, 0x08, 0x7f, 0x3e, 0xff, 0x07, 0x7f, 0x3f, 0xff, 0x07, 0x80, 0x3f, 0xff, 0x07, 0x7f, 0x41, 0xff, 0x08, 0x7e, 0x41, 0xff, 0x09, 0x7c, 0x41, 0xff, 0x07, 0x79, 0x3f, 0xff, 0x05, 0x7a, 0x38, 0xff, 0x06, 0x78, 0x36, 0xff, 0x09, 0x71, 0x36, 0xff, 0x0a, 0x65, 0x34, 0xff, 0x08, 0x58, 0x30, 0xff, 0x04, 0x4e, 0x2c, 0xff, 0x02, 0x4a, 0x2c, 0xff, 0x04, 0x4e, 0x31, 0xff, 0x0a, 0x51, 0x36, 0xff, 0x0d, 0x4e, 0x3e, 0xff, 0x09, 0x51, 0x33, 0xff, 0x0e, 0x51, 0x30, 0xff, 0x0e, 0x91, 0x61, 0xff, 0x16, 0xe7, 0x9e, 0xff, 0x17, 0xf0, 0x95, 0xff, 0x07, 0xd7, 0x68, 0xff, 0x15, 0xe5, 0x88, 0xff, 0x21, 0xe4, 0x9f, 0xff, 0x21, 0xcf, 0x87, 0xff, 0x12, 0xb2, 0x60, 0xff, 0x0c, 0xaa, 0x48, 0xff, 0x02, 0x8a, 0x22, 0xff, 0x00, 0x82, 0x1e, 0xff, 0x02, 0x79, 0x1d, 0xff, 0x11, 0xa2, 0x40, 0xff, 0x05, 0x96, 0x2e, 0xff, 0x08, 0x82, 0x28, 0xff, 0x08, 0x87, 0x31, 0xff, 0x0a, 0x99, 0x46, 0xff, 0x13, 0x90, 0x50, 0xff, 0x0e, 0x70, 0x38, 0xff, 0x6b, 0x92, 0x75, 0xff, + 0x16, 0x74, 0x3f, 0xff, 0x01, 0x39, 0x18, 0xff, 0x08, 0x3f, 0x25, 0xff, 0x07, 0x5d, 0x29, 0xff, 0x13, 0x86, 0x42, 0xff, 0x0b, 0x5f, 0x35, 0xff, 0x01, 0x39, 0x1f, 0xff, 0x09, 0x65, 0x32, 0xff, 0x1f, 0x9c, 0x55, 0xff, 0x03, 0x72, 0x31, 0xff, 0x02, 0x64, 0x27, 0xff, 0x02, 0x75, 0x3a, 0xff, 0x2e, 0xa4, 0x84, 0xff, 0x5e, 0xb8, 0xca, 0xff, 0x65, 0xbe, 0xda, 0xff, 0x73, 0xcf, 0xea, 0xff, 0x73, 0xd2, 0xed, 0xff, 0x20, 0x8a, 0x83, 0xff, 0x0a, 0x8b, 0x5a, 0xff, 0x0c, 0xa4, 0x55, 0xff, 0x10, 0xb1, 0x60, 0xff, 0x14, 0xa3, 0x5f, 0xff, 0x02, 0x60, 0x2b, 0xff, 0x0f, 0x7f, 0x4f, 0xff, 0x17, 0xa0, 0x6b, 0xff, 0x11, 0xa1, 0x69, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x11, 0x9e, 0x6a, 0xff, 0x09, 0x91, 0x5c, 0xff, 0x16, 0xa6, 0x6b, 0xff, 0x08, 0x86, 0x48, 0xff, 0x0b, 0x93, 0x53, 0xff, 0x06, 0x8d, 0x51, 0xff, 0x13, 0x86, 0x74, 0xff, 0x10, 0x61, 0x92, 0xff, 0x15, 0x48, 0xbc, 0xff, 0x08, 0x2e, 0xcc, 0xff, 0x03, 0x2c, 0xd3, 0xff, 0x0a, 0x3e, 0xe4, 0xff, 0x06, 0x46, 0xea, 0xff, 0x03, 0x4d, 0xe0, 0xff, 0x0c, 0x60, 0xed, 0xff, 0x0e, 0x65, 0xf5, 0xff, 0x08, 0x63, 0xf4, 0xff, 0x07, 0x62, 0xee, 0xff, 0x13, 0x70, 0xf7, 0xff, 0x11, 0x65, 0xef, 0xff, 0x06, 0x4f, 0xbe, 0xff, 0x08, 0x7a, 0x8c, 0xff, 0x0e, 0xa9, 0x70, 0xff, 0x06, 0xa9, 0x70, 0xff, 0x05, 0xaa, 0x6e, 0xff, 0x06, 0xa8, 0x71, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x07, 0xaa, 0x6f, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x08, 0xa7, 0x69, 0xff, 0x09, 0xa8, 0x69, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0b, 0xa9, 0x68, 0xff, 0x0a, 0xa7, 0x67, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0a, 0xa9, 0x67, 0xff, 0x0a, 0xa9, 0x67, 0xff, 0x09, 0xa9, 0x67, 0xff, 0x08, 0xa9, 0x67, 0xff, 0x08, 0xa9, 0x65, 0xff, 0x08, 0xa9, 0x66, 0xff, 0x09, 0xa9, 0x68, 0xff, 0x0d, 0xab, 0x69, 0xff, 0x11, 0xac, 0x6b, 0xff, 0x10, 0xab, 0x69, 0xff, 0x0a, 0xa2, 0x60, 0xff, 0x0a, 0xa1, 0x5d, 0xff, 0x0b, 0xa2, 0x5d, 0xff, 0x0b, 0xa2, 0x5d, 0xff, 0x0b, 0xa2, 0x5d, 0xff, 0x0b, 0xa2, 0x5d, 0xff, 0x08, 0xa0, 0x5e, 0xff, 0x08, 0xa0, 0x5e, 0xff, 0x09, 0x9f, 0x5e, 0xff, 0x09, 0x9e, 0x5e, 0xff, 0x0b, 0x9e, 0x60, 0xff, 0x0a, 0x9e, 0x5f, 0xff, 0x0a, 0xa0, 0x65, 0xff, 0x0e, 0xa1, 0x67, 0xff, 0x11, 0xa0, 0x66, 0xff, 0x11, 0xa2, 0x66, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x08, 0xa1, 0x62, 0xff, 0x0a, 0xa4, 0x63, 0xff, 0x09, 0xa2, 0x60, 0xff, 0x09, 0xa0, 0x5a, 0xff, 0x09, 0x9f, 0x5a, 0xff, 0x0c, 0xa1, 0x5e, 0xff, 0x0b, 0xa1, 0x5f, 0xff, 0x0e, 0xa5, 0x66, 0xff, 0x0c, 0xa6, 0x6a, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x07, 0xa0, 0x69, 0xff, 0x06, 0x9f, 0x63, 0xff, 0x08, 0xa2, 0x5b, 0xff, 0x06, 0xa1, 0x51, 0xff, 0x04, 0x9d, 0x47, 0xff, 0x06, 0x9d, 0x46, 0xff, 0x08, 0x9b, 0x47, 0xff, 0x07, 0x99, 0x47, 0xff, 0x04, 0x97, 0x46, 0xff, 0x02, 0x96, 0x47, 0xff, 0x03, 0x9a, 0x4c, 0xff, 0x07, 0x9f, 0x54, 0xff, 0x0a, 0xa4, 0x5c, 0xff, 0x0c, 0xa7, 0x61, 0xff, 0x0c, 0xa9, 0x65, 0xff, 0x0d, 0xab, 0x68, 0xff, 0x0e, 0xac, 0x68, 0xff, 0x0f, 0xad, 0x69, 0xff, 0x0f, 0xab, 0x68, 0xff, 0x0d, 0xaa, 0x67, 0xff, 0x0e, 0xab, 0x68, 0xff, 0x0d, 0xaa, 0x67, 0xff, 0x0d, 0xaa, 0x67, 0xff, 0x0d, 0xaa, 0x67, 0xff, 0x0b, 0xab, 0x68, 0xff, 0x0c, 0xab, 0x66, 0xff, 0x0d, 0xaa, 0x62, 0xff, 0x0d, 0xa8, 0x5e, 0xff, 0x0d, 0xa7, 0x59, 0xff, 0x0d, 0xa6, 0x56, 0xff, 0x0d, 0xa5, 0x55, 0xff, 0x0d, 0xa4, 0x53, 0xff, 0x0d, 0xa2, 0x51, 0xff, 0x0c, 0xa2, 0x51, 0xff, 0x0d, 0xa2, 0x51, 0xff, 0x0e, 0xa1, 0x51, 0xff, 0x0e, 0xa1, 0x4f, 0xff, 0x0e, 0xa1, 0x4f, 0xff, 0x0f, 0xa2, 0x4e, 0xff, 0x0e, 0xa1, 0x4d, 0xff, 0x0b, 0xa0, 0x4f, 0xff, 0x08, 0x9f, 0x4f, 0xff, 0x07, 0x9f, 0x4d, 0xff, 0x07, 0x9f, 0x4b, 0xff, 0x07, 0x9e, 0x49, 0xff, 0x08, 0x9e, 0x48, 0xff, 0x08, 0x9d, 0x46, 0xff, 0x08, 0x9b, 0x43, 0xff, 0x09, 0x97, 0x3f, 0xff, 0x04, 0x91, 0x39, 0xff, 0x03, 0x92, 0x3a, 0xff, 0x05, 0x97, 0x3f, 0xff, 0x0a, 0x9e, 0x49, 0xff, 0x0b, 0xa0, 0x4e, 0xff, 0x0b, 0xa1, 0x51, 0xff, 0x09, 0x9e, 0x52, 0xff, 0x05, 0x99, 0x4c, 0xff, 0x03, 0x97, 0x48, 0xff, 0x04, 0x9a, 0x4b, 0xff, 0x03, 0x9a, 0x4b, 0xff, 0x04, 0x9d, 0x4d, 0xff, 0x02, 0x9c, 0x4c, 0xff, 0x02, 0x9d, 0x4d, 0xff, 0x03, 0x9d, 0x4e, 0xff, 0x03, 0x9e, 0x4d, 0xff, 0x04, 0x9e, 0x4e, 0xff, 0x05, 0x9d, 0x52, 0xff, 0x07, 0x9c, 0x58, 0xff, 0x09, 0x9e, 0x5d, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0b, 0x9f, 0x66, 0xff, 0x09, 0x9e, 0x67, 0xff, 0x08, 0x9c, 0x67, 0xff, 0x0a, 0x9d, 0x69, 0xff, 0x0b, 0x9f, 0x6a, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0a, 0xa3, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x06, 0xa1, 0x64, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x06, 0xa2, 0x66, 0xff, 0x03, 0xa1, 0x64, 0xff, 0x08, 0xa9, 0x6c, 0xff, 0x0e, 0xa8, 0x73, 0xff, 0x0f, 0xa1, 0x79, 0xff, 0x2e, 0xb9, 0x9e, 0xff, 0x3a, 0xc6, 0xaf, 0xff, 0x1e, 0xaf, 0x90, 0xff, 0x0c, 0xa6, 0x7a, 0xff, 0x15, 0xb6, 0x84, 0xff, 0x0b, 0xa9, 0x7e, 0xff, 0x15, 0xb1, 0x84, 0xff, 0x09, 0xa1, 0x73, 0xff, 0x0b, 0xa2, 0x71, 0xff, 0x0d, 0xa4, 0x72, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0c, 0xa7, 0x74, 0xff, 0x0c, 0xa9, 0x75, 0xff, 0x09, 0xa8, 0x6d, 0xff, 0x11, 0xac, 0x71, 0xff, 0x11, 0xa9, 0x6e, 0xff, 0x18, 0xb1, 0x72, 0xff, 0x0e, 0xa8, 0x66, 0xff, 0x10, 0xa8, 0x65, 0xff, 0x13, 0xa5, 0x66, 0xff, 0x36, 0xb4, 0x7f, 0xff, 0x81, 0xdb, 0xb5, 0xff, 0x75, 0xce, 0xa7, 0xff, 0x5a, 0xbb, 0x92, 0xff, 0x27, 0x9b, 0x6f, 0xff, 0x19, 0x9d, 0x6b, 0xff, 0x14, 0xa7, 0x71, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x11, 0xa7, 0x6f, 0xff, 0x12, 0xa9, 0x70, 0xff, 0x13, 0xa9, 0x72, 0xff, 0x13, 0xa9, 0x73, 0xff, 0x0e, 0xa4, 0x70, 0xff, 0x08, 0x9e, 0x68, 0xff, 0x07, 0x9c, 0x65, 0xff, 0x09, 0x9f, 0x64, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x08, 0xa1, 0x68, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa2, 0x6c, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x0d, 0x9f, 0x69, 0xff, 0x0b, 0x9b, 0x66, 0xff, 0x09, 0x95, 0x60, 0xff, 0x05, 0x92, 0x5d, 0xff, 0x02, 0x92, 0x5d, 0xff, 0x0a, 0x9c, 0x68, 0xff, 0x0c, 0xa0, 0x6c, 0xff, 0x0b, 0xa1, 0x6c, 0xff, 0x09, 0xa0, 0x6b, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x08, 0x9f, 0x69, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x08, 0x9f, 0x6a, 0xff, 0x07, 0x9c, 0x66, 0xff, 0x05, 0x98, 0x62, 0xff, 0x07, 0x9a, 0x64, 0xff, 0x0a, 0x9f, 0x69, 0xff, 0x09, 0xa1, 0x6b, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x05, 0xa1, 0x69, 0xff, 0x07, 0xa3, 0x68, 0xff, 0x08, 0xa1, 0x64, 0xff, 0x04, 0x9a, 0x5b, 0xff, 0x04, 0x96, 0x56, 0xff, 0x05, 0x94, 0x55, 0xff, 0x08, 0x93, 0x53, 0xff, 0x08, 0x90, 0x4f, 0xff, 0x07, 0x90, 0x4d, 0xff, 0x06, 0x92, 0x4e, 0xff, 0x04, 0x93, 0x4e, 0xff, 0x06, 0x94, 0x4f, 0xff, 0x09, 0x92, 0x4e, 0xff, 0x0a, 0x92, 0x4c, 0xff, 0x07, 0x8e, 0x4a, 0xff, 0x07, 0x8c, 0x49, 0xff, 0x08, 0x8c, 0x49, 0xff, 0x09, 0x8c, 0x49, 0xff, 0x0b, 0x8b, 0x48, 0xff, 0x09, 0x86, 0x43, 0xff, 0x05, 0x80, 0x3f, 0xff, 0x08, 0x80, 0x40, 0xff, 0x0a, 0x7f, 0x40, 0xff, 0x09, 0x7e, 0x3f, 0xff, 0x09, 0x7f, 0x41, 0xff, 0x09, 0x7e, 0x41, 0xff, 0x07, 0x7c, 0x40, 0xff, 0x06, 0x7a, 0x3f, 0xff, 0x05, 0x78, 0x3d, 0xff, 0x06, 0x83, 0x3d, 0xff, 0x0e, 0x8f, 0x46, 0xff, 0x0a, 0x7e, 0x3a, 0xff, 0x09, 0x68, 0x31, 0xff, 0x06, 0x57, 0x28, 0xff, 0x01, 0x45, 0x1f, 0xff, 0x00, 0x3d, 0x1a, 0xff, 0x04, 0x3d, 0x1d, 0xff, 0x04, 0x42, 0x27, 0xff, 0x0d, 0x4e, 0x37, 0xff, 0x0c, 0x5f, 0x38, 0xff, 0x06, 0x54, 0x2f, 0xff, 0x09, 0x82, 0x50, 0xff, 0x13, 0xe2, 0x96, 0xff, 0x0c, 0xee, 0x9f, 0xff, 0x08, 0xdc, 0x82, 0xff, 0x07, 0xce, 0x71, 0xff, 0x0b, 0xc9, 0x74, 0xff, 0x14, 0xc9, 0x72, 0xff, 0x07, 0xa8, 0x4f, 0xff, 0x0a, 0xa5, 0x44, 0xff, 0x03, 0x8a, 0x26, 0xff, 0x00, 0x80, 0x1f, 0xff, 0x04, 0x81, 0x25, 0xff, 0x0d, 0x97, 0x39, 0xff, 0x01, 0x8a, 0x28, 0xff, 0x03, 0x80, 0x27, 0xff, 0x20, 0xae, 0x5a, 0xff, 0x15, 0xb2, 0x60, 0xff, 0x17, 0xab, 0x63, 0xff, 0x15, 0x93, 0x50, 0xff, 0x70, 0xa9, 0x85, 0xff, + 0x0d, 0x58, 0x2f, 0xff, 0x00, 0x32, 0x19, 0xff, 0x05, 0x3c, 0x23, 0xff, 0x0e, 0x66, 0x32, 0xff, 0x16, 0x84, 0x44, 0xff, 0x04, 0x4c, 0x2b, 0xff, 0x01, 0x33, 0x20, 0xff, 0x03, 0x4d, 0x24, 0xff, 0x23, 0x9a, 0x5f, 0xff, 0x12, 0x92, 0x4a, 0xff, 0x07, 0x6f, 0x29, 0xff, 0x04, 0x67, 0x2b, 0xff, 0x19, 0x87, 0x5c, 0xff, 0x57, 0xbb, 0xba, 0xff, 0x5f, 0xbb, 0xd1, 0xff, 0x6f, 0xc7, 0xe1, 0xff, 0x7d, 0xd9, 0xe9, 0xff, 0x3a, 0xa6, 0x91, 0xff, 0x0d, 0x92, 0x56, 0xff, 0x06, 0xac, 0x56, 0xff, 0x11, 0xb4, 0x65, 0xff, 0x11, 0x82, 0x48, 0xff, 0x02, 0x52, 0x22, 0xff, 0x18, 0x92, 0x61, 0xff, 0x10, 0xa2, 0x6e, 0xff, 0x11, 0xa0, 0x6b, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x06, 0x98, 0x5e, 0xff, 0x11, 0xa3, 0x66, 0xff, 0x0c, 0x93, 0x58, 0xff, 0x04, 0x73, 0x3c, 0xff, 0x07, 0x92, 0x51, 0xff, 0x0b, 0x89, 0x57, 0xff, 0x05, 0x5a, 0x81, 0xff, 0x01, 0x3a, 0xa3, 0xff, 0x03, 0x30, 0xc7, 0xff, 0x01, 0x24, 0xd8, 0xff, 0x06, 0x36, 0xda, 0xff, 0x06, 0x3c, 0xdd, 0xff, 0x01, 0x41, 0xe4, 0xff, 0x04, 0x4d, 0xe9, 0xff, 0x0c, 0x60, 0xef, 0xff, 0x0d, 0x67, 0xf2, 0xff, 0x08, 0x64, 0xf3, 0xff, 0x06, 0x62, 0xf4, 0xff, 0x09, 0x65, 0xf3, 0xff, 0x09, 0x5b, 0xec, 0xff, 0x02, 0x3f, 0xd0, 0xff, 0x02, 0x4f, 0x9e, 0xff, 0x14, 0x96, 0x7e, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x04, 0xa9, 0x6c, 0xff, 0x05, 0xaa, 0x73, 0xff, 0x08, 0xaa, 0x6f, 0xff, 0x0b, 0xaa, 0x6b, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x68, 0xff, 0x0b, 0xa8, 0x67, 0xff, 0x0b, 0xa7, 0x66, 0xff, 0x0b, 0xa8, 0x67, 0xff, 0x0c, 0xa9, 0x68, 0xff, 0x0d, 0xa8, 0x67, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0b, 0xa8, 0x66, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0a, 0xa9, 0x67, 0xff, 0x0a, 0xa9, 0x67, 0xff, 0x08, 0xa9, 0x66, 0xff, 0x08, 0xa9, 0x66, 0xff, 0x0a, 0xa8, 0x67, 0xff, 0x0a, 0xa7, 0x66, 0xff, 0x0b, 0xa5, 0x64, 0xff, 0x0a, 0xa1, 0x60, 0xff, 0x10, 0xa5, 0x63, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0a, 0xa0, 0x5c, 0xff, 0x0a, 0xa0, 0x5c, 0xff, 0x0b, 0xa1, 0x5e, 0xff, 0x0a, 0xa1, 0x5d, 0xff, 0x07, 0x9f, 0x5d, 0xff, 0x07, 0x9f, 0x5e, 0xff, 0x08, 0x9f, 0x5f, 0xff, 0x08, 0x9d, 0x5e, 0xff, 0x09, 0x9c, 0x5e, 0xff, 0x07, 0x9b, 0x5d, 0xff, 0x05, 0x9b, 0x5f, 0xff, 0x0a, 0x9c, 0x61, 0xff, 0x11, 0xa1, 0x65, 0xff, 0x0d, 0xa0, 0x61, 0xff, 0x0a, 0xa0, 0x60, 0xff, 0x09, 0xa0, 0x5f, 0xff, 0x08, 0xa1, 0x5f, 0xff, 0x08, 0x9f, 0x5d, 0xff, 0x09, 0x9e, 0x57, 0xff, 0x0c, 0xa1, 0x5a, 0xff, 0x0e, 0xa2, 0x5d, 0xff, 0x0a, 0x9f, 0x5c, 0xff, 0x0e, 0xa4, 0x63, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x07, 0x9f, 0x64, 0xff, 0x07, 0xa1, 0x5b, 0xff, 0x07, 0xa1, 0x53, 0xff, 0x05, 0x9f, 0x49, 0xff, 0x07, 0x9e, 0x45, 0xff, 0x09, 0x9c, 0x47, 0xff, 0x09, 0x98, 0x47, 0xff, 0x04, 0x97, 0x43, 0xff, 0x03, 0x96, 0x44, 0xff, 0x05, 0x99, 0x48, 0xff, 0x07, 0x9d, 0x4f, 0xff, 0x0a, 0xa2, 0x57, 0xff, 0x0b, 0xa6, 0x5d, 0xff, 0x0b, 0xa7, 0x61, 0xff, 0x0a, 0xa8, 0x63, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x0e, 0xab, 0x66, 0xff, 0x0d, 0xaa, 0x66, 0xff, 0x0d, 0xab, 0x66, 0xff, 0x0d, 0xab, 0x66, 0xff, 0x0e, 0xab, 0x66, 0xff, 0x0d, 0xab, 0x66, 0xff, 0x0c, 0xaa, 0x65, 0xff, 0x0d, 0xab, 0x65, 0xff, 0x0c, 0xa8, 0x5f, 0xff, 0x0b, 0xa6, 0x5a, 0xff, 0x0d, 0xa5, 0x54, 0xff, 0x0f, 0xa4, 0x52, 0xff, 0x0e, 0xa2, 0x50, 0xff, 0x0d, 0xa2, 0x4e, 0xff, 0x0b, 0xa1, 0x4d, 0xff, 0x0c, 0xa0, 0x4d, 0xff, 0x0c, 0xa0, 0x4d, 0xff, 0x0c, 0x9f, 0x4c, 0xff, 0x0c, 0x9f, 0x4c, 0xff, 0x0c, 0x9f, 0x4c, 0xff, 0x0b, 0x9e, 0x4a, 0xff, 0x0a, 0x9d, 0x49, 0xff, 0x09, 0x9f, 0x4c, 0xff, 0x08, 0x9d, 0x4c, 0xff, 0x09, 0x9f, 0x4c, 0xff, 0x08, 0xa0, 0x4a, 0xff, 0x08, 0x9f, 0x47, 0xff, 0x0a, 0x9f, 0x47, 0xff, 0x08, 0x9a, 0x44, 0xff, 0x05, 0x95, 0x3f, 0xff, 0x05, 0x90, 0x3b, 0xff, 0x02, 0x8c, 0x37, 0xff, 0x03, 0x91, 0x3c, 0xff, 0x02, 0x92, 0x3d, 0xff, 0x03, 0x96, 0x42, 0xff, 0x04, 0x98, 0x44, 0xff, 0x03, 0x96, 0x45, 0xff, 0x02, 0x95, 0x46, 0xff, 0x03, 0x96, 0x46, 0xff, 0x04, 0x98, 0x45, 0xff, 0x04, 0x99, 0x47, 0xff, 0x07, 0x9d, 0x4a, 0xff, 0x06, 0x9d, 0x4b, 0xff, 0x04, 0x9e, 0x4b, 0xff, 0x05, 0xa1, 0x4c, 0xff, 0x03, 0x9f, 0x4a, 0xff, 0x02, 0x9d, 0x49, 0xff, 0x04, 0x9d, 0x4c, 0xff, 0x07, 0x9f, 0x54, 0xff, 0x09, 0x9f, 0x5a, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x0b, 0x9f, 0x62, 0xff, 0x0a, 0x9d, 0x62, 0xff, 0x08, 0x9c, 0x61, 0xff, 0x09, 0x9e, 0x5f, 0xff, 0x08, 0x9e, 0x5d, 0xff, 0x08, 0x9d, 0x5e, 0xff, 0x08, 0x9c, 0x5f, 0xff, 0x0a, 0x9e, 0x64, 0xff, 0x09, 0x9e, 0x66, 0xff, 0x09, 0x9d, 0x68, 0xff, 0x09, 0x9c, 0x68, 0xff, 0x0a, 0x9e, 0x69, 0xff, 0x09, 0xa1, 0x6a, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x06, 0xa2, 0x66, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x08, 0xa5, 0x68, 0xff, 0x0c, 0xaa, 0x6c, 0xff, 0x0d, 0xac, 0x70, 0xff, 0x08, 0xaa, 0x6d, 0xff, 0x0a, 0xac, 0x71, 0xff, 0x12, 0xae, 0x78, 0xff, 0x17, 0xac, 0x7f, 0xff, 0x50, 0xe0, 0xbc, 0xff, 0x28, 0xb6, 0x97, 0xff, 0x08, 0x9b, 0x78, 0xff, 0x16, 0xb0, 0x86, 0xff, 0x1b, 0xb9, 0x8e, 0xff, 0x2a, 0xc3, 0x9f, 0xff, 0x40, 0xd8, 0xaf, 0xff, 0x16, 0xad, 0x81, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x0f, 0xa6, 0x74, 0xff, 0x10, 0xaa, 0x75, 0xff, 0x0e, 0xa9, 0x76, 0xff, 0x0e, 0xac, 0x76, 0xff, 0x0f, 0xb0, 0x72, 0xff, 0x10, 0xac, 0x6d, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x19, 0xb6, 0x70, 0xff, 0x0b, 0xa9, 0x5f, 0xff, 0x15, 0xaf, 0x66, 0xff, 0x14, 0xa8, 0x63, 0xff, 0x44, 0xc1, 0x88, 0xff, 0x75, 0xc8, 0xa0, 0xff, 0x69, 0xb4, 0x8e, 0xff, 0x48, 0x94, 0x6e, 0xff, 0x3e, 0x9e, 0x73, 0xff, 0x27, 0x9d, 0x6d, 0xff, 0x1b, 0xa6, 0x71, 0xff, 0x14, 0xa6, 0x70, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x09, 0xa0, 0x6f, 0xff, 0x05, 0x9c, 0x68, 0xff, 0x07, 0xa0, 0x68, 0xff, 0x07, 0x9f, 0x65, 0xff, 0x04, 0x9d, 0x65, 0xff, 0x06, 0x9e, 0x66, 0xff, 0x0a, 0xa1, 0x69, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0d, 0xa3, 0x6c, 0xff, 0x0d, 0xa2, 0x6c, 0xff, 0x0c, 0xa0, 0x6a, 0xff, 0x0b, 0x9e, 0x68, 0xff, 0x0e, 0x9a, 0x67, 0xff, 0x05, 0x92, 0x5e, 0xff, 0x05, 0x95, 0x61, 0xff, 0x0c, 0x9e, 0x6a, 0xff, 0x09, 0xa0, 0x6b, 0xff, 0x08, 0xa1, 0x6c, 0xff, 0x09, 0xa1, 0x6d, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x07, 0xa2, 0x6b, 0xff, 0x07, 0xa3, 0x6b, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x08, 0xa3, 0x6f, 0xff, 0x09, 0xa1, 0x6e, 0xff, 0x08, 0xa0, 0x6b, 0xff, 0x08, 0x9f, 0x6a, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x07, 0x9f, 0x6a, 0xff, 0x06, 0xa0, 0x6b, 0xff, 0x05, 0xa1, 0x6a, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x05, 0x9a, 0x5c, 0xff, 0x05, 0x95, 0x55, 0xff, 0x09, 0x94, 0x53, 0xff, 0x09, 0x93, 0x54, 0xff, 0x08, 0x8f, 0x50, 0xff, 0x08, 0x8e, 0x4b, 0xff, 0x09, 0x90, 0x4d, 0xff, 0x07, 0x92, 0x4d, 0xff, 0x05, 0x94, 0x4d, 0xff, 0x07, 0x93, 0x4e, 0xff, 0x07, 0x90, 0x4c, 0xff, 0x09, 0x8f, 0x4a, 0xff, 0x07, 0x8c, 0x48, 0xff, 0x07, 0x8b, 0x48, 0xff, 0x0b, 0x8d, 0x4a, 0xff, 0x0b, 0x8b, 0x48, 0xff, 0x08, 0x85, 0x44, 0xff, 0x06, 0x81, 0x40, 0xff, 0x06, 0x80, 0x40, 0xff, 0x09, 0x7f, 0x40, 0xff, 0x0a, 0x7f, 0x40, 0xff, 0x0a, 0x7e, 0x40, 0xff, 0x0b, 0x7f, 0x41, 0xff, 0x09, 0x7c, 0x40, 0xff, 0x08, 0x7b, 0x40, 0xff, 0x07, 0x79, 0x3f, 0xff, 0x0a, 0x7c, 0x42, 0xff, 0x1e, 0x9e, 0x5c, 0xff, 0x1c, 0x9c, 0x57, 0xff, 0x09, 0x7b, 0x3c, 0xff, 0x02, 0x62, 0x2c, 0xff, 0x08, 0x5d, 0x2f, 0xff, 0x0e, 0x59, 0x30, 0xff, 0x08, 0x49, 0x26, 0xff, 0x03, 0x3c, 0x1d, 0xff, 0x01, 0x3a, 0x1b, 0xff, 0x06, 0x48, 0x25, 0xff, 0x1d, 0x8c, 0x55, 0xff, 0x03, 0x6a, 0x38, 0xff, 0x03, 0x7a, 0x41, 0xff, 0x14, 0xdc, 0x91, 0xff, 0x0b, 0xe9, 0x9f, 0xff, 0x04, 0xd3, 0x80, 0xff, 0x01, 0xb4, 0x52, 0xff, 0x05, 0xb3, 0x50, 0xff, 0x08, 0xaa, 0x48, 0xff, 0x07, 0x91, 0x36, 0xff, 0x0a, 0x90, 0x33, 0xff, 0x05, 0x87, 0x29, 0xff, 0x04, 0x7c, 0x23, 0xff, 0x0f, 0x81, 0x2a, 0xff, 0x12, 0x85, 0x30, 0xff, 0x03, 0x74, 0x1b, 0xff, 0x0d, 0x86, 0x33, 0xff, 0x14, 0x96, 0x49, 0xff, 0x09, 0x92, 0x46, 0xff, 0x05, 0x8c, 0x43, 0xff, 0x09, 0x89, 0x3e, 0xff, 0x6e, 0xac, 0x84, 0xff, + 0x05, 0x43, 0x23, 0xff, 0x00, 0x33, 0x1e, 0xff, 0x04, 0x40, 0x26, 0xff, 0x0f, 0x68, 0x36, 0xff, 0x18, 0x7e, 0x45, 0xff, 0x03, 0x41, 0x27, 0xff, 0x02, 0x31, 0x21, 0xff, 0x00, 0x39, 0x1d, 0xff, 0x12, 0x7c, 0x4e, 0xff, 0x14, 0x9f, 0x54, 0xff, 0x0c, 0x7b, 0x30, 0xff, 0x04, 0x64, 0x25, 0xff, 0x07, 0x71, 0x3a, 0xff, 0x46, 0xb3, 0x9d, 0xff, 0x60, 0xbf, 0xc9, 0xff, 0x6e, 0xc6, 0xd7, 0xff, 0x6d, 0xcb, 0xcb, 0xff, 0x2a, 0x9d, 0x76, 0xff, 0x0a, 0x98, 0x50, 0xff, 0x01, 0xaf, 0x57, 0xff, 0x14, 0xb2, 0x6b, 0xff, 0x07, 0x61, 0x33, 0xff, 0x01, 0x4e, 0x23, 0xff, 0x19, 0x94, 0x62, 0xff, 0x0d, 0xa1, 0x6d, 0xff, 0x14, 0xa0, 0x6c, 0xff, 0x09, 0x99, 0x5e, 0xff, 0x01, 0x97, 0x56, 0xff, 0x18, 0xad, 0x6d, 0xff, 0x04, 0x75, 0x3f, 0xff, 0x0e, 0x7e, 0x4b, 0xff, 0x06, 0x8e, 0x4d, 0xff, 0x0c, 0x7d, 0x5d, 0xff, 0x04, 0x43, 0x9b, 0xff, 0x03, 0x37, 0xb6, 0xff, 0x00, 0x36, 0xc5, 0xff, 0x00, 0x30, 0xdf, 0xff, 0x09, 0x3f, 0xe2, 0xff, 0x08, 0x41, 0xe2, 0xff, 0x02, 0x46, 0xe5, 0xff, 0x02, 0x4b, 0xe9, 0xff, 0x0f, 0x63, 0xf3, 0xff, 0x15, 0x70, 0xf8, 0xff, 0x07, 0x64, 0xf2, 0xff, 0x07, 0x63, 0xf8, 0xff, 0x0d, 0x67, 0xf9, 0xff, 0x0e, 0x63, 0xf4, 0xff, 0x04, 0x43, 0xe1, 0xff, 0x00, 0x38, 0xb6, 0xff, 0x0d, 0x72, 0x8c, 0xff, 0x17, 0x9b, 0x83, 0xff, 0x07, 0xa7, 0x73, 0xff, 0x02, 0xa8, 0x72, 0xff, 0x07, 0xa9, 0x6c, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0a, 0xa8, 0x6a, 0xff, 0x09, 0xa8, 0x6a, 0xff, 0x0b, 0xa7, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0c, 0xa8, 0x67, 0xff, 0x0c, 0xa8, 0x67, 0xff, 0x0c, 0xa8, 0x67, 0xff, 0x0b, 0xa8, 0x67, 0xff, 0x0c, 0xa8, 0x68, 0xff, 0x0c, 0xa8, 0x68, 0xff, 0x0c, 0xa9, 0x68, 0xff, 0x0c, 0xaa, 0x68, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x09, 0xa9, 0x66, 0xff, 0x09, 0xa9, 0x66, 0xff, 0x0a, 0xa7, 0x68, 0xff, 0x09, 0xa3, 0x63, 0xff, 0x09, 0xa0, 0x60, 0xff, 0x06, 0x9b, 0x5b, 0xff, 0x0a, 0x9e, 0x5c, 0xff, 0x15, 0xa9, 0x67, 0xff, 0x0b, 0x9f, 0x5c, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0b, 0xa0, 0x5e, 0xff, 0x09, 0x9e, 0x5d, 0xff, 0x07, 0x9e, 0x5e, 0xff, 0x07, 0x9f, 0x5e, 0xff, 0x06, 0x9e, 0x5e, 0xff, 0x06, 0x9c, 0x5d, 0xff, 0x07, 0x9b, 0x5c, 0xff, 0x08, 0x9b, 0x5d, 0xff, 0x04, 0x9c, 0x5f, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x10, 0xa1, 0x63, 0xff, 0x0d, 0xa0, 0x60, 0xff, 0x09, 0x9f, 0x5d, 0xff, 0x07, 0x9f, 0x5d, 0xff, 0x07, 0x9e, 0x5c, 0xff, 0x08, 0x9e, 0x5c, 0xff, 0x0c, 0xa0, 0x59, 0xff, 0x0e, 0xa2, 0x5a, 0xff, 0x0e, 0xa2, 0x5b, 0xff, 0x0b, 0xa0, 0x5b, 0xff, 0x0c, 0xa1, 0x5f, 0xff, 0x0d, 0xa5, 0x66, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x09, 0xa2, 0x66, 0xff, 0x07, 0xa2, 0x5c, 0xff, 0x07, 0xa3, 0x55, 0xff, 0x06, 0xa0, 0x4d, 0xff, 0x06, 0x9d, 0x47, 0xff, 0x08, 0x9a, 0x47, 0xff, 0x08, 0x98, 0x47, 0xff, 0x04, 0x96, 0x43, 0xff, 0x03, 0x96, 0x43, 0xff, 0x04, 0x97, 0x47, 0xff, 0x07, 0x9b, 0x4c, 0xff, 0x0b, 0xa2, 0x55, 0xff, 0x0c, 0xa5, 0x5a, 0xff, 0x0c, 0xa8, 0x5f, 0xff, 0x0c, 0xa8, 0x61, 0xff, 0x0d, 0xaa, 0x63, 0xff, 0x0d, 0xab, 0x64, 0xff, 0x0e, 0xab, 0x64, 0xff, 0x0e, 0xab, 0x65, 0xff, 0x0e, 0xab, 0x65, 0xff, 0x0e, 0xab, 0x65, 0xff, 0x0f, 0xac, 0x66, 0xff, 0x0e, 0xac, 0x65, 0xff, 0x0d, 0xab, 0x65, 0xff, 0x0c, 0xab, 0x63, 0xff, 0x0a, 0xa6, 0x5a, 0xff, 0x0b, 0xa4, 0x54, 0xff, 0x0d, 0xa4, 0x51, 0xff, 0x0f, 0xa4, 0x4f, 0xff, 0x0d, 0xa1, 0x4d, 0xff, 0x0c, 0xa0, 0x4c, 0xff, 0x0b, 0x9e, 0x4a, 0xff, 0x0a, 0x9e, 0x4a, 0xff, 0x0b, 0x9e, 0x49, 0xff, 0x0a, 0x9d, 0x48, 0xff, 0x0a, 0x9c, 0x48, 0xff, 0x0a, 0x9d, 0x48, 0xff, 0x09, 0x9c, 0x47, 0xff, 0x0a, 0x9d, 0x47, 0xff, 0x0b, 0x9e, 0x4b, 0xff, 0x08, 0x9e, 0x4a, 0xff, 0x09, 0x9f, 0x4a, 0xff, 0x09, 0xa0, 0x47, 0xff, 0x07, 0x9c, 0x44, 0xff, 0x08, 0x9b, 0x43, 0xff, 0x09, 0x96, 0x41, 0xff, 0x07, 0x91, 0x3e, 0xff, 0x02, 0x8a, 0x39, 0xff, 0x02, 0x8a, 0x3a, 0xff, 0x06, 0x93, 0x40, 0xff, 0x06, 0x95, 0x42, 0xff, 0x02, 0x95, 0x41, 0xff, 0x01, 0x93, 0x42, 0xff, 0x02, 0x94, 0x44, 0xff, 0x04, 0x96, 0x47, 0xff, 0x07, 0x9b, 0x49, 0xff, 0x09, 0x9d, 0x4a, 0xff, 0x08, 0x9c, 0x49, 0xff, 0x08, 0x9e, 0x4c, 0xff, 0x06, 0x9d, 0x4a, 0xff, 0x05, 0x9e, 0x4a, 0xff, 0x04, 0x9e, 0x4a, 0xff, 0x01, 0x9d, 0x48, 0xff, 0x02, 0x9d, 0x4a, 0xff, 0x05, 0x9e, 0x50, 0xff, 0x09, 0xa0, 0x57, 0xff, 0x09, 0x9e, 0x5b, 0xff, 0x08, 0x9d, 0x60, 0xff, 0x0b, 0x9e, 0x63, 0xff, 0x0a, 0x9c, 0x63, 0xff, 0x08, 0x9b, 0x61, 0xff, 0x09, 0x9d, 0x5f, 0xff, 0x08, 0x9e, 0x5d, 0xff, 0x08, 0x9d, 0x5d, 0xff, 0x07, 0x9c, 0x5e, 0xff, 0x09, 0x9e, 0x62, 0xff, 0x0a, 0x9e, 0x66, 0xff, 0x0a, 0x9d, 0x68, 0xff, 0x0a, 0x9e, 0x69, 0xff, 0x09, 0xa0, 0x6a, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x05, 0xa2, 0x67, 0xff, 0x08, 0xa6, 0x6a, 0xff, 0x09, 0xaa, 0x6b, 0xff, 0x09, 0xac, 0x6f, 0xff, 0x0f, 0xb2, 0x75, 0xff, 0x0d, 0xb1, 0x75, 0xff, 0x0b, 0xae, 0x74, 0xff, 0x10, 0xae, 0x76, 0xff, 0x0e, 0xa7, 0x73, 0xff, 0x39, 0xcd, 0x9f, 0xff, 0x22, 0xb6, 0x8d, 0xff, 0x12, 0xa7, 0x7f, 0xff, 0x1c, 0xb5, 0x8c, 0xff, 0x0d, 0xa6, 0x80, 0xff, 0x25, 0xb8, 0x98, 0xff, 0x42, 0xd6, 0xb0, 0xff, 0x1c, 0xb2, 0x87, 0xff, 0x09, 0xa0, 0x70, 0xff, 0x0c, 0xa4, 0x71, 0xff, 0x0f, 0xa9, 0x74, 0xff, 0x0d, 0xa9, 0x76, 0xff, 0x0e, 0xac, 0x76, 0xff, 0x13, 0xb2, 0x73, 0xff, 0x0c, 0xa9, 0x68, 0xff, 0x0f, 0xad, 0x69, 0xff, 0x12, 0xb1, 0x67, 0xff, 0x09, 0xab, 0x5b, 0xff, 0x19, 0xb5, 0x67, 0xff, 0x22, 0xb8, 0x6e, 0xff, 0x39, 0xbc, 0x7e, 0xff, 0x56, 0xb7, 0x8b, 0xff, 0x3b, 0x8e, 0x65, 0xff, 0x42, 0x91, 0x69, 0xff, 0x63, 0xc0, 0x93, 0xff, 0x36, 0xa6, 0x77, 0xff, 0x16, 0x9e, 0x6a, 0xff, 0x14, 0xa5, 0x6f, 0xff, 0x10, 0xa7, 0x6f, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x08, 0xa0, 0x6c, 0xff, 0x09, 0xa2, 0x6f, 0xff, 0x0b, 0xa3, 0x74, 0xff, 0x0b, 0xa3, 0x73, 0xff, 0x07, 0xa0, 0x6d, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x06, 0x9f, 0x67, 0xff, 0x05, 0x9e, 0x66, 0xff, 0x09, 0xa0, 0x68, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0d, 0xa3, 0x6d, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x08, 0x9d, 0x68, 0xff, 0x0c, 0x9b, 0x68, 0xff, 0x05, 0x94, 0x61, 0xff, 0x07, 0x98, 0x64, 0xff, 0x09, 0x9f, 0x6a, 0xff, 0x07, 0xa0, 0x6b, 0xff, 0x07, 0xa1, 0x6c, 0xff, 0x07, 0xa1, 0x6e, 0xff, 0x08, 0xa2, 0x6e, 0xff, 0x05, 0xa3, 0x6c, 0xff, 0x04, 0xa4, 0x6d, 0xff, 0x06, 0xa5, 0x6e, 0xff, 0x05, 0xa2, 0x6e, 0xff, 0x05, 0xa1, 0x6d, 0xff, 0x08, 0xa1, 0x6c, 0xff, 0x08, 0xa1, 0x6b, 0xff, 0x08, 0xa0, 0x69, 0xff, 0x07, 0xa2, 0x6a, 0xff, 0x06, 0xa1, 0x6a, 0xff, 0x07, 0xa2, 0x6b, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x10, 0xa4, 0x68, 0xff, 0x08, 0x97, 0x59, 0xff, 0x09, 0x92, 0x52, 0xff, 0x0c, 0x92, 0x50, 0xff, 0x0b, 0x90, 0x50, 0xff, 0x08, 0x8d, 0x4c, 0xff, 0x09, 0x8d, 0x4b, 0xff, 0x0a, 0x90, 0x4c, 0xff, 0x07, 0x91, 0x4a, 0xff, 0x06, 0x92, 0x4b, 0xff, 0x05, 0x90, 0x4b, 0xff, 0x07, 0x8d, 0x4a, 0xff, 0x08, 0x8d, 0x47, 0xff, 0x07, 0x8c, 0x48, 0xff, 0x09, 0x8b, 0x48, 0xff, 0x0c, 0x8b, 0x49, 0xff, 0x0b, 0x88, 0x46, 0xff, 0x08, 0x82, 0x41, 0xff, 0x06, 0x7f, 0x40, 0xff, 0x06, 0x7f, 0x40, 0xff, 0x09, 0x7f, 0x40, 0xff, 0x0a, 0x7f, 0x41, 0xff, 0x0b, 0x7e, 0x41, 0xff, 0x0a, 0x7c, 0x40, 0xff, 0x09, 0x7a, 0x40, 0xff, 0x08, 0x78, 0x3f, 0xff, 0x08, 0x79, 0x40, 0xff, 0x17, 0x87, 0x4f, 0xff, 0x16, 0x8a, 0x51, 0xff, 0x0a, 0x7a, 0x42, 0xff, 0x09, 0x6e, 0x3a, 0xff, 0x0b, 0x67, 0x39, 0xff, 0x0c, 0x61, 0x38, 0xff, 0x0f, 0x60, 0x3c, 0xff, 0x11, 0x5b, 0x3b, 0xff, 0x13, 0x55, 0x36, 0xff, 0x0d, 0x49, 0x2b, 0xff, 0x02, 0x4b, 0x1e, 0xff, 0x1e, 0xa9, 0x60, 0xff, 0x05, 0x8f, 0x41, 0xff, 0x0b, 0x9b, 0x51, 0xff, 0x19, 0xdc, 0x8b, 0xff, 0x09, 0xdf, 0x8d, 0xff, 0x06, 0xd0, 0x74, 0xff, 0x01, 0xb5, 0x49, 0xff, 0x08, 0xb0, 0x45, 0xff, 0x09, 0xa3, 0x3a, 0xff, 0x0d, 0x8d, 0x2f, 0xff, 0x08, 0x7d, 0x23, 0xff, 0x0c, 0x83, 0x2b, 0xff, 0x06, 0x78, 0x24, 0xff, 0x07, 0x6d, 0x1b, 0xff, 0x0b, 0x71, 0x22, 0xff, 0x02, 0x64, 0x12, 0xff, 0x0e, 0x78, 0x2d, 0xff, 0x03, 0x65, 0x22, 0xff, 0x03, 0x6e, 0x2b, 0xff, 0x03, 0x6f, 0x2a, 0xff, 0x01, 0x6f, 0x22, 0xff, 0x68, 0xa0, 0x76, 0xff, + 0x03, 0x36, 0x21, 0xff, 0x02, 0x35, 0x20, 0xff, 0x08, 0x4a, 0x2b, 0xff, 0x09, 0x63, 0x32, 0xff, 0x1a, 0x76, 0x47, 0xff, 0x03, 0x39, 0x23, 0xff, 0x05, 0x33, 0x23, 0xff, 0x01, 0x32, 0x1e, 0xff, 0x04, 0x56, 0x35, 0xff, 0x13, 0x9d, 0x55, 0xff, 0x08, 0x83, 0x35, 0xff, 0x0e, 0x70, 0x2b, 0xff, 0x03, 0x6e, 0x29, 0xff, 0x25, 0x9a, 0x6b, 0xff, 0x59, 0xbf, 0xb2, 0xff, 0x69, 0xc7, 0xc2, 0xff, 0x37, 0xa0, 0x86, 0xff, 0x0d, 0x8b, 0x52, 0xff, 0x0a, 0xa1, 0x4f, 0xff, 0x06, 0xb3, 0x5e, 0xff, 0x12, 0x9f, 0x64, 0xff, 0x04, 0x49, 0x24, 0xff, 0x06, 0x4c, 0x24, 0xff, 0x1b, 0x8c, 0x5d, 0xff, 0x13, 0xa1, 0x6d, 0xff, 0x0f, 0x97, 0x5f, 0xff, 0x04, 0x89, 0x4b, 0xff, 0x06, 0xa5, 0x60, 0xff, 0x13, 0x9f, 0x60, 0xff, 0x06, 0x64, 0x35, 0xff, 0x1a, 0x8d, 0x5a, 0xff, 0x09, 0x86, 0x43, 0xff, 0x08, 0x6d, 0x5c, 0xff, 0x0d, 0x42, 0xb0, 0xff, 0x08, 0x43, 0xb5, 0xff, 0x02, 0x4b, 0xb9, 0xff, 0x05, 0x45, 0xe3, 0xff, 0x0e, 0x4c, 0xf2, 0xff, 0x08, 0x47, 0xea, 0xff, 0x03, 0x4a, 0xe6, 0xff, 0x04, 0x50, 0xed, 0xff, 0x09, 0x5e, 0xf1, 0xff, 0x09, 0x66, 0xee, 0xff, 0x06, 0x65, 0xf2, 0xff, 0x05, 0x61, 0xf6, 0xff, 0x0a, 0x64, 0xf7, 0xff, 0x0f, 0x67, 0xf5, 0xff, 0x08, 0x4f, 0xed, 0xff, 0x04, 0x39, 0xda, 0xff, 0x03, 0x46, 0xa3, 0xff, 0x10, 0x78, 0x95, 0xff, 0x0b, 0x99, 0x83, 0xff, 0x06, 0xa6, 0x76, 0xff, 0x07, 0xa8, 0x69, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x09, 0xa7, 0x69, 0xff, 0x09, 0xa8, 0x68, 0xff, 0x08, 0xa7, 0x68, 0xff, 0x09, 0xa7, 0x67, 0xff, 0x0b, 0xa9, 0x68, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x06, 0xa5, 0x63, 0xff, 0x06, 0xa4, 0x63, 0xff, 0x09, 0xa6, 0x66, 0xff, 0x0a, 0xa7, 0x68, 0xff, 0x0b, 0xa8, 0x68, 0xff, 0x0a, 0xa7, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa9, 0x67, 0xff, 0x0b, 0xa8, 0x67, 0xff, 0x0b, 0xa7, 0x67, 0xff, 0x0c, 0xa7, 0x69, 0xff, 0x0b, 0xa3, 0x65, 0xff, 0x0c, 0xa0, 0x62, 0xff, 0x0b, 0x9e, 0x5f, 0xff, 0x04, 0x91, 0x51, 0xff, 0x1c, 0xac, 0x6c, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x09, 0x9e, 0x5c, 0xff, 0x09, 0x9d, 0x5e, 0xff, 0x07, 0x9c, 0x5d, 0xff, 0x05, 0x9d, 0x5f, 0xff, 0x04, 0x9e, 0x5e, 0xff, 0x02, 0x9d, 0x5e, 0xff, 0x04, 0x9e, 0x5f, 0xff, 0x03, 0x9b, 0x5c, 0xff, 0x06, 0x9c, 0x5d, 0xff, 0x06, 0x9f, 0x60, 0xff, 0x09, 0x9f, 0x60, 0xff, 0x0d, 0x9f, 0x5f, 0xff, 0x0b, 0x9e, 0x5d, 0xff, 0x09, 0xa0, 0x5c, 0xff, 0x07, 0x9f, 0x5a, 0xff, 0x09, 0x9e, 0x5d, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0d, 0xa1, 0x59, 0xff, 0x0d, 0xa1, 0x5b, 0xff, 0x0c, 0xa1, 0x5c, 0xff, 0x09, 0xa0, 0x5b, 0xff, 0x0b, 0xa3, 0x61, 0xff, 0x0a, 0xa5, 0x65, 0xff, 0x0a, 0xa5, 0x67, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x69, 0xff, 0x08, 0xa5, 0x61, 0xff, 0x07, 0xa3, 0x5a, 0xff, 0x08, 0xa3, 0x56, 0xff, 0x06, 0x9e, 0x4e, 0xff, 0x06, 0x99, 0x4b, 0xff, 0x06, 0x97, 0x49, 0xff, 0x05, 0x96, 0x45, 0xff, 0x04, 0x96, 0x44, 0xff, 0x05, 0x98, 0x45, 0xff, 0x04, 0x99, 0x48, 0xff, 0x0a, 0xa0, 0x51, 0xff, 0x0e, 0xa5, 0x59, 0xff, 0x0d, 0xa7, 0x5c, 0xff, 0x0c, 0xa8, 0x5e, 0xff, 0x0e, 0xaa, 0x62, 0xff, 0x0e, 0xaa, 0x63, 0xff, 0x0f, 0xab, 0x64, 0xff, 0x0f, 0xab, 0x64, 0xff, 0x0f, 0xab, 0x64, 0xff, 0x0f, 0xab, 0x64, 0xff, 0x10, 0xac, 0x65, 0xff, 0x0f, 0xac, 0x64, 0xff, 0x0d, 0xaa, 0x62, 0xff, 0x0b, 0xa8, 0x5d, 0xff, 0x08, 0xa2, 0x54, 0xff, 0x09, 0xa0, 0x4f, 0xff, 0x0b, 0xa0, 0x4b, 0xff, 0x0c, 0x9f, 0x4a, 0xff, 0x0b, 0x9e, 0x49, 0xff, 0x0a, 0x9d, 0x48, 0xff, 0x0a, 0x9d, 0x47, 0xff, 0x08, 0x9c, 0x45, 0xff, 0x07, 0x9b, 0x44, 0xff, 0x08, 0x9b, 0x44, 0xff, 0x08, 0x9c, 0x45, 0xff, 0x08, 0x9c, 0x44, 0xff, 0x08, 0x9c, 0x44, 0xff, 0x08, 0x9c, 0x44, 0xff, 0x0a, 0x9d, 0x48, 0xff, 0x09, 0x9c, 0x47, 0xff, 0x08, 0x9d, 0x46, 0xff, 0x08, 0x9d, 0x45, 0xff, 0x08, 0x9a, 0x42, 0xff, 0x09, 0x97, 0x42, 0xff, 0x09, 0x91, 0x40, 0xff, 0x06, 0x8b, 0x3e, 0xff, 0x01, 0x86, 0x3b, 0xff, 0x05, 0x8a, 0x41, 0xff, 0x07, 0x91, 0x44, 0xff, 0x08, 0x97, 0x49, 0xff, 0x05, 0x97, 0x48, 0xff, 0x04, 0x96, 0x48, 0xff, 0x04, 0x97, 0x48, 0xff, 0x06, 0x97, 0x49, 0xff, 0x04, 0x96, 0x47, 0xff, 0x03, 0x96, 0x46, 0xff, 0x03, 0x95, 0x45, 0xff, 0x03, 0x95, 0x47, 0xff, 0x03, 0x97, 0x48, 0xff, 0x04, 0x9a, 0x49, 0xff, 0x03, 0x9b, 0x49, 0xff, 0x02, 0x9d, 0x49, 0xff, 0x03, 0x9d, 0x4d, 0xff, 0x06, 0x9e, 0x53, 0xff, 0x07, 0x9d, 0x57, 0xff, 0x05, 0x9a, 0x58, 0xff, 0x08, 0x9c, 0x5e, 0xff, 0x0a, 0x9d, 0x63, 0xff, 0x0a, 0x9d, 0x63, 0xff, 0x09, 0x9d, 0x62, 0xff, 0x09, 0x9d, 0x60, 0xff, 0x0a, 0x9f, 0x5d, 0xff, 0x0a, 0x9f, 0x5f, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x0a, 0x9d, 0x62, 0xff, 0x0b, 0x9d, 0x64, 0xff, 0x0a, 0x9d, 0x66, 0xff, 0x0b, 0x9f, 0x69, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x06, 0xa2, 0x6a, 0xff, 0x06, 0xa4, 0x6b, 0xff, 0x08, 0xa9, 0x6d, 0xff, 0x0a, 0xad, 0x70, 0xff, 0x0b, 0xb0, 0x73, 0xff, 0x10, 0xb6, 0x7b, 0xff, 0x0e, 0xb3, 0x79, 0xff, 0x05, 0xa8, 0x6d, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x14, 0xab, 0x77, 0xff, 0x0c, 0xa3, 0x72, 0xff, 0x18, 0xae, 0x81, 0xff, 0x22, 0xb7, 0x8f, 0xff, 0x22, 0xb4, 0x92, 0xff, 0x21, 0xac, 0x8f, 0xff, 0x1c, 0xab, 0x88, 0xff, 0x0b, 0xa0, 0x75, 0xff, 0x05, 0x9e, 0x6c, 0xff, 0x08, 0xa2, 0x6d, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x0e, 0xa8, 0x76, 0xff, 0x0f, 0xa9, 0x74, 0xff, 0x12, 0xb0, 0x71, 0xff, 0x04, 0xa1, 0x5f, 0xff, 0x08, 0xa6, 0x60, 0xff, 0x0f, 0xb1, 0x64, 0xff, 0x0a, 0xad, 0x5b, 0xff, 0x1a, 0xba, 0x6a, 0xff, 0x1f, 0xb9, 0x6d, 0xff, 0x25, 0xb3, 0x73, 0xff, 0x21, 0x9e, 0x6b, 0xff, 0x24, 0x91, 0x62, 0xff, 0x40, 0xa3, 0x75, 0xff, 0x60, 0xca, 0x9a, 0xff, 0x2a, 0xa3, 0x71, 0xff, 0x0c, 0x97, 0x62, 0xff, 0x10, 0xa0, 0x6a, 0xff, 0x15, 0xa8, 0x70, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x05, 0x9e, 0x69, 0xff, 0x05, 0x9e, 0x69, 0xff, 0x0a, 0xa2, 0x70, 0xff, 0x0c, 0xa5, 0x72, 0xff, 0x09, 0xa2, 0x6e, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x07, 0xa1, 0x6c, 0xff, 0x04, 0x9e, 0x68, 0xff, 0x08, 0x9b, 0x67, 0xff, 0x08, 0x9c, 0x68, 0xff, 0x09, 0x9f, 0x6b, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x71, 0xff, 0x09, 0xa5, 0x71, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x06, 0xa7, 0x71, 0xff, 0x05, 0xa5, 0x6f, 0xff, 0x04, 0xa1, 0x6b, 0xff, 0x06, 0xa2, 0x6a, 0xff, 0x09, 0xa2, 0x69, 0xff, 0x08, 0xa2, 0x68, 0xff, 0x08, 0xa2, 0x67, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0e, 0xa5, 0x69, 0xff, 0x12, 0xa3, 0x67, 0xff, 0x10, 0x9c, 0x5f, 0xff, 0x09, 0x91, 0x52, 0xff, 0x0a, 0x8e, 0x4d, 0xff, 0x0c, 0x8e, 0x4c, 0xff, 0x09, 0x8c, 0x4b, 0xff, 0x07, 0x8a, 0x47, 0xff, 0x08, 0x8b, 0x49, 0xff, 0x09, 0x8e, 0x49, 0xff, 0x06, 0x8e, 0x48, 0xff, 0x04, 0x8f, 0x48, 0xff, 0x06, 0x8e, 0x48, 0xff, 0x09, 0x8d, 0x49, 0xff, 0x08, 0x8c, 0x47, 0xff, 0x09, 0x8d, 0x47, 0xff, 0x0a, 0x8b, 0x48, 0xff, 0x0b, 0x87, 0x45, 0xff, 0x09, 0x83, 0x43, 0xff, 0x08, 0x81, 0x40, 0xff, 0x08, 0x7f, 0x41, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x09, 0x7e, 0x41, 0xff, 0x0a, 0x7f, 0x42, 0xff, 0x0a, 0x7d, 0x41, 0xff, 0x0a, 0x7a, 0x40, 0xff, 0x09, 0x79, 0x3f, 0xff, 0x09, 0x78, 0x3f, 0xff, 0x0a, 0x78, 0x40, 0xff, 0x10, 0x7f, 0x49, 0xff, 0x0b, 0x74, 0x43, 0xff, 0x0d, 0x6b, 0x41, 0xff, 0x0c, 0x65, 0x3d, 0xff, 0x0c, 0x65, 0x3e, 0xff, 0x08, 0x63, 0x3f, 0xff, 0x02, 0x5c, 0x39, 0xff, 0x05, 0x58, 0x37, 0xff, 0x0c, 0x55, 0x39, 0xff, 0x12, 0x53, 0x36, 0xff, 0x08, 0x77, 0x43, 0xff, 0x21, 0xd0, 0x73, 0xff, 0x0b, 0xbd, 0x46, 0xff, 0x0f, 0xb7, 0x4b, 0xff, 0x13, 0xd2, 0x71, 0xff, 0x13, 0xdd, 0x7a, 0xff, 0x05, 0xc6, 0x5b, 0xff, 0x01, 0xb1, 0x41, 0xff, 0x05, 0xa7, 0x37, 0xff, 0x04, 0x9c, 0x2f, 0xff, 0x10, 0x8f, 0x2e, 0xff, 0x0b, 0x79, 0x1f, 0xff, 0x04, 0x71, 0x1c, 0xff, 0x01, 0x75, 0x22, 0xff, 0x05, 0x7c, 0x28, 0xff, 0x08, 0x81, 0x31, 0xff, 0x0b, 0x77, 0x26, 0xff, 0x0f, 0x72, 0x2a, 0xff, 0x01, 0x52, 0x16, 0xff, 0x0c, 0x68, 0x2e, 0xff, 0x0c, 0x6c, 0x2b, 0xff, 0x07, 0x68, 0x1f, 0xff, 0x6a, 0x9e, 0x74, 0xff, + 0x06, 0x33, 0x24, 0xff, 0x03, 0x39, 0x22, 0xff, 0x12, 0x55, 0x30, 0xff, 0x04, 0x5b, 0x2d, 0xff, 0x18, 0x70, 0x4a, 0xff, 0x05, 0x35, 0x21, 0xff, 0x08, 0x32, 0x20, 0xff, 0x02, 0x30, 0x1e, 0xff, 0x01, 0x3f, 0x24, 0xff, 0x1d, 0x9d, 0x5b, 0xff, 0x12, 0x99, 0x49, 0xff, 0x0d, 0x7d, 0x2f, 0xff, 0x0a, 0x7d, 0x2d, 0xff, 0x0f, 0x89, 0x46, 0xff, 0x38, 0xa5, 0x7c, 0xff, 0x2f, 0x9c, 0x79, 0xff, 0x09, 0x81, 0x4f, 0xff, 0x0b, 0x93, 0x50, 0xff, 0x0d, 0xaa, 0x56, 0xff, 0x12, 0xb2, 0x62, 0xff, 0x0b, 0x7a, 0x48, 0xff, 0x05, 0x41, 0x21, 0xff, 0x0a, 0x4a, 0x26, 0xff, 0x1f, 0x80, 0x57, 0xff, 0x18, 0x98, 0x61, 0xff, 0x02, 0x84, 0x41, 0xff, 0x05, 0x91, 0x4c, 0xff, 0x13, 0xac, 0x69, 0xff, 0x0e, 0x82, 0x4c, 0xff, 0x0e, 0x67, 0x3c, 0xff, 0x19, 0x8b, 0x59, 0xff, 0x0c, 0x7f, 0x3f, 0xff, 0x07, 0x63, 0x53, 0xff, 0x0d, 0x4f, 0x9f, 0xff, 0x0e, 0x5c, 0xa4, 0xff, 0x08, 0x59, 0xb6, 0xff, 0x0b, 0x4f, 0xe7, 0xff, 0x06, 0x4b, 0xf1, 0xff, 0x03, 0x4c, 0xed, 0xff, 0x03, 0x50, 0xe9, 0xff, 0x01, 0x51, 0xea, 0xff, 0x07, 0x5f, 0xf3, 0xff, 0x06, 0x64, 0xf2, 0xff, 0x05, 0x65, 0xf4, 0xff, 0x03, 0x63, 0xf4, 0xff, 0x05, 0x62, 0xf2, 0xff, 0x0a, 0x65, 0xf2, 0xff, 0x08, 0x57, 0xef, 0xff, 0x0a, 0x43, 0xed, 0xff, 0x01, 0x32, 0xc2, 0xff, 0x02, 0x48, 0xa7, 0xff, 0x02, 0x71, 0x8c, 0xff, 0x07, 0x98, 0x77, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x08, 0xa5, 0x71, 0xff, 0x09, 0xa7, 0x6a, 0xff, 0x08, 0xa7, 0x6a, 0xff, 0x09, 0xa8, 0x6c, 0xff, 0x08, 0xa7, 0x6b, 0xff, 0x09, 0xaa, 0x6c, 0xff, 0x0a, 0xaa, 0x6c, 0xff, 0x06, 0xa7, 0x68, 0xff, 0x07, 0xa7, 0x69, 0xff, 0x07, 0xa8, 0x6a, 0xff, 0x09, 0xa9, 0x6b, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x0c, 0xa8, 0x68, 0xff, 0x0c, 0xa8, 0x68, 0xff, 0x0d, 0xa7, 0x67, 0xff, 0x0c, 0xa4, 0x66, 0xff, 0x09, 0xa2, 0x65, 0xff, 0x0b, 0xa0, 0x64, 0xff, 0x0b, 0x9e, 0x61, 0xff, 0x0b, 0x9b, 0x5e, 0xff, 0x09, 0x96, 0x58, 0xff, 0x0d, 0x98, 0x58, 0xff, 0x10, 0xa4, 0x64, 0xff, 0x06, 0x9b, 0x5c, 0xff, 0x09, 0x9c, 0x61, 0xff, 0x07, 0x9b, 0x60, 0xff, 0x04, 0x9c, 0x60, 0xff, 0x01, 0x9c, 0x5f, 0xff, 0x01, 0x9d, 0x60, 0xff, 0x03, 0xa0, 0x60, 0xff, 0x04, 0x9e, 0x5f, 0xff, 0x06, 0x9f, 0x60, 0xff, 0x06, 0xa1, 0x60, 0xff, 0x07, 0xa0, 0x5e, 0xff, 0x09, 0x9e, 0x5b, 0xff, 0x0b, 0xa0, 0x5c, 0xff, 0x0a, 0xa1, 0x5c, 0xff, 0x08, 0xa0, 0x5b, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x0c, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5b, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x09, 0xa0, 0x5a, 0xff, 0x08, 0xa0, 0x5c, 0xff, 0x07, 0xa1, 0x5e, 0xff, 0x06, 0xa2, 0x61, 0xff, 0x08, 0xa6, 0x67, 0xff, 0x09, 0xa8, 0x68, 0xff, 0x09, 0xa7, 0x65, 0xff, 0x08, 0xa6, 0x61, 0xff, 0x09, 0xa6, 0x5e, 0xff, 0x09, 0xa2, 0x58, 0xff, 0x06, 0x9c, 0x50, 0xff, 0x03, 0x98, 0x4c, 0xff, 0x05, 0x98, 0x48, 0xff, 0x04, 0x97, 0x48, 0xff, 0x06, 0x99, 0x48, 0xff, 0x05, 0x98, 0x46, 0xff, 0x06, 0x9b, 0x4b, 0xff, 0x0b, 0xa2, 0x53, 0xff, 0x0d, 0xa7, 0x59, 0xff, 0x0c, 0xa7, 0x5c, 0xff, 0x0d, 0xa9, 0x61, 0xff, 0x0d, 0xa9, 0x62, 0xff, 0x0e, 0xaa, 0x63, 0xff, 0x0d, 0xa9, 0x62, 0xff, 0x0e, 0xab, 0x61, 0xff, 0x0e, 0xab, 0x61, 0xff, 0x0e, 0xab, 0x61, 0xff, 0x0d, 0xaa, 0x60, 0xff, 0x0b, 0xa8, 0x5d, 0xff, 0x0a, 0xa6, 0x5a, 0xff, 0x0b, 0xa3, 0x52, 0xff, 0x0a, 0xa0, 0x4c, 0xff, 0x0b, 0x9d, 0x47, 0xff, 0x0b, 0x9d, 0x46, 0xff, 0x09, 0x9c, 0x44, 0xff, 0x08, 0x9c, 0x46, 0xff, 0x08, 0x9d, 0x45, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x05, 0x9a, 0x40, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x08, 0x9c, 0x44, 0xff, 0x07, 0x9b, 0x43, 0xff, 0x08, 0x9c, 0x44, 0xff, 0x0b, 0x9d, 0x45, 0xff, 0x0b, 0x9d, 0x45, 0xff, 0x08, 0x9c, 0x43, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x07, 0x99, 0x41, 0xff, 0x08, 0x94, 0x41, 0xff, 0x06, 0x8a, 0x3c, 0xff, 0x04, 0x83, 0x3a, 0xff, 0x02, 0x82, 0x3d, 0xff, 0x02, 0x86, 0x44, 0xff, 0x01, 0x88, 0x42, 0xff, 0x01, 0x8f, 0x45, 0xff, 0x01, 0x93, 0x48, 0xff, 0x01, 0x93, 0x46, 0xff, 0x01, 0x94, 0x47, 0xff, 0x02, 0x94, 0x48, 0xff, 0x02, 0x94, 0x47, 0xff, 0x03, 0x97, 0x4a, 0xff, 0x05, 0x98, 0x4b, 0xff, 0x08, 0x99, 0x4e, 0xff, 0x09, 0x9a, 0x4f, 0xff, 0x08, 0x9b, 0x4e, 0xff, 0x05, 0x9b, 0x4c, 0xff, 0x02, 0x9b, 0x4a, 0xff, 0x01, 0x9a, 0x4c, 0xff, 0x03, 0x9a, 0x51, 0xff, 0x01, 0x97, 0x52, 0xff, 0x03, 0x98, 0x57, 0xff, 0x08, 0x9d, 0x5f, 0xff, 0x09, 0x9d, 0x61, 0xff, 0x0b, 0x9f, 0x63, 0xff, 0x0b, 0x9f, 0x63, 0xff, 0x0b, 0x9f, 0x60, 0xff, 0x0c, 0xa0, 0x60, 0xff, 0x0b, 0xa0, 0x60, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0a, 0x9e, 0x61, 0xff, 0x09, 0x9d, 0x62, 0xff, 0x0a, 0x9d, 0x64, 0xff, 0x0c, 0x9f, 0x68, 0xff, 0x0a, 0xa1, 0x6b, 0xff, 0x08, 0xa0, 0x6b, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x08, 0xaa, 0x70, 0xff, 0x09, 0xad, 0x73, 0xff, 0x09, 0xae, 0x75, 0xff, 0x08, 0xab, 0x70, 0xff, 0x06, 0xa4, 0x66, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x07, 0xa1, 0x6a, 0xff, 0x14, 0xab, 0x78, 0xff, 0x19, 0xad, 0x7c, 0xff, 0x15, 0xa6, 0x79, 0xff, 0x27, 0xb5, 0x8d, 0xff, 0x56, 0xdf, 0xbe, 0xff, 0x2c, 0xb0, 0x95, 0xff, 0x08, 0x93, 0x70, 0xff, 0x09, 0x9c, 0x70, 0xff, 0x07, 0xa1, 0x6d, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x10, 0xa9, 0x77, 0xff, 0x0e, 0xa6, 0x74, 0xff, 0x13, 0xad, 0x73, 0xff, 0x06, 0x9f, 0x62, 0xff, 0x05, 0xa3, 0x5f, 0xff, 0x16, 0xb9, 0x6c, 0xff, 0x09, 0xaf, 0x5e, 0xff, 0x18, 0xba, 0x6b, 0xff, 0x16, 0xb3, 0x6a, 0xff, 0x16, 0xac, 0x6a, 0xff, 0x0a, 0x9a, 0x61, 0xff, 0x29, 0xaa, 0x75, 0xff, 0x28, 0x9f, 0x6c, 0xff, 0x23, 0x9e, 0x6b, 0xff, 0x0a, 0x92, 0x5c, 0xff, 0x0a, 0x9d, 0x66, 0xff, 0x0e, 0x9f, 0x68, 0xff, 0x14, 0xa2, 0x6b, 0xff, 0x11, 0xa5, 0x6d, 0xff, 0x0b, 0xa2, 0x6a, 0xff, 0x09, 0xa0, 0x69, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x08, 0xa1, 0x68, 0xff, 0x08, 0xa1, 0x69, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x05, 0xa2, 0x6d, 0xff, 0x08, 0xa0, 0x6e, 0xff, 0x0b, 0xa3, 0x71, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x07, 0xa5, 0x6f, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa1, 0x68, 0xff, 0x0a, 0xa3, 0x67, 0xff, 0x0c, 0xa3, 0x67, 0xff, 0x0f, 0xa4, 0x65, 0xff, 0x0d, 0x9f, 0x60, 0xff, 0x0e, 0x9b, 0x5c, 0xff, 0x0d, 0x94, 0x56, 0xff, 0x0a, 0x8f, 0x50, 0xff, 0x09, 0x8c, 0x4b, 0xff, 0x08, 0x8c, 0x4a, 0xff, 0x07, 0x8c, 0x48, 0xff, 0x08, 0x8a, 0x48, 0xff, 0x07, 0x88, 0x46, 0xff, 0x08, 0x89, 0x45, 0xff, 0x08, 0x8c, 0x46, 0xff, 0x06, 0x8d, 0x46, 0xff, 0x04, 0x8e, 0x47, 0xff, 0x07, 0x8d, 0x47, 0xff, 0x09, 0x8c, 0x49, 0xff, 0x09, 0x8d, 0x48, 0xff, 0x0a, 0x8c, 0x47, 0xff, 0x0a, 0x89, 0x46, 0xff, 0x08, 0x84, 0x42, 0xff, 0x09, 0x81, 0x41, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x08, 0x7f, 0x42, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x08, 0x7e, 0x41, 0xff, 0x09, 0x7b, 0x40, 0xff, 0x08, 0x78, 0x3e, 0xff, 0x09, 0x77, 0x3e, 0xff, 0x0a, 0x77, 0x3f, 0xff, 0x0a, 0x77, 0x41, 0xff, 0x06, 0x75, 0x3e, 0xff, 0x07, 0x70, 0x42, 0xff, 0x07, 0x6a, 0x41, 0xff, 0x05, 0x66, 0x3d, 0xff, 0x02, 0x65, 0x3b, 0xff, 0x02, 0x68, 0x3c, 0xff, 0x01, 0x6e, 0x42, 0xff, 0x03, 0x6e, 0x43, 0xff, 0x05, 0x65, 0x3e, 0xff, 0x03, 0x59, 0x34, 0xff, 0x0d, 0x9f, 0x5e, 0xff, 0x1a, 0xe2, 0x78, 0xff, 0x13, 0xdd, 0x53, 0xff, 0x05, 0xb8, 0x35, 0xff, 0x08, 0xbd, 0x4c, 0xff, 0x0d, 0xce, 0x5b, 0xff, 0x09, 0xbd, 0x4c, 0xff, 0x05, 0xa4, 0x36, 0xff, 0x09, 0x9c, 0x30, 0xff, 0x05, 0x9a, 0x2c, 0xff, 0x08, 0x8e, 0x2b, 0xff, 0x05, 0x76, 0x1b, 0xff, 0x02, 0x7a, 0x22, 0xff, 0x0c, 0xa1, 0x49, 0xff, 0x21, 0xcd, 0x70, 0xff, 0x13, 0xc1, 0x65, 0xff, 0x1b, 0xad, 0x55, 0xff, 0x17, 0x84, 0x3a, 0xff, 0x02, 0x56, 0x1e, 0xff, 0x04, 0x62, 0x2d, 0xff, 0x05, 0x64, 0x27, 0xff, 0x08, 0x65, 0x20, 0xff, 0x66, 0x9b, 0x77, 0xff, + 0x08, 0x31, 0x25, 0xff, 0x04, 0x3c, 0x21, 0xff, 0x0f, 0x53, 0x28, 0xff, 0x09, 0x60, 0x33, 0xff, 0x10, 0x67, 0x46, 0xff, 0x05, 0x35, 0x21, 0xff, 0x0b, 0x32, 0x1e, 0xff, 0x05, 0x32, 0x1f, 0xff, 0x01, 0x36, 0x1c, 0xff, 0x15, 0x86, 0x4b, 0xff, 0x1b, 0xaa, 0x5a, 0xff, 0x11, 0x93, 0x3c, 0xff, 0x0b, 0x87, 0x30, 0xff, 0x08, 0x82, 0x33, 0xff, 0x12, 0x84, 0x43, 0xff, 0x0e, 0x86, 0x4b, 0xff, 0x02, 0x84, 0x42, 0xff, 0x12, 0x9f, 0x5a, 0xff, 0x09, 0xa7, 0x58, 0xff, 0x1a, 0xa9, 0x5f, 0xff, 0x05, 0x59, 0x2d, 0xff, 0x07, 0x43, 0x25, 0xff, 0x08, 0x47, 0x26, 0xff, 0x22, 0x72, 0x50, 0xff, 0x0e, 0x7b, 0x42, 0xff, 0x06, 0x8d, 0x41, 0xff, 0x0c, 0xa1, 0x55, 0xff, 0x22, 0xaa, 0x6f, 0xff, 0x08, 0x5f, 0x33, 0xff, 0x10, 0x69, 0x41, 0xff, 0x0f, 0x7f, 0x4e, 0xff, 0x0e, 0x74, 0x3b, 0xff, 0x06, 0x61, 0x46, 0xff, 0x06, 0x5f, 0x76, 0xff, 0x0b, 0x69, 0x87, 0xff, 0x0d, 0x58, 0xc1, 0xff, 0x0d, 0x4d, 0xeb, 0xff, 0x03, 0x51, 0xee, 0xff, 0x02, 0x55, 0xf0, 0xff, 0x06, 0x57, 0xf1, 0xff, 0x07, 0x5c, 0xf0, 0xff, 0x05, 0x61, 0xf5, 0xff, 0x03, 0x62, 0xf7, 0xff, 0x01, 0x63, 0xf4, 0xff, 0x02, 0x63, 0xf0, 0xff, 0x03, 0x63, 0xf1, 0xff, 0x06, 0x62, 0xf3, 0xff, 0x06, 0x58, 0xf0, 0xff, 0x06, 0x45, 0xeb, 0xff, 0x03, 0x31, 0xd8, 0xff, 0x05, 0x34, 0xca, 0xff, 0x01, 0x53, 0x9e, 0xff, 0x0c, 0x8e, 0x7c, 0xff, 0x0b, 0xa8, 0x74, 0xff, 0x05, 0xa8, 0x6e, 0xff, 0x07, 0xa6, 0x6c, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x08, 0xa8, 0x6f, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x08, 0xab, 0x70, 0xff, 0x0a, 0xad, 0x71, 0xff, 0x0a, 0xae, 0x71, 0xff, 0x0b, 0xb0, 0x71, 0xff, 0x0d, 0xb1, 0x72, 0xff, 0x0e, 0xaf, 0x71, 0xff, 0x0e, 0xad, 0x6e, 0xff, 0x0c, 0xa8, 0x6b, 0xff, 0x0c, 0xa7, 0x67, 0xff, 0x0b, 0xa3, 0x64, 0xff, 0x09, 0xa0, 0x62, 0xff, 0x09, 0x9f, 0x63, 0xff, 0x0a, 0x9d, 0x62, 0xff, 0x0a, 0x9b, 0x5f, 0xff, 0x0c, 0x9a, 0x5e, 0xff, 0x0b, 0x9a, 0x5d, 0xff, 0x04, 0x8c, 0x4e, 0xff, 0x1d, 0xb0, 0x70, 0xff, 0x08, 0x9c, 0x5c, 0xff, 0x08, 0x9a, 0x61, 0xff, 0x07, 0x9b, 0x62, 0xff, 0x05, 0x9d, 0x63, 0xff, 0x07, 0xa4, 0x67, 0xff, 0x0d, 0xad, 0x6f, 0xff, 0x09, 0xa9, 0x6a, 0xff, 0x06, 0xa4, 0x64, 0xff, 0x05, 0xa2, 0x62, 0xff, 0x06, 0xa3, 0x61, 0xff, 0x08, 0xa3, 0x5f, 0xff, 0x09, 0x9f, 0x5a, 0xff, 0x0a, 0xa0, 0x5b, 0xff, 0x09, 0xa0, 0x5b, 0xff, 0x08, 0xa1, 0x5c, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x0a, 0xa1, 0x5c, 0xff, 0x0a, 0xa1, 0x5c, 0xff, 0x0b, 0xa1, 0x5b, 0xff, 0x0a, 0xa0, 0x5a, 0xff, 0x09, 0xa1, 0x59, 0xff, 0x08, 0xa1, 0x5b, 0xff, 0x06, 0xa1, 0x5c, 0xff, 0x07, 0xa3, 0x5f, 0xff, 0x09, 0xa7, 0x66, 0xff, 0x08, 0xa9, 0x69, 0xff, 0x09, 0xa9, 0x69, 0xff, 0x09, 0xa8, 0x67, 0xff, 0x0a, 0xa8, 0x65, 0xff, 0x0c, 0xa7, 0x62, 0xff, 0x09, 0xa1, 0x59, 0xff, 0x05, 0x9b, 0x51, 0xff, 0x05, 0x99, 0x4c, 0xff, 0x04, 0x99, 0x49, 0xff, 0x07, 0x9b, 0x49, 0xff, 0x06, 0x99, 0x47, 0xff, 0x03, 0x99, 0x47, 0xff, 0x04, 0x9b, 0x4b, 0xff, 0x0a, 0xa2, 0x54, 0xff, 0x0c, 0xa6, 0x59, 0xff, 0x0a, 0xa7, 0x5d, 0xff, 0x0b, 0xa7, 0x5f, 0xff, 0x0d, 0xa8, 0x61, 0xff, 0x0d, 0xaa, 0x61, 0xff, 0x0d, 0xaa, 0x60, 0xff, 0x0c, 0xa9, 0x5f, 0xff, 0x0c, 0xa9, 0x5e, 0xff, 0x0a, 0xa8, 0x5c, 0xff, 0x09, 0xa5, 0x59, 0xff, 0x09, 0xa3, 0x55, 0xff, 0x0a, 0xa1, 0x4f, 0xff, 0x0b, 0xa0, 0x49, 0xff, 0x0a, 0x9d, 0x44, 0xff, 0x0b, 0x9d, 0x44, 0xff, 0x08, 0x9c, 0x44, 0xff, 0x08, 0x9c, 0x45, 0xff, 0x08, 0x9c, 0x43, 0xff, 0x06, 0x9c, 0x42, 0xff, 0x05, 0x9a, 0x40, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x07, 0x9b, 0x42, 0xff, 0x07, 0x9c, 0x43, 0xff, 0x0a, 0x9c, 0x43, 0xff, 0x0a, 0x9c, 0x42, 0xff, 0x07, 0x9a, 0x3f, 0xff, 0x06, 0x99, 0x3e, 0xff, 0x07, 0x96, 0x3f, 0xff, 0x08, 0x92, 0x40, 0xff, 0x04, 0x87, 0x3c, 0xff, 0x05, 0x81, 0x3c, 0xff, 0x07, 0x85, 0x46, 0xff, 0x05, 0x89, 0x4c, 0xff, 0x03, 0x8c, 0x4b, 0xff, 0x03, 0x91, 0x4c, 0xff, 0x05, 0x98, 0x4f, 0xff, 0x05, 0x99, 0x4e, 0xff, 0x05, 0x9a, 0x4f, 0xff, 0x07, 0x9a, 0x4f, 0xff, 0x07, 0x9a, 0x4f, 0xff, 0x08, 0x9c, 0x50, 0xff, 0x07, 0x98, 0x4e, 0xff, 0x06, 0x96, 0x4d, 0xff, 0x03, 0x93, 0x4b, 0xff, 0x02, 0x92, 0x48, 0xff, 0x01, 0x94, 0x48, 0xff, 0x00, 0x97, 0x49, 0xff, 0x01, 0x99, 0x4d, 0xff, 0x03, 0x9a, 0x51, 0xff, 0x04, 0x9a, 0x56, 0xff, 0x07, 0x9c, 0x5b, 0xff, 0x09, 0x9f, 0x60, 0xff, 0x09, 0x9d, 0x5f, 0xff, 0x0a, 0x9f, 0x60, 0xff, 0x0b, 0xa0, 0x61, 0xff, 0x09, 0x9e, 0x5e, 0xff, 0x0a, 0x9e, 0x5e, 0xff, 0x0a, 0x9e, 0x5e, 0xff, 0x09, 0x9d, 0x5f, 0xff, 0x0a, 0x9e, 0x61, 0xff, 0x0a, 0x9e, 0x63, 0xff, 0x0c, 0x9f, 0x66, 0xff, 0x0d, 0xa1, 0x68, 0xff, 0x0c, 0xa1, 0x6b, 0xff, 0x0a, 0xa1, 0x6e, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x0a, 0xab, 0x71, 0xff, 0x08, 0xaa, 0x72, 0xff, 0x04, 0xa7, 0x6e, 0xff, 0x05, 0xa7, 0x69, 0xff, 0x06, 0xa2, 0x62, 0xff, 0x05, 0x9e, 0x64, 0xff, 0x09, 0x9f, 0x6c, 0xff, 0x32, 0xc5, 0x97, 0xff, 0x25, 0xb5, 0x88, 0xff, 0x18, 0xa4, 0x77, 0xff, 0x18, 0xa1, 0x77, 0xff, 0x4a, 0xcb, 0xa9, 0xff, 0x21, 0x9e, 0x83, 0xff, 0x19, 0xa1, 0x7f, 0xff, 0x16, 0xa7, 0x7c, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x0f, 0xa8, 0x76, 0xff, 0x10, 0xa6, 0x76, 0xff, 0x10, 0xa7, 0x71, 0xff, 0x08, 0xa1, 0x67, 0xff, 0x03, 0x9f, 0x5e, 0xff, 0x09, 0xac, 0x61, 0xff, 0x03, 0xaa, 0x5b, 0xff, 0x0e, 0xb3, 0x66, 0xff, 0x19, 0xb7, 0x71, 0xff, 0x13, 0xab, 0x6b, 0xff, 0x11, 0xa5, 0x69, 0xff, 0x1e, 0xa5, 0x6c, 0xff, 0x1f, 0xa0, 0x69, 0xff, 0x13, 0x9b, 0x64, 0xff, 0x0a, 0x9f, 0x66, 0xff, 0x06, 0x9f, 0x67, 0xff, 0x08, 0x9c, 0x65, 0xff, 0x13, 0x9e, 0x68, 0xff, 0x0e, 0xa0, 0x68, 0xff, 0x0d, 0xa1, 0x66, 0xff, 0x09, 0x9f, 0x63, 0xff, 0x0a, 0xa1, 0x63, 0xff, 0x09, 0xa1, 0x63, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0b, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x09, 0xa3, 0x69, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x05, 0xa6, 0x6f, 0xff, 0x05, 0xa0, 0x6e, 0xff, 0x07, 0xa3, 0x70, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x0b, 0xad, 0x74, 0xff, 0x09, 0xa9, 0x72, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x08, 0xa6, 0x70, 0xff, 0x09, 0xa6, 0x71, 0xff, 0x09, 0xa6, 0x71, 0xff, 0x0a, 0xa7, 0x71, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x0a, 0xa1, 0x66, 0xff, 0x0d, 0xa3, 0x65, 0xff, 0x0e, 0xa1, 0x62, 0xff, 0x0f, 0x9e, 0x5c, 0xff, 0x08, 0x92, 0x51, 0xff, 0x07, 0x8c, 0x4d, 0xff, 0x08, 0x88, 0x49, 0xff, 0x0a, 0x89, 0x4a, 0xff, 0x09, 0x8b, 0x48, 0xff, 0x08, 0x8d, 0x4a, 0xff, 0x06, 0x8f, 0x48, 0xff, 0x09, 0x8d, 0x4a, 0xff, 0x0a, 0x8b, 0x48, 0xff, 0x0a, 0x8b, 0x46, 0xff, 0x08, 0x8c, 0x45, 0xff, 0x06, 0x8c, 0x45, 0xff, 0x06, 0x8d, 0x46, 0xff, 0x08, 0x8d, 0x47, 0xff, 0x09, 0x8a, 0x47, 0xff, 0x09, 0x8c, 0x46, 0xff, 0x08, 0x89, 0x44, 0xff, 0x07, 0x85, 0x43, 0xff, 0x07, 0x82, 0x40, 0xff, 0x09, 0x81, 0x41, 0xff, 0x09, 0x7f, 0x41, 0xff, 0x0a, 0x7f, 0x42, 0xff, 0x09, 0x7f, 0x42, 0xff, 0x07, 0x7e, 0x41, 0xff, 0x06, 0x7c, 0x40, 0xff, 0x07, 0x79, 0x3f, 0xff, 0x08, 0x79, 0x3f, 0xff, 0x0b, 0x79, 0x40, 0xff, 0x0b, 0x76, 0x40, 0xff, 0x08, 0x74, 0x3f, 0xff, 0x06, 0x73, 0x3e, 0xff, 0x09, 0x71, 0x3e, 0xff, 0x05, 0x6b, 0x3b, 0xff, 0x10, 0x7c, 0x4a, 0xff, 0x22, 0xa1, 0x6a, 0xff, 0x20, 0xb3, 0x77, 0xff, 0x18, 0xc0, 0x7f, 0xff, 0x1b, 0xc5, 0x84, 0xff, 0x16, 0xb4, 0x76, 0xff, 0x06, 0x8b, 0x4e, 0xff, 0x0b, 0xb9, 0x5f, 0xff, 0x12, 0xe4, 0x76, 0xff, 0x11, 0xe5, 0x66, 0xff, 0x01, 0xaf, 0x2c, 0xff, 0x03, 0xad, 0x36, 0xff, 0x07, 0xc4, 0x4c, 0xff, 0x0d, 0xb7, 0x45, 0xff, 0x07, 0x97, 0x2d, 0xff, 0x0c, 0x93, 0x2d, 0xff, 0x07, 0x99, 0x2f, 0xff, 0x01, 0x8a, 0x27, 0xff, 0x02, 0x7d, 0x1d, 0xff, 0x14, 0xb2, 0x54, 0xff, 0x18, 0xc2, 0x66, 0xff, 0x0e, 0xbd, 0x5a, 0xff, 0x08, 0xc7, 0x63, 0xff, 0x0d, 0xb1, 0x53, 0xff, 0x06, 0x70, 0x24, 0xff, 0x03, 0x52, 0x1c, 0xff, 0x01, 0x57, 0x26, 0xff, 0x07, 0x5d, 0x25, 0xff, 0x08, 0x58, 0x19, 0xff, 0x62, 0x8e, 0x76, 0xff, + 0x08, 0x32, 0x23, 0xff, 0x06, 0x3c, 0x20, 0xff, 0x08, 0x47, 0x1f, 0xff, 0x12, 0x65, 0x3b, 0xff, 0x0c, 0x5d, 0x3e, 0xff, 0x05, 0x38, 0x22, 0xff, 0x09, 0x34, 0x20, 0xff, 0x06, 0x32, 0x21, 0xff, 0x01, 0x34, 0x1d, 0xff, 0x0a, 0x69, 0x38, 0xff, 0x1a, 0xa4, 0x5b, 0xff, 0x20, 0xab, 0x53, 0xff, 0x0a, 0x8a, 0x32, 0xff, 0x06, 0x7c, 0x2a, 0xff, 0x0a, 0x7b, 0x32, 0xff, 0x08, 0x81, 0x3b, 0xff, 0x05, 0x8e, 0x44, 0xff, 0x0f, 0xa4, 0x5b, 0xff, 0x08, 0xa7, 0x5a, 0xff, 0x1a, 0x96, 0x56, 0xff, 0x02, 0x44, 0x1f, 0xff, 0x09, 0x43, 0x28, 0xff, 0x08, 0x46, 0x28, 0xff, 0x11, 0x5c, 0x3a, 0xff, 0x07, 0x71, 0x37, 0xff, 0x0c, 0x9c, 0x4b, 0xff, 0x11, 0xab, 0x5c, 0xff, 0x20, 0x99, 0x65, 0xff, 0x02, 0x45, 0x24, 0xff, 0x06, 0x5d, 0x37, 0xff, 0x05, 0x72, 0x41, 0xff, 0x0b, 0x66, 0x34, 0xff, 0x06, 0x60, 0x3d, 0xff, 0x0e, 0x74, 0x61, 0xff, 0x09, 0x73, 0x78, 0xff, 0x12, 0x53, 0xc3, 0xff, 0x0b, 0x46, 0xe9, 0xff, 0x02, 0x53, 0xef, 0xff, 0x05, 0x58, 0xef, 0xff, 0x0a, 0x5e, 0xf5, 0xff, 0x08, 0x62, 0xf6, 0xff, 0x03, 0x61, 0xf5, 0xff, 0x04, 0x60, 0xf9, 0xff, 0x01, 0x63, 0xf4, 0xff, 0x01, 0x64, 0xf1, 0xff, 0x04, 0x65, 0xf2, 0xff, 0x06, 0x61, 0xf5, 0xff, 0x03, 0x55, 0xec, 0xff, 0x07, 0x46, 0xec, 0xff, 0x03, 0x2d, 0xdd, 0xff, 0x08, 0x32, 0xd5, 0xff, 0x02, 0x52, 0xa1, 0xff, 0x11, 0x92, 0x80, 0xff, 0x07, 0xa5, 0x71, 0xff, 0x04, 0xa8, 0x6d, 0xff, 0x05, 0xa0, 0x69, 0xff, 0x04, 0x9f, 0x68, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa8, 0x6f, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x08, 0xac, 0x72, 0xff, 0x09, 0xad, 0x72, 0xff, 0x0c, 0xb2, 0x73, 0xff, 0x0c, 0xb0, 0x72, 0xff, 0x0a, 0xab, 0x6d, 0xff, 0x0a, 0xa9, 0x6a, 0xff, 0x0c, 0xa7, 0x69, 0xff, 0x0c, 0xa4, 0x66, 0xff, 0x09, 0x9e, 0x61, 0xff, 0x06, 0x9c, 0x60, 0xff, 0x07, 0x9b, 0x64, 0xff, 0x06, 0x9b, 0x60, 0xff, 0x09, 0x9a, 0x5d, 0xff, 0x10, 0x99, 0x61, 0xff, 0x08, 0x9c, 0x60, 0xff, 0x03, 0x90, 0x52, 0xff, 0x1e, 0xad, 0x6d, 0xff, 0x10, 0xa2, 0x5f, 0xff, 0x0b, 0x9d, 0x64, 0xff, 0x0a, 0xa1, 0x68, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x0f, 0xae, 0x72, 0xff, 0x11, 0xb5, 0x77, 0xff, 0x0b, 0xae, 0x6f, 0xff, 0x0b, 0xa9, 0x6c, 0xff, 0x07, 0xa9, 0x6a, 0xff, 0x08, 0xaa, 0x67, 0xff, 0x09, 0xa9, 0x64, 0xff, 0x09, 0xa5, 0x5e, 0xff, 0x07, 0xa2, 0x5c, 0xff, 0x08, 0xa2, 0x5d, 0xff, 0x09, 0xa3, 0x5f, 0xff, 0x0a, 0xa2, 0x60, 0xff, 0x0a, 0xa0, 0x5f, 0xff, 0x09, 0xa2, 0x5d, 0xff, 0x08, 0xa2, 0x5c, 0xff, 0x0a, 0xa2, 0x5c, 0xff, 0x0a, 0xa2, 0x5c, 0xff, 0x07, 0xa1, 0x5a, 0xff, 0x08, 0xa3, 0x5d, 0xff, 0x09, 0xa4, 0x60, 0xff, 0x0a, 0xa6, 0x62, 0xff, 0x0b, 0xa9, 0x66, 0xff, 0x09, 0xab, 0x69, 0xff, 0x07, 0xab, 0x6b, 0xff, 0x07, 0xa9, 0x6b, 0xff, 0x08, 0xaa, 0x6a, 0xff, 0x0b, 0xab, 0x69, 0xff, 0x0a, 0xa7, 0x61, 0xff, 0x05, 0xa2, 0x58, 0xff, 0x02, 0x9e, 0x51, 0xff, 0x01, 0x9b, 0x4d, 0xff, 0x04, 0x9c, 0x4c, 0xff, 0x04, 0x9b, 0x4a, 0xff, 0x03, 0x99, 0x48, 0xff, 0x01, 0x97, 0x47, 0xff, 0x05, 0x9d, 0x4c, 0xff, 0x09, 0xa2, 0x52, 0xff, 0x0a, 0xa5, 0x59, 0xff, 0x0b, 0xa6, 0x5b, 0xff, 0x0d, 0xa8, 0x5e, 0xff, 0x0e, 0xaa, 0x5f, 0xff, 0x0f, 0xa9, 0x5f, 0xff, 0x0e, 0xa8, 0x5e, 0xff, 0x0c, 0xa7, 0x5c, 0xff, 0x0a, 0xa5, 0x5a, 0xff, 0x08, 0xa3, 0x56, 0xff, 0x07, 0xa1, 0x50, 0xff, 0x09, 0x9f, 0x49, 0xff, 0x09, 0x9e, 0x44, 0xff, 0x08, 0x9c, 0x42, 0xff, 0x08, 0x9c, 0x42, 0xff, 0x06, 0x9a, 0x43, 0xff, 0x07, 0x9a, 0x45, 0xff, 0x08, 0x9b, 0x44, 0xff, 0x06, 0x9b, 0x42, 0xff, 0x05, 0x9a, 0x41, 0xff, 0x06, 0x9b, 0x42, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x07, 0x9c, 0x43, 0xff, 0x07, 0x9c, 0x42, 0xff, 0x06, 0x9b, 0x41, 0xff, 0x07, 0x99, 0x41, 0xff, 0x07, 0x9a, 0x40, 0xff, 0x05, 0x98, 0x3c, 0xff, 0x03, 0x96, 0x3a, 0xff, 0x05, 0x94, 0x3a, 0xff, 0x07, 0x90, 0x3d, 0xff, 0x02, 0x83, 0x3a, 0xff, 0x03, 0x7f, 0x3c, 0xff, 0x04, 0x82, 0x46, 0xff, 0x02, 0x84, 0x48, 0xff, 0x02, 0x8b, 0x4b, 0xff, 0x01, 0x90, 0x4b, 0xff, 0x06, 0x9b, 0x50, 0xff, 0x08, 0x9f, 0x51, 0xff, 0x06, 0x9b, 0x4e, 0xff, 0x04, 0x96, 0x4a, 0xff, 0x04, 0x96, 0x4b, 0xff, 0x02, 0x94, 0x49, 0xff, 0x01, 0x90, 0x45, 0xff, 0x01, 0x90, 0x47, 0xff, 0x00, 0x91, 0x48, 0xff, 0x00, 0x8f, 0x46, 0xff, 0x00, 0x92, 0x47, 0xff, 0x00, 0x97, 0x4a, 0xff, 0x01, 0x9b, 0x4f, 0xff, 0x04, 0x9c, 0x54, 0xff, 0x09, 0x9e, 0x5a, 0xff, 0x0b, 0xa0, 0x5f, 0xff, 0x08, 0xa0, 0x5f, 0xff, 0x06, 0x9f, 0x5e, 0xff, 0x07, 0xa0, 0x5f, 0xff, 0x08, 0x9f, 0x5f, 0xff, 0x07, 0x9e, 0x5e, 0xff, 0x09, 0x9d, 0x5d, 0xff, 0x08, 0x9c, 0x5c, 0xff, 0x09, 0x9c, 0x5d, 0xff, 0x0b, 0x9f, 0x62, 0xff, 0x0b, 0xa0, 0x64, 0xff, 0x0d, 0xa2, 0x68, 0xff, 0x0d, 0xa3, 0x69, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x0c, 0xa3, 0x6d, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x0c, 0xa8, 0x71, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x0b, 0xaa, 0x71, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x04, 0xa3, 0x6b, 0xff, 0x03, 0xa4, 0x67, 0xff, 0x04, 0xa0, 0x5f, 0xff, 0x06, 0x9e, 0x63, 0xff, 0x13, 0xa8, 0x75, 0xff, 0x47, 0xd8, 0xaa, 0xff, 0x2a, 0xb7, 0x8a, 0xff, 0x14, 0x9e, 0x6f, 0xff, 0x0e, 0x95, 0x67, 0xff, 0x19, 0x99, 0x74, 0xff, 0x32, 0xa8, 0x91, 0xff, 0x42, 0xc0, 0xa4, 0xff, 0x2d, 0xb6, 0x91, 0xff, 0x15, 0xab, 0x7c, 0xff, 0x07, 0xa3, 0x6f, 0xff, 0x07, 0xa4, 0x70, 0xff, 0x0d, 0xa7, 0x74, 0xff, 0x0f, 0xa7, 0x75, 0xff, 0x0d, 0xa4, 0x70, 0xff, 0x0e, 0xa6, 0x6f, 0xff, 0x07, 0xa2, 0x66, 0xff, 0x02, 0xa3, 0x5f, 0xff, 0x01, 0xa6, 0x5d, 0xff, 0x0a, 0xaf, 0x68, 0xff, 0x18, 0xb7, 0x75, 0xff, 0x13, 0xad, 0x70, 0xff, 0x10, 0xa7, 0x6b, 0xff, 0x13, 0xa3, 0x68, 0xff, 0x16, 0xa2, 0x6a, 0xff, 0x13, 0xa5, 0x6c, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x0c, 0xa2, 0x6b, 0xff, 0x12, 0xa0, 0x6a, 0xff, 0x08, 0x99, 0x61, 0xff, 0x07, 0x9a, 0x5e, 0xff, 0x04, 0x9c, 0x5c, 0xff, 0x04, 0x9d, 0x5c, 0xff, 0x04, 0x9c, 0x5c, 0xff, 0x0b, 0xa0, 0x65, 0xff, 0x0d, 0xa2, 0x64, 0xff, 0x0e, 0xa4, 0x64, 0xff, 0x0b, 0xa2, 0x66, 0xff, 0x08, 0xa3, 0x68, 0xff, 0x0b, 0xa5, 0x69, 0xff, 0x0e, 0xa3, 0x67, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x06, 0xa6, 0x6d, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x09, 0xa3, 0x72, 0xff, 0x05, 0xa5, 0x6d, 0xff, 0x02, 0xa6, 0x6b, 0xff, 0x03, 0xa7, 0x70, 0xff, 0x0b, 0xab, 0x76, 0xff, 0x0b, 0xa9, 0x73, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x07, 0xa3, 0x6b, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0e, 0xa3, 0x6a, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa1, 0x63, 0xff, 0x11, 0xa0, 0x61, 0xff, 0x10, 0x9a, 0x5a, 0xff, 0x08, 0x93, 0x4e, 0xff, 0x07, 0x88, 0x47, 0xff, 0x08, 0x85, 0x45, 0xff, 0x06, 0x84, 0x46, 0xff, 0x09, 0x88, 0x48, 0xff, 0x07, 0x8d, 0x47, 0xff, 0x05, 0x90, 0x4c, 0xff, 0x07, 0x92, 0x50, 0xff, 0x0a, 0x90, 0x4d, 0xff, 0x0b, 0x8c, 0x49, 0xff, 0x0a, 0x8c, 0x45, 0xff, 0x0c, 0x8d, 0x47, 0xff, 0x0a, 0x8d, 0x46, 0xff, 0x07, 0x8c, 0x45, 0xff, 0x07, 0x8a, 0x47, 0xff, 0x08, 0x8a, 0x45, 0xff, 0x0b, 0x8a, 0x44, 0xff, 0x08, 0x85, 0x42, 0xff, 0x06, 0x82, 0x41, 0xff, 0x05, 0x80, 0x42, 0xff, 0x07, 0x7f, 0x43, 0xff, 0x09, 0x7e, 0x42, 0xff, 0x0a, 0x7e, 0x41, 0xff, 0x0a, 0x7f, 0x3f, 0xff, 0x06, 0x7e, 0x40, 0xff, 0x06, 0x78, 0x40, 0xff, 0x07, 0x78, 0x40, 0xff, 0x07, 0x79, 0x3e, 0xff, 0x0c, 0x76, 0x3e, 0xff, 0x0c, 0x74, 0x3e, 0xff, 0x0a, 0x73, 0x3d, 0xff, 0x05, 0x74, 0x44, 0xff, 0x04, 0x71, 0x3f, 0xff, 0x03, 0x6a, 0x3a, 0xff, 0x0e, 0x7c, 0x49, 0xff, 0x2d, 0xb1, 0x71, 0xff, 0x39, 0xe0, 0x95, 0xff, 0x2b, 0xf5, 0xa4, 0xff, 0x21, 0xf3, 0xa2, 0xff, 0x1f, 0xe7, 0x98, 0xff, 0x07, 0xad, 0x5b, 0xff, 0x0b, 0xc4, 0x59, 0xff, 0x12, 0xec, 0x78, 0xff, 0x0f, 0xe8, 0x6c, 0xff, 0x06, 0xb8, 0x3a, 0xff, 0x03, 0xa8, 0x32, 0xff, 0x09, 0xc3, 0x4a, 0xff, 0x07, 0xaa, 0x37, 0xff, 0x09, 0x93, 0x29, 0xff, 0x09, 0x90, 0x2c, 0xff, 0x07, 0x96, 0x31, 0xff, 0x00, 0x8d, 0x27, 0xff, 0x08, 0x9d, 0x32, 0xff, 0x1b, 0xc6, 0x64, 0xff, 0x13, 0xbe, 0x61, 0xff, 0x05, 0xaf, 0x46, 0xff, 0x10, 0xcc, 0x63, 0xff, 0x06, 0x9e, 0x43, 0xff, 0x07, 0x67, 0x21, 0xff, 0x01, 0x42, 0x10, 0xff, 0x00, 0x4b, 0x1d, 0xff, 0x0a, 0x53, 0x22, 0xff, 0x09, 0x48, 0x15, 0xff, 0x61, 0x81, 0x70, 0xff, + 0x07, 0x30, 0x1d, 0xff, 0x08, 0x35, 0x1e, 0xff, 0x04, 0x39, 0x1c, 0xff, 0x1e, 0x67, 0x48, 0xff, 0x0b, 0x4e, 0x32, 0xff, 0x05, 0x40, 0x27, 0xff, 0x04, 0x37, 0x24, 0xff, 0x05, 0x2e, 0x23, 0xff, 0x04, 0x32, 0x20, 0xff, 0x04, 0x4c, 0x25, 0xff, 0x16, 0x8d, 0x4f, 0xff, 0x17, 0xa3, 0x51, 0xff, 0x19, 0x98, 0x46, 0xff, 0x07, 0x75, 0x28, 0xff, 0x11, 0x7d, 0x38, 0xff, 0x0a, 0x80, 0x3c, 0xff, 0x08, 0x9a, 0x4c, 0xff, 0x03, 0xa2, 0x52, 0xff, 0x14, 0xac, 0x66, 0xff, 0x0a, 0x67, 0x39, 0xff, 0x06, 0x3c, 0x1f, 0xff, 0x0b, 0x41, 0x29, 0xff, 0x07, 0x45, 0x28, 0xff, 0x08, 0x5b, 0x2f, 0xff, 0x09, 0x7e, 0x42, 0xff, 0x0b, 0xa5, 0x55, 0xff, 0x1a, 0xb4, 0x68, 0xff, 0x0d, 0x72, 0x48, 0xff, 0x00, 0x38, 0x23, 0xff, 0x01, 0x4c, 0x2c, 0xff, 0x04, 0x68, 0x38, 0xff, 0x04, 0x56, 0x2c, 0xff, 0x02, 0x50, 0x29, 0xff, 0x10, 0x80, 0x51, 0xff, 0x07, 0x79, 0x68, 0xff, 0x05, 0x46, 0x95, 0xff, 0x04, 0x3e, 0xc6, 0xff, 0x0c, 0x5a, 0xef, 0xff, 0x0d, 0x56, 0xea, 0xff, 0x0b, 0x5d, 0xee, 0xff, 0x02, 0x61, 0xf5, 0xff, 0x07, 0x62, 0xf6, 0xff, 0x0a, 0x60, 0xf5, 0xff, 0x02, 0x64, 0xef, 0xff, 0x02, 0x64, 0xf2, 0xff, 0x07, 0x61, 0xf0, 0xff, 0x09, 0x5d, 0xf3, 0xff, 0x02, 0x4e, 0xe7, 0xff, 0x09, 0x41, 0xea, 0xff, 0x09, 0x32, 0xd7, 0xff, 0x02, 0x38, 0xb0, 0xff, 0x07, 0x71, 0x8a, 0xff, 0x11, 0xa2, 0x7c, 0xff, 0x05, 0xa9, 0x6d, 0xff, 0x05, 0xa7, 0x6f, 0xff, 0x05, 0x9d, 0x66, 0xff, 0x02, 0x9a, 0x63, 0xff, 0x06, 0xa4, 0x6d, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x05, 0xa9, 0x6f, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x05, 0xa9, 0x6f, 0xff, 0x08, 0xac, 0x72, 0xff, 0x0b, 0xaf, 0x72, 0xff, 0x0d, 0xaf, 0x73, 0xff, 0x09, 0xaa, 0x6c, 0xff, 0x0a, 0xa8, 0x68, 0xff, 0x06, 0xa2, 0x62, 0xff, 0x06, 0x9e, 0x62, 0xff, 0x06, 0x9b, 0x60, 0xff, 0x08, 0x9a, 0x63, 0xff, 0x08, 0x97, 0x66, 0xff, 0x04, 0x9d, 0x62, 0xff, 0x06, 0x9e, 0x5e, 0xff, 0x0f, 0x99, 0x64, 0xff, 0x04, 0xa4, 0x67, 0xff, 0x09, 0xa2, 0x60, 0xff, 0x16, 0x96, 0x59, 0xff, 0x1f, 0xab, 0x60, 0xff, 0x15, 0xa8, 0x6b, 0xff, 0x17, 0xb5, 0x78, 0xff, 0x05, 0xa7, 0x69, 0xff, 0x0a, 0xae, 0x6f, 0xff, 0x06, 0xaf, 0x70, 0xff, 0x0b, 0xb0, 0x71, 0xff, 0x0d, 0xaf, 0x72, 0xff, 0x07, 0xaf, 0x72, 0xff, 0x03, 0xad, 0x6a, 0xff, 0x04, 0xae, 0x6a, 0xff, 0x04, 0xab, 0x67, 0xff, 0x04, 0xa9, 0x66, 0xff, 0x07, 0xa9, 0x66, 0xff, 0x09, 0xa9, 0x66, 0xff, 0x09, 0xa7, 0x64, 0xff, 0x07, 0xa6, 0x63, 0xff, 0x07, 0xa6, 0x61, 0xff, 0x08, 0xa7, 0x61, 0xff, 0x09, 0xa8, 0x62, 0xff, 0x0a, 0xa9, 0x63, 0xff, 0x0b, 0xa9, 0x65, 0xff, 0x0b, 0xa9, 0x65, 0xff, 0x0a, 0xa9, 0x66, 0xff, 0x0c, 0xab, 0x68, 0xff, 0x0b, 0xab, 0x68, 0xff, 0x09, 0xaa, 0x69, 0xff, 0x07, 0xaa, 0x6b, 0xff, 0x06, 0xaa, 0x6b, 0xff, 0x05, 0xaa, 0x6c, 0xff, 0x05, 0xab, 0x6a, 0xff, 0x08, 0xac, 0x68, 0xff, 0x09, 0xac, 0x66, 0xff, 0x08, 0xaa, 0x60, 0xff, 0x06, 0xa7, 0x5b, 0xff, 0x04, 0xa2, 0x57, 0xff, 0x04, 0x9e, 0x54, 0xff, 0x04, 0x9d, 0x50, 0xff, 0x04, 0x9a, 0x4c, 0xff, 0x02, 0x9a, 0x47, 0xff, 0x04, 0x9c, 0x48, 0xff, 0x07, 0x9f, 0x4f, 0xff, 0x08, 0xa2, 0x52, 0xff, 0x0b, 0xa4, 0x56, 0xff, 0x0b, 0xa5, 0x59, 0xff, 0x0d, 0xa5, 0x5b, 0xff, 0x0d, 0xa5, 0x5b, 0xff, 0x0f, 0xa5, 0x5a, 0xff, 0x0d, 0xa3, 0x58, 0xff, 0x09, 0xa2, 0x53, 0xff, 0x07, 0xa1, 0x4c, 0xff, 0x09, 0x9f, 0x43, 0xff, 0x09, 0x9e, 0x3f, 0xff, 0x06, 0x9c, 0x3e, 0xff, 0x06, 0x9b, 0x42, 0xff, 0x06, 0x9a, 0x45, 0xff, 0x09, 0x9a, 0x46, 0xff, 0x08, 0x9b, 0x46, 0xff, 0x07, 0x9b, 0x44, 0xff, 0x05, 0x99, 0x42, 0xff, 0x03, 0x99, 0x42, 0xff, 0x04, 0x9a, 0x41, 0xff, 0x07, 0x9b, 0x42, 0xff, 0x09, 0x9b, 0x41, 0xff, 0x08, 0x99, 0x3f, 0xff, 0x05, 0x95, 0x3d, 0xff, 0x05, 0x95, 0x3d, 0xff, 0x03, 0x96, 0x39, 0xff, 0x02, 0x95, 0x36, 0xff, 0x02, 0x92, 0x36, 0xff, 0x04, 0x8e, 0x39, 0xff, 0x04, 0x8b, 0x44, 0xff, 0x04, 0x8c, 0x4d, 0xff, 0x03, 0x8b, 0x4e, 0xff, 0x02, 0x8d, 0x4f, 0xff, 0x02, 0x8e, 0x4d, 0xff, 0x01, 0x91, 0x4a, 0xff, 0x01, 0x93, 0x45, 0xff, 0x01, 0x95, 0x41, 0xff, 0x01, 0x96, 0x45, 0xff, 0x01, 0x95, 0x47, 0xff, 0x03, 0x97, 0x4b, 0xff, 0x02, 0x97, 0x4a, 0xff, 0x01, 0x96, 0x4b, 0xff, 0x03, 0x95, 0x4c, 0xff, 0x04, 0x99, 0x4e, 0xff, 0x03, 0x9a, 0x50, 0xff, 0x04, 0x9d, 0x52, 0xff, 0x04, 0xa0, 0x54, 0xff, 0x02, 0xa2, 0x56, 0xff, 0x05, 0xa2, 0x59, 0xff, 0x0c, 0x9f, 0x5d, 0xff, 0x0a, 0x9f, 0x5e, 0xff, 0x05, 0xa1, 0x5f, 0xff, 0x01, 0xa1, 0x5d, 0xff, 0x05, 0xa0, 0x5f, 0xff, 0x06, 0x9f, 0x62, 0xff, 0x04, 0x9f, 0x60, 0xff, 0x05, 0x9f, 0x5c, 0xff, 0x0b, 0x9e, 0x5d, 0xff, 0x0e, 0xa1, 0x62, 0xff, 0x0d, 0xa5, 0x67, 0xff, 0x0c, 0xa5, 0x69, 0xff, 0x0d, 0xa4, 0x6a, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa3, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x08, 0xa7, 0x6c, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x09, 0xa4, 0x6d, 0xff, 0x03, 0xa0, 0x66, 0xff, 0x00, 0x9e, 0x60, 0xff, 0x06, 0xa0, 0x66, 0xff, 0x18, 0xae, 0x77, 0xff, 0x1d, 0xae, 0x7a, 0xff, 0x07, 0x91, 0x5e, 0xff, 0x07, 0x93, 0x5f, 0xff, 0x18, 0xa3, 0x6e, 0xff, 0x17, 0x98, 0x6d, 0xff, 0x32, 0xa1, 0x8d, 0xff, 0x4e, 0xc1, 0xaa, 0xff, 0x3b, 0xb8, 0x9b, 0xff, 0x12, 0x9e, 0x78, 0xff, 0x0c, 0xa2, 0x76, 0xff, 0x08, 0xa6, 0x74, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x0c, 0xa8, 0x72, 0xff, 0x0d, 0xa6, 0x73, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x04, 0xa1, 0x69, 0xff, 0x07, 0xa8, 0x6d, 0xff, 0x03, 0xa6, 0x68, 0xff, 0x0a, 0xad, 0x70, 0xff, 0x0e, 0xb2, 0x76, 0xff, 0x09, 0xac, 0x71, 0xff, 0x0b, 0xad, 0x71, 0xff, 0x08, 0xa9, 0x6e, 0xff, 0x0c, 0xaa, 0x71, 0xff, 0x0c, 0xa8, 0x70, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0e, 0xa7, 0x71, 0xff, 0x0f, 0xa7, 0x70, 0xff, 0x11, 0xa5, 0x6f, 0xff, 0x0d, 0x9e, 0x69, 0xff, 0x09, 0x9d, 0x62, 0xff, 0x07, 0xa1, 0x61, 0xff, 0x01, 0x9e, 0x5b, 0xff, 0x03, 0x9a, 0x5c, 0xff, 0x09, 0x97, 0x5d, 0xff, 0x0b, 0x9b, 0x5d, 0xff, 0x08, 0x9d, 0x57, 0xff, 0x08, 0x9b, 0x5c, 0xff, 0x03, 0xa0, 0x60, 0xff, 0x09, 0xa3, 0x5e, 0xff, 0x18, 0xa5, 0x62, 0xff, 0x0f, 0x9e, 0x65, 0xff, 0x03, 0x9e, 0x64, 0xff, 0x06, 0xa3, 0x64, 0xff, 0x0b, 0xa0, 0x69, 0xff, 0x0e, 0xa3, 0x77, 0xff, 0x0a, 0xa9, 0x6f, 0xff, 0x06, 0xac, 0x6d, 0xff, 0x05, 0xa8, 0x73, 0xff, 0x0a, 0xa6, 0x78, 0xff, 0x0e, 0xa6, 0x72, 0xff, 0x0b, 0xa2, 0x67, 0xff, 0x0c, 0xa1, 0x64, 0xff, 0x11, 0x9c, 0x67, 0xff, 0x09, 0x9d, 0x66, 0xff, 0x0c, 0x9a, 0x61, 0xff, 0x10, 0x97, 0x5b, 0xff, 0x05, 0x98, 0x58, 0xff, 0x06, 0x94, 0x54, 0xff, 0x0c, 0x8c, 0x4e, 0xff, 0x08, 0x85, 0x46, 0xff, 0x02, 0x85, 0x3f, 0xff, 0x08, 0x81, 0x44, 0xff, 0x09, 0x84, 0x46, 0xff, 0x05, 0x89, 0x4b, 0xff, 0x08, 0x91, 0x50, 0xff, 0x09, 0x99, 0x4f, 0xff, 0x07, 0x96, 0x55, 0xff, 0x08, 0x91, 0x53, 0xff, 0x06, 0x8c, 0x4a, 0xff, 0x08, 0x8b, 0x48, 0xff, 0x07, 0x8c, 0x42, 0xff, 0x0b, 0x8c, 0x48, 0xff, 0x08, 0x88, 0x43, 0xff, 0x08, 0x89, 0x45, 0xff, 0x08, 0x86, 0x48, 0xff, 0x08, 0x88, 0x44, 0xff, 0x0b, 0x85, 0x41, 0xff, 0x08, 0x81, 0x41, 0xff, 0x05, 0x80, 0x42, 0xff, 0x03, 0x7f, 0x43, 0xff, 0x05, 0x7e, 0x43, 0xff, 0x09, 0x7e, 0x43, 0xff, 0x0b, 0x7f, 0x41, 0xff, 0x0c, 0x7e, 0x3e, 0xff, 0x06, 0x7c, 0x3d, 0xff, 0x09, 0x75, 0x42, 0xff, 0x09, 0x76, 0x42, 0xff, 0x05, 0x79, 0x3d, 0xff, 0x0e, 0x75, 0x3d, 0xff, 0x0c, 0x73, 0x3e, 0xff, 0x09, 0x71, 0x3c, 0xff, 0x19, 0x99, 0x70, 0xff, 0x1c, 0xa6, 0x70, 0xff, 0x03, 0x7a, 0x44, 0xff, 0x02, 0x6f, 0x3c, 0xff, 0x03, 0x69, 0x26, 0xff, 0x09, 0x99, 0x42, 0xff, 0x17, 0xd9, 0x79, 0xff, 0x13, 0xe5, 0x87, 0xff, 0x16, 0xdf, 0x83, 0xff, 0x09, 0xb6, 0x53, 0xff, 0x09, 0xc6, 0x55, 0xff, 0x06, 0xe0, 0x67, 0xff, 0x13, 0xec, 0x68, 0xff, 0x12, 0xcb, 0x4e, 0xff, 0x08, 0xb3, 0x3f, 0xff, 0x09, 0xba, 0x3e, 0xff, 0x0c, 0xa9, 0x36, 0xff, 0x07, 0x95, 0x28, 0xff, 0x03, 0x8c, 0x30, 0xff, 0x04, 0x8d, 0x3e, 0xff, 0x02, 0x95, 0x2c, 0xff, 0x0d, 0xbd, 0x3d, 0xff, 0x09, 0xb2, 0x4d, 0xff, 0x07, 0xa2, 0x47, 0xff, 0x0a, 0xb2, 0x43, 0xff, 0x0b, 0xb5, 0x47, 0xff, 0x0c, 0x8a, 0x3c, 0xff, 0x0b, 0x62, 0x2b, 0xff, 0x00, 0x3d, 0x10, 0xff, 0x00, 0x37, 0x10, 0xff, 0x02, 0x3a, 0x14, 0xff, 0x02, 0x34, 0x0f, 0xff, 0x66, 0x7d, 0x6b, 0xff, + 0x05, 0x2d, 0x1a, 0xff, 0x06, 0x32, 0x1c, 0xff, 0x02, 0x35, 0x1a, 0xff, 0x1f, 0x67, 0x49, 0xff, 0x07, 0x44, 0x28, 0xff, 0x09, 0x44, 0x2b, 0xff, 0x04, 0x3a, 0x26, 0xff, 0x05, 0x31, 0x22, 0xff, 0x04, 0x32, 0x20, 0xff, 0x01, 0x3e, 0x1c, 0xff, 0x10, 0x7a, 0x42, 0xff, 0x07, 0x88, 0x3d, 0xff, 0x17, 0x8f, 0x40, 0xff, 0x0c, 0x79, 0x2f, 0xff, 0x0c, 0x7e, 0x38, 0xff, 0x0c, 0x85, 0x3e, 0xff, 0x0b, 0x98, 0x4b, 0xff, 0x08, 0xa6, 0x5b, 0xff, 0x17, 0xa0, 0x62, 0xff, 0x03, 0x4b, 0x24, 0xff, 0x05, 0x3e, 0x21, 0xff, 0x09, 0x43, 0x28, 0xff, 0x08, 0x48, 0x27, 0xff, 0x0d, 0x67, 0x35, 0xff, 0x0d, 0x89, 0x47, 0xff, 0x0d, 0xa9, 0x5b, 0xff, 0x1a, 0xad, 0x68, 0xff, 0x04, 0x55, 0x2f, 0xff, 0x00, 0x3b, 0x23, 0xff, 0x06, 0x4d, 0x2c, 0xff, 0x05, 0x5e, 0x32, 0xff, 0x01, 0x4e, 0x28, 0xff, 0x00, 0x56, 0x2b, 0xff, 0x12, 0x8c, 0x56, 0xff, 0x09, 0x75, 0x51, 0xff, 0x12, 0x67, 0x80, 0xff, 0x03, 0x4e, 0x98, 0xff, 0x0b, 0x52, 0xcc, 0xff, 0x0f, 0x51, 0xdd, 0xff, 0x12, 0x63, 0xec, 0xff, 0x03, 0x62, 0xf0, 0xff, 0x0d, 0x63, 0xf3, 0xff, 0x10, 0x60, 0xf1, 0xff, 0x09, 0x66, 0xed, 0xff, 0x06, 0x62, 0xf0, 0xff, 0x0f, 0x5f, 0xf2, 0xff, 0x09, 0x52, 0xed, 0xff, 0x08, 0x49, 0xe6, 0xff, 0x06, 0x3c, 0xd9, 0xff, 0x08, 0x43, 0xbd, 0xff, 0x04, 0x56, 0x97, 0xff, 0x0e, 0x8d, 0x82, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x06, 0xa7, 0x6c, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x08, 0xa2, 0x6b, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x05, 0xa9, 0x6f, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x05, 0xa9, 0x70, 0xff, 0x09, 0xae, 0x71, 0xff, 0x0b, 0xb0, 0x73, 0xff, 0x0b, 0xad, 0x6f, 0xff, 0x0b, 0xab, 0x6c, 0xff, 0x04, 0xa0, 0x63, 0xff, 0x02, 0x9c, 0x60, 0xff, 0x05, 0x9d, 0x62, 0xff, 0x0a, 0x9c, 0x66, 0xff, 0x10, 0x9f, 0x6b, 0xff, 0x0a, 0xa9, 0x6b, 0xff, 0x07, 0xac, 0x69, 0xff, 0x0d, 0xa7, 0x6f, 0xff, 0x14, 0xb3, 0x72, 0xff, 0x22, 0xb1, 0x6e, 0xff, 0x0f, 0x7b, 0x41, 0xff, 0x1f, 0xa0, 0x56, 0xff, 0x10, 0xa3, 0x63, 0xff, 0x1d, 0xb8, 0x79, 0xff, 0x07, 0xa7, 0x69, 0xff, 0x08, 0xac, 0x6f, 0xff, 0x06, 0xac, 0x6f, 0xff, 0x0d, 0xb2, 0x75, 0xff, 0x0e, 0xb3, 0x76, 0xff, 0x0a, 0xae, 0x72, 0xff, 0x07, 0xaf, 0x6f, 0xff, 0x06, 0xad, 0x6c, 0xff, 0x06, 0xad, 0x6b, 0xff, 0x06, 0xad, 0x6b, 0xff, 0x06, 0xab, 0x69, 0xff, 0x05, 0xab, 0x68, 0xff, 0x04, 0xa9, 0x66, 0xff, 0x04, 0xa8, 0x65, 0xff, 0x06, 0xa9, 0x65, 0xff, 0x08, 0xaa, 0x66, 0xff, 0x08, 0xab, 0x67, 0xff, 0x09, 0xab, 0x67, 0xff, 0x0a, 0xab, 0x68, 0xff, 0x08, 0xa9, 0x67, 0xff, 0x05, 0xa7, 0x66, 0xff, 0x07, 0xaa, 0x69, 0xff, 0x0b, 0xaa, 0x6b, 0xff, 0x0c, 0xa9, 0x6b, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0d, 0xa8, 0x6d, 0xff, 0x0d, 0xa8, 0x6e, 0xff, 0x0b, 0xa8, 0x6c, 0xff, 0x0a, 0xa9, 0x69, 0xff, 0x09, 0xa9, 0x68, 0xff, 0x0c, 0xa8, 0x65, 0xff, 0x0d, 0xa8, 0x64, 0xff, 0x0c, 0xa6, 0x62, 0xff, 0x09, 0xa2, 0x5d, 0xff, 0x08, 0xa0, 0x58, 0xff, 0x07, 0x9e, 0x53, 0xff, 0x03, 0x9c, 0x4b, 0xff, 0x01, 0x99, 0x47, 0xff, 0x02, 0x99, 0x47, 0xff, 0x06, 0x9d, 0x4c, 0xff, 0x08, 0xa1, 0x51, 0xff, 0x08, 0xa1, 0x54, 0xff, 0x08, 0xa1, 0x56, 0xff, 0x0a, 0xa3, 0x59, 0xff, 0x0d, 0xa4, 0x5b, 0xff, 0x0c, 0xa3, 0x5a, 0xff, 0x08, 0xa1, 0x54, 0xff, 0x03, 0x9d, 0x49, 0xff, 0x06, 0x9c, 0x41, 0xff, 0x07, 0x9d, 0x3e, 0xff, 0x05, 0x9c, 0x3d, 0xff, 0x06, 0x9d, 0x41, 0xff, 0x06, 0x9b, 0x43, 0xff, 0x08, 0x9a, 0x44, 0xff, 0x09, 0x9b, 0x43, 0xff, 0x08, 0x9b, 0x41, 0xff, 0x06, 0x9a, 0x41, 0xff, 0x05, 0x99, 0x40, 0xff, 0x06, 0x9b, 0x3f, 0xff, 0x08, 0x9b, 0x3f, 0xff, 0x09, 0x99, 0x3d, 0xff, 0x08, 0x97, 0x3a, 0xff, 0x07, 0x93, 0x36, 0xff, 0x05, 0x93, 0x35, 0xff, 0x03, 0x95, 0x35, 0xff, 0x03, 0x96, 0x36, 0xff, 0x04, 0x95, 0x3a, 0xff, 0x04, 0x92, 0x40, 0xff, 0x0e, 0x9c, 0x58, 0xff, 0x0f, 0x9f, 0x63, 0xff, 0x0b, 0x9d, 0x60, 0xff, 0x09, 0x9c, 0x5c, 0xff, 0x09, 0x9a, 0x5a, 0xff, 0x09, 0x99, 0x55, 0xff, 0x04, 0x95, 0x4b, 0xff, 0x00, 0x92, 0x44, 0xff, 0x02, 0x98, 0x4c, 0xff, 0x04, 0x9c, 0x53, 0xff, 0x07, 0x9e, 0x58, 0xff, 0x06, 0x9f, 0x57, 0xff, 0x04, 0x9f, 0x56, 0xff, 0x07, 0x9e, 0x56, 0xff, 0x08, 0x9e, 0x57, 0xff, 0x06, 0x9f, 0x57, 0xff, 0x06, 0xa1, 0x59, 0xff, 0x08, 0xa3, 0x5a, 0xff, 0x04, 0xa2, 0x59, 0xff, 0x03, 0xa1, 0x5b, 0xff, 0x0a, 0x9f, 0x5e, 0xff, 0x08, 0x9f, 0x5e, 0xff, 0x04, 0xa2, 0x5e, 0xff, 0x04, 0xa2, 0x5d, 0xff, 0x09, 0x9f, 0x5f, 0xff, 0x09, 0x9f, 0x63, 0xff, 0x06, 0x9f, 0x63, 0xff, 0x07, 0xa0, 0x5f, 0xff, 0x0c, 0xa1, 0x61, 0xff, 0x10, 0xa4, 0x66, 0xff, 0x0f, 0xa7, 0x6b, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x08, 0xa7, 0x6c, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x03, 0xa1, 0x67, 0xff, 0x02, 0x9f, 0x63, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x13, 0xa9, 0x71, 0xff, 0x2b, 0xbc, 0x86, 0xff, 0x1c, 0xab, 0x76, 0xff, 0x13, 0xa1, 0x6c, 0xff, 0x2e, 0xbc, 0x87, 0xff, 0x1e, 0xa4, 0x75, 0xff, 0x0e, 0x84, 0x66, 0xff, 0x25, 0x9f, 0x7e, 0xff, 0x2a, 0xac, 0x88, 0xff, 0x0e, 0x9c, 0x72, 0xff, 0x0d, 0xa5, 0x77, 0xff, 0x0c, 0xab, 0x78, 0xff, 0x08, 0xa7, 0x73, 0xff, 0x0b, 0xa7, 0x74, 0xff, 0x0f, 0xa8, 0x74, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa8, 0x6d, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x09, 0xab, 0x71, 0xff, 0x0a, 0xae, 0x74, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x09, 0xac, 0x71, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x0b, 0xab, 0x71, 0xff, 0x0a, 0xa9, 0x70, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x0e, 0xa4, 0x6b, 0xff, 0x08, 0xa1, 0x63, 0xff, 0x02, 0x9c, 0x5a, 0xff, 0x05, 0x9b, 0x59, 0xff, 0x07, 0x98, 0x58, 0xff, 0x05, 0x95, 0x55, 0xff, 0x05, 0x98, 0x54, 0xff, 0x05, 0x95, 0x53, 0xff, 0x01, 0x9b, 0x53, 0xff, 0x03, 0x9c, 0x55, 0xff, 0x0d, 0x9f, 0x57, 0xff, 0x05, 0x94, 0x59, 0xff, 0x07, 0x91, 0x60, 0xff, 0x11, 0x97, 0x5e, 0xff, 0x0a, 0x8f, 0x61, 0xff, 0x04, 0x90, 0x68, 0xff, 0x0c, 0x9f, 0x6b, 0xff, 0x0f, 0xa7, 0x6f, 0xff, 0x0c, 0xa5, 0x74, 0xff, 0x07, 0xa3, 0x72, 0xff, 0x08, 0xa2, 0x69, 0xff, 0x09, 0x9e, 0x60, 0xff, 0x0d, 0x97, 0x5e, 0xff, 0x0c, 0x90, 0x59, 0xff, 0x06, 0x90, 0x55, 0xff, 0x06, 0x8b, 0x4f, 0xff, 0x05, 0x87, 0x49, 0xff, 0x01, 0x89, 0x48, 0xff, 0x02, 0x87, 0x47, 0xff, 0x07, 0x82, 0x46, 0xff, 0x02, 0x81, 0x43, 0xff, 0x06, 0x84, 0x43, 0xff, 0x07, 0x8a, 0x4d, 0xff, 0x08, 0x8f, 0x50, 0xff, 0x0c, 0x94, 0x54, 0xff, 0x0c, 0x9a, 0x57, 0xff, 0x0d, 0x99, 0x57, 0xff, 0x0f, 0x93, 0x54, 0xff, 0x0c, 0x8e, 0x4b, 0xff, 0x09, 0x89, 0x48, 0xff, 0x06, 0x89, 0x49, 0xff, 0x04, 0x8b, 0x45, 0xff, 0x04, 0x8b, 0x49, 0xff, 0x04, 0x88, 0x43, 0xff, 0x05, 0x84, 0x45, 0xff, 0x08, 0x83, 0x46, 0xff, 0x08, 0x81, 0x45, 0xff, 0x05, 0x80, 0x43, 0xff, 0x05, 0x80, 0x41, 0xff, 0x07, 0x81, 0x3f, 0xff, 0x08, 0x81, 0x3d, 0xff, 0x0a, 0x81, 0x3d, 0xff, 0x0d, 0x81, 0x3f, 0xff, 0x0d, 0x7f, 0x40, 0xff, 0x0c, 0x7c, 0x40, 0xff, 0x09, 0x79, 0x3c, 0xff, 0x0a, 0x75, 0x41, 0xff, 0x0b, 0x76, 0x44, 0xff, 0x07, 0x75, 0x3f, 0xff, 0x0a, 0x74, 0x40, 0xff, 0x06, 0x71, 0x3f, 0xff, 0x05, 0x70, 0x41, 0xff, 0x21, 0xb2, 0x89, 0xff, 0x29, 0xd1, 0x85, 0xff, 0x0d, 0xa0, 0x50, 0xff, 0x12, 0x96, 0x54, 0xff, 0x04, 0x7e, 0x34, 0xff, 0x03, 0x94, 0x37, 0xff, 0x05, 0xb2, 0x49, 0xff, 0x05, 0xbd, 0x56, 0xff, 0x10, 0xc6, 0x62, 0xff, 0x05, 0xa6, 0x3e, 0xff, 0x14, 0xd2, 0x60, 0xff, 0x06, 0xd8, 0x64, 0xff, 0x09, 0xd5, 0x5c, 0xff, 0x0f, 0xc8, 0x4c, 0xff, 0x0c, 0xad, 0x39, 0xff, 0x08, 0xa5, 0x31, 0xff, 0x17, 0xb3, 0x41, 0xff, 0x06, 0x9c, 0x30, 0xff, 0x0c, 0x9b, 0x5b, 0xff, 0x0a, 0x96, 0x6a, 0xff, 0x04, 0x9c, 0x36, 0xff, 0x0d, 0xb5, 0x32, 0xff, 0x01, 0x95, 0x2e, 0xff, 0x01, 0x88, 0x2d, 0xff, 0x08, 0xa2, 0x3e, 0xff, 0x02, 0xa1, 0x3b, 0xff, 0x09, 0x86, 0x35, 0xff, 0x0a, 0x61, 0x29, 0xff, 0x05, 0x44, 0x19, 0xff, 0x03, 0x37, 0x13, 0xff, 0x00, 0x31, 0x10, 0xff, 0x00, 0x31, 0x0f, 0xff, 0x6a, 0x80, 0x71, 0xff, + 0x03, 0x29, 0x19, 0xff, 0x07, 0x32, 0x1c, 0xff, 0x02, 0x34, 0x1b, 0xff, 0x18, 0x5c, 0x40, 0xff, 0x04, 0x3b, 0x21, 0xff, 0x0c, 0x44, 0x2c, 0xff, 0x08, 0x40, 0x2a, 0xff, 0x04, 0x36, 0x23, 0xff, 0x03, 0x33, 0x21, 0xff, 0x00, 0x36, 0x19, 0xff, 0x0a, 0x5f, 0x32, 0xff, 0x0d, 0x83, 0x40, 0xff, 0x03, 0x6e, 0x25, 0xff, 0x0f, 0x7c, 0x35, 0xff, 0x09, 0x81, 0x38, 0xff, 0x08, 0x89, 0x3c, 0xff, 0x0b, 0x93, 0x48, 0xff, 0x16, 0xaa, 0x67, 0xff, 0x0d, 0x77, 0x44, 0xff, 0x02, 0x3f, 0x1f, 0xff, 0x05, 0x41, 0x26, 0xff, 0x06, 0x45, 0x26, 0xff, 0x0a, 0x50, 0x29, 0xff, 0x10, 0x76, 0x3b, 0xff, 0x08, 0x90, 0x47, 0xff, 0x12, 0xb0, 0x65, 0xff, 0x11, 0x95, 0x5b, 0xff, 0x00, 0x41, 0x20, 0xff, 0x00, 0x3d, 0x1f, 0xff, 0x0d, 0x51, 0x2b, 0xff, 0x05, 0x52, 0x27, 0xff, 0x01, 0x5a, 0x2b, 0xff, 0x01, 0x72, 0x3a, 0xff, 0x10, 0x93, 0x5c, 0xff, 0x09, 0x6c, 0x41, 0xff, 0x22, 0x96, 0x79, 0xff, 0x0f, 0x81, 0x83, 0xff, 0x03, 0x4d, 0x8f, 0xff, 0x04, 0x41, 0xab, 0xff, 0x0b, 0x57, 0xdc, 0xff, 0x03, 0x58, 0xe2, 0xff, 0x18, 0x63, 0xf3, 0xff, 0x17, 0x5d, 0xf3, 0xff, 0x10, 0x63, 0xf2, 0xff, 0x07, 0x57, 0xed, 0xff, 0x12, 0x58, 0xf0, 0xff, 0x09, 0x4b, 0xe3, 0xff, 0x09, 0x46, 0xd0, 0xff, 0x02, 0x3e, 0xb3, 0xff, 0x03, 0x55, 0x90, 0xff, 0x0e, 0x83, 0x85, 0xff, 0x0d, 0xa2, 0x73, 0xff, 0x04, 0xa4, 0x6b, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x05, 0xa7, 0x6d, 0xff, 0x06, 0xab, 0x70, 0xff, 0x0a, 0xaf, 0x72, 0xff, 0x0c, 0xb0, 0x72, 0xff, 0x0e, 0xb0, 0x72, 0xff, 0x09, 0xa7, 0x6a, 0xff, 0x08, 0xa5, 0x68, 0xff, 0x0f, 0xaa, 0x6f, 0xff, 0x13, 0xac, 0x72, 0xff, 0x16, 0xb1, 0x76, 0xff, 0x0e, 0xb7, 0x77, 0xff, 0x0a, 0xb6, 0x74, 0xff, 0x10, 0xb2, 0x76, 0xff, 0x29, 0xb7, 0x73, 0xff, 0x2e, 0xac, 0x66, 0xff, 0x04, 0x4b, 0x13, 0xff, 0x0d, 0x7a, 0x34, 0xff, 0x0f, 0x9a, 0x56, 0xff, 0x17, 0xab, 0x6c, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x08, 0xab, 0x6f, 0xff, 0x09, 0xaa, 0x71, 0xff, 0x09, 0xae, 0x72, 0xff, 0x08, 0xae, 0x70, 0xff, 0x0f, 0xac, 0x6f, 0xff, 0x06, 0xa7, 0x6a, 0xff, 0x06, 0xaa, 0x6d, 0xff, 0x06, 0xac, 0x6d, 0xff, 0x05, 0xab, 0x6c, 0xff, 0x01, 0xa9, 0x68, 0xff, 0x02, 0xab, 0x69, 0xff, 0x01, 0xac, 0x68, 0xff, 0x00, 0xab, 0x67, 0xff, 0x03, 0xa9, 0x67, 0xff, 0x03, 0xa9, 0x67, 0xff, 0x03, 0xa9, 0x67, 0xff, 0x03, 0xa9, 0x67, 0xff, 0x02, 0xa8, 0x67, 0xff, 0x02, 0xa9, 0x67, 0xff, 0x01, 0xa8, 0x65, 0xff, 0x02, 0xa9, 0x67, 0xff, 0x07, 0xa7, 0x6b, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x09, 0xa8, 0x6b, 0xff, 0x08, 0xa8, 0x6c, 0xff, 0x07, 0xa8, 0x6a, 0xff, 0x05, 0xa7, 0x69, 0xff, 0x05, 0xa8, 0x6a, 0xff, 0x05, 0xa8, 0x6a, 0xff, 0x08, 0xa6, 0x67, 0xff, 0x08, 0xa5, 0x68, 0xff, 0x0b, 0xa7, 0x67, 0xff, 0x0a, 0xa5, 0x63, 0xff, 0x08, 0xa2, 0x5c, 0xff, 0x07, 0xa1, 0x57, 0xff, 0x06, 0x9b, 0x4e, 0xff, 0x05, 0x98, 0x49, 0xff, 0x04, 0x98, 0x45, 0xff, 0x05, 0x99, 0x46, 0xff, 0x06, 0x9d, 0x4c, 0xff, 0x06, 0x9e, 0x51, 0xff, 0x07, 0x9f, 0x54, 0xff, 0x0a, 0xa4, 0x5b, 0xff, 0x0d, 0xa7, 0x5f, 0xff, 0x0c, 0xa5, 0x5f, 0xff, 0x09, 0xa4, 0x59, 0xff, 0x01, 0x9c, 0x4b, 0xff, 0x02, 0x99, 0x41, 0xff, 0x05, 0x9b, 0x3f, 0xff, 0x04, 0x9b, 0x3d, 0xff, 0x04, 0x9d, 0x3f, 0xff, 0x06, 0x9c, 0x3f, 0xff, 0x07, 0x9b, 0x3f, 0xff, 0x0a, 0x9c, 0x40, 0xff, 0x08, 0x9a, 0x3e, 0xff, 0x06, 0x98, 0x3c, 0xff, 0x06, 0x99, 0x3c, 0xff, 0x09, 0x9b, 0x3e, 0xff, 0x09, 0x9b, 0x3d, 0xff, 0x08, 0x97, 0x38, 0xff, 0x05, 0x92, 0x34, 0xff, 0x07, 0x93, 0x2f, 0xff, 0x06, 0x93, 0x2e, 0xff, 0x06, 0x97, 0x33, 0xff, 0x04, 0x97, 0x38, 0xff, 0x01, 0x93, 0x3e, 0xff, 0x04, 0x95, 0x49, 0xff, 0x11, 0xa5, 0x67, 0xff, 0x0f, 0xa7, 0x6f, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x0a, 0xa5, 0x64, 0xff, 0x0e, 0xa3, 0x64, 0xff, 0x0f, 0xa1, 0x60, 0xff, 0x09, 0x9b, 0x57, 0xff, 0x04, 0x98, 0x53, 0xff, 0x04, 0x9c, 0x58, 0xff, 0x06, 0xa1, 0x61, 0xff, 0x09, 0xa3, 0x64, 0xff, 0x08, 0xa3, 0x62, 0xff, 0x07, 0xa6, 0x64, 0xff, 0x08, 0xa3, 0x61, 0xff, 0x09, 0x9e, 0x5c, 0xff, 0x05, 0x9f, 0x5c, 0xff, 0x05, 0xa2, 0x5f, 0xff, 0x0b, 0xa5, 0x63, 0xff, 0x07, 0xa4, 0x61, 0xff, 0x01, 0xa0, 0x5f, 0xff, 0x04, 0x9e, 0x5e, 0xff, 0x03, 0x9f, 0x5d, 0xff, 0x02, 0xa2, 0x5d, 0xff, 0x06, 0xa0, 0x5c, 0xff, 0x0d, 0x9e, 0x5f, 0xff, 0x0c, 0xa1, 0x67, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa3, 0x66, 0xff, 0x0c, 0xa4, 0x66, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0d, 0xa6, 0x6b, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0b, 0xa8, 0x6c, 0xff, 0x0a, 0xa8, 0x6d, 0xff, 0x09, 0xa8, 0x6e, 0xff, 0x09, 0xa8, 0x6f, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x08, 0xa3, 0x6b, 0xff, 0x07, 0xa3, 0x6a, 0xff, 0x09, 0xa6, 0x6a, 0xff, 0x0a, 0xa5, 0x6a, 0xff, 0x12, 0xa8, 0x70, 0xff, 0x26, 0xba, 0x83, 0xff, 0x12, 0xa3, 0x6d, 0xff, 0x12, 0xa2, 0x6b, 0xff, 0x32, 0xc3, 0x8c, 0xff, 0x1b, 0xa7, 0x73, 0xff, 0x06, 0x8b, 0x5d, 0xff, 0x28, 0xae, 0x80, 0xff, 0x1e, 0xa8, 0x79, 0xff, 0x09, 0x9b, 0x6b, 0xff, 0x0b, 0xa7, 0x75, 0xff, 0x08, 0xa8, 0x75, 0xff, 0x0b, 0xaa, 0x77, 0xff, 0x09, 0xa5, 0x72, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x08, 0xa1, 0x6b, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x07, 0xa9, 0x70, 0xff, 0x07, 0xaa, 0x71, 0xff, 0x05, 0xa8, 0x6f, 0xff, 0x06, 0xaa, 0x70, 0xff, 0x04, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x0b, 0xa8, 0x71, 0xff, 0x0b, 0xa7, 0x70, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0d, 0xa7, 0x70, 0xff, 0x0e, 0xa8, 0x71, 0xff, 0x0d, 0xa7, 0x6e, 0xff, 0x09, 0xa2, 0x66, 0xff, 0x09, 0xa0, 0x5f, 0xff, 0x04, 0x9a, 0x53, 0xff, 0x02, 0x98, 0x4f, 0xff, 0x01, 0x96, 0x50, 0xff, 0x02, 0x95, 0x51, 0xff, 0x04, 0x97, 0x4a, 0xff, 0x02, 0x9a, 0x51, 0xff, 0x05, 0x99, 0x5e, 0xff, 0x0b, 0x97, 0x54, 0xff, 0x0b, 0x8b, 0x57, 0xff, 0x15, 0x83, 0x62, 0xff, 0x1a, 0x88, 0x59, 0xff, 0x0b, 0x7c, 0x59, 0xff, 0x04, 0x77, 0x4a, 0xff, 0x05, 0x7a, 0x44, 0xff, 0x0b, 0x7f, 0x4a, 0xff, 0x16, 0x8d, 0x5c, 0xff, 0x12, 0x92, 0x5e, 0xff, 0x07, 0x90, 0x52, 0xff, 0x05, 0x8d, 0x4e, 0xff, 0x02, 0x81, 0x4d, 0xff, 0x04, 0x82, 0x46, 0xff, 0x01, 0x81, 0x42, 0xff, 0x01, 0x82, 0x42, 0xff, 0x02, 0x81, 0x40, 0xff, 0x01, 0x81, 0x42, 0xff, 0x02, 0x80, 0x44, 0xff, 0x07, 0x80, 0x45, 0xff, 0x02, 0x83, 0x47, 0xff, 0x09, 0x8a, 0x4b, 0xff, 0x0b, 0x94, 0x56, 0xff, 0x0a, 0x98, 0x58, 0xff, 0x0b, 0x9b, 0x58, 0xff, 0x07, 0x9a, 0x57, 0xff, 0x0e, 0x8f, 0x56, 0xff, 0x13, 0x8a, 0x4e, 0xff, 0x0a, 0x8e, 0x42, 0xff, 0x0e, 0x8f, 0x4a, 0xff, 0x17, 0x98, 0x5b, 0xff, 0x19, 0x9d, 0x5e, 0xff, 0x11, 0x96, 0x58, 0xff, 0x0b, 0x91, 0x4a, 0xff, 0x03, 0x83, 0x40, 0xff, 0x05, 0x84, 0x40, 0xff, 0x05, 0x7e, 0x43, 0xff, 0x02, 0x7e, 0x44, 0xff, 0x04, 0x80, 0x41, 0xff, 0x0a, 0x81, 0x3e, 0xff, 0x0d, 0x81, 0x3a, 0xff, 0x0f, 0x82, 0x39, 0xff, 0x0d, 0x81, 0x3d, 0xff, 0x0c, 0x7e, 0x40, 0xff, 0x0b, 0x79, 0x42, 0xff, 0x0b, 0x77, 0x3e, 0xff, 0x08, 0x77, 0x3f, 0xff, 0x09, 0x73, 0x42, 0xff, 0x09, 0x71, 0x45, 0xff, 0x07, 0x71, 0x43, 0xff, 0x05, 0x6e, 0x3f, 0xff, 0x09, 0x6b, 0x43, 0xff, 0x11, 0xa3, 0x7a, 0xff, 0x22, 0xe0, 0x84, 0xff, 0x0b, 0xb9, 0x4d, 0xff, 0x1c, 0xbf, 0x63, 0xff, 0x07, 0xad, 0x4d, 0xff, 0x04, 0xa3, 0x3c, 0xff, 0x0c, 0xae, 0x44, 0xff, 0x04, 0xa4, 0x3c, 0xff, 0x03, 0x9e, 0x37, 0xff, 0x03, 0x96, 0x2a, 0xff, 0x18, 0xd3, 0x5e, 0xff, 0x10, 0xe3, 0x6e, 0xff, 0x08, 0xcf, 0x5d, 0xff, 0x09, 0xc0, 0x48, 0xff, 0x07, 0x98, 0x2d, 0xff, 0x0a, 0x92, 0x35, 0xff, 0x08, 0x9d, 0x36, 0xff, 0x08, 0xa7, 0x43, 0xff, 0x2a, 0xc3, 0xa9, 0xff, 0x1c, 0xab, 0xaa, 0xff, 0x09, 0x9e, 0x49, 0xff, 0x10, 0xa1, 0x26, 0xff, 0x03, 0x85, 0x22, 0xff, 0x06, 0x89, 0x2b, 0xff, 0x0e, 0x9a, 0x40, 0xff, 0x06, 0x9b, 0x3c, 0xff, 0x06, 0x7f, 0x2e, 0xff, 0x0a, 0x5f, 0x27, 0xff, 0x0c, 0x4a, 0x22, 0xff, 0x0d, 0x43, 0x21, 0xff, 0x05, 0x37, 0x19, 0xff, 0x01, 0x30, 0x10, 0xff, 0x66, 0x80, 0x6c, 0xff, + 0x02, 0x29, 0x19, 0xff, 0x07, 0x30, 0x1e, 0xff, 0x03, 0x35, 0x1f, 0xff, 0x0e, 0x4d, 0x34, 0xff, 0x01, 0x38, 0x1f, 0xff, 0x08, 0x3f, 0x28, 0xff, 0x0e, 0x48, 0x2f, 0xff, 0x01, 0x37, 0x20, 0xff, 0x01, 0x32, 0x20, 0xff, 0x03, 0x34, 0x1d, 0xff, 0x04, 0x49, 0x24, 0xff, 0x1e, 0x86, 0x4c, 0xff, 0x04, 0x69, 0x27, 0xff, 0x0d, 0x7c, 0x37, 0xff, 0x07, 0x84, 0x39, 0xff, 0x05, 0x90, 0x3f, 0xff, 0x13, 0x9e, 0x56, 0xff, 0x18, 0x90, 0x5a, 0xff, 0x04, 0x4e, 0x2a, 0xff, 0x04, 0x3c, 0x23, 0xff, 0x05, 0x42, 0x25, 0xff, 0x06, 0x4a, 0x25, 0xff, 0x0f, 0x61, 0x31, 0xff, 0x11, 0x84, 0x40, 0xff, 0x05, 0x99, 0x4a, 0xff, 0x13, 0xaa, 0x65, 0xff, 0x08, 0x70, 0x42, 0xff, 0x01, 0x3c, 0x1e, 0xff, 0x04, 0x45, 0x21, 0xff, 0x06, 0x52, 0x24, 0xff, 0x0a, 0x5c, 0x2b, 0xff, 0x09, 0x7d, 0x3d, 0xff, 0x0f, 0x9d, 0x57, 0xff, 0x0f, 0x86, 0x58, 0xff, 0x06, 0x63, 0x41, 0xff, 0x17, 0xa1, 0x6e, 0xff, 0x10, 0xa0, 0x75, 0xff, 0x0f, 0x7f, 0x82, 0xff, 0x09, 0x5c, 0x8f, 0xff, 0x01, 0x38, 0xa2, 0xff, 0x01, 0x3f, 0xad, 0xff, 0x15, 0x50, 0xc9, 0xff, 0x16, 0x4d, 0xd4, 0xff, 0x10, 0x55, 0xda, 0xff, 0x0a, 0x4f, 0xda, 0xff, 0x07, 0x4a, 0xca, 0xff, 0x04, 0x48, 0xbb, 0xff, 0x02, 0x4c, 0xa0, 0xff, 0x07, 0x60, 0x95, 0xff, 0x12, 0x86, 0x86, 0xff, 0x10, 0x9c, 0x78, 0xff, 0x04, 0xa5, 0x69, 0xff, 0x04, 0xa8, 0x6b, 0xff, 0x07, 0xa2, 0x6c, 0xff, 0x0a, 0xa2, 0x6e, 0xff, 0x0a, 0xa3, 0x6d, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x06, 0xa5, 0x6d, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x05, 0xa8, 0x6e, 0xff, 0x05, 0xa7, 0x6d, 0xff, 0x05, 0xa9, 0x6f, 0xff, 0x07, 0xab, 0x6f, 0xff, 0x09, 0xae, 0x70, 0xff, 0x0c, 0xb0, 0x72, 0xff, 0x0e, 0xb0, 0x73, 0xff, 0x0f, 0xb1, 0x73, 0xff, 0x13, 0xb2, 0x76, 0xff, 0x12, 0xb3, 0x76, 0xff, 0x0a, 0xb5, 0x72, 0xff, 0x08, 0xb3, 0x76, 0xff, 0x0a, 0xb5, 0x78, 0xff, 0x13, 0xb0, 0x74, 0xff, 0x1e, 0x9c, 0x55, 0xff, 0x11, 0x82, 0x37, 0xff, 0x0f, 0x5b, 0x23, 0xff, 0x05, 0x5e, 0x1e, 0xff, 0x1a, 0xab, 0x64, 0xff, 0x09, 0x94, 0x54, 0xff, 0x13, 0xa5, 0x68, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x01, 0xa5, 0x6a, 0xff, 0x06, 0xaa, 0x6b, 0xff, 0x05, 0x98, 0x59, 0xff, 0x01, 0x97, 0x5b, 0xff, 0x07, 0xa8, 0x6b, 0xff, 0x03, 0xa7, 0x69, 0xff, 0x03, 0xa9, 0x69, 0xff, 0x02, 0xaa, 0x67, 0xff, 0x00, 0xaa, 0x66, 0xff, 0x00, 0xaa, 0x64, 0xff, 0x00, 0xab, 0x63, 0xff, 0x02, 0xa9, 0x65, 0xff, 0x02, 0xaa, 0x65, 0xff, 0x03, 0xab, 0x67, 0xff, 0x05, 0xad, 0x69, 0xff, 0x07, 0xb0, 0x6a, 0xff, 0x07, 0xb1, 0x6b, 0xff, 0x07, 0xb2, 0x6b, 0xff, 0x07, 0xb2, 0x6a, 0xff, 0x04, 0xb1, 0x6d, 0xff, 0x03, 0xb0, 0x6d, 0xff, 0x03, 0xb1, 0x6a, 0xff, 0x04, 0xb2, 0x69, 0xff, 0x04, 0xb1, 0x68, 0xff, 0x03, 0xae, 0x67, 0xff, 0x02, 0xaa, 0x67, 0xff, 0x01, 0xa7, 0x65, 0xff, 0x01, 0xa3, 0x64, 0xff, 0x01, 0xa2, 0x63, 0xff, 0x03, 0xa5, 0x63, 0xff, 0x06, 0xa6, 0x64, 0xff, 0x08, 0xa6, 0x60, 0xff, 0x06, 0xa2, 0x5b, 0xff, 0x06, 0x9c, 0x51, 0xff, 0x06, 0x99, 0x4d, 0xff, 0x06, 0x99, 0x47, 0xff, 0x05, 0x98, 0x45, 0xff, 0x04, 0x99, 0x49, 0xff, 0x06, 0x9d, 0x51, 0xff, 0x09, 0xa0, 0x59, 0xff, 0x0d, 0xa6, 0x62, 0xff, 0x0f, 0xa8, 0x66, 0xff, 0x0d, 0xa8, 0x66, 0xff, 0x0c, 0xa9, 0x62, 0xff, 0x08, 0xa3, 0x58, 0xff, 0x05, 0x9d, 0x4a, 0xff, 0x04, 0x9c, 0x45, 0xff, 0x01, 0x9a, 0x41, 0xff, 0x01, 0x99, 0x3f, 0xff, 0x03, 0x9a, 0x3d, 0xff, 0x06, 0x9b, 0x3c, 0xff, 0x08, 0x9a, 0x3c, 0xff, 0x06, 0x97, 0x3a, 0xff, 0x03, 0x93, 0x36, 0xff, 0x04, 0x95, 0x37, 0xff, 0x06, 0x97, 0x37, 0xff, 0x06, 0x96, 0x36, 0xff, 0x06, 0x94, 0x33, 0xff, 0x05, 0x92, 0x32, 0xff, 0x08, 0x92, 0x2e, 0xff, 0x07, 0x95, 0x2f, 0xff, 0x04, 0x96, 0x37, 0xff, 0x02, 0x96, 0x3e, 0xff, 0x02, 0x94, 0x47, 0xff, 0x0c, 0x9f, 0x5c, 0xff, 0x12, 0xab, 0x70, 0xff, 0x09, 0xa7, 0x72, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x08, 0xa9, 0x6b, 0xff, 0x0d, 0xa9, 0x6d, 0xff, 0x0f, 0xa6, 0x6a, 0xff, 0x09, 0x9f, 0x61, 0xff, 0x05, 0x9e, 0x5d, 0xff, 0x06, 0xa3, 0x63, 0xff, 0x08, 0xa5, 0x6a, 0xff, 0x0c, 0xa9, 0x6f, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x08, 0xa9, 0x6d, 0xff, 0x05, 0xa6, 0x69, 0xff, 0x06, 0xa1, 0x64, 0xff, 0x06, 0xa1, 0x65, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x03, 0xa5, 0x68, 0xff, 0x05, 0xa2, 0x65, 0xff, 0x02, 0xa0, 0x60, 0xff, 0x01, 0xa0, 0x5b, 0xff, 0x08, 0xa0, 0x5b, 0xff, 0x10, 0xa1, 0x63, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0e, 0xa4, 0x6b, 0xff, 0x08, 0xa5, 0x6a, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0a, 0xa6, 0x6b, 0xff, 0x0b, 0xa5, 0x6d, 0xff, 0x0b, 0xa6, 0x6c, 0xff, 0x0a, 0xa8, 0x6c, 0xff, 0x0b, 0xa9, 0x6e, 0xff, 0x0b, 0xa8, 0x6f, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x04, 0xa2, 0x69, 0xff, 0x05, 0xa3, 0x6a, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x0d, 0xa8, 0x6e, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x0b, 0xa5, 0x6b, 0xff, 0x0c, 0xa4, 0x6b, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0c, 0xa0, 0x69, 0xff, 0x0f, 0xa4, 0x6c, 0xff, 0x13, 0xa8, 0x6f, 0xff, 0x0c, 0xa0, 0x67, 0xff, 0x0f, 0xa0, 0x68, 0xff, 0x18, 0xa9, 0x73, 0xff, 0x18, 0xab, 0x75, 0xff, 0x08, 0xa1, 0x6d, 0xff, 0x07, 0xa8, 0x73, 0xff, 0x08, 0xa9, 0x76, 0xff, 0x09, 0xa8, 0x76, 0xff, 0x09, 0xa6, 0x72, 0xff, 0x0e, 0xa9, 0x72, 0xff, 0x0a, 0xa5, 0x6e, 0xff, 0x06, 0xa3, 0x6c, 0xff, 0x06, 0xa7, 0x6d, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x05, 0xa7, 0x70, 0xff, 0x05, 0xa8, 0x71, 0xff, 0x04, 0xa7, 0x6e, 0xff, 0x03, 0xa7, 0x6e, 0xff, 0x05, 0xa7, 0x6e, 0xff, 0x07, 0xa7, 0x6e, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x0a, 0xa7, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0d, 0xaa, 0x73, 0xff, 0x0f, 0xad, 0x71, 0xff, 0x0c, 0xa7, 0x6a, 0xff, 0x0d, 0xa3, 0x62, 0xff, 0x05, 0x9c, 0x55, 0xff, 0x02, 0x9e, 0x4f, 0xff, 0x03, 0xa0, 0x52, 0xff, 0x09, 0xa2, 0x55, 0xff, 0x10, 0xae, 0x4e, 0xff, 0x11, 0xa8, 0x59, 0xff, 0x07, 0x95, 0x59, 0xff, 0x0c, 0x82, 0x4b, 0xff, 0x19, 0x6a, 0x58, 0xff, 0x16, 0x5d, 0x5a, 0xff, 0x06, 0x65, 0x3e, 0xff, 0x05, 0x67, 0x41, 0xff, 0x0a, 0x70, 0x39, 0xff, 0x06, 0x6f, 0x2c, 0xff, 0x02, 0x6c, 0x27, 0xff, 0x05, 0x6c, 0x30, 0xff, 0x03, 0x67, 0x2b, 0xff, 0x04, 0x6d, 0x2d, 0xff, 0x0b, 0x78, 0x3c, 0xff, 0x0d, 0x7d, 0x4b, 0xff, 0x07, 0x80, 0x44, 0xff, 0x02, 0x87, 0x47, 0xff, 0x05, 0x8a, 0x49, 0xff, 0x0f, 0x89, 0x4a, 0xff, 0x0e, 0x87, 0x49, 0xff, 0x0c, 0x87, 0x4b, 0xff, 0x0a, 0x89, 0x4c, 0xff, 0x05, 0x8b, 0x4e, 0xff, 0x05, 0x90, 0x51, 0xff, 0x0e, 0x95, 0x57, 0xff, 0x0e, 0x97, 0x59, 0xff, 0x06, 0x99, 0x54, 0xff, 0x03, 0x93, 0x4f, 0xff, 0x0c, 0x87, 0x4e, 0xff, 0x0e, 0x87, 0x49, 0xff, 0x04, 0x8a, 0x40, 0xff, 0x06, 0x89, 0x40, 0xff, 0x0b, 0x84, 0x48, 0xff, 0x10, 0x81, 0x48, 0xff, 0x15, 0x8a, 0x50, 0xff, 0x1f, 0x99, 0x59, 0xff, 0x1d, 0x9b, 0x54, 0xff, 0x08, 0x8a, 0x3f, 0xff, 0x03, 0x81, 0x3e, 0xff, 0x02, 0x7f, 0x40, 0xff, 0x08, 0x7e, 0x41, 0xff, 0x0e, 0x7f, 0x41, 0xff, 0x10, 0x7e, 0x3f, 0xff, 0x0e, 0x7f, 0x3f, 0xff, 0x08, 0x7d, 0x40, 0xff, 0x05, 0x7a, 0x41, 0xff, 0x07, 0x77, 0x42, 0xff, 0x0a, 0x77, 0x41, 0xff, 0x03, 0x77, 0x3d, 0xff, 0x07, 0x75, 0x46, 0xff, 0x0b, 0x7a, 0x54, 0xff, 0x02, 0x71, 0x45, 0xff, 0x08, 0x70, 0x42, 0xff, 0x0a, 0x66, 0x41, 0xff, 0x0c, 0x93, 0x67, 0xff, 0x1e, 0xe1, 0x82, 0xff, 0x02, 0xb4, 0x3f, 0xff, 0x0e, 0xb9, 0x4a, 0xff, 0x19, 0xcf, 0x5e, 0xff, 0x07, 0xaa, 0x3e, 0xff, 0x0a, 0x96, 0x34, 0xff, 0x17, 0xa4, 0x47, 0xff, 0x08, 0x8d, 0x31, 0xff, 0x02, 0x80, 0x1c, 0xff, 0x07, 0xbc, 0x43, 0xff, 0x08, 0xd5, 0x54, 0xff, 0x14, 0xdb, 0x65, 0xff, 0x0e, 0xc0, 0x4c, 0xff, 0x03, 0x88, 0x2e, 0xff, 0x0a, 0x8e, 0x55, 0xff, 0x01, 0x8c, 0x3e, 0xff, 0x01, 0x8e, 0x31, 0xff, 0x1d, 0xab, 0x99, 0xff, 0x19, 0x9b, 0xa6, 0xff, 0x09, 0x8f, 0x4d, 0xff, 0x0f, 0x90, 0x2a, 0xff, 0x0a, 0x8c, 0x29, 0xff, 0x09, 0x92, 0x2d, 0xff, 0x04, 0x8d, 0x2f, 0xff, 0x07, 0x90, 0x34, 0xff, 0x0b, 0x75, 0x2d, 0xff, 0x02, 0x4b, 0x17, 0xff, 0x06, 0x46, 0x1b, 0xff, 0x0f, 0x4b, 0x27, 0xff, 0x0c, 0x44, 0x24, 0xff, 0x02, 0x33, 0x12, 0xff, 0x64, 0x79, 0x67, 0xff, + 0x01, 0x28, 0x1a, 0xff, 0x05, 0x2e, 0x1d, 0xff, 0x04, 0x37, 0x22, 0xff, 0x0c, 0x48, 0x30, 0xff, 0x01, 0x37, 0x1f, 0xff, 0x04, 0x3a, 0x23, 0xff, 0x14, 0x4f, 0x35, 0xff, 0x02, 0x3b, 0x20, 0xff, 0x01, 0x34, 0x21, 0xff, 0x05, 0x30, 0x1f, 0xff, 0x03, 0x3a, 0x1d, 0xff, 0x20, 0x7c, 0x49, 0xff, 0x09, 0x6c, 0x2f, 0xff, 0x0e, 0x7e, 0x3a, 0xff, 0x07, 0x85, 0x39, 0xff, 0x02, 0x96, 0x44, 0xff, 0x1b, 0xa8, 0x63, 0xff, 0x0c, 0x64, 0x3a, 0xff, 0x03, 0x3a, 0x20, 0xff, 0x05, 0x3d, 0x26, 0xff, 0x06, 0x42, 0x23, 0xff, 0x0a, 0x56, 0x2a, 0xff, 0x0e, 0x73, 0x38, 0xff, 0x0d, 0x8f, 0x44, 0xff, 0x09, 0xa6, 0x53, 0xff, 0x0f, 0x97, 0x59, 0xff, 0x04, 0x4f, 0x2b, 0xff, 0x07, 0x43, 0x24, 0xff, 0x07, 0x4f, 0x24, 0xff, 0x03, 0x5f, 0x2a, 0xff, 0x0f, 0x75, 0x3d, 0xff, 0x0d, 0x9e, 0x54, 0xff, 0x21, 0xbd, 0x72, 0xff, 0x0a, 0x67, 0x43, 0xff, 0x07, 0x5f, 0x47, 0xff, 0x0a, 0x9f, 0x6d, 0xff, 0x06, 0xa6, 0x6e, 0xff, 0x13, 0x9d, 0x78, 0xff, 0x1d, 0x85, 0x86, 0xff, 0x0d, 0x44, 0x87, 0xff, 0x15, 0x4d, 0x92, 0xff, 0x19, 0x49, 0x99, 0xff, 0x0d, 0x41, 0x9d, 0xff, 0x03, 0x49, 0x9a, 0xff, 0x03, 0x49, 0x9b, 0xff, 0x03, 0x54, 0x8f, 0xff, 0x04, 0x64, 0x8c, 0xff, 0x13, 0x80, 0x8d, 0xff, 0x0e, 0x88, 0x7a, 0xff, 0x0e, 0x98, 0x70, 0xff, 0x0c, 0xa2, 0x6f, 0xff, 0x04, 0xa5, 0x6b, 0xff, 0x02, 0xa5, 0x67, 0xff, 0x08, 0xa3, 0x6e, 0xff, 0x0a, 0xa1, 0x72, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x08, 0xa4, 0x6d, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x08, 0xa8, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x05, 0xaa, 0x6d, 0xff, 0x05, 0xab, 0x6e, 0xff, 0x0a, 0xaf, 0x72, 0xff, 0x0f, 0xb3, 0x76, 0xff, 0x0f, 0xb2, 0x76, 0xff, 0x0d, 0xb3, 0x75, 0xff, 0x06, 0xb7, 0x73, 0xff, 0x0b, 0xb1, 0x77, 0xff, 0x0e, 0xb2, 0x79, 0xff, 0x17, 0xac, 0x70, 0xff, 0x05, 0x72, 0x27, 0xff, 0x22, 0x91, 0x47, 0xff, 0x30, 0x7d, 0x4c, 0xff, 0x14, 0x57, 0x23, 0xff, 0x21, 0xae, 0x65, 0xff, 0x09, 0x8f, 0x4a, 0xff, 0x0f, 0x97, 0x5a, 0xff, 0x0b, 0x9b, 0x63, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x03, 0xa5, 0x6a, 0xff, 0x03, 0x9c, 0x5c, 0xff, 0x03, 0x91, 0x50, 0xff, 0x0a, 0xa4, 0x65, 0xff, 0x0a, 0xa8, 0x69, 0xff, 0x08, 0xa8, 0x66, 0xff, 0x07, 0xaa, 0x66, 0xff, 0x06, 0xab, 0x64, 0xff, 0x05, 0xad, 0x64, 0xff, 0x09, 0xb2, 0x66, 0xff, 0x0c, 0xb8, 0x6a, 0xff, 0x10, 0xba, 0x6f, 0xff, 0x11, 0xbc, 0x6f, 0xff, 0x16, 0xc1, 0x74, 0xff, 0x19, 0xc6, 0x79, 0xff, 0x1c, 0xcb, 0x7d, 0xff, 0x1c, 0xce, 0x7f, 0xff, 0x1e, 0xd0, 0x7f, 0xff, 0x1d, 0xd1, 0x7f, 0xff, 0x15, 0xd5, 0x83, 0xff, 0x12, 0xd3, 0x80, 0xff, 0x13, 0xd1, 0x7b, 0xff, 0x17, 0xd2, 0x7a, 0xff, 0x1b, 0xd1, 0x7a, 0xff, 0x19, 0xcc, 0x79, 0xff, 0x14, 0xc4, 0x76, 0xff, 0x0f, 0xbd, 0x71, 0xff, 0x0c, 0xb6, 0x6d, 0xff, 0x07, 0xb1, 0x68, 0xff, 0x03, 0xac, 0x64, 0xff, 0x02, 0xaa, 0x62, 0xff, 0x04, 0xa8, 0x60, 0xff, 0x05, 0xa5, 0x5d, 0xff, 0x04, 0x9e, 0x55, 0xff, 0x04, 0x9a, 0x51, 0xff, 0x06, 0x9a, 0x4a, 0xff, 0x07, 0x9a, 0x49, 0xff, 0x06, 0x9b, 0x4e, 0xff, 0x08, 0x9e, 0x55, 0xff, 0x0a, 0xa1, 0x5e, 0xff, 0x0d, 0xa6, 0x66, 0xff, 0x0c, 0xa7, 0x6a, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x0d, 0xaa, 0x6b, 0xff, 0x0e, 0xa9, 0x66, 0xff, 0x0f, 0xa7, 0x5c, 0xff, 0x0c, 0xa4, 0x55, 0xff, 0x04, 0x9d, 0x4c, 0xff, 0x00, 0x99, 0x45, 0xff, 0x04, 0x9c, 0x42, 0xff, 0x08, 0x9e, 0x40, 0xff, 0x08, 0x9b, 0x3c, 0xff, 0x08, 0x97, 0x3a, 0xff, 0x05, 0x94, 0x36, 0xff, 0x04, 0x94, 0x34, 0xff, 0x04, 0x94, 0x33, 0xff, 0x04, 0x93, 0x35, 0xff, 0x04, 0x92, 0x34, 0xff, 0x05, 0x92, 0x34, 0xff, 0x06, 0x94, 0x34, 0xff, 0x05, 0x95, 0x37, 0xff, 0x02, 0x94, 0x3f, 0xff, 0x04, 0x97, 0x49, 0xff, 0x0c, 0x9f, 0x5c, 0xff, 0x15, 0xa9, 0x6b, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x07, 0xa6, 0x72, 0xff, 0x07, 0xa8, 0x71, 0xff, 0x07, 0xa8, 0x6f, 0xff, 0x09, 0xa8, 0x73, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x07, 0xa8, 0x6c, 0xff, 0x05, 0xa6, 0x68, 0xff, 0x08, 0xa8, 0x6b, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x0a, 0xa6, 0x71, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x05, 0xa9, 0x70, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x70, 0xff, 0x0b, 0xa7, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x04, 0xa6, 0x68, 0xff, 0x04, 0xa3, 0x60, 0xff, 0x0b, 0xa3, 0x60, 0xff, 0x0f, 0xa7, 0x68, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x11, 0xa5, 0x70, 0xff, 0x05, 0xa4, 0x6d, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x08, 0xa7, 0x6c, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x07, 0xa6, 0x6a, 0xff, 0x0b, 0xa8, 0x6d, 0xff, 0x0c, 0xa7, 0x6e, 0xff, 0x07, 0xa4, 0x6b, 0xff, 0x04, 0xa5, 0x6a, 0xff, 0x08, 0xa8, 0x6d, 0xff, 0x09, 0xa7, 0x6d, 0xff, 0x0c, 0xa8, 0x6e, 0xff, 0x09, 0xa5, 0x69, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa1, 0x68, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0d, 0xa5, 0x6b, 0xff, 0x0d, 0xa7, 0x6c, 0xff, 0x0f, 0xa8, 0x6d, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x06, 0xa8, 0x72, 0xff, 0x05, 0xa7, 0x73, 0xff, 0x06, 0xa6, 0x72, 0xff, 0x07, 0xa4, 0x70, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x0c, 0xa9, 0x71, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x08, 0xa8, 0x72, 0xff, 0x07, 0xa6, 0x71, 0xff, 0x05, 0xa7, 0x70, 0xff, 0x04, 0xa7, 0x6f, 0xff, 0x04, 0xa7, 0x6f, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x0a, 0xa7, 0x70, 0xff, 0x0f, 0xb1, 0x72, 0xff, 0x0e, 0xac, 0x6c, 0xff, 0x0b, 0x9f, 0x62, 0xff, 0x08, 0xa0, 0x5c, 0xff, 0x02, 0xa4, 0x4f, 0xff, 0x0a, 0xae, 0x56, 0xff, 0x10, 0xac, 0x54, 0xff, 0x08, 0xa8, 0x43, 0xff, 0x08, 0x9d, 0x44, 0xff, 0x06, 0x93, 0x47, 0xff, 0x20, 0x7c, 0x58, 0xff, 0x46, 0x61, 0x81, 0xff, 0x36, 0x5a, 0x78, 0xff, 0x17, 0x62, 0x4c, 0xff, 0x1f, 0x65, 0x4e, 0xff, 0x1e, 0x6f, 0x4b, 0xff, 0x15, 0x7f, 0x40, 0xff, 0x0a, 0x85, 0x36, 0xff, 0x0b, 0x83, 0x36, 0xff, 0x06, 0x6d, 0x27, 0xff, 0x05, 0x5d, 0x1c, 0xff, 0x05, 0x58, 0x20, 0xff, 0x09, 0x60, 0x32, 0xff, 0x0f, 0x7c, 0x45, 0xff, 0x10, 0x8e, 0x53, 0xff, 0x0d, 0x8d, 0x51, 0xff, 0x16, 0x8a, 0x4f, 0xff, 0x16, 0x87, 0x4b, 0xff, 0x0f, 0x8b, 0x4d, 0xff, 0x09, 0x90, 0x4f, 0xff, 0x06, 0x92, 0x51, 0xff, 0x01, 0x92, 0x55, 0xff, 0x0e, 0x94, 0x56, 0xff, 0x0f, 0x93, 0x56, 0xff, 0x05, 0x92, 0x4f, 0xff, 0x05, 0x8c, 0x47, 0xff, 0x08, 0x87, 0x48, 0xff, 0x09, 0x89, 0x4b, 0xff, 0x07, 0x7e, 0x46, 0xff, 0x05, 0x7d, 0x3c, 0xff, 0x0a, 0x7e, 0x3f, 0xff, 0x07, 0x6c, 0x34, 0xff, 0x02, 0x5c, 0x24, 0xff, 0x04, 0x5e, 0x32, 0xff, 0x1e, 0x85, 0x4f, 0xff, 0x1d, 0x95, 0x51, 0xff, 0x06, 0x82, 0x3a, 0xff, 0x07, 0x80, 0x3d, 0xff, 0x0b, 0x7e, 0x40, 0xff, 0x0f, 0x7d, 0x43, 0xff, 0x0d, 0x7c, 0x46, 0xff, 0x09, 0x7b, 0x46, 0xff, 0x04, 0x79, 0x44, 0xff, 0x02, 0x77, 0x41, 0xff, 0x07, 0x77, 0x42, 0xff, 0x0a, 0x76, 0x41, 0xff, 0x03, 0x77, 0x3f, 0xff, 0x02, 0x72, 0x45, 0xff, 0x2a, 0xa7, 0x83, 0xff, 0x26, 0xa6, 0x78, 0xff, 0x04, 0x73, 0x40, 0xff, 0x03, 0x65, 0x3d, 0xff, 0x13, 0xa3, 0x6d, 0xff, 0x20, 0xdf, 0x81, 0xff, 0x05, 0xb3, 0x42, 0xff, 0x03, 0xa1, 0x30, 0xff, 0x08, 0xad, 0x39, 0xff, 0x0a, 0x9e, 0x31, 0xff, 0x05, 0x7e, 0x21, 0xff, 0x0e, 0x8c, 0x38, 0xff, 0x0c, 0x82, 0x37, 0xff, 0x01, 0x6d, 0x19, 0xff, 0x0a, 0xb2, 0x3d, 0xff, 0x04, 0xc4, 0x3c, 0xff, 0x04, 0xbe, 0x41, 0xff, 0x14, 0xbd, 0x49, 0xff, 0x08, 0x81, 0x39, 0xff, 0x28, 0xaa, 0x91, 0xff, 0x03, 0x89, 0x58, 0xff, 0x02, 0x7d, 0x28, 0xff, 0x0a, 0x80, 0x57, 0xff, 0x18, 0x89, 0x75, 0xff, 0x02, 0x78, 0x3e, 0xff, 0x02, 0x81, 0x30, 0xff, 0x0b, 0x99, 0x36, 0xff, 0x06, 0x98, 0x2f, 0xff, 0x06, 0x8d, 0x2c, 0xff, 0x0a, 0x81, 0x2d, 0xff, 0x04, 0x54, 0x1c, 0xff, 0x00, 0x3e, 0x0f, 0xff, 0x00, 0x45, 0x14, 0xff, 0x03, 0x49, 0x1c, 0xff, 0x07, 0x49, 0x21, 0xff, 0x04, 0x3b, 0x16, 0xff, 0x60, 0x7b, 0x67, 0xff, + 0x04, 0x2b, 0x1d, 0xff, 0x06, 0x2f, 0x1e, 0xff, 0x05, 0x37, 0x24, 0xff, 0x0c, 0x44, 0x2f, 0xff, 0x02, 0x35, 0x1f, 0xff, 0x02, 0x37, 0x20, 0xff, 0x11, 0x4c, 0x32, 0xff, 0x0a, 0x49, 0x2f, 0xff, 0x01, 0x34, 0x22, 0xff, 0x07, 0x2f, 0x22, 0xff, 0x03, 0x34, 0x1d, 0xff, 0x15, 0x6a, 0x3b, 0xff, 0x0c, 0x70, 0x35, 0xff, 0x10, 0x80, 0x3e, 0xff, 0x09, 0x87, 0x3c, 0xff, 0x09, 0x9e, 0x4e, 0xff, 0x19, 0xa1, 0x61, 0xff, 0x07, 0x47, 0x27, 0xff, 0x0b, 0x38, 0x23, 0xff, 0x04, 0x3d, 0x25, 0xff, 0x04, 0x43, 0x21, 0xff, 0x0b, 0x61, 0x2e, 0xff, 0x0d, 0x7d, 0x3d, 0xff, 0x0a, 0x97, 0x49, 0xff, 0x0f, 0xab, 0x5c, 0xff, 0x0d, 0x80, 0x49, 0xff, 0x01, 0x42, 0x22, 0xff, 0x08, 0x4b, 0x2a, 0xff, 0x02, 0x58, 0x26, 0xff, 0x04, 0x76, 0x3a, 0xff, 0x09, 0x8a, 0x4e, 0xff, 0x0c, 0xaf, 0x67, 0xff, 0x22, 0xba, 0x77, 0xff, 0x05, 0x4c, 0x2e, 0xff, 0x09, 0x5f, 0x46, 0xff, 0x0b, 0x9d, 0x6d, 0xff, 0x04, 0xa1, 0x6c, 0xff, 0x13, 0x9f, 0x73, 0xff, 0x1a, 0x87, 0x78, 0xff, 0x1e, 0x56, 0x8d, 0xff, 0x29, 0x62, 0x96, 0xff, 0x3f, 0x74, 0xac, 0xff, 0x27, 0x6b, 0x9d, 0xff, 0x0d, 0x78, 0x84, 0xff, 0x10, 0x85, 0x88, 0xff, 0x0f, 0x91, 0x7d, 0xff, 0x0d, 0x9b, 0x78, 0xff, 0x14, 0x9e, 0x79, 0xff, 0x08, 0x90, 0x60, 0xff, 0x0b, 0xa0, 0x6a, 0xff, 0x0b, 0xa2, 0x6e, 0xff, 0x06, 0xa4, 0x6d, 0xff, 0x05, 0xa5, 0x6b, 0xff, 0x07, 0xa3, 0x6e, 0xff, 0x08, 0xa1, 0x72, 0xff, 0x07, 0xa3, 0x6d, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x09, 0xa9, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x06, 0xa9, 0x6f, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x03, 0xa7, 0x6c, 0xff, 0x04, 0xa9, 0x6b, 0xff, 0x07, 0xac, 0x6f, 0xff, 0x0a, 0xb0, 0x72, 0xff, 0x0a, 0xb1, 0x71, 0xff, 0x0a, 0xb4, 0x72, 0xff, 0x11, 0xaf, 0x7a, 0xff, 0x0f, 0xae, 0x76, 0xff, 0x19, 0xae, 0x70, 0xff, 0x16, 0x9a, 0x4b, 0xff, 0x32, 0xa1, 0x58, 0xff, 0x17, 0x4b, 0x25, 0xff, 0x1d, 0x5f, 0x2c, 0xff, 0x1d, 0x99, 0x4f, 0xff, 0x09, 0x90, 0x48, 0xff, 0x11, 0x91, 0x53, 0xff, 0x0a, 0x8b, 0x51, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x06, 0xa5, 0x66, 0xff, 0x0f, 0xa0, 0x5e, 0xff, 0x11, 0x9f, 0x5a, 0xff, 0x12, 0xab, 0x67, 0xff, 0x0c, 0xa9, 0x64, 0xff, 0x0a, 0xa8, 0x60, 0xff, 0x0a, 0xa9, 0x5f, 0xff, 0x0c, 0xab, 0x5f, 0xff, 0x0e, 0xb0, 0x61, 0xff, 0x0f, 0xb3, 0x61, 0xff, 0x0d, 0xb2, 0x5f, 0xff, 0x08, 0xb0, 0x5c, 0xff, 0x06, 0xb0, 0x5b, 0xff, 0x0a, 0xb6, 0x61, 0xff, 0x0c, 0xba, 0x63, 0xff, 0x0a, 0xb9, 0x60, 0xff, 0x07, 0xb7, 0x5d, 0xff, 0x08, 0xba, 0x5f, 0xff, 0x06, 0xb8, 0x5d, 0xff, 0x05, 0xba, 0x5d, 0xff, 0x04, 0xbc, 0x5e, 0xff, 0x05, 0xba, 0x59, 0xff, 0x07, 0xb9, 0x57, 0xff, 0x0a, 0xba, 0x5a, 0xff, 0x0c, 0xc1, 0x65, 0xff, 0x0c, 0xc3, 0x6a, 0xff, 0x0d, 0xc4, 0x6f, 0xff, 0x11, 0xc6, 0x75, 0xff, 0x0d, 0xc2, 0x70, 0xff, 0x0a, 0xba, 0x6b, 0xff, 0x08, 0xb5, 0x66, 0xff, 0x07, 0xad, 0x61, 0xff, 0x06, 0xa6, 0x5b, 0xff, 0x06, 0x9f, 0x56, 0xff, 0x06, 0x9b, 0x54, 0xff, 0x04, 0x99, 0x4b, 0xff, 0x06, 0x9b, 0x4d, 0xff, 0x07, 0x9c, 0x52, 0xff, 0x09, 0x9f, 0x5a, 0xff, 0x08, 0x9f, 0x60, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0b, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6e, 0xff, 0x0b, 0xa7, 0x6d, 0xff, 0x0d, 0xa8, 0x6a, 0xff, 0x12, 0xa9, 0x66, 0xff, 0x11, 0xa8, 0x61, 0xff, 0x0a, 0xa3, 0x58, 0xff, 0x05, 0x9e, 0x51, 0xff, 0x05, 0x9c, 0x49, 0xff, 0x07, 0x9d, 0x44, 0xff, 0x07, 0x99, 0x3c, 0xff, 0x06, 0x95, 0x39, 0xff, 0x05, 0x94, 0x36, 0xff, 0x06, 0x95, 0x36, 0xff, 0x04, 0x94, 0x35, 0xff, 0x05, 0x94, 0x38, 0xff, 0x03, 0x92, 0x38, 0xff, 0x03, 0x91, 0x3a, 0xff, 0x02, 0x92, 0x3c, 0xff, 0x01, 0x94, 0x41, 0xff, 0x03, 0x97, 0x4c, 0xff, 0x0b, 0x9f, 0x5b, 0xff, 0x16, 0xa9, 0x6d, 0xff, 0x14, 0xa9, 0x70, 0xff, 0x10, 0xa8, 0x72, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x0a, 0xa7, 0x72, 0xff, 0x05, 0xa6, 0x74, 0xff, 0x02, 0xa6, 0x73, 0xff, 0x01, 0xa9, 0x6f, 0xff, 0x02, 0xaa, 0x6c, 0xff, 0x05, 0xaa, 0x6b, 0xff, 0x08, 0xa9, 0x6d, 0xff, 0x04, 0xa7, 0x6f, 0xff, 0x0a, 0xa8, 0x72, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x04, 0xa7, 0x6f, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x06, 0xa3, 0x6e, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x0c, 0xa9, 0x72, 0xff, 0x06, 0xa7, 0x6e, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x0a, 0xa8, 0x6e, 0xff, 0x0b, 0xa4, 0x67, 0xff, 0x0f, 0xa8, 0x68, 0xff, 0x0a, 0xab, 0x6c, 0xff, 0x03, 0xab, 0x71, 0xff, 0x0c, 0xa8, 0x73, 0xff, 0x14, 0xa5, 0x72, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x04, 0xa6, 0x6d, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x05, 0xa6, 0x6b, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x04, 0xa6, 0x6c, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x0b, 0xa7, 0x6b, 0xff, 0x09, 0xa7, 0x6b, 0xff, 0x05, 0xa6, 0x6b, 0xff, 0x06, 0xa8, 0x6b, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0a, 0xa6, 0x6a, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0b, 0xa4, 0x6a, 0xff, 0x0e, 0xa5, 0x6a, 0xff, 0x0e, 0xa6, 0x6c, 0xff, 0x0d, 0xa7, 0x6c, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0e, 0xaa, 0x6f, 0xff, 0x0a, 0xa8, 0x6f, 0xff, 0x0d, 0xa8, 0x6f, 0xff, 0x0d, 0xa8, 0x71, 0xff, 0x0a, 0xa9, 0x71, 0xff, 0x06, 0xa8, 0x72, 0xff, 0x06, 0xa9, 0x72, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x09, 0xa4, 0x6e, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x07, 0xa7, 0x72, 0xff, 0x07, 0xa7, 0x73, 0xff, 0x07, 0xa8, 0x72, 0xff, 0x05, 0xa9, 0x70, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x06, 0xa8, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x09, 0xa6, 0x6f, 0xff, 0x0b, 0xa4, 0x6f, 0xff, 0x06, 0xaa, 0x69, 0xff, 0x09, 0xaa, 0x66, 0xff, 0x08, 0x9d, 0x61, 0xff, 0x03, 0x9c, 0x5a, 0xff, 0x0b, 0xb2, 0x5c, 0xff, 0x10, 0xb5, 0x5a, 0xff, 0x05, 0x97, 0x42, 0xff, 0x08, 0x96, 0x41, 0xff, 0x0c, 0xa0, 0x4a, 0xff, 0x10, 0xa0, 0x50, 0xff, 0x35, 0x80, 0x76, 0xff, 0x4e, 0x51, 0x93, 0xff, 0x38, 0x4b, 0x75, 0xff, 0x33, 0x60, 0x65, 0xff, 0x55, 0x60, 0x89, 0xff, 0x3f, 0x57, 0x73, 0xff, 0x20, 0x69, 0x52, 0xff, 0x0c, 0x7e, 0x3f, 0xff, 0x0b, 0x90, 0x3f, 0xff, 0x14, 0x8b, 0x41, 0xff, 0x13, 0x70, 0x30, 0xff, 0x11, 0x5e, 0x28, 0xff, 0x01, 0x46, 0x17, 0xff, 0x0b, 0x5d, 0x2d, 0xff, 0x17, 0x78, 0x47, 0xff, 0x13, 0x82, 0x4d, 0xff, 0x0b, 0x84, 0x4a, 0xff, 0x08, 0x83, 0x46, 0xff, 0x06, 0x87, 0x47, 0xff, 0x05, 0x8c, 0x49, 0xff, 0x08, 0x91, 0x4d, 0xff, 0x07, 0x93, 0x52, 0xff, 0x0a, 0x94, 0x54, 0xff, 0x0a, 0x91, 0x52, 0xff, 0x07, 0x89, 0x4b, 0xff, 0x09, 0x89, 0x45, 0xff, 0x07, 0x8a, 0x49, 0xff, 0x1b, 0x91, 0x63, 0xff, 0x1c, 0x6d, 0x5d, 0xff, 0x1f, 0x7c, 0x57, 0xff, 0x10, 0x83, 0x45, 0xff, 0x13, 0x7b, 0x41, 0xff, 0x10, 0x70, 0x35, 0xff, 0x09, 0x53, 0x41, 0xff, 0x0b, 0x4c, 0x40, 0xff, 0x0d, 0x66, 0x3e, 0xff, 0x1b, 0x89, 0x46, 0xff, 0x0f, 0x82, 0x3e, 0xff, 0x0b, 0x7f, 0x40, 0xff, 0x0a, 0x7e, 0x43, 0xff, 0x06, 0x7c, 0x44, 0xff, 0x05, 0x7a, 0x44, 0xff, 0x06, 0x7b, 0x44, 0xff, 0x05, 0x77, 0x40, 0xff, 0x09, 0x77, 0x3e, 0xff, 0x0c, 0x74, 0x3f, 0xff, 0x05, 0x74, 0x3d, 0xff, 0x01, 0x70, 0x42, 0xff, 0x2f, 0xb8, 0x91, 0xff, 0x3c, 0xc9, 0x95, 0xff, 0x19, 0x93, 0x58, 0xff, 0x03, 0x6f, 0x3b, 0xff, 0x0d, 0x97, 0x59, 0xff, 0x22, 0xda, 0x78, 0xff, 0x08, 0xb4, 0x42, 0xff, 0x04, 0xa1, 0x34, 0xff, 0x0a, 0xb1, 0x43, 0xff, 0x24, 0xca, 0x5e, 0xff, 0x0d, 0x99, 0x35, 0xff, 0x01, 0x7e, 0x27, 0xff, 0x05, 0x6e, 0x2d, 0xff, 0x03, 0x68, 0x24, 0xff, 0x0e, 0xa3, 0x3b, 0xff, 0x06, 0xb2, 0x33, 0xff, 0x01, 0xab, 0x2e, 0xff, 0x07, 0xaa, 0x35, 0xff, 0x10, 0x8a, 0x43, 0xff, 0x4d, 0xc9, 0xb9, 0xff, 0x07, 0x7f, 0x5f, 0xff, 0x01, 0x6f, 0x27, 0xff, 0x03, 0x76, 0x33, 0xff, 0x04, 0x6c, 0x2f, 0xff, 0x12, 0x8d, 0x53, 0xff, 0x03, 0x89, 0x44, 0xff, 0x06, 0x9e, 0x3c, 0xff, 0x0d, 0x99, 0x35, 0xff, 0x0e, 0x7d, 0x27, 0xff, 0x05, 0x5d, 0x1a, 0xff, 0x00, 0x38, 0x0e, 0xff, 0x00, 0x38, 0x11, 0xff, 0x02, 0x4f, 0x1a, 0xff, 0x00, 0x4a, 0x15, 0xff, 0x01, 0x44, 0x15, 0xff, 0x03, 0x3f, 0x16, 0xff, 0x61, 0x7d, 0x67, 0xff, + 0x04, 0x2e, 0x21, 0xff, 0x06, 0x2f, 0x20, 0xff, 0x09, 0x39, 0x28, 0xff, 0x08, 0x3e, 0x2b, 0xff, 0x06, 0x35, 0x22, 0xff, 0x03, 0x36, 0x22, 0xff, 0x07, 0x40, 0x29, 0xff, 0x12, 0x52, 0x3b, 0xff, 0x02, 0x38, 0x28, 0xff, 0x09, 0x31, 0x25, 0xff, 0x03, 0x34, 0x1f, 0xff, 0x04, 0x54, 0x29, 0xff, 0x11, 0x79, 0x3e, 0xff, 0x10, 0x84, 0x40, 0xff, 0x08, 0x89, 0x41, 0xff, 0x19, 0xa6, 0x5f, 0xff, 0x0a, 0x7c, 0x48, 0xff, 0x06, 0x3a, 0x21, 0xff, 0x0c, 0x36, 0x25, 0xff, 0x04, 0x3d, 0x22, 0xff, 0x03, 0x4c, 0x23, 0xff, 0x0a, 0x6e, 0x35, 0xff, 0x0b, 0x84, 0x40, 0xff, 0x0f, 0xa3, 0x57, 0xff, 0x1a, 0xab, 0x65, 0xff, 0x05, 0x5f, 0x2e, 0xff, 0x02, 0x44, 0x21, 0xff, 0x04, 0x55, 0x2a, 0xff, 0x02, 0x6f, 0x35, 0xff, 0x04, 0x8c, 0x4d, 0xff, 0x03, 0x9f, 0x5c, 0xff, 0x17, 0xbe, 0x7a, 0xff, 0x0d, 0x8c, 0x5b, 0xff, 0x01, 0x3a, 0x25, 0xff, 0x08, 0x59, 0x3e, 0xff, 0x15, 0x99, 0x67, 0xff, 0x0e, 0xa2, 0x6d, 0xff, 0x11, 0x91, 0x64, 0xff, 0x13, 0x7c, 0x63, 0xff, 0x27, 0x67, 0x83, 0xff, 0x57, 0x91, 0xb0, 0xff, 0x7d, 0xb3, 0xd9, 0xff, 0x51, 0x9f, 0xb3, 0xff, 0x16, 0x96, 0x73, 0xff, 0x15, 0xa0, 0x78, 0xff, 0x0d, 0xa1, 0x72, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x12, 0xab, 0x6c, 0xff, 0x03, 0x8b, 0x50, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x05, 0xa3, 0x6d, 0xff, 0x06, 0xa3, 0x6d, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x07, 0xa7, 0x6e, 0xff, 0x07, 0xa9, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x04, 0xa7, 0x6e, 0xff, 0x03, 0xa7, 0x6e, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x01, 0xa5, 0x6a, 0xff, 0x01, 0xa6, 0x69, 0xff, 0x02, 0xa8, 0x69, 0xff, 0x02, 0xa9, 0x69, 0xff, 0x07, 0xab, 0x6c, 0xff, 0x0d, 0xa9, 0x75, 0xff, 0x10, 0xa6, 0x6d, 0xff, 0x19, 0xa6, 0x64, 0xff, 0x21, 0xb5, 0x61, 0xff, 0x0e, 0x5f, 0x1f, 0xff, 0x01, 0x2d, 0x07, 0xff, 0x20, 0x82, 0x43, 0xff, 0x0e, 0x87, 0x3b, 0xff, 0x0f, 0x94, 0x49, 0xff, 0x26, 0x9a, 0x58, 0xff, 0x09, 0x73, 0x34, 0xff, 0x11, 0xa6, 0x66, 0xff, 0x1a, 0xb1, 0x6c, 0xff, 0x14, 0x9e, 0x57, 0xff, 0x11, 0x9c, 0x53, 0xff, 0x08, 0x9e, 0x53, 0xff, 0x04, 0x9b, 0x4d, 0xff, 0x03, 0x9a, 0x4b, 0xff, 0x04, 0x9d, 0x4c, 0xff, 0x04, 0x9f, 0x4b, 0xff, 0x03, 0x9c, 0x47, 0xff, 0x02, 0x9e, 0x46, 0xff, 0x04, 0xa2, 0x48, 0xff, 0x01, 0xa7, 0x48, 0xff, 0x01, 0xaa, 0x4c, 0xff, 0x01, 0xac, 0x4d, 0xff, 0x00, 0xab, 0x4b, 0xff, 0x01, 0xae, 0x4c, 0xff, 0x01, 0xb0, 0x4e, 0xff, 0x01, 0xb2, 0x4f, 0xff, 0x03, 0xb6, 0x52, 0xff, 0x0a, 0xb3, 0x4e, 0xff, 0x0a, 0xb4, 0x4f, 0xff, 0x05, 0xb5, 0x4f, 0xff, 0x02, 0xb4, 0x4f, 0xff, 0x02, 0xb5, 0x51, 0xff, 0x05, 0xb9, 0x5a, 0xff, 0x09, 0xba, 0x60, 0xff, 0x0a, 0xb9, 0x63, 0xff, 0x0c, 0xbb, 0x65, 0xff, 0x12, 0xc0, 0x6b, 0xff, 0x11, 0xba, 0x67, 0xff, 0x13, 0xba, 0x68, 0xff, 0x16, 0xb8, 0x69, 0xff, 0x11, 0xb1, 0x65, 0xff, 0x06, 0xa3, 0x59, 0xff, 0x02, 0x9e, 0x55, 0xff, 0x01, 0x9b, 0x50, 0xff, 0x01, 0x9b, 0x4f, 0xff, 0x06, 0x9e, 0x58, 0xff, 0x07, 0x9e, 0x5c, 0xff, 0x09, 0xa0, 0x64, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0c, 0xa7, 0x70, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0f, 0xa6, 0x69, 0xff, 0x10, 0xa7, 0x68, 0xff, 0x11, 0xa8, 0x67, 0xff, 0x0f, 0xa7, 0x63, 0xff, 0x0d, 0xa4, 0x59, 0xff, 0x07, 0x9c, 0x4a, 0xff, 0x04, 0x97, 0x3d, 0xff, 0x05, 0x96, 0x39, 0xff, 0x04, 0x94, 0x38, 0xff, 0x04, 0x95, 0x39, 0xff, 0x05, 0x95, 0x3c, 0xff, 0x02, 0x93, 0x3d, 0xff, 0x05, 0x96, 0x46, 0xff, 0x08, 0x99, 0x4c, 0xff, 0x04, 0x96, 0x4f, 0xff, 0x06, 0x9d, 0x58, 0xff, 0x0d, 0xa5, 0x65, 0xff, 0x11, 0xa8, 0x6c, 0xff, 0x14, 0xa6, 0x6f, 0xff, 0x14, 0xa6, 0x70, 0xff, 0x0f, 0xa6, 0x6e, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0e, 0xa7, 0x70, 0xff, 0x0f, 0xa7, 0x73, 0xff, 0x08, 0xa6, 0x74, 0xff, 0x04, 0xa9, 0x75, 0xff, 0x01, 0xa8, 0x6e, 0xff, 0x01, 0xaa, 0x6c, 0xff, 0x03, 0xaa, 0x6a, 0xff, 0x05, 0xa8, 0x69, 0xff, 0x02, 0xa8, 0x6e, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x06, 0xa9, 0x70, 0xff, 0x13, 0xaf, 0x76, 0xff, 0x0b, 0x9a, 0x65, 0xff, 0x09, 0xa1, 0x6e, 0xff, 0x0a, 0xa4, 0x73, 0xff, 0x07, 0xa0, 0x6b, 0xff, 0x09, 0xa9, 0x71, 0xff, 0x09, 0xa9, 0x72, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x05, 0x8d, 0x56, 0xff, 0x10, 0xa6, 0x6c, 0xff, 0x05, 0xae, 0x71, 0xff, 0x02, 0xad, 0x72, 0xff, 0x11, 0xa6, 0x72, 0xff, 0x08, 0x94, 0x64, 0xff, 0x06, 0xa8, 0x72, 0xff, 0x03, 0xa7, 0x6e, 0xff, 0x0e, 0xa7, 0x6c, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x03, 0xa6, 0x6a, 0xff, 0x07, 0xa6, 0x6d, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x03, 0xa6, 0x6c, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0c, 0xa7, 0x6c, 0xff, 0x0a, 0xa7, 0x6c, 0xff, 0x04, 0xa7, 0x6a, 0xff, 0x04, 0xa9, 0x6b, 0xff, 0x08, 0xa9, 0x6c, 0xff, 0x0b, 0xa7, 0x6c, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0e, 0xa7, 0x6a, 0xff, 0x0e, 0xa9, 0x6d, 0xff, 0x0c, 0xa8, 0x6c, 0xff, 0x0a, 0xa7, 0x6c, 0xff, 0x08, 0xa5, 0x6f, 0xff, 0x0b, 0xa6, 0x70, 0xff, 0x0d, 0xa7, 0x71, 0xff, 0x0b, 0xa9, 0x72, 0xff, 0x07, 0xa8, 0x72, 0xff, 0x04, 0xa6, 0x6f, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa6, 0x6d, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x09, 0xa7, 0x6f, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x07, 0xa7, 0x72, 0xff, 0x07, 0xa7, 0x72, 0xff, 0x06, 0xa7, 0x71, 0xff, 0x05, 0xa8, 0x70, 0xff, 0x05, 0xa8, 0x71, 0xff, 0x07, 0xa8, 0x71, 0xff, 0x07, 0xa8, 0x71, 0xff, 0x08, 0xa9, 0x71, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x02, 0xa6, 0x63, 0xff, 0x03, 0xa6, 0x62, 0xff, 0x08, 0x9f, 0x62, 0xff, 0x0b, 0xa8, 0x63, 0xff, 0x0a, 0xae, 0x58, 0xff, 0x06, 0x99, 0x48, 0xff, 0x17, 0x90, 0x54, 0xff, 0x17, 0x95, 0x57, 0xff, 0x07, 0x9d, 0x4b, 0xff, 0x0f, 0x93, 0x4d, 0xff, 0x3f, 0x65, 0x81, 0xff, 0x4d, 0x3f, 0x90, 0xff, 0x30, 0x41, 0x5a, 0xff, 0x4c, 0x65, 0x76, 0xff, 0x82, 0x66, 0xce, 0xff, 0x5a, 0x38, 0xa3, 0xff, 0x3b, 0x4f, 0x72, 0xff, 0x0f, 0x55, 0x3a, 0xff, 0x06, 0x71, 0x2d, 0xff, 0x15, 0x80, 0x3b, 0xff, 0x13, 0x6d, 0x30, 0xff, 0x0a, 0x54, 0x1f, 0xff, 0x04, 0x42, 0x15, 0xff, 0x03, 0x3f, 0x16, 0xff, 0x0a, 0x4c, 0x22, 0xff, 0x13, 0x6b, 0x3b, 0xff, 0x0d, 0x84, 0x4c, 0xff, 0x0b, 0x8b, 0x4e, 0xff, 0x04, 0x8a, 0x47, 0xff, 0x03, 0x8a, 0x44, 0xff, 0x09, 0x90, 0x47, 0xff, 0x11, 0x91, 0x4b, 0xff, 0x0c, 0x8a, 0x4c, 0xff, 0x0c, 0x89, 0x49, 0xff, 0x0c, 0x8a, 0x4a, 0xff, 0x08, 0x8b, 0x4a, 0xff, 0x24, 0x99, 0x6c, 0xff, 0x3d, 0x83, 0x88, 0xff, 0x4a, 0x56, 0x8f, 0xff, 0x3a, 0x63, 0x74, 0xff, 0x12, 0x75, 0x47, 0xff, 0x0c, 0x76, 0x3f, 0xff, 0x16, 0x7d, 0x41, 0xff, 0x26, 0x5f, 0x67, 0xff, 0x2d, 0x3d, 0x6a, 0xff, 0x15, 0x43, 0x42, 0xff, 0x0f, 0x5f, 0x2f, 0xff, 0x18, 0x7d, 0x41, 0xff, 0x0c, 0x80, 0x41, 0xff, 0x05, 0x7f, 0x3f, 0xff, 0x02, 0x7e, 0x3d, 0xff, 0x06, 0x7b, 0x3e, 0xff, 0x0b, 0x79, 0x3f, 0xff, 0x0c, 0x78, 0x3f, 0xff, 0x06, 0x75, 0x3c, 0xff, 0x05, 0x7f, 0x44, 0xff, 0x05, 0x8c, 0x4e, 0xff, 0x06, 0x8d, 0x56, 0xff, 0x11, 0xaf, 0x7b, 0xff, 0x10, 0xae, 0x6f, 0xff, 0x1d, 0xa8, 0x62, 0xff, 0x29, 0xad, 0x6b, 0xff, 0x09, 0x8a, 0x44, 0xff, 0x14, 0xc1, 0x5b, 0xff, 0x02, 0xa7, 0x33, 0xff, 0x07, 0xa1, 0x34, 0xff, 0x23, 0xc5, 0x60, 0xff, 0x08, 0x94, 0x34, 0xff, 0x0a, 0x8d, 0x2d, 0xff, 0x0d, 0x8b, 0x2f, 0xff, 0x02, 0x64, 0x18, 0xff, 0x04, 0x64, 0x21, 0xff, 0x08, 0x83, 0x2b, 0xff, 0x0e, 0x9c, 0x30, 0xff, 0x03, 0x9e, 0x28, 0xff, 0x00, 0xa0, 0x26, 0xff, 0x07, 0x87, 0x32, 0xff, 0x23, 0x92, 0x72, 0xff, 0x0c, 0x75, 0x57, 0xff, 0x09, 0x81, 0x55, 0xff, 0x08, 0x8c, 0x51, 0xff, 0x02, 0x6c, 0x21, 0xff, 0x3c, 0xb6, 0x83, 0xff, 0x10, 0x95, 0x5e, 0xff, 0x03, 0x8d, 0x31, 0xff, 0x05, 0x7a, 0x20, 0xff, 0x02, 0x4d, 0x0b, 0xff, 0x00, 0x36, 0x07, 0xff, 0x03, 0x33, 0x14, 0xff, 0x07, 0x3d, 0x19, 0xff, 0x0b, 0x5b, 0x22, 0xff, 0x01, 0x54, 0x1a, 0xff, 0x00, 0x45, 0x14, 0xff, 0x01, 0x3a, 0x10, 0xff, 0x63, 0x7f, 0x6d, 0xff, + 0x00, 0x2c, 0x1f, 0xff, 0x04, 0x2d, 0x1f, 0xff, 0x0c, 0x3b, 0x2b, 0xff, 0x05, 0x37, 0x28, 0xff, 0x07, 0x35, 0x25, 0xff, 0x04, 0x36, 0x23, 0xff, 0x02, 0x37, 0x24, 0xff, 0x0d, 0x49, 0x36, 0xff, 0x06, 0x3f, 0x31, 0xff, 0x06, 0x31, 0x27, 0xff, 0x04, 0x36, 0x21, 0xff, 0x0e, 0x62, 0x36, 0xff, 0x12, 0x7e, 0x43, 0xff, 0x0d, 0x85, 0x40, 0xff, 0x08, 0x8c, 0x46, 0xff, 0x1f, 0x9b, 0x60, 0xff, 0x03, 0x52, 0x29, 0xff, 0x05, 0x37, 0x23, 0xff, 0x0a, 0x39, 0x26, 0xff, 0x06, 0x42, 0x22, 0xff, 0x04, 0x59, 0x2a, 0xff, 0x08, 0x79, 0x3b, 0xff, 0x0c, 0x8c, 0x46, 0xff, 0x16, 0xa9, 0x63, 0xff, 0x1a, 0x99, 0x5e, 0xff, 0x02, 0x4e, 0x22, 0xff, 0x00, 0x4e, 0x23, 0xff, 0x01, 0x68, 0x32, 0xff, 0x06, 0x87, 0x48, 0xff, 0x06, 0x9c, 0x5a, 0xff, 0x0b, 0xb3, 0x6c, 0xff, 0x15, 0xac, 0x6b, 0xff, 0x02, 0x57, 0x35, 0xff, 0x06, 0x40, 0x2d, 0xff, 0x0d, 0x5b, 0x3a, 0xff, 0x14, 0x8d, 0x56, 0xff, 0x0f, 0xa1, 0x63, 0xff, 0x06, 0x85, 0x4d, 0xff, 0x0b, 0x79, 0x4f, 0xff, 0x15, 0x69, 0x5f, 0xff, 0x53, 0x9a, 0x99, 0xff, 0x8b, 0xc7, 0xdb, 0xff, 0x59, 0xac, 0xb2, 0xff, 0x18, 0x9a, 0x6f, 0xff, 0x14, 0x9d, 0x73, 0xff, 0x0d, 0x9e, 0x75, 0xff, 0x09, 0xa5, 0x72, 0xff, 0x16, 0xa7, 0x67, 0xff, 0x03, 0x86, 0x52, 0xff, 0x0b, 0xa2, 0x6f, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x0a, 0xa4, 0x6a, 0xff, 0x09, 0xa2, 0x6d, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x05, 0xa5, 0x69, 0xff, 0x06, 0xa5, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x08, 0xa9, 0x6f, 0xff, 0x06, 0xa8, 0x6e, 0xff, 0x04, 0xa7, 0x6d, 0xff, 0x05, 0xa7, 0x6e, 0xff, 0x04, 0xa7, 0x6f, 0xff, 0x04, 0xa7, 0x6d, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x01, 0xa6, 0x69, 0xff, 0x00, 0xa6, 0x67, 0xff, 0x02, 0xa7, 0x67, 0xff, 0x02, 0xa6, 0x68, 0xff, 0x02, 0xa2, 0x6b, 0xff, 0x0b, 0x95, 0x59, 0xff, 0x09, 0x84, 0x3d, 0xff, 0x16, 0x9b, 0x47, 0xff, 0x06, 0x49, 0x0e, 0xff, 0x04, 0x38, 0x0e, 0xff, 0x1e, 0xa5, 0x5d, 0xff, 0x04, 0x76, 0x2a, 0xff, 0x0d, 0x83, 0x39, 0xff, 0x19, 0x7e, 0x39, 0xff, 0x01, 0x62, 0x1e, 0xff, 0x0c, 0x9a, 0x51, 0xff, 0x12, 0xa1, 0x56, 0xff, 0x06, 0x8a, 0x3f, 0xff, 0x04, 0x8c, 0x3e, 0xff, 0x00, 0x8d, 0x3c, 0xff, 0x00, 0x90, 0x3d, 0xff, 0x01, 0x94, 0x3f, 0xff, 0x02, 0x97, 0x40, 0xff, 0x02, 0x99, 0x40, 0xff, 0x03, 0x9a, 0x40, 0xff, 0x06, 0x9f, 0x42, 0xff, 0x05, 0xa1, 0x42, 0xff, 0x03, 0xa9, 0x44, 0xff, 0x02, 0xaa, 0x46, 0xff, 0x01, 0xab, 0x47, 0xff, 0x03, 0xaf, 0x4b, 0xff, 0x04, 0xb4, 0x4e, 0xff, 0x04, 0xb7, 0x50, 0xff, 0x05, 0xb9, 0x52, 0xff, 0x08, 0xbe, 0x56, 0xff, 0x11, 0xbb, 0x55, 0xff, 0x0f, 0xb8, 0x53, 0xff, 0x0b, 0xba, 0x58, 0xff, 0x0a, 0xba, 0x5b, 0xff, 0x0d, 0xb8, 0x5f, 0xff, 0x14, 0xb5, 0x62, 0xff, 0x1a, 0xad, 0x5f, 0xff, 0x1b, 0xa5, 0x5b, 0xff, 0x18, 0xa6, 0x5a, 0xff, 0x18, 0xa8, 0x5d, 0xff, 0x1c, 0xac, 0x5f, 0xff, 0x1f, 0xb2, 0x65, 0xff, 0x1c, 0xb5, 0x68, 0xff, 0x19, 0xb9, 0x6c, 0xff, 0x0e, 0xb7, 0x6a, 0xff, 0x02, 0xae, 0x61, 0xff, 0x00, 0xa4, 0x58, 0xff, 0x00, 0x9c, 0x53, 0xff, 0x03, 0x9f, 0x5a, 0xff, 0x05, 0xa0, 0x5f, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa4, 0x6b, 0xff, 0x0c, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa7, 0x6f, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0d, 0xa6, 0x6b, 0xff, 0x0f, 0xa6, 0x6c, 0xff, 0x0e, 0xa5, 0x6b, 0xff, 0x0d, 0xa7, 0x6a, 0xff, 0x0f, 0xa7, 0x63, 0xff, 0x07, 0x9c, 0x51, 0xff, 0x03, 0x95, 0x3f, 0xff, 0x05, 0x97, 0x3e, 0xff, 0x05, 0x97, 0x3e, 0xff, 0x04, 0x96, 0x3f, 0xff, 0x01, 0x94, 0x42, 0xff, 0x05, 0x98, 0x4a, 0xff, 0x0f, 0xa2, 0x5d, 0xff, 0x13, 0xa6, 0x65, 0xff, 0x0e, 0xa5, 0x67, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x15, 0xa7, 0x6f, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0c, 0xa7, 0x69, 0xff, 0x0f, 0xa7, 0x6a, 0xff, 0x12, 0xa6, 0x6d, 0xff, 0x10, 0xa8, 0x73, 0xff, 0x0b, 0xa7, 0x72, 0xff, 0x07, 0xa9, 0x70, 0xff, 0x06, 0xaa, 0x6e, 0xff, 0x04, 0xaa, 0x6c, 0xff, 0x05, 0xab, 0x6c, 0xff, 0x02, 0xab, 0x6e, 0xff, 0x03, 0xac, 0x6e, 0xff, 0x0e, 0xb1, 0x74, 0xff, 0x15, 0xba, 0x7b, 0xff, 0x1b, 0xaa, 0x70, 0xff, 0x03, 0x7e, 0x48, 0xff, 0x0f, 0xa5, 0x71, 0xff, 0x0d, 0x9f, 0x70, 0xff, 0x06, 0x94, 0x60, 0xff, 0x0b, 0xac, 0x70, 0xff, 0x0a, 0xaa, 0x74, 0xff, 0x13, 0x9f, 0x6f, 0xff, 0x02, 0x72, 0x42, 0xff, 0x13, 0xa3, 0x6f, 0xff, 0x04, 0xaf, 0x74, 0xff, 0x0a, 0xae, 0x74, 0xff, 0x0d, 0x91, 0x60, 0xff, 0x04, 0x86, 0x57, 0xff, 0x07, 0xab, 0x74, 0xff, 0x02, 0xa8, 0x6d, 0xff, 0x0d, 0xa7, 0x6b, 0xff, 0x0a, 0xa5, 0x69, 0xff, 0x01, 0xa7, 0x6b, 0xff, 0x04, 0xa7, 0x6e, 0xff, 0x07, 0xa5, 0x6d, 0xff, 0x02, 0xa6, 0x6b, 0xff, 0x10, 0xab, 0x71, 0xff, 0x08, 0x9e, 0x63, 0xff, 0x07, 0xa4, 0x68, 0xff, 0x03, 0xa8, 0x6b, 0xff, 0x03, 0xa9, 0x6b, 0xff, 0x06, 0xa7, 0x6b, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x66, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0d, 0xa8, 0x6a, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x07, 0xa2, 0x6c, 0xff, 0x0a, 0xa3, 0x6e, 0xff, 0x0c, 0xa4, 0x6f, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x0a, 0xa6, 0x6f, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x08, 0xa6, 0x6f, 0xff, 0x08, 0xa5, 0x71, 0xff, 0x08, 0xa5, 0x72, 0xff, 0x06, 0xa6, 0x72, 0xff, 0x06, 0xa6, 0x70, 0xff, 0x06, 0xa7, 0x70, 0xff, 0x05, 0xa7, 0x70, 0xff, 0x05, 0xa7, 0x70, 0xff, 0x07, 0xa7, 0x71, 0xff, 0x08, 0xa7, 0x71, 0xff, 0x08, 0xa9, 0x70, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0e, 0xa3, 0x6d, 0xff, 0x02, 0xa6, 0x64, 0xff, 0x01, 0xa3, 0x60, 0xff, 0x15, 0xad, 0x6e, 0xff, 0x10, 0xab, 0x5f, 0xff, 0x05, 0x9c, 0x49, 0xff, 0x16, 0x92, 0x5b, 0xff, 0x33, 0x7d, 0x73, 0xff, 0x1f, 0x6e, 0x60, 0xff, 0x08, 0x8a, 0x41, 0xff, 0x10, 0x82, 0x44, 0xff, 0x35, 0x52, 0x6b, 0xff, 0x3f, 0x49, 0x74, 0xff, 0x19, 0x45, 0x35, 0xff, 0x33, 0x53, 0x55, 0xff, 0x7c, 0x61, 0xcc, 0xff, 0x5b, 0x2e, 0xa9, 0xff, 0x49, 0x42, 0x7a, 0xff, 0x19, 0x3a, 0x35, 0xff, 0x04, 0x4a, 0x19, 0xff, 0x08, 0x58, 0x21, 0xff, 0x13, 0x6c, 0x33, 0xff, 0x06, 0x5c, 0x24, 0xff, 0x02, 0x52, 0x1d, 0xff, 0x03, 0x4d, 0x1d, 0xff, 0x02, 0x41, 0x13, 0xff, 0x03, 0x46, 0x14, 0xff, 0x10, 0x71, 0x3c, 0xff, 0x1e, 0x90, 0x54, 0xff, 0x05, 0x8c, 0x47, 0xff, 0x0a, 0x9e, 0x53, 0xff, 0x15, 0xa1, 0x56, 0xff, 0x13, 0x7a, 0x42, 0xff, 0x09, 0x5e, 0x3d, 0xff, 0x11, 0x6f, 0x3e, 0xff, 0x09, 0x82, 0x42, 0xff, 0x13, 0x9b, 0x5c, 0xff, 0x36, 0x8c, 0x7c, 0xff, 0x60, 0x6a, 0xa9, 0xff, 0x68, 0x41, 0xb3, 0xff, 0x47, 0x41, 0x87, 0xff, 0x26, 0x69, 0x64, 0xff, 0x14, 0x70, 0x4a, 0xff, 0x16, 0x79, 0x46, 0xff, 0x36, 0x64, 0x78, 0xff, 0x4d, 0x47, 0x88, 0xff, 0x29, 0x41, 0x53, 0xff, 0x02, 0x3b, 0x1a, 0xff, 0x09, 0x57, 0x26, 0xff, 0x17, 0x7e, 0x46, 0xff, 0x0b, 0x7d, 0x43, 0xff, 0x08, 0x7b, 0x3f, 0xff, 0x0f, 0x78, 0x3e, 0xff, 0x12, 0x77, 0x40, 0xff, 0x0a, 0x76, 0x3f, 0xff, 0x0e, 0x8c, 0x53, 0xff, 0x1a, 0xbe, 0x76, 0xff, 0x18, 0xd7, 0x89, 0xff, 0x1f, 0xd5, 0x8e, 0xff, 0x0c, 0xc7, 0x7f, 0xff, 0x20, 0xd8, 0x8a, 0xff, 0x06, 0xaa, 0x57, 0xff, 0x17, 0xac, 0x5a, 0xff, 0x1f, 0xa7, 0x5c, 0xff, 0x0d, 0xab, 0x4a, 0xff, 0x05, 0xa6, 0x33, 0xff, 0x0b, 0xa1, 0x2f, 0xff, 0x19, 0xaa, 0x46, 0xff, 0x00, 0x77, 0x1f, 0xff, 0x05, 0x7d, 0x24, 0xff, 0x10, 0x8d, 0x2d, 0xff, 0x08, 0x7a, 0x1d, 0xff, 0x04, 0x65, 0x18, 0xff, 0x05, 0x70, 0x1e, 0xff, 0x0c, 0x8d, 0x2d, 0xff, 0x07, 0x9f, 0x2d, 0xff, 0x05, 0xad, 0x2d, 0xff, 0x02, 0x86, 0x21, 0xff, 0x01, 0x61, 0x24, 0xff, 0x03, 0x62, 0x36, 0xff, 0x2b, 0xac, 0x98, 0xff, 0x17, 0xa2, 0x81, 0xff, 0x03, 0x71, 0x30, 0xff, 0x0f, 0x82, 0x50, 0xff, 0x0a, 0x81, 0x49, 0xff, 0x08, 0x86, 0x2d, 0xff, 0x04, 0x71, 0x1a, 0xff, 0x01, 0x49, 0x0e, 0xff, 0x05, 0x40, 0x17, 0xff, 0x07, 0x3a, 0x1a, 0xff, 0x0e, 0x44, 0x1f, 0xff, 0x13, 0x60, 0x28, 0xff, 0x0a, 0x59, 0x23, 0xff, 0x07, 0x4b, 0x1e, 0xff, 0x03, 0x39, 0x13, 0xff, 0x67, 0x7f, 0x6a, 0xff, + 0x05, 0x32, 0x24, 0xff, 0x05, 0x30, 0x23, 0xff, 0x08, 0x36, 0x29, 0xff, 0x06, 0x37, 0x29, 0xff, 0x09, 0x35, 0x27, 0xff, 0x06, 0x38, 0x27, 0xff, 0x04, 0x38, 0x27, 0xff, 0x05, 0x3c, 0x2d, 0xff, 0x06, 0x42, 0x36, 0xff, 0x07, 0x37, 0x2b, 0xff, 0x08, 0x3e, 0x27, 0xff, 0x15, 0x6f, 0x41, 0xff, 0x11, 0x81, 0x44, 0xff, 0x08, 0x86, 0x40, 0xff, 0x0e, 0x92, 0x50, 0xff, 0x12, 0x7b, 0x4d, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x05, 0x37, 0x25, 0xff, 0x07, 0x39, 0x23, 0xff, 0x07, 0x4b, 0x25, 0xff, 0x06, 0x66, 0x31, 0xff, 0x08, 0x81, 0x3f, 0xff, 0x0e, 0x96, 0x4f, 0xff, 0x19, 0xa4, 0x66, 0xff, 0x11, 0x73, 0x45, 0xff, 0x00, 0x4a, 0x22, 0xff, 0x00, 0x5e, 0x2b, 0xff, 0x07, 0x81, 0x41, 0xff, 0x08, 0x93, 0x52, 0xff, 0x0b, 0xa8, 0x65, 0xff, 0x19, 0xb9, 0x72, 0xff, 0x0a, 0x7c, 0x44, 0xff, 0x00, 0x3f, 0x22, 0xff, 0x0d, 0x51, 0x35, 0xff, 0x0d, 0x60, 0x33, 0xff, 0x09, 0x7e, 0x3a, 0xff, 0x1d, 0xb7, 0x67, 0xff, 0x12, 0xa7, 0x5a, 0xff, 0x1d, 0x9d, 0x5d, 0xff, 0x10, 0x7e, 0x4a, 0xff, 0x19, 0x74, 0x4c, 0xff, 0x61, 0xa4, 0xa4, 0xff, 0x4f, 0xa1, 0xa7, 0xff, 0x1b, 0x94, 0x78, 0xff, 0x17, 0x92, 0x78, 0xff, 0x15, 0x98, 0x74, 0xff, 0x1c, 0xae, 0x77, 0xff, 0x0c, 0x8a, 0x51, 0xff, 0x0b, 0x90, 0x5c, 0xff, 0x0e, 0xa2, 0x6f, 0xff, 0x09, 0xa3, 0x6d, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x09, 0xa2, 0x6f, 0xff, 0x07, 0xa4, 0x6c, 0xff, 0x07, 0xa5, 0x6a, 0xff, 0x06, 0xa4, 0x6c, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x07, 0xa5, 0x6c, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x05, 0xa7, 0x6d, 0xff, 0x05, 0xa7, 0x6e, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x05, 0xa7, 0x6d, 0xff, 0x03, 0xa6, 0x69, 0xff, 0x03, 0xa6, 0x67, 0xff, 0x03, 0xa7, 0x66, 0xff, 0x01, 0xa6, 0x66, 0xff, 0x02, 0xa7, 0x6b, 0xff, 0x0c, 0x93, 0x4f, 0xff, 0x11, 0x80, 0x33, 0xff, 0x0e, 0x80, 0x2b, 0xff, 0x2c, 0x84, 0x47, 0xff, 0x0b, 0x4b, 0x1f, 0xff, 0x22, 0xb3, 0x64, 0xff, 0x04, 0x6c, 0x21, 0xff, 0x0d, 0x77, 0x2d, 0xff, 0x0b, 0x7f, 0x34, 0xff, 0x07, 0x80, 0x34, 0xff, 0x05, 0x87, 0x39, 0xff, 0x05, 0x89, 0x3a, 0xff, 0x03, 0x87, 0x38, 0xff, 0x03, 0x89, 0x38, 0xff, 0x03, 0x8c, 0x37, 0xff, 0x02, 0x8e, 0x37, 0xff, 0x04, 0x93, 0x3b, 0xff, 0x06, 0x98, 0x3e, 0xff, 0x03, 0x98, 0x3c, 0xff, 0x05, 0x9d, 0x3e, 0xff, 0x05, 0xa1, 0x41, 0xff, 0x04, 0xa3, 0x41, 0xff, 0x04, 0xaa, 0x44, 0xff, 0x06, 0xac, 0x46, 0xff, 0x05, 0xae, 0x47, 0xff, 0x06, 0xb1, 0x4b, 0xff, 0x05, 0xb4, 0x4e, 0xff, 0x04, 0xb6, 0x4f, 0xff, 0x06, 0xbb, 0x54, 0xff, 0x09, 0xbe, 0x58, 0xff, 0x0d, 0xbc, 0x5b, 0xff, 0x11, 0xba, 0x5e, 0xff, 0x15, 0xb3, 0x5f, 0xff, 0x13, 0xa6, 0x5a, 0xff, 0x0e, 0x8e, 0x4c, 0xff, 0x0a, 0x7b, 0x3e, 0xff, 0x08, 0x69, 0x30, 0xff, 0x07, 0x64, 0x2e, 0xff, 0x04, 0x68, 0x2e, 0xff, 0x04, 0x6b, 0x30, 0xff, 0x08, 0x71, 0x31, 0xff, 0x0b, 0x7c, 0x38, 0xff, 0x11, 0x96, 0x4e, 0xff, 0x12, 0xa8, 0x5e, 0xff, 0x14, 0xbb, 0x6e, 0xff, 0x0e, 0xbf, 0x70, 0xff, 0x0c, 0xb7, 0x6a, 0xff, 0x08, 0xae, 0x64, 0xff, 0x08, 0xa9, 0x62, 0xff, 0x09, 0xa7, 0x64, 0xff, 0x0e, 0xa8, 0x69, 0xff, 0x0e, 0xa6, 0x6a, 0xff, 0x0e, 0xa5, 0x6b, 0xff, 0x0e, 0xa5, 0x6b, 0xff, 0x0c, 0xa6, 0x6b, 0xff, 0x0c, 0xa7, 0x6d, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x0d, 0xa5, 0x6c, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0c, 0xa6, 0x6d, 0xff, 0x0e, 0xa5, 0x65, 0xff, 0x06, 0x9d, 0x55, 0xff, 0x02, 0x96, 0x42, 0xff, 0x04, 0x97, 0x3f, 0xff, 0x02, 0x95, 0x3f, 0xff, 0x01, 0x94, 0x42, 0xff, 0x05, 0x99, 0x4d, 0xff, 0x0d, 0xa1, 0x5c, 0xff, 0x12, 0xa8, 0x6b, 0xff, 0x10, 0xa6, 0x6f, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0c, 0xa5, 0x6f, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x6e, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x10, 0xa5, 0x69, 0xff, 0x0c, 0xa4, 0x65, 0xff, 0x0f, 0xab, 0x6b, 0xff, 0x13, 0xab, 0x68, 0xff, 0x07, 0x9a, 0x57, 0xff, 0x11, 0x9f, 0x64, 0xff, 0x18, 0xa7, 0x70, 0xff, 0x17, 0xa8, 0x71, 0xff, 0x13, 0xaa, 0x71, 0xff, 0x09, 0xaa, 0x6e, 0xff, 0x03, 0xaa, 0x6e, 0xff, 0x01, 0xae, 0x6d, 0xff, 0x09, 0xbb, 0x76, 0xff, 0x21, 0xd4, 0x90, 0xff, 0x19, 0xbf, 0x7c, 0xff, 0x09, 0x80, 0x45, 0xff, 0x08, 0x75, 0x3e, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x09, 0x93, 0x63, 0xff, 0x0a, 0x8d, 0x57, 0xff, 0x0b, 0xae, 0x70, 0xff, 0x0b, 0xab, 0x75, 0xff, 0x0d, 0x8e, 0x61, 0xff, 0x02, 0x5f, 0x38, 0xff, 0x15, 0x9e, 0x6f, 0xff, 0x04, 0xae, 0x75, 0xff, 0x0f, 0xa7, 0x6f, 0xff, 0x05, 0x70, 0x3f, 0xff, 0x0c, 0x89, 0x5a, 0xff, 0x0a, 0xad, 0x75, 0xff, 0x03, 0xaa, 0x6f, 0xff, 0x0e, 0xa7, 0x6b, 0xff, 0x0b, 0xa7, 0x6a, 0xff, 0x01, 0xa9, 0x6c, 0xff, 0x03, 0xa6, 0x6c, 0xff, 0x09, 0xa8, 0x70, 0xff, 0x16, 0xbd, 0x81, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x04, 0x90, 0x54, 0xff, 0x0c, 0xa9, 0x6d, 0xff, 0x05, 0xaa, 0x6c, 0xff, 0x03, 0xaa, 0x6b, 0xff, 0x06, 0xa7, 0x69, 0xff, 0x09, 0xa4, 0x69, 0xff, 0x08, 0xa3, 0x6a, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0a, 0xa4, 0x66, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x07, 0xa2, 0x67, 0xff, 0x07, 0xa2, 0x69, 0xff, 0x09, 0xa2, 0x6a, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x06, 0xa6, 0x6e, 0xff, 0x08, 0xa5, 0x6e, 0xff, 0x09, 0xa5, 0x6e, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x07, 0xa5, 0x70, 0xff, 0x08, 0xa5, 0x72, 0xff, 0x08, 0xa5, 0x72, 0xff, 0x08, 0xa6, 0x71, 0xff, 0x07, 0xa7, 0x70, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x07, 0xa6, 0x70, 0xff, 0x09, 0xa7, 0x71, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x07, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6e, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x02, 0xa5, 0x66, 0xff, 0x08, 0xac, 0x6d, 0xff, 0x17, 0xb1, 0x6c, 0xff, 0x07, 0xa3, 0x4c, 0xff, 0x11, 0xa1, 0x4f, 0xff, 0x26, 0x82, 0x69, 0xff, 0x45, 0x59, 0x8e, 0xff, 0x2b, 0x41, 0x68, 0xff, 0x17, 0x6e, 0x40, 0xff, 0x1a, 0x6a, 0x46, 0xff, 0x31, 0x52, 0x63, 0xff, 0x26, 0x54, 0x52, 0xff, 0x15, 0x63, 0x33, 0xff, 0x1a, 0x5d, 0x3b, 0xff, 0x45, 0x5d, 0x81, 0xff, 0x39, 0x41, 0x74, 0xff, 0x25, 0x41, 0x4c, 0xff, 0x0f, 0x3d, 0x25, 0xff, 0x0a, 0x45, 0x1c, 0xff, 0x06, 0x46, 0x1b, 0xff, 0x1c, 0x73, 0x3e, 0xff, 0x2b, 0x99, 0x5b, 0xff, 0x24, 0xa4, 0x62, 0xff, 0x2a, 0xa5, 0x66, 0xff, 0x1f, 0x8b, 0x4f, 0xff, 0x0d, 0x66, 0x2b, 0xff, 0x0b, 0x56, 0x1d, 0xff, 0x0c, 0x64, 0x28, 0xff, 0x16, 0xa5, 0x5d, 0xff, 0x16, 0xbd, 0x6e, 0xff, 0x20, 0xa6, 0x60, 0xff, 0x21, 0x5e, 0x54, 0xff, 0x32, 0x43, 0x65, 0xff, 0x15, 0x41, 0x3b, 0xff, 0x0d, 0x7a, 0x42, 0xff, 0x25, 0xa4, 0x69, 0xff, 0x2e, 0x64, 0x65, 0xff, 0x79, 0x5e, 0xba, 0xff, 0x6a, 0x34, 0xb2, 0xff, 0x5c, 0x38, 0xa0, 0xff, 0x38, 0x4e, 0x86, 0xff, 0x27, 0x5d, 0x57, 0xff, 0x17, 0x5f, 0x3f, 0xff, 0x2b, 0x58, 0x60, 0xff, 0x42, 0x4b, 0x6d, 0xff, 0x32, 0x59, 0x59, 0xff, 0x0a, 0x48, 0x26, 0xff, 0x03, 0x38, 0x11, 0xff, 0x0d, 0x56, 0x2d, 0xff, 0x13, 0x6d, 0x45, 0xff, 0x14, 0x70, 0x4a, 0xff, 0x1b, 0x6f, 0x4b, 0xff, 0x14, 0x6f, 0x48, 0xff, 0x05, 0x73, 0x46, 0xff, 0x24, 0xc4, 0x8a, 0xff, 0x27, 0xf4, 0x9e, 0xff, 0x0f, 0xfa, 0x9d, 0xff, 0x20, 0xf5, 0x9f, 0xff, 0x15, 0xdb, 0x83, 0xff, 0x21, 0xe4, 0x8a, 0xff, 0x11, 0xc8, 0x6b, 0xff, 0x0a, 0xa9, 0x4e, 0xff, 0x10, 0x94, 0x47, 0xff, 0x08, 0x8b, 0x3a, 0xff, 0x08, 0x96, 0x30, 0xff, 0x08, 0x9c, 0x2b, 0xff, 0x0c, 0x99, 0x33, 0xff, 0x00, 0x76, 0x1e, 0xff, 0x05, 0x7f, 0x25, 0xff, 0x06, 0x87, 0x25, 0xff, 0x12, 0x95, 0x32, 0xff, 0x14, 0x88, 0x2f, 0xff, 0x0f, 0x8d, 0x30, 0xff, 0x06, 0x95, 0x2d, 0xff, 0x16, 0xc3, 0x47, 0xff, 0x07, 0xb5, 0x34, 0xff, 0x10, 0x9d, 0x32, 0xff, 0x0b, 0x7d, 0x25, 0xff, 0x01, 0x5f, 0x1d, 0xff, 0x14, 0x8a, 0x70, 0xff, 0x1d, 0x9f, 0x82, 0xff, 0x07, 0x77, 0x3b, 0xff, 0x01, 0x71, 0x27, 0xff, 0x07, 0x7e, 0x2a, 0xff, 0x19, 0x9d, 0x39, 0xff, 0x13, 0x9a, 0x32, 0xff, 0x0e, 0x72, 0x2b, 0xff, 0x0a, 0x59, 0x26, 0xff, 0x04, 0x45, 0x18, 0xff, 0x05, 0x41, 0x15, 0xff, 0x0a, 0x4e, 0x1b, 0xff, 0x0a, 0x4a, 0x1e, 0xff, 0x0e, 0x45, 0x24, 0xff, 0x09, 0x39, 0x19, 0xff, 0x66, 0x7e, 0x6d, 0xff, + 0x08, 0x36, 0x28, 0xff, 0x08, 0x35, 0x27, 0xff, 0x05, 0x34, 0x26, 0xff, 0x07, 0x37, 0x29, 0xff, 0x0b, 0x37, 0x29, 0xff, 0x08, 0x3b, 0x2d, 0xff, 0x03, 0x36, 0x28, 0xff, 0x05, 0x39, 0x2c, 0xff, 0x03, 0x3e, 0x34, 0xff, 0x0c, 0x3e, 0x32, 0xff, 0x0a, 0x43, 0x2b, 0xff, 0x15, 0x73, 0x42, 0xff, 0x11, 0x83, 0x43, 0xff, 0x07, 0x88, 0x41, 0xff, 0x14, 0x95, 0x57, 0xff, 0x06, 0x60, 0x3a, 0xff, 0x02, 0x37, 0x20, 0xff, 0x04, 0x37, 0x26, 0xff, 0x07, 0x3f, 0x25, 0xff, 0x09, 0x55, 0x29, 0xff, 0x09, 0x71, 0x37, 0xff, 0x0a, 0x87, 0x42, 0xff, 0x10, 0x9d, 0x57, 0xff, 0x12, 0x93, 0x5b, 0xff, 0x05, 0x54, 0x2f, 0xff, 0x00, 0x51, 0x28, 0xff, 0x02, 0x70, 0x36, 0xff, 0x0b, 0x92, 0x4c, 0xff, 0x08, 0x98, 0x55, 0xff, 0x0f, 0xae, 0x6b, 0xff, 0x15, 0xa4, 0x64, 0xff, 0x02, 0x54, 0x26, 0xff, 0x04, 0x40, 0x22, 0xff, 0x11, 0x63, 0x36, 0xff, 0x08, 0x66, 0x2b, 0xff, 0x17, 0x98, 0x49, 0xff, 0x1c, 0xc2, 0x63, 0xff, 0x08, 0xb1, 0x56, 0xff, 0x17, 0xa3, 0x55, 0xff, 0x07, 0x7c, 0x2d, 0xff, 0x0e, 0x6f, 0x2c, 0xff, 0x2d, 0x6e, 0x5f, 0xff, 0x42, 0x8b, 0x95, 0xff, 0x1f, 0x84, 0x7f, 0xff, 0x1c, 0x80, 0x7d, 0xff, 0x22, 0x93, 0x72, 0xff, 0x2a, 0xaa, 0x70, 0xff, 0x07, 0x73, 0x43, 0xff, 0x17, 0x99, 0x65, 0xff, 0x11, 0xa3, 0x6d, 0xff, 0x09, 0xa0, 0x70, 0xff, 0x06, 0xa1, 0x72, 0xff, 0x06, 0xa3, 0x6f, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x06, 0xa4, 0x6b, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa3, 0x6c, 0xff, 0x09, 0xa4, 0x6b, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x05, 0xa8, 0x6e, 0xff, 0x05, 0xa7, 0x6e, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x07, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6f, 0xff, 0x06, 0xa7, 0x6d, 0xff, 0x04, 0xa6, 0x6a, 0xff, 0x04, 0xa6, 0x68, 0xff, 0x05, 0xa7, 0x66, 0xff, 0x02, 0xa5, 0x66, 0xff, 0x03, 0xa7, 0x6a, 0xff, 0x12, 0x99, 0x4f, 0xff, 0x2a, 0x9c, 0x4b, 0xff, 0x25, 0x8f, 0x3b, 0xff, 0x3f, 0xa8, 0x69, 0xff, 0x12, 0x5f, 0x2d, 0xff, 0x23, 0xac, 0x5a, 0xff, 0x0d, 0x76, 0x2b, 0xff, 0x17, 0x7e, 0x33, 0xff, 0x0b, 0x83, 0x35, 0xff, 0x09, 0x89, 0x39, 0xff, 0x09, 0x84, 0x33, 0xff, 0x07, 0x84, 0x34, 0xff, 0x03, 0x88, 0x36, 0xff, 0x06, 0x8a, 0x38, 0xff, 0x08, 0x8d, 0x37, 0xff, 0x07, 0x8f, 0x37, 0xff, 0x09, 0x94, 0x3a, 0xff, 0x09, 0x99, 0x3c, 0xff, 0x06, 0x9c, 0x3e, 0xff, 0x05, 0xa0, 0x40, 0xff, 0x02, 0xa1, 0x3f, 0xff, 0x02, 0xa4, 0x40, 0xff, 0x03, 0xa8, 0x44, 0xff, 0x05, 0xab, 0x46, 0xff, 0x07, 0xae, 0x49, 0xff, 0x05, 0xb0, 0x4b, 0xff, 0x04, 0xb3, 0x4e, 0xff, 0x03, 0xb4, 0x51, 0xff, 0x07, 0xb9, 0x56, 0xff, 0x0e, 0xbd, 0x5c, 0xff, 0x14, 0xb9, 0x61, 0xff, 0x14, 0xa8, 0x5a, 0xff, 0x11, 0x85, 0x41, 0xff, 0x07, 0x66, 0x2c, 0xff, 0x02, 0x53, 0x24, 0xff, 0x06, 0x52, 0x27, 0xff, 0x0d, 0x63, 0x39, 0xff, 0x07, 0x6c, 0x3e, 0xff, 0x04, 0x73, 0x40, 0xff, 0x04, 0x77, 0x42, 0xff, 0x09, 0x76, 0x3d, 0xff, 0x08, 0x70, 0x32, 0xff, 0x05, 0x75, 0x32, 0xff, 0x04, 0x80, 0x39, 0xff, 0x12, 0xa0, 0x57, 0xff, 0x1d, 0xb7, 0x6c, 0xff, 0x18, 0xbf, 0x73, 0xff, 0x13, 0xbd, 0x71, 0xff, 0x0d, 0xb2, 0x6a, 0xff, 0x0a, 0xa9, 0x65, 0xff, 0x0e, 0xa9, 0x68, 0xff, 0x0f, 0xa7, 0x67, 0xff, 0x10, 0xa6, 0x6a, 0xff, 0x0e, 0xa5, 0x68, 0xff, 0x0b, 0xa6, 0x68, 0xff, 0x0c, 0xa7, 0x6a, 0xff, 0x0d, 0xa5, 0x6a, 0xff, 0x0b, 0xa3, 0x6c, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0b, 0xa4, 0x6d, 0xff, 0x0e, 0xa5, 0x67, 0xff, 0x09, 0x9f, 0x5a, 0xff, 0x03, 0x97, 0x47, 0xff, 0x04, 0x97, 0x42, 0xff, 0x01, 0x94, 0x42, 0xff, 0x05, 0x98, 0x4a, 0xff, 0x0d, 0xa2, 0x5b, 0xff, 0x13, 0xa8, 0x68, 0xff, 0x0f, 0xa7, 0x70, 0xff, 0x0c, 0xa3, 0x73, 0xff, 0x0d, 0xa4, 0x73, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x0f, 0xa8, 0x71, 0xff, 0x0d, 0xa8, 0x6d, 0xff, 0x0d, 0xa5, 0x67, 0xff, 0x0b, 0xa2, 0x63, 0xff, 0x09, 0xa2, 0x62, 0xff, 0x0e, 0xab, 0x69, 0xff, 0x1a, 0xb6, 0x6d, 0xff, 0x0b, 0x9e, 0x54, 0xff, 0x04, 0x80, 0x41, 0xff, 0x0e, 0x8c, 0x53, 0xff, 0x14, 0x96, 0x61, 0xff, 0x15, 0x9f, 0x69, 0xff, 0x10, 0xaa, 0x71, 0xff, 0x06, 0xab, 0x72, 0xff, 0x05, 0xb7, 0x75, 0xff, 0x1f, 0xda, 0x90, 0xff, 0x19, 0xd3, 0x88, 0xff, 0x05, 0xa6, 0x61, 0xff, 0x01, 0x64, 0x2a, 0xff, 0x15, 0x85, 0x4e, 0xff, 0x08, 0x9a, 0x63, 0xff, 0x06, 0x86, 0x56, 0xff, 0x0c, 0x87, 0x51, 0xff, 0x0a, 0xaf, 0x70, 0xff, 0x0a, 0xa9, 0x74, 0xff, 0x05, 0x77, 0x4e, 0xff, 0x02, 0x53, 0x31, 0xff, 0x18, 0x9b, 0x6f, 0xff, 0x06, 0xae, 0x76, 0xff, 0x0f, 0x9c, 0x67, 0xff, 0x02, 0x58, 0x29, 0xff, 0x15, 0x93, 0x63, 0xff, 0x0a, 0xae, 0x75, 0xff, 0x06, 0xac, 0x71, 0xff, 0x10, 0xa7, 0x6b, 0xff, 0x0d, 0xa8, 0x6b, 0xff, 0x01, 0xa9, 0x6c, 0xff, 0x03, 0xa7, 0x6d, 0xff, 0x13, 0xb5, 0x7b, 0xff, 0x29, 0xd0, 0x94, 0xff, 0x06, 0x8f, 0x56, 0xff, 0x08, 0x96, 0x5b, 0xff, 0x0e, 0xab, 0x6f, 0xff, 0x06, 0xab, 0x6d, 0xff, 0x03, 0xa9, 0x6b, 0xff, 0x06, 0xa6, 0x69, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0b, 0xa4, 0x6c, 0xff, 0x09, 0xa3, 0x68, 0xff, 0x09, 0xa4, 0x66, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0a, 0xa4, 0x63, 0xff, 0x0b, 0xa4, 0x65, 0xff, 0x0b, 0xa4, 0x66, 0xff, 0x08, 0xa2, 0x66, 0xff, 0x09, 0xa3, 0x67, 0xff, 0x0b, 0xa3, 0x68, 0xff, 0x0c, 0xa3, 0x69, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x09, 0xa5, 0x6d, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x07, 0xa5, 0x70, 0xff, 0x07, 0xa4, 0x71, 0xff, 0x08, 0xa5, 0x73, 0xff, 0x0a, 0xa6, 0x73, 0xff, 0x09, 0xa8, 0x71, 0xff, 0x08, 0xa8, 0x70, 0xff, 0x07, 0xa8, 0x70, 0xff, 0x08, 0xa6, 0x72, 0xff, 0x08, 0xa6, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x08, 0xa7, 0x70, 0xff, 0x09, 0xa7, 0x70, 0xff, 0x07, 0xa6, 0x6f, 0xff, 0x06, 0xa6, 0x6e, 0xff, 0x09, 0xa4, 0x6c, 0xff, 0x0d, 0xa2, 0x6b, 0xff, 0x03, 0xa8, 0x6b, 0xff, 0x10, 0xb9, 0x7a, 0xff, 0x08, 0xa3, 0x59, 0xff, 0x0d, 0xa9, 0x49, 0xff, 0x12, 0x99, 0x49, 0xff, 0x23, 0x6a, 0x64, 0xff, 0x49, 0x41, 0x95, 0xff, 0x2d, 0x32, 0x64, 0xff, 0x16, 0x46, 0x38, 0xff, 0x3c, 0x5b, 0x74, 0xff, 0x4a, 0x4f, 0x89, 0xff, 0x26, 0x4f, 0x54, 0xff, 0x0f, 0x6f, 0x3c, 0xff, 0x0f, 0x7b, 0x3b, 0xff, 0x18, 0x75, 0x47, 0xff, 0x19, 0x68, 0x46, 0xff, 0x10, 0x65, 0x34, 0xff, 0x08, 0x5f, 0x26, 0xff, 0x08, 0x4e, 0x1f, 0xff, 0x0a, 0x44, 0x1d, 0xff, 0x08, 0x4d, 0x1c, 0xff, 0x1a, 0x7c, 0x3d, 0xff, 0x27, 0xad, 0x64, 0xff, 0x20, 0xad, 0x64, 0xff, 0x22, 0xae, 0x67, 0xff, 0x26, 0xa9, 0x63, 0xff, 0x28, 0x86, 0x47, 0xff, 0x0a, 0x68, 0x29, 0xff, 0x20, 0xc0, 0x74, 0xff, 0x0f, 0xbe, 0x6e, 0xff, 0x1e, 0x89, 0x52, 0xff, 0x41, 0x4f, 0x7b, 0xff, 0x6a, 0x45, 0xa9, 0xff, 0x30, 0x36, 0x5b, 0xff, 0x15, 0x72, 0x46, 0xff, 0x1d, 0x85, 0x4f, 0xff, 0x26, 0x48, 0x4d, 0xff, 0x64, 0x46, 0x9c, 0xff, 0x5c, 0x2f, 0x96, 0xff, 0x66, 0x3b, 0xa8, 0xff, 0x4d, 0x3e, 0xa3, 0xff, 0x2d, 0x3d, 0x52, 0xff, 0x0d, 0x36, 0x2d, 0xff, 0x14, 0x3e, 0x3c, 0xff, 0x1d, 0x3d, 0x38, 0xff, 0x22, 0x5d, 0x44, 0xff, 0x16, 0x5d, 0x35, 0xff, 0x0b, 0x37, 0x15, 0xff, 0x03, 0x2c, 0x12, 0xff, 0x08, 0x42, 0x2e, 0xff, 0x1d, 0x5f, 0x56, 0xff, 0x23, 0x5e, 0x5a, 0xff, 0x14, 0x65, 0x53, 0xff, 0x04, 0x79, 0x55, 0xff, 0x29, 0xe8, 0xac, 0xff, 0x1d, 0xf8, 0x9b, 0xff, 0x08, 0xf6, 0x92, 0xff, 0x15, 0xe4, 0x87, 0xff, 0x17, 0xc8, 0x6a, 0xff, 0x13, 0xc3, 0x67, 0xff, 0x1a, 0xcd, 0x6e, 0xff, 0x18, 0xba, 0x5b, 0xff, 0x0b, 0x8a, 0x3c, 0xff, 0x03, 0x6c, 0x25, 0xff, 0x0c, 0x88, 0x30, 0xff, 0x06, 0x96, 0x30, 0xff, 0x06, 0x88, 0x29, 0xff, 0x02, 0x75, 0x1c, 0xff, 0x0b, 0x85, 0x23, 0xff, 0x0c, 0x91, 0x2b, 0xff, 0x12, 0x9b, 0x40, 0xff, 0x07, 0x80, 0x25, 0xff, 0x0a, 0x94, 0x2c, 0xff, 0x0a, 0xb4, 0x3f, 0xff, 0x0f, 0xd3, 0x49, 0xff, 0x02, 0xb1, 0x30, 0xff, 0x0c, 0x9c, 0x34, 0xff, 0x0d, 0x8c, 0x27, 0xff, 0x03, 0x72, 0x1e, 0xff, 0x06, 0x77, 0x42, 0xff, 0x15, 0x91, 0x5b, 0xff, 0x03, 0x75, 0x29, 0xff, 0x0a, 0x93, 0x25, 0xff, 0x0b, 0x96, 0x22, 0xff, 0x13, 0xa3, 0x32, 0xff, 0x0d, 0xa2, 0x2d, 0xff, 0x13, 0x83, 0x30, 0xff, 0x05, 0x5e, 0x20, 0xff, 0x08, 0x55, 0x1e, 0xff, 0x01, 0x40, 0x10, 0xff, 0x01, 0x3a, 0x0a, 0xff, 0x03, 0x34, 0x0f, 0xff, 0x06, 0x31, 0x18, 0xff, 0x08, 0x30, 0x15, 0xff, 0x64, 0x7d, 0x6c, 0xff, + 0x06, 0x36, 0x25, 0xff, 0x05, 0x3b, 0x28, 0xff, 0x03, 0x3b, 0x28, 0xff, 0x05, 0x3c, 0x29, 0xff, 0x08, 0x3f, 0x2c, 0xff, 0x04, 0x3b, 0x2a, 0xff, 0x04, 0x38, 0x28, 0xff, 0x07, 0x39, 0x2e, 0xff, 0x01, 0x35, 0x31, 0xff, 0x0d, 0x3d, 0x36, 0xff, 0x0b, 0x49, 0x32, 0xff, 0x17, 0x79, 0x46, 0xff, 0x11, 0x83, 0x42, 0xff, 0x07, 0x8c, 0x45, 0xff, 0x18, 0x92, 0x56, 0xff, 0x03, 0x40, 0x27, 0xff, 0x06, 0x36, 0x2c, 0xff, 0x07, 0x3a, 0x26, 0xff, 0x0b, 0x4a, 0x27, 0xff, 0x0b, 0x66, 0x31, 0xff, 0x08, 0x7e, 0x39, 0xff, 0x09, 0x8d, 0x48, 0xff, 0x16, 0x96, 0x5e, 0xff, 0x05, 0x61, 0x37, 0xff, 0x01, 0x48, 0x26, 0xff, 0x01, 0x6a, 0x39, 0xff, 0x0a, 0x88, 0x47, 0xff, 0x0f, 0x98, 0x50, 0xff, 0x03, 0x9c, 0x58, 0xff, 0x0b, 0x97, 0x61, 0xff, 0x04, 0x68, 0x3b, 0xff, 0x01, 0x47, 0x1e, 0xff, 0x0d, 0x5f, 0x32, 0xff, 0x0e, 0x6e, 0x32, 0xff, 0x06, 0x6e, 0x2e, 0xff, 0x1a, 0xb1, 0x57, 0xff, 0x0b, 0xb8, 0x4b, 0xff, 0x07, 0xae, 0x53, 0xff, 0x0f, 0x95, 0x49, 0xff, 0x05, 0x71, 0x1e, 0xff, 0x16, 0x6d, 0x2a, 0xff, 0x08, 0x4a, 0x2b, 0xff, 0x21, 0x77, 0x63, 0xff, 0x1a, 0x7a, 0x70, 0xff, 0x1a, 0x7d, 0x73, 0xff, 0x3a, 0xac, 0x7c, 0xff, 0x2f, 0x94, 0x61, 0xff, 0x1f, 0x6a, 0x5e, 0xff, 0x37, 0x91, 0x7b, 0xff, 0x1d, 0x99, 0x71, 0xff, 0x14, 0x9e, 0x75, 0xff, 0x06, 0xa4, 0x6d, 0xff, 0x01, 0xa9, 0x66, 0xff, 0x09, 0xa3, 0x6b, 0xff, 0x10, 0xa1, 0x6c, 0xff, 0x07, 0xa6, 0x66, 0xff, 0x0a, 0xa1, 0x6f, 0xff, 0x09, 0xa1, 0x6e, 0xff, 0x08, 0xa4, 0x6b, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x08, 0xa4, 0x6c, 0xff, 0x09, 0xa6, 0x6a, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x01, 0xaa, 0x6f, 0xff, 0x06, 0xa7, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa6, 0x70, 0xff, 0x03, 0xa6, 0x6e, 0xff, 0x01, 0xa6, 0x6b, 0xff, 0x01, 0xa6, 0x69, 0xff, 0x05, 0xa6, 0x69, 0xff, 0x06, 0xa6, 0x69, 0xff, 0x12, 0xa6, 0x6b, 0xff, 0x0d, 0x86, 0x45, 0xff, 0x21, 0x8d, 0x48, 0xff, 0x3d, 0xac, 0x63, 0xff, 0x21, 0x8b, 0x46, 0xff, 0x0e, 0x74, 0x31, 0xff, 0x10, 0x87, 0x3a, 0xff, 0x0c, 0x7e, 0x30, 0xff, 0x0e, 0x80, 0x31, 0xff, 0x08, 0x82, 0x32, 0xff, 0x06, 0x83, 0x33, 0xff, 0x0a, 0x83, 0x33, 0xff, 0x0a, 0x84, 0x34, 0xff, 0x06, 0x86, 0x33, 0xff, 0x0a, 0x88, 0x36, 0xff, 0x0a, 0x8b, 0x36, 0xff, 0x07, 0x90, 0x35, 0xff, 0x05, 0x98, 0x39, 0xff, 0x05, 0x98, 0x3b, 0xff, 0x07, 0x97, 0x3f, 0xff, 0x0a, 0x9b, 0x42, 0xff, 0x03, 0xa0, 0x41, 0xff, 0x00, 0xa4, 0x41, 0xff, 0x03, 0xa9, 0x48, 0xff, 0x03, 0xa8, 0x48, 0xff, 0x0c, 0xac, 0x49, 0xff, 0x0b, 0xb1, 0x47, 0xff, 0x01, 0xb5, 0x4d, 0xff, 0x06, 0xb3, 0x56, 0xff, 0x19, 0xac, 0x59, 0xff, 0x1b, 0x99, 0x49, 0xff, 0x09, 0x68, 0x2c, 0xff, 0x02, 0x4d, 0x16, 0xff, 0x07, 0x54, 0x23, 0xff, 0x08, 0x6b, 0x3b, 0xff, 0x10, 0x82, 0x50, 0xff, 0x24, 0x76, 0x51, 0xff, 0x21, 0x83, 0x5e, 0xff, 0x0e, 0x95, 0x5b, 0xff, 0x21, 0xce, 0x84, 0xff, 0x24, 0xc8, 0x81, 0xff, 0x1a, 0xa8, 0x66, 0xff, 0x14, 0xa3, 0x62, 0xff, 0x1f, 0xb8, 0x77, 0xff, 0x0e, 0x93, 0x53, 0xff, 0x06, 0x6a, 0x2f, 0xff, 0x0c, 0x78, 0x3c, 0xff, 0x16, 0xa2, 0x5c, 0xff, 0x1d, 0xb5, 0x6e, 0xff, 0x1d, 0xb7, 0x70, 0xff, 0x19, 0xb4, 0x6e, 0xff, 0x16, 0xae, 0x6c, 0xff, 0x10, 0xa5, 0x65, 0xff, 0x0c, 0xa3, 0x65, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0c, 0xa5, 0x67, 0xff, 0x10, 0xa7, 0x68, 0xff, 0x0f, 0xa5, 0x6b, 0xff, 0x0e, 0xa4, 0x6e, 0xff, 0x0c, 0xa3, 0x6f, 0xff, 0x0c, 0xa3, 0x6e, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0e, 0xa5, 0x66, 0xff, 0x08, 0x9f, 0x57, 0xff, 0x04, 0x9b, 0x50, 0xff, 0x08, 0x9e, 0x57, 0xff, 0x0f, 0xa6, 0x62, 0xff, 0x0e, 0xa6, 0x69, 0xff, 0x0f, 0xa6, 0x6c, 0xff, 0x0c, 0xa5, 0x70, 0xff, 0x0b, 0xa4, 0x72, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x0c, 0xa2, 0x6a, 0xff, 0x0d, 0xa5, 0x67, 0xff, 0x0e, 0xa6, 0x65, 0xff, 0x0b, 0xa3, 0x60, 0xff, 0x09, 0xa1, 0x5f, 0xff, 0x0c, 0xa0, 0x5e, 0xff, 0x0c, 0xa8, 0x63, 0xff, 0x0e, 0xb6, 0x64, 0xff, 0x0c, 0xab, 0x57, 0xff, 0x0b, 0x90, 0x4c, 0xff, 0x01, 0x6e, 0x35, 0xff, 0x04, 0x6f, 0x3d, 0xff, 0x05, 0x72, 0x3f, 0xff, 0x05, 0x81, 0x4b, 0xff, 0x06, 0x92, 0x59, 0xff, 0x13, 0xbc, 0x76, 0xff, 0x20, 0xd5, 0x81, 0xff, 0x07, 0xad, 0x5a, 0xff, 0x02, 0x84, 0x44, 0xff, 0x03, 0x5e, 0x2f, 0xff, 0x22, 0x9d, 0x67, 0xff, 0x05, 0x81, 0x45, 0xff, 0x07, 0x79, 0x4e, 0xff, 0x04, 0x72, 0x4b, 0xff, 0x0b, 0xad, 0x71, 0xff, 0x12, 0x99, 0x6c, 0xff, 0x05, 0x58, 0x3d, 0xff, 0x02, 0x45, 0x2a, 0xff, 0x11, 0x93, 0x66, 0xff, 0x0e, 0xad, 0x74, 0xff, 0x0d, 0x83, 0x5a, 0xff, 0x02, 0x50, 0x2b, 0xff, 0x17, 0x9c, 0x69, 0xff, 0x05, 0xaf, 0x75, 0xff, 0x07, 0xab, 0x6f, 0xff, 0x17, 0xa0, 0x66, 0xff, 0x0d, 0x9b, 0x62, 0xff, 0x02, 0xa4, 0x6c, 0xff, 0x02, 0xa6, 0x6f, 0xff, 0x21, 0xd4, 0x95, 0xff, 0x1c, 0xc0, 0x80, 0xff, 0x03, 0x74, 0x44, 0xff, 0x0f, 0x9e, 0x6a, 0xff, 0x0d, 0xac, 0x6e, 0xff, 0x08, 0xad, 0x6d, 0xff, 0x05, 0xa9, 0x6e, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x1d, 0x9c, 0x67, 0xff, 0x12, 0x98, 0x67, 0xff, 0x10, 0xa3, 0x6c, 0xff, 0x0a, 0xa2, 0x66, 0xff, 0x0e, 0xa4, 0x65, 0xff, 0x0c, 0xa4, 0x64, 0xff, 0x09, 0xa4, 0x65, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0d, 0xa2, 0x67, 0xff, 0x0d, 0xa3, 0x68, 0xff, 0x0b, 0xa3, 0x69, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x0a, 0xa4, 0x6b, 0xff, 0x09, 0xa5, 0x6c, 0xff, 0x09, 0xa5, 0x6f, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa5, 0x70, 0xff, 0x07, 0xa7, 0x6d, 0xff, 0x0c, 0xa4, 0x75, 0xff, 0x0e, 0xa5, 0x75, 0xff, 0x04, 0xac, 0x6c, 0xff, 0x02, 0xac, 0x6e, 0xff, 0x07, 0xa9, 0x71, 0xff, 0x07, 0xa7, 0x73, 0xff, 0x04, 0xa9, 0x6d, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x04, 0xa5, 0x71, 0xff, 0x06, 0xa1, 0x6f, 0xff, 0x07, 0xa4, 0x6d, 0xff, 0x02, 0xa6, 0x6c, 0xff, 0x06, 0xa2, 0x66, 0xff, 0x04, 0xa2, 0x69, 0xff, 0x0d, 0xba, 0x71, 0xff, 0x08, 0xb8, 0x61, 0xff, 0x01, 0xb1, 0x4d, 0xff, 0x08, 0xab, 0x43, 0xff, 0x0f, 0x88, 0x3f, 0xff, 0x0c, 0x50, 0x3a, 0xff, 0x21, 0x31, 0x4f, 0xff, 0x11, 0x28, 0x2e, 0xff, 0x4e, 0x51, 0x78, 0xff, 0x7e, 0x5b, 0xca, 0xff, 0x5a, 0x35, 0xa5, 0xff, 0x36, 0x51, 0x63, 0xff, 0x09, 0x73, 0x34, 0xff, 0x08, 0x8c, 0x3c, 0xff, 0x09, 0x8a, 0x37, 0xff, 0x0a, 0x89, 0x37, 0xff, 0x0d, 0x88, 0x35, 0xff, 0x0d, 0x81, 0x32, 0xff, 0x0e, 0x6e, 0x2c, 0xff, 0x11, 0x5a, 0x25, 0xff, 0x08, 0x40, 0x12, 0xff, 0x01, 0x3a, 0x0a, 0xff, 0x15, 0x70, 0x38, 0xff, 0x0e, 0x8e, 0x3c, 0xff, 0x02, 0x8b, 0x3e, 0xff, 0x09, 0x86, 0x3c, 0xff, 0x12, 0x74, 0x38, 0xff, 0x13, 0x7d, 0x3a, 0xff, 0x20, 0xc2, 0x79, 0xff, 0x18, 0xa7, 0x5d, 0xff, 0x35, 0x64, 0x6b, 0xff, 0x67, 0x43, 0xaf, 0xff, 0x81, 0x40, 0xd1, 0xff, 0x52, 0x41, 0x8b, 0xff, 0x08, 0x42, 0x2b, 0xff, 0x0f, 0x39, 0x29, 0xff, 0x13, 0x20, 0x28, 0xff, 0x1e, 0x1e, 0x3f, 0xff, 0x19, 0x13, 0x33, 0xff, 0x46, 0x34, 0x84, 0xff, 0x64, 0x3f, 0x9f, 0xff, 0x31, 0x27, 0x48, 0xff, 0x52, 0x3f, 0x81, 0xff, 0x35, 0x36, 0x62, 0xff, 0x10, 0x35, 0x25, 0xff, 0x0a, 0x39, 0x18, 0xff, 0x0a, 0x3a, 0x1b, 0xff, 0x0b, 0x25, 0x18, 0xff, 0x1c, 0x1f, 0x32, 0xff, 0x24, 0x2c, 0x48, 0xff, 0x67, 0x5f, 0xa5, 0xff, 0x58, 0x53, 0xa6, 0xff, 0x26, 0x4f, 0x69, 0xff, 0x0b, 0x7f, 0x64, 0xff, 0x1d, 0xf9, 0xaf, 0xff, 0x11, 0xf5, 0x96, 0xff, 0x10, 0xe5, 0x85, 0xff, 0x0c, 0xb3, 0x56, 0xff, 0x10, 0x9d, 0x41, 0xff, 0x03, 0x83, 0x2a, 0xff, 0x1d, 0xbd, 0x62, 0xff, 0x14, 0xb7, 0x56, 0xff, 0x19, 0xa8, 0x4b, 0xff, 0x06, 0x75, 0x2c, 0xff, 0x07, 0x6f, 0x29, 0xff, 0x0a, 0x8f, 0x32, 0xff, 0x04, 0x79, 0x26, 0xff, 0x03, 0x77, 0x23, 0xff, 0x0a, 0x8f, 0x28, 0xff, 0x15, 0xa0, 0x38, 0xff, 0x02, 0x73, 0x22, 0xff, 0x02, 0x66, 0x18, 0xff, 0x01, 0x7f, 0x22, 0xff, 0x0c, 0xbf, 0x46, 0xff, 0x08, 0xd8, 0x47, 0xff, 0x02, 0xab, 0x33, 0xff, 0x01, 0x86, 0x22, 0xff, 0x05, 0xa0, 0x28, 0xff, 0x10, 0xb5, 0x35, 0xff, 0x10, 0xa3, 0x38, 0xff, 0x06, 0x8b, 0x2f, 0xff, 0x09, 0x92, 0x29, 0xff, 0x14, 0xbc, 0x36, 0xff, 0x02, 0xa0, 0x1e, 0xff, 0x0c, 0x9f, 0x2b, 0xff, 0x04, 0x8f, 0x20, 0xff, 0x06, 0x79, 0x1f, 0xff, 0x09, 0x74, 0x24, 0xff, 0x08, 0x5e, 0x1c, 0xff, 0x05, 0x4b, 0x16, 0xff, 0x04, 0x49, 0x12, 0xff, 0x00, 0x34, 0x07, 0xff, 0x01, 0x21, 0x0a, 0xff, 0x04, 0x1e, 0x0e, 0xff, 0x62, 0x76, 0x68, 0xff, + 0x07, 0x38, 0x27, 0xff, 0x05, 0x40, 0x2a, 0xff, 0x07, 0x45, 0x2d, 0xff, 0x07, 0x47, 0x2d, 0xff, 0x06, 0x47, 0x2e, 0xff, 0x04, 0x46, 0x2d, 0xff, 0x03, 0x3e, 0x29, 0xff, 0x04, 0x3b, 0x2d, 0xff, 0x01, 0x35, 0x2f, 0xff, 0x08, 0x38, 0x31, 0xff, 0x08, 0x4a, 0x32, 0xff, 0x15, 0x7a, 0x48, 0xff, 0x10, 0x83, 0x44, 0xff, 0x08, 0x8d, 0x48, 0xff, 0x13, 0x87, 0x4f, 0xff, 0x01, 0x38, 0x24, 0xff, 0x04, 0x35, 0x2c, 0xff, 0x08, 0x40, 0x27, 0xff, 0x0a, 0x51, 0x29, 0xff, 0x0f, 0x6f, 0x3a, 0xff, 0x0b, 0x7f, 0x3e, 0xff, 0x12, 0x90, 0x52, 0xff, 0x11, 0x82, 0x52, 0xff, 0x01, 0x51, 0x29, 0xff, 0x01, 0x58, 0x2d, 0xff, 0x02, 0x7d, 0x43, 0xff, 0x0c, 0x91, 0x50, 0xff, 0x10, 0x96, 0x54, 0xff, 0x0d, 0x96, 0x59, 0xff, 0x05, 0x70, 0x42, 0xff, 0x01, 0x50, 0x28, 0xff, 0x08, 0x61, 0x31, 0xff, 0x0f, 0x75, 0x3b, 0xff, 0x0b, 0x73, 0x34, 0xff, 0x07, 0x70, 0x33, 0xff, 0x14, 0xab, 0x4f, 0xff, 0x0c, 0xb6, 0x46, 0xff, 0x12, 0xa9, 0x52, 0xff, 0x10, 0x8b, 0x44, 0xff, 0x08, 0x72, 0x2c, 0xff, 0x18, 0x65, 0x2e, 0xff, 0x04, 0x41, 0x21, 0xff, 0x23, 0x81, 0x5a, 0xff, 0x1d, 0x91, 0x6a, 0xff, 0x1a, 0x91, 0x6b, 0xff, 0x33, 0xa4, 0x6e, 0xff, 0x1b, 0x6d, 0x49, 0xff, 0x29, 0x69, 0x6e, 0xff, 0x2b, 0x75, 0x78, 0xff, 0x23, 0x82, 0x74, 0xff, 0x1b, 0x8b, 0x77, 0xff, 0x14, 0x9d, 0x77, 0xff, 0x10, 0xa3, 0x71, 0xff, 0x0e, 0xa0, 0x71, 0xff, 0x10, 0xa2, 0x6c, 0xff, 0x08, 0xa5, 0x68, 0xff, 0x08, 0xa4, 0x6e, 0xff, 0x05, 0xa5, 0x6b, 0xff, 0x04, 0xa5, 0x6a, 0xff, 0x06, 0xa3, 0x70, 0xff, 0x08, 0xa3, 0x6c, 0xff, 0x08, 0xa6, 0x6a, 0xff, 0x06, 0xa7, 0x6e, 0xff, 0x02, 0xa8, 0x6e, 0xff, 0x06, 0xa7, 0x6e, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x03, 0xa7, 0x6e, 0xff, 0x04, 0xa7, 0x6c, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0e, 0xa1, 0x69, 0xff, 0x0e, 0x9a, 0x61, 0xff, 0x17, 0x92, 0x5b, 0xff, 0x0d, 0x74, 0x3c, 0xff, 0x08, 0x5f, 0x23, 0xff, 0x1f, 0x87, 0x45, 0xff, 0x08, 0x72, 0x2c, 0xff, 0x06, 0x77, 0x2e, 0xff, 0x06, 0x78, 0x2e, 0xff, 0x06, 0x7e, 0x2f, 0xff, 0x09, 0x82, 0x32, 0xff, 0x08, 0x83, 0x33, 0xff, 0x07, 0x82, 0x32, 0xff, 0x08, 0x83, 0x33, 0xff, 0x09, 0x84, 0x34, 0xff, 0x08, 0x85, 0x34, 0xff, 0x0a, 0x87, 0x36, 0xff, 0x08, 0x8c, 0x39, 0xff, 0x05, 0x90, 0x37, 0xff, 0x05, 0x98, 0x3a, 0xff, 0x03, 0x99, 0x3a, 0xff, 0x06, 0x9a, 0x3f, 0xff, 0x07, 0x9b, 0x41, 0xff, 0x05, 0x9f, 0x41, 0xff, 0x05, 0xa3, 0x41, 0xff, 0x03, 0xa9, 0x45, 0xff, 0x02, 0xaa, 0x49, 0xff, 0x08, 0xaa, 0x48, 0xff, 0x0d, 0xaf, 0x48, 0xff, 0x08, 0xab, 0x4c, 0xff, 0x0b, 0x9b, 0x4e, 0xff, 0x0c, 0x74, 0x35, 0xff, 0x07, 0x5b, 0x1d, 0xff, 0x03, 0x50, 0x1e, 0xff, 0x0e, 0x57, 0x29, 0xff, 0x1c, 0x74, 0x47, 0xff, 0x1e, 0x96, 0x65, 0xff, 0x16, 0x99, 0x63, 0xff, 0x21, 0x76, 0x4f, 0xff, 0x0f, 0x7a, 0x4f, 0xff, 0x16, 0xb1, 0x6b, 0xff, 0x11, 0xd1, 0x7b, 0xff, 0x1e, 0xd4, 0x83, 0xff, 0x23, 0xbd, 0x75, 0xff, 0x0d, 0xa3, 0x5f, 0xff, 0x1a, 0xb9, 0x79, 0xff, 0x16, 0xa8, 0x6b, 0xff, 0x1e, 0x90, 0x58, 0xff, 0x0b, 0x73, 0x3b, 0xff, 0x06, 0x72, 0x32, 0xff, 0x0c, 0x82, 0x40, 0xff, 0x13, 0x90, 0x4e, 0xff, 0x10, 0x92, 0x4f, 0xff, 0x0b, 0x93, 0x52, 0xff, 0x06, 0x94, 0x54, 0xff, 0x0a, 0x9d, 0x5f, 0xff, 0x0e, 0xa4, 0x68, 0xff, 0x0e, 0xa6, 0x66, 0xff, 0x0f, 0xa6, 0x67, 0xff, 0x0d, 0xa4, 0x69, 0xff, 0x0e, 0xa5, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6e, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0d, 0xa6, 0x69, 0xff, 0x0e, 0xa6, 0x64, 0xff, 0x0d, 0xa4, 0x60, 0xff, 0x0f, 0xa6, 0x65, 0xff, 0x10, 0xa8, 0x6b, 0xff, 0x0e, 0xa6, 0x6d, 0xff, 0x0e, 0xa6, 0x6e, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6e, 0xff, 0x0c, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x68, 0xff, 0x0b, 0xa4, 0x61, 0xff, 0x0c, 0xa3, 0x5c, 0xff, 0x09, 0x9f, 0x58, 0xff, 0x09, 0xa0, 0x5b, 0xff, 0x0e, 0xa0, 0x5a, 0xff, 0x10, 0xab, 0x62, 0xff, 0x0b, 0xba, 0x63, 0xff, 0x07, 0xae, 0x55, 0xff, 0x0f, 0xa0, 0x57, 0xff, 0x04, 0x79, 0x3e, 0xff, 0x09, 0x6e, 0x3a, 0xff, 0x0d, 0x70, 0x3d, 0xff, 0x08, 0x77, 0x42, 0xff, 0x04, 0x80, 0x48, 0xff, 0x08, 0xa5, 0x5e, 0xff, 0x10, 0xbf, 0x67, 0xff, 0x0a, 0x9f, 0x4c, 0xff, 0x01, 0x6b, 0x2f, 0xff, 0x07, 0x6a, 0x40, 0xff, 0x1e, 0x99, 0x66, 0xff, 0x06, 0x76, 0x3b, 0xff, 0x0b, 0x75, 0x4d, 0xff, 0x01, 0x67, 0x45, 0xff, 0x10, 0xaa, 0x72, 0xff, 0x0e, 0x84, 0x5b, 0xff, 0x05, 0x4b, 0x35, 0xff, 0x02, 0x40, 0x28, 0xff, 0x0e, 0x8a, 0x5e, 0xff, 0x11, 0xaa, 0x72, 0xff, 0x0a, 0x70, 0x4e, 0xff, 0x03, 0x51, 0x2f, 0xff, 0x1a, 0xa3, 0x6f, 0xff, 0x06, 0xab, 0x71, 0xff, 0x09, 0xa7, 0x6c, 0xff, 0x17, 0x99, 0x62, 0xff, 0x09, 0x8f, 0x5b, 0xff, 0x07, 0xa3, 0x6e, 0xff, 0x07, 0xa9, 0x71, 0xff, 0x21, 0xd6, 0x93, 0xff, 0x0b, 0xa3, 0x62, 0xff, 0x03, 0x71, 0x44, 0xff, 0x0c, 0xa2, 0x6f, 0xff, 0x07, 0xad, 0x6c, 0xff, 0x06, 0xae, 0x6c, 0xff, 0x07, 0xaa, 0x70, 0xff, 0x0a, 0xa1, 0x67, 0xff, 0x0f, 0x87, 0x53, 0xff, 0x08, 0x7f, 0x51, 0xff, 0x0c, 0x90, 0x5d, 0xff, 0x0f, 0x9d, 0x65, 0xff, 0x0d, 0xa4, 0x65, 0xff, 0x0a, 0xa4, 0x66, 0xff, 0x08, 0xa4, 0x65, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x0d, 0xa2, 0x68, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x0b, 0xa3, 0x6a, 0xff, 0x09, 0xa4, 0x6a, 0xff, 0x08, 0xa5, 0x6b, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa6, 0x6e, 0xff, 0x0b, 0xa5, 0x6f, 0xff, 0x0b, 0xa6, 0x6f, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x08, 0xa5, 0x70, 0xff, 0x04, 0xa9, 0x6b, 0xff, 0x0b, 0xa4, 0x74, 0xff, 0x0e, 0xa5, 0x74, 0xff, 0x04, 0xac, 0x6b, 0xff, 0x03, 0xab, 0x6e, 0xff, 0x07, 0xa7, 0x72, 0xff, 0x08, 0xa6, 0x75, 0xff, 0x07, 0xa9, 0x6b, 0xff, 0x12, 0xa7, 0x71, 0xff, 0x0c, 0xa3, 0x75, 0xff, 0x04, 0xa4, 0x6d, 0xff, 0x05, 0xa5, 0x6c, 0xff, 0x03, 0xa6, 0x6d, 0xff, 0x0a, 0xa4, 0x68, 0xff, 0x0a, 0xac, 0x6e, 0xff, 0x11, 0xbd, 0x6c, 0xff, 0x04, 0xb3, 0x50, 0xff, 0x04, 0xb2, 0x46, 0xff, 0x09, 0xa7, 0x44, 0xff, 0x0b, 0x83, 0x3d, 0xff, 0x06, 0x5e, 0x33, 0xff, 0x05, 0x3c, 0x28, 0xff, 0x0b, 0x2f, 0x20, 0xff, 0x6f, 0x67, 0x99, 0xff, 0x8e, 0x5e, 0xd7, 0xff, 0x6a, 0x3e, 0xaf, 0xff, 0x30, 0x46, 0x57, 0xff, 0x0b, 0x70, 0x2e, 0xff, 0x09, 0x87, 0x38, 0xff, 0x0b, 0x8a, 0x36, 0xff, 0x07, 0x88, 0x32, 0xff, 0x05, 0x84, 0x2e, 0xff, 0x08, 0x7f, 0x2d, 0xff, 0x12, 0x74, 0x2f, 0xff, 0x1a, 0x66, 0x2f, 0xff, 0x0a, 0x42, 0x18, 0xff, 0x01, 0x2f, 0x0a, 0xff, 0x09, 0x42, 0x1b, 0xff, 0x11, 0x71, 0x2d, 0xff, 0x03, 0x77, 0x31, 0xff, 0x06, 0x77, 0x2e, 0xff, 0x08, 0x69, 0x2b, 0xff, 0x0d, 0x79, 0x36, 0xff, 0x24, 0xbc, 0x75, 0xff, 0x10, 0x81, 0x46, 0xff, 0x57, 0x5e, 0x92, 0xff, 0x73, 0x38, 0xc3, 0xff, 0x7e, 0x39, 0xd5, 0xff, 0x5a, 0x44, 0x93, 0xff, 0x0f, 0x25, 0x2a, 0xff, 0x3d, 0x3b, 0x59, 0xff, 0x47, 0x3f, 0x63, 0xff, 0x1a, 0x1d, 0x34, 0xff, 0x04, 0x13, 0x14, 0xff, 0x1e, 0x21, 0x4a, 0xff, 0x42, 0x2d, 0x68, 0xff, 0x23, 0x20, 0x3b, 0xff, 0x82, 0x5b, 0xc0, 0xff, 0x57, 0x49, 0x8f, 0xff, 0x12, 0x38, 0x29, 0xff, 0x04, 0x28, 0x09, 0xff, 0x04, 0x22, 0x0f, 0xff, 0x1c, 0x27, 0x39, 0xff, 0x6c, 0x51, 0x94, 0xff, 0x4b, 0x3a, 0x74, 0xff, 0x8f, 0x68, 0xca, 0xff, 0x75, 0x52, 0xc2, 0xff, 0x2e, 0x3a, 0x74, 0xff, 0x16, 0x86, 0x7a, 0xff, 0x25, 0xfb, 0xae, 0xff, 0x08, 0xe0, 0x7f, 0xff, 0x10, 0xd0, 0x6f, 0xff, 0x08, 0x9e, 0x40, 0xff, 0x0f, 0x8b, 0x36, 0xff, 0x01, 0x6e, 0x20, 0xff, 0x17, 0xa0, 0x4f, 0xff, 0x13, 0xad, 0x53, 0xff, 0x0c, 0x9f, 0x3d, 0xff, 0x06, 0x7d, 0x2d, 0xff, 0x03, 0x66, 0x23, 0xff, 0x0b, 0x8a, 0x30, 0xff, 0x02, 0x7b, 0x25, 0xff, 0x02, 0x7a, 0x24, 0xff, 0x0e, 0x93, 0x31, 0xff, 0x08, 0x85, 0x2a, 0xff, 0x01, 0x64, 0x1a, 0xff, 0x04, 0x65, 0x1c, 0xff, 0x03, 0x78, 0x24, 0xff, 0x10, 0xbc, 0x49, 0xff, 0x0c, 0xd6, 0x45, 0xff, 0x01, 0xa3, 0x29, 0xff, 0x06, 0x9d, 0x31, 0xff, 0x14, 0xd0, 0x4a, 0xff, 0x12, 0xcf, 0x3c, 0xff, 0x0f, 0xb5, 0x34, 0xff, 0x06, 0x90, 0x26, 0xff, 0x0c, 0xa1, 0x2b, 0xff, 0x08, 0xb3, 0x2a, 0xff, 0x00, 0x99, 0x1d, 0xff, 0x06, 0x8f, 0x26, 0xff, 0x09, 0x80, 0x25, 0xff, 0x02, 0x71, 0x16, 0xff, 0x0a, 0x81, 0x25, 0xff, 0x04, 0x5b, 0x18, 0xff, 0x09, 0x53, 0x1c, 0xff, 0x0c, 0x5e, 0x21, 0xff, 0x02, 0x47, 0x11, 0xff, 0x02, 0x26, 0x0d, 0xff, 0x05, 0x1a, 0x0d, 0xff, 0x62, 0x73, 0x67, 0xff, + 0x09, 0x3c, 0x28, 0xff, 0x05, 0x45, 0x2a, 0xff, 0x06, 0x4d, 0x2f, 0xff, 0x0f, 0x5b, 0x39, 0xff, 0x05, 0x54, 0x32, 0xff, 0x10, 0x64, 0x40, 0xff, 0x0c, 0x59, 0x39, 0xff, 0x00, 0x3d, 0x25, 0xff, 0x03, 0x3b, 0x2f, 0xff, 0x02, 0x34, 0x2a, 0xff, 0x01, 0x43, 0x2c, 0xff, 0x0b, 0x74, 0x44, 0xff, 0x0b, 0x81, 0x45, 0xff, 0x0a, 0x8c, 0x4a, 0xff, 0x10, 0x7c, 0x46, 0xff, 0x01, 0x39, 0x23, 0xff, 0x02, 0x39, 0x29, 0xff, 0x08, 0x4a, 0x27, 0xff, 0x0d, 0x5e, 0x30, 0xff, 0x11, 0x70, 0x43, 0xff, 0x12, 0x7b, 0x4a, 0xff, 0x0f, 0x7b, 0x48, 0xff, 0x03, 0x62, 0x35, 0xff, 0x00, 0x58, 0x2a, 0xff, 0x01, 0x6e, 0x35, 0xff, 0x03, 0x8a, 0x46, 0xff, 0x08, 0x8f, 0x50, 0xff, 0x15, 0x93, 0x5e, 0xff, 0x11, 0x7b, 0x4c, 0xff, 0x02, 0x4f, 0x1f, 0xff, 0x0a, 0x69, 0x33, 0xff, 0x11, 0x86, 0x46, 0xff, 0x0a, 0x7f, 0x38, 0xff, 0x0d, 0x7e, 0x3c, 0xff, 0x07, 0x6c, 0x32, 0xff, 0x17, 0xa0, 0x46, 0xff, 0x11, 0xb4, 0x47, 0xff, 0x0f, 0x96, 0x40, 0xff, 0x0c, 0x7e, 0x37, 0xff, 0x09, 0x72, 0x37, 0xff, 0x15, 0x5c, 0x31, 0xff, 0x03, 0x3c, 0x23, 0xff, 0x25, 0x81, 0x56, 0xff, 0x39, 0xc4, 0x7e, 0xff, 0x2f, 0xbd, 0x76, 0xff, 0x0f, 0x73, 0x40, 0xff, 0x0c, 0x4c, 0x3c, 0xff, 0x29, 0x6f, 0x7b, 0xff, 0x20, 0x68, 0x7c, 0xff, 0x28, 0x6c, 0x7a, 0xff, 0x1e, 0x71, 0x7c, 0xff, 0x29, 0x88, 0x8d, 0xff, 0x35, 0x96, 0x90, 0xff, 0x1c, 0x97, 0x7d, 0xff, 0x10, 0xa1, 0x71, 0xff, 0x0e, 0xa0, 0x72, 0xff, 0x05, 0xa5, 0x69, 0xff, 0x01, 0xaa, 0x65, 0xff, 0x01, 0xa7, 0x6a, 0xff, 0x07, 0xa3, 0x71, 0xff, 0x09, 0xa3, 0x6e, 0xff, 0x05, 0xa6, 0x6c, 0xff, 0x03, 0xa7, 0x6f, 0xff, 0x08, 0xa7, 0x6e, 0xff, 0x06, 0xa9, 0x6e, 0xff, 0x03, 0xa9, 0x6e, 0xff, 0x03, 0xa8, 0x6d, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x14, 0xa5, 0x6e, 0xff, 0x16, 0x96, 0x5f, 0xff, 0x0d, 0x82, 0x4e, 0xff, 0x06, 0x69, 0x3a, 0xff, 0x04, 0x5a, 0x2c, 0xff, 0x04, 0x51, 0x21, 0xff, 0x02, 0x4e, 0x18, 0xff, 0x05, 0x62, 0x25, 0xff, 0x03, 0x6d, 0x2b, 0xff, 0x02, 0x72, 0x2d, 0xff, 0x06, 0x78, 0x30, 0xff, 0x06, 0x7f, 0x32, 0xff, 0x09, 0x84, 0x34, 0xff, 0x08, 0x83, 0x33, 0xff, 0x07, 0x82, 0x32, 0xff, 0x08, 0x83, 0x33, 0xff, 0x08, 0x83, 0x33, 0xff, 0x07, 0x85, 0x33, 0xff, 0x08, 0x87, 0x35, 0xff, 0x02, 0x8b, 0x3a, 0xff, 0x05, 0x8f, 0x3b, 0xff, 0x07, 0x95, 0x3b, 0xff, 0x04, 0x99, 0x3a, 0xff, 0x01, 0x9e, 0x3b, 0xff, 0x01, 0xa0, 0x3d, 0xff, 0x07, 0xa0, 0x3e, 0xff, 0x0d, 0xa1, 0x40, 0xff, 0x05, 0xab, 0x41, 0xff, 0x01, 0xa9, 0x46, 0xff, 0x0b, 0xa9, 0x4d, 0xff, 0x14, 0xa2, 0x4b, 0xff, 0x08, 0x7a, 0x31, 0xff, 0x02, 0x4f, 0x1b, 0xff, 0x05, 0x47, 0x1e, 0xff, 0x0a, 0x5f, 0x2f, 0xff, 0x0b, 0x73, 0x40, 0xff, 0x1b, 0x76, 0x44, 0xff, 0x10, 0x6e, 0x3d, 0xff, 0x16, 0x8d, 0x5a, 0xff, 0x20, 0x93, 0x62, 0xff, 0x17, 0x6a, 0x40, 0xff, 0x0e, 0x84, 0x4d, 0xff, 0x19, 0xbf, 0x71, 0xff, 0x09, 0xc0, 0x6c, 0xff, 0x17, 0xcc, 0x7b, 0xff, 0x29, 0xc5, 0x7d, 0xff, 0x10, 0x9b, 0x5a, 0xff, 0x14, 0xa6, 0x67, 0xff, 0x11, 0xa3, 0x66, 0xff, 0x20, 0xaa, 0x6e, 0xff, 0x19, 0xa2, 0x65, 0xff, 0x12, 0x88, 0x4b, 0xff, 0x0a, 0x75, 0x38, 0xff, 0x03, 0x6f, 0x31, 0xff, 0x03, 0x75, 0x35, 0xff, 0x0c, 0x8a, 0x4b, 0xff, 0x0f, 0x97, 0x59, 0xff, 0x15, 0xa4, 0x66, 0xff, 0x13, 0xa3, 0x67, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x0d, 0xa5, 0x65, 0xff, 0x0c, 0xa5, 0x68, 0xff, 0x0b, 0xa3, 0x6b, 0xff, 0x0a, 0xa4, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0b, 0xa4, 0x6b, 0xff, 0x0b, 0xa6, 0x69, 0xff, 0x0e, 0xa7, 0x67, 0xff, 0x10, 0xa7, 0x68, 0xff, 0x11, 0xa7, 0x6a, 0xff, 0x0f, 0xa7, 0x6b, 0xff, 0x0f, 0xa5, 0x6d, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0c, 0xa5, 0x6b, 0xff, 0x0d, 0xa3, 0x67, 0xff, 0x0e, 0xa3, 0x63, 0xff, 0x06, 0xa1, 0x59, 0xff, 0x09, 0x9e, 0x53, 0xff, 0x0b, 0x9f, 0x53, 0xff, 0x08, 0xa0, 0x55, 0xff, 0x0a, 0x9e, 0x54, 0xff, 0x13, 0xb1, 0x63, 0xff, 0x0b, 0xbf, 0x65, 0xff, 0x07, 0xb8, 0x5d, 0xff, 0x11, 0xa9, 0x5d, 0xff, 0x0b, 0x8a, 0x49, 0xff, 0x04, 0x6c, 0x34, 0xff, 0x0f, 0x72, 0x3f, 0xff, 0x0f, 0x79, 0x44, 0xff, 0x06, 0x7a, 0x43, 0xff, 0x07, 0x9e, 0x56, 0xff, 0x0b, 0xb4, 0x5d, 0xff, 0x09, 0x8c, 0x41, 0xff, 0x00, 0x55, 0x1e, 0xff, 0x12, 0x7a, 0x4f, 0xff, 0x16, 0x83, 0x53, 0xff, 0x08, 0x69, 0x37, 0xff, 0x0d, 0x6d, 0x4a, 0xff, 0x02, 0x5e, 0x3d, 0xff, 0x18, 0xa6, 0x71, 0xff, 0x07, 0x6e, 0x47, 0xff, 0x06, 0x49, 0x32, 0xff, 0x02, 0x39, 0x22, 0xff, 0x0f, 0x7f, 0x56, 0xff, 0x17, 0xa8, 0x72, 0xff, 0x06, 0x5e, 0x3e, 0xff, 0x04, 0x54, 0x35, 0xff, 0x1a, 0xa3, 0x72, 0xff, 0x0c, 0xa1, 0x6a, 0xff, 0x14, 0xa5, 0x6c, 0xff, 0x0a, 0x87, 0x54, 0xff, 0x0d, 0x8c, 0x5e, 0xff, 0x08, 0x98, 0x66, 0xff, 0x13, 0xaf, 0x75, 0xff, 0x21, 0xc7, 0x84, 0xff, 0x04, 0x81, 0x45, 0xff, 0x07, 0x7b, 0x4d, 0xff, 0x08, 0xa9, 0x72, 0xff, 0x02, 0xae, 0x6c, 0xff, 0x05, 0xae, 0x6b, 0xff, 0x05, 0xa1, 0x66, 0xff, 0x02, 0x8e, 0x53, 0xff, 0x0c, 0x8d, 0x54, 0xff, 0x04, 0x70, 0x42, 0xff, 0x03, 0x70, 0x41, 0xff, 0x14, 0x90, 0x5d, 0xff, 0x0e, 0xa6, 0x6b, 0xff, 0x06, 0xa5, 0x67, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x67, 0xff, 0x07, 0xa5, 0x67, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x09, 0xa4, 0x68, 0xff, 0x0a, 0xa4, 0x69, 0xff, 0x09, 0xa5, 0x6a, 0xff, 0x08, 0xa5, 0x6c, 0xff, 0x09, 0xa6, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0c, 0xa6, 0x6f, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x07, 0xa5, 0x70, 0xff, 0x03, 0xa9, 0x69, 0xff, 0x05, 0xa7, 0x6f, 0xff, 0x09, 0xa6, 0x70, 0xff, 0x07, 0xa8, 0x6e, 0xff, 0x08, 0xa6, 0x73, 0xff, 0x08, 0xa5, 0x72, 0xff, 0x05, 0xa2, 0x71, 0xff, 0x17, 0xa6, 0x70, 0xff, 0x26, 0x93, 0x75, 0xff, 0x22, 0x92, 0x7c, 0xff, 0x11, 0xa4, 0x72, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x07, 0xa5, 0x6e, 0xff, 0x0a, 0xa7, 0x67, 0xff, 0x15, 0xbb, 0x73, 0xff, 0x0a, 0xaf, 0x57, 0xff, 0x0a, 0xb0, 0x4b, 0xff, 0x0c, 0xad, 0x47, 0xff, 0x08, 0x9f, 0x46, 0xff, 0x08, 0x8c, 0x44, 0xff, 0x0a, 0x81, 0x41, 0xff, 0x09, 0x68, 0x33, 0xff, 0x0e, 0x40, 0x27, 0xff, 0x45, 0x4c, 0x66, 0xff, 0x74, 0x5a, 0xaa, 0xff, 0x5c, 0x47, 0x94, 0xff, 0x1b, 0x38, 0x3d, 0xff, 0x09, 0x61, 0x26, 0xff, 0x0a, 0x79, 0x30, 0xff, 0x0f, 0x86, 0x30, 0xff, 0x0e, 0x87, 0x30, 0xff, 0x07, 0x82, 0x2e, 0xff, 0x09, 0x79, 0x2c, 0xff, 0x12, 0x66, 0x28, 0xff, 0x14, 0x58, 0x27, 0xff, 0x03, 0x3b, 0x17, 0xff, 0x01, 0x2d, 0x11, 0xff, 0x07, 0x2a, 0x10, 0xff, 0x06, 0x41, 0x14, 0xff, 0x0b, 0x74, 0x34, 0xff, 0x1d, 0x98, 0x49, 0xff, 0x15, 0x81, 0x38, 0xff, 0x0b, 0x78, 0x32, 0xff, 0x22, 0xaf, 0x63, 0xff, 0x0a, 0x63, 0x3b, 0xff, 0x6b, 0x53, 0xa6, 0xff, 0x7a, 0x33, 0xd0, 0xff, 0x83, 0x3c, 0xd8, 0xff, 0x52, 0x3a, 0x7f, 0xff, 0x42, 0x33, 0x5b, 0xff, 0x90, 0x67, 0xbf, 0xff, 0x73, 0x4b, 0xa8, 0xff, 0x46, 0x33, 0x6f, 0xff, 0x05, 0x16, 0x18, 0xff, 0x06, 0x17, 0x17, 0xff, 0x0a, 0x14, 0x20, 0xff, 0x0a, 0x1f, 0x26, 0xff, 0x69, 0x52, 0xa5, 0xff, 0x4b, 0x50, 0x83, 0xff, 0x0b, 0x3c, 0x22, 0xff, 0x04, 0x2b, 0x0b, 0xff, 0x0a, 0x24, 0x1a, 0xff, 0x53, 0x4f, 0x82, 0xff, 0x9c, 0x6b, 0xda, 0xff, 0x4e, 0x31, 0x7e, 0xff, 0x6c, 0x42, 0x9e, 0xff, 0x56, 0x28, 0x8d, 0xff, 0x3a, 0x2e, 0x87, 0xff, 0x31, 0x8b, 0x9a, 0xff, 0x24, 0xe0, 0x96, 0xff, 0x04, 0xbc, 0x5b, 0xff, 0x15, 0xc1, 0x5d, 0xff, 0x05, 0x97, 0x39, 0xff, 0x0b, 0x80, 0x32, 0xff, 0x08, 0x69, 0x27, 0xff, 0x06, 0x67, 0x25, 0xff, 0x17, 0x98, 0x4b, 0xff, 0x05, 0x90, 0x34, 0xff, 0x02, 0x7b, 0x28, 0xff, 0x02, 0x65, 0x22, 0xff, 0x0e, 0x8a, 0x34, 0xff, 0x02, 0x7e, 0x21, 0xff, 0x02, 0x85, 0x24, 0xff, 0x0b, 0x87, 0x30, 0xff, 0x04, 0x68, 0x21, 0xff, 0x01, 0x60, 0x1c, 0xff, 0x08, 0x6d, 0x22, 0xff, 0x05, 0x71, 0x23, 0xff, 0x0c, 0xa5, 0x3d, 0xff, 0x16, 0xd7, 0x47, 0xff, 0x03, 0xaa, 0x22, 0xff, 0x13, 0xcd, 0x4f, 0xff, 0x14, 0xe3, 0x54, 0xff, 0x07, 0xca, 0x34, 0xff, 0x0a, 0xaf, 0x2d, 0xff, 0x04, 0x88, 0x19, 0xff, 0x0e, 0xa7, 0x2b, 0xff, 0x0e, 0xac, 0x28, 0xff, 0x02, 0x8a, 0x19, 0xff, 0x02, 0x7a, 0x20, 0xff, 0x09, 0x6d, 0x26, 0xff, 0x06, 0x74, 0x19, 0xff, 0x0e, 0x84, 0x23, 0xff, 0x04, 0x5b, 0x17, 0xff, 0x0b, 0x59, 0x1f, 0xff, 0x0d, 0x66, 0x24, 0xff, 0x08, 0x55, 0x1c, 0xff, 0x04, 0x2d, 0x11, 0xff, 0x06, 0x1d, 0x0e, 0xff, 0x62, 0x72, 0x68, 0xff, + 0x0b, 0x40, 0x28, 0xff, 0x06, 0x4b, 0x2c, 0xff, 0x09, 0x57, 0x34, 0xff, 0x0a, 0x60, 0x36, 0xff, 0x09, 0x64, 0x38, 0xff, 0x0b, 0x6d, 0x3e, 0xff, 0x16, 0x77, 0x48, 0xff, 0x0a, 0x5d, 0x38, 0xff, 0x02, 0x43, 0x2b, 0xff, 0x01, 0x38, 0x27, 0xff, 0x00, 0x44, 0x2b, 0xff, 0x09, 0x74, 0x47, 0xff, 0x09, 0x82, 0x48, 0xff, 0x0c, 0x8d, 0x4c, 0xff, 0x11, 0x79, 0x45, 0xff, 0x00, 0x38, 0x20, 0xff, 0x03, 0x3f, 0x28, 0xff, 0x07, 0x54, 0x28, 0xff, 0x0b, 0x66, 0x33, 0xff, 0x0f, 0x6f, 0x48, 0xff, 0x0a, 0x68, 0x45, 0xff, 0x01, 0x58, 0x30, 0xff, 0x03, 0x55, 0x2d, 0xff, 0x06, 0x61, 0x32, 0xff, 0x05, 0x79, 0x39, 0xff, 0x06, 0x8a, 0x44, 0xff, 0x0a, 0x89, 0x4f, 0xff, 0x12, 0x7b, 0x55, 0xff, 0x03, 0x4c, 0x27, 0xff, 0x05, 0x66, 0x2c, 0xff, 0x15, 0x98, 0x4f, 0xff, 0x11, 0x94, 0x46, 0xff, 0x08, 0x84, 0x31, 0xff, 0x14, 0x87, 0x47, 0xff, 0x07, 0x5c, 0x28, 0xff, 0x11, 0x96, 0x3e, 0xff, 0x0d, 0xae, 0x44, 0xff, 0x03, 0x81, 0x2d, 0xff, 0x05, 0x75, 0x2a, 0xff, 0x0e, 0x71, 0x35, 0xff, 0x12, 0x58, 0x2c, 0xff, 0x01, 0x38, 0x20, 0xff, 0x0d, 0x63, 0x3e, 0xff, 0x3c, 0xc2, 0x7d, 0xff, 0x25, 0xaa, 0x60, 0xff, 0x04, 0x51, 0x26, 0xff, 0x16, 0x52, 0x4e, 0xff, 0x29, 0x68, 0x82, 0xff, 0x28, 0x65, 0x85, 0xff, 0x25, 0x6e, 0x81, 0xff, 0x2e, 0x78, 0x8e, 0xff, 0x36, 0x79, 0x93, 0xff, 0x2f, 0x73, 0x87, 0xff, 0x2a, 0x83, 0x86, 0xff, 0x2b, 0x9a, 0x87, 0xff, 0x1f, 0x9c, 0x83, 0xff, 0x0f, 0x9f, 0x71, 0xff, 0x08, 0xa8, 0x69, 0xff, 0x06, 0xa6, 0x69, 0xff, 0x0b, 0xa3, 0x6f, 0xff, 0x0a, 0xa3, 0x6c, 0xff, 0x04, 0xa4, 0x6e, 0xff, 0x04, 0xa6, 0x71, 0xff, 0x0b, 0xa7, 0x6e, 0xff, 0x03, 0xa5, 0x6b, 0xff, 0x05, 0xaa, 0x6e, 0xff, 0x0a, 0xa9, 0x6d, 0xff, 0x13, 0x9d, 0x65, 0xff, 0x11, 0x88, 0x52, 0xff, 0x04, 0x66, 0x32, 0xff, 0x01, 0x56, 0x24, 0xff, 0x01, 0x49, 0x20, 0xff, 0x02, 0x49, 0x20, 0xff, 0x02, 0x49, 0x1a, 0xff, 0x0a, 0x57, 0x23, 0xff, 0x0d, 0x6a, 0x2e, 0xff, 0x04, 0x6d, 0x2c, 0xff, 0x07, 0x75, 0x31, 0xff, 0x08, 0x77, 0x32, 0xff, 0x07, 0x80, 0x34, 0xff, 0x08, 0x82, 0x34, 0xff, 0x07, 0x82, 0x33, 0xff, 0x08, 0x82, 0x34, 0xff, 0x06, 0x82, 0x32, 0xff, 0x07, 0x83, 0x33, 0xff, 0x06, 0x83, 0x33, 0xff, 0x07, 0x85, 0x34, 0xff, 0x04, 0x8b, 0x38, 0xff, 0x05, 0x8e, 0x3b, 0xff, 0x04, 0x92, 0x3d, 0xff, 0x02, 0x97, 0x3d, 0xff, 0x00, 0x9b, 0x39, 0xff, 0x01, 0xa1, 0x3b, 0xff, 0x07, 0xa1, 0x3d, 0xff, 0x08, 0xa0, 0x3d, 0xff, 0x04, 0xa8, 0x42, 0xff, 0x0d, 0xa4, 0x4b, 0xff, 0x15, 0x84, 0x3b, 0xff, 0x08, 0x5d, 0x1b, 0xff, 0x03, 0x43, 0x0d, 0xff, 0x0c, 0x43, 0x1e, 0xff, 0x0d, 0x56, 0x34, 0xff, 0x08, 0x77, 0x48, 0xff, 0x02, 0x7d, 0x46, 0xff, 0x0c, 0x7b, 0x43, 0xff, 0x09, 0x71, 0x38, 0xff, 0x0c, 0x7e, 0x49, 0xff, 0x2a, 0x83, 0x5b, 0xff, 0x10, 0x63, 0x36, 0xff, 0x11, 0x98, 0x51, 0xff, 0x0d, 0xb5, 0x62, 0xff, 0x04, 0xa8, 0x58, 0xff, 0x25, 0xd2, 0x85, 0xff, 0x28, 0xc5, 0x7f, 0xff, 0x12, 0x96, 0x56, 0xff, 0x18, 0x9d, 0x60, 0xff, 0x0a, 0x98, 0x59, 0xff, 0x0e, 0xa6, 0x67, 0xff, 0x0c, 0xa5, 0x64, 0xff, 0x0f, 0xa8, 0x67, 0xff, 0x11, 0xa5, 0x64, 0xff, 0x12, 0x9c, 0x5c, 0xff, 0x13, 0x9b, 0x5b, 0xff, 0x13, 0xa2, 0x61, 0xff, 0x11, 0xa4, 0x63, 0xff, 0x0f, 0xa2, 0x63, 0xff, 0x13, 0xa2, 0x66, 0xff, 0x11, 0xa5, 0x66, 0xff, 0x0e, 0xa4, 0x64, 0xff, 0x0d, 0xa5, 0x68, 0xff, 0x0b, 0xa4, 0x69, 0xff, 0x0a, 0xa5, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x0a, 0xa5, 0x6b, 0xff, 0x0b, 0xa6, 0x6b, 0xff, 0x0e, 0xa7, 0x6c, 0xff, 0x0f, 0xa8, 0x6d, 0xff, 0x0e, 0xa5, 0x6c, 0xff, 0x0e, 0xa4, 0x6c, 0xff, 0x10, 0xa5, 0x6d, 0xff, 0x10, 0xa5, 0x6c, 0xff, 0x10, 0xa6, 0x6a, 0xff, 0x0e, 0xa4, 0x66, 0xff, 0x0b, 0x9e, 0x5e, 0xff, 0x0a, 0x9f, 0x5b, 0xff, 0x01, 0x9e, 0x52, 0xff, 0x06, 0x9e, 0x4e, 0xff, 0x0d, 0xa0, 0x50, 0xff, 0x0a, 0xa3, 0x55, 0xff, 0x0c, 0xa3, 0x54, 0xff, 0x15, 0xb6, 0x64, 0xff, 0x0e, 0xc6, 0x69, 0xff, 0x0a, 0xc2, 0x64, 0xff, 0x0c, 0xb0, 0x5d, 0xff, 0x0d, 0x9a, 0x52, 0xff, 0x01, 0x6f, 0x33, 0xff, 0x0a, 0x6f, 0x38, 0xff, 0x0b, 0x73, 0x3c, 0xff, 0x05, 0x74, 0x3b, 0xff, 0x11, 0xa5, 0x5a, 0xff, 0x0b, 0xac, 0x58, 0xff, 0x04, 0x75, 0x34, 0xff, 0x01, 0x4b, 0x1b, 0xff, 0x1d, 0x81, 0x55, 0xff, 0x0b, 0x62, 0x37, 0xff, 0x07, 0x59, 0x32, 0xff, 0x11, 0x62, 0x45, 0xff, 0x02, 0x4c, 0x2d, 0xff, 0x1c, 0x9a, 0x6a, 0xff, 0x06, 0x62, 0x3c, 0xff, 0x0d, 0x4f, 0x36, 0xff, 0x01, 0x34, 0x1c, 0xff, 0x0b, 0x6b, 0x47, 0xff, 0x19, 0x9e, 0x6c, 0xff, 0x05, 0x4f, 0x2e, 0xff, 0x04, 0x56, 0x3a, 0xff, 0x18, 0x9a, 0x6d, 0xff, 0x0c, 0x91, 0x5c, 0xff, 0x18, 0x9d, 0x69, 0xff, 0x03, 0x6c, 0x42, 0xff, 0x1b, 0x8e, 0x69, 0xff, 0x08, 0x8a, 0x5a, 0xff, 0x23, 0xbc, 0x7d, 0xff, 0x15, 0xa9, 0x67, 0xff, 0x03, 0x67, 0x33, 0xff, 0x0d, 0x89, 0x58, 0xff, 0x04, 0xab, 0x70, 0xff, 0x03, 0xad, 0x6b, 0xff, 0x07, 0xaa, 0x69, 0xff, 0x03, 0x97, 0x5b, 0xff, 0x19, 0xaf, 0x72, 0xff, 0x2e, 0xbf, 0x81, 0xff, 0x19, 0x8e, 0x5b, 0xff, 0x0d, 0x6d, 0x40, 0xff, 0x14, 0x82, 0x52, 0xff, 0x0e, 0xa3, 0x6c, 0xff, 0x05, 0xa5, 0x69, 0xff, 0x0e, 0xa3, 0x68, 0xff, 0x0c, 0xa4, 0x66, 0xff, 0x07, 0xa5, 0x65, 0xff, 0x0b, 0xa5, 0x65, 0xff, 0x0b, 0xa4, 0x66, 0xff, 0x0c, 0xa4, 0x68, 0xff, 0x0c, 0xa4, 0x69, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0a, 0xa3, 0x6b, 0xff, 0x0b, 0xa5, 0x6a, 0xff, 0x0e, 0xa6, 0x6c, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x06, 0xa5, 0x6f, 0xff, 0x03, 0xa9, 0x69, 0xff, 0x00, 0xa9, 0x6b, 0xff, 0x04, 0xa7, 0x6c, 0xff, 0x0b, 0xa4, 0x70, 0xff, 0x0b, 0xa2, 0x74, 0xff, 0x05, 0xa6, 0x6e, 0xff, 0x08, 0xa6, 0x6e, 0xff, 0x28, 0x88, 0x72, 0xff, 0x40, 0x5f, 0x7b, 0xff, 0x43, 0x61, 0x89, 0xff, 0x2f, 0x79, 0x78, 0xff, 0x20, 0x9a, 0x74, 0xff, 0x09, 0xa1, 0x6c, 0xff, 0x04, 0xaa, 0x63, 0xff, 0x10, 0xc0, 0x6e, 0xff, 0x06, 0xab, 0x4a, 0xff, 0x11, 0xb5, 0x4c, 0xff, 0x0d, 0xab, 0x49, 0xff, 0x06, 0xa1, 0x4a, 0xff, 0x0a, 0x9a, 0x4f, 0xff, 0x11, 0x95, 0x4a, 0xff, 0x17, 0x86, 0x3c, 0xff, 0x17, 0x67, 0x34, 0xff, 0x0f, 0x40, 0x27, 0xff, 0x20, 0x38, 0x43, 0xff, 0x21, 0x38, 0x4b, 0xff, 0x0c, 0x3d, 0x2a, 0xff, 0x02, 0x4e, 0x1a, 0xff, 0x04, 0x62, 0x25, 0xff, 0x10, 0x81, 0x30, 0xff, 0x15, 0x81, 0x30, 0xff, 0x07, 0x70, 0x24, 0xff, 0x04, 0x61, 0x1e, 0xff, 0x05, 0x4c, 0x19, 0xff, 0x03, 0x3e, 0x16, 0xff, 0x04, 0x35, 0x18, 0xff, 0x03, 0x2b, 0x12, 0xff, 0x08, 0x26, 0x0e, 0xff, 0x08, 0x42, 0x16, 0xff, 0x27, 0xa6, 0x5c, 0xff, 0x14, 0xa0, 0x42, 0xff, 0x0d, 0x85, 0x33, 0xff, 0x08, 0x70, 0x27, 0xff, 0x1d, 0x9c, 0x4a, 0xff, 0x0c, 0x50, 0x32, 0xff, 0x72, 0x4f, 0xab, 0xff, 0x97, 0x50, 0xe0, 0xff, 0x81, 0x44, 0xbc, 0xff, 0x35, 0x27, 0x4e, 0xff, 0x6f, 0x4f, 0x8a, 0xff, 0x94, 0x5d, 0xd7, 0xff, 0x7e, 0x38, 0xd2, 0xff, 0x63, 0x32, 0xac, 0xff, 0x1c, 0x23, 0x38, 0xff, 0x05, 0x1d, 0x0f, 0xff, 0x08, 0x28, 0x12, 0xff, 0x0a, 0x31, 0x18, 0xff, 0x1a, 0x34, 0x3e, 0xff, 0x15, 0x4c, 0x3c, 0xff, 0x0c, 0x48, 0x1b, 0xff, 0x09, 0x35, 0x0e, 0xff, 0x0f, 0x30, 0x25, 0xff, 0x47, 0x41, 0x78, 0xff, 0x6d, 0x40, 0xac, 0xff, 0x40, 0x26, 0x73, 0xff, 0x78, 0x49, 0xa2, 0xff, 0x6f, 0x39, 0x97, 0xff, 0x5f, 0x3d, 0xa7, 0xff, 0x41, 0x75, 0x9b, 0xff, 0x12, 0x97, 0x61, 0xff, 0x1d, 0xa3, 0x54, 0xff, 0x22, 0xb0, 0x5a, 0xff, 0x13, 0xa6, 0x51, 0xff, 0x11, 0x86, 0x3e, 0xff, 0x1c, 0x71, 0x36, 0xff, 0x08, 0x4f, 0x17, 0xff, 0x0b, 0x66, 0x25, 0xff, 0x0e, 0x85, 0x33, 0xff, 0x05, 0x71, 0x25, 0xff, 0x01, 0x63, 0x24, 0xff, 0x0a, 0x82, 0x2f, 0xff, 0x05, 0x8b, 0x26, 0xff, 0x05, 0x90, 0x2b, 0xff, 0x06, 0x7b, 0x29, 0xff, 0x06, 0x5d, 0x20, 0xff, 0x05, 0x64, 0x22, 0xff, 0x10, 0x76, 0x2b, 0xff, 0x02, 0x5d, 0x19, 0xff, 0x06, 0x79, 0x21, 0xff, 0x21, 0xda, 0x4d, 0xff, 0x0c, 0xc8, 0x33, 0xff, 0x06, 0xd3, 0x45, 0xff, 0x04, 0xd4, 0x41, 0xff, 0x0c, 0xc3, 0x34, 0xff, 0x04, 0x96, 0x1e, 0xff, 0x08, 0x95, 0x1d, 0xff, 0x0d, 0xac, 0x2d, 0xff, 0x0e, 0x98, 0x26, 0xff, 0x0b, 0x85, 0x1d, 0xff, 0x07, 0x6e, 0x1e, 0xff, 0x06, 0x62, 0x1f, 0xff, 0x06, 0x6a, 0x18, 0xff, 0x0e, 0x77, 0x21, 0xff, 0x01, 0x53, 0x10, 0xff, 0x08, 0x5d, 0x1e, 0xff, 0x0c, 0x6c, 0x24, 0xff, 0x08, 0x59, 0x1c, 0xff, 0x04, 0x31, 0x11, 0xff, 0x05, 0x1f, 0x0c, 0xff, 0x64, 0x72, 0x66, 0xff, + 0x09, 0x3f, 0x27, 0xff, 0x05, 0x4e, 0x2d, 0xff, 0x08, 0x5b, 0x34, 0xff, 0x03, 0x60, 0x31, 0xff, 0x02, 0x64, 0x2f, 0xff, 0x06, 0x6e, 0x36, 0xff, 0x07, 0x73, 0x3b, 0xff, 0x1b, 0x81, 0x50, 0xff, 0x15, 0x69, 0x45, 0xff, 0x02, 0x42, 0x29, 0xff, 0x00, 0x45, 0x29, 0xff, 0x0d, 0x74, 0x4a, 0xff, 0x07, 0x7e, 0x47, 0xff, 0x0c, 0x8b, 0x4c, 0xff, 0x12, 0x7a, 0x46, 0xff, 0x01, 0x3d, 0x22, 0xff, 0x04, 0x47, 0x2c, 0xff, 0x07, 0x5c, 0x2d, 0xff, 0x09, 0x69, 0x34, 0xff, 0x10, 0x70, 0x4a, 0xff, 0x04, 0x5d, 0x41, 0xff, 0x01, 0x54, 0x33, 0xff, 0x05, 0x59, 0x33, 0xff, 0x0b, 0x68, 0x39, 0xff, 0x08, 0x7a, 0x3c, 0xff, 0x0a, 0x80, 0x41, 0xff, 0x10, 0x7c, 0x4d, 0xff, 0x07, 0x4e, 0x34, 0xff, 0x00, 0x43, 0x21, 0xff, 0x0d, 0x9d, 0x57, 0xff, 0x13, 0xb4, 0x5e, 0xff, 0x08, 0x97, 0x41, 0xff, 0x07, 0x8b, 0x30, 0xff, 0x19, 0x8a, 0x50, 0xff, 0x08, 0x54, 0x29, 0xff, 0x0d, 0x95, 0x40, 0xff, 0x08, 0xa5, 0x41, 0xff, 0x01, 0x7b, 0x2a, 0xff, 0x03, 0x74, 0x23, 0xff, 0x11, 0x71, 0x2e, 0xff, 0x0a, 0x52, 0x21, 0xff, 0x00, 0x37, 0x1d, 0xff, 0x04, 0x4d, 0x30, 0xff, 0x2d, 0x9d, 0x6a, 0xff, 0x0f, 0x75, 0x3f, 0xff, 0x03, 0x42, 0x27, 0xff, 0x1c, 0x59, 0x5e, 0xff, 0x2b, 0x67, 0x84, 0xff, 0x2a, 0x6a, 0x82, 0xff, 0x30, 0x86, 0x91, 0xff, 0x2e, 0x78, 0x8d, 0xff, 0x2b, 0x67, 0x82, 0xff, 0x29, 0x6a, 0x80, 0xff, 0x2b, 0x69, 0x84, 0xff, 0x30, 0x75, 0x86, 0xff, 0x32, 0x91, 0x90, 0xff, 0x2f, 0x9c, 0x90, 0xff, 0x1f, 0x9e, 0x78, 0xff, 0x17, 0xa0, 0x6a, 0xff, 0x10, 0xa3, 0x6b, 0xff, 0x07, 0xa5, 0x6b, 0xff, 0x06, 0xa4, 0x6e, 0xff, 0x09, 0xa5, 0x71, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x0b, 0xa8, 0x6e, 0xff, 0x11, 0xa4, 0x6a, 0xff, 0x0c, 0x90, 0x57, 0xff, 0x03, 0x6f, 0x39, 0xff, 0x02, 0x5e, 0x2b, 0xff, 0x07, 0x5f, 0x2c, 0xff, 0x05, 0x5a, 0x2a, 0xff, 0x02, 0x52, 0x2b, 0xff, 0x04, 0x51, 0x27, 0xff, 0x09, 0x58, 0x29, 0xff, 0x10, 0x65, 0x2f, 0xff, 0x0a, 0x6d, 0x30, 0xff, 0x05, 0x70, 0x2e, 0xff, 0x09, 0x75, 0x31, 0xff, 0x0c, 0x79, 0x34, 0xff, 0x07, 0x7e, 0x33, 0xff, 0x09, 0x81, 0x35, 0xff, 0x07, 0x81, 0x35, 0xff, 0x08, 0x82, 0x34, 0xff, 0x05, 0x82, 0x33, 0xff, 0x06, 0x83, 0x33, 0xff, 0x06, 0x83, 0x33, 0xff, 0x06, 0x85, 0x33, 0xff, 0x08, 0x8c, 0x32, 0xff, 0x08, 0x8d, 0x38, 0xff, 0x06, 0x8e, 0x3d, 0xff, 0x05, 0x93, 0x40, 0xff, 0x03, 0x99, 0x3c, 0xff, 0x04, 0x9f, 0x3c, 0xff, 0x06, 0xa2, 0x3e, 0xff, 0x07, 0xa1, 0x40, 0xff, 0x17, 0x9c, 0x4a, 0xff, 0x13, 0x7c, 0x3a, 0xff, 0x03, 0x44, 0x0f, 0xff, 0x0f, 0x4b, 0x14, 0xff, 0x2c, 0x77, 0x40, 0xff, 0x13, 0x58, 0x2c, 0xff, 0x04, 0x51, 0x29, 0xff, 0x02, 0x75, 0x41, 0xff, 0x01, 0x83, 0x45, 0xff, 0x01, 0x82, 0x41, 0xff, 0x0a, 0x84, 0x40, 0xff, 0x05, 0x73, 0x39, 0xff, 0x2b, 0x6c, 0x4c, 0xff, 0x0f, 0x66, 0x39, 0xff, 0x0c, 0x9e, 0x50, 0xff, 0x06, 0xa3, 0x54, 0xff, 0x0c, 0x9a, 0x51, 0xff, 0x28, 0xca, 0x81, 0xff, 0x24, 0xc2, 0x7d, 0xff, 0x10, 0x91, 0x52, 0xff, 0x1d, 0x9c, 0x61, 0xff, 0x15, 0xa1, 0x64, 0xff, 0x0e, 0xa4, 0x65, 0xff, 0x0c, 0xa5, 0x64, 0xff, 0x04, 0xa8, 0x67, 0xff, 0x09, 0xaa, 0x69, 0xff, 0x0a, 0x9e, 0x5e, 0xff, 0x0e, 0x9f, 0x5e, 0xff, 0x0a, 0xa2, 0x61, 0xff, 0x05, 0xa3, 0x61, 0xff, 0x06, 0xa2, 0x61, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x0f, 0xa2, 0x64, 0xff, 0x0e, 0xa1, 0x65, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0c, 0xa5, 0x6a, 0xff, 0x0c, 0xa5, 0x6d, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0c, 0xa5, 0x6e, 0xff, 0x0d, 0xa5, 0x6e, 0xff, 0x0e, 0xa5, 0x6f, 0xff, 0x10, 0xa5, 0x6f, 0xff, 0x0f, 0xa4, 0x6d, 0xff, 0x0e, 0xa2, 0x69, 0xff, 0x0d, 0xa1, 0x64, 0xff, 0x09, 0x9d, 0x5e, 0xff, 0x09, 0x9a, 0x59, 0xff, 0x08, 0x9e, 0x58, 0xff, 0x01, 0xa2, 0x53, 0xff, 0x06, 0x9f, 0x4d, 0xff, 0x0d, 0x9e, 0x4e, 0xff, 0x0b, 0xa2, 0x53, 0xff, 0x0b, 0xa3, 0x54, 0xff, 0x13, 0xb5, 0x62, 0xff, 0x0c, 0xc6, 0x68, 0xff, 0x09, 0xc4, 0x63, 0xff, 0x04, 0xb1, 0x58, 0xff, 0x0b, 0xa3, 0x55, 0xff, 0x01, 0x74, 0x34, 0xff, 0x04, 0x6d, 0x33, 0xff, 0x08, 0x6e, 0x37, 0xff, 0x07, 0x76, 0x3d, 0xff, 0x1a, 0xac, 0x5f, 0xff, 0x0c, 0xa5, 0x54, 0xff, 0x02, 0x62, 0x2c, 0xff, 0x02, 0x49, 0x1e, 0xff, 0x1f, 0x7b, 0x4f, 0xff, 0x04, 0x48, 0x22, 0xff, 0x04, 0x46, 0x2a, 0xff, 0x0f, 0x52, 0x3b, 0xff, 0x02, 0x3c, 0x1e, 0xff, 0x1c, 0x86, 0x5c, 0xff, 0x06, 0x5c, 0x38, 0xff, 0x10, 0x56, 0x38, 0xff, 0x01, 0x31, 0x1c, 0xff, 0x05, 0x55, 0x37, 0xff, 0x1c, 0x96, 0x66, 0xff, 0x04, 0x4d, 0x2b, 0xff, 0x05, 0x4f, 0x36, 0xff, 0x13, 0x84, 0x5d, 0xff, 0x11, 0x89, 0x56, 0xff, 0x14, 0x8d, 0x5d, 0xff, 0x02, 0x5f, 0x3f, 0xff, 0x19, 0x7c, 0x5f, 0xff, 0x0d, 0x82, 0x53, 0xff, 0x25, 0xbe, 0x7b, 0xff, 0x0f, 0x92, 0x51, 0xff, 0x02, 0x57, 0x2a, 0xff, 0x0e, 0x94, 0x60, 0xff, 0x04, 0xae, 0x70, 0xff, 0x06, 0xa4, 0x65, 0xff, 0x0e, 0x9c, 0x62, 0xff, 0x24, 0xb6, 0x7e, 0xff, 0x42, 0xdd, 0xa0, 0xff, 0x38, 0xd7, 0x97, 0xff, 0x28, 0xae, 0x76, 0xff, 0x11, 0x76, 0x46, 0xff, 0x0b, 0x74, 0x46, 0xff, 0x13, 0x9d, 0x6a, 0xff, 0x0a, 0xa2, 0x6b, 0xff, 0x10, 0xa0, 0x67, 0xff, 0x0f, 0xa3, 0x65, 0xff, 0x08, 0xa6, 0x64, 0xff, 0x0a, 0xa5, 0x64, 0xff, 0x0a, 0xa4, 0x65, 0xff, 0x0b, 0xa3, 0x67, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x0a, 0xa2, 0x6a, 0xff, 0x08, 0xa2, 0x69, 0xff, 0x08, 0xa4, 0x68, 0xff, 0x0b, 0xa6, 0x6a, 0xff, 0x0c, 0xa3, 0x70, 0xff, 0x06, 0xa6, 0x6e, 0xff, 0x06, 0xa8, 0x6b, 0xff, 0x00, 0xa8, 0x69, 0xff, 0x02, 0xa8, 0x6a, 0xff, 0x0b, 0xa2, 0x70, 0xff, 0x08, 0xa3, 0x71, 0xff, 0x04, 0xa7, 0x67, 0xff, 0x18, 0x9e, 0x70, 0xff, 0x41, 0x57, 0x7b, 0xff, 0x87, 0x54, 0xb4, 0xff, 0xa2, 0x69, 0xd4, 0xff, 0x74, 0x5a, 0xa1, 0xff, 0x44, 0x77, 0x7f, 0xff, 0x19, 0x9a, 0x74, 0xff, 0x08, 0xb5, 0x6c, 0xff, 0x09, 0xb7, 0x5d, 0xff, 0x09, 0xb3, 0x4d, 0xff, 0x0e, 0xb7, 0x4d, 0xff, 0x0d, 0xaf, 0x4e, 0xff, 0x0b, 0xa5, 0x4f, 0xff, 0x09, 0x93, 0x4a, 0xff, 0x0d, 0x86, 0x40, 0xff, 0x0d, 0x73, 0x2e, 0xff, 0x0d, 0x69, 0x2a, 0xff, 0x12, 0x5a, 0x21, 0xff, 0x12, 0x4b, 0x26, 0xff, 0x11, 0x49, 0x31, 0xff, 0x16, 0x56, 0x31, 0xff, 0x0e, 0x54, 0x2a, 0xff, 0x08, 0x58, 0x29, 0xff, 0x0d, 0x73, 0x2f, 0xff, 0x0d, 0x6c, 0x25, 0xff, 0x01, 0x51, 0x12, 0xff, 0x00, 0x44, 0x10, 0xff, 0x00, 0x3c, 0x14, 0xff, 0x03, 0x36, 0x15, 0xff, 0x08, 0x31, 0x16, 0xff, 0x01, 0x26, 0x0c, 0xff, 0x00, 0x25, 0x06, 0xff, 0x16, 0x7c, 0x3d, 0xff, 0x1a, 0xa4, 0x4f, 0xff, 0x0f, 0x93, 0x37, 0xff, 0x0d, 0x76, 0x3a, 0xff, 0x13, 0x7b, 0x42, 0xff, 0x13, 0x6e, 0x2c, 0xff, 0x12, 0x39, 0x30, 0xff, 0x59, 0x38, 0x9a, 0xff, 0x9f, 0x68, 0xdb, 0xff, 0x6a, 0x4a, 0x8c, 0xff, 0x15, 0x19, 0x21, 0xff, 0x60, 0x4e, 0x7c, 0xff, 0x9e, 0x71, 0xda, 0xff, 0x95, 0x49, 0xf3, 0xff, 0x7b, 0x3d, 0xdb, 0xff, 0x2d, 0x2d, 0x4f, 0xff, 0x04, 0x23, 0x13, 0xff, 0x0c, 0x3e, 0x10, 0xff, 0x0b, 0x40, 0x11, 0xff, 0x0f, 0x4f, 0x25, 0xff, 0x07, 0x5f, 0x2a, 0xff, 0x0f, 0x53, 0x1f, 0xff, 0x0e, 0x41, 0x12, 0xff, 0x08, 0x2f, 0x21, 0xff, 0x1b, 0x18, 0x47, 0xff, 0x26, 0x15, 0x54, 0xff, 0x34, 0x2a, 0x6a, 0xff, 0xa7, 0x6f, 0xde, 0xff, 0x9d, 0x5f, 0xd5, 0xff, 0x63, 0x2f, 0xaf, 0xff, 0x45, 0x48, 0x91, 0xff, 0x05, 0x41, 0x26, 0xff, 0x09, 0x4c, 0x1d, 0xff, 0x09, 0x5b, 0x27, 0xff, 0x11, 0x83, 0x44, 0xff, 0x16, 0x82, 0x42, 0xff, 0x17, 0x66, 0x2e, 0xff, 0x0e, 0x51, 0x1e, 0xff, 0x06, 0x4c, 0x16, 0xff, 0x09, 0x5e, 0x1f, 0xff, 0x10, 0x67, 0x2d, 0xff, 0x03, 0x63, 0x26, 0xff, 0x05, 0x7d, 0x2a, 0xff, 0x0f, 0x97, 0x31, 0xff, 0x0a, 0x94, 0x31, 0xff, 0x01, 0x6d, 0x1d, 0xff, 0x07, 0x61, 0x20, 0xff, 0x0e, 0x70, 0x2a, 0xff, 0x0b, 0x68, 0x20, 0xff, 0x00, 0x4c, 0x15, 0xff, 0x03, 0x5a, 0x14, 0xff, 0x20, 0xd4, 0x50, 0xff, 0x0d, 0xdc, 0x42, 0xff, 0x0c, 0xd9, 0x49, 0xff, 0x19, 0xdb, 0x52, 0xff, 0x0d, 0xab, 0x2c, 0xff, 0x01, 0x77, 0x11, 0xff, 0x0f, 0x9e, 0x27, 0xff, 0x0a, 0xaa, 0x2b, 0xff, 0x03, 0x7e, 0x17, 0xff, 0x0e, 0x7e, 0x1f, 0xff, 0x06, 0x63, 0x17, 0xff, 0x03, 0x61, 0x16, 0xff, 0x03, 0x5e, 0x16, 0xff, 0x02, 0x55, 0x12, 0xff, 0x00, 0x52, 0x10, 0xff, 0x04, 0x5e, 0x1b, 0xff, 0x08, 0x6e, 0x20, 0xff, 0x07, 0x5c, 0x1e, 0xff, 0x03, 0x31, 0x10, 0xff, 0x03, 0x1e, 0x09, 0xff, 0x64, 0x6f, 0x65, 0xff, + 0x07, 0x3f, 0x27, 0xff, 0x01, 0x49, 0x29, 0xff, 0x04, 0x58, 0x30, 0xff, 0x04, 0x61, 0x31, 0xff, 0x01, 0x64, 0x2f, 0xff, 0x05, 0x6c, 0x34, 0xff, 0x04, 0x71, 0x35, 0xff, 0x0b, 0x76, 0x3e, 0xff, 0x1c, 0x7b, 0x50, 0xff, 0x0d, 0x5e, 0x3f, 0xff, 0x01, 0x4a, 0x2b, 0xff, 0x0f, 0x72, 0x49, 0xff, 0x08, 0x7a, 0x47, 0xff, 0x0b, 0x8b, 0x4d, 0xff, 0x13, 0x7f, 0x4a, 0xff, 0x05, 0x48, 0x29, 0xff, 0x06, 0x4e, 0x32, 0xff, 0x0b, 0x62, 0x37, 0xff, 0x0b, 0x6a, 0x36, 0xff, 0x16, 0x78, 0x4d, 0xff, 0x17, 0x76, 0x55, 0xff, 0x02, 0x5d, 0x3c, 0xff, 0x02, 0x5c, 0x34, 0xff, 0x09, 0x6c, 0x3d, 0xff, 0x0b, 0x74, 0x3f, 0xff, 0x15, 0x77, 0x47, 0xff, 0x10, 0x68, 0x46, 0xff, 0x01, 0x36, 0x20, 0xff, 0x01, 0x5f, 0x39, 0xff, 0x12, 0xc1, 0x75, 0xff, 0x12, 0xbf, 0x68, 0xff, 0x01, 0x94, 0x3d, 0xff, 0x06, 0x91, 0x36, 0xff, 0x24, 0x92, 0x5e, 0xff, 0x09, 0x4c, 0x29, 0xff, 0x12, 0x9e, 0x4c, 0xff, 0x10, 0xa7, 0x47, 0xff, 0x04, 0x7c, 0x2e, 0xff, 0x09, 0x79, 0x27, 0xff, 0x16, 0x79, 0x34, 0xff, 0x07, 0x49, 0x1d, 0xff, 0x02, 0x36, 0x21, 0xff, 0x03, 0x42, 0x29, 0xff, 0x1d, 0x78, 0x4f, 0xff, 0x0a, 0x54, 0x2f, 0xff, 0x08, 0x3a, 0x31, 0xff, 0x1e, 0x5f, 0x66, 0xff, 0x20, 0x6c, 0x78, 0xff, 0x39, 0x8c, 0x95, 0xff, 0x31, 0x84, 0x8d, 0xff, 0x28, 0x6a, 0x84, 0xff, 0x2b, 0x67, 0x82, 0xff, 0x27, 0x69, 0x7e, 0xff, 0x2e, 0x65, 0x8a, 0xff, 0x33, 0x65, 0x8b, 0xff, 0x2b, 0x70, 0x84, 0xff, 0x2d, 0x7c, 0x8f, 0xff, 0x3b, 0x9f, 0x8e, 0xff, 0x30, 0xa5, 0x7a, 0xff, 0x16, 0xa1, 0x6e, 0xff, 0x07, 0xa3, 0x6c, 0xff, 0x05, 0xa5, 0x6c, 0xff, 0x0b, 0xa5, 0x70, 0xff, 0x09, 0xa7, 0x6e, 0xff, 0x15, 0xa7, 0x70, 0xff, 0x0c, 0x84, 0x4c, 0xff, 0x02, 0x66, 0x30, 0xff, 0x04, 0x61, 0x2c, 0xff, 0x0c, 0x64, 0x31, 0xff, 0x0e, 0x65, 0x33, 0xff, 0x0c, 0x62, 0x31, 0xff, 0x02, 0x58, 0x2d, 0xff, 0x03, 0x5b, 0x2e, 0xff, 0x0b, 0x64, 0x31, 0xff, 0x0a, 0x6a, 0x31, 0xff, 0x04, 0x6f, 0x2d, 0xff, 0x05, 0x73, 0x30, 0xff, 0x09, 0x76, 0x31, 0xff, 0x0c, 0x78, 0x31, 0xff, 0x06, 0x7b, 0x31, 0xff, 0x09, 0x7f, 0x35, 0xff, 0x09, 0x81, 0x35, 0xff, 0x07, 0x81, 0x34, 0xff, 0x06, 0x81, 0x33, 0xff, 0x05, 0x82, 0x33, 0xff, 0x05, 0x82, 0x32, 0xff, 0x05, 0x85, 0x32, 0xff, 0x06, 0x8b, 0x2e, 0xff, 0x0a, 0x8d, 0x35, 0xff, 0x0a, 0x8d, 0x3c, 0xff, 0x08, 0x91, 0x3f, 0xff, 0x03, 0x97, 0x3e, 0xff, 0x04, 0x9c, 0x3e, 0xff, 0x0c, 0x9f, 0x44, 0xff, 0x12, 0x9b, 0x46, 0xff, 0x11, 0x6e, 0x2e, 0xff, 0x03, 0x3f, 0x0d, 0xff, 0x09, 0x49, 0x17, 0xff, 0x32, 0x84, 0x47, 0xff, 0x64, 0xc6, 0x83, 0xff, 0x10, 0x64, 0x2b, 0xff, 0x03, 0x4f, 0x1f, 0xff, 0x08, 0x71, 0x39, 0xff, 0x09, 0x8b, 0x45, 0xff, 0x01, 0x89, 0x41, 0xff, 0x09, 0x91, 0x46, 0xff, 0x0a, 0x7d, 0x3f, 0xff, 0x23, 0x5e, 0x40, 0xff, 0x0e, 0x6a, 0x3e, 0xff, 0x0f, 0xa1, 0x55, 0xff, 0x0d, 0x9c, 0x54, 0xff, 0x14, 0x9b, 0x57, 0xff, 0x17, 0xb1, 0x6b, 0xff, 0x21, 0xba, 0x78, 0xff, 0x15, 0x96, 0x5a, 0xff, 0x36, 0xb2, 0x79, 0xff, 0x2b, 0xae, 0x73, 0xff, 0x1d, 0xa5, 0x68, 0xff, 0x0d, 0x9d, 0x5e, 0xff, 0x0e, 0xb1, 0x72, 0xff, 0x08, 0xa8, 0x69, 0xff, 0x09, 0x9d, 0x5e, 0xff, 0x0c, 0x9c, 0x5d, 0xff, 0x08, 0xa0, 0x5f, 0xff, 0x04, 0xa1, 0x60, 0xff, 0x08, 0xa3, 0x63, 0xff, 0x0d, 0xa1, 0x63, 0xff, 0x10, 0xa1, 0x65, 0xff, 0x14, 0xa4, 0x6b, 0xff, 0x16, 0xa9, 0x6e, 0xff, 0x11, 0xa7, 0x6d, 0xff, 0x10, 0xa7, 0x70, 0xff, 0x0f, 0xa5, 0x6e, 0xff, 0x11, 0xa6, 0x71, 0xff, 0x11, 0xa6, 0x72, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0e, 0xa6, 0x71, 0xff, 0x0e, 0xa5, 0x71, 0xff, 0x0e, 0xa3, 0x6f, 0xff, 0x10, 0xa5, 0x6d, 0xff, 0x0f, 0xa4, 0x69, 0xff, 0x0e, 0xa2, 0x65, 0xff, 0x0b, 0x9e, 0x5f, 0xff, 0x0b, 0x9c, 0x5c, 0xff, 0x0b, 0xa2, 0x5f, 0xff, 0x02, 0xa4, 0x57, 0xff, 0x08, 0xa3, 0x53, 0xff, 0x0e, 0x9e, 0x50, 0xff, 0x08, 0x9d, 0x51, 0xff, 0x07, 0x9d, 0x50, 0xff, 0x11, 0xb4, 0x63, 0xff, 0x0b, 0xc4, 0x68, 0xff, 0x09, 0xc5, 0x63, 0xff, 0x02, 0xb5, 0x58, 0xff, 0x0b, 0xab, 0x57, 0xff, 0x03, 0x7d, 0x38, 0xff, 0x04, 0x6c, 0x31, 0xff, 0x07, 0x6f, 0x39, 0xff, 0x08, 0x77, 0x3f, 0xff, 0x19, 0xaa, 0x5c, 0xff, 0x0a, 0x9c, 0x4e, 0xff, 0x01, 0x56, 0x27, 0xff, 0x08, 0x4b, 0x25, 0xff, 0x1c, 0x6e, 0x44, 0xff, 0x01, 0x3c, 0x1b, 0xff, 0x06, 0x3d, 0x28, 0xff, 0x0b, 0x45, 0x30, 0xff, 0x02, 0x39, 0x1b, 0xff, 0x1d, 0x77, 0x53, 0xff, 0x06, 0x5a, 0x35, 0xff, 0x12, 0x5f, 0x3c, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x03, 0x46, 0x2e, 0xff, 0x1e, 0x90, 0x63, 0xff, 0x04, 0x50, 0x2c, 0xff, 0x05, 0x44, 0x2e, 0xff, 0x08, 0x65, 0x42, 0xff, 0x1a, 0x8a, 0x5a, 0xff, 0x0e, 0x7e, 0x53, 0xff, 0x04, 0x54, 0x3c, 0xff, 0x15, 0x66, 0x50, 0xff, 0x17, 0x8f, 0x60, 0xff, 0x24, 0xc0, 0x79, 0xff, 0x0b, 0x82, 0x44, 0xff, 0x02, 0x51, 0x2a, 0xff, 0x07, 0x98, 0x63, 0xff, 0x07, 0xab, 0x6e, 0xff, 0x08, 0x8d, 0x57, 0xff, 0x1c, 0x90, 0x60, 0xff, 0x36, 0xbb, 0x89, 0xff, 0x4d, 0xe5, 0xab, 0xff, 0x3d, 0xe1, 0xa0, 0xff, 0x2b, 0xc2, 0x85, 0xff, 0x15, 0x88, 0x53, 0xff, 0x06, 0x6f, 0x41, 0xff, 0x11, 0x8e, 0x5f, 0xff, 0x12, 0x9f, 0x6b, 0xff, 0x10, 0xa1, 0x69, 0xff, 0x0d, 0xa2, 0x64, 0xff, 0x07, 0xa4, 0x63, 0xff, 0x08, 0xa4, 0x64, 0xff, 0x08, 0xa4, 0x66, 0xff, 0x08, 0xa4, 0x67, 0xff, 0x06, 0xa2, 0x69, 0xff, 0x05, 0xa2, 0x68, 0xff, 0x03, 0xa2, 0x67, 0xff, 0x04, 0xa5, 0x68, 0xff, 0x06, 0xa5, 0x69, 0xff, 0x0a, 0xa4, 0x6e, 0xff, 0x06, 0xa6, 0x6c, 0xff, 0x0b, 0xa6, 0x6d, 0xff, 0x02, 0xa7, 0x6b, 0xff, 0x03, 0xa7, 0x6b, 0xff, 0x08, 0xa3, 0x6d, 0xff, 0x04, 0xa4, 0x6b, 0xff, 0x0e, 0xa3, 0x6a, 0xff, 0x2b, 0x7a, 0x73, 0xff, 0x76, 0x4a, 0xa3, 0xff, 0xba, 0x55, 0xdc, 0xff, 0xc6, 0x64, 0xec, 0xff, 0xc4, 0x6e, 0xe2, 0xff, 0x6d, 0x60, 0x97, 0xff, 0x25, 0x86, 0x7a, 0xff, 0x10, 0xbd, 0x76, 0xff, 0x03, 0xb1, 0x50, 0xff, 0x09, 0xb6, 0x51, 0xff, 0x0c, 0xb4, 0x52, 0xff, 0x16, 0xae, 0x56, 0xff, 0x0f, 0x93, 0x46, 0xff, 0x05, 0x70, 0x30, 0xff, 0x02, 0x5b, 0x24, 0xff, 0x01, 0x4e, 0x1b, 0xff, 0x01, 0x48, 0x18, 0xff, 0x04, 0x43, 0x0e, 0xff, 0x06, 0x3f, 0x13, 0xff, 0x06, 0x3f, 0x1c, 0xff, 0x0b, 0x47, 0x20, 0xff, 0x12, 0x49, 0x27, 0xff, 0x0a, 0x47, 0x26, 0xff, 0x05, 0x57, 0x25, 0xff, 0x06, 0x53, 0x1c, 0xff, 0x03, 0x41, 0x11, 0xff, 0x03, 0x3a, 0x13, 0xff, 0x01, 0x36, 0x14, 0xff, 0x06, 0x35, 0x15, 0xff, 0x03, 0x2a, 0x0b, 0xff, 0x01, 0x2e, 0x0e, 0xff, 0x0c, 0x4e, 0x25, 0xff, 0x30, 0xa7, 0x5f, 0xff, 0x14, 0x88, 0x45, 0xff, 0x0b, 0x66, 0x31, 0xff, 0x14, 0x52, 0x47, 0xff, 0x1b, 0x65, 0x4b, 0xff, 0x08, 0x42, 0x1a, 0xff, 0x22, 0x32, 0x44, 0xff, 0x54, 0x2d, 0x9d, 0xff, 0x5d, 0x3b, 0x97, 0xff, 0x30, 0x2d, 0x45, 0xff, 0x05, 0x1a, 0x10, 0xff, 0x22, 0x34, 0x42, 0xff, 0x61, 0x52, 0x8b, 0xff, 0x99, 0x5d, 0xe5, 0xff, 0x83, 0x51, 0xdf, 0xff, 0x2b, 0x30, 0x4a, 0xff, 0x02, 0x2a, 0x14, 0xff, 0x08, 0x51, 0x15, 0xff, 0x0c, 0x4f, 0x1a, 0xff, 0x17, 0x5b, 0x2e, 0xff, 0x16, 0x78, 0x43, 0xff, 0x0c, 0x4f, 0x23, 0xff, 0x16, 0x42, 0x22, 0xff, 0x18, 0x31, 0x37, 0xff, 0x55, 0x48, 0x80, 0xff, 0x25, 0x21, 0x4a, 0xff, 0x20, 0x20, 0x52, 0xff, 0x88, 0x5a, 0xbf, 0xff, 0x7c, 0x43, 0xbd, 0xff, 0x67, 0x32, 0xb4, 0xff, 0x56, 0x3f, 0x93, 0xff, 0x06, 0x19, 0x13, 0xff, 0x00, 0x18, 0x04, 0xff, 0x00, 0x1c, 0x04, 0xff, 0x02, 0x49, 0x1b, 0xff, 0x07, 0x63, 0x2b, 0xff, 0x04, 0x53, 0x1d, 0xff, 0x08, 0x50, 0x1f, 0xff, 0x06, 0x4c, 0x1b, 0xff, 0x02, 0x46, 0x13, 0xff, 0x04, 0x4b, 0x19, 0xff, 0x01, 0x58, 0x17, 0xff, 0x04, 0x7b, 0x26, 0xff, 0x0f, 0x99, 0x34, 0xff, 0x04, 0x8a, 0x28, 0xff, 0x01, 0x6a, 0x1a, 0xff, 0x06, 0x67, 0x20, 0xff, 0x08, 0x6b, 0x22, 0xff, 0x02, 0x55, 0x11, 0xff, 0x03, 0x45, 0x19, 0xff, 0x01, 0x47, 0x12, 0xff, 0x19, 0xbe, 0x4b, 0xff, 0x17, 0xe6, 0x55, 0xff, 0x1c, 0xd8, 0x50, 0xff, 0x0c, 0xac, 0x31, 0xff, 0x01, 0x83, 0x14, 0xff, 0x05, 0x6e, 0x18, 0xff, 0x0b, 0x8a, 0x20, 0xff, 0x11, 0xa5, 0x29, 0xff, 0x01, 0x7a, 0x0e, 0xff, 0x04, 0x6d, 0x14, 0xff, 0x09, 0x65, 0x1b, 0xff, 0x03, 0x62, 0x16, 0xff, 0x07, 0x5b, 0x1a, 0xff, 0x00, 0x4a, 0x0e, 0xff, 0x00, 0x53, 0x10, 0xff, 0x02, 0x61, 0x19, 0xff, 0x09, 0x73, 0x23, 0xff, 0x06, 0x59, 0x1a, 0xff, 0x02, 0x31, 0x0e, 0xff, 0x02, 0x1f, 0x09, 0xff, 0x64, 0x6f, 0x64, 0xff, + 0x09, 0x43, 0x2c, 0xff, 0x02, 0x4a, 0x2a, 0xff, 0x02, 0x52, 0x2e, 0xff, 0x06, 0x60, 0x33, 0xff, 0x04, 0x61, 0x2f, 0xff, 0x07, 0x67, 0x31, 0xff, 0x04, 0x6b, 0x31, 0xff, 0x04, 0x70, 0x35, 0xff, 0x07, 0x70, 0x3d, 0xff, 0x18, 0x7c, 0x55, 0xff, 0x06, 0x5b, 0x38, 0xff, 0x11, 0x6e, 0x48, 0xff, 0x09, 0x75, 0x44, 0xff, 0x09, 0x89, 0x4e, 0xff, 0x10, 0x81, 0x4a, 0xff, 0x03, 0x51, 0x2a, 0xff, 0x05, 0x56, 0x33, 0xff, 0x0c, 0x64, 0x3d, 0xff, 0x0d, 0x6c, 0x3b, 0xff, 0x0c, 0x70, 0x3c, 0xff, 0x15, 0x79, 0x4f, 0xff, 0x15, 0x7c, 0x57, 0xff, 0x07, 0x6e, 0x44, 0xff, 0x04, 0x62, 0x35, 0xff, 0x07, 0x5f, 0x37, 0xff, 0x0d, 0x56, 0x39, 0xff, 0x04, 0x3f, 0x29, 0xff, 0x00, 0x39, 0x1f, 0xff, 0x11, 0x95, 0x67, 0xff, 0x1d, 0xd6, 0x8d, 0xff, 0x1c, 0xbf, 0x73, 0xff, 0x19, 0xab, 0x5f, 0xff, 0x17, 0xa5, 0x57, 0xff, 0x21, 0x85, 0x5b, 0xff, 0x03, 0x43, 0x27, 0xff, 0x15, 0xa3, 0x57, 0xff, 0x1c, 0xb0, 0x54, 0xff, 0x09, 0x78, 0x2d, 0xff, 0x0f, 0x7f, 0x2e, 0xff, 0x18, 0x78, 0x3a, 0xff, 0x04, 0x39, 0x1e, 0xff, 0x09, 0x31, 0x25, 0xff, 0x03, 0x37, 0x22, 0xff, 0x05, 0x47, 0x24, 0xff, 0x04, 0x35, 0x1a, 0xff, 0x09, 0x38, 0x34, 0xff, 0x0c, 0x5d, 0x56, 0xff, 0x26, 0x90, 0x7e, 0xff, 0x37, 0x9a, 0x99, 0xff, 0x27, 0x68, 0x7b, 0xff, 0x2f, 0x65, 0x89, 0xff, 0x2a, 0x68, 0x86, 0xff, 0x2c, 0x6b, 0x84, 0xff, 0x2b, 0x64, 0x8e, 0xff, 0x34, 0x65, 0x94, 0xff, 0x34, 0x67, 0x90, 0xff, 0x27, 0x68, 0x8e, 0xff, 0x35, 0x8c, 0x89, 0xff, 0x56, 0xb9, 0xa0, 0xff, 0x1f, 0x96, 0x78, 0xff, 0x0c, 0x9f, 0x72, 0xff, 0x04, 0xa7, 0x6b, 0xff, 0x0a, 0xa7, 0x6e, 0xff, 0x11, 0xa3, 0x6e, 0xff, 0x0d, 0x89, 0x55, 0xff, 0x02, 0x5c, 0x2a, 0xff, 0x0a, 0x60, 0x2d, 0xff, 0x10, 0x65, 0x30, 0xff, 0x0f, 0x67, 0x32, 0xff, 0x10, 0x66, 0x34, 0xff, 0x09, 0x5e, 0x2d, 0xff, 0x02, 0x5c, 0x2c, 0xff, 0x04, 0x63, 0x2e, 0xff, 0x07, 0x69, 0x30, 0xff, 0x07, 0x6e, 0x2f, 0xff, 0x03, 0x71, 0x2c, 0xff, 0x05, 0x74, 0x2e, 0xff, 0x0a, 0x78, 0x30, 0xff, 0x0b, 0x79, 0x30, 0xff, 0x05, 0x79, 0x30, 0xff, 0x06, 0x7b, 0x32, 0xff, 0x08, 0x7e, 0x34, 0xff, 0x08, 0x7f, 0x34, 0xff, 0x07, 0x81, 0x33, 0xff, 0x06, 0x82, 0x34, 0xff, 0x06, 0x83, 0x33, 0xff, 0x05, 0x83, 0x32, 0xff, 0x02, 0x86, 0x2e, 0xff, 0x09, 0x8d, 0x36, 0xff, 0x09, 0x8d, 0x36, 0xff, 0x07, 0x92, 0x3a, 0xff, 0x05, 0x98, 0x3f, 0xff, 0x0d, 0x99, 0x44, 0xff, 0x15, 0x8b, 0x43, 0xff, 0x0a, 0x66, 0x28, 0xff, 0x01, 0x38, 0x06, 0xff, 0x08, 0x46, 0x18, 0xff, 0x1f, 0x74, 0x3b, 0xff, 0x23, 0x8f, 0x44, 0xff, 0x65, 0xd9, 0x85, 0xff, 0x3a, 0x92, 0x4c, 0xff, 0x07, 0x4e, 0x19, 0xff, 0x0e, 0x6c, 0x36, 0xff, 0x0d, 0x8f, 0x43, 0xff, 0x05, 0x91, 0x41, 0xff, 0x05, 0x95, 0x43, 0xff, 0x09, 0x87, 0x43, 0xff, 0x0d, 0x54, 0x2f, 0xff, 0x0d, 0x6e, 0x41, 0xff, 0x0f, 0x94, 0x52, 0xff, 0x0a, 0x87, 0x49, 0xff, 0x12, 0x98, 0x57, 0xff, 0x0f, 0xa6, 0x61, 0xff, 0x19, 0xa8, 0x68, 0xff, 0x23, 0xa0, 0x65, 0xff, 0x29, 0x9b, 0x64, 0xff, 0x29, 0x97, 0x61, 0xff, 0x1d, 0x8e, 0x56, 0xff, 0x13, 0x95, 0x59, 0xff, 0x1a, 0xb7, 0x78, 0xff, 0x08, 0xa6, 0x67, 0xff, 0x0d, 0xa0, 0x62, 0xff, 0x0a, 0x9b, 0x5c, 0xff, 0x08, 0x9e, 0x5d, 0xff, 0x07, 0xa0, 0x5f, 0xff, 0x0c, 0xa2, 0x61, 0xff, 0x12, 0xa3, 0x64, 0xff, 0x15, 0xa3, 0x68, 0xff, 0x15, 0xa4, 0x6a, 0xff, 0x11, 0xa4, 0x68, 0xff, 0x0e, 0xa2, 0x64, 0xff, 0x0f, 0xa5, 0x68, 0xff, 0x13, 0xa9, 0x6f, 0xff, 0x14, 0xa6, 0x71, 0xff, 0x13, 0xa4, 0x71, 0xff, 0x0e, 0xa5, 0x72, 0xff, 0x0c, 0xa4, 0x72, 0xff, 0x0c, 0xa3, 0x71, 0xff, 0x0e, 0xa4, 0x70, 0xff, 0x0f, 0xa4, 0x6e, 0xff, 0x0f, 0xa4, 0x6a, 0xff, 0x10, 0xa4, 0x67, 0xff, 0x0e, 0xa2, 0x64, 0xff, 0x0e, 0xa2, 0x64, 0xff, 0x0d, 0xa5, 0x65, 0xff, 0x03, 0xa3, 0x5b, 0xff, 0x0b, 0xa5, 0x5a, 0xff, 0x0f, 0x9f, 0x55, 0xff, 0x0e, 0x9e, 0x57, 0xff, 0x10, 0x9e, 0x58, 0xff, 0x16, 0xb4, 0x6b, 0xff, 0x0c, 0xc4, 0x6b, 0xff, 0x0c, 0xc9, 0x65, 0xff, 0x04, 0xbd, 0x5b, 0xff, 0x0c, 0xb5, 0x5b, 0xff, 0x08, 0x8d, 0x43, 0xff, 0x02, 0x6e, 0x32, 0xff, 0x05, 0x6b, 0x38, 0xff, 0x02, 0x6d, 0x38, 0xff, 0x15, 0xa5, 0x58, 0xff, 0x07, 0x90, 0x44, 0xff, 0x02, 0x4c, 0x22, 0xff, 0x0d, 0x4c, 0x2b, 0xff, 0x0e, 0x55, 0x2f, 0xff, 0x01, 0x38, 0x19, 0xff, 0x0a, 0x3a, 0x29, 0xff, 0x0d, 0x42, 0x2e, 0xff, 0x02, 0x38, 0x1a, 0xff, 0x1c, 0x67, 0x48, 0xff, 0x06, 0x5b, 0x34, 0xff, 0x12, 0x67, 0x3e, 0xff, 0x01, 0x31, 0x1b, 0xff, 0x01, 0x39, 0x24, 0xff, 0x1c, 0x83, 0x59, 0xff, 0x07, 0x56, 0x2e, 0xff, 0x05, 0x36, 0x22, 0xff, 0x02, 0x4c, 0x30, 0xff, 0x1b, 0x8a, 0x5e, 0xff, 0x0a, 0x72, 0x4e, 0xff, 0x0b, 0x4a, 0x3c, 0xff, 0x0a, 0x50, 0x3c, 0xff, 0x25, 0xa3, 0x6e, 0xff, 0x1c, 0xb8, 0x6e, 0xff, 0x04, 0x6c, 0x34, 0xff, 0x01, 0x51, 0x2e, 0xff, 0x0c, 0xa2, 0x6c, 0xff, 0x0f, 0x9e, 0x68, 0xff, 0x08, 0x6d, 0x47, 0xff, 0x0e, 0x5d, 0x40, 0xff, 0x21, 0x90, 0x69, 0xff, 0x3c, 0xcb, 0x97, 0xff, 0x3c, 0xdb, 0x9c, 0xff, 0x2b, 0xcc, 0x8b, 0xff, 0x1e, 0xa0, 0x69, 0xff, 0x09, 0x77, 0x47, 0xff, 0x0c, 0x7b, 0x4f, 0xff, 0x19, 0x99, 0x68, 0xff, 0x0c, 0xa1, 0x68, 0xff, 0x0a, 0xa4, 0x67, 0xff, 0x0c, 0xa3, 0x64, 0xff, 0x12, 0xa3, 0x68, 0xff, 0x0c, 0xa1, 0x65, 0xff, 0x08, 0x9f, 0x61, 0xff, 0x08, 0xa5, 0x66, 0xff, 0x05, 0xa3, 0x66, 0xff, 0x04, 0xa4, 0x66, 0xff, 0x03, 0xa2, 0x66, 0xff, 0x04, 0xa3, 0x67, 0xff, 0x05, 0xa4, 0x69, 0xff, 0x07, 0xa3, 0x69, 0xff, 0x0e, 0xa0, 0x6a, 0xff, 0x05, 0xa2, 0x6a, 0xff, 0x03, 0xa2, 0x68, 0xff, 0x06, 0xa4, 0x68, 0xff, 0x01, 0xa6, 0x64, 0xff, 0x23, 0x93, 0x74, 0xff, 0x49, 0x47, 0x81, 0xff, 0xb7, 0x56, 0xd8, 0xff, 0xcc, 0x55, 0xe8, 0xff, 0xb2, 0x4c, 0xd2, 0xff, 0xc8, 0x57, 0xdf, 0xff, 0xa9, 0x6e, 0xce, 0xff, 0x40, 0x7d, 0x8d, 0xff, 0x10, 0xb8, 0x6c, 0xff, 0x04, 0xb6, 0x4b, 0xff, 0x0b, 0xb4, 0x55, 0xff, 0x11, 0xa7, 0x57, 0xff, 0x0d, 0x7f, 0x3e, 0xff, 0x06, 0x5a, 0x20, 0xff, 0x01, 0x40, 0x0e, 0xff, 0x00, 0x34, 0x0d, 0xff, 0x00, 0x2d, 0x0f, 0xff, 0x00, 0x2b, 0x11, 0xff, 0x00, 0x2a, 0x0c, 0xff, 0x00, 0x29, 0x0b, 0xff, 0x00, 0x29, 0x0a, 0xff, 0x00, 0x2a, 0x09, 0xff, 0x02, 0x29, 0x0d, 0xff, 0x02, 0x27, 0x10, 0xff, 0x01, 0x2f, 0x11, 0xff, 0x05, 0x3a, 0x14, 0xff, 0x07, 0x35, 0x15, 0xff, 0x05, 0x32, 0x15, 0xff, 0x06, 0x32, 0x16, 0xff, 0x05, 0x2d, 0x0c, 0xff, 0x08, 0x39, 0x10, 0xff, 0x18, 0x60, 0x31, 0xff, 0x35, 0x98, 0x65, 0xff, 0x26, 0x83, 0x4e, 0xff, 0x0e, 0x42, 0x3c, 0xff, 0x24, 0x33, 0x52, 0xff, 0x50, 0x4b, 0x8a, 0xff, 0x1d, 0x3b, 0x41, 0xff, 0x0d, 0x31, 0x1f, 0xff, 0x3e, 0x3a, 0x60, 0xff, 0x79, 0x4a, 0xc2, 0xff, 0x36, 0x2a, 0x6f, 0xff, 0x0b, 0x23, 0x1c, 0xff, 0x07, 0x2e, 0x17, 0xff, 0x14, 0x60, 0x40, 0xff, 0x0c, 0x2d, 0x27, 0xff, 0x4d, 0x3b, 0x75, 0xff, 0x50, 0x3f, 0x89, 0xff, 0x0c, 0x1f, 0x20, 0xff, 0x04, 0x40, 0x1b, 0xff, 0x07, 0x70, 0x28, 0xff, 0x1b, 0x6b, 0x34, 0xff, 0x09, 0x38, 0x1d, 0xff, 0x24, 0x81, 0x59, 0xff, 0x0f, 0x4a, 0x2f, 0xff, 0x4a, 0x57, 0x68, 0xff, 0x51, 0x4a, 0x7d, 0xff, 0x86, 0x63, 0xb4, 0xff, 0x58, 0x49, 0x83, 0xff, 0x13, 0x11, 0x40, 0xff, 0x2f, 0x1b, 0x4d, 0xff, 0x37, 0x18, 0x6b, 0xff, 0x69, 0x47, 0xa8, 0xff, 0x40, 0x2f, 0x67, 0xff, 0x14, 0x1b, 0x1e, 0xff, 0x06, 0x23, 0x11, 0xff, 0x0f, 0x48, 0x24, 0xff, 0x15, 0x68, 0x36, 0xff, 0x16, 0x73, 0x38, 0xff, 0x0a, 0x66, 0x2b, 0xff, 0x03, 0x5c, 0x26, 0xff, 0x01, 0x51, 0x1d, 0xff, 0x04, 0x54, 0x1d, 0xff, 0x05, 0x5d, 0x20, 0xff, 0x07, 0x6a, 0x1f, 0xff, 0x04, 0x7c, 0x25, 0xff, 0x0b, 0x9d, 0x34, 0xff, 0x02, 0x8a, 0x25, 0xff, 0x00, 0x6a, 0x1b, 0xff, 0x04, 0x68, 0x22, 0xff, 0x03, 0x61, 0x1b, 0xff, 0x02, 0x4e, 0x10, 0xff, 0x07, 0x41, 0x1d, 0xff, 0x03, 0x3f, 0x16, 0xff, 0x0d, 0x8f, 0x33, 0xff, 0x22, 0xda, 0x5c, 0xff, 0x07, 0x9b, 0x23, 0xff, 0x05, 0x84, 0x1a, 0xff, 0x02, 0x7b, 0x18, 0xff, 0x01, 0x6d, 0x1b, 0xff, 0x05, 0x6a, 0x12, 0xff, 0x1d, 0x9e, 0x2d, 0xff, 0x08, 0x84, 0x11, 0xff, 0x00, 0x6b, 0x10, 0xff, 0x03, 0x60, 0x19, 0xff, 0x05, 0x63, 0x1a, 0xff, 0x05, 0x51, 0x15, 0xff, 0x04, 0x4e, 0x15, 0xff, 0x02, 0x5c, 0x16, 0xff, 0x01, 0x68, 0x1a, 0xff, 0x0a, 0x78, 0x24, 0xff, 0x05, 0x54, 0x16, 0xff, 0x02, 0x2e, 0x0e, 0xff, 0x01, 0x1f, 0x07, 0xff, 0x65, 0x71, 0x66, 0xff, + 0x08, 0x43, 0x2a, 0xff, 0x06, 0x4f, 0x32, 0xff, 0x03, 0x54, 0x31, 0xff, 0x06, 0x5c, 0x33, 0xff, 0x09, 0x60, 0x34, 0xff, 0x07, 0x61, 0x31, 0xff, 0x05, 0x65, 0x2e, 0xff, 0x02, 0x6a, 0x2f, 0xff, 0x02, 0x6a, 0x35, 0xff, 0x11, 0x7d, 0x50, 0xff, 0x0e, 0x6e, 0x45, 0xff, 0x0f, 0x6a, 0x41, 0xff, 0x08, 0x71, 0x41, 0xff, 0x09, 0x89, 0x4d, 0xff, 0x0c, 0x7e, 0x46, 0xff, 0x08, 0x62, 0x31, 0xff, 0x04, 0x5e, 0x2f, 0xff, 0x08, 0x61, 0x39, 0xff, 0x09, 0x66, 0x3a, 0xff, 0x0a, 0x6f, 0x39, 0xff, 0x05, 0x6d, 0x3a, 0xff, 0x11, 0x7f, 0x54, 0xff, 0x17, 0x88, 0x58, 0xff, 0x0b, 0x6e, 0x3f, 0xff, 0x03, 0x4c, 0x2b, 0xff, 0x01, 0x37, 0x27, 0xff, 0x01, 0x35, 0x25, 0xff, 0x0c, 0x65, 0x44, 0xff, 0x35, 0xcf, 0x9d, 0xff, 0x28, 0xc2, 0x87, 0xff, 0x18, 0x8e, 0x58, 0xff, 0x1e, 0x92, 0x59, 0xff, 0x2f, 0xaa, 0x6e, 0xff, 0x08, 0x50, 0x2e, 0xff, 0x01, 0x3a, 0x22, 0xff, 0x1f, 0xb1, 0x68, 0xff, 0x17, 0xb3, 0x56, 0xff, 0x05, 0x78, 0x2b, 0xff, 0x09, 0x78, 0x2e, 0xff, 0x0d, 0x5e, 0x30, 0xff, 0x03, 0x31, 0x22, 0xff, 0x08, 0x30, 0x27, 0xff, 0x03, 0x33, 0x25, 0xff, 0x03, 0x37, 0x1f, 0xff, 0x03, 0x2f, 0x17, 0xff, 0x01, 0x43, 0x29, 0xff, 0x06, 0x6b, 0x43, 0xff, 0x38, 0xae, 0x8f, 0xff, 0x20, 0x77, 0x7a, 0xff, 0x29, 0x62, 0x7d, 0xff, 0x2e, 0x64, 0x87, 0xff, 0x29, 0x65, 0x82, 0xff, 0x2c, 0x67, 0x86, 0xff, 0x2f, 0x66, 0x98, 0xff, 0x31, 0x66, 0x9a, 0xff, 0x33, 0x63, 0x97, 0xff, 0x24, 0x6e, 0x8d, 0xff, 0x3b, 0x97, 0x96, 0xff, 0x4b, 0xa1, 0x9c, 0xff, 0x17, 0x76, 0x74, 0xff, 0x11, 0x90, 0x77, 0xff, 0x0a, 0xa5, 0x6f, 0xff, 0x0f, 0xa8, 0x6f, 0xff, 0x16, 0x90, 0x60, 0xff, 0x01, 0x61, 0x31, 0xff, 0x09, 0x5c, 0x2c, 0xff, 0x10, 0x61, 0x30, 0xff, 0x10, 0x66, 0x31, 0xff, 0x0d, 0x69, 0x34, 0xff, 0x07, 0x5c, 0x2b, 0xff, 0x05, 0x56, 0x26, 0xff, 0x0a, 0x61, 0x2d, 0xff, 0x0a, 0x66, 0x2e, 0xff, 0x0b, 0x6b, 0x30, 0xff, 0x09, 0x6f, 0x2f, 0xff, 0x06, 0x72, 0x2e, 0xff, 0x08, 0x76, 0x2e, 0xff, 0x08, 0x79, 0x2f, 0xff, 0x08, 0x78, 0x2f, 0xff, 0x06, 0x79, 0x32, 0xff, 0x05, 0x78, 0x32, 0xff, 0x06, 0x7a, 0x31, 0xff, 0x08, 0x7e, 0x34, 0xff, 0x08, 0x80, 0x34, 0xff, 0x08, 0x81, 0x33, 0xff, 0x07, 0x83, 0x33, 0xff, 0x05, 0x82, 0x32, 0xff, 0x06, 0x84, 0x36, 0xff, 0x02, 0x87, 0x33, 0xff, 0x01, 0x91, 0x33, 0xff, 0x03, 0x95, 0x36, 0xff, 0x10, 0x96, 0x41, 0xff, 0x12, 0x83, 0x3c, 0xff, 0x07, 0x51, 0x1d, 0xff, 0x00, 0x33, 0x07, 0xff, 0x0c, 0x52, 0x18, 0xff, 0x2b, 0x7f, 0x47, 0xff, 0x50, 0xad, 0x6c, 0xff, 0x5f, 0xc8, 0x78, 0xff, 0x4a, 0xb8, 0x5d, 0xff, 0x5f, 0xb7, 0x6d, 0xff, 0x0c, 0x54, 0x1f, 0xff, 0x05, 0x66, 0x33, 0xff, 0x09, 0x92, 0x43, 0xff, 0x0d, 0x95, 0x40, 0xff, 0x04, 0x96, 0x3f, 0xff, 0x08, 0x93, 0x48, 0xff, 0x02, 0x5e, 0x2d, 0xff, 0x0b, 0x6d, 0x3e, 0xff, 0x0a, 0x7a, 0x42, 0xff, 0x04, 0x75, 0x3d, 0xff, 0x0c, 0x99, 0x57, 0xff, 0x1d, 0xb0, 0x6b, 0xff, 0x2e, 0xae, 0x70, 0xff, 0x63, 0xd2, 0x9a, 0xff, 0x79, 0xdd, 0xaa, 0xff, 0x82, 0xde, 0xac, 0xff, 0x77, 0xda, 0xa4, 0xff, 0x39, 0xb2, 0x78, 0xff, 0x14, 0xa9, 0x6a, 0xff, 0x0c, 0xa7, 0x68, 0xff, 0x12, 0xad, 0x6c, 0xff, 0x04, 0x9e, 0x5c, 0xff, 0x02, 0x9e, 0x5b, 0xff, 0x06, 0xa1, 0x5f, 0xff, 0x08, 0xa2, 0x61, 0xff, 0x0c, 0xa4, 0x64, 0xff, 0x10, 0xa3, 0x63, 0xff, 0x09, 0x9a, 0x57, 0xff, 0x02, 0x95, 0x51, 0xff, 0x01, 0x95, 0x4f, 0xff, 0x05, 0x9d, 0x56, 0xff, 0x0a, 0xa0, 0x5e, 0xff, 0x0f, 0xa2, 0x66, 0xff, 0x13, 0xa4, 0x6c, 0xff, 0x10, 0xa5, 0x70, 0xff, 0x0b, 0xa3, 0x6e, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x10, 0xa6, 0x71, 0xff, 0x0f, 0xa5, 0x6f, 0xff, 0x0d, 0xa4, 0x6c, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0f, 0xa5, 0x69, 0xff, 0x0e, 0xa4, 0x6a, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0b, 0xa6, 0x65, 0xff, 0x0c, 0xa4, 0x5f, 0xff, 0x13, 0xa0, 0x5e, 0xff, 0x12, 0x98, 0x58, 0xff, 0x08, 0x84, 0x47, 0xff, 0x0d, 0xa0, 0x5e, 0xff, 0x0f, 0xc5, 0x70, 0xff, 0x0e, 0xcc, 0x6b, 0xff, 0x05, 0xc5, 0x60, 0xff, 0x10, 0xbf, 0x61, 0xff, 0x0b, 0x97, 0x4c, 0xff, 0x04, 0x76, 0x3a, 0xff, 0x03, 0x67, 0x37, 0xff, 0x03, 0x67, 0x36, 0xff, 0x16, 0xa0, 0x57, 0xff, 0x07, 0x88, 0x3f, 0xff, 0x02, 0x45, 0x20, 0xff, 0x08, 0x44, 0x26, 0xff, 0x02, 0x3d, 0x1a, 0xff, 0x01, 0x37, 0x1a, 0xff, 0x0b, 0x3a, 0x28, 0xff, 0x0d, 0x43, 0x2d, 0xff, 0x01, 0x36, 0x1a, 0xff, 0x0f, 0x4d, 0x35, 0xff, 0x04, 0x5e, 0x37, 0xff, 0x11, 0x6e, 0x41, 0xff, 0x01, 0x30, 0x1a, 0xff, 0x01, 0x33, 0x22, 0xff, 0x18, 0x75, 0x4f, 0xff, 0x0a, 0x5c, 0x34, 0xff, 0x08, 0x2e, 0x1d, 0xff, 0x07, 0x48, 0x30, 0xff, 0x15, 0x82, 0x5a, 0xff, 0x0d, 0x68, 0x4c, 0xff, 0x11, 0x42, 0x3a, 0xff, 0x05, 0x48, 0x33, 0xff, 0x2c, 0xb2, 0x75, 0xff, 0x13, 0xa8, 0x60, 0xff, 0x01, 0x59, 0x2a, 0xff, 0x01, 0x51, 0x32, 0xff, 0x0e, 0x9f, 0x69, 0xff, 0x08, 0x7d, 0x4f, 0xff, 0x03, 0x48, 0x34, 0xff, 0x04, 0x36, 0x2c, 0xff, 0x0f, 0x63, 0x4c, 0xff, 0x2c, 0xa8, 0x7f, 0xff, 0x20, 0xb1, 0x7a, 0xff, 0x2e, 0xc9, 0x8b, 0xff, 0x28, 0xb1, 0x79, 0xff, 0x15, 0x87, 0x56, 0xff, 0x0b, 0x6f, 0x43, 0xff, 0x0d, 0x82, 0x52, 0xff, 0x0b, 0x9f, 0x67, 0xff, 0x05, 0x9f, 0x63, 0xff, 0x14, 0x9c, 0x61, 0xff, 0x15, 0x8c, 0x56, 0xff, 0x03, 0x7a, 0x41, 0xff, 0x01, 0x82, 0x43, 0xff, 0x05, 0x96, 0x53, 0xff, 0x07, 0x9a, 0x58, 0xff, 0x0d, 0x9f, 0x60, 0xff, 0x12, 0xa1, 0x66, 0xff, 0x11, 0xa2, 0x68, 0xff, 0x05, 0xa2, 0x64, 0xff, 0x03, 0x9a, 0x5f, 0xff, 0x07, 0x92, 0x5d, 0xff, 0x03, 0x9a, 0x62, 0xff, 0x08, 0xa2, 0x6a, 0xff, 0x03, 0xa5, 0x62, 0xff, 0x08, 0xa4, 0x64, 0xff, 0x36, 0x70, 0x7c, 0xff, 0x68, 0x27, 0x95, 0xff, 0xc0, 0x50, 0xde, 0xff, 0xc5, 0x53, 0xdc, 0xff, 0xba, 0x5a, 0xd7, 0xff, 0xbb, 0x4d, 0xd6, 0xff, 0xa7, 0x63, 0xd3, 0xff, 0x62, 0x95, 0xac, 0xff, 0x0b, 0xb4, 0x57, 0xff, 0x0b, 0xbd, 0x4f, 0xff, 0x11, 0x9d, 0x4c, 0xff, 0x0b, 0x6f, 0x37, 0xff, 0x00, 0x3d, 0x15, 0xff, 0x00, 0x33, 0x0d, 0xff, 0x00, 0x37, 0x0e, 0xff, 0x01, 0x39, 0x14, 0xff, 0x03, 0x3d, 0x1f, 0xff, 0x04, 0x44, 0x23, 0xff, 0x06, 0x47, 0x26, 0xff, 0x05, 0x44, 0x23, 0xff, 0x01, 0x37, 0x13, 0xff, 0x01, 0x2e, 0x0a, 0xff, 0x02, 0x25, 0x09, 0xff, 0x07, 0x21, 0x0e, 0xff, 0x07, 0x1f, 0x11, 0xff, 0x02, 0x21, 0x0a, 0xff, 0x04, 0x29, 0x13, 0xff, 0x04, 0x2c, 0x15, 0xff, 0x03, 0x2b, 0x0d, 0xff, 0x03, 0x35, 0x09, 0xff, 0x1c, 0x6e, 0x33, 0xff, 0x19, 0x7e, 0x3f, 0xff, 0x11, 0x71, 0x39, 0xff, 0x12, 0x3f, 0x33, 0xff, 0x5a, 0x50, 0x99, 0xff, 0x68, 0x39, 0xaf, 0xff, 0x69, 0x37, 0xa9, 0xff, 0x1f, 0x29, 0x36, 0xff, 0x08, 0x2a, 0x15, 0xff, 0x3b, 0x3d, 0x55, 0xff, 0x78, 0x59, 0xaf, 0xff, 0x27, 0x2d, 0x4e, 0xff, 0x0f, 0x2d, 0x15, 0xff, 0x08, 0x41, 0x1d, 0xff, 0x0f, 0x93, 0x4d, 0xff, 0x02, 0x56, 0x23, 0xff, 0x0a, 0x24, 0x1a, 0xff, 0x0d, 0x19, 0x1d, 0xff, 0x06, 0x28, 0x13, 0xff, 0x07, 0x5f, 0x27, 0xff, 0x13, 0x8f, 0x42, 0xff, 0x18, 0x63, 0x2e, 0xff, 0x01, 0x21, 0x07, 0xff, 0x20, 0x7d, 0x4a, 0xff, 0x23, 0x4f, 0x45, 0xff, 0x86, 0x68, 0xb3, 0xff, 0x50, 0x32, 0x81, 0xff, 0x55, 0x26, 0x83, 0xff, 0x72, 0x46, 0xa7, 0xff, 0x3e, 0x26, 0x6e, 0xff, 0x11, 0x0d, 0x25, 0xff, 0x1c, 0x18, 0x34, 0xff, 0x2b, 0x27, 0x4d, 0xff, 0x0a, 0x14, 0x1c, 0xff, 0x12, 0x2a, 0x20, 0xff, 0x10, 0x56, 0x29, 0xff, 0x21, 0x9f, 0x52, 0xff, 0x16, 0x9e, 0x4a, 0xff, 0x08, 0x87, 0x33, 0xff, 0x06, 0x7a, 0x2e, 0xff, 0x08, 0x72, 0x2c, 0xff, 0x02, 0x71, 0x29, 0xff, 0x04, 0x7c, 0x2d, 0xff, 0x12, 0x8f, 0x3b, 0xff, 0x1d, 0x97, 0x3e, 0xff, 0x03, 0x78, 0x23, 0xff, 0x0c, 0x9e, 0x35, 0xff, 0x09, 0x97, 0x2b, 0xff, 0x05, 0x72, 0x1e, 0xff, 0x0f, 0x77, 0x2f, 0xff, 0x05, 0x65, 0x1f, 0xff, 0x03, 0x54, 0x17, 0xff, 0x0a, 0x46, 0x20, 0xff, 0x07, 0x3e, 0x1a, 0xff, 0x07, 0x61, 0x19, 0xff, 0x15, 0xa4, 0x3e, 0xff, 0x09, 0x8b, 0x1f, 0xff, 0x0a, 0x82, 0x1b, 0xff, 0x04, 0x85, 0x1d, 0xff, 0x00, 0x7e, 0x1a, 0xff, 0x08, 0x73, 0x1d, 0xff, 0x0b, 0x6f, 0x14, 0xff, 0x1b, 0x9b, 0x2f, 0xff, 0x07, 0x7f, 0x1c, 0xff, 0x05, 0x5e, 0x14, 0xff, 0x0b, 0x60, 0x1c, 0xff, 0x03, 0x4a, 0x14, 0xff, 0x05, 0x4f, 0x19, 0xff, 0x10, 0x71, 0x28, 0xff, 0x07, 0x74, 0x20, 0xff, 0x0e, 0x7b, 0x27, 0xff, 0x04, 0x4d, 0x14, 0xff, 0x02, 0x2b, 0x0f, 0xff, 0x02, 0x20, 0x09, 0xff, 0x63, 0x72, 0x64, 0xff, + 0x07, 0x41, 0x27, 0xff, 0x08, 0x51, 0x33, 0xff, 0x08, 0x58, 0x37, 0xff, 0x04, 0x58, 0x32, 0xff, 0x08, 0x5d, 0x34, 0xff, 0x06, 0x5e, 0x32, 0xff, 0x04, 0x60, 0x2e, 0xff, 0x04, 0x65, 0x2e, 0xff, 0x03, 0x68, 0x34, 0xff, 0x07, 0x75, 0x44, 0xff, 0x14, 0x7c, 0x4e, 0xff, 0x05, 0x65, 0x39, 0xff, 0x06, 0x73, 0x41, 0xff, 0x08, 0x85, 0x4a, 0xff, 0x0c, 0x78, 0x40, 0xff, 0x0d, 0x6c, 0x31, 0xff, 0x14, 0x7d, 0x3a, 0xff, 0x02, 0x5f, 0x2e, 0xff, 0x02, 0x5f, 0x34, 0xff, 0x04, 0x67, 0x35, 0xff, 0x07, 0x6c, 0x39, 0xff, 0x04, 0x6f, 0x40, 0xff, 0x09, 0x7a, 0x46, 0xff, 0x17, 0x85, 0x50, 0xff, 0x17, 0x74, 0x4f, 0xff, 0x05, 0x47, 0x32, 0xff, 0x05, 0x3f, 0x2c, 0xff, 0x2b, 0x8d, 0x6c, 0xff, 0x27, 0xa4, 0x79, 0xff, 0x09, 0x64, 0x3e, 0xff, 0x03, 0x42, 0x22, 0xff, 0x02, 0x41, 0x20, 0xff, 0x06, 0x4f, 0x27, 0xff, 0x02, 0x3b, 0x20, 0xff, 0x02, 0x3c, 0x24, 0xff, 0x2b, 0xbf, 0x76, 0xff, 0x0f, 0xad, 0x4b, 0xff, 0x03, 0x80, 0x2e, 0xff, 0x0d, 0x79, 0x34, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x02, 0x30, 0x21, 0xff, 0x03, 0x32, 0x24, 0xff, 0x00, 0x32, 0x25, 0xff, 0x05, 0x37, 0x1f, 0xff, 0x04, 0x3f, 0x1a, 0xff, 0x03, 0x66, 0x2e, 0xff, 0x1c, 0x98, 0x58, 0xff, 0x1e, 0x80, 0x69, 0xff, 0x1d, 0x61, 0x69, 0xff, 0x2d, 0x6d, 0x7f, 0xff, 0x28, 0x65, 0x7b, 0xff, 0x29, 0x64, 0x79, 0xff, 0x2b, 0x64, 0x81, 0xff, 0x33, 0x65, 0x98, 0xff, 0x31, 0x68, 0x99, 0xff, 0x29, 0x6a, 0x8f, 0xff, 0x2e, 0x8b, 0x94, 0xff, 0x2d, 0x8b, 0x8d, 0xff, 0x2f, 0x77, 0x86, 0xff, 0x1d, 0x66, 0x75, 0xff, 0x0e, 0x73, 0x71, 0xff, 0x1c, 0x9e, 0x7d, 0xff, 0x1a, 0x9a, 0x69, 0xff, 0x0b, 0x68, 0x3e, 0xff, 0x01, 0x51, 0x26, 0xff, 0x0a, 0x5a, 0x2c, 0xff, 0x0e, 0x5f, 0x2f, 0xff, 0x0b, 0x63, 0x31, 0xff, 0x07, 0x62, 0x2e, 0xff, 0x02, 0x56, 0x25, 0xff, 0x08, 0x5a, 0x2a, 0xff, 0x0d, 0x64, 0x2d, 0xff, 0x0d, 0x69, 0x2e, 0xff, 0x0b, 0x6c, 0x2f, 0xff, 0x0a, 0x70, 0x2e, 0xff, 0x0a, 0x73, 0x2e, 0xff, 0x0b, 0x76, 0x30, 0xff, 0x09, 0x77, 0x30, 0xff, 0x06, 0x77, 0x30, 0xff, 0x07, 0x77, 0x32, 0xff, 0x07, 0x78, 0x32, 0xff, 0x07, 0x79, 0x31, 0xff, 0x07, 0x7b, 0x32, 0xff, 0x07, 0x7e, 0x33, 0xff, 0x08, 0x80, 0x32, 0xff, 0x07, 0x81, 0x31, 0xff, 0x06, 0x81, 0x32, 0xff, 0x08, 0x7e, 0x36, 0xff, 0x03, 0x88, 0x36, 0xff, 0x02, 0x91, 0x34, 0xff, 0x0b, 0x91, 0x3b, 0xff, 0x13, 0x78, 0x35, 0xff, 0x07, 0x4f, 0x1d, 0xff, 0x03, 0x34, 0x0a, 0xff, 0x13, 0x50, 0x22, 0xff, 0x2c, 0x84, 0x3f, 0xff, 0x3a, 0x96, 0x55, 0xff, 0x7c, 0xd2, 0x92, 0xff, 0x9b, 0xf8, 0xad, 0xff, 0x64, 0xd4, 0x78, 0xff, 0x59, 0xbe, 0x72, 0xff, 0x17, 0x67, 0x32, 0xff, 0x04, 0x5f, 0x2c, 0xff, 0x05, 0x96, 0x44, 0xff, 0x0e, 0x98, 0x3f, 0xff, 0x04, 0x98, 0x3f, 0xff, 0x04, 0x97, 0x45, 0xff, 0x06, 0x7c, 0x3a, 0xff, 0x08, 0x6f, 0x3a, 0xff, 0x09, 0x6c, 0x3b, 0xff, 0x04, 0x72, 0x3a, 0xff, 0x14, 0x9e, 0x5a, 0xff, 0x14, 0x9d, 0x5b, 0xff, 0x52, 0xc4, 0x89, 0xff, 0x86, 0xea, 0xb4, 0xff, 0x90, 0xef, 0xbd, 0xff, 0x98, 0xf2, 0xc1, 0xff, 0x8f, 0xed, 0xba, 0xff, 0x6d, 0xe0, 0xa8, 0xff, 0x1a, 0xaf, 0x6f, 0xff, 0x13, 0xb5, 0x72, 0xff, 0x0d, 0xb2, 0x6e, 0xff, 0x01, 0xa0, 0x5b, 0xff, 0x01, 0x9b, 0x58, 0xff, 0x0a, 0x9c, 0x5b, 0xff, 0x11, 0x9f, 0x60, 0xff, 0x0e, 0x9c, 0x5e, 0xff, 0x02, 0x91, 0x49, 0xff, 0x02, 0x97, 0x47, 0xff, 0x06, 0xa3, 0x4e, 0xff, 0x07, 0xa5, 0x4f, 0xff, 0x05, 0xa4, 0x4e, 0xff, 0x06, 0xa2, 0x51, 0xff, 0x03, 0x9b, 0x51, 0xff, 0x06, 0x9b, 0x57, 0xff, 0x0e, 0xa4, 0x69, 0xff, 0x0f, 0xa6, 0x70, 0xff, 0x0f, 0xa6, 0x71, 0xff, 0x0f, 0xa5, 0x70, 0xff, 0x0e, 0xa6, 0x70, 0xff, 0x0d, 0xa5, 0x70, 0xff, 0x0d, 0xa6, 0x6f, 0xff, 0x0d, 0xa6, 0x6e, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x16, 0xa7, 0x71, 0xff, 0x12, 0xa5, 0x68, 0xff, 0x0a, 0x9a, 0x59, 0xff, 0x05, 0x8b, 0x4d, 0xff, 0x04, 0x7d, 0x45, 0xff, 0x01, 0x62, 0x2c, 0xff, 0x0c, 0x92, 0x56, 0xff, 0x10, 0xc5, 0x73, 0xff, 0x0b, 0xcd, 0x6c, 0xff, 0x0a, 0xd0, 0x6a, 0xff, 0x0d, 0xc5, 0x64, 0xff, 0x0c, 0x9d, 0x52, 0xff, 0x09, 0x7a, 0x42, 0xff, 0x07, 0x66, 0x39, 0xff, 0x04, 0x62, 0x35, 0xff, 0x15, 0x94, 0x51, 0xff, 0x0c, 0x85, 0x40, 0xff, 0x02, 0x46, 0x21, 0xff, 0x0a, 0x3f, 0x24, 0xff, 0x01, 0x35, 0x1a, 0xff, 0x02, 0x37, 0x1c, 0xff, 0x08, 0x3a, 0x24, 0xff, 0x0a, 0x44, 0x2b, 0xff, 0x02, 0x36, 0x1b, 0xff, 0x05, 0x36, 0x23, 0xff, 0x04, 0x60, 0x38, 0xff, 0x14, 0x76, 0x44, 0xff, 0x02, 0x31, 0x1a, 0xff, 0x01, 0x31, 0x24, 0xff, 0x15, 0x6c, 0x48, 0xff, 0x10, 0x62, 0x39, 0xff, 0x06, 0x2b, 0x1a, 0xff, 0x0e, 0x52, 0x3a, 0xff, 0x15, 0x7f, 0x5b, 0xff, 0x14, 0x60, 0x4d, 0xff, 0x11, 0x3c, 0x38, 0xff, 0x09, 0x55, 0x3b, 0xff, 0x23, 0xaf, 0x6d, 0xff, 0x11, 0x97, 0x53, 0xff, 0x02, 0x4b, 0x25, 0xff, 0x09, 0x5a, 0x3d, 0xff, 0x11, 0x8f, 0x5e, 0xff, 0x08, 0x62, 0x3e, 0xff, 0x05, 0x37, 0x32, 0xff, 0x0c, 0x32, 0x39, 0xff, 0x04, 0x3e, 0x35, 0xff, 0x21, 0x83, 0x65, 0xff, 0x17, 0x9b, 0x6a, 0xff, 0x2b, 0xbd, 0x82, 0xff, 0x28, 0xb7, 0x7d, 0xff, 0x22, 0x9d, 0x68, 0xff, 0x09, 0x6e, 0x3f, 0xff, 0x05, 0x73, 0x42, 0xff, 0x10, 0x96, 0x61, 0xff, 0x0a, 0x91, 0x5a, 0xff, 0x05, 0x6d, 0x39, 0xff, 0x03, 0x5e, 0x2b, 0xff, 0x01, 0x62, 0x27, 0xff, 0x03, 0x77, 0x34, 0xff, 0x0b, 0x93, 0x48, 0xff, 0x0b, 0x96, 0x4c, 0xff, 0x06, 0x8d, 0x4a, 0xff, 0x07, 0x85, 0x49, 0xff, 0x08, 0x8c, 0x52, 0xff, 0x02, 0x95, 0x59, 0xff, 0x06, 0x96, 0x5d, 0xff, 0x0c, 0x97, 0x5d, 0xff, 0x07, 0xa2, 0x63, 0xff, 0x0a, 0xa3, 0x69, 0xff, 0x05, 0xa7, 0x62, 0xff, 0x14, 0x9c, 0x6b, 0xff, 0x49, 0x49, 0x82, 0xff, 0x87, 0x2b, 0xae, 0xff, 0xb2, 0x42, 0xd2, 0xff, 0xb8, 0x4a, 0xd1, 0xff, 0xcb, 0x63, 0xe9, 0xff, 0xba, 0x4f, 0xdc, 0xff, 0x89, 0x5f, 0xc2, 0xff, 0x51, 0x99, 0x9c, 0xff, 0x10, 0xb2, 0x4f, 0xff, 0x15, 0xa1, 0x48, 0xff, 0x08, 0x66, 0x28, 0xff, 0x01, 0x3f, 0x15, 0xff, 0x03, 0x3e, 0x1e, 0xff, 0x06, 0x54, 0x2d, 0xff, 0x08, 0x70, 0x40, 0xff, 0x0d, 0x7c, 0x4b, 0xff, 0x13, 0x84, 0x55, 0xff, 0x14, 0x8e, 0x56, 0xff, 0x14, 0x8f, 0x59, 0xff, 0x16, 0x8c, 0x59, 0xff, 0x14, 0x7f, 0x4e, 0xff, 0x11, 0x6d, 0x3f, 0xff, 0x07, 0x49, 0x23, 0xff, 0x04, 0x2f, 0x14, 0xff, 0x05, 0x1e, 0x0e, 0xff, 0x04, 0x1e, 0x0c, 0xff, 0x01, 0x20, 0x0e, 0xff, 0x01, 0x24, 0x0e, 0xff, 0x01, 0x2a, 0x06, 0xff, 0x13, 0x62, 0x2a, 0xff, 0x17, 0x8a, 0x41, 0xff, 0x08, 0x81, 0x37, 0xff, 0x02, 0x5c, 0x22, 0xff, 0x3a, 0x4b, 0x5b, 0xff, 0x72, 0x4a, 0xb8, 0xff, 0x72, 0x2b, 0xc8, 0xff, 0x62, 0x2d, 0xa5, 0xff, 0x14, 0x20, 0x26, 0xff, 0x05, 0x25, 0x0f, 0xff, 0x1b, 0x2b, 0x30, 0xff, 0x32, 0x37, 0x51, 0xff, 0x13, 0x38, 0x28, 0xff, 0x0f, 0x30, 0x0f, 0xff, 0x0e, 0x5b, 0x2f, 0xff, 0x10, 0xa2, 0x56, 0xff, 0x0b, 0x7a, 0x39, 0xff, 0x11, 0x43, 0x1e, 0xff, 0x0b, 0x24, 0x09, 0xff, 0x06, 0x43, 0x1d, 0xff, 0x16, 0x8b, 0x3d, 0xff, 0x22, 0x8f, 0x4c, 0xff, 0x0a, 0x37, 0x1b, 0xff, 0x06, 0x18, 0x0f, 0xff, 0x17, 0x66, 0x36, 0xff, 0x26, 0x46, 0x46, 0xff, 0x6a, 0x44, 0x94, 0xff, 0x2f, 0x17, 0x53, 0xff, 0x45, 0x1c, 0x6a, 0xff, 0x9e, 0x64, 0xd5, 0xff, 0x70, 0x3c, 0xb1, 0xff, 0x49, 0x2e, 0x77, 0xff, 0x12, 0x11, 0x26, 0xff, 0x25, 0x34, 0x36, 0xff, 0x17, 0x34, 0x28, 0xff, 0x0a, 0x3a, 0x17, 0xff, 0x42, 0xab, 0x65, 0xff, 0x37, 0xdf, 0x7f, 0xff, 0x27, 0xd5, 0x6e, 0xff, 0x0f, 0xad, 0x46, 0xff, 0x04, 0x8c, 0x30, 0xff, 0x26, 0x94, 0x42, 0xff, 0x16, 0x99, 0x44, 0xff, 0x11, 0xa9, 0x4c, 0xff, 0x26, 0xb0, 0x54, 0xff, 0x13, 0x91, 0x34, 0xff, 0x05, 0x74, 0x23, 0xff, 0x0a, 0x8f, 0x2d, 0xff, 0x06, 0x8e, 0x22, 0xff, 0x11, 0x92, 0x2f, 0xff, 0x0d, 0x89, 0x2e, 0xff, 0x0c, 0x7a, 0x28, 0xff, 0x0c, 0x65, 0x25, 0xff, 0x04, 0x46, 0x1a, 0xff, 0x04, 0x3f, 0x18, 0xff, 0x02, 0x4f, 0x14, 0xff, 0x09, 0x7a, 0x24, 0xff, 0x0b, 0x8b, 0x20, 0xff, 0x05, 0x8b, 0x19, 0xff, 0x18, 0xb4, 0x37, 0xff, 0x04, 0x9e, 0x1f, 0xff, 0x0b, 0x89, 0x22, 0xff, 0x06, 0x65, 0x14, 0xff, 0x0a, 0x6b, 0x15, 0xff, 0x1a, 0x8e, 0x2f, 0xff, 0x09, 0x64, 0x16, 0xff, 0x10, 0x5e, 0x1d, 0xff, 0x00, 0x3f, 0x10, 0xff, 0x05, 0x4f, 0x1a, 0xff, 0x0f, 0x73, 0x26, 0xff, 0x08, 0x7a, 0x22, 0xff, 0x0d, 0x78, 0x26, 0xff, 0x02, 0x46, 0x12, 0xff, 0x06, 0x29, 0x13, 0xff, 0x04, 0x22, 0x0c, 0xff, 0x62, 0x75, 0x64, 0xff, + 0x09, 0x44, 0x26, 0xff, 0x05, 0x4f, 0x30, 0xff, 0x08, 0x5a, 0x39, 0xff, 0x05, 0x5a, 0x36, 0xff, 0x05, 0x5b, 0x34, 0xff, 0x03, 0x5c, 0x32, 0xff, 0x01, 0x59, 0x2b, 0xff, 0x06, 0x62, 0x2f, 0xff, 0x02, 0x62, 0x2f, 0xff, 0x04, 0x70, 0x3d, 0xff, 0x15, 0x81, 0x50, 0xff, 0x02, 0x65, 0x36, 0xff, 0x04, 0x76, 0x43, 0xff, 0x07, 0x81, 0x47, 0xff, 0x0d, 0x77, 0x40, 0xff, 0x08, 0x6b, 0x28, 0xff, 0x1b, 0x90, 0x3c, 0xff, 0x0c, 0x78, 0x3c, 0xff, 0x02, 0x5e, 0x35, 0xff, 0x02, 0x61, 0x33, 0xff, 0x06, 0x67, 0x35, 0xff, 0x04, 0x68, 0x37, 0xff, 0x05, 0x6f, 0x37, 0xff, 0x0a, 0x79, 0x3f, 0xff, 0x14, 0x7b, 0x4e, 0xff, 0x14, 0x6b, 0x4d, 0xff, 0x05, 0x44, 0x2b, 0xff, 0x11, 0x5f, 0x41, 0xff, 0x04, 0x51, 0x31, 0xff, 0x01, 0x3a, 0x22, 0xff, 0x07, 0x32, 0x22, 0xff, 0x02, 0x32, 0x21, 0xff, 0x01, 0x35, 0x1b, 0xff, 0x06, 0x3b, 0x22, 0xff, 0x03, 0x3b, 0x22, 0xff, 0x2c, 0xbd, 0x74, 0xff, 0x0b, 0xa2, 0x3b, 0xff, 0x06, 0x88, 0x31, 0xff, 0x1f, 0x83, 0x42, 0xff, 0x06, 0x38, 0x1e, 0xff, 0x02, 0x31, 0x20, 0xff, 0x02, 0x35, 0x21, 0xff, 0x00, 0x35, 0x23, 0xff, 0x08, 0x4a, 0x23, 0xff, 0x05, 0x60, 0x23, 0xff, 0x11, 0x90, 0x49, 0xff, 0x2c, 0xa7, 0x66, 0xff, 0x08, 0x52, 0x46, 0xff, 0x10, 0x4f, 0x53, 0xff, 0x27, 0x6c, 0x71, 0xff, 0x2d, 0x6b, 0x77, 0xff, 0x2f, 0x66, 0x75, 0xff, 0x2a, 0x61, 0x77, 0xff, 0x33, 0x65, 0x90, 0xff, 0x2f, 0x69, 0x91, 0xff, 0x28, 0x7f, 0x8c, 0xff, 0x37, 0xa2, 0x97, 0xff, 0x1f, 0x75, 0x80, 0xff, 0x32, 0x6a, 0x87, 0xff, 0x32, 0x6a, 0x7e, 0xff, 0x09, 0x58, 0x66, 0xff, 0x20, 0x82, 0x79, 0xff, 0x13, 0x76, 0x4e, 0xff, 0x02, 0x4c, 0x27, 0xff, 0x04, 0x4d, 0x26, 0xff, 0x0b, 0x59, 0x2d, 0xff, 0x0b, 0x5e, 0x2d, 0xff, 0x0b, 0x60, 0x2f, 0xff, 0x02, 0x5a, 0x27, 0xff, 0x03, 0x5b, 0x2a, 0xff, 0x08, 0x61, 0x30, 0xff, 0x08, 0x67, 0x2e, 0xff, 0x08, 0x6b, 0x2f, 0xff, 0x07, 0x6e, 0x2f, 0xff, 0x07, 0x70, 0x2f, 0xff, 0x09, 0x73, 0x2f, 0xff, 0x0c, 0x75, 0x31, 0xff, 0x0a, 0x76, 0x32, 0xff, 0x07, 0x76, 0x31, 0xff, 0x08, 0x76, 0x32, 0xff, 0x08, 0x77, 0x32, 0xff, 0x08, 0x78, 0x32, 0xff, 0x06, 0x79, 0x30, 0xff, 0x07, 0x7d, 0x31, 0xff, 0x07, 0x7f, 0x31, 0xff, 0x07, 0x81, 0x31, 0xff, 0x07, 0x81, 0x31, 0xff, 0x08, 0x7f, 0x35, 0xff, 0x06, 0x88, 0x36, 0xff, 0x0b, 0x8f, 0x3a, 0xff, 0x0d, 0x7d, 0x36, 0xff, 0x04, 0x45, 0x1a, 0xff, 0x01, 0x2c, 0x0c, 0xff, 0x0d, 0x46, 0x1c, 0xff, 0x44, 0x95, 0x5a, 0xff, 0x3e, 0x9f, 0x54, 0xff, 0x29, 0x8a, 0x47, 0xff, 0x5b, 0xb0, 0x73, 0xff, 0x94, 0xee, 0xa5, 0xff, 0x74, 0xe4, 0x8e, 0xff, 0x5e, 0xcd, 0x80, 0xff, 0x24, 0x7d, 0x45, 0xff, 0x04, 0x59, 0x25, 0xff, 0x05, 0x98, 0x46, 0xff, 0x0d, 0x9b, 0x41, 0xff, 0x03, 0x9c, 0x41, 0xff, 0x03, 0x98, 0x42, 0xff, 0x05, 0x8d, 0x3d, 0xff, 0x02, 0x70, 0x32, 0xff, 0x09, 0x6a, 0x39, 0xff, 0x09, 0x7a, 0x3d, 0xff, 0x14, 0x93, 0x50, 0xff, 0x11, 0x8d, 0x4c, 0xff, 0x68, 0xd2, 0x98, 0xff, 0x89, 0xe9, 0xb4, 0xff, 0x8a, 0xed, 0xba, 0xff, 0x86, 0xe5, 0xb4, 0xff, 0x75, 0xd3, 0xa1, 0xff, 0x70, 0xdd, 0xa7, 0xff, 0x45, 0xd3, 0x94, 0xff, 0x1b, 0xbd, 0x7a, 0xff, 0x0d, 0xba, 0x74, 0xff, 0x01, 0xa6, 0x60, 0xff, 0x03, 0x9e, 0x5a, 0xff, 0x10, 0xa2, 0x61, 0xff, 0x10, 0x9b, 0x5d, 0xff, 0x08, 0x95, 0x57, 0xff, 0x06, 0xa0, 0x4e, 0xff, 0x07, 0xa8, 0x4c, 0xff, 0x08, 0xad, 0x4b, 0xff, 0x08, 0xae, 0x4a, 0xff, 0x07, 0xad, 0x49, 0xff, 0x08, 0xab, 0x4c, 0xff, 0x06, 0xa4, 0x4e, 0xff, 0x03, 0x9c, 0x4e, 0xff, 0x07, 0x9e, 0x5e, 0xff, 0x0c, 0xa3, 0x6b, 0xff, 0x0f, 0xa6, 0x6f, 0xff, 0x0e, 0xa5, 0x70, 0xff, 0x0c, 0xa4, 0x70, 0xff, 0x0d, 0xa5, 0x71, 0xff, 0x0c, 0xa6, 0x71, 0xff, 0x0c, 0xa7, 0x71, 0xff, 0x0e, 0xa7, 0x74, 0xff, 0x18, 0xa5, 0x72, 0xff, 0x0e, 0x98, 0x5e, 0xff, 0x08, 0x90, 0x53, 0xff, 0x07, 0x8b, 0x50, 0xff, 0x04, 0x75, 0x40, 0xff, 0x00, 0x56, 0x25, 0xff, 0x0e, 0x8c, 0x55, 0xff, 0x0f, 0xc4, 0x75, 0xff, 0x08, 0xcf, 0x6f, 0xff, 0x0b, 0xd7, 0x70, 0xff, 0x0a, 0xc8, 0x66, 0xff, 0x09, 0x9c, 0x51, 0xff, 0x09, 0x78, 0x42, 0xff, 0x0a, 0x63, 0x3a, 0xff, 0x04, 0x5c, 0x33, 0xff, 0x10, 0x86, 0x47, 0xff, 0x0f, 0x82, 0x40, 0xff, 0x04, 0x46, 0x20, 0xff, 0x0e, 0x3e, 0x24, 0xff, 0x01, 0x33, 0x1b, 0xff, 0x04, 0x37, 0x1c, 0xff, 0x06, 0x3b, 0x20, 0xff, 0x07, 0x46, 0x2a, 0xff, 0x07, 0x39, 0x20, 0xff, 0x04, 0x2c, 0x1d, 0xff, 0x03, 0x5d, 0x35, 0xff, 0x15, 0x7b, 0x47, 0xff, 0x03, 0x34, 0x1c, 0xff, 0x02, 0x2d, 0x22, 0xff, 0x0b, 0x5d, 0x3b, 0xff, 0x11, 0x63, 0x38, 0xff, 0x01, 0x29, 0x18, 0xff, 0x0b, 0x56, 0x3b, 0xff, 0x18, 0x7e, 0x5d, 0xff, 0x1e, 0x5d, 0x50, 0xff, 0x11, 0x3b, 0x38, 0xff, 0x0b, 0x61, 0x40, 0xff, 0x1d, 0xad, 0x66, 0xff, 0x0e, 0x88, 0x47, 0xff, 0x04, 0x41, 0x22, 0xff, 0x12, 0x5e, 0x44, 0xff, 0x12, 0x7d, 0x50, 0xff, 0x13, 0x5c, 0x3e, 0xff, 0x0e, 0x37, 0x3d, 0xff, 0x0e, 0x2d, 0x40, 0xff, 0x05, 0x32, 0x34, 0xff, 0x0f, 0x5c, 0x48, 0xff, 0x19, 0x94, 0x68, 0xff, 0x1e, 0xac, 0x72, 0xff, 0x26, 0xb9, 0x7e, 0xff, 0x27, 0xaa, 0x73, 0xff, 0x07, 0x71, 0x3f, 0xff, 0x0a, 0x74, 0x44, 0xff, 0x17, 0x8a, 0x58, 0xff, 0x0a, 0x75, 0x44, 0xff, 0x03, 0x55, 0x26, 0xff, 0x03, 0x57, 0x24, 0xff, 0x03, 0x68, 0x29, 0xff, 0x09, 0x80, 0x37, 0xff, 0x0a, 0x95, 0x41, 0xff, 0x07, 0x96, 0x43, 0xff, 0x06, 0x90, 0x47, 0xff, 0x01, 0x7c, 0x3c, 0xff, 0x01, 0x7f, 0x47, 0xff, 0x04, 0x92, 0x59, 0xff, 0x0f, 0x9b, 0x62, 0xff, 0x12, 0x9f, 0x60, 0xff, 0x05, 0xa4, 0x5d, 0xff, 0x08, 0xa1, 0x65, 0xff, 0x08, 0xa9, 0x62, 0xff, 0x19, 0x8d, 0x6b, 0xff, 0x72, 0x45, 0xa0, 0xff, 0xa5, 0x3f, 0xc7, 0xff, 0xac, 0x3a, 0xcf, 0xff, 0xb8, 0x48, 0xd7, 0xff, 0xc0, 0x50, 0xe0, 0xff, 0xb3, 0x48, 0xd8, 0xff, 0x7b, 0x71, 0xbb, 0xff, 0x39, 0x9b, 0x87, 0xff, 0x15, 0xa2, 0x49, 0xff, 0x0e, 0x71, 0x33, 0xff, 0x01, 0x47, 0x18, 0xff, 0x03, 0x4f, 0x26, 0xff, 0x10, 0x71, 0x47, 0xff, 0x14, 0x8c, 0x5b, 0xff, 0x10, 0x9d, 0x63, 0xff, 0x10, 0xa2, 0x66, 0xff, 0x10, 0xa3, 0x65, 0xff, 0x0e, 0xa5, 0x64, 0xff, 0x0a, 0xa4, 0x65, 0xff, 0x0e, 0xa4, 0x67, 0xff, 0x15, 0xa1, 0x67, 0xff, 0x19, 0x9b, 0x66, 0xff, 0x16, 0x88, 0x58, 0xff, 0x0e, 0x65, 0x3d, 0xff, 0x01, 0x2f, 0x14, 0xff, 0x01, 0x21, 0x0c, 0xff, 0x05, 0x1e, 0x0e, 0xff, 0x03, 0x1f, 0x08, 0xff, 0x06, 0x41, 0x14, 0xff, 0x1e, 0x8d, 0x49, 0xff, 0x0b, 0x96, 0x42, 0xff, 0x07, 0x89, 0x38, 0xff, 0x08, 0x63, 0x2a, 0xff, 0x4f, 0x5d, 0x6f, 0xff, 0x86, 0x5b, 0xc5, 0xff, 0x7c, 0x35, 0xd1, 0xff, 0x54, 0x2a, 0x94, 0xff, 0x0c, 0x1c, 0x23, 0xff, 0x23, 0x38, 0x34, 0xff, 0x26, 0x35, 0x3a, 0xff, 0x0d, 0x34, 0x21, 0xff, 0x15, 0x5a, 0x27, 0xff, 0x1e, 0x41, 0x1f, 0xff, 0x27, 0x7a, 0x4f, 0xff, 0x2b, 0xac, 0x6b, 0xff, 0x1b, 0x85, 0x48, 0xff, 0x0d, 0x41, 0x1b, 0xff, 0x12, 0x30, 0x10, 0xff, 0x0d, 0x6c, 0x36, 0xff, 0x2d, 0xb3, 0x5d, 0xff, 0x19, 0x69, 0x3a, 0xff, 0x1f, 0x2d, 0x35, 0xff, 0x22, 0x23, 0x38, 0xff, 0x12, 0x4d, 0x2e, 0xff, 0x12, 0x33, 0x2d, 0xff, 0x2f, 0x21, 0x4f, 0xff, 0x26, 0x1a, 0x40, 0xff, 0x77, 0x57, 0x96, 0xff, 0xa6, 0x71, 0xdd, 0xff, 0x75, 0x33, 0xbf, 0xff, 0x80, 0x50, 0xbe, 0xff, 0x4a, 0x44, 0x62, 0xff, 0x5f, 0x77, 0x6c, 0xff, 0x49, 0x6b, 0x5b, 0xff, 0x3b, 0x83, 0x51, 0xff, 0x78, 0xe4, 0xa1, 0xff, 0x49, 0xea, 0x98, 0xff, 0x46, 0xeb, 0x8f, 0xff, 0x1a, 0xb7, 0x54, 0xff, 0x07, 0x93, 0x36, 0xff, 0x44, 0xb3, 0x61, 0xff, 0x3c, 0xc5, 0x72, 0xff, 0x2a, 0xc4, 0x6d, 0xff, 0x4e, 0xcc, 0x7a, 0xff, 0x0e, 0x83, 0x2a, 0xff, 0x0d, 0x78, 0x2b, 0xff, 0x02, 0x77, 0x20, 0xff, 0x03, 0x86, 0x21, 0xff, 0x0c, 0xa2, 0x2e, 0xff, 0x05, 0x9e, 0x26, 0xff, 0x16, 0x97, 0x33, 0xff, 0x1a, 0x74, 0x2f, 0xff, 0x01, 0x46, 0x16, 0xff, 0x02, 0x44, 0x18, 0xff, 0x01, 0x44, 0x0f, 0xff, 0x03, 0x64, 0x17, 0xff, 0x05, 0x8c, 0x1d, 0xff, 0x04, 0xa5, 0x23, 0xff, 0x1a, 0xcf, 0x3c, 0xff, 0x06, 0xb4, 0x20, 0xff, 0x09, 0x94, 0x20, 0xff, 0x08, 0x70, 0x1b, 0xff, 0x02, 0x4e, 0x07, 0xff, 0x15, 0x6f, 0x1f, 0xff, 0x1a, 0x79, 0x2a, 0xff, 0x0d, 0x5b, 0x1d, 0xff, 0x00, 0x38, 0x0e, 0xff, 0x04, 0x4b, 0x14, 0xff, 0x0f, 0x75, 0x25, 0xff, 0x08, 0x7d, 0x21, 0xff, 0x08, 0x70, 0x1f, 0xff, 0x02, 0x3e, 0x0f, 0xff, 0x09, 0x28, 0x16, 0xff, 0x07, 0x23, 0x0e, 0xff, 0x62, 0x75, 0x66, 0xff, +}; + +const lv_image_dsc_t grassland = { + .header.cf = LV_COLOR_FORMAT_ARGB8888, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.w = 320, + .header.h = 240, + .data_size = 76800 * 4, + .data = grassland_map, +}; diff --git a/Whackmole/pic/grassland.h b/Whackmole/pic/grassland.h new file mode 100644 index 0000000000000000000000000000000000000000..6236c7fe17031376acbdf18508c0f8eaec0cf809 --- /dev/null +++ b/Whackmole/pic/grassland.h @@ -0,0 +1,17 @@ +#ifndef GRASSLAND_H +#define GRASSLAND_H + +#include "lvgl.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +extern const lv_img_dsc_t grassland; + +#ifdef __cplusplus +} +#endif + +#endif /* MOLE_IMG_H */ diff --git a/Whackmole/pic/hammer_image.c b/Whackmole/pic/hammer_image.c new file mode 100644 index 0000000000000000000000000000000000000000..eb8dc2e5993acc60ad596c97b3c42aff8ce0cb75 --- /dev/null +++ b/Whackmole/pic/hammer_image.c @@ -0,0 +1,82 @@ +#ifdef __has_include + #if __has_include("lvgl.h") + #ifndef LV_LVGL_H_INCLUDE_SIMPLE + #define LV_LVGL_H_INCLUDE_SIMPLE + #endif + #endif +#endif + +#if defined(LV_LVGL_H_INCLUDE_SIMPLE) + #include "lvgl.h" +#else + #include "lvgl/lvgl.h" +#endif + + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMAGE_HAMMER +#define LV_ATTRIBUTE_IMAGE_HAMMER +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_HAMMER uint8_t hammer_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x0c, 0x36, 0x36, 0x36, 0x21, 0x3c, 0x48, 0x53, 0x2e, 0x41, 0x50, 0x5f, 0x33, 0x38, 0x3f, 0x46, 0x24, 0x33, 0x33, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x3c, 0x4e, 0x58, 0x37, 0x54, 0x79, 0x95, 0x9d, 0x65, 0x9d, 0xc2, 0xe0, 0x6c, 0xa9, 0xd3, 0xf5, 0x6b, 0xa9, 0xd5, 0xfe, 0x6c, 0xab, 0xd8, 0xff, 0x8a, 0xb5, 0xd4, 0xf8, 0x5f, 0x87, 0xa4, 0xc2, 0x43, 0x56, 0x65, 0x44, 0xff, 0xff, 0xff, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x06, 0x4a, 0x63, 0x74, 0x67, 0x63, 0x99, 0xbe, 0xf1, 0x76, 0xbd, 0xee, 0xff, 0x6e, 0xb9, 0xef, 0xff, 0x5e, 0xad, 0xea, 0xff, 0x55, 0xa6, 0xe7, 0xff, 0x51, 0xa4, 0xe7, 0xff, 0x55, 0xa5, 0xe6, 0xff, 0x66, 0xb2, 0xec, 0xff, 0x60, 0x95, 0xba, 0xe7, 0x3e, 0x4f, 0x5d, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x05, 0x4b, 0x67, 0x7a, 0x94, 0x82, 0xb8, 0xde, 0xff, 0x75, 0xbd, 0xef, 0xff, 0x5d, 0xad, 0xeb, 0xff, 0x45, 0x9b, 0xe4, 0xff, 0x45, 0x9a, 0xe2, 0xff, 0x44, 0x99, 0xe0, 0xff, 0x3d, 0x9e, 0xd8, 0xff, 0x45, 0x9a, 0xe2, 0xff, 0x48, 0x9c, 0xe3, 0xff, 0x6f, 0xb9, 0xed, 0xff, 0x61, 0x95, 0xb9, 0xed, 0x32, 0x3d, 0x3d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x3c, 0x4b, 0x58, 0x7f, 0xa6, 0xc6, 0xf8, 0xde, 0xef, 0xfb, 0xff, 0x61, 0xae, 0xeb, 0xff, 0x45, 0x9c, 0xe5, 0xff, 0x44, 0x98, 0xe1, 0xff, 0x45, 0x99, 0xe2, 0xff, 0x43, 0x96, 0xd3, 0xff, 0x05, 0xf7, 0xf8, 0xff, 0x29, 0xb8, 0xd6, 0xff, 0x43, 0x94, 0xd1, 0xff, 0x61, 0xaa, 0xd9, 0xff, 0x72, 0xba, 0xe9, 0xff, 0x4f, 0x6e, 0x85, 0xb4, 0x33, 0x33, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x57, 0x7d, 0xce, 0x5d, 0x9b, 0xd0, 0xff, 0x82, 0xc4, 0xf1, 0xff, 0x57, 0xa9, 0xea, 0xff, 0x45, 0x9a, 0xe3, 0xff, 0x45, 0x99, 0xe2, 0xff, 0x45, 0x9b, 0xe2, 0xff, 0x3b, 0x9b, 0xcc, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x08, 0xf4, 0xf5, 0xff, 0x5b, 0xba, 0xde, 0xff, 0x72, 0xb5, 0xe3, 0xfe, 0x48, 0x5f, 0x71, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x36, 0x2a, 0x37, 0x66, 0x9b, 0xfd, 0x45, 0x7f, 0xb9, 0xff, 0x73, 0xba, 0xec, 0xff, 0x69, 0xb4, 0xec, 0xff, 0x46, 0x9c, 0xe4, 0xff, 0x44, 0x97, 0xdf, 0xff, 0x33, 0xac, 0xd7, 0xff, 0x0c, 0xe7, 0xeb, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x0d, 0xf1, 0xf4, 0xff, 0x63, 0xb2, 0xd9, 0xff, 0x77, 0xbf, 0xf1, 0xff, 0x5e, 0x8e, 0xae, 0xe5, 0x37, 0x37, 0x37, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x44, 0x58, 0x8a, 0x38, 0x6f, 0xac, 0xff, 0x39, 0x70, 0xad, 0xff, 0x5a, 0x99, 0xd0, 0xff, 0x75, 0xbd, 0xef, 0xff, 0x55, 0xa6, 0xe7, 0xff, 0x44, 0x98, 0xe0, 0xff, 0x42, 0x98, 0xda, 0xff, 0x35, 0xa4, 0xd4, 0xff, 0x23, 0xc0, 0xdb, 0xff, 0x02, 0xfd, 0xfd, 0xff, 0x01, 0xff, 0xff, 0xff, 0x02, 0xfd, 0xfd, 0xff, 0x2c, 0xd0, 0xdf, 0xff, 0x76, 0xbe, 0xf0, 0xff, 0x78, 0xc0, 0xf0, 0xff, 0x4c, 0x66, 0x76, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x0f, 0x40, 0x65, 0x8a, 0xe3, 0x52, 0x8f, 0xc7, 0xff, 0x3b, 0x72, 0xae, 0xff, 0x3b, 0x73, 0xaf, 0xff, 0x6e, 0xb3, 0xe6, 0xff, 0x71, 0xb9, 0xed, 0xff, 0x48, 0x9d, 0xe4, 0xff, 0x44, 0x97, 0xdf, 0xff, 0x44, 0x99, 0xe1, 0xff, 0x3e, 0xa1, 0xdd, 0xff, 0x05, 0xf5, 0xf5, 0xff, 0x11, 0xe2, 0xec, 0xff, 0x34, 0xc9, 0xde, 0xff, 0x3d, 0xc6, 0xdb, 0xff, 0x73, 0xba, 0xec, 0xff, 0x86, 0xc7, 0xf3, 0xff, 0x97, 0xa4, 0xac, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3f, 0x4c, 0x3c, 0x51, 0x88, 0xb9, 0xfe, 0x67, 0xaa, 0xde, 0xff, 0x59, 0x98, 0xcf, 0xff, 0x3f, 0x77, 0xb3, 0xff, 0x4c, 0x89, 0xc2, 0xff, 0x74, 0xbc, 0xed, 0xff, 0x60, 0xae, 0xea, 0xff, 0x45, 0x9a, 0xe2, 0xff, 0x44, 0x97, 0xde, 0xff, 0x43, 0x9a, 0xdd, 0xff, 0x26, 0xb8, 0xd2, 0xff, 0x48, 0x9c, 0xd8, 0xff, 0x70, 0xb8, 0xec, 0xff, 0x75, 0xbd, 0xee, 0xff, 0x74, 0xbb, 0xed, 0xff, 0x78, 0xc0, 0xf1, 0xff, 0x5a, 0x79, 0x8e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x51, 0x6b, 0x87, 0x60, 0xa1, 0xd7, 0xff, 0x66, 0xaa, 0xdf, 0xff, 0x70, 0xb8, 0xe9, 0xff, 0x69, 0xae, 0xe1, 0xff, 0x4c, 0x89, 0xc2, 0xff, 0x4b, 0x87, 0xc0, 0xff, 0x74, 0xbc, 0xee, 0xff, 0x5b, 0xaa, 0xe9, 0xff, 0x45, 0x9c, 0xe5, 0xff, 0x45, 0x9b, 0xe3, 0xff, 0x45, 0x9b, 0xe4, 0xff, 0x5c, 0xab, 0xe9, 0xff, 0x74, 0xbb, 0xed, 0xff, 0x75, 0xbd, 0xee, 0xff, 0x76, 0xbf, 0xf0, 0xff, 0x58, 0x89, 0xaf, 0xf3, 0x30, 0x36, 0x3c, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x55, 0x72, 0xad, 0x61, 0xa3, 0xd9, 0xff, 0x69, 0xae, 0xe2, 0xff, 0x71, 0xb9, 0xea, 0xff, 0x68, 0xad, 0xe0, 0xff, 0x55, 0x93, 0xcb, 0xff, 0x3a, 0x71, 0xae, 0xff, 0x5a, 0x9a, 0xd1, 0xff, 0x74, 0xbb, 0xee, 0xff, 0x69, 0xb2, 0xeb, 0xff, 0x48, 0x9e, 0xe5, 0xff, 0x4b, 0xa0, 0xe6, 0xff, 0x6f, 0xb9, 0xed, 0xff, 0x76, 0xbf, 0xf0, 0xff, 0x73, 0xba, 0xec, 0xff, 0x52, 0x87, 0xb4, 0xf8, 0x39, 0x48, 0x5b, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x4d, 0x69, 0x94, 0x5c, 0x9c, 0xd2, 0xff, 0x68, 0xac, 0xe0, 0xff, 0x6b, 0xb0, 0xe4, 0xff, 0x67, 0xab, 0xdf, 0xff, 0x64, 0xa7, 0xdc, 0xff, 0x4c, 0x88, 0xc1, 0xff, 0x3a, 0x72, 0xae, 0xff, 0x74, 0xab, 0xda, 0xff, 0xd6, 0xeb, 0xfa, 0xff, 0x72, 0xba, 0xef, 0xff, 0x70, 0xbb, 0xf0, 0xff, 0x72, 0xb8, 0xeb, 0xff, 0x61, 0xa2, 0xd7, 0xff, 0x44, 0x77, 0xaa, 0xfe, 0x33, 0x44, 0x55, 0x78, 0x55, 0x55, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x3f, 0x4e, 0x44, 0x4a, 0x7e, 0xaf, 0xfc, 0x65, 0xa8, 0xdd, 0xff, 0x62, 0xa4, 0xda, 0xff, 0x5d, 0x9e, 0xd4, 0xff, 0x3e, 0x75, 0xb1, 0xff, 0x38, 0x6d, 0xaa, 0xff, 0x38, 0x6e, 0xab, 0xff, 0x5e, 0xa0, 0xd5, 0xff, 0x76, 0xbb, 0xec, 0xff, 0x4c, 0x87, 0xbf, 0xff, 0x3b, 0x6f, 0xa6, 0xff, 0x32, 0x67, 0x9f, 0xff, 0x32, 0x5b, 0x8a, 0xf2, 0x33, 0x42, 0x55, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x05, 0x36, 0x4f, 0x66, 0xae, 0x63, 0xa5, 0xda, 0xff, 0x60, 0xa2, 0xd8, 0xff, 0x40, 0x78, 0xb4, 0xff, 0x38, 0x6d, 0xab, 0xff, 0x38, 0x6d, 0xa9, 0xff, 0x41, 0x79, 0xb4, 0xff, 0x6a, 0xae, 0xe2, 0xff, 0x45, 0x7e, 0xb8, 0xff, 0x36, 0x62, 0x94, 0xff, 0x4f, 0xa2, 0xe5, 0xff, 0x46, 0x9f, 0xe9, 0xff, 0x39, 0x7d, 0xb9, 0xe4, 0x1c, 0x33, 0x55, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x1a, 0x4d, 0x7a, 0xa2, 0xec, 0x5f, 0xa0, 0xd6, 0xff, 0x3c, 0x73, 0xaf, 0xff, 0x38, 0x6d, 0xa9, 0xff, 0x38, 0x6e, 0xaa, 0xff, 0x5a, 0x99, 0xd0, 0xff, 0x49, 0x84, 0xbd, 0xff, 0x33, 0x63, 0x9b, 0xff, 0x37, 0x6b, 0xa6, 0xff, 0x59, 0x9f, 0xd8, 0xff, 0x4b, 0xa3, 0xea, 0xff, 0x46, 0x9e, 0xe8, 0xff, 0x38, 0x7b, 0xb8, 0xd3, 0x24, 0x24, 0x48, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x4a, 0x5b, 0x59, 0x4a, 0x7a, 0xa3, 0xe8, 0x3a, 0x70, 0xab, 0xff, 0x38, 0x6e, 0xaa, 0xff, 0x49, 0x84, 0xbd, 0xff, 0x4f, 0x8b, 0xc4, 0xff, 0x38, 0x6b, 0xa5, 0xff, 0x35, 0x5c, 0x87, 0xe3, 0x2e, 0x54, 0x87, 0xcf, 0x3d, 0x75, 0xb0, 0xff, 0x5c, 0xaa, 0xe6, 0xff, 0x48, 0x9f, 0xe7, 0xff, 0x45, 0x9c, 0xe5, 0xff, 0x30, 0x66, 0x9b, 0xa4, 0x2e, 0x45, 0x5c, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x40, 0x4f, 0x47, 0x34, 0x55, 0x7a, 0xd1, 0x4c, 0x84, 0xba, 0xff, 0x6d, 0xb3, 0xe6, 0xff, 0x37, 0x62, 0x91, 0xf7, 0x35, 0x4f, 0x6d, 0xa3, 0x34, 0x34, 0x39, 0x2c, 0x25, 0x3a, 0x64, 0x30, 0x33, 0x63, 0x9c, 0xf0, 0x4e, 0x8c, 0xc5, 0xff, 0x57, 0xa9, 0xe8, 0xff, 0x45, 0x9c, 0xe5, 0xff, 0x43, 0x98, 0xe0, 0xfe, 0x2b, 0x58, 0x89, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x33, 0x37, 0x3b, 0x3c, 0x3c, 0x48, 0x51, 0x55, 0x30, 0x30, 0x30, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x3d, 0x66, 0x64, 0x36, 0x6a, 0xa5, 0xfd, 0x56, 0x99, 0xd1, 0xff, 0x55, 0xa8, 0xea, 0xff, 0x45, 0x9c, 0xe4, 0xff, 0x43, 0x96, 0xdd, 0xff, 0x28, 0x4f, 0x7c, 0x64, 0xff, 0xff, 0xff, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x02, 0x2c, 0x54, 0x87, 0xa8, 0x3f, 0x75, 0xaf, 0xff, 0x79, 0xb5, 0xe5, 0xff, 0x50, 0xa2, 0xe7, 0xff, 0x45, 0x9a, 0xe3, 0xff, 0x3d, 0x88, 0xca, 0xef, 0x28, 0x4c, 0x78, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x32, 0x5b, 0x19, 0x32, 0x5e, 0x92, 0xcb, 0x4e, 0x83, 0xb9, 0xff, 0x68, 0xb6, 0xef, 0xff, 0x46, 0x9c, 0xe4, 0xff, 0x45, 0x9b, 0xe4, 0xff, 0x3b, 0x80, 0xbf, 0xdc, 0x21, 0x3c, 0x63, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x49, 0x76, 0x45, 0x33, 0x64, 0x9c, 0xed, 0x58, 0x9a, 0xd1, 0xff, 0x58, 0xac, 0xec, 0xff, 0x45, 0x9b, 0xe4, 0xff, 0x44, 0x9a, 0xe2, 0xff, 0x36, 0x77, 0xb2, 0xc5, 0x17, 0x2e, 0x45, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x02, 0x29, 0x4c, 0x7a, 0x75, 0x3a, 0x70, 0xac, 0xff, 0x65, 0xad, 0xe3, 0xff, 0x4f, 0xa4, 0xe8, 0xff, 0x45, 0x9b, 0xe4, 0xff, 0x44, 0x99, 0xe2, 0xff, 0x2b, 0x5b, 0x8c, 0x8e, 0x3f, 0x3f, 0x3f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x2c, 0x51, 0x82, 0xbe, 0x3e, 0x75, 0xb0, 0xff, 0x6a, 0xb6, 0xec, 0xff, 0x50, 0xa4, 0xe8, 0xff, 0x47, 0x9c, 0xe4, 0xff, 0x48, 0x9b, 0xe1, 0xfe, 0x2c, 0x57, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x34, 0x57, 0x1d, 0x31, 0x60, 0x96, 0xe3, 0x4d, 0x8b, 0xc3, 0xff, 0x79, 0xbf, 0xf0, 0xff, 0x66, 0xa8, 0xdf, 0xff, 0x3b, 0x73, 0xb3, 0xff, 0x25, 0x4a, 0x7e, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x38, 0x5f, 0x48, 0x3d, 0x70, 0xa7, 0xf9, 0x5f, 0x97, 0xcc, 0xff, 0x34, 0x60, 0xa1, 0xff, 0x27, 0x51, 0x90, 0xf6, 0x20, 0x38, 0x65, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x57, 0x86, 0x89, 0x2d, 0x59, 0x95, 0xe9, 0x24, 0x4b, 0x85, 0xcd, 0x1e, 0x39, 0x67, 0x54, 0x55, 0x55, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x18, 0x24, 0x3c, 0x15, 0x2a, 0x2a, 0x55, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t hammer_image = { + .header.cf = LV_COLOR_FORMAT_ARGB8888, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.w = 48, + .header.h = 48, + .data_size = 2304 * 4, + .data = hammer_map, +}; diff --git a/Whackmole/pic/hammer_image.h b/Whackmole/pic/hammer_image.h new file mode 100644 index 0000000000000000000000000000000000000000..7fc10c84a6cadbf06360d011110642d14ac22ffd --- /dev/null +++ b/Whackmole/pic/hammer_image.h @@ -0,0 +1,15 @@ +#ifndef HAMMER_H +#define HAMMER_H + +#include "lvgl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_img_dsc_t hammer_image; + +#ifdef __cplusplus +#endif + +#endif /* HAMMER_IMG_H */ diff --git a/Whackmole/pic/hammer_img.h b/Whackmole/pic/hammer_img.h new file mode 100644 index 0000000000000000000000000000000000000000..8247cd9a67f0ad55a01fdf87dcb81cd0c693c20e --- /dev/null +++ b/Whackmole/pic/hammer_img.h @@ -0,0 +1,16 @@ +#ifndef HAMMER_IMG_H +#define HAMMER_IMG_H + +#include "lvgl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_img_dsc_t hammer_img; + +#ifdef __cplusplus +} +#endif + +#endif /* HAMMER_IMG_H */ diff --git a/Whackmole/pic/icons/grassland.png b/Whackmole/pic/icons/grassland.png new file mode 100644 index 0000000000000000000000000000000000000000..bd460576b29f3d116cdf047d85b41a3d47b6940a Binary files /dev/null and b/Whackmole/pic/icons/grassland.png differ diff --git a/Whackmole/pic/icons/hammer.png b/Whackmole/pic/icons/hammer.png new file mode 100644 index 0000000000000000000000000000000000000000..6eca66c53e71fb8af46c1a9e739cf212850d9fdc Binary files /dev/null and b/Whackmole/pic/icons/hammer.png differ diff --git a/Whackmole/pic/icons/mole.png b/Whackmole/pic/icons/mole.png new file mode 100644 index 0000000000000000000000000000000000000000..4e61cbf4bef4e97213bc808c1304f913016aca90 Binary files /dev/null and b/Whackmole/pic/icons/mole.png differ diff --git a/Whackmole/pic/mole_image.c b/Whackmole/pic/mole_image.c new file mode 100644 index 0000000000000000000000000000000000000000..9b7106ad343e0b77f982963bd797f9d278b47390 --- /dev/null +++ b/Whackmole/pic/mole_image.c @@ -0,0 +1,82 @@ +#ifdef __has_include + #if __has_include("lvgl.h") + #ifndef LV_LVGL_H_INCLUDE_SIMPLE + #define LV_LVGL_H_INCLUDE_SIMPLE + #endif + #endif +#endif + +#if defined(LV_LVGL_H_INCLUDE_SIMPLE) + #include "lvgl.h" +#else + #include "lvgl/lvgl.h" +#endif + + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMAGE_MOLE +#define LV_ATTRIBUTE_IMAGE_MOLE +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMAGE_MOLE uint8_t mole_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x24, 0x64, 0x4f, 0x4f, 0x71, 0xc4, 0x1a, 0x19, 0x3b, 0xb0, 0x00, 0x00, 0x09, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x20, 0x35, 0x60, 0x80, 0x8c, 0xb0, 0xff, 0x83, 0x91, 0xbb, 0xff, 0x5e, 0x66, 0x95, 0xff, 0x4a, 0x4d, 0x77, 0xff, 0x07, 0x07, 0x20, 0x69, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x1d, 0x35, 0x60, 0x5f, 0x61, 0x75, 0x8b, 0x00, 0x00, 0x1a, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x45, 0x6c, 0xd6, 0x76, 0x7e, 0xaa, 0xff, 0x20, 0x27, 0x54, 0xff, 0x53, 0x56, 0x88, 0xff, 0x2b, 0x26, 0x60, 0xff, 0x20, 0x18, 0x4a, 0xff, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x3e, 0x5e, 0x4b, 0x49, 0x5d, 0x84, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x23, 0x60, 0x6d, 0x43, 0x35, 0x7e, 0xff, 0x60, 0x67, 0x90, 0xff, 0x77, 0x7f, 0x95, 0xee, 0x37, 0x37, 0x30, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x47, 0x11, 0x11, 0x3b, 0xb0, 0x25, 0x28, 0x5b, 0xff, 0x2e, 0x38, 0x63, 0xff, 0x45, 0x51, 0x7b, 0xff, 0x50, 0x5b, 0x86, 0xff, 0x5e, 0x67, 0x95, 0xff, 0x56, 0x5c, 0x8e, 0xff, 0x48, 0x49, 0x71, 0xf4, 0x26, 0x25, 0x40, 0xba, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x02, 0x56, 0x5a, 0x60, 0x85, 0x93, 0x9c, 0xb3, 0xff, 0x4d, 0x4a, 0x7f, 0xff, 0x30, 0x23, 0x5d, 0xe9, 0x00, 0x00, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x57, 0x43, 0x99, 0xd4, 0x92, 0x71, 0xf6, 0xff, 0x3c, 0x2d, 0x90, 0xff, 0x78, 0x81, 0x9e, 0xff, 0x5c, 0x5c, 0x7a, 0xc3, 0x0d, 0x0b, 0x34, 0xb7, 0x3a, 0x41, 0x6d, 0xff, 0x58, 0x6e, 0x99, 0xff, 0x72, 0x92, 0xb7, 0xff, 0x86, 0xa9, 0xc4, 0xff, 0x8e, 0xb1, 0xcc, 0xff, 0x90, 0xb2, 0xcd, 0xff, 0x8d, 0xb2, 0xcd, 0xff, 0x89, 0xb2, 0xce, 0xff, 0x9a, 0xb5, 0xd3, 0xff, 0xa6, 0xaf, 0xcd, 0xff, 0x7a, 0x77, 0x95, 0xff, 0x17, 0x12, 0x30, 0xcf, 0x6a, 0x71, 0x86, 0xfe, 0x56, 0x5b, 0x8f, 0xff, 0x74, 0x57, 0xbd, 0xff, 0xb6, 0x9c, 0xf5, 0xff, 0x38, 0x2f, 0x58, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x57, 0x42, 0x9e, 0xe5, 0x8e, 0x6e, 0xef, 0xff, 0x74, 0x5e, 0xcb, 0xff, 0x2c, 0x2a, 0x64, 0xff, 0x2b, 0x2f, 0x64, 0xff, 0x4c, 0x62, 0x8e, 0xff, 0x6c, 0x89, 0xab, 0xff, 0x85, 0xa7, 0xc1, 0xff, 0x89, 0xae, 0xc5, 0xff, 0x88, 0xa7, 0xc6, 0xff, 0x86, 0xa5, 0xc5, 0xff, 0x86, 0xa4, 0xc4, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x86, 0xa7, 0xc1, 0xff, 0x84, 0xa7, 0xc0, 0xff, 0x85, 0xa8, 0xc3, 0xff, 0x9f, 0xbf, 0xd7, 0xff, 0xa4, 0xac, 0xc3, 0xff, 0x25, 0x23, 0x55, 0xff, 0x33, 0x2a, 0x7a, 0xff, 0xb1, 0x92, 0xf6, 0xff, 0xc8, 0xab, 0xff, 0xff, 0x43, 0x39, 0x67, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x31, 0x82, 0xc4, 0x82, 0x64, 0xdb, 0xff, 0x3b, 0x2b, 0x7f, 0xff, 0x1f, 0x20, 0x5d, 0xff, 0x55, 0x6b, 0x8c, 0xff, 0x68, 0x8a, 0xa1, 0xff, 0x92, 0xb2, 0xcd, 0xff, 0x93, 0xb2, 0xd2, 0xff, 0x89, 0xa7, 0xc7, 0xff, 0x84, 0xa5, 0xc1, 0xff, 0x85, 0xa7, 0xc2, 0xff, 0x85, 0xa7, 0xc2, 0xff, 0x85, 0xa6, 0xc3, 0xff, 0x84, 0xa5, 0xc4, 0xff, 0x8d, 0xad, 0xcb, 0xff, 0x93, 0xb3, 0xd0, 0xff, 0x8b, 0xad, 0xc9, 0xff, 0x9f, 0xb7, 0xcd, 0xff, 0xae, 0xaf, 0xc6, 0xff, 0x25, 0x1c, 0x50, 0xff, 0x5f, 0x49, 0xa7, 0xff, 0x99, 0x80, 0xd8, 0xff, 0x20, 0x19, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0d, 0x3d, 0x3b, 0x4a, 0x33, 0x88, 0xdd, 0x21, 0x18, 0x59, 0xff, 0x4a, 0x64, 0x86, 0xff, 0x62, 0x82, 0xa0, 0xff, 0x88, 0xa1, 0xc0, 0xff, 0x62, 0x78, 0x95, 0xff, 0x5a, 0x70, 0x96, 0xff, 0x81, 0x96, 0xb9, 0xff, 0x8a, 0xa9, 0xc7, 0xff, 0x85, 0xa5, 0xc3, 0xff, 0x85, 0xa5, 0xc3, 0xff, 0x86, 0xa6, 0xc5, 0xff, 0x8b, 0xa8, 0xc6, 0xff, 0x6e, 0x82, 0xa3, 0xff, 0x58, 0x65, 0x87, 0xff, 0x5f, 0x6f, 0x91, 0xff, 0x81, 0xa0, 0xbd, 0xff, 0xa9, 0xc5, 0xd9, 0xff, 0x87, 0x87, 0x9c, 0xff, 0x26, 0x15, 0x63, 0xfd, 0x38, 0x2c, 0x6f, 0xbe, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x39, 0x3f, 0x6d, 0xff, 0x5c, 0x77, 0x9c, 0xff, 0x7b, 0x99, 0xbc, 0xff, 0x89, 0xa2, 0xc1, 0xff, 0x6d, 0x80, 0xa0, 0xff, 0x72, 0x77, 0xa4, 0xff, 0x40, 0x4c, 0x71, 0xff, 0x74, 0x91, 0xb0, 0xff, 0x89, 0xa9, 0xc8, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x8d, 0xac, 0xca, 0xff, 0x6e, 0x81, 0xa1, 0xff, 0x56, 0x60, 0x85, 0xff, 0x71, 0x7e, 0xa4, 0xff, 0x5a, 0x70, 0x92, 0xff, 0x7f, 0x9e, 0xc0, 0xff, 0x85, 0xa5, 0xc0, 0xff, 0xc2, 0xcc, 0xdc, 0xff, 0x36, 0x2f, 0x54, 0xea, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0c, 0x3d, 0x92, 0x52, 0x63, 0x94, 0xff, 0x62, 0x80, 0x9d, 0xff, 0x8a, 0xa7, 0xc5, 0xff, 0x84, 0xac, 0xc6, 0xff, 0x87, 0xa7, 0xc9, 0xff, 0x5e, 0x5f, 0x94, 0xff, 0x81, 0x97, 0xbd, 0xff, 0x83, 0xa3, 0xc1, 0xff, 0x86, 0xa6, 0xc5, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x85, 0xa6, 0xc3, 0xff, 0x89, 0xab, 0xc2, 0xff, 0x81, 0x93, 0xb5, 0xff, 0x7e, 0x94, 0xb5, 0xff, 0x91, 0xb4, 0xcf, 0xff, 0x87, 0xa6, 0xc6, 0xff, 0x83, 0xa1, 0xc0, 0xff, 0xad, 0xc7, 0xd9, 0xff, 0x84, 0x83, 0x97, 0xfe, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x25, 0x28, 0x58, 0xde, 0x57, 0x75, 0x94, 0xff, 0x6f, 0x91, 0xa3, 0xff, 0x8d, 0xa8, 0xca, 0xff, 0x8c, 0xb2, 0xcb, 0xff, 0x64, 0x7b, 0xa2, 0xff, 0x00, 0x00, 0x2b, 0xff, 0x73, 0x85, 0xab, 0xff, 0x8d, 0xae, 0xcc, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x85, 0xa5, 0xc3, 0xff, 0x95, 0xb1, 0xd2, 0xff, 0x3a, 0x3e, 0x70, 0xff, 0x22, 0x22, 0x55, 0xff, 0x92, 0xaa, 0xcd, 0xff, 0x89, 0xa7, 0xc1, 0xff, 0x86, 0xa4, 0xc5, 0xff, 0x8e, 0xb0, 0xcb, 0xff, 0xb2, 0xb6, 0xcb, 0xff, 0x10, 0x07, 0x2d, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x31, 0x36, 0x3b, 0x68, 0xfe, 0x5b, 0x7b, 0x98, 0xff, 0x7c, 0x9a, 0xb9, 0xff, 0x86, 0xaa, 0xc4, 0xff, 0x8f, 0xb4, 0xcf, 0xff, 0x55, 0x58, 0x8a, 0xff, 0x08, 0x00, 0x37, 0xff, 0x79, 0x8b, 0xaf, 0xff, 0x8c, 0xac, 0xca, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x93, 0xb4, 0xd1, 0xff, 0x45, 0x4e, 0x7e, 0xff, 0x0e, 0x01, 0x3e, 0xff, 0x7e, 0x97, 0xba, 0xff, 0x8a, 0xab, 0xc5, 0xff, 0x87, 0xa5, 0xc6, 0xff, 0x83, 0xa5, 0xbf, 0xff, 0xbb, 0xca, 0xda, 0xff, 0x34, 0x2e, 0x51, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x51, 0x43, 0x4c, 0x78, 0xff, 0x5b, 0x7d, 0x9a, 0xff, 0x81, 0x9f, 0xc1, 0xff, 0x84, 0xa8, 0xc3, 0xff, 0x91, 0xb3, 0xcf, 0xff, 0x42, 0x44, 0x77, 0xff, 0x0d, 0x00, 0x3d, 0xff, 0x7e, 0x93, 0xb6, 0xff, 0x8a, 0xab, 0xc8, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x86, 0xa5, 0xc4, 0xff, 0x86, 0xa5, 0xc3, 0xff, 0x92, 0xb4, 0xd0, 0xff, 0x51, 0x5a, 0x89, 0xff, 0x06, 0x00, 0x34, 0xff, 0x6f, 0x86, 0xa9, 0xff, 0x8c, 0xae, 0xc8, 0xff, 0x87, 0xa5, 0xc6, 0xff, 0x82, 0xa4, 0xbe, 0xff, 0xc2, 0xd3, 0xe1, 0xff, 0x4e, 0x49, 0x69, 0xdf, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x5d, 0x47, 0x57, 0x81, 0xff, 0x57, 0x7e, 0x99, 0xff, 0x80, 0x9f, 0xc2, 0xff, 0x85, 0xa6, 0xc4, 0xff, 0x93, 0xb2, 0xcd, 0xff, 0x3a, 0x3a, 0x6d, 0xff, 0x0f, 0x02, 0x41, 0xff, 0x7e, 0x95, 0xb8, 0xff, 0x88, 0xa9, 0xc7, 0xff, 0x87, 0xa8, 0xc6, 0xff, 0x8b, 0xab, 0xca, 0xff, 0x89, 0xa9, 0xc7, 0xff, 0x90, 0xb3, 0xcf, 0xff, 0x55, 0x5d, 0x8c, 0xff, 0x06, 0x00, 0x31, 0xff, 0x67, 0x7a, 0x9e, 0xff, 0x8e, 0xb0, 0xca, 0xff, 0x87, 0xa5, 0xc4, 0xff, 0x81, 0xa3, 0xbd, 0xff, 0xc3, 0xd3, 0xe3, 0xff, 0x5d, 0x58, 0x77, 0xf0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x2d, 0x66, 0x48, 0x5a, 0x81, 0xff, 0x54, 0x7d, 0x95, 0xff, 0x7f, 0x9e, 0xc0, 0xff, 0x86, 0xa8, 0xc7, 0xff, 0x8f, 0xaf, 0xcc, 0xff, 0x2b, 0x2e, 0x5f, 0xff, 0x0d, 0x05, 0x3f, 0xff, 0x83, 0x9d, 0xbe, 0xff, 0x92, 0xb2, 0xd0, 0xff, 0x81, 0x9c, 0xbd, 0xff, 0x70, 0x8a, 0xaa, 0xff, 0x7e, 0x99, 0xba, 0xff, 0x98, 0xb8, 0xd5, 0xff, 0x52, 0x5b, 0x8b, 0xff, 0x00, 0x00, 0x24, 0xff, 0x66, 0x78, 0x9b, 0xff, 0x91, 0xb5, 0xcc, 0xff, 0x89, 0xaa, 0xc3, 0xff, 0x80, 0xa2, 0xba, 0xff, 0xc4, 0xd4, 0xe4, 0xff, 0x66, 0x62, 0x7d, 0xf6, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2b, 0x64, 0x49, 0x58, 0x82, 0xff, 0x56, 0x79, 0x94, 0xff, 0x7e, 0x99, 0xc2, 0xff, 0x8c, 0xaa, 0xd6, 0xff, 0x93, 0xb0, 0xd8, 0xff, 0x78, 0x86, 0xb4, 0xff, 0x68, 0x77, 0xa0, 0xff, 0x91, 0xb0, 0xd0, 0xff, 0x65, 0x78, 0x9c, 0xff, 0x25, 0x23, 0x51, 0xff, 0x44, 0x4b, 0x7c, 0xff, 0x40, 0x45, 0x76, 0xff, 0x79, 0x90, 0xb2, 0xff, 0x7e, 0x94, 0xbb, 0xff, 0x58, 0x61, 0x8c, 0xff, 0x86, 0x9d, 0xc1, 0xff, 0x7c, 0x97, 0xb7, 0xff, 0x7d, 0x97, 0xbb, 0xff, 0x82, 0x9e, 0xc4, 0xff, 0xca, 0xda, 0xe8, 0xff, 0x6c, 0x68, 0x80, 0xfa, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x58, 0x44, 0x51, 0x7d, 0xff, 0x5a, 0x7a, 0x9b, 0xff, 0x54, 0x62, 0x96, 0xff, 0x57, 0x5e, 0x99, 0xff, 0x64, 0x6a, 0x9f, 0xff, 0x7b, 0x8a, 0xbb, 0xff, 0x94, 0xad, 0xd4, 0xff, 0x8e, 0xa9, 0xc8, 0xff, 0x24, 0x2f, 0x56, 0xff, 0x23, 0x1e, 0x4e, 0xff, 0x41, 0x40, 0x72, 0xff, 0x19, 0x1b, 0x49, 0xff, 0x6a, 0x7f, 0xa4, 0xff, 0x99, 0xb3, 0xcd, 0xff, 0x82, 0x8c, 0xaf, 0xff, 0x5d, 0x68, 0x9a, 0xff, 0x64, 0x68, 0x9e, 0xff, 0x73, 0x7a, 0xc4, 0xff, 0x7e, 0x91, 0xcf, 0xff, 0xd2, 0xdf, 0xef, 0xff, 0x6d, 0x69, 0x81, 0xfc, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x2d, 0x39, 0x45, 0x69, 0xfe, 0x59, 0x7e, 0x93, 0xff, 0x61, 0x76, 0x9b, 0xff, 0x74, 0x7a, 0xa7, 0xff, 0x64, 0x67, 0x9a, 0xff, 0x46, 0x48, 0x7a, 0xff, 0x58, 0x67, 0x8f, 0xff, 0x90, 0xae, 0xcb, 0xff, 0x55, 0x6a, 0x8d, 0xff, 0x20, 0x27, 0x54, 0xff, 0x1d, 0x1c, 0x49, 0xff, 0x47, 0x57, 0x7b, 0xff, 0x90, 0xaa, 0xc9, 0xff, 0x5c, 0x6f, 0x8a, 0xff, 0x58, 0x5d, 0x82, 0xff, 0x72, 0x79, 0xab, 0xff, 0x7f, 0x85, 0xb5, 0xff, 0x88, 0x97, 0xd0, 0xff, 0x81, 0x9b, 0xc6, 0xff, 0xdb, 0xe8, 0xf0, 0xff, 0x5b, 0x54, 0x74, 0xf3, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x0a, 0x07, 0x04, 0x2f, 0x8e, 0x37, 0x42, 0x6d, 0xfe, 0x54, 0x79, 0x93, 0xff, 0x51, 0x6c, 0x8e, 0xff, 0x6d, 0x7d, 0xa1, 0xff, 0x51, 0x5d, 0x82, 0xff, 0x33, 0x31, 0x5b, 0xff, 0x6e, 0x7b, 0xa0, 0xff, 0x92, 0xb7, 0xd3, 0xff, 0x97, 0xb8, 0xd7, 0xff, 0x61, 0x76, 0x9e, 0xff, 0x41, 0x46, 0x6e, 0xff, 0x87, 0xa1, 0xc2, 0xff, 0x97, 0xb7, 0xcf, 0xff, 0x73, 0x85, 0xa9, 0xff, 0x45, 0x45, 0x70, 0xff, 0x42, 0x49, 0x73, 0xff, 0x74, 0x88, 0xa8, 0xff, 0x74, 0x96, 0xb0, 0xff, 0x8a, 0xa9, 0xc1, 0xff, 0xdf, 0xe8, 0xf0, 0xff, 0x55, 0x4e, 0x6f, 0xf7, 0x00, 0x00, 0x08, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x2a, 0x6c, 0x40, 0x4c, 0x7d, 0xff, 0x5c, 0x78, 0x98, 0xff, 0x6b, 0x89, 0xa8, 0xff, 0x67, 0x7c, 0xa0, 0xff, 0x5d, 0x67, 0x8e, 0xff, 0x6e, 0x79, 0xa0, 0xff, 0x3e, 0x48, 0x72, 0xff, 0x5c, 0x69, 0x94, 0xff, 0x59, 0x67, 0x92, 0xff, 0x42, 0x4b, 0x6d, 0xff, 0x6f, 0x6a, 0x86, 0xff, 0x8c, 0x82, 0x9a, 0xff, 0x74, 0x71, 0x91, 0xff, 0x3c, 0x44, 0x70, 0xff, 0x55, 0x5a, 0x8a, 0xff, 0x30, 0x31, 0x63, 0xff, 0x40, 0x42, 0x73, 0xff, 0x6d, 0x79, 0xa2, 0xff, 0x85, 0xa4, 0xc2, 0xff, 0x81, 0xa0, 0xc0, 0xff, 0xa2, 0xb9, 0xcb, 0xff, 0xcb, 0xd0, 0xd7, 0xff, 0x85, 0x81, 0x99, 0xff, 0x00, 0x00, 0x0f, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1f, 0x51, 0x3c, 0x43, 0x72, 0xfa, 0x59, 0x72, 0x97, 0xff, 0x7c, 0x96, 0xb9, 0xff, 0x76, 0x8e, 0xb2, 0xff, 0x8a, 0xa3, 0xc5, 0xff, 0x8f, 0xb4, 0xd0, 0xff, 0x79, 0x97, 0xb5, 0xff, 0x5c, 0x6f, 0x91, 0xff, 0x64, 0x73, 0x98, 0xff, 0x5e, 0x6b, 0x8e, 0xff, 0x79, 0x7f, 0x9b, 0xff, 0x7c, 0x81, 0x97, 0xff, 0x7d, 0x86, 0x9c, 0xff, 0x6e, 0x80, 0x9e, 0xff, 0x6a, 0x7f, 0x9b, 0xff, 0x7a, 0x95, 0xac, 0xff, 0xa2, 0xbc, 0xd5, 0xff, 0x74, 0x86, 0x9f, 0xff, 0x95, 0xaa, 0xbc, 0xff, 0xb2, 0xc6, 0xda, 0xff, 0xaf, 0xc3, 0xcc, 0xff, 0xda, 0xe1, 0xe5, 0xff, 0xa9, 0xa5, 0xbc, 0xff, 0x02, 0x02, 0x11, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x0f, 0x13, 0x4b, 0xd2, 0x1b, 0x34, 0x70, 0xff, 0x26, 0x39, 0x70, 0xff, 0x31, 0x3c, 0x70, 0xff, 0x29, 0x32, 0x61, 0xff, 0x36, 0x39, 0x67, 0xff, 0x3a, 0x3e, 0x6e, 0xff, 0x38, 0x42, 0x74, 0xff, 0x37, 0x45, 0x75, 0xff, 0x3f, 0x4b, 0x78, 0xff, 0x41, 0x48, 0x77, 0xff, 0x4d, 0x51, 0x7e, 0xff, 0x66, 0x70, 0x97, 0xff, 0x66, 0x7b, 0x9c, 0xff, 0x5e, 0x6d, 0x8d, 0xff, 0x65, 0x69, 0x88, 0xff, 0x5e, 0x5f, 0x7f, 0xff, 0x6b, 0x6c, 0x89, 0xff, 0x6a, 0x65, 0x84, 0xff, 0x61, 0x62, 0x8a, 0xff, 0x60, 0x71, 0x92, 0xff, 0x48, 0x49, 0x67, 0xfa, 0x16, 0x06, 0x1d, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e, 0x2f, 0x36, 0x1b, 0x3a, 0x70, 0xd9, 0x22, 0x5e, 0xa8, 0xff, 0x1f, 0x59, 0xa1, 0xff, 0x18, 0x37, 0x79, 0xff, 0x12, 0x1a, 0x58, 0xff, 0x22, 0x24, 0x5d, 0xff, 0x52, 0x6a, 0x8d, 0xff, 0x50, 0x69, 0x8b, 0xff, 0x64, 0x7a, 0x9f, 0xff, 0x74, 0x85, 0xac, 0xff, 0x60, 0x6c, 0x96, 0xff, 0x44, 0x4c, 0x7a, 0xff, 0x38, 0x3e, 0x6f, 0xff, 0x3a, 0x41, 0x6e, 0xff, 0x59, 0x68, 0x8c, 0xff, 0x67, 0x7a, 0xa2, 0xff, 0x5a, 0x6f, 0x9a, 0xff, 0x5d, 0x73, 0x9b, 0xff, 0x8d, 0x9a, 0xb7, 0xff, 0x4e, 0x48, 0x6e, 0xff, 0x01, 0x0e, 0x45, 0xff, 0x1b, 0x3d, 0x73, 0xff, 0x31, 0x52, 0x7a, 0xfa, 0x17, 0x23, 0x4b, 0x98, 0x30, 0x45, 0x73, 0x64, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x2e, 0x63, 0xcb, 0x1f, 0x6b, 0xb7, 0xff, 0x1d, 0x4c, 0x97, 0xff, 0x14, 0x1a, 0x5b, 0xff, 0x0d, 0x15, 0x4c, 0xff, 0x0b, 0x12, 0x42, 0xff, 0x2f, 0x36, 0x65, 0xff, 0x60, 0x81, 0x9e, 0xff, 0x7b, 0xa7, 0xbc, 0xff, 0x95, 0xb7, 0xd0, 0xff, 0x61, 0x6f, 0x94, 0xff, 0x51, 0x5e, 0x8a, 0xff, 0x6f, 0x7f, 0xa7, 0xff, 0x89, 0x9b, 0xbe, 0xff, 0x8a, 0x9a, 0xb4, 0xff, 0x58, 0x63, 0x7e, 0xff, 0x69, 0x7c, 0xa0, 0xff, 0x97, 0xb7, 0xd8, 0xff, 0x80, 0xae, 0xc5, 0xff, 0xb4, 0xd0, 0xe0, 0xff, 0x88, 0x7f, 0x9d, 0xff, 0x00, 0x0c, 0x41, 0xff, 0x09, 0x18, 0x50, 0xff, 0x1e, 0x32, 0x66, 0xff, 0x30, 0x57, 0x8e, 0xff, 0x38, 0x5e, 0x9a, 0xff, 0x42, 0x71, 0x9b, 0xea, 0x12, 0x16, 0x2c, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1e, 0x5e, 0x14, 0x39, 0x7f, 0xff, 0x21, 0x79, 0xc5, 0xff, 0x12, 0x23, 0x61, 0xff, 0x1a, 0x1f, 0x52, 0xff, 0x4d, 0x5e, 0x87, 0xff, 0x6e, 0x7f, 0xa3, 0xff, 0x4d, 0x59, 0x7e, 0xff, 0x48, 0x54, 0x76, 0xff, 0x98, 0xac, 0xd0, 0xff, 0x57, 0x65, 0x8c, 0xff, 0x63, 0x72, 0x9d, 0xff, 0x9b, 0xbb, 0xe2, 0xff, 0xb9, 0xda, 0xfe, 0xff, 0xc5, 0xe8, 0xff, 0xff, 0xcb, 0xed, 0xff, 0xff, 0xcd, 0xe0, 0xf6, 0xff, 0x66, 0x67, 0x80, 0xff, 0x63, 0x72, 0x8e, 0xff, 0x91, 0xb5, 0xd3, 0xff, 0x70, 0x7d, 0x9c, 0xff, 0x50, 0x58, 0x78, 0xff, 0x40, 0x4b, 0x74, 0xff, 0x3f, 0x43, 0x6b, 0xff, 0x08, 0x0a, 0x42, 0xff, 0x21, 0x5e, 0x9e, 0xff, 0x1c, 0x53, 0x8e, 0xff, 0x33, 0x60, 0x9a, 0xff, 0x33, 0x4e, 0x79, 0xd0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x0f, 0x3b, 0x7a, 0x16, 0x17, 0x4f, 0xfb, 0x22, 0x4f, 0x9a, 0xff, 0x1b, 0x89, 0xce, 0xff, 0x1a, 0x4b, 0x86, 0xff, 0x41, 0x54, 0x7b, 0xff, 0x76, 0x9b, 0xb7, 0xff, 0x90, 0xb7, 0xd1, 0xff, 0x99, 0xb6, 0xd5, 0xff, 0x80, 0x89, 0xa5, 0xff, 0x4a, 0x4e, 0x74, 0xff, 0x5e, 0x6b, 0x99, 0xff, 0x9e, 0xb9, 0xe6, 0xff, 0xb1, 0xce, 0xf0, 0xff, 0xc3, 0xdf, 0xff, 0xff, 0xbe, 0xdb, 0xfd, 0xff, 0xbc, 0xda, 0xfd, 0xff, 0xc5, 0xe2, 0xfe, 0xff, 0xdf, 0xe5, 0xf5, 0xff, 0x58, 0x5d, 0x75, 0xff, 0x58, 0x66, 0x8f, 0xff, 0x37, 0x47, 0x6b, 0xff, 0x7b, 0x98, 0xb5, 0xff, 0x98, 0xb3, 0xd5, 0xff, 0xaf, 0xbe, 0xd1, 0xff, 0x5a, 0x59, 0x81, 0xff, 0x14, 0x56, 0x99, 0xff, 0x31, 0x81, 0xaa, 0xff, 0x0f, 0x36, 0x69, 0xff, 0x2e, 0x56, 0x87, 0xff, 0x00, 0x00, 0x0d, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x28, 0x40, 0x1e, 0x1e, 0x4a, 0xb9, 0x17, 0x1c, 0x5a, 0xff, 0x19, 0x50, 0x93, 0xff, 0x1b, 0x47, 0x8b, 0xff, 0x14, 0x69, 0xa8, 0xff, 0x21, 0x5e, 0x9c, 0xff, 0x41, 0x4b, 0x72, 0xff, 0x64, 0x86, 0xa2, 0xff, 0x79, 0xa0, 0xbf, 0xff, 0x9b, 0xb3, 0xce, 0xff, 0xb4, 0xbc, 0xd1, 0xff, 0x2a, 0x2a, 0x53, 0xff, 0x91, 0xa3, 0xd2, 0xff, 0xa6, 0xcc, 0xf1, 0xff, 0xce, 0xee, 0xff, 0xff, 0xcd, 0xec, 0xff, 0xff, 0xcd, 0xec, 0xff, 0xff, 0xca, 0xec, 0xff, 0xff, 0xc9, 0xec, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0x9a, 0x94, 0xad, 0xff, 0x26, 0x1c, 0x4d, 0xff, 0x59, 0x76, 0x96, 0xff, 0x70, 0x9c, 0xb2, 0xff, 0x88, 0xae, 0xcd, 0xff, 0x9f, 0xc2, 0xd2, 0xff, 0x67, 0x72, 0x8d, 0xff, 0x0d, 0x3a, 0x7c, 0xff, 0x30, 0x87, 0xb3, 0xff, 0x10, 0x32, 0x5a, 0xff, 0x2c, 0x57, 0x87, 0xff, 0x17, 0x1b, 0x4a, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x25, 0x0d, 0x13, 0x3d, 0x76, 0x16, 0x22, 0x4b, 0xc8, 0x1e, 0x32, 0x5d, 0xff, 0x1b, 0x26, 0x60, 0xff, 0x1c, 0x45, 0x85, 0xff, 0x0d, 0x68, 0xad, 0xff, 0x1a, 0x74, 0xbb, 0xff, 0x11, 0x53, 0x92, 0xff, 0x3f, 0x59, 0x8a, 0xff, 0x60, 0x53, 0x77, 0xff, 0x2f, 0x39, 0x64, 0xff, 0x5e, 0x6f, 0x93, 0xff, 0xa4, 0xb0, 0xb9, 0xff, 0x6d, 0x64, 0x7b, 0xff, 0x1d, 0x25, 0x5a, 0xff, 0x4a, 0x5f, 0x90, 0xff, 0x59, 0x69, 0x91, 0xff, 0x6e, 0x7d, 0x9e, 0xff, 0x70, 0x80, 0xa3, 0xff, 0x72, 0x82, 0xa7, 0xff, 0x72, 0x82, 0xa8, 0xff, 0x78, 0x84, 0xa8, 0xff, 0x84, 0x8b, 0xab, 0xff, 0x5b, 0x5a, 0x87, 0xff, 0x18, 0x17, 0x50, 0xff, 0x34, 0x4c, 0x72, 0xff, 0x5a, 0x6c, 0x8c, 0xff, 0x58, 0x6c, 0x93, 0xff, 0x3c, 0x49, 0x6e, 0xff, 0x61, 0x54, 0x71, 0xff, 0x3e, 0x5c, 0x8e, 0xff, 0x20, 0xa3, 0xdf, 0xff, 0x2d, 0x71, 0x93, 0xff, 0x12, 0x29, 0x59, 0xff, 0x3c, 0x60, 0x96, 0xff, 0x22, 0x2e, 0x52, 0x95, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x12, 0x17, 0x44, 0x99, 0x1c, 0x2b, 0x5f, 0xf4, 0x14, 0x3e, 0x6f, 0xff, 0x12, 0x48, 0x76, 0xff, 0x16, 0x2f, 0x64, 0xff, 0x1d, 0x3f, 0x80, 0xff, 0x14, 0x6b, 0xb2, 0xff, 0x11, 0x84, 0xc8, 0xff, 0x06, 0x91, 0xd3, 0xff, 0x16, 0x8e, 0xcc, 0xff, 0x2f, 0x5a, 0x93, 0xff, 0x3d, 0x50, 0x85, 0xff, 0x2b, 0x3d, 0x72, 0xff, 0x66, 0x58, 0x72, 0xff, 0x1f, 0x2e, 0x5c, 0xff, 0x68, 0x65, 0x86, 0xff, 0x2b, 0x85, 0xb0, 0xff, 0x23, 0xa6, 0xce, 0xff, 0x1e, 0x92, 0xbc, 0xff, 0x16, 0x8e, 0xb7, 0xff, 0x1a, 0x89, 0xb6, 0xff, 0x19, 0x84, 0xb4, 0xff, 0x19, 0x7e, 0xaf, 0xff, 0x1a, 0x75, 0xab, 0xff, 0x0a, 0x64, 0x9f, 0xff, 0x19, 0x76, 0xb3, 0xff, 0x20, 0x70, 0xb8, 0xff, 0x45, 0x48, 0x74, 0xff, 0x36, 0x2d, 0x60, 0xff, 0x46, 0x45, 0x6e, 0xff, 0x3f, 0x50, 0x7a, 0xff, 0x30, 0x57, 0x8c, 0xff, 0x2e, 0x57, 0x8f, 0xff, 0x0d, 0x8a, 0xd1, 0xff, 0x1c, 0xa7, 0xd9, 0xff, 0x26, 0x61, 0x86, 0xff, 0x19, 0x40, 0x7c, 0xff, 0x3a, 0x7b, 0xb4, 0xff, 0x25, 0x3e, 0x6b, 0xcc, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x1f, 0x4f, 0xe1, 0x1c, 0x40, 0x74, 0xff, 0x17, 0x42, 0x74, 0xff, 0x07, 0x47, 0x6e, 0xff, 0x11, 0x59, 0x88, 0xff, 0x13, 0x29, 0x65, 0xff, 0x19, 0x56, 0x9a, 0xff, 0x0f, 0x7f, 0xc8, 0xff, 0x0c, 0x8e, 0xd1, 0xff, 0x0e, 0x88, 0xcd, 0xff, 0x0a, 0x8b, 0xce, 0xff, 0x0e, 0x87, 0xc8, 0xff, 0x0d, 0x85, 0xc7, 0xff, 0x17, 0x6e, 0xb6, 0xff, 0x2b, 0x59, 0x94, 0xff, 0x1f, 0x61, 0xa6, 0xff, 0x2d, 0x3d, 0x79, 0xff, 0x17, 0x5e, 0xa3, 0xff, 0x14, 0x65, 0xa6, 0xff, 0x1a, 0x5f, 0xa0, 0xff, 0x19, 0x6b, 0xa4, 0xff, 0x20, 0x6c, 0xa6, 0xff, 0x22, 0x69, 0xa4, 0xff, 0x21, 0x66, 0xa3, 0xff, 0x1e, 0x66, 0xa5, 0xff, 0x12, 0x64, 0xa8, 0xff, 0x16, 0x71, 0xb5, 0xff, 0x15, 0x6a, 0xb0, 0xff, 0x31, 0x4c, 0x82, 0xff, 0x1e, 0x62, 0x9b, 0xff, 0x34, 0x65, 0x99, 0xff, 0x32, 0x5d, 0x92, 0xff, 0x0f, 0x8a, 0xd4, 0xff, 0x05, 0x82, 0xcd, 0xff, 0x00, 0x86, 0xcd, 0xff, 0x13, 0xa4, 0xda, 0xff, 0x36, 0x92, 0xb3, 0xff, 0x0b, 0x2d, 0x65, 0xff, 0x12, 0x60, 0x9d, 0xff, 0x2f, 0x72, 0xb2, 0xff, 0x33, 0x4c, 0x7c, 0xe9, 0x09, 0x09, 0x22, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x45, 0x75, 0xff, 0x09, 0x47, 0x6b, 0xff, 0x09, 0x40, 0x65, 0xff, 0x13, 0x4d, 0x7c, 0xff, 0x24, 0x63, 0x9b, 0xff, 0x16, 0x28, 0x69, 0xff, 0x13, 0x4a, 0x8e, 0xff, 0x0f, 0x7a, 0xc1, 0xff, 0x0f, 0x8d, 0xd2, 0xff, 0x0e, 0x8c, 0xd1, 0xff, 0x08, 0x8c, 0xd4, 0xff, 0x10, 0x8b, 0xd8, 0xff, 0x0d, 0x90, 0xd7, 0xff, 0x11, 0x94, 0xd8, 0xff, 0x0f, 0x91, 0xdd, 0xff, 0x0c, 0x8b, 0xcd, 0xff, 0x0c, 0x83, 0xc8, 0xff, 0x10, 0x7b, 0xc7, 0xff, 0x11, 0x77, 0xbb, 0xff, 0x10, 0x70, 0xb6, 0xff, 0x12, 0x6a, 0xb4, 0xff, 0x0e, 0x67, 0xb0, 0xff, 0x0e, 0x67, 0xb0, 0xff, 0x0f, 0x6a, 0xb0, 0xff, 0x11, 0x75, 0xb6, 0xff, 0x13, 0x7d, 0xc4, 0xff, 0x11, 0x86, 0xcc, 0xff, 0x11, 0x8b, 0xcf, 0xff, 0x10, 0x84, 0xcc, 0xff, 0x0f, 0x89, 0xd4, 0xff, 0x0c, 0x82, 0xd2, 0xff, 0x09, 0x86, 0xc8, 0xff, 0x0b, 0x96, 0xd6, 0xff, 0x1a, 0x9c, 0xdc, 0xff, 0x2a, 0xa1, 0xcd, 0xff, 0x30, 0x8e, 0xb4, 0xff, 0x1b, 0x38, 0x70, 0xff, 0x1f, 0x5a, 0x8f, 0xff, 0x1a, 0x68, 0x9d, 0xff, 0x10, 0x5e, 0x99, 0xff, 0x25, 0x6f, 0xac, 0xff, 0x33, 0x4b, 0x7d, 0xff, 0x12, 0x0d, 0x28, 0x39, + 0x0e, 0x23, 0x4f, 0xf0, 0x1d, 0x3e, 0x6d, 0xff, 0x13, 0x42, 0x6e, 0xff, 0x0f, 0x4e, 0x7e, 0xff, 0x19, 0x62, 0x98, 0xff, 0x1e, 0x48, 0x80, 0xff, 0x15, 0x28, 0x68, 0xff, 0x1c, 0x56, 0x98, 0xff, 0x12, 0x6b, 0xac, 0xff, 0x13, 0x73, 0xb4, 0xff, 0x14, 0x6f, 0xb4, 0xff, 0x17, 0x63, 0xac, 0xff, 0x1b, 0x57, 0x9d, 0xff, 0x13, 0x54, 0x94, 0xff, 0x0f, 0x6f, 0xaf, 0xff, 0x0d, 0x8a, 0xcf, 0xff, 0x0f, 0x8a, 0xd1, 0xff, 0x08, 0x8b, 0xd1, 0xff, 0x0b, 0x8c, 0xd1, 0xff, 0x0e, 0x8a, 0xd0, 0xff, 0x09, 0x8a, 0xd2, 0xff, 0x04, 0x90, 0xd7, 0xff, 0x00, 0x8b, 0xd2, 0xff, 0x02, 0x89, 0xd1, 0xff, 0x0a, 0x89, 0xd5, 0xff, 0x0c, 0x87, 0xcf, 0xff, 0x09, 0x93, 0xd2, 0xff, 0x13, 0x9c, 0xd5, 0xff, 0x13, 0xa0, 0xd5, 0xff, 0x1d, 0x9e, 0xd7, 0xff, 0x23, 0x9c, 0xd1, 0xff, 0x29, 0x8d, 0xbe, 0xff, 0x2a, 0x70, 0x9c, 0xff, 0x26, 0x60, 0x83, 0xff, 0x27, 0x4a, 0x74, 0xff, 0x1b, 0x2d, 0x66, 0xff, 0x27, 0x47, 0x80, 0xff, 0x2e, 0x53, 0x85, 0xf5, 0x27, 0x4d, 0x79, 0xf5, 0x23, 0x53, 0x88, 0xff, 0x23, 0x5a, 0x9c, 0xff, 0x43, 0x66, 0xa6, 0xff, 0x14, 0x14, 0x30, 0x5b, + 0x00, 0x00, 0x0f, 0x21, 0x0e, 0x10, 0x35, 0x7d, 0x10, 0x1d, 0x46, 0xc4, 0x0e, 0x2a, 0x5f, 0xff, 0x13, 0x52, 0x83, 0xff, 0x1a, 0x66, 0x94, 0xff, 0x1a, 0x45, 0x7d, 0xff, 0x15, 0x26, 0x66, 0xff, 0x10, 0x28, 0x67, 0xff, 0x0e, 0x29, 0x67, 0xff, 0x10, 0x28, 0x67, 0xff, 0x16, 0x27, 0x67, 0xff, 0x12, 0x30, 0x68, 0xff, 0x17, 0x2e, 0x64, 0xff, 0x0e, 0x1d, 0x59, 0xff, 0x1f, 0x5d, 0x99, 0xff, 0x19, 0x97, 0xcf, 0xff, 0x02, 0x86, 0xd2, 0xff, 0x11, 0x7f, 0xd0, 0xff, 0x10, 0x98, 0xd0, 0xff, 0x21, 0xa4, 0xcc, 0xff, 0x26, 0x95, 0xbd, 0xff, 0x2b, 0xa4, 0xce, 0xff, 0x1c, 0xaa, 0xd6, 0xff, 0x0a, 0x9a, 0xd2, 0xff, 0x17, 0xa3, 0xd3, 0xff, 0x2c, 0x83, 0xaf, 0xff, 0x33, 0x67, 0x94, 0xff, 0x2c, 0x65, 0x90, 0xff, 0x27, 0x53, 0x7f, 0xff, 0x22, 0x49, 0x75, 0xff, 0x1d, 0x3f, 0x6e, 0xff, 0x13, 0x3c, 0x6e, 0xff, 0x16, 0x3d, 0x75, 0xff, 0x14, 0x25, 0x56, 0xfb, 0x0f, 0x16, 0x42, 0x88, 0x08, 0x0d, 0x2a, 0x3d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x0b, 0x00, 0x26, 0x43, 0x1f, 0x27, 0x5c, 0xa3, 0x18, 0x1d, 0x4d, 0x8b, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x22, 0x61, 0x15, 0x2f, 0x63, 0xff, 0x0e, 0x59, 0x8e, 0xff, 0x16, 0x64, 0x9c, 0xff, 0x21, 0x5f, 0x99, 0xff, 0x1c, 0x58, 0x91, 0xff, 0x16, 0x56, 0x8d, 0xff, 0x15, 0x55, 0x89, 0xff, 0x16, 0x4f, 0x83, 0xff, 0x20, 0x49, 0x7f, 0xff, 0x23, 0x52, 0x83, 0xff, 0x21, 0x53, 0x8a, 0xff, 0x1c, 0x33, 0x70, 0xff, 0x31, 0x73, 0x9e, 0xff, 0x1d, 0xa5, 0xd4, 0xff, 0x1b, 0xaa, 0xd8, 0xff, 0x33, 0x9a, 0xbc, 0xff, 0x21, 0x46, 0x6e, 0xff, 0x1c, 0x46, 0x6c, 0xff, 0x22, 0x4f, 0x75, 0xff, 0x2f, 0x70, 0x92, 0xff, 0x3f, 0xa9, 0xbe, 0xff, 0x31, 0x76, 0x98, 0xff, 0x16, 0x2c, 0x5d, 0xff, 0x33, 0x60, 0x92, 0xff, 0x1f, 0x26, 0x58, 0xe3, 0x0a, 0x06, 0x30, 0x9f, 0x0e, 0x1b, 0x48, 0xb2, 0x12, 0x2f, 0x5d, 0xed, 0x18, 0x39, 0x6b, 0xff, 0x16, 0x28, 0x53, 0xf2, 0x03, 0x03, 0x1f, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0d, 0x2f, 0x26, 0x25, 0x1f, 0x49, 0xd1, 0x0f, 0x0a, 0x27, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x13, 0x3a, 0xb3, 0x15, 0x3a, 0x6d, 0xff, 0x17, 0x48, 0x7e, 0xff, 0x16, 0x4b, 0x7b, 0xff, 0x12, 0x41, 0x71, 0xff, 0x0d, 0x2e, 0x58, 0xfe, 0x09, 0x1f, 0x47, 0xd0, 0x04, 0x12, 0x37, 0x8f, 0x06, 0x06, 0x2a, 0x5b, 0x03, 0x06, 0x2c, 0x5c, 0x11, 0x24, 0x53, 0xa8, 0x2d, 0x57, 0x93, 0xff, 0x1d, 0x47, 0x7e, 0xff, 0x2b, 0x5d, 0x85, 0xff, 0x34, 0x80, 0x9e, 0xff, 0x17, 0x3a, 0x68, 0xff, 0x1b, 0x57, 0x8c, 0xff, 0x26, 0x66, 0x9f, 0xff, 0x21, 0x55, 0x92, 0xff, 0x1c, 0x45, 0x82, 0xff, 0x1b, 0x3a, 0x79, 0xff, 0x18, 0x43, 0x7f, 0xff, 0x3b, 0x7f, 0xb3, 0xff, 0x2a, 0x4a, 0x73, 0xd0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0x00, 0x1a, 0x44, 0x07, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x32, 0x29, 0x17, 0x17, 0x4d, 0x63, 0x21, 0x21, 0x4a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x2f, 0x1b, 0x16, 0x16, 0x3a, 0x5d, 0x17, 0x17, 0x2e, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0d, 0x0d, 0x31, 0x78, 0x0c, 0x11, 0x39, 0x93, 0x0b, 0x0f, 0x31, 0x87, 0x0b, 0x08, 0x2d, 0x61, 0x00, 0x00, 0x0b, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x1a, 0x42, 0x6c, 0x39, 0x5c, 0x93, 0xf9, 0x30, 0x63, 0x9d, 0xff, 0x17, 0x4d, 0x87, 0xff, 0x27, 0x5e, 0x9b, 0xff, 0x18, 0x4b, 0x85, 0xff, 0x15, 0x2a, 0x5e, 0xf1, 0x0e, 0x16, 0x48, 0xa2, 0x09, 0x1f, 0x4c, 0xa4, 0x12, 0x34, 0x68, 0xf2, 0x29, 0x54, 0x90, 0xff, 0x21, 0x34, 0x61, 0xb0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x16, 0x2c, 0x5c, 0xe0, 0x41, 0x6d, 0xac, 0xff, 0x24, 0x2d, 0x55, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x3a, 0x28, 0x48, 0x78, 0xb2, 0x27, 0x52, 0x84, 0xd3, 0x1b, 0x30, 0x5c, 0xb6, 0x05, 0x07, 0x38, 0x6e, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x14, 0x33, 0x00, 0x00, 0x00, 0x00, 0x31, 0x24, 0x49, 0x15, 0x21, 0x1a, 0x3b, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x1a, 0x3a, 0x1d, 0x34, 0x71, 0xff, 0x15, 0x43, 0x79, 0xff, 0x07, 0x0c, 0x2f, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x21, 0x17, 0x11, 0x11, 0x45, 0x6b, 0x09, 0x0f, 0x40, 0x77, 0x0f, 0x19, 0x38, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x1e, 0x4a, 0xd2, 0x25, 0x24, 0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0b, 0x0b, 0x11, 0x3d, 0x86, 0x07, 0x0b, 0x2c, 0x8b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x16, 0x1e, 0x49, 0xe0, 0x24, 0x49, 0x8a, 0xff, 0x36, 0x6b, 0xa6, 0xff, 0x30, 0x3e, 0x63, 0xdf, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x2f, 0x3c, 0x07, 0x07, 0x29, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x19, 0x3a, 0xa2, 0x11, 0x28, 0x52, 0xeb, 0x1f, 0x3c, 0x66, 0xcc, 0x1d, 0x23, 0x40, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const lv_image_dsc_t mole_image = { + .header.cf = LV_COLOR_FORMAT_ARGB8888, + .header.magic = LV_IMAGE_HEADER_MAGIC, + .header.w = 43, + .header.h = 48, + .data_size = 2064 * 4, + .data = mole_map, +}; \ No newline at end of file diff --git a/Whackmole/pic/mole_image.h b/Whackmole/pic/mole_image.h new file mode 100644 index 0000000000000000000000000000000000000000..53f0bc77dd0f9e81fb342cfe7c8d157f53a4597b --- /dev/null +++ b/Whackmole/pic/mole_image.h @@ -0,0 +1,16 @@ +#ifndef MOLE_IMG_H +#define MOLE_IMG_H + +#include "lvgl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const lv_img_dsc_t mole_image; + +#ifdef __cplusplus +} +#endif + +#endif /* MOLE_IMG_H */ diff --git a/bandx/Kconfig b/bandx/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..8691459f0ef9bdc00ac582b00ff860182b1d82d5 --- /dev/null +++ b/bandx/Kconfig @@ -0,0 +1,14 @@ +config LVX_USE_DEMO_BANDX + bool "Smart Band demo" + depends on GRAPHICS_LVGL && LV_USE_FRAGMENT && LV_USE_LIBPNG + default n + ---help--- + Enable build bandx Demo programs + +if LVX_USE_DEMO_BANDX + +config BANDX_BASE_PATH + string "Base path in bandx example" + default "/data" + +endif # LVX_USE_DEMO_BANDX diff --git a/bandx/Make.defs b/bandx/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..c08e4edf3f1096fc8787fbdb956d6d1a5e544806 --- /dev/null +++ b/bandx/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_BANDX),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/bandx +endif diff --git a/bandx/Makefile b/bandx/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..191bc9f6d8cf2e798fe1f8c323c255dd1c9c86e7 --- /dev/null +++ b/bandx/Makefile @@ -0,0 +1,14 @@ +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_BANDX), y) +PROGNAME += bandx +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_BANDX) + +MAINSRC += bandx_demo_main.c +CSRCS += $(shell find -L ./ -name "*.c" | grep -v bandx_demo_main.c) + +endif + +include $(APPDIR)/Application.mk diff --git a/bandx/bandx_demo.c b/bandx/bandx_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..0f07371e4f7826b4ce3c2035e4a0008efae0d3d0 --- /dev/null +++ b/bandx/bandx_demo.c @@ -0,0 +1,63 @@ +/** + * @file bandx_demo.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "bandx_demo.h" + +#include "page/page.h" +#include "resource/resource.h" + +/********************* + * DEFINES + *********************/ +#define ROOT_VER_RES 368 +#define ROOT_HOR_RES 194 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void bandx_demo_create(void) +{ + lv_obj_set_style_bg_color(lv_scr_act(), lv_palette_main(LV_PALETTE_GREY), 0); + + /* prepare base root */ + static lv_obj_t* root; + root = lv_obj_create(lv_scr_act()); + lv_obj_remove_style_all(root); + lv_obj_set_size(root, ROOT_HOR_RES, ROOT_VER_RES); + lv_obj_center(root); + + resource_init(); + page_init(); + + lv_fragment_manager_t* manager = lv_fragment_manager_create(NULL); + + /* push first page */ + lv_fragment_t* page = page_create("dialplate", NULL); + lv_fragment_manager_push(manager, page, &root); +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/bandx_demo.h b/bandx/bandx_demo.h new file mode 100644 index 0000000000000000000000000000000000000000..1a82f1e1efc0e56f605e872b0ee166c32edcbf1c --- /dev/null +++ b/bandx/bandx_demo.h @@ -0,0 +1,44 @@ +/** + * @file bandx_demo.h + * + */ + +#ifndef BANDX_DEMO_H +#define BANDX_DEMO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include <lvgl/lvgl.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Demo function for bandx. + */ +void bandx_demo_create(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*BANDX_DEMO_H*/ diff --git a/bandx/bandx_demo_main.c b/bandx/bandx_demo_main.c new file mode 100644 index 0000000000000000000000000000000000000000..da2184ef35ae3b76a67a4f9db756021cce68b81f --- /dev/null +++ b/bandx/bandx_demo_main.c @@ -0,0 +1,63 @@ +// include NuttX headers +#include <nuttx/config.h> +#include <unistd.h> +#include <uv.h> + +// include lvgl headers +#include <lvgl/lvgl.h> + +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +#include "bandx_demo.h" + +int main(int argc, FAR char* argv[]) +{ + // init lvgl + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("bandx_demo initialization failure!"); + return 1; + } + + bandx_demo_create(); + + // refresh lvgl ui + lv_nuttx_uv_loop(&ui_loop, &result); + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/bandx/hal/backlight.c b/bandx/hal/backlight.c new file mode 100755 index 0000000000000000000000000000000000000000..8fdf4087a8530c39050d348664e419601363d5eb --- /dev/null +++ b/bandx/hal/backlight.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/********************* + * INCLUDES + *********************/ +#include "backlight.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +static uint16_t backlight_value = 0; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +uint16_t backlight_get_value(void) +{ + return backlight_value; +} + +void backlight_set_value(int16_t val) +{ + backlight_value = val; +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/hal/backlight.h b/bandx/hal/backlight.h new file mode 100755 index 0000000000000000000000000000000000000000..73c8c8ecbc682f66d8761bd8466f31d837c8e562 --- /dev/null +++ b/bandx/hal/backlight.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __BACKLIGHT_H +#define __BACKLIGHT_H + +/********************* + * INCLUDES + *********************/ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the current value of the backlight. + * @return The current backlight value. + */ +uint16_t backlight_get_value(void); + +/** + * Set the value of the backlight. + * @param val The value to set for the backlight. + */ +void backlight_set_value(int16_t val); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bandx/hal/clock.c b/bandx/hal/clock.c new file mode 100755 index 0000000000000000000000000000000000000000..d019038a85d14d14ae057cf0bd13fea766de936f --- /dev/null +++ b/bandx/hal/clock.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/********************* + * INCLUDES + *********************/ + +#include "clock.h" +#include <time.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void clock_get_value(clock_value_t* clock_value) +{ + struct tm* t; + time_t tt; + time(&tt); + t = localtime(&tt); + + clock_value->year = t->tm_year + 1900; + clock_value->month = t->tm_mon + 1; + clock_value->date = t->tm_mday; + clock_value->week = t->tm_wday; + clock_value->hour = t->tm_hour; + clock_value->min = t->tm_min; + clock_value->sec = t->tm_sec; + clock_value->ms = 0; +} + +void clock_set_value(const clock_value_t* clock_value) +{ +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/hal/clock.h b/bandx/hal/clock.h new file mode 100755 index 0000000000000000000000000000000000000000..55a7a5cc97fc551a2859a2741371dfb285afe370 --- /dev/null +++ b/bandx/hal/clock.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __CLOCK_H +#define __CLOCK_H + +/********************* + * INCLUDES + *********************/ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint8_t hour; + uint8_t min; + uint8_t sec; + uint16_t ms; + uint16_t year; + uint8_t month; + uint8_t date; + uint8_t week; +} clock_value_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the current time value from the clock. + * @param clock_value Pointer to a structure to store the current clock value. + */ +void clock_get_value(clock_value_t* clock_value); + +/** + * Set the clock to a specific time value. + * @param clock_value Pointer to a structure of clock_value_t value to set. + */ +void clock_set_value(const clock_value_t* clock_value); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bandx/hal/hal.h b/bandx/hal/hal.h new file mode 100755 index 0000000000000000000000000000000000000000..dfe456d92a3982c23c48f62061eb2b6a366cde0a --- /dev/null +++ b/bandx/hal/hal.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __HAL_H +#define __HAL_H + +/********************* + * INCLUDES + *********************/ + +#include "backlight.h" +#include "clock.h" +#include "imu.h" +#include "particle_sensor.h" +#include "power.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif diff --git a/bandx/hal/imu.c b/bandx/hal/imu.c new file mode 100644 index 0000000000000000000000000000000000000000..b7557487f5b4bfe135fe618bb12c751bcca44849 --- /dev/null +++ b/bandx/hal/imu.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/********************* + * INCLUDES + *********************/ + +#include "imu.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +static uint16_t step_cnt = 0; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +int16_t imu_get_steps(void) +{ + return step_cnt++; +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/hal/imu.h b/bandx/hal/imu.h new file mode 100644 index 0000000000000000000000000000000000000000..177775e11ea3c02c79252fd02ddee0eb10548576 --- /dev/null +++ b/bandx/hal/imu.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __IMU_H +#define __IMU_H + +/********************* + * INCLUDES + *********************/ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Retrieve the number of steps recorded by the IMU. + * @return The number of steps as an integer value. + */ +int16_t imu_get_steps(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bandx/hal/particle_sensor.c b/bandx/hal/particle_sensor.c new file mode 100755 index 0000000000000000000000000000000000000000..7865e4f72b04865db0c45f2ef829558b227c6922 --- /dev/null +++ b/bandx/hal/particle_sensor.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "particle_sensor.h" + +#include <stdint.h> +#include <stdlib.h> + +/********************* + * DEFINES + *********************/ + +#define HR_BEATS_MAX 1000 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void particle_sensor_update_range(float beats); + +/********************** + * STATIC VARIABLES + **********************/ + +static int hr_last_beats = 600; +static float hr_beats_min = HR_BEATS_MAX; +static float hr_beats_max = 0; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +float particle_sensor_get_beats(void) +{ + float retval; + int breats = ((uint16_t)rand() % 600 + 400); + if (breats > hr_last_beats) { + hr_last_beats++; + } else if (breats < hr_last_beats) { + hr_last_beats--; + } + retval = hr_last_beats / 10.0f; + + particle_sensor_update_range(retval); + + return retval; +} + +bool particle_sensor_get_beats_range(float* min, float* max) +{ + if (hr_beats_min > HR_BEATS_MAX - 1 || hr_beats_max < 1) { + return false; + } + + *min = hr_beats_min; + *max = hr_beats_max; + return true; +} + +void particle_sensor_reset_beats_range(void) +{ + hr_beats_min = HR_BEATS_MAX; + hr_beats_max = 0; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void particle_sensor_update_range(float beats) +{ + if (beats < 1) { + return; + } + + if (beats < hr_beats_min) { + hr_beats_min = beats; + } + if (beats > hr_beats_max) { + hr_beats_max = beats; + } +} diff --git a/bandx/hal/particle_sensor.h b/bandx/hal/particle_sensor.h new file mode 100755 index 0000000000000000000000000000000000000000..e92b3dc5e87d80f83ed4d27723a06bb216744690 --- /dev/null +++ b/bandx/hal/particle_sensor.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __PARTICLE_SENSOR_H +#define __PARTICLE_SENSOR_H + +/********************* + * INCLUDES + *********************/ + +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the current heartbeats detected by the particle sensor. + * @return The current number of beats as a float value. + */ +float particle_sensor_get_beats(void); + +/** + * Get the range of heartbeats detected by the particle sensor. + * @param min Pointer to a float to store the minimum beat value. + * @param max Pointer to a float to store the maximum beat value. + * @return Return true if the operation was successful, otherwise return false. + */ +bool particle_sensor_get_beats_range(float* min, float* max); + +/** + * Reset the beats range for the particle sensor. + */ +void particle_sensor_reset_beats_range(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bandx/hal/power.c b/bandx/hal/power.c new file mode 100755 index 0000000000000000000000000000000000000000..1d358f114418cd01d53cd80ab093c9711161fb81 --- /dev/null +++ b/bandx/hal/power.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/********************* + * INCLUDES + *********************/ + +#include "power.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +uint8_t power_get_battery_usage(void) +{ + return 80; +} + +bool power_get_battery_is_charging(void) +{ + return false; +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/hal/power.h b/bandx/hal/power.h new file mode 100755 index 0000000000000000000000000000000000000000..34393808b5fcf0640c0cb6632bba87ff75163d3e --- /dev/null +++ b/bandx/hal/power.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __POWER_H +#define __POWER_H + +/********************* + * INCLUDES + *********************/ + +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Get the current battery usage percentage. + * @return The current battery usage as an unsigned integer value. + */ +uint8_t power_get_battery_usage(void); + +/** + * Check if the battery is currently charging. + * @return Return true if the battery is charging, otherwise return false. + */ +bool power_get_battery_is_charging(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bandx/page/_template.c b/bandx/page/_template.c new file mode 100644 index 0000000000000000000000000000000000000000..66da47ba33ffda1b8fd3890141603dbefd9b6871 --- /dev/null +++ b/bandx/page/_template.c @@ -0,0 +1,100 @@ +/** + * @file _template.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_fragment_t base; + lv_obj_t* label; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_USER("self: %p args: %p", self, args); +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_USER("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_USER("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_USER("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_USER("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_set_style_bg_color(root, lv_palette_main(LV_PALETTE_BLUE), 0); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_USER("self: %p obj: %p", self, obj); + + lv_obj_t* label = lv_label_create(obj); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_38"), 0); + lv_label_set_text(label, "SPORT"); + lv_obj_center(label); + + lv_obj_t* img = lv_img_create(obj); + lv_img_set_src(img, resource_get_img("sport")); + lv_obj_align(img, LV_ALIGN_TOP_MID, 0, 20); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_USER("self: %p obj: %p", self, obj); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_USER("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_USER("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(template); diff --git a/bandx/page/dialplate.c b/bandx/page/dialplate.c new file mode 100644 index 0000000000000000000000000000000000000000..d7b0735a920c016ecd94a70d6a3c359a0190cd43 --- /dev/null +++ b/bandx/page/dialplate.c @@ -0,0 +1,379 @@ +/** + * @file dialplate.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +#include "../hal/hal.h" + +/********************* + * DEFINES + *********************/ + +#define EVENT_CNT 1 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint32_t color; + lv_coord_t y; + lv_coord_t bar_width; + lv_coord_t arc_radius; + const void* img_src; + lv_obj_t* label; + lv_obj_t* bar; + lv_obj_t* arc; +} color_bar_t; + +enum color_bar_index { + COLOR_BAR_WEATHER, + COLOR_BAR_STEP, + COLOR_BAR_HEART, + COLOR_BAR_MAX +}; + +typedef struct { + lv_fragment_t base; + lv_span_t* span_date; + lv_span_t* span_month; + lv_span_t* span_week; + lv_obj_t* bar_batt; + lv_obj_t* label_time_hour; + lv_obj_t* label_time_min; + lv_timer_t* timer_label_time_update; + lv_timer_t* timer_color_bar_update; + clock_value_t clock_value; + color_bar_t color_bar_grp[COLOR_BAR_MAX]; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ +static lv_obj_t* obj_batt_create(lv_obj_t* par) +{ + lv_obj_t* bar = lv_obj_create(par); + lv_obj_set_style_bg_color(bar, lv_color_white(), LV_PART_MAIN); + lv_obj_clear_flag(bar, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_border_width(bar, 0, LV_PART_MAIN); + lv_obj_set_style_radius(bar, 0, LV_PART_MAIN); + lv_obj_set_size(bar, lv_obj_get_self_width(par) / 2, lv_obj_get_self_height(par) - 2); + lv_obj_align(bar, LV_ALIGN_LEFT_MID, 2, 0); + + return bar; +} + +static void topbar_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* topbar = lv_obj_create(par); + lv_obj_set_size(topbar, LV_PCT(100), 25); + lv_obj_set_style_bg_color(topbar, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(topbar, 0, LV_PART_MAIN); + lv_obj_clear_flag(topbar, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_align(topbar, LV_ALIGN_TOP_MID, 0, 0); + + lv_obj_t* img1 = lv_img_create(topbar); + lv_img_set_src(img1, resource_get_img("icon_bluetooth")); + lv_obj_align(img1, LV_ALIGN_LEFT_MID, 20, 0); + + lv_obj_t* img2 = lv_img_create(topbar); + lv_img_set_src(img2, resource_get_img("icon_battery")); + lv_obj_set_style_pad_all(topbar, 0, LV_PART_MAIN); + lv_obj_align(img2, LV_ALIGN_RIGHT_MID, -20, 0); + + lv_obj_t* bar = obj_batt_create(img2); + ctx->bar_batt = bar; +} + +static void label_date_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* spangroup = lv_spangroup_create(par); + lv_obj_set_style_text_font(spangroup, resource_get_font(BANDX_BOLD_FONT "_23"), LV_PART_MAIN); + lv_obj_set_style_text_color(spangroup, lv_color_white(), LV_PART_MAIN); + lv_obj_align(spangroup, LV_ALIGN_TOP_MID, 0, 25); + + lv_span_t* span1 = lv_spangroup_new_span(spangroup); + lv_span_t* span2 = lv_spangroup_new_span(spangroup); + lv_span_t* span3 = lv_spangroup_new_span(spangroup); + lv_style_set_text_color(&span2->style, lv_color_hex(0xF15A24)); + + ctx->span_month = span1; + ctx->span_date = span2; + ctx->span_week = span3; +} + +static void label_time_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_BOLD_FONT "_110"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 33); + ctx->label_time_hour = label; + + lv_obj_t* img = lv_img_create(par); + lv_img_set_src(img, resource_get_img("num_shadow")); + lv_obj_set_pos(img, 16, 136); + + img = lv_img_create(par); + lv_img_set_src(img, resource_get_img("num_shadow")); + lv_obj_set_pos(img, 99, 136); + + label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_BOLD_FONT "_110"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_hex(0xF15A24), LV_PART_MAIN); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 115); + ctx->label_time_min = label; +} + +static void label_time_update(lv_timer_t* timer) +{ + page_ctx_t* ctx = lv_timer_get_user_data(timer); + clock_get_value(&ctx->clock_value); + + char month_buf[32]; + char date_buf[32]; + const char* week_str[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; + int week_index = ctx->clock_value.week % ARRAY_SIZE(week_str); + + lv_snprintf(month_buf, sizeof(month_buf), "%02d-", ctx->clock_value.month); + lv_snprintf(date_buf, sizeof(date_buf), "%02d ", ctx->clock_value.date); + lv_span_set_text(ctx->span_month, month_buf); + lv_span_set_text(ctx->span_date, date_buf); + lv_span_set_text(ctx->span_week, week_str[week_index]); + + lv_label_set_text_fmt(ctx->label_time_hour, "%02d", ctx->clock_value.hour); + lv_label_set_text_fmt(ctx->label_time_min, "%02d", ctx->clock_value.min); +} + +static void color_bar_create(lv_obj_t* par, color_bar_t* color_bar, int len) +{ + for (int i = 0; i < len; i++) { + lv_color_t color = lv_color_hex(color_bar[i].color); + lv_coord_t y_pos = color_bar[i].y; + lv_coord_t bar_width = color_bar[i].bar_width; + lv_coord_t arc_size = color_bar[i].arc_radius * 2; + + lv_obj_t* bar = lv_bar_create(par); + lv_bar_set_value(bar, 100, LV_ANIM_OFF); + lv_obj_set_style_bg_color(bar, color, LV_PART_INDICATOR); + lv_obj_set_style_bg_color(bar, color, LV_PART_MAIN); + lv_obj_set_size(bar, bar_width, 32); + lv_obj_set_pos(bar, -12, y_pos); + + lv_obj_t* arc = lv_arc_create(par); + lv_obj_set_style_arc_color(arc, color, LV_PART_INDICATOR); + lv_obj_set_style_arc_width( + arc, + lv_obj_get_style_height(bar, 0), + LV_PART_INDICATOR); + lv_obj_set_style_bg_color(arc, color, LV_PART_KNOB); + lv_obj_set_style_pad_all(arc, 0, LV_PART_KNOB); + lv_obj_set_style_bg_opa(arc, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_set_style_border_width(arc, 0, LV_PART_MAIN); + lv_arc_set_angles(arc, 270, 360); + lv_arc_set_bg_angles(arc, 270, 360); + lv_obj_set_size(arc, arc_size, arc_size); + lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE); + + lv_obj_align_to(arc, bar, LV_ALIGN_OUT_RIGHT_TOP, -arc_size / 2 - 10, 0); + + lv_obj_t* img = lv_img_create(bar); + lv_img_set_src(img, resource_get_img(color_bar[i].img_src)); + lv_obj_align(img, LV_ALIGN_LEFT_MID, 20, 0); + + if (i == COLOR_BAR_WEATHER) { + lv_obj_t* img_deg = lv_img_create(bar); + lv_img_set_src(img_deg, resource_get_img("centigrade")); + lv_obj_align(img_deg, LV_ALIGN_RIGHT_MID, 0, 0); + } + + lv_obj_t* label = lv_label_create(bar); + lv_obj_set_style_text_font( + label, + resource_get_font(BANDX_BOLD_FONT "_28"), + LV_PART_MAIN); + lv_obj_set_style_text_color( + label, + lv_color_white(), + LV_PART_MAIN); + lv_obj_align_to(label, img, LV_ALIGN_OUT_RIGHT_MID, 10, 0); + + lv_obj_move_foreground(bar); + + color_bar[i].bar = bar; + color_bar[i].label = label; + color_bar[i].arc = arc; + } +} + +static void color_bar_update(lv_timer_t* timer) +{ + page_ctx_t* ctx = lv_timer_get_user_data(timer); + + lv_label_set_text_fmt(ctx->color_bar_grp[COLOR_BAR_WEATHER].label, "15"); + lv_label_set_text_fmt(ctx->color_bar_grp[COLOR_BAR_STEP].label, "%d", imu_get_steps()); + lv_label_set_text_fmt( + ctx->color_bar_grp[COLOR_BAR_HEART].label, + "%d", + (int)particle_sensor_get_beats()); +} + +static void auto_event_create(page_ctx_t* ctx) +{ + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &ctx->base.obj, LV_EVENT_LEAVE, 2000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_LEFT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } else if (code == LV_EVENT_LEAVE) { + page_push(&ctx->base, "launcher", NULL); + page_set_last_page_dialplate(true); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + color_bar_t color_bar_grp[COLOR_BAR_MAX] = { + { .color = 0xF7931E, + .y = 245, + .bar_width = 130, + .arc_radius = 120, + .img_src = "weather" }, + + { .color = 0x3FA9F5, + .y = 285, + .bar_width = 130, + .arc_radius = 80, + .img_src = "step" }, + + { .color = 0xED1C24, + .y = 325, + .bar_width = 130, + .arc_radius = 40, + .img_src = "heart" }, + }; + + for (int i = 0; i < COLOR_BAR_MAX; i++) { + ctx->color_bar_grp[i] = color_bar_grp[i]; + } +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + clock_get_value(&ctx->clock_value); + + topbar_create(obj); + label_date_create(obj); + label_time_create(obj); + color_bar_create(obj, ctx->color_bar_grp, COLOR_BAR_MAX); + + ctx->timer_label_time_update = lv_timer_create(label_time_update, 100, ctx); + label_time_update(ctx->timer_label_time_update); + + ctx->timer_color_bar_update = lv_timer_create(color_bar_update, 1000, ctx); + color_bar_update(ctx->timer_color_bar_update); + auto_event_create(ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + lv_timer_del(ctx->timer_color_bar_update); + lv_timer_del(ctx->timer_label_time_update); + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(dialplate); diff --git a/bandx/page/flashlight.c b/bandx/page/flashlight.c new file mode 100755 index 0000000000000000000000000000000000000000..a08902a81ff58d93bafb041ffd41ddc6c32dca2c --- /dev/null +++ b/bandx/page/flashlight.c @@ -0,0 +1,159 @@ +/** + * @file flashlight.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +#include "../utils/lv_obj_ext_func.h" + +/********************* + * DEFINES + *********************/ + +#define EVENT_CNT 3 + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_fragment_t base; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void auto_event_create(page_ctx_t* ctx) +{ + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &ctx->base.obj, LV_EVENT_REFRESH, 1000 }, + { &ctx->base.obj, LV_EVENT_REFRESH, 1000 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 1000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + switch (code) { + case LV_EVENT_GESTURE: { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } break; + case LV_EVENT_REFRESH: { + if (lv_obj_has_state(root, LV_STATE_CHECKED)) { + lv_obj_remove_state(root, LV_STATE_CHECKED); + } else { + lv_obj_add_state(root, LV_STATE_CHECKED); + } + } break; + case LV_EVENT_LEAVE: { + page_pop(&ctx->base); + } break; + default: + break; + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE); + + static const lv_style_prop_t props[] = { LV_STYLE_BG_COLOR, LV_STYLE_PROP_INV }; + static lv_style_transition_dsc_t dsc; + lv_style_transition_dsc_init(&dsc, props, lv_anim_path_ease_out, 200, 0, NULL); + + lv_obj_set_style_bg_color(obj, lv_color_white(), LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(obj, lv_color_mix(lv_color_white(), lv_color_black(), 200), LV_STATE_CHECKED); + lv_obj_set_style_transition(obj, &dsc, LV_STATE_DEFAULT); + lv_obj_set_style_transition(obj, &dsc, LV_STATE_CHECKED); + auto_event_create(ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + page_ctx_t* ctx = (page_ctx_t*)self; + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(flashlight); diff --git a/bandx/page/heart_rate.c b/bandx/page/heart_rate.c new file mode 100644 index 0000000000000000000000000000000000000000..2ccc4ceeb43e478cbff539dacba4561e9a0e6c37 --- /dev/null +++ b/bandx/page/heart_rate.c @@ -0,0 +1,481 @@ +/** + * @file heart_rate.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +#include "../hal/hal.h" +#include "../utils/lv_obj_ext_func.h" + +/********************* + * DEFINES + *********************/ + +#define COLOR_BAR_CNT 4 +#define EVENT_CNT 4 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char* text; + int value; + uint32_t color; + lv_coord_t y; +} color_bar_t; + +typedef struct { + lv_fragment_t base; + lv_obj_t* img_down; + lv_obj_t* img_up; + lv_obj_t* btn_rst; + lv_obj_t* img_heart; + lv_obj_t* chart_hr; + lv_obj_t* cont_hr; + lv_obj_t* label_hr_current; + lv_obj_t* label_hr_record_range; + lv_obj_t* label_hr_record_time; + lv_chart_series_t* chart_hr_ser1; + lv_timer_t* timer_label_hr_update; + lv_style_t color_bar_style; + lv_style_t label_hr_style1; + lv_style_t label_hr_style2; + color_bar_t color_bar_grp[COLOR_BAR_CNT]; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define CONT_HR_MOVE_DOWN(down, cont_hr, img_heart) \ + do { \ + LV_OBJ_ADD_ANIM( \ + cont_hr, \ + y, \ + (down) ? -PAGE_VER_RES : 0, LV_ANIM_TIME_DEFAULT); \ + img_heart_anim_enable(img_heart, !down); \ + } while (0) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void label_hr_current_update(lv_timer_t* timer) +{ + page_ctx_t* ctx = lv_timer_get_user_data(timer); + + float hr_min, hr_max; + int hr_beats = (int)particle_sensor_get_beats(); + if (!particle_sensor_get_beats_range(&hr_min, &hr_max)) { + return; + } + + lv_label_set_text_fmt(ctx->label_hr_current, "%d", hr_beats); + lv_label_set_text_fmt(ctx->label_hr_record_range, "%d-%d", (int)hr_min, (int)hr_max); + lv_chart_set_next_value(ctx->chart_hr, ctx->chart_hr_ser1, hr_beats); +} + +static void img_heart_anim_enable(lv_obj_t* img_heart, bool en) +{ + if (en) { + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, img_heart); + lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_img_set_zoom); + lv_anim_set_values(&a, 256, (int)(256 * 0.7f)); + lv_anim_set_time(&a, 300); + lv_anim_set_playback_time(&a, 300); + lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); + lv_anim_set_repeat_delay(&a, 800); + lv_anim_set_path_cb(&a, lv_anim_path_overshoot); + lv_anim_start(&a); + } else { + lv_anim_del(img_heart, (lv_anim_exec_xcb_t)lv_img_set_zoom); + } +} + +static void cont_hr_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* obj = lv_obj_create(par); + lv_obj_remove_style_all(obj); + lv_obj_set_size(obj, PAGE_HOR_RES, PAGE_VER_RES * 2); + lv_obj_align(obj, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_style_bg_color(obj, lv_color_black(), LV_PART_MAIN); + lv_obj_set_user_data(obj, ctx); + + ctx->cont_hr = obj; +} + +static void label_hr_current_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* img = lv_img_create(par); + lv_img_set_src(img, resource_get_img("heart_color")); + lv_obj_align(img, LV_ALIGN_TOP_MID, 0, 28); + + lv_obj_t* label1 = lv_label_create(par); + lv_obj_set_style_text_font(label1, resource_get_font(BANDX_REGULAR_FONT "_72"), LV_PART_MAIN); + lv_label_set_text(label1, "--"); + lv_obj_set_style_text_color(label1, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_text_align(label1, LV_ALIGN_CENTER, LV_PART_MAIN); + lv_obj_align(label1, LV_ALIGN_TOP_MID, 0, 95); + + lv_obj_t* label2 = lv_label_create(par); + lv_obj_set_style_text_font( + label2, + resource_get_font(BANDX_REGULAR_FONT "_20"), + LV_PART_MAIN); + lv_obj_set_style_text_color(label2, lv_palette_main(LV_PALETTE_GREY), LV_PART_MAIN); + lv_label_set_text(label2, "bpm"); + lv_obj_align_to(label2, label1, LV_ALIGN_OUT_RIGHT_BOTTOM, 10, -20); + + ctx->label_hr_current = label1; + ctx->img_heart = img; +} + +static void label_hr_record_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* label1 = lv_label_create(par); + lv_obj_add_style(label1, &ctx->label_hr_style1, LV_PART_MAIN); + lv_label_set_text(label1, "Recent updates"); + lv_obj_align(label1, LV_ALIGN_TOP_MID, 0, 165); + + lv_obj_t* label2 = lv_label_create(par); + lv_obj_add_style(label2, &ctx->label_hr_style2, LV_PART_MAIN); + lv_label_set_text(label2, "--:--"); + lv_obj_align(label2, LV_ALIGN_TOP_MID, 0, 192); + + lv_obj_t* label3 = lv_label_create(par); + lv_obj_add_style(label3, &ctx->label_hr_style1, LV_PART_MAIN); + lv_label_set_text(label3, "Range"); + lv_obj_align(label3, LV_ALIGN_TOP_MID, 0, 222); + + lv_obj_t* label4 = lv_label_create(par); + lv_obj_add_style(label4, &ctx->label_hr_style2, LV_PART_MAIN); + lv_label_set_text(label4, ""); + lv_obj_align(label4, LV_ALIGN_TOP_MID, 0, 246); + + ctx->label_hr_record_time = label2; + ctx->label_hr_record_range = label4; +} + +static void label_hr_record_time_update(lv_obj_t* label) +{ + clock_value_t clock_value; + clock_get_value(&clock_value); + lv_label_set_text_fmt(label, "%02d:%02d", clock_value.hour, clock_value.min); +} + +static void btn_rst_event_handler(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + lv_obj_t* obj = lv_event_get_current_target_obj(event); + page_ctx_t* ctx = (page_ctx_t*)lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + particle_sensor_reset_beats_range(); + label_hr_record_time_update(ctx->label_hr_record_time); + + lv_obj_t* img = lv_obj_get_child(obj, 0); + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, img); + lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_img_set_angle); + lv_anim_set_values(&a, 0, 3600); + lv_anim_set_time(&a, 1000); + lv_anim_set_path_cb(&a, lv_anim_path_ease_out); + lv_anim_start(&a); + } +} + +static void btn_rst_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* btn = lv_btn_create(par); + lv_obj_set_size(btn, 149, 44); + lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 279); + lv_obj_add_event(btn, btn_rst_event_handler, LV_EVENT_ALL, ctx); + lv_obj_set_style_bg_color( + btn, + lv_color_make(0xFF, 0x54, 0x2A), + LV_STATE_DEFAULT); + lv_obj_set_style_bg_color( + btn, + lv_palette_main(LV_PALETTE_GREY), + LV_STATE_PRESSED); + + lv_style_t* trans_style = resource_get_style("btn_trans"); + lv_obj_add_style(btn, trans_style, LV_STATE_PRESSED); + lv_obj_add_style(btn, trans_style, LV_STATE_DEFAULT); + lv_obj_set_style_radius(btn, 8, LV_PART_MAIN); + lv_obj_set_style_border_color(btn, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(btn, 0, LV_PART_MAIN); + lv_obj_set_style_outline_width(btn, 0, LV_PART_MAIN); + + lv_obj_t* img = lv_img_create(btn); + lv_img_set_src(img, resource_get_img("icon_reset")); + lv_obj_align_to(img, btn, LV_ALIGN_CENTER, 0, 0); + + ctx->btn_rst = btn; +} + +static void img_arrow_event_handler(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + lv_obj_t* obj = lv_event_get_current_target_obj(event); + page_ctx_t* ctx = (page_ctx_t*)lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + bool is_down = (lv_strcmp(lv_img_get_src(obj), resource_get_img("arrow_down")) == 0); + CONT_HR_MOVE_DOWN(is_down, ctx->cont_hr, ctx->img_heart); + } +} + +static void img_arrow_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* img1 = lv_img_create(par); + lv_img_set_src(img1, resource_get_img("arrow_down")); + lv_obj_align(img1, LV_ALIGN_TOP_MID, 0, 339); + lv_obj_add_event(img1, img_arrow_event_handler, LV_EVENT_ALL, ctx); + lv_obj_add_flag(img1, LV_OBJ_FLAG_CLICKABLE); + ctx->img_down = img1; + + lv_obj_t* img2 = lv_img_create(par); + lv_img_set_src(img2, resource_get_img("arrow_up")); + lv_obj_align(img2, LV_ALIGN_TOP_MID, 0, PAGE_VER_RES + 12); + lv_obj_add_event(img2, img_arrow_event_handler, LV_EVENT_ALL, ctx); + lv_obj_add_flag(img2, LV_OBJ_FLAG_CLICKABLE); + ctx->img_up = img2; +} + +static void color_bar_create(lv_obj_t* par, color_bar_t* color_bar, int len) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + for (int i = 0; i < len; i++) { + lv_obj_t* bar = lv_bar_create(par); + lv_bar_set_value(bar, color_bar[i].value, LV_ANIM_OFF); + lv_obj_set_size(bar, 156, 10); + lv_obj_set_style_bg_color( + bar, + lv_color_hex(color_bar[i].color), + LV_PART_INDICATOR); + lv_obj_align(bar, LV_ALIGN_TOP_MID, 0, PAGE_VER_RES + color_bar[i].y); + + lv_obj_t* label = lv_label_create(par); + lv_obj_add_style(label, &ctx->color_bar_style, LV_PART_MAIN); + lv_label_set_text_fmt(label, "%s %d%%", color_bar[i].text, color_bar[i].value); + lv_obj_align_to(label, bar, LV_ALIGN_OUT_TOP_LEFT, 0, -2); + } +} + +static void chart_hr_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* chart = lv_chart_create(par); + lv_obj_set_size(chart, 156, 87); + lv_obj_clear_flag(chart, LV_OBJ_FLAG_CLICKABLE); + lv_obj_align(chart, LV_ALIGN_TOP_MID, 0, PAGE_VER_RES + 36); + lv_chart_set_type(chart, LV_CHART_TYPE_LINE); + + lv_obj_set_style_bg_color( + chart, + lv_color_make(0x1A, 0x1A, 0x1A), + LV_PART_MAIN); + lv_obj_set_style_border_width(chart, 2, LV_PART_MAIN); + lv_obj_set_style_radius(chart, 5, LV_PART_MAIN); + lv_obj_set_style_border_color( + chart, + lv_color_make(0x66, 0x66, 0x66), + LV_PART_MAIN); + + lv_obj_set_style_bg_opa(chart, LV_OPA_50, LV_PART_ITEMS); + lv_obj_set_style_bg_grad_dir(chart, LV_GRAD_DIR_VER, LV_PART_ITEMS); + lv_obj_set_style_bg_main_stop(chart, 255, LV_PART_ITEMS); + lv_obj_set_style_bg_grad_stop(chart, 0, LV_PART_ITEMS); + lv_obj_set_style_line_width(chart, 1, LV_PART_ITEMS); + + lv_chart_set_div_line_count(chart, 0, 4); + lv_obj_set_style_line_color( + chart, + lv_color_make(0x66, 0x66, 0x66), + LV_PART_ITEMS); + lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 50, 180); + lv_chart_set_point_count(chart, 100); + + ctx->chart_hr_ser1 = lv_chart_add_series(chart, lv_color_make(0xfc, 0x5c, 0x00), 0); + + ctx->chart_hr = chart; +} + +static void auto_event_create(page_ctx_t* ctx) +{ + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &ctx->btn_rst, LV_EVENT_CLICKED, 2000 }, + { &ctx->img_down, LV_EVENT_CLICKED, 1000 }, + { &ctx->img_up, LV_EVENT_CLICKED, 1000 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 1000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } else if (dir == LV_DIR_BOTTOM) { + CONT_HR_MOVE_DOWN(false, ctx->cont_hr, ctx->img_heart); + } else if (dir == LV_DIR_TOP) { + CONT_HR_MOVE_DOWN(true, ctx->cont_hr, ctx->img_heart); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + color_bar_t color_bar_grp[COLOR_BAR_CNT] = { + { "Relaxation", 45, 0x3FA9F5, 158 }, + { "Sports", 30, 0x7AC943, 212 }, + { "Competition", 20, 0xF15A24, 266 }, + { "Endurance", 5, 0xC1272D, 320 }, + }; + + for (int i = 0; i < COLOR_BAR_CNT; i++) { + ctx->color_bar_grp[i] = color_bar_grp[i]; + } + lv_style_init(&ctx->color_bar_style); + lv_style_set_text_font(&ctx->color_bar_style, resource_get_font(BANDX_REGULAR_FONT "_20")); + lv_style_set_text_color(&ctx->color_bar_style, lv_color_white()); + + lv_style_init(&ctx->label_hr_style1); + lv_style_set_text_font(&ctx->label_hr_style1, resource_get_font(BANDX_REGULAR_FONT "_20")); + lv_style_set_text_color(&ctx->label_hr_style1, lv_palette_main(LV_PALETTE_GREY)); + + lv_style_init(&ctx->label_hr_style2); + lv_style_set_text_font(&ctx->label_hr_style2, resource_get_font(BANDX_REGULAR_FONT "_20")); + lv_style_set_text_color(&ctx->label_hr_style2, lv_color_make(0xF1, 0x5A, 0x24)); +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); + + page_ctx_t* ctx = (page_ctx_t*)self; + + lv_style_reset(&ctx->color_bar_style); + lv_style_reset(&ctx->label_hr_style1); + lv_style_reset(&ctx->label_hr_style2); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + cont_hr_create(obj); + label_hr_current_create(ctx->cont_hr); + label_hr_record_create(ctx->cont_hr); + label_hr_record_time_update(ctx->label_hr_record_time); + btn_rst_create(ctx->cont_hr); + img_arrow_create(ctx->cont_hr); + chart_hr_create(ctx->cont_hr); + color_bar_create(ctx->cont_hr, ctx->color_bar_grp, COLOR_BAR_CNT); + + ctx->timer_label_hr_update = lv_timer_create(label_hr_current_update, 1000, ctx); + + img_heart_anim_enable(ctx->img_heart, true); + auto_event_create(ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + lv_timer_del(ctx->timer_label_hr_update); + img_heart_anim_enable(ctx->img_heart, false); + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(heart_rate); diff --git a/bandx/page/launcher.c b/bandx/page/launcher.c new file mode 100644 index 0000000000000000000000000000000000000000..578b20bb66d2d937c4fd3eee87848435fd9e2adb --- /dev/null +++ b/bandx/page/launcher.c @@ -0,0 +1,336 @@ +/** + * @file launcher.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../utils/lv_obj_ext_func.h" +#include "page.h" + +/********************* + * DEFINES + *********************/ + +#define APP_ENTRY_CNT 7 +#define EVENT_CNT 3 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const void* name; + const char* text; + uint32_t bg_color; + lv_obj_t* icon; +} app_entry_t; + +typedef struct { + lv_fragment_t base; + lv_style_t cont_style; + lv_style_t icon_style; + lv_style_t label_style; + app_entry_t app_entry[APP_ENTRY_CNT]; + lv_timer_t* auto_show_timer; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define APP_ICON_SIZE 100 +#define APP_ICON_PAD_VER (APP_ICON_SIZE / 2) +#define APP_ICON_ANIM_TIME 200 + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void app_icon_click_anim(lv_obj_t* img, bool ispress) +{ + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, img); + lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_img_set_zoom); + lv_anim_set_values( + &a, + lv_img_get_zoom(img), + ispress ? (int)(256 * 0.8f) : 256); + lv_anim_set_time(&a, APP_ICON_ANIM_TIME); + + lv_anim_set_path_cb(&a, ispress ? lv_anim_path_ease_in_out : lv_anim_path_overshoot); + + lv_anim_start(&a); +} + +static void on_app_icon_event(lv_event_t* e) +{ + page_ctx_t* ctx = lv_event_get_user_data(e); + lv_obj_t* icon = lv_event_get_current_target(e); + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t* img = lv_obj_get_child(icon, 0); + + switch (code) { + case LV_EVENT_PRESSED: + app_icon_click_anim(img, true); + break; + case LV_EVENT_RELEASED: + case LV_EVENT_PRESS_LOST: + app_icon_click_anim(img, false); + break; + case LV_EVENT_CLICKED: { + app_entry_t* entry = lv_obj_get_user_data(icon); + page_set_last_page_dialplate(false); + page_push(&ctx->base, entry->name, NULL); + } break; + default: + break; + } +} + +static void app_icon_create(page_ctx_t* ctx, lv_obj_t* par, app_entry_t* entry) +{ + lv_obj_t* cont = lv_obj_create(par); + lv_obj_remove_style_all(cont); + lv_obj_add_style(cont, &ctx->cont_style, 0); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t* icon = lv_obj_create(cont); + lv_style_t* trans_style = resource_get_style("btn_trans"); + lv_obj_remove_style_all(icon); + lv_obj_add_style(icon, &ctx->icon_style, 0); + + lv_obj_set_style_bg_color(icon, lv_palette_main(LV_PALETTE_GREY), LV_STATE_PRESSED); + lv_obj_set_style_transform_width(icon, 5, LV_STATE_PRESSED); + lv_obj_set_style_transform_height(icon, -5, LV_STATE_PRESSED); + lv_obj_add_style(icon, trans_style, LV_STATE_PRESSED); + lv_obj_add_style(icon, trans_style, LV_STATE_DEFAULT); + + lv_obj_set_style_bg_color(icon, lv_color_hex(entry->bg_color), 0); + lv_obj_set_user_data(icon, (void*)entry); + lv_obj_add_event(icon, on_app_icon_event, LV_EVENT_ALL, ctx); + lv_obj_clear_flag(icon, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* img = lv_img_create(icon); + lv_img_set_src(img, resource_get_img(entry->name)); + lv_obj_center(img); + + lv_obj_t* label = lv_label_create(cont); + lv_obj_add_style(label, &ctx->label_style, 0); + lv_label_set_text(label, entry->text); + entry->icon = icon; +} + +static void auto_show_update(lv_timer_t* timer) +{ + page_ctx_t* ctx = lv_timer_get_user_data(timer); + + static int current_show_app_index = -1; + + if (current_show_app_index >= APP_ENTRY_CNT) { + current_show_app_index = -1; + } + + enum state_type { IDLE, + FOCUS, + PRESSED, + PRESSED_LOST, + CLICK, + _END }; + static uint8_t state = IDLE; + if (page_is_last_page_dialplate()) { + current_show_app_index = 0; + page_set_last_page_dialplate(false); + } + + if (current_show_app_index >= 0 && current_show_app_index < APP_ENTRY_CNT) { + lv_obj_t* current_icon = ctx->app_entry[current_show_app_index].icon; + + switch (state) { + case IDLE: + break; + case FOCUS: + lv_obj_scroll_to_view_recursive(current_icon, LV_ANIM_ON); + lv_obj_send_event(current_icon, LV_EVENT_FOCUSED, ctx); + break; + case PRESSED: + lv_obj_send_event(current_icon, LV_EVENT_PRESSED, ctx); + break; + case PRESSED_LOST: + lv_obj_send_event(current_icon, LV_EVENT_PRESS_LOST, ctx); + break; + case CLICK: + if (lv_strcmp(ctx->app_entry[current_show_app_index].text, "Settings") == 0) { + current_show_app_index = -1; + } else { + current_show_app_index++; + } + lv_obj_send_event(current_icon, LV_EVENT_CLICKED, ctx); + break; + case _END: + break; + default: + break; + } + state++; + state %= _END; + } else { + lv_obj_send_event(ctx->base.obj, LV_EVENT_LEAVE, NULL); + } +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + page_ctx_t* ctx = (page_ctx_t*)self; + + lv_style_init(&ctx->cont_style); + lv_style_set_width(&ctx->cont_style, LV_PCT(100)); + lv_style_set_height(&ctx->cont_style, LV_SIZE_CONTENT); + + lv_style_init(&ctx->icon_style); + lv_style_set_bg_opa(&ctx->icon_style, LV_OPA_COVER); + lv_style_set_size(&ctx->icon_style, APP_ICON_SIZE, APP_ICON_SIZE); + lv_style_set_radius(&ctx->icon_style, 10); + + lv_style_init(&ctx->label_style); + lv_style_set_text_font(&ctx->label_style, resource_get_font(BANDX_BOLD_FONT "_23")); + lv_style_set_text_color(&ctx->label_style, lv_color_white()); + + app_entry_t app_entry[APP_ENTRY_CNT] = { + { "heart_rate", "Heart", 0xFF542A }, + { "music", "Music", 0xEE4C84 }, + { "stop_watch", "StWatch", 0x3CFFA7 }, + { "flashlight", "Light", 0xFFB428 }, + { "sleep", "Sleep", 0x001BC8 }, + { "sport", "Sport", 0x9B5DFF }, + { "settings", "Settings", 0x0089FF }, + }; + + for (int i = 0; i < APP_ENTRY_CNT; i++) { + ctx->app_entry[i] = app_entry[i]; + } +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); + page_ctx_t* ctx = (page_ctx_t*)self; + lv_style_reset(&ctx->cont_style); + lv_style_reset(&ctx->icon_style); + lv_style_reset(&ctx->label_style); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + /* root */ + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(obj, 20, 0); + lv_obj_set_style_pad_ver(obj, APP_ICON_PAD_VER, 0); + + /* apps */ + for (int i = 0; i < APP_ENTRY_CNT; i++) { + app_icon_create( + ctx, + obj, + &ctx->app_entry[i]); + } + + /* shadow image */ + { + lv_obj_t* img1 = lv_img_create(obj); + lv_img_set_src(img1, resource_get_img("icon_shadow_up")); + lv_obj_align(img1, LV_ALIGN_TOP_MID, 0, -APP_ICON_PAD_VER); + lv_obj_add_flag(img1, LV_OBJ_FLAG_FLOATING); + + lv_obj_t* img2 = lv_img_create(obj); + lv_img_set_src(img2, resource_get_img("icon_shadow_down")); + lv_obj_align(img2, LV_ALIGN_BOTTOM_MID, 0, APP_ICON_PAD_VER); + lv_obj_add_flag(img2, LV_OBJ_FLAG_FLOATING); + } + + if (page_get_autoshow_enable()) { + ctx->auto_show_timer = lv_timer_create(auto_show_update, 500, ctx); + } +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + page_ctx_t* ctx = (page_ctx_t*)self; + if (page_get_autoshow_enable()) { + lv_timer_del(ctx->auto_show_timer); + } +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(launcher); diff --git a/bandx/page/music.c b/bandx/page/music.c new file mode 100644 index 0000000000000000000000000000000000000000..5a3bdda1dc1a84f25b982688624555ef007a6314 --- /dev/null +++ b/bandx/page/music.c @@ -0,0 +1,563 @@ +/** + * @file music.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +/********************* + * DEFINES + *********************/ + +#define MC_COLOR_GRAY lv_color_make(0x33, 0x33, 0x33) +#define MC_COLOR_PINK lv_color_make(0xB9, 0x00, 0x5E) +#define MC_COLOR_PINK_BG lv_color_make(0x17, 0x00, 0x0B) + +#define MUSIC_TIME_TO_MS(min, sec) ((min)*60 * 1000 + (sec)*1000) +#define MUSIC_INFO_CNT 3 +#define EVENT_CNT 9 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char* name; + uint32_t time_ms; +} music_info_t; + +typedef struct { + lv_fragment_t base; + lv_style_t btn_style; + lv_style_t trans_style; + lv_obj_t* bar_volume; + lv_obj_t* arc_play; + lv_obj_t* obj_play; + lv_obj_t* label_music_info; + lv_obj_t* btn_volume_add; + lv_obj_t* btn_volume_reduce; + lv_obj_t* btn_music_ctrl_next; + lv_obj_t* btn_music_ctrl_prev; + lv_span_t* span_cur_time; + lv_span_t* span_end_time; + lv_timer_t* timer_music_update; + uint32_t music_current_time; + uint32_t music_end_time; + uint16_t music_current_index; + bool music_is_playing; + music_info_t music_info_grp[MUSIC_INFO_CNT]; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_target(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void bar_volume_set_value(int16_t value, lv_obj_t* bar_volume) +{ + lv_bar_set_value(bar_volume, value, LV_ANIM_ON); +} + +static void bar_volume_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* bar = lv_bar_create(par); + lv_obj_set_size(bar, 160, 3); + lv_obj_align(bar, LV_ALIGN_TOP_MID, 0, 70); + lv_obj_set_style_bg_color(bar, MC_COLOR_PINK, LV_PART_MAIN); + lv_obj_set_style_bg_color(bar, MC_COLOR_PINK, LV_PART_INDICATOR); + + ctx->bar_volume = bar; +} + +static void btn_volume_event_handler(lv_event_t* event) +{ + lv_obj_t* obj = lv_event_get_target(event); + lv_event_code_t code = lv_event_get_code(event); + page_ctx_t* ctx = lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + lv_obj_t* img = lv_obj_get_child(obj, 0); + int16_t vol_value = lv_bar_get_value(ctx->bar_volume); + + if (lv_strcmp(lv_img_get_src(img), resource_get_img("icon_volume_add")) == 0) { + bar_volume_set_value(vol_value + 10, ctx->bar_volume); + } else { + bar_volume_set_value(vol_value - 10, ctx->bar_volume); + } + } +} + +static void btn_volume_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* btn1 = lv_btn_create(par); + lv_obj_set_size(btn1, 85, 48); + lv_obj_add_style(btn1, &ctx->btn_style, LV_PART_MAIN); + lv_obj_add_style(btn1, &ctx->trans_style, LV_STATE_DEFAULT); + lv_obj_add_style(btn1, &ctx->trans_style, LV_STATE_PRESSED); + lv_obj_set_style_bg_color(btn1, lv_color_white(), LV_STATE_PRESSED); + lv_obj_align(btn1, LV_ALIGN_TOP_MID, -lv_obj_get_style_width(btn1, 0) / 2 - 3, 10); + lv_obj_add_event(btn1, btn_volume_event_handler, LV_EVENT_ALL, ctx); + + lv_obj_t* btn2 = lv_btn_create(par); + lv_obj_set_size(btn2, 85, 48); + lv_obj_add_style(btn2, &ctx->btn_style, LV_PART_MAIN); + lv_obj_add_style(btn2, &ctx->trans_style, LV_STATE_DEFAULT); + lv_obj_add_style(btn2, &ctx->trans_style, LV_STATE_PRESSED); + lv_obj_set_style_bg_color(btn2, lv_color_white(), LV_STATE_PRESSED); + lv_obj_align(btn2, LV_ALIGN_TOP_MID, lv_obj_get_style_width(btn2, 0) / 2 + 3, 10); + lv_obj_add_event(btn2, btn_volume_event_handler, LV_EVENT_ALL, ctx); + + lv_obj_t* img1 = lv_img_create(btn1); + lv_img_set_src(img1, resource_get_img("icon_volume_reduce")); + lv_obj_set_style_image_recolor_opa(img1, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_image_recolor(img1, lv_color_black(), LV_PART_MAIN); + lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t* img2 = lv_img_create(btn2); + lv_img_set_src(img2, resource_get_img("icon_volume_add")); + lv_obj_set_style_image_recolor_opa(img2, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_image_recolor(img2, lv_color_black(), LV_PART_MAIN); + lv_obj_align(img2, LV_ALIGN_CENTER, 0, 0); + + ctx->btn_volume_reduce = btn1; + ctx->btn_volume_add = btn2; +} + +static void obj_play_anim_ready_callback(lv_anim_t* a_p) +{ + page_ctx_t* ctx = lv_anim_get_user_data(a_p); + + if (a_p->act_time == 0) + return; + + lv_obj_t* img = (lv_obj_t*)a_p->var; + const char* img_src_next; + img_src_next = (lv_strcmp(lv_img_get_src(img), resource_get_img("icon_start")) == 0) ? resource_get_img("icon_pause") : resource_get_img("icon_start"); + lv_img_set_src(img, img_src_next); + + ctx->music_is_playing = (lv_strcmp(lv_img_get_src(img), resource_get_img("icon_pause")) == 0); + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, img); + lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_img_set_angle); + lv_anim_set_values(&a, 1800, 3600); + lv_anim_set_time(&a, 300); + + lv_anim_set_path_cb(&a, lv_anim_path_ease_out); + lv_anim_start(&a); +} + +static void obj_play_event_handler(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + lv_obj_t* obj = lv_event_get_target(event); + page_ctx_t* ctx = lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + lv_obj_t* img = lv_obj_get_child(obj, 0); + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, img); + lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_img_set_angle); + lv_anim_set_ready_cb(&a, obj_play_anim_ready_callback); + lv_anim_set_user_data(&a, ctx); + lv_anim_set_values(&a, 0, 1800); + lv_anim_set_time(&a, 300); + lv_anim_set_path_cb(&a, lv_anim_path_ease_in); + lv_anim_start(&a); + } +} + +static void obj_play_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* obj = lv_obj_create(ctx->arc_play); + lv_obj_set_size(obj, 104, 104); + lv_obj_add_style(obj, &ctx->btn_style, LV_PART_MAIN); + lv_obj_add_style(obj, &ctx->trans_style, LV_STATE_DEFAULT); + lv_obj_add_style(obj, &ctx->trans_style, LV_STATE_PRESSED); + lv_obj_set_style_bg_color(obj, lv_color_white(), LV_STATE_PRESSED); + lv_obj_add_event(obj, obj_play_event_handler, LV_EVENT_ALL, ctx); + lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_set_style_bg_color(obj, MC_COLOR_GRAY, LV_PART_MAIN); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN); + lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t* img = lv_img_create(obj); + lv_img_set_src(img, resource_get_img("icon_start")); + lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); + + ctx->obj_play = obj; +} + +static void spangroup_time_update(page_ctx_t* ctx, uint32_t cur_ms, uint32_t end_ms) +{ + uint32_t cur_min = cur_ms / 60 / 1000; + uint32_t cur_sec = (cur_ms / 1000) % 60; + + uint32_t end_min = end_ms / 60 / 1000; + uint32_t end_sec = (end_ms / 1000) % 60; + + char cur_buf[32]; + char end_buf[32]; + + lv_snprintf(cur_buf, sizeof(cur_buf), "%d:%02d", cur_min, cur_sec); + lv_snprintf(end_buf, sizeof(end_buf), " -- %d:%02d", end_min, end_sec); + lv_span_set_text(ctx->span_cur_time, cur_buf); + lv_span_set_text(ctx->span_end_time, end_buf); +} + +static void arc_play_event_handler(lv_event_t* event) +{ + page_ctx_t* ctx = lv_event_get_user_data(event); + int32_t value = lv_arc_get_value(ctx->arc_play); + ctx->music_current_time = lv_map(value, lv_arc_get_min_value(ctx->arc_play), lv_arc_get_max_value(ctx->arc_play), 0, ctx->music_end_time); + spangroup_time_update(ctx, ctx->music_current_time, ctx->music_end_time); +} + +static void arc_play_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* arc = lv_arc_create(par); + lv_obj_set_style_arc_color(arc, MC_COLOR_PINK, LV_PART_INDICATOR); + lv_obj_set_style_arc_width(arc, 6, LV_PART_INDICATOR); + + lv_obj_set_style_bg_color(arc, MC_COLOR_PINK, LV_PART_KNOB); // 设置 arc knob颜色 + lv_obj_set_style_pad_all(arc, 0, LV_PART_KNOB); // 设置arc knob size + + lv_obj_set_style_arc_color(arc, MC_COLOR_PINK_BG, LV_PART_MAIN); + lv_obj_set_style_arc_width(arc, 6, LV_PART_MAIN); + + lv_obj_set_style_border_width(arc, 0, LV_PART_MAIN); + lv_obj_set_size(arc, 121, 121); + lv_obj_align(arc, LV_ALIGN_CENTER, 0, 0); + lv_obj_add_event_cb(arc, arc_play_event_handler, LV_EVENT_VALUE_CHANGED, ctx); + + lv_arc_set_start_angle(arc, 270); + lv_arc_set_bg_angles(arc, 0, 360); + lv_arc_set_range(arc, 0, 1000); + lv_arc_set_rotation(arc, 270); + + ctx->arc_play = arc; +} + +static void spangroup_time_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_label_set_text(label, "--"); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 87); + + lv_obj_t* spangroup = lv_spangroup_create(par); + lv_obj_set_style_text_font(spangroup, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + + lv_span_t* cur_span = lv_spangroup_new_span(spangroup); + lv_style_set_text_color(&cur_span->style, lv_color_hex(0xB9005E)); + + lv_span_t* end_span = lv_spangroup_new_span(spangroup); + lv_style_set_text_color(&end_span->style, lv_color_hex(0x666666)); + lv_span_set_text(end_span, "--"); + + lv_obj_align(spangroup, LV_ALIGN_TOP_MID, 0, 87); + + ctx->span_cur_time = cur_span; + ctx->span_end_time = end_span; +} + +static void label_music_info_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN); + lv_label_set_text(label, ""); + lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_align(label, LV_ALIGN_CENTER); + lv_obj_set_width(label, 166); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 259); + + ctx->label_music_info = label; +} + +static void music_change_current(page_ctx_t* ctx, int index) +{ + index %= MUSIC_INFO_CNT; + + ctx->music_current_time = 0; + ctx->music_end_time = ctx->music_info_grp[index].time_ms; + + lv_label_set_text(ctx->label_music_info, ctx->music_info_grp[index].name); + lv_arc_set_value(ctx->arc_play, ctx->music_current_time * 1000 / ctx->music_end_time); + spangroup_time_update(ctx, ctx->music_current_time, ctx->music_end_time); +} + +static void music_change_next(page_ctx_t* ctx, bool next) +{ + if (next) { + if (ctx->music_current_index >= MUSIC_INFO_CNT - 1) { + ctx->music_current_index = 0; + } else { + ctx->music_current_index++; + } + } else { + if (ctx->music_current_index == 0) { + ctx->music_current_index = MUSIC_INFO_CNT; + } else { + ctx->music_current_index--; + } + } + + music_change_current(ctx, ctx->music_current_index); +} + +static void btn_music_event_handler(lv_event_t* event) +{ + lv_obj_t* obj = lv_event_get_target(event); + lv_event_code_t code = lv_event_get_code(event); + page_ctx_t* ctx = lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + lv_obj_t* img = lv_obj_get_child(obj, 0); + + bool is_next = (lv_strcmp(lv_img_get_src(img), resource_get_img("icon_next")) == 0); + music_change_next(ctx, is_next); + } +} + +static void btn_music_ctrl_create(lv_obj_t* par) +{ + page_ctx_t* ctx = lv_obj_get_user_data(par); + + lv_obj_t* btn1 = lv_btn_create(par); + lv_obj_set_size(btn1, 85, 64); + lv_obj_add_style(btn1, &ctx->btn_style, LV_PART_MAIN); + lv_obj_set_style_bg_color(btn1, lv_color_white(), LV_STATE_PRESSED); + lv_obj_add_style(btn1, &ctx->trans_style, LV_STATE_DEFAULT); + lv_obj_add_style(btn1, &ctx->trans_style, LV_STATE_PRESSED); + lv_obj_align(btn1, LV_ALIGN_BOTTOM_MID, -lv_obj_get_style_width(btn1, 0) / 2 - 3, -10); + lv_obj_add_event(btn1, btn_music_event_handler, LV_EVENT_ALL, ctx); + + lv_obj_t* btn2 = lv_btn_create(par); + lv_obj_set_size(btn2, 85, 64); + lv_obj_add_style(btn2, &ctx->btn_style, LV_PART_MAIN); + lv_obj_set_style_bg_color(btn2, lv_color_white(), LV_STATE_PRESSED); + lv_obj_add_style(btn2, &ctx->trans_style, LV_STATE_DEFAULT); + lv_obj_add_style(btn2, &ctx->trans_style, LV_STATE_PRESSED); + lv_obj_add_event(btn2, btn_music_event_handler, LV_EVENT_ALL, ctx); + lv_obj_align(btn2, LV_ALIGN_BOTTOM_MID, lv_obj_get_style_width(btn2, 0) / 2 + 3, -10); + + lv_obj_t* img1 = lv_img_create(btn1); + lv_img_set_src(img1, resource_get_img("icon_prev")); + lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t* img2 = lv_img_create(btn2); + lv_img_set_src(img2, resource_get_img("icon_next")); + lv_obj_align(img2, LV_ALIGN_CENTER, 0, 0); + + ctx->btn_music_ctrl_prev = btn1; + ctx->btn_music_ctrl_next = btn2; +} + +static void music_update(lv_timer_t* timer) +{ + page_ctx_t* ctx = lv_timer_get_user_data(timer); + + if (!ctx->music_is_playing) { + return; + } + ctx->music_current_time += timer->period; + + if (ctx->music_current_time > ctx->music_end_time) { + music_change_next(ctx, true); + } + + lv_arc_set_value(ctx->arc_play, ctx->music_current_time * 1000 / ctx->music_end_time); + spangroup_time_update(ctx, ctx->music_current_time, ctx->music_end_time); +} + +static void auto_event_create(page_ctx_t* ctx) +{ + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &ctx->obj_play, LV_EVENT_CLICKED, 1000 }, + { &ctx->btn_volume_add, LV_EVENT_CLICKED, 500 }, + { &ctx->btn_volume_add, LV_EVENT_CLICKED, 500 }, + { &ctx->btn_volume_reduce, LV_EVENT_CLICKED, 500 }, + { &ctx->btn_volume_reduce, LV_EVENT_CLICKED, 500 }, + { &ctx->btn_music_ctrl_next, LV_EVENT_CLICKED, 2000 }, + { &ctx->btn_music_ctrl_next, LV_EVENT_CLICKED, 2000 }, + { &ctx->obj_play, LV_EVENT_CLICKED, 1000 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 1000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + lv_style_init(&ctx->btn_style); + lv_style_set_bg_color(&ctx->btn_style, MC_COLOR_GRAY); + lv_style_set_border_width(&ctx->btn_style, 0); + lv_style_set_outline_width(&ctx->btn_style, 0); + lv_style_set_radius(&ctx->btn_style, 10); + + lv_style_init(&ctx->trans_style); + static lv_style_transition_dsc_t dsc; + static const lv_style_prop_t props[] = { + LV_STYLE_BG_COLOR, + LV_STYLE_TRANSFORM_WIDTH, + LV_STYLE_TRANSFORM_HEIGHT, + LV_STYLE_PROP_INV + }; + lv_style_transition_dsc_init( + &dsc, + props, + lv_anim_path_ease_in_out, + 50, + 0, + NULL); + lv_style_set_transition(&ctx->trans_style, &dsc); + + music_info_t music_info_grp[MUSIC_INFO_CNT] = { + { .name = "Wannabe (Instrumental)", MUSIC_TIME_TO_MS(3, 37) }, + { .name = "River", MUSIC_TIME_TO_MS(3, 40) }, + { .name = "I Feel Tired", MUSIC_TIME_TO_MS(3, 25) }, + }; + + for (int i = 0; i < MUSIC_INFO_CNT; i++) { + ctx->music_info_grp[i] = music_info_grp[i]; + } + + ctx->music_current_time = 0; + ctx->music_end_time = 0; + ctx->music_current_index = 0; + ctx->music_is_playing = false; +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); + + page_ctx_t* ctx = (page_ctx_t*)self; + lv_style_reset(&ctx->btn_style); + lv_style_reset(&ctx->trans_style); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + btn_volume_create(obj); + bar_volume_create(obj); + bar_volume_set_value(50, ctx->bar_volume); + + arc_play_create(obj); + obj_play_create(obj); + spangroup_time_create(obj); + label_music_info_create(obj); + btn_music_ctrl_create(obj); + + ctx->music_is_playing = false; + music_change_current(ctx, ctx->music_current_index); + auto_event_create(ctx); + ctx->timer_music_update = lv_timer_create(music_update, 100, ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + lv_timer_del(ctx->timer_music_update); + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(music); diff --git a/bandx/page/page.c b/bandx/page/page.c new file mode 100644 index 0000000000000000000000000000000000000000..5dd159d6df182b4ddcc7263cdff0d2b09a613b5e --- /dev/null +++ b/bandx/page/page.c @@ -0,0 +1,113 @@ +/** + * @file page.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "page.h" + +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +#define PAGE_STYLE_MATCH(NAME) \ + do { \ + if (lv_strcmp(name, #NAME) == 0) { \ + return &g_style_grp.NAME; \ + } \ + } while (0) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static bool autoshow_enable = false; +static bool is_last_page_dialplate = false; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void page_init(void) +{ +} + +lv_fragment_t* page_create(const char* name, void* arg) +{ + LV_LOG_USER("name: %s arg: %p", name, arg); + +#define PAGE_DEF(NAME) \ + do { \ + if (lv_strcmp(name, #NAME) == 0) { \ + extern const lv_fragment_class_t _page_##NAME##_cls; \ + return lv_fragment_create(&_page_##NAME##_cls, arg); \ + } \ + } while (0); +#include "page.inc" +#undef PAGE_DEF + + LV_LOG_WARN("NO match for %s", name); + return NULL; +} + +bool page_push(lv_fragment_t* self, const char* name, void* arg) +{ + lv_fragment_t* page = page_create(name, NULL); + + if (!page) { + LV_LOG_WARN("page push %s failed", name); + return false; + } + + lv_fragment_manager_t* manager = lv_fragment_get_manager(self); + lv_obj_t* const* container = lv_fragment_get_container(self); + lv_fragment_manager_push(manager, page, container); + return true; +} + +void page_pop(lv_fragment_t* self) +{ + lv_fragment_manager_t* manager = lv_fragment_get_manager(self); + lv_fragment_manager_pop(manager); +} + +bool page_get_autoshow_enable(void) +{ + return autoshow_enable; +} + +void page_set_autoshow_enable(bool en) +{ + autoshow_enable = en; +} + +void page_set_last_page_dialplate(bool value) +{ + is_last_page_dialplate = value; +} + +bool page_is_last_page_dialplate(void) +{ + return is_last_page_dialplate; +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/page/page.h b/bandx/page/page.h new file mode 100644 index 0000000000000000000000000000000000000000..e73af20fc362909b1fec940436dd4ad59426e32e --- /dev/null +++ b/bandx/page/page.h @@ -0,0 +1,139 @@ +/** + * @file page.h + * + */ + +#ifndef PAGE_H +#define PAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include <lvgl/lvgl.h> + +#ifdef CONFIG_LVX_USE_DEMO_BANDX + +#include "../resource/resource.h" +#include "../utils/lv_auto_event.h" + +/********************* + * DEFINES + *********************/ + +#define PAGE_CLASS_DEF(NAME) \ + const lv_fragment_class_t _page_##NAME##_cls = { \ + .constructor_cb = on_page_construct, \ + .destructor_cb = on_page_destruct, \ + .attached_cb = on_page_attached, \ + .detached_cb = on_page_detached, \ + .create_obj_cb = on_page_create, \ + .obj_created_cb = on_page_created, \ + .obj_will_delete_cb = on_page_will_delete, \ + .obj_deleted_cb = on_page_deleted, \ + .event_cb = on_page_event, \ + .instance_size = sizeof(page_ctx_t) \ + } + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the page manager. + */ +void page_init(void); + +/** + * Create a new page fragment. + * @param name The name of the page. + * @param arg Arguments to be passed for the page fragment create. + * @return A pointer to the newly created page fragment. + */ +lv_fragment_t* page_create(const char* name, void* arg); + +/** + * Push a new page onto the stack. + * @param self Pointer to the current page fragment. + * @param name The name of the page to push. + * @param arg Arguments for the new page. + * @return Return true if the push operation was successful. + */ +bool page_push(lv_fragment_t* self, const char* name, void* arg); + +/** + * Pop the current page from the stack. + * @param self Pointer to the current page fragment. + */ +void page_pop(lv_fragment_t* self); + +/** + * Get the auto-show enable status. + * @return Return true if auto-show is enabled, false otherwise. + */ +bool page_get_autoshow_enable(void); + +/** + * Set the auto-show enable status. + * @param en Enable or disable the auto-show. + */ +void page_set_autoshow_enable(bool en); + +/** + * Set the status of the last page dial plate. + * @param value Set to true to indicate that the last page is dial plate, false otherwise. + */ +void page_set_last_page_dialplate(bool value); + +/** + * Check if the last page is dial plate. + * @return Return true if the last page is dial plate, false otherwise. + */ +bool page_is_last_page_dialplate(void); + +/********************** + * MACROS + **********************/ +#define PAGE_VER_RES 368 +#define PAGE_HOR_RES 194 + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#endif + +#if !defined(BANDX_REGULAR_FONT) && !defined(BANDX_BOLD_FONT) +#define BANDX_REGULAR_FONT "AlibabaPuHuiTi-3-55-Regular" +#define BANDX_BOLD_FONT "AlibabaPuHuiTi-3-95-ExtraBold" +#endif + +#define AUTO_EVENT_CREATE(ae, ae_data) \ + do { \ + if (page_get_autoshow_enable()) { \ + ae = lv_auto_event_create(ae_data, ARRAY_SIZE(ae_data)); \ + } else { \ + ae = NULL; \ + } \ + } while (0) + +#define AUTO_EVENT_DELETE(ae) \ + do { \ + if (page_get_autoshow_enable()) { \ + lv_auto_event_del(ae); \ + ae = NULL; \ + } \ + } while (0) + +#endif /*CONFIG_LVX_USE_DEMO_BANDX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*PAGE_H*/ diff --git a/bandx/page/page.inc b/bandx/page/page.inc new file mode 100644 index 0000000000000000000000000000000000000000..2018b5503f58cf4f076c4f7a471d38d0ecb0e82c --- /dev/null +++ b/bandx/page/page.inc @@ -0,0 +1,11 @@ +/* page list */ +PAGE_DEF(template) +PAGE_DEF(dialplate) +PAGE_DEF(launcher) +PAGE_DEF(flashlight) +PAGE_DEF(settings) +PAGE_DEF(stop_watch) +PAGE_DEF(sleep) +PAGE_DEF(sport) +PAGE_DEF(music) +PAGE_DEF(heart_rate) \ No newline at end of file diff --git a/bandx/page/settings.c b/bandx/page/settings.c new file mode 100644 index 0000000000000000000000000000000000000000..bb03f1d8a2ee8f5a7610de76c01de42d747149d0 --- /dev/null +++ b/bandx/page/settings.c @@ -0,0 +1,286 @@ +/** + * @file settings.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +#include "../utils/lv_obj_ext_func.h" + +/********************* + * DEFINES + *********************/ + +#define BAR_SETTING_CNT 2 +#define EVENT_CNT 9 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char* text; + const char* img_src_left; + const char* img_src_right; + lv_coord_t y; + + lv_obj_t* img_left; + lv_obj_t* img_right; + lv_obj_t* bar; +} bar_setting_t; + +typedef struct { + lv_fragment_t base; + bar_setting_t bar_setting_grp[BAR_SETTING_CNT]; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define BX_NAME "BandX" +#define BX_VERSION "v1.0" + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void bar_setting_event_handler(lv_event_t* event) +{ + lv_obj_t* obj = lv_event_get_user_data(event); + lv_event_code_t code = lv_event_get_code(event); + if (code == LV_EVENT_CLICKED) { + bar_setting_t* bar_setting = (bar_setting_t*)lv_obj_get_user_data(obj); + const char* img_src = lv_img_get_src(obj); + int add_value = (lv_strcmp(img_src, resource_get_img(bar_setting->img_src_left)) == 0) ? -10 : +10; + int16_t old_value = lv_bar_get_value(bar_setting->bar); + lv_bar_set_value(bar_setting->bar, old_value + add_value, LV_ANIM_ON); + } +} + +static void img_setting_set_style(lv_obj_t* img) +{ + lv_obj_add_event(img, bar_setting_event_handler, LV_EVENT_ALL, img); + lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE); + + lv_obj_set_style_image_recolor_opa(img, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_image_recolor(img, lv_color_make(0x66, 0x66, 0x66), LV_PART_MAIN); + lv_obj_set_style_image_recolor(img, lv_color_make(0x00, 0x89, 0xFF), LV_STATE_PRESSED); +} + +static void bar_setting_create(lv_obj_t* par, bar_setting_t* bar_setting, int len) +{ + for (int i = 0; i < len; i++) { + lv_obj_t* obj_base = lv_obj_create(par); + lv_obj_remove_style_all(obj_base); + lv_obj_set_size(obj_base, PAGE_HOR_RES - 40, 50); + lv_obj_clear_flag(obj_base, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_align(obj_base, LV_ALIGN_TOP_MID, 0, bar_setting[i].y); + + lv_obj_t* label = lv_label_create(obj_base); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_make(0x66, 0x66, 0x66), LV_PART_MAIN); + lv_label_set_text(label, bar_setting[i].text); + lv_obj_align_to(label, obj_base, LV_ALIGN_TOP_LEFT, 0, 0); + + lv_obj_t* bar = lv_bar_create(obj_base); + lv_obj_set_size(bar, 74, 6); + lv_obj_set_style_bg_color(bar, lv_color_make(0x00, 0x89, 0xFF), LV_PART_INDICATOR); + lv_obj_set_style_bg_color(bar, lv_color_make(0x33, 0x33, 0x33), LV_PART_MAIN); + lv_obj_align(bar, LV_ALIGN_BOTTOM_MID, 0, -10); + lv_bar_set_value(bar, 50, LV_ANIM_OFF); + bar_setting[i].bar = bar; + + lv_obj_t* img1 = lv_img_create(obj_base); + lv_img_set_src(img1, resource_get_img(bar_setting[i].img_src_left)); + lv_obj_set_user_data(img1, &(bar_setting[i])); + img_setting_set_style(img1); + lv_obj_align_to(img1, bar, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + lv_obj_t* img2 = lv_img_create(obj_base); + lv_img_set_src(img2, resource_get_img(bar_setting[i].img_src_right)); + lv_obj_set_user_data(img2, &(bar_setting[i])); + img_setting_set_style(img2); + lv_obj_align_to(img2, bar, LV_ALIGN_OUT_RIGHT_MID, 10, 0); + + bar_setting[i].img_left = img1; + bar_setting[i].img_right = img2; + } +} + +static void sw_auto_show_event_handler(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_event_get_user_data(e); + + if (code == LV_EVENT_VALUE_CHANGED) { + page_set_autoshow_enable(!page_get_autoshow_enable()); + if (page_get_autoshow_enable()) { + LV_LOG_USER("Auto-show Begin ..."); + lv_obj_send_event(ctx->base.obj, LV_EVENT_LEAVE, NULL); + } else { + lv_auto_event_del(ctx->auto_event); + ctx->auto_event = NULL; + LV_LOG_USER("Auto-show End ..."); + } + } +} + +static void sw_auto_show_create(page_ctx_t* ctx) +{ + lv_obj_t* par = ctx->base.obj; + lv_obj_t* label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_make(0x66, 0x66, 0x66), LV_PART_MAIN); + lv_label_set_text(label, "Auto-show"); + lv_obj_align(label, LV_ALIGN_TOP_LEFT, 23, 187); + + lv_obj_t* sw = lv_switch_create(par); + lv_obj_set_size(sw, 41, 23); + lv_obj_align_to(sw, label, LV_ALIGN_OUT_RIGHT_MID, 12, -5); + lv_obj_set_style_bg_color(sw, lv_color_make(0x33, 0x33, 0x33), LV_PART_MAIN); + lv_obj_set_style_bg_color(sw, lv_color_make(0x00, 0x89, 0xFF), LV_PART_INDICATOR); + lv_obj_set_style_bg_color(sw, lv_color_make(0xAA, 0xAA, 0xAA), LV_PART_KNOB); + lv_obj_set_style_outline_width(sw, 0, LV_PART_MAIN); + lv_obj_add_event(sw, sw_auto_show_event_handler, LV_EVENT_ALL, ctx); + page_get_autoshow_enable() ? lv_obj_add_state(sw, LV_STATE_CHECKED) : lv_obj_clear_state(sw, LV_STATE_CHECKED); +} + +static void label_info_create(lv_obj_t* par) +{ + lv_obj_t* label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN); + lv_label_set_text(label, BX_NAME " " BX_VERSION "\n"__DATE__ + "\nBuild"); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 270); +} + +static void auto_event_create(page_ctx_t* ctx) +{ + bar_setting_t* bar_setting_grp = ctx->bar_setting_grp; + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &(bar_setting_grp[0].img_left), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[0].img_left), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[0].img_right), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[0].img_right), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[1].img_left), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[1].img_left), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[1].img_right), LV_EVENT_CLICKED, 500 }, + { &(bar_setting_grp[1].img_right), LV_EVENT_CLICKED, 500 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 1000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + bar_setting_t bar_setting_grp[BAR_SETTING_CNT] = { + { .text = "Volume", .img_src_left = "icon_volume_reduce", .img_src_right = "icon_volume_add", 24 }, + { .text = "Backlight", .img_src_left = "icon_minus", .img_src_right = "icon_plus", 98 }, + }; + + for (int i = 0; i < BAR_SETTING_CNT; i++) { + ctx->bar_setting_grp[i] = bar_setting_grp[i]; + } +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + bar_setting_create(obj, ctx->bar_setting_grp, BAR_SETTING_CNT); + sw_auto_show_create(ctx); + label_info_create(obj); + auto_event_create(ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + page_ctx_t* ctx = (page_ctx_t*)self; + lv_auto_event_del(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(settings); diff --git a/bandx/page/sleep.c b/bandx/page/sleep.c new file mode 100644 index 0000000000000000000000000000000000000000..d20444f00d868c0d7dcc8b18c090fb0443757904 --- /dev/null +++ b/bandx/page/sleep.c @@ -0,0 +1,469 @@ +/** + * @file sleep.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +#include "../utils/lv_obj_ext_func.h" + +/********************* + * DEFINES + *********************/ + +#define SLEEP_TIME_CNT 6 +#define SLEEP_INFO_CNT 4 +#define EVENT_CNT 3 + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + SLEEP_TYPE_SHALLOW, + SLEEP_TYPE_DEEP, + SLEEP_TYPE_REM, + SLEEP_TYPE_AWAKE, + SLEEP_TYPE_MAX +} sleep_type; + +typedef struct { + const char* text; + sleep_type type; +} sleep_info_t; + +typedef struct { + sleep_type type; + uint32_t start_min; + uint32_t end_min; +} sleep_time_t; + +typedef struct { + lv_fragment_t base; + lv_obj_t* img_down; + lv_obj_t* img_up; + lv_obj_t* cont_sleep; + + uint32_t sleep_type_color[SLEEP_TYPE_MAX]; + sleep_time_t sleep_time_grp[SLEEP_TIME_CNT]; + sleep_info_t sleep_info_grp[SLEEP_INFO_CNT]; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define CONT_SLEEP_MOVE_DOWN(down, obj) \ + LV_OBJ_ADD_ANIM( \ + obj, \ + y, \ + (down) ? -PAGE_VER_RES : 0, LV_ANIM_TIME_DEFAULT) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void cont_sleep_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + lv_obj_t* obj = lv_obj_create(par); + lv_obj_remove_style_all(obj); + lv_obj_set_size(obj, PAGE_HOR_RES, PAGE_VER_RES * 2); + lv_obj_align(obj, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_style_bg_color(obj, lv_color_black(), LV_PART_MAIN); + lv_obj_set_user_data(obj, ctx); + + ctx->cont_sleep = obj; +} + +static void img_arrow_event_handler(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + lv_obj_t* obj = lv_event_get_current_target_obj(event); + page_ctx_t* ctx = (page_ctx_t*)lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + bool is_down = (lv_strcmp(lv_img_get_src(obj), resource_get_img("arrow_down")) == 0); + CONT_SLEEP_MOVE_DOWN(is_down, ctx->cont_sleep); + } +} + +static void img_arrow_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* img1 = lv_img_create(par); + lv_img_set_src(img1, resource_get_img("arrow_down")); + lv_obj_align(img1, LV_ALIGN_TOP_MID, 0, 339); + lv_obj_add_event(img1, img_arrow_event_handler, LV_EVENT_ALL, ctx); + lv_obj_add_flag(img1, LV_OBJ_FLAG_CLICKABLE); + + lv_obj_t* img2 = lv_img_create(par); + lv_img_set_src(img2, resource_get_img("arrow_up")); + lv_obj_align(img2, LV_ALIGN_TOP_MID, 0, PAGE_VER_RES + 12); + lv_obj_add_event(img2, img_arrow_event_handler, LV_EVENT_ALL, ctx); + lv_obj_add_flag(img2, LV_OBJ_FLAG_CLICKABLE); + + ctx->img_down = img1; + ctx->img_up = img2; +} + +static void img_sleep_create(lv_obj_t* par) +{ + lv_obj_t* img = lv_img_create(par); + lv_img_set_src(img, resource_get_img("sleep")); + lv_obj_align(img, LV_ALIGN_TOP_MID, 0, 32); +} + +static void label_score_create(lv_obj_t* par) +{ + lv_obj_t* label1 = lv_label_create(par); + lv_obj_set_style_text_font( + label1, + resource_get_font(BANDX_REGULAR_FONT "_20"), + LV_PART_MAIN); + lv_obj_set_style_text_color(label1, lv_color_hex(0x808080), LV_PART_MAIN); + lv_label_set_text(label1, "Score"); + lv_obj_align(label1, LV_ALIGN_TOP_MID, 0, 123); + + lv_obj_t* label2 = lv_label_create(par); + lv_obj_set_style_text_font( + label2, + resource_get_font(BANDX_REGULAR_FONT "_72"), + LV_PART_MAIN); + lv_obj_set_style_text_color(label2, lv_color_white(), LV_PART_MAIN); + lv_label_set_text(label2, "78"); + lv_obj_align(label2, LV_ALIGN_TOP_MID, 0, 148); +} + +static void label_total_time_create(lv_obj_t* par) +{ + lv_obj_t* label1 = lv_label_create(par); + lv_obj_set_style_text_font(label1, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_text_color(label1, lv_color_hex(0x808080), LV_PART_MAIN); + lv_label_set_text(label1, "Total time"); + lv_obj_align(label1, LV_ALIGN_TOP_MID, 0, 224); + + lv_obj_t* label2 = lv_label_create(par); + lv_obj_set_style_text_font(label2, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_text_color(label2, lv_color_hex(0x3FA9F5), LV_PART_MAIN); + lv_label_set_text(label2, "8 h 52 min"); + lv_obj_set_style_text_align(label2, LV_ALIGN_CENTER, 0); + lv_obj_align(label2, LV_ALIGN_TOP_MID, 0, 249); + + lv_obj_t* spangroup = lv_spangroup_create(par); + lv_obj_set_style_text_font(spangroup, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + + lv_span_t* span = lv_spangroup_new_span(spangroup); + lv_span_set_text_static(span, "00:29"); + lv_style_set_text_color(&span->style, lv_color_hex(0x3FA9F5)); + + lv_span_t* span1 = lv_spangroup_new_span(spangroup); + lv_span_set_text_static(span1, "-"); + lv_style_set_text_color(&span1->style, lv_color_hex(0x808080)); + + lv_span_t* span2 = lv_spangroup_new_span(spangroup); + lv_span_set_text_static(span2, "09:48"); + lv_style_set_text_color(&span2->style, lv_color_hex(0x3FA9F5)); + lv_obj_align(spangroup, LV_ALIGN_TOP_MID, 0, 274); +} + +static uint32_t sleep_time_get_sum(sleep_time_t* sleep_time, int len, sleep_type check_type) +{ + uint32_t sum = 0; + if (check_type == SLEEP_TYPE_SHALLOW) { + sum = sleep_time[0].end_min - sleep_time[0].start_min; + sum -= sleep_time_get_sum(sleep_time, len, SLEEP_TYPE_DEEP); + sum -= sleep_time_get_sum(sleep_time, len, SLEEP_TYPE_REM); + sum -= sleep_time_get_sum(sleep_time, len, SLEEP_TYPE_AWAKE); + } else { + for (int i = 0; i < len; i++) { + if (sleep_time[i].type == check_type) { + uint32_t time = sleep_time[i].end_min - sleep_time[i].start_min; + sum += time; + } + } + } + return sum; +} + +static void obj_sleep_time_create(lv_obj_t* par, sleep_time_t* sleep_time, int len) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* obj_base = lv_obj_create(par); + lv_obj_remove_style_all(obj_base); + lv_obj_set_size(obj_base, 165, 74); + lv_obj_set_style_radius(obj_base, 10, LV_PART_MAIN); + lv_obj_set_style_clip_corner(obj_base, 10, LV_PART_MAIN); + + lv_obj_align(obj_base, LV_ALIGN_TOP_MID, 0, PAGE_VER_RES + 42); + lv_obj_clear_flag(obj_base, LV_OBJ_FLAG_SCROLLABLE); + + uint32_t time_len = sleep_time[0].end_min - sleep_time[0].start_min; + uint32_t time_start = sleep_time[0].start_min; + lv_coord_t width_base = lv_obj_get_style_width(obj_base, 0); + + for (int i = 0; i < len; i++) { + uint8_t type_index = sleep_time[i].type; + lv_color_t color = lv_color_hex(ctx->sleep_type_color[type_index]); + + lv_obj_t* obj = lv_obj_create(obj_base); + lv_obj_set_style_radius(obj, 0, LV_PART_MAIN); + lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN); + lv_obj_set_style_bg_color(obj, color, LV_PART_MAIN); + + lv_coord_t width = width_base * (sleep_time[i].end_min - sleep_time[i].start_min) / time_len; + lv_coord_t x_ofs = width_base * (sleep_time[i].start_min - time_start) / time_len; + + lv_obj_set_size(obj, width, lv_obj_get_style_height(obj_base, 0)); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_align(obj, LV_ALIGN_TOP_LEFT, x_ofs, 0); + } + + lv_obj_t* label1 = lv_label_create(par); + lv_obj_set_style_text_font( + label1, + resource_get_font(BANDX_REGULAR_FONT "_15"), + LV_PART_MAIN); + lv_obj_set_style_text_color( + label1, + lv_color_make(0x80, 0x80, 0x80), + LV_PART_MAIN); + + uint32_t start_min = sleep_time[0].start_min; + lv_label_set_text_fmt(label1, "%02" LV_PRIu32 ":%02" LV_PRIu32, start_min / 60, start_min % 60); + lv_obj_align_to(label1, obj_base, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5); + + lv_obj_t* label2 = lv_label_create(par); + lv_obj_set_style_text_font( + label2, + resource_get_font(BANDX_REGULAR_FONT "_15"), + LV_PART_MAIN); + lv_obj_set_style_text_color( + label2, + lv_color_make(0x80, 0x80, 0x80), + LV_PART_MAIN); + + uint32_t end_min = sleep_time[0].end_min; + lv_label_set_text_fmt(label2, "%02" LV_PRIu32 ":%02" LV_PRIu32, end_min / 60, end_min % 60); + lv_obj_align_to(label2, obj_base, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 5); +} + +static void obj_sleep_info_create(lv_obj_t* par, sleep_info_t* sleep_info, int len) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + for (int i = 0; i < len; i++) { + lv_obj_t* obj_base = lv_obj_create(par); + lv_obj_remove_style_all(obj_base); + lv_obj_set_style_bg_opa(obj_base, LV_OPA_0, LV_PART_MAIN); + lv_obj_set_size(obj_base, PAGE_HOR_RES - 40, 50); + lv_obj_clear_flag(obj_base, LV_OBJ_FLAG_SCROLLABLE); + + lv_coord_t y_ofs = PAGE_VER_RES + 150 + (lv_obj_get_style_height(obj_base, 0) + 5) * i; + lv_obj_align(obj_base, LV_ALIGN_TOP_MID, 0, y_ofs); + + lv_obj_t* label1 = lv_label_create(obj_base); + lv_obj_set_style_text_font( + label1, + resource_get_font(BANDX_REGULAR_FONT "_20"), + LV_PART_MAIN); + lv_obj_set_style_text_color( + label1, + lv_color_make(0x80, 0x80, 0x80), + LV_PART_MAIN); + lv_label_set_text(label1, sleep_info[i].text); + lv_obj_align_to(label1, obj_base, LV_ALIGN_TOP_LEFT, 0, 0); + + lv_obj_t* label2 = lv_label_create(obj_base); + lv_obj_set_style_text_font( + label2, + resource_get_font(BANDX_REGULAR_FONT "_20"), + LV_PART_MAIN); + lv_obj_set_style_text_color( + label2, + lv_color_white(), + LV_PART_MAIN); + uint32_t time = sleep_time_get_sum( + ctx->sleep_time_grp, + SLEEP_TIME_CNT, + sleep_info[i].type); + lv_label_set_text_fmt(label2, "%" LV_PRIu32 "h %" LV_PRIu32 "min", time / 60, time % 60); + lv_obj_align_to(label2, obj_base, LV_ALIGN_BOTTOM_LEFT, 0, 0); + + lv_obj_t* label3 = lv_label_create(obj_base); + lv_obj_set_style_text_font( + label3, + resource_get_font(BANDX_REGULAR_FONT "_20"), + LV_PART_MAIN); + lv_obj_set_style_text_color( + label3, + lv_color_hex(ctx->sleep_type_color[sleep_info[i].type]), + LV_PART_MAIN); + uint32_t time_len = ctx->sleep_time_grp[0].end_min - ctx->sleep_time_grp[0].start_min; + lv_label_set_text_fmt(label3, "%" LV_PRIu32 "%%", time * 100 / time_len); + lv_obj_align_to(label3, obj_base, LV_ALIGN_BOTTOM_RIGHT, 0, 0); + } +} + +static void auto_event_create(page_ctx_t* ctx) +{ + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &ctx->img_down, LV_EVENT_CLICKED, 2000 }, + { &ctx->img_up, LV_EVENT_CLICKED, 2000 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 2000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } else if (dir == LV_DIR_BOTTOM) { + CONT_SLEEP_MOVE_DOWN(false, ctx->cont_sleep); + } else if (dir == LV_DIR_TOP) { + CONT_SLEEP_MOVE_DOWN(true, ctx->cont_sleep); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + uint32_t sleep_type_color[SLEEP_TYPE_MAX] = { + 0x3f71f5, + 0x023192, + 0x7ac943, + 0xff931e, + }; + + for (int i = 0; i < SLEEP_TYPE_MAX; i++) { + ctx->sleep_type_color[i] = sleep_type_color[i]; + } + + sleep_time_t sleep_time_grp[SLEEP_TIME_CNT] = { + { SLEEP_TYPE_SHALLOW, 29, 588 }, + { SLEEP_TYPE_DEEP, 61, 80 }, + { SLEEP_TYPE_DEEP, 120, 200 }, + { SLEEP_TYPE_REM, 80, 95 }, + { SLEEP_TYPE_REM, 250, 310 }, + { SLEEP_TYPE_AWAKE, 400, 410 }, + }; + + for (int i = 0; i < SLEEP_TIME_CNT; i++) { + ctx->sleep_time_grp[i] = sleep_time_grp[i]; + } + + sleep_info_t sleep_info_grp[SLEEP_INFO_CNT] = { + { "Shallow sleep", SLEEP_TYPE_SHALLOW }, + { "Deep sleep", SLEEP_TYPE_DEEP }, + { "REM", SLEEP_TYPE_REM }, + { "Awake", SLEEP_TYPE_AWAKE }, + }; + + for (int i = 0; i < SLEEP_INFO_CNT; i++) { + ctx->sleep_info_grp[i] = sleep_info_grp[i]; + } +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + cont_sleep_create(obj); + + img_arrow_create(ctx->cont_sleep); + img_sleep_create(ctx->cont_sleep); + label_score_create(ctx->cont_sleep); + label_total_time_create(ctx->cont_sleep); + + obj_sleep_time_create(ctx->cont_sleep, ctx->sleep_time_grp, SLEEP_TIME_CNT); + obj_sleep_info_create(ctx->cont_sleep, ctx->sleep_info_grp, SLEEP_INFO_CNT); + auto_event_create(ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(sleep); diff --git a/bandx/page/sport.c b/bandx/page/sport.c new file mode 100644 index 0000000000000000000000000000000000000000..3cfd43ccd9e81e8fcfa150f8788b02274bf64f81 --- /dev/null +++ b/bandx/page/sport.c @@ -0,0 +1,233 @@ +/** + * @file sport.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +/********************* + * DEFINES + *********************/ + +#define BTN_WIDTH 170 +#define BTN_HEIGHT 50 +#define SPORT_INFO_CNT 9 +#define EVENT_CNT 2 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char* img_src_name; + const char* sport_name; + uint32_t color; +} sport_info_t; + +typedef struct { + lv_fragment_t base; + lv_obj_t* list; + sport_info_t sport_info_grp[SPORT_INFO_CNT]; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void on_sport_icon_event(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + if (code == LV_EVENT_CLICKED) { + LV_LOG_WARN("NO match for this sport."); + } +} +static void on_sport_list_event(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + lv_obj_t* last_obj = lv_event_get_user_data(event); + if (code == LV_EVENT_VALUE_CHANGED) { + lv_obj_scroll_to_view(last_obj, LV_ANIM_ON); + } +} + +static void sport_title_create(lv_obj_t* par) +{ + lv_obj_t* obj = lv_obj_create(par); + lv_obj_remove_style_all(obj); + lv_obj_set_size(obj, PAGE_HOR_RES, 35); + lv_obj_align(obj, LV_ALIGN_TOP_MID, 0, 0); + + lv_obj_t* label = lv_label_create(obj); + lv_label_set_text(label, "Sports"); + lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_15"), LV_PART_MAIN); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); +} + +static void sport_list_create(page_ctx_t* ctx) +{ + ctx->list = lv_obj_create(ctx->base.obj); + lv_obj_remove_style_all(ctx->list); + lv_obj_set_size(ctx->list, PAGE_HOR_RES, PAGE_VER_RES - 40); + lv_obj_set_flex_flow(ctx->list, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(ctx->list, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(ctx->list, 10, 0); + lv_obj_align(ctx->list, LV_ALIGN_TOP_MID, 0, 40); + + lv_obj_t* obj_base = NULL; + + for (int i = 0; i < SPORT_INFO_CNT; i++) { + + obj_base = lv_btn_create(ctx->list); + lv_obj_set_style_bg_color(obj_base, lv_color_hex(0x666666), LV_PART_MAIN); + lv_obj_set_style_border_width(obj_base, 0, LV_PART_MAIN); + lv_obj_set_size(obj_base, BTN_WIDTH, BTN_HEIGHT); + lv_obj_set_style_pad_left(obj_base, 10, LV_PART_MAIN); + lv_obj_add_event(obj_base, on_sport_icon_event, LV_EVENT_ALL, NULL); + + lv_obj_t* img = lv_img_create(obj_base); + lv_img_set_src(img, resource_get_img(ctx->sport_info_grp[i].img_src_name)); + lv_obj_set_style_image_recolor_opa(img, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_image_recolor(img, lv_color_hex(ctx->sport_info_grp[i].color), LV_PART_MAIN); + lv_obj_align(img, LV_ALIGN_LEFT_MID, 0, 0); + + lv_obj_t* label = lv_label_create(obj_base); + lv_label_set_text(label, ctx->sport_info_grp[i].sport_name); + lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_15"), LV_PART_MAIN); + lv_obj_align_to(label, img, LV_ALIGN_OUT_RIGHT_MID, 4, 0); + } + lv_obj_add_event(ctx->list, on_sport_list_event, LV_EVENT_ALL, obj_base); +} + +static void auto_event_create(page_ctx_t* ctx) +{ + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &ctx->list, LV_EVENT_VALUE_CHANGED, 1000 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 2000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + sport_info_t sport_info_grp[SPORT_INFO_CNT] = { + { "icon_running", "Running", 0x9AFF9A }, + { "icon_stretching", "Stretching", 0xFFF68F }, + { "icon_riding", "Riding", 0xFFC1C1 }, + { "icon_skiing", "Skiing", 0xAB82FF }, + { "icon_yoga", "Yoga", 0x97FFFF }, + { "icon_tabletennis", "Table tennis", 0xFF83FA }, + { "icon_basketball", "Basketball", 0xFFA54F }, + { "icon_volleyball", "Volleyball", 0x87CEFA }, + { "icon_more_sports", "More sports", 0x4876FF }, + }; + + for (int i = 0; i < SPORT_INFO_CNT; i++) { + ctx->sport_info_grp[i] = sport_info_grp[i]; + } +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + sport_title_create(obj); + sport_list_create(ctx); + auto_event_create(ctx); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + page_ctx_t* ctx = (page_ctx_t*)self; + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(sport); diff --git a/bandx/page/stop_watch.c b/bandx/page/stop_watch.c new file mode 100644 index 0000000000000000000000000000000000000000..5ba72497873ef56025ebbd6a20883a11f96a7d0c --- /dev/null +++ b/bandx/page/stop_watch.c @@ -0,0 +1,417 @@ +/** + * @file stop_watch.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "page.h" + +#include "../utils/lv_obj_ext_func.h" + +/********************* + * DEFINES + *********************/ + +#define BTN_WIDTH 83 +#define BTN_HEIGHT 60 +#define BTN_CNT 2 +#define EVENT_CNT 10 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char* img_src; + lv_obj_t* btn; + lv_obj_t* img; +} btn_sw_t; + +typedef struct { + lv_obj_t* list_btn; + const char* text; + const uint16_t btn_val; +} list_btn_t; + +enum BtnGrpEnum { + BTN_START_PAUSE, + BTN_FLAG_RESET, +}; + +typedef struct { + lv_fragment_t base; + lv_obj_t* label_time; + lv_obj_t* list_history; + lv_timer_t* timer_sw_update; + btn_sw_t btn_grp[BTN_CNT]; + + lv_coord_t label_time_record_y; + lv_coord_t label_time_ready_y; + + bool sw_is_pause; + uint32_t sw_current_time; + uint32_t sw_interval_time; + uint32_t sw_last_time; + uint8_t sw_history_record_cnt; + lv_auto_event_data_t event_data[EVENT_CNT]; + lv_auto_event_t* auto_event; +} page_ctx_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void line_sw_create(lv_obj_t* par) +{ + static const lv_point_precise_t line_points[] = { { 0, 0 }, { 170, 0 } }; + + lv_obj_t* line = lv_line_create(par); + lv_line_set_points(line, line_points, ARRAY_SIZE(line_points)); + + lv_obj_set_style_line_color( + line, + lv_color_make(0x80, 0x80, 0x80), + LV_STATE_DEFAULT); + lv_obj_set_style_line_width(line, 2, LV_STATE_DEFAULT); + lv_obj_align_to(line, par, LV_ALIGN_TOP_MID, 0, 286); +} + +static void list_history_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* list = lv_list_create(par); + lv_obj_set_style_text_font(list, resource_get_font(BANDX_REGULAR_FONT "_20"), LV_PART_MAIN); + lv_obj_set_style_bg_color(list, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(list, 0, LV_PART_MAIN); + + lv_obj_set_size(list, 170, 170); + lv_obj_align(list, LV_ALIGN_CENTER, 0, 0); + ctx->list_history = list; +} + +static void label_time_create(lv_obj_t* par) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + lv_obj_t* label = lv_label_create(par); + lv_obj_set_style_text_font(label, resource_get_font(BANDX_REGULAR_FONT "_38"), LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_hex(0x87FFCE), LV_PART_MAIN); + + lv_label_set_text(label, "00:00.000"); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, ctx->label_time_ready_y); + lv_obj_set_width(label, 180); + lv_obj_set_style_border_color(label, lv_color_make(0x80, 0x80, 0x80), LV_PART_MAIN); + lv_obj_set_style_border_width(label, 2, LV_PART_MAIN); + lv_obj_set_style_border_side(label, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN); + ctx->label_time = label; +} + +static void sw_show_time(uint32_t ms, lv_obj_t* label_time) +{ + uint16_t min = 0, sec = 0, msec = 0; + min = ms / 60000; + sec = (ms - (min * 60000)) / 1000; + msec = ms - (sec * 1000) - (min * 60000); + lv_label_set_text_fmt(label_time, "%02d:%02d.%03d", min, sec, msec); +} + +static void sw_pause(page_ctx_t* ctx) +{ + if (ctx->sw_is_pause) { + ctx->sw_interval_time = lv_tick_get() - ctx->sw_last_time; + lv_timer_resume(ctx->timer_sw_update); + ctx->sw_is_pause = false; + } else { + ctx->sw_last_time = ctx->sw_current_time; + lv_timer_pause(ctx->timer_sw_update); + ctx->sw_is_pause = true; + } +} + +static void sw_reset(page_ctx_t* ctx) +{ + ctx->sw_last_time = 0; + ctx->sw_current_time = 0; + ctx->sw_interval_time = 0; + ctx->sw_is_pause = true; + ctx->sw_history_record_cnt = 0; + lv_timer_pause(ctx->timer_sw_update); + sw_show_time(ctx->sw_current_time, ctx->label_time); + lv_obj_clean(ctx->list_history); + + if (lv_obj_get_y(ctx->label_time) == ctx->label_time_record_y) { + LV_OBJ_ADD_ANIM(ctx->label_time, y, ctx->label_time_ready_y, 500); + } +} + +static void sw_update(lv_timer_t* timer) +{ + page_ctx_t* ctx = lv_timer_get_user_data(timer); + + ctx->sw_current_time = lv_tick_get() - ctx->sw_interval_time; + sw_show_time(ctx->sw_current_time, ctx->label_time); +} + +static void sw_record(page_ctx_t* ctx) +{ + lv_obj_t* list_btn; + lv_obj_t* spangroup; + uint16_t min = 0, sec = 0, msec = 0; + + if (ctx->sw_history_record_cnt < 10 && !ctx->sw_is_pause) { + min = ctx->sw_current_time / 60000; + sec = (ctx->sw_current_time - (min * 60000)) / 1000; + msec = ctx->sw_current_time - (sec * 1000) - (min * 60000); + + char cnt_buf[8]; + char time_buf[64]; + + lv_snprintf(cnt_buf, sizeof(cnt_buf), "%d. ", ctx->sw_history_record_cnt + 1); + lv_snprintf(time_buf, sizeof(time_buf), "%02d:%02d.%03d", min, sec, msec); + + list_btn = lv_list_add_btn(ctx->list_history, NULL, NULL); + lv_obj_clear_flag(list_btn, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_style_border_width(list_btn, 2, LV_STATE_DEFAULT); + lv_obj_set_style_pad_left(list_btn, 0, LV_PART_MAIN); + + spangroup = lv_spangroup_create(list_btn); + + lv_span_t* cnt_span = lv_spangroup_new_span(spangroup); + lv_span_set_text(cnt_span, cnt_buf); + lv_style_set_text_color(&cnt_span->style, lv_color_hex(0x87FFCE)); + + lv_span_t* time_span = lv_spangroup_new_span(spangroup); + lv_span_set_text(time_span, time_buf); + lv_style_set_text_color(&time_span->style, lv_color_hex(0xffffff)); + + lv_obj_add_state(list_btn, LV_STATE_FOCUSED); + lv_obj_set_style_bg_color(list_btn, lv_color_black(), 0); + lv_obj_set_style_text_decor( + list_btn, + LV_TEXT_DECOR_NONE, + LV_STATE_FOCUSED); + ctx->sw_history_record_cnt++; + } + + if (lv_obj_get_y(ctx->label_time) == ctx->label_time_ready_y) { + LV_OBJ_ADD_ANIM(ctx->label_time, y, ctx->label_time_record_y, 500); + } +} + +static void btn_grp_event_handler(lv_event_t* event) +{ + lv_event_code_t code = lv_event_get_code(event); + lv_obj_t* obj = lv_event_get_current_target_obj(event); + page_ctx_t* ctx = (page_ctx_t*)lv_event_get_user_data(event); + + if (code == LV_EVENT_CLICKED) { + lv_obj_t* img = lv_obj_get_child(obj, 0); + const char* img_src = lv_img_get_src(img); + + if (obj == ctx->btn_grp[BTN_START_PAUSE].btn) { + sw_pause(ctx); + if (ctx->sw_is_pause) { + lv_img_set_src(ctx->btn_grp[BTN_START_PAUSE].img, resource_get_img("icon_start")); + lv_img_set_src(ctx->btn_grp[BTN_FLAG_RESET].img, resource_get_img("icon_reset")); + } else { + lv_img_set_src(ctx->btn_grp[BTN_START_PAUSE].img, resource_get_img("icon_pause")); + lv_img_set_src(ctx->btn_grp[BTN_FLAG_RESET].img, resource_get_img("icon_flag")); + lv_obj_clear_state(ctx->btn_grp[BTN_FLAG_RESET].btn, LV_STATE_DISABLED); + } + } else if (obj == ctx->btn_grp[BTN_FLAG_RESET].btn) { + if (lv_strcmp(img_src, resource_get_img("icon_flag")) == 0) { + sw_record(ctx); + } else { + if (ctx->sw_is_pause) { + sw_reset(ctx); + lv_obj_add_state(ctx->btn_grp[BTN_FLAG_RESET].btn, LV_STATE_DISABLED); + ctx->sw_history_record_cnt = 0; + } + } + } + } +} + +static void btn_grp_create(lv_obj_t* par, btn_sw_t* btn_sw, int len) +{ + page_ctx_t* ctx = (page_ctx_t*)lv_obj_get_user_data(par); + + for (int i = 0; i < len; i++) { + lv_obj_t* btn = lv_btn_create(par); + lv_obj_set_size(btn, BTN_WIDTH, BTN_HEIGHT); + + lv_coord_t x_ofs = BTN_WIDTH / 2 + 3; + lv_obj_align(btn, LV_ALIGN_TOP_MID, i == 0 ? -x_ofs : x_ofs, 300); + lv_obj_set_style_border_color(btn, lv_color_black(), LV_STATE_DEFAULT); + lv_obj_set_style_border_width(btn, 2, LV_STATE_DEFAULT); + lv_obj_set_style_bg_color( + btn, + lv_palette_main(LV_PALETTE_GREY), + LV_STATE_PRESSED || LV_STATE_DISABLED); + lv_obj_set_style_bg_color( + btn, + lv_color_make(0x87, 0xFF, 0xCE), + LV_STATE_DEFAULT); + lv_obj_set_style_radius(btn, 10, LV_PART_MAIN); + lv_obj_add_event(btn, btn_grp_event_handler, LV_EVENT_ALL, ctx); + + lv_obj_t* img = lv_img_create(btn); + lv_img_set_src(img, resource_get_img(btn_sw[i].img_src)); + lv_obj_align_to(img, btn, LV_ALIGN_CENTER, 0, 0); + + btn_sw[i].btn = btn; + btn_sw[i].img = img; + } +} + +static void auto_event_create(page_ctx_t* ctx) +{ + btn_sw_t* btn_sw = ctx->btn_grp; + lv_auto_event_data_t ae_grp[EVENT_CNT] = { + { &(btn_sw[BTN_START_PAUSE].btn), LV_EVENT_CLICKED, 2000 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 453 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 888 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 1605 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 785 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 1200 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 1456 }, + { &(btn_sw[BTN_START_PAUSE].btn), LV_EVENT_CLICKED, 2000 }, + { &(btn_sw[BTN_FLAG_RESET].btn), LV_EVENT_CLICKED, 1000 }, + { &ctx->base.obj, LV_EVENT_LEAVE, 2000 }, + }; + for (int i = 0; i < EVENT_CNT; i++) { + ctx->event_data[i] = ae_grp[i]; + } + + AUTO_EVENT_CREATE(ctx->auto_event, ctx->event_data); +} + +static void on_root_event(lv_event_t* e) +{ + lv_obj_t* root = lv_event_get_current_target_obj(e); + lv_event_code_t code = lv_event_get_code(e); + page_ctx_t* ctx = lv_obj_get_user_data(root); + + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + if (dir == LV_DIR_RIGHT) { + lv_obj_send_event(root, LV_EVENT_LEAVE, NULL); + } + } else if (code == LV_EVENT_LEAVE) { + page_pop(&ctx->base); + } +} + +static void on_page_construct(lv_fragment_t* self, void* args) +{ + LV_LOG_INFO("self: %p args: %p", self, args); + + page_ctx_t* ctx = (page_ctx_t*)self; + + btn_sw_t btn_grp[BTN_CNT] = { + { "icon_start" }, + { "icon_reset" }, + }; + + for (int i = 0; i < BTN_CNT; i++) { + ctx->btn_grp[i] = btn_grp[i]; + } + + ctx->label_time_record_y = 18; + ctx->label_time_ready_y = 64; + + ctx->sw_is_pause = true; + ctx->sw_current_time = 0; + ctx->sw_interval_time = 0; + ctx->sw_last_time = 0; + ctx->sw_history_record_cnt = 0; +} + +static void on_page_destruct(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_attached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static void on_page_detached(lv_fragment_t* self) +{ + LV_LOG_INFO("self: %p", self); +} + +static lv_obj_t* on_page_create(lv_fragment_t* self, lv_obj_t* container) +{ + LV_LOG_INFO("self: %p container: %p", self, container); + + lv_obj_t* root = lv_obj_create(container); + lv_obj_remove_style_all(root); + lv_obj_add_style(root, resource_get_style("root_def"), 0); + lv_obj_add_event(root, on_root_event, LV_EVENT_ALL, NULL); + lv_obj_clear_flag(root, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_user_data(root, self); + return root; +} + +static void on_page_created(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + ctx->timer_sw_update = lv_timer_create(sw_update, 51, ctx); + + list_history_create(obj); + label_time_create(obj); + btn_grp_create(obj, ctx->btn_grp, BTN_CNT); + line_sw_create(obj); + auto_event_create(ctx); + + ctx->sw_is_pause ? lv_timer_pause(ctx->timer_sw_update) : lv_timer_resume(ctx->timer_sw_update); +} + +static void on_page_will_delete(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); + + page_ctx_t* ctx = (page_ctx_t*)self; + + lv_timer_del(ctx->timer_sw_update); + AUTO_EVENT_DELETE(ctx->auto_event); +} + +static void on_page_deleted(lv_fragment_t* self, lv_obj_t* obj) +{ + LV_LOG_INFO("self: %p obj: %p", self, obj); +} + +static bool on_page_event(lv_fragment_t* self, int code, void* user_data) +{ + LV_LOG_INFO("self: %p code: %d user_data: %p", self, code, user_data); + return false; +} + +PAGE_CLASS_DEF(stop_watch); diff --git a/bandx/resource/font/assets/AlibabaPuHuiTi-3-55-Regular.ttf b/bandx/resource/font/assets/AlibabaPuHuiTi-3-55-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a6eaf3613ee1160caf604ab3f11b303fdb5f8668 Binary files /dev/null and b/bandx/resource/font/assets/AlibabaPuHuiTi-3-55-Regular.ttf differ diff --git a/bandx/resource/font/assets/AlibabaPuHuiTi-3-95-ExtraBold.ttf b/bandx/resource/font/assets/AlibabaPuHuiTi-3-95-ExtraBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..79f26640f72fa5b81f9ebf915cd29319eba487d7 Binary files /dev/null and b/bandx/resource/font/assets/AlibabaPuHuiTi-3-95-ExtraBold.ttf differ diff --git a/bandx/resource/font/font.inc b/bandx/resource/font/font.inc new file mode 100644 index 0000000000000000000000000000000000000000..da9bb9defa752d7fe61ce969a75a17ec62ada08c --- /dev/null +++ b/bandx/resource/font/font.inc @@ -0,0 +1,8 @@ +/* font list */ +FONT_DEF(AlibabaPuHuiTi-3-55-Regular, 15) +FONT_DEF(AlibabaPuHuiTi-3-55-Regular, 20) +FONT_DEF(AlibabaPuHuiTi-3-55-Regular, 38) +FONT_DEF(AlibabaPuHuiTi-3-55-Regular, 72) +FONT_DEF(AlibabaPuHuiTi-3-95-ExtraBold, 23) +FONT_DEF(AlibabaPuHuiTi-3-95-ExtraBold, 28) +FONT_DEF(AlibabaPuHuiTi-3-95-ExtraBold, 110) \ No newline at end of file diff --git a/bandx/resource/image/assets/arrow_down.png b/bandx/resource/image/assets/arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..90e532f8b777e4bf45bfdb8cb2f6fdfaa11146de Binary files /dev/null and b/bandx/resource/image/assets/arrow_down.png differ diff --git a/bandx/resource/image/assets/arrow_up.png b/bandx/resource/image/assets/arrow_up.png new file mode 100644 index 0000000000000000000000000000000000000000..b93a69d3f0235b06ffa069c7d00aff4c080f6e10 Binary files /dev/null and b/bandx/resource/image/assets/arrow_up.png differ diff --git a/bandx/resource/image/assets/centigrade.png b/bandx/resource/image/assets/centigrade.png new file mode 100644 index 0000000000000000000000000000000000000000..0eb787adf935d104370ce00d2b9ce282747b21fd Binary files /dev/null and b/bandx/resource/image/assets/centigrade.png differ diff --git a/bandx/resource/image/assets/flashlight.png b/bandx/resource/image/assets/flashlight.png new file mode 100644 index 0000000000000000000000000000000000000000..45a6a78609a2e8504f46e7008f48ad2d416ef0ff Binary files /dev/null and b/bandx/resource/image/assets/flashlight.png differ diff --git a/bandx/resource/image/assets/heart.png b/bandx/resource/image/assets/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..59f72d3a58fd758e2929f7ff1885bc641604bd36 Binary files /dev/null and b/bandx/resource/image/assets/heart.png differ diff --git a/bandx/resource/image/assets/heart_color.png b/bandx/resource/image/assets/heart_color.png new file mode 100644 index 0000000000000000000000000000000000000000..c0117de706f65b467f72eeaa5617a5335875212a Binary files /dev/null and b/bandx/resource/image/assets/heart_color.png differ diff --git a/bandx/resource/image/assets/heart_rate.png b/bandx/resource/image/assets/heart_rate.png new file mode 100644 index 0000000000000000000000000000000000000000..393544fa58b4ef0fce0ee83d6291a6e1f976a1a9 Binary files /dev/null and b/bandx/resource/image/assets/heart_rate.png differ diff --git a/bandx/resource/image/assets/icon_basketball.png b/bandx/resource/image/assets/icon_basketball.png new file mode 100644 index 0000000000000000000000000000000000000000..68973a0eb939e25a20e801cb6614bfccc8b5f562 Binary files /dev/null and b/bandx/resource/image/assets/icon_basketball.png differ diff --git a/bandx/resource/image/assets/icon_battery.png b/bandx/resource/image/assets/icon_battery.png new file mode 100644 index 0000000000000000000000000000000000000000..546096f08e82f61ff34d089db66044965f7fc3cb Binary files /dev/null and b/bandx/resource/image/assets/icon_battery.png differ diff --git a/bandx/resource/image/assets/icon_bluetooth.png b/bandx/resource/image/assets/icon_bluetooth.png new file mode 100644 index 0000000000000000000000000000000000000000..9b5fe0c50fc334d484833df8b5a6bae23c4ed666 Binary files /dev/null and b/bandx/resource/image/assets/icon_bluetooth.png differ diff --git a/bandx/resource/image/assets/icon_flag.png b/bandx/resource/image/assets/icon_flag.png new file mode 100644 index 0000000000000000000000000000000000000000..3b4c8e94187417e93223ce0639ebfc86806ff503 Binary files /dev/null and b/bandx/resource/image/assets/icon_flag.png differ diff --git a/bandx/resource/image/assets/icon_minus.png b/bandx/resource/image/assets/icon_minus.png new file mode 100644 index 0000000000000000000000000000000000000000..db7467c5c7534e0ae8b1ff328a0203b86ee3bdcc Binary files /dev/null and b/bandx/resource/image/assets/icon_minus.png differ diff --git a/bandx/resource/image/assets/icon_more_sports.png b/bandx/resource/image/assets/icon_more_sports.png new file mode 100644 index 0000000000000000000000000000000000000000..f98e4234800defb0e1362ad94e3a531814b59c09 Binary files /dev/null and b/bandx/resource/image/assets/icon_more_sports.png differ diff --git a/bandx/resource/image/assets/icon_next.png b/bandx/resource/image/assets/icon_next.png new file mode 100644 index 0000000000000000000000000000000000000000..a3545ce2489c2a387775c1f0da6ebe51f23530f5 Binary files /dev/null and b/bandx/resource/image/assets/icon_next.png differ diff --git a/bandx/resource/image/assets/icon_pause.png b/bandx/resource/image/assets/icon_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ac579c25e5e1feb8b2884091843efc96c832f5 Binary files /dev/null and b/bandx/resource/image/assets/icon_pause.png differ diff --git a/bandx/resource/image/assets/icon_plus.png b/bandx/resource/image/assets/icon_plus.png new file mode 100644 index 0000000000000000000000000000000000000000..27f41d65a1f7e44d4719809169380721a8890c7c Binary files /dev/null and b/bandx/resource/image/assets/icon_plus.png differ diff --git a/bandx/resource/image/assets/icon_prev.png b/bandx/resource/image/assets/icon_prev.png new file mode 100644 index 0000000000000000000000000000000000000000..2f3d62a057aa7d82b604a06bd2a9f148ca89fd67 Binary files /dev/null and b/bandx/resource/image/assets/icon_prev.png differ diff --git a/bandx/resource/image/assets/icon_reset.png b/bandx/resource/image/assets/icon_reset.png new file mode 100644 index 0000000000000000000000000000000000000000..c61ea2ef94b5bc384b0e9ad8278e15a17ca109cc Binary files /dev/null and b/bandx/resource/image/assets/icon_reset.png differ diff --git a/bandx/resource/image/assets/icon_riding.png b/bandx/resource/image/assets/icon_riding.png new file mode 100644 index 0000000000000000000000000000000000000000..70d607bbd459386ac9ad407a35f9c5ea9d10fb11 Binary files /dev/null and b/bandx/resource/image/assets/icon_riding.png differ diff --git a/bandx/resource/image/assets/icon_running.png b/bandx/resource/image/assets/icon_running.png new file mode 100644 index 0000000000000000000000000000000000000000..0623c81cbdf433eed2131920402f0eadc146b43e Binary files /dev/null and b/bandx/resource/image/assets/icon_running.png differ diff --git a/bandx/resource/image/assets/icon_shadow_down.png b/bandx/resource/image/assets/icon_shadow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..47c48985ec81752c293018bd3f85cfbb3c08d6a5 Binary files /dev/null and b/bandx/resource/image/assets/icon_shadow_down.png differ diff --git a/bandx/resource/image/assets/icon_shadow_up.png b/bandx/resource/image/assets/icon_shadow_up.png new file mode 100644 index 0000000000000000000000000000000000000000..82af8cf81e5a2643d875d68f3d64aa1fef49ebfe Binary files /dev/null and b/bandx/resource/image/assets/icon_shadow_up.png differ diff --git a/bandx/resource/image/assets/icon_skiing.png b/bandx/resource/image/assets/icon_skiing.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2b04ce2af243e70f1be5d51b9c212dbcaca515 Binary files /dev/null and b/bandx/resource/image/assets/icon_skiing.png differ diff --git a/bandx/resource/image/assets/icon_start.png b/bandx/resource/image/assets/icon_start.png new file mode 100644 index 0000000000000000000000000000000000000000..5006892b7dedefcfa2cc52560f322f3770cfa594 Binary files /dev/null and b/bandx/resource/image/assets/icon_start.png differ diff --git a/bandx/resource/image/assets/icon_stretching.png b/bandx/resource/image/assets/icon_stretching.png new file mode 100644 index 0000000000000000000000000000000000000000..ce8a6740c7826fb97d0f4ceb9e67f72694b7d3e4 Binary files /dev/null and b/bandx/resource/image/assets/icon_stretching.png differ diff --git a/bandx/resource/image/assets/icon_tabletennis.png b/bandx/resource/image/assets/icon_tabletennis.png new file mode 100644 index 0000000000000000000000000000000000000000..97de39a2b067a250e059b675ba738efde9a7a0dd Binary files /dev/null and b/bandx/resource/image/assets/icon_tabletennis.png differ diff --git a/bandx/resource/image/assets/icon_volleyball.png b/bandx/resource/image/assets/icon_volleyball.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1891fbdab1680a4ba8c8824d4bea6da27e7f4a Binary files /dev/null and b/bandx/resource/image/assets/icon_volleyball.png differ diff --git a/bandx/resource/image/assets/icon_volume_add.png b/bandx/resource/image/assets/icon_volume_add.png new file mode 100644 index 0000000000000000000000000000000000000000..84c483a31d7234fff4769c859177ebd05a87c8f6 Binary files /dev/null and b/bandx/resource/image/assets/icon_volume_add.png differ diff --git a/bandx/resource/image/assets/icon_volume_reduce.png b/bandx/resource/image/assets/icon_volume_reduce.png new file mode 100644 index 0000000000000000000000000000000000000000..42633fc4606387fbb5842dd188f9a63344c5412e Binary files /dev/null and b/bandx/resource/image/assets/icon_volume_reduce.png differ diff --git a/bandx/resource/image/assets/icon_yoga.png b/bandx/resource/image/assets/icon_yoga.png new file mode 100644 index 0000000000000000000000000000000000000000..376448d02fe15f0b9f23b1251aeb0915c19bf969 Binary files /dev/null and b/bandx/resource/image/assets/icon_yoga.png differ diff --git a/bandx/resource/image/assets/music.png b/bandx/resource/image/assets/music.png new file mode 100644 index 0000000000000000000000000000000000000000..641e09c1df4a6a034308b4f3fa564a4c41ab78d2 Binary files /dev/null and b/bandx/resource/image/assets/music.png differ diff --git a/bandx/resource/image/assets/num_shadow.png b/bandx/resource/image/assets/num_shadow.png new file mode 100644 index 0000000000000000000000000000000000000000..30174950769ed56a9e32c096f540061bfb045661 Binary files /dev/null and b/bandx/resource/image/assets/num_shadow.png differ diff --git a/bandx/resource/image/assets/settings.png b/bandx/resource/image/assets/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..96b0721bb74a8f7f13bbe38f70784aa68b03db8a Binary files /dev/null and b/bandx/resource/image/assets/settings.png differ diff --git a/bandx/resource/image/assets/sleep.png b/bandx/resource/image/assets/sleep.png new file mode 100644 index 0000000000000000000000000000000000000000..c34f3fe816a36207365275901ed99a79f9e1a4a6 Binary files /dev/null and b/bandx/resource/image/assets/sleep.png differ diff --git a/bandx/resource/image/assets/sport.png b/bandx/resource/image/assets/sport.png new file mode 100644 index 0000000000000000000000000000000000000000..8bf1f8ac29a8af7881b3b3cba3657072069929d0 Binary files /dev/null and b/bandx/resource/image/assets/sport.png differ diff --git a/bandx/resource/image/assets/step.png b/bandx/resource/image/assets/step.png new file mode 100644 index 0000000000000000000000000000000000000000..708614c1450adddcebefb68111c75812531d4563 Binary files /dev/null and b/bandx/resource/image/assets/step.png differ diff --git a/bandx/resource/image/assets/stop_watch.png b/bandx/resource/image/assets/stop_watch.png new file mode 100644 index 0000000000000000000000000000000000000000..acc2e9521065c3bc27f90393ac8a96c62c98cce6 Binary files /dev/null and b/bandx/resource/image/assets/stop_watch.png differ diff --git a/bandx/resource/image/assets/weather.png b/bandx/resource/image/assets/weather.png new file mode 100644 index 0000000000000000000000000000000000000000..77dc8dbc4443a0d23f3407bc46845531d97d103d Binary files /dev/null and b/bandx/resource/image/assets/weather.png differ diff --git a/bandx/resource/image/img_src.inc b/bandx/resource/image/img_src.inc new file mode 100644 index 0000000000000000000000000000000000000000..c373bb160450b6fd27c5d8e432da74694815dbd8 --- /dev/null +++ b/bandx/resource/image/img_src.inc @@ -0,0 +1,39 @@ +/* img list */ +IMG_DEF(arrow_down) +IMG_DEF(arrow_up) +IMG_DEF(icon_battery) +IMG_DEF(icon_bluetooth) +IMG_DEF(centigrade) +IMG_DEF(flashlight) +IMG_DEF(heart_color) +IMG_DEF(heart_rate) +IMG_DEF(heart) +IMG_DEF(icon_flag) +IMG_DEF(icon_minus) +IMG_DEF(icon_next) +IMG_DEF(icon_pause) +IMG_DEF(icon_plus) +IMG_DEF(icon_prev) +IMG_DEF(icon_reset) +IMG_DEF(icon_shadow_down) +IMG_DEF(icon_shadow_up) +IMG_DEF(icon_start) +IMG_DEF(icon_volume_add) +IMG_DEF(icon_volume_reduce) +IMG_DEF(music) +IMG_DEF(num_shadow) +IMG_DEF(settings) +IMG_DEF(sleep) +IMG_DEF(sport) +IMG_DEF(step) +IMG_DEF(stop_watch) +IMG_DEF(weather) +IMG_DEF(icon_more_sports) +IMG_DEF(icon_running) +IMG_DEF(icon_stretching) +IMG_DEF(icon_riding) +IMG_DEF(icon_skiing) +IMG_DEF(icon_yoga) +IMG_DEF(icon_tabletennis) +IMG_DEF(icon_basketball) +IMG_DEF(icon_volleyball) diff --git a/bandx/resource/resource.c b/bandx/resource/resource.c new file mode 100644 index 0000000000000000000000000000000000000000..4b7088052c24ae799c72d508c0ce8efaec0dac8e --- /dev/null +++ b/bandx/resource/resource.c @@ -0,0 +1,154 @@ +/** + * @file resource.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "resource.h" + +/********************* + * DEFINES + *********************/ + +#define ARRAY_SIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0])) + +/* import images*/ +#define IMG_DEF(NAME) LV_IMG_DECLARE(img_src_##NAME); +#include "image/img_src.inc" +#undef IMG_DEF + +#define FONT_BASE_PATH "/font/" +#define IMG_BASE_PATH "/image/" + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char* key; + const char* img_src; +} resource_img_t; + +typedef struct { + const char* key; + const lv_font_t* font; +} resource_font_t; + +typedef struct { + const char* key; + lv_style_t style; +} resource_style_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +#define IMG_DEF(NAME) { #NAME, CONFIG_BANDX_BASE_PATH IMG_BASE_PATH #NAME ".png" }, +static const resource_img_t g_img_resource_map[] = { +#include "image/img_src.inc" +}; +#undef IMG_DEF + +#define FONT_DEF(NAME, SIZE) { "default", LV_FONT_DEFAULT }, +static resource_font_t g_font_resource_map[] = { +#include "font/font.inc" +}; +#undef FONT_DEF + +#define STYLE_DEF(NAME) { "empty" }, +static resource_style_t g_style_resource_map[] = { +#include "style/style.inc" +}; +#undef STYLE_DEF + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void resource_init(void) +{ + /* create fonts */ + int font_index = 0; +#define FONT_DEF(NAME, SIZE) \ + do { \ + lv_font_t* font = lv_freetype_font_create(CONFIG_BANDX_BASE_PATH FONT_BASE_PATH #NAME ".ttf", \ + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, \ + SIZE, \ + LV_FREETYPE_FONT_STYLE_NORMAL); \ + if (font) { \ + g_font_resource_map[font_index].key = #NAME "_" #SIZE; \ + g_font_resource_map[font_index].font = font; \ + font_index++; \ + } else { \ + LV_LOG_WARN("font_" #NAME "_" #SIZE "not found"); \ + } \ + } while (0); +#include "font/font.inc" +#undef FONT_DEF + LV_LOG_USER("create %d fonts", font_index); + + /* init styles */ + int style_index = 0; +#define STYLE_DEF(NAME) \ + do { \ + extern void style_##NAME##_init(lv_style_t* style); \ + g_style_resource_map[style_index].key = #NAME; \ + lv_style_init(&g_style_resource_map[style_index].style); \ + style_##NAME##_init(&g_style_resource_map[style_index].style); \ + style_index++; \ + } while (0); +#include "style/style.inc" +#undef STYLE_DEF + LV_LOG_USER("create %d styles", style_index); +} + +const lv_font_t* resource_get_font(const char* key) +{ + for (int i = 0; i < ARRAY_SIZE(g_font_resource_map); i++) { + if (lv_strcmp(key, g_font_resource_map[i].key) == 0) { + return g_font_resource_map[i].font; + } + } + + LV_LOG_WARN("key %s not found", key); + return LV_FONT_DEFAULT; +} + +const void* resource_get_img(const char* key) +{ + for (int i = 0; i < ARRAY_SIZE(g_img_resource_map); i++) { + if (lv_strcmp(key, g_img_resource_map[i].key) == 0) { + return g_img_resource_map[i].img_src; + } + } + + LV_LOG_WARN("key %s not found", key); + return LV_SYMBOL_IMAGE; +} + +lv_style_t* resource_get_style(const char* key) +{ + for (int i = 0; i < ARRAY_SIZE(g_style_resource_map); i++) { + if (lv_strcmp(key, g_style_resource_map[i].key) == 0) { + return &g_style_resource_map[i].style; + } + } + + LV_LOG_WARN("key %s not found", key); + return &g_style_resource_map[0].style; +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/resource/resource.h b/bandx/resource/resource.h new file mode 100644 index 0000000000000000000000000000000000000000..0fe0a7b5617d8dfd6696394f7a104def389bb047 --- /dev/null +++ b/bandx/resource/resource.h @@ -0,0 +1,65 @@ +/** + * @file resource.h + * + */ + +#ifndef RESOURCE_H +#define RESOURCE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include <lvgl/lvgl.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the resource manager. + */ +void resource_init(void); + +/** + * Get a font resource by key. + * @param key The key associated with the desired font. + * @return A pointer to the font resource, or NULL if not found. + */ +const lv_font_t* resource_get_font(const char* key); + +/** + * Get an image resource by key. + * @param key The key associated with the desired image. + * @return A pointer to the image resource, or NULL if not found. + */ +const void* resource_get_img(const char* key); + +/** + * Get a style resource by key. + * @param key The key associated with the desired style. + * @return A pointer to the style resource, or NULL if not found. + */ +lv_style_t* resource_get_style(const char* key); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*RESOURCE_H*/ diff --git a/bandx/resource/style/style.c b/bandx/resource/style/style.c new file mode 100644 index 0000000000000000000000000000000000000000..c3e02f2f3b9a3e3201fc7b2597167495600303fc --- /dev/null +++ b/bandx/resource/style/style.c @@ -0,0 +1,62 @@ +/** + * @file style.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void style_empty_init(lv_style_t* style) +{ +} + +void style_root_def_init(lv_style_t* style) +{ + lv_style_set_bg_color(style, lv_color_black()); + lv_style_set_bg_opa(style, LV_OPA_COVER); + lv_style_set_size(style, LV_PCT(100), LV_PCT(100)); +} + +void style_btn_trans_init(lv_style_t* style) +{ + static const lv_style_prop_t props[] = { + LV_STYLE_BG_COLOR, + LV_STYLE_TRANSFORM_WIDTH, + LV_STYLE_TRANSFORM_HEIGHT, + LV_STYLE_PROP_INV + }; + static lv_style_transition_dsc_t dsc; + lv_style_transition_dsc_init(&dsc, props, lv_anim_path_overshoot, 200, 0, NULL); + lv_style_set_transition(style, &dsc); +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/resource/style/style.inc b/bandx/resource/style/style.inc new file mode 100644 index 0000000000000000000000000000000000000000..5a7c1b120794fcf2d2d820cac7006fa4a0b904c7 --- /dev/null +++ b/bandx/resource/style/style.inc @@ -0,0 +1,4 @@ +/* style list */ +STYLE_DEF(empty) +STYLE_DEF(root_def) +STYLE_DEF(btn_trans) diff --git a/bandx/utils/lv_anim_label.c b/bandx/utils/lv_anim_label.c new file mode 100755 index 0000000000000000000000000000000000000000..61f42b8bb8adec174825341fcb3d7fafddfe0e11 --- /dev/null +++ b/bandx/utils/lv_anim_label.c @@ -0,0 +1,349 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_anim_label.h" + +/********************* + * DEFINES + *********************/ +#define MY_CLASS &lv_anim_label_class + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_anim_label_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj); +static void lv_anim_label_set_x(void* obj, int32_t x); +static void lv_anim_label_set_y(void* obj, int32_t y); + +/********************** + * STATIC VARIABLES + **********************/ + +const lv_obj_class_t lv_anim_label_class = { + .constructor_cb = lv_anim_label_constructor, + .instance_size = sizeof(lv_anim_label_t), + .base_class = &lv_obj_class +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t* lv_anim_label_create(lv_obj_t* parent) +{ + lv_obj_t* obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + return obj; +} + +void lv_anim_label_set_dir(lv_obj_t* obj, lv_dir_t dir) +{ + lv_anim_label_set_enter_dir(obj, dir); + lv_anim_label_set_exit_dir(obj, dir); +} + +void lv_anim_label_set_enter_dir(lv_obj_t* obj, lv_dir_t dir) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + alabel->enter_dir = dir; +} + +void lv_anim_label_set_exit_dir(lv_obj_t* obj, lv_dir_t dir) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + alabel->exit_dir = dir; +} + +void lv_anim_label_set_time(lv_obj_t* obj, uint32_t duration) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + alabel->duration = duration; +} + +void lv_anim_label_set_path(lv_obj_t* obj, lv_anim_path_cb_t path_cb) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + alabel->path_cb = path_cb; +} + +void lv_anim_label_add_style(lv_obj_t* obj, lv_style_t* style) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + lv_obj_add_style(alabel->label_1, style, LV_PART_MAIN); + lv_obj_add_style(alabel->label_2, style, LV_PART_MAIN); +} + +void lv_anim_label_set_custom_enter_anim(lv_obj_t* obj, const lv_anim_t* a) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + if (a != NULL) { + alabel->a_enter = *a; + } +} + +void lv_anim_label_set_custom_exit_anim(lv_obj_t* obj, const lv_anim_t* a) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + if (a != NULL) { + alabel->a_exit = *a; + } +} + +static void lv_anim_label_start_anim( + lv_obj_t* label, + lv_dir_t dir, + int32_t start, + int32_t end, + uint32_t duration, + lv_anim_path_cb_t path_cb) +{ + lv_anim_exec_xcb_t exec_xcb; + + if (dir & LV_DIR_HOR) { + exec_xcb = lv_anim_label_set_x; + } else if (dir & LV_DIR_VER) { + exec_xcb = lv_anim_label_set_y; + } else { + return; + } + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, label); + lv_anim_set_values(&a, start, end); + lv_anim_set_time(&a, duration); + lv_anim_set_path_cb(&a, path_cb); + lv_anim_set_exec_cb(&a, exec_xcb); + lv_anim_start(&a); +} + +void lv_anim_label_push_text(lv_obj_t* obj, const char* txt) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + lv_obj_t* label_exit = alabel->label_act; + lv_obj_t* label_enter = alabel->label_act == alabel->label_1 ? alabel->label_2 : alabel->label_1; + lv_dir_t enter_dir = alabel->enter_dir; + lv_dir_t exit_dir = alabel->exit_dir; + + lv_label_set_text(label_enter, txt); + lv_obj_update_layout(label_enter); + + lv_coord_t obj_width = lv_obj_get_width(obj); + lv_coord_t obj_height = lv_obj_get_height(obj); + + /* enter */ + lv_coord_t label_enter_width = lv_obj_get_width(label_enter); + lv_coord_t label_enter_height = lv_obj_get_height(label_enter); + lv_coord_t label_enter_end_x = (obj_width - label_enter_width) / 2; + lv_coord_t label_enter_end_y = (obj_height - label_enter_height) / 2; + + if (enter_dir & LV_DIR_HOR) { + lv_obj_set_y(label_enter, label_enter_end_y); + lv_coord_t start_x = label_enter_end_x; + start_x += ((enter_dir == LV_DIR_LEFT) ? -obj_width : obj_width); + lv_anim_label_start_anim( + label_enter, + enter_dir, + start_x, + label_enter_end_x, + alabel->duration, + alabel->path_cb); + } else if (enter_dir & LV_DIR_VER) { + lv_obj_set_x(label_enter, label_enter_end_x); + lv_coord_t start_y = label_enter_end_y; + start_y += ((enter_dir == LV_DIR_TOP) ? -obj_height : obj_height); + lv_anim_label_start_anim( + label_enter, + enter_dir, + start_y, + label_enter_end_y, + alabel->duration, + alabel->path_cb); + } else { + lv_obj_set_pos(label_enter, label_enter_end_x, label_enter_end_y); + } + + if (alabel->a_enter.exec_cb != NULL) { + lv_anim_set_var(&alabel->a_enter, label_enter); + lv_anim_start(&alabel->a_enter); + } + + /* exit */ + lv_coord_t label_exit_width = lv_obj_get_width(label_exit); + lv_coord_t label_exit_height = lv_obj_get_height(label_exit); + lv_coord_t label_exit_start_x = (obj_width - label_exit_width) / 2; + lv_coord_t label_exit_start_y = (obj_height - label_exit_height) / 2; + + if (exit_dir & LV_DIR_HOR) { + lv_obj_set_y(label_exit, label_exit_start_y); + lv_coord_t end_x = label_exit_start_x; + end_x += ((exit_dir == LV_DIR_LEFT) ? obj_width : -obj_width); + lv_anim_label_start_anim( + label_exit, + exit_dir, + label_exit_start_x, + end_x, + alabel->duration, + alabel->path_cb); + } else if (exit_dir & LV_DIR_VER) { + lv_obj_set_x(label_exit, label_exit_start_x); + lv_coord_t end_y = label_exit_start_y; + end_y += ((exit_dir == LV_DIR_TOP) ? obj_height : -obj_height); + lv_anim_label_start_anim( + label_exit, + exit_dir, + label_exit_start_y, + end_y, + alabel->duration, + alabel->path_cb); + } else { + lv_obj_set_pos(label_exit, label_exit_start_x, label_exit_start_y); + } + + if (alabel->a_exit.exec_cb != NULL) { + lv_anim_set_var(&alabel->a_exit, label_exit); + lv_anim_start(&alabel->a_exit); + } + + alabel->label_act = label_enter; +} + +lv_dir_t lv_anim_label_get_enter_dir(lv_obj_t* obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + return alabel->enter_dir; +} + +lv_dir_t lv_anim_label_get_exit_dir(lv_obj_t* obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + return alabel->exit_dir; +} + +uint32_t lv_anim_label_get_time(lv_obj_t* obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + return alabel->duration; +} + +lv_anim_path_cb_t lv_anim_label_get_path(lv_obj_t* obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + return alabel->path_cb; +} + +const char* lv_anim_label_get_text(lv_obj_t* obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + return lv_label_get_text(alabel->label_act); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_anim_label_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) +{ + LV_TRACE_OBJ_CREATE("begin"); + + lv_anim_label_t* alabel = (lv_anim_label_t*)obj; + + alabel->label_1 = lv_label_create(obj); + lv_label_set_text(alabel->label_1, ""); + + alabel->label_2 = lv_label_create(obj); + lv_label_set_text(alabel->label_2, ""); + + alabel->label_act = alabel->label_1; + // alabel->dir = LV_DIR_BOTTOM; + alabel->duration = 500; + alabel->path_cb = lv_anim_path_ease_out; + + lv_anim_init(&alabel->a_enter); + lv_anim_init(&alabel->a_exit); + + LV_TRACE_OBJ_CREATE("finished"); +} + +static void lv_anim_label_set_x(void* obj, int32_t x) +{ + lv_obj_set_x(obj, x); +} + +static void lv_anim_label_set_y(void* obj, int32_t y) +{ + lv_obj_set_y(obj, y); +} \ No newline at end of file diff --git a/bandx/utils/lv_anim_label.h b/bandx/utils/lv_anim_label.h new file mode 100755 index 0000000000000000000000000000000000000000..32b8e85c31f05cc09f01f32a94f2c5f5d6611135 --- /dev/null +++ b/bandx/utils/lv_anim_label.h @@ -0,0 +1,158 @@ +/** + * @file lv_anim_label.h + * + */ + +#ifndef LV_ANIM_LABEL_H +#define LV_ANIM_LABEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_obj_t obj; + lv_obj_t* label_1; + lv_obj_t* label_2; + lv_obj_t* label_act; + lv_dir_t enter_dir; + lv_dir_t exit_dir; + lv_anim_t a_enter; + lv_anim_t a_exit; + uint32_t duration; + lv_anim_path_cb_t path_cb; +} lv_anim_label_t; + +extern const lv_obj_class_t lv_anim_label_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a new animation label object. + * @param parent Pointer to the parent object. + * @return A pointer to the newly created animation label object. + */ +lv_obj_t* lv_anim_label_create(lv_obj_t* parent); + +/** + * Set the direction of the animation label. + * @param obj Pointer to the animation label object. + * @param dir The direction to set for the animation. + */ +void lv_anim_label_set_dir(lv_obj_t* obj, lv_dir_t dir); + +/** + * Set the entry direction for the animation label. + * @param obj Pointer to the animation label object. + * @param dir The entry direction to set. + */ +void lv_anim_label_set_enter_dir(lv_obj_t* obj, lv_dir_t dir); + +/** + * Set the exit direction for the animation label. + * @param obj Pointer to the animation label object. + * @param dir The exit direction to set. + */ +void lv_anim_label_set_exit_dir(lv_obj_t* obj, lv_dir_t dir); + +/** + * Set the duration of the animation for the animation label. + * @param obj Pointer to the animation label object. + * @param duration The duration of the animation in milliseconds. + */ +void lv_anim_label_set_time(lv_obj_t* obj, uint32_t duration); + +/** + * Set the animation path callback for the animation label. + * @param obj Pointer to the animation label object. + * @param path_cb Callback function for the animation path. + */ +void lv_anim_label_set_path(lv_obj_t* obj, lv_anim_path_cb_t path_cb); + +/** + * Add a style to the animation label. + * @param obj Pointer to the animation label object. + * @param style Pointer to the style to add. + */ +void lv_anim_label_add_style(lv_obj_t* obj, lv_style_t* style); + +/** + * Set a custom enter animation for the animation label. + * @param obj Pointer to the animation label object. + * @param a Pointer to the custom animation. + */ +void lv_anim_label_set_custom_enter_anim(lv_obj_t* obj, const lv_anim_t* a); + +/** + * Set a custom exit animation for the animation label. + * @param obj Pointer to the animation label object. + * @param a Pointer to the custom animation. + */ +void lv_anim_label_set_custom_exit_anim(lv_obj_t* obj, const lv_anim_t* a); + +/** + * Push new text to the animation label. + * @param obj Pointer to the animation label object. + * @param txt The text to push to the animation label. + */ +void lv_anim_label_push_text(lv_obj_t* obj, const char* txt); + +/** + * Get the enter direction of the animation label. + * @param obj Pointer to the animation label object. + * @return The current enter direction of the animation label. + */ +lv_dir_t lv_anim_label_get_enter_dir(lv_obj_t* obj); + +/** + * Get the exit direction of the animation label. + * @param obj Pointer to the animation label object. + * @return The current exit direction of the animation label. + */ +lv_dir_t lv_anim_label_get_exit_dir(lv_obj_t* obj); + +/** + * Get the duration of the animation for the animation label. + * @param obj Pointer to the animation label object. + * @return The duration of the animation in milliseconds. + */ +uint32_t lv_anim_label_get_time(lv_obj_t* obj); + +/** + * Get the animation path callback for the animation label. + * @param obj Pointer to the animation label object. + * @return The callback function for the animation path. + */ +lv_anim_path_cb_t lv_anim_label_get_path(lv_obj_t* obj); + +/** + * Get the current text of the animation label. + * @param obj Pointer to the animation label object. + * @return The current text of the animation label. + */ +const char* lv_anim_label_get_text(lv_obj_t* obj); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_LABEL_H*/ \ No newline at end of file diff --git a/bandx/utils/lv_auto_event.c b/bandx/utils/lv_auto_event.c new file mode 100755 index 0000000000000000000000000000000000000000..c99f31eed9ca642e7aa7734059c572fbe1a0c48d --- /dev/null +++ b/bandx/utils/lv_auto_event.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_auto_event.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_auto_event_timer_handler(lv_timer_t* timer); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_auto_event_t* lv_auto_event_create(lv_auto_event_data_t* auto_event_data, uint32_t len) +{ + lv_auto_event_t* ae = lv_malloc(sizeof(lv_auto_event_t)); + + if (ae == NULL) { + return NULL; + } + + ae->auto_event_data = auto_event_data; + ae->len = len; + ae->run_index = 0; + ae->timer = lv_timer_create(lv_auto_event_timer_handler, auto_event_data[0].delay, ae); + return ae; +} + +void lv_auto_event_del(lv_auto_event_t* ae) +{ + if (ae == NULL) { + return; + } + + if (ae->timer != NULL) { + lv_timer_del(ae->timer); + ae->timer = NULL; + } + + lv_free(ae); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_auto_event_timer_handler(lv_timer_t* timer) +{ + lv_auto_event_t* ae = lv_timer_get_user_data(timer); + + uint32_t cur_index = ae->run_index; + ae->run_index++; + + if (ae->run_index < ae->len) { + lv_timer_set_period(timer, ae->auto_event_data[ae->run_index].delay); + } else { + lv_timer_del(timer); + ae->timer = NULL; + } + + lv_obj_send_event( + *(ae->auto_event_data[cur_index].obj_p), + ae->auto_event_data[cur_index].event, + ae->auto_event_data[cur_index].user_data); +} \ No newline at end of file diff --git a/bandx/utils/lv_auto_event.h b/bandx/utils/lv_auto_event.h new file mode 100755 index 0000000000000000000000000000000000000000..a101854d1b3c6be8f00935d5cf77e2bed698a2ce --- /dev/null +++ b/bandx/utils/lv_auto_event.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __LV_AUTO_EVENT_H +#define __LV_AUTO_EVENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_obj_t** obj_p; + lv_event_code_t event; + uint32_t delay; + void* user_data; +} lv_auto_event_data_t; + +typedef struct { + lv_timer_t* timer; + lv_auto_event_data_t* auto_event_data; + uint32_t len; + uint32_t run_index; +} lv_auto_event_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a new auto event. + * @param auto_event_data Pointer to the data structure containing auto event parameters. + * @param len Length of the auto event data array. + * @return A pointer to the newly created auto event, or NULL if creation failed. + */ +lv_auto_event_t* lv_auto_event_create(lv_auto_event_data_t* auto_event_data, uint32_t len); + +/** + * Delete an existing auto event. + * @param ae Pointer to the auto event to be deleted. + */ +void lv_auto_event_del(lv_auto_event_t* ae); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bandx/utils/lv_obj_ext_func.c b/bandx/utils/lv_obj_ext_func.c new file mode 100755 index 0000000000000000000000000000000000000000..c20dd33d73b99f60c13bc63705c716c97099b1cd --- /dev/null +++ b/bandx/utils/lv_obj_ext_func.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_obj_ext_func.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_obj_add_anim( + lv_obj_t* obj, lv_anim_t* a, + lv_anim_exec_xcb_t exec_cb, + int32_t start, int32_t end, + uint16_t time, + uint32_t delay, + lv_anim_ready_cb_t ready_cb, + lv_anim_path_cb_t path_cb) +{ + lv_anim_t anim_temp; + + if (a == NULL) { + a = &anim_temp; + + /* INITIALIZE AN ANIMATION + *-----------------------*/ + lv_anim_init(a); + } + + /* MANDATORY SETTINGS + *------------------*/ + + /*Set the "animator" function*/ + lv_anim_set_exec_cb(a, exec_cb); + + /*Set the "animator" function*/ + lv_anim_set_var(a, obj); + + /*Length of the animation [ms]*/ + lv_anim_set_time(a, time); + + /*Set start and end values. E.g. 0, 150*/ + lv_anim_set_values(a, start, end); + + /* OPTIONAL SETTINGS + *------------------*/ + + /*Time to wait before starting the animation [ms]*/ + lv_anim_set_delay(a, delay); + + /*Set the path in an animation*/ + lv_anim_set_path_cb(a, path_cb); + + /*Set a callback to call when animation is ready.*/ + lv_anim_set_ready_cb(a, ready_cb); + + /*Set a callback to call when animation is started (after delay).*/ + lv_anim_set_start_cb(a, ready_cb); + + /* START THE ANIMATION + *------------------*/ + lv_anim_start(a); /*Start the animation*/ +} + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/bandx/utils/lv_obj_ext_func.h b/bandx/utils/lv_obj_ext_func.h new file mode 100755 index 0000000000000000000000000000000000000000..a0f34d76bbb80002e4f801e6ca57135216e2613d --- /dev/null +++ b/bandx/utils/lv_obj_ext_func.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __LV_OBJ_EXT_FUNC_H +#define __LV_OBJ_EXT_FUNC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +#define LV_ANIM_TIME_DEFAULT 300 +#define LV_ANIM_EXEC(attr) (lv_anim_exec_xcb_t) lv_obj_set_##attr + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Add animation to an object. + * @param obj pointer to the object. + * @param a pointer to the animation (can be NULL). + * @param exec_cb the callback to execute for the animation. + * @param start the starting value of the animation. + * @param end the ending value of the animation. + * @param time the duration of the animation in milliseconds. + * @param delay the delay before the animation starts in milliseconds. + * @param ready_cb the callback to call when the animation is ready (can be NULL). + * @param path_cb the callback for the animation path (can be NULL). + */ +void lv_obj_add_anim( + lv_obj_t* obj, lv_anim_t* a, + lv_anim_exec_xcb_t exec_cb, + int32_t start, + int32_t end, + uint16_t time, + uint32_t delay, + lv_anim_ready_cb_t ready_cb, + lv_anim_path_cb_t path_cb); + +/** + * Macro to add animation to an object with specified attributes. + * @param obj pointer to the object. + * @param attr the attribute to animate. + * @param target the target value for the animation. + * @param time the duration of the animation in milliseconds. + */ +#define LV_OBJ_ADD_ANIM(obj, attr, target, time) \ + do { \ + lv_obj_add_anim( \ + (obj), NULL, \ + (lv_anim_exec_xcb_t)lv_obj_set_##attr, \ + lv_obj_get_##attr(obj), \ + (target), \ + (time), \ + 0, \ + NULL, \ + lv_anim_path_ease_out); \ + } while (0) + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/breakout/Kconfig b/breakout/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..b34c07af636201ea95a17d884665a12be989a5c6 --- /dev/null +++ b/breakout/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_BREAKOUT + bool "breakout" + default n + +if LVX_USE_DEMO_BREAKOUT + config LVX_BREAKOUT_DATA_ROOT + string "BREAKOUT Data Root" + default "/data" + config LVX_BREAKOUT_STACKSIZE + int "LVX_BREAKOUT stack size" + default 65536 +endif diff --git a/breakout/Make.defs b/breakout/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..e5f6c177df689ddb2c039a5e0b4db1a0082dbce2 --- /dev/null +++ b/breakout/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_BREAKOUT),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/breakout +endif diff --git a/breakout/Makefile b/breakout/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f9dbb5020a7bd0dbd8063540a00407edd901c174 --- /dev/null +++ b/breakout/Makefile @@ -0,0 +1,32 @@ +# +# Copyright (C) 2022 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_BREAKOUT), y) +PROGNAME = breakout +PRIORITY = 100 +STACKSIZE = $(CONFIG_LVX_BREAKOUT_STACKSIZE) +MODULE = $(CONFIG_LVX_USE_DEMO_BREAKOUT) +CSRCS += src/Audio/audio_ctl.c +CXXFLAGS += -I$(APPDIR)/packages/demos/breakout/src +CXXEXT := .cpp +CXXSRCS += $(shell find -L ./ -name "*.cpp" | grep -v breakout_main.cpp) + +MAINSRC = breakout_main.cpp +endif + +include $(APPDIR)/Application.mk diff --git a/breakout/Readme.md b/breakout/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..18cb7a15ab311691e0f4eef2a41a28e85dea47ab --- /dev/null +++ b/breakout/Readme.md @@ -0,0 +1,164 @@ +# 🎮 Breakout Game 《打砖块游戏v3.2》 +`“KUN生是旷野,不是轨道!”` 拥有对篮球无限热爱的KUN,在家族中独树一帜,正挥洒着汗水,勤奋努力的击打篮球撞碎砖块,缔造属于自己的篮球哲学。 + + +🧱 开发时长不足`两年半`的作品,是基于OpenVela和LVGL开发的触屏打砖块游戏,将篮球和鸡融合到一起,已实现了基本游戏逻辑,增加了图片素材并实现了打击音效。 + +<img src="./screenshot/kun.gif" alt="Kun" width="75%"> +**本项目中的图片及音频资源已按要求遵守相应的许可协议,可用于个人作品及商业用途。** +在对应素材文件夹下,已通过`readme`和`LICENSE`文件详细标明了作者出处等信息,满足了相应的license协议要求,允许个人在作品及商业中使用,但不得对素材进行单独售卖。 + +**最新公告V3.2 修复球类bug,增加通关道具** + +**修复球类运动方向问题的bug** +- 现在道具获得的小球,会正确的向左或向右发射 + +**在少于15个方块时掉落,终结剩余方块的通关道具TROPHY** +- 可以跳过一段不愉快的时光。 + +以下是实机画面: +<img src="./screenshot/game.gif" alt="game" width="75%"> +以下是第三版游戏部分界面: +<img src="./screenshot/level1.png" alt="" width="75%"> +<img src="./screenshot/level2.png" alt="" width="75%"> + +# ✨ Features 特点 + +- **游戏区域**:使用 LVGL 创建全屏的游戏区域,并支持动态生成砖块。 +- **挡板与球的物理机制**:挡板通过触摸输入进行控制,球的运动具有物理效果,碰撞后反弹。 +- **砖块系统**:砖块具有血量,可被破坏,支持不同类型砖块的行为。 +- **音效反馈**:根据砖块的血量播放不同的音效。 +- **触摸输入**:支持触摸屏输入来控制挡板移动。 +- **道具系统**: 支持增长挡板,分裂小球等功能。 +- **游戏状态管理**:管理游戏状态(例如:PLAYING、GAME_OVER、PAUSED)以控制游戏流程。 + + + +# 🖼️ Image Handling(图片处理) +## 1. libpng decoder(libpng 解码器) +好消息,OpenVela系统已经内置了该PNG解码器,仅需将`LIB_PNG`和`LV_USE_LIBPNG`配置为`yes`,即可轻松使用`lv_image_set_src`等函数读取使用`PNG`图片。使用方法可以参考:`https://lvgl.100ask.net/master/details/libs/libpng.html` +此外,这是libpng的github仓库链接:`https://github.com/pnggroup/libpng`,自己手动引入还是有难度。 + +## 2.Image Caching(图片缓存) +LVGL 支持将图像缓存到内存中,以提升图像组件在运行时的加载速度,特别适用于反复绘制的图像场景,如游戏背景、按钮图标等。 +在从外部读入图片过多,会有明显卡顿,可以使用图片缓存的方法,将图片读入内存。具体可以参考:`https://lvgl.100ask.net/master/details/main-components/image.html#overview-image-caching` + +# 🔊 Audio Handling(音频处理) +引用了`packages_demos`仓库下的`music_player`的音频控制文件`audio_ctl.c`和`audio_ctl.h`,通过`audio_ctl_init_nxaudio`加载音频文件,`audio_ctl_start`播放音频,`audio_ctl_stop`暂停音频,`audio_ctl_uninit_nxaudio`释放资源,实现了碰撞砖块发出音效。 + + +# 🚀 Getting Started 快速开始 + +首先进入模拟器配置 +## 1.配置模拟器(menuconfig) +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig +``` + +使用`/`键进入搜索模式 +- 配置`LVX_USE_DEMO_BREAKOUT `为 `yes` +- `LVX_BREAKOUT_DATA_ROOT`的路径设置为`/data ` (Kconfig文件默认预设为 `/data`) +- `LVX_BREAKOUT_STACKSIZE`设置为65536 +- `LIB_PNG`和`LV_USE_LIBPNG`配置为`yes` (读取png图片资源) +- `AUDIO`和`AUDIOUTILS_NXAUDIO_LIB`配置为`yes` (读取wav音频文件) +- `Default image header cache count`配置为`18` (缓存图片数) +- `Default image cache size`配置为`8388608` ,这一步设定图片内存8MB,实测只用了大概3648003,不到4MB,设为8MB这样保险一些。**在配置后,一定要先`清理构建产物`,再`重新构建`,否则`image cache max size`不会更新。** +## 2.构建和清除构建文件 +### 开始构建 +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j$(nproc) +``` +### 清理构建产物 +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j$(nproc) +``` +## 3.ADB推送更新关卡等资源(在模拟器运行状况下) +```bash +adb push apps/packages/demos/breakout/res /data/ +``` + +## 4.启动模拟器 +```bash +./emulator.sh vela +``` + +## 5.启动游戏 +```bash +breakout & +``` +--- +# ▶️ 启动游戏 + +在 main文件函数中初始化 LVGL后,调用: + +ballgame_start(); // 启动游戏 + + +# 🎮 Controls + +- 移动挡板:按住并拖动屏幕,挡板随手指水平移动。 + +- 发射小球:游戏开始时,轻触屏幕即可发射小球。 + +- 重新开始:掉球后点击 "Restart" 按钮重开一局。 + +# 📄 Level File Format (.dat) + +放置关卡文件: +将 .dat 文件放到资源路径下,例如: + + `breakout/res/map/level_1.dat` + +关卡文件为文本格式,使用字符描述砖块: +| 字符 | 说明 | 生命值 | +|------|----------------|--------| +| 空格 | 空(无生成) | 无 | +| `#` | 墙(不可破坏) | -1 | +| `A` | 绿色砖块 | 1 | +| `B` | 橙色砖块 | 2 | +| `C` | 紫色砖块 | 3 | +| `D` | 黄色砖块 | 4 | +| `E` | 蓝色砖块 | 5 | +| 未知类型 | 绿色砖块 | 1 | + +此处读取文件时,会将换行符`\n`,制表符`\r`,文件结尾符号`\0`也识别出来,需要注意排除。 + +关卡示例: +``` +####### +#A B A# +# C # +####### +``` +**V3.0增加了三个充满激情的buff道具** +- 可以呼朋引伴的友情魔法 +- 让篮球无丝分裂的奇妙技艺 +- 与朋友们一起发射篮球的友谊力量 +**好好运用,相信你一定能战胜砖块!(๑•̀ㅂ•́)و✧** + +**V3.1 球绘制方法更新概述** +**旧版(每球独立对象)** +- 每个球都是一个独立的 LVGL 对象。 +- 每帧通过 lv_obj_set_pos 移动对象。 +- 球多时容易卡顿,对象管理开销大,频繁创建销毁对象成本高。 + +**新版(统一 Canvas 绘制)** +- 创建一个覆盖游戏区域的 canvas。 +- 所有球每帧绘制到同一个 canvas 上。 +- 每帧只需刷新一次 canvas(先填充背景去除拖影,再绘制球的新位置)。 +- 显著降低对象管理开销,提升多球场景下的刷新性能。 + + +# 素材使用说明 +- 素材来源于`https://icon.sucai999.com/`以及`https://craftpix.net` +- 道具图标来源于`game-icons.net` +- 音频素材来源于`https://freesound.org/` + +**本项目中的图片及音频资源已按要求遵守相应的许可协议,可用于个人作品及商业用途,但不得对素材单独进行售卖。** + +- **Microsoft 图片**:可在个人及商业项目中使用,需遵守 **MIT** 许可协议。 +- **Google 图片**:可在个人及商业项目中使用,需遵守 **Apache 2.0** 许可协议,并附带版权声明、许可证文本及修改声明。 +- **CraftPix.net 图片**:可用于个人及商业项目,但需遵守 **CraftPix 自定义许可协议**,保留版权信息并不得单独转售源文件。 +- **game-icons.net图标**:可用于个人及商业项目,但必须 署名原作者,并标明许可协议;允许修改、分发和再使用,但不得去除作者署名。 +- **freesound音频**:本作品使用的音频文件皆为 **CC0(Creative Commons 0)** 授权的资源,表示该资源已被作者明确放弃所有版权及相关权利,可自由复制、修改、分发,亦可用于个人或商业用途,无需署名、无需许可、无任何限制。 + diff --git a/breakout/breakout_main.cpp b/breakout/breakout_main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6b64e80c7d90d12a4535786598a24671089e944e --- /dev/null +++ b/breakout/breakout_main.cpp @@ -0,0 +1,78 @@ +/**************************************************** + * breakout_main.cpp + * Main program entry for the breakout game on NuttX OS. + ***************************************************/ + +#include <nuttx/config.h> +#include <unistd.h> +#include <uv.h> +#include "src/breakout.h" +#include <lvgl/lvgl.h> + +/** + * A helper function to initialize and run the libuv event loop. + * The loop handles input events, timers, and screen refreshes. + */ +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + // Create a struct to pass integration info between NuttX and LVGL + lv_nuttx_uv_t uv_info; + void* data; + + // Initialize the libuv event loop + uv_loop_init(loop); + + // Prepare config info to pass to the LVGL-UV integration layer + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; // Pass in the initialized display device + uv_info.indev = result->indev; // Pass in the initialized input device (touchscreen) +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; // If configured, also pass virtual user input device +#endif + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +/************************************************** + * Application main entry function. + ***************************************************/ +extern "C" int breakout_main(int argc, FAR char *argv[]) +{ + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); + + // Safety check: ensure LVGL is not initialized multiple times + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + // Initialize LVGL core library + lv_init(); + + // Initialize and bind NuttX display and input drivers + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + // Check if the display device was successfully initialized + if (result.disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + // Call the game start function to create the game UI and all objects + ballgame_start(); + + // Start the main event loop driving the entire UI and application + lv_nuttx_uv_loop(&ui_loop, &result); + + // After the application exits the loop, deinitialize all resources + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/breakout/res/audio/A4.wav b/breakout/res/audio/A4.wav new file mode 100644 index 0000000000000000000000000000000000000000..7137b6c75a10175d9f49910b797be1bbc8bc1632 Binary files /dev/null and b/breakout/res/audio/A4.wav differ diff --git a/breakout/res/audio/B4.wav b/breakout/res/audio/B4.wav new file mode 100644 index 0000000000000000000000000000000000000000..8d2e1e71a6c958ea360daa2645e03ce9b58b52e1 Binary files /dev/null and b/breakout/res/audio/B4.wav differ diff --git a/breakout/res/audio/C4.wav b/breakout/res/audio/C4.wav new file mode 100644 index 0000000000000000000000000000000000000000..2ba65afad1bfd257879b8ed31f5e00e5115613b1 Binary files /dev/null and b/breakout/res/audio/C4.wav differ diff --git a/breakout/res/audio/C5.wav b/breakout/res/audio/C5.wav new file mode 100644 index 0000000000000000000000000000000000000000..1269b363a7fa38d3006d682b5f0b378fc0921dad Binary files /dev/null and b/breakout/res/audio/C5.wav differ diff --git a/breakout/res/audio/D4.wav b/breakout/res/audio/D4.wav new file mode 100644 index 0000000000000000000000000000000000000000..6b18f52995739d98306249d267f957b79d50a1fc Binary files /dev/null and b/breakout/res/audio/D4.wav differ diff --git a/breakout/res/audio/E4.wav b/breakout/res/audio/E4.wav new file mode 100644 index 0000000000000000000000000000000000000000..b9dbeb5d1ce1b1f4b52a8b54e11c5a796c555994 Binary files /dev/null and b/breakout/res/audio/E4.wav differ diff --git a/breakout/res/audio/F4.wav b/breakout/res/audio/F4.wav new file mode 100644 index 0000000000000000000000000000000000000000..fcbd66beb0d0b5e4e4b0c605281d1d781dd2ca1a Binary files /dev/null and b/breakout/res/audio/F4.wav differ diff --git a/breakout/res/audio/G4.wav b/breakout/res/audio/G4.wav new file mode 100644 index 0000000000000000000000000000000000000000..4ffb2b850acb04241d88e42d55dd77816003e253 Binary files /dev/null and b/breakout/res/audio/G4.wav differ diff --git a/breakout/res/audio/LICENSE b/breakout/res/audio/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..a1974cbb9cb88a97653494b3d3f899ee22873653 --- /dev/null +++ b/breakout/res/audio/LICENSE @@ -0,0 +1,36 @@ +CC0 1.0 Universal + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. +1. Copyright and Related Rights. + +A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: + + the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; + moral rights retained by the original author(s) and/or performer(s); + publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; + rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; + rights protecting the extraction, dissemination, use and reuse of data in a Work; + database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and + other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. + +To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. +3. Public License Fallback. + +Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. +4. Limitations and Disclaimers. + + No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. + Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. + Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. + Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. + + diff --git a/breakout/res/audio/readme.md b/breakout/res/audio/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..f53e8e758fe1f8bb096b3e037ddc1f92c7b089be --- /dev/null +++ b/breakout/res/audio/readme.md @@ -0,0 +1,24 @@ + +All audio files are from: https://freesound.org/people/Teddy_Frost/ + +All are licensed under the Creative Commons 0 (CC0) license. + +You can copy, modify, distribute, and perform the sound, even for commercial purposes, all without the need of asking permission from the author. + + + + E4.wav by Teddy_Frost — https://freesound.org/s/334542/ — License: Creative Commons 0 + + F4.wav by Teddy_Frost — https://freesound.org/s/334541/ — License: Creative Commons 0 + + G4.wav by Teddy_Frost — https://freesound.org/s/334540/ — License: Creative Commons 0 + + B4.wav by Teddy_Frost — https://freesound.org/s/334539/ — License: Creative Commons 0 + + C4.wav by Teddy_Frost — https://freesound.org/s/334538/ — License: Creative Commons 0 + + C5.wav by Teddy_Frost — https://freesound.org/s/334537/ — License: Creative Commons 0 + + D4.wav by Teddy_Frost — https://freesound.org/s/334536/ — License: Creative Commons 0 + + A4.wav by Teddy_Frost — https://freesound.org/s/334534/ — License: Creative Commons 0 diff --git a/breakout/res/fonts/MiSans-Normal.ttf b/breakout/res/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/breakout/res/fonts/MiSans-Normal.ttf differ diff --git a/breakout/res/fonts/MiSans-Semibold.ttf b/breakout/res/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/breakout/res/fonts/MiSans-Semibold.ttf differ diff --git a/breakout/res/icons/KUN.png b/breakout/res/icons/KUN.png new file mode 100644 index 0000000000000000000000000000000000000000..2efcde2c9a73633e2fefab9d5ab647e03add6b4d Binary files /dev/null and b/breakout/res/icons/KUN.png differ diff --git a/breakout/res/icons/LICENSE b/breakout/res/icons/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..951d81b0a828c0fd09e678d2a12a8c94cccacf20 --- /dev/null +++ b/breakout/res/icons/LICENSE @@ -0,0 +1,66 @@ +# LICENSE + +The copyright and license statements for the image resources used in this project are as follows: + +--- + +## Microsoft Corporation Image Resources (MIT License) + +Images: ball.png, brick_#.png, brick_A.png, brick_B.png, brick_C.png, brick_D.png, brick_E.png + +Copyright Notice: +Copyright (c) Microsoft Corporation + +License: +MIT License + +Full license text: https://opensource.org/licenses/MIT + +--- + +## Google Inc Image Resources (Apache License 2.0) + +Image: KUN.png + +Copyright Notice: +Copyright 2023 Google Inc + +License: +Apache License, Version 2.0 + +Full license text: https://www.apache.org/licenses/LICENSE-2.0 + +--- + +## CraftPix.net Image Resources (CraftPix.net License) + +Images: background_1.png, bcakground_2.png, bcakground_3.png, bcakground_4.png, bcakground_5.png, bcakground_6.png + +Copyright Notice: +© CraftPix.net - 2D & 3D Game Assets + +License details: +Please refer to https://craftpix.net/file-licenses/ + +--- + +## game-icons.net Image Resources (CC BY 3.0 License) + +Images: three_balls.png, friends.png, up_balls.png , trophy.png + +Copyright Notice: +© Delapouite, © Lorc — Icons licensed under CC BY 3.0 + +license details: +https://creativecommons.org/licenses/by/3.0/ + +--- +## Usage Notes + +- The image resources included in this project are subject to the above different licenses; please comply with the corresponding license terms. +- Both MIT and Apache 2.0 licenses allow commercial use but require preserving copyright and license notices. +- Use of CraftPix assets must strictly follow their official license terms; direct resale of source files is prohibited. +- Use of Delapouite and Lorc icons must follow the Creative Commons Attribution 3.0 (CC BY 3.0) license; proper attribution is required and modifications must be indicated. + + + diff --git a/breakout/res/icons/background_1.png b/breakout/res/icons/background_1.png new file mode 100644 index 0000000000000000000000000000000000000000..aa7e66e7c84a48b36da34d9623c852357f4d0a28 Binary files /dev/null and b/breakout/res/icons/background_1.png differ diff --git a/breakout/res/icons/background_2.png b/breakout/res/icons/background_2.png new file mode 100644 index 0000000000000000000000000000000000000000..248c3846b0c644e82e6bc18b47055b3906114602 Binary files /dev/null and b/breakout/res/icons/background_2.png differ diff --git a/breakout/res/icons/background_3.png b/breakout/res/icons/background_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bfe203f58483abcc07c249b061b624b93c2c02 Binary files /dev/null and b/breakout/res/icons/background_3.png differ diff --git a/breakout/res/icons/background_4.png b/breakout/res/icons/background_4.png new file mode 100644 index 0000000000000000000000000000000000000000..248c3846b0c644e82e6bc18b47055b3906114602 Binary files /dev/null and b/breakout/res/icons/background_4.png differ diff --git a/breakout/res/icons/background_5.png b/breakout/res/icons/background_5.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1022a413297689f6f268e3d7d3a06cb6209f24 Binary files /dev/null and b/breakout/res/icons/background_5.png differ diff --git a/breakout/res/icons/background_6.png b/breakout/res/icons/background_6.png new file mode 100644 index 0000000000000000000000000000000000000000..0e43843f348f807f44e48aafa438e45a267ce182 Binary files /dev/null and b/breakout/res/icons/background_6.png differ diff --git a/breakout/res/icons/ball.png b/breakout/res/icons/ball.png new file mode 100644 index 0000000000000000000000000000000000000000..4c43f9ea92b4616d9ff331f50d02c4f436384484 Binary files /dev/null and b/breakout/res/icons/ball.png differ diff --git a/breakout/res/icons/brick_#.png b/breakout/res/icons/brick_#.png new file mode 100644 index 0000000000000000000000000000000000000000..4835ec82981f8e621af49a53ef95d193c67ddb3f Binary files /dev/null and b/breakout/res/icons/brick_#.png differ diff --git a/breakout/res/icons/brick_A.png b/breakout/res/icons/brick_A.png new file mode 100644 index 0000000000000000000000000000000000000000..db7a95b4af9029dfae6a515545ccd89a38296ceb Binary files /dev/null and b/breakout/res/icons/brick_A.png differ diff --git a/breakout/res/icons/brick_B.png b/breakout/res/icons/brick_B.png new file mode 100644 index 0000000000000000000000000000000000000000..187ed63a2a9a47bb46a4ffc999d9eb7199d90547 Binary files /dev/null and b/breakout/res/icons/brick_B.png differ diff --git a/breakout/res/icons/brick_C.png b/breakout/res/icons/brick_C.png new file mode 100644 index 0000000000000000000000000000000000000000..ed398d6f4f84a1731b5a27d843a2da00757b11be Binary files /dev/null and b/breakout/res/icons/brick_C.png differ diff --git a/breakout/res/icons/brick_D.png b/breakout/res/icons/brick_D.png new file mode 100644 index 0000000000000000000000000000000000000000..a77025c84dd17b8e6387d554e89c7518e17e24f8 Binary files /dev/null and b/breakout/res/icons/brick_D.png differ diff --git a/breakout/res/icons/brick_E.png b/breakout/res/icons/brick_E.png new file mode 100644 index 0000000000000000000000000000000000000000..247696da70a88849564a3e5601ed9e64737a1747 Binary files /dev/null and b/breakout/res/icons/brick_E.png differ diff --git a/breakout/res/icons/friends.png b/breakout/res/icons/friends.png new file mode 100644 index 0000000000000000000000000000000000000000..cfdc08744905752a55c1498b3aa265a41bedc8b0 Binary files /dev/null and b/breakout/res/icons/friends.png differ diff --git a/breakout/res/icons/readme.md b/breakout/res/icons/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..1418c2aa6f44de9a47525bd36bb0fb9afc4d994c --- /dev/null +++ b/breakout/res/icons/readme.md @@ -0,0 +1,40 @@ +The sources, author information, and license details of all images are as follows. This work is adapted from the original images, and the image dimensions have been adjusted. + +1. Microsoft Images (MIT License) + + Images: ball.png, brick_#.png, brick_A.png, brick_B.png, brick_C.png, brick_D.png, brick_E.png + + Author: Microsoft Corporation + + License: MIT License + +2. Google Images (Apache 2.0 License) + + Image: KUN.png + + Author: Google Inc + + License: https://www.apache.org/licenses/LICENSE-2.0 + +The Apache 2.0 License requires including copyright notices, the license text, and the NOTICE file (if any), stating any modifications, and allows commercial use. + +3. CraftPix.net Images (CraftPix Custom License) + + Images: background_1.png, bcakground_2.png, bcakground_3.png, bcakground_4.png, bcakground_5.png, bcakground_6.png + + Author: CraftPix.net + + License: https://craftpix.net/file-licenses/ + +The CraftPix license generally requires retaining copyright information, prohibits separate resale of source files, and allows use in commercial projects; please refer to their official license details for specifics. + +4. game-icons.net Images (CC BY 3.0) + + Images: three_balls.png, friends.png, up_balls.png, trophy.png + + Author: Lorc, Delapouite, + + License: https://creativecommons.org/licenses/by/3.0/ + +The Creative Commons Attribution 3.0 (CC BY 3.0) license allows you to copy, modify, distribute, and publicly perform the work, including for commercial purposes, as long as you give proper credit to the original author. It does not allow sublicensing or applying additional restrictions, and you must clearly indicate any changes made. The work is provided “as-is” without warranties. Please refer to the full license text for complete details. + diff --git a/breakout/res/icons/three_balls.png b/breakout/res/icons/three_balls.png new file mode 100644 index 0000000000000000000000000000000000000000..c0bb28c4d7c4dfb3ab3795d50286c90cf3e40b62 Binary files /dev/null and b/breakout/res/icons/three_balls.png differ diff --git a/breakout/res/icons/trophy.png b/breakout/res/icons/trophy.png new file mode 100644 index 0000000000000000000000000000000000000000..ed7eccf5f711cb78a08b2315c6883f02deb8d49d Binary files /dev/null and b/breakout/res/icons/trophy.png differ diff --git a/breakout/res/icons/up_balls.png b/breakout/res/icons/up_balls.png new file mode 100644 index 0000000000000000000000000000000000000000..22f3ba84f8e564bb51519c616b12cfebf95fcb4e Binary files /dev/null and b/breakout/res/icons/up_balls.png differ diff --git a/breakout/res/map/level_1.dat b/breakout/res/map/level_1.dat new file mode 100644 index 0000000000000000000000000000000000000000..1999d3e71de6ed0b69560cac1249b4b6708b5140 --- /dev/null +++ b/breakout/res/map/level_1.dat @@ -0,0 +1,29 @@ + + + + E + EEE + E + E + EEEE AE EE EEEE AE EAE AEE EEA EEEE E EEE + E E EE E A A EE E E E A A E A E + E E E E E E E E E E E E E EE + E E E E EEEEEE E E E E EEEEEE E EE E + E E E E E E E E E E E E E + E E EE E E A E E E E A E E EE + EEEE E EE EEEE EEE EEE E EEEE EEEEE EE EA + E + EEE + + C C C D C + DDDDDDDDDDD D DDDDDDDD D D DDDDDDDDDD + D D D D D DDDDD D D + D D D D DDDDD D D C D DD D + D D C D D D D D DDDDDDD D D D + DDDDDDDDDDDD D D DDDDD D D D D + D D C D D D DD D D D D + D D D D DDDDD D D D D D D D + D D D D DD D D D DD D + D D D D D D D D D C D C + D D D D D D D D DDCDDDCD DDDDDDDDDDD + DD D DD DD C D C diff --git a/breakout/res/map/level_2.dat b/breakout/res/map/level_2.dat new file mode 100644 index 0000000000000000000000000000000000000000..becd5369cbf71078ae568d87337c91ec08a5b78c --- /dev/null +++ b/breakout/res/map/level_2.dat @@ -0,0 +1,27 @@ + + B + B AA + BBB A + B B A + B B BB BB DDD DDD A AAA EEEE + B B BB B D D D D AA A E E + BBBBB B B DD D A A E E + B B B B DD D D A A EEEEEE + B B B B D D D A A E + B B BB B D DD D D A A E E + BBB BBB B BB DD DD DDD AAA AAA EEEE + B + BBB + + BB BBB EEE EEE A A A + BB B E E A A A A A + BB B D D E E AAAAAAAAAAA A AAAAAAAA + B B B D D E E A A A AAAAA A + B B B BB BB DDDDD DDDDD EE A A A A A A + B B B B B D D EE A AA A AAA AAAAAA + B B B B B D D EE A A A A A A A A A + B B B B B D D E E A A A A A A A A + B BB B B D D E E A A AA A A AA A + B BB B BB D D D D E E A A A A A + BBB B BBB BB DD DD EEE EEE A A A A A A + A AA A AA A diff --git a/breakout/res/map/level_3.dat b/breakout/res/map/level_3.dat new file mode 100644 index 0000000000000000000000000000000000000000..544b35196ff57d418f1ab1c5fe006ac5caf937ac --- /dev/null +++ b/breakout/res/map/level_3.dat @@ -0,0 +1,26 @@ + + BBBB DDDD CC A DDDDDD EEE BBBBB CCCCC EEE EEE + B B D D C C A D D E E B B C D D + B B D D C C A D D E E B B C D D + B B D D C C A D D E E B C C C + B B D D C C A D D E E B C BB + BB DD CC A DDDDD B B BB C AA + B B D D A CC D E E B C BB + B B D D A C C D E E B C C C + B B D D A C C D E E B B C D D + B B D D A C C D E E B B C D D + BBBB DDDD A CC DDD EEE BBBBB CCCCC FFF FFF + + + A A A E D + AAAAAAAAAAAA AAAAAAAAAAA E DDDDDDDCDD + A A A A E E D D + AAAAAAAAA A A A A A EEEEE E E D D D + A A A A A A E E E D D D + AAAAAAAAAAAA A A A AA E EE D D D + A A A A A E E E DDDDDDDDDDD + AAAAAAAAA A AA E E E D + AA AA AA AAAAAA AA E E E D + A A A A A A E E EE D + A A A AA A A E E E E D + A A A A AAAAAA E D diff --git a/breakout/res/map/level_4.dat b/breakout/res/map/level_4.dat new file mode 100644 index 0000000000000000000000000000000000000000..bac86ffd9712d1f23fc010713691903f2577ecc4 --- /dev/null +++ b/breakout/res/map/level_4.dat @@ -0,0 +1,27 @@ + + DDDDD DDDDDD CCCCC BBBBBBB B B + D D D C C B B B B + D D D C C B B B BBBBBBBB + D D D C B BBBBBBB BB + D D D C B B B B B BBBBBB + D DDDDD C BBB BBBBBBB B B + D D C B B B B B BBBBB + D D C B BBBBBBB B + D D C C B B B B B BBBBBB + D D C C B B B BB B B B + DDDDD DDD CCCCC B B B BBBBBB + B BBBBBBBBB B B B + + + AAAAAA AAAAAA EEEEE C C C C + A A A A E E C CCCCCCCC CCCCCC CCCCC + A A A A E E CCCC C C C C C + A A A A E C C CCCCCC C C C C + AAAAA A A E C C C CC C CCCC + A A AAAAA E CC C CCCCCC C C C C + A A A E C CC C C C C + A A A E C C C C CCCCCCCCCCCC + A A A E E C C CCCCCC C CC + A A A E E C C C C C + AAA AA AAA EEEEE C C C C CCC + C CCCCCCCC CC C C diff --git a/breakout/res/map/level_5.dat b/breakout/res/map/level_5.dat new file mode 100644 index 0000000000000000000000000000000000000000..a64bb406d979ee1a8004a16fff719828f3ecbc62 --- /dev/null +++ b/breakout/res/map/level_5.dat @@ -0,0 +1,26 @@ + DDD + A A + D D B + D D B + D D EE EEE EEEE BBBBB BBBBB DDDD DD DD + D D EE E E E B B B D D DD D + D D E E E E B B D D D D + D D E E EEEEEE FFFFF BBBBB B D D D D + D D E E E B B D D D D + A A E E E E B B B B D D DD D + DDD EEE EEE EEEE BBBBB BB DDDD D DD + D + DDD + + D D D D E A + D D D D EEEEEEEEEE A A AA + D D D DDDDDDDDDDDD E E A A + DDDDDD DDDD D E E AAAAAAAAAAA + D D D E E E A + BBBBBBBBBBBB D D D D DDDDD D EEEEEEEEEEEE AAAAAA + D D DDDDDD D D E E A A + D D D D D D E E A A A + DD D D D D E E A AA + DD D D DDDD D D E E A A + DD DDDDD DDD D D E E A AA AAAA + D D DD EE E AAA A diff --git a/breakout/res/map/level_6.dat b/breakout/res/map/level_6.dat new file mode 100644 index 0000000000000000000000000000000000000000..df62ef95a055facd6375d3373a8d86c406249c9a --- /dev/null +++ b/breakout/res/map/level_6.dat @@ -0,0 +1,27 @@ + + EEE EEE EE DD + E E EE DD + E E + E E + EE EEE BBB BBBB DDDDDDD DDD + EE E B B B B D D D D + EE E BB B B D D D D + E E E BB B B B D D D D + E E E B B B B D D D D + E E E B BB B B D D D D + EEE EEE EEEEE BB BB BBBB DDD DD D DDDDD + + + AAA AAA EEE EEEEE + A A E E E E + A A E E E E + A A E E E + A A AAA AAA CC CC CCCC BBB BBB E E E + AAAAAA A A CC C C C BB B E E EE + A A A A C C C C B E E E + A A A A C C CCCCCC B E E E + A A AA C C C B E E E E + A A AA CC C C C B E E E E + AAA AAA A C CC CCCC BBBBB EEE EEEEE + A C + AA CCC diff --git a/breakout/screenshot/game.gif b/breakout/screenshot/game.gif new file mode 100755 index 0000000000000000000000000000000000000000..4cd593c76c1e05ba89ec70978f442d0893a87312 Binary files /dev/null and b/breakout/screenshot/game.gif differ diff --git a/breakout/screenshot/kun.gif b/breakout/screenshot/kun.gif new file mode 100755 index 0000000000000000000000000000000000000000..de735e652273ff96061116928519682326fae3c0 Binary files /dev/null and b/breakout/screenshot/kun.gif differ diff --git a/breakout/screenshot/level1.png b/breakout/screenshot/level1.png new file mode 100644 index 0000000000000000000000000000000000000000..5562a05939ce058404062c9cde0297b87678719b Binary files /dev/null and b/breakout/screenshot/level1.png differ diff --git a/breakout/screenshot/level2.png b/breakout/screenshot/level2.png new file mode 100644 index 0000000000000000000000000000000000000000..0dd871275963870e5524e270edd94f00062cbfda Binary files /dev/null and b/breakout/screenshot/level2.png differ diff --git a/breakout/screenshot/level3.png b/breakout/screenshot/level3.png new file mode 100644 index 0000000000000000000000000000000000000000..b53dcf4de04e27e1cafa7b1214eefff69897a023 Binary files /dev/null and b/breakout/screenshot/level3.png differ diff --git a/breakout/screenshot/level4.png b/breakout/screenshot/level4.png new file mode 100644 index 0000000000000000000000000000000000000000..17f1e81714be9781cb79ade1b523a912b4605f2e Binary files /dev/null and b/breakout/screenshot/level4.png differ diff --git a/breakout/screenshot/level5.png b/breakout/screenshot/level5.png new file mode 100644 index 0000000000000000000000000000000000000000..bf5e67f6b6a07ddf0bb89fc0d95cb2235d6a115f Binary files /dev/null and b/breakout/screenshot/level5.png differ diff --git a/breakout/screenshot/level6.png b/breakout/screenshot/level6.png new file mode 100644 index 0000000000000000000000000000000000000000..0bae0fcb3b18e909407060ecc27c9eeb21aa0785 Binary files /dev/null and b/breakout/screenshot/level6.png differ diff --git a/breakout/screenshot/screenshot_1.png b/breakout/screenshot/screenshot_1.png new file mode 100644 index 0000000000000000000000000000000000000000..84845540a78f8984e881e2eb83c0c977e7fab5d0 Binary files /dev/null and b/breakout/screenshot/screenshot_1.png differ diff --git a/breakout/screenshot/screenshot_2.png b/breakout/screenshot/screenshot_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ccea37c533510142d1a8483d72bac88d31d65727 Binary files /dev/null and b/breakout/screenshot/screenshot_2.png differ diff --git a/breakout/src/Audio/audio_ctl.c b/breakout/src/Audio/audio_ctl.c new file mode 100644 index 0000000000000000000000000000000000000000..765c6f437451bc80ac089d6757a758aa82a3edd6 --- /dev/null +++ b/breakout/src/Audio/audio_ctl.c @@ -0,0 +1,287 @@ +/********************* + * INCLUDES + *********************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "audio_ctl.h" + +#include <audioutils/nxaudio.h> + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void app_dequeue_cb(unsigned long arg, + FAR struct ap_buffer_s *apb); +static void app_complete_cb(unsigned long arg); +static void app_user_cb(unsigned long arg, + FAR struct audio_msg_s *msg, FAR bool *running); + +/********************** + * STATIC VARIABLES + **********************/ + +static struct nxaudio_callbacks_s cbs = +{ + app_dequeue_cb, + app_complete_cb, + app_user_cb +}; + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void app_dequeue_cb(unsigned long arg, FAR struct ap_buffer_s *apb) +{ + FAR audioctl_s *ctl = (FAR audioctl_s *)(uintptr_t)arg; + + if (!apb) + { + return; + } + + if (ctl->seek) { + lseek(ctl->fd, ctl->seek_position, SEEK_SET); + ctl->file_position = ctl->seek_position; + ctl->seek = false; + } + + apb->nbytes = read(ctl->fd, apb->samp, apb->nmaxbytes); + apb->curbyte = 0; + apb->flags = 0; + + while (0 < apb->nbytes && apb->nbytes < apb->nmaxbytes) + { + int n = apb->nmaxbytes - apb->nbytes; + int ret = read(ctl->fd, &apb->samp[apb->nbytes], n); + + if (0 >= ret) + { + break; + } + apb->nbytes += ret; + } + + if (apb->nbytes < apb->nmaxbytes) + { + close(ctl->fd); + ctl->fd = -1; + + return ; + } + + ctl->file_position += apb->nbytes; + + nxaudio_enqbuffer(&ctl->nxaudio, apb); +} + +static void app_complete_cb(unsigned long arg) +{ + /* Do nothing.. */ + + printf("Audio loop is Done\n"); +} + +static void app_user_cb(unsigned long arg, + FAR struct audio_msg_s *msg, FAR bool *running) +{ + /* Do nothing.. */ +} + +static FAR void *audio_loop_thread(pthread_addr_t arg) +{ + FAR audioctl_s *ctl = (FAR audioctl_s *)arg; + + nxaudio_start(&ctl->nxaudio); + nxaudio_msgloop(&ctl->nxaudio, &cbs, + (unsigned long)(uintptr_t)ctl); + + return NULL; +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +FAR audioctl_s *audio_ctl_init_nxaudio(FAR const char *arg) +{ + FAR audioctl_s *ctl; + int ret; + int i; + + ctl = (FAR audioctl_s *)malloc(sizeof(audioctl_s)); + if(ctl == NULL) + { + return NULL; + } + + ctl->seek = false; + ctl->seek_position = 0; + ctl->file_position = 0; + + ctl->fd = open(arg, O_RDONLY); + if (ctl->fd < 0) { + printf("can't open audio file\n"); + return NULL; + } + + read(ctl->fd, &ctl->wav, sizeof(ctl->wav)); + + ret = init_nxaudio(&ctl->nxaudio, ctl->wav.fmt.samplerate, + ctl->wav.fmt.bitspersample, + ctl->wav.fmt.numchannels); + if (ret < 0) + { + printf("init_nxaudio() return with error!!\n"); + return NULL; + } + + for (i = 0; i < ctl->nxaudio.abufnum; i++) + { + app_dequeue_cb((unsigned long)ctl, ctl->nxaudio.abufs[i]); + } + + ctl->state = AUDIO_CTL_STATE_INIT; + + return ctl; +} + +int audio_ctl_start(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_INIT && ctl->state != AUDIO_CTL_STATE_PAUSE) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_START; + + pthread_attr_t tattr; + struct sched_param sparam; + + pthread_attr_init(&tattr); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 9; + pthread_attr_setschedparam(&tattr, &sparam); + pthread_attr_setstacksize(&tattr, 4096); + + pthread_create(&ctl->pid, &tattr, audio_loop_thread, + (pthread_addr_t)ctl); + + pthread_attr_destroy(&tattr); + pthread_setname_np(ctl->pid, "audioctl_thread"); + + return 0; +} + +int audio_ctl_pause(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_START) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_PAUSE; + + return nxaudio_pause(&ctl->nxaudio); +} + +int audio_ctl_resume(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_PAUSE) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_START; + + return nxaudio_resume(&ctl->nxaudio); +} + +int audio_ctl_seek(FAR audioctl_s *ctl, unsigned ms) +{ + if (ctl == NULL) + return -EINVAL; + + ctl->seek_position = ms * ctl->wav.fmt.samplerate * ctl->wav.fmt.bitspersample * ctl->wav.fmt.numchannels / 8; + ctl->seek = true; + + return 0; +} + +int audio_ctl_stop(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_PAUSE && ctl->state != AUDIO_CTL_STATE_START) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_STOP; + + nxaudio_stop(&ctl->nxaudio); + + if (ctl->pid > 0) + { + pthread_join(ctl->pid, NULL); + } + + return 0; +} + +int audio_ctl_set_volume(FAR audioctl_s *ctl, uint16_t vol) +{ + if (ctl == NULL) + return -EINVAL; + + return nxaudio_setvolume(&ctl->nxaudio, vol); +} + +int audio_ctl_get_position(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + return ctl->file_position / (ctl->wav.fmt.bitspersample * ctl->wav.fmt.numchannels * ctl->wav.fmt.samplerate / 8); +} + +int audio_ctl_uninit_nxaudio(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state == AUDIO_CTL_STATE_NOP) + { + return 0; + } + + if (ctl->fd > 0) + { + close(ctl->fd); + ctl->fd = -1; + } + + fin_nxaudio(&ctl->nxaudio); + + free(ctl); + + return 0; +} diff --git a/breakout/src/Audio/audio_ctl.h b/breakout/src/Audio/audio_ctl.h new file mode 100644 index 0000000000000000000000000000000000000000..e7e60993b3da128a7917731c5f59195a718653f2 --- /dev/null +++ b/breakout/src/Audio/audio_ctl.h @@ -0,0 +1,85 @@ +#ifndef AUDIO_CTL_H +#define AUDIO_CTL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include <audioutils/nxaudio.h> +#include <pthread.h> + +enum { + AUDIO_CTL_STATE_NOP, + AUDIO_CTL_STATE_INIT, + AUDIO_CTL_STATE_START, + AUDIO_CTL_STATE_PAUSE, + AUDIO_CTL_STATE_STOP, +}; + +typedef struct wav_riff { + /* chunk "riff" */ + char chunkID[4]; /* "RIFF" */ + /* sub-chunk-size */ + uint32_t chunksize; /* 36 + subchunk2size */ + /* sub-chunk-data */ + char format[4]; /* "WAVE" */ +} riff_s; + +typedef struct wav_fmt { + /* sub-chunk "fmt" */ + char subchunk1ID[4]; /* "fmt " */ + /* sub-chunk-size */ + uint32_t subchunk1size; /* 16 for PCM */ + /* sub-chunk-data */ + uint16_t audioformat; /* PCM = 1*/ + uint16_t numchannels; /* Mono = 1, Stereo = 2, etc. */ + uint32_t samplerate; /* 8000, 44100, etc. */ + uint32_t byterate; /* = samplerate * numchannels * bitspersample/8 */ + uint16_t blockalign; /* = numchannels * bitspersample/8 */ + uint16_t bitspersample; /* 8bits, 16bits, etc. */ +} fmt_s; + +typedef struct wav_data { + /* sub-chunk "data" */ + char subchunk2ID[4]; /* "data" */ + /* sub-chunk-size */ + uint32_t subchunk2size; /* data size */ + /* sub-chunk-data */ + //Data_block_t block; +} data_s; + +typedef struct wav_fotmat { + riff_s riff; + fmt_s fmt; + data_s data; +} wav_s; + +typedef struct audioctl { + struct nxaudio_s nxaudio; + wav_s wav; + int fd; + int state; + pthread_t pid; + int seek; + uint32_t seek_position; + uint32_t file_position; +} audioctl_s; + +FAR audioctl_s *audio_ctl_init_nxaudio(FAR const char *arg); +int audio_ctl_start(FAR audioctl_s *ctl); +int audio_ctl_pause(FAR audioctl_s *ctl); +int audio_ctl_resume(FAR audioctl_s *ctl); +int audio_ctl_seek(FAR audioctl_s *ctl, unsigned ms); +int audio_ctl_stop(FAR audioctl_s *ctl); +int audio_ctl_set_volume(FAR audioctl_s *ctl, uint16_t vol); +int audio_ctl_get_position(FAR audioctl_s *ctl); +int audio_ctl_uninit_nxaudio(FAR audioctl_s *ctl); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* AUDIO_CTL_H */ diff --git a/breakout/src/Ball/Ball.cpp b/breakout/src/Ball/Ball.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba03e3d5b9543443b6a623e4289e767c45bcea24 --- /dev/null +++ b/breakout/src/Ball/Ball.cpp @@ -0,0 +1,72 @@ +#include "Ball.h" +#include "GameResourceManager/GameResourceManager.h" +#include <cmath> + +// Gravity acceleration +static const float GRAVITY = 300.0f; +// Maximum ball speed +static const float MAX_BALL_SPEED = 900.0f; + +// Constructor +Ball::Ball(lv_obj_t* parent, float radius, State initialState) + : m_state(initialState), m_radius(radius), m_pos({0,0}), m_vel({0,0}) +{ + GameResourceManager resourceManager; + m_ball_src = resourceManager.getIconSource("ball.png"); + +} + + +void Ball::limitSpeed(float maxSpeed) { + float speedSq = m_vel.x * m_vel.x + m_vel.y * m_vel.y; + float maxSpeedSq = maxSpeed * maxSpeed; + + if (speedSq > maxSpeedSq) { + float currentSpeed = sqrtf(speedSq); + m_vel.x = (m_vel.x / currentSpeed) * maxSpeed; + m_vel.y = (m_vel.y / currentSpeed) * maxSpeed; + } +} + +void Ball::update(float deltaTime) { + if (m_state != State::MOVING) return; + + // Apply gravity + m_vel.y += GRAVITY * deltaTime; + + // Limit speed + limitSpeed(MAX_BALL_SPEED); + + // Update position + m_pos.x += m_vel.x * deltaTime; + m_pos.y += m_vel.y * deltaTime; +} + +void Ball::stickToPaddle(const Rect& paddleRect) { + if (m_state != State::HELD) return; + m_pos.x = paddleRect.x + paddleRect.width / 2.0f; + m_pos.y = paddleRect.y - m_radius; +} + +void Ball::launch() { + if (m_state == State::HELD) { + m_state = State::MOVING; + m_vel = {150.0f, -900.0f}; + } +} + +void Ball::bounceX() { m_vel.x = -m_vel.x; } +void Ball::bounceY() { m_vel.y = -m_vel.y; } +void Ball::boostSpeed(float factor) { m_vel.x *= factor; m_vel.y *= factor; } + +void Ball::setPosition(const Vec2& pos) { m_pos = pos; } +void Ball::setVelocity(const Vec2& vel) { m_vel = vel; } + +Vec2 Ball::getPosition() const { return m_pos; } +Vec2 Ball::getVelocity() const { return m_vel; } +Ball::State Ball::getState() const { return m_state; } +float Ball::getRadius() const { return m_radius; } +void Ball::setState(State state) { m_state = state; } +void Ball::setRadius(float r) { m_radius = r; } +const lv_draw_buf_t* Ball::get_ball_src() {return m_ball_src;} + diff --git a/breakout/src/Ball/Ball.h b/breakout/src/Ball/Ball.h new file mode 100644 index 0000000000000000000000000000000000000000..06bf60138bc7d7cc8db947e0695c57889abcce40 --- /dev/null +++ b/breakout/src/Ball/Ball.h @@ -0,0 +1,42 @@ +#ifndef BALL_H +#define BALL_H + +#pragma once + +#include "breakout_types.h" + +class Ball { +public: + enum class State { HELD, MOVING, STATIC }; + + Ball(lv_obj_t* parent, float radius, Ball::State state = State::HELD); + + void limitSpeed(float maxSpeed); + void update(float deltaTime); + void stickToPaddle(const Rect& paddleRect); + void launch(); + void bounceX(); + void bounceY(); + void setPosition(const Vec2& pos); + void setVelocity(const Vec2& vel); + void boostSpeed(float factor); + + Vec2 getVelocity() const; + State getState() const; + Vec2 getPosition() const; + float getRadius() const; + void setState(State state); + void setRadius(float r); + const lv_draw_buf_t* get_ball_src(); + + +private: + State m_state; + float m_radius; + Vec2 m_pos; + Vec2 m_vel; + const lv_draw_buf_t* m_ball_src; + uint8_t* m_buf; +}; + +#endif // BALL_H \ No newline at end of file diff --git a/breakout/src/Brick/Brick.cpp b/breakout/src/Brick/Brick.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d7fe4d9a31bee95c647db718161156f90fcc3793 --- /dev/null +++ b/breakout/src/Brick/Brick.cpp @@ -0,0 +1,127 @@ +/******************************************** + * Brick.cpp + * Implementation file for the Brick class + * Responsible for creating individual bricks, managing hit points, updating colors, and handling collisions. + *******************************************/ +#include "GameResourceManager/GameResourceManager.h" +#include "Brick.h" + +/***************************************** + * x Brick's X coordinate + * y Brick's Y coordinate + * width Brick's width (also used for height as bricks are square) + * type Character representing the brick type and its initial hit points + ****************************************/ +Brick::Brick(lv_obj_t* parent, float x, float y, float width, char type) + : m_is_active(true), + m_rect{x, y, width, width}, + m_gui_object(nullptr) +{ + // Set hit points based on brick type character + switch(type) { + case '#': m_hp = -1; break; // Indestructible wall + case 'A': m_hp = 1; break; + case 'B': m_hp = 2; break; + case 'C': m_hp = 3; break; + case 'D': m_hp = 4; break; + case 'E': m_hp = 5; break; + default: m_hp = 1; break; + } + + m_gui_object = lv_img_create(parent); + if (!m_gui_object) { + printf("Failed to create lv_img object\n"); + return; + } + updateImage(); + // Set position and size + lv_obj_set_pos(m_gui_object, x, y); + lv_obj_set_size(m_gui_object, width, width); + + // Add black border style + lv_style_init(&m_border_style); + lv_style_set_bg_color(&m_border_style, lv_color_white()); + lv_style_set_border_width(&m_border_style, 1); + lv_style_set_border_color(&m_border_style, lv_color_black()); + lv_style_set_pad_all(&m_border_style, 0); + lv_obj_add_style(m_gui_object, &m_border_style, 0); +} + +/*************************************** + * Destructor automatically called when Brick object is deleted + * Ensures corresponding UI object is also removed from screen to prevent memory leaks. + ***************************************/ +Brick::~Brick() { + if (m_gui_object) { + lv_obj_del(m_gui_object); + m_gui_object = nullptr; + } + lv_style_reset(&m_border_style); +} + +/** + * Called when the ball hits the brick + */ +void Brick::onHit() { + // Only apply damage if hit points > 0 (i.e., not an indestructible wall) + if (m_hp > 0) { + m_hp--; // Decrease hit points by 1 + + if (m_hp == 0) { + // If hit points are depleted + m_is_active = false; // Mark brick as inactive, collision checks will ignore it + lv_obj_add_flag(m_gui_object, LV_OBJ_FLAG_HIDDEN); // Hide brick's UI object on screen + } else { + // If still has hit points, update color for visual feedback + updateImage(); + } + } +} + +/** + * Checks if the brick is currently active (not destroyed) + * Returns true if active, false if destroyed + */ +bool Brick::isActive() const { + return m_is_active; +} + +/** + * Gets the bounding box of the brick (collision box) + * Returns a Rect containing position and size + */ +Rect Brick::getBoundingBox() const { + return m_rect; +} + +int Brick::getHP() const { + return m_hp; +} + +/** + * Updates the brick's background image based on current hit points + */ +void Brick::updateImage() { + if (!m_gui_object) return; + + std::string image_filename; + switch (m_hp) { + case -1: image_filename = "brick_#.png"; break; // Wall: black + case 1: image_filename = "brick_A.png"; break; // HP=1: green + case 2: image_filename = "brick_B.png"; break; // HP=2: orange + case 3: image_filename = "brick_C.png"; break; // HP=3: purple + case 4: image_filename = "brick_D.png"; break; // HP=4: yellow + case 5: image_filename = "brick_E.png"; break; // HP=5: blue + default: image_filename = "brick_A.png"; break; // green + } + + GameResourceManager resourceManager; + auto img_src = resourceManager.getIconSource(image_filename); + if(img_src) { + lv_img_set_src(m_gui_object, img_src); + } + else{ + printf("Failed to load brick.png\n"); + } + +} diff --git a/breakout/src/Brick/Brick.h b/breakout/src/Brick/Brick.h new file mode 100644 index 0000000000000000000000000000000000000000..033842f4caa4c8908be80ae5e98dd91b656a1de7 --- /dev/null +++ b/breakout/src/Brick/Brick.h @@ -0,0 +1,25 @@ +#ifndef BRICK_H +#define BRICK_H + +#pragma once +#include "breakout_types.h" + +class Brick { +public: + Brick(lv_obj_t* parent, float x, float y, float width, char type); + ~Brick(); + void onHit(); + bool isActive() const; + Rect getBoundingBox() const; + int getHP() const; + lv_obj_t* getGUIObject() const { return m_gui_object; } +private: + void updateImage(); + int m_hp; + bool m_is_active; + Rect m_rect; + lv_obj_t* m_gui_object; + lv_style_t m_style; + lv_style_t m_border_style; +}; +#endif // BRICK_H \ No newline at end of file diff --git a/breakout/src/GameResourceManager/GameResourceManager.cpp b/breakout/src/GameResourceManager/GameResourceManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a64cdd02a2f7c581ee848b392f69e96400e0195 --- /dev/null +++ b/breakout/src/GameResourceManager/GameResourceManager.cpp @@ -0,0 +1,251 @@ +/** + * GameResourceManager.cpp + * Implementation file for the game resource manager. + * Responsible for constructing resource paths, loading level maps, + * and managing the image resource cache. + * (Version: uses lv_draw_buf_dup and lv_draw_buf_destroy) + */ + +#include "GameResourceManager.h" +#include <cstdio> +#include <time.h> +#include "Brick/Brick.h" +#include "breakout.h" +int GameResourceManager::currentLevel = 1; +// Define the static member variable for image caching, now storing lv_draw_buf_t* +std::map<std::string, lv_draw_buf_t*> GameResourceManager::s_imageCache; + +GameResourceManager::GameResourceManager() : m_audioCtl(nullptr) {} +GameResourceManager::~GameResourceManager() { + stopAudio(); +} + +/** + * @brief Frees all cached image resources. + * Equivalent to the `cleanup_resources` function from your example. + */ +void GameResourceManager::cleanupCache() { + printf("[ResourceManager] Cleaning up image cache, %zu items to delete.\n", s_imageCache.size()); + for (auto const& [key, buf] : s_imageCache) { + if (buf != nullptr) { + lv_draw_buf_destroy(buf); // Use LVGL function to destroy draw_buf + } + } + s_imageCache.clear(); + printf("[ResourceManager] Cache cleanup complete.\n"); +} + + +/** + * @brief Get the current game level, ensuring it stays within the valid range (1–6). + * If currentLevel is less than 1 or greater than 6, it resets to 1. + * @return The current level number. + */ +int GameResourceManager::getCurrentLevel() { + if (currentLevel < 1) { + currentLevel = 1; + } else if (currentLevel > 6) { + currentLevel = 1; + } + return currentLevel; +} + +/** + * @brief Set the current game level. + * @param level The new level number to set. + * Note: The level is not automatically clamped here; getCurrentLevel() enforces valid range. + */ +void GameResourceManager::setCurrentLevel(int level) { + currentLevel = level; +} + +/** + * @brief Retrieves an icon resource. Loads and caches it if not already cached. + * Core logic corresponding to your `app_create_main_page` example. + */ +const lv_draw_buf_t* GameResourceManager::getIconSource(const std::string& iconName) { + // 1. Check cache + auto it = s_imageCache.find(iconName); + if (it != s_imageCache.end()) { + return it->second; + } + + // 2. Load and decode + std::string fullPath = getIconsPath() + "/" + iconName; + + lv_image_decoder_dsc_t decoder_dsc; + lv_result_t res = lv_image_decoder_open(&decoder_dsc, fullPath.c_str(), NULL); + + if (res != LV_RESULT_OK) { + printf("[ERROR] Failed to open image decoder: %s\n", fullPath.c_str()); + return nullptr; + } + + // 3. Copy the decoded image data to a permanent draw_buf + lv_draw_buf_t* permanent_buf = lv_draw_buf_dup(decoder_dsc.decoded); + + // 4. Close decoder and free temporary resources + lv_image_decoder_close(&decoder_dsc); + + if (permanent_buf == nullptr) { + printf("[ERROR] Failed to duplicate draw buffer.\n"); + return nullptr; + } + + // 5. Cache and return + s_imageCache[iconName] = permanent_buf; + //printf("[ResourceManager] New image cached: %s\n", iconName.c_str()); + + return permanent_buf; +} + +// --- Resource path accessors --- + +std::string GameResourceManager::getResPath() { + return std::string(RES_ROOT) + "/res"; +} + +std::string GameResourceManager::getMapPath() { + return getResPath() + "/map"; +} + +std::string GameResourceManager::getFontsPath() { + return getResPath() + "/fonts"; +} + +std::string GameResourceManager::getIconsPath() { + return getResPath() + "/icons"; +} + +std::string GameResourceManager::getAudioPath() { + return getResPath() + "/audio"; +} + +/** + * @brief Loads a map from file and populates the game brick list. + */ +bool GameResourceManager::loadMap(const std::string& mapName, Game* game) { + std::string fullPath = getMapPath() + "/" + mapName; + const int BRICK_COLS = 80; + const int BRICK_ROWS = 35; + const float BRICK_WIDTH = (float)GAME_AREA_WIDTH / BRICK_COLS; + FILE* file = fopen(fullPath.c_str(), "r"); + if (!file) { + return false; + } + char line[BRICK_COLS + 2]; + for (int row = 0; row < BRICK_ROWS; ++row) { + if (!fgets(line, sizeof(line), file)) { + break; + } + for (int col = 0; col < BRICK_COLS && line[col] != '\0'; ++col) { + char brickType = line[col]; + if (brickType != ' ' && brickType != '\n' && brickType != '\r') { + float x = col * BRICK_WIDTH; + float y = row * BRICK_WIDTH; + Brick* newBrick = new Brick(game->m_game_area, x, y, BRICK_WIDTH, brickType); + game->m_bricks.push_back(newBrick); + } + } + } + fclose(file); + return true; +} + +/** + * @brief Loads and displays a background image onto the parent object. + */ +void GameResourceManager::loadBackground(lv_obj_t* parent, const std::string& iconName) { + const lv_draw_buf_t* bg_src = getIconSource(iconName); + if (!bg_src) return; + + lv_obj_t* bg_img = lv_img_create(parent); + lv_img_set_src(bg_img, bg_src); // Use draw buffer directly + lv_obj_set_size(bg_img, GAME_AREA_WIDTH, GAME_AREA_HEIGHT); + lv_obj_align(bg_img, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_move_background(bg_img); +} + +/** + * @brief Plays the corresponding audio based on the brick HP. + * + * This function selects the appropriate `.wav` file based on the brick's HP, + * initializes or reinitializes the audio controller, and starts audio playback. + * If the current audio is already playing for the given brick HP, it avoids reinitialization. + * + * @param brickHp The HP of the brick, used to select the correct audio file. + * @return true if the audio started successfully, false if an error occurred. + */ +bool GameResourceManager::playAudio(int brickHp) { + static struct timespec lastPlayTime = {0, 0}; + struct timespec now; + + clock_gettime(CLOCK_MONOTONIC, &now); + + long diffMs = (now.tv_sec - lastPlayTime.tv_sec) * 1000 + + (now.tv_nsec - lastPlayTime.tv_nsec) / 1000000; + //Set a cooldown time to protect against excessive triggering + const int COOLDOWN_MS = 500; + if (diffMs < COOLDOWN_MS) { + return false; + } + lastPlayTime = now; + + const char* wavFile = nullptr; + // Select appropriate audio file based on brick's HP + switch (brickHp) { + case -1: wavFile = "C4.wav"; break; // For brick HP -1, play C4.wav + case 1: wavFile = "E4.wav"; break; // For brick HP 1, play E4.wav + case 2: wavFile = "F4.wav"; break; // For brick HP 2, play F4.wav + case 3: wavFile = "G4.wav"; break; // For brick HP 3, play G4.wav + case 4: wavFile = "A4.wav"; break; // For brick HP 4, play A4.wav + case 5: wavFile = "B4.wav"; break; // For brick HP 5, play B4.wav + case 6: wavFile = "C5.wav"; break; // For brick HP 6, play C5.wav + default: wavFile = "C4.wav"; break; // Default case, play C4.wav + } + + // Build full audio file path + std::string fullPath = getAudioPath() + "/" + wavFile; + + if (!m_audioCtl) { + // If no audio control is initialized, initialize the audio controller + m_audioCtl = audio_ctl_init_nxaudio(fullPath.c_str()); + audio_ctl_start(m_audioCtl); + if (!m_audioCtl) { + //printf("[Audio] Failed to initialize audio: %s\n", fullPath.c_str()); + return false; + } + } else { + //printf("[Audio] Stopping and reinitializing audio controller...\n"); + audio_ctl_stop(m_audioCtl); + //audio_ctl_seek(m_audioCtl, 0); + audio_ctl_uninit_nxaudio(m_audioCtl); + //m_audioCtl = NULL; + m_audioCtl = audio_ctl_init_nxaudio(fullPath.c_str()); + audio_ctl_start(m_audioCtl); + } + return false; +} +/** + * @brief Stops the currently playing audio and releases resources. + * + * This function stops the audio if it is currently playing, uninitializes the + * audio controller, and frees associated resources. + */ +void GameResourceManager::stopAudio() { + // Check if the audio controller is initialized + if (m_audioCtl) { + //printf("[Audio] Stopping and uninitializing audio controller...\n"); + + // If audio is playing, stop it + audio_ctl_stop(m_audioCtl); + + // Uninitialize the audio controller and clean up + audio_ctl_uninit_nxaudio(m_audioCtl); + m_audioCtl = nullptr; + + //printf("[Audio] Audio stopped and cleaned up.\n"); + } else { + //printf("[Audio] No audio to stop.\n"); + } +} diff --git a/breakout/src/GameResourceManager/GameResourceManager.h b/breakout/src/GameResourceManager/GameResourceManager.h new file mode 100644 index 0000000000000000000000000000000000000000..ab466627daf4624f6ad0ab3afec8da7e3ddbf1aa --- /dev/null +++ b/breakout/src/GameResourceManager/GameResourceManager.h @@ -0,0 +1,52 @@ +#ifndef GAME_RESOURCE_MANAGER_H +#define GAME_RESOURCE_MANAGER_H + +#include <string> +#include <map> +#include "lvgl.h" +#include "Audio/audio_ctl.h" + +#define RES_ROOT CONFIG_LVX_BREAKOUT_DATA_ROOT + +class Game; + +class GameResourceManager { +public: + // Constructor + GameResourceManager(); + + // Destructor + ~GameResourceManager(); + + // Resource path getters + std::string getResPath(); // Get root resource path + std::string getMapPath(); // Get map resource path + std::string getFontsPath(); // Get fonts resource path + std::string getIconsPath(); // Get icons resource path + std::string getAudioPath(); // Get audio resource path + + // Audio control + bool playAudio(int brickHp); // Play audio corresponding to brick HP + void stopAudio(); // Stop audio playback + + // Map and background loading + bool loadMap(const std::string& mapName, Game* game); // Load a map file into the game + void loadBackground(lv_obj_t* parent, const std::string& iconName); // Load background image + + // Image resource management + const lv_draw_buf_t* getIconSource(const std::string& iconName); // Get cached or decoded image + + // Static level management + static int getCurrentLevel(); // Get current game level + static void setCurrentLevel(int level); // Set current game level + + // Static resource cache cleanup + static void cleanupCache(); // Free all cached images + +private: + static std::map<std::string, lv_draw_buf_t*> s_imageCache; // Static image cache + audioctl_s* m_audioCtl = nullptr; // Audio control handle + static int currentLevel; // Current game level +}; + +#endif // GAME_RESOURCE_MANAGER_H \ No newline at end of file diff --git a/breakout/src/Paddle/Paddle.h b/breakout/src/Paddle/Paddle.h new file mode 100644 index 0000000000000000000000000000000000000000..d16b34a47f263e8d4beb01d73857bc21716fa867 --- /dev/null +++ b/breakout/src/Paddle/Paddle.h @@ -0,0 +1,37 @@ +#ifndef PADDLE_H +#define PADDLE_H + +#include "lvgl.h" +#include "breakout_types.h" + +class Paddle { +public: + // Constructor + Paddle(lv_obj_t* parent, float startX, float startY, float width, float height, Rect screenBounds); + + // Destructor + ~Paddle(); + + // Member function declarations + void update(float deltaTime); // Update paddle position based on movement + Rect getBoundingBox() const; // Get the paddle's bounding rectangle + void moveTo(float targetX); // Move paddle to target X position + void stopMovement(); // Stop paddle movement + float getX() const; // Get current X position + float getY() const; // Get current Y position + float getWidth() const; // Get current width + void setWidth(float w); // Set paddle width + +private: + float m_x; // Current X position + float m_y; // Current Y position + float m_width; // Paddle width + float m_height; // Paddle height + float m_targetX; // Target X position for movement + bool m_isMoving; // Whether paddle is moving + lv_obj_t* m_parent; // Pointer to parent LVGL object + Rect m_screenBounds; // Boundaries of the game screen + lv_obj_t* m_gui_object; // Pointer to LVGL image object representing the paddle +}; + +#endif // PADDLE_H diff --git a/breakout/src/Paddle/paddle.cpp b/breakout/src/Paddle/paddle.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a175ede8db91838a7344118734d2c7eef9c0307 --- /dev/null +++ b/breakout/src/Paddle/paddle.cpp @@ -0,0 +1,134 @@ +/************************************** + * Paddle.cpp + * Implementation file for the player-controlled paddle class + * Responsible for paddle creation, updating, movement, and boundary checking logic. + *************************************/ +#include "Paddle.h" +#include "GameResourceManager/GameResourceManager.h" +#include <algorithm> +#include <cmath> +#include <cstdio> + + + +Paddle::Paddle(lv_obj_t* parent, float startX, float startY, float width, float height, Rect screenBounds) + : m_x(startX), + m_y(startY), + m_width(width), + m_height(height), + m_targetX(0.0f), + m_isMoving(false), + m_parent(parent), + m_screenBounds(screenBounds), + m_gui_object(nullptr) +{ + //printf("DEBUG: Paddle constructor called.\n"); + + // Image data and descriptor must remain static to ensure their lifetime + + GameResourceManager resourceManager; + auto paddle_src = resourceManager.getIconSource("KUN.png"); + + //printf("DEBUG: Paddle image requested from cache/file.\n"); + + m_gui_object = lv_img_create(m_parent); + if (!m_gui_object) { + printf("Failed to create lv_img object\n"); + return; + } + + if(paddle_src) { + lv_img_set_src(m_gui_object, paddle_src); + } + else{ + printf("Failed to load KUN.png\n"); + } + lv_obj_set_size(m_gui_object, (lv_coord_t)m_width, (lv_coord_t)m_height); + lv_obj_set_pos(m_gui_object, (lv_coord_t)m_x, (lv_coord_t)m_y); + + m_targetX = m_x + m_width / 2.0f; +} + +Paddle::~Paddle() { + printf("DEBUG: Paddle destructor called. Deleting lv_obj...\n"); + if (m_gui_object) { + lv_obj_del(m_gui_object); + m_gui_object = nullptr; + } +} + +void Paddle::update(float deltaTime) { + if (m_isMoving) { + float diff = m_targetX - (m_x + m_width / 2.0f); + float speed = 950.0f; // Movement speed, can be adjusted as needed + if (std::abs(diff) > 1.0f) { + float move = speed * deltaTime; + if (diff > 0) { + m_x += std::min(move, diff); + } else { + m_x += std::max(-move, diff); + } + + // Boundary check + m_x = std::max(m_screenBounds.x, std::min(m_x, m_screenBounds.x + m_screenBounds.width - m_width)); + + if (m_gui_object) { + lv_obj_set_x(m_gui_object, (lv_coord_t)m_x); + } + } else { + m_isMoving = false; + } + } +} + +Rect Paddle::getBoundingBox() const { + return {m_x, m_y, m_width, m_height}; +} + +void Paddle::moveTo(float targetX) { + m_targetX = targetX; + m_isMoving = true; +} + +void Paddle::stopMovement() { + m_isMoving = false; +} + +float Paddle::getX() const { return m_x; } + +float Paddle::getY() const { return m_y; } +float Paddle::getWidth() const { return m_width; } +void Paddle::setWidth(float w) { + m_width = w; + + // Each KUN.png is 80 pixels wide + const int baseWidth = 80.0f; + // Ensure w is a multiple of 80 + int repeatCount = static_cast<int>(w / baseWidth); + + if (m_gui_object) { + lv_obj_del(m_gui_object); + m_gui_object = nullptr; + } + + + m_gui_object = lv_obj_create(m_parent); + lv_obj_set_size(m_gui_object, (lv_coord_t)repeatCount * baseWidth, (lv_coord_t)m_height); + lv_obj_set_pos(m_gui_object,(lv_coord_t)m_x, (lv_coord_t)m_y); + lv_obj_clear_flag(m_gui_object, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_opa(m_gui_object, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(m_gui_object, 0, 0); + GameResourceManager resourceManager; + const void* paddle_src = resourceManager.getIconSource("KUN.png"); + if (!paddle_src) { + printf("Failed to load KUN.png\n"); + return; + } + + for (int i = 0; i < repeatCount; ++i) { + lv_obj_t* img = lv_img_create(m_gui_object); + lv_img_set_src(img, paddle_src); + lv_obj_set_size(img, (lv_coord_t)baseWidth, (lv_coord_t)m_height); + lv_obj_set_pos(img, (lv_coord_t)i * (baseWidth-10), (lv_coord_t)(-20)); + } +} \ No newline at end of file diff --git a/breakout/src/PowerUp/PowerUp.cpp b/breakout/src/PowerUp/PowerUp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac656d1e1aa2fd9e32fe05e43a26b92cb10bb61c --- /dev/null +++ b/breakout/src/PowerUp/PowerUp.cpp @@ -0,0 +1,58 @@ +#include "PowerUp.h" +#include "GameResourceManager/GameResourceManager.h" +#include <cstdio> + +PowerUp::PowerUp(lv_obj_t* parent, Type type, const Vec2& pos) + : m_type(type), m_position(pos), m_speed(200.0f), m_active(true) +{ + m_obj = lv_img_create(parent); + GameResourceManager resourceManager; + + switch (type) { + case Type::SPLIT_BALL: { + auto src = resourceManager.getIconSource("three_balls.png"); + lv_img_set_src(m_obj, src); + break; + } + case Type::EXTRA_PADDLE: { + auto src = resourceManager.getIconSource("friends.png"); + lv_img_set_src(m_obj, src); + break; + } + case Type::UP_BALLS: { + auto src = resourceManager.getIconSource("up_balls.png"); + lv_img_set_src(m_obj, src); + break; + } + case Type::TROPHY: { + auto src = resourceManager.getIconSource("trophy.png"); + lv_img_set_src(m_obj, src); + break; + } + } + + lv_obj_set_pos(m_obj, (lv_coord_t)pos.x, (lv_coord_t)pos.y); +} + +PowerUp::~PowerUp() { + if (m_obj) { + lv_obj_del(m_obj); + m_obj = nullptr; + } +} + +void PowerUp::update(float deltaTime) { + if (!m_active) return; + m_position.y += m_speed * deltaTime; // fall down + if (m_obj) { + lv_obj_set_pos(m_obj, (lv_coord_t)m_position.x, (lv_coord_t)m_position.y); + } +} + +void PowerUp::remove() { + m_active = false; + if (m_obj) { + lv_obj_del(m_obj); + m_obj = nullptr; + } +} diff --git a/breakout/src/PowerUp/PowerUp.h b/breakout/src/PowerUp/PowerUp.h new file mode 100644 index 0000000000000000000000000000000000000000..5cffe8ec095b94ebc2b76e405ad5cf9d2ceae9be --- /dev/null +++ b/breakout/src/PowerUp/PowerUp.h @@ -0,0 +1,35 @@ +#ifndef POWERUP_H +#define POWERUP_H + +#include "breakout_types.h" +#include <lvgl.h> + +class PowerUp { +public: + // Define available power-up types + enum class Type { + SPLIT_BALL, // Split the ball into multiple balls + EXTRA_PADDLE, // Enlarge the paddle + UP_BALLS, // Make all balls move upward + TROPHY // Level complete + }; + + PowerUp(lv_obj_t* parent, Type type, const Vec2& pos); + ~PowerUp(); + + void update(float deltaTime); // Move downward + void remove(); // Destroy GUI object + Type getType() const { return m_type; } + Vec2 getPosition() const { return m_position; } // For collision + bool isActive() const { return m_active; } + +private: + Type m_type; + Vec2 m_position; + float m_speed; // Falling speed + bool m_active; + + lv_obj_t* m_obj; // LVGL object (image) +}; + +#endif // POWERUP_H \ No newline at end of file diff --git a/breakout/src/breakout.cpp b/breakout/src/breakout.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a045827557c4e105775c78dd062f4473b1d042f8 --- /dev/null +++ b/breakout/src/breakout.cpp @@ -0,0 +1,693 @@ +/****************************************************************** + * breakout.cpp + * Main game logic implementation file + * Contains all method implementations for the Game class, as well as + * the global game entry point ballgame_start(). + * The Game class manages the game state, object lifecycle, and core logic. + ********************************************************************/ + +#include "breakout.h" +#include <algorithm> +#include <cstdio> +#include <cmath> +#include <stdio.h> + +// ################################################# +// ## Implementation of Game class member functions +// ################################################# + +/** + * Constructor of the Game class + * @param parent The LVGL parent object on which the Game instance is created (usually the screen) + */ +Game::Game(lv_obj_t* parent) + : m_game_area(nullptr), + m_bricks(), + m_parent_screen(parent), + m_state(GameState::PLAYING), + m_game_timer(nullptr), + m_gameBounds(), + m_paddle(nullptr), + m_resourceManager(new GameResourceManager()) +{ + init(); +} + +/** + * Destructor of the Game class + * Responsible for safely cleaning up all dynamically allocated resources upon object destruction to prevent memory leaks. + */ +Game::~Game() { + printf("[Game] Destructor called, starting resource cleanup.\n"); + + // Clean up static resource cache + GameResourceManager::cleanupCache(); + if (m_resourceManager) { + m_resourceManager->stopAudio(); + delete m_resourceManager; + m_resourceManager = nullptr; + } + printf("[Game] Stopped audio\n"); + + // Delete all PowerUp + for (PowerUp* pu : m_powerUps) { + pu->remove(); + delete pu; + } + m_powerUps.clear(); + printf("[Game] Deleted all PowerUp\n"); + // Delete all balls + for (Ball* ball : m_balls) { + delete ball; // free Ball itself + } + m_balls.clear(); + printf("[Game] Deleted all balls\n"); + // Delete the game timer + if (m_game_timer) { + lv_timer_del(m_game_timer); + m_game_timer = nullptr; + } + printf("[Game] Deleted game timer\n"); + // Delete all bricks + for (Brick* b : m_bricks) { + if (b->getGUIObject()) { + lv_obj_del(b->getGUIObject()); // delete LVGL object + } + delete b; + } + m_bricks.clear(); + printf("[Game] Deleted bricks\n"); + + // Delete the paddle + delete m_paddle; + printf("[Game] Deleted paddle\n"); + + printf("[Game] Resource cleanup completed.\n"); +} + +/** + * @brief Initialize all game elements, UI, and timers + */ +void Game::init() { + printf("[Game] Init Start\n"); + // Create the UI object serving as game background and container + m_game_area = lv_obj_create(m_parent_screen); + lv_obj_set_size(m_game_area, GAME_AREA_WIDTH, GAME_AREA_HEIGHT); + lv_obj_center(m_game_area); + lv_obj_set_style_bg_color(m_game_area, lv_color_white(), 0); + lv_obj_set_style_border_width(m_game_area, 0, 0); + lv_obj_set_style_radius(m_game_area, 0, 0); + lv_obj_set_style_pad_all(m_game_area, 0, 0); + lv_obj_clear_flag(m_game_area, LV_OBJ_FLAG_SCROLLABLE); + + // Define game logic boundaries (relative to m_game_area) + m_gameBounds = {0, 0, (float)GAME_AREA_WIDTH, (float)GAME_AREA_HEIGHT}; + + // Load level map and background + char bgFile[32]; + char mapFile[32]; + snprintf(bgFile, sizeof(bgFile), "background_%d.png", m_resourceManager->getCurrentLevel()); + snprintf(mapFile, sizeof(mapFile), "level_%d.dat", m_resourceManager->getCurrentLevel()); + m_resourceManager->loadBackground(m_game_area, bgFile); + m_resourceManager->loadMap(mapFile, this); + + // Create paddle + m_paddle = new Paddle(m_game_area, + (GAME_AREA_WIDTH / 2.0f) - 50.0f, + GAME_AREA_HEIGHT - 70.0f, + 80.0f, 80.0f, m_gameBounds); + printf("[Game] Paddle created\n"); + + // Create first ball + Ball* newBall = new Ball(m_game_area, 16.0f, Ball::State::HELD); + m_balls.push_back(newBall); + + + printf("[Game] Ball created\n"); + + // Create transparent touch layer to capture input + lv_obj_t* touch_area = lv_obj_create(m_game_area); + lv_obj_set_size(touch_area, GAME_AREA_WIDTH, GAME_AREA_HEIGHT); + lv_obj_set_pos(touch_area, 0, 0); + lv_obj_set_style_bg_opa(touch_area, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(touch_area, 0, 0); + lv_obj_add_event_cb(touch_area, touch_area_event_cb, LV_EVENT_ALL, this); + lv_obj_move_background(touch_area); + + // Create game loop timer + m_game_timer = lv_timer_create(game_timer_cb, GAME_TICK_PERIOD, this); + static uint8_t cbuf[LV_CANVAS_BUF_SIZE(GAME_AREA_WIDTH, GAME_AREA_HEIGHT, 32, LV_DRAW_BUF_STRIDE_ALIGN)]; + + // Add a canvas where all the balls will be drawn, and update their positions together. + m_canvas = lv_canvas_create(m_game_area); + lv_canvas_set_buffer(m_canvas, cbuf, GAME_AREA_WIDTH, GAME_AREA_HEIGHT, LV_COLOR_FORMAT_ARGB8888); + lv_obj_set_style_bg_opa(m_canvas, LV_OPA_TRANSP, 0); + lv_obj_align(m_canvas, LV_ALIGN_CENTER, 0, 0); + + + printf("[Game] Init End\n"); +} + +/** + * Game main loop timer callback + * Updates paddle, balls, collisions, and checks win/lose conditions + * @param timer Pointer to the LVGL timer + */ +void Game::game_timer_cb(lv_timer_t* timer) { + Game* game = static_cast<Game*>(timer->user_data); + if (game->m_state != GameState::PLAYING) return; + + const float deltaTime = (float)GAME_TICK_PERIOD / 1000.0f; + + // --- Update paddle position --- + game->m_paddle->update(deltaTime); + + // --- Iterate through all balls --- + for (auto it = game->m_balls.begin(); it != game->m_balls.end();) { + Ball* ball = *it; + Vec2 ballPos = ball->getPosition(); + + // Check if the ball has fallen below the bottom boundary + if (ballPos.y - ball->getRadius() >= game->m_gameBounds.y + game->m_gameBounds.height) { + ball->setState(Ball::State::STATIC); + ball->setVelocity({0.0f, 0.0f}); + } + + if (ball->getState() == Ball::State::HELD) { + ball->stickToPaddle(game->m_paddle->getBoundingBox()); + ++it; + continue; + } + + if (ball->getState() == Ball::State::STATIC) { + delete ball; + it = game->m_balls.erase(it); + continue; + } + + // MOVING state: update ball physics + ball->update(deltaTime); + + // Horizontal walls + if (ballPos.x - ball->getRadius() < game->m_gameBounds.x) { + ball->bounceX(); + ball->setPosition({game->m_gameBounds.x + ball->getRadius(), ballPos.y}); + } else if (ballPos.x + ball->getRadius() > game->m_gameBounds.x + game->m_gameBounds.width) { + ball->bounceX(); + ball->setPosition({game->m_gameBounds.x + game->m_gameBounds.width - ball->getRadius(), ballPos.y}); + } + + // Top wall + if (ballPos.y - ball->getRadius() < game->m_gameBounds.y) { + ball->bounceY(); + ball->boostSpeed(4.0f); + ball->setPosition({ballPos.x, game->m_gameBounds.y + ball->getRadius()}); + } + + // Ball-brick collision + game->handleBallBrickCollision(ball); + + // Ball-paddle collision + game->handleBallPaddleCollision(ball); + + ++it; + } + + // --- Update all power-ups --- + for (auto it = game->m_powerUps.begin(); it != game->m_powerUps.end();) { + PowerUp* pu = *it; + pu->update(deltaTime); + + if (game->checkPowerUpPaddleCollision(pu, game->m_paddle)) { + game->activatePowerUp(pu->getType()); + pu->remove(); + delete pu; + it = game->m_powerUps.erase(it); + continue; + } + + if (pu->getPosition().y > game->m_gameBounds.y + game->m_gameBounds.height) { + pu->remove(); + delete pu; + it = game->m_powerUps.erase(it); + continue; + } + + ++it; + } + + // --- Check pass level --- + bool allCleared = true; + for (Brick* b : game->m_bricks) { + if (b->isActive() && b->getHP() != -1) { + allCleared = false; + break; + } + } + if (allCleared) { + game->trigger_next_level(); + } + + // --- Check game over --- + bool allStatic = true; + for (Ball* ball : game->m_balls) { + if (ball->getState() != Ball::State::STATIC) { + allStatic = false; + break; + } + } + if (allStatic) { + game->trigger_game_over(); + } + + // --- Render all balls on canvas --- + lv_layer_t layer; + lv_canvas_init_layer(game->m_canvas, &layer); + + // Eliminate the trailing effect of the balls. + lv_canvas_fill_bg(game->m_canvas, lv_color_black(), LV_OPA_TRANSP); + + for (Ball* ball : game->m_balls) { + Vec2 pos = ball->getPosition(); + auto ballImg = ball->get_ball_src(); + if (!ballImg) continue; + + lv_draw_image_dsc_t dsc; + lv_draw_image_dsc_init(&dsc); + dsc.src = ballImg; + + lv_area_t coords; + coords.x1 = static_cast<int>(pos.x - ballImg->header.w / 2); + coords.y1 = static_cast<int>(pos.y - ballImg->header.h / 2); + coords.x2 = coords.x1 + ballImg->header.w - 1; + coords.y2 = coords.y1 + ballImg->header.h - 1; + + lv_draw_image(&layer, &dsc, &coords); + + } + + lv_canvas_finish_layer(game->m_canvas, &layer); + lv_obj_invalidate(game->m_canvas); + +} + + +Ball* Game::getMainBall() { + Ball* mainBall = nullptr; + float minY = std::numeric_limits<float>::max(); + + for (Ball* ball : m_balls) { + if (ball->getState() == Ball::State::MOVING || ball->getState() == Ball::State::HELD) { + float y = ball->getPosition().y; + if (y < minY) { + minY = y; + mainBall = ball; + } + } + } + return mainBall; +} +/** + * Collision detection helper - Ball vs Paddle + */ +bool Game::checkBallPaddleCollision(const Ball* ball, const Paddle* paddle) { + Vec2 ballPos = ball->getPosition(); + float ballRadius = ball->getRadius(); + Rect paddleRect = paddle->getBoundingBox(); + float closestX = std::max(paddleRect.x, std::min(ballPos.x, paddleRect.x + paddleRect.width)); + float closestY = std::max(paddleRect.y, std::min(ballPos.y, paddleRect.y + paddleRect.height)); + float distanceX = ballPos.x - closestX; + float distanceY = ballPos.y - closestY; + return (distanceX * distanceX) + (distanceY * distanceY) < (ballRadius * ballRadius); +} + +/** + * Collision detection helper - Ball vs Brick + */ +bool Game::checkBallBrickCollision(const Ball* ball, const Brick* brick) { + Vec2 ballPos = ball->getPosition(); + float ballRadius = ball->getRadius(); + Rect brickRect = brick->getBoundingBox(); + float closestX = std::max(brickRect.x, std::min(ballPos.x, brickRect.x + brickRect.width)); + float closestY = std::max(brickRect.y, std::min(ballPos.y, brickRect.y + brickRect.height)); + float distanceX = ballPos.x - closestX; + float distanceY = ballPos.y - closestY; + return (distanceX * distanceX) + (distanceY * distanceY) < (ballRadius * ballRadius); +} + +bool Game::checkPowerUpPaddleCollision(const PowerUp* pu, const Paddle* paddle) { + Vec2 pos = pu->getPosition(); + Rect paddleRect = paddle->getBoundingBox(); + return (pos.x >= paddleRect.x && pos.x <= paddleRect.x + paddleRect.width && + pos.y >= paddleRect.y && pos.y <= paddleRect.y + paddleRect.height); +} +/** + * Handle collision between a ball and all bricks + */ +void Game::handleBallBrickCollision(Ball* ball) { + Vec2 ballPos = ball->getPosition(); + + for (Brick* brick : m_bricks) { + if (!brick->isActive()) continue; + if (!checkBallBrickCollision(ball, brick)) continue; + + Rect brickRect = brick->getBoundingBox(); + Vec2 brickCenter = {brickRect.x + brickRect.width / 2.0f, + brickRect.y + brickRect.height / 2.0f}; + Vec2 offset = {ballPos.x - brickCenter.x, + ballPos.y - brickCenter.y}; + + float overlapX = ball->getRadius() + (brickRect.width / 2.0f) - fabsf(offset.x); + float overlapY = ball->getRadius() + (brickRect.height / 2.0f) - fabsf(offset.y); + + if (brick->getHP() == -1) { + // Indestructible brick + if (overlapX < overlapY) { + ball->bounceX(); + ballPos.x = offset.x > 0 ? brickRect.x + brickRect.width + ball->getRadius() + : brickRect.x - ball->getRadius(); + } else { + ball->bounceY(); + ballPos.y = offset.y > 0 ? brickRect.y + brickRect.height + ball->getRadius() + : brickRect.y - ball->getRadius(); + } + ball->setPosition(ballPos); + ball->boostSpeed(4.0f); + break; + } + int hpBefore = brick->getHP(); + // Normal brick: damage and bounce + m_resourceManager->playAudio(hpBefore); + brick->onHit(); + int hpReduced = hpBefore - brick->getHP(); + m_totalHpReduced += hpReduced; // accumulate total HP reduced + + if (overlapX < overlapY) { + ball->bounceX(); + ballPos.x = offset.x > 0 ? brickRect.x + brickRect.width + ball->getRadius() + : brickRect.x - ball->getRadius(); + } else { + ball->bounceY(); + ballPos.y = offset.y > 0 ? brickRect.y + brickRect.height + ball->getRadius() + : brickRect.y - ball->getRadius(); + } + ball->setPosition(ballPos); + ball->boostSpeed(4.0f); + + // Only drop a power-up every 5 brick hits + if (!brick->isActive()) { + if (m_totalHpReduced >= 5) { + m_totalHpReduced = 0; + + // >>> Limit: max 3 power-ups on screen + if (m_powerUps.size() < 3) { + // Randomly choose a power-up type + int randVal = rand() % 3; + PowerUp::Type type; + int activeBricks = 0; + for (Brick* b : m_bricks) { + if (b->isActive() && b->getHP() != -1) { + activeBricks++; + if (activeBricks > 15) { + break; + } + } + } + // When the number of bricks is less than 15, only TROPHY will drop. + if (activeBricks < 15) { + type = PowerUp::Type::TROPHY; + } else { + if (randVal == 0) type = PowerUp::Type::SPLIT_BALL; + else if (randVal == 1){ + if(m_paddle->getWidth()/80 >= 5){ + type = PowerUp::Type::SPLIT_BALL; + } + else{ + type = PowerUp::Type::EXTRA_PADDLE; + } + } + else{ + if(m_paddle->getWidth()/80 >= 3){ + type = PowerUp::Type::UP_BALLS; + } + else{ + type = PowerUp::Type::EXTRA_PADDLE; + } + } + } + // Drop position: center-top of the destroyed brick + Vec2 dropPos = { brickRect.x + brickRect.width / 2.0f, brickRect.y }; + PowerUp* pu = new PowerUp(m_game_area, type, dropPos); + m_powerUps.push_back(pu); + + //printf("[Game] Power-up dropped after 3 HP reduced, current count = %zu\n", m_powerUps.size()); + } else { + //printf("[Game] Power-up limit reached (3), no new drop.\n"); + } + } + } + break; + } +} + +/** + * Handle collision between a ball and the paddle + */ +void Game::handleBallPaddleCollision(Ball* ball) { + if (!ball || !m_paddle) return; + + Vec2 ballPos = ball->getPosition(); + + if (checkBallPaddleCollision(ball, m_paddle)) { + Rect paddleRect = m_paddle->getBoundingBox(); + float paddleCenter = paddleRect.x + paddleRect.width / 2.0f; + + // Compute hit factor (-1 left, +1 right) + float hitFactor = (ballPos.x - paddleCenter) / (paddleRect.width / 2.0f); + const float maxAngleFactor = 350.0f; + + Vec2 newVel = ball->getVelocity(); + newVel.x = hitFactor * maxAngleFactor; + + // Always bounce upward + if (newVel.y > 0) newVel.y = -newVel.y; + + ball->setVelocity(newVel); + ball->boostSpeed(150.0f); + + // Correct position to stay above paddle + Vec2 correctedPos = ballPos; + correctedPos.y = paddleRect.y - ball->getRadius() - 1.0f; + ball->setPosition(correctedPos); + } +} + +Ball* Game::getFreeBall(float radius) { + //printf("m_balls.size():%d",m_balls.size()); + //if (m_balls.size() > 10) { + // return nullptr; + //} + // create a new one and add to m_balls + Ball* newBall = new Ball(m_game_area, radius, Ball::State::HELD); + m_balls.push_back(newBall); + return newBall; +} + +/** + * @brief Activate a power-up effect in the game. + * @param type Type of the power-up to activate + */ +void Game::activatePowerUp(PowerUp::Type type) { + switch (type) { + case PowerUp::Type::SPLIT_BALL: { + Ball* original = getMainBall(); + if (original) { + Vec2 pos = original->getPosition(); + float r = original->getRadius(); + // Get two free balls from the m_balls + Ball* left = getFreeBall(r); + if(left!=nullptr){ + left->setPosition(pos); + left->setVelocity({-200.0f, -700.0f}); + left->setState(Ball::State::MOVING); + } + Ball* right = getFreeBall(r); + if(right!=nullptr){ + right->setPosition(pos); + right->setVelocity({200.0f, -700.0f}); + right->setState(Ball::State::MOVING); + } + // Original ball remains in play + } + break; + } + case PowerUp::Type::EXTRA_PADDLE: { + // Double the paddle width + if (m_paddle) { + if(m_paddle->getWidth()/80 <= 4) + { + float newWidth = m_paddle->getWidth() + 80; + m_paddle->setWidth(newWidth); // Adjust LVGL object width + } + } + break; + } + case PowerUp::Type::UP_BALLS: { + // Determine number of new balls based on paddle width + int numBalls = m_paddle->getWidth() / 80; // example: 80 width per ball + if (numBalls < 1) numBalls = 1; + + float paddleX = m_paddle->getX(); + float paddleY = m_paddle->getY(); + float paddleWidth = m_paddle->getWidth(); + float ballRadius = 16.0f; + + // Horizontal spacing for evenly distributed balls + float spacing = paddleWidth / (numBalls + 1); + + for (int i = 0; i < numBalls; ++i) { + Ball* newBall = getFreeBall(ballRadius); + if(newBall!=nullptr){ + float x = paddleX + spacing * (i + 1); // evenly spaced across paddle + float y = paddleY - ballRadius; // just above paddle + newBall->setPosition({x, y}); + float vx = (rand() % 2 == 0 ? -1.0f : 1.0f) * (100.0f); + float vy = -900.0f; + newBall->setVelocity({vx, vy}); + newBall->setState(Ball::State::MOVING); + } + } + break; + } + case PowerUp::Type::TROPHY: { + // >>> Force clear all bricks + for (Brick* brick : m_bricks) { + if (brick->isActive() && brick->getHP() != -1) { + while (brick->isActive()) { + brick->onHit(); + } + } + } + break; + } + + } +} + +/** + * Touch event callback + * Controls paddle movement and ball launching + */ +void Game::touch_area_event_cb(lv_event_t* e) { + Game* game = static_cast<Game*>(lv_event_get_user_data(e)); + if (game->m_state != GameState::PLAYING) return; + + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_PRESSED || code == LV_EVENT_PRESSING) { + // Drag: move paddle + lv_point_t screen_point; + lv_indev_get_point(lv_event_get_indev(e), &screen_point); + lv_coord_t game_area_x = lv_obj_get_x(game->m_game_area); + lv_coord_t local_x = screen_point.x - game_area_x; + game->m_paddle->moveTo(local_x); + } else if (code == LV_EVENT_RELEASED || code == LV_EVENT_PRESS_LOST) { + // Release: stop paddle and launch any held balls + game->m_paddle->stopMovement(); + for (Ball* ball : game->m_balls) { + if (ball->getState() == Ball::State::HELD) { + ball->launch(); + } + } + } +} + +/** + * Restart button callback + */ +void Game::restart_button_event_cb(lv_event_t* e) { + Game* game = static_cast<Game*>(lv_event_get_user_data(e)); + if (!game) return; + + delete game; + ballgame_start(); +} +/** + * Next level button callback + */ +void Game::next_level_button_event_cb(lv_event_t* e) { + Game* game = static_cast<Game*>(lv_event_get_user_data(e)); + if (!game) return; + + if (game->m_resourceManager) { + int level = game->m_resourceManager->getCurrentLevel(); + level++; + if (level > 6) level = 1; + game->m_resourceManager->setCurrentLevel(level); + } + + delete game; + ballgame_start(); +} + +/** + * Trigger next level screen + */ +void Game::trigger_next_level() { + m_state = GameState::PAUSED; + lv_timer_pause(m_game_timer); + + lv_obj_t* label = lv_label_create(m_parent_screen); + lv_label_set_text_fmt(label, "LEVEL %d CLEARED!", m_resourceManager->getCurrentLevel()); + lv_obj_set_style_text_color(label, lv_color_black(), 0); + lv_obj_center(label); + + lv_obj_t* next_btn = lv_button_create(m_parent_screen); + lv_obj_align_to(next_btn, label, LV_ALIGN_OUT_BOTTOM_MID, -35, 20); + lv_obj_t* btn_label = lv_label_create(next_btn); + lv_label_set_text(btn_label, "Next Level"); + lv_obj_center(btn_label); + + lv_obj_add_event_cb(next_btn, next_level_button_event_cb, LV_EVENT_CLICKED, this); +} + +/** + * Trigger game over screen + */ +void Game::trigger_game_over() { + m_state = GameState::GAME_OVER; + lv_obj_t* game_over_label = lv_label_create(m_parent_screen); + lv_label_set_text(game_over_label, "GAME OVER!"); + lv_obj_set_style_text_color(game_over_label, lv_color_black(), 0); + lv_obj_center(game_over_label); + + lv_obj_t* restart_btn = lv_button_create(m_parent_screen); + lv_obj_align_to(restart_btn, game_over_label, LV_ALIGN_OUT_BOTTOM_MID, -23, 20); + lv_obj_t* btn_label = lv_label_create(restart_btn); + lv_label_set_text(btn_label, "Restart"); + lv_obj_center(btn_label); + + lv_obj_add_event_cb(restart_btn, restart_button_event_cb, LV_EVENT_CLICKED, this); + + // "Skip level" button + lv_obj_t* skip_btn = lv_button_create(m_parent_screen); + lv_obj_align_to(skip_btn, game_over_label, LV_ALIGN_OUT_BOTTOM_MID, -35, 60); + lv_obj_t* skip_btn_label = lv_label_create(skip_btn); + lv_label_set_text(skip_btn_label, "SKIP LEVEL"); + lv_obj_center(skip_btn_label); + lv_obj_add_event_cb(skip_btn, next_level_button_event_cb, LV_EVENT_CLICKED, this); +} + +// ################################################# +// ## Global startup function +// ################################################# + +/** + * Global game start/restart function + * Manages creation and destruction of the Game instance. + */ +void ballgame_start() { + lv_obj_t* screen = lv_screen_active(); + lv_obj_clean(screen); + lv_obj_set_style_bg_color(screen, lv_color_black(), 0); + new Game(screen); +} \ No newline at end of file diff --git a/breakout/src/breakout.h b/breakout/src/breakout.h new file mode 100644 index 0000000000000000000000000000000000000000..fadb79eaf104a1622269fbe61f50a56549a07923 --- /dev/null +++ b/breakout/src/breakout.h @@ -0,0 +1,107 @@ +#ifndef BREAKOUT_H +#define BREAKOUT_H + +#pragma once +#include "breakout_types.h" +#include <vector> // C++ vector container to store dynamic lists (e.g., bricks) +#include <string> // C++ string class to handle file paths and names +#include "Paddle/Paddle.h" +#include "Ball/Ball.h" +#include "Brick/Brick.h" +#include "PowerUp/PowerUp.h" +#include "GameResourceManager/GameResourceManager.h" +// --- Game State Enumeration --- +/** + * @brief Core game states + */ +enum class GameState { + PLAYING, ///< Game is running + PAUSED, + GAME_OVER, ///< Game has ended +}; + +// --- Main Game Class --- +/** + * @class Game + * @brief Encapsulates all game states, objects, and core logic. + * + * Creates and initializes a game session in the constructor, + * and automatically cleans up all resources in the destructor. + */ +class Game { +public: + /** + * @brief Construct a new Game instance. + * @param parent Pointer to the parent LVGL object (screen/container). + */ + Game(lv_obj_t* parent); + + /** + * @brief Destroy the Game instance and release all resources. + */ + ~Game(); + + // --- Public Members --- + /** + * @brief Pointer to the UI container for the game area. + * Exposed for access by GameResourceManager during map loading. + */ + lv_obj_t* m_game_area; + + /** + * @brief Dynamic array holding all brick objects. + * Exposed for access by GameResourceManager during map loading. + */ + std::vector<Brick*> m_bricks; + +private: + // --- Core State and UI --- + lv_obj_t* m_parent_screen; ///< Parent screen where the game resides + GameState m_state; ///< Current game state + lv_timer_t* m_game_timer; ///< Main game loop timer + + // --- Game Boundaries --- + Rect m_gameBounds; ///< Logical bounds of the game area + + // --- Game Objects --- + Paddle* m_paddle; ///< Paddle object + GameResourceManager* m_resourceManager; ///< Resource manager + int m_currentLevel; + std::vector<PowerUp*> m_powerUps; + int m_totalHpReduced = 0; + std::vector<Ball*> m_balls; // Active balls + lv_obj_t* m_canvas; + + +private: + // --- Internal Methods --- + void init(); ///< Initialize game objects and state + void trigger_game_over(); ///< Handle game over logic + void trigger_next_level(); + + bool checkBallBrickCollision(const Ball* ball, const Brick* brick); ///< Detect collision between ball and brick + bool checkBallPaddleCollision(const Ball* ball, const Paddle* paddle); ///< Detect collision between ball and paddle + bool checkPowerUpPaddleCollision(const PowerUp* pu, const Paddle* paddle); + void handleBallBrickCollision(Ball* ball); ///< Handle ball-brick collision events + void handleBallPaddleCollision(Ball* ball); ///< Handle ball-paddle collision events + Ball* getMainBall(); + Ball* getFreeBall(float radius); + void activatePowerUp(PowerUp::Type type); + + + // --- Static Callbacks --- + static void game_timer_cb(lv_timer_t* timer); ///< Main game loop callback + static void touch_area_event_cb(lv_event_t* e); ///< Touch input callback + static void restart_button_event_cb(lv_event_t* e); ///< Restart button callback + static void next_level_button_event_cb(lv_event_t* e); +}; + +// --- Global Function --- +/** + * @brief Start or restart the ball game. + * + * This is the only external entry point to start/restart the game. + */ +void ballgame_start(); + +#endif // BREAKOUT_H \ No newline at end of file diff --git a/breakout/src/breakout_types.h b/breakout/src/breakout_types.h new file mode 100644 index 0000000000000000000000000000000000000000..05edca789cb7c5018fca658cc0e3d1ef458f063c --- /dev/null +++ b/breakout/src/breakout_types.h @@ -0,0 +1,14 @@ +#pragma once + +#include "lvgl.h" + +// 2D vector struct, represents position and velocity +struct Vec2 { float x = 0.0f; float y = 0.0f; }; + +// Rectangle struct, represents position, size, and bounds +struct Rect { float x = 0.0f; float y = 0.0f; float width = 0.0f; float height = 0.0f; }; + +// Define global constants for game screen size and timer period +static const int GAME_AREA_WIDTH = 1200; +static const int GAME_AREA_HEIGHT = 760; +static const int GAME_TICK_PERIOD = 20; // Game logic update period (milliseconds) \ No newline at end of file diff --git a/calculator/Kconfig b/calculator/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..41e5a1b8e9ddbde48bb5ed4ff45f1ef9bf7bfaa1 --- /dev/null +++ b/calculator/Kconfig @@ -0,0 +1,14 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_CALCULATOR + bool "CALCULATOR" + default n + +if LVX_USE_DEMO_CALCULATOR + config LVX_CALCULATOR_DATA_ROOT + string "Calculator Data Root" + default "/data" +endif diff --git a/calculator/Make.defs b/calculator/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..9397a98284b77451c0b96dc87425ab62d08df467 --- /dev/null +++ b/calculator/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_CALCULATOR),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/calculator +endif diff --git a/calculator/Makefile b/calculator/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7f08a2a89476f82b352a93175a45f0b7677b5c4f --- /dev/null +++ b/calculator/Makefile @@ -0,0 +1,29 @@ +# +# Copyright (C) 2022 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_CALCULATOR), y) +PROGNAME = calculator +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_CALCULATOR) +CXXEXT := .cpp +CXXSRCS = calculator_cre.cpp expression_calc.cpp +MAINSRC = calculator_main.cpp +endif + +include $(APPDIR)/Application.mk diff --git a/calculator/Readme.md b/calculator/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..c854388c5c6eec5e9280fdc92554422147cba3ef --- /dev/null +++ b/calculator/Readme.md @@ -0,0 +1,210 @@ +# 高级计算器 - 基于 open-vela + +## 📚 目录 + +- [一、基本介绍](#一基本介绍) + - [1.1 基本四则运算](#1-基本四则运算) + - [1.2 高级计算支持](#2-高级计算支持) + - [1.3 结果后输入智能处理](#3-结果后输入智能处理) + +- [二、实现思路](#二实现思路) + - [2.1 Token 级别与运算符优先级](#1-token-级别与运算符优先级) + - [2.2 表达式解析](#2-表达式解析) + - [2.3 逆波兰表示法计算](#3-逆波兰表示法计算) + - [2.4 基于 LVGL 使用 create_button() 动态创建按键](#4-基于-lvgl-使用-create_button-动态创建按键) + - [2.5 输入保护机制](#5-输入保护机制) + +- [三、使用说明](#三使用说明) + - [3.1 配置模拟器(menuconfig)](#1配置模拟器menuconfig) + - [3.2 makefile 编译问题](#2makefile编译问题) + - [3.3 资源推送更新 /res](#3资源推送更新-res) + +- [📁 原工程路径](#原工程路径) +- [🛠️ 常用指令](#常用指令) + +--- +## 一、基本介绍 + +- 基于 open-vela,制作了一个 **高级计算器**, +- 计算器函数部分引用自仓库https://github.com/W-Mai/ExpressionCalc +- 其中 calculate是计算结果,Clear是清屏,Del是退位。 +- sqrt以及cos等函数需要加括号使用,常量PI和E可以直接使用。 +例如 PI / 2 、 E + 4 、sqrt(4) 、cos(-2) + +![计算器界面](./screen_history/screenshot_commit7.png) + +该计算器实现了以下功能: + +### 1. 基本四则运算 + +- 支持加、减、乘、除运算 +- 运算支持 double 精度,仅显示有效数字,不显示多余的 `0` +- 例如:显示 `1.5`,而不是 `1.50000000` + +### 2. 高级计算支持 +使用方法。例如 cos(2) + +- sqrt 平方根(√) +- log 自然对数(ln) +- sin 正弦函数 +- cos 余弦函数 +- PI 圆周率 π 3.1415926... +- E 自然常数 e 2.7182818... +- . 小数点 +- ( 左括号 +- ) 右括号 + +### 3. 结果后输入智能处理 + +- 运算结果显示后,再次输入新数字会自动清屏 +- 如果输入的是运算符,则保留结果并继续运算 +--- + +## 二、实现思路 + +### 1. Token 级别与运算符优先级 + +- 通过 TokenLevel 来定义每个操作符的优先级。例如,+ 和 - 的优先级是 1,而 *, /, % 等是 2。 + +- 这样就能在处理逆波兰表示法时判断操作符的优先级,确保正确的运算顺序。 + + +### 2. 表达式解析 +- reversePolishNotation 方法负责将输入的中缀表达式(例如 a + b * c)转换为逆波兰表示法(如 a b c * +)。这个过程使用了栈来处理操作符和括号。 + +- 当遇到数字时,直接将其添加到结果队列。 + +- 当遇到操作符时,根据其优先级判断是否需要弹出栈中的操作符。 + +- 遇到左括号 ( 时,压入栈中,右括号 ) 时,弹出栈中的操作符直到遇到左括号。 + + +### 3. 逆波兰表示法计算 + +- evalNotation 方法通过栈来计算逆波兰表示法的结果。 + +- 如果遇到数字,将其压入栈中。 + +- 如果遇到运算符,从栈中弹出参数并进行计算,然后将结果压回栈中。 + +- 支持的运算符可以是自定义的,也可以是内置的,如 +, -, *, sin, log 等。 + + +### 4. 基于 LVGL 使用 `create_button()` 动态创建按键 + +- 通过 `create_button()` 函数动态创建按键 + +- 使用二维 `btn_map` 配置按钮排布,便于维护和扩展 + +- 使用 LVGL 的组件函数设置按钮及输入框,设定合理设置尺寸和位置,颜色 + +### 5. 输入保护机制 + +- 输入非法或不符合规则(如多个 `.`、负数开根号、除以零等)时,运算显示 `ERROR` + +- 删除、清除、错误重置等操作处理完善,确保系统稳定运行 + +--- + + +## 三、使用说明 +首先进入模拟器配置 +### 1.配置模拟器(menuconfig) +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig +``` +#### (1)编译设置 +- 配置LVX_USE_DEMO_CALCULATOR 为 yes +- LVX_CALCULATOR_DATA_ROOT的路径设置为/data (Kconfig文件默认预设为 /data) + +#### (2)使用C++头文件需要配置 +进行以下操作设置,以支持C++编写include头文件,例如iostream.h,cmath.h +- 设置 C++ library为 Toolchain C++ support +- 设置 C++ low level library select 为 GNU low level libsupc++ +- 设置 (gnu++20) Language standard + +如果使用异常处理机制try-catch,需要开启以下设置(嵌入式中不推荐,当前版本已不使用该机制) +- enable exception support + + +### 2.makefile编译问题 +#### (1)编译找不到Main函数 + +``` +arm-none-eabi-ld: /home/foam/vela-opensource/nuttx/staging/libapps.a(builtin_list.c.home.foam.vela-opensource.apps.builtin_1.o):(.rodata.g_builtins+0x7c): undefined reference to calculator_main' +``` +- 因为makefile文件中的PROGNAME = calculator +- 在编译时会试图链接一个函数名叫:int calculator_main(int argc, char *argv[]) +- 并且还需要加上extern "C" ,所以得到主函数为extern "C" int calculator_main 才能成功编译。 + +#### (2)makefile编写 +- 因为使用了cpp文件,所以需要增加CXXEXT以指出.cpp格式文件 +``` +CXXEXT := .cpp +``` +- 并且C++文件需要使用CXXSRCS标出,如 +``` +CXXSRCS = calculator_cre.cpp expression_calc.cpp +``` + +### 3.资源推送更新 /res +需要在模拟器运行状况下,使用ADB指令更新资源推送,才能显示更换的新图片和字体。 +- 启动模拟器 +```bash +./emulator.sh vela +``` +- ADB推送更新资源(在模拟器运行状况下,终端使用) +```bash +adb push apps/packages/demos/calculator/res /data/ +``` +- 之后启动计算器应用即可 +```bash +calculator & +``` + + +## 📁原工程路径 +vela-opensource/apps/packages/demos/calculator/ + +--- + +## 🛠️常用指令 + +### 开始构建 + +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j$(nproc) +``` +### 配置模拟器(menuconfig) +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig +``` + +### ADB推送更新资源(在模拟器运行状况下) +```bash +adb push apps/packages/demos/calculator/res /data/ +``` + +### 清理构建产物 +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j$(nproc) +``` +### 启动模拟器 +```bash +./emulator.sh vela +``` + +### 启动计算器应用 +```bash +calculator & +``` +--- + + + + + + + + + diff --git a/calculator/calculator_cre.cpp b/calculator/calculator_cre.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ada4b4aadb608ed3133b95faf93d4176229feb44 --- /dev/null +++ b/calculator/calculator_cre.cpp @@ -0,0 +1,370 @@ +/* UI +*│ +*├── CalculatorState +*│ ├── Label: Text display for input and result +*│ ├── clear_on_next_input: bool flag to clear on next input +*│ ├── clear_error: bool flag to indicate error state +*│ +*├── Resource +*│ ├── Fonts: Loaded fonts of different sizes for various UI elements +*│ ├── Images: Paths to icon images like "background" +*│ ├── get_res_path(): Returns the resource directory path +*│ ├── get_fonts_path(): Returns the fonts directory path +*│ ├── get_icons_path(): Returns the icons directory path +*│ ├── load_resources(): Initializes fonts and images; returns false if any resource fails to load +*│ +*├── Functions +*│ ├── cleanup_resources(): ensuring no memory leaks occur during UI rendering cleanup. +*│ ├── app_create_main_page(): Creates the main UI page with background image +*│ ├── btn_input_cb(): Button click handler for input; appends the button text to the display +*│ ├── btn_clear_cb(): Button click handler for clearing the display +*│ ├── btn_del_cb(): Button click handler for deleting the last character +*│ ├── calc_btn_cb(): Button click handler for performing calculations +*│ ├── create_button(): Helper function to create buttons dynamically based on a map of button labels +*│ ├── calculator_create(): Main function to create the entire calculator UI, including buttons, display, and events +*│ +*├── Button Layout +*│ ├── Input Buttons: A grid of buttons representing calculator digits and functions like "sqrt", "log", "sin", "cos", etc. +*│ ├── Control Buttons: Additional buttons like "Clear", "Delete", and "Calculate" +*│ +*├── Button Event Handlers +*│ ├── btn_input_cb: Handles number and operator input, updating the display text +*│ ├── btn_clear_cb: Clears the display when the "Clear" button is pressed +*│ ├── btn_del_cb: Deletes the last character from the display when the "Delete" button is pressed +*│ ├── calc_btn_cb: Handles calculation logic when the "Calculate" button is pressed, evaluates the expression and displays the result +*│ +*└── UI Style and Appearance +* ├── Button Styles: Rounded corners, colors for different button states (default, pressed) +* ├── Label Styles: Font, border, background color, and opacity settings for input/output display +* ├── Background Image: A background image set in the main page +*/ + +#include "calculator_cre.h" + + +#include "lvgl.h" + + +void cleanup_resources(lv_draw_buf_t *draw_buf) { + if (draw_buf != NULL) { + lv_draw_buf_destroy(draw_buf); + } + LV_LOG_INFO("Resources cleaned up."); +} + +lv_draw_buf_t* app_create_main_page(lv_obj_t *parent, Resource* R) { + // Step 1: Create image decoder descriptor + lv_image_decoder_dsc_t decoder_dsc; + lv_image_decoder_args_t args = { 0 }; // Custom args if needed + lv_result_t res = lv_image_decoder_open(&decoder_dsc, R->images.background.c_str(), &args); + + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Image decode failed: %s", R->images.background.c_str()); + return NULL; + } + + // Step 2: Get decoded data (decoder_dsc.decoded) + const lv_draw_buf_t* const_buf = decoder_dsc.decoded; + + // Create a writable copy of the draw buffer + lv_draw_buf_t* draw_buf = lv_draw_buf_dup(const_buf); + + if(draw_buf == NULL) { + LV_LOG_ERROR("Failed to duplicate draw buffer."); + lv_image_decoder_close(&decoder_dsc); + return NULL; + } + + // Step 3: Use the decoded image (e.g., draw it to a canvas) + lv_obj_t* canvas = lv_canvas_create(parent); + lv_canvas_set_draw_buf(canvas, draw_buf); // Set the decoded buffer + + lv_obj_clear_flag(canvas, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_flag(canvas, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + lv_obj_set_style_opa(canvas, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_move_background(canvas); + lv_obj_align(canvas, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_size(canvas, 1280, 800); + + // Step 4: Clean up after we're done with the buffer + lv_image_decoder_close(&decoder_dsc); + return draw_buf; +} + + + +// Button input callback function +static void btn_input_cb(lv_event_t *e) { + auto btn = static_cast<lv_obj_t*>(lv_event_get_target(e)); + + // Retrieve the button text from the user data + auto txt = static_cast<const char*>(lv_obj_get_user_data(btn)); + auto state = static_cast<CalculatorState*>(lv_event_get_user_data(e)); // Get the calculator state + + auto old = lv_label_get_text(state->label); + std::string buf; + + // Check if the input is one of the special functions or constants (e.g., sin, cos, log, sqrt, PI, E) + bool is_function_or_constant = + strcmp(txt, "sin") == 0 || strcmp(txt, "cos") == 0 || strcmp(txt, "log") == 0 || + strcmp(txt, "sqrt") == 0 || strcmp(txt, "PI") == 0 || strcmp(txt, "E") == 0 || + strcmp(txt, "(") == 0 || strcmp(txt, ")") == 0; + + bool is_digit_or_func = std::isdigit(txt[0]) || is_function_or_constant; + bool should_clear = (state->clear_on_next_input && is_digit_or_func) || state->clear_error; + + if (should_clear) { + buf = txt; // Start with the current button text + state->clear_on_next_input = false; + state->clear_error = false; + } else { + buf = std::string(old) + txt; // Concatenate the old text with new input + state->clear_on_next_input = false; + } + + lv_label_set_text(state->label, buf.c_str()); // Update the label with the new text +} + + +// Callback function for the clear button +static void btn_clear_cb(lv_event_t *e) { + auto state = static_cast<CalculatorState*>(lv_event_get_user_data(e)); + lv_label_set_text(state->label, ""); // Clear the label text + state->clear_on_next_input = false; + state->clear_error = false; +} + +// Callback function for the delete button +static void btn_del_cb(lv_event_t *e) { + auto state = static_cast<CalculatorState*>(lv_event_get_user_data(e)); + auto txt = lv_label_get_text(state->label); + std::string str(txt); // Convert to std::string for easier manipulation + size_t len = str.length(); + + // If input should be cleared or there's an error, reset the label + if (state->clear_on_next_input || state->clear_error) { + lv_label_set_text(state->label, ""); + state->clear_on_next_input = false; + state->clear_error = false; + return; + } + + // Define keywords to delete as a whole + const std::vector<std::string> keywords = { "sqrt", "sin", "cos", "log", "PI" }; + + // Check if the current text ends with any of the keywords + for (const auto& kw : keywords) { + if (len >= kw.length() && str.compare(len - kw.length(), kw.length(), kw) == 0) { + str.erase(len - kw.length()); // Erase the entire keyword + lv_label_set_text(state->label, str.c_str()); + return; + } + } + + // Otherwise, delete the last character + if (len > 0) { + str.pop_back(); + lv_label_set_text(state->label, str.c_str()); + } +} + +// Callback function for the calculate button +static void calc_btn_cb(lv_event_t *e) { + auto state = static_cast<CalculatorState*>(lv_event_get_user_data(e)); // Get the user data passed into the event callback + auto expr = lv_label_get_text(state->label); + char result_buf[256]; + + // Process the expression to handle negative numbers correctly + std::string modified_expr = expr; + + // If the first character is '-', prepend '0' for negative number + if (modified_expr[0] == '-') { + modified_expr = "0" + modified_expr; // Change '-2' to '0-2' + } + + // For other negative numbers in the expression, check if '(-' is found + size_t pos = 0; + while ((pos = modified_expr.find("(-", pos)) != std::string::npos) { + modified_expr.replace(pos, 2, "(0-"); // Change '(-' to '(0-' + pos += 3; // Skip over the replaced text "(0-" to avoid infinite loop + } + + // Detect "PI" and append "()" if not followed by '(' + pos = 0; + while ((pos = modified_expr.find("PI", pos)) != std::string::npos) { + if (pos + 2 >= modified_expr.size() || modified_expr[pos + 2] != '(') { + modified_expr.insert(pos + 2, "()"); + pos += 4; // Move past "PI()" + } else { + pos += 3; // Skip over "PI(" + } + } + + // Detect "E" and append "()" if not followed by '(' + pos = 0; + while ((pos = modified_expr.find("E", pos)) != std::string::npos) { + if (pos + 1 >= modified_expr.size() || modified_expr[pos + 1] != '(') { + modified_expr.insert(pos + 1, "()"); + pos += 3; // Move past the inserted "E()" + } else { + pos += 2; // Already has '(', skip over "E(" + } + } + + + XCLZ::eXpressionCalc calc; + calc.setExpression(modified_expr); // Use the modified expression + + const auto rpn = calc.reversePolishNotation(); + if (calc.getError().type != XCLZ::ErrorType::Well) { + std::snprintf(result_buf, sizeof(result_buf), "Error: %s: %s", calc.errorToString().c_str(), calc.getError().msg.c_str()); + state->clear_on_next_input = true; + state->clear_error = true; + } else { + const auto val = calc.evalNotation(rpn); + if (calc.getError().type != XCLZ::ErrorType::Well) { + std::snprintf(result_buf, sizeof(result_buf), "Error: %s: %s", calc.errorToString().c_str(), calc.getError().msg.c_str()); + state->clear_on_next_input = true; + state->clear_error = true; + } else { + std::snprintf(result_buf, sizeof(result_buf), "%.8g", val); // Format the result + state->clear_on_next_input = true; + } + } + + lv_label_set_text(state->label, result_buf); // Update label with the result or error message +} + + +// Helper function to create a button +static void create_button(lv_obj_t *parent, const char *txt, int col, int row, CalculatorState* state, Resource* R) { + auto btn = lv_btn_create(parent); + lv_obj_set_size(btn, 100, 80); // Set button size + lv_obj_align(btn, LV_ALIGN_CENTER, col * 110 - 220, row * 90 - 80); // Position the button on the screen + + // Set style properties for the button + lv_obj_set_style_radius(btn, 30, LV_STATE_DEFAULT); // Rounded corners + lv_obj_set_style_border_width(btn, 2, LV_STATE_DEFAULT); // Border width + lv_obj_set_style_border_color(btn, lv_color_hex(0x000000), LV_STATE_DEFAULT); // Border color (black) + + // Set colors based on the row and column + if (col == 0) { // First column + lv_obj_set_style_bg_color(btn, lv_color_hex(0x2196F3), LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(btn, lv_color_hex(0x5E3370), LV_STATE_PRESSED); + } else if (row == 0 && col != 0) { // First row except for the first button + lv_obj_set_style_bg_color(btn, lv_color_hex(0xFFE4C4), LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(btn, lv_color_hex(0xEE82EE), LV_STATE_PRESSED); + } else { // Other buttons + lv_obj_set_style_bg_color(btn, lv_color_hex(0xFFFAFA), LV_STATE_DEFAULT); // Default color (light gray) + lv_obj_set_style_bg_color(btn, lv_color_hex(0xF5F5F5), LV_STATE_PRESSED); // Pressed color (light gray) + } + + // Create label for the button and set its text + auto btn_label = lv_label_create(btn); + lv_label_set_text(btn_label, txt); // Set the button label text + lv_obj_set_style_text_font(btn_label, R->fonts.size_22_bold, LV_STATE_DEFAULT); // Set the font + if (col == 0) { + lv_obj_set_style_text_color(btn_label, lv_color_hex(0xFFFFFF), LV_STATE_DEFAULT); // Set label color + } else if (row == 0 && col != 0) { // First row except for the first button + lv_obj_set_style_text_color(btn_label, lv_color_hex(0x4F4F4F), LV_STATE_DEFAULT); // Set label color + } else { // Other buttons + lv_obj_set_style_text_color(btn_label, lv_color_hex(0x000000), LV_STATE_DEFAULT); // Set label color + } + + lv_obj_center(btn_label); // Center the text inside the button + + // Store the button text in the user data for future reference + lv_obj_set_user_data(btn, (void*)txt); // Associate the button's text with the button object + + // Add event callback for the button click + lv_obj_add_event_cb(btn, btn_input_cb, LV_EVENT_CLICKED, state); +} + +// Function to create the entire calculator UI +lv_draw_buf_t* calculator_create(lv_obj_t *parent, CalculatorState* state, Resource* R) { + // Initialize resources (fonts and images) by calling load_resources + if (!R->load_resources()) { + // Handle error if resources failed to load + printf("Failed to load resources\n"); + }// Initialize resources (fonts and images) + auto draw_buf = app_create_main_page(parent, R); // Create the main page with the background + + // Input display box + auto screen = lv_scr_act(); // Get the current screen + lv_obj_set_style_bg_color(screen, lv_color_hex(0xF0F0F0), LV_STATE_DEFAULT); // Set gray background + state->label = lv_label_create(parent); + lv_obj_set_size(state->label, 540, 130); // Set label size + lv_obj_align(state->label, LV_ALIGN_TOP_MID, 0, 40); // Align label at the top center + lv_obj_set_style_text_font(state->label, R->fonts.size_48_normal, LV_STATE_DEFAULT); // Set label font + lv_obj_set_style_radius(state->label, 10, 0); // Set label border radius + lv_obj_set_style_border_width(state->label, 2, 0); // Set border width + lv_obj_set_style_border_color(state->label, lv_color_hex(0x000000), 0); // Set border color (black) + lv_obj_set_style_bg_color(state->label, lv_color_hex(0xE1FFFF), LV_STATE_DEFAULT); // Set background color (light cyan) + + // Ensure the background is fully opaque + lv_obj_set_style_bg_opa(state->label, LV_OPA_COVER, LV_STATE_DEFAULT); + lv_label_set_text(state->label, ""); // Clear label text initially + + // Input button matrix + const char *btn_map[5][5] = { + {"PI", "log", "sin", "cos", "sqrt"}, + {"E", "7", "8", "9", "+"}, + {"%", "4", "5", "6", "-"}, + {"^", "1", "2", "3", "*"}, + {".", "(", "0", ")", "/"} + }; + + // Create buttons from the button map + for (int row = 0; row < 5; ++row) { + for (int col = 0; col < 5; ++col) { + create_button(parent, btn_map[row][col], col, row, state, R); // Create each button + } + } + + // Calculate button + auto calc_btn = lv_btn_create(parent); + lv_obj_set_style_bg_color(calc_btn, lv_color_hex(0xFF8C00), LV_STATE_DEFAULT); // Purple background + lv_obj_set_style_radius(calc_btn, 35, LV_STATE_DEFAULT); // Rounded corners + lv_obj_set_style_border_width(calc_btn, 2, LV_STATE_DEFAULT); // Border width + lv_obj_set_style_border_color(calc_btn, lv_color_hex(0x000000), LV_STATE_DEFAULT); // Border color (black) + lv_obj_set_size(calc_btn, 130, 80); // Set button size + lv_obj_align(calc_btn, LV_ALIGN_CENTER, -200, -170); // Position the button on the screen + auto calc_lbl = lv_label_create(calc_btn); // Create button label + lv_label_set_text(calc_lbl, "calculate"); + lv_obj_set_style_text_font(calc_lbl, R->fonts.size_22_bold, LV_STATE_DEFAULT); + lv_obj_set_style_text_color(calc_lbl, lv_color_hex(0xFFFAFA), LV_STATE_DEFAULT); // Set label color + lv_obj_center(calc_lbl); // Center the label + lv_obj_add_event_cb(calc_btn, calc_btn_cb, LV_EVENT_CLICKED, state); // Add event callback + + // Clear button (Red) + auto clear_btn = lv_btn_create(parent); + lv_obj_set_style_bg_color(clear_btn, lv_color_hex(0xFF8C00), LV_STATE_DEFAULT); // Red color + lv_obj_set_size(clear_btn, 130, 80); + lv_obj_set_style_radius(clear_btn, 35, LV_STATE_DEFAULT); // Rounded corners + lv_obj_set_style_border_width(clear_btn, 2, LV_STATE_DEFAULT); // Border width + lv_obj_set_style_border_color(clear_btn, lv_color_hex(0x000000), LV_STATE_DEFAULT); // Border color (black) + lv_obj_align(clear_btn, LV_ALIGN_CENTER, 200, -170); // Position the button on the screen + auto clear_lbl = lv_label_create(clear_btn); + lv_label_set_text(clear_lbl, "Clear"); + lv_obj_set_style_text_font(clear_lbl, R->fonts.size_22_bold , LV_STATE_DEFAULT); + lv_obj_set_style_text_color(clear_lbl, lv_color_hex(0xFFFAFA), LV_STATE_DEFAULT); // Set label color + lv_obj_center(clear_lbl); + lv_obj_add_event_cb(clear_btn, btn_clear_cb, LV_EVENT_CLICKED, state); + + // Delete button (Green) + auto del_btn = lv_btn_create(parent); + lv_obj_set_style_bg_color(del_btn, lv_color_hex(0xFF8C00), LV_STATE_DEFAULT); // Green color + lv_obj_set_size(del_btn, 130, 80); + lv_obj_set_style_radius(del_btn, 35, LV_STATE_DEFAULT); // Rounded corners + lv_obj_set_style_border_width(del_btn, 2, LV_STATE_DEFAULT); // Border width + lv_obj_set_style_border_color(del_btn, lv_color_hex(0x000000), LV_STATE_DEFAULT); // Border color (black) + lv_obj_align(del_btn, LV_ALIGN_CENTER, 0, -170); // Position the button on the screen + auto del_lbl = lv_label_create(del_btn); + lv_label_set_text(del_lbl, "Del"); // ⌫ + lv_obj_set_style_text_font(del_lbl, R->fonts.size_22_bold , LV_STATE_DEFAULT); + lv_obj_set_style_text_color(del_lbl, lv_color_hex(0xFFFAFA), LV_STATE_DEFAULT); // Set label color + lv_obj_center(del_lbl); + lv_obj_add_event_cb(del_btn, btn_del_cb, LV_EVENT_CLICKED, state); + + return draw_buf; +} diff --git a/calculator/calculator_cre.h b/calculator/calculator_cre.h new file mode 100644 index 0000000000000000000000000000000000000000..ed2f2ebda803383fa0a123a0355e3b16a995bacf --- /dev/null +++ b/calculator/calculator_cre.h @@ -0,0 +1,98 @@ +#ifndef CALCULATOR_H +#define CALCULATOR_H + +#include "lvgl.h" +#include "expression_calc.h" +#include <cstring> +#define RES_ROOT CONFIG_LVX_CALCULATOR_DATA_ROOT + +class CalculatorState { +public: + lv_obj_t *label; + bool clear_on_next_input; + bool clear_error; + + CalculatorState() + : label(nullptr), clear_on_next_input(false), clear_error(false) {} +}; + +// C++ class for Resource +class Resource { +public: + // Fonts sub-structure + class Fonts { + public: + lv_font_t* size_16_normal; + lv_font_t* size_22_bold; + lv_font_t* size_24_normal; + lv_font_t* size_28_normal; + lv_font_t* size_48_normal; + lv_font_t* size_60_bold; + + Fonts() + : size_16_normal(nullptr), size_22_bold(nullptr), + size_24_normal(nullptr), size_28_normal(nullptr), + size_48_normal(nullptr), size_60_bold(nullptr) {} + }; + + // Images sub-structure + class Images { + public: + std::string background; + + Images() : background("") {} + }; + + // Member variables + Fonts fonts; + Images images; + + // Constructor to initialize resources + Resource() {} + + // Method to load the resources (fonts and images) + bool load_resources() { + std::string icons_path = get_icons_path(); + std::string fonts_path = get_fonts_path(); + + // Font initialization using std::string for paths + fonts.size_16_normal = lv_freetype_font_create((fonts_path + "/MiSans-Normal.ttf").c_str(), LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 16, LV_FREETYPE_FONT_STYLE_NORMAL); + fonts.size_22_bold = lv_freetype_font_create((fonts_path + "/MiSans-Semibold.ttf").c_str(), LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 22, LV_FREETYPE_FONT_STYLE_NORMAL); + fonts.size_24_normal = lv_freetype_font_create((fonts_path + "/MiSans-Normal.ttf").c_str(), LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, LV_FREETYPE_FONT_STYLE_NORMAL); + fonts.size_28_normal = lv_freetype_font_create((fonts_path + "/MiSans-Normal.ttf").c_str(), LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 28, LV_FREETYPE_FONT_STYLE_NORMAL); + fonts.size_48_normal = lv_freetype_font_create((fonts_path + "/MiSans-Normal.ttf").c_str(), LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 48, LV_FREETYPE_FONT_STYLE_NORMAL); + fonts.size_60_bold = lv_freetype_font_create((fonts_path + "/MiSans-Semibold.ttf").c_str(), LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 60, LV_FREETYPE_FONT_STYLE_NORMAL); + + // Image initialization + images.background = icons_path + "/background.png"; + printf("icons Path: %s\n", images.background.c_str()); + + // Check if fonts were loaded successfully + if (!fonts.size_16_normal || !fonts.size_22_bold || !fonts.size_24_normal || !fonts.size_28_normal || !fonts.size_48_normal || !fonts.size_60_bold ) { + return false; + } + + return true; + } + +private: + // Function to get the resource path + std::string get_res_path() { + return std::string(RES_ROOT) + "/res"; + } + + // Function to get the fonts path + std::string get_fonts_path() { + return get_res_path() + "/fonts"; + } + + // Function to get the icons path + std::string get_icons_path() { + return get_res_path() + "/icons"; + } +}; + +// Function to create the calculator UI +lv_draw_buf_t* calculator_create(lv_obj_t *parent, CalculatorState* state, Resource* R); +void cleanup_resources(lv_draw_buf_t *draw_buf); +#endif // CALCULATOR_H diff --git a/calculator/calculator_main.cpp b/calculator/calculator_main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b9dc694960dbb4c8da2f8137ed57e7f4a21cdf9 --- /dev/null +++ b/calculator/calculator_main.cpp @@ -0,0 +1,73 @@ +// Include NuttX headers +#include <nuttx/config.h> +#include <unistd.h> +#include <uv.h> +#include "calculator_cre.h" // Include the header for calculator creation +// Include LVGL headers +#include <lvgl/lvgl.h> + +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +extern "C" int calculator_main(int argc, FAR char *argv[]) +{ + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + // Dynamically allocate memory for the CalculatorState object + CalculatorState* state = new CalculatorState(); + Resource* R = new Resource(); + + // Create the screen and calculator UI + lv_obj_t* scr = lv_screen_active(); + lv_draw_buf_t* draw_buf = calculator_create(scr, state, R); // Create the calculator UI + + lv_nuttx_uv_loop(&ui_loop, &result); + + lv_nuttx_deinit(&result); + lv_deinit(); + + // Clean up: delete allocated objects + if (draw_buf) { + cleanup_resources(draw_buf); + } else { + LV_LOG_WARN("no resources to clean."); + } + delete state; + delete R; + + return 0; +} diff --git a/calculator/expression_calc.cpp b/calculator/expression_calc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6cd1ddaf9309aad235b83eb788527eaaa5aa91bb --- /dev/null +++ b/calculator/expression_calc.cpp @@ -0,0 +1,279 @@ +/* + * expression_calc.cpp + * + * MIT License + * Copyright (c) 2022 XCLZ STUDIO@W-Mai + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "readability-convert-member-functions-to-static" + +#include "expression_calc.h" + +#include <utility> + +#define ERROR(type_, msg_, tag_) \ + Error.type = (type_); \ + Error.msg = (msg_); \ + goto tag_ + +namespace XCLZ { + +eXpressionCalc::eXpressionCalc() { + ErrorType2Name = { + {ErrorType::Well, "Well Done" }, + { ErrorType::BracketNotMatched, "Bracket Not Matched"}, + { ErrorType::FunctionNotFound, "Function Not Found" }, + { ErrorType::EvalError, "Evaluate Error" }, + { ErrorType::SyntaxError, "Syntax Error" } + }; + + TokenLevel = { + {'+', 1}, + { '-', 1}, + { '*', 2}, + { '/', 2}, + { '^', 2}, + { '%', 2}, + { '\\', 2}, + { '(', 0}, + { ')', 0} + }; + + NoteTable = { + {"+", { 2, LAMBDA_EXPR(params[0] + params[1]) } }, + { "-", { 2, LAMBDA_EXPR(params[0] - params[1]) } }, + { "*", { 2, LAMBDA_EXPR(params[0] * params[1]) } }, + { "/", { 2, LAMBDA_EXPR(params[0] / params[1]) } }, + { "^", { 2, LAMBDA_EXPR(pow(params[0], params[1])) } }, + { "%", { 2, LAMBDA_EXPR(fmod(params[0], params[1])) } }, + { "\\", { 2, LAMBDA_EXPR((int)((int)params[0] / (int)params[1])) } }, + { "addFunc", { 2, LAMBDA_EXPR(params[0] + params[1]) } }, + { "sub", { 2, LAMBDA_EXPR(params[0] - params[1]) } }, + { "mul", { 2, LAMBDA_EXPR(params[0] * params[1]) } }, + { "div", { 2, LAMBDA_EXPR(params[0] / params[1]) } }, + { "pow", { 2, LAMBDA_EXPR(pow(params[0], params[1])) } }, + { "mod", { 2, LAMBDA_EXPR(fmod(params[0], params[1])) } }, + { "divi", { 2, LAMBDA_EXPR((int)((int)params[0] / (int)params[1])) } }, + { "sqrt", { 1, LAMBDA_EXPR(sqrt(params[0])) } }, + { "abs", { 1, LAMBDA_EXPR(fabs(params[0])) } }, + { "sin", { 1, LAMBDA_EXPR(sin(params[0])) } }, + { "cos", { 1, LAMBDA_EXPR(cos(params[0])) } }, + { "tan", { 1, LAMBDA_EXPR(tan(params[0])) } }, + { "asin", { 1, LAMBDA_EXPR(asin(params[0])) } }, + { "acos", { 1, LAMBDA_EXPR(acos((params[0]))) } }, + { "atan", { 1, LAMBDA_EXPR(atan(params[0])) } }, + { "ln", { 1, LAMBDA_EXPR(log(params[0])) } }, + { "log", { 1, LAMBDA_EXPR(log10(params[0])) } }, + { "log2", { 1, LAMBDA_EXPR(log2(params[0])) } }, + { "floor", { 1, LAMBDA_EXPR(floor(params[0])) } }, + { "ceil", { 1, LAMBDA_EXPR(ceil(params[0])) } }, + { "sign", { 1, LAMBDA_EXPR(abs(params[0]) < 1e-10 ? 0 : params[0] > 0 ? 1 + : -1) }}, + { "PI", { 0, LAMBDA_EXPR(M_PI) } }, + { "E", { 0, LAMBDA_EXPR(M_E) } }, + }; +} + +void eXpressionCalc::resetError() { + Error.type = ErrorType::Well; + Error.msg = ""; +} + +inline bool eXpressionCalc::checkNumber() { + return isdigit(*ExprIt) + || ((ExprIt == Expr.begin() || *(ExprIt - 1) == '(') + && ((*ExprIt == '-' || *ExprIt == '+') && (ExprIt + 1) != Expr.end())) + || ((*ExprIt == '.') && (ExprIt + 1) != Expr.end() && isdigit(*(ExprIt + 1))); +} + +std::string eXpressionCalc::readNumber() { + int dot_count = 0; + std::string rtn; + while (ExprIt != Expr.end() && checkNumber()) { + if (*ExprIt == '.') dot_count++; + if (dot_count > 1) break; + if (*ExprIt != '+') rtn += *ExprIt++; + else ++ExprIt; + } + return rtn; +} + +inline bool eXpressionCalc::checkFunc() { + return isalnum(*ExprIt); +} + +std::string eXpressionCalc::readFunc() { + std::string rtn; + while (ExprIt != Expr.end() && checkFunc()) rtn += *ExprIt++; + return rtn; +} + +bool eXpressionCalc::eatWhitespace() { + while (ExprIt != Expr.end() && (isspace(*ExprIt) || *ExprIt == ',')) ExprIt++; + return ExprIt == Expr.end(); +} + +bool eXpressionCalc::isNumber(const Expression_t& expr) { + return std::all_of(expr.begin(), expr.end(), [](char ch) -> bool { + return isdigit(ch) || ch == '.'; + }); +} + +Notation_t eXpressionCalc::reversePolishNotation() { + resetError(); + Notation_t result; + std::vector<std::string::const_iterator> buffer; + std::stack<std::pair<std::string, std::string::const_iterator>> tmpFunc; + for (ExprIt = Expr.begin(); ExprIt != Expr.end();) { + if (eatWhitespace()) + break; + + auto ch = *ExprIt; + if (!checkNumber()) { + if (checkFunc()) { + tmpFunc.push({ readFunc(), ExprIt }); + continue; + } + if (ch == '(' || buffer.empty()) { + buffer.push_back(ExprIt); + } else if (ch == ')') { + while (!buffer.empty() && *buffer.back() != '(') { + result.push_back(std::string { *buffer.back() }); + buffer.pop_back(); + } + + if (!tmpFunc.empty() && buffer.back() == tmpFunc.top().second) { + result.push_back(tmpFunc.top().first); + tmpFunc.pop(); + } + + if (buffer.empty()) { + ERROR(ErrorType::BracketNotMatched, std::string({ '(' }), ERROR_BUT_RETURN_RESULT_TAG); + } else { + buffer.pop_back(); + } + + } else { + auto search_res_ch = TokenLevel.find(ch); + auto search_res_back = TokenLevel.find(*buffer.back()); + if (search_res_ch == TokenLevel.end()) { + ERROR(ErrorType::SyntaxError, std::string({ ch }), ERROR_BUT_RETURN_RESULT_TAG); + } + if (search_res_back == TokenLevel.end()) { + ERROR(ErrorType::SyntaxError, std::string({ *buffer.back() }), ERROR_BUT_RETURN_RESULT_TAG); + } + if (TokenLevel.at(ch) <= TokenLevel.at(*buffer.back())) { + while (!buffer.empty() && TokenLevel.at(ch) <= TokenLevel.at(*buffer.back())) { + result.push_back(std::string { *buffer.back() }); + buffer.pop_back(); + } + } + buffer.push_back(ExprIt); + } + ++ExprIt; + } else { + std::string num = readNumber(); + result.push_back(num); + } + } + + while (!buffer.empty()) { + result.push_back(std::string { *buffer.back() }); + buffer.pop_back(); + } + +ERROR_BUT_RETURN_RESULT_TAG: + return result; +} + +double eXpressionCalc::evalNotation(const Notation_t& notation) { + resetError(); + if (notation.empty()) + return INFINITY; + + std::stack<double> resultStack; + + for (auto& note : notation) { + if (isNumber(note)) { + resultStack.push(strtod(note.c_str(), nullptr)); + } else { + if (note == "(" || note == ")") { + ERROR(ErrorType::BracketNotMatched, note, ERROR_BUT_RETURN_INFINITY_TAG); + } + + auto nt_it = NoteTable.find(note); + if (nt_it == NoteTable.end()) { + ERROR(ErrorType::FunctionNotFound, note, ERROR_BUT_RETURN_INFINITY_TAG); + } + + const auto pCount = nt_it->second.first; + const auto param = new double[pCount]; + for (auto i = pCount - 1; i >= 0; i--) { + if (resultStack.empty()) { + delete[] param; + ERROR(ErrorType::SyntaxError, note, ERROR_BUT_RETURN_INFINITY_TAG); + } + param[i] = resultStack.top(); + resultStack.pop(); + } + + resultStack.push(nt_it->second.second(param, pCount)); + + delete[] param; + } + } + + if (resultStack.size() > 1) { + ERROR(ErrorType::EvalError, "Can't Evaluate Correctly", ERROR_BUT_RETURN_RESULT_TAG); + } + +ERROR_BUT_RETURN_RESULT_TAG: + return resultStack.top(); +ERROR_BUT_RETURN_INFINITY_TAG: + return INFINITY; +} + +void eXpressionCalc::setExpression(Expression_t expression) { + Expr = std::move(expression); +} + +const Error_t& eXpressionCalc::getError() { + return Error; +} + +std::string eXpressionCalc::errorToString() { + return ErrorType2Name[getError().type]; +} + +void eXpressionCalc::addFunc(const std::string& note, int pNum, MyFunc_t func) { + NoteTable[note] = { + pNum, + func + }; +} + +void eXpressionCalc::addToken(char token, int level) { + TokenLevel[token] = level; +} +} + +#pragma clang diagnostic pop diff --git a/calculator/expression_calc.h b/calculator/expression_calc.h new file mode 100644 index 0000000000000000000000000000000000000000..e6122d26f924e2fdd53abcd5aacdf4bdccb547e7 --- /dev/null +++ b/calculator/expression_calc.h @@ -0,0 +1,100 @@ +/* + * expression_calc.h + * Created by W-Mai on 2022/10/2. + * + * MIT License + * Copyright (c) 2022 XCLZ STUDIO@W-Mai + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef EXPRESSIONCALC_EXPRESSION_CALC_H +#define EXPRESSIONCALC_EXPRESSION_CALC_H + +#include <algorithm> +#include <cmath> +#include <iostream> +#include <map> +#include <stack> +#include <string> +#include <vector> + +#define LAMBDA_EXPR(expr) [](const double* params, const int num) -> double { return expr; } + +namespace XCLZ { + +enum class ErrorType { + Well, + FunctionNotFound, + EvalError, + SyntaxError, + BracketNotMatched +}; + +typedef struct Error { + ErrorType type = ErrorType::Well; + std::string msg; +} Error_t; + +typedef std::map<char, int> TokenLevel_t; +typedef std::vector<std::string> Notation_t; +typedef std::string Expression_t; +typedef std::string String_t; +typedef std::string::const_iterator ExpressionIt_t; +typedef std::map<ErrorType, std::string> ErrorType2Name_t; + +typedef double (*MyFunc_t)(const double* params, const int num); +typedef std::map<std::string, std::pair<int, MyFunc_t>> NoteTable_t; + +// Class Declaration +class eXpressionCalc { + +private: + ErrorType2Name_t ErrorType2Name; + TokenLevel_t TokenLevel; + NoteTable_t NoteTable; + Error_t Error; + + Expression_t Expr; + ExpressionIt_t ExprIt; + + void resetError(); + + bool eatWhitespace(); + bool checkNumber(); + String_t readNumber(); + bool checkFunc(); + String_t readFunc(); + bool isNumber(const Expression_t& expr); + +public: + eXpressionCalc(); + Notation_t reversePolishNotation(); + double evalNotation(const Notation_t& notation); + + void setExpression(Expression_t expression); + const Error_t& getError(); + String_t errorToString(); + + void addFunc(const String_t& note, int pNum, MyFunc_t func); + void addToken(char token, int level); +}; +} + +#endif // EXPRESSIONCALC_EXPRESSION_CALC_H diff --git a/calculator/res/fonts/MiSans-Normal.ttf b/calculator/res/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/calculator/res/fonts/MiSans-Normal.ttf differ diff --git a/calculator/res/fonts/MiSans-Semibold.ttf b/calculator/res/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/calculator/res/fonts/MiSans-Semibold.ttf differ diff --git a/calculator/res/icons/background.png b/calculator/res/icons/background.png new file mode 100644 index 0000000000000000000000000000000000000000..b3cb7909b7bdb9cde8d501099ac161d8bb801e5b Binary files /dev/null and b/calculator/res/icons/background.png differ diff --git a/calculator/screen_history/screenshot_commit1.jpg b/calculator/screen_history/screenshot_commit1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..da591844bcf9f1cadcff64f92336513814c1f3bb Binary files /dev/null and b/calculator/screen_history/screenshot_commit1.jpg differ diff --git a/calculator/screen_history/screenshot_commit4.png b/calculator/screen_history/screenshot_commit4.png new file mode 100644 index 0000000000000000000000000000000000000000..9984ac0bcfe90ebc329130fa1bf0c5654c630c88 Binary files /dev/null and b/calculator/screen_history/screenshot_commit4.png differ diff --git a/calculator/screen_history/screenshot_commit5.png b/calculator/screen_history/screenshot_commit5.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4b3756ba583b9db322932a5b09c7292c688f17 Binary files /dev/null and b/calculator/screen_history/screenshot_commit5.png differ diff --git a/calculator/screen_history/screenshot_commit7.png b/calculator/screen_history/screenshot_commit7.png new file mode 100644 index 0000000000000000000000000000000000000000..6725b7605d817643a8fce68e9c41b17b7bdef4cd Binary files /dev/null and b/calculator/screen_history/screenshot_commit7.png differ diff --git a/hourglass/Kconfig b/hourglass/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..bc7741a0b4e78c445aa4026f49952d14a1b12171 --- /dev/null +++ b/hourglass/Kconfig @@ -0,0 +1,30 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig LVX_USE_DEMO_HOURGLASS + tristate "Hourglass Demo" + depends on GRAPHICS_LVGL + default n + ---help--- + Enable build the Light and Versatile Graphics Library Demo programs + +if LVX_USE_DEMO_HOURGLASS + +config LVX_USE_DEMO_HOURGLASS_PRIORITY + int "hourglass task priority" + default 100 + +config LVX_USE_DEMO_HOURGLASS_STACKSIZE + int "hourglass stack size" + default 16384 + +config LVX_USE_DEMO_HOURGLASS_DEVPATH + string "Touchscreen device path" + default "/dev/input0" + depends on INPUT_TOUCHSCREEN + ---help--- + The path to the touchscreen device. Default: "/dev/input0" + +endif # LVX_USE_DEMO_HOURGLASS diff --git a/hourglass/Make.defs b/hourglass/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..521d3840c650f9c4258be89eb960c5cb605bf32c --- /dev/null +++ b/hourglass/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# packages/demos/hourglass/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_LVX_USE_DEMO_HOURGLASS),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/hourglass +endif diff --git a/hourglass/Makefile b/hourglass/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8d7900a4935df013113e809c2c0a44548ac3d399 --- /dev/null +++ b/hourglass/Makefile @@ -0,0 +1,33 @@ +############################################################################ +# packages/demos/hourglass/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_HOURGLASS), y) +PROGNAME = hourglass +PRIORITY = $(CONFIG_LVX_USE_DEMO_HOURGLASS_PRIORITY) +STACKSIZE = $(CONFIG_LVX_USE_DEMO_HOURGLASS_STACKSIZE) +MODULE = $(CONFIG_LVX_USE_DEMO_HOURGLASS) + +CSRCS = hourglass_page.c hourglass_control.c +MAINSRC = hourglass_main.c +endif + +include $(APPDIR)/Application.mk diff --git a/hourglass/Readme.md b/hourglass/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..7f7da3b0a3c335287c03f92e3c41e4976f148d57 --- /dev/null +++ b/hourglass/Readme.md @@ -0,0 +1,79 @@ +电子沙漏 Demo (Hourglass Demo) +项目简介 +这是一个基于openvela系统,在模拟器上运行的电子沙漏演示程序。它使用LVGL图形库创建了一个可视化的沙漏效果,用户可以通过触摸屏控制沙漏的启动和计时时间。 +功能特性 +逼真的沙漏动画:模拟沙粒从上至下的流动效果。 +交互控制: +开始/重置:启动或重置沙漏计时。 +时间调整:增加或减少沙漏的总计时时间。 +模块化设计:UI界面与控制逻辑分离,便于维护和扩展。 +前提条件: +已搭建OpenVela开发环境(参考:[环境搭建](https://gitee.com/open-vela/docs/blob/dev/zh-cn/quickstart/Set_up_the_development_environment_zh-cn.md)) +已获取OpenVela源码(参考:[下载openvela源码](https://gitee.com/open-vela/docs/blob/dev/zh-cn/quickstart/Download_Vela_sources_zh-cn.md)) +快速开始 +1. 配置项目 +### 打开功能选项 +```bash +./build.sh vendor/openvela/boards/vela/configs/qemu-armeabi-v7a-ap/ distclean -j$(nproc) menuconfig +``` +在打开的配置界面中,进行如下操作: +按下 / 键,搜索 LVX_USE_DEMO_HOURGLASS。 +按回车键进入该配置项。 +按下空格键,将选项标记为 [*] (即 =y) 以启用该Demo。 +多次按 Q 键退出,并在提示是否保存时按 Y 键。 +注意:其他相关配置(如设备路径、任务优先级等)已预设好,无需修改,除非有特殊需求。 +2. 编译与构建 +在源码根目录下,依次执行以下命令: +### 构建 +```bash +./build.sh vendor/openvela/boards/vela/configs/qemu-armeabi-v7a-ap/ -j$(nproc) +``` + +### 清理构建产物 +```bash +./build.sh vendor/openvela/boards/vela/configs/qemu-armeabi-v7a-ap/ distclean -j$(nproc) +``` + +3. 运行Demo +### 启动模拟器 +```bash +./emulator.sh vela +``` + +### 启动计算器应用 +```bash +hourglass & +``` + +项目结构 +text +vela/packages/demos/hourglass/ +├── hourglass_page.c/h # UI界面绘制、按钮事件处理 +├── hourglass_control.c/h # 沙漏动画的核心控制逻辑与状态机 +├── hourglass_main.c # 程序入口,任务初始化 +├── Kconfig # 项目配置选项(使能、优先级、设备路径等) +├── Make.defs # 编译系统依赖项定义 +└── Makefile # 编译规则 +核心实现说明 +UI界面 +沙漏主体:由两个旋转45度的正方形容器构成,每个容器内动态创建8x8的红色小方块矩阵来模拟沙粒。 +控制面板:包含Start按钮和+/-按钮,用于控制沙漏运行和调整时间。 +控制逻辑 +状态机:管理沙漏的初始、运行、结束三种状态。 +定时器驱动:核心动画由LVGL定时器周期性触发。 +沙粒移动算法:使用对角线扫描与随机方向策略,每次移动一粒“沙粒”(即改变一个小方块的颜色),模拟自然下落。 +故障排除 +Demo未启动:请确认配置步骤中 LVX_USE_DEMO_HOURGLASS 已正确设置为 y。 +触摸无响应:检查 LVX_USE_DEMO_HOURGLASS_DEVPATH 配置的设备路径是否与系统实际设备节点匹配。 +编译错误:确保开发环境已正确搭建,并执行过彻底的 distclean。 + +--- + + + + + + + + + diff --git a/hourglass/hourglass_control.c b/hourglass/hourglass_control.c new file mode 100644 index 0000000000000000000000000000000000000000..d1b97dedf710dc47bbc0d81748ed4becf4c1b66a --- /dev/null +++ b/hourglass/hourglass_control.c @@ -0,0 +1,265 @@ +#include "hourglass_control.h" + +#define ROWS 8 +#define CLOUMS 8 +#define MATRIX_SIZE 8 + +static void demo_start(lv_timer_t *timer); + +extern int time_value; +extern struct post1 (*matrix_top_ptr)[CLOUMS]; +extern struct post1 (*matrix_bottom_ptr)[CLOUMS]; + +lv_timer_t *ptimer = NULL; + +static void setLed(int addr, int row, int column, bool state) +{ + if(addr<0 || addr>=2) + return; + if(row<0 || row>7 || column<0 || column>7) + return; + + if (addr == 0) { + if (state) { + lv_obj_set_style_bg_color(matrix_top_ptr[row][column].obj, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); + matrix_top_ptr[row][column].state = true; + } else { + lv_obj_set_style_bg_color(matrix_top_ptr[row][column].obj, lv_color_white(), LV_PART_MAIN); + matrix_top_ptr[row][column].state = false; + } + } else { + if (state) { + lv_obj_set_style_bg_color(matrix_bottom_ptr[row][column].obj, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); + matrix_bottom_ptr[row][column].state = true; + LV_LOG_USER("%s %d, bottom led on x %d, y %d", __func__, __LINE__, row, column); + } else { + lv_obj_set_style_bg_color(matrix_bottom_ptr[row][column].obj, lv_color_white(), LV_PART_MAIN); + matrix_bottom_ptr[row][column].state = false; + } + } +} + +static bool getLed(int addr, int row, int column) +{ + if(addr<0 || addr>=2) + return false; + if(row<0 || row>7 || column<0 || column>7) + return false; + + if (addr == 0) { + return matrix_top_ptr[row][column].state; + } + + return matrix_bottom_ptr[row][column].state; +} + +static bool canGoLeft(int addr, int x, int y) +{ + if (x == 0) return false; // not available + + return !getLed(addr, x - 1, y); +} +static bool canGoRight(int addr, int x, int y) +{ + if (y == 7) return false; // not available + + return !getLed(addr, x, y + 1); +} +static bool canGoDown(int addr, int x, int y) +{ + if (y == 7) return false; // not available + if (x == 0) return false; // not available + if (!canGoLeft(addr, x, y)) return false; + if (!canGoRight(addr, x, y)) return false; + + return !getLed(addr, x - 1, y + 1); +} + +static void goDown(int addr, int x, int y) +{ + setLed(addr, x, y, false); + setLed(addr, x - 1, y + 1, true); +} + +static void goLeft(int addr, int x, int y) +{ + setLed(addr, x, y, false); + setLed(addr, x - 1, y, true); +} + +static void goRight(int addr, int x, int y) +{ + setLed(addr, x, y, false); + setLed(addr, x, y + 1, true); +} + +static void checking(int addr) +{ + if (!getLed(addr, 5, 2)) { + setLed(addr, 5, 2, true); + for (int i = 0; i < 100000; i++) { + } + LV_LOG_USER("%s %d, getLed is no", __func__, __LINE__); + setLed(addr, 5, 2, false); + } +} + +static bool moveParticle(int addr, int x, int y) +{ + bool can_GoLeft = canGoLeft(addr, x, y); + bool can_GoRight = canGoRight(addr, x, y); + + if (!can_GoLeft && !can_GoRight) { + return false; + } + + checking(addr); + + bool can_GoDown = canGoDown(addr, x, y); + if (can_GoDown) { + goDown(addr, x, y); + } else if (can_GoLeft && !can_GoRight) { + goLeft(addr, x, y); + } else if (can_GoRight && !can_GoLeft) { + goRight(addr, x, y); + } else if (random() % 2 == 1) { + goLeft(addr, x, y); + } else { + goRight(addr, x, y); + } + return true; +} + +static bool updateMatrix(void) +{ + int n = 8; + bool somethingMoved = false; + int x, y; + bool direction; + + for (int slice = 0; slice < 2 * n - 1; ++slice) { + direction = (random() % 2 == 1); + int z = slice < n ? 0 : slice - n + 1; + + for (int j = z; j <= slice - z; ++j) { + y = direction ? (7 - j) : (7 - (slice - j)); + x = direction ? (slice - j) : j; + if (moveParticle(1, x, y)) { + somethingMoved = true; + goto find; + } else { + LV_LOG_USER("%s %d, moveParticle 1 is no", __func__, __LINE__); + } + } + } + +find: + + return somethingMoved; +} + +// 重置沙漏 +void reset_sand_hourglass(void) +{ + if (ptimer) { + lv_timer_del(ptimer); + ptimer = NULL; + } + + // 重置上方矩阵 (全亮) + for (uint8_t y = 0; y < MATRIX_SIZE; y++) { + for (uint8_t x = 0; x < MATRIX_SIZE; x++) { + if ((x == 0 || x == 1) && (y == 6 || y == 7)) { + lv_obj_set_style_bg_color(matrix_top_ptr[y][x].obj, lv_color_white(), LV_PART_MAIN); + matrix_top_ptr[y][x].state = false; + } else { + lv_obj_set_style_bg_color(matrix_top_ptr[y][x].obj, lv_palette_main(LV_PALETTE_RED), 0); + matrix_top_ptr[y][x].state = true; + } + } + } + + // 重置下方矩阵 (全暗) + for (uint8_t y = 0; y < MATRIX_SIZE; y++) { + for (uint8_t x = 0; x < MATRIX_SIZE; x++) { + lv_obj_set_style_bg_color(matrix_bottom_ptr[y][x].obj, lv_color_white(), 0); + matrix_bottom_ptr[y][x].state = 0; + } + } + + // 重新创建定时器 + ptimer = lv_timer_create(demo_start, time_value * 1000, NULL); +} + +// 尝试移动沙粒(优化后的对角线扫描+随机方向) +static uint8_t move_sand_particle(uint8_t from_top) +{ + uint8_t something_moved = 0; + uint8_t x, y; + uint8_t direction; + LV_LOG_USER("%s %d", __func__, __LINE__); + + // 对角线扫描(类似您提供的算法) + for (uint8_t slice = 0; slice < 2 * ROWS - 1; ++slice) { + direction = (rand() % 2); // 随机扫描方向 + uint8_t z = slice < ROWS ? 0 : slice - ROWS + 1; + + for (uint8_t j = z; j <= slice - z; ++j) { + y = direction ? (ROWS - 1 - j) : (ROWS - 1 - (slice - j)); + x = direction ? (slice - j) : j; + + // 只在上矩阵寻找亮起的元素,或在下矩阵寻找暗的元素 + if ((from_top && matrix_top_ptr[y][x].state) || (!from_top && !matrix_bottom_ptr[y][x].state)) { + // 检查边界 + if (x >= 0 && x < ROWS && y >= 0 && y < ROWS) { + // 上矩阵:尝试移动亮起的元素 + if (from_top && matrix_top_ptr[y][x].state) { + matrix_top_ptr[y][x].state = 0; + lv_obj_set_style_bg_color(matrix_top_ptr[y][x].obj, lv_color_white(), 0); + something_moved = 1; + return something_moved; // 每次只移动一粒沙子 + } + // 下矩阵:尝试填充暗的元素 + else if (!from_top && !matrix_bottom_ptr[y][x].state) { + matrix_bottom_ptr[y][x].state = 1; + lv_obj_set_style_bg_color(matrix_bottom_ptr[y][x].obj, lv_palette_main(LV_PALETTE_RED), 0); + something_moved = 1; + return something_moved; // 每次只填充一粒沙子 + } + } + } + } + } + + return something_moved; +} + +static void demo_start(lv_timer_t *timer) +{ + LV_LOG_USER("%s %d, Clicked", __func__, __LINE__); + + // 1. 从上矩阵移动一粒沙子(随机对角线扫描) + uint8_t moved = move_sand_particle(1); + + // 2. 如果成功移除了沙子,在下矩阵添加一粒沙子 + if (moved) { + updateMatrix(); + } + + // 3. 检查上矩阵是否还有沙子 + uint8_t has_sand = 0; + for (uint8_t y = 0; y < ROWS && !has_sand; y++) { + for (uint8_t x = 0; x < ROWS && !has_sand; x++) { + if (matrix_top_ptr[y][x].state) has_sand = 1; + } + } + + if (!has_sand) { + if (ptimer) { + lv_timer_del(ptimer); + ptimer = NULL; + } + } +} + + diff --git a/hourglass/hourglass_control.h b/hourglass/hourglass_control.h new file mode 100644 index 0000000000000000000000000000000000000000..3671e6efe2e4ba8f834aae6b50a3d505abf60251 --- /dev/null +++ b/hourglass/hourglass_control.h @@ -0,0 +1,9 @@ +#ifndef HOURGLASS_CONTROL_H +#define HOURGLASS_CONTROL_H + +#include <stdio.h> +#include <time.h> +#include "lvgl.h" +#include "hourglass_page.h" + +#endif \ No newline at end of file diff --git a/hourglass/hourglass_main.c b/hourglass/hourglass_main.c new file mode 100644 index 0000000000000000000000000000000000000000..593f49c118bbdcee10d5e4a4799119bb560b6868 --- /dev/null +++ b/hourglass/hourglass_main.c @@ -0,0 +1,171 @@ +/**************************************************************************** + * packages/demos/hourglass/hourglass_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <unistd.h> +#include <sys/boardctl.h> + +#include <lvgl/lvgl.h> +#include <lvgl/demos/lv_demos.h> +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +#include <uv.h> +#endif + +#include "hourglass_page.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Should we perform board-specific driver initialization? There are two + * ways that board initialization can occur: 1) automatically via + * board_late_initialize() during bootupif CONFIG_BOARD_LATE_INITIALIZE + * or 2). + * via a call to boardctl() if the interface is enabled + * (CONFIG_BOARDCTL=y). + * If this task is running as an NSH built-in application, then that + * initialization has probably already been performed otherwise we do it + * here. + */ + +#undef NEED_BOARDINIT + +#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_NSH_ARCHINIT) +# define NEED_BOARDINIT 1 +#endif + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void launcher_create(void) +{ + sandglass_page_create(); +} + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +static void lv_nuttx_uv_loop(uv_loop_t *loop, lv_nuttx_result_t *result) +{ + lv_nuttx_uv_t uv_info; + void *data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: main or lv_demos_main + * + * Description: + * + * Input Parameters: + * Standard argc and argv + * + * Returned Value: + * Zero on success; a positive, non-zero value on failure. + * + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + uv_loop_t ui_loop; + lv_memzero(&ui_loop, sizeof(ui_loop)); +#endif + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + +#ifdef NEED_BOARDINIT + /* Perform board-specific driver initialization */ + boardctl(BOARDIOC_INIT, 0); +#endif + + lv_init(); + lv_nuttx_dsc_init(&info); + +#ifdef CONFIG_LV_USE_NUTTX_LCD + info.fb_path = "/dev/lcd0"; +#endif + +#ifdef CONFIG_INPUT_TOUCHSCREEN + info.input_path = CONFIG_LVX_USE_DEMO_HOURGLASS_DEVPATH; +#endif + + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + launcher_create(); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + lv_nuttx_uv_loop(&ui_loop, &result); +#else + + while (1) { + uint32_t idle; + idle = lv_timer_handler(); + /* Minimum sleep of 1ms */ + idle = idle ? idle : 1; + usleep(idle * 1000); + } +#endif + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/hourglass/hourglass_page.c b/hourglass/hourglass_page.c new file mode 100644 index 0000000000000000000000000000000000000000..d1b2219f1c6bb8e25df318de1b110ef0f403bbd9 --- /dev/null +++ b/hourglass/hourglass_page.c @@ -0,0 +1,260 @@ +#include "hourglass_page.h" + +#define PART_WIDTH_HEIGHT 130 +#define CHILD_WIDTH_HEIGHT 16 +#define EXPAND_WIDTH 50 +#define PADDING_WIDTH 5 +#define ROWS_VALUE 8 +#define CLOUMS_VALUE 8 +#define DISP_ROTATION_SUPPORT 1 // 1横屏 0竖屏 + +extern void reset_sand_hourglass(void); +static void SetStyle_PartChildren(lv_style_t *style); +static void SetStyle_Part(lv_style_t *style); +static void Menu_Create( lv_obj_t *parent,lv_obj_t *obj); + +typedef enum { + LV_EVENT_USER_START = 100, +}lv_event_user_code_t; + +static void plus_event_cb(lv_event_t * e); +static void minus_event_cb(lv_event_t * e); +static void start_event_cb(lv_event_t * e); +static void excu_event_cb(lv_event_t * e); + +lv_obj_t *start_btn = NULL; +lv_obj_t *part_parent = NULL; +lv_obj_t *plus_label = NULL; +lv_obj_t *minus_label = NULL; +lv_obj_t *time_label = NULL; + +int time_value = 1; + +Post1_t (*matrix_top_ptr)[CLOUMS_VALUE] = NULL; +Post1_t (*matrix_bottom_ptr)[CLOUMS_VALUE] = NULL; +Post1_t matrix_top[ROWS_VALUE][CLOUMS_VALUE]; +Post1_t matrix_bottom[ROWS_VALUE][CLOUMS_VALUE]; + +void sandglass_page_create(void) +{ + lv_obj_t *menu = NULL; + + static lv_style_t part_style; + static lv_style_t children_style; + SetStyle_Part(&part_style); + SetStyle_PartChildren(&children_style); + lv_obj_t *screen = lv_screen_active(); + + // 创建父对象 + part_parent = lv_obj_create(screen); + lv_obj_clear_flag(part_parent, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_style_opa(part_parent, LV_OPA_COVER, LV_PART_MAIN); +#if DISP_ROTATION_SUPPORT + lv_obj_set_size(part_parent, 272,480); +#else + lv_obj_set_size(part_parent, 480,272); +#endif + lv_obj_align(part_parent, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_radius(part_parent, 30, LV_PART_MAIN); // 四角圆角半径150 + lv_obj_set_style_bg_color(part_parent, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_border_width(part_parent, 0, LV_PART_MAIN); // 父对象无边框 + lv_obj_add_event_cb(part_parent, excu_event_cb, (lv_event_code_t)LV_EVENT_USER_START, NULL); + + lv_obj_t *part_top = lv_obj_create(part_parent); + lv_obj_remove_style_all(part_top); + lv_obj_add_style(part_top, &part_style, LV_PART_MAIN); + lv_obj_set_style_transform_pivot_x(part_top, PART_WIDTH_HEIGHT / 2,LV_PART_MAIN); // 中心点 X 轴(百分比) + lv_obj_set_style_transform_pivot_y(part_top, PART_WIDTH_HEIGHT / 2,LV_PART_MAIN); // 中心点 Y 轴 + #if DISP_ROTATION_SUPPORT + lv_obj_align(part_top,LV_ALIGN_TOP_MID,0,20); + lv_obj_set_style_transform_rotation(part_top, -450,LV_PART_MAIN | LV_STATE_DEFAULT); // 旋转角度 +#else + lv_obj_align(part_top,LV_ALIGN_RIGHT_MID,-20,0); + lv_obj_set_style_transform_rotation(part_top, 450,LV_PART_MAIN | LV_STATE_DEFAULT); // 旋转角度 +#endif + + lv_obj_set_style_clip_corner(part_top,false,0); + lv_obj_clear_flag(part_top,LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_CLICKABLE); + + // 配置子对象统一样式 + // 生成子对象 + for (int i = 0; i < ROWS_VALUE ; i++) { + for (int j = 0; j < CLOUMS_VALUE; j++) { + lv_obj_t* child = lv_obj_create(part_top); + lv_obj_add_style(child, &children_style, LV_PART_MAIN); + lv_obj_set_pos(child,i*CHILD_WIDTH_HEIGHT,j*CHILD_WIDTH_HEIGHT); + + matrix_top[i][j].obj = child; + matrix_top[i][j].state = true; + if ((i == 6 || i == 7) && (j == 0 || j == 1)) { + lv_obj_set_style_bg_color(matrix_top[i][j].obj, lv_color_white(), LV_PART_MAIN); + matrix_top[i][j].state = false; + } + } + } + matrix_top_ptr = matrix_top; + + lv_obj_t *part_bottom = lv_obj_create(part_parent); + lv_obj_remove_style_all(part_bottom); + lv_obj_add_style(part_bottom, &part_style, LV_PART_MAIN); + lv_obj_set_style_transform_pivot_x(part_bottom, PART_WIDTH_HEIGHT / 2,LV_PART_MAIN); // 中心点 X 轴(百分比) + lv_obj_set_style_transform_pivot_y(part_bottom, PART_WIDTH_HEIGHT / 2,LV_PART_MAIN); // 中心点 Y 轴 +#if DISP_ROTATION_SUPPORT + lv_obj_align(part_bottom,LV_ALIGN_BOTTOM_MID,0,-110); + lv_obj_set_style_transform_rotation(part_bottom, -450,LV_PART_MAIN | LV_STATE_DEFAULT); // 旋转角度 +#else + lv_obj_align(part_bottom,LV_ALIGN_LEFT_MID,111,0); + lv_obj_set_style_transform_rotation(part_bottom, 450,LV_PART_MAIN | LV_STATE_DEFAULT); // 旋转角度 +#endif + lv_obj_set_style_clip_corner(part_bottom,false,0); + lv_obj_clear_flag(part_bottom,LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_CLICKABLE); + + // 生成子对象 + for (int i = 0; i < ROWS_VALUE; i++) { + for (int j = 0; j < CLOUMS_VALUE; j++) { + lv_obj_t* child = lv_obj_create(part_bottom); + lv_obj_add_style(child, &children_style, LV_PART_MAIN); + lv_obj_set_pos(child,i*CHILD_WIDTH_HEIGHT,j*CHILD_WIDTH_HEIGHT); + + matrix_bottom[i][j].obj = child; + lv_obj_set_style_bg_color(matrix_bottom[i][j].obj, lv_color_white(), LV_PART_MAIN); + matrix_bottom[i][j].state = false; + } + } + matrix_bottom_ptr = matrix_bottom; + Menu_Create(screen,menu); +} + +static void SetStyle_PartChildren(lv_style_t *style) +{ + lv_style_init(style); + lv_style_set_size(style, CHILD_WIDTH_HEIGHT,CHILD_WIDTH_HEIGHT); + lv_style_set_border_width(style, 1); + lv_style_set_border_color(style, lv_color_black()); + lv_style_set_border_opa(style, LV_OPA_20); + lv_style_set_bg_color(style, lv_palette_main(LV_PALETTE_RED)); + lv_style_set_bg_opa(style, LV_OPA_COVER); + lv_style_set_pad_all(style, 0); // 清除内边距[citation:3] + lv_style_set_radius(style,0); +} + +static void SetStyle_Part(lv_style_t *style) +{ + lv_style_init(style); + lv_style_set_pad_all(style,0); + lv_style_set_width(style,PART_WIDTH_HEIGHT); + lv_style_set_height(style,PART_WIDTH_HEIGHT); + lv_style_set_border_width(style, 1); + lv_style_set_border_color(style, lv_color_black()); + lv_style_set_radius(style,0); +} + +static void Menu_Create( lv_obj_t *parent,lv_obj_t *obj) +{ + obj = lv_obj_create(parent); + lv_obj_set_size(obj, 180, 52); + lv_obj_clear_flag(obj,LV_OBJ_FLAG_SCROLLABLE ); + lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffff), LV_PART_MAIN); +#if DISP_ROTATION_SUPPORT + lv_obj_align(obj,LV_ALIGN_BOTTOM_MID,0,-200); +#else + lv_obj_align(obj,LV_ALIGN_LEFT_MID,-30,0); + lv_obj_set_style_transform_pivot_x(obj, 90,LV_PART_MAIN); // 中心点 X 轴(百分比) + lv_obj_set_style_transform_pivot_y(obj, 25,LV_PART_MAIN); // 中心点 Y 轴 + lv_obj_set_style_transform_rotation(obj, 900,LV_PART_MAIN | LV_STATE_DEFAULT); // 旋转角度 +#endif + start_btn = lv_button_create(obj); + lv_obj_align(start_btn,LV_ALIGN_LEFT_MID,-10,0); + lv_obj_set_size(start_btn, 45, 25); + lv_obj_clear_flag(start_btn,LV_OBJ_FLAG_SCROLLABLE ); + + lv_obj_t * btn_label = lv_label_create(start_btn); + lv_obj_center(btn_label); + lv_label_set_text(btn_label, "Start"); + lv_obj_set_style_bg_color(btn_label, lv_color_hex(0xfe8d00), LV_PART_MAIN | LV_STATE_CHECKED); + + time_label = lv_label_create(obj); + lv_obj_align(time_label,LV_ALIGN_LEFT_MID,75,0); + lv_obj_set_size(time_label, 40,20); + lv_obj_set_style_radius(time_label, 5, LV_PART_MAIN); + lv_obj_set_style_border_width(time_label,1,LV_PART_MAIN); + lv_obj_set_style_border_color(time_label, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_opa(time_label, LV_OPA_COVER,LV_PART_MAIN); + lv_obj_set_style_text_font(time_label, &lv_font_montserrat_14,LV_PART_MAIN); + lv_obj_set_style_text_color(time_label, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_text_align(time_label, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + char str[16] = {0}; + sprintf(str, "%d", time_value); + lv_label_set_text(time_label, str); + + lv_obj_t *plus = lv_button_create(obj); + lv_obj_align_to(plus,time_label,LV_ALIGN_OUT_LEFT_MID,15,0); + lv_obj_set_size(plus, 20, 20); + plus_label = lv_label_create(plus); + lv_obj_align(plus_label,LV_ALIGN_CENTER,0,0); + lv_label_set_text(plus_label, LV_SYMBOL_PLUS); + + lv_obj_t * minus = lv_button_create(obj); + lv_obj_align_to(minus,time_label,LV_ALIGN_OUT_RIGHT_MID,5,0); + lv_obj_set_size(minus, 20, 20); + + minus_label = lv_label_create(minus); + lv_obj_align(minus_label,LV_ALIGN_CENTER,0,0); + lv_label_set_text(minus_label, LV_SYMBOL_MINUS); + + lv_obj_add_event_cb(plus, plus_event_cb, LV_EVENT_SHORT_CLICKED, NULL); + lv_obj_add_event_cb(minus, minus_event_cb, LV_EVENT_SHORT_CLICKED, NULL); + lv_obj_add_event_cb(start_btn, start_event_cb, LV_EVENT_SHORT_CLICKED, NULL); +} + +static void plus_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_SHORT_CLICKED) { + LV_LOG_USER("Clicked"); + if (time_value >= 20) { + time_value = 20; + } else { + time_value++; + } + char str[16] = {0}; + sprintf(str, "%d", time_value); + lv_label_set_text(time_label, str); + } +} + +static void minus_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_SHORT_CLICKED) { + LV_LOG_USER("Clicked"); + if (time_value <= 1) { + time_value = 1; + } else { + time_value--; + } + char str[16] = {0}; + sprintf(str, "%d", time_value); + lv_label_set_text(time_label, str); + } +} + +static void start_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + if(code != LV_EVENT_SHORT_CLICKED ) { + return; + } + LV_LOG_USER("Clicked"); + reset_sand_hourglass(); +} + +static void excu_event_cb(lv_event_t * e) +{ + if(LV_EVENT_USER_START != (lv_event_user_code_t)lv_event_get_code(e)){ + return; + } +} + diff --git a/hourglass/hourglass_page.h b/hourglass/hourglass_page.h new file mode 100644 index 0000000000000000000000000000000000000000..53d6a43f54f72d1e3c7091fd9bc2c778c5936675 --- /dev/null +++ b/hourglass/hourglass_page.h @@ -0,0 +1,15 @@ +#ifndef HOURGLASS_PAGE_H +#define HOURGLASS_PAGE_H + +#include <string.h> +#include <stdio.h> +#include "lvgl.h" + +typedef struct post1 { + lv_obj_t *obj; + bool state; +}Post1_t; + +void sandglass_page_create(void); + +#endif \ No newline at end of file diff --git a/music_player/Kconfig b/music_player/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..f6534204589fe84d915ecf01d7eb9c3077365cd5 --- /dev/null +++ b/music_player/Kconfig @@ -0,0 +1,14 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_MUSIC_PLAYER + bool "Music Player" + default n + +if LVX_USE_DEMO_MUSIC_PLAYER + config LVX_MUSIC_PLAYER_DATA_ROOT + string "Music Player Data Root" + default "/sdcard" +endif diff --git a/music_player/Make.defs b/music_player/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..67bf18180e861389b6620e3e62c024cbd725cab0 --- /dev/null +++ b/music_player/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_MUSIC_PLAYER),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/music_player +endif diff --git a/music_player/Makefile b/music_player/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ed7255f5a947f2a8df28adfb4b1ae8c2996a7cdc --- /dev/null +++ b/music_player/Makefile @@ -0,0 +1,29 @@ +# +# Copyright (C) 2022 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_MUSIC_PLAYER), y) +PROGNAME = music_player +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_MUSIC_PLAYER) + +CSRCS = music_player.c audio_ctl.c wifi.c +MAINSRC = music_player_main.c +endif + +include $(APPDIR)/Application.mk diff --git a/music_player/audio_ctl.c b/music_player/audio_ctl.c new file mode 100644 index 0000000000000000000000000000000000000000..765c6f437451bc80ac089d6757a758aa82a3edd6 --- /dev/null +++ b/music_player/audio_ctl.c @@ -0,0 +1,287 @@ +/********************* + * INCLUDES + *********************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "audio_ctl.h" + +#include <audioutils/nxaudio.h> + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void app_dequeue_cb(unsigned long arg, + FAR struct ap_buffer_s *apb); +static void app_complete_cb(unsigned long arg); +static void app_user_cb(unsigned long arg, + FAR struct audio_msg_s *msg, FAR bool *running); + +/********************** + * STATIC VARIABLES + **********************/ + +static struct nxaudio_callbacks_s cbs = +{ + app_dequeue_cb, + app_complete_cb, + app_user_cb +}; + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void app_dequeue_cb(unsigned long arg, FAR struct ap_buffer_s *apb) +{ + FAR audioctl_s *ctl = (FAR audioctl_s *)(uintptr_t)arg; + + if (!apb) + { + return; + } + + if (ctl->seek) { + lseek(ctl->fd, ctl->seek_position, SEEK_SET); + ctl->file_position = ctl->seek_position; + ctl->seek = false; + } + + apb->nbytes = read(ctl->fd, apb->samp, apb->nmaxbytes); + apb->curbyte = 0; + apb->flags = 0; + + while (0 < apb->nbytes && apb->nbytes < apb->nmaxbytes) + { + int n = apb->nmaxbytes - apb->nbytes; + int ret = read(ctl->fd, &apb->samp[apb->nbytes], n); + + if (0 >= ret) + { + break; + } + apb->nbytes += ret; + } + + if (apb->nbytes < apb->nmaxbytes) + { + close(ctl->fd); + ctl->fd = -1; + + return ; + } + + ctl->file_position += apb->nbytes; + + nxaudio_enqbuffer(&ctl->nxaudio, apb); +} + +static void app_complete_cb(unsigned long arg) +{ + /* Do nothing.. */ + + printf("Audio loop is Done\n"); +} + +static void app_user_cb(unsigned long arg, + FAR struct audio_msg_s *msg, FAR bool *running) +{ + /* Do nothing.. */ +} + +static FAR void *audio_loop_thread(pthread_addr_t arg) +{ + FAR audioctl_s *ctl = (FAR audioctl_s *)arg; + + nxaudio_start(&ctl->nxaudio); + nxaudio_msgloop(&ctl->nxaudio, &cbs, + (unsigned long)(uintptr_t)ctl); + + return NULL; +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +FAR audioctl_s *audio_ctl_init_nxaudio(FAR const char *arg) +{ + FAR audioctl_s *ctl; + int ret; + int i; + + ctl = (FAR audioctl_s *)malloc(sizeof(audioctl_s)); + if(ctl == NULL) + { + return NULL; + } + + ctl->seek = false; + ctl->seek_position = 0; + ctl->file_position = 0; + + ctl->fd = open(arg, O_RDONLY); + if (ctl->fd < 0) { + printf("can't open audio file\n"); + return NULL; + } + + read(ctl->fd, &ctl->wav, sizeof(ctl->wav)); + + ret = init_nxaudio(&ctl->nxaudio, ctl->wav.fmt.samplerate, + ctl->wav.fmt.bitspersample, + ctl->wav.fmt.numchannels); + if (ret < 0) + { + printf("init_nxaudio() return with error!!\n"); + return NULL; + } + + for (i = 0; i < ctl->nxaudio.abufnum; i++) + { + app_dequeue_cb((unsigned long)ctl, ctl->nxaudio.abufs[i]); + } + + ctl->state = AUDIO_CTL_STATE_INIT; + + return ctl; +} + +int audio_ctl_start(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_INIT && ctl->state != AUDIO_CTL_STATE_PAUSE) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_START; + + pthread_attr_t tattr; + struct sched_param sparam; + + pthread_attr_init(&tattr); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 9; + pthread_attr_setschedparam(&tattr, &sparam); + pthread_attr_setstacksize(&tattr, 4096); + + pthread_create(&ctl->pid, &tattr, audio_loop_thread, + (pthread_addr_t)ctl); + + pthread_attr_destroy(&tattr); + pthread_setname_np(ctl->pid, "audioctl_thread"); + + return 0; +} + +int audio_ctl_pause(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_START) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_PAUSE; + + return nxaudio_pause(&ctl->nxaudio); +} + +int audio_ctl_resume(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_PAUSE) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_START; + + return nxaudio_resume(&ctl->nxaudio); +} + +int audio_ctl_seek(FAR audioctl_s *ctl, unsigned ms) +{ + if (ctl == NULL) + return -EINVAL; + + ctl->seek_position = ms * ctl->wav.fmt.samplerate * ctl->wav.fmt.bitspersample * ctl->wav.fmt.numchannels / 8; + ctl->seek = true; + + return 0; +} + +int audio_ctl_stop(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_PAUSE && ctl->state != AUDIO_CTL_STATE_START) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_STOP; + + nxaudio_stop(&ctl->nxaudio); + + if (ctl->pid > 0) + { + pthread_join(ctl->pid, NULL); + } + + return 0; +} + +int audio_ctl_set_volume(FAR audioctl_s *ctl, uint16_t vol) +{ + if (ctl == NULL) + return -EINVAL; + + return nxaudio_setvolume(&ctl->nxaudio, vol); +} + +int audio_ctl_get_position(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + return ctl->file_position / (ctl->wav.fmt.bitspersample * ctl->wav.fmt.numchannels * ctl->wav.fmt.samplerate / 8); +} + +int audio_ctl_uninit_nxaudio(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state == AUDIO_CTL_STATE_NOP) + { + return 0; + } + + if (ctl->fd > 0) + { + close(ctl->fd); + ctl->fd = -1; + } + + fin_nxaudio(&ctl->nxaudio); + + free(ctl); + + return 0; +} diff --git a/music_player/audio_ctl.h b/music_player/audio_ctl.h new file mode 100644 index 0000000000000000000000000000000000000000..e7e60993b3da128a7917731c5f59195a718653f2 --- /dev/null +++ b/music_player/audio_ctl.h @@ -0,0 +1,85 @@ +#ifndef AUDIO_CTL_H +#define AUDIO_CTL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include <audioutils/nxaudio.h> +#include <pthread.h> + +enum { + AUDIO_CTL_STATE_NOP, + AUDIO_CTL_STATE_INIT, + AUDIO_CTL_STATE_START, + AUDIO_CTL_STATE_PAUSE, + AUDIO_CTL_STATE_STOP, +}; + +typedef struct wav_riff { + /* chunk "riff" */ + char chunkID[4]; /* "RIFF" */ + /* sub-chunk-size */ + uint32_t chunksize; /* 36 + subchunk2size */ + /* sub-chunk-data */ + char format[4]; /* "WAVE" */ +} riff_s; + +typedef struct wav_fmt { + /* sub-chunk "fmt" */ + char subchunk1ID[4]; /* "fmt " */ + /* sub-chunk-size */ + uint32_t subchunk1size; /* 16 for PCM */ + /* sub-chunk-data */ + uint16_t audioformat; /* PCM = 1*/ + uint16_t numchannels; /* Mono = 1, Stereo = 2, etc. */ + uint32_t samplerate; /* 8000, 44100, etc. */ + uint32_t byterate; /* = samplerate * numchannels * bitspersample/8 */ + uint16_t blockalign; /* = numchannels * bitspersample/8 */ + uint16_t bitspersample; /* 8bits, 16bits, etc. */ +} fmt_s; + +typedef struct wav_data { + /* sub-chunk "data" */ + char subchunk2ID[4]; /* "data" */ + /* sub-chunk-size */ + uint32_t subchunk2size; /* data size */ + /* sub-chunk-data */ + //Data_block_t block; +} data_s; + +typedef struct wav_fotmat { + riff_s riff; + fmt_s fmt; + data_s data; +} wav_s; + +typedef struct audioctl { + struct nxaudio_s nxaudio; + wav_s wav; + int fd; + int state; + pthread_t pid; + int seek; + uint32_t seek_position; + uint32_t file_position; +} audioctl_s; + +FAR audioctl_s *audio_ctl_init_nxaudio(FAR const char *arg); +int audio_ctl_start(FAR audioctl_s *ctl); +int audio_ctl_pause(FAR audioctl_s *ctl); +int audio_ctl_resume(FAR audioctl_s *ctl); +int audio_ctl_seek(FAR audioctl_s *ctl, unsigned ms); +int audio_ctl_stop(FAR audioctl_s *ctl); +int audio_ctl_set_volume(FAR audioctl_s *ctl, uint16_t vol); +int audio_ctl_get_position(FAR audioctl_s *ctl); +int audio_ctl_uninit_nxaudio(FAR audioctl_s *ctl); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* AUDIO_CTL_H */ diff --git a/music_player/music_player.c b/music_player/music_player.c new file mode 100644 index 0000000000000000000000000000000000000000..d1ea2c2e19ee67a66c67b0f9eed9d5994cd26af1 --- /dev/null +++ b/music_player/music_player.c @@ -0,0 +1,1033 @@ +// +// Created by BenignX on 2024/3/21. +// + +/* + * UI: + * + * TIME GROUP: + * TIME: 00:00:00 + * DATE: 2024/03/21 + * + * PLAYER GROUP: + * ALBUM GROUP: + * ALBUM PICTURE + * ALBUM INFO: + * ALBUM NAME + * ALBUM ARTIST + * PROGRESS GROUP: + * CURRENT TIME: 00:00/00:00 + * PLAYBACK PROGRESS BAR + * CONTROL GROUP: + * PLAYLIST + * PREVIOUS + * PLAY/PAUSE + * NEXT + * AUDIO + * + * TOP Layer: + * VOLUME BAR + * PLAYLIST GROUP: + * TITLE + * LIST: + * ICON + * ALBUM NAME + * ALBUM ARTIST + */ + +/********************* + * INCLUDES + *********************/ + +#include "music_player.h" +#include <stdlib.h> +#include <netutils/cJSON.h> +#include <time.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/* Init functions */ +static void read_configs(void); +static bool init_resource(void); +static void reload_music_config(void); +static void app_create_error_page(void); +static void app_create_main_page(void); +static void app_create_top_layer(void); + +/* Timer starting functions */ +static void app_start_updating_date_time(void); + +/* Album operations */ +static int32_t app_get_album_index(album_info_t* album); +static void app_switch_to_album(int index); + +/* Album operations */ +static void app_set_play_status(play_status_t status); +static void app_set_playback_time(uint32_t current_time); +static void app_set_volume(uint16_t volume); + +/* UI refresh functions */ +static void app_refresh_album_info(void); +static void app_refresh_date_time(void); +static void app_refresh_play_status(void); +static void app_refresh_playback_progress(void); +static void app_refresh_playlist(void); +static void app_refresh_volume_bar(void); +static void app_refresh_volume_countdown_timer(void); + +/* Event handler functions */ +static void app_audio_event_handler(lv_event_t* e); +static void app_play_status_event_handler(lv_event_t* e); +static void app_playlist_btn_event_handler(lv_event_t* e); +static void app_playlist_event_handler(lv_event_t* e); +static void app_switch_album_event_handler(lv_event_t* e); +static void app_volume_bar_event_handler(lv_event_t* e); +static void app_playback_progress_bar_event_handler(lv_event_t* e); + +/* Timer callback functions */ +static void app_refresh_date_time_timer_cb(lv_timer_t* timer); +static void app_playback_progress_update_timer_cb(lv_timer_t* timer); +static void app_volume_bar_countdown_timer_cb(lv_timer_t* timer); + +/********************** + * STATIC VARIABLES + **********************/ + +// clang-format off +struct resource_s R; /**< Resources */ +struct ctx_s C; /**< Context */ +struct conf_s CF; /**< Configuration */ +// clang-format on + +/* Week days mapping */ +const char* WEEK_DAYS[] = { "Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat." }; + +/* Transition properties for the objects */ +const lv_style_prop_t transition_props[] = { + LV_STYLE_OPA, + LV_STYLE_BG_OPA, + LV_STYLE_Y, + LV_STYLE_HEIGHT, + LV_STYLE_PROP_FLAG_NONE +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void app_create(void) +{ + // Init resource and context structure + lv_memzero(&R, sizeof(R)); + lv_memzero(&C, sizeof(C)); + lv_memzero(&CF, sizeof(CF)); + + read_configs(); + +#if WIFI_ENABLED + CF.wifi.conn_delay = 2000000; + wifi_connect(&CF.wifi); +#endif + + C.resource_healthy_check = init_resource(); + + if (!C.resource_healthy_check) { + app_create_error_page(); + return; + } + + app_create_main_page(); + app_set_play_status(PLAY_STATUS_STOP); + app_switch_to_album(0); + app_set_volume(30); + + app_refresh_album_info(); + app_refresh_playlist(); + app_refresh_volume_bar(); + + app_start_updating_date_time(); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int32_t app_get_album_index(album_info_t* album) +{ + for (int i = 0; i < R.album_count; i++) { + if (album == &R.albums[i]) { + return i; + } + } + return -1; +} + +static void app_set_volume(uint16_t volume) +{ + C.volume = volume; + audio_ctl_set_volume(C.audioctl, C.volume); +} + +static void app_set_play_status(play_status_t status) +{ + C.play_status_prev = C.play_status; + C.play_status = status; + app_refresh_play_status(); +} + +static void app_switch_to_album(int index) +{ + if (R.album_count == 0 || index < 0 || index >= R.album_count || C.current_album == &R.albums[index]) + return; + + C.current_album = &R.albums[index]; + app_refresh_album_info(); + app_refresh_playlist(); + app_set_playback_time(0); + + if (C.play_status == PLAY_STATUS_STOP) { + return; + } + + app_set_play_status(PLAY_STATUS_STOP); + app_set_play_status(PLAY_STATUS_PLAY); +} + +static void app_set_playback_time(uint32_t current_time) +{ + C.current_time = current_time; + + audio_ctl_seek(C.audioctl, C.current_time / 1000); + app_refresh_playback_progress(); +} + +static void app_refresh_date_time(void) +{ + time_t now = time(NULL); + struct tm* timeinfo = localtime(&now); + + char date_str[20]; + strftime(date_str, sizeof(date_str), "%Y.%m.%d", timeinfo); + lv_snprintf(date_str + 10, sizeof(date_str), " %s", WEEK_DAYS[timeinfo->tm_wday]); + lv_label_set_text(R.ui.date, date_str); + + char time_str[9]; + strftime(time_str, sizeof(time_str), "%H:%M", timeinfo); + lv_label_set_text(R.ui.time, time_str); +} + +static void app_refresh_volume_bar(void) +{ + int32_t volume_bar_indic_height = C.volume; + + lv_obj_set_height(R.ui.volume_bar_indic, volume_bar_indic_height); + + lv_obj_refr_size(R.ui.volume_bar_indic); + lv_obj_update_layout(R.ui.volume_bar_indic); + + if (C.volume > 0) { + lv_image_set_src(R.ui.audio, R.images.audio); + } else { + lv_image_set_src(R.ui.audio, R.images.mute); + } +} + +static void app_refresh_album_info(void) +{ + if (C.current_album) { + if (access(C.current_album->cover, F_OK) == 0) + lv_image_set_src(R.ui.album_cover, C.current_album->cover); + else + lv_image_set_src(R.ui.album_cover, R.images.nocover); + lv_label_set_text(R.ui.album_name, C.current_album->name); + lv_label_set_text(R.ui.album_artist, C.current_album->artist); + } +} + +static void app_refresh_play_status(void) +{ + if (C.timers.playback_progress_update == NULL) { + C.timers.playback_progress_update = lv_timer_create(app_playback_progress_update_timer_cb, 1000, NULL); + } + + switch (C.play_status) { + case PLAY_STATUS_STOP: + lv_image_set_src(R.ui.play_btn, R.images.play); + lv_timer_pause(C.timers.playback_progress_update); + if (C.audioctl) { + audio_ctl_stop(C.audioctl); + audio_ctl_uninit_nxaudio(C.audioctl); + C.audioctl = NULL; + } + break; + case PLAY_STATUS_PLAY: + lv_image_set_src(R.ui.play_btn, R.images.pause); + lv_timer_resume(C.timers.playback_progress_update); + if (C.play_status_prev == PLAY_STATUS_PAUSE) + audio_ctl_resume(C.audioctl); + else if (C.play_status_prev == PLAY_STATUS_STOP) { + C.audioctl = audio_ctl_init_nxaudio(C.current_album->path); + audio_ctl_start(C.audioctl); + } + break; + case PLAY_STATUS_PAUSE: + lv_image_set_src(R.ui.play_btn, R.images.play); + lv_timer_pause(C.timers.playback_progress_update); + audio_ctl_pause(C.audioctl); + break; + default: + break; + } +} + +static void app_refresh_playback_progress(void) +{ + uint64_t total_time = C.current_album->total_time; + + if (C.current_time > total_time) { + app_set_play_status(PLAY_STATUS_STOP); + C.current_time = 0; + return; + } + + lv_bar_set_range(R.ui.playback_progress, 0, (int32_t)total_time); + lv_bar_set_value(R.ui.playback_progress, (int32_t)C.current_time, LV_ANIM_ON); + + char buff[256]; + + uint32_t current_time_min = C.current_time / 60000; + uint32_t current_time_sec = (C.current_time % 60000) / 1000; + uint32_t total_time_min = total_time / 60000; + uint32_t total_time_sec = (total_time % 60000) / 1000; + + lv_snprintf(buff, sizeof(buff), "%02d:%02d", current_time_min, current_time_sec); + lv_span_set_text(R.ui.playback_current_time, buff); + lv_snprintf(buff, sizeof(buff), "%02d:%02d", total_time_min, total_time_sec); + lv_span_set_text(R.ui.playback_total_time, buff); +} + +static void app_refresh_playlist(void) +{ + lv_obj_clean(R.ui.playlist); + for (int i = 0; i < R.album_count; i++) { + // LIST ITEM + lv_obj_t* list_item = lv_obj_create(R.ui.playlist); + lv_obj_remove_style_all(list_item); + lv_obj_set_size(list_item, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_margin_all(list_item, 20, LV_PART_MAIN); + lv_obj_set_flex_flow(list_item, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(list_item, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // ICON + if (C.current_album == &R.albums[i]) { + lv_obj_t* icon = lv_image_create(list_item); + lv_image_set_src(icon, R.images.music); + lv_obj_set_style_bg_opa(icon, LV_OPA_TRANSP, LV_PART_MAIN); + lv_obj_set_style_radius(icon, 16, LV_PART_MAIN); + lv_obj_set_style_margin_right(icon, 12, LV_PART_MAIN); + lv_obj_align(icon, LV_ALIGN_TOP_LEFT, 10, 10); + + C.current_album_related_obj = list_item; + } + + // ALBUM NAME + lv_obj_t* album_info_spangroup = lv_spangroup_create(list_item); + lv_obj_set_size(album_info_spangroup, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_add_flag(album_info_spangroup, LV_OBJ_FLAG_EVENT_BUBBLE); + lv_spangroup_set_overflow(album_info_spangroup, LV_SPAN_OVERFLOW_ELLIPSIS); + + lv_span_t* album_name = lv_spangroup_new_span(album_info_spangroup); + lv_span_set_text(album_name, R.albums[i].name); + lv_obj_set_style_text_font(album_info_spangroup, R.fonts.size_24.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(album_info_spangroup, lv_color_white(), LV_PART_MAIN); + + // ALBUM ARTIST DOT + lv_span_t* album_artist_dot = lv_spangroup_new_span(album_info_spangroup); + lv_span_set_text(album_artist_dot, "·"); + lv_style_set_text_color(&album_artist_dot->style, lv_color_hex(0x878787)); + + // ALBUM ARTIST + lv_span_t* album_artist = lv_spangroup_new_span(album_info_spangroup); + lv_span_set_text(album_artist, R.albums[i].artist); + lv_style_set_text_color(&album_artist->style, lv_color_hex(0x878787)); + + // EVENTS + lv_obj_add_event_cb(list_item, app_playlist_btn_event_handler, LV_EVENT_CLICKED, &R.albums[i]); + } + + if (C.current_album_related_obj) + lv_obj_scroll_to_view(C.current_album_related_obj, LV_ANIM_ON); +} + +static void app_volume_bar_countdown_timer_cb(lv_timer_t* timer) +{ + LV_UNUSED(timer); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_DEFAULT, true); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_USER_1, false); +} + +static void app_playback_progress_update_timer_cb(lv_timer_t* timer) +{ + LV_UNUSED(timer); + + C.current_time = audio_ctl_get_position(C.audioctl) * 1000; + app_refresh_playback_progress(); +} + +static void app_refresh_date_time_timer_cb(lv_timer_t* timer) +{ + LV_UNUSED(timer); + + app_refresh_date_time(); +} + +static void app_refresh_volume_countdown_timer(void) +{ + if (C.timers.volume_bar_countdown) { + lv_timer_set_repeat_count(C.timers.volume_bar_countdown, 1); + lv_timer_reset(C.timers.volume_bar_countdown); + lv_timer_resume(C.timers.volume_bar_countdown); + } else { + C.timers.volume_bar_countdown = lv_timer_create(app_volume_bar_countdown_timer_cb, 3000, NULL); + lv_timer_set_auto_delete(C.timers.volume_bar_countdown, false); + } +} + +static void app_playlist_event_handler(lv_event_t* e) +{ + LV_UNUSED(e); + + lv_obj_t* top_layer = lv_layer_top(); + + int32_t screen_height = lv_obj_get_height(lv_screen_active()); + + if (lv_obj_has_state(R.ui.playlist_base, LV_STATE_USER_1)) { + lv_obj_set_style_y(R.ui.playlist_base, screen_height, LV_STATE_DEFAULT); + lv_obj_set_state(R.ui.playlist_base, LV_STATE_DEFAULT, true); + lv_obj_set_state(R.ui.playlist_base, LV_STATE_USER_1, false); + lv_obj_set_state(top_layer, LV_STATE_DEFAULT, true); + lv_obj_set_state(top_layer, LV_STATE_USER_1, false); + } else { + lv_obj_set_state(R.ui.playlist_base, LV_STATE_DEFAULT, false); + lv_obj_set_state(R.ui.playlist_base, LV_STATE_USER_1, true); + lv_obj_set_state(top_layer, LV_STATE_DEFAULT, false); + lv_obj_set_state(top_layer, LV_STATE_USER_1, true); + } +} + +static void app_volume_bar_event_handler(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + + if (!(code == LV_EVENT_PRESSED || code == LV_EVENT_PRESSING || code == LV_EVENT_PRESS_LOST)) { + return; + } + + lv_point_t point; + lv_indev_t* indev = lv_indev_active(); + lv_indev_get_vect(indev, &point); + + int32_t volume_bar_height = lv_obj_get_height(R.ui.volume_bar); + int32_t volume_bar_indic_height = lv_obj_get_height(R.ui.volume_bar_indic); + + if (volume_bar_indic_height < 0) { + volume_bar_indic_height = 0; + } else if (volume_bar_indic_height > volume_bar_height) { + volume_bar_indic_height = volume_bar_height; + } + + int32_t volume = volume_bar_indic_height - point.y; + if (volume < 0) + volume = 0; + + app_set_volume(volume); + + app_refresh_volume_bar(); + app_refresh_volume_countdown_timer(); +} + +static void app_audio_event_handler(lv_event_t* e) +{ + LV_UNUSED(e); + + if (lv_obj_has_state(R.ui.volume_bar, LV_STATE_USER_1)) { + lv_obj_set_state(R.ui.volume_bar, LV_STATE_DEFAULT, true); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_USER_1, false); + } else { + lv_obj_set_state(R.ui.volume_bar, LV_STATE_DEFAULT, false); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_USER_1, true); + app_refresh_volume_countdown_timer(); + } +} + +static void app_playlist_btn_event_handler(lv_event_t* e) +{ + album_info_t* album_info = (album_info_t*)lv_event_get_user_data(e); + + int32_t index = app_get_album_index(album_info); + if (index >= 0) { + app_switch_to_album(index); + app_playlist_event_handler(NULL); + } +} + +static void app_switch_album_event_handler(lv_event_t* e) +{ + switch_album_mode_t direction = (switch_album_mode_t)(lv_uintptr_t)lv_event_get_user_data(e); + + int32_t album_index = app_get_album_index(C.current_album); + if (album_index < 0) { + return; + } + + switch (direction) { + case SWITCH_ALBUM_MODE_PREV: + album_index--; + break; + case SWITCH_ALBUM_MODE_NEXT: + album_index++; + break; + default: + break; + } + + album_index = (album_index + R.album_count) % R.album_count; + + app_switch_to_album(album_index); +} + +static void app_play_status_event_handler(lv_event_t* e) +{ + LV_UNUSED(e); + + switch (C.play_status) { + case PLAY_STATUS_STOP: + app_set_play_status(PLAY_STATUS_PLAY); + break; + case PLAY_STATUS_PLAY: + app_set_play_status(PLAY_STATUS_PAUSE); + break; + case PLAY_STATUS_PAUSE: + app_set_play_status(PLAY_STATUS_PLAY); + break; + default: + break; + } +} + +static void app_playback_progress_bar_event_handler(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + + switch (code) { + case LV_EVENT_LONG_PRESSED: + lv_obj_set_height(R.ui.playback_progress, 8); + lv_obj_set_style_margin_ver(R.ui.playback_progress, 0, LV_PART_MAIN); + lv_obj_set_state(R.ui.playback_progress, LV_STATE_CHECKED, true); + break; + case LV_EVENT_PRESS_LOST: + case LV_EVENT_RELEASED: + lv_obj_set_height(R.ui.playback_progress, 4); + lv_obj_set_style_margin_ver(R.ui.playback_progress, 2, LV_PART_MAIN); + lv_obj_set_state(R.ui.playback_progress, LV_STATE_CHECKED, false); + break; + case LV_EVENT_PRESSING: { + if (lv_obj_has_state(R.ui.playback_progress, LV_STATE_CHECKED)) { + lv_point_t point; + lv_point_t vec; + lv_indev_t* indev = lv_indev_active(); + lv_indev_get_point(indev, &point); + lv_indev_get_vect(indev, &vec); + + if (point.y <= 0) { + return; + } + + int32_t screen_height = lv_obj_get_height(lv_screen_active()); + int32_t screen_width = lv_obj_get_width(lv_screen_active()); + int32_t level_height = screen_height / 10; + int32_t level = point.y / level_height + 1; + + uint64_t total_time = C.current_album ? C.current_album->total_time : 0; + + C.current_time += vec.x * level * (int32_t)total_time / screen_width / 10; + app_set_playback_time(C.current_time); + } + break; + } + default: + break; + } +} + +static bool init_resource(void) +{ + // Fonts + R.fonts.size_16.normal = lv_freetype_font_create(FONTS_ROOT "/MiSans-Normal.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 16, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_22.bold = lv_freetype_font_create(FONTS_ROOT "/MiSans-Semibold.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 22, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_24.normal = lv_freetype_font_create(FONTS_ROOT "/MiSans-Normal.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_28.normal = lv_freetype_font_create(FONTS_ROOT "/MiSans-Semibold.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 38, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_60.bold = lv_freetype_font_create(FONTS_ROOT "/MiSans-Semibold.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 60, LV_FREETYPE_FONT_STYLE_NORMAL); + + if (R.fonts.size_16.normal == NULL || + R.fonts.size_22.bold == NULL || + R.fonts.size_24.normal == NULL || + R.fonts.size_28.normal == NULL || + R.fonts.size_60.bold == NULL ) { + return false; + } + + // Styles + lv_style_init(&R.styles.button_default); + lv_style_init(&R.styles.button_pressed); + lv_style_set_opa(&R.styles.button_default, LV_OPA_COVER); + lv_style_set_opa(&R.styles.button_pressed, LV_OPA_70); + + // transition animation + lv_style_transition_dsc_init(&R.styles.transition_dsc, transition_props, &lv_anim_path_ease_in_out, 300, 0, NULL); + lv_style_transition_dsc_init(&R.styles.button_transition_dsc, transition_props, &lv_anim_path_ease_in_out, 80, 0, NULL); + lv_style_set_transition(&R.styles.button_default, &R.styles.button_transition_dsc); + lv_style_set_transition(&R.styles.button_pressed, &R.styles.button_transition_dsc); + + // images + R.images.playlist = ICONS_ROOT "/playlist.png"; + R.images.previous = ICONS_ROOT "/previous.png"; + R.images.play = ICONS_ROOT "/play.png"; + R.images.pause = ICONS_ROOT "/pause.png"; + R.images.next = ICONS_ROOT "/next.png"; + R.images.audio = ICONS_ROOT "/audio.png"; + R.images.mute = ICONS_ROOT "/mute.png"; + R.images.music = ICONS_ROOT "/music.png"; + R.images.nocover = ICONS_ROOT "/nocover.png"; + + // albums + reload_music_config(); + + return true; +} + +static void app_create_top_layer(void) +{ + lv_obj_t* top_layer = lv_layer_top(); + lv_obj_set_scroll_dir(top_layer, LV_DIR_NONE); + lv_obj_set_style_bg_color(top_layer, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_bg_opa(top_layer, LV_OPA_COVER, LV_STATE_USER_1); + lv_obj_set_style_bg_opa(top_layer, LV_OPA_0, LV_STATE_DEFAULT); + lv_obj_set_style_transition(top_layer, &R.styles.transition_dsc, LV_STATE_DEFAULT); + lv_obj_set_style_transition(top_layer, &R.styles.transition_dsc, LV_STATE_USER_1); + + // VOLUME BAR + R.ui.volume_bar = lv_obj_create(top_layer); + lv_obj_remove_style_all(R.ui.volume_bar); + lv_obj_set_size(R.ui.volume_bar, 60, 180); + lv_obj_set_style_bg_color(R.ui.volume_bar, lv_color_hex(0x444444), LV_PART_MAIN); + lv_obj_set_style_bg_opa(R.ui.volume_bar, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_opa(R.ui.volume_bar, LV_OPA_0, LV_STATE_DEFAULT); + lv_obj_set_style_opa(R.ui.volume_bar, LV_OPA_COVER, LV_STATE_USER_1); + lv_obj_set_style_border_width(R.ui.volume_bar, 0, LV_PART_MAIN); + lv_obj_set_style_radius(R.ui.volume_bar, 16, LV_PART_MAIN); + lv_obj_set_style_clip_corner(R.ui.volume_bar, true, LV_PART_MAIN); + lv_obj_align(R.ui.volume_bar, LV_ALIGN_BOTTOM_RIGHT, -45, -95); + lv_obj_set_style_transition(R.ui.volume_bar, &R.styles.transition_dsc, LV_STATE_DEFAULT); + + R.ui.volume_bar_indic = lv_obj_create(R.ui.volume_bar); + lv_obj_remove_style_all(R.ui.volume_bar_indic); + lv_obj_set_style_bg_color(R.ui.volume_bar_indic, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_bg_opa(R.ui.volume_bar_indic, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_size(R.ui.volume_bar_indic, LV_PCT(100), 40); + lv_obj_align(R.ui.volume_bar_indic, LV_ALIGN_BOTTOM_MID, 0, 0); + + // PLAYLIST GROUP + R.ui.playlist_base = lv_obj_create(top_layer); + lv_obj_remove_style_all(R.ui.playlist_base); + lv_obj_set_size(R.ui.playlist_base, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_y(R.ui.playlist_base, 480, LV_STATE_DEFAULT); + lv_obj_set_style_y(R.ui.playlist_base, 0, LV_STATE_USER_1); + lv_obj_set_flex_flow(R.ui.playlist_base, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_top(R.ui.playlist_base, 60, LV_PART_MAIN); + lv_obj_set_style_pad_left(R.ui.playlist_base, 10, LV_PART_MAIN); + lv_obj_set_style_pad_right(R.ui.playlist_base, 10, LV_PART_MAIN); + lv_obj_set_style_pad_bottom(R.ui.playlist_base, 10, LV_PART_MAIN); + lv_obj_set_flex_align(R.ui.playlist_base, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t* playlist_group = lv_obj_create(R.ui.playlist_base); + lv_obj_remove_style_all(playlist_group); + lv_obj_set_style_bg_color(playlist_group, lv_color_hex(0x1E1E20), LV_PART_MAIN); + lv_obj_set_style_bg_opa(playlist_group, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_size(playlist_group, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_radius(playlist_group, 16, LV_PART_MAIN); + lv_obj_set_style_clip_corner(playlist_group, true, LV_PART_MAIN); + lv_obj_set_flex_flow(playlist_group, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(playlist_group, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // TITLE + lv_obj_t* title = lv_label_create(playlist_group); + lv_label_set_text(title, "PLAYLIST"); + lv_obj_set_style_text_font(title, R.fonts.size_28.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(title, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_margin_all(title, 15, LV_PART_MAIN); + + // LIST + lv_obj_t* list = lv_obj_create(playlist_group); + R.ui.playlist = list; + lv_obj_set_size(list, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_border_width(list, 0, LV_PART_MAIN); + lv_obj_set_style_bg_color(list, lv_color_hex(0x1E1E20), LV_PART_MAIN); + lv_obj_set_style_bg_opa(list, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_radius(list, 0, LV_PART_MAIN); + lv_obj_set_flex_grow(list, 1); + lv_obj_set_flex_flow(list, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(list, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // EVENTS + lv_obj_add_event_cb(R.ui.playlist_base, app_playlist_event_handler, LV_EVENT_CLICKED, NULL); + lv_obj_set_style_transition(R.ui.playlist_base, &R.styles.transition_dsc, LV_STATE_DEFAULT); + lv_obj_set_style_transition(R.ui.playlist_base, &R.styles.transition_dsc, LV_STATE_USER_1); + + lv_obj_add_flag(R.ui.volume_bar_indic, LV_OBJ_FLAG_EVENT_BUBBLE); + lv_obj_add_event_cb(R.ui.volume_bar, app_volume_bar_event_handler, LV_EVENT_ALL, NULL); +} + +static void app_create_error_page(void) +{ + lv_obj_t* root = lv_screen_active(); + lv_obj_t* label = lv_label_create(root); + lv_obj_set_width(label, LV_PCT(80)); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + lv_label_set_text(label, "Resource loading failed. \nPlease check the device and \nread the document for more details."); + lv_obj_set_style_text_font(label, &lv_font_montserrat_32, LV_PART_MAIN); + lv_obj_center(label); +} + +static void app_create_main_page(void) +{ + lv_obj_t* root = lv_screen_active(); + + lv_obj_set_style_bg_color(root, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(root, 0, LV_PART_MAIN); + lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(root, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(root, 20, LV_PART_MAIN); + + // TIME GROUP + lv_obj_t* time_group = lv_obj_create(root); + lv_obj_set_size(time_group, LV_PCT(100), LV_PCT(50)); + lv_obj_set_style_bg_color(time_group, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(time_group, 0, LV_PART_MAIN); + lv_obj_set_style_radius(time_group, 0, LV_PART_MAIN); + lv_obj_set_flex_grow(time_group, 1); + lv_obj_set_flex_flow(time_group, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(time_group, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // TIME + lv_obj_t* time = lv_label_create(time_group); + R.ui.time = time; + lv_label_set_text(time, "13:14"); + lv_obj_set_style_text_font(time, R.fonts.size_60.bold, LV_PART_MAIN); + lv_obj_set_style_text_color(time, lv_color_white(), LV_PART_MAIN); + + // DATE + lv_obj_t* date = lv_label_create(time_group); + R.ui.date = date; + lv_label_set_text(date, "2024.03.22 Fri."); + lv_obj_set_style_text_font(date, R.fonts.size_24.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(date, lv_color_hex(0x878787), LV_PART_MAIN); + + // PLAYER GROUP + lv_obj_t* player_group = lv_obj_create(root); + R.ui.player_group = player_group; + lv_obj_set_size(player_group, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_bg_color(player_group, lv_color_hex(0x1E1E20), LV_PART_MAIN); + lv_obj_set_style_border_width(player_group, 0, LV_PART_MAIN); + lv_obj_set_style_radius(player_group, 16, LV_PART_MAIN); + lv_obj_set_style_pad_all(player_group, 20, LV_PART_MAIN); + lv_obj_set_flex_flow(player_group, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(player_group, LV_FLEX_ALIGN_SPACE_AROUND, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // ALBUM GROUP + lv_obj_t* album_group = lv_obj_create(player_group); + lv_obj_remove_style_all(album_group); + lv_obj_set_size(album_group, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_flex_flow(album_group, LV_FLEX_FLOW_ROW, LV_PART_MAIN); + lv_obj_set_flex_align(album_group, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // ALBUM PICTURE + lv_obj_t* album_cover = lv_obj_create(album_group); + lv_obj_t* album_cover_img = lv_image_create(album_cover); + R.ui.album_cover = album_cover_img; + lv_obj_remove_style_all(album_cover); + lv_obj_set_size(album_cover, 80, 80); + lv_obj_set_size(album_cover_img, 80, 80); + lv_obj_set_style_radius(album_cover, 12, LV_PART_MAIN); + lv_obj_set_style_radius(album_cover_img, 12, LV_PART_MAIN); + lv_obj_set_style_clip_corner(album_cover, true, LV_PART_MAIN); + lv_obj_set_style_clip_corner(album_cover_img, true, LV_PART_MAIN); + lv_image_set_align(album_cover_img, LV_IMAGE_ALIGN_STRETCH); + lv_image_set_src(album_cover_img, R.images.nocover); + + // ALBUM INFO + lv_obj_t* album_info = lv_obj_create(album_group); + lv_obj_remove_style_all(album_info); + lv_obj_remove_flag(album_info, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_size(album_info, LV_SIZE_CONTENT, 80); + lv_obj_set_style_pad_left(album_info, 20, LV_PART_MAIN); + lv_obj_set_flex_grow(album_info, 1); + lv_obj_set_style_flex_flow(album_info, LV_FLEX_FLOW_COLUMN, LV_PART_MAIN); + lv_obj_set_flex_align(album_info, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + + // ALBUM NAME + lv_obj_t* album_name = lv_label_create(album_info); + R.ui.album_name = album_name; + lv_label_set_long_mode(album_name, LV_LABEL_LONG_SCROLL); + lv_obj_set_width(album_name, LV_PCT(100)); + lv_obj_set_style_text_align(album_name, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN); + lv_obj_set_style_text_font(album_name, R.fonts.size_22.bold, LV_PART_MAIN); + lv_obj_set_style_text_color(album_name, lv_color_white(), LV_PART_MAIN); + lv_label_set_text(album_name, "No Album"); + + // ALBUM ARTIST + lv_obj_t* album_artist = lv_label_create(album_info); + R.ui.album_artist = album_artist; + lv_label_set_long_mode(album_name, LV_LABEL_LONG_SCROLL); + lv_obj_set_width(album_artist, LV_PCT(100)); + lv_obj_set_style_text_align(album_artist, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN); + lv_obj_set_style_text_font(album_artist, R.fonts.size_22.bold, LV_PART_MAIN); + lv_obj_set_style_text_color(album_artist, lv_color_hex3(0x666), LV_PART_MAIN); + lv_label_set_text(album_artist, "No Artist"); + + // PROGRESS BAR GROUP + lv_obj_t* progress_group = lv_obj_create(player_group); + R.ui.playback_group = progress_group; + lv_obj_remove_style_all(progress_group); + lv_obj_set_size(progress_group, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_margin_top(progress_group, -16, LV_PART_MAIN); + lv_obj_set_style_flex_flow(progress_group, LV_FLEX_FLOW_COLUMN, LV_PART_MAIN); + lv_obj_set_flex_align(progress_group, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER); + + lv_obj_t* progress_time_spangroup = lv_spangroup_create(progress_group); + lv_span_t* current_time_span = lv_spangroup_new_span(progress_time_spangroup); + lv_span_t* slash_span = lv_spangroup_new_span(progress_time_spangroup); + lv_span_t* total_time_span = lv_spangroup_new_span(progress_time_spangroup); + R.ui.playback_current_time = current_time_span; + R.ui.playback_total_time = total_time_span; + lv_span_set_text(current_time_span, "00:00"); + lv_span_set_text(slash_span, "/"); + lv_span_set_text(total_time_span, "00:00"); + lv_obj_set_style_text_font(progress_time_spangroup, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(progress_time_spangroup, lv_color_white(), LV_PART_MAIN); + lv_style_set_text_color(&slash_span->style, lv_color_hex(0x666666)); + lv_style_set_text_color(&total_time_span->style, lv_color_hex(0x666666)); + + lv_obj_t* progress_bar = lv_bar_create(progress_group); + R.ui.playback_progress = progress_bar; + lv_obj_set_size(progress_bar, LV_PCT(100), 4); + lv_obj_add_flag(progress_bar, LV_OBJ_FLAG_EVENT_BUBBLE); + lv_obj_set_style_margin_ver(progress_bar, 2, LV_PART_MAIN); + lv_obj_set_style_bg_color(progress_bar, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_bg_color(progress_bar, lv_color_hex(0x3A3A3C), LV_PART_MAIN); + lv_obj_set_style_bg_opa(progress_bar, LV_OPA_COVER, LV_PART_MAIN); + + // CONTROL GROUP + lv_obj_t* control_group = lv_obj_create(player_group); + lv_obj_remove_style_all(control_group); + lv_obj_set_size(control_group, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_flex_flow(control_group, LV_FLEX_FLOW_ROW, LV_PART_MAIN); + lv_obj_set_flex_align(control_group, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // PLAYLIST + lv_obj_t* playlist = lv_button_create(control_group); + lv_obj_t* playlist_image = lv_image_create(playlist); + lv_obj_remove_style_all(playlist); + lv_image_set_src(playlist_image, R.images.playlist); + lv_obj_set_size(playlist_image, 66, 66); + lv_obj_add_style(playlist, &R.styles.button_default, LV_STATE_DEFAULT); + lv_obj_add_style(playlist, &R.styles.button_pressed, LV_STATE_PRESSED); + + // PREVIOUS + lv_obj_t* previous = lv_button_create(control_group); + lv_obj_t* previous_image = lv_image_create(previous); + lv_obj_remove_style_all(previous); + lv_image_set_src(previous_image, R.images.previous); + lv_obj_set_size(previous_image, 66, 66); + lv_obj_add_style(previous, &R.styles.button_default, LV_STATE_DEFAULT); + lv_obj_add_style(previous, &R.styles.button_pressed, LV_STATE_PRESSED); + + // PLAY/PAUSE + lv_obj_t* play_pause = lv_button_create(control_group); + lv_obj_t* play_pause_image = lv_image_create(play_pause); + R.ui.play_btn = play_pause_image; + lv_obj_remove_style_all(play_pause); + lv_image_set_src(play_pause_image, R.images.play); + lv_obj_set_size(play_pause_image, 66, 66); + lv_obj_add_style(play_pause, &R.styles.button_default, LV_STATE_DEFAULT); + lv_obj_add_style(play_pause, &R.styles.button_pressed, LV_STATE_PRESSED); + + // NEXT + lv_obj_t* next = lv_button_create(control_group); + lv_obj_t* next_image = lv_image_create(next); + lv_obj_remove_style_all(next); + lv_image_set_src(next_image, R.images.next); + lv_obj_set_size(next_image, 66, 66); + lv_obj_add_style(next, &R.styles.button_default, LV_STATE_DEFAULT); + lv_obj_add_style(next, &R.styles.button_pressed, LV_STATE_PRESSED); + + // AUDIO + lv_obj_t* audio = lv_button_create(control_group); + lv_obj_t* audio_image = lv_image_create(audio); + R.ui.audio = audio_image; + lv_obj_remove_style_all(audio); + lv_obj_set_size(audio_image, 66, 66); + lv_obj_add_style(audio, &R.styles.button_default, LV_STATE_DEFAULT); + lv_obj_add_style(audio, &R.styles.button_pressed, LV_STATE_PRESSED); + + app_create_top_layer(); + + lv_obj_add_event_cb(playlist, app_playlist_event_handler, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(audio, app_audio_event_handler, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(play_pause, app_play_status_event_handler, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(previous, app_switch_album_event_handler, LV_EVENT_CLICKED, (lv_uintptr_t*)SWITCH_ALBUM_MODE_PREV); + lv_obj_add_event_cb(next, app_switch_album_event_handler, LV_EVENT_CLICKED, (lv_uintptr_t*)SWITCH_ALBUM_MODE_NEXT); + lv_obj_add_event_cb(progress_group, app_playback_progress_bar_event_handler, LV_EVENT_ALL, NULL); +} + +static void app_start_updating_date_time(void) +{ + lv_timer_t* timer = lv_timer_create(app_refresh_date_time_timer_cb, 1000, NULL); + lv_timer_ready(timer); +} + +static void read_configs(void) +{ + uint32_t file_size; + lv_fs_file_t file; + lv_fs_open(&file, RES_ROOT "/config.json", LV_FS_MODE_RD); + + lv_fs_seek(&file, 0, LV_FS_SEEK_END); + lv_fs_tell(&file, &file_size); + lv_fs_seek(&file, 0, LV_FS_SEEK_SET); + + char* buff = lv_malloc(file_size); + lv_fs_read(&file, buff, file_size, NULL); + + const char* json_string = buff; + + cJSON* json = cJSON_Parse(json_string); + if (json == NULL) { + const char* error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) { + LV_LOG_ERROR("parse error: %p", error_ptr); + } + lv_free(buff); + return; + } + +#if WIFI_ENABLED + cJSON* wifi_object = cJSON_GetObjectItem(json, "wifi"); + + const char* ssid = cJSON_GetStringValue(cJSON_GetObjectItem(wifi_object, "ssid")); + const char* pswd = cJSON_GetStringValue(cJSON_GetObjectItem(wifi_object, "pswd")); + const int version = cJSON_GetNumberValue(cJSON_GetObjectItem(wifi_object, "wpa_ver")); + + lv_strcpy(CF.wifi.ssid, ssid); + lv_strcpy(CF.wifi.pswd, pswd); + CF.wifi.ver_flag = version; +#endif + + cJSON_Delete(json); + + lv_free(buff); +} + +static void reload_music_config(void) +{ + + /* Clear previous music config */ + + for (int i = 0; i < R.album_count; i++) { + lv_free((void*)R.albums[i].name); + lv_free((void*)R.albums[i].artist); + } + + lv_free(R.albums); + R.album_count = 0; + + /* Load music config */ + uint32_t file_size; + lv_fs_file_t file; + lv_fs_open(&file, MUSICS_ROOT "/manifest.json", LV_FS_MODE_RD); + + lv_fs_seek(&file, 0, LV_FS_SEEK_END); + lv_fs_tell(&file, &file_size); + lv_fs_seek(&file, 0, LV_FS_SEEK_SET); + + char* buff = lv_malloc(file_size); + lv_fs_read(&file, buff, file_size, NULL); + + const char* json_string = buff; + + cJSON* json = cJSON_Parse(json_string); + if (json == NULL) { + const char* error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) { + LV_LOG_ERROR("parse error: %p", error_ptr); + } + lv_free(buff); + return; + } + + cJSON* musics_object = cJSON_GetObjectItem(json, "musics"); + + if (musics_object == NULL) { + lv_free(buff); + return; + } + + R.album_count = cJSON_GetArraySize(musics_object); + R.albums = lv_malloc_zeroed(R.album_count * sizeof(album_info_t)); + + for (int i = 0; i < R.album_count; i++) { + cJSON* music_object = cJSON_GetArrayItem(musics_object, i); + + const char* path = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "path")); + const char* name = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "name")); + const char* artist = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "artist")); + const char* cover = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "cover")); + const double total_time_double = cJSON_GetNumberValue(cJSON_GetObjectItem(music_object, "total_time")); + const char* color_str = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "color")); + + uint64_t total_time = (uint64_t)total_time_double; + uint32_t color_int = strtoul(color_str + 1, NULL, 16); + + if (total_time == 0) + total_time = 1; + + lv_color_t color = lv_color_hex(color_int); + + lv_snprintf(R.albums[i].path, sizeof(R.albums[i].path), "%s/%s", MUSICS_ROOT, path); + lv_snprintf(R.albums[i].cover, sizeof(R.albums[i].cover), "%s/%s", MUSICS_ROOT, cover); + R.albums[i].name = lv_strdup(name); + R.albums[i].artist = lv_strdup(artist); + R.albums[i].total_time = total_time; + R.albums[i].color = color; + + LV_LOG_USER("Album %d: %s - %s | %s %s %llu", i, R.albums[i].name, R.albums[i].artist, R.albums[i].path, R.albums[i].cover, total_time); + } + + cJSON_Delete(json); + + lv_free(buff); +} diff --git a/music_player/music_player.h b/music_player/music_player.h new file mode 100644 index 0000000000000000000000000000000000000000..dccd1ce0ac3b696dfd74636ac346b5de9e9cd324 --- /dev/null +++ b/music_player/music_player.h @@ -0,0 +1,131 @@ +// +// Created by BenignX on 2024/3/21. +// + +#ifndef LVGL_APP_H +#define LVGL_APP_H + +#include "audio_ctl.h" +#include "lvgl.h" +#include "wifi.h" + +#define RES_ROOT CONFIG_LVX_MUSIC_PLAYER_DATA_ROOT "/res" +#define FONTS_ROOT RES_ROOT "/fonts" +#define ICONS_ROOT RES_ROOT "/icons" +#define MUSICS_ROOT RES_ROOT "/musics" + +typedef struct _album_info_t { + const char* name; + const char* artist; + char path[LV_FS_MAX_PATH_LENGTH]; + char cover[LV_FS_MAX_PATH_LENGTH]; + uint64_t total_time; /**< in milliseconds */ + lv_color_t color; +} album_info_t; + +typedef enum _switch_album_mode_t { + SWITCH_ALBUM_MODE_PREV, + SWITCH_ALBUM_MODE_NEXT, +} switch_album_mode_t; + +typedef enum _play_status_t { + PLAY_STATUS_STOP, + PLAY_STATUS_PLAY, + PLAY_STATUS_PAUSE, +} play_status_t; + +struct resource_s { + struct { + lv_obj_t* time; + lv_obj_t* date; + + lv_obj_t* player_group; + + lv_obj_t* volume_bar; + lv_obj_t* volume_bar_indic; + lv_obj_t* audio; + lv_obj_t* playlist_base; + + lv_obj_t* album_cover; + lv_obj_t* album_name; + lv_obj_t* album_artist; + + lv_obj_t* play_btn; + lv_obj_t* playback_group; + lv_obj_t* playback_progress; + lv_span_t* playback_current_time; + lv_span_t* playback_total_time; + + lv_obj_t* playlist; + } ui; + + struct { + struct { + lv_font_t* normal; + } size_16; + struct { + lv_font_t* bold; + } size_22; + struct { + lv_font_t* normal; + } size_24; + struct { + lv_font_t* normal; + } size_28; + struct { + lv_font_t* bold; + } size_60; + } fonts; + + struct { + lv_style_t button_default; + lv_style_t button_pressed; + lv_style_transition_dsc_t button_transition_dsc; + lv_style_transition_dsc_t transition_dsc; + } styles; + + struct { + const char* playlist; + const char* previous; + const char* play; + const char* pause; + const char* next; + const char* audio; + const char* mute; + const char* music; + const char* nocover; + } images; + + album_info_t* albums; + uint8_t album_count; +}; + +struct ctx_s { + bool resource_healthy_check; + + album_info_t* current_album; + lv_obj_t* current_album_related_obj; + + uint16_t volume; + + play_status_t play_status_prev; + play_status_t play_status; + uint64_t current_time; + + struct { + lv_timer_t* volume_bar_countdown; + lv_timer_t* playback_progress_update; + } timers; + + audioctl_s* audioctl; +}; + +struct conf_s { +#if WIFI_ENABLED + wifi_conf_t wifi; +#endif +}; + +void app_create(void); + +#endif // LVGL_APP_H diff --git a/music_player/music_player_main.c b/music_player/music_player_main.c new file mode 100644 index 0000000000000000000000000000000000000000..0dce2f5013b3533e14f641a81f5c8ec0b8e7d0fd --- /dev/null +++ b/music_player/music_player_main.c @@ -0,0 +1,63 @@ +// include NuttX headers +#include <nuttx/config.h> +#include <unistd.h> +#include <uv.h> + +// include lvgl headers +#include <lvgl/lvgl.h> + +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +#include "music_player.h" + +int main(int argc, FAR char* argv[]) +{ + // init lvgl + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + app_create(); + + // refresh lvgl ui + lv_nuttx_uv_loop(&ui_loop, &result); + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/music_player/res/.DS_Store b/music_player/res/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e7970ce24cc0c4a9ab1af62185a61ab4320e2240 Binary files /dev/null and b/music_player/res/.DS_Store differ diff --git a/music_player/res/config.json b/music_player/res/config.json new file mode 100644 index 0000000000000000000000000000000000000000..b760c4852d1c9399dd0b15b7ff5f6b0cc7abe6fa --- /dev/null +++ b/music_player/res/config.json @@ -0,0 +1,6 @@ +{ + "wifi": { + "ssid": "BenignX", + "pswd": "19991123" + } +} diff --git a/music_player/res/fonts/MiSans-Normal.ttf b/music_player/res/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/music_player/res/fonts/MiSans-Normal.ttf differ diff --git a/music_player/res/fonts/MiSans-Semibold.ttf b/music_player/res/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/music_player/res/fonts/MiSans-Semibold.ttf differ diff --git a/music_player/res/icons/album_picture.png b/music_player/res/icons/album_picture.png new file mode 100644 index 0000000000000000000000000000000000000000..5495d183881dc06a0ee0bd0358c4a00c0e4a66d2 Binary files /dev/null and b/music_player/res/icons/album_picture.png differ diff --git a/music_player/res/icons/audio.png b/music_player/res/icons/audio.png new file mode 100644 index 0000000000000000000000000000000000000000..1c99091775d008bfba7d4e1e3dd7dad9d47599c3 Binary files /dev/null and b/music_player/res/icons/audio.png differ diff --git a/music_player/res/icons/music.png b/music_player/res/icons/music.png new file mode 100644 index 0000000000000000000000000000000000000000..be4f163e5d2b0cece03f8ef52b081a3ade804b6e Binary files /dev/null and b/music_player/res/icons/music.png differ diff --git a/music_player/res/icons/mute.png b/music_player/res/icons/mute.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d8b3b5cc2af4d6bb5e0976471af674b8759764 Binary files /dev/null and b/music_player/res/icons/mute.png differ diff --git a/music_player/res/icons/next.png b/music_player/res/icons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..1db3575fb8b4ea7547a9e0c958a6cc62274cd0e2 Binary files /dev/null and b/music_player/res/icons/next.png differ diff --git a/music_player/res/icons/nocover.png b/music_player/res/icons/nocover.png new file mode 100644 index 0000000000000000000000000000000000000000..25282616d4119db1a99f94365254f64105da0acc Binary files /dev/null and b/music_player/res/icons/nocover.png differ diff --git a/music_player/res/icons/pause.png b/music_player/res/icons/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..9fcd00cc4b60533e1ad91f3f5c20e538a04a2a72 Binary files /dev/null and b/music_player/res/icons/pause.png differ diff --git a/music_player/res/icons/play.png b/music_player/res/icons/play.png new file mode 100644 index 0000000000000000000000000000000000000000..f8e7bf726e45a94ac3ee44b9df3b7bbc58bed091 Binary files /dev/null and b/music_player/res/icons/play.png differ diff --git a/music_player/res/icons/playlist.png b/music_player/res/icons/playlist.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1b35a42b02d184def2fee67161b667fd31420c Binary files /dev/null and b/music_player/res/icons/playlist.png differ diff --git a/music_player/res/icons/previous.png b/music_player/res/icons/previous.png new file mode 100644 index 0000000000000000000000000000000000000000..e847a824e020585a156a68a6c794e189922939bd Binary files /dev/null and b/music_player/res/icons/previous.png differ diff --git a/music_player/res/musics/UnamedRhythm.png b/music_player/res/musics/UnamedRhythm.png new file mode 100644 index 0000000000000000000000000000000000000000..5a079cb565f96310773d5c5411d2e1ece948ddfc Binary files /dev/null and b/music_player/res/musics/UnamedRhythm.png differ diff --git a/music_player/res/musics/UnamedRhythm.wav b/music_player/res/musics/UnamedRhythm.wav new file mode 100644 index 0000000000000000000000000000000000000000..7292e7f48f41fbec961c5b27b4f6af3676466550 Binary files /dev/null and b/music_player/res/musics/UnamedRhythm.wav differ diff --git a/music_player/res/musics/manifest.json b/music_player/res/musics/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..d101ea068561fb07f2c17f8b4bb21246cf972b0b --- /dev/null +++ b/music_player/res/musics/manifest.json @@ -0,0 +1,12 @@ +{ + "musics": [ + { + "path": "UnamedRhythm.wav", + "name": "UnamedRhythm", + "artist": "Benign X", + "cover": "UnamedRhythm.png", + "total_time": 12000, + "color": "#114514" + } + ] +} diff --git a/music_player/wifi.c b/music_player/wifi.c new file mode 100644 index 0000000000000000000000000000000000000000..295d83262a558bc7a2dfc09adf8b719c8a144161 --- /dev/null +++ b/music_player/wifi.c @@ -0,0 +1,141 @@ +/** + * @file wifi.c + * Provide wifi connection and network configuration functions + */ + +/********************* + * INCLUDES + *********************/ +#include "wifi.h" + +#if WIFI_ENABLED + +#include <debug.h> +#include <time.h> + +#include "netutils/netlib.h" +#include "netutils/ntpclient.h" + +/********************* + * DEFINES + *********************/ + +#define NET_DEVNAME "wlan0" + + /********************** + * TYPEDEFS + **********************/ + +typedef struct { + struct work_s work; + wifi_conf_t conf; +} wifi_work_conf_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +int wifi_conf_set(FAR wifi_conf_t *usr_conf, + FAR struct wpa_wconfig_s *wifi_conf) +{ + if(strlen(usr_conf->ssid) == 0) { + nerr("ERROR: SSID is NULL\n"); + return -EINVAL; + } + + switch(usr_conf->ver_flag) { + case WPA_VER_NONE: + wifi_conf->auth_wpa = IW_AUTH_WPA_VERSION_DISABLED; + wifi_conf->cipher_mode = IW_AUTH_CIPHER_NONE; + wifi_conf->alg = WPA_ALG_NONE; + break; + + case WPA_VER_1: + wifi_conf->auth_wpa = IW_AUTH_WPA_VERSION_WPA; + wifi_conf->cipher_mode = IW_AUTH_CIPHER_TKIP; + wifi_conf->alg = WPA_ALG_TKIP; + break; + + case WPA_VER_2: + wifi_conf->auth_wpa = IW_AUTH_WPA_VERSION_WPA2; + wifi_conf->cipher_mode = IW_AUTH_CIPHER_CCMP; + wifi_conf->alg = WPA_ALG_CCMP; + break; + + default: + nerr("ERROR: unknown WPA version\n"); + return -EINVAL; + } + + wifi_conf->ifname = NET_DEVNAME; + wifi_conf->sta_mode = IW_MODE_INFRA; + wifi_conf->ssid = usr_conf->ssid; + wifi_conf->passphrase = usr_conf->pswd; + wifi_conf->ssidlen = strlen(usr_conf->ssid); + wifi_conf->phraselen = strlen(usr_conf->pswd); + wifi_conf->bssid = NULL; + wifi_conf->freq = 0; + + return 0; +} + +void wifi_connect_worker(FAR void *arg) +{ + FAR wifi_work_conf_t *wifi_conf = arg; + struct wpa_wconfig_s conf; + + if(wifi_conf_set(&wifi_conf->conf, &conf) < 0) { + nerr("ERROR: wifi parameter is wrong\n"); + goto fail; + } + + if(netlib_ifup(NET_DEVNAME) < 0) { + nerr("ERROR: %s up failed\n", NET_DEVNAME); + goto fail; + } + + if(wpa_driver_wext_associate(&conf) < 0) { + nerr("ERROR: associate failed\n"); + goto fail; + } + + if(netlib_obtain_ipv4addr(NET_DEVNAME) < 0) { + nerr("ERROR: network configuration failed\n"); + goto fail; + } + + ntpc_start(); + +fail: + free(wifi_conf); +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void wifi_connect(FAR const wifi_conf_t *conf) +{ + FAR wifi_work_conf_t *wifi_conf = zalloc(sizeof(*wifi_conf)); + if (wifi_conf == NULL) { + nerr("ERROR: zalloc failed\n"); + return; + } + + wifi_conf->conf = *conf; + + work_queue(USRWORK, &wifi_conf->work, wifi_connect_worker, wifi_conf, conf->conn_delay); +} + +#endif diff --git a/music_player/wifi.h b/music_player/wifi.h new file mode 100644 index 0000000000000000000000000000000000000000..1441eeeddfbf389f47aa2955355aa2024e291f1c --- /dev/null +++ b/music_player/wifi.h @@ -0,0 +1,42 @@ +/** + * @file wifi.h + * Provide wifi connection and network configuration functions + */ + +/********************* + * INCLUDES + *********************/ +#include <nuttx/config.h> + +#if !defined(CONFIG_NETUTILS_DHCPC) || !defined(CONFIG_WIRELESS_WAPI) || !defined(CONFIG_NETUTILS_NTPCLIENT) || (CONFIG_SCHED_LPNTHREADS < 2) +#warning "If you want enable WIFI, please make sure DHCPC, WAPI, IEEE80211, NTP to be enabled \ + and number of lpthreads need greater than or equal to 2." +#define WIFI_ENABLED 0 +#else +#define WIFI_ENABLED 1 +#endif + +#if WIFI_ENABLED + +#include <nuttx/wqueue.h> + +#include "wireless/wapi.h" + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + char ssid[128]; + char pswd[128]; + enum wpa_ver_e ver_flag; + clock_t conn_delay; +} wifi_conf_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void wifi_connect(FAR const wifi_conf_t* conf); + +#endif /* WIFI_ENABLED */ diff --git a/music_player2/.gitignore b/music_player2/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..83f3ea7155e82a4d9ec7f4a1c216ffc92f5d3cfe --- /dev/null +++ b/music_player2/.gitignore @@ -0,0 +1,46 @@ +# 草稿 +ignore.md + +# 编译产物 +*.o +*.d +*.elf +*.bin +*.map +.built +.depend +Make.dep + +# 构建目录 +build/ +out/ +nuttx/ +apps/builtin/registry/ + +# 临时文件 +*.tmp +*.log +*.swp +*.swo +*~ + +# IDE/编辑器文件 +.vscode/ +.idea/ +*.code-workspace + +# 系统文件 +.DS_Store +Thumbs.db + +# 测试输出 +test_results/ +coverage/ + +# 文档草稿 +*.draft.md +*.bak + +# 个人配置 +.env +config.local.json diff --git a/music_player2/Kconfig b/music_player2/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..2f20a28fcfe0c79a8b0632847e46fc99bbb50134 --- /dev/null +++ b/music_player2/Kconfig @@ -0,0 +1,18 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_VELA_AUDIO + bool "Music_player2" + default n + help + Vela Audio Music Player 2. + +if LVX_USE_DEMO_VELA_AUDIO +config LVX_MUSIC_PLAYER_DATA_ROOT + string "Music Player2 Data Root" + default "/data" + help + Root directory for music player data and assets. +endif diff --git a/music_player2/Make.defs b/music_player2/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..e05de7c5afdfaebbcdbc44c45fabcb930c61fdc5 --- /dev/null +++ b/music_player2/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_VELA_AUDIO),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/music_player2 +endif diff --git a/music_player2/Makefile b/music_player2/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..34f6b6e66c7311b6f01890e0283241078118f055 --- /dev/null +++ b/music_player2/Makefile @@ -0,0 +1,35 @@ +# +# Copyright (C) 2022 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +-include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_VELA_AUDIO), y) +PROGNAME = music_player2 +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_VELA_AUDIO) + +CSRCS = music_player2.c audio_ctl.c wifi.c splash_screen.c playlist_manager.c font_config.c + +MAINSRC = music_player2_main.c + +CFLAGS += -DUSING_SIMULATOR_AUDIO=1 + +LDLIBS += -lm -lpthread + +endif + +include $(TOPDIR)/../apps/Application.mk \ No newline at end of file diff --git a/music_player2/README-en.md b/music_player2/README-en.md new file mode 100644 index 0000000000000000000000000000000000000000..13e9d4e918cb95bffd0c330c0300b69e3d36f8cc --- /dev/null +++ b/music_player2/README-en.md @@ -0,0 +1,258 @@ +# music_player2 + +music_player2 is an embedded music player designed based on the openvela system. It provides a UI interface with support for audio playback, playlist management, splash screen, volume control, and other features. Built with a modular architecture design for easy extension and maintenance. + +## Table of Contents + +- [Features](#features) +- [System Requirements](#system-requirements) +- [Project Structure](#project-structure) +- [Getting Started](#getting-started) +- [User Guide](#user-guide) +- [Customization Guide](#customization-guide) +- [Contributing](#contributing) + +## Detailed Documentation + +- [Troubleshooting Guide](docs/en/TROUBLESHOOTING.md) +- [Technical Documentation](docs/en/TECHNICAL.md) +- [Changelog](docs/en/CHANGELOG.md) + +## Features + +### Core Features +- Audio playback control +- Previous/next track switching +- Volume adjustment control +- Playlist management +- Real-time playback progress display +- Top status bar (time, date, Wi-Fi, battery) + +### Interface Features +- Splash screen: Logo animation and loading effects +- Rectangle adaptation: Optimized for simulator rectangular screen +- Volume bar: Visual volume control +- Scrolling song information: Long titles automatically scroll + +### System Features +- Wi-Fi network connection management +- Complete file system integration +- JSON configuration file management +- Real-time system resource monitoring +- Modular architecture design + +## System Requirements + +### Hardware Requirements +ARM architecture embedded devices with audio output and display capabilities. + +### Software Requirements +- **Operating System**: openvela +- **Graphics Library**: LVGL +- **Audio Library**: NuttX Audio Framework / Simulator Audio Controller +- **Network**: Wi-Fi driver support + +### Development Environment +- **Compiler**: arm-none-eabi-gcc +- **Build System**: Make / NuttX Build System +- **Debug Tools**: ADB +- **Host System**: Linux +- **Emulator**: QEMU + +## Project Structure + +``` +music_player2/ +├── music_player2.c +├── music_player2.h +├── music_player2_main.c +├── splash_screen.c +├── playlist_manager.c +├── playlist_manager.h +├── audio_ctl.c +├── audio_ctl.h +├── font_config.c +├── font_config.h +├── wifi.c +├── wifi.h +├── Kconfig +├── Makefile +├── Make.defs +├── README.md +├── README-en.md +├── docs/ +│ ├── ch/ +│ └── en/ +└── res/ + ├── fonts/ + ├── icons/ + ├── musics/ + └── config.json +``` + +## Getting Started + +### Environment Setup +```bash +# Install necessary tools +sudo apt update && sudo apt install -y android-tools-adb build-essential git + +# Clone openvela repository +git clone <openvela-repo-url> && cd vela_code +``` + +### Configuration and Build +```bash +# Configure music player +echo "CONFIG_LVX_USE_DEMO_VELA_AUDIO=y" >> vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig +echo 'CONFIG_LVX_MUSIC_PLAYER_DATA_ROOT="/data"' >> vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig + +# Build project +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 +``` + +### Startup and Deployment +```bash +cd nuttx && ln -sf vela_ap.elf nuttx && cd .. +./emulator.sh vela +sleep 15 && adb connect 127.0.0.1:5555 +adb -s emulator-5554 push apps/packages/demos/music_player2/res /data/ +adb -s emulator-5554 shell "music_player2 &" +``` + +### Configuration File Description + +#### config.json - Wi-Fi Configuration +```json +{ + "wifi": { + "ssid": "vela_network", + "pswd": "vela123456" + } +} +``` + +#### manifest.json - Music Configuration +```json +{ + "musics": [ + { + "path": "test.mp3", + "name": "Test Song", + "artist": "Demo Artist", + "cover": "test.png", + "total_time": 180000, + "color": "#4A90E2" + } + ] +} +``` + +## User Guide + +### Basic Operations +1. **Play/Pause**: Click the central play button +2. **Previous/Next**: Click the left/right arrow buttons +3. **Volume Control**: Click the volume button to show volume bar +4. **Open Playlist**: Click the playlist button +5. **Select Song**: Click the desired song in the list + +### Debug Mode +Enable debug mode by adding the `-DDEBUG` flag during compilation: +```bash +make CFLAGS="-DDEBUG" +``` + +## Customization Guide + +### Adding New Music + +#### 1. Prepare Audio Files +```bash +convert cover.jpg -resize 300x300 cover.png +``` + +#### 2. Update Configuration File +```json +{ + "musics": [ + { + "path": "new_song.mp3", + "name": "New Song Title", + "artist": "Artist Name", + "cover": "new_cover.png", + "total_time": 240000, + "color": "#FF5722" + } + ] +} +``` + +#### 3. Deploy Files +```bash +# Copy files to resource directory +cp new_song.mp3 res/musics/ +cp new_cover.png res/musics/ + +# Push to device +adb push res/musics/ /data/res/musics/ +``` + +### Interface Customization + +#### Modify Theme Colors +```c +// Modify in music_player2.c +#define MODERN_PRIMARY_COLOR lv_color_hex(0x00BFFF) +#define MODERN_SECONDARY_COLOR lv_color_hex(0xFF6B6B) +#define MODERN_BACKGROUND_COLOR lv_color_hex(0x121212) +``` + +#### Adjust Interface Layout +```c +// Modify resolution adaptation +#define SCREEN_WIDTH 1280 +#define SCREEN_HEIGHT 800 + +// Adjust component sizes +#define COVER_SIZE 200 +#define BUTTON_SIZE 60 +``` + +## Contributing + +### Development Process +1. Fork the project +2. Create feature branch +3. Develop and test +4. Submit changes +5. Create Pull Request + +### Code Standards +- Function naming: snake_case +- Variable naming: snake_case +- Constant naming: UPPER_CASE +- Structure naming: snake_case_t + +### Commit Message Standards +- feat: New feature +- fix: Bug fix +- docs: Documentation update +- style: Code formatting adjustment +- refactor: Refactoring +- test: Test related + +## License + +This project is licensed under the Apache License 2.0 open source license. + +## Acknowledgments + +- **openvela**: Providing embedded operating system platform +- **LVGL Community**: Providing graphics library and UI component support + +--- + +*Last updated: 2025-10-29* +*Current version: v2.3.3* diff --git a/music_player2/README.md b/music_player2/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ccdd88a186c62956a7b0cb87d8bd9f753bf64e2c --- /dev/null +++ b/music_player2/README.md @@ -0,0 +1,257 @@ +# music_player2 + +music_player2是一个嵌入式音乐播放器,基于 openvela 系统设计。提供 UI 界面,支持音频播放、播放列表管理、启动页面、音量控制等功能。采用模块化架构设计,易于扩展和维护。 + +## 目录 + +- [功能特性](#功能特性) +- [系统要求](#系统要求) +- [项目结构](#项目结构) +- [启动指南](#启动指南) +- [使用指南](#使用指南) +- [自定义指南](#自定义指南) +- [贡献指南](#贡献指南) + +## 详细文档 + +- [故障排除指南](docs/ch/TROUBLESHOOTING.md) +- [技术文档](docs/ch/TECHNICAL.md) +- [更新日志](docs/ch/CHANGELOG.md) + +## 功能特性 + +### 核心功能 +- 音频播放控制 +- 上一首/下一首切换 +- 音量调节控制 +- 播放列表管理 +- 实时播放进度显示 +- 顶部状态栏(时间、日期、Wi-Fi、电池) + +### 界面功能 +- 启动页面:Logo 动画和加载效果 +- 长方形适配:为模拟器长方形屏幕优化 +- 音量条:可视化音量控制 +- 滚动歌曲信息:长标题自动滚动显示 + +### 系统功能 +- Wi-Fi 网络连接管理 +- 完整文件系统集成 +- JSON 配置文件管理 +- 系统资源实时监控 +- 模块化架构设计 + +## 系统要求 + +### 硬件要求 +支持 ARM 架构的嵌入式设备,具备音频输出和显示功能。 + +### 软件要求 +- **操作系统**:openvela +- **图形库**:LVGL +- **音频库**:NuttX Audio 框架 / 模拟器音频控制器 +- **网络**:Wi-Fi 驱动支持 + +### 开发环境 +- **编译器**:arm-none-eabi-gcc +- **构建系统**:Make / NuttX 构建系统 +- **调试工具**:ADB +- **主机系统**:Linux +- **模拟器**:QEMU + +## 项目结构 + +``` +music_player2/ +├── music_player2.c +├── music_player2.h +├── music_player2_main.c +├── splash_screen.c +├── playlist_manager.c +├── playlist_manager.h +├── audio_ctl.c +├── audio_ctl.h +├── font_config.c +├── font_config.h +├── wifi.c +├── wifi.h +├── Kconfig +├── Makefile +├── Make.defs +├── README.md +├── README-en.md +├── docs/ +│ ├── ch/ +│ └── en/ +└── res/ + ├── fonts/ + ├── icons/ + ├── musics/ + └── config.json +``` + +## 启动指南 + +### 环境准备 +```bash +# 安装必要的工具 +sudo apt update && sudo apt install -y android-tools-adb build-essential git + +# 克隆 openvela 仓库 +git clone <openvela-repo-url> && cd vela_code +``` + +### 配置和构建 +```bash +# 配置音乐播放器 +echo "CONFIG_LVX_USE_DEMO_VELA_AUDIO=y" >> vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig +echo 'CONFIG_LVX_MUSIC_PLAYER_DATA_ROOT="/data"' >> vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig + +# 构建项目 +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 +``` + +### 启动和部署 +```bash +./emulator.sh vela +adb -s emulator-5554 push apps/packages/demos/music_player2/res /data/ +``` + +### 配置文件说明 + +#### config.json - Wi-Fi配置 +```json +{ + "wifi": { + "ssid": "vela_network", + "pswd": "vela123456" + } +} +``` + +#### manifest.json - 音乐配置 +```json +{ + "musics": [ + { + "path": "test.mp3", + "name": "Test Song", + "artist": "Demo Artist", + "cover": "test.png", + "total_time": 180000, + "color": "#4A90E2" + } + ] +} +``` + +## 使用指南 + +### 基本操作 +1. **播放/暂停**: 点击中央播放按钮 +2. **上一首/下一首**: 点击左右箭头按钮 +3. **音量控制**: 点击音量按钮显示音量条 +4. **打开播放列表**: 点击播放列表按钮 +5. **选择歌曲**: 在列表中点击想要播放的歌曲 + +### 调试模式 +在编译时添加 `-DDEBUG` 标志启用调试模式: +```bash +make CFLAGS="-DDEBUG" +``` + +## 自定义指南 + +### 添加新音乐 + +#### 1. 准备音频文件 +```bash +# 确保音频文件为支持的格式(MP3/WAV) +# 准备专辑封面(推荐 300x300,支持 JPG/PNG 格式) +convert cover.jpg -resize 300x300 cover.png +``` + +#### 2. 更新配置文件 +```json +{ + "musics": [ + { + "path": "new_song.mp3", + "name": "New Song Title", + "artist": "Artist Name", + "cover": "new_cover.png", + "total_time": 240000, + "color": "#FF5722" + } + ] +} +``` + +#### 3. 部署文件 +```bash +# 复制文件到资源目录 +cp new_song.mp3 res/musics/ +cp new_cover.png res/musics/ + +# 推送到设备 +adb push res/musics/ /data/res/musics/ +``` + +### 自定义界面 + +#### 修改主题颜色 +```c +// 在 music_player2.c 中修改 +#define MODERN_PRIMARY_COLOR lv_color_hex(0x00BFFF) +#define MODERN_SECONDARY_COLOR lv_color_hex(0xFF6B6B) +#define MODERN_BACKGROUND_COLOR lv_color_hex(0x121212) +``` + +#### 调整界面布局 +```c +// 修改分辨率适配 +#define SCREEN_WIDTH 1280 +#define SCREEN_HEIGHT 800 + +// 调整控件大小 +#define COVER_SIZE 200 +#define BUTTON_SIZE 60 +``` + +## 贡献指南 + +### 开发流程 +1. Fork 项目 +2. 创建功能分支 +3. 开发和测试 +4. 提交更改 +5. 创建 Pull Request + +### 代码规范 +- 函数命名:snake_case +- 变量命名:snake_case +- 常量命名:UPPER_CASE +- 结构体命名:snake_case_t + +### 提交信息规范 +- feat: 新功能 +- fix: 修复bug +- docs: 文档更新 +- style: 代码格式调整 +- refactor: 重构 +- test: 测试相关 + +## 许可证 + +本项目采用 Apache License 2.0 开源许可证。 + +## 致谢 + +- **openvela**:提供嵌入式操作系统平台 +- **LVGL 社区**:提供图形库和UI组件支持 + +--- + +*最后更新时间:2025-10-29* +*当前版本:v2.3.3* \ No newline at end of file diff --git a/music_player2/audio_ctl.c b/music_player2/audio_ctl.c new file mode 100644 index 0000000000000000000000000000000000000000..f535c0b5ecf9357738ea41165f05161de1de2b4d --- /dev/null +++ b/music_player2/audio_ctl.c @@ -0,0 +1,387 @@ +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> + +#define _GNU_SOURCE + +#include "audio_ctl.h" + +#define USING_SIMULATOR_AUDIO 1 +#ifndef AUDIO_DEBUG +#define AUDIO_DEBUG 0 +#endif + +#ifdef AUDIO_DEBUG +#include <syslog.h> +#define AUDIO_LOG(fmt, ...) syslog(LOG_INFO, "[AUDIO] " fmt, ##__VA_ARGS__) +#else +#define AUDIO_LOG(fmt, ...) +#endif + +static uint32_t estimate_mp3_duration(off_t file_size); +static void* monitor_thread_func(void* arg); +static void* playback_simulation_thread(void* arg) __attribute__((unused)); + +static uint32_t estimate_mp3_duration(off_t file_size) { + const uint32_t avg_bitrate = 128000; + const uint32_t bytes_per_sec = avg_bitrate / 8; + + if (bytes_per_sec > 0) { + return (uint32_t)(file_size / bytes_per_sec); + } + + return 240; +} + +static void* monitor_thread_func(void* arg) { + audioctl_s* ctl = (audioctl_s*)arg; + if (!ctl) { + AUDIO_LOG("Monitor thread: null parameter"); + return NULL; + } + + AUDIO_LOG("Monitor thread started"); + + while (ctl->monitor_running) { + usleep(100000); + + pthread_mutex_lock(&ctl->control_mutex); + + if (ctl->is_playing && !ctl->is_paused) { + ctl->current_position_ms += 100; + + if (ctl->current_position_ms >= ctl->total_duration_ms * 1000) { + AUDIO_LOG("Playback completed"); + ctl->is_playing = false; + ctl->state = AUDIO_CTL_STATE_STOP; + } + } + + pthread_mutex_unlock(&ctl->control_mutex); + } + + AUDIO_LOG("Monitor thread exited"); + return NULL; +} + +static void* playback_simulation_thread(void* arg) { + audioctl_s* ctl = (audioctl_s*)arg; + if (!ctl) { + return NULL; + } + + AUDIO_LOG("Simulation thread started: %s", ctl->file_path); + + while (ctl->is_playing && !ctl->should_stop) { + usleep(1000000); + + pthread_mutex_lock(&ctl->control_mutex); + if (ctl->is_playing && !ctl->is_paused) { + } + pthread_mutex_unlock(&ctl->control_mutex); + } + + AUDIO_LOG("Simulation thread ended"); + return NULL; +} + +int audio_ctl_detect_format(const char* path) { + if (!path) { + AUDIO_LOG("Null file path"); + return AUDIO_FORMAT_UNKNOWN; + } + + size_t len = strlen(path); + if (len < 4) { + AUDIO_LOG("File path too short: %s", path); + return AUDIO_FORMAT_UNKNOWN; + } + + const char* ext = path + len - 4; + AUDIO_LOG("Detecting format: %s", ext); + + if (strcasecmp(ext, ".mp3") == 0) { + AUDIO_LOG("MP3 format detected: %s", path); + return AUDIO_FORMAT_MP3; + } else if (strcasecmp(ext, ".wav") == 0) { + AUDIO_LOG("WAV format detected: %s", path); + return AUDIO_FORMAT_WAV; + } + + AUDIO_LOG("Unknown audio format: %s", path); + return AUDIO_FORMAT_UNKNOWN; +} + +audioctl_s* audio_ctl_init_nxaudio(const char* path) { + if (!path) { + AUDIO_LOG("Init failed: null path"); + return NULL; + } + + AUDIO_LOG("Initializing audio controller: %s", path); + + audioctl_s* ctl = (audioctl_s*)calloc(1, sizeof(audioctl_s)); + if (!ctl) { + return NULL; + } + + strncpy(ctl->file_path, path, sizeof(ctl->file_path) - 1); + ctl->file_path[sizeof(ctl->file_path) - 1] = '\0'; + + ctl->audio_format = audio_ctl_detect_format(path); + if (ctl->audio_format == AUDIO_FORMAT_UNKNOWN) { + AUDIO_LOG("Unsupported audio format"); + free(ctl); + return NULL; + } + + struct stat st; + if (stat(path, &st) == 0) { + ctl->file_size = st.st_size; + AUDIO_LOG("File size: %lld bytes", (long long)ctl->file_size); + + if (ctl->audio_format == AUDIO_FORMAT_MP3) { + uint32_t duration_sec = estimate_mp3_duration(ctl->file_size); + ctl->total_duration_ms = duration_sec * 1000; + AUDIO_LOG("Estimated MP3 duration: %lu seconds", + (unsigned long)duration_sec); + } else { + ctl->total_duration_ms = 240 * 1000; + } + } else { + AUDIO_LOG("Cannot get file info: %s", strerror(errno)); + free(ctl); + return NULL; + } + + ctl->nxplayer = (struct nxplayer_s*)0x12345678; + AUDIO_LOG("Created virtual NxPlayer instance: %p", ctl->nxplayer); + + if (pthread_mutex_init(&ctl->control_mutex, NULL) != 0) { + AUDIO_LOG("Failed to init mutex"); + free(ctl); + return NULL; + } + + ctl->state = AUDIO_CTL_STATE_STOP; + ctl->is_playing = false; + ctl->is_paused = false; + ctl->should_stop = false; + ctl->current_position_ms = 0; + ctl->monitor_running = 0; + + AUDIO_LOG("Audio controller initialized"); + return ctl; +} + +int audio_ctl_start(audioctl_s* ctl) { + if (!ctl) { + AUDIO_LOG("Start failed: null controller"); + return -1; + } + + if (!ctl->nxplayer) { + AUDIO_LOG("Start failed: null NxPlayer"); + return -1; + } + + AUDIO_LOG("Starting simulation: %s", ctl->file_path); + AUDIO_LOG("Audio format: %d", ctl->audio_format); + + pthread_mutex_lock(&ctl->control_mutex); + + if (ctl->is_playing) { + AUDIO_LOG("Stopping current playback"); + ctl->is_playing = false; + ctl->should_stop = true; + } + + if (access(ctl->file_path, R_OK) != 0) { + AUDIO_LOG("File access failed: %s, errno: %d (%s)", ctl->file_path, errno, + strerror(errno)); + pthread_mutex_unlock(&ctl->control_mutex); + return -1; + } + + AUDIO_LOG("File access OK, starting simulation..."); + + ctl->state = AUDIO_CTL_STATE_START; + ctl->is_playing = true; + ctl->is_paused = false; + ctl->should_stop = false; + ctl->current_position_ms = 0; + + if (!ctl->monitor_running) { + ctl->monitor_running = 1; + if (pthread_create(&ctl->monitor_thread, NULL, monitor_thread_func, ctl) != 0) { + AUDIO_LOG("Failed to create monitoring thread"); + } else { + AUDIO_LOG("Monitoring thread started"); + } + } + + pthread_mutex_unlock(&ctl->control_mutex); + + AUDIO_LOG("Simulation playback started successfully"); + return 0; +} + +int audio_ctl_pause(audioctl_s* ctl) { + if (!ctl || !ctl->nxplayer) { + AUDIO_LOG("Pause failed: controller or NxPlayer is null"); + return -1; + } + + AUDIO_LOG("Pausing simulation playback"); + + pthread_mutex_lock(&ctl->control_mutex); + + if (!ctl->is_playing || ctl->is_paused) { + AUDIO_LOG("Currently not playing or already paused"); + pthread_mutex_unlock(&ctl->control_mutex); + return 0; + } + + ctl->state = AUDIO_CTL_STATE_PAUSE; + ctl->is_paused = true; + AUDIO_LOG("Simulation pause successful"); + + pthread_mutex_unlock(&ctl->control_mutex); + return 0; +} + +int audio_ctl_resume(audioctl_s* ctl) { + if (!ctl || !ctl->nxplayer) { + AUDIO_LOG("Resume playback failed: controller or NxPlayer is null"); + return -1; + } + + AUDIO_LOG("Resuming simulation playback"); + + pthread_mutex_lock(&ctl->control_mutex); + + if (!ctl->is_playing || !ctl->is_paused) { + AUDIO_LOG("Currently not paused"); + pthread_mutex_unlock(&ctl->control_mutex); + return 0; + } + + ctl->state = AUDIO_CTL_STATE_START; + ctl->is_paused = false; + AUDIO_LOG("Resume simulation playback successful"); + + pthread_mutex_unlock(&ctl->control_mutex); + return 0; +} + +int audio_ctl_stop(audioctl_s* ctl) { + if (!ctl || !ctl->nxplayer) { + AUDIO_LOG("Stop playback failed: controller or NxPlayer is null"); + return -1; + } + + AUDIO_LOG("Stopping simulation playback"); + + pthread_mutex_lock(&ctl->control_mutex); + + if (ctl->monitor_running) { + ctl->monitor_running = 0; + ctl->should_stop = true; + pthread_mutex_unlock(&ctl->control_mutex); + + if (ctl->monitor_thread != 0) { + pthread_join(ctl->monitor_thread, NULL); + ctl->monitor_thread = 0; + AUDIO_LOG("Monitoring thread stopped"); + } + + pthread_mutex_lock(&ctl->control_mutex); + } + + ctl->state = AUDIO_CTL_STATE_STOP; + ctl->is_playing = false; + ctl->is_paused = false; + ctl->current_position_ms = 0; + AUDIO_LOG("Stop simulation playback successful"); + + pthread_mutex_unlock(&ctl->control_mutex); + return 0; +} + +int audio_ctl_set_volume(audioctl_s* ctl, uint16_t vol) { + if (!ctl || !ctl->nxplayer) { + AUDIO_LOG("Set volume failed: controller or NxPlayer is null"); + return -1; + } + + if (vol > 100) { + vol = 100; + } + + AUDIO_LOG("Set simulation volume: %d", vol); + return 0; +} + +int audio_ctl_get_position(audioctl_s* ctl) { + if (!ctl) { + return 0; + } + + pthread_mutex_lock(&ctl->control_mutex); + uint32_t position_sec = ctl->current_position_ms / 1000; + pthread_mutex_unlock(&ctl->control_mutex); + + return (int)position_sec; +} + +int audio_ctl_seek(audioctl_s* ctl, unsigned ms) { + if (!ctl) { + AUDIO_LOG("Seek failed: controller is null"); + return -1; + } + + AUDIO_LOG("Simulation seek to position: %lu ms", (unsigned long)ms); + + pthread_mutex_lock(&ctl->control_mutex); + + if (ms <= ctl->total_duration_ms) { + ctl->current_position_ms = ms; + AUDIO_LOG("Simulation position update successful: %lu ms", + (unsigned long)ms); + } else { + AUDIO_LOG("Seek position exceeds file length: %lu ms > %lu ms", + (unsigned long)ms, (unsigned long)ctl->total_duration_ms); + pthread_mutex_unlock(&ctl->control_mutex); + return -1; + } + + pthread_mutex_unlock(&ctl->control_mutex); + return 0; +} + +int audio_ctl_uninit_nxaudio(audioctl_s* ctl) { + if (!ctl) { + return 0; + } + + AUDIO_LOG("Releasing simulator audio controller"); + + audio_ctl_stop(ctl); + + ctl->nxplayer = NULL; + + pthread_mutex_destroy(&ctl->control_mutex); + + free(ctl); + + AUDIO_LOG("Simulator audio controller release completed"); + return 0; +} diff --git a/music_player2/audio_ctl.h b/music_player2/audio_ctl.h new file mode 100644 index 0000000000000000000000000000000000000000..733b9cabaec8f59a9d2ff6a08f274c7401f6dfa6 --- /dev/null +++ b/music_player2/audio_ctl.h @@ -0,0 +1,74 @@ +#ifndef AUDIO_CTL_H +#define AUDIO_CTL_H + +#include <pthread.h> +#include <stdbool.h> +#include <stdint.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define AUDIO_FORMAT_UNKNOWN 0 +#define AUDIO_FORMAT_WAV 1 +#define AUDIO_FORMAT_MP3 2 + +#define AUDIO_CTL_STATE_STOP 0 +#define AUDIO_CTL_STATE_START 1 +#define AUDIO_CTL_STATE_PAUSE 2 + +typedef struct { + uint32_t sample_rate; + uint16_t num_channels; + uint16_t bits_per_sample; + uint32_t data_size; + uint32_t data_offset; +} wav_s; + +struct nxplayer_s; + +typedef struct audioctl { + char file_path[512]; + int audio_format; + off_t file_size; + + struct nxplayer_s* nxplayer; + + volatile int state; + volatile int is_playing; + volatile int is_paused; + volatile int should_stop; + pthread_mutex_t control_mutex; + + uint32_t current_position_ms; + uint32_t total_duration_ms; + + pthread_t monitor_thread; + int monitor_running; + + wav_s wav; + int fd; + + int seek; + uint32_t seek_position; + uint32_t file_position; + pthread_t pid; +} audioctl_s; + +int audio_ctl_detect_format(const char* path); +audioctl_s* audio_ctl_init_nxaudio(const char* path); +int audio_ctl_start(audioctl_s* ctl); +int audio_ctl_pause(audioctl_s* ctl); +int audio_ctl_resume(audioctl_s* ctl); +int audio_ctl_stop(audioctl_s* ctl); +int audio_ctl_set_volume(audioctl_s* ctl, uint16_t vol); +int audio_ctl_get_position(audioctl_s* ctl); +int audio_ctl_seek(audioctl_s* ctl, unsigned ms); +int audio_ctl_uninit_nxaudio(audioctl_s* ctl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/music_player2/docs/ch/CHANGELOG.md b/music_player2/docs/ch/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..6fab1af2a234996bd5a0e176775993f9c4702fa4 --- /dev/null +++ b/music_player2/docs/ch/CHANGELOG.md @@ -0,0 +1,56 @@ +# music_player2 更新日志 + +- 所有代码注释从中文转换为英文 +- 将故障排除和更新日志分离为独立文档 + +--- + +## v2.1 (2025-09-19) + +### 界面系统 +- 优化用户交互体验 +- 提升界面响应速度和流畅度 +- 改进动画效果和视觉反馈 + +### 错误处理 +- 完善状态管理机制 +- 增强异常情况下的恢复能力 +- 改进错误日志记录和诊断 + +### 代码质量 +- 优化函数声明和实现 +- 统一代码风格和命名规范 + +--- + +## v2.0 (2025-08-18) + +### UI设计重构 +- 适配不同屏幕尺寸的响应式设计 + +### 启动页面模块 +- Logo展示动画效果 +- 平滑的加载过渡效果 + +### 播放列表管理器 +- 播放列表作为独立模块设计 +- 播放列表与主界面状态同步 + +### 模块化架构 +- 更好的模块化代码组织 +- 提高代码可维护性和扩展性 +- 清晰的模块间接口设计 + +--- + +## v1.0 (2025-07-20) + +### 基础功能 +- 基础的音乐播放器界面 +- 播放、暂停、上一首、下一首按钮 +- 歌曲标题和艺术家信息显示 +- 基本的音频文件播放功能 + +--- + +*最后更新时间:2025-09-29* \ No newline at end of file diff --git a/music_player2/docs/ch/TECHNICAL.md b/music_player2/docs/ch/TECHNICAL.md new file mode 100644 index 0000000000000000000000000000000000000000..88bec38d80144b49c94c52d89dc981cd3fccdb1c --- /dev/null +++ b/music_player2/docs/ch/TECHNICAL.md @@ -0,0 +1,428 @@ +# music_player2 技术文档 + +## 目录 + +- [技术架构](#技术架构) +- [API 参考](#api-参考) +- [开发指南](#开发指南) + +## 技术架构 + +### 系统概览 + +music_player2 采用模块化分层架构设计,确保代码的可维护性、可扩展性和高性能。整个系统基于事件驱动模型,通过清晰的接口分离各个功能模块。 + +**核心设计原则**: +- **模块化**:每个功能模块独立设计,职责明确 +- **分层架构**:清晰的层次结构,降低耦合度 +- **事件驱动**:基于 LVGL 9.x 事件系统的响应式设计 +- **资源管理**:统一的资源生命周期管理 +- **状态机**:可预测的状态转换和管理 + +### 架构层次 + +系统采用六层架构设计,从下到上包括: + +``` +┌─────────────────────────────────────────┐ +│ 用户界面层 (LVGL 9.x) │ ← 图形界面渲染和触屏交互 +├─────────────────────────────────────────┤ +│ UI模块层 │ ← 启动页面、主界面、播放列表管理器 +├─────────────────────────────────────────┤ +│ 业务逻辑层 │ ← 状态管理、播放控制、播放列表逻辑 +├─────────────────────────────────────────┤ +│ 服务层 │ ← 音频控制、文件管理、Wi-Fi管理 +├─────────────────────────────────────────┤ +│ 系统抽象层 (NuttX) │ ← 音频驱动、文件系统、网络栈 +├─────────────────────────────────────────┤ +│ 硬件抽象层 │ ← 音频硬件、存储设备、网络硬件 +└─────────────────────────────────────────┘ +``` + +### 数据流图 + +系统的数据流主要包括 3 个主要路径: + +#### 1. 应用启动流 +``` +main() → splash_screen_create() → 启动动画 → app_create() → 主界面 + ↓ +资源初始化 → 字体加载 → 配置读取 → UI组件创建 +``` + +#### 2. 用户交互流 +``` +用户操作 → LVGL 9.x 事件 → 事件处理函数 → 状态更新 → UI刷新 + ↓ +音频控制 → 播放列表更新 → 界面反馈 +``` + +#### 3. 模块通信流 +``` +主界面 ↔ 播放列表管理器 ↔ 音频控制器 ↔ 状态管理 + ↓ ↓ ↓ +UI更新 列表显示 播放控制 +``` + +### 主要数据结构 + +#### 运行时上下文 +```c +struct ctx_s { + bool resource_healthy_check; + album_info_t* current_album; + + uint16_t volume; + play_status_t play_status_prev; + play_status_t play_status; + uint64_t current_time; + + struct { + lv_timer_t* volume_bar_countdown; + lv_timer_t* playback_progress_update; + lv_timer_t* refresh_date_time; + } timers; + + audioctl_s* audioctl; +}; +``` + +#### 资源管理结构 +```c +struct resource_s { + struct { + lv_obj_t* time; + lv_obj_t* date; + lv_obj_t* player_group; + lv_obj_t* album_cover_container; + lv_obj_t* volume_bar; + } ui; + + struct { + struct { const lv_font_t* normal; } size_16; + struct { const lv_font_t* bold; } size_22; + struct { const lv_font_t* normal; } size_24; + } fonts; + + album_info_t* albums; + uint8_t album_count; +}; +``` + +### 状态机设计 + +#### 播放状态定义 +```c +typedef enum { + PLAY_STATUS_STOP, + PLAY_STATUS_PLAY, + PLAY_STATUS_PAUSE, +} play_status_t; +``` + +#### 状态转换逻辑 + +状态转换通过 `switch` 语句实现,主要在两个函数中处理: + +**1. 播放按钮点击事件处理**(状态切换逻辑): +```c +play_status_t new_status; +switch (C.play_status) { + case PLAY_STATUS_STOP: + new_status = PLAY_STATUS_PLAY; + break; + case PLAY_STATUS_PLAY: + new_status = PLAY_STATUS_PAUSE; + break; + case PLAY_STATUS_PAUSE: + new_status = PLAY_STATUS_PLAY; + break; + default: + return; +} +app_set_play_status(new_status); +``` + +**2. 状态刷新函数**(状态动作执行): +```c +static void app_refresh_play_status(void) { + switch (C.play_status) { + case PLAY_STATUS_STOP: + audio_ctl_stop(C.audioctl); + audio_ctl_uninit_nxaudio(C.audioctl); + C.audioctl = NULL; + break; + case PLAY_STATUS_PLAY: + if (C.play_status_prev == PLAY_STATUS_PAUSE) { + audio_ctl_resume(C.audioctl); + } else if (C.play_status_prev == PLAY_STATUS_STOP) { + C.audioctl = audio_ctl_init_nxaudio(audio_path); + audio_ctl_start(C.audioctl); + } + break; + case PLAY_STATUS_PAUSE: + audio_ctl_pause(C.audioctl); + break; + } +} +``` + +**状态转换图**: +``` +STOP ──[点击播放]──> PLAY ──[点击暂停]──> PAUSE + ↑ │ + └────────[播放结束/错误]─────────────────┘ + PAUSE ──[点击播放]──> PLAY +``` + +## API 参考 + +### 核心 API + +#### 应用程序控制 +```c +/** + * @brief 创建并初始化音乐播放器应用 + */ +void app_create(void); + +/** + * @brief 设置播放状态 + * @param status 播放状态 + */ +void app_set_play_status(play_status_t status); + +/** + * @brief 切换到指定专辑 + * @param index 专辑索引 (0-based) + */ +void app_switch_to_album(int index); +``` + +#### 启动页面模块 API +```c +/** + * @brief 创建启动页面 + */ +void splash_screen_create(void); +``` + +#### 播放列表管理器 API +```c +/** + * @brief 创建专业播放列表界面 + * @param parent 父容器对象 + */ +void playlist_manager_create(lv_obj_t* parent); + +/** + * @brief 刷新播放列表显示 + */ +void playlist_manager_refresh(void); + +/** + * @brief 关闭播放列表 + */ +void playlist_manager_close(void); + +/** + * @brief 检查播放列表是否打开 + * @return true 已打开, false 已关闭 + */ +bool playlist_manager_is_open(void); +``` + +#### 音频控制 API +```c +/** + * @brief 初始化音频控制器 + * @param file_path 音频文件路径 + * @return 音频控制句柄,失败返回NULL + */ +audioctl_s* audio_ctl_init_nxaudio(const char* file_path); + +/** + * @brief 开始播放 + * @param audioctl 音频控制句柄 + * @return 0 成功, -1 失败 + */ +int audio_ctl_start(audioctl_s* audioctl); + +/** + * @brief 暂停播放 + * @param audioctl 音频控制句柄 + * @return 0 成功, -1 失败 + */ +int audio_ctl_pause(audioctl_s* audioctl); + +/** + * @brief 停止播放 + * @param audioctl 音频控制句柄 + * @return 0 成功, -1 失败 + */ +int audio_ctl_stop(audioctl_s* audioctl); + +/** + * @brief 设置音量 + * @param audioctl 音频控制句柄 + * @param volume 音量值 (0-100) + * @return 0 成功, -1 失败 + */ +int audio_ctl_set_volume(audioctl_s* audioctl, uint16_t volume); + +/** + * @brief 跳转到指定位置 + * @param audioctl 音频控制句柄 + * @param position 位置(秒) + * @return 0 成功, -1 失败 + */ +int audio_ctl_seek(audioctl_s* audioctl, uint32_t position); + +/** + * @brief 获取当前播放位置 + * @param audioctl 音频控制句柄 + * @return 当前位置(秒),-1表示失败 + */ +int audio_ctl_get_position(audioctl_s* audioctl); +``` + +#### 字体配置 API +```c +/** + * @brief 初始化字体系统 + */ +void font_system_init(void); + +/** + * @brief 根据大小获取字体 + * @param size 字体大小 + * @return 字体指针,失败返回默认字体 + */ +const lv_font_t* get_font_by_size(int size); + +/** + * @brief 设置UTF-8文本 + * @param label 标签对象 + * @param text 文本内容 + * @param font 字体 + */ +void set_label_utf8_text(lv_obj_t* label, const char* text, const lv_font_t* font); +``` + +### 错误代码 + +```c +#define MUSIC_ERROR_OK 0 +#define MUSIC_ERROR_INVALID_PARAM -1 +#define MUSIC_ERROR_NO_MEMORY -2 +#define MUSIC_ERROR_TIMEOUT -3 +#define MUSIC_ERROR_FILE_NOT_FOUND -10 +#define MUSIC_ERROR_FILE_READ -11 +#define MUSIC_ERROR_FILE_WRITE -12 +#define MUSIC_ERROR_AUDIO_INIT -20 +#define MUSIC_ERROR_AUDIO_PLAY -21 +#define MUSIC_ERROR_NETWORK -30 +#define MUSIC_ERROR_WIFI_CONNECT -31 +#define MUSIC_ERROR_UI_INIT -50 +#define MUSIC_ERROR_FONT_LOAD -51 +``` + +## 开发指南 + +### 代码规范 + +#### C 代码风格 +```c +static void app_create_main_page(void); +static bool init_audio_system(void); + +static bool resource_healthy_check = false; +static uint32_t current_playback_time = 0; + +#define MAX_ALBUM_COUNT 100 +#define DEFAULT_VOLUME 50 + +typedef struct album_info_s { + const char* name; + const char* artist; + uint32_t duration; +} album_info_t; +``` + +#### 注释规范 +```c +/** + * @brief 函数简要描述 + * @param param1 参数1描述 + * @param param2 参数2描述 + * @return 返回值描述 + */ +int function_name(int param1, const char* param2); + +int volume = 50; +``` + +#### 错误处理规范 +```c +int audio_operation(audioctl_s* ctl) { + if (!ctl) { + return MUSIC_ERROR_INVALID_PARAM; + } + + int result = low_level_operation(ctl); + if (result < 0) { + return MUSIC_ERROR_AUDIO_PLAY; + } + + return MUSIC_ERROR_OK; +} +``` + +### 测试框架 + +#### 单元测试 +```c +#include "unity.h" +#include "audio_ctl.h" + +void test_audio_ctl_init_valid_file(void) { + audioctl_s* ctl = audio_ctl_init_nxaudio("test.mp3"); + TEST_ASSERT_NOT_NULL(ctl); + audio_ctl_uninit_nxaudio(ctl); +} + +void test_audio_ctl_init_invalid_file(void) { + audioctl_s* ctl = audio_ctl_init_nxaudio("nonexistent.mp3"); + TEST_ASSERT_NULL(ctl); +} +``` + +### 性能考量 + +#### 内存管理 +```c +static uint8_t audio_buffer_pool[AUDIO_BUFFER_SIZE * 4]; + +static void* allocate_audio_buffer(size_t size) { + return audio_buffer_pool; +} +``` + +#### UI性能优化 +```c +static uint32_t last_ui_update = 0; + +void update_ui_if_needed(void) { + uint32_t now = lv_tick_get(); + if (now - last_ui_update < UI_UPDATE_INTERVAL_MS) { + return; + } + + app_refresh_playback_status(); + last_ui_update = now; +} +``` + +--- + +*最后更新时间:2025-09-29* \ No newline at end of file diff --git a/music_player2/docs/ch/TROUBLESHOOTING.md b/music_player2/docs/ch/TROUBLESHOOTING.md new file mode 100644 index 0000000000000000000000000000000000000000..2d83a9f784c6a0c8192e3e09a40240c909f70340 --- /dev/null +++ b/music_player2/docs/ch/TROUBLESHOOTING.md @@ -0,0 +1,285 @@ +# music_player2 故障排除指南 + +本文档提供了 music_player2 音乐播放器的常见问题解决方案、调试技巧和性能优化建议。 + +## 目录 + +- [常见问题](#常见问题) +- [调试技巧](#调试技巧) +- [性能优化](#性能优化) + +## 常见问题 + +### 1. 编译错误 + +#### 问题:`music_player: command not found` +**症状**:编译后无法找到 music_player 命令 + +**解决方案**: +```bash +# 检查配置是否正确 +grep -r LVX_USE_DEMO_MUSIC_PLAYER vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig + +# 重新配置和编译 +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 +``` + +#### 问题:栈溢出错误 +**症状**:运行时出现栈溢出崩溃 + +**解决方案**: +```bash +# 编辑 Makefile,调整栈大小 +STACKSIZE = 32768 # 当前为16384,可调整到32768 +``` + +### 2. 运行时错误 + +#### 问题:找不到资源文件 +**症状**:应用启动后显示默认界面,无法加载音乐或图标 + +**解决方案**: +```bash +# 检查文件是否存在 +adb shell ls -la /data/res/ + +# 重新推送资源 +adb push res/ /data/ +``` + +#### 问题:音频播放失败 +**症状**:点击播放按钮无反应,或播放状态异常 + +**解决方案**: +```bash +# 检查音频设备 +adb shell ls -la /dev/audio/ + +# 检查音频格式 +file res/musics/*.mp3 + +# 验证音频文件完整性 +adb shell "cd /data/res/musics && ls -la *.mp3" +``` + +### 3. 界面问题 + +#### 问题:界面显示异常 +**症状**:字体显示乱码、界面布局错乱、颜色异常 + +**排查步骤**: +- 检查LVGL 9.x配置是否正确 +- 确保字体文件已正确加载 +- 检查屏幕分辨率设置 +- 验证资源文件路径 + +**解决方案**: +```bash +# 检查字体文件 +adb shell ls -la /data/res/fonts/ + +# 重新推送字体资源 +adb push res/fonts/ /data/res/fonts/ +``` + +#### 问题:操作无响应 +**症状**:触摸操作无效果,按钮点击无反应 + +**排查步骤**: +- 检查触摸屏驱动是否正常 +- 查看日志中的错误信息 +- 确保应用已正确初始化 +- 验证事件处理函数是否正确注册 + +### 4. 模拟器问题 + +#### 问题:模拟器启动失败 +**症状**:执行 `./emulator.sh vela` 失败 + +**解决方案**: +```bash +# 检查 nuttx 文件 +ls -la nuttx/nuttx + +# 重新创建符号链接 +cd nuttx && rm -f nuttx && ln -sf vela_ap.elf nuttx && cd .. + +# 确保构建产物存在 +ls -la nuttx/vela_ap.elf +``` + +#### 问题:ADB 连接失败 +**症状**:无法连接到模拟器,adb connect 失败 + +**解决方案**: +```bash +# 检查端口占用 +netstat -tlnp | grep 555 + +# 重启ADB服务 +adb kill-server +adb start-server + +# 重新连接 +adb disconnect 127.0.0.1:5555 +sleep 2 +adb connect 127.0.0.1:5555 + +# 验证连接 +adb devices +``` + +## 调试技巧 + +### 1. 使用日志输出 + +在代码中添加调试日志来跟踪程序执行: + +```c +// 在源文件开头定义调试宏 +#define MUSIC_DEBUG 1 + +#if MUSIC_DEBUG +#define DLOG(fmt, ...) printf("[MUSIC] " fmt "\n", ##__VA_ARGS__) +#else +#define DLOG(fmt, ...) +#endif + +// 在关键位置添加日志 +DLOG("Loading audio file: %s", file_path); +DLOG("Audio playback started, duration: %lu ms", duration); +DLOG("UI event triggered: %d", event_code); +DLOG("Volume changed to: %d", volume); +``` + +### 2. 界面调试 + +启用界面调试功能来验证UI组件: + +```c +// 添加界面测试函数 +#ifdef DEBUG +static void test_ui_functionality(void) { + // 测试按钮响应 + DLOG("Testing button functionality..."); + + // 测试字体加载 + if (resource.fonts.size_16.normal) { + DLOG("Font loaded successfully"); + } else { + DLOG("Font loading failed"); + } + + // 测试样式应用 + DLOG("UI components initialized: %d", ui_component_count); +} + +// 在初始化后调用 +test_ui_functionality(); +#endif +``` + +### 3. 内存分析 + +监控内存使用情况来识别内存泄漏: + +```c +// 内存监控函数 +static void print_memory_usage(void) { + lv_mem_monitor_t info; + lv_mem_monitor(&info); + printf("=== Memory Usage Report ===\n"); + printf("Total heap size: %zu bytes\n", info.total_size); + printf("Free heap: %zu bytes\n", info.free_size); + printf("Used heap: %zu bytes\n", info.total_size - info.free_size); + printf("===========================\n"); +} +``` + +## 性能优化 + +### 1. 界面优化 + +减少不必要的重绘和提高渲染效率: + +```c +// 减少不必要的重绘 +lv_obj_add_flag(obj, LV_OBJ_FLAG_FLOATING); + +// 使用缓存提高性能 +lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0); + +// 优化图像显示 +lv_img_set_src(img, &image_dsc); +lv_obj_set_style_img_opa(img, LV_OPA_COVER, 0); + +// 减少透明度计算 +lv_obj_set_style_bg_opa(container, LV_OPA_COVER, 0); +``` + +### 2. 内存优化 + +优化内存使用和减少碎片: + +```c +// 预分配内存池 +static uint8_t audio_buffer_pool[AUDIO_BUFFER_SIZE * 4]; + +// 使用对象池管理 +static album_info_t album_pool[MAX_ALBUMS]; +static uint8_t album_pool_usage[MAX_ALBUMS] = {0}; + +// 智能内存分配 +static void* smart_malloc(size_t size) { + void* ptr = malloc(size); + if (!ptr) { + // 触发垃圾回收 + lv_gc_collect(); + ptr = malloc(size); + } + return ptr; +} +``` + +### 3. 性能分析 + +```c +// 性能计时器 +static uint64_t perf_start_time; + +#define PERF_START() do { \ + perf_start_time = lv_tick_get(); \ +} while(0) + +#define PERF_END(name) do { \ + uint64_t elapsed = lv_tick_get() - perf_start_time; \ + printf("[PERF] %s took %llu ms\n", name, elapsed); \ +} while(0) + +// 使用示例 +PERF_START(); +load_audio_file(path); +PERF_END("Audio file loading"); +``` + +## 问题报告 + +如果遇到本文档未覆盖的问题,请提交 Issue 并包含以下信息: + +### 必需信息 +- **操作系统**:Ubuntu 版本等 +- **openvela 版本**:构建版本和日期 +- **硬件平台**:目标设备或模拟器 +- **复现步骤**:详细的操作步骤 +- **期望行为**:应该发生什么 +- **实际行为**:实际发生了什么 + +### 可选信息 +- **日志输出**:相关的错误日志 +- **配置文件**:相关的配置信息 +- **环境变量**:可能相关的环境设置 + +--- + +*最后更新:2025-09-29* \ No newline at end of file diff --git a/music_player2/docs/en/CHANGELOG.md b/music_player2/docs/en/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..60f0cdb35592cfdf17f769b5ed63cc9c459167e6 --- /dev/null +++ b/music_player2/docs/en/CHANGELOG.md @@ -0,0 +1,56 @@ +# music_player2 Changelog + +- All code comments converted from Chinese to English +- Separated troubleshooting and changelog into independent documents + +--- + +## v2.1 (2025-09-19) + +### Interface System +- Optimized user interaction experience +- Improved interface response speed and smoothness +- Enhanced animation effects and visual feedback + +### Error Handling +- Improved state management mechanism +- Enhanced recovery capability in exceptional situations +- Improved error logging and diagnostics + +### Code Quality +- Optimized function declarations and implementations +- Unified code style and naming conventions + +--- + +## v2.0 (2025-08-18) + +### UI Design Refactoring +- Responsive design adapted to different screen sizes + +### Splash Screen Module +- Logo display animation effects +- Smooth loading transition effects + +### Playlist Manager +- Playlist designed as independent module +- Playlist synchronized with main interface state + +### Modular Architecture +- Better modular code organization +- Improved code maintainability and scalability +- Clear inter-module interface design + +--- + +## v1.0 (2025-07-20) + +### Basic Features +- Basic music player interface +- Play, pause, previous, next buttons +- Song title and artist information display +- Basic audio file playback functionality + +--- + +*Last updated: 2025-09-29* diff --git a/music_player2/docs/en/TECHNICAL.md b/music_player2/docs/en/TECHNICAL.md new file mode 100644 index 0000000000000000000000000000000000000000..c5e9c17f2e3f191e99d103f5b944ee64841fa20c --- /dev/null +++ b/music_player2/docs/en/TECHNICAL.md @@ -0,0 +1,428 @@ +# music_player2 Technical Documentation + +## Table of Contents + +- [Technical Architecture](#technical-architecture) +- [API Reference](#api-reference) +- [Development Guide](#development-guide) + +## Technical Architecture + +### System Overview + +music_player2 adopts a modular layered architecture design to ensure code maintainability, scalability, and high performance. The entire system is based on an event-driven model, separating functional modules through clear interfaces. + +**Core Design Principles**: +- **Modularity**: Each functional module is independently designed with clear responsibilities +- **Layered Architecture**: Clear hierarchical structure reducing coupling +- **Event-Driven**: Responsive design based on LVGL 9.x event system +- **Resource Management**: Unified resource lifecycle management +- **State Machine**: Predictable state transitions and management + +### Architecture Layers + +The system adopts a six-layer architecture design, from bottom to top including: + +``` +┌─────────────────────────────────────────┐ +│ User Interface Layer (LVGL 9.x) │ ← Graphics rendering and touch interaction +├─────────────────────────────────────────┤ +│ UI Module Layer │ ← Splash screen, main interface, playlist manager +├─────────────────────────────────────────┤ +│ Business Logic Layer │ ← State management, playback control, playlist logic +├─────────────────────────────────────────┤ +│ Service Layer │ ← Audio control, file management, Wi-Fi management +├─────────────────────────────────────────┤ +│ System Abstraction Layer (NuttX) │ ← Audio drivers, file system, network stack +├─────────────────────────────────────────┤ +│ Hardware Abstraction Layer │ ← Audio hardware, storage devices, network hardware +└─────────────────────────────────────────┘ +``` + +### Data Flow Diagram + +The system's data flow mainly includes 3 primary paths: + +#### 1. Application Startup Flow +``` +main() → splash_screen_create() → Startup animation → app_create() → Main interface + ↓ +Resource initialization → Font loading → Configuration reading → UI component creation +``` + +#### 2. User Interaction Flow +``` +User operation → LVGL 9.x event → Event handler → State update → UI refresh + ↓ +Audio control → Playlist update → Interface feedback +``` + +#### 3. Module Communication Flow +``` +Main interface ↔ Playlist manager ↔ Audio controller ↔ State management + ↓ ↓ ↓ +UI update List display Playback control +``` + +### Main Data Structures + +#### Runtime Context +```c +struct ctx_s { + bool resource_healthy_check; + album_info_t* current_album; + + uint16_t volume; + play_status_t play_status_prev; + play_status_t play_status; + uint64_t current_time; + + struct { + lv_timer_t* volume_bar_countdown; + lv_timer_t* playback_progress_update; + lv_timer_t* refresh_date_time; + } timers; + + audioctl_s* audioctl; +}; +``` + +#### Resource Management Structure +```c +struct resource_s { + struct { + lv_obj_t* time; + lv_obj_t* date; + lv_obj_t* player_group; + lv_obj_t* album_cover_container; + lv_obj_t* volume_bar; + } ui; + + struct { + struct { const lv_font_t* normal; } size_16; + struct { const lv_font_t* bold; } size_22; + struct { const lv_font_t* normal; } size_24; + } fonts; + + album_info_t* albums; + uint8_t album_count; +}; +``` + +### State Machine Design + +#### Playback State Definition +```c +typedef enum { + PLAY_STATUS_STOP, + PLAY_STATUS_PLAY, + PLAY_STATUS_PAUSE, +} play_status_t; +``` + +#### State Transition Logic + +State transitions are implemented using `switch` statements, primarily handled in two functions: + +**1. Play Button Click Event Handler** (State switching logic): +```c +play_status_t new_status; +switch (C.play_status) { + case PLAY_STATUS_STOP: + new_status = PLAY_STATUS_PLAY; + break; + case PLAY_STATUS_PLAY: + new_status = PLAY_STATUS_PAUSE; + break; + case PLAY_STATUS_PAUSE: + new_status = PLAY_STATUS_PLAY; + break; + default: + return; +} +app_set_play_status(new_status); +``` + +**2. State Refresh Function** (State action execution): +```c +static void app_refresh_play_status(void) { + switch (C.play_status) { + case PLAY_STATUS_STOP: + audio_ctl_stop(C.audioctl); + audio_ctl_uninit_nxaudio(C.audioctl); + C.audioctl = NULL; + break; + case PLAY_STATUS_PLAY: + if (C.play_status_prev == PLAY_STATUS_PAUSE) { + audio_ctl_resume(C.audioctl); + } else if (C.play_status_prev == PLAY_STATUS_STOP) { + C.audioctl = audio_ctl_init_nxaudio(audio_path); + audio_ctl_start(C.audioctl); + } + break; + case PLAY_STATUS_PAUSE: + audio_ctl_pause(C.audioctl); + break; + } +} +``` + +**State Transition Diagram**: +``` +STOP ──[Click Play]──> PLAY ──[Click Pause]──> PAUSE + ↑ │ + └─────────[Playback End/Error]─────────────────┘ + PAUSE ──[Click Play]──> PLAY +``` + +## API Reference + +### Core API + +#### Application Control +```c +/** + * @brief Create and initialize music player application + */ +void app_create(void); + +/** + * @brief Set playback status + * @param status Playback status + */ +void app_set_play_status(play_status_t status); + +/** + * @brief Switch to specified album + * @param index Album index (0-based) + */ +void app_switch_to_album(int index); +``` + +#### Splash Screen Module API +```c +/** + * @brief Create splash screen + */ +void splash_screen_create(void); +``` + +#### Playlist Manager API +```c +/** + * @brief Create professional playlist interface + * @param parent Parent container object + */ +void playlist_manager_create(lv_obj_t* parent); + +/** + * @brief Refresh playlist display + */ +void playlist_manager_refresh(void); + +/** + * @brief Close playlist + */ +void playlist_manager_close(void); + +/** + * @brief Check if playlist is open + * @return true if open, false if closed + */ +bool playlist_manager_is_open(void); +``` + +#### Audio Control API +```c +/** + * @brief Initialize audio controller + * @param file_path Audio file path + * @return Audio control handle, NULL on failure + */ +audioctl_s* audio_ctl_init_nxaudio(const char* file_path); + +/** + * @brief Start playback + * @param audioctl Audio control handle + * @return 0 on success, -1 on failure + */ +int audio_ctl_start(audioctl_s* audioctl); + +/** + * @brief Pause playback + * @param audioctl Audio control handle + * @return 0 on success, -1 on failure + */ +int audio_ctl_pause(audioctl_s* audioctl); + +/** + * @brief Stop playback + * @param audioctl Audio control handle + * @return 0 on success, -1 on failure + */ +int audio_ctl_stop(audioctl_s* audioctl); + +/** + * @brief Set volume + * @param audioctl Audio control handle + * @param volume Volume value (0-100) + * @return 0 on success, -1 on failure + */ +int audio_ctl_set_volume(audioctl_s* audioctl, uint16_t volume); + +/** + * @brief Seek to specified position + * @param audioctl Audio control handle + * @param position Position (seconds) + * @return 0 on success, -1 on failure + */ +int audio_ctl_seek(audioctl_s* audioctl, uint32_t position); + +/** + * @brief Get current playback position + * @param audioctl Audio control handle + * @return Current position (seconds), -1 on failure + */ +int audio_ctl_get_position(audioctl_s* audioctl); +``` + +#### Font Configuration API +```c +/** + * @brief Initialize font system + */ +void font_system_init(void); + +/** + * @brief Get font by size + * @param size Font size + * @return Font pointer, returns default font on failure + */ +const lv_font_t* get_font_by_size(int size); + +/** + * @brief Set UTF-8 text + * @param label Label object + * @param text Text content + * @param font Font + */ +void set_label_utf8_text(lv_obj_t* label, const char* text, const lv_font_t* font); +``` + +### Error Codes + +```c +#define MUSIC_ERROR_OK 0 +#define MUSIC_ERROR_INVALID_PARAM -1 +#define MUSIC_ERROR_NO_MEMORY -2 +#define MUSIC_ERROR_TIMEOUT -3 +#define MUSIC_ERROR_FILE_NOT_FOUND -10 +#define MUSIC_ERROR_FILE_READ -11 +#define MUSIC_ERROR_FILE_WRITE -12 +#define MUSIC_ERROR_AUDIO_INIT -20 +#define MUSIC_ERROR_AUDIO_PLAY -21 +#define MUSIC_ERROR_NETWORK -30 +#define MUSIC_ERROR_WIFI_CONNECT -31 +#define MUSIC_ERROR_UI_INIT -50 +#define MUSIC_ERROR_FONT_LOAD -51 +``` + +## Development Guide + +### Code Standards + +#### C Code Style +```c +static void app_create_main_page(void); +static bool init_audio_system(void); + +static bool resource_healthy_check = false; +static uint32_t current_playback_time = 0; + +#define MAX_ALBUM_COUNT 100 +#define DEFAULT_VOLUME 50 + +typedef struct album_info_s { + const char* name; + const char* artist; + uint32_t duration; +} album_info_t; +``` + +#### Comment Standards +```c +/** + * @brief Brief function description + * @param param1 Parameter 1 description + * @param param2 Parameter 2 description + * @return Return value description + */ +int function_name(int param1, const char* param2); + +int volume = 50; +``` + +#### Error Handling Standards +```c +int audio_operation(audioctl_s* ctl) { + if (!ctl) { + return MUSIC_ERROR_INVALID_PARAM; + } + + int result = low_level_operation(ctl); + if (result < 0) { + return MUSIC_ERROR_AUDIO_PLAY; + } + + return MUSIC_ERROR_OK; +} +``` + +### Testing Framework + +#### Unit Testing +```c +#include "unity.h" +#include "audio_ctl.h" + +void test_audio_ctl_init_valid_file(void) { + audioctl_s* ctl = audio_ctl_init_nxaudio("test.mp3"); + TEST_ASSERT_NOT_NULL(ctl); + audio_ctl_uninit_nxaudio(ctl); +} + +void test_audio_ctl_init_invalid_file(void) { + audioctl_s* ctl = audio_ctl_init_nxaudio("nonexistent.mp3"); + TEST_ASSERT_NULL(ctl); +} +``` + +### Performance Considerations + +#### Memory Management +```c +static uint8_t audio_buffer_pool[AUDIO_BUFFER_SIZE * 4]; + +static void* allocate_audio_buffer(size_t size) { + return audio_buffer_pool; +} +``` + +#### UI Performance Optimization +```c +static uint32_t last_ui_update = 0; + +void update_ui_if_needed(void) { + uint32_t now = lv_tick_get(); + if (now - last_ui_update < UI_UPDATE_INTERVAL_MS) { + return; + } + + app_refresh_playback_status(); + last_ui_update = now; +} +``` + +--- + +*Last updated: 2025-09-29* diff --git a/music_player2/docs/en/TROUBLESHOOTING.md b/music_player2/docs/en/TROUBLESHOOTING.md new file mode 100644 index 0000000000000000000000000000000000000000..a8c4b16dab2682edec7158941a446549e09a88e4 --- /dev/null +++ b/music_player2/docs/en/TROUBLESHOOTING.md @@ -0,0 +1,285 @@ +# music_player2 Troubleshooting Guide + +This document provides common problem solutions, debugging techniques, and performance optimization suggestions for the music_player2 music player. + +## Table of Contents + +- [Common Issues](#common-issues) +- [Debugging Techniques](#debugging-techniques) +- [Performance Optimization](#performance-optimization) + +## Common Issues + +### 1. Compilation Errors + +#### Issue: `music_player: command not found` +**Symptoms**: Cannot find music_player command after compilation + +**Solution**: +```bash +# Check if configuration is correct +grep -r LVX_USE_DEMO_MUSIC_PLAYER vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap/defconfig + +# Reconfigure and compile +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 +``` + +#### Issue: Stack overflow error +**Symptoms**: Stack overflow crash during runtime + +**Solution**: +```bash +# Edit Makefile, adjust stack size +STACKSIZE = 32768 # Currently 16384, can be adjusted to 32768 +``` + +### 2. Runtime Errors + +#### Issue: Resource files not found +**Symptoms**: Application starts with default interface, cannot load music or icons + +**Solution**: +```bash +# Check if files exist +adb shell ls -la /data/res/ + +# Re-push resources +adb push res/ /data/ +``` + +#### Issue: Audio playback failure +**Symptoms**: No response when clicking play button, or abnormal playback status + +**Solution**: +```bash +# Check audio device +adb shell ls -la /dev/audio/ + +# Check audio format +file res/musics/*.mp3 + +# Verify audio file integrity +adb shell "cd /data/res/musics && ls -la *.mp3" +``` + +### 3. Interface Issues + +#### Issue: Abnormal interface display +**Symptoms**: Garbled font display, interface layout disorder, abnormal colors + +**Troubleshooting Steps**: +- Check if LVGL 9.x configuration is correct +- Ensure font files are loaded correctly +- Check screen resolution settings +- Verify resource file paths + +**Solution**: +```bash +# Check font files +adb shell ls -la /data/res/fonts/ + +# Re-push font resources +adb push res/fonts/ /data/res/fonts/ +``` + +#### Issue: Unresponsive operations +**Symptoms**: Touch operations have no effect, button clicks are unresponsive + +**Troubleshooting Steps**: +- Check if touchscreen driver is working properly +- Look for error messages in logs +- Ensure application has initialized correctly +- Verify event handler functions are registered correctly + +### 4. Emulator Issues + +#### Issue: Emulator startup failure +**Symptoms**: Executing `./emulator.sh vela` fails + +**Solution**: +```bash +# Check nuttx file +ls -la nuttx/nuttx + +# Recreate symbolic link +cd nuttx && rm -f nuttx && ln -sf vela_ap.elf nuttx && cd .. + +# Ensure build artifacts exist +ls -la nuttx/vela_ap.elf +``` + +#### Issue: ADB connection failure +**Symptoms**: Cannot connect to emulator, adb connect fails + +**Solution**: +```bash +# Check port usage +netstat -tlnp | grep 555 + +# Restart ADB service +adb kill-server +adb start-server + +# Reconnect +adb disconnect 127.0.0.1:5555 +sleep 2 +adb connect 127.0.0.1:5555 + +# Verify connection +adb devices +``` + +## Debugging Techniques + +### 1. Using Log Output + +Add debug logs in code to track program execution: + +```c +// Define debug macro at the beginning of source file +#define MUSIC_DEBUG 1 + +#if MUSIC_DEBUG +#define DLOG(fmt, ...) printf("[MUSIC] " fmt "\n", ##__VA_ARGS__) +#else +#define DLOG(fmt, ...) +#endif + +// Add logs at key positions +DLOG("Loading audio file: %s", file_path); +DLOG("Audio playback started, duration: %lu ms", duration); +DLOG("UI event triggered: %d", event_code); +DLOG("Volume changed to: %d", volume); +``` + +### 2. Interface Debugging + +Enable interface debugging features to verify UI components: + +```c +// Add interface test function +#ifdef DEBUG +static void test_ui_functionality(void) { + // Test button response + DLOG("Testing button functionality..."); + + // Test font loading + if (resource.fonts.size_16.normal) { + DLOG("Font loaded successfully"); + } else { + DLOG("Font loading failed"); + } + + // Test style application + DLOG("UI components initialized: %d", ui_component_count); +} + +// Call after initialization +test_ui_functionality(); +#endif +``` + +### 3. Memory Analysis + +Monitor memory usage to identify memory leaks: + +```c +// Memory monitoring function +static void print_memory_usage(void) { + lv_mem_monitor_t info; + lv_mem_monitor(&info); + printf("=== Memory Usage Report ===\n"); + printf("Total heap size: %zu bytes\n", info.total_size); + printf("Free heap: %zu bytes\n", info.free_size); + printf("Used heap: %zu bytes\n", info.total_size - info.free_size); + printf("===========================\n"); +} +``` + +## Performance Optimization + +### 1. Interface Optimization + +Reduce unnecessary redraws and improve rendering efficiency: + +```c +// Reduce unnecessary redraws +lv_obj_add_flag(obj, LV_OBJ_FLAG_FLOATING); + +// Use cache to improve performance +lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0); + +// Optimize image display +lv_img_set_src(img, &image_dsc); +lv_obj_set_style_img_opa(img, LV_OPA_COVER, 0); + +// Reduce transparency calculations +lv_obj_set_style_bg_opa(container, LV_OPA_COVER, 0); +``` + +### 2. Memory Optimization + +Optimize memory usage and reduce fragmentation: + +```c +// Pre-allocate memory pool +static uint8_t audio_buffer_pool[AUDIO_BUFFER_SIZE * 4]; + +// Use object pool management +static album_info_t album_pool[MAX_ALBUMS]; +static uint8_t album_pool_usage[MAX_ALBUMS] = {0}; + +// Smart memory allocation +static void* smart_malloc(size_t size) { + void* ptr = malloc(size); + if (!ptr) { + // Trigger garbage collection + lv_gc_collect(); + ptr = malloc(size); + } + return ptr; +} +``` + +### 3. Performance Analysis + +```c +// Performance timer +static uint64_t perf_start_time; + +#define PERF_START() do { \ + perf_start_time = lv_tick_get(); \ +} while(0) + +#define PERF_END(name) do { \ + uint64_t elapsed = lv_tick_get() - perf_start_time; \ + printf("[PERF] %s took %llu ms\n", name, elapsed); \ +} while(0) + +// Usage example +PERF_START(); +load_audio_file(path); +PERF_END("Audio file loading"); +``` + +## Issue Reporting + +If you encounter issues not covered in this document, please submit an Issue and include the following information: + +### Required Information +- **Operating System**: Ubuntu version, etc. +- **openvela Version**: Build version and date +- **Hardware Platform**: Target device or emulator +- **Reproduction Steps**: Detailed operation steps +- **Expected Behavior**: What should happen +- **Actual Behavior**: What actually happened + +### Optional Information +- **Log Output**: Relevant error logs +- **Configuration Files**: Relevant configuration information +- **Environment Variables**: Possibly relevant environment settings + +--- + +*Last updated: 2025-09-29* diff --git a/music_player2/font_config.c b/music_player2/font_config.c new file mode 100644 index 0000000000000000000000000000000000000000..fbc3d6e0c770d7a7cbd34fba9ba79e7fa3fa72c4 --- /dev/null +++ b/music_player2/font_config.c @@ -0,0 +1,95 @@ +#include "font_config.h" +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#if LV_USE_FREETYPE +lv_font_t* misans_font_16 = NULL; +lv_font_t* misans_font_20 = NULL; +lv_font_t* misans_font_24 = NULL; +lv_font_t* misans_font_28 = NULL; +lv_font_t* misans_font_32 = NULL; +#endif + +static bool font_system_initialized = false; + +const lv_font_t* get_font_by_size(int size) { +#if LV_USE_FREETYPE + if (size >= 32 && CHINESE_FONT_32) { + return CHINESE_FONT_32; + } else if (size >= 28 && CHINESE_FONT_28) { + return CHINESE_FONT_28; + } else if (size >= 24 && CHINESE_FONT_24) { + return CHINESE_FONT_24; + } else if (size >= 20 && CHINESE_FONT_20) { + return CHINESE_FONT_20; + } else if (CHINESE_FONT_16) { + return CHINESE_FONT_16; + } +#endif + + if (size >= 32) { + return FONT_DEFAULT_32; + } else if (size >= 28) { + return FONT_DEFAULT_28; + } else if (size >= 24) { + return FONT_DEFAULT_24; + } else if (size >= 20) { + return FONT_DEFAULT_20; + } else { + return FONT_DEFAULT_16; + } +} +void set_label_utf8_text(lv_obj_t* label, const char* text, + const lv_font_t* font) { + if (!label || !text) + return; + + if (font) { + lv_obj_set_style_text_font(label, font, LV_PART_MAIN); + } + + lv_label_set_text(label, text); +} +const lv_font_t* get_playlist_font(const char* font_type) { + if (!font_type) + return get_font_by_size(16); + + if (strcmp(font_type, "title") == 0) { + return get_font_by_size(PLAYLIST_TITLE_FONT_SIZE); + } else if (strcmp(font_type, "song") == 0) { + return get_font_by_size(PLAYLIST_SONG_NAME_FONT_SIZE); + } else if (strcmp(font_type, "artist") == 0) { + return get_font_by_size(PLAYLIST_ARTIST_FONT_SIZE); + } else if (strcmp(font_type, "info") == 0) { + return get_font_by_size(PLAYLIST_INFO_FONT_SIZE); + } else if (strcmp(font_type, "button") == 0) { + return get_font_by_size(PLAYLIST_BUTTON_FONT_SIZE); + } + + return get_font_by_size(16); +} +void optimize_text_display(lv_obj_t* label, const char* text, + const char* font_type) { + if (!label || !text) + return; + + const lv_font_t* font = get_playlist_font(font_type); + lv_obj_set_style_text_font(label, font, LV_PART_MAIN); + lv_label_set_text(label, text); + lv_label_set_long_mode(label, LV_LABEL_LONG_DOT); + + if (strcmp(font_type, "title") == 0) { + lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + } else if (strcmp(font_type, "song") == 0) { + lv_obj_set_style_text_color(label, lv_color_hex(0xF3F4F6), LV_PART_MAIN); + } else if (strcmp(font_type, "artist") == 0) { + lv_obj_set_style_text_color(label, lv_color_hex(0x9CA3AF), LV_PART_MAIN); + } else if (strcmp(font_type, "info") == 0) { + lv_obj_set_style_text_color(label, lv_color_hex(0x6B7280), LV_PART_MAIN); + } +} +int font_system_init(void) { + font_system_initialized = true; + return 0; +} diff --git a/music_player2/font_config.h b/music_player2/font_config.h new file mode 100644 index 0000000000000000000000000000000000000000..c330110f5d58a7ff7a09c47b058099d6d8eb9a8b --- /dev/null +++ b/music_player2/font_config.h @@ -0,0 +1,76 @@ +#ifndef FONT_CONFIG_H +#define FONT_CONFIG_H + +#include "lvgl.h" + +#define FONT_UTF8_SUPPORT 1 +#define FONT_CHINESE_SUPPORT 1 + +#define PLAYLIST_TITLE_FONT_SIZE 32 +#define PLAYLIST_SONG_NAME_FONT_SIZE 24 +#define PLAYLIST_ARTIST_FONT_SIZE 20 +#define PLAYLIST_INFO_FONT_SIZE 16 +#define PLAYLIST_BUTTON_FONT_SIZE 18 + +#define MISANS_NORMAL_PATH "/data/res/fonts/MiSans-Normal.ttf" +#define MISANS_SEMIBOLD_PATH "/data/res/fonts/MiSans-Semibold.ttf" + +#if LV_FONT_MONTSERRAT_16 +#define FONT_DEFAULT_16 &lv_font_montserrat_16 +#else +#define FONT_DEFAULT_16 &lv_font_default +#endif + +#if LV_FONT_MONTSERRAT_20 +#define FONT_DEFAULT_20 &lv_font_montserrat_20 +#else +#define FONT_DEFAULT_20 FONT_DEFAULT_16 +#endif + +#if LV_FONT_MONTSERRAT_24 +#define FONT_DEFAULT_24 &lv_font_montserrat_24 +#else +#define FONT_DEFAULT_24 FONT_DEFAULT_20 +#endif + +#if LV_FONT_MONTSERRAT_28 +#define FONT_DEFAULT_28 &lv_font_montserrat_28 +#else +#define FONT_DEFAULT_28 FONT_DEFAULT_24 +#endif + +#if LV_FONT_MONTSERRAT_32 +#define FONT_DEFAULT_32 &lv_font_montserrat_32 +#else +#define FONT_DEFAULT_32 FONT_DEFAULT_28 +#endif + +#if LV_USE_FREETYPE +extern lv_font_t* misans_font_16; +extern lv_font_t* misans_font_20; +extern lv_font_t* misans_font_24; +extern lv_font_t* misans_font_28; +extern lv_font_t* misans_font_32; + +#define CHINESE_FONT_16 misans_font_16 +#define CHINESE_FONT_20 misans_font_20 +#define CHINESE_FONT_24 misans_font_24 +#define CHINESE_FONT_28 misans_font_28 +#define CHINESE_FONT_32 misans_font_32 +#else +#define CHINESE_FONT_16 FONT_DEFAULT_16 +#define CHINESE_FONT_20 FONT_DEFAULT_20 +#define CHINESE_FONT_24 FONT_DEFAULT_24 +#define CHINESE_FONT_28 FONT_DEFAULT_28 +#define CHINESE_FONT_32 FONT_DEFAULT_32 +#endif + +const lv_font_t* get_font_by_size(int size); +void set_label_utf8_text(lv_obj_t* label, const char* text, + const lv_font_t* font); +int font_system_init(void); +const lv_font_t* get_playlist_font(const char* font_type); +void optimize_text_display(lv_obj_t* label, const char* text, + const char* font_type); + +#endif diff --git a/music_player2/music_player2.c b/music_player2/music_player2.c new file mode 100644 index 0000000000000000000000000000000000000000..17a406f2924a258f1cbf17a59f537ebeee9f91cc --- /dev/null +++ b/music_player2/music_player2.c @@ -0,0 +1,1794 @@ +#include "music_player2.h" +#include "font_config.h" +#include "playlist_manager.h" +#include <netutils/cJSON.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * MODERN UI CONSTANTS + **********************/ +#define MODERN_BACKGROUND_COLOR lv_color_hex(0x121212) +#define MODERN_CARD_COLOR lv_color_hex(0x1E1E1E) +#define MODERN_PRIMARY_COLOR lv_color_hex(0x00BFFF) +#define MODERN_SECONDARY_COLOR lv_color_hex(0xFF6B6B) +#define MODERN_TEXT_PRIMARY lv_color_hex(0xFFFFFF) +#define MODERN_TEXT_SECONDARY lv_color_hex(0xBBBBBB) +#define MODERN_ACCENT_COLOR lv_color_hex(0x4ECDC4) + +#define COVER_SIZE 200 +#define COVER_ROTATION_DURATION 8000 + +static char g_musics_root[256] = MUSICS_ROOT; + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + bool is_seeking; + bool was_playing; + uint64_t seek_preview_time; + uint32_t last_update_tick; + lv_anim_t smooth_anim; + bool smooth_update_enabled; + int32_t target_value; + int32_t current_value; +} progress_bar_state_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/* Init functions */ +static void read_configs(void); +static bool init_resource(void); +static void reload_music_config(void); +static void app_create_error_page(void); +static void app_create_main_page(void); +static void app_create_top_layer(void); + +static void app_refresh_album_info(void); +static void app_refresh_date_time(void); +static void app_refresh_play_status(void); +static void app_refresh_playback_progress(void); +static void app_refresh_playlist(void); +static void app_refresh_volume_bar(void); +static void app_refresh_volume_countdown_timer(void); + +static void app_set_volume(uint16_t volume); +static void app_set_playback_time(uint32_t current_time); +static void app_start_updating_date_time(void); + +static void app_audio_event_handler(lv_event_t* e); +static void app_play_status_event_handler(lv_event_t* e); +static void app_playlist_event_handler(lv_event_t* e); +static void app_switch_album_event_handler(lv_event_t* e); +static void app_volume_bar_event_handler(lv_event_t* e); +static void app_playback_progress_bar_event_handler(lv_event_t* e); + +static void app_refresh_date_time_timer_cb(lv_timer_t* timer); +static void app_playback_progress_update_timer_cb(lv_timer_t* timer); +static void app_volume_bar_countdown_timer_cb(lv_timer_t* timer); + +static void progress_smooth_anim_cb(void* obj, int32_t value); +static void start_smooth_progress_animation(int32_t target_value); +static void reset_progress_bar_state(void); + +struct resource_s R; +struct ctx_s C; +struct conf_s CF; +static progress_bar_state_t progress_state = {.is_seeking = false, + .was_playing = false, + .seek_preview_time = 0, + .last_update_tick = 0, + .smooth_update_enabled = true, + .target_value = 0, + .current_value = 0}; + +const char* WEEK_DAYS[] = {"Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"}; +const lv_style_prop_t transition_props[] = {LV_STYLE_OPA, LV_STYLE_BG_OPA, + LV_STYLE_Y, LV_STYLE_HEIGHT, + LV_STYLE_PROP_FLAG_NONE}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void app_create(void) { + lv_memzero(&R, sizeof(R)); + lv_memzero(&C, sizeof(C)); + lv_memzero(&CF, sizeof(CF)); + LV_LOG_USER("Starting music player..."); + font_system_init(); + read_configs(); + +#if WIFI_ENABLED + CF.wifi.conn_delay = 2000000; + wifi_connect(&CF.wifi); +#endif + + C.resource_healthy_check = init_resource(); + + if (!C.resource_healthy_check) { + app_create_error_page(); + return; + } + + app_create_main_page(); + app_set_play_status(PLAY_STATUS_STOP); + app_switch_to_album(0); + app_set_volume(30); + + app_refresh_album_info(); + app_refresh_playlist(); + app_refresh_volume_bar(); + + LV_LOG_USER("Music Player initialized"); + + // Initialization complete +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int32_t app_get_album_index(album_info_t* album) { + for (int i = 0; i < R.album_count; i++) { + if (album == &R.albums[i]) { + return i; + } + } + return -1; +} + +static void app_set_volume(uint16_t volume) { + C.volume = volume; + audio_ctl_set_volume(C.audioctl, C.volume); +} + +void app_set_play_status(play_status_t status) { + C.play_status_prev = C.play_status; + C.play_status = status; + app_refresh_play_status(); +} + +void app_switch_to_album(int index) { + if (R.album_count == 0 || index < 0 || index >= R.album_count || C.current_album == &R.albums[index]) + return; + + C.current_album = &R.albums[index]; + + reset_progress_bar_state(); + + app_refresh_album_info(); + app_refresh_playlist(); + app_set_playback_time(0); + + if (C.play_status == PLAY_STATUS_STOP) { + return; + } + + app_set_play_status(PLAY_STATUS_STOP); + app_set_play_status(PLAY_STATUS_PLAY); +} + +static void app_set_playback_time(uint32_t current_time) { + C.current_time = current_time; + + if (C.audioctl) { + audio_ctl_seek(C.audioctl, C.current_time); + } + progress_state.current_value = (int32_t)current_time; + progress_state.target_value = (int32_t)current_time; + + app_refresh_playback_progress(); +} + +static void app_refresh_date_time(void) { + if (!R.ui.time || !R.ui.date) { + LV_LOG_WARN("Time/Date UI components not initialized"); + return; + } + + time_t now = time(NULL); + struct tm* current_time = localtime(&now); + + if (current_time == NULL) { + static struct tm default_time = {0}; + default_time.tm_year = 2024 - 1900; + default_time.tm_mon = 9 - 1; + default_time.tm_mday = 14; + default_time.tm_hour = 14; + default_time.tm_min = 30; + default_time.tm_sec = 0; + default_time.tm_wday = 6; + current_time = &default_time; + + static int minute_counter = 0; + default_time.tm_min = 30 + (minute_counter++ % 60); + if (default_time.tm_min >= 60) { + default_time.tm_min %= 60; + default_time.tm_hour = (default_time.tm_hour + 1) % 24; + } + } + + char time_str[6]; + lv_snprintf(time_str, sizeof(time_str), "%02d:%02d", current_time->tm_hour, + current_time->tm_min); + lv_label_set_text(R.ui.time, time_str); + + char date_str[12]; + int wday = current_time->tm_wday; + if (wday < 0 || wday > 6) + wday = 0; + lv_snprintf(date_str, sizeof(date_str), "%s", WEEK_DAYS[wday]); + lv_label_set_text(R.ui.date, date_str); +} + +static void app_refresh_volume_bar(void) { + int32_t volume_bar_indic_height = C.volume; + + lv_obj_set_height(R.ui.volume_bar_indic, volume_bar_indic_height); + + lv_obj_refr_size(R.ui.volume_bar_indic); + lv_obj_update_layout(R.ui.volume_bar_indic); + + if (C.volume > 0) { + lv_image_set_src(R.ui.audio, R.images.audio); + } else { + lv_image_set_src(R.ui.audio, R.images.mute); + } +} + +static void app_refresh_album_info(void) { + if (C.current_album) { + const char* cover_path = C.current_album->cover; + const char* fallback_path = NULL; + + if (access(cover_path, F_OK) != 0) { + const char* filename = strrchr(cover_path, '/'); + filename = filename ? filename + 1 : cover_path; + + static char candidate[3][512]; + lv_snprintf(candidate[0], sizeof(candidate[0]), "%s/%s", g_musics_root, + filename); + lv_snprintf(candidate[1], sizeof(candidate[1]), "/data/res/musics/%s", + filename); + lv_snprintf(candidate[2], sizeof(candidate[2]), "res/musics/%s", + filename); + + for (int i = 0; i < 3; i++) { + if (access(candidate[i], F_OK) == 0) { + fallback_path = candidate[i]; + break; + } + } + } + + const char* final_path = (fallback_path) ? fallback_path : cover_path; + if (access(final_path, F_OK) == 0) { + lv_image_set_src(R.ui.album_cover, final_path); + LV_LOG_USER("Loading album cover: %s", final_path); + lv_image_set_scale(R.ui.album_cover, 256); + lv_image_set_inner_align(R.ui.album_cover, LV_IMAGE_ALIGN_CENTER); + lv_obj_set_style_bg_image_opa(R.ui.album_cover, LV_OPA_COVER, + LV_PART_MAIN); + lv_obj_set_style_image_recolor_opa(R.ui.album_cover, LV_OPA_0, + LV_PART_MAIN); + } else { + lv_image_set_src(R.ui.album_cover, R.images.nocover); + LV_LOG_WARN("Album cover file not found, using default. tried: %s", + cover_path); + } + + const char* display_name = (C.current_album->name && strlen(C.current_album->name) > 0) + ? C.current_album->name + : "Unknown Song"; + const char* display_artist = (C.current_album->artist && strlen(C.current_album->artist) > 0) + ? C.current_album->artist + : "Unknown Artist"; + + set_label_utf8_text(R.ui.album_name, display_name, get_font_by_size(28)); + lv_obj_set_style_text_align(R.ui.album_name, LV_TEXT_ALIGN_CENTER, + LV_PART_MAIN); + set_label_utf8_text(R.ui.album_artist, display_artist, + get_font_by_size(22)); + lv_obj_set_style_text_align(R.ui.album_artist, LV_TEXT_ALIGN_CENTER, + LV_PART_MAIN); + } +} + +static void app_refresh_play_status(void) { + if (C.timers.playback_progress_update == NULL) { + C.timers.playback_progress_update = lv_timer_create(app_playback_progress_update_timer_cb, 1000, NULL); + } + + switch (C.play_status) { + case PLAY_STATUS_STOP: + lv_image_set_src(R.ui.play_btn, R.images.play); + lv_timer_pause(C.timers.playback_progress_update); + if (C.audioctl) { + audio_ctl_stop(C.audioctl); + audio_ctl_uninit_nxaudio(C.audioctl); + C.audioctl = NULL; + } + break; + case PLAY_STATUS_PLAY: + lv_image_set_src(R.ui.play_btn, R.images.pause); + lv_timer_resume(C.timers.playback_progress_update); + if (C.play_status_prev == PLAY_STATUS_PAUSE) + audio_ctl_resume(C.audioctl); + else if (C.play_status_prev == PLAY_STATUS_STOP) { + if (!C.current_album || C.current_album->path[0] == '\0') { + LV_LOG_ERROR("Current album or path is empty, cannot initialize audio"); + app_set_play_status(PLAY_STATUS_STOP); + return; + } + + const char* audio_path = C.current_album->path; + + if (access(audio_path, R_OK) != 0) { + LV_LOG_WARN("Main path not accessible, trying backup paths..."); + const char* filename = strrchr(audio_path, '/'); + if (filename) { + filename++; + } else { + filename = audio_path; + } + static char backup_paths[5][512]; + snprintf(backup_paths[0], sizeof(backup_paths[0]), "%s/%s", + g_musics_root, filename); + snprintf(backup_paths[1], sizeof(backup_paths[1]), + "/data/res/musics/%s", filename); + snprintf(backup_paths[2], sizeof(backup_paths[2]), "res/musics/%s", + filename); + snprintf(backup_paths[3], sizeof(backup_paths[3]), "./res/musics/%s", + filename); + snprintf(backup_paths[4], sizeof(backup_paths[4]), + "/sdcard/res/musics/%s", filename); + + audio_path = NULL; + for (int i = 0; i < 5; i++) { + if (access(backup_paths[i], R_OK) == 0) { + audio_path = backup_paths[i]; + break; + } + } + + if (!audio_path) { + LV_LOG_ERROR("Cannot find audio file: %s", C.current_album->path); + app_set_play_status(PLAY_STATUS_STOP); + return; + } + } + + int retry_count = 3; + while (retry_count > 0 && !C.audioctl) { + C.audioctl = audio_ctl_init_nxaudio(audio_path); + if (!C.audioctl) { + retry_count--; + LV_LOG_WARN("Audio controller init failed, retries left: %d", + retry_count); + if (retry_count > 0) { + lv_delay_ms(100); + } + } + } + + if (!C.audioctl) { + LV_LOG_ERROR( + "Audio controller init finally failed, check audio file: %s", + audio_path); + app_set_play_status(PLAY_STATUS_STOP); + return; + } + + int ret = audio_ctl_start(C.audioctl); + if (ret < 0) { + LV_LOG_ERROR("Audio playback start failed: %d", ret); + audio_ctl_uninit_nxaudio(C.audioctl); + C.audioctl = NULL; + app_set_play_status(PLAY_STATUS_STOP); + return; + } + } + break; + case PLAY_STATUS_PAUSE: + lv_image_set_src(R.ui.play_btn, R.images.play); + lv_timer_pause(C.timers.playback_progress_update); + audio_ctl_pause(C.audioctl); + break; + default: + break; + } +} + +static void app_refresh_playback_progress(void) { + if (!C.current_album) { + return; + } + + uint64_t total_time = C.current_album->total_time; + + if (C.current_time > total_time) { + app_set_play_status(PLAY_STATUS_STOP); + C.current_time = 0; + return; + } + + lv_bar_set_range(R.ui.playback_progress, 0, (int32_t)total_time); + + if (!progress_state.is_seeking) { + if (progress_state.smooth_update_enabled) { + int32_t current_value = lv_bar_get_value(R.ui.playback_progress); + int32_t new_value = (int32_t)C.current_time; + + if (abs(new_value - current_value) > 2000) { + start_smooth_progress_animation(new_value); + } else { + lv_bar_set_value(R.ui.playback_progress, new_value, LV_ANIM_OFF); + progress_state.current_value = new_value; + } + } else { + lv_bar_set_value(R.ui.playback_progress, (int32_t)C.current_time, + LV_ANIM_OFF); + } + } + + if (!progress_state.is_seeking) { + char buff[16]; + + uint32_t current_time_min = C.current_time / 60000; + uint32_t current_time_sec = (C.current_time % 60000) / 1000; + uint32_t total_time_min = total_time / 60000; + uint32_t total_time_sec = (total_time % 60000) / 1000; + + lv_snprintf(buff, sizeof(buff), "%02d:%02d", current_time_min, + current_time_sec); + lv_span_set_text(R.ui.playback_current_time, buff); + lv_snprintf(buff, sizeof(buff), "%02d:%02d", total_time_min, + total_time_sec); + lv_span_set_text(R.ui.playback_total_time, buff); + } +} + +static void app_refresh_playlist(void) { + if (playlist_manager_is_open()) { + playlist_manager_refresh(); + } + LV_LOG_USER("Playlist refresh triggered - using new playlist manager system"); +} + +static void app_volume_bar_countdown_timer_cb(lv_timer_t* timer) { + LV_UNUSED(timer); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_DEFAULT, true); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_USER_1, false); +} + +static void app_playback_progress_update_timer_cb(lv_timer_t* timer) { + LV_UNUSED(timer); + if (!C.audioctl) { + LV_LOG_WARN("Audio controller invalid, stopping progress updates"); + return; + } + if (C.play_status != PLAY_STATUS_PLAY) { + return; + } + if (progress_state.is_seeking) { + return; + } + int position = audio_ctl_get_position(C.audioctl); + if (position >= 0) { + uint64_t new_time = position * 1000; + if (abs((int64_t)new_time - (int64_t)C.current_time) > 100) { // Reduce threshold to 100ms + C.current_time = new_time; + app_refresh_playback_progress(); + } + static int debug_counter = 0; + if (++debug_counter >= 10) { + debug_counter = 0; + } + } else { + LV_LOG_WARN("Failed to get playback position: %d", position); + } +} + +static void app_refresh_date_time_timer_cb(lv_timer_t* timer) { + LV_UNUSED(timer); + + app_refresh_date_time(); +} + +static void app_refresh_volume_countdown_timer(void) { + if (C.timers.volume_bar_countdown) { + lv_timer_set_repeat_count(C.timers.volume_bar_countdown, 1); + lv_timer_reset(C.timers.volume_bar_countdown); + lv_timer_resume(C.timers.volume_bar_countdown); + } else { + C.timers.volume_bar_countdown = lv_timer_create(app_volume_bar_countdown_timer_cb, 3000, NULL); + lv_timer_set_auto_delete(C.timers.volume_bar_countdown, false); + } +} + +static void app_playlist_event_handler(lv_event_t* e) { + static uint32_t last_click_time = 0; + uint32_t current_time = lv_tick_get(); + if (!e) { + LV_LOG_WARN("Playlist button event pointer is null"); + return; + } + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_CLICKED) { + if (current_time - last_click_time < 500) { + LV_LOG_WARN("Click too fast, ignoring repeat click"); + return; + } + last_click_time = current_time; + } + if (code != LV_EVENT_CLICKED && code != LV_EVENT_PRESSED) { + return; + } + if (code == LV_EVENT_PRESSED) { + lv_obj_t* target = lv_event_get_target(e); + if (target) { + lv_obj_set_style_transform_scale(target, 240, + LV_PART_MAIN | LV_STATE_PRESSED); + } + return; + } + if (!R.albums || R.album_count == 0) { + LV_LOG_WARN("Playlist is empty or not initialized, cannot display"); + if (R.ui.album_name) { + lv_label_set_text(R.ui.album_name, "No music files found"); + } + lv_obj_t* mbox = lv_msgbox_create(lv_screen_active()); + lv_msgbox_add_title(mbox, "Empty Playlist"); + lv_msgbox_add_text( + mbox, "No music files found.\nPlease add music files to continue."); + lv_msgbox_add_close_button(mbox); + return; + } + if (playlist_manager_is_open()) { + LV_LOG_USER("Closing playlist (songs: %d)", R.album_count); + playlist_manager_close(); + } else { + LV_LOG_USER("Opening playlist (songs: %d)", R.album_count); + lv_obj_t* parent_container = lv_layer_top(); + if (!parent_container) { + LV_LOG_WARN("Top container unavailable, using active screen"); + parent_container = lv_screen_active(); + } + if (parent_container) { + lv_mem_monitor_t mem_info; + lv_mem_monitor(&mem_info); + playlist_manager_create(parent_container); + lv_mem_monitor(&mem_info); + } else { + LV_LOG_ERROR("Cannot find suitable parent container"); + } + } +} + +static void app_volume_bar_event_handler(lv_event_t* e) { + lv_event_code_t code = lv_event_get_code(e); + + if (!(code == LV_EVENT_PRESSED || code == LV_EVENT_PRESSING || code == LV_EVENT_PRESS_LOST)) { + return; + } + + lv_point_t point; + lv_indev_t* indev = lv_indev_active(); + lv_indev_get_vect(indev, &point); + + int32_t volume_bar_height = lv_obj_get_height(R.ui.volume_bar); + int32_t volume_bar_indic_height = lv_obj_get_height(R.ui.volume_bar_indic); + + if (volume_bar_indic_height < 0) { + volume_bar_indic_height = 0; + } else if (volume_bar_indic_height > volume_bar_height) { + volume_bar_indic_height = volume_bar_height; + } + + int32_t volume = volume_bar_indic_height - point.y; + if (volume < 0) + volume = 0; + + app_set_volume(volume); + + app_refresh_volume_bar(); + app_refresh_volume_countdown_timer(); +} + +static void app_audio_event_handler(lv_event_t* e) { + if (!e) { + LV_LOG_ERROR("Volume button event pointer is null"); + return; + } + + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t* target = lv_event_get_target(e); + + if (code == LV_EVENT_PRESSED && target) { + lv_obj_set_style_transform_scale(target, 240, + LV_PART_MAIN | LV_STATE_PRESSED); + return; + } + + if (code == LV_EVENT_RELEASED && target) { + lv_obj_set_style_transform_scale(target, 256, LV_PART_MAIN); + return; + } + + if (code != LV_EVENT_CLICKED) { + return; + } + + if (!R.ui.volume_bar) { + LV_LOG_ERROR("Volume bar component not initialized"); + + if (R.ui.audio) { + LV_LOG_WARN("Trying to reinitialize volume controls..."); + } + return; + } + + bool volume_visible = lv_obj_has_state(R.ui.volume_bar, LV_STATE_USER_1); + + if (volume_visible) { + LV_LOG_USER("Hiding volume bar (current volume: %d)", C.volume); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_DEFAULT, true); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_USER_1, false); + if (C.timers.volume_bar_countdown) { + lv_timer_pause(C.timers.volume_bar_countdown); + } + } else { + lv_obj_set_state(R.ui.volume_bar, LV_STATE_DEFAULT, false); + lv_obj_set_state(R.ui.volume_bar, LV_STATE_USER_1, true); + app_refresh_volume_countdown_timer(); + } + if (R.ui.audio) { + if (C.volume > 0) { + lv_image_set_src(R.ui.audio, R.images.audio); + } else { + lv_image_set_src(R.ui.audio, R.images.mute); + } + } + lv_mem_monitor_t mem_info; + lv_mem_monitor(&mem_info); +} + +static void app_switch_album_event_handler(lv_event_t* e) { + if (!e) { + // Event pointer is null + return; + } + + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t* target = lv_event_get_target(e); + + if (code == LV_EVENT_PRESSED && target) { + lv_obj_set_style_transform_scale(target, 245, LV_PART_MAIN); + lv_obj_set_style_shadow_width(target, 20, LV_PART_MAIN); + return; + } else if (code == LV_EVENT_RELEASED && target) { + lv_obj_set_style_transform_scale(target, 256, LV_PART_MAIN); + lv_obj_set_style_shadow_width(target, 15, LV_PART_MAIN); + return; + } + + if (code != LV_EVENT_CLICKED && code != LV_EVENT_LONG_PRESSED_REPEAT) { + return; + } + + // Basic state validation + if (R.album_count == 0) { + LV_LOG_WARN("Playlist is empty, cannot switch songs"); + return; + } + + if (!C.current_album) { + LV_LOG_WARN("Current album is empty, trying to select first song"); + app_switch_to_album(0); + return; + } + + switch_album_mode_t direction = (switch_album_mode_t)(lv_uintptr_t)lv_event_get_user_data(e); + + if (direction != SWITCH_ALBUM_MODE_PREV && direction != SWITCH_ALBUM_MODE_NEXT) { + LV_LOG_ERROR("Invalid switch direction: %d", direction); + return; + } + + int32_t album_index = app_get_album_index(C.current_album); + if (album_index < 0) { + app_switch_to_album(0); + return; + } + + int32_t new_index = album_index; + switch (direction) { + case SWITCH_ALBUM_MODE_PREV: + new_index = (album_index - 1 + R.album_count) % R.album_count; + break; + case SWITCH_ALBUM_MODE_NEXT: + new_index = (album_index + 1) % R.album_count; + break; + } + + if (new_index < 0 || new_index >= R.album_count) { + LV_LOG_ERROR("Calculated index is invalid: %ld (range: 0-%d)", + (long)new_index, R.album_count - 1); + return; + } + + app_switch_to_album(new_index); +} + +static void app_play_status_event_handler(lv_event_t* e) { + if (!e) { + LV_LOG_ERROR("Event pointer is null, play button event handling failed"); + return; + } + + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t* target = lv_event_get_target(e); + + if (!target) { + LV_LOG_ERROR("Target object is null, play button event handling failed"); + return; + } + + if (code == LV_EVENT_PRESSED) { + lv_obj_add_state(target, LV_STATE_PRESSED); + lv_obj_set_style_transform_scale(target, 245, LV_PART_MAIN); + lv_obj_set_style_shadow_width(target, 35, LV_PART_MAIN); + return; + } else if (code == LV_EVENT_RELEASED) { + lv_obj_clear_state(target, LV_STATE_PRESSED); + lv_obj_set_style_transform_scale(target, 256, LV_PART_MAIN); + lv_obj_set_style_shadow_width(target, 25, LV_PART_MAIN); + return; + } else if (code != LV_EVENT_CLICKED) { + return; + } + if (!C.current_album && R.album_count > 0) { + LV_LOG_WARN( + "No album selected currently, automatically selecting first song"); + app_switch_to_album(0); + return; + } else if (R.album_count == 0) { + LV_LOG_ERROR("Playlist is empty, cannot play"); + return; + } + play_status_t new_status; + + switch (C.play_status) { + case PLAY_STATUS_STOP: + new_status = PLAY_STATUS_PLAY; + break; + case PLAY_STATUS_PLAY: + new_status = PLAY_STATUS_PAUSE; + break; + case PLAY_STATUS_PAUSE: + new_status = PLAY_STATUS_PLAY; + break; + default: + LV_LOG_ERROR("Unknown play status: %d, operation rejected", C.play_status); + return; + } + + app_set_play_status(new_status); +} + +static void progress_smooth_anim_cb(void* obj, int32_t value) { + lv_obj_t* progress_bar = (lv_obj_t*)obj; + if (progress_bar && lv_obj_is_valid(progress_bar)) { + progress_state.current_value = value; + lv_bar_set_value(progress_bar, value, LV_ANIM_OFF); + } +} + +static void start_smooth_progress_animation(int32_t target_value) { + if (!R.ui.playback_progress || !progress_state.smooth_update_enabled) { + return; + } + + if (progress_state.is_seeking) { + return; + } + + progress_state.target_value = target_value; + + lv_anim_delete(R.ui.playback_progress, progress_smooth_anim_cb); + + lv_anim_init(&progress_state.smooth_anim); + lv_anim_set_var(&progress_state.smooth_anim, R.ui.playback_progress); + lv_anim_set_exec_cb(&progress_state.smooth_anim, progress_smooth_anim_cb); + lv_anim_set_values(&progress_state.smooth_anim, progress_state.current_value, + target_value); + lv_anim_set_duration(&progress_state.smooth_anim, 200); + lv_anim_set_path_cb(&progress_state.smooth_anim, lv_anim_path_ease_out); + lv_anim_start(&progress_state.smooth_anim); +} + +static void reset_progress_bar_state(void) { + progress_state.is_seeking = false; + progress_state.was_playing = false; + progress_state.seek_preview_time = 0; + progress_state.last_update_tick = 0; + progress_state.target_value = 0; + progress_state.current_value = 0; + + if (R.ui.playback_progress) { + lv_anim_delete(R.ui.playback_progress, progress_smooth_anim_cb); + } + + LV_LOG_USER("Progress bar state has been reset"); +} + +static void app_playback_progress_bar_event_handler(lv_event_t* e) { + if (!e) { + LV_LOG_ERROR("Progress bar event pointer is null"); + return; + } + + lv_event_code_t code = lv_event_get_code(e); + + if (!C.current_album) { + LV_LOG_ERROR("Current album is empty, cannot operate progress bar"); + return; + } + + uint32_t current_tick = lv_tick_get(); + + switch (code) { + case LV_EVENT_PRESSED: { + progress_state.is_seeking = true; + progress_state.was_playing = (C.play_status == PLAY_STATUS_PLAY); + progress_state.last_update_tick = current_tick; + lv_anim_delete(R.ui.playback_progress, progress_smooth_anim_cb); + if (C.timers.playback_progress_update) { + lv_timer_pause(C.timers.playback_progress_update); + } + lv_obj_set_height(R.ui.playback_progress, 14); + lv_obj_set_style_bg_color(R.ui.playback_progress, lv_color_hex(0x0078D4), + LV_PART_INDICATOR); + lv_obj_set_style_shadow_width(R.ui.playback_progress, 12, + LV_PART_INDICATOR); + lv_obj_set_style_shadow_color(R.ui.playback_progress, + lv_color_hex(0x0078D4), LV_PART_INDICATOR); + lv_obj_set_style_shadow_opa(R.ui.playback_progress, LV_OPA_70, + LV_PART_INDICATOR); + lv_obj_set_style_radius(R.ui.playback_progress, 7, LV_PART_INDICATOR); + lv_obj_set_style_transform_zoom(R.ui.playback_progress, 256 + 20, + LV_PART_INDICATOR); + + break; + } + case LV_EVENT_PRESSING: { + if (!progress_state.is_seeking) + break; + if (current_tick - progress_state.last_update_tick < 8) { + break; + } + progress_state.last_update_tick = current_tick; + + lv_point_t point; + lv_indev_t* indev = lv_indev_active(); + lv_indev_get_point(indev, &point); + + lv_area_t area; + lv_obj_get_coords(R.ui.playback_progress, &area); + + int32_t bar_width = lv_area_get_width(&area); + int32_t relative_x = point.x - area.x1; + + const int32_t touch_tolerance = 30; + if (relative_x < -touch_tolerance) + relative_x = 0; + else if (relative_x > bar_width + touch_tolerance) + relative_x = bar_width; + else if (relative_x < 0) + relative_x = 0; + else if (relative_x > bar_width) + relative_x = bar_width; + + uint64_t total_time = C.current_album->total_time; + uint64_t new_time = (uint64_t)relative_x * total_time / bar_width; + + if (new_time > total_time) + new_time = total_time; + + progress_state.seek_preview_time = new_time; + + progress_state.current_value = (int32_t)new_time; + lv_bar_set_value(R.ui.playback_progress, (int32_t)new_time, LV_ANIM_OFF); + + char buff[16]; + uint32_t preview_min = new_time / 60000; + uint32_t preview_sec = (new_time % 60000) / 1000; + lv_snprintf(buff, sizeof(buff), "%02d:%02d", preview_min, preview_sec); + lv_span_set_text(R.ui.playback_current_time, buff); + break; + } + case LV_EVENT_RELEASED: { + if (!progress_state.is_seeking) + break; + + progress_state.is_seeking = false; + lv_obj_set_height(R.ui.playback_progress, 8); + lv_obj_set_style_bg_color(R.ui.playback_progress, lv_color_hex(0xFF4757), + LV_PART_INDICATOR); + lv_obj_set_style_shadow_width(R.ui.playback_progress, 0, LV_PART_INDICATOR); + lv_obj_set_style_radius(R.ui.playback_progress, 4, LV_PART_INDICATOR); + lv_obj_set_style_transform_zoom(R.ui.playback_progress, 256, + LV_PART_INDICATOR); + uint64_t seek_time = progress_state.seek_preview_time; + if (seek_time > C.current_album->total_time) { + seek_time = C.current_album->total_time; + } + + if (C.audioctl && seek_time <= C.current_album->total_time) { + int seek_result = audio_ctl_seek(C.audioctl, seek_time); + + if (seek_result == 0) { + C.current_time = seek_time; + progress_state.current_value = (int32_t)seek_time; + progress_state.target_value = (int32_t)seek_time; + app_refresh_playback_progress(); + } else { + C.current_time = progress_state.current_value; + app_refresh_playback_progress(); + } + } else { + app_refresh_playback_progress(); + } + if (progress_state.was_playing) { + if (C.play_status == PLAY_STATUS_PAUSE) { + if (C.audioctl) { + audio_ctl_resume(C.audioctl); + app_set_play_status(PLAY_STATUS_PLAY); + } + } + } + if (C.timers.playback_progress_update) { + lv_timer_resume(C.timers.playback_progress_update); + } + progress_state.smooth_update_enabled = true; + break; + } + case LV_EVENT_CLICKED: { + if (progress_state.is_seeking) + break; + + lv_point_t point; + lv_indev_t* indev = lv_indev_active(); + lv_indev_get_point(indev, &point); + lv_area_t area; + lv_obj_get_coords(R.ui.playback_progress, &area); + + int32_t bar_width = lv_area_get_width(&area); + int32_t relative_x = point.x - area.x1; + + if (relative_x < 0) + relative_x = 0; + if (relative_x > bar_width) + relative_x = bar_width; + + uint64_t total_time = C.current_album->total_time; + uint64_t new_time = (uint64_t)relative_x * total_time / bar_width; + + if (new_time > total_time) + new_time = total_time; + lv_bar_set_value(R.ui.playback_progress, (int32_t)new_time, LV_ANIM_ON); + if (C.audioctl) { + int seek_result = audio_ctl_seek(C.audioctl, new_time); + + if (seek_result == 0) { + C.current_time = new_time; + char buff[16]; + uint32_t current_min = new_time / 60000; + uint32_t current_sec = (new_time % 60000) / 1000; + lv_snprintf(buff, sizeof(buff), "%02d:%02d", current_min, current_sec); + lv_span_set_text(R.ui.playback_current_time, buff); + } else { + app_refresh_playback_progress(); + } + } + break; + } + case LV_EVENT_PRESS_LOST: { + if (progress_state.is_seeking) { + progress_state.is_seeking = false; + + lv_obj_set_height(R.ui.playback_progress, 8); + lv_obj_set_style_bg_color(R.ui.playback_progress, lv_color_hex(0xFF4757), + LV_PART_INDICATOR); + lv_obj_set_style_shadow_width(R.ui.playback_progress, 0, + LV_PART_INDICATOR); + lv_obj_set_style_radius(R.ui.playback_progress, 4, LV_PART_INDICATOR); + lv_obj_set_style_transform_zoom(R.ui.playback_progress, 256, + LV_PART_INDICATOR); + + if (C.timers.playback_progress_update) { + lv_timer_resume(C.timers.playback_progress_update); + } + app_refresh_playback_progress(); + } + break; + } + case LV_EVENT_LONG_PRESSED: { + if (!progress_state.is_seeking) { + progress_state.is_seeking = true; + progress_state.was_playing = (C.play_status == PLAY_STATUS_PLAY); + progress_state.last_update_tick = current_tick; + lv_anim_delete(R.ui.playback_progress, progress_smooth_anim_cb); + if (C.timers.playback_progress_update) { + lv_timer_pause(C.timers.playback_progress_update); + } + } + lv_obj_set_height(R.ui.playback_progress, 16); + lv_obj_set_style_bg_color(R.ui.playback_progress, lv_color_hex(0x00C851), + LV_PART_INDICATOR); + lv_obj_set_style_shadow_width(R.ui.playback_progress, 8, LV_PART_INDICATOR); + lv_obj_set_style_shadow_color(R.ui.playback_progress, + lv_color_hex(0x00C851), LV_PART_INDICATOR); + lv_obj_set_style_shadow_opa(R.ui.playback_progress, LV_OPA_80, + LV_PART_INDICATOR); + lv_obj_set_style_radius(R.ui.playback_progress, 8, LV_PART_INDICATOR); + lv_obj_set_style_transform_zoom(R.ui.playback_progress, 256 + 30, + LV_PART_INDICATOR); + break; + } + default: + break; + } +} + +static bool init_resource(void) { + R.fonts.size_16.normal = &lv_font_montserrat_16; + R.fonts.size_22.bold = &lv_font_montserrat_22; + R.fonts.size_24.normal = &lv_font_montserrat_24; + R.fonts.size_28.normal = &lv_font_montserrat_32; + R.fonts.size_60.bold = &lv_font_montserrat_32; + + if (R.fonts.size_16.normal == NULL || R.fonts.size_22.bold == NULL || R.fonts.size_24.normal == NULL || R.fonts.size_28.normal == NULL || R.fonts.size_60.bold == NULL) { + return false; + } + + lv_style_init(&R.styles.button_default); + lv_style_init(&R.styles.button_pressed); + lv_style_init(&R.styles.circular_cover); + lv_style_init(&R.styles.vinyl_ring); + lv_style_init(&R.styles.vinyl_center); + lv_style_init(&R.styles.gradient_progress); + lv_style_init(&R.styles.frosted_glass); + lv_style_init(&R.styles.modern_card); + + lv_style_set_opa(&R.styles.button_default, LV_OPA_COVER); + lv_style_set_opa(&R.styles.button_pressed, LV_OPA_80); + lv_style_set_shadow_width(&R.styles.button_default, 8); + lv_style_set_shadow_color(&R.styles.button_default, MODERN_PRIMARY_COLOR); + lv_style_set_shadow_opa(&R.styles.button_default, LV_OPA_40); + lv_style_set_shadow_width(&R.styles.button_pressed, 15); + lv_style_set_shadow_color(&R.styles.button_pressed, MODERN_PRIMARY_COLOR); + lv_style_set_shadow_opa(&R.styles.button_pressed, LV_OPA_60); + lv_style_set_border_width(&R.styles.button_default, 2); + lv_style_set_border_color(&R.styles.button_default, lv_color_hex(0x4B5563)); + lv_style_set_border_opa(&R.styles.button_default, LV_OPA_50); + lv_style_set_border_width(&R.styles.button_pressed, 2); + lv_style_set_border_color(&R.styles.button_pressed, MODERN_PRIMARY_COLOR); + lv_style_set_border_opa(&R.styles.button_pressed, LV_OPA_80); + + lv_style_set_radius(&R.styles.circular_cover, LV_RADIUS_CIRCLE); + lv_style_set_border_width(&R.styles.circular_cover, 6); + lv_style_set_border_color(&R.styles.circular_cover, lv_color_hex(0x3B82F6)); + lv_style_set_border_opa(&R.styles.circular_cover, LV_OPA_80); + lv_style_set_shadow_width(&R.styles.circular_cover, 25); + lv_style_set_shadow_color(&R.styles.circular_cover, lv_color_hex(0x3B82F6)); + lv_style_set_shadow_opa(&R.styles.circular_cover, LV_OPA_30); + lv_style_set_shadow_spread(&R.styles.circular_cover, 5); + + lv_style_set_radius(&R.styles.vinyl_ring, LV_RADIUS_CIRCLE); + lv_style_set_border_width(&R.styles.vinyl_ring, 8); + lv_style_set_border_color(&R.styles.vinyl_ring, lv_color_hex(0x1A1A1A)); + lv_style_set_border_opa(&R.styles.vinyl_ring, LV_OPA_COVER); + lv_style_set_bg_color(&R.styles.vinyl_ring, lv_color_hex(0x0F0F0F)); + lv_style_set_bg_opa(&R.styles.vinyl_ring, LV_OPA_30); + lv_style_set_shadow_width(&R.styles.vinyl_ring, 30); + lv_style_set_shadow_color(&R.styles.vinyl_ring, lv_color_hex(0x000000)); + lv_style_set_shadow_opa(&R.styles.vinyl_ring, LV_OPA_70); + lv_style_set_shadow_spread(&R.styles.vinyl_ring, 8); + + lv_style_set_radius(&R.styles.vinyl_center, LV_RADIUS_CIRCLE); + lv_style_set_bg_color(&R.styles.vinyl_center, lv_color_hex(0x1A1A1A)); + lv_style_set_bg_opa(&R.styles.vinyl_center, LV_OPA_COVER); + lv_style_set_border_width(&R.styles.vinyl_center, 2); + lv_style_set_border_color(&R.styles.vinyl_center, lv_color_hex(0x333333)); + lv_style_set_border_opa(&R.styles.vinyl_center, LV_OPA_COVER); + + lv_style_set_bg_color(&R.styles.gradient_progress, MODERN_PRIMARY_COLOR); + lv_style_set_bg_grad_color(&R.styles.gradient_progress, + MODERN_SECONDARY_COLOR); + lv_style_set_bg_grad_dir(&R.styles.gradient_progress, LV_GRAD_DIR_HOR); + lv_style_set_radius(&R.styles.gradient_progress, 10); + + lv_style_set_bg_color(&R.styles.frosted_glass, lv_color_hex(0x1E1E1E)); + lv_style_set_bg_opa(&R.styles.frosted_glass, LV_OPA_70); + lv_style_set_radius(&R.styles.frosted_glass, 20); + + lv_style_set_bg_color(&R.styles.modern_card, MODERN_CARD_COLOR); + lv_style_set_bg_opa(&R.styles.modern_card, LV_OPA_90); + lv_style_set_radius(&R.styles.modern_card, 25); + lv_style_set_shadow_width(&R.styles.modern_card, 15); + lv_style_set_shadow_color(&R.styles.modern_card, lv_color_black()); + lv_style_set_shadow_opa(&R.styles.modern_card, LV_OPA_30); + + lv_style_transition_dsc_init(&R.styles.transition_dsc, transition_props, + &lv_anim_path_ease_in_out, 300, 0, NULL); + lv_style_transition_dsc_init(&R.styles.button_transition_dsc, + transition_props, &lv_anim_path_ease_in_out, 150, + 0, NULL); + lv_style_set_transition(&R.styles.button_default, + &R.styles.button_transition_dsc); + lv_style_set_transition(&R.styles.button_pressed, + &R.styles.button_transition_dsc); + + R.images.playlist = ICONS_ROOT "/playlist.png"; + R.images.previous = ICONS_ROOT "/previous.png"; + R.images.play = ICONS_ROOT "/play.png"; + R.images.pause = ICONS_ROOT "/pause.png"; + R.images.next = ICONS_ROOT "/next.png"; + R.images.audio = ICONS_ROOT "/audio.png"; + R.images.mute = ICONS_ROOT "/mute.png"; + R.images.music = ICONS_ROOT "/music.png"; + R.images.nocover = ICONS_ROOT "/nocover.png"; + + R.images.background = NULL; + + reload_music_config(); + + return true; +} + +static void app_create_top_layer(void) { + lv_obj_t* top_layer = lv_layer_top(); + lv_obj_set_scroll_dir(top_layer, LV_DIR_NONE); + lv_obj_set_style_bg_color(top_layer, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_bg_opa(top_layer, LV_OPA_COVER, LV_STATE_USER_1); + lv_obj_set_style_bg_opa(top_layer, LV_OPA_0, LV_STATE_DEFAULT); + lv_obj_set_style_transition(top_layer, &R.styles.transition_dsc, + LV_STATE_DEFAULT); + lv_obj_set_style_transition(top_layer, &R.styles.transition_dsc, + LV_STATE_USER_1); + + R.ui.volume_bar = lv_obj_create(top_layer); + lv_obj_remove_style_all(R.ui.volume_bar); + lv_obj_set_size(R.ui.volume_bar, 60, 180); + lv_obj_set_style_bg_color(R.ui.volume_bar, lv_color_hex(0x444444), + LV_PART_MAIN); + lv_obj_set_style_bg_opa(R.ui.volume_bar, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_opa(R.ui.volume_bar, LV_OPA_0, LV_STATE_DEFAULT); + lv_obj_set_style_opa(R.ui.volume_bar, LV_OPA_COVER, LV_STATE_USER_1); + lv_obj_set_style_border_width(R.ui.volume_bar, 0, LV_PART_MAIN); + lv_obj_set_style_radius(R.ui.volume_bar, 16, LV_PART_MAIN); + lv_obj_set_style_clip_corner(R.ui.volume_bar, true, LV_PART_MAIN); + lv_obj_align(R.ui.volume_bar, LV_ALIGN_BOTTOM_RIGHT, -45, -95); + lv_obj_set_style_transition(R.ui.volume_bar, &R.styles.transition_dsc, + LV_STATE_DEFAULT); + + R.ui.volume_bar_indic = lv_obj_create(R.ui.volume_bar); + lv_obj_remove_style_all(R.ui.volume_bar_indic); + lv_obj_set_style_bg_color(R.ui.volume_bar_indic, lv_color_white(), + LV_PART_MAIN); + lv_obj_set_style_bg_opa(R.ui.volume_bar_indic, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_size(R.ui.volume_bar_indic, LV_PCT(100), 40); + lv_obj_align(R.ui.volume_bar_indic, LV_ALIGN_BOTTOM_MID, 0, 0); + + R.ui.playlist_base = NULL; + R.ui.playlist = NULL; + + lv_obj_add_flag(R.ui.volume_bar_indic, LV_OBJ_FLAG_EVENT_BUBBLE); + lv_obj_add_event_cb(R.ui.volume_bar, app_volume_bar_event_handler, + LV_EVENT_ALL, NULL); +} + +static void app_create_error_page(void) { + lv_obj_t* root = lv_screen_active(); + lv_obj_t* label = lv_label_create(root); + lv_obj_set_width(label, LV_PCT(80)); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + lv_label_set_text(label, "Vela Music Player\nResource loading failed\nPlease " + "check device and configuration"); + lv_obj_set_style_text_font(label, &lv_font_montserrat_32, LV_PART_MAIN); + lv_obj_set_style_text_color(label, lv_color_hex(0xFF6B6B), LV_PART_MAIN); + lv_obj_center(label); +} + +static void app_create_main_page(void) { + lv_obj_t* root = lv_screen_active(); + + lv_obj_set_style_bg_color(root, lv_color_hex(0x121212), LV_PART_MAIN); + lv_obj_set_style_bg_grad_color(root, lv_color_hex(0x0F0F0F), LV_PART_MAIN); + lv_obj_set_style_bg_grad_dir(root, LV_GRAD_DIR_VER, LV_PART_MAIN); + lv_obj_set_style_bg_opa(root, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_border_width(root, 0, LV_PART_MAIN); + lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(root, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(root, 16, LV_PART_MAIN); + + lv_obj_t* status_bar = lv_obj_create(root); + lv_obj_remove_style_all(status_bar); + lv_obj_set_size(status_bar, LV_PCT(100), 48); + lv_obj_add_style(status_bar, &R.styles.frosted_glass, LV_PART_MAIN); + lv_obj_set_style_pad_hor(status_bar, 20, LV_PART_MAIN); + lv_obj_set_style_pad_ver(status_bar, 8, LV_PART_MAIN); + lv_obj_set_flex_flow(status_bar, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(status_bar, LV_FLEX_ALIGN_SPACE_BETWEEN, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t* brand_label = lv_label_create(status_bar); + lv_label_set_text(brand_label, "openvela"); + lv_obj_set_style_text_font(brand_label, R.fonts.size_22.bold, LV_PART_MAIN); + lv_obj_set_style_text_color(brand_label, lv_color_hex(0x3B82F6), + LV_PART_MAIN); + + lv_obj_t* status_info = lv_obj_create(status_bar); + lv_obj_remove_style_all(status_info); + lv_obj_set_size(status_info, LV_PCT(60), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(status_info, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(status_info, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + lv_obj_t* wifi_label = lv_label_create(status_info); + lv_label_set_text(wifi_label, "WiFi"); + lv_obj_set_style_text_font(wifi_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(wifi_label, lv_color_hex(0xBBBBBB), LV_PART_MAIN); + lv_obj_set_style_margin_right(wifi_label, 16, LV_PART_MAIN); + + lv_obj_t* battery_label = lv_label_create(status_info); + lv_label_set_text(battery_label, "85%"); + lv_obj_set_style_text_font(battery_label, R.fonts.size_16.normal, + LV_PART_MAIN); + lv_obj_set_style_text_color(battery_label, lv_color_hex(0xBBBBBB), + LV_PART_MAIN); + lv_obj_set_style_margin_right(battery_label, 20, LV_PART_MAIN); + + lv_obj_t* time_container = lv_obj_create(status_info); + lv_obj_remove_style_all(time_container); + lv_obj_set_size(time_container, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_flex_flow(time_container, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(time_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_END, + LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(time_container, 0, LV_PART_MAIN); + + lv_obj_t* time_label = lv_label_create(time_container); + R.ui.time = time_label; + lv_label_set_text(time_label, "14:28"); + lv_obj_set_style_text_font(time_label, R.fonts.size_24.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(time_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + lv_obj_set_style_text_align(time_label, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN); + lv_obj_set_style_margin_bottom(time_label, 2, LV_PART_MAIN); + + lv_obj_t* date_label = lv_label_create(time_container); + R.ui.date = date_label; + lv_label_set_text(date_label, "Monday"); + lv_obj_set_style_text_font(date_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(date_label, lv_color_hex(0xBBBBBB), LV_PART_MAIN); + lv_obj_set_style_text_align(date_label, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN); + + lv_obj_t* player_main = lv_obj_create(root); + R.ui.player_group = player_main; + lv_obj_remove_style_all(player_main); + lv_obj_add_style(player_main, &R.styles.modern_card, LV_PART_MAIN); + lv_obj_set_size(player_main, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(player_main, 32, LV_PART_MAIN); + lv_obj_set_flex_flow(player_main, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(player_main, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + lv_obj_set_flex_grow(player_main, 1); + + lv_obj_t* cover_section = lv_obj_create(player_main); + lv_obj_remove_style_all(cover_section); + lv_obj_set_size(cover_section, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(cover_section, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(cover_section, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_margin_bottom(cover_section, 24, LV_PART_MAIN); + + lv_obj_t* album_container = lv_obj_create(cover_section); + R.ui.album_cover_container = album_container; + lv_obj_remove_style_all(album_container); + lv_obj_set_size(album_container, 320, 320); + lv_obj_set_style_transform_pivot_x(album_container, 160, 0); + lv_obj_set_style_transform_pivot_y(album_container, 160, 0); + + lv_obj_t* vinyl_ring = lv_obj_create(album_container); + R.ui.vinyl_ring = vinyl_ring; + lv_obj_remove_style_all(vinyl_ring); + lv_obj_add_style(vinyl_ring, &R.styles.vinyl_ring, LV_PART_MAIN); + lv_obj_set_size(vinyl_ring, 320, 320); + lv_obj_center(vinyl_ring); + + lv_obj_t* album_cover = lv_image_create(album_container); + R.ui.album_cover = album_cover; + lv_obj_remove_style_all(album_cover); + lv_obj_add_style(album_cover, &R.styles.circular_cover, LV_PART_MAIN); + lv_obj_set_size(album_cover, 280, 280); + lv_obj_center(album_cover); + + lv_image_set_scale(album_cover, 256); + lv_image_set_inner_align(album_cover, LV_IMAGE_ALIGN_CENTER); + lv_image_set_pivot(album_cover, 140, 140); + + lv_image_set_src(album_cover, R.images.nocover); + + lv_obj_set_style_clip_corner(album_cover, true, LV_PART_MAIN); + lv_obj_set_style_bg_img_recolor_opa(album_cover, LV_OPA_0, LV_PART_MAIN); + lv_obj_set_style_image_recolor_opa(album_cover, LV_OPA_0, LV_PART_MAIN); + + lv_obj_set_style_bg_image_opa(album_cover, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_radius(album_cover, LV_RADIUS_CIRCLE, LV_PART_MAIN); + + R.ui.vinyl_center = NULL; + + lv_obj_t* song_info = lv_obj_create(player_main); + lv_obj_remove_style_all(song_info); + lv_obj_set_size(song_info, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(song_info, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(song_info, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_margin_bottom(song_info, 20, LV_PART_MAIN); + + lv_obj_t* song_title = lv_label_create(song_info); + R.ui.album_name = song_title; + lv_label_set_text(song_title, "Select Your Music"); + lv_label_set_long_mode(song_title, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_width(song_title, LV_PCT(90)); + lv_obj_set_style_text_align(song_title, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + lv_obj_set_style_text_font(song_title, R.fonts.size_28.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(song_title, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + lv_obj_set_style_margin_bottom(song_title, 12, LV_PART_MAIN); + + lv_obj_t* artist_name = lv_label_create(song_info); + R.ui.album_artist = artist_name; + lv_label_set_text(artist_name, "Vela Music"); + lv_label_set_long_mode(artist_name, LV_LABEL_LONG_SCROLL); + lv_obj_set_width(artist_name, LV_PCT(80)); + lv_obj_set_style_text_align(artist_name, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + lv_obj_set_style_text_font(artist_name, R.fonts.size_22.bold, LV_PART_MAIN); + lv_obj_set_style_text_color(artist_name, lv_color_hex(0xE5E7EB), + LV_PART_MAIN); + + lv_obj_t* progress_section = lv_obj_create(player_main); + R.ui.playback_group = progress_section; + lv_obj_remove_style_all(progress_section); + lv_obj_set_size(progress_section, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(progress_section, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(progress_section, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_margin_bottom(progress_section, 24, LV_PART_MAIN); + + lv_obj_t* progress_bar_container = lv_obj_create(progress_section); + lv_obj_remove_style_all(progress_bar_container); + lv_obj_set_size(progress_bar_container, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(progress_bar_container, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(progress_bar_container, LV_FLEX_ALIGN_SPACE_BETWEEN, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_margin_bottom(progress_bar_container, 12, LV_PART_MAIN); + lv_obj_set_style_pad_all(progress_bar_container, 0, LV_PART_MAIN); + + lv_obj_t* progress_bar = lv_bar_create(progress_bar_container); + R.ui.playback_progress = progress_bar; + lv_obj_remove_style_all(progress_bar); + lv_obj_add_style(progress_bar, &R.styles.gradient_progress, + LV_PART_INDICATOR); + lv_obj_set_size(progress_bar, LV_PCT(65), 6); + lv_obj_set_style_bg_color(progress_bar, lv_color_hex(0x374151), LV_PART_MAIN); + lv_obj_set_style_bg_opa(progress_bar, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_radius(progress_bar, 3, LV_PART_MAIN); + + lv_obj_t* time_display = lv_spangroup_create(progress_bar_container); + lv_span_t* current_time = lv_spangroup_new_span(time_display); + lv_span_t* separator = lv_spangroup_new_span(time_display); + lv_span_t* total_time = lv_spangroup_new_span(time_display); + R.ui.playback_current_time = current_time; + R.ui.playback_total_time = total_time; + + lv_span_set_text(current_time, "00:00"); + lv_span_set_text(separator, " / "); + lv_span_set_text(total_time, "00:00"); + lv_obj_set_style_text_font(time_display, R.fonts.size_22.bold, LV_PART_MAIN); + lv_obj_set_style_text_color(time_display, lv_color_hex(0x3B82F6), + LV_PART_MAIN); + lv_obj_set_style_text_align(time_display, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN); + lv_obj_set_style_margin_right(time_display, 8, LV_PART_MAIN); + lv_style_set_text_color(&separator->style, lv_color_hex(0x9CA3AF)); + lv_style_set_text_color(&total_time->style, lv_color_hex(0x9CA3AF)); + + lv_obj_t* control_area = lv_obj_create(player_main); + lv_obj_remove_style_all(control_area); + lv_obj_set_size(control_area, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(control_area, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(control_area, LV_FLEX_ALIGN_SPACE_EVENLY, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(control_area, 20, LV_PART_MAIN); + lv_obj_set_style_pad_column(control_area, 16, LV_PART_MAIN); + + lv_obj_t* playlist_btn = lv_button_create(control_area); + lv_obj_t* playlist_icon = lv_image_create(playlist_btn); + lv_obj_remove_style_all(playlist_btn); + + lv_obj_set_style_bg_color(playlist_btn, lv_color_hex(0x374151), LV_PART_MAIN); + lv_obj_set_style_bg_color(playlist_btn, lv_color_hex(0x4B5563), + LV_PART_MAIN | LV_STATE_PRESSED); + + lv_image_set_src(playlist_icon, R.images.playlist); + lv_obj_set_size(playlist_icon, 28, 28); + lv_obj_center(playlist_icon); + + lv_obj_t* prev_btn = lv_button_create(control_area); + lv_obj_t* prev_icon = lv_image_create(prev_btn); + lv_obj_remove_style_all(prev_btn); + + lv_obj_set_style_bg_color(prev_btn, lv_color_hex(0x374151), LV_PART_MAIN); + lv_obj_set_style_bg_color(prev_btn, lv_color_hex(0x4B5563), + LV_PART_MAIN | LV_STATE_PRESSED); + + lv_image_set_src(prev_icon, R.images.previous); + lv_obj_set_size(prev_icon, 32, 32); + lv_obj_center(prev_icon); + + lv_obj_t* play_btn = lv_button_create(control_area); + lv_obj_t* play_icon = lv_image_create(play_btn); + R.ui.play_btn = play_icon; + lv_obj_remove_style_all(play_btn); + + lv_obj_set_style_bg_color(play_btn, lv_color_hex(0x374151), LV_PART_MAIN); + lv_obj_set_style_bg_color(play_btn, lv_color_hex(0x4B5563), + LV_PART_MAIN | LV_STATE_PRESSED); + + lv_obj_set_style_shadow_width(play_btn, 25, LV_STATE_DEFAULT); + lv_obj_set_style_shadow_width(play_btn, 35, LV_STATE_PRESSED); + lv_obj_set_style_shadow_color(play_btn, lv_color_hex(0x00BFFF), LV_PART_MAIN); + lv_obj_set_style_shadow_opa(play_btn, LV_OPA_70, LV_STATE_DEFAULT); + lv_obj_set_style_shadow_opa(play_btn, LV_OPA_90, LV_STATE_PRESSED); + + lv_image_set_src(play_icon, R.images.play); + lv_obj_set_size(play_icon, 48, 48); + lv_obj_center(play_icon); + + lv_obj_t* next_btn = lv_button_create(control_area); + lv_obj_t* next_icon = lv_image_create(next_btn); + lv_obj_remove_style_all(next_btn); + + lv_obj_set_style_bg_color(next_btn, lv_color_hex(0x374151), LV_PART_MAIN); + lv_obj_set_style_bg_color(next_btn, lv_color_hex(0x4B5563), + LV_PART_MAIN | LV_STATE_PRESSED); + + lv_image_set_src(next_icon, R.images.next); + lv_obj_set_size(next_icon, 32, 32); + lv_obj_center(next_icon); + + lv_obj_t* volume_btn = lv_button_create(control_area); + lv_obj_t* volume_icon = lv_image_create(volume_btn); + R.ui.audio = volume_icon; + lv_obj_remove_style_all(volume_btn); + + lv_obj_set_style_bg_color(volume_btn, lv_color_hex(0x374151), LV_PART_MAIN); + lv_obj_set_style_bg_color(volume_btn, lv_color_hex(0x4B5563), + LV_PART_MAIN | LV_STATE_PRESSED); + + lv_obj_set_size(volume_icon, 28, 28); + lv_obj_center(volume_icon); + + app_create_top_layer(); + + lv_obj_add_event_cb(playlist_btn, app_playlist_event_handler, + LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(playlist_btn, app_playlist_event_handler, + LV_EVENT_PRESSED, NULL); + lv_obj_add_event_cb(playlist_btn, app_playlist_event_handler, + LV_EVENT_RELEASED, NULL); + + lv_obj_add_event_cb(volume_btn, app_audio_event_handler, LV_EVENT_CLICKED, + NULL); + lv_obj_add_event_cb(volume_btn, app_audio_event_handler, LV_EVENT_PRESSED, + NULL); + lv_obj_add_event_cb(volume_btn, app_audio_event_handler, LV_EVENT_RELEASED, + NULL); + + lv_obj_add_event_cb(play_btn, app_play_status_event_handler, LV_EVENT_CLICKED, + NULL); + lv_obj_add_event_cb(play_btn, app_play_status_event_handler, LV_EVENT_PRESSED, + NULL); + lv_obj_add_event_cb(play_btn, app_play_status_event_handler, + LV_EVENT_RELEASED, NULL); + + lv_obj_add_event_cb(prev_btn, app_switch_album_event_handler, + LV_EVENT_CLICKED, (lv_uintptr_t*)SWITCH_ALBUM_MODE_PREV); + lv_obj_add_event_cb(prev_btn, app_switch_album_event_handler, + LV_EVENT_PRESSED, (lv_uintptr_t*)SWITCH_ALBUM_MODE_PREV); + lv_obj_add_event_cb(prev_btn, app_switch_album_event_handler, + LV_EVENT_RELEASED, + (lv_uintptr_t*)SWITCH_ALBUM_MODE_PREV); + + lv_obj_add_event_cb(next_btn, app_switch_album_event_handler, + LV_EVENT_CLICKED, (lv_uintptr_t*)SWITCH_ALBUM_MODE_NEXT); + lv_obj_add_event_cb(next_btn, app_switch_album_event_handler, + LV_EVENT_PRESSED, (lv_uintptr_t*)SWITCH_ALBUM_MODE_NEXT); + lv_obj_add_event_cb(next_btn, app_switch_album_event_handler, + LV_EVENT_RELEASED, + (lv_uintptr_t*)SWITCH_ALBUM_MODE_NEXT); + + lv_obj_add_event_cb(prev_btn, app_switch_album_event_handler, + LV_EVENT_LONG_PRESSED_REPEAT, + (lv_uintptr_t*)SWITCH_ALBUM_MODE_PREV); + lv_obj_add_event_cb(next_btn, app_switch_album_event_handler, + LV_EVENT_LONG_PRESSED_REPEAT, + (lv_uintptr_t*)SWITCH_ALBUM_MODE_NEXT); + + lv_obj_add_event_cb(progress_bar, app_playback_progress_bar_event_handler, + LV_EVENT_ALL, NULL); + lv_obj_set_ext_click_area(progress_bar, 15); + + lv_obj_set_ext_click_area(R.ui.volume_bar, 10); + + app_start_updating_date_time(); +} + +static void app_start_updating_date_time(void) { + if (!R.ui.time || !R.ui.date) { + LV_LOG_ERROR("Time/Date UI components not ready, cannot start timer"); + return; + } + + LV_LOG_USER("Starting date/time update system..."); + + app_refresh_date_time(); + + if (C.timers.refresh_date_time != NULL) { + lv_timer_delete(C.timers.refresh_date_time); + C.timers.refresh_date_time = NULL; + } + + C.timers.refresh_date_time = lv_timer_create(app_refresh_date_time_timer_cb, 1000, NULL); + if (C.timers.refresh_date_time == NULL) { + LV_LOG_ERROR("Failed to create date/time update timer"); + return; + } + + LV_LOG_USER( + "Date/Time update timer created successfully - updating every 1000ms"); +} + +static void read_configs(void) { + uint32_t file_size; + lv_fs_file_t file; + lv_fs_open(&file, RES_ROOT "/config.json", LV_FS_MODE_RD); + + lv_fs_seek(&file, 0, LV_FS_SEEK_END); + lv_fs_tell(&file, &file_size); + lv_fs_seek(&file, 0, LV_FS_SEEK_SET); + + char* buff = lv_malloc(file_size); + lv_fs_read(&file, buff, file_size, NULL); + + const char* json_string = buff; + + cJSON* json = cJSON_Parse(json_string); + if (json == NULL) { + const char* error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) { + LV_LOG_ERROR("parse error: %p", error_ptr); + } + lv_free(buff); + return; + } + +#if WIFI_ENABLED + cJSON* wifi_object = cJSON_GetObjectItem(json, "wifi"); + + const char* ssid = cJSON_GetStringValue(cJSON_GetObjectItem(wifi_object, "ssid")); + const char* pswd = cJSON_GetStringValue(cJSON_GetObjectItem(wifi_object, "pswd")); + const int version = cJSON_GetNumberValue(cJSON_GetObjectItem(wifi_object, "wpa_ver")); + + lv_strcpy(CF.wifi.ssid, ssid); + lv_strcpy(CF.wifi.pswd, pswd); + CF.wifi.ver_flag = version; +#endif + + cJSON_Delete(json); + + lv_free(buff); +} + +static void reload_music_config(void) { + LV_LOG_USER("Starting to reload music configuration..."); + + if (R.albums) { + for (int i = 0; i < R.album_count; i++) { + if (R.albums[i].name) { + lv_free((void*)R.albums[i].name); + R.albums[i].name = NULL; + } + if (R.albums[i].artist) { + lv_free((void*)R.albums[i].artist); + R.albums[i].artist = NULL; + } + memset(R.albums[i].path, 0, sizeof(R.albums[i].path)); + memset(R.albums[i].cover, 0, sizeof(R.albums[i].cover)); + } + + lv_free(R.albums); + R.albums = NULL; + } + + R.album_count = 0; + + uint32_t file_size; + lv_fs_file_t file; + char* buff = NULL; + cJSON* json = NULL; + + lv_fs_res_t res = lv_fs_open(&file, MUSICS_ROOT "/manifest.json", LV_FS_MODE_RD); + if (res != LV_FS_RES_OK) { + static const char* candidates[] = { + "/data/res/musics", + "res/musics", + "./res/musics", + "/sdcard/res/musics", + }; + for (size_t i = 0; i < sizeof(candidates) / sizeof(candidates[0]); i++) { + char manifest_path[384]; + lv_snprintf(manifest_path, sizeof(manifest_path), "%s/manifest.json", + candidates[i]); + res = lv_fs_open(&file, manifest_path, LV_FS_MODE_RD); + if (res == LV_FS_RES_OK) { + lv_snprintf(g_musics_root, sizeof(g_musics_root), "%s", candidates[i]); + LV_LOG_USER("Using discovered musics root: %s", g_musics_root); + break; + } + } + if (res != LV_FS_RES_OK) { + LV_LOG_ERROR("Cannot open music manifest file in any known location"); + return; + } + } + if (res != LV_FS_RES_OK) { + LV_LOG_ERROR("Cannot open music manifest file: %s", + MUSICS_ROOT "/manifest.json"); + return; + } + + if (lv_fs_seek(&file, 0, LV_FS_SEEK_END) != LV_FS_RES_OK || lv_fs_tell(&file, &file_size) != LV_FS_RES_OK || lv_fs_seek(&file, 0, LV_FS_SEEK_SET) != LV_FS_RES_OK) { + LV_LOG_ERROR("File operation failed"); + lv_fs_close(&file); + return; + } + + if (file_size == 0 || file_size > 2 * 1024 * 1024) { + LV_LOG_ERROR("Music manifest file size abnormal: %lu bytes", + (unsigned long)file_size); + lv_fs_close(&file); + return; + } + + buff = lv_malloc(file_size + 1); + if (!buff) { + lv_fs_close(&file); + return; + } + + memset(buff, 0, file_size + 1); + + uint32_t bytes_read; + if (lv_fs_read(&file, buff, file_size, &bytes_read) != LV_FS_RES_OK || bytes_read != file_size) { + LV_LOG_ERROR( + "File read failed: expected %lu bytes, actually read %lu bytes", + (unsigned long)file_size, (unsigned long)bytes_read); + goto cleanup_and_exit; + } + + lv_fs_close(&file); + + json = cJSON_Parse(buff); + if (json == NULL) { + const char* error_ptr = cJSON_GetErrorPtr(); + LV_LOG_ERROR("JSON parsing error: %s", + error_ptr ? error_ptr : "unknown error"); + goto cleanup_and_exit; + } + + cJSON* musics_object = cJSON_GetObjectItem(json, "musics"); + if (musics_object == NULL) { + LV_LOG_ERROR("'musics' object not found in JSON"); + goto cleanup_and_exit; + } + + int total_albums = cJSON_GetArraySize(musics_object); +#define MAX_SAFE_ALBUMS 50 + R.album_count = (total_albums > MAX_SAFE_ALBUMS) ? MAX_SAFE_ALBUMS : total_albums; + + LV_LOG_USER("Found %d albums in JSON, loading %d", total_albums, + R.album_count); + + R.albums = lv_malloc_zeroed(R.album_count * sizeof(album_info_t)); + if (!R.albums) { + lv_free(buff); + return; + } + + for (int i = 0; i < R.album_count; i++) { + cJSON* music_object = cJSON_GetArrayItem(musics_object, i); + if (!music_object) { + continue; + } + + const char* path = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "path")); + const char* name = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "name")); + const char* artist = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "artist")); + const char* cover = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "cover")); + const double total_time_double = cJSON_GetNumberValue(cJSON_GetObjectItem(music_object, "total_time")); + const char* color_str = cJSON_GetStringValue(cJSON_GetObjectItem(music_object, "color")); + + if (!path || !name) { + continue; + } + + uint64_t total_time = (uint64_t)total_time_double; + LV_LOG_USER("Loading album %d: %s - %s", i, name, + artist ? artist : "Unknown Artist"); + uint32_t color_int = strtoul(color_str + 1, NULL, 16); + + if (total_time == 0) + total_time = 1; + + lv_color_t color = lv_color_hex(color_int); + + lv_snprintf(R.albums[i].path, sizeof(R.albums[i].path), "%s/%s", + g_musics_root, path); + lv_snprintf(R.albums[i].cover, sizeof(R.albums[i].cover), "%s/%s", + g_musics_root, cover); + R.albums[i].name = lv_strdup(name); + R.albums[i].artist = lv_strdup(artist); + R.albums[i].total_time = total_time; + R.albums[i].color = color; + + LV_LOG_USER("Album %d: %s - %s | %s %s %lu", i, R.albums[i].name, + R.albums[i].artist, R.albums[i].path, R.albums[i].cover, + (unsigned long)total_time); + } + + goto cleanup_success; + +cleanup_and_exit: + if (R.albums) { + lv_free(R.albums); + R.albums = NULL; + R.album_count = 0; + } + +cleanup_success: + if (json) { + cJSON_Delete(json); + json = NULL; + } + + if (buff) { + lv_free(buff); + buff = NULL; + } +} diff --git a/music_player2/music_player2.h b/music_player2/music_player2.h new file mode 100644 index 0000000000000000000000000000000000000000..f40d29b7b84b13ca80a8024fcd3525f89220e8a3 --- /dev/null +++ b/music_player2/music_player2.h @@ -0,0 +1,172 @@ +#ifndef LVGL_APP_H +#define LVGL_APP_H + +#include "audio_ctl.h" +#include "lvgl.h" +#include "wifi.h" + +#ifndef LV_FS_MAX_PATH_LENGTH +#define LV_FS_MAX_PATH_LENGTH 256 +#endif + +#define RES_ROOT CONFIG_LVX_MUSIC_PLAYER_DATA_ROOT "/res" +#define FONTS_ROOT RES_ROOT "/fonts" +#define ICONS_ROOT RES_ROOT "/icons" +#define MUSICS_ROOT RES_ROOT "/musics" + +typedef struct _album_info_t { + const char* name; + const char* artist; + char path[LV_FS_MAX_PATH_LENGTH]; + char cover[LV_FS_MAX_PATH_LENGTH]; + uint64_t total_time; + lv_color_t color; +} album_info_t; + +typedef enum _switch_album_mode_t { + SWITCH_ALBUM_MODE_PREV, + SWITCH_ALBUM_MODE_NEXT, +} switch_album_mode_t; + +typedef enum _play_status_t { + PLAY_STATUS_STOP, + PLAY_STATUS_PLAY, + PLAY_STATUS_PAUSE, +} play_status_t; + +struct resource_s { + struct { + lv_obj_t* time; + lv_obj_t* date; + + lv_obj_t* player_group; + + lv_obj_t* volume_bar; + lv_obj_t* volume_bar_indic; + lv_obj_t* audio; + lv_obj_t* playlist_base; + + lv_obj_t* album_cover_container; + lv_obj_t* album_cover; + lv_obj_t* vinyl_ring; + lv_obj_t* vinyl_center; + lv_obj_t* album_name; + lv_obj_t* album_artist; + + lv_obj_t* play_btn; + lv_obj_t* playback_group; + lv_obj_t* playback_progress; + lv_span_t* playback_current_time; + lv_span_t* playback_total_time; + + lv_obj_t* playlist; + lv_obj_t* frosted_bg; + lv_obj_t* backward_10s_btn; + lv_obj_t* forward_10s_btn; + lv_obj_t* wifi_status_label; + } ui; + + struct { + struct { + const lv_font_t* normal; + } size_16; + struct { + const lv_font_t* bold; + } size_22; + struct { + const lv_font_t* normal; + } size_24; + struct { + const lv_font_t* normal; + } size_28; + struct { + const lv_font_t* bold; + } size_60; + } fonts; + + struct { + lv_style_t button_default; + lv_style_t button_pressed; + lv_style_t circular_cover; + lv_style_t vinyl_ring; + lv_style_t vinyl_center; + lv_style_t gradient_progress; + lv_style_t frosted_glass; + lv_style_t modern_card; + lv_style_transition_dsc_t button_transition_dsc; + lv_style_transition_dsc_t transition_dsc; + lv_style_transition_dsc_t cover_rotation; + } styles; + + struct { + const char* playlist; + const char* previous; + const char* play; + const char* pause; + const char* next; + const char* audio; + const char* mute; + const char* music; + const char* nocover; + const char* background; + } images; + + album_info_t* albums; + uint8_t album_count; +}; + +struct ctx_s { + bool resource_healthy_check; + + album_info_t* current_album; + lv_obj_t* current_album_related_obj; + + uint16_t volume; + + play_status_t play_status_prev; + play_status_t play_status; + uint64_t current_time; + + struct { + lv_timer_t* volume_bar_countdown; + lv_timer_t* playback_progress_update; + lv_timer_t* refresh_date_time; + lv_timer_t* cover_rotation; + } timers; + + struct { + lv_anim_t cover_rotation_anim; + bool is_rotating; + int16_t rotation_angle; + } animations; + + audioctl_s* audioctl; +}; + +struct conf_s { +#if WIFI_ENABLED + wifi_conf_t wifi; +#endif +}; + +void app_create(void); +void splash_screen_create(void); + +void playlist_manager_create(lv_obj_t* parent); +void playlist_manager_refresh(void); +void playlist_manager_close(void); +bool playlist_manager_is_open(void); + +void app_set_play_status(play_status_t status); +void app_switch_to_album(int index); + +int wifi_manager_optimized_init(void); +int wifi_connect_optimized(const char* ssid, const char* password); +void wifi_start_connection_monitor(void); +void wifi_set_auto_reconnect(bool enabled); +void wifi_create_settings_ui(lv_obj_t* parent); +void wifi_manager_optimized_cleanup(void); + +void app_switch_to_album(int index); + +#endif // LVGL_APP_H diff --git a/music_player2/music_player2_main.c b/music_player2/music_player2_main.c new file mode 100644 index 0000000000000000000000000000000000000000..6fdeef280088ab0dc879796a8e364c6cf50a7ab8 --- /dev/null +++ b/music_player2/music_player2_main.c @@ -0,0 +1,58 @@ +#include <nuttx/config.h> +#include <unistd.h> +#include <uv.h> + +#include <lvgl/lvgl.h> + +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) { + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +#include "music_player2.h" + +int main(int argc, FAR char* argv[]) { + // Initialize LVGL + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + splash_screen_create(); + + lv_nuttx_uv_loop(&ui_loop, &result); + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/music_player2/playlist_manager.c b/music_player2/playlist_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..e78553d9414534ae62f9243c53891dd68833b184 --- /dev/null +++ b/music_player2/playlist_manager.c @@ -0,0 +1,146 @@ +#include "playlist_manager.h" +#include "font_config.h" +#include "music_player2.h" +#include <stdio.h> + +extern struct resource_s R; +extern struct ctx_s C; + +#define MAX_PLAYLIST_ITEMS 6 +#define PLAYLIST_ITEM_HEIGHT 70 +#define PLAYLIST_NO_ANIMATION +static lv_obj_t* playlist_container = NULL; +static bool playlist_is_open = false; + +static void create_playlist_item(lv_obj_t* parent, int index); +static void playlist_item_click_cb(lv_event_t* e); +static void playlist_close_cb(lv_event_t* e); +static void create_playlist_item(lv_obj_t* parent, int index) { + if (index >= R.album_count || index >= MAX_PLAYLIST_ITEMS) { + return; + } + + lv_obj_t* btn = lv_btn_create(parent); + if (!btn) + return; + + lv_obj_set_size(btn, LV_PCT(100), PLAYLIST_ITEM_HEIGHT); + lv_obj_set_style_bg_color(btn, lv_color_hex(0x333333), LV_PART_MAIN); + lv_obj_set_style_bg_color(btn, lv_color_hex(0x4A4A4A), + LV_PART_MAIN | LV_STATE_PRESSED); + lv_obj_set_style_radius(btn, 8, LV_PART_MAIN); + lv_obj_set_style_margin_bottom(btn, 4, LV_PART_MAIN); + + lv_obj_t* label = lv_label_create(btn); + if (!label) + return; + + char text[80]; + const char* name = R.albums[index].name ? R.albums[index].name : "Unknown"; + snprintf(text, sizeof(text), "%d. %s", index + 1, name); + lv_label_set_text(label, text); + lv_obj_center(label); + + const lv_font_t* playlist_font = get_playlist_font("song"); + if (playlist_font) { + lv_obj_set_style_text_font(label, playlist_font, LV_PART_MAIN); + } + + lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_add_event_cb(btn, playlist_item_click_cb, LV_EVENT_CLICKED, + (void*)(uintptr_t)index); +} + +static void playlist_item_click_cb(lv_event_t* e) { + int index = (int)(uintptr_t)lv_event_get_user_data(e); + + if (index >= 0 && index < R.album_count) { + extern void app_switch_to_album(int index); + app_switch_to_album(index); + playlist_manager_close(); + } +} + +static void playlist_close_cb(lv_event_t* e) { + playlist_manager_close(); +} + +void playlist_manager_create(lv_obj_t* parent) { + if (playlist_container || !parent) { + return; + } + + playlist_container = lv_obj_create(parent); + if (!playlist_container) { + return; + } + + lv_obj_remove_style_all(playlist_container); + lv_obj_set_size(playlist_container, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_bg_color(playlist_container, lv_color_hex(0x000000), + LV_PART_MAIN); + lv_obj_set_style_bg_opa(playlist_container, LV_OPA_80, LV_PART_MAIN); + + lv_obj_add_flag(playlist_container, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(playlist_container, playlist_close_cb, LV_EVENT_CLICKED, + NULL); + + lv_obj_t* content = lv_obj_create(playlist_container); + if (!content) { + lv_obj_del(playlist_container); + playlist_container = NULL; + return; + } + + lv_obj_remove_style_all(content); + lv_obj_set_size(content, LV_PCT(90), LV_PCT(80)); + lv_obj_center(content); + lv_obj_set_style_bg_color(content, lv_color_hex(0x222222), LV_PART_MAIN); + lv_obj_set_style_bg_opa(content, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_radius(content, 8, LV_PART_MAIN); + lv_obj_set_flex_flow(content, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_all(content, 8, LV_PART_MAIN); + + lv_obj_remove_flag(content, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t* title = lv_label_create(content); + if (title) { + lv_label_set_text(title, "Playlist"); + lv_obj_set_style_text_color(title, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + lv_obj_set_style_margin_bottom(title, 12, LV_PART_MAIN); + const lv_font_t* title_font = get_playlist_font("title"); + if (title_font) { + lv_obj_set_style_text_font(title, title_font, LV_PART_MAIN); + } + lv_obj_set_style_text_align(title, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN); + } + + int max_items = (R.album_count < MAX_PLAYLIST_ITEMS) ? R.album_count : MAX_PLAYLIST_ITEMS; + for (int i = 0; i < max_items; i++) { + create_playlist_item(content, i); + } + playlist_is_open = true; +} + +void playlist_manager_close(void) { + if (playlist_container) { + lv_obj_del(playlist_container); + playlist_container = NULL; + } + playlist_is_open = false; +} + +bool playlist_manager_is_open(void) { + return playlist_is_open; +} + +void playlist_manager_refresh(void) { + if (playlist_is_open) { + lv_obj_t* parent = lv_obj_get_parent(playlist_container); + playlist_manager_close(); + if (parent) { + playlist_manager_create(parent); + } + } +} \ No newline at end of file diff --git a/music_player2/playlist_manager.h b/music_player2/playlist_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..725dafa93bb810e471607efb418a72ee31173d66 --- /dev/null +++ b/music_player2/playlist_manager.h @@ -0,0 +1,12 @@ +#ifndef PLAYLIST_MANAGER_H +#define PLAYLIST_MANAGER_H + +#include "lvgl.h" +#include <stdbool.h> + +void playlist_manager_create(lv_obj_t* parent); +void playlist_manager_refresh(void); +void playlist_manager_close(void); +bool playlist_manager_is_open(void); + +#endif \ No newline at end of file diff --git a/music_player2/png/main_page.png b/music_player2/png/main_page.png new file mode 100644 index 0000000000000000000000000000000000000000..771890b8f605a5d18c19f41264e82da9edad5fee Binary files /dev/null and b/music_player2/png/main_page.png differ diff --git a/music_player2/png/player.gif b/music_player2/png/player.gif new file mode 100644 index 0000000000000000000000000000000000000000..1994cb928b13ae0e35125ccdd02898f9ee75118d Binary files /dev/null and b/music_player2/png/player.gif differ diff --git a/music_player2/png/playlist.png b/music_player2/png/playlist.png new file mode 100644 index 0000000000000000000000000000000000000000..bacc906e4cc950aeab31c5b6702462f24829283c Binary files /dev/null and b/music_player2/png/playlist.png differ diff --git a/music_player2/res/config.json b/music_player2/res/config.json new file mode 100644 index 0000000000000000000000000000000000000000..f7cb93ca285c7c780f8f1570055e8c2def6110f1 --- /dev/null +++ b/music_player2/res/config.json @@ -0,0 +1,6 @@ +{ + "wifi": { + "ssid": "vela_network", + "pswd": "vela123456" + } +} diff --git a/music_player2/res/fonts/MiSans-Normal.ttf b/music_player2/res/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/music_player2/res/fonts/MiSans-Normal.ttf differ diff --git a/music_player2/res/fonts/MiSans-Semibold.ttf b/music_player2/res/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/music_player2/res/fonts/MiSans-Semibold.ttf differ diff --git a/music_player2/res/icons/audio.png b/music_player2/res/icons/audio.png new file mode 100644 index 0000000000000000000000000000000000000000..1c99091775d008bfba7d4e1e3dd7dad9d47599c3 Binary files /dev/null and b/music_player2/res/icons/audio.png differ diff --git a/music_player2/res/icons/music.png b/music_player2/res/icons/music.png new file mode 100644 index 0000000000000000000000000000000000000000..be4f163e5d2b0cece03f8ef52b081a3ade804b6e Binary files /dev/null and b/music_player2/res/icons/music.png differ diff --git a/music_player2/res/icons/mute.png b/music_player2/res/icons/mute.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d8b3b5cc2af4d6bb5e0976471af674b8759764 Binary files /dev/null and b/music_player2/res/icons/mute.png differ diff --git a/music_player2/res/icons/next.png b/music_player2/res/icons/next.png new file mode 100644 index 0000000000000000000000000000000000000000..1db3575fb8b4ea7547a9e0c958a6cc62274cd0e2 Binary files /dev/null and b/music_player2/res/icons/next.png differ diff --git a/music_player2/res/icons/nocover.png b/music_player2/res/icons/nocover.png new file mode 100644 index 0000000000000000000000000000000000000000..25282616d4119db1a99f94365254f64105da0acc Binary files /dev/null and b/music_player2/res/icons/nocover.png differ diff --git a/music_player2/res/icons/pause.png b/music_player2/res/icons/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..9fcd00cc4b60533e1ad91f3f5c20e538a04a2a72 Binary files /dev/null and b/music_player2/res/icons/pause.png differ diff --git a/music_player2/res/icons/play.png b/music_player2/res/icons/play.png new file mode 100644 index 0000000000000000000000000000000000000000..f8e7bf726e45a94ac3ee44b9df3b7bbc58bed091 Binary files /dev/null and b/music_player2/res/icons/play.png differ diff --git a/music_player2/res/icons/playlist.png b/music_player2/res/icons/playlist.png new file mode 100644 index 0000000000000000000000000000000000000000..4a1b35a42b02d184def2fee67161b667fd31420c Binary files /dev/null and b/music_player2/res/icons/playlist.png differ diff --git a/music_player2/res/icons/previous.png b/music_player2/res/icons/previous.png new file mode 100644 index 0000000000000000000000000000000000000000..e847a824e020585a156a68a6c794e189922939bd Binary files /dev/null and b/music_player2/res/icons/previous.png differ diff --git a/music_player2/res/musics/manifest.json b/music_player2/res/musics/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9676a51abbc65fd7b51cc3f976547b77fac2f24b --- /dev/null +++ b/music_player2/res/musics/manifest.json @@ -0,0 +1,12 @@ +{ + "musics": [ + { + "path": "test.mp3", + "name": "Test Song", + "artist": "Demo Artist", + "cover": "test.png", + "total_time": 180000, + "color": "#4A90E2" + } + ] +} \ No newline at end of file diff --git a/music_player2/res/musics/test.mp3 b/music_player2/res/musics/test.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c28d8f5509ed62bd5f0af4db608a87c21c335e28 Binary files /dev/null and b/music_player2/res/musics/test.mp3 differ diff --git a/music_player2/res/musics/test.png b/music_player2/res/musics/test.png new file mode 100644 index 0000000000000000000000000000000000000000..a5aac13ef8f2138bcb368e34f5f53cd5f935238e Binary files /dev/null and b/music_player2/res/musics/test.png differ diff --git a/music_player2/splash_screen.c b/music_player2/splash_screen.c new file mode 100644 index 0000000000000000000000000000000000000000..1aad8ba0130615a8b565c5c2deeaa53082a51b2b --- /dev/null +++ b/music_player2/splash_screen.c @@ -0,0 +1,138 @@ +#include "music_player2.h" + +#define SPLASH_DURATION 2000 + +static lv_obj_t* splash_screen; +static lv_timer_t* splash_timer; + +static void splash_timer_cb(lv_timer_t* timer); +static void logo_fade_in_anim_cb(void* obj, int32_t value); +static void vinyl_rotation_anim_cb(void* obj, int32_t value); +static void splash_fadeout_complete_cb(lv_anim_t* anim); + +void splash_screen_create(void) { + splash_screen = lv_obj_create(lv_screen_active()); + lv_obj_remove_style_all(splash_screen); + lv_obj_set_size(splash_screen, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_bg_color(splash_screen, lv_color_hex(0x0A0A0A), + LV_PART_MAIN); + lv_obj_set_style_bg_opa(splash_screen, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_center(splash_screen); + lv_obj_set_flex_flow(splash_screen, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(splash_screen, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t* logo_container = lv_obj_create(splash_screen); + lv_obj_remove_style_all(logo_container); + lv_obj_set_size(logo_container, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_flex_flow(logo_container, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(logo_container, LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t* vinyl_container = lv_obj_create(logo_container); + lv_obj_remove_style_all(vinyl_container); + lv_obj_set_size(vinyl_container, 120, 120); + lv_obj_set_style_radius(vinyl_container, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_set_style_bg_color(vinyl_container, lv_color_hex(0x1A1A1A), + LV_PART_MAIN); + lv_obj_set_style_bg_opa(vinyl_container, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_border_width(vinyl_container, 2, LV_PART_MAIN); + lv_obj_set_style_border_color(vinyl_container, lv_color_hex(0x3B82F6), + LV_PART_MAIN); + lv_obj_set_style_shadow_width(vinyl_container, 15, LV_PART_MAIN); + lv_obj_set_style_shadow_color(vinyl_container, lv_color_hex(0x3B82F6), + LV_PART_MAIN); + lv_obj_set_style_shadow_opa(vinyl_container, LV_OPA_50, LV_PART_MAIN); + lv_obj_set_style_margin_bottom(vinyl_container, 20, LV_PART_MAIN); + lv_obj_set_style_transform_pivot_x(vinyl_container, 60, 0); + lv_obj_set_style_transform_pivot_y(vinyl_container, 60, 0); + + lv_obj_t* vinyl_center = lv_obj_create(vinyl_container); + lv_obj_remove_style_all(vinyl_center); + lv_obj_set_size(vinyl_center, 20, 20); + lv_obj_set_style_radius(vinyl_center, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_set_style_bg_color(vinyl_center, lv_color_hex(0x3B82F6), LV_PART_MAIN); + lv_obj_set_style_bg_opa(vinyl_center, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_center(vinyl_center); + + lv_obj_t* music_icon = lv_label_create(vinyl_center); + lv_label_set_text(music_icon, "V"); + lv_obj_set_style_text_font(music_icon, &lv_font_montserrat_16, LV_PART_MAIN); + lv_obj_set_style_text_color(music_icon, lv_color_white(), LV_PART_MAIN); + lv_obj_center(music_icon); + + lv_obj_t* brand_title = lv_label_create(logo_container); + lv_label_set_text(brand_title, "openvela"); + lv_obj_set_style_text_font(brand_title, &lv_font_montserrat_32, LV_PART_MAIN); + lv_obj_set_style_text_color(brand_title, lv_color_hex(0x3B82F6), + LV_PART_MAIN); + lv_obj_set_style_margin_bottom(brand_title, 8, LV_PART_MAIN); + + lv_obj_t* tagline = lv_label_create(logo_container); + lv_label_set_text(tagline, "Music Connects Souls"); + lv_obj_set_style_text_font(tagline, &lv_font_montserrat_16, LV_PART_MAIN); + lv_obj_set_style_text_color(tagline, lv_color_hex(0xAAAAAA), LV_PART_MAIN); + lv_obj_set_style_margin_bottom(tagline, 40, LV_PART_MAIN); + + lv_obj_t* loading_circle = lv_obj_create(splash_screen); + lv_obj_remove_style_all(loading_circle); + lv_obj_set_size(loading_circle, 40, 40); + lv_obj_set_style_radius(loading_circle, LV_RADIUS_CIRCLE, LV_PART_MAIN); + lv_obj_set_style_border_width(loading_circle, 3, LV_PART_MAIN); + lv_obj_set_style_border_color(loading_circle, lv_color_hex(0x3B82F6), + LV_PART_MAIN); + lv_obj_set_style_border_opa(loading_circle, LV_OPA_30, LV_PART_MAIN); + lv_obj_set_style_bg_opa(loading_circle, LV_OPA_TRANSP, LV_PART_MAIN); + + lv_anim_t logo_anim; + lv_anim_init(&logo_anim); + lv_anim_set_var(&logo_anim, logo_container); + lv_anim_set_exec_cb(&logo_anim, logo_fade_in_anim_cb); + lv_anim_set_values(&logo_anim, 0, 255); + lv_anim_set_duration(&logo_anim, 800); + lv_anim_set_path_cb(&logo_anim, lv_anim_path_ease_out); + lv_anim_start(&logo_anim); + + lv_anim_t vinyl_anim; + lv_anim_init(&vinyl_anim); + lv_anim_set_var(&vinyl_anim, vinyl_container); + lv_anim_set_exec_cb(&vinyl_anim, vinyl_rotation_anim_cb); + lv_anim_set_values(&vinyl_anim, 0, 3600); + lv_anim_set_duration(&vinyl_anim, 3000); + lv_anim_set_repeat_count(&vinyl_anim, LV_ANIM_REPEAT_INFINITE); + lv_anim_start(&vinyl_anim); + + splash_timer = lv_timer_create(splash_timer_cb, SPLASH_DURATION, NULL); + lv_timer_set_repeat_count(splash_timer, 1); +} + +static void logo_fade_in_anim_cb(void* obj, int32_t value) { + lv_obj_t* logo = (lv_obj_t*)obj; + lv_obj_set_style_opa(logo, value, LV_PART_MAIN); +} + +static void vinyl_rotation_anim_cb(void* obj, int32_t value) { + lv_obj_t* vinyl = (lv_obj_t*)obj; + lv_obj_set_style_transform_rotation(vinyl, value, 0); +} + +static void splash_timer_cb(lv_timer_t* timer) { + LV_UNUSED(timer); + lv_anim_t fadeout_anim; + lv_anim_init(&fadeout_anim); + lv_anim_set_var(&fadeout_anim, splash_screen); + lv_anim_set_exec_cb(&fadeout_anim, logo_fade_in_anim_cb); + lv_anim_set_values(&fadeout_anim, 255, 0); + lv_anim_set_duration(&fadeout_anim, 500); + lv_anim_set_path_cb(&fadeout_anim, lv_anim_path_ease_in); + lv_anim_set_completed_cb(&fadeout_anim, splash_fadeout_complete_cb); + lv_anim_start(&fadeout_anim); + lv_timer_delete(splash_timer); + splash_timer = NULL; +} + +static void splash_fadeout_complete_cb(lv_anim_t* anim) { + LV_UNUSED(anim); + lv_obj_delete(splash_screen); + app_create(); +} diff --git a/music_player2/wifi.c b/music_player2/wifi.c new file mode 100644 index 0000000000000000000000000000000000000000..494e9149463e3b97c5eea764a6a5edb886ac78f4 --- /dev/null +++ b/music_player2/wifi.c @@ -0,0 +1,140 @@ +/** + * @file wifi.c + * Provide wifi connection and network configuration functions + */ + +/********************* + * INCLUDES + *********************/ +#include "wifi.h" + +#if WIFI_ENABLED + +#include <debug.h> +#include <time.h> + +#include "netutils/netlib.h" +#include "netutils/ntpclient.h" + +/********************* + * DEFINES + *********************/ + +#define NET_DEVNAME "wlan0" + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + struct work_s work; + wifi_conf_t conf; +} wifi_work_conf_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +int wifi_conf_set(FAR wifi_conf_t* usr_conf, + FAR struct wpa_wconfig_s* wifi_conf) { + if (strlen(usr_conf->ssid) == 0) { + nerr("ERROR: SSID is NULL\n"); + return -EINVAL; + } + + switch (usr_conf->ver_flag) { + case WPA_VER_NONE: + wifi_conf->auth_wpa = IW_AUTH_WPA_VERSION_DISABLED; + wifi_conf->cipher_mode = IW_AUTH_CIPHER_NONE; + wifi_conf->alg = WPA_ALG_NONE; + break; + + case WPA_VER_1: + wifi_conf->auth_wpa = IW_AUTH_WPA_VERSION_WPA; + wifi_conf->cipher_mode = IW_AUTH_CIPHER_TKIP; + wifi_conf->alg = WPA_ALG_TKIP; + break; + + case WPA_VER_2: + wifi_conf->auth_wpa = IW_AUTH_WPA_VERSION_WPA2; + wifi_conf->cipher_mode = IW_AUTH_CIPHER_CCMP; + wifi_conf->alg = WPA_ALG_CCMP; + break; + + default: + nerr("ERROR: unknown WPA version\n"); + return -EINVAL; + } + + wifi_conf->ifname = NET_DEVNAME; + wifi_conf->sta_mode = IW_MODE_INFRA; + wifi_conf->ssid = usr_conf->ssid; + wifi_conf->passphrase = usr_conf->pswd; + wifi_conf->ssidlen = strlen(usr_conf->ssid); + wifi_conf->phraselen = strlen(usr_conf->pswd); + wifi_conf->bssid = NULL; + wifi_conf->freq = 0; + + return 0; +} + +void wifi_connect_worker(FAR void* arg) { + FAR wifi_work_conf_t* wifi_conf = arg; + struct wpa_wconfig_s conf; + + if (wifi_conf_set(&wifi_conf->conf, &conf) < 0) { + nerr("ERROR: wifi parameter is wrong\n"); + goto fail; + } + + if (netlib_ifup(NET_DEVNAME) < 0) { + nerr("ERROR: %s up failed\n", NET_DEVNAME); + goto fail; + } + + if (wpa_driver_wext_associate(&conf) < 0) { + nerr("ERROR: associate failed\n"); + goto fail; + } + + if (netlib_obtain_ipv4addr(NET_DEVNAME) < 0) { + nerr("ERROR: network configuration failed\n"); + goto fail; + } + + ntpc_start(); + +fail: + free(wifi_conf); +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void wifi_connect(FAR const wifi_conf_t* conf) { + FAR wifi_work_conf_t* wifi_conf = zalloc(sizeof(*wifi_conf)); + if (wifi_conf == NULL) { + nerr("ERROR: zalloc failed\n"); + return; + } + + wifi_conf->conf = *conf; + + work_queue(USRWORK, &wifi_conf->work, wifi_connect_worker, wifi_conf, + conf->conn_delay); +} + +#endif +// Test sync modification - Tue Aug 26 06:40:52 UTC 2025 diff --git a/music_player2/wifi.h b/music_player2/wifi.h new file mode 100644 index 0000000000000000000000000000000000000000..767c2a73b89708447523bc4a54ef5cf4b41729d2 --- /dev/null +++ b/music_player2/wifi.h @@ -0,0 +1,27 @@ +#include <nuttx/config.h> + +#if !defined(CONFIG_NETUTILS_DHCPC) || !defined(CONFIG_WIRELESS_WAPI) || !defined(CONFIG_NETUTILS_NTPCLIENT) || (CONFIG_SCHED_LPNTHREADS < 2) +#warning \ + "If you want enable WIFI, please make sure DHCPC, WAPI, IEEE80211, NTP to be enabled \ + and number of lpthreads need greater than or equal to 2." +#define WIFI_ENABLED 0 +#else +#define WIFI_ENABLED 1 +#endif + +#if WIFI_ENABLED + +#include <nuttx/wqueue.h> + +#include "wireless/wapi.h" + +typedef struct { + char ssid[128]; + char pswd[128]; + enum wpa_ver_e ver_flag; + clock_t conn_delay; +} wifi_conf_t; + +void wifi_connect(FAR const wifi_conf_t* conf); + +#endif diff --git a/pet/Kconfig b/pet/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..6a1281b9cfcb3ac2860ae63192f090ad652fcdc8 --- /dev/null +++ b/pet/Kconfig @@ -0,0 +1,14 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_PET + bool "Virtual Pet Demo" + default n + +if LVX_USE_DEMO_PET + config LVX_PET_DATA_ROOT + string "Pet Demo Data Root" + default "/sdcard" +endif diff --git a/pet/Make.defs b/pet/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..25ac79407d51ddd6767175ab52f063b099ecabdb --- /dev/null +++ b/pet/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_PET),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/pet +endif diff --git a/pet/Makefile b/pet/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..319253b05865009c27c5f9fb6949a1d7b56a0fda --- /dev/null +++ b/pet/Makefile @@ -0,0 +1,13 @@ +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_PET),y) +PROGNAME = pet +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_PET) + +CSRCS = pet.c +MAINSRC = pet_main.c +endif + +include $(APPDIR)/Application.mk diff --git a/pet/README.md b/pet/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8ed0154ba4facc739937261ef5fe7802c801f52e --- /dev/null +++ b/pet/README.md @@ -0,0 +1,91 @@ +# 虚拟宠物应用 (Virtual Pet Demo) + +## 简介 + +虚拟宠物应用是一个基于LVGL图形库的交互式演示程序,模拟了一个数字宠物的饲养过程。用户可以通过喂食、饮水、运动和休息等操作来照顾虚拟宠物,提升其心情和等级。 + +## 界面预览 + +![虚拟宠物主界面](docs/images/jiemian.png) + +*主界面:左侧显示宠物状态,右侧为操作按钮* + +![宠物平静状态](docs/images/calm.png) +![宠物难过状态](docs/images/sad.png) + +*宠物的不同情绪状态:开心、平静、难过* + +## 功能特性 + +### 宠物状态管理 +- **饥饿度**:随时间缓慢下降,可通过喂食恢复 +- **口渴度**:随时间缓慢下降,可通过饮水恢复 +- **心情值**:受饥饿度和口渴度影响,可通过运动提升 +- **经验值**:随时间自动增长,运动可获得额外经验值 +- **等级系统**:积累足够经验值后升级 + +### 宠物状态表现 +- **三种情绪状态**:开心、平静、难过(根据心情值自动变化) +- **睡眠状态**:可手动切换,睡眠时状态下降更慢,心情缓慢恢复 + +### 成就系统 +- 连续7天喂食/饮水/运动 +- 存活30天 +- 达到5级/10级 + +### 数据持久化 +- 自动保存宠物数据 +- 应用重启后可恢复之前的状态 + +### 用户界面 +- 现代化UI设计,左侧状态面板,右侧操作按钮 +- 图形化按钮,带有点击反馈效果 +- 状态条直观显示宠物各项属性 + +## 使用方法 + +### 基本操作 +1. **喂食**:点击食物图标,增加饥饿度和少量心情值 +2. **饮水**:点击水杯图标,增加口渴度和少量心情值 +3. **运动**:点击运动图标,大幅提升心情值并获得额外经验,但会消耗饥饿度和口渴度 +4. **睡眠**:点击睡眠图标,切换宠物睡眠状态,睡眠时状态下降更慢 + +### 状态指示 +- 左侧进度条显示宠物的饥饿度、口渴度、心情值和经验值 +- 宠物图像会根据心情状态变化 +- 顶部状态栏显示当前时间、电量和宠物等级 + +## 配置与编译 + +### 依赖项 +- LVGL图形库 +- NuttX操作系统 +- libuv事件循环库 + +### 编译选项 +在NuttX配置中启用: +``` +CONFIG_LVX_USE_DEMO_PET=y +CONFIG_LVX_PET_DATA_ROOT="/sdcard" # 设置资源文件路径 +``` + +## 资源文件结构 +``` +/sdcard/res/ + ├── fonts/ # 字体文件 + ├── image/ # 宠物和背景图像 + └── icons/ # 操作按钮图标 +``` + +## 开发者信息 + +### 主要文件 +- `pet.h`:定义结构体和常量 +- `pet.c`:实现主要功能 +- `pet_main.c`:应用入口和LVGL初始化 + +### 扩展建议 +- 添加更多互动方式 +- 实现随机事件系统 +- 增加更多成就和奖励 +- 添加社交功能 \ No newline at end of file diff --git a/pet/docs/images/calm.png b/pet/docs/images/calm.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0b91eb5d0048c1cffa4b1ef3d93a9d90510fa4 Binary files /dev/null and b/pet/docs/images/calm.png differ diff --git a/pet/docs/images/jiemian.png b/pet/docs/images/jiemian.png new file mode 100644 index 0000000000000000000000000000000000000000..0dfbf1c71863785c299ceb1513758bf3fbebc3bb Binary files /dev/null and b/pet/docs/images/jiemian.png differ diff --git a/pet/docs/images/sad.png b/pet/docs/images/sad.png new file mode 100644 index 0000000000000000000000000000000000000000..a4efc6315f92864bf6216c744c33845f3b576a38 Binary files /dev/null and b/pet/docs/images/sad.png differ diff --git a/pet/pet.c b/pet/pet.c new file mode 100644 index 0000000000000000000000000000000000000000..8910b4c5dcddd795b0725881bfd53551ed78d8e9 --- /dev/null +++ b/pet/pet.c @@ -0,0 +1,952 @@ +// +// Virtual Pet Demo Application +// + +/********************* + * INCLUDES + *********************/ +#include "pet.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/* Init functions */ +static bool init_resource(void); +static void app_create_error_page(void); +static void app_create_main_page(void); +static void app_create_top_layer(void); +static void init_pet_data(void); +static void load_images(void); + +/* UI Creation functions */ +static void create_status_bar(void); +static void create_pet_area(void); +static void create_unified_control_panel(void); + +/* Timer starting functions */ +static void app_start_updating_timers(void); + +/* Pet status and operations */ +static void update_pet_mood(void); +static void update_pet_status(lv_timer_t *timer); +static void reset_pet_state(lv_timer_t *timer); +static void update_time_display(lv_timer_t *timer); +static void feed_pet(lv_event_t *e); +static void give_water(lv_event_t *e); +static void exercise_pet(lv_event_t *e); +static void toggle_sleep(lv_event_t *e); +static void close_msgbox_timer_cb(lv_timer_t* timer); + +/* Data persistence functions */ +static void save_pet_data(void); +static bool load_pet_data(void); + +/* Achievement functions */ +static void add_achievement(uint32_t achievement); +static void check_achievements(void); +static void init_random_event(void); + +/* Utility functions */ +static uint32_t calc_experience_for_level(uint8_t level); +static void update_visuals(void); + +/********************** + * STATIC VARIABLES + **********************/ + +// clang-format off +pet_res_t R; /**< Resources */ +pet_ctx_t C; /**< Context */ +pet_conf_t CF; /**< Configuration */ +// clang-format on + +/* Week days mapping */ +const char* WEEK_DAYS[] = { "Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri.", "Sat." }; + +/* Transition properties for the objects */ +const lv_style_prop_t transition_props[] = { + LV_STYLE_OPA, + LV_STYLE_BG_OPA, + LV_STYLE_Y, + LV_STYLE_HEIGHT, + LV_STYLE_PROP_FLAG_NONE +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * 应用创建入口函数 + */ +void app_create(void) +{ + // 初始化资源和上下文结构 + lv_memzero(&R, sizeof(R)); + lv_memzero(&C, sizeof(C)); + lv_memzero(&CF, sizeof(CF)); + + // 初始化随机数生成器 + srand(time(NULL)); + + // 初始化资源 + C.resource_healthy_check = init_resource(); + + if (!C.resource_healthy_check) { + app_create_error_page(); + return; + } + + // 初始化宠物数据 + init_pet_data(); + + // 创建UI + app_create_main_page(); + + // 更新一次界面 + update_visuals(); + + // 启动定时器 + app_start_updating_timers(); + + // 初始化随机事件 + init_random_event(); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * 初始化资源 + */ +static bool init_resource(void) +{ + // Fonts + R.fonts.size_16.normal = lv_freetype_font_create(FONTS_ROOT "/MiSans-Normal.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 16, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_22.bold = lv_freetype_font_create(FONTS_ROOT "/MiSans-Semibold.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 22, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_24.normal = lv_freetype_font_create(FONTS_ROOT "/MiSans-Normal.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_28.normal = lv_freetype_font_create(FONTS_ROOT "/MiSans-Semibold.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 38, LV_FREETYPE_FONT_STYLE_NORMAL); + R.fonts.size_60.bold = lv_freetype_font_create(FONTS_ROOT "/MiSans-Semibold.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 60, LV_FREETYPE_FONT_STYLE_NORMAL); + + if (R.fonts.size_16.normal == NULL || + R.fonts.size_22.bold == NULL || + R.fonts.size_24.normal == NULL || + R.fonts.size_28.normal == NULL || + R.fonts.size_60.bold == NULL ) { + return false; + } + + // Styles + lv_style_init(&R.styles.button_default); + lv_style_init(&R.styles.button_pressed); + lv_style_set_opa(&R.styles.button_default, LV_OPA_COVER); + lv_style_set_opa(&R.styles.button_pressed, LV_OPA_70); + + // transition animation + lv_style_transition_dsc_init(&R.styles.transition_dsc, transition_props, &lv_anim_path_ease_in_out, 300, 0, NULL); + lv_style_transition_dsc_init(&R.styles.button_transition_dsc, transition_props, &lv_anim_path_ease_in_out, 80, 0, NULL); + lv_style_set_transition(&R.styles.button_default, &R.styles.button_transition_dsc); + lv_style_set_transition(&R.styles.button_pressed, &R.styles.button_transition_dsc); + + // Images + R.images.background = IMAGES_ROOT "/background.png"; + R.images.sad = IMAGES_ROOT "/sad.png"; + R.images.calm = IMAGES_ROOT "/calm.png"; + R.images.happy = IMAGES_ROOT "/happy.png"; + R.images.eat_img = IMAGES_ROOT "/eat.png"; // 宠物进食图片 + R.images.drink_img = IMAGES_ROOT "/drink.png"; // 宠物喝水图片 + R.images.sleep_img = IMAGES_ROOT "/sleep.png"; + + R.images.eat = ICONS_ROOT "/eat.png"; // 喂食按钮图标 + R.images.drink = ICONS_ROOT "/drink.png"; // 喝水按钮图标 + R.images.exercise = ICONS_ROOT "/exercise.png"; + R.images.sleep_icon = ICONS_ROOT "/sleep.png"; + + + return true; +} + +/** + * 计算经验值 + */ +static uint32_t calc_experience_for_level(uint8_t level) +{ + return level * level * 100; +} + +/** + * 创建错误页面 + */ +static void app_create_error_page(void) +{ + lv_obj_t* root = lv_screen_active(); + lv_obj_t* label = lv_label_create(root); + lv_obj_set_width(label, LV_PCT(80)); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + lv_label_set_text(label, "Resource loading failed. \nPlease check the device and \nread the document for more details."); + lv_obj_set_style_text_font(label, &lv_font_montserrat_32, LV_PART_MAIN); + lv_obj_center(label); +} + +/** + * 创建主页面 + */ +static void app_create_main_page(void) +{ + // 创建状态栏 + create_status_bar(); + + // 创建宠物区域 + create_pet_area(); + + // 创建新的合并UI面板 + create_unified_control_panel(); +} + +/** + * 创建状态栏 + */ +static void create_status_bar(void) +{ + lv_obj_t* root = lv_screen_active(); + + // 设置根对象样式 + lv_obj_set_style_bg_color(root, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_border_width(root, 0, LV_PART_MAIN); + lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(root, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(root, 20, LV_PART_MAIN); + + // 创建状态栏 + lv_obj_t* status_bar = lv_obj_create(root); + lv_obj_set_size(status_bar, LV_PCT(100), 40); + lv_obj_align(status_bar, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_style_bg_color(status_bar, lv_color_hex(0x222222), 0); + lv_obj_set_style_radius(status_bar, 0, 0); + R.ui.status_bar = status_bar; + + // 时间标签 + lv_obj_t* time_label = lv_label_create(status_bar); + lv_obj_align(time_label, LV_ALIGN_LEFT_MID, 10, 0); + lv_label_set_text(time_label, "00:00"); + lv_obj_set_style_text_font(time_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(time_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + R.ui.time_label = time_label; + + // 电量标签 + lv_obj_t* battery_label = lv_label_create(status_bar); + lv_obj_align(battery_label, LV_ALIGN_CENTER, 0, 0); + lv_label_set_text(battery_label, "100%"); + lv_obj_set_style_text_font(battery_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(battery_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + R.ui.battery_label = battery_label; + + // 等级标签 + lv_obj_t* level_label = lv_label_create(status_bar); + lv_obj_align(level_label, LV_ALIGN_RIGHT_MID, -10, 0); + lv_label_set_text_fmt(level_label, "Lv.%d", C.data.level); + lv_obj_set_style_text_font(level_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(level_label, lv_color_hex(0xFFFF00), LV_PART_MAIN); + R.ui.level_label = level_label; +} + +/** + * 创建宠物显示区域 + */ +static void create_pet_area(void) +{ + lv_obj_t* root = lv_screen_active(); + + // 创建宠物显示区域 + lv_obj_t* pet_area = lv_obj_create(root); + lv_obj_set_size(pet_area, LV_PCT(100), LV_PCT(60)); + lv_obj_align_to(pet_area, R.ui.status_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 0); + lv_obj_set_style_bg_opa(pet_area, LV_OPA_0, 0); + lv_obj_set_style_border_width(pet_area, 0, 0); + R.ui.pet_area = pet_area; + + // 获取区域高度,用于计算缩放比例 + int area_height = lv_obj_get_height(pet_area); + int area_width = lv_obj_get_width(pet_area); + int scale = LV_MIN(area_width, area_height) * 100 / 1024; // 计算适合的缩放比例 + scale = scale * 2; // 将缩放比例增大一倍 + + // 背景图像 + lv_obj_t* bg_img = lv_img_create(pet_area); + lv_img_set_src(bg_img, R.images.background); + lv_obj_align(bg_img, LV_ALIGN_CENTER, 0, 0); + lv_img_set_zoom(bg_img, scale); // 使用增大后的缩放比例 + R.ui.background_img = bg_img; + + // 宠物图像 + lv_obj_t* pet_img = lv_img_create(pet_area); + lv_img_set_src(pet_img, R.images.calm); // 默认为平静状态 + lv_obj_align(pet_img, LV_ALIGN_CENTER, 0, 0); + lv_img_set_zoom(pet_img, scale); // 使用增大后的缩放比例 + R.ui.pet_img = pet_img; +} + +/** + * 创建合并的控制面板(状态 + 操作按钮) + */ +static void create_unified_control_panel(void) +{ + lv_obj_t* root = lv_screen_active(); + + // 创建控制面板 + lv_obj_t* control_panel = lv_obj_create(root); + lv_obj_set_size(control_panel, LV_PCT(100), 180); + lv_obj_align_to(control_panel, R.ui.pet_area, LV_ALIGN_OUT_BOTTOM_MID, 0, 0); + lv_obj_set_style_bg_color(control_panel, lv_color_hex(0x222222), 0); + lv_obj_set_style_pad_all(control_panel, 10, 0); + R.ui.status_panel = control_panel; // 重用原状态面板引用 + + // 创建左右布局 + lv_obj_set_flex_flow(control_panel, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(control_panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // 左侧状态面板 + lv_obj_t* status_area = lv_obj_create(control_panel); + lv_obj_set_size(status_area, LV_PCT(45), LV_PCT(100)); + lv_obj_set_style_bg_opa(status_area, LV_OPA_0, 0); + lv_obj_set_style_border_width(status_area, 0, 0); + lv_obj_set_style_pad_all(status_area, 5, 0); + + // 右侧按钮面板 + lv_obj_t* buttons_area = lv_obj_create(control_panel); + lv_obj_set_size(buttons_area, LV_PCT(50), LV_PCT(100)); + lv_obj_set_style_bg_opa(buttons_area, LV_OPA_0, 0); + lv_obj_set_style_border_width(buttons_area, 0, 0); + lv_obj_set_style_pad_all(buttons_area, 5, 0); + + // 在左侧添加状态条 + // 饥饿度条 + lv_obj_t* hunger_label = lv_label_create(status_area); + lv_label_set_text(hunger_label, "饥饿:"); + lv_obj_set_pos(hunger_label, 0, 10); + lv_obj_set_style_text_font(hunger_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(hunger_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_t* hunger_bar = lv_bar_create(status_area); + lv_obj_set_size(hunger_bar, 180, 15); + lv_obj_set_pos(hunger_bar, 60, 10); + lv_bar_set_range(hunger_bar, 0, 100); + lv_bar_set_value(hunger_bar, C.data.hunger, LV_ANIM_OFF); + lv_obj_set_style_bg_color(hunger_bar, lv_color_hex(0xFFAA00), LV_PART_INDICATOR); + R.ui.hunger_bar = hunger_bar; + + // 口渴度条 + lv_obj_t* thirst_label = lv_label_create(status_area); + lv_label_set_text(thirst_label, "口渴:"); + lv_obj_set_pos(thirst_label, 0, 40); + lv_obj_set_style_text_font(thirst_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(thirst_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_t* thirst_bar = lv_bar_create(status_area); + lv_obj_set_size(thirst_bar, 180, 15); + lv_obj_set_pos(thirst_bar, 60, 40); + lv_bar_set_range(thirst_bar, 0, 100); + lv_bar_set_value(thirst_bar, C.data.thirst, LV_ANIM_OFF); + lv_obj_set_style_bg_color(thirst_bar, lv_color_hex(0x00AAFF), LV_PART_INDICATOR); + R.ui.thirst_bar = thirst_bar; + + // 心情度条 + lv_obj_t* happiness_label = lv_label_create(status_area); + lv_label_set_text(happiness_label, "心情:"); + lv_obj_set_pos(happiness_label, 0, 70); + lv_obj_set_style_text_font(happiness_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(happiness_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_t* happiness_bar = lv_bar_create(status_area); + lv_obj_set_size(happiness_bar, 180, 15); + lv_obj_set_pos(happiness_bar, 60, 70); + lv_bar_set_range(happiness_bar, 0, 100); + lv_bar_set_value(happiness_bar, C.data.happiness, LV_ANIM_OFF); + lv_obj_set_style_bg_color(happiness_bar, lv_color_hex(0xFF5555), LV_PART_INDICATOR); + R.ui.happiness_bar = happiness_bar; + + // 经验条 + lv_obj_t* exp_label = lv_label_create(status_area); + lv_label_set_text(exp_label, "经验:"); + lv_obj_set_pos(exp_label, 0, 100); + lv_obj_set_style_text_font(exp_label, R.fonts.size_16.normal, LV_PART_MAIN); + lv_obj_set_style_text_color(exp_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN); + + lv_obj_t* exp_bar = lv_bar_create(status_area); + lv_obj_set_size(exp_bar, 180, 15); + lv_obj_set_pos(exp_bar, 60, 100); + lv_bar_set_range(exp_bar, 0, C.data.next_level_exp); + lv_bar_set_value(exp_bar, C.data.experience, LV_ANIM_OFF); + lv_obj_set_style_bg_color(exp_bar, lv_color_hex(0x55FF55), LV_PART_INDICATOR); + R.ui.exp_bar = exp_bar; + + // 为按钮区域设置水平行布局 + lv_obj_set_flex_flow(buttons_area, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(buttons_area, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + // 喂食按钮 - 直接使用图像而不是按钮背景 + lv_obj_t* feed_btn = lv_img_create(buttons_area); + lv_img_set_src(feed_btn, R.images.eat); + lv_obj_set_size(feed_btn, 88, 88); + lv_obj_add_event_cb(feed_btn, feed_pet, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(feed_btn, LV_OBJ_FLAG_CLICKABLE); // 设置图像可点击 + lv_obj_set_style_img_recolor(feed_btn, lv_color_hex(0xFFFFFF), LV_STATE_PRESSED); // 点击时的反馈 + lv_obj_set_style_img_recolor_opa(feed_btn, LV_OPA_30, LV_STATE_PRESSED); + R.ui.feed_btn = feed_btn; + + // 喝水按钮 + lv_obj_t* water_btn = lv_img_create(buttons_area); + lv_img_set_src(water_btn, R.images.drink); + lv_obj_set_size(water_btn, 88, 88); + lv_obj_add_event_cb(water_btn, give_water, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(water_btn, LV_OBJ_FLAG_CLICKABLE); // 设置图像可点击 + lv_obj_set_style_img_recolor(water_btn, lv_color_hex(0xFFFFFF), LV_STATE_PRESSED); // 点击时的反馈 + lv_obj_set_style_img_recolor_opa(water_btn, LV_OPA_30, LV_STATE_PRESSED); + R.ui.water_btn = water_btn; + + // 运动按钮 + lv_obj_t* exercise_btn = lv_img_create(buttons_area); + lv_img_set_src(exercise_btn, R.images.exercise); + lv_obj_set_size(exercise_btn, 88, 88); + lv_obj_add_event_cb(exercise_btn, exercise_pet, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(exercise_btn, LV_OBJ_FLAG_CLICKABLE); // 设置图像可点击 + lv_obj_set_style_img_recolor(exercise_btn, lv_color_hex(0xFFFFFF), LV_STATE_PRESSED); // 点击时的反馈 + lv_obj_set_style_img_recolor_opa(exercise_btn, LV_OPA_30, LV_STATE_PRESSED); + R.ui.exercise_btn = exercise_btn; + + // 睡眠按钮 + lv_obj_t* sleep_btn = lv_img_create(buttons_area); + lv_img_set_src(sleep_btn, R.images.sleep_icon); + lv_obj_set_size(sleep_btn, 88, 88); + lv_obj_add_event_cb(sleep_btn, toggle_sleep, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(sleep_btn, LV_OBJ_FLAG_CLICKABLE); // 设置图像可点击 + lv_obj_set_style_img_recolor(sleep_btn, lv_color_hex(0xFFFFFF), LV_STATE_PRESSED); // 点击时的反馈 + lv_obj_set_style_img_recolor_opa(sleep_btn, LV_OPA_30, LV_STATE_PRESSED); + R.ui.sleep_btn = sleep_btn; +} + +// 初始化宠物数据 +static void init_pet_data(void) +{ + // 尝试加载保存的数据,如果失败则初始化默认值 + if (!load_pet_data()) { + C.data.level = 1; + C.data.hunger = 60; // 初始饥饿度为60% + C.data.thirst = 60; // 初始口渴度为60% + C.data.happiness = 60; // 初始心情值为60% + C.data.experience = 0; // 经验值从0开始 + C.data.next_level_exp = calc_experience_for_level(2); + C.data.mood = PET_MOOD_CALM; + C.data.state = PET_STATE_NORMAL; + C.data.sleeping = false; + C.data.days_alive = 0; + C.data.achievements = 0; + } + + C.data.last_update = time(NULL); + C.start_time = time(NULL); + C.initialized = true; +} + +// 更新时间显示 +void update_time_display(lv_timer_t *timer) +{ + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + + char time_str[16]; + strftime(time_str, sizeof(time_str), "%H:%M", tm_info); + + lv_label_set_text(R.ui.time_label, time_str); + + // 模拟电池电量(真实设备应该读取系统电量) + static int battery = 100; + if (rand() % 100 > 95) { + // 偶尔减少电量 + battery = (battery > 5) ? battery - 1 : 5; + } + lv_label_set_text_fmt(R.ui.battery_label, "%d%%", battery); + + // 每天更新一次天数 + static int last_day = -1; + if (tm_info->tm_mday != last_day) { + if (last_day != -1) { + C.data.days_alive++; + check_achievements(); + } + last_day = tm_info->tm_mday; + } +} + +// 更新宠物心情状态 +static void update_pet_mood() +{ + // 根据幸福度确定心情 + if (C.data.happiness < MOOD_SAD_THRESHOLD) { + C.data.mood = PET_MOOD_SAD; + } else if (C.data.happiness > MOOD_HAPPY_THRESHOLD) { + C.data.mood = PET_MOOD_HAPPY; + } else { + C.data.mood = PET_MOOD_CALM; + } +} + +// 更新宠物状态 +void update_pet_status(lv_timer_t *timer) +{ + if (!C.initialized) return; + + time_t current_time = time(NULL); + double elapsed_minutes = difftime(current_time, C.data.last_update) / 60.0; + + if (elapsed_minutes < 0.01) return; // 避免频繁更新 + + // 更新状态值 + if (!C.data.sleeping) { + // 正常状态下的变化 + C.data.hunger = (C.data.hunger > HUNGER_DECREASE_RATE * elapsed_minutes) + ? C.data.hunger - HUNGER_DECREASE_RATE * elapsed_minutes : 0; + + C.data.thirst = (C.data.thirst > THIRST_DECREASE_RATE * elapsed_minutes) + ? C.data.thirst - THIRST_DECREASE_RATE * elapsed_minutes : 0; + + // 心情变化逻辑 + double happiness_change = HAPPINESS_DECREASE_RATE * elapsed_minutes; + + // 如果饥饿或口渴低于阈值,心情下降更快 + if (C.data.hunger < HUNGER_THRESHOLD || C.data.thirst < THIRST_THRESHOLD) { + happiness_change *= 2; + } + + C.data.happiness = (C.data.happiness > happiness_change) + ? C.data.happiness - happiness_change : 0; + } else { + // 睡眠状态下的变化(大幅减缓下降速度) + C.data.hunger = (C.data.hunger > HUNGER_DECREASE_RATE * elapsed_minutes * 0.3) + ? C.data.hunger - HUNGER_DECREASE_RATE * elapsed_minutes * 0.3 : 0; + + C.data.thirst = (C.data.thirst > THIRST_DECREASE_RATE * elapsed_minutes * 0.3) + ? C.data.thirst - THIRST_DECREASE_RATE * elapsed_minutes * 0.3 : 0; + + // 睡眠时心情缓慢恢复 + C.data.happiness = (C.data.happiness + HAPPINESS_DECREASE_RATE * elapsed_minutes * 1.5 < 100) + ? C.data.happiness + HAPPINESS_DECREASE_RATE * elapsed_minutes * 1.5 : 100; + } + + // 经验值增长 + C.data.experience += EXP_INCREASE_RATE * elapsed_minutes; + + // 检查是否升级 + if (C.data.experience >= C.data.next_level_exp) { + C.data.level++; + C.data.experience = 0; // 升级后经验值清零 + C.data.next_level_exp = calc_experience_for_level(C.data.level + 1); + lv_label_set_text_fmt(R.ui.level_label, "Lv.%d", C.data.level); + + // 升级成就检查 + if (C.data.level == 5) { + add_achievement(ACHIEVEMENT_REACH_LEVEL_5); + } else if (C.data.level == 10) { + add_achievement(ACHIEVEMENT_REACH_LEVEL_10); + } + } + + // 更新心情状态 + update_pet_mood(); + + // 更新上次更新时间 + C.data.last_update = current_time; + + // 更新UI显示 + update_visuals(); + + // 定期保存数据 + static int save_counter = 0; + save_counter++; + if (save_counter >= 60) { // 每60次更新保存一次(约1分钟) + save_pet_data(); + save_counter = 0; + } +} + +// 更新视觉显示 +void update_visuals(void) +{ + // 更新状态条 + lv_bar_set_value(R.ui.hunger_bar, C.data.hunger, LV_ANIM_ON); + lv_bar_set_value(R.ui.thirst_bar, C.data.thirst, LV_ANIM_ON); + lv_bar_set_value(R.ui.happiness_bar, C.data.happiness, LV_ANIM_ON); + + // 更新经验条 + lv_bar_set_range(R.ui.exp_bar, 0, C.data.next_level_exp); + lv_bar_set_value(R.ui.exp_bar, C.data.experience, LV_ANIM_ON); + + // 根据状态更新宠物图像 + if (C.data.sleeping) { + lv_img_set_src(R.ui.pet_img, R.images.sleep_img); + } else { + // 根据当前状态显示不同图像 + switch (C.data.state) { + case PET_STATE_EATING: + lv_img_set_src(R.ui.pet_img, R.images.eat_img); + break; + case PET_STATE_DRINKING: + lv_img_set_src(R.ui.pet_img, R.images.drink_img); + break; + case PET_STATE_EXERCISING: + // 运动时根据心情显示不同图像 + switch (C.data.mood) { + case PET_MOOD_SAD: + lv_img_set_src(R.ui.pet_img, R.images.sad); + break; + case PET_MOOD_HAPPY: + lv_img_set_src(R.ui.pet_img, R.images.happy); + break; + case PET_MOOD_CALM: + default: + lv_img_set_src(R.ui.pet_img, R.images.calm); + break; + } + break; + case PET_STATE_NORMAL: + default: + // 正常状态下根据心情显示不同图像 + switch (C.data.mood) { + case PET_MOOD_SAD: + lv_img_set_src(R.ui.pet_img, R.images.sad); + break; + case PET_MOOD_HAPPY: + lv_img_set_src(R.ui.pet_img, R.images.happy); + break; + case PET_MOOD_CALM: + default: + lv_img_set_src(R.ui.pet_img, R.images.calm); + break; + } + break; + } + } +} + +// 重置宠物状态(用于动作结束后) +void reset_pet_state(lv_timer_t *timer) +{ + // 将状态恢复到正常 + C.data.state = PET_STATE_NORMAL; + + // 更新视觉显示,恢复到基于心情的图像 + update_visuals(); + + R.timers.state_timer = NULL; +} + +// 喂食事件 +void feed_pet(lv_event_t *e) +{ + if (C.data.sleeping || C.data.state != PET_STATE_NORMAL) + return; + + C.data.state = PET_STATE_EATING; + C.data.hunger = (C.data.hunger + 20 <= 100) ? C.data.hunger + 20 : 100; + C.data.happiness = (C.data.happiness + 5 <= 100) ? C.data.happiness + 5 : 100; + + static int feed_days = 0; + time_t now = time(NULL); + struct tm *tm_now = localtime(&now); + static int last_feed_day = -1; + + if (tm_now->tm_mday != last_feed_day) { + feed_days++; + last_feed_day = tm_now->tm_mday; + + // 检查连续7天喂食成就 + if (feed_days >= 7) { + add_achievement(ACHIEVEMENT_FEED_7_DAYS); + } + } + + // 更新显示状态数据,但不再更改宠物图像 + update_visuals(); + + // 创建状态重置定时器 + if (R.timers.state_timer != NULL) { + lv_timer_del(R.timers.state_timer); + } + R.timers.state_timer = lv_timer_create(reset_pet_state, STATE_DURATION, NULL); +} + +// 喝水事件 +void give_water(lv_event_t *e) +{ + if (C.data.sleeping || C.data.state != PET_STATE_NORMAL) + return; + + C.data.state = PET_STATE_DRINKING; + C.data.thirst = (C.data.thirst + 20 <= 100) ? C.data.thirst + 20 : 100; + C.data.happiness = (C.data.happiness + 5 <= 100) ? C.data.happiness + 5 : 100; + + static int water_days = 0; + time_t now = time(NULL); + struct tm *tm_now = localtime(&now); + static int last_water_day = -1; + + if (tm_now->tm_mday != last_water_day) { + water_days++; + last_water_day = tm_now->tm_mday; + + // 检查连续7天喝水成就 + if (water_days >= 7) { + add_achievement(ACHIEVEMENT_WATER_7_DAYS); + } + } + + // 更新显示状态数据,但不再更改宠物图像 + update_visuals(); + + // 创建状态重置定时器 + if (R.timers.state_timer != NULL) { + lv_timer_del(R.timers.state_timer); + } + R.timers.state_timer = lv_timer_create(reset_pet_state, STATE_DURATION, NULL); +} + +// 运动事件 +void exercise_pet(lv_event_t *e) +{ + if (C.data.sleeping || C.data.state != PET_STATE_NORMAL) + return; + + // 检查饥饿度和口渴度,如果任一为0则不允许运动 + if (C.data.hunger <= 0 || C.data.thirst <= 0) { + // 创建提示消息 + lv_obj_t* msg = lv_msgbox_create(NULL); + if (C.data.hunger <= 0 && C.data.thirst <= 0) { + lv_msgbox_add_title(msg, "Can't exercise"); + lv_msgbox_add_text(msg, "The pet is too hungry and thirsty, can't exercise!\nPlease feed and drink first."); + } else if (C.data.hunger <= 0) { + lv_msgbox_add_title(msg, "Can't exercise"); + lv_msgbox_add_text(msg, "The pet is too hungry, can't exercise!\nPlease feed first."); + } else { + lv_msgbox_add_title(msg, "Can't exercise"); + lv_msgbox_add_text(msg, "The pet is too thirsty, can't exercise!\nPlease drink first."); + } + lv_obj_t* btn = lv_msgbox_add_footer_button(msg, "OK"); + lv_obj_center(msg); + + // 自动关闭消息框 + lv_timer_t* timer = lv_timer_create(close_msgbox_timer_cb, 2000, msg); + lv_timer_set_repeat_count(timer, 1); + return; + } + + C.data.state = PET_STATE_EXERCISING; + C.data.hunger = (C.data.hunger > 10) ? C.data.hunger - 10 : 0; + C.data.thirst = (C.data.thirst > 15) ? C.data.thirst - 15 : 0; + C.data.happiness = (C.data.happiness + 15 <= 100) ? C.data.happiness + 15 : 100; + C.data.experience += 20; // 运动可以获得额外经验 + + static int exercise_days = 0; + time_t now = time(NULL); + struct tm *tm_now = localtime(&now); + static int last_exercise_day = -1; + + if (tm_now->tm_mday != last_exercise_day) { + exercise_days++; + last_exercise_day = tm_now->tm_mday; + + // 检查连续7天运动成就 + if (exercise_days >= 7) { + add_achievement(ACHIEVEMENT_EXERCISE_7_DAYS); + } + } + + // 更新显示状态数据,但不再更改宠物图像 + update_visuals(); + + // 创建状态重置定时器 + if (R.timers.state_timer != NULL) { + lv_timer_del(R.timers.state_timer); + } + R.timers.state_timer = lv_timer_create(reset_pet_state, STATE_DURATION, NULL); +} + +// 睡眠切换事件 +void toggle_sleep(lv_event_t *e) +{ + if (C.data.state != PET_STATE_NORMAL) + return; + + C.data.sleeping = !C.data.sleeping; + update_visuals(); +} + +// 定时器回调函数 +static void close_msgbox_timer_cb(lv_timer_t* timer) +{ + lv_msgbox_close(timer->user_data); +} + +// 添加成就 +void add_achievement(uint32_t achievement) +{ + if ((C.data.achievements & achievement) == 0) { + C.data.achievements |= achievement; + + // 显示成就提示 + lv_obj_t* achievement_msg = lv_msgbox_create(NULL); + lv_msgbox_add_title(achievement_msg, "New achievement unlocked!"); + + const char* achievement_text = NULL; + switch (achievement) { + case ACHIEVEMENT_FEED_7_DAYS: + achievement_text = "Feed for 7 days!"; + break; + case ACHIEVEMENT_WATER_7_DAYS: + achievement_text = "Drink for 7 days!"; + break; + case ACHIEVEMENT_EXERCISE_7_DAYS: + achievement_text = "Exercise for 7 days!"; + break; + case ACHIEVEMENT_SURVIVE_30_DAYS: + achievement_text = "Pet for 30 days!"; + break; + case ACHIEVEMENT_REACH_LEVEL_5: + achievement_text = "Pet level 5!"; + break; + case ACHIEVEMENT_REACH_LEVEL_10: + achievement_text = "Pet level 10!"; + break; + default: + achievement_text = "New achievement unlocked!"; + break; + } + + lv_msgbox_add_text(achievement_msg, achievement_text); + lv_obj_t* btn = lv_msgbox_add_footer_button(achievement_msg, "OK"); + lv_obj_center(achievement_msg); + + // 自动关闭消息框 + lv_timer_t* timer = lv_timer_create(close_msgbox_timer_cb, 3000, achievement_msg); + lv_timer_set_repeat_count(timer, 1); + } +} + +// 检查成就 +void check_achievements(void) +{ + // 检查存活天数成就 + if (C.data.days_alive >= 30) { + add_achievement(ACHIEVEMENT_SURVIVE_30_DAYS); + } +} + +// 随机事件初始化 +void init_random_event(void) +{ + // 随机事件将在未来的版本中实现 + // 例如:宠物生病、遇到玩伴等特殊事件 +} + +// 保存宠物数据到文件 +void save_pet_data(void) +{ + char save_path[256]; + snprintf(save_path, sizeof(save_path), "%s/pet_data.bin", RES_ROOT); + + int fd = open(save_path, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) { + LV_LOG_ERROR("Failed to open save file for writing"); + return; + } + + // 写入数据版本号 + uint32_t version = 1; + write(fd, &version, sizeof(version)); + + // 写入宠物数据 + write(fd, &C.data, sizeof(C.data)); + + close(fd); + LV_LOG_INFO("Pet data saved successfully"); +} + +// 从文件加载宠物数据 +bool load_pet_data(void) +{ + char save_path[256]; + snprintf(save_path, sizeof(save_path), "%s/pet_data.bin", RES_ROOT); + + int fd = open(save_path, O_RDONLY); + if (fd < 0) { + LV_LOG_WARN("No save file found, starting with default values"); + return false; + } + + // 读取数据版本号 + uint32_t version; + if (read(fd, &version, sizeof(version)) != sizeof(version)) { + LV_LOG_ERROR("Failed to read version from save file"); + close(fd); + return false; + } + + if (version != 1) { + LV_LOG_ERROR("Incompatible save file version"); + close(fd); + return false; + } + + // 读取宠物数据 + if (read(fd, &C.data, sizeof(C.data)) != sizeof(C.data)) { + LV_LOG_ERROR("Failed to read pet data from save file"); + close(fd); + return false; + } + + close(fd); + LV_LOG_INFO("Pet data loaded successfully"); + C.data_loaded = true; + return true; +} + +/** + * 启动更新定时器 + */ +static void app_start_updating_timers(void) +{ + R.timers.update_timer = lv_timer_create(update_pet_status, TIMER_UPDATE_PERIOD, NULL); + R.timers.time_update_timer = lv_timer_create(update_time_display, 1000, NULL); +} + +/** + * 加载图片资源 + */ +static void load_images(void) +{ + // 图片已经在init_resource中作为路径字符串加载, + // 不需要实际加载图片到内存,LVGL会直接显示图片文件 + LV_LOG_INFO("Using image paths instead of loading images to memory"); +} + + diff --git a/pet/pet.h b/pet/pet.h new file mode 100644 index 0000000000000000000000000000000000000000..69fa8b399c90838e468b85810792e5be619f7b86 --- /dev/null +++ b/pet/pet.h @@ -0,0 +1,183 @@ +#ifndef VIRTUAL_PET_H +#define VIRTUAL_PET_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <time.h> + +/********************* + * DEFINES + *********************/ +#define RES_ROOT CONFIG_LVX_PET_DATA_ROOT "/res" +#define IMAGES_ROOT RES_ROOT "/image" +#define FONTS_ROOT RES_ROOT "/fonts" +#define ICONS_ROOT RES_ROOT "/icons" + +// 常量定义 +#define HUNGER_THRESHOLD 30 +#define THIRST_THRESHOLD 30 +#define MOOD_SAD_THRESHOLD 30 +#define MOOD_HAPPY_THRESHOLD 70 +#define TIMER_UPDATE_PERIOD 1000 // 更新周期(ms) +#define STATE_DURATION 3000 // 状态持续时间(ms) +#define HUNGER_DECREASE_RATE 0.3 // 每分钟饥饿值下降,进一步减慢 +#define THIRST_DECREASE_RATE 0.4 // 每分钟口渴值下降,进一步减慢 +#define HAPPINESS_DECREASE_RATE 0.2 // 每分钟心情值下降,进一步减慢 +#define EXP_INCREASE_RATE 10 // 每分钟经验值增加 +#define ACHIEVEMENT_FEED_7_DAYS (1 << 0) +#define ACHIEVEMENT_WATER_7_DAYS (1 << 1) +#define ACHIEVEMENT_EXERCISE_7_DAYS (1 << 2) +#define ACHIEVEMENT_SURVIVE_30_DAYS (1 << 3) +#define ACHIEVEMENT_REACH_LEVEL_5 (1 << 4) +#define ACHIEVEMENT_REACH_LEVEL_10 (1 << 5) + +/********************** + * TYPEDEFS + **********************/ + +// 宠物状态 +typedef enum { + PET_MOOD_SAD = 0, + PET_MOOD_CALM = 1, + PET_MOOD_HAPPY = 2 +} pet_mood_t; + +typedef enum { + PET_STATE_NORMAL = 0, + PET_STATE_EATING = 1, + PET_STATE_DRINKING = 2, + PET_STATE_EXERCISING = 3, + PET_STATE_SLEEPING = 4 +} pet_state_t; + +// 宠物信息结构体 +typedef struct { + uint8_t level; // 宠物等级 + uint8_t hunger; // 饥饿值 (0-100) + uint8_t thirst; // 口渴值 (0-100) + uint8_t happiness; // 心情值 (0-100) + uint32_t experience; // 经验值 + uint32_t next_level_exp; // 下一级所需经验 + pet_mood_t mood; // 当前心情 + pet_state_t state; // 当前状态 + time_t last_update; // 上次更新时间 + bool sleeping; // 是否睡眠 + int days_alive; // 存活天数 + uint32_t achievements; // 成就(位图) +} pet_data_t; + +// UI资源结构体 +typedef struct { + struct { + lv_obj_t *status_bar; + lv_obj_t *time_label; + lv_obj_t *battery_label; + lv_obj_t *level_label; + + lv_obj_t *pet_area; + lv_obj_t *pet_img; + lv_obj_t *background_img; + + lv_obj_t *status_panel; + lv_obj_t *hunger_bar; + lv_obj_t *thirst_bar; + lv_obj_t *happiness_bar; + lv_obj_t *exp_bar; + + lv_obj_t *action_panel; + lv_obj_t *feed_btn; + lv_obj_t *water_btn; + lv_obj_t *exercise_btn; + lv_obj_t *sleep_btn; + } ui; + + struct { + struct { + lv_font_t* normal; + } size_16; + struct { + lv_font_t* bold; + } size_22; + struct { + lv_font_t* normal; + } size_24; + struct { + lv_font_t* normal; + } size_28; + struct { + lv_font_t* bold; + } size_60; + } fonts; + + struct { + lv_style_t button_default; + lv_style_t button_pressed; + lv_style_transition_dsc_t button_transition_dsc; + lv_style_transition_dsc_t transition_dsc; + } styles; + + struct { + const char* background; + const char* sad; + const char* calm; + const char* happy; + const char* eat_img; // 宠物进食图片 + const char* drink_img; // 宠物喝水图片 + const char* eat; // 喂食按钮图标 + const char* drink; // 喝水按钮图标 + const char* exercise; + const char* sleep_img; + const char* sleep_icon; + } images; + + struct { + lv_timer_t *update_timer; + lv_timer_t *state_timer; + lv_timer_t *time_update_timer; + } timers; +} pet_res_t; + +// 应用上下文 +typedef struct { + pet_data_t data; + bool initialized; + time_t start_time; + time_t action_start_time; + bool data_loaded; + bool resource_healthy_check; + lv_obj_t *current_pet_related_obj; +} pet_ctx_t; + +// 配置结构体 +typedef struct { + // 可扩展配置项 + int dummy; +} pet_conf_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void app_create(void); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* VIRTUAL_PET_H */ diff --git a/pet/pet_main.c b/pet/pet_main.c new file mode 100644 index 0000000000000000000000000000000000000000..7f09c4fec4c0825146ed1f10ad35166fcfe52e77 --- /dev/null +++ b/pet/pet_main.c @@ -0,0 +1,102 @@ +// +// Virtual Pet Demo Application Main +// + +/********************* + * INCLUDES + *********************/ +#include <nuttx/config.h> +#include <unistd.h> +#include <uv.h> +#include <lvgl/lvgl.h> +#include "pet.h" +#include <stdlib.h> +#include <time.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * LVGL UI循环函数 + */ +static void lv_nuttx_uv_loop(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +/** + * 主函数入口 + */ +int main(int argc, FAR char* argv[]) +{ + // 初始化LVGL + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + // 初始化NuttX平台适配 + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("LVGL initialization failure!"); + return 1; + } + + // 创建虚拟宠物应用 + app_create(); + + // 启动LVGL UI刷新循环 + lv_nuttx_uv_loop(&ui_loop, &result); + + // 清理资源 + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} \ No newline at end of file diff --git a/pet/res/config.json b/pet/res/config.json new file mode 100644 index 0000000000000000000000000000000000000000..b760c4852d1c9399dd0b15b7ff5f6b0cc7abe6fa --- /dev/null +++ b/pet/res/config.json @@ -0,0 +1,6 @@ +{ + "wifi": { + "ssid": "BenignX", + "pswd": "19991123" + } +} diff --git a/pet/res/fonts/MiSans-Normal.ttf b/pet/res/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/pet/res/fonts/MiSans-Normal.ttf differ diff --git a/pet/res/fonts/MiSans-Semibold.ttf b/pet/res/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/pet/res/fonts/MiSans-Semibold.ttf differ diff --git a/pet/res/icons/drink.png b/pet/res/icons/drink.png new file mode 100644 index 0000000000000000000000000000000000000000..d27f834a7651d8651d5b9d9cb57e5a22e531ff0b Binary files /dev/null and b/pet/res/icons/drink.png differ diff --git a/pet/res/icons/eat.png b/pet/res/icons/eat.png new file mode 100644 index 0000000000000000000000000000000000000000..28f064048b3699e897e37633eeaeed22bfdbe646 Binary files /dev/null and b/pet/res/icons/eat.png differ diff --git a/pet/res/icons/exercise.png b/pet/res/icons/exercise.png new file mode 100644 index 0000000000000000000000000000000000000000..44f30182f48eacf967941dec336b191782b75148 Binary files /dev/null and b/pet/res/icons/exercise.png differ diff --git a/pet/res/icons/sleep.png b/pet/res/icons/sleep.png new file mode 100644 index 0000000000000000000000000000000000000000..6af4c5b49ab7688d61c0c9def66f1d58eb6d3bcb Binary files /dev/null and b/pet/res/icons/sleep.png differ diff --git a/pet/res/image/background.png b/pet/res/image/background.png new file mode 100644 index 0000000000000000000000000000000000000000..f992554143efddb2066359b39c4c590d8fd674f8 Binary files /dev/null and b/pet/res/image/background.png differ diff --git a/pet/res/image/calm.png b/pet/res/image/calm.png new file mode 100644 index 0000000000000000000000000000000000000000..52245e371ea02171de02e212e051c6a1cfc57c18 Binary files /dev/null and b/pet/res/image/calm.png differ diff --git a/pet/res/image/drink.png b/pet/res/image/drink.png new file mode 100644 index 0000000000000000000000000000000000000000..31ef912b62e47809eda7669b26210931252a3b83 Binary files /dev/null and b/pet/res/image/drink.png differ diff --git a/pet/res/image/eat.png b/pet/res/image/eat.png new file mode 100644 index 0000000000000000000000000000000000000000..cd3c4e49524fa686d7b6f0dbcca18ea96cbcaff1 Binary files /dev/null and b/pet/res/image/eat.png differ diff --git a/pet/res/image/happy.png b/pet/res/image/happy.png new file mode 100644 index 0000000000000000000000000000000000000000..56c7a3ea1fa6138e43ed2cc06d508f4af8fcecdb Binary files /dev/null and b/pet/res/image/happy.png differ diff --git a/pet/res/image/sad.png b/pet/res/image/sad.png new file mode 100644 index 0000000000000000000000000000000000000000..bc3ce3e0284df79589abb45ba2317b569f02d6cb Binary files /dev/null and b/pet/res/image/sad.png differ diff --git a/pet/res/image/sleep.png b/pet/res/image/sleep.png new file mode 100644 index 0000000000000000000000000000000000000000..5625dd099b8cc2a27b1d853e7449a89f2f987aba Binary files /dev/null and b/pet/res/image/sleep.png differ diff --git a/relation_calculator/Kconfig b/relation_calculator/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..3e069ad730fc680f6a9a84cdb5a6228a9099a568 --- /dev/null +++ b/relation_calculator/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_RELATIVES_CALCULATOR + bool "Relatives Calculator" + default n diff --git a/relation_calculator/Make.defs b/relation_calculator/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..9a6d721d371b3bd92951c72f9c12aef1070e7a25 --- /dev/null +++ b/relation_calculator/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_RELATIVES_CALCULATOR),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/relation_calculator +endif diff --git a/relation_calculator/Makefile b/relation_calculator/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8c0e85df9a8fc8e6f70197c9f07ae27dd6840c64 --- /dev/null +++ b/relation_calculator/Makefile @@ -0,0 +1,35 @@ +# +# Copyright (C) 2022 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_RELATIVES_CALCULATOR), y) +PROGNAME = rel_cal +PRIORITY = 100 +STACKSIZE = 131072 +MODULE = $(CONFIG_LVX_USE_DEMO_RELATIVES_CALCULATOR) + +MAINSRC = relation_cal_main.c +CSRCS += relation_cal.c +ifeq ($(CONFIG_ESP32S3_BOX_LCD), y) +CSRCS += ./fonts/lv_font_siyuan_10.c +else +CSRCS += ./fonts/lv_font_siyuan_16.c +endif + +include $(APPDIR)/Application.mk + +endif \ No newline at end of file diff --git a/relation_calculator/Readme.md b/relation_calculator/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..fd58d57d10b5b2d24a357e6e52a289a47915f2f9 --- /dev/null +++ b/relation_calculator/Readme.md @@ -0,0 +1,181 @@ +# Relatives Calculator Demo Quick Start + +\[ English | [简体中文](Readme_zh-cn.md) \] + +This document provides a comprehensive guide to building, deploying, and running the **Relatives Calculator** demo application on the `openvela` system. It covers procedures for both the QEMU emulator and the ESP32-S3-BOX development board, as well as how to customize the application by adding new relationships. + +## I. Demonstration + +![img](./img/show.gif) + +## II. Build and Run + +This section walks you through the entire process, from project configuration to launching the application on your target platform. + +### Prerequisites + +Before you begin, ensure you are in the root directory of the `openvela` repository. All commands in this guide assume they are executed from this location. + +### Step 1: Configure the Project + +Use the `menuconfig` utility to enable the **Relatives Calculator** demo application. + +1. Launch `menuconfig` by selecting the command that matches your target platform: + + - **For the QEMU emulator:** + + ```bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + + - **For the ESP32-S3-BOX development board:** + + ```bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 menuconfig + ``` + +2. Inside the `menuconfig` interface, press the `/` key to open the search tool. Find and enable the following configuration option: + + ```kconfig + LVX_USE_DEMO_RELATIVES_CALCULATOR=y + ``` + +3. Save your configuration and exit `menuconfig`. + +### Step 2: Build the Project + +It is recommended to clean previous build artifacts before starting a new compilation to avoid potential conflicts. + +1. Clean previous build artifacts (distclean): + + - **For the QEMU emulator:** + + ```bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 + ``` + + - **For the ESP32-S3-BOX development board:** + + ```bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 distclean -j8 + ``` + +2. Execute the build: + + - **For the QEMU emulator:** + + ```bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 + ``` + + - **For the ESP32-S3-BOX development board:** + + ```bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 -j8 + ``` + +### Step 3: Deploy and Run the Application + +After a successful build, follow the instructions for your target platform to deploy the firmware and run the calculator. + +#### Option A: Run on the QEMU Emulator + +1. From the `openvela` root directory, start the emulator: + + ```bash + ./emulator.sh vela + ``` + +2. Once the `openvela` terminal (`openvela-ap>`) appears, run the following command to start the application in the background: + + ```bash + rel_cal & + ``` + +#### Option B: Run on the ESP32-S3-BOX Board + +1. Flash the Firmware: + + Connect the ESP32-S3-BOX board to your computer via USB. Run the following command to flash the firmware. Remember to replace `/dev/ttyACM0` with your device's actual serial port. + + ```bash + pushd nuttx && make -j8 flash ESPTOOL_PORT=/dev/ttyACM0 ESPTOOL_BINDIR=./ && popd + ``` + +2. Open the Serial Terminal: + + Use a serial terminal tool like `minicom` to monitor the device output and interact with the Shell. + + ```bash + sudo minicom -D /dev/ttyACM0 -b 115200 + ``` + +3. Start the Calculator: + + In the `minicom` terminal, enter the following command. + + ```bash + rel_cal & + ``` + +## III. Customizing the Application + +You can extend the calculator's functionality by adding new relationships. All modifications are made within the `demos/relation_calculator/relation_cal.c` file. + +The calculator uses a state transition model to determine the final relationship. To add a new relationship, you need to define its transition logic and its corresponding name. + +### 1. Define the Relationship Logic + +In the `transitions` array, add a new entry to define how relationships combine. Each entry follows the `relation_transformation_t` struct format. + +For example, `[Me]` `[Father]` = `[Father]` is defined as: `{ME, FATHER, FATHER}`. + +```c +// Defines the logic for relationship transitions +typedef struct relation_transformation_s +{ + relation_type_t from; // The current relationship state + relation_type_t to; // The new input relationship (button pressed) + relation_type_t result; // The resulting relationship state +} relation_transformation_t; + +// Add new state transitions to this array +static const relation_transformation_t transitions[] = { + // ... existing transitions ... + { ME, FATHER, FATHER }, // Example: "My" + "Father" results in "Father" + // Add your new transition logic here +}; +``` + +### 2. Define the Relationship Type and Name + +First, add a new enumerator to `relation_type_e`. Then, add the corresponding display name as a string to the `relation_names` array. + +**Important:** The order of entries in the `relation_names` array must exactly match the order in the `relation_type_e` enum to ensure the calculator displays the correct text. + +```c +// 1. Add the new relationship type to the enum +typedef enum relation_type_e +{ + // ... existing types ... + NEW_RELATIONSHIP, // Your new relationship type +} relation_type_t; + +// 2. Add the corresponding name to the names array +static const char *relation_names[] = { + // ... existing names ... + "New Relationship", // The display name for NEW_RELATIONSHIP +}; +``` + +After making these changes, rebuild and deploy the project to see your new relationship in the calculator. + +## IV. Implementation Overview + +The Relatives Calculator is implemented using a state transition system. Each button press triggers a state change, transforming the current relationship (e.g., "Me") into a new one (e.g., "Father") based on a predefined transition table. This model provides a clear and extensible way to manage complex family relationship calculations. + +## V. Contributing and Future Improvements + +The current state-transition implementation requires a significant amount of predefined static data to build a complete relationship graph. We are actively seeking more efficient and scalable models to optimize the relationship network. + +If you have ideas for a better implementation or want to contribute, we welcome you to open an Issue or submit a Pull Request to discuss your approach with the community. diff --git a/relation_calculator/Readme_zh-cn.md b/relation_calculator/Readme_zh-cn.md new file mode 100644 index 0000000000000000000000000000000000000000..60bda301099883881a9329f18e8c0501bf12a319 --- /dev/null +++ b/relation_calculator/Readme_zh-cn.md @@ -0,0 +1,175 @@ +# 亲戚计算器 Demo 快速上手 + +\[ [English](Readme.md) | 简体中文 \] + +本文档为在 `openvela` 系统上构建、部署和运行**亲戚计算器**演示应用提供了全面的指导。内容涵盖 QEMU 模拟器和 ESP32-S3-BOX 开发板的操作流程,以及如何通过增加新关系来自定义此应用。 + +## 一、运行效果 + +![img](./img/show.gif) + +## 二、构建与运行 + +本章节将引导您完成从项目配置到在目标平台上启动应用的完整过程。 + +### 准备工作 + +在开始之前,请确保您位于 `openvela` 仓库的根目录下。本指南中的所有命令均默认从该位置执行。 + +### 第一步:配置项目 + +使用 `menuconfig` 工具来启用**亲戚计算器**演示应用。 + +1. 根据您的目标平台,选择对应的命令启动 `menuconfig`: + + - **QEMU 模拟器:** + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + + - **ESP32-S3-BOX 开发板:** + + ```Bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 menuconfig + ``` + +2. 在 `menuconfig` 界面中,按下 `/` 键打开搜索工具,查找并启用以下配置项: + + ```Bash + LVX_USE_DEMO_RELATIVES_CALCULATOR=y + ``` + +3. 保存您的配置并退出 `menuconfig`。 + +### 第二步:构建项目 + +为避免潜在的冲突,建议在开始新的编译前清理旧的构建产物。 + +1. 清理构建产物 (distclean): + + - **QEMU 模拟器:** + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 + ``` + + - **ESP32-S3-BOX 开发板:** + + ```Bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 distclean -j8 + ``` + +2. 执行构建: + + - **QEMU 模拟器:** + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 + ``` + + - **ESP32-S3-BOX 开发板:** + + ```Bash + ./build.sh nuttx/boards/xtensa/esp32s3/esp32s3-box/configs/lvgl-3 -j8 + ``` + +### 第三步:部署并运行应用 + +成功构建后,请根据您的目标平台执行相应指令来部署固件并运行计算器。 + +#### 选项 A:在 QEMU 模拟器上运行 + +1. 在 `openvela` 根目录,执行以下命令启动模拟器: + + ```Bash + ./emulator.sh vela + ``` + +2. 等待 openvela 终端(`openvela-ap>`)出现后,运行以下命令在后台启动应用: + + ```Bash + rel_cal & + ``` + +#### 选项 B:在 ESP32-S3-BOX 开发板上运行 + +1. 烧录固件: 通过 USB 将 ESP32-S3-BOX 开发板连接到您的计算机。运行以下命令烧录固件,需将 `/dev/ttyACM0` 替换为您设备的实际串口号。 + + ```Bash + pushd nuttx && make -j8 flash ESPTOOL_PORT=/dev/ttyACM0 ESPTOOL_BINDIR=./ && popd + ``` + +2. 打开串口终端: 使用 `minicom` 等串口终端工具来监控设备输出并与 Shell 交互。 + + ```Bash + sudo minicom -D /dev/ttyACM0 -b 115200 + ``` + +3. 启动计算器: 在 `minicom` 的终端中,输入以下命令。 + + ```Bash + rel_cal & + ``` + +## 三、自定义应用 + +您可以通过修改 `demos/relation_calculator/relation_cal.c` 文件来扩展计算器功能,增加新的关系。 + +此计算器采用状态转移模型来确定最终关系。要增加一个新关系,您需要定义其转换逻辑和对应的名称。 + +### 1、定义关系逻辑 + +在 `transitions` 数组中,添加一个新的条目来定义关系如何组合。每个条目遵循 `relation_transformation_t` 结构体格式。 + +例如,`[我][爸爸]` = `[爸爸]`,这一逻辑被定义为:`{ME, FATHER, FATHER}`。 + +```C +// 定义关系转换的逻辑 +typedef struct relation_transformation_s +{ + relation_type_t from; // 当前的关系状态 + relation_type_t to; // 新输入的关系(按下的按钮) + relation_type_t result; // 最终得到的关系状态 +} relation_transformation_t; + +// 将新的状态转换逻辑添加到此数组中 +static const relation_transformation_t transitions[] = { + // ... 已有的转换关系 ... + { ME, FATHER, FATHER }, // 示例:我的爸爸是爸爸 + // 在此处添加您新的转换逻辑 +}; +``` + +### 2、定义关系类型与名称 + +首先,在 `relation_type_e` 枚举中添加一个新的关系类型。然后,在 `relation_names` 数组中添加其对应的显示名称字符串。 + +**重要提示:** `relation_names` 数组中条目的顺序必须与 `relation_type_e` 枚举中的顺序严格对应,以确保计算器能显示正确的文本。 + +```C +// 1. 在枚举中添加新的关系类型 +typedef enum relation_type_e +{ + // ... 已有的类型 ... + NEW_RELATIONSHIP, // 您定义的新关系类型 +} relation_type_t; + +// 2. 在名称数组中添加对应的名称 +static const char *relation_names[] = { + // ... 已有的名称 ... + "新关系", // NEW_RELATIONSHIP 对应的显示名称 +}; +``` + +完成这些修改后,重新构建并部署项目,即可在计算器中看到您添加的新关系。 + +## 四、实现原理概述 + +亲戚计算器是基于一个状态转移系统实现的。用户的每一次按键操作都会触发一次状态变更,系统会根据预定义的转换表,将当前关系(如“我”)转换为一个新的关系(如“爸爸”)。该模型能够以清晰且可扩展的方式管理复杂的亲属关系计算。 + +## 五、贡献与未来改进 + +当前基于状态转移的实现方式需要预定义大量的静态数据来构建完整的关系图谱。我们正在积极寻求更高效、更具扩展性的模型来优化关系网的构建方式。 + +如果您对此有更好的实现思路或愿意参与贡献,我们非常欢迎您通过提交 Issue 或 Pull Request 来与社区共同探讨。 diff --git a/relation_calculator/fonts/lv_font_siyuan_10.c b/relation_calculator/fonts/lv_font_siyuan_10.c new file mode 100644 index 0000000000000000000000000000000000000000..c7a589000cfa01575ec394444e516e05d46fe685 --- /dev/null +++ b/relation_calculator/fonts/lv_font_siyuan_10.c @@ -0,0 +1,1027 @@ +/******************************************************************************* + * Size: 10 px + * Bpp: 1 + * Opts: --bpp 1 --size 10 --no-compress --font SourceHanSansCN-Bold.ttf --symbols 父、亲、夫、丈、儿、子、哥、姐、母、妻、女、弟、妹、自、己、祖、伯、姑、堂、曾、外、舅、姨、侄、媳、婿、孙、姥、公、奶、爷、甥、嫡、庶、继、养、岳、妯、娌、玄、叔、清除、计算、<-、\n、空格、请、输、入、选、择、确、定、返、回、主、菜、单、计、算、结、果、关、系、帮、助、说、明、界、面、查、询、显、示、祖母、伯父、姑母、堂兄弟、堂姐妹、曾祖父、曾祖母、外祖父、外祖母、外曾祖父、外曾祖母、表侄、表侄女、再从兄弟、再从姐妹、叔祖父、姑祖母、舅父、姨母、侄子、侄女、儿媳、女婿、孙子、孙女、曾孙子、曾孙女、堂侄 / 表侄、堂侄女 / 表侄女、孙侄、孙侄女、未知、0、1、2、3、4、5、6、7、8、9、+、-、×、÷、=、?、!、,、。、:、;、《》、[]、{}、@、#、←、→、↑、↓、√、×、这、是、一、个、亲、属、关、系、计、算、器、。、未、支、持、关、系、:、“、未、知、”、。的 --range 32-127 --format lvgl -o lv_font_siyuan_10.c + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_FONT_SIYUAN_10 +#define LV_FONT_SIYUAN_10 1 +#endif + +#if LV_FONT_SIYUAN_10 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xaa, 0x8f, + + /* U+0022 "\"" */ + 0xff, 0xf0, + + /* U+0023 "#" */ + 0x52, 0xbe, 0xa5, 0x7e, 0x52, + + /* U+0024 "$" */ + 0x23, 0xb1, 0x8f, 0x1c, 0x73, 0xf1, 0x0, + + /* U+0025 "%" */ + 0x64, 0x4a, 0x25, 0x13, 0x66, 0xc8, 0xa4, 0x52, + 0x26, + + /* U+0026 "&" */ + 0x38, 0x91, 0x61, 0x87, 0x3b, 0xf3, 0x3d, + + /* U+0027 "'" */ + 0xfc, + + /* U+0028 "(" */ + 0x5a, 0xaa, 0x94, + + /* U+0029 ")" */ + 0xa5, 0x55, 0x68, + + /* U+002A "*" */ + 0x23, 0x88, 0xa0, + + /* U+002B "+" */ + 0x21, 0x3e, 0x42, 0x0, + + /* U+002C "," */ + 0xf6, + + /* U+002D "-" */ + 0xc0, + + /* U+002E "." */ + 0xf0, + + /* U+002F "/" */ + 0x22, 0x22, 0x24, 0x44, 0x48, 0x80, + + /* U+0030 "0" */ + 0x76, 0xf7, 0xbd, 0xef, 0x6e, + + /* U+0031 "1" */ + 0x6e, 0x66, 0x66, 0x6f, + + /* U+0032 "2" */ + 0x74, 0xc6, 0x33, 0x19, 0x9f, + + /* U+0033 "3" */ + 0x72, 0x42, 0x60, 0x85, 0x2e, + + /* U+0034 "4" */ + 0x39, 0xde, 0xbd, 0xfc, 0x63, + + /* U+0035 "5" */ + 0x79, 0x4, 0x1e, 0xc, 0x30, 0xde, + + /* U+0036 "6" */ + 0x76, 0x31, 0xed, 0xef, 0x6e, + + /* U+0037 "7" */ + 0xf8, 0x8c, 0x66, 0x31, 0x8c, + + /* U+0038 "8" */ + 0x73, 0x2c, 0x9e, 0x5b, 0x3c, 0xde, + + /* U+0039 "9" */ + 0x76, 0xf7, 0xb7, 0x8c, 0x6e, + + /* U+003A ":" */ + 0xf0, 0xf0, + + /* U+003B ";" */ + 0xf0, 0xf6, + + /* U+003C "<" */ + 0x1, 0xf9, 0xc3, 0x80, + + /* U+003D "=" */ + 0xf8, 0x1, 0xf0, + + /* U+003E ">" */ + 0x7, 0xe, 0x7e, 0x0, + + /* U+003F "?" */ + 0xe3, 0x36, 0x40, 0x66, + + /* U+0040 "@" */ + 0x1e, 0x30, 0x90, 0x33, 0x9a, 0x4d, 0x6e, 0xfd, + 0x0, 0x40, 0x1e, 0x0, + + /* U+0041 "A" */ + 0x30, 0xe3, 0x9a, 0x49, 0xfc, 0xf1, + + /* U+0042 "B" */ + 0xf3, 0x6d, 0xbc, 0xcf, 0x3c, 0xfe, + + /* U+0043 "C" */ + 0x3d, 0x9c, 0x30, 0xc3, 0x6, 0x4f, + + /* U+0044 "D" */ + 0xf3, 0x6c, 0xf3, 0xcf, 0x3d, 0xbc, + + /* U+0045 "E" */ + 0xfe, 0x31, 0xfc, 0x63, 0x1f, + + /* U+0046 "F" */ + 0xfe, 0x31, 0x8f, 0xe3, 0x18, + + /* U+0047 "G" */ + 0x39, 0xac, 0x30, 0xdf, 0x36, 0xcf, + + /* U+0048 "H" */ + 0xcf, 0x3c, 0xff, 0xcf, 0x3c, 0xf3, + + /* U+0049 "I" */ + 0xff, 0xff, + + /* U+004A "J" */ + 0x18, 0xc6, 0x31, 0x8e, 0x7e, + + /* U+004B "K" */ + 0xcd, 0xb3, 0x47, 0x8f, 0x99, 0x33, 0x62, + + /* U+004C "L" */ + 0xc6, 0x31, 0x8c, 0x63, 0x1f, + + /* U+004D "M" */ + 0xc7, 0xdf, 0xbf, 0x7e, 0xfa, 0xf5, 0xe3, + + /* U+004E "N" */ + 0xcf, 0xbe, 0xfb, 0xdf, 0x7d, 0xf3, + + /* U+004F "O" */ + 0x38, 0xdb, 0x1e, 0x3c, 0x78, 0xdb, 0x1c, + + /* U+0050 "P" */ + 0xfb, 0x3c, 0xf3, 0xfb, 0xc, 0x30, + + /* U+0051 "Q" */ + 0x38, 0xdb, 0x1e, 0x3c, 0x78, 0xdb, 0x1e, 0x18, + 0x1c, + + /* U+0052 "R" */ + 0xfb, 0x3c, 0xf3, 0xfb, 0x6c, 0xb3, + + /* U+0053 "S" */ + 0x76, 0xb1, 0xe7, 0x8e, 0x7e, + + /* U+0054 "T" */ + 0xfc, 0xc3, 0xc, 0x30, 0xc3, 0xc, + + /* U+0055 "U" */ + 0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xde, + + /* U+0056 "V" */ + 0xc7, 0x34, 0xd2, 0x69, 0xe3, 0xc, + + /* U+0057 "W" */ + 0xc9, 0xe6, 0xd7, 0x6a, 0xa5, 0x52, 0xa9, 0xdc, + 0x66, + + /* U+0058 "X" */ + 0x4d, 0xa3, 0x8c, 0x31, 0xe4, 0xb3, + + /* U+0059 "Y" */ + 0xcf, 0x34, 0x9e, 0x30, 0xc3, 0xc, + + /* U+005A "Z" */ + 0xf8, 0xcc, 0x46, 0x23, 0x1f, + + /* U+005B "[" */ + 0xea, 0xaa, 0xb0, + + /* U+005C "\\" */ + 0x84, 0x44, 0x42, 0x22, 0x21, 0x10, + + /* U+005D "]" */ + 0xd5, 0x55, 0x70, + + /* U+005E "^" */ + 0x66, 0x69, 0x90, + + /* U+005F "_" */ + 0xfc, + + /* U+0060 "`" */ + 0x19, 0x80, + + /* U+0061 "a" */ + 0x70, 0xdf, 0xbd, 0xfc, + + /* U+0062 "b" */ + 0xc6, 0x3d, 0xbd, 0xef, 0x7e, + + /* U+0063 "c" */ + 0x7e, 0x31, 0x8c, 0xbc, + + /* U+0064 "d" */ + 0x18, 0xdf, 0xbd, 0xef, 0x6f, + + /* U+0065 "e" */ + 0x76, 0x7f, 0x8c, 0x3c, + + /* U+0066 "f" */ + 0xfb, 0xed, 0xb6, + + /* U+0067 "g" */ + 0x7f, 0x6d, 0x9c, 0xc1, 0xf8, 0xfe, + + /* U+0068 "h" */ + 0xc6, 0x3f, 0xbd, 0xef, 0x7b, + + /* U+0069 "i" */ + 0xcf, 0xff, + + /* U+006A "j" */ + 0x61, 0xb6, 0xdb, 0x78, + + /* U+006B "k" */ + 0xc3, 0xc, 0xb4, 0xf3, 0xcd, 0xb2, + + /* U+006C "l" */ + 0xdb, 0x6d, 0xb7, + + /* U+006D "m" */ + 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, + + /* U+006E "n" */ + 0xfe, 0xf7, 0xbd, 0xec, + + /* U+006F "o" */ + 0x7b, 0x3c, 0xf3, 0xcd, 0xe0, + + /* U+0070 "p" */ + 0xf6, 0xf7, 0xbd, 0xfb, 0x18, + + /* U+0071 "q" */ + 0x7e, 0xf7, 0xbd, 0xbc, 0x63, + + /* U+0072 "r" */ + 0xfc, 0xcc, 0xcc, + + /* U+0073 "s" */ + 0x78, 0xe7, 0x9e, + + /* U+0074 "t" */ + 0x66, 0xf6, 0x66, 0x63, + + /* U+0075 "u" */ + 0xde, 0xf7, 0xbd, 0xfc, + + /* U+0076 "v" */ + 0xc9, 0x24, 0x9e, 0x30, 0xc0, + + /* U+0077 "w" */ + 0xc9, 0x59, 0x5f, 0x57, 0x76, 0x36, + + /* U+0078 "x" */ + 0x4b, 0xcc, 0x65, 0xe4, + + /* U+0079 "y" */ + 0xc9, 0x25, 0x9c, 0x30, 0xc2, 0x18, + + /* U+007A "z" */ + 0xf3, 0x64, 0xcf, + + /* U+007B "{" */ + 0x69, 0x25, 0x12, 0x4c, + + /* U+007C "|" */ + 0xff, 0xf0, + + /* U+007D "}" */ + 0xc9, 0x24, 0x52, 0x58, + + /* U+007E "~" */ + 0x60, 0x60, + + /* U+00D7 "×" */ + 0x85, 0x23, 0xc, 0x4a, 0x10, + + /* U+00F7 "÷" */ + 0x18, 0x30, 0x7, 0xf0, 0x3, 0x6, 0x0, + + /* U+201C "“" */ + 0x5a, 0xf0, + + /* U+201D "”" */ + 0xf5, 0xa0, + + /* U+2190 "←" */ + 0x10, 0x8, 0xf, 0xfc, 0x80, 0x10, 0x0, + + /* U+2191 "↑" */ + 0x23, 0xbe, 0x42, 0x10, 0x84, 0x20, + + /* U+2192 "→" */ + 0x2, 0x0, 0x4f, 0xfc, 0x4, 0x2, 0x0, + + /* U+2193 "↓" */ + 0x21, 0x8, 0x42, 0x13, 0xee, 0x20, + + /* U+221A "√" */ + 0x7, 0xc1, 0x0, 0x80, 0x20, 0x8, 0x4, 0x5, + 0x1, 0x40, 0x20, 0x8, 0x0, + + /* U+3001 "、" */ + 0xc6, 0x20, + + /* U+3002 "。" */ + 0x69, 0x96, + + /* U+300A "《" */ + 0x1, 0x94, 0xaa, 0x51, 0x8a, 0x31, 0x40, + + /* U+300B "》" */ + 0x3, 0x14, 0xa2, 0x94, 0xca, 0x65, 0x0, + + /* U+4E00 "一" */ + 0xff, 0x80, + + /* U+4E08 "丈" */ + 0x4, 0x7f, 0xd1, 0xc, 0x82, 0xc0, 0xc0, 0xf1, + 0xcf, + + /* U+4E2A "个" */ + 0x8, 0xe, 0xd, 0x9d, 0x30, 0x80, 0x40, 0x20, + 0x10, 0x8, 0x0, + + /* U+4E3B "主" */ + 0x18, 0x6, 0x3f, 0xe1, 0x0, 0x83, 0xf8, 0x20, + 0x10, 0xff, 0x80, + + /* U+4EB2 "亲" */ + 0x8, 0x3f, 0xc8, 0x9f, 0xf0, 0x87, 0xfc, 0xa8, + 0x92, 0x19, 0x0, + + /* U+4ECE "从" */ + 0x22, 0x11, 0x8, 0x84, 0x43, 0x63, 0xf9, 0x14, + 0x9b, 0xd8, 0x80, + + /* U+4F2F "伯" */ + 0x24, 0x64, 0x5f, 0xd1, 0xd1, 0x5f, 0x51, 0x51, + 0x5f, 0x51, + + /* U+4F84 "侄" */ + 0x7f, 0xa4, 0xb6, 0x5f, 0xf4, 0x43, 0xfd, 0x10, + 0xff, 0x40, 0x0, + + /* U+513F "儿" */ + 0x22, 0x11, 0x8, 0x84, 0x42, 0x21, 0x11, 0x8a, + 0x85, 0x83, 0x80, + + /* U+5144 "兄" */ + 0x7f, 0x20, 0x90, 0x4f, 0xe3, 0x41, 0x20, 0x92, + 0xc9, 0xc7, 0x80, + + /* U+5165 "入" */ + 0x10, 0x2, 0x0, 0xc0, 0x38, 0x1a, 0x6, 0xc3, + 0x19, 0x83, 0x40, 0x0, + + /* U+516C "公" */ + 0x12, 0xc, 0xc6, 0x19, 0x22, 0x18, 0x4, 0xc2, + 0x11, 0xfe, 0x0, 0x80, + + /* U+5173 "关" */ + 0x63, 0x19, 0x1f, 0xc1, 0xf, 0xf8, 0xe0, 0xd9, + 0xc7, 0x0, 0x80, + + /* U+517B "养" */ + 0x22, 0x7f, 0xdf, 0xdf, 0xf6, 0x23, 0x1b, 0xde, + 0x4c, 0x46, 0x0, + + /* U+518D "再" */ + 0xff, 0x84, 0x1f, 0xc9, 0x27, 0xf2, 0x4b, 0xfe, + 0x82, 0x47, 0x0, + + /* U+52A9 "助" */ + 0x72, 0x29, 0x1d, 0xea, 0x57, 0x2a, 0x95, 0xf3, + 0xd9, 0xb, 0x80, + + /* U+5355 "单" */ + 0x22, 0x3f, 0x92, 0x4f, 0xe4, 0x91, 0xf3, 0xfe, + 0x10, 0x8, 0x0, + + /* U+53D4 "叔" */ + 0x27, 0x9f, 0xc9, 0x3f, 0xf2, 0x37, 0x5a, 0xad, + 0x4f, 0x64, 0x80, + + /* U+54E5 "哥" */ + 0xff, 0xbe, 0x91, 0x4f, 0xaf, 0xfb, 0xe9, 0x14, + 0xfa, 0x3, 0x0, + + /* U+5668 "器" */ + 0x77, 0x2a, 0x9d, 0xc3, 0x4f, 0xfb, 0x1b, 0xde, + 0xaa, 0x77, 0x0, + + /* U+56DE "回" */ + 0xff, 0x81, 0xbd, 0xa5, 0xa5, 0xbd, 0x81, 0xff, + 0x81, + + /* U+5802 "堂" */ + 0x49, 0x7f, 0xe0, 0x37, 0xd2, 0x20, 0xe1, 0xfc, + 0x10, 0xff, 0x80, + + /* U+5916 "外" */ + 0x22, 0xf, 0x84, 0xb1, 0xac, 0x3a, 0x86, 0x83, + 0x21, 0x88, 0x42, 0x0, + + /* U+592B "夫" */ + 0x8, 0x3f, 0x82, 0x1, 0xf, 0xf8, 0xe0, 0xd0, + 0xc6, 0xc1, 0x80, + + /* U+5973 "女" */ + 0x18, 0x8, 0x3f, 0xe4, 0x46, 0x63, 0xa0, 0x39, + 0xf7, 0xc1, 0x0, + + /* U+5976 "奶" */ + 0x4f, 0x7a, 0xbd, 0x5a, 0xff, 0x4b, 0x64, 0xe2, + 0xd1, 0xdb, 0x80, + + /* U+59AF "妯" */ + 0x42, 0x21, 0x3f, 0xf7, 0x5b, 0xfb, 0xd5, 0xeb, + 0xff, 0x98, 0x80, + + /* U+59B9 "妹" */ + 0x42, 0x77, 0xe8, 0x97, 0xfe, 0x73, 0x39, 0xbf, + 0xf5, 0x82, 0x0, + + /* U+59BB "妻" */ + 0xff, 0xbf, 0x9f, 0xdf, 0xf7, 0xf7, 0xfc, 0xc8, + 0x3c, 0xfb, 0x0, + + /* U+59D0 "姐" */ + 0x4f, 0x24, 0xba, 0x55, 0xea, 0x97, 0x79, 0x24, + 0xd2, 0x9f, 0x80, + + /* U+59D1 "姑" */ + 0x42, 0x21, 0x3f, 0xfa, 0x4f, 0xfb, 0x65, 0xf3, + 0xbf, 0x8c, 0x80, + + /* U+59E5 "姥" */ + 0x44, 0x2f, 0xb9, 0xd7, 0xfa, 0xc5, 0xf9, 0x70, + 0xd9, 0xa7, 0x0, + + /* U+59E8 "姨" */ + 0x5f, 0xb9, 0x6, 0x7a, 0xbe, 0xaf, 0xb9, 0x26, + 0xfb, 0xac, 0x90, 0x80, + + /* U+5A0C "娌" */ + 0x5f, 0xad, 0x7f, 0xf7, 0x5b, 0xfd, 0x11, 0x7e, + 0xc4, 0xbf, 0x80, + + /* U+5A7F "婿" */ + 0x5f, 0xa5, 0x7a, 0xf7, 0xfa, 0xff, 0x7d, 0xbf, + 0xd1, 0x89, 0x80, + + /* U+5AB3 "媳" */ + 0x44, 0x27, 0xbb, 0xd5, 0xea, 0xf7, 0x21, 0xec, + 0xf3, 0x9e, 0x0, + + /* U+5AE1 "嫡" */ + 0x42, 0x76, 0xeb, 0xf5, 0x5a, 0xaa, 0x7d, 0xff, + 0xd1, 0x89, 0x80, + + /* U+5B50 "子" */ + 0x7f, 0x3, 0x3, 0x1, 0xf, 0xf8, 0x40, 0x20, + 0x10, 0x38, 0x0, + + /* U+5B59 "孙" */ + 0xf2, 0x11, 0x13, 0xe9, 0x5e, 0xae, 0xd5, 0x8, + 0x84, 0x46, 0x0, + + /* U+5B9A "定" */ + 0x8, 0xff, 0x81, 0x7e, 0x68, 0x4f, 0x68, 0xf8, + 0x9f, + + /* U+5C5E "属" */ + 0x7f, 0x41, 0x7f, 0x5f, 0x5f, 0x5f, 0x7f, 0xff, + 0xb1, + + /* U+5CB3 "岳" */ + 0x0, 0x3f, 0x98, 0xf, 0xe6, 0x27, 0xfc, 0x20, + 0x92, 0x49, 0x3f, 0x80, + + /* U+5DF1 "己" */ + 0xfe, 0x2, 0x2, 0xfe, 0x82, 0x80, 0x81, 0x81, + 0xff, + + /* U+5E2E "帮" */ + 0xff, 0x92, 0xbf, 0x5f, 0x96, 0x53, 0xf9, 0x24, + 0x96, 0x8, 0x0, + + /* U+5EB6 "庶" */ + 0x4, 0x1f, 0xe4, 0x91, 0xfe, 0x49, 0x13, 0xc5, + 0x9, 0xda, 0x26, 0x80, + + /* U+5F1F "弟" */ + 0x22, 0x7f, 0x82, 0x4f, 0xe4, 0x83, 0xfc, 0xe7, + 0xd6, 0x8, 0x0, + + /* U+62E9 "择" */ + 0x5f, 0x77, 0x13, 0x8b, 0x6e, 0x42, 0x71, 0x7c, + 0x88, 0xc4, 0x0, + + /* U+6301 "持" */ + 0x42, 0x27, 0xf8, 0x8b, 0xf6, 0x17, 0xfd, 0x24, + 0x8a, 0xc3, 0x0, + + /* U+652F "支" */ + 0x8, 0x7f, 0xc2, 0xf, 0xe6, 0x31, 0xb0, 0x71, + 0xef, 0x0, 0x0, + + /* U+660E "明" */ + 0xef, 0xa9, 0xa9, 0xef, 0xa9, 0xef, 0x89, 0x11, + 0x13, + + /* U+662F "是" */ + 0x7f, 0x3f, 0x90, 0x4f, 0xef, 0xf9, 0x41, 0xbe, + 0xf0, 0x9f, 0x80, + + /* U+663E "显" */ + 0x7f, 0x20, 0x9f, 0xcf, 0xe5, 0x52, 0xa8, 0x51, + 0xff, + + /* U+66FE "曾" */ + 0x64, 0xff, 0xd5, 0x91, 0xff, 0x7e, 0x7e, 0x7e, + 0x42, + + /* U+672A "未" */ + 0x8, 0x3f, 0x82, 0x1, 0xf, 0xf8, 0xe0, 0xa9, + 0x93, 0x88, 0x0, + + /* U+679C "果" */ + 0x7f, 0x24, 0x9f, 0xc9, 0x23, 0xe7, 0xfc, 0xf9, + 0xd7, 0x88, 0x80, + + /* U+67E5 "查" */ + 0x8, 0x7f, 0xcf, 0x8d, 0x6f, 0xeb, 0xf1, 0x88, + 0x38, 0xff, 0x80, + + /* U+683C "格" */ + 0x4f, 0x7e, 0x99, 0x9f, 0xfd, 0x8e, 0x79, 0x24, + 0x9e, 0x49, 0x0, + + /* U+6BCD "母" */ + 0x3f, 0x34, 0x9b, 0x5f, 0xf5, 0x92, 0x49, 0xfe, + 0x4, 0x6, 0x0, + + /* U+6E05 "清" */ + 0x7f, 0xc3, 0xe4, 0x21, 0xff, 0xf, 0x8b, 0xe2, + 0xf9, 0x22, 0x49, 0x80, + + /* U+7236 "父" */ + 0x33, 0x8, 0x65, 0x28, 0x48, 0x1e, 0x3, 0x1, + 0xe1, 0xce, 0x40, 0x80, + + /* U+7237 "爷" */ + 0x12, 0x39, 0xd7, 0x83, 0xc6, 0x1b, 0xf8, 0x24, + 0x12, 0xb, 0x4, 0x0, + + /* U+7384 "玄" */ + 0x8, 0x7f, 0xc4, 0x4, 0x47, 0xc0, 0xd0, 0xc4, + 0xff, 0x0, 0x80, + + /* U+7525 "甥" */ + 0x6f, 0xbf, 0xea, 0xa5, 0xf7, 0x21, 0x7c, 0xca, + 0xc9, 0x9, 0x80, + + /* U+754C "界" */ + 0x7f, 0x24, 0x9f, 0xcf, 0xe3, 0x63, 0x1b, 0xde, + 0x6c, 0x66, 0x0, + + /* U+7684 "的" */ + 0x44, 0x32, 0x3d, 0xf3, 0x99, 0x8f, 0xb6, 0x4b, + 0x21, 0xf0, 0xc1, 0x80, + + /* U+77E5 "知" */ + 0x40, 0xff, 0xad, 0x2d, 0xfd, 0x6d, 0x7d, 0xdf, + 0x80, + + /* U+786E "确" */ + 0xf7, 0x24, 0x93, 0xff, 0x5d, 0xfe, 0xd5, 0x7e, + 0xf5, 0x9, 0x80, + + /* U+793A "示" */ + 0x7f, 0x0, 0x0, 0x1f, 0xf0, 0x83, 0x59, 0x25, + 0x13, 0x38, 0x0, + + /* U+7956 "祖" */ + 0x40, 0x27, 0xba, 0x5d, 0x26, 0xf7, 0x4b, 0xbc, + 0x92, 0x49, 0x2f, 0xc0, + + /* U+7A7A "空" */ + 0x8, 0x7f, 0xe0, 0x3e, 0xf7, 0xf0, 0x40, 0x21, + 0xff, + + /* U+7B97 "算" */ + 0x77, 0xd5, 0x9f, 0xcf, 0xe7, 0xf3, 0xfb, 0xfe, + 0xc4, 0x42, 0x0, + + /* U+7CFB "系" */ + 0x7, 0x3e, 0xd, 0x8f, 0x81, 0xa1, 0x99, 0xf6, + 0x54, 0x49, 0x4c, 0x0, + + /* U+7ED3 "结" */ + 0x22, 0x37, 0xf4, 0x9d, 0xf6, 0x7, 0xfc, 0x37, + 0xff, 0xd, 0x80, + + /* U+7EE7 "继" */ + 0x29, 0x13, 0x65, 0x9b, 0xbf, 0x6b, 0xbf, 0xd1, + 0x93, 0xbf, + + /* U+81EA "自" */ + 0x11, 0xfe, 0xf, 0xf8, 0x3f, 0xe0, 0xff, 0x82, + + /* U+8205 "舅" */ + 0x77, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe, + 0x31, 0x63, 0x80, + + /* U+83DC "菜" */ + 0xff, 0x91, 0x3f, 0x89, 0x26, 0x97, 0xfc, 0xf9, + 0xd7, 0x88, 0x80, + + /* U+8868 "表" */ + 0xff, 0x84, 0x1f, 0xdf, 0xf3, 0x57, 0x3a, 0x8c, + 0xf3, 0x0, 0x0, + + /* U+8BA1 "计" */ + 0x44, 0x64, 0x4, 0xdf, 0x44, 0x44, 0x64, 0x64, + 0x44, + + /* U+8BE2 "询" */ + 0x8, 0x2f, 0xc4, 0x3b, 0xd5, 0x2a, 0xf5, 0xfa, + 0xa3, 0x3, 0x0, + + /* U+8BF4 "说" */ + 0x19, 0x25, 0x7, 0xda, 0x25, 0xf2, 0x51, 0xa8, + 0xf5, 0x33, 0x80, + + /* U+8BF7 "请" */ + 0xdf, 0xf, 0xb7, 0xfb, 0xf5, 0xf2, 0x89, 0xfc, + 0xfe, 0x13, 0x0, + + /* U+8F93 "输" */ + 0x46, 0x75, 0xa7, 0xf8, 0xf, 0xfa, 0xff, 0xfe, + 0xa9, 0x55, 0x80, + + /* U+8FD4 "返" */ + 0x1, 0x6f, 0x94, 0x3, 0xed, 0x12, 0xb9, 0x5c, + 0xfa, 0xa8, 0x4f, 0xc0, + + /* U+8FD9 "这" */ + 0x4, 0x62, 0x1f, 0xe2, 0x4d, 0xe2, 0x31, 0x6c, + 0xf2, 0xa0, 0x4f, 0xc0, + + /* U+9009 "选" */ + 0x94, 0x2f, 0x81, 0x1f, 0xe4, 0xa2, 0xd5, 0xcd, + 0xc0, 0x9f, 0x0, + + /* U+9664 "除" */ + 0x4, 0x72, 0x3a, 0xda, 0x3c, 0xf5, 0x22, 0xff, + 0xfa, 0x95, 0xc6, 0x0, + + /* U+9762 "面" */ + 0xff, 0x84, 0x3f, 0xfa, 0xbd, 0xde, 0xaf, 0x77, + 0xff, 0xc1, 0x80, + + /* U+FF01 "!" */ + 0xff, 0xcf, + + /* U+FF0C "," */ + 0xf6, + + /* U+FF1A ":" */ + 0xf0, 0x3c, + + /* U+FF1B ";" */ + 0xf0, 0x3d, 0x80, + + /* U+FF1F "?" */ + 0xf1, 0x12, 0x66, 0x60 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 36, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 59, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3, .adv_w = 92, .box_w = 4, .box_h = 3, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 5, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 10, .adv_w = 94, .box_w = 5, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 17, .adv_w = 154, .box_w = 9, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 26, .adv_w = 118, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 33, .adv_w = 52, .box_w = 2, .box_h = 3, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 34, .adv_w = 60, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 37, .adv_w = 60, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40, .adv_w = 81, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 43, .adv_w = 94, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 47, .adv_w = 52, .box_w = 2, .box_h = 4, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 48, .adv_w = 59, .box_w = 2, .box_h = 1, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 49, .adv_w = 52, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 50, .adv_w = 62, .box_w = 4, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 56, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 61, .adv_w = 94, .box_w = 4, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 65, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 70, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 75, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 80, .adv_w = 94, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 86, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 91, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 96, .adv_w = 94, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 102, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 107, .adv_w = 52, .box_w = 2, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 109, .adv_w = 52, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111, .adv_w = 94, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 115, .adv_w = 94, .box_w = 5, .box_h = 4, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 118, .adv_w = 94, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 122, .adv_w = 82, .box_w = 4, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 126, .adv_w = 161, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 138, .adv_w = 103, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 144, .adv_w = 109, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 150, .adv_w = 105, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 156, .adv_w = 114, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 162, .adv_w = 98, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 167, .adv_w = 94, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 172, .adv_w = 115, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 178, .adv_w = 121, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 184, .adv_w = 53, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 186, .adv_w = 91, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 191, .adv_w = 110, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 198, .adv_w = 92, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 203, .adv_w = 137, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 210, .adv_w = 120, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 216, .adv_w = 123, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 223, .adv_w = 107, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 229, .adv_w = 123, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 238, .adv_w = 109, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 244, .adv_w = 100, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 249, .adv_w = 100, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 255, .adv_w = 120, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 261, .adv_w = 99, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 267, .adv_w = 146, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 276, .adv_w = 100, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 282, .adv_w = 93, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 288, .adv_w = 98, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 293, .adv_w = 60, .box_w = 2, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 296, .adv_w = 62, .box_w = 4, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 302, .adv_w = 60, .box_w = 2, .box_h = 10, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 305, .adv_w = 94, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 308, .adv_w = 91, .box_w = 6, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 309, .adv_w = 100, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 311, .adv_w = 95, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 315, .adv_w = 103, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 320, .adv_w = 84, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 324, .adv_w = 103, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 329, .adv_w = 93, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 333, .adv_w = 60, .box_w = 3, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 336, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 342, .adv_w = 102, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 347, .adv_w = 49, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 349, .adv_w = 49, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 353, .adv_w = 97, .box_w = 6, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 359, .adv_w = 50, .box_w = 3, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 362, .adv_w = 154, .box_w = 8, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 368, .adv_w = 103, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 372, .adv_w = 100, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 377, .adv_w = 103, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 382, .adv_w = 103, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 387, .adv_w = 70, .box_w = 4, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 390, .adv_w = 79, .box_w = 4, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 393, .adv_w = 67, .box_w = 4, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 397, .adv_w = 102, .box_w = 5, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 401, .adv_w = 92, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 406, .adv_w = 138, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 412, .adv_w = 90, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 416, .adv_w = 92, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 422, .adv_w = 82, .box_w = 4, .box_h = 6, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 425, .adv_w = 60, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 429, .adv_w = 47, .box_w = 1, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 431, .adv_w = 60, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 435, .adv_w = 94, .box_w = 6, .box_h = 2, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 437, .adv_w = 160, .box_w = 6, .box_h = 6, .ofs_x = 2, .ofs_y = 1}, + {.bitmap_index = 442, .adv_w = 160, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 449, .adv_w = 160, .box_w = 4, .box_h = 3, .ofs_x = 6, .ofs_y = 6}, + {.bitmap_index = 451, .adv_w = 160, .box_w = 4, .box_h = 3, .ofs_x = 1, .ofs_y = 6}, + {.bitmap_index = 453, .adv_w = 160, .box_w = 10, .box_h = 5, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 460, .adv_w = 160, .box_w = 5, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 466, .adv_w = 160, .box_w = 10, .box_h = 5, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 473, .adv_w = 160, .box_w = 5, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 479, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 492, .adv_w = 160, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 494, .adv_w = 160, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 496, .adv_w = 160, .box_w = 5, .box_h = 10, .ofs_x = 5, .ofs_y = -1}, + {.bitmap_index = 503, .adv_w = 160, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 510, .adv_w = 160, .box_w = 9, .box_h = 1, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 512, .adv_w = 160, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 521, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 532, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 543, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 554, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 565, .adv_w = 160, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 575, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 586, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 597, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 608, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 620, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 632, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 643, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 654, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 665, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 676, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 687, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 698, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 709, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 720, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 729, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 740, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 752, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 763, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 774, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 785, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 796, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 807, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 818, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 829, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 840, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 851, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 863, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 874, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 885, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 896, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 907, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 918, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 929, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 938, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 947, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 959, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 968, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 979, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 991, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1002, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1013, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1024, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1035, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1044, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1055, .adv_w = 160, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1064, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1073, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1084, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1095, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1106, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1117, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1128, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1140, .adv_w = 160, .box_w = 10, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1152, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1164, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1175, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1186, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1197, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1209, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1218, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1229, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1240, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1252, .adv_w = 160, .box_w = 9, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1261, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1272, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1284, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1295, .adv_w = 160, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1305, .adv_w = 160, .box_w = 7, .box_h = 9, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 1313, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1324, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1335, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1346, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1355, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1366, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1377, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1388, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1399, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1411, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1423, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1434, .adv_w = 160, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1446, .adv_w = 160, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1457, .adv_w = 160, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1459, .adv_w = 160, .box_w = 2, .box_h = 4, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 1460, .adv_w = 160, .box_w = 2, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1462, .adv_w = 160, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1465, .adv_w = 160, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x20, 0x1f45, 0x1f46, 0x20b9, 0x20ba, 0x20bb, 0x20bc, + 0x2143, 0x2f2a, 0x2f2b, 0x2f33, 0x2f34, 0x4d29, 0x4d31, 0x4d53, + 0x4d64, 0x4ddb, 0x4df7, 0x4e58, 0x4ead, 0x5068, 0x506d, 0x508e, + 0x5095, 0x509c, 0x50a4, 0x50b6, 0x51d2, 0x527e, 0x52fd, 0x540e, + 0x5591, 0x5607, 0x572b, 0x583f, 0x5854, 0x589c, 0x589f, 0x58d8, + 0x58e2, 0x58e4, 0x58f9, 0x58fa, 0x590e, 0x5911, 0x5935, 0x59a8, + 0x59dc, 0x5a0a, 0x5a79, 0x5a82, 0x5ac3, 0x5b87, 0x5bdc, 0x5d1a, + 0x5d57, 0x5ddf, 0x5e48, 0x6212, 0x622a, 0x6458, 0x6537, 0x6558, + 0x6567, 0x6627, 0x6653, 0x66c5, 0x670e, 0x6765, 0x6af6, 0x6d2e, + 0x715f, 0x7160, 0x72ad, 0x744e, 0x7475, 0x75ad, 0x770e, 0x7797, + 0x7863, 0x787f, 0x79a3, 0x7ac0, 0x7c24, 0x7dfc, 0x7e10, 0x8113, + 0x812e, 0x8305, 0x8791, 0x8aca, 0x8b0b, 0x8b1d, 0x8b20, 0x8ebc, + 0x8efd, 0x8f02, 0x8f32, 0x958d, 0x968b, 0xfe2a, 0xfe35, 0xfe43, + 0xfe44, 0xfe48 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 215, .range_length = 65097, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 106, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 2, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_siyuan_10 = { +#else +lv_font_t lv_font_siyuan_10 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 13, /*The maximum line height required by the font*/ + .base_line = 3, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if LV_FONT_SIYUAN_10*/ + diff --git a/relation_calculator/fonts/lv_font_siyuan_16.c b/relation_calculator/fonts/lv_font_siyuan_16.c new file mode 100644 index 0000000000000000000000000000000000000000..1e36956c0fa095177a64834f9eb7c90cc84d1d9e --- /dev/null +++ b/relation_calculator/fonts/lv_font_siyuan_16.c @@ -0,0 +1,1274 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 1 + * Opts: --bpp 1 --size 16 --no-compress --font SourceHanSansCN-Bold.ttf --symbols 父、亲、夫、丈、儿、子、哥、姐、母、妻、女、弟、妹、自、己、祖、伯、姑、堂、曾、外、舅、姨、侄、媳、婿、孙、姥、公、奶、爷、甥、嫡、庶、继、养、岳、妯、娌、玄、叔、清除、计算、<-、\n、空格、请、输、入、选、择、确、定、返、回、主、菜、单、计、算、结、果、关、系、帮、助、说、明、界、面、查、询、显、示、祖母、伯父、姑母、堂兄弟、堂姐妹、曾祖父、曾祖母、外祖父、外祖母、外曾祖父、外曾祖母、表侄、表侄女、再从兄弟、再从姐妹、叔祖父、姑祖母、舅父、姨母、侄子、侄女、儿媳、女婿、孙子、孙女、曾孙子、曾孙女、堂侄 / 表侄、堂侄女 / 表侄女、孙侄、孙侄女、未知、0、1、2、3、4、5、6、7、8、9、+、-、×、÷、=、?、!、,、。、:、;、《》、[]、{}、@、#、←、→、↑、↓、√、×、这、是、一、个、亲、属、关、系、计、算、器、。、未、支、持、关、系、:、“、未、知、”、。的 --range 32-127 --format lvgl -o lv_font_siyuan_16.c + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_FONT_SIYUAN_16 +#define LV_FONT_SIYUAN_16 1 +#endif + +#if LV_FONT_SIYUAN_16 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xdb, 0x6d, 0xb6, 0x1f, 0xf0, + + /* U+0022 "\"" */ + 0xcf, 0x3c, 0xf3, 0xcc, + + /* U+0023 "#" */ + 0x32, 0x22, 0x26, 0xff, 0xff, 0x66, 0x64, 0xff, + 0xff, 0x44, 0x4c, 0x4c, + + /* U+0024 "$" */ + 0x30, 0x61, 0xfe, 0x2c, 0x1c, 0x3c, 0x3e, 0x1e, + 0xc, 0x1e, 0x3f, 0xc6, 0xc, 0x0, + + /* U+0025 "%" */ + 0x78, 0x60, 0xf0, 0x83, 0x33, 0x6, 0x64, 0xc, + 0xdb, 0x99, 0xaf, 0x9e, 0xf1, 0xbd, 0x63, 0x6, + 0xc6, 0x9, 0x8c, 0x21, 0xf0, 0x41, 0xc0, + + /* U+0026 "&" */ + 0x3c, 0xf, 0xc1, 0x98, 0x33, 0x6, 0xc0, 0x71, + 0xde, 0x36, 0xe6, 0xcf, 0x98, 0xf3, 0xff, 0x9e, + 0x20, + + /* U+0027 "'" */ + 0xff, 0xc0, + + /* U+0028 "(" */ + 0x32, 0x66, 0xcc, 0xcc, 0xcc, 0xcc, 0x66, 0x63, + + /* U+0029 ")" */ + 0xc4, 0x66, 0x33, 0x33, 0x33, 0x33, 0x66, 0x4c, + + /* U+002A "*" */ + 0x30, 0xcf, 0xde, 0x79, 0x20, + + /* U+002B "+" */ + 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, + + /* U+002C "," */ + 0x77, 0x37, 0xe0, + + /* U+002D "-" */ + 0xff, + + /* U+002E "." */ + 0xff, 0x80, + + /* U+002F "/" */ + 0xc, 0x20, 0x86, 0x18, 0x41, 0xc, 0x30, 0x86, + 0x18, 0x61, 0xc, 0x30, + + /* U+0030 "0" */ + 0x3c, 0x7e, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0x66, 0x7e, 0x3c, + + /* U+0031 "1" */ + 0x39, 0xf0, 0x60, 0xc1, 0x83, 0x6, 0xc, 0x18, + 0x33, 0xff, 0xf0, + + /* U+0032 "2" */ + 0x78, 0xfc, 0xc6, 0x6, 0x6, 0x6, 0xc, 0x1c, + 0x38, 0x70, 0xff, 0xff, + + /* U+0033 "3" */ + 0x78, 0xfe, 0x46, 0x6, 0xe, 0x3c, 0x3e, 0x7, + 0x3, 0xc7, 0xfe, 0x7c, + + /* U+0034 "4" */ + 0xe, 0xf, 0x7, 0x86, 0xc3, 0x63, 0x33, 0x99, + 0xff, 0xff, 0x83, 0x1, 0x80, 0xc0, + + /* U+0035 "5" */ + 0x7f, 0x7f, 0x60, 0x60, 0x7c, 0x7e, 0x7, 0x3, + 0x3, 0x47, 0xfe, 0x7c, + + /* U+0036 "6" */ + 0x1e, 0x7f, 0x62, 0xc0, 0xdc, 0xfe, 0xe3, 0xc3, + 0xc3, 0x67, 0x7e, 0x3c, + + /* U+0037 "7" */ + 0xff, 0xff, 0x6, 0xc, 0x1c, 0x18, 0x18, 0x30, + 0x30, 0x30, 0x30, 0x30, + + /* U+0038 "8" */ + 0x3c, 0xfd, 0x9b, 0x36, 0x67, 0x9f, 0x63, 0xc7, + 0x8f, 0xfb, 0xe0, + + /* U+0039 "9" */ + 0x3c, 0x7e, 0xe6, 0xc3, 0xc3, 0xc7, 0x7f, 0x3b, + 0x3, 0x46, 0xfe, 0x78, + + /* U+003A ":" */ + 0xff, 0x80, 0x3f, 0xe0, + + /* U+003B ";" */ + 0xff, 0x80, 0x7, 0xef, 0xe0, + + /* U+003C "<" */ + 0x1, 0x7, 0x3e, 0xf0, 0xe0, 0x7c, 0xf, 0x1, + + /* U+003D "=" */ + 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, + + /* U+003E ">" */ + 0x80, 0xe0, 0x7c, 0xf, 0x7, 0x3e, 0xf0, 0x80, + + /* U+003F "?" */ + 0x3d, 0xfd, 0x18, 0x30, 0xc3, 0x86, 0x1c, 0x0, + 0x70, 0xe1, 0xc0, + + /* U+0040 "@" */ + 0x3, 0xe0, 0x1f, 0xf0, 0xf0, 0xf1, 0x80, 0x66, + 0x3e, 0x6c, 0xfc, 0xf1, 0x91, 0xe6, 0x23, 0xcc, + 0xc7, 0x99, 0x9b, 0x3d, 0xf7, 0x3b, 0xc6, 0x0, + 0xf, 0x0, 0xf, 0xf0, 0x7, 0xc0, + + /* U+0041 "A" */ + 0xe, 0x7, 0x81, 0xe0, 0x6c, 0x33, 0xc, 0xc3, + 0x39, 0xfe, 0x7f, 0x98, 0x7e, 0x1f, 0x3, + + /* U+0042 "B" */ + 0xfe, 0x7f, 0xb0, 0xd8, 0x6c, 0x77, 0xf3, 0xfd, + 0x87, 0xc1, 0xe1, 0xff, 0xdf, 0xc0, + + /* U+0043 "C" */ + 0x1e, 0x1f, 0xdc, 0x5c, 0xc, 0x6, 0x3, 0x1, + 0x80, 0xe0, 0x30, 0x8f, 0xe3, 0xc0, + + /* U+0044 "D" */ + 0xfc, 0x7f, 0x31, 0xd8, 0x7c, 0x1e, 0xf, 0x7, + 0x83, 0xc3, 0xe3, 0xbf, 0x9f, 0x80, + + /* U+0045 "E" */ + 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xfe, 0xfe, 0xc0, + 0xc0, 0xc0, 0xff, 0xff, + + /* U+0046 "F" */ + 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xfe, 0xfe, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, + + /* U+0047 "G" */ + 0x1f, 0x1f, 0xdc, 0x5c, 0xc, 0x6, 0x3f, 0x1f, + 0x83, 0xe1, 0xb8, 0xcf, 0xe3, 0xe0, + + /* U+0048 "H" */ + 0xc1, 0xe0, 0xf0, 0x78, 0x3c, 0x1f, 0xff, 0xff, + 0x83, 0xc1, 0xe0, 0xf0, 0x78, 0x30, + + /* U+0049 "I" */ + 0xff, 0xff, 0xff, + + /* U+004A "J" */ + 0x6, 0xc, 0x18, 0x30, 0x60, 0xc1, 0x83, 0x6, + 0x8f, 0xf3, 0xc0, + + /* U+004B "K" */ + 0xc3, 0x63, 0x33, 0x9b, 0x8d, 0x87, 0xc3, 0xf1, + 0xdc, 0xc6, 0x63, 0xb0, 0xd8, 0x70, + + /* U+004C "L" */ + 0xc1, 0x83, 0x6, 0xc, 0x18, 0x30, 0x60, 0xc1, + 0x83, 0xff, 0xf0, + + /* U+004D "M" */ + 0xe0, 0xfc, 0x1f, 0x83, 0xf8, 0xff, 0x1f, 0xb6, + 0xf6, 0xde, 0xdb, 0xce, 0x79, 0xcf, 0x11, 0xe0, + 0x30, + + /* U+004E "N" */ + 0xe1, 0xf0, 0xfc, 0x7e, 0x3d, 0x9e, 0xef, 0x37, + 0x9f, 0xc7, 0xe3, 0xf0, 0xf8, 0x30, + + /* U+004F "O" */ + 0x1e, 0x1f, 0xe6, 0x1b, 0x87, 0xc0, 0xf0, 0x3c, + 0xf, 0x3, 0xe1, 0xd8, 0x67, 0xf8, 0x78, + + /* U+0050 "P" */ + 0xfc, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xfc, + 0xc0, 0xc0, 0xc0, 0xc0, + + /* U+0051 "Q" */ + 0x1e, 0xf, 0xf1, 0x86, 0x70, 0xec, 0xd, 0x81, + 0xb0, 0x36, 0x6, 0xe1, 0xcc, 0x31, 0xfe, 0xf, + 0x0, 0xe0, 0xf, 0x80, 0xf0, + + /* U+0052 "R" */ + 0xfc, 0x7f, 0x31, 0xd8, 0x6c, 0x36, 0x3b, 0xf9, + 0xf8, 0xce, 0x63, 0x31, 0xd8, 0x60, + + /* U+0053 "S" */ + 0x1e, 0x1f, 0xd8, 0x4c, 0x7, 0x1, 0xf0, 0x3c, + 0x7, 0x1, 0xb0, 0xdf, 0xc7, 0xc0, + + /* U+0054 "T" */ + 0xff, 0xff, 0xc3, 0x1, 0x80, 0xc0, 0x60, 0x30, + 0x18, 0xc, 0x6, 0x3, 0x1, 0x80, + + /* U+0055 "U" */ + 0xc1, 0xe0, 0xf0, 0x78, 0x3c, 0x1e, 0xf, 0x7, + 0x83, 0xc1, 0xf1, 0xdf, 0xc7, 0xc0, + + /* U+0056 "V" */ + 0xe1, 0xf8, 0x76, 0x19, 0x86, 0x73, 0x8c, 0xc3, + 0x30, 0xcc, 0x3e, 0x7, 0x81, 0xe0, 0x78, + + /* U+0057 "W" */ + 0xe3, 0x8d, 0x8e, 0x36, 0x38, 0xd8, 0xe3, 0x66, + 0x9d, 0xdb, 0x63, 0x6d, 0x8d, 0x36, 0x3c, 0xd8, + 0xf1, 0x63, 0xc7, 0xf, 0x1c, + + /* U+0058 "X" */ + 0x61, 0x9c, 0xe3, 0x30, 0xec, 0x1e, 0x7, 0x81, + 0xe0, 0x78, 0x37, 0xc, 0xc6, 0x3b, 0x87, + + /* U+0059 "Y" */ + 0x61, 0x9c, 0x63, 0x30, 0xcc, 0x1e, 0x7, 0x81, + 0xe0, 0x30, 0xc, 0x3, 0x0, 0xc0, 0x30, + + /* U+005A "Z" */ + 0xff, 0xff, 0x6, 0xe, 0xc, 0x18, 0x38, 0x30, + 0x60, 0x60, 0xff, 0xff, + + /* U+005B "[" */ + 0xfc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0xf0, + + /* U+005C "\\" */ + 0x41, 0x6, 0x18, 0x20, 0x83, 0xc, 0x10, 0x41, + 0x86, 0x8, 0x20, 0xc3, + + /* U+005D "]" */ + 0xf3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3f, 0xf0, + + /* U+005E "^" */ + 0x18, 0x70, 0xf3, 0x66, 0x48, 0xf1, 0x80, + + /* U+005F "_" */ + 0xff, 0xff, 0xc0, + + /* U+0060 "`" */ + 0xce, 0x70, + + /* U+0061 "a" */ + 0x3d, 0xfd, 0x18, 0x77, 0xf8, 0xf1, 0xff, 0x76, + + /* U+0062 "b" */ + 0xc0, 0xc0, 0xc0, 0xc0, 0xdc, 0xfe, 0xc7, 0xc3, + 0xc3, 0xc3, 0xc7, 0xfe, 0xdc, + + /* U+0063 "c" */ + 0x3c, 0xfb, 0x86, 0xc, 0x18, 0x38, 0x3f, 0x3c, + + /* U+0064 "d" */ + 0x3, 0x3, 0x3, 0x3, 0x3b, 0x7f, 0xe3, 0xc3, + 0xc3, 0xc3, 0xe3, 0x7f, 0x3b, + + /* U+0065 "e" */ + 0x3c, 0x7e, 0xe3, 0xff, 0xff, 0xe0, 0xe0, 0x7e, + 0x3e, + + /* U+0066 "f" */ + 0x3d, 0xf6, 0x18, 0xfb, 0xe6, 0x18, 0x61, 0x86, + 0x18, 0x60, + + /* U+0067 "g" */ + 0x7f, 0xff, 0xc6, 0xc6, 0x7e, 0x7c, 0xc0, 0xfe, + 0x7f, 0xc3, 0xfe, 0x7c, + + /* U+0068 "h" */ + 0xc0, 0xc0, 0xc0, 0xc0, 0xde, 0xff, 0xe3, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + + /* U+0069 "i" */ + 0xf0, 0xff, 0xff, 0xc0, + + /* U+006A "j" */ + 0x33, 0x0, 0x33, 0x33, 0x33, 0x33, 0x33, 0xfe, + + /* U+006B "k" */ + 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0xcc, 0xdc, 0xf8, + 0xf8, 0xfc, 0xcc, 0xc6, 0xc7, + + /* U+006C "l" */ + 0xdb, 0x6d, 0xb6, 0xdb, 0x76, + + /* U+006D "m" */ + 0xdc, 0xef, 0xff, 0xe7, 0x3c, 0x63, 0xc6, 0x3c, + 0x63, 0xc6, 0x3c, 0x63, 0xc6, 0x30, + + /* U+006E "n" */ + 0xde, 0xff, 0xe3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, + + /* U+006F "o" */ + 0x3c, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e, + 0x3c, + + /* U+0070 "p" */ + 0xdc, 0xfe, 0xc7, 0xc3, 0xc3, 0xc3, 0xc7, 0xfe, + 0xdc, 0xc0, 0xc0, 0xc0, + + /* U+0071 "q" */ + 0x3b, 0x7f, 0xe3, 0xc3, 0xc3, 0xc3, 0xe3, 0x7f, + 0x3b, 0x3, 0x3, 0x3, + + /* U+0072 "r" */ + 0xdf, 0xf9, 0x8c, 0x63, 0x18, 0xc0, + + /* U+0073 "s" */ + 0x7b, 0xfc, 0x38, 0x78, 0x38, 0xff, 0x78, + + /* U+0074 "t" */ + 0x61, 0x86, 0x3f, 0xfd, 0x86, 0x18, 0x61, 0x87, + 0xcf, + + /* U+0075 "u" */ + 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xff, + 0x7b, + + /* U+0076 "v" */ + 0xe1, 0xb1, 0x98, 0xce, 0x63, 0x71, 0xb0, 0xd8, + 0x3c, 0x1c, 0x0, + + /* U+0077 "w" */ + 0x63, 0x1b, 0x18, 0xd9, 0xe6, 0xef, 0x73, 0x5b, + 0x1a, 0x58, 0xf3, 0xc7, 0x9e, 0x1c, 0xe0, + + /* U+0078 "x" */ + 0x63, 0x3b, 0x8d, 0x83, 0xc1, 0xc1, 0xf0, 0xd8, + 0xce, 0x63, 0x0, + + /* U+0079 "y" */ + 0xe1, 0xb1, 0x9c, 0xc6, 0x63, 0x60, 0xf0, 0x78, + 0x38, 0xc, 0xe, 0x1e, 0xe, 0x0, + + /* U+007A "z" */ + 0x7e, 0xfc, 0x30, 0xe3, 0x86, 0x1c, 0x7f, 0xfe, + + /* U+007B "{" */ + 0x19, 0x8c, 0x63, 0x1b, 0xde, 0x31, 0x8c, 0x63, + 0x1c, 0x60, + + /* U+007C "|" */ + 0xff, 0xff, 0xff, 0xff, 0xf0, + + /* U+007D "}" */ + 0xc3, 0x18, 0xc6, 0x31, 0xef, 0x63, 0x18, 0xc6, + 0x73, 0x0, + + /* U+007E "~" */ + 0x72, 0xfe, 0x9e, + + /* U+00D7 "×" */ + 0xc0, 0xf8, 0x77, 0x38, 0xfc, 0x1e, 0x7, 0x83, + 0xf1, 0xce, 0xe1, 0xf0, 0x30, + + /* U+00F7 "÷" */ + 0xe, 0x1, 0xc0, 0x0, 0x0, 0xf, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0xe, 0x1, 0xc0, + + /* U+201C "“" */ + 0x1, 0x18, 0xb3, 0xcc, + + /* U+201D "”" */ + 0xcf, 0x34, 0x62, 0x0, + + /* U+2190 "←" */ + 0x18, 0x0, 0xe0, 0x7, 0x0, 0x3f, 0xff, 0x70, + 0x0, 0xe0, 0x1, 0x80, 0x0, + + /* U+2191 "↑" */ + 0x0, 0x18, 0x3c, 0x7e, 0xdb, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + + /* U+2192 "→" */ + 0x0, 0x60, 0x1, 0xc0, 0x3, 0xbf, 0xff, 0x0, + 0x38, 0x1, 0xc0, 0x6, 0x0, + + /* U+2193 "↓" */ + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xdb, 0x7e, 0x3c, 0x18, 0x0, + + /* U+221A "√" */ + 0x0, 0x7f, 0x0, 0x80, 0x0, 0x80, 0x1, 0x0, + 0x1, 0x0, 0x1, 0x0, 0x2, 0x0, 0x2, 0x0, + 0x2, 0x0, 0x24, 0x0, 0x24, 0x0, 0xf4, 0x0, + 0x18, 0x0, 0x18, 0x0, 0x10, 0x0, + + /* U+3001 "、" */ + 0x47, 0x1c, 0x71, 0x0, + + /* U+3002 "。" */ + 0x74, 0x63, 0x17, 0x0, + + /* U+300A "《" */ + 0x12, 0x1a, 0x16, 0x34, 0x2c, 0x6c, 0x48, 0xd8, + 0x58, 0x48, 0x6c, 0x24, 0x34, 0x16, 0x1a, + + /* U+300B "》" */ + 0x48, 0x48, 0x68, 0x2c, 0x34, 0x36, 0x12, 0x1b, + 0x1a, 0x12, 0x36, 0x24, 0x2c, 0x68, 0x58, + + /* U+4E00 "一" */ + 0xff, 0xff, 0xff, 0xfc, + + /* U+4E08 "丈" */ + 0x0, 0xc0, 0x3, 0x0, 0xc, 0x3f, 0xff, 0xff, + 0xfc, 0x7, 0x3, 0x18, 0xc, 0x60, 0x19, 0x80, + 0x66, 0x0, 0xf0, 0x1, 0xc0, 0x1f, 0xc3, 0xe7, + 0xf6, 0x3, 0x80, + + /* U+4E2A "个" */ + 0x0, 0x80, 0x1, 0x80, 0x3, 0xc0, 0x7, 0x70, + 0x1e, 0x38, 0x79, 0x9e, 0x71, 0x8e, 0x1, 0x80, + 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, + 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, + + /* U+4E3B "主" */ + 0x6, 0x0, 0x1c, 0x0, 0x38, 0x1f, 0xfe, 0x7f, + 0xf8, 0xc, 0x0, 0x30, 0x0, 0xc0, 0x7f, 0xf1, + 0xff, 0xc0, 0x30, 0x0, 0xc0, 0x3, 0x3, 0xff, + 0xff, 0xff, 0xc0, + + /* U+4EB2 "亲" */ + 0x3, 0x0, 0xc, 0x7, 0xff, 0x86, 0x18, 0x18, + 0x63, 0xff, 0xf0, 0x30, 0x0, 0xc0, 0xff, 0xfc, + 0xc, 0x83, 0x37, 0xc, 0xce, 0x63, 0x19, 0x3c, + 0x0, + + /* U+4ECE "从" */ + 0x18, 0x60, 0x30, 0xc0, 0x61, 0x80, 0xc3, 0x1, + 0x86, 0x3, 0xc, 0x7, 0x38, 0x1e, 0x70, 0x36, + 0xf0, 0x65, 0xe1, 0xc6, 0xe3, 0xc, 0xce, 0x38, + 0xd8, 0x61, 0x90, 0x0, 0x0, + + /* U+4F2F "伯" */ + 0x18, 0xe0, 0x63, 0x1, 0x8c, 0xd, 0xff, 0x37, + 0xfd, 0xd8, 0x3f, 0x60, 0xfd, 0x83, 0x77, 0xfc, + 0xdf, 0xf3, 0x60, 0xcd, 0x83, 0x36, 0xc, 0xdf, + 0xf3, 0x7f, 0xc0, + + /* U+4F84 "侄" */ + 0x8, 0x0, 0x37, 0xfc, 0x63, 0x1, 0x8c, 0xc3, + 0x19, 0xce, 0x71, 0xbd, 0xff, 0xb9, 0x3, 0x70, + 0x64, 0x60, 0xc0, 0xcf, 0xf1, 0x83, 0x3, 0x6, + 0x6, 0xc, 0xd, 0xff, 0x80, + + /* U+513F "儿" */ + 0xc, 0x30, 0xc, 0x30, 0xc, 0x30, 0xc, 0x30, + 0xc, 0x30, 0xc, 0x30, 0xc, 0x30, 0xc, 0x30, + 0xc, 0x30, 0x18, 0x32, 0x18, 0x33, 0x38, 0x33, + 0x70, 0x3f, 0x60, 0x1e, + + /* U+5144 "兄" */ + 0x3f, 0xf8, 0x7f, 0xf0, 0xc0, 0x61, 0x80, 0xc3, + 0x1, 0x87, 0xff, 0xf, 0xfe, 0x6, 0x60, 0xc, + 0xc0, 0x19, 0x80, 0x63, 0x19, 0xc6, 0x3f, 0xf, + 0xcc, 0xf, 0x80, + + /* U+5165 "入" */ + 0xc, 0x0, 0x1c, 0x0, 0x18, 0x0, 0x18, 0x0, + 0x38, 0x0, 0xf0, 0x1, 0xb0, 0x3, 0x60, 0xc, + 0x60, 0x38, 0xe0, 0x60, 0xe3, 0x80, 0xef, 0x1, + 0xc8, 0x0, 0x80, + + /* U+516C "公" */ + 0x1c, 0xc0, 0x30, 0xc0, 0xe1, 0xc1, 0x81, 0xc7, + 0x21, 0xdc, 0xe1, 0x91, 0x82, 0x7, 0x0, 0xc, + 0x60, 0x30, 0xe0, 0xc0, 0xc3, 0xff, 0xc7, 0xff, + 0x88, 0x1, 0x80, + + /* U+5173 "关" */ + 0x30, 0x30, 0x30, 0xc0, 0x61, 0x83, 0xff, 0xc7, + 0xff, 0x80, 0x60, 0x0, 0xc0, 0x7f, 0xfe, 0xff, + 0xfc, 0xf, 0x0, 0x1f, 0x0, 0xf7, 0x7, 0xc7, + 0x9e, 0x7, 0x90, 0x0, 0x0, + + /* U+517B "养" */ + 0x8, 0x60, 0x30, 0xc1, 0xff, 0xe0, 0x18, 0x0, + 0x30, 0x7, 0xff, 0x1, 0x80, 0x7f, 0xfe, 0x38, + 0x71, 0xf1, 0xf9, 0x63, 0x30, 0xc6, 0x3, 0x8c, + 0xe, 0x18, 0x18, 0x30, 0x0, + + /* U+518D "再" */ + 0x7f, 0xfc, 0xff, 0xf8, 0xc, 0x1, 0xff, 0xc3, + 0x31, 0x86, 0x63, 0xf, 0xfe, 0x19, 0x8c, 0x33, + 0x19, 0xff, 0xff, 0xff, 0xf9, 0x80, 0xc3, 0x1, + 0x86, 0xf, 0x0, + + /* U+52A9 "助" */ + 0x0, 0x60, 0xfc, 0xc1, 0x99, 0x83, 0x33, 0x6, + 0x7f, 0xef, 0xff, 0xd9, 0x99, 0xb3, 0x33, 0x7e, + 0x66, 0xcc, 0xcd, 0x9f, 0x1f, 0xfe, 0x3f, 0x1c, + 0x60, 0x77, 0x80, 0x4f, 0x0, + + /* U+5355 "单" */ + 0x0, 0x0, 0x61, 0xc0, 0xc6, 0x1f, 0xfe, 0x63, + 0x19, 0x8c, 0x67, 0xff, 0x98, 0xc6, 0x63, 0x19, + 0xff, 0xe0, 0x30, 0x3f, 0xff, 0xff, 0xfc, 0xc, + 0x0, 0x30, 0x0, + + /* U+53D4 "叔" */ + 0x30, 0x0, 0x63, 0xf0, 0xc7, 0xf1, 0xff, 0xe3, + 0xc, 0xc6, 0x19, 0xbf, 0xd3, 0x7f, 0xb4, 0x18, + 0x78, 0xbc, 0xf3, 0x68, 0xc6, 0xd9, 0x8d, 0xb7, + 0x83, 0x39, 0x8c, 0x61, 0x80, + + /* U+54E5 "哥" */ + 0xff, 0xfc, 0x0, 0x43, 0xf9, 0x8, 0x64, 0x21, + 0x90, 0xfe, 0x40, 0x1, 0x3f, 0xff, 0x0, 0x10, + 0xfe, 0x42, 0x19, 0x8, 0x64, 0x3f, 0x90, 0x1, + 0xc0, + + /* U+5668 "器" */ + 0x7d, 0xf9, 0x96, 0x66, 0x59, 0x9f, 0x7e, 0x6, + 0x60, 0x19, 0xcf, 0xff, 0xc6, 0x38, 0x38, 0x73, + 0xc0, 0xef, 0xdf, 0xd9, 0x66, 0x65, 0x99, 0xf7, + 0xe0, + + /* U+56DE "回" */ + 0xff, 0xff, 0xff, 0xfc, 0x0, 0xf0, 0x3, 0xdf, + 0xcf, 0x63, 0x3d, 0x8c, 0xf6, 0x33, 0xd8, 0xcf, + 0x7f, 0x3c, 0x0, 0xf0, 0x3, 0xff, 0xff, 0xff, + 0xf0, + + /* U+5802 "堂" */ + 0x3, 0x18, 0x66, 0x30, 0xcc, 0xc7, 0xff, 0xfc, + 0x0, 0x78, 0x0, 0xf7, 0xfd, 0x88, 0x18, 0x1f, + 0xf0, 0x6, 0x0, 0xc, 0x1, 0xff, 0xc0, 0x30, + 0x0, 0x60, 0x3f, 0xff, 0x80, + + /* U+5916 "外" */ + 0x18, 0x60, 0x30, 0xc0, 0xc1, 0x81, 0xfb, 0x3, + 0xf6, 0xc, 0x6c, 0x18, 0xde, 0x6b, 0xbe, 0x7e, + 0x6e, 0x1c, 0xc8, 0x31, 0x80, 0xe3, 0x3, 0x86, + 0x1e, 0xc, 0x10, 0x18, 0x0, + + /* U+592B "夫" */ + 0x3, 0x0, 0x6, 0x0, 0xc, 0x3, 0xff, 0xc7, + 0xff, 0x80, 0x60, 0x0, 0xc0, 0x7f, 0xfe, 0xff, + 0xfc, 0xf, 0x0, 0x1e, 0x0, 0x76, 0x3, 0xcf, + 0x1f, 0xf, 0xb8, 0x7, 0x0, + + /* U+5973 "女" */ + 0x4, 0x0, 0x18, 0x0, 0x60, 0x3, 0x0, 0xff, + 0xff, 0xff, 0xf1, 0x86, 0x6, 0x18, 0x38, 0xe0, + 0xf3, 0x1, 0xfc, 0x1, 0xf0, 0xf, 0xf3, 0xf9, + 0xff, 0x1, 0x80, + + /* U+5976 "奶" */ + 0x30, 0x0, 0x60, 0x0, 0x8f, 0xe7, 0xec, 0xcf, + 0xd9, 0x8d, 0xb7, 0x1b, 0x6f, 0xe6, 0xc3, 0xf9, + 0x86, 0xf3, 0xc, 0x6c, 0x19, 0xf8, 0x37, 0xb0, + 0x7c, 0xc7, 0x90, 0x8f, 0x0, + + /* U+59AF "妯" */ + 0x60, 0x61, 0x81, 0x86, 0x6, 0x18, 0x18, 0xfb, + 0xff, 0xef, 0xf5, 0xb6, 0xd6, 0xdb, 0xdb, 0x6f, + 0x4f, 0xf7, 0x36, 0xce, 0xdb, 0x7b, 0xff, 0x2f, + 0xfc, 0x30, 0xc0, + + /* U+59B9 "妹" */ + 0x60, 0x60, 0xc0, 0xc1, 0x8f, 0xf7, 0xdf, 0xef, + 0x86, 0xb, 0xc, 0x16, 0x18, 0x6f, 0xff, 0xd8, + 0xf0, 0xe1, 0xe0, 0xc7, 0xe1, 0xdb, 0x66, 0xf6, + 0xf8, 0xcc, 0xa0, 0x18, 0x0, + + /* U+59BB "妻" */ + 0x3, 0x0, 0xc, 0xf, 0xff, 0xc0, 0xc0, 0x7f, + 0xf0, 0xc, 0x4f, 0xff, 0xc0, 0xc4, 0x7f, 0xf0, + 0x18, 0xf, 0xff, 0xc6, 0x18, 0x3f, 0xc0, 0x1f, + 0x8f, 0xe7, 0x80, + + /* U+59D0 "姐" */ + 0x60, 0x1, 0x8f, 0xe6, 0x3f, 0x98, 0xc6, 0xfb, + 0x1b, 0xec, 0x65, 0xbf, 0xb6, 0xc6, 0xdb, 0x1b, + 0xcf, 0xe7, 0x31, 0x9c, 0xc6, 0x7b, 0x1b, 0xff, + 0xfc, 0xff, 0xc0, 0x0, + + /* U+59D1 "姑" */ + 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc1, 0x81, 0x8f, + 0xff, 0xff, 0xff, 0xdb, 0xc, 0x36, 0x18, 0x6c, + 0x31, 0xd3, 0xfc, 0xe6, 0x18, 0xcc, 0x33, 0xd8, + 0x7e, 0xbf, 0xd0, 0x61, 0x80, + + /* U+59E5 "姥" */ + 0x60, 0xc1, 0x83, 0x26, 0xc, 0xd8, 0xfe, 0xf8, + 0xdb, 0xe3, 0xc5, 0xff, 0xd6, 0x30, 0xdb, 0x8b, + 0x5e, 0xf7, 0xff, 0xd, 0x70, 0x79, 0x85, 0xe6, + 0x3c, 0xf, 0xc0, + + /* U+59E8 "姨" */ + 0x60, 0x61, 0x9f, 0xf6, 0x7f, 0xd8, 0x18, 0xfb, + 0xf9, 0x61, 0xa5, 0x86, 0x96, 0xfe, 0xde, 0x63, + 0x5f, 0xf7, 0xe, 0xcc, 0x3b, 0x79, 0xb3, 0x1c, + 0x78, 0x60, 0xc0, + + /* U+5A0C "娌" */ + 0x60, 0x0, 0xc7, 0xf9, 0x89, 0xb7, 0xd3, 0x6f, + 0xbf, 0xcb, 0x4d, 0x96, 0x9b, 0x6d, 0x36, 0xdb, + 0xfd, 0xa0, 0xc1, 0xcf, 0xf1, 0xc3, 0x7, 0x86, + 0x1f, 0xc, 0x31, 0xff, 0x80, + + /* U+5A7F "婿" */ + 0x60, 0x0, 0xcf, 0xfd, 0x81, 0x9b, 0x1b, 0x2f, + 0xb7, 0xcb, 0x7f, 0xd7, 0xbf, 0xae, 0x0, 0xdb, + 0xfd, 0xa6, 0x19, 0xcf, 0xf1, 0x98, 0x63, 0xbf, + 0xcd, 0x61, 0xb0, 0xc7, 0x0, + + /* U+5AB3 "媳" */ + 0x60, 0x60, 0xc0, 0xc1, 0x8f, 0xf7, 0xd8, 0x6f, + 0xbf, 0xcb, 0x61, 0x96, 0xc3, 0x2d, 0xfe, 0xdb, + 0xd, 0xa7, 0xf9, 0xc1, 0x81, 0xaf, 0xe3, 0xfa, + 0x6c, 0xb3, 0xf1, 0x7e, 0x0, + + /* U+5AE1 "嫡" */ + 0x60, 0x60, 0xc0, 0x61, 0x9f, 0xfb, 0xc, 0x6f, + 0x88, 0x8b, 0x7f, 0xd6, 0xc9, 0xed, 0xff, 0xdb, + 0x26, 0xe7, 0xfc, 0xcf, 0x79, 0xdf, 0xf7, 0xbc, + 0x69, 0x60, 0xf0, 0xc3, 0x80, + + /* U+5B50 "子" */ + 0x3f, 0xf8, 0x7f, 0xf0, 0x1, 0xc0, 0xf, 0x0, + 0x18, 0x0, 0x30, 0x3f, 0xff, 0xff, 0xff, 0x1, + 0x80, 0x3, 0x0, 0x6, 0x0, 0xc, 0x0, 0xf8, + 0x1, 0xe0, 0x0, + + /* U+5B59 "孙" */ + 0x0, 0x61, 0xf8, 0xc0, 0x31, 0x80, 0xcb, 0x43, + 0x16, 0xc6, 0x2d, 0x8e, 0xdb, 0x1f, 0xb6, 0xfb, + 0x65, 0xe4, 0xcc, 0xd9, 0x99, 0x93, 0x3, 0x6, + 0x6, 0xc, 0x1c, 0x70, 0x0, + + /* U+5B9A "定" */ + 0x1, 0x80, 0x1, 0x80, 0x7f, 0xfe, 0x7f, 0xfe, + 0x60, 0x6, 0x6f, 0xfe, 0xf, 0xf8, 0x1, 0x80, + 0x19, 0x80, 0x19, 0xf8, 0x19, 0xf8, 0x3d, 0x80, + 0x3f, 0x80, 0x67, 0xfe, 0x61, 0xfe, + + /* U+5C5E "属" */ + 0x3f, 0xfe, 0x60, 0x1c, 0xc0, 0x39, 0xff, 0xf3, + 0x7f, 0x86, 0xf8, 0xd, 0xff, 0x1a, 0x66, 0x37, + 0xfc, 0x61, 0x80, 0xbf, 0xfb, 0x66, 0xb6, 0xff, + 0x69, 0x81, 0xc0, + + /* U+5CB3 "岳" */ + 0x0, 0x70, 0xff, 0xc3, 0x0, 0xc, 0x0, 0x3f, + 0xfc, 0xc1, 0x83, 0x6, 0xc, 0x18, 0xff, 0xfc, + 0xc, 0x6, 0x31, 0x98, 0xc6, 0x63, 0x19, 0xff, + 0xe0, 0x1, 0x80, + + /* U+5DF1 "己" */ + 0xff, 0xe7, 0xff, 0x0, 0x18, 0x0, 0xc0, 0x6, + 0x7f, 0xf3, 0xff, 0x98, 0xc, 0xc0, 0x6, 0x0, + 0xb0, 0x7, 0x80, 0x7f, 0xff, 0x3f, 0xf8, + + /* U+5E2E "帮" */ + 0x18, 0x3, 0xff, 0xff, 0xfd, 0xc6, 0x36, 0x7f, + 0xd8, 0x63, 0x3f, 0xfc, 0xce, 0x3f, 0xf3, 0x1, + 0x8c, 0x3, 0xff, 0x88, 0xc6, 0x23, 0x18, 0x8d, + 0xe0, 0x30, 0x0, + + /* U+5EB6 "庶" */ + 0x1, 0x80, 0x6, 0x7, 0xff, 0xdf, 0xff, 0x60, + 0x1, 0x98, 0xc7, 0xff, 0xd9, 0x8c, 0x66, 0x31, + 0x98, 0xc6, 0x7f, 0x18, 0x2, 0xcb, 0x5b, 0x6d, + 0xbd, 0xb6, 0xc0, 0x0, + + /* U+5F1F "弟" */ + 0x38, 0x60, 0x61, 0x87, 0xff, 0x80, 0xc6, 0x3, + 0x19, 0xff, 0xe6, 0x30, 0x18, 0xc0, 0x63, 0x1, + 0xff, 0xf0, 0xf0, 0xcf, 0xc7, 0xf3, 0x39, 0xc, + 0x0, + + /* U+62E9 "择" */ + 0x20, 0x0, 0x47, 0xf8, 0x86, 0x77, 0xcf, 0xcf, + 0x8f, 0x4, 0x3f, 0x9, 0xe7, 0x9f, 0x36, 0x78, + 0x61, 0xc7, 0xf8, 0x81, 0x81, 0x3, 0x2, 0x7f, + 0xfc, 0xc, 0x18, 0x18, 0x0, + + /* U+6301 "持" */ + 0x30, 0x60, 0x60, 0xc0, 0xc1, 0x81, 0x9f, 0xef, + 0x86, 0x1f, 0xc, 0xd, 0xff, 0x9c, 0xc, 0x38, + 0x19, 0xef, 0xfc, 0xc4, 0x61, 0x8c, 0xc3, 0x19, + 0x9e, 0xf, 0x18, 0x1e, 0x0, + + /* U+652F "支" */ + 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x7f, 0xfe, + 0x7f, 0xfe, 0x1, 0x80, 0x3f, 0xfc, 0x3f, 0xfc, + 0x18, 0x18, 0xc, 0x30, 0x6, 0x70, 0x3, 0xe0, + 0x7, 0xf0, 0xfe, 0x7f, 0x78, 0x1e, + + /* U+660E "明" */ + 0xfd, 0xff, 0x36, 0x3c, 0xd8, 0xf3, 0x63, 0xcd, + 0xff, 0xf7, 0xfc, 0xd8, 0xf3, 0x63, 0xcd, 0xff, + 0xf7, 0xf0, 0x38, 0xc0, 0xc3, 0x7, 0x3c, 0x8, + 0xe0, + + /* U+662F "是" */ + 0x3f, 0xfc, 0x60, 0x18, 0xff, 0xf1, 0x80, 0x63, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x3f, 0xff, 0x19, + 0x80, 0x33, 0xf8, 0x76, 0x1, 0xfc, 0x6, 0x7f, + 0xec, 0x3f, 0xc0, + + /* U+663E "显" */ + 0x3f, 0xf8, 0x60, 0x30, 0xff, 0xe1, 0xff, 0xc3, + 0x1, 0x87, 0xff, 0x0, 0x0, 0x3, 0x60, 0x66, + 0xcc, 0x6d, 0xb0, 0xdb, 0x60, 0x36, 0xf, 0xff, + 0xff, 0xff, 0xc0, + + /* U+66FE "曾" */ + 0x30, 0xc1, 0x88, 0xff, 0xfd, 0x6b, 0xd6, 0xbd, + 0x6b, 0xff, 0xf0, 0x0, 0x7f, 0xe6, 0x6, 0x7f, + 0xe6, 0x6, 0x7f, 0xe6, 0x6, + + /* U+672A "未" */ + 0x1, 0x80, 0x3, 0x0, 0x6, 0x1, 0xff, 0xe3, + 0xff, 0xc0, 0x30, 0x0, 0x60, 0x3f, 0xff, 0x7f, + 0xfe, 0x7, 0x80, 0x1f, 0x80, 0xed, 0xc7, 0x99, + 0xcc, 0x31, 0xc0, 0x60, 0x0, + + /* U+679C "果" */ + 0x3f, 0xf8, 0x8c, 0xe2, 0x33, 0x8f, 0xfe, 0x23, + 0x38, 0x8c, 0xe3, 0xff, 0x80, 0xc0, 0xff, 0xff, + 0xff, 0xf0, 0xfc, 0xe, 0xdc, 0xf3, 0x1c, 0xc, + 0x0, + + /* U+67E5 "查" */ + 0x1, 0x80, 0x1, 0x80, 0x7f, 0xfe, 0x7, 0xe0, + 0xd, 0xb0, 0x39, 0xbe, 0x70, 0xe, 0x7f, 0xf8, + 0x18, 0x18, 0x1f, 0xf8, 0x18, 0x18, 0x1f, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xfe, + + /* U+683C "格" */ + 0x30, 0xc0, 0x63, 0xf8, 0xc7, 0xff, 0xdc, 0x6f, + 0xf9, 0x86, 0x5f, 0x1e, 0x1c, 0x3f, 0xfe, 0x7f, + 0x9f, 0xee, 0xf, 0xcf, 0xf5, 0x98, 0x63, 0x30, + 0xc6, 0x7f, 0x8c, 0xc3, 0x0, + + /* U+6BCD "母" */ + 0x3f, 0xf8, 0xc8, 0x63, 0x71, 0x8c, 0xe6, 0x31, + 0x1b, 0xff, 0xff, 0xff, 0xcc, 0x8c, 0x67, 0x31, + 0x84, 0xc7, 0xff, 0xc0, 0xc, 0x0, 0x60, 0x7, + 0x80, + + /* U+6E05 "清" */ + 0x0, 0xc0, 0xc1, 0x81, 0xdf, 0xf1, 0x86, 0x0, + 0x7f, 0xc8, 0x18, 0x3b, 0xff, 0xb0, 0x0, 0x7, + 0xfc, 0xc, 0x18, 0xdf, 0xf1, 0xb0, 0x66, 0x7f, + 0xcc, 0xc1, 0x91, 0x8e, 0x0, + + /* U+7236 "父" */ + 0x0, 0x0, 0xe, 0x70, 0xc, 0x38, 0x18, 0x1c, + 0x38, 0xe, 0x7c, 0x36, 0x2c, 0x30, 0x6, 0x70, + 0x7, 0x60, 0x3, 0xc0, 0x3, 0xc0, 0x7, 0xe0, + 0xe, 0xf8, 0x7c, 0x3f, 0x70, 0xe, + + /* U+7237 "爷" */ + 0x0, 0x0, 0x1c, 0xe1, 0xf0, 0xf3, 0xf3, 0xe0, + 0x3e, 0x1, 0xfc, 0x3f, 0x9f, 0xb8, 0x6, 0x3f, + 0xf8, 0x7f, 0xf0, 0xc, 0x60, 0x18, 0xc0, 0x37, + 0x80, 0x6e, 0x0, 0xc0, 0x0, + + /* U+7384 "玄" */ + 0x6, 0x0, 0xc, 0xf, 0xff, 0xff, 0xff, 0x6, + 0x0, 0x38, 0x1, 0xc6, 0xe, 0x38, 0x7f, 0xc0, + 0x1e, 0x80, 0xe3, 0x7, 0xe, 0x7f, 0xfd, 0xfc, + 0x30, 0x0, 0x80, + + /* U+7525 "甥" */ + 0x5b, 0xfe, 0xb6, 0x4d, 0xff, 0xff, 0xff, 0xfd, + 0xb2, 0x63, 0x7f, 0xdf, 0x18, 0x3e, 0x30, 0x1b, + 0xfe, 0x31, 0xcc, 0xf3, 0x1f, 0xee, 0x3e, 0x38, + 0x60, 0xc7, 0x80, + + /* U+754C "界" */ + 0x3f, 0xf8, 0x63, 0x30, 0xc6, 0x61, 0xff, 0xc3, + 0x19, 0x86, 0x33, 0xf, 0xfe, 0x7, 0x30, 0x3c, + 0x39, 0xec, 0xf9, 0x39, 0x90, 0x63, 0x3, 0xc6, + 0x6, 0xc, 0x0, + + /* U+7684 "的" */ + 0x30, 0xc0, 0xc3, 0xf, 0xdf, 0xff, 0x7f, 0xcf, + 0xf, 0x3c, 0x3c, 0xc8, 0xff, 0x33, 0xcc, 0xef, + 0x31, 0xbc, 0xc0, 0xff, 0x7, 0xc0, 0xfb, 0x1, + 0xe0, + + /* U+77E5 "知" */ + 0x70, 0x1, 0x83, 0xf7, 0xff, 0xdf, 0xf3, 0xd8, + 0xcf, 0x63, 0x31, 0x8c, 0xff, 0xf3, 0xff, 0xcc, + 0x63, 0x31, 0xcc, 0xcd, 0xb3, 0x37, 0xfd, 0x8b, + 0xfc, 0xc, 0xc0, + + /* U+786E "确" */ + 0x0, 0x3, 0xf6, 0x3, 0x1f, 0x98, 0xcc, 0x63, + 0x31, 0x9f, 0xf7, 0xd6, 0xff, 0x5b, 0xef, 0xff, + 0xbd, 0xbe, 0xff, 0xdb, 0xff, 0x7f, 0x6d, 0x89, + 0xb0, 0x61, 0xc0, + + /* U+793A "示" */ + 0x3f, 0xfc, 0x7f, 0xf8, 0x0, 0x0, 0x0, 0x7, + 0xff, 0xef, 0xff, 0xc0, 0x60, 0xc, 0xcc, 0x19, + 0x98, 0x63, 0x19, 0xc6, 0x3b, 0xc, 0x30, 0x78, + 0x0, 0xf0, 0x0, + + /* U+7956 "祖" */ + 0x10, 0x0, 0x33, 0xf8, 0x67, 0xf7, 0xfc, 0x60, + 0xd8, 0xc1, 0xb1, 0x87, 0x7f, 0x1e, 0xc6, 0x7f, + 0x8d, 0xbb, 0xf8, 0x66, 0x30, 0xcc, 0x61, 0x98, + 0xc3, 0x7f, 0xc6, 0xff, 0x80, + + /* U+7A7A "空" */ + 0x3, 0x0, 0xc, 0xf, 0xff, 0xf0, 0x3, 0xcc, + 0xec, 0xf1, 0xcf, 0x83, 0xd8, 0x2, 0x3f, 0xf0, + 0xc, 0x0, 0x30, 0x0, 0xc0, 0xff, 0xfc, + + /* U+7B97 "算" */ + 0x30, 0xc1, 0xff, 0xfd, 0xb3, 0xf, 0xfe, 0x30, + 0x18, 0xff, 0xe3, 0x1, 0x8f, 0xfe, 0x3f, 0xf8, + 0x31, 0x80, 0xc6, 0x3f, 0xff, 0x38, 0x61, 0x81, + 0x80, + + /* U+7CFB "系" */ + 0x0, 0xf1, 0xff, 0xc0, 0xe4, 0x6, 0x38, 0x7f, + 0xc0, 0x3d, 0x83, 0x83, 0x1f, 0xfe, 0x63, 0xc, + 0xcc, 0x87, 0x37, 0x38, 0xc7, 0xcf, 0x8, 0x3c, + 0x0, + + /* U+7ED3 "结" */ + 0x30, 0x70, 0x60, 0xe0, 0xcf, 0xfb, 0x5f, 0xf6, + 0xc7, 0x1f, 0x8e, 0x3e, 0xff, 0x99, 0xff, 0x60, + 0x1, 0xfb, 0xfa, 0x6, 0x30, 0x2c, 0x67, 0xd8, + 0xdf, 0x3f, 0x80, 0x63, 0x0, + + /* U+7EE7 "继" */ + 0x10, 0x30, 0x66, 0x60, 0xce, 0xdb, 0x9b, 0xa6, + 0xb7, 0xdd, 0xe6, 0x3e, 0xff, 0x99, 0xbc, 0x67, + 0x7d, 0xf7, 0xed, 0xe, 0xd0, 0xf9, 0x8f, 0xf0, + 0x1e, 0x7f, 0xc0, + + /* U+81EA "自" */ + 0x6, 0x0, 0xe0, 0xff, 0xff, 0xff, 0xc0, 0x3c, + 0x3, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, + 0xfc, 0x3, 0xc0, 0x3f, 0xff, 0xff, 0xf0, + + /* U+8205 "舅" */ + 0x7f, 0xfb, 0xff, 0xdf, 0xfe, 0xff, 0xf0, 0x0, + 0x3f, 0xfd, 0x8c, 0x6f, 0xff, 0x63, 0x18, 0xff, + 0x1f, 0xfe, 0x1c, 0x31, 0xc1, 0xf8, 0x38, + + /* U+83DC "菜" */ + 0x18, 0x63, 0xff, 0xf1, 0x86, 0x0, 0x1c, 0x3, + 0xf9, 0xff, 0xc6, 0x21, 0x8c, 0xcc, 0x33, 0x0, + 0xc, 0xf, 0xff, 0xc3, 0xf0, 0x7b, 0x73, 0xcc, + 0xf0, 0x30, 0x0, + + /* U+8868 "表" */ + 0x1, 0x80, 0x3f, 0xfc, 0x3f, 0xfc, 0x1, 0x80, + 0x3f, 0xfc, 0x1, 0x80, 0x1, 0x80, 0x7f, 0xfe, + 0x7, 0xc4, 0x1c, 0xce, 0x7c, 0x78, 0x6c, 0x30, + 0xf, 0xbc, 0x1f, 0x8e, 0xc, 0x6, + + /* U+8BA1 "计" */ + 0x20, 0x60, 0xe0, 0xc0, 0xe1, 0x80, 0x83, 0x0, + 0x6, 0x1e, 0xff, 0xfd, 0xff, 0x98, 0x30, 0x30, + 0x60, 0x60, 0xc0, 0xd1, 0x81, 0xe3, 0x3, 0x86, + 0xe, 0xc, 0x8, 0x18, 0x0, + + /* U+8BE2 "询" */ + 0x21, 0x80, 0xe3, 0x0, 0x4f, 0xf8, 0x30, 0x3f, + 0x7f, 0x7e, 0x7e, 0xcc, 0xcd, 0x99, 0xfb, 0x33, + 0x36, 0x66, 0x6c, 0xff, 0xd9, 0xd8, 0x77, 0x3, + 0xc0, 0x7, 0x80, + + /* U+8BF4 "说" */ + 0x23, 0x18, 0xe6, 0x30, 0xe6, 0xc0, 0xbf, 0xe0, + 0x7f, 0xde, 0xc1, 0x8d, 0xff, 0x1b, 0xfe, 0x31, + 0xb0, 0x73, 0x60, 0xfc, 0xd3, 0xd9, 0xb6, 0xe3, + 0xe0, 0x87, 0x80, + + /* U+8BF7 "请" */ + 0x0, 0x60, 0xc0, 0xc1, 0xdf, 0xf9, 0x83, 0x1, + 0x3f, 0xc0, 0xc, 0x3d, 0xff, 0xf8, 0x0, 0x33, + 0xfc, 0x66, 0x18, 0xcf, 0xf1, 0xd8, 0x63, 0xbf, + 0xc6, 0x61, 0x88, 0xce, 0x0, + + /* U+8F93 "输" */ + 0x20, 0x60, 0xc1, 0xc3, 0xe7, 0xc7, 0xfc, 0xe4, + 0x7f, 0xee, 0x0, 0x3c, 0xf1, 0x7d, 0xea, 0xfb, + 0xd4, 0x67, 0xab, 0xef, 0x57, 0x9e, 0xa3, 0x34, + 0x46, 0x68, 0x8c, 0xf7, 0x0, + + /* U+8FD4 "返" */ + 0x0, 0xc, 0x63, 0xfe, 0x33, 0x0, 0x3, 0xfe, + 0x3, 0xfe, 0xf3, 0xc, 0xf3, 0xec, 0x33, 0x78, + 0x36, 0x38, 0x36, 0xfc, 0x3e, 0xce, 0x78, 0x0, + 0xff, 0xfe, 0x47, 0xfe, + + /* U+8FD9 "这" */ + 0x40, 0xc1, 0xc1, 0x81, 0xff, 0xf9, 0x7f, 0xf0, + 0x21, 0x9e, 0xf6, 0x3c, 0x7c, 0x18, 0x70, 0x31, + 0xf8, 0x6f, 0x38, 0xd8, 0x33, 0xe0, 0xf, 0xff, + 0xe8, 0xff, 0xc0, + + /* U+9009 "选" */ + 0x0, 0x60, 0xc6, 0xc1, 0xcd, 0x81, 0xbf, 0xe0, + 0x66, 0x0, 0xff, 0xfd, 0xff, 0xf8, 0xd8, 0x31, + 0xb0, 0x63, 0x68, 0xce, 0xc9, 0xb8, 0xf3, 0xa1, + 0xfd, 0xff, 0xd0, 0xff, 0x80, + + /* U+9664 "除" */ + 0x0, 0x41, 0xf0, 0xc3, 0x63, 0xc6, 0xcc, 0xcd, + 0x31, 0xde, 0xe1, 0xfc, 0xfe, 0x6c, 0x30, 0xdf, + 0xff, 0xbf, 0xff, 0xed, 0xa6, 0x1b, 0x6c, 0x66, + 0xd9, 0x8c, 0xf0, 0x78, 0x0, + + /* U+9762 "面" */ + 0xff, 0xff, 0xff, 0xf0, 0x30, 0x1f, 0xfe, 0x7f, + 0xf9, 0x33, 0x64, 0xcd, 0x93, 0xf6, 0x4c, 0xd9, + 0x3f, 0x64, 0xcd, 0x93, 0x36, 0x7f, 0xf9, 0xff, + 0xe0, + + /* U+FF01 "!" */ + 0xff, 0xff, 0xfa, 0x1f, 0xf0, + + /* U+FF0C "," */ + 0xdf, 0xbd, 0x80, + + /* U+FF1A ":" */ + 0xff, 0x80, 0x0, 0xff, 0x80, + + /* U+FF1B ";" */ + 0xff, 0x80, 0x7, 0xfc, 0xbd, 0x0, + + /* U+FF1F "?" */ + 0x3c, 0xfd, 0x18, 0x30, 0xe3, 0x86, 0x8, 0x0, + 0x70, 0xe1, 0xc0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 58, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 95, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6, .adv_w = 147, .box_w = 6, .box_h = 5, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 10, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 22, .adv_w = 151, .box_w = 7, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 36, .adv_w = 246, .box_w = 15, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 59, .adv_w = 189, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 76, .adv_w = 83, .box_w = 2, .box_h = 5, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 78, .adv_w = 97, .box_w = 4, .box_h = 16, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 86, .adv_w = 97, .box_w = 4, .box_h = 16, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 94, .adv_w = 130, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 99, .adv_w = 151, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 107, .adv_w = 83, .box_w = 4, .box_h = 5, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 110, .adv_w = 95, .box_w = 4, .box_h = 2, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 111, .adv_w = 83, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 113, .adv_w = 99, .box_w = 6, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 125, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 137, .adv_w = 151, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 148, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 160, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 172, .adv_w = 151, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 186, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 198, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 210, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 222, .adv_w = 151, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 233, .adv_w = 151, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 245, .adv_w = 83, .box_w = 3, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 249, .adv_w = 83, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 254, .adv_w = 151, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 262, .adv_w = 151, .box_w = 8, .box_h = 6, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 268, .adv_w = 151, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 276, .adv_w = 132, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 287, .adv_w = 258, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 317, .adv_w = 164, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 332, .adv_w = 174, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 346, .adv_w = 168, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 360, .adv_w = 183, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 374, .adv_w = 157, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 386, .adv_w = 150, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 398, .adv_w = 184, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 412, .adv_w = 194, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 426, .adv_w = 84, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 429, .adv_w = 145, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 440, .adv_w = 176, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 454, .adv_w = 148, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 465, .adv_w = 219, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 482, .adv_w = 192, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 496, .adv_w = 197, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 511, .adv_w = 171, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 523, .adv_w = 197, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 544, .adv_w = 175, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 558, .adv_w = 160, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 572, .adv_w = 160, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 586, .adv_w = 191, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 600, .adv_w = 158, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 615, .adv_w = 234, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 636, .adv_w = 161, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 651, .adv_w = 149, .box_w = 10, .box_h = 12, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 666, .adv_w = 157, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 678, .adv_w = 97, .box_w = 4, .box_h = 15, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 686, .adv_w = 99, .box_w = 6, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 698, .adv_w = 97, .box_w = 4, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 706, .adv_w = 151, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 713, .adv_w = 145, .box_w = 9, .box_h = 2, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 716, .adv_w = 160, .box_w = 4, .box_h = 4, .ofs_x = 2, .ofs_y = 10}, + {.bitmap_index = 718, .adv_w = 151, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 726, .adv_w = 165, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 739, .adv_w = 135, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 747, .adv_w = 165, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 760, .adv_w = 149, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 769, .adv_w = 95, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 779, .adv_w = 153, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 791, .adv_w = 164, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 804, .adv_w = 78, .box_w = 2, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 808, .adv_w = 78, .box_w = 4, .box_h = 16, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 816, .adv_w = 155, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 829, .adv_w = 81, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 834, .adv_w = 247, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 848, .adv_w = 164, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 857, .adv_w = 160, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 866, .adv_w = 165, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 878, .adv_w = 165, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 890, .adv_w = 112, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 896, .adv_w = 127, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 903, .adv_w = 108, .box_w = 6, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 912, .adv_w = 163, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 921, .adv_w = 147, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 932, .adv_w = 221, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 947, .adv_w = 144, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 958, .adv_w = 147, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 972, .adv_w = 131, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 980, .adv_w = 97, .box_w = 5, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 990, .adv_w = 76, .box_w = 2, .box_h = 18, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 995, .adv_w = 97, .box_w = 5, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1005, .adv_w = 151, .box_w = 8, .box_h = 3, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 1008, .adv_w = 256, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 1}, + {.bitmap_index = 1021, .adv_w = 256, .box_w = 11, .box_h = 10, .ofs_x = 2, .ofs_y = 2}, + {.bitmap_index = 1035, .adv_w = 256, .box_w = 6, .box_h = 5, .ofs_x = 10, .ofs_y = 9}, + {.bitmap_index = 1039, .adv_w = 256, .box_w = 6, .box_h = 5, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 1043, .adv_w = 256, .box_w = 14, .box_h = 7, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 1056, .adv_w = 256, .box_w = 8, .box_h = 15, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 1071, .adv_w = 256, .box_w = 14, .box_h = 7, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 1084, .adv_w = 256, .box_w = 8, .box_h = 15, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 1099, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1129, .adv_w = 256, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1133, .adv_w = 256, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1137, .adv_w = 256, .box_w = 8, .box_h = 15, .ofs_x = 8, .ofs_y = -1}, + {.bitmap_index = 1152, .adv_w = 256, .box_w = 8, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1167, .adv_w = 256, .box_w = 15, .box_h = 2, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 1171, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1198, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1228, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1255, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1280, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1309, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1336, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1365, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1393, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1420, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1447, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1474, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1503, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1532, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1559, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1588, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1615, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1644, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1669, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1694, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1719, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1748, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1777, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1806, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1833, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1862, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1889, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1918, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1945, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 1973, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2002, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2029, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2056, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2085, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2114, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2143, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2172, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2199, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2228, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2258, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2285, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2312, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2335, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2362, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 2390, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2415, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2444, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2473, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2503, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2528, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2555, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2582, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2603, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2632, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2657, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2687, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2716, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2741, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2770, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2800, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2829, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2856, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2883, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2910, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2935, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2962, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 2989, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3016, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3045, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3068, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3093, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3118, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3147, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3174, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3197, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3220, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3247, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3277, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3306, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3333, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3360, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3389, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3418, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3446, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3473, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3502, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3531, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3556, .adv_w = 256, .box_w = 3, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3561, .adv_w = 256, .box_w = 3, .box_h = 6, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 3564, .adv_w = 256, .box_w = 3, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3569, .adv_w = 256, .box_w = 3, .box_h = 14, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 3575, .adv_w = 256, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x20, 0x1f45, 0x1f46, 0x20b9, 0x20ba, 0x20bb, 0x20bc, + 0x2143, 0x2f2a, 0x2f2b, 0x2f33, 0x2f34, 0x4d29, 0x4d31, 0x4d53, + 0x4d64, 0x4ddb, 0x4df7, 0x4e58, 0x4ead, 0x5068, 0x506d, 0x508e, + 0x5095, 0x509c, 0x50a4, 0x50b6, 0x51d2, 0x527e, 0x52fd, 0x540e, + 0x5591, 0x5607, 0x572b, 0x583f, 0x5854, 0x589c, 0x589f, 0x58d8, + 0x58e2, 0x58e4, 0x58f9, 0x58fa, 0x590e, 0x5911, 0x5935, 0x59a8, + 0x59dc, 0x5a0a, 0x5a79, 0x5a82, 0x5ac3, 0x5b87, 0x5bdc, 0x5d1a, + 0x5d57, 0x5ddf, 0x5e48, 0x6212, 0x622a, 0x6458, 0x6537, 0x6558, + 0x6567, 0x6627, 0x6653, 0x66c5, 0x670e, 0x6765, 0x6af6, 0x6d2e, + 0x715f, 0x7160, 0x72ad, 0x744e, 0x7475, 0x75ad, 0x770e, 0x7797, + 0x7863, 0x787f, 0x79a3, 0x7ac0, 0x7c24, 0x7dfc, 0x7e10, 0x8113, + 0x812e, 0x8305, 0x8791, 0x8aca, 0x8b0b, 0x8b1d, 0x8b20, 0x8ebc, + 0x8efd, 0x8f02, 0x8f32, 0x958d, 0x968b, 0xfe2a, 0xfe35, 0xfe43, + 0xfe44, 0xfe48 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 215, .range_length = 65097, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 106, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 2, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_siyuan_16 = { +#else +lv_font_t lv_font_siyuan_16 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 18, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -2, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if LV_FONT_SIYUAN_16*/ + diff --git a/relation_calculator/img/show.gif b/relation_calculator/img/show.gif new file mode 100644 index 0000000000000000000000000000000000000000..52f591632accb17ec81ff775c040426bc73b12f9 Binary files /dev/null and b/relation_calculator/img/show.gif differ diff --git a/relation_calculator/relation_cal.c b/relation_calculator/relation_cal.c new file mode 100644 index 0000000000000000000000000000000000000000..ed8f086a404584405ff3584bce1b8716faeba950 --- /dev/null +++ b/relation_calculator/relation_cal.c @@ -0,0 +1,444 @@ +#include "relation_cal.h" +#include <string.h> + +#define SCREEN_WIDTH (lv_obj_get_width(lv_scr_act())) +#define SCREEN_HEIGHT (lv_obj_get_height(lv_scr_act())) + +#define DEMO_WIDTH (int32_t)((SCREEN_WIDTH * 0.85f)) +#define DEMO_HEIGHT (int32_t)(((DEMO_WIDTH) / 16.0f) * 9.0f) +#define DEMO_TITLE_HEIGHT (int32_t)(((DEMO_WIDTH) / 16.0f) * 1.2f) + +static relation_cal_t g_rel_cal; + +static const relation_transformation_t transitions[] = { + // Self - related relationships + {REL_SELF, REL_SELF, REL_SELF}, // Self to self remains self + {REL_SELF, REL_FATHER, REL_FATHER}, // Self to father is father + {REL_SELF, REL_MOTHER, REL_MOTHER}, // Self to mother is mother + {REL_SELF, REL_SON, REL_SON}, // Self to son is son + {REL_SELF, REL_DAUGHTER, REL_DAUGHTER}, // Self to daughter is daughter + {REL_SELF, REL_ELDER_BROTHER, REL_ELDER_BROTHER}, // Self to elder brother is elder brother + {REL_SELF, REL_YOUNGER_BROTHER, REL_YOUNGER_BROTHER}, // Self to younger brother is younger brother + {REL_SELF, REL_ELDER_SISTER, REL_ELDER_SISTER}, // Self to elder sister is elder sister + {REL_SELF, REL_YOUNGER_SISTER, REL_YOUNGER_SISTER}, // Self to younger sister is younger sister + + // Parent - child relationships + {REL_FATHER, REL_SON, REL_SELF}, // Father to son is self + {REL_FATHER, REL_DAUGHTER, REL_SELF}, // Father to daughter is self + {REL_FATHER, REL_WIFE, REL_MOTHER}, + {REL_MOTHER, REL_SON, REL_SELF}, // Mother to son is self + {REL_MOTHER, REL_DAUGHTER, REL_SELF}, // Mother to daughter is self + {REL_MOTHER, REL_HUSBAND, REL_FATHER}, + {REL_SON, REL_FATHER, REL_SELF}, // Son to father is self + {REL_SON, REL_MOTHER, REL_SELF}, // Son to mother is self + {REL_DAUGHTER, REL_FATHER, REL_SELF}, // Daughter to father is self + {REL_DAUGHTER, REL_MOTHER, REL_SELF}, // Daughter to mother is self + + // Grandparent relationships + {REL_FATHER, REL_FATHER, REL_GRANDFATHER}, // Father's father is grandfather + {REL_FATHER, REL_MOTHER, REL_GRANDMOTHER}, // Father's mother is grandmother + {REL_MOTHER, REL_FATHER, REL_GRANDFATHER}, // Mother's father is grandfather + {REL_MOTHER, REL_MOTHER, REL_GRANDMOTHER}, // Mother's mother is grandmother + {REL_GRANDFATHER, REL_SON, REL_FATHER}, // Grandfather to son is father + {REL_GRANDFATHER, REL_DAUGHTER, REL_AUNT}, // Grandfather to daughter is aunt + {REL_GRANDMOTHER, REL_SON, REL_FATHER}, // Grandmother to son is father + {REL_GRANDMOTHER, REL_DAUGHTER, REL_AUNT}, // Grandmother to daughter is aunt + + // Great - grandparent relationships + {REL_GRANDFATHER, REL_FATHER, REL_GREAT_GRANDFATHER}, // Grandfather's father is great - grandfather + {REL_GRANDFATHER, REL_MOTHER, REL_GREAT_GRANDMOTHER}, // Grandfather's mother is great - grandmother + {REL_GRANDMOTHER, REL_FATHER, REL_GREAT_GRANDFATHER}, // Grandmother's father is great - grandfather + {REL_GRANDMOTHER, REL_MOTHER, REL_GREAT_GRANDMOTHER}, // Grandmother's mother is great - grandmother + {REL_MATERNAL_GRANDFATHER, REL_FATHER, REL_MATERNAL_GREAT_GRANDFATHER}, // Maternal grandfather's father is maternal great - grandfather + {REL_MATERNAL_GRANDFATHER, REL_MOTHER, REL_MATERNAL_GREAT_GRANDMOTHER}, // Maternal grandfather's mother is maternal great - grandmother + {REL_MATERNAL_GRANDMOTHER, REL_FATHER, REL_MATERNAL_GREAT_GRANDFATHER}, // Maternal grandmother's father is maternal great - grandfather + {REL_MATERNAL_GRANDMOTHER, REL_MOTHER, REL_MATERNAL_GREAT_GRANDMOTHER}, // Maternal grandmother's mother is maternal great - grandmother + + // Sibling relationships + {REL_ELDER_BROTHER, REL_FATHER, REL_FATHER}, + {REL_ELDER_BROTHER, REL_MOTHER, REL_MOTHER}, + {REL_YOUNGER_BROTHER, REL_FATHER, REL_FATHER}, // Younger brother to father remains father + {REL_YOUNGER_BROTHER, REL_MOTHER, REL_MOTHER}, // Younger brother to mother remains younger brother + {REL_ELDER_SISTER, REL_FATHER, REL_ELDER_SISTER}, // Elder sister to father remains elder sister + {REL_ELDER_SISTER, REL_MOTHER, REL_ELDER_SISTER}, // Elder sister to mother remains elder sister + {REL_YOUNGER_SISTER, REL_FATHER, REL_YOUNGER_SISTER}, // Younger sister to father remains younger sister + {REL_YOUNGER_SISTER, REL_MOTHER, REL_YOUNGER_SISTER}, // Younger sister to mother remains younger sister + {REL_ELDER_BROTHER, REL_ELDER_BROTHER, REL_ELDER_BROTHER}, // Elder brother to elder brother remains elder brother + {REL_ELDER_BROTHER, REL_YOUNGER_BROTHER, REL_YOUNGER_BROTHER}, // Elder brother to younger brother remains elder brother + {REL_YOUNGER_BROTHER, REL_ELDER_BROTHER, REL_ELDER_BROTHER}, // Younger brother to elder brother remains younger brother + {REL_YOUNGER_BROTHER, REL_YOUNGER_BROTHER, REL_YOUNGER_BROTHER}, // Younger brother to younger brother remains younger brother + {REL_ELDER_SISTER, REL_ELDER_SISTER, REL_ELDER_SISTER}, // Elder sister to elder sister remains elder sister + {REL_ELDER_SISTER, REL_YOUNGER_SISTER, REL_ELDER_SISTER}, // Elder sister to younger sister remains elder sister + {REL_YOUNGER_SISTER, REL_ELDER_SISTER, REL_YOUNGER_SISTER}, // Younger sister to elder sister remains younger sister + {REL_YOUNGER_SISTER, REL_YOUNGER_SISTER, REL_YOUNGER_SISTER}, // Younger sister to younger sister remains younger sister + + // Spouse relationships + {REL_WIFE, REL_HUSBAND, REL_SELF}, + {REL_HUSBAND, REL_WIFE, REL_SELF}, + + // Uncle and aunt relationships + {REL_FATHER, REL_ELDER_BROTHER, REL_UNCLE}, // Father's elder brother is uncle + {REL_FATHER, REL_YOUNGER_BROTHER, REL_UNCLE}, // Father's younger brother is uncle + {REL_FATHER, REL_ELDER_SISTER, REL_AUNT}, // Father's elder sister is aunt + {REL_FATHER, REL_YOUNGER_SISTER, REL_AUNT}, // Father's younger sister is aunt + {REL_MOTHER, REL_ELDER_BROTHER, REL_MATERNAL_UNCLE}, // Mother's elder brother is maternal uncle + {REL_MOTHER, REL_YOUNGER_BROTHER, REL_MATERNAL_UNCLE}, // Mother's younger brother is maternal uncle + {REL_MOTHER, REL_ELDER_SISTER, REL_MATERNAL_AUNT}, // Mother's elder sister is maternal aunt + {REL_MOTHER, REL_YOUNGER_SISTER, REL_MATERNAL_AUNT}, // Mother's younger sister is maternal aunt + {REL_UNCLE, REL_SON, REL_COUSIN_MALE}, // Uncle to son is male cousin + {REL_UNCLE, REL_DAUGHTER, REL_COUSIN_FEMALE}, // Uncle to daughter is female cousin + {REL_AUNT, REL_SON, REL_COUSIN_MALE}, // Aunt to son is male cousin + {REL_AUNT, REL_DAUGHTER, REL_COUSIN_FEMALE}, // Aunt to daughter is female cousin + {REL_MATERNAL_UNCLE, REL_SON, REL_COUSIN_MALE}, // Maternal uncle to son is male cousin + {REL_MATERNAL_UNCLE, REL_DAUGHTER, REL_COUSIN_FEMALE}, // Maternal uncle to daughter is female cousin + {REL_MATERNAL_AUNT, REL_SON, REL_COUSIN_MALE}, // Maternal aunt to son is male cousin + {REL_MATERNAL_AUNT, REL_DAUGHTER, REL_COUSIN_FEMALE}, // Maternal aunt to daughter is female cousin + + // Cousin relationships + {REL_COUSIN_MALE, REL_FATHER, REL_COUSIN_MALE}, // Male cousin to father remains male cousin + {REL_COUSIN_MALE, REL_MOTHER, REL_COUSIN_MALE}, // Male cousin to mother remains male cousin + {REL_COUSIN_FEMALE, REL_FATHER, REL_COUSIN_FEMALE}, // Female cousin to father remains female cousin + {REL_COUSIN_FEMALE, REL_MOTHER, REL_COUSIN_FEMALE}, // Female cousin to mother remains female cousin + + // Great - uncle and great - aunt relationships + {REL_GRANDFATHER, REL_ELDER_BROTHER, REL_GREAT_UNCLE}, // Grandfather's elder brother is great - uncle + {REL_GRANDFATHER, REL_YOUNGER_BROTHER, REL_GREAT_UNCLE}, // Grandfather's younger brother is great - uncle + {REL_GRANDFATHER, REL_ELDER_SISTER, REL_GREAT_AUNT}, // Grandfather's elder sister is great - aunt + {REL_GRANDFATHER, REL_YOUNGER_SISTER, REL_GREAT_AUNT}, // Grandfather's younger sister is great - aunt + {REL_GREAT_UNCLE, REL_SON, REL_FIRST_COUSIN_ONCE_REMOVED_MALE}, // Great - uncle to son is male first cousin once removed + {REL_GREAT_UNCLE, REL_DAUGHTER, REL_FIRST_COUSIN_ONCE_REMOVED_FEMALE}, // Great - uncle to daughter is female first cousin once removed + {REL_GREAT_AUNT, REL_SON, REL_FIRST_COUSIN_ONCE_REMOVED_MALE}, // Great - aunt to son is male first cousin once removed + {REL_GREAT_AUNT, REL_DAUGHTER, REL_FIRST_COUSIN_ONCE_REMOVED_FEMALE}, // Great - aunt to daughter is female first cousin once removed + + // Second - cousin relationships + {REL_FIRST_COUSIN_ONCE_REMOVED_MALE, REL_SON, REL_SECOND_COUSIN_MALE}, // Male first cousin once removed to son is male second cousin + {REL_FIRST_COUSIN_ONCE_REMOVED_MALE, REL_DAUGHTER, REL_SECOND_COUSIN_FEMALE}, // Male first cousin once removed to daughter is female second cousin + {REL_FIRST_COUSIN_ONCE_REMOVED_FEMALE, REL_SON, REL_SECOND_COUSIN_MALE}, // Female first cousin once removed to son is male second cousin + {REL_FIRST_COUSIN_ONCE_REMOVED_FEMALE, REL_DAUGHTER, REL_SECOND_COUSIN_FEMALE}, // Female first cousin once removed to daughter is female second cousin + + // Nephew and niece relationships + {REL_ELDER_BROTHER, REL_SON, REL_NEPHEW}, // Elder brother to son is nephew + {REL_ELDER_BROTHER, REL_DAUGHTER, REL_NIECE}, // Elder brother to daughter is niece + {REL_YOUNGER_BROTHER, REL_SON, REL_NEPHEW}, // Younger brother to son is nephew + {REL_YOUNGER_BROTHER, REL_DAUGHTER, REL_NIECE}, // Younger brother to daughter is niece + {REL_ELDER_SISTER, REL_SON, REL_NEPHEW}, // Elder sister to son is nephew + {REL_ELDER_SISTER, REL_DAUGHTER, REL_NIECE}, // Elder sister to daughter is niece + {REL_YOUNGER_SISTER, REL_SON, REL_NEPHEW}, // Younger sister to son is nephew + {REL_YOUNGER_SISTER, REL_DAUGHTER, REL_NIECE}, // Younger sister to daughter is niece + + {REL_SELF, REL_SON_IN_LAW, REL_SON_IN_LAW}, // Self to son - in - law is son - in - law + {REL_SELF, REL_DAUGHTER_IN_LAW, REL_DAUGHTER_IN_LAW}, // Self to daughter - in - law is daughter - in - law + {REL_SELF, REL_GRANDSON, REL_GRANDSON}, // Self to grandson is grandson + {REL_SELF, REL_GRANDDAUGHTER, REL_GRANDDAUGHTER}, // Self to granddaughter is granddaughter + {REL_SELF, REL_GREAT_GRANDSON, REL_GREAT_GRANDSON}, // Self to great - grandson is great - grandson + {REL_SELF, REL_GREAT_GRANDDAUGHTER, REL_GREAT_GRANDDAUGHTER}, // Self to great - granddaughter is great - granddaughter + + {REL_SON, REL_SON, REL_GRANDSON}, // Son to son is grandson + {REL_SON, REL_DAUGHTER, REL_GRANDDAUGHTER}, // Son to daughter is granddaughter + {REL_DAUGHTER, REL_SON, REL_GRANDSON}, // Daughter to son is grandson + {REL_DAUGHTER, REL_DAUGHTER, REL_GRANDDAUGHTER}, // Daughter to daughter is granddaughter + + {REL_GRANDSON, REL_FATHER, REL_SON}, // Grandson to father is son + {REL_GRANDSON, REL_MOTHER, REL_DAUGHTER_IN_LAW}, // Grandson to mother is daughter + {REL_GRANDDAUGHTER, REL_FATHER, REL_SON}, // Granddaughter to father is son + {REL_GRANDDAUGHTER, REL_MOTHER, REL_DAUGHTER_IN_LAW}, // Granddaughter to mother is daughter + + {REL_SON_IN_LAW, REL_HUSBAND, REL_SON}, // Son - in - law to husband is son + {REL_DAUGHTER_IN_LAW, REL_WIFE, REL_DAUGHTER}, // Daughter - in - law to wife is daughter + + {REL_GRANDSON, REL_SON, REL_GREAT_GRANDSON}, // Grandson to son is great - grandson + {REL_GRANDDAUGHTER, REL_DAUGHTER, REL_GREAT_GRANDDAUGHTER}, // Granddaughter to daughter is great - granddaughter + + // Newly added other junior - generation relationships + {REL_SON, REL_SON, REL_GRANDSON}, // Son to son is grandson + {REL_SON, REL_DAUGHTER, REL_GRANDDAUGHTER}, // Son to daughter is granddaughter + {REL_DAUGHTER, REL_SON, REL_GRANDSON}, // Daughter to son is grandson + {REL_DAUGHTER, REL_DAUGHTER, REL_GRANDDAUGHTER}, // Daughter to daughter is granddaughter + + {REL_NEPHEW, REL_SON, REL_GRAND_NEPHEW}, // Nephew to son is grand - nephew + {REL_NEPHEW, REL_DAUGHTER, REL_GRAND_NIECE}, // Nephew to daughter is grand - niece + {REL_NIECE, REL_SON, REL_GRAND_NEPHEW}, // Niece to son is grand - nephew + {REL_NIECE, REL_DAUGHTER, REL_GRAND_NIECE}, // Niece to daughter is grand - niece + + {REL_COUSIN_MALE, REL_SON, REL_COUSIN_SON}, // Male cousin to son is cousin - son + {REL_COUSIN_MALE, REL_DAUGHTER, REL_COUSIN_DAUGHTER}, // Male cousin to daughter is cousin - daughter + {REL_COUSIN_FEMALE, REL_SON, REL_COUSIN_SON}, // Female cousin to son is cousin - son + {REL_COUSIN_FEMALE, REL_DAUGHTER, REL_COUSIN_DAUGHTER}, // Female cousin to daughter is cousin - daughter + + {REL_SON, REL_WIFE, REL_SON_IN_LAW}, // Son to wife is son - in - law + {REL_DAUGHTER, REL_HUSBAND, REL_DAUGHTER_IN_LAW}, // Daughter to husband is daughter - in - law + + {REL_SON_IN_LAW, REL_FATHER, REL_SON}, // Son - in - law to father is son + {REL_DAUGHTER_IN_LAW, REL_FATHER, REL_DAUGHTER}, // Daughter - in - law to father is daughter + + {REL_NULL, REL_NULL, REL_NULL} // End marker +}; + +static const char *relation_names[] = { + "自己", // REL_SELF + "父亲", // REL_FATHER + "母亲", // REL_MOTHER + "儿子", // REL_SON + "女儿", // REL_DAUGHTER + "妻子", // REL_WIFE + "丈夫", // REL_HUSBAND + "哥哥", // REL_ELDER_BROTHER + "弟弟", // REL_YOUNGER_BROTHER + "姐姐", // REL_ELDER_SISTER + "妹妹", // REL_YOUNGER_SISTER + "祖父", // REL_GRANDFATHER + "祖母", // REL_GRANDMOTHER + "伯父", // REL_UNCLE + "姑母", // REL_AUNT + "堂兄弟", // REL_COUSIN_MALE + "堂姐妹", // REL_COUSIN_FEMALE + "曾祖父", // REL_GREAT_GRANDFATHER + "曾祖母", // REL_GREAT_GRANDMOTHER + "外祖父", // REL_MATERNAL_GRANDFATHER + "外祖母", // REL_MATERNAL_GRANDMOTHER + "外曾祖父", // REL_MATERNAL_GREAT_GRANDFATHER + "外曾祖母", // REL_MATERNAL_GREAT_GRANDMOTHER + "表侄", // REL_FIRST_COUSIN_ONCE_REMOVED_MALE + "表侄女", // REL_FIRST_COUSIN_ONCE_REMOVED_FEMALE + "再从兄弟", // REL_SECOND_COUSIN_MALE + "再从姐妹", // REL_SECOND_COUSIN_FEMALE + "叔祖父", // REL_GREAT_UNCLE + "姑祖母", // REL_GREAT_AUNT + "舅父", // REL_MATERNAL_UNCLE + "姨母", // REL_MATERNAL_AUNT + "侄子", // REL_NEPHEW + "侄女", // REL_NIECE + "儿媳", // REL_SON_IN_LAW + "女婿", // REL_DAUGHTER_IN_LAW + "孙子", // REL_GRANDSON + "孙女", // REL_GRANDDAUGHTER + "曾孙子", // REL_GREAT_GRANDSON + "曾孙女", // REL_GREAT_GRANDDAUGHTER + "堂侄/表侄", // REL_COUSIN_SON + "堂侄女/表侄女", // REL_COUSIN_DAUGHTER + "孙侄", // REL_GRAND_NEPHEW + "孙侄女", // REL_GRAND_NIECE + "未知" // REL_NULL +}; + +static const btnm_relation_t btnm_relation[] = { + {"父亲", REL_FATHER, GENDER_MALE}, + {"母亲", REL_MOTHER, GENDER_FEMALE}, + {"丈夫", REL_HUSBAND, GENDER_MALE}, + {"妻子", REL_WIFE, GENDER_FEMALE}, + {"儿子", REL_SON, GENDER_MALE}, + {"女儿", REL_DAUGHTER, GENDER_FEMALE}, + {"哥哥", REL_ELDER_BROTHER, GENDER_MALE}, + {"弟弟", REL_YOUNGER_BROTHER, GENDER_MALE}, + {"姐姐", REL_ELDER_SISTER, GENDER_FEMALE}, + {"妹妹", REL_YOUNGER_SISTER, GENDER_FEMALE} +}; + +static const char *btnm_map[] = { + "父亲", "丈夫", "儿子", "哥哥", "姐姐", "<-", "清除", "\n", + "母亲", "妻子", "女儿", "弟弟", "妹妹", " ", "计算", "" +}; + +static void rel_cal_main_page(void); +static void rel_cal_btnmatrix_event_cb(lv_event_t *e); +static void rel_transform_handle(const uint8_t id, const char *text); +static const char *calculate_relationship(relation_cal_t *self); + +void relation_cal_app_create(void) +{ +#ifdef CONFIG_ESP32S3_BOX_LCD + LV_FONT_DECLARE(lv_font_siyuan_10); + + g_rel_cal.fonts.siyuan = &lv_font_siyuan_10; +#else + LV_FONT_DECLARE(lv_font_siyuan_16); + + g_rel_cal.fonts.siyuan = &lv_font_siyuan_16; +#endif + + if (NULL == g_rel_cal.fonts.siyuan) + { + return; + } + + g_rel_cal.rel_count = 0; + rel_cal_main_page(); +} + +static void rel_cal_main_page(void) +{ + lv_obj_t *root = lv_obj_create(lv_scr_act()); + lv_obj_remove_style_all(root); + lv_obj_center(root); + lv_obj_set_style_bg_color(root, lv_color_white(), 0); + lv_obj_align(root, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_size(root, DEMO_WIDTH, DEMO_HEIGHT); + lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scrollbar_mode(root, LV_SCROLLBAR_MODE_OFF); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); + + g_rel_cal.ui.title = lv_label_create(root); + lv_obj_set_size(g_rel_cal.ui.title, DEMO_WIDTH, DEMO_TITLE_HEIGHT); + lv_label_set_text(g_rel_cal.ui.title, "亲属关系计算器"); + lv_obj_set_style_text_font(g_rel_cal.ui.title, g_rel_cal.fonts.siyuan, LV_PART_MAIN); + lv_obj_set_style_text_color(g_rel_cal.ui.title, lv_color_hex(0x2C3E50), 0); + lv_obj_set_style_text_align(g_rel_cal.ui.title, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_style_pad_top(g_rel_cal.ui.title, 10, 0); + lv_obj_set_style_text_color(g_rel_cal.ui.title, lv_color_hex(0xFFA500), 0); + + g_rel_cal.ui.screen = lv_textarea_create(root); + lv_obj_set_size(g_rel_cal.ui.screen, LV_PCT(100), LV_PCT(40)); + + lv_obj_set_style_text_font(g_rel_cal.ui.screen, g_rel_cal.fonts.siyuan, LV_PART_MAIN); + + lv_obj_set_style_bg_color(g_rel_cal.ui.screen, lv_color_hex(0x2C3E50), 0); + lv_obj_set_style_text_color(g_rel_cal.ui.screen, lv_color_white(), 0); + lv_obj_set_style_radius(g_rel_cal.ui.screen, 20, 0); + lv_obj_set_style_pad_all(g_rel_cal.ui.screen, 15, 0); + lv_textarea_set_cursor_click_pos(g_rel_cal.ui.screen, false); + lv_textarea_set_max_length(g_rel_cal.ui.screen, 128); + lv_textarea_set_align(g_rel_cal.ui.screen, LV_TEXT_ALIGN_LEFT); + lv_textarea_set_text(g_rel_cal.ui.screen, ""); + + g_rel_cal.ui.btnm = lv_btnmatrix_create(root); + lv_obj_set_style_border_width(g_rel_cal.ui.btnm, 0, 0); + lv_obj_set_size(g_rel_cal.ui.btnm, LV_PCT(100), LV_PCT(40)); + + lv_obj_set_style_text_font(g_rel_cal.ui.btnm, g_rel_cal.fonts.siyuan, LV_PART_MAIN); + + lv_buttonmatrix_set_map(g_rel_cal.ui.btnm, btnm_map); + lv_obj_add_event_cb(g_rel_cal.ui.btnm, rel_cal_btnmatrix_event_cb, LV_EVENT_VALUE_CHANGED, root); + lv_obj_set_style_bg_color(g_rel_cal.ui.btnm, lv_color_hex(0xECF0F1), 0); + lv_obj_set_style_radius(g_rel_cal.ui.btnm, 10, 0); + lv_obj_set_style_pad_all(g_rel_cal.ui.btnm, 10, 0); + + g_rel_cal.ui.note = lv_label_create(root); + lv_obj_set_size(g_rel_cal.ui.note, LV_PCT(100), LV_PCT(10)); + lv_label_set_text(g_rel_cal.ui.note, "这是一个亲属关系计算器。未支持关系:“未知”。"); + + lv_obj_set_style_text_font(g_rel_cal.ui.note, g_rel_cal.fonts.siyuan, LV_PART_MAIN); + + lv_obj_set_style_text_color(g_rel_cal.ui.note, lv_color_hex(0x7F8C8D), 0); + lv_obj_set_style_text_align(g_rel_cal.ui.note, LV_TEXT_ALIGN_CENTER, 0); +} + +static void rel_cal_btnmatrix_event_cb(lv_event_t *e) +{ + lv_obj_t *obj = lv_event_get_target(e); + uint8_t id = lv_buttonmatrix_get_selected_button(obj); + const char *text = lv_buttonmatrix_get_button_text(obj, id); + + rel_transform_handle(id, text); +} + +static void rel_transform_handle(const uint8_t id, const char *text) +{ + static btnm_relation_t last_input = {"?", REL_NULL, GENDER_UNKNOWN}; + + if (g_rel_cal.status == STATUS_CALCULATED) + { + g_rel_cal.status = STATUS_INPUTTING; + lv_textarea_set_text(g_rel_cal.ui.screen, ""); + } + + switch (id) + { + case CALCULATED: + if (g_rel_cal.rel_count > 0) + { + const char *result = calculate_relationship(&g_rel_cal); + lv_textarea_set_text(g_rel_cal.ui.screen, result); + g_rel_cal.rel_count = 0; + } + else + { + lv_textarea_set_text(g_rel_cal.ui.screen, "自己"); + g_rel_cal.rel_count = 0; + } + g_rel_cal.status = STATUS_CALCULATED; + last_input.relation = REL_NULL; + last_input.gender = GENDER_UNKNOWN; + + break; + + case CLEAR: + lv_textarea_set_text(g_rel_cal.ui.screen, ""); + g_rel_cal.rel_count = 0; + + last_input.relation = REL_NULL; + last_input.gender = GENDER_UNKNOWN; + break; + + case DELETE: + if (g_rel_cal.rel_count) + { + g_rel_cal.rel_count--; + lv_textarea_delete_char(g_rel_cal.ui.screen); + lv_textarea_delete_char(g_rel_cal.ui.screen); + lv_textarea_delete_char(g_rel_cal.ui.screen); + } + break; + + case MY_NULL: + break; + + default: + for (int i = 0; i < sizeof(btnm_relation) / sizeof(btnm_relation[0]); i++) + { + if (0 == strcmp(text, btnm_relation[i].btnm_text)) + { + if ((GENDER_FEMALE == last_input.gender && + REL_WIFE == btnm_relation[i].relation) || + (GENDER_MALE == last_input.gender && + REL_HUSBAND == btnm_relation[i].relation)) + { + return; + } + if (g_rel_cal.rel_count < MAX_REL_LEN) + { + g_rel_cal.rel_list[g_rel_cal.rel_count++] = btnm_relation[i].relation; + } + + last_input = btnm_relation[i]; + break; + } + } + + if (g_rel_cal.rel_count == 1) + { + lv_textarea_add_text(g_rel_cal.ui.screen, text); + } + else if (g_rel_cal.rel_count > 1) + { + lv_textarea_add_text(g_rel_cal.ui.screen, "的"); + lv_textarea_add_text(g_rel_cal.ui.screen, text); + } + + break; + } +} + +static const char *calculate_relationship(relation_cal_t *self) +{ + relation_type_t current = REL_SELF; + for (int i = 0; i < self->rel_count; i++) + { + int found = 0; + for (int j = 0; transitions[j].from != REL_NULL; j++) + { + if (transitions[j].from == current && transitions[j].to == self->rel_list[i]) + { + current = transitions[j].result; + found = 1; + break; + } + } + if (!found) + { + current = REL_NULL; + break; + } + } + + return relation_names[current]; +} diff --git a/relation_calculator/relation_cal.h b/relation_calculator/relation_cal.h new file mode 100644 index 0000000000000000000000000000000000000000..198da955a844e2ef198a82b076a4c9ffb8b4e3a5 --- /dev/null +++ b/relation_calculator/relation_cal.h @@ -0,0 +1,135 @@ +#ifndef __RELATION_CAL_H__ +#define __RELATION_CAL_H__ + +/********************* + * INCLUDES + *********************/ +#include <lvgl/lvgl.h> + +#define MAX_REL_LEN 256 + +#define FATHER 0 +#define HUSBAND 1 +#define SON 2 +#define ELDER_BRO 3 +#define ELDER_SIS 4 +#define DELETE 5 +#define CLEAR 6 +#define MOTHER 7 +#define WIFI 8 +#define DAUGHTER 9 +#define YOUNGER_BRO 10 +#define YOUNGER_SIS 11 +#define MY_NULL 12 +#define CALCULATED 13 + +#define REL_CAL_RES_ROOT CONFIG_LVX_REL_CAL_DATA_ROOT "/res" +#define REL_CAL_FONTS_ROOT REL_CAL_RES_ROOT "/fonts" + +typedef enum relation_cal_status_e +{ + STATUS_INIT, + STATUS_INPUTTING, + STATUS_CALCULATED, + STATUS_XXX +} relation_cal_status_t; + +typedef enum gender_e +{ + GENDER_MALE, + GENDER_FEMALE, + GENDER_UNKNOWN +} gender_t; + +typedef enum relation_type_e +{ + REL_SELF, // Self + REL_FATHER, // Father + REL_MOTHER, // Mother + REL_SON, // Son + REL_DAUGHTER, // Daughter + REL_WIFE, // Wife + REL_HUSBAND, // Husband + REL_ELDER_BROTHER, // Elder brother + REL_YOUNGER_BROTHER, // Younger brother + REL_ELDER_SISTER, // Elder sister + REL_YOUNGER_SISTER, // Younger sister + REL_GRANDFATHER, // Paternal grandfather + REL_GRANDMOTHER, // Paternal grandmother + REL_UNCLE, // Uncle (father's elder brother) + REL_AUNT, // Aunt (father's sister) + REL_COUSIN_MALE, // Paternal male cousin + REL_COUSIN_FEMALE, // Paternal female cousin + REL_GREAT_GRANDFATHER, // Paternal great - grandfather + REL_GREAT_GRANDMOTHER, // Paternal great - grandmother + REL_MATERNAL_GRANDFATHER, // Maternal grandfather + REL_MATERNAL_GRANDMOTHER, // Maternal grandmother + REL_MATERNAL_GREAT_GRANDFATHER, // Maternal great - grandfather + REL_MATERNAL_GREAT_GRANDMOTHER, // Maternal great - grandmother + REL_FIRST_COUSIN_ONCE_REMOVED_MALE, // First cousin once removed (male) + REL_FIRST_COUSIN_ONCE_REMOVED_FEMALE, // First cousin once removed (female) + REL_SECOND_COUSIN_MALE, // Second male cousin + REL_SECOND_COUSIN_FEMALE, // Second female cousin + REL_GREAT_UNCLE, // Granduncle (grandfather's younger brother) + REL_GREAT_AUNT, // Grandaunt (grandfather's sister) + REL_MATERNAL_UNCLE, // Maternal uncle (mother's brother) + REL_MATERNAL_AUNT, // Maternal aunt (mother's sister) + REL_NEPHEW, // Nephew + REL_NIECE, // Niece + REL_SON_IN_LAW, // Son - in - law + REL_DAUGHTER_IN_LAW, // Daughter - in - law + REL_GRANDSON, // Grandson + REL_GRANDDAUGHTER, // Granddaughter + REL_GREAT_GRANDSON, // Great - grandson + REL_GREAT_GRANDDAUGHTER, // Great - granddaughter + REL_COUSIN_SON, // Cousin's son + REL_COUSIN_DAUGHTER, // Cousin's daughter + REL_GRAND_NEPHEW, // Grand - nephew (brother's grandson) + REL_GRAND_NIECE, // Grand - niece (brother's granddaughter) + REL_NULL // Unknown +} relation_type_t; + +typedef struct btnm_relation_s +{ + const char *btnm_text; + relation_type_t relation; + gender_t gender; +} btnm_relation_t; + +typedef struct relation_call_s +{ + const char *call; + relation_type_t relation; +} relation_call_t; + +typedef struct relation_cal_s +{ + struct + { + lv_obj_t *title; + lv_obj_t *note; + lv_obj_t *btnm; + lv_obj_t *screen; + } ui; + + struct + { + const lv_font_t *siyuan; + } fonts; + + relation_type_t rel_list[MAX_REL_LEN]; + int rel_count; + relation_cal_status_t status; + +} relation_cal_t; + +typedef struct relation_transformation_s +{ + relation_type_t from; + relation_type_t to; + relation_type_t result; +} relation_transformation_t; + +void relation_cal_app_create(void); + +#endif /* __RELATION_CAL_H__ */ diff --git a/relation_calculator/relation_cal_main.c b/relation_calculator/relation_cal_main.c new file mode 100644 index 0000000000000000000000000000000000000000..d785930bcfebcf5245c40e49230f90fb61c54a0b --- /dev/null +++ b/relation_calculator/relation_cal_main.c @@ -0,0 +1,93 @@ +// include NuttX headers +#include <nuttx/config.h> +#include <unistd.h> + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +#include <uv.h> +#endif + +// include lvgl headers +#include <lvgl/lvgl.h> + +#include "relation_cal.h" + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + +static void lv_nuttx_uv_loop(uv_loop_t *loop, lv_nuttx_result_t *result) +{ + lv_nuttx_uv_t uv_info; + void *data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +#endif + +int main(int argc, FAR char *argv[]) +{ + // init lvgl + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); +#endif + + if (lv_is_initialized()) + { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + lv_nuttx_dsc_init(&info); + +#ifdef CONFIG_LV_USE_NUTTX_LCD + info.fb_path = "/dev/lcd0"; +#endif + + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) + { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + relation_cal_app_create(); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + // refresh lvgl ui + lv_nuttx_uv_loop(&ui_loop, &result); +#endif + + while (1) + { + uint32_t idle; + idle = lv_timer_handler(); + + /* Minimum sleep of 1ms */ + + idle = idle ? idle : 1; + usleep(idle * 1000); + } + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/smart_home/Kconfig b/smart_home/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..dd1f344c62afa43527feb3dc22fb28ce6518bd8f --- /dev/null +++ b/smart_home/Kconfig @@ -0,0 +1,55 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig LVX_USE_DEMO_SMART_HOME + tristate "Smart Home Demo" + default n + depends on GRAPHICS_LVGL && LIB_PNG && LV_USE_LIBPNG + ---help--- + Enable build the LVGL Smart Home Demo application + +if LVX_USE_DEMO_SMART_HOME + +config LVX_SMART_HOME_DATA_ROOT + string "Smart Home Data Root" + default "/data" + ---help--- + Path to smart home assets and fonts data + +config LVX_USE_DEMO_SMART_HOME_PRIORITY + int "Smart Home task priority" + default 100 + +config LVX_USE_DEMO_SMART_HOME_STACKSIZE + int "Smart Home stack size" + default 40960 + ---help--- + Larger stack size required for smart home graphics + +config LVX_USE_DEMO_SMART_HOME_DEVPATH + string "Touchscreen device path" + default "/dev/input0" + depends on INPUT_TOUCHSCREEN + ---help--- + The path to the touchscreen device. Default: "/dev/input0" + +config LVX_USE_DEMO_SMART_HOME_MEM_SIZE + int "LVGL memory size for smart home demo" + default 81920 + depends on GRAPHICS_LVGL + ---help--- + Increased memory size for smart home assets + +config LV_NUTTX_DSC_DEFAULT_WIDTH + int "Default display width for smart home demo" + default 800 + depends on LVX_USE_DEMO_SMART_HOME + +config LV_NUTTX_DSC_DEFAULT_HEIGHT + int "Default display height for smart home demo" + default 400 + depends on LVX_USE_DEMO_SMART_HOME + +endif # LVX_USE_DEMO_SMART_HOME \ No newline at end of file diff --git a/smart_home/Make.defs b/smart_home/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..2c092ce612cb53c83190dd7a7b529d0b4464f8c9 --- /dev/null +++ b/smart_home/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# packages/demos/smart_home/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ +# Smart Home Demo +ifneq ($(CONFIG_LVX_USE_DEMO_SMART_HOME),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/smart_home +endif diff --git a/smart_home/Makefile b/smart_home/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..bd0c114783867bab49644d8d4b995aeb302db67b --- /dev/null +++ b/smart_home/Makefile @@ -0,0 +1,62 @@ +############################################################################ +# packages/demos/smart_home/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_SMART_HOME), y) +PROGNAME = smart_home +PRIORITY = $(CONFIG_LVX_USE_DEMO_SMART_HOME_PRIORITY) +STACKSIZE = $(CONFIG_LVX_USE_DEMO_SMART_HOME_STACKSIZE) + +# Common source files for smart home demo +MODULE = $(CONFIG_LVX_USE_DEMO_SMART_HOME) +CSRCS = smart_home_main.c \ + lv_demo_smart_home.c \ + lv_demo_smart_home_home.c \ + lv_demo_smart_home_util.c \ + lv_demo_smart_home_top_margin.c \ + lv_demo_smart_home_app_about.c \ + lv_demo_smart_home_app_ev_charging.c \ + lv_demo_smart_home_app_smart_home.c \ + lv_demo_smart_home_app_smart_meter.c \ + lv_demo_smart_home_app_thermostat.c \ + lv_demo_smart_home_api_example.c \ + lv_demo_panel_display_control.c \ + +CFLAGS += -DLV_FS_STDIO_LETTER='A' -DLV_FONT_FMT_TXT_LARGE=1 +CFLAGS += -Wno-address -Wno-array-parameter \ + -Wno-builtin-declaration-mismatch \ + -Wno-incompatible-pointer-types \ + -Wno-implicit-function-declaration -Wno-shadow \ + -Wno-stringop-overflow -Wno-unused-variable \ + -Wno-unused-but-set-variable \ + -Wno-discarded-qualifiers \ + -Wno-unused-function +MAINSRC = smart_home_main.c + +include $(APPDIR)/Application.mk + +else + +$(error "LVX_USE_DEMO_SMART_HOME is not set in the configuration") + +endif + +# End of packages/demos/smart_home/Makefile \ No newline at end of file diff --git a/smart_home/Readme.md b/smart_home/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..9820f871666ce1cc6b5daef2c7c22ae6640778de --- /dev/null +++ b/smart_home/Readme.md @@ -0,0 +1,145 @@ +# Smart hub - 基于 openvela + +## 概要 +这是一个基于 openvela 平台,使用 LVGL (Light and Versatile Graphics Library) 9.1.0 版本开发的高分辨率智能家居界面演示程序。该演示可以在模拟器上运行,展示了现代化的智能家居控制界面设计。 + +## 功能特点 +- 主界面功能 + - 日期时间显示 - 实时显示当前日期、星期和时间 +- 应用卡片 - 网格布局的应用入口 +- 主题切换 - 支持亮色和暗色主题切换 +- 内置应用 + - EV Charging - 电动车充电管理 + - Smart Home - 智能家居控制 + - Smart Meter - 智能电表监控 +- 关于信息 + +## 系统架构 +- 基于 LVGL 图形库 +- 基于 openvela 平台 + +## 界面特色 +- 高分辨率适配设计 + +- 响应式布局 + +- 现代化的卡片式设计 + +- 平滑的主题切换 + +- 统一的视觉风格 + +## 技术架构 +- 核心组件 + - LVGL 图形库 - 轻量级嵌入式图形库 + - openvela 平台 - 运行环境支持 +- 模拟器兼容 - 可在桌面环境进行开发和测试 + +## 代码结构 +``` +├── packages +│ └── demos +│ └── smart_home +│ ├── smart_home_main.c +│ ├── Kconfig +│ ├── lv_demo_smart_home_api_example.c +│ ├── lv_demo_smart_home_app_about.c +│ ├── lv_demo_smart_home_app_ev_charging.c +│ ├── lv_demo_smart_home_app_smart_home.c +│ ├── lv_demo_smart_home_app_smart_meter.c +│ ├── lv_demo_smart_home_app_thermostat.c +│ ├── lv_demo_smart_home.c +│ ├── lv_demo_smart_home.h +│ ├── lv_demo_smart_home_home.c +│ ├── lv_demo_smart_home_private.h +│ ├── lv_demo_smart_home_top_margin.c +│ ├── lv_demo_smart_home_util.c +│ ├── lv_demo_panel_display_control.c +│ ├── lv_demo_panel_display_control.h +│ ├── Make.defs +│ ├── Makefile +│ ├── Readme.md +│ └── res +│ ├── fonts +│ │ ├── MiSans-Normal.ttf +│ │ └── MiSans-Semibold.ttf +│ └── icons + +``` +## 三、使用说明 +前提条件: +已搭建openvela开发环境(参考:[环境搭建](https://gitee.com/open-vela/docs/blob/dev/zh-cn/quickstart/Set_up_the_development_environment_zh-cn.md)) +已获取openvela源码(参考:[下载openvela源码](https://gitee.com/open-vela/docs/blob/dev/zh-cn/quickstart/Download_Vela_sources_zh-cn.md)) +首先进入模拟器配置 +### 1.配置模拟器(menuconfig) +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig +``` +#### (1)编译设置 +- 配置GRAPHICS_LVGL 为 yes +- 配置LIB_PNG 为 yes +- 配置LV_USE_LIBPNG 为 yes +- 配置LVX_USE_DEMO_SMART_HOME 为 yes +- LVX_SMART_HOME_DATA_ROOT的路径设置为/data (Kconfig文件默认预设为 /data) + +### 2.资源推送更新 /res +需要在模拟器运行状况下,使用ADB指令更新资源推送,才能显示更换的新图片和字体。 +- 启动模拟器 +```bash +./emulator.sh vela +``` +- ADB推送更新资源(在模拟器运行状况下,终端使用) +```bash +adb push packages/demos/smart_home/res /data/ +``` +- 之后启动计算器应用即可 +```bash +smart_home & +``` + + +## 📁工程路径 +packages/demos/smart_home/ + +--- + +## 🛠️常用指令 + +### 开始构建 + +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j$(nproc) +``` +### 配置模拟器(menuconfig) +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig +``` + +### ADB推送更新资源(在模拟器运行状况下) +```bash +adb push packages/demos/smart_home/res /data/ +``` + +### 清理构建产物 +```bash +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j$(nproc) +``` +### 启动模拟器 +```bash +./emulator.sh vela +``` + +### 启动计算器应用 +```bash +smart_home & +``` +--- + + + + + + + + + diff --git a/smart_home/lv_demo_panel_display_control.c b/smart_home/lv_demo_panel_display_control.c new file mode 100644 index 0000000000000000000000000000000000000000..bd75b7e7207892d165a4265ff19c9d6f5f249c74 --- /dev/null +++ b/smart_home/lv_demo_panel_display_control.c @@ -0,0 +1,156 @@ +#include <nuttx/config.h> +#include <uORB/uORB.h> +#include <poll.h> +#include "lv_demo_panel_display_control.h" +#include <sensor/humi.h> +#include <sensor/temp.h> +#include <sensor/tvoc.h> +#include <sensor/co2.h> +#include <syslog.h> + +#define LV_DEMO_POLLFD_NUM 4 + +typedef struct { + int temperature_sub; + int humidity_sub; + int formaldehyde_sub; + int co2_sub; + struct pollfd fds[LV_DEMO_POLLFD_NUM]; + bool initialized; +} sensor_subscriber; + +static sensor_subscriber sensor_sub = { + .temperature_sub = -1, + .humidity_sub = -1, + .formaldehyde_sub = -1, + .co2_sub = -1, + .initialized = false +}; + +// 初始化 uORB 订阅 +int lv_demo_init_sensor_subscriptions(void) { + // 订阅温度数据 + sensor_sub.temperature_sub = orb_subscribe_multi(ORB_ID(sensor_temp),0); + if (sensor_sub.temperature_sub < 0) { + + syslog(LOG_INFO, " Failed to subscribe to temperature topic\n"); + return -1; + } + + // 订阅湿度数据 + sensor_sub.humidity_sub = orb_subscribe_multi(ORB_ID(sensor_humi),0); + if (sensor_sub.humidity_sub < 0) { + syslog(LOG_INFO,"Failed to subscribe to humidity topic\n"); + return -1; + } + + // // 订阅甲醛数据 + sensor_sub.formaldehyde_sub = orb_subscribe(ORB_ID(sensor_tvoc)); + if (sensor_sub.formaldehyde_sub < 0) { + printf("Failed to subscribe to formaldehyde topic\n"); + return -1; + } + + // // 订阅 + sensor_sub.co2_sub = orb_subscribe(ORB_ID(sensor_co2)); + if (sensor_sub.co2_sub < 0) { + printf("Failed to subscribe to co2_sub topic\n"); + return -1; + } + + // 设置 poll 文件描述符 + sensor_sub.fds[0].fd = sensor_sub.temperature_sub; + sensor_sub.fds[0].events = POLLIN; + + sensor_sub.fds[1].fd = sensor_sub.humidity_sub; + sensor_sub.fds[1].events = POLLIN; + + sensor_sub.fds[2].fd = sensor_sub.formaldehyde_sub; + sensor_sub.fds[2].events = POLLIN; + + sensor_sub.fds[3].fd = sensor_sub.co2_sub; + sensor_sub.fds[3].events = POLLIN; + + sensor_sub.initialized = true; + return 0; +} + +// 检查并更新传感器数据 +int lv_demo_update_sensor_data(lv_demo_sensor_select_t sensors_to_update,lv_demo_smart_home_ctx_t *c) { + if(c == NULL) { + return -1; + } + + lv_demo_smart_home_api_t *api = &c->api; + + if (!sensor_sub.initialized) { + return -1; + } + + int ret = poll(sensor_sub.fds, LV_DEMO_POLLFD_NUM, 0); // 非阻塞检查 + if (ret <= 0) { + syslog(LOG_INFO,"Failed to read sensor data"); + return 0; // 没有新数据 + } + + int updated = 0; + + // // 检查温度数据更新 + if (sensors_to_update & LV_DEMO_UPDATE_TEMPERATURE && sensor_sub.fds[0].revents & POLLIN) { + struct sensor_temp temp_data; + if (orb_copy(ORB_ID(sensor_temp), sensor_sub.temperature_sub, &temp_data) == OK) { + lv_subject_set_int( &api->subjects.temperature_indoor, temp_data.temperature * 10); + updated++; + } + } + + // 检查湿度数据更新 + if ( sensors_to_update & LV_DEMO_UPDATE_HUMIDITY && sensor_sub.fds[1].revents & POLLIN) { + struct sensor_humi humi_data; + if (orb_copy(ORB_ID(sensor_humi), sensor_sub.humidity_sub, &humi_data) == OK) { + lv_subject_set_int( &api->subjects.temperature_outdoor, humi_data.humidity * 10); + + updated++; + } + } + + // // 检查甲醛数据更新 + if (sensors_to_update & LV_DEMO_UPDATE_FORMALDEHYDE && sensor_sub.fds[2].revents & POLLIN) { + struct sensor_tvoc formal_data; + if (orb_copy(ORB_ID(sensor_tvoc), sensor_sub.formaldehyde_sub, &formal_data) == OK) { + syslog(LOG_INFO,"sensor_tvoc %.1f",formal_data.tvoc); + lv_subject_set_int( &c->ev_charging_progress, (int32_t)(formal_data.tvoc*10)); + updated++; + } + } + + if(sensor_sub.fds[3].revents & POLLIN) { + struct sensor_co2 co2_data; + if (orb_copy(ORB_ID(sensor_co2), sensor_sub.co2_sub, &co2_data) == OK) { + syslog(LOG_INFO,"co2_valuer %d",(int)co2_data.co2); + lv_subject_set_int( &c->co2_value, (int)co2_data.co2); + updated++; + } + } + + return updated; +} + +// 清理订阅 +void lv_demo_cleanup_sensor_subscriptions(void) { + if (sensor_sub.temperature_sub >= 0) { + orb_unsubscribe(sensor_sub.temperature_sub); + } + if (sensor_sub.humidity_sub >= 0) { + orb_unsubscribe(sensor_sub.humidity_sub); + } + if (sensor_sub.formaldehyde_sub >= 0) { + orb_unsubscribe(sensor_sub.formaldehyde_sub); + } + if (sensor_sub.co2_sub >= 0) { + orb_unsubscribe(sensor_sub.co2_sub); + } + + sensor_sub.initialized = false; +} + diff --git a/smart_home/lv_demo_panel_display_control.h b/smart_home/lv_demo_panel_display_control.h new file mode 100644 index 0000000000000000000000000000000000000000..386275f14aed053ddeea4de15c109284fc20f21d --- /dev/null +++ b/smart_home/lv_demo_panel_display_control.h @@ -0,0 +1,20 @@ +#ifndef LV_DEMO_PANEL_DISPLAY_CONTROL_H +#define LV_DEMO_PANEL_DISPLAY_CONTROL_H + +#include <stdint.h> +#include <stdio.h> +#include <time.h> +#include <uORB/uORB.h> +#include "lv_demo_smart_home_private.h" + +typedef enum { + LV_DEMO_UPDATE_TEMPERATURE = 0x01, + LV_DEMO_UPDATE_HUMIDITY = 0x02, + LV_DEMO_UPDATE_FORMALDEHYDE= 0x04, + LV_DEMO_UPDATE_ALL = 0x07 // 所有传感器的位或 +} lv_demo_sensor_select_t; + +extern int lv_demo_init_sensor_subscriptions(void); +extern void lv_demo_cleanup_sensor_subscriptions(void); +extern int lv_demo_update_sensor_data(lv_demo_sensor_select_t sensors_to_update,lv_demo_smart_home_ctx_t *c); +#endif /* PANEL_DISPLAY_CONTROL_H */ \ No newline at end of file diff --git a/smart_home/lv_demo_smart_home.c b/smart_home/lv_demo_smart_home.c new file mode 100644 index 0000000000000000000000000000000000000000..f01af085f29b039acd59369146550628f4c17ae4 --- /dev/null +++ b/smart_home/lv_demo_smart_home.c @@ -0,0 +1,45 @@ +/** + * @file lv_demo_smart_home.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_smart_home_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_demo_smart_home_api_t * lv_demo_smart_home(const char * assets_path, + const char * logo_path, + const char * slides_path, + lv_demo_smart_home_exit_cb_t exit_cb) +{ + if(assets_path == NULL) assets_path = "packages/demos/smart_home/assets"; + if(logo_path == NULL) logo_path = "packages/demos/smart_home/assets/img_lv_demo_smart_home_lvgl_logo.png"; + if(slides_path == NULL) slides_path = "about_app_slides"; + lv_obj_t * base_obj = lv_demo_smart_home_base_obj_create(assets_path, logo_path, slides_path, exit_cb); + lv_demo_smart_home_home(base_obj); + + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + return &c->api; +} diff --git a/smart_home/lv_demo_smart_home.h b/smart_home/lv_demo_smart_home.h new file mode 100644 index 0000000000000000000000000000000000000000..508ef4386db63455a31d2bc186e77d1c00345846 --- /dev/null +++ b/smart_home/lv_demo_smart_home.h @@ -0,0 +1,174 @@ +/** + * @file lv_demo_smart_home.h + * + */ + +#ifndef LV_DEMO_SMART_HOME_H +#define LV_DEMO_SMART_HOME_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl.h" + +/********************* + * DEFINES + *********************/ +#define LV_USE_DEMO_SMART_HOME 1 +#if LV_USE_DEMO_SMART_HOME + +/* Default asset paths for NuttX */ +#ifndef CONFIG_LVX_SMART_HOME_DATA_ROOT +# define CONFIG_LVX_SMART_HOME_DATA_ROOT "/data" +# define CONFIG_LVX_SMART_HOME_ICONS_PATH CONFIG_LVX_SMART_HOME_DATA_ROOT "/res/icons" +# define CONFIG_LVX_SMART_HOME_FONTS_PATH CONFIG_LVX_SMART_HOME_DATA_ROOT "/res/fonts" +#else +# define CONFIG_LVX_SMART_HOME_ICONS_PATH CONFIG_LVX_SMART_HOME_DATA_ROOT "/res/icons" +# define CONFIG_LVX_SMART_HOME_FONTS_PATH CONFIG_LVX_SMART_HOME_DATA_ROOT "/res/fonts" +#endif + +#ifndef CONFIG_LVX_SMART_HOME_LOGO_PATH +# define CONFIG_LVX_SMART_HOME_LOGO_PATH CONFIG_LVX_SMART_HOME_ICONS_PATH "img_lv_demo_smart_home_lvgl_logo.png" +#endif + +#ifndef CONFIG_LVX_SMART_HOME_SLIDES_PATH +# define CONFIG_LVX_SMART_HOME_SLIDES_PATH CONFIG_LVX_SMART_HOME_ICONS_PATH +#endif + +#define LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH CONFIG_LVX_SMART_HOME_FONTS_PATH "/MiSans-Normal.ttf" +#define LV_DEMO_SMART_HOME_MISANS_BOLD_PATH CONFIG_LVX_SMART_HOME_FONTS_PATH "/MiSans-Semibold.ttf" +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + struct { + /* input subjects */ + /* int: the hour shown on clocks, e.g. 9 */ + lv_subject_t hour; + /* int: the minute shown on clocks, e.g. 36 */ + lv_subject_t minute; + /* pointer: day of the week string, e.g. "Tuesday" */ + lv_subject_t week_day_name; + /* int: the day of the month, e.g. 31 */ + lv_subject_t month_day; + /* pointer: the month string, e.g. "October" */ + lv_subject_t month_name; + /* int: tenths of a degree C, e.g. 140 (for 14.0 degrees celsius) */ + lv_subject_t temperature_outdoor; + /* int: tenths of a degree C, e.g. 225 (for 22.5 degrees celsius) */ + lv_subject_t temperature_indoor; + /* pointer: wifi network name string, e.g. "my home Wi-Fi network" (or `NULL` for offline) */ + lv_subject_t wifi_ssid; + /* pointer: wifi local IP address string, e.g. "192.168.1.1" (or `NULL` for offline) */ + lv_subject_t wifi_ip; + /* int: boolean 0 for door closed, 1 for door open */ + lv_subject_t door; + + /* output subjects */ + /* int: boolean 0 for music paused, 1 for music playing */ + lv_subject_t music_play; + /* pointer: wifi network password, the UI sets it right before it sets `wifi_ssid` */ + lv_subject_t wifi_password; + + /* input+output subjects */ + /* int: boolean 0 for not locked, 1 for locked. When it is 1, you can set it back to 0 */ + lv_subject_t locked; + /* int: a value 0-100 of the smart home volume slider */ + lv_subject_t volume; + /* int: a value 0-20000 of the smart home light "temperature" slider in Kelvin */ + lv_subject_t main_light_temperature; + /* int: a value 0-100 of the smart home light intensity slider */ + lv_subject_t main_light_intensity; + /* int: boolean 0 for off, 1 for on of the Matter lightbulb */ + lv_subject_t lightbulb_matter; + /* int: boolean 0 for off, 1 for on of the Zigbee lightbulb */ + lv_subject_t lightbulb_zigbee; + /* int: a value 0-3 of the smart home Matter fan slider */ + lv_subject_t fan_matter; + /* int: boolean 0 for off, 1 for on of the Zigbee fan */ + lv_subject_t fan_zigbee; + /* int: a value 0-3 of the smart home air purifier slider */ + lv_subject_t air_purifier; + /* int: a value 0-100 of the thermostat fan speed slider */ + lv_subject_t thermostat_fan_speed; + /* int: a value 150-300 in tenths of a degree C, e.g. 225 (for 22.5 degrees celsius) */ + lv_subject_t thermostat_target_temperature; + } subjects; + + /* the object that is created on the active screen which contains the demo contents. + * Can be deleted to close the demo. + */ + lv_obj_t * base_obj; + void * user_data; /* optional extra data field for the user to use freely */ +} lv_demo_smart_home_api_t; + +typedef void (*lv_demo_smart_home_exit_cb_t)(lv_demo_smart_home_api_t * api); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Start the Smart Home Demo on the default display, on the active screen. + * This demo requires `LV_USE_DEMO_SMART_HOME` and `LV_FONT_FMT_TXT_LARGE` + * to be enabled as well as a filesystem driver to be configured and the + * `LV_FS_DEFAULT_DRIVER_LETTER` set. The display size should be + * 800x480, 1280x720, or 1920x1080. + * @param assets_path Folder where the image assets are. + * If `NULL`, "lvgl/demos/smart_home/assets" will be used. + * @param logo_path A path to a logo to display in the bottom-left + * of the home screen. If `NULL`, an LVGL logo is used. + * @param slides_path Folder where the "About" app slideshow slides are. + * If `NULL`, "about_app_slides" will be used. + * The images should be named like Slide1.png, Slide2.png, etc. + * They will be scaled to nine sixteenths the height of the + * display. I.e., a slide will not be scaled if it is + * 405 px high and the display is 720 px high. + * @param exit_cb A callback function which will be called when the + * "logout" button is clicked, or `NULL` to do nothing. + * @return A struct with subjects to control the UI + * and react to input. + */ +lv_demo_smart_home_api_t * lv_demo_smart_home(const char * assets_path, + const char * logo_path, + const char * slides_path, + lv_demo_smart_home_exit_cb_t exit_cb); + +/** + * This function demonstrates how the demo's API can be used. + * Start the Smart Home Demo on the default display, on the active screen. + * This demo requires `LV_USE_DEMO_SMART_HOME` and `LV_FONT_FMT_TXT_LARGE` + * to be enabled as well as a filesystem driver to be configured and the + * `LV_FS_DEFAULT_DRIVER_LETTER` set. The display size should be + * 800x480, 1280x720, or 1920x1080. + * @param assets_path Folder where the image assets are. + * If `NULL`, "lvgl/demos/smart_home/assets" will be used. + * @param logo_path A path to a logo to display in the bottom-left + * of the home screen. If `NULL`, an LVGL logo is used. + * @param slides_path Folder where the "About" app slideshow slides are. + * If `NULL`, "about_app_slides" will be used. + * The images should be named like Slide1.png, Slide2.png, etc. + * They will be scaled to nine sixteenths the height of the + * display. I.e., a slide will not be scaled if it is + * 405 px high and the display is 720 px high. + */ +void lv_demo_smart_home_api_example(const char * assets_path, const char * logo_path, const char * slides_path); + + + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DEMO_SMART_HOME*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DEMO_SMART_HOME_H*/ diff --git a/smart_home/lv_demo_smart_home_api_example.c b/smart_home/lv_demo_smart_home_api_example.c new file mode 100644 index 0000000000000000000000000000000000000000..a38714e4a9bb8e41f5d73dd3be343b52d4f68ca1 --- /dev/null +++ b/smart_home/lv_demo_smart_home_api_example.c @@ -0,0 +1,209 @@ +/** + * @file lv_demo_smart_home_api_example.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_smart_home.h" +#include "lv_demo_panel_display_control.h" +#if LV_USE_DEMO_SMART_HOME + +/* see `wifi_ssid_observer_cb` */ +#if 0 + #include <stdlib.h> +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void exit_cb(lv_demo_smart_home_api_t * api); +static void output_subject_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void locked_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void locked_timer_cb(lv_timer_t * t); +static void delete_timer_cb(lv_event_t * e); +static void clock_timer_cb(lv_timer_t * t); +static void door_timer_cb(lv_timer_t * t); +static void wifi_ssid_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void sensor_timer_update_cb(lv_timer_t* timer); +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_smart_home_api_example(const char * assets_path, const char * logo_path, const char * slides_path) +{ + lv_demo_smart_home_api_t * api = lv_demo_smart_home(assets_path, logo_path, slides_path, exit_cb); + lv_demo_init_sensor_subscriptions();//订阅传感器数据 + /* see lv_demo_smart_home.h for documentation of the available subjects */ + lv_subject_set_int(&api->subjects.volume, 50); + lv_subject_set_pointer(&api->subjects.month_name, "August"); + lv_subject_set_int(&api->subjects.month_day, 1); + lv_subject_set_pointer(&api->subjects.week_day_name, "Wednesday"); + lv_subject_set_int(&api->subjects.temperature_outdoor, 16 * 10); /* 16 degrees C */ + lv_subject_set_int(&api->subjects.main_light_temperature, 50); /* 4500 degrees K */ + lv_subject_set_int(&api->subjects.thermostat_target_temperature, 25 * 10); /* 25 degrees C */ + lv_subject_set_int(&api->subjects.door, 0); /* tell the UI the door is closed */ + lv_subject_set_int(&api->subjects.lightbulb_matter, 0); /* 0 or 1 */ + lv_subject_set_int(&api->subjects.lightbulb_zigbee, 1); /* 0 or 1 */ + lv_subject_set_int(&api->subjects.fan_matter, 0); /* 0-3 */ + lv_subject_set_int(&api->subjects.fan_zigbee, 0); /* 0 or 1*/ + lv_subject_set_int(&api->subjects.air_purifier, 3); /* 0-3 */ + + lv_subject_add_observer(&api->subjects.music_play, output_subject_observer_cb, (void *)"music_play"); + lv_subject_add_observer(&api->subjects.locked, output_subject_observer_cb, (void *)"locked"); + lv_subject_add_observer(&api->subjects.volume, output_subject_observer_cb, (void *)"volume"); + lv_subject_add_observer(&api->subjects.main_light_temperature, output_subject_observer_cb, + (void *)"main_light_temperature"); + lv_subject_add_observer(&api->subjects.main_light_intensity, output_subject_observer_cb, + (void *)"main_light_intensity"); + lv_subject_add_observer(&api->subjects.thermostat_fan_speed, output_subject_observer_cb, + (void *)"thermostat_fan_speed"); + lv_subject_add_observer(&api->subjects.thermostat_target_temperature, output_subject_observer_cb, + (void *)"thermostat_target_temperature"); + lv_subject_add_observer(&api->subjects.door, output_subject_observer_cb, (void *)"door"); + lv_subject_add_observer(&api->subjects.lightbulb_matter, output_subject_observer_cb, (void *)"Matter lightbulb"); + lv_subject_add_observer(&api->subjects.lightbulb_zigbee, output_subject_observer_cb, (void *)"Zigbee lightbulb"); + lv_subject_add_observer(&api->subjects.fan_matter, output_subject_observer_cb, (void *)"Matter fan"); + lv_subject_add_observer(&api->subjects.fan_zigbee, output_subject_observer_cb, (void *)"Zigbee fan"); + lv_subject_add_observer(&api->subjects.air_purifier, output_subject_observer_cb, (void *)"air purifier"); + + /* unlock after being locked for 3 seconds */ + lv_timer_t * locked_timer = lv_timer_create_basic(); + lv_obj_add_event_cb(api->base_obj, delete_timer_cb, LV_EVENT_DELETE, locked_timer); + lv_subject_add_observer(&api->subjects.locked, locked_observer_cb, locked_timer); + + /* slowly increment the time */ + lv_timer_t * clock_timer = lv_timer_create(clock_timer_cb, 10000, api); + lv_obj_add_event_cb(api->base_obj, delete_timer_cb, LV_EVENT_DELETE, clock_timer); + + /* simulate the door opening and closing */ + lv_timer_t * door_timer = lv_timer_create(door_timer_cb, 3000, api); + lv_obj_add_event_cb(api->base_obj, delete_timer_cb, LV_EVENT_DELETE, door_timer); + + lv_subject_add_observer(&api->subjects.wifi_ssid, wifi_ssid_observer_cb, api); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void sensor_timer_update_cb(lv_timer_t* timer) +{ + LV_UNUSED(timer); + + lv_demo_smart_home_api_t * api = lv_timer_get_user_data(timer); + + lv_demo_update_sensor_data(LV_DEMO_UPDATE_ALL, api); +} + +static void exit_cb(lv_demo_smart_home_api_t * api) +{ + lv_obj_delete(api->base_obj); +} + +static void output_subject_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + const char * subject_name = (const char *)observer->user_data; + LV_LOG_USER("%s output subject value: %"PRId32, subject_name, lv_subject_get_int(subject)); +} + +static void locked_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + if(lv_subject_get_int(subject)) { + /* unlock after being locked for 3 seconds */ + lv_timer_t * timer = (lv_timer_t *)observer->user_data; + lv_timer_set_cb(timer, locked_timer_cb); + lv_timer_set_period(timer, 3000); + lv_timer_set_user_data(timer, subject); + lv_timer_set_repeat_count(timer, 1); + lv_timer_set_auto_delete(timer, false); + lv_timer_resume(timer); + } +} + +static void locked_timer_cb(lv_timer_t * t) +{ + lv_subject_t * locked_subject = lv_timer_get_user_data(t); + lv_subject_set_int(locked_subject, 0); +} + +static void delete_timer_cb(lv_event_t * e) +{ + lv_timer_t * timer = lv_event_get_user_data(e); + lv_timer_delete(timer); +} + +static void clock_timer_cb(lv_timer_t * t) +{ + /* slowly increment the time */ + lv_demo_smart_home_api_t * api = lv_timer_get_user_data(t); + int32_t minutes = lv_subject_get_int(&api->subjects.minute); + minutes += 1; + if(minutes > 59) { + minutes = 0; + int32_t hour = lv_subject_get_int(&api->subjects.hour); + hour += 1; + if(hour > 12) { + hour = 1; + } + lv_subject_set_int(&api->subjects.hour, hour); + } + lv_subject_set_int(&api->subjects.minute, minutes); +} + +static void door_timer_cb(lv_timer_t * t) +{ + lv_demo_smart_home_api_t * api = lv_timer_get_user_data(t); + lv_subject_set_int(&api->subjects.door, !lv_subject_get_int(&api->subjects.door)); +} + +static void wifi_ssid_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_demo_smart_home_api_t * api = (lv_demo_smart_home_api_t *)observer->user_data;; + const char * ssid = lv_subject_get_pointer(subject); + const char * password = lv_subject_get_pointer(&api->subjects.wifi_password); + + if(ssid) { + LV_LOG_USER("The WiFi SSID is \"%s\"", ssid); + if(ssid[0] == '\0') ssid = NULL; + } + else LV_LOG_USER("The WiFi SSID is `NULL`"); + + if(password) { + LV_LOG_USER("The WiFi password is %d characters long", (int) lv_strlen(password)); + if(password[0] == '\0') password = NULL; + } + else LV_LOG_USER("The WiFi password is `NULL`"); + + /* This block contains non-portable code which is a working example implementation + * of how you can programmatically connect the host device to WiFi using the + * SSID and password that was entered in the demo. + * It is for illustrative purposes. It will not be maintained. It was tested on Ubuntu 20.04. + */ + + /* Set an imaginary IP address. */ + if(ssid) { + lv_subject_set_pointer(&api->subjects.wifi_ip, "10.0.2.15"); + } +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_app_about.c b/smart_home/lv_demo_smart_home_app_about.c new file mode 100644 index 0000000000000000000000000000000000000000..a08053371fc52a3d5e0456a89f386639e6f587c2 --- /dev/null +++ b/smart_home/lv_demo_smart_home_app_about.c @@ -0,0 +1,281 @@ +/** + * @file lv_demo_smart_home_app_about.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void back_clicked_cb(lv_event_t * e); +static void slide_deck_scrolled_cb(lv_event_t * e); +static lv_obj_t * create_button(lv_obj_t * parent, const void * img_src, lv_demo_smart_home_ctx_t * c); +static void left_clicked_cb(lv_event_t * e); +static void bg_cont_delete_cb(lv_event_t * e); +static bool advance_slides(lv_obj_t * slide_deck); +static void right_clicked_cb(lv_event_t * e); +static void play_pause_timer_cb(lv_timer_t * t); +static void play_pause_clicked_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_smart_home_app_about(lv_obj_t * base_obj) +{ + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + /* background */ + + lv_obj_t * bg = base_obj; + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); + + lv_obj_t * bg_img = lv_image_create(bg); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, bg_img, + (void *)&c->imgs[IMG_LIGHT_BG_ABOUT]); + + lv_obj_t * bg_cont = lv_obj_create(bg); + lv_obj_remove_style_all(bg_cont); + lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0); + lv_obj_set_style_pad_bottom(bg_cont, c->sz->gap[10], 0); + lv_obj_set_style_pad_hor(bg_cont, c->sz->gap[10], 0); + + /* top margin */ + + lv_obj_t * top_margin = lv_demo_smart_home_top_margin_create(bg_cont, 0, true, c); + + /* app info */ + + lv_obj_t * app_info = lv_demo_smart_home_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_align_to(app_info, top_margin, LV_ALIGN_OUT_BOTTOM_LEFT, 0, c->sz->gap[7]); + + lv_obj_t * back = lv_demo_smart_home_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t * back_icon = lv_image_create(back); + lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]); + lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * back_label = lv_label_create(back); + lv_label_set_text_static(back_label, "Back"); + lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0); + lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0); + + lv_obj_t * app_label = lv_label_create(app_info); + lv_label_set_text_static(app_label, "About"); + lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0); + + /* slides */ + + if(lv_array_is_empty(&c->about_slides_array)) { + lv_obj_t * label = lv_label_create(bg_cont); + if(c->about_slides_dir_exists) { + lv_label_set_text_fmt(label, "Couldn't find images named Slide1.png, Slide2.png, etc. in the '%s' folder", + c->slides_path); + } + else { + lv_label_set_text_fmt(label, "Couldn't open the '%s' folder to load the images", c->slides_path); + } + lv_obj_center(label); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + return; + } + + lv_obj_t * slides_cont = lv_obj_create(bg_cont); + lv_obj_remove_style_all(slides_cont); + lv_obj_set_size(slides_cont, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(slides_cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(slides_cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_align(slides_cont, LV_ALIGN_BOTTOM_MID); + lv_obj_set_style_pad_row(slides_cont, c->sz->gap[3], 0); + + + lv_obj_t * slide_deck_cont = lv_obj_create(slides_cont); + lv_obj_remove_style_all(slide_deck_cont); + lv_obj_set_size(slide_deck_cont, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_t * slide_deck = lv_demo_smart_home_simple_container_create(slide_deck_cont, false, c->sz->gap[2], + LV_FLEX_ALIGN_START); + lv_obj_set_style_pad_left(slide_deck, lv_display_get_horizontal_resolution(NULL) * 2 / 5, 0); + + lv_obj_t * buttons = lv_demo_smart_home_simple_container_create(slides_cont, false, c->sz->gap[2], LV_FLEX_ALIGN_START); + lv_obj_t * left = create_button(buttons, c->imgs[IMG_PAGER_LEFT], c); + lv_obj_set_width(left, c->sz->icon[3]); + lv_obj_add_state(left, LV_STATE_DISABLED); + lv_obj_t * play_pause = create_button(buttons, c->imgs[IMG_PAGER_PAUSE], c); + lv_obj_set_width(play_pause, c->sz->icon[4]); + lv_obj_set_user_data(play_pause, c); + lv_obj_t * right = create_button(buttons, c->imgs[IMG_PAGER_RIGHT], c); + lv_obj_set_width(right, c->sz->icon[3]); + + lv_obj_add_event_cb(slide_deck_cont, slide_deck_scrolled_cb, LV_EVENT_SCROLL, buttons); + lv_obj_add_event_cb(left, left_clicked_cb, LV_EVENT_CLICKED, slide_deck); + lv_obj_add_event_cb(right, right_clicked_cb, LV_EVENT_CLICKED, slide_deck); + + lv_timer_t * play_pause_timer = lv_timer_create(play_pause_timer_cb, 5000, slide_deck); + lv_obj_add_event_cb(play_pause, play_pause_clicked_cb, LV_EVENT_CLICKED, play_pause_timer); + lv_obj_add_event_cb(bg_cont, bg_cont_delete_cb, LV_EVENT_DELETE, play_pause_timer); + + lv_obj_t * slide; + + uint32_t about_slides_count = lv_array_size(&c->about_slides_array); + for(uint32_t i = 0; i < about_slides_count; i++) { + lv_image_dsc_t ** slide_src = lv_array_at(&c->about_slides_array, i); + slide = lv_image_create(slide_deck); + lv_image_set_src(slide, *slide_src); + } + + slide = lv_obj_get_child(slide_deck, 0); + if(slide) { + lv_obj_scroll_to_view_recursive(slide, LV_ANIM_OFF); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void back_clicked_cb(lv_event_t * e) +{ + lv_obj_t * back = lv_event_get_target_obj(e); + + lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back))); + lv_obj_clean(base_obj); + lv_demo_smart_home_home(base_obj); +} + +static void slide_deck_scrolled_cb(lv_event_t * e) +{ + lv_obj_t * slide_deck_cont = lv_event_get_target_obj(e); + lv_obj_t * slide_deck = lv_obj_get_child(slide_deck_cont, 0); + lv_obj_t * buttons = lv_event_get_user_data(e); + lv_obj_t * left_button = lv_obj_get_child(buttons, 0); + lv_obj_t * right_button = lv_obj_get_child(buttons, 2); + + lv_obj_set_state(left_button, LV_STATE_DISABLED, + lv_obj_get_scroll_left(slide_deck_cont) - lv_obj_get_style_pad_left(slide_deck, 0) <= 0); + lv_obj_set_state(right_button, LV_STATE_DISABLED, lv_obj_get_scroll_right(slide_deck_cont) <= 0); +} + +static lv_obj_t * create_button(lv_obj_t * parent, const void * img_src, lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * button = lv_obj_create(parent); + lv_obj_remove_style_all(button); + lv_obj_set_style_bg_opa(button, LV_OPA_COVER, 0); + lv_obj_set_size(button, c->sz->icon[4], c->sz->icon[1]); + lv_obj_set_style_radius(button, c->sz->gap[3], 0); + lv_obj_add_style(button, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_OBJ], 0); + lv_obj_set_style_opa(button, LV_OPA_20, LV_STATE_DISABLED); + lv_obj_t * img = lv_image_create(button); + lv_image_set_src(img, img_src); + lv_obj_set_style_image_recolor(img, lv_color_white(), 0); + lv_obj_set_style_image_recolor_opa(img, LV_OPA_COVER, 0); + lv_obj_center(img); + return button; +} + +static void left_clicked_cb(lv_event_t * e) +{ + lv_obj_t * slide_deck = lv_event_get_user_data(e); + lv_obj_t * slide_deck_cont = lv_obj_get_parent(slide_deck); + lv_area_t slide_deck_cont_area; + lv_obj_get_coords(slide_deck_cont, &slide_deck_cont_area); + + int32_t slide_count = lv_obj_get_child_count(slide_deck); + for(int32_t i = slide_count - 1; i >= 0; i--) { + lv_obj_t * slide = lv_obj_get_child(slide_deck, i); + lv_area_t slide_area; + lv_obj_get_coords(slide, &slide_area); + if(slide_area.x1 < slide_deck_cont_area.x1 && slide_area.x2 < slide_deck_cont_area.x2) { + lv_obj_scroll_to_view_recursive(slide, LV_ANIM_ON); + break; + } + } +} + +static void bg_cont_delete_cb(lv_event_t * e) +{ + lv_timer_t * play_pause_timer = lv_event_get_user_data(e); + lv_timer_delete(play_pause_timer); +} + +static bool advance_slides(lv_obj_t * slide_deck) +{ + lv_obj_t * slide_deck_cont = lv_obj_get_parent(slide_deck); + lv_area_t slide_deck_cont_area; + lv_obj_get_coords(slide_deck_cont, &slide_deck_cont_area); + + int32_t slide_count = lv_obj_get_child_count(slide_deck); + for(int32_t i = 0; i < slide_count; i++) { + lv_obj_t * slide = lv_obj_get_child(slide_deck, i); + lv_area_t slide_area; + lv_obj_get_coords(slide, &slide_area); + if(slide_area.x1 > slide_deck_cont_area.x1 && slide_area.x2 > slide_deck_cont_area.x2) { + lv_obj_scroll_to_view_recursive(slide, LV_ANIM_ON); + return true; + } + } + return false; +} + +static void right_clicked_cb(lv_event_t * e) +{ + lv_obj_t * slide_deck = lv_event_get_user_data(e); + advance_slides(slide_deck); +} + +static void play_pause_timer_cb(lv_timer_t * t) +{ + lv_obj_t * slide_deck = lv_timer_get_user_data(t); + bool scrolled = advance_slides(slide_deck); + if(!scrolled) { + lv_obj_t * first_slide = lv_obj_get_child(slide_deck, 0); + lv_obj_scroll_to_view_recursive(first_slide, LV_ANIM_ON); + } +} + +static void play_pause_clicked_cb(lv_event_t * e) +{ + lv_obj_t * play_pause = lv_event_get_target_obj(e); + lv_timer_t * play_pause_timer = lv_event_get_user_data(e); + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(play_pause); + lv_obj_t * play_pause_img = lv_obj_get_child(play_pause, 0); + + if(lv_image_get_src(play_pause_img) == c->imgs[IMG_PAGER_PAUSE]) { + lv_image_set_src(play_pause_img, c->imgs[IMG_PAGER_PLAY]); + lv_timer_pause(play_pause_timer); + } else { + lv_image_set_src(play_pause_img, c->imgs[IMG_PAGER_PAUSE]); + lv_timer_reset(play_pause_timer); + lv_timer_resume(play_pause_timer); + } +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_app_ev_charging.c b/smart_home/lv_demo_smart_home_app_ev_charging.c new file mode 100644 index 0000000000000000000000000000000000000000..ff12bf14019ad03cc51b453c7ea6b998b10bf139 --- /dev/null +++ b/smart_home/lv_demo_smart_home_app_ev_charging.c @@ -0,0 +1,596 @@ +/** + * @file lv_demo_smart_home_app_ev_charging.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#undef LV_USE_PRIVATE_API +#define LV_USE_PRIVATE_API 1 /*Include the *_private.h LVGL headers too*/ + +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_obj_t * percent_label; + lv_obj_t * arc; + lv_obj_t * spent_label_large; + lv_obj_t * spent_spangroup_small; + lv_obj_t * saved_label; + lv_obj_t * charged_label; + lv_obj_t * time_to_full_label; + lv_obj_t * energy_consumed_label; + lv_obj_t * driving_range_label; + lv_obj_t * widget3; + lv_obj_t * charging_status_label; +} anim_state_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void bg_cont_delete_cb(lv_event_t * e); +static void base_obj_delete_cb(lv_event_t * e); +static void anim_state_apply(anim_state_t * anim_state, int32_t v); +static void anim_exec_cb(void * var, int32_t v); +static void anim_completed_cb(lv_anim_t * a); +static void back_clicked_cb(lv_event_t * e); +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static lv_obj_t * widget2_chart_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text); +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static lv_obj_t * create_widget3_info(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const lv_image_dsc_t * img_dsc, + const char * text, const char * unit); +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void prepare_default_anim(lv_anim_t * a, int32_t start_v, lv_obj_t * base_obj); +static void charging_status_box_clicked_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +static const char start_charging_string[] = "Start charging"; +static const char stop_charging_string[] = "Stop charging"; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_smart_home_app_ev_charging(lv_obj_t * base_obj) +{ + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + /* background */ + + lv_obj_t * bg = base_obj; + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); + + lv_obj_t * bg_img = lv_image_create(bg); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, bg_img, + &c->imgs[IMG_LIGHT_BG_EV_CHARGING]); + + lv_obj_t * bg_cont = lv_obj_create(bg); + lv_obj_remove_style_all(bg_cont); + lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0); + int32_t app_padding = c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10]; + lv_obj_set_style_pad_bottom(bg_cont, app_padding, 0); + lv_obj_set_style_pad_hor(bg_cont, app_padding, 0); + c->ev_charging_bg_cont = bg_cont; + lv_obj_add_event_cb(bg_cont, bg_cont_delete_cb, LV_EVENT_DELETE, base_obj); + + anim_state_t * anim_state = NULL; + uint32_t base_obj_event_count = lv_obj_get_event_count(base_obj); + for(uint32_t i = 0; i < base_obj_event_count; i++) { + lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(base_obj, i); + lv_event_cb_t event_cb = lv_event_dsc_get_cb(event_dsc); + if(event_cb == base_obj_delete_cb) { + anim_state = lv_event_dsc_get_user_data(event_dsc); + break; + } + } + if(anim_state == NULL) { + anim_state = lv_malloc_zeroed(sizeof(anim_state_t)); + LV_ASSERT_MALLOC(anim_state); + lv_obj_add_event_cb(base_obj, base_obj_delete_cb, LV_EVENT_DELETE, anim_state); + } + lv_obj_set_user_data(bg_cont, anim_state); + + /* top margin */ + + lv_obj_t * top_margin = lv_demo_smart_home_top_margin_create(bg_cont, 0, true, c); + + /* app info */ + + lv_obj_t * app_info = lv_demo_smart_home_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_align_to(app_info, top_margin, LV_ALIGN_OUT_BOTTOM_LEFT, 0, c->sz->gap[7]); + + lv_obj_t * back = lv_demo_smart_home_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t * back_icon = lv_image_create(back); + lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]); + lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * back_label = lv_label_create(back); + lv_label_set_text_static(back_label, "Back"); + lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0); + lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0); + + lv_obj_t * app_label = lv_label_create(app_info); + lv_label_set_text_static(app_label, "EV Charging"); + lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0); + + + /* widgets */ + + int32_t widget_gap_padding = c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[4] : c->sz->gap[7]; + lv_obj_t * widgets = lv_demo_smart_home_simple_container_create(bg_cont, false, widget_gap_padding, LV_FLEX_ALIGN_END); + lv_obj_set_align(widgets, LV_ALIGN_BOTTOM_RIGHT); + + create_widget1(c, widgets); + create_widget2(c, widgets); + create_widget3(c, widgets); + + anim_state_apply(anim_state, lv_subject_get_int(&c->ev_charging_progress)); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void bg_cont_delete_cb(lv_event_t * e) +{ + lv_obj_t * base_obj = lv_event_get_user_data(e); + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + if(!c) return; + c->ev_charging_bg_cont = NULL; +} + +static void base_obj_delete_cb(lv_event_t * e) +{ + anim_state_t * anim_state = lv_event_get_user_data(e); + lv_free(anim_state); +} + +static void anim_state_apply(anim_state_t * anim_state, int32_t v) +{ + int32_t v_range_100 = lv_map(v, 0, EV_CHARGING_RANGE_END, 0, 100); + lv_label_set_text_fmt(anim_state->percent_label, "%"LV_PRId32"%%", v_range_100); + lv_arc_set_value(anim_state->arc, v_range_100); + + int32_t v_range_spent = lv_map(v, 0, EV_CHARGING_RANGE_END, 96, 176); + lv_label_set_text_fmt(anim_state->spent_label_large, "$%"LV_PRId32, v_range_spent); + char buf[32]; + lv_snprintf(buf, sizeof(buf), "$%"LV_PRId32" - ", v_range_spent); + lv_span_set_text(lv_spangroup_get_child(anim_state->spent_spangroup_small,0) , buf); + + + lv_label_set_text_fmt(anim_state->saved_label, "$%"LV_PRId32, 340 - v_range_spent); + + int32_t v_range_charged = lv_map(v, 0, EV_CHARGING_RANGE_END, 640, 683); + lv_label_set_text_fmt(anim_state->charged_label, "%"LV_PRId32, v_range_charged); + + int32_t v_range_time_to_full = lv_map(v, 0, EV_CHARGING_RANGE_END, 72, 0); + int32_t whole = v_range_time_to_full / 10; + int32_t fraction = v_range_time_to_full % 10; + lv_label_set_text_fmt(anim_state->time_to_full_label, + "%"LV_PRId32".%"LV_PRId32, whole, fraction); + + int32_t v_range_consumed = lv_map(v, 0, EV_CHARGING_RANGE_END, 0, 1012); + whole = v_range_consumed / 100; + fraction = v_range_consumed % 100; + lv_label_set_text_fmt(anim_state->energy_consumed_label, + "%"LV_PRId32".%"LV_PRId32, whole, fraction); + + int32_t v_range_driving_range = lv_map(v, 0, EV_CHARGING_RANGE_END, 0, 240); + lv_label_set_text_fmt(anim_state->driving_range_label, "%"LV_PRId32, v_range_driving_range); +} + +static void anim_exec_cb(void * var, int32_t v) +{ + lv_obj_t * base_obj = var; + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + lv_subject_set_int(&c->ev_charging_progress, v); + + if(c->ev_charging_bg_cont) { + anim_state_t * anim_state = lv_obj_get_user_data(c->ev_charging_bg_cont); + anim_state_apply(anim_state, v); + } +} + +static void anim_completed_cb(lv_anim_t * a) +{ + lv_obj_t * base_obj = lv_anim_get_user_data(a); + lv_anim_t new_a; + prepare_default_anim(&new_a, 0, base_obj); + lv_anim_set_delay(&new_a, 1000); + lv_anim_set_early_apply(&new_a, false); + lv_anim_start(&new_a); +} + +static void back_clicked_cb(lv_event_t * e) +{ + lv_obj_t * back = lv_event_get_target_obj(e); + + lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back))); + lv_obj_clean(base_obj); + lv_demo_smart_home_home(base_obj); +} + +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * bg_cont = lv_obj_get_parent(widgets); + anim_state_t * anim_state = lv_obj_get_user_data(bg_cont); + + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET3_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + + lv_obj_t * title_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[1], LV_FLEX_ALIGN_START); + + lv_obj_t * gas_savings_label = lv_label_create(title_box); + lv_label_set_text_static(gas_savings_label, "Gas Savings"); + lv_obj_add_style(gas_savings_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(gas_savings_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_t * estimated_values_label = lv_label_create(title_box); + lv_label_set_text_static(estimated_values_label, "Estimated values"); + lv_obj_add_style(estimated_values_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(estimated_values_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(estimated_values_label, LV_OPA_40, 0); + + lv_obj_t * saved_box = lv_obj_create(widget); + lv_obj_remove_style_all(saved_box); + lv_obj_set_width(saved_box, LV_PCT(100)); + lv_obj_set_flex_grow(saved_box, 1); + lv_obj_set_flex_flow(saved_box, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_row(saved_box, c->sz->gap[2], 0); + lv_obj_set_flex_align(saved_box, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + + lv_obj_t * saved_amount_label = lv_label_create(saved_box); + lv_obj_add_style(saved_amount_label, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(saved_amount_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + anim_state->saved_label = saved_amount_label; + lv_obj_t * saved_label = lv_label_create(saved_box); + lv_label_set_text_static(saved_label, "Saved"); + lv_obj_add_style(saved_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(saved_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * spent_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + + lv_obj_t * total_spent_span = lv_spangroup_create(spent_box); + lv_obj_add_style(total_spent_span, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(total_spent_span, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_spangroup_new_span(total_spent_span); + + anim_state->spent_spangroup_small = total_spent_span; + lv_span_t * total_spent_label = lv_spangroup_new_span(total_spent_span); + lv_span_set_text_static(total_spent_label, "Total spent"); + lv_style_set_text_opa(&total_spent_label->style, LV_OPA_40); + + lv_obj_t * total_spent_bar = lv_demo_smart_home_simple_container_create(spent_box, false, c->sz->gap[1], + LV_FLEX_ALIGN_START); + for(int32_t i = 0; i < 11; i++) { + lv_obj_t * bar = lv_obj_create(total_spent_bar); + lv_obj_set_style_border_width(bar, 0, 0); + lv_obj_set_size(bar, c->sz->gap[2], c->sz->gap[8]); + lv_obj_set_style_radius(bar, LV_COORD_MAX, 0); + lv_obj_set_style_opa(bar, LV_OPA_TRANSP, LV_PART_SCROLLBAR); + } + + lv_obj_t * gas_equivalent_bar = lv_demo_smart_home_simple_container_create(spent_box, false, c->sz->gap[1], + LV_FLEX_ALIGN_START); + for(int32_t i = 0; i < 26; i++) { + lv_obj_t * bar = lv_obj_create(gas_equivalent_bar); + lv_obj_set_style_border_width(bar, 0, 0); + lv_obj_set_size(bar, c->sz->gap[2], c->sz->gap[8]); + lv_obj_set_style_radius(bar, LV_COORD_MAX, 0); + lv_obj_set_style_opa(bar, LV_OPA_30, 0); + lv_obj_set_style_opa(bar, LV_OPA_TRANSP, LV_PART_SCROLLBAR); + } + + lv_obj_t * gas_equivalent_span = lv_spangroup_create(spent_box); + lv_obj_add_style(gas_equivalent_span, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(gas_equivalent_span, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_span_t * gas_equivalent_amount = lv_spangroup_new_span(gas_equivalent_span); + lv_span_set_text_static(gas_equivalent_amount, "$340 - "); + lv_span_t * gas_equivalent_label = lv_spangroup_new_span(gas_equivalent_span); + lv_span_set_text_static(gas_equivalent_label, "Gas Equivalent"); + lv_style_set_text_opa(&gas_equivalent_label->style, LV_OPA_40); + lv_spangroup_refr_mode(gas_equivalent_span); +} + +static lv_obj_t * widget2_chart_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text) +{ + lv_obj_t * label = lv_label_create(parent); + lv_label_set_text_static(label, text); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(label, LV_OPA_40, 0); + return label; +} + +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * bg_cont = lv_obj_get_parent(widgets); + anim_state_t * anim_state = lv_obj_get_user_data(bg_cont); + + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET1_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + lv_obj_set_style_pad_row(widget, 18, 0); + + lv_obj_t * title_label = lv_label_create(widget); + lv_label_set_text_static(title_label, "Last 14 days"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * chart_grid = lv_obj_create(widget); + lv_obj_remove_style_all(chart_grid); + lv_obj_set_size(chart_grid, LV_PCT(100), LV_SIZE_CONTENT); + static const int32_t column_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + static const int32_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_style_grid_column_dsc_array(chart_grid, column_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(chart_grid, row_dsc, 0); + lv_obj_set_layout(chart_grid, LV_LAYOUT_GRID); + lv_obj_set_style_pad_column(chart_grid, c->sz->gap[3], 0); + lv_obj_set_style_pad_row(chart_grid, 5, 0); + + lv_obj_t * chart = lv_chart_create(chart_grid); + lv_obj_set_height(chart, c->sz->small_chart_height); + lv_obj_set_style_bg_opa(chart, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_column(chart, c->sz->gap[1], 0); + lv_obj_set_style_radius(chart, c->sz->gap[3], LV_PART_ITEMS); + lv_obj_set_style_border_width(chart, 2, 0); + lv_obj_set_style_border_color(chart, lv_color_black(), 0); + lv_obj_set_style_border_side(chart, LV_BORDER_SIDE_BOTTOM, 0); + lv_obj_set_style_border_post(chart, true, 0); + lv_obj_set_style_radius(chart, 0, 0); + lv_obj_set_style_pad_all(chart, 0, 0); + lv_obj_set_grid_cell(chart, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1); + lv_chart_set_type(chart, LV_CHART_TYPE_BAR); + lv_chart_set_range(chart,LV_CHART_AXIS_PRIMARY_Y, 0, 96); + lv_chart_set_div_line_count(chart, 3, 0); + lv_obj_set_style_line_opa(chart, LV_OPA_40, 0); + lv_obj_set_style_line_color(chart, lv_color_black(), 0); + lv_obj_set_style_line_dash_width(chart, 2, 0); + lv_obj_set_style_line_dash_gap(chart, 1, 0); + lv_chart_series_t * ser = lv_chart_add_series(chart, lv_color_white(), LV_CHART_AXIS_PRIMARY_Y); + static const int32_t chart_values[] = {45, 14, 78, 95, 45, 52, 78, 34, 63, 52, 38, 83, 63, 19, LV_CHART_POINT_NONE}; + lv_chart_set_ext_y_array(chart, ser, (int32_t *)chart_values); + lv_chart_set_point_count(chart, sizeof(chart_values) / sizeof(*chart_values)); + lv_chart_refresh(chart); + + lv_obj_t * hscale_label_1 = widget2_chart_label(c, chart_grid, "Aug 2"); + lv_obj_set_grid_cell(hscale_label_1, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 1, 1); + lv_obj_t * hscale_label_2 = widget2_chart_label(c, chart_grid, "Sep 1"); + lv_obj_set_grid_cell(hscale_label_2, LV_GRID_ALIGN_END, 0, 1, LV_GRID_ALIGN_START, 1, 1); + + lv_obj_t * vscale_label_1 = widget2_chart_label(c, chart_grid, "95\nkWh"); + lv_obj_set_grid_cell(vscale_label_1, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 0, 1); + lv_obj_t * vscale_label_2 = widget2_chart_label(c, chart_grid, "48"); + lv_obj_set_grid_cell(vscale_label_2, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_t * vscale_label_3 = widget2_chart_label(c, chart_grid, "0"); + lv_obj_set_grid_cell(vscale_label_3, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_END, 0, 1); + + lv_obj_t * totals_box = lv_obj_create(widget); + lv_obj_remove_style_all(totals_box); + lv_obj_set_size(totals_box, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(totals_box, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_grow(totals_box, 1); + lv_obj_set_flex_align(totals_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END); + + lv_obj_t * charged_box = lv_demo_smart_home_simple_container_create(totals_box, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + + lv_obj_t * charged_label = lv_label_create(charged_box); + lv_label_set_text_static(charged_label, "Total Charged"); + lv_obj_add_style(charged_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(charged_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * charged_amount_box = lv_demo_smart_home_simple_container_create(charged_box, false, c->sz->gap[1], + LV_FLEX_ALIGN_END); + + lv_obj_t * charged_amount_number = lv_label_create(charged_amount_box); + lv_obj_add_style(charged_amount_number, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(charged_amount_number, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + anim_state->charged_label = charged_amount_number; + + lv_obj_t * charged_amount_kwh = lv_label_create(charged_amount_box); + lv_label_set_text_static(charged_amount_kwh, "kWh"); + lv_obj_add_style(charged_amount_kwh, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(charged_amount_kwh, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(charged_amount_kwh, LV_OPA_40, 0); + + lv_obj_t * spent_box = lv_demo_smart_home_simple_container_create(totals_box, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + lv_obj_set_width(spent_box, LV_PCT(45)); + + lv_obj_t * spent_label = lv_label_create(spent_box); + lv_label_set_text_static(spent_label, "Total Spent"); + lv_obj_add_style(spent_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(spent_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * spent_amount_number = lv_label_create(spent_box); + lv_obj_add_style(spent_amount_number, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(spent_amount_number, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + anim_state->spent_label_large = spent_amount_number; +} + +static lv_obj_t * create_widget3_info(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const lv_image_dsc_t * img_dsc, + const char * text, const char * unit) +{ + lv_obj_t * info = lv_obj_create(parent); + lv_obj_remove_style_all(info); + lv_obj_set_height(info, LV_SIZE_CONTENT); + lv_obj_set_flex_flow(info, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_row(info, c->sz->gap[4], 0); + lv_obj_set_flex_grow(info, 1); + lv_obj_set_style_bg_color(info, lv_color_white(), 0); + lv_obj_set_style_bg_opa(info, 16 * 255 / 100, 0); + lv_obj_set_style_radius(info, c->sz->gap[3], 0); + lv_obj_set_style_pad_all(info, c->sz->gap[5], 0); + + lv_obj_t * sub_box1 = lv_demo_smart_home_simple_container_create(info, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + + lv_obj_t * img = lv_image_create(sub_box1); + lv_image_set_src(img, img_dsc); + lv_obj_set_style_image_recolor_opa(img, LV_OPA_COVER, 0); + lv_obj_set_style_image_recolor(img, lv_color_white(), 0); + + lv_obj_t * label = lv_label_create(sub_box1); + lv_label_set_text_static(label, text); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(label, lv_color_white(), 0); + + lv_obj_t * sub_box2 = lv_demo_smart_home_simple_container_create(info, false, c->sz->gap[1], LV_FLEX_ALIGN_END); + + lv_obj_t * label_number = lv_label_create(sub_box2); + lv_obj_add_style(label_number, &c->fonts[FONT_LABEL_LG], 0); + lv_obj_set_style_text_color(label_number, lv_color_white(), 0); + + lv_obj_t * label_unit = lv_label_create(sub_box2); + lv_label_set_text_static(label_unit, unit); + lv_obj_add_style(label_unit, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(label_unit, lv_color_white(), 0); + lv_obj_set_style_text_opa(label_unit, LV_OPA_60, 0); + + return label_number; +} + +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * bg_cont = lv_obj_get_parent(widgets); + lv_obj_t * base_obj = lv_obj_get_parent(bg_cont); + bool is_animating = NULL != lv_anim_get(base_obj, anim_exec_cb); + anim_state_t * anim_state = lv_obj_get_user_data(bg_cont); + + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.w, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.h); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_bg_image_src(widget, c->imgs[is_animating ? IMG_EV_CHARGING_WIDGET3_BG : IMG_EV_CHARGING_WIDGET3_1_BG], + 0); + anim_state->widget3 = widget; + + lv_obj_t * top_label = lv_label_create(widget); + lv_label_set_text_static(top_label, "Charging"); + lv_obj_set_width(top_label, LV_PCT(100)); + lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_set_style_text_color(top_label, lv_color_white(), 0); + + lv_obj_t * arc = lv_arc_create(widget); + lv_obj_set_size(arc, c->sz->ev_charging_arc_diameter, c->sz->ev_charging_arc_diameter); + lv_arc_set_rotation(arc, 270); + lv_arc_set_bg_angles(arc, 0, 360); + lv_obj_remove_style(arc, NULL, LV_PART_KNOB); + lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_style_arc_rounded(arc, false, 0); + lv_obj_set_style_arc_rounded(arc, false, LV_PART_INDICATOR); + lv_obj_set_style_arc_width(arc, 7, 0); + lv_obj_set_style_arc_width(arc, 7, LV_PART_INDICATOR); + lv_obj_set_style_arc_color(arc, lv_color_white(), 0); + lv_obj_set_style_arc_color(arc, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_arc_opa(arc, LV_OPA_20, 0); + lv_obj_set_flex_flow(arc, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(arc, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(arc, c->sz->gap[2], 0); + anim_state->arc = arc; + + lv_obj_t * percent_label = lv_label_create(arc); + lv_obj_add_style(percent_label, &c->fonts[FONT_LABEL_2XL], 0); + lv_obj_set_style_text_color(percent_label, lv_color_white(), 0); + anim_state->percent_label = percent_label; + + lv_obj_t * charging_status_box = lv_obj_create(arc); + lv_obj_remove_style_all(charging_status_box); + lv_obj_set_size(charging_status_box, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_style_pad_hor(charging_status_box, c->sz->gap[6], 0); + lv_obj_set_style_pad_ver(charging_status_box, c->sz->gap[3], 0); + lv_obj_set_style_bg_color(charging_status_box, lv_color_white(), 0); + lv_obj_set_style_bg_opa(charging_status_box, LV_OPA_30, 0); + lv_obj_set_style_radius(charging_status_box, LV_COORD_MAX, 0); + lv_obj_add_flag(charging_status_box, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(charging_status_box, charging_status_box_clicked_cb, LV_EVENT_CLICKED, bg_cont); + + lv_obj_t * charging_status_label = lv_label_create(charging_status_box); + lv_obj_add_style(charging_status_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(charging_status_label, lv_color_white(), 0); + lv_obj_center(charging_status_label); + lv_label_set_text_static(charging_status_label, is_animating ? stop_charging_string : start_charging_string); + anim_state->charging_status_label = charging_status_label; + + lv_obj_t * info_box = lv_demo_smart_home_simple_container_create(widget, false, c->sz->gap[5], LV_FLEX_ALIGN_CENTER); + lv_obj_set_width(info_box, LV_PCT(100)); + anim_state->time_to_full_label = create_widget3_info(c, info_box, c->imgs[IMG_TIME_ICON], "Time to\nfull charge", "h"); + anim_state->energy_consumed_label = create_widget3_info(c, info_box, c->imgs[IMG_ENERGY_ICON], "Energy\nconsumed", + "kW"); + anim_state->driving_range_label = create_widget3_info(c, info_box, c->imgs[IMG_RANGE_ICON], "Driving\nRange", "km"); +} + +static void prepare_default_anim(lv_anim_t * a, int32_t start_v, lv_obj_t * base_obj) +{ + lv_anim_init(a); + lv_anim_set_values(a, start_v, EV_CHARGING_RANGE_END); + lv_anim_set_duration(a, (EV_CHARGING_RANGE_END - start_v) * 5); + lv_anim_set_exec_cb(a, anim_exec_cb); + lv_anim_set_completed_cb(a, anim_completed_cb); + lv_anim_set_var(a, base_obj); + lv_anim_set_user_data(a, base_obj); +} + +static void charging_status_box_clicked_cb(lv_event_t * e) +{ + lv_obj_t * bg_cont = lv_event_get_user_data(e); + lv_obj_t * base_obj = lv_obj_get_parent(bg_cont); + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + lv_obj_t * charging_status_box = lv_event_get_target_obj(e); + lv_obj_t * charging_status_label = lv_obj_get_child(charging_status_box, 0); + bool was_charging = lv_label_get_text(charging_status_label) == stop_charging_string; + lv_label_set_text_static(charging_status_label, was_charging ? start_charging_string : stop_charging_string); + + lv_obj_t * widget = lv_obj_get_parent(lv_obj_get_parent(charging_status_box)); + lv_obj_set_style_bg_image_src(widget, c->imgs[was_charging ? IMG_EV_CHARGING_WIDGET3_1_BG : IMG_EV_CHARGING_WIDGET3_BG], + 0); + + if(was_charging) { + lv_anim_delete(base_obj, anim_exec_cb); + } + else { + int32_t start_v = lv_subject_get_int(&c->ev_charging_progress); + if(start_v >= EV_CHARGING_RANGE_END) start_v = 0; + + lv_anim_t a; + prepare_default_anim(&a, start_v, base_obj); + lv_anim_start(&a); + } +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_app_smart_home.c b/smart_home/lv_demo_smart_home_app_smart_home.c new file mode 100644 index 0000000000000000000000000000000000000000..0653f84df2c48e90792822a298098b4a267640e4 --- /dev/null +++ b/smart_home/lv_demo_smart_home_app_smart_home.c @@ -0,0 +1,855 @@ +/** + * @file lv_demo_smart_home_app_smart_home.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include <stdio.h> + +#include <stdlib.h> +#include "lv_demo_panel_display_control.h" +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void back_clicked_cb(lv_event_t * e); +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void charging_arc_observer(lv_observer_t * observer, lv_subject_t * subject); +static void charging_percent_label_observer(lv_observer_t * observer, lv_subject_t * subject); +static void charging_time_until_full_label_observer(lv_observer_t * observer, lv_subject_t * subject); +static void create_widget_charging(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void handle_locked_value(lv_obj_t * slider, bool locked); +static void widget2_slider_released_cb(lv_event_t * e); +static void widget2_slider_locked_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void widget3_play_pause_clicked_cb(lv_event_t * e); +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void create_widget4(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void door_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static lv_obj_t * create_widget5_door(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent); +static void switch_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static lv_obj_t * create_switch(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, lv_image_dsc_t ** img_dsc_pair, + lv_subject_t * subject); +static lv_obj_t * create_lightbulbs_switch_with_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, + const char * label_text, lv_subject_t * subject); +static lv_obj_t * create_widget5_lightbulbs(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent); +static lv_obj_t * create_widget5_zigbee_fan(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent); +static void slider_draw_start_cb(lv_event_t * e); +static void slider_draw_end_cb(lv_event_t * e); +static void slider_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void slider_label_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static lv_obj_t * create_slider(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * label_text, + lv_image_dsc_t ** img_dsc_pair, lv_subject_t * subject); +static void create_widget5(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); + + +/********************** + * STATIC VARIABLES + **********************/ +static void sensor_timer_update_cb(lv_timer_t* timer) +{ + LV_UNUSED(timer); + + lv_demo_smart_home_ctx_t * c = lv_timer_get_user_data(timer); + + // refresh_emoji_time(); + // int random_num = rand() % 101; + // lv_subject_set_int( &api->subjects.temperature_indoor, random_num * 10); + // lv_subject_set_int( &api->subjects.temperature_outdoor, random_num * 10); + + lv_demo_update_sensor_data(LV_DEMO_UPDATE_ALL, c); +} +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + + + +void lv_demo_smart_home_app_smart_home(lv_obj_t * base_obj) +{ + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + /* background */ + + lv_obj_t * bg = base_obj; + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); + + lv_obj_t * bg_img = lv_image_create(bg); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, bg_img, + &c->imgs[IMG_LIGHT_BG_SMART_HOME]); + + lv_obj_t * bg_cont = lv_obj_create(bg); + lv_obj_remove_style_all(bg_cont); + lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); + lv_obj_set_flex_flow(bg_cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0); + + /* top margin */ + + lv_obj_t * top_margin = lv_demo_smart_home_top_margin_create(bg_cont, + c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10], true, c); + + /* app info */ + + lv_obj_t * app_info = lv_demo_smart_home_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_add_flag(app_info, LV_OBJ_FLAG_IGNORE_LAYOUT); + lv_obj_align_to(app_info, top_margin, LV_ALIGN_OUT_BOTTOM_LEFT, c->sz->gap[10], c->sz->gap[10]); + + lv_obj_t * back = lv_demo_smart_home_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t * back_icon = lv_image_create(back); + lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]); + lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * back_label = lv_label_create(back); + lv_label_set_text_static(back_label, "Back"); + lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0); + lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0); + + lv_obj_t * app_label = lv_label_create(app_info); + lv_label_set_text_static(app_label, "Smart Home"); + lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0); + + /* widgets */ + + lv_obj_t * widgets = lv_obj_create(bg_cont); + lv_obj_remove_style_all(widgets); + lv_obj_set_width(widgets, LV_PCT(100)); + lv_obj_set_flex_grow(widgets, 1); + lv_obj_set_style_pad_bottom(widgets, c->sz->gap[10], 0); + lv_obj_set_style_pad_left(widgets, c->sz->gap[10], 0); + lv_obj_set_style_pad_right(widgets, c->sz->gap[10], 0); + lv_obj_set_flex_flow(widgets, LV_FLEX_FLOW_ROW); + lv_obj_set_style_pad_column(widgets, c->sz->gap[7], 0); + lv_obj_set_flex_align(widgets, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END); + + create_widget1(c, widgets); + create_widget_charging(c, widgets); + create_widget2(c, widgets); + create_widget3(c, widgets); + create_widget4(c, widgets); + create_widget5(c, widgets); + + lv_timer_t * sensor_timer = lv_timer_create(sensor_timer_update_cb, 1000, c); + + /* bring app info to top so the back button can be clicked */ + lv_obj_move_to_index(app_info, -1); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void back_clicked_cb(lv_event_t * e) +{ + lv_obj_t * back = lv_event_get_target_obj(e); + + lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back))); + lv_obj_clean(base_obj); + lv_demo_smart_home_home(base_obj); +} + +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_obj_set_style_bg_image_src(widget, c->imgs[IMG_SMART_HOME_WIDGET1_BG], 0); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t * top_label = lv_label_create(widget); + lv_label_set_text_static(top_label, "Temperature"); + lv_obj_set_width(top_label, LV_PCT(100)); + lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_set_style_text_color(top_label, lv_color_white(), 0); + + lv_obj_t * main_temp_box = lv_obj_create(widget); + lv_obj_remove_style_all(main_temp_box); + lv_obj_set_size(main_temp_box, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_ver(main_temp_box, c->sz->gap[6], 0); + lv_obj_set_style_bg_color(main_temp_box, lv_color_white(), 0); + lv_obj_set_style_bg_opa(main_temp_box, LV_OPA_20, 0); + lv_obj_set_style_radius(main_temp_box, LV_COORD_MAX, 0); + + lv_obj_t * main_temp = lv_label_create(main_temp_box); + lv_obj_add_style(main_temp, &c->fonts[FONT_LABEL_2XL], 0); + lv_obj_set_style_text_color(main_temp, lv_color_white(), 0); + lv_obj_center(main_temp); + lv_demo_smart_home_label_bind_temperature(main_temp, &c->api.subjects.temperature_indoor, c,true); + + lv_obj_t * outdoor_temp_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[2], + LV_FLEX_ALIGN_CENTER); + + lv_obj_t * outdoor_temp = lv_label_create(outdoor_temp_box); + lv_obj_add_style(outdoor_temp, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_set_style_text_color(outdoor_temp, lv_color_white(), 0); + lv_demo_smart_home_label_bind_temperature(outdoor_temp, &c->api.subjects.temperature_outdoor, c,false); + + lv_obj_t * outdoor_label = lv_label_create(outdoor_temp_box); + lv_label_set_text_static(outdoor_label, "humidity"); + lv_obj_add_style(outdoor_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(outdoor_label, lv_color_white(), 0); + + +} + +static void charging_arc_observer(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * arc = lv_observer_get_target_obj(observer); + lv_arc_set_value(arc, lv_map(lv_subject_get_int(subject), 0, EV_CHARGING_RANGE_END, 0, 100)); +} + +static void charging_percent_label_observer(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * label = lv_observer_get_target_obj(observer); + lv_label_set_text_fmt(label, "%"LV_PRId32"%%", lv_map(lv_subject_get_int(subject), 0, EV_CHARGING_RANGE_END, 0, 100)); +} + +static void charging_time_until_full_label_observer(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * label = lv_observer_get_target_obj(observer); + int32_t v_range_time_to_full = lv_map(lv_subject_get_int(subject), 0, EV_CHARGING_RANGE_END, 72, 0); + int32_t whole = v_range_time_to_full / 10; + int32_t fraction = v_range_time_to_full % 10; + lv_label_set_text_fmt(label, "%"LV_PRId32".%"LV_PRId32, whole, fraction); +} + +static void value_label_observer(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + + int32_t val = lv_subject_get_int(subject); + lv_obj_t * label = lv_observer_get_target_obj(observer); + + int32_t full = val / 10; + int32_t fraction = val % 10; + char buf[16]; + if(fraction) { + lv_snprintf(buf, sizeof(buf), "%"PRId32".%"PRId32, full, fraction); + } + else { + lv_snprintf(buf, sizeof(buf), "%"PRId32, full); + } + + lv_label_set_text(label, buf); +} + +static void co2_value_label_observer(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * label = lv_observer_get_target_obj(observer); + int32_t co2_value = lv_subject_get_int(subject); + + // 显示 CO2 数值和单位 + lv_label_set_text_fmt(label, "%"LV_PRId32" ppm", co2_value); +} + +static void create_widget_charging(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_obj_set_style_bg_image_src(widget, c->imgs[IMG_SMART_HOME_WIDGET2_BG], 0); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t * top_label = lv_label_create(widget); + lv_label_set_text_static(top_label, "Tovc"); + lv_obj_set_width(top_label, LV_PCT(100)); + lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_set_style_text_color(top_label, lv_color_white(), 0); + + lv_obj_t * arc_cont = lv_obj_create(widget); + lv_obj_remove_style_all(arc_cont); + lv_obj_set_width(arc_cont, LV_PCT(100)); + lv_obj_set_flex_grow(arc_cont, 1); + + lv_obj_t * arc = lv_arc_create(arc_cont); + lv_obj_set_align(arc, LV_ALIGN_BOTTOM_MID); + lv_obj_set_size(arc, c->sz->smart_home_arc_diameter, c->sz->smart_home_arc_diameter); + lv_arc_set_rotation(arc, 270); + lv_arc_set_bg_angles(arc, 0, 360); + lv_obj_remove_style(arc, NULL, LV_PART_KNOB); + lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_style_arc_rounded(arc, false, 0); + lv_obj_set_style_arc_rounded(arc, false, LV_PART_INDICATOR); + lv_obj_set_style_arc_width(arc, 8, 0); + lv_obj_set_style_arc_width(arc, 8, LV_PART_INDICATOR); + lv_obj_set_style_arc_color(arc, lv_color_white(), 0); + lv_obj_set_style_arc_color(arc, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_arc_opa(arc, LV_OPA_20, 0); + lv_subject_add_observer_obj(&c->ev_charging_progress, charging_arc_observer, arc, NULL); + + lv_obj_t * percent_label = lv_label_create(arc); + lv_obj_add_style(percent_label, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_set_style_text_color(percent_label, lv_color_white(), 0); + lv_obj_center(percent_label); + lv_subject_add_observer_obj(&c->ev_charging_progress, value_label_observer, percent_label, NULL); + + + lv_obj_t * num_label_cont = lv_demo_smart_home_simple_container_create(widget, + false, + c->sz->gap[1], + LV_FLEX_ALIGN_END); + lv_obj_set_width(num_label_cont, LV_PCT(100)); + + lv_obj_t * time_to_full_num_label = lv_label_create(num_label_cont); + lv_obj_add_style(time_to_full_num_label, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_set_style_text_color(time_to_full_num_label, lv_color_white(), 0); + + lv_subject_add_observer_obj(&c->co2_value, co2_value_label_observer, time_to_full_num_label, NULL); + lv_obj_add_flag(time_to_full_num_label, LV_OBJ_FLAG_HIDDEN); + lv_obj_t * h_label = lv_label_create(num_label_cont); + lv_label_set_text_static(h_label, "ppm"); + lv_obj_add_style(h_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(h_label, lv_color_white(), 0); + lv_obj_set_width(h_label, LV_PCT(100)); + + lv_obj_t * time_to_full_label = lv_label_create(widget); + lv_label_set_text_static(time_to_full_label, "CO2"); + lv_obj_add_style(time_to_full_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(time_to_full_label, lv_color_white(), 0); + lv_obj_set_width(time_to_full_label, LV_PCT(100)); + lv_obj_add_flag(time_to_full_label, LV_OBJ_FLAG_HIDDEN); +} + +static void handle_locked_value(lv_obj_t * slider, bool locked) +{ + lv_slider_set_value(slider, locked ? 100 : 0, LV_ANIM_ON); + lv_obj_update_flag(slider, LV_OBJ_FLAG_CLICKABLE, !locked); +} + +static void widget2_slider_released_cb(lv_event_t * e) +{ + lv_obj_t * slider = lv_event_get_target_obj(e); + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + bool locked = lv_slider_get_value(slider) >= 100; + handle_locked_value(slider, locked); + lv_subject_set_int(&c->api.subjects.locked, locked); +} +static void widget2_slider_locked_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * slider = lv_observer_get_target_obj(observer); + bool locked = lv_subject_get_int(subject); + handle_locked_value(slider, locked); +} + +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET2_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t * top_label = lv_label_create(widget); + lv_label_set_text_static(top_label, "Lock"); + lv_obj_set_width(top_label, LV_PCT(100)); + lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(top_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * slider = lv_slider_create(widget); + lv_obj_set_size(slider, LV_PCT(100), c->sz->icon[ICON_2XL]); + lv_obj_set_style_pad_hor(slider, c->sz->icon[ICON_2XL] / 2, 0); + lv_obj_set_style_pad_all(slider, 0, LV_PART_KNOB); + lv_obj_set_style_bg_opa(slider, 0, LV_PART_INDICATOR); + lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST); + lv_obj_set_style_bg_image_src(slider, c->imgs[IMG_UNLOCK], LV_PART_KNOB); + lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); + lv_obj_set_style_bg_color(slider, lv_color_white(), 0); + lv_obj_set_style_bg_opa(slider, LV_OPA_30, 0); + lv_slider_set_value(slider, lv_subject_get_int(&c->api.subjects.locked) ? 100 : 0, LV_ANIM_OFF); + lv_obj_set_style_anim_duration(slider, lv_anim_speed(2000), 0); + lv_obj_add_event_cb(slider, widget2_slider_released_cb, LV_EVENT_RELEASED, c); + lv_subject_add_observer_obj(&c->api.subjects.locked, widget2_slider_locked_observer_cb, slider, c); + + lv_obj_t * bottom_label = lv_label_create(widget); + lv_label_set_text_static(bottom_label, "Swipe to lock screen"); + lv_obj_add_style(bottom_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(bottom_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); +} + +static void widget3_play_pause_clicked_cb(lv_event_t * e) +{ + lv_obj_t * play_pause_img = lv_event_get_target_obj(e); + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + + bool was_playing = lv_image_get_src(play_pause_img) == c->imgs[IMG_PLAY_ICON]; + lv_image_set_src(play_pause_img, c->imgs[was_playing ? IMG_PLAY_ICON_1 : IMG_PLAY_ICON]); + lv_subject_set_int(&c->api.subjects.music_play, !was_playing); +} + +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET3_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + + lv_obj_t * top_label = lv_label_create(widget); + lv_label_set_text_static(top_label, "Speaker"); + lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(top_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_align(top_label, LV_ALIGN_TOP_LEFT); + + lv_obj_t * music_labels_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[1], + LV_FLEX_ALIGN_START); + lv_obj_set_align(music_labels_box, LV_ALIGN_BOTTOM_LEFT); + lv_obj_t * song_title = lv_label_create(music_labels_box); + lv_label_set_text_static(song_title, "there, then, now"); + lv_obj_add_style(song_title, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(song_title, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_t * song_artist = lv_label_create(music_labels_box); + lv_label_set_text_static(song_artist, "imagiro, Lowswimm..."); + lv_obj_add_style(song_artist, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(song_artist, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(song_artist, LV_OPA_40, 0); + + lv_obj_t * slider = lv_slider_create(widget); + lv_obj_set_size(slider, c->sz->slider_width, LV_PCT(100)); + lv_obj_set_align(slider, LV_ALIGN_RIGHT_MID); + lv_obj_set_style_bg_color(slider, lv_color_white(), 0); + lv_obj_set_style_bg_opa(slider, 30, 0); + lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_radius(slider, c->sz->gap[4], 0); + lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR); + lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB); + lv_obj_set_style_pad_top(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB); + lv_obj_set_style_pad_bottom(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB); + lv_obj_set_style_pad_hor(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB); + + lv_obj_t * slider_pct_label = lv_label_create(slider); + lv_obj_add_style(slider_pct_label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(slider_pct_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_align(slider_pct_label, LV_ALIGN_TOP_MID, 0, 10); + + lv_slider_bind_value(slider, &c->api.subjects.volume); + lv_label_bind_text(slider_pct_label, &c->api.subjects.volume, "%"PRId32"%%"); + + lv_obj_t * slider_volume_img = lv_image_create(slider); + lv_image_set_src(slider_volume_img, c->imgs[IMG_VOLUME]); + lv_obj_align(slider_volume_img, LV_ALIGN_BOTTOM_MID, 0, -8); + + lv_obj_t * album_art = lv_image_create(widget); + lv_image_set_src(album_art, c->imgs[IMG_ALBUM_ART]); + + lv_obj_t * controls = lv_demo_smart_home_simple_container_create(widget, false, 0, LV_FLEX_ALIGN_CENTER); + lv_obj_set_align(controls, LV_ALIGN_LEFT_MID); + + lv_obj_t * prev_song = lv_image_create(controls); + lv_image_set_src(prev_song, c->imgs[IMG_BACKWARD_ICON]); + lv_obj_set_style_image_recolor(prev_song, lv_color_white(), 0); + lv_obj_set_style_image_recolor_opa(prev_song, LV_OPA_COVER, 0); + + lv_obj_t * play_pause_img = lv_image_create(controls); + lv_image_set_src(play_pause_img, c->imgs[lv_subject_get_int(&c->api.subjects.music_play) ? IMG_PLAY_ICON : + IMG_PLAY_ICON_1]); + lv_obj_set_style_image_recolor(play_pause_img, lv_color_white(), 0); + lv_obj_set_style_image_recolor_opa(play_pause_img, LV_OPA_COVER, 0); + lv_obj_add_flag(play_pause_img, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(play_pause_img, widget3_play_pause_clicked_cb, LV_EVENT_CLICKED, c); + + lv_obj_t * next_song = lv_image_create(controls); + lv_image_set_src(next_song, c->imgs[IMG_FORWARD_ICON]); + lv_obj_set_style_image_recolor(next_song, lv_color_white(), 0); + lv_obj_set_style_image_recolor_opa(next_song, LV_OPA_COVER, 0); + + lv_obj_align_to(album_art, controls, LV_ALIGN_CENTER, 0, 0); +} + +static void create_widget4(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->widget_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET4_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t * top_label = lv_label_create(widget); + lv_label_set_text_static(top_label, "Main Light"); + lv_obj_add_style(top_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(top_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * temperature_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[5], LV_FLEX_ALIGN_START); + lv_obj_set_width(temperature_box, LV_PCT(100)); + lv_obj_set_style_pad_ver(temperature_box, 8, 0); /* so the slider knob is not clipped */ + + lv_obj_t * temperature_slider = lv_slider_create(temperature_box); + lv_obj_set_size(temperature_slider, LV_PCT(100), c->imgs[IMG_MAIN_LIGHT_SLIDER]->header.h); + lv_obj_set_style_bg_opa(temperature_slider, LV_OPA_TRANSP, 0); + lv_obj_set_style_bg_opa(temperature_slider, LV_OPA_TRANSP, LV_PART_INDICATOR); + lv_obj_set_style_bg_color(temperature_slider, lv_color_white(), LV_PART_KNOB); + lv_obj_set_style_radius(temperature_slider, 0, 0); + lv_obj_set_style_pad_ver(temperature_slider, 4, 0); + lv_obj_set_style_pad_hor(temperature_slider, -((c->sz->slider_width - 6) / 2), LV_PART_KNOB); + lv_obj_set_style_bg_image_src(temperature_slider, c->imgs[IMG_MAIN_LIGHT_SLIDER], 0); + lv_slider_set_range(temperature_slider, 0, 100); + + + lv_obj_t * temperature_label_box = lv_demo_smart_home_simple_container_create(temperature_box, true, c->sz->gap[1], + LV_FLEX_ALIGN_START); + lv_obj_t * temperature_label = lv_label_create(temperature_label_box); + lv_label_set_text_static(temperature_label, "Light"); + lv_obj_add_style(temperature_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_t * temperature_value_label = lv_label_create(temperature_label_box); + lv_obj_add_style(temperature_value_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(temperature_value_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(temperature_value_label, LV_OPA_40, 0); + + lv_slider_bind_value(temperature_slider, &c->api.subjects.main_light_temperature); + lv_label_bind_text(temperature_value_label, &c->api.subjects.main_light_temperature, "%"PRId32"%%"); + + lv_obj_t * slider = lv_slider_create(widget); + lv_obj_set_size(slider, LV_PCT(100), c->sz->slider_width); + lv_obj_set_style_bg_color(slider, lv_color_white(), 0); + lv_obj_set_style_bg_opa(slider, 30, 0); + lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_radius(slider, c->sz->gap[4], 0); + lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR); + lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB); + lv_obj_set_style_pad_right(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB); + lv_obj_set_style_pad_left(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB); + lv_obj_set_style_pad_ver(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB); + + lv_obj_t * slider_pct_label = lv_label_create(slider); + lv_obj_add_style(slider_pct_label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(slider_pct_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_align(slider_pct_label, LV_ALIGN_RIGHT_MID, -10, 0); + + + lv_slider_bind_value(slider, &c->api.subjects.main_light_intensity); + lv_label_bind_text(slider_pct_label, &c->api.subjects.main_light_intensity, "%"PRId32"%%"); + + lv_obj_t * slider_lamp_img = lv_image_create(slider); + lv_image_set_src(slider_lamp_img, c->imgs[IMG_LAMP]); + lv_obj_align(slider_lamp_img, LV_ALIGN_LEFT_MID, 8, 0); +} + +static void door_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + lv_obj_t * door_box = lv_observer_get_target_obj(observer); + lv_obj_t * icon = lv_obj_get_child(door_box, 0); + lv_obj_t * label = lv_obj_get_child(door_box, 1); + bool door_is_open = lv_subject_get_int(subject); + lv_obj_set_style_bg_opa(door_box, door_is_open ? LV_OPA_60 : LV_OPA_20, 0); + lv_image_set_src(icon, c->imgs[door_is_open ? IMG_DOOR_1 : IMG_DOOR]); + lv_obj_set_style_bg_opa(icon, door_is_open ? LV_OPA_COVER : LV_OPA_40, 0); + lv_label_set_text_static(label, door_is_open ? "Door open" : "Door closed"); +} + +static lv_obj_t * create_widget5_door(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent) +{ + lv_obj_t * door_box = lv_obj_create(parent); + lv_obj_remove_style_all(door_box); + lv_obj_set_size(door_box, c->sz->indicator_width, c->sz->indicator_height); + lv_obj_set_flex_flow(door_box, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(door_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(door_box, 0, 0); + lv_obj_set_style_bg_color(door_box, lv_color_white(), 0); + lv_obj_set_style_radius(door_box, c->sz->gap[3], 0); + lv_obj_set_style_pad_ver(door_box, c->sz->gap[5], 0); + + lv_obj_t * icon = lv_image_create(door_box); + lv_image_set_inner_align(icon, LV_IMAGE_ALIGN_CENTER); + lv_obj_set_size(icon, c->sz->icon[ICON_XL], c->sz->icon[ICON_XL]); + lv_obj_set_style_bg_color(icon, lv_color_white(), 0); + lv_obj_set_style_radius(icon, LV_COORD_MAX, 0); + lv_obj_set_style_shadow_width(icon, 50, 0); + lv_obj_set_style_shadow_opa(icon, 15 * 255 / 100, 0); + lv_obj_add_flag(icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * label = lv_label_create(door_box); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_subject_add_observer_obj(&c->api.subjects.door, door_observer_cb, door_box, c); + + return door_box; +} + +static void switch_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * sw = lv_observer_get_target_obj(observer); + lv_image_dsc_t ** pair = (lv_image_dsc_t **)observer->user_data; + bool is_on = lv_subject_get_int(subject); + lv_obj_set_style_bg_image_src(sw, pair[is_on], LV_PART_KNOB); +} + +static lv_obj_t * create_switch(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, lv_image_dsc_t ** img_dsc_pair, + lv_subject_t * subject) +{ + lv_obj_t * sw = lv_switch_create(parent); + lv_obj_set_size(sw, c->sz->slider_width * 2, c->sz->slider_width); + lv_obj_set_style_pad_all(sw, 0, LV_PART_KNOB); + lv_obj_set_style_bg_color(sw, lv_color_hex(0xCAF0A2), LV_PART_INDICATOR | LV_STATE_CHECKED); + lv_obj_set_style_bg_color(sw, lv_color_white(), 0); + lv_obj_set_style_bg_opa(sw, LV_OPA_30, 0); + lv_obj_set_style_shadow_width(sw, 25, LV_PART_KNOB); + lv_obj_set_style_shadow_opa(sw, 15 * 255 / 100, LV_PART_KNOB); + + lv_subject_add_observer_obj(subject, switch_observer_cb, sw, img_dsc_pair); + + return sw; +} + +static lv_obj_t * create_lightbulbs_switch_with_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, + const char * label_text, lv_subject_t * subject) +{ + lv_obj_t * box = lv_demo_smart_home_simple_container_create(parent, true, c->sz->gap[3], LV_FLEX_ALIGN_CENTER); + + lv_obj_t * label = lv_label_create(box); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(label, LV_OPA_50, 0); + lv_label_set_text_static(label, label_text); + + create_switch(c, box, &c->imgs[IMG_LAMP2], subject); + + return box; +} + +static lv_obj_t * create_widget5_lightbulbs(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent) +{ + lv_obj_t * lightbulbs_box = lv_obj_create(parent); + lv_obj_remove_style_all(lightbulbs_box); + lv_obj_set_height(lightbulbs_box, c->sz->indicator_height); + lv_obj_set_flex_flow(lightbulbs_box, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(lightbulbs_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(lightbulbs_box, 0, 0); + lv_obj_set_style_bg_color(lightbulbs_box, lv_color_white(), 0); + lv_obj_set_style_bg_opa(lightbulbs_box, LV_OPA_20, 0); + lv_obj_set_style_radius(lightbulbs_box, c->sz->gap[3], 0); + lv_obj_set_style_pad_ver(lightbulbs_box, c->sz->gap[5], 0); + + lv_obj_t * switch_box = lv_demo_smart_home_simple_container_create(lightbulbs_box, false, c->sz->gap[7], + LV_FLEX_ALIGN_END); + create_lightbulbs_switch_with_label(c, switch_box, "MATTER", &c->api.subjects.lightbulb_matter); + create_lightbulbs_switch_with_label(c, switch_box, "ZIGBEE", &c->api.subjects.lightbulb_zigbee); + + lv_obj_t * label = lv_label_create(lightbulbs_box); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_label_set_text_static(label, "Lightbulbs Sensors"); + + return lightbulbs_box; +} + +static lv_obj_t * create_widget5_zigbee_fan(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent) +{ + lv_obj_t * box = lv_demo_smart_home_simple_container_create(parent, true, c->sz->gap[9], LV_FLEX_ALIGN_END); + lv_obj_set_style_pad_top(box, c->sz->gap[5], 0); + + lv_obj_t * label = lv_label_create(box); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_label_set_text_static(label, "Zigbee Fan"); + + create_switch(c, box, &c->imgs[IMG_FAN2], &c->api.subjects.fan_zigbee); + + return box; +} + +static void slider_draw_start_cb(lv_event_t * e) +{ + lv_obj_t * slider = lv_event_get_target_obj(e); + lv_area_t indic_area; + lv_obj_get_coords(slider, &indic_area); + int32_t indic_w = lv_area_get_width(&indic_area); + int32_t indic_h = lv_area_get_height(&indic_area); + lv_draw_rect_dsc_t rect_dsc; + lv_draw_rect_dsc_init(&rect_dsc); + lv_area_t rect_area; + lv_layer_t * layer = lv_event_get_layer(e); + + /* draw the ticks */ + lv_area_set(&rect_area, 0, 0, 1, indic_h / 4); + rect_dsc.bg_opa = LV_OPA_40; + + for(int32_t i = 1; i <= 3; i++) { + lv_area_set_width(&indic_area, indic_w * i / 3); + int32_t offset_from_right = -indic_h * i / 4; + lv_area_align(&indic_area, &rect_area, LV_ALIGN_RIGHT_MID, offset_from_right, 0); + lv_draw_rect(layer, &rect_dsc, &rect_area); + } +} + +static void slider_draw_end_cb(lv_event_t * e) +{ + lv_obj_t * slider = lv_event_get_target_obj(e); + if(lv_slider_get_value(slider) == 0) { + /* Add a rectangle for the off state instead of no indicator + * showing at all. + */ + lv_draw_rect_dsc_t rect_dsc; + lv_draw_rect_dsc_init(&rect_dsc); + rect_dsc.radius = lv_obj_get_style_radius(slider, LV_PART_INDICATOR); + + lv_area_t rect_area; + lv_obj_get_coords(slider, &rect_area); + int32_t indic_h = lv_area_get_height(&rect_area); + lv_area_set_width(&rect_area, indic_h * 5 / 4); + + lv_layer_t * layer = lv_event_get_layer(e); + lv_draw_rect(layer, &rect_dsc, &rect_area); + + rect_dsc.radius = 0; + } +} + +static void slider_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * slider = lv_observer_get_target_obj(observer); + lv_obj_t * slider_img = lv_obj_get_child(slider, 0); + lv_image_dsc_t ** pair = (lv_image_dsc_t **)observer->user_data; + bool is_on = lv_slider_get_value(slider) > 0; + lv_image_set_src(slider_img, pair[is_on]); +} + +static void slider_label_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * slider = lv_observer_get_target_obj(observer); + lv_obj_t * label_box = (lv_obj_t *)observer->user_data; + int32_t selected = lv_slider_get_value(slider); + for(int32_t i = 0; i < 4; i++) { + lv_obj_t * label = lv_obj_get_child(label_box, i); + lv_obj_set_style_opa(label, i == selected ? LV_OPA_100 : LV_OPA_50, 0); + } +} + +static lv_obj_t * create_slider(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * label_text, + lv_image_dsc_t ** img_dsc_pair, lv_subject_t * subject) +{ + lv_obj_t * box = lv_demo_smart_home_simple_container_create(parent, true, c->sz->gap[9], LV_FLEX_ALIGN_START); + lv_obj_set_style_pad_top(box, c->sz->gap[5], 0); + + lv_obj_t * label = lv_label_create(box); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_label_set_text_static(label, label_text); + + lv_obj_t * slider = lv_slider_create(box); + lv_obj_set_size(slider, LV_PCT(100), c->sz->slider_width); + lv_slider_set_range(slider, 0, 3); + lv_obj_set_style_bg_color(slider, lv_color_white(), 0); + lv_obj_set_style_bg_opa(slider, 30, 0); + lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_radius(slider, c->sz->gap[4], 0); + lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR); + lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB); + lv_obj_set_style_pad_right(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB); + lv_obj_set_style_pad_left(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB); + lv_obj_set_style_pad_ver(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB); + lv_obj_add_event_cb(slider, slider_draw_start_cb, LV_EVENT_DRAW_MAIN_BEGIN, NULL); + lv_obj_add_event_cb(slider, slider_draw_end_cb, LV_EVENT_DRAW_MAIN_END, NULL); + + lv_obj_t * slider_img = lv_image_create(slider); + lv_obj_align(slider_img, LV_ALIGN_LEFT_MID, 8, 0); + + lv_slider_bind_value(slider, subject); + lv_subject_add_observer_obj(subject, slider_observer_cb, slider, img_dsc_pair); + + lv_obj_t * label_box = lv_demo_smart_home_simple_container_create(box, false, 0, LV_FLEX_ALIGN_CENTER); + lv_obj_set_width(label_box, LV_PCT(100)); + lv_obj_set_flex_align(label_box, LV_FLEX_ALIGN_SPACE_AROUND, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_add_flag(label_box, LV_OBJ_FLAG_IGNORE_LAYOUT); + lv_style_value_t font; + lv_style_get_prop(&c->fonts[FONT_LABEL_XS], LV_STYLE_TEXT_FONT, &font); + int32_t offset = lv_font_get_line_height(font.ptr) + c->sz->slider_width * 13 / 40; + lv_obj_align_to(label_box, slider, LV_ALIGN_OUT_TOP_MID, 0, -offset); + + static const char * const texts[4] = {"OFF", "LOW", "MIDDLE", "HIGH"}; + for(int32_t i = 0; i < 4; i++) { + label = lv_label_create(label_box); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_label_set_text_static(label, texts[i]); + } + + lv_subject_add_observer_obj(subject, slider_label_observer_cb, slider, label_box); + + return box; +} + +static void create_widget5(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.w, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.h); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET5_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + + lv_obj_t * title_label = lv_label_create(widget); + lv_label_set_text_static(title_label, "Sensor Controls"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * cluster_1 = lv_obj_create(widget); + lv_obj_remove_style_all(cluster_1); + lv_obj_set_size(cluster_1, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(cluster_1, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(cluster_1, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_column(cluster_1, c->sz->gap[9], 0); + + create_widget5_door(c, cluster_1); + + lv_obj_t * lightbulbs_box = create_widget5_lightbulbs(c, cluster_1); + lv_obj_set_flex_grow(lightbulbs_box, 1); + + lv_obj_t * cluster_2 = lv_obj_create(widget); + lv_obj_remove_style_all(cluster_2); + lv_obj_set_size(cluster_2, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(cluster_2, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(cluster_2, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END); + lv_obj_set_style_pad_column(cluster_2, c->sz->gap[10], 0); + + lv_obj_t * matter_fan_box = create_slider(c, cluster_2, "Matter Fan", &c->imgs[IMG_FAN2], &c->api.subjects.fan_matter); + lv_obj_set_flex_grow(matter_fan_box, 1); + + create_widget5_zigbee_fan(c, cluster_2); + + lv_obj_t * air_purifier_box = create_slider(c, widget, "Air Purifier", &c->imgs[IMG_WIND], + &c->api.subjects.air_purifier); + lv_obj_set_width(air_purifier_box, LV_PCT(100)); +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_app_smart_meter.c b/smart_home/lv_demo_smart_home_app_smart_meter.c new file mode 100644 index 0000000000000000000000000000000000000000..bd672e94f366feda6b41e803e3de8fa4f6e1f953 --- /dev/null +++ b/smart_home/lv_demo_smart_home_app_smart_meter.c @@ -0,0 +1,614 @@ +/** + * @file lv_demo_smart_home_app_smart_meter.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#undef LV_USE_PRIVATE_API +#define LV_USE_PRIVATE_API 1 /*Include the *_private.h LVGL headers too*/ +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +#define WIDGET3_POINT_COUNT 24 +#define WIDGET3_ANIM_RANGE_END 10000 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + int32_t current[WIDGET3_POINT_COUNT]; + int32_t start[WIDGET3_POINT_COUNT]; +} widget3_chart_anim_values_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void back_clicked_cb(lv_event_t * e); +static lv_obj_t * create_widget1_part(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * title_val, + const char * daily_val, const char * weekly_val); +static void widget1_anim_height_range(lv_demo_smart_home_ctx_t * c, int32_t * min, int32_t * max); +static void widget1_open_part1_anim_cb(void * arg, int32_t val); +static void widget1_open_part2_anim_cb(void * arg, int32_t val); +static void widget1_clicked_cb(lv_event_t * e); +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static lv_obj_t * widget23_chart_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text); +static void widget2_chart_event_draw_task_cb(lv_event_t * e); +static void widget2_chart_bar_clicked_cb(lv_event_t * e); +static void widget2_chart_selected_day_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void widget3_chart_draw_task_event_cb(lv_event_t * e); +static void widget3_chart_free_anim_values(lv_event_t * e); +static void widget3_chart_anim_cb(void * var, int32_t v); +static void widget3_chart_selected_day_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static lv_obj_t * create_widget3_stat(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * title_val, + const char * kwh_val, const char * detail_val); +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_smart_home_app_smart_meter(lv_obj_t * base_obj) +{ + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + /* background */ + + lv_obj_t * bg = base_obj; + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); + + lv_obj_t * bg_img = lv_image_create(bg); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, bg_img, + &c->imgs[IMG_LIGHT_BG_SMART_METER]); + + lv_obj_t * bg_cont = lv_obj_create(bg); + lv_obj_remove_style_all(bg_cont); + lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0); + int32_t app_padding = c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10]; + lv_obj_set_style_pad_bottom(bg_cont, app_padding, 0); + lv_obj_set_style_pad_hor(bg_cont, app_padding, 0); + + /* top margin */ + + lv_obj_t * top_margin = lv_demo_smart_home_top_margin_create(bg_cont, 0, true, c); + + /* app info */ + + lv_obj_t * app_info = lv_demo_smart_home_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_align_to(app_info, top_margin, LV_ALIGN_OUT_BOTTOM_LEFT, 0, c->sz->gap[7]); + + lv_obj_t * back = lv_demo_smart_home_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t * back_icon = lv_image_create(back); + lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]); + lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * back_label = lv_label_create(back); + lv_label_set_text_static(back_label, "Back"); + lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0); + lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0); + + lv_obj_t * app_label = lv_label_create(app_info); + lv_label_set_text_static(app_label, "Smart Meter"); + lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0); + + /* widgets */ + + int32_t widget_gap_padding = c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[4] : c->sz->gap[7]; + lv_obj_t * widgets = lv_demo_smart_home_simple_container_create(bg_cont, false, widget_gap_padding, LV_FLEX_ALIGN_END); + lv_obj_set_align(widgets, LV_ALIGN_BOTTOM_RIGHT); + + create_widget1(c, widgets); + create_widget2(c, widgets); + create_widget3(c, widgets); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void back_clicked_cb(lv_event_t * e) +{ + lv_obj_t * back = lv_event_get_target_obj(e); + + lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back))); + lv_obj_clean(base_obj); + lv_demo_smart_home_home(base_obj); +} + +static lv_obj_t * create_widget1_part(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * title_val, + const char * daily_val, const char * weekly_val) +{ + lv_obj_t * part = lv_obj_create(parent); + lv_obj_remove_style_all(part); + lv_obj_remove_flag(part, LV_OBJ_FLAG_SCROLLABLE); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, part, + &c->imgs[IMG_LIGHT_WIDGET1_BG]); + lv_obj_set_style_bg_color(part, lv_color_white(), 0); + lv_obj_set_style_bg_opa(part, LV_OPA_COVER, 0); + lv_obj_set_style_radius(part, c->sz->card_radius, 0); + lv_obj_set_width(part, LV_PCT(100)); + lv_obj_set_style_pad_all(part, c->sz->gap[7], 0); + lv_obj_set_style_clip_corner(part, true, 0); + + lv_obj_t * title = lv_label_create(part); + lv_label_set_text_static(title, title_val); + lv_obj_add_style(title, &c->fonts[FONT_LABEL_MD], 0); + + lv_obj_t * box = lv_obj_create(part); + lv_obj_remove_style_all(box); + lv_obj_add_flag(box, LV_OBJ_FLAG_EVENT_BUBBLE); + lv_obj_set_size(box, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_align(box, LV_ALIGN_BOTTOM_MID); + lv_obj_set_flex_flow(box, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + + lv_obj_t * daily_box = lv_demo_smart_home_simple_container_create(box, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + lv_obj_add_flag(daily_box, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * daily_label = lv_label_create(daily_box); + lv_label_set_text_static(daily_label, "Daily"); + lv_obj_add_style(daily_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(daily_label, lv_color_black(), 0); + + lv_obj_t * daily_value_box = lv_demo_smart_home_simple_container_create(daily_box, false, c->sz->gap[1], + LV_FLEX_ALIGN_END); + lv_obj_add_flag(daily_value_box, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * daily_value_label = lv_label_create(daily_value_box); + lv_label_set_text_static(daily_value_label, daily_val); + lv_obj_add_style(daily_value_label, &c->fonts[FONT_LABEL_LG], 0); + lv_obj_set_style_text_color(daily_value_label, lv_color_black(), 0); + lv_obj_t * daily_kwh_label = lv_label_create(daily_value_box); + lv_label_set_text_static(daily_kwh_label, "kWh"); + lv_obj_add_style(daily_kwh_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(daily_kwh_label, lv_color_black(), 0); + lv_obj_set_style_text_opa(daily_kwh_label, LV_OPA_40, 0); + + lv_obj_t * weekly_box = lv_demo_smart_home_simple_container_create(box, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + lv_obj_add_flag(weekly_box, LV_OBJ_FLAG_EVENT_BUBBLE); + lv_obj_set_width(weekly_box, LV_PCT(45)); + + lv_obj_t * weekly_label = lv_label_create(weekly_box); + lv_label_set_text_static(weekly_label, "Weekly"); + lv_obj_add_style(weekly_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(weekly_label, lv_color_black(), 0); + + lv_obj_t * weekly_value_box = lv_demo_smart_home_simple_container_create(weekly_box, false, c->sz->gap[1], + LV_FLEX_ALIGN_END); + lv_obj_add_flag(weekly_value_box, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * weekly_value_label = lv_label_create(weekly_value_box); + lv_label_set_text_static(weekly_value_label, weekly_val); + lv_obj_add_style(weekly_value_label, &c->fonts[FONT_LABEL_LG], 0); + lv_obj_set_style_text_color(weekly_value_label, lv_color_black(), 0); + lv_obj_t * weekly_kwh_label = lv_label_create(weekly_value_box); + lv_label_set_text_static(weekly_kwh_label, "kWh"); + lv_obj_add_style(weekly_kwh_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(weekly_kwh_label, lv_color_black(), 0); + lv_obj_set_style_text_opa(weekly_kwh_label, LV_OPA_40, 0); + + return part; +} + +static void widget1_anim_height_range(lv_demo_smart_home_ctx_t * c, int32_t * min, int32_t * max) +{ + *min = c->sz->smart_meter_collapsed_part_height; + *max = c->sz->card_long_edge - c->sz->gap[7] - c->sz->smart_meter_collapsed_part_height; +} + +static void widget1_open_part1_anim_cb(void * arg, int32_t val) +{ + lv_obj_t * box = arg; + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(box); + lv_obj_t * part1 = lv_obj_get_child(box, 0); + lv_obj_t * part2 = lv_obj_get_child(box, 1); + int32_t min; + int32_t max; + widget1_anim_height_range(c, &min, &max); + lv_obj_set_height(part1, lv_map(val, 0, 1000, min, max)); + lv_obj_set_style_bg_image_opa(part1, lv_map(val, 0, 1000, 255, 0), 0); + lv_obj_set_style_bg_image_opa(part2, lv_map(val, 0, 1000, 0, 255), 0); + lv_obj_set_style_opa(lv_obj_get_child(part1, 1), lv_map(val, 0, 1000, 0, 255), 0); + lv_obj_set_style_opa(lv_obj_get_child(part2, 1), lv_map(val, 0, 1000, 255, 0), 0); + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(&c->th); + if(th == &lv_demo_smart_home_theme_dark) { + int32_t g = lv_map(val, 0, 1000, 0, 255); + int32_t ginv = 255 - g; + lv_obj_set_style_text_color(lv_obj_get_child(part1, 0), th == &lv_demo_smart_home_theme_light + ? lv_color_make(g, g, g) : lv_color_make(ginv, ginv, ginv), 0); + lv_obj_set_style_text_color(lv_obj_get_child(part2, 0), th == &lv_demo_smart_home_theme_light + ? lv_color_make(ginv, ginv, ginv) : lv_color_make(g, g, g), 0); + } +} + +static void widget1_open_part2_anim_cb(void * arg, int32_t val) +{ + lv_obj_t * box = arg; + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(box); + lv_obj_t * part1 = lv_obj_get_child(box, 0); + lv_obj_t * part2 = lv_obj_get_child(box, 1); + int32_t min; + int32_t max; + widget1_anim_height_range(c, &min, &max); + lv_obj_set_height(part1, lv_map(val, 0, 1000, max, min)); + lv_obj_set_style_bg_image_opa(part1, lv_map(val, 0, 1000, 0, 255), 0); + lv_obj_set_style_bg_image_opa(part2, lv_map(val, 0, 1000, 255, 0), 0); + lv_obj_set_style_opa(lv_obj_get_child(part1, 1), lv_map(val, 0, 1000, 255, 0), 0); + lv_obj_set_style_opa(lv_obj_get_child(part2, 1), lv_map(val, 0, 1000, 0, 255), 0); + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(&c->th); + if(th == &lv_demo_smart_home_theme_dark) { + int32_t g = lv_map(val, 0, 1000, 0, 255); + int32_t ginv = 255 - g; + lv_obj_set_style_text_color(lv_obj_get_child(part1, 0), th == &lv_demo_smart_home_theme_light + ? lv_color_make(ginv, ginv, ginv) : lv_color_make(g, g, g), 0); + lv_obj_set_style_text_color(lv_obj_get_child(part2, 0), th == &lv_demo_smart_home_theme_light + ? lv_color_make(g, g, g) : lv_color_make(ginv, ginv, ginv), 0); + } +} + +static void widget1_clicked_cb(lv_event_t * e) +{ + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + lv_obj_t * part = lv_event_get_current_target_obj(e); + lv_obj_t * box = lv_obj_get_parent(part); + lv_obj_t * part1 = lv_obj_get_child(box, 0); + bool open_part1 = part == part1; + + if(lv_anim_get(box, NULL)) { + return; + } + int32_t part1_height = lv_obj_get_height(part1); + if((open_part1 && part1_height != c->sz->smart_meter_collapsed_part_height) + || (!open_part1 && part1_height == c->sz->smart_meter_collapsed_part_height)) { + return; + } + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_duration(&a, 325); + lv_anim_set_exec_cb(&a, open_part1 ? widget1_open_part1_anim_cb : widget1_open_part2_anim_cb); + lv_anim_set_values(&a, 0, 1000); + lv_anim_set_var(&a, box); + lv_anim_start(&a); +} + +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * box = lv_obj_create(widgets); + lv_obj_remove_style_all(box); + lv_obj_set_size(box, c->sz->card_long_edge, c->sz->card_long_edge); + lv_obj_set_flex_flow(box, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_row(box, c->sz->gap[7], 0); + lv_obj_set_user_data(box, c); + + lv_obj_t * part_title; + + lv_obj_t * part1 = create_widget1_part(c, box, "Self-consumption", "14.71", "89.32"); + lv_obj_set_height(part1, c->sz->smart_meter_collapsed_part_height); + lv_obj_set_style_opa(lv_obj_get_child(part1, 1), LV_OPA_TRANSP, 0); + part_title = lv_obj_get_child(part1, 0); + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(&c->th); + lv_obj_set_style_text_color(part_title, th == &lv_demo_smart_home_theme_light ? lv_color_black() : lv_color_white(), 0); + + lv_obj_t * part2 = create_widget1_part(c, box, "Production", "12.56", "90.28"); + lv_obj_set_flex_grow(part2, 1); + lv_obj_set_style_bg_image_opa(part2, LV_OPA_TRANSP, 0); + part_title = lv_obj_get_child(part2, 0); + lv_obj_set_style_text_color(part_title, lv_color_black(), 0); + + lv_obj_add_event_cb(part1, widget1_clicked_cb, LV_EVENT_CLICKED, c); + lv_obj_add_event_cb(part2, widget1_clicked_cb, LV_EVENT_CLICKED, c); +} + +static lv_obj_t * widget23_chart_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text) +{ + lv_obj_t * label = lv_label_create(parent); + lv_label_set_text_static(label, text); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(label, LV_OPA_40, 0); + return label; +} + +static void widget2_chart_event_draw_task_cb(lv_event_t * e) +{ + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + lv_subject_get_int(&c->smart_meter_selected_bar); +} + +static void widget2_chart_bar_clicked_cb(lv_event_t * e) +{ + lv_obj_t * chart = lv_event_get_target_obj(e); + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + uint32_t clicked_bar = lv_chart_get_pressed_point(chart); + + lv_subject_set_int(&c->smart_meter_selected_bar, clicked_bar); +} + +static void widget2_chart_selected_day_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * chart = lv_observer_get_target_obj(observer); + lv_obj_invalidate(chart); +} + +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET1_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + lv_obj_set_style_pad_row(widget, 18, 0); + + lv_obj_t * title_label = lv_label_create(widget); + lv_label_set_text_static(title_label, "Daily usage"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * usage_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + + lv_obj_t * date_label = lv_label_create(usage_box); + lv_label_set_text_static(date_label, "August 30, 2024"); + lv_obj_add_style(date_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(date_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * amount_box = lv_demo_smart_home_simple_container_create(usage_box, false, c->sz->gap[1], LV_FLEX_ALIGN_END); + + lv_obj_t * amount_number = lv_label_create(amount_box); + lv_label_set_text_static(amount_number, "15"); + lv_obj_add_style(amount_number, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(amount_number, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * amount_kwh = lv_label_create(amount_box); + lv_label_set_text_static(amount_kwh, "kWh"); + lv_obj_add_style(amount_kwh, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(amount_kwh, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(amount_kwh, LV_OPA_40, 0); + + lv_obj_t * chart_grid = lv_obj_create(widget); + lv_obj_remove_style_all(chart_grid); + lv_obj_set_size(chart_grid, LV_PCT(100), LV_SIZE_CONTENT); + static const int32_t column_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + static const int32_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_style_grid_column_dsc_array(chart_grid, column_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(chart_grid, row_dsc, 0); + lv_obj_set_layout(chart_grid, LV_LAYOUT_GRID); + lv_obj_set_style_pad_column(chart_grid, c->sz->gap[3], 0); + lv_obj_set_style_pad_row(chart_grid, 5, 0); + + lv_obj_t * chart = lv_chart_create(chart_grid); + lv_obj_set_height(chart, c->sz->small_chart_height); + lv_obj_set_style_bg_opa(chart, LV_OPA_MIN + 1, 0); + lv_obj_set_style_pad_column(chart, c->sz->gap[1], 0); + lv_obj_set_style_radius(chart, c->sz->gap[3], LV_PART_ITEMS); + lv_obj_set_style_border_width(chart, 2, 0); + lv_obj_set_style_border_color(chart, lv_color_black(), 0); + lv_obj_set_style_border_side(chart, LV_BORDER_SIDE_BOTTOM, 0); + lv_obj_set_style_border_post(chart, true, 0); + lv_obj_set_style_radius(chart, 0, 0); + lv_obj_set_style_pad_all(chart, 0, 0); + + lv_obj_add_event_cb(chart, widget2_chart_event_draw_task_cb, LV_EVENT_DRAW_TASK_ADDED, c); + lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + + lv_obj_set_grid_cell(chart, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1); + lv_chart_set_type(chart, LV_CHART_TYPE_BAR); + lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 101); + lv_chart_set_div_line_count(chart, 3, 0); + lv_obj_set_style_line_opa(chart, LV_OPA_40, 0); + lv_obj_set_style_line_color(chart, lv_color_black(), 0); + lv_obj_set_style_line_dash_width(chart, 2, 0); + lv_obj_set_style_line_dash_gap(chart, 1, 0); + lv_chart_series_t * ser = lv_chart_add_series(chart, lv_color_white(), LV_CHART_AXIS_PRIMARY_Y); + static const int32_t chart_values[] = {45, 14, 45, 52, 69, 52, 63}; + lv_chart_set_ext_y_array(chart, ser, (int32_t *)chart_values); + lv_chart_set_point_count(chart, sizeof(chart_values) / sizeof(*chart_values)); + lv_chart_refresh(chart); + + lv_obj_add_event_cb(chart, widget2_chart_bar_clicked_cb, LV_EVENT_VALUE_CHANGED, c); + lv_subject_add_observer_obj(&c->smart_meter_selected_bar, widget2_chart_selected_day_observer_cb, chart, NULL); + + lv_obj_t * hscale_label_1 = widget23_chart_label(c, chart_grid, "Aug 2"); + lv_obj_set_grid_cell(hscale_label_1, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 1, 1); + lv_obj_t * hscale_label_2 = widget23_chart_label(c, chart_grid, "Sep 1"); + lv_obj_set_grid_cell(hscale_label_2, LV_GRID_ALIGN_END, 0, 1, LV_GRID_ALIGN_START, 1, 1); + + lv_obj_t * vscale_label_1 = widget23_chart_label(c, chart_grid, "20"); + lv_obj_set_grid_cell(vscale_label_1, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 0, 1); + lv_obj_t * vscale_label_2 = widget23_chart_label(c, chart_grid, "10"); + lv_obj_set_grid_cell(vscale_label_2, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_t * vscale_label_3 = widget23_chart_label(c, chart_grid, "0"); + lv_obj_set_grid_cell(vscale_label_3, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_END, 0, 1); +} + +static void widget3_chart_draw_task_event_cb(lv_event_t * e) +{ + lv_draw_task_t * t = lv_event_get_draw_task(e); +} + +static void widget3_chart_free_anim_values(lv_event_t * e) +{ + lv_obj_t * chart = lv_event_get_target_obj(e); + widget3_chart_anim_values_t * anim_values = lv_obj_get_user_data(chart); + lv_free(anim_values); +} + +static void widget3_chart_anim_cb(void * var, int32_t v) +{ + lv_obj_t * chart = var; + widget3_chart_anim_values_t * anim_values = lv_obj_get_user_data(chart); + int32_t * end_values = lv_anim_get_user_data(lv_anim_get(var, widget3_chart_anim_cb)); + + for(int32_t i = 0; i < WIDGET3_POINT_COUNT; i++) { + anim_values->current[i] = lv_map(v, 0, WIDGET3_ANIM_RANGE_END, anim_values->start[i], end_values[i]); + } + + lv_chart_refresh(chart); +} + +static void widget3_chart_selected_day_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + static bool data_is_init = false; + static int32_t data[WIDGET3_POINT_COUNT * 7]; + if(!data_is_init) { + data_is_init = true; + for(int32_t i = 0; i < WIDGET3_POINT_COUNT * 7; i++) { + data[i] = lv_map(-lv_trigo_cos(i * 15), -32767, 32767, -105, 105) + lv_rand(-20, 20); + } + } + + lv_obj_t * chart = lv_observer_get_target_obj(observer); + int32_t idx = lv_subject_get_int(subject); + + widget3_chart_anim_values_t * anim_values = lv_obj_get_user_data(chart); + if(!anim_values) { + anim_values = lv_malloc_zeroed(sizeof(widget3_chart_anim_values_t)); + LV_ASSERT_MALLOC(anim_values); + lv_obj_set_user_data(chart, anim_values); + lv_obj_add_event_cb(chart, widget3_chart_free_anim_values, LV_EVENT_DELETE, NULL); + + lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL); + } + + lv_memcpy(anim_values->start, anim_values->current, sizeof(anim_values->current)); + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, chart); + lv_anim_set_duration(&a, 400); + lv_anim_set_values(&a, 0, WIDGET3_ANIM_RANGE_END); + lv_anim_set_exec_cb(&a, widget3_chart_anim_cb); + lv_anim_set_user_data(&a, &data[idx * WIDGET3_POINT_COUNT]); + lv_anim_set_early_apply(&a, true); + lv_anim_start(&a); +} + +static lv_obj_t * create_widget3_stat(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * title_val, + const char * kwh_val, const char * detail_val) +{ + lv_obj_t * obj = lv_demo_smart_home_simple_container_create(parent, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_set_flex_grow(obj, 1); + + lv_obj_t * title_label = lv_label_create(obj); + lv_label_set_text_static(title_label, title_val); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * kwh_box = lv_demo_smart_home_simple_container_create(obj, false, c->sz->gap[1], LV_FLEX_ALIGN_END); + + lv_obj_t * kwh_value_label = lv_label_create(kwh_box); + lv_label_set_text_static(kwh_value_label, kwh_val); + lv_obj_add_style(kwh_value_label, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(kwh_value_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * kwh_label = lv_label_create(kwh_box); + lv_label_set_text_static(kwh_label, "kWh"); + lv_obj_add_style(kwh_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(kwh_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(kwh_label, LV_OPA_60, 0); + + lv_obj_t * detail_label = lv_label_create(obj); + lv_label_set_text_static(detail_label, detail_val); + lv_obj_add_style(detail_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(detail_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(detail_label, LV_OPA_60, 0); + + return obj; +} + +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.w, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.h); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET5_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + + lv_obj_t * title_label = lv_label_create(widget); + lv_label_set_text_static(title_label, "Balance"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * chart_grid = lv_obj_create(widget); + lv_obj_remove_style_all(chart_grid); + lv_obj_set_size(chart_grid, LV_PCT(100), LV_SIZE_CONTENT); + static const int32_t column_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + static const int32_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_style_grid_column_dsc_array(chart_grid, column_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(chart_grid, row_dsc, 0); + lv_obj_set_layout(chart_grid, LV_LAYOUT_GRID); + lv_obj_set_style_pad_column(chart_grid, c->sz->gap[3], 0); + lv_obj_set_style_pad_row(chart_grid, 5, 0); + + lv_obj_t * chart = lv_chart_create(chart_grid); + lv_obj_set_height(chart, c->sz->large_chart_height); + lv_obj_set_style_bg_opa(chart, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_column(chart, c->sz->gap[1], 0); + lv_obj_set_style_radius(chart, c->sz->gap[3], LV_PART_ITEMS); + lv_obj_set_style_border_side(chart, LV_BORDER_SIDE_NONE, 0); + lv_obj_set_style_radius(chart, 0, 0); + lv_obj_set_style_pad_all(chart, 5, 0); + lv_obj_set_grid_cell(chart, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1); + lv_chart_set_type(chart, LV_CHART_TYPE_BAR); + lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, -125, 125); + lv_chart_set_div_line_count(chart, 3, 0); + lv_obj_set_style_line_opa(chart, LV_OPA_40, 0); + lv_obj_set_style_line_color(chart, lv_color_black(), 0); + lv_obj_set_style_line_dash_width(chart, 2, 0); + lv_obj_set_style_line_dash_gap(chart, 1, 0); + lv_obj_add_event_cb(chart, widget3_chart_draw_task_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); + lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + lv_chart_add_series(chart, lv_color_white(), LV_CHART_AXIS_PRIMARY_Y); + lv_chart_set_point_count(chart, WIDGET3_POINT_COUNT); + lv_subject_add_observer_obj(&c->smart_meter_selected_bar, widget3_chart_selected_day_observer_cb, chart, NULL); + + lv_obj_t * hscale_label_1 = widget23_chart_label(c, chart_grid, "0h"); + lv_obj_set_grid_cell(hscale_label_1, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 1, 1); + lv_obj_t * hscale_label_2 = widget23_chart_label(c, chart_grid, "24h"); + lv_obj_set_grid_cell(hscale_label_2, LV_GRID_ALIGN_END, 0, 1, LV_GRID_ALIGN_START, 1, 1); + + lv_obj_t * vscale_label_1 = widget23_chart_label(c, chart_grid, "5"); + lv_obj_set_grid_cell(vscale_label_1, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 0, 1); + lv_obj_t * vscale_label_2 = widget23_chart_label(c, chart_grid, "0\nkWh"); + lv_obj_set_grid_cell(vscale_label_2, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_t * vscale_label_3 = widget23_chart_label(c, chart_grid, "-5"); + lv_obj_set_grid_cell(vscale_label_3, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_END, 0, 1); + + lv_obj_t * stat_box = lv_demo_smart_home_simple_container_create(widget, false, c->sz->gap[5], LV_FLEX_ALIGN_CENTER); + lv_obj_set_width(stat_box, LV_PCT(100)); + create_widget3_stat(c, stat_box, "Sep 1, 2024", "+12", "P: +36kWh U: -18kWh"); + create_widget3_stat(c, stat_box, "Week 41", "-56", "P: +243kWh U: -299kWh"); +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_app_thermostat.c b/smart_home/lv_demo_smart_home_app_thermostat.c new file mode 100644 index 0000000000000000000000000000000000000000..41e3928f9b5d210fc294ecf926ab959a788e6935 --- /dev/null +++ b/smart_home/lv_demo_smart_home_app_thermostat.c @@ -0,0 +1,620 @@ +/** + * @file lv_demo_smart_home_app_thermostat.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void back_clicked_cb(lv_event_t * e); +static lv_obj_t * widget1_chart_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text); +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static void widget2_slider_changed_cb(lv_event_t * e); +static void widget2_temperature_button_clicked_cb(lv_event_t * e); +static lv_obj_t * create_widget2_value(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * title_val, + const char * range_val, int32_t temperature_val); +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); +static lv_obj_t * create_widget3_setting(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const lv_image_dsc_t * img_dsc, + const char * text_val, bool active); +static void widget3_setting_clicked_cb(lv_event_t * e); +static void widget3_scale_and_arc_box_ext_draw_size_event_cb(lv_event_t * e); +static void temperature_arc_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void temperature_arc_changed_cb(lv_event_t * e); +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_smart_home_app_thermostat(lv_obj_t * base_obj) +{ + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + /* background */ + + lv_obj_t * bg = base_obj; + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); + + lv_obj_t * bg_img = lv_image_create(bg); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, bg_img, + &c->imgs[IMG_LIGHT_BG_THERMOSTAT]); + + lv_obj_t * bg_cont = lv_obj_create(bg); + lv_obj_remove_style_all(bg_cont); + lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0); + int32_t app_padding = c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10]; + lv_obj_set_style_pad_bottom(bg_cont, app_padding, 0); + lv_obj_set_style_pad_hor(bg_cont, app_padding, 0); + + /* top margin */ + + lv_obj_t * top_margin = lv_demo_smart_home_top_margin_create(bg_cont, 0, true, c); + + /* app info */ + + lv_obj_t * app_info = lv_demo_smart_home_simple_container_create(bg_cont, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_align_to(app_info, top_margin, LV_ALIGN_OUT_BOTTOM_LEFT, 0, c->sz->gap[7]); + + lv_obj_t * back = lv_demo_smart_home_simple_container_create(app_info, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + lv_obj_add_event_cb(back, back_clicked_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t * back_icon = lv_image_create(back); + lv_image_set_src(back_icon, c->imgs[IMG_ARROW_LEFT]); + lv_obj_add_style(back_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(back_icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * back_label = lv_label_create(back); + lv_label_set_text_static(back_label, "Back"); + lv_obj_set_style_text_opa(back_label, LV_OPA_60, 0); + lv_obj_add_style(back_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(back_label, &c->fonts[FONT_HEADING_MD], 0); + + lv_obj_t * app_label = lv_label_create(app_info); + lv_label_set_text_static(app_label, "Thermostat"); + lv_obj_add_style(app_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(app_label, &c->fonts[FONT_HEADING_LG], 0); + + /* widgets */ + + int32_t widget_gap_padding = c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[4] : c->sz->gap[7]; + lv_obj_t * widgets = lv_demo_smart_home_simple_container_create(bg_cont, false, widget_gap_padding, LV_FLEX_ALIGN_END); + lv_obj_set_align(widgets, LV_ALIGN_BOTTOM_RIGHT); + + create_widget1(c, widgets); + create_widget2(c, widgets); + create_widget3(c, widgets); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void back_clicked_cb(lv_event_t * e) +{ + lv_obj_t * back = lv_event_get_target_obj(e); + + lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(back))); + lv_obj_clean(base_obj); + lv_demo_smart_home_home(base_obj); +} + +static lv_obj_t * widget1_chart_label(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text) +{ + lv_obj_t * label = lv_label_create(parent); + lv_label_set_text_static(label, text); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(label, LV_OPA_40, 0); + return label; +} + +static void create_widget1(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET1_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + lv_obj_set_style_pad_row(widget, 18, 0); + lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t * title_label = lv_label_create(widget); + lv_label_set_text_static(title_label, "Last 7 days"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * chart_grid = lv_obj_create(widget); + lv_obj_remove_style_all(chart_grid); + lv_obj_set_size(chart_grid, LV_PCT(100), LV_SIZE_CONTENT); + static const int32_t column_dsc[] = {LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + static const int32_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; + lv_obj_set_style_grid_column_dsc_array(chart_grid, column_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(chart_grid, row_dsc, 0); + lv_obj_set_layout(chart_grid, LV_LAYOUT_GRID); + lv_obj_set_style_pad_column(chart_grid, c->sz->gap[3], 0); + lv_obj_set_style_pad_row(chart_grid, 5, 0); + + lv_obj_t * chart = lv_chart_create(chart_grid); + // lv_chart_series_t *ser1 = lv_chart_add_series(chart, LV_COLOR_RED); + lv_obj_set_height(chart, c->sz->small_chart_height); + lv_obj_set_style_bg_opa(chart, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_column(chart, c->sz->gap[1], 0); + lv_obj_set_style_radius(chart, c->sz->gap[3], LV_PART_ITEMS); + lv_obj_set_style_border_width(chart, 2, 0); + lv_obj_set_style_border_color(chart, lv_color_black(), 0); + lv_obj_set_style_border_side(chart, LV_BORDER_SIDE_BOTTOM, 0); + lv_obj_set_style_border_post(chart, true, 0); + lv_obj_set_style_radius(chart, 0, 0); + lv_obj_set_style_pad_all(chart, 0, 0); + lv_obj_set_grid_cell(chart, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1); + lv_chart_set_type(chart, LV_CHART_TYPE_BAR); + // lv_chart_set_axis_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 109); + lv_chart_set_range(chart,LV_CHART_AXIS_PRIMARY_Y, 0, 109); + lv_chart_set_div_line_count(chart, 3, 0); + lv_obj_set_style_line_opa(chart, LV_OPA_40, 0); + lv_obj_set_style_line_color(chart, lv_color_black(), 0); + lv_obj_set_style_line_dash_width(chart, 2, 0); + lv_obj_set_style_line_dash_gap(chart, 1, 0); + lv_chart_series_t * ser = lv_chart_add_series(chart, lv_color_white(), LV_CHART_AXIS_PRIMARY_Y); + static const int32_t chart_values[] = {14, 95, 52, 34, 52, 83, 19}; + // lv_chart_set_series_ext_y_array(chart, ser, (int32_t *)chart_values); + // ser1->points[0] = 10; + // ser1->points[1] = 20; + // ser1->points[2] = 30; + lv_chart_set_point_count(chart, sizeof(chart_values) / sizeof(*chart_values)); + lv_chart_refresh(chart); + + lv_obj_t * hscale_label_1 = widget1_chart_label(c, chart_grid, "Aug 26"); + lv_obj_set_grid_cell(hscale_label_1, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 1, 1); + lv_obj_t * hscale_label_2 = widget1_chart_label(c, chart_grid, "Sep 1"); + lv_obj_set_grid_cell(hscale_label_2, LV_GRID_ALIGN_END, 0, 1, LV_GRID_ALIGN_START, 1, 1); + + lv_obj_t * vscale_label_1 = widget1_chart_label(c, chart_grid, "20\nkWh"); + lv_obj_set_grid_cell(vscale_label_1, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 0, 1); + lv_obj_t * vscale_label_2 = widget1_chart_label(c, chart_grid, "10"); + lv_obj_set_grid_cell(vscale_label_2, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_t * vscale_label_3 = widget1_chart_label(c, chart_grid, "0"); + lv_obj_set_grid_cell(vscale_label_3, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_END, 0, 1); + + lv_obj_t * consumed_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + + lv_obj_t * consumed_label = lv_label_create(consumed_box); + lv_label_set_text_static(consumed_label, "Total energy consumed"); + lv_obj_add_style(consumed_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(consumed_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * amount_box = lv_demo_smart_home_simple_container_create(consumed_box, false, c->sz->gap[1], LV_FLEX_ALIGN_END); + + lv_obj_t * amount_number = lv_label_create(amount_box); + lv_label_set_text_static(amount_number, "102"); + lv_obj_add_style(amount_number, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(amount_number, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * amount_kwh = lv_label_create(amount_box); + lv_label_set_text_static(amount_kwh, "kWh"); + lv_obj_add_style(amount_kwh, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(amount_kwh, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(amount_kwh, LV_OPA_40, 0); +} + +static void widget2_slider_changed_cb(lv_event_t * e) +{ + lv_obj_t * slider = lv_event_get_current_target_obj(e); + lv_obj_t * slider_box = lv_obj_get_parent(slider); + lv_obj_t * label = lv_event_get_user_data(e); + int32_t val = lv_slider_get_value(slider); + + if(slider == lv_obj_get_child(slider_box, 0)) { + lv_label_set_text_fmt(label, "9pm - %"PRId32"am", val != 0 ? val : 12); + } + else { + val = 6 - val + 6; + lv_label_set_text_fmt(label, "%"PRId32"%s - 9pm", val, val < 12 ? "am" : "pm"); + } +} + +static void widget2_temperature_button_clicked_cb(lv_event_t * e) +{ + lv_obj_t * button = lv_event_get_current_target_obj(e); + lv_obj_t * box = lv_obj_get_parent(button); + lv_obj_t * label = lv_obj_get_child(box, 1); + int32_t label_val = (int32_t)(intptr_t)lv_obj_get_user_data(label); + int32_t change = button == lv_obj_get_child(box, 0) ? -1 : 1; + label_val += change; + lv_label_set_text_fmt(label, "%"LV_PRId32, label_val); + lv_obj_set_user_data(label, (void *)(intptr_t)label_val); +} + +static lv_obj_t * create_widget2_value(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * title_val, + const char * range_val, int32_t temperature_val) +{ + lv_obj_t * box = lv_demo_smart_home_simple_container_create(parent, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + lv_obj_set_flex_grow(box, 1); + + lv_obj_t * title_label = lv_label_create(box); + lv_label_set_text_static(title_label, title_val); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * range_label = lv_label_create(box); + lv_label_set_text_static(range_label, range_val); + lv_obj_add_style(range_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(range_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(range_label, LV_OPA_40, 0); + + lv_obj_t * temperature_box = lv_demo_smart_home_simple_container_create(box, false, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + lv_obj_set_width(temperature_box, LV_PCT(100)); + + lv_obj_t * minus = lv_image_create(temperature_box); + lv_image_set_inner_align(minus, LV_IMAGE_ALIGN_CENTER); + lv_obj_set_size(minus, c->sz->icon[ICON_MD], c->sz->icon[ICON_MD]); + lv_obj_set_style_bg_color(minus, lv_color_white(), 0); + lv_obj_set_style_bg_opa(minus, LV_OPA_COVER, 0); + lv_obj_set_style_radius(minus, LV_COORD_MAX, 0); + lv_obj_add_flag(minus, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(minus, widget2_temperature_button_clicked_cb, LV_EVENT_CLICKED, NULL); + lv_image_set_src(minus, c->imgs[IMG_MINUS]); + + lv_obj_t * temperature_label = lv_label_create(temperature_box); + lv_obj_set_flex_grow(temperature_label, 1); + lv_obj_set_style_text_align(temperature_label, LV_TEXT_ALIGN_CENTER, 0); + lv_label_set_text_fmt(temperature_label, "%"LV_PRId32, temperature_val); + lv_obj_set_user_data(temperature_label, (void *)(intptr_t)temperature_val); + lv_obj_add_style(temperature_label, &c->fonts[FONT_LABEL_XL], 0); + lv_obj_add_style(temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * plus = lv_image_create(temperature_box); + lv_image_set_inner_align(plus, LV_IMAGE_ALIGN_CENTER); + lv_obj_set_size(plus, c->sz->icon[ICON_MD], c->sz->icon[ICON_MD]); + lv_obj_set_style_bg_color(plus, lv_color_white(), 0); + lv_obj_set_style_bg_opa(plus, LV_OPA_COVER, 0); + lv_obj_set_style_radius(plus, LV_COORD_MAX, 0); + lv_obj_add_flag(plus, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(plus, widget2_temperature_button_clicked_cb, LV_EVENT_CLICKED, NULL); + lv_image_set_src(plus, c->imgs[IMG_PLUS]); + + return box; +} + +static void create_widget2(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->sz->card_long_edge, c->sz->card_long_edge); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET1_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + lv_obj_set_style_pad_row(widget, 0, 0); + + lv_obj_t * title_label = lv_label_create(widget); + lv_label_set_text_static(title_label, "Scheduler"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * outer_slider_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[4], + LV_FLEX_ALIGN_START); + lv_obj_set_width(outer_slider_box, LV_PCT(100)); + lv_obj_set_style_pad_top(outer_slider_box, c->sz->gap[5], 0); + + lv_obj_t * slider_box = lv_demo_smart_home_simple_container_create(outer_slider_box, false, 0, LV_FLEX_ALIGN_CENTER); + lv_obj_set_width(slider_box, LV_PCT(100)); + lv_obj_set_style_radius(slider_box, c->sz->gap[4], 0); + lv_obj_set_style_bg_color(slider_box, lv_color_white(), 0); + lv_obj_set_style_bg_opa(slider_box, LV_OPA_20, 0); + + lv_obj_t * slider_left = lv_slider_create(slider_box); + lv_slider_set_range(slider_left, 0, 6); + lv_slider_set_value(slider_left, 4, LV_ANIM_OFF); + lv_obj_set_size(slider_left, LV_PCT(50), c->sz->slider_width); + lv_obj_set_style_bg_opa(slider_left, LV_OPA_TRANSP, 0); + lv_obj_set_style_bg_color(slider_left, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_radius(slider_left, c->sz->gap[4], 0); + lv_obj_set_style_radius(slider_left, c->sz->gap[4], LV_PART_INDICATOR); + lv_obj_set_style_bg_color(slider_left, lv_color_black(), LV_PART_KNOB); + lv_obj_set_style_pad_right(slider_left, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB); + lv_obj_set_style_pad_left(slider_left, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB); + lv_obj_set_style_pad_ver(slider_left, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB); + + lv_obj_t * slider_right = lv_slider_create(slider_box); + lv_slider_set_range(slider_right, 6, 0); + lv_slider_set_value(slider_right, 5, LV_ANIM_OFF); + lv_obj_set_size(slider_right, LV_PCT(50), c->sz->slider_width); + lv_obj_set_style_bg_opa(slider_right, LV_OPA_TRANSP, 0); + lv_obj_set_style_bg_color(slider_right, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_radius(slider_right, c->sz->gap[4], 0); + lv_obj_set_style_radius(slider_right, c->sz->gap[4], LV_PART_INDICATOR); + lv_obj_set_style_bg_color(slider_right, lv_color_black(), LV_PART_KNOB); + lv_obj_set_style_pad_right(slider_right, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB); + lv_obj_set_style_pad_left(slider_right, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB); + lv_obj_set_style_pad_ver(slider_right, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB); + + lv_obj_t * slider_label_box = lv_obj_create(outer_slider_box); + lv_obj_remove_style_all(slider_label_box); + lv_obj_set_size(slider_label_box, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(slider_label_box, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(slider_label_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t * slider_label_left = lv_label_create(slider_label_box); + lv_label_set_text_static(slider_label_left, "12am"); + lv_obj_add_style(slider_label_left, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(slider_label_left, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(slider_label_left, LV_OPA_40, 0); + + lv_obj_t * slider_label_right = lv_label_create(slider_label_box); + lv_label_set_text_static(slider_label_right, "12pm"); + lv_obj_add_style(slider_label_right, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(slider_label_right, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(slider_label_right, LV_OPA_40, 0); + + lv_obj_t * values_box = lv_obj_create(outer_slider_box); + lv_obj_remove_style_all(values_box); + lv_obj_set_size(values_box, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(values_box, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(values_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_top(values_box, c->sz->gap[7], 0); + lv_obj_set_style_pad_column(values_box, c->sz->gap[5], 0); + + lv_obj_t * value1 = create_widget2_value(c, values_box, "Sleep", "9pm - 4am", 21); + lv_obj_add_event_cb(slider_left, widget2_slider_changed_cb, LV_EVENT_VALUE_CHANGED, lv_obj_get_child(value1, 1)); + lv_obj_t * value2 = create_widget2_value(c, values_box, "Home", "7am - 9pm", 23); + lv_obj_add_event_cb(slider_right, widget2_slider_changed_cb, LV_EVENT_VALUE_CHANGED, lv_obj_get_child(value2, 1)); +} + +static lv_obj_t * create_widget3_setting(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const lv_image_dsc_t * img_dsc, + const char * text_val, bool active) +{ + lv_obj_t * setting = lv_obj_create(parent); + lv_obj_remove_style_all(setting); + lv_obj_set_size(setting, c->sz->indicator_width, c->sz->indicator_height); + lv_obj_set_flex_flow(setting, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(setting, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(setting, 0, 0); + lv_obj_set_style_bg_color(setting, lv_color_white(), 0); + lv_obj_set_style_bg_opa(setting, active ? LV_OPA_60 : LV_OPA_20, 0); + lv_obj_set_style_radius(setting, c->sz->gap[3], 0); + lv_obj_set_style_pad_all(setting, c->sz->gap[5], 0); + lv_obj_add_flag(setting, LV_OBJ_FLAG_CLICKABLE); + + lv_obj_t * icon = lv_image_create(setting); + lv_image_set_src(icon, img_dsc); + lv_image_set_inner_align(icon, LV_IMAGE_ALIGN_CENTER); + lv_obj_set_size(icon, c->sz->icon[ICON_XL], c->sz->icon[ICON_XL]); + lv_obj_set_style_bg_color(icon, lv_color_white(), 0); + lv_obj_set_style_bg_opa(icon, active ? LV_OPA_COVER : LV_OPA_40, 0); + lv_obj_set_style_radius(icon, LV_COORD_MAX, 0); + lv_obj_set_style_shadow_width(icon, 50, 0); + lv_obj_set_style_shadow_opa(icon, 15 * 255 / 100, 0); + lv_obj_add_flag(icon, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t * label = lv_label_create(setting); + lv_label_set_text_static(label, text_val); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + return setting; +} + +static void widget3_setting_clicked_cb(lv_event_t * e) +{ + lv_obj_t * setting = lv_event_get_target_obj(e); + lv_obj_t * setting_box = lv_obj_get_parent(setting); + lv_obj_t * setting1 = lv_obj_get_child(setting_box, 0); + lv_obj_t * setting2 = lv_obj_get_child(setting_box, 1); + lv_obj_t * setting3 = lv_obj_get_child(setting_box, 2); + if(setting == setting1) { + lv_obj_set_style_bg_opa(setting1, LV_OPA_60, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting1, 0), LV_OPA_COVER, 0); + lv_obj_set_style_bg_opa(setting2, LV_OPA_20, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting2, 0), LV_OPA_40, 0); + lv_obj_set_style_bg_opa(setting3, LV_OPA_20, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting3, 0), LV_OPA_40, 0); + } + else if(setting == setting2) { + lv_obj_set_style_bg_opa(setting1, LV_OPA_20, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting1, 0), LV_OPA_40, 0); + lv_obj_set_style_bg_opa(setting2, LV_OPA_60, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting2, 0), LV_OPA_COVER, 0); + lv_obj_set_style_bg_opa(setting3, LV_OPA_20, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting3, 0), LV_OPA_40, 0); + } + else { + lv_obj_set_style_bg_opa(setting1, LV_OPA_20, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting1, 0), LV_OPA_40, 0); + lv_obj_set_style_bg_opa(setting2, LV_OPA_20, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting2, 0), LV_OPA_40, 0); + lv_obj_set_style_bg_opa(setting3, LV_OPA_60, 0); + lv_obj_set_style_bg_opa(lv_obj_get_child(setting3, 0), LV_OPA_COVER, 0); + } +} + +static void widget3_scale_and_arc_box_ext_draw_size_event_cb(lv_event_t * e) +{ + lv_event_set_ext_draw_size(e, 100); +} + +static void temperature_arc_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * arc = lv_observer_get_target_obj(observer); + lv_arc_set_value(arc, (lv_subject_get_int(subject) + 5) / 10); +} + +static void temperature_arc_changed_cb(lv_event_t * e) +{ + lv_obj_t * arc = lv_event_get_target_obj(e); + lv_subject_t * temperature_subject = lv_event_get_user_data(e); + + int32_t arc_val = lv_arc_get_value(arc); + lv_subject_set_int(temperature_subject, arc_val * 10); +} + +static void create_widget3(lv_demo_smart_home_ctx_t * c, lv_obj_t * widgets) +{ + lv_obj_t * widget = lv_obj_create(widgets); + lv_obj_remove_style_all(widget); + lv_obj_set_size(widget, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.w, c->imgs[IMG_LIGHT_WIDGET5_BG]->header.h); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_obj_bg_image_src_cb, widget, + &c->imgs[IMG_LIGHT_WIDGET5_BG]); + lv_obj_set_style_pad_all(widget, c->sz->gap[7], 0); + lv_obj_set_flex_flow(widget, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(widget, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_row(widget, c->sz->gap[5], 0); + lv_obj_remove_flag(widget, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t * title_label = lv_label_create(widget); + lv_obj_set_width(title_label, LV_PCT(100)); + lv_label_set_text_static(title_label, "Temperature"); + lv_obj_add_style(title_label, &c->fonts[FONT_LABEL_MD], 0); + lv_obj_add_style(title_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * scale_and_arc_box = lv_obj_create(widget); + lv_obj_remove_style_all(scale_and_arc_box); + lv_obj_set_size(scale_and_arc_box, LV_PCT(100), 57 * c->sz->card_long_edge / 100); + lv_obj_add_flag(scale_and_arc_box, LV_OBJ_FLAG_OVERFLOW_VISIBLE); + lv_obj_add_event_cb(scale_and_arc_box, widget3_scale_and_arc_box_ext_draw_size_event_cb, LV_EVENT_REFR_EXT_DRAW_SIZE, + c); + lv_obj_remove_flag(scale_and_arc_box, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t * scale = lv_scale_create(scale_and_arc_box); + lv_obj_set_align(scale, LV_ALIGN_TOP_MID); + lv_scale_set_mode(scale, LV_SCALE_MODE_ROUND_OUTER); + lv_obj_set_size(scale, c->sz->card_long_edge, c->sz->card_long_edge); + lv_obj_set_style_arc_opa(scale, LV_OPA_TRANSP, 0); + // lv_obj_set_style_radial_offset(scale, 12, LV_PART_ITEMS); + lv_obj_set_style_line_rounded(scale, true, LV_PART_ITEMS); + lv_obj_set_style_line_color(scale, lv_color_white(), LV_PART_ITEMS); + lv_obj_set_style_line_width(scale, 4, LV_PART_ITEMS); + lv_obj_set_style_length(scale, 1, LV_PART_ITEMS); + // lv_obj_set_style_radial_offset(scale, 12, LV_PART_INDICATOR); + lv_obj_set_style_line_rounded(scale, true, LV_PART_INDICATOR); + lv_obj_set_style_line_color(scale, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_line_width(scale, 8, LV_PART_INDICATOR); + lv_obj_set_style_length(scale, 1, LV_PART_INDICATOR); + lv_scale_set_total_tick_count(scale, 16); + lv_scale_set_angle_range(scale, 180); + lv_scale_set_rotation(scale, 180); + lv_scale_set_major_tick_every(scale, 5); + lv_scale_set_label_show(scale, false); + + lv_obj_t * arc = lv_arc_create(scale_and_arc_box); + lv_obj_set_align(arc, LV_ALIGN_TOP_MID); + lv_obj_set_size(arc, c->sz->card_long_edge, c->sz->card_long_edge); + lv_arc_set_rotation(arc, 180); + lv_arc_set_bg_angles(arc, 0, 180); + lv_arc_set_range(arc, 15, 30); + + lv_obj_set_style_arc_rounded(arc, false, 0); + lv_obj_set_style_arc_rounded(arc, false, LV_PART_INDICATOR); + lv_obj_set_style_arc_width(arc, 9, 0); + lv_obj_set_style_arc_width(arc, 9, LV_PART_INDICATOR); + lv_obj_set_style_arc_color(arc, lv_color_white(), 0); + lv_obj_set_style_arc_color(arc, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_arc_opa(arc, LV_OPA_20, 0); + + lv_obj_set_style_bg_color(arc, lv_color_white(), LV_PART_KNOB); + lv_obj_set_style_pad_all(arc, (32 - 9) / 2, LV_PART_KNOB); + lv_obj_set_style_shadow_width(arc, 24, LV_PART_KNOB); + lv_obj_set_style_shadow_opa(arc, 16 * 255 / 100, LV_PART_KNOB); + + lv_obj_t * current_temperature_box = lv_demo_smart_home_simple_container_create(scale_and_arc_box, true, c->sz->gap[2], + LV_FLEX_ALIGN_CENTER); + lv_obj_set_align(current_temperature_box, LV_ALIGN_BOTTOM_MID); + + lv_obj_t * current_temperature_val_label = lv_label_create(current_temperature_box); + lv_obj_add_style(current_temperature_val_label, &c->fonts[FONT_LABEL_2XL], 0); + lv_obj_add_style(current_temperature_val_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_subject_add_observer_obj(&c->api.subjects.thermostat_target_temperature, temperature_arc_observer_cb, arc, NULL); + lv_obj_add_event_cb(arc, temperature_arc_changed_cb, LV_EVENT_VALUE_CHANGED, + &c->api.subjects.thermostat_target_temperature); + lv_demo_smart_home_label_bind_temperature(current_temperature_val_label, &c->api.subjects.thermostat_target_temperature, + c ,true); + + lv_obj_t * current_temperature_label = lv_label_create(current_temperature_box); + lv_label_set_text_static(current_temperature_label, "Current\ntemperature"); + lv_obj_add_style(current_temperature_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(current_temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_align(current_temperature_label, LV_TEXT_ALIGN_CENTER, 0); + + lv_obj_t * setting_box = lv_obj_create(widget); + lv_obj_remove_style_all(setting_box); + lv_obj_set_size(setting_box, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_flex_flow(setting_box, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(setting_box, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_column(setting_box, 0, 0); + lv_obj_t * setting1 = create_widget3_setting(c, setting_box, c->imgs[IMG_COLD_ICON], "Cold", true); + lv_obj_t * setting2 = create_widget3_setting(c, setting_box, c->imgs[IMG_DRY_ICON], "Dry", false); + lv_obj_t * setting3 = create_widget3_setting(c, setting_box, c->imgs[IMG_HEAT_ICON], "Heat", false); + + lv_obj_add_event_cb(setting1, widget3_setting_clicked_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(setting2, widget3_setting_clicked_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(setting3, widget3_setting_clicked_cb, LV_EVENT_CLICKED, NULL); + + lv_obj_t * slider_box = lv_demo_smart_home_simple_container_create(widget, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_set_width(slider_box, LV_PCT(100)); + lv_obj_set_style_pad_top(slider_box, 16, 0); + + lv_obj_t * fan_speed_label = lv_label_create(slider_box); + lv_label_set_text_static(fan_speed_label, "Fan Speed"); + lv_obj_add_style(fan_speed_label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(fan_speed_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + + lv_obj_t * slider = lv_slider_create(slider_box); + lv_obj_set_size(slider, LV_PCT(100), c->sz->slider_width); + lv_obj_set_style_bg_color(slider, lv_color_white(), 0); + lv_obj_set_style_bg_opa(slider, 30, 0); + lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_INDICATOR); + lv_obj_set_style_radius(slider, c->sz->gap[4], 0); + lv_obj_set_style_radius(slider, c->sz->gap[4], LV_PART_INDICATOR); + lv_obj_set_style_bg_color(slider, lv_color_black(), LV_PART_KNOB); + lv_obj_set_style_pad_right(slider, -(c->sz->slider_width - 6) / 2 - 8, LV_PART_KNOB); + lv_obj_set_style_pad_left(slider, -(c->sz->slider_width - 6) / 2 + 8, LV_PART_KNOB); + lv_obj_set_style_pad_ver(slider, -(c->sz->slider_width - 12) / 2, LV_PART_KNOB); + + lv_obj_t * slider_pct_label = lv_label_create(slider); + lv_obj_add_style(slider_pct_label, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(slider_pct_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_align(slider_pct_label, LV_ALIGN_RIGHT_MID, -10, 0); + + lv_slider_bind_value(slider, &c->api.subjects.thermostat_fan_speed); + lv_label_bind_text(slider_pct_label, &c->api.subjects.thermostat_fan_speed, "%"PRId32"%%"); + + lv_label_set_text_static(slider_pct_label, "40%"); + lv_slider_set_value(slider, 40, LV_ANIM_OFF); + + lv_obj_t * slider_volume_img = lv_image_create(slider); + lv_image_set_src(slider_volume_img, c->imgs[IMG_FAN]); + lv_obj_align(slider_volume_img, LV_ALIGN_LEFT_MID, 8, 0); +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_home.c b/smart_home/lv_demo_smart_home_home.c new file mode 100644 index 0000000000000000000000000000000000000000..b4b25f6cecff6f1b59aa3bb736ab3c367a9a6326 --- /dev/null +++ b/smart_home/lv_demo_smart_home_home.c @@ -0,0 +1,336 @@ +/** + * @file lv_demo_smart_home_home.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#undef LV_USE_PRIVATE_API +#define LV_USE_PRIVATE_API 1 /*Include the *_private.h LVGL headers too*/ + +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef void (*app_cb_t)(lv_obj_t * base_obj); + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void theme_observer_accent_span_cb(lv_observer_t * observer, lv_subject_t * subject); +static void app_card_click_cb(lv_event_t * e); +static void app_card_create(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text, + const lv_image_dsc_t * icon_img_dsc, app_cb_t app_cb); +static void set_light_theme_event_cb(lv_event_t * e); +static void set_dark_theme_event_cb(lv_event_t * e); +static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void date_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void hi_lo_observer_cb(lv_observer_t * observer, lv_subject_t * subject); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_demo_smart_home_home(lv_obj_t * base_obj) +{ + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + /* background */ + + lv_obj_t * bg = base_obj; + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, LV_PCT(100), LV_PCT(100)); + + lv_obj_t * bg_img = lv_image_create(bg); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, bg_img, &c->imgs[IMG_LIGHT_BG_HOME]); + + lv_obj_t * bg_cont = lv_obj_create(bg); + lv_obj_remove_style_all(bg_cont); + lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); + lv_obj_set_flex_flow(bg_cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_top(bg_cont, c->sz->gap[7], 0); + + /* top margin */ + + lv_demo_smart_home_top_margin_create(bg_cont, + c->sz == &lv_demo_smart_home_sizes_all[SIZE_SM] ? c->sz->gap[9] : c->sz->gap[10], false, c); + + /* info area */ + + lv_obj_t * info_area = lv_obj_create(bg_cont); + lv_obj_remove_style_all(info_area); + lv_obj_set_width(info_area, LV_PCT(100)); + lv_obj_set_style_pad_left(info_area, c->sz->gap[10], 0); + lv_obj_set_style_pad_right(info_area, c->sz->gap[10], 0); + lv_obj_set_flex_grow(info_area, 1); + lv_obj_set_flex_flow(info_area, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(info_area, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + lv_obj_t * date_and_time = lv_demo_smart_home_simple_container_create(info_area, true, c->sz->gap[4], + LV_FLEX_ALIGN_START); + + lv_obj_t * date = lv_spangroup_create(date_and_time); + lv_obj_add_style(date, &c->fonts[FONT_HEADING_MD], 0); + lv_obj_add_style(date, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_spangroup_new_span(date); + lv_span_t * day_and_month = lv_spangroup_new_span(date); + lv_subject_add_observer_obj(&c->th, theme_observer_accent_span_cb, date, day_and_month); + lv_subject_add_observer_obj(&c->subject_groups.date.group, date_observer_cb, date, c); + + lv_obj_t * time = lv_spangroup_create(date_and_time); + lv_obj_add_style(time, &c->fonts[FONT_HEADING_XXL], 0); + lv_obj_add_style(time, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_spangroup_new_span(time); + lv_span_t * minute = lv_spangroup_new_span(time); + lv_subject_add_observer_obj(&c->th, theme_observer_accent_span_cb, time, minute); + lv_subject_add_observer_obj(&c->subject_groups.time.group, time_observer_cb, time, c); + + lv_obj_t * weather = lv_demo_smart_home_simple_container_create(info_area, false, 50, LV_FLEX_ALIGN_END); + lv_obj_t * weather_left = lv_demo_smart_home_simple_container_create(weather, true, c->sz->gap[2], LV_FLEX_ALIGN_START); + + lv_obj_t * weather_img = lv_image_create(weather_left);//CONFIG_LVX_SMART_HOME_LOGO_PATH + lv_image_set_src(weather_img, c->imgs[IMG_WEATHER]);//c->imgs[IMG_WEATHER] + lv_obj_add_style(weather_img, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + + lv_obj_t * weather_left_bottom = lv_demo_smart_home_simple_container_create(weather_left, true, c->sz->gap[3], + LV_FLEX_ALIGN_START); + + lv_obj_t * weather_label = lv_label_create(weather_left_bottom); + lv_label_set_text_static(weather_label, "Cloudy"); + lv_obj_add_style(weather_label, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(weather_label, &c->fonts[FONT_LABEL_MD], 0); + + lv_obj_t * weather_hi_lo_label = lv_label_create(weather_left_bottom); + lv_obj_add_style(weather_hi_lo_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(weather_hi_lo_label, &c->fonts[FONT_LABEL_MD], 0); + lv_subject_add_observer_obj(&c->temperature_units_are_celsius, hi_lo_observer_cb, weather_hi_lo_label, NULL); + + lv_obj_t * weather_right = lv_demo_smart_home_simple_container_create(weather, true, c->sz->gap[2], LV_FLEX_ALIGN_CENTER); + + lv_obj_t * weather_temperature_label = lv_label_create(weather_right); + lv_obj_add_style(weather_temperature_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(weather_temperature_label, &c->fonts[FONT_HEADING_XL], 0); + lv_demo_smart_home_label_bind_temperature(weather_temperature_label, &c->api.subjects.temperature_outdoor, c,true); + + lv_obj_t * weather_temperature_location_label = lv_label_create(weather_right); + lv_label_set_text_static(weather_temperature_location_label, "Outdoor"); + lv_obj_add_style(weather_temperature_location_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(weather_temperature_location_label, &c->fonts[FONT_LABEL_MD], 0); + + /* apps */ + + lv_obj_t * apps = lv_obj_create(bg_cont); + lv_obj_remove_style_all(apps); + lv_obj_set_size(apps, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_bottom(apps, c->sz->gap[10], 0); + lv_obj_set_style_pad_left(apps, c->sz->gap[10], 0); + lv_obj_set_style_pad_right(apps, c->sz->gap[10], 0); + lv_obj_set_style_border_side(apps, LV_BORDER_SIDE_BOTTOM, 0); + lv_obj_set_style_border_color(apps, lv_color_black(), 0); + lv_obj_set_style_border_width(apps, 1, 0); + lv_obj_set_style_border_opa(apps, 8 * 255 / 100, 0); + lv_obj_set_flex_flow(apps, LV_FLEX_FLOW_ROW); + lv_obj_set_style_pad_column(apps, c->sz->gap[6], 0); + app_card_create(c, apps, "EV Charging", c->imgs[IMG_EV_CHARGING_APP_ICON], lv_demo_smart_home_app_ev_charging); + app_card_create(c, apps, "Smart Home", c->imgs[IMG_SMART_HOME_APP_ICON], lv_demo_smart_home_app_smart_home); + app_card_create(c, apps, "Smart Meter", c->imgs[IMG_SMART_METER_APP_ICON], lv_demo_smart_home_app_smart_meter); + app_card_create(c, apps, "Thermostat", c->imgs[IMG_THERMOSTAT_APP_ICON], lv_demo_smart_home_app_thermostat); + app_card_create(c, apps, "About", c->imgs[IMG_ABOUT_APP_ICON], lv_demo_smart_home_app_about); + + /* bottom_margin */ + + lv_obj_t * bottom_margin = lv_obj_create(bg_cont); + lv_obj_remove_style_all(bottom_margin); + lv_obj_set_size(bottom_margin, LV_PCT(100), c->sz->home_bottom_margin_height); + lv_obj_set_flex_flow(bottom_margin, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(bottom_margin, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_left(bottom_margin, c->sz->gap[10], 0); + lv_obj_set_style_pad_right(bottom_margin, c->sz->gap[10], 0); + + lv_obj_t * logo = lv_image_create(bottom_margin); + lv_obj_set_height(logo, c->sz->icon[1]); + lv_image_set_inner_align(logo, LV_IMAGE_ALIGN_STRETCH); + lv_image_set_src(logo, c->logo_path); + int32_t scale = lv_image_get_scale_y(logo); + lv_image_set_inner_align(logo, LV_IMAGE_ALIGN_DEFAULT); + lv_image_set_scale(logo, scale); + + lv_obj_t * theme_selector = lv_demo_smart_home_simple_container_create(bottom_margin, false, c->sz->gap[4], + LV_FLEX_ALIGN_CENTER); + lv_obj_set_style_pad_all(theme_selector, c->sz->gap[1], 0); /* for icon outline */ + lv_obj_set_style_pad_right(bottom_margin, lv_obj_get_style_pad_right(bottom_margin, 0) - c->sz->gap[1], + 0); /* compensate parent `bottom_margin` */ + + lv_obj_t * theme_label = lv_label_create(theme_selector); + lv_label_set_text_static(theme_label, "Theme:"); + lv_obj_add_style(theme_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(theme_label, &c->fonts[FONT_LABEL_SM], 0); + + lv_obj_t * light_theme_icon = lv_image_create(theme_selector); + lv_obj_set_style_radius(light_theme_icon, LV_COORD_MAX, 0); + lv_obj_set_style_outline_pad(light_theme_icon, -1, 0); /* FIXME */ + if(((const lv_demo_smart_home_theme_t *) lv_subject_get_pointer(&c->th)) == &lv_demo_smart_home_theme_light) + lv_obj_set_style_outline_width(light_theme_icon, 2, 0); + lv_obj_add_style(light_theme_icon, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_OBJ], 0); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, light_theme_icon, + &c->imgs[IMG_LIGHT_LIGHT_THEME_ICON]); + + lv_obj_t * dark_theme_icon = lv_image_create(theme_selector); + lv_obj_set_style_radius(dark_theme_icon, LV_COORD_MAX, 0); + lv_obj_set_style_outline_pad(dark_theme_icon, -1, 0); /* FIXME */ + if(((const lv_demo_smart_home_theme_t *) lv_subject_get_pointer(&c->th)) == &lv_demo_smart_home_theme_dark) + lv_obj_set_style_outline_width(dark_theme_icon, 2, 0); + lv_obj_add_style(dark_theme_icon, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_OBJ], 0); + lv_subject_add_observer_obj(&c->th, lv_demo_smart_home_theme_observer_image_src_cb, dark_theme_icon, + &c->imgs[IMG_LIGHT_DARK_THEME_ICON]); + + lv_obj_add_flag(light_theme_icon, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_user_data(light_theme_icon, dark_theme_icon); + lv_obj_add_event_cb(light_theme_icon, set_light_theme_event_cb, LV_EVENT_CLICKED, c); + lv_obj_add_flag(dark_theme_icon, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_user_data(dark_theme_icon, light_theme_icon); + lv_obj_add_event_cb(dark_theme_icon, set_dark_theme_event_cb, LV_EVENT_CLICKED, c); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void theme_observer_accent_span_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_span_t * span = (lv_span_t *)observer->user_data; + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(subject); + + lv_style_set_text_color(&span->style, th->accent); +} + +static void app_card_click_cb(lv_event_t * e) +{ + lv_obj_t * app_card = lv_event_get_target_obj(e); + app_cb_t app_cb = (app_cb_t)((uintptr_t)lv_event_get_user_data(e)); + + lv_obj_t * base_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(app_card))); + lv_obj_clean(base_obj); + app_cb(base_obj); +} + +static void app_card_create(lv_demo_smart_home_ctx_t * c, lv_obj_t * parent, const char * text, + const lv_image_dsc_t * icon_img_dsc, app_cb_t app_cb) +{ + if(icon_img_dsc == NULL) return; + lv_obj_t * app_card = lv_obj_create(parent); + lv_obj_remove_style_all(app_card); + lv_obj_set_size(app_card, c->sz->card_long_edge, c->sz->card_short_edge); + lv_obj_set_style_radius(app_card, c->sz->gap[6], 0); + lv_obj_set_style_bg_opa(app_card, 16 * 255 / 100, 0); + lv_obj_set_style_pad_all(app_card, c->sz->gap[7], 0); + lv_obj_add_style(app_card, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_OBJ], 0); + lv_obj_add_event_cb(app_card, app_card_click_cb, LV_EVENT_CLICKED, (void *)((lv_uintptr_t)app_cb)); + + lv_obj_t * label = lv_label_create(app_card); + lv_label_set_text(label, text); + lv_obj_set_align(label, LV_ALIGN_BOTTOM_LEFT); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_MD], 0); + + lv_obj_t * icon = lv_image_create(app_card); + lv_obj_set_size(icon, icon_img_dsc->header.w, icon_img_dsc->header.h); + lv_image_set_inner_align(icon, LV_IMAGE_ALIGN_CENTER); + lv_image_set_src(icon, icon_img_dsc); + lv_obj_set_style_bg_opa(icon, LV_OPA_COVER, 0); + lv_obj_set_style_bg_color(icon, lv_color_white(), 0); + lv_obj_set_style_radius(icon, LV_COORD_MAX, 0); + lv_obj_add_style(icon, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(icon, LV_OBJ_FLAG_EVENT_BUBBLE); +} + +static void set_light_theme_event_cb(lv_event_t * e) +{ + lv_obj_t * obj = lv_event_get_target_obj(e); + lv_obj_set_style_outline_width(obj, 2, 0); + obj = lv_obj_get_user_data(obj); + lv_obj_set_style_outline_width(obj, 0, 0); + + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(&c->th); + if(th == &lv_demo_smart_home_theme_light) return; + + lv_subject_set_pointer(&c->th, (void *)&lv_demo_smart_home_theme_light); +} + +static void set_dark_theme_event_cb(lv_event_t * e) +{ + lv_obj_t * obj = lv_event_get_target_obj(e); + lv_obj_set_style_outline_width(obj, 2, 0); + obj = lv_obj_get_user_data(obj); + lv_obj_set_style_outline_width(obj, 0, 0); + + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(&c->th); + if(th == &lv_demo_smart_home_theme_dark) return; + + lv_subject_set_pointer(&c->th, (void *)&lv_demo_smart_home_theme_dark); +} + +static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * spangroup = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + + char buf[16]; + + lv_snprintf(buf, sizeof(buf), "%02"LV_PRId32, lv_subject_get_int(&c->api.subjects.hour)); + lv_span_set_text(lv_spangroup_get_child(spangroup, 0), buf); + + lv_snprintf(buf, sizeof(buf), ":%02"LV_PRId32, lv_subject_get_int(&c->api.subjects.minute)); + lv_span_set_text(lv_spangroup_get_child(spangroup, 1), buf); + + lv_spangroup_refr_mode(spangroup); +} + +static void date_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * spangroup = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + + char buf[32]; + + lv_snprintf(buf, sizeof(buf), "%s, ", lv_subject_get_pointer(&c->api.subjects.week_day_name)); + lv_span_set_text(lv_spangroup_get_child(spangroup, 0), buf); + lv_snprintf(buf, sizeof(buf), "%"PRId32" %s", lv_subject_get_int(&c->api.subjects.month_day), + lv_subject_get_pointer(&c->api.subjects.month_name)); + lv_span_set_text(lv_spangroup_get_child(spangroup, 1), buf); + + lv_spangroup_refr_mode(spangroup); +} + +static void hi_lo_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * weather_hi_lo_label = lv_observer_get_target_obj(observer); + lv_label_set_text_static(weather_hi_lo_label, + lv_subject_get_int(subject) ? "H: 19\xc2\xb0 L: 10\xc2\xb0" : "H: 66.2\xc2\xb0 L: 50\xc2\xb0"); +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_private.h b/smart_home/lv_demo_smart_home_private.h new file mode 100644 index 0000000000000000000000000000000000000000..16e44ffb66176252d184e20b8a471174c0d99550 --- /dev/null +++ b/smart_home/lv_demo_smart_home_private.h @@ -0,0 +1,259 @@ +/** + * @file lv_demo_smart_home_private.h + * + */ + +#ifndef LV_DEMO_SMART_HOME_PRIVATE_H +#define LV_DEMO_SMART_HOME_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_smart_home.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +#define EV_CHARGING_RANGE_END 10000 + +/********************** + * TYPEDEFS + **********************/ + +enum { + IMG_ABOUT_APP_ICON = 0, + IMG_ALBUM_ART, + IMG_ARROW_LEFT, + IMG_BACKWARD_ICON, + IMG_COLD_ICON, + IMG_DOOR, + IMG_DOOR_1, + IMG_DRY_ICON, + IMG_ENERGY_ICON, + IMG_EV_CHARGING_APP_ICON, + IMG_EV_CHARGING_WIDGET3_1_BG, + IMG_EV_CHARGING_WIDGET3_BG, + IMG_FAN, + IMG_FAN2, + IMG_FAN2_1, + IMG_FORWARD_ICON, + IMG_HEALTH_ICON, + IMG_HEALTH_ICON_BOLD, + IMG_HEAT_ICON, + IMG_LAMP, + IMG_LAMP2, + IMG_LAMP2_1, + IMG_LOGOUT_ICON, + IMG_MAIN_LIGHT_SLIDER, + IMG_MINUS, + IMG_PAGER_LEFT, + IMG_PAGER_PAUSE, + IMG_PAGER_PLAY, + IMG_PAGER_RIGHT, + IMG_PLAY_ICON, + IMG_PLAY_ICON_1, + IMG_PLUS, + IMG_RANGE_ICON, + IMG_SETTING_ICON, + IMG_SETTING_ICON_BOLD, + IMG_SMART_HOME_APP_ICON, + IMG_SMART_HOME_WIDGET1_BG, + IMG_SMART_HOME_WIDGET2_BG, + IMG_SMART_METER_APP_ICON, + IMG_THERMOSTAT_APP_ICON, + IMG_TIME_ICON, + IMG_UNLOCK, + IMG_VOLUME, + IMG_WEATHER, + IMG_WIFI_ICON, + IMG_WIND, + IMG_WIND_1, + IMG_LIGHT_BG_ABOUT, + IMG_DARK_BG_ABOUT, + IMG_LIGHT_BG_EV_CHARGING, + IMG_DARK_BG_EV_CHARGING, + IMG_LIGHT_BG_HOME, + IMG_DARK_BG_HOME, + IMG_LIGHT_BG_SMART_HOME, + IMG_DARK_BG_SMART_HOME, + IMG_LIGHT_BG_SMART_METER, + IMG_DARK_BG_SMART_METER, + IMG_LIGHT_BG_THERMOSTAT, + IMG_DARK_BG_THERMOSTAT, + IMG_LIGHT_DARK_THEME_ICON, + IMG_DARK_DARK_THEME_ICON, + IMG_LIGHT_LIGHT_THEME_ICON, + IMG_DARK_LIGHT_THEME_ICON, + IMG_LIGHT_WIDGET1_BG, + IMG_DARK_WIDGET1_BG, + IMG_LIGHT_WIDGET2_BG, + IMG_DARK_WIDGET2_BG, + IMG_LIGHT_WIDGET3_BG, + IMG_DARK_WIDGET3_BG, + IMG_LIGHT_WIDGET4_BG, + IMG_DARK_WIDGET4_BG, + IMG_LIGHT_WIDGET5_BG, + IMG_DARK_WIDGET5_BG, + IMG_COUNT +}; + +enum { + STYLE_COLOR_BASE = 0, + STYLE_COLOR_ACCENT, + STYLE_COLOR_COUNT +}; + +enum { + STYLE_TYPE_OBJ = 0, + STYLE_TYPE_TEXT, + STYLE_TYPE_A8_IMG, + STYLE_TYPE_TEXTAREA, + STYLE_TYPE_TEXTAREA_CURSOR, + STYLE_TYPE_COUNT +}; + +enum { + FONT_HEADING_MD = 0, + FONT_HEADING_LG, + FONT_HEADING_XL, + FONT_HEADING_XXL, + FONT_LABEL_XS, + FONT_LABEL_SM, + FONT_LABEL_MD, + FONT_LABEL_LG, + FONT_LABEL_XL, + FONT_LABEL_2XL, + FONT_COUNT +}; + +enum { + SIZE_SM = 0, + SIZE_MD, + SIZE_LG, + SIZE_COUNT +}; + +enum { + ICON_SM = 0, + ICON_MD, + ICON_LG, + ICON_XL, + ICON_2XL, + ICON_COUNT +}; + +typedef struct { + lv_color_t base; + lv_color_t accent; +} lv_demo_smart_home_theme_t; + +typedef struct { + int32_t gap[10 + 1]; + int32_t icon[ICON_COUNT]; + int32_t card_long_edge; + int32_t widget_long_edge; + int32_t card_short_edge; + int32_t smart_home_arc_diameter; + int32_t ev_charging_arc_diameter; + int32_t smart_meter_collapsed_part_height; + int32_t slider_width; + int32_t small_chart_height; + int32_t large_chart_height; + int32_t card_radius; + int32_t settings_panel_width; + int32_t home_bottom_margin_height; + int32_t indicator_width; + int32_t indicator_height; + void (*init_fonts_cb)(lv_style_t * fonts); +} lv_demo_smart_home_sizes_t; + +typedef struct { + struct { + lv_subject_t group; + lv_subject_t * members[2]; + } time; + struct { + lv_subject_t group; + lv_subject_t * members[3]; + } date; + struct { + lv_subject_t group; + lv_subject_t * members[2]; + } wifi; +} lv_demo_smart_home_subject_groups_t; + +typedef struct { + const lv_demo_smart_home_sizes_t * sz; + lv_image_dsc_t * imgs[IMG_COUNT]; + lv_style_t styles[STYLE_COLOR_COUNT][STYLE_TYPE_COUNT]; + lv_style_t fonts[FONT_COUNT]; + lv_subject_t th; + char * logo_path; + char * slides_path; + lv_demo_smart_home_exit_cb_t exit_cb; + lv_subject_t temperature_units_are_celsius; + lv_obj_t * ev_charging_bg_cont; + lv_subject_t ev_charging_progress; + lv_subject_t co2_value; + lv_subject_t smart_meter_selected_bar; + bool top_margin_subjects_are_init; + bool wifi_connect_ui_active; + char * wifi_ssid_tmp; + char * wifi_password_tmp; + lv_subject_t top_margin_wifi_subject; + lv_subject_t top_margin_health_subject; + lv_subject_t top_margin_setting_subject; + lv_demo_smart_home_api_t api; + lv_demo_smart_home_subject_groups_t subject_groups; + lv_array_t about_slides_array; + bool about_slides_dir_exists; +} lv_demo_smart_home_ctx_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_demo_smart_home_theme_t lv_demo_smart_home_theme_light; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_demo_smart_home_theme_t lv_demo_smart_home_theme_dark; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_demo_smart_home_sizes_t lv_demo_smart_home_sizes_all[SIZE_COUNT]; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_obj_t * lv_demo_smart_home_base_obj_create(const char * assets_path, + const char * logo_path, + const char * slides_path, + lv_demo_smart_home_exit_cb_t exit_cb); + +void lv_demo_smart_home_home(lv_obj_t * base_obj); +void lv_demo_smart_home_app_smart_home(lv_obj_t * base_obj); +void lv_demo_smart_home_app_ev_charging(lv_obj_t * base_obj); +void lv_demo_smart_home_app_smart_meter(lv_obj_t * base_obj); +void lv_demo_smart_home_app_thermostat(lv_obj_t * base_obj); +void lv_demo_smart_home_app_about(lv_obj_t * base_obj); +lv_obj_t * lv_demo_smart_home_top_margin_create(lv_obj_t * parent, int32_t pad_hor, bool show_time, + lv_demo_smart_home_ctx_t * c); +void lv_demo_smart_home_top_margin_deinit_subjects(lv_demo_smart_home_ctx_t * c); + +lv_obj_t * lv_demo_smart_home_simple_container_create(lv_obj_t * parent, bool vertical, int32_t pad, + lv_flex_align_t align_cross_place); +void lv_demo_smart_home_label_bind_temperature(lv_obj_t * label, lv_subject_t * subject, lv_demo_smart_home_ctx_t * c,bool temp); +void lv_demo_smart_home_theme_observer_image_src_cb(lv_observer_t * observer, lv_subject_t * subject); +void lv_demo_smart_home_theme_observer_obj_bg_image_src_cb(lv_observer_t * observer, lv_subject_t * subject); +lv_image_dsc_t * lv_demo_smart_home_image_preload(const void * src, lv_color_format_t cf, int32_t scale); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DEMO_SMART_HOME*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DEMO_SMART_HOME_PRIVATE_H*/ diff --git a/smart_home/lv_demo_smart_home_top_margin.c b/smart_home/lv_demo_smart_home_top_margin.c new file mode 100644 index 0000000000000000000000000000000000000000..3fc7cd8ab8e2400db372c2b04645ae3d8c8d9c15 --- /dev/null +++ b/smart_home/lv_demo_smart_home_top_margin.c @@ -0,0 +1,562 @@ +/** + * @file lv_demo_smart_home_top_margin.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#undef LV_USE_PRIVATE_API +#define LV_USE_PRIVATE_API 1 /*Include the *_private.h LVGL headers too*/ +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void logout_cb(lv_event_t * e); +static lv_obj_t * create_icon(lv_obj_t * parent, lv_subject_t * subject, lv_image_dsc_t ** img_dsc_pair, + lv_demo_smart_home_ctx_t * c); +static void delete_modal_cb(lv_event_t * e); +static void icon_clicked_cb(lv_event_t * e); +static void sys_layer_clicked_cb(lv_event_t * e); +static void wifi_ssid_ip_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void wifi_button_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void wifi_button_clicked_cb(lv_event_t * e); +static void wifi_connect_ui(lv_demo_smart_home_ctx_t * c); +static void wifi_connect_ui_textarea_apply_styles(lv_demo_smart_home_ctx_t * c, lv_obj_t * ta); +static void wifi_connect_ui_join_button_clicked_cb(lv_event_t * e); +static void wifi_connect_ui_textarea_focused_cb(lv_event_t * e); +static void wifi_connect_ui_keyboard_event_cb(lv_event_t * e); +static void wifi_connect_ui_save_ssid_and_password(lv_demo_smart_home_ctx_t * c); +static void wifi_connect_ui_end(lv_demo_smart_home_ctx_t * c); +static lv_obj_t * create_wifi(lv_obj_t * parent, lv_demo_smart_home_ctx_t * c); +static void wifi_icon_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static lv_obj_t * create_perfmon(lv_obj_t * parent, lv_demo_smart_home_ctx_t * c); +#if LV_USE_PERF_MONITOR +static void perfmon_data_cb(lv_observer_t * observer, lv_subject_t * subject); +#endif +static lv_obj_t * create_settings(lv_obj_t * parent, lv_demo_smart_home_ctx_t * c); +static lv_obj_t * create_setting_label_cont(lv_obj_t * parent, const char * text, lv_demo_smart_home_ctx_t * c); +static void setting_clicked_cb(lv_event_t * e); +static void date_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(*arr)) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_demo_smart_home_top_margin_create(lv_obj_t * parent, int32_t pad_hor, bool show_time, + lv_demo_smart_home_ctx_t * c) +{ + if(!c->top_margin_subjects_are_init) { + c->top_margin_subjects_are_init = true; + lv_subject_init_int(&c->top_margin_wifi_subject, 0); + lv_subject_init_int(&c->top_margin_health_subject, 0); + lv_subject_init_int(&c->top_margin_setting_subject, 0); + } + + lv_obj_t * top_margin = lv_obj_create(parent); + lv_obj_remove_style_all(top_margin); + lv_obj_set_size(top_margin, LV_PCT(100), c->sz->gap[10]); + lv_obj_set_style_pad_hor(top_margin, pad_hor, 0); + lv_obj_set_flex_flow(top_margin, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(top_margin, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + if(show_time) { + lv_obj_t * date_label = lv_label_create(top_margin); + lv_obj_add_style(date_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(date_label, &c->fonts[FONT_LABEL_SM], 0); + lv_subject_add_observer_obj(&c->subject_groups.date.group, date_observer_cb, date_label, c); + + lv_obj_t * time_label = lv_label_create(top_margin); + lv_obj_add_style(time_label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_add_style(time_label, &c->fonts[FONT_LABEL_SM], 0); + lv_subject_add_observer_obj(&c->subject_groups.time.group, time_observer_cb, time_label, c); + } else { + lv_obj_t * logout_icon = lv_image_create(top_margin); + lv_image_set_src(logout_icon, c->imgs[IMG_LOGOUT_ICON]); + lv_obj_add_style(logout_icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + lv_obj_add_flag(logout_icon, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(logout_icon, logout_cb, LV_EVENT_CLICKED, c); + } + + lv_obj_t * top_margin_right_cluster = lv_demo_smart_home_simple_container_create(top_margin, false, c->sz->gap[6], + LV_FLEX_ALIGN_CENTER); + + lv_obj_t * wifi_icon = create_icon(top_margin_right_cluster, &c->top_margin_wifi_subject, NULL, c); + lv_image_set_src(wifi_icon, c->imgs[IMG_WIFI_ICON]); + lv_subject_add_observer_obj(&c->subject_groups.wifi.group, wifi_icon_observer_cb, wifi_icon, c); + lv_obj_t * wifi = create_wifi(lv_layer_sys(), c); + lv_obj_bind_flag_if_eq(wifi, &c->top_margin_wifi_subject, LV_OBJ_FLAG_HIDDEN, 0); + lv_obj_add_event_cb(wifi_icon, delete_modal_cb, LV_EVENT_DELETE, wifi); + lv_obj_move_to_index(wifi, 0); /* move behind other lv_layer_sys objs */ + + lv_obj_t * health_icon = create_icon(top_margin_right_cluster, &c->top_margin_health_subject, &c->imgs[IMG_HEALTH_ICON], + c); + lv_image_set_src(health_icon, c->imgs[lv_subject_get_int(&c->top_margin_health_subject) ? IMG_HEALTH_ICON_BOLD : + IMG_HEALTH_ICON]); + lv_obj_t * perfmon = create_perfmon(lv_layer_sys(), c); + lv_obj_bind_flag_if_eq(perfmon, &c->top_margin_health_subject, LV_OBJ_FLAG_HIDDEN, 0); + lv_obj_add_event_cb(health_icon, delete_modal_cb, LV_EVENT_DELETE, perfmon); + lv_obj_move_to_index(perfmon, 0); /* move behind other lv_layer_sys objs */ + + lv_obj_t * settings_icon = create_icon(top_margin_right_cluster, &c->top_margin_setting_subject, + &c->imgs[IMG_SETTING_ICON], c); + lv_image_set_src(settings_icon, c->imgs[lv_subject_get_int(&c->top_margin_setting_subject) ? IMG_SETTING_ICON_BOLD : + IMG_SETTING_ICON]); + lv_obj_t * settings = create_settings(lv_layer_sys(), c); + lv_obj_bind_flag_if_eq(settings, &c->top_margin_setting_subject, LV_OBJ_FLAG_HIDDEN, 0); + lv_obj_add_event_cb(settings_icon, delete_modal_cb, LV_EVENT_DELETE, settings); + lv_obj_move_to_index(settings, 0); /* move behind other lv_layer_sys objs */ + + lv_obj_update_layout(top_margin_right_cluster); + lv_obj_align_to(wifi, wifi_icon, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0); + lv_obj_align_to(perfmon, health_icon, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0); + lv_obj_align_to(settings, settings_icon, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0); + + return top_margin; +} + +void lv_demo_smart_home_top_margin_deinit_subjects(lv_demo_smart_home_ctx_t * c) +{ + if(!c->top_margin_subjects_are_init) return; + c->top_margin_subjects_are_init = false; + lv_observer_remove(&c->top_margin_wifi_subject); + lv_observer_remove(&c->top_margin_health_subject); + lv_observer_remove(&c->top_margin_setting_subject); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void logout_cb(lv_event_t * e) +{ + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + if(c->exit_cb) c->exit_cb(&c->api); +} + +static lv_obj_t * create_icon(lv_obj_t * parent, lv_subject_t * subject, lv_image_dsc_t ** img_dsc_pair, + lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * icon = lv_image_create(parent); + lv_obj_add_style(icon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_A8_IMG], 0); + subject->user_data = icon; + lv_obj_set_user_data(icon, img_dsc_pair); + lv_obj_add_flag(icon, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(icon, icon_clicked_cb, LV_EVENT_CLICKED, c); + return icon; +} + +static void delete_modal_cb(lv_event_t * e) +{ + if(lv_layer_sys() == NULL) return; + lv_obj_t * modal = lv_event_get_user_data(e); + lv_obj_delete(modal); +} + +static void icon_clicked_cb(lv_event_t * e) +{ + lv_obj_t * clicked_icon = lv_event_get_target_obj(e); + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + lv_subject_t * icon_subjects[] = { + &c->top_margin_wifi_subject, + &c->top_margin_health_subject, + &c->top_margin_setting_subject + }; + for(int32_t i = 0; i < (int32_t)ARRAY_LEN(icon_subjects); i++) { + lv_subject_t * subject = icon_subjects[i]; + if(subject == &c->top_margin_wifi_subject && c->wifi_connect_ui_active) continue; + lv_obj_t * icon = subject->user_data; + lv_image_dsc_t ** pair = lv_obj_get_user_data(icon); + int32_t value = icon == clicked_icon && !lv_subject_get_int(subject); + lv_subject_set_int(subject, value); + if(pair) lv_image_set_src(icon, pair[value]); + if(value) { + lv_obj_add_flag(lv_layer_sys(), LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(lv_layer_sys(), sys_layer_clicked_cb, LV_EVENT_CLICKED, clicked_icon); + } + } +} + +static void sys_layer_clicked_cb(lv_event_t * e) +{ + lv_obj_remove_event_cb(lv_layer_sys(), sys_layer_clicked_cb); + lv_obj_remove_flag(lv_layer_sys(), LV_OBJ_FLAG_CLICKABLE); + + lv_obj_t * relevant_icon = lv_event_get_user_data(e); + lv_obj_send_event(relevant_icon, LV_EVENT_CLICKED, NULL); +} + +static void wifi_ssid_ip_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * spangroup = lv_observer_get_target_obj(observer); + lv_span_t * span = (lv_span_t *)observer->user_data; + const char * ssid_ip_value = lv_subject_get_pointer(subject); + lv_span_set_text(span, ssid_ip_value ? ssid_ip_value : "(offline)"); +} + +static void wifi_button_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * label = lv_observer_get_target_obj(observer); + const char * ssid_ip_value = lv_subject_get_pointer(subject); + lv_label_set_text_static(label, ssid_ip_value ? "Disconnect" : "Connect"); +} + +static void wifi_button_clicked_cb(lv_event_t * e) +{ + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + const char * ssid_ip_value = lv_subject_get_pointer(&c->api.subjects.wifi_ssid); + if(ssid_ip_value) { + lv_subject_set_pointer(&c->api.subjects.wifi_password, NULL); + lv_subject_set_pointer(&c->api.subjects.wifi_ssid, NULL); + lv_subject_set_pointer(&c->api.subjects.wifi_ip, NULL); + } + else { + wifi_connect_ui(c); + } +} + +static void wifi_connect_ui(lv_demo_smart_home_ctx_t * c) +{ + if(c->wifi_connect_ui_active) return; + + /* close the WiFi details */ + lv_obj_send_event(lv_layer_sys(), LV_EVENT_CLICKED, NULL); + + c->wifi_connect_ui_active = true; + + lv_obj_t * kb = lv_keyboard_create(c->api.base_obj); + lv_obj_add_style(kb, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_event_cb(kb, wifi_connect_ui_keyboard_event_cb, LV_EVENT_READY, c); + lv_obj_add_event_cb(kb, wifi_connect_ui_keyboard_event_cb, LV_EVENT_CANCEL, c); + + lv_obj_t * popup = lv_obj_create(c->api.base_obj); + lv_obj_set_size(popup, c->sz->settings_panel_width, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(popup, c->sz->gap[7], 0); + lv_obj_set_flex_flow(popup, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_column(popup, c->sz->gap[4], 0); + lv_obj_set_style_radius(popup, c->sz->gap[3], 0); + lv_obj_set_style_border_width(popup, 0, 0); + lv_obj_add_style(popup, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_OBJ], 0); + + lv_obj_t * ta_ssid = lv_textarea_create(popup); + lv_obj_set_width(ta_ssid, LV_PCT(100)); + lv_textarea_set_one_line(ta_ssid, true); + lv_textarea_set_placeholder_text(ta_ssid, "SSID"); + wifi_connect_ui_textarea_apply_styles(c, ta_ssid); + lv_obj_add_event_cb(ta_ssid, wifi_connect_ui_textarea_focused_cb, LV_EVENT_FOCUSED, kb); + + lv_obj_t * ta_password = lv_textarea_create(popup); + lv_obj_set_width(ta_password, LV_PCT(100)); + lv_textarea_set_one_line(ta_password, true); + lv_textarea_set_placeholder_text(ta_password, "Password"); + lv_textarea_set_password_mode(ta_password, true); + wifi_connect_ui_textarea_apply_styles(c, ta_password); + lv_obj_add_event_cb(ta_password, wifi_connect_ui_textarea_focused_cb, LV_EVENT_FOCUSED, kb); + + lv_obj_t * btn = lv_label_create(popup); + lv_obj_add_style(btn, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(btn, lv_color_white(), 0); + lv_obj_set_style_text_align(btn, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_width(btn, LV_PCT(100)); + lv_obj_set_style_radius(btn, LV_COORD_MAX, 0); + lv_obj_set_style_pad_ver(btn, c->sz->gap[4], 0); + lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0); + lv_obj_add_style(btn, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_OBJ], 0); + lv_label_set_text_static(btn, "Join"); + lv_obj_add_event_cb(btn, wifi_connect_ui_join_button_clicked_cb, LV_EVENT_CLICKED, c); + lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE); + + lv_obj_t * wifi_icon = c->top_margin_wifi_subject.user_data; + lv_obj_align_to(popup, wifi_icon, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 0); +} + +static void wifi_connect_ui_textarea_apply_styles(lv_demo_smart_home_ctx_t * c, lv_obj_t * ta) +{ + lv_obj_add_style(ta, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXTAREA], 0); + lv_obj_add_style(ta, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXTAREA], LV_PART_TEXTAREA_PLACEHOLDER); + lv_obj_add_style(ta, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXTAREA_CURSOR], LV_PART_CURSOR | LV_STATE_FOCUSED); + lv_obj_add_style(ta, &c->fonts[FONT_LABEL_XS], 0); + + lv_obj_set_style_bg_opa(ta, 12 * 255 / 100, 0); + lv_obj_set_style_bg_opa(ta, 30 * 255 / 100, LV_STATE_FOCUSED); + lv_obj_set_style_border_width(ta, 0, 0); +} + +static void wifi_connect_ui_join_button_clicked_cb(lv_event_t * e) +{ + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + wifi_connect_ui_save_ssid_and_password(c); + wifi_connect_ui_end(c); +} + +static void wifi_connect_ui_textarea_focused_cb(lv_event_t * e) +{ + lv_obj_t * ta = lv_event_get_target_obj(e); + lv_obj_t * kb = lv_event_get_user_data(e); + lv_keyboard_set_textarea(kb, ta); +} + +static void wifi_connect_ui_keyboard_event_cb(lv_event_t * e) +{ + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_READY) { + wifi_connect_ui_save_ssid_and_password(c); + } + + wifi_connect_ui_end(c); +} + +static void wifi_connect_ui_save_ssid_and_password(lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * popup = lv_obj_get_child(c->api.base_obj, -1); + + lv_obj_t * ta_ssid = lv_obj_get_child(popup, 0); + lv_obj_t * ta_password = lv_obj_get_child(popup, 1); + + /* set the SSID after the password, so the password will be ready + * when the user is observing the SSID to get both SSID and password. + */ + lv_free(c->wifi_password_tmp); + c->wifi_password_tmp = lv_strdup(lv_textarea_get_text(ta_password)); + LV_ASSERT_MALLOC(c->wifi_password_tmp); + lv_subject_set_pointer(&c->api.subjects.wifi_password, c->wifi_password_tmp); + + lv_free(c->wifi_ssid_tmp); + c->wifi_ssid_tmp = lv_strdup(lv_textarea_get_text(ta_ssid)); + LV_ASSERT_MALLOC(c->wifi_ssid_tmp); + lv_subject_set_pointer(&c->api.subjects.wifi_ssid, c->wifi_ssid_tmp); +} + +static void wifi_connect_ui_end(lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * kb = lv_obj_get_child(c->api.base_obj, -2); + lv_obj_t * popup = lv_obj_get_child(c->api.base_obj, -1); + + lv_obj_delete(popup); + lv_obj_delete(kb); + c->wifi_connect_ui_active = false; +} + +static lv_obj_t * create_wifi(lv_obj_t * parent, lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * settings = lv_obj_create(parent); + lv_obj_remove_style_all(settings); + lv_obj_add_flag(settings, LV_OBJ_FLAG_FLOATING); + lv_obj_set_style_bg_opa(settings, LV_OPA_COVER, 0); + lv_obj_set_style_radius(settings, c->sz->gap[3], 0); + lv_obj_set_size(settings, c->sz->settings_panel_width, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(settings, c->sz->gap[7], 0); + lv_obj_add_style(settings, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_OBJ], 0); + + lv_obj_t * cont = lv_demo_smart_home_simple_container_create(settings, true, c->sz->gap[4], LV_FLEX_ALIGN_START); + lv_obj_set_width(cont, LV_PCT(100)); + + lv_obj_t * ssid = lv_spangroup_create(cont); + lv_obj_add_style(ssid, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(ssid, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_span_set_text_static(lv_spangroup_new_span(ssid), "SSID: "); + lv_span_t * ssid_value = lv_spangroup_new_span(ssid); + lv_style_set_text_opa(&ssid_value->style, LV_OPA_40); + lv_subject_add_observer_obj(&c->api.subjects.wifi_ssid, wifi_ssid_ip_observer_cb, ssid, ssid_value); + + lv_obj_t * ip = lv_spangroup_create(cont); + lv_obj_add_style(ip, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(ip, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_span_set_text_static(lv_spangroup_new_span(ip), "IP Address: "); + lv_span_t * ip_value = lv_spangroup_new_span(ip); + lv_style_set_text_opa(&ip_value->style, LV_OPA_40); + lv_subject_add_observer_obj(&c->api.subjects.wifi_ip, wifi_ssid_ip_observer_cb, ip, ip_value); + + lv_obj_t * btn = lv_label_create(cont); + lv_obj_add_style(btn, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_set_style_text_color(btn, lv_color_white(), 0); + lv_obj_set_style_text_align(btn, LV_TEXT_ALIGN_CENTER, 0); + lv_obj_set_width(btn, LV_PCT(100)); + lv_obj_set_style_radius(btn, LV_COORD_MAX, 0); + lv_obj_set_style_pad_ver(btn, c->sz->gap[4], 0); + lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0); + lv_obj_add_style(btn, &c->styles[STYLE_COLOR_ACCENT][STYLE_TYPE_OBJ], 0); + lv_subject_add_observer_obj(&c->api.subjects.wifi_ssid, wifi_button_observer_cb, btn, NULL); + lv_obj_add_event_cb(btn, wifi_button_clicked_cb, LV_EVENT_CLICKED, c); + lv_obj_add_flag(btn, LV_OBJ_FLAG_CLICKABLE); + + return settings; +} + +static void wifi_icon_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * wifi_icon = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + lv_obj_set_style_opa(wifi_icon, lv_subject_get_pointer(&c->api.subjects.wifi_ssid) + ? LV_OPA_COVER : LV_OPA_50, 0); +} + +static lv_obj_t * create_perfmon(lv_obj_t * parent, lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * perfmon = lv_obj_create(parent); + lv_obj_add_flag(perfmon, LV_OBJ_FLAG_FLOATING); + + lv_obj_set_style_border_opa(perfmon, LV_OPA_TRANSP, 0); + lv_obj_set_style_radius(perfmon, c->sz->gap[3], 0); + lv_obj_set_size(perfmon, c->sz->settings_panel_width, LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(perfmon, c->sz->gap[7], 0); + lv_obj_add_style(perfmon, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_OBJ], 0); + + lv_obj_t * cont = lv_demo_smart_home_simple_container_create(perfmon, true, 0, LV_FLEX_ALIGN_START); + lv_obj_set_width(cont, LV_PCT(100)); + lv_obj_t * lab1 = lv_label_create(cont); + lv_obj_add_style(lab1, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(lab1, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_label_set_text(lab1, "Perf. monitor is not enabled"); + +#if LV_USE_PERF_MONITOR + lv_obj_t * divider = lv_line_create(cont); + lv_obj_set_size(divider, LV_PCT(100), c->sz->gap[4]); + lv_obj_set_style_line_width(divider, 1, 0); + lv_obj_add_style(divider, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_line_opa(divider, LV_OPA_10, 0); + lv_obj_t * lab2 = lv_label_create(cont); + lv_obj_add_style(lab2, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(lab2, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_t * lab3 = lv_label_create(cont); + lv_obj_add_style(lab3, &c->fonts[FONT_LABEL_XS], 0); + lv_obj_add_style(lab3, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_style_text_opa(lab3, LV_OPA_60, 0); + + lv_display_t * disp = lv_display_get_default(); + lv_subject_add_observer_obj(&disp->perf_sysmon_backend.subject, perfmon_data_cb, cont, NULL); +#endif + return perfmon; +} + +#if LV_USE_PERF_MONITOR +static void perfmon_data_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * cont = lv_observer_get_target_obj(observer); + const lv_sysmon_perf_info_t * perf = lv_subject_get_pointer(subject); + + lv_obj_t * lab1 = lv_obj_get_child(cont, 0); + lv_obj_t * lab2 = lv_obj_get_child(cont, 2); + lv_obj_t * lab3 = lv_obj_get_child(cont, 3); + + lv_label_set_text_fmt(lab1, "%"PRIu32" FPS, %"PRIu32"%% CPU", perf->calculated.fps, perf->calculated.cpu); + lv_label_set_text_fmt(lab2, "Refresh: %"PRIu32"ms", perf->calculated.render_avg_time + perf->calculated.flush_avg_time); + lv_label_set_text_fmt(lab3, "Render / Flush: %"PRIu32"ms / %"PRIu32"ms", perf->calculated.render_avg_time, + perf->calculated.flush_avg_time); + +} +#endif + +static lv_obj_t * create_settings(lv_obj_t * parent, lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * settings = lv_obj_create(parent); + lv_obj_remove_style_all(settings); + lv_obj_add_flag(settings, LV_OBJ_FLAG_FLOATING); + lv_obj_set_style_bg_opa(settings, LV_OPA_COVER, 0); + lv_obj_set_style_radius(settings, c->sz->gap[3], 0); + lv_obj_set_size(settings, c->sz->settings_panel_width, LV_SIZE_CONTENT); + lv_obj_set_style_pad_ver(settings, c->sz->gap[5], 0); + lv_obj_add_style(settings, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_OBJ], 0); + + lv_obj_set_flex_flow(settings, LV_FLEX_FLOW_COLUMN); + + lv_obj_t * temperature_label_cont = create_setting_label_cont(settings, "Temperature", c); + lv_obj_set_style_text_opa(lv_obj_get_child(temperature_label_cont, 0), LV_OPA_60, 0); + + lv_obj_t * celsius_label_cont = create_setting_label_cont(settings, "Celsius (\xc2\xb0""C)", c); + lv_obj_set_style_bg_opa(celsius_label_cont, 255 * lv_subject_get_int(&c->temperature_units_are_celsius), 0); + + lv_obj_t * fahrenheit_label_cont = create_setting_label_cont(settings, "Fahrenheit (\xc2\xb0""F)", c); + lv_obj_set_style_bg_opa(fahrenheit_label_cont, 255 * !lv_subject_get_int(&c->temperature_units_are_celsius), 0); + + lv_obj_add_event_cb(celsius_label_cont, setting_clicked_cb, LV_EVENT_CLICKED, c); + lv_obj_add_event_cb(fahrenheit_label_cont, setting_clicked_cb, LV_EVENT_CLICKED, c); + + return settings; +} + +static lv_obj_t * create_setting_label_cont(lv_obj_t * parent, const char * text, lv_demo_smart_home_ctx_t * c) +{ + lv_obj_t * label_cont = lv_obj_create(parent); + lv_obj_remove_style_all(label_cont); + lv_obj_set_size(label_cont, LV_PCT(100), c->sz->icon[1]); + lv_obj_set_style_bg_color(label_cont, lv_color_hex(0xCC0000), 0); + lv_obj_set_style_pad_left(label_cont, c->sz->gap[7], 0); + + lv_obj_t * label = lv_label_create(label_cont); + lv_label_set_text_static(label, text); + lv_obj_add_style(label, &c->fonts[FONT_LABEL_SM], 0); + lv_obj_add_style(label, &c->styles[STYLE_COLOR_BASE][STYLE_TYPE_TEXT], 0); + lv_obj_set_align(label, LV_ALIGN_LEFT_MID); + + return label_cont; +} + +static void setting_clicked_cb(lv_event_t * e) +{ + lv_obj_t * obj = lv_event_get_target_obj(e); + lv_obj_t * parent = lv_obj_get_parent(obj); + lv_demo_smart_home_ctx_t * c = lv_event_get_user_data(e); + lv_obj_t * celsius = lv_obj_get_child(parent, 1); + lv_obj_t * fahrenheit = lv_obj_get_child(parent, 2); + if(obj == celsius) { + lv_obj_set_style_bg_opa(celsius, LV_OPA_COVER, 0); + lv_obj_set_style_bg_opa(fahrenheit, LV_OPA_TRANSP, 0); + lv_subject_set_int(&c->temperature_units_are_celsius, 1); + } + else { + lv_obj_set_style_bg_opa(fahrenheit, LV_OPA_COVER, 0); + lv_obj_set_style_bg_opa(celsius, LV_OPA_TRANSP, 0); + lv_subject_set_int(&c->temperature_units_are_celsius, 0); + } +} + +static void date_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * date_label = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + + lv_label_set_text_fmt(date_label, "%s, %"PRId32" %s", + (char *)lv_subject_get_pointer(&c->api.subjects.week_day_name), + lv_subject_get_int(&c->api.subjects.month_day), + (char *)lv_subject_get_pointer(&c->api.subjects.month_name)); +} + +static void time_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_obj_t * time_label = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + + lv_label_set_text_fmt(time_label, "%02ld:%02ld", lv_subject_get_int(&c->api.subjects.hour), + lv_subject_get_int(&c->api.subjects.minute)); +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/lv_demo_smart_home_util.c b/smart_home/lv_demo_smart_home_util.c new file mode 100644 index 0000000000000000000000000000000000000000..3f6308237db88c183243152e6c6ddb08b5c2da28 --- /dev/null +++ b/smart_home/lv_demo_smart_home_util.c @@ -0,0 +1,781 @@ +/** + * @file lv_demo_smart_home_util.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_demo_smart_home_private.h" +#if LV_USE_DEMO_SMART_HOME +#include <dirent.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void init_fonts_sm(lv_style_t * fonts); +static void init_fonts_md(lv_style_t * fonts); +static void init_fonts_lg(lv_style_t * fonts); +static void theme_observer_cb(lv_observer_t * observer, lv_subject_t * subject); +static void free_ctx_event_cb(lv_event_t * e); +static void label_text_temperature_cb(lv_observer_t * observer, lv_subject_t * subject); +static void label_text_temperature_humi_cb(lv_observer_t * observer, lv_subject_t * subject); +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +const lv_demo_smart_home_theme_t lv_demo_smart_home_theme_light = { + .base = LV_COLOR_MAKE(0xff, 0xff, 0xff), + .accent = LV_COLOR_MAKE(0xcc, 0x00, 0x00), +}; + +const lv_demo_smart_home_theme_t lv_demo_smart_home_theme_dark = { + .base = LV_COLOR_MAKE(0x00, 0x00, 0x00), + .accent = LV_COLOR_MAKE(0xe1, 0x2b, 0x17), +}; + +const lv_demo_smart_home_sizes_t lv_demo_smart_home_sizes_all[SIZE_COUNT] = { + { + .gap = {0, 2, 4, 6, 9, 12, 14, 16, 20, 24, 32}, + .icon = {16, 21, 32, 42, 64}, + .card_long_edge = 200, + .widget_long_edge = 256, + .card_short_edge = 120, + .smart_home_arc_diameter = 107, + .ev_charging_arc_diameter = 160, + .smart_meter_collapsed_part_height = 48, + .slider_width = 27, + .small_chart_height = 67, + .large_chart_height = 167, + .card_radius = 12, + .settings_panel_width = 133, + .home_bottom_margin_height = 53, + .indicator_width = 94, + .indicator_height = 85, + .init_fonts_cb = init_fonts_sm + }, + { + .gap = {0, 3, 6, 9, 12, 16, 20, 24, 30, 36, 48}, + .icon = {24, 32, 48, 64, 96}, + .card_long_edge = 300, + .widget_long_edge = 384, + .card_short_edge = 180, + .smart_home_arc_diameter = 160, + .ev_charging_arc_diameter = 240, + .smart_meter_collapsed_part_height = 72, + .slider_width = 40, + .small_chart_height = 100, + .large_chart_height = 250, + .card_radius = 18, + .settings_panel_width = 200, + .home_bottom_margin_height = 80, + .indicator_width = 141, + .indicator_height = 128, + .init_fonts_cb = init_fonts_md + }, + { + .gap = {0, 5, 10, 15, 18, 24, 30, 36, 45, 54, 72}, + .icon = {36, 48, 72, 96, 144}, + .card_long_edge = 450, + .widget_long_edge = 576, + .card_short_edge = 270, + .smart_home_arc_diameter = 240, + .ev_charging_arc_diameter = 360, + .smart_meter_collapsed_part_height = 108, + .slider_width = 60, + .small_chart_height = 150, + .large_chart_height = 375, + .card_radius = 27, + .settings_panel_width = 300, + .home_bottom_margin_height = 120, + .indicator_width = 212, + .indicator_height = 192, + .init_fonts_cb = init_fonts_lg + } +}; + +/********************** + * MACROS + **********************/ + +#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(*arr)) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_demo_smart_home_base_obj_create(const char * assets_path, + const char * logo_path, + const char * slides_path, + lv_demo_smart_home_exit_cb_t exit_cb) +{ + lv_demo_smart_home_ctx_t * c = lv_malloc_zeroed(sizeof(lv_demo_smart_home_ctx_t)); + LV_ASSERT_MALLOC(c); + lv_obj_t * base_obj = lv_obj_create(lv_screen_active()); + lv_obj_set_user_data(base_obj, c); + lv_obj_add_event_cb(base_obj, free_ctx_event_cb, LV_EVENT_DELETE, NULL); + + lv_display_t * disp = lv_display_get_default(); + int32_t hres = lv_display_get_horizontal_resolution(disp); + int32_t vres = lv_display_get_vertical_resolution(disp); + bool is_exact; + int32_t size; + + is_exact = hres == 1280 && vres == 720; + size = SIZE_MD; + + if(!is_exact) { + LV_LOG_WARN("a display size of exactly 800x480, 1280x720, or 1920x1080 is recommended for the high-res demo"); + } + c->sz = &lv_demo_smart_home_sizes_all[size]; + + static const struct { + const char * name; + lv_color_format_t cf; + } image_details[IMG_COUNT] = { + {"about_app_icon", LV_COLOR_FORMAT_ARGB8888}, + {"album_art", LV_COLOR_FORMAT_ARGB8888}, + {"arrow_left", LV_COLOR_FORMAT_ARGB8888}, + {"backward_icon", LV_COLOR_FORMAT_ARGB8888}, + {"cold_icon", LV_COLOR_FORMAT_ARGB8888}, + {"door", LV_COLOR_FORMAT_ARGB8888}, + {"door_1", LV_COLOR_FORMAT_ARGB8888}, + {"dry_icon", LV_COLOR_FORMAT_ARGB8888}, + {"energy_icon", LV_COLOR_FORMAT_ARGB8888}, + {"ev_charging_app_icon", LV_COLOR_FORMAT_ARGB8888}, + {"ev_charging_widget3_1_bg", LV_COLOR_FORMAT_ARGB8888}, + {"ev_charging_widget3_bg", LV_COLOR_FORMAT_ARGB8888}, + {"fan", LV_COLOR_FORMAT_ARGB8888}, + {"fan2", LV_COLOR_FORMAT_ARGB8888}, + {"fan2_1", LV_COLOR_FORMAT_ARGB8888}, + {"forward_icon", LV_COLOR_FORMAT_ARGB8888}, + {"health_icon", LV_COLOR_FORMAT_ARGB8888}, + {"health_icon_bold", LV_COLOR_FORMAT_ARGB8888}, + {"heat_icon", LV_COLOR_FORMAT_ARGB8888}, + {"lamp", LV_COLOR_FORMAT_ARGB8888}, + {"lamp2", LV_COLOR_FORMAT_ARGB8888}, + {"lamp2_1", LV_COLOR_FORMAT_ARGB8888}, + {"logout_icon", LV_COLOR_FORMAT_ARGB8888}, + {"main_light_slider", LV_COLOR_FORMAT_ARGB8888}, + {"minus", LV_COLOR_FORMAT_ARGB8888}, + {"pager_left", LV_COLOR_FORMAT_ARGB8888}, + {"pager_pause", LV_COLOR_FORMAT_ARGB8888}, + {"pager_play", LV_COLOR_FORMAT_ARGB8888}, + {"pager_right", LV_COLOR_FORMAT_ARGB8888}, + {"play_icon", LV_COLOR_FORMAT_ARGB8888}, + {"play_icon_1", LV_COLOR_FORMAT_ARGB8888}, + {"plus", LV_COLOR_FORMAT_ARGB8888}, + {"range_icon", LV_COLOR_FORMAT_ARGB8888}, + {"setting_icon", LV_COLOR_FORMAT_ARGB8888}, + {"setting_icon_bold", LV_COLOR_FORMAT_ARGB8888}, + {"smart_home_app_icon", LV_COLOR_FORMAT_ARGB8888}, + {"smart_home_widget1_bg", LV_COLOR_FORMAT_ARGB8888}, + {"smart_home_widget2_bg", LV_COLOR_FORMAT_ARGB8888}, + {"smart_meter_app_icon", LV_COLOR_FORMAT_ARGB8888}, + {"thermostat_app_icon", LV_COLOR_FORMAT_ARGB8888}, + {"time_icon", LV_COLOR_FORMAT_ARGB8888}, + {"unlock", LV_COLOR_FORMAT_ARGB8888}, + {"volume", LV_COLOR_FORMAT_ARGB8888}, + {"weather", LV_COLOR_FORMAT_ARGB8888}, + {"wifi_icon", LV_COLOR_FORMAT_ARGB8888}, + {"wind", LV_COLOR_FORMAT_ARGB8888}, + {"wind_1", LV_COLOR_FORMAT_ARGB8888}, + {"light_bg_about", LV_COLOR_FORMAT_NATIVE}, + {"dark_bg_about", LV_COLOR_FORMAT_NATIVE}, + {"light_bg_ev_charging", LV_COLOR_FORMAT_NATIVE}, + {"dark_bg_ev_charging", LV_COLOR_FORMAT_NATIVE}, + {"light_bg_home", LV_COLOR_FORMAT_NATIVE}, + {"dark_bg_home", LV_COLOR_FORMAT_NATIVE}, + {"light_bg_smart_home", LV_COLOR_FORMAT_NATIVE}, + {"dark_bg_smart_home", LV_COLOR_FORMAT_NATIVE}, + {"light_bg_smart_meter", LV_COLOR_FORMAT_NATIVE}, + {"dark_bg_smart_meter", LV_COLOR_FORMAT_NATIVE}, + {"light_bg_thermostat", LV_COLOR_FORMAT_NATIVE}, + {"dark_bg_thermostat", LV_COLOR_FORMAT_NATIVE}, + {"light_dark_theme_icon", LV_COLOR_FORMAT_ARGB8888}, + {"dark_dark_theme_icon", LV_COLOR_FORMAT_ARGB8888}, + {"light_light_theme_icon", LV_COLOR_FORMAT_ARGB8888}, + {"dark_light_theme_icon", LV_COLOR_FORMAT_ARGB8888}, + {"light_widget1_bg", LV_COLOR_FORMAT_ARGB8888}, + {"dark_widget1_bg", LV_COLOR_FORMAT_ARGB8888}, + {"light_widget2_bg", LV_COLOR_FORMAT_ARGB8888}, + {"dark_widget2_bg", LV_COLOR_FORMAT_ARGB8888}, + {"light_widget3_bg", LV_COLOR_FORMAT_ARGB8888}, + {"dark_widget3_bg", LV_COLOR_FORMAT_ARGB8888}, + {"light_widget4_bg", LV_COLOR_FORMAT_ARGB8888}, + {"dark_widget4_bg", LV_COLOR_FORMAT_ARGB8888}, + {"light_widget5_bg", LV_COLOR_FORMAT_ARGB8888}, + {"dark_widget5_bg", LV_COLOR_FORMAT_ARGB8888}, + }; + const char * size_prefix = size == SIZE_SM ? "sm" : size == SIZE_MD ? "md" : "lg"; + for(uint32_t i = 0; i < IMG_COUNT; i++) { + char path_buf[256]; + int chars = lv_snprintf(path_buf, sizeof(path_buf), "%s/img_lv_demo_smart_home_%s_%s.png", + assets_path, image_details[i].name, size_prefix); + LV_ASSERT(chars < (int)sizeof(path_buf)); + c->imgs[i] = lv_demo_smart_home_image_preload(path_buf, image_details[i].cf, LV_SCALE_NONE); + + + } + + for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { + for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) { + lv_style_init(&c->styles[i][j]); + } + } + for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { + lv_style_set_image_recolor_opa(&c->styles[i][STYLE_TYPE_A8_IMG], LV_OPA_COVER); + } + + for(uint32_t i = 0; i < FONT_COUNT; i++) { + lv_style_init(&c->fonts[i]); + } + c->sz->init_fonts_cb(c->fonts); + + lv_subject_init_pointer(&c->th, (void *)&lv_demo_smart_home_theme_dark); + c->th.user_data = c; + lv_subject_add_observer(&c->th, theme_observer_cb, c); + + c->logo_path = lv_strdup(logo_path); + LV_ASSERT_MALLOC(c->logo_path); + c->slides_path = lv_strdup(slides_path); + LV_ASSERT_MALLOC(c->slides_path); + + c->exit_cb = exit_cb; + + lv_subject_init_int(&c->temperature_units_are_celsius, 1); + c->ev_charging_bg_cont = NULL; + lv_subject_init_int(&c->ev_charging_progress, EV_CHARGING_RANGE_END * 0 / 100); + lv_subject_init_int(&c->co2_value, 10); + lv_subject_init_int(&c->smart_meter_selected_bar, 4); + + c->top_margin_subjects_are_init = false; + + /* API subjects */ + + /* input subjects */ + lv_subject_init_int(&c->api.subjects.hour, 9); + lv_subject_init_int(&c->api.subjects.minute, 36); + lv_subject_init_pointer(&c->api.subjects.week_day_name, "Tuesday"); + lv_subject_init_int(&c->api.subjects.month_day, 31); + lv_subject_init_pointer(&c->api.subjects.month_name, "October"); + lv_subject_init_int(&c->api.subjects.temperature_outdoor, 140); /* tenths of a degree */ + lv_subject_init_int(&c->api.subjects.temperature_indoor, 225); /* tenths of a degree */ + lv_subject_init_pointer(&c->api.subjects.wifi_ssid, NULL); + lv_subject_init_pointer(&c->api.subjects.wifi_ip, NULL); + lv_subject_init_int(&c->api.subjects.door, 0); + + /* output subjects */ + lv_subject_init_int(&c->api.subjects.music_play, 1); + lv_subject_init_pointer(&c->api.subjects.wifi_password, NULL); + + /* input+output subjects */ + lv_subject_init_int(&c->api.subjects.locked, 0); + lv_subject_init_int(&c->api.subjects.volume, 63); + lv_subject_init_int(&c->api.subjects.main_light_temperature, 50); + lv_subject_init_int(&c->api.subjects.main_light_intensity, 52); + lv_subject_init_int(&c->api.subjects.lightbulb_matter, 0); + lv_subject_init_int(&c->api.subjects.lightbulb_zigbee, 1); + lv_subject_init_int(&c->api.subjects.fan_matter, 0); + lv_subject_init_int(&c->api.subjects.fan_zigbee, 0); + lv_subject_init_int(&c->api.subjects.air_purifier, 3); + lv_subject_init_int(&c->api.subjects.thermostat_fan_speed, 40); + lv_subject_init_int(&c->api.subjects.thermostat_target_temperature, 240); /* tenths of a degree */ + + c->api.base_obj = base_obj; + c->api.user_data = NULL; + + c->subject_groups.time.members[0] = &c->api.subjects.hour; + c->subject_groups.time.members[1] = &c->api.subjects.minute; + lv_subject_init_group(&c->subject_groups.time.group, c->subject_groups.time.members, + ARRAY_LEN(c->subject_groups.time.members)); + c->subject_groups.date.members[0] = &c->api.subjects.week_day_name; + c->subject_groups.date.members[1] = &c->api.subjects.month_day; + c->subject_groups.date.members[2] = &c->api.subjects.month_name; + lv_subject_init_group(&c->subject_groups.date.group, c->subject_groups.date.members, + ARRAY_LEN(c->subject_groups.date.members)); + c->subject_groups.wifi.members[0] = &c->api.subjects.wifi_ssid; + c->subject_groups.wifi.members[1] = &c->api.subjects.wifi_ip; + lv_subject_init_group(&c->subject_groups.wifi.group, c->subject_groups.wifi.members, + ARRAY_LEN(c->subject_groups.wifi.members)); + + lv_array_init(&c->about_slides_array, 1, sizeof(lv_image_dsc_t *)); + lv_fs_dir_t dir; + lv_fs_res_t fs_res = lv_fs_dir_open(&dir, slides_path); + if(fs_res == LV_FS_RES_OK) { + fs_res = lv_fs_dir_close(&dir); + LV_ASSERT(fs_res == LV_FS_RES_OK); + + c->about_slides_dir_exists = true; + + for(int32_t i = 1; ; i++) { + char buf[256]; + lv_snprintf(buf, sizeof(buf), "%s/Slide%"LV_PRId32".png", slides_path, i); + lv_fs_file_t file; + fs_res = lv_fs_open(&file, buf, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + break; + } + fs_res = lv_fs_close(&file); + LV_ASSERT(fs_res == LV_FS_RES_OK); + + lv_image_header_t header; + lv_result_t res = lv_image_decoder_get_info(buf, &header); + if(res == LV_RESULT_INVALID) { + LV_LOG_WARN("Couldn't read the header info of slide image"); + continue; + } + /* the ratio of a slide's height to the display's height will be 9:16 */ + int32_t scale = (9 * 256 * vres) / (16 * header.h); + + lv_image_dsc_t * loaded_draw_buf = lv_demo_smart_home_image_preload(buf, LV_COLOR_FORMAT_NATIVE, scale); + if(loaded_draw_buf == NULL) continue; + lv_array_push_back(&c->about_slides_array, &loaded_draw_buf); + + if(scale != LV_SCALE_NONE) LV_LOG_INFO("A slide was scaled by %"LV_PRId32" (256 means 1:1)", scale); + } + } + + return base_obj; +} + +lv_obj_t * lv_demo_smart_home_simple_container_create(lv_obj_t * parent, bool vertical, int32_t pad, + lv_flex_align_t align_cross_place) +{ + lv_obj_t * obj = lv_obj_create(parent); + lv_obj_remove_style_all(obj); + lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + if(vertical) { + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_row(obj, pad, 0); + } else { + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW); + lv_obj_set_style_pad_column(obj, pad, 0); + } + lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, align_cross_place, align_cross_place); + return obj; +} + +void lv_demo_smart_home_label_bind_temperature(lv_obj_t * label, lv_subject_t * subject, lv_demo_smart_home_ctx_t * c,bool temp) +{ + lv_obj_set_user_data(label, c); + + if(temp) { + lv_subject_add_observer_obj(subject, label_text_temperature_cb, label, subject); + lv_subject_add_observer_obj(&c->temperature_units_are_celsius, label_text_temperature_cb, label, subject); + } else { + lv_subject_add_observer_obj(subject, label_text_temperature_humi_cb, label, subject); + lv_subject_add_observer_obj(&c->temperature_units_are_celsius, label_text_temperature_humi_cb, label, subject); + } +} + +void lv_demo_smart_home_theme_observer_image_src_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * obj = lv_observer_get_target_obj(observer); + lv_image_dsc_t ** pair = (lv_image_dsc_t **)observer->user_data; + + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(subject); + + if(th == &lv_demo_smart_home_theme_light) { + lv_image_set_src(obj, pair[0]); + } else { + lv_image_set_src(obj, pair[1]); + } +} + +void lv_demo_smart_home_theme_observer_obj_bg_image_src_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + lv_obj_t * obj = lv_observer_get_target_obj(observer); + lv_image_dsc_t ** pair = (lv_image_dsc_t **)observer->user_data; + + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(subject); + + if(th == &lv_demo_smart_home_theme_light) { + lv_obj_set_style_bg_image_src(obj, pair[0], 0); + } else { + lv_obj_set_style_bg_image_src(obj, pair[1], 0); + } +} + +static lv_image_dsc_t * process_image_scaling(const void * src, const lv_image_header_t * header, + lv_color_format_t cf, int32_t scale) +{ + int32_t dest_w = header->w * scale / 256; + int32_t dest_h = header->h * scale / 256; + + LV_LOG_USER("Scaling: %dx%d -> %ldx%ld (scale: %ld)", + header->w, header->h, dest_w, dest_h, scale); + + lv_draw_buf_t * dest = lv_draw_buf_create(dest_w, dest_h, cf, LV_STRIDE_AUTO); + if(dest == NULL) { + LV_LOG_ERROR("Failed to create draw buffer"); + return NULL; + } + + // 使用 canvas 进行缩放绘制 + lv_obj_t * canvas = lv_canvas_create(lv_screen_active()); + lv_canvas_set_draw_buf(canvas, dest); + lv_canvas_fill_bg(canvas, lv_color_hex3(0x000), LV_OPA_TRANSP); + + lv_layer_t layer; + lv_canvas_init_layer(canvas, &layer); + + lv_draw_image_dsc_t dsc; + lv_draw_image_dsc_init(&dsc); + dsc.src = src; + dsc.scale_x = scale; + dsc.scale_y = scale; + + lv_area_t coords = {0, 0, header->w - 1, header->h - 1}; + lv_draw_image(&layer, &dsc, &coords); + lv_canvas_finish_layer(canvas, &layer); + + lv_obj_delete(canvas); + + LV_LOG_USER("Preload completed successfully"); + return (lv_image_dsc_t *) dest; +} + +lv_image_dsc_t * lv_demo_smart_home_image_preload(const void * src, lv_color_format_t cf, int32_t scale) +{ + lv_image_header_t header; + lv_result_t res; + + res = lv_image_decoder_get_info(src, &header); + if(res == LV_RESULT_OK) { + LV_LOG_USER("Method 1 success: %dx%d", header.w, header.h); + } else { + LV_LOG_WARN("Method 1 failed, trying lv_image_decoder_open..."); + + lv_image_decoder_dsc_t dsc; + lv_image_decoder_args_t args = {0}; + + res = lv_image_decoder_open(&dsc, src, &args); + + if(res == LV_RESULT_OK) { + LV_LOG_USER("Method 2 success: %dx%d", + dsc.decoded->header.w, dsc.decoded->header.h); + header = dsc.decoded->header; + lv_image_decoder_close(&dsc); + } else { + LV_LOG_ERROR("All decoder methods failed"); + + return NULL; + } + } + + // 图像缩放处理 + return process_image_scaling(src, &header, cf, scale); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void init_fonts_sm(lv_style_t * fonts) +{ + lv_font_t* normal_sm_8 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 8, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_11 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 11, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_16 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 16, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_20 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 20, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_24 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_40 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 40, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_80 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 80, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_sm_107 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 107, + LV_FREETYPE_FONT_STYLE_NORMAL); + + if(normal_sm_8 == NULL||normal_sm_16 == NULL || normal_sm_20 == NULL ||normal_sm_24 == NULL|| + normal_sm_40 == NULL|| normal_sm_80 == NULL|| normal_sm_107 == NULL) { + normal_sm_8 = &lv_font_montserrat_14; + normal_sm_16 = &lv_font_montserrat_14; + normal_sm_20 = &lv_font_montserrat_14; + normal_sm_24 = &lv_font_montserrat_14; + normal_sm_40 = &lv_font_montserrat_14; + normal_sm_80 = &lv_font_montserrat_14; + normal_sm_107 = &lv_font_montserrat_14; + } + + lv_style_set_text_font(&fonts[FONT_HEADING_MD], normal_sm_20); + lv_style_set_text_font(&fonts[FONT_HEADING_LG], normal_sm_40); + lv_style_set_text_font(&fonts[FONT_HEADING_XL], normal_sm_80); + lv_style_set_text_font(&fonts[FONT_HEADING_XXL], normal_sm_107); + lv_style_set_text_font(&fonts[FONT_LABEL_XS], normal_sm_11); + lv_style_set_text_line_space(&fonts[FONT_LABEL_XS], + 30 * lv_font_get_line_height(normal_sm_11) / 100); /* +30% */ + + lv_style_set_text_font(&fonts[FONT_LABEL_SM], normal_sm_11); + lv_style_set_text_font(&fonts[FONT_LABEL_MD], normal_sm_16); + lv_style_set_text_font(&fonts[FONT_LABEL_LG], normal_sm_20); + lv_style_set_text_font(&fonts[FONT_LABEL_XL], normal_sm_24); + lv_style_set_text_font(&fonts[FONT_LABEL_2XL], normal_sm_40); +} + +static void init_fonts_md(lv_style_t * fonts) +{ + lv_font_t* normal_md_13 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 13, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_md_16 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 16, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_md_20 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 20, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_md_24 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_md_40 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 40, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_md_80 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 80, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_md_107 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 107, + LV_FREETYPE_FONT_STYLE_NORMAL); + + if(normal_md_13 == NULL||normal_md_16 == NULL || normal_md_20 == NULL ||normal_md_24 == NULL|| + normal_md_40 == NULL|| normal_md_80 == NULL|| normal_md_107 == NULL) { + normal_md_13 = &lv_font_montserrat_14; + normal_md_16 = &lv_font_montserrat_14; + normal_md_20 = &lv_font_montserrat_14; + normal_md_24 = &lv_font_montserrat_14; + normal_md_40 = &lv_font_montserrat_14; + normal_md_80 = &lv_font_montserrat_14; + normal_md_107 = &lv_font_montserrat_14; + } + + lv_style_set_text_font(&fonts[FONT_HEADING_MD], normal_md_20); + lv_style_set_text_font(&fonts[FONT_HEADING_LG], normal_md_40); + lv_style_set_text_font(&fonts[FONT_HEADING_XL], normal_md_80); + lv_style_set_text_font(&fonts[FONT_HEADING_XXL], normal_md_107); + lv_style_set_text_font(&fonts[FONT_LABEL_XS], normal_md_13); + lv_style_set_text_line_space(&fonts[FONT_LABEL_XS], + 30 * lv_font_get_line_height(normal_md_13) / 100); /* +30% */ + + lv_style_set_text_font(&fonts[FONT_LABEL_SM], normal_md_13); + lv_style_set_text_font(&fonts[FONT_LABEL_MD], normal_md_16); + lv_style_set_text_font(&fonts[FONT_LABEL_LG], normal_md_20); + lv_style_set_text_font(&fonts[FONT_LABEL_XL], normal_md_24); + lv_style_set_text_font(&fonts[FONT_LABEL_2XL], normal_md_40); +} + +static void init_fonts_lg(lv_style_t * fonts) +{ + lv_font_t* normal_lg_13 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 13, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_lg_16 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 16, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_lg_20 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 20, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_lg_24 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_lg_40 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 40, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_lg_80 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 80, + LV_FREETYPE_FONT_STYLE_NORMAL); + lv_font_t* normal_lg_107 = lv_freetype_font_create(LV_DEMO_SMART_HOME_MISANS_NORMAL_PATH, + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 107, + LV_FREETYPE_FONT_STYLE_NORMAL); + + if(normal_lg_13 == NULL||normal_lg_16 == NULL || normal_lg_20 == NULL ||normal_lg_24 == NULL|| + normal_lg_40 == NULL|| normal_lg_80 == NULL|| normal_lg_107 == NULL) { + normal_lg_13 = &lv_font_montserrat_14; + normal_lg_16 = &lv_font_montserrat_14; + normal_lg_20 = &lv_font_montserrat_14; + normal_lg_24 = &lv_font_montserrat_14; + normal_lg_40 = &lv_font_montserrat_14; + normal_lg_80 = &lv_font_montserrat_14; + normal_lg_107 = &lv_font_montserrat_14; + } + + lv_style_set_text_font(&fonts[FONT_HEADING_MD], normal_lg_20); + lv_style_set_text_font(&fonts[FONT_HEADING_LG], normal_lg_40); + lv_style_set_text_font(&fonts[FONT_HEADING_XL], normal_lg_80); + lv_style_set_text_font(&fonts[FONT_HEADING_XXL], normal_lg_107); + lv_style_set_text_font(&fonts[FONT_LABEL_XS], normal_lg_13); + lv_style_set_text_line_space(&fonts[FONT_LABEL_XS], + 30 * lv_font_get_line_height(normal_lg_13) / 100); /* +30% */ + + lv_style_set_text_font(&fonts[FONT_LABEL_SM], normal_lg_13); + lv_style_set_text_font(&fonts[FONT_LABEL_MD], normal_lg_16); + lv_style_set_text_font(&fonts[FONT_LABEL_LG], normal_lg_20); + lv_style_set_text_font(&fonts[FONT_LABEL_XL], normal_lg_24); + lv_style_set_text_font(&fonts[FONT_LABEL_2XL], normal_lg_40); +} + +static void theme_observer_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + const lv_demo_smart_home_theme_t * th = lv_subject_get_pointer(subject); + const lv_demo_smart_home_theme_t * th_other = th == &lv_demo_smart_home_theme_light ? &lv_demo_smart_home_theme_dark : + &lv_demo_smart_home_theme_light; + lv_demo_smart_home_ctx_t * c = (lv_demo_smart_home_ctx_t *)observer->user_data; + + for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { + lv_color_t color = i == STYLE_COLOR_BASE ? th->base : th->accent; + lv_color_t color_inv = i == STYLE_COLOR_ACCENT ? th->accent : th_other->base; + + lv_style_set_bg_color(&c->styles[i][STYLE_TYPE_OBJ], color); + lv_style_set_outline_color(&c->styles[i][STYLE_TYPE_OBJ], color); + + lv_style_set_text_color(&c->styles[i][STYLE_TYPE_TEXT], color_inv); + lv_style_set_line_color(&c->styles[i][STYLE_TYPE_TEXT], color_inv); + + lv_style_set_image_recolor(&c->styles[i][STYLE_TYPE_A8_IMG], color_inv); + + lv_style_set_bg_color(&c->styles[i][STYLE_TYPE_TEXTAREA], color_inv); + lv_style_set_text_color(&c->styles[i][STYLE_TYPE_TEXTAREA], color_inv); + lv_style_set_border_color(&c->styles[i][STYLE_TYPE_TEXTAREA_CURSOR], color_inv); + } + + for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { + for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) { + lv_obj_report_style_change(&c->styles[i][j]); + } + } +} + +static void free_ctx_event_cb(lv_event_t * e) +{ + lv_obj_t * base_obj = lv_event_get_target_obj(e); + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(base_obj); + + lv_observer_remove(&c->th); + + for(uint32_t i = 0; i < IMG_COUNT; i++) { + lv_draw_buf_destroy((lv_draw_buf_t *)c->imgs[i]); + } + + for(uint32_t i = 0; i < STYLE_COLOR_COUNT; i++) { + for(uint32_t j = 0; j < STYLE_TYPE_COUNT; j++) { + lv_style_reset(&c->styles[i][j]); + } + } + + for(uint32_t i = 0; i < FONT_COUNT; i++) { + lv_style_reset(&c->fonts[i]); + } + + lv_free(c->logo_path); + lv_free(c->slides_path); + + lv_observer_remove(&c->temperature_units_are_celsius); + lv_observer_remove(&c->ev_charging_progress); + lv_observer_remove(&c->smart_meter_selected_bar); + + lv_demo_smart_home_top_margin_deinit_subjects(c); + + lv_observer_remove(&c->subject_groups.time.group); + lv_observer_remove(&c->subject_groups.date.group); + lv_observer_remove(&c->subject_groups.wifi.group); + + lv_subject_t * subjects = (lv_subject_t *) &c->api.subjects; + for(uint32_t i = 0; i < sizeof(c->api.subjects) / sizeof(lv_subject_t); i++) { + lv_observer_remove(&subjects[i]); + } + + uint32_t about_slides_count = lv_array_size(&c->about_slides_array); + for(uint32_t i = 0; i < about_slides_count; i++) { + lv_image_dsc_t ** slide = lv_array_at(&c->about_slides_array, i); + lv_draw_buf_destroy((lv_draw_buf_t *) *slide); + } + lv_array_deinit(&c->about_slides_array); + + lv_free(c->wifi_ssid_tmp); + lv_free(c->wifi_password_tmp); + + lv_free(c); + + lv_obj_set_user_data(base_obj, NULL); +} + +static void label_text_temperature_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_subject_t * temperature_subject = (lv_subject_t *)observer->user_data; + int32_t val = lv_subject_get_int(temperature_subject); + lv_obj_t * label = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(label); + + if(!lv_subject_get_int(&c->temperature_units_are_celsius)) { + /* convert to fahrenheit */ + /* + 320 instead of 32 because temperatures in are tenths of a degree */ + val = val * 9 / 5 + 320; + } + + int32_t full = val / 10; + int32_t fraction = val % 10; + char buf[16]; + if(fraction) { + lv_snprintf(buf, sizeof(buf), "%"PRId32".%"PRId32"\xc2\xb0""C", full, fraction); + } else { + lv_snprintf(buf, sizeof(buf), "%"PRId32"\xc2\xb0""C", full); + } + + lv_label_set_text(label, buf); +} + +static void label_text_temperature_humi_cb(lv_observer_t * observer, lv_subject_t * subject) +{ + LV_UNUSED(subject); + lv_subject_t * temperature_subject = (lv_subject_t *)observer->user_data; + int32_t val = lv_subject_get_int(temperature_subject); + lv_obj_t * label = lv_observer_get_target_obj(observer); + lv_demo_smart_home_ctx_t * c = lv_obj_get_user_data(label); + + if(!lv_subject_get_int(&c->temperature_units_are_celsius)) { + /* convert to fahrenheit */ + /* + 320 instead of 32 because temperatures in are tenths of a degree */ + val = val * 9 / 5 + 320; + } + + int32_t full = val / 10; + int32_t fraction = val % 10; + char buf[16]; + if(fraction) { + lv_snprintf(buf, sizeof(buf), "%"PRId32".%"PRId32"%%", full, fraction); + } else { + lv_snprintf(buf, sizeof(buf), "%"PRId32"%%", full); + } + + lv_label_set_text(label, buf); +} + +#endif /*LV_USE_DEMO_SMART_HOME*/ diff --git a/smart_home/res/fonts/MiSans-Normal.ttf b/smart_home/res/fonts/MiSans-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3199d464141d0599dd1269a3fef4264a829c6da0 Binary files /dev/null and b/smart_home/res/fonts/MiSans-Normal.ttf differ diff --git a/smart_home/res/fonts/MiSans-Semibold.ttf b/smart_home/res/fonts/MiSans-Semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..83c1a532632f582550d48bae117d758191ad1800 Binary files /dev/null and b/smart_home/res/fonts/MiSans-Semibold.ttf differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..3e41551a3c0d8bd3f5c5a42705460a2572f1e902 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..f4f9f3f20b3f38359645603e031bcff07f18b321 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..bd2e59960977ba981f976dba40a5d6308eef4725 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_about_app_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_album_art_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_album_art_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..2c5a2455e7dbb607c07b5431338ea0a886aca3da Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_album_art_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_album_art_md.png b/smart_home/res/icons/img_lv_demo_smart_home_album_art_md.png new file mode 100644 index 0000000000000000000000000000000000000000..c8e229ff407f840b3795d240e772cfc4d3198c2b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_album_art_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_album_art_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_album_art_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..5eb6fab4bd5176aa15e42793c4bee5f87184e3ac Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_album_art_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..695105b6e2879b1a3694ad1277f33af2a62f8478 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_md.png b/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_md.png new file mode 100644 index 0000000000000000000000000000000000000000..359e8a9fe8fe5ea9033bb7f8ed6c0e6dba7f18bd Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..e006a409d6165d0d57b9293017f772d3140b3cb2 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_arrow_left_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..3f96aeab192e9a68092fff3a579f5cf8dfeedea0 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..5d2836a548e533245f9c9763b256548c2ce45a7e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0289a261fbb4087102b109175aabe0ea4f4582f2 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_backward_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..513e94848ff041b8e81a1d77ca1cd08c82e863fa Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..eb7fb79fee2fdc47bd63dddc021cafd8ccc2d3b1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..302ac3696ce46828e9a330f1f18b8b0bee131b9c Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_cold_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f03ad42f5d0411ab5772cfe1076b81441d1a2c1d Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_md.png new file mode 100644 index 0000000000000000000000000000000000000000..37a549736b1fd5d63453f988fd0c327dc68cd554 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..58d788cf54b46e0344451c9d52edf18e602aa8a1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_about_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..a3b776659c1252502f6675ccfc53ab7208abecb7 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_md.png new file mode 100644 index 0000000000000000000000000000000000000000..6dae2a4bdbba8dbb513cc39a4de1aaffd2d09b6e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..4d450cfb2876d67bcaaa7d26bc6ef8775de30933 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_ev_charging_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..17a0d1e65fe7aee728458f866b5a287fc6e01e60 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_md.png new file mode 100644 index 0000000000000000000000000000000000000000..b57ff3d5edd8269b7c2a22e645dceb6fd30122b7 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..fa2caa8272a4742591cb2834d82228058ba50828 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_home_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f278b215a96bb4af67740cbfb8387b12909c8e50 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_md.png new file mode 100644 index 0000000000000000000000000000000000000000..c5aad63a223be95c8a84ac780fd99bb99aad56bc Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..ffdddee72dd891b08651ecd40c3943338827f3d9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_home_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..c5a39d14f14d7ace46813899157a342608857878 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_md.png new file mode 100644 index 0000000000000000000000000000000000000000..235bc8972aab84f8dbbae4229274b6c758c0ad5e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..6fe96b62d36379838466747c2aef2442c1dfbb56 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_smart_meter_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ff02a8ca020e0b52242f7e5689b7a6b3f00ac9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_md.png new file mode 100644 index 0000000000000000000000000000000000000000..7f8caadbc7e3f674831d36d6571c88c456af5bd6 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a2f29b9886e28b2d502e0bad138cfb656a41b1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_bg_thermostat_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..0d85344cbb78adf01ae40e30e3f85d5df95dfc46 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..19dd2cf189a8cb51795e162f2374714e386d2057 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..cd0752ed56d42f0fffe52db3b4f1f1484e5c5c9e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_dark_theme_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..5257bf9e25787c4e9d94e5cfdf2a45a9ff38d6e9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..3f4af8e4fa62e6870a028a6f1446f26d49b70b41 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..a87d996d57729457fbcceb17046f9b012f87561c Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_light_theme_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..ecfe02a72a6b4c57ac285ad0cea92e59ba5830b5 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..84c59479c0fbbf9326be6e373c1e4e1bb376e77e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..8fd3b9e895de8cd681d903394080967e1f3ae44b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget1_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..32743fbbb2bfa51815c646c8750c978801744ec0 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..01d964531f5a1c2b4d5585197a63968e94fee118 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..003c6a24ceee8eeaf21f659c64fa556833a6e618 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget2_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f2d13734711612c79c11375d287050bd8c1b8685 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..d8148078f615a008a654b5920331f6e511b7e30e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..48da6f043fc4d38297de1957b5f0e826be246647 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget3_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..baa7e9371666d847fbeef13bac5dfd4360e067dc Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..181e9113ed1a91f1f1a89fb24f22163b000e3c82 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..e1c6b859cb411bf1b57f5ef5b893d6d606a1d9c6 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget4_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..12893cf2b234f80481ce4dea4d0967a85f41660a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..20c64b6c56c0465b44e9924c05df18667ef455c5 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..cfc875fe9e255e76b8e2af91172400118dd5e1a4 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dark_widget5_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_door_1_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_door_1_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..4170cf9557d76e2d74b56fe3c9d32feab9d13fcf Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_door_1_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_door_1_md.png b/smart_home/res/icons/img_lv_demo_smart_home_door_1_md.png new file mode 100644 index 0000000000000000000000000000000000000000..195f11554a12a2681ef4ba7876eef3d5f15e4b79 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_door_1_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_door_1_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_door_1_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..71324fd5d17d63980fa4bc5502b9bd3a882c8640 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_door_1_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_door_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_door_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..6e25c4858066364edfb9547d324a1e1bc5b2d7be Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_door_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_door_md.png b/smart_home/res/icons/img_lv_demo_smart_home_door_md.png new file mode 100644 index 0000000000000000000000000000000000000000..b840f26070d722ccaaca712832d907ef7ef066a7 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_door_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_door_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_door_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..46836366a3a1f04cb963f0e10e049e0eb7803c0c Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_door_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..bfb5d73c96c62fac2d63a783ce155aa983f0a748 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba2dc5c86b7d0187bce1eded1a2545a69a5b667 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..259eb44336e59c18a490cec37ab82f5a1bc0d3a8 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_dry_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..438721b7dd1ad92e3b5b8036e9ffacc058f19c67 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..87e42c0335c046ce0470445b3405fe7787014492 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..b9496d72eeabd37c2aa2861cde6c8bec3cc69fbc Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_energy_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f541fe85f159a1ca49ab36811c04f72170172e8e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..6f86a70fcfb62b4b3a68fb634cf65f6b015f1a60 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..fc06747be795010fc36f08ff313cc95044126ce1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_app_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..05483dea9e56529e31a7467836cab9b1e1200c18 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..c2a8f686fb98ce44ad756d9bcd8e5179f72a6ca6 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..4d0854d817439a627b828af8d2e636b58283c5cd Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_1_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..52af6acfab6082dd54686212ae8663c31601f1ca Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..b5657d626a50150cd9e04ae567fa5c524fd4032e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..c532fbb3ed698fff56a661bf957a7a7c5b50700f Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_ev_charging_widget3_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..d33216d6030087b10d104b17915d641b798aec5f Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_md.png b/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_md.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d44283e6970c7cbe8b55c4ff2954794dabe72a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..44cfc6e2c95e0e1212d676de9a76b2efeaf701bf Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan2_1_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan2_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_fan2_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..41ae74347d6c91398aa67e4bb52c4318eababd81 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan2_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan2_md.png b/smart_home/res/icons/img_lv_demo_smart_home_fan2_md.png new file mode 100644 index 0000000000000000000000000000000000000000..d5285c8ecef8694a1d0b6ebb9bfd81a76e2814c9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan2_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan2_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_fan2_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..daede06f2fe7e25ffb3acdc9f43a71cb4fd8bb6a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan2_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_fan_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..3b437497dee39d35be8477da864616425f007e99 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan_md.png b/smart_home/res/icons/img_lv_demo_smart_home_fan_md.png new file mode 100644 index 0000000000000000000000000000000000000000..e1ae2ab0818bd2fd6aeccab17227d1562f812975 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_fan_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_fan_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7c75fc867d513e2ef10582b8d34ce4911f342913 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_fan_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..bdf89e177b92b026668af452cadcbbb130c24cc9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef8ba0659feeba2a5df6c3e00405fef5c4c8671 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..33a5b4b450d6d24815d699b4bc6cc4eca0eba0fc Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_forward_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..a0a3f9e9dcd9a0137782bf548c91139fa3893998 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_md.png b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_md.png new file mode 100644 index 0000000000000000000000000000000000000000..54da77d58a9299a5a5811e17e4b3904c0e2ea3aa Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..dac63622c474d237a9a0b025188b0f9d59b00962 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_bold_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_health_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..d25a17cd680c340be79bfe4e449671537130d7b1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_health_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..876885324aa8589ce0e9d5ed237fcf8c033625fd Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_health_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..adfd05af4e228e366d83f4263a3f829676b9255e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_health_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..5a07a8d36cc883090d010701d3a10df5417d54c0 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..bab8938a9ccf57d9173a1aa5dfea3c1bc4722782 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7e017bb065c9d4a5c255d717e498f7da7a2cd0cf Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_heat_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..50ef6763433647681cef015e6dcead29851b22de Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_md.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_md.png new file mode 100644 index 0000000000000000000000000000000000000000..d6123f5a5c9527970a7be4c9ce9de1c44228c789 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..b39ff702efdde08da1da9eee6b540c001bcbd781 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_1_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp2_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..a56db15abeb30ad0d33896704551ee7fb8bf9526 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp2_md.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_md.png new file mode 100644 index 0000000000000000000000000000000000000000..1525ae65148a887f6215d74200b67bce48972d0b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp2_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..5c17a7db76e7e8bbbf0927190cb6b77747d476d3 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp2_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f57203babfcf5ad77f81c34b581a10f7552d6646 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp_md.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp_md.png new file mode 100644 index 0000000000000000000000000000000000000000..c671597a4cd118fd08119eb890aa165de0f61093 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lamp_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_lamp_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..c877f4d758699b226bc05a488b4b79789ce880ca Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lamp_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c29dc3ca8f9eab29fe851accb4f2de21887df4 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_md.png new file mode 100644 index 0000000000000000000000000000000000000000..979b4565cadf3a817e936b625b748feffffc81ef Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..a0505fe11236b4bff939d4cff1fb274c93d703c2 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_about_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..ceadeb79449edea8f4bfe3015872cc2382136421 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_md.png new file mode 100644 index 0000000000000000000000000000000000000000..65d1b988d76ac81ea892db643ea0e71d66178ae7 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..82322d9a1060af12fea328bb125a49e4f5c0f238 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_ev_charging_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..2e2a196c006b79ef0e1cf9285ec5807488c3af0f Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_md.png new file mode 100644 index 0000000000000000000000000000000000000000..aa177c67ed42b80f3e3aab33ed27931303a986c3 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..62224e3e7e984a8ecea1b1f7bace698dd59bdafb Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_home_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..bc3d0c36f4e5e43ffaa977ab9d66c564c6309168 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_md.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd49f40048e8a856a63ab20f8a1b8609fecb556 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..ead42733b60ab65ef302418d14b66738ce7c62ab Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_home_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..8725e800950e7a8cc64335299592bfb1a7e69890 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_md.png new file mode 100644 index 0000000000000000000000000000000000000000..25ce1d9205eb19b605353c5e1b02c276744b604a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0b5e70718f51c691e552aaa79ba58ada6586ca4b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_smart_meter_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..c59e09af184e856747f61c9d3ff9635f36def6cc Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_md.png new file mode 100644 index 0000000000000000000000000000000000000000..fd9e97161fdc3453cc85902f4fd1fd858d709694 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..3ee550935367f08c957dbb74dff5909e38f15eaa Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_bg_thermostat_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..af93b98a9486ff9fbc6be78bf396d0ca303a50f8 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..f74b195d6716470a69023409450052745e870bde Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..cd16141da55178bf98e6bfd3d87f2e20a7b3a130 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_dark_theme_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..a5eb2258f2a7a763b39c344220a81a83d9868067 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..24e34fb215d09fb036b5797b86de18216fdc489a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..c98e6d050340fda866244f95fdcab5ca6efbb0b6 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_light_theme_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..b666da9e31babb4ca62551e0107315eafd03605c Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..017687aee79ba9fbddb6e6b185a7629855149212 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..35feb4aa63c1178359fcd6497f43339fc011ac2b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget1_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..ba96052a9845ee0bc63516eac572e9d992083440 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..e555f2472b5b9f4606c32d527e607fc606f7d0df Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..03ecd698754295ec674e30b9f5ee228e9acb641a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget2_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..e73cf3ffd6875063c252b9ad2354ca2417d037e5 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..e3aeadc79d65cbeb4c1cab7e7517cb4e98c33044 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..f276938d9debb7c7847b76e9351368721511f267 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget3_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f825224cb28d02bc29a8a3adda9ad4caaccec887 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..62c540fa78c82737620cb4a285a8c13dc578b3fe Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0c59e1906a48624f062e24a6d4c7935c706b73 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget4_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..015cec7fc7d27b7c35a92292c247dd1c18341a6a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..deb95418e10694f845ee15c128d66063e3dd0397 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7ca068f4a48f32d38c6f6859cc5655d411685822 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_light_widget5_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..8df258c373815e8fbcb355d1f81b286906e1bd22 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..9afeeb9ac16c621ad827cd73a434e1e98a2ad4a9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..5c8d72d464eceb27827f73ab6d5b71e05f8faac8 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_logout_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_lvgl_logo.png b/smart_home/res/icons/img_lv_demo_smart_home_lvgl_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..24df4d710eb5704a913ef945ca5af2decb00e32d Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_lvgl_logo.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..cb519f8817a08c71d7f095f9b6d11474338eecd1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_md.png b/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_md.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab3fb7bbe196977d17ad25a382aa30bc806c888 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0e9a2c1832138e35f4d3fa4758fccc027517c441 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_main_light_slider_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_minus_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_minus_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..726fbf18a3349080b9da41a871b2da6d6d06c7bb Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_minus_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_minus_md.png b/smart_home/res/icons/img_lv_demo_smart_home_minus_md.png new file mode 100644 index 0000000000000000000000000000000000000000..488d9e7c86386f26010b6490d68138c678956034 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_minus_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_minus_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_minus_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..393490805672f86d48e5f10c4a452f8f542013cd Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_minus_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_left_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_left_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..2f290f53d837b28f0450f267ec93da5e43a6b22e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_left_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_left_md.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_left_md.png new file mode 100644 index 0000000000000000000000000000000000000000..c6744cbdb26852ccda39fc5c33eac32ad6a04dd8 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_left_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_left_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_left_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0c8e47b93a63c445dd87e6cde7057cf0c47fd90a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_left_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..e2005ea9dda144930977001420816602320fae91 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_md.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_md.png new file mode 100644 index 0000000000000000000000000000000000000000..5e69280fb92f90090ac33755db357bb04e1e1b80 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..295203367568e72a89d0524b15684f5eac9a4a1a Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_pause_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_play_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_play_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..8cb4c1c3dad403eb5f7e172367679df1058f86d7 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_play_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_play_md.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_play_md.png new file mode 100644 index 0000000000000000000000000000000000000000..ed3bc0b248d083e021f57149ee408b759794fa55 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_play_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_play_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_play_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..809df7bb230971d4a2b8196b5af88780b8780908 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_play_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_right_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_right_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..b24b64704f491a58d0f571ebd519955de7a0a229 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_right_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_right_md.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_right_md.png new file mode 100644 index 0000000000000000000000000000000000000000..75771b20edb7c7b9733184f6713857815f268042 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_right_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_pager_right_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_pager_right_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..14195358de59a368fdcdf97d9e3b4c46d25961da Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_pager_right_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..41c12d13cc08da885c212c6270efbcb791cf46f1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_md.png b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_md.png new file mode 100644 index 0000000000000000000000000000000000000000..bf500b864ba0d5645e1c5b79488208a6b16998ff Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..3052f689607b2044888adc25cd9166209b7af8f9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_1_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_play_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..57752ddbcaef6a4250d4d8310ed57a79154f13cb Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_play_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..86a5b8c7686f23649258639e306ba08125ab5be1 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_play_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..269d90bb2fed382f08f85131b1be60299bf535f6 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_play_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_plus_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_plus_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..853a3ac0c938f9527f26c3847b68a89cb2184276 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_plus_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_plus_md.png b/smart_home/res/icons/img_lv_demo_smart_home_plus_md.png new file mode 100644 index 0000000000000000000000000000000000000000..af24584ebcf585026f55c28ce93b2bb210cbec04 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_plus_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_plus_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_plus_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..362b54f98f3f7c506a43038e3de7dd091cee314c Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_plus_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_range_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_range_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f38318c07f0e68df8fa80d5f2336369ca61d8de2 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_range_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_range_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_range_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..05de9ea62b4a4e184492d9f88c1a5abaccb8aa9d Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_range_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_range_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_range_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..ae4bc95d8c282b98cefc050ca92fee7b4702a4ee Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_range_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..0a7a7f555a78a9af56fb9f5e2e823c174de76ec9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_md.png b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_md.png new file mode 100644 index 0000000000000000000000000000000000000000..d546e0fb91441d18dcd7cb4d59970f41801fbce0 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7e8d123a33e453d129a55cfb929e95939d7cebff Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_bold_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..d598b1214584baa24d19d61b33a7f6301f3368f3 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..751dc1165fdfe558fda0993f98e22b6756e3adfa Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..83e0ea3aa6e3ce0545b77060e5b65307fb658845 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_setting_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..ec4a28f74e1d296fb67d9d2b51cfd6b140c947e8 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..8557b10664fea50af35fe4b73e2c2891ba4821b6 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..3e4d21032b57e70bf116faaa69f57310a3b06b5b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_app_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..35cc7a962eca9db9eba9ad0e20b6f4de2f68214e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..c69937e8e697730e4431ba7ad50939b4ab38605b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..978e1dc149d4e9a051d6ed65cfc24471fd0951d4 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget1_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..62dae494e3fac3198b09babf863d4fbb704f702f Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_md.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_md.png new file mode 100644 index 0000000000000000000000000000000000000000..81803500eff5c16d9ecf2f14848700ce8c999252 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..fbcf6258f19cdbf7d82cbb0a26d0a36904c04a23 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_home_widget2_bg_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6d7a8cbd517e8515baf736d98fd86a8274becd Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..5d922c7a87ae2a712389ea980ff1c7dd30a6e708 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..f387917e9e0455cdec3a9f9b2786a3c65a68e637 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_smart_meter_app_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..f8db3cd4886c4b10be7e6a809ab70277d738f450 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..855baa3c1d896f8919fe65e637afcacc2350f051 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..974868c21511c5a7bb91a4aee0731750cf74ef27 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_thermostat_app_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_time_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_time_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..0a94def3cac7461a915c3f339e744ba99e8ada27 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_time_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_time_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_time_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..2efeaa6eef0fb5da3a551149c4cf63d958a21aeb Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_time_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_time_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_time_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..85194e386ca26bab34cef53c00089ca8017e934c Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_time_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_unlock_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_unlock_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..919dbd40e50973b0f26d0d6640cd2e3ddd24c2fe Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_unlock_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_unlock_md.png b/smart_home/res/icons/img_lv_demo_smart_home_unlock_md.png new file mode 100644 index 0000000000000000000000000000000000000000..85ba54be6183aabfdb89e950bd5839060c048baa Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_unlock_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_unlock_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_unlock_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..72c3f65047c2ae79d371b3cdde4171139826a45e Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_unlock_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_volume_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_volume_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..2eb5e4edf8630b33a5fc2378bdc2d9f9d90ea069 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_volume_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_volume_md.png b/smart_home/res/icons/img_lv_demo_smart_home_volume_md.png new file mode 100644 index 0000000000000000000000000000000000000000..b012781becec8f9ae12a3651b041d3d90cab8d35 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_volume_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_volume_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_volume_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..afadabb030a25a181cc0d3fdcfbf8be11f9f0cf9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_volume_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_weather_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_weather_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..2880e4c35a3ad0ffd4873f9f501145d75165f598 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_weather_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_weather_md.png b/smart_home/res/icons/img_lv_demo_smart_home_weather_md.png new file mode 100644 index 0000000000000000000000000000000000000000..7bad1f6065cfcc6324353a7e586efa22d36695e9 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_weather_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_weather_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_weather_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..28a853f1557d9e2d05c0bf4e655fb2eaf7f86a18 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_weather_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..e7a2cc87a1cf071a88362fd61b0d44501c3ee5d8 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_md.png b/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_md.png new file mode 100644 index 0000000000000000000000000000000000000000..ae11a5398a6c98f7666dafd109cc5628319ccaff Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..c9e3bbecd321b57d23776cdadef4c6be7f7140e3 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wifi_icon_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wind_1_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_wind_1_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..7500f508c32eb0d0bf2321ed5deb1f9e6189a257 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wind_1_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wind_1_md.png b/smart_home/res/icons/img_lv_demo_smart_home_wind_1_md.png new file mode 100644 index 0000000000000000000000000000000000000000..16a4a2c9d2722dbfcbdbf8771cac2160bbf657ed Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wind_1_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wind_1_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_wind_1_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..f034bf80312d7277b5956eb88109e3abf83b0f93 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wind_1_sm.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wind_lg.png b/smart_home/res/icons/img_lv_demo_smart_home_wind_lg.png new file mode 100644 index 0000000000000000000000000000000000000000..9daa2996730383a01011d322d0e4c686db5eff3b Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wind_lg.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wind_md.png b/smart_home/res/icons/img_lv_demo_smart_home_wind_md.png new file mode 100644 index 0000000000000000000000000000000000000000..b90041662983f308a7795a88ce49f78599411308 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wind_md.png differ diff --git a/smart_home/res/icons/img_lv_demo_smart_home_wind_sm.png b/smart_home/res/icons/img_lv_demo_smart_home_wind_sm.png new file mode 100644 index 0000000000000000000000000000000000000000..65160213229beb5b6e02a846530101fa0e336245 Binary files /dev/null and b/smart_home/res/icons/img_lv_demo_smart_home_wind_sm.png differ diff --git a/smart_home/smart_home_main.c b/smart_home/smart_home_main.c new file mode 100644 index 0000000000000000000000000000000000000000..a8b4569979d29e276ebafdf8b76de4147dd47e6a --- /dev/null +++ b/smart_home/smart_home_main.c @@ -0,0 +1,174 @@ +/**************************************************************************** + * apps/packages/demos/smart_home/smart_home_main.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <unistd.h> +#include <sys/boardctl.h> +#include <stdio.h> +#include <string.h> + +#include <lvgl/lvgl.h> +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +#include <uv.h> +#endif + +#include "lv_demo_smart_home.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Should we perform board-specific driver initialization? */ +#undef NEED_BOARDINIT + +#if defined(CONFIG_BOARDCTL) && !defined(CONFIG_NSH_ARCHINIT) +# define NEED_BOARDINIT 1 +#endif + + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static void launcher_create(void) +{ + lv_demo_smart_home_api_example(CONFIG_LVX_SMART_HOME_ICONS_PATH, + CONFIG_LVX_SMART_HOME_LOGO_PATH, + CONFIG_LVX_SMART_HOME_SLIDES_PATH); + +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +static void lv_nuttx_uv_loop(uv_loop_t *loop, lv_nuttx_result_t *result) +{ + lv_nuttx_uv_t uv_info; + void *data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: smart_home_main + * + * Description: + * Main entry point for the LVGL High Resolution Demo application + * + ****************************************************************************/ + +int smart_home_main(int argc, FAR char *argv[]) +{ + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + uv_loop_t ui_loop; + lv_memzero(&ui_loop, sizeof(ui_loop)); +#endif + + printf("LVGL High Resolution Demo Starting\n"); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + +#ifdef NEED_BOARDINIT + /* Perform board-specific driver initialization */ + boardctl(BOARDIOC_INIT, 0); +#endif + + lv_init(); + + lv_nuttx_dsc_init(&info); + +#ifdef CONFIG_LV_USE_NUTTX_LCD + info.fb_path = "/dev/lcd0";///dev/fb0 /dev/lcd0 +#endif + + + + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("High Resolution Demo initialization failure!"); + return 1; + } + + launcher_create(); + + LV_LOG_INFO("LVGL initialized successfully"); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + /* Use libuv event loop */ + lv_nuttx_uv_loop(&ui_loop, &result); +#else + /* Use traditional event loop */ + while (1) { + uint32_t idle; + idle = lv_timer_handler(); + /* Minimum sleep of 1ms */ + idle = idle ? idle : 1; + usleep(idle * 1000); + } +#endif + +//demo_end: + printf("High Resolution Demo exiting...\n"); + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +{ + return smart_home_main(argc, argv); +} +#endif \ No newline at end of file diff --git a/snake_game/Kconfig b/snake_game/Kconfig new file mode 100755 index 0000000000000000000000000000000000000000..de5d207fc4bb1e1f12cb39fb661a76a75a57bdd0 --- /dev/null +++ b/snake_game/Kconfig @@ -0,0 +1,14 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_SNAKE_GAME + bool "Snake Game" + default n + +if LVX_USE_DEMO_SNAKE_GAME + config LVX_SNAKE_GAME_DATA_ROOT + string "Snake Game Data Root" + default "/data" +endif diff --git a/snake_game/Make.defs b/snake_game/Make.defs new file mode 100755 index 0000000000000000000000000000000000000000..fa6aa677a9127cc8bc6bfe42ea72cc4697d05175 --- /dev/null +++ b/snake_game/Make.defs @@ -0,0 +1,3 @@ +ifneq ($(CONFIG_LVX_USE_DEMO_SNAKE_GAME),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/snake_game +endif diff --git a/snake_game/Makefile b/snake_game/Makefile new file mode 100755 index 0000000000000000000000000000000000000000..b69d5087dbf9a434fb2a66f0bcc9f6738699c7f1 --- /dev/null +++ b/snake_game/Makefile @@ -0,0 +1,14 @@ +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_SNAKE_GAME), y) +PROGNAME = snake_game +PRIORITY = 100 +STACKSIZE = 131072 +MODULE = $(CONFIG_LVX_USE_DEMO_SNAKE_GAME) + +CSRCS = snake_game.c +MAINSRC = snake_game_main.c +endif + +include $(APPDIR)/Application.mk + diff --git a/snake_game/Readme.md b/snake_game/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..792637144fc0a53cadeacb45578c7b91ff229b3f --- /dev/null +++ b/snake_game/Readme.md @@ -0,0 +1,91 @@ +# Snake Game + +## Introduction + +This is an automatic snake game implemented using the LVGL graphics library. The game area is a 60×35 grid, with each grid cell being 20×20 pixels. + +### Features + +- Click "START" button to begin the game +- After clicking start, the snake automatically searches for and eats food +- Reach 1000 points to win, displaying "Victory!" +- Game ends when hitting self or wall, displaying "GAME OVER" +- "RESTART" button appears when game ends +- Real-time score display +- Random food generation +- Snake head is bright green, body is dark green + +![Simulator Interface](screen/1.png) +![Game Running Interface](screen/2.png) +![Game Start Interface](screen/3.png) +![Game Over Interface](screen/4.png) + +## Configuration + +1. Switch to the openvela repository root directory and execute the following command to configure the snake game: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + +2. Press `/` to search and modify the following configurations: + + ```Bash + LVX_USE_DEMO_SNAKE_GAME=y + LVX_SNAKE_GAME_DATA_ROOT="/data" + ``` + +## Compilation + +```Bash +# Clean build files +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j$(nproc) + +# Start compilation +./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j$(nproc) +``` + +## Running + +1. Start the emulator: + + ```Bash + ./emulator.sh vela + ``` + +2. In the emulator terminal environment `openvela-ap>`, enter: + + ```Bash + snake_game & + ``` + +## Game Rules + +- Click "START" button to begin the game +- Snake automatically finds the shortest path to food +- Each food eaten scores 10 points +- Game ends when hitting self or wall, displaying "GAME OVER" +- Click "RESTART" button to start a new game when game ends +- Reach 1000 points to win, displaying "Victory!" + +## Operation Guide + +1. **Start Game**: + - Click the "START" button in the center of the screen + - Button automatically hides after game starts + +2. **During Game**: + - Snake automatically searches for food and moves + - Score displayed in top left corner + - Game status shown in top right corner + +3. **Game End**: + - Game ends when snake hits itself or wall, displaying "GAME OVER" + - Victory achieved at 1000 points, displaying "Victory!" + - "RESTART" button appears in screen center + - Click "RESTART" to begin a new game + +## Technical Implementation + +The game uses a linked list structure to store the snake's body and implements automatic movement through a timer. The snake calculates the shortest path to food (considering turnaround situations) and automatically chooses the optimal movement direction. The game uses LVGL's canvas component for rendering, redrawing the entire screen after each move. The game interface features a clean design with prominent control buttons and status displays. + diff --git a/snake_game/screen/1.png b/snake_game/screen/1.png new file mode 100644 index 0000000000000000000000000000000000000000..929e2aee264e22132a02f192998718779cb280f9 Binary files /dev/null and b/snake_game/screen/1.png differ diff --git a/snake_game/screen/2.png b/snake_game/screen/2.png new file mode 100644 index 0000000000000000000000000000000000000000..9f120a117028738f11004f77450afa8086e89063 Binary files /dev/null and b/snake_game/screen/2.png differ diff --git a/snake_game/screen/3.png b/snake_game/screen/3.png new file mode 100644 index 0000000000000000000000000000000000000000..8a4daf393248196e8ffa3118793e59978618303a Binary files /dev/null and b/snake_game/screen/3.png differ diff --git a/snake_game/screen/4.png b/snake_game/screen/4.png new file mode 100644 index 0000000000000000000000000000000000000000..a16647d4867c4256b6c7cc220041cea38bbbff86 Binary files /dev/null and b/snake_game/screen/4.png differ diff --git a/snake_game/snake_game.c b/snake_game/snake_game.c new file mode 100755 index 0000000000000000000000000000000000000000..0eff53f403091bb5e2744b2d7663fb78c566ccfe --- /dev/null +++ b/snake_game/snake_game.c @@ -0,0 +1,545 @@ +#include "snake_game.h" +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +static snake_game_t g_game; +static int last_score = 0; // Track the previous score +static int no_score_frames = 0; // Count frames without score increase + +// Forward declarations +static void snake_game_draw(void); +static void snake_game_timer_cb(lv_timer_t* timer); +static void snake_game_key_event_cb(lv_event_t* e); +static void generate_food(void); +static void auto_move(void); +static void start_button_event_cb(lv_event_t * e); +static void restart_button_event_cb(lv_event_t * e); + +void snake_game_create(void) +{ + // Create main interface + lv_obj_t* root = lv_obj_create(lv_scr_act()); + lv_obj_set_size(root, GAME_GRID_SIZE * GAME_GRID_WIDTH, GAME_GRID_SIZE * GAME_GRID_HEIGHT + 40); + lv_obj_center(root); + lv_obj_set_style_bg_color(root, lv_color_hex(0x000000), 0); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); // Disable scrolling + lv_obj_add_flag(root, LV_OBJ_FLAG_CLICKABLE); // Enable click + + // Create game canvas + g_game.ui.canvas = lv_canvas_create(root); + lv_obj_align(g_game.ui.canvas, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_size(g_game.ui.canvas, GAME_GRID_SIZE * GAME_GRID_WIDTH, GAME_GRID_SIZE * GAME_GRID_HEIGHT); + lv_obj_set_style_bg_color(g_game.ui.canvas, lv_color_hex(0x000000), 0); + + // Create score label + g_game.ui.score_label = lv_label_create(root); + lv_obj_align(g_game.ui.score_label, LV_ALIGN_BOTTOM_LEFT, 10, -5); + lv_obj_set_style_text_color(g_game.ui.score_label, lv_color_white(), 0); + + // Create status label + g_game.ui.status_label = lv_label_create(root); + lv_obj_align(g_game.ui.status_label, LV_ALIGN_BOTTOM_RIGHT, -10, -5); + lv_obj_set_style_text_color(g_game.ui.status_label, lv_color_white(), 0); + + // Create start button + g_game.ui.start_btn = lv_btn_create(root); + lv_obj_set_size(g_game.ui.start_btn, 200, 60); + lv_obj_center(g_game.ui.start_btn); + lv_obj_add_event_cb(g_game.ui.start_btn, start_button_event_cb, LV_EVENT_CLICKED, NULL); + + // Add label to the start button + lv_obj_t * start_label = lv_label_create(g_game.ui.start_btn); + lv_label_set_text(start_label, "START"); + lv_obj_set_style_text_font(start_label, &lv_font_montserrat_24, 0); + lv_obj_center(start_label); + + // Create restart button (initially hidden) + g_game.ui.restart_btn = lv_btn_create(root); + lv_obj_set_size(g_game.ui.restart_btn, 200, 60); + lv_obj_center(g_game.ui.restart_btn); + lv_obj_add_event_cb(g_game.ui.restart_btn, restart_button_event_cb, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(g_game.ui.restart_btn, LV_OBJ_FLAG_HIDDEN); // Initially hidden + + // Add label to the restart button + lv_obj_t * restart_label = lv_label_create(g_game.ui.restart_btn); + lv_label_set_text(restart_label, "RESTART"); + lv_obj_set_style_text_font(restart_label, &lv_font_montserrat_24, 0); + lv_obj_center(restart_label); + + // Initialize game in paused state + g_game.status = GAME_STATUS_INIT; + g_game.game_timer = lv_timer_create(snake_game_timer_cb, 50, NULL); + lv_timer_pause(g_game.game_timer); + + // Set initial labels + lv_label_set_text(g_game.ui.score_label, "Score: 0"); + lv_label_set_text(g_game.ui.status_label, "Ready"); + + // Add keyboard event processing + lv_obj_t* scr = lv_scr_act(); + lv_obj_add_event_cb(scr, snake_game_key_event_cb, LV_EVENT_KEY, NULL); + + // Set group and focus + lv_group_t* g = lv_group_create(); + lv_group_add_obj(g, scr); + lv_indev_t* kb_indev = lv_indev_get_next(NULL); + while(kb_indev) { + if(lv_indev_get_type(kb_indev) == LV_INDEV_TYPE_KEYPAD) { + lv_indev_set_group(kb_indev, g); + break; + } + kb_indev = lv_indev_get_next(kb_indev); + } + lv_group_focus_obj(scr); +} + +void snake_game_init(void) +{ + // Initialize random number generator + srand(time(NULL)); + + // Initialize snake + g_game.snake_head = malloc(sizeof(snake_node_t)); + g_game.snake_head->x = GAME_GRID_WIDTH / 2; + g_game.snake_head->y = GAME_GRID_HEIGHT / 2; + g_game.snake_head->next = NULL; + + // Initialize game state + g_game.direction = DIR_RIGHT; + g_game.score = 0; + + // Reset infinite loop detection variables + last_score = 0; + no_score_frames = 0; + + // Generate first food + generate_food(); + + // Update display + lv_label_set_text(g_game.ui.score_label, "Score: 0"); +} + +static void snake_game_timer_cb(lv_timer_t* timer) +{ + if (g_game.status != GAME_STATUS_RUNNING) { + return; + } + + // Check for infinite loop condition + if (g_game.score == last_score) { + no_score_frames++; + // If no score increase for 300 frames (about 15 seconds), consider it stuck + if (no_score_frames > 300) { + g_game.status = GAME_STATUS_OVER; + lv_label_set_text(g_game.ui.status_label, "STUCK! GAME OVER"); + lv_timer_pause(g_game.game_timer); + // Show restart button + lv_obj_clear_flag(g_game.ui.restart_btn, LV_OBJ_FLAG_HIDDEN); + lv_obj_t* restart_label = lv_obj_get_child(g_game.ui.restart_btn, 0); + lv_label_set_text(restart_label, "RESTART"); + return; + } + } else { + // Reset counter when score changes + last_score = g_game.score; + no_score_frames = 0; + } + + // Check score for victory + if (g_game.score >= 1000) { + lv_label_set_text(g_game.ui.status_label, "Victory!"); + g_game.status = GAME_STATUS_OVER; + lv_timer_pause(g_game.game_timer); + // Show victory button + lv_obj_clear_flag(g_game.ui.restart_btn, LV_OBJ_FLAG_HIDDEN); + lv_obj_t* restart_label = lv_obj_get_child(g_game.ui.restart_btn, 0); + lv_label_set_text(restart_label, "Victory!"); + return; + } + + // Auto move + auto_move(); + + // Save old head position + int old_x = g_game.snake_head->x; + int old_y = g_game.snake_head->y; + + // Move snake head according to direction + switch (g_game.direction) { + case DIR_UP: g_game.snake_head->y--; break; + case DIR_DOWN: g_game.snake_head->y++; break; + case DIR_LEFT: g_game.snake_head->x--; break; + case DIR_RIGHT: g_game.snake_head->x++; break; + } + + // Handle wall collision - turn around instead of crossing + bool wall_collision = false; + if (g_game.snake_head->x < 0 || g_game.snake_head->x >= GAME_GRID_WIDTH || + g_game.snake_head->y < 0 || g_game.snake_head->y >= GAME_GRID_HEIGHT) { + // Restore position + g_game.snake_head->x = old_x; + g_game.snake_head->y = old_y; + // Reverse direction + switch (g_game.direction) { + case DIR_UP: g_game.direction = DIR_DOWN; break; + case DIR_DOWN: g_game.direction = DIR_UP; break; + case DIR_LEFT: g_game.direction = DIR_RIGHT; break; + case DIR_RIGHT: g_game.direction = DIR_LEFT; break; + } + wall_collision = true; + + // Execute one step in the new direction immediately + switch (g_game.direction) { + case DIR_UP: g_game.snake_head->y--; break; + case DIR_DOWN: g_game.snake_head->y++; break; + case DIR_LEFT: g_game.snake_head->x--; break; + case DIR_RIGHT: g_game.snake_head->x++; break; + } + } + + // Check self collision + snake_node_t* check_node = g_game.snake_head->next; + bool self_collision = false; + while (check_node != NULL) { + if (check_node->x == g_game.snake_head->x && check_node->y == g_game.snake_head->y) { + self_collision = true; + break; + } + check_node = check_node->next; + } + + if (self_collision) { + // If hit self, game over + g_game.snake_head->x = old_x; + g_game.snake_head->y = old_y; + g_game.status = GAME_STATUS_OVER; + lv_label_set_text(g_game.ui.status_label, "GAME OVER"); + lv_timer_pause(g_game.game_timer); + // Show restart button + lv_obj_clear_flag(g_game.ui.restart_btn, LV_OBJ_FLAG_HIDDEN); + return; + } + + // Check if food is eaten + if (g_game.snake_head->x == g_game.food_x && g_game.snake_head->y == g_game.food_y) { + // Increase score + g_game.score += 10; + char score_text[32]; + sprintf(score_text, "Score: %d", g_game.score); + lv_label_set_text(g_game.ui.score_label, score_text); + + // Generate new food + generate_food(); + + // Increase snake length + snake_node_t* new_node = malloc(sizeof(snake_node_t)); + new_node->x = old_x; + new_node->y = old_y; + new_node->next = g_game.snake_head->next; + g_game.snake_head->next = new_node; + } else { + // Move snake body + snake_node_t* move_node = g_game.snake_head->next; + while (move_node != NULL) { + int temp_x = move_node->x; + int temp_y = move_node->y; + move_node->x = old_x; + move_node->y = old_y; + old_x = temp_x; + old_y = temp_y; + move_node = move_node->next; + } + } + + if (wall_collision) { + // Recalculate path after turning around + auto_move(); + } + + // Update display + snake_game_draw(); +} + +static void snake_game_key_event_cb(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_KEY) { + uint32_t key = lv_event_get_key(e); + + switch (key) { + case LV_KEY_UP: + if (g_game.direction != DIR_DOWN) { + g_game.direction = DIR_UP; + } + break; + case LV_KEY_DOWN: + if (g_game.direction != DIR_UP) { + g_game.direction = DIR_DOWN; + } + break; + case LV_KEY_LEFT: + if (g_game.direction != DIR_RIGHT) { + g_game.direction = DIR_LEFT; + } + break; + case LV_KEY_RIGHT: + if (g_game.direction != DIR_LEFT) { + g_game.direction = DIR_RIGHT; + } + break; + case LV_KEY_ENTER: + if (g_game.status == GAME_STATUS_INIT || g_game.status == GAME_STATUS_OVER) { + snake_game_init(); + g_game.status = GAME_STATUS_RUNNING; + lv_label_set_text(g_game.ui.status_label, "In Game"); + lv_timer_resume(g_game.game_timer); + } else if (g_game.status == GAME_STATUS_RUNNING) { + g_game.status = GAME_STATUS_PAUSED; + lv_label_set_text(g_game.ui.status_label, "Paused"); + lv_timer_pause(g_game.game_timer); + } else if (g_game.status == GAME_STATUS_PAUSED) { + g_game.status = GAME_STATUS_RUNNING; + lv_label_set_text(g_game.ui.status_label, "In Game"); + lv_timer_resume(g_game.game_timer); + } + break; + } + } +} + +static void snake_game_draw(void) +{ + // Delete all objects on canvas + lv_obj_clean(g_game.ui.canvas); + + // Reset canvas background color + lv_obj_set_style_bg_color(g_game.ui.canvas, lv_color_hex(0x000000), 0); + + // Draw food + lv_obj_t* food = lv_obj_create(g_game.ui.canvas); + lv_obj_set_size(food, GAME_GRID_SIZE - 2, GAME_GRID_SIZE - 2); + lv_obj_set_pos(food, g_game.food_x * GAME_GRID_SIZE + 1, g_game.food_y * GAME_GRID_SIZE + 1); + lv_obj_set_style_bg_color(food, lv_color_hex(0xFF0000), 0); + + // Draw snake + snake_node_t* current = g_game.snake_head; + while (current != NULL) { + lv_obj_t* node = lv_obj_create(g_game.ui.canvas); + lv_obj_set_size(node, GAME_GRID_SIZE - 2, GAME_GRID_SIZE - 2); + lv_obj_set_pos(node, current->x * GAME_GRID_SIZE + 1, current->y * GAME_GRID_SIZE + 1); + if (current == g_game.snake_head) { + // Different color for snake head + lv_obj_set_style_bg_color(node, lv_color_hex(0x00FF00), 0); + } else { + // Darker color for snake body + lv_obj_set_style_bg_color(node, lv_color_hex(0x008800), 0); + } + current = current->next; + } +} + +static void generate_food(void) +{ + bool valid; + int attempts = 0; + const int MAX_ATTEMPTS = 100; // Maximum attempts to find optimal position + const int MIN_BORDER_DISTANCE = 2; // Minimum distance from borders + + do { + valid = true; + if (attempts < MAX_ATTEMPTS) { + // Try to generate food away from borders first + g_game.food_x = MIN_BORDER_DISTANCE + (rand() % (GAME_GRID_WIDTH - 2 * MIN_BORDER_DISTANCE)); + g_game.food_y = MIN_BORDER_DISTANCE + (rand() % (GAME_GRID_HEIGHT - 2 * MIN_BORDER_DISTANCE)); + } else { + // If too many attempts, allow food anywhere as fallback + g_game.food_x = rand() % GAME_GRID_WIDTH; + g_game.food_y = rand() % GAME_GRID_HEIGHT; + } + + // Check if food is generated on snake body + snake_node_t* current = g_game.snake_head; + while (current != NULL) { + if (current->x == g_game.food_x && current->y == g_game.food_y) { + valid = false; + break; + } + current = current->next; + } + + attempts++; + + // If snake is too long and we can't find space in preferred area, + // allow food generation anywhere after MAX_ATTEMPTS tries + if (attempts > MAX_ATTEMPTS && !valid) { + g_game.food_x = rand() % GAME_GRID_WIDTH; + g_game.food_y = rand() % GAME_GRID_HEIGHT; + valid = true; // Force exit but keep checking snake collision + } + } while (!valid); +} + +static bool is_position_safe(int x, int y) { + // Check if position is out of bounds + if (x < 0 || x >= GAME_GRID_WIDTH || y < 0 || y >= GAME_GRID_HEIGHT) { + return false; + } + + // Check if position collides with snake body + snake_node_t* check_node = g_game.snake_head->next; + while (check_node != NULL) { + if (check_node->x == x && check_node->y == y) { + return false; + } + check_node = check_node->next; + } + + return true; +} + +static void auto_move(void) +{ + int current_x = g_game.snake_head->x; + int current_y = g_game.snake_head->y; + + // Define possible movement directions + struct { + direction_t dir; + int dx; + int dy; + bool opposite; + } directions[] = { + {DIR_UP, 0, -1, g_game.direction == DIR_DOWN}, + {DIR_DOWN, 0, 1, g_game.direction == DIR_UP}, + {DIR_LEFT, -1, 0, g_game.direction == DIR_RIGHT}, + {DIR_RIGHT, 1, 0, g_game.direction == DIR_LEFT} + }; + + // Find best movement direction + direction_t best_dir = g_game.direction; + bool found_safe_move = false; + int best_score = -1; + + // Calculate Manhattan distance to food + int food_distance = abs(g_game.food_x - current_x) + abs(g_game.food_y - current_y); + + // Evaluate each possible direction + for (int i = 0; i < 4; i++) { + if (directions[i].opposite) continue; // Don't move in opposite direction + + int new_x = current_x + directions[i].dx; + int new_y = current_y + directions[i].dy; + + if (!is_position_safe(new_x, new_y)) continue; + + // Calculate score for this direction + int score = 0; + + // 1. Check safe spaces in 8 surrounding cells + int safe_spaces = 0; + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx == 0 && dy == 0) continue; + if (is_position_safe(new_x + dx, new_y + dy)) { + safe_spaces++; + } + } + } + score += safe_spaces * 3; // Increase weight of safe spaces + + // 2. Calculate new distance to food + int new_food_distance = abs(g_game.food_x - new_x) + abs(g_game.food_y - new_y); + + // Add score if getting closer to food + if (new_food_distance < food_distance) { + score += 10; // Increase weight of food direction + } + + // 3. Look ahead two steps + for (int j = 0; j < 4; j++) { + if (directions[j].opposite) continue; + int look_x = new_x + directions[j].dx; + int look_y = new_y + directions[j].dy; + if (is_position_safe(look_x, look_y)) { + score += 2; // Reward paths with more future options + } + } + + // 4. Avoid moving along walls + if ((new_x == 0 || new_x == GAME_GRID_WIDTH - 1) && + (new_y > 0 && new_y < GAME_GRID_HEIGHT - 1)) { + score -= 5; // Penalty for moving along vertical walls + } + if ((new_y == 0 || new_y == GAME_GRID_HEIGHT - 1) && + (new_x > 0 && new_x < GAME_GRID_WIDTH - 1)) { + score -= 5; // Penalty for moving along horizontal walls + } + + // 5. Prefer current direction only if other factors are equal + if (directions[i].dir == g_game.direction) { + score += 1; + } + + // Update best direction + if (score > best_score) { + best_score = score; + best_dir = directions[i].dir; + found_safe_move = true; + } + } + + // Update direction if safe move found + if (found_safe_move) { + g_game.direction = best_dir; + } +} + +static void start_button_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_CLICKED) { + // Hide the start button + lv_obj_t * btn = lv_event_get_target(e); + lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); + + // Start the game + snake_game_init(); + g_game.status = GAME_STATUS_RUNNING; + lv_label_set_text(g_game.ui.status_label, "Auto Running"); + lv_timer_resume(g_game.game_timer); + } +} + +static void restart_button_event_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + if(code == LV_EVENT_CLICKED) { + // Hide the restart button + lv_obj_t * btn = lv_event_get_target(e); + lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); + + // Start new game + snake_game_init(); + g_game.status = GAME_STATUS_RUNNING; + lv_label_set_text(g_game.ui.status_label, "Auto Running"); + lv_timer_resume(g_game.game_timer); + } +} + +void snake_game_deinit(void) +{ + // Free snake body memory + snake_node_t* current = g_game.snake_head; + while (current != NULL) { + snake_node_t* next = current->next; + free(current); + current = next; + } + + // Delete timer + if (g_game.game_timer) { + lv_timer_del(g_game.game_timer); + g_game.game_timer = NULL; + } +} \ No newline at end of file diff --git a/snake_game/snake_game.h b/snake_game/snake_game.h new file mode 100755 index 0000000000000000000000000000000000000000..7cb28192d8f579b99f091889e69db6a6a32b6dc5 --- /dev/null +++ b/snake_game/snake_game.h @@ -0,0 +1,66 @@ +#ifndef __SNAKE_GAME_H__ +#define __SNAKE_GAME_H__ + +#include <lvgl/lvgl.h> + +// Game grid size +#define GAME_GRID_SIZE 20 // Size of each grid cell (pixels) +#define GAME_GRID_WIDTH 60 // Game area width (cells) +#define GAME_GRID_HEIGHT 35 // Game area height (cells) + +// Game status +typedef enum { + GAME_STATUS_INIT, + GAME_STATUS_RUNNING, + GAME_STATUS_PAUSED, + GAME_STATUS_OVER +} game_status_t; + +// Movement direction +typedef enum { + DIR_UP, + DIR_DOWN, + DIR_LEFT, + DIR_RIGHT +} direction_t; + +// Snake node structure +typedef struct snake_node { + int x; + int y; + struct snake_node* next; +} snake_node_t; + +// UI structure +typedef struct { + lv_obj_t *canvas; // Game canvas + lv_obj_t *score_label; // Score display + lv_obj_t *status_label; // Status display + lv_obj_t *start_btn; // Start button + lv_obj_t *restart_btn; // Restart button +} snake_game_ui_t; + +// Font structure +typedef struct { + lv_font_t *font; // Game font +} snake_game_fonts_t; + +// Game state structure +typedef struct { + snake_game_ui_t ui; // UI elements + snake_game_fonts_t fonts; // Font resources + snake_node_t* snake_head; // Snake head pointer + direction_t direction; // Current movement direction + int food_x; // Food X coordinate + int food_y; // Food Y coordinate + int score; // Current score + game_status_t status; // Game status + lv_timer_t* game_timer; // Game timer +} snake_game_t; + +// Function declarations +void snake_game_create(void); +void snake_game_init(void); +void snake_game_deinit(void); + +#endif /* __SNAKE_GAME_H__ */ \ No newline at end of file diff --git a/snake_game/snake_game_main.c b/snake_game/snake_game_main.c new file mode 100755 index 0000000000000000000000000000000000000000..42d24ef00a7e7c8f5e1474c6d06e2241d25d6096 --- /dev/null +++ b/snake_game/snake_game_main.c @@ -0,0 +1,79 @@ +#include <nuttx/config.h> +#include <unistd.h> + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +#include <uv.h> +#endif + +#include <lvgl/lvgl.h> +#include "snake_game.h" + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +static void lv_nuttx_uv_loop(uv_loop_t *loop, lv_nuttx_result_t *result) +{ + lv_nuttx_uv_t uv_info; + void *data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} +#endif + +int main(int argc, FAR char *argv[]) +{ + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); +#endif + + if (lv_is_initialized()) + { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) + { + LV_LOG_ERROR("LVGL initialization failure!"); + return 1; + } + + snake_game_create(); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + lv_nuttx_uv_loop(&ui_loop, &result); +#endif + + while (1) + { + uint32_t idle; + idle = lv_timer_handler(); + idle = idle ? idle : 1; + usleep(idle * 1000); + } + + snake_game_deinit(); + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} \ No newline at end of file diff --git a/wooden_fish/Kconfig b/wooden_fish/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..769c8b2c8054db511f4626e2713afaac4678b4d8 --- /dev/null +++ b/wooden_fish/Kconfig @@ -0,0 +1,14 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_WOODEN_FISH + bool "Wooden Fish" + default n + +if LVX_USE_DEMO_WOODEN_FISH + config LVX_WOODEN_FISH_DATA_ROOT + string "WOO FIS Data Root" + default "/data" +endif diff --git a/wooden_fish/Make.defs b/wooden_fish/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..4634dab232b568e4920e11b26db0d040c39b8c49 --- /dev/null +++ b/wooden_fish/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2023 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_WOODEN_FISH),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/wooden_fish +endif diff --git a/wooden_fish/Makefile b/wooden_fish/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0b516f7889e7445a16a7491534fe590398b59b22 --- /dev/null +++ b/wooden_fish/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (C) 2022 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_WOODEN_FISH), y) +PROGNAME = wooden_fish +PRIORITY = 100 +STACKSIZE = 131072 +MODULE = $(CONFIG_LVX_USE_DEMO_WOODEN_FISH) + +CSRCS = wooden_fish.c audio_ctl.c +MAINSRC = wooden_fish_main.c +endif + +include $(APPDIR)/Application.mk + diff --git a/wooden_fish/README.md b/wooden_fish/README.md new file mode 100644 index 0000000000000000000000000000000000000000..46f1a85bc87b6d07532cde129669bbdd37c5f11c --- /dev/null +++ b/wooden_fish/README.md @@ -0,0 +1,221 @@ +# Wooden Fish Demo Quick Start + +\[ English | [简体中文](./README_zh-cn.md) \] + +This document provides a comprehensive guide on how to build, deploy, and run the Wooden Fish demo application on the OpenVela system for QEMU emulator. You'll learn how to configure the project, compile firmware, run the application, and make custom modifications. + +## 1. Demo Features + +The Wooden Fish application provides the following features: +- 🐠 **Manual Tapping**: Click the wooden fish image to tap and increase merit points +- 🔄 **Auto Mode**: Enable auto-tapping switch for automatic tapping every 2 seconds +- 💻 **Programmer Mode**: Switch to programmer theme where merit becomes PR (Pull Request) +- 🔊 **Audio Feedback**: Play wooden fish sound effect with each tap +- ✨ **Animation Effects**: Display "Merit+1" or "pr+1" flying text animation when tapping + +![Wooden Fish Demo](res/wooden_fish_demo.gif) + +## 2. Build and Run + +This section will guide you through the complete process from project configuration to running the application on your target platform. + +### Prerequisites + +Before starting, ensure you are in the root directory of the `openvela` repository. All commands in this document start from this location. + +### Step 1: Project Configuration + +You need to use the `menuconfig` tool to enable the Wooden Fish application and configure related settings. + +1. Launch `menuconfig`. Choose the appropriate command based on your target platform: + + - QEMU Emulator: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + +2. In the `menuconfig` interface, press `/` to open search function, find and enable the following configuration items: + + ```Bash + LVX_USE_DEMO_WOODEN_FISH=y + LVX_WOODEN_FISH_DATA_ROOT="/data" + ``` + +3. **(Optional)** If you encounter interface lag or display issues during runtime, try increasing the LVGL (Light and Versatile Graphics Library) cache size. Search for `lv_cache_def_size` and set its value to `20000000`. + +4. **(Audio Support)** Ensure audio-related configurations are enabled to support wooden fish sound effects: + ```Bash + CONFIG_AUDIO=y + CONFIG_AUDIOUTILS=y + CONFIG_AUDIOUTILS_NXAUDIO=y + ``` + +5. Save configuration and exit `menuconfig`. + +### Step 2: Build Project + +Before building, it's recommended to clean old build artifacts to avoid potential build errors. + +1. Clean build artifacts (distclean): + + - QEMU Emulator: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 + ``` + +2. Execute build: + + - QEMU Emulator: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 + ``` + +### Step 3: Deploy and Run + +After successful compilation, you can deploy the firmware to the target platform and launch the application. + +#### Option A: Run in QEMU Emulator + +1. In the `openvela` root directory, execute the following command to start the emulator: + + ```Bash + ./emulator.sh vela + ``` + +2. After the openvela terminal (`openvela-ap>`) appears, enter the following command to start the Wooden Fish: + + ```Bash + wooden_fish + ``` + +## 3. Application Customization + +You can modify the application's core functionality according to your needs, such as replacing resources or adjusting behavior parameters. + +### Core File Structure + +- `wooden_fish.c`: Contains the core application logic, including UI creation, event handling, animation effects, etc. All feature development and modifications should be done in this file. +- `wooden_fish.h`: Defines application data structures, configuration parameters, and function declarations. +- `wooden_fish_main.c`: Serves as the application entry point, responsible for creating and starting the task that runs the application logic. Usually, you don't need to modify this file. +- `audio_ctl.c` / `audio_ctl.h`: Audio control module responsible for sound effect playback. + +### Modifying Resource Files + +The images, audio, and font resources used by the application are located in the `res/` directory. + +#### Image Resources +- `res/wooden_fish.png`: Traditional wooden fish image +- `res/enter_white.png`: Enter key image for programmer mode + +You can replace these image files, but please ensure: +- Image format is PNG +- Resolution is suitable for target display device +- File names remain consistent + +#### Audio Resources +- `res/knock.wav`: Tapping sound effect file + +To replace sound effects: +1. Prepare WAV format audio file +2. Ensure compatible sample rate and bit depth (recommended 16-bit, 44.1kHz) +3. Replace the `res/knock.wav` file + +#### Font Resources +- `res/fonts/MiSans-Normal.ttf`: Font file used by the application + +### Adjusting Application Parameters + +#### Auto-tapping Frequency +In the `auto_knock_timer_cb` function, auto-tapping interval is controlled by a timer: + +```C +// Start auto-tapping timer (every 2 seconds) +app->auto_timer = lv_timer_create(auto_knock_timer_cb, 2000, app); +``` + +To adjust frequency: +- **Increase frequency**: Decrease time value (e.g., `1500` milliseconds) +- **Decrease frequency**: Increase time value (e.g., `3000` milliseconds) + +#### Debounce Time +In the `play_wooden_fish_sound` function, debounce mechanism prevents too-rapid clicking: + +```C +// Debounce: only play once within 500ms +if (current_time - last_play_time < 500) { + return; +} +``` + +Adjust debounce time to change response sensitivity. + +#### Animation Effects +In the `create_merit_animation` function you can adjust flying text animation: + +```C +// Adjust animation time and distance +lv_anim_set_values(&move_anim, label_y, label_y - 120); // Movement distance +lv_anim_set_time(&move_anim, 1500); // Animation duration +``` + +## 4. Technical Features + +### Audio System +- Uses NuttX nxaudio framework +- Supports WAV format audio playback +- Implements safe resource management to avoid memory leaks + +### UI System +- Based on LVGL graphics library +- Responsive layout design +- Smooth animation effects + +### State Management +- Singleton pattern for audio resource management +- Debounce mechanism improves user experience +- Unified resource cleanup mechanism + +## 5. Troubleshooting + +### Common Issues + +#### Audio Not Playing +1. Check if audio configuration is correctly enabled +2. Confirm `res/knock.wav` file exists +3. Check if audio device is working properly + +#### UI Display Issues +1. Check if font files are loaded correctly +2. Increase LVGL cache size +3. Confirm image resource paths are correct + +#### Application Crashes +1. Check if memory configuration is sufficient +2. View error messages in serial output +3. Confirm all dependencies are correctly compiled + +### Debugging Methods + +Enable debug logging: +```C +#define LV_USE_LOG 1 +#define LV_LOG_LEVEL LV_LOG_LEVEL_TRACE +``` + +View runtime logs for detailed debugging information. + +## 6. Contribution Guide + +We welcome improvement suggestions and feature enhancements! Before submitting a PR, please ensure: + +1. Code style follows project standards +2. Appropriate comments and documentation are added +3. Basic functionality has been tested to work properly +4. Related README documentation has been updated + +--- + +**Note**: This documentation is written based on the OpenVela development environment. If you encounter platform-related issues, please refer to the OpenVela official documentation or submit an Issue in the project repository. diff --git a/wooden_fish/README_zh-cn.md b/wooden_fish/README_zh-cn.md new file mode 100644 index 0000000000000000000000000000000000000000..19d0c10609547a9b22bb3409252047d9bb719a47 --- /dev/null +++ b/wooden_fish/README_zh-cn.md @@ -0,0 +1,222 @@ +# 电子木鱼 Demo 快速上手 + +\[ [English](./README.md) | 简体中文 \] + +本文档详细介绍如何在 openvela 系统上为 QEMU 模拟器构建、部署和运行电子木鱼(Wooden Fish)演示应用程序。您将学习如何配置项目、编译固件、运行应用,并对功能进行自定义修改。 + +## 一、运行效果 + +电子木鱼应用提供以下功能: +- 🐠 **手动敲击**:点击木鱼图片进行敲击,增加功德值 +- 🔄 **自动模式**:开启自动敲击开关,每2秒自动敲击一次 +- 💻 **程序猿模式**:切换到程序猿主题,功德变为PR(Pull Request) +- 🔊 **音效反馈**:每次敲击播放木鱼音效 +- ✨ **动画效果**:敲击时显示"功德+1"或"pr+1"飞字动画 + +![电子木鱼演示](res/wooden_fish_demo.gif) + +## 二、构建与运行 + +本节将指导您完成从项目配置到在目标平台上运行应用程序的完整流程。 + +### 准备工作 + +在开始之前,请确保您已位于 `openvela` 仓库的根目录下。本文中的所有命令均以此为起点。 + +### 步骤 1:配置项目 + +您需要通过 `menuconfig` 工具来启用电子木鱼应用并进行相关设置。 + +1. 启动 `menuconfig`。请根据您的目标平台选择对应的命令: + + - QEMU 模拟器: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap menuconfig + ``` + +2. 在 `menuconfig` 界面中,按 `/` 键打开搜索功能,查找并启用以下配置项: + + ```Bash + LVX_USE_DEMO_WOODEN_FISH=y + LVX_WOODEN_FISH_DATA_ROOT="/data" + ``` + +3. **(可选)** 如果您在运行时遇到界面卡顿或显示不流畅的问题,可以尝试增加 LVGL (Light and Versatile Graphics Library) 的缓存大小。搜索 `lv_cache_def_size` 并将其值设置为 `20000000`。 + +4. **(音频支持)** 确保启用音频相关配置以支持木鱼音效: + ```Bash + CONFIG_AUDIO=y + CONFIG_AUDIOUTILS=y + CONFIG_AUDIOUTILS_NXAUDIO=y + ``` + +5. 保存配置并退出 `menuconfig`。 + +### 步骤 2:编译项目 + +编译前,建议先清理旧的构建产物以避免潜在的构建错误。 + +1. 清理构建产物 (distclean): + + - QEMU 模拟器: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap distclean -j8 + ``` + +2. 执行构建: + + - QEMU 模拟器: + + ```Bash + ./build.sh vendor/openvela/boards/vela/configs/goldfish-armeabi-v7a-ap -j8 + ``` + + +### 步骤 3:部署与运行 + +编译成功后,您可以将固件部署到目标平台并启动应用。 + +#### 选项 A:在 QEMU 模拟器中运行 + +1. 在 `openvela` 根目录,执行以下命令启动模拟器: + + ```Bash + ./emulator.sh vela + ``` + +2. 等待 openvela 终端(`openvela-ap>`)出现后,输入以下命令启动电子木鱼: + + ```Bash + wooden_fish + ``` + +## 三、应用定制 + +您可以根据需求修改应用的核心功能,例如替换资源或调整行为参数。 + +### 核心文件结构 + +- `wooden_fish.c`: 包含应用的核心逻辑,包括UI创建、事件处理、动画效果等。所有功能开发和修改都应在此文件中进行。 +- `wooden_fish.h`: 定义应用的数据结构、配置参数和函数声明。 +- `wooden_fish_main.c`: 作为应用程序的入口,负责创建并启动运行应用逻辑的任务。通常情况下,您无需修改此文件。 +- `audio_ctl.c` / `audio_ctl.h`: 音频控制模块,负责音效播放。 + +### 修改资源文件 + +应用使用的图片、音频和字体资源位于 `res/` 目录下。 + +#### 图片资源 +- `res/wooden_fish.png`: 传统木鱼图片 +- `res/enter_white.png`: 程序猿模式的Enter键图片 + +您可以替换这些图片文件,但请确保: +- 图片格式为PNG +- 分辨率适合目标显示设备 +- 文件名保持一致 + +#### 音频资源 +- `res/knock.wav`: 敲击音效文件 + +要替换音效: +1. 准备WAV格式的音频文件 +2. 确保采样率和位深度兼容(推荐16位,44.1kHz) +3. 替换 `res/knock.wav` 文件 + +#### 字体资源 +- `res/fonts/MiSans-Normal.ttf`: 应用使用的字体文件 + +### 调整应用参数 + +#### 自动敲击频率 +在 `auto_knock_timer_cb` 函数中,自动敲击的间隔由定时器控制: + +``` +// 启动自动敲击定时器 (每2秒一次) +app->auto_timer = lv_timer_create(auto_knock_timer_cb, 2000, app); +``` + +要调整频率: +- **加快频率**: 减小时间值(例如 `1500` 毫秒) +- **放慢频率**: 增大时间值(例如 `3000` 毫秒) + +#### 防抖时间 +在 `play_wooden_fish_sound` 函数中,防抖机制防止过快点击: + +```C +// 防抖:500ms内只播放一次 +if (current_time - last_play_time < 500) { + return; +} +``` + +调整防抖时间来改变响应敏感度。 + +#### 动画效果 +在 `create_merit_animation` 函数中可以调整飞字动画: + +```C +// 调整动画时间和距离 +lv_anim_set_values(&move_anim, label_y, label_y - 120); // 移动距离 +lv_anim_set_time(&move_anim, 1500); // 动画时长 +``` + +## 四、技术特性 + +### 音频系统 +- 使用 NuttX 的 nxaudio 框架 +- 支持WAV格式音频播放 +- 实现了安全的资源管理,避免内存泄漏 + +### UI系统 +- 基于 LVGL 图形库 +- 响应式布局设计 +- 流畅的动画效果 + +### 状态管理 +- 单例模式管理音频资源 +- 防抖机制提升用户体验 +- 统一的资源清理机制 + +## 五、故障排除 + +### 常见问题 + +#### 音频无法播放 +1. 检查音频配置是否正确启用 +2. 确认 `res/knock.wav` 文件存在 +3. 检查音频设备是否正常工作 + +#### 界面显示异常 +1. 检查字体文件是否正确加载 +2. 增加 LVGL 缓存大小 +3. 确认图片资源路径正确 + +#### 应用崩溃 +1. 检查内存配置是否足够 +2. 查看串口输出的错误信息 +3. 确认所有依赖项已正确编译 + +### 调试方法 + +启用调试日志: +``` +#define LV_USE_LOG 1 +#define LV_LOG_LEVEL LV_LOG_LEVEL_TRACE +``` + +查看运行时日志以获取详细的调试信息。 + +## 六、贡献指南 + +欢迎提交改进建议和功能增强!在提交PR前,请确保: + +1. 代码风格符合项目规范 +2. 添加了适当的注释和文档 +3. 测试了基本功能的正常运行 +4. 更新了相关的README文档 + +--- + +**注意**:本文档基于 openvela 开发环境编写。如遇到平台相关问题,请参考 openvela 官方文档或在项目仓库中提交Issue。 diff --git a/wooden_fish/audio_ctl.c b/wooden_fish/audio_ctl.c new file mode 100644 index 0000000000000000000000000000000000000000..df6d0a3519b07d042335b0dac606d8b6fe0e89e8 --- /dev/null +++ b/wooden_fish/audio_ctl.c @@ -0,0 +1,287 @@ +/********************* + * INCLUDES + *********************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "audio_ctl.h" +#include "wooden_fish.h" // 声明回调 + +#include <audioutils/nxaudio.h> + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void app_dequeue_cb(unsigned long arg, + FAR struct ap_buffer_s *apb); +static void app_complete_cb(unsigned long arg); +static void app_user_cb(unsigned long arg, + FAR struct audio_msg_s *msg, FAR bool *running); + +/********************** + * STATIC VARIABLES + **********************/ + +static struct nxaudio_callbacks_s cbs = +{ + app_dequeue_cb, + app_complete_cb, + app_user_cb +}; + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void app_dequeue_cb(unsigned long arg, FAR struct ap_buffer_s *apb) +{ + FAR audioctl_s *ctl = (FAR audioctl_s *)(uintptr_t)arg; + + if (!apb) + { + return; + } + + if (ctl->seek) { + lseek(ctl->fd, ctl->seek_position, SEEK_SET); + ctl->file_position = ctl->seek_position; + ctl->seek = false; + } + + apb->nbytes = read(ctl->fd, apb->samp, apb->nmaxbytes); + apb->curbyte = 0; + apb->flags = 0; + + while (0 < apb->nbytes && apb->nbytes < apb->nmaxbytes) + { + int n = apb->nmaxbytes - apb->nbytes; + int ret = read(ctl->fd, &apb->samp[apb->nbytes], n); + + if (0 >= ret) + { + break; + } + apb->nbytes += ret; + } + + if (apb->nbytes < apb->nmaxbytes) + { + close(ctl->fd); + ctl->fd = -1; + + return ; + } + + ctl->file_position += apb->nbytes; + + nxaudio_enqbuffer(&ctl->nxaudio, apb); +} + +static void app_complete_cb(unsigned long arg) +{ + /* Audio playback completed - do not auto-cleanup to avoid crashes */ + printf("Audio playback completed\n"); +} + +static void app_user_cb(unsigned long arg, + FAR struct audio_msg_s *msg, FAR bool *running) +{ + /* Do nothing.. */ +} + +static FAR void *audio_loop_thread(pthread_addr_t arg) +{ + FAR audioctl_s *ctl = (FAR audioctl_s *)arg; + + nxaudio_start(&ctl->nxaudio); + nxaudio_msgloop(&ctl->nxaudio, &cbs, + (unsigned long)(uintptr_t)ctl); + + return NULL; +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +FAR audioctl_s *audio_ctl_init_nxaudio(FAR const char *arg) +{ + FAR audioctl_s *ctl; + int ret; + int i; + + ctl = (FAR audioctl_s *)malloc(sizeof(audioctl_s)); + if(ctl == NULL) + { + return NULL; + } + + ctl->seek = false; + ctl->seek_position = 0; + ctl->file_position = 0; + + ctl->fd = open(arg, O_RDONLY); + if (ctl->fd < 0) { + printf("can't open audio file\n"); + return NULL; + } + + read(ctl->fd, &ctl->wav, sizeof(ctl->wav)); + + ret = init_nxaudio(&ctl->nxaudio, ctl->wav.fmt.samplerate, + ctl->wav.fmt.bitspersample, + ctl->wav.fmt.numchannels); + if (ret < 0) + { + printf("init_nxaudio() return with error!!\n"); + return NULL; + } + + for (i = 0; i < ctl->nxaudio.abufnum; i++) + { + app_dequeue_cb((unsigned long)ctl, ctl->nxaudio.abufs[i]); + } + + ctl->state = AUDIO_CTL_STATE_INIT; + + return ctl; +} + +int audio_ctl_start(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_INIT && ctl->state != AUDIO_CTL_STATE_PAUSE) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_START; + + pthread_attr_t tattr; + struct sched_param sparam; + + pthread_attr_init(&tattr); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 9; + pthread_attr_setschedparam(&tattr, &sparam); + pthread_attr_setstacksize(&tattr, 4096); + + pthread_create(&ctl->pid, &tattr, audio_loop_thread, + (pthread_addr_t)ctl); + + pthread_attr_destroy(&tattr); + pthread_setname_np(ctl->pid, "audioctl_thread"); + + return 0; +} + +int audio_ctl_pause(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_START) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_PAUSE; + + return nxaudio_pause(&ctl->nxaudio); +} + +int audio_ctl_resume(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_PAUSE) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_START; + + return nxaudio_resume(&ctl->nxaudio); +} + +int audio_ctl_seek(FAR audioctl_s *ctl, unsigned ms) +{ + if (ctl == NULL) + return -EINVAL; + + ctl->seek_position = ms * ctl->wav.fmt.samplerate * ctl->wav.fmt.bitspersample * ctl->wav.fmt.numchannels / 8; + ctl->seek = true; + + return 0; +} + +int audio_ctl_stop(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state != AUDIO_CTL_STATE_PAUSE && ctl->state != AUDIO_CTL_STATE_START) + { + return -1; + } + + ctl->state = AUDIO_CTL_STATE_STOP; + + nxaudio_stop(&ctl->nxaudio); + + if (ctl->pid > 0) + { + pthread_join(ctl->pid, NULL); + } + + return 0; +} + +int audio_ctl_set_volume(FAR audioctl_s *ctl, uint16_t vol) +{ + if (ctl == NULL) + return -EINVAL; + + return nxaudio_setvolume(&ctl->nxaudio, vol); +} + +int audio_ctl_get_position(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + return ctl->file_position / (ctl->wav.fmt.bitspersample * ctl->wav.fmt.numchannels * ctl->wav.fmt.samplerate / 8); +} + +int audio_ctl_uninit_nxaudio(FAR audioctl_s *ctl) +{ + if (ctl == NULL) + return -EINVAL; + + if (ctl->state == AUDIO_CTL_STATE_NOP) + { + return 0; + } + + if (ctl->fd > 0) + { + close(ctl->fd); + ctl->fd = -1; + } + + fin_nxaudio(&ctl->nxaudio); + + free(ctl); + + return 0; +} diff --git a/wooden_fish/audio_ctl.h b/wooden_fish/audio_ctl.h new file mode 100644 index 0000000000000000000000000000000000000000..e7e60993b3da128a7917731c5f59195a718653f2 --- /dev/null +++ b/wooden_fish/audio_ctl.h @@ -0,0 +1,85 @@ +#ifndef AUDIO_CTL_H +#define AUDIO_CTL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include <audioutils/nxaudio.h> +#include <pthread.h> + +enum { + AUDIO_CTL_STATE_NOP, + AUDIO_CTL_STATE_INIT, + AUDIO_CTL_STATE_START, + AUDIO_CTL_STATE_PAUSE, + AUDIO_CTL_STATE_STOP, +}; + +typedef struct wav_riff { + /* chunk "riff" */ + char chunkID[4]; /* "RIFF" */ + /* sub-chunk-size */ + uint32_t chunksize; /* 36 + subchunk2size */ + /* sub-chunk-data */ + char format[4]; /* "WAVE" */ +} riff_s; + +typedef struct wav_fmt { + /* sub-chunk "fmt" */ + char subchunk1ID[4]; /* "fmt " */ + /* sub-chunk-size */ + uint32_t subchunk1size; /* 16 for PCM */ + /* sub-chunk-data */ + uint16_t audioformat; /* PCM = 1*/ + uint16_t numchannels; /* Mono = 1, Stereo = 2, etc. */ + uint32_t samplerate; /* 8000, 44100, etc. */ + uint32_t byterate; /* = samplerate * numchannels * bitspersample/8 */ + uint16_t blockalign; /* = numchannels * bitspersample/8 */ + uint16_t bitspersample; /* 8bits, 16bits, etc. */ +} fmt_s; + +typedef struct wav_data { + /* sub-chunk "data" */ + char subchunk2ID[4]; /* "data" */ + /* sub-chunk-size */ + uint32_t subchunk2size; /* data size */ + /* sub-chunk-data */ + //Data_block_t block; +} data_s; + +typedef struct wav_fotmat { + riff_s riff; + fmt_s fmt; + data_s data; +} wav_s; + +typedef struct audioctl { + struct nxaudio_s nxaudio; + wav_s wav; + int fd; + int state; + pthread_t pid; + int seek; + uint32_t seek_position; + uint32_t file_position; +} audioctl_s; + +FAR audioctl_s *audio_ctl_init_nxaudio(FAR const char *arg); +int audio_ctl_start(FAR audioctl_s *ctl); +int audio_ctl_pause(FAR audioctl_s *ctl); +int audio_ctl_resume(FAR audioctl_s *ctl); +int audio_ctl_seek(FAR audioctl_s *ctl, unsigned ms); +int audio_ctl_stop(FAR audioctl_s *ctl); +int audio_ctl_set_volume(FAR audioctl_s *ctl, uint16_t vol); +int audio_ctl_get_position(FAR audioctl_s *ctl); +int audio_ctl_uninit_nxaudio(FAR audioctl_s *ctl); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* AUDIO_CTL_H */ diff --git a/wooden_fish/res/enter_white.png b/wooden_fish/res/enter_white.png new file mode 100644 index 0000000000000000000000000000000000000000..5c5a6fbe689903532d93390e6278bc066550c691 Binary files /dev/null and b/wooden_fish/res/enter_white.png differ diff --git a/wooden_fish/res/fonts/SourceHanSansCN-Bold.ttf b/wooden_fish/res/fonts/SourceHanSansCN-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ef7574bad5e60009be61a0550fcd5ed158f669da Binary files /dev/null and b/wooden_fish/res/fonts/SourceHanSansCN-Bold.ttf differ diff --git a/wooden_fish/res/knock.wav b/wooden_fish/res/knock.wav new file mode 100644 index 0000000000000000000000000000000000000000..a37b54da059afae0315f7326937b669d79072f54 Binary files /dev/null and b/wooden_fish/res/knock.wav differ diff --git a/wooden_fish/res/wooden_fish.png b/wooden_fish/res/wooden_fish.png new file mode 100644 index 0000000000000000000000000000000000000000..f41e656b1abd2c5af40fb84a749310a02f91b9ff Binary files /dev/null and b/wooden_fish/res/wooden_fish.png differ diff --git a/wooden_fish/wooden_fish.c b/wooden_fish/wooden_fish.c new file mode 100644 index 0000000000000000000000000000000000000000..4c2e5ca7dc55adc84774efe41e0677100dd3f5e7 --- /dev/null +++ b/wooden_fish/wooden_fish.c @@ -0,0 +1,399 @@ +#include <lvgl/lvgl.h> +#include "wooden_fish.h" +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> + +// 前向声明 +static void create_pr_animation(wooden_fish_t *app, int32_t x, int32_t y); +static void create_merit_animation(wooden_fish_t *app, int32_t x, int32_t y); +static void anim_ready_cb(lv_anim_t *a); +static void auto_knock_timer_cb(lv_timer_t *timer); + +static wooden_fish_t g_wooden_fish; +static bool is_coder_mode = false; +static lv_obj_t *coder_switch = NULL; + +// 全局音频控制器,避免重复创建 +static audioctl_s *g_audioctl = NULL; + +// 直接播放音频文件 - 每次敲击播放 knock.wav +static void play_wooden_fish_sound(void) +{ + static uint32_t last_play_time = 0; + uint32_t current_time = lv_tick_get(); + + // 防抖:500ms内只播放一次 + if (current_time - last_play_time < 500) { + return; + } + + last_play_time = current_time; + + // 如果已经有音频在播放,先停止 + if (g_audioctl) { + audio_ctl_stop(g_audioctl); + audio_ctl_uninit_nxaudio(g_audioctl); + g_audioctl = NULL; + } + + // 创建新的音频控制器并播放 + g_audioctl = audio_ctl_init_nxaudio(WOODEN_FISH_SOUND_PATH); + if (g_audioctl) { + audio_ctl_start(g_audioctl); + } +} + +// 简化的自动敲击回调函数 +static void auto_knock_timer_cb(lv_timer_t *timer) { + wooden_fish_t *app = (wooden_fish_t *)timer->user_data; + if (!app) return; + + // 检查自动开关状态 + if (app->ui.auto_switch == NULL || !lv_obj_has_state(app->ui.auto_switch, LV_STATE_CHECKED)) { + return; + } + + // 自动敲击 + app->knock_count++; + + // 根据模式更新文本 + if (is_coder_mode) { + lv_label_set_text_fmt(app->ui.counter, "pr: %lu", (unsigned long)app->knock_count); + lv_label_set_text_fmt(app->ui.today_label, "今日pr: %lu", (unsigned long)app->knock_count); + } else { + lv_label_set_text_fmt(app->ui.counter, "功德: %lu", (unsigned long)app->knock_count); + lv_label_set_text_fmt(app->ui.today_label, "今日功德: %lu", (unsigned long)app->knock_count); + } + + // 播放敲击音效 + play_wooden_fish_sound(); + + // 简单的木鱼动画 + lv_anim_t anim; + lv_anim_init(&anim); + lv_anim_set_var(&anim, app->ui.fish_img); + lv_anim_set_values(&anim, 0, 10); + lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)lv_obj_set_style_transform_angle); + lv_anim_set_time(&anim, 100); + lv_anim_set_playback_time(&anim, 100); + lv_anim_start(&anim); + + // 获取木鱼中心位置并创建动画 + lv_area_t fish_area; + lv_obj_get_coords(app->ui.fish_img, &fish_area); + int32_t center_x = fish_area.x1 + (fish_area.x2 - fish_area.x1) / 2; + int32_t center_y = fish_area.y1 + (fish_area.y2 - fish_area.y1) / 2; + + // 根据模式创建对应动画 + if (is_coder_mode) { + create_pr_animation(app, center_x, center_y); + } else { + create_merit_animation(app, center_x, center_y); + } +} + +// 木鱼点击事件回调 +static void fish_click_cb(lv_event_t *e) { + wooden_fish_t *app = (wooden_fish_t *)lv_event_get_user_data(e); + // 手动敲击 + app->knock_count++; + if (is_coder_mode) { + lv_label_set_text_fmt(app->ui.counter, "pr: %lu", (unsigned long)app->knock_count); + lv_label_set_text_fmt(app->ui.today_label, "今日pr: %lu", (unsigned long)app->knock_count); + } else { + lv_label_set_text_fmt(app->ui.counter, "功德: %lu", (unsigned long)app->knock_count); + lv_label_set_text_fmt(app->ui.today_label, "今日功德: %lu", (unsigned long)app->knock_count); + } + // 播放敲击音效 + play_wooden_fish_sound(); + // 添加木鱼图片动画 + lv_anim_t anim; + lv_anim_init(&anim); + lv_anim_set_var(&anim, app->ui.fish_img); + lv_anim_set_values(&anim, 0, 10); + lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)lv_obj_set_style_transform_angle); + lv_anim_set_time(&anim, 100); + lv_anim_set_playback_time(&anim, 100); + lv_anim_start(&anim); + // 获取点击位置并创建动画 + lv_point_t point; + lv_indev_get_point(lv_indev_active(), &point); + if (is_coder_mode) { + create_pr_animation(app, point.x, point.y); + } else { + create_merit_animation(app, point.x, point.y); + } +} + +// 自动模式开关回调 +static void auto_switch_cb(lv_event_t *e) { + lv_obj_t *sw = lv_event_get_target(e); + wooden_fish_t *app = (wooden_fish_t *)lv_event_get_user_data(e); + + if (lv_obj_has_state(sw, LV_STATE_CHECKED)) { + // 启动自动敲击定时器 (每2秒一次) + app->auto_timer = lv_timer_create(auto_knock_timer_cb, 2000, app); + } else { + // 停止自动敲击 + if (app->auto_timer) { + lv_timer_del(app->auto_timer); + app->auto_timer = NULL; + } + } +} + +// 创建主界面 + +// 切换程序猿/功德模式(无按钮,自动敲击时切换) +// 程序猿/功德模式切换开关回调 +static void switch_mode_cb(lv_event_t *e) { + lv_obj_t *sw = lv_event_get_target(e); + is_coder_mode = lv_obj_has_state(sw, LV_STATE_CHECKED); + if (is_coder_mode) { + LV_LOG_USER("切换图片路径: %s", WOODEN_FISH_ENTER_IMG_PATH); + lv_img_set_src(g_wooden_fish.ui.fish_img, WOODEN_FISH_ENTER_IMG_PATH); + lv_obj_invalidate(g_wooden_fish.ui.fish_img); + lv_label_set_text(g_wooden_fish.ui.today_label, "今日pr: 0"); + lv_label_set_text(g_wooden_fish.ui.counter, "pr: 0"); + } else { + LV_LOG_USER("切换图片路径: %s", WOODEN_FISH_IMG_PATH); + lv_img_set_src(g_wooden_fish.ui.fish_img, WOODEN_FISH_IMG_PATH); + lv_obj_invalidate(g_wooden_fish.ui.fish_img); + lv_label_set_text(g_wooden_fish.ui.today_label, "今日功德: 0"); + lv_label_set_text(g_wooden_fish.ui.counter, "功德: 0"); + } + g_wooden_fish.knock_count = 0; +} + +static void create_pr_animation(wooden_fish_t *app, int32_t x, int32_t y) { + if (app->font == NULL) return; + lv_obj_t *label = lv_label_create(lv_layer_top()); + if (!label) return; + lv_label_set_text(label, "pr+1"); + lv_obj_set_style_text_font(label, app->font, 0); + lv_obj_set_style_text_color(label, lv_color_hex(0x00BFFF), 0); + lv_obj_set_style_text_opa(label, LV_OPA_COVER, 0); + lv_obj_set_style_bg_opa(label, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_opa(label, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_all(label, 0, 0); + lv_point_t text_size; + lv_text_get_size(&text_size, "pr+1", app->font, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + int32_t label_x = x - text_size.x / 2; + int32_t label_y = y - text_size.y / 2; + lv_obj_set_size(label, text_size.x, text_size.y); + lv_obj_set_pos(label, label_x, label_y); + lv_anim_t move_anim; + lv_anim_init(&move_anim); + lv_anim_set_var(&move_anim, label); + lv_anim_set_values(&move_anim, label_y, label_y - 120); + lv_anim_set_exec_cb(&move_anim, (lv_anim_exec_xcb_t)lv_obj_set_y); + lv_anim_set_time(&move_anim, 1500); + lv_anim_set_path_cb(&move_anim, lv_anim_path_ease_out); + lv_anim_t fade_anim; + lv_anim_init(&fade_anim); + lv_anim_set_var(&fade_anim, label); + lv_anim_set_values(&fade_anim, LV_OPA_COVER, LV_OPA_TRANSP); + lv_anim_set_exec_cb(&fade_anim, (lv_anim_exec_xcb_t)lv_obj_set_style_text_opa); + lv_anim_set_time(&fade_anim, 1500); + lv_anim_set_path_cb(&fade_anim, lv_anim_path_ease_out); + lv_anim_set_ready_cb(&move_anim, anim_ready_cb); + lv_anim_start(&move_anim); + lv_anim_start(&fade_anim); + lv_refr_now(NULL); +} + +static void create_main_ui(void) { + // 创建主屏幕 + g_wooden_fish.ui.screen = lv_obj_create(lv_scr_act()); + lv_obj_remove_style_all(g_wooden_fish.ui.screen); + lv_obj_set_size(g_wooden_fish.ui.screen, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_bg_color(g_wooden_fish.ui.screen, lv_color_black(), 0); + lv_obj_set_style_bg_opa(g_wooden_fish.ui.screen, LV_OPA_COVER, 0); + + // 程序猿模式开关(右上角) + coder_switch = lv_switch_create(g_wooden_fish.ui.screen); + lv_obj_align(coder_switch, LV_ALIGN_TOP_RIGHT, -20, 20); + lv_obj_add_event_cb(coder_switch, switch_mode_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_t *coder_label = lv_label_create(g_wooden_fish.ui.screen); + lv_label_set_text(coder_label, "程序猿模式"); + lv_obj_set_style_text_font(coder_label, g_wooden_fish.font, 0); + lv_obj_set_style_text_color(coder_label, lv_color_white(), 0); + lv_obj_align_to(coder_label, coder_switch, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + // 创建木鱼图片 + g_wooden_fish.ui.fish_img = lv_img_create(g_wooden_fish.ui.screen); + lv_img_set_src(g_wooden_fish.ui.fish_img, WOODEN_FISH_IMG_PATH); + lv_obj_align(g_wooden_fish.ui.fish_img, LV_ALIGN_CENTER, 0, -50); + lv_obj_add_flag(g_wooden_fish.ui.fish_img, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(g_wooden_fish.ui.fish_img, fish_click_cb, LV_EVENT_CLICKED, &g_wooden_fish); + + // 创建功德计数器 + g_wooden_fish.ui.counter = lv_label_create(g_wooden_fish.ui.screen); + lv_label_set_text(g_wooden_fish.ui.counter, "功德: 0"); + // 使用加载的字体 + lv_obj_set_style_text_font(g_wooden_fish.ui.counter, g_wooden_fish.font, 0); + lv_obj_align(g_wooden_fish.ui.counter, LV_ALIGN_CENTER, 0, 80); + + // 创建今日功德标签(字体更大) + g_wooden_fish.ui.today_label = lv_label_create(g_wooden_fish.ui.screen); + lv_label_set_text_fmt(g_wooden_fish.ui.today_label, "今日功德: %lu", (unsigned long)g_wooden_fish.knock_count); + /* 加载更大字号字体 */ + lv_font_t *big_font = lv_freetype_font_create(FONTS_ROOT "/MiSans-Normal.ttf", LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 32, LV_FREETYPE_FONT_STYLE_NORMAL); + if (big_font) { + lv_obj_set_style_text_font(g_wooden_fish.ui.today_label, big_font, 0); + } else { + lv_obj_set_style_text_font(g_wooden_fish.ui.today_label, g_wooden_fish.font, 0); + } + lv_obj_set_style_text_color(g_wooden_fish.ui.today_label, lv_color_white(), 0); + lv_obj_align(g_wooden_fish.ui.today_label, LV_ALIGN_TOP_MID, 0, 20); + + // 创建自动敲击开关 + g_wooden_fish.ui.auto_switch = lv_switch_create(g_wooden_fish.ui.screen); + lv_obj_align(g_wooden_fish.ui.auto_switch, LV_ALIGN_BOTTOM_MID, 0, -40); + lv_obj_add_event_cb(g_wooden_fish.ui.auto_switch, auto_switch_cb, LV_EVENT_VALUE_CHANGED, &g_wooden_fish); + + // 创建自动敲击标签 + lv_obj_t *auto_label = lv_label_create(g_wooden_fish.ui.screen); + lv_label_set_text(auto_label, "自动敲击"); + // 使用加载的字体 + lv_obj_set_style_text_font(auto_label, g_wooden_fish.font, 0); + lv_obj_set_style_text_color(auto_label, lv_color_white(), 0); + lv_obj_align_to(auto_label, g_wooden_fish.ui.auto_switch, LV_ALIGN_OUT_LEFT_MID, -10, 0); +} + +// 清理函数 +void wooden_fish_cleanup(void) +{ + // 清理音频资源 + if (g_audioctl) { + audio_ctl_stop(g_audioctl); + audio_ctl_uninit_nxaudio(g_audioctl); + g_audioctl = NULL; + } + + // 清理定时器 + if (g_wooden_fish.auto_timer) { + lv_timer_delete(g_wooden_fish.auto_timer); + g_wooden_fish.auto_timer = NULL; + } +} + +void wooden_fish_app_create(void) { + // 初始化计数器 + g_wooden_fish.knock_count = 0; + g_wooden_fish.auto_timer = NULL; + + // 字体加载 + g_wooden_fish.font = lv_freetype_font_create( + FONTS_ROOT "/MiSans-Normal.ttf", // 使用FONTS_ROOT宏 + LV_FREETYPE_FONT_RENDER_MODE_BITMAP, + 24, + LV_FREETYPE_FONT_STYLE_NORMAL + ); + + // 错误处理 + if (g_wooden_fish.font == NULL) { + // 如果加载失败,输出错误信息 + LV_LOG_ERROR("字体加载失败: %s", FONTS_ROOT "/MiSans-Normal.ttf"); + // 回退到默认字体 + g_wooden_fish.font = &lv_font_montserrat_24; + } else { + LV_LOG_INFO("字体加载成功: %s", FONTS_ROOT "/MiSans-Normal.ttf"); + } + + // 创建UI + create_main_ui(); +} + +__attribute__((unused)) static void app_create_error_page(void) +{ + lv_obj_t * label = lv_label_create(lv_scr_act()); + lv_label_set_text(label, "字体加载失败,请检查资源文件。"); + lv_obj_set_style_text_font(label, &lv_font_montserrat_24, LV_PART_MAIN); + lv_obj_center(label); +} + +// 新增:动画结束回调函数 +static void anim_ready_cb(lv_anim_t *a) { + lv_obj_t *obj = (lv_obj_t *)a->var; + if(obj && lv_obj_is_valid(obj)) { + lv_obj_del(obj); + } +} + +// 简化的音频播放完成回调 +void wooden_fish_audio_complete_cb(void) { + // 什么也不做,让音频系统自己清理 + LV_LOG_USER("音频播放完成"); +} + +static void create_merit_animation(wooden_fish_t *app, int32_t x, int32_t y){ + // 确保字体可用 - 遵循字体规范 + if (app->font == NULL) { + LV_LOG_ERROR("字体不可用,无法创建功德+1动画"); + return; + } + + // 创建"功德+1"标签 + lv_obj_t *label = lv_label_create(lv_layer_top()); + if (label == NULL) { + LV_LOG_ERROR("创建功德+1标签失败"); + return; + } + + lv_label_set_text(label, "功德+1"); + // 使用app->font设置字体 + lv_obj_set_style_text_font(label, app->font, 0); + lv_obj_set_style_text_color(label, lv_color_hex(0xFFD700), 0); + lv_obj_set_style_text_opa(label, LV_OPA_COVER, 0); + lv_obj_set_style_bg_opa(label, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_opa(label, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_all(label, 0, 0); + + // 测量文字尺寸 + lv_point_t text_size; + lv_text_get_size(&text_size, "功德+1", app->font, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + + // 设置标签位置(居中) + int32_t label_x = x - text_size.x / 2; + int32_t label_y = y - text_size.y / 2; + lv_obj_set_size(label, text_size.x, text_size.y); + lv_obj_set_pos(label, label_x, label_y); + + // 调试日志 + LV_LOG_INFO("创建功德+1动画: 位置(%d,%d) 尺寸(%d,%d)", + label_x, label_y, text_size.x, text_size.y); + + // 创建移动动画 + lv_anim_t move_anim; + lv_anim_init(&move_anim); + lv_anim_set_var(&move_anim, label); + lv_anim_set_values(&move_anim, label_y, label_y - 120); + lv_anim_set_exec_cb(&move_anim, (lv_anim_exec_xcb_t)lv_obj_set_y); + lv_anim_set_time(&move_anim, 1500); + lv_anim_set_path_cb(&move_anim, lv_anim_path_ease_out); + + // 创建淡出动画 + lv_anim_t fade_anim; + lv_anim_init(&fade_anim); + lv_anim_set_var(&fade_anim, label); + lv_anim_set_values(&fade_anim, LV_OPA_COVER, LV_OPA_TRANSP); + lv_anim_set_exec_cb(&fade_anim, (lv_anim_exec_xcb_t)lv_obj_set_style_text_opa); + lv_anim_set_time(&fade_anim, 1500); + lv_anim_set_path_cb(&fade_anim, lv_anim_path_ease_out); + + // 动画结束时删除标签 + lv_anim_set_ready_cb(&move_anim, anim_ready_cb); + + // 启动动画 + lv_anim_start(&move_anim); + lv_anim_start(&fade_anim); + + // 立即刷新显示 + lv_refr_now(NULL); + LV_LOG_INFO("功德+1动画已启动"); +} + + diff --git a/wooden_fish/wooden_fish.h b/wooden_fish/wooden_fish.h new file mode 100644 index 0000000000000000000000000000000000000000..b817854c8578be8d15040abd9888d8313399c04e --- /dev/null +++ b/wooden_fish/wooden_fish.h @@ -0,0 +1,45 @@ +#ifndef __RRLATION_CAL_H__ +#define __RRLATION_CAL_H__ +#include <nuttx/config.h> +#include <lvgl/lvgl.h> +#include "audio_ctl.h" + +#ifndef CONFIG_LVX_WOODEN_FISH_DATA_ROOT +#define CONFIG_LVX_WOODEN_FISH_DATA_ROOT "/data" +#endif + +// 资源路径定义 +#define WOODEN_FISH_RES_ROOT CONFIG_LVX_WOODEN_FISH_DATA_ROOT "/res" +#define WOODEN_FISH_IMG_PATH WOODEN_FISH_RES_ROOT "/wooden_fish.png" +#define WOODEN_FISH_ENTER_IMG_PATH WOODEN_FISH_RES_ROOT "/enter_white.png" +#define WOODEN_FISH_SOUND_PATH WOODEN_FISH_RES_ROOT "/knock.wav" +#define FONTS_ROOT WOODEN_FISH_RES_ROOT "/fonts" + +/** + * @struct wooden_fish_t + * @brief 电子木鱼应用数据结构 + */ +typedef struct wooden_fish_s { + struct { + lv_obj_t *screen; // 主屏幕 + lv_obj_t *fish_img; // 木鱼图片 + lv_obj_t *counter; // 功德计数器 + lv_obj_t *auto_switch; // 自动敲击开关 + lv_obj_t *today_label; // 今日功德标签 + } ui; + + uint32_t knock_count; // 敲击次数 + lv_timer_t *auto_timer; // 自动敲击定时器 + const lv_font_t *font; // 添加字体指针 +} wooden_fish_t; + +/** + * @brief 创建电子木鱼应用 + */ +void wooden_fish_app_create(void); +// 音频完成回调供 audio_ctl 调用 +void wooden_fish_audio_complete_cb(void); +// 程序清理函数 +void wooden_fish_cleanup(void); + +#endif \ No newline at end of file diff --git a/wooden_fish/wooden_fish_main.c b/wooden_fish/wooden_fish_main.c new file mode 100644 index 0000000000000000000000000000000000000000..89d8d57a106755fdbc9b87899658ddf3e4cf6ff8 --- /dev/null +++ b/wooden_fish/wooden_fish_main.c @@ -0,0 +1,106 @@ +// include NuttX headers +#include <nuttx/config.h> +#include <unistd.h> +#include <signal.h> + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV +#include <uv.h> +#endif + +// include lvgl headers +#include <lvgl/lvgl.h> + +#include "wooden_fish.h" + +// 全局退出标志 +static volatile bool g_exit_flag = false; + +// 信号处理函数 +static void signal_handler(int sig) { + if (sig == SIGTERM || sig == SIGINT) { + g_exit_flag = true; + } +} + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + +static void lv_nuttx_uv_loop(uv_loop_t *loop, lv_nuttx_result_t *result) +{ + lv_nuttx_uv_t uv_info; + void *data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +#endif + +int main(int argc, FAR char *argv[]) +{ + // init lvgl + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + uv_loop_t ui_loop; + lv_memset(&ui_loop, 0, sizeof(uv_loop_t)); +#endif + + if (lv_is_initialized()) + { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + + // 设置信号处理 + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) + { + LV_LOG_ERROR("lv_demos initialization failure!"); + return 1; + } + + wooden_fish_app_create(); + +#ifdef CONFIG_LV_USE_NUTTX_LIBUV + // refresh lvgl ui + lv_nuttx_uv_loop(&ui_loop, &result); +#endif + + while (!g_exit_flag) + { + uint32_t idle; + idle = lv_timer_handler(); + + /* Minimum sleep of 1ms */ + + idle = idle ? idle : 1; + usleep(idle * 1000); + } + + // 程序退出前清理资源 + wooden_fish_cleanup(); + + lv_nuttx_deinit(&result); + lv_deinit(); + + return 0; +} diff --git a/x_track/Kconfig b/x_track/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..1f176f173f874549e1c8a472a0b88c2f45dbb3df --- /dev/null +++ b/x_track/Kconfig @@ -0,0 +1,19 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LVX_USE_DEMO_X_TRACK + bool "X-TRACK demo" + depends on GRAPHICS_LVGL && LV_USE_LIBPNG && LIB_PNG && NETUTILS_CJSON && UIKIT_FONT_MANAGER + default n + ---help--- + Enable build X-TRACK Demo programs + +if LVX_USE_DEMO_X_TRACK + +config X_TRACK_RESOURCE_DIR_PATH + string "Resource directory path for X-TRACK" + default "/data" + +endif # LVX_USE_DEMO_X_TRACK diff --git a/x_track/Make.defs b/x_track/Make.defs new file mode 100644 index 0000000000000000000000000000000000000000..75149bb8d23228aa2e0b98bfa2da0a59e9f467f6 --- /dev/null +++ b/x_track/Make.defs @@ -0,0 +1,18 @@ +# +# Copyright (C) 2024 Xiaomi Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ifneq ($(CONFIG_LVX_USE_DEMO_X_TRACK),) +CONFIGURED_APPS += $(APPDIR)/packages/demos/x_track +endif diff --git a/x_track/Makefile b/x_track/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..48c1b4ab3a1a6afc70ea938d16fcd088ec6f8979 --- /dev/null +++ b/x_track/Makefile @@ -0,0 +1,33 @@ +include $(APPDIR)/Make.defs + +ifeq ($(CONFIG_LVX_USE_DEMO_X_TRACK), y) + +CXXEXT := .cpp + +PROGNAME += x_track +PRIORITY = 100 +STACKSIZE = 32768 +MODULE = $(CONFIG_LVX_USE_DEMO_X_TRACK) + +# Absolute page size mode +CXXFLAGS += -DPAGE_HOR_RES=240 -DPAGE_VER_RES=320 + +# Map resource path configuration +CXXFLAGS += -DCONFIG_RESOURCE_DIR_PATH=CONFIG_X_TRACK_RESOURCE_DIR_PATH + +# Log level configuration +CXXFLAGS += -DDATA_BROKER_LOG_LEVEL=1 -DPAGE_LOG_LEVEL=0 + +# Include paths +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/include/netutils +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/frameworks/graphics/uikit/include +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/packages/demos/x_track/src +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/packages/demos/x_track/src/App +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/packages/demos/x_track/src/Vendor/Simulator + +MAINSRC += x_track_main.cpp +CSRCS += $(shell find -L ./ -name "*.c") +CXXSRCS += $(shell find -L ./ -name "*.cpp" | grep -v x_track_main.cpp) +endif # CONFIG_LVX_USE_DEMO_X_TRACK + +include $(APPDIR)/Application.mk diff --git a/x_track/resource/font/Alibaba_PuHuiTi_2.0_115_Black.ttf b/x_track/resource/font/Alibaba_PuHuiTi_2.0_115_Black.ttf new file mode 100755 index 0000000000000000000000000000000000000000..70281c0ce65ad3067aa4585c8211d2f83c497549 Binary files /dev/null and b/x_track/resource/font/Alibaba_PuHuiTi_2.0_115_Black.ttf differ diff --git a/x_track/resource/font/Alibaba_PuHuiTi_2.0_55_Regular.ttf b/x_track/resource/font/Alibaba_PuHuiTi_2.0_55_Regular.ttf new file mode 100755 index 0000000000000000000000000000000000000000..b69b5109d35e564a0a9fd31b2190e68f796e108d Binary files /dev/null and b/x_track/resource/font/Alibaba_PuHuiTi_2.0_55_Regular.ttf differ diff --git a/x_track/resource/font/Alibaba_PuHuiTi_2.0_65_Medium.ttf b/x_track/resource/font/Alibaba_PuHuiTi_2.0_65_Medium.ttf new file mode 100755 index 0000000000000000000000000000000000000000..588a02dddbd178b7b19606789837ca27ef55202b Binary files /dev/null and b/x_track/resource/font/Alibaba_PuHuiTi_2.0_65_Medium.ttf differ diff --git a/x_track/resource/font/Font Awesome 6 Brands-Regular-400.ttf b/x_track/resource/font/Font Awesome 6 Brands-Regular-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d2fc00991f6a8edbbafddc0d3776cf1e7792ee99 Binary files /dev/null and b/x_track/resource/font/Font Awesome 6 Brands-Regular-400.ttf differ diff --git a/x_track/resource/font/Font Awesome 6 Free-Regular-400.ttf b/x_track/resource/font/Font Awesome 6 Free-Regular-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..59f4a6edd45234250ce78277cfe0c13aabaf211d Binary files /dev/null and b/x_track/resource/font/Font Awesome 6 Free-Regular-400.ttf differ diff --git a/x_track/resource/font/Font Awesome 6 Free-Solid-900.ttf b/x_track/resource/font/Font Awesome 6 Free-Solid-900.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a16a38fb46811bfff03bd3b5db478131ecbf7253 Binary files /dev/null and b/x_track/resource/font/Font Awesome 6 Free-Solid-900.ttf differ diff --git a/x_track/resource/images/navi_arrow_dark.png b/x_track/resource/images/navi_arrow_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..cd02eccbed4834c57cb974fef46996eb926c29e3 Binary files /dev/null and b/x_track/resource/images/navi_arrow_dark.png differ diff --git a/x_track/resource/images/navi_arrow_light.png b/x_track/resource/images/navi_arrow_light.png new file mode 100644 index 0000000000000000000000000000000000000000..ec0d98efd81b3e07ca9c119f9eda79418d356e8e Binary files /dev/null and b/x_track/resource/images/navi_arrow_light.png differ diff --git a/x_track/resource/track/TRK_EXAMPLE.gpx b/x_track/resource/track/TRK_EXAMPLE.gpx new file mode 100644 index 0000000000000000000000000000000000000000..536c5a062f4e9d346fed65c1728860b3f729afe5 --- /dev/null +++ b/x_track/resource/track/TRK_EXAMPLE.gpx @@ -0,0 +1,2751 @@ +<gpx version="1.1" creator="Arduino GPX Lib" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://www.topografix.com/GPX/1/1" + xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" +> +<metadata><name><![CDATA[X-TRACK EVO v1.0.0]]></name> +<desc><![CDATA[https://github.com/X-TRACK-OVERFLOW/X-TRACK-EVO]]></desc> +</metadata> +<trk><name><![CDATA[/Track/2024_11/TRK_20241111_113804.gpx]]></name> +<trkseg><trkpt lat="40.048031" lon="116.309013"><ele>0.00</ele> +<time>2024-11-11T11:38:04Z</time> +</trkpt> +<trkpt lat="40.048069" lon="116.309021"><ele>0.00</ele> +<time>2024-11-11T11:38:04Z</time> +</trkpt> +<trkpt lat="40.048054" lon="116.309021"><ele>0.00</ele> +<time>2024-11-11T11:38:05Z</time> +</trkpt> +<trkpt lat="40.048038" lon="116.309029"><ele>0.00</ele> +<time>2024-11-11T11:38:07Z</time> +</trkpt> +<trkpt lat="40.048008" lon="116.309052"><ele>0.00</ele> +<time>2024-11-11T11:38:08Z</time> +</trkpt> +<trkpt lat="40.047970" lon="116.309074"><ele>0.00</ele> +<time>2024-11-11T11:38:09Z</time> +</trkpt> +<trkpt lat="40.047935" lon="116.309074"><ele>0.00</ele> +<time>2024-11-11T11:38:09Z</time> +</trkpt> +<trkpt lat="40.047874" lon="116.309090"><ele>0.00</ele> +<time>2024-11-11T11:38:10Z</time> +</trkpt> +<trkpt lat="40.047825" lon="116.309090"><ele>0.00</ele> +<time>2024-11-11T11:38:11Z</time> +</trkpt> +<trkpt lat="40.047779" lon="116.309082"><ele>0.00</ele> +<time>2024-11-11T11:38:12Z</time> +</trkpt> +<trkpt lat="40.047745" lon="116.309067"><ele>0.00</ele> +<time>2024-11-11T11:38:13Z</time> +</trkpt> +<trkpt lat="40.047710" lon="116.309044"><ele>0.00</ele> +<time>2024-11-11T11:38:14Z</time> +</trkpt> +<trkpt lat="40.047699" lon="116.309013"><ele>0.00</ele> +<time>2024-11-11T11:38:15Z</time> +</trkpt> +<trkpt lat="40.047665" lon="116.308968"><ele>0.00</ele> +<time>2024-11-11T11:38:16Z</time> +</trkpt> +<trkpt lat="40.047626" lon="116.308922"><ele>0.00</ele> +<time>2024-11-11T11:38:17Z</time> +</trkpt> +<trkpt lat="40.047604" lon="116.308868"><ele>0.00</ele> +<time>2024-11-11T11:38:19Z</time> +</trkpt> +<trkpt lat="40.047550" lon="116.308815"><ele>0.00</ele> +<time>2024-11-11T11:38:20Z</time> +</trkpt> +<trkpt lat="40.047504" lon="116.308754"><ele>0.00</ele> +<time>2024-11-11T11:38:21Z</time> +</trkpt> +<trkpt lat="40.047466" lon="116.308693"><ele>0.00</ele> +<time>2024-11-11T11:38:21Z</time> +</trkpt> +<trkpt lat="40.047413" lon="116.308632"><ele>0.00</ele> +<time>2024-11-11T11:38:22Z</time> +</trkpt> +<trkpt lat="40.047359" lon="116.308571"><ele>0.00</ele> +<time>2024-11-11T11:38:23Z</time> +</trkpt> +<trkpt lat="40.047310" lon="116.308510"><ele>0.00</ele> +<time>2024-11-11T11:38:24Z</time> +</trkpt> +<trkpt lat="40.047272" lon="116.308456"><ele>0.00</ele> +<time>2024-11-11T11:38:25Z</time> +</trkpt> +<trkpt lat="40.047237" lon="116.308395"><ele>0.00</ele> +<time>2024-11-11T11:38:26Z</time> +</trkpt> +<trkpt lat="40.047203" lon="116.308334"><ele>0.00</ele> +<time>2024-11-11T11:38:27Z</time> +</trkpt> +<trkpt lat="40.047176" lon="116.308273"><ele>0.00</ele> +<time>2024-11-11T11:38:28Z</time> +</trkpt> +<trkpt lat="40.047176" lon="116.308273"><ele>0.00</ele> +<time>2024-11-11T11:38:29Z</time> +</trkpt> +<trkpt lat="40.047176" lon="116.308273"><ele>0.00</ele> +<time>2024-11-11T11:38:30Z</time> +</trkpt> +<trkpt lat="40.047089" lon="116.308098"><ele>0.00</ele> +<time>2024-11-11T11:38:32Z</time> +</trkpt> +<trkpt lat="40.047066" lon="116.308037"><ele>0.00</ele> +<time>2024-11-11T11:38:32Z</time> +</trkpt> +<trkpt lat="40.047039" lon="116.307968"><ele>0.00</ele> +<time>2024-11-11T11:38:33Z</time> +</trkpt> +<trkpt lat="40.047016" lon="116.307907"><ele>0.00</ele> +<time>2024-11-11T11:38:34Z</time> +</trkpt> +<trkpt lat="40.046989" lon="116.307838"><ele>0.00</ele> +<time>2024-11-11T11:38:35Z</time> +</trkpt> +<trkpt lat="40.046970" lon="116.307777"><ele>0.00</ele> +<time>2024-11-11T11:38:36Z</time> +</trkpt> +<trkpt lat="40.046947" lon="116.307709"><ele>0.00</ele> +<time>2024-11-11T11:38:37Z</time> +</trkpt> +<trkpt lat="40.046925" lon="116.307648"><ele>0.00</ele> +<time>2024-11-11T11:38:38Z</time> +</trkpt> +<trkpt lat="40.046909" lon="116.307587"><ele>0.00</ele> +<time>2024-11-11T11:38:39Z</time> +</trkpt> +<trkpt lat="40.046883" lon="116.307518"><ele>0.00</ele> +<time>2024-11-11T11:38:40Z</time> +</trkpt> +<trkpt lat="40.046860" lon="116.307457"><ele>0.00</ele> +<time>2024-11-11T11:38:41Z</time> +</trkpt> +<trkpt lat="40.046837" lon="116.307388"><ele>0.00</ele> +<time>2024-11-11T11:38:42Z</time> +</trkpt> +<trkpt lat="40.046818" lon="116.307327"><ele>0.00</ele> +<time>2024-11-11T11:38:43Z</time> +</trkpt> +<trkpt lat="40.046795" lon="116.307259"><ele>0.00</ele> +<time>2024-11-11T11:38:44Z</time> +</trkpt> +<trkpt lat="40.046776" lon="116.307190"><ele>0.00</ele> +<time>2024-11-11T11:38:45Z</time> +</trkpt> +<trkpt lat="40.046749" lon="116.307129"><ele>0.00</ele> +<time>2024-11-11T11:38:46Z</time> +</trkpt> +<trkpt lat="40.046726" lon="116.307060"><ele>0.00</ele> +<time>2024-11-11T11:38:47Z</time> +</trkpt> +<trkpt lat="40.046715" lon="116.306992"><ele>0.00</ele> +<time>2024-11-11T11:38:48Z</time> +</trkpt> +<trkpt lat="40.046696" lon="116.306923"><ele>0.00</ele> +<time>2024-11-11T11:38:49Z</time> +</trkpt> +<trkpt lat="40.046677" lon="116.306854"><ele>0.00</ele> +<time>2024-11-11T11:38:50Z</time> +</trkpt> +<trkpt lat="40.046658" lon="116.306786"><ele>0.00</ele> +<time>2024-11-11T11:38:51Z</time> +</trkpt> +<trkpt lat="40.046642" lon="116.306725"><ele>0.00</ele> +<time>2024-11-11T11:38:52Z</time> +</trkpt> +<trkpt lat="40.046616" lon="116.306664"><ele>0.00</ele> +<time>2024-11-11T11:38:53Z</time> +</trkpt> +<trkpt lat="40.046566" lon="116.306602"><ele>0.00</ele> +<time>2024-11-11T11:38:54Z</time> +</trkpt> +<trkpt lat="40.046516" lon="116.306541"><ele>0.00</ele> +<time>2024-11-11T11:38:55Z</time> +</trkpt> +<trkpt lat="40.046478" lon="116.306480"><ele>0.00</ele> +<time>2024-11-11T11:38:56Z</time> +</trkpt> +<trkpt lat="40.046444" lon="116.306419"><ele>0.00</ele> +<time>2024-11-11T11:38:57Z</time> +</trkpt> +<trkpt lat="40.046417" lon="116.306358"><ele>0.00</ele> +<time>2024-11-11T11:38:58Z</time> +</trkpt> +<trkpt lat="40.046391" lon="116.306290"><ele>0.00</ele> +<time>2024-11-11T11:38:59Z</time> +</trkpt> +<trkpt lat="40.046364" lon="116.306229"><ele>0.00</ele> +<time>2024-11-11T11:39:00Z</time> +</trkpt> +<trkpt lat="40.046341" lon="116.306168"><ele>0.00</ele> +<time>2024-11-11T11:39:01Z</time> +</trkpt> +<trkpt lat="40.046318" lon="116.306107"><ele>0.00</ele> +<time>2024-11-11T11:39:02Z</time> +</trkpt> +<trkpt lat="40.046291" lon="116.306046"><ele>0.00</ele> +<time>2024-11-11T11:39:03Z</time> +</trkpt> +<trkpt lat="40.046272" lon="116.305984"><ele>0.00</ele> +<time>2024-11-11T11:39:04Z</time> +</trkpt> +<trkpt lat="40.046249" lon="116.305916"><ele>0.00</ele> +<time>2024-11-11T11:39:05Z</time> +</trkpt> +<trkpt lat="40.046230" lon="116.305855"><ele>0.00</ele> +<time>2024-11-11T11:39:06Z</time> +</trkpt> +<trkpt lat="40.046207" lon="116.305794"><ele>0.00</ele> +<time>2024-11-11T11:39:07Z</time> +</trkpt> +<trkpt lat="40.046185" lon="116.305733"><ele>0.00</ele> +<time>2024-11-11T11:39:08Z</time> +</trkpt> +<trkpt lat="40.046162" lon="116.305672"><ele>0.00</ele> +<time>2024-11-11T11:39:09Z</time> +</trkpt> +<trkpt lat="40.046139" lon="116.305611"><ele>0.00</ele> +<time>2024-11-11T11:39:10Z</time> +</trkpt> +<trkpt lat="40.046112" lon="116.305550"><ele>0.00</ele> +<time>2024-11-11T11:39:11Z</time> +</trkpt> +<trkpt lat="40.046082" lon="116.305496"><ele>0.00</ele> +<time>2024-11-11T11:39:12Z</time> +</trkpt> +<trkpt lat="40.046043" lon="116.305450"><ele>0.00</ele> +<time>2024-11-11T11:39:13Z</time> +</trkpt> +<trkpt lat="40.045998" lon="116.305420"><ele>0.00</ele> +<time>2024-11-11T11:39:14Z</time> +</trkpt> +<trkpt lat="40.045956" lon="116.305397"><ele>0.00</ele> +<time>2024-11-11T11:39:15Z</time> +</trkpt> +<trkpt lat="40.045910" lon="116.305389"><ele>0.00</ele> +<time>2024-11-11T11:39:16Z</time> +</trkpt> +<trkpt lat="40.045860" lon="116.305397"><ele>0.00</ele> +<time>2024-11-11T11:39:17Z</time> +</trkpt> +<trkpt lat="40.045815" lon="116.305420"><ele>0.00</ele> +<time>2024-11-11T11:39:18Z</time> +</trkpt> +<trkpt lat="40.045765" lon="116.305450"><ele>0.00</ele> +<time>2024-11-11T11:39:19Z</time> +</trkpt> +<trkpt lat="40.045715" lon="116.305481"><ele>0.00</ele> +<time>2024-11-11T11:39:20Z</time> +</trkpt> +<trkpt lat="40.045666" lon="116.305511"><ele>0.00</ele> +<time>2024-11-11T11:39:21Z</time> +</trkpt> +<trkpt lat="40.045620" lon="116.305542"><ele>0.00</ele> +<time>2024-11-11T11:39:22Z</time> +</trkpt> +<trkpt lat="40.045574" lon="116.305573"><ele>0.00</ele> +<time>2024-11-11T11:39:23Z</time> +</trkpt> +<trkpt lat="40.045528" lon="116.305603"><ele>0.00</ele> +<time>2024-11-11T11:39:24Z</time> +</trkpt> +<trkpt lat="40.045486" lon="116.305641"><ele>52.64</ele> +<time>2024-11-11T11:39:25Z</time> +</trkpt> +<trkpt lat="40.045444" lon="116.305679"><ele>52.52</ele> +<time>2024-11-11T11:39:26Z</time> +</trkpt> +<trkpt lat="40.045403" lon="116.305717"><ele>52.85</ele> +<time>2024-11-11T11:39:27Z</time> +</trkpt> +<trkpt lat="40.045361" lon="116.305748"><ele>52.85</ele> +<time>2024-11-11T11:39:28Z</time> +</trkpt> +<trkpt lat="40.045315" lon="116.305779"><ele>52.74</ele> +<time>2024-11-11T11:39:29Z</time> +</trkpt> +<trkpt lat="40.045273" lon="116.305809"><ele>52.72</ele> +<time>2024-11-11T11:39:30Z</time> +</trkpt> +<trkpt lat="40.045227" lon="116.305840"><ele>52.74</ele> +<time>2024-11-11T11:39:31Z</time> +</trkpt> +<trkpt lat="40.045181" lon="116.305878"><ele>53.02</ele> +<time>2024-11-11T11:39:32Z</time> +</trkpt> +<trkpt lat="40.045139" lon="116.305908"><ele>53.02</ele> +<time>2024-11-11T11:39:33Z</time> +</trkpt> +<trkpt lat="40.045097" lon="116.305946"><ele>53.02</ele> +<time>2024-11-11T11:39:34Z</time> +</trkpt> +<trkpt lat="40.045052" lon="116.305977"><ele>53.01</ele> +<time>2024-11-11T11:39:35Z</time> +</trkpt> +<trkpt lat="40.045006" lon="116.306015"><ele>53.01</ele> +<time>2024-11-11T11:39:36Z</time> +</trkpt> +<trkpt lat="40.044964" lon="116.306046"><ele>53.27</ele> +<time>2024-11-11T11:39:37Z</time> +</trkpt> +<trkpt lat="40.044918" lon="116.306084"><ele>53.33</ele> +<time>2024-11-11T11:39:38Z</time> +</trkpt> +<trkpt lat="40.044876" lon="116.306114"><ele>53.27</ele> +<time>2024-11-11T11:39:39Z</time> +</trkpt> +<trkpt lat="40.044830" lon="116.306152"><ele>53.27</ele> +<time>2024-11-11T11:39:40Z</time> +</trkpt> +<trkpt lat="40.044788" lon="116.306183"><ele>53.25</ele> +<time>2024-11-11T11:39:41Z</time> +</trkpt> +<trkpt lat="40.044746" lon="116.306221"><ele>53.27</ele> +<time>2024-11-11T11:39:42Z</time> +</trkpt> +<trkpt lat="40.044704" lon="116.306259"><ele>53.44</ele> +<time>2024-11-11T11:39:43Z</time> +</trkpt> +<trkpt lat="40.044662" lon="116.306297"><ele>53.44</ele> +<time>2024-11-11T11:39:44Z</time> +</trkpt> +<trkpt lat="40.044624" lon="116.306335"><ele>53.46</ele> +<time>2024-11-11T11:39:45Z</time> +</trkpt> +<trkpt lat="40.044586" lon="116.306374"><ele>53.59</ele> +<time>2024-11-11T11:39:46Z</time> +</trkpt> +<trkpt lat="40.044540" lon="116.306404"><ele>53.69</ele> +<time>2024-11-11T11:39:47Z</time> +</trkpt> +<trkpt lat="40.044498" lon="116.306442"><ele>53.71</ele> +<time>2024-11-11T11:39:48Z</time> +</trkpt> +<trkpt lat="40.044460" lon="116.306473"><ele>53.67</ele> +<time>2024-11-11T11:39:49Z</time> +</trkpt> +<trkpt lat="40.044418" lon="116.306503"><ele>53.67</ele> +<time>2024-11-11T11:39:50Z</time> +</trkpt> +<trkpt lat="40.044376" lon="116.306541"><ele>53.40</ele> +<time>2024-11-11T11:39:51Z</time> +</trkpt> +<trkpt lat="40.044334" lon="116.306572"><ele>53.42</ele> +<time>2024-11-11T11:39:52Z</time> +</trkpt> +<trkpt lat="40.044292" lon="116.306602"><ele>53.38</ele> +<time>2024-11-11T11:39:53Z</time> +</trkpt> +<trkpt lat="40.044247" lon="116.306633"><ele>53.29</ele> +<time>2024-11-11T11:39:54Z</time> +</trkpt> +<trkpt lat="40.044205" lon="116.306671"><ele>53.23</ele> +<time>2024-11-11T11:39:55Z</time> +</trkpt> +<trkpt lat="40.044159" lon="116.306702"><ele>53.07</ele> +<time>2024-11-11T11:39:56Z</time> +</trkpt> +<trkpt lat="40.044117" lon="116.306740"><ele>53.07</ele> +<time>2024-11-11T11:39:57Z</time> +</trkpt> +<trkpt lat="40.044075" lon="116.306778"><ele>53.02</ele> +<time>2024-11-11T11:39:58Z</time> +</trkpt> +<trkpt lat="40.044025" lon="116.306808"><ele>52.96</ele> +<time>2024-11-11T11:39:59Z</time> +</trkpt> +<trkpt lat="40.043980" lon="116.306847"><ele>52.96</ele> +<time>2024-11-11T11:40:00Z</time> +</trkpt> +<trkpt lat="40.043930" lon="116.306885"><ele>52.95</ele> +<time>2024-11-11T11:40:01Z</time> +</trkpt> +<trkpt lat="40.043877" lon="116.306915"><ele>52.95</ele> +<time>2024-11-11T11:40:02Z</time> +</trkpt> +<trkpt lat="40.043831" lon="116.306953"><ele>52.60</ele> +<time>2024-11-11T11:40:03Z</time> +</trkpt> +<trkpt lat="40.043781" lon="116.306992"><ele>52.60</ele> +<time>2024-11-11T11:40:04Z</time> +</trkpt> +<trkpt lat="40.043732" lon="116.307030"><ele>52.58</ele> +<time>2024-11-11T11:40:05Z</time> +</trkpt> +<trkpt lat="40.043682" lon="116.307060"><ele>52.58</ele> +<time>2024-11-11T11:40:06Z</time> +</trkpt> +<trkpt lat="40.043633" lon="116.307098"><ele>52.41</ele> +<time>2024-11-11T11:40:07Z</time> +</trkpt> +<trkpt lat="40.043587" lon="116.307137"><ele>52.52</ele> +<time>2024-11-11T11:40:08Z</time> +</trkpt> +<trkpt lat="40.043537" lon="116.307175"><ele>52.52</ele> +<time>2024-11-11T11:40:09Z</time> +</trkpt> +<trkpt lat="40.043491" lon="116.307213"><ele>52.53</ele> +<time>2024-11-11T11:40:10Z</time> +</trkpt> +<trkpt lat="40.043442" lon="116.307251"><ele>52.59</ele> +<time>2024-11-11T11:40:11Z</time> +</trkpt> +<trkpt lat="40.043392" lon="116.307281"><ele>52.59</ele> +<time>2024-11-11T11:40:12Z</time> +</trkpt> +<trkpt lat="40.043343" lon="116.307320"><ele>52.67</ele> +<time>2024-11-11T11:40:13Z</time> +</trkpt> +<trkpt lat="40.043297" lon="116.307350"><ele>52.58</ele> +<time>2024-11-11T11:40:14Z</time> +</trkpt> +<trkpt lat="40.043255" lon="116.307388"><ele>52.62</ele> +<time>2024-11-11T11:40:15Z</time> +</trkpt> +<trkpt lat="40.043213" lon="116.307426"><ele>52.65</ele> +<time>2024-11-11T11:40:16Z</time> +</trkpt> +<trkpt lat="40.043171" lon="116.307465"><ele>52.76</ele> +<time>2024-11-11T11:40:17Z</time> +</trkpt> +<trkpt lat="40.043121" lon="116.307510"><ele>52.81</ele> +<time>2024-11-11T11:40:18Z</time> +</trkpt> +<trkpt lat="40.043068" lon="116.307564"><ele>52.88</ele> +<time>2024-11-11T11:40:19Z</time> +</trkpt> +<trkpt lat="40.043034" lon="116.307617"><ele>53.08</ele> +<time>2024-11-11T11:40:20Z</time> +</trkpt> +<trkpt lat="40.043011" lon="116.307655"><ele>53.09</ele> +<time>2024-11-11T11:40:21Z</time> +</trkpt> +<trkpt lat="40.042995" lon="116.307678"><ele>53.08</ele> +<time>2024-11-11T11:40:22Z</time> +</trkpt> +<trkpt lat="40.042980" lon="116.307739"><ele>53.08</ele> +<time>2024-11-11T11:40:23Z</time> +</trkpt> +<trkpt lat="40.042961" lon="116.307808"><ele>53.31</ele> +<time>2024-11-11T11:40:24Z</time> +</trkpt> +<trkpt lat="40.042950" lon="116.307884"><ele>53.39</ele> +<time>2024-11-11T11:40:25Z</time> +</trkpt> +<trkpt lat="40.042953" lon="116.307945"><ele>53.58</ele> +<time>2024-11-11T11:40:26Z</time> +</trkpt> +<trkpt lat="40.042969" lon="116.307999"><ele>53.48</ele> +<time>2024-11-11T11:40:27Z</time> +</trkpt> +<trkpt lat="40.042980" lon="116.308029"><ele>53.44</ele> +<time>2024-11-11T11:40:28Z</time> +</trkpt> +<trkpt lat="40.043018" lon="116.308060"><ele>53.31</ele> +<time>2024-11-11T11:40:29Z</time> +</trkpt> +<trkpt lat="40.043053" lon="116.308121"><ele>53.28</ele> +<time>2024-11-11T11:40:30Z</time> +</trkpt> +<trkpt lat="40.043087" lon="116.308182"><ele>53.10</ele> +<time>2024-11-11T11:40:31Z</time> +</trkpt> +<trkpt lat="40.043118" lon="116.308243"><ele>52.64</ele> +<time>2024-11-11T11:40:32Z</time> +</trkpt> +<trkpt lat="40.043152" lon="116.308304"><ele>52.59</ele> +<time>2024-11-11T11:40:33Z</time> +</trkpt> +<trkpt lat="40.043182" lon="116.308365"><ele>52.36</ele> +<time>2024-11-11T11:40:34Z</time> +</trkpt> +<trkpt lat="40.043213" lon="116.308434"><ele>52.25</ele> +<time>2024-11-11T11:40:35Z</time> +</trkpt> +<trkpt lat="40.043243" lon="116.308487"><ele>52.25</ele> +<time>2024-11-11T11:40:36Z</time> +</trkpt> +<trkpt lat="40.043278" lon="116.308548"><ele>52.29</ele> +<time>2024-11-11T11:40:37Z</time> +</trkpt> +<trkpt lat="40.043316" lon="116.308601"><ele>52.28</ele> +<time>2024-11-11T11:40:38Z</time> +</trkpt> +<trkpt lat="40.043350" lon="116.308662"><ele>52.05</ele> +<time>2024-11-11T11:40:39Z</time> +</trkpt> +<trkpt lat="40.043388" lon="116.308716"><ele>52.05</ele> +<time>2024-11-11T11:40:40Z</time> +</trkpt> +<trkpt lat="40.043427" lon="116.308769"><ele>51.93</ele> +<time>2024-11-11T11:40:41Z</time> +</trkpt> +<trkpt lat="40.043461" lon="116.308830"><ele>51.93</ele> +<time>2024-11-11T11:40:42Z</time> +</trkpt> +<trkpt lat="40.043495" lon="116.308884"><ele>51.99</ele> +<time>2024-11-11T11:40:43Z</time> +</trkpt> +<trkpt lat="40.043533" lon="116.308937"><ele>51.93</ele> +<time>2024-11-11T11:40:44Z</time> +</trkpt> +<trkpt lat="40.043568" lon="116.308990"><ele>51.92</ele> +<time>2024-11-11T11:40:45Z</time> +</trkpt> +<trkpt lat="40.043602" lon="116.309044"><ele>51.88</ele> +<time>2024-11-11T11:40:46Z</time> +</trkpt> +<trkpt lat="40.043636" lon="116.309105"><ele>51.92</ele> +<time>2024-11-11T11:40:47Z</time> +</trkpt> +<trkpt lat="40.043671" lon="116.309158"><ele>51.88</ele> +<time>2024-11-11T11:40:48Z</time> +</trkpt> +<trkpt lat="40.043705" lon="116.309219"><ele>51.69</ele> +<time>2024-11-11T11:40:49Z</time> +</trkpt> +<trkpt lat="40.043736" lon="116.309273"><ele>51.12</ele> +<time>2024-11-11T11:40:50Z</time> +</trkpt> +<trkpt lat="40.043774" lon="116.309326"><ele>51.12</ele> +<time>2024-11-11T11:40:51Z</time> +</trkpt> +<trkpt lat="40.043808" lon="116.309387"><ele>51.39</ele> +<time>2024-11-11T11:40:52Z</time> +</trkpt> +<trkpt lat="40.043842" lon="116.309441"><ele>51.41</ele> +<time>2024-11-11T11:40:53Z</time> +</trkpt> +<trkpt lat="40.043877" lon="116.309494"><ele>51.66</ele> +<time>2024-11-11T11:40:54Z</time> +</trkpt> +<trkpt lat="40.043911" lon="116.309547"><ele>51.67</ele> +<time>2024-11-11T11:40:55Z</time> +</trkpt> +<trkpt lat="40.043949" lon="116.309608"><ele>51.95</ele> +<time>2024-11-11T11:40:56Z</time> +</trkpt> +<trkpt lat="40.043983" lon="116.309662"><ele>52.10</ele> +<time>2024-11-11T11:40:57Z</time> +</trkpt> +<trkpt lat="40.044018" lon="116.309723"><ele>52.10</ele> +<time>2024-11-11T11:40:58Z</time> +</trkpt> +<trkpt lat="40.044052" lon="116.309776"><ele>51.92</ele> +<time>2024-11-11T11:40:59Z</time> +</trkpt> +<trkpt lat="40.044086" lon="116.309837"><ele>51.77</ele> +<time>2024-11-11T11:41:00Z</time> +</trkpt> +<trkpt lat="40.044121" lon="116.309891"><ele>51.89</ele> +<time>2024-11-11T11:41:01Z</time> +</trkpt> +<trkpt lat="40.044159" lon="116.309952"><ele>51.69</ele> +<time>2024-11-11T11:41:02Z</time> +</trkpt> +<trkpt lat="40.044193" lon="116.310005"><ele>51.69</ele> +<time>2024-11-11T11:41:03Z</time> +</trkpt> +<trkpt lat="40.044228" lon="116.310059"><ele>51.96</ele> +<time>2024-11-11T11:41:04Z</time> +</trkpt> +<trkpt lat="40.044258" lon="116.310120"><ele>51.80</ele> +<time>2024-11-11T11:41:05Z</time> +</trkpt> +<trkpt lat="40.044292" lon="116.310181"><ele>51.97</ele> +<time>2024-11-11T11:41:06Z</time> +</trkpt> +<trkpt lat="40.044327" lon="116.310234"><ele>52.00</ele> +<time>2024-11-11T11:41:07Z</time> +</trkpt> +<trkpt lat="40.044357" lon="116.310287"><ele>52.00</ele> +<time>2024-11-11T11:41:08Z</time> +</trkpt> +<trkpt lat="40.044392" lon="116.310341"><ele>52.24</ele> +<time>2024-11-11T11:41:09Z</time> +</trkpt> +<trkpt lat="40.044422" lon="116.310379"><ele>52.24</ele> +<time>2024-11-11T11:41:10Z</time> +</trkpt> +<trkpt lat="40.044456" lon="116.310425"><ele>52.05</ele> +<time>2024-11-11T11:41:11Z</time> +</trkpt> +<trkpt lat="40.044495" lon="116.310471"><ele>52.05</ele> +<time>2024-11-11T11:41:12Z</time> +</trkpt> +<trkpt lat="40.044533" lon="116.310509"><ele>51.99</ele> +<time>2024-11-11T11:41:13Z</time> +</trkpt> +<trkpt lat="40.044571" lon="116.310539"><ele>51.94</ele> +<time>2024-11-11T11:41:14Z</time> +</trkpt> +<trkpt lat="40.044609" lon="116.310570"><ele>51.87</ele> +<time>2024-11-11T11:41:15Z</time> +</trkpt> +<trkpt lat="40.044651" lon="116.310600"><ele>51.89</ele> +<time>2024-11-11T11:41:16Z</time> +</trkpt> +<trkpt lat="40.044697" lon="116.310623"><ele>52.20</ele> +<time>2024-11-11T11:41:17Z</time> +</trkpt> +<trkpt lat="40.044743" lon="116.310638"><ele>52.24</ele> +<time>2024-11-11T11:41:18Z</time> +</trkpt> +<trkpt lat="40.044788" lon="116.310646"><ele>52.20</ele> +<time>2024-11-11T11:41:19Z</time> +</trkpt> +<trkpt lat="40.044838" lon="116.310646"><ele>52.15</ele> +<time>2024-11-11T11:41:20Z</time> +</trkpt> +<trkpt lat="40.044884" lon="116.310631"><ele>52.15</ele> +<time>2024-11-11T11:41:21Z</time> +</trkpt> +<trkpt lat="40.044933" lon="116.310616"><ele>52.23</ele> +<time>2024-11-11T11:41:22Z</time> +</trkpt> +<trkpt lat="40.044979" lon="116.310593"><ele>52.43</ele> +<time>2024-11-11T11:41:23Z</time> +</trkpt> +<trkpt lat="40.045029" lon="116.310555"><ele>52.44</ele> +<time>2024-11-11T11:41:24Z</time> +</trkpt> +<trkpt lat="40.045078" lon="116.310524"><ele>52.74</ele> +<time>2024-11-11T11:41:25Z</time> +</trkpt> +<trkpt lat="40.045128" lon="116.310486"><ele>52.74</ele> +<time>2024-11-11T11:41:26Z</time> +</trkpt> +<trkpt lat="40.045174" lon="116.310455"><ele>52.67</ele> +<time>2024-11-11T11:41:27Z</time> +</trkpt> +<trkpt lat="40.045223" lon="116.310425"><ele>52.67</ele> +<time>2024-11-11T11:41:28Z</time> +</trkpt> +<trkpt lat="40.045273" lon="116.310387"><ele>52.77</ele> +<time>2024-11-11T11:41:29Z</time> +</trkpt> +<trkpt lat="40.045322" lon="116.310356"><ele>52.78</ele> +<time>2024-11-11T11:41:30Z</time> +</trkpt> +<trkpt lat="40.045372" lon="116.310318"><ele>52.90</ele> +<time>2024-11-11T11:41:31Z</time> +</trkpt> +<trkpt lat="40.045422" lon="116.310287"><ele>52.95</ele> +<time>2024-11-11T11:41:32Z</time> +</trkpt> +<trkpt lat="40.045467" lon="116.310265"><ele>52.90</ele> +<time>2024-11-11T11:41:33Z</time> +</trkpt> +<trkpt lat="40.045521" lon="116.310234"><ele>52.72</ele> +<time>2024-11-11T11:41:34Z</time> +</trkpt> +<trkpt lat="40.045570" lon="116.310196"><ele>52.57</ele> +<time>2024-11-11T11:41:35Z</time> +</trkpt> +<trkpt lat="40.045616" lon="116.310165"><ele>52.57</ele> +<time>2024-11-11T11:41:36Z</time> +</trkpt> +<trkpt lat="40.045658" lon="116.310143"><ele>52.64</ele> +<time>2024-11-11T11:41:37Z</time> +</trkpt> +<trkpt lat="40.045700" lon="116.310127"><ele>52.99</ele> +<time>2024-11-11T11:41:38Z</time> +</trkpt> +<trkpt lat="40.045738" lon="116.310112"><ele>53.08</ele> +<time>2024-11-11T11:41:39Z</time> +</trkpt> +<trkpt lat="40.045780" lon="116.310081"><ele>53.08</ele> +<time>2024-11-11T11:41:40Z</time> +</trkpt> +<trkpt lat="40.045830" lon="116.310066"><ele>52.96</ele> +<time>2024-11-11T11:41:41Z</time> +</trkpt> +<trkpt lat="40.045879" lon="116.310051"><ele>52.81</ele> +<time>2024-11-11T11:41:42Z</time> +</trkpt> +<trkpt lat="40.045929" lon="116.310028"><ele>52.81</ele> +<time>2024-11-11T11:41:43Z</time> +</trkpt> +<trkpt lat="40.045979" lon="116.310013"><ele>52.81</ele> +<time>2024-11-11T11:41:44Z</time> +</trkpt> +<trkpt lat="40.046024" lon="116.310005"><ele>52.81</ele> +<time>2024-11-11T11:41:45Z</time> +</trkpt> +<trkpt lat="40.046066" lon="116.310005"><ele>52.36</ele> +<time>2024-11-11T11:41:46Z</time> +</trkpt> +<trkpt lat="40.046112" lon="116.309982"><ele>52.36</ele> +<time>2024-11-11T11:41:47Z</time> +</trkpt> +<trkpt lat="40.046158" lon="116.309952"><ele>52.27</ele> +<time>2024-11-11T11:41:48Z</time> +</trkpt> +<trkpt lat="40.046207" lon="116.309914"><ele>52.36</ele> +<time>2024-11-11T11:41:49Z</time> +</trkpt> +<trkpt lat="40.046249" lon="116.309883"><ele>51.98</ele> +<time>2024-11-11T11:41:50Z</time> +</trkpt> +<trkpt lat="40.046295" lon="116.309845"><ele>51.77</ele> +<time>2024-11-11T11:41:51Z</time> +</trkpt> +<trkpt lat="40.046345" lon="116.309830"><ele>51.87</ele> +<time>2024-11-11T11:41:52Z</time> +</trkpt> +<trkpt lat="40.046394" lon="116.309807"><ele>51.98</ele> +<time>2024-11-11T11:41:53Z</time> +</trkpt> +<trkpt lat="40.046440" lon="116.309792"><ele>52.12</ele> +<time>2024-11-11T11:41:54Z</time> +</trkpt> +<trkpt lat="40.046486" lon="116.309776"><ele>52.12</ele> +<time>2024-11-11T11:41:55Z</time> +</trkpt> +<trkpt lat="40.046524" lon="116.309753"><ele>52.37</ele> +<time>2024-11-11T11:41:56Z</time> +</trkpt> +<trkpt lat="40.046558" lon="116.309723"><ele>52.47</ele> +<time>2024-11-11T11:41:57Z</time> +</trkpt> +<trkpt lat="40.046585" lon="116.309708"><ele>52.75</ele> +<time>2024-11-11T11:41:58Z</time> +</trkpt> +<trkpt lat="40.046608" lon="116.309700"><ele>52.75</ele> +<time>2024-11-11T11:41:59Z</time> +</trkpt> +<trkpt lat="40.046635" lon="116.309708"><ele>52.75</ele> +<time>2024-11-11T11:42:00Z</time> +</trkpt> +<trkpt lat="40.046669" lon="116.309715"><ele>52.75</ele> +<time>2024-11-11T11:42:01Z</time> +</trkpt> +<trkpt lat="40.046700" lon="116.309731"><ele>52.58</ele> +<time>2024-11-11T11:42:02Z</time> +</trkpt> +<trkpt lat="40.046719" lon="116.309746"><ele>52.57</ele> +<time>2024-11-11T11:42:03Z</time> +</trkpt> +<trkpt lat="40.046719" lon="116.309753"><ele>52.56</ele> +<time>2024-11-11T11:42:04Z</time> +</trkpt> +<trkpt lat="40.046726" lon="116.309776"><ele>52.42</ele> +<time>2024-11-11T11:42:05Z</time> +</trkpt> +<trkpt lat="40.046738" lon="116.309807"><ele>52.28</ele> +<time>2024-11-11T11:42:06Z</time> +</trkpt> +<trkpt lat="40.046757" lon="116.309845"><ele>52.07</ele> +<time>2024-11-11T11:42:07Z</time> +</trkpt> +<trkpt lat="40.046776" lon="116.309883"><ele>52.07</ele> +<time>2024-11-11T11:42:08Z</time> +</trkpt> +<trkpt lat="40.046795" lon="116.309929"><ele>52.07</ele> +<time>2024-11-11T11:42:09Z</time> +</trkpt> +<trkpt lat="40.046814" lon="116.309975"><ele>52.06</ele> +<time>2024-11-11T11:42:10Z</time> +</trkpt> +<trkpt lat="40.046837" lon="116.310028"><ele>52.17</ele> +<time>2024-11-11T11:42:11Z</time> +</trkpt> +<trkpt lat="40.046864" lon="116.310081"><ele>52.17</ele> +<time>2024-11-11T11:42:12Z</time> +</trkpt> +<trkpt lat="40.046886" lon="116.310135"><ele>52.17</ele> +<time>2024-11-11T11:42:13Z</time> +</trkpt> +<trkpt lat="40.046913" lon="116.310196"><ele>52.20</ele> +<time>2024-11-11T11:42:14Z</time> +</trkpt> +<trkpt lat="40.046940" lon="116.310257"><ele>52.20</ele> +<time>2024-11-11T11:42:15Z</time> +</trkpt> +<trkpt lat="40.046963" lon="116.310318"><ele>52.20</ele> +<time>2024-11-11T11:42:16Z</time> +</trkpt> +<trkpt lat="40.046989" lon="116.310371"><ele>51.85</ele> +<time>2024-11-11T11:42:17Z</time> +</trkpt> +<trkpt lat="40.047016" lon="116.310432"><ele>51.85</ele> +<time>2024-11-11T11:42:18Z</time> +</trkpt> +<trkpt lat="40.047047" lon="116.310486"><ele>52.33</ele> +<time>2024-11-11T11:42:19Z</time> +</trkpt> +<trkpt lat="40.047073" lon="116.310547"><ele>52.39</ele> +<time>2024-11-11T11:42:20Z</time> +</trkpt> +<trkpt lat="40.047104" lon="116.310616"><ele>52.52</ele> +<time>2024-11-11T11:42:21Z</time> +</trkpt> +<trkpt lat="40.047134" lon="116.310677"><ele>52.50</ele> +<time>2024-11-11T11:42:22Z</time> +</trkpt> +<trkpt lat="40.047161" lon="116.310738"><ele>52.50</ele> +<time>2024-11-11T11:42:23Z</time> +</trkpt> +<trkpt lat="40.047192" lon="116.310806"><ele>52.50</ele> +<time>2024-11-11T11:42:24Z</time> +</trkpt> +<trkpt lat="40.047215" lon="116.310867"><ele>52.06</ele> +<time>2024-11-11T11:42:25Z</time> +</trkpt> +<trkpt lat="40.047234" lon="116.310928"><ele>52.06</ele> +<time>2024-11-11T11:42:26Z</time> +</trkpt> +<trkpt lat="40.047260" lon="116.310997"><ele>51.96</ele> +<time>2024-11-11T11:42:27Z</time> +</trkpt> +<trkpt lat="40.047287" lon="116.311050"><ele>51.92</ele> +<time>2024-11-11T11:42:28Z</time> +</trkpt> +<trkpt lat="40.047310" lon="116.311111"><ele>51.76</ele> +<time>2024-11-11T11:42:29Z</time> +</trkpt> +<trkpt lat="40.047337" lon="116.311172"><ele>51.74</ele> +<time>2024-11-11T11:42:30Z</time> +</trkpt> +<trkpt lat="40.047359" lon="116.311226"><ele>51.62</ele> +<time>2024-11-11T11:42:31Z</time> +</trkpt> +<trkpt lat="40.047386" lon="116.311287"><ele>51.62</ele> +<time>2024-11-11T11:42:32Z</time> +</trkpt> +<trkpt lat="40.047413" lon="116.311348"><ele>51.62</ele> +<time>2024-11-11T11:42:33Z</time> +</trkpt> +<trkpt lat="40.047440" lon="116.311409"><ele>51.86</ele> +<time>2024-11-11T11:42:34Z</time> +</trkpt> +<trkpt lat="40.047470" lon="116.311455"><ele>51.86</ele> +<time>2024-11-11T11:42:35Z</time> +</trkpt> +<trkpt lat="40.047501" lon="116.311516"><ele>51.81</ele> +<time>2024-11-11T11:42:36Z</time> +</trkpt> +<trkpt lat="40.047527" lon="116.311569"><ele>51.94</ele> +<time>2024-11-11T11:42:37Z</time> +</trkpt> +<trkpt lat="40.047543" lon="116.311615"><ele>51.94</ele> +<time>2024-11-11T11:42:38Z</time> +</trkpt> +<trkpt lat="40.047565" lon="116.311676"><ele>52.06</ele> +<time>2024-11-11T11:42:39Z</time> +</trkpt> +<trkpt lat="40.047596" lon="116.311729"><ele>52.06</ele> +<time>2024-11-11T11:42:40Z</time> +</trkpt> +<trkpt lat="40.047615" lon="116.311790"><ele>51.89</ele> +<time>2024-11-11T11:42:41Z</time> +</trkpt> +<trkpt lat="40.047646" lon="116.311844"><ele>51.62</ele> +<time>2024-11-11T11:42:42Z</time> +</trkpt> +<trkpt lat="40.047672" lon="116.311897"><ele>51.62</ele> +<time>2024-11-11T11:42:43Z</time> +</trkpt> +<trkpt lat="40.047699" lon="116.311958"><ele>51.62</ele> +<time>2024-11-11T11:42:44Z</time> +</trkpt> +<trkpt lat="40.047726" lon="116.312012"><ele>51.92</ele> +<time>2024-11-11T11:42:45Z</time> +</trkpt> +<trkpt lat="40.047752" lon="116.312065"><ele>52.03</ele> +<time>2024-11-11T11:42:46Z</time> +</trkpt> +<trkpt lat="40.047775" lon="116.312119"><ele>52.15</ele> +<time>2024-11-11T11:42:47Z</time> +</trkpt> +<trkpt lat="40.047798" lon="116.312164"><ele>52.20</ele> +<time>2024-11-11T11:42:48Z</time> +</trkpt> +<trkpt lat="40.047817" lon="116.312210"><ele>52.21</ele> +<time>2024-11-11T11:42:49Z</time> +</trkpt> +<trkpt lat="40.047844" lon="116.312248"><ele>52.29</ele> +<time>2024-11-11T11:42:50Z</time> +</trkpt> +<trkpt lat="40.047871" lon="116.312294"><ele>52.34</ele> +<time>2024-11-11T11:42:51Z</time> +</trkpt> +<trkpt lat="40.047886" lon="116.312340"><ele>52.43</ele> +<time>2024-11-11T11:42:52Z</time> +</trkpt> +<trkpt lat="40.047890" lon="116.312386"><ele>52.43</ele> +<time>2024-11-11T11:42:53Z</time> +</trkpt> +<trkpt lat="40.047871" lon="116.312431"><ele>52.43</ele> +<time>2024-11-11T11:42:54Z</time> +</trkpt> +<trkpt lat="40.047848" lon="116.312469"><ele>52.44</ele> +<time>2024-11-11T11:42:55Z</time> +</trkpt> +<trkpt lat="40.047813" lon="116.312500"><ele>52.36</ele> +<time>2024-11-11T11:42:56Z</time> +</trkpt> +<trkpt lat="40.047771" lon="116.312538"><ele>52.30</ele> +<time>2024-11-11T11:42:57Z</time> +</trkpt> +<trkpt lat="40.047726" lon="116.312553"><ele>52.14</ele> +<time>2024-11-11T11:42:58Z</time> +</trkpt> +<trkpt lat="40.047680" lon="116.312561"><ele>52.10</ele> +<time>2024-11-11T11:42:59Z</time> +</trkpt> +<trkpt lat="40.047634" lon="116.312584"><ele>51.79</ele> +<time>2024-11-11T11:43:00Z</time> +</trkpt> +<trkpt lat="40.047588" lon="116.312607"><ele>51.79</ele> +<time>2024-11-11T11:43:01Z</time> +</trkpt> +<trkpt lat="40.047543" lon="116.312614"><ele>52.07</ele> +<time>2024-11-11T11:43:02Z</time> +</trkpt> +<trkpt lat="40.047493" lon="116.312637"><ele>52.07</ele> +<time>2024-11-11T11:43:03Z</time> +</trkpt> +<trkpt lat="40.047447" lon="116.312653"><ele>51.93</ele> +<time>2024-11-11T11:43:04Z</time> +</trkpt> +<trkpt lat="40.047405" lon="116.312668"><ele>51.86</ele> +<time>2024-11-11T11:43:05Z</time> +</trkpt> +<trkpt lat="40.047359" lon="116.312691"><ele>51.71</ele> +<time>2024-11-11T11:43:06Z</time> +</trkpt> +<trkpt lat="40.047310" lon="116.312714"><ele>51.86</ele> +<time>2024-11-11T11:43:07Z</time> +</trkpt> +<trkpt lat="40.047260" lon="116.312729"><ele>51.96</ele> +<time>2024-11-11T11:43:08Z</time> +</trkpt> +<trkpt lat="40.047211" lon="116.312752"><ele>51.96</ele> +<time>2024-11-11T11:43:09Z</time> +</trkpt> +<trkpt lat="40.047157" lon="116.312775"><ele>51.86</ele> +<time>2024-11-11T11:43:10Z</time> +</trkpt> +<trkpt lat="40.047096" lon="116.312798"><ele>51.86</ele> +<time>2024-11-11T11:43:11Z</time> +</trkpt> +<trkpt lat="40.047050" lon="116.312813"><ele>51.95</ele> +<time>2024-11-11T11:43:12Z</time> +</trkpt> +<trkpt lat="40.047001" lon="116.312843"><ele>52.07</ele> +<time>2024-11-11T11:43:13Z</time> +</trkpt> +<trkpt lat="40.046959" lon="116.312866"><ele>52.20</ele> +<time>2024-11-11T11:43:14Z</time> +</trkpt> +<trkpt lat="40.046921" lon="116.312889"><ele>52.22</ele> +<time>2024-11-11T11:43:15Z</time> +</trkpt> +<trkpt lat="40.046879" lon="116.312912"><ele>52.43</ele> +<time>2024-11-11T11:43:16Z</time> +</trkpt> +<trkpt lat="40.046837" lon="116.312920"><ele>52.43</ele> +<time>2024-11-11T11:43:17Z</time> +</trkpt> +<trkpt lat="40.046803" lon="116.312935"><ele>52.37</ele> +<time>2024-11-11T11:43:18Z</time> +</trkpt> +<trkpt lat="40.046761" lon="116.312950"><ele>52.22</ele> +<time>2024-11-11T11:43:19Z</time> +</trkpt> +<trkpt lat="40.046722" lon="116.312973"><ele>52.21</ele> +<time>2024-11-11T11:43:20Z</time> +</trkpt> +<trkpt lat="40.046688" lon="116.312988"><ele>52.22</ele> +<time>2024-11-11T11:43:21Z</time> +</trkpt> +<trkpt lat="40.046650" lon="116.313004"><ele>52.45</ele> +<time>2024-11-11T11:43:22Z</time> +</trkpt> +<trkpt lat="40.046619" lon="116.313011"><ele>52.51</ele> +<time>2024-11-11T11:43:23Z</time> +</trkpt> +<trkpt lat="40.046589" lon="116.313026"><ele>52.54</ele> +<time>2024-11-11T11:43:24Z</time> +</trkpt> +<trkpt lat="40.046566" lon="116.313026"><ele>52.65</ele> +<time>2024-11-11T11:43:25Z</time> +</trkpt> +<trkpt lat="40.046539" lon="116.313026"><ele>52.65</ele> +<time>2024-11-11T11:43:26Z</time> +</trkpt> +<trkpt lat="40.046513" lon="116.313019"><ele>52.72</ele> +<time>2024-11-11T11:43:27Z</time> +</trkpt> +<trkpt lat="40.046486" lon="116.313011"><ele>52.65</ele> +<time>2024-11-11T11:43:28Z</time> +</trkpt> +<trkpt lat="40.046459" lon="116.312988"><ele>52.63</ele> +<time>2024-11-11T11:43:29Z</time> +</trkpt> +<trkpt lat="40.046436" lon="116.312958"><ele>52.63</ele> +<time>2024-11-11T11:43:30Z</time> +</trkpt> +<trkpt lat="40.046406" lon="116.312920"><ele>52.54</ele> +<time>2024-11-11T11:43:31Z</time> +</trkpt> +<trkpt lat="40.046375" lon="116.312881"><ele>52.51</ele> +<time>2024-11-11T11:43:32Z</time> +</trkpt> +<trkpt lat="40.046349" lon="116.312836"><ele>52.33</ele> +<time>2024-11-11T11:43:33Z</time> +</trkpt> +<trkpt lat="40.046314" lon="116.312790"><ele>52.33</ele> +<time>2024-11-11T11:43:34Z</time> +</trkpt> +<trkpt lat="40.046284" lon="116.312744"><ele>52.24</ele> +<time>2024-11-11T11:43:35Z</time> +</trkpt> +<trkpt lat="40.046253" lon="116.312698"><ele>52.35</ele> +<time>2024-11-11T11:43:36Z</time> +</trkpt> +<trkpt lat="40.046219" lon="116.312645"><ele>52.35</ele> +<time>2024-11-11T11:43:37Z</time> +</trkpt> +<trkpt lat="40.046185" lon="116.312599"><ele>52.35</ele> +<time>2024-11-11T11:43:38Z</time> +</trkpt> +<trkpt lat="40.046150" lon="116.312561"><ele>52.38</ele> +<time>2024-11-11T11:43:39Z</time> +</trkpt> +<trkpt lat="40.046112" lon="116.312515"><ele>52.33</ele> +<time>2024-11-11T11:43:40Z</time> +</trkpt> +<trkpt lat="40.046078" lon="116.312469"><ele>52.36</ele> +<time>2024-11-11T11:43:41Z</time> +</trkpt> +<trkpt lat="40.046043" lon="116.312424"><ele>52.36</ele> +<time>2024-11-11T11:43:42Z</time> +</trkpt> +<trkpt lat="40.046001" lon="116.312378"><ele>52.36</ele> +<time>2024-11-11T11:43:43Z</time> +</trkpt> +<trkpt lat="40.045963" lon="116.312332"><ele>52.35</ele> +<time>2024-11-11T11:43:44Z</time> +</trkpt> +<trkpt lat="40.045929" lon="116.312286"><ele>52.22</ele> +<time>2024-11-11T11:43:45Z</time> +</trkpt> +<trkpt lat="40.045898" lon="116.312233"><ele>52.19</ele> +<time>2024-11-11T11:43:46Z</time> +</trkpt> +<trkpt lat="40.045860" lon="116.312180"><ele>52.19</ele> +<time>2024-11-11T11:43:47Z</time> +</trkpt> +<trkpt lat="40.045826" lon="116.312134"><ele>52.17</ele> +<time>2024-11-11T11:43:48Z</time> +</trkpt> +<trkpt lat="40.045788" lon="116.312080"><ele>52.16</ele> +<time>2024-11-11T11:43:49Z</time> +</trkpt> +<trkpt lat="40.045750" lon="116.312035"><ele>52.16</ele> +<time>2024-11-11T11:43:50Z</time> +</trkpt> +<trkpt lat="40.045712" lon="116.311981"><ele>52.03</ele> +<time>2024-11-11T11:43:51Z</time> +</trkpt> +<trkpt lat="40.045673" lon="116.311935"><ele>52.00</ele> +<time>2024-11-11T11:43:52Z</time> +</trkpt> +<trkpt lat="40.045639" lon="116.311882"><ele>51.98</ele> +<time>2024-11-11T11:43:53Z</time> +</trkpt> +<trkpt lat="40.045612" lon="116.311836"><ele>51.94</ele> +<time>2024-11-11T11:43:54Z</time> +</trkpt> +<trkpt lat="40.045582" lon="116.311783"><ele>51.95</ele> +<time>2024-11-11T11:43:55Z</time> +</trkpt> +<trkpt lat="40.045547" lon="116.311729"><ele>51.92</ele> +<time>2024-11-11T11:43:56Z</time> +</trkpt> +<trkpt lat="40.045509" lon="116.311676"><ele>51.94</ele> +<time>2024-11-11T11:43:57Z</time> +</trkpt> +<trkpt lat="40.045475" lon="116.311623"><ele>51.92</ele> +<time>2024-11-11T11:43:58Z</time> +</trkpt> +<trkpt lat="40.045441" lon="116.311569"><ele>52.04</ele> +<time>2024-11-11T11:43:59Z</time> +</trkpt> +<trkpt lat="40.045410" lon="116.311516"><ele>51.98</ele> +<time>2024-11-11T11:44:00Z</time> +</trkpt> +<trkpt lat="40.045376" lon="116.311462"><ele>51.98</ele> +<time>2024-11-11T11:44:01Z</time> +</trkpt> +<trkpt lat="40.045345" lon="116.311409"><ele>51.83</ele> +<time>2024-11-11T11:44:02Z</time> +</trkpt> +<trkpt lat="40.045315" lon="116.311356"><ele>51.96</ele> +<time>2024-11-11T11:44:03Z</time> +</trkpt> +<trkpt lat="40.045284" lon="116.311310"><ele>51.97</ele> +<time>2024-11-11T11:44:04Z</time> +</trkpt> +<trkpt lat="40.045254" lon="116.311256"><ele>52.06</ele> +<time>2024-11-11T11:44:05Z</time> +</trkpt> +<trkpt lat="40.045223" lon="116.311211"><ele>52.23</ele> +<time>2024-11-11T11:44:06Z</time> +</trkpt> +<trkpt lat="40.045193" lon="116.311165"><ele>52.23</ele> +<time>2024-11-11T11:44:07Z</time> +</trkpt> +<trkpt lat="40.045158" lon="116.311119"><ele>52.23</ele> +<time>2024-11-11T11:44:08Z</time> +</trkpt> +<trkpt lat="40.045124" lon="116.311073"><ele>52.30</ele> +<time>2024-11-11T11:44:09Z</time> +</trkpt> +<trkpt lat="40.045094" lon="116.311028"><ele>52.30</ele> +<time>2024-11-11T11:44:10Z</time> +</trkpt> +<trkpt lat="40.045059" lon="116.310982"><ele>52.28</ele> +<time>2024-11-11T11:44:11Z</time> +</trkpt> +<trkpt lat="40.045036" lon="116.310936"><ele>52.18</ele> +<time>2024-11-11T11:44:12Z</time> +</trkpt> +<trkpt lat="40.045013" lon="116.310883"><ele>52.10</ele> +<time>2024-11-11T11:44:13Z</time> +</trkpt> +<trkpt lat="40.045010" lon="116.310829"><ele>51.94</ele> +<time>2024-11-11T11:44:14Z</time> +</trkpt> +<trkpt lat="40.045021" lon="116.310776"><ele>51.94</ele> +<time>2024-11-11T11:44:15Z</time> +</trkpt> +<trkpt lat="40.045040" lon="116.310745"><ele>51.73</ele> +<time>2024-11-11T11:44:16Z</time> +</trkpt> +<trkpt lat="40.045067" lon="116.310722"><ele>51.51</ele> +<time>2024-11-11T11:44:17Z</time> +</trkpt> +<trkpt lat="40.045105" lon="116.310707"><ele>51.44</ele> +<time>2024-11-11T11:44:18Z</time> +</trkpt> +<trkpt lat="40.045147" lon="116.310684"><ele>51.44</ele> +<time>2024-11-11T11:44:19Z</time> +</trkpt> +<trkpt lat="40.045189" lon="116.310654"><ele>51.38</ele> +<time>2024-11-11T11:44:20Z</time> +</trkpt> +<trkpt lat="40.045231" lon="116.310623"><ele>51.44</ele> +<time>2024-11-11T11:44:21Z</time> +</trkpt> +<trkpt lat="40.045277" lon="116.310585"><ele>51.38</ele> +<time>2024-11-11T11:44:22Z</time> +</trkpt> +<trkpt lat="40.045322" lon="116.310555"><ele>51.28</ele> +<time>2024-11-11T11:44:23Z</time> +</trkpt> +<trkpt lat="40.045364" lon="116.310532"><ele>51.28</ele> +<time>2024-11-11T11:44:24Z</time> +</trkpt> +<trkpt lat="40.045406" lon="116.310493"><ele>51.69</ele> +<time>2024-11-11T11:44:25Z</time> +</trkpt> +<trkpt lat="40.045452" lon="116.310463"><ele>51.81</ele> +<time>2024-11-11T11:44:26Z</time> +</trkpt> +<trkpt lat="40.045498" lon="116.310432"><ele>51.81</ele> +<time>2024-11-11T11:44:27Z</time> +</trkpt> +<trkpt lat="40.045544" lon="116.310402"><ele>51.77</ele> +<time>2024-11-11T11:44:28Z</time> +</trkpt> +<trkpt lat="40.045586" lon="116.310371"><ele>51.81</ele> +<time>2024-11-11T11:44:29Z</time> +</trkpt> +<trkpt lat="40.045628" lon="116.310333"><ele>51.85</ele> +<time>2024-11-11T11:44:30Z</time> +</trkpt> +<trkpt lat="40.045673" lon="116.310295"><ele>51.85</ele> +<time>2024-11-11T11:44:31Z</time> +</trkpt> +<trkpt lat="40.045715" lon="116.310265"><ele>51.57</ele> +<time>2024-11-11T11:44:32Z</time> +</trkpt> +<trkpt lat="40.045757" lon="116.310242"><ele>51.57</ele> +<time>2024-11-11T11:44:33Z</time> +</trkpt> +<trkpt lat="40.045788" lon="116.310211"><ele>51.72</ele> +<time>2024-11-11T11:44:34Z</time> +</trkpt> +<trkpt lat="40.045822" lon="116.310188"><ele>51.78</ele> +<time>2024-11-11T11:44:35Z</time> +</trkpt> +<trkpt lat="40.045856" lon="116.310158"><ele>52.14</ele> +<time>2024-11-11T11:44:36Z</time> +</trkpt> +<trkpt lat="40.045879" lon="116.310143"><ele>52.14</ele> +<time>2024-11-11T11:44:37Z</time> +</trkpt> +<trkpt lat="40.045902" lon="116.310127"><ele>51.99</ele> +<time>2024-11-11T11:44:38Z</time> +</trkpt> +<trkpt lat="40.045937" lon="116.310104"><ele>51.87</ele> +<time>2024-11-11T11:44:39Z</time> +</trkpt> +<trkpt lat="40.045971" lon="116.310081"><ele>51.74</ele> +<time>2024-11-11T11:44:40Z</time> +</trkpt> +<trkpt lat="40.046009" lon="116.310043"><ele>51.63</ele> +<time>2024-11-11T11:44:41Z</time> +</trkpt> +<trkpt lat="40.046047" lon="116.310020"><ele>51.53</ele> +<time>2024-11-11T11:44:42Z</time> +</trkpt> +<trkpt lat="40.046085" lon="116.309998"><ele>51.36</ele> +<time>2024-11-11T11:44:43Z</time> +</trkpt> +<trkpt lat="40.046127" lon="116.309982"><ele>51.36</ele> +<time>2024-11-11T11:44:44Z</time> +</trkpt> +<trkpt lat="40.046162" lon="116.309975"><ele>51.25</ele> +<time>2024-11-11T11:44:45Z</time> +</trkpt> +<trkpt lat="40.046200" lon="116.309975"><ele>51.23</ele> +<time>2024-11-11T11:44:46Z</time> +</trkpt> +<trkpt lat="40.046242" lon="116.309952"><ele>51.32</ele> +<time>2024-11-11T11:44:47Z</time> +</trkpt> +<trkpt lat="40.046284" lon="116.309914"><ele>51.32</ele> +<time>2024-11-11T11:44:48Z</time> +</trkpt> +<trkpt lat="40.046326" lon="116.309891"><ele>51.32</ele> +<time>2024-11-11T11:44:49Z</time> +</trkpt> +<trkpt lat="40.046368" lon="116.309875"><ele>51.32</ele> +<time>2024-11-11T11:44:50Z</time> +</trkpt> +<trkpt lat="40.046410" lon="116.309837"><ele>51.19</ele> +<time>2024-11-11T11:44:51Z</time> +</trkpt> +<trkpt lat="40.046429" lon="116.309845"><ele>51.22</ele> +<time>2024-11-11T11:44:52Z</time> +</trkpt> +<trkpt lat="40.046444" lon="116.309845"><ele>51.23</ele> +<time>2024-11-11T11:44:53Z</time> +</trkpt> +<trkpt lat="40.046486" lon="116.309830"><ele>51.41</ele> +<time>2024-11-11T11:44:54Z</time> +</trkpt> +<trkpt lat="40.046513" lon="116.309822"><ele>51.43</ele> +<time>2024-11-11T11:44:55Z</time> +</trkpt> +<trkpt lat="40.046543" lon="116.309814"><ele>51.83</ele> +<time>2024-11-11T11:44:56Z</time> +</trkpt> +<trkpt lat="40.046566" lon="116.309784"><ele>51.83</ele> +<time>2024-11-11T11:44:57Z</time> +</trkpt> +<trkpt lat="40.046597" lon="116.309769"><ele>51.89</ele> +<time>2024-11-11T11:44:58Z</time> +</trkpt> +<trkpt lat="40.046627" lon="116.309746"><ele>51.97</ele> +<time>2024-11-11T11:44:59Z</time> +</trkpt> +<trkpt lat="40.046658" lon="116.309731"><ele>52.08</ele> +<time>2024-11-11T11:45:00Z</time> +</trkpt> +<trkpt lat="40.046684" lon="116.309700"><ele>52.08</ele> +<time>2024-11-11T11:45:01Z</time> +</trkpt> +<trkpt lat="40.046711" lon="116.309677"><ele>52.03</ele> +<time>2024-11-11T11:45:02Z</time> +</trkpt> +<trkpt lat="40.046734" lon="116.309647"><ele>51.96</ele> +<time>2024-11-11T11:45:03Z</time> +</trkpt> +<trkpt lat="40.046757" lon="116.309616"><ele>51.85</ele> +<time>2024-11-11T11:45:04Z</time> +</trkpt> +<trkpt lat="40.046776" lon="116.309570"><ele>51.83</ele> +<time>2024-11-11T11:45:05Z</time> +</trkpt> +<trkpt lat="40.046791" lon="116.309509"><ele>51.63</ele> +<time>2024-11-11T11:45:06Z</time> +</trkpt> +<trkpt lat="40.046803" lon="116.309456"><ele>51.57</ele> +<time>2024-11-11T11:45:07Z</time> +</trkpt> +<trkpt lat="40.046810" lon="116.309395"><ele>51.57</ele> +<time>2024-11-11T11:45:08Z</time> +</trkpt> +<trkpt lat="40.046822" lon="116.309334"><ele>51.57</ele> +<time>2024-11-11T11:45:09Z</time> +</trkpt> +<trkpt lat="40.046833" lon="116.309280"><ele>51.57</ele> +<time>2024-11-11T11:45:10Z</time> +</trkpt> +<trkpt lat="40.046829" lon="116.309227"><ele>51.46</ele> +<time>2024-11-11T11:45:11Z</time> +</trkpt> +<trkpt lat="40.046814" lon="116.309166"><ele>51.43</ele> +<time>2024-11-11T11:45:12Z</time> +</trkpt> +<trkpt lat="40.046799" lon="116.309090"><ele>51.35</ele> +<time>2024-11-11T11:45:13Z</time> +</trkpt> +<trkpt lat="40.046787" lon="116.309021"><ele>51.03</ele> +<time>2024-11-11T11:45:14Z</time> +</trkpt> +<trkpt lat="40.046768" lon="116.308952"><ele>50.91</ele> +<time>2024-11-11T11:45:15Z</time> +</trkpt> +<trkpt lat="40.046753" lon="116.308884"><ele>50.91</ele> +<time>2024-11-11T11:45:16Z</time> +</trkpt> +<trkpt lat="40.046738" lon="116.308815"><ele>51.10</ele> +<time>2024-11-11T11:45:17Z</time> +</trkpt> +<trkpt lat="40.046719" lon="116.308746"><ele>51.22</ele> +<time>2024-11-11T11:45:18Z</time> +</trkpt> +<trkpt lat="40.046703" lon="116.308670"><ele>51.17</ele> +<time>2024-11-11T11:45:19Z</time> +</trkpt> +<trkpt lat="40.046692" lon="116.308601"><ele>51.01</ele> +<time>2024-11-11T11:45:20Z</time> +</trkpt> +<trkpt lat="40.046673" lon="116.308533"><ele>51.01</ele> +<time>2024-11-11T11:45:21Z</time> +</trkpt> +<trkpt lat="40.046661" lon="116.308464"><ele>51.17</ele> +<time>2024-11-11T11:45:22Z</time> +</trkpt> +<trkpt lat="40.046646" lon="116.308395"><ele>51.17</ele> +<time>2024-11-11T11:45:23Z</time> +</trkpt> +<trkpt lat="40.046631" lon="116.308327"><ele>51.17</ele> +<time>2024-11-11T11:45:24Z</time> +</trkpt> +<trkpt lat="40.046619" lon="116.308258"><ele>51.17</ele> +<time>2024-11-11T11:45:25Z</time> +</trkpt> +<trkpt lat="40.046604" lon="116.308189"><ele>51.18</ele> +<time>2024-11-11T11:45:26Z</time> +</trkpt> +<trkpt lat="40.046589" lon="116.308113"><ele>51.26</ele> +<time>2024-11-11T11:45:27Z</time> +</trkpt> +<trkpt lat="40.046574" lon="116.308044"><ele>51.30</ele> +<time>2024-11-11T11:45:28Z</time> +</trkpt> +<trkpt lat="40.046558" lon="116.307976"><ele>51.27</ele> +<time>2024-11-11T11:45:29Z</time> +</trkpt> +<trkpt lat="40.046543" lon="116.307907"><ele>51.09</ele> +<time>2024-11-11T11:45:30Z</time> +</trkpt> +<trkpt lat="40.046524" lon="116.307838"><ele>51.09</ele> +<time>2024-11-11T11:45:31Z</time> +</trkpt> +<trkpt lat="40.046513" lon="116.307762"><ele>51.10</ele> +<time>2024-11-11T11:45:32Z</time> +</trkpt> +<trkpt lat="40.046501" lon="116.307693"><ele>51.25</ele> +<time>2024-11-11T11:45:33Z</time> +</trkpt> +<trkpt lat="40.046486" lon="116.307625"><ele>51.32</ele> +<time>2024-11-11T11:45:34Z</time> +</trkpt> +<trkpt lat="40.046467" lon="116.307564"><ele>51.36</ele> +<time>2024-11-11T11:45:35Z</time> +</trkpt> +<trkpt lat="40.046448" lon="116.307487"><ele>51.58</ele> +<time>2024-11-11T11:45:36Z</time> +</trkpt> +<trkpt lat="40.046440" lon="116.307426"><ele>51.64</ele> +<time>2024-11-11T11:45:37Z</time> +</trkpt> +<trkpt lat="40.046421" lon="116.307350"><ele>51.64</ele> +<time>2024-11-11T11:45:38Z</time> +</trkpt> +<trkpt lat="40.046406" lon="116.307281"><ele>51.64</ele> +<time>2024-11-11T11:45:39Z</time> +</trkpt> +<trkpt lat="40.046391" lon="116.307213"><ele>51.27</ele> +<time>2024-11-11T11:45:40Z</time> +</trkpt> +<trkpt lat="40.046379" lon="116.307144"><ele>51.22</ele> +<time>2024-11-11T11:45:41Z</time> +</trkpt> +<trkpt lat="40.046368" lon="116.307076"><ele>51.22</ele> +<time>2024-11-11T11:45:42Z</time> +</trkpt> +<trkpt lat="40.046364" lon="116.307014"><ele>51.21</ele> +<time>2024-11-11T11:45:43Z</time> +</trkpt> +<trkpt lat="40.046352" lon="116.306946"><ele>51.02</ele> +<time>2024-11-11T11:45:44Z</time> +</trkpt> +<trkpt lat="40.046337" lon="116.306877"><ele>50.95</ele> +<time>2024-11-11T11:45:45Z</time> +</trkpt> +<trkpt lat="40.046318" lon="116.306808"><ele>50.79</ele> +<time>2024-11-11T11:45:46Z</time> +</trkpt> +<trkpt lat="40.046303" lon="116.306740"><ele>50.79</ele> +<time>2024-11-11T11:45:47Z</time> +</trkpt> +<trkpt lat="40.046284" lon="116.306671"><ele>50.96</ele> +<time>2024-11-11T11:45:48Z</time> +</trkpt> +<trkpt lat="40.046268" lon="116.306602"><ele>50.96</ele> +<time>2024-11-11T11:45:49Z</time> +</trkpt> +<trkpt lat="40.046253" lon="116.306526"><ele>51.07</ele> +<time>2024-11-11T11:45:50Z</time> +</trkpt> +<trkpt lat="40.046234" lon="116.306458"><ele>51.13</ele> +<time>2024-11-11T11:45:51Z</time> +</trkpt> +<trkpt lat="40.046211" lon="116.306389"><ele>51.13</ele> +<time>2024-11-11T11:45:52Z</time> +</trkpt> +<trkpt lat="40.046196" lon="116.306320"><ele>51.04</ele> +<time>2024-11-11T11:45:53Z</time> +</trkpt> +<trkpt lat="40.046177" lon="116.306244"><ele>50.98</ele> +<time>2024-11-11T11:45:54Z</time> +</trkpt> +<trkpt lat="40.046158" lon="116.306175"><ele>51.02</ele> +<time>2024-11-11T11:45:55Z</time> +</trkpt> +<trkpt lat="40.046143" lon="116.306099"><ele>50.93</ele> +<time>2024-11-11T11:45:56Z</time> +</trkpt> +<trkpt lat="40.046124" lon="116.306030"><ele>50.93</ele> +<time>2024-11-11T11:45:57Z</time> +</trkpt> +<trkpt lat="40.046104" lon="116.305962"><ele>50.85</ele> +<time>2024-11-11T11:45:58Z</time> +</trkpt> +<trkpt lat="40.046089" lon="116.305893"><ele>50.85</ele> +<time>2024-11-11T11:45:59Z</time> +</trkpt> +<trkpt lat="40.046070" lon="116.305832"><ele>50.66</ele> +<time>2024-11-11T11:46:00Z</time> +</trkpt> +<trkpt lat="40.046040" lon="116.305771"><ele>50.66</ele> +<time>2024-11-11T11:46:01Z</time> +</trkpt> +<trkpt lat="40.046001" lon="116.305725"><ele>50.73</ele> +<time>2024-11-11T11:46:02Z</time> +</trkpt> +<trkpt lat="40.045959" lon="116.305687"><ele>50.82</ele> +<time>2024-11-11T11:46:03Z</time> +</trkpt> +<trkpt lat="40.045910" lon="116.305664"><ele>50.92</ele> +<time>2024-11-11T11:46:04Z</time> +</trkpt> +<trkpt lat="40.045860" lon="116.305649"><ele>51.05</ele> +<time>2024-11-11T11:46:05Z</time> +</trkpt> +<trkpt lat="40.045811" lon="116.305656"><ele>51.05</ele> +<time>2024-11-11T11:46:06Z</time> +</trkpt> +<trkpt lat="40.045765" lon="116.305672"><ele>51.10</ele> +<time>2024-11-11T11:46:07Z</time> +</trkpt> +<trkpt lat="40.045723" lon="116.305695"><ele>51.41</ele> +<time>2024-11-11T11:46:08Z</time> +</trkpt> +<trkpt lat="40.045677" lon="116.305717"><ele>51.44</ele> +<time>2024-11-11T11:46:09Z</time> +</trkpt> +<trkpt lat="40.045628" lon="116.305748"><ele>51.55</ele> +<time>2024-11-11T11:46:10Z</time> +</trkpt> +<trkpt lat="40.045586" lon="116.305771"><ele>51.55</ele> +<time>2024-11-11T11:46:11Z</time> +</trkpt> +<trkpt lat="40.045540" lon="116.305801"><ele>51.57</ele> +<time>2024-11-11T11:46:12Z</time> +</trkpt> +<trkpt lat="40.045498" lon="116.305832"><ele>51.61</ele> +<time>2024-11-11T11:46:13Z</time> +</trkpt> +<trkpt lat="40.045452" lon="116.305862"><ele>51.82</ele> +<time>2024-11-11T11:46:14Z</time> +</trkpt> +<trkpt lat="40.045406" lon="116.305901"><ele>51.85</ele> +<time>2024-11-11T11:46:15Z</time> +</trkpt> +<trkpt lat="40.045361" lon="116.305931"><ele>51.85</ele> +<time>2024-11-11T11:46:16Z</time> +</trkpt> +<trkpt lat="40.045315" lon="116.305962"><ele>51.99</ele> +<time>2024-11-11T11:46:17Z</time> +</trkpt> +<trkpt lat="40.045269" lon="116.305992"><ele>52.08</ele> +<time>2024-11-11T11:46:18Z</time> +</trkpt> +<trkpt lat="40.045219" lon="116.306023"><ele>52.09</ele> +<time>2024-11-11T11:46:19Z</time> +</trkpt> +<trkpt lat="40.045174" lon="116.306053"><ele>52.08</ele> +<time>2024-11-11T11:46:20Z</time> +</trkpt> +<trkpt lat="40.045124" lon="116.306084"><ele>52.08</ele> +<time>2024-11-11T11:46:21Z</time> +</trkpt> +<trkpt lat="40.045074" lon="116.306114"><ele>52.00</ele> +<time>2024-11-11T11:46:22Z</time> +</trkpt> +<trkpt lat="40.045025" lon="116.306152"><ele>52.00</ele> +<time>2024-11-11T11:46:23Z</time> +</trkpt> +<trkpt lat="40.044975" lon="116.306183"><ele>52.09</ele> +<time>2024-11-11T11:46:24Z</time> +</trkpt> +<trkpt lat="40.044930" lon="116.306221"><ele>52.10</ele> +<time>2024-11-11T11:46:25Z</time> +</trkpt> +<trkpt lat="40.044880" lon="116.306259"><ele>52.09</ele> +<time>2024-11-11T11:46:26Z</time> +</trkpt> +<trkpt lat="40.044830" lon="116.306290"><ele>52.00</ele> +<time>2024-11-11T11:46:27Z</time> +</trkpt> +<trkpt lat="40.044785" lon="116.306328"><ele>51.97</ele> +<time>2024-11-11T11:46:28Z</time> +</trkpt> +<trkpt lat="40.044739" lon="116.306366"><ele>52.00</ele> +<time>2024-11-11T11:46:29Z</time> +</trkpt> +<trkpt lat="40.044689" lon="116.306412"><ele>52.12</ele> +<time>2024-11-11T11:46:30Z</time> +</trkpt> +<trkpt lat="40.044643" lon="116.306450"><ele>52.12</ele> +<time>2024-11-11T11:46:31Z</time> +</trkpt> +<trkpt lat="40.044594" lon="116.306488"><ele>52.24</ele> +<time>2024-11-11T11:46:32Z</time> +</trkpt> +<trkpt lat="40.044548" lon="116.306534"><ele>52.42</ele> +<time>2024-11-11T11:46:33Z</time> +</trkpt> +<trkpt lat="40.044498" lon="116.306564"><ele>52.42</ele> +<time>2024-11-11T11:46:34Z</time> +</trkpt> +<trkpt lat="40.044449" lon="116.306602"><ele>52.25</ele> +<time>2024-11-11T11:46:35Z</time> +</trkpt> +<trkpt lat="40.044399" lon="116.306641"><ele>52.24</ele> +<time>2024-11-11T11:46:36Z</time> +</trkpt> +<trkpt lat="40.044350" lon="116.306679"><ele>52.24</ele> +<time>2024-11-11T11:46:37Z</time> +</trkpt> +<trkpt lat="40.044300" lon="116.306709"><ele>52.24</ele> +<time>2024-11-11T11:46:38Z</time> +</trkpt> +<trkpt lat="40.044254" lon="116.306747"><ele>52.18</ele> +<time>2024-11-11T11:46:39Z</time> +</trkpt> +<trkpt lat="40.044205" lon="116.306786"><ele>52.18</ele> +<time>2024-11-11T11:46:40Z</time> +</trkpt> +<trkpt lat="40.044155" lon="116.306824"><ele>52.14</ele> +<time>2024-11-11T11:46:41Z</time> +</trkpt> +<trkpt lat="40.044106" lon="116.306854"><ele>52.14</ele> +<time>2024-11-11T11:46:42Z</time> +</trkpt> +<trkpt lat="40.044056" lon="116.306892"><ele>52.11</ele> +<time>2024-11-11T11:46:43Z</time> +</trkpt> +<trkpt lat="40.044006" lon="116.306931"><ele>52.34</ele> +<time>2024-11-11T11:46:44Z</time> +</trkpt> +<trkpt lat="40.043957" lon="116.306969"><ele>52.34</ele> +<time>2024-11-11T11:46:45Z</time> +</trkpt> +<trkpt lat="40.043907" lon="116.307007"><ele>52.44</ele> +<time>2024-11-11T11:46:46Z</time> +</trkpt> +<trkpt lat="40.043858" lon="116.307037"><ele>52.44</ele> +<time>2024-11-11T11:46:47Z</time> +</trkpt> +<trkpt lat="40.043804" lon="116.307068"><ele>52.15</ele> +<time>2024-11-11T11:46:48Z</time> +</trkpt> +<trkpt lat="40.043755" lon="116.307098"><ele>52.10</ele> +<time>2024-11-11T11:46:49Z</time> +</trkpt> +<trkpt lat="40.043701" lon="116.307129"><ele>52.12</ele> +<time>2024-11-11T11:46:50Z</time> +</trkpt> +<trkpt lat="40.043652" lon="116.307159"><ele>52.12</ele> +<time>2024-11-11T11:46:51Z</time> +</trkpt> +<trkpt lat="40.043598" lon="116.307190"><ele>52.11</ele> +<time>2024-11-11T11:46:52Z</time> +</trkpt> +<trkpt lat="40.043552" lon="116.307228"><ele>51.97</ele> +<time>2024-11-11T11:46:53Z</time> +</trkpt> +<trkpt lat="40.043503" lon="116.307259"><ele>51.97</ele> +<time>2024-11-11T11:46:54Z</time> +</trkpt> +<trkpt lat="40.043453" lon="116.307297"><ele>51.92</ele> +<time>2024-11-11T11:46:55Z</time> +</trkpt> +<trkpt lat="40.043404" lon="116.307343"><ele>52.24</ele> +<time>2024-11-11T11:46:56Z</time> +</trkpt> +<trkpt lat="40.043350" lon="116.307381"><ele>52.29</ele> +<time>2024-11-11T11:46:57Z</time> +</trkpt> +<trkpt lat="40.043304" lon="116.307411"><ele>52.47</ele> +<time>2024-11-11T11:46:58Z</time> +</trkpt> +<trkpt lat="40.043259" lon="116.307457"><ele>52.47</ele> +<time>2024-11-11T11:46:59Z</time> +</trkpt> +<trkpt lat="40.043217" lon="116.307495"><ele>52.45</ele> +<time>2024-11-11T11:47:00Z</time> +</trkpt> +<trkpt lat="40.043171" lon="116.307541"><ele>52.45</ele> +<time>2024-11-11T11:47:01Z</time> +</trkpt> +<trkpt lat="40.043133" lon="116.307587"><ele>52.42</ele> +<time>2024-11-11T11:47:02Z</time> +</trkpt> +<trkpt lat="40.043095" lon="116.307625"><ele>52.57</ele> +<time>2024-11-11T11:47:03Z</time> +</trkpt> +<trkpt lat="40.043060" lon="116.307671"><ele>52.47</ele> +<time>2024-11-11T11:47:04Z</time> +</trkpt> +<trkpt lat="40.043026" lon="116.307716"><ele>52.61</ele> +<time>2024-11-11T11:47:05Z</time> +</trkpt> +<trkpt lat="40.042999" lon="116.307770"><ele>52.61</ele> +<time>2024-11-11T11:47:06Z</time> +</trkpt> +<trkpt lat="40.042984" lon="116.307816"><ele>52.78</ele> +<time>2024-11-11T11:47:07Z</time> +</trkpt> +<trkpt lat="40.042969" lon="116.307884"><ele>52.89</ele> +<time>2024-11-11T11:47:08Z</time> +</trkpt> +<trkpt lat="40.042961" lon="116.307953"><ele>52.89</ele> +<time>2024-11-11T11:47:09Z</time> +</trkpt> +<trkpt lat="40.042957" lon="116.308022"><ele>52.78</ele> +<time>2024-11-11T11:47:10Z</time> +</trkpt> +<trkpt lat="40.042957" lon="116.308090"><ele>52.55</ele> +<time>2024-11-11T11:47:11Z</time> +</trkpt> +<trkpt lat="40.042961" lon="116.308151"><ele>52.51</ele> +<time>2024-11-11T11:47:12Z</time> +</trkpt> +<trkpt lat="40.042969" lon="116.308189"><ele>52.00</ele> +<time>2024-11-11T11:47:13Z</time> +</trkpt> +<trkpt lat="40.042992" lon="116.308243"><ele>51.93</ele> +<time>2024-11-11T11:47:14Z</time> +</trkpt> +<trkpt lat="40.043022" lon="116.308304"><ele>51.91</ele> +<time>2024-11-11T11:47:15Z</time> +</trkpt> +<trkpt lat="40.043049" lon="116.308365"><ele>51.66</ele> +<time>2024-11-11T11:47:16Z</time> +</trkpt> +<trkpt lat="40.043083" lon="116.308418"><ele>51.47</ele> +<time>2024-11-11T11:47:17Z</time> +</trkpt> +<trkpt lat="40.043114" lon="116.308479"><ele>51.36</ele> +<time>2024-11-11T11:47:18Z</time> +</trkpt> +<trkpt lat="40.043140" lon="116.308533"><ele>51.27</ele> +<time>2024-11-11T11:47:19Z</time> +</trkpt> +<trkpt lat="40.043171" lon="116.308586"><ele>51.27</ele> +<time>2024-11-11T11:47:20Z</time> +</trkpt> +<trkpt lat="40.043198" lon="116.308632"><ele>51.23</ele> +<time>2024-11-11T11:47:21Z</time> +</trkpt> +<trkpt lat="40.043232" lon="116.308685"><ele>51.23</ele> +<time>2024-11-11T11:47:22Z</time> +</trkpt> +<trkpt lat="40.043270" lon="116.308739"><ele>51.10</ele> +<time>2024-11-11T11:47:23Z</time> +</trkpt> +<trkpt lat="40.043304" lon="116.308784"><ele>51.04</ele> +<time>2024-11-11T11:47:24Z</time> +</trkpt> +<trkpt lat="40.043339" lon="116.308838"><ele>50.93</ele> +<time>2024-11-11T11:47:25Z</time> +</trkpt> +<trkpt lat="40.043377" lon="116.308884"><ele>50.93</ele> +<time>2024-11-11T11:47:26Z</time> +</trkpt> +<trkpt lat="40.043411" lon="116.308937"><ele>50.84</ele> +<time>2024-11-11T11:47:27Z</time> +</trkpt> +<trkpt lat="40.043449" lon="116.308990"><ele>50.74</ele> +<time>2024-11-11T11:47:28Z</time> +</trkpt> +<trkpt lat="40.043484" lon="116.309044"><ele>50.84</ele> +<time>2024-11-11T11:47:29Z</time> +</trkpt> +<trkpt lat="40.043518" lon="116.309097"><ele>50.86</ele> +<time>2024-11-11T11:47:30Z</time> +</trkpt> +<trkpt lat="40.043556" lon="116.309151"><ele>50.86</ele> +<time>2024-11-11T11:47:31Z</time> +</trkpt> +<trkpt lat="40.043591" lon="116.309204"><ele>50.87</ele> +<time>2024-11-11T11:47:32Z</time> +</trkpt> +<trkpt lat="40.043625" lon="116.309265"><ele>50.86</ele> +<time>2024-11-11T11:47:33Z</time> +</trkpt> +<trkpt lat="40.043659" lon="116.309319"><ele>50.76</ele> +<time>2024-11-11T11:47:34Z</time> +</trkpt> +<trkpt lat="40.043697" lon="116.309372"><ele>50.73</ele> +<time>2024-11-11T11:47:35Z</time> +</trkpt> +<trkpt lat="40.043736" lon="116.309425"><ele>50.73</ele> +<time>2024-11-11T11:47:36Z</time> +</trkpt> +<trkpt lat="40.043774" lon="116.309479"><ele>51.07</ele> +<time>2024-11-11T11:47:37Z</time> +</trkpt> +<trkpt lat="40.043808" lon="116.309532"><ele>51.19</ele> +<time>2024-11-11T11:47:38Z</time> +</trkpt> +<trkpt lat="40.043842" lon="116.309586"><ele>51.38</ele> +<time>2024-11-11T11:47:39Z</time> +</trkpt> +<trkpt lat="40.043877" lon="116.309639"><ele>51.48</ele> +<time>2024-11-11T11:47:40Z</time> +</trkpt> +<trkpt lat="40.043915" lon="116.309700"><ele>51.51</ele> +<time>2024-11-11T11:47:41Z</time> +</trkpt> +<trkpt lat="40.043949" lon="116.309753"><ele>51.67</ele> +<time>2024-11-11T11:47:42Z</time> +</trkpt> +<trkpt lat="40.043987" lon="116.309807"><ele>51.67</ele> +<time>2024-11-11T11:47:43Z</time> +</trkpt> +<trkpt lat="40.044022" lon="116.309860"><ele>51.70</ele> +<time>2024-11-11T11:47:44Z</time> +</trkpt> +<trkpt lat="40.044060" lon="116.309921"><ele>51.89</ele> +<time>2024-11-11T11:47:45Z</time> +</trkpt> +<trkpt lat="40.044098" lon="116.309982"><ele>52.13</ele> +<time>2024-11-11T11:47:46Z</time> +</trkpt> +<trkpt lat="40.044132" lon="116.310036"><ele>51.97</ele> +<time>2024-11-11T11:47:47Z</time> +</trkpt> +<trkpt lat="40.044167" lon="116.310089"><ele>51.97</ele> +<time>2024-11-11T11:47:48Z</time> +</trkpt> +<trkpt lat="40.044205" lon="116.310150"><ele>52.14</ele> +<time>2024-11-11T11:47:49Z</time> +</trkpt> +<trkpt lat="40.044239" lon="116.310204"><ele>51.96</ele> +<time>2024-11-11T11:47:50Z</time> +</trkpt> +<trkpt lat="40.044273" lon="116.310257"><ele>51.96</ele> +<time>2024-11-11T11:47:51Z</time> +</trkpt> +<trkpt lat="40.044308" lon="116.310310"><ele>51.96</ele> +<time>2024-11-11T11:47:52Z</time> +</trkpt> +<trkpt lat="40.044342" lon="116.310371"><ele>51.94</ele> +<time>2024-11-11T11:47:53Z</time> +</trkpt> +<trkpt lat="40.044376" lon="116.310425"><ele>51.98</ele> +<time>2024-11-11T11:47:54Z</time> +</trkpt> +<trkpt lat="40.044407" lon="116.310478"><ele>52.00</ele> +<time>2024-11-11T11:47:55Z</time> +</trkpt> +<trkpt lat="40.044441" lon="116.310539"><ele>52.02</ele> +<time>2024-11-11T11:47:56Z</time> +</trkpt> +<trkpt lat="40.044479" lon="116.310600"><ele>52.02</ele> +<time>2024-11-11T11:47:57Z</time> +</trkpt> +<trkpt lat="40.044510" lon="116.310654"><ele>51.96</ele> +<time>2024-11-11T11:47:58Z</time> +</trkpt> +<trkpt lat="40.044540" lon="116.310715"><ele>51.89</ele> +<time>2024-11-11T11:47:59Z</time> +</trkpt> +<trkpt lat="40.044567" lon="116.310776"><ele>51.85</ele> +<time>2024-11-11T11:48:00Z</time> +</trkpt> +<trkpt lat="40.044598" lon="116.310837"><ele>51.85</ele> +<time>2024-11-11T11:48:01Z</time> +</trkpt> +<trkpt lat="40.044628" lon="116.310898"><ele>51.72</ele> +<time>2024-11-11T11:48:02Z</time> +</trkpt> +<trkpt lat="40.044655" lon="116.310959"><ele>51.63</ele> +<time>2024-11-11T11:48:03Z</time> +</trkpt> +<trkpt lat="40.044682" lon="116.311020"><ele>51.63</ele> +<time>2024-11-11T11:48:04Z</time> +</trkpt> +<trkpt lat="40.044712" lon="116.311073"><ele>51.63</ele> +<time>2024-11-11T11:48:05Z</time> +</trkpt> +<trkpt lat="40.044746" lon="116.311134"><ele>51.16</ele> +<time>2024-11-11T11:48:06Z</time> +</trkpt> +<trkpt lat="40.044781" lon="116.311188"><ele>51.16</ele> +<time>2024-11-11T11:48:07Z</time> +</trkpt> +<trkpt lat="40.044811" lon="116.311241"><ele>51.33</ele> +<time>2024-11-11T11:48:08Z</time> +</trkpt> +<trkpt lat="40.044853" lon="116.311302"><ele>51.37</ele> +<time>2024-11-11T11:48:09Z</time> +</trkpt> +<trkpt lat="40.044888" lon="116.311356"><ele>51.37</ele> +<time>2024-11-11T11:48:10Z</time> +</trkpt> +<trkpt lat="40.044926" lon="116.311424"><ele>51.42</ele> +<time>2024-11-11T11:48:11Z</time> +</trkpt> +<trkpt lat="40.044960" lon="116.311478"><ele>51.59</ele> +<time>2024-11-11T11:48:12Z</time> +</trkpt> +<trkpt lat="40.044998" lon="116.311539"><ele>51.66</ele> +<time>2024-11-11T11:48:13Z</time> +</trkpt> +<trkpt lat="40.045033" lon="116.311592"><ele>51.74</ele> +<time>2024-11-11T11:48:14Z</time> +</trkpt> +<trkpt lat="40.045063" lon="116.311638"><ele>51.74</ele> +<time>2024-11-11T11:48:15Z</time> +</trkpt> +<trkpt lat="40.045101" lon="116.311691"><ele>51.72</ele> +<time>2024-11-11T11:48:16Z</time> +</trkpt> +<trkpt lat="40.045135" lon="116.311745"><ele>51.72</ele> +<time>2024-11-11T11:48:17Z</time> +</trkpt> +<trkpt lat="40.045166" lon="116.311798"><ele>51.83</ele> +<time>2024-11-11T11:48:18Z</time> +</trkpt> +<trkpt lat="40.045204" lon="116.311852"><ele>51.87</ele> +<time>2024-11-11T11:48:19Z</time> +</trkpt> +<trkpt lat="40.045246" lon="116.311913"><ele>51.83</ele> +<time>2024-11-11T11:48:20Z</time> +</trkpt> +<trkpt lat="40.045284" lon="116.311966"><ele>51.75</ele> +<time>2024-11-11T11:48:21Z</time> +</trkpt> +<trkpt lat="40.045326" lon="116.312035"><ele>51.57</ele> +<time>2024-11-11T11:48:22Z</time> +</trkpt> +<trkpt lat="40.045361" lon="116.312088"><ele>51.51</ele> +<time>2024-11-11T11:48:23Z</time> +</trkpt> +<trkpt lat="40.045391" lon="116.312141"><ele>51.57</ele> +<time>2024-11-11T11:48:24Z</time> +</trkpt> +<trkpt lat="40.045425" lon="116.312195"><ele>51.53</ele> +<time>2024-11-11T11:48:25Z</time> +</trkpt> +<trkpt lat="40.045456" lon="116.312241"><ele>51.79</ele> +<time>2024-11-11T11:48:26Z</time> +</trkpt> +<trkpt lat="40.045490" lon="116.312286"><ele>51.79</ele> +<time>2024-11-11T11:48:27Z</time> +</trkpt> +<trkpt lat="40.045525" lon="116.312332"><ele>51.84</ele> +<time>2024-11-11T11:48:28Z</time> +</trkpt> +<trkpt lat="40.045559" lon="116.312378"><ele>52.17</ele> +<time>2024-11-11T11:48:29Z</time> +</trkpt> +<trkpt lat="40.045601" lon="116.312431"><ele>52.29</ele> +<time>2024-11-11T11:48:30Z</time> +</trkpt> +<trkpt lat="40.045639" lon="116.312477"><ele>52.29</ele> +<time>2024-11-11T11:48:31Z</time> +</trkpt> +<trkpt lat="40.045670" lon="116.312515"><ele>52.30</ele> +<time>2024-11-11T11:48:32Z</time> +</trkpt> +<trkpt lat="40.045700" lon="116.312561"><ele>52.44</ele> +<time>2024-11-11T11:48:33Z</time> +</trkpt> +<trkpt lat="40.045734" lon="116.312607"><ele>52.30</ele> +<time>2024-11-11T11:48:34Z</time> +</trkpt> +<trkpt lat="40.045769" lon="116.312653"><ele>52.44</ele> +<time>2024-11-11T11:48:35Z</time> +</trkpt> +<trkpt lat="40.045795" lon="116.312698"><ele>52.71</ele> +<time>2024-11-11T11:48:36Z</time> +</trkpt> +<trkpt lat="40.045826" lon="116.312737"><ele>52.68</ele> +<time>2024-11-11T11:48:37Z</time> +</trkpt> +<trkpt lat="40.045856" lon="116.312782"><ele>52.69</ele> +<time>2024-11-11T11:48:38Z</time> +</trkpt> +<trkpt lat="40.045872" lon="116.312790"><ele>52.69</ele> +<time>2024-11-11T11:48:39Z</time> +</trkpt> +<trkpt lat="40.045918" lon="116.312843"><ele>52.86</ele> +<time>2024-11-11T11:48:40Z</time> +</trkpt> +<trkpt lat="40.045956" lon="116.312889"><ele>52.92</ele> +<time>2024-11-11T11:48:41Z</time> +</trkpt> +<trkpt lat="40.045994" lon="116.312920"><ele>52.86</ele> +<time>2024-11-11T11:48:42Z</time> +</trkpt> +<trkpt lat="40.046028" lon="116.312958"><ele>52.84</ele> +<time>2024-11-11T11:48:43Z</time> +</trkpt> +<trkpt lat="40.046055" lon="116.313004"><ele>52.83</ele> +<time>2024-11-11T11:48:44Z</time> +</trkpt> +<trkpt lat="40.046074" lon="116.313049"><ele>52.91</ele> +<time>2024-11-11T11:48:45Z</time> +</trkpt> +<trkpt lat="40.046085" lon="116.313072"><ele>52.99</ele> +<time>2024-11-11T11:48:46Z</time> +</trkpt> +<trkpt lat="40.046104" lon="116.313087"><ele>53.02</ele> +<time>2024-11-11T11:48:47Z</time> +</trkpt> +<trkpt lat="40.046127" lon="116.313118"><ele>53.02</ele> +<time>2024-11-11T11:48:48Z</time> +</trkpt> +<trkpt lat="40.046139" lon="116.313133"><ele>52.93</ele> +<time>2024-11-11T11:48:49Z</time> +</trkpt> +<trkpt lat="40.046146" lon="116.313156"><ele>52.93</ele> +<time>2024-11-11T11:48:50Z</time> +</trkpt> +<trkpt lat="40.046154" lon="116.313171"><ele>52.93</ele> +<time>2024-11-11T11:48:51Z</time> +</trkpt> +<trkpt lat="40.046162" lon="116.313194"><ele>52.95</ele> +<time>2024-11-11T11:48:52Z</time> +</trkpt> +<trkpt lat="40.046165" lon="116.313202"><ele>53.06</ele> +<time>2024-11-11T11:48:53Z</time> +</trkpt> +<trkpt lat="40.046165" lon="116.313202"><ele>53.06</ele> +<time>2024-11-11T11:48:54Z</time> +</trkpt> +<trkpt lat="40.046169" lon="116.313202"><ele>53.07</ele> +<time>2024-11-11T11:48:55Z</time> +</trkpt> +<trkpt lat="40.046169" lon="116.313202"><ele>53.01</ele> +<time>2024-11-11T11:48:56Z</time> +</trkpt> +<trkpt lat="40.046173" lon="116.313210"><ele>53.09</ele> +<time>2024-11-11T11:48:57Z</time> +</trkpt> +<trkpt lat="40.046173" lon="116.313210"><ele>53.09</ele> +<time>2024-11-11T11:48:58Z</time> +</trkpt> +<trkpt lat="40.046173" lon="116.313210"><ele>53.17</ele> +<time>2024-11-11T11:48:59Z</time> +</trkpt> +<trkpt lat="40.046177" lon="116.313217"><ele>53.18</ele> +<time>2024-11-11T11:49:00Z</time> +</trkpt> +<trkpt lat="40.046177" lon="116.313217"><ele>53.18</ele> +<time>2024-11-11T11:49:01Z</time> +</trkpt> +<trkpt lat="40.046181" lon="116.313225"><ele>53.17</ele> +<time>2024-11-11T11:49:02Z</time> +</trkpt> +<trkpt lat="40.046181" lon="116.313225"><ele>53.17</ele> +<time>2024-11-11T11:49:03Z</time> +</trkpt> +<trkpt lat="40.046185" lon="116.313232"><ele>53.18</ele> +<time>2024-11-11T11:49:04Z</time> +</trkpt> +<trkpt lat="40.046185" lon="116.313232"><ele>53.16</ele> +<time>2024-11-11T11:49:05Z</time> +</trkpt> +<trkpt lat="40.046185" lon="116.313232"><ele>53.18</ele> +<time>2024-11-11T11:49:06Z</time> +</trkpt> +<trkpt lat="40.046188" lon="116.313240"><ele>53.23</ele> +<time>2024-11-11T11:49:07Z</time> +</trkpt> +<trkpt lat="40.046188" lon="116.313240"><ele>53.23</ele> +<time>2024-11-11T11:49:08Z</time> +</trkpt> +<trkpt lat="40.046188" lon="116.313240"><ele>53.10</ele> +<time>2024-11-11T11:49:09Z</time> +</trkpt> +<trkpt lat="40.046188" lon="116.313240"><ele>53.10</ele> +<time>2024-11-11T11:49:10Z</time> +</trkpt> +<trkpt lat="40.046188" lon="116.313240"><ele>52.91</ele> +<time>2024-11-11T11:49:11Z</time> +</trkpt> +<trkpt lat="40.046192" lon="116.313248"><ele>52.88</ele> +<time>2024-11-11T11:49:12Z</time> +</trkpt> +<trkpt lat="40.046192" lon="116.313248"><ele>52.88</ele> +<time>2024-11-11T11:49:13Z</time> +</trkpt> +<trkpt lat="40.046196" lon="116.313248"><ele>52.88</ele> +<time>2024-11-11T11:49:14Z</time> +</trkpt> +<trkpt lat="40.046200" lon="116.313248"><ele>52.88</ele> +<time>2024-11-11T11:49:15Z</time> +</trkpt> +<trkpt lat="40.046200" lon="116.313255"><ele>52.90</ele> +<time>2024-11-11T11:49:16Z</time> +</trkpt> +<trkpt lat="40.046200" lon="116.313255"><ele>52.90</ele> +<time>2024-11-11T11:49:17Z</time> +</trkpt> +<trkpt lat="40.046200" lon="116.313255"><ele>52.77</ele> +<time>2024-11-11T11:49:18Z</time> +</trkpt> +<trkpt lat="40.046200" lon="116.313255"><ele>52.90</ele> +<time>2024-11-11T11:49:19Z</time> +</trkpt> +<trkpt lat="40.046204" lon="116.313255"><ele>52.83</ele> +<time>2024-11-11T11:49:20Z</time> +</trkpt> +<trkpt lat="40.046211" lon="116.313263"><ele>52.90</ele> +<time>2024-11-11T11:49:21Z</time> +</trkpt> +<trkpt lat="40.046219" lon="116.313286"><ele>52.90</ele> +<time>2024-11-11T11:49:22Z</time> +</trkpt> +<trkpt lat="40.046234" lon="116.313324"><ele>52.85</ele> +<time>2024-11-11T11:49:23Z</time> +</trkpt> +<trkpt lat="40.046249" lon="116.313354"><ele>52.85</ele> +<time>2024-11-11T11:49:24Z</time> +</trkpt> +<trkpt lat="40.046268" lon="116.313393"><ele>52.67</ele> +<time>2024-11-11T11:49:25Z</time> +</trkpt> +<trkpt lat="40.046288" lon="116.313431"><ele>52.61</ele> +<time>2024-11-11T11:49:26Z</time> +</trkpt> +<trkpt lat="40.046303" lon="116.313469"><ele>52.60</ele> +<time>2024-11-11T11:49:27Z</time> +</trkpt> +<trkpt lat="40.046318" lon="116.313507"><ele>52.59</ele> +<time>2024-11-11T11:49:28Z</time> +</trkpt> +<trkpt lat="40.046337" lon="116.313530"><ele>52.59</ele> +<time>2024-11-11T11:49:29Z</time> +</trkpt> +<trkpt lat="40.046352" lon="116.313545"><ele>52.59</ele> +<time>2024-11-11T11:49:30Z</time> +</trkpt> +<trkpt lat="40.046356" lon="116.313545"><ele>52.48</ele> +<time>2024-11-11T11:49:31Z</time> +</trkpt> +<trkpt lat="40.046360" lon="116.313545"><ele>52.48</ele> +<time>2024-11-11T11:49:32Z</time> +</trkpt> +<trkpt lat="40.046360" lon="116.313545"><ele>52.64</ele> +<time>2024-11-11T11:49:33Z</time> +</trkpt> +<trkpt lat="40.046364" lon="116.313545"><ele>52.74</ele> +<time>2024-11-11T11:49:34Z</time> +</trkpt> +<trkpt lat="40.046368" lon="116.313545"><ele>52.73</ele> +<time>2024-11-11T11:49:35Z</time> +</trkpt> +<trkpt lat="40.046368" lon="116.313545"><ele>52.73</ele> +<time>2024-11-11T11:49:36Z</time> +</trkpt> +<trkpt lat="40.046371" lon="116.313553"><ele>52.73</ele> +<time>2024-11-11T11:49:37Z</time> +</trkpt> +<trkpt lat="40.046371" lon="116.313553"><ele>52.73</ele> +<time>2024-11-11T11:49:38Z</time> +</trkpt> +<trkpt lat="40.046375" lon="116.313553"><ele>52.71</ele> +<time>2024-11-11T11:49:39Z</time> +</trkpt> +<trkpt lat="40.046379" lon="116.313553"><ele>52.69</ele> +<time>2024-11-11T11:49:40Z</time> +</trkpt> +<trkpt lat="40.046383" lon="116.313553"><ele>52.69</ele> +<time>2024-11-11T11:49:41Z</time> +</trkpt> +<trkpt lat="40.046387" lon="116.313553"><ele>52.68</ele> +<time>2024-11-11T11:49:42Z</time> +</trkpt> +<trkpt lat="40.046387" lon="116.313553"><ele>52.75</ele> +<time>2024-11-11T11:49:43Z</time> +</trkpt> +<trkpt lat="40.046391" lon="116.313553"><ele>52.81</ele> +<time>2024-11-11T11:49:44Z</time> +</trkpt> +<trkpt lat="40.046394" lon="116.313553"><ele>52.81</ele> +<time>2024-11-11T11:49:45Z</time> +</trkpt> +<trkpt lat="40.046398" lon="116.313553"><ele>52.81</ele> +<time>2024-11-11T11:49:46Z</time> +</trkpt> +<trkpt lat="40.046402" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:49:47Z</time> +</trkpt> +<trkpt lat="40.046402" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:49:48Z</time> +</trkpt> +<trkpt lat="40.046406" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:49:49Z</time> +</trkpt> +<trkpt lat="40.046406" lon="116.313553"><ele>52.81</ele> +<time>2024-11-11T11:49:50Z</time> +</trkpt> +<trkpt lat="40.046410" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:49:51Z</time> +</trkpt> +<trkpt lat="40.046410" lon="116.313553"><ele>52.90</ele> +<time>2024-11-11T11:49:52Z</time> +</trkpt> +<trkpt lat="40.046413" lon="116.313553"><ele>52.90</ele> +<time>2024-11-11T11:49:53Z</time> +</trkpt> +<trkpt lat="40.046413" lon="116.313553"><ele>52.90</ele> +<time>2024-11-11T11:49:54Z</time> +</trkpt> +<trkpt lat="40.046417" lon="116.313553"><ele>52.90</ele> +<time>2024-11-11T11:49:55Z</time> +</trkpt> +<trkpt lat="40.046417" lon="116.313553"><ele>52.91</ele> +<time>2024-11-11T11:49:56Z</time> +</trkpt> +<trkpt lat="40.046417" lon="116.313553"><ele>52.85</ele> +<time>2024-11-11T11:49:57Z</time> +</trkpt> +<trkpt lat="40.046421" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:49:58Z</time> +</trkpt> +<trkpt lat="40.046421" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:49:59Z</time> +</trkpt> +<trkpt lat="40.046421" lon="116.313553"><ele>52.93</ele> +<time>2024-11-11T11:50:00Z</time> +</trkpt> +<trkpt lat="40.046425" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:50:01Z</time> +</trkpt> +<trkpt lat="40.046436" lon="116.313553"><ele>52.84</ele> +<time>2024-11-11T11:50:02Z</time> +</trkpt> +<trkpt lat="40.046452" lon="116.313538"><ele>52.84</ele> +<time>2024-11-11T11:50:03Z</time> +</trkpt> +<trkpt lat="40.046474" lon="116.313522"><ele>52.72</ele> +<time>2024-11-11T11:50:04Z</time> +</trkpt> +<trkpt lat="40.046497" lon="116.313507"><ele>52.72</ele> +<time>2024-11-11T11:50:05Z</time> +</trkpt> +<trkpt lat="40.046520" lon="116.313484"><ele>52.72</ele> +<time>2024-11-11T11:50:06Z</time> +</trkpt> +<trkpt lat="40.046551" lon="116.313461"><ele>52.65</ele> +<time>2024-11-11T11:50:07Z</time> +</trkpt> +<trkpt lat="40.046589" lon="116.313438"><ele>52.37</ele> +<time>2024-11-11T11:50:08Z</time> +</trkpt> +<trkpt lat="40.046627" lon="116.313416"><ele>52.29</ele> +<time>2024-11-11T11:50:09Z</time> +</trkpt> +<trkpt lat="40.046665" lon="116.313393"><ele>52.29</ele> +<time>2024-11-11T11:50:10Z</time> +</trkpt> +<trkpt lat="40.046703" lon="116.313370"><ele>52.29</ele> +<time>2024-11-11T11:50:11Z</time> +</trkpt> +<trkpt lat="40.046738" lon="116.313347"><ele>52.29</ele> +<time>2024-11-11T11:50:12Z</time> +</trkpt> +<trkpt lat="40.046772" lon="116.313332"><ele>52.41</ele> +<time>2024-11-11T11:50:13Z</time> +</trkpt> +<trkpt lat="40.046810" lon="116.313316"><ele>52.54</ele> +<time>2024-11-11T11:50:14Z</time> +</trkpt> +<trkpt lat="40.046852" lon="116.313301"><ele>52.54</ele> +<time>2024-11-11T11:50:15Z</time> +</trkpt> +<trkpt lat="40.046898" lon="116.313286"><ele>52.54</ele> +<time>2024-11-11T11:50:16Z</time> +</trkpt> +<trkpt lat="40.046944" lon="116.313271"><ele>52.54</ele> +<time>2024-11-11T11:50:17Z</time> +</trkpt> +<trkpt lat="40.046989" lon="116.313248"><ele>52.54</ele> +<time>2024-11-11T11:50:18Z</time> +</trkpt> +<trkpt lat="40.047035" lon="116.313232"><ele>52.54</ele> +<time>2024-11-11T11:50:19Z</time> +</trkpt> +<trkpt lat="40.047073" lon="116.313217"><ele>52.62</ele> +<time>2024-11-11T11:50:20Z</time> +</trkpt> +<trkpt lat="40.047115" lon="116.313202"><ele>52.86</ele> +<time>2024-11-11T11:50:21Z</time> +</trkpt> +<trkpt lat="40.047157" lon="116.313194"><ele>52.86</ele> +<time>2024-11-11T11:50:22Z</time> +</trkpt> +<trkpt lat="40.047199" lon="116.313179"><ele>52.86</ele> +<time>2024-11-11T11:50:23Z</time> +</trkpt> +<trkpt lat="40.047245" lon="116.313164"><ele>52.86</ele> +<time>2024-11-11T11:50:24Z</time> +</trkpt> +<trkpt lat="40.047287" lon="116.313148"><ele>53.08</ele> +<time>2024-11-11T11:50:25Z</time> +</trkpt> +<trkpt lat="40.047325" lon="116.313133"><ele>53.08</ele> +<time>2024-11-11T11:50:26Z</time> +</trkpt> +<trkpt lat="40.047367" lon="116.313126"><ele>53.08</ele> +<time>2024-11-11T11:50:27Z</time> +</trkpt> +<trkpt lat="40.047409" lon="116.313110"><ele>52.89</ele> +<time>2024-11-11T11:50:28Z</time> +</trkpt> +<trkpt lat="40.047451" lon="116.313095"><ele>52.75</ele> +<time>2024-11-11T11:50:29Z</time> +</trkpt> +<trkpt lat="40.047497" lon="116.313080"><ele>52.63</ele> +<time>2024-11-11T11:50:30Z</time> +</trkpt> +<trkpt lat="40.047546" lon="116.313065"><ele>52.21</ele> +<time>2024-11-11T11:50:31Z</time> +</trkpt> +<trkpt lat="40.047592" lon="116.313049"><ele>52.21</ele> +<time>2024-11-11T11:50:32Z</time> +</trkpt> +<trkpt lat="40.047638" lon="116.313034"><ele>52.51</ele> +<time>2024-11-11T11:50:33Z</time> +</trkpt> +<trkpt lat="40.047684" lon="116.313019"><ele>52.52</ele> +<time>2024-11-11T11:50:34Z</time> +</trkpt> +<trkpt lat="40.047729" lon="116.313004"><ele>52.52</ele> +<time>2024-11-11T11:50:35Z</time> +</trkpt> +<trkpt lat="40.047771" lon="116.312981"><ele>52.55</ele> +<time>2024-11-11T11:50:36Z</time> +</trkpt> +<trkpt lat="40.047817" lon="116.312965"><ele>52.85</ele> +<time>2024-11-11T11:50:37Z</time> +</trkpt> +<trkpt lat="40.047863" lon="116.312950"><ele>52.85</ele> +<time>2024-11-11T11:50:38Z</time> +</trkpt> +<trkpt lat="40.047905" lon="116.312935"><ele>52.65</ele> +<time>2024-11-11T11:50:39Z</time> +</trkpt> +<trkpt lat="40.047947" lon="116.312920"><ele>52.64</ele> +<time>2024-11-11T11:50:40Z</time> +</trkpt> +<trkpt lat="40.047989" lon="116.312897"><ele>52.64</ele> +<time>2024-11-11T11:50:41Z</time> +</trkpt> +<trkpt lat="40.048031" lon="116.312881"><ele>52.84</ele> +<time>2024-11-11T11:50:42Z</time> +</trkpt> +<trkpt lat="40.048069" lon="116.312866"><ele>52.84</ele> +<time>2024-11-11T11:50:43Z</time> +</trkpt> +<trkpt lat="40.048107" lon="116.312859"><ele>52.84</ele> +<time>2024-11-11T11:50:44Z</time> +</trkpt> +<trkpt lat="40.048145" lon="116.312843"><ele>52.99</ele> +<time>2024-11-11T11:50:45Z</time> +</trkpt> +<trkpt lat="40.048187" lon="116.312836"><ele>52.99</ele> +<time>2024-11-11T11:50:46Z</time> +</trkpt> +<trkpt lat="40.048225" lon="116.312828"><ele>52.99</ele> +<time>2024-11-11T11:50:47Z</time> +</trkpt> +<trkpt lat="40.048267" lon="116.312828"><ele>52.79</ele> +<time>2024-11-11T11:50:48Z</time> +</trkpt> +<trkpt lat="40.048306" lon="116.312820"><ele>52.79</ele> +<time>2024-11-11T11:50:49Z</time> +</trkpt> +<trkpt lat="40.048340" lon="116.312813"><ele>52.95</ele> +<time>2024-11-11T11:50:50Z</time> +</trkpt> +<trkpt lat="40.048374" lon="116.312805"><ele>53.06</ele> +<time>2024-11-11T11:50:51Z</time> +</trkpt> +<trkpt lat="40.048401" lon="116.312805"><ele>53.15</ele> +<time>2024-11-11T11:50:52Z</time> +</trkpt> +<trkpt lat="40.048428" lon="116.312790"><ele>53.15</ele> +<time>2024-11-11T11:50:53Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312782"><ele>53.15</ele> +<time>2024-11-11T11:50:54Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312767"><ele>53.15</ele> +<time>2024-11-11T11:50:55Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312767"><ele>53.12</ele> +<time>2024-11-11T11:50:56Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312767"><ele>53.12</ele> +<time>2024-11-11T11:50:57Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312767"><ele>53.19</ele> +<time>2024-11-11T11:50:58Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312767"><ele>53.20</ele> +<time>2024-11-11T11:50:59Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312759"><ele>53.25</ele> +<time>2024-11-11T11:51:00Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312759"><ele>53.26</ele> +<time>2024-11-11T11:51:01Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312759"><ele>53.26</ele> +<time>2024-11-11T11:51:02Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312759"><ele>53.26</ele> +<time>2024-11-11T11:51:03Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312759"><ele>53.10</ele> +<time>2024-11-11T11:51:04Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312752"><ele>53.10</ele> +<time>2024-11-11T11:51:05Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312752"><ele>53.10</ele> +<time>2024-11-11T11:51:06Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312752"><ele>53.20</ele> +<time>2024-11-11T11:51:07Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312752"><ele>53.13</ele> +<time>2024-11-11T11:51:08Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312752"><ele>53.20</ele> +<time>2024-11-11T11:51:09Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312752"><ele>53.26</ele> +<time>2024-11-11T11:51:10Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312752"><ele>53.26</ele> +<time>2024-11-11T11:51:11Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312744"><ele>53.13</ele> +<time>2024-11-11T11:51:12Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312744"><ele>53.10</ele> +<time>2024-11-11T11:51:13Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312744"><ele>53.10</ele> +<time>2024-11-11T11:51:14Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312737"><ele>53.10</ele> +<time>2024-11-11T11:51:15Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312737"><ele>53.06</ele> +<time>2024-11-11T11:51:16Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312737"><ele>53.14</ele> +<time>2024-11-11T11:51:17Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312737"><ele>53.14</ele> +<time>2024-11-11T11:51:18Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.05</ele> +<time>2024-11-11T11:51:19Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.05</ele> +<time>2024-11-11T11:51:20Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.21</ele> +<time>2024-11-11T11:51:21Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.21</ele> +<time>2024-11-11T11:51:22Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.27</ele> +<time>2024-11-11T11:51:23Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.27</ele> +<time>2024-11-11T11:51:24Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.27</ele> +<time>2024-11-11T11:51:25Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312729"><ele>53.28</ele> +<time>2024-11-11T11:51:26Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312729"><ele>53.28</ele> +<time>2024-11-11T11:51:27Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312729"><ele>53.20</ele> +<time>2024-11-11T11:51:28Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312729"><ele>53.20</ele> +<time>2024-11-11T11:51:29Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312729"><ele>53.20</ele> +<time>2024-11-11T11:51:30Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312729"><ele>53.17</ele> +<time>2024-11-11T11:51:31Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312729"><ele>53.20</ele> +<time>2024-11-11T11:51:32Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.20</ele> +<time>2024-11-11T11:51:33Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.22</ele> +<time>2024-11-11T11:51:34Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.28</ele> +<time>2024-11-11T11:51:35Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.28</ele> +<time>2024-11-11T11:51:36Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.22</ele> +<time>2024-11-11T11:51:37Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.11</ele> +<time>2024-11-11T11:51:38Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.11</ele> +<time>2024-11-11T11:51:39Z</time> +</trkpt> +<trkpt lat="40.048447" lon="116.312721"><ele>53.11</ele> +<time>2024-11-11T11:51:40Z</time> +</trkpt> +<trkpt lat="40.048443" lon="116.312714"><ele>53.19</ele> +<time>2024-11-11T11:51:41Z</time> +</trkpt> +<trkpt lat="40.048439" lon="116.312698"><ele>53.24</ele> +<time>2024-11-11T11:51:42Z</time> +</trkpt> +<trkpt lat="40.048424" lon="116.312668"><ele>53.24</ele> +<time>2024-11-11T11:51:43Z</time> +</trkpt> +<trkpt lat="40.048405" lon="116.312645"><ele>53.15</ele> +<time>2024-11-11T11:51:44Z</time> +</trkpt> +<trkpt lat="40.048389" lon="116.312607"><ele>53.15</ele> +<time>2024-11-11T11:51:45Z</time> +</trkpt> +<trkpt lat="40.048374" lon="116.312569"><ele>53.15</ele> +<time>2024-11-11T11:51:46Z</time> +</trkpt> +<trkpt lat="40.048355" lon="116.312531"><ele>52.68</ele> +<time>2024-11-11T11:51:47Z</time> +</trkpt> +<trkpt lat="40.048340" lon="116.312485"><ele>52.68</ele> +<time>2024-11-11T11:51:48Z</time> +</trkpt> +<trkpt lat="40.048325" lon="116.312439"><ele>52.63</ele> +<time>2024-11-11T11:51:49Z</time> +</trkpt> +<trkpt lat="40.048306" lon="116.312386"><ele>52.40</ele> +<time>2024-11-11T11:51:50Z</time> +</trkpt> +<trkpt lat="40.048283" lon="116.312332"><ele>52.37</ele> +<time>2024-11-11T11:51:51Z</time> +</trkpt> +<trkpt lat="40.048260" lon="116.312279"><ele>52.37</ele> +<time>2024-11-11T11:51:52Z</time> +</trkpt> +<trkpt lat="40.048237" lon="116.312225"><ele>52.37</ele> +<time>2024-11-11T11:51:53Z</time> +</trkpt> +<trkpt lat="40.048214" lon="116.312172"><ele>52.35</ele> +<time>2024-11-11T11:51:54Z</time> +</trkpt> +<trkpt lat="40.048191" lon="116.312111"><ele>52.33</ele> +<time>2024-11-11T11:51:55Z</time> +</trkpt> +<trkpt lat="40.048161" lon="116.312057"><ele>52.08</ele> +<time>2024-11-11T11:51:56Z</time> +</trkpt> +<trkpt lat="40.048134" lon="116.311996"><ele>52.08</ele> +<time>2024-11-11T11:51:57Z</time> +</trkpt> +<trkpt lat="40.048103" lon="116.311935"><ele>52.43</ele> +<time>2024-11-11T11:51:58Z</time> +</trkpt> +<trkpt lat="40.048077" lon="116.311874"><ele>52.43</ele> +<time>2024-11-11T11:51:59Z</time> +</trkpt> +<trkpt lat="40.048046" lon="116.311813"><ele>52.18</ele> +<time>2024-11-11T11:52:00Z</time> +</trkpt> +<trkpt lat="40.048019" lon="116.311752"><ele>52.01</ele> +<time>2024-11-11T11:52:01Z</time> +</trkpt> +<trkpt lat="40.047993" lon="116.311684"><ele>51.92</ele> +<time>2024-11-11T11:52:02Z</time> +</trkpt> +<trkpt lat="40.047962" lon="116.311623"><ele>51.92</ele> +<time>2024-11-11T11:52:03Z</time> +</trkpt> +<trkpt lat="40.047935" lon="116.311562"><ele>52.06</ele> +<time>2024-11-11T11:52:04Z</time> +</trkpt> +<trkpt lat="40.047905" lon="116.311501"><ele>52.19</ele> +<time>2024-11-11T11:52:05Z</time> +</trkpt> +<trkpt lat="40.047874" lon="116.311440"><ele>52.20</ele> +<time>2024-11-11T11:52:06Z</time> +</trkpt> +<trkpt lat="40.047844" lon="116.311378"><ele>52.30</ele> +<time>2024-11-11T11:52:07Z</time> +</trkpt> +<trkpt lat="40.047825" lon="116.311317"><ele>52.50</ele> +<time>2024-11-11T11:52:08Z</time> +</trkpt> +<trkpt lat="40.047798" lon="116.311256"><ele>52.53</ele> +<time>2024-11-11T11:52:09Z</time> +</trkpt> +<trkpt lat="40.047771" lon="116.311195"><ele>52.63</ele> +<time>2024-11-11T11:52:10Z</time> +</trkpt> +<trkpt lat="40.047741" lon="116.311134"><ele>52.63</ele> +<time>2024-11-11T11:52:11Z</time> +</trkpt> +<trkpt lat="40.047714" lon="116.311073"><ele>52.83</ele> +<time>2024-11-11T11:52:12Z</time> +</trkpt> +<trkpt lat="40.047688" lon="116.311012"><ele>52.91</ele> +<time>2024-11-11T11:52:13Z</time> +</trkpt> +<trkpt lat="40.047661" lon="116.310951"><ele>52.91</ele> +<time>2024-11-11T11:52:14Z</time> +</trkpt> +<trkpt lat="40.047634" lon="116.310890"><ele>52.63</ele> +<time>2024-11-11T11:52:15Z</time> +</trkpt> +<trkpt lat="40.047607" lon="116.310837"><ele>52.63</ele> +<time>2024-11-11T11:52:16Z</time> +</trkpt> +<trkpt lat="40.047585" lon="116.310783"><ele>52.63</ele> +<time>2024-11-11T11:52:17Z</time> +</trkpt> +<trkpt lat="40.047554" lon="116.310730"><ele>52.99</ele> +<time>2024-11-11T11:52:18Z</time> +</trkpt> +<trkpt lat="40.047531" lon="116.310669"><ele>53.00</ele> +<time>2024-11-11T11:52:19Z</time> +</trkpt> +<trkpt lat="40.047504" lon="116.310608"><ele>53.03</ele> +<time>2024-11-11T11:52:20Z</time> +</trkpt> +<trkpt lat="40.047478" lon="116.310555"><ele>53.03</ele> +<time>2024-11-11T11:52:21Z</time> +</trkpt> +<trkpt lat="40.047451" lon="116.310493"><ele>53.03</ele> +<time>2024-11-11T11:52:22Z</time> +</trkpt> +<trkpt lat="40.047428" lon="116.310432"><ele>52.86</ele> +<time>2024-11-11T11:52:23Z</time> +</trkpt> +<trkpt lat="40.047405" lon="116.310371"><ele>52.86</ele> +<time>2024-11-11T11:52:24Z</time> +</trkpt> +<trkpt lat="40.047379" lon="116.310310"><ele>52.62</ele> +<time>2024-11-11T11:52:25Z</time> +</trkpt> +<trkpt lat="40.047356" lon="116.310249"><ele>52.46</ele> +<time>2024-11-11T11:52:26Z</time> +</trkpt> +<trkpt lat="40.047329" lon="116.310188"><ele>52.46</ele> +<time>2024-11-11T11:52:27Z</time> +</trkpt> +<trkpt lat="40.047302" lon="116.310127"><ele>52.50</ele> +<time>2024-11-11T11:52:28Z</time> +</trkpt> +<trkpt lat="40.047279" lon="116.310074"><ele>52.50</ele> +<time>2024-11-11T11:52:29Z</time> +</trkpt> +<trkpt lat="40.047256" lon="116.310013"><ele>52.39</ele> +<time>2024-11-11T11:52:30Z</time> +</trkpt> +<trkpt lat="40.047234" lon="116.309952"><ele>52.39</ele> +<time>2024-11-11T11:52:31Z</time> +</trkpt> +<trkpt lat="40.047215" lon="116.309898"><ele>52.39</ele> +<time>2024-11-11T11:52:32Z</time> +</trkpt> +<trkpt lat="40.047195" lon="116.309837"><ele>52.39</ele> +<time>2024-11-11T11:52:33Z</time> +</trkpt> +<trkpt lat="40.047176" lon="116.309784"><ele>52.70</ele> +<time>2024-11-11T11:52:34Z</time> +</trkpt> +<trkpt lat="40.047153" lon="116.309738"><ele>52.70</ele> +<time>2024-11-11T11:52:35Z</time> +</trkpt> +<trkpt lat="40.047131" lon="116.309685"><ele>52.70</ele> +<time>2024-11-11T11:52:36Z</time> +</trkpt> +<trkpt lat="40.047115" lon="116.309631"><ele>52.52</ele> +<time>2024-11-11T11:52:37Z</time> +</trkpt> +<trkpt lat="40.047100" lon="116.309586"><ele>52.52</ele> +<time>2024-11-11T11:52:38Z</time> +</trkpt> +<trkpt lat="40.047092" lon="116.309547"><ele>52.68</ele> +<time>2024-11-11T11:52:39Z</time> +</trkpt> +<trkpt lat="40.047077" lon="116.309509"><ele>52.93</ele> +<time>2024-11-11T11:52:40Z</time> +</trkpt> +<trkpt lat="40.047066" lon="116.309471"><ele>52.96</ele> +<time>2024-11-11T11:52:41Z</time> +</trkpt> +<trkpt lat="40.047062" lon="116.309425"><ele>53.01</ele> +<time>2024-11-11T11:52:42Z</time> +</trkpt> +<trkpt lat="40.047070" lon="116.309387"><ele>52.96</ele> +<time>2024-11-11T11:52:43Z</time> +</trkpt> +<trkpt lat="40.047085" lon="116.309341"><ele>52.82</ele> +<time>2024-11-11T11:52:44Z</time> +</trkpt> +<trkpt lat="40.047112" lon="116.309319"><ele>52.60</ele> +<time>2024-11-11T11:52:45Z</time> +</trkpt> +<trkpt lat="40.047142" lon="116.309303"><ele>52.60</ele> +<time>2024-11-11T11:52:46Z</time> +</trkpt> +<trkpt lat="40.047173" lon="116.309280"><ele>52.64</ele> +<time>2024-11-11T11:52:47Z</time> +</trkpt> +<trkpt lat="40.047203" lon="116.309258"><ele>52.68</ele> +<time>2024-11-11T11:52:48Z</time> +</trkpt> +<trkpt lat="40.047237" lon="116.309235"><ele>52.75</ele> +<time>2024-11-11T11:52:49Z</time> +</trkpt> +<trkpt lat="40.047272" lon="116.309204"><ele>52.81</ele> +<time>2024-11-11T11:52:50Z</time> +</trkpt> +<trkpt lat="40.047310" lon="116.309189"><ele>52.78</ele> +<time>2024-11-11T11:52:51Z</time> +</trkpt> +<trkpt lat="40.047344" lon="116.309174"><ele>52.83</ele> +<time>2024-11-11T11:52:52Z</time> +</trkpt> +<trkpt lat="40.047382" lon="116.309151"><ele>52.83</ele> +<time>2024-11-11T11:52:53Z</time> +</trkpt> +<trkpt lat="40.047417" lon="116.309135"><ele>52.89</ele> +<time>2024-11-11T11:52:54Z</time> +</trkpt> +<trkpt lat="40.047459" lon="116.309120"><ele>52.89</ele> +<time>2024-11-11T11:52:55Z</time> +</trkpt> +<trkpt lat="40.047497" lon="116.309105"><ele>52.77</ele> +<time>2024-11-11T11:52:56Z</time> +</trkpt> +<trkpt lat="40.047531" lon="116.309097"><ele>52.45</ele> +<time>2024-11-11T11:52:57Z</time> +</trkpt> +<trkpt lat="40.047565" lon="116.309074"><ele>52.45</ele> +<time>2024-11-11T11:52:58Z</time> +</trkpt> +<trkpt lat="40.047596" lon="116.309059"><ele>52.33</ele> +<time>2024-11-11T11:52:59Z</time> +</trkpt> +<trkpt lat="40.047623" lon="116.309036"><ele>52.46</ele> +<time>2024-11-11T11:53:00Z</time> +</trkpt> +<trkpt lat="40.047653" lon="116.309021"><ele>52.39</ele> +<time>2024-11-11T11:53:01Z</time> +</trkpt> +<trkpt lat="40.047691" lon="116.309006"><ele>52.29</ele> +<time>2024-11-11T11:53:02Z</time> +</trkpt> +<trkpt lat="40.047726" lon="116.308998"><ele>52.12</ele> +<time>2024-11-11T11:53:03Z</time> +</trkpt> +<trkpt lat="40.047760" lon="116.308990"><ele>52.12</ele> +<time>2024-11-11T11:53:04Z</time> +</trkpt> +<trkpt lat="40.047794" lon="116.308975"><ele>52.10</ele> +<time>2024-11-11T11:53:05Z</time> +</trkpt> +<trkpt lat="40.047825" lon="116.308952"><ele>52.20</ele> +<time>2024-11-11T11:53:06Z</time> +</trkpt> +<trkpt lat="40.047855" lon="116.308945"><ele>52.51</ele> +<time>2024-11-11T11:53:07Z</time> +</trkpt> +<trkpt lat="40.047878" lon="116.308937"><ele>52.51</ele> +<time>2024-11-11T11:53:08Z</time> +</trkpt> +<trkpt lat="40.047901" lon="116.308922"><ele>52.51</ele> +<time>2024-11-11T11:53:09Z</time> +</trkpt> +<trkpt lat="40.047920" lon="116.308907"><ele>52.88</ele> +<time>2024-11-11T11:53:10Z</time> +</trkpt> +<trkpt lat="40.047932" lon="116.308891"><ele>52.96</ele> +<time>2024-11-11T11:53:11Z</time> +</trkpt> +<trkpt lat="40.047943" lon="116.308884"><ele>52.96</ele> +<time>2024-11-11T11:53:12Z</time> +</trkpt> +<trkpt lat="40.047951" lon="116.308884"><ele>52.96</ele> +<time>2024-11-11T11:53:13Z</time> +</trkpt> +<trkpt lat="40.047951" lon="116.308891"><ele>53.11</ele> +<time>2024-11-11T11:53:14Z</time> +</trkpt> +<trkpt lat="40.047951" lon="116.308891"><ele>53.11</ele> +<time>2024-11-11T11:53:15Z</time> +</trkpt> +</trkseg> +</trk> +</gpx> diff --git a/x_track/resource/upload_res.sh b/x_track/resource/upload_res.sh new file mode 100755 index 0000000000000000000000000000000000000000..38ad9eeeed9bed657718b7ce0af4a0870c651260 --- /dev/null +++ b/x_track/resource/upload_res.sh @@ -0,0 +1,3 @@ +adb push font /data +adb push images /data +adb push track /data diff --git a/x_track/src/App/App.cpp b/x_track/src/App/App.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d8bb17e7507e347981f922c3f63a06c1b864d053 --- /dev/null +++ b/x_track/src/App/App.cpp @@ -0,0 +1,105 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "App.h" +#include "Config/Config.h" +#include "Frameworks/PageManager/PageManager.h" +#include "Service/DataProc/DataProc.h" +#include "UI/AppFactory.h" +#include "UI/Resource/ResourcePool.h" +#include "UI/StatusBar/StatusBar.h" + +struct AppContext { + DataBroker* broker; + DataProc::Global_Helper* global; + PageManager* manager; + Page::StatusBar* statusBar; +}; + +static void App_ParseArgsToEnv(AppContext_t* context, int argc, const char* argv[]) +{ + if (argc < 2) { + return; + } + + DataProc::Env_Helper env(context->broker->mainNode()); + + int i = 1; + while (i < argc) { + const char* key = argv[i++]; + const char* value = i < argc ? argv[i++] : nullptr; + LV_LOG_USER("Setting env: %s = %s", key, value); + env.set(key, value); + } + + context->global->publish(DataProc::GLOBAL_EVENT::APP_ARGS_PARSED); +} + +AppContext_t* App_CreateContext(int argc, const char* argv[]) +{ + AppContext_t* context = new AppContext; + + /* Resource pool manager */ + ResourcePool::init(); + + /* Data processor */ + context->broker = new DataBroker("Broker"); + DataProc_Init(context->broker); + + context->global = new DataProc::Global_Helper(context->broker->mainNode()); + context->global->publish(DataProc::GLOBAL_EVENT::DATA_PROC_INIT_FINISHED); + + App_ParseArgsToEnv(context, argc, argv); + + /* Page manager */ + context->manager = new PageManager(AppFactory::getInstance()); + AppFactory::getInstance()->intsallAll(context->manager); + context->global->publish(DataProc::GLOBAL_EVENT::PAGE_MANAGER_INIT_FINISHED, context->manager); + + /* StatusBar */ + context->statusBar = new Page::StatusBar(context->manager->getLayerTop()); + context->global->publish(DataProc::GLOBAL_EVENT::STATUS_BAR_INIT_FINISHED); + + /* App started */ + context->global->publish(DataProc::GLOBAL_EVENT::APP_STARTED); + + return context; +} + +uint32_t App_RunLoopExecute(AppContext_t* context) +{ + LV_ASSERT_NULL(context); + context->global->publish(DataProc::GLOBAL_EVENT::APP_RUN_LOOP_EXECUTE); + return context->broker->handleTimer(); +} + +void App_DestroyContext(AppContext_t* context) +{ + LV_ASSERT_NULL(context); + context->global->publish(DataProc::GLOBAL_EVENT::APP_STOPPED); + + delete context->manager; + delete context->statusBar; + delete context->broker; + ResourcePool::deinit(); + delete context; +} diff --git a/x_track/src/App/App.h b/x_track/src/App/App.h new file mode 100644 index 0000000000000000000000000000000000000000..3775dd4aedeb33b8268b1ec1bacf6f5e899ba83e --- /dev/null +++ b/x_track/src/App/App.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __APP_H +#define __APP_H + +#include <stdint.h> + +typedef struct AppContext AppContext_t; + +extern "C" { + +/** + * @brief Create app context + * + * @param argc Number of arguments + * @param argv Arguments + * @return AppContext_t* + */ +AppContext_t* App_CreateContext(int argc, const char* argv[]); + +/** + * @brief Run app loop + * + * @param context + */ +uint32_t App_RunLoopExecute(AppContext_t* context); + +/** + * @brief Destroy app context + * + * @param context + */ +void App_DestroyContext(AppContext_t* context); + +} /* extern "C" */ + +#endif diff --git a/x_track/src/App/Config/Config.h b/x_track/src/App/Config/Config.h new file mode 100644 index 0000000000000000000000000000000000000000..93217fc5739b202a99cca3b77865dcc964dcc114 --- /dev/null +++ b/x_track/src/App/Config/Config.h @@ -0,0 +1,93 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* clang-format off */ + +/*========================= + Application configuration + *=========================*/ + +/* Default time zone (GMT+ X)*/ +#define CONFIG_TIME_ZONE_DEFAULT 8 + +/* Default language code + * zh-CN: Chinese (PRC) + * en-US: English (United States) + * + * Language coding standards: https://www.andiamo.co.uk/resources/iso-language-codes + */ +#define CONFIG_LANGUAGE_DEFAULT "zh-CN" + +/* Default weight (kilogram) */ +#define CONFIG_WEIGHT_DEFAULT 65 + +/* Default GNSS data refresh period (milliseconds) */ +#ifndef CONFIG_GNSS_UPDATE_PERIOD +# define CONFIG_GNSS_UPDATE_PERIOD 1000 +#endif + +/* Resource path configuration */ +#ifndef CONFIG_RESOURCE_FS_LETTER +#define CONFIG_RESOURCE_FS_LETTER "/" +#endif + +#ifndef CONFIG_RESOURCE_DIR_PATH +#define CONFIG_RESOURCE_DIR_PATH "Resource" +#endif + +#define RESOURCE_MAKE_PATH_NO_LETTER(path) CONFIG_RESOURCE_DIR_PATH path +#define RESOURCE_MAKE_PATH(path) CONFIG_RESOURCE_FS_LETTER RESOURCE_MAKE_PATH_NO_LETTER(path) + +/* Image and font storage directory */ +#ifndef CONFIG_IMAGE_DIR_PATH +#define CONFIG_IMAGE_DIR_PATH RESOURCE_MAKE_PATH("/images") +#endif + +#define CONFIG_IMAGE_EXT_NAME ".png" + +#ifndef CONFIG_FONT_DIR_PATH +/* Freetype uses relative paths and does not add letter */ +#define CONFIG_FONT_DIR_PATH RESOURCE_MAKE_PATH_NO_LETTER("/font") +#endif + +#define CONFIG_FONT_EXT_NAME ".ttf" +#define FONT_MAKE_PATH(name) CONFIG_FONT_DIR_PATH "/" name CONFIG_FONT_EXT_NAME + +/* Default latitude and longitude */ +#define CONFIG_GNSS_LONGITUDE_DEFAULT 116.391332f +#define CONFIG_GNSS_LATITUDE_DEFAULT 39.907415f + +/* Track file storage directory */ +#define CONFIG_TRACK_RECORD_FILE_DIR_NAME RESOURCE_MAKE_PATH("/Track") + +/* Default map file storage directory */ +#define CONFIG_MAP_DIR_PATH_DEFAULT RESOURCE_MAKE_PATH("/MAP") + +/* Default map file extension name */ +#define CONFIG_MAP_EXT_NAME_DEFAULT CONFIG_IMAGE_EXT_NAME + +/* clang-format on */ + +#endif /* __CONFIG_H */ diff --git a/x_track/src/App/Service/DataProc/DP_Backlight.cpp b/x_track/src/App/Service/DataProc/DP_Backlight.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0456e62a1062e93e597cac0a1c5ee9602a8bab59 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Backlight.cpp @@ -0,0 +1,228 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Utils/CommonMacro/CommonMacro.h" +#include "Utils/easing/easing.h" +#include <cmath> + +#define TIMER_PERIOD 30 + +// LN(1000) = 6.9077552789821f +#define PSYCHO2PHYSICAL 6.9077552789821f + +using namespace DataProc; + +class DP_Backlight { +public: + DP_Backlight(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodePower; + const DataNode* _nodeStorage; + const DataNode* _nodeSunRise; + DeviceObject* _dev; + easing_t _easing; + int _targetBrightness; + int _currentBrightness; + int _dayBrightness; + int _nightBrightness; + +private: + int onEvent(DataNode::EventParam_t* param); + void onTimer(); + void setBacklight(int brightness, bool anim, bool disable = false); + void setBacklight(int brightness); + void updateAutoBrightness(const Backlight_Info_t* info); +}; + +DP_Backlight::DP_Backlight(DataNode* node) + : _node(node) + , _nodePower(nullptr) + , _dev(nullptr) + , _targetBrightness(500) + , _currentBrightness(0) + , _dayBrightness(500) + , _nightBrightness(500) +{ + _dev = HAL::Manager()->getDevice("Backlight"); + if (!_dev) { + return; + } + + easing_init( + &_easing, + EASING_MODE_DEFAULT, + _easing_calc_Linear, + 0, + TIMER_PERIOD, + 0); + easing_set_tick_callback(HAL::GetTick); + + _nodePower = node->subscribe("Power"); + _nodeStorage = node->subscribe("Storage"); + _nodeSunRise = node->subscribe("SunRise"); + + Storage_Helper storage(node); + storage.structStart("backlight"); + storage.add("current", &_targetBrightness); + storage.add("day", &_dayBrightness); + storage.add("night", &_nightBrightness); + storage.structEnd(); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Backlight*)n->getUserData(); + return ctx->onEvent(param); + }); +} + +int DP_Backlight::onEvent(DataNode::EventParam_t* param) +{ + auto info = (Backlight_Info_t*)param->data_p; + + switch (param->event) { + case DataNode::EVENT_TIMER: + onTimer(); + break; + case DataNode::EVENT_NOTIFY: + if (!info->disable && (info->brightnessDay >= 0 || info->brightnessNight >= 0)) { + updateAutoBrightness(info); + } else { + setBacklight(info->brightness, info->anim, info->disable); + } + break; + case DataNode::EVENT_PULL: + info->brightness = _targetBrightness; + info->anim = false; + info->brightnessDay = _dayBrightness; + info->brightnessNight = _nightBrightness; + break; + case DataNode::EVENT_PUBLISH: + if (param->tran == _nodePower) { + auto powerInfo = (const Power_Info_t*)param->data_p; + if (powerInfo->isReadyToShutdown) { + /* shutdown */ + setBacklight(0, true); + } + } else if (param->tran == _nodeStorage) { + auto storageInfo = (const Storage_Info_t*)param->data_p; + if (storageInfo->cmd == STORAGE_CMD::LOAD) { + /* load success */ + setBacklight(_targetBrightness, true); + } + } else if (param->tran == _nodeSunRise) { + auto sunRiseInfo = (const SunRise_Info_t*)param->data_p; + if (sunRiseInfo->state == SUNRISE_STATE::DAY) { + setBacklight(_dayBrightness, true); + } else if (sunRiseInfo->state == SUNRISE_STATE::NIGHT) { + setBacklight(_nightBrightness, true); + } + } + break; + + default: + break; + } + + return DataNode::RES_OK; +} + +void DP_Backlight::onTimer() +{ + easing_update(&_easing); + int pos = easing_curpos(&_easing); + + setBacklight(pos); + + /* when animation is finish, stop timer */ + if (pos == _targetBrightness) { + _node->stopTimer(); + } +} + +void DP_Backlight::setBacklight(int brightness) +{ + /* record current brightness */ + _currentBrightness = brightness; + + /* gamma correction */ + if (brightness != 0 && brightness != 1000) { + brightness = (int)expf((float)brightness / 1000.0f * PSYCHO2PHYSICAL); + } + + _dev->write(&brightness, sizeof(brightness)); +} + +void DP_Backlight::setBacklight(int brightness, bool anim, bool disable) +{ + if (disable) { + /* stop animation */ + easing_stop(&_easing, _targetBrightness); + _node->stopTimer(); + setBacklight(0); + return; + } + + CM_VALUE_LIMIT(brightness, 0, 1000); + _targetBrightness = brightness; + + /* start animation */ + if (anim) { + easing_start_absolute(&_easing, _currentBrightness, _targetBrightness); + _node->startTimer(TIMER_PERIOD); + return; + } + + /* stop animation */ + easing_stop(&_easing, _targetBrightness); + _node->stopTimer(); + + /* set backlight directly */ + setBacklight(_targetBrightness); +} + +void DP_Backlight::updateAutoBrightness(const Backlight_Info_t* info) +{ + if (info->brightnessDay >= 0) { + _dayBrightness = info->brightnessDay; + } + + if (info->brightnessNight >= 0) { + _nightBrightness = info->brightnessNight; + } + + SunRise_Info_t sunRiseInfo; + if (_node->pull(_nodeSunRise, &sunRiseInfo, sizeof(sunRiseInfo)) != DataNode::RES_OK) { + return; + } + + if (sunRiseInfo.state == SUNRISE_STATE::DAY) { + setBacklight(_dayBrightness, info->anim); + } else if (sunRiseInfo.state == SUNRISE_STATE::NIGHT) { + setBacklight(_nightBrightness, info->anim); + } +} + +DATA_PROC_DESCRIPTOR_DEF(Backlight) diff --git a/x_track/src/App/Service/DataProc/DP_Clock.cpp b/x_track/src/App/Service/DataProc/DP_Clock.cpp new file mode 100755 index 0000000000000000000000000000000000000000..b9e22d44ac842c55d8468a5fb0953095e5380d3b --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Clock.cpp @@ -0,0 +1,160 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Utils/Time/Time.h" +#include <stdlib.h> + +#define TIMEZONE_STR "timeZone" + +using namespace DataProc; + +class DP_Clock { +public: + DP_Clock(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeGNSS; + const DataNode* _nodeStroage; + Env_Helper _env; + DeviceObject* _dev; + int _timeZone; + +private: + int onEvent(DataNode::EventParam_t* param); + bool calibrate(const HAL::Clock_Info_t* info); +}; + +DP_Clock::DP_Clock(DataNode* node) + : _node(node) + , _env(node) + , _dev(nullptr) + , _timeZone(CONFIG_TIME_ZONE_DEFAULT) +{ + _dev = HAL::Manager()->getDevice("Clock"); + if (!_dev) { + return; + } + + _nodeGNSS = node->subscribe("GNSS"); + _nodeStroage = node->subscribe("Storage"); + + Storage_Helper storage(node); + storage.add(TIMEZONE_STR, &_timeZone); + + _node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Clock*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PUBLISH | DataNode::EVENT_PULL | DataNode::EVENT_TIMER); + + node->startTimer(1000); +} + +int DP_Clock::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_PUBLISH: { + if (param->tran == _nodeGNSS) { + auto gnssInfo = (HAL::GNSS_Info_t*)param->data_p; + + if (!gnssInfo->isVaild) { + return DataNode::RES_NO_DATA; + } + + if (calibrate(&gnssInfo->clock)) { + _node->unsubscribe("GNSS"); + _nodeGNSS = nullptr; + } + } else if (param->tran == _nodeStroage) { + auto info = (const Storage_Info_t*)param->data_p; + if (info->cmd == STORAGE_CMD::LOAD) { + _env.setInt(TIMEZONE_STR, _timeZone); + } + } else if (param->tran == _env) { + auto info = (const Env_Info_t*)param->data_p; + if (strcmp(info->key, TIMEZONE_STR) == 0) { + _timeZone = atoi(info->value); + + /* re-calibrate */ + _nodeGNSS = _node->subscribe("GNSS"); + } + } + + return DataNode::RES_OK; + } + + case DataNode::EVENT_PULL: { + /* Clock info pull request */ + int ret = _dev->read(param->data_p, param->size); + return ret == sizeof(HAL::Clock_Info_t) ? DataNode::RES_OK : DataNode::RES_NO_DATA; + } + + case DataNode::EVENT_TIMER: { + HAL::Clock_Info_t clock; + int ret = _dev->read(&clock, sizeof(clock)); + if (ret != sizeof(clock)) { + return DataNode::RES_NO_DATA; + } + return _node->publish(&clock, sizeof(clock)); + } + + default: + break; + } + + return DataNode::RES_UNKNOWN; +} + +bool DP_Clock::calibrate(const HAL::Clock_Info_t* info) +{ + setTime( + info->hour, + info->minute, + info->second, + info->day, + info->month, + info->year); + adjustTime(_timeZone * SECS_PER_HOUR); + + HAL::Clock_Info_t clock; + clock.year = (uint16_t)year(); + clock.month = (uint8_t)month(); + clock.day = (uint8_t)day(); + clock.week = 0; + clock.hour = (uint8_t)hour(); + clock.minute = (uint8_t)minute(); + clock.second = (uint8_t)second(); + clock.millisecond = 0; + + if (_dev->ioctl(CLOCK_IOCMD_CALIBRATE, &clock, sizeof(clock)) != DeviceObject::RES_OK) { + return false; + } + + return true; +} + +DATA_PROC_DESCRIPTOR_DEF(Clock) diff --git a/x_track/src/App/Service/DataProc/DP_Env.cpp b/x_track/src/App/Service/DataProc/DP_Env.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7759e209bc2581d97a06df10368cb414b388c685 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Env.cpp @@ -0,0 +1,115 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Utils/WString/WString.h" +#include <vector> + +using namespace DataProc; + +class DP_Env { +public: + DP_Env(DataNode* node); + +private: + typedef struct { + String key; + String value; + } key_pair_t; + +private: + DataNode* _node; + std::vector<key_pair_t> _keyPairs; + +private: + int onEvent(DataNode::EventParam_t* param); + int onSet(const Env_Info_t* info); + int onGet(Env_Info_t* info); +}; + +DP_Env::DP_Env(DataNode* node) + : _node(node) +{ + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Env*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_NOTIFY | DataNode::EVENT_PULL); +} + +int DP_Env::onEvent(DataNode::EventParam_t* param) +{ + if (param->size != sizeof(Env_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + auto info = (Env_Info_t*)param->data_p; + + switch (param->event) { + case DataNode::EVENT_NOTIFY: { + auto res = onSet(info); + if (res == DataNode::RES_OK) { + _node->publish(info, sizeof(Env_Info_t)); + } + return res; + } + + case DataNode::EVENT_PULL: + return onGet(info); + + default: + break; + } + + return DataNode::RES_UNSUPPORTED_REQUEST; +} + +int DP_Env::onSet(const Env_Info_t* info) +{ + for (auto iter = _keyPairs.begin(); iter != _keyPairs.end(); ++iter) { + if (iter->key == info->key) { + iter->value = info->value; + return DataNode::RES_OK; + } + } + + key_pair_t pair = { info->key, info->value }; + _keyPairs.push_back(pair); + + return DataNode::RES_OK; +} + +int DP_Env::onGet(Env_Info_t* info) +{ + for (auto iter = _keyPairs.begin(); iter != _keyPairs.end(); ++iter) { + if (iter->key == info->key) { + info->value = iter->value.c_str(); + return DataNode::RES_OK; + } + } + + info->value = nullptr; + return DataNode::RES_NO_DATA; +} + +DATA_PROC_DESCRIPTOR_DEF(Env) diff --git a/x_track/src/App/Service/DataProc/DP_GNSS.cpp b/x_track/src/App/Service/DataProc/DP_GNSS.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72c9fe492a15c0ac2639f0d6da841057d0fac589 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_GNSS.cpp @@ -0,0 +1,317 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Service/i18n/lv_i18n.h" +#include "lvgl/lvgl.h" +#include <cmath> + +using namespace DataProc; + +#define GNSS_EPHEMERIS_DEFAULT_FILE_PATH RESOURCE_MAKE_PATH("/mgaoffline.ubx") +#define GNSS_EPHEMERIS_LOAD_PERIOD 10 +#define GNSS_EPHEMERIS_LOAD_BYTES 64 +#define GNSS_SIGNAL_QUALITY_GOOD 7 + +#ifndef GNSS_ERROR_THRESHOLD +#define GNSS_ERROR_THRESHOLD 2 +#endif + +class DP_GNSS { +public: + DP_GNSS(DataNode* node); + +private: + enum class STATUS { + DISCONNECT, + CONNECTED, + }; + +private: + DataNode* _node; + const DataNode* _nodeGlobal; + STATUS _nowStatus; + STATUS _lastStatus; + DeviceObject* _dev; + FeedbackGen_Helper _feedback; + MsgBox_Helper _msgbox; + Toast_Helper _toast; + LED_Helper _led; + lv_timer_t* _timer; + lv_fs_file_t _file; + +#if GNSS_ERROR_THRESHOLD > 0 + int16_t _lastLongitude; + int16_t _lastLatitude; + int16_t _errorCount; +#endif + +private: + int onEvent(DataNode::EventParam_t* param); + void onPublish(); + int onNotify(const GNSS_Config_Info_t* info); + bool readGNSSInfo(HAL::GNSS_Info_t* info); + bool loadEphemeris(const char* path); + static void onTimer(lv_timer_t* timer); +}; + +DP_GNSS::DP_GNSS(DataNode* node) + : _node(node) + , _nowStatus(STATUS::DISCONNECT) + , _lastStatus(STATUS::DISCONNECT) + , _dev(nullptr) + , _feedback(node) + , _msgbox(node) + , _toast(node) + , _led(node, LED_ID::BLUE) + , _timer(nullptr) +#if GNSS_ERROR_THRESHOLD > 0 + , _lastLongitude(0) + , _lastLatitude(0) + , _errorCount(0) +#endif +{ + _dev = HAL::Manager()->getDevice("GNSS"); + if (!_dev) { + return; + } + + _nodeGlobal = node->subscribe("Global"); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_GNSS*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL | DataNode::EVENT_NOTIFY | DataNode::EVENT_PUBLISH); + + loadEphemeris(GNSS_EPHEMERIS_DEFAULT_FILE_PATH); +} + +int DP_GNSS::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_PULL: { + if (param->size != sizeof(HAL::GNSS_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + if (!readGNSSInfo((HAL::GNSS_Info_t*)param->data_p)) { + return DataNode::RES_NO_DATA; + } + } break; + + case DataNode::EVENT_NOTIFY: { + if (param->size != sizeof(GNSS_Config_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + return onNotify((const GNSS_Config_Info_t*)param->data_p); + } + + case DataNode::EVENT_PUBLISH: { + if (param->tran == _nodeGlobal) { + auto globalInfo = (const Global_Info_t*)param->data_p; + if (globalInfo->event == GLOBAL_EVENT::APP_RUN_LOOP_EXECUTE) { + onPublish(); + } + } + } break; + + default: + return DataNode::RES_UNSUPPORTED_REQUEST; + } + + return DataNode::RES_OK; +} + +void DP_GNSS::onPublish() +{ + if (_dev->ioctl(GNSS_IOCMD_UPDATE) != DeviceObject::RES_OK) { + return; + } + + HAL::GNSS_Info_t gnssInfo; + if (!readGNSSInfo(&gnssInfo)) { + static const LED_Squence_t seqError[] = { + { LED_STATUS::ON, 50 }, + { LED_STATUS::OFF, 50 }, + { LED_STATUS::ON, 50 }, + { LED_STATUS::OFF, 50 }, + { LED_STATUS::ON, 50 }, + { LED_STATUS::OFF, 50 }, + { LED_STATUS::STOP, 0 }, + }; + _led.start(seqError); + return; + } + + int satellites = gnssInfo.satellites; + + if (satellites > GNSS_SIGNAL_QUALITY_GOOD) { + _nowStatus = STATUS::CONNECTED; + } else if (satellites == 0) { + _nowStatus = STATUS::DISCONNECT; + } + + /* on status changed */ + if (_nowStatus != _lastStatus) { + _lastStatus = _nowStatus; + static const FEEDBACK_GEN_EFFECT effect[] = { + FEEDBACK_GEN_EFFECT::NOTIFICATION_ERROR, + FEEDBACK_GEN_EFFECT::NOTIFICATION_SUCCESS + }; + + _feedback.trigger(effect[(int)_nowStatus]); + + /* publish disconnect info */ + if (_nowStatus == STATUS::DISCONNECT) { + _node->publish(&gnssInfo, sizeof(gnssInfo)); + } + } + + static const LED_Squence_t seqSlow[] = { + { LED_STATUS::ON, 300 }, + { LED_STATUS::OFF, 0 }, + { LED_STATUS::STOP, 0 }, + }; + const LED_Squence_t* seq = seqSlow; + + /* publish info */ + if (gnssInfo.isVaild && satellites >= 3) { + _node->publish(&gnssInfo, sizeof(gnssInfo)); + + static const LED_Squence_t seqFast[] = { + { LED_STATUS::ON, 50 }, + { LED_STATUS::OFF, 0 }, + { LED_STATUS::STOP, 0 }, + }; + seq = seqFast; + } + + _led.start(seq); +} + +int DP_GNSS::onNotify(const GNSS_Config_Info_t* info) +{ + switch (info->cmd) { + case GNSS_CMD::LOAD_EPHEMERIS: { + auto path = GNSS_EPHEMERIS_DEFAULT_FILE_PATH; + + /* use custom path */ + if (info->param.ephemerisPath) { + path = info->param.ephemerisPath; + } + + return loadEphemeris(path) ? DataNode::RES_OK : DataNode::RES_NO_DATA; + } + + default: + break; + } + + return DataNode::RES_UNSUPPORTED_REQUEST; +} + +bool DP_GNSS::readGNSSInfo(HAL::GNSS_Info_t* info) +{ + if (_dev->read(info, sizeof(HAL::GNSS_Info_t)) != sizeof(HAL::GNSS_Info_t)) { + return false; + } + +#if GNSS_ERROR_THRESHOLD > 0 + if (_lastLatitude != 0 && _lastLongitude != 0 + && (std::fabs(info->latitude - _lastLatitude) > GNSS_ERROR_THRESHOLD + || std::fabs(info->longitude - _lastLongitude) > GNSS_ERROR_THRESHOLD)) { + + _errorCount++; + + char buf[64]; + lv_snprintf(buf, sizeof(buf), + "Latitude: %f\nLongitude: %f\nError Count: %d", + info->latitude, info->longitude, _errorCount); + static const char* btns[] = { "OK", "" }; + _msgbox.show("GNSS ERROR", buf, btns); + return false; + } + + _lastLatitude = info->latitude; + _lastLongitude = info->longitude; +#endif + + return true; +} + +bool DP_GNSS::loadEphemeris(const char* path) +{ + if (_timer) { + LV_LOG_WARN("GNSS ephemeris is loading, please wait..."); + return false; + } + + lv_fs_res_t res = lv_fs_open(&_file, path, LV_FS_MODE_RD); + if (res != LV_FS_RES_OK) { + LV_LOG_WARN("open %s failed: %d", path, res); + return false; + } + + _timer = lv_timer_create(onTimer, GNSS_EPHEMERIS_LOAD_PERIOD, this); + return true; +} + +void DP_GNSS::onTimer(lv_timer_t* timer) +{ + auto self = (DP_GNSS*)lv_timer_get_user_data(timer); + + uint32_t rd; + uint8_t buff[GNSS_EPHEMERIS_LOAD_BYTES]; + auto res = lv_fs_read(&self->_file, buff, sizeof(buff), &rd); + if (res != LV_FS_RES_OK) { + goto onFinished; + } + + if (rd < 1) { + LV_LOG_WARN("read EOF Finished"); + self->_toast.show("%s %s", _("EPHEMERIS"), _("LOAD_SUCCESS")); + goto onFinished; + } + + if (self->_dev->write(buff, rd) < 0) { + LV_LOG_ERROR("write GNSS failed"); + goto onFinished; + } + + self->_led.on(); + + return; + +onFinished: + lv_fs_close(&self->_file); + lv_timer_del(self->_timer); + self->_timer = nullptr; + + self->_led.off(); +} + +DATA_PROC_DESCRIPTOR_DEF(GNSS) diff --git a/x_track/src/App/Service/DataProc/DP_Global.cpp b/x_track/src/App/Service/DataProc/DP_Global.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39efdf7aecc55bcdf2fd9b9602aee1ee4ffd2216 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Global.cpp @@ -0,0 +1,58 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" + +using namespace DataProc; + +class DP_Global { +public: + DP_Global(DataNode* node); + +private: + DataNode* _node; + +private: + int onEvent(DataNode::EventParam_t* param); +}; + +DP_Global::DP_Global(DataNode* node) + : _node(node) +{ + _node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Global*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_NOTIFY); +} + +int DP_Global::onEvent(DataNode::EventParam_t* param) +{ + if (param->size != sizeof(Global_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + return _node->publish(param->data_p, param->size); +} + +DATA_PROC_DESCRIPTOR_DEF(Global) diff --git a/x_track/src/App/Service/DataProc/DP_MapInfo.cpp b/x_track/src/App/Service/DataProc/DP_MapInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..16f4935337928ca9cefa3ef657a109dbc622a1b1 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_MapInfo.cpp @@ -0,0 +1,187 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "lvgl/lvgl.h" +#include <stdlib.h> + +#define MAP_LEVEL_MIN_DEFAULT 3 +#define MAP_LEVEL_MAX_DEFAULT 16 +#define MAP_LEVEL_MIN 0 +#define MAP_LEVEL_MAX 19 + +using namespace DataProc; + +class DP_MapInfo { +public: + DP_MapInfo(DataNode* node); + +private: + Map_Info_t _info; + char _path[32]; + char _ext[8]; + bool _isSearched; + +private: + int onEvent(DataNode::EventParam_t* param); + bool searchDirLevel(const char* dirName, uint8_t* min, uint8_t* max); +}; + +DP_MapInfo::DP_MapInfo(DataNode* node) + : _path { CONFIG_MAP_DIR_PATH_DEFAULT } + , _ext { CONFIG_MAP_EXT_NAME_DEFAULT } + , _isSearched(false) +{ + _info.path = _path; + _info.ext = _ext; + _info.levelMin = MAP_LEVEL_MIN_DEFAULT; + _info.levelMax = MAP_LEVEL_MAX_DEFAULT; + _info.coordTrans = false; + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_MapInfo*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL | DataNode::EVENT_NOTIFY); + + Storage_Helper storage(node); + storage.structStart("map"); + storage.add("path", _path, sizeof(_path), STORAGE_TYPE::STRING); + storage.add("ext", _ext, sizeof(_ext), STORAGE_TYPE::STRING); + storage.add("coordTrans", &_info.coordTrans); + storage.structEnd(); +} + +int DP_MapInfo::onEvent(DataNode::EventParam_t* param) +{ + if (param->size != sizeof(Map_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + auto info = (Map_Info_t*)param->data_p; + + switch (param->event) { + case DataNode::EVENT_PULL: { + if (!_isSearched) { + searchDirLevel(_path, &_info.levelMin, &_info.levelMax); + + LV_LOG_USER( + "Map path: %s, ext: %s, coord: %s, level min = %d, max = %d", + _info.path, + _info.ext, + _info.coordTrans ? "GCJ02" : "WGS84", + _info.levelMin, + _info.levelMax); + + _isSearched = true; + } + + *info = _info; + } break; + + case DataNode::EVENT_NOTIFY: { + _info.coordTrans = info->coordTrans; + + if (info->path && info->path != _path) { + strncpy(_path, info->path, sizeof(_path)); + _path[sizeof(_path) - 1] = '\0'; + } + + if (info->ext && info->ext != _ext) { + strncpy(_ext, info->ext, sizeof(_ext)); + _ext[sizeof(_ext) - 1] = '\0'; + } + } break; + + default: + break; + } + + return DataNode::RES_OK; +} + +bool DP_MapInfo::searchDirLevel(const char* dirName, uint8_t* min, uint8_t* max) +{ + lv_fs_dir_t dir; + + if (lv_fs_dir_open(&dir, dirName) != LV_FS_RES_OK) { + LV_LOG_ERROR("%s open faild", dirName); + return false; + } + + LV_LOG_USER("%s open success", dirName); + + uint8_t levelMin = MAP_LEVEL_MAX; + uint8_t levelMax = MAP_LEVEL_MIN; + int levelCnt = MAP_LEVEL_MAX + 1; + bool retval = false; + + char name[128]; + while (levelCnt--) { + lv_fs_res_t res = lv_fs_dir_read(&dir, name, sizeof(name)); + + if (name[0] == '\0' || res != LV_FS_RES_OK) { + break; + } + LV_LOG_INFO("dir: %s", name); + + if (name[0] == '/') { + + /* skip "/" */ + if (name[1] == '\0') { + continue; + } + + retval = true; + int level = atoi(name + 1); + + if (level < MAP_LEVEL_MIN || level > MAP_LEVEL_MAX) { + LV_LOG_ERROR("Error level = %d", level); + retval = false; + break; + } + + if (level < levelMin) { + levelMin = level; + } + + if (level > levelMax) { + levelMax = level; + } + } + } + + if (retval) { + *min = levelMin; + *max = levelMax; + } else { + LV_LOG_WARN("search failed!"); + } + + lv_fs_dir_close(&dir); + + return retval; +} + +DATA_PROC_DESCRIPTOR_DEF(MapInfo) diff --git a/x_track/src/App/Service/DataProc/DP_PageNavi.cpp b/x_track/src/App/Service/DataProc/DP_PageNavi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a63398e10572ef39c1fdf25873e9d597c553e22 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_PageNavi.cpp @@ -0,0 +1,228 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Frameworks/PageManager/PageManager.h" +#include "UI/AppFactory.h" + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) + +using namespace DataProc; + +class DP_PageNavi { +public: + DP_PageNavi(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeGlobal; + Env_Helper _env; + PageManager* _manager; + bool _enable; + lv_style_t _pageStyle; + +private: + int onEvent(DataNode::EventParam_t* param); + int onNotify(const PageNavi_Info_t* info); + int onGlobalEvent(const Global_Info_t* info); + int naviToPage(PAGE_NAVI_CMD cmd, const char* name = nullptr); + static PageManager::RES_TYPE onPageEvent(PageManager::EVENT* event); +}; + +DP_PageNavi::DP_PageNavi(DataNode* node) + : _node(node) + , _env(node) +{ + _nodeGlobal = node->subscribe("Global"); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_PageNavi*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PUBLISH | DataNode::EVENT_NOTIFY); + + APP_DESCRIPTOR_IMPORT(Dashboard); + APP_DESCRIPTOR_IMPORT(LiveMap); + APP_DESCRIPTOR_IMPORT(Shutdown); + APP_DESCRIPTOR_IMPORT(Startup); + APP_DESCRIPTOR_IMPORT(SystemInfos); +} + +int DP_PageNavi::onEvent(DataNode::EventParam_t* param) +{ + if (param->event == DataNode::EVENT_NOTIFY) { + if (param->size != sizeof(PageNavi_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + return onNotify((const PageNavi_Info_t*)param->data_p); + } + + if (param->tran == _env) { + auto info = (const Env_Info_t*)param->data_p; + if (IS_STR_EQ(info->key, "pagenavi")) { + _enable = IS_STR_EQ(info->value, "enable"); + } + } + + if (param->tran == _nodeGlobal) { + return onGlobalEvent((const Global_Info_t*)param->data_p); + } + + if (!_enable) { + return DataNode::RES_UNSUPPORTED_REQUEST; + } + + return DataNode::RES_UNSUPPORTED_REQUEST; +} + +int DP_PageNavi::onNotify(const PageNavi_Info_t* info) +{ + auto retval = PageManager::RES_TYPE::ERR_UNKNOWN; + + switch (info->cmd) { + case PAGE_NAVI_CMD::PUSH: { + retval = _manager->push(info->name); + } break; + + case PAGE_NAVI_CMD::POP: { + retval = _manager->pop(); + } break; + + default: + break; + } + + return retval == PageManager::RES_TYPE::OK ? DataNode::RES_OK : DataNode::RES_UNSUPPORTED_REQUEST; +} + +int DP_PageNavi::onGlobalEvent(const Global_Info_t* info) +{ + switch (info->event) { + case GLOBAL_EVENT::PAGE_MANAGER_INIT_FINISHED: { + _manager = (PageManager*)info->param; + +#if defined(PAGE_HOR_RES) && PAGE_HOR_RES > 0 && defined(PAGE_VER_RES) && PAGE_VER_RES > 0 + lv_obj_t* scr = lv_obj_create(lv_scr_act()); + lv_obj_remove_style_all(scr); + lv_obj_set_size(scr, PAGE_HOR_RES, PAGE_VER_RES); + lv_obj_center(scr); + _manager->setRootParent(scr); + + lv_obj_t* layer_top = lv_obj_create(lv_layer_top()); + lv_obj_remove_style_all(layer_top); + lv_obj_remove_flag(layer_top, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_remove_flag(layer_top, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(layer_top, PAGE_HOR_RES, PAGE_VER_RES); + lv_obj_center(layer_top); + _manager->setLayerTop(layer_top); +#endif + + /* Screen style */ + lv_obj_set_style_pad_all(_manager->getRootParent(), 0, 0); + lv_obj_clear_flag(_manager->getRootParent(), LV_OBJ_FLAG_SCROLLABLE); + + /* Page style */ + lv_style_init(&_pageStyle); + lv_style_set_size(&_pageStyle, lv_pct(100), lv_pct(100)); + lv_style_set_pad_all(&_pageStyle, 0); + lv_style_set_radius(&_pageStyle, 0); + lv_style_set_border_width(&_pageStyle, 0); + lv_style_set_text_font(&_pageStyle, lv_theme_get_font_normal(nullptr)); + _manager->setRootDefaultStyle(&_pageStyle); + + /* Page event hooker */ + _manager->setEventCallback(onPageEvent, this); + } break; + + case GLOBAL_EVENT::STATUS_BAR_INIT_FINISHED: { + /* Update StatusBar padding */ + lv_style_set_pad_top(&_pageStyle, _env.getInt("statusbar-padding-top")); + } break; + + case GLOBAL_EVENT::APP_STARTED: { + /* Open page */ + _manager->push("Startup"); + } break; + + case GLOBAL_EVENT::APP_STOPPED: { + /* Close page */ + _manager->setRootDefaultStyle(nullptr); + lv_style_reset(&_pageStyle); + } break; + + default: + break; + } + + return DataNode::RES_OK; +} + +int DP_PageNavi::naviToPage(PAGE_NAVI_CMD cmd, const char* name) +{ + PageNavi_Info_t info; + info.cmd = cmd; + info.name = name; + return onNotify(&info); +} + +PageManager::RES_TYPE DP_PageNavi::onPageEvent(PageManager::EVENT* event) +{ + auto self = (DP_PageNavi*)event->userData; + + switch (event->type) { + case PageManager::EVENT_TYPE::PAGE_STATE_CHANGED: { + auto state = *(const PageBase::STATE*)event->param; + + /* Set default env when page did appear */ + if (state == PageBase::STATE::DID_APPEAR) { + self->_env.set("statusbar-opa", "cover"); + self->_env.set("navibar", "enable"); + self->_env.set("statusbar", "enable"); + self->_env.set("pagenavi", "enable"); + } + } break; + + case PageManager::EVENT_TYPE::PAGE_PUSH: + case PageManager::EVENT_TYPE::PAGE_POP: { + PageNavi_Info_t info; + info.cmd = event->type == PageManager::EVENT_TYPE::PAGE_PUSH ? PAGE_NAVI_CMD::PUSH : PAGE_NAVI_CMD::POP; + info.name = (const char*)event->param; + auto res = self->_node->publish(&info, sizeof(info)); + + /* if the page navigation is intercept, stop process */ + if (res == DataNode::RES_STOP_PROCESS) { + return PageManager::RES_TYPE::STOP_PROCESS; + } + + return PageManager::RES_TYPE::OK; + } break; + + default: + break; + } + + return PageManager::RES_TYPE::OK; +} + +DATA_PROC_DESCRIPTOR_DEF(PageNavi); diff --git a/x_track/src/App/Service/DataProc/DP_Power.cpp b/x_track/src/App/Service/DataProc/DP_Power.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3aea62711ca001589204f60c5ef4c2e0f044079c --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Power.cpp @@ -0,0 +1,302 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Service/HAL/HAL_Log.h" +#include "Service/i18n/lv_i18n.h" + +using namespace DataProc; + +/* clang-format off */ + +#define POWER_SYSTEM_VOLTAGE (2800) // mV +#define POWER_FORCE_SHUTDOWN_VOLTAGE (3100) // mV +#define POWER_FORCE_SHUTDOWN_TIMEOUT (10 * 1000) // ms + +/* clang-format on */ + +class DP_Power { +public: + DP_Power(DataNode* node); + +private: + enum class AUTO_SHUTDOWN_STATE { + IDLE, + ACTIVE, + WAIT_USER_CONFIRM, + USER_CANCELED, + USER_ACCEPTED, + }; + +private: + DataNode* _node; + const DataNode* _nodeBtn; + MsgBox_Helper _msgBox; + Env_Helper _env; + DeviceObject* _dev; + Power_Info_t _info; + uint32_t _lastTick; + uint32_t _pressStartTick; + + uint32_t _wakeUpTick; + int _lockCount; + + AUTO_SHUTDOWN_STATE _autoShutdownState; + +private: + int onEvent(DataNode::EventParam_t* param); + void onPowerNotify(const Power_Info_t* info); + void onMsgBoxNotify(const MsgBox_Info_t* info); + void requestShutdown(uint32_t delayTime = 2000); + void checkShutdown(); + void publishInfo(); + void notifyUserReadyToShutdown(const char* title, const char* text); +}; + +DP_Power::DP_Power(DataNode* node) + : _node(node) + , _msgBox(node) + , _env(node) + , _lockCount(0) + , _autoShutdownState(AUTO_SHUTDOWN_STATE::ACTIVE) +{ + _dev = HAL::Manager()->getDevice("Power"); + if (!_dev) { + return; + } + + /* power on */ + _dev->ioctl(POWER_IOCMD_POWER_ON); + int sysVoltage = POWER_SYSTEM_VOLTAGE; + _dev->ioctl(POWER_IOCMD_SET_SYS_VOLTAGE, &sysVoltage, sizeof(sysVoltage)); + + /* init info */ + Storage_Helper storage(node); + storage.addArray("batteryUseTime", &_info.batteryUseTime, sizeof(uint32_t), 2, STORAGE_TYPE::INT); + storage.add("autoShutdownTime", &_info.autoShutdownTime); + + _nodeBtn = node->subscribe("Button"); + + _node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Power*)n->getUserData(); + return ctx->onEvent(param); + }); + _node->startTimer(1000); + + _lastTick = HAL::GetTick(); + _wakeUpTick = HAL::GetTick(); +} + +int DP_Power::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_TIMER: + checkShutdown(); + publishInfo(); + break; + + case DataNode::EVENT_PULL: + if (param->size != sizeof(Power_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + memcpy(param->data_p, &_info, sizeof(Power_Info_t)); + break; + + case DataNode::EVENT_NOTIFY: + if (param->tran == _msgBox) { + onMsgBoxNotify((MsgBox_Info_t*)param->data_p); + } else { + if (param->size != sizeof(Power_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + onPowerNotify((Power_Info_t*)param->data_p); + } + break; + + default: + return DataNode::RES_UNSUPPORTED_REQUEST; + } + + return DataNode::RES_OK; +} + +void DP_Power::onPowerNotify(const Power_Info_t* info) +{ + switch (info->cmd) { + case POWER_CMD::SHUTDOWN: { + requestShutdown(info->delayShutdownTime); + } break; + + case POWER_CMD::REBOOT: { + _dev->ioctl(POWER_IOCMD_REBOOT); + } break; + + case POWER_CMD::LOCK_WAKEUP: { + _lockCount++; + // HAL_LOG_INFO("Lock wakeup, count = %d", _lockCount); + } break; + + case POWER_CMD::UNLOCK_WAKEUP: { + _lockCount--; + // HAL_LOG_INFO("Unlock wakeup, count = %d", _lockCount); + + if (_lockCount < 0) { + HAL_LOG_WARN("Error unlock wakeup"); + _lockCount = 0; + } + + /* update wake up tick */ + _wakeUpTick = HAL::GetTick(); + } break; + + case POWER_CMD::KICK_WAKEUP: { + /* update wake up tick */ + _wakeUpTick = HAL::GetTick(); + } break; + + case POWER_CMD::SET_AUTO_SHUTDOWN_TIME: { + _info.autoShutdownTime = info->autoShutdownTime; + } break; + + case POWER_CMD::RESET_FUEL_GAUGE: { + _dev->ioctl(POWER_IOCMD_GAUGE_RESET); + } break; + + default: + break; + } +} + +void DP_Power::onMsgBoxNotify(const MsgBox_Info_t* info) +{ + switch (info->activeBtn) { + case 0: + _autoShutdownState = AUTO_SHUTDOWN_STATE::USER_CANCELED; + HAL_LOG_WARN("shutdown canceled"); + break; + case 1: + _autoShutdownState = AUTO_SHUTDOWN_STATE::USER_ACCEPTED; + requestShutdown(); + break; + + default: + break; + } +} + +void DP_Power::requestShutdown(uint32_t delayTime) +{ + HAL_LOG_WARN("Shutdown requested"); + + _info.isReadyToShutdown = true; + + /* delay to shutdown */ + _node->setTimerPeriod(delayTime); + + /* notify storage to save data */ + _env.set("storage", "save"); + + /* publish shutdown info */ + _node->publish(&_info, sizeof(_info)); +} + +void DP_Power::checkShutdown() +{ + /* check shutdown request */ + if (_info.isReadyToShutdown) { + _dev->ioctl(POWER_IOCMD_POWER_OFF); + _node->stopTimer(); + return; + } + + switch (_autoShutdownState) { + case AUTO_SHUTDOWN_STATE::ACTIVE: { + if (_info.voltage > 0 && _info.voltage < POWER_FORCE_SHUTDOWN_VOLTAGE) { + HAL_LOG_WARN("Voltage = %dmV is too low", _info.voltage); + _info.isBatteryLow = true; + notifyUserReadyToShutdown(_("LOW_BATTERY"), _("SHUTDOWN?")); + } + + /* check auto shutdown */ + if (_info.autoShutdownTime > 0 && _lockCount == 0) { + if (HAL::GetTickElaps(_wakeUpTick) > _info.autoShutdownTime * 1000U) { + HAL_LOG_WARN("Auto shutdown after %dsec", _info.autoShutdownTime); + notifyUserReadyToShutdown(_("NO_OPERATION"), _("SHUTDOWN?")); + } + } + } break; + + default: + break; + } +} + +void DP_Power::publishInfo() +{ + /* if ready to shutdown, do not publish info */ + if (_info.isReadyToShutdown) { + return; + } + + /* read power info */ + HAL::Power_Info_t info; + if (_dev->read(&info, sizeof(info)) != sizeof(info)) { + return; + } + + /* basic info */ + _info.voltage = info.voltage; + _info.level = info.level; + _info.isReady = info.isReady; + _info.isCharging = info.isCharging; + + uint32_t elaps = HAL::GetTickElaps(_lastTick); + _lastTick = HAL::GetTick(); + + if (info.isCharging) { + _info.batteryUseTime = 0; + } else { + _info.batteryUseTime += elaps; + } + + _info.uptime += elaps; + + _node->publish(&_info, sizeof(_info)); +} + +void DP_Power::notifyUserReadyToShutdown(const char* title, const char* text) +{ + static const char* btns[] = { _("NO"), _("YES"), "" }; + + MsgBox_Info_t info; + info.title = title; + info.txt = text; + info.btns = btns; + info.autoSelectBtn = 1; + _msgBox.show(&info); + + _autoShutdownState = AUTO_SHUTDOWN_STATE::WAIT_USER_CONFIRM; +} + +DATA_PROC_DESCRIPTOR_DEF(Power) diff --git a/x_track/src/App/Service/DataProc/DP_Recorder.cpp b/x_track/src/App/Service/DataProc/DP_Recorder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..607a1690983bde26cabc709bb30217238befdbe9 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Recorder.cpp @@ -0,0 +1,396 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Service/i18n/lv_i18n.h" +#include "Utils/GPX/GPX.h" +#include "lvgl/lvgl.h" + +using namespace DataProc; + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) + +#define RECORDER_GPX_TIME_FMT "%d-%02d-%02dT%02d:%02d:%02dZ" +#define RECORDER_GPX_MONTH_FMT "%d_%02d" +#define RECORDER_GPX_FILE_NAME CONFIG_TRACK_RECORD_FILE_DIR_NAME "/" RECORDER_GPX_MONTH_FMT "/TRK_%d%02d%02d_%02d%02d%02d.gpx" + +class DP_Recorder { +public: + DP_Recorder(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeClock; + const DataNode* _nodeGNSS; + const DataNode* _nodePower; + const DataNode* _nodeSlope; + Env_Helper _env; + bool _autoRec; + bool _autoRecFinish; + Recorder_Info_t _recInfo; + lv_fs_file_t _file; + GPX _gpx; + +private: + int onEvent(DataNode::EventParam_t* param); + int onPublish(DataNode::EventParam_t* param); + int onNotify(Recorder_Info_t* info); + bool onAutoRecord(); + bool recStart(uint16_t time); + bool recStop(); + void recPoint(const HAL::GNSS_Info_t* gnssInfo, const Slope_Info_t* slopeInfo = nullptr); + void showToast(const char* msg); + void setEnv(const char* value); + int notifyFilter(bool active); + lv_fs_res_t writeFile(lv_fs_file_t* file_p, const char* str); + int getTimeString(const char* format, char* buf, uint32_t size); + int makeDir(const char* path); +}; + +DP_Recorder::DP_Recorder(DataNode* node) + : _node(node) + , _env(node) + , _autoRec(true) + , _autoRecFinish(false) + , _file { 0 } +{ + _nodeClock = node->subscribe("Clock"); + _nodeGNSS = node->subscribe("GNSS"); + _nodePower = node->subscribe("Power"); + _nodeSlope = node->subscribe("Slope"); + node->subscribe("TrackFilter"); + node->subscribe("Toast"); + node->subscribe("Version"); + + /* create Track dir */ + makeDir(CONFIG_TRACK_RECORD_FILE_DIR_NAME); + + Storage_Helper storage(node); + storage.add("autoRec", &_autoRec); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Recorder*)n->getUserData(); + return ctx->onEvent(param); + }); +} + +int DP_Recorder::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_PUBLISH: + return onPublish(param); + + case DataNode::EVENT_PULL: + if (param->size != sizeof(Recorder_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + _recInfo.autoRec = _autoRec; + memcpy(param->data_p, &(_recInfo), param->size); + break; + + case DataNode::EVENT_NOTIFY: + if (param->size != sizeof(Recorder_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + if (!onNotify((Recorder_Info_t*)param->data_p)) { + return DataNode::RES_UNSUPPORTED_REQUEST; + } + break; + + default: + break; + } + + return DataNode::RES_OK; +} + +int DP_Recorder::onPublish(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeGNSS) { + auto info = (HAL::GNSS_Info_t*)param->data_p; + + if (info->isVaild && _autoRec && !_autoRecFinish) { + onAutoRecord(); + } + + if (_recInfo.active) { + Slope_Info_t slopeInfo; + bool hasSlope = _node->pull(_nodeSlope, &slopeInfo, sizeof(slopeInfo)) == DataNode::RES_OK; + + recPoint(info, hasSlope ? &slopeInfo : nullptr); + } + + return DataNode::RES_OK; + } + + if (param->tran == _nodePower) { + auto info = (Power_Info_t*)param->data_p; + if (info->isReadyToShutdown) { + Recorder_Info_t recInfo; + recInfo.active = false; + return onNotify(&recInfo); + } + + return DataNode::RES_OK; + } + + if (param->tran == _env) { + auto info = (const Env_Info_t*)param->data_p; + if (IS_STR_EQ(info->key, "storage") && IS_STR_EQ(info->value, "save")) { + Recorder_Info_t recInfo; + recInfo.active = false; + return onNotify(&recInfo); + } + + return DataNode::RES_OK; + } + + return DataNode::RES_UNSUPPORTED_REQUEST; +} + +int DP_Recorder::onNotify(Recorder_Info_t* info) +{ + if (info->cmd == RECORDER_CMD::ENABLE_AUTO_REC) { + _autoRec = true; + } else if (info->cmd == RECORDER_CMD::DISABLE_AUTO_REC) { + _autoRec = false; + } + + if (info->active) { + if (!recStart(info->time)) { + return DataNode::RES_NO_DATA; + } + + setEnv("REC"); + notifyFilter(true); + showToast(_("START_RECORD")); + _node->publish(info, sizeof(Recorder_Info_t)); + return DataNode::RES_OK; + } + + if (!recStop()) { + return DataNode::RES_NO_DATA; + } + + setEnv(""); + notifyFilter(false); + showToast(_("STOP_RECORD")); + _node->publish(info, sizeof(Recorder_Info_t)); + return DataNode::RES_OK; +} + +bool DP_Recorder::onAutoRecord() +{ + Recorder_Info_t info; + info.active = true, + info.time = 1000; + _autoRecFinish = true; + + /* notify self to start record */ + return onNotify(&info); +} + +lv_fs_res_t DP_Recorder::writeFile(lv_fs_file_t* file_p, const char* str) +{ + // LV_LOG_USER(str); + + lv_fs_res_t res = lv_fs_write( + file_p, + str, + (uint32_t)strlen(str), + nullptr); + + return res; +} + +int DP_Recorder::makeDir(const char* path) +{ + auto dev = HAL::Manager()->getDevice("SdCard"); + if (!dev) { + return -1; + } + + auto ret = dev->ioctl(SDCARD_IOCMD_MKDIR, (void*)path, sizeof(path)); + + if (ret != DeviceObject::RES_OK) { + LV_LOG_ERROR("mkdir: %s failed %d", path, ret); + } + + return ret; +} + +int DP_Recorder::getTimeString(const char* format, char* buf, uint32_t size) +{ + HAL::Clock_Info_t clock; + int retval = -1; + if (_node->pull(_nodeClock, &clock, sizeof(clock)) == DataNode::RES_OK) { + retval = snprintf( + buf, + size, + format, + clock.year, + clock.month, + clock.day, + clock.hour, + clock.minute, + clock.second); + } + + return retval; +} + +void DP_Recorder::recPoint(const HAL::GNSS_Info_t* gnssInfo, const Slope_Info_t* slopeInfo) +{ + // LV_LOG_USER("Track recording..."); + + char timeBuf[64]; + int ret = getTimeString(RECORDER_GPX_TIME_FMT, timeBuf, sizeof(timeBuf)); + if (ret < 0) { + LV_LOG_WARN("cant't get time"); + return; + } + + auto altitude = slopeInfo ? slopeInfo->altitude : gnssInfo->altitude; + + _gpx.setEle(String(altitude, 2)); + _gpx.setTime(timeBuf); + + String gpxStr = _gpx.getPt( + GPX_TRKPT, + String(gnssInfo->longitude, 6), + String(gnssInfo->latitude, 6)); + + writeFile(&(_file), gpxStr.c_str()); +} + +void DP_Recorder::showToast(const char* msg) +{ + Toast_Info_t info; + info.txt = msg; + info.duration = 2000; + _node->notify("Toast", &info, sizeof(info)); +} + +bool DP_Recorder::recStart(uint16_t time) +{ + if (_recInfo.active) { + return false; + } + + HAL::GNSS_Info_t gnssInfo; + if (!(_node->pull("GNSS", &gnssInfo, sizeof(gnssInfo)) == DataNode::RES_OK + && gnssInfo.isVaild)) { + showToast(_("GNSS_NOT_READY")); + return false; + } + + Version_Info_t versionInfo; + if (_node->pull("Version", &versionInfo, sizeof(versionInfo)) != DataNode::RES_OK) { + return false; + } + + LV_LOG_USER("start"); + + HAL::Clock_Info_t clock; + if (_node->pull(_nodeClock, &clock, sizeof(clock)) != DataNode::RES_OK) { + LV_LOG_ERROR("cant't get clock"); + return false; + } + + char filepath[128]; + + /* create dir */ + lv_snprintf(filepath, sizeof(filepath), CONFIG_TRACK_RECORD_FILE_DIR_NAME "/" RECORDER_GPX_MONTH_FMT, + clock.year, clock.month); + if (makeDir(filepath) != DeviceObject::RES_OK) { + return false; + } + + /* create file */ + lv_snprintf(filepath, sizeof(filepath), RECORDER_GPX_FILE_NAME, + clock.year, clock.month, + clock.year, clock.month, clock.day, clock.hour, clock.minute, clock.second); + + LV_LOG_USER("Track file %s opening...", filepath); + + lv_fs_res_t res = lv_fs_open(&(_file), filepath, LV_FS_MODE_WR); + + if (res != LV_FS_RES_OK) { + LV_LOG_ERROR("failed %d", res); + showToast(_("OPEN_FILE_FAILED")); + return false; + } + + GPX* gpx = &_gpx; + lv_fs_file_t* file_p = &(_file); + + gpx->setMetaName(String(versionInfo.name) + " " + versionInfo.software); + gpx->setMetaDesc(versionInfo.website); + gpx->setName(filepath); + gpx->setDesc(""); + + writeFile(file_p, gpx->getOpen().c_str()); + writeFile(file_p, gpx->getMetaData().c_str()); + writeFile(file_p, gpx->getTrakOpen().c_str()); + writeFile(file_p, gpx->getInfo().c_str()); + writeFile(file_p, gpx->getTrakSegOpen().c_str()); + + _recInfo.active = true; + return true; +} + +bool DP_Recorder::recStop() +{ + if (!_recInfo.active) { + return false; + } + + GPX* gpx = &_gpx; + lv_fs_file_t* file_p = &(_file); + + writeFile(file_p, gpx->getTrakSegClose().c_str()); + writeFile(file_p, gpx->getTrakClose().c_str()); + writeFile(file_p, gpx->getClose().c_str()); + lv_fs_close(file_p); + + _recInfo.active = false; + return true; +} + +void DP_Recorder::setEnv(const char* value) +{ + _env.set("rec", value); +} + +int DP_Recorder::notifyFilter(bool active) +{ + TrackFilter_Info_t info; + info.active = active; + return _node->notify("TrackFilter", &info, sizeof(info)); +} + +DATA_PROC_DESCRIPTOR_DEF(Recorder) diff --git a/x_track/src/App/Service/DataProc/DP_SportStatus.cpp b/x_track/src/App/Service/DataProc/DP_SportStatus.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2921a39134fdc21786bca90385e3262f037b33a --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_SportStatus.cpp @@ -0,0 +1,225 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Service/HAL/HAL_Log.h" +#include "Utils/Filters/Filters.h" +#include "Utils/Geo/Geo.h" + +/* clang-format off */ + +#define CALORIC_CORFFICIENT 0.5f + +#define CADENCE_TIMEOUT_MS (3000) // 20rpm + +#define MPS_TO_KPH(x) ((x) * 3.6f) +#define MPS_TO_MPH(x) ((x) * 2.2369362920544f) + +/* clang-format on */ + +using namespace DataProc; + +class DP_SportStatus { +public: + DP_SportStatus(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeGNSS; + SportStatus_Info_t _sportStatus; + bool _isDistanceFirst; + double _preLongitude; + double _preLatitude; + +private: + int onEvent(DataNode::EventParam_t* param); + void onTimer(); + int onNotify(const SportStatus_Info_t* info); + double getDistanceOffset(const HAL::GNSS_Info_t* gnssInfo); +}; + +DP_SportStatus::DP_SportStatus(DataNode* node) + : _node(node) + , _nodeGNSS(nullptr) + , _isDistanceFirst(true) + , _preLongitude(0.0f) + , _preLatitude(0.0f) +{ + _nodeGNSS = node->subscribe("GNSS"); + +#define SPORT_STORAGE(MEMBER) storage.add(#MEMBER, &_sportStatus.MEMBER) + + Storage_Helper storage(node); + + storage.structStart("sportStatus"); + SPORT_STORAGE(totalDistance); + storage.addArray("totalTime", &_sportStatus.totalTime, sizeof(uint32_t), 2, STORAGE_TYPE::INT); + SPORT_STORAGE(speedMaxKph); + SPORT_STORAGE(weight); + SPORT_STORAGE(longitude); + SPORT_STORAGE(latitude); + storage.structEnd(); + + _sportStatus.weight = CONFIG_WEIGHT_DEFAULT; + _sportStatus.longitude = CONFIG_GNSS_LONGITUDE_DEFAULT; + _sportStatus.latitude = CONFIG_GNSS_LATITUDE_DEFAULT; + _sportStatus.lastTick = HAL::GetTick(); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_SportStatus*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL | DataNode::EVENT_TIMER | DataNode::EVENT_NOTIFY); + + node->startTimer(500); +} + +int DP_SportStatus::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_NOTIFY: + if (param->size != sizeof(SportStatus_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + return onNotify((SportStatus_Info_t*)param->data_p); + + case DataNode::EVENT_PULL: + if (param->size != sizeof(SportStatus_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + memcpy(param->data_p, &_sportStatus, sizeof(SportStatus_Info_t)); + break; + + case DataNode::EVENT_TIMER: + onTimer(); + break; + + default: + break; + } + + return DataNode::RES_OK; +} + +void DP_SportStatus::onTimer() +{ + /* GPS */ + HAL::GNSS_Info_t gnssInfo; + if (_node->pull(_nodeGNSS, &gnssInfo, sizeof(gnssInfo)) != DataNode::RES_OK) { + return; + } + + uint32_t timeElaps = HAL::GetTickElaps(_sportStatus.lastTick); + + float speedKph = 0.0f; + bool isSignaLost = (gnssInfo.isVaild && (gnssInfo.satellites == 0)); + + /* Only valid latitude and longitude are recorded */ + if (gnssInfo.isVaild) { + _sportStatus.longitude = gnssInfo.longitude; + _sportStatus.latitude = gnssInfo.latitude; + _sportStatus.altitude = gnssInfo.altitude; + } + + if (gnssInfo.satellites >= 3) { + float spd = gnssInfo.speed; + speedKph = spd > 1 ? spd : 0; + } + + if (speedKph > 0.0f || isSignaLost) { + _sportStatus.singleTime += timeElaps; + _sportStatus.totalTime += timeElaps; + + if (speedKph > 0.0f) { + float dist = getDistanceOffset(&gnssInfo); + + _sportStatus.singleDistance += dist; + _sportStatus.totalDistance += dist; + + float meterPerSec = _sportStatus.singleDistance * 1000 / _sportStatus.singleTime; + _sportStatus.speedAvgKph = MPS_TO_KPH(meterPerSec); + + if (speedKph > _sportStatus.speedMaxKph) { + _sportStatus.speedMaxKph = speedKph; + } + + float calorie = speedKph * _sportStatus.weight * CALORIC_CORFFICIENT * timeElaps / 1000 / 3600; + _sportStatus.singleCalorie += calorie; + } + } + + _sportStatus.speedKph = speedKph; + + _sportStatus.lastTick = HAL::GetTick(); + + _node->publish(&_sportStatus, sizeof(SportStatus_Info_t)); +} + +int DP_SportStatus::onNotify(const SportStatus_Info_t* info) +{ + switch (info->cmd) { + case SPORT_STATUS_CMD::RESET_SINGLE: + _sportStatus.singleDistance = 0; + _sportStatus.singleCalorie = 0; + _sportStatus.singleTime = 0; + break; + case SPORT_STATUS_CMD::RESET_TOTAL: + _sportStatus.totalDistance = 0; + _sportStatus.totalTime = 0; + break; + case SPORT_STATUS_CMD::RESET_SPEED_MAX: + _sportStatus.speedMaxKph = 0; + break; + case SPORT_STATUS_CMD::SET_WEIGHT: + _sportStatus.weight = info->weight; + break; + default: + return DataNode::RES_PARAM_ERROR; + } + + return DataNode::RES_OK; +} + +double DP_SportStatus::getDistanceOffset(const HAL::GNSS_Info_t* gnssInfo) +{ + double offset = 0.0f; + + if (!_isDistanceFirst) { + offset = Geo::distanceBetween( + gnssInfo->latitude, + gnssInfo->longitude, + _preLatitude, + _preLongitude); + } else { + _isDistanceFirst = false; + } + + _preLongitude = gnssInfo->longitude; + _preLatitude = gnssInfo->latitude; + + return offset; +} + +DATA_PROC_DESCRIPTOR_DEF(SportStatus) diff --git a/x_track/src/App/Service/DataProc/DP_Storage.cpp b/x_track/src/App/Service/DataProc/DP_Storage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2106d935a3fb8267facbd1a3ba5e32b010ab05de --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Storage.cpp @@ -0,0 +1,222 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERDP_Storage + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Service/HAL/HAL.h" +#include "Utils/StorageService/StorageService.h" +#include "lvgl/lvgl.h" + +/* System configuration file */ +#define SYSTEM_SAVE_PATH RESOURCE_MAKE_PATH("/SystemSave.json") +#define SYSTEM_SAVE_BACKUP_DIR RESOURCE_MAKE_PATH("/Backup") +#define SYSTEM_SAVE_BACKUP_FMT SYSTEM_SAVE_BACKUP_DIR "/SystemSave_%d%02d%02d_%02d%02d%02d.json" + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) + +using namespace DataProc; + +class DP_Storage { +public: + DP_Storage(DataNode* node); + +public: + DataNode* _node; + const DataNode* _nodeGlobal; + Env_Helper _env; + StorageService _service; + DeviceObject* _dev; + +public: + int onEvent(DataNode::EventParam_t* param); + int onNotify(Storage_Info_t* info); + int onSdCardMount(bool isMount); + const char* getTimeString(const char* format, char* buf, size_t size); +}; + +DP_Storage::DP_Storage(DataNode* node) + : _node(node) + , _env(node) + , _service(SYSTEM_SAVE_PATH) +{ + _dev = HAL::Manager()->getDevice("SdCard"); + if (!_dev) { + return; + } + + /* create backup dir */ + const char* backupPath = SYSTEM_SAVE_BACKUP_DIR; + _dev->ioctl(SDCARD_IOCMD_MKDIR, (void*)backupPath, sizeof(backupPath)); + + node->subscribe("Clock"); + _nodeGlobal = node->subscribe("Global"); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Storage*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL | DataNode::EVENT_NOTIFY | DataNode::EVENT_PUBLISH); +} + +int DP_Storage::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_PULL: { + if (param->size != sizeof(Storage_Device_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + Storage_Device_Info_t* info = (Storage_Device_Info_t*)param->data_p; + HAL::SdCard_Info_t sdInfo; + if (_dev->read(&sdInfo, sizeof(sdInfo)) != sizeof(sdInfo)) { + return DataNode::RES_NO_DATA; + } + + info->isDetect = sdInfo.isInsert; + info->isActive = sdInfo.isActive; + info->totalSize = sdInfo.totalCapacity; + info->freeSize = sdInfo.freeCapacity; + } break; + + case DataNode::EVENT_NOTIFY: { + if (param->size != sizeof(Storage_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + Storage_Info_t* info = (Storage_Info_t*)param->data_p; + return onNotify(info); + } break; + + case DataNode::EVENT_PUBLISH: { + if (param->tran == _env) { + auto envInfo = (DataProc::Env_Info_t*)param->data_p; + if (IS_STR_EQ(envInfo->key, "storage")) { + Storage_Info_t info; + if (IS_STR_EQ(envInfo->value, "save")) { + info.cmd = STORAGE_CMD::SAVE; + } else if (IS_STR_EQ(envInfo->value, "load")) { + info.cmd = STORAGE_CMD::LOAD; + } else { + return DataNode::RES_PARAM_ERROR; + } + + return onNotify(&info); + } + } + + if (param->tran == _nodeGlobal) { + auto globalInfo = (const DataProc::Global_Info_t*)param->data_p; + + /* Load data after initialization */ + if (globalInfo->event == DataProc::GLOBAL_EVENT::DATA_PROC_INIT_FINISHED) { + Storage_Info_t info; + info.cmd = STORAGE_CMD::LOAD; + + /* Unsubscribe global data node */ + _node->unsubscribe("Global"); + _nodeGlobal = nullptr; + return onNotify(&info); + } + } + } break; + + default: + break; + } + + return DataNode::RES_OK; +} + +int DP_Storage::onNotify(Storage_Info_t* info) +{ + switch (info->cmd) { + case STORAGE_CMD::LOAD: { + if (_service.load()) { + _node->publish(info, sizeof(Storage_Info_t)); + } else { + LV_LOG_WARN("Load " SYSTEM_SAVE_PATH " error"); + } + } break; + + case STORAGE_CMD::SAVE: { + bool ret = _service.save(); + LV_LOG_USER("Saving file '" SYSTEM_SAVE_PATH "', ret: %d", ret); + + char buf[128]; + const char* timeStr = getTimeString(SYSTEM_SAVE_BACKUP_FMT, buf, sizeof(buf)); + ret = _service.save(timeStr); + LV_LOG_USER("Saving backup file '%s', ret: %d", timeStr, ret); + } break; + + case STORAGE_CMD::ADD: + _service.add( + info->key, + info->value, + info->size, + (StorageService::TYPE)info->type); + break; + case STORAGE_CMD::MOUNT: + case STORAGE_CMD::UNMOUNT: + return onSdCardMount(info->cmd == STORAGE_CMD::MOUNT); + + default: + break; + } + + return DataNode::RES_OK; +} + +int DP_Storage::onSdCardMount(bool isMount) +{ + int ret = isMount ? _dev->ioctl(SDCARD_IOCMD_MOUNT) : _dev->ioctl(SDCARD_IOCMD_UNMOUNT); + LV_LOG_WARN("isMount: %d, ret = %d", isMount, ret); + + return (ret == DeviceObject::RES_OK) ? DataNode::RES_OK : DataNode::RES_UNKNOWN; +} + +const char* DP_Storage::getTimeString(const char* format, char* buf, size_t size) +{ + HAL::Clock_Info_t clock; + if (_node->pull("Clock", &clock, sizeof(clock)) != DataNode::RES_OK) { + return nullptr; + } + + int retval = lv_snprintf( + buf, + size, + format, + clock.year, + clock.month, + clock.day, + clock.hour, + clock.minute, + clock.second); + + if (retval < 0 || retval >= (int)size) { + return nullptr; + } + + return buf; +} + +DATA_PROC_DESCRIPTOR_DEF(Storage) diff --git a/x_track/src/App/Service/DataProc/DP_SunRise.cpp b/x_track/src/App/Service/DataProc/DP_SunRise.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89bbd9578530873e2127b3cd20490d710f3dd175 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_SunRise.cpp @@ -0,0 +1,158 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Utils/SunRiseCalc/SunRiseCalc.h" + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) + +using namespace DataProc; + +class DP_SunRise { +public: + DP_SunRise(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeClock; + Env_Helper _env; + SunRise_Info_t _info; + +private: + int onEvent(DataNode::EventParam_t* param); + int onClockEvent(const HAL::Clock_Info_t* clock); + SunRise_Info_t getInfo(const HAL::Clock_Info_t* clock); + SUNRISE_STATE compare(const HAL::Clock_Info_t* clock, const SunRise_Info_t* sunRise); +}; + +DP_SunRise::DP_SunRise(DataNode* node) + : _node(node) + , _env(node) +{ + node->subscribe("SportStatus"); + _nodeClock = node->subscribe("Clock"); + + _node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_SunRise*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL | DataNode::EVENT_PUBLISH); +} + +int DP_SunRise::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_PULL: { + if (param->size != sizeof(SunRise_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + auto info = (SunRise_Info_t*)param->data_p; + + if (_info.state != SUNRISE_STATE::UNKNOWN) { + /* use the cached value */ + *info = _info; + return DataNode::RES_OK; + } + + HAL::Clock_Info_t clockInfo; + if (_node->pull(_nodeClock, &clockInfo, sizeof(clockInfo)) != DataNode::RES_OK) { + return DataNode::RES_NO_DATA; + } + + *info = getInfo(&clockInfo); + } break; + + case DataNode::EVENT_PUBLISH: + if (param->tran == _nodeClock) { + return onClockEvent((HAL::Clock_Info_t*)param->data_p); + } else if (param->tran == _env) { + auto envInfo = (const Env_Info_t*)param->data_p; + + /* when timezone changed, reset the state */ + if (IS_STR_EQ(envInfo->key, "timeZone")) { + _info.state = SUNRISE_STATE::UNKNOWN; + } + } + break; + + default: + return DataNode::RES_UNSUPPORTED_REQUEST; + } + + return DataNode::RES_OK; +} + +int DP_SunRise::onClockEvent(const HAL::Clock_Info_t* clock) +{ + if (_info.state == SUNRISE_STATE::UNKNOWN) { + _info = getInfo(clock); + _node->publish(&_info, sizeof(_info)); + return DataNode::RES_OK; + } + + /* compare the state */ + auto newState = compare(clock, &_info); + if (newState != _info.state) { + _info.state = newState; + _node->publish(&_info, sizeof(_info)); + } + + return DataNode::RES_OK; +} + +SunRise_Info_t DP_SunRise::getInfo(const HAL::Clock_Info_t* clock) +{ + SunRise_Info_t result; + + SportStatus_Info_t sportStatus; + if (_node->pull("SportStatus", &sportStatus, sizeof(sportStatus)) == DataNode::RES_OK) { + SunRiseSunSetCalculator( + _env.getInt("timeZone"), + clock->year, + clock->month, + clock->day, + sportStatus.longitude, + sportStatus.latitude, + &result.sunriseHour, + &result.sunriseMinute, + &result.sunsetHour, + &result.sunsetMinute); + + result.state = compare(clock, &result); + } + + return result; +} + +SUNRISE_STATE DP_SunRise::compare(const HAL::Clock_Info_t* clock, const SunRise_Info_t* sunRise) +{ + if ((clock->hour > sunRise->sunriseHour || (clock->hour == sunRise->sunriseHour && clock->minute >= sunRise->sunriseMinute)) + && (clock->hour < sunRise->sunsetHour || (clock->hour == sunRise->sunsetHour && clock->minute < sunRise->sunsetMinute))) { + return SUNRISE_STATE::DAY; + } + + return SUNRISE_STATE::NIGHT; +} + +DATA_PROC_DESCRIPTOR_DEF(SunRise) diff --git a/x_track/src/App/Service/DataProc/DP_Theme.cpp b/x_track/src/App/Service/DataProc/DP_Theme.cpp new file mode 100644 index 0000000000000000000000000000000000000000..342f4c6891a509e334b547a15a38bddbca73935a --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Theme.cpp @@ -0,0 +1,184 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "UI/Resource/ResourcePool.h" +#include "lvgl/src/lvgl_private.h" +#include <cstdlib> + +#define THEME_DARK_COLOR_PRIMARY lv_color_hex(0xEB5E00) +#define THEME_DARK_COLOR_SECONDARY lv_color_hex(0xEA5455) +#define THEME_LIGHT_COLOR_PRIMARY lv_palette_main(LV_PALETTE_BLUE) +#define THEME_LIGHT_COLOR_SECONDARY lv_palette_main(LV_PALETTE_RED) + +#define THEME_NAME "theme" +#define THEME_DARK_NAME "dark" +#define THEME_LIGHT_NAME "light" +#define THEME_AUTO_NAME "auto" +#define DISP_ROTATION_NAME "disp-rotation" + +#define THEME_FONT_SMALL "<12>regular" +#define THEME_FONT_NORMAL "<16>regular" +#define THEME_FONT_LARGE "<20>regular" + +#define THEME_FONTAWESOME_SMALL "<12>awesome" +#define THEME_FONTAWESOME_NORMAL "<16>awesome" +#define THEME_FONTAWESOME_LARGE "<20>awesome" + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) + +using namespace DataProc; + +class DP_Theme { +public: + DP_Theme(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeStorage; + const DataNode* _nodeSunRise; + Env_Helper _env; + char _themeName[8]; + int _dispRotation; + int8_t _isDark; + ResourcePool::Font _fontSmall; + ResourcePool::Font _fontNormal; + ResourcePool::Font _fontLarge; + ResourcePool::Font _fontAwesomeSmall; + ResourcePool::Font _fontAwesomeNormal; + ResourcePool::Font _fontAwesomeLarge; + lv_font_t _fontSmallHandle; + lv_font_t _fontNormalHandle; + lv_font_t _fontLargeHandle; + +private: + int onEvent(DataNode::EventParam_t* param); + void updateTheme(bool isDark); +}; + +DP_Theme::DP_Theme(DataNode* node) + : _node(node) + , _nodeStorage(nullptr) + , _nodeSunRise(nullptr) + , _env(node) + , _themeName(THEME_DARK_NAME) + , _isDark(-1) + , _fontSmall(THEME_FONT_SMALL) + , _fontNormal(THEME_FONT_NORMAL) + , _fontLarge(THEME_FONT_LARGE) + , _fontAwesomeSmall(THEME_FONTAWESOME_SMALL) + , _fontAwesomeNormal(THEME_FONTAWESOME_NORMAL) + , _fontAwesomeLarge(THEME_FONTAWESOME_LARGE) +{ + _nodeStorage = node->subscribe("Storage"); + _nodeSunRise = node->subscribe("SunRise"); + + Storage_Helper storage(node); + storage.add(THEME_NAME, _themeName, sizeof(_themeName), STORAGE_TYPE::STRING); + storage.add(DISP_ROTATION_NAME, &_dispRotation, sizeof(_dispRotation), STORAGE_TYPE::INT); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Theme*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PUBLISH); + + lv_display_add_event_cb( + lv_display_get_default(), + [](lv_event_t* e) { + auto self = (DP_Theme*)lv_event_get_user_data(e); + auto disp = (lv_disp_t*)lv_event_get_current_target(e); + self->_dispRotation = lv_disp_get_rotation(disp); + }, + LV_EVENT_RESOLUTION_CHANGED, + this); + + /* Initialize font handles */ + _fontSmallHandle = *_fontSmall; + _fontSmallHandle.fallback = _fontAwesomeSmall; + _fontNormalHandle = *_fontNormal; + _fontNormalHandle.fallback = _fontAwesomeNormal; + _fontLargeHandle = *_fontLarge; + _fontLargeHandle.fallback = _fontAwesomeLarge; + + updateTheme(true); +} + +int DP_Theme::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _env) { + auto info = (const Env_Info_t*)param->data_p; + + if (IS_STR_EQ(info->key, THEME_NAME)) { + if (info->value != _themeName) { + strncpy(_themeName, info->value, sizeof(_themeName) - 1); + } + + bool isDark; + if (IS_STR_EQ(info->value, THEME_AUTO_NAME)) { + SunRise_Info_t sunRiseInfo; + _node->pull(_nodeSunRise, &sunRiseInfo, sizeof(sunRiseInfo)); + isDark = sunRiseInfo.state == SUNRISE_STATE::NIGHT; + } else { + isDark = IS_STR_EQ(info->value, THEME_DARK_NAME); + } + updateTheme(isDark); + } + } else if (param->tran == _nodeStorage) { + auto info = (const Storage_Info_t*)param->data_p; + + if (info->cmd != STORAGE_CMD::LOAD) { + return DataNode::RES_UNSUPPORTED_REQUEST; + } + + _env.set(THEME_NAME, _themeName); + lv_disp_set_rotation(nullptr, (lv_disp_rotation_t)_dispRotation); + } else if (param->tran == _nodeSunRise) { + if (IS_STR_EQ(_themeName, THEME_AUTO_NAME)) { + auto info = (const SunRise_Info_t*)param->data_p; + updateTheme(info->state == SUNRISE_STATE::NIGHT); + } + } + + return DataNode::RES_OK; +} + +void DP_Theme::updateTheme(bool isDark) +{ + /* Update theme only when the theme is changed */ + if (_isDark == isDark) { + return; + } + + _isDark = isDark; + + lv_color_t color_primary = isDark ? THEME_DARK_COLOR_PRIMARY : THEME_LIGHT_COLOR_PRIMARY; + lv_color_t color_secondary = isDark ? THEME_DARK_COLOR_SECONDARY : THEME_LIGHT_COLOR_SECONDARY; + + lv_theme_t* def_theme = lv_theme_default_init(nullptr, color_primary, color_secondary, isDark, LV_FONT_DEFAULT); + def_theme->font_small = &_fontSmallHandle; + def_theme->font_normal = &_fontNormalHandle; + def_theme->font_large = &_fontLargeHandle; +} + +DATA_PROC_DESCRIPTOR_DEF(Theme) diff --git a/x_track/src/App/Service/DataProc/DP_Toast.cpp b/x_track/src/App/Service/DataProc/DP_Toast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e90ab2e83a5f44cc96c38686f85aa102fc39def --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Toast.cpp @@ -0,0 +1,102 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Frameworks/PageManager/PageManager.h" +#include "UI/Resource/ResourcePool.h" +#include "Utils/lv_toast/lv_toast.h" + +using namespace DataProc; + +class DP_Toast { +public: + DP_Toast(DataNode* node); + +private: + const DataNode* _nodeGlobal; + lv_obj_t* _toast; + lv_style_t _style; + ResourcePool::Font _font; + +private: + int onEvent(DataNode::EventParam_t* param); +}; + +DP_Toast::DP_Toast(DataNode* node) + : _toast(nullptr) + , _font(16, "bold") +{ + _nodeGlobal = node->subscribe("Global"); + + lv_style_init(&_style); + lv_style_set_radius(&_style, LV_RADIUS_CIRCLE); + lv_style_set_margin_top(&_style, 10); + lv_style_set_bg_color(&_style, lv_color_black()); + lv_style_set_bg_opa(&_style, LV_OPA_60); + lv_style_set_border_width(&_style, 0); + lv_style_set_text_color(&_style, lv_color_white()); + lv_style_set_text_font(&_style, _font); + + _toast = lv_toast_create(lv_layer_top()); + lv_toast_set_cont_style(_toast, &_style); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Toast*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_NOTIFY | DataNode::EVENT_PUBLISH); +} + +int DP_Toast::onEvent(DataNode::EventParam_t* param) +{ + switch (param->event) { + case DataNode::EVENT_NOTIFY: { + if (param->size != sizeof(Toast_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + auto info = (const Toast_Info_t*)param->data_p; + lv_toast_show_text(_toast, info->txt, info->duration); + } break; + + case DataNode::EVENT_PUBLISH: { + if (param->tran == _nodeGlobal) { + auto info = (const Global_Info_t*)param->data_p; + if (info->event == GLOBAL_EVENT::PAGE_MANAGER_INIT_FINISHED) { + auto manager = (PageManager*)info->param; + + /* Change the parent of the toast to the top layer of the page manager */ + lv_obj_set_parent(_toast, manager->getLayerTop()); + } + } + } break; + + default: + return DataNode::RES_UNSUPPORTED_REQUEST; + } + + return DataNode::RES_OK; +} + +DATA_PROC_DESCRIPTOR_DEF(Toast) diff --git a/x_track/src/App/Service/DataProc/DP_TrackFilter.cpp b/x_track/src/App/Service/DataProc/DP_TrackFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ee0174e75c655f1625299514e64755ffc51a483 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_TrackFilter.cpp @@ -0,0 +1,170 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Utils/MapConv/MapConv.h" +#include "Utils/PointContainer/PointContainer.h" +#include "Utils/TrackPointFilter/TrackPointFilter.h" +#include "lvgl/lvgl.h" +#include <vector> + +#define FILTER_LEVEL 16 + +using namespace DataProc; + +class DP_TrackFilter { +public: + DP_TrackFilter(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeGNSS; + const DataNode* _nodeMapInfo; + PointContainer* _pointContainer; + bool _isActive; + MapConv _mapConv; + TrackPointFilter _pointFilter; + +private: + int onEvent(DataNode::EventParam_t* param); + bool onNotify(const TrackFilter_Info_t* info); + void onGNSSPublish(const HAL::GNSS_Info_t* gnssInfo); +}; + +DP_TrackFilter::DP_TrackFilter(DataNode* node) + : _node(node) + , _nodeGNSS(nullptr) + , _pointContainer(nullptr) + , _isActive(false) + , _mapConv(true, FILTER_LEVEL) +{ + _nodeGNSS = node->subscribe("GNSS"); + if (!_nodeGNSS) { + return; + } + + _nodeMapInfo = node->subscribe("MapInfo"); + + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_TrackFilter*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PUBLISH | DataNode::EVENT_PULL | DataNode::EVENT_NOTIFY); +} + +int DP_TrackFilter::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeGNSS) { + onGNSSPublish((HAL::GNSS_Info_t*)param->data_p); + return DataNode::RES_OK; + } + + if (param->size != sizeof(TrackFilter_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + switch (param->event) { + case DataNode::EVENT_PULL: { + TrackFilter_Info_t* info = (TrackFilter_Info_t*)param->data_p; + info->active = _isActive; + info->level = FILTER_LEVEL; + info->pointCont = _pointContainer; + } break; + case DataNode::EVENT_NOTIFY: + if (onNotify((TrackFilter_Info_t*)param->data_p)) { + + /* publish status */ + TrackFilter_Info_t info; + info.active = _isActive; + info.level = FILTER_LEVEL; + info.pointCont = _pointContainer; + _node->publish(&info, sizeof(info)); + } + break; + + default: + break; + } + + return DataNode::RES_OK; +} + +bool DP_TrackFilter::onNotify(const TrackFilter_Info_t* info) +{ + if (info->active) { + /* check already started */ + if (_pointContainer) { + LV_LOG_WARN("Track filter already started"); + return false; + } + + /* start */ + _pointContainer = new PointContainer; + _pointFilter.reset(); + _isActive = true; + + /* get map info */ + Map_Info_t mapInfo; + if (_node->pull(_nodeMapInfo, &mapInfo, sizeof(mapInfo)) == DataNode::RES_OK) { + _mapConv.setCoordTransformEnable(mapInfo.coordTrans); + } + + LV_LOG_USER("Track filter start"); + return true; + } + + if (!_pointContainer) { + LV_LOG_WARN("NOT started"); + return false; + } + + _isActive = false; + delete _pointContainer; + _pointContainer = nullptr; + + uint32_t sum = 0, output = 0; + _pointFilter.getCounts(&sum, &output); + LV_LOG_USER( + "Track filter stop, " + "filted(%" LV_PRIu32 "%%): sum = %" LV_PRIu32 ", output = %" LV_PRIu32, + sum ? (100 - output * 100 / sum) : 0, + sum, + output); + + return true; +} + +void DP_TrackFilter::onGNSSPublish(const HAL::GNSS_Info_t* gnssInfo) +{ + if (!_isActive) { + return; + } + + MapConv::Point_t point = _mapConv.getCoordinate(gnssInfo->longitude, gnssInfo->latitude); + + if (_pointFilter.pushPoint(point.x, point.y)) { + _pointContainer->pushPoint(point.x, point.y); + } +} + +DATA_PROC_DESCRIPTOR_DEF(TrackFilter); diff --git a/x_track/src/App/Service/DataProc/DP_Version.cpp b/x_track/src/App/Service/DataProc/DP_Version.cpp new file mode 100644 index 0000000000000000000000000000000000000000..014d113f90ca7d8596f1fee4d5aa80f68cdab237 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_Version.cpp @@ -0,0 +1,125 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "../HAL/HAL_Log.h" +#include "DataProc.h" +#include "Version.h" + +/* clang-format off */ + +/* Number to string macro */ +#define _VERSION_NUM_TO_STR_(n) #n +#define VERSION_NUM_TO_STR(n) _VERSION_NUM_TO_STR_(n) + +/* Compiler Version */ +#if defined(_MSC_FULL_VER) +# define VERSION_COMPILER "MSVC v" VERSION_NUM_TO_STR(_MSC_FULL_VER) +#elif defined(__ARMCC_VERSION) +# define VERSION_COMPILER "ARMCC v" VERSION_NUM_TO_STR(__ARMCC_VERSION) +#elif defined(__GNUC__) +# define VERSION_COMPILER "GCC v"\ + VERSION_NUM_TO_STR(__GNUC__)\ + "."\ + VERSION_NUM_TO_STR(__GNUC_MINOR__)\ + "."\ + VERSION_NUM_TO_STR(__GNUC_PATCHLEVEL__) +#else +# define VERSION_COMPILER "UNKNOW" +#endif + +/* LVGL Version */ +#include "lvgl/lvgl.h" +#define VERSION_GRAPHICS "LVGL v"\ + VERSION_NUM_TO_STR(LVGL_VERSION_MAJOR)\ + "."\ + VERSION_NUM_TO_STR(LVGL_VERSION_MINOR)\ + "."\ + VERSION_NUM_TO_STR(LVGL_VERSION_PATCH)\ + " "\ + LVGL_VERSION_INFO + +/* clang-format on */ + +using namespace DataProc; + +class DP_Version { +public: + DP_Version(DataNode* node); + +private: + int onEvent(DataNode::EventParam_t* param); + void getInfo(Version_Info_t* info); + void dumpInfo(const Version_Info_t* info); +}; + +DP_Version::DP_Version(DataNode* node) +{ + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Version*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL); + + Version_Info_t version; + getInfo(&version); + dumpInfo(&version); +} + +int DP_Version::onEvent(DataNode::EventParam_t* param) +{ + if (param->size != sizeof(Version_Info_t)) { + return DataNode::RES_SIZE_MISMATCH; + } + + auto info = (Version_Info_t*)param->data_p; + getInfo(info); + + return DataNode::RES_OK; +} + +void DP_Version::getInfo(Version_Info_t* info) +{ + info->name = VERSION_FIRMWARE_NAME; + info->software = VERSION_SOFTWARE; + info->hardware = VERSION_HARDWARE; + info->author = VERSION_AUTHOR_NAME; + info->website = VERSION_WEBSITE; + info->graphics = VERSION_GRAPHICS; + info->compiler = VERSION_COMPILER; + info->buildDate = __DATE__; + info->buildTime = __TIME__; +} + +void DP_Version::dumpInfo(const Version_Info_t* info) +{ + HAL_LOG_INFO("Firmware: %s", info->name); + HAL_LOG_INFO("Software: %s", info->software); + HAL_LOG_INFO("Hardware: %s", info->hardware); + HAL_LOG_INFO("Author: %s", info->author); + HAL_LOG_INFO("Website: %s", info->website); + HAL_LOG_INFO("Graphics: %s", info->graphics); + HAL_LOG_INFO("Compiler: %s", info->compiler); + HAL_LOG_INFO("Build Time: %s %s", info->buildDate, info->buildTime); +} + +DATA_PROC_DESCRIPTOR_DEF(Version) diff --git a/x_track/src/App/Service/DataProc/DP_i18n.cpp b/x_track/src/App/Service/DataProc/DP_i18n.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e644648bcfdfb4efb9e9c119696aede754c10633 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DP_i18n.cpp @@ -0,0 +1,100 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "DataProc.h" +#include "Service/i18n/lv_i18n.h" +#include "lvgl/lvgl.h" + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) +#define LANGUAGE_STR "language" + +using namespace DataProc; + +class DP_i18n { +public: + DP_i18n(DataNode* node); + +private: + DataNode* _node; + const DataNode* _nodeEnv; + const DataNode* _nodeStorage; + char _language[8]; + +private: + int onEvent(DataNode::EventParam_t* param); +}; + +DP_i18n::DP_i18n(DataNode* node) + : _node(node) + , _nodeEnv(nullptr) + , _language { CONFIG_LANGUAGE_DEFAULT } +{ + lv_i18n_init(lv_i18n_language_pack); + + _nodeEnv = node->subscribe("Env"); + _nodeStorage = node->subscribe("Storage"); + node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_i18n*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PUBLISH); + + Storage_Helper storage(node); + storage.add(LANGUAGE_STR, _language, sizeof(_language), STORAGE_TYPE::STRING); + + if (lv_i18n_set_locale(_language) != 0) { + LV_LOG_ERROR("set locale '%s' failed", _language); + } +} + +int DP_i18n::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeEnv) { + auto info = (Env_Info_t*)param->data_p; + if (IS_STR_EQ(info->key, LANGUAGE_STR)) { + if (lv_i18n_set_locale(info->value) != 0) { + LV_LOG_ERROR("set locale '%s' failed", info->value); + return DataNode::RES_PARAM_ERROR; + } + + /* fix strncpy-param-overlap */ + if (info->value != _language) { + strncpy(_language, info->value, sizeof(_language) - 1); + } + LV_LOG_USER("set locale to %s", info->value); + } + } else if (param->tran == _nodeStorage) { + auto info = (Storage_Info_t*)param->data_p; + /* load language */ + if (info->cmd == STORAGE_CMD::LOAD) { + Env_Info_t envInfo; + envInfo.key = LANGUAGE_STR; + envInfo.value = _language; + _node->notify(_nodeEnv, &envInfo, sizeof(Env_Info_t)); + } + } + return DataNode::RES_OK; +} + +DATA_PROC_DESCRIPTOR_DEF(i18n) diff --git a/x_track/src/App/Service/DataProc/DataProc.cpp b/x_track/src/App/Service/DataProc/DataProc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ca5d2c2a5608c979229488a7b240723a6f724838 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DataProc.cpp @@ -0,0 +1,53 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" +#include "Service/HAL/HAL.h" + +static DataBroker* DataProcBroker = nullptr; + +void DataProc_Init(DataBroker* broker) +{ + DataProcBroker = broker; + + broker->initTimerManager(HAL::GetTick); + +/* Create DataNode */ +#define DP_DEF(NAME) \ + DataNode* node##NAME = new DataNode(#NAME, broker); +#include "DataProc_NodeList.inc" +#undef DP_DEF + +/* Init DataNode */ +#define DP_DEF(NAME) \ + do { \ + void DP_##NAME##_Init(DataNode* node); \ + DP_##NAME##_Init(node##NAME); \ + } while (0) +#include "DataProc_NodeList.inc" +#undef DP_DEF +} + +DataBroker* DataProc::broker() +{ + return DataProcBroker; +} diff --git a/x_track/src/App/Service/DataProc/DataProc.h b/x_track/src/App/Service/DataProc/DataProc.h new file mode 100644 index 0000000000000000000000000000000000000000..c4a7a158d1ff8fcd300603cc199f9cb6586eb098 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DataProc.h @@ -0,0 +1,47 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_H +#define __DATA_PROC_H + +#include "DataProc_Def.h" +#include "DataProc_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" +#include "Service/HAL/HAL_Def.h" +#include <cstring> + +#define DATA_PROC_DESCRIPTOR_DEF(NAME) \ + void DP_##NAME##_Init(DataNode* node) \ + { \ + static DP_##NAME ctx(node); \ + node->setUserData(&ctx); \ + } + +void DataProc_Init(DataBroker* broker); + +namespace DataProc { + +DataBroker* broker(); + +} + +#endif diff --git a/x_track/src/App/Service/DataProc/DataProc_Def.h b/x_track/src/App/Service/DataProc/DataProc_Def.h new file mode 100644 index 0000000000000000000000000000000000000000..af9fbc5f5a2cc204f6d33fef52e8fd92f96bdf3f --- /dev/null +++ b/x_track/src/App/Service/DataProc/DataProc_Def.h @@ -0,0 +1,43 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_DEF_H +#define __DATA_PROC_DEF_H + +#include "Def/DP_Backlight.h" +#include "Def/DP_Env.h" +#include "Def/DP_FeedbackGen.h" +#include "Def/DP_GNSS.h" +#include "Def/DP_Global.h" +#include "Def/DP_MapInfo.h" +#include "Def/DP_PageNavi.h" +#include "Def/DP_Power.h" +#include "Def/DP_Recorder.h" +#include "Def/DP_Slope.h" +#include "Def/DP_SportStatus.h" +#include "Def/DP_Storage.h" +#include "Def/DP_SunRise.h" +#include "Def/DP_Toast.h" +#include "Def/DP_TrackFilter.h" +#include "Def/DP_Version.h" + +#endif // __DATA_PROC_DEF_H diff --git a/x_track/src/App/Service/DataProc/DataProc_Helper.h b/x_track/src/App/Service/DataProc/DataProc_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..2dd8691cca87d73dc1f9f0c1e4c0cc26497d17b0 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DataProc_Helper.h @@ -0,0 +1,34 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_HELPER_H +#define __DATA_PROC_HELPER_H + +#include "Helper/Env_Helper.h" +#include "Helper/FeedbackGen_Helper.h" +#include "Helper/Global_Helper.h" +#include "Helper/LED_Helper.h" +#include "Helper/MsgBox_Helper.h" +#include "Helper/Storage_Helper.h" +#include "Helper/Toast_Helper.h" + +#endif // __DATA_PROC_HELPER_H diff --git a/x_track/src/App/Service/DataProc/DataProc_NodeList.inc b/x_track/src/App/Service/DataProc/DataProc_NodeList.inc new file mode 100644 index 0000000000000000000000000000000000000000..3882621e48b91b83d9efed42c080e2bdb2072973 --- /dev/null +++ b/x_track/src/App/Service/DataProc/DataProc_NodeList.inc @@ -0,0 +1,20 @@ + +/* Data processing node list */ + +DP_DEF(Global); +DP_DEF(Storage); +DP_DEF(i18n); +DP_DEF(Backlight); +DP_DEF(Clock); +DP_DEF(Env); +DP_DEF(Power); +DP_DEF(GNSS); +DP_DEF(MapInfo); +DP_DEF(Recorder); +DP_DEF(SportStatus); +DP_DEF(PageNavi); +DP_DEF(Toast); +DP_DEF(TrackFilter); +DP_DEF(Version); +DP_DEF(Theme); +DP_DEF(SunRise); diff --git a/x_track/src/App/Service/DataProc/Def/DP_Backlight.h b/x_track/src/App/Service/DataProc/Def/DP_Backlight.h new file mode 100644 index 0000000000000000000000000000000000000000..219b4763a4dfe9e99d76a15efe1382e8fe9bab12 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Backlight.h @@ -0,0 +1,50 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_BACKLIGHT_DEF_H +#define __DATA_PROC_BACKLIGHT_DEF_H + +#include <cstdint> + +namespace DataProc { + +/* Backlight */ + +typedef struct Backlight_Info { + Backlight_Info() + : brightness(0) + , brightnessDay(-1) + , brightnessNight(-1) + , anim(false) + , disable(false) + { + } + int brightness; + int brightnessDay; + int brightnessNight; + bool anim; + bool disable; +} Backlight_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_BACKLIGHT_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_Env.h b/x_track/src/App/Service/DataProc/Def/DP_Env.h new file mode 100644 index 0000000000000000000000000000000000000000..d0706ab1ead8753367eb2ce482c0366442cdb4bf --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Env.h @@ -0,0 +1,42 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_ENV_DEF_H +#define __DATA_PROC_ENV_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct Env_Info { + Env_Info() + : key(nullptr) + , value(nullptr) + { + } + const char* key; + const char* value; +} Env_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_ENV_DEF_H diff --git a/x_track/src/App/Service/DataProc/Def/DP_FeedbackGen.h b/x_track/src/App/Service/DataProc/Def/DP_FeedbackGen.h new file mode 100644 index 0000000000000000000000000000000000000000..ab35cd49b0a9fa102a45628a61b65259a85aef18 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_FeedbackGen.h @@ -0,0 +1,68 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_FEEDBACK_GEN_DEF_H +#define __DATA_PROC_FEEDBACK_GEN_DEF_H + +#include <cstdint> + +namespace DataProc { + +/* https://developer.apple.com/documentation/uikit/uifeedbackgenerator */ + +enum class FEEDBACK_GEN_CMD { + ENABLE, + PREPARE, + TRIGGER, + FINALIZE, + CALIBRATE, +}; + +enum class FEEDBACK_GEN_EFFECT { + NONE, + IMPACT_LIGHT, + IMPACT_MEDIUM, + IMPACT_HEAVY, + SELECTION, + NOTIFICATION_ERROR, + NOTIFICATION_SUCCESS, + NOTIFICATION_WARNING, + LOCKDOWN, + STRONG_BUZZ, +}; + +typedef struct FeedbackGen_Info { + FeedbackGen_Info() + : cmd(FEEDBACK_GEN_CMD::ENABLE) + , effect(FEEDBACK_GEN_EFFECT::NONE) + { + } + FEEDBACK_GEN_CMD cmd; + union { + FEEDBACK_GEN_EFFECT effect; + bool enable; + }; +} FeedbackGen_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_FEEDBACK_GEN_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_GNSS.h b/x_track/src/App/Service/DataProc/Def/DP_GNSS.h new file mode 100644 index 0000000000000000000000000000000000000000..92f4c0126fb40248296229d52c01ceb80fa71910 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_GNSS.h @@ -0,0 +1,54 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_GNSS_DEF_H +#define __DATA_PROC_GNSS_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class GNSS_CMD { + NONE, + ENABLE, + DISABLE, + LOAD_EPHEMERIS, + SET_UPDATE_PERIOD, +}; + +typedef struct GNSS_Config { + GNSS_Config() + : cmd(GNSS_CMD::NONE) + , param { 0 } + { + } + + GNSS_CMD cmd; + union { + const char* ephemerisPath; + uint32_t updatePeriod; + } param; +} GNSS_Config_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_GNSS_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_Global.h b/x_track/src/App/Service/DataProc/Def/DP_Global.h new file mode 100644 index 0000000000000000000000000000000000000000..b254e714a4791c0187470fc3912ce53672856da0 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Global.h @@ -0,0 +1,52 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_GLOBAL_DEF_H +#define __DATA_PROC_GLOBAL_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class GLOBAL_EVENT { + NONE, + DATA_PROC_INIT_FINISHED, + PAGE_MANAGER_INIT_FINISHED, + STATUS_BAR_INIT_FINISHED, + APP_ARGS_PARSED, + APP_STARTED, + APP_RUN_LOOP_EXECUTE, + APP_STOPPED, +}; + +typedef struct Global_Info { + Global_Info() + : event(GLOBAL_EVENT::NONE) + { + } + GLOBAL_EVENT event; + void * param; +} Global_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_GLOBAL_DEF_H diff --git a/x_track/src/App/Service/DataProc/Def/DP_LED.h b/x_track/src/App/Service/DataProc/Def/DP_LED.h new file mode 100644 index 0000000000000000000000000000000000000000..dbc970c3192d4203a22944d30ebe84cf6adce683 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_LED.h @@ -0,0 +1,66 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_LED_DEF_H +#define __DATA_PROC_LED_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class LED_STATUS { + STOP, + RESET, + OFF, + ON, +}; + +enum class LED_ID { + NONE, + RED, + GREEN, + BLUE +}; + +typedef struct LED_Squence { + LED_Squence(LED_STATUS stat, uint16_t dur) + : status(stat) + , duration(dur) + { + } + LED_STATUS status; + uint32_t duration; +} LED_Squence_t; + +typedef struct LED_Info { + LED_Info() + : id(LED_ID::NONE) + , squence(nullptr) + { + } + LED_ID id; + const LED_Squence_t* squence; +} LED_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_LED_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_MapInfo.h b/x_track/src/App/Service/DataProc/Def/DP_MapInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..3cad5dec813c751c07ba00e072a30ca13cf1033b --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_MapInfo.h @@ -0,0 +1,50 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_MAP_INFO_DEF_H +#define __DATA_PROC_MAP_INFO_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct Map_Info { + Map_Info() + : path(nullptr) + , ext(nullptr) + , tileSize(256) + , levelMin(0) + , levelMax(0) + , coordTrans(false) + { + } + const char* path; + const char* ext; + uint16_t tileSize; + uint8_t levelMin; + uint8_t levelMax; + bool coordTrans; +} Map_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_MAP_INFO_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_MsgBox.h b/x_track/src/App/Service/DataProc/Def/DP_MsgBox.h new file mode 100644 index 0000000000000000000000000000000000000000..c8dfcbd5446ecef90902abb6cd9a49d23e3d51c7 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_MsgBox.h @@ -0,0 +1,62 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_MSG_BOX_DEF_H +#define __DATA_PROC_MSG_BOX_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct MsgBox_Info { + MsgBox_Info() + : title(nullptr) + , txt(nullptr) + , btns(nullptr) + , defaultBtn(0) + , autoSelectBtn(-1) + , autoSelecTimeoutSec(10) + { + } + union { + struct { + const char* title; + const char* txt; + const char** btns; + int defaultBtn; + int autoSelectBtn; + uint32_t autoSelecTimeoutSec; + }; + + /* return text value */ + + struct + { + int activeBtn; + const char* activeTxt; + }; + }; +} MsgBox_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_MSG_BOX_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_PageNavi.h b/x_track/src/App/Service/DataProc/Def/DP_PageNavi.h new file mode 100644 index 0000000000000000000000000000000000000000..3fac49f9cb909cae88b88fa1581382651122d162 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_PageNavi.h @@ -0,0 +1,48 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_PAGE_NAVI_DEF_H +#define __DATA_PROC_PAGE_NAVI_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class PAGE_NAVI_CMD { + NONE, + PUSH, + POP, +}; + +typedef struct PageNavi_Info { + PageNavi_Info() + : cmd(PAGE_NAVI_CMD::NONE) + , name(nullptr) + { + } + PAGE_NAVI_CMD cmd; + const char* name; +} PageNavi_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_PAGE_NAVI_DEF_H diff --git a/x_track/src/App/Service/DataProc/Def/DP_Power.h b/x_track/src/App/Service/DataProc/Def/DP_Power.h new file mode 100644 index 0000000000000000000000000000000000000000..691b9735ee630be6d2d084fd8e536fddd4a1aaaa --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Power.h @@ -0,0 +1,69 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_POWER_DEF_H +#define __DATA_PROC_POWER_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class POWER_CMD { + NONE, + SHUTDOWN, + REBOOT, + LOCK_WAKEUP, + UNLOCK_WAKEUP, + KICK_WAKEUP, + SET_AUTO_SHUTDOWN_TIME, + RESET_FUEL_GAUGE, +}; + +typedef struct Power_Info { + Power_Info() + : cmd(POWER_CMD::NONE) + , isReady(false) + , isCharging(false) + , level(0) + , voltage(0) + , delayShutdownTime(2000) + , autoShutdownTime(0) + , batteryUseTime(0) + , uptime(0) + { + } + POWER_CMD cmd; + bool isReady; + bool isCharging; + bool isReadyToShutdown; + bool isBatteryLow; + uint8_t level; + uint16_t voltage; + uint16_t delayShutdownTime; + int autoShutdownTime; + uint64_t batteryUseTime; + uint64_t uptime; +} Power_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_POWER_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_Recorder.h b/x_track/src/App/Service/DataProc/Def/DP_Recorder.h new file mode 100644 index 0000000000000000000000000000000000000000..db3fd514e664b0dd141f111bef42df70a81d1f92 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Recorder.h @@ -0,0 +1,51 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_RECORDER_DEF_H +#define __DATA_PROC_RECORDER_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class RECORDER_CMD { + NONE, + ENABLE_AUTO_REC, + DISABLE_AUTO_REC, +}; + +typedef struct Recorder_Info { + Recorder_Info() + : active(false) + , cmd(RECORDER_CMD::NONE) + , time(0) + { + } + bool active; + bool autoRec; + RECORDER_CMD cmd; + uint16_t time; +} Recorder_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_RECORDER_DEF_H diff --git a/x_track/src/App/Service/DataProc/Def/DP_Slope.h b/x_track/src/App/Service/DataProc/Def/DP_Slope.h new file mode 100644 index 0000000000000000000000000000000000000000..ef4c1134fad21f053545c52a895e96ed2f1c6968 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Slope.h @@ -0,0 +1,44 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_SLOPE_DEF_H +#define __DATA_PROC_SLOPE_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct Slope_Info { + Slope_Info() + : slope(0) + , angle(0) + , altitude(0) + { + } + float slope; + float angle; + float altitude; +} Slope_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_SLOPE_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_SportStatus.h b/x_track/src/App/Service/DataProc/Def/DP_SportStatus.h new file mode 100644 index 0000000000000000000000000000000000000000..c846bfa8f6a575ad708cf2c31caf426a5837ffaf --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_SportStatus.h @@ -0,0 +1,80 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_SPORT_STATUS_DEF_H +#define __DATA_PROC_SPORT_STATUS_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class SPORT_STATUS_CMD { + NONE, + RESET_SINGLE, + RESET_TOTAL, + RESET_SPEED_MAX, + SET_WEIGHT, +}; + +typedef struct SportStatus_Info { + SportStatus_Info() + : cmd(SPORT_STATUS_CMD::NONE) + , lastTick(0) + , weight(0) + , speedKph(0) + , speedMaxKph(0) + , speedAvgKph(0) + , totalTime(0) + , totalDistance(0) + , singleTime(0) + , singleDistance(0) + , singleCalorie(0) + , longitude(0) + , latitude(0) + , altitude(0) + { + } + + SPORT_STATUS_CMD cmd; + + uint32_t lastTick; + + float weight; + + float speedKph; + float speedMaxKph; + float speedAvgKph; + + uint64_t totalTime; + float totalDistance; + uint64_t singleTime; + float singleDistance; + float singleCalorie; + + float longitude; + float latitude; + float altitude; +} SportStatus_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_SPORT_STATUS_DEF_H diff --git a/x_track/src/App/Service/DataProc/Def/DP_Storage.h b/x_track/src/App/Service/DataProc/Def/DP_Storage.h new file mode 100644 index 0000000000000000000000000000000000000000..b50b65707400c9f9537a7d1963e739c5efdc6ba8 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Storage.h @@ -0,0 +1,80 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_STORAGE_DEF_H +#define __DATA_PROC_STORAGE_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class STORAGE_CMD { + LOAD, + SAVE, + ADD, + MOUNT, + UNMOUNT, +}; + +enum class STORAGE_TYPE { + BOOL = 1, + INT, + FLOAT, + DOUBLE, + STRING, + ARRAY, + STRUCT_START, + STRUCT_END, +}; + +typedef struct Storage_Info { + Storage_Info() + : cmd(STORAGE_CMD::LOAD) + , key(nullptr) + , value(nullptr) + , size(0) + , type(STORAGE_TYPE::BOOL) + { + } + STORAGE_CMD cmd; + const char* key; + void* value; + uint16_t size; + STORAGE_TYPE type; +} Storage_Info_t; + +typedef struct Storage_Device_Info { + Storage_Device_Info() + : isDetect(false) + , totalSize(0) + , freeSize(0) + { + } + bool isDetect; + bool isActive; + uint64_t totalSize; + uint64_t freeSize; +} Storage_Device_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_STORAGE_DEF_H diff --git a/x_track/src/App/Service/DataProc/Def/DP_SunRise.h b/x_track/src/App/Service/DataProc/Def/DP_SunRise.h new file mode 100644 index 0000000000000000000000000000000000000000..a5e844a3d226829738c67eb8df993940c1d32e4f --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_SunRise.h @@ -0,0 +1,50 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_SUN_RISE_DEF_H +#define __DATA_PROC_SUN_RISE_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class SUNRISE_STATE { + UNKNOWN, + DAY, + NIGHT, +}; + +typedef struct SunRise_Info { + SunRise_Info() + : state(SUNRISE_STATE::UNKNOWN) + { + } + SUNRISE_STATE state; + uint8_t sunriseHour; + uint8_t sunriseMinute; + uint8_t sunsetHour; + uint8_t sunsetMinute; +} SunRise_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_SUN_RISE_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_Toast.h b/x_track/src/App/Service/DataProc/Def/DP_Toast.h new file mode 100644 index 0000000000000000000000000000000000000000..0f4a9b720c7bc3ba70fa6127939ef556f19c32e3 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Toast.h @@ -0,0 +1,42 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_TOAST_DEF_H +#define __DATA_PROC_TOAST_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct Toast_Info { + Toast_Info() + : txt(nullptr) + , duration(0) + { + } + const char* txt; + uint32_t duration; +} Toast_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_TOAST_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_TrackFilter.h b/x_track/src/App/Service/DataProc/Def/DP_TrackFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..0b1fd5a1f168132b0d79bc89fee2eb619916d31f --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_TrackFilter.h @@ -0,0 +1,44 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_TRACK_FILTER_DEF_H +#define __DATA_PROC_TRACK_FILTER_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct TrackFilter_Info { + TrackFilter_Info() + : active(false) + , level(0) + , pointCont(nullptr) + { + } + bool active; + uint8_t level; + void* pointCont; +} TrackFilter_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_TRACK_FILTER_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/DP_Version.h b/x_track/src/App/Service/DataProc/Def/DP_Version.h new file mode 100644 index 0000000000000000000000000000000000000000..d2182c9b42f1d7d018e1faf124d5a02d8589a5b8 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/DP_Version.h @@ -0,0 +1,56 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_VERSION_DEF_H +#define __DATA_PROC_VERSION_DEF_H + +#include <cstdint> + +namespace DataProc { + +typedef struct Version_Info { + Version_Info() + : name(nullptr) + , software(nullptr) + , hardware(nullptr) + , author(nullptr) + , website(nullptr) + , graphics(nullptr) + , compiler(nullptr) + , buildDate(nullptr) + , buildTime(nullptr) + { + } + const char* name; + const char* software; + const char* hardware; + const char* author; + const char* website; + const char* graphics; + const char* compiler; + const char* buildDate; + const char* buildTime; +} Version_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_VERSION_DEF_H \ No newline at end of file diff --git a/x_track/src/App/Service/DataProc/Def/_DP_Template.h b/x_track/src/App/Service/DataProc/Def/_DP_Template.h new file mode 100644 index 0000000000000000000000000000000000000000..7e010ce8ed07a0855076ae200e6af9c2a9d9652f --- /dev/null +++ b/x_track/src/App/Service/DataProc/Def/_DP_Template.h @@ -0,0 +1,45 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_TEMPLATE_DEF_H +#define __DATA_PROC_TEMPLATE_DEF_H + +#include <cstdint> + +namespace DataProc { + +enum class TEMPLATE_CMD { + NONE, +}; + +typedef struct Template_Info { + Template_Info() + : cmd(TEMPLATE_CMD::NONE) + { + } + TEMPLATE_CMD cmd; + int value; +} Template_Info_t; + +} // namespace DataProc + +#endif // __DATA_PROC_TEMPLATE_DEF_H diff --git a/x_track/src/App/Service/DataProc/Helper/Env_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/Env_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26f9af36001970c658a36ee5fd564a657a366847 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Env_Helper.cpp @@ -0,0 +1,62 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Env_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" +#include <cstdio> +#include <cstdlib> + +using namespace DataProc; + +Env_Helper::Env_Helper(DataNode* node) + : _node(node) +{ + _nodeEnv = node->subscribe("Env"); +} + +int Env_Helper::set(const char* key, const char* value) +{ + DataProc::Env_Info_t envInfo; + envInfo.key = key; + envInfo.value = value; + return _node->notify(_nodeEnv, &envInfo, sizeof(envInfo)); +} + +int Env_Helper::setInt(const char* key, int value) +{ + char buf[16]; + snprintf(buf, sizeof(buf), "%d", value); + return set(key, buf); +} + +const char* Env_Helper::get(const char* key, const char* def) +{ + DataProc::Env_Info_t envInfo; + envInfo.key = key; + _node->pull(_nodeEnv, &envInfo, sizeof(envInfo)); + return envInfo.value ? envInfo.value : def; +} + +int Env_Helper::getInt(const char* key) +{ + return atoi(get(key, "0")); +} diff --git a/x_track/src/App/Service/DataProc/Helper/Env_Helper.h b/x_track/src/App/Service/DataProc/Helper/Env_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..b6f505ce57b7f794f3d26d6335c21395bb8f9c70 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Env_Helper.h @@ -0,0 +1,51 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_ENV_HELPER_H +#define __DATA_PROC_ENV_HELPER_H + +#include "../Def/DP_Env.h" + +class DataNode; + +namespace DataProc { + +class Env_Helper { +public: + Env_Helper(DataNode* node); + int set(const char* key, const char* value); + int setInt(const char* key, int value); + const char* get(const char* key, const char* def = nullptr); + int getInt(const char* key); + operator const DataNode*() const + { + return _nodeEnv; + } + +private: + DataNode* _node; + const DataNode* _nodeEnv; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_ENV_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/FeedbackGen_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/FeedbackGen_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..083016482468bc63c72a1e7bfde1510eff089991 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/FeedbackGen_Helper.cpp @@ -0,0 +1,47 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "FeedbackGen_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" + +using namespace DataProc; + +FeedbackGen_Helper::FeedbackGen_Helper(DataNode* node) + : _node(node) +{ + _nodeFeedBackGen = node->subscribe("FeedbackGen"); +} + +int FeedbackGen_Helper::trigger(DataProc::FEEDBACK_GEN_EFFECT effect) +{ + DataProc::FeedbackGen_Info_t info; + info.cmd = DataProc::FEEDBACK_GEN_CMD::PREPARE; + info.effect = effect; + + int retval = _node->notify(_nodeFeedBackGen, &info, sizeof(info)); + if (retval != DataNode::RES_OK) { + return retval; + } + + info.cmd = DataProc::FEEDBACK_GEN_CMD::TRIGGER; + return _node->notify(_nodeFeedBackGen, &info, sizeof(info)); +} diff --git a/x_track/src/App/Service/DataProc/Helper/FeedbackGen_Helper.h b/x_track/src/App/Service/DataProc/Helper/FeedbackGen_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..0c70455f7f0d825373f34524c18c8f2dd1515843 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/FeedbackGen_Helper.h @@ -0,0 +1,48 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_FEEDBACK_GEN_HELPER_H +#define __DATA_PROC_FEEDBACK_GEN_HELPER_H + +#include "../Def/DP_FeedbackGen.h" + +class DataNode; + +namespace DataProc { + +class FeedbackGen_Helper { +public: + FeedbackGen_Helper(DataNode* node); + int trigger(DataProc::FEEDBACK_GEN_EFFECT effect); + operator const DataNode*() const + { + return _nodeFeedBackGen; + } + +private: + DataNode* _node; + const DataNode* _nodeFeedBackGen; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_FEEDBACK_GEN_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/Global_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/Global_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9224b32e91dfd3d4e9683cc88f1eefbe9f42e28c --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Global_Helper.cpp @@ -0,0 +1,40 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Global_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" + +using namespace DataProc; + +Global_Helper::Global_Helper(DataNode* node) +{ + _node = node; + _nodeGlobal = node->subscribe("Global"); +} + +int Global_Helper::publish(GLOBAL_EVENT event, void* param) +{ + Global_Info_t info; + info.event = event; + info.param = param; + return _node->notify(_nodeGlobal, &info, sizeof(info)); +} diff --git a/x_track/src/App/Service/DataProc/Helper/Global_Helper.h b/x_track/src/App/Service/DataProc/Helper/Global_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..8cbace0b64391f0f04494af98fa290c0b537d9e7 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Global_Helper.h @@ -0,0 +1,44 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_GLOBAL_HELPER_H +#define __DATA_PROC_GLOBAL_HELPER_H + +#include "../Def/DP_Global.h" + +class DataNode; + +namespace DataProc { + +class Global_Helper { +public: + Global_Helper(DataNode* node); + int publish(GLOBAL_EVENT event, void* param = nullptr); + +private: + DataNode* _node; + const DataNode* _nodeGlobal; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_GLOBAL_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/LED_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/LED_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..df0c56c255def79045a71ebe5b2a7aad83e88606 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/LED_Helper.cpp @@ -0,0 +1,61 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "LED_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" + +using namespace DataProc; + +LED_Helper::LED_Helper(DataNode* node, LED_ID id) + : _node(node) + , _nodeLED(node->subscribe("LED")) + , _id(id) +{ +} + +int LED_Helper::start(const LED_Squence_t* squence) +{ + LED_Info_t info; + info.id = _id; + info.squence = squence; + return _node->notify(_nodeLED, &info, sizeof(info)); +} + +int LED_Helper::on() +{ + static const LED_Squence_t seq[] = { + { LED_STATUS::ON, 0 }, + { LED_STATUS::STOP, 0 }, + }; + + return start(seq); +} + +int LED_Helper::off() +{ + static const LED_Squence_t seq[] = { + { LED_STATUS::OFF, 0 }, + { LED_STATUS::STOP, 0 }, + }; + + return start(seq); +} diff --git a/x_track/src/App/Service/DataProc/Helper/LED_Helper.h b/x_track/src/App/Service/DataProc/Helper/LED_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..982056e0829ff79ac0190840494aa0ebe40ffd4e --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/LED_Helper.h @@ -0,0 +1,51 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_LED_HELPER_H +#define __DATA_PROC_LED_HELPER_H + +#include "../Def/DP_LED.h" + +class DataNode; + +namespace DataProc { + +class LED_Helper { +public: + LED_Helper(DataNode* node, LED_ID id); + int start(const LED_Squence_t* squence); + int on(); + int off(); + operator const DataNode*() const + { + return _nodeLED; + } + +private: + DataNode* _node; + const DataNode* _nodeLED; + LED_ID _id; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_LED_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/MsgBox_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/MsgBox_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ac0ff78354476d23553d5789f987a8cddfd0daf --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/MsgBox_Helper.cpp @@ -0,0 +1,46 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "MsgBox_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" + +using namespace DataProc; + +MsgBox_Helper::MsgBox_Helper(DataNode* node) + : _node(node) +{ + _nodeMsgBox = node->subscribe("MsgBox"); +} + +int MsgBox_Helper::show(const char* title, const char* txt, const char** btns) +{ + DataProc::MsgBox_Info_t info; + info.title = title; + info.txt = txt; + info.btns = btns; + return show(&info); +} + +int MsgBox_Helper::show(const DataProc::MsgBox_Info_t* info) +{ + return _node->notify(_nodeMsgBox, info, sizeof(DataProc::MsgBox_Info_t)); +} diff --git a/x_track/src/App/Service/DataProc/Helper/MsgBox_Helper.h b/x_track/src/App/Service/DataProc/Helper/MsgBox_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..05f0071faa482d1e12060663c1d18fe02bc3cc79 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/MsgBox_Helper.h @@ -0,0 +1,49 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_MSGBOX_HELPER_H +#define __DATA_PROC_MSGBOX_HELPER_H + +#include "../Def/DP_MsgBox.h" + +class DataNode; + +namespace DataProc { + +class MsgBox_Helper { +public: + MsgBox_Helper(DataNode* node); + int show(const char* title, const char* txt, const char** btns); + int show(const DataProc::MsgBox_Info_t* info); + operator const DataNode*() const + { + return _nodeMsgBox; + } + +private: + DataNode* _node; + const DataNode* _nodeMsgBox; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_MSGBOX_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/Storage_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/Storage_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..037dc45e1a0f49dd972721189016ab10f40c9f43 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Storage_Helper.cpp @@ -0,0 +1,101 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Storage_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" + +using namespace DataProc; + +Storage_Helper::Storage_Helper(DataNode* node) + : _node(node) +{ + _nodeStorage = node->subscribe("Storage"); +} + +int Storage_Helper::add(const char* key, void* value, uint32_t size, DataProc::STORAGE_TYPE type) +{ + DataProc::Storage_Info_t storageInfo; + storageInfo.cmd = DataProc::STORAGE_CMD::ADD; + storageInfo.key = key; + storageInfo.value = value; + storageInfo.size = size; + storageInfo.type = type; + return _node->notify(_nodeStorage, &storageInfo, sizeof(storageInfo)); +} + +int Storage_Helper::add(const char* key, float* value) +{ + return add(key, value, sizeof(float), DataProc::STORAGE_TYPE::FLOAT); +} + +int Storage_Helper::add(const char* key, int* value) +{ + return add(key, value, sizeof(int), DataProc::STORAGE_TYPE::INT); +} + +int Storage_Helper::add(const char* key, bool* value) +{ + return add(key, value, sizeof(bool), DataProc::STORAGE_TYPE::BOOL); +} + +int Storage_Helper::addArray(const char* key, void* value, uint32_t size, uint32_t len, DataProc::STORAGE_TYPE type) +{ + DataProc::Storage_Info_t storageInfo; + storageInfo.cmd = DataProc::STORAGE_CMD::ADD; + storageInfo.key = key; + storageInfo.size = len; + storageInfo.type = DataProc::STORAGE_TYPE::ARRAY; + + auto ret = _node->notify(_nodeStorage, &storageInfo, sizeof(storageInfo)); + if (ret != DataNode::RES_OK) { + return ret; + } + + storageInfo.cmd = DataProc::STORAGE_CMD::ADD; + storageInfo.key = nullptr; + storageInfo.value = value; + storageInfo.size = size; + storageInfo.type = type; + return _node->notify(_nodeStorage, &storageInfo, sizeof(storageInfo)); +} + +int Storage_Helper::structStart(const char* key) +{ + DataProc::Storage_Info_t storageInfo; + storageInfo.cmd = DataProc::STORAGE_CMD::ADD; + storageInfo.key = key; + storageInfo.value = nullptr; + storageInfo.size = 0; + storageInfo.type = DataProc::STORAGE_TYPE::STRUCT_START; + return _node->notify(_nodeStorage, &storageInfo, sizeof(storageInfo)); +} + +int Storage_Helper::structEnd() +{ + DataProc::Storage_Info_t storageInfo; + storageInfo.cmd = DataProc::STORAGE_CMD::ADD; + storageInfo.key = nullptr; + storageInfo.value = nullptr; + storageInfo.size = 0; + storageInfo.type = DataProc::STORAGE_TYPE::STRUCT_END; + return _node->notify(_nodeStorage, &storageInfo, sizeof(storageInfo)); +} diff --git a/x_track/src/App/Service/DataProc/Helper/Storage_Helper.h b/x_track/src/App/Service/DataProc/Helper/Storage_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..51f0e19bd18f58b15176de4da004b066128d6047 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Storage_Helper.h @@ -0,0 +1,54 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_STORAGE_HELPER_H +#define __DATA_PROC_STORAGE_HELPER_H + +#include "../Def/DP_Storage.h" + +class DataNode; + +namespace DataProc { + +class Storage_Helper { +public: + Storage_Helper(DataNode* node); + int add(const char* key, void* value, uint32_t size, DataProc::STORAGE_TYPE type); + int add(const char* key, float* value); + int add(const char* key, int* value); + int add(const char* key, bool* value); + int addArray(const char* key, void* value, uint32_t size, uint32_t len, DataProc::STORAGE_TYPE type); + int structStart(const char* key); + int structEnd(); + operator const DataNode*() const + { + return _nodeStorage; + } + +private: + DataNode* _node; + const DataNode* _nodeStorage; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_STORAGE_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/Toast_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/Toast_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b21cdc2a04bcdc56a4f5c0529e737b7daa1260c --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Toast_Helper.cpp @@ -0,0 +1,50 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Toast_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" +#include <cstdarg> +#include <cstdio> + +using namespace DataProc; + +Toast_Helper::Toast_Helper(DataNode* node) +{ + _node = node; + _nodeToast = node->subscribe("Toast"); +} + +int Toast_Helper::show(const char* format, ...) +{ + va_list args; + va_start(args, format); + + char buf[256]; + vsnprintf(buf, sizeof(buf), format, args); + + va_end(args); + + Toast_Info_t info; + info.txt = buf; + info.duration = 2000; + return _node->notify(_nodeToast, &info, sizeof(info)); +} diff --git a/x_track/src/App/Service/DataProc/Helper/Toast_Helper.h b/x_track/src/App/Service/DataProc/Helper/Toast_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..19a715cae902c36be890c82e3203e54fdc6c4e14 --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/Toast_Helper.h @@ -0,0 +1,48 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_TOAST_HELPER_H +#define __DATA_PROC_TOAST_HELPER_H + +#include "../Def/DP_Toast.h" + +class DataNode; + +namespace DataProc { + +class Toast_Helper { +public: + Toast_Helper(DataNode* node); + int show(const char* format, ...); + operator const DataNode*() const + { + return _nodeToast; + } + +private: + DataNode* _node; + const DataNode* _nodeToast; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_TOAST_HELPER_H diff --git a/x_track/src/App/Service/DataProc/Helper/_Template_Helper.cpp b/x_track/src/App/Service/DataProc/Helper/_Template_Helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7127aa98bba51403a0b5e442d8ff60552aac54c --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/_Template_Helper.cpp @@ -0,0 +1,32 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "_Template_Helper.h" +#include "Frameworks/DataBroker/DataBroker.h" + +using namespace DataProc; + +Template_Helper::Template_Helper(DataNode* node) + : _node(node) +{ + _nodeTemplate = node->subscribe("Template"); +} diff --git a/x_track/src/App/Service/DataProc/Helper/_Template_Helper.h b/x_track/src/App/Service/DataProc/Helper/_Template_Helper.h new file mode 100644 index 0000000000000000000000000000000000000000..c0ec4897315d37422bcd7b2d0c7e99d7874b936a --- /dev/null +++ b/x_track/src/App/Service/DataProc/Helper/_Template_Helper.h @@ -0,0 +1,45 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_PROC_TEMPLATE_HELPER_H +#define __DATA_PROC_TEMPLATE_HELPER_H + +class DataNode; + +namespace DataProc { + +class Template_Helper { +public: + Template_Helper(DataNode* node); + operator const DataNode*() const + { + return _nodeTemplate; + } + +private: + DataNode* _node; + const DataNode* _nodeTemplate; +}; + +} // namespace DataProc + +#endif // __DATA_PROC_TEMPLATE_HELPER_H diff --git a/x_track/src/App/Service/DataProc/_DP_Template.cpp b/x_track/src/App/Service/DataProc/_DP_Template.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81e028e78497062d0ed342d685ff6eece85fb438 --- /dev/null +++ b/x_track/src/App/Service/DataProc/_DP_Template.cpp @@ -0,0 +1,73 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataProc.h" + +using namespace DataProc; + +class DP_Template { +public: + DP_Template(DataNode* node); + +private: + DataNode* _node; + int _value; + +private: + int onEvent(DataNode::EventParam_t* param); +}; + +DP_Template::DP_Template(DataNode* node) + : _node(node) + , _value(0) +{ + _node->setEventCallback( + [](DataNode* n, DataNode::EventParam_t* param) { + auto ctx = (DP_Template*)n->getUserData(); + return ctx->onEvent(param); + }, + DataNode::EVENT_PULL | DataNode::EVENT_NOTIFY); +} + +int DP_Template::onEvent(DataNode::EventParam_t* param) +{ + if (param->size != sizeof(_value)) { + return DataNode::RES_SIZE_MISMATCH; + } + + switch (param->event) { + case DataNode::EVENT_PULL: + memcpy(param->data_p, &_value, sizeof(_value)); + break; + + case DataNode::EVENT_NOTIFY: + memcpy(&_value, param->data_p, sizeof(_value)); + break; + + default: + break; + } + + return DataNode::RES_OK; +} + +DATA_PROC_DESCRIPTOR_DEF(Template) diff --git a/x_track/src/App/Service/HAL/Def/HAL_Backlight.h b/x_track/src/App/Service/HAL/Def/HAL_Backlight.h new file mode 100644 index 0000000000000000000000000000000000000000..e8fcf1bdc883ffe30c37fd2a372b12e5ba83e5ed --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/HAL_Backlight.h @@ -0,0 +1,45 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_BACKLIGHT_DEF_H +#define __HAL_BACKLIGHT_DEF_H + +#include <stdbool.h> +#include <stdint.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * Backlight + *********************/ + +#define BACKLIGHT_IOCMD_FORCE_LIT DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 0, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_BACKLIGHT_DEF_H diff --git a/x_track/src/App/Service/HAL/Def/HAL_Clock.h b/x_track/src/App/Service/HAL/Def/HAL_Clock.h new file mode 100644 index 0000000000000000000000000000000000000000..d647369a1018f5ed8e91cf8c92ed13c72013bf80 --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/HAL_Clock.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_CLOCK_DEF_H +#define __HAL_CLOCK_DEF_H + +#include <stdbool.h> +#include <stdint.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * Clock + *********************/ + +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t week; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint16_t millisecond; +} Clock_Info_t; + +#define CLOCK_IOCMD_CALIBRATE DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(HAL::Clock_Info_t), 0, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_CLOCK_DEF_H diff --git a/x_track/src/App/Service/HAL/Def/HAL_Display.h b/x_track/src/App/Service/HAL/Def/HAL_Display.h new file mode 100644 index 0000000000000000000000000000000000000000..0f220bca3ed54e522a423fd41e0f1a4c48424a36 --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/HAL_Display.h @@ -0,0 +1,86 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_DISPLAY_DEF_H +#define __HAL_DISPLAY_DEF_H + +#include <stdbool.h> +#include <stdint.h> +#include <stddef.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * Display + *********************/ + +typedef struct +{ + int16_t width; + int16_t height; + void* buffer0; + void* buffer1; + size_t size; + uint8_t bpp; +} Display_Info_t; + +typedef struct +{ + int16_t x0; + int16_t y0; + int16_t x1; + int16_t y1; + void* buffer; + size_t size; +} Display_PutArea_Info_t; + +typedef void (*Display_CallbackFunc_t)(void*); + +typedef struct +{ + Display_CallbackFunc_t callback; + void* userData; +} Display_SetCallback_Info_t; + +typedef struct +{ + const char* title; + const char* info; + const char* callstack; +} Display_ShowCrash_Info_t; + +#define DISPLAY_IOCMD_GET_INFO DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_OUT, sizeof(HAL::Display_Info_t), 0, 0) +#define DISPLAY_IOCMD_PUT_AREA DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(HAL::Display_PutArea_Info_t), 1, 0) +#define DISPLAY_IOCMD_SET_CALLBACK DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(HAL::Display_SetCallback_Info_t), 2, 0) +#define DISPLAY_IOCMD_SET_ROTATION DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(int), 3, 0) +#define DISPLAY_IOCMD_SHOW_CRASH_INFO DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(HAL::Display_ShowCrash_Info_t), 4, 0) +#define DISPLAY_IOCMD_FILL_COLOR DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(uint16_t), 5, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_DISPLAY_DEF_H diff --git a/x_track/src/App/Service/HAL/Def/HAL_GNSS.h b/x_track/src/App/Service/HAL/Def/HAL_GNSS.h new file mode 100644 index 0000000000000000000000000000000000000000..f4e4a55f01d86bea2c5d8f038932549e196dcb83 --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/HAL_GNSS.h @@ -0,0 +1,77 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_GNSS_DEF_H +#define __HAL_GNSS_DEF_H + +#include <stdbool.h> +#include <stdint.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * GNSS + *********************/ + +typedef struct +{ + uint8_t id; + int16_t elevation; + int16_t azimuth; + int16_t snr; +} GNSS_GSV_Item_t; + +typedef struct +{ + bool isVaild; + int16_t satellites; + Clock_Info_t clock; + + float longitude; + float latitude; + float altitude; + float course; + float speed; + + float pdop; + float hdop; + float vdop; + + struct + { + const GNSS_GSV_Item_t* items; + uint8_t num; + int16_t satsInView; + } gsv; +} GNSS_Info_t; + +#define GNSS_IOCMD_UPDATE DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 0, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_GNSS_DEF_H diff --git a/x_track/src/App/Service/HAL/Def/HAL_Power.h b/x_track/src/App/Service/HAL/Def/HAL_Power.h new file mode 100644 index 0000000000000000000000000000000000000000..e66297d2ef2845c44e47f42d01e2378925178a12 --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/HAL_Power.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_POWER_DEF_H +#define __HAL_POWER_DEF_H + +#include <stdbool.h> +#include <stdint.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * Power + *********************/ + +typedef struct +{ + uint16_t voltage; + uint8_t level; + bool isReady; + bool isCharging; +} Power_Info_t; + +#define POWER_IOCMD_POWER_ON DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 0, 0) +#define POWER_IOCMD_POWER_OFF DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 1, 0) +#define POWER_IOCMD_REBOOT DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 2, 0) +#define POWER_IOCMD_GAUGE_RESET DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 3, 0) +#define POWER_IOCMD_SET_SYS_VOLTAGE DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(int), 5, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_TEMPLATE_DEF_H diff --git a/x_track/src/App/Service/HAL/Def/HAL_SdCard.h b/x_track/src/App/Service/HAL/Def/HAL_SdCard.h new file mode 100644 index 0000000000000000000000000000000000000000..c9a7e8a0dd2623edc3b2d95176210c7ac5923847 --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/HAL_SdCard.h @@ -0,0 +1,56 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_SDCARD_DEF_H +#define __HAL_SDCARD_DEF_H + +#include <stdbool.h> +#include <stdint.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * SD-Card + *********************/ +typedef struct +{ + bool isInsert; + bool isMounted; + bool isActive; + uint64_t freeCapacity; + uint64_t totalCapacity; +} SdCard_Info_t; + +#define SDCARD_IOCMD_MOUNT DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 1, 0) +#define SDCARD_IOCMD_UNMOUNT DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 2, 0) +#define SDCARD_IOCMD_MKDIR DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(const char*), 3, 0) +#define SDCARD_IOCMD_REMOVE DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, sizeof(const char*), 4, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_SDCARD_DEF_H diff --git a/x_track/src/App/Service/HAL/Def/_HAL_Template.h b/x_track/src/App/Service/HAL/Def/_HAL_Template.h new file mode 100644 index 0000000000000000000000000000000000000000..be7ad8cca814dd6ca2f678d6c1f2286389178ce5 --- /dev/null +++ b/x_track/src/App/Service/HAL/Def/_HAL_Template.h @@ -0,0 +1,51 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_TEMPLATE_DEF_H +#define __HAL_TEMPLATE_DEF_H + +#include <stdbool.h> +#include <stdint.h> + +namespace HAL { + +/* clang-format off */ + +/* DEVICEO_OBJECT_IOCMD_DEF(dir, size, type, number) */ + +/********************* + * Template + *********************/ + +typedef struct +{ + int value; +} Template_Info_t; + +#define TEMPLATE_IOCMD_ON DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 0, 0) +#define TEMPLATE_IOCMD_OFF DEVICE_OBJECT_IOCMD_DEF(DeviceObject::DIR_IN, 0, 1, 0) + +/* clang-format on */ + +} // namespace HAL + +#endif // __HAL_TEMPLATE_DEF_H diff --git a/x_track/src/App/Service/HAL/HAL.h b/x_track/src/App/Service/HAL/HAL.h new file mode 100644 index 0000000000000000000000000000000000000000..989abda35fe34090ad6592c48a642a55e9869512 --- /dev/null +++ b/x_track/src/App/Service/HAL/HAL.h @@ -0,0 +1,41 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_COMMON_H +#define __HAL_COMMON_H + +#include "HAL_Def.h" + +#include "Frameworks/DeviceManager/DeviceManager.h" +#include "Frameworks/DeviceManager/DeviceObject.h" + +#define DEVICE_OBJECT_MAKE(name) HAL::name DevObj_##name(#name) + +namespace HAL { + +void Init(); +DeviceManager* Manager(); +uint32_t GetTick(); +uint32_t GetTickElaps(uint32_t prevTick); + +} +#endif diff --git a/x_track/src/App/Service/HAL/HAL_Assert.h b/x_track/src/App/Service/HAL/HAL_Assert.h new file mode 100644 index 0000000000000000000000000000000000000000..4f42b92f8fb158d071a6f5ddcac0ffccef052638 --- /dev/null +++ b/x_track/src/App/Service/HAL/HAL_Assert.h @@ -0,0 +1,44 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __HAL_PANIC_H +#define __HAL_PANIC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAL_ASSERT(expr) \ + do { \ + if (!(expr)) \ + HAL_Assert(__FILE__, __LINE__, __func__, #expr); \ + } while (0) + +void HAL_Assert(const char* file, int line, const char* func, const char* expr); +void HAL_Panic(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_PANIC_H */ diff --git a/x_track/src/App/Service/HAL/HAL_Def.h b/x_track/src/App/Service/HAL/HAL_Def.h new file mode 100644 index 0000000000000000000000000000000000000000..eddccce81fec82e4c66d0d9f5cb463973ddb4532 --- /dev/null +++ b/x_track/src/App/Service/HAL/HAL_Def.h @@ -0,0 +1,34 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __HAL_DEF_H +#define __HAL_DEF_H + +#include "Def/HAL_Backlight.h" +#include "Def/HAL_Clock.h" +#include "Def/HAL_Display.h" +#include "Def/HAL_GNSS.h" +#include "Def/HAL_Power.h" +#include "Def/HAL_SdCard.h" + +#endif /* __HAL_DEF_H */ diff --git a/x_track/src/App/Service/HAL/HAL_Log.h b/x_track/src/App/Service/HAL/HAL_Log.h new file mode 100644 index 0000000000000000000000000000000000000000..e4f1c7409bc79a15c4405b4043abff323b6d611e --- /dev/null +++ b/x_track/src/App/Service/HAL/HAL_Log.h @@ -0,0 +1,79 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_LOG_H +#define __HAL_LOG_H + +#include <inttypes.h> +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define HAL_LOG_LEVEL_OFF -1 +#define HAL_LOG_LEVEL_INFO 0 +#define HAL_LOG_LEVEL_WARN 1 +#define HAL_LOG_LEVEL_ERROR 2 +#define _HAL_LOG_LEVEL_LAST 3 + +#ifndef HAL_LOG_LEVEL +#define HAL_LOG_LEVEL HAL_LOG_LEVEL_INFO +#endif + +#if HAL_LOG_LEVEL > HAL_LOG_LEVEL_OFF + +#if HAL_LOG_LEVEL <= HAL_LOG_LEVEL_INFO +#define HAL_LOG_INFO(...) HAL_Log(HAL_LOG_LEVEL_INFO, __func__, __VA_ARGS__) +#else +#define HAL_LOG_INFO(...) +#endif + +#if HAL_LOG_LEVEL <= HAL_LOG_LEVEL_WARN +#define HAL_LOG_WARN(...) HAL_Log(HAL_LOG_LEVEL_WARN, __func__, __VA_ARGS__) +#else +#define HAL_LOG_WARN(...) +#endif + +#if HAL_LOG_LEVEL <= HAL_LOG_LEVEL_ERROR +#define HAL_LOG_ERROR(...) HAL_Log(HAL_LOG_LEVEL_ERROR, __func__, __VA_ARGS__) +#else +#define HAL_LOG_ERROR(...) +#endif + +#else +#define HAL_LOG_INFO(...) +#define HAL_LOG_WARN(...) +#define HAL_LOG_ERROR(...) +#endif + +void HAL_Log_Init(void); +void HAL_Log_PrintString(const char* str); +void HAL_Log(uint8_t level, const char* func, const char* fmt, ...); +void HAL_Log_Printf(const char* fmt, ...); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/x_track/src/App/Service/HAL/HAL_Template.cpp b/x_track/src/App/Service/HAL/HAL_Template.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0afbacd047ddce8cff68f362b12159b6e8b43b65 --- /dev/null +++ b/x_track/src/App/Service/HAL/HAL_Template.cpp @@ -0,0 +1,73 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#if 0 + +#include "HAL.h" + +namespace HAL { + +class Template : private DeviceObject { +public: + Template(const char* name) + : DeviceObject(name) + { + } + +private: + virtual int onInit(); + virtual int onRead(void* buffer, size_t size); + virtual int onWrite(const void* buffer, size_t size); + virtual int onIoctl(DeviceObject::IO_Cmd_t cmd, void* data); +}; + +int Template::onInit() +{ + return DeviceObject::RES_OK; +} + +int Template::onRead(void* buffer, size_t size) +{ + return DeviceObject::RES_UNSUPPORT; +} + +int Template::onWrite(const void* buffer, size_t size) +{ + return DeviceObject::RES_UNSUPPORT; +} + +int Template::onIoctl(DeviceObject::IO_Cmd_t cmd, void* data) +{ + switch (cmd.full) { + case 0: + break; + default: + return DeviceObject::RES_UNSUPPORT; + } + return DeviceObject::RES_OK; +} + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(Template); + +#endif diff --git a/x_track/src/App/Service/i18n/lv_i18n.c b/x_track/src/App/Service/i18n/lv_i18n.c new file mode 100644 index 0000000000000000000000000000000000000000..789b46d58a06f040be6a7e9ae985f397a7f70abb --- /dev/null +++ b/x_track/src/App/Service/i18n/lv_i18n.c @@ -0,0 +1,301 @@ +#include "./lv_i18n.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Define plural operands +// http://unicode.org/reports/tr35/tr35-numbers.html#Operands + +// Integer version, simplified + +#ifndef UNUSED +#define UNUSED(x) (void)(x) +#endif + +static inline uint32_t op_n(int32_t val) { return (uint32_t)(val < 0 ? -val : val); } +static inline uint32_t op_i(uint32_t val) { return val; } +// always zero, when decimal part not exists. +static inline uint32_t op_v(uint32_t val) { UNUSED(val); return 0;} +static inline uint32_t op_w(uint32_t val) { UNUSED(val); return 0; } +static inline uint32_t op_f(uint32_t val) { UNUSED(val); return 0; } +static inline uint32_t op_t(uint32_t val) { UNUSED(val); return 0; } + +static lv_i18n_phrase_t en_us_singulars[] = { + {"EPHEMERIS", "Ephemeris"}, + {"LOAD_SUCCESS", "Load Success"}, + {"LOW_BATTERY", "Low Battery"}, + {"SHUTDOWN?", "Shutdown?"}, + {"NO_OPERATION", "No Operation"}, + {"NO", "No"}, + {"YES", "Yes"}, + {"START_RECORD", "Start Record"}, + {"STOP_RECORD", "Stop Record"}, + {"GNSS_NOT_READY", "GNSS Not Ready"}, + {"OPEN_FILE_FAILED", "Open File Failed"}, + {"AVG_SPEED", "AVG"}, + {"TIME", "Time"}, + {"DISTANCE", "Distance"}, + {"CALORIES", "Calories"}, + {"LOADING...", "Loading..."}, + {"POWER_OFF", "Power Off"}, + {"SPORT", "Sport"}, + {"GNSS", "GNSS"}, + {"BATTERY", "Battery"}, + {"ABOUT", "About"}, + {"TOTAL_TRIP", "Total Trip"}, + {"TOTAL_TIME", "Total Time"}, + {"MAX_SPEED", "Max Speed"}, + {"LATITUDE", "Latitude"}, + {"LONGITUDE", "Longitude"}, + {"ALTITUDE", "Altitude"}, + {"UTC_TIME", "UTC Time"}, + {"COURSE", "Course"}, + {"SPEED", "Speed"}, + {"DATE", "Date"}, + {"USAGE", "Usage"}, + {"VOLTAGE", "Voltage"}, + {"STATUS", "Status"}, + {"CHARGE", "Charge"}, + {"DISCHARGE", "Discharge"}, + {"NAME", "Name"}, + {"AUTHOR", "Author"}, + {"GRAPHICS", "GUI"}, + {"COMPILER", "Compiler"}, + {"BUILD_DATE", "Build"}, + {NULL, NULL} // End mark +}; + + + +static uint8_t en_us_plural_fn(int32_t num) +{ + uint32_t n = op_n(num); UNUSED(n); + uint32_t i = op_i(n); UNUSED(i); + uint32_t v = op_v(n); UNUSED(v); + + if ((i == 1 && v == 0)) return LV_I18N_PLURAL_TYPE_ONE; + return LV_I18N_PLURAL_TYPE_OTHER; +} + +static const lv_i18n_lang_t en_us_lang = { + .locale_name = "en-US", + .singulars = en_us_singulars, + + .locale_plural_fn = en_us_plural_fn +}; + +static lv_i18n_phrase_t zh_cn_singulars[] = { + {"EPHEMERIS", "星历"}, + {"LOAD_SUCCESS", "加载成功"}, + {"LOW_BATTERY", "低电量"}, + {"SHUTDOWN?", "关闭?"}, + {"NO_OPERATION", "无操作"}, + {"NO", "否"}, + {"YES", "是"}, + {"START_RECORD", "开始记录"}, + {"STOP_RECORD", "停止记录"}, + {"GNSS_NOT_READY", "GNSS 未就绪"}, + {"OPEN_FILE_FAILED", "打开文件失败"}, + {"AVG_SPEED", "平均速度"}, + {"TIME", "时间"}, + {"DISTANCE", "距离"}, + {"CALORIES", "卡路里"}, + {"LOADING...", "加载中..."}, + {"POWER_OFF", "关机"}, + {"SPORT", "运动"}, + {"GNSS", "卫星"}, + {"BATTERY", "电池"}, + {"ABOUT", "关于"}, + {"TOTAL_TRIP", "总里程"}, + {"TOTAL_TIME", "总时间"}, + {"MAX_SPEED", "最高速度"}, + {"LATITUDE", "纬度"}, + {"LONGITUDE", "经度"}, + {"ALTITUDE", "海拔"}, + {"UTC_TIME", "UTC 时间"}, + {"COURSE", "航向"}, + {"SPEED", "速度"}, + {"DATE", "日期"}, + {"USAGE", "使用量"}, + {"VOLTAGE", "电压"}, + {"STATUS", "状态"}, + {"CHARGE", "充电"}, + {"DISCHARGE", "放电"}, + {"NAME", "名称"}, + {"AUTHOR", "作者"}, + {"GRAPHICS", "图形"}, + {"COMPILER", "编译器"}, + {"BUILD_DATE", "编译日期"}, + {NULL, NULL} // End mark +}; + + + +static uint8_t zh_cn_plural_fn(int32_t num) +{ + + + + return LV_I18N_PLURAL_TYPE_OTHER; +} + +static const lv_i18n_lang_t zh_cn_lang = { + .locale_name = "zh-CN", + .singulars = zh_cn_singulars, + + .locale_plural_fn = zh_cn_plural_fn +}; + +const lv_i18n_language_pack_t lv_i18n_language_pack[] = { + &en_us_lang, + &zh_cn_lang, + NULL // End mark +}; + +//////////////////////////////////////////////////////////////////////////////// + + +// Internal state +static const lv_i18n_language_pack_t * current_lang_pack; +static const lv_i18n_lang_t * current_lang; + + +/** + * Reset internal state. For testing. + */ +void __lv_i18n_reset(void) +{ + current_lang_pack = NULL; + current_lang = NULL; +} + +/** + * Set the languages for internationalization + * @param langs pointer to the array of languages. (Last element has to be `NULL`) + */ +int lv_i18n_init(const lv_i18n_language_pack_t * langs) +{ + if(langs == NULL) return -1; + if(langs[0] == NULL) return -1; + + current_lang_pack = langs; + current_lang = langs[0]; /*Automatically select the first language*/ + return 0; +} + +/** + * Change the localization (language) + * @param l_name name of the translation locale to use. E.g. "en-GB" + */ +int lv_i18n_set_locale(const char * l_name) +{ + if(current_lang_pack == NULL) return -1; + + uint16_t i; + + for(i = 0; current_lang_pack[i] != NULL; i++) { + // Found -> finish + if(strcmp(current_lang_pack[i]->locale_name, l_name) == 0) { + current_lang = current_lang_pack[i]; + return 0; + } + } + + return -1; +} + + +static const char * __lv_i18n_get_text_core(lv_i18n_phrase_t * trans, const char * msg_id) +{ + uint16_t i; + for(i = 0; trans[i].msg_id != NULL; i++) { + if(strcmp(trans[i].msg_id, msg_id) == 0) { + /*The msg_id has found. Check the translation*/ + if(trans[i].translation) return trans[i].translation; + } + } + + return NULL; +} + + +/** + * Get the translation from a message ID + * @param msg_id message ID + * @return the translation of `msg_id` on the set local + */ +const char * lv_i18n_get_text(const char * msg_id) +{ + if(current_lang == NULL) return msg_id; + + const lv_i18n_lang_t * lang = current_lang; + const void * txt; + + // Search in current locale + if(lang->singulars != NULL) { + txt = __lv_i18n_get_text_core(lang->singulars, msg_id); + if (txt != NULL) return txt; + } + + // Try to fallback + if(lang == current_lang_pack[0]) return msg_id; + lang = current_lang_pack[0]; + + // Repeat search for default locale + if(lang->singulars != NULL) { + txt = __lv_i18n_get_text_core(lang->singulars, msg_id); + if (txt != NULL) return txt; + } + + return msg_id; +} + +/** + * Get the translation from a message ID and apply the language's plural rule to get correct form + * @param msg_id message ID + * @param num an integer to select the correct plural form + * @return the translation of `msg_id` on the set local + */ +const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num) +{ + if(current_lang == NULL) return msg_id; + + const lv_i18n_lang_t * lang = current_lang; + const void * txt; + lv_i18n_plural_type_t ptype; + + // Search in current locale + if(lang->locale_plural_fn != NULL) { + ptype = lang->locale_plural_fn(num); + + if(lang->plurals[ptype] != NULL) { + txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id); + if (txt != NULL) return txt; + } + } + + // Try to fallback + if(lang == current_lang_pack[0]) return msg_id; + lang = current_lang_pack[0]; + + // Repeat search for default locale + if(lang->locale_plural_fn != NULL) { + ptype = lang->locale_plural_fn(num); + + if(lang->plurals[ptype] != NULL) { + txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id); + if (txt != NULL) return txt; + } + } + + return msg_id; +} + +/** + * Get the name of the currently used locale. + * @return name of the currently used locale. E.g. "en-GB" + */ +const char * lv_i18n_get_current_locale(void) +{ + if(!current_lang) return NULL; + return current_lang->locale_name; +} diff --git a/x_track/src/App/Service/i18n/lv_i18n.h b/x_track/src/App/Service/i18n/lv_i18n.h new file mode 100644 index 0000000000000000000000000000000000000000..9e803537cc784bb1e52e41d55092f6d43d15b307 --- /dev/null +++ b/x_track/src/App/Service/i18n/lv_i18n.h @@ -0,0 +1,85 @@ +#ifndef LV_I18N_H +#define LV_I18N_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <string.h> + +typedef enum { + LV_I18N_PLURAL_TYPE_ZERO, + LV_I18N_PLURAL_TYPE_ONE, + LV_I18N_PLURAL_TYPE_TWO, + LV_I18N_PLURAL_TYPE_FEW, + LV_I18N_PLURAL_TYPE_MANY, + LV_I18N_PLURAL_TYPE_OTHER, + _LV_I18N_PLURAL_TYPE_NUM, +} lv_i18n_plural_type_t; + +typedef struct { + const char * msg_id; + const char * translation; +} lv_i18n_phrase_t; + +typedef struct { + const char * locale_name; + lv_i18n_phrase_t * singulars; + lv_i18n_phrase_t * plurals[_LV_I18N_PLURAL_TYPE_NUM]; + uint8_t (*locale_plural_fn)(int32_t num); +} lv_i18n_lang_t; + +// Null-terminated list of languages. First one used as default. +typedef const lv_i18n_lang_t * lv_i18n_language_pack_t; + + +extern const lv_i18n_language_pack_t lv_i18n_language_pack[]; + + +/** + * Set the languages for internationalization + * @param langs pointer to the array of languages. (Last element has to be `NULL`) + */ +int lv_i18n_init(const lv_i18n_language_pack_t * langs); + +/** + * Change the localization (language) + * @param l_name name of the translation locale to use. E.g. "en_GB" + */ +int lv_i18n_set_locale(const char * l_name); + +/** + * Get the translation from a message ID + * @param msg_id message ID + * @return the translation of `msg_id` on the set local + */ +const char * lv_i18n_get_text(const char * msg_id); + +/** + * Get the translation from a message ID and apply the language's plural rule to get correct form + * @param msg_id message ID + * @param num an integer to select the correct plural form + * @return the translation of `msg_id` on the set local + */ +const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num); + +/** + * Get the name of the currently used localization. + * @return name of the currently used localization. E.g. "en_GB" + */ +const char * lv_i18n_get_current_locale(void); + + +void __lv_i18n_reset(void); + + +#define _(text) lv_i18n_get_text(text) +#define _p(text, num) lv_i18n_get_text_plural(text, num) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_LANG_H*/ diff --git a/x_track/src/App/Service/i18n/translations/en-US.yml b/x_track/src/App/Service/i18n/translations/en-US.yml new file mode 100644 index 0000000000000000000000000000000000000000..a1e543061c4d1e7a9010e939343c5eac0804ec96 --- /dev/null +++ b/x_track/src/App/Service/i18n/translations/en-US.yml @@ -0,0 +1,42 @@ +en-US: + EPHEMERIS: Ephemeris + LOAD_SUCCESS: Load Success + LOW_BATTERY: Low Battery + SHUTDOWN?: Shutdown? + NO_OPERATION: No Operation + 'NO': 'No' + 'YES': 'Yes' + START_RECORD: Start Record + STOP_RECORD: Stop Record + GNSS_NOT_READY: GNSS Not Ready + OPEN_FILE_FAILED: Open File Failed + AVG_SPEED: AVG + TIME: Time + DISTANCE: Distance + CALORIES: Calories + LOADING...: Loading... + POWER_OFF: Power Off + SPORT: Sport + GNSS: GNSS + BATTERY: Battery + ABOUT: About + TOTAL_TRIP: Total Trip + TOTAL_TIME: Total Time + MAX_SPEED: Max Speed + LATITUDE: Latitude + LONGITUDE: Longitude + ALTITUDE: Altitude + UTC_TIME: UTC Time + COURSE: Course + SPEED: Speed + DATE: Date + USAGE: Usage + VOLTAGE: Voltage + STATUS: Status + CHARGE: Charge + DISCHARGE: Discharge + NAME: Name + AUTHOR: Author + GRAPHICS: GUI + COMPILER: Compiler + BUILD_DATE: Build diff --git a/x_track/src/App/Service/i18n/translations/zh-CN.yml b/x_track/src/App/Service/i18n/translations/zh-CN.yml new file mode 100644 index 0000000000000000000000000000000000000000..28fb58f844eb5072447058d508d3bf201c7ce5e1 --- /dev/null +++ b/x_track/src/App/Service/i18n/translations/zh-CN.yml @@ -0,0 +1,42 @@ +zh-CN: + EPHEMERIS: 星历 + LOAD_SUCCESS: 加载成功 + LOW_BATTERY: 低电量 + SHUTDOWN?: 关闭? + NO_OPERATION: 无操作 + 'NO': 否 + 'YES': 是 + START_RECORD: 开始记录 + STOP_RECORD: 停止记录 + GNSS_NOT_READY: GNSS 未就绪 + OPEN_FILE_FAILED: 打开文件失败 + AVG_SPEED: 平均速度 + TIME: 时间 + DISTANCE: 距离 + CALORIES: 卡路里 + LOADING...: 加载中... + POWER_OFF: 关机 + SPORT: 运动 + GNSS: 卫星 + BATTERY: 电池 + ABOUT: 关于 + TOTAL_TRIP: 总里程 + TOTAL_TIME: 总时间 + MAX_SPEED: 最高速度 + LATITUDE: 纬度 + LONGITUDE: 经度 + ALTITUDE: 海拔 + UTC_TIME: UTC 时间 + COURSE: 航向 + SPEED: 速度 + DATE: 日期 + USAGE: 使用量 + VOLTAGE: 电压 + STATUS: 状态 + CHARGE: 充电 + DISCHARGE: 放电 + NAME: 名称 + AUTHOR: 作者 + GRAPHICS: 图形 + COMPILER: 编译器 + BUILD_DATE: 编译日期 diff --git a/x_track/src/App/Service/i18n/update_translation.sh b/x_track/src/App/Service/i18n/update_translation.sh new file mode 100755 index 0000000000000000000000000000000000000000..eb139595158bf93b01ddd33c99897f2a93066936 --- /dev/null +++ b/x_track/src/App/Service/i18n/update_translation.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Check if lv_i18n is installed +if npm list -g lv_i18n >/dev/null 2>&1; then + echo "lv_i18n is already installed." +else + echo "lv_i18n is not installed. Please run the following command to install it:" + echo "npm install -g littlevgl/lv_i18n" + exit -1 +fi + +lv_i18n extract -s '../../**/*.+(c|cpp|h|hpp)' -t './translations/*.yml' +lv_i18n compile -t './translations/*.yml' -o './' diff --git a/x_track/src/App/UI/AppFactory.cpp b/x_track/src/App/UI/AppFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fae76d76f85828a7ecc8b57647f86984f88067cd --- /dev/null +++ b/x_track/src/App/UI/AppFactory.cpp @@ -0,0 +1,62 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "AppFactory.h" +#include <cstring> + +AppFactory::AppFactory() + : _nameArray { 0 } + , _descriptorArray { 0 } + , _num(0) +{ +} + +AppFactory::~AppFactory() { } + +void AppFactory::add(const char* name, AppDescriptor* descriptor) +{ + if (_num >= APP_FACTORY_MAX_NUM) { + return; + } + + _nameArray[_num] = name; + _descriptorArray[_num] = descriptor; + _num++; +} + +PageBase* AppFactory::create(const char* name) +{ + for (int i = 0; i < _num; i++) { + if (strcmp(name, _nameArray[i]) == 0) { + return _descriptorArray[i]->create(); + } + } + + return nullptr; +} + +void AppFactory::intsallAll(PageManager* manager) +{ + for (int i = 0; i < _num; i++) { + manager->install(_nameArray[i], nullptr); + } +} diff --git a/x_track/src/App/UI/AppFactory.h b/x_track/src/App/UI/AppFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..08add7920aac7a6f0ddf8362ab675e6e9f66a464 --- /dev/null +++ b/x_track/src/App/UI/AppFactory.h @@ -0,0 +1,81 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __APP_FACTORY_H +#define __APP_FACTORY_H + +#include "Frameworks/PageManager/PageManager.h" + +#ifndef APP_FACTORY_MAX_NUM +#define APP_FACTORY_MAX_NUM 32 +#endif + +#define APP_DESCRIPTOR_DEF(name) \ + class name##Descriptor : public AppDescriptor { \ + public: \ + name##Descriptor() \ + : AppDescriptor(#name) \ + { \ + } \ + virtual PageBase* create() { return new name; } \ + }; \ + static name##Descriptor name##DescriptorInstance; \ + void name##Constructor() { (void)&name##DescriptorInstance; } + +/* Force reference to DescriptorInstance to prevent optimization */ +#define APP_DESCRIPTOR_IMPORT(name) \ + extern void name##Constructor(); \ + name##Constructor(); + +class AppDescriptor; + +class AppFactory : public PageFactory { +public: + AppFactory(); + virtual ~AppFactory(); + virtual PageBase* create(const char* name); + void add(const char* name, AppDescriptor* descriptor); + + static AppFactory* getInstance() + { + static AppFactory instance; + return &instance; + } + + void intsallAll(PageManager* manager); + +private: + const char* _nameArray[APP_FACTORY_MAX_NUM]; + AppDescriptor* _descriptorArray[APP_FACTORY_MAX_NUM]; + int _num; +}; + +class AppDescriptor { +public: + AppDescriptor(const char* name) + { + AppFactory::getInstance()->add(name, this); + } + virtual PageBase* create() = 0; +}; + +#endif /* __APP_FACTORY_H */ diff --git a/x_track/src/App/UI/Dashboard/BindingDef.inc b/x_track/src/App/UI/Dashboard/BindingDef.inc new file mode 100644 index 0000000000000000000000000000000000000000..9c36fa55a29f4cc9e4693678decc455dd0cdaa52 --- /dev/null +++ b/x_track/src/App/UI/Dashboard/BindingDef.inc @@ -0,0 +1,3 @@ +/* Binding definition */ + +BINDING_DEF(Rec, bool) diff --git a/x_track/src/App/UI/Dashboard/Dashboard.cpp b/x_track/src/App/UI/Dashboard/Dashboard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d1975b37c06cf173a5e8ed77940f370a5cac8a05 --- /dev/null +++ b/x_track/src/App/UI/Dashboard/Dashboard.cpp @@ -0,0 +1,124 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Dashboard.h" +#include <cmath> + +using namespace Page; + +APP_DESCRIPTOR_DEF(Dashboard); + +Dashboard::Dashboard() + : _model(nullptr) + , _view(nullptr) +{ +} + +Dashboard::~Dashboard() +{ +} + +void Dashboard::onInstalled() +{ + setLoadAnimType(PAGE_ANIM::NONE); +} + +void Dashboard::onViewLoad() +{ + _model = new DashboardModel(this); + _view = new DashboardView(this, getRoot()); +} + +void Dashboard::onViewDidLoad() +{ +} + +void Dashboard::onViewWillAppear() +{ +} + +void Dashboard::onViewDidAppear() +{ + Param_t param; + param.animEnable = false, + + PAGE_GET_PARAM(param); + if (param.animEnable) { + _view->publish(DashboardView::MSG_ID::ANIM_START); + } +} + +void Dashboard::onViewWillDisappear() +{ +} + +void Dashboard::onViewDidDisappear() +{ +} + +void Dashboard::onViewUnload() +{ + delete _model; + delete _view; +} + +void Dashboard::onViewDidUnload() +{ +} + +void Dashboard::onModelEvent(DashboardModel::EVENT_ID id, const void* param) +{ + switch (id) { + case DashboardModel::EVENT_ID::SPORT_STATUS: { + _view->publish(DashboardView::MSG_ID::SPORT_STATUS, param); + } break; + + case DashboardModel::EVENT_ID::RECORDER_STATUS: { + _view->publish(DashboardView::MSG_ID::RECORDER_STATUS, param); + } break; + + case DashboardModel::EVENT_ID::GNSS: { + _view->publish(DashboardView::MSG_ID::GNSS_STATUS, param); + } break; + + default: + break; + } +} + +void Dashboard::onViewEvent(DashboardView::EVENT_ID id, const void* param) +{ + switch (id) { + case DashboardView::EVENT_ID::GET_BINDING: { + auto binding = (DashboardView::Binding_Info_t*)param; + binding->binding = _model->getBinding((DashboardModel::BINDING_TYPE)binding->type); + } break; + + case DashboardView::EVENT_ID::NAVI_TO_PAGE: { + auto pageID = (const char*)param; + getManager()->push(pageID); + }; break; + + default: + break; + } +} diff --git a/x_track/src/App/UI/Dashboard/Dashboard.h b/x_track/src/App/UI/Dashboard/Dashboard.h new file mode 100644 index 0000000000000000000000000000000000000000..203e13a2a335db0131f6c596cb59ae0adfcdf422 --- /dev/null +++ b/x_track/src/App/UI/Dashboard/Dashboard.h @@ -0,0 +1,62 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DASHBOARD_PRESENTER_H +#define __DASHBOARD_PRESENTER_H + +#include "DashboardModel.h" +#include "DashboardView.h" + +namespace Page { + +class Dashboard : public PageBase, public DashboardModel::EventListener, public DashboardView::EventListener { +public: + typedef struct { + bool animEnable; + } Param_t; + +public: + Dashboard(); + virtual ~Dashboard(); + + virtual void onInstalled(); + virtual void onViewLoad(); + virtual void onViewDidLoad(); + virtual void onViewWillAppear(); + virtual void onViewDidAppear(); + virtual void onViewWillDisappear(); + virtual void onViewDidDisappear(); + virtual void onViewUnload(); + virtual void onViewDidUnload(); + +private: + virtual void onModelEvent(DashboardModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(DashboardView::EVENT_ID id, const void* param) override; + +private: + DashboardModel* _model; + DashboardView* _view; +}; + +} + +#endif diff --git a/x_track/src/App/UI/Dashboard/DashboardModel.cpp b/x_track/src/App/UI/Dashboard/DashboardModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..50a0626c86dffb2b674c16f0b2f7a81a2fd89cd0 --- /dev/null +++ b/x_track/src/App/UI/Dashboard/DashboardModel.cpp @@ -0,0 +1,84 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DashboardModel.h" + +using namespace Page; + +DashboardModel::DashboardModel(EventListener* listener) + : DataNode(__func__, DataProc::broker()) + , _listener(listener) + , _env(this) +{ + _nodeSportStatus = subscribe("SportStatus"); + _nodeRecorder = subscribe("Recorder"); + _nodeGNSS = subscribe("GNSS"); + setEventFilter(DataNode::EVENT_PUBLISH); +} + +DashboardModel::~DashboardModel() +{ +} + +void DashboardModel::initBingdings() +{ + _bindingRec.setCallback( + /* setter */ + [](DashboardModel* self, bool v) { + DataProc::Recorder_Info_t info; + info.active = v; + self->notify(self->_nodeRecorder, &info, sizeof(info)); + }, + /* getter */ + [](DashboardModel* self) -> bool { + DataProc::Recorder_Info_t info; + self->pull(self->_nodeRecorder, &info, sizeof(info)); + return info.active; + }, + this); +} + +void* DashboardModel::getBinding(BINDING_TYPE type) +{ + switch (type) { +#define BINDING_DEF(name, type) \ + case BINDING_TYPE::name: \ + return &_binding##name; +#include "BindingDef.inc" +#undef BINDING_DEF + default: + return nullptr; + } +} + +int DashboardModel::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeSportStatus) { + _listener->onModelEvent(EVENT_ID::SPORT_STATUS, param->data_p); + } else if (param->tran == _nodeRecorder) { + _listener->onModelEvent(EVENT_ID::RECORDER_STATUS, param->data_p); + } else if (param->tran == _nodeGNSS) { + _listener->onModelEvent(EVENT_ID::GNSS, param->data_p); + } + + return DataNode::RES_OK; +} diff --git a/x_track/src/App/UI/Dashboard/DashboardModel.h b/x_track/src/App/UI/Dashboard/DashboardModel.h new file mode 100644 index 0000000000000000000000000000000000000000..807cb8009e7196c58d1c5c688654bd3bce64d42e --- /dev/null +++ b/x_track/src/App/UI/Dashboard/DashboardModel.h @@ -0,0 +1,84 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DASHBOARD_MODEL_H +#define __DASHBOARD_MODEL_H + +#include "Service/DataProc/DataProc.h" +#include "Utils/Binding/Binding.h" + +namespace Page { + +class DashboardModel : private DataNode { + +public: + enum class EVENT_ID { + SPORT_STATUS, /* param: SportStatus_Info_t */ + RECORDER_STATUS, /* param: Recorder_Info_t */ + GNSS, /* param: GNSS_Info_t */ + _EVENT_LAST, + }; + + enum class BINDING_TYPE { +#define BINDING_DEF(name, type) name, +#include "BindingDef.inc" +#undef BINDING_DEF + }; + + typedef struct { + BINDING_TYPE type; + void* binding; + } Binding_Info_t; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + DashboardModel(EventListener* listener); + ~DashboardModel(); + void initBingdings(); + void* getBinding(BINDING_TYPE type); + DataProc::Env_Helper* env() + { + return &_env; + } + +private: + EventListener* _listener; + const DataNode* _nodeSportStatus; + const DataNode* _nodeRecorder; + const DataNode* _nodeGNSS; + DataProc::Env_Helper _env; + +#define BINDING_DEF(name, type) Binding<type, DashboardModel> _binding##name; +#include "BindingDef.inc" +#undef BINDING_DEF + +private: + virtual int onEvent(DataNode::EventParam_t* param); +}; + +} /* namespace Page */ + +#endif diff --git a/x_track/src/App/UI/Dashboard/DashboardView.cpp b/x_track/src/App/UI/Dashboard/DashboardView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dad123f84a9dce6e18393cbb9e53a4974540da00 --- /dev/null +++ b/x_track/src/App/UI/Dashboard/DashboardView.cpp @@ -0,0 +1,397 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DashboardView.h" +#include "Service/DataProc/DataProc_Def.h" +#include "Service/HAL/HAL_Def.h" +#include "Utils/Geo/Geo.h" +#include "Utils/lv_ext/lv_anim_timeline_wrapper.h" +#include "Utils/lv_ext/lv_ext_func.h" +#include <stdarg.h> +#include <stdio.h> + +using namespace Page; + +DashboardView::DashboardView(EventListener* listener, lv_obj_t* root) + : _listener(listener) + , _fontLarge(65, "regular") +#define BINDING_DEF(name, type) , _binding##name((Binding<type, DashboardModel>*)getBinding(BINDING_TYPE::name)) +#include "BindingDef.inc" +#undef BINDING_DEF +{ + lv_obj_set_style_pad_all(root, 0, 0); + + lv_obj_t* topInfoCont = topInfoCreate(root); + lv_obj_t* bottomInfoCont = bottomInfoCreate(root); + lv_obj_t* btnGrpCont = btnGroupCreate(root); + lv_obj_move_foreground(topInfoCont); + + _anim_timeline = lv_anim_timeline_create(); + +#define ANIM_DEF(start_time, obj, attr, start, end) \ + { \ + start_time, obj, LV_ANIM_EXEC(attr), start, end, 500, lv_anim_path_ease_out, true \ + } + + auto lv_obj_set_opa = [](void* obj, int32_t v) { + lv_obj_set_style_opa((lv_obj_t*)obj, v, 0); + }; + + auto lv_obj_set_trans_y = [](void* obj, int32_t v) { + lv_obj_set_style_translate_y((lv_obj_t*)obj, v, 0); + }; + + auto lv_obj_set_trans_h = [](void* obj, int32_t v) { + lv_obj_set_style_transform_height((lv_obj_t*)obj, v, 0); + }; + + auto lv_obj_set_text_opa = [](void* obj, int32_t v) { + lv_obj_set_style_text_opa((lv_obj_t*)obj, v, 0); + }; + + lv_obj_update_layout(root); + lv_coord_t btn_h = lv_obj_get_height(lv_obj_get_child(btnGrpCont, 0)); + + lv_anim_timeline_wrapper_t wrapper[] = { + ANIM_DEF(0, topInfoCont, trans_y, -lv_obj_get_height(topInfoCont), 0), + ANIM_DEF(200, bottomInfoCont, trans_y, -lv_obj_get_height(bottomInfoCont), 0), + ANIM_DEF(200, bottomInfoCont, opa, LV_OPA_TRANSP, LV_OPA_COVER), + + ANIM_DEF(500, lv_obj_get_child(btnGrpCont, 0), trans_h, -btn_h, 0), + ANIM_DEF(600, lv_obj_get_child(btnGrpCont, 1), trans_h, -btn_h, 0), + ANIM_DEF(700, lv_obj_get_child(btnGrpCont, 2), trans_h, -btn_h, 0), + ANIM_DEF(900, btnGrpCont, text_opa, LV_OPA_TRANSP, LV_OPA_COVER), + LV_ANIM_TIMELINE_WRAPPER_END + }; + lv_anim_timeline_add_wrapper(_anim_timeline, wrapper); + lv_anim_timeline_set_progress(_anim_timeline, 0); + + subscribe( + MSG_ID::ANIM_START, + root, + [](lv_event_t* e) { + auto self = (DashboardView*)lv_event_get_user_data(e); + auto msg = lv_event_get_msg(e); + if (lv_msg_get_id(msg) != self->msgID(MSG_ID::ANIM_START)) { + return; + } + + lv_anim_timeline_start(self->_anim_timeline); + }, + this); +} + +DashboardView::~DashboardView() +{ +} + +lv_uintptr_t DashboardView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void DashboardView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void DashboardView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb, void* user_data) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, user_data); +} + +void* DashboardView::getBinding(BINDING_TYPE type) +{ + Binding_Info_t info; + info.type = type; + info.binding = nullptr; + _listener->onViewEvent(EVENT_ID::GET_BINDING, &info); + return info.binding; +} + +lv_obj_t* DashboardView::topInfoCreate(lv_obj_t* par) +{ + lv_obj_t* cont = lv_obj_create(par); + { + lv_obj_remove_style_all(cont); + lv_obj_set_size(cont, lv_pct(100), 135); + + lv_obj_set_style_bg_opa(cont, LV_OPA_COVER, 0); + lv_obj_set_style_bg_color(cont, lv_color_hex(0x333333), 0); + + lv_obj_set_style_radius(cont, 27, 0); + lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, -27); + + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + cont, + LV_FLEX_ALIGN_END, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + } + + { + lv_obj_t* label = lv_label_create(cont); + lv_obj_set_style_text_font(label, _fontLarge, 0); + lv_obj_set_style_text_color(label, lv_color_white(), 0); + lv_obj_set_style_translate_y(label, 10, 0); + lv_label_set_text_static(label, "00"); + + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%02d", (int)info->speedKph); + }); + } + + { + lv_obj_t* label = lv_label_create(cont); + lv_obj_set_style_text_color(label, lv_color_white(), 0); + lv_obj_set_style_translate_y(label, -5, 0); + lv_label_set_text_static(label, "km/h"); + } + + return cont; +} + +lv_obj_t* DashboardView::bottomInfoCreate(lv_obj_t* par) +{ + lv_obj_t* cont = lv_obj_create(par); + lv_obj_remove_style_all(cont); + lv_obj_set_size(cont, lv_pct(100), 160); + lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 110); + + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP); + lv_obj_set_flex_align( + cont, + LV_FLEX_ALIGN_SPACE_EVENLY, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_SPACE_EVENLY); + + { + lv_obj_t* label = infoItemCreate(cont, _("AVG_SPEED")); + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%0.1f km/h", info->speedAvgKph); + }); + } + + { + lv_obj_t* label = infoItemCreate(cont, _("TIME")); + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%s", makeTimeString(info->singleTime)); + }); + } + + { + lv_obj_t* label = infoItemCreate(cont, _("DISTANCE")); + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%0.1f km", info->singleDistance / 1000.0f); + }); + } + + { + lv_obj_t* label = infoItemCreate(cont, _("ALTITUDE")); + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%0.1f m", info->altitude); + }); + } + + { + lv_obj_t* label = infoItemCreate(cont, _("CALORIES")); + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%d k", (int)info->singleCalorie); + }); + } + + { + lv_obj_t* label = infoItemCreate(cont, _("COURSE")); + subscribe( + MSG_ID::GNSS_STATUS, + label, + [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto info = (const HAL::GNSS_Info_t*)lv_msg_get_payload(msg); + auto obj = lv_event_get_current_target_obj(e); + lv_label_set_text_fmt(obj, "%s", Geo::cardinal(info->course)); + }); + } + + return cont; +} + +lv_obj_t* DashboardView::infoItemCreate(lv_obj_t* par, const char* title) +{ + lv_obj_t* cont = lv_obj_create(par); + lv_obj_remove_style_all(cont); + lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_size(cont, 100, 39); + + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + cont, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + lv_obj_t* labelValue = lv_label_create(cont); + lv_label_set_text_static(labelValue, "-"); + + { + lv_obj_t* label = lv_label_create(cont); + lv_obj_set_style_text_color(label, lv_color_hex(0xb3b3b3), 0); + lv_label_set_text(label, title); + } + + return labelValue; +} + +lv_obj_t* DashboardView::btnGroupCreate(lv_obj_t* par) +{ + lv_obj_t* cont = lv_obj_create(par); + lv_obj_remove_style_all(cont); + lv_obj_set_size(cont, lv_pct(100), 40); + lv_obj_align(cont, LV_ALIGN_BOTTOM_MID, 0, -10); + + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align( + cont, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + btnCreate(cont, LV_SYMBOL_EXT_LOCATION_DOT, "LiveMap"); + btnCreate(cont, LV_SYMBOL_EXT_POWER_OFF, "Shutdown"); + btnCreate(cont, LV_SYMBOL_EXT_BARS, "SystemInfos"); + + return cont; +} + +lv_obj_t* DashboardView::btnCreate(lv_obj_t* par, const char* symbol, const char* pageID) +{ + lv_obj_t* btn = lv_obj_create(par); + lv_obj_remove_style_all(btn); + lv_obj_set_size(btn, 40, 31); + lv_obj_clear_flag(btn, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* label = lv_label_create(btn); + lv_label_set_text_static(label, symbol); + lv_obj_center(label); + + lv_obj_set_style_bg_opa(btn, LV_OPA_COVER, 0); + lv_obj_set_style_transform_width(btn, 5, LV_STATE_PRESSED); + lv_obj_set_style_transform_height(btn, -5, LV_STATE_PRESSED); + lv_obj_set_style_bg_color(btn, lv_color_hex(0x666666), 0); + lv_obj_set_style_bg_color(btn, lv_color_hex(0xbbbbbb), LV_STATE_PRESSED); + lv_obj_set_style_bg_color(btn, lv_color_hex(0xff931e), LV_STATE_FOCUSED); + lv_obj_set_style_radius(btn, 9, 0); + + static lv_style_transition_dsc_t tran; + static const lv_style_prop_t prop[] = { + LV_STYLE_TRANSFORM_WIDTH, + LV_STYLE_TRANSFORM_HEIGHT, + LV_STYLE_PROP_INV + }; + lv_style_transition_dsc_init( + &tran, + prop, + lv_anim_path_ease_out, + 200, + 0, + nullptr); + lv_obj_set_style_transition(btn, &tran, LV_STATE_PRESSED); + lv_obj_set_style_transition(btn, &tran, LV_STATE_FOCUSED); + + if (pageID) { + lv_obj_set_user_data(btn, (void*)pageID); + lv_obj_add_event_cb( + btn, + [](lv_event_t* e) { + auto self = (DashboardView*)lv_event_get_user_data(e); + auto id = lv_obj_get_user_data(lv_event_get_current_target_obj(e)); + self->_listener->onViewEvent(EVENT_ID::NAVI_TO_PAGE, id); + }, + LV_EVENT_CLICKED, + this); + } + + return btn; +} + +const char* DashboardView::makeTimeString(uint64_t ms) +{ + static char buf[16]; + uint64_t ss = ms / 1000; + uint64_t mm = ss / 60; + uint32_t hh = (uint32_t)(mm / 60); + + if (hh < 100) { + lv_snprintf( + buf, sizeof(buf), + "%d:%02d:%02d", + (int)hh, + (int)(mm % 60), + (int)(ss % 60)); + } else { + lv_snprintf( + buf, sizeof(buf), + "%d:%02d", + (int)hh, + (int)(mm % 60)); + } + + return buf; +} diff --git a/x_track/src/App/UI/Dashboard/DashboardView.h b/x_track/src/App/UI/Dashboard/DashboardView.h new file mode 100644 index 0000000000000000000000000000000000000000..ba7acac346cd6261e16d14484daad8f59383f55a --- /dev/null +++ b/x_track/src/App/UI/Dashboard/DashboardView.h @@ -0,0 +1,98 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DASHBOARD_VIEW_H +#define __DASHBOARD_VIEW_H + +#include "../Page.h" +#include "Utils/Binding/Binding.h" + +namespace Page { + +class DashboardModel; + +class DashboardView { +public: + enum class EVENT_ID { + GET_BINDING, /* Param: Binding_Info_t */ + NAVI_TO_PAGE, /* Param: const char* */ + _LAST, + }; + + enum class MSG_ID { + NONE, + SPORT_STATUS, /* param: SportStatus_Info_t */ + RECORDER_STATUS, /* param: Recorder_Info_t */ + GNSS_STATUS, /* param: GNSS_Info_t */ + ANIM_START, /* param: None */ + _LAST + }; + + enum class BINDING_TYPE { +#define BINDING_DEF(name, type) name, +#include "BindingDef.inc" +#undef BINDING_DEF + }; + + typedef struct { + BINDING_TYPE type; + void* binding; + } Binding_Info_t; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + DashboardView(EventListener* listener, lv_obj_t* root); + ~DashboardView(); + void publish(MSG_ID id, const void* payload = nullptr); + +private: + EventListener* _listener; + ResourcePool::Font _fontLarge; + lv_anim_timeline_t* _anim_timeline; + +#define BINDING_DEF(name, type) Binding<type, DashboardModel>* _binding##name; +#include "BindingDef.inc" +#undef BINDING_DEF + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t cb, void* user_data = nullptr); + void* getBinding(BINDING_TYPE type); + + lv_obj_t* topInfoCreate(lv_obj_t* par); + + lv_obj_t* bottomInfoCreate(lv_obj_t* par); + lv_obj_t* infoItemCreate(lv_obj_t* par, const char* title); + + lv_obj_t* btnGroupCreate(lv_obj_t* par); + lv_obj_t* btnCreate(lv_obj_t* par, const char* symbol, const char* pageID = nullptr); + + static const char* makeTimeString(uint64_t ms); +}; + +} + +#endif /* __DASHBOARD_VIEW_H */ diff --git a/x_track/src/App/UI/LiveMap/LiveMap.cpp b/x_track/src/App/UI/LiveMap/LiveMap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..107fe88352a9c6e86bf86035fc9255f4d12776da --- /dev/null +++ b/x_track/src/App/UI/LiveMap/LiveMap.cpp @@ -0,0 +1,161 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "LiveMap.h" + +using namespace Page; + +APP_DESCRIPTOR_DEF(LiveMap); + +LiveMap::LiveMap() + : _model(nullptr) + , _view(nullptr) +{ +} + +LiveMap::~LiveMap() +{ +} + +void LiveMap::onInstalled() +{ + /* workaround page is hidden after the model is not disconnected */ + setAutoCacheEnable(false); + + setBackGestureDirection(LV_DIR_RIGHT); +} + +void LiveMap::onViewLoad() +{ + _model = new LiveMapModel(this); + _view = new LiveMapView(this, getRoot()); + + DataProc::Map_Info_t mapInfo; + if (_model->getMapInfo(&mapInfo)) { + MapView::MapConfig_t config; + config.path = mapInfo.path; + config.ext = mapInfo.ext; + config.levelMin = mapInfo.levelMin; + config.levelMax = mapInfo.levelMax; + config.coordTrans = mapInfo.coordTrans; + _view->publish(LiveMapView::MSG_ID::MAP_CONFIG_UPDATE, &config); + } +} + +void LiveMap::onViewDidLoad() +{ +} + +void LiveMap::onViewWillAppear() +{ +} + +void LiveMap::onViewDidAppear() +{ + _model->env()->set("statusbar-opa", "light"); + + _model->loadSportStatusInfo(); + + int mapLevel = _model->getMapLevel(); + onModelEvent(LiveMapModel::EVENT_ID::MAP_LEVEL_CHANGE, &mapLevel); + + DataProc::TrackFilter_Info_t trackFilterInfo; + if (_model->getTrackFilterInfo(&trackFilterInfo)) { + onModelEvent(LiveMapModel::EVENT_ID::TRACK_REC, &trackFilterInfo); + } + + HAL::GNSS_Info_t gnssInfo; + if (_model->getGNSSInfo(&gnssInfo)) { + onModelEvent(LiveMapModel::EVENT_ID::GNSS, &gnssInfo); + + /* enable gnss event */ + _model->setGNSSEnable(true); + } +} + +void LiveMap::onViewWillDisappear() +{ + /* disable gnss event */ + _model->setGNSSEnable(false); + + int mapLevel = _model->getMapLevel(); + char buf[8]; + lv_snprintf(buf, sizeof(buf), "%d", mapLevel); + _model->env()->set("maplevel", buf); +} + +void LiveMap::onViewDidDisappear() +{ +} + +void LiveMap::onViewUnload() +{ + delete _model; + delete _view; +} + +void LiveMap::onViewDidUnload() +{ +} + +void LiveMap::onModelEvent(LiveMapModel::EVENT_ID id, const void* param) +{ + switch (id) { + case LiveMapModel::EVENT_ID::SPORT_STATUS: { + _view->publish(LiveMapView::MSG_ID::SPORT_STATUS, param); + } break; + + case LiveMapModel::EVENT_ID::GNSS: { + auto gnssInfo = (const HAL::GNSS_Info_t*)param; + MapView::GeoCoord_t geoCoord; + geoCoord.longitude = gnssInfo->longitude; + geoCoord.latitude = gnssInfo->latitude; + geoCoord.altitude = gnssInfo->altitude; + geoCoord.course = gnssInfo->course; + _view->publish(LiveMapView::MSG_ID::GEO_COORD_UPDATE, &geoCoord); + } break; + + case LiveMapModel::EVENT_ID::MAP_LEVEL_CHANGE: + _view->publish(LiveMapView::MSG_ID::MAP_SET_LEVEL, param); + break; + + case LiveMapModel::EVENT_ID::TRACK_REC: + _view->publish(LiveMapView::MSG_ID::TRACK_REC, param); + break; + + default: + break; + } +} + +void LiveMap::onViewEvent(LiveMapView::EVENT_ID id, const void* param) +{ + switch (id) { + case LiveMapView::EVENT_ID::MAP_LEVEL_CHANGED: { + int mapLevel = *(const int*)param; + _model->setMapLevel(mapLevel); + } break; + + default: + break; + } +} diff --git a/x_track/src/App/UI/LiveMap/LiveMap.h b/x_track/src/App/UI/LiveMap/LiveMap.h new file mode 100644 index 0000000000000000000000000000000000000000..5b353f93a91f04038bb5fbbfd5575848456f579a --- /dev/null +++ b/x_track/src/App/UI/LiveMap/LiveMap.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __LIVE_MAP_PRESENTER_H +#define __LIVE_MAP_PRESENTER_H + +#include "LiveMapModel.h" +#include "LiveMapView.h" + +namespace Page { + +class LiveMap : public PageBase, public LiveMapModel::EventListener, public LiveMapView::EventListener { +public: + LiveMap(); + virtual ~LiveMap(); + + virtual void onInstalled(); + virtual void onViewLoad(); + virtual void onViewDidLoad(); + virtual void onViewWillAppear(); + virtual void onViewDidAppear(); + virtual void onViewWillDisappear(); + virtual void onViewDidDisappear(); + virtual void onViewUnload(); + virtual void onViewDidUnload(); + +private: + LiveMapModel* _model; + LiveMapView* _view; + +private: + virtual void onModelEvent(LiveMapModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(LiveMapView::EVENT_ID id, const void* param) override; +}; + +} + +#endif diff --git a/x_track/src/App/UI/LiveMap/LiveMapModel.cpp b/x_track/src/App/UI/LiveMap/LiveMapModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9538e13a6de8e8a78fe1c8c4106897e89a80084f --- /dev/null +++ b/x_track/src/App/UI/LiveMap/LiveMapModel.cpp @@ -0,0 +1,139 @@ + +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "LiveMapModel.h" +#include <stdlib.h> + +using namespace Page; + +LiveMapModel::LiveMapModel(EventListener* listener) + : DataNode(__func__, DataProc::broker()) + , _listener(listener) + , _env(this) + , _mapLevel(0) + , _gnssEnable(false) +{ + _nodeGNSS = subscribe("GNSS"); + _nodeSportStatus = subscribe("SportStatus"); + _nodeTrackFilter = subscribe("TrackFilter"); + + subscribe("MapInfo"); + setEventFilter(DataNode::EVENT_PUBLISH); + + auto maplevelStr = _env.get("maplevel"); + if (maplevelStr) { + _mapLevel = atoi(maplevelStr); + } else { + DataProc::Map_Info_t mapInfo; + if (getMapInfo(&mapInfo)) { + _mapLevel = mapInfo.levelMax; + } + } +} + +LiveMapModel::~LiveMapModel() +{ +} + +bool LiveMapModel::getGNSSInfo(HAL::GNSS_Info_t* info) +{ + if (pull(_nodeGNSS, info, sizeof(HAL::GNSS_Info_t)) == DataNode::RES_OK) { + if (info->isVaild) { + return true; + } + } + + memset(info, 0, sizeof(HAL::GNSS_Info_t)); + + /* Use default location */ + DataProc::SportStatus_Info_t ssInfo; + if (pull(_nodeSportStatus, &ssInfo, sizeof(ssInfo)) == DataNode::RES_OK) { + info->longitude = ssInfo.longitude; + info->latitude = ssInfo.latitude; + return true; + } + + return false; +} + +bool LiveMapModel::getMapInfo(DataProc::Map_Info_t* info) +{ + if (_mapInfo.path) { + *info = _mapInfo; + return true; + } + + if (pull("MapInfo", &_mapInfo, sizeof(DataProc::Map_Info_t)) == DataNode::RES_OK) { + *info = _mapInfo; + return true; + } + + return false; +} + +bool LiveMapModel::setMapLevel(int level, bool sendEvent) +{ + DataProc::Map_Info_t mapInfo; + if (!getMapInfo(&mapInfo)) { + return false; + } + + if (level < mapInfo.levelMin || level > mapInfo.levelMax) { + return false; + } + + _mapLevel = level; + if (sendEvent) { + _listener->onModelEvent(EVENT_ID::MAP_LEVEL_CHANGE, &_mapLevel); + } + + return true; +} + +bool LiveMapModel::getTrackFilterInfo(DataProc::TrackFilter_Info_t* info) +{ + return pull(_nodeTrackFilter, info, sizeof(DataProc::TrackFilter_Info_t)) == DataNode::RES_OK; +} + +void LiveMapModel::loadSportStatusInfo() +{ + DataProc::SportStatus_Info_t info; + if (pull(_nodeSportStatus, &info, sizeof(info)) != DataNode::RES_OK) { + return; + } + + _listener->onModelEvent(EVENT_ID::SPORT_STATUS, &info); +} + +int LiveMapModel::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeSportStatus) { + _listener->onModelEvent(EVENT_ID::SPORT_STATUS, param->data_p); + } else if (param->tran == _nodeGNSS && _gnssEnable) { + _listener->onModelEvent(EVENT_ID::GNSS, param->data_p); + } else if (param->tran == _nodeTrackFilter) { + _listener->onModelEvent(EVENT_ID::TRACK_REC, param->data_p); + } + + return DataNode::RES_OK; +} diff --git a/x_track/src/App/UI/LiveMap/LiveMapModel.h b/x_track/src/App/UI/LiveMap/LiveMapModel.h new file mode 100644 index 0000000000000000000000000000000000000000..b100361e6de03327d3ee9b662d36198ec6d8825f --- /dev/null +++ b/x_track/src/App/UI/LiveMap/LiveMapModel.h @@ -0,0 +1,78 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __LIVEMAP_MODEL_H +#define __LIVEMAP_MODEL_H + +#include "Service/DataProc/DataProc.h" + +namespace Page { + +class LiveMapModel : private DataNode { +public: + enum class EVENT_ID { + SPORT_STATUS, /* param: SportStatus_Info_t */ + TRACK_REC, /* param: TrackFilter_Info_t */ + GNSS, /* param: GNSS_Info_t */ + MAP_LEVEL_CHANGE, /* param: int */ + _LAST, + }; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + LiveMapModel(EventListener* listener); + ~LiveMapModel(); + + DataProc::Env_Helper* env() + { + return &_env; + } + + bool getGNSSInfo(HAL::GNSS_Info_t* info); + void setGNSSEnable(bool enable) { _gnssEnable = enable; } + bool getMapInfo(DataProc::Map_Info_t* info); + int getMapLevel() { return _mapLevel; }; + bool setMapLevel(int level, bool sendEvent = false); + bool getTrackFilterInfo(DataProc::TrackFilter_Info_t* info); + void loadSportStatusInfo(); + +private: + EventListener* _listener; + DataProc::Env_Helper _env; + const DataNode* _nodeSportStatus; + const DataNode* _nodeGNSS; + const DataNode* _nodeTrackFilter; + int _mapLevel; + DataProc::Map_Info_t _mapInfo; + bool _gnssEnable; + +private: + virtual int onEvent(DataNode::EventParam_t* param); +}; + +} + +#endif /* __LIVEMAP_MODEL_H */ diff --git a/x_track/src/App/UI/LiveMap/LiveMapView.cpp b/x_track/src/App/UI/LiveMap/LiveMapView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..926c8539610473daa6505024b0c92b2a8d0417cd --- /dev/null +++ b/x_track/src/App/UI/LiveMap/LiveMapView.cpp @@ -0,0 +1,340 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "LiveMapView.h" +#include "Service/DataProc/DataProc_Def.h" +#include "Utils/TrackView/TrackView.h" + +#define MAP_MOVE_START_STATE LV_STATE_USER_1 +#define SPEED_OVER_STATE LV_STATE_USER_1 + +using namespace Page; + +LiveMapView::LiveMapView(EventListener* listener, lv_obj_t* root) + : _listener(listener) + , _fontSpeed(32, "medium") + , _mapView(nullptr) + , _roadMapView(nullptr) + , _trackView(nullptr) + , _mapConv(true, 16) +{ + lv_obj_set_style_pad_all(root, 0, 0); + + /* label loading */ + { + lv_obj_t* label = lv_label_create(root); + lv_obj_center(label); + lv_label_set_text(label, _("LOADING...")); + + subscribe(MSG_ID::GEO_COORD_UPDATE, label, [](lv_event_t* e) { + auto obj = lv_event_get_target_obj(e); + lv_obj_del(obj); + }); + } + + styleInit(); + mapViewCreate(root); + sportInfoCreate(root); +} + +LiveMapView::~LiveMapView() +{ + delete _roadMapView; + delete _trackView; + delete _mapView; +} + +lv_uintptr_t LiveMapView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void LiveMapView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void LiveMapView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} + +void LiveMapView::styleInit() +{ + /* cont style */ + lv_style_set_pad_all(&_style.cont, 0); + lv_style_set_border_width(&_style.cont, 0); + lv_style_set_bg_opa(&_style.cont, LV_OPA_60); + lv_style_set_radius(&_style.cont, 6); + lv_style_set_shadow_width(&_style.cont, 10); + lv_style_set_shadow_color(&_style.cont, lv_color_black()); + + /* line style */ + lv_style_set_line_color(&_style.line, lv_color_hex(0xff931e)); + lv_style_set_line_width(&_style.line, 5); + lv_style_set_line_opa(&_style.line, LV_OPA_COVER); + lv_style_set_line_rounded(&_style.line, true); +} + +void LiveMapView::mapViewCreate(lv_obj_t* par) +{ + /* update view size */ + lv_obj_update_layout(par); + lv_coord_t view_w = lv_obj_get_width(par); + lv_coord_t view_h = lv_obj_get_height(par); + + /* map viewer */ + _mapView = new MapView(view_w, view_h, par, onMapViewEvent, this); + _mapView->setScrollEanble(false); + _mapView->setTileSrcEanble(false); + lv_obj_t* viewCont = _mapView->getViewCont(); + + /* geo coord update */ + subscribe(MSG_ID::GEO_COORD_UPDATE, viewCont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::GEO_COORD_UPDATE) != lv_msg_get_id(msg)) { + return; + } + + auto geoCoord = (const MapView::GeoCoord_t*)lv_msg_get_payload(msg); + self->_mapView->setGeoCoord(geoCoord); + }); + + /* set map config */ + subscribe(MSG_ID::MAP_CONFIG_UPDATE, viewCont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::MAP_CONFIG_UPDATE) != lv_msg_get_id(msg)) { + return; + } + + auto mapConfig = (const MapView::MapConfig_t*)lv_msg_get_payload(msg); + self->_mapView->setConfig(mapConfig); + }); + + /* set map level */ + subscribe(MSG_ID::MAP_SET_LEVEL, viewCont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::MAP_SET_LEVEL) != lv_msg_get_id(msg)) { + return; + } + + auto level = (const int*)lv_msg_get_payload(msg); + self->_mapView->setLevel(*level); + }); + + /* track */ + trackCreate(viewCont); + + /* img arrow */ + _mapView->addArrowImage(ResourcePool::getImage("navi_arrow_light")); +} + +void LiveMapView::onMapViewEvent(MapView::EVENT_ID id, const void* param, void* userData) +{ + auto self = (LiveMapView*)userData; + + switch (id) { + case MapView::EVENT_ID::LEVEL_CHANGED: + self->_listener->onViewEvent(EVENT_ID::MAP_LEVEL_CHANGED, param); + break; + + case MapView::EVENT_ID::TILE_RECT_CHANGED: + self->publish(MSG_ID::MAP_TILE_RECT_CHANGED, param); + break; + + default: + break; + } +} + +void LiveMapView::sportInfoCreate(lv_obj_t* par) +{ + /* cont */ + lv_obj_t* cont = lv_obj_create(par); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_style(cont, &_style.cont, 0); + lv_obj_set_size(cont, 160, 66); + lv_obj_align(cont, LV_ALIGN_BOTTOM_LEFT, -10, 10); + lv_obj_set_style_radius(cont, 10, 0); + lv_obj_set_style_translate_y(cont, 180, MAP_MOVE_START_STATE); + + static const lv_style_prop_t prop[] = { + LV_STYLE_TRANSLATE_Y, + LV_STYLE_PROP_INV + }; + static lv_style_transition_dsc_t tran; + lv_style_transition_dsc_init(&tran, prop, lv_anim_path_ease_out, 300, 0, nullptr); + lv_obj_set_style_transition(cont, &tran, LV_STATE_DEFAULT); + + /* speed */ + lv_obj_t* labelSpeed = lv_label_create(cont); + { + lv_label_set_text(labelSpeed, "00"); + lv_obj_set_style_text_font(labelSpeed, _fontSpeed, 0); + lv_obj_align(labelSpeed, LV_ALIGN_LEFT_MID, 20, -10); + lv_obj_set_style_translate_x(labelSpeed, -8, SPEED_OVER_STATE); + + subscribe(MSG_ID::SPORT_STATUS, labelSpeed, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto speed = (int)info->speedKph; + lv_label_set_text_fmt(obj, "%02d", speed); + + if (speed >= 100) { + lv_obj_add_state(obj, SPEED_OVER_STATE); + } else { + lv_obj_clear_state(obj, SPEED_OVER_STATE); + } + }); + } + + /* unit */ + { + lv_obj_t* labelUnit = lv_label_create(cont); + lv_label_set_text(labelUnit, "km/h"); + lv_obj_set_style_text_font(labelUnit, lv_theme_get_font_small(labelUnit), 0); + lv_obj_align_to(labelUnit, labelSpeed, LV_ALIGN_OUT_BOTTOM_MID, 0, -8); + } + + /* trip dist */ + { + lv_obj_t* label = lv_label_create(cont); + lv_label_set_text(label, LV_SYMBOL_EXT_ROAD " --"); + lv_obj_align(label, LV_ALIGN_TOP_LEFT, 73, 10); + + subscribe(MSG_ID::SPORT_STATUS, label, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + auto dist = info->singleDistance / 1000.0f; + if (dist < 100) { + lv_label_set_text_fmt(obj, LV_SYMBOL_EXT_ROAD " %0.1f km", dist); + } else { + lv_label_set_text_fmt(obj, LV_SYMBOL_EXT_ROAD " %d km", (int)dist); + } + }); + } + + /* trip time */ + { + lv_obj_t* label = lv_label_create(cont); + lv_label_set_text(label, LV_SYMBOL_EXT_CLOCK "--"); + lv_obj_align(label, LV_ALIGN_TOP_LEFT, 74, 30); + + subscribe(MSG_ID::SPORT_STATUS, label, [](lv_event_t* e) { + auto obj = lv_event_get_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + + uint64_t ss = info->singleTime / 1000; + uint64_t mm = ss / 60; + uint32_t hh = (uint32_t)(mm / 60); + + lv_label_set_text_fmt(obj, + LV_SYMBOL_EXT_CLOCK " %d:%02d:%02d", + (int)hh, + (int)(mm % 60), + (int)(ss % 60)); + }); + } +} + +void LiveMapView::trackCreate(lv_obj_t* par) +{ + _trackView = new TrackView(par); + _trackView->setStyle(&_style.line); + + lv_obj_t* cont = _trackView->getViewCont(); + + /* track recorder state change */ + subscribe(MSG_ID::TRACK_REC, cont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::TRACK_REC) != lv_msg_get_id(msg)) { + return; + } + + auto info = (const DataProc::TrackFilter_Info_t*)lv_msg_get_payload(msg); + self->_trackView->setPointContainer((PointContainer*)info->pointCont, info->level); + self->_trackView->reload(); + }); + + /* map tile change */ + subscribe(MSG_ID::MAP_TILE_RECT_CHANGED, cont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::MAP_TILE_RECT_CHANGED) != lv_msg_get_id(msg)) { + return; + } + + auto info = (const TileView::Rect_t*)lv_msg_get_payload(msg); + self->_trackView->setArea(info->x, info->y, info->x + info->width - 1, info->y + info->height - 1); + self->_trackView->reload(); + }); + + /* map level change */ + subscribe(MSG_ID::MAP_SET_LEVEL, cont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::MAP_SET_LEVEL) != lv_msg_get_id(msg)) { + return; + } + + auto level = *(const int*)lv_msg_get_payload(msg); + self->_trackView->setLevel(level); + self->_trackView->reload(); + }); + + /* geo coord update */ + subscribe(MSG_ID::GEO_COORD_UPDATE, cont, [](lv_event_t* e) { + auto msg = lv_event_get_msg(e); + auto self = (LiveMapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::GEO_COORD_UPDATE) != lv_msg_get_id(msg)) { + return; + } + + auto geoCoord = (const MapView::GeoCoord_t*)lv_msg_get_payload(msg); + + /* sync status */ + self->_mapConv.setCoordTransformEnable(self->_mapView->getCoordTrans()); + self->_mapConv.setLevel(self->_trackView->getRefLevel()); + + /* convert coord */ + MapConv::Point_t point = self->_mapConv.getCoordinate(geoCoord->longitude, geoCoord->latitude); + + /* push point */ + self->_trackView->pushPoint(point.x, point.y); + self->_trackView->setActivePoint(point.x, point.y); + }); +} diff --git a/x_track/src/App/UI/LiveMap/LiveMapView.h b/x_track/src/App/UI/LiveMap/LiveMapView.h new file mode 100644 index 0000000000000000000000000000000000000000..48a16c2f115594673d46a216f5e3d9f9dcad4161 --- /dev/null +++ b/x_track/src/App/UI/LiveMap/LiveMapView.h @@ -0,0 +1,97 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __LIVE_MAP_VIEW_H +#define __LIVE_MAP_VIEW_H + +#include "../Page.h" +#include "Utils/MapView/MapView.h" + +class TrackView; + +namespace Page { + +class LiveMapView { +public: + enum class EVENT_ID { + MAP_LEVEL_CHANGED, /* param: None */ + LOAD_FILE, /* param: None */ + _LAST, + }; + + enum class MSG_ID { + GEO_COORD_UPDATE, /* param: MapView::GeoCoord_t */ + SPORT_STATUS, /* param: SportStatus_Infot */ + TRACK_REC, /* param: DataProc::TrackFilter_Info_t */ + MAP_CONFIG_UPDATE, /* param: MapView::MapConfig_t */ + MAP_SET_LEVEL, /* param: int */ + MAP_TILE_RECT_CHANGED, /* param: TileView::TileRect_t */ + LOAD_ROAD_MAP, /* param: DataProc::RoadMap_Info_t */ + _LAST, + }; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + LiveMapView(EventListener* listener, lv_obj_t* root); + ~LiveMapView(); + void publish(MSG_ID id, const void* payload = nullptr); + +private: + EventListener* _listener; + ResourcePool::Font _fontSpeed; + struct STYLE { + STYLE() + { + lv_style_init(&cont); + lv_style_init(&line); + } + ~STYLE() + { + lv_style_reset(&cont); + lv_style_reset(&line); + } + lv_style_t cont; + lv_style_t line; + } _style; + + MapView* _mapView; + TrackView* _roadMapView; + TrackView* _trackView; + MapConv _mapConv; + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); + void styleInit(); + void mapViewCreate(lv_obj_t* par); + static void onMapViewEvent(MapView::EVENT_ID id, const void* param, void* userData); + void sportInfoCreate(lv_obj_t* par); + void trackCreate(lv_obj_t* par); +}; + +} + +#endif /* __LIVE_MAP_VIEW_H */ diff --git a/x_track/src/App/UI/Page.h b/x_track/src/App/UI/Page.h new file mode 100644 index 0000000000000000000000000000000000000000..ab73d9b08b18722d88fdf4ac7e054328f6ecc90e --- /dev/null +++ b/x_track/src/App/UI/Page.h @@ -0,0 +1,32 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PAGE_H +#define __PAGE_H + +#include "AppFactory.h" +#include "Frameworks/PageManager/PageManager.h" +#include "Resource/ResourcePool.h" +#include "Service/i18n/lv_i18n.h" +#include "Utils/lv_msg/lv_msg.h" + +#endif diff --git a/x_track/src/App/UI/Resource/ResourcePool.cpp b/x_track/src/App/UI/Resource/ResourcePool.cpp new file mode 100755 index 0000000000000000000000000000000000000000..e4fbe5eb51ed6d0414ce2cd926f2e546f2018f4a --- /dev/null +++ b/x_track/src/App/UI/Resource/ResourcePool.cpp @@ -0,0 +1,155 @@ +/* + * MIT License + * Copyright (c) 2022 XCLZ STUDIO@W-Mai + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "ResourcePool.h" +#include "Config/Config.h" +#include "Frameworks/ResourceManager/ResourceManagerStatic.cpp" +#include "ResourcePoolDefs.h" +#include "Utils/lv_msg/lv_msg.h" +#include <uikit/uikit.h> +#include <cstdlib> + +/* clang-format off */ + +#define FONT_REGULAR_NAME "Alibaba_PuHuiTi_2.0_55_Regular" +#define FONT_MEDIUM_NAME "Alibaba_PuHuiTi_2.0_65_Medium" +#define FONT_BOLD_NAME "Alibaba_PuHuiTi_2.0_115_Black" +#define FONT_AWESOME_BRANDS_REGULAR_NAME "Font Awesome 6 Brands-Regular-400" +#define FONT_AWESOME_FREE_REGULAR_NAME "Font Awesome 6 Free-Regular-400" +#define FONT_AWESOME_FREE_SOLID_NAME "Font Awesome 6 Free-Solid-900" + +/* clang-format on */ + +namespace ResourcePool { + +DEF_RES_MNGR_OBJ_EXT(Font, font_value_t, + IMPORT_FONT_NATIVE(montserrat, 14), + IMPORT_FONT_FILE("regular", FONT_REGULAR_NAME), + IMPORT_FONT_FILE("medium", FONT_MEDIUM_NAME), + IMPORT_FONT_FILE("bold", FONT_BOLD_NAME), + IMPORT_FONT_FILE("awesome", FONT_AWESOME_FREE_SOLID_NAME), ); + +DEF_RES_MNGR_OBJ(Image, + IMPORT_IMAGE_FILE("navi_arrow_dark"), + IMPORT_IMAGE_FILE("navi_arrow_light"), ); + +void init() +{ + lv_msg_init(); + vg_init(); + +#define FONT_MANAGER_ADD_FONT(name) vg_font_add_path(name, FONT_MAKE_PATH(name)); + + FONT_MANAGER_ADD_FONT(FONT_REGULAR_NAME); + FONT_MANAGER_ADD_FONT(FONT_MEDIUM_NAME); + FONT_MANAGER_ADD_FONT(FONT_BOLD_NAME); + FONT_MANAGER_ADD_FONT(FONT_AWESOME_BRANDS_REGULAR_NAME); + FONT_MANAGER_ADD_FONT(FONT_AWESOME_FREE_REGULAR_NAME); + FONT_MANAGER_ADD_FONT(FONT_AWESOME_FREE_SOLID_NAME); + + font_value_t default_font = { + font_value_type::UNKNOWN, + LV_FONT_DEFAULT + }; + SET_DEFAULT(Font, std::forward<font_value_t>(default_font)); + SET_DEFAULT(Image, LV_SYMBOL_WARNING); +} + +void deinit() +{ +} + +/** + * @brief Parse real font name and font size from input name. + * @param name Font name + * @param size Return font size + * @return Pointer of real NAME start + */ +static const char* get_font_size_from_name(const char* name, int* size) +{ + if (name[0] != '<' || size == nullptr) { + return name; + } + LV_ASSERT_NULL(size); + + /* +1 to skip '<' */ + char* end_ptr; + *size = (int)strtol(name + 1, &end_ptr, 10); + if (end_ptr == name) { + return name; + } + return end_ptr + 1; /* +1 to skip '>' */ +} + +DEF_RES_MNGR_GET(Font) +{ + /* font key: "name_size" */ + + auto font = OName(Font).get(key); + + /* native font */ + if (font.type == font_value_type::NATIVE) { + return font.value; + } + + int size = -1; + auto font_key = get_font_size_from_name(key, &size); + auto freetype_font = OName(Font).get(font_key); + + if (freetype_font.type == font_value_type::UNKNOWN) { + LV_LOG_ERROR("error key = %s", key); + return font.value; + } + + if (size <= 0) { + LV_LOG_ERROR("error size = %d", size); + return font.value; + } + + const lv_font_t* new_font = vg_font_create( + (const char*)freetype_font.value, + size, + LV_FREETYPE_FONT_STYLE_NORMAL); + + if (!new_font) { + new_font = LV_FONT_DEFAULT; + LV_LOG_WARN("new_font is NULL, use LV_FONT_DEFAULT"); + } + + return new_font; +} + +void dropFont(const lv_font_t* font) +{ + if (font == LV_FONT_DEFAULT) { + return; + } + + vg_font_destroy((lv_font_t*)font); +} + +DEF_RES_MNGR_GET(Image) +{ + return OName(Image).get(key); +} +} diff --git a/x_track/src/App/UI/Resource/ResourcePool.h b/x_track/src/App/UI/Resource/ResourcePool.h new file mode 100755 index 0000000000000000000000000000000000000000..96d1b9b7bc9d5677ca68e64f5b19f75bd60fb7ec --- /dev/null +++ b/x_track/src/App/UI/Resource/ResourcePool.h @@ -0,0 +1,78 @@ +/* + * MIT License + * Copyright (c) 2022 XCLZ STUDIO@W-Mai + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef RESOURCE_POOL_H +#define RESOURCE_POOL_H + +#include "lv_symbol_ext_def.h" +#include "lvgl/lvgl.h" + +/* Macro Definitions */ +#define RES_MNG(NAME, K_TYPE, V_TYPE) \ + using KType_##NAME = K_TYPE; \ + using VType_##NAME = V_TYPE; \ + VType_##NAME get##NAME(KType_##NAME key) + +namespace ResourcePool { + +void init(); +void deinit(); + +RES_MNG(Font, const char*, const lv_font_t*); +RES_MNG(Image, const char*, const void*); + +void dropFont(const lv_font_t* font); + +/* Font Wrapper */ +class Font { +public: + Font(const char* key) + { + _font = getFont(key); + } + Font(int size, const char* name) + { + char key[64]; + lv_snprintf(key, sizeof(key), "<%d>%s", size, name); + _font = getFont(key); + } + ~Font() + { + dropFont(_font); + } + + operator const lv_font_t*() const + { + return _font; + } + +private: + const lv_font_t* _font; +}; + +} + +/* Macro UnDefinitions */ +#undef RES_MNG + +#endif // RESOURCE_POOL_H diff --git a/x_track/src/App/UI/Resource/ResourcePoolDefs.h b/x_track/src/App/UI/Resource/ResourcePoolDefs.h new file mode 100755 index 0000000000000000000000000000000000000000..68112518485513fbe114810411f269be5a327825 --- /dev/null +++ b/x_track/src/App/UI/Resource/ResourcePoolDefs.h @@ -0,0 +1,90 @@ +/* + * MIT License + * Copyright (c) 2022 XCLZ STUDIO@W-Mai + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Created by W-Mai on 2022/11/23. + */ + +#ifndef SIMULATOR_RESOURCEPOOLDEFS_H +#define SIMULATOR_RESOURCEPOOLDEFS_H + +#include "Config/Config.h" + +#define KType(NAME) KType_##NAME +#define VType(NAME) VType_##NAME +#define OName(NAME) __RMSO_##NAME##_ +#define ONameArray(NAME) __RMSO_##NAME##_ARRAY +#define RMSType(NAME) RMSType_##NAME + +#define DEF_RES_MNGR_OBJ_EXT(NAME, VTYPE, ...) \ + static std::pair<KType(NAME), VTYPE> ONameArray(NAME)[] { \ + __VA_ARGS__ \ + }; \ + using RMSType(NAME) = ResourceManagerStatic<KType(NAME), VTYPE, \ + sizeof(ONameArray(NAME)) / sizeof(std::pair<KType(NAME), VTYPE>)>; \ + static RMSType(NAME) OName(NAME)(ONameArray(NAME)) + +#define DEF_RES_MNGR_OBJ(NAME, ...) DEF_RES_MNGR_OBJ_EXT(NAME, VType(NAME), __VA_ARGS__) + +#define DEF_RES_MNGR_GET(NAME) VType(NAME) get##NAME(KType(NAME) key) + +#define IMPORT_FONT_NATIVE(NAME, SIZE) \ + { \ + "<" #SIZE ">" #NAME, \ + { \ + font_value_type::NATIVE, \ + &lv_font_##NAME##_##SIZE \ + } \ + } + +#define IMPORT_FONT_FILE(NAME, FONT_NAME) \ + { \ + NAME, \ + { \ + font_value_type::FREETYPE, \ + (lv_font_t*)FONT_NAME \ + } \ + } + +#define IMPORT_IMAGE_NATIVE(NAME) \ + { \ +#NAME, &img_src_##NAME \ + } + +#define IMPORT_IMAGE_FILE(NAME) \ + { \ + NAME, (CONFIG_IMAGE_DIR_PATH "/" NAME CONFIG_IMAGE_EXT_NAME) \ + } + +#define SET_DEFAULT(NAME, VALUE) OName(NAME).setDefaultValue((VALUE)) + +enum font_value_type { + UNKNOWN, + NATIVE, + FREETYPE +}; + +struct font_value_t { + font_value_type type; + const lv_font_t* value; +}; + +#endif // SIMULATOR_RESOURCEPOOLDEFS_H diff --git a/x_track/src/App/UI/Resource/lv_symbol_ext_def.h b/x_track/src/App/UI/Resource/lv_symbol_ext_def.h new file mode 100755 index 0000000000000000000000000000000000000000..becf736f30418ebf28fec78b4f37eb08448706fa --- /dev/null +++ b/x_track/src/App/UI/Resource/lv_symbol_ext_def.h @@ -0,0 +1,1883 @@ +/* + * This file is automatically generated by a script. + * Please DO NOT manually edit this file. + */ + +#ifndef LV_SYMBOL_EXT_DEF +#define LV_SYMBOL_EXT_DEF + +#define LV_SYMBOL_EXT_0 "\x30" /*48, 30*/ +#define LV_SYMBOL_EXT_1 "\x31" /*49, 31*/ +#define LV_SYMBOL_EXT_2 "\x32" /*50, 32*/ +#define LV_SYMBOL_EXT_3 "\x33" /*51, 33*/ +#define LV_SYMBOL_EXT_4 "\x34" /*52, 34*/ +#define LV_SYMBOL_EXT_5 "\x35" /*53, 35*/ +#define LV_SYMBOL_EXT_6 "\x36" /*54, 36*/ +#define LV_SYMBOL_EXT_7 "\x37" /*55, 37*/ +#define LV_SYMBOL_EXT_8 "\x38" /*56, 38*/ +#define LV_SYMBOL_EXT_9 "\x39" /*57, 39*/ +#define LV_SYMBOL_EXT_42_GROUP "\xEE\x82\x80" /*57472, e080*/ +#define LV_SYMBOL_EXT_500PX "\xEF\x89\xAE" /*62062, f26e*/ +#define LV_SYMBOL_EXT_A "\x41" /*65, 41*/ +#define LV_SYMBOL_EXT_ACCESSIBLE_ICON "\xEF\x8D\xA8" /*62312, f368*/ +#define LV_SYMBOL_EXT_ACCUSOFT "\xEF\x8D\xA9" /*62313, f369*/ +#define LV_SYMBOL_EXT_ADDRESS_BOOK "\xEF\x8A\xB9" /*62137, f2b9*/ +#define LV_SYMBOL_EXT_ADDRESS_CARD "\xEF\x8A\xBB" /*62139, f2bb*/ +#define LV_SYMBOL_EXT_ADN "\xEF\x85\xB0" /*61808, f170*/ +#define LV_SYMBOL_EXT_ADVERSAL "\xEF\x8D\xAA" /*62314, f36a*/ +#define LV_SYMBOL_EXT_AFFILIATETHEME "\xEF\x8D\xAB" /*62315, f36b*/ +#define LV_SYMBOL_EXT_AIRBNB "\xEF\xA0\xB4" /*63540, f834*/ +#define LV_SYMBOL_EXT_ALGOLIA "\xEF\x8D\xAC" /*62316, f36c*/ +#define LV_SYMBOL_EXT_ALIGN_CENTER "\xEF\x80\xB7" /*61495, f037*/ +#define LV_SYMBOL_EXT_ALIGN_JUSTIFY "\xEF\x80\xB9" /*61497, f039*/ +#define LV_SYMBOL_EXT_ALIGN_LEFT "\xEF\x80\xB6" /*61494, f036*/ +#define LV_SYMBOL_EXT_ALIGN_RIGHT "\xEF\x80\xB8" /*61496, f038*/ +#define LV_SYMBOL_EXT_ALIPAY "\xEF\x99\x82" /*63042, f642*/ +#define LV_SYMBOL_EXT_AMAZON "\xEF\x89\xB0" /*62064, f270*/ +#define LV_SYMBOL_EXT_AMAZON_PAY "\xEF\x90\xAC" /*62508, f42c*/ +#define LV_SYMBOL_EXT_AMILIA "\xEF\x8D\xAD" /*62317, f36d*/ +#define LV_SYMBOL_EXT_ANCHOR "\xEF\x84\xBD" /*61757, f13d*/ +#define LV_SYMBOL_EXT_ANCHOR_CIRCLE_CHECK "\xEE\x92\xAA" /*58538, e4aa*/ +#define LV_SYMBOL_EXT_ANCHOR_CIRCLE_EXCLAMATION "\xEE\x92\xAB" /*58539, e4ab*/ +#define LV_SYMBOL_EXT_ANCHOR_CIRCLE_XMARK "\xEE\x92\xAC" /*58540, e4ac*/ +#define LV_SYMBOL_EXT_ANCHOR_LOCK "\xEE\x92\xAD" /*58541, e4ad*/ +#define LV_SYMBOL_EXT_ANDROID "\xEF\x85\xBB" /*61819, f17b*/ +#define LV_SYMBOL_EXT_ANGELLIST "\xEF\x88\x89" /*61961, f209*/ +#define LV_SYMBOL_EXT_ANGLE_DOWN "\xEF\x84\x87" /*61703, f107*/ +#define LV_SYMBOL_EXT_ANGLE_LEFT "\xEF\x84\x84" /*61700, f104*/ +#define LV_SYMBOL_EXT_ANGLE_RIGHT "\xEF\x84\x85" /*61701, f105*/ +#define LV_SYMBOL_EXT_ANGLE_UP "\xEF\x84\x86" /*61702, f106*/ +#define LV_SYMBOL_EXT_ANGLES_DOWN "\xEF\x84\x83" /*61699, f103*/ +#define LV_SYMBOL_EXT_ANGLES_LEFT "\xEF\x84\x80" /*61696, f100*/ +#define LV_SYMBOL_EXT_ANGLES_RIGHT "\xEF\x84\x81" /*61697, f101*/ +#define LV_SYMBOL_EXT_ANGLES_UP "\xEF\x84\x82" /*61698, f102*/ +#define LV_SYMBOL_EXT_ANGRYCREATIVE "\xEF\x8D\xAE" /*62318, f36e*/ +#define LV_SYMBOL_EXT_ANGULAR "\xEF\x90\xA0" /*62496, f420*/ +#define LV_SYMBOL_EXT_ANKH "\xEF\x99\x84" /*63044, f644*/ +#define LV_SYMBOL_EXT_APP_STORE "\xEF\x8D\xAF" /*62319, f36f*/ +#define LV_SYMBOL_EXT_APP_STORE_IOS "\xEF\x8D\xB0" /*62320, f370*/ +#define LV_SYMBOL_EXT_APPER "\xEF\x8D\xB1" /*62321, f371*/ +#define LV_SYMBOL_EXT_APPLE "\xEF\x85\xB9" /*61817, f179*/ +#define LV_SYMBOL_EXT_APPLE_PAY "\xEF\x90\x95" /*62485, f415*/ +#define LV_SYMBOL_EXT_APPLE_WHOLE "\xEF\x97\x91" /*62929, f5d1*/ +#define LV_SYMBOL_EXT_ARCHWAY "\xEF\x95\x97" /*62807, f557*/ +#define LV_SYMBOL_EXT_ARROW_DOWN "\xEF\x81\xA3" /*61539, f063*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_1_9 "\xEF\x85\xA2" /*61794, f162*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_9_1 "\xEF\xA2\x86" /*63622, f886*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_A_Z "\xEF\x85\x9D" /*61789, f15d*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_LONG "\xEF\x85\xB5" /*61813, f175*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_SHORT_WIDE "\xEF\xA2\x84" /*63620, f884*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_UP_ACROSS_LINE "\xEE\x92\xAF" /*58543, e4af*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_UP_LOCK "\xEE\x92\xB0" /*58544, e4b0*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_WIDE_SHORT "\xEF\x85\xA0" /*61792, f160*/ +#define LV_SYMBOL_EXT_ARROW_DOWN_Z_A "\xEF\xA2\x81" /*63617, f881*/ +#define LV_SYMBOL_EXT_ARROW_LEFT "\xEF\x81\xA0" /*61536, f060*/ +#define LV_SYMBOL_EXT_ARROW_LEFT_LONG "\xEF\x85\xB7" /*61815, f177*/ +#define LV_SYMBOL_EXT_ARROW_POINTER "\xEF\x89\x85" /*62021, f245*/ +#define LV_SYMBOL_EXT_ARROW_RIGHT "\xEF\x81\xA1" /*61537, f061*/ +#define LV_SYMBOL_EXT_ARROW_RIGHT_ARROW_LEFT "\xEF\x83\xAC" /*61676, f0ec*/ +#define LV_SYMBOL_EXT_ARROW_RIGHT_FROM_BRACKET "\xEF\x82\x8B" /*61579, f08b*/ +#define LV_SYMBOL_EXT_ARROW_RIGHT_LONG "\xEF\x85\xB8" /*61816, f178*/ +#define LV_SYMBOL_EXT_ARROW_RIGHT_TO_BRACKET "\xEF\x82\x90" /*61584, f090*/ +#define LV_SYMBOL_EXT_ARROW_RIGHT_TO_CITY "\xEE\x92\xB3" /*58547, e4b3*/ +#define LV_SYMBOL_EXT_ARROW_ROTATE_LEFT "\xEF\x83\xA2" /*61666, f0e2*/ +#define LV_SYMBOL_EXT_ARROW_ROTATE_RIGHT "\xEF\x80\x9E" /*61470, f01e*/ +#define LV_SYMBOL_EXT_ARROW_TREND_DOWN "\xEE\x82\x97" /*57495, e097*/ +#define LV_SYMBOL_EXT_ARROW_TREND_UP "\xEE\x82\x98" /*57496, e098*/ +#define LV_SYMBOL_EXT_ARROW_TURN_DOWN "\xEF\x85\x89" /*61769, f149*/ +#define LV_SYMBOL_EXT_ARROW_TURN_UP "\xEF\x85\x88" /*61768, f148*/ +#define LV_SYMBOL_EXT_ARROW_UP "\xEF\x81\xA2" /*61538, f062*/ +#define LV_SYMBOL_EXT_ARROW_UP_1_9 "\xEF\x85\xA3" /*61795, f163*/ +#define LV_SYMBOL_EXT_ARROW_UP_9_1 "\xEF\xA2\x87" /*63623, f887*/ +#define LV_SYMBOL_EXT_ARROW_UP_A_Z "\xEF\x85\x9E" /*61790, f15e*/ +#define LV_SYMBOL_EXT_ARROW_UP_FROM_BRACKET "\xEE\x82\x9A" /*57498, e09a*/ +#define LV_SYMBOL_EXT_ARROW_UP_FROM_GROUND_WATER "\xEE\x92\xB5" /*58549, e4b5*/ +#define LV_SYMBOL_EXT_ARROW_UP_FROM_WATER_PUMP "\xEE\x92\xB6" /*58550, e4b6*/ +#define LV_SYMBOL_EXT_ARROW_UP_LONG "\xEF\x85\xB6" /*61814, f176*/ +#define LV_SYMBOL_EXT_ARROW_UP_RIGHT_DOTS "\xEE\x92\xB7" /*58551, e4b7*/ +#define LV_SYMBOL_EXT_ARROW_UP_RIGHT_FROM_SQUARE "\xEF\x82\x8E" /*61582, f08e*/ +#define LV_SYMBOL_EXT_ARROW_UP_SHORT_WIDE "\xEF\xA2\x85" /*63621, f885*/ +#define LV_SYMBOL_EXT_ARROW_UP_WIDE_SHORT "\xEF\x85\xA1" /*61793, f161*/ +#define LV_SYMBOL_EXT_ARROW_UP_Z_A "\xEF\xA2\x82" /*63618, f882*/ +#define LV_SYMBOL_EXT_ARROWS_DOWN_TO_LINE "\xEE\x92\xB8" /*58552, e4b8*/ +#define LV_SYMBOL_EXT_ARROWS_DOWN_TO_PEOPLE "\xEE\x92\xB9" /*58553, e4b9*/ +#define LV_SYMBOL_EXT_ARROWS_LEFT_RIGHT "\xEF\x81\xBE" /*61566, f07e*/ +#define LV_SYMBOL_EXT_ARROWS_LEFT_RIGHT_TO_LINE "\xEE\x92\xBA" /*58554, e4ba*/ +#define LV_SYMBOL_EXT_ARROWS_ROTATE "\xEF\x80\xA1" /*61473, f021*/ +#define LV_SYMBOL_EXT_ARROWS_SPIN "\xEE\x92\xBB" /*58555, e4bb*/ +#define LV_SYMBOL_EXT_ARROWS_SPLIT_UP_AND_LEFT "\xEE\x92\xBC" /*58556, e4bc*/ +#define LV_SYMBOL_EXT_ARROWS_TO_CIRCLE "\xEE\x92\xBD" /*58557, e4bd*/ +#define LV_SYMBOL_EXT_ARROWS_TO_DOT "\xEE\x92\xBE" /*58558, e4be*/ +#define LV_SYMBOL_EXT_ARROWS_TO_EYE "\xEE\x92\xBF" /*58559, e4bf*/ +#define LV_SYMBOL_EXT_ARROWS_TURN_RIGHT "\xEE\x93\x80" /*58560, e4c0*/ +#define LV_SYMBOL_EXT_ARROWS_TURN_TO_DOTS "\xEE\x93\x81" /*58561, e4c1*/ +#define LV_SYMBOL_EXT_ARROWS_UP_DOWN "\xEF\x81\xBD" /*61565, f07d*/ +#define LV_SYMBOL_EXT_ARROWS_UP_DOWN_LEFT_RIGHT "\xEF\x81\x87" /*61511, f047*/ +#define LV_SYMBOL_EXT_ARROWS_UP_TO_LINE "\xEE\x93\x82" /*58562, e4c2*/ +#define LV_SYMBOL_EXT_ARTSTATION "\xEF\x9D\xBA" /*63354, f77a*/ +#define LV_SYMBOL_EXT_ASTERISK "\x2A" /*42, 2a*/ +#define LV_SYMBOL_EXT_ASYMMETRIK "\xEF\x8D\xB2" /*62322, f372*/ +#define LV_SYMBOL_EXT_AT "\x40" /*64, 40*/ +#define LV_SYMBOL_EXT_ATLASSIAN "\xEF\x9D\xBB" /*63355, f77b*/ +#define LV_SYMBOL_EXT_ATOM "\xEF\x97\x92" /*62930, f5d2*/ +#define LV_SYMBOL_EXT_AUDIBLE "\xEF\x8D\xB3" /*62323, f373*/ +#define LV_SYMBOL_EXT_AUDIO_DESCRIPTION "\xEF\x8A\x9E" /*62110, f29e*/ +#define LV_SYMBOL_EXT_AUSTRAL_SIGN "\xEE\x82\xA9" /*57513, e0a9*/ +#define LV_SYMBOL_EXT_AUTOPREFIXER "\xEF\x90\x9C" /*62492, f41c*/ +#define LV_SYMBOL_EXT_AVIANEX "\xEF\x8D\xB4" /*62324, f374*/ +#define LV_SYMBOL_EXT_AVIATO "\xEF\x90\xA1" /*62497, f421*/ +#define LV_SYMBOL_EXT_AWARD "\xEF\x95\x99" /*62809, f559*/ +#define LV_SYMBOL_EXT_AWS "\xEF\x8D\xB5" /*62325, f375*/ +#define LV_SYMBOL_EXT_B "\x42" /*66, 42*/ +#define LV_SYMBOL_EXT_BABY "\xEF\x9D\xBC" /*63356, f77c*/ +#define LV_SYMBOL_EXT_BABY_CARRIAGE "\xEF\x9D\xBD" /*63357, f77d*/ +#define LV_SYMBOL_EXT_BACKWARD "\xEF\x81\x8A" /*61514, f04a*/ +#define LV_SYMBOL_EXT_BACKWARD_FAST "\xEF\x81\x89" /*61513, f049*/ +#define LV_SYMBOL_EXT_BACKWARD_STEP "\xEF\x81\x88" /*61512, f048*/ +#define LV_SYMBOL_EXT_BACON "\xEF\x9F\xA5" /*63461, f7e5*/ +#define LV_SYMBOL_EXT_BACTERIA "\xEE\x81\x99" /*57433, e059*/ +#define LV_SYMBOL_EXT_BACTERIUM "\xEE\x81\x9A" /*57434, e05a*/ +#define LV_SYMBOL_EXT_BAG_SHOPPING "\xEF\x8A\x90" /*62096, f290*/ +#define LV_SYMBOL_EXT_BAHAI "\xEF\x99\xA6" /*63078, f666*/ +#define LV_SYMBOL_EXT_BAHT_SIGN "\xEE\x82\xAC" /*57516, e0ac*/ +#define LV_SYMBOL_EXT_BAN "\xEF\x81\x9E" /*61534, f05e*/ +#define LV_SYMBOL_EXT_BAN_SMOKING "\xEF\x95\x8D" /*62797, f54d*/ +#define LV_SYMBOL_EXT_BANDAGE "\xEF\x91\xA2" /*62562, f462*/ +#define LV_SYMBOL_EXT_BANDCAMP "\xEF\x8B\x95" /*62165, f2d5*/ +#define LV_SYMBOL_EXT_BANGLADESHI_TAKA_SIGN "\xEE\x8B\xA6" /*58086, e2e6*/ +#define LV_SYMBOL_EXT_BARCODE "\xEF\x80\xAA" /*61482, f02a*/ +#define LV_SYMBOL_EXT_BARS "\xEF\x83\x89" /*61641, f0c9*/ +#define LV_SYMBOL_EXT_BARS_PROGRESS "\xEF\xA0\xA8" /*63528, f828*/ +#define LV_SYMBOL_EXT_BARS_STAGGERED "\xEF\x95\x90" /*62800, f550*/ +#define LV_SYMBOL_EXT_BASEBALL "\xEF\x90\xB3" /*62515, f433*/ +#define LV_SYMBOL_EXT_BASEBALL_BAT_BALL "\xEF\x90\xB2" /*62514, f432*/ +#define LV_SYMBOL_EXT_BASKET_SHOPPING "\xEF\x8A\x91" /*62097, f291*/ +#define LV_SYMBOL_EXT_BASKETBALL "\xEF\x90\xB4" /*62516, f434*/ +#define LV_SYMBOL_EXT_BATH "\xEF\x8B\x8D" /*62157, f2cd*/ +#define LV_SYMBOL_EXT_BATTERY_EMPTY "\xEF\x89\x84" /*62020, f244*/ +#define LV_SYMBOL_EXT_BATTERY_FULL "\xEF\x89\x80" /*62016, f240*/ +#define LV_SYMBOL_EXT_BATTERY_HALF "\xEF\x89\x82" /*62018, f242*/ +#define LV_SYMBOL_EXT_BATTERY_QUARTER "\xEF\x89\x83" /*62019, f243*/ +#define LV_SYMBOL_EXT_BATTERY_THREE_QUARTERS "\xEF\x89\x81" /*62017, f241*/ +#define LV_SYMBOL_EXT_BATTLE_NET "\xEF\xA0\xB5" /*63541, f835*/ +#define LV_SYMBOL_EXT_BED "\xEF\x88\xB6" /*62006, f236*/ +#define LV_SYMBOL_EXT_BED_PULSE "\xEF\x92\x87" /*62599, f487*/ +#define LV_SYMBOL_EXT_BEER_MUG_EMPTY "\xEF\x83\xBC" /*61692, f0fc*/ +#define LV_SYMBOL_EXT_BEHANCE "\xEF\x86\xB4" /*61876, f1b4*/ +#define LV_SYMBOL_EXT_BELL "\xEF\x83\xB3" /*61683, f0f3*/ +#define LV_SYMBOL_EXT_BELL_CONCIERGE "\xEF\x95\xA2" /*62818, f562*/ +#define LV_SYMBOL_EXT_BELL_SLASH "\xEF\x87\xB6" /*61942, f1f6*/ +#define LV_SYMBOL_EXT_BEZIER_CURVE "\xEF\x95\x9B" /*62811, f55b*/ +#define LV_SYMBOL_EXT_BICYCLE "\xEF\x88\x86" /*61958, f206*/ +#define LV_SYMBOL_EXT_BILIBILI "\xEE\x8F\x99" /*58329, e3d9*/ +#define LV_SYMBOL_EXT_BIMOBJECT "\xEF\x8D\xB8" /*62328, f378*/ +#define LV_SYMBOL_EXT_BINOCULARS "\xEF\x87\xA5" /*61925, f1e5*/ +#define LV_SYMBOL_EXT_BIOHAZARD "\xEF\x9E\x80" /*63360, f780*/ +#define LV_SYMBOL_EXT_BITBUCKET "\xEF\x85\xB1" /*61809, f171*/ +#define LV_SYMBOL_EXT_BITCOIN "\xEF\x8D\xB9" /*62329, f379*/ +#define LV_SYMBOL_EXT_BITCOIN_SIGN "\xEE\x82\xB4" /*57524, e0b4*/ +#define LV_SYMBOL_EXT_BITY "\xEF\x8D\xBA" /*62330, f37a*/ +#define LV_SYMBOL_EXT_BLACK_TIE "\xEF\x89\xBE" /*62078, f27e*/ +#define LV_SYMBOL_EXT_BLACKBERRY "\xEF\x8D\xBB" /*62331, f37b*/ +#define LV_SYMBOL_EXT_BLENDER "\xEF\x94\x97" /*62743, f517*/ +#define LV_SYMBOL_EXT_BLENDER_PHONE "\xEF\x9A\xB6" /*63158, f6b6*/ +#define LV_SYMBOL_EXT_BLOG "\xEF\x9E\x81" /*63361, f781*/ +#define LV_SYMBOL_EXT_BLOGGER "\xEF\x8D\xBC" /*62332, f37c*/ +#define LV_SYMBOL_EXT_BLOGGER_B "\xEF\x8D\xBD" /*62333, f37d*/ +#define LV_SYMBOL_EXT_BLUETOOTH "\xEF\x8A\x93" /*62099, f293*/ +#define LV_SYMBOL_EXT_BLUETOOTH_B "\xEF\x8A\x94" /*62100, f294*/ +#define LV_SYMBOL_EXT_BOLD "\xEF\x80\xB2" /*61490, f032*/ +#define LV_SYMBOL_EXT_BOLT "\xEF\x83\xA7" /*61671, f0e7*/ +#define LV_SYMBOL_EXT_BOLT_LIGHTNING "\xEE\x82\xB7" /*57527, e0b7*/ +#define LV_SYMBOL_EXT_BOMB "\xEF\x87\xA2" /*61922, f1e2*/ +#define LV_SYMBOL_EXT_BONE "\xEF\x97\x97" /*62935, f5d7*/ +#define LV_SYMBOL_EXT_BONG "\xEF\x95\x9C" /*62812, f55c*/ +#define LV_SYMBOL_EXT_BOOK "\xEF\x80\xAD" /*61485, f02d*/ +#define LV_SYMBOL_EXT_BOOK_ATLAS "\xEF\x95\x98" /*62808, f558*/ +#define LV_SYMBOL_EXT_BOOK_BIBLE "\xEF\x99\x87" /*63047, f647*/ +#define LV_SYMBOL_EXT_BOOK_BOOKMARK "\xEE\x82\xBB" /*57531, e0bb*/ +#define LV_SYMBOL_EXT_BOOK_JOURNAL_WHILLS "\xEF\x99\xAA" /*63082, f66a*/ +#define LV_SYMBOL_EXT_BOOK_MEDICAL "\xEF\x9F\xA6" /*63462, f7e6*/ +#define LV_SYMBOL_EXT_BOOK_OPEN "\xEF\x94\x98" /*62744, f518*/ +#define LV_SYMBOL_EXT_BOOK_OPEN_READER "\xEF\x97\x9A" /*62938, f5da*/ +#define LV_SYMBOL_EXT_BOOK_QURAN "\xEF\x9A\x87" /*63111, f687*/ +#define LV_SYMBOL_EXT_BOOK_SKULL "\xEF\x9A\xB7" /*63159, f6b7*/ +#define LV_SYMBOL_EXT_BOOK_TANAKH "\xEF\xA0\xA7" /*63527, f827*/ +#define LV_SYMBOL_EXT_BOOKMARK "\xEF\x80\xAE" /*61486, f02e*/ +#define LV_SYMBOL_EXT_BOOTSTRAP "\xEF\xA0\xB6" /*63542, f836*/ +#define LV_SYMBOL_EXT_BORDER_ALL "\xEF\xA1\x8C" /*63564, f84c*/ +#define LV_SYMBOL_EXT_BORDER_NONE "\xEF\xA1\x90" /*63568, f850*/ +#define LV_SYMBOL_EXT_BORDER_TOP_LEFT "\xEF\xA1\x93" /*63571, f853*/ +#define LV_SYMBOL_EXT_BORE_HOLE "\xEE\x93\x83" /*58563, e4c3*/ +#define LV_SYMBOL_EXT_BOTS "\xEE\x8D\x80" /*58176, e340*/ +#define LV_SYMBOL_EXT_BOTTLE_DROPLET "\xEE\x93\x84" /*58564, e4c4*/ +#define LV_SYMBOL_EXT_BOTTLE_WATER "\xEE\x93\x85" /*58565, e4c5*/ +#define LV_SYMBOL_EXT_BOWL_FOOD "\xEE\x93\x86" /*58566, e4c6*/ +#define LV_SYMBOL_EXT_BOWL_RICE "\xEE\x8B\xAB" /*58091, e2eb*/ +#define LV_SYMBOL_EXT_BOWLING_BALL "\xEF\x90\xB6" /*62518, f436*/ +#define LV_SYMBOL_EXT_BOX "\xEF\x91\xA6" /*62566, f466*/ +#define LV_SYMBOL_EXT_BOX_ARCHIVE "\xEF\x86\x87" /*61831, f187*/ +#define LV_SYMBOL_EXT_BOX_OPEN "\xEF\x92\x9E" /*62622, f49e*/ +#define LV_SYMBOL_EXT_BOX_TISSUE "\xEE\x81\x9B" /*57435, e05b*/ +#define LV_SYMBOL_EXT_BOXES_PACKING "\xEE\x93\x87" /*58567, e4c7*/ +#define LV_SYMBOL_EXT_BOXES_STACKED "\xEF\x91\xA8" /*62568, f468*/ +#define LV_SYMBOL_EXT_BRAILLE "\xEF\x8A\xA1" /*62113, f2a1*/ +#define LV_SYMBOL_EXT_BRAIN "\xEF\x97\x9C" /*62940, f5dc*/ +#define LV_SYMBOL_EXT_BRAVE "\xEE\x98\xBC" /*58940, e63c*/ +#define LV_SYMBOL_EXT_BRAVE_REVERSE "\xEE\x98\xBD" /*58941, e63d*/ +#define LV_SYMBOL_EXT_BRAZILIAN_REAL_SIGN "\xEE\x91\xAC" /*58476, e46c*/ +#define LV_SYMBOL_EXT_BREAD_SLICE "\xEF\x9F\xAC" /*63468, f7ec*/ +#define LV_SYMBOL_EXT_BRIDGE "\xEE\x93\x88" /*58568, e4c8*/ +#define LV_SYMBOL_EXT_BRIDGE_CIRCLE_CHECK "\xEE\x93\x89" /*58569, e4c9*/ +#define LV_SYMBOL_EXT_BRIDGE_CIRCLE_EXCLAMATION "\xEE\x93\x8A" /*58570, e4ca*/ +#define LV_SYMBOL_EXT_BRIDGE_CIRCLE_XMARK "\xEE\x93\x8B" /*58571, e4cb*/ +#define LV_SYMBOL_EXT_BRIDGE_LOCK "\xEE\x93\x8C" /*58572, e4cc*/ +#define LV_SYMBOL_EXT_BRIDGE_WATER "\xEE\x93\x8E" /*58574, e4ce*/ +#define LV_SYMBOL_EXT_BRIEFCASE "\xEF\x82\xB1" /*61617, f0b1*/ +#define LV_SYMBOL_EXT_BRIEFCASE_MEDICAL "\xEF\x91\xA9" /*62569, f469*/ +#define LV_SYMBOL_EXT_BROOM "\xEF\x94\x9A" /*62746, f51a*/ +#define LV_SYMBOL_EXT_BROOM_BALL "\xEF\x91\x98" /*62552, f458*/ +#define LV_SYMBOL_EXT_BRUSH "\xEF\x95\x9D" /*62813, f55d*/ +#define LV_SYMBOL_EXT_BTC "\xEF\x85\x9A" /*61786, f15a*/ +#define LV_SYMBOL_EXT_BUCKET "\xEE\x93\x8F" /*58575, e4cf*/ +#define LV_SYMBOL_EXT_BUFFER "\xEF\xA0\xB7" /*63543, f837*/ +#define LV_SYMBOL_EXT_BUG "\xEF\x86\x88" /*61832, f188*/ +#define LV_SYMBOL_EXT_BUG_SLASH "\xEE\x92\x90" /*58512, e490*/ +#define LV_SYMBOL_EXT_BUGS "\xEE\x93\x90" /*58576, e4d0*/ +#define LV_SYMBOL_EXT_BUILDING "\xEF\x86\xAD" /*61869, f1ad*/ +#define LV_SYMBOL_EXT_BUILDING_CIRCLE_ARROW_RIGHT "\xEE\x93\x91" /*58577, e4d1*/ +#define LV_SYMBOL_EXT_BUILDING_CIRCLE_CHECK "\xEE\x93\x92" /*58578, e4d2*/ +#define LV_SYMBOL_EXT_BUILDING_CIRCLE_EXCLAMATION "\xEE\x93\x93" /*58579, e4d3*/ +#define LV_SYMBOL_EXT_BUILDING_CIRCLE_XMARK "\xEE\x93\x94" /*58580, e4d4*/ +#define LV_SYMBOL_EXT_BUILDING_COLUMNS "\xEF\x86\x9C" /*61852, f19c*/ +#define LV_SYMBOL_EXT_BUILDING_FLAG "\xEE\x93\x95" /*58581, e4d5*/ +#define LV_SYMBOL_EXT_BUILDING_LOCK "\xEE\x93\x96" /*58582, e4d6*/ +#define LV_SYMBOL_EXT_BUILDING_NGO "\xEE\x93\x97" /*58583, e4d7*/ +#define LV_SYMBOL_EXT_BUILDING_SHIELD "\xEE\x93\x98" /*58584, e4d8*/ +#define LV_SYMBOL_EXT_BUILDING_UN "\xEE\x93\x99" /*58585, e4d9*/ +#define LV_SYMBOL_EXT_BUILDING_USER "\xEE\x93\x9A" /*58586, e4da*/ +#define LV_SYMBOL_EXT_BUILDING_WHEAT "\xEE\x93\x9B" /*58587, e4db*/ +#define LV_SYMBOL_EXT_BULLHORN "\xEF\x82\xA1" /*61601, f0a1*/ +#define LV_SYMBOL_EXT_BULLSEYE "\xEF\x85\x80" /*61760, f140*/ +#define LV_SYMBOL_EXT_BURGER "\xEF\xA0\x85" /*63493, f805*/ +#define LV_SYMBOL_EXT_BUROMOBELEXPERTE "\xEF\x8D\xBF" /*62335, f37f*/ +#define LV_SYMBOL_EXT_BURST "\xEE\x93\x9C" /*58588, e4dc*/ +#define LV_SYMBOL_EXT_BUS "\xEF\x88\x87" /*61959, f207*/ +#define LV_SYMBOL_EXT_BUS_SIMPLE "\xEF\x95\x9E" /*62814, f55e*/ +#define LV_SYMBOL_EXT_BUSINESS_TIME "\xEF\x99\x8A" /*63050, f64a*/ +#define LV_SYMBOL_EXT_BUY_N_LARGE "\xEF\xA2\xA6" /*63654, f8a6*/ +#define LV_SYMBOL_EXT_BUYSELLADS "\xEF\x88\x8D" /*61965, f20d*/ +#define LV_SYMBOL_EXT_C "\x43" /*67, 43*/ +#define LV_SYMBOL_EXT_CABLE_CAR "\xEF\x9F\x9A" /*63450, f7da*/ +#define LV_SYMBOL_EXT_CAKE_CANDLES "\xEF\x87\xBD" /*61949, f1fd*/ +#define LV_SYMBOL_EXT_CALCULATOR "\xEF\x87\xAC" /*61932, f1ec*/ +#define LV_SYMBOL_EXT_CALENDAR "\xEF\x84\xB3" /*61747, f133*/ +#define LV_SYMBOL_EXT_CALENDAR_CHECK "\xEF\x89\xB4" /*62068, f274*/ +#define LV_SYMBOL_EXT_CALENDAR_DAY "\xEF\x9E\x83" /*63363, f783*/ +#define LV_SYMBOL_EXT_CALENDAR_DAYS "\xEF\x81\xB3" /*61555, f073*/ +#define LV_SYMBOL_EXT_CALENDAR_MINUS "\xEF\x89\xB2" /*62066, f272*/ +#define LV_SYMBOL_EXT_CALENDAR_PLUS "\xEF\x89\xB1" /*62065, f271*/ +#define LV_SYMBOL_EXT_CALENDAR_WEEK "\xEF\x9E\x84" /*63364, f784*/ +#define LV_SYMBOL_EXT_CALENDAR_XMARK "\xEF\x89\xB3" /*62067, f273*/ +#define LV_SYMBOL_EXT_CAMERA "\xEF\x80\xB0" /*61488, f030*/ +#define LV_SYMBOL_EXT_CAMERA_RETRO "\xEF\x82\x83" /*61571, f083*/ +#define LV_SYMBOL_EXT_CAMERA_ROTATE "\xEE\x83\x98" /*57560, e0d8*/ +#define LV_SYMBOL_EXT_CAMPGROUND "\xEF\x9A\xBB" /*63163, f6bb*/ +#define LV_SYMBOL_EXT_CANADIAN_MAPLE_LEAF "\xEF\x9E\x85" /*63365, f785*/ +#define LV_SYMBOL_EXT_CANDY_CANE "\xEF\x9E\x86" /*63366, f786*/ +#define LV_SYMBOL_EXT_CANNABIS "\xEF\x95\x9F" /*62815, f55f*/ +#define LV_SYMBOL_EXT_CAPSULES "\xEF\x91\xAB" /*62571, f46b*/ +#define LV_SYMBOL_EXT_CAR "\xEF\x86\xB9" /*61881, f1b9*/ +#define LV_SYMBOL_EXT_CAR_BATTERY "\xEF\x97\x9F" /*62943, f5df*/ +#define LV_SYMBOL_EXT_CAR_BURST "\xEF\x97\xA1" /*62945, f5e1*/ +#define LV_SYMBOL_EXT_CAR_ON "\xEE\x93\x9D" /*58589, e4dd*/ +#define LV_SYMBOL_EXT_CAR_REAR "\xEF\x97\x9E" /*62942, f5de*/ +#define LV_SYMBOL_EXT_CAR_SIDE "\xEF\x97\xA4" /*62948, f5e4*/ +#define LV_SYMBOL_EXT_CAR_TUNNEL "\xEE\x93\x9E" /*58590, e4de*/ +#define LV_SYMBOL_EXT_CARAVAN "\xEF\xA3\xBF" /*63743, f8ff*/ +#define LV_SYMBOL_EXT_CARET_DOWN "\xEF\x83\x97" /*61655, f0d7*/ +#define LV_SYMBOL_EXT_CARET_LEFT "\xEF\x83\x99" /*61657, f0d9*/ +#define LV_SYMBOL_EXT_CARET_RIGHT "\xEF\x83\x9A" /*61658, f0da*/ +#define LV_SYMBOL_EXT_CARET_UP "\xEF\x83\x98" /*61656, f0d8*/ +#define LV_SYMBOL_EXT_CARROT "\xEF\x9E\x87" /*63367, f787*/ +#define LV_SYMBOL_EXT_CART_ARROW_DOWN "\xEF\x88\x98" /*61976, f218*/ +#define LV_SYMBOL_EXT_CART_FLATBED "\xEF\x91\xB4" /*62580, f474*/ +#define LV_SYMBOL_EXT_CART_FLATBED_SUITCASE "\xEF\x96\x9D" /*62877, f59d*/ +#define LV_SYMBOL_EXT_CART_PLUS "\xEF\x88\x97" /*61975, f217*/ +#define LV_SYMBOL_EXT_CART_SHOPPING "\xEF\x81\xBA" /*61562, f07a*/ +#define LV_SYMBOL_EXT_CASH_REGISTER "\xEF\x9E\x88" /*63368, f788*/ +#define LV_SYMBOL_EXT_CAT "\xEF\x9A\xBE" /*63166, f6be*/ +#define LV_SYMBOL_EXT_CC_AMAZON_PAY "\xEF\x90\xAD" /*62509, f42d*/ +#define LV_SYMBOL_EXT_CC_AMEX "\xEF\x87\xB3" /*61939, f1f3*/ +#define LV_SYMBOL_EXT_CC_APPLE_PAY "\xEF\x90\x96" /*62486, f416*/ +#define LV_SYMBOL_EXT_CC_DINERS_CLUB "\xEF\x89\x8C" /*62028, f24c*/ +#define LV_SYMBOL_EXT_CC_DISCOVER "\xEF\x87\xB2" /*61938, f1f2*/ +#define LV_SYMBOL_EXT_CC_JCB "\xEF\x89\x8B" /*62027, f24b*/ +#define LV_SYMBOL_EXT_CC_MASTERCARD "\xEF\x87\xB1" /*61937, f1f1*/ +#define LV_SYMBOL_EXT_CC_PAYPAL "\xEF\x87\xB4" /*61940, f1f4*/ +#define LV_SYMBOL_EXT_CC_STRIPE "\xEF\x87\xB5" /*61941, f1f5*/ +#define LV_SYMBOL_EXT_CC_VISA "\xEF\x87\xB0" /*61936, f1f0*/ +#define LV_SYMBOL_EXT_CEDI_SIGN "\xEE\x83\x9F" /*57567, e0df*/ +#define LV_SYMBOL_EXT_CENT_SIGN "\xEE\x8F\xB5" /*58357, e3f5*/ +#define LV_SYMBOL_EXT_CENTERCODE "\xEF\x8E\x80" /*62336, f380*/ +#define LV_SYMBOL_EXT_CENTOS "\xEF\x9E\x89" /*63369, f789*/ +#define LV_SYMBOL_EXT_CERTIFICATE "\xEF\x82\xA3" /*61603, f0a3*/ +#define LV_SYMBOL_EXT_CHAIR "\xEF\x9B\x80" /*63168, f6c0*/ +#define LV_SYMBOL_EXT_CHALKBOARD "\xEF\x94\x9B" /*62747, f51b*/ +#define LV_SYMBOL_EXT_CHALKBOARD_USER "\xEF\x94\x9C" /*62748, f51c*/ +#define LV_SYMBOL_EXT_CHAMPAGNE_GLASSES "\xEF\x9E\x9F" /*63391, f79f*/ +#define LV_SYMBOL_EXT_CHARGING_STATION "\xEF\x97\xA7" /*62951, f5e7*/ +#define LV_SYMBOL_EXT_CHART_AREA "\xEF\x87\xBE" /*61950, f1fe*/ +#define LV_SYMBOL_EXT_CHART_BAR "\xEF\x82\x80" /*61568, f080*/ +#define LV_SYMBOL_EXT_CHART_COLUMN "\xEE\x83\xA3" /*57571, e0e3*/ +#define LV_SYMBOL_EXT_CHART_GANTT "\xEE\x83\xA4" /*57572, e0e4*/ +#define LV_SYMBOL_EXT_CHART_LINE "\xEF\x88\x81" /*61953, f201*/ +#define LV_SYMBOL_EXT_CHART_PIE "\xEF\x88\x80" /*61952, f200*/ +#define LV_SYMBOL_EXT_CHART_SIMPLE "\xEE\x91\xB3" /*58483, e473*/ +#define LV_SYMBOL_EXT_CHECK "\xEF\x80\x8C" /*61452, f00c*/ +#define LV_SYMBOL_EXT_CHECK_DOUBLE "\xEF\x95\xA0" /*62816, f560*/ +#define LV_SYMBOL_EXT_CHECK_TO_SLOT "\xEF\x9D\xB2" /*63346, f772*/ +#define LV_SYMBOL_EXT_CHEESE "\xEF\x9F\xAF" /*63471, f7ef*/ +#define LV_SYMBOL_EXT_CHESS "\xEF\x90\xB9" /*62521, f439*/ +#define LV_SYMBOL_EXT_CHESS_BISHOP "\xEF\x90\xBA" /*62522, f43a*/ +#define LV_SYMBOL_EXT_CHESS_BOARD "\xEF\x90\xBC" /*62524, f43c*/ +#define LV_SYMBOL_EXT_CHESS_KING "\xEF\x90\xBF" /*62527, f43f*/ +#define LV_SYMBOL_EXT_CHESS_KNIGHT "\xEF\x91\x81" /*62529, f441*/ +#define LV_SYMBOL_EXT_CHESS_PAWN "\xEF\x91\x83" /*62531, f443*/ +#define LV_SYMBOL_EXT_CHESS_QUEEN "\xEF\x91\x85" /*62533, f445*/ +#define LV_SYMBOL_EXT_CHESS_ROOK "\xEF\x91\x87" /*62535, f447*/ +#define LV_SYMBOL_EXT_CHEVRON_DOWN "\xEF\x81\xB8" /*61560, f078*/ +#define LV_SYMBOL_EXT_CHEVRON_LEFT "\xEF\x81\x93" /*61523, f053*/ +#define LV_SYMBOL_EXT_CHEVRON_RIGHT "\xEF\x81\x94" /*61524, f054*/ +#define LV_SYMBOL_EXT_CHEVRON_UP "\xEF\x81\xB7" /*61559, f077*/ +#define LV_SYMBOL_EXT_CHILD "\xEF\x86\xAE" /*61870, f1ae*/ +#define LV_SYMBOL_EXT_CHILD_COMBATANT "\xEE\x93\xA0" /*58592, e4e0*/ +#define LV_SYMBOL_EXT_CHILD_DRESS "\xEE\x96\x9C" /*58780, e59c*/ +#define LV_SYMBOL_EXT_CHILD_REACHING "\xEE\x96\x9D" /*58781, e59d*/ +#define LV_SYMBOL_EXT_CHILDREN "\xEE\x93\xA1" /*58593, e4e1*/ +#define LV_SYMBOL_EXT_CHROME "\xEF\x89\xA8" /*62056, f268*/ +#define LV_SYMBOL_EXT_CHROMECAST "\xEF\xA0\xB8" /*63544, f838*/ +#define LV_SYMBOL_EXT_CHURCH "\xEF\x94\x9D" /*62749, f51d*/ +#define LV_SYMBOL_EXT_CIRCLE "\xEF\x84\x91" /*61713, f111*/ +#define LV_SYMBOL_EXT_CIRCLE_ARROW_DOWN "\xEF\x82\xAB" /*61611, f0ab*/ +#define LV_SYMBOL_EXT_CIRCLE_ARROW_LEFT "\xEF\x82\xA8" /*61608, f0a8*/ +#define LV_SYMBOL_EXT_CIRCLE_ARROW_RIGHT "\xEF\x82\xA9" /*61609, f0a9*/ +#define LV_SYMBOL_EXT_CIRCLE_ARROW_UP "\xEF\x82\xAA" /*61610, f0aa*/ +#define LV_SYMBOL_EXT_CIRCLE_CHECK "\xEF\x81\x98" /*61528, f058*/ +#define LV_SYMBOL_EXT_CIRCLE_CHEVRON_DOWN "\xEF\x84\xBA" /*61754, f13a*/ +#define LV_SYMBOL_EXT_CIRCLE_CHEVRON_LEFT "\xEF\x84\xB7" /*61751, f137*/ +#define LV_SYMBOL_EXT_CIRCLE_CHEVRON_RIGHT "\xEF\x84\xB8" /*61752, f138*/ +#define LV_SYMBOL_EXT_CIRCLE_CHEVRON_UP "\xEF\x84\xB9" /*61753, f139*/ +#define LV_SYMBOL_EXT_CIRCLE_DOLLAR_TO_SLOT "\xEF\x92\xB9" /*62649, f4b9*/ +#define LV_SYMBOL_EXT_CIRCLE_DOT "\xEF\x86\x92" /*61842, f192*/ +#define LV_SYMBOL_EXT_CIRCLE_DOWN "\xEF\x8D\x98" /*62296, f358*/ +#define LV_SYMBOL_EXT_CIRCLE_EXCLAMATION "\xEF\x81\xAA" /*61546, f06a*/ +#define LV_SYMBOL_EXT_CIRCLE_H "\xEF\x91\xBE" /*62590, f47e*/ +#define LV_SYMBOL_EXT_CIRCLE_HALF_STROKE "\xEF\x81\x82" /*61506, f042*/ +#define LV_SYMBOL_EXT_CIRCLE_INFO "\xEF\x81\x9A" /*61530, f05a*/ +#define LV_SYMBOL_EXT_CIRCLE_LEFT "\xEF\x8D\x99" /*62297, f359*/ +#define LV_SYMBOL_EXT_CIRCLE_MINUS "\xEF\x81\x96" /*61526, f056*/ +#define LV_SYMBOL_EXT_CIRCLE_NODES "\xEE\x93\xA2" /*58594, e4e2*/ +#define LV_SYMBOL_EXT_CIRCLE_NOTCH "\xEF\x87\x8E" /*61902, f1ce*/ +#define LV_SYMBOL_EXT_CIRCLE_PAUSE "\xEF\x8A\x8B" /*62091, f28b*/ +#define LV_SYMBOL_EXT_CIRCLE_PLAY "\xEF\x85\x84" /*61764, f144*/ +#define LV_SYMBOL_EXT_CIRCLE_PLUS "\xEF\x81\x95" /*61525, f055*/ +#define LV_SYMBOL_EXT_CIRCLE_QUESTION "\xEF\x81\x99" /*61529, f059*/ +#define LV_SYMBOL_EXT_CIRCLE_RADIATION "\xEF\x9E\xBA" /*63418, f7ba*/ +#define LV_SYMBOL_EXT_CIRCLE_RIGHT "\xEF\x8D\x9A" /*62298, f35a*/ +#define LV_SYMBOL_EXT_CIRCLE_STOP "\xEF\x8A\x8D" /*62093, f28d*/ +#define LV_SYMBOL_EXT_CIRCLE_UP "\xEF\x8D\x9B" /*62299, f35b*/ +#define LV_SYMBOL_EXT_CIRCLE_USER "\xEF\x8A\xBD" /*62141, f2bd*/ +#define LV_SYMBOL_EXT_CIRCLE_XMARK "\xEF\x81\x97" /*61527, f057*/ +#define LV_SYMBOL_EXT_CITY "\xEF\x99\x8F" /*63055, f64f*/ +#define LV_SYMBOL_EXT_CLAPPERBOARD "\xEE\x84\xB1" /*57649, e131*/ +#define LV_SYMBOL_EXT_CLIPBOARD "\xEF\x8C\xA8" /*62248, f328*/ +#define LV_SYMBOL_EXT_CLIPBOARD_CHECK "\xEF\x91\xAC" /*62572, f46c*/ +#define LV_SYMBOL_EXT_CLIPBOARD_LIST "\xEF\x91\xAD" /*62573, f46d*/ +#define LV_SYMBOL_EXT_CLIPBOARD_QUESTION "\xEE\x93\xA3" /*58595, e4e3*/ +#define LV_SYMBOL_EXT_CLIPBOARD_USER "\xEF\x9F\xB3" /*63475, f7f3*/ +#define LV_SYMBOL_EXT_CLOCK "\xEF\x80\x97" /*61463, f017*/ +#define LV_SYMBOL_EXT_CLOCK_ROTATE_LEFT "\xEF\x87\x9A" /*61914, f1da*/ +#define LV_SYMBOL_EXT_CLONE "\xEF\x89\x8D" /*62029, f24d*/ +#define LV_SYMBOL_EXT_CLOSED_CAPTIONING "\xEF\x88\x8A" /*61962, f20a*/ +#define LV_SYMBOL_EXT_CLOUD "\xEF\x83\x82" /*61634, f0c2*/ +#define LV_SYMBOL_EXT_CLOUD_ARROW_DOWN "\xEF\x83\xAD" /*61677, f0ed*/ +#define LV_SYMBOL_EXT_CLOUD_ARROW_UP "\xEF\x83\xAE" /*61678, f0ee*/ +#define LV_SYMBOL_EXT_CLOUD_BOLT "\xEF\x9D\xAC" /*63340, f76c*/ +#define LV_SYMBOL_EXT_CLOUD_MEATBALL "\xEF\x9C\xBB" /*63291, f73b*/ +#define LV_SYMBOL_EXT_CLOUD_MOON "\xEF\x9B\x83" /*63171, f6c3*/ +#define LV_SYMBOL_EXT_CLOUD_MOON_RAIN "\xEF\x9C\xBC" /*63292, f73c*/ +#define LV_SYMBOL_EXT_CLOUD_RAIN "\xEF\x9C\xBD" /*63293, f73d*/ +#define LV_SYMBOL_EXT_CLOUD_SHOWERS_HEAVY "\xEF\x9D\x80" /*63296, f740*/ +#define LV_SYMBOL_EXT_CLOUD_SHOWERS_WATER "\xEE\x93\xA4" /*58596, e4e4*/ +#define LV_SYMBOL_EXT_CLOUD_SUN "\xEF\x9B\x84" /*63172, f6c4*/ +#define LV_SYMBOL_EXT_CLOUD_SUN_RAIN "\xEF\x9D\x83" /*63299, f743*/ +#define LV_SYMBOL_EXT_CLOUDFLARE "\xEE\x81\xBD" /*57469, e07d*/ +#define LV_SYMBOL_EXT_CLOUDSCALE "\xEF\x8E\x83" /*62339, f383*/ +#define LV_SYMBOL_EXT_CLOUDSMITH "\xEF\x8E\x84" /*62340, f384*/ +#define LV_SYMBOL_EXT_CLOUDVERSIFY "\xEF\x8E\x85" /*62341, f385*/ +#define LV_SYMBOL_EXT_CLOVER "\xEE\x84\xB9" /*57657, e139*/ +#define LV_SYMBOL_EXT_CMPLID "\xEE\x8D\xA0" /*58208, e360*/ +#define LV_SYMBOL_EXT_CODE "\xEF\x84\xA1" /*61729, f121*/ +#define LV_SYMBOL_EXT_CODE_BRANCH "\xEF\x84\xA6" /*61734, f126*/ +#define LV_SYMBOL_EXT_CODE_COMMIT "\xEF\x8E\x86" /*62342, f386*/ +#define LV_SYMBOL_EXT_CODE_COMPARE "\xEE\x84\xBA" /*57658, e13a*/ +#define LV_SYMBOL_EXT_CODE_FORK "\xEE\x84\xBB" /*57659, e13b*/ +#define LV_SYMBOL_EXT_CODE_MERGE "\xEF\x8E\x87" /*62343, f387*/ +#define LV_SYMBOL_EXT_CODE_PULL_REQUEST "\xEE\x84\xBC" /*57660, e13c*/ +#define LV_SYMBOL_EXT_CODEPEN "\xEF\x87\x8B" /*61899, f1cb*/ +#define LV_SYMBOL_EXT_CODIEPIE "\xEF\x8A\x84" /*62084, f284*/ +#define LV_SYMBOL_EXT_COINS "\xEF\x94\x9E" /*62750, f51e*/ +#define LV_SYMBOL_EXT_COLON_SIGN "\xEE\x85\x80" /*57664, e140*/ +#define LV_SYMBOL_EXT_COMMENT "\xEF\x81\xB5" /*61557, f075*/ +#define LV_SYMBOL_EXT_COMMENT_DOLLAR "\xEF\x99\x91" /*63057, f651*/ +#define LV_SYMBOL_EXT_COMMENT_DOTS "\xEF\x92\xAD" /*62637, f4ad*/ +#define LV_SYMBOL_EXT_COMMENT_MEDICAL "\xEF\x9F\xB5" /*63477, f7f5*/ +#define LV_SYMBOL_EXT_COMMENT_SLASH "\xEF\x92\xB3" /*62643, f4b3*/ +#define LV_SYMBOL_EXT_COMMENT_SMS "\xEF\x9F\x8D" /*63437, f7cd*/ +#define LV_SYMBOL_EXT_COMMENTS "\xEF\x82\x86" /*61574, f086*/ +#define LV_SYMBOL_EXT_COMMENTS_DOLLAR "\xEF\x99\x93" /*63059, f653*/ +#define LV_SYMBOL_EXT_COMPACT_DISC "\xEF\x94\x9F" /*62751, f51f*/ +#define LV_SYMBOL_EXT_COMPASS "\xEF\x85\x8E" /*61774, f14e*/ +#define LV_SYMBOL_EXT_COMPASS_DRAFTING "\xEF\x95\xA8" /*62824, f568*/ +#define LV_SYMBOL_EXT_COMPRESS "\xEF\x81\xA6" /*61542, f066*/ +#define LV_SYMBOL_EXT_COMPUTER "\xEE\x93\xA5" /*58597, e4e5*/ +#define LV_SYMBOL_EXT_COMPUTER_MOUSE "\xEF\xA3\x8C" /*63692, f8cc*/ +#define LV_SYMBOL_EXT_CONFLUENCE "\xEF\x9E\x8D" /*63373, f78d*/ +#define LV_SYMBOL_EXT_CONNECTDEVELOP "\xEF\x88\x8E" /*61966, f20e*/ +#define LV_SYMBOL_EXT_CONTAO "\xEF\x89\xAD" /*62061, f26d*/ +#define LV_SYMBOL_EXT_COOKIE "\xEF\x95\xA3" /*62819, f563*/ +#define LV_SYMBOL_EXT_COOKIE_BITE "\xEF\x95\xA4" /*62820, f564*/ +#define LV_SYMBOL_EXT_COPY "\xEF\x83\x85" /*61637, f0c5*/ +#define LV_SYMBOL_EXT_COPYRIGHT "\xEF\x87\xB9" /*61945, f1f9*/ +#define LV_SYMBOL_EXT_COTTON_BUREAU "\xEF\xA2\x9E" /*63646, f89e*/ +#define LV_SYMBOL_EXT_COUCH "\xEF\x92\xB8" /*62648, f4b8*/ +#define LV_SYMBOL_EXT_COW "\xEF\x9B\x88" /*63176, f6c8*/ +#define LV_SYMBOL_EXT_CPANEL "\xEF\x8E\x88" /*62344, f388*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS "\xEF\x89\x9E" /*62046, f25e*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_BY "\xEF\x93\xA7" /*62695, f4e7*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_NC "\xEF\x93\xA8" /*62696, f4e8*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_NC_EU "\xEF\x93\xA9" /*62697, f4e9*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_NC_JP "\xEF\x93\xAA" /*62698, f4ea*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_ND "\xEF\x93\xAB" /*62699, f4eb*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_PD "\xEF\x93\xAC" /*62700, f4ec*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_PD_ALT "\xEF\x93\xAD" /*62701, f4ed*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_REMIX "\xEF\x93\xAE" /*62702, f4ee*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_SA "\xEF\x93\xAF" /*62703, f4ef*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_SAMPLING "\xEF\x93\xB0" /*62704, f4f0*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_SAMPLING_PLUS "\xEF\x93\xB1" /*62705, f4f1*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_SHARE "\xEF\x93\xB2" /*62706, f4f2*/ +#define LV_SYMBOL_EXT_CREATIVE_COMMONS_ZERO "\xEF\x93\xB3" /*62707, f4f3*/ +#define LV_SYMBOL_EXT_CREDIT_CARD "\xEF\x82\x9D" /*61597, f09d*/ +#define LV_SYMBOL_EXT_CRITICAL_ROLE "\xEF\x9B\x89" /*63177, f6c9*/ +#define LV_SYMBOL_EXT_CROP "\xEF\x84\xA5" /*61733, f125*/ +#define LV_SYMBOL_EXT_CROP_SIMPLE "\xEF\x95\xA5" /*62821, f565*/ +#define LV_SYMBOL_EXT_CROSS "\xEF\x99\x94" /*63060, f654*/ +#define LV_SYMBOL_EXT_CROSSHAIRS "\xEF\x81\x9B" /*61531, f05b*/ +#define LV_SYMBOL_EXT_CROW "\xEF\x94\xA0" /*62752, f520*/ +#define LV_SYMBOL_EXT_CROWN "\xEF\x94\xA1" /*62753, f521*/ +#define LV_SYMBOL_EXT_CRUTCH "\xEF\x9F\xB7" /*63479, f7f7*/ +#define LV_SYMBOL_EXT_CRUZEIRO_SIGN "\xEE\x85\x92" /*57682, e152*/ +#define LV_SYMBOL_EXT_CSS3 "\xEF\x84\xBC" /*61756, f13c*/ +#define LV_SYMBOL_EXT_CSS3_ALT "\xEF\x8E\x8B" /*62347, f38b*/ +#define LV_SYMBOL_EXT_CUBE "\xEF\x86\xB2" /*61874, f1b2*/ +#define LV_SYMBOL_EXT_CUBES "\xEF\x86\xB3" /*61875, f1b3*/ +#define LV_SYMBOL_EXT_CUBES_STACKED "\xEE\x93\xA6" /*58598, e4e6*/ +#define LV_SYMBOL_EXT_CUTTLEFISH "\xEF\x8E\x8C" /*62348, f38c*/ +#define LV_SYMBOL_EXT_D "\x44" /*68, 44*/ +#define LV_SYMBOL_EXT_D_AND_D "\xEF\x8E\x8D" /*62349, f38d*/ +#define LV_SYMBOL_EXT_D_AND_D_BEYOND "\xEF\x9B\x8A" /*63178, f6ca*/ +#define LV_SYMBOL_EXT_DAILYMOTION "\xEE\x81\x92" /*57426, e052*/ +#define LV_SYMBOL_EXT_DASHCUBE "\xEF\x88\x90" /*61968, f210*/ +#define LV_SYMBOL_EXT_DATABASE "\xEF\x87\x80" /*61888, f1c0*/ +#define LV_SYMBOL_EXT_DEBIAN "\xEE\x98\x8B" /*58891, e60b*/ +#define LV_SYMBOL_EXT_DEEZER "\xEE\x81\xB7" /*57463, e077*/ +#define LV_SYMBOL_EXT_DELETE_LEFT "\xEF\x95\x9A" /*62810, f55a*/ +#define LV_SYMBOL_EXT_DELICIOUS "\xEF\x86\xA5" /*61861, f1a5*/ +#define LV_SYMBOL_EXT_DEMOCRAT "\xEF\x9D\x87" /*63303, f747*/ +#define LV_SYMBOL_EXT_DEPLOYDOG "\xEF\x8E\x8E" /*62350, f38e*/ +#define LV_SYMBOL_EXT_DESKPRO "\xEF\x8E\x8F" /*62351, f38f*/ +#define LV_SYMBOL_EXT_DESKTOP "\xEF\x8E\x90" /*62352, f390*/ +#define LV_SYMBOL_EXT_DEV "\xEF\x9B\x8C" /*63180, f6cc*/ +#define LV_SYMBOL_EXT_DEVIANTART "\xEF\x86\xBD" /*61885, f1bd*/ +#define LV_SYMBOL_EXT_DHARMACHAKRA "\xEF\x99\x95" /*63061, f655*/ +#define LV_SYMBOL_EXT_DHL "\xEF\x9E\x90" /*63376, f790*/ +#define LV_SYMBOL_EXT_DIAGRAM_NEXT "\xEE\x91\xB6" /*58486, e476*/ +#define LV_SYMBOL_EXT_DIAGRAM_PREDECESSOR "\xEE\x91\xB7" /*58487, e477*/ +#define LV_SYMBOL_EXT_DIAGRAM_PROJECT "\xEF\x95\x82" /*62786, f542*/ +#define LV_SYMBOL_EXT_DIAGRAM_SUCCESSOR "\xEE\x91\xBA" /*58490, e47a*/ +#define LV_SYMBOL_EXT_DIAMOND "\xEF\x88\x99" /*61977, f219*/ +#define LV_SYMBOL_EXT_DIAMOND_TURN_RIGHT "\xEF\x97\xAB" /*62955, f5eb*/ +#define LV_SYMBOL_EXT_DIASPORA "\xEF\x9E\x91" /*63377, f791*/ +#define LV_SYMBOL_EXT_DICE "\xEF\x94\xA2" /*62754, f522*/ +#define LV_SYMBOL_EXT_DICE_D20 "\xEF\x9B\x8F" /*63183, f6cf*/ +#define LV_SYMBOL_EXT_DICE_D6 "\xEF\x9B\x91" /*63185, f6d1*/ +#define LV_SYMBOL_EXT_DICE_FIVE "\xEF\x94\xA3" /*62755, f523*/ +#define LV_SYMBOL_EXT_DICE_FOUR "\xEF\x94\xA4" /*62756, f524*/ +#define LV_SYMBOL_EXT_DICE_ONE "\xEF\x94\xA5" /*62757, f525*/ +#define LV_SYMBOL_EXT_DICE_SIX "\xEF\x94\xA6" /*62758, f526*/ +#define LV_SYMBOL_EXT_DICE_THREE "\xEF\x94\xA7" /*62759, f527*/ +#define LV_SYMBOL_EXT_DICE_TWO "\xEF\x94\xA8" /*62760, f528*/ +#define LV_SYMBOL_EXT_DIGG "\xEF\x86\xA6" /*61862, f1a6*/ +#define LV_SYMBOL_EXT_DIGITAL_OCEAN "\xEF\x8E\x91" /*62353, f391*/ +#define LV_SYMBOL_EXT_DISCORD "\xEF\x8E\x92" /*62354, f392*/ +#define LV_SYMBOL_EXT_DISCOURSE "\xEF\x8E\x93" /*62355, f393*/ +#define LV_SYMBOL_EXT_DISEASE "\xEF\x9F\xBA" /*63482, f7fa*/ +#define LV_SYMBOL_EXT_DISPLAY "\xEE\x85\xA3" /*57699, e163*/ +#define LV_SYMBOL_EXT_DIVIDE "\xEF\x94\xA9" /*62761, f529*/ +#define LV_SYMBOL_EXT_DNA "\xEF\x91\xB1" /*62577, f471*/ +#define LV_SYMBOL_EXT_DOCHUB "\xEF\x8E\x94" /*62356, f394*/ +#define LV_SYMBOL_EXT_DOCKER "\xEF\x8E\x95" /*62357, f395*/ +#define LV_SYMBOL_EXT_DOG "\xEF\x9B\x93" /*63187, f6d3*/ +#define LV_SYMBOL_EXT_DOLLAR_SIGN "\x24" /*36, 24*/ +#define LV_SYMBOL_EXT_DOLLY "\xEF\x91\xB2" /*62578, f472*/ +#define LV_SYMBOL_EXT_DONG_SIGN "\xEE\x85\xA9" /*57705, e169*/ +#define LV_SYMBOL_EXT_DOOR_CLOSED "\xEF\x94\xAA" /*62762, f52a*/ +#define LV_SYMBOL_EXT_DOOR_OPEN "\xEF\x94\xAB" /*62763, f52b*/ +#define LV_SYMBOL_EXT_DOVE "\xEF\x92\xBA" /*62650, f4ba*/ +#define LV_SYMBOL_EXT_DOWN_LEFT_AND_UP_RIGHT_TO_CENTER "\xEF\x90\xA2" /*62498, f422*/ +#define LV_SYMBOL_EXT_DOWN_LONG "\xEF\x8C\x89" /*62217, f309*/ +#define LV_SYMBOL_EXT_DOWNLOAD "\xEF\x80\x99" /*61465, f019*/ +#define LV_SYMBOL_EXT_DRAFT2DIGITAL "\xEF\x8E\x96" /*62358, f396*/ +#define LV_SYMBOL_EXT_DRAGON "\xEF\x9B\x95" /*63189, f6d5*/ +#define LV_SYMBOL_EXT_DRAW_POLYGON "\xEF\x97\xAE" /*62958, f5ee*/ +#define LV_SYMBOL_EXT_DRIBBBLE "\xEF\x85\xBD" /*61821, f17d*/ +#define LV_SYMBOL_EXT_DROPBOX "\xEF\x85\xAB" /*61803, f16b*/ +#define LV_SYMBOL_EXT_DROPLET "\xEF\x81\x83" /*61507, f043*/ +#define LV_SYMBOL_EXT_DROPLET_SLASH "\xEF\x97\x87" /*62919, f5c7*/ +#define LV_SYMBOL_EXT_DRUM "\xEF\x95\xA9" /*62825, f569*/ +#define LV_SYMBOL_EXT_DRUM_STEELPAN "\xEF\x95\xAA" /*62826, f56a*/ +#define LV_SYMBOL_EXT_DRUMSTICK_BITE "\xEF\x9B\x97" /*63191, f6d7*/ +#define LV_SYMBOL_EXT_DRUPAL "\xEF\x86\xA9" /*61865, f1a9*/ +#define LV_SYMBOL_EXT_DUMBBELL "\xEF\x91\x8B" /*62539, f44b*/ +#define LV_SYMBOL_EXT_DUMPSTER "\xEF\x9E\x93" /*63379, f793*/ +#define LV_SYMBOL_EXT_DUMPSTER_FIRE "\xEF\x9E\x94" /*63380, f794*/ +#define LV_SYMBOL_EXT_DUNGEON "\xEF\x9B\x99" /*63193, f6d9*/ +#define LV_SYMBOL_EXT_DYALOG "\xEF\x8E\x99" /*62361, f399*/ +#define LV_SYMBOL_EXT_E "\x45" /*69, 45*/ +#define LV_SYMBOL_EXT_EAR_DEAF "\xEF\x8A\xA4" /*62116, f2a4*/ +#define LV_SYMBOL_EXT_EAR_LISTEN "\xEF\x8A\xA2" /*62114, f2a2*/ +#define LV_SYMBOL_EXT_EARLYBIRDS "\xEF\x8E\x9A" /*62362, f39a*/ +#define LV_SYMBOL_EXT_EARTH_AFRICA "\xEF\x95\xBC" /*62844, f57c*/ +#define LV_SYMBOL_EXT_EARTH_AMERICAS "\xEF\x95\xBD" /*62845, f57d*/ +#define LV_SYMBOL_EXT_EARTH_ASIA "\xEF\x95\xBE" /*62846, f57e*/ +#define LV_SYMBOL_EXT_EARTH_EUROPE "\xEF\x9E\xA2" /*63394, f7a2*/ +#define LV_SYMBOL_EXT_EARTH_OCEANIA "\xEE\x91\xBB" /*58491, e47b*/ +#define LV_SYMBOL_EXT_EBAY "\xEF\x93\xB4" /*62708, f4f4*/ +#define LV_SYMBOL_EXT_EDGE "\xEF\x8A\x82" /*62082, f282*/ +#define LV_SYMBOL_EXT_EDGE_LEGACY "\xEE\x81\xB8" /*57464, e078*/ +#define LV_SYMBOL_EXT_EGG "\xEF\x9F\xBB" /*63483, f7fb*/ +#define LV_SYMBOL_EXT_EJECT "\xEF\x81\x92" /*61522, f052*/ +#define LV_SYMBOL_EXT_ELEMENTOR "\xEF\x90\xB0" /*62512, f430*/ +#define LV_SYMBOL_EXT_ELEVATOR "\xEE\x85\xAD" /*57709, e16d*/ +#define LV_SYMBOL_EXT_ELLIPSIS "\xEF\x85\x81" /*61761, f141*/ +#define LV_SYMBOL_EXT_ELLIPSIS_VERTICAL "\xEF\x85\x82" /*61762, f142*/ +#define LV_SYMBOL_EXT_ELLO "\xEF\x97\xB1" /*62961, f5f1*/ +#define LV_SYMBOL_EXT_EMBER "\xEF\x90\xA3" /*62499, f423*/ +#define LV_SYMBOL_EXT_EMPIRE "\xEF\x87\x91" /*61905, f1d1*/ +#define LV_SYMBOL_EXT_ENVELOPE "\xEF\x83\xA0" /*61664, f0e0*/ +#define LV_SYMBOL_EXT_ENVELOPE_CIRCLE_CHECK "\xEE\x93\xA8" /*58600, e4e8*/ +#define LV_SYMBOL_EXT_ENVELOPE_OPEN "\xEF\x8A\xB6" /*62134, f2b6*/ +#define LV_SYMBOL_EXT_ENVELOPE_OPEN_TEXT "\xEF\x99\x98" /*63064, f658*/ +#define LV_SYMBOL_EXT_ENVELOPES_BULK "\xEF\x99\xB4" /*63092, f674*/ +#define LV_SYMBOL_EXT_ENVIRA "\xEF\x8A\x99" /*62105, f299*/ +#define LV_SYMBOL_EXT_EQUALS "\x3D" /*61, 3d*/ +#define LV_SYMBOL_EXT_ERASER "\xEF\x84\xAD" /*61741, f12d*/ +#define LV_SYMBOL_EXT_ERLANG "\xEF\x8E\x9D" /*62365, f39d*/ +#define LV_SYMBOL_EXT_ETHEREUM "\xEF\x90\xAE" /*62510, f42e*/ +#define LV_SYMBOL_EXT_ETHERNET "\xEF\x9E\x96" /*63382, f796*/ +#define LV_SYMBOL_EXT_ETSY "\xEF\x8B\x97" /*62167, f2d7*/ +#define LV_SYMBOL_EXT_EURO_SIGN "\xEF\x85\x93" /*61779, f153*/ +#define LV_SYMBOL_EXT_EVERNOTE "\xEF\xA0\xB9" /*63545, f839*/ +#define LV_SYMBOL_EXT_EXCLAMATION "\x21" /*33, 21*/ +#define LV_SYMBOL_EXT_EXPAND "\xEF\x81\xA5" /*61541, f065*/ +#define LV_SYMBOL_EXT_EXPEDITEDSSL "\xEF\x88\xBE" /*62014, f23e*/ +#define LV_SYMBOL_EXT_EXPLOSION "\xEE\x93\xA9" /*58601, e4e9*/ +#define LV_SYMBOL_EXT_EYE "\xEF\x81\xAE" /*61550, f06e*/ +#define LV_SYMBOL_EXT_EYE_DROPPER "\xEF\x87\xBB" /*61947, f1fb*/ +#define LV_SYMBOL_EXT_EYE_LOW_VISION "\xEF\x8A\xA8" /*62120, f2a8*/ +#define LV_SYMBOL_EXT_EYE_SLASH "\xEF\x81\xB0" /*61552, f070*/ +#define LV_SYMBOL_EXT_F "\x46" /*70, 46*/ +#define LV_SYMBOL_EXT_FACE_ANGRY "\xEF\x95\x96" /*62806, f556*/ +#define LV_SYMBOL_EXT_FACE_DIZZY "\xEF\x95\xA7" /*62823, f567*/ +#define LV_SYMBOL_EXT_FACE_FLUSHED "\xEF\x95\xB9" /*62841, f579*/ +#define LV_SYMBOL_EXT_FACE_FROWN "\xEF\x84\x99" /*61721, f119*/ +#define LV_SYMBOL_EXT_FACE_FROWN_OPEN "\xEF\x95\xBA" /*62842, f57a*/ +#define LV_SYMBOL_EXT_FACE_GRIMACE "\xEF\x95\xBF" /*62847, f57f*/ +#define LV_SYMBOL_EXT_FACE_GRIN "\xEF\x96\x80" /*62848, f580*/ +#define LV_SYMBOL_EXT_FACE_GRIN_BEAM "\xEF\x96\x82" /*62850, f582*/ +#define LV_SYMBOL_EXT_FACE_GRIN_BEAM_SWEAT "\xEF\x96\x83" /*62851, f583*/ +#define LV_SYMBOL_EXT_FACE_GRIN_HEARTS "\xEF\x96\x84" /*62852, f584*/ +#define LV_SYMBOL_EXT_FACE_GRIN_SQUINT "\xEF\x96\x85" /*62853, f585*/ +#define LV_SYMBOL_EXT_FACE_GRIN_SQUINT_TEARS "\xEF\x96\x86" /*62854, f586*/ +#define LV_SYMBOL_EXT_FACE_GRIN_STARS "\xEF\x96\x87" /*62855, f587*/ +#define LV_SYMBOL_EXT_FACE_GRIN_TEARS "\xEF\x96\x88" /*62856, f588*/ +#define LV_SYMBOL_EXT_FACE_GRIN_TONGUE "\xEF\x96\x89" /*62857, f589*/ +#define LV_SYMBOL_EXT_FACE_GRIN_TONGUE_SQUINT "\xEF\x96\x8A" /*62858, f58a*/ +#define LV_SYMBOL_EXT_FACE_GRIN_TONGUE_WINK "\xEF\x96\x8B" /*62859, f58b*/ +#define LV_SYMBOL_EXT_FACE_GRIN_WIDE "\xEF\x96\x81" /*62849, f581*/ +#define LV_SYMBOL_EXT_FACE_GRIN_WINK "\xEF\x96\x8C" /*62860, f58c*/ +#define LV_SYMBOL_EXT_FACE_KISS "\xEF\x96\x96" /*62870, f596*/ +#define LV_SYMBOL_EXT_FACE_KISS_BEAM "\xEF\x96\x97" /*62871, f597*/ +#define LV_SYMBOL_EXT_FACE_KISS_WINK_HEART "\xEF\x96\x98" /*62872, f598*/ +#define LV_SYMBOL_EXT_FACE_LAUGH "\xEF\x96\x99" /*62873, f599*/ +#define LV_SYMBOL_EXT_FACE_LAUGH_BEAM "\xEF\x96\x9A" /*62874, f59a*/ +#define LV_SYMBOL_EXT_FACE_LAUGH_SQUINT "\xEF\x96\x9B" /*62875, f59b*/ +#define LV_SYMBOL_EXT_FACE_LAUGH_WINK "\xEF\x96\x9C" /*62876, f59c*/ +#define LV_SYMBOL_EXT_FACE_MEH "\xEF\x84\x9A" /*61722, f11a*/ +#define LV_SYMBOL_EXT_FACE_MEH_BLANK "\xEF\x96\xA4" /*62884, f5a4*/ +#define LV_SYMBOL_EXT_FACE_ROLLING_EYES "\xEF\x96\xA5" /*62885, f5a5*/ +#define LV_SYMBOL_EXT_FACE_SAD_CRY "\xEF\x96\xB3" /*62899, f5b3*/ +#define LV_SYMBOL_EXT_FACE_SAD_TEAR "\xEF\x96\xB4" /*62900, f5b4*/ +#define LV_SYMBOL_EXT_FACE_SMILE "\xEF\x84\x98" /*61720, f118*/ +#define LV_SYMBOL_EXT_FACE_SMILE_BEAM "\xEF\x96\xB8" /*62904, f5b8*/ +#define LV_SYMBOL_EXT_FACE_SMILE_WINK "\xEF\x93\x9A" /*62682, f4da*/ +#define LV_SYMBOL_EXT_FACE_SURPRISE "\xEF\x97\x82" /*62914, f5c2*/ +#define LV_SYMBOL_EXT_FACE_TIRED "\xEF\x97\x88" /*62920, f5c8*/ +#define LV_SYMBOL_EXT_FACEBOOK "\xEF\x82\x9A" /*61594, f09a*/ +#define LV_SYMBOL_EXT_FACEBOOK_F "\xEF\x8E\x9E" /*62366, f39e*/ +#define LV_SYMBOL_EXT_FACEBOOK_MESSENGER "\xEF\x8E\x9F" /*62367, f39f*/ +#define LV_SYMBOL_EXT_FAN "\xEF\xA1\xA3" /*63587, f863*/ +#define LV_SYMBOL_EXT_FANTASY_FLIGHT_GAMES "\xEF\x9B\x9C" /*63196, f6dc*/ +#define LV_SYMBOL_EXT_FAUCET "\xEE\x80\x85" /*57349, e005*/ +#define LV_SYMBOL_EXT_FAUCET_DRIP "\xEE\x80\x86" /*57350, e006*/ +#define LV_SYMBOL_EXT_FAX "\xEF\x86\xAC" /*61868, f1ac*/ +#define LV_SYMBOL_EXT_FEATHER "\xEF\x94\xAD" /*62765, f52d*/ +#define LV_SYMBOL_EXT_FEATHER_POINTED "\xEF\x95\xAB" /*62827, f56b*/ +#define LV_SYMBOL_EXT_FEDEX "\xEF\x9E\x97" /*63383, f797*/ +#define LV_SYMBOL_EXT_FEDORA "\xEF\x9E\x98" /*63384, f798*/ +#define LV_SYMBOL_EXT_FERRY "\xEE\x93\xAA" /*58602, e4ea*/ +#define LV_SYMBOL_EXT_FIGMA "\xEF\x9E\x99" /*63385, f799*/ +#define LV_SYMBOL_EXT_FILE "\xEF\x85\x9B" /*61787, f15b*/ +#define LV_SYMBOL_EXT_FILE_ARROW_DOWN "\xEF\x95\xAD" /*62829, f56d*/ +#define LV_SYMBOL_EXT_FILE_ARROW_UP "\xEF\x95\xB4" /*62836, f574*/ +#define LV_SYMBOL_EXT_FILE_AUDIO "\xEF\x87\x87" /*61895, f1c7*/ +#define LV_SYMBOL_EXT_FILE_CIRCLE_CHECK "\xEE\x96\xA0" /*58784, e5a0*/ +#define LV_SYMBOL_EXT_FILE_CIRCLE_EXCLAMATION "\xEE\x93\xAB" /*58603, e4eb*/ +#define LV_SYMBOL_EXT_FILE_CIRCLE_MINUS "\xEE\x93\xAD" /*58605, e4ed*/ +#define LV_SYMBOL_EXT_FILE_CIRCLE_PLUS "\xEE\x92\x94" /*58516, e494*/ +#define LV_SYMBOL_EXT_FILE_CIRCLE_QUESTION "\xEE\x93\xAF" /*58607, e4ef*/ +#define LV_SYMBOL_EXT_FILE_CIRCLE_XMARK "\xEE\x96\xA1" /*58785, e5a1*/ +#define LV_SYMBOL_EXT_FILE_CODE "\xEF\x87\x89" /*61897, f1c9*/ +#define LV_SYMBOL_EXT_FILE_CONTRACT "\xEF\x95\xAC" /*62828, f56c*/ +#define LV_SYMBOL_EXT_FILE_CSV "\xEF\x9B\x9D" /*63197, f6dd*/ +#define LV_SYMBOL_EXT_FILE_EXCEL "\xEF\x87\x83" /*61891, f1c3*/ +#define LV_SYMBOL_EXT_FILE_EXPORT "\xEF\x95\xAE" /*62830, f56e*/ +#define LV_SYMBOL_EXT_FILE_IMAGE "\xEF\x87\x85" /*61893, f1c5*/ +#define LV_SYMBOL_EXT_FILE_IMPORT "\xEF\x95\xAF" /*62831, f56f*/ +#define LV_SYMBOL_EXT_FILE_INVOICE "\xEF\x95\xB0" /*62832, f570*/ +#define LV_SYMBOL_EXT_FILE_INVOICE_DOLLAR "\xEF\x95\xB1" /*62833, f571*/ +#define LV_SYMBOL_EXT_FILE_LINES "\xEF\x85\x9C" /*61788, f15c*/ +#define LV_SYMBOL_EXT_FILE_MEDICAL "\xEF\x91\xB7" /*62583, f477*/ +#define LV_SYMBOL_EXT_FILE_PDF "\xEF\x87\x81" /*61889, f1c1*/ +#define LV_SYMBOL_EXT_FILE_PEN "\xEF\x8C\x9C" /*62236, f31c*/ +#define LV_SYMBOL_EXT_FILE_POWERPOINT "\xEF\x87\x84" /*61892, f1c4*/ +#define LV_SYMBOL_EXT_FILE_PRESCRIPTION "\xEF\x95\xB2" /*62834, f572*/ +#define LV_SYMBOL_EXT_FILE_SHIELD "\xEE\x93\xB0" /*58608, e4f0*/ +#define LV_SYMBOL_EXT_FILE_SIGNATURE "\xEF\x95\xB3" /*62835, f573*/ +#define LV_SYMBOL_EXT_FILE_VIDEO "\xEF\x87\x88" /*61896, f1c8*/ +#define LV_SYMBOL_EXT_FILE_WAVEFORM "\xEF\x91\xB8" /*62584, f478*/ +#define LV_SYMBOL_EXT_FILE_WORD "\xEF\x87\x82" /*61890, f1c2*/ +#define LV_SYMBOL_EXT_FILE_ZIPPER "\xEF\x87\x86" /*61894, f1c6*/ +#define LV_SYMBOL_EXT_FILL "\xEF\x95\xB5" /*62837, f575*/ +#define LV_SYMBOL_EXT_FILL_DRIP "\xEF\x95\xB6" /*62838, f576*/ +#define LV_SYMBOL_EXT_FILM "\xEF\x80\x88" /*61448, f008*/ +#define LV_SYMBOL_EXT_FILTER "\xEF\x82\xB0" /*61616, f0b0*/ +#define LV_SYMBOL_EXT_FILTER_CIRCLE_DOLLAR "\xEF\x99\xA2" /*63074, f662*/ +#define LV_SYMBOL_EXT_FILTER_CIRCLE_XMARK "\xEE\x85\xBB" /*57723, e17b*/ +#define LV_SYMBOL_EXT_FINGERPRINT "\xEF\x95\xB7" /*62839, f577*/ +#define LV_SYMBOL_EXT_FIRE "\xEF\x81\xAD" /*61549, f06d*/ +#define LV_SYMBOL_EXT_FIRE_BURNER "\xEE\x93\xB1" /*58609, e4f1*/ +#define LV_SYMBOL_EXT_FIRE_EXTINGUISHER "\xEF\x84\xB4" /*61748, f134*/ +#define LV_SYMBOL_EXT_FIRE_FLAME_CURVED "\xEF\x9F\xA4" /*63460, f7e4*/ +#define LV_SYMBOL_EXT_FIRE_FLAME_SIMPLE "\xEF\x91\xAA" /*62570, f46a*/ +#define LV_SYMBOL_EXT_FIREFOX "\xEF\x89\xA9" /*62057, f269*/ +#define LV_SYMBOL_EXT_FIREFOX_BROWSER "\xEE\x80\x87" /*57351, e007*/ +#define LV_SYMBOL_EXT_FIRST_ORDER "\xEF\x8A\xB0" /*62128, f2b0*/ +#define LV_SYMBOL_EXT_FIRST_ORDER_ALT "\xEF\x94\x8A" /*62730, f50a*/ +#define LV_SYMBOL_EXT_FIRSTDRAFT "\xEF\x8E\xA1" /*62369, f3a1*/ +#define LV_SYMBOL_EXT_FISH "\xEF\x95\xB8" /*62840, f578*/ +#define LV_SYMBOL_EXT_FISH_FINS "\xEE\x93\xB2" /*58610, e4f2*/ +#define LV_SYMBOL_EXT_FLAG "\xEF\x80\xA4" /*61476, f024*/ +#define LV_SYMBOL_EXT_FLAG_CHECKERED "\xEF\x84\x9E" /*61726, f11e*/ +#define LV_SYMBOL_EXT_FLAG_USA "\xEF\x9D\x8D" /*63309, f74d*/ +#define LV_SYMBOL_EXT_FLASK "\xEF\x83\x83" /*61635, f0c3*/ +#define LV_SYMBOL_EXT_FLASK_VIAL "\xEE\x93\xB3" /*58611, e4f3*/ +#define LV_SYMBOL_EXT_FLICKR "\xEF\x85\xAE" /*61806, f16e*/ +#define LV_SYMBOL_EXT_FLIPBOARD "\xEF\x91\x8D" /*62541, f44d*/ +#define LV_SYMBOL_EXT_FLOPPY_DISK "\xEF\x83\x87" /*61639, f0c7*/ +#define LV_SYMBOL_EXT_FLORIN_SIGN "\xEE\x86\x84" /*57732, e184*/ +#define LV_SYMBOL_EXT_FLY "\xEF\x90\x97" /*62487, f417*/ +#define LV_SYMBOL_EXT_FOLDER "\xEF\x81\xBB" /*61563, f07b*/ +#define LV_SYMBOL_EXT_FOLDER_CLOSED "\xEE\x86\x85" /*57733, e185*/ +#define LV_SYMBOL_EXT_FOLDER_MINUS "\xEF\x99\x9D" /*63069, f65d*/ +#define LV_SYMBOL_EXT_FOLDER_OPEN "\xEF\x81\xBC" /*61564, f07c*/ +#define LV_SYMBOL_EXT_FOLDER_PLUS "\xEF\x99\x9E" /*63070, f65e*/ +#define LV_SYMBOL_EXT_FOLDER_TREE "\xEF\xA0\x82" /*63490, f802*/ +#define LV_SYMBOL_EXT_FONT "\xEF\x80\xB1" /*61489, f031*/ +#define LV_SYMBOL_EXT_FONT_AWESOME "\xEF\x8A\xB4" /*62132, f2b4*/ +#define LV_SYMBOL_EXT_FONTICONS "\xEF\x8A\x80" /*62080, f280*/ +#define LV_SYMBOL_EXT_FONTICONS_FI "\xEF\x8E\xA2" /*62370, f3a2*/ +#define LV_SYMBOL_EXT_FOOTBALL "\xEF\x91\x8E" /*62542, f44e*/ +#define LV_SYMBOL_EXT_FORT_AWESOME "\xEF\x8A\x86" /*62086, f286*/ +#define LV_SYMBOL_EXT_FORT_AWESOME_ALT "\xEF\x8E\xA3" /*62371, f3a3*/ +#define LV_SYMBOL_EXT_FORUMBEE "\xEF\x88\x91" /*61969, f211*/ +#define LV_SYMBOL_EXT_FORWARD "\xEF\x81\x8E" /*61518, f04e*/ +#define LV_SYMBOL_EXT_FORWARD_FAST "\xEF\x81\x90" /*61520, f050*/ +#define LV_SYMBOL_EXT_FORWARD_STEP "\xEF\x81\x91" /*61521, f051*/ +#define LV_SYMBOL_EXT_FOURSQUARE "\xEF\x86\x80" /*61824, f180*/ +#define LV_SYMBOL_EXT_FRANC_SIGN "\xEE\x86\x8F" /*57743, e18f*/ +#define LV_SYMBOL_EXT_FREE_CODE_CAMP "\xEF\x8B\x85" /*62149, f2c5*/ +#define LV_SYMBOL_EXT_FREEBSD "\xEF\x8E\xA4" /*62372, f3a4*/ +#define LV_SYMBOL_EXT_FROG "\xEF\x94\xAE" /*62766, f52e*/ +#define LV_SYMBOL_EXT_FULCRUM "\xEF\x94\x8B" /*62731, f50b*/ +#define LV_SYMBOL_EXT_FUTBOL "\xEF\x87\xA3" /*61923, f1e3*/ +#define LV_SYMBOL_EXT_G "\x47" /*71, 47*/ +#define LV_SYMBOL_EXT_GALACTIC_REPUBLIC "\xEF\x94\x8C" /*62732, f50c*/ +#define LV_SYMBOL_EXT_GALACTIC_SENATE "\xEF\x94\x8D" /*62733, f50d*/ +#define LV_SYMBOL_EXT_GAMEPAD "\xEF\x84\x9B" /*61723, f11b*/ +#define LV_SYMBOL_EXT_GAS_PUMP "\xEF\x94\xAF" /*62767, f52f*/ +#define LV_SYMBOL_EXT_GAUGE "\xEF\x98\xA4" /*63012, f624*/ +#define LV_SYMBOL_EXT_GAUGE_HIGH "\xEF\x98\xA5" /*63013, f625*/ +#define LV_SYMBOL_EXT_GAUGE_SIMPLE "\xEF\x98\xA9" /*63017, f629*/ +#define LV_SYMBOL_EXT_GAUGE_SIMPLE_HIGH "\xEF\x98\xAA" /*63018, f62a*/ +#define LV_SYMBOL_EXT_GAVEL "\xEF\x83\xA3" /*61667, f0e3*/ +#define LV_SYMBOL_EXT_GEAR "\xEF\x80\x93" /*61459, f013*/ +#define LV_SYMBOL_EXT_GEARS "\xEF\x82\x85" /*61573, f085*/ +#define LV_SYMBOL_EXT_GEM "\xEF\x8E\xA5" /*62373, f3a5*/ +#define LV_SYMBOL_EXT_GENDERLESS "\xEF\x88\xAD" /*61997, f22d*/ +#define LV_SYMBOL_EXT_GET_POCKET "\xEF\x89\xA5" /*62053, f265*/ +#define LV_SYMBOL_EXT_GG "\xEF\x89\xA0" /*62048, f260*/ +#define LV_SYMBOL_EXT_GG_CIRCLE "\xEF\x89\xA1" /*62049, f261*/ +#define LV_SYMBOL_EXT_GHOST "\xEF\x9B\xA2" /*63202, f6e2*/ +#define LV_SYMBOL_EXT_GIFT "\xEF\x81\xAB" /*61547, f06b*/ +#define LV_SYMBOL_EXT_GIFTS "\xEF\x9E\x9C" /*63388, f79c*/ +#define LV_SYMBOL_EXT_GIT "\xEF\x87\x93" /*61907, f1d3*/ +#define LV_SYMBOL_EXT_GIT_ALT "\xEF\xA1\x81" /*63553, f841*/ +#define LV_SYMBOL_EXT_GITHUB "\xEF\x82\x9B" /*61595, f09b*/ +#define LV_SYMBOL_EXT_GITHUB_ALT "\xEF\x84\x93" /*61715, f113*/ +#define LV_SYMBOL_EXT_GITKRAKEN "\xEF\x8E\xA6" /*62374, f3a6*/ +#define LV_SYMBOL_EXT_GITLAB "\xEF\x8A\x96" /*62102, f296*/ +#define LV_SYMBOL_EXT_GITTER "\xEF\x90\xA6" /*62502, f426*/ +#define LV_SYMBOL_EXT_GLASS_WATER "\xEE\x93\xB4" /*58612, e4f4*/ +#define LV_SYMBOL_EXT_GLASS_WATER_DROPLET "\xEE\x93\xB5" /*58613, e4f5*/ +#define LV_SYMBOL_EXT_GLASSES "\xEF\x94\xB0" /*62768, f530*/ +#define LV_SYMBOL_EXT_GLIDE "\xEF\x8A\xA5" /*62117, f2a5*/ +#define LV_SYMBOL_EXT_GLIDE_G "\xEF\x8A\xA6" /*62118, f2a6*/ +#define LV_SYMBOL_EXT_GLOBE "\xEF\x82\xAC" /*61612, f0ac*/ +#define LV_SYMBOL_EXT_GOFORE "\xEF\x8E\xA7" /*62375, f3a7*/ +#define LV_SYMBOL_EXT_GOLANG "\xEE\x90\x8F" /*58383, e40f*/ +#define LV_SYMBOL_EXT_GOLF_BALL_TEE "\xEF\x91\x90" /*62544, f450*/ +#define LV_SYMBOL_EXT_GOODREADS "\xEF\x8E\xA8" /*62376, f3a8*/ +#define LV_SYMBOL_EXT_GOODREADS_G "\xEF\x8E\xA9" /*62377, f3a9*/ +#define LV_SYMBOL_EXT_GOOGLE "\xEF\x86\xA0" /*61856, f1a0*/ +#define LV_SYMBOL_EXT_GOOGLE_DRIVE "\xEF\x8E\xAA" /*62378, f3aa*/ +#define LV_SYMBOL_EXT_GOOGLE_PAY "\xEE\x81\xB9" /*57465, e079*/ +#define LV_SYMBOL_EXT_GOOGLE_PLAY "\xEF\x8E\xAB" /*62379, f3ab*/ +#define LV_SYMBOL_EXT_GOOGLE_PLUS "\xEF\x8A\xB3" /*62131, f2b3*/ +#define LV_SYMBOL_EXT_GOOGLE_PLUS_G "\xEF\x83\x95" /*61653, f0d5*/ +#define LV_SYMBOL_EXT_GOOGLE_SCHOLAR "\xEE\x98\xBB" /*58939, e63b*/ +#define LV_SYMBOL_EXT_GOOGLE_WALLET "\xEF\x87\xAE" /*61934, f1ee*/ +#define LV_SYMBOL_EXT_GOPURAM "\xEF\x99\xA4" /*63076, f664*/ +#define LV_SYMBOL_EXT_GRADUATION_CAP "\xEF\x86\x9D" /*61853, f19d*/ +#define LV_SYMBOL_EXT_GRATIPAY "\xEF\x86\x84" /*61828, f184*/ +#define LV_SYMBOL_EXT_GRAV "\xEF\x8B\x96" /*62166, f2d6*/ +#define LV_SYMBOL_EXT_GREATER_THAN "\x3E" /*62, 3e*/ +#define LV_SYMBOL_EXT_GREATER_THAN_EQUAL "\xEF\x94\xB2" /*62770, f532*/ +#define LV_SYMBOL_EXT_GRIP "\xEF\x96\x8D" /*62861, f58d*/ +#define LV_SYMBOL_EXT_GRIP_LINES "\xEF\x9E\xA4" /*63396, f7a4*/ +#define LV_SYMBOL_EXT_GRIP_LINES_VERTICAL "\xEF\x9E\xA5" /*63397, f7a5*/ +#define LV_SYMBOL_EXT_GRIP_VERTICAL "\xEF\x96\x8E" /*62862, f58e*/ +#define LV_SYMBOL_EXT_GRIPFIRE "\xEF\x8E\xAC" /*62380, f3ac*/ +#define LV_SYMBOL_EXT_GROUP_ARROWS_ROTATE "\xEE\x93\xB6" /*58614, e4f6*/ +#define LV_SYMBOL_EXT_GRUNT "\xEF\x8E\xAD" /*62381, f3ad*/ +#define LV_SYMBOL_EXT_GUARANI_SIGN "\xEE\x86\x9A" /*57754, e19a*/ +#define LV_SYMBOL_EXT_GUILDED "\xEE\x81\xBE" /*57470, e07e*/ +#define LV_SYMBOL_EXT_GUITAR "\xEF\x9E\xA6" /*63398, f7a6*/ +#define LV_SYMBOL_EXT_GULP "\xEF\x8E\xAE" /*62382, f3ae*/ +#define LV_SYMBOL_EXT_GUN "\xEE\x86\x9B" /*57755, e19b*/ +#define LV_SYMBOL_EXT_H "\x48" /*72, 48*/ +#define LV_SYMBOL_EXT_HACKER_NEWS "\xEF\x87\x94" /*61908, f1d4*/ +#define LV_SYMBOL_EXT_HACKERRANK "\xEF\x97\xB7" /*62967, f5f7*/ +#define LV_SYMBOL_EXT_HAMMER "\xEF\x9B\xA3" /*63203, f6e3*/ +#define LV_SYMBOL_EXT_HAMSA "\xEF\x99\xA5" /*63077, f665*/ +#define LV_SYMBOL_EXT_HAND "\xEF\x89\x96" /*62038, f256*/ +#define LV_SYMBOL_EXT_HAND_BACK_FIST "\xEF\x89\x95" /*62037, f255*/ +#define LV_SYMBOL_EXT_HAND_DOTS "\xEF\x91\xA1" /*62561, f461*/ +#define LV_SYMBOL_EXT_HAND_FIST "\xEF\x9B\x9E" /*63198, f6de*/ +#define LV_SYMBOL_EXT_HAND_HOLDING "\xEF\x92\xBD" /*62653, f4bd*/ +#define LV_SYMBOL_EXT_HAND_HOLDING_DOLLAR "\xEF\x93\x80" /*62656, f4c0*/ +#define LV_SYMBOL_EXT_HAND_HOLDING_DROPLET "\xEF\x93\x81" /*62657, f4c1*/ +#define LV_SYMBOL_EXT_HAND_HOLDING_HAND "\xEE\x93\xB7" /*58615, e4f7*/ +#define LV_SYMBOL_EXT_HAND_HOLDING_HEART "\xEF\x92\xBE" /*62654, f4be*/ +#define LV_SYMBOL_EXT_HAND_HOLDING_MEDICAL "\xEE\x81\x9C" /*57436, e05c*/ +#define LV_SYMBOL_EXT_HAND_LIZARD "\xEF\x89\x98" /*62040, f258*/ +#define LV_SYMBOL_EXT_HAND_MIDDLE_FINGER "\xEF\xA0\x86" /*63494, f806*/ +#define LV_SYMBOL_EXT_HAND_PEACE "\xEF\x89\x9B" /*62043, f25b*/ +#define LV_SYMBOL_EXT_HAND_POINT_DOWN "\xEF\x82\xA7" /*61607, f0a7*/ +#define LV_SYMBOL_EXT_HAND_POINT_LEFT "\xEF\x82\xA5" /*61605, f0a5*/ +#define LV_SYMBOL_EXT_HAND_POINT_RIGHT "\xEF\x82\xA4" /*61604, f0a4*/ +#define LV_SYMBOL_EXT_HAND_POINT_UP "\xEF\x82\xA6" /*61606, f0a6*/ +#define LV_SYMBOL_EXT_HAND_POINTER "\xEF\x89\x9A" /*62042, f25a*/ +#define LV_SYMBOL_EXT_HAND_SCISSORS "\xEF\x89\x97" /*62039, f257*/ +#define LV_SYMBOL_EXT_HAND_SPARKLES "\xEE\x81\x9D" /*57437, e05d*/ +#define LV_SYMBOL_EXT_HAND_SPOCK "\xEF\x89\x99" /*62041, f259*/ +#define LV_SYMBOL_EXT_HANDCUFFS "\xEE\x93\xB8" /*58616, e4f8*/ +#define LV_SYMBOL_EXT_HANDS "\xEF\x8A\xA7" /*62119, f2a7*/ +#define LV_SYMBOL_EXT_HANDS_ASL_INTERPRETING "\xEF\x8A\xA3" /*62115, f2a3*/ +#define LV_SYMBOL_EXT_HANDS_BOUND "\xEE\x93\xB9" /*58617, e4f9*/ +#define LV_SYMBOL_EXT_HANDS_BUBBLES "\xEE\x81\x9E" /*57438, e05e*/ +#define LV_SYMBOL_EXT_HANDS_CLAPPING "\xEE\x86\xA8" /*57768, e1a8*/ +#define LV_SYMBOL_EXT_HANDS_HOLDING "\xEF\x93\x82" /*62658, f4c2*/ +#define LV_SYMBOL_EXT_HANDS_HOLDING_CHILD "\xEE\x93\xBA" /*58618, e4fa*/ +#define LV_SYMBOL_EXT_HANDS_HOLDING_CIRCLE "\xEE\x93\xBB" /*58619, e4fb*/ +#define LV_SYMBOL_EXT_HANDS_PRAYING "\xEF\x9A\x84" /*63108, f684*/ +#define LV_SYMBOL_EXT_HANDSHAKE "\xEF\x8A\xB5" /*62133, f2b5*/ +#define LV_SYMBOL_EXT_HANDSHAKE_ANGLE "\xEF\x93\x84" /*62660, f4c4*/ +#define LV_SYMBOL_EXT_HANDSHAKE_SIMPLE "\xEF\x93\x86" /*62662, f4c6*/ +#define LV_SYMBOL_EXT_HANDSHAKE_SIMPLE_SLASH "\xEE\x81\x9F" /*57439, e05f*/ +#define LV_SYMBOL_EXT_HANDSHAKE_SLASH "\xEE\x81\xA0" /*57440, e060*/ +#define LV_SYMBOL_EXT_HANUKIAH "\xEF\x9B\xA6" /*63206, f6e6*/ +#define LV_SYMBOL_EXT_HARD_DRIVE "\xEF\x82\xA0" /*61600, f0a0*/ +#define LV_SYMBOL_EXT_HASHNODE "\xEE\x92\x99" /*58521, e499*/ +#define LV_SYMBOL_EXT_HASHTAG "\x23" /*35, 23*/ +#define LV_SYMBOL_EXT_HAT_COWBOY "\xEF\xA3\x80" /*63680, f8c0*/ +#define LV_SYMBOL_EXT_HAT_COWBOY_SIDE "\xEF\xA3\x81" /*63681, f8c1*/ +#define LV_SYMBOL_EXT_HAT_WIZARD "\xEF\x9B\xA8" /*63208, f6e8*/ +#define LV_SYMBOL_EXT_HEAD_SIDE_COUGH "\xEE\x81\xA1" /*57441, e061*/ +#define LV_SYMBOL_EXT_HEAD_SIDE_COUGH_SLASH "\xEE\x81\xA2" /*57442, e062*/ +#define LV_SYMBOL_EXT_HEAD_SIDE_MASK "\xEE\x81\xA3" /*57443, e063*/ +#define LV_SYMBOL_EXT_HEAD_SIDE_VIRUS "\xEE\x81\xA4" /*57444, e064*/ +#define LV_SYMBOL_EXT_HEADING "\xEF\x87\x9C" /*61916, f1dc*/ +#define LV_SYMBOL_EXT_HEADPHONES "\xEF\x80\xA5" /*61477, f025*/ +#define LV_SYMBOL_EXT_HEADPHONES_SIMPLE "\xEF\x96\x8F" /*62863, f58f*/ +#define LV_SYMBOL_EXT_HEADSET "\xEF\x96\x90" /*62864, f590*/ +#define LV_SYMBOL_EXT_HEART "\xEF\x80\x84" /*61444, f004*/ +#define LV_SYMBOL_EXT_HEART_CIRCLE_BOLT "\xEE\x93\xBC" /*58620, e4fc*/ +#define LV_SYMBOL_EXT_HEART_CIRCLE_CHECK "\xEE\x93\xBD" /*58621, e4fd*/ +#define LV_SYMBOL_EXT_HEART_CIRCLE_EXCLAMATION "\xEE\x93\xBE" /*58622, e4fe*/ +#define LV_SYMBOL_EXT_HEART_CIRCLE_MINUS "\xEE\x93\xBF" /*58623, e4ff*/ +#define LV_SYMBOL_EXT_HEART_CIRCLE_PLUS "\xEE\x94\x80" /*58624, e500*/ +#define LV_SYMBOL_EXT_HEART_CIRCLE_XMARK "\xEE\x94\x81" /*58625, e501*/ +#define LV_SYMBOL_EXT_HEART_CRACK "\xEF\x9E\xA9" /*63401, f7a9*/ +#define LV_SYMBOL_EXT_HEART_PULSE "\xEF\x88\x9E" /*61982, f21e*/ +#define LV_SYMBOL_EXT_HELICOPTER "\xEF\x94\xB3" /*62771, f533*/ +#define LV_SYMBOL_EXT_HELICOPTER_SYMBOL "\xEE\x94\x82" /*58626, e502*/ +#define LV_SYMBOL_EXT_HELMET_SAFETY "\xEF\xA0\x87" /*63495, f807*/ +#define LV_SYMBOL_EXT_HELMET_UN "\xEE\x94\x83" /*58627, e503*/ +#define LV_SYMBOL_EXT_HIGHLIGHTER "\xEF\x96\x91" /*62865, f591*/ +#define LV_SYMBOL_EXT_HILL_AVALANCHE "\xEE\x94\x87" /*58631, e507*/ +#define LV_SYMBOL_EXT_HILL_ROCKSLIDE "\xEE\x94\x88" /*58632, e508*/ +#define LV_SYMBOL_EXT_HIPPO "\xEF\x9B\xAD" /*63213, f6ed*/ +#define LV_SYMBOL_EXT_HIPS "\xEF\x91\x92" /*62546, f452*/ +#define LV_SYMBOL_EXT_HIRE_A_HELPER "\xEF\x8E\xB0" /*62384, f3b0*/ +#define LV_SYMBOL_EXT_HIVE "\xEE\x81\xBF" /*57471, e07f*/ +#define LV_SYMBOL_EXT_HOCKEY_PUCK "\xEF\x91\x93" /*62547, f453*/ +#define LV_SYMBOL_EXT_HOLLY_BERRY "\xEF\x9E\xAA" /*63402, f7aa*/ +#define LV_SYMBOL_EXT_HOOLI "\xEF\x90\xA7" /*62503, f427*/ +#define LV_SYMBOL_EXT_HORNBILL "\xEF\x96\x92" /*62866, f592*/ +#define LV_SYMBOL_EXT_HORSE "\xEF\x9B\xB0" /*63216, f6f0*/ +#define LV_SYMBOL_EXT_HORSE_HEAD "\xEF\x9E\xAB" /*63403, f7ab*/ +#define LV_SYMBOL_EXT_HOSPITAL "\xEF\x83\xB8" /*61688, f0f8*/ +#define LV_SYMBOL_EXT_HOSPITAL_USER "\xEF\xA0\x8D" /*63501, f80d*/ +#define LV_SYMBOL_EXT_HOT_TUB_PERSON "\xEF\x96\x93" /*62867, f593*/ +#define LV_SYMBOL_EXT_HOTDOG "\xEF\xA0\x8F" /*63503, f80f*/ +#define LV_SYMBOL_EXT_HOTEL "\xEF\x96\x94" /*62868, f594*/ +#define LV_SYMBOL_EXT_HOTJAR "\xEF\x8E\xB1" /*62385, f3b1*/ +#define LV_SYMBOL_EXT_HOURGLASS "\xEF\x89\x94" /*62036, f254*/ +#define LV_SYMBOL_EXT_HOURGLASS_END "\xEF\x89\x93" /*62035, f253*/ +#define LV_SYMBOL_EXT_HOURGLASS_HALF "\xEF\x89\x92" /*62034, f252*/ +#define LV_SYMBOL_EXT_HOURGLASS_START "\xEF\x89\x91" /*62033, f251*/ +#define LV_SYMBOL_EXT_HOUSE "\xEF\x80\x95" /*61461, f015*/ +#define LV_SYMBOL_EXT_HOUSE_CHIMNEY "\xEE\x8E\xAF" /*58287, e3af*/ +#define LV_SYMBOL_EXT_HOUSE_CHIMNEY_CRACK "\xEF\x9B\xB1" /*63217, f6f1*/ +#define LV_SYMBOL_EXT_HOUSE_CHIMNEY_MEDICAL "\xEF\x9F\xB2" /*63474, f7f2*/ +#define LV_SYMBOL_EXT_HOUSE_CHIMNEY_USER "\xEE\x81\xA5" /*57445, e065*/ +#define LV_SYMBOL_EXT_HOUSE_CHIMNEY_WINDOW "\xEE\x80\x8D" /*57357, e00d*/ +#define LV_SYMBOL_EXT_HOUSE_CIRCLE_CHECK "\xEE\x94\x89" /*58633, e509*/ +#define LV_SYMBOL_EXT_HOUSE_CIRCLE_EXCLAMATION "\xEE\x94\x8A" /*58634, e50a*/ +#define LV_SYMBOL_EXT_HOUSE_CIRCLE_XMARK "\xEE\x94\x8B" /*58635, e50b*/ +#define LV_SYMBOL_EXT_HOUSE_CRACK "\xEE\x8E\xB1" /*58289, e3b1*/ +#define LV_SYMBOL_EXT_HOUSE_FIRE "\xEE\x94\x8C" /*58636, e50c*/ +#define LV_SYMBOL_EXT_HOUSE_FLAG "\xEE\x94\x8D" /*58637, e50d*/ +#define LV_SYMBOL_EXT_HOUSE_FLOOD_WATER "\xEE\x94\x8E" /*58638, e50e*/ +#define LV_SYMBOL_EXT_HOUSE_FLOOD_WATER_CIRCLE_ARROW_RIGHT "\xEE\x94\x8F" /*58639, e50f*/ +#define LV_SYMBOL_EXT_HOUSE_LAPTOP "\xEE\x81\xA6" /*57446, e066*/ +#define LV_SYMBOL_EXT_HOUSE_LOCK "\xEE\x94\x90" /*58640, e510*/ +#define LV_SYMBOL_EXT_HOUSE_MEDICAL "\xEE\x8E\xB2" /*58290, e3b2*/ +#define LV_SYMBOL_EXT_HOUSE_MEDICAL_CIRCLE_CHECK "\xEE\x94\x91" /*58641, e511*/ +#define LV_SYMBOL_EXT_HOUSE_MEDICAL_CIRCLE_EXCLAMATION "\xEE\x94\x92" /*58642, e512*/ +#define LV_SYMBOL_EXT_HOUSE_MEDICAL_CIRCLE_XMARK "\xEE\x94\x93" /*58643, e513*/ +#define LV_SYMBOL_EXT_HOUSE_MEDICAL_FLAG "\xEE\x94\x94" /*58644, e514*/ +#define LV_SYMBOL_EXT_HOUSE_SIGNAL "\xEE\x80\x92" /*57362, e012*/ +#define LV_SYMBOL_EXT_HOUSE_TSUNAMI "\xEE\x94\x95" /*58645, e515*/ +#define LV_SYMBOL_EXT_HOUSE_USER "\xEE\x86\xB0" /*57776, e1b0*/ +#define LV_SYMBOL_EXT_HOUZZ "\xEF\x89\xBC" /*62076, f27c*/ +#define LV_SYMBOL_EXT_HRYVNIA_SIGN "\xEF\x9B\xB2" /*63218, f6f2*/ +#define LV_SYMBOL_EXT_HTML5 "\xEF\x84\xBB" /*61755, f13b*/ +#define LV_SYMBOL_EXT_HUBSPOT "\xEF\x8E\xB2" /*62386, f3b2*/ +#define LV_SYMBOL_EXT_HURRICANE "\xEF\x9D\x91" /*63313, f751*/ +#define LV_SYMBOL_EXT_I "\x49" /*73, 49*/ +#define LV_SYMBOL_EXT_I_CURSOR "\xEF\x89\x86" /*62022, f246*/ +#define LV_SYMBOL_EXT_ICE_CREAM "\xEF\xA0\x90" /*63504, f810*/ +#define LV_SYMBOL_EXT_ICICLES "\xEF\x9E\xAD" /*63405, f7ad*/ +#define LV_SYMBOL_EXT_ICONS "\xEF\xA1\xAD" /*63597, f86d*/ +#define LV_SYMBOL_EXT_ID_BADGE "\xEF\x8B\x81" /*62145, f2c1*/ +#define LV_SYMBOL_EXT_ID_CARD "\xEF\x8B\x82" /*62146, f2c2*/ +#define LV_SYMBOL_EXT_ID_CARD_CLIP "\xEF\x91\xBF" /*62591, f47f*/ +#define LV_SYMBOL_EXT_IDEAL "\xEE\x80\x93" /*57363, e013*/ +#define LV_SYMBOL_EXT_IGLOO "\xEF\x9E\xAE" /*63406, f7ae*/ +#define LV_SYMBOL_EXT_IMAGE "\xEF\x80\xBE" /*61502, f03e*/ +#define LV_SYMBOL_EXT_IMAGE_PORTRAIT "\xEF\x8F\xA0" /*62432, f3e0*/ +#define LV_SYMBOL_EXT_IMAGES "\xEF\x8C\x82" /*62210, f302*/ +#define LV_SYMBOL_EXT_IMDB "\xEF\x8B\x98" /*62168, f2d8*/ +#define LV_SYMBOL_EXT_INBOX "\xEF\x80\x9C" /*61468, f01c*/ +#define LV_SYMBOL_EXT_INDENT "\xEF\x80\xBC" /*61500, f03c*/ +#define LV_SYMBOL_EXT_INDIAN_RUPEE_SIGN "\xEE\x86\xBC" /*57788, e1bc*/ +#define LV_SYMBOL_EXT_INDUSTRY "\xEF\x89\xB5" /*62069, f275*/ +#define LV_SYMBOL_EXT_INFINITY "\xEF\x94\xB4" /*62772, f534*/ +#define LV_SYMBOL_EXT_INFO "\xEF\x84\xA9" /*61737, f129*/ +#define LV_SYMBOL_EXT_INSTAGRAM "\xEF\x85\xAD" /*61805, f16d*/ +#define LV_SYMBOL_EXT_INSTALOD "\xEE\x82\x81" /*57473, e081*/ +#define LV_SYMBOL_EXT_INTERCOM "\xEF\x9E\xAF" /*63407, f7af*/ +#define LV_SYMBOL_EXT_INTERNET_EXPLORER "\xEF\x89\xAB" /*62059, f26b*/ +#define LV_SYMBOL_EXT_INVISION "\xEF\x9E\xB0" /*63408, f7b0*/ +#define LV_SYMBOL_EXT_IOXHOST "\xEF\x88\x88" /*61960, f208*/ +#define LV_SYMBOL_EXT_ITALIC "\xEF\x80\xB3" /*61491, f033*/ +#define LV_SYMBOL_EXT_ITCH_IO "\xEF\xA0\xBA" /*63546, f83a*/ +#define LV_SYMBOL_EXT_ITUNES "\xEF\x8E\xB4" /*62388, f3b4*/ +#define LV_SYMBOL_EXT_ITUNES_NOTE "\xEF\x8E\xB5" /*62389, f3b5*/ +#define LV_SYMBOL_EXT_J "\x4A" /*74, 4a*/ +#define LV_SYMBOL_EXT_JAR "\xEE\x94\x96" /*58646, e516*/ +#define LV_SYMBOL_EXT_JAR_WHEAT "\xEE\x94\x97" /*58647, e517*/ +#define LV_SYMBOL_EXT_JAVA "\xEF\x93\xA4" /*62692, f4e4*/ +#define LV_SYMBOL_EXT_JEDI "\xEF\x99\xA9" /*63081, f669*/ +#define LV_SYMBOL_EXT_JEDI_ORDER "\xEF\x94\x8E" /*62734, f50e*/ +#define LV_SYMBOL_EXT_JENKINS "\xEF\x8E\xB6" /*62390, f3b6*/ +#define LV_SYMBOL_EXT_JET_FIGHTER "\xEF\x83\xBB" /*61691, f0fb*/ +#define LV_SYMBOL_EXT_JET_FIGHTER_UP "\xEE\x94\x98" /*58648, e518*/ +#define LV_SYMBOL_EXT_JIRA "\xEF\x9E\xB1" /*63409, f7b1*/ +#define LV_SYMBOL_EXT_JOGET "\xEF\x8E\xB7" /*62391, f3b7*/ +#define LV_SYMBOL_EXT_JOINT "\xEF\x96\x95" /*62869, f595*/ +#define LV_SYMBOL_EXT_JOOMLA "\xEF\x86\xAA" /*61866, f1aa*/ +#define LV_SYMBOL_EXT_JS "\xEF\x8E\xB8" /*62392, f3b8*/ +#define LV_SYMBOL_EXT_JSFIDDLE "\xEF\x87\x8C" /*61900, f1cc*/ +#define LV_SYMBOL_EXT_JUG_DETERGENT "\xEE\x94\x99" /*58649, e519*/ +#define LV_SYMBOL_EXT_K "\x4B" /*75, 4b*/ +#define LV_SYMBOL_EXT_KAABA "\xEF\x99\xAB" /*63083, f66b*/ +#define LV_SYMBOL_EXT_KAGGLE "\xEF\x97\xBA" /*62970, f5fa*/ +#define LV_SYMBOL_EXT_KEY "\xEF\x82\x84" /*61572, f084*/ +#define LV_SYMBOL_EXT_KEYBASE "\xEF\x93\xB5" /*62709, f4f5*/ +#define LV_SYMBOL_EXT_KEYBOARD "\xEF\x84\x9C" /*61724, f11c*/ +#define LV_SYMBOL_EXT_KEYCDN "\xEF\x8E\xBA" /*62394, f3ba*/ +#define LV_SYMBOL_EXT_KHANDA "\xEF\x99\xAD" /*63085, f66d*/ +#define LV_SYMBOL_EXT_KICKSTARTER "\xEF\x8E\xBB" /*62395, f3bb*/ +#define LV_SYMBOL_EXT_KICKSTARTER_K "\xEF\x8E\xBC" /*62396, f3bc*/ +#define LV_SYMBOL_EXT_KIP_SIGN "\xEE\x87\x84" /*57796, e1c4*/ +#define LV_SYMBOL_EXT_KIT_MEDICAL "\xEF\x91\xB9" /*62585, f479*/ +#define LV_SYMBOL_EXT_KITCHEN_SET "\xEE\x94\x9A" /*58650, e51a*/ +#define LV_SYMBOL_EXT_KIWI_BIRD "\xEF\x94\xB5" /*62773, f535*/ +#define LV_SYMBOL_EXT_KORVUE "\xEF\x90\xAF" /*62511, f42f*/ +#define LV_SYMBOL_EXT_L "\x4C" /*76, 4c*/ +#define LV_SYMBOL_EXT_LAND_MINE_ON "\xEE\x94\x9B" /*58651, e51b*/ +#define LV_SYMBOL_EXT_LANDMARK "\xEF\x99\xAF" /*63087, f66f*/ +#define LV_SYMBOL_EXT_LANDMARK_DOME "\xEF\x9D\x92" /*63314, f752*/ +#define LV_SYMBOL_EXT_LANDMARK_FLAG "\xEE\x94\x9C" /*58652, e51c*/ +#define LV_SYMBOL_EXT_LANGUAGE "\xEF\x86\xAB" /*61867, f1ab*/ +#define LV_SYMBOL_EXT_LAPTOP "\xEF\x84\x89" /*61705, f109*/ +#define LV_SYMBOL_EXT_LAPTOP_CODE "\xEF\x97\xBC" /*62972, f5fc*/ +#define LV_SYMBOL_EXT_LAPTOP_FILE "\xEE\x94\x9D" /*58653, e51d*/ +#define LV_SYMBOL_EXT_LAPTOP_MEDICAL "\xEF\xA0\x92" /*63506, f812*/ +#define LV_SYMBOL_EXT_LARAVEL "\xEF\x8E\xBD" /*62397, f3bd*/ +#define LV_SYMBOL_EXT_LARI_SIGN "\xEE\x87\x88" /*57800, e1c8*/ +#define LV_SYMBOL_EXT_LASTFM "\xEF\x88\x82" /*61954, f202*/ +#define LV_SYMBOL_EXT_LAYER_GROUP "\xEF\x97\xBD" /*62973, f5fd*/ +#define LV_SYMBOL_EXT_LEAF "\xEF\x81\xAC" /*61548, f06c*/ +#define LV_SYMBOL_EXT_LEANPUB "\xEF\x88\x92" /*61970, f212*/ +#define LV_SYMBOL_EXT_LEFT_LONG "\xEF\x8C\x8A" /*62218, f30a*/ +#define LV_SYMBOL_EXT_LEFT_RIGHT "\xEF\x8C\xB7" /*62263, f337*/ +#define LV_SYMBOL_EXT_LEMON "\xEF\x82\x94" /*61588, f094*/ +#define LV_SYMBOL_EXT_LESS "\xEF\x90\x9D" /*62493, f41d*/ +#define LV_SYMBOL_EXT_LESS_THAN "\x3C" /*60, 3c*/ +#define LV_SYMBOL_EXT_LESS_THAN_EQUAL "\xEF\x94\xB7" /*62775, f537*/ +#define LV_SYMBOL_EXT_LETTERBOXD "\xEE\x98\xAD" /*58925, e62d*/ +#define LV_SYMBOL_EXT_LIFE_RING "\xEF\x87\x8D" /*61901, f1cd*/ +#define LV_SYMBOL_EXT_LIGHTBULB "\xEF\x83\xAB" /*61675, f0eb*/ +#define LV_SYMBOL_EXT_LINE "\xEF\x8F\x80" /*62400, f3c0*/ +#define LV_SYMBOL_EXT_LINES_LEANING "\xEE\x94\x9E" /*58654, e51e*/ +#define LV_SYMBOL_EXT_LINK "\xEF\x83\x81" /*61633, f0c1*/ +#define LV_SYMBOL_EXT_LINK_SLASH "\xEF\x84\xA7" /*61735, f127*/ +#define LV_SYMBOL_EXT_LINKEDIN "\xEF\x82\x8C" /*61580, f08c*/ +#define LV_SYMBOL_EXT_LINKEDIN_IN "\xEF\x83\xA1" /*61665, f0e1*/ +#define LV_SYMBOL_EXT_LINODE "\xEF\x8A\xB8" /*62136, f2b8*/ +#define LV_SYMBOL_EXT_LINUX "\xEF\x85\xBC" /*61820, f17c*/ +#define LV_SYMBOL_EXT_LIRA_SIGN "\xEF\x86\x95" /*61845, f195*/ +#define LV_SYMBOL_EXT_LIST "\xEF\x80\xBA" /*61498, f03a*/ +#define LV_SYMBOL_EXT_LIST_CHECK "\xEF\x82\xAE" /*61614, f0ae*/ +#define LV_SYMBOL_EXT_LIST_OL "\xEF\x83\x8B" /*61643, f0cb*/ +#define LV_SYMBOL_EXT_LIST_UL "\xEF\x83\x8A" /*61642, f0ca*/ +#define LV_SYMBOL_EXT_LITECOIN_SIGN "\xEE\x87\x93" /*57811, e1d3*/ +#define LV_SYMBOL_EXT_LOCATION_ARROW "\xEF\x84\xA4" /*61732, f124*/ +#define LV_SYMBOL_EXT_LOCATION_CROSSHAIRS "\xEF\x98\x81" /*62977, f601*/ +#define LV_SYMBOL_EXT_LOCATION_DOT "\xEF\x8F\x85" /*62405, f3c5*/ +#define LV_SYMBOL_EXT_LOCATION_PIN "\xEF\x81\x81" /*61505, f041*/ +#define LV_SYMBOL_EXT_LOCATION_PIN_LOCK "\xEE\x94\x9F" /*58655, e51f*/ +#define LV_SYMBOL_EXT_LOCK "\xEF\x80\xA3" /*61475, f023*/ +#define LV_SYMBOL_EXT_LOCK_OPEN "\xEF\x8F\x81" /*62401, f3c1*/ +#define LV_SYMBOL_EXT_LOCUST "\xEE\x94\xA0" /*58656, e520*/ +#define LV_SYMBOL_EXT_LUNGS "\xEF\x98\x84" /*62980, f604*/ +#define LV_SYMBOL_EXT_LUNGS_VIRUS "\xEE\x81\xA7" /*57447, e067*/ +#define LV_SYMBOL_EXT_LYFT "\xEF\x8F\x83" /*62403, f3c3*/ +#define LV_SYMBOL_EXT_M "\x4D" /*77, 4d*/ +#define LV_SYMBOL_EXT_MAGENTO "\xEF\x8F\x84" /*62404, f3c4*/ +#define LV_SYMBOL_EXT_MAGNET "\xEF\x81\xB6" /*61558, f076*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS "\xEF\x80\x82" /*61442, f002*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS_ARROW_RIGHT "\xEE\x94\xA1" /*58657, e521*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS_CHART "\xEE\x94\xA2" /*58658, e522*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS_DOLLAR "\xEF\x9A\x88" /*63112, f688*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS_LOCATION "\xEF\x9A\x89" /*63113, f689*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS_MINUS "\xEF\x80\x90" /*61456, f010*/ +#define LV_SYMBOL_EXT_MAGNIFYING_GLASS_PLUS "\xEF\x80\x8E" /*61454, f00e*/ +#define LV_SYMBOL_EXT_MAILCHIMP "\xEF\x96\x9E" /*62878, f59e*/ +#define LV_SYMBOL_EXT_MANAT_SIGN "\xEE\x87\x95" /*57813, e1d5*/ +#define LV_SYMBOL_EXT_MANDALORIAN "\xEF\x94\x8F" /*62735, f50f*/ +#define LV_SYMBOL_EXT_MAP "\xEF\x89\xB9" /*62073, f279*/ +#define LV_SYMBOL_EXT_MAP_LOCATION "\xEF\x96\x9F" /*62879, f59f*/ +#define LV_SYMBOL_EXT_MAP_LOCATION_DOT "\xEF\x96\xA0" /*62880, f5a0*/ +#define LV_SYMBOL_EXT_MAP_PIN "\xEF\x89\xB6" /*62070, f276*/ +#define LV_SYMBOL_EXT_MARKDOWN "\xEF\x98\x8F" /*62991, f60f*/ +#define LV_SYMBOL_EXT_MARKER "\xEF\x96\xA1" /*62881, f5a1*/ +#define LV_SYMBOL_EXT_MARS "\xEF\x88\xA2" /*61986, f222*/ +#define LV_SYMBOL_EXT_MARS_AND_VENUS "\xEF\x88\xA4" /*61988, f224*/ +#define LV_SYMBOL_EXT_MARS_AND_VENUS_BURST "\xEE\x94\xA3" /*58659, e523*/ +#define LV_SYMBOL_EXT_MARS_DOUBLE "\xEF\x88\xA7" /*61991, f227*/ +#define LV_SYMBOL_EXT_MARS_STROKE "\xEF\x88\xA9" /*61993, f229*/ +#define LV_SYMBOL_EXT_MARS_STROKE_RIGHT "\xEF\x88\xAB" /*61995, f22b*/ +#define LV_SYMBOL_EXT_MARS_STROKE_UP "\xEF\x88\xAA" /*61994, f22a*/ +#define LV_SYMBOL_EXT_MARTINI_GLASS "\xEF\x95\xBB" /*62843, f57b*/ +#define LV_SYMBOL_EXT_MARTINI_GLASS_CITRUS "\xEF\x95\xA1" /*62817, f561*/ +#define LV_SYMBOL_EXT_MARTINI_GLASS_EMPTY "\xEF\x80\x80" /*61440, f000*/ +#define LV_SYMBOL_EXT_MASK "\xEF\x9B\xBA" /*63226, f6fa*/ +#define LV_SYMBOL_EXT_MASK_FACE "\xEE\x87\x97" /*57815, e1d7*/ +#define LV_SYMBOL_EXT_MASK_VENTILATOR "\xEE\x94\xA4" /*58660, e524*/ +#define LV_SYMBOL_EXT_MASKS_THEATER "\xEF\x98\xB0" /*63024, f630*/ +#define LV_SYMBOL_EXT_MASTODON "\xEF\x93\xB6" /*62710, f4f6*/ +#define LV_SYMBOL_EXT_MATTRESS_PILLOW "\xEE\x94\xA5" /*58661, e525*/ +#define LV_SYMBOL_EXT_MAXCDN "\xEF\x84\xB6" /*61750, f136*/ +#define LV_SYMBOL_EXT_MAXIMIZE "\xEF\x8C\x9E" /*62238, f31e*/ +#define LV_SYMBOL_EXT_MDB "\xEF\xA3\x8A" /*63690, f8ca*/ +#define LV_SYMBOL_EXT_MEDAL "\xEF\x96\xA2" /*62882, f5a2*/ +#define LV_SYMBOL_EXT_MEDAPPS "\xEF\x8F\x86" /*62406, f3c6*/ +#define LV_SYMBOL_EXT_MEDIUM "\xEF\x88\xBA" /*62010, f23a*/ +#define LV_SYMBOL_EXT_MEDRT "\xEF\x8F\x88" /*62408, f3c8*/ +#define LV_SYMBOL_EXT_MEETUP "\xEF\x8B\xA0" /*62176, f2e0*/ +#define LV_SYMBOL_EXT_MEGAPORT "\xEF\x96\xA3" /*62883, f5a3*/ +#define LV_SYMBOL_EXT_MEMORY "\xEF\x94\xB8" /*62776, f538*/ +#define LV_SYMBOL_EXT_MENDELEY "\xEF\x9E\xB3" /*63411, f7b3*/ +#define LV_SYMBOL_EXT_MENORAH "\xEF\x99\xB6" /*63094, f676*/ +#define LV_SYMBOL_EXT_MERCURY "\xEF\x88\xA3" /*61987, f223*/ +#define LV_SYMBOL_EXT_MESSAGE "\xEF\x89\xBA" /*62074, f27a*/ +#define LV_SYMBOL_EXT_META "\xEE\x92\x9B" /*58523, e49b*/ +#define LV_SYMBOL_EXT_METEOR "\xEF\x9D\x93" /*63315, f753*/ +#define LV_SYMBOL_EXT_MICROBLOG "\xEE\x80\x9A" /*57370, e01a*/ +#define LV_SYMBOL_EXT_MICROCHIP "\xEF\x8B\x9B" /*62171, f2db*/ +#define LV_SYMBOL_EXT_MICROPHONE "\xEF\x84\xB0" /*61744, f130*/ +#define LV_SYMBOL_EXT_MICROPHONE_LINES "\xEF\x8F\x89" /*62409, f3c9*/ +#define LV_SYMBOL_EXT_MICROPHONE_LINES_SLASH "\xEF\x94\xB9" /*62777, f539*/ +#define LV_SYMBOL_EXT_MICROPHONE_SLASH "\xEF\x84\xB1" /*61745, f131*/ +#define LV_SYMBOL_EXT_MICROSCOPE "\xEF\x98\x90" /*62992, f610*/ +#define LV_SYMBOL_EXT_MICROSOFT "\xEF\x8F\x8A" /*62410, f3ca*/ +#define LV_SYMBOL_EXT_MILL_SIGN "\xEE\x87\xAD" /*57837, e1ed*/ +#define LV_SYMBOL_EXT_MINIMIZE "\xEF\x9E\x8C" /*63372, f78c*/ +#define LV_SYMBOL_EXT_MINTBIT "\xEE\x98\xAF" /*58927, e62f*/ +#define LV_SYMBOL_EXT_MINUS "\xEF\x81\xA8" /*61544, f068*/ +#define LV_SYMBOL_EXT_MITTEN "\xEF\x9E\xB5" /*63413, f7b5*/ +#define LV_SYMBOL_EXT_MIX "\xEF\x8F\x8B" /*62411, f3cb*/ +#define LV_SYMBOL_EXT_MIXCLOUD "\xEF\x8A\x89" /*62089, f289*/ +#define LV_SYMBOL_EXT_MIXER "\xEE\x81\x96" /*57430, e056*/ +#define LV_SYMBOL_EXT_MIZUNI "\xEF\x8F\x8C" /*62412, f3cc*/ +#define LV_SYMBOL_EXT_MOBILE "\xEF\x8F\x8E" /*62414, f3ce*/ +#define LV_SYMBOL_EXT_MOBILE_BUTTON "\xEF\x84\x8B" /*61707, f10b*/ +#define LV_SYMBOL_EXT_MOBILE_RETRO "\xEE\x94\xA7" /*58663, e527*/ +#define LV_SYMBOL_EXT_MOBILE_SCREEN "\xEF\x8F\x8F" /*62415, f3cf*/ +#define LV_SYMBOL_EXT_MOBILE_SCREEN_BUTTON "\xEF\x8F\x8D" /*62413, f3cd*/ +#define LV_SYMBOL_EXT_MODX "\xEF\x8A\x85" /*62085, f285*/ +#define LV_SYMBOL_EXT_MONERO "\xEF\x8F\x90" /*62416, f3d0*/ +#define LV_SYMBOL_EXT_MONEY_BILL "\xEF\x83\x96" /*61654, f0d6*/ +#define LV_SYMBOL_EXT_MONEY_BILL_1 "\xEF\x8F\x91" /*62417, f3d1*/ +#define LV_SYMBOL_EXT_MONEY_BILL_1_WAVE "\xEF\x94\xBB" /*62779, f53b*/ +#define LV_SYMBOL_EXT_MONEY_BILL_TRANSFER "\xEE\x94\xA8" /*58664, e528*/ +#define LV_SYMBOL_EXT_MONEY_BILL_TREND_UP "\xEE\x94\xA9" /*58665, e529*/ +#define LV_SYMBOL_EXT_MONEY_BILL_WAVE "\xEF\x94\xBA" /*62778, f53a*/ +#define LV_SYMBOL_EXT_MONEY_BILL_WHEAT "\xEE\x94\xAA" /*58666, e52a*/ +#define LV_SYMBOL_EXT_MONEY_BILLS "\xEE\x87\xB3" /*57843, e1f3*/ +#define LV_SYMBOL_EXT_MONEY_CHECK "\xEF\x94\xBC" /*62780, f53c*/ +#define LV_SYMBOL_EXT_MONEY_CHECK_DOLLAR "\xEF\x94\xBD" /*62781, f53d*/ +#define LV_SYMBOL_EXT_MONUMENT "\xEF\x96\xA6" /*62886, f5a6*/ +#define LV_SYMBOL_EXT_MOON "\xEF\x86\x86" /*61830, f186*/ +#define LV_SYMBOL_EXT_MORTAR_PESTLE "\xEF\x96\xA7" /*62887, f5a7*/ +#define LV_SYMBOL_EXT_MOSQUE "\xEF\x99\xB8" /*63096, f678*/ +#define LV_SYMBOL_EXT_MOSQUITO "\xEE\x94\xAB" /*58667, e52b*/ +#define LV_SYMBOL_EXT_MOSQUITO_NET "\xEE\x94\xAC" /*58668, e52c*/ +#define LV_SYMBOL_EXT_MOTORCYCLE "\xEF\x88\x9C" /*61980, f21c*/ +#define LV_SYMBOL_EXT_MOUND "\xEE\x94\xAD" /*58669, e52d*/ +#define LV_SYMBOL_EXT_MOUNTAIN "\xEF\x9B\xBC" /*63228, f6fc*/ +#define LV_SYMBOL_EXT_MOUNTAIN_CITY "\xEE\x94\xAE" /*58670, e52e*/ +#define LV_SYMBOL_EXT_MOUNTAIN_SUN "\xEE\x94\xAF" /*58671, e52f*/ +#define LV_SYMBOL_EXT_MUG_HOT "\xEF\x9E\xB6" /*63414, f7b6*/ +#define LV_SYMBOL_EXT_MUG_SAUCER "\xEF\x83\xB4" /*61684, f0f4*/ +#define LV_SYMBOL_EXT_MUSIC "\xEF\x80\x81" /*61441, f001*/ +#define LV_SYMBOL_EXT_N "\x4E" /*78, 4e*/ +#define LV_SYMBOL_EXT_NAIRA_SIGN "\xEE\x87\xB6" /*57846, e1f6*/ +#define LV_SYMBOL_EXT_NAPSTER "\xEF\x8F\x92" /*62418, f3d2*/ +#define LV_SYMBOL_EXT_NEOS "\xEF\x98\x92" /*62994, f612*/ +#define LV_SYMBOL_EXT_NETWORK_WIRED "\xEF\x9B\xBF" /*63231, f6ff*/ +#define LV_SYMBOL_EXT_NEUTER "\xEF\x88\xAC" /*61996, f22c*/ +#define LV_SYMBOL_EXT_NEWSPAPER "\xEF\x87\xAA" /*61930, f1ea*/ +#define LV_SYMBOL_EXT_NFC_DIRECTIONAL "\xEE\x94\xB0" /*58672, e530*/ +#define LV_SYMBOL_EXT_NFC_SYMBOL "\xEE\x94\xB1" /*58673, e531*/ +#define LV_SYMBOL_EXT_NIMBLR "\xEF\x96\xA8" /*62888, f5a8*/ +#define LV_SYMBOL_EXT_NODE "\xEF\x90\x99" /*62489, f419*/ +#define LV_SYMBOL_EXT_NODE_JS "\xEF\x8F\x93" /*62419, f3d3*/ +#define LV_SYMBOL_EXT_NOT_EQUAL "\xEF\x94\xBE" /*62782, f53e*/ +#define LV_SYMBOL_EXT_NOTDEF "\xEE\x87\xBE" /*57854, e1fe*/ +#define LV_SYMBOL_EXT_NOTE_STICKY "\xEF\x89\x89" /*62025, f249*/ +#define LV_SYMBOL_EXT_NOTES_MEDICAL "\xEF\x92\x81" /*62593, f481*/ +#define LV_SYMBOL_EXT_NPM "\xEF\x8F\x94" /*62420, f3d4*/ +#define LV_SYMBOL_EXT_NS8 "\xEF\x8F\x95" /*62421, f3d5*/ +#define LV_SYMBOL_EXT_NUTRITIONIX "\xEF\x8F\x96" /*62422, f3d6*/ +#define LV_SYMBOL_EXT_O "\x4F" /*79, 4f*/ +#define LV_SYMBOL_EXT_OBJECT_GROUP "\xEF\x89\x87" /*62023, f247*/ +#define LV_SYMBOL_EXT_OBJECT_UNGROUP "\xEF\x89\x88" /*62024, f248*/ +#define LV_SYMBOL_EXT_OCTOPUS_DEPLOY "\xEE\x82\x82" /*57474, e082*/ +#define LV_SYMBOL_EXT_ODNOKLASSNIKI "\xEF\x89\xA3" /*62051, f263*/ +#define LV_SYMBOL_EXT_ODYSEE "\xEE\x97\x86" /*58822, e5c6*/ +#define LV_SYMBOL_EXT_OIL_CAN "\xEF\x98\x93" /*62995, f613*/ +#define LV_SYMBOL_EXT_OIL_WELL "\xEE\x94\xB2" /*58674, e532*/ +#define LV_SYMBOL_EXT_OLD_REPUBLIC "\xEF\x94\x90" /*62736, f510*/ +#define LV_SYMBOL_EXT_OM "\xEF\x99\xB9" /*63097, f679*/ +#define LV_SYMBOL_EXT_OPENCART "\xEF\x88\xBD" /*62013, f23d*/ +#define LV_SYMBOL_EXT_OPENID "\xEF\x86\x9B" /*61851, f19b*/ +#define LV_SYMBOL_EXT_OPENSUSE "\xEE\x98\xAB" /*58923, e62b*/ +#define LV_SYMBOL_EXT_OPERA "\xEF\x89\xAA" /*62058, f26a*/ +#define LV_SYMBOL_EXT_OPTIN_MONSTER "\xEF\x88\xBC" /*62012, f23c*/ +#define LV_SYMBOL_EXT_ORCID "\xEF\xA3\x92" /*63698, f8d2*/ +#define LV_SYMBOL_EXT_OSI "\xEF\x90\x9A" /*62490, f41a*/ +#define LV_SYMBOL_EXT_OTTER "\xEF\x9C\x80" /*63232, f700*/ +#define LV_SYMBOL_EXT_OUTDENT "\xEF\x80\xBB" /*61499, f03b*/ +#define LV_SYMBOL_EXT_P "\x50" /*80, 50*/ +#define LV_SYMBOL_EXT_PADLET "\xEE\x92\xA0" /*58528, e4a0*/ +#define LV_SYMBOL_EXT_PAGE4 "\xEF\x8F\x97" /*62423, f3d7*/ +#define LV_SYMBOL_EXT_PAGELINES "\xEF\x86\x8C" /*61836, f18c*/ +#define LV_SYMBOL_EXT_PAGER "\xEF\xA0\x95" /*63509, f815*/ +#define LV_SYMBOL_EXT_PAINT_ROLLER "\xEF\x96\xAA" /*62890, f5aa*/ +#define LV_SYMBOL_EXT_PAINTBRUSH "\xEF\x87\xBC" /*61948, f1fc*/ +#define LV_SYMBOL_EXT_PALETTE "\xEF\x94\xBF" /*62783, f53f*/ +#define LV_SYMBOL_EXT_PALFED "\xEF\x8F\x98" /*62424, f3d8*/ +#define LV_SYMBOL_EXT_PALLET "\xEF\x92\x82" /*62594, f482*/ +#define LV_SYMBOL_EXT_PANORAMA "\xEE\x88\x89" /*57865, e209*/ +#define LV_SYMBOL_EXT_PAPER_PLANE "\xEF\x87\x98" /*61912, f1d8*/ +#define LV_SYMBOL_EXT_PAPERCLIP "\xEF\x83\x86" /*61638, f0c6*/ +#define LV_SYMBOL_EXT_PARACHUTE_BOX "\xEF\x93\x8D" /*62669, f4cd*/ +#define LV_SYMBOL_EXT_PARAGRAPH "\xEF\x87\x9D" /*61917, f1dd*/ +#define LV_SYMBOL_EXT_PASSPORT "\xEF\x96\xAB" /*62891, f5ab*/ +#define LV_SYMBOL_EXT_PASTE "\xEF\x83\xAA" /*61674, f0ea*/ +#define LV_SYMBOL_EXT_PATREON "\xEF\x8F\x99" /*62425, f3d9*/ +#define LV_SYMBOL_EXT_PAUSE "\xEF\x81\x8C" /*61516, f04c*/ +#define LV_SYMBOL_EXT_PAW "\xEF\x86\xB0" /*61872, f1b0*/ +#define LV_SYMBOL_EXT_PAYPAL "\xEF\x87\xAD" /*61933, f1ed*/ +#define LV_SYMBOL_EXT_PEACE "\xEF\x99\xBC" /*63100, f67c*/ +#define LV_SYMBOL_EXT_PEN "\xEF\x8C\x84" /*62212, f304*/ +#define LV_SYMBOL_EXT_PEN_CLIP "\xEF\x8C\x85" /*62213, f305*/ +#define LV_SYMBOL_EXT_PEN_FANCY "\xEF\x96\xAC" /*62892, f5ac*/ +#define LV_SYMBOL_EXT_PEN_NIB "\xEF\x96\xAD" /*62893, f5ad*/ +#define LV_SYMBOL_EXT_PEN_RULER "\xEF\x96\xAE" /*62894, f5ae*/ +#define LV_SYMBOL_EXT_PEN_TO_SQUARE "\xEF\x81\x84" /*61508, f044*/ +#define LV_SYMBOL_EXT_PENCIL "\xEF\x8C\x83" /*62211, f303*/ +#define LV_SYMBOL_EXT_PEOPLE_ARROWS "\xEE\x81\xA8" /*57448, e068*/ +#define LV_SYMBOL_EXT_PEOPLE_CARRY_BOX "\xEF\x93\x8E" /*62670, f4ce*/ +#define LV_SYMBOL_EXT_PEOPLE_GROUP "\xEE\x94\xB3" /*58675, e533*/ +#define LV_SYMBOL_EXT_PEOPLE_LINE "\xEE\x94\xB4" /*58676, e534*/ +#define LV_SYMBOL_EXT_PEOPLE_PULLING "\xEE\x94\xB5" /*58677, e535*/ +#define LV_SYMBOL_EXT_PEOPLE_ROBBERY "\xEE\x94\xB6" /*58678, e536*/ +#define LV_SYMBOL_EXT_PEOPLE_ROOF "\xEE\x94\xB7" /*58679, e537*/ +#define LV_SYMBOL_EXT_PEPPER_HOT "\xEF\xA0\x96" /*63510, f816*/ +#define LV_SYMBOL_EXT_PERBYTE "\xEE\x82\x83" /*57475, e083*/ +#define LV_SYMBOL_EXT_PERCENT "\x25" /*37, 25*/ +#define LV_SYMBOL_EXT_PERISCOPE "\xEF\x8F\x9A" /*62426, f3da*/ +#define LV_SYMBOL_EXT_PERSON "\xEF\x86\x83" /*61827, f183*/ +#define LV_SYMBOL_EXT_PERSON_ARROW_DOWN_TO_LINE "\xEE\x94\xB8" /*58680, e538*/ +#define LV_SYMBOL_EXT_PERSON_ARROW_UP_FROM_LINE "\xEE\x94\xB9" /*58681, e539*/ +#define LV_SYMBOL_EXT_PERSON_BIKING "\xEF\xA1\x8A" /*63562, f84a*/ +#define LV_SYMBOL_EXT_PERSON_BOOTH "\xEF\x9D\x96" /*63318, f756*/ +#define LV_SYMBOL_EXT_PERSON_BREASTFEEDING "\xEE\x94\xBA" /*58682, e53a*/ +#define LV_SYMBOL_EXT_PERSON_BURST "\xEE\x94\xBB" /*58683, e53b*/ +#define LV_SYMBOL_EXT_PERSON_CANE "\xEE\x94\xBC" /*58684, e53c*/ +#define LV_SYMBOL_EXT_PERSON_CHALKBOARD "\xEE\x94\xBD" /*58685, e53d*/ +#define LV_SYMBOL_EXT_PERSON_CIRCLE_CHECK "\xEE\x94\xBE" /*58686, e53e*/ +#define LV_SYMBOL_EXT_PERSON_CIRCLE_EXCLAMATION "\xEE\x94\xBF" /*58687, e53f*/ +#define LV_SYMBOL_EXT_PERSON_CIRCLE_MINUS "\xEE\x95\x80" /*58688, e540*/ +#define LV_SYMBOL_EXT_PERSON_CIRCLE_PLUS "\xEE\x95\x81" /*58689, e541*/ +#define LV_SYMBOL_EXT_PERSON_CIRCLE_QUESTION "\xEE\x95\x82" /*58690, e542*/ +#define LV_SYMBOL_EXT_PERSON_CIRCLE_XMARK "\xEE\x95\x83" /*58691, e543*/ +#define LV_SYMBOL_EXT_PERSON_DIGGING "\xEF\xA1\x9E" /*63582, f85e*/ +#define LV_SYMBOL_EXT_PERSON_DOTS_FROM_LINE "\xEF\x91\xB0" /*62576, f470*/ +#define LV_SYMBOL_EXT_PERSON_DRESS "\xEF\x86\x82" /*61826, f182*/ +#define LV_SYMBOL_EXT_PERSON_DRESS_BURST "\xEE\x95\x84" /*58692, e544*/ +#define LV_SYMBOL_EXT_PERSON_DROWNING "\xEE\x95\x85" /*58693, e545*/ +#define LV_SYMBOL_EXT_PERSON_FALLING "\xEE\x95\x86" /*58694, e546*/ +#define LV_SYMBOL_EXT_PERSON_FALLING_BURST "\xEE\x95\x87" /*58695, e547*/ +#define LV_SYMBOL_EXT_PERSON_HALF_DRESS "\xEE\x95\x88" /*58696, e548*/ +#define LV_SYMBOL_EXT_PERSON_HARASSING "\xEE\x95\x89" /*58697, e549*/ +#define LV_SYMBOL_EXT_PERSON_HIKING "\xEF\x9B\xAC" /*63212, f6ec*/ +#define LV_SYMBOL_EXT_PERSON_MILITARY_POINTING "\xEE\x95\x8A" /*58698, e54a*/ +#define LV_SYMBOL_EXT_PERSON_MILITARY_RIFLE "\xEE\x95\x8B" /*58699, e54b*/ +#define LV_SYMBOL_EXT_PERSON_MILITARY_TO_PERSON "\xEE\x95\x8C" /*58700, e54c*/ +#define LV_SYMBOL_EXT_PERSON_PRAYING "\xEF\x9A\x83" /*63107, f683*/ +#define LV_SYMBOL_EXT_PERSON_PREGNANT "\xEE\x8C\x9E" /*58142, e31e*/ +#define LV_SYMBOL_EXT_PERSON_RAYS "\xEE\x95\x8D" /*58701, e54d*/ +#define LV_SYMBOL_EXT_PERSON_RIFLE "\xEE\x95\x8E" /*58702, e54e*/ +#define LV_SYMBOL_EXT_PERSON_RUNNING "\xEF\x9C\x8C" /*63244, f70c*/ +#define LV_SYMBOL_EXT_PERSON_SHELTER "\xEE\x95\x8F" /*58703, e54f*/ +#define LV_SYMBOL_EXT_PERSON_SKATING "\xEF\x9F\x85" /*63429, f7c5*/ +#define LV_SYMBOL_EXT_PERSON_SKIING "\xEF\x9F\x89" /*63433, f7c9*/ +#define LV_SYMBOL_EXT_PERSON_SKIING_NORDIC "\xEF\x9F\x8A" /*63434, f7ca*/ +#define LV_SYMBOL_EXT_PERSON_SNOWBOARDING "\xEF\x9F\x8E" /*63438, f7ce*/ +#define LV_SYMBOL_EXT_PERSON_SWIMMING "\xEF\x97\x84" /*62916, f5c4*/ +#define LV_SYMBOL_EXT_PERSON_THROUGH_WINDOW "\xEE\x96\xA9" /*58793, e5a9*/ +#define LV_SYMBOL_EXT_PERSON_WALKING "\xEF\x95\x94" /*62804, f554*/ +#define LV_SYMBOL_EXT_PERSON_WALKING_ARROW_LOOP_LEFT "\xEE\x95\x91" /*58705, e551*/ +#define LV_SYMBOL_EXT_PERSON_WALKING_ARROW_RIGHT "\xEE\x95\x92" /*58706, e552*/ +#define LV_SYMBOL_EXT_PERSON_WALKING_DASHED_LINE_ARROW_RIGHT "\xEE\x95\x93" /*58707, e553*/ +#define LV_SYMBOL_EXT_PERSON_WALKING_LUGGAGE "\xEE\x95\x94" /*58708, e554*/ +#define LV_SYMBOL_EXT_PERSON_WALKING_WITH_CANE "\xEF\x8A\x9D" /*62109, f29d*/ +#define LV_SYMBOL_EXT_PESETA_SIGN "\xEE\x88\xA1" /*57889, e221*/ +#define LV_SYMBOL_EXT_PESO_SIGN "\xEE\x88\xA2" /*57890, e222*/ +#define LV_SYMBOL_EXT_PHABRICATOR "\xEF\x8F\x9B" /*62427, f3db*/ +#define LV_SYMBOL_EXT_PHOENIX_FRAMEWORK "\xEF\x8F\x9C" /*62428, f3dc*/ +#define LV_SYMBOL_EXT_PHOENIX_SQUADRON "\xEF\x94\x91" /*62737, f511*/ +#define LV_SYMBOL_EXT_PHONE "\xEF\x82\x95" /*61589, f095*/ +#define LV_SYMBOL_EXT_PHONE_FLIP "\xEF\xA1\xB9" /*63609, f879*/ +#define LV_SYMBOL_EXT_PHONE_SLASH "\xEF\x8F\x9D" /*62429, f3dd*/ +#define LV_SYMBOL_EXT_PHONE_VOLUME "\xEF\x8A\xA0" /*62112, f2a0*/ +#define LV_SYMBOL_EXT_PHOTO_FILM "\xEF\xA1\xBC" /*63612, f87c*/ +#define LV_SYMBOL_EXT_PHP "\xEF\x91\x97" /*62551, f457*/ +#define LV_SYMBOL_EXT_PIED_PIPER "\xEF\x8A\xAE" /*62126, f2ae*/ +#define LV_SYMBOL_EXT_PIED_PIPER_ALT "\xEF\x86\xA8" /*61864, f1a8*/ +#define LV_SYMBOL_EXT_PIED_PIPER_HAT "\xEF\x93\xA5" /*62693, f4e5*/ +#define LV_SYMBOL_EXT_PIED_PIPER_PP "\xEF\x86\xA7" /*61863, f1a7*/ +#define LV_SYMBOL_EXT_PIGGY_BANK "\xEF\x93\x93" /*62675, f4d3*/ +#define LV_SYMBOL_EXT_PILLS "\xEF\x92\x84" /*62596, f484*/ +#define LV_SYMBOL_EXT_PINTEREST "\xEF\x83\x92" /*61650, f0d2*/ +#define LV_SYMBOL_EXT_PINTEREST_P "\xEF\x88\xB1" /*62001, f231*/ +#define LV_SYMBOL_EXT_PIX "\xEE\x90\xBA" /*58426, e43a*/ +#define LV_SYMBOL_EXT_PIXIV "\xEE\x99\x80" /*58944, e640*/ +#define LV_SYMBOL_EXT_PIZZA_SLICE "\xEF\xA0\x98" /*63512, f818*/ +#define LV_SYMBOL_EXT_PLACE_OF_WORSHIP "\xEF\x99\xBF" /*63103, f67f*/ +#define LV_SYMBOL_EXT_PLANE "\xEF\x81\xB2" /*61554, f072*/ +#define LV_SYMBOL_EXT_PLANE_ARRIVAL "\xEF\x96\xAF" /*62895, f5af*/ +#define LV_SYMBOL_EXT_PLANE_CIRCLE_CHECK "\xEE\x95\x95" /*58709, e555*/ +#define LV_SYMBOL_EXT_PLANE_CIRCLE_EXCLAMATION "\xEE\x95\x96" /*58710, e556*/ +#define LV_SYMBOL_EXT_PLANE_CIRCLE_XMARK "\xEE\x95\x97" /*58711, e557*/ +#define LV_SYMBOL_EXT_PLANE_DEPARTURE "\xEF\x96\xB0" /*62896, f5b0*/ +#define LV_SYMBOL_EXT_PLANE_LOCK "\xEE\x95\x98" /*58712, e558*/ +#define LV_SYMBOL_EXT_PLANE_SLASH "\xEE\x81\xA9" /*57449, e069*/ +#define LV_SYMBOL_EXT_PLANE_UP "\xEE\x88\xAD" /*57901, e22d*/ +#define LV_SYMBOL_EXT_PLANT_WILT "\xEE\x96\xAA" /*58794, e5aa*/ +#define LV_SYMBOL_EXT_PLATE_WHEAT "\xEE\x95\x9A" /*58714, e55a*/ +#define LV_SYMBOL_EXT_PLAY "\xEF\x81\x8B" /*61515, f04b*/ +#define LV_SYMBOL_EXT_PLAYSTATION "\xEF\x8F\x9F" /*62431, f3df*/ +#define LV_SYMBOL_EXT_PLUG "\xEF\x87\xA6" /*61926, f1e6*/ +#define LV_SYMBOL_EXT_PLUG_CIRCLE_BOLT "\xEE\x95\x9B" /*58715, e55b*/ +#define LV_SYMBOL_EXT_PLUG_CIRCLE_CHECK "\xEE\x95\x9C" /*58716, e55c*/ +#define LV_SYMBOL_EXT_PLUG_CIRCLE_EXCLAMATION "\xEE\x95\x9D" /*58717, e55d*/ +#define LV_SYMBOL_EXT_PLUG_CIRCLE_MINUS "\xEE\x95\x9E" /*58718, e55e*/ +#define LV_SYMBOL_EXT_PLUG_CIRCLE_PLUS "\xEE\x95\x9F" /*58719, e55f*/ +#define LV_SYMBOL_EXT_PLUG_CIRCLE_XMARK "\xEE\x95\xA0" /*58720, e560*/ +#define LV_SYMBOL_EXT_PLUS "\x2B" /*43, 2b*/ +#define LV_SYMBOL_EXT_PLUS_MINUS "\xEE\x90\xBC" /*58428, e43c*/ +#define LV_SYMBOL_EXT_PODCAST "\xEF\x8B\x8E" /*62158, f2ce*/ +#define LV_SYMBOL_EXT_POO "\xEF\x8B\xBE" /*62206, f2fe*/ +#define LV_SYMBOL_EXT_POO_STORM "\xEF\x9D\x9A" /*63322, f75a*/ +#define LV_SYMBOL_EXT_POOP "\xEF\x98\x99" /*63001, f619*/ +#define LV_SYMBOL_EXT_POWER_OFF "\xEF\x80\x91" /*61457, f011*/ +#define LV_SYMBOL_EXT_PRESCRIPTION "\xEF\x96\xB1" /*62897, f5b1*/ +#define LV_SYMBOL_EXT_PRESCRIPTION_BOTTLE "\xEF\x92\x85" /*62597, f485*/ +#define LV_SYMBOL_EXT_PRESCRIPTION_BOTTLE_MEDICAL "\xEF\x92\x86" /*62598, f486*/ +#define LV_SYMBOL_EXT_PRINT "\xEF\x80\xAF" /*61487, f02f*/ +#define LV_SYMBOL_EXT_PRODUCT_HUNT "\xEF\x8A\x88" /*62088, f288*/ +#define LV_SYMBOL_EXT_PUMP_MEDICAL "\xEE\x81\xAA" /*57450, e06a*/ +#define LV_SYMBOL_EXT_PUMP_SOAP "\xEE\x81\xAB" /*57451, e06b*/ +#define LV_SYMBOL_EXT_PUSHED "\xEF\x8F\xA1" /*62433, f3e1*/ +#define LV_SYMBOL_EXT_PUZZLE_PIECE "\xEF\x84\xAE" /*61742, f12e*/ +#define LV_SYMBOL_EXT_PYTHON "\xEF\x8F\xA2" /*62434, f3e2*/ +#define LV_SYMBOL_EXT_Q "\x51" /*81, 51*/ +#define LV_SYMBOL_EXT_QQ "\xEF\x87\x96" /*61910, f1d6*/ +#define LV_SYMBOL_EXT_QRCODE "\xEF\x80\xA9" /*61481, f029*/ +#define LV_SYMBOL_EXT_QUESTION "\x3F" /*63, 3f*/ +#define LV_SYMBOL_EXT_QUINSCAPE "\xEF\x91\x99" /*62553, f459*/ +#define LV_SYMBOL_EXT_QUORA "\xEF\x8B\x84" /*62148, f2c4*/ +#define LV_SYMBOL_EXT_QUOTE_LEFT "\xEF\x84\x8D" /*61709, f10d*/ +#define LV_SYMBOL_EXT_QUOTE_RIGHT "\xEF\x84\x8E" /*61710, f10e*/ +#define LV_SYMBOL_EXT_R "\x52" /*82, 52*/ +#define LV_SYMBOL_EXT_R_PROJECT "\xEF\x93\xB7" /*62711, f4f7*/ +#define LV_SYMBOL_EXT_RADIATION "\xEF\x9E\xB9" /*63417, f7b9*/ +#define LV_SYMBOL_EXT_RADIO "\xEF\xA3\x97" /*63703, f8d7*/ +#define LV_SYMBOL_EXT_RAINBOW "\xEF\x9D\x9B" /*63323, f75b*/ +#define LV_SYMBOL_EXT_RANKING_STAR "\xEE\x95\xA1" /*58721, e561*/ +#define LV_SYMBOL_EXT_RASPBERRY_PI "\xEF\x9E\xBB" /*63419, f7bb*/ +#define LV_SYMBOL_EXT_RAVELRY "\xEF\x8B\x99" /*62169, f2d9*/ +#define LV_SYMBOL_EXT_REACT "\xEF\x90\x9B" /*62491, f41b*/ +#define LV_SYMBOL_EXT_REACTEUROPE "\xEF\x9D\x9D" /*63325, f75d*/ +#define LV_SYMBOL_EXT_README "\xEF\x93\x95" /*62677, f4d5*/ +#define LV_SYMBOL_EXT_REBEL "\xEF\x87\x90" /*61904, f1d0*/ +#define LV_SYMBOL_EXT_RECEIPT "\xEF\x95\x83" /*62787, f543*/ +#define LV_SYMBOL_EXT_RECORD_VINYL "\xEF\xA3\x99" /*63705, f8d9*/ +#define LV_SYMBOL_EXT_RECTANGLE_AD "\xEF\x99\x81" /*63041, f641*/ +#define LV_SYMBOL_EXT_RECTANGLE_LIST "\xEF\x80\xA2" /*61474, f022*/ +#define LV_SYMBOL_EXT_RECTANGLE_XMARK "\xEF\x90\x90" /*62480, f410*/ +#define LV_SYMBOL_EXT_RECYCLE "\xEF\x86\xB8" /*61880, f1b8*/ +#define LV_SYMBOL_EXT_RED_RIVER "\xEF\x8F\xA3" /*62435, f3e3*/ +#define LV_SYMBOL_EXT_REDDIT "\xEF\x86\xA1" /*61857, f1a1*/ +#define LV_SYMBOL_EXT_REDDIT_ALIEN "\xEF\x8A\x81" /*62081, f281*/ +#define LV_SYMBOL_EXT_REDHAT "\xEF\x9E\xBC" /*63420, f7bc*/ +#define LV_SYMBOL_EXT_REGISTERED "\xEF\x89\x9D" /*62045, f25d*/ +#define LV_SYMBOL_EXT_RENREN "\xEF\x86\x8B" /*61835, f18b*/ +#define LV_SYMBOL_EXT_REPEAT "\xEF\x8D\xA3" /*62307, f363*/ +#define LV_SYMBOL_EXT_REPLY "\xEF\x8F\xA5" /*62437, f3e5*/ +#define LV_SYMBOL_EXT_REPLY_ALL "\xEF\x84\xA2" /*61730, f122*/ +#define LV_SYMBOL_EXT_REPLYD "\xEF\x8F\xA6" /*62438, f3e6*/ +#define LV_SYMBOL_EXT_REPUBLICAN "\xEF\x9D\x9E" /*63326, f75e*/ +#define LV_SYMBOL_EXT_RESEARCHGATE "\xEF\x93\xB8" /*62712, f4f8*/ +#define LV_SYMBOL_EXT_RESOLVING "\xEF\x8F\xA7" /*62439, f3e7*/ +#define LV_SYMBOL_EXT_RESTROOM "\xEF\x9E\xBD" /*63421, f7bd*/ +#define LV_SYMBOL_EXT_RETWEET "\xEF\x81\xB9" /*61561, f079*/ +#define LV_SYMBOL_EXT_REV "\xEF\x96\xB2" /*62898, f5b2*/ +#define LV_SYMBOL_EXT_RIBBON "\xEF\x93\x96" /*62678, f4d6*/ +#define LV_SYMBOL_EXT_RIGHT_FROM_BRACKET "\xEF\x8B\xB5" /*62197, f2f5*/ +#define LV_SYMBOL_EXT_RIGHT_LEFT "\xEF\x8D\xA2" /*62306, f362*/ +#define LV_SYMBOL_EXT_RIGHT_LONG "\xEF\x8C\x8B" /*62219, f30b*/ +#define LV_SYMBOL_EXT_RIGHT_TO_BRACKET "\xEF\x8B\xB6" /*62198, f2f6*/ +#define LV_SYMBOL_EXT_RING "\xEF\x9C\x8B" /*63243, f70b*/ +#define LV_SYMBOL_EXT_ROAD "\xEF\x80\x98" /*61464, f018*/ +#define LV_SYMBOL_EXT_ROAD_BARRIER "\xEE\x95\xA2" /*58722, e562*/ +#define LV_SYMBOL_EXT_ROAD_BRIDGE "\xEE\x95\xA3" /*58723, e563*/ +#define LV_SYMBOL_EXT_ROAD_CIRCLE_CHECK "\xEE\x95\xA4" /*58724, e564*/ +#define LV_SYMBOL_EXT_ROAD_CIRCLE_EXCLAMATION "\xEE\x95\xA5" /*58725, e565*/ +#define LV_SYMBOL_EXT_ROAD_CIRCLE_XMARK "\xEE\x95\xA6" /*58726, e566*/ +#define LV_SYMBOL_EXT_ROAD_LOCK "\xEE\x95\xA7" /*58727, e567*/ +#define LV_SYMBOL_EXT_ROAD_SPIKES "\xEE\x95\xA8" /*58728, e568*/ +#define LV_SYMBOL_EXT_ROBOT "\xEF\x95\x84" /*62788, f544*/ +#define LV_SYMBOL_EXT_ROCKET "\xEF\x84\xB5" /*61749, f135*/ +#define LV_SYMBOL_EXT_ROCKETCHAT "\xEF\x8F\xA8" /*62440, f3e8*/ +#define LV_SYMBOL_EXT_ROCKRMS "\xEF\x8F\xA9" /*62441, f3e9*/ +#define LV_SYMBOL_EXT_ROTATE "\xEF\x8B\xB1" /*62193, f2f1*/ +#define LV_SYMBOL_EXT_ROTATE_LEFT "\xEF\x8B\xAA" /*62186, f2ea*/ +#define LV_SYMBOL_EXT_ROTATE_RIGHT "\xEF\x8B\xB9" /*62201, f2f9*/ +#define LV_SYMBOL_EXT_ROUTE "\xEF\x93\x97" /*62679, f4d7*/ +#define LV_SYMBOL_EXT_RSS "\xEF\x82\x9E" /*61598, f09e*/ +#define LV_SYMBOL_EXT_RUBLE_SIGN "\xEF\x85\x98" /*61784, f158*/ +#define LV_SYMBOL_EXT_RUG "\xEE\x95\xA9" /*58729, e569*/ +#define LV_SYMBOL_EXT_RULER "\xEF\x95\x85" /*62789, f545*/ +#define LV_SYMBOL_EXT_RULER_COMBINED "\xEF\x95\x86" /*62790, f546*/ +#define LV_SYMBOL_EXT_RULER_HORIZONTAL "\xEF\x95\x87" /*62791, f547*/ +#define LV_SYMBOL_EXT_RULER_VERTICAL "\xEF\x95\x88" /*62792, f548*/ +#define LV_SYMBOL_EXT_RUPEE_SIGN "\xEF\x85\x96" /*61782, f156*/ +#define LV_SYMBOL_EXT_RUPIAH_SIGN "\xEE\x88\xBD" /*57917, e23d*/ +#define LV_SYMBOL_EXT_RUST "\xEE\x81\xBA" /*57466, e07a*/ +#define LV_SYMBOL_EXT_S "\x53" /*83, 53*/ +#define LV_SYMBOL_EXT_SACK_DOLLAR "\xEF\xA0\x9D" /*63517, f81d*/ +#define LV_SYMBOL_EXT_SACK_XMARK "\xEE\x95\xAA" /*58730, e56a*/ +#define LV_SYMBOL_EXT_SAFARI "\xEF\x89\xA7" /*62055, f267*/ +#define LV_SYMBOL_EXT_SAILBOAT "\xEE\x91\x85" /*58437, e445*/ +#define LV_SYMBOL_EXT_SALESFORCE "\xEF\xA0\xBB" /*63547, f83b*/ +#define LV_SYMBOL_EXT_SASS "\xEF\x90\x9E" /*62494, f41e*/ +#define LV_SYMBOL_EXT_SATELLITE "\xEF\x9E\xBF" /*63423, f7bf*/ +#define LV_SYMBOL_EXT_SATELLITE_DISH "\xEF\x9F\x80" /*63424, f7c0*/ +#define LV_SYMBOL_EXT_SCALE_BALANCED "\xEF\x89\x8E" /*62030, f24e*/ +#define LV_SYMBOL_EXT_SCALE_UNBALANCED "\xEF\x94\x95" /*62741, f515*/ +#define LV_SYMBOL_EXT_SCALE_UNBALANCED_FLIP "\xEF\x94\x96" /*62742, f516*/ +#define LV_SYMBOL_EXT_SCHLIX "\xEF\x8F\xAA" /*62442, f3ea*/ +#define LV_SYMBOL_EXT_SCHOOL "\xEF\x95\x89" /*62793, f549*/ +#define LV_SYMBOL_EXT_SCHOOL_CIRCLE_CHECK "\xEE\x95\xAB" /*58731, e56b*/ +#define LV_SYMBOL_EXT_SCHOOL_CIRCLE_EXCLAMATION "\xEE\x95\xAC" /*58732, e56c*/ +#define LV_SYMBOL_EXT_SCHOOL_CIRCLE_XMARK "\xEE\x95\xAD" /*58733, e56d*/ +#define LV_SYMBOL_EXT_SCHOOL_FLAG "\xEE\x95\xAE" /*58734, e56e*/ +#define LV_SYMBOL_EXT_SCHOOL_LOCK "\xEE\x95\xAF" /*58735, e56f*/ +#define LV_SYMBOL_EXT_SCISSORS "\xEF\x83\x84" /*61636, f0c4*/ +#define LV_SYMBOL_EXT_SCREENPAL "\xEE\x95\xB0" /*58736, e570*/ +#define LV_SYMBOL_EXT_SCREWDRIVER "\xEF\x95\x8A" /*62794, f54a*/ +#define LV_SYMBOL_EXT_SCREWDRIVER_WRENCH "\xEF\x9F\x99" /*63449, f7d9*/ +#define LV_SYMBOL_EXT_SCRIBD "\xEF\x8A\x8A" /*62090, f28a*/ +#define LV_SYMBOL_EXT_SCROLL "\xEF\x9C\x8E" /*63246, f70e*/ +#define LV_SYMBOL_EXT_SCROLL_TORAH "\xEF\x9A\xA0" /*63136, f6a0*/ +#define LV_SYMBOL_EXT_SD_CARD "\xEF\x9F\x82" /*63426, f7c2*/ +#define LV_SYMBOL_EXT_SEARCHENGIN "\xEF\x8F\xAB" /*62443, f3eb*/ +#define LV_SYMBOL_EXT_SECTION "\xEE\x91\x87" /*58439, e447*/ +#define LV_SYMBOL_EXT_SEEDLING "\xEF\x93\x98" /*62680, f4d8*/ +#define LV_SYMBOL_EXT_SELLCAST "\xEF\x8B\x9A" /*62170, f2da*/ +#define LV_SYMBOL_EXT_SELLSY "\xEF\x88\x93" /*61971, f213*/ +#define LV_SYMBOL_EXT_SERVER "\xEF\x88\xB3" /*62003, f233*/ +#define LV_SYMBOL_EXT_SERVICESTACK "\xEF\x8F\xAC" /*62444, f3ec*/ +#define LV_SYMBOL_EXT_SHAPES "\xEF\x98\x9F" /*63007, f61f*/ +#define LV_SYMBOL_EXT_SHARE "\xEF\x81\xA4" /*61540, f064*/ +#define LV_SYMBOL_EXT_SHARE_FROM_SQUARE "\xEF\x85\x8D" /*61773, f14d*/ +#define LV_SYMBOL_EXT_SHARE_NODES "\xEF\x87\xA0" /*61920, f1e0*/ +#define LV_SYMBOL_EXT_SHEET_PLASTIC "\xEE\x95\xB1" /*58737, e571*/ +#define LV_SYMBOL_EXT_SHEKEL_SIGN "\xEF\x88\x8B" /*61963, f20b*/ +#define LV_SYMBOL_EXT_SHIELD "\xEF\x84\xB2" /*61746, f132*/ +#define LV_SYMBOL_EXT_SHIELD_CAT "\xEE\x95\xB2" /*58738, e572*/ +#define LV_SYMBOL_EXT_SHIELD_DOG "\xEE\x95\xB3" /*58739, e573*/ +#define LV_SYMBOL_EXT_SHIELD_HALVED "\xEF\x8F\xAD" /*62445, f3ed*/ +#define LV_SYMBOL_EXT_SHIELD_HEART "\xEE\x95\xB4" /*58740, e574*/ +#define LV_SYMBOL_EXT_SHIELD_VIRUS "\xEE\x81\xAC" /*57452, e06c*/ +#define LV_SYMBOL_EXT_SHIP "\xEF\x88\x9A" /*61978, f21a*/ +#define LV_SYMBOL_EXT_SHIRT "\xEF\x95\x93" /*62803, f553*/ +#define LV_SYMBOL_EXT_SHIRTSINBULK "\xEF\x88\x94" /*61972, f214*/ +#define LV_SYMBOL_EXT_SHOE_PRINTS "\xEF\x95\x8B" /*62795, f54b*/ +#define LV_SYMBOL_EXT_SHOELACE "\xEE\x98\x8C" /*58892, e60c*/ +#define LV_SYMBOL_EXT_SHOP "\xEF\x95\x8F" /*62799, f54f*/ +#define LV_SYMBOL_EXT_SHOP_LOCK "\xEE\x92\xA5" /*58533, e4a5*/ +#define LV_SYMBOL_EXT_SHOP_SLASH "\xEE\x81\xB0" /*57456, e070*/ +#define LV_SYMBOL_EXT_SHOPIFY "\xEE\x81\x97" /*57431, e057*/ +#define LV_SYMBOL_EXT_SHOPWARE "\xEF\x96\xB5" /*62901, f5b5*/ +#define LV_SYMBOL_EXT_SHOWER "\xEF\x8B\x8C" /*62156, f2cc*/ +#define LV_SYMBOL_EXT_SHRIMP "\xEE\x91\x88" /*58440, e448*/ +#define LV_SYMBOL_EXT_SHUFFLE "\xEF\x81\xB4" /*61556, f074*/ +#define LV_SYMBOL_EXT_SHUTTLE_SPACE "\xEF\x86\x97" /*61847, f197*/ +#define LV_SYMBOL_EXT_SIGN_HANGING "\xEF\x93\x99" /*62681, f4d9*/ +#define LV_SYMBOL_EXT_SIGNAL "\xEF\x80\x92" /*61458, f012*/ +#define LV_SYMBOL_EXT_SIGNAL_MESSENGER "\xEE\x99\xA3" /*58979, e663*/ +#define LV_SYMBOL_EXT_SIGNATURE "\xEF\x96\xB7" /*62903, f5b7*/ +#define LV_SYMBOL_EXT_SIGNS_POST "\xEF\x89\xB7" /*62071, f277*/ +#define LV_SYMBOL_EXT_SIM_CARD "\xEF\x9F\x84" /*63428, f7c4*/ +#define LV_SYMBOL_EXT_SIMPLYBUILT "\xEF\x88\x95" /*61973, f215*/ +#define LV_SYMBOL_EXT_SINK "\xEE\x81\xAD" /*57453, e06d*/ +#define LV_SYMBOL_EXT_SISTRIX "\xEF\x8F\xAE" /*62446, f3ee*/ +#define LV_SYMBOL_EXT_SITEMAP "\xEF\x83\xA8" /*61672, f0e8*/ +#define LV_SYMBOL_EXT_SITH "\xEF\x94\x92" /*62738, f512*/ +#define LV_SYMBOL_EXT_SITROX "\xEE\x91\x8A" /*58442, e44a*/ +#define LV_SYMBOL_EXT_SKETCH "\xEF\x9F\x86" /*63430, f7c6*/ +#define LV_SYMBOL_EXT_SKULL "\xEF\x95\x8C" /*62796, f54c*/ +#define LV_SYMBOL_EXT_SKULL_CROSSBONES "\xEF\x9C\x94" /*63252, f714*/ +#define LV_SYMBOL_EXT_SKYATLAS "\xEF\x88\x96" /*61974, f216*/ +#define LV_SYMBOL_EXT_SKYPE "\xEF\x85\xBE" /*61822, f17e*/ +#define LV_SYMBOL_EXT_SLACK "\xEF\x86\x98" /*61848, f198*/ +#define LV_SYMBOL_EXT_SLASH "\xEF\x9C\x95" /*63253, f715*/ +#define LV_SYMBOL_EXT_SLEIGH "\xEF\x9F\x8C" /*63436, f7cc*/ +#define LV_SYMBOL_EXT_SLIDERS "\xEF\x87\x9E" /*61918, f1de*/ +#define LV_SYMBOL_EXT_SLIDESHARE "\xEF\x87\xA7" /*61927, f1e7*/ +#define LV_SYMBOL_EXT_SMOG "\xEF\x9D\x9F" /*63327, f75f*/ +#define LV_SYMBOL_EXT_SMOKING "\xEF\x92\x8D" /*62605, f48d*/ +#define LV_SYMBOL_EXT_SNAPCHAT "\xEF\x8A\xAB" /*62123, f2ab*/ +#define LV_SYMBOL_EXT_SNOWFLAKE "\xEF\x8B\x9C" /*62172, f2dc*/ +#define LV_SYMBOL_EXT_SNOWMAN "\xEF\x9F\x90" /*63440, f7d0*/ +#define LV_SYMBOL_EXT_SNOWPLOW "\xEF\x9F\x92" /*63442, f7d2*/ +#define LV_SYMBOL_EXT_SOAP "\xEE\x81\xAE" /*57454, e06e*/ +#define LV_SYMBOL_EXT_SOCKS "\xEF\x9A\x96" /*63126, f696*/ +#define LV_SYMBOL_EXT_SOLAR_PANEL "\xEF\x96\xBA" /*62906, f5ba*/ +#define LV_SYMBOL_EXT_SORT "\xEF\x83\x9C" /*61660, f0dc*/ +#define LV_SYMBOL_EXT_SORT_DOWN "\xEF\x83\x9D" /*61661, f0dd*/ +#define LV_SYMBOL_EXT_SORT_UP "\xEF\x83\x9E" /*61662, f0de*/ +#define LV_SYMBOL_EXT_SOUNDCLOUD "\xEF\x86\xBE" /*61886, f1be*/ +#define LV_SYMBOL_EXT_SOURCETREE "\xEF\x9F\x93" /*63443, f7d3*/ +#define LV_SYMBOL_EXT_SPA "\xEF\x96\xBB" /*62907, f5bb*/ +#define LV_SYMBOL_EXT_SPACE_AWESOME "\xEE\x96\xAC" /*58796, e5ac*/ +#define LV_SYMBOL_EXT_SPAGHETTI_MONSTER_FLYING "\xEF\x99\xBB" /*63099, f67b*/ +#define LV_SYMBOL_EXT_SPEAKAP "\xEF\x8F\xB3" /*62451, f3f3*/ +#define LV_SYMBOL_EXT_SPEAKER_DECK "\xEF\xA0\xBC" /*63548, f83c*/ +#define LV_SYMBOL_EXT_SPELL_CHECK "\xEF\xA2\x91" /*63633, f891*/ +#define LV_SYMBOL_EXT_SPIDER "\xEF\x9C\x97" /*63255, f717*/ +#define LV_SYMBOL_EXT_SPINNER "\xEF\x84\x90" /*61712, f110*/ +#define LV_SYMBOL_EXT_SPLOTCH "\xEF\x96\xBC" /*62908, f5bc*/ +#define LV_SYMBOL_EXT_SPOON "\xEF\x8B\xA5" /*62181, f2e5*/ +#define LV_SYMBOL_EXT_SPOTIFY "\xEF\x86\xBC" /*61884, f1bc*/ +#define LV_SYMBOL_EXT_SPRAY_CAN "\xEF\x96\xBD" /*62909, f5bd*/ +#define LV_SYMBOL_EXT_SPRAY_CAN_SPARKLES "\xEF\x97\x90" /*62928, f5d0*/ +#define LV_SYMBOL_EXT_SQUARE "\xEF\x83\x88" /*61640, f0c8*/ +#define LV_SYMBOL_EXT_SQUARE_ARROW_UP_RIGHT "\xEF\x85\x8C" /*61772, f14c*/ +#define LV_SYMBOL_EXT_SQUARE_BEHANCE "\xEF\x86\xB5" /*61877, f1b5*/ +#define LV_SYMBOL_EXT_SQUARE_CARET_DOWN "\xEF\x85\x90" /*61776, f150*/ +#define LV_SYMBOL_EXT_SQUARE_CARET_LEFT "\xEF\x86\x91" /*61841, f191*/ +#define LV_SYMBOL_EXT_SQUARE_CARET_RIGHT "\xEF\x85\x92" /*61778, f152*/ +#define LV_SYMBOL_EXT_SQUARE_CARET_UP "\xEF\x85\x91" /*61777, f151*/ +#define LV_SYMBOL_EXT_SQUARE_CHECK "\xEF\x85\x8A" /*61770, f14a*/ +#define LV_SYMBOL_EXT_SQUARE_DRIBBBLE "\xEF\x8E\x97" /*62359, f397*/ +#define LV_SYMBOL_EXT_SQUARE_ENVELOPE "\xEF\x86\x99" /*61849, f199*/ +#define LV_SYMBOL_EXT_SQUARE_FACEBOOK "\xEF\x82\x82" /*61570, f082*/ +#define LV_SYMBOL_EXT_SQUARE_FONT_AWESOME "\xEE\x96\xAD" /*58797, e5ad*/ +#define LV_SYMBOL_EXT_SQUARE_FONT_AWESOME_STROKE "\xEF\x8D\x9C" /*62300, f35c*/ +#define LV_SYMBOL_EXT_SQUARE_FULL "\xEF\x91\x9C" /*62556, f45c*/ +#define LV_SYMBOL_EXT_SQUARE_GIT "\xEF\x87\x92" /*61906, f1d2*/ +#define LV_SYMBOL_EXT_SQUARE_GITHUB "\xEF\x82\x92" /*61586, f092*/ +#define LV_SYMBOL_EXT_SQUARE_GITLAB "\xEE\x96\xAE" /*58798, e5ae*/ +#define LV_SYMBOL_EXT_SQUARE_GOOGLE_PLUS "\xEF\x83\x94" /*61652, f0d4*/ +#define LV_SYMBOL_EXT_SQUARE_H "\xEF\x83\xBD" /*61693, f0fd*/ +#define LV_SYMBOL_EXT_SQUARE_HACKER_NEWS "\xEF\x8E\xAF" /*62383, f3af*/ +#define LV_SYMBOL_EXT_SQUARE_INSTAGRAM "\xEE\x81\x95" /*57429, e055*/ +#define LV_SYMBOL_EXT_SQUARE_JS "\xEF\x8E\xB9" /*62393, f3b9*/ +#define LV_SYMBOL_EXT_SQUARE_LASTFM "\xEF\x88\x83" /*61955, f203*/ +#define LV_SYMBOL_EXT_SQUARE_LETTERBOXD "\xEE\x98\xAE" /*58926, e62e*/ +#define LV_SYMBOL_EXT_SQUARE_MINUS "\xEF\x85\x86" /*61766, f146*/ +#define LV_SYMBOL_EXT_SQUARE_NFI "\xEE\x95\xB6" /*58742, e576*/ +#define LV_SYMBOL_EXT_SQUARE_ODNOKLASSNIKI "\xEF\x89\xA4" /*62052, f264*/ +#define LV_SYMBOL_EXT_SQUARE_PARKING "\xEF\x95\x80" /*62784, f540*/ +#define LV_SYMBOL_EXT_SQUARE_PEN "\xEF\x85\x8B" /*61771, f14b*/ +#define LV_SYMBOL_EXT_SQUARE_PERSON_CONFINED "\xEE\x95\xB7" /*58743, e577*/ +#define LV_SYMBOL_EXT_SQUARE_PHONE "\xEF\x82\x98" /*61592, f098*/ +#define LV_SYMBOL_EXT_SQUARE_PHONE_FLIP "\xEF\xA1\xBB" /*63611, f87b*/ +#define LV_SYMBOL_EXT_SQUARE_PIED_PIPER "\xEE\x80\x9E" /*57374, e01e*/ +#define LV_SYMBOL_EXT_SQUARE_PINTEREST "\xEF\x83\x93" /*61651, f0d3*/ +#define LV_SYMBOL_EXT_SQUARE_PLUS "\xEF\x83\xBE" /*61694, f0fe*/ +#define LV_SYMBOL_EXT_SQUARE_POLL_HORIZONTAL "\xEF\x9A\x82" /*63106, f682*/ +#define LV_SYMBOL_EXT_SQUARE_POLL_VERTICAL "\xEF\x9A\x81" /*63105, f681*/ +#define LV_SYMBOL_EXT_SQUARE_REDDIT "\xEF\x86\xA2" /*61858, f1a2*/ +#define LV_SYMBOL_EXT_SQUARE_ROOT_VARIABLE "\xEF\x9A\x98" /*63128, f698*/ +#define LV_SYMBOL_EXT_SQUARE_RSS "\xEF\x85\x83" /*61763, f143*/ +#define LV_SYMBOL_EXT_SQUARE_SHARE_NODES "\xEF\x87\xA1" /*61921, f1e1*/ +#define LV_SYMBOL_EXT_SQUARE_SNAPCHAT "\xEF\x8A\xAD" /*62125, f2ad*/ +#define LV_SYMBOL_EXT_SQUARE_STEAM "\xEF\x86\xB7" /*61879, f1b7*/ +#define LV_SYMBOL_EXT_SQUARE_THREADS "\xEE\x98\x99" /*58905, e619*/ +#define LV_SYMBOL_EXT_SQUARE_TUMBLR "\xEF\x85\xB4" /*61812, f174*/ +#define LV_SYMBOL_EXT_SQUARE_TWITTER "\xEF\x82\x81" /*61569, f081*/ +#define LV_SYMBOL_EXT_SQUARE_UP_RIGHT "\xEF\x8D\xA0" /*62304, f360*/ +#define LV_SYMBOL_EXT_SQUARE_VIADEO "\xEF\x8A\xAA" /*62122, f2aa*/ +#define LV_SYMBOL_EXT_SQUARE_VIMEO "\xEF\x86\x94" /*61844, f194*/ +#define LV_SYMBOL_EXT_SQUARE_VIRUS "\xEE\x95\xB8" /*58744, e578*/ +#define LV_SYMBOL_EXT_SQUARE_WHATSAPP "\xEF\x90\x8C" /*62476, f40c*/ +#define LV_SYMBOL_EXT_SQUARE_X_TWITTER "\xEE\x98\x9A" /*58906, e61a*/ +#define LV_SYMBOL_EXT_SQUARE_XING "\xEF\x85\xA9" /*61801, f169*/ +#define LV_SYMBOL_EXT_SQUARE_XMARK "\xEF\x8B\x93" /*62163, f2d3*/ +#define LV_SYMBOL_EXT_SQUARE_YOUTUBE "\xEF\x90\xB1" /*62513, f431*/ +#define LV_SYMBOL_EXT_SQUARESPACE "\xEF\x96\xBE" /*62910, f5be*/ +#define LV_SYMBOL_EXT_STACK_EXCHANGE "\xEF\x86\x8D" /*61837, f18d*/ +#define LV_SYMBOL_EXT_STACK_OVERFLOW "\xEF\x85\xAC" /*61804, f16c*/ +#define LV_SYMBOL_EXT_STACKPATH "\xEF\xA1\x82" /*63554, f842*/ +#define LV_SYMBOL_EXT_STAFF_SNAKE "\xEE\x95\xB9" /*58745, e579*/ +#define LV_SYMBOL_EXT_STAIRS "\xEE\x8A\x89" /*57993, e289*/ +#define LV_SYMBOL_EXT_STAMP "\xEF\x96\xBF" /*62911, f5bf*/ +#define LV_SYMBOL_EXT_STAPLER "\xEE\x96\xAF" /*58799, e5af*/ +#define LV_SYMBOL_EXT_STAR "\xEF\x80\x85" /*61445, f005*/ +#define LV_SYMBOL_EXT_STAR_AND_CRESCENT "\xEF\x9A\x99" /*63129, f699*/ +#define LV_SYMBOL_EXT_STAR_HALF "\xEF\x82\x89" /*61577, f089*/ +#define LV_SYMBOL_EXT_STAR_HALF_STROKE "\xEF\x97\x80" /*62912, f5c0*/ +#define LV_SYMBOL_EXT_STAR_OF_DAVID "\xEF\x9A\x9A" /*63130, f69a*/ +#define LV_SYMBOL_EXT_STAR_OF_LIFE "\xEF\x98\xA1" /*63009, f621*/ +#define LV_SYMBOL_EXT_STAYLINKED "\xEF\x8F\xB5" /*62453, f3f5*/ +#define LV_SYMBOL_EXT_STEAM "\xEF\x86\xB6" /*61878, f1b6*/ +#define LV_SYMBOL_EXT_STEAM_SYMBOL "\xEF\x8F\xB6" /*62454, f3f6*/ +#define LV_SYMBOL_EXT_STERLING_SIGN "\xEF\x85\x94" /*61780, f154*/ +#define LV_SYMBOL_EXT_STETHOSCOPE "\xEF\x83\xB1" /*61681, f0f1*/ +#define LV_SYMBOL_EXT_STICKER_MULE "\xEF\x8F\xB7" /*62455, f3f7*/ +#define LV_SYMBOL_EXT_STOP "\xEF\x81\x8D" /*61517, f04d*/ +#define LV_SYMBOL_EXT_STOPWATCH "\xEF\x8B\xB2" /*62194, f2f2*/ +#define LV_SYMBOL_EXT_STOPWATCH_20 "\xEE\x81\xAF" /*57455, e06f*/ +#define LV_SYMBOL_EXT_STORE "\xEF\x95\x8E" /*62798, f54e*/ +#define LV_SYMBOL_EXT_STORE_SLASH "\xEE\x81\xB1" /*57457, e071*/ +#define LV_SYMBOL_EXT_STRAVA "\xEF\x90\xA8" /*62504, f428*/ +#define LV_SYMBOL_EXT_STREET_VIEW "\xEF\x88\x9D" /*61981, f21d*/ +#define LV_SYMBOL_EXT_STRIKETHROUGH "\xEF\x83\x8C" /*61644, f0cc*/ +#define LV_SYMBOL_EXT_STRIPE "\xEF\x90\xA9" /*62505, f429*/ +#define LV_SYMBOL_EXT_STRIPE_S "\xEF\x90\xAA" /*62506, f42a*/ +#define LV_SYMBOL_EXT_STROOPWAFEL "\xEF\x95\x91" /*62801, f551*/ +#define LV_SYMBOL_EXT_STUBBER "\xEE\x97\x87" /*58823, e5c7*/ +#define LV_SYMBOL_EXT_STUDIOVINARI "\xEF\x8F\xB8" /*62456, f3f8*/ +#define LV_SYMBOL_EXT_STUMBLEUPON "\xEF\x86\xA4" /*61860, f1a4*/ +#define LV_SYMBOL_EXT_STUMBLEUPON_CIRCLE "\xEF\x86\xA3" /*61859, f1a3*/ +#define LV_SYMBOL_EXT_SUBSCRIPT "\xEF\x84\xAC" /*61740, f12c*/ +#define LV_SYMBOL_EXT_SUITCASE "\xEF\x83\xB2" /*61682, f0f2*/ +#define LV_SYMBOL_EXT_SUITCASE_MEDICAL "\xEF\x83\xBA" /*61690, f0fa*/ +#define LV_SYMBOL_EXT_SUITCASE_ROLLING "\xEF\x97\x81" /*62913, f5c1*/ +#define LV_SYMBOL_EXT_SUN "\xEF\x86\x85" /*61829, f185*/ +#define LV_SYMBOL_EXT_SUN_PLANT_WILT "\xEE\x95\xBA" /*58746, e57a*/ +#define LV_SYMBOL_EXT_SUPERPOWERS "\xEF\x8B\x9D" /*62173, f2dd*/ +#define LV_SYMBOL_EXT_SUPERSCRIPT "\xEF\x84\xAB" /*61739, f12b*/ +#define LV_SYMBOL_EXT_SUPPLE "\xEF\x8F\xB9" /*62457, f3f9*/ +#define LV_SYMBOL_EXT_SUSE "\xEF\x9F\x96" /*63446, f7d6*/ +#define LV_SYMBOL_EXT_SWATCHBOOK "\xEF\x97\x83" /*62915, f5c3*/ +#define LV_SYMBOL_EXT_SWIFT "\xEF\xA3\xA1" /*63713, f8e1*/ +#define LV_SYMBOL_EXT_SYMFONY "\xEF\xA0\xBD" /*63549, f83d*/ +#define LV_SYMBOL_EXT_SYNAGOGUE "\xEF\x9A\x9B" /*63131, f69b*/ +#define LV_SYMBOL_EXT_SYRINGE "\xEF\x92\x8E" /*62606, f48e*/ +#define LV_SYMBOL_EXT_T "\x54" /*84, 54*/ +#define LV_SYMBOL_EXT_TABLE "\xEF\x83\x8E" /*61646, f0ce*/ +#define LV_SYMBOL_EXT_TABLE_CELLS "\xEF\x80\x8A" /*61450, f00a*/ +#define LV_SYMBOL_EXT_TABLE_CELLS_LARGE "\xEF\x80\x89" /*61449, f009*/ +#define LV_SYMBOL_EXT_TABLE_COLUMNS "\xEF\x83\x9B" /*61659, f0db*/ +#define LV_SYMBOL_EXT_TABLE_LIST "\xEF\x80\x8B" /*61451, f00b*/ +#define LV_SYMBOL_EXT_TABLE_TENNIS_PADDLE_BALL "\xEF\x91\x9D" /*62557, f45d*/ +#define LV_SYMBOL_EXT_TABLET "\xEF\x8F\xBB" /*62459, f3fb*/ +#define LV_SYMBOL_EXT_TABLET_BUTTON "\xEF\x84\x8A" /*61706, f10a*/ +#define LV_SYMBOL_EXT_TABLET_SCREEN_BUTTON "\xEF\x8F\xBA" /*62458, f3fa*/ +#define LV_SYMBOL_EXT_TABLETS "\xEF\x92\x90" /*62608, f490*/ +#define LV_SYMBOL_EXT_TACHOGRAPH_DIGITAL "\xEF\x95\xA6" /*62822, f566*/ +#define LV_SYMBOL_EXT_TAG "\xEF\x80\xAB" /*61483, f02b*/ +#define LV_SYMBOL_EXT_TAGS "\xEF\x80\xAC" /*61484, f02c*/ +#define LV_SYMBOL_EXT_TAPE "\xEF\x93\x9B" /*62683, f4db*/ +#define LV_SYMBOL_EXT_TARP "\xEE\x95\xBB" /*58747, e57b*/ +#define LV_SYMBOL_EXT_TARP_DROPLET "\xEE\x95\xBC" /*58748, e57c*/ +#define LV_SYMBOL_EXT_TAXI "\xEF\x86\xBA" /*61882, f1ba*/ +#define LV_SYMBOL_EXT_TEAMSPEAK "\xEF\x93\xB9" /*62713, f4f9*/ +#define LV_SYMBOL_EXT_TEETH "\xEF\x98\xAE" /*63022, f62e*/ +#define LV_SYMBOL_EXT_TEETH_OPEN "\xEF\x98\xAF" /*63023, f62f*/ +#define LV_SYMBOL_EXT_TELEGRAM "\xEF\x8B\x86" /*62150, f2c6*/ +#define LV_SYMBOL_EXT_TEMPERATURE_ARROW_DOWN "\xEE\x80\xBF" /*57407, e03f*/ +#define LV_SYMBOL_EXT_TEMPERATURE_ARROW_UP "\xEE\x81\x80" /*57408, e040*/ +#define LV_SYMBOL_EXT_TEMPERATURE_EMPTY "\xEF\x8B\x8B" /*62155, f2cb*/ +#define LV_SYMBOL_EXT_TEMPERATURE_FULL "\xEF\x8B\x87" /*62151, f2c7*/ +#define LV_SYMBOL_EXT_TEMPERATURE_HALF "\xEF\x8B\x89" /*62153, f2c9*/ +#define LV_SYMBOL_EXT_TEMPERATURE_HIGH "\xEF\x9D\xA9" /*63337, f769*/ +#define LV_SYMBOL_EXT_TEMPERATURE_LOW "\xEF\x9D\xAB" /*63339, f76b*/ +#define LV_SYMBOL_EXT_TEMPERATURE_QUARTER "\xEF\x8B\x8A" /*62154, f2ca*/ +#define LV_SYMBOL_EXT_TEMPERATURE_THREE_QUARTERS "\xEF\x8B\x88" /*62152, f2c8*/ +#define LV_SYMBOL_EXT_TENCENT_WEIBO "\xEF\x87\x95" /*61909, f1d5*/ +#define LV_SYMBOL_EXT_TENGE_SIGN "\xEF\x9F\x97" /*63447, f7d7*/ +#define LV_SYMBOL_EXT_TENT "\xEE\x95\xBD" /*58749, e57d*/ +#define LV_SYMBOL_EXT_TENT_ARROW_DOWN_TO_LINE "\xEE\x95\xBE" /*58750, e57e*/ +#define LV_SYMBOL_EXT_TENT_ARROW_LEFT_RIGHT "\xEE\x95\xBF" /*58751, e57f*/ +#define LV_SYMBOL_EXT_TENT_ARROW_TURN_LEFT "\xEE\x96\x80" /*58752, e580*/ +#define LV_SYMBOL_EXT_TENT_ARROWS_DOWN "\xEE\x96\x81" /*58753, e581*/ +#define LV_SYMBOL_EXT_TENTS "\xEE\x96\x82" /*58754, e582*/ +#define LV_SYMBOL_EXT_TERMINAL "\xEF\x84\xA0" /*61728, f120*/ +#define LV_SYMBOL_EXT_TEXT_HEIGHT "\xEF\x80\xB4" /*61492, f034*/ +#define LV_SYMBOL_EXT_TEXT_SLASH "\xEF\xA1\xBD" /*63613, f87d*/ +#define LV_SYMBOL_EXT_TEXT_WIDTH "\xEF\x80\xB5" /*61493, f035*/ +#define LV_SYMBOL_EXT_THE_RED_YETI "\xEF\x9A\x9D" /*63133, f69d*/ +#define LV_SYMBOL_EXT_THEMECO "\xEF\x97\x86" /*62918, f5c6*/ +#define LV_SYMBOL_EXT_THEMEISLE "\xEF\x8A\xB2" /*62130, f2b2*/ +#define LV_SYMBOL_EXT_THERMOMETER "\xEF\x92\x91" /*62609, f491*/ +#define LV_SYMBOL_EXT_THINK_PEAKS "\xEF\x9C\xB1" /*63281, f731*/ +#define LV_SYMBOL_EXT_THREADS "\xEE\x98\x98" /*58904, e618*/ +#define LV_SYMBOL_EXT_THUMBS_DOWN "\xEF\x85\xA5" /*61797, f165*/ +#define LV_SYMBOL_EXT_THUMBS_UP "\xEF\x85\xA4" /*61796, f164*/ +#define LV_SYMBOL_EXT_THUMBTACK "\xEF\x82\x8D" /*61581, f08d*/ +#define LV_SYMBOL_EXT_TICKET "\xEF\x85\x85" /*61765, f145*/ +#define LV_SYMBOL_EXT_TICKET_SIMPLE "\xEF\x8F\xBF" /*62463, f3ff*/ +#define LV_SYMBOL_EXT_TIKTOK "\xEE\x81\xBB" /*57467, e07b*/ +#define LV_SYMBOL_EXT_TIMELINE "\xEE\x8A\x9C" /*58012, e29c*/ +#define LV_SYMBOL_EXT_TOGGLE_OFF "\xEF\x88\x84" /*61956, f204*/ +#define LV_SYMBOL_EXT_TOGGLE_ON "\xEF\x88\x85" /*61957, f205*/ +#define LV_SYMBOL_EXT_TOILET "\xEF\x9F\x98" /*63448, f7d8*/ +#define LV_SYMBOL_EXT_TOILET_PAPER "\xEF\x9C\x9E" /*63262, f71e*/ +#define LV_SYMBOL_EXT_TOILET_PAPER_SLASH "\xEE\x81\xB2" /*57458, e072*/ +#define LV_SYMBOL_EXT_TOILET_PORTABLE "\xEE\x96\x83" /*58755, e583*/ +#define LV_SYMBOL_EXT_TOILETS_PORTABLE "\xEE\x96\x84" /*58756, e584*/ +#define LV_SYMBOL_EXT_TOOLBOX "\xEF\x95\x92" /*62802, f552*/ +#define LV_SYMBOL_EXT_TOOTH "\xEF\x97\x89" /*62921, f5c9*/ +#define LV_SYMBOL_EXT_TORII_GATE "\xEF\x9A\xA1" /*63137, f6a1*/ +#define LV_SYMBOL_EXT_TORNADO "\xEF\x9D\xAF" /*63343, f76f*/ +#define LV_SYMBOL_EXT_TOWER_BROADCAST "\xEF\x94\x99" /*62745, f519*/ +#define LV_SYMBOL_EXT_TOWER_CELL "\xEE\x96\x85" /*58757, e585*/ +#define LV_SYMBOL_EXT_TOWER_OBSERVATION "\xEE\x96\x86" /*58758, e586*/ +#define LV_SYMBOL_EXT_TRACTOR "\xEF\x9C\xA2" /*63266, f722*/ +#define LV_SYMBOL_EXT_TRADE_FEDERATION "\xEF\x94\x93" /*62739, f513*/ +#define LV_SYMBOL_EXT_TRADEMARK "\xEF\x89\x9C" /*62044, f25c*/ +#define LV_SYMBOL_EXT_TRAFFIC_LIGHT "\xEF\x98\xB7" /*63031, f637*/ +#define LV_SYMBOL_EXT_TRAILER "\xEE\x81\x81" /*57409, e041*/ +#define LV_SYMBOL_EXT_TRAIN "\xEF\x88\xB8" /*62008, f238*/ +#define LV_SYMBOL_EXT_TRAIN_SUBWAY "\xEF\x88\xB9" /*62009, f239*/ +#define LV_SYMBOL_EXT_TRAIN_TRAM "\xEE\x96\xB4" /*58804, e5b4*/ +#define LV_SYMBOL_EXT_TRANSGENDER "\xEF\x88\xA5" /*61989, f225*/ +#define LV_SYMBOL_EXT_TRASH "\xEF\x87\xB8" /*61944, f1f8*/ +#define LV_SYMBOL_EXT_TRASH_ARROW_UP "\xEF\xA0\xA9" /*63529, f829*/ +#define LV_SYMBOL_EXT_TRASH_CAN "\xEF\x8B\xAD" /*62189, f2ed*/ +#define LV_SYMBOL_EXT_TRASH_CAN_ARROW_UP "\xEF\xA0\xAA" /*63530, f82a*/ +#define LV_SYMBOL_EXT_TREE "\xEF\x86\xBB" /*61883, f1bb*/ +#define LV_SYMBOL_EXT_TREE_CITY "\xEE\x96\x87" /*58759, e587*/ +#define LV_SYMBOL_EXT_TRELLO "\xEF\x86\x81" /*61825, f181*/ +#define LV_SYMBOL_EXT_TRIANGLE_EXCLAMATION "\xEF\x81\xB1" /*61553, f071*/ +#define LV_SYMBOL_EXT_TROPHY "\xEF\x82\x91" /*61585, f091*/ +#define LV_SYMBOL_EXT_TROWEL "\xEE\x96\x89" /*58761, e589*/ +#define LV_SYMBOL_EXT_TROWEL_BRICKS "\xEE\x96\x8A" /*58762, e58a*/ +#define LV_SYMBOL_EXT_TRUCK "\xEF\x83\x91" /*61649, f0d1*/ +#define LV_SYMBOL_EXT_TRUCK_ARROW_RIGHT "\xEE\x96\x8B" /*58763, e58b*/ +#define LV_SYMBOL_EXT_TRUCK_DROPLET "\xEE\x96\x8C" /*58764, e58c*/ +#define LV_SYMBOL_EXT_TRUCK_FAST "\xEF\x92\x8B" /*62603, f48b*/ +#define LV_SYMBOL_EXT_TRUCK_FIELD "\xEE\x96\x8D" /*58765, e58d*/ +#define LV_SYMBOL_EXT_TRUCK_FIELD_UN "\xEE\x96\x8E" /*58766, e58e*/ +#define LV_SYMBOL_EXT_TRUCK_FRONT "\xEE\x8A\xB7" /*58039, e2b7*/ +#define LV_SYMBOL_EXT_TRUCK_MEDICAL "\xEF\x83\xB9" /*61689, f0f9*/ +#define LV_SYMBOL_EXT_TRUCK_MONSTER "\xEF\x98\xBB" /*63035, f63b*/ +#define LV_SYMBOL_EXT_TRUCK_MOVING "\xEF\x93\x9F" /*62687, f4df*/ +#define LV_SYMBOL_EXT_TRUCK_PICKUP "\xEF\x98\xBC" /*63036, f63c*/ +#define LV_SYMBOL_EXT_TRUCK_PLANE "\xEE\x96\x8F" /*58767, e58f*/ +#define LV_SYMBOL_EXT_TRUCK_RAMP_BOX "\xEF\x93\x9E" /*62686, f4de*/ +#define LV_SYMBOL_EXT_TTY "\xEF\x87\xA4" /*61924, f1e4*/ +#define LV_SYMBOL_EXT_TUMBLR "\xEF\x85\xB3" /*61811, f173*/ +#define LV_SYMBOL_EXT_TURKISH_LIRA_SIGN "\xEE\x8A\xBB" /*58043, e2bb*/ +#define LV_SYMBOL_EXT_TURN_DOWN "\xEF\x8E\xBE" /*62398, f3be*/ +#define LV_SYMBOL_EXT_TURN_UP "\xEF\x8E\xBF" /*62399, f3bf*/ +#define LV_SYMBOL_EXT_TV "\xEF\x89\xAC" /*62060, f26c*/ +#define LV_SYMBOL_EXT_TWITCH "\xEF\x87\xA8" /*61928, f1e8*/ +#define LV_SYMBOL_EXT_TWITTER "\xEF\x82\x99" /*61593, f099*/ +#define LV_SYMBOL_EXT_TYPO3 "\xEF\x90\xAB" /*62507, f42b*/ +#define LV_SYMBOL_EXT_U "\x55" /*85, 55*/ +#define LV_SYMBOL_EXT_UBER "\xEF\x90\x82" /*62466, f402*/ +#define LV_SYMBOL_EXT_UBUNTU "\xEF\x9F\x9F" /*63455, f7df*/ +#define LV_SYMBOL_EXT_UIKIT "\xEF\x90\x83" /*62467, f403*/ +#define LV_SYMBOL_EXT_UMBRACO "\xEF\xA3\xA8" /*63720, f8e8*/ +#define LV_SYMBOL_EXT_UMBRELLA "\xEF\x83\xA9" /*61673, f0e9*/ +#define LV_SYMBOL_EXT_UMBRELLA_BEACH "\xEF\x97\x8A" /*62922, f5ca*/ +#define LV_SYMBOL_EXT_UNCHARTED "\xEE\x82\x84" /*57476, e084*/ +#define LV_SYMBOL_EXT_UNDERLINE "\xEF\x83\x8D" /*61645, f0cd*/ +#define LV_SYMBOL_EXT_UNIREGISTRY "\xEF\x90\x84" /*62468, f404*/ +#define LV_SYMBOL_EXT_UNITY "\xEE\x81\x89" /*57417, e049*/ +#define LV_SYMBOL_EXT_UNIVERSAL_ACCESS "\xEF\x8A\x9A" /*62106, f29a*/ +#define LV_SYMBOL_EXT_UNLOCK "\xEF\x82\x9C" /*61596, f09c*/ +#define LV_SYMBOL_EXT_UNLOCK_KEYHOLE "\xEF\x84\xBE" /*61758, f13e*/ +#define LV_SYMBOL_EXT_UNSPLASH "\xEE\x81\xBC" /*57468, e07c*/ +#define LV_SYMBOL_EXT_UNTAPPD "\xEF\x90\x85" /*62469, f405*/ +#define LV_SYMBOL_EXT_UP_DOWN "\xEF\x8C\xB8" /*62264, f338*/ +#define LV_SYMBOL_EXT_UP_DOWN_LEFT_RIGHT "\xEF\x82\xB2" /*61618, f0b2*/ +#define LV_SYMBOL_EXT_UP_LONG "\xEF\x8C\x8C" /*62220, f30c*/ +#define LV_SYMBOL_EXT_UP_RIGHT_AND_DOWN_LEFT_FROM_CENTER "\xEF\x90\xA4" /*62500, f424*/ +#define LV_SYMBOL_EXT_UP_RIGHT_FROM_SQUARE "\xEF\x8D\x9D" /*62301, f35d*/ +#define LV_SYMBOL_EXT_UPLOAD "\xEF\x82\x93" /*61587, f093*/ +#define LV_SYMBOL_EXT_UPS "\xEF\x9F\xA0" /*63456, f7e0*/ +#define LV_SYMBOL_EXT_UPWORK "\xEE\x99\x81" /*58945, e641*/ +#define LV_SYMBOL_EXT_USB "\xEF\x8A\x87" /*62087, f287*/ +#define LV_SYMBOL_EXT_USER "\xEF\x80\x87" /*61447, f007*/ +#define LV_SYMBOL_EXT_USER_ASTRONAUT "\xEF\x93\xBB" /*62715, f4fb*/ +#define LV_SYMBOL_EXT_USER_CHECK "\xEF\x93\xBC" /*62716, f4fc*/ +#define LV_SYMBOL_EXT_USER_CLOCK "\xEF\x93\xBD" /*62717, f4fd*/ +#define LV_SYMBOL_EXT_USER_DOCTOR "\xEF\x83\xB0" /*61680, f0f0*/ +#define LV_SYMBOL_EXT_USER_GEAR "\xEF\x93\xBE" /*62718, f4fe*/ +#define LV_SYMBOL_EXT_USER_GRADUATE "\xEF\x94\x81" /*62721, f501*/ +#define LV_SYMBOL_EXT_USER_GROUP "\xEF\x94\x80" /*62720, f500*/ +#define LV_SYMBOL_EXT_USER_INJURED "\xEF\x9C\xA8" /*63272, f728*/ +#define LV_SYMBOL_EXT_USER_LARGE "\xEF\x90\x86" /*62470, f406*/ +#define LV_SYMBOL_EXT_USER_LARGE_SLASH "\xEF\x93\xBA" /*62714, f4fa*/ +#define LV_SYMBOL_EXT_USER_LOCK "\xEF\x94\x82" /*62722, f502*/ +#define LV_SYMBOL_EXT_USER_MINUS "\xEF\x94\x83" /*62723, f503*/ +#define LV_SYMBOL_EXT_USER_NINJA "\xEF\x94\x84" /*62724, f504*/ +#define LV_SYMBOL_EXT_USER_NURSE "\xEF\xA0\xAF" /*63535, f82f*/ +#define LV_SYMBOL_EXT_USER_PEN "\xEF\x93\xBF" /*62719, f4ff*/ +#define LV_SYMBOL_EXT_USER_PLUS "\xEF\x88\xB4" /*62004, f234*/ +#define LV_SYMBOL_EXT_USER_SECRET "\xEF\x88\x9B" /*61979, f21b*/ +#define LV_SYMBOL_EXT_USER_SHIELD "\xEF\x94\x85" /*62725, f505*/ +#define LV_SYMBOL_EXT_USER_SLASH "\xEF\x94\x86" /*62726, f506*/ +#define LV_SYMBOL_EXT_USER_TAG "\xEF\x94\x87" /*62727, f507*/ +#define LV_SYMBOL_EXT_USER_TIE "\xEF\x94\x88" /*62728, f508*/ +#define LV_SYMBOL_EXT_USER_XMARK "\xEF\x88\xB5" /*62005, f235*/ +#define LV_SYMBOL_EXT_USERS "\xEF\x83\x80" /*61632, f0c0*/ +#define LV_SYMBOL_EXT_USERS_BETWEEN_LINES "\xEE\x96\x91" /*58769, e591*/ +#define LV_SYMBOL_EXT_USERS_GEAR "\xEF\x94\x89" /*62729, f509*/ +#define LV_SYMBOL_EXT_USERS_LINE "\xEE\x96\x92" /*58770, e592*/ +#define LV_SYMBOL_EXT_USERS_RAYS "\xEE\x96\x93" /*58771, e593*/ +#define LV_SYMBOL_EXT_USERS_RECTANGLE "\xEE\x96\x94" /*58772, e594*/ +#define LV_SYMBOL_EXT_USERS_SLASH "\xEE\x81\xB3" /*57459, e073*/ +#define LV_SYMBOL_EXT_USERS_VIEWFINDER "\xEE\x96\x95" /*58773, e595*/ +#define LV_SYMBOL_EXT_USPS "\xEF\x9F\xA1" /*63457, f7e1*/ +#define LV_SYMBOL_EXT_USSUNNAH "\xEF\x90\x87" /*62471, f407*/ +#define LV_SYMBOL_EXT_UTENSILS "\xEF\x8B\xA7" /*62183, f2e7*/ +#define LV_SYMBOL_EXT_V "\x56" /*86, 56*/ +#define LV_SYMBOL_EXT_VAADIN "\xEF\x90\x88" /*62472, f408*/ +#define LV_SYMBOL_EXT_VAN_SHUTTLE "\xEF\x96\xB6" /*62902, f5b6*/ +#define LV_SYMBOL_EXT_VAULT "\xEE\x8B\x85" /*58053, e2c5*/ +#define LV_SYMBOL_EXT_VECTOR_SQUARE "\xEF\x97\x8B" /*62923, f5cb*/ +#define LV_SYMBOL_EXT_VENUS "\xEF\x88\xA1" /*61985, f221*/ +#define LV_SYMBOL_EXT_VENUS_DOUBLE "\xEF\x88\xA6" /*61990, f226*/ +#define LV_SYMBOL_EXT_VENUS_MARS "\xEF\x88\xA8" /*61992, f228*/ +#define LV_SYMBOL_EXT_VEST "\xEE\x82\x85" /*57477, e085*/ +#define LV_SYMBOL_EXT_VEST_PATCHES "\xEE\x82\x86" /*57478, e086*/ +#define LV_SYMBOL_EXT_VIACOIN "\xEF\x88\xB7" /*62007, f237*/ +#define LV_SYMBOL_EXT_VIADEO "\xEF\x8A\xA9" /*62121, f2a9*/ +#define LV_SYMBOL_EXT_VIAL "\xEF\x92\x92" /*62610, f492*/ +#define LV_SYMBOL_EXT_VIAL_CIRCLE_CHECK "\xEE\x96\x96" /*58774, e596*/ +#define LV_SYMBOL_EXT_VIAL_VIRUS "\xEE\x96\x97" /*58775, e597*/ +#define LV_SYMBOL_EXT_VIALS "\xEF\x92\x93" /*62611, f493*/ +#define LV_SYMBOL_EXT_VIBER "\xEF\x90\x89" /*62473, f409*/ +#define LV_SYMBOL_EXT_VIDEO "\xEF\x80\xBD" /*61501, f03d*/ +#define LV_SYMBOL_EXT_VIDEO_SLASH "\xEF\x93\xA2" /*62690, f4e2*/ +#define LV_SYMBOL_EXT_VIHARA "\xEF\x9A\xA7" /*63143, f6a7*/ +#define LV_SYMBOL_EXT_VIMEO "\xEF\x90\x8A" /*62474, f40a*/ +#define LV_SYMBOL_EXT_VIMEO_V "\xEF\x89\xBD" /*62077, f27d*/ +#define LV_SYMBOL_EXT_VINE "\xEF\x87\x8A" /*61898, f1ca*/ +#define LV_SYMBOL_EXT_VIRUS "\xEE\x81\xB4" /*57460, e074*/ +#define LV_SYMBOL_EXT_VIRUS_COVID "\xEE\x92\xA8" /*58536, e4a8*/ +#define LV_SYMBOL_EXT_VIRUS_COVID_SLASH "\xEE\x92\xA9" /*58537, e4a9*/ +#define LV_SYMBOL_EXT_VIRUS_SLASH "\xEE\x81\xB5" /*57461, e075*/ +#define LV_SYMBOL_EXT_VIRUSES "\xEE\x81\xB6" /*57462, e076*/ +#define LV_SYMBOL_EXT_VK "\xEF\x86\x89" /*61833, f189*/ +#define LV_SYMBOL_EXT_VNV "\xEF\x90\x8B" /*62475, f40b*/ +#define LV_SYMBOL_EXT_VOICEMAIL "\xEF\xA2\x97" /*63639, f897*/ +#define LV_SYMBOL_EXT_VOLCANO "\xEF\x9D\xB0" /*63344, f770*/ +#define LV_SYMBOL_EXT_VOLLEYBALL "\xEF\x91\x9F" /*62559, f45f*/ +#define LV_SYMBOL_EXT_VOLUME_HIGH "\xEF\x80\xA8" /*61480, f028*/ +#define LV_SYMBOL_EXT_VOLUME_LOW "\xEF\x80\xA7" /*61479, f027*/ +#define LV_SYMBOL_EXT_VOLUME_OFF "\xEF\x80\xA6" /*61478, f026*/ +#define LV_SYMBOL_EXT_VOLUME_XMARK "\xEF\x9A\xA9" /*63145, f6a9*/ +#define LV_SYMBOL_EXT_VR_CARDBOARD "\xEF\x9C\xA9" /*63273, f729*/ +#define LV_SYMBOL_EXT_VUEJS "\xEF\x90\x9F" /*62495, f41f*/ +#define LV_SYMBOL_EXT_W "\x57" /*87, 57*/ +#define LV_SYMBOL_EXT_WALKIE_TALKIE "\xEF\xA3\xAF" /*63727, f8ef*/ +#define LV_SYMBOL_EXT_WALLET "\xEF\x95\x95" /*62805, f555*/ +#define LV_SYMBOL_EXT_WAND_MAGIC "\xEF\x83\x90" /*61648, f0d0*/ +#define LV_SYMBOL_EXT_WAND_MAGIC_SPARKLES "\xEE\x8B\x8A" /*58058, e2ca*/ +#define LV_SYMBOL_EXT_WAND_SPARKLES "\xEF\x9C\xAB" /*63275, f72b*/ +#define LV_SYMBOL_EXT_WAREHOUSE "\xEF\x92\x94" /*62612, f494*/ +#define LV_SYMBOL_EXT_WATCHMAN_MONITORING "\xEE\x82\x87" /*57479, e087*/ +#define LV_SYMBOL_EXT_WATER "\xEF\x9D\xB3" /*63347, f773*/ +#define LV_SYMBOL_EXT_WATER_LADDER "\xEF\x97\x85" /*62917, f5c5*/ +#define LV_SYMBOL_EXT_WAVE_SQUARE "\xEF\xA0\xBE" /*63550, f83e*/ +#define LV_SYMBOL_EXT_WAZE "\xEF\xA0\xBF" /*63551, f83f*/ +#define LV_SYMBOL_EXT_WEBFLOW "\xEE\x99\x9C" /*58972, e65c*/ +#define LV_SYMBOL_EXT_WEEBLY "\xEF\x97\x8C" /*62924, f5cc*/ +#define LV_SYMBOL_EXT_WEIBO "\xEF\x86\x8A" /*61834, f18a*/ +#define LV_SYMBOL_EXT_WEIGHT_HANGING "\xEF\x97\x8D" /*62925, f5cd*/ +#define LV_SYMBOL_EXT_WEIGHT_SCALE "\xEF\x92\x96" /*62614, f496*/ +#define LV_SYMBOL_EXT_WEIXIN "\xEF\x87\x97" /*61911, f1d7*/ +#define LV_SYMBOL_EXT_WHATSAPP "\xEF\x88\xB2" /*62002, f232*/ +#define LV_SYMBOL_EXT_WHEAT_AWN "\xEE\x8B\x8D" /*58061, e2cd*/ +#define LV_SYMBOL_EXT_WHEAT_AWN_CIRCLE_EXCLAMATION "\xEE\x96\x98" /*58776, e598*/ +#define LV_SYMBOL_EXT_WHEELCHAIR "\xEF\x86\x93" /*61843, f193*/ +#define LV_SYMBOL_EXT_WHEELCHAIR_MOVE "\xEE\x8B\x8E" /*58062, e2ce*/ +#define LV_SYMBOL_EXT_WHISKEY_GLASS "\xEF\x9E\xA0" /*63392, f7a0*/ +#define LV_SYMBOL_EXT_WHMCS "\xEF\x90\x8D" /*62477, f40d*/ +#define LV_SYMBOL_EXT_WIFI "\xEF\x87\xAB" /*61931, f1eb*/ +#define LV_SYMBOL_EXT_WIKIPEDIA_W "\xEF\x89\xA6" /*62054, f266*/ +#define LV_SYMBOL_EXT_WIND "\xEF\x9C\xAE" /*63278, f72e*/ +#define LV_SYMBOL_EXT_WINDOW_MAXIMIZE "\xEF\x8B\x90" /*62160, f2d0*/ +#define LV_SYMBOL_EXT_WINDOW_MINIMIZE "\xEF\x8B\x91" /*62161, f2d1*/ +#define LV_SYMBOL_EXT_WINDOW_RESTORE "\xEF\x8B\x92" /*62162, f2d2*/ +#define LV_SYMBOL_EXT_WINDOWS "\xEF\x85\xBA" /*61818, f17a*/ +#define LV_SYMBOL_EXT_WINE_BOTTLE "\xEF\x9C\xAF" /*63279, f72f*/ +#define LV_SYMBOL_EXT_WINE_GLASS "\xEF\x93\xA3" /*62691, f4e3*/ +#define LV_SYMBOL_EXT_WINE_GLASS_EMPTY "\xEF\x97\x8E" /*62926, f5ce*/ +#define LV_SYMBOL_EXT_WIRSINDHANDWERK "\xEE\x8B\x90" /*58064, e2d0*/ +#define LV_SYMBOL_EXT_WIX "\xEF\x97\x8F" /*62927, f5cf*/ +#define LV_SYMBOL_EXT_WIZARDS_OF_THE_COAST "\xEF\x9C\xB0" /*63280, f730*/ +#define LV_SYMBOL_EXT_WODU "\xEE\x82\x88" /*57480, e088*/ +#define LV_SYMBOL_EXT_WOLF_PACK_BATTALION "\xEF\x94\x94" /*62740, f514*/ +#define LV_SYMBOL_EXT_WON_SIGN "\xEF\x85\x99" /*61785, f159*/ +#define LV_SYMBOL_EXT_WORDPRESS "\xEF\x86\x9A" /*61850, f19a*/ +#define LV_SYMBOL_EXT_WORDPRESS_SIMPLE "\xEF\x90\x91" /*62481, f411*/ +#define LV_SYMBOL_EXT_WORM "\xEE\x96\x99" /*58777, e599*/ +#define LV_SYMBOL_EXT_WPBEGINNER "\xEF\x8A\x97" /*62103, f297*/ +#define LV_SYMBOL_EXT_WPEXPLORER "\xEF\x8B\x9E" /*62174, f2de*/ +#define LV_SYMBOL_EXT_WPFORMS "\xEF\x8A\x98" /*62104, f298*/ +#define LV_SYMBOL_EXT_WPRESSR "\xEF\x8F\xA4" /*62436, f3e4*/ +#define LV_SYMBOL_EXT_WRENCH "\xEF\x82\xAD" /*61613, f0ad*/ +#define LV_SYMBOL_EXT_X "\x58" /*88, 58*/ +#define LV_SYMBOL_EXT_X_RAY "\xEF\x92\x97" /*62615, f497*/ +#define LV_SYMBOL_EXT_X_TWITTER "\xEE\x98\x9B" /*58907, e61b*/ +#define LV_SYMBOL_EXT_XBOX "\xEF\x90\x92" /*62482, f412*/ +#define LV_SYMBOL_EXT_XING "\xEF\x85\xA8" /*61800, f168*/ +#define LV_SYMBOL_EXT_XMARK "\xEF\x80\x8D" /*61453, f00d*/ +#define LV_SYMBOL_EXT_XMARKS_LINES "\xEE\x96\x9A" /*58778, e59a*/ +#define LV_SYMBOL_EXT_Y "\x59" /*89, 59*/ +#define LV_SYMBOL_EXT_Y_COMBINATOR "\xEF\x88\xBB" /*62011, f23b*/ +#define LV_SYMBOL_EXT_YAHOO "\xEF\x86\x9E" /*61854, f19e*/ +#define LV_SYMBOL_EXT_YAMMER "\xEF\xA1\x80" /*63552, f840*/ +#define LV_SYMBOL_EXT_YANDEX "\xEF\x90\x93" /*62483, f413*/ +#define LV_SYMBOL_EXT_YANDEX_INTERNATIONAL "\xEF\x90\x94" /*62484, f414*/ +#define LV_SYMBOL_EXT_YARN "\xEF\x9F\xA3" /*63459, f7e3*/ +#define LV_SYMBOL_EXT_YELP "\xEF\x87\xA9" /*61929, f1e9*/ +#define LV_SYMBOL_EXT_YEN_SIGN "\xEF\x85\x97" /*61783, f157*/ +#define LV_SYMBOL_EXT_YIN_YANG "\xEF\x9A\xAD" /*63149, f6ad*/ +#define LV_SYMBOL_EXT_YOAST "\xEF\x8A\xB1" /*62129, f2b1*/ +#define LV_SYMBOL_EXT_YOUTUBE "\xEF\x85\xA7" /*61799, f167*/ +#define LV_SYMBOL_EXT_Z "\x5A" /*90, 5a*/ +#define LV_SYMBOL_EXT_ZHIHU "\xEF\x98\xBF" /*63039, f63f*/ + +#endif /* LV_SYMBOL_EXT_DEF */ \ No newline at end of file diff --git a/x_track/src/App/UI/Shutdown/Shutdown.cpp b/x_track/src/App/UI/Shutdown/Shutdown.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e18400e93f14562b7c9ab5a9ffd702e5d4a0ec00 --- /dev/null +++ b/x_track/src/App/UI/Shutdown/Shutdown.cpp @@ -0,0 +1,131 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Shutdown.h" +#include "../Startup/Startup.h" + +using namespace Page; + +APP_DESCRIPTOR_DEF(Shutdown); + +Shutdown::Shutdown() + : _model(nullptr) + , _view(nullptr) +{ +} + +Shutdown::~Shutdown() +{ +} + +void Shutdown::onInstalled() +{ + setLoadAnimType(PAGE_ANIM::OVER_TOP); +} + +void Shutdown::onViewLoad() +{ + _model = new ShutdownModel(this); + _view = new ShutdownView(this, getRoot()); +} + +void Shutdown::onViewDidLoad() +{ +} + +void Shutdown::onViewWillAppear() +{ + _model->setInterceptPageNavi(true); + _model->feedback()->trigger(DataProc::FEEDBACK_GEN_EFFECT::NOTIFICATION_WARNING); +} + +void Shutdown::onViewDidAppear() +{ + _model->env()->set("statusbar", "disable"); + _model->env()->set("navibar", "enable"); + _model->env()->set("pagenavi", "enable"); +} + +void Shutdown::onViewWillDisappear() +{ +} + +void Shutdown::onViewDidDisappear() +{ + _model->setInterceptPageNavi(false); +} + +void Shutdown::onViewUnload() +{ + delete _model; + delete _view; +} + +void Shutdown::onViewDidUnload() +{ +} + +void Shutdown::onModelEvent(ShutdownModel::EVENT_ID id, const void* param) +{ + switch (id) { + case ShutdownModel::EVENT_ID::PAGE_NAVI: { + _model->feedback()->trigger(DataProc::FEEDBACK_GEN_EFFECT::IMPACT_LIGHT); + getManager()->pop(); + } break; + + default: + break; + } +} + +void Shutdown::onViewEvent(ShutdownView::EVENT_ID id, const void* param) +{ + switch (id) { + case ShutdownView::EVENT_ID::READY: + _model->feedback()->trigger(DataProc::FEEDBACK_GEN_EFFECT::SELECTION); + break; + case ShutdownView::EVENT_ID::SHUTDOWN: { + if(_model->checkShutdownDisable()) { + LV_LOG_WARN("Shutdown disabled by user"); + return; + } + + _model->setInterceptPageNavi(false); + + /* Let Startup page show shoutdown animation */ + Startup::Param_t startupParam; + startupParam.shutdown = true; + PARAM pageParam = PAGE_PARAM_MAKE(startupParam); + getManager()->push("Startup", &pageParam); + + _model->feedback()->trigger(DataProc::FEEDBACK_GEN_EFFECT::NOTIFICATION_ERROR); + _model->env()->set("navibar", "disable"); + _model->shutdown(); + } break; + case ShutdownView::EVENT_ID::EXIT: + getManager()->pop(); + break; + + default: + break; + } +} diff --git a/x_track/src/App/UI/Shutdown/Shutdown.h b/x_track/src/App/UI/Shutdown/Shutdown.h new file mode 100644 index 0000000000000000000000000000000000000000..db2c02ae4c4f4c09593be2f8e2bcefdac7a5be91 --- /dev/null +++ b/x_track/src/App/UI/Shutdown/Shutdown.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SHUTDOWN_PRESENTER_H +#define __SHUTDOWN_PRESENTER_H + +#include "ShutdownModel.h" +#include "ShutdownView.h" + +namespace Page { + +class Shutdown : public PageBase, public ShutdownModel::EventListener, public ShutdownView::EventListener { +public: + Shutdown(); + virtual ~Shutdown(); + + virtual void onInstalled(); + virtual void onViewLoad(); + virtual void onViewDidLoad(); + virtual void onViewWillAppear(); + virtual void onViewDidAppear(); + virtual void onViewWillDisappear(); + virtual void onViewDidDisappear(); + virtual void onViewUnload(); + virtual void onViewDidUnload(); + +private: + virtual void onModelEvent(ShutdownModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(ShutdownView::EVENT_ID id, const void* param) override; + +private: + ShutdownModel* _model; + ShutdownView* _view; +}; + +} + +#endif /* __SHUTDOWN_PRESENTER_H */ diff --git a/x_track/src/App/UI/Shutdown/ShutdownModel.cpp b/x_track/src/App/UI/Shutdown/ShutdownModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..70d4df735ed4c5fff4479116fbea6d2fdece4e7b --- /dev/null +++ b/x_track/src/App/UI/Shutdown/ShutdownModel.cpp @@ -0,0 +1,78 @@ + +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "ShutdownModel.h" + +using namespace Page; + +ShutdownModel::ShutdownModel(EventListener* listener) + : DataNode(__func__, DataProc::broker()) + , _env(this) + , _feedback(this) + , _listener(listener) + , _interceptPageNavi(false) +{ + _nodePower = subscribe("Power"); + _nodePageNavi = subscribe("PageNavi"); + + setEventFilter(DataNode::EVENT_PUBLISH); +} + +ShutdownModel::~ShutdownModel() +{ +} + +int ShutdownModel::shutdown() +{ + DataProc::Power_Info_t info; + info.delayShutdownTime = 3000; + info.cmd = DataProc::POWER_CMD::SHUTDOWN; + return notify(_nodePower, &info, sizeof(info)); +} + +void ShutdownModel::setInterceptPageNavi(bool en) +{ + _interceptPageNavi = en; +} + +bool ShutdownModel::checkShutdownDisable() +{ + auto value = _env.get("shutdown"); + if (!value) { + return false; + } + + return (strcmp(value, "disable") == 0); +} + +int ShutdownModel::onEvent(DataNode::EventParam_t* param) +{ + if (_interceptPageNavi && param->tran == _nodePageNavi) { + auto info = (const DataProc::PageNavi_Info_t*)param->data_p; + if (info->cmd == DataProc::PAGE_NAVI_CMD::PUSH) { + _listener->onModelEvent(EVENT_ID::PAGE_NAVI); + } + } + + return DataNode::RES_OK; +} diff --git a/x_track/src/App/UI/Shutdown/ShutdownModel.h b/x_track/src/App/UI/Shutdown/ShutdownModel.h new file mode 100644 index 0000000000000000000000000000000000000000..4a20a5039f6cb6a304cfa0c573c28e191d0bdcb4 --- /dev/null +++ b/x_track/src/App/UI/Shutdown/ShutdownModel.h @@ -0,0 +1,73 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SHUTDOWN_MODEL_H +#define __SHUTDOWN_MODEL_H + +#include "Service/DataProc/DataProc.h" + +namespace Page { + +class ShutdownModel : private DataNode { +public: + enum class EVENT_ID { + PAGE_NAVI, /* param: None */ + _LAST, + }; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + ShutdownModel(EventListener* listener); + ~ShutdownModel(); + int shutdown(); + void setInterceptPageNavi(bool en); + bool checkShutdownDisable(); + + DataProc::Env_Helper* env() + { + return &_env; + } + + DataProc::FeedbackGen_Helper* feedback() + { + return &_feedback; + } + +private: + DataProc::Env_Helper _env; + DataProc::FeedbackGen_Helper _feedback; + const DataNode* _nodePower; + const DataNode* _nodePageNavi; + EventListener* _listener; + bool _interceptPageNavi; + +private: + virtual int onEvent(DataNode::EventParam_t* param); +}; + +} + +#endif /* __SHUTDOWN_MODEL_H */ diff --git a/x_track/src/App/UI/Shutdown/ShutdownView.cpp b/x_track/src/App/UI/Shutdown/ShutdownView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21a83b4320a000705d8cf634082e7afc9bc2632d --- /dev/null +++ b/x_track/src/App/UI/Shutdown/ShutdownView.cpp @@ -0,0 +1,125 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "ShutdownView.h" + +using namespace Page; + +ShutdownView::ShutdownView(EventListener* listener, lv_obj_t* root) + : _listener(listener) +{ + lv_obj_add_event( + root, + [](lv_event_t* e) { + auto self = (ShutdownView*)lv_event_get_user_data(e); + self->_listener->onViewEvent(EVENT_ID::EXIT); + }, + LV_EVENT_CLICKED, + this); + + /* cont */ + lv_obj_t* cont = lv_obj_create(root); + { + lv_obj_set_size(cont, 60, lv_pct(50)); + + lv_obj_center(cont); + lv_obj_set_style_radius(cont, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_pad_hor(cont, 0, 0); + lv_obj_set_style_pad_ver(cont, 28, 0); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* label = lv_label_create(cont); + lv_label_set_text_static(label, LV_SYMBOL_POWER); + lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_RED), 0); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, -10); + } + + /* label */ + { + lv_obj_t* label = lv_label_create(root); + + lv_label_set_text_static(label, _("POWER_OFF")); + lv_obj_set_style_text_font(label, lv_theme_get_font_large(label), 0); + lv_obj_align_to(label, cont, LV_ALIGN_OUT_TOP_MID, 0, -10); + } + + /* slider */ + lv_obj_t* slider = lv_slider_create(cont); + { + lv_obj_set_style_bg_opa(slider, LV_OPA_TRANSP, 0); + lv_obj_set_style_bg_opa(slider, LV_OPA_TRANSP, LV_PART_INDICATOR); + lv_obj_set_size(slider, lv_pct(50), lv_pct(100)); + lv_obj_center(slider); + + lv_obj_set_style_anim_time(slider, 300, 0); + lv_obj_set_style_bg_img_src(slider, LV_SYMBOL_UP, LV_PART_KNOB); + lv_obj_set_style_text_color(slider, lv_color_white(), LV_PART_KNOB); + + lv_obj_add_event( + slider, + [](lv_event_t* e) { + auto self = (ShutdownView*)lv_event_get_user_data(e); + auto obj = lv_event_get_current_target_obj(e); + auto value = lv_slider_get_value(obj); + + if (value == lv_slider_get_max_value(obj)) { + self->_listener->onViewEvent(EVENT_ID::SHUTDOWN, &value); + } else { + lv_slider_set_value(obj, lv_slider_get_min_value(obj), LV_ANIM_ON); + } + }, + LV_EVENT_RELEASED, this); + + lv_obj_add_event( + slider, + [](lv_event_t* e) { + auto self = (ShutdownView*)lv_event_get_user_data(e); + auto obj = lv_event_get_current_target_obj(e); + auto value = lv_slider_get_value(obj); + + if (value == lv_slider_get_max_value(obj)) { + self->_listener->onViewEvent(EVENT_ID::READY, &value); + } + }, + LV_EVENT_VALUE_CHANGED, this); + } +} + +ShutdownView::~ShutdownView() +{ +} + +lv_uintptr_t ShutdownView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void ShutdownView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void ShutdownView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} diff --git a/x_track/src/App/UI/Shutdown/ShutdownView.h b/x_track/src/App/UI/Shutdown/ShutdownView.h new file mode 100644 index 0000000000000000000000000000000000000000..a72f985d47939b033f2b21adb3125459f3185b83 --- /dev/null +++ b/x_track/src/App/UI/Shutdown/ShutdownView.h @@ -0,0 +1,63 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SHUTDOWN_VIEW_H +#define __SHUTDOWN_VIEW_H + +#include "../Page.h" + +namespace Page { + +class ShutdownView { +public: + enum class MSG_ID { + _LAST, + }; + + enum class EVENT_ID { + READY, + SHUTDOWN, + EXIT, + _LAST, + }; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + ShutdownView(EventListener* listener, lv_obj_t* root); + ~ShutdownView(); + void publish(MSG_ID id, const void* payload); + +private: + EventListener* _listener; + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); +}; + +} + +#endif /* __SHUTDOWN_VIEW_H */ diff --git a/x_track/src/App/UI/Startup/Startup.cpp b/x_track/src/App/UI/Startup/Startup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd4b7cc7ea1bf07387c6d2b77d0c5d491a300f2d --- /dev/null +++ b/x_track/src/App/UI/Startup/Startup.cpp @@ -0,0 +1,126 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Startup.h" +#include "UI/Dashboard/Dashboard.h" + +using namespace Page; + +APP_DESCRIPTOR_DEF(Startup); + +Startup::Startup() + : _model(nullptr) + , _view(nullptr) +{ +} + +Startup::~Startup() +{ +} + +void Startup::onInstalled() +{ + setCacheEnable(false); + setLoadAnimType(PAGE_ANIM::FADE_ON); +} + +void Startup::onViewLoad() +{ + _model = new StartupModel(this); + _view = new StartupView(this, getRoot()); +} + +void Startup::onViewDidLoad() +{ +} + +void Startup::onViewWillAppear() +{ + Param_t param = { 0 }; + PAGE_GET_PARAM(param); + + _view->publish(StartupView::MSG_ID::SHOW, (void*)(lv_uintptr_t)!param.shutdown); + + /* load ephemeris when animation is done */ + if (!param.shutdown) { + lv_timer_t* timer = lv_timer_create( + [](lv_timer_t* tmr) { + auto self = (Startup*)lv_timer_get_user_data(tmr); + self->readyToExit(); + }, + 1500, this); + lv_timer_set_repeat_count(timer, 1); + } +} + +void Startup::onViewDidAppear() +{ + _model->env()->set("navibar", "disable"); + _model->env()->set("statusbar", "disable"); + _model->env()->set("pagenavi", "disable"); +} + +void Startup::onViewWillDisappear() +{ +} + +void Startup::onViewDidDisappear() +{ +} + +void Startup::onViewUnload() +{ + delete _model; + delete _view; +} + +void Startup::onViewDidUnload() +{ +} + +void Startup::onModelEvent(StartupModel::EVENT_ID id, const void* param) +{ +} + +void Startup::onViewEvent(StartupView::EVENT_ID id, const void* param) +{ +} + +void Startup::readyToExit() +{ + /* wait fade out animation done */ + lv_timer_t* timer = lv_timer_create( + [](lv_timer_t* tmr) { + auto self = (Startup*)lv_timer_get_user_data(tmr); + self->onExitTimer(); + }, + 500, this); + lv_timer_set_repeat_count(timer, 1); +} + +void Startup::onExitTimer() +{ + Dashboard::Param_t dashBoardParam; + dashBoardParam.animEnable = true; + PARAM param = PAGE_PARAM_MAKE(dashBoardParam); + getManager()->replace("Dashboard", ¶m); +} diff --git a/x_track/src/App/UI/Startup/Startup.h b/x_track/src/App/UI/Startup/Startup.h new file mode 100644 index 0000000000000000000000000000000000000000..897c454df434ec80d2ef9a28761ac2ce1c0c4322 --- /dev/null +++ b/x_track/src/App/UI/Startup/Startup.h @@ -0,0 +1,65 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STARTUP_PRESENTER_H +#define __STARTUP_PRESENTER_H + +#include "StartupModel.h" +#include "StartupView.h" + +namespace Page { + +class Startup : public PageBase, public StartupModel::EventListener, public StartupView::EventListener { + +public: + typedef struct { + bool shutdown; + } Param_t; + +public: + Startup(); + virtual ~Startup(); + + virtual void onInstalled(); + virtual void onViewLoad(); + virtual void onViewDidLoad(); + virtual void onViewWillAppear(); + virtual void onViewDidAppear(); + virtual void onViewWillDisappear(); + virtual void onViewDidDisappear(); + virtual void onViewUnload(); + virtual void onViewDidUnload(); + +private: + virtual void onModelEvent(StartupModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(StartupView::EVENT_ID id, const void* param) override; + void readyToExit(); + void onExitTimer(); + +private: + StartupModel* _model; + StartupView* _view; +}; + +} + +#endif diff --git a/x_track/src/App/UI/Startup/StartupModel.cpp b/x_track/src/App/UI/Startup/StartupModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a1deb5ae976f357d93f449138bc4c4790bd230a --- /dev/null +++ b/x_track/src/App/UI/Startup/StartupModel.cpp @@ -0,0 +1,36 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "StartupModel.h" + +using namespace Page; + +StartupModel::StartupModel(EventListener* listener) + : _node(__func__, DataProc::broker(), this) + , _env(&_node) + , _listener(listener) +{ +} + +StartupModel::~StartupModel() +{ +} diff --git a/x_track/src/App/UI/Startup/StartupModel.h b/x_track/src/App/UI/Startup/StartupModel.h new file mode 100644 index 0000000000000000000000000000000000000000..4301cdf99a8cb9b998aeb83326af890473bcfd55 --- /dev/null +++ b/x_track/src/App/UI/Startup/StartupModel.h @@ -0,0 +1,54 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STARTUP_MODEL_H +#define __STARTUP_MODEL_H + +#include "Service/DataProc/DataProc.h" + +namespace Page { + +class StartupModel { +public: + enum class EVENT_ID { + _LAST, + }; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + StartupModel(EventListener* listener); + ~StartupModel(); + DataProc::Env_Helper* env() { return &_env; } + +private: + DataNode _node; + DataProc::Env_Helper _env; + EventListener* _listener; +}; + +} + +#endif diff --git a/x_track/src/App/UI/Startup/StartupView.cpp b/x_track/src/App/UI/Startup/StartupView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9e79ff4e37cfad7ec146dc925b14c0959a50bf5 --- /dev/null +++ b/x_track/src/App/UI/Startup/StartupView.cpp @@ -0,0 +1,115 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "StartupView.h" +#include "Utils/lv_ext/lv_anim_timeline_wrapper.h" +#include "Utils/lv_ext/lv_ext_func.h" +#include "Version.h" + +using namespace Page; + +#define COLOR_ORANGE lv_color_hex(0xff931e) + +StartupView::StartupView(EventListener* listener, lv_obj_t* root) + : _listener(listener) + , _font(36, "medium") +{ + static_assert(sizeof(StartupView) >= (size_t)MSG_ID::_LAST, "Large MSG_ID"); + + lv_obj_set_style_pad_all(root, 0, 0); + + lv_obj_t* cont = lv_obj_create(root); + lv_obj_remove_style_all(cont); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_border_color(cont, COLOR_ORANGE, 0); + lv_obj_set_style_border_side(cont, LV_BORDER_SIDE_BOTTOM, 0); + lv_obj_set_style_border_width(cont, 3, 0); + lv_obj_set_style_border_post(cont, true, 0); + lv_obj_center(cont); + + lv_obj_t* label = lv_label_create(cont); + lv_obj_set_style_text_font(label, _font, 0); + lv_label_set_text_static(label, VERSION_FIRMWARE_NAME); + + lv_obj_update_layout(label); + int32_t contWidth = lv_obj_get_width(label); + int32_t contHeight = lv_obj_get_height(label); + lv_obj_set_size(cont, contWidth, contHeight); + + _anim_timeline = lv_anim_timeline_create(); + + auto lv_obj_set_opa = [](void* obj, int32_t v) { + lv_obj_set_style_opa((lv_obj_t*)obj, v, 0); + }; + +#define ANIM_DEF(start_time, obj, attr, start, end) \ + { start_time, obj, LV_ANIM_EXEC(attr), start, end, 500, lv_anim_path_ease_out, true } + + lv_anim_timeline_wrapper_t wrapper[] = { + ANIM_DEF(0, cont, width, 0, contWidth), + ANIM_DEF(500, label, y, contHeight, lv_obj_get_y(label)), + ANIM_DEF(1500, cont, opa, LV_OPA_COVER, LV_OPA_TRANSP), + LV_ANIM_TIMELINE_WRAPPER_END + }; + + lv_anim_timeline_add_wrapper(_anim_timeline, wrapper); + + subscribe(MSG_ID::SHOW, cont, + [](lv_event_t* e) { + auto self = (StartupView*)lv_event_get_user_data(e); + auto msg = lv_event_get_msg(e); + + if (lv_msg_get_id(msg) != self->msgID(MSG_ID::SHOW)) { + return; + } + + auto show = (bool)(lv_uintptr_t)lv_msg_get_payload(msg); + + lv_anim_timeline_set_reverse(self->_anim_timeline, !show); + if (!show) { + /* set progress to max to hide the view */ + lv_anim_timeline_set_progress(self->_anim_timeline, LV_ANIM_TIMELINE_PROGRESS_MAX); + } + lv_anim_timeline_start(self->_anim_timeline); + }); +} + +StartupView::~StartupView() +{ + lv_anim_timeline_delete(_anim_timeline); +} + +lv_uintptr_t StartupView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void StartupView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void StartupView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} diff --git a/x_track/src/App/UI/Startup/StartupView.h b/x_track/src/App/UI/Startup/StartupView.h new file mode 100644 index 0000000000000000000000000000000000000000..21c4ee59e098a7a40d5c964ceb746a57b591329a --- /dev/null +++ b/x_track/src/App/UI/Startup/StartupView.h @@ -0,0 +1,63 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STARTUP_VIEW_H +#define __STARTUP_VIEW_H + +#include "../Page.h" + +namespace Page { + +class StartupView { +public: + enum class EVENT_ID { + _LAST, + }; + + enum class MSG_ID { + SHOW, /* param: bool */ + _LAST, + }; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + StartupView(EventListener* listener, lv_obj_t* root); + ~StartupView(); + void publish(MSG_ID id, const void* payload); + +private: + EventListener* _listener; + ResourcePool::Font _font; + lv_anim_timeline_t* _anim_timeline; + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); +}; + +} + +#endif /* __STARTUP_VIEW_H */ diff --git a/x_track/src/App/UI/StatusBar/StatusBar.cpp b/x_track/src/App/UI/StatusBar/StatusBar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e3025ea83cbf72a323692994ebf138f530296ed --- /dev/null +++ b/x_track/src/App/UI/StatusBar/StatusBar.cpp @@ -0,0 +1,88 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "StatusBar.h" +#include "Frameworks/PageManager/PageManager.h" + +#define IS_STR_EQ(STR1, STR2) (strcmp(STR1, STR2) == 0) + +using namespace Page; + +StatusBar::StatusBar(lv_obj_t* parent) +{ + _model = new StatusBarModel(this); + _view = new StatusBarView(this, parent); +} + +StatusBar::~StatusBar() +{ + delete _view; + delete _model; +} + +void StatusBar::onModelEvent(StatusBarModel::EVENT_ID id, const void* param) +{ + switch (id) { + case StatusBarModel::EVENT_ID::CLOCK: { + _view->publish(StatusBarView::MSG_ID::CLOCK, param); + } break; + + case StatusBarModel::EVENT_ID::GNSS: { + _view->publish(StatusBarView::MSG_ID::SAT_NUM, param); + } break; + + case StatusBarModel::EVENT_ID::POWER: { + _view->publish(StatusBarView::MSG_ID::POWER, param); + } break; + + case StatusBarModel::EVENT_ID::ENV: { + auto envInfo = (const DataProc::Env_Info_t*)param; + if (IS_STR_EQ(envInfo->key, "statusbar-opa")) { + StatusBarView::STYLE_ID style = IS_STR_EQ(envInfo->value, "light") + ? StatusBarView::STYLE_ID::LIGHT + : StatusBarView::STYLE_ID::DARK; + _view->publish(StatusBarView::MSG_ID::STYLE_CHANGE, &style); + } else if (IS_STR_EQ(envInfo->key, "rec")) { + _view->publish(StatusBarView::MSG_ID::REC_CHANGE, envInfo->value); + } else if (IS_STR_EQ(envInfo->key, "statusbar")) { + bool show = IS_STR_EQ(envInfo->value, "enable"); + _view->publish(StatusBarView::MSG_ID::SHOW, &show); + } + } break; + + default: + break; + } +} + +void StatusBar::onViewEvent(StatusBarView::EVENT_ID id, const void* param) +{ + switch (id) { + case StatusBarView::EVENT_ID::HEIGHT_UPDATE: { + auto height = *(int*)param; + _model->env()->setInt("statusbar-padding-top", height); + } break; + + default: + break; + } +} diff --git a/x_track/src/App/UI/StatusBar/StatusBar.h b/x_track/src/App/UI/StatusBar/StatusBar.h new file mode 100644 index 0000000000000000000000000000000000000000..3d02d47031bf2e7fc48a379127ed839d4b5ace38 --- /dev/null +++ b/x_track/src/App/UI/StatusBar/StatusBar.h @@ -0,0 +1,47 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STATUS_BAR_PRESENTER_H +#define __STATUS_BAR_PRESENTER_H + +#include "StatusBarModel.h" +#include "StatusBarView.h" + +namespace Page { + +class StatusBar : public StatusBarModel::EventListener, public StatusBarView::EventListener { +public: + StatusBar(lv_obj_t* parent); + virtual ~StatusBar(); + +private: + virtual void onModelEvent(StatusBarModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(StatusBarView::EVENT_ID id, const void* param) override; + +private: + StatusBarModel* _model; + StatusBarView* _view; +}; + +} + +#endif diff --git a/x_track/src/App/UI/StatusBar/StatusBarModel.cpp b/x_track/src/App/UI/StatusBar/StatusBarModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32e799172a0055fa8ef53706f91a4cf6edb4bb4e --- /dev/null +++ b/x_track/src/App/UI/StatusBar/StatusBarModel.cpp @@ -0,0 +1,70 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "StatusBarModel.h" + +using namespace Page; + +StatusBarModel::StatusBarModel(EventListener* listener) + : DataNode(__func__, DataProc::broker()) + , _env(this) + , _listener(listener) +{ + _nodeClock = subscribe("Clock"); + _nodeGNSS = subscribe("GNSS"); + _nodePower = subscribe("Power"); + _nodePageNavi = subscribe("PageNavi"); + + setEventFilter(DataNode::EVENT_PUBLISH); +} + +StatusBarModel::~StatusBarModel() +{ +} + +int StatusBarModel::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeClock) { + auto info = (const HAL::Clock_Info_t*)param->data_p; + uint16_t hhmm = (uint8_t)info->hour << 8 | (uint8_t)info->minute; + _listener->onModelEvent(EVENT_ID::CLOCK, &hhmm); + return DataNode::RES_OK; + } + + if (param->tran == _nodeGNSS) { + auto info = (const HAL::GNSS_Info_t*)param->data_p; + _listener->onModelEvent(EVENT_ID::GNSS, &info->satellites); + return DataNode::RES_OK; + } + + if (param->tran == _nodePower) { + _listener->onModelEvent(EVENT_ID::POWER, param->data_p); + return DataNode::RES_OK; + } + + if (param->tran == _env) { + _listener->onModelEvent(EVENT_ID::ENV, param->data_p); + return DataNode::RES_OK; + } + + return DataNode::RES_UNSUPPORTED_REQUEST; +} diff --git a/x_track/src/App/UI/StatusBar/StatusBarModel.h b/x_track/src/App/UI/StatusBar/StatusBarModel.h new file mode 100644 index 0000000000000000000000000000000000000000..f5607be4b7ec57b283b61582f7bd864e49865c82 --- /dev/null +++ b/x_track/src/App/UI/StatusBar/StatusBarModel.h @@ -0,0 +1,70 @@ + +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STATUS_BAR_MODEL_H +#define __STATUS_BAR_MODEL_H + +#include "Service/DataProc/DataProc.h" + +namespace Page { + +class StatusBarModel : private DataNode { + +public: + enum class EVENT_ID { + CLOCK, /* param: uint16_t (hhmm) */ + GNSS, /* param: int16_t (satellites) */ + POWER, /* param: DataProc::Power_Info_t */ + ENV, /* param: Env_Info_t */ + SHOW, /* param: bool */ + _LAST, + }; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + StatusBarModel(EventListener* listener); + ~StatusBarModel(); + DataProc::Env_Helper* env() + { + return &_env; + } + +private: + const DataNode* _nodeClock; + const DataNode* _nodeGNSS; + const DataNode* _nodePower; + const DataNode* _nodePageNavi; + DataProc::Env_Helper _env; + EventListener* _listener; + +private: + virtual int onEvent(DataNode::EventParam_t* param); +}; + +} + +#endif diff --git a/x_track/src/App/UI/StatusBar/StatusBarView.cpp b/x_track/src/App/UI/StatusBar/StatusBarView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..475b0cabad000381bc963f2a8b73a1adbf7f5026 --- /dev/null +++ b/x_track/src/App/UI/StatusBar/StatusBarView.cpp @@ -0,0 +1,330 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "StatusBarView.h" +#include "Service/DataProc/Def/DP_Power.h" +#include "Utils/lv_anim_label/lv_anim_label.h" + +using namespace Page; + +StatusBarView::StatusBarView(EventListener* listener, lv_obj_t* par) + : _listener(listener) + , _fontMedium(15, "medium") + , _fontAwesome(15, "awesome") + , _fontHandle { 0 } + , _curState { 0 } +{ + /* Ensure that MSG_ID is unique */ + static_assert(sizeof(StatusBarView) >= (size_t)MSG_ID::_LAST, "Large MSG_ID"); + + _curState.satellitesNum = -1; + _curState.battLevel = -1; + + _fontHandle = *_fontMedium; + _fontHandle.fallback = _fontAwesome; + lv_obj_set_style_text_font(par, &_fontHandle, 0); + + lv_obj_t* cont = contCreate(par); + satelliteCreate(cont); + clockCreate(cont); + recCreate(cont); + batteryCreate(cont); + + lv_obj_update_layout(cont); + int height = lv_obj_get_height(cont); + lv_obj_set_y(cont, -height); + lv_obj_set_style_translate_y(cont, height, LV_STATE_DEFAULT); + lv_obj_set_style_translate_y(cont, 0, LV_STATE_DISABLED); + _listener->onViewEvent(EVENT_ID::HEIGHT_UPDATE, &height); +} + +StatusBarView::~StatusBarView() +{ +} + +lv_obj_t* StatusBarView::contCreate(lv_obj_t* par) +{ + lv_obj_t* cont = lv_obj_create(par); + { + lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_size(cont, lv_pct(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(cont, 2, 0); + lv_obj_set_style_radius(cont, 0, 0); + lv_obj_set_style_border_width(cont, 0, 0); + lv_obj_add_state(cont, LV_STATE_DISABLED); + } + + /* style trans & cover */ + { + auto dark_state = LV_STATE_USER_1; + + /* style trans */ + lv_obj_set_style_bg_opa(cont, LV_OPA_TRANSP, LV_STATE_DEFAULT); + + /* style cover */ + lv_obj_set_style_bg_color(cont, lv_color_black(), dark_state); + lv_obj_set_style_bg_opa(cont, LV_OPA_60, dark_state); + lv_obj_set_style_shadow_color(cont, lv_color_black(), dark_state); + lv_obj_set_style_shadow_width(cont, 10, dark_state); + + static lv_style_transition_dsc_t tran; + static const lv_style_prop_t prop[] = { + LV_STYLE_SHADOW_WIDTH, + LV_STYLE_BG_OPA, + LV_STYLE_PROP_INV + }; + lv_style_transition_dsc_init( + &tran, + prop, + lv_anim_path_ease_out, + 200, + 0, + nullptr); + lv_obj_set_style_transition(cont, &tran, dark_state); + lv_obj_set_style_transition(cont, &tran, LV_STATE_DEFAULT); + + subscribe(MSG_ID::STYLE_CHANGE, cont, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (StatusBarView*)lv_msg_get_user_data(msg); + + if (lv_msg_get_id(msg) != self->msgID(MSG_ID::STYLE_CHANGE)) { + return; + } + + auto style = *(STYLE_ID*)lv_msg_get_payload(msg); + if (style == STYLE_ID::LIGHT) { + lv_obj_add_state(obj, LV_STATE_USER_1); + } else { + lv_obj_clear_state(obj, LV_STATE_USER_1); + } + }); + } + + /* style show & hide */ + { + static lv_style_transition_dsc_t tran; + static const lv_style_prop_t prop[] = { + LV_STYLE_TRANSLATE_Y, + LV_STYLE_PROP_INV + }; + lv_style_transition_dsc_init( + &tran, + prop, + lv_anim_path_ease_out, + 300, + 0, + nullptr); + lv_obj_set_style_transition(cont, &tran, LV_STATE_DEFAULT); + lv_obj_set_style_transition(cont, &tran, LV_STATE_DISABLED); + + subscribe(MSG_ID::SHOW, cont, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (StatusBarView*)lv_msg_get_user_data(msg); + + if (lv_msg_get_id(msg) != self->msgID(MSG_ID::SHOW)) { + return; + } + + auto show = *(bool*)lv_msg_get_payload(msg); + if (show) { + lv_obj_clear_state(obj, LV_STATE_DISABLED); + } else { + lv_obj_add_state(obj, LV_STATE_DISABLED); + } + }); + } + + return cont; +} + +void StatusBarView::satelliteCreate(lv_obj_t* par) +{ + { + lv_obj_t* label = lv_label_create(par); + lv_label_set_text_static(label, LV_SYMBOL_EXT_SATELLITE); + lv_obj_align(label, LV_ALIGN_LEFT_MID, 5, 0); + } + + { + lv_obj_t* label = lv_label_create(par); + lv_obj_align(label, LV_ALIGN_LEFT_MID, 25, 0); + lv_label_set_text(label, "00"); + + subscribe(MSG_ID::SAT_NUM, label, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (StatusBarView*)lv_msg_get_user_data(msg); + auto satnum = *(int16_t*)lv_msg_get_payload(msg); + + if (satnum == self->_curState.satellitesNum) { + return; + } + + lv_label_set_text_fmt(obj, "%02d", satnum); + self->_curState.satellitesNum = satnum; + }); + } + + int16_t satnum = 0; + publish(MSG_ID::SAT_NUM, &satnum); +} + +void StatusBarView::clockCreate(lv_obj_t* par) +{ + lv_obj_t* label = lv_label_create(par); + { + lv_obj_center(label); + lv_label_set_text(label, "00:00"); + } + + subscribe(MSG_ID::CLOCK, label, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto hhmm = *(uint16_t*)lv_msg_get_payload(msg); + auto self = (StatusBarView*)lv_msg_get_user_data(msg); + + int hour = hhmm >> 8; + int min = hhmm & 0xFF; + int sum = hour + min; + + if (sum == self->_curState.timeCheckSum) { + return; + } + + lv_label_set_text_fmt(obj, "%02d:%02d", hour, min); + self->_curState.timeCheckSum = sum; + }); +} + +void StatusBarView::batteryCreate(lv_obj_t* par) +{ + lv_obj_t* batteryLabel = lv_label_create(par); + { + lv_label_set_text_static(batteryLabel, LV_SYMBOL_EXT_BATTERY_EMPTY); + lv_obj_align(batteryLabel, LV_ALIGN_RIGHT_MID, -30, 0); + } + + /* battery bg */ + { + lv_obj_t* bg = lv_obj_create(batteryLabel); + lv_obj_remove_style_all(bg); + lv_obj_set_size(bg, 10, 3); + lv_obj_align(bg, LV_ALIGN_LEFT_MID, 3, -1); + lv_obj_set_style_bg_color(bg, lv_color_white(), 0); + lv_obj_set_style_bg_opa(bg, LV_OPA_COVER, 0); + + subscribe(MSG_ID::POWER, bg, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (StatusBarView*)lv_msg_get_user_data(msg); + + if (lv_msg_get_id(msg) != self->msgID(MSG_ID::POWER)) { + return; + } + + auto info = (const DataProc::Power_Info_t*)lv_msg_get_payload(msg); + + if (info->level != self->_curState.battLevel) { + lv_obj_set_width(obj, lv_map(info->level, 0, 100, 0, 10)); + } + }); + } + + lv_obj_t* label = lv_label_create(par); + { + lv_obj_align(label, LV_ALIGN_RIGHT_MID, -5, 0); + lv_label_set_text(label, "-"); + + subscribe(MSG_ID::POWER, label, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (StatusBarView*)lv_msg_get_user_data(msg); + + if (lv_msg_get_id(msg) != self->msgID(MSG_ID::POWER)) { + return; + } + + auto info = (const DataProc::Power_Info_t*)lv_msg_get_payload(msg); + + if (info->level == self->_curState.battLevel) { + return; + } + + lv_label_set_text_fmt(obj, "%02d", info->level); + self->_curState.battLevel = info->level; + }); + } +} + +void StatusBarView::recCreate(lv_obj_t* par) +{ + lv_obj_t* alabel = lv_anim_label_create(par); + lv_obj_set_size(alabel, 40, 20); + lv_anim_label_set_enter_dir(alabel, LV_DIR_TOP); + lv_anim_label_set_exit_dir(alabel, LV_DIR_BOTTOM); + lv_anim_label_set_path(alabel, lv_anim_path_ease_out); + lv_anim_label_set_time(alabel, 500); + + lv_obj_align(alabel, LV_ALIGN_RIGHT_MID, -50, 0); + // lv_obj_set_style_border_color(alabel, lv_color_white(), 0); + // lv_obj_set_style_border_width(alabel, 1, 0); + + lv_anim_t a_enter; + lv_anim_init(&a_enter); + lv_anim_set_early_apply(&a_enter, true); + lv_anim_set_values(&a_enter, LV_OPA_TRANSP, LV_OPA_COVER); + lv_anim_set_exec_cb(&a_enter, [](void* var, int32_t v) { + lv_obj_set_style_opa((lv_obj_t*)var, v, 0); + }); + lv_anim_set_time(&a_enter, 300); + + lv_anim_t a_exit = a_enter; + lv_anim_set_values(&a_exit, LV_OPA_COVER, LV_OPA_TRANSP); + + lv_anim_label_set_custom_enter_anim(alabel, &a_enter); + lv_anim_label_set_custom_exit_anim(alabel, &a_exit); + + subscribe(MSG_ID::REC_CHANGE, alabel, [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto str = (const char*)lv_msg_get_payload(msg); + lv_anim_label_push_text(obj, str); + }); +} + +lv_uintptr_t StatusBarView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void StatusBarView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void StatusBarView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} diff --git a/x_track/src/App/UI/StatusBar/StatusBarView.h b/x_track/src/App/UI/StatusBar/StatusBarView.h new file mode 100644 index 0000000000000000000000000000000000000000..5683851efae6c775a7b77c75aa047d63b37d7b95 --- /dev/null +++ b/x_track/src/App/UI/StatusBar/StatusBarView.h @@ -0,0 +1,88 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STATUS_BAR_VIEW_H +#define __STATUS_BAR_VIEW_H + +#include "../Page.h" + +namespace Page { + +class StatusBarView { +public: + enum class STYLE_ID { + DARK, + LIGHT, + _LAST + }; + + enum class MSG_ID { + SHOW, /* param: bool */ + CLOCK, /* param: uint16_t (uint8_t)Hour << 8 | (uint8_t)Minute */ + SAT_NUM, /* param: int16_t */ + POWER, /* param: DataProc::Power_Info_t */ + STYLE_CHANGE, /* param: STYLE_ID */ + REC_CHANGE, /* param: const char* */ + _LAST, + }; + + enum class EVENT_ID { + HEIGHT_UPDATE, /* param: int */ + _LAST, + }; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + StatusBarView(EventListener* listener, lv_obj_t* par); + ~StatusBarView(); + void publish(MSG_ID id, const void* payload); + +private: + EventListener* _listener; + + ResourcePool::Font _fontMedium; + ResourcePool::Font _fontAwesome; + lv_font_t _fontHandle; + + struct { + int16_t satellitesNum; + uint8_t timeCheckSum; + uint8_t battLevel; + } _curState; + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); + lv_obj_t* contCreate(lv_obj_t* par); + void satelliteCreate(lv_obj_t* par); + void clockCreate(lv_obj_t* par); + void batteryCreate(lv_obj_t* par); + void recCreate(lv_obj_t* par); +}; + +} + +#endif /* __STATUS_BAR_VIEW_H */ diff --git a/x_track/src/App/UI/SystemInfos/BindingDef.inc b/x_track/src/App/UI/SystemInfos/BindingDef.inc new file mode 100644 index 0000000000000000000000000000000000000000..c7ab169724973a0367099ce794a3899187869e51 --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/BindingDef.inc @@ -0,0 +1,4 @@ +/* Binding definition */ + +BINDING_DEF(Verison, DataProc::Version_Info_t) +BINDING_DEF(Storage, DataProc::Storage_Device_Info_t) diff --git a/x_track/src/App/UI/SystemInfos/SystemInfos.cpp b/x_track/src/App/UI/SystemInfos/SystemInfos.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7533e7f722b565e2ea4a5d81490500497a8fb83b --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/SystemInfos.cpp @@ -0,0 +1,112 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "SystemInfos.h" + +using namespace Page; + +APP_DESCRIPTOR_DEF(SystemInfos); + +SystemInfos::SystemInfos() + : _model(nullptr) + , _view(nullptr) +{ +} + +SystemInfos::~SystemInfos() +{ +} + +void SystemInfos::onInstalled() +{ + setBackGestureDirection(LV_DIR_RIGHT); +} + +void SystemInfos::onViewLoad() +{ + _model = new SystemInfosModel(this); + _view = new SystemInfosView(this, getRoot()); +} + +void SystemInfos::onViewDidLoad() +{ +} + +void SystemInfos::onViewWillAppear() +{ +} + +void SystemInfos::onViewDidAppear() +{ + _model->env()->set("statusbar-opa", "light"); +} + +void SystemInfos::onViewWillDisappear() +{ +} + +void SystemInfos::onViewDidDisappear() +{ +} + +void SystemInfos::onViewUnload() +{ + delete _model; + delete _view; +} + +void SystemInfos::onViewDidUnload() +{ +} + +void SystemInfos::onModelEvent(SystemInfosModel::EVENT_ID id, const void* param) +{ + switch (id) { + case SystemInfosModel::EVENT_ID::SPORT_STATUS: { + _view->publish(SystemInfosView::MSG_ID::SPORT_STATUS, param); + } break; + case SystemInfosModel::EVENT_ID::GNSS: { + _view->publish(SystemInfosView::MSG_ID::GNSS, param); + } break; + case SystemInfosModel::EVENT_ID::CLOCK: { + _view->publish(SystemInfosView::MSG_ID::CLOCK, param); + } break; + case SystemInfosModel::EVENT_ID::POWER: { + _view->publish(SystemInfosView::MSG_ID::POWER, param); + } break; + default: + break; + } +} + +void SystemInfos::onViewEvent(SystemInfosView::EVENT_ID id, const void* param) +{ + switch (id) { + case SystemInfosView::EVENT_ID::GET_BINDING: { + auto binding = (SystemInfosView::Binding_Info_t*)param; + binding->binding = _model->getBinding((SystemInfosModel::BINDING_TYPE)binding->type); + } break; + + default: + break; + } +} diff --git a/x_track/src/App/UI/SystemInfos/SystemInfos.h b/x_track/src/App/UI/SystemInfos/SystemInfos.h new file mode 100644 index 0000000000000000000000000000000000000000..84a641146d2a453a7da6b5af66fa699915f9360c --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/SystemInfos.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SYSTEMINFOS_PRESENTER_H +#define __SYSTEMINFOS_PRESENTER_H + +#include "SystemInfosModel.h" +#include "SystemInfosView.h" + +namespace Page { + +class SystemInfos : public PageBase, public SystemInfosModel::EventListener, public SystemInfosView::EventListener { +public: + SystemInfos(); + virtual ~SystemInfos(); + + virtual void onInstalled(); + virtual void onViewLoad(); + virtual void onViewDidLoad(); + virtual void onViewWillAppear(); + virtual void onViewDidAppear(); + virtual void onViewWillDisappear(); + virtual void onViewDidDisappear(); + virtual void onViewUnload(); + virtual void onViewDidUnload(); + +private: + SystemInfosModel* _model; + SystemInfosView* _view; + +private: + virtual void onModelEvent(SystemInfosModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(SystemInfosView::EVENT_ID id, const void* param) override; +}; + +} + +#endif /* __SYSTEMINFOS_PRESENTER_H */ diff --git a/x_track/src/App/UI/SystemInfos/SystemInfosModel.cpp b/x_track/src/App/UI/SystemInfos/SystemInfosModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26a9216fbc90062cd2529eb77e420bfeddd2a41c --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/SystemInfosModel.cpp @@ -0,0 +1,100 @@ + +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "SystemInfosModel.h" + +using namespace Page; + +SystemInfosModel::SystemInfosModel(EventListener* listener) + : DataNode(__func__, DataProc::broker()) + , _listener(listener) + , _env(this) +{ + _nodeSportStatus = subscribe("SportStatus"); + _nodeGNSS = subscribe("GNSS"); + _nodeClock = subscribe("Clock"); + _nodePower = subscribe("Power"); + _nodeStorage = subscribe("Storage"); + _nodeVersion = subscribe("Version"); + + setEventFilter(DataNode::EVENT_PUBLISH); + + initBingdings(); +} + +SystemInfosModel::~SystemInfosModel() +{ +} + +void SystemInfosModel::initBingdings() +{ + _bindingVerison.setCallback( + /* setter */ + nullptr, + /* getter */ + [](SystemInfosModel* self) -> DataProc::Version_Info_t { + DataProc::Version_Info_t info; + self->pull(self->_nodeVersion, &info, sizeof(info)); + return info; + }, + this); + + _bindingStorage.setCallback( + /* setter */ + nullptr, + /* getter */ + [](SystemInfosModel* self) -> DataProc::Storage_Device_Info_t { + DataProc::Storage_Device_Info_t info; + self->pull(self->_nodeStorage, &info, sizeof(info)); + return info; + }, + this); +} + +void* SystemInfosModel::getBinding(BINDING_TYPE type) +{ + switch (type) { +#define BINDING_DEF(name, type) \ + case BINDING_TYPE::name: \ + return &_binding##name; +#include "BindingDef.inc" +#undef BINDING_DEF + default: + return nullptr; + } +} + +int SystemInfosModel::onEvent(DataNode::EventParam_t* param) +{ + if (param->tran == _nodeSportStatus) { + _listener->onModelEvent(EVENT_ID::SPORT_STATUS, param->data_p); + } else if (param->tran == _nodeGNSS) { + _listener->onModelEvent(EVENT_ID::GNSS, param->data_p); + } else if (param->tran == _nodeClock) { + _listener->onModelEvent(EVENT_ID::CLOCK, param->data_p); + } else if (param->tran == _nodePower) { + _listener->onModelEvent(EVENT_ID::POWER, param->data_p); + } + + return DataNode::RES_OK; +} diff --git a/x_track/src/App/UI/SystemInfos/SystemInfosModel.h b/x_track/src/App/UI/SystemInfos/SystemInfosModel.h new file mode 100644 index 0000000000000000000000000000000000000000..07f996ef9ea07cea2e430ac9b4a136047e9bc533 --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/SystemInfosModel.h @@ -0,0 +1,84 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SYSTEMINFOS_MODEL_H +#define __SYSTEMINFOS_MODEL_H + +#include "Service/DataProc/DataProc.h" +#include "Utils/Binding/Binding.h" + +namespace Page { + +class SystemInfosModel : private DataNode { +public: + enum class EVENT_ID { + SPORT_STATUS, + GNSS, + CLOCK, + POWER, + _LAST, + }; + + enum class BINDING_TYPE { +#define BINDING_DEF(name, type) name, +#include "BindingDef.inc" +#undef BINDING_DEF + }; + + typedef struct { + BINDING_TYPE type; + void* binding; + } Binding_Info_t; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + SystemInfosModel(EventListener* listener); + ~SystemInfosModel(); + void* getBinding(BINDING_TYPE type); + DataProc::Env_Helper* env() { return &_env; } + +private: + EventListener* _listener; + const DataNode* _nodeSportStatus; + const DataNode* _nodeGNSS; + const DataNode* _nodeClock; + const DataNode* _nodePower; + const DataNode* _nodeStorage; + const DataNode* _nodeVersion; + DataProc::Env_Helper _env; + +#define BINDING_DEF(name, type) Binding<type, SystemInfosModel> _binding##name; +#include "BindingDef.inc" +#undef BINDING_DEF + +private: + virtual int onEvent(DataNode::EventParam_t* param); + void initBingdings(); +}; + +} + +#endif /* __SYSTEMINFOS_MODEL_H */ diff --git a/x_track/src/App/UI/SystemInfos/SystemInfosView.cpp b/x_track/src/App/UI/SystemInfos/SystemInfosView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2983f53206b144f7817c5d0bed376027a9077077 --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/SystemInfosView.cpp @@ -0,0 +1,415 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "SystemInfosView.h" + +using namespace Page; + +#define ITEM_HEIGHT_MIN 100 + +SystemInfosView::SystemInfosView(EventListener* listener, lv_obj_t* root) + : _listener(listener) + , _fontAwesome(40, "awesome") +#define BINDING_DEF(name, type) , _binding##name((Binding<type, SystemInfosModel>*)getBinding(BINDING_TYPE::name)) +#include "BindingDef.inc" +#undef BINDING_DEF +{ + /* Ensure that MSG_ID is unique */ + static_assert(sizeof(SystemInfosView) >= (size_t)MSG_ID::_LAST, "Large MSG_ID"); + + rootInit(root); + + styleInit(); + + itemGroupCreate(root); + + onRootScroll(root); +} + +SystemInfosView::~SystemInfosView() +{ +} + +lv_uintptr_t SystemInfosView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void SystemInfosView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void SystemInfosView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} + +void* SystemInfosView::getBinding(BINDING_TYPE type) +{ + Binding_Info_t info; + info.type = type; + info.binding = nullptr; + _listener->onViewEvent(EVENT_ID::GET_BINDING, &info); + return info.binding; +} + +void SystemInfosView::rootInit(lv_obj_t* root) +{ + lv_obj_update_layout(root); + lv_obj_set_style_pad_ver(root, ((lv_obj_get_height(root) - ITEM_HEIGHT_MIN) / 2), 0); + + lv_obj_set_flex_flow(root, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + root, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_START, + LV_FLEX_ALIGN_CENTER); + + lv_obj_add_event_cb( + root, + [](lv_event_t* e) { + onRootScroll(lv_event_get_current_target_obj(e)); + }, + LV_EVENT_SCROLL, + this); + + lv_obj_add_flag(root, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_scroll_snap_y(root, LV_SCROLL_SNAP_CENTER); + lv_obj_set_scrollbar_mode(root, LV_SCROLLBAR_MODE_OFF); +} + +void SystemInfosView::onRootScroll(lv_obj_t* obj) +{ + auto child_cnt = lv_obj_get_child_count(obj); + auto obj_height = lv_obj_get_height(obj); + auto obj_pad_top = lv_obj_get_style_pad_top(obj, 0); + auto scroll_y = lv_obj_get_scroll_y(obj); + + for (uint32_t i = 0; i < child_cnt; i++) { + auto cont = lv_obj_get_child(obj, i); + + /* skip 2 label obj */ + auto icon = lv_obj_get_child(cont, 2); + + auto cont_height = lv_obj_get_height(cont); + auto cont_y = lv_obj_get_y(cont); + auto offset_y = (obj_height / 2.0f + scroll_y) - (obj_pad_top + cont_y + cont_height / 2.0f); + + lv_anim_t a; + lv_anim_init(&a); + a.duration = cont_height; + a.act_time = LV_ABS(offset_y); + a.start_value = 70; + a.end_value = 220; + auto width = lv_anim_path_ease_out(&a); + + a.duration = cont_height / 2; + a.start_value = LV_OPA_COVER; + a.end_value = LV_OPA_TRANSP; + auto opa = lv_anim_path_ease_out(&a); + + // LV_LOG_USER("index: %d, icon: %p, offset_y: %d, width: %d", i, icon, (int)offset_y, width); + lv_obj_set_width(icon, width); + lv_obj_set_style_border_opa(icon, opa, 0); + } +} + +void SystemInfosView::styleInit() +{ + lv_style_set_pad_all(&_style.icon, 0); + lv_style_set_border_width(&_style.icon, 0); + lv_style_set_radius(&_style.icon, 0); + lv_style_set_width(&_style.icon, 220); + lv_style_set_border_side(&_style.icon, LV_BORDER_SIDE_RIGHT); + lv_style_set_border_width(&_style.icon, 2); + lv_style_set_border_color(&_style.icon, lv_color_hex(0xff931e)); + lv_style_set_text_font(&_style.icon, lv_theme_get_font_normal(nullptr)); + lv_style_set_text_color(&_style.icon, lv_color_white()); + + lv_style_set_text_font(&_style.info, lv_theme_get_font_small(nullptr)); +} + +void SystemInfosView::itemGroupCreate(lv_obj_t* par) +{ + char infoBuf[128]; + + /* Sport */ + { + lv_snprintf(infoBuf, sizeof(infoBuf), + "%s\n%s\n%s", + _("TOTAL_TRIP"), _("TOTAL_TIME"), _("MAX_SPEED")); + lv_obj_t* label = itemCreate( + par, + _("SPORT"), + LV_SYMBOL_EXT_BICYCLE, + infoBuf); + + subscribe( + MSG_ID::SPORT_STATUS, + label, + [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::SportStatus_Info_t*)lv_msg_get_payload(msg); + lv_label_set_text_fmt( + obj, + "%0.2fkm\n" + "%s\n" + "%0.1fkm/h", + info->totalDistance / 1000.0f, + makeTimeString(info->totalTime), + info->speedMaxKph); + }); + } + + { + lv_snprintf(infoBuf, sizeof(infoBuf), + "%s\n%s\n%s\n%s\n\n%s\n%s", + _("LATITUDE"), + _("LONGITUDE"), + _("ALTITUDE"), + _("UTC_TIME"), + _("COURSE"), + _("SPEED")); + lv_obj_t* label = itemCreate( + par, + _("GNSS"), + LV_SYMBOL_EXT_SATELLITE, + infoBuf); + + subscribe( + MSG_ID::GNSS, + label, + [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const HAL::GNSS_Info_t*)lv_msg_get_payload(msg); + lv_label_set_text_fmt( + obj, + "%0.6f\n" + "%0.6f\n" + "%0.2fm\n" + "%s\n" + "%0.1f deg\n" + "%0.1fkm/h", + info->latitude, + info->longitude, + info->altitude, + makeTimeString(&info->clock), + info->course, + info->speed); + }); + } + + { + lv_snprintf(infoBuf, sizeof(infoBuf), + "%s\n%s", + _("DATE"), + _("TIME")); + lv_obj_t* label = itemCreate( + par, + _("TIME"), + LV_SYMBOL_EXT_CLOCK, + infoBuf); + + subscribe( + MSG_ID::CLOCK, + label, + [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const HAL::Clock_Info_t*)lv_msg_get_payload(msg); + lv_label_set_text_fmt( + obj, + "%s", + makeTimeString(info)); + }); + } + + { + lv_snprintf(infoBuf, sizeof(infoBuf), + "%s\n%s\n%s", + _("USAGE"), + _("VOLTAGE"), + _("STATUS")); + lv_obj_t* label = itemCreate( + par, + _("BATTERY"), + LV_SYMBOL_EXT_BATTERY_THREE_QUARTERS, + infoBuf); + + subscribe( + MSG_ID::POWER, + label, + [](lv_event_t* e) { + auto obj = lv_event_get_current_target_obj(e); + auto msg = lv_event_get_msg(e); + auto info = (const DataProc::Power_Info_t*)lv_msg_get_payload(msg); + lv_label_set_text_fmt( + obj, + "%d%%\n" + "%0.2fV\n" + "%s", + info->level, + info->voltage / 1000.0f, + info->isCharging ? _("CHARGE") : _("DISCHARGE")); + }); + } + + { + lv_snprintf(infoBuf, sizeof(infoBuf), + "%s\n%s\n%s\n%s\n%s", + _("NAME"), + _("AUTHOR"), + _("GRAPHICS"), + _("COMPILER"), + _("BUILD_DATE")); + lv_obj_t* label = itemCreate( + par, + _("ABOUT"), + LV_SYMBOL_EXT_ADDRESS_CARD, + infoBuf); + + auto info = _bindingVerison->get(); + + lv_label_set_text_fmt( + label, + "%s\n" + "%s\n" + "%s\n" + "%s\n" + "%s", + info.name, + info.author, + info.graphics, + info.compiler, + info.buildDate); + } +} + +lv_obj_t* SystemInfosView::itemCreate( + lv_obj_t* par, + const char* name, + const char* symbol, + const char* infos) +{ + lv_obj_t* cont = lv_obj_create(par); + lv_obj_enable_style_refresh(false); + lv_obj_remove_style_all(cont); + lv_obj_set_width(cont, 220); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + + /* icon */ + lv_obj_t* icon = lv_obj_create(cont); + lv_obj_enable_style_refresh(false); + lv_obj_clear_flag(icon, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_flag(icon, LV_OBJ_FLAG_SCROLL_ON_FOCUS); + + lv_obj_add_style(icon, &_style.icon, 0); + lv_obj_set_style_align(icon, LV_ALIGN_LEFT_MID, 0); + + lv_obj_set_flex_flow(icon, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align( + icon, + LV_FLEX_ALIGN_SPACE_AROUND, + LV_FLEX_ALIGN_CENTER, + LV_FLEX_ALIGN_CENTER); + + { + lv_obj_t* label = lv_label_create(icon); + lv_obj_enable_style_refresh(false); + lv_obj_set_style_text_font(label, _fontAwesome, 0); + lv_label_set_text_static(label, symbol); + } + + { + lv_obj_t* label = lv_label_create(icon); + lv_obj_enable_style_refresh(false); + lv_label_set_text(label, name); + } + + /* infos */ + lv_obj_t* labelInfo = lv_label_create(cont); + { + lv_obj_enable_style_refresh(false); + lv_label_set_text(labelInfo, infos); + lv_obj_add_style(labelInfo, &_style.info, 0); + lv_obj_align(labelInfo, LV_ALIGN_LEFT_MID, 75, 0); + } + + /* datas */ + lv_obj_t* labelData = lv_label_create(cont); + { + lv_obj_enable_style_refresh(false); + lv_label_set_text(labelData, "-"); + lv_obj_add_style(labelData, &_style.info, 0); + lv_obj_align(labelData, LV_ALIGN_CENTER, 60, 0); + } + + lv_obj_move_foreground(icon); + lv_obj_enable_style_refresh(true); + + /* get real max height */ + lv_obj_update_layout(labelInfo); + lv_coord_t height = lv_obj_get_height(labelInfo); + height = LV_MAX(height, ITEM_HEIGHT_MIN); + lv_obj_set_height(cont, height); + lv_obj_set_height(icon, height); + + return labelData; +} + +const char* SystemInfosView::makeTimeString(uint64_t ms) +{ + static char buf[16]; + uint64_t ss = ms / 1000; + uint64_t mm = ss / 60; + uint32_t hh = (uint32_t)(mm / 60); + + lv_snprintf( + buf, sizeof(buf), + "%d:%02d:%02d", + (int)hh, + (int)(mm % 60), + (int)(ss % 60)); + + return buf; +} + +const char* SystemInfosView::makeTimeString(const HAL::Clock_Info_t* info) +{ + static char buf[32]; + lv_snprintf( + buf, + sizeof(buf), + "%d-%d-%d\n%02d:%02d:%02d", + info->year, + info->month, + info->day, + info->hour, + info->minute, + info->second); + + return buf; +} diff --git a/x_track/src/App/UI/SystemInfos/SystemInfosView.h b/x_track/src/App/UI/SystemInfos/SystemInfosView.h new file mode 100644 index 0000000000000000000000000000000000000000..9302a8b5ce4e0e078bfefb7488911d4938dde20f --- /dev/null +++ b/x_track/src/App/UI/SystemInfos/SystemInfosView.h @@ -0,0 +1,115 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SYSTEMINFOS_VIEW_H +#define __SYSTEMINFOS_VIEW_H + +#include "../Page.h" +#include "Service/DataProc/DataProc.h" +#include "Service/HAL/HAL.h" +#include "Utils/Binding/Binding.h" + +namespace Page { + +class SystemInfosModel; + +class SystemInfosView { +public: + enum class EVENT_ID { + GET_BINDING, /* Param: Binding_Info_t */ + _LAST, + }; + + enum class MSG_ID { + SPORT_STATUS, /* param: SportStatus_Info_t */ + GNSS, /* param: GNSS_Info_t */ + CLOCK, /* param: Clock_Info_t */ + POWER, /* param: Power_Info_t */ + _LAST, + }; + + enum class BINDING_TYPE { +#define BINDING_DEF(name, type) name, +#include "BindingDef.inc" +#undef BINDING_DEF + }; + + typedef struct { + BINDING_TYPE type; + void* binding; + } Binding_Info_t; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + SystemInfosView(EventListener* listener, lv_obj_t* root); + ~SystemInfosView(); + void publish(MSG_ID id, const void* payload = nullptr); + +private: + EventListener* _listener; + + struct STYLE { + STYLE() + { + lv_style_init(&icon); + lv_style_init(&info); + } + ~STYLE() + { + lv_style_reset(&icon); + lv_style_reset(&info); + } + lv_style_t icon; + lv_style_t info; + } _style; + + ResourcePool::Font _fontAwesome; + +#define BINDING_DEF(name, type) Binding<type, SystemInfosModel>* _binding##name; +#include "BindingDef.inc" +#undef BINDING_DEF + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); + void* getBinding(BINDING_TYPE type); + void rootInit(lv_obj_t* root); + static void onRootScroll(lv_obj_t* obj); + void styleInit(); + void itemGroupCreate(lv_obj_t* par); + lv_obj_t* itemCreate( + lv_obj_t* par, + const char* name, + const char* symbol, + const char* infos); + + static const char* makeTimeString(uint64_t ms); + static const char* makeTimeString(const HAL::Clock_Info_t* info); +}; + +} + +#endif /* __SYSTEMINFOS_VIEW_H */ diff --git a/x_track/src/App/UI/_Template/Template.cpp b/x_track/src/App/UI/_Template/Template.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41beabc83b4129f342e7f4cbbf72eb3b4616678d --- /dev/null +++ b/x_track/src/App/UI/_Template/Template.cpp @@ -0,0 +1,93 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Template.h" + +using namespace Page; + +APP_DESCRIPTOR_DEF(Template); + +Template::Template() + : _model(nullptr) + , _view(nullptr) +{ +} + +Template::~Template() +{ +} + +void Template::onInstalled() +{ +} + +void Template::onViewLoad() +{ + _model = new TemplateModel(this); + _view = new TemplateView(this, getRoot()); +} + +void Template::onViewDidLoad() +{ +} + +void Template::onViewWillAppear() +{ +} + +void Template::onViewDidAppear() +{ +} + +void Template::onViewWillDisappear() +{ +} + +void Template::onViewDidDisappear() +{ +} + +void Template::onViewUnload() +{ + delete _model; + delete _view; +} + +void Template::onViewDidUnload() +{ +} + +void Template::onModelEvent(TemplateModel::EVENT_ID id, const void* param) +{ + switch (id) { + default: + break; + } +} + +void Template::onViewEvent(TemplateView::EVENT_ID id, const void* param) +{ + switch (id) { + default: + break; + } +} diff --git a/x_track/src/App/UI/_Template/Template.h b/x_track/src/App/UI/_Template/Template.h new file mode 100644 index 0000000000000000000000000000000000000000..8fe36729b58e35a41aa01cb9f72823b827d30aaf --- /dev/null +++ b/x_track/src/App/UI/_Template/Template.h @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TEMPLATE_PRESENTER_H +#define __TEMPLATE_PRESENTER_H + +#include "TemplateModel.h" +#include "TemplateView.h" + +namespace Page { + +class Template : public PageBase, public TemplateModel::EventListener, public TemplateView::EventListener { +public: + Template(); + virtual ~Template(); + + virtual void onInstalled(); + virtual void onViewLoad(); + virtual void onViewDidLoad(); + virtual void onViewWillAppear(); + virtual void onViewDidAppear(); + virtual void onViewWillDisappear(); + virtual void onViewDidDisappear(); + virtual void onViewUnload(); + virtual void onViewDidUnload(); + +private: + TemplateModel* _model; + TemplateView* _view; + +private: + virtual void onModelEvent(TemplateModel::EVENT_ID id, const void* param) override; + virtual void onViewEvent(TemplateView::EVENT_ID id, const void* param) override; +}; + +} + +#endif /* __TEMPLATE_PRESENTER_H */ diff --git a/x_track/src/App/UI/_Template/TemplateModel.cpp b/x_track/src/App/UI/_Template/TemplateModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2af54ed96a52f021cb49bafc8ae3d4c3ece227b9 --- /dev/null +++ b/x_track/src/App/UI/_Template/TemplateModel.cpp @@ -0,0 +1,42 @@ + +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "TemplateModel.h" + +using namespace Page; + +TemplateModel::TemplateModel(EventListener* listener) + : DataNode(__func__, DataProc::broker()) + , _listener(listener) +{ + setEventFilter(DataNode::EVENT_ALL); +} + +TemplateModel::~TemplateModel() +{ +} + +int TemplateModel::onEvent(DataNode::EventParam_t* param) +{ + return DataNode::RES_OK; +} diff --git a/x_track/src/App/UI/_Template/TemplateModel.h b/x_track/src/App/UI/_Template/TemplateModel.h new file mode 100644 index 0000000000000000000000000000000000000000..c9da9c0d0a254c59c291497d78aabf2eb0721f59 --- /dev/null +++ b/x_track/src/App/UI/_Template/TemplateModel.h @@ -0,0 +1,54 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TEMPLATE_MODEL_H +#define __TEMPLATE_MODEL_H + +#include "Service/DataProc/DataProc.h" + +namespace Page { + +class TemplateModel : private DataNode { +public: + enum class EVENT_ID { + _LAST, + }; + + class EventListener { + public: + virtual void onModelEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + TemplateModel(EventListener* listener); + ~TemplateModel(); + +private: + EventListener* _listener; + +private: + virtual int onEvent(DataNode::EventParam_t* param); +}; + +} + +#endif /* __TEMPLATE_MODEL_H */ diff --git a/x_track/src/App/UI/_Template/TemplateView.cpp b/x_track/src/App/UI/_Template/TemplateView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7075fb935f580f649a67b68370a863c5909ffcd --- /dev/null +++ b/x_track/src/App/UI/_Template/TemplateView.cpp @@ -0,0 +1,52 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "TemplateView.h" + +using namespace Page; + +TemplateView::TemplateView(EventListener* listener, lv_obj_t* root) + : _listener(listener) +{ + /* Ensure that MSG_ID is unique */ + static_assert(sizeof(TemplateView) >= (size_t)MSG_ID::_LAST, "Large MSG_ID"); +} + +TemplateView::~TemplateView() +{ +} + +lv_uintptr_t TemplateView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void TemplateView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void TemplateView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} diff --git a/x_track/src/App/UI/_Template/TemplateView.h b/x_track/src/App/UI/_Template/TemplateView.h new file mode 100644 index 0000000000000000000000000000000000000000..16e5a59dd478b6c0fd48a85c2ab0a37d5d48fcd9 --- /dev/null +++ b/x_track/src/App/UI/_Template/TemplateView.h @@ -0,0 +1,60 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TEMPLATE_VIEW_H +#define __TEMPLATE_VIEW_H + +#include "../Page.h" + +namespace Page { + +class TemplateView { +public: + enum class EVENT_ID { + _LAST, + }; + + enum class MSG_ID { + _LAST, + }; + + class EventListener { + public: + virtual void onViewEvent(EVENT_ID id, const void* param = nullptr) = 0; + }; + +public: + TemplateView(EventListener* listener, lv_obj_t* root); + ~TemplateView(); + void publish(MSG_ID id, const void* payload = nullptr); + +private: + EventListener* _listener; + +private: + lv_uintptr_t msgID(MSG_ID id); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); +}; + +} + +#endif /* __TEMPLATE_VIEW_H */ diff --git a/x_track/src/App/UI/app_gen.py b/x_track/src/App/UI/app_gen.py new file mode 100644 index 0000000000000000000000000000000000000000..21b218c8c86e493465a51277500c6428318c7714 --- /dev/null +++ b/x_track/src/App/UI/app_gen.py @@ -0,0 +1,67 @@ +""" +MIT License + +Copyright (c) 2024 _VIFEXTech, ChatGPT-3.5 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + +import os +import shutil +import sys + +def copy_template_to_new_app(template_dir, new_app_name): + # New app directory name + new_app_dir = new_app_name + + # Check if directory already exists + if os.path.exists(new_app_dir): + print(f"Directory '{new_app_dir}' already exists. Aborting.") + sys.exit(1) + + # Copy template directory to new app directory + shutil.copytree(template_dir, new_app_dir) + + # Generate new file names + new_file_names = [file.replace('Template', new_app_name) for file in os.listdir(new_app_dir)] + + # Modify file names + for old_file, new_file in zip(os.listdir(new_app_dir), new_file_names): + os.rename(os.path.join(new_app_dir, old_file), os.path.join(new_app_dir, new_file)) + + # Modify template name in file contents + for file_name in new_file_names: + file_path = os.path.join(new_app_dir, file_name) + with open(file_path, 'r') as file: + file_data = file.read() + file_data = file_data.replace('Template', new_app_name) + file_data = file_data.replace('__TEMPLATE', '__' + new_app_name.upper()) + with open(file_path, 'w') as file: + file.write(file_data) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print(f"Usage: python {sys.argv[0]} <NewAppName>") + sys.exit(1) + + new_app_name = sys.argv[1] + template_dir = "_Template" + + copy_template_to_new_app(template_dir, new_app_name) + print(f"Successfully created new app '{new_app_name}' from template.") diff --git a/x_track/src/App/Utils/Binding/Binding.h b/x_track/src/App/Utils/Binding/Binding.h new file mode 100644 index 0000000000000000000000000000000000000000..7e5a2a718d0cc81326b35f7d32c415fa6167041f --- /dev/null +++ b/x_track/src/App/Utils/Binding/Binding.h @@ -0,0 +1,87 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __BINDING_H +#define __BINDING_H + +template <class T, class CONTEXT> +class Binding { +public: + typedef void (*SET_FUNC)(CONTEXT*, T); + typedef T (*GET_FUNC)(CONTEXT*); + +public: + Binding(T v, SET_FUNC setFunc, GET_FUNC getFunc, CONTEXT* ctx) + { + Binding(setFunc, getFunc, ctx); + set(v); + } + + Binding(SET_FUNC setFunc, GET_FUNC getFunc, CONTEXT* ctx) + : _setFunc(setFunc) + , _getFunc(getFunc) + , _ctx(ctx) + { + } + + Binding() + : _setFunc(nullptr) + , _getFunc(nullptr) + , _ctx(nullptr) + { + } + + void setCallback(SET_FUNC setFunc, GET_FUNC getFunc, CONTEXT* ctx) + { + _setFunc = setFunc; + _getFunc = getFunc; + _ctx = ctx; + } + + void set(T v) + { + _setFunc(_ctx, v); + } + + T get() const + { + return _getFunc(_ctx); + } + + operator T() const + { + return get(); + } + + Binding& operator=(T v) + { + set(v); + return *this; + } + +private: + SET_FUNC _setFunc; + GET_FUNC _getFunc; + CONTEXT* _ctx; +}; + +#endif /* __BINDING_H */ diff --git a/x_track/src/App/Utils/CommonMacro/CommonMacro.h b/x_track/src/App/Utils/CommonMacro/CommonMacro.h new file mode 100644 index 0000000000000000000000000000000000000000..a9554920e7c1c59684182183ec3192b856518c28 --- /dev/null +++ b/x_track/src/App/Utils/CommonMacro/CommonMacro.h @@ -0,0 +1,209 @@ +/** + * @file CommonMacro.h + * @author _VIFEXTech (vifextech@foxmail.com) + * @brief General macro definition method library + * @version 1.8 + * @date 2023-02-04 + * + * @copyright Copyright (c) 2023 + * + */ +#ifndef __COMMON_MACRO_H +#define __COMMON_MACRO_H + +// 2019-03-21 v1.0 Add notes +// 2019-03-21 v1.1 Add __ValueCloseTo +// 2019-05-16 v1.2 Add __ExecuteexprWithTimeout +// 2019-05-16 v1.3 Add __ValueStep +// 2019-09-25 v1.4 Add __ExecuteOnce +// 2020-01-27 v1.5 Add __SemaphoreTake +// 2020-03-10 v1.6 Add __ValuePlus +// 2022-03-14 v1.7 Rename APIs: CM_XXX; __Sizeof -> __ARRAY_SIZE; Add __EventMonitor +// 2023-02-04 v1.8 Refactoring; use English comments + +#ifndef CM_TICK_GET +#ifdef ARDUINO +#define CM_TICK_GET() millis() +#endif +#endif + +/** + * @brief Variable Watcher, which fires an event when a variable changes + * @param now: monitored variables (integer) + * @param expr: an expression triggered by an event + */ +#define CM_VALUE_MONITOR(now, expr) \ + do { \ + static int last = (now); \ + if (last != (now)) { \ + expr; \ + last = (now); \ + } \ + } while (0) + +/** + * @brief Make a variable approach a specified value in designed steps + * @param src: controlled variable + * @param dest: value being approximated + * @param step: step length + */ +#define CM_VALUE_CLOSE_TO(src, dest, step) \ + do { \ + if ((src) < (dest)) { \ + (src) += (step); \ + } else if ((src) > (dest)) { \ + (src) -= (step); \ + } \ + } while (0) + +/** + * @brief Let a variable increase or subtract a value, + * starting from 0 when it is greater than or equal to the maximum value, + * and starting from the maximum value after being lower than 0 + * @param src: controlled variable. + * @param step: step length + * @param max: maximum value + */ +#define CM_VALUE_STEP(src, step, max) \ + ((src) = (((step) >= 0) \ + ? (((src) + (step)) % (max)) \ + : (((src) + (max) + (step)) % (max)))) + +/** + * @brief Let a variable increase or decrease a value, + * start from the minimum value after it is greater than the maximum value, + * and start from the maximum value after it is less than the minimum value + * @param src: controlled variable + * @param plus: value added + * @param min: minimum value + * @param max: maximum value + */ +#define CM_VALUE_PLUS(src, plus, min, max) \ + do { \ + int cm_tmp_value = (src); \ + cm_tmp_value += (plus); \ + if (cm_tmp_value < (min)) { \ + cm_tmp_value = (max); \ + } else if (cm_tmp_value > (max)) { \ + cm_tmp_value = (min); \ + } \ + (src) = cm_tmp_value; \ + } while (0) + +/** + * @brief Get constraint value + * @param x: original value + * @param min: minimum value + * @param max: maximum value + * @retval constraint value + */ +#define CM_CONSTRAIN(x, low, high) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x))) + +/** + * @brief Restrict a value to a range + * @param x: original value + * @param min: minimum value + * @param max: maximum value + */ +#define CM_VALUE_LIMIT(x, min, max) ((x) = CM_CONSTRAIN((x), (min), (max))) + +/** + * @brief Linearly maps a range of changes in one value to another + * @param x: mapped value + * @param in_min: the minimum value to be mapped + * @param in_max: the maximum value to be mapped + * @param out_min: the minimum value of the map output + * @param out_max: the maximum value of the map output + * @retval mapped value + */ +#define CM_VALUE_MAP(x, in_min, in_max, out_min, out_max) \ + (((x) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min)) + +/** + * @brief Non-blocking execution of an expression at specified time intervals + * @param expr: executed expression + * @param time: time interval + */ +#define CM_EXECUTE_INTERVAL(expr, time) \ + do { \ + static unsigned long lasttime = 0; \ + if (CM_TICK_GET() - lasttime >= (time)) { \ + expr; \ + lasttime = CM_TICK_GET(); \ + }; \ + } while (0) + +/** + * @brief Repeated call expression + * @param expr: executed expression + * @param n: number of calls + */ +#define CM_EXECUTE_LOOP(expr, n) \ + do { \ + for (unsigned long i = 0; i < (n); i++) { \ + expr; \ + } \ + } while (0) + +/** + * @brief ִExecutes an expression until the exprtion returns + * the specified value without timing out + * @param expr: executed expression + * @param retval: expected exprtion return value + * @param timeout: time out + * @param is_timeout: Provide variables externally to check whether timeout + */ +#define CM_EXECUTE_WITH_TIMEOUT(expr, n, timeout, is_timeout) \ + do { \ + unsigned long start = CM_TICK_GET(); \ + (is_timeout) = false; \ + while (CM_TICK_GET() - start < (timeout)) { \ + if (expr == (n)) { \ + (is_timeout) = true; \ + break; \ + } \ + } \ + } while (0) + +/** + * @brief Execute the expression only once + * @param expr: executed expression + */ +#define CM_EXECUTE_ONCE(expr) \ + do { \ + static bool cm_is_inited = false; \ + if (!cm_is_inited) { \ + expr; \ + cm_is_inited = true; \ + } \ + } while (0) + +/** + * @brief Get the semaphore and execute the expression once when sem is true + * @param sem: semaphore (bool) + * @param expr: executed expression + */ +#define CM_EXECUTE_SEM_TAKE(sem, expr) \ + do { \ + if ((sem)) { \ + expr; \ + (sem) = false; \ + } \ + } while (0) + +/** + * @brief Get the number of elements in the array + * @param arr: array + * @retval the number of elements in the array + */ +#define CM_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +/** + * @brief Force conversion of a value, often used for structure copy + * @param type: cast type + * @param data: data being cast + * @retval transformed data + */ +#define CM_TYPE_CAST(type, data) (*((type*)(&(data)))) + +#endif diff --git a/x_track/src/App/Utils/FifoQueue/FifoQueue.h b/x_track/src/App/Utils/FifoQueue/FifoQueue.h new file mode 100644 index 0000000000000000000000000000000000000000..17a13ee4694a3c5518c6e3207ecd84790ab9f01c --- /dev/null +++ b/x_track/src/App/Utils/FifoQueue/FifoQueue.h @@ -0,0 +1,90 @@ +/* + * MIT License + * Copyright (c) 2020 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __FIFO_QUEUE_H +#define __FIFO_QUEUE_H + +#include <cstddef> + +template <class T, size_t SIZE> +class FifoQueue { +public: + FifoQueue() + : _head(0) + , _tail(0) {}; + + size_t available() + { + return (SIZE + _head - _tail) % SIZE; + } + + size_t size() + { + return SIZE - 1; + } + + bool full() + { + return (available() == size()); + } + + bool empty() + { + return (_head == _tail); + } + + bool write(const T& data) + { + size_t i = (_head + 1) % SIZE; + + if (i == _tail) { + return false; + } + + _buffer[_head] = data; + _head = i; + return true; + } + + bool read(T& data) + { + if (empty()) { + return false; + } + + data = _buffer[_tail]; + _tail = (_tail + 1) % SIZE; + return true; + } + + void flush() + { + _head = _tail; + } + +private: + T _buffer[SIZE]; + size_t _head; + size_t _tail; +}; + +#endif /* __FIFO_QUEUE_H */ diff --git a/x_track/src/App/Utils/Filters/FilterBase.h b/x_track/src/App/Utils/Filters/FilterBase.h new file mode 100644 index 0000000000000000000000000000000000000000..2f344473c810dc1a409a5fc8825cc6e1c45cebc6 --- /dev/null +++ b/x_track/src/App/Utils/Filters/FilterBase.h @@ -0,0 +1,61 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __FILTER_BASE_H +#define __FILTER_BASE_H + +#include <stdint.h> + +#define FILTER_ABS(x) (((x)>0)?(x):-(x)) + +namespace Filter +{ + +template <class T> class Base +{ +public: + virtual void Reset() + { + isFirst = true; + } + + virtual bool CheckFirst() + { + bool retval = isFirst; + isFirst = false; + return retval; + } + + virtual T GetNext(T value) + { + lastValue = value; + return lastValue; + } + +protected: + T lastValue; + bool isFirst; +}; + +} + +#endif // ! __FILTER_BASE_H diff --git a/x_track/src/App/Utils/Filters/Filters.h b/x_track/src/App/Utils/Filters/Filters.h new file mode 100644 index 0000000000000000000000000000000000000000..dec45d606c21b0e70ab8b287c35b8b15b738fbf9 --- /dev/null +++ b/x_track/src/App/Utils/Filters/Filters.h @@ -0,0 +1,32 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __FILTERS_H +#define __FILTERS_H + +#include "HysteresisFilter.h" +#include "LowpassFilter.h" +#include "MedianFilter.h" +#include "MedianQueueFilter.h" +#include "SlidingFilter.h" + +#endif diff --git a/x_track/src/App/Utils/Filters/HysteresisFilter.h b/x_track/src/App/Utils/Filters/HysteresisFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..68ffe304e026487066940f4d30a4c8c41ca447b2 --- /dev/null +++ b/x_track/src/App/Utils/Filters/HysteresisFilter.h @@ -0,0 +1,55 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HYSTERESIS_FILTER_H +#define __HYSTERESIS_FILTER_H + +#include "FilterBase.h" + +namespace Filter +{ + +template <typename T> class Hysteresis : public Base<T> +{ +public: + Hysteresis(T hysVal) + { + this->Reset(); + this->hysValue = hysVal; + } + + virtual T GetNext(T value) + { + if (FILTER_ABS(value - this->lastValue) > this->hysValue) + { + this->lastValue = value; + } + return this->lastValue; + } + +private: + T hysValue; +}; + +} + +#endif diff --git a/x_track/src/App/Utils/Filters/LowpassFilter.h b/x_track/src/App/Utils/Filters/LowpassFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..77991f6a8406501ee2622d6894505355d0f6036a --- /dev/null +++ b/x_track/src/App/Utils/Filters/LowpassFilter.h @@ -0,0 +1,68 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __LOWPASS_FILTER_H +#define __LOWPASS_FILTER_H + +#include "FilterBase.h" + +namespace Filter +{ + +template <typename T> class Lowpass : public Base<T> +{ +public: + Lowpass(float dt, float cutoff) + { + this->Reset(); + + if (cutoff > 0.001f) + { + float RC = 1 / (2 * 3.141592653f * cutoff); + this->rc = dt / (RC + dt); + } + else + { + this->rc = 1; + } + } + + virtual T GetNext(T value) + { + if (this->CheckFirst()) + { + return this->lastValue = value; + } + else + { + this->lastValue = (this->lastValue + (value - this->lastValue) * this->rc); + return this->lastValue; + } + } + +private: + float rc; +}; + +} + +#endif diff --git a/x_track/src/App/Utils/Filters/MedianFilter.h b/x_track/src/App/Utils/Filters/MedianFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..a8498db3b14d9e6e9b76043aef7dd45d10a5017e --- /dev/null +++ b/x_track/src/App/Utils/Filters/MedianFilter.h @@ -0,0 +1,79 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MEDIAN_FILTER_H +#define __MEDIAN_FILTER_H + +#include "FilterBase.h" +#include <algorithm> + +namespace Filter +{ + +template <typename T, size_t bufferSize> class Median : public Base<T> +{ +public: + Median() + { + this->Reset(); + this->dataIndex = 0; + } + + bool FillBuffer(T value) + { + if (this->dataIndex < bufferSize) + { + this->buffer[this->dataIndex] = value; + this->dataIndex++; + return false; + } + return true; + } + + virtual T GetNext(T value) + { + if (this->isFirst) + { + this->isFirst = !FillBuffer(value); + this->lastValue = value; + } + else + { + if (FillBuffer(value)) + { + std::sort(this->buffer, this->buffer + bufferSize); + this->lastValue = this->buffer[bufferSize / 2]; + this->dataIndex = 0; + } + } + + return this->lastValue; + } + +protected: + T buffer[bufferSize]; + size_t dataIndex; +}; + +} + +#endif diff --git a/x_track/src/App/Utils/Filters/MedianQueueFilter.h b/x_track/src/App/Utils/Filters/MedianQueueFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..7b2ee4dfae4035705be5db08c2fa5f50e50e37b7 --- /dev/null +++ b/x_track/src/App/Utils/Filters/MedianQueueFilter.h @@ -0,0 +1,68 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MEDIAN_QUEUE_FILTER_H +#define __MEDIAN_QUEUE_FILTER_H + +#include "MedianFilter.h" + +namespace Filter +{ + +template <typename T, size_t bufferSize> class MedianQueue : public Median<T, bufferSize> +{ +public: + MedianQueue() : Median<T, bufferSize>() + { + } + + virtual T GetNext(T value) + { + if (this->isFirst) + { + this->isFirst = !this->FillBuffer(value); + this->lastValue = value; + } + else + { + this->dataIndex %= bufferSize; + this->buffer[this->dataIndex] = value; + this->dataIndex++; + + for (size_t i = 0; i < bufferSize; i++) + { + this->bufferSort[i] = this->buffer[i]; + } + std::sort(this->bufferSort, this->bufferSort + bufferSize); + this->lastValue = this->bufferSort[bufferSize / 2]; + } + + return this->lastValue; + } + +protected: + T bufferSort[bufferSize]; +}; + +} + +#endif diff --git a/x_track/src/App/Utils/Filters/SlidingFilter.h b/x_track/src/App/Utils/Filters/SlidingFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..6d82870d605ebc18c5e5a9d9dd60f9ae6cf06f8a --- /dev/null +++ b/x_track/src/App/Utils/Filters/SlidingFilter.h @@ -0,0 +1,73 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __SLIDING_FILTER_H +#define __SLIDING_FILTER_H + +#include "FilterBase.h" + +namespace Filter +{ + +template <typename T> class Sliding : public Base<T> +{ +public: + Sliding(T sldVal) + { + this->Reset(); + this->slideValue = sldVal; + } + + virtual T GetNext(T value) + { + if (this->CheckFirst()) + { + this->lastValue = value; + } + else + { + if (FILTER_ABS(value - this->lastValue) < this->slideValue) + { + this->lastValue = value; + } + else + { + if (this->lastValue < value) + { + this->lastValue += this->slideValue; + } + else if (this->lastValue > value) + { + this->lastValue -= this->slideValue; + } + } + } + return this->lastValue; + } + +private: + T slideValue; +}; + +} + +#endif diff --git a/x_track/src/App/Utils/GPX/Examples/Static_Track/Static_Track.pde b/x_track/src/App/Utils/GPX/Examples/Static_Track/Static_Track.pde new file mode 100644 index 0000000000000000000000000000000000000000..05e99f0d3837027394bbb79bf6af25c9e6fcf2bf --- /dev/null +++ b/x_track/src/App/Utils/GPX/Examples/Static_Track/Static_Track.pde @@ -0,0 +1,29 @@ +#include <GPX.h> + +GPX myGPX; + +void setup() +{ + // start serial port at 9600 bps: + Serial.begin(9600); + String dumbString(""); +} + +void loop(){ + Serial.print(myGPX.getOpen()); + myGPX.setMetaDesc("foofoofoo"); + myGPX.setName("track name"); + myGPX.setDesc("Track description"); + myGPX.setSrc("SUP500Ff"); + Serial.print(myGPX.getMetaData()); + Serial.print(myGPX.getTrakOpen()); + Serial.print(myGPX.getInfo()); + Serial.print(myGPX.getTrakSegOpen()); + Serial.print(myGPX.getPt(GPX_TRKPT,"41.123","-71.456")); + Serial.print(myGPX.getPt(GPX_TRKPT,"42.123","-72.456")); + Serial.print(myGPX.getPt(GPX_TRKPT,"43.123","-73.456")); + Serial.print(myGPX.getTrakSegClose()); + Serial.print(myGPX.getTrakClose()); + Serial.print(myGPX.getClose()); + delay(10000); +} diff --git a/x_track/src/App/Utils/GPX/GPX.cpp b/x_track/src/App/Utils/GPX/GPX.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2365787e17afbd23c6d8dab97fc254eb50145b22 --- /dev/null +++ b/x_track/src/App/Utils/GPX/GPX.cpp @@ -0,0 +1,216 @@ +/* + * GPX Library -- GPX.cpp + * Created by: Ryan M Sutton + * + * Copyright (c) 2010, Ryan M Sutton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Ryan M Sutton nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Ryan M Sutton BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "GPX.h" + +#define _GPX_HEAD "<gpx version=\"1.1\" creator=\"Arduino GPX Lib\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xmlns=\"http://www.topografix.com/GPX/1/1\"\n xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\"\n>\n" +#define _GPX_TAIL "</gpx>\n" +#define _GPX_META_HEAD "<metadata>" +#define _GPX_META_TAIL "</metadata>\n" +#define _GPX_TRAK_HEAD "<trk>" +#define _GPX_TRAK_TAIL "</trk>\n" +#define _GPX_TRKSEG_HEAD "<trkseg>" +#define _GPX_TRKSEG_TAIL "</trkseg>\n" +#define _GPX_PT_HEAD "<TYPE lat=\"" +#define _GPX_PT_TAIL "</TYPE>\n" + +// Property Tags +#define _GPX_NAME_HEAD "<name>" +#define _GPX_NAME_TAIL "</name>\n" +#define _GPX_DESC_HEAD "<desc>" +#define _GPX_DESC_TAIL "</desc>\n" +#define _GPX_SYM_HEAD "<sym>" +#define _GPX_SYM_TAIL "</sym>\n" +#define _GPX_ELE_HEAD "<ele>" +#define _GPX_ELE_TAIL "</ele>\n" +#define _GPX_SRC_HEAD "<src>" +#define _GPX_SRC_TAIL "</src>\n" +#define _GPX_TIME_HEAD "<time>" +#define _GPX_TIME_TAIL "</time>\n" + +GPX::GPX() +{ +} + +//Get methods + +String GPX::getOpen() +{ + return String(_GPX_HEAD); +} + +String GPX::getClose() +{ + return String(_GPX_TAIL); +} + +String GPX::getMetaData() +{ + String localStr(_GPX_META_HEAD); + if (_metaName.length() > 0) + { + localStr = localStr + String(_GPX_NAME_HEAD); + localStr = localStr + wrapCDATA(_metaName); + localStr = localStr + String(_GPX_NAME_TAIL); + } + if (_metaDesc.length() > 0) + { + localStr = localStr + String(_GPX_DESC_HEAD); + localStr = localStr + wrapCDATA(_metaDesc); + localStr = localStr + String(_GPX_DESC_TAIL); + } + localStr = localStr + String(_GPX_META_TAIL); + return localStr; +} + +String GPX::getTrakOpen() +{ + return String(_GPX_TRAK_HEAD); +} + +String GPX::getTrakClose() +{ + return String(_GPX_TRAK_TAIL); +} + +String GPX::getTrakSegOpen() +{ + return String(_GPX_TRKSEG_HEAD); +} + +String GPX::getTrakSegClose() +{ + return String(_GPX_TRKSEG_TAIL); +} + +String GPX::getInfo() +{ + String localStr(""); + if (_name.length() > 0) + { + localStr += _GPX_NAME_HEAD; + localStr += wrapCDATA(_name); + localStr += _GPX_NAME_TAIL; + } + if (_desc.length() > 0) + { + localStr += _GPX_DESC_HEAD; + localStr += wrapCDATA(_desc); + localStr += _GPX_DESC_TAIL; + } + return localStr; +} + +String GPX::getPt(String typ, String lon, String lat) +{ + String localStr(_GPX_PT_HEAD); + //localStr = localStr.replace("TYPE",typ); + localStr.replace("TYPE", typ); + localStr += lat + "\" lon=\""; + localStr += lon + "\">"; + if (_ele.length() > 0) + { + localStr += _GPX_ELE_HEAD; + localStr += _ele; + localStr += _GPX_ELE_TAIL; + } + if (_time.length() > 0) + { + localStr += _GPX_TIME_HEAD; + localStr += _time; + localStr += _GPX_TIME_TAIL; + } + if (_sym.length() > 0) + { + localStr += _GPX_SYM_HEAD; + localStr += _sym; + localStr += _GPX_SYM_TAIL; + } + if (_src.length() > 0) + { + localStr += _GPX_SRC_HEAD; + localStr += wrapCDATA(_src); + localStr += _GPX_SRC_TAIL; + } + String GPX_PT_TAIL = _GPX_PT_TAIL; + GPX_PT_TAIL.replace("TYPE", typ); + localStr += GPX_PT_TAIL; + return localStr; +} + +String GPX::getPt(String typ, String lon, String lat, String ele) +{ + return getPt(typ, lon, lat); +} + +//Set Methods +void GPX::setMetaName(String name) +{ + _metaName = name; +} +void GPX::setMetaDesc(String desc) +{ + _metaDesc = desc; +} +void GPX::setName(String name) +{ + _name = name; +} +void GPX::setDesc(String desc) +{ + _desc = desc; +} +void GPX::setEle(String ele) +{ + _ele = ele; +} +void GPX::setSym(String sym) +{ + _sym = sym; +} +void GPX::setSrc(String src) +{ + _src = src; +} +void GPX::setTime(String time) +{ + _time = time; +} + +//Private Functions +String GPX::wrapCDATA(String input) +{ + String localStr("<![CDATA["); + localStr += input; + localStr += "]]>"; + + return localStr; +} diff --git a/x_track/src/App/Utils/GPX/GPX.h b/x_track/src/App/Utils/GPX/GPX.h new file mode 100644 index 0000000000000000000000000000000000000000..8b3cf503ca591012bd1761bc361602e5594aaf9a --- /dev/null +++ b/x_track/src/App/Utils/GPX/GPX.h @@ -0,0 +1,83 @@ +/* + * GPX Library -- GPX.h + * Created by: Ryan Sutton + * + * Copyright (c) 2010, Ryan M Sutton + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Ryan M Sutton nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GPX_h +#define GPX_h + +#ifdef ARDUINO +#include "WString.h" +#else +#include "../WString/WString.h" +#endif // ARDUINO + +// 'Public' Tags +#define GPX_TRKPT "trkpt" +#define GPX_WPT "wpt" +#define GPX_RTEPT "rtept" + +class GPX +{ +public: + GPX(); + String getOpen(); + String getClose(); + String getMetaData(); + String getTrakOpen(); + String getTrakClose(); + String getTrakSegOpen(); + String getTrakSegClose(); + String getInfo(); + String getPt(String typ, String lon, String lat); + String getPt(String typ, String lon, String lat, String ele); + void setMetaName(String name); + void setMetaDesc(String desc); + void setName(String name); + void setDesc(String desc); + void setEle(String ele); + void setSym(String sym); + void setSrc(String src); + void setTime(String time); +private: + //Variables + String _metaName; + String _metaDesc; + String _name; + String _desc; + String _ele; + String _sym; + String _src; + String _time; + + //Functions + String wrapCDATA(String input); +}; + +#endif + diff --git a/x_track/src/App/Utils/GPX_Parser/GPX_Parser.cpp b/x_track/src/App/Utils/GPX_Parser/GPX_Parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31e18ca1604184bb9c1fe8da2cc44fdd2354d893 --- /dev/null +++ b/x_track/src/App/Utils/GPX_Parser/GPX_Parser.cpp @@ -0,0 +1,118 @@ +#include "GPX_Parser.h" +#include <string.h> + +GPX_Parser::GPX_Parser(Callback_t avaliableCallback, Callback_t readCallback, void* userData) + : _avaliableCallback(avaliableCallback) + , _readCallback(readCallback) + , _userData(userData) +{ +} + +bool GPX_Parser::readStringUntil(char terminator, String* str) +{ + bool retval = false; + char strBuf[64]; + + size_t len = readBytesUntil(terminator, strBuf, sizeof(strBuf)); + + if (len < sizeof(strBuf)) { + strBuf[len] = '\0'; + *str = strBuf; + retval = true; + } + + return retval; +} + +int GPX_Parser::getNext(Point_t* point) +{ + String str; + int flag = FLAG_NONE; + + if (!find((char*)"<trkpt")) { + flag |= FLAG_UNMATCHED; + flag |= FLAG_END_OF_FILE; + goto failed; + } + + while (true) { + bool ret = readStringUntil('>', &str); + if (!ret) { + flag |= FLAG_UNMATCHED; + goto failed; + } + + int index = str.indexOf("lat="); + if (index >= 0) { + String lat = str.substring(str.indexOf('"') + 1); + point->latitude = lat.toFloat(); + flag |= FLAG_LATITUDE; + + String lon = str.substring(str.indexOf("lon=")); + lon = lon.substring(lon.indexOf('"') + 1); + point->longitude = lon.toFloat(); + flag |= FLAG_LONGITUDE; + continue; + } + + index = str.indexOf("<ele"); + if (index >= 0) { + if (!readStringUntil('>', &str)) { + flag |= FLAG_UNMATCHED; + goto failed; + } + String ele = str; + point->altitude = ele.toFloat(); + flag |= FLAG_ALTITUDE; + continue; + } + + index = str.indexOf("<time"); + if (index >= 0) { + if (!readStringUntil('>', &str)) { + flag |= FLAG_UNMATCHED; + goto failed; + } + String time = str; + int year, month, day, hour, minute, second; + sscanf( + time.c_str(), + "%d-%d-%dT%d:%d:%dZ", + &year, + &month, + &day, + &hour, + &minute, + &second); + point->time.year = year; + point->time.month = month; + point->time.day = day; + point->time.hour = hour; + point->time.minute = minute; + point->time.second = second; + flag |= FLAG_TIME; + continue; + } + + if (str.length() == 0) { + goto failed; + } + + if (str.indexOf("</trkpt") >= 0) { + break; + } + } + +failed: + return flag; +} + +int GPX_Parser::available() +{ + return _avaliableCallback(this); +} + +int GPX_Parser::read() +{ + return _readCallback(this); +} diff --git a/x_track/src/App/Utils/GPX_Parser/GPX_Parser.h b/x_track/src/App/Utils/GPX_Parser/GPX_Parser.h new file mode 100644 index 0000000000000000000000000000000000000000..28dcc687dd5b6f0af1c9b9e7084e4bb32764a679 --- /dev/null +++ b/x_track/src/App/Utils/GPX_Parser/GPX_Parser.h @@ -0,0 +1,74 @@ +#ifndef __GPX_PARSER_H +#define __GPX_PARSER_H + +#ifdef ARDUINO +#include "Stream.h" +#else +#include "../Stream/Stream.h" +#endif /* ARDUINO */ + +class GPX_Parser : public Stream { +public: + typedef int (*Callback_t)(GPX_Parser* parser); + + typedef struct { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + } Time_t; + + typedef struct + { + float longitude; + float latitude; + float altitude; + Time_t time; + } Point_t; + + typedef enum { + FLAG_NONE = 0, + + /* Error */ + FLAG_END_OF_FILE = 1 << 0, + FLAG_OVER_FLOW = 1 << 1, + FLAG_UNMATCHED = 1 << 2, + FLAG_RESERVE = 1 << 3, + + /* Data ready */ + FLAG_LONGITUDE = 1 << 4, + FLAG_LATITUDE = 1 << 5, + FLAG_ALTITUDE = 1 << 6, + FLAG_TIME = 1 << 7 + } Flag_t; + +public: + GPX_Parser(Callback_t avaliableCallback, Callback_t readCallback, void* userData); + int getNext(Point_t* point); + void* getUserData() { return _userData; } + +private: + virtual int available(); + virtual int read(); + virtual int peek() + { + return 0; + } + virtual void flush() { } + virtual size_t write(uint8_t ch) + { + return 0; + } + using Print::write; + + bool readStringUntil(char terminator, String* str); + +private: + Callback_t _avaliableCallback; + Callback_t _readCallback; + void* _userData; +}; + +#endif diff --git a/x_track/src/App/Utils/Geo/Geo.cpp b/x_track/src/App/Utils/Geo/Geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9238a09a183cbd67bd638f87b54963e48bae43f5 --- /dev/null +++ b/x_track/src/App/Utils/Geo/Geo.cpp @@ -0,0 +1,120 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "Geo.h" +#include <cfloat> +#include <cmath> + +/* clang-format off */ + +#define TWO_PI (2.0 * M_PI) +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define RADIANS(deg) ((deg) * DEG_TO_RAD) +#define DEGREES(rad) ((rad) * RAD_TO_DEG) +#define SQ(x) ((x) * (x)) + +/* clang-format on */ + +static inline bool math_zero(float a) +{ + return (fabsf(a) < FLT_EPSILON); +} + +double Geo::distanceBetween(double lat1, double long1, double lat2, double long2) +{ + /* returns distance in meters between two positions, both specified + * as signed decimal-DEGREES latitude and longitude. Uses great-circle + * distance computation for hypothetical sphere of radius 6372795 meters. + * Because Earth is no exact sphere, rounding errors may be up to 0.5%. + * Courtesy of Maarten Lamers + */ + double delta = RADIANS(long1 - long2); + double sdlong = sin(delta); + double cdlong = cos(delta); + lat1 = RADIANS(lat1); + lat2 = RADIANS(lat2); + double slat1 = sin(lat1); + double clat1 = cos(lat1); + double slat2 = sin(lat2); + double clat2 = cos(lat2); + delta = (clat1 * slat2) - (slat1 * clat2 * cdlong); + delta = SQ(delta); + delta += SQ(clat2 * sdlong); + delta = sqrt(delta); + double denom = (slat1 * slat2) + (clat1 * clat2 * cdlong); + delta = atan2(delta, denom); + return delta * 6372795; +} + +double Geo::courseTo(double lat1, double long1, double lat2, double long2) +{ + /* returns course in DEGREES (North=0, West=270) from position 1 to position 2, + * both specified as signed decimal-DEGREES latitude and longitude. + * Because Earth is no exact sphere, calculated course may be off by a tiny fraction. + * Courtesy of Maarten Lamers + */ + double dlon = RADIANS(long2 - long1); + lat1 = RADIANS(lat1); + lat2 = RADIANS(lat2); + double a1 = sin(dlon) * cos(lat2); + double a2 = sin(lat1) * cos(lat2) * cos(dlon); + a2 = cos(lat1) * sin(lat2) - a2; + a2 = atan2(a1, a2); + if (a2 < 0.0) { + a2 += TWO_PI; + } + + return DEGREES(a2); +} + +const char* Geo::cardinal(float course) +{ + static const char* directions[] = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW" }; + int direction = (int)((course + 11.25f) / 22.5f); + return directions[direction % 16]; +} + +float Geo::grade(float height, float distance) +{ + if (math_zero(distance)) { + return 0; + } + + return (height / distance) * 100.0f; +} + +float Geo::slope(float height, float distance) +{ + return DEGREES(atan2f(height, distance)); +} + +float Geo::sealevel(float pressure, float altitude) +{ + return (pressure / powf(1 - (altitude / 44330.0f), 5.255f)); +} + +float Geo::pressureToAltitude(float pressure, float sealevel) +{ + return (44330.0f * (1 - powf(pressure / sealevel, 1 / 5.255f))); +} diff --git a/x_track/src/App/Utils/Geo/Geo.h b/x_track/src/App/Utils/Geo/Geo.h new file mode 100644 index 0000000000000000000000000000000000000000..0c6167ab90e8a137d0b4bbccc21ad1731707871f --- /dev/null +++ b/x_track/src/App/Utils/Geo/Geo.h @@ -0,0 +1,116 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __GEO_H +#define __GEO_H + +namespace Geo { + +/** + * @brief Calculate the distance between two points on the Earth's surface. + * @param lat1 Latitude of the first point in degrees. + * @param long1 Longitude of the first point in degrees. + * @param lat2 Latitude of the second point in degrees. + * @param long2 Longitude of the second point in degrees. + * @return Distance between the two points in meters. + */ +double distanceBetween(double lat1, double long1, double lat2, double long2); + +/** + * @brief Calculate the course to reach the second point from the first point. + * @param lat1 Latitude of the first point in degrees. + * @param long1 Longitude of the first point in degrees. + * @param lat2 Latitude of the second point in degrees. + * @param long2 Longitude of the second point in degrees. + * @return Course to reach the second point from the first point in degrees. + */ +double courseTo(double lat1, double long1, double lat2, double long2); + +/** + * @brief Calculate the cardinal direction of the course. + * @param course Course in degrees. + * @return Cardinal direction of the course. + */ +const char* cardinal(float course); + +/** + * @brief Calculate the grade of the slope. + * @param height Height of the slope in meters. + * @param distance Distance between the two points on the slope in meters. + * @return Grade of the slope in percent. + * @note The formula used is: grade = (height / distance) * 100. + * @note If the distance is zero, the function returns zero. +*/ +float grade(float height, float distance); + +/** + * @brief Calculate the slope of the line. + * @param height Height of the slope in meters. + * @param distance Distance between the two points on the slope in meters. + * @return Slope of the line in degrees. + * @note The formula used is: slope = atan2f(height, distance) * 180 / pi. + * @note If the distance is zero, the function returns zero. + */ +float slope(float height, float distance); + +/** + * @brief Given a pressure (mb) taken at a specific altitude (meters), + * calculate the equivalent pressure (mb) at sea level. + * This produces pressure readings that can be used for weather measurements. + * @param pressure Pressure (mb) taken at a specific altitude (meters). + * @param altitude Altitude (meters) at which the pressure was taken. + * @return Equivalent pressure (mb) at sea level. + */ +float sealevel(float pressure, float altitude); + +/** + * @brief Given a pressure (mb) and the pressure at sea level (mb), + * return altitude (meters) above sea level. + * @param pressure Pressure (mb) taken at a specific altitude (meters). + * @param sealevel Pressure (mb) at sea level. + * @return Altitude (meters) above sea level. + */ +float pressureToAltitude(float pressure, float sealevel); + +/** + * @brief Convert kilopascals (kPa) to millibars (mb). + * @param kpa Pressure in kilopascals. + * @return Pressure in millibars. + */ +static inline float kpaTombar(float kpa) +{ + return kpa * 10.0f; +} + +/** + * @brief Convert millibars (mb) to kilopascals (kPa). + * @param mb Pressure in millibars. + * @return Pressure in kilopascals. + */ +static inline float mbarTokpa(float mb) +{ + return mb / 10.0f; +} + +} // namespace Geo + +#endif // __GEO_H diff --git a/x_track/src/App/Utils/MapConv/MapConv.cpp b/x_track/src/App/Utils/MapConv/MapConv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..115d5c08d2d47e9f210270314d49d57993a22e85 --- /dev/null +++ b/x_track/src/App/Utils/MapConv/MapConv.cpp @@ -0,0 +1,120 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "MapConv.h" +#include "TileSystem.h" +#include <cmath> +#include <cstdio> + +#define LONGITUDE_OFFSET 0.008 +#define LATITUDE_OFFSET 0.009 + +using namespace ::Microsoft_MapPoint; + +MapConv::MapConv(bool coordTransformEnable, int level, int tileSize) + : _longitudeOffset(0) + , _latitudeOffset(0) + , _longitudeLast(0) + , _latitudeLast(0) + , _level(level) + , _tileSize(tileSize) + , _coordTransformEnable(coordTransformEnable) +{ +} + +void MapConv::setCoordTransformEnable(bool enable) +{ + _coordTransformEnable = enable; +} + +bool MapConv::getCoordTransformEnable() +{ + return _coordTransformEnable; +} + +void MapConv::setLevel(int level) +{ + _level = level; +} + +int MapConv::getLevel() +{ + return _level; +} + +MapConv::Tile_t MapConv::getTile(double longitude, double latitude) +{ + Point_t point = getCoordinate(longitude, latitude); + return posToTile(point.x, point.y); +} + +MapConv::Point_t MapConv::getCoordinate(double longitude, double latitude) +{ + int pixelX, pixelY; + + TileSystem::LatLongToPixelXY( + latitude, + longitude, + _level, + &pixelX, + &pixelY); + + Point_t point; + point.x = pixelX; + point.y = pixelY; + return point; +}; + +int MapConv::getPath(char* path, size_t len, int32_t x, int32_t y) +{ + int tileX = x / _tileSize; + int tileY = y / _tileSize; + int ret = snprintf(path, len, "/%d/%d/%d", _level, tileX, tileY); + return ret; +} + +MapConv::Tile_t MapConv::posToTile(int32_t x, int32_t y) +{ + Tile_t mapTile; + mapTile.tileX = x / _tileSize; + mapTile.tileY = y / _tileSize; + mapTile.subX = x % _tileSize; + mapTile.subY = y % _tileSize; + return mapTile; +} + +MapConv::Point_t MapConv::convertPoint(int32_t x, int32_t y, int level) +{ + Point_t point; + + int diff = level - _level; + + if (diff >= 0) { + point.x = x >> diff; + point.y = y >> diff; + } else { + point.x = x << -diff; + point.y = y << -diff; + } + + return point; +} diff --git a/x_track/src/App/Utils/MapConv/MapConv.h b/x_track/src/App/Utils/MapConv/MapConv.h new file mode 100644 index 0000000000000000000000000000000000000000..b30ffe3bef4a69474cba2626a505c1fd1a03b419 --- /dev/null +++ b/x_track/src/App/Utils/MapConv/MapConv.h @@ -0,0 +1,69 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MAP_CONV_H +#define __MAP_CONV_H + +#include <stddef.h> +#include <stdint.h> + +class MapConv { +public: + typedef struct + { + uint32_t tileX; + uint32_t tileY; + uint32_t subX; + uint32_t subY; + } Tile_t; + + typedef struct + { + int32_t x; + int32_t y; + } Point_t; + +public: + MapConv(bool coordTransformEnable, int level, int tileSize = 256); + ~MapConv() { } + + void setCoordTransformEnable(bool enable); + bool getCoordTransformEnable(); + void setLevel(int level); + int getLevel(); + Tile_t getTile(double longitude, double latitude); + int getPath(char* path, size_t len, int32_t x, int32_t y); + Point_t getCoordinate(double longitude, double latitude); + Tile_t posToTile(int32_t x, int32_t y); + Point_t convertPoint(int32_t x, int32_t y, int level); + +private: + double _longitudeOffset; + double _latitudeOffset; + double _longitudeLast; + double _latitudeLast; + int _level; + int _tileSize; + bool _coordTransformEnable; +}; + +#endif diff --git a/x_track/src/App/Utils/MapConv/TileSystem.cpp b/x_track/src/App/Utils/MapConv/TileSystem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..35d090b585152ece1d5e84ab726b10380358ca1f --- /dev/null +++ b/x_track/src/App/Utils/MapConv/TileSystem.cpp @@ -0,0 +1,140 @@ +#include "TileSystem.h" + +#include <algorithm> +#include <math.h> +#include <string.h> + +using namespace Microsoft_MapPoint; + +static const double EarthRadius = 6378137; +static const double MinLatitude = -85.05112878; +static const double MaxLatitude = 85.05112878; +static const double MinLongitude = -180; +static const double MaxLongitude = 180; +static const double MATH_PI = 3.1415926535897932384626433832795; + +/// <summary> +/// Clips a number to the specified minimum and maximum values. +/// </summary> +/// <param name="n">The number to clip.</param> +/// <param name="minValue">Minimum allowable value.</param> +/// <param name="maxValue">Maximum allowable value.</param> +/// <returns>The clipped value.</returns> +static double Clip(double n, double minValue, double maxValue) +{ + return std::min(std::max(n, minValue), maxValue); +} + + +uint32_t TileSystem::MapSize(int levelOfDetail) +{ + return (uint32_t)256 << levelOfDetail; +} + +double TileSystem::GroundResolution(double latitude, int levelOfDetail) +{ + latitude = Clip(latitude, MinLatitude, MaxLatitude); + return cos(latitude * MATH_PI / 180) * 2 * MATH_PI * EarthRadius / MapSize(levelOfDetail); +} + +double TileSystem::MapScale(double latitude, int levelOfDetail, int screenDpi) +{ + return GroundResolution(latitude, levelOfDetail) * screenDpi / 0.0254; +} + +void TileSystem::LatLongToPixelXY(double latitude, double longitude, int levelOfDetail, int* pixelX, int* pixelY) +{ + latitude = Clip(latitude, MinLatitude, MaxLatitude); + longitude = Clip(longitude, MinLongitude, MaxLongitude); + + double x = (longitude + 180) / 360; + double sinLatitude = sin(latitude * MATH_PI / 180); + double y = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * MATH_PI); + + uint32_t mapSize = MapSize(levelOfDetail); + *pixelX = (int)Clip(x * mapSize + 0.5, 0, mapSize - 1); + *pixelY = (int)Clip(y * mapSize + 0.5, 0, mapSize - 1); +} + +void TileSystem::PixelXYToLatLong(int pixelX, int pixelY, int levelOfDetail, double* latitude, double* longitude) +{ + double mapSize = MapSize(levelOfDetail); + double x = (Clip(pixelX, 0, mapSize - 1) / mapSize) - 0.5; + double y = 0.5 - (Clip(pixelY, 0, mapSize - 1) / mapSize); + + *latitude = 90 - 360 * atan(exp(-y * 2 * MATH_PI)) / MATH_PI; + *longitude = 360 * x; +} + +void TileSystem::PixelXYToTileXY(int pixelX, int pixelY, int* tileX, int* tileY) +{ + *tileX = pixelX / 256; + *tileY = pixelY / 256; +} + +void TileSystem::TileXYToPixelXY(int tileX, int tileY, int* pixelX, int* pixelY) +{ + *pixelX = tileX * 256; + *pixelY = tileY * 256; +} + +void TileSystem::TileXYToQuadKey(int tileX, int tileY, int levelOfDetail, char* quadKeyBuffer, uint32_t len) +{ + uint32_t quadKeyIndex = 0; + for (int i = levelOfDetail; i > 0; i--) + { + char digit = '0'; + int mask = 1 << (i - 1); + if ((tileX & mask) != 0) + { + digit++; + } + if ((tileY & mask) != 0) + { + digit++; + digit++; + } + quadKeyBuffer[quadKeyIndex] = digit; + quadKeyIndex++; + + if (quadKeyIndex >= len - 1) + { + break; + } + } + + quadKeyBuffer[quadKeyIndex] = '\0'; +} + +void TileSystem::QuadKeyToTileXY(const char* quadKey, int* tileX, int* tileY, int* levelOfDetail) +{ + *tileX = *tileY = 0; + int len = (int)strlen(quadKey); + *levelOfDetail = len; + for (int i = len; i > 0; i--) + { + int mask = 1 << (i - 1); + switch (quadKey[len - i]) + { + case '0': + break; + + case '1': + *tileX |= mask; + break; + + case '2': + *tileY |= mask; + break; + + case '3': + *tileX |= mask; + *tileY |= mask; + break; + + default: + //throw new ArgumentException("Invalid QuadKey digit sequence."); + break; + } + } +} diff --git a/x_track/src/App/Utils/MapConv/TileSystem.h b/x_track/src/App/Utils/MapConv/TileSystem.h new file mode 100644 index 0000000000000000000000000000000000000000..b635d830cd778da71b989f17c307ecd79383d2a0 --- /dev/null +++ b/x_track/src/App/Utils/MapConv/TileSystem.h @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// <copyright company="Microsoft"> +// Copyright (c) 2006-2009 Microsoft Corporation. All rights reserved. +// </copyright> +//------------------------------------------------------------------------------ + +// Reference Link: https://docs.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system?redirectedfrom=MSDN + +#ifndef __MICROSOFT_MAP_POINT_TILE_SYSTEM_H +#define __MICROSOFT_MAP_POINT_TILE_SYSTEM_H + +#include <stdint.h> + +namespace Microsoft_MapPoint +{ + +namespace TileSystem +{ + +/// <summary> +/// Determines the map width and height (in pixels) at a specified level +/// of detail. +/// </summary> +/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) +/// to 23 (highest detail).</param> +/// <returns>The map width and height in pixels.</returns> +uint32_t MapSize(int levelOfDetail); + +/// <summary> +/// Determines the ground resolution (in meters per pixel) at a specified +/// latitude and level of detail. +/// </summary> +/// <param name="latitude">Latitude (in degrees) at which to measure the +/// ground resolution.</param> +/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) +/// to 23 (highest detail).</param> +/// <returns>The ground resolution, in meters per pixel.</returns> +double GroundResolution(double latitude, int levelOfDetail); + +/// <summary> +/// Determines the map scale at a specified latitude, level of detail, +/// and screen resolution. +/// </summary> +/// <param name="latitude">Latitude (in degrees) at which to measure the +/// map scale.</param> +/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) +/// to 23 (highest detail).</param> +/// <param name="screenDpi">Resolution of the screen, in dots per inch.</param> +/// <returns>The map scale, expressed as the denominator N of the ratio 1 : N.</returns> +double MapScale(double latitude, int levelOfDetail, int screenDpi); + +/// <summary> +/// Converts a point from latitude/longitude WGS-84 coordinates (in degrees) +/// into pixel XY coordinates at a specified level of detail. +/// </summary> +/// <param name="latitude">Latitude of the point, in degrees.</param> +/// <param name="longitude">Longitude of the point, in degrees.</param> +/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) +/// to 23 (highest detail).</param> +/// <param name="pixelX">Output parameter receiving the X coordinate in pixels.</param> +/// <param name="pixelY">Output parameter receiving the Y coordinate in pixels.</param> +void LatLongToPixelXY(double latitude, double longitude, int levelOfDetail, int* pixelX, int* pixelY); + +/// <summary> +/// Converts a pixel from pixel XY coordinates at a specified level of detail +/// into latitude/longitude WGS-84 coordinates (in degrees). +/// </summary> +/// <param name="pixelX">X coordinate of the point, in pixels.</param> +/// <param name="pixelY">Y coordinates of the point, in pixels.</param> +/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) +/// to 23 (highest detail).</param> +/// <param name="latitude">Output parameter receiving the latitude in degrees.</param> +/// <param name="longitude">Output parameter receiving the longitude in degrees.</param> +void PixelXYToLatLong(int pixelX, int pixelY, int levelOfDetail, double* latitude, double* longitude); + +/// <summary> +/// Converts pixel XY coordinates into tile XY coordinates of the tile containing +/// the specified pixel. +/// </summary> +/// <param name="pixelX">Pixel X coordinate.</param> +/// <param name="pixelY">Pixel Y coordinate.</param> +/// <param name="tileX">Output parameter receiving the tile X coordinate.</param> +/// <param name="tileY">Output parameter receiving the tile Y coordinate.</param> +void PixelXYToTileXY(int pixelX, int pixelY, int* tileX, int* tileY); + +/// <summary> +/// Converts tile XY coordinates into pixel XY coordinates of the upper-left pixel +/// of the specified tile. +/// </summary> +/// <param name="tileX">Tile X coordinate.</param> +/// <param name="tileY">Tile Y coordinate.</param> +/// <param name="pixelX">Output parameter receiving the pixel X coordinate.</param> +/// <param name="pixelY">Output parameter receiving the pixel Y coordinate.</param> +void TileXYToPixelXY(int tileX, int tileY, int* pixelX, int* pixelY); + +/// <summary> +/// Converts tile XY coordinates into a QuadKey at a specified level of detail. +/// </summary> +/// <param name="tileX">Tile X coordinate.</param> +/// <param name="tileY">Tile Y coordinate.</param> +/// <param name="levelOfDetail">Level of detail, from 1 (lowest detail) +/// to 23 (highest detail).</param> +/// <returns>A string containing the QuadKey.</returns> +void TileXYToQuadKey(int tileX, int tileY, int levelOfDetail, char* quadKeyBuffer, uint32_t len); + +/// <summary> +/// Converts a QuadKey into tile XY coordinates. +/// </summary> +/// <param name="quadKey">QuadKey of the tile.</param> +/// <param name="tileX">Output parameter receiving the tile X coordinate.</param> +/// <param name="tileY">Output parameter receiving the tile Y coordinate.</param> +/// <param name="levelOfDetail">Output parameter receiving the level of detail.</param> +void QuadKeyToTileXY(const char* quadKey, int* tileX, int* tileY, int* levelOfDetail); +} + +} + +#endif diff --git a/x_track/src/App/Utils/MapView/MapView.cpp b/x_track/src/App/Utils/MapView/MapView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ad21c8029f85dd4a7cc1668ebb2ad263b00d694 --- /dev/null +++ b/x_track/src/App/Utils/MapView/MapView.cpp @@ -0,0 +1,449 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "MapView.h" +#include "Utils/lv_msg/lv_msg.h" +#include <string.h> + +#define MAP_MOVED_STATE LV_STATE_USER_1 +#define MAP_RESET_TIMEOUT (60 * 1000) + +MapView::MapView( + uint32_t width, + uint32_t height, + lv_obj_t* parent, + EventListener* listener, + void* userData) + : _tileView(width, height) + , _mapConv(true, 16) + , _curGeoCoord { 0 } + , _curLevel(0) + , _config { 0 } + , _viewCont(nullptr) + , _timerMapReset(nullptr) + , _lastShortClickTime(0) + , _animBusy(false) + , _animStart { 0 } + , _animEnd { 0 } + , _tileSrcEanble(true) + , _listener(listener) + , _userData(userData) +{ + _tileView.setFocusPos(0, 0); + + lv_obj_t* viewCont = lv_obj_create(parent); + _viewCont = viewCont; + lv_obj_remove_style_all(viewCont); + lv_obj_set_size(viewCont, width, height); + + /* scoll auto load map view */ + lv_obj_add_event( + viewCont, [](lv_event_t* e) { + if (!lv_indev_get_act()) { + return; + } + + auto self = (MapView*)lv_event_get_user_data(e); + self->onMoving(); + + /* update focus point */ + auto focus = self->getFocus(); + self->setFocusRow(focus.x, focus.y); + }, + LV_EVENT_SCROLL, this); + + /* double click to zoom up */ + lv_obj_add_event( + viewCont, [](lv_event_t* e) { + auto self = (MapView*)lv_event_get_user_data(e); + + /* not scrollable */ + if (!lv_obj_has_flag(self->_viewCont, LV_OBJ_FLAG_SCROLLABLE)) { + return; + } + + /* double click */ + if (lv_tick_elaps(self->_lastShortClickTime) < 300) { + if (self->setLevel(self->_curLevel + 1)) { + self->sendEvent(EVENT_ID::LEVEL_CHANGED, &self->_curLevel); + } + + self->onMoving(); + + lv_point_t p; + lv_indev_get_point(lv_indev_get_act(), &p); + + lv_obj_t* cont = lv_obj_get_child(self->_viewCont, 0); + lv_area_t area; + lv_obj_get_coords(cont, &area); + + int32_t x = p.x - area.x1; + int32_t y = p.y - area.y1; + + auto oriPos = self->_tileView.getTilePos(0); + self->setFocus(oriPos.x + x, oriPos.y + y, LV_ANIM_ON); + } + + self->_lastShortClickTime = lv_tick_get(); + }, + LV_EVENT_SHORT_CLICKED, this); + + /* coord change move map */ + subscribe(MSG_ID::GEO_COORD_UPDATE, viewCont, [](lv_event_t* e) { + auto self = (MapView*)lv_event_get_user_data(e); + auto msg = lv_event_get_msg(e); + + if (self->msgID(MSG_ID::GEO_COORD_UPDATE) != lv_msg_get_id(msg)) { + return; + } + auto obj = lv_event_get_target_obj(e); + + /* not move when edit */ + if (lv_obj_has_state(obj, MAP_MOVED_STATE)) { + return; + } + + auto geoCoord = (const GeoCoord_t*)lv_msg_get_payload(msg); + self->setFocus(geoCoord); + }); + + subscribe(MSG_ID::MOVE_RESET, viewCont, [](lv_event_t* e) { + auto self = (MapView*)lv_event_get_user_data(e); + auto msg = lv_event_get_msg(e); + + if (self->msgID(MSG_ID::MOVE_RESET) != lv_msg_get_id(msg)) { + return; + } + + auto obj = lv_event_get_current_target_obj(e); + lv_obj_clear_state(obj, MAP_MOVED_STATE); + self->setFocus(&self->_curGeoCoord, true); + }); + + /* map cont */ + { + lv_obj_t* cont = lv_obj_create(viewCont); + lv_obj_remove_style_all(cont); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_CLICKABLE); + + TileView::Rect_t rect = _tileView.getTileRect(); + lv_obj_set_size(cont, rect.width, rect.height); + + /* map img */ + uint32_t tileNum = _tileView.getTileNum(); + for (uint32_t i = 0; i < tileNum; i++) { + lv_obj_t* img = lv_img_create(cont); + lv_obj_remove_style_all(img); + } + } + + /* map reset timer */ + _timerMapReset = lv_timer_create([](lv_timer_t* timer) { + auto self = (MapView*)lv_timer_get_user_data(timer); + self->publish(MSG_ID::MOVE_RESET); + self->sendEvent(EVENT_ID::MOVE_RESET); + lv_timer_pause(timer); + }, + 0, this); + lv_timer_pause(_timerMapReset); +} + +MapView::~MapView() +{ + lv_timer_del(_timerMapReset); + lv_obj_del(_viewCont); + _viewCont = nullptr; +} + +void MapView::setConfig(const MapConfig_t* config) +{ + _config = *config; + _mapConv.setCoordTransformEnable(_config.coordTrans); + tileTectInvalidate(); +} + +void MapView::setFocus(int32_t x, int32_t y, bool animEn) +{ + if (animEn) { + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, this); + lv_anim_set_path_cb(&a, lv_anim_path_ease_out); + lv_anim_set_time(&a, 300); + lv_anim_set_values(&a, 0, 1000); + lv_anim_set_ready_cb(&a, [](lv_anim_t* anim) { + auto self = (MapView*)anim->var; + self->cancelAnim(); + }); + + lv_anim_set_exec_cb(&a, [](void* var, int32_t v) { + auto self = (MapView*)var; + int32_t fx = lv_map(v, 0, 1000, self->_animStart.x, self->_animEnd.x); + int32_t fy = lv_map(v, 0, 1000, self->_animStart.y, self->_animEnd.y); + self->setFocusRow(fx, fy); + }); + + _animStart = getFocus(); + _animEnd.x = x; + _animEnd.y = y; + _animBusy = true; + lv_anim_start(&a); + return; + } + + if (_animBusy) { + return; + } + + setFocusRow(x, y); +} + +void MapView::setFocus(const GeoCoord_t* geoCoord, bool animEn) +{ + MapConv::Point_t point = _mapConv.getCoordinate(geoCoord->longitude, geoCoord->latitude); + setFocus(point.x, point.y, animEn); +} + +bool MapView::setLevel(int level) +{ + /* check level */ + if (level < _config.levelMin || level > _config.levelMax) { + return false; + } + + TileView::Point_t cur = _tileView.getFocusPos(); + + _mapConv.setLevel(level); + MapConv::Point_t newPoint = _mapConv.convertPoint(cur.x, cur.y, _curLevel); + _curLevel = level; + tileTectInvalidate(); + cancelAnim(); + setFocus(newPoint.x, newPoint.y); + + return true; +} + +void MapView::setScrollEanble(bool enable) +{ + enable ? lv_obj_add_flag(_viewCont, LV_OBJ_FLAG_SCROLLABLE) : lv_obj_clear_flag(_viewCont, LV_OBJ_FLAG_SCROLLABLE); +} + +void MapView::setTileSrcEanble(bool enable) +{ + _tileSrcEanble = enable; +} + +MapView::MapPoint_t MapView::getFocus() +{ + auto scroll_x = lv_obj_get_scroll_x(_viewCont); + auto scroll_y = lv_obj_get_scroll_y(_viewCont); + auto tilePoint = _tileView.getTilePos(0); + auto focusX = tilePoint.x + scroll_x + _tileView.getViewWidth() / 2; + auto focusY = tilePoint.y + scroll_y + _tileView.getViewHeight() / 2; + return { focusX, focusY }; +} + +lv_obj_t* MapView::getViewCont() +{ + return _viewCont; +} + +MapView::MapPoint_t MapView::getOffset(int32_t x, int32_t y) +{ + TileView::Point_t tilePoint = { x, y }; + auto offset = _tileView.getOffset(&tilePoint); + return { offset.x, offset.y }; +} + +void MapView::addArrowImage(const void* src) +{ + lv_obj_t* img = lv_img_create(_viewCont); + lv_img_set_src(img, src); + lv_obj_add_flag(img, LV_OBJ_FLAG_HIDDEN); + lv_obj_update_layout(img); + lv_obj_set_style_translate_x(img, -lv_obj_get_width(img) / 2, 0); + lv_obj_set_style_translate_y(img, -lv_obj_get_height(img) / 2, 0); + + subscribe(MSG_ID::GEO_COORD_UPDATE, img, [](lv_event_t* e) { + auto obj = lv_event_get_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (MapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::GEO_COORD_UPDATE) != lv_msg_get_id(msg)) { + return; + } + + /* copy geo coord */ + auto geoCoord = (const GeoCoord_t*)lv_msg_get_payload(msg); + + if (!self->arrowCheck(obj)) { + return; + } + + lv_img_set_angle(obj, geoCoord->course * 10); + }); + + subscribe(MSG_ID::TILE_RECT_CHANGED, img, [](lv_event_t* e) { + auto obj = lv_event_get_target_obj(e); + auto msg = lv_event_get_msg(e); + auto self = (MapView*)lv_event_get_user_data(e); + + if (self->msgID(MSG_ID::TILE_RECT_CHANGED) != lv_msg_get_id(msg)) { + return; + } + + self->arrowCheck(obj); + }); +} + +void MapView::setGeoCoord(const GeoCoord_t* geoCoord) +{ + _curGeoCoord = *geoCoord; + publish(MSG_ID::GEO_COORD_UPDATE, &_curGeoCoord); +} + +void MapView::reset(uint32_t timeout) +{ + lv_timer_set_period(_timerMapReset, timeout); + lv_timer_reset(_timerMapReset); + lv_timer_resume(_timerMapReset); +} + +lv_uintptr_t MapView::msgID(MSG_ID id) +{ + return (lv_uintptr_t)this + (lv_uintptr_t)id; +} + +void MapView::publish(MSG_ID id, const void* payload) +{ + lv_msg_send(msgID(id), payload); +} + +void MapView::subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb) +{ + lv_msg_subscribe_obj(msgID(id), obj, this); + lv_obj_add_event(obj, event_cb, LV_EVENT_MSG_RECEIVED, this); +} + +void MapView::sendEvent(EVENT_ID id, const void* param) +{ + _listener(id, param, _userData); +} + +void MapView::onMoving() +{ + cancelAnim(); + reset(MAP_RESET_TIMEOUT); + + if (lv_obj_has_state(_viewCont, MAP_MOVED_STATE)) { + return; + } + + lv_obj_add_state(_viewCont, MAP_MOVED_STATE); + publish(MSG_ID::MOVE_START); + sendEvent(EVENT_ID::MOVE_START); +} + +void MapView::setFocusRow(int32_t x, int32_t y) +{ + _tileView.setFocusPos(x, y); + TileView::Point offset = _tileView.getTileRectOffset(); + lv_obj_scroll_to(_viewCont, offset.x, offset.y, LV_ANIM_OFF); + + /* map reload check */ + if (!isTileRectChanged()) { + return; + } + + /* tile src */ + if (_tileSrcEanble) { + lv_obj_t* cont = lv_obj_get_child(_viewCont, 0); + uint32_t tileNum = _tileView.getTileNum(); + lv_disp_t* disp = lv_obj_get_disp(cont); + lv_disp_enable_invalidation(disp, false); + for (uint32_t i = 0; i < tileNum; i++) { + TileView::Point_t pos = _tileView.getTilePos(i); + lv_obj_t* img = lv_obj_get_child(cont, i); + + char mapPath[32]; + _mapConv.getPath(mapPath, sizeof(mapPath), pos.x, pos.y); + + char realPath[64]; + lv_snprintf(realPath, sizeof(realPath), + "%s%s.%s", _config.path, mapPath, _config.ext); + + auto imgPos = _tileView.getOffset(&pos); + lv_obj_set_pos(img, imgPos.x, imgPos.y); + lv_img_set_src(img, realPath); + } + lv_disp_enable_invalidation(disp, true); + + /* merge invalid area */ + lv_obj_invalidate(_viewCont); + } + + /* update tile view rect */ + _curTileRect = _tileView.getTileRect(); + LV_LOG_INFO("tile rect: %" LV_PRId32 ", %" LV_PRId32 ", %" LV_PRId32 ", %" LV_PRId32, + _curTileRect.x, _curTileRect.y, _curTileRect.width, _curTileRect.height); + + publish(MSG_ID::TILE_RECT_CHANGED, &_curTileRect); + sendEvent(EVENT_ID::TILE_RECT_CHANGED, &_curTileRect); +} + +void MapView::cancelAnim() +{ + if (!_animBusy) { + return; + } + + lv_anim_del(this, NULL); + _animBusy = false; +} + +bool MapView::isTileRectChanged() +{ + TileView::Rect_t rect = _tileView.getTileRect(); + return memcmp(&_curTileRect, &rect, sizeof(TileView::Rect_t)) != 0; +} + +void MapView::tileTectInvalidate() +{ + lv_memzero(&_curTileRect, sizeof(TileView::Rect_t)); +} + +bool MapView::arrowCheck(lv_obj_t* img) +{ + auto mapCoord = _mapConv.getCoordinate(_curGeoCoord.longitude, _curGeoCoord.latitude); + auto imgPos = _tileView.getOffset((TileView::Point_t*)&mapCoord); + + if (imgPos.x < 0 || imgPos.y < 0 + || imgPos.x > _curTileRect.width || imgPos.y > _curTileRect.height) { + lv_obj_add_flag(img, LV_OBJ_FLAG_HIDDEN); + return false; + } + + lv_obj_set_pos(img, imgPos.x, imgPos.y); + lv_obj_clear_flag(img, LV_OBJ_FLAG_HIDDEN); + return true; +} diff --git a/x_track/src/App/Utils/MapView/MapView.h b/x_track/src/App/Utils/MapView/MapView.h new file mode 100644 index 0000000000000000000000000000000000000000..235631cd7eb04a5dabc191336361ba1c056aa07b --- /dev/null +++ b/x_track/src/App/Utils/MapView/MapView.h @@ -0,0 +1,131 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MAP_VIEW_H +#define __MAP_VIEW_H + +#include "Utils/MapConv/MapConv.h" +#include "Utils/TileView/TileView.h" +#include "lvgl/lvgl.h" + +class MapView { +public: + typedef struct + { + float longitude; + float latitude; + float altitude; + float course; + } GeoCoord_t; + + typedef struct + { + const char* path; + const char* ext; + uint8_t levelMin; + uint8_t levelMax; + bool coordTrans; + } MapConfig_t; + + typedef struct + { + int32_t x; + int32_t y; + } MapPoint_t; + + enum class EVENT_ID { + MOVE_START, /* param: None */ + MOVE_RESET, /* param: None */ + LEVEL_CHANGED, /* param: int */ + TILE_RECT_CHANGED, /* param: TileView::Rect_t */ + _LAST, + }; + + typedef void EventListener(EVENT_ID id, const void* param, void* userData); + +public: + MapView(uint32_t width, uint32_t height, lv_obj_t* parent, EventListener* listener, void* userData); + ~MapView(); + + void setConfig(const MapConfig_t* config); + void setFocus(int32_t x, int32_t y, bool animEn = false); + void setFocus(const GeoCoord_t* geoCoord, bool animEn = false); + bool setLevel(int level); + void setScrollEanble(bool enable); + void setTileSrcEanble(bool enable); + MapPoint_t getFocus(); + lv_obj_t* getViewCont(); + MapPoint_t getOffset(int32_t x, int32_t y); + void addArrowImage(const void* src); + void setGeoCoord(const GeoCoord_t* geoCoord); + void reset(uint32_t timeout); + uint32_t getTileSize() { return _tileView.getTileSize(); } + bool getCoordTrans() { return _mapConv.getCoordTransformEnable(); } + +private: + enum class MSG_ID { + GEO_COORD_UPDATE, /* param: GeoCoord_t */ + TILE_RECT_CHANGED, /* param: TileView::Rect_t */ + MOVE_START, /* param: None */ + MOVE_RESET, /* param: None */ + _LAST, + }; + +private: + TileView _tileView; + MapConv _mapConv; + + /* current state */ + TileView::Rect_t _curTileRect; + GeoCoord_t _curGeoCoord; + int _curLevel; + + /* config */ + MapConfig_t _config; + + /* view interaction */ + lv_obj_t* _viewCont; + lv_timer_t* _timerMapReset; + uint32_t _lastShortClickTime; + bool _animBusy; + MapPoint_t _animStart; + MapPoint_t _animEnd; + bool _tileSrcEanble; + + /* event */ + EventListener* _listener; + void* _userData; + +private: + lv_uintptr_t msgID(MSG_ID id); + void publish(MSG_ID id, const void* payload = nullptr); + void subscribe(MSG_ID id, lv_obj_t* obj, lv_event_cb_t event_cb); + void sendEvent(EVENT_ID id, const void* param = nullptr); + void onMoving(); + void setFocusRow(int32_t x, int32_t y); + void cancelAnim(); + bool isTileRectChanged(); + void tileTectInvalidate(); + bool arrowCheck(lv_obj_t* img); +}; + +#endif // __MAP_VIEW_H diff --git a/x_track/src/App/Utils/PointContainer/PointContainer.cpp b/x_track/src/App/Utils/PointContainer/PointContainer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2bf8ede77971379ffc39241ca7309b9013b8002 --- /dev/null +++ b/x_track/src/App/Utils/PointContainer/PointContainer.cpp @@ -0,0 +1,133 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PointContainer.h" +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +PointContainer::PointContainer() + : _curPushPoint { 0 } + , _curPopPoint { 0 } + , _curPopIndex(0) +{ +} + +PointContainer::~PointContainer() +{ +} + +bool PointContainer::isFlag(const DiffPoint_t* point) +{ + if (point->x == FLAG_END_POINT && point->y == FLAG_END_POINT) { + return true; + } + + if (point->x == FLAG_FULL_POINT && point->y == FLAG_FULL_POINT) { + return true; + } + + return false; +} + +void PointContainer::pushPoint(const FullPoint_t* point) +{ + size_t curIndex = vecPoints.size(); + if (curIndex == 0) { + _curPushPoint = *point; + pushFullPoint(point); + return; + } + + int32_t diffX = point->x - _curPushPoint.x; + int32_t diffY = point->y - _curPushPoint.y; + _curPushPoint = *point; + + if (std::abs((int)diffX) > SCHAR_MAX || std::abs((int)diffY) > SCHAR_MAX) { + pushFullPoint(point); + return; + } + + const DiffPoint_t diffPoint = { (int8_t)diffX, (int8_t)diffY }; + if (isFlag(&diffPoint)) { + pushFullPoint(point); + return; + } + + vecPoints.push_back(diffPoint); +} + +void PointContainer::pushFullPoint(const FullPoint_t* point) +{ + vecPoints.push_back(makeFlag(FLAG_FULL_POINT)); + const DiffPoint_t* pData = (const DiffPoint_t*)point; + for (size_t i = 0; i < sizeof(FullPoint_t) / sizeof(DiffPoint_t); i++) { + vecPoints.push_back(pData[i]); + } +} + +bool PointContainer::popFullPoint(FullPoint_t* point) +{ + size_t size = vecPoints.size(); + if (size - _curPopIndex < 4) { + return false; + } + + DiffPoint_t* pData = (DiffPoint_t*)point; + for (size_t i = 0; i < sizeof(FullPoint_t) / sizeof(DiffPoint_t); i++) { + pData[i] = vecPoints[_curPopIndex]; + _curPopIndex++; + } + return true; +} + +bool PointContainer::popPoint(FullPoint_t* point) +{ + size_t size = vecPoints.size(); + + if (size - _curPopIndex == 0) { + return false; + } + + DiffPoint_t diffPoint = vecPoints[_curPopIndex]; + + if (diffPoint.x == FLAG_FULL_POINT && diffPoint.y == FLAG_FULL_POINT) { + _curPopIndex++; + if (popFullPoint(point)) { + _curPopPoint = *point; + } else { + return false; + } + } else { + _curPopPoint.x += diffPoint.x; + _curPopPoint.y += diffPoint.y; + *point = _curPopPoint; + _curPopIndex++; + } + + return true; +} + +void PointContainer::popStart() +{ + _curPopIndex = 0; +} diff --git a/x_track/src/App/Utils/PointContainer/PointContainer.h b/x_track/src/App/Utils/PointContainer/PointContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..01331743d13341f9e7ce184f0c4f5ea19ba190d5 --- /dev/null +++ b/x_track/src/App/Utils/PointContainer/PointContainer.h @@ -0,0 +1,90 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __POINT_CONTAINER_H +#define __POINT_CONTAINER_H + +#include <stdint.h> +#include <vector> + +class PointContainer { +public: + PointContainer(); + ~PointContainer(); + void pushPoint(int32_t x, int32_t y) + { + const FullPoint_t point = { x, y }; + pushPoint(&point); + } + + bool popPoint(int32_t* x, int32_t* y) + { + FullPoint_t point; + bool retval = popPoint(&point); + + if (retval) { + *x = point.x; + *y = point.y; + } + return retval; + } + + void popStart(); + +private: + typedef enum { + FLAG_END_POINT = 0, + FLAG_FULL_POINT = 1, + } Flag_t; + + typedef struct + { + int32_t x; + int32_t y; + } FullPoint_t; + + typedef struct + { + int8_t x; + int8_t y; + } DiffPoint_t; + +private: + void pushPoint(const FullPoint_t* point); + bool popPoint(FullPoint_t* point); + void pushFullPoint(const FullPoint_t* point); + bool popFullPoint(FullPoint_t* point); + bool isFlag(const DiffPoint_t* point); + inline DiffPoint_t makeFlag(Flag_t flag) + { + DiffPoint_t point = { (int8_t)flag, (int8_t)flag }; + return point; + } + +private: + std::vector<DiffPoint_t> vecPoints; + FullPoint_t _curPushPoint; + FullPoint_t _curPopPoint; + uint32_t _curPopIndex; +}; + +#endif diff --git a/x_track/src/App/Utils/StorageService/StorageService.cpp b/x_track/src/App/Utils/StorageService/StorageService.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9515aaea64673f24251f1d510a0b8669fbb77660 --- /dev/null +++ b/x_track/src/App/Utils/StorageService/StorageService.cpp @@ -0,0 +1,506 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "StorageService.h" +#include "lvgl/lvgl.h" +#include <algorithm> +#include <cJSON.h> +#include <cstring> +#include <stack> + +#define JSON_GET_ITEM(DEST, JSON_TYPE) \ + do { \ + cJSON* it = cJSON_GetObjectItem(curObj, iter.key); \ + if (!it) { \ + LV_LOG_WARN("Can't get " #JSON_TYPE " item: %s", iter.key); \ + retval = false; \ + } \ + DEST = it->value##JSON_TYPE; \ + } while (0) + +#define JSON_ADD_ITEM(TYPE, OBJ_TYPE) \ + do { \ + TYPE value = *(TYPE*)iter.value; \ + cJSON* it = cJSON_Add##OBJ_TYPE##ToObject(curObj, iter.key, value); \ + LV_ASSERT_MSG(it != nullptr, "Add" #OBJ_TYPE "failed"); \ + } while (0) + +#define JSON_GET_ARRAY(DEST_TYPE, JSON_TYPE) \ + do { \ + for (int i = 0; i < arrSize; i++) { \ + cJSON* it = cJSON_GetArrayItem(json, i); \ + if (!it) { \ + LV_LOG_WARN("Can't get array item: %d", i); \ + return false; \ + } \ + *(TYPE*)value = (TYPE)it->value##JSON_TYPE; \ + value = (TYPE*)value + 1; \ + } \ + } while (0) + +StorageService::StorageService(const char* path) +{ + LV_ASSERT_NULL(path); + _pathDefault = path; + + cJSON_Hooks hooks; + memset(&hooks, 0, sizeof(hooks)); + hooks.malloc_fn = lv_malloc, + hooks.free_fn = lv_free, + cJSON_InitHooks(&hooks); +} + +StorageService::~StorageService() +{ +} + +bool StorageService::add(const char* key, void* value, size_t size, TYPE type) +{ + LV_LOG_INFO("key: %s, value: %p, size: %zu, type: %d", + key, value, size, (int)type); + + switch (type) { + case TYPE::BOOL: + LV_ASSERT(size == sizeof(bool)); + break; + case TYPE::INT: + LV_ASSERT(size == sizeof(int)); + break; + case TYPE::FLOAT: + LV_ASSERT(size == sizeof(float)); + break; + case TYPE::DOUBLE: + LV_ASSERT(size == sizeof(double)); + break; + default: + break; + } + + Node_t node; + node.key = key; + node.value = value; + node.size = size; + node.type = type; + _nodePool.push_back(node); + + return true; +} + +bool StorageService::loadArray(struct cJSON* json, void* value, size_t size, int len, TYPE type) +{ + int arrSize = cJSON_GetArraySize(json); + + if (arrSize != len) { + LV_LOG_WARN("array size(%d) not match: %d", arrSize, len); + } + + len = std::min(arrSize, (int)len); + + if (len <= 0) { + return false; + } + + switch (type) { + case TYPE::BOOL: + JSON_GET_ARRAY(bool, int); + break; + + case TYPE::INT: + JSON_GET_ARRAY(int, int); + break; + + case TYPE::FLOAT: + JSON_GET_ARRAY(float, double); + break; + + case TYPE::DOUBLE: + JSON_GET_ARRAY(double, double); + break; + + case TYPE::STRING: { + for (int i = 0; i < arrSize; i++) { + cJSON* it = cJSON_GetArrayItem(json, i); + if (!it) { + LV_LOG_WARN("Can't get array item: %d", i); + return false; + } + lv_snprintf((char*)value, size, "%s", cJSON_GetStringValue(it)); + value = (char*)value + size; + } + } break; + + default: + LV_LOG_ERROR("Unknow type: %d", (int)type); + return false; + } + + return true; +} + +bool StorageService::saveArray(struct cJSON* json, const char* key, void* value, size_t size, int len, TYPE type) +{ + LV_ASSERT_NULL(json); + LV_ASSERT_NULL(key); + LV_ASSERT_NULL(value); + + bool retval = false; + cJSON* array = nullptr; + + switch (type) { + case TYPE::BOOL: + LV_LOG_WARN("bool array not support"); + break; + + case TYPE::INT: { + array = cJSON_CreateIntArray((const int*)value, len); + retval = cJSON_AddItemToObject(json, key, array); + } break; + + case TYPE::FLOAT: { + array = cJSON_CreateFloatArray((const float*)value, len); + retval = cJSON_AddItemToObject(json, key, array); + } break; + + case TYPE::DOUBLE: { + array = cJSON_CreateDoubleArray((const double*)value, len); + retval = cJSON_AddItemToObject(json, key, array); + } break; + + case TYPE::STRING: { + array = cJSON_CreateStringArray((const char* const*)value, len); + retval = cJSON_AddItemToObject(json, key, array); + } break; + + default: + LV_LOG_ERROR("Unknow type: %d", (int)type); + break; + } + + return retval && array != nullptr; +} + +bool StorageService::load(const char* path) +{ + bool retval = true; + char* buf = nullptr; + cJSON* cjson = nullptr; + cJSON* curObj = nullptr; + cJSON* arrayObj = nullptr; + int arrayLen = 0; + std::stack<cJSON*> objStack; + + path = path ? path : _pathDefault; + + buf = loadJson(path); + if (!buf) { + return false; + } + + cjson = cJSON_Parse(buf); + if (!cjson) { + LV_LOG_ERROR("cJSON_Parse failed"); + retval = false; + goto failed; + } + + curObj = cjson; + + for (auto& iter : _nodePool) { + /* print node info */ + LV_LOG_INFO("key: %s, value: %p, size: %zu, type: %d", + iter.key, iter.value, iter.size, (int)iter.type); + + if (arrayObj) { + retval = loadArray( + arrayObj, + iter.value, + iter.size, + arrayLen, + iter.type); + arrayObj = nullptr; + arrayLen = 0; + continue; + } + + cJSON* item = nullptr; + if (iter.key) { + item = cJSON_GetObjectItem(curObj, iter.key); + if (!item) { + LV_LOG_WARN("could NOT get key: %s", iter.key); + retval = false; + continue; + } + } + + /* skip empty data */ + if (!iter.key && iter.type != TYPE::STRUCT_END) { + continue; + } + + switch (iter.type) { + case TYPE::STRUCT_START: + LV_LOG_INFO("struct start: %s {", iter.key); + objStack.push(curObj); + curObj = cJSON_GetObjectItem(curObj, iter.key); + break; + + case TYPE::STRUCT_END: + if (objStack.empty()) { + LV_LOG_ERROR("struct end not match"); + retval = false; + continue; + } + curObj = objStack.top(); + objStack.pop(); + LV_LOG_INFO("} struct end"); + break; + + case TYPE::ARRAY: + arrayObj = item; + arrayLen = iter.size; + LV_LOG_INFO("array: %s[%d]", iter.key, arrayLen); + break; + + case TYPE::BOOL: + JSON_GET_ITEM(*(bool*)iter.value, int); + break; + + case TYPE::INT: + JSON_GET_ITEM(*(int*)iter.value, int); + break; + + case TYPE::FLOAT: + JSON_GET_ITEM(*(float*)iter.value, double); + break; + + case TYPE::DOUBLE: + JSON_GET_ITEM(*(double*)iter.value, double); + break; + + case TYPE::STRING: { + cJSON* it = cJSON_GetObjectItem(curObj, iter.key); + if (!it) { + LV_LOG_WARN("can't get string item: %s", iter.key); + retval = false; + } + lv_snprintf((char*)iter.value, iter.size, "%s", cJSON_GetStringValue(it)); + } break; + + default: + LV_LOG_ERROR("Unknow type: %d", (int)iter.type); + retval = false; + break; + } + } + +failed: + if (buf) { + lv_free(buf); + } + + if (cjson) { + cJSON_Delete(cjson); + } + + return retval; +} + +bool StorageService::save(const char* path) +{ + bool retval = false; + char* json_str = nullptr; + cJSON* cjson = nullptr; + cJSON* curObj = nullptr; + int arrayLen = 0; + const char* arrayKey = nullptr; + std::stack<cJSON*> objStack; + + cjson = cJSON_CreateObject(); + LV_ASSERT_MALLOC(cjson); + curObj = cjson; + + path = path ? path : _pathDefault; + + if (!cjson) { + LV_LOG_ERROR("can't create cjson object"); + return false; + } + + for (auto& iter : _nodePool) { + /* print node info */ + LV_LOG_INFO("key: %s, value: %p, size: %zu, type: %d", + iter.key, iter.value, iter.size, (int)iter.type); + + if (arrayLen > 0) { + LV_ASSERT(saveArray( + curObj, + arrayKey, + iter.value, + iter.size, + arrayLen, + iter.type)); + arrayLen = 0; + continue; + } + + switch (iter.type) { + case TYPE::STRUCT_START: + LV_LOG_INFO("struct start: %s {", iter.key); + objStack.push(curObj); + curObj = cJSON_AddObjectToObject(curObj, iter.key); + break; + + case TYPE::STRUCT_END: + curObj = objStack.top(); + objStack.pop(); + LV_LOG_INFO("} struct end"); + break; + + case TYPE::ARRAY: + arrayKey = iter.key; + arrayLen = iter.size; + LV_LOG_INFO("array: %s[%d]", iter.key, arrayLen); + break; + + case TYPE::BOOL: + JSON_ADD_ITEM(bool, Bool); + break; + + case TYPE::INT: + JSON_ADD_ITEM(int, Number); + break; + + case TYPE::FLOAT: + JSON_ADD_ITEM(float, Number); + break; + + case TYPE::DOUBLE: + JSON_ADD_ITEM(double, Number); + break; + + case TYPE::STRING: { + cJSON* it = cJSON_AddStringToObject(curObj, iter.key, (const char*)iter.value); + LV_ASSERT_MSG(it != nullptr, "add String failed"); + } break; + + default: + LV_ASSERT_MSG(false, "Unknow type"); + break; + } + } + + json_str = cJSON_Print(cjson); + if (!json_str) { + LV_LOG_ERROR("json_str is NULL"); + goto failed; + } + + retval = saveJson(json_str, path); + +failed: + if (cjson) { + cJSON_Delete(cjson); + } + + if (json_str) { + cJSON_free(json_str); + } + + return retval; +} + +char* StorageService::loadJson(const char* path) +{ + lv_fs_file_t file; + char* buf = NULL; + + /* open json file */ + lv_fs_res_t res = lv_fs_open(&file, path, LV_FS_MODE_RD); + if (res != LV_FS_RES_OK) { + LV_LOG_ERROR("open file: %s faild: %d", path, res); + return NULL; + } + + /* get file size */ + lv_fs_seek(&file, 0, LV_FS_SEEK_END); + uint32_t size; + res = lv_fs_tell(&file, &size); + if (res != LV_FS_RES_OK) { + LV_LOG_ERROR("can't get file size"); + goto failed; + } + lv_fs_seek(&file, 0, LV_FS_SEEK_SET); + + /* alloc string buffer */ + buf = (char*)lv_malloc(size + 1); + LV_ASSERT_MALLOC(buf); + if (!buf) { + LV_LOG_ERROR("malloc failed for json buf"); + goto failed; + } + + /* read json sting */ + uint32_t br; + res = lv_fs_read(&file, buf, size, &br); + lv_fs_close(&file); + if (res != LV_FS_RES_OK || br != size) { + LV_LOG_ERROR("read file failed"); + goto failed; + } + buf[size] = '\0'; + + return buf; + +failed: + lv_fs_close(&file); + + if (buf) { + lv_free(buf); + } + + return NULL; +} + +bool StorageService::saveJson(const char* str, const char* path) +{ + LV_ASSERT_NULL(str); + + uint32_t len = strlen(str); + + lv_fs_file_t file; + lv_fs_res_t res = lv_fs_open(&file, path, LV_FS_MODE_WR); + if (res != LV_FS_RES_OK) { + LV_LOG_ERROR("open file: %s faild: %d", path, res); + return false; + } + + uint32_t bw; + res = lv_fs_write(&file, str, len, &bw); + lv_fs_close(&file); + + if (!(res == LV_FS_RES_OK && bw == len)) { + LV_LOG_ERROR("write file failed: %d", res); + return false; + } + + return true; +} diff --git a/x_track/src/App/Utils/StorageService/StorageService.h b/x_track/src/App/Utils/StorageService/StorageService.h new file mode 100644 index 0000000000000000000000000000000000000000..b0d7d832d5e8925a8780cc91ce0651ac361d3294 --- /dev/null +++ b/x_track/src/App/Utils/StorageService/StorageService.h @@ -0,0 +1,81 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __STORAGE_SERVICE_H +#define __STORAGE_SERVICE_H + +#include <cstddef> +#include <cstdint> +#include <vector> + +struct cJSON; + +class StorageService { +public: + enum class TYPE { + UNKNOW, + BOOL, + INT, + FLOAT, + DOUBLE, + STRING, + ARRAY, + STRUCT_START, + STRUCT_END, + }; + +public: + StorageService(const char* path); + ~StorageService(); + + bool add(const char* key, void* value, size_t size, TYPE type); + bool save(const char* path = nullptr); + bool load(const char* path = nullptr); + +private: + typedef struct Node + { + Node() + : key(nullptr) + , value(nullptr) + , size(0) + , type(TYPE::UNKNOW) + { + } + const char* key; + void* value; + size_t size; + TYPE type; + } Node_t; + +private: + const char* _pathDefault; + std::vector<Node_t> _nodePool; + +private: + char* loadJson(const char* path); + bool saveJson(const char* str, const char* path); + bool loadArray(struct cJSON* json, void* value, size_t size, int len, TYPE type); + bool saveArray(struct cJSON* json, const char* key, void* value, size_t size, int len, TYPE type); +}; + +#endif diff --git a/x_track/src/App/Utils/Stream/Print.cpp b/x_track/src/App/Utils/Stream/Print.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd0ef02dec07bfe587fb88405e157c117fdcb680 --- /dev/null +++ b/x_track/src/App/Utils/Stream/Print.cpp @@ -0,0 +1,376 @@ +/* + * Print.cpp - Base class that provides print() and println() + * Copyright (c) 2008 David A. Mellis. All right reserved. + * Copyright (c) 2011 LeafLabs, LLC. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Modified 23 November 2006 by David A. Mellis + * Modified 12 April 2011 by Marti Bolivar <mbolivar@leaflabs.com> + */ + +#include "Print.h" +//#include "wirish_math.h" +#include "limits.h" + +#define ABS(x) (((x)>0)?(x):-(x)) + +#ifndef LLONG_MAX +/* + * Note: + * + * At time of writing (12 April 2011), the limits.h that came with the + * newlib we distributed didn't include LLONG_MAX. Because we're + * staying away from using templates (see /notes/coding_standard.rst, + * "Language Features and Compiler Extensions"), this value was + * copy-pasted from a println() of the value + * + * std::numeric_limits<long long>::max(). + */ +#define LLONG_MAX 9223372036854775807LL +#endif + +/* + * Public methods + */ + +size_t Print::write(const char *str) +{ + size_t n = 0; + while (*str) + { + write(*str++); + n++; + } + return n; +} + +size_t Print::write(const void *buffer, uint32_t size) +{ + size_t n = 0; + uint8_t *ch = (uint8_t*)buffer; + while (size--) + { + write(*ch++); + n++; + } + return n; +} + +size_t Print::print(uint8_t b, int base) +{ + return print((uint64_t)b, base); +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(int n, int base) +{ + return print((long long)n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long long)n, base); +} + +size_t Print::print(long n, int base) +{ + return print((long long)n, base); +} + +size_t Print::print(unsigned long n, int base) +{ + return print((unsigned long long)n, base); +} + +size_t Print::print(long long n, int base) +{ + if (base == BYTE) + { + return write((uint8_t)n); + } + if (n < 0) + { + print('-'); + n = -n; + } + return printNumber(n, base); +} + +size_t Print::print(unsigned long long n, int base) +{ + size_t c = 0; + if (base == BYTE) + { + c = write((uint8_t)n); + } + else + { + c = printNumber(n, base); + } + return c; +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + return print(reinterpret_cast<const char *>(ifsh)); +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(uint8_t b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int n, int base) +{ + size_t s = print(n, base); + s += println(); + return s; +} + +size_t Print::println(unsigned int n, int base) +{ + size_t s = print(n, base); + s += println(); + return s; +} + +size_t Print::println(long n, int base) +{ + size_t s = print((long long)n, base); + s += println(); + return s; +} + +size_t Print::println(unsigned long n, int base) +{ + size_t s = print((unsigned long long)n, base); + s += println(); + return s; +} + +size_t Print::println(long long n, int base) +{ + size_t s = print(n, base); + s += println(); + return s; +} + +size_t Print::println(unsigned long long n, int base) +{ + size_t s = print(n, base); + s += println(); + return s; +} + +size_t Print::println(double n, int digits) +{ + size_t s = print(n, digits); + s += println(); + return s; +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +#ifdef SUPPORTS_PRINTF + +extern "C" { +#include <stdio.h> +#include <stdarg.h> +} + +// Work in progress to support printf. +// Need to implement stream FILE to write individual chars to chosen serial port +int Print::printf (const char *__restrict __format, ...) +{ + char printf_buff[PRINTF_BUFFER_LENGTH]; + + va_list args; + va_start(args, __format); + int ret_status = vsnprintf(printf_buff, sizeof(printf_buff), __format, args); + //int ret_status = vsprintf(printf_buff,__format, args); + va_end(args); + print(printf_buff); + + return ret_status; +} +#endif + +/* + * Private methods + */ + +size_t Print::printNumber(unsigned long long n, uint8_t base) +{ + unsigned char buf[CHAR_BIT * sizeof(long long)]; + unsigned long i = 0; + size_t s = 0; + if (n == 0) + { + print('0'); + return 1; + } + + while (n > 0) + { + buf[i++] = n % base; + n /= base; + } + + for (; i > 0; i--) + { + s += print((char)(buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10)); + } + return s; +} + + +/* According to snprintf(), + * + * nextafter((double)numeric_limits<long long>::max(), 0.0) ~= 9.22337e+18 + * + * This slightly smaller value was picked semi-arbitrarily. */ +#define LARGE_DOUBLE_TRESHOLD (9.1e18) + +/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS. + * + * This implementation is meant to be simple and not occupy too much + * code size. However, printing floating point values accurately is a + * subtle task, best left to a well-tested library function. + * + * See Steele and White 2003 for more details: + * + * http://kurtstephens.com/files/p372-steele.pdf + */ +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t s = 0; + // Hackish fail-fast behavior for large-magnitude doubles + if (ABS(number) >= LARGE_DOUBLE_TRESHOLD) + { + if (number < 0.0) + { + s = print('-'); + } + s += print("<large double>"); + return s; + } + + // Handle negative numbers + if (number < 0.0) + { + s += print('-'); + number = -number; + } + + // Simplistic rounding strategy so that e.g. print(1.999, 2) + // prints as "2.00" + double rounding = 0.5; + for (uint8_t i = 0; i < digits; i++) + { + rounding /= 10.0; + } + number += rounding; + + // Extract the integer part of the number and print it + long long int_part = (long long)number; + double remainder = number - int_part; + s += print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) + { + s += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int to_print = (int)remainder; + s += print(to_print); + remainder -= to_print; + } + return s; +} diff --git a/x_track/src/App/Utils/Stream/Print.h b/x_track/src/App/Utils/Stream/Print.h new file mode 100644 index 0000000000000000000000000000000000000000..9f876f32c804deebdbac7f3ced43dad06af3c29e --- /dev/null +++ b/x_track/src/App/Utils/Stream/Print.h @@ -0,0 +1,109 @@ +/* + * Print.h - Base class that provides print() and println() + * Copyright (c) 2008 David A. Mellis. All right reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA. + * + * Modified 12 April 2011 by Marti Bolivar <mbolivar@leaflabs.com> + */ + +#ifndef _PRINT_H_ +#define _PRINT_H_ + +#include <stdint.h> +#include "../WString/WString.h" +#include "Printable.h" + +#define SUPPORTS_PRINTF 1 +#define PRINTF_BUFFER_LENGTH 128 + +enum +{ + BYTE = 0, + BIN = 2, + OCT = 8, + DEC = 10, + HEX = 16 +}; + +class Print +{ +public: + virtual size_t write(uint8_t ch) = 0; + virtual size_t write(const char *str); + virtual size_t write(const void *buf, uint32_t len); + + size_t print(const String &); + size_t print(char); + size_t print(const char[]); + size_t print(uint8_t, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(long long, int = DEC); + size_t print(unsigned long long, int = DEC); + size_t print(double, int = 2); + size_t print(const __FlashStringHelper *); + size_t print(const Printable&); + size_t println(void); + size_t println(const String &s); + size_t println(char); + size_t println(const char[]); + size_t println(uint8_t, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(long long, int = DEC); + size_t println(unsigned long long, int = DEC); + size_t println(double, int = 2); + size_t println(const __FlashStringHelper *); + size_t println(const Printable&); +#ifdef SUPPORTS_PRINTF +// Roger Clark. Work in progress to add printf support + int printf(const char * format, ...); +#endif + Print() : write_error(0) {} + + int getWriteError() + { + return write_error; + } + void clearWriteError() + { + setWriteError(0); + } + +protected: + void setWriteError(int err = 1) + { + write_error = err; + } + +private: + int write_error; + size_t printNumber(unsigned long long, uint8_t); + size_t printFloat(double, uint8_t); +}; + +template<class T> inline Print &operator << (Print &obj, T arg) +{ + obj.print(arg); + return obj; +} + +#endif diff --git a/x_track/src/App/Utils/Stream/Printable.h b/x_track/src/App/Utils/Stream/Printable.h new file mode 100644 index 0000000000000000000000000000000000000000..3a33e9ac21940876b5509bac4bbd5c16592ef7c7 --- /dev/null +++ b/x_track/src/App/Utils/Stream/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include <stdlib.h> + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ +public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/x_track/src/App/Utils/Stream/Stream.cpp b/x_track/src/App/Utils/Stream/Stream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d7d004f59792a0a6074014cf02eef3d1e39b29f0 --- /dev/null +++ b/x_track/src/App/Utils/Stream/Stream.cpp @@ -0,0 +1,362 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + */ + +#include "Stream.h" +#include "lvgl/lvgl.h" + +#define millis() lv_tick_get() + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait +#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do + { + c = read(); + if (c >= 0) return c; + } + while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do + { + c = peek(); + if (c >= 0) return c; + } + while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) + { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + +// find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, (char*)""); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + size_t index = 0; // maximum target string length is 64k bytes! + size_t termIndex = 0; + int c; + + if( *target == 0) + return true; // return true if target is a null string + while( (c = timedRead()) > 0) + { + + if(c != target[index]) + index = 0; // reset index if any char does not match + + if( c == target[index]) + { + //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); + if(++index >= targetLen) // return true if all chars in the target match + { + return true; + } + } + + if(termLen > 0 && c == terminator[termIndex]) + { + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string + } + else + termIndex = 0; + } + return false; +} + + +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long Stream::parseInt() +{ + return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long Stream::parseInt(char skipChar) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do + { + if(c == skipChar) + ; // ignore this charactor + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + return parseFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float Stream::parseFloat(char skipChar) +{ + bool isNegative = false; + bool isFraction = false; + long value = 0; + int c; + float fraction = 1.0f; + + c = peekNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do + { + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') // is c a digit? + { + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1f; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return (float)value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) + { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) + { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) +{ + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets + tCount; ++t) + { + if (t->len <= 0) + return t - targets; + } + + while (1) + { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets + tCount; ++t) + { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) + { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do + { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) + { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) + { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) + { + t->index++; + break; + } + + // otherwise we just try the next index + } + while (t->index); + } + } + // unreachable +// return -1; +} diff --git a/x_track/src/App/Utils/Stream/Stream.h b/x_track/src/App/Utils/Stream/Stream.h new file mode 100644 index 0000000000000000000000000000000000000000..5d93255aa0f810851cd31b0ce8d8a1c581402e3f --- /dev/null +++ b/x_track/src/App/Utils/Stream/Stream.h @@ -0,0 +1,134 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include <inttypes.h> +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(skipChar) parseInt(skipchar) +#define getFloat() parseFloat() +#define getFloat(skipChar) parseFloat(skipChar) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +class Stream : public Print +{ +protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + +public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual void flush() = 0; + + Stream() { + _timeout = 1000; + _startMillis = 0; + } + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + unsigned long getTimeout(void) { + return _timeout; + } + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { + return find ((char *)target); + } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { + return find ((char *)target, length); + } + // returns true if target string is found, false if timed out + + bool find(char target) { + return find (&target, 1); + } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { + return findUntil((char *)target, terminator); + } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) { + return findUntil((char *)target, targetLen, terminate, termLen); + } + + + long parseInt(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + float parseFloat(); // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { + return readBytes((char *)buffer, length); + } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { + return readBytesUntil(terminator, (char *)buffer, length); + } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + +protected: + long parseInt(char skipChar); // as above but the given skipChar is ignored + // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float parseFloat(char skipChar); // as above but the given skipChar is ignored + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#endif diff --git a/x_track/src/App/Utils/SunRiseCalc/SunRiseCalc.c b/x_track/src/App/Utils/SunRiseCalc/SunRiseCalc.c new file mode 100644 index 0000000000000000000000000000000000000000..958bd08f8065af83ea5d4138b040069d31848015 --- /dev/null +++ b/x_track/src/App/Utils/SunRiseCalc/SunRiseCalc.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 HanfG + */ +#include "SunRiseCalc.h" +#include <math.h> +#include <stdbool.h> + +#define PI 3.1415926f +#define ACOS acosf +#define COS cosf +#define TAN tanf + +static bool isLeapYear(uint16_t year) +{ + if (year % 4 != 0) + return false; + if (year % 100 != 0) + return true; + if (year % 400 == 0) + return true; + return false; +} + +static uint16_t dayOfYear(uint16_t year, uint8_t month, uint8_t day) +{ + uint16_t days = 0; + if (month > 2 && isLeapYear(year)) { + days += 1; + } + for (uint8_t i = 0; i < month; i++) { + static const uint8_t daysOfMonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 }; + days += daysOfMonth[i]; + } + return days; +} + +void SunRiseSunSetCalculator( + int8_t timeZone, + uint16_t year, + uint8_t month, + uint8_t day, + float longitude, + float latitude, + uint8_t* sunriseHour, + uint8_t* sunriseMinute, + uint8_t* sunsetHour, + uint8_t* sunsetMinute) +{ + float sunriseFloat = 24 * (180 + timeZone * 15 - longitude - ACOS(-TAN(-23.4f * COS(2 * PI * (dayOfYear(year, month, day) + 9) / 365) * PI / 180) * TAN(latitude * PI / 180)) * 180 / PI) / 360; + float sunsetFloat = 24 * (1 + (timeZone * 15 - longitude) / 180) - sunriseFloat; + + *sunriseHour = (uint8_t)sunriseFloat; + *sunriseMinute = (uint8_t)((sunriseFloat - *sunriseHour) * 60); + *sunsetHour = (uint8_t)sunsetFloat; + *sunsetMinute = (uint8_t)((sunsetFloat - *sunsetHour) * 60); +} diff --git a/x_track/src/App/Utils/SunRiseCalc/SunRiseCalc.h b/x_track/src/App/Utils/SunRiseCalc/SunRiseCalc.h new file mode 100644 index 0000000000000000000000000000000000000000..5725fb174cb336f033871ba60a52f1ff4e1db8be --- /dev/null +++ b/x_track/src/App/Utils/SunRiseCalc/SunRiseCalc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 HanfG + */ +#ifndef __SUN_RISE_CALC_H__ +#define __SUN_RISE_CALC_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Calculate the sunrise and sunset time + * @param timeZone Time zone + * @param year Year + * @param month Month + * @param day Day + * @param longitude Longitude + * @param latitude Latitude + * @param sunriseHour Sunrise hour + * @param sunriseMinute Sunrise minute + * @param sunsetHour Sunset hour + * @param sunsetMinute Sunset minute + */ +void SunRiseSunSetCalculator( + int8_t timeZone, + uint16_t year, + uint8_t month, + uint8_t day, + float longitude, + float latitude, + uint8_t* sunriseHour, + uint8_t* sunriseMinute, + uint8_t* sunsetHour, + uint8_t* sunsetMinute); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SUN_RISE_CALC_H__ */ diff --git a/x_track/src/App/Utils/TileView/TileView.cpp b/x_track/src/App/Utils/TileView/TileView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..493ff5331ad26b7f3686737c2ac1e875aaf952a5 --- /dev/null +++ b/x_track/src/App/Utils/TileView/TileView.cpp @@ -0,0 +1,144 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "TileView.h" +#include <string.h> + +TileView::TileView(uint32_t viewWidth, uint32_t viewHeight, uint32_t tileSize) + : _viewWidth(viewWidth) + , _viewHeight(viewHeight) + , _tileSize(tileSize) +{ +} + +void TileView::setViewSize(uint32_t width, uint32_t height) +{ + _viewWidth = width; + _viewHeight = height; +} + +void TileView::setFocusPos(int32_t x, int32_t y) +{ + _pointFocus.x = x; + _pointFocus.y = y; + + const int32_t viewHalfWidth = _viewWidth / 2; + const int32_t viewHalfHeight = _viewHeight / 2; + const uint32_t tileSize = _tileSize; + + _pointView[0].x = x - viewHalfWidth; + _pointView[0].y = y - viewHalfHeight; + _pointView[1].x = x + viewHalfWidth; + _pointView[1].y = y - viewHalfHeight; + _pointView[2].x = x - viewHalfWidth; + _pointView[2].y = y + viewHalfHeight; + _pointView[3].x = x + viewHalfWidth; + _pointView[3].y = y + viewHalfHeight; + + const int32_t tileContWidth = (_viewWidth / tileSize + 2) * tileSize; + const int32_t tileContHeight = (_viewHeight / tileSize + 2) * tileSize; + + _pointTileCont[0].x = roundTile(_pointView[0].x, false); + _pointTileCont[0].y = roundTile(_pointView[0].y, false); + _pointTileCont[1].x = _pointTileCont[0].x + tileContWidth; + _pointTileCont[1].y = _pointTileCont[0].y; + _pointTileCont[2].x = _pointTileCont[0].x; + _pointTileCont[2].y = _pointTileCont[0].y + tileContHeight; + _pointTileCont[3].x = _pointTileCont[0].x + tileContWidth; + _pointTileCont[3].y = _pointTileCont[0].y + tileContHeight; +} + +TileView::Point_t TileView::getFocusPos() +{ + return _pointFocus; +} + +TileView::Point_t TileView::getFocusOffset() +{ + return getOffset(&_pointFocus); +} + +void TileView::setTileSize(uint32_t size) +{ + _tileSize = size; +} + +uint32_t TileView::getTileSize() +{ + return _tileSize; +} + +TileView::Rect_t TileView::getTileRect() +{ + Rect_t rect; + rect.x = _pointTileCont[0].x; + rect.y = _pointTileCont[0].y; + rect.width = _pointTileCont[1].x - _pointTileCont[0].x; + rect.height = _pointTileCont[2].y - _pointTileCont[0].y; + return rect; +} + +TileView::Point_t TileView::getTileRectOffset() +{ + return getOffset(&_pointView[0]); +} + +TileView::Point_t TileView::getTilePos(uint32_t index) +{ + Point_t pos; + int32_t width = _pointTileCont[1].x - _pointTileCont[0].x; + int32_t widthIndexMax = width / _tileSize; + pos.x = _pointTileCont[0].x + _tileSize * (index % widthIndexMax); + pos.y = _pointTileCont[0].y + _tileSize * (index / widthIndexMax); + return pos; +} + +uint32_t TileView::getTileNum() +{ + Rect_t rect = getTileRect(); + return (rect.width / _tileSize) * (rect.height / _tileSize); +} + +int32_t TileView::roundTile(int32_t x, bool up) +{ + int32_t r = x % _tileSize; + + if (r == 0) { + return x; + } + + int32_t ret = x - r; + + if (up) { + ret += _tileSize; + } + + return ret; +} + +TileView::Point_t TileView::getOffset(const Point_t* point) +{ + Point_t offset; + offset.x = point->x - _pointTileCont[0].x; + offset.y = point->y - _pointTileCont[0].y; + return offset; +} diff --git a/x_track/src/App/Utils/TileView/TileView.h b/x_track/src/App/Utils/TileView/TileView.h new file mode 100644 index 0000000000000000000000000000000000000000..fb93bd6d3b309280f674b8450757272da7bb3c47 --- /dev/null +++ b/x_track/src/App/Utils/TileView/TileView.h @@ -0,0 +1,92 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TILE_VIEW_H +#define __TILE_VIEW_H + +#include <stdint.h> + +class TileView { +public: + typedef struct Point { + Point(int32_t _x = 0, int32_t _y = 0) + : x(_x) + , y(_y) + { + } + int32_t x; + int32_t y; + } Point_t; + + typedef struct Rect { + Rect(int32_t _x = 0, int32_t _y = 0, int32_t _width = 0, int32_t _height = 0) + : x(_x) + , y(_y) + , width(_width) + , height(_height) + { + } + int32_t x; + int32_t y; + int32_t width; + int32_t height; + } Rect_t; + +public: + TileView(uint32_t viewWidth = 240, uint32_t viewHeight = 240, uint32_t tileSize = 256); + ~TileView() { } + + void setViewSize(uint32_t width, uint32_t height); + int32_t getViewWidth() + { + return _viewWidth; + } + int32_t getViewHeight() + { + return _viewHeight; + } + + void setFocusPos(int32_t x, int32_t y); + Point_t getFocusPos(); + Point_t getFocusOffset(); + + void setTileSize(uint32_t size); + uint32_t getTileSize(); + Rect_t getTileRect(); + Point_t getTileRectOffset(); + Point_t getTilePos(uint32_t index); + uint32_t getTileNum(); + + int32_t roundTile(int32_t x, bool up); + Point_t getOffset(const Point_t* point); + +private: + uint32_t _viewWidth; + uint32_t _viewHeight; + uint32_t _tileSize; + + Point_t _pointFocus; + Point_t _pointView[4]; + Point_t _pointTileCont[4]; +}; + +#endif /* __TILE_VIEW_H */ diff --git a/x_track/src/App/Utils/Time/DateStrings.cpp b/x_track/src/App/Utils/Time/DateStrings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..489bb150c12d8cda16d47f0788f83620fb9d7c2a --- /dev/null +++ b/x_track/src/App/Utils/Time/DateStrings.cpp @@ -0,0 +1,97 @@ +/* DateStrings.cpp + * Definitions for date strings for use with the Time library + * + * Updated for Arduino 1.5.7 18 July 2014 + * + * No memory is consumed in the sketch if your code does not call any of the string methods + * You can change the text of the strings, make sure the short strings are each exactly 3 characters + * the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in Time.h + * + */ + +#if defined(__AVR__) +#include <avr/pgmspace.h> +#else +// for compatiblity with Arduino Due and Teensy 3.0 and maybe others? +#define PROGMEM +#define PGM_P const char * +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned char **)(addr)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#endif +#include <string.h> // for strcpy_P or strcpy +#include "Time.h" + +// the short strings for each day or month must be exactly dt_SHORT_STR_LEN +#define dt_SHORT_STR_LEN 3 // the length of short strings + +static char buffer[dt_MAX_STRING_LEN+1]; // must be big enough for longest string and the terminating null + +const char monthStr0[] PROGMEM = ""; +const char monthStr1[] PROGMEM = "January"; +const char monthStr2[] PROGMEM = "February"; +const char monthStr3[] PROGMEM = "March"; +const char monthStr4[] PROGMEM = "April"; +const char monthStr5[] PROGMEM = "May"; +const char monthStr6[] PROGMEM = "June"; +const char monthStr7[] PROGMEM = "July"; +const char monthStr8[] PROGMEM = "August"; +const char monthStr9[] PROGMEM = "September"; +const char monthStr10[] PROGMEM = "October"; +const char monthStr11[] PROGMEM = "November"; +const char monthStr12[] PROGMEM = "December"; + +const PROGMEM char * const PROGMEM monthNames_P[] = +{ + monthStr0,monthStr1,monthStr2,monthStr3,monthStr4,monthStr5,monthStr6, + monthStr7,monthStr8,monthStr9,monthStr10,monthStr11,monthStr12 +}; + +const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec"; + +const char dayStr0[] PROGMEM = "Err"; +const char dayStr1[] PROGMEM = "Sunday"; +const char dayStr2[] PROGMEM = "Monday"; +const char dayStr3[] PROGMEM = "Tuesday"; +const char dayStr4[] PROGMEM = "Wednesday"; +const char dayStr5[] PROGMEM = "Thursday"; +const char dayStr6[] PROGMEM = "Friday"; +const char dayStr7[] PROGMEM = "Saturday"; + +const PROGMEM char * const PROGMEM dayNames_P[] = +{ + dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7 +}; + +const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThuFriSat"; + +/* functions to return date strings */ + +char* monthStr(uint8_t month) +{ + strcpy_P(buffer, (PGM_P)pgm_read_word(&(monthNames_P[month]))); + return buffer; +} + +char* monthShortStr(uint8_t month) +{ + for (int i=0; i < dt_SHORT_STR_LEN; i++) + buffer[i] = pgm_read_byte(&(monthShortNames_P[i+ (month*dt_SHORT_STR_LEN)])); + buffer[dt_SHORT_STR_LEN] = 0; + return buffer; +} + +char* dayStr(uint8_t day) +{ + strcpy_P(buffer, (PGM_P)pgm_read_word(&(dayNames_P[day]))); + return buffer; +} + +char* dayShortStr(uint8_t day) +{ + uint8_t index = day*dt_SHORT_STR_LEN; + for (int i=0; i < dt_SHORT_STR_LEN; i++) + buffer[i] = pgm_read_byte(&(dayShortNames_P[index + i])); + buffer[dt_SHORT_STR_LEN] = 0; + return buffer; +} diff --git a/x_track/src/App/Utils/Time/Readme.txt b/x_track/src/App/Utils/Time/Readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..67b148ecd07e1b8d3bb5306df46786d449e959ab --- /dev/null +++ b/x_track/src/App/Utils/Time/Readme.txt @@ -0,0 +1,131 @@ +Readme file for Arduino Time Library + +Time is a library that provides timekeeping functionality for Arduino. + +The code is derived from the Playground DateTime library but is updated +to provide an API that is more flexable and easier to use. + +A primary goal was to enable date and time functionality that can be used with +a variety of external time sources with minimum differences required in sketch logic. + +Example sketches illustrate how similar sketch code can be used with: a Real Time Clock, +internet NTP time service, GPS time data, and Serial time messages from a computer +for time synchronization. + +The functions available in the library include: + +hour(); // the hour now (0-23) +minute(); // the minute now (0-59) +second(); // the second now (0-59) +day(); // the day now (1-31) +weekday(); // day of the week, Sunday is day 0 +month(); // the month now (1-12) +year(); // the full four digit year: (2009, 2010 etc) + +there are also functions to return the hour in 12 hour format +hourFormat12(); // the hour now in 12 hour format +isAM(); // returns true if time now is AM +isPM(); // returns true if time now is PM + +now(); // returns the current time as seconds since Jan 1 1970 + +The time and date functions can take an optional parameter for the time. This prevents +errors if the time rolls over between elements. For example, if a new minute begins +between getting the minute and second, the values will be inconsistent. Using the +following functions eliminates this probglem + time_t t = now(); // store the current time in time variable t + hour(t); // returns the hour for the given time t + minute(t); // returns the minute for the given time t + second(t); // returns the second for the given time t + day(t); // the day for the given time t + weekday(t); // day of the week for the given time t + month(t); // the month for the given time t + year(t); // the year for the given time t + + +Functions for managing the timer services are: +setTime(t); // set the system time to the give time t +setTime(hr,min,sec,day,mnth,yr); // alternative to above, yr is 2 or 4 digit yr (2010 or 10 sets year to 2010) +adjustTime(adjustment); // adjust system time by adding the adjustment value + +timeStatus(); // indicates if time has been set and recently synchronized + // returns one of the following enumerations: + timeNotSet // the time has never been set, the clock started at Jan 1 1970 + timeNeedsSync // the time had been set but a sync attempt did not succeed + timeSet // the time is set and is synced +Time and Date values are not valid if the status is timeNotSet. Otherwise values can be used but +the returned time may have drifted if the status is timeNeedsSync. + +setSyncProvider(getTimeFunction); // set the external time provider +setSyncInterval(interval); // set the number of seconds between re-sync + + +There are many convenience macros in the time.h file for time constants and conversion of time units. + +To use the library, copy the download to the Library directory. + +The Time directory contains the Time library and some example sketches +illustrating how the library can be used with various time sources: + +- TimeSerial.pde shows Arduino as a clock without external hardware. + It is synchronized by time messages sent over the serial port. + A companion Processing sketch will automatically provide these messages + if it is running and connected to the Arduino serial port. + +- TimeSerialDateStrings.pde adds day and month name strings to the sketch above + Short (3 character) and long strings are available to print the days of + the week and names of the months. + +- TimeRTC uses a DS1307 real time clock to provide time synchronization. + A basic RTC library named DS1307RTC is included in the download. + To run this sketch the DS1307RTC library must be installed. + +- TimeRTCSet is similar to the above and adds the ability to set the Real Time Clock + +- TimeRTCLog demonstrates how to calculate the difference between times. + It is a vary simple logger application that monitors events on digtial pins + and prints (to the serial port) the time of an event and the time period since the previous event. + +- TimeNTP uses the Arduino Ethernet shield to access time using the internet NTP time service. + The NTP protocol uses UDP and the UdpBytewise library is required, see: + http://bitbucket.org/bjoern/arduino_osc/src/14667490521f/libraries/Ethernet/ + +- TimeGPS gets time from a GPS + This requires the TinyGPS library from Mikal Hart: + http://arduiniana.org/libraries/TinyGPS + +Differences between this code and the playground DateTime library +although the Time library is based on the DateTime codebase, the API has changed. +Changes in the Time library API: +- time elements are functions returning int (they are variables in DateTime) +- Years start from 1970 +- days of the week and months start from 1 (they start from 0 in DateTime) +- DateStrings do not require a seperate library +- time elements can be accessed non-atomically (in DateTime they are always atomic) +- function added to automatically sync time with extrnal source +- localTime and maketime parameters changed, localTime renamed to breakTime + +Technical notes: + +Internal system time is based on the standard Unix time_t. +The value is the number of seconds since Jan 1 1970. +System time begins at zero when the sketch starts. + +The internal time can be automatically synchronized at regular intervals to an external time source. +This is enabled by calling the setSyncProvider(provider) function - the provider argument is +the address of a function that returns the current time as a time_t. +See the sketches in the examples directory for usage. + +The default interval for re-syncing the time is 5 minutes but can be changed by calling the +setSyncInterval( interval) method to set the number of seconds between re-sync attempts. + +The Time library defines a structure for holding time elements that is a compact version of the C tm structure. +All the members of the Arduino tm structure are bytes and the year is offset from 1970. +Convenience macros provide conversion to and from the Arduino format. + +Low level functions to convert between system time and individual time elements are provided: + breakTime( time, &tm); // break time_t into elements stored in tm struct + makeTime( &tm); // return time_t from elements stored in tm struct + +The DS1307RTC library included in the download provides an example of how a time provider +can use the low level functions to interface with the Time library. diff --git a/x_track/src/App/Utils/Time/Time.cpp b/x_track/src/App/Utils/Time/Time.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74db7bb5abb18b4a8999656406c78ecd3149e0f4 --- /dev/null +++ b/x_track/src/App/Utils/Time/Time.cpp @@ -0,0 +1,326 @@ +/* + time.c - low level time and date functions + Copyright (c) Michael Margolis 2009-2014 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + 1.0 6 Jan 2010 - initial release + 1.1 12 Feb 2010 - fixed leap year calculation error + 1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this) + 1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update + status, updated examples for Arduino 1.0, fixed ARM + compatibility issues, added TimeArduinoDue and TimeTeensy3 + examples, add error checking and messages to RTC examples, + add examples to DS1307RTC library. + 1.4 5 Sep 2014 - compatibility with Arduino 1.5.7 +*/ + +#ifdef ARDUINO +# if ARDUINO >= 100 +# include <Arduino.h> +# else +# include <WProgram.h> +# endif +#else +# include "lvgl/lvgl.h" +# define millis() lv_tick_get() +#endif + +#include "Time.h" + +static tmElements_t g_tm; // a cache of time elements +static time_t g_cacheTime; // the time the cache was updated +static uint32_t g_syncInterval = 300; // time sync will be attempted after this many seconds + +void refreshCache(time_t t) { + if (t != g_cacheTime) { + breakTime(t, g_tm); + g_cacheTime = t; + } +} + +int hour() { // the hour now + return hour(now()); +} + +int hour(time_t t) { // the hour for the given time + refreshCache(t); + return g_tm.Hour; +} + +int hourFormat12() { // the hour now in 12 hour format + return hourFormat12(now()); +} + +int hourFormat12(time_t t) { // the hour for the given time in 12 hour format + refreshCache(t); + if( g_tm.Hour == 0 ) + return 12; // 12 midnight + else if( g_tm.Hour > 12) + return g_tm.Hour - 12 ; + else + return g_tm.Hour ; +} + +uint8_t isAM() { // returns true if time now is AM + return !isPM(now()); +} + +uint8_t isAM(time_t t) { // returns true if given time is AM + return !isPM(t); +} + +uint8_t isPM() { // returns true if PM + return isPM(now()); +} + +uint8_t isPM(time_t t) { // returns true if PM + return (hour(t) >= 12); +} + +int minute() { + return minute(now()); +} + +int minute(time_t t) { // the minute for the given time + refreshCache(t); + return g_tm.Minute; +} + +int second() { + return second(now()); +} + +int second(time_t t) { // the second for the given time + refreshCache(t); + return g_tm.Second; +} + +int day(){ + return(day(now())); +} + +int day(time_t t) { // the day for the given time (0-6) + refreshCache(t); + return g_tm.Day; +} + +int weekday() { // Sunday is day 1 + return weekday(now()); +} + +int weekday(time_t t) { + refreshCache(t); + return g_tm.Wday; +} + +int month(){ + return month(now()); +} + +int month(time_t t) { // the month for the given time + refreshCache(t); + return g_tm.Month; +} + +int year() { // as in Processing, the full four digit year: (2009, 2010 etc) + return year(now()); +} + +int year(time_t t) { // the year for the given time + refreshCache(t); + return tmYearToCalendar(g_tm.Year); +} + +/*============================================================================*/ +/* functions to convert to and from system time */ +/* These are for interfacing with time serivces and are not normally needed in a sketch */ + +// leap year calulator expects year argument as years offset from 1970 +#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) + +static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 + +void breakTime(time_t timeInput, tmElements_t &tm){ +// break the given time_t into time components +// this is a more compact version of the C library localtime function +// note that year is offset from 1970 !!! + + uint8_t year; + uint8_t month, monthLength; + uint32_t time; + unsigned long days; + + time = (uint32_t)timeInput; + tm.Second = time % 60; + time /= 60; // now it is minutes + tm.Minute = time % 60; + time /= 60; // now it is hours + tm.Hour = time % 24; + time /= 24; // now it is days + tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 + + year = 0; + days = 0; + while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { + year++; + } + tm.Year = year; // year is offset from 1970 + + days -= LEAP_YEAR(year) ? 366 : 365; + time -= days; // now it is days in this year, starting at 0 + + days=0; + month=0; + monthLength=0; + for (month=0; month<12; month++) { + if (month==1) { // february + if (LEAP_YEAR(year)) { + monthLength=29; + } else { + monthLength=28; + } + } else { + monthLength = monthDays[month]; + } + + if (time >= monthLength) { + time -= monthLength; + } else { + break; + } + } + tm.Month = month + 1; // jan is month 1 + tm.Day = time + 1; // day of month +} + +time_t makeTime(tmElements_t &tm){ +// assemble time elements into time_t +// note year argument is offset from 1970 (see macros in time.h to convert to other formats) +// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 + + int i; + uint32_t seconds; + + // seconds from 1970 till 1 jan 00:00:00 of the given year + seconds= tm.Year*(SECS_PER_DAY * 365); + for (i = 0; i < tm.Year; i++) { + if (LEAP_YEAR(i)) { + seconds += SECS_PER_DAY; // add extra days for leap years + } + } + + // add days for this year, months start from 1 + for (i = 1; i < tm.Month; i++) { + if ( (i == 2) && LEAP_YEAR(tm.Year)) { + seconds += SECS_PER_DAY * 29; + } else { + seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 + } + } + seconds+= (tm.Day-1) * SECS_PER_DAY; + seconds+= tm.Hour * SECS_PER_HOUR; + seconds+= tm.Minute * SECS_PER_MIN; + seconds+= tm.Second; + return (time_t)seconds; +} +/*=====================================================*/ +/* Low level system time functions */ + +static uint32_t sysTime = 0; +static uint32_t prevMillis = 0; +static uint32_t nextSyncTime = 0; +static timeStatus_t Status = timeNotSet; + +getExternalTime getTimePtr; // pointer to external sync function +//setExternalTime setTimePtr; // not used in this version + +#ifdef TIME_DRIFT_INFO // define this to get drift data +time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync +#endif + + +time_t now() { + // calculate number of seconds passed since last call to now() + while (millis() - prevMillis >= 1000) { + // millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference + sysTime++; + prevMillis += 1000; +#ifdef TIME_DRIFT_INFO + sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift +#endif + } + if (nextSyncTime <= sysTime) { + if (getTimePtr != 0) { + time_t t = getTimePtr(); + if (t != 0) { + setTime(t); + } else { + nextSyncTime = sysTime + g_syncInterval; + Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync; + } + } + } + return (time_t)sysTime; +} + +void setTime(time_t t) { +#ifdef TIME_DRIFT_INFO + if(sysUnsyncedTime == 0) + sysUnsyncedTime = t; // store the time of the first call to set a valid Time +#endif + + sysTime = (uint32_t)t; + nextSyncTime = (uint32_t)t + g_syncInterval; + Status = timeSet; + prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) +} + +void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ + // year can be given as full four digit year or two digts (2010 or 10 for 2010); + //it is converted to years since 1970 + if( yr > 99) + yr = yr - 1970; + else + yr += 30; + g_tm.Year = yr; + g_tm.Month = mnth; + g_tm.Day = dy; + g_tm.Hour = hr; + g_tm.Minute = min; + g_tm.Second = sec; + setTime(makeTime(g_tm)); +} + +void adjustTime(long adjustment) { + sysTime += adjustment; +} + +// indicates if time has been set and recently synchronized +timeStatus_t timeStatus() { + now(); // required to actually update the status + return Status; +} + +void setSyncProvider( getExternalTime getTimeFunction){ + getTimePtr = getTimeFunction; + nextSyncTime = sysTime; + now(); // this will sync the clock +} + +void setSyncInterval(time_t interval){ // set the number of seconds between re-sync + g_syncInterval = (uint32_t)interval; + nextSyncTime = sysTime + g_syncInterval; +} diff --git a/x_track/src/App/Utils/Time/Time.h b/x_track/src/App/Utils/Time/Time.h new file mode 100644 index 0000000000000000000000000000000000000000..a79b0801ed2f4dcf3098112cd69bc219662265dc --- /dev/null +++ b/x_track/src/App/Utils/Time/Time.h @@ -0,0 +1 @@ +#include "TimeLib.h" diff --git a/x_track/src/App/Utils/Time/TimeLib.h b/x_track/src/App/Utils/Time/TimeLib.h new file mode 100644 index 0000000000000000000000000000000000000000..90b2fed575f46e93d9276dfe94b835633f2701bd --- /dev/null +++ b/x_track/src/App/Utils/Time/TimeLib.h @@ -0,0 +1,144 @@ +/* + time.h - low level time and date functions +*/ + +/* + July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this) + - fixed daysToTime_t macro (thanks maniacbug) +*/ + +#ifndef _Time_h +#ifdef __cplusplus +#define _Time_h + +#include <inttypes.h> +#if !defined(ARDUINO) +#include <sys/types.h> // for __time_t_defined, but avr libc lacks sys/types.h +#endif + + +#if !defined(__time_t_defined) && defined(ARDUINO) // avoid conflict with newlib or other posix libc +typedef unsigned long time_t; +#endif + + +// This ugly hack allows us to define C++ overloaded functions, when included +// from within an extern "C", as newlib's sys/stat.h does. Actually it is +// intended to include "time.h" from the C library (on ARM, but AVR does not +// have that file at all). On Mac and Windows, the compiler will find this +// "Time.h" instead of the C library "time.h", so we may cause other weird +// and unpredictable effects by conflicting with the C library header "time.h", +// but at least this hack lets us define C++ functions as intended. Hopefully +// nothing too terrible will result from overriding the C library header?! +extern "C++" { +typedef enum {timeNotSet, timeNeedsSync, timeSet +} timeStatus_t ; + +typedef enum { + dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday +} timeDayOfWeek_t; + +typedef enum { + tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields +} tmByteFields; + +typedef struct { + uint8_t Second; + uint8_t Minute; + uint8_t Hour; + uint8_t Wday; // day of week, sunday is day 1 + uint8_t Day; + uint8_t Month; + uint8_t Year; // offset from 1970; +} tmElements_t, TimeElements, *tmElementsPtr_t; + +//convenience macros to convert to and from tm years +#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year +#define CalendarYrToTm(Y) ((Y) - 1970) +#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000 +#define y2kYearToTm(Y) ((Y) + 30) + +typedef time_t(*getExternalTime)(); +//typedef void (*setExternalTime)(const time_t); // not used in this version + + +/*==============================================================================*/ +/* Useful Constants */ +#define SECS_PER_MIN (60UL) +#define SECS_PER_HOUR (3600UL) +#define SECS_PER_DAY (SECS_PER_HOUR * 24UL) +#define DAYS_PER_WEEK (7UL) +#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK) +#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL) +#define SECS_YR_2000 (946684800UL) // the time at the start of y2k + +/* Useful Macros for getting elapsed time */ +#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) +#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) +#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR) +#define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday +#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970 +#define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight +// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 +// Always set the correct time before settting alarms +#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day +#define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day +#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1 +#define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time +#define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time + + +/* Useful Macros for converting elapsed time to a time_t */ +#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN) +#define hoursToTime_t ((H)) ( (H) * SECS_PER_HOUR) +#define daysToTime_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011 +#define weeksToTime_t ((W)) ( (W) * SECS_PER_WEEK) + +/*============================================================================*/ +/* time and date functions */ +int hour(); // the hour now +int hour(time_t t); // the hour for the given time +int hourFormat12(); // the hour now in 12 hour format +int hourFormat12(time_t t); // the hour for the given time in 12 hour format +uint8_t isAM(); // returns true if time now is AM +uint8_t isAM(time_t t); // returns true the given time is AM +uint8_t isPM(); // returns true if time now is PM +uint8_t isPM(time_t t); // returns true the given time is PM +int minute(); // the minute now +int minute(time_t t); // the minute for the given time +int second(); // the second now +int second(time_t t); // the second for the given time +int day(); // the day now +int day(time_t t); // the day for the given time +int weekday(); // the weekday now (Sunday is day 1) +int weekday(time_t t); // the weekday for the given time +int month(); // the month now (Jan is month 1) +int month(time_t t); // the month for the given time +int year(); // the full four digit year: (2009, 2010 etc) +int year(time_t t); // the year for the given time + +time_t now(); // return the current time as seconds since Jan 1 1970 +void setTime(time_t t); +void setTime(int hr,int min,int sec,int day, int month, int yr); +void adjustTime(long adjustment); + +/* date strings */ +#define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null) +char* monthStr(uint8_t month); +char* dayStr(uint8_t day); +char* monthShortStr(uint8_t month); +char* dayShortStr(uint8_t day); + +/* time sync functions */ +timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized +void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider +void setSyncInterval(time_t interval); // set the number of seconds between re-sync + +/* low level functions to convert to and from system time */ +void breakTime(time_t time, tmElements_t &tm); // break time_t into elements +time_t makeTime(tmElements_t &tm); // convert time elements into time_t + +} // extern "C++" +#endif // __cplusplus +#endif /* _Time_h */ + diff --git a/x_track/src/App/Utils/Time/examples/Processing/SyncArduinoClock/SyncArduinoClock.pde b/x_track/src/App/Utils/Time/examples/Processing/SyncArduinoClock/SyncArduinoClock.pde new file mode 100644 index 0000000000000000000000000000000000000000..4313be33c2a4ccdbc2ad904ca41ab35a3e3fee1b --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/Processing/SyncArduinoClock/SyncArduinoClock.pde @@ -0,0 +1,78 @@ +/** + * SyncArduinoClock. + * + * portIndex must be set to the port connected to the Arduino + * + * The current time is sent in response to request message from Arduino + * or by clicking the display window + * + * The time message is 11 ASCII text characters; a header (the letter 'T') + * followed by the ten digit system time (unix time) + */ + + +import processing.serial.*; +import java.util.Date; +import java.util.Calendar; +import java.util.GregorianCalendar; + +public static final short portIndex = 0; // select the com port, 0 is the first port +public static final String TIME_HEADER = "T"; //header for arduino serial time message +public static final char TIME_REQUEST = 7; // ASCII bell character +public static final char LF = 10; // ASCII linefeed +public static final char CR = 13; // ASCII linefeed +Serial myPort; // Create object from Serial class + +void setup() { + size(200, 200); + println(Serial.list()); + println(" Connecting to -> " + Serial.list()[portIndex]); + myPort = new Serial(this,Serial.list()[portIndex], 9600); + println(getTimeNow()); +} + +void draw() +{ + textSize(20); + textAlign(CENTER); + fill(0); + text("Click to send\nTime Sync", 0, 75, 200, 175); + if ( myPort.available() > 0) { // If data is available, + char val = char(myPort.read()); // read it and store it in val + if(val == TIME_REQUEST){ + long t = getTimeNow(); + sendTimeMessage(TIME_HEADER, t); + } + else + { + if(val == LF) + ; //igonore + else if(val == CR) + println(); + else + print(val); // echo everying but time request + } + } +} + +void mousePressed() { + sendTimeMessage( TIME_HEADER, getTimeNow()); +} + + +void sendTimeMessage(String header, long time) { + String timeStr = String.valueOf(time); + myPort.write(header); // send header and time to arduino + myPort.write(timeStr); + myPort.write('\n'); +} + +long getTimeNow(){ + // java time is in ms, we want secs + Date d = new Date(); + Calendar cal = new GregorianCalendar(); + long current = d.getTime()/1000; + long timezone = cal.get(cal.ZONE_OFFSET)/1000; + long daylight = cal.get(cal.DST_OFFSET)/1000; + return current + timezone + daylight; +} diff --git a/x_track/src/App/Utils/Time/examples/Processing/SyncArduinoClock/readme.txt b/x_track/src/App/Utils/Time/examples/Processing/SyncArduinoClock/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..da9721d7b9834bb20c0d938d05115b2eed14e536 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/Processing/SyncArduinoClock/readme.txt @@ -0,0 +1,9 @@ +SyncArduinoClock is a Processing sketch that responds to Arduino requests for +time synchronization messages. + +The portIndex must be set the Serial port connected to Arduino. + +Download TimeSerial.pde onto Arduino and you should see the time +message displayed when you run SyncArduinoClock in Processing. +The Arduino time is set from the time on your computer through the +Processing sketch. diff --git a/x_track/src/App/Utils/Time/examples/TimeArduinoDue/TimeArduinoDue.ino b/x_track/src/App/Utils/Time/examples/TimeArduinoDue/TimeArduinoDue.ino new file mode 100644 index 0000000000000000000000000000000000000000..f0a9a95df2dcce7d7f1e8908c87f9a6ad9e407db --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeArduinoDue/TimeArduinoDue.ino @@ -0,0 +1,71 @@ +/* + * TimeRTC.pde + * example code illustrating Time library with Real Time Clock. + * + * This example requires Markus Lange's Arduino Due RTC Library + * https://github.com/MarkusLange/Arduino-Due-RTC-Library + */ + +#include <TimeLib.h> +#include <rtc_clock.h> + +// Select the Slowclock source +//RTC_clock rtc_clock(RC); +RTC_clock rtc_clock(XTAL); + +void setup() { + Serial.begin(9600); + rtc_clock.init(); + if (rtc_clock.date_already_set() == 0) { + // Unfortunately, the Arduino Due hardware does not seem to + // be designed to maintain the RTC clock state when the + // board resets. Markus described it thusly: "Uhh the Due + // does reset with the NRSTB pin. This resets the full chip + // with all backup regions including RTC, RTT and SC. Only + // if the reset is done with the NRST pin will these regions + // stay with their old values." + rtc_clock.set_time(__TIME__); + rtc_clock.set_date(__DATE__); + // However, this might work on other unofficial SAM3X boards + // with different reset circuitry than Arduino Due? + } + setSyncProvider(getArduinoDueTime); + if(timeStatus()!= timeSet) + Serial.println("Unable to sync with the RTC"); + else + Serial.println("RTC has set the system time"); +} + +time_t getArduinoDueTime() +{ + return rtc_clock.unixtime(); +} + +void loop() +{ + digitalClockDisplay(); + delay(1000); +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits){ + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + diff --git a/x_track/src/App/Utils/Time/examples/TimeGPS/TimeGPS.ino b/x_track/src/App/Utils/Time/examples/TimeGPS/TimeGPS.ino new file mode 100644 index 0000000000000000000000000000000000000000..fea9698867b35abf43e35bdb4fb41d69a01f27dc --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeGPS/TimeGPS.ino @@ -0,0 +1,87 @@ +/* + * TimeGPS.pde + * example code illustrating time synced from a GPS + * + */ + +#include <TimeLib.h> +#include <TinyGPS.h> // http://arduiniana.org/libraries/TinyGPS/ +#include <SoftwareSerial.h> +// TinyGPS and SoftwareSerial libraries are the work of Mikal Hart + +SoftwareSerial SerialGPS = SoftwareSerial(10, 11); // receive on pin 10 +TinyGPS gps; + +// To use a hardware serial port, which is far more efficient than +// SoftwareSerial, uncomment this line and remove SoftwareSerial +//#define SerialGPS Serial1 + +// Offset hours from gps time (UTC) +const int offset = 1; // Central European Time +//const int offset = -5; // Eastern Standard Time (USA) +//const int offset = -4; // Eastern Daylight Time (USA) +//const int offset = -8; // Pacific Standard Time (USA) +//const int offset = -7; // Pacific Daylight Time (USA) + +// Ideally, it should be possible to learn the time zone +// based on the GPS position data. However, that would +// require a complex library, probably incorporating some +// sort of database using Eric Muller's time zone shape +// maps, at http://efele.net/maps/tz/ + +time_t prevDisplay = 0; // when the digital clock was displayed + +void setup() +{ + Serial.begin(9600); + while (!Serial) ; // Needed for Leonardo only + SerialGPS.begin(4800); + Serial.println("Waiting for GPS time ... "); +} + +void loop() +{ + while (SerialGPS.available()) { + if (gps.encode(SerialGPS.read())) { // process gps messages + // when TinyGPS reports new data... + unsigned long age; + int Year; + byte Month, Day, Hour, Minute, Second; + gps.crack_datetime(&Year, &Month, &Day, &Hour, &Minute, &Second, NULL, &age); + if (age < 500) { + // set the Time to the latest GPS reading + setTime(Hour, Minute, Second, Day, Month, Year); + adjustTime(offset * SECS_PER_HOUR); + } + } + } + if (timeStatus()!= timeNotSet) { + if (now() != prevDisplay) { //update the display only if the time has changed + prevDisplay = now(); + digitalClockDisplay(); + } + } +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits) { + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + diff --git a/x_track/src/App/Utils/Time/examples/TimeNTP/TimeNTP.ino b/x_track/src/App/Utils/Time/examples/TimeNTP/TimeNTP.ino new file mode 100644 index 0000000000000000000000000000000000000000..17a908f821b7f6978d98f84e5918a8d8af5345d8 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeNTP/TimeNTP.ino @@ -0,0 +1,135 @@ +/* + * Time_NTP.pde + * Example showing time sync to NTP time source + * + * This sketch uses the Ethernet library + */ + +#include <TimeLib.h> +#include <Ethernet.h> +#include <EthernetUdp.h> +#include <SPI.h> + +byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; +// NTP Servers: +IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov +// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov +// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov + + +const int timeZone = 1; // Central European Time +//const int timeZone = -5; // Eastern Standard Time (USA) +//const int timeZone = -4; // Eastern Daylight Time (USA) +//const int timeZone = -8; // Pacific Standard Time (USA) +//const int timeZone = -7; // Pacific Daylight Time (USA) + + +EthernetUDP Udp; +unsigned int localPort = 8888; // local port to listen for UDP packets + +void setup() +{ + Serial.begin(9600); + while (!Serial) ; // Needed for Leonardo only + delay(250); + Serial.println("TimeNTP Example"); + if (Ethernet.begin(mac) == 0) { + // no point in carrying on, so do nothing forevermore: + while (1) { + Serial.println("Failed to configure Ethernet using DHCP"); + delay(10000); + } + } + Serial.print("IP number assigned by DHCP is "); + Serial.println(Ethernet.localIP()); + Udp.begin(localPort); + Serial.println("waiting for sync"); + setSyncProvider(getNtpTime); +} + +time_t prevDisplay = 0; // when the digital clock was displayed + +void loop() +{ + if (timeStatus() != timeNotSet) { + if (now() != prevDisplay) { //update the display only if time has changed + prevDisplay = now(); + digitalClockDisplay(); + } + } +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits){ + // utility for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + +/*-------- NTP code ----------*/ + +const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message +byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets + +time_t getNtpTime() +{ + while (Udp.parsePacket() > 0) ; // discard any previously received packets + Serial.println("Transmit NTP Request"); + sendNTPpacket(timeServer); + uint32_t beginWait = millis(); + while (millis() - beginWait < 1500) { + int size = Udp.parsePacket(); + if (size >= NTP_PACKET_SIZE) { + Serial.println("Receive NTP Response"); + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer + unsigned long secsSince1900; + // convert four bytes starting at location 40 to a long integer + secsSince1900 = (unsigned long)packetBuffer[40] << 24; + secsSince1900 |= (unsigned long)packetBuffer[41] << 16; + secsSince1900 |= (unsigned long)packetBuffer[42] << 8; + secsSince1900 |= (unsigned long)packetBuffer[43]; + return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; + } + } + Serial.println("No NTP Response :-("); + return 0; // return 0 if unable to get the time +} + +// send an NTP request to the time server at the given address +void sendNTPpacket(IPAddress &address) +{ + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); //NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} + diff --git a/x_track/src/App/Utils/Time/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino b/x_track/src/App/Utils/Time/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino new file mode 100644 index 0000000000000000000000000000000000000000..cab64883fa1362ddae939e8c11406ba8c8f7f05f --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino @@ -0,0 +1,143 @@ +/* + * Time_NTP.pde + * Example showing time sync to NTP time source + * + * This sketch uses the ESP8266WiFi library + */ + +#include <TimeLib.h> +#include <ESP8266WiFi.h> +#include <WiFiUdp.h> + +const char ssid[] = "*************"; // your network SSID (name) +const char pass[] = "********"; // your network password + +// NTP Servers: +IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov +// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov +// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov + + +const int timeZone = 1; // Central European Time +//const int timeZone = -5; // Eastern Standard Time (USA) +//const int timeZone = -4; // Eastern Daylight Time (USA) +//const int timeZone = -8; // Pacific Standard Time (USA) +//const int timeZone = -7; // Pacific Daylight Time (USA) + + +WiFiUDP Udp; +unsigned int localPort = 8888; // local port to listen for UDP packets + +void setup() +{ + Serial.begin(9600); + while (!Serial) ; // Needed for Leonardo only + delay(250); + Serial.println("TimeNTP Example"); + Serial.print("Connecting to "); + Serial.println(ssid); + WiFi.begin(ssid, pass); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + + Serial.print("IP number assigned by DHCP is "); + Serial.println(WiFi.localIP()); + Serial.println("Starting UDP"); + Udp.begin(localPort); + Serial.print("Local port: "); + Serial.println(Udp.localPort()); + Serial.println("waiting for sync"); + setSyncProvider(getNtpTime); +} + +time_t prevDisplay = 0; // when the digital clock was displayed + +void loop() +{ + if (timeStatus() != timeNotSet) { + if (now() != prevDisplay) { //update the display only if time has changed + prevDisplay = now(); + digitalClockDisplay(); + } + } +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print("."); + Serial.print(month()); + Serial.print("."); + Serial.print(year()); + Serial.println(); +} + + + +void printDigits(int digits){ + // utility for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + +/*-------- NTP code ----------*/ + +const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message +byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets + +time_t getNtpTime() +{ + while (Udp.parsePacket() > 0) ; // discard any previously received packets + Serial.println("Transmit NTP Request"); + sendNTPpacket(timeServer); + uint32_t beginWait = millis(); + while (millis() - beginWait < 1500) { + int size = Udp.parsePacket(); + if (size >= NTP_PACKET_SIZE) { + Serial.println("Receive NTP Response"); + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer + unsigned long secsSince1900; + // convert four bytes starting at location 40 to a long integer + secsSince1900 = (unsigned long)packetBuffer[40] << 24; + secsSince1900 |= (unsigned long)packetBuffer[41] << 16; + secsSince1900 |= (unsigned long)packetBuffer[42] << 8; + secsSince1900 |= (unsigned long)packetBuffer[43]; + return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR; + } + } + Serial.println("No NTP Response :-("); + return 0; // return 0 if unable to get the time +} + +// send an NTP request to the time server at the given address +void sendNTPpacket(IPAddress &address) +{ + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); //NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} diff --git a/x_track/src/App/Utils/Time/examples/TimeRTC/TimeRTC.ino b/x_track/src/App/Utils/Time/examples/TimeRTC/TimeRTC.ino new file mode 100644 index 0000000000000000000000000000000000000000..fa10ff6f58d278901dbae84db306b1403e353497 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeRTC/TimeRTC.ino @@ -0,0 +1,55 @@ +/* + * TimeRTC.pde + * example code illustrating Time library with Real Time Clock. + * + */ + +#include <TimeLib.h> +#include <Wire.h> +#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t + +void setup() { + Serial.begin(9600); + while (!Serial) ; // wait until Arduino Serial Monitor opens + setSyncProvider(RTC.get); // the function to get the time from the RTC + if(timeStatus()!= timeSet) + Serial.println("Unable to sync with the RTC"); + else + Serial.println("RTC has set the system time"); +} + +void loop() +{ + if (timeStatus() == timeSet) { + digitalClockDisplay(); + } else { + Serial.println("The time has not been set. Please run the Time"); + Serial.println("TimeRTCSet example, or DS1307RTC SetTime example."); + Serial.println(); + delay(4000); + } + delay(1000); +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits){ + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + diff --git a/x_track/src/App/Utils/Time/examples/TimeRTCLog/TimeRTCLog.ino b/x_track/src/App/Utils/Time/examples/TimeRTCLog/TimeRTCLog.ino new file mode 100644 index 0000000000000000000000000000000000000000..0b250c2020ba21f27fec919bf0a0be04378094a4 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeRTCLog/TimeRTCLog.ino @@ -0,0 +1,107 @@ +/* + * TimeRTCLogger.pde + * example code illustrating adding and subtracting Time. + * + * this sketch logs pin state change events + * the time of the event and time since the previous event is calculated and sent to the serial port. + */ + +#include <TimeLib.h> +#include <Wire.h> +#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t + +const int nbrInputPins = 6; // monitor 6 digital pins +const int inputPins[nbrInputPins] = {2,3,4,5,6,7}; // pins to monitor +boolean state[nbrInputPins] ; // the state of the monitored pins +time_t prevEventTime[nbrInputPins] ; // the time of the previous event + +void setup() { + Serial.begin(9600); + setSyncProvider(RTC.get); // the function to sync the time from the RTC + for(int i=0; i < nbrInputPins; i++){ + pinMode( inputPins[i], INPUT); + // uncomment these lines if pull-up resistors are wanted + // pinMode( inputPins[i], INPUT_PULLUP); + // state[i] = HIGH; + } +} + +void loop() +{ + for(int i=0; i < nbrInputPins; i++) + { + boolean val = digitalRead(inputPins[i]); + if(val != state[i]) + { + time_t duration = 0; // the time since the previous event + state[i] = val; + time_t timeNow = now(); + if(prevEventTime[i] > 0) + // if this was not the first state change, calculate the time from the previous change + duration = duration = timeNow - prevEventTime[i]; + logEvent(inputPins[i], val, timeNow, duration ); // log the event + prevEventTime[i] = timeNow; // store the time for this event + } + } +} + +void logEvent( int pin, boolean state, time_t timeNow, time_t duration) +{ + Serial.print("Pin "); + Serial.print(pin); + if( state == HIGH) + Serial.print(" went High at "); + else + Serial.print(" went Low at "); + showTime(timeNow); + if(duration > 0){ + // only display duration if greater than 0 + Serial.print(", Duration was "); + showDuration(duration); + } + Serial.println(); +} + + +void showTime(time_t t){ + // display the given time + Serial.print(hour(t)); + printDigits(minute(t)); + printDigits(second(t)); + Serial.print(" "); + Serial.print(day(t)); + Serial.print(" "); + Serial.print(month(t)); + Serial.print(" "); + Serial.print(year(t)); +} + +void printDigits(int digits){ + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + +void showDuration(time_t duration){ +// prints the duration in days, hours, minutes and seconds + if(duration >= SECS_PER_DAY){ + Serial.print(duration / SECS_PER_DAY); + Serial.print(" day(s) "); + duration = duration % SECS_PER_DAY; + } + if(duration >= SECS_PER_HOUR){ + Serial.print(duration / SECS_PER_HOUR); + Serial.print(" hour(s) "); + duration = duration % SECS_PER_HOUR; + } + if(duration >= SECS_PER_MIN){ + Serial.print(duration / SECS_PER_MIN); + Serial.print(" minute(s) "); + duration = duration % SECS_PER_MIN; + } + Serial.print(duration); + Serial.print(" second(s) "); +} + diff --git a/x_track/src/App/Utils/Time/examples/TimeRTCSet/TimeRTCSet.ino b/x_track/src/App/Utils/Time/examples/TimeRTCSet/TimeRTCSet.ino new file mode 100644 index 0000000000000000000000000000000000000000..49c49f3740cdcade51d5d4aa4236729ba72c8f5b --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeRTCSet/TimeRTCSet.ino @@ -0,0 +1,80 @@ +/* + * TimeRTCSet.pde + * example code illustrating Time library with Real Time Clock. + * + * RTC clock is set in response to serial port time message + * A Processing example sketch to set the time is included in the download + * On Linux, you can use "date +T%s > /dev/ttyACM0" (UTC time zone) + */ + +#include <TimeLib.h> +#include <Wire.h> +#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t + + +void setup() { + Serial.begin(9600); + while (!Serial) ; // Needed for Leonardo only + setSyncProvider(RTC.get); // the function to get the time from the RTC + if (timeStatus() != timeSet) + Serial.println("Unable to sync with the RTC"); + else + Serial.println("RTC has set the system time"); +} + +void loop() +{ + if (Serial.available()) { + time_t t = processSyncMessage(); + if (t != 0) { + RTC.set(t); // set the RTC and the system time to the received value + setTime(t); + } + } + digitalClockDisplay(); + delay(1000); +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits){ + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + +/* code to process time sync messages from the serial port */ +#define TIME_HEADER "T" // Header tag for serial time sync message + +unsigned long processSyncMessage() { + unsigned long pctime = 0L; + const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 + + if(Serial.find(TIME_HEADER)) { + pctime = Serial.parseInt(); + return pctime; + if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013) + pctime = 0L; // return 0 to indicate that the time is not valid + } + } + return pctime; +} + + + + + diff --git a/x_track/src/App/Utils/Time/examples/TimeSerial/TimeSerial.ino b/x_track/src/App/Utils/Time/examples/TimeSerial/TimeSerial.ino new file mode 100644 index 0000000000000000000000000000000000000000..07e609fde171e5a467bf4292d86cfd9d40077de6 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeSerial/TimeSerial.ino @@ -0,0 +1,81 @@ +/* + * TimeSerial.pde + * example code illustrating Time library set through serial port messages. + * + * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970) + * you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013 + T1357041600 + * + * A Processing example sketch to automatically send the messages is included in the download + * On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone) + */ + +#include <TimeLib.h> + +#define TIME_HEADER "T" // Header tag for serial time sync message +#define TIME_REQUEST 7 // ASCII bell character requests a time sync message + +void setup() { + Serial.begin(9600); + while (!Serial) ; // Needed for Leonardo only + pinMode(13, OUTPUT); + setSyncProvider( requestSync); //set function to call when sync required + Serial.println("Waiting for sync message"); +} + +void loop(){ + if (Serial.available()) { + processSyncMessage(); + } + if (timeStatus()!= timeNotSet) { + digitalClockDisplay(); + } + if (timeStatus() == timeSet) { + digitalWrite(13, HIGH); // LED on if synced + } else { + digitalWrite(13, LOW); // LED off if needs refresh + } + delay(1000); +} + +void digitalClockDisplay(){ + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits){ + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + + +void processSyncMessage() { + unsigned long pctime; + const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 + + if(Serial.find(TIME_HEADER)) { + pctime = Serial.parseInt(); + if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013) + setTime(pctime); // Sync Arduino clock to the time received on the serial port + } + } +} + +time_t requestSync() +{ + Serial.write(TIME_REQUEST); + return 0; // the time will be sent later in response to serial mesg +} + diff --git a/x_track/src/App/Utils/Time/examples/TimeSerialDateStrings/TimeSerialDateStrings.ino b/x_track/src/App/Utils/Time/examples/TimeSerialDateStrings/TimeSerialDateStrings.ino new file mode 100644 index 0000000000000000000000000000000000000000..95d2568c1763e37b3293f4bccdcecdf0c2b6cd20 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeSerialDateStrings/TimeSerialDateStrings.ino @@ -0,0 +1,108 @@ +/* + * TimeSerialDateStrings.pde + * example code illustrating Time library date strings + * + * This sketch adds date string functionality to TimeSerial sketch + * Also shows how to handle different messages + * + * A message starting with a time header sets the time + * A Processing example sketch to automatically send the messages is inclided in the download + * On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone) + * + * A message starting with a format header sets the date format + + * send: Fs\n for short date format + * send: Fl\n for long date format + */ + +#include <TimeLib.h> + +// single character message tags +#define TIME_HEADER 'T' // Header tag for serial time sync message +#define FORMAT_HEADER 'F' // Header tag indicating a date format message +#define FORMAT_SHORT 's' // short month and day strings +#define FORMAT_LONG 'l' // (lower case l) long month and day strings + +#define TIME_REQUEST 7 // ASCII bell character requests a time sync message + +static boolean isLongFormat = true; + +void setup() { + Serial.begin(9600); + while (!Serial) ; // Needed for Leonardo only + setSyncProvider( requestSync); //set function to call when sync required + Serial.println("Waiting for sync message"); +} + +void loop(){ + if (Serial.available() > 1) { // wait for at least two characters + char c = Serial.read(); + if( c == TIME_HEADER) { + processSyncMessage(); + } + else if( c== FORMAT_HEADER) { + processFormatMessage(); + } + } + if (timeStatus()!= timeNotSet) { + digitalClockDisplay(); + } + delay(1000); +} + +void digitalClockDisplay() { + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + if(isLongFormat) + Serial.print(dayStr(weekday())); + else + Serial.print(dayShortStr(weekday())); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + if(isLongFormat) + Serial.print(monthStr(month())); + else + Serial.print(monthShortStr(month())); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +void printDigits(int digits) { + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + +void processFormatMessage() { + char c = Serial.read(); + if( c == FORMAT_LONG){ + isLongFormat = true; + Serial.println(F("Setting long format")); + } + else if( c == FORMAT_SHORT) { + isLongFormat = false; + Serial.println(F("Setting short format")); + } +} + +void processSyncMessage() { + unsigned long pctime; + const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 - paul, perhaps we define in time.h? + + pctime = Serial.parseInt(); + if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013) + setTime(pctime); // Sync Arduino clock to the time received on the serial port + } +} + +time_t requestSync() { + Serial.write(TIME_REQUEST); + return 0; // the time will be sent later in response to serial mesg +} diff --git a/x_track/src/App/Utils/Time/examples/TimeTeensy3/TimeTeensy3.ino b/x_track/src/App/Utils/Time/examples/TimeTeensy3/TimeTeensy3.ino new file mode 100644 index 0000000000000000000000000000000000000000..f68dd8cc7f2ecdeb9ebd14f96720fe8a110252d7 --- /dev/null +++ b/x_track/src/App/Utils/Time/examples/TimeTeensy3/TimeTeensy3.ino @@ -0,0 +1,78 @@ +/* + * TimeRTC.pde + * example code illustrating Time library with Real Time Clock. + * + */ + +#include <TimeLib.h> + +void setup() { + // set the Time library to use Teensy 3.0's RTC to keep time + setSyncProvider(getTeensy3Time); + + Serial.begin(115200); + while (!Serial); // Wait for Arduino Serial Monitor to open + delay(100); + if (timeStatus()!= timeSet) { + Serial.println("Unable to sync with the RTC"); + } else { + Serial.println("RTC has set the system time"); + } +} + +void loop() { + if (Serial.available()) { + time_t t = processSyncMessage(); + if (t != 0) { + Teensy3Clock.set(t); // set the RTC + setTime(t); + } + } + digitalClockDisplay(); + delay(1000); +} + +void digitalClockDisplay() { + // digital clock display of the time + Serial.print(hour()); + printDigits(minute()); + printDigits(second()); + Serial.print(" "); + Serial.print(day()); + Serial.print(" "); + Serial.print(month()); + Serial.print(" "); + Serial.print(year()); + Serial.println(); +} + +time_t getTeensy3Time() +{ + return Teensy3Clock.get(); +} + +/* code to process time sync messages from the serial port */ +#define TIME_HEADER "T" // Header tag for serial time sync message + +unsigned long processSyncMessage() { + unsigned long pctime = 0L; + const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 + + if(Serial.find(TIME_HEADER)) { + pctime = Serial.parseInt(); + return pctime; + if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013) + pctime = 0L; // return 0 to indicate that the time is not valid + } + } + return pctime; +} + +void printDigits(int digits){ + // utility function for digital clock display: prints preceding colon and leading 0 + Serial.print(":"); + if(digits < 10) + Serial.print('0'); + Serial.print(digits); +} + diff --git a/x_track/src/App/Utils/Time/keywords.txt b/x_track/src/App/Utils/Time/keywords.txt new file mode 100644 index 0000000000000000000000000000000000000000..073f8f8855020d95241a84adad53b20b443bdc75 --- /dev/null +++ b/x_track/src/App/Utils/Time/keywords.txt @@ -0,0 +1,34 @@ +####################################### +# Syntax Coloring Map For Time +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +time_t KEYWORD1 +####################################### +# Methods and Functions (KEYWORD2) +####################################### +now KEYWORD2 +second KEYWORD2 +minute KEYWORD2 +hour KEYWORD2 +day KEYWORD2 +month KEYWORD2 +year KEYWORD2 +isAM KEYWORD2 +isPM KEYWORD2 +weekday KEYWORD2 +setTime KEYWORD2 +adjustTime KEYWORD2 +setSyncProvider KEYWORD2 +setSyncInterval KEYWORD2 +timeStatus KEYWORD2 +TimeLib KEYWORD2 +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/x_track/src/App/Utils/Time/library.json b/x_track/src/App/Utils/Time/library.json new file mode 100644 index 0000000000000000000000000000000000000000..071e74c9faae40afe31f4ef0c69d5fdad17b3c14 --- /dev/null +++ b/x_track/src/App/Utils/Time/library.json @@ -0,0 +1,22 @@ +{ +"name": "Time", +"frameworks": "Arduino", +"keywords": "Time, date, hour, minute, second, day, week, month, year, RTC", +"description": "Time keeping library", +"url": "http://playground.arduino.cc/Code/Time", +"authors": +[ +{ + "name": "Michael Margolis" +}, +{ + "name": "Paul Stoffregen" +} +], +"repository": +{ + "type": "git", + "url": "https://github.com/PaulStoffregen/Time" +} +} + diff --git a/x_track/src/App/Utils/Time/library.properties b/x_track/src/App/Utils/Time/library.properties new file mode 100644 index 0000000000000000000000000000000000000000..49b1e2a16e8215d7e63ffa8a50e4af41569c9116 --- /dev/null +++ b/x_track/src/App/Utils/Time/library.properties @@ -0,0 +1,10 @@ +name=Time +version=1.5 +author=Michael Margolis +maintainer=Paul Stoffregen +sentence=Timekeeping functionality for Arduino +paragraph=Date and Time functions, with provisions to synchronize to external time sources like GPS and NTP (Internet). This library is often used together with TimeAlarms and DS1307RTC. +category=Timing +url=http://playground.arduino.cc/code/time +architectures=* + diff --git a/x_track/src/App/Utils/TrackLineFilter/TrackLineFilter.cpp b/x_track/src/App/Utils/TrackLineFilter/TrackLineFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f8e3ca30920c6816d00122759f02ac7544008dd --- /dev/null +++ b/x_track/src/App/Utils/TrackLineFilter/TrackLineFilter.cpp @@ -0,0 +1,207 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "TrackLineFilter.h" +#include <math.h> +#include <string.h> + +#define SQ(x) ((x) * (x)) + +#define TLF_USE_LOG 0 + +#if TLF_USE_LOG +#include <stdio.h> +#define LOG_PRINT(format, ...) printf(format, ##__VA_ARGS__), printf("\n") +#else +#define LOG_PRINT(format, ...) +#endif + +TrackLineFilter::TrackLineFilter(Callback_t callback, void* userData) + : _outputCallback(callback) + , _userData(userData) + , _clipArea { 0 } + , _prePoint { 0 } + , _pointCnt(0) + , _pointOutputCnt(0) + , _isFirstPoint(false) + , _isInArea(true) +{ +} + +TrackLineFilter::~TrackLineFilter() +{ +} + +void TrackLineFilter::reset() +{ + _pointCnt = 0; + _pointOutputCnt = 0; + _isFirstPoint = false; + _isInArea = false; +} + +void TrackLineFilter::pushPoint(const Point_t* point) +{ + checkPoint(point); + next(point); +} + +void TrackLineFilter::pushEnd() +{ + const Point_t* p = _pointCnt > 0 ? &_prePoint : nullptr; + outputPoint(p); +} + +void TrackLineFilter::setArea(const Area_t* area) +{ + _clipArea = *area; +} + +bool TrackLineFilter::getIsPointInArea(const Point_t* point) +{ + bool inArea = (point->x >= _clipArea.x0 + && point->x <= _clipArea.x1 + && point->y >= _clipArea.y0 + && point->y <= _clipArea.y1); + + LOG_PRINT( + "# Point(%d,%d) Area(%d,%d # %d,%d) inArea:%d", + point->x, point->y, + _clipArea.x0, _clipArea.y0, + _clipArea.x1, _clipArea.y1, + inArea); + + return inArea; +} + +void TrackLineFilter::outputPoint(const Point_t* point) +{ + if (!_isInArea) { + sendEvent(EVENT_ID::START_LINE, nullptr); + _isInArea = true; + } + sendEvent(EVENT_ID::APPEND_POINT, point); + _pointOutputCnt++; +} + +void TrackLineFilter::next(const Point_t* point) +{ + _prePoint = *point; + _pointCnt++; +} + +bool TrackLineFilter::checkPoint(const Point_t* point) +{ + /* if line start, record first point */ + if (!_isFirstPoint) { + _isFirstPoint = true; + return false; + } + + /* if two point all in area */ + if (getIsPointInArea(&_prePoint) && getIsPointInArea(point)) { + outputPoint(point); + return true; + } + + /* + + p1 *------------------* p2 + | | + | | + | | + | | + | | + | | + | | + p4 *------------------* p3 + + */ + + Point_t p1; + p1.x = _clipArea.x0; + p1.y = _clipArea.y0; + + Point_t p2; + p2.x = _clipArea.x1; + p2.y = _clipArea.y0; + + Point_t p3; + p3.x = _clipArea.x1; + p3.y = _clipArea.y1; + + Point_t p4; + p4.x = _clipArea.x0; + p4.y = _clipArea.y1; + + Point_t q1 = _prePoint; + Point_t q2 = *point; + + /* check if line intersect with area */ + if (isIntersect(&p1, &p2, &q1, &q2) + || isIntersect(&p2, &p3, &q1, &q2) + || isIntersect(&p3, &p4, &q1, &q2) + || isIntersect(&p4, &p1, &q1, &q2)) { + outputPoint(&_prePoint); + outputPoint(point); + return true; + } + + return false; +} + +void TrackLineFilter::sendEvent(EVENT_ID id, const Point_t* point) +{ + if (!_outputCallback) { + return; + } + + Event_t event; + event.eventID = id; + event.point = point; + _outputCallback(this, &event); +} + +int64_t TrackLineFilter::crossProduct(const Point_t* a, const Point_t* b) +{ + return (int64_t)a->x * (int64_t)b->y - (int64_t)b->x * (int64_t)a->y; +} + +bool TrackLineFilter::isIntersect(const Point_t* p1, const Point_t* p2, const Point_t* q1, const Point_t* q2) +{ + Point_t u = { p2->x - p1->x, p2->y - p1->y }; + Point_t v = { q2->x - q1->x, q2->y - q1->y }; + Point_t w = { p1->x - q1->x, p1->y - q1->y }; + int64_t t = crossProduct(&u, &v); + int64_t s1 = crossProduct(&w, &u); + int64_t s2 = crossProduct(&w, &v); + + if (t > 0) { + return s1 >= 0 && s1 <= t && s2 >= 0 && s2 <= t; + } + + if (t < 0) { + return s1 <= 0 && s1 >= t && s2 <= 0 && s2 >= t; + } + + return s1 == 0 || s2 == 0; +} diff --git a/x_track/src/App/Utils/TrackLineFilter/TrackLineFilter.h b/x_track/src/App/Utils/TrackLineFilter/TrackLineFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..71a7ad14ca86defa2e5ddf94108dc20071a3cbcc --- /dev/null +++ b/x_track/src/App/Utils/TrackLineFilter/TrackLineFilter.h @@ -0,0 +1,96 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TRACK_LINE_FILTER_H +#define __TRACK_LINE_FILTER_H + +#include <stdint.h> + +class TrackLineFilter { +public: + typedef struct + { + int32_t x; + int32_t y; + } Point_t; + + enum class EVENT_ID { + START_LINE, + APPEND_POINT, + }; + + typedef struct + { + EVENT_ID eventID; + uint32_t lineIndex; + const Point_t* point; + } Event_t; + + typedef struct + { + int32_t x0; + int32_t y0; + int32_t x1; + int32_t y1; + } Area_t; + + typedef void (*Callback_t)(TrackLineFilter* filter, const Event_t* event); + +public: +public: + TrackLineFilter(Callback_t callback, void* userData); + ~TrackLineFilter(); + + void reset(); + void pushPoint(int32_t x, int32_t y) + { + Point_t point = { x, y }; + pushPoint(&point); + } + void pushPoint(const Point_t* point); + void pushEnd(); + + void setArea(const Area_t* area); + const Area_t* getArea() { return &_clipArea; } + bool getIsPointInArea(const Point_t* point); + void* getUserData() { return _userData; } + +private: + Callback_t _outputCallback; + void* _userData; + Area_t _clipArea; + Point_t _prePoint; + uint32_t _pointCnt; + uint32_t _pointOutputCnt; + bool _isFirstPoint; + bool _isInArea; + +private: + void next(const Point_t* point); + bool checkPoint(const Point_t* point); + void outputPoint(const Point_t* point); + void sendEvent(EVENT_ID id, const Point_t* point); + int64_t crossProduct(const Point_t* a, const Point_t* b); + bool isIntersect(const Point_t* p1, const Point_t* p2, const Point_t* q1, const Point_t* q2); +}; + +#endif diff --git a/x_track/src/App/Utils/TrackPointFilter/TrackPointFilter.cpp b/x_track/src/App/Utils/TrackPointFilter/TrackPointFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f4945ded70a6a4c4bdbf0f7ab3fa31d49e78d269 --- /dev/null +++ b/x_track/src/App/Utils/TrackPointFilter/TrackPointFilter.cpp @@ -0,0 +1,280 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "TrackPointFilter.h" +#include <cmath> +#include <float.h> +#include <string.h> + +#define SQ(x) ((x) * (x)) +#define FLOAT_0 FLT_EPSILON + +#define TPF_USE_LOG 0 +#define TPF_USE_LINE_CHECKED 0 + +#if TPF_USE_LOG +#include <stdio.h> +#define LOG_PRINT(format, ...) printf(format, ##__VA_ARGS__), printf("\n") +#else +#define LOG_PRINT(format, ...) +#endif + +TrackPointFilter::TrackPointFilter(Callback_t callback, void* userData, double offsetThr) + : _outputCallback(callback) + , _userData(userData) + , _offsetThreshold(offsetThr) + , _tailPoint { 0 } + , _prePoint { 0 } + , _refLine { 0 } + , _pointCnt(0) + , _pointOutputCnt(0) + , _secondFilterMode(false) +{ +} + +TrackPointFilter::~TrackPointFilter() +{ +} + +void TrackPointFilter::reset() +{ + _pointCnt = 0; + _pointOutputCnt = 0; +} + +bool TrackPointFilter::pushPoint(const Point_t* point) +{ + bool retval = false; + dumpPoint("\n+P", point); + if (_pointCnt == 0) { + retval = true; + outputPoint(point); + } else if (_pointCnt == 1) { + if (!getLine(&_refLine, &_prePoint, point)) { + return false; + } + dumpLine("First", &_refLine); + } else { + dumpLine("--", &_refLine); + + double offset = getOffset(&_refLine, point); + LOG_PRINT("OFS = %lf", offset); + + if (offset > _offsetThreshold) { + LOG_PRINT("<---> offset detect!"); + + retval = true; + + if (_secondFilterMode) { + outputPoint(&_tailPoint); + } + + outputPoint(&_prePoint); + if (!getLine(&_refLine, &_prePoint, point)) { + return false; + } + } else { + Line_t line; + if (!getLine(&line, &_tailPoint, &_prePoint)) { + return false; + } + + dumpLine("L", &line); +#if TPF_USE_LINE_CHECKED + bool inLine1 = getIsPointInLine(&line, &_tailPoint); + if (!inLine1) { + dumpPoint("tailPoint", &_tailPoint); + LOG_PRINT("not in L"); + while (1) { } + } + + bool inLine2 = getIsPointInLine(&line, &_prePoint); + if (!inLine2) { + dumpPoint("prePoint", &_prePoint); + LOG_PRINT("not in L"); + while (1) { } + } +#endif + + Line_t verLine; + getVerticalLine(&verLine, &line, &_prePoint); + + dumpLine("|", &verLine); + dumpPoint("in", &_prePoint); + +#if TPF_USE_LINE_CHECKED + bool inLine3 = getIsPointInLine(&verLine, &_prePoint); + if (!inLine3) { + dumpPoint("prePoint", &_prePoint); + LOG_PRINT("not in verLine"); + while (1) { } + } +#endif + + if (getIsOnSameSide(&verLine, &_tailPoint, point)) { + LOG_PRINT("~~~ direction change detect!"); + + dumpPoint("p0", &_tailPoint); + dumpPoint("p1", &_prePoint); + dumpPoint("p2", point); + + retval = true; + + if (_secondFilterMode) { + outputPoint(&_tailPoint); + } + + outputPoint(&_prePoint); + if (!getLine(&_refLine, &_prePoint, point)) { + return false; + } + } + } + } + + _tailPoint = _prePoint; + _prePoint = *point; + _pointCnt++; + + return retval; +} + +void TrackPointFilter::pushEnd() +{ + outputPoint(&_prePoint); + reset(); +} + +void TrackPointFilter::setSecondFilterModeEnable(bool en) +{ + _secondFilterMode = en; +} + +void TrackPointFilter::outputPoint(const Point_t* point) +{ + if (_outputCallback) { + dumpPoint(">>> output", point); + LOG_PRINT(" "); + _outputCallback(this, point); + } + _pointOutputCnt++; +} + +bool TrackPointFilter::getLine(Line_t* line, const Point_t* point0, const Point_t* point1) +{ + bool retval = true; + + double x0 = point0->x; + double x1 = point1->x; + double y0 = point0->y; + double y1 = point1->y; + + double x_diff_abs = std::abs(x0 - x1); + double y_diff_abs = std::abs(y0 - y1); + + double a = 0; + double b = 0; + double c = 0; + + if (x_diff_abs < FLOAT_0 && y_diff_abs > FLOAT_0) { + a = 1; + b = 0; + c = -x0; + } else if (x_diff_abs > FLOAT_0 && y_diff_abs < FLOAT_0) { + a = 0; + b = 1; + c = -y0; + } else if (x_diff_abs > FLOAT_0 && y_diff_abs > FLOAT_0) { + a = (y1 - y0) / (x0 - x1); + b = (a * (x0 - x1)) / (y1 - y0); + c = 0 - a * x0 - b * y0; + } else { + retval = false; + } + + line->a = a; + line->b = b; + line->c = c; + + return retval; +} + +void TrackPointFilter::dumpLine(const char* name, const Line_t* line) +{ + LOG_PRINT( + "%s : %lfx + %lfy + %lf = 0 { y = %lfx + %lf }", + name, line->a, line->b, line->c, + -line->a / line->b, -line->c / line->b); +} + +void TrackPointFilter::dumpPoint(const char* name, const Point_t* point) +{ + LOG_PRINT("%s : (%lf, %lf)", name, point->x, point->y); +} + +void TrackPointFilter::getVerticalLine(Line_t* verLine, const Line_t* oriLine, const Point_t* point) +{ + verLine->a = -oriLine->b; + verLine->b = oriLine->a; + verLine->c = 0 - verLine->a * point->x - verLine->b * point->y; +} + +double TrackPointFilter::getOffset(const Line_t* line, const Point_t* point) +{ + double temp = line->a * point->x + line->b * point->y + line->c; + double offset = std::abs(temp) * invSqrt(SQ(line->a) + SQ(line->b)); + return offset; +} + +bool TrackPointFilter::getIsOnSameSide(const Line_t* line, const Point_t* point0, const Point_t* point1) +{ + bool retval = true; + double side = (line->a * point0->x + line->b * point0->y + line->c) + * (line->a * point1->x + line->b * point1->y + line->c); + + if (side < FLOAT_0) { + retval = false; + } + + return retval; +} + +bool TrackPointFilter::getIsPointInLine(const Line_t* line, const Point_t* point) +{ + double result = line->a * point->x + line->b * point->y + line->c; + return std::abs(result) < FLOAT_0; +} + +double TrackPointFilter::invSqrt(double num) +{ + uint32_t i; + float x2, y; + const float threehalfs = 1.5f; + x2 = (float)num * 0.5f; + y = (float)num; + i = *(uint32_t*)&y; + i = 0x5f3759df - (i >> 1); + y = *(float*)&i; + y = y * (threehalfs - (x2 * y * y)); + y = y * (threehalfs - (x2 * y * y)); + return y; +} diff --git a/x_track/src/App/Utils/TrackPointFilter/TrackPointFilter.h b/x_track/src/App/Utils/TrackPointFilter/TrackPointFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..ab74c3b02c694f338b340325fc787846c1640216 --- /dev/null +++ b/x_track/src/App/Utils/TrackPointFilter/TrackPointFilter.h @@ -0,0 +1,94 @@ +/* + * MIT License + * Copyright (c) 2021 - 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TRACK_POINT_FILTER_H +#define __TRACK_POINT_FILTER_H + +#include <stdint.h> + +class TrackPointFilter { +public: + typedef struct + { + double x; + double y; + } Point_t; + + typedef void (*Callback_t)(TrackPointFilter* filter, const Point_t* point); + +public: + TrackPointFilter(Callback_t callback = nullptr, void* userData = nullptr, double offsetThr = 2); + ~TrackPointFilter(); + + void reset(); + bool pushPoint(double x, double y) + { + Point_t point = { x, y }; + return pushPoint(&point); + } + bool pushPoint(const Point_t* point); + void pushEnd(); + + void setSecondFilterModeEnable(bool en); + void getCounts(uint32_t* sum, uint32_t* output) + { + *sum = _pointCnt; + *output = _pointOutputCnt; + } + void* getUserData() + { + return _userData; + } + +private: + typedef struct + { + double a; + double b; + double c; + } Line_t; + +private: + Callback_t _outputCallback; + void* _userData; + double _offsetThreshold; + Point_t _tailPoint; + Point_t _prePoint; + Line_t _refLine; + uint32_t _pointCnt; + uint32_t _pointOutputCnt; + bool _secondFilterMode; + +private: + bool getLine(Line_t* line, const Point_t* point0, const Point_t* point1); + void getVerticalLine(Line_t* verLine, const Line_t* oriLine, const Point_t* point); + double getOffset(const Line_t* line, const Point_t* point); + bool getIsOnSameSide(const Line_t* line, const Point_t* point0, const Point_t* point1); + bool getIsPointInLine(const Line_t* line, const Point_t* point); + + void dumpLine(const char* name, const Line_t* line); + void dumpPoint(const char* name, const Point_t* point); + void outputPoint(const Point_t* point); + double invSqrt(double num); +}; + +#endif diff --git a/x_track/src/App/Utils/TrackView/TrackView.cpp b/x_track/src/App/Utils/TrackView/TrackView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b9865eaa47557ad38252249396ba2dfe3a0d640 --- /dev/null +++ b/x_track/src/App/Utils/TrackView/TrackView.cpp @@ -0,0 +1,203 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "TrackView.h" +#include "Utils/PointContainer/PointContainer.h" +#include "Utils/lv_poly_line/lv_poly_line.h" + +TrackView::TrackView(lv_obj_t* parent) + : _cont(nullptr) + , _trackLine(nullptr) + , _activeLine(nullptr) + , _activePoint { 0 } + , _pointContainer(nullptr) + , _refLevel(0) + , _curLevel(0) + , _pointFilter(onPointFilterEvent, &_lineFilter) + , _lineFilter(onLineFilterEvent, this) +{ + _cont = lv_obj_create(parent); + lv_obj_remove_style_all(_cont); + lv_obj_clear_flag(_cont, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_clear_flag(_cont, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_flag(_cont, LV_OBJ_FLAG_IGNORE_LAYOUT); + lv_obj_add_flag(_cont, LV_OBJ_FLAG_HIDDEN); + + _trackLine = new lv_poly_line(_cont); + _activeLine = lv_line_create(_cont); + lv_obj_add_flag(_activeLine, LV_OBJ_FLAG_HIDDEN); + + _pointFilter.setSecondFilterModeEnable(true); +} + +TrackView::~TrackView() +{ + delete _trackLine; + lv_obj_del(_cont); +} + +void TrackView::setStyle(lv_style_t* style) +{ + _trackLine->set_style(style); + lv_obj_add_style(_activeLine, style, 0); + // lv_obj_set_style_line_color(_activeLine, lv_palette_main(LV_PALETTE_BLUE), 0); +} + +void TrackView::setArea(int32_t x0, int32_t y0, int32_t x1, int32_t y1) +{ + lv_obj_set_size(_cont, x1 - x0 + 1, y1 - y0 + 1); + + TrackLineFilter::Area_t area = { x0, y0, x1, y1 }; + _lineFilter.setArea(&area); +} + +void TrackView::setActivePoint(int32_t x, int32_t y) +{ + if (!_pointContainer) { + return; + } + + lv_point_precise_t end; + if (!_trackLine->get_end_point(&end)) { + lv_obj_add_flag(_activeLine, LV_OBJ_FLAG_HIDDEN); + return; + } + + const TrackLineFilter::Area_t* area = _lineFilter.getArea(); + + TrackLineFilter::Point_t relEndPoint = { area->x0 + (int32_t)end.x, area->y0 + (int32_t)end.y }; + auto relActivePoint = convertPoint(x, y, _refLevel, _curLevel); + + if (!_lineFilter.getIsPointInArea(&relEndPoint) + && !_lineFilter.getIsPointInArea((TrackLineFilter::Point_t*)&relActivePoint)) { + lv_obj_add_flag(_activeLine, LV_OBJ_FLAG_HIDDEN); + LV_LOG_INFO("Point out of area"); + return; + } + + auto offset = getOffset(relActivePoint.x, relActivePoint.y); + _activePoint[0].x = end.x; + _activePoint[0].y = end.y; + _activePoint[1].x = offset.x; + _activePoint[1].y = offset.y; + + lv_line_set_points(_activeLine, _activePoint, 2); + lv_obj_clear_flag(_activeLine, LV_OBJ_FLAG_HIDDEN); +} + +void TrackView::pushPoint(int32_t x, int32_t y) +{ + if (!_pointContainer) { + return; + } + + auto point = convertPoint(x, y, _refLevel, _curLevel); + _pointFilter.pushPoint(point.x, point.y); +} + +void TrackView::setLevel(int level) +{ + if (level == _curLevel) { + return; + } + + _curLevel = level; +} + +void TrackView::setPointContainer(PointContainer* pointCont, int refLevel) +{ + _pointContainer = pointCont; + _refLevel = refLevel; +} + +bool TrackView::reload() +{ + if (!_pointContainer) { + lv_obj_add_flag(_cont, LV_OBJ_FLAG_HIDDEN); + return false; + } + + _pointFilter.reset(); + _lineFilter.reset(); + _trackLine->reset(); + + int32_t x, y; + _pointContainer->popStart(); + while (_pointContainer->popPoint(&x, &y)) { + pushPoint(x, y); + } + + lv_obj_add_flag(_activeLine, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(_cont, LV_OBJ_FLAG_HIDDEN); + return true; +} + +TrackView::Point_t TrackView::convertPoint(int32_t srcX, int32_t srcY, int srcLevel, int destLevel) +{ + Point_t point; + + int diff = srcLevel - destLevel; + + if (diff == 0) { + return { srcX, srcY }; + } + + if (diff > 0) { + point.x = srcX >> diff; + point.y = srcY >> diff; + } else { + point.x = srcX << -diff; + point.y = srcY << -diff; + } + + return point; +} + +TrackView::Point_t TrackView::getOffset(int32_t x, int32_t y) +{ + const TrackLineFilter::Area_t* area = _lineFilter.getArea(); + return { x - area->x0, y - area->y0 }; +} + +void TrackView::onPointFilterEvent(TrackPointFilter* filter, const TrackPointFilter::Point_t* point) +{ + auto lineFilter = (TrackLineFilter*)filter->getUserData(); + lineFilter->pushPoint(point->x, point->y); +} + +void TrackView::onLineFilterEvent(TrackLineFilter* filter, const TrackLineFilter::Event_t* event) +{ + auto self = (TrackView*)filter->getUserData(); + + switch (event->eventID) { + case TrackLineFilter::EVENT_ID::START_LINE: + self->_trackLine->start(); + break; + case TrackLineFilter::EVENT_ID::APPEND_POINT: { + Point_t offset = self->getOffset(event->point->x, event->point->y); + self->_trackLine->append(offset.x, offset.y); + } break; + default: + break; + } +} diff --git a/x_track/src/App/Utils/TrackView/TrackView.h b/x_track/src/App/Utils/TrackView/TrackView.h new file mode 100644 index 0000000000000000000000000000000000000000..a24812ab0bae55dcadc63e71cab7c0caeff9d66e --- /dev/null +++ b/x_track/src/App/Utils/TrackView/TrackView.h @@ -0,0 +1,75 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __TRACK_VIEW_H +#define __TRACK_VIEW_H + +#include "Utils/TrackLineFilter/TrackLineFilter.h" +#include "Utils/TrackPointFilter/TrackPointFilter.h" +#include "lvgl/lvgl.h" + +class PointContainer; +class lv_poly_line; + +class TrackView { +public: + TrackView(lv_obj_t* parent); + ~TrackView(); + + void setStyle(lv_style_t* style); + void setArea(int32_t x0, int32_t y0, int32_t x1, int32_t y1); + void setActivePoint(int32_t x, int32_t y); + void pushPoint(int32_t x, int32_t y); + void setLevel(int level); + void setPointContainer(PointContainer* pointCont, int refLevel); + bool reload(); + lv_obj_t* getViewCont() { return _cont; } + int getLevel() { return _curLevel; } + int getRefLevel() { return _refLevel; } + +private: + typedef struct + { + int32_t x; + int32_t y; + } Point_t; + +private: + lv_obj_t* _cont; + lv_poly_line* _trackLine; + lv_obj_t* _activeLine; + lv_point_precise_t _activePoint[2]; + PointContainer* _pointContainer; + int _refLevel; + int _curLevel; + + TrackPointFilter _pointFilter; + TrackLineFilter _lineFilter; + +private: + Point_t getOffset(int32_t x, int32_t y); + Point_t convertPoint(int32_t srcX, int32_t srcY, int srcLevel, int destLevel); + static void onPointFilterEvent(TrackPointFilter* filter, const TrackPointFilter::Point_t* point); + static void onLineFilterEvent(TrackLineFilter* filter, const TrackLineFilter::Event_t* event); +}; + +#endif // __TRACK_VIEW_H diff --git a/x_track/src/App/Utils/WString/WCharacter.h b/x_track/src/App/Utils/WString/WCharacter.h new file mode 100644 index 0000000000000000000000000000000000000000..fbde2265d050a01f4c4540cde0a97553e5f9d355 --- /dev/null +++ b/x_track/src/App/Utils/WString/WCharacter.h @@ -0,0 +1,172 @@ +/* + WCharacter.h - Character utility functions for Wiring & Arduino + Copyright (c) 2010 Hernando Barragan. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Character_h +#define Character_h + +#include <ctype.h> + +//#define isascii(c) ((unsigned int)c < 0x7F) +//#define toascii(c) ((unsigned char)c) +#define isblank(C) (c==' '||c=='\t') + +// WCharacter.h prototypes +inline bool isAlphaNumeric(int c); +inline bool isAlpha(int c); +inline bool isAscii(int c); +inline bool isWhitespace(int c); +inline bool isControl(int c); +inline bool isDigit(int c); +inline bool isGraph(int c); +inline bool isLowerCase(int c); +inline bool isPrintable(int c); +inline bool isPunct(int c); +inline bool isSpace(int c); +inline bool isUpperCase(int c); +inline bool isHexadecimalDigit(int c); +inline int toAscii(int c); +inline int toLowerCase(int c); +inline int toUpperCase(int c); + + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline bool isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline bool isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline bool isAscii(int c) +{ + return ( isascii (c) == 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline bool isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline bool isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline bool isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline bool isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline bool isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline bool isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline bool isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline bool isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline bool isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline bool isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ + return toascii (c); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#endif diff --git a/x_track/src/App/Utils/WString/WString.cpp b/x_track/src/App/Utils/WString/WString.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c97bf880c1fa87c92b3ef618e3738368efb06b5 --- /dev/null +++ b/x_track/src/App/Utils/WString/WString.cpp @@ -0,0 +1,823 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" + +#define WS_USE_STD_LIB 0 + +#if WS_USE_STD_LIB +# define WS_MEM_REALLOC(ptr, new_size) realloc(ptr, new_size) +# define WS_MEM_FREE(ptr) free(ptr) +#else +#include "lvgl/lvgl.h" +# define WS_MEM_REALLOC(ptr, new_size) lv_realloc(ptr, new_size) +# define WS_MEM_FREE(ptr) lv_free(ptr) +#endif + +#ifdef WIN32 +# define ultoa _ultoa_s +# define ltoa _ltoa_s +# define itoa _itoa_s +#else +# include "itoa.h" +#endif + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + WS_MEM_FREE(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) WS_MEM_FREE(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) + { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)WS_MEM_REALLOC(buffer, maxStrLen + 1); + if (newbuffer) + { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) + { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) + { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, (PGM_P)pstr);//strcpy_P + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) +{ + if (buffer) + { + if (rhs && capacity >= rhs.len) + { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } + else + { + WS_MEM_FREE(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen((PGM_P)pstr));//strlen_P + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast<StringSumHelper&>(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) + { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) + { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) + { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) + { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) + { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) + { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) + { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) + { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) + { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } + else if (diff < 0) + { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) + { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } + else + { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) + { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) + { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index) +{ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int) -1); +} + +void String::remove(unsigned int index, unsigned int count) +{ + if (index >= len || count == 0) + { + return; + } + if (count > len - index) + { + count = len - index; + } + char *writeTo = buffer + index; + memmove(writeTo, buffer + index + count, len - index - count); + len -= count; + buffer[len] = '\0'; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) + { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) + { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + if (buffer) return float(atof(buffer)); + return 0; +} + +extern "C" { +#include <stdio.h> +#include <stdarg.h> +} + +#ifdef SUPPORTS_WSTRING_SPRINTF + +#define SPRINTF_BUFFER_LENGTH 100 + +// Work in progress to support printf. +// Need to implement stream FILE to write individual chars to chosen serial port +int String::sprintf (const char *__restrict __format, ...) +{ + char printf_buff[SPRINTF_BUFFER_LENGTH]; + + va_list args; + va_start(args, __format); + int ret_status = vsnprintf(printf_buff, sizeof(printf_buff), __format, args); + va_end(args); + copy(printf_buff, strlen(printf_buff)); + + return ret_status; +} + +#endif diff --git a/x_track/src/App/Utils/WString/WString.h b/x_track/src/App/Utils/WString/WString.h new file mode 100644 index 0000000000000000000000000000000000000000..e01bd0e0c6b1bc9480e8c65ca72818dc0741b689 --- /dev/null +++ b/x_track/src/App/Utils/WString/WString.h @@ -0,0 +1,302 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus +extern "C"{ +#include "dtostrf.h" +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +} + +#define SUPPORTS_WSTRING_SPRINTF + +//#include <pgmspace.h> + +#define PGM_P const char * + +#define PGM_VOID_P const void * + +//#define PSTR(s) ((const PROGMEM char *)(s)) + + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); +#endif + explicit String(char c); + explicit String(unsigned char, unsigned char base = 10); + explicit String(int, unsigned char base = 10); + explicit String(unsigned int, unsigned char base = 10); + explicit String(long, unsigned char base = 10); + explicit String(unsigned long, unsigned char base = 10); + explicit String(float, unsigned char decimalPlaces = 2); + explicit String(double, unsigned char decimalPlaces = 2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const { + return len; + } + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); +#endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) { + concat(rhs); + return (*this); + } + String & operator += (const char *cstr) { + concat(cstr); + return (*this); + } + String & operator += (char c) { + concat(c); + return (*this); + } + String & operator += (unsigned char num) { + concat(num); + return (*this); + } + String & operator += (int num) { + concat(num); + return (*this); + } + String & operator += (unsigned int num) { + concat(num); + return (*this); + } + String & operator += (long num) { + concat(num); + return (*this); + } + String & operator += (unsigned long num) { + concat(num); + return (*this); + } + String & operator += (float num) { + concat(num); + return (*this); + } + String & operator += (double num) { + concat(num); + return (*this); + } + String & operator += (const __FlashStringHelper *str) { + concat(str); + return (*this); + } + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { + return buffer ? &String::StringIfHelper : 0; + } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const { + return equals(rhs); + } + unsigned char operator == (const char *cstr) const { + return equals(cstr); + } + unsigned char operator != (const String &rhs) const { + return !equals(rhs); + } + unsigned char operator != (const char *cstr) const { + return !equals(cstr); + } + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const + { + getBytes((unsigned char *)buf, bufsize, index); + } + const char * c_str() const { + return buffer; + } + char* begin() { + return buffer; + } + char* end() { + return buffer + length(); + } + const char* begin() const { + return c_str(); + } + const char* end() const { + return c_str() + length(); + } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { + return substring(beginIndex, len); + }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + + //sprintf support + int sprintf(const char *__restrict __format, ...); + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); +#endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/x_track/src/App/Utils/WString/dtostrf.c b/x_track/src/App/Utils/WString/dtostrf.c new file mode 100644 index 0000000000000000000000000000000000000000..7625ac0c7d48e30a66e01f0cdec86d2d6e64c5f6 --- /dev/null +++ b/x_track/src/App/Utils/WString/dtostrf.c @@ -0,0 +1,29 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie <c.maglie@bug.st> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "dtostrf.h" + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { + char fmt[20]; + sprintf(fmt, "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout; +} + diff --git a/x_track/src/App/Utils/WString/dtostrf.h b/x_track/src/App/Utils/WString/dtostrf.h new file mode 100644 index 0000000000000000000000000000000000000000..ea8972aa4888098b8909f4df4e915244b5145b81 --- /dev/null +++ b/x_track/src/App/Utils/WString/dtostrf.h @@ -0,0 +1,34 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2013 Arduino. All rights reserved. + Written by Cristian Maglie <c.maglie@bug.st> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef __DTOSTRF_H +#define __DTOSTRF_H +#include "stdio.h" +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/x_track/src/App/Utils/WString/itoa.c b/x_track/src/App/Utils/WString/itoa.c new file mode 100755 index 0000000000000000000000000000000000000000..842a977143379ec787179516351695750c72929c --- /dev/null +++ b/x_track/src/App/Utils/WString/itoa.c @@ -0,0 +1,121 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "itoa.h" + +#ifndef NULL +#define NULL ((void*)0) +#endif + +char *itoa(int value, char *string, int radix) +{ + return ltoa(value, string, radix) ; +} + +char *ltoa(long value, char *string, int radix) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v; + int sign; + char *sp; + + if (string == NULL) + { + return 0 ; + } + + if (radix > 36 || radix <= 1) + { + return 0 ; + } + + sign = (radix == 10 && value < 0); + if (sign) + { + v = -value; + } + else + { + v = (unsigned long)value; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i + '0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + if (sign) + *sp++ = '-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} + +char *utoa(unsigned int value, char *string, int radix) +{ + return ultoa( value, string, radix ) ; +} + +char *ultoa(unsigned long value, char *string, int radix) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if (string == NULL) + { + return 0; + } + + if (radix > 36 || radix <= 1) + { + return 0; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i + '0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} diff --git a/x_track/src/App/Utils/WString/itoa.h b/x_track/src/App/Utils/WString/itoa.h new file mode 100755 index 0000000000000000000000000000000000000000..2e606c030b4dcc14db972138c08bfc862276e470 --- /dev/null +++ b/x_track/src/App/Utils/WString/itoa.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _ITOA_ +#define _ITOA_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +char *itoa(int value, char *string, int radix); +char *ltoa(long value, char *string, int radix); +char *utoa(unsigned int value, char *string, int radix); +char *ultoa(unsigned long value, char *string, int radix); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _ITOA_ diff --git a/x_track/src/App/Utils/easing/easing.c b/x_track/src/App/Utils/easing/easing.c new file mode 100644 index 0000000000000000000000000000000000000000..ea99ac135aaaa28029ba4770666ff5cb6fffe425 --- /dev/null +++ b/x_track/src/App/Utils/easing/easing.c @@ -0,0 +1,331 @@ +/** + * @file easing.c + * @author uYanki (https://github.com/uYanki) + * @brief https://github.com/uYanki/board-stm32f103rc-berial/blob/main/7.Example/HAL/19.GUI/03%20u8g2/02%20menu/Lib/easing/easing.c + * @version 0.1 + * @date 2023-01-15 + * + * @copyright Copyright (c) 2023 + * + */ + +#include "easing.h" +#include <string.h> + +#define PI 3.1415926f + +static easing_tick_cb_t g_easing_tick_cb = 0; + +#define easing_mills() g_easing_tick_cb() + +static const float DH = 1.0f / 22.0f; +static const float D1 = 1.0f / 11.0f; +static const float D2 = 2.0f / 11.0f; +static const float D3 = 3.0f / 11.0f; +// static const float D4 = 4.0f / 11.0f; +static const float D5 = 5.0f / 11.0f; +static const float D7 = 7.0f / 11.0f; +static const float IH = 1.0f / (1.0f / 22.0f); +static const float I1 = 1.0f / (1.0f / 11.0f); +static const float I2 = 1.0f / (2.0f / 11.0f); +static const float I4D = 1.0f / (4.0f / 11.0f) / (4.0f / 11.0f); +// static const float IH = 1.0f / DH; +// static const float I1 = 1.0f / D1; +// static const float I2 = 1.0f / D2; +// static const float I4D = 1.0f / D4 / D4; + +float _easing_calc_InBounce(const float t) +{ + float s; + if (t < D1) { + s = t - DH; + s = DH - s * s * IH; + } else if (t < D3) { + s = t - D2; + s = D1 - s * s * I1; + } else if (t < D7) { + s = t - D5; + s = D2 - s * s * I2; + } else { + s = t - 1; + s = 1 - s * s * I4D; + } + return s; +} + +float _easing_calc_OutBounce(const float t) +{ + return 1.0f - _easing_calc_InBounce(1.0f - t); +} + +float _easing_calc_InOutBounce(const float t) +{ + return (t < 0.5f) ? _easing_calc_InBounce(t * 2.0f) * 0.5f : 1 - _easing_calc_InBounce(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InCirc(const float t) +{ + return 1.0f - sqrtf(1.0f - t * t); +} + +float _easing_calc_OutCirc(const float t) +{ + return 1.0f - _easing_calc_InCirc(1.0f - t); +} + +float _easing_calc_InOutCirc(const float t) +{ + return (t < 0.5f) ? _easing_calc_InCirc(t * 2.0f) * 0.5f : 1 - _easing_calc_InCirc(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InCubic(const float t) +{ + return t * t * t; +} + +float _easing_calc_OutCubic(const float t) +{ + return 1.0f - _easing_calc_InCubic(1.0f - t); +} + +float _easing_calc_InOutCubic(const float t) +{ + return (t < 0.5f) ? _easing_calc_InCubic(t * 2.0f) * 0.5f : 1 - _easing_calc_InCubic(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_OutElastic(const float t) +{ + float s = 1 - t; + return 1 - powf(s, 8) + sinf(t * t * 6 * PI) * s * s; +} + +float _easing_calc_InElastic(const float t) +{ + return 1.0f - _easing_calc_OutElastic(1.0f - t); +} + +float _easing_calc_InOutElastic(const float t) +{ + return (t < 0.5f) ? _easing_calc_InElastic(t * 2.0f) * 0.5f : 1 - _easing_calc_InElastic(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InExpo(const float t) +{ + return powf(2, 10 * (t - 1)); +} + +float _easing_calc_OutExpo(const float t) +{ + return 1.0f - powf(2, -10 * t); +} + +float _easing_calc_InOutExpo(const float t) +{ + return (t < 0.5f) ? _easing_calc_InExpo(t * 2.0f) * 0.5f : 1 - _easing_calc_InExpo(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_Linear(const float t) +{ + return t; +} + +float _easing_calc_InQuad(const float t) +{ + return t * t; +} + +float _easing_calc_OutQuad(const float t) +{ + return 1.0f - _easing_calc_InQuad(1.0f - t); +} + +float _easing_calc_InOutQuad(const float t) +{ + return (t < 0.5f) ? _easing_calc_InQuad(t * 2.0f) * 0.5f : 1 - _easing_calc_InQuad(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InQuart(const float t) +{ + return t * t * t * t; +} + +float _easing_calc_OutQuart(const float t) +{ + return 1.0f - _easing_calc_InQuart(1.0f - t); +} + +float _easing_calc_InOutQuart(const float t) +{ + return (t < 0.5f) ? _easing_calc_InQuart(t * 2.0f) * 0.5f : 1 - _easing_calc_InQuart(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InQuint(const float t) +{ + return t * t * t * t * t; +} + +float _easing_calc_OutQuint(const float t) +{ + return 1.0f - _easing_calc_InQuint(1.0f - t); +} + +float _easing_calc_InOutQuint(const float t) +{ + return (t < 0.5f) ? _easing_calc_InQuint(t * 2.0f) * 0.5f : 1 - _easing_calc_InQuint(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InSine(const float t) +{ + return 1.0f - cosf(t * (PI / 2)); +} + +float _easing_calc_OutSine(const float t) +{ + return 1.0f - _easing_calc_InSine(1.0f - t); +} + +float _easing_calc_InOutSine(const float t) +{ + return (t < 0.5f) ? _easing_calc_InSine(t * 2.0f) * 0.5f : 1 - _easing_calc_InSine(2.0f - t * 2.0f) * 0.5f; +} + +float _easing_calc_InBack(const float t) +{ + return 3 * t * t * t - 2 * t * t; +} + +float _easing_calc_OutBack(const float t) +{ + return 1.0f - _easing_calc_InBack(1.0f - t); +} + +float _easing_calc_InOutBack(const float t) +{ + return (t < 0.5f) ? _easing_calc_InBack(t * 2.0f) * 0.5f : 1 - _easing_calc_InBack(2.0f - t * 2.0f) * 0.5f; +} + +//////////////////////////////////////////////////////////////////////////////////// + +void easing_set_tick_callback(easing_tick_cb_t tick_cb) +{ + g_easing_tick_cb = tick_cb; +} + +void easing_init( + easing_t* pEasing, + easing_mode_t dwMode, + easing_calc_t lpfnCalc, + easing_pos_t nOffset, + uint16_t nFrameCount, + uint16_t nInterval) +{ + memset(pEasing, 0, sizeof(easing_t)); + pEasing->dwMode = dwMode; + pEasing->lpfnCalc = lpfnCalc == 0 ? _easing_calc_Linear : lpfnCalc; + pEasing->nOffset = nOffset; + pEasing->nFrameCount = (nFrameCount < 2) ? 2 : nFrameCount; + pEasing->nInterval = nInterval; + pEasing->bDirection = dwMode & EASING_DIR_REVERSE; +} + +void easing_start_absolute( + easing_t* pEasing, + easing_pos_t nStart, + easing_pos_t nStop) +{ + pEasing->nStart = nStart; + pEasing->nStop = nStop; + pEasing->nDelta = nStop - nStart; + + pEasing->nFrameIndex = 0; // first frame is nStart + pEasing->fProgress = 0.0f; + + pEasing->bDirection = pEasing->dwMode & EASING_DIR_REVERSE; + + if (pEasing->dwMode & EASING_TIMES_INFINITE) { + pEasing->nTimes = -1; + } else { + pEasing->nTimes = (pEasing->dwMode & EASING_TIMES_MANYTIMES) ? (pEasing->dwMode >> EASING_TIMES_SET) : 1; + if (pEasing->dwMode & EASING_DIR_BACKANDFORTH) + pEasing->nTimes *= 2; + } + +#ifdef easing_mills + pEasing->nMills = easing_mills(); +#endif +} + +void easing_start_relative( + easing_t* pEasing, + easing_pos_t nDistance) +{ + easing_start_absolute( + pEasing, +#if 1 + pEasing->nCurrent, // from current pos +#else + easing->nStop, // from stop pos +#endif + pEasing->nStop + nDistance); +} + +void easing_update(easing_t* pEasing) +{ + // isok + if (pEasing->nTimes == 0) + return; + +#ifdef easing_mills + if (pEasing->nInterval > 0) { + if (easing_mills() < pEasing->nMills) + return; + pEasing->nMills = easing_mills() + pEasing->nInterval; + } +#endif + + // next frame + ++pEasing->nFrameIndex; + + if (pEasing->nFrameIndex > pEasing->nFrameCount) { + if (pEasing->dwMode & EASING_DIR_BACKANDFORTH) { + // reverse direction + pEasing->bDirection = !pEasing->bDirection; + // skip once nStart/nStop pos + pEasing->nFrameIndex = 2; + } else { + // at first frame + pEasing->nFrameIndex = 1; + } + } + + if (pEasing->nFrameIndex == pEasing->nFrameCount) { + // at last frame + pEasing->fProgress = 1.0f; + pEasing->nCurrent = pEasing->bDirection ? pEasing->nStart : pEasing->nStop; + // decrease times + if (!(pEasing->dwMode & EASING_TIMES_INFINITE)) + if (--pEasing->nTimes) + return; + } else { + // calculate progress + pEasing->fProgress = (float)(pEasing->nFrameIndex - 1) / (pEasing->nFrameCount - 1); + // calculate position + pEasing->nCurrent = pEasing->bDirection ? (pEasing->nStop - pEasing->nDelta * pEasing->lpfnCalc(pEasing->fProgress)) : (pEasing->nStart + pEasing->nDelta * pEasing->lpfnCalc(pEasing->fProgress)); + } +} + +bool easing_isok(easing_t* pEasing) +{ + return pEasing->nTimes == 0; +} + +void easing_stop(easing_t* pEasing, easing_pos_t nCurrent) +{ + pEasing->nTimes = 0; + pEasing->nCurrent = nCurrent; +} + +easing_pos_t easing_curpos(easing_t* pEasing) +{ + return pEasing->nCurrent + pEasing->nOffset; +} diff --git a/x_track/src/App/Utils/easing/easing.h b/x_track/src/App/Utils/easing/easing.h new file mode 100644 index 0000000000000000000000000000000000000000..6771be5a0af0af254c5876e328c067f492101821 --- /dev/null +++ b/x_track/src/App/Utils/easing/easing.h @@ -0,0 +1,156 @@ +/** + * @file easing.h + * @author uYanki (https://github.com/uYanki) + * @brief https://github.com/uYanki/board-stm32f103rc-berial/blob/main/7.Example/HAL/19.GUI/03%20u8g2/02%20menu/Lib/easing/easing.h + * @version 0.1 + * @date 2023-01-15 + * + * @copyright Copyright (c) 2023 + * + */ + +// https://blog.csdn.net/z2014z/article/details/120691794 + +#ifndef __EASING_H__ +#define __EASING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <math.h> +#include <stdbool.h> +#include <stdint.h> + +//////////////// + +typedef float (*easing_calc_t)(const float t); +typedef uint32_t (*easing_tick_cb_t)(void); + +typedef float easing_pos_t; // data type + +typedef enum { + EASING_MODE_BITCNT = 4, + EASING_MODE_MASK = (1 << EASING_MODE_BITCNT) - 1, + + EASING_TIMES_SINGLE = 0 << 0, // 单次(default) + EASING_TIMES_MANYTIMES = 1 << 0, // 多次 + EASING_TIMES_INFINITE = 1 << 1, // 循环 + + EASING_TIMES_SET = EASING_MODE_BITCNT, + + EASING_DIR_FORWARD = 0 << 0, // 正向(default) + EASING_DIR_REVERSE = 1 << 2, // 反向 + EASING_DIR_BACKANDFORTH = 1 << 3, // 往返 + +} easing_mode_t; + +#define EASING_MODE_DEFAULT ((easing_mode_t)(EASING_TIMES_SINGLE | EASING_DIR_FORWARD)) +#define EASING_MODE_NTIMES(n) EASING_TIMES_MANYTIMES | (n << EASING_TIMES_SET) + +#define EASING_INTERVAL_NONE 0 + +typedef struct easing { + easing_mode_t dwMode; + + // type + easing_calc_t lpfnCalc; // _easing_calc_xxx + + // position + easing_pos_t nStart; + easing_pos_t nStop; + easing_pos_t nOffset; + easing_pos_t nDelta; + easing_pos_t nCurrent; // range: [nStart, nStop] + + // progress + uint16_t nFrameCount; // range: [2,n], 1: nStart/nStop; n:nStop/nStart; + uint16_t nFrameIndex; // current frame. range: [0, nFrameCount], 0:nStart/nStop; nFrameCount:nStop/nStart; + float fProgress; // current progress. range: [0,1] + + int16_t nTimes; + bool bDirection; // true: reverse, false:forward + + uint32_t nMills; + uint16_t nInterval; // minimum time interval per frame (ms) +} easing_t; + +//////////////// _easing_calc_xxx + +float _easing_calc_Linear(const float t); // linear t + +float _easing_calc_InQuad(const float t); // quadratic t^2 +float _easing_calc_OutQuad(const float t); +float _easing_calc_InOutQuad(const float t); + +float _easing_calc_InCubic(const float t); // cubic t^3 +float _easing_calc_OutCubic(const float t); +float _easing_calc_InOutCubic(const float t); + +float _easing_calc_InQuart(const float t); // quartic t^4 +float _easing_calc_OutQuart(const float t); +float _easing_calc_InOutQuart(const float t); + +float _easing_calc_InQuint(const float t); // quintic t^5 +float _easing_calc_OutQuint(const float t); +float _easing_calc_InOutQuint(const float t); + +float _easing_calc_InSine(const float t); // sinusoidal 正弦 sin(t) +float _easing_calc_OutSine(const float t); +float _easing_calc_InOutSine(const float t); + +float _easing_calc_InExpo(const float t); // exponential 指数 2^t +float _easing_calc_OutExpo(const float t); +float _easing_calc_InOutExpo(const float t); + +float _easing_calc_InCirc(const float t); // circular 圆形 +float _easing_calc_OutCirc(const float t); +float _easing_calc_InOutCirc(const float t); + +float _easing_calc_InBack(const float t); // elastic 衰减三次幂 (s+1)t^3 - st^2 +float _easing_calc_OutBack(const float t); +float _easing_calc_InOutBack(const float t); + +float _easing_calc_InElastic(const float t); // elastic 衰减正弦 +float _easing_calc_OutElastic(const float t); +float _easing_calc_InOutElastic(const float t); + +float _easing_calc_InBounce(const float t); // back 衰减反弹 +float _easing_calc_OutBounce(const float t); +float _easing_calc_InOutBounce(const float t); + +//////////////// + +void easing_set_tick_callback(easing_tick_cb_t tick_cb); + +void easing_init( + easing_t* pEasing, + easing_mode_t dwMode, // default: EASING_TIMES_SINGLE | EASING_DIR_FORWARD + easing_calc_t lpfnCalc, // default: _easing_calc_Linear + easing_pos_t nOffset, // default: 0 + uint16_t nFrameCount, // default: 2 + uint16_t nInterval // default: EASING_INTERVAL_NONE +); + +void easing_start_absolute( + easing_t* pEasing, + easing_pos_t nStart, + easing_pos_t nStop); + +void easing_start_relative( + easing_t* pEasing, + easing_pos_t nDistance); + +// update easing position +void easing_update(easing_t* easing); + +bool easing_isok(easing_t* pEasing); +void easing_stop(easing_t* pEasing, easing_pos_t nCurrent); + +easing_pos_t easing_curpos(easing_t* pEasing); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/x_track/src/App/Utils/easing/easing_demo.c b/x_track/src/App/Utils/easing/easing_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..dfc18a6c92c14bf20ca48a768e555a2182fcd2e4 --- /dev/null +++ b/x_track/src/App/Utils/easing/easing_demo.c @@ -0,0 +1,47 @@ +/** + * @file easing_demo.c + * @author uYanki (https://github.com/uYanki) + * @brief easing demo + * @version 0.1 + * @date 2023-01-15 + * + * @copyright Copyright (c) 2023 + * + */ + +#if 0 + +#include "easing.h" +#include <stdio.h> + +void easing_demo(void) +{ +#if 0 + // easing_t e = easing_create(EASING_DIR_FORWARD | EASING_TIMES_SINGLE, _easing_calc_Linear, 10, 5, 0); + // easing_t e = easing_create(EASING_DIR_FORWARD | EASING_TIMES_MANYTIMES | (2 << EASING_TIMES_SET), _easing_calc_Linear, 0, 5, 0); + // easing_t e = easing_create(EASING_DIR_REVERSE | EASING_TIMES_MANYTIMES | (2 << EASING_TIMES_SET), _easing_calc_Linear, 0, 1, 0); + easing_t e = easing_create(EASING_DIR_BACKANDFORTH | EASING_TIMES_MANYTIMES | (2 << EASING_TIMES_SET), _easing_calc_Linear, 0, 5, 0); + easing_start_relative(&e, 10); // 0 [2.5 5 7.5] 10 + while (!easing_isok(&e)) { + easing_update(&e); + printf("%f\r\n", easing_curpos(&e)); + // printf("%f\r\n", e.nCurrent); + } +#endif + + easing_t e = easing_create(EASING_MODE_DEFAULT, _easing_calc_Linear, 0, 400, 0); + + easing_start_absolute(&e, -1.57f, 1.57f); + + char buff[32]; + FILE* f = fopen("data.csv", "w"); + while (!easing_isok(&e)) { + easing_update(&e); + float x = easing_curpos(&e); + snprintf(buff, sizeof(buff),"%f\n", x); + fputs(buff, f); + } + fclose(f); +} + +#endif diff --git a/x_track/src/App/Utils/easing/type.png b/x_track/src/App/Utils/easing/type.png new file mode 100755 index 0000000000000000000000000000000000000000..dee6870a785902448cf9e9254eff6abc23bc7ca6 Binary files /dev/null and b/x_track/src/App/Utils/easing/type.png differ diff --git a/x_track/src/App/Utils/lv_anim_label/lv_anim_label.c b/x_track/src/App/Utils/lv_anim_label/lv_anim_label.c new file mode 100644 index 0000000000000000000000000000000000000000..1fe04fcec58009eb473a491f785a724a20f193ad --- /dev/null +++ b/x_track/src/App/Utils/lv_anim_label/lv_anim_label.c @@ -0,0 +1,368 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "lv_anim_label.h" + +/********************* + * DEFINES + *********************/ +#define MY_CLASS &lv_anim_label_class + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_anim_label_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_anim_label_set_x(void* obj, int32_t x); +static void lv_anim_label_set_y(void* obj, int32_t y); + +/********************** + * STATIC VARIABLES + **********************/ +const lv_obj_class_t lv_anim_label_class = +{ + .constructor_cb = lv_anim_label_constructor, + .instance_size = sizeof(lv_anim_label_t), + .base_class = &lv_obj_class +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_anim_label_create(lv_obj_t * parent) +{ + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); + return obj; +} + +void lv_anim_label_set_dir(lv_obj_t * obj, lv_dir_t dir) +{ + lv_anim_label_set_enter_dir(obj, dir); + lv_anim_label_set_exit_dir(obj, dir); +} + +void lv_anim_label_set_enter_dir(lv_obj_t * obj, lv_dir_t dir) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + alabel->enter_dir = dir; +} + +void lv_anim_label_set_exit_dir(lv_obj_t * obj, lv_dir_t dir) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + alabel->exit_dir = dir; +} + +void lv_anim_label_set_time(lv_obj_t * obj, uint32_t duration) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + alabel->duration = duration; +} + +void lv_anim_label_set_path(lv_obj_t * obj, lv_anim_path_cb_t path_cb) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + alabel->path_cb = path_cb; +} + +void lv_anim_label_add_style(lv_obj_t * obj, lv_style_t * style) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + lv_obj_add_style(alabel->label_1, style, LV_PART_MAIN); + lv_obj_add_style(alabel->label_2, style, LV_PART_MAIN); +} + +void lv_anim_label_set_custom_enter_anim(lv_obj_t * obj, const lv_anim_t * a) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + if (a != NULL) + { + alabel->a_enter = *a; + } +} + +void lv_anim_label_set_custom_exit_anim(lv_obj_t * obj, const lv_anim_t * a) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + if (a != NULL) + { + alabel->a_exit = *a; + } +} + +static void lv_anim_label_start_anim( + lv_obj_t * label, + lv_dir_t dir, + int32_t start, + int32_t end, + uint32_t duration, + lv_anim_path_cb_t path_cb +) +{ + lv_anim_exec_xcb_t exec_xcb; + + if (dir & LV_DIR_HOR) + { + exec_xcb = lv_anim_label_set_x; + } + else if (dir & LV_DIR_VER) + { + exec_xcb = lv_anim_label_set_y; + } + else + { + return; + } + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, label); + lv_anim_set_values(&a, start, end); + lv_anim_set_time(&a, duration); + lv_anim_set_path_cb(&a, path_cb); + lv_anim_set_exec_cb(&a, exec_xcb); + lv_anim_start(&a); +} + +void lv_anim_label_push_text(lv_obj_t * obj, const char * txt) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + lv_obj_t * label_exit = alabel->label_act; + lv_obj_t * label_enter = alabel->label_act == alabel->label_1 ? alabel->label_2 : alabel->label_1; + lv_dir_t enter_dir = alabel->enter_dir; + lv_dir_t exit_dir = alabel->exit_dir; + + lv_label_set_text(label_enter, txt); + lv_obj_update_layout(label_enter); + + lv_coord_t obj_width = lv_obj_get_width(obj); + lv_coord_t obj_height = lv_obj_get_height(obj); + + /* enter */ + lv_coord_t label_enter_width = lv_obj_get_width(label_enter); + lv_coord_t label_enter_height = lv_obj_get_height(label_enter); + lv_coord_t label_enter_end_x = (obj_width - label_enter_width) / 2; + lv_coord_t label_enter_end_y = (obj_height - label_enter_height) / 2; + + if (enter_dir & LV_DIR_HOR) + { + lv_obj_set_y(label_enter, label_enter_end_y); + lv_coord_t start_x = label_enter_end_x; + start_x += ((enter_dir == LV_DIR_LEFT) ? -obj_width : obj_width); + lv_anim_label_start_anim( + label_enter, + enter_dir, + start_x, + label_enter_end_x, + alabel->duration, + alabel->path_cb + ); + } + else if (enter_dir & LV_DIR_VER) + { + lv_obj_set_x(label_enter, label_enter_end_x); + lv_coord_t start_y = label_enter_end_y; + start_y += ((enter_dir == LV_DIR_TOP) ? -obj_height : obj_height); + lv_anim_label_start_anim( + label_enter, + enter_dir, + start_y, + label_enter_end_y, + alabel->duration, + alabel->path_cb + ); + } + else + { + lv_obj_set_pos(label_enter, label_enter_end_x, label_enter_end_y); + } + + if (alabel->a_enter.exec_cb != NULL) + { + lv_anim_set_var(&alabel->a_enter, label_enter); + lv_anim_start(&alabel->a_enter); + } + + /* exit */ + lv_coord_t label_exit_width = lv_obj_get_width(label_exit); + lv_coord_t label_exit_height = lv_obj_get_height(label_exit); + lv_coord_t label_exit_start_x = (obj_width - label_exit_width) / 2; + lv_coord_t label_exit_start_y = (obj_height - label_exit_height) / 2; + + if (exit_dir & LV_DIR_HOR) + { + lv_obj_set_y(label_exit, label_exit_start_y); + lv_coord_t end_x = label_exit_start_x; + end_x += ((exit_dir == LV_DIR_LEFT) ? obj_width : -obj_width); + lv_anim_label_start_anim( + label_exit, + exit_dir, + label_exit_start_x, + end_x, + alabel->duration, + alabel->path_cb + ); + } + else if (exit_dir & LV_DIR_VER) + { + lv_obj_set_x(label_exit, label_exit_start_x); + lv_coord_t end_y = label_exit_start_y; + end_y += ((exit_dir == LV_DIR_TOP) ? obj_height : -obj_height); + lv_anim_label_start_anim( + label_exit, + exit_dir, + label_exit_start_y, + end_y, + alabel->duration, + alabel->path_cb + ); + } + else + { + lv_obj_set_pos(label_exit, label_exit_start_x, label_exit_start_y); + } + + if (alabel->a_exit.exec_cb != NULL) + { + lv_anim_set_var(&alabel->a_exit, label_exit); + lv_anim_start(&alabel->a_exit); + } + + alabel->label_act = label_enter; +} + +lv_dir_t lv_anim_label_get_enter_dir(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + return alabel->enter_dir; +} + +lv_dir_t lv_anim_label_get_exit_dir(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + return alabel->exit_dir; +} + +uint32_t lv_anim_label_get_time(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + return alabel->duration; +} + +lv_anim_path_cb_t lv_anim_label_get_path(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + return alabel->path_cb; +} + +const char * lv_anim_label_get_text(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + return lv_label_get_text(alabel->label_act); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_anim_label_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_TRACE_OBJ_CREATE("begin"); + + lv_anim_label_t * alabel = (lv_anim_label_t *)obj; + + alabel->label_1 = lv_label_create(obj); + lv_label_set_text(alabel->label_1, ""); + + alabel->label_2 = lv_label_create(obj); + lv_label_set_text(alabel->label_2, ""); + + alabel->label_act = alabel->label_1; + //alabel->dir = LV_DIR_BOTTOM; + alabel->duration = 500; + alabel->path_cb = lv_anim_path_ease_out; + + lv_anim_init(&alabel->a_enter); + lv_anim_init(&alabel->a_exit); + + LV_TRACE_OBJ_CREATE("finished"); +} + +static void lv_anim_label_set_x(void * obj, int32_t x) +{ + lv_obj_set_x(obj, x); +} + +static void lv_anim_label_set_y(void * obj, int32_t y) +{ + lv_obj_set_y(obj, y); +} diff --git a/x_track/src/App/Utils/lv_anim_label/lv_anim_label.h b/x_track/src/App/Utils/lv_anim_label/lv_anim_label.h new file mode 100644 index 0000000000000000000000000000000000000000..0fbe668ede4982e2c212afe31997746b3204515f --- /dev/null +++ b/x_track/src/App/Utils/lv_anim_label/lv_anim_label.h @@ -0,0 +1,68 @@ +/** + * @file lv_anim_label.h + * + */ + +#ifndef LV_ANIM_LABEL_H +#define LV_ANIM_LABEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" +#include "lvgl/src/lvgl_private.h" + +typedef struct { + lv_obj_t obj; + lv_obj_t * label_1; + lv_obj_t * label_2; + lv_obj_t * label_act; + lv_dir_t enter_dir; + lv_dir_t exit_dir; + lv_anim_t a_enter; + lv_anim_t a_exit; + uint32_t duration; + lv_anim_path_cb_t path_cb; +}lv_anim_label_t; + +extern const lv_obj_class_t lv_anim_label_class; + +lv_obj_t * lv_anim_label_create(lv_obj_t * parent); + +void lv_anim_label_set_dir(lv_obj_t * obj, lv_dir_t dir); + +void lv_anim_label_set_enter_dir(lv_obj_t * obj, lv_dir_t dir); + +void lv_anim_label_set_exit_dir(lv_obj_t * obj, lv_dir_t dir); + +void lv_anim_label_set_time(lv_obj_t * obj, uint32_t duration); + +void lv_anim_label_set_path(lv_obj_t * obj, lv_anim_path_cb_t path_cb); + +void lv_anim_label_add_style(lv_obj_t * obj, lv_style_t * style); + +void lv_anim_label_set_custom_enter_anim(lv_obj_t * obj, const lv_anim_t * a); + +void lv_anim_label_set_custom_exit_anim(lv_obj_t * obj, const lv_anim_t * a); + +void lv_anim_label_push_text(lv_obj_t * obj, const char* txt); + +lv_dir_t lv_anim_label_get_enter_dir(lv_obj_t * obj); + +lv_dir_t lv_anim_label_get_exit_dir(lv_obj_t * obj); + +uint32_t lv_anim_label_get_time(lv_obj_t * obj); + +lv_anim_path_cb_t lv_anim_label_get_path(lv_obj_t * obj); + +const char * lv_anim_label_get_text(lv_obj_t * obj); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_LABEL_H*/ diff --git a/x_track/src/App/Utils/lv_ext/lv_anim_timeline_wrapper.c b/x_track/src/App/Utils/lv_ext/lv_anim_timeline_wrapper.c new file mode 100644 index 0000000000000000000000000000000000000000..2be8cec7d195f76d26c69d385e3eebd49efda1c0 --- /dev/null +++ b/x_track/src/App/Utils/lv_ext/lv_anim_timeline_wrapper.c @@ -0,0 +1,20 @@ +#include "lv_anim_timeline_wrapper.h" + +void lv_anim_timeline_add_wrapper(lv_anim_timeline_t* at, const lv_anim_timeline_wrapper_t* wrapper) +{ + for(uint32_t i = 0; wrapper[i].obj != NULL; i++) + { + const lv_anim_timeline_wrapper_t* atw = &wrapper[i]; + + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, atw->obj); + lv_anim_set_values(&a, atw->start, atw->end); + lv_anim_set_exec_cb(&a, atw->exec_cb); + lv_anim_set_time(&a, atw->duration); + lv_anim_set_path_cb(&a, atw->path_cb); + lv_anim_set_early_apply(&a, atw->early_apply); + + lv_anim_timeline_add(at, atw->start_time, &a); + } +} diff --git a/x_track/src/App/Utils/lv_ext/lv_anim_timeline_wrapper.h b/x_track/src/App/Utils/lv_ext/lv_anim_timeline_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..e80fa2f0bc642bd1703999148c774f46b2d63f8a --- /dev/null +++ b/x_track/src/App/Utils/lv_ext/lv_anim_timeline_wrapper.h @@ -0,0 +1,38 @@ +#ifndef LV_ANIM_TIMELINE_WRAPPER_H +#define LV_ANIM_TIMELINE_WRAPPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl/lvgl.h" + +/*Data of anim_timeline*/ +typedef struct { + uint32_t start_time; + void* obj; + lv_anim_exec_xcb_t exec_cb; + int32_t start; + int32_t end; + uint16_t duration; + lv_anim_path_cb_t path_cb; + bool early_apply; +} lv_anim_timeline_wrapper_t; + +/********************** +* GLOBAL PROTOTYPES +**********************/ + +void lv_anim_timeline_add_wrapper(lv_anim_timeline_t* at, const lv_anim_timeline_wrapper_t* wrapper); + +/********************** +* MACROS +**********************/ + +#define LV_ANIM_TIMELINE_WRAPPER_END {0, NULL} + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ANIM_TIMELINE_wrapper_H*/ diff --git a/x_track/src/App/Utils/lv_ext/lv_ext_func.cpp b/x_track/src/App/Utils/lv_ext/lv_ext_func.cpp new file mode 100644 index 0000000000000000000000000000000000000000..131ed4955740c4976d2d1de0beb712fcde4712eb --- /dev/null +++ b/x_track/src/App/Utils/lv_ext/lv_ext_func.cpp @@ -0,0 +1,39 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "lv_ext_func.h" + +lv_indev_t* lv_indev_search(lv_indev_type_t type) +{ + lv_indev_t* cur_indev = NULL; + for (;;) { + cur_indev = lv_indev_get_next(cur_indev); + if (!cur_indev) { + break; + } + + if (lv_indev_get_type(cur_indev) == type) { + return cur_indev; + } + } + return NULL; +} diff --git a/x_track/src/App/Utils/lv_ext/lv_ext_func.h b/x_track/src/App/Utils/lv_ext/lv_ext_func.h new file mode 100644 index 0000000000000000000000000000000000000000..49ad4f743aeeebaaf25edbcfd102a6871891dfc1 --- /dev/null +++ b/x_track/src/App/Utils/lv_ext/lv_ext_func.h @@ -0,0 +1,32 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __LV_EXT_FUNC_H +#define __LV_EXT_FUNC_H + +#include "lvgl/lvgl.h" + +#define LV_ANIM_EXEC(attr) (lv_anim_exec_xcb_t) lv_obj_set_##attr + +lv_indev_t* lv_indev_search(lv_indev_type_t type); + +#endif /* __LV_EXT_FUNC_H */ diff --git a/x_track/src/App/Utils/lv_msg/lv_msg.c b/x_track/src/App/Utils/lv_msg/lv_msg.c new file mode 100644 index 0000000000000000000000000000000000000000..882707de3b219b33bb6a66bd4cde954f5cb783f3 --- /dev/null +++ b/x_track/src/App/Utils/lv_msg/lv_msg.c @@ -0,0 +1,221 @@ +/** + * @file lv_msg.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_msg.h" +#include "lvgl/src/lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +#define LV_GC_ROOT(x) (x) + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_msg_id_t msg_id; + lv_msg_subscribe_cb_t callback; + void * user_data; + void * _priv_data; /*Internal: used only store 'obj' in lv_obj_subscribe*/ + uint8_t _checked : 1; /*Internal: used to prevent multiple notifications*/ +} sub_dsc_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void notify(lv_msg_t * m); +static void obj_notify_cb(lv_msg_t * m); +static void obj_delete_event_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ +static bool restart_notify; +static lv_ll_t _subs_ll; + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#define MSG_TRACE(...) LV_LOG_TRACE(__VA_ARGS__) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_msg_init(void) +{ + _lv_ll_init(&LV_GC_ROOT(_subs_ll), sizeof(sub_dsc_t)); +} + +void * lv_msg_subscribe(lv_msg_id_t msg_id, lv_msg_subscribe_cb_t cb, void * user_data) +{ + sub_dsc_t * s = _lv_ll_ins_tail(&LV_GC_ROOT(_subs_ll)); + LV_ASSERT_MALLOC(s); + if(s == NULL) return NULL; + + lv_memzero(s, sizeof(*s)); + + s->msg_id = msg_id; + s->callback = cb; + s->user_data = user_data; + s->_checked = 0; /*if subsribed during `notify`, it should be notified immediately*/ + restart_notify = true; + return s; +} + +void * lv_msg_subscribe_obj(lv_msg_id_t msg_id, lv_obj_t * obj, void * user_data) +{ + sub_dsc_t * s = lv_msg_subscribe(msg_id, obj_notify_cb, user_data); + if(s == NULL) return NULL; + s->_priv_data = obj; + + /*If not added yet, add a delete_event_cb which automatically unsubcribes the object when its deleted*/ + uint32_t i; + uint32_t event_cnt = lv_obj_get_event_count(obj); + sub_dsc_t * s_first = NULL; + for(i = 0; i < event_cnt; i++) { + lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(obj, i); + if(lv_event_dsc_get_cb(event_dsc) == obj_delete_event_cb) { + s_first = lv_event_dsc_get_user_data(event_dsc); + break; + } + } + + if(s_first == NULL) { + lv_obj_add_event(obj, obj_delete_event_cb, LV_EVENT_DELETE, s); + } + + return s; +} + +void lv_msg_unsubscribe(void * s) +{ + LV_ASSERT_NULL(s); + _lv_ll_remove(&LV_GC_ROOT(_subs_ll), s); + restart_notify = true; + lv_free(s); +} + +void lv_msg_send(lv_msg_id_t msg_id, const void * payload) +{ + lv_msg_t m; + lv_memzero(&m, sizeof(m)); + m.id = msg_id; + m.payload = payload; + notify(&m); +} + +void lv_msg_update_value(void * v) +{ + lv_msg_send((lv_msg_id_t)v, v); +} + +lv_msg_id_t lv_msg_get_id(lv_msg_t * m) +{ + return m->id; +} + +const void * lv_msg_get_payload(lv_msg_t * m) +{ + return m->payload; +} + +void * lv_msg_get_user_data(lv_msg_t * m) +{ + return m->user_data; +} + +lv_msg_t * lv_event_get_msg(lv_event_t * e) +{ + if(e->code == LV_EVENT_MSG_RECEIVED) { + return lv_event_get_param(e); + } + else { + LV_LOG_WARN("Not interpreted with this event code"); + return NULL; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void notify(lv_msg_t * m) +{ + static unsigned int _recursion_counter = 0; + _recursion_counter++; + + /*First clear all _checked flags*/ + sub_dsc_t * s; + if(_recursion_counter == 1) { + _LV_LL_READ(&LV_GC_ROOT(_subs_ll), s) { + s->_checked = 0; + } + } + + /*Run all sub_dsc_t from the list*/ + do { + restart_notify = false; + s = _lv_ll_get_head(&LV_GC_ROOT(_subs_ll)); + while(s) { + /*get next element while current is surely valid*/ + sub_dsc_t * next = _lv_ll_get_next(&LV_GC_ROOT(_subs_ll), s); + + /*Notify only once*/ + if(!s->_checked) { + /*Check if this sub_dsc_t is about this msg_id*/ + if(s->msg_id == m->id && s->callback) { + // Set this flag and notify + s->_checked = 1; + m->user_data = s->user_data; + m->_priv_data = s->_priv_data; + s->callback(m); + } + } + + /*restart or load next*/ + if(restart_notify) { + MSG_TRACE("Start from the first sub_dsc_t again because _subs_ll may have changed"); + break; + } + s = next; + } + } while(s); + + _recursion_counter--; + restart_notify = (_recursion_counter > 0); +} + +static void obj_notify_cb(lv_msg_t * m) +{ + lv_obj_send_event(m->_priv_data, LV_EVENT_MSG_RECEIVED, m); +} + +static void obj_delete_event_cb(lv_event_t * e) +{ + lv_obj_t * obj = lv_event_get_target(e); + + sub_dsc_t * s = _lv_ll_get_head(&LV_GC_ROOT(_subs_ll)); + sub_dsc_t * s_next; + while(s) { + /*On unsubscribe the list changes s becomes invalid so get next item while it's surely valid*/ + s_next = _lv_ll_get_next(&LV_GC_ROOT(_subs_ll), s); + if(s->_priv_data == obj) { + lv_msg_unsubscribe(s); + } + s = s_next; + } +} diff --git a/x_track/src/App/Utils/lv_msg/lv_msg.h b/x_track/src/App/Utils/lv_msg/lv_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..43e29e34e69bdb619254e78f97b0f696d85b8e19 --- /dev/null +++ b/x_track/src/App/Utils/lv_msg/lv_msg.h @@ -0,0 +1,132 @@ +/** + * @file lv_msg.h + * + */ + +#ifndef LV_MSG_H +#define LV_MSG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" + +/********************* + * DEFINES + *********************/ + +#define LV_EVENT_MSG_RECEIVED ((lv_event_code_t)(_LV_EVENT_LAST + 32)) + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_uintptr_t lv_msg_id_t; + +typedef struct { + lv_msg_id_t id; /*Identifier of the message*/ + void * user_data; /*Set the the user_data set in `lv_msg_subscribe`*/ + void * _priv_data; /*Used internally*/ + const void * payload; /*Pointer to the data of the message*/ +} lv_msg_t; + + +typedef void (*lv_msg_subscribe_cb_t)(lv_msg_t * msg); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Called internally to initialize the message module + */ +void lv_msg_init(void); + +/** + * Subscribe to an `msg_id` + * @param msg_id the message ID to listen to + * @param cb callback to call if a message with `msg_id` was sent + * @param user_data arbitrary data which will be available in `cb` too + * @return pointer to a "subscribe object". It can be used the unsubscribe. + */ +void * lv_msg_subscribe(lv_msg_id_t msg_id, lv_msg_subscribe_cb_t cb, void * user_data); + +/** + * Subscribe an `lv_obj` to a message. + * `LV_EVENT_MSG_RECEIVED` will be triggered if a message with matching ID was sent + * @param msg_id the message ID to listen to + * @param obj pointer to an `lv_obj` + * @param user_data arbitrary data which will be available in `cb` too + * @return pointer to a "subscribe object". It can be used the unsubscribe. + */ +void * lv_msg_subscribe_obj(lv_msg_id_t msg_id, lv_obj_t * obj, void * user_data); + +/** + * Cancel a previous subscription + * @param s pointer to a "subscibe object". + * Return value of `lv_msg_subscribe` or `lv_msg_subscribe_obj` + */ +void lv_msg_unsubscribe(void * s); + +/** + * Send a message with a given ID and payload + * @param msg_id ID of the message to send + * @param payload pointer to the data to send + */ +void lv_msg_send(lv_msg_id_t msg_id, const void * payload); + +/** + * Send a message where the message ID is `v` (the value of the pointer) + * and the payload is `v`. + * It can be used to send unique messages when a variable changed. + * @param v pointer to a variable. + * @note to subscribe to a variable use `lv_msg_subscribe((lv_msg_id_t)v, msg_cb, user_data)` + * or `lv_msg_subscribe_obj((lv_msg_id_t)v, obj, user_data)` + */ +void lv_msg_update_value(void * v); + +/** + * Get the ID of a message object. Typically used in the subscriber callback. + * @param m pointer to a message object + * @return the ID of the message + */ +lv_msg_id_t lv_msg_get_id(lv_msg_t * m); + +/** + * Get the payload of a message object. Typically used in the subscriber callback. + * @param m pointer to a message object + * @return the payload of the message + */ +const void * lv_msg_get_payload(lv_msg_t * m); + +/** + * Get the user data of a message object. Typically used in the subscriber callback. + * @param m pointer to a message object + * @return the user data of the message + */ +void * lv_msg_get_user_data(lv_msg_t * m); + +/** + * Get the message object from an event object. Can be used in `LV_EVENT_MSG_RECEIVED` events. + * @param e pointer to an event object + * @return the message object or NULL if called with unrelated event code. + */ +lv_msg_t * lv_event_get_msg(lv_event_t * e); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_MSG_H*/ diff --git a/x_track/src/App/Utils/lv_poly_line/lv_poly_line.cpp b/x_track/src/App/Utils/lv_poly_line/lv_poly_line.cpp new file mode 100644 index 0000000000000000000000000000000000000000..64f25208a7ccf1dd4c00e4de518ba6e489add096 --- /dev/null +++ b/x_track/src/App/Utils/lv_poly_line/lv_poly_line.cpp @@ -0,0 +1,124 @@ +#include "lv_poly_line.h" + +lv_poly_line::lv_poly_line(lv_obj_t* par) + : current_index(0) + , styleLine(nullptr) + , parent(par) +{ +} + +lv_poly_line::~lv_poly_line() +{ + for (auto iter : poly_line) { + if (iter.line) { + lv_obj_del(iter.line); + } + + decltype(iter.points) vec; + iter.points.swap(vec); + } +} + +void lv_poly_line::add_line() +{ + lv_obj_t* line = lv_line_create(parent); + lv_obj_remove_style_all(line); + + if (styleLine) { + lv_obj_add_style(line, styleLine, 0); + } + + single_line_t single_line; + single_line.line = line; + poly_line.push_back(single_line); + + LV_LOG_INFO("line: %p", line); +} + +void lv_poly_line::start() +{ + if (current_index >= poly_line.size()) { + add_line(); + } + + LV_LOG_INFO("show poly_line[%" LV_PRId32 "]", current_index); + + single_line_t* single_line = &poly_line[current_index]; + + lv_obj_clear_flag(single_line->line, LV_OBJ_FLAG_HIDDEN); + lv_line_set_points(single_line->line, nullptr, 0); + + // const lv_palette_t palette[] = { LV_PALETTE_RED, LV_PALETTE_GREEN, LV_PALETTE_GREY }; + // lv_obj_set_style_line_color(single_line->line, lv_palette_main(palette[current_index % 3]), 0); + current_index++; +} + +void lv_poly_line::append(const lv_point_precise_t* point) +{ + if (current_index == 0) { + LV_LOG_WARN("NOT start"); + return; + } + + LV_LOG_INFO("poly_line[%" LV_PRId32 "]: (%d, %d)", current_index - 1, (int)point->x, (int)point->y); + single_line_t* single_line = &poly_line[current_index - 1]; + single_line->points.push_back(*point); + lv_line_set_points(single_line->line, get_points(single_line), single_line->points.size()); +} + +void lv_poly_line::reset() +{ + current_index = 0; + size_t size = poly_line.size(); + LV_LOG_INFO("poly_line.size() = %zu", size); + LV_LOG_INFO("reset current_index"); + + for (size_t i = 0; i < size; i++) { + single_line_t* single_line = &poly_line[i]; + lv_line_set_points(single_line->line, nullptr, 0); + single_line->points.clear(); + lv_obj_add_flag(single_line->line, LV_OBJ_FLAG_HIDDEN); + } +} + +lv_poly_line::single_line_t* lv_poly_line::get_end_line() +{ + if (current_index == 0) { + LV_LOG_INFO("NOT found"); + return nullptr; + } + + LV_LOG_INFO("end_line index = %" LV_PRId32, current_index - 1); + + return &poly_line[current_index - 1]; +} + +const lv_point_precise_t* lv_poly_line::get_points(single_line_t* single_line) +{ + const lv_point_precise_t* points = nullptr; + + if (single_line->points.size()) { + points = &single_line->points[0]; + } else { + LV_LOG_WARN("NOT found"); + } + + return points; +} + +bool lv_poly_line::get_end_point(lv_point_precise_t* point) +{ + single_line_t* single_line = get_end_line(); + if (!single_line) { + LV_LOG_INFO("end line NOT found"); + return false; + } + + if (single_line->points.size() == 0) { + LV_LOG_WARN("single_line->points is EMPTY"); + return false; + } + + *point = single_line->points.back(); + return true; +} diff --git a/x_track/src/App/Utils/lv_poly_line/lv_poly_line.h b/x_track/src/App/Utils/lv_poly_line/lv_poly_line.h new file mode 100644 index 0000000000000000000000000000000000000000..61fe9fdb5862d3f871a3e70e4c92d2a5c28f94c3 --- /dev/null +++ b/x_track/src/App/Utils/lv_poly_line/lv_poly_line.h @@ -0,0 +1,46 @@ +#ifndef LV_POLY_LINE_H +#define LV_POLY_LINE_H + +#include "lvgl/lvgl.h" +#include <vector> + +class lv_poly_line { +public: + lv_poly_line(lv_obj_t* par); + ~lv_poly_line(); + + void set_style(lv_style_t* style) + { + styleLine = style; + } + + void start(); + void append(const lv_point_precise_t* point); + void append(lv_coord_t x, lv_coord_t y) + { + lv_point_precise_t point = { (lv_value_precise_t)x, (lv_value_precise_t)y }; + append(&point); + } + void reset(); + bool get_end_point(lv_point_precise_t* point); + +private: + typedef struct + { + lv_obj_t* line; + std::vector<lv_point_precise_t> points; + } single_line_t; + +private: + void add_line(); + single_line_t* get_end_line(); + const lv_point_precise_t* get_points(single_line_t* single_line); + +private: + std::vector<single_line_t> poly_line; + uint32_t current_index; + lv_style_t* styleLine; + lv_obj_t* parent; +}; + +#endif // !LV_POLY_LINE_H diff --git a/x_track/src/App/Utils/lv_toast/lv_toast.c b/x_track/src/App/Utils/lv_toast/lv_toast.c new file mode 100644 index 0000000000000000000000000000000000000000..904960a821153d8c17299e6ae70bb1911d0ba6b6 --- /dev/null +++ b/x_track/src/App/Utils/lv_toast/lv_toast.c @@ -0,0 +1,151 @@ +/** + * @file lv_toast.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_toast.h" + +/********************* + * DEFINES + *********************/ + +#define MY_CLASS &lv_toast_class + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_toast_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj); +static void lv_toast_event(const lv_obj_class_t* class_p, lv_event_t* e); +static void lv_toast_set_height(void* var, int32_t y); +static void lv_toast_set_opa(void* var, int32_t opa); +static void lv_toast_anim_del(lv_anim_t* a); + +/********************** + * STATIC VARIABLES + **********************/ + +const lv_obj_class_t lv_toast_class = { + .base_class = &lv_obj_class, + .constructor_cb = lv_toast_constructor, + .width_def = LV_DPI_DEF / 5, + .height_def = LV_DPI_DEF / 5, + .event_cb = lv_toast_event, + .instance_size = sizeof(lv_toast_t), +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t* lv_toast_create(lv_obj_t* parent) +{ + LV_LOG_INFO("begin"); + lv_obj_t* obj = lv_obj_class_create_obj(MY_CLASS, parent); + lv_obj_class_init_obj(obj); + + lv_obj_remove_style_all(obj); + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(obj, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + lv_obj_align(obj, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_obj_set_size(obj, lv_pct(100), LV_SIZE_CONTENT); + lv_obj_set_style_anim_time(obj, 200, 0); + lv_obj_set_style_pad_all(obj, 10, 0); + + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); + + return obj; +} + +void lv_toast_show_text(lv_obj_t* obj, const char* txt, uint32_t duration) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_toast_t* toast = (lv_toast_t*)obj; + + lv_obj_t* cont = lv_obj_create(obj); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_size(cont, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF); + if (toast->style) { + lv_obj_add_style(cont, toast->style, 0); + } + + lv_obj_t* label = lv_label_create(cont); + lv_label_set_text(label, txt); + lv_obj_center(label); + + lv_obj_update_layout(cont); + lv_coord_t h = lv_obj_get_height(cont); + + uint32_t anim_time = lv_obj_get_style_anim_time(obj, 0); + + /* height anim */ + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, cont); + lv_anim_set_exec_cb(&a, lv_toast_set_height); + lv_anim_set_values(&a, 0, h); + lv_anim_set_time(&a, anim_time); + lv_anim_set_path_cb(&a, lv_anim_path_ease_out); + lv_anim_start(&a); + + /* opa anim */ + lv_anim_set_delay(&a, anim_time + duration); + lv_anim_set_values(&a, LV_OPA_COVER, LV_OPA_TRANSP); + lv_anim_set_exec_cb(&a, lv_toast_set_opa); + lv_anim_set_deleted_cb(&a, lv_toast_anim_del); + lv_anim_start(&a); +} + +void lv_toast_set_cont_style(lv_obj_t* obj, lv_style_t* style) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_toast_t* toast = (lv_toast_t*)obj; + toast->style = style; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_toast_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) +{ + LV_UNUSED(class_p); + lv_toast_t* toast = (lv_toast_t*)obj; + toast->style = NULL; +} + +static void lv_toast_event(const lv_obj_class_t* class_p, lv_event_t* e) +{ + LV_UNUSED(class_p); + lv_obj_event_base(MY_CLASS, e); +} + +static void lv_toast_set_height(void* var, int32_t y) +{ + lv_obj_set_height(var, y); +} + +static void lv_toast_set_opa(void* var, int32_t opa) +{ + lv_obj_set_style_opa(var, opa, 0); +} + +static void lv_toast_anim_del(lv_anim_t* a) +{ + lv_obj_del(a->var); +} diff --git a/x_track/src/App/Utils/lv_toast/lv_toast.h b/x_track/src/App/Utils/lv_toast/lv_toast.h new file mode 100644 index 0000000000000000000000000000000000000000..e3521adeacf5a025f48ad88a7b02df4d41ce7a4b --- /dev/null +++ b/x_track/src/App/Utils/lv_toast/lv_toast.h @@ -0,0 +1,53 @@ +/** + * @file lv_toast.h + * + */ + +#ifndef LV_TOAST_H +#define LV_TOAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lvgl/lvgl.h" +#include "lvgl/src/lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_obj_t obj; + lv_style_t* style; +} lv_toast_t; + +extern const lv_obj_class_t lv_toast_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_obj_t* lv_toast_create(lv_obj_t* parent); + +void lv_toast_show_text(lv_obj_t* obj, const char* txt, uint32_t duration); + +void lv_toast_set_cont_style(lv_obj_t* obj, lv_style_t* style); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TOAST_H*/ diff --git a/x_track/src/App/Version.h b/x_track/src/App/Version.h new file mode 100644 index 0000000000000000000000000000000000000000..5240e6a8da37c125084a21d085ea4cb696cae318 --- /dev/null +++ b/x_track/src/App/Version.h @@ -0,0 +1,33 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __VERSION_H +#define __VERSION_H + +/* Firmware Version */ +#define VERSION_FIRMWARE_NAME "X-TRACK" +#define VERSION_SOFTWARE "v2.7 (dev-lvgl-v9)" +#define VERSION_HARDWARE "v1.0" +#define VERSION_AUTHOR_NAME "_VIFEXTech" +#define VERSION_WEBSITE "https://github.com/FASTSHIFT/X-TRACK" + +#endif diff --git a/x_track/src/Frameworks/DataBroker/DataBroker.cpp b/x_track/src/Frameworks/DataBroker/DataBroker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..245959077688e87023e0de091b8d6d066fc156a7 --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataBroker.cpp @@ -0,0 +1,135 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataBroker.h" +#include "DataBrokerLog.h" +#include "DataTimer.h" +#include <algorithm> +#include <cstring> + +DataBroker::DataBroker(const char* name) + : _nodePool(nullptr) + , _mainNode(nullptr) + , _timerManager(nullptr) +{ + _name = name; + _nodePool = new DataNode::DataNodeList_t; + _mainNode = new DataNode(name, this); +} + +DataBroker::~DataBroker() +{ + DN_LOG_WARN("DataBroker[%s] closing...", _name); + + DN_LOG_INFO("Deleting main node: %p", _mainNode); + delete _mainNode; + _mainNode = nullptr; + + /* check leak */ + for (auto iter : *_nodePool) { + (void)iter; + DN_LOG_WARN("Leak: DataNode[%s]", iter->getID()); + } + + DN_LOG_INFO("Deleting node pool: %p", _nodePool); + delete _nodePool; + _nodePool = nullptr; + + if (_timerManager) { + DN_LOG_INFO("Deleting timer manager: %p", _timerManager); + delete _timerManager; + _timerManager = nullptr; + } + + DN_LOG_WARN("DataBroker[%s] closed.", _name); +} + +DataNode* DataBroker::search(const char* id) +{ + return search(_nodePool, id); +} + +DataNode* DataBroker::search(DataNode::DataNodeList_t* vec, const char* id) +{ + for (auto iter : *vec) { + if (strcmp(id, iter->getID()) == 0) { + return iter; + } + } + return nullptr; +} + +bool DataBroker::add(DataNode* node) +{ + if (_mainNode == nullptr || node == _mainNode) { + return false; + } + + if (search(node->getID()) != nullptr) { + DN_LOG_ERROR("Multi add DataNode[%s]", node->getID()); + return false; + } + + _nodePool->push_back(node); + + _mainNode->subscribe(node->getID()); + + return true; +} + +bool DataBroker::remove(DataNode* node) +{ + return remove(_nodePool, node); +} + +bool DataBroker::remove(DataNode::DataNodeList_t* vec, DataNode* node) +{ + auto iter = std::find(vec->begin(), vec->end(), node); + + if (iter == vec->end()) { + DN_LOG_ERROR("DataNode[%s] was not found", node->getID()); + return false; + } + + vec->erase(iter); + + return true; +} + +size_t DataBroker::getNodeNumber() +{ + return _nodePool->size(); +} + +void DataBroker::initTimerManager(uint32_t (*tickFunction)(void)) +{ + if (!_timerManager) { + _timerManager = new DataTimerManager; + } + + _timerManager->setTickCallback(tickFunction); +} + +uint32_t DataBroker::handleTimer() +{ + return _timerManager->handler(); +} diff --git a/x_track/src/Frameworks/DataBroker/DataBroker.h b/x_track/src/Frameworks/DataBroker/DataBroker.h new file mode 100644 index 0000000000000000000000000000000000000000..2e5f51fdccefd3956dcc04d4438a19c9c1498c8f --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataBroker.h @@ -0,0 +1,133 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_BROKER_H +#define __DATA_BROKER_H + +#include "DataNode.h" + +class DataTimerManager; + +class DataBroker { + friend class DataNode; + +public: + /** + * @brief Data broker constructor + * @param name: The name of the data broker + */ + DataBroker(const char* name); + + /** + * @brief Data broker destructor + */ + ~DataBroker(); + + /** + * @brief Get the number of nodes in the node pool + * @retval Number of nodes + */ + size_t getNodeNumber(); + + /** + * @brief Get the main node + * @retval Pointer to the main node + */ + DataNode* mainNode() + { + return _mainNode; + } + + /** + * @brief Set the main node + * @param node: Pointer to the main node + */ + void initTimerManager(uint32_t (*tickFunction)(void)); + + /** + * @brief Handle timer + * @retval Time till next timer event in millisecond + */ + uint32_t handleTimer(); + +protected: + /** + * @brief Add an node to the node pool + * @param node: Pointer to node + * @retval If the addition is successful, return true + */ + bool add(DataNode* node); + + /** + * @brief Remove the node from the node pool + * @param node: Pointer to node + * @retval Return true if the removal is successful + */ + bool remove(DataNode* node); + + /** + * @brief Remove node in vector + * @param vec: Pointer to vector + * @param id: DataNode ID + * @retval Return true if the removal is successful + */ + bool remove(DataNode::DataNodeList_t* vec, DataNode* node); + + /** + * @brief Search node + * @param id: DataNode ID + * @retval If the search is successful, return the pointer of the node + */ + DataNode* search(const char* id); + + /** + * @brief Search node in vector + * @param vec: Pointer to vector + * @param id: DataNode ID + * @retval If the search is successful, return the pointer of the node + */ + DataNode* search(DataNode::DataNodeList_t* vec, const char* id); + + /** + * @brief Get the timer manager + * @retval Pointer to the timer manager + */ + DataTimerManager* timerManager() + { + return _timerManager; + } + +private: + /* DataNode pool */ + DataNode::DataNodeList_t* _nodePool; + + /* Main node, will automatically follow all nodes */ + DataNode* _mainNode; + + /* Timer manager */ + DataTimerManager* _timerManager; + + /* The name of the data center will be used as the ID of the main node */ + const char* _name; +}; + +#endif diff --git a/x_track/src/Frameworks/DataBroker/DataBrokerLog.h b/x_track/src/Frameworks/DataBroker/DataBrokerLog.h new file mode 100644 index 0000000000000000000000000000000000000000..58341028c18c20768cfff00f462c6e48e0d49931 --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataBrokerLog.h @@ -0,0 +1,58 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_BROKER_LOG_H +#define __DATA_BROKER_LOG_H + +#define DATA_BROKER_LOG_LEVEL_INFO 0 +#define DATA_BROKER_LOG_LEVEL_WARN 1 +#define DATA_BROKER_LOG_LEVEL_ERROR 2 +#define DATA_BROKER_LOG_LEVEL_OFF 3 + +#ifndef DATA_BROKER_LOG_LEVEL +#define DATA_BROKER_LOG_LEVEL DATA_BROKER_LOG_LEVEL_OFF +#endif + +#if (DATA_BROKER_LOG_LEVEL < DATA_BROKER_LOG_LEVEL_OFF) +#include <stdio.h> +#define _DN_LOG(format, ...) printf("[DN]" format "\r\n", ##__VA_ARGS__) +#endif + +#if (DATA_BROKER_LOG_LEVEL <= DATA_BROKER_LOG_LEVEL_INFO) +#define DN_LOG_INFO(format, ...) _DN_LOG("[Info] " format, ##__VA_ARGS__) +#define DN_LOG_WARN(format, ...) _DN_LOG("[Warn] " format, ##__VA_ARGS__) +#define DN_LOG_ERROR(format, ...) _DN_LOG("[Error] " format, ##__VA_ARGS__) +#elif (DATA_BROKER_LOG_LEVEL <= DATA_BROKER_LOG_LEVEL_WARN) +#define DN_LOG_INFO(format, ...) +#define DN_LOG_WARN(format, ...) _DN_LOG("[Warn] " format, ##__VA_ARGS__) +#define DN_LOG_ERROR(format, ...) _DN_LOG("[Error] " format, ##__VA_ARGS__) +#elif (DATA_BROKER_LOG_LEVEL <= DATA_BROKER_LOG_LEVEL_ERROR) +#define DN_LOG_INFO(format, ...) +#define DN_LOG_WARN(format, ...) +#define DN_LOG_ERROR(format, ...) _DN_LOG("[Error] " format, ##__VA_ARGS__) +#else +#define DN_LOG_INFO(...) +#define DN_LOG_WARN(...) +#define DN_LOG_ERROR(...) +#endif + +#endif diff --git a/x_track/src/Frameworks/DataBroker/DataNode.cpp b/x_track/src/Frameworks/DataBroker/DataNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8a9e3882109d2bce0b4bac0ba6f4b6307927713 --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataNode.cpp @@ -0,0 +1,303 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataNode.h" +#include "DataBroker.h" +#include "DataBrokerLog.h" +#include "DataTimer.h" +#include <cstring> + +DataNode::DataNode( + const char* id, + DataBroker* broker, + void* userData) + : _ID(id) + , _broker(broker) + , _userData(userData) + , _eventCallback(nullptr) + , _eventFilterMask(0) + , _timer(nullptr) +{ + _broker->add(this); + + DN_LOG_INFO("DataNode[%s] created", _ID); +} + +DataNode::~DataNode() +{ + DN_LOG_INFO("DataNode[%s] deleting...", _ID); + + /* Delete timer */ + if (_timer) { + delete _timer; + _timer = nullptr; + } + + auto next = _subscribers.begin(); + decltype(next) current; + + /* Let subscribers unfollow */ + while (next != _subscribers.end()) { + current = next++; + DN_LOG_INFO("sub[%s] unsubscribed pub[%s]", (*current)->_ID, _ID); + (*current)->unsubscribe(_ID); + } + + /* Ask the publisher to delete this subscriber */ + for (auto iter : _publishers) { + DN_LOG_INFO("pub[%s] removed sub[%s]", iter->_ID, _ID); + _broker->remove(&iter->_subscribers, this); + } + + /* Let the data broker delete the node */ + _broker->remove(this); + DN_LOG_INFO("DataNode[%s] deleted", _ID); +} + +const DataNode* DataNode::subscribe(const char* pubID) +{ + /* Not allowed to subscribe to itself */ + if (strcmp(pubID, _ID) == 0) { + DN_LOG_ERROR("DataNode[%s] try to subscribe to it itself", _ID); + return nullptr; + } + + /* Check subscribe repeatedly */ + DataNode* pub = _broker->search(&_publishers, pubID); + if (pub) { + DN_LOG_WARN("Multi subscribe pub[%s]", pubID); + return pub; + } + + /* Check node is created */ + pub = _broker->search(pubID); + if (!pub) { + DN_LOG_ERROR("pub[%s] was not found", pubID); + return nullptr; + } + + /* Add the publisher to the subscription list */ + _publishers.push_back(pub); + + /* Let the publisher add this subscriber */ + pub->_subscribers.push_back(this); + + DN_LOG_INFO("sub[%s] subscribed pub[%s]", _ID, pubID); + + return pub; +} + +bool DataNode::unsubscribe(const char* pubID) +{ + /* Whether to subscribe to the publisher */ + DataNode* pub = _broker->search(&_publishers, pubID); + if (!pub) { + DN_LOG_WARN("sub[%s] was not subscribe pub[%s]", _ID, pubID); + return false; + } + + /* Remove the publisher from the subscription list */ + _broker->remove(&_publishers, pub); + + /* Let the publisher remove this subscriber */ + _broker->remove(&pub->_subscribers, this); + + return true; +} + +int DataNode::publish(const void* data_p, size_t size) +{ + int retval = RES_OK; + + EventParam_t param(this, nullptr, EVENT_PUBLISH, (void*)data_p, size); + + auto next = _subscribers.begin(); + /* Publish messages to subscribers */ + while (next != _subscribers.end()) { + auto sub = *next++; + param.recv = sub; + + DN_LOG_INFO("pub[%s] publish >> data(%p)[%zu] >> sub[%s]...", + _ID, param.data_p, param.size, sub->_ID); + + retval = sendEvent(sub, ¶m); + DN_LOG_INFO("publish done: %d", retval); + + /* record the last error code */ + if (retval == RES_STOP_PROCESS) { + DN_LOG_INFO("publish stop"); + break; + } + } + + return retval; +} + +int DataNode::pull(const char* pubID, void* data_p, size_t size) +{ + DataNode* pub = _broker->search(&_publishers, pubID); + if (!pub) { + DN_LOG_ERROR("sub[%s] was not subscribe pub[%s]", _ID, pubID); + return RES_NOT_FOUND; + } + return pull(pub, data_p, size); +} + +int DataNode::pull(const DataNode* pub, void* data_p, size_t size) +{ + if (!pub) { + return RES_PARAM_ERROR; + } + + DN_LOG_INFO("sub[%s] pull << data(%p)[%zu] << pub[%s] ...", + _ID, data_p, size, pub->_ID); + + EventCallback_t callback = pub->_eventCallback; + if (!callback) { + return RES_NO_CALLBACK; + } + + EventParam_t param(this, pub, EVENT_PULL, data_p, size); + int ret = sendEvent((DataNode*)pub, ¶m); + + DN_LOG_INFO("pull done: %d", ret); + return ret; +} + +int DataNode::notify(const char* pubID, const void* data_p, size_t size) +{ + DataNode* pub = _broker->search(&_publishers, pubID); + if (!pub) { + DN_LOG_ERROR("sub[%s] was not subscribe pub[%s]", _ID, pubID); + return RES_NOT_FOUND; + } + + return notify(pub, data_p, size); +} + +int DataNode::notify(const DataNode* pub, const void* data_p, size_t size) +{ + if (!pub) { + return RES_PARAM_ERROR; + } + + DN_LOG_INFO("sub[%s] notify >> data(%p)[%zu] >> pub[%s] ...", + _ID, data_p, size, pub->_ID); + + EventParam_t param(this, pub, EVENT_NOTIFY, (void*)data_p, size); + int ret = sendEvent((DataNode*)pub, ¶m); + + DN_LOG_INFO("send done: %d", ret); + + return ret; +} + +void DataNode::setEventCallback(EventCallback_t callback, uint32_t eventFilter) +{ + _eventCallback = callback; + _eventFilterMask = eventFilter; +} + +void DataNode::setEventFilter(uint32_t eventFilter) +{ + _eventFilterMask = eventFilter; +} + +int DataNode::onEvent(EventParam_t* param) +{ + if (!_eventCallback) { + DN_LOG_INFO("DataNode[%s] not register callback", _ID); + return RES_NO_CALLBACK; + } + + return _eventCallback(this, param); +} + +int DataNode::sendEvent(DataNode* node, EventParam_t* param) +{ + if (!(node->_eventFilterMask & param->event)) { + return RES_UNSUPPORTED_REQUEST; + } + + return node->onEvent(param); +} + +void DataNode::timerCallbackHandler(DataTimer* timer) +{ + auto instance = (DataNode*)timer->getUserData(); + + EventParam_t param(instance, instance, EVENT_TIMER, nullptr, 0); + instance->sendEvent(instance, ¶m); +} + +void DataNode::startTimer(uint32_t period) +{ + if (_timer) { + _timer->setPeriod(period); + _timer->resume(); + return; + } + + _timer = new DataTimer(_broker->timerManager(), timerCallbackHandler, period, this); +} + +void DataNode::setTimerPeriod(uint32_t period) +{ + if (!_timer) { + DN_LOG_ERROR("Timer not created"); + return; + } + + _timer->setPeriod(period); + _timer->resume(); +} + +void DataNode::resetTimer() +{ + if (!_timer) { + DN_LOG_ERROR("Timer not created"); + return; + } + + _timer->resume(); +} + +void DataNode::stopTimer() +{ + if (!_timer) { + return; + } + + _timer->pause(); + + DN_LOG_INFO("DataNode[%s] timer stop", _ID); +} + +size_t DataNode::getPublishersNumber() +{ + return _publishers.size(); +} + +size_t DataNode::getSubscribersNumber() +{ + return _subscribers.size(); +} diff --git a/x_track/src/Frameworks/DataBroker/DataNode.h b/x_track/src/Frameworks/DataBroker/DataNode.h new file mode 100644 index 0000000000000000000000000000000000000000..07a4a44327fc3bbda48158a2092095a77f3e0284 --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataNode.h @@ -0,0 +1,265 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_NODE_H +#define __DATA_NODE_H + +#include <cstddef> +#include <cstdint> +#include <list> + +class DataBroker; +class DataTimer; + +class DataNode { +public: + /* Event type enumeration */ + typedef enum { + EVENT_NONE = 0, /* No event */ + EVENT_PUBLISH = 1 << 0, /* Publisher posted information */ + EVENT_PULL = 1 << 1, /* Subscriber data pull request */ + EVENT_NOTIFY = 1 << 2, /* Subscribers send notifications to publishers */ + EVENT_TIMER = 1 << 3, /* Timer event */ + EVENT_ALL = 0xFFFFFFFF /* All Event */ + } EventCode_t; + + /* Error type enumeration */ + typedef enum { + RES_OK = 0, + RES_UNKNOWN = -1, + RES_SIZE_MISMATCH = -2, + RES_UNSUPPORTED_REQUEST = -3, + RES_NO_CALLBACK = -4, + RES_NO_DATA = -5, + RES_NOT_FOUND = -6, + RES_PARAM_ERROR = -7, + RES_STOP_PROCESS = -8, + } ResCode_t; + + /* Event parameter structure */ + typedef struct EventParam { + EventParam(const DataNode* _tran, const DataNode* _recv, EventCode_t _event, void* _data_p, size_t _size) + : tran(_tran) + , recv(_recv) + , event(_event) + , data_p(_data_p) + , size(_size) + { + } + const DataNode* tran; /* Pointer to sender */ + const DataNode* recv; /* Pointer to receiver */ + EventCode_t event; /* Event type */ + void* data_p; /* Pointer to data */ + size_t size; /* The size of the data */ + } EventParam_t; + + /* Event callback function pointer */ + typedef int (*EventCallback_t)(DataNode* node, EventParam_t* param); + + typedef std::list<DataNode*> DataNodeList_t; + +public: + /** + * @brief DataNode constructor + * @param id: Unique name + * @param broker: Pointer to the data broker + * @param bufSize: The length of the data to be cached + * @param userData: Point to the address of user-defined data + */ + DataNode( + const char* id, + DataBroker* broker, + void* userData = nullptr); + + /** + * @brief DataNode destructor + */ + virtual ~DataNode(); + + /** + * @brief Subscribe to Publisher + * @param pubID: Publisher _ID + * @retval Pointer to publisher + */ + const DataNode* subscribe(const char* pubID); + + /** + * @brief Unsubscribe from publisher + * @param pubID: Publisher _ID + * @retval Return true if unsubscribe is successful + */ + bool unsubscribe(const char* pubID); + + /** + * @brief Get the number of publishers + * @retval number of publishers + */ + size_t getPublishersNumber(); + + /** + * @brief Get the number of subscribes + * @retval number of subscribes + */ + size_t getSubscribersNumber(); + + /** + * @brief Publish data to subscribers + * @param data_p: Pointer to data + * @param size: The size of the data + * @retval error code + */ + int publish(const void* data_p, size_t size); + + /** + * @brief Pull data from the publisher + * @param pubID: Publisher _ID + * @param data_p: Pointer to data + * @param size: The size of the data + * @retval error code + */ + int pull(const char* pubID, void* data_p, size_t size); + + /** + * @brief Send notification to the publisher + * @param pub: Publisher node pointer + * @param data_p: Pointer to data + * @param size: The size of the data + * @retval error code + */ + int pull(const DataNode* pub, void* data_p, size_t size); + + /** + * @brief Send a notification to the publisher + * @param pubID: Publisher _ID + * @param data_p: Pointer to data + * @param size: The size of the data + * @retval error code + */ + int notify(const char* pubID, const void* data_p, size_t size); + + /** + * @brief Send a notification to the publisher + * @param pub: Pointer to publisher + * @param data_p: Pointer to data + * @param size: The size of the data + * @retval error code + */ + int notify(const DataNode* pub, const void* data_p, size_t size); + + /** + * @brief Set event callback + * @param callback: Callback function pointer + * @param eventFilter: Event filter mask + */ + void setEventCallback(EventCallback_t callback, uint32_t eventFilter = EVENT_ALL); + + /** + * @brief Set event filter + * @param eventFilter: Event filter mask + */ + void setEventFilter(uint32_t eventFilter); + + /** + * @brief Event handler + * @param param: Event parameter structure + * @retval error code + */ + virtual int onEvent(EventParam_t* param); + + /** + * @brief Start timer + * @param period: Timer period + */ + void startTimer(uint32_t period); + + /** + * @brief Change timer period + * @param period: Timer period + */ + void setTimerPeriod(uint32_t period); + + /** + * @brief Reset timer + */ + void resetTimer(); + + /** + * @brief Stop timer + */ + void stopTimer(); + + /** + * @brief Set user-defined data + * @param userData: Point to the address of user-defined data + */ + void setUserData(void* userData) + { + _userData = userData; + } + + /** + * @brief Get user-defined data + * @retval Point to the address of user-defined data + */ + void* getUserData() + { + return _userData; + } + + /** + * @brief Get node ID + * @retval Node ID + */ + const char* getID() const + { + return _ID; + } + +private: + DataNodeList_t _publishers; /* Followed publishers */ + DataNodeList_t _subscribers; /* Followed subscribers */ + + const char* _ID; /* Node ID */ + DataBroker* _broker; /* Pointer to the data broker */ + void* _userData; + + EventCallback_t _eventCallback; + uint32_t _eventFilterMask; + DataTimer* _timer; + +private: + /** + * @brief Timer callback entry function + * @param timer: Pointer to timer + */ + static void timerCallbackHandler(DataTimer* timer); + + /** + * @brief Send event to the receiver + * @param node: Receiver node pointer + * @param param: Event parameter structure + * @retval error code + */ + static int sendEvent(DataNode* node, EventParam_t* param); +}; + +#endif diff --git a/x_track/src/Frameworks/DataBroker/DataTimer.cpp b/x_track/src/Frameworks/DataBroker/DataTimer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80ff8de63db114f74aea1b976529d5005554fa77 --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataTimer.cpp @@ -0,0 +1,174 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "DataTimer.h" + +#ifndef UINT32_MAX +#define UINT32_MAX 0xFFFFFFFF +#endif + +DataTimer::DataTimer(DataTimerManager* manager, TimerFunction_t timerFunc, uint32_t period, void* userData) + : _manager(manager) + , _timerFunc(timerFunc) + , _userData(userData) + , _period(period) + , _lastTick(0) + , _isPause(false) +{ + _manager->add(this); +} + +DataTimer::~DataTimer() +{ + _manager->remove(this); +} + +void DataTimer::pause() +{ + _isPause = true; +} + +void DataTimer::resume() +{ + _isPause = false; +} + +void DataTimer::reset() +{ + _lastTick = _manager->getTick(); +} + +uint32_t DataTimer::remain() +{ + auto elaps = _manager->getTickElaps(_lastTick); + return elaps > _period ? 0 : _period - elaps; +} + +void DataTimer::setPeriod(uint32_t period) +{ + _period = period; +} + +uint32_t DataTimer::getPeriod() +{ + return _period; +} + +void* DataTimer::getUserData() +{ + return _userData; +} + +bool DataTimer::isReady() +{ + if (_isPause) { + return false; + } + + if (remain() > 0) { + return false; + } + + return true; +} + +bool DataTimer::isPause() +{ + return _isPause; +} + +void DataTimer::invoke() +{ + _timerFunc(this); +} + +DataTimerManager::DataTimerManager(TickFunction_t tickCallback) +{ + _getTick = tickCallback; +} + +DataTimerManager::~DataTimerManager() +{ +} + +void DataTimerManager::setTickCallback(TickFunction_t tickCallback) +{ + _getTick = tickCallback; +} + +void DataTimerManager::add(DataTimer* timer) +{ + _timerList.push_back(timer); +} + +void DataTimerManager::remove(DataTimer* timer) +{ + _timerList.remove(timer); +} + +uint32_t DataTimerManager::getTick() +{ + return _getTick(); +} + +uint32_t DataTimerManager::getTickElaps(uint32_t prevTick) +{ + uint32_t act_time = getTick(); + + /*If there is no overflow in sys_time simple subtract*/ + if (act_time >= prevTick) { + prevTick = act_time - prevTick; + } else { + prevTick = UINT32_MAX - prevTick + 1; + prevTick += act_time; + } + + return prevTick; +} + +uint32_t DataTimerManager::handler() +{ + /* invoke all timers that are ready */ + for (const auto& iter : _timerList) { + if (iter->isReady()) { + iter->reset(); + iter->invoke(); + } + } + + uint32_t timeTillNext = UINT32_MAX; + + /* Find the minimum remaining time */ + for (const auto& iter : _timerList) { + /* Ignore paused timers */ + if (iter->isPause()) { + continue; + } + + uint32_t remain = iter->remain(); + if (remain < timeTillNext) { + timeTillNext = remain; + } + } + + return timeTillNext; +} diff --git a/x_track/src/Frameworks/DataBroker/DataTimer.h b/x_track/src/Frameworks/DataBroker/DataTimer.h new file mode 100644 index 0000000000000000000000000000000000000000..e779ec0e66b1a7a0d605fe328c0a7ff39e9f272e --- /dev/null +++ b/x_track/src/Frameworks/DataBroker/DataTimer.h @@ -0,0 +1,170 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __DATA_TIMER_H +#define __DATA_TIMER_H + +#include <cstdint> +#include <list> + +class DataTimerManager; + +class DataTimer { + friend class DataTimerManager; + +public: + typedef void (*TimerFunction_t)(DataTimer*); + +public: + /** + * @brief create a timer + * @param manager the timer manager + * @param timerFunc the timer function to be invoked + * @param period the timer period in millisecond + * @param userData the user data to be passed to the timer function + */ + DataTimer(DataTimerManager* manager, TimerFunction_t timerFunc, uint32_t period, void* userData = nullptr); + + ~DataTimer(); + + /** + * @brief pause the timer + */ + void pause(); + + /** + * @brief resume the timer + */ + void resume(); + + /** + * @brief reset the timer + */ + void reset(); + + /** + * @brief get the remaining time of the timer + * @return the remaining time in millisecond + */ + uint32_t remain(); + + /** + * @brief set the timer period + * @param period the timer period in millisecond + */ + void setPeriod(uint32_t period); + + /** + * @brief get the timer period + * @return the timer period in millisecond + */ + uint32_t getPeriod(); + + /** + * @brief get the user data + * @return the user data + */ + void* getUserData(); + +protected: + /** + * @brief get the timer is ready to invoke + * @return true if the timer is ready to invoke, false otherwise + */ + bool isReady(); + + /** + * @brief get the timer is pause + * @return true if the timer is pause, false otherwise + */ + bool isPause(); + + /** + * @brief invoke the timer function + */ + void invoke(); + +private: + DataTimerManager* _manager; + TimerFunction_t _timerFunc; + void* _userData; + uint32_t _period; + uint32_t _lastTick; + bool _isPause; +}; + +class DataTimerManager { +public: + typedef uint32_t (*TickFunction_t)(void); + +public: + /** + * @brief create a timer manager + * @param tickCallback the tick callback function to get the current tick + */ + DataTimerManager(TickFunction_t tickCallback = nullptr); + + ~DataTimerManager(); + + /** + * @brief set the tick callback function + * @param tickCallback the tick callback function to get the current tick + */ + void setTickCallback(TickFunction_t tickCallback); + + /** + * @brief add a timer + * @param timer the timer to be added + */ + void add(DataTimer* timer); + + /** + * @brief remove a timer + * @param timer the timer to be removed + */ + void remove(DataTimer* timer); + + /** + * @brief get the current tick + * @return the current tick + */ + uint32_t getTick(); + + /** + * @brief get the elapsed time from the previous tick + * @param prevTick the previous tick + * @return the elapsed time in millisecond + */ + uint32_t getTickElaps(uint32_t prevTick); + + /** + * @brief handle the timer events + * @return time till next timer event in millisecond + */ + uint32_t handler(); + +private: + TickFunction_t _getTick; + std::list<DataTimer*> _timerList; +}; + +#endif /* __DATA_TIMER_H */ diff --git a/x_track/src/Frameworks/DeviceManager/DeviceManager.cpp b/x_track/src/Frameworks/DeviceManager/DeviceManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2dfc63c8148d284160ecc5ea931c309142b30f8 --- /dev/null +++ b/x_track/src/Frameworks/DeviceManager/DeviceManager.cpp @@ -0,0 +1,58 @@ +/* + * MIT License + * Copyright (c) 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "DeviceManager.h" +#include "DeviceObject.h" +#include <string.h> + +DeviceManager::DeviceManager(DeviceObject** devArray, size_t len) +{ + _devArray = devArray; + _devArrayLen = len; +} + +DeviceManager::~DeviceManager() +{ +} + +void DeviceManager::init(InitFinishCallback_t callback) +{ + for (size_t i = 0; i < _devArrayLen; i++) { + DeviceObject* dev = _devArray[i]; + int retval = dev->init(); + if (callback) { + callback(this, dev, retval); + } + } +} + +DeviceObject* DeviceManager::getDevice(const char* name) +{ + for (size_t i = 0; i < _devArrayLen; i++) { + DeviceObject* dev = _devArray[i]; + if (strcmp(name, dev->getName()) == 0) { + return dev; + } + } + return nullptr; +} diff --git a/x_track/src/Frameworks/DeviceManager/DeviceManager.h b/x_track/src/Frameworks/DeviceManager/DeviceManager.h new file mode 100644 index 0000000000000000000000000000000000000000..58df406a99ccfa718ff3f55f835ba8e9c7b6ca45 --- /dev/null +++ b/x_track/src/Frameworks/DeviceManager/DeviceManager.h @@ -0,0 +1,47 @@ +/* + * MIT License + * Copyright (c) 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __DEVICE_MANAGER_H +#define __DEVICE_MANAGER_H + +#include <stddef.h> + +class DeviceObject; + +class DeviceManager { +public: + typedef void (*InitFinishCallback_t)(DeviceManager* manager, DeviceObject* dev, int retval); + +public: + DeviceManager(DeviceObject** devArray, size_t len); + ~DeviceManager(); + + void init(InitFinishCallback_t callback = nullptr); + DeviceObject* getDevice(const char* name); + +private: + DeviceObject** _devArray; + size_t _devArrayLen; +}; + +#endif // !__DEVICE_MANAGER diff --git a/x_track/src/Frameworks/DeviceManager/DeviceObject.h b/x_track/src/Frameworks/DeviceManager/DeviceObject.h new file mode 100644 index 0000000000000000000000000000000000000000..f448b89226ac6fc04071d9e51198b63ca1e418b5 --- /dev/null +++ b/x_track/src/Frameworks/DeviceManager/DeviceObject.h @@ -0,0 +1,139 @@ +/* + * MIT License + * Copyright (c) 2022 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __DEVICE_OBJECT_H +#define __DEVICE_OBJECT_H + +#include <stddef.h> +#include <stdint.h> + +#define DEVICE_OBJECT_IOCMD_DEF(dir, size, type, number) \ + (uint32_t)( \ + (((uint32_t)(dir) & 0x0003) << 30) \ + | (((uint32_t)(size) & 0x3FFF) << 16) \ + | (((uint32_t)(type) & 0x00FF) << 8) \ + | ((uint32_t)(number) & 0x00FF)) + +class DeviceObject { +public: + typedef enum { + DIR_NONE = 0x00, + DIR_IN = 0x01, + DIR_OUT = 0x02, + DIR_IN_OUT = 0x03, + } Direction_t; + + typedef union { + uint32_t full; + struct + { + uint32_t number : 8; + uint32_t type : 8; + uint32_t size : 14; + uint32_t dir : 2; + } ch; + } IO_Cmd_t; + + typedef enum { + RES_OK = 0, + RES_UNKNOWN = -1, + RES_NO_IMPLEMENTED = -2, + RES_INIT_FAILED = -3, + RES_PARAM_ERROR = -4, + RES_UNSUPPORT = -5, + } ResCode_t; + +public: + DeviceObject(const char* name) + : _name(name) + , initOK(false) + { + } + virtual ~DeviceObject() {}; + + int init() + { + int retval = onInit(); + initOK = retval >= RES_OK; + + return retval; + } + + int read(void* buffer, size_t size) + { + if (!initOK) { + return RES_INIT_FAILED; + } + + if (!buffer) { + return RES_PARAM_ERROR; + } + + return onRead(buffer, size); + } + + int write(const void* buffer, size_t size) + { + if (!initOK) { + return RES_INIT_FAILED; + } + + if (!buffer) { + return RES_PARAM_ERROR; + } + + return onWrite(buffer, size); + } + + int ioctl(uint32_t cmd, void* data = nullptr, size_t size = 0) + { + IO_Cmd_t* c = (IO_Cmd_t*)&cmd; + + if (!initOK) { + return RES_INIT_FAILED; + } + + if (size != c->ch.size) { + return RES_PARAM_ERROR; + } + + return onIoctl(*c, data); + } + + const char* getName() + { + return _name; + } + +private: + const char* _name; + bool initOK; + +private: + virtual int onInit() { return RES_NO_IMPLEMENTED; }; + virtual int onRead(void* buffer, size_t size) { return RES_NO_IMPLEMENTED; } + virtual int onWrite(const void* buffer, size_t size) { return RES_NO_IMPLEMENTED; } + virtual int onIoctl(IO_Cmd_t cmd, void* data) { return RES_NO_IMPLEMENTED; } +}; + +#endif diff --git a/x_track/src/Frameworks/PageManager/PageBase.cpp b/x_track/src/Frameworks/PageManager/PageBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2fa33504dfb9aa514fb898ac6258803f2e3f4c2 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageBase.cpp @@ -0,0 +1,92 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PageBase.h" +#include "PageLog.h" + +PageBase::PageBase() + : _manager(nullptr) + , _name(nullptr) + , _id(0) + , _root(nullptr) + , _context { 0 } +{ +} + +PageBase::~PageBase() +{ +} + +void PageBase::setCacheEnable(bool en) +{ + PAGE_LOG_INFO("Page(%s) enable %d", _name, en); + setAutoCacheEnable(false); + _context.reqEnableCache = en; +} + +void PageBase::setAutoCacheEnable(bool en) +{ + PAGE_LOG_INFO("Page(%s) enable %d", _name, en); + _context.reqDisableAutoCache = !en; +} + +void PageBase::setLoadAnimType(PAGE_ANIM type) +{ + _context.anim.attr.type = type; +} + +void PageBase::setLoadAnimTime(uint32_t time) +{ + _context.anim.attr.duration = time; +} + +void PageBase::setLoadAnimPath(lv_anim_path_cb_t path) +{ + _context.anim.attr.path = path; +} + +void PageBase::setBackGestureDirection(lv_dir_t dir) +{ + _context.backGestureDir = dir; +} + +bool PageBase::getParam(void* ptr, uint32_t size) +{ + if (!_context.param.ptr) { + PAGE_LOG_WARN("No param found"); + return false; + } + + if (_context.param.size != size) { + PAGE_LOG_WARN( + "param[%p](%" PRIu32 ") does not match the size(%" PRIu32 ")", + _context.param.ptr, + _context.param.size, + size); + return false; + } + + lv_memcpy(ptr, _context.param.ptr, _context.param.size); + lv_free(_context.param.ptr); + _context.param.ptr = nullptr; + return true; +} diff --git a/x_track/src/Frameworks/PageManager/PageBase.h b/x_track/src/Frameworks/PageManager/PageBase.h new file mode 100644 index 0000000000000000000000000000000000000000..562ebb4843c30065c3f5051a2eaa938151e6c553 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageBase.h @@ -0,0 +1,232 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PAGE_BASE_H +#define __PAGE_BASE_H + +#include "PageDef.h" +#include "lvgl/lvgl.h" + +/* Generate page param */ +#define PAGE_PARAM_MAKE(PARAM) \ + { \ + &(PARAM), sizeof(PARAM) \ + } + +/* Get page param */ +#define PAGE_GET_PARAM(PARAM) this->getParam(&(PARAM), sizeof(PARAM)) + +class PageManager; + +class PageBase { + friend class PageManager; + +public: + /* Page statement */ + enum class STATE { + IDLE, + LOAD, + WILL_APPEAR, + DID_APPEAR, + ACTIVITY, + WILL_DISAPPEAR, + DID_DISAPPEAR, + UNLOAD, + }; + +public: + PageBase(); + virtual ~PageBase(); + + /** + * @brief Page installation callback + */ + virtual void onInstalled() { } + + /** + * @brief Page load start callback + */ + virtual void onViewLoad() { } + + /** + * @brief Page load end callback + */ + virtual void onViewDidLoad() { } + + /** + * @brief Page appear animation start callback + */ + virtual void onViewWillAppear() { } + + /** + * @brief Page appear animation end callback + */ + virtual void onViewDidAppear() { } + + /** + * @brief Page disappear animation start callback + */ + virtual void onViewWillDisappear() { } + + /** + * @brief Page disappear animation end callback + */ + virtual void onViewDidDisappear() { } + + /** + * @brief Page unload start callback + */ + virtual void onViewUnload() { } + + /** + * @brief Page unload end callback + */ + virtual void onViewDidUnload() { } + + /** + * @brief Set page cache enable + * @param en: Cache enable + * @retval None + */ + void setCacheEnable(bool en); + + /** + * @brief Set page automatic cache management enable + * @param en: Automatic cache management enable + * @retval None + */ + void setAutoCacheEnable(bool en); + + /** + * @brief Set page animation type + * @param type: Animation type + * @retval None + */ + void setLoadAnimType(PAGE_ANIM type); + + /** + * @brief Set page animation time + * @param time: Animation time + * @retval None + */ + void setLoadAnimTime(uint32_t time); + + /** + * @brief Set page animation path + * @param path: Animation path + * @retval None + */ + void setLoadAnimPath(lv_anim_path_cb_t path); + + /** + * @brief Set page back gesture direction + * @param dir: Back gesture direction, See lv_dir_t + * @retval None + */ + void setBackGestureDirection(lv_dir_t dir); + + /** + * @brief Get page parameter + * @param ptr: Parameter pointer + * @param size: Parameter size + * @retval return true if success + */ + bool getParam(void* ptr, uint32_t size); + + /** + * @brief Get page manager + * @param None + * @retval Page manager pointer + */ + PageManager* getManager() { return _manager; } + + /** + * @brief Get page name + * @param None + * @retval Page name + */ + const char* getName() { return _name; } + + /** + * @brief Get page ID + * @param None + * @retval Page ID + */ + uint16_t getID() { return _id; } + + /** + * @brief Get page root node + * @param None + * @retval Page root node + */ + lv_obj_t* getRoot() { return _root; } + +protected: + /* Page parameter */ + struct PARAM { + void* ptr; + uint32_t size; + }; + +private: + /* Page switching animation properties */ + struct ANIM_ATTR { + ANIM_ATTR() + : type(PAGE_ANIM::GLOBAL) + , duration(PAGE_ANIM_TIME_DEFAULT) + , path(PAGE_ANIM_PATH_DEFAULT) + { + } + PAGE_ANIM type; + uint32_t duration; + lv_anim_path_cb_t path; + }; + + struct CONTEXT { + bool reqEnableCache; /* Cache enable request */ + bool reqDisableAutoCache; /* Automatic cache management enable request */ + + bool isDisableAutoCache; /* Whether it is automatic cache management */ + bool isCached; /* Cache enable */ + + PARAM param; /* Page parameter */ + STATE state; /* Page statement */ + + struct + { + bool isEnter; /* Animation enter or exit */ + bool isBusy; /* Animation is busy */ + ANIM_ATTR attr; /* Animation properties */ + } anim; + + lv_dir_t backGestureDir; /* Back gesture direction */ + }; + +private: + PageManager* _manager; /* Page manager pointer */ + const char* _name; /* Page name */ + uint16_t _id; /* Page ID */ + lv_obj_t* _root; /* UI root node */ + CONTEXT _context; /* Page context */ +}; + +#endif /* __PAGE_BASE_H */ diff --git a/x_track/src/Frameworks/PageManager/PageDef.h b/x_track/src/Frameworks/PageManager/PageDef.h new file mode 100644 index 0000000000000000000000000000000000000000..b1e40d24a04847ea71f080977cefc54ddd7d7294 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageDef.h @@ -0,0 +1,54 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PAGE_DEF_H +#define __PAGE_DEF_H + +#define PAGE_ANIM_TIME_DEFAULT 300 //[ms] + +#define PAGE_ANIM_PATH_DEFAULT lv_anim_path_ease_out + +/* Page switching animation type */ +enum class PAGE_ANIM { + /* Default (global) animation type */ + GLOBAL = 0, + + /* No animation */ + NONE, + + /* New page overwrites old page */ + OVER_LEFT, + OVER_RIGHT, + OVER_TOP, + OVER_BOTTOM, + + /* New page pushes old page */ + MOVE_LEFT, + MOVE_RIGHT, + MOVE_TOP, + MOVE_BOTTOM, + + /* The new interface fades in, the old page fades out */ + FADE_ON, +}; + +#endif /* __PAGE_DEF_H */ diff --git a/x_track/src/Frameworks/PageManager/PageFactory.h b/x_track/src/Frameworks/PageManager/PageFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..40f303c9aba6415cfb81a1a805e019ad74c76195 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageFactory.h @@ -0,0 +1,44 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PAGE_FACTORY_H +#define __PAGE_FACTORY_H + +#include "PageBase.h" + +class PageFactory { +public: + PageFactory() {}; + virtual ~PageFactory() {}; + + /** + * @brief Create a page + * @param name Page name + * @return Pointer to the page + */ + virtual PageBase* create(const char* name) + { + return nullptr; + }; +}; + +#endif // !__PAGE_FACTORY_H diff --git a/x_track/src/Frameworks/PageManager/PageLog.cpp b/x_track/src/Frameworks/PageManager/PageLog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..338178fdeb84733d37a4258036e2047cc4be7b9e --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageLog.cpp @@ -0,0 +1,48 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PageLog.h" + +#if (PAGE_LOG_LEVEL < PAGE_LOG_LEVEL_OFF) + +#include <stdarg.h> +#include <stdio.h> + +void PageLog(int level, const char* func, const char* format, ...) +{ + if (level < PAGE_LOG_LEVEL) { + return; + } + + va_list args; + va_start(args, format); + + static const char* prefix[] = { "Info", "Warn", "Error" }; + + printf("[PM][%s] %s: ", prefix[level], func); + vprintf(format, args); + printf("\n"); + + va_end(args); +} + +#endif diff --git a/x_track/src/Frameworks/PageManager/PageLog.h b/x_track/src/Frameworks/PageManager/PageLog.h new file mode 100644 index 0000000000000000000000000000000000000000..ee47f2e7bd9818a66eb4bf1dccdf78987862b763 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageLog.h @@ -0,0 +1,48 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PAGE_LOG_H +#define __PAGE_LOG_H + +#define PAGE_LOG_LEVEL_INFO 0 +#define PAGE_LOG_LEVEL_WARN 1 +#define PAGE_LOG_LEVEL_ERROR 2 +#define PAGE_LOG_LEVEL_OFF 3 + +#ifndef PAGE_LOG_LEVEL +#define PAGE_LOG_LEVEL PAGE_LOG_LEVEL_OFF +#endif + +#if (PAGE_LOG_LEVEL < PAGE_LOG_LEVEL_OFF) + +void PageLog(int level, const char* func, const char* format, ...); + +#define PAGE_LOG_INFO(...) PageLog(PAGE_LOG_LEVEL_INFO, __func__, __VA_ARGS__) +#define PAGE_LOG_WARN(...) PageLog(PAGE_LOG_LEVEL_WARN, __func__, __VA_ARGS__) +#define PAGE_LOG_ERROR(...) PageLog(PAGE_LOG_LEVEL_ERROR, __func__, __VA_ARGS__) +#else +#define PAGE_LOG_INFO(...) +#define PAGE_LOG_WARN(...) +#define PAGE_LOG_ERROR(...) +#endif + +#endif diff --git a/x_track/src/Frameworks/PageManager/PageManager.cpp b/x_track/src/Frameworks/PageManager/PageManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46ca864502929c28fa84a00146f743e0eeb43f9e --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageManager.cpp @@ -0,0 +1,258 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PageManager.h" +#include "PageLog.h" +#include <algorithm> +#include <string.h> + +#define PM_EMPTY_PAGE_NAME "EMPTY_PAGE" + +PageManager::PageManager(PageFactory* factory) + : _factory(factory) + , _pageCnt(0) + , _pagePrev(nullptr) + , _pageCurrent(nullptr) + , _animState { 0 } + , _rootParent(nullptr) + , _rootDefaultStyle(nullptr) + , _layerTop(nullptr) + , _eventCallback(nullptr) + , _eventUserData(nullptr) +{ + setGlobalLoadAnim(PAGE_ANIM::OVER_LEFT); +} + +PageManager::~PageManager() +{ + clearStack(); +} + +PageBase* PageManager::findPageInPool(const char* name) +{ + for (auto iter : _pagePool) { + if (strcmp(name, iter->_name) == 0) { + return iter; + } + } + return nullptr; +} + +PageBase* PageManager::findPageInStack(const char* name) +{ + decltype(_pageStack) stk = _pageStack; + while (!stk.empty()) { + PageBase* base = stk.top(); + + if (strcmp(name, base->_name) == 0) { + return base; + } + + stk.pop(); + } + + return nullptr; +} + +PageManager::RES_TYPE PageManager::install(const char* className, const char* appName) +{ + if (!_factory) { + PAGE_LOG_ERROR("Factory was not registered, can't install page"); + return RES_TYPE::ERR_NOT_FOUND; + } + + if (!appName) { + PAGE_LOG_WARN("appName has not set"); + appName = className; + } + + if (findPageInPool(appName) != nullptr) { + PAGE_LOG_ERROR("Page(%s) was registered", appName); + return RES_TYPE::ERR_DUPLICATE; + } + + PageBase* base = _factory->create(className); + if (!base) { + PAGE_LOG_ERROR("Factory has not %s", className); + return RES_TYPE::ERR_UNKNOWN; + } + + base->_id = _pageCnt++; + + PAGE_LOG_INFO("Install Page[class = %s, name = %s]", className, appName); + auto res = registerPage(base, appName); + if (res == RES_TYPE::OK) { + base->onInstalled(); + } + + return res; +} + +PageManager::RES_TYPE PageManager::uninstall(const char* appName) +{ + PAGE_LOG_INFO("Page(%s) uninstall...", appName); + + PageBase* base = findPageInPool(appName); + if (!base) { + PAGE_LOG_ERROR("Page(%s) was not found", appName); + return RES_TYPE::ERR_NOT_FOUND; + } + + auto res = unregisterPage(appName); + if (res != RES_TYPE::OK) { + PAGE_LOG_ERROR("Page(%s) unregister failed", appName); + return res; + } + + if (base->_context.isCached) { + PAGE_LOG_WARN("Page(%s) has cached, unloading...", appName); + base->_context.state = PageBase::STATE::UNLOAD; + stateNext(base); + stateNext(base); + stateNext(base); + stateNext(base); + stateNext(base); + } else { + PAGE_LOG_INFO("Page(%s) has not cache", appName); + } + + delete base; + PAGE_LOG_INFO("Uninstall OK"); + return RES_TYPE::OK; +} + +PageManager::RES_TYPE PageManager::registerPage(PageBase* base, const char* name) +{ + if (findPageInPool(name) != nullptr) { + PAGE_LOG_ERROR("Page(%s) was multi registered", name); + return RES_TYPE::ERR_DUPLICATE; + } + + base->_manager = this; + base->_name = name; + + _pagePool.push_back(base); + + return RES_TYPE::OK; +} + +PageManager::RES_TYPE PageManager::unregisterPage(const char* name) +{ + PAGE_LOG_INFO("Page(%s) unregister...", name); + + PageBase* base = findPageInStack(name); + + if (base != nullptr) { + PAGE_LOG_ERROR("Page(%s) was in stack", name); + return RES_TYPE::ERR_OPERATION; + } + + base = findPageInPool(name); + if (!base) { + PAGE_LOG_ERROR("Page(%s) was not found", name); + return RES_TYPE::ERR_NOT_FOUND; + } + + auto iter = std::find(_pagePool.begin(), _pagePool.end(), base); + + if (iter == _pagePool.end()) { + PAGE_LOG_ERROR("Page(%s) was not found in PagePool", name); + return RES_TYPE::ERR_NOT_FOUND; + } + + _pagePool.erase(iter); + + PAGE_LOG_INFO("Unregister OK"); + return RES_TYPE::OK; +} + +PageBase* PageManager::getStackTop() +{ + return _pageStack.empty() ? nullptr : _pageStack.top(); +} + +PageBase* PageManager::getStackTopAfter() +{ + PageBase* top = getStackTop(); + + if (!top) { + return nullptr; + } + + _pageStack.pop(); + + PageBase* topAfter = getStackTop(); + + _pageStack.push(top); + + return topAfter; +} + +void PageManager::clearStack(bool keepBottom) +{ + while (1) { + PageBase* top = getStackTop(); + + if (!top) { + PAGE_LOG_INFO("Page stack is empty, breaking..."); + break; + } + + PageBase* topAfter = getStackTopAfter(); + + if (!topAfter) { + if (keepBottom) { + _pagePrev = top; + PAGE_LOG_INFO("Keep page stack bottom(%s), breaking...", top->_name); + break; + } else { + _pagePrev = nullptr; + } + } + + fourceUnload(top); + + _pageStack.pop(); + } + PAGE_LOG_INFO("Stack clear done"); +} + +const char* PageManager::getPagePrevName() +{ + return _pagePrev ? _pagePrev->_name : PM_EMPTY_PAGE_NAME; +} + +void PageManager::setEventCallback(EVENT_CALLBACK callback, void* userData) +{ + _eventCallback = callback; + _eventUserData = userData; +} + +PageManager::RES_TYPE PageManager::sendEvent(EVENT_TYPE eventType, void* param) +{ + if (!_eventCallback) { + return RES_TYPE::OK; + } + + EVENT event(eventType, param, _eventUserData); + return _eventCallback(&event); +} diff --git a/x_track/src/Frameworks/PageManager/PageManager.h b/x_track/src/Frameworks/PageManager/PageManager.h new file mode 100644 index 0000000000000000000000000000000000000000..0ca4400bc06063c2da6644922114f605218db1c2 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageManager.h @@ -0,0 +1,487 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __PAGE_MANAGER_H +#define __PAGE_MANAGER_H + +#include "PageBase.h" +#include "PageDef.h" +#include "PageFactory.h" +#include <stack> +#include <vector> + +class PageManager { + friend class PageBase; + +public: + enum class EVENT_TYPE { + PAGE_STATE_CHANGED, /* param: PageBase::STATE */ + PAGE_PUSH, /* param: const char* */ + PAGE_POP, /* param: None */ + PAGE_REPLACE, /* param: const char* */ + PAGE_BACK_HOME, /* param: None */ + }; + + enum class RES_TYPE { + OK, + STOP_PROCESS, + ERR_NOT_FOUND, + ERR_DUPLICATE, + ERR_BUSY, + ERR_PARAM, + ERR_OPERATION, + ERR_UNKNOWN, + }; + + struct EVENT { + EVENT(EVENT_TYPE t, void* p, void* u) + : type(t) + , param(p) + , userData(u) + { + } + EVENT_TYPE type; + void* param; + void* userData; + }; + + typedef RES_TYPE (*EVENT_CALLBACK)(EVENT* event); + +public: + PageManager(PageFactory* factory = nullptr); + ~PageManager(); + + /** + * @brief Install the page, and register the page to the page pool + * @param className: The class name of the page + * @param appName: Page application name, no duplicates allowed + * @retval Return true if successful + */ + RES_TYPE install(const char* className, const char* appName); + + /** + * @brief Uninstall page + * @param appName: Page application name, no duplicates allowed + * @retval Return true if the uninstallation is successful + */ + RES_TYPE uninstall(const char* appName); + + /** + * @brief Register the page to the page pool + * @param name: Page application name, duplicate registration is not allowed + * @retval Return true if the registration is successful + */ + RES_TYPE registerPage(PageBase* base, const char* name); + + /** + * @brief Log out the page from the page pool + * @param name: Page application name + * @retval Return true if the logout is successful + */ + RES_TYPE unregisterPage(const char* name); + + /** + * @brief Enter a new page, replace the old page + * @param name: The name of the page to enter + * @param param: Parameters passed to the new page + * @retval Return true if successful + */ + RES_TYPE replace(const char* name, const PageBase::PARAM* param = nullptr); + + /** + * @brief Enter a new page, the old page is pushed onto the stack + * @param name: The name of the page to enter + * @param param: Parameters passed to the new page + * @retval Return true if successful + */ + RES_TYPE push(const char* name, const PageBase::PARAM* param = nullptr); + + /** + * @brief Pop the current page + * @param None + * @retval Return true if successful + */ + RES_TYPE pop(); + + /** + * @brief Back to the main page (the page at the bottom of the stack) + * @param None + * @retval Return true if successful + */ + RES_TYPE backHome(); + + /** + * @brief Get the name of the previous page + * @param None + * @retval The name of the previous page, if it does not exist, return PM_EMPTY_PAGE_NAME + */ + const char* getPagePrevName(); + + /** + * @brief Get page stack depth + * @param None + * @retval The depth of the page stack + */ + size_t getStackDepth() + { + return _pageStack.size(); + } + + /** + * @brief Set global animation properties + * @param anim: Animation type + * @param time: Animation duration + * @param path: Animation curve + * @retval None + */ + void setGlobalLoadAnim( + PAGE_ANIM anim, + uint32_t time = PAGE_ANIM_TIME_DEFAULT, + lv_anim_path_cb_t path = PAGE_ANIM_PATH_DEFAULT); + + /** + * @brief Set the root parent of the page + * @param par: The parent of the root, if it is nullptr, the parent is lv_scr_act() + * @retval None + */ + void setRootParent(lv_obj_t* par) + { + _rootParent = par; + } + + /** + * @brief Get the root parent of the page + * @param None + * @retval The parent of the root + */ + lv_obj_t* getRootParent() + { + return (_rootParent ? _rootParent : lv_scr_act()); + } + + /** + * @brief Set the default style of the root + * @param style: The default style of the root + * @retval None + */ + void setRootDefaultStyle(lv_style_t* style) + { + _rootDefaultStyle = style; + } + + /** + * @brief Set the top layer of the page + * @param obj: The top layer of the page + * @retval None + */ + void setLayerTop(lv_obj_t* obj) + { + _layerTop = obj; + } + + /** + * @brief Get the top layer of the page + * @param None + * @retval The top layer of the page + */ + lv_obj_t* getLayerTop() + { + return _layerTop ? _layerTop : lv_layer_top(); + } + + /** + * @brief Set the event callback + * @param callback: Event callback + * @param userData: User data + * @retval None + */ + void setEventCallback(EVENT_CALLBACK callback, void* userData); + +private: + /* Animation switching param */ + struct ANIM_PARAM { + ANIM_PARAM() + : enter { 0 } + , exit { 0 } + + { + } + /* As the entered party */ + struct + { + int32_t start; + int32_t end; + } enter; + + /* As the exited party */ + struct + { + int32_t start; + int32_t end; + } exit; + }; + + /* Page loading animation properties */ + struct LOAD_ANIM_ATTR { + LOAD_ANIM_ATTR() + : setter(nullptr) + , getter(nullptr) + { + } + void (*setter)(void*, int32_t); + int32_t (*getter)(void*); + ANIM_PARAM push; + ANIM_PARAM pop; + }; + +private: + /* Page factory */ + PageFactory* _factory; + + /* Page count */ + uint16_t _pageCnt; + + /* Page pool */ + std::vector<PageBase*> _pagePool; + + /* Page stack */ + std::stack<PageBase*> _pageStack; + + /* Previous page */ + PageBase* _pagePrev; + + /* The current page */ + PageBase* _pageCurrent; + + /* Page animation status */ + struct + { + bool isSwitchReq; // Has switch request + bool isBusy; // Is switching + bool isEntering; // Is in entering action + + PageBase::ANIM_ATTR current; // Current animation properties + PageBase::ANIM_ATTR global; // global animation properties + } _animState; + + /* Root */ + lv_obj_t* _rootParent; + lv_style_t* _rootDefaultStyle; + + /* Top layer */ + lv_obj_t* _layerTop; + + /* Event */ + EVENT_CALLBACK _eventCallback; + void* _eventUserData; + +private: + /** + * @brief Search pages in the page pool + * @param name: Page name + * @retval A pointer to the base class of the page, or nullptr if not found + */ + PageBase* findPageInPool(const char* name); + + /** + * @brief Search pages in the page stack + * @param name: Page name + * @retval A pointer to the base class of the page, or nullptr if not found + */ + PageBase* findPageInStack(const char* name); + + /** + * @brief Get the top page of the page stack + * @param None + * @retval A pointer to the base class of the page + */ + PageBase* getStackTop(); + + /** + * @brief Get the page below the top of the page stack + * @param None + * @retval A pointer to the base class of the page + */ + PageBase* getStackTopAfter(); + + /** + * @brief Clear the page stack and end the life cycle of all pages in the page stack + * @param keepBottom: Whether to keep the bottom page of the stack + * @retval None + */ + void clearStack(bool keepBottom = false); + + /** + * @brief Force the end of the life cycle of the page without animation + * @param base: Pointer to the page being executed + * @retval Return true if successful + */ + RES_TYPE fourceUnload(PageBase* base); + + /** + * @brief Get page loading animation properties + * @param anim: Animation type + * @param attr: Pointer to attribute + * @retval Whether the acquisition is successful + */ + RES_TYPE getLoadAnimAttr(PAGE_ANIM anim, LOAD_ANIM_ATTR* attr); + + /** + * @brief Set animation default parameters + * @param a: Pointer to animation + * @retval None + */ + void animDefaultInit(lv_anim_t* a); + + /** + * @brief Get the current page loading animation properties + * @param attr: Pointer to attribute + * @retval Whether the acquisition is successful + */ + RES_TYPE getCurrentLoadAnimAttr(LOAD_ANIM_ATTR* attr) + { + return getLoadAnimAttr(getCurrentLoadAnimType(), attr); + } + + /** + * @brief Get the current page loading animation type + * @param None + * @retval The current page loading animation type + */ + PAGE_ANIM getCurrentLoadAnimType() + { + return _animState.current.type; + } + + /** + * @brief Page switching + * @param newNode: Pointer to new page + * @param isEnterAct: Whether it is a ENTER action + * @param param: Parameters passed to the new page + * @retval Return true if successful + */ + RES_TYPE switchTo(PageBase* base, bool isEnterAct, const PageBase::PARAM* param = nullptr); + + /** + * @brief PPage switching animation execution end callback + * @param a: Pointer to animation + * @retval None + */ + static void onSwitchAnimFinish(lv_anim_t* a); + + /** + * @brief Create page switching animation + * @param a: Point to the animated page + * @retval None + */ + void switchAnimCreate(PageBase* base); + + /** + * @brief Update current animation properties, apply page custom animation + * @param base: Pointer to page + * @retval None + */ + void switchAnimTypeUpdate(PageBase* base); + + /** + * @brief Page switching request check + * @param None + * @retval Return true if all pages are executed + */ + RES_TYPE switchReqCheck(); + + /** + * @brief Check if the page switching animation is being executed + * @param None + * @retval Return true if it is executing + */ + RES_TYPE switchAnimStateCheck(); + + /** + * @brief Page loading status + * @param base: Pointer to the updated page + * @retval Next state + */ + PageBase::STATE stateLoad(PageBase* base); + + /** + * @brief The page is about to show the status + * @param base: Pointer to the updated page + * @retval Next state + */ + PageBase::STATE stateWillAppear(PageBase* base); + + /** + * @brief The status of the page display + * @param base: Pointer to the updated page + * @retval Next state + */ + PageBase::STATE stateDidAppear(PageBase* base); + + /** + * @brief The page is about to disappear + * @param base: Pointer to the updated page + * @retval Next state + */ + PageBase::STATE stateWillDisappear(PageBase* base); + + /** + * @brief Page disappeared end state + * @param base: Pointer to the updated page + * @retval Next state + */ + PageBase::STATE stateDidDisappear(PageBase* base); + + /** + * @brief Page unload complete + * @param base: Pointer to the updated page + * @retval Next state + */ + PageBase::STATE stateUnload(PageBase* base); + + /** + * @brief Update page state machine + * @param base: Pointer to the updated page + * @retval None + */ + void stateNext(PageBase* base); + + /** + * @brief Get the current state of the page + * @param None + * @retval The current state of the page + */ + PageBase::STATE getState() + { + return _pageCurrent->_context.state; + } + + /** + * @brief Send event + * @param eventType: Event type + * @param param: Event parameters + * @retval None + */ + RES_TYPE sendEvent(EVENT_TYPE eventType, void* param = nullptr); +}; + +#endif /* __PAGE_BASE_H */ diff --git a/x_track/src/Frameworks/PageManager/PageManagerAnim.cpp b/x_track/src/Frameworks/PageManager/PageManagerAnim.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4429e675bfb650b90ff8d6461b403b83f6bfc5b3 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageManagerAnim.cpp @@ -0,0 +1,191 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PageLog.h" +#include "PageManager.h" + +PageManager::RES_TYPE PageManager::getLoadAnimAttr(PAGE_ANIM anim, LOAD_ANIM_ATTR* attr) +{ + lv_obj_t* rootParent = getRootParent(); + lv_obj_update_layout(rootParent); + lv_coord_t hor = lv_obj_get_width(rootParent); + lv_coord_t ver = lv_obj_get_height(rootParent); + + switch (anim) { + case PAGE_ANIM::OVER_LEFT: + attr->push.enter.start = hor; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = 0; + + attr->pop.enter.start = 0; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = hor; + break; + + case PAGE_ANIM::OVER_RIGHT: + attr->push.enter.start = -hor; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = 0; + + attr->pop.enter.start = 0; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = -hor; + break; + + case PAGE_ANIM::OVER_TOP: + attr->push.enter.start = ver; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = 0; + + attr->pop.enter.start = 0; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = ver; + break; + + case PAGE_ANIM::OVER_BOTTOM: + attr->push.enter.start = -ver; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = 0; + + attr->pop.enter.start = 0; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = -ver; + break; + + case PAGE_ANIM::MOVE_LEFT: + attr->push.enter.start = hor; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = -hor; + + attr->pop.enter.start = -hor; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = hor; + break; + + case PAGE_ANIM::MOVE_RIGHT: + attr->push.enter.start = -hor; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = hor; + + attr->pop.enter.start = hor; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = -hor; + break; + + case PAGE_ANIM::MOVE_TOP: + attr->push.enter.start = ver; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = -ver; + + attr->pop.enter.start = -ver; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = ver; + break; + + case PAGE_ANIM::MOVE_BOTTOM: + attr->push.enter.start = -ver; + attr->push.enter.end = 0; + attr->push.exit.start = 0; + attr->push.exit.end = ver; + + attr->pop.enter.start = ver; + attr->pop.enter.end = 0; + attr->pop.exit.start = 0; + attr->pop.exit.end = -ver; + break; + + case PAGE_ANIM::FADE_ON: + attr->push.enter.start = LV_OPA_TRANSP; + attr->push.enter.end = LV_OPA_COVER; + attr->push.exit.start = LV_OPA_COVER; + attr->push.exit.end = LV_OPA_COVER; + + attr->pop.enter.start = LV_OPA_COVER; + attr->pop.enter.end = LV_OPA_COVER; + attr->pop.exit.start = LV_OPA_COVER; + attr->pop.exit.end = LV_OPA_TRANSP; + break; + + case PAGE_ANIM::NONE: + /* Use default NONE */ + break; + + default: + PAGE_LOG_ERROR("Load anim type error: %d", anim); + return RES_TYPE::ERR_PARAM; + } + + /* Determine the setter and getter of the animation */ + switch (anim) { + case PAGE_ANIM::OVER_LEFT: + case PAGE_ANIM::OVER_RIGHT: + case PAGE_ANIM::MOVE_LEFT: + case PAGE_ANIM::MOVE_RIGHT: + attr->setter = [](void* obj, int32_t v) { + lv_obj_set_x((lv_obj_t*)obj, v); + }; + attr->getter = [](void* obj) { + return (int32_t)lv_obj_get_x((lv_obj_t*)obj); + }; + break; + + case PAGE_ANIM::OVER_TOP: + case PAGE_ANIM::OVER_BOTTOM: + case PAGE_ANIM::MOVE_TOP: + case PAGE_ANIM::MOVE_BOTTOM: + attr->setter = [](void* obj, int32_t v) { + lv_obj_set_y((lv_obj_t*)obj, v); + }; + attr->getter = [](void* obj) { + return (int32_t)lv_obj_get_y((lv_obj_t*)obj); + }; + break; + + case PAGE_ANIM::FADE_ON: + attr->setter = [](void* obj, int32_t v) { + lv_obj_set_style_opa((lv_obj_t*)obj, (lv_opa_t)v, LV_PART_MAIN); + }; + attr->getter = [](void* obj) { + return (int32_t)lv_obj_get_style_opa((lv_obj_t*)obj, LV_PART_MAIN); + }; + break; + + default: + break; + } + + return RES_TYPE::OK; +} diff --git a/x_track/src/Frameworks/PageManager/PageManagerRouter.cpp b/x_track/src/Frameworks/PageManager/PageManagerRouter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a8ecac23dde55224c84d1f8a130ceefbc351cd0 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageManagerRouter.cpp @@ -0,0 +1,447 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PageLog.h" +#include "PageManager.h" +#include <string.h> + +PageManager::RES_TYPE PageManager::replace(const char* name, const PageBase::PARAM* param) +{ + /* Precheck event hook */ + auto res = sendEvent(EVENT_TYPE::PAGE_REPLACE, (void*)name); + if (res != RES_TYPE::OK) { + return res; + } + + /* Check whether the animation of switching pages is being executed */ + res = switchAnimStateCheck(); + if (res != RES_TYPE::OK) { + return res; + } + + /* Check whether the stack is repeatedly pushed */ + if (findPageInStack(name) != nullptr) { + PAGE_LOG_ERROR("Page(%s) was multi push", name); + return RES_TYPE::ERR_DUPLICATE; + } + + /* Check if the page is registered in the page pool */ + PageBase* base = findPageInPool(name); + + if (!base) { + PAGE_LOG_ERROR("Page(%s) was not install", name); + return RES_TYPE::ERR_NOT_FOUND; + } + + /* Get the top page of the stack */ + PageBase* top = getStackTop(); + + if (!top) { + PAGE_LOG_ERROR("Stack top is NULL"); + return RES_TYPE::ERR_OPERATION; + } + + /* Force disable cache */ + top->_context.isCached = false; + + /* Synchronous automatic cache configuration */ + base->_context.isDisableAutoCache = base->_context.reqDisableAutoCache; + + /* Remove current page */ + _pageStack.pop(); + + /* Push into the stack */ + _pageStack.push(base); + + PAGE_LOG_INFO("Page(%s) replace Page(%s) (param = %p)", name, top->_name, param); + + /* Page switching execution */ + return switchTo(base, true, param); +} + +PageManager::RES_TYPE PageManager::push(const char* name, const PageBase::PARAM* param) +{ + /* Precheck event hook */ + auto res = sendEvent(EVENT_TYPE::PAGE_PUSH, (void*)name); + if (res != RES_TYPE::OK) { + return res; + } + + /* Check whether the animation of switching pages is being executed */ + res = switchAnimStateCheck(); + if (res != RES_TYPE::OK) { + return res; + } + + /* Check whether the stack is repeatedly pushed */ + if (findPageInStack(name) != nullptr) { + PAGE_LOG_ERROR("Page(%s) was multi push", name); + return RES_TYPE::ERR_DUPLICATE; + } + + /* Check if the page is registered in the page pool */ + PageBase* base = findPageInPool(name); + + if (!base) { + PAGE_LOG_ERROR("Page(%s) was not install", name); + return RES_TYPE::ERR_NOT_FOUND; + } + + /* Synchronous automatic cache configuration */ + base->_context.isDisableAutoCache = base->_context.reqDisableAutoCache; + + /* Push into the stack */ + _pageStack.push(base); + + PAGE_LOG_INFO("Page(%s) push >> [Screen] (param = %p)", name, param); + + /* Page switching execution */ + return switchTo(base, true, param); +} + +PageManager::RES_TYPE PageManager::pop() +{ + /* Precheck event hook */ + auto res = sendEvent(EVENT_TYPE::PAGE_POP); + if (res != RES_TYPE::OK) { + return res; + } + + /* Check whether the animation of switching pages is being executed */ + res = switchAnimStateCheck(); + if (res != RES_TYPE::OK) { + return res; + } + + if (_pageStack.size() <= 1) { + PAGE_LOG_WARN("Bottom of stack, cat't pop"); + return RES_TYPE::ERR_OPERATION; + } + + /* Get the top page of the stack */ + PageBase* top = getStackTop(); + LV_ASSERT_NULL(top); + if (!top) { + PAGE_LOG_ERROR("Stack top is NULL"); + return RES_TYPE::ERR_OPERATION; + } + + /* Whether to turn off automatic cache */ + if (!top->_context.isDisableAutoCache) { + PAGE_LOG_INFO("Page(%s) has auto cache, cache disabled", top->_name); + top->_context.isCached = false; + } + + PAGE_LOG_INFO("Page(%s) pop << [Screen]", top->_name); + + /* Page popup */ + _pageStack.pop(); + + /* Get the next page */ + top = getStackTop(); + + /* Page switching execution */ + return switchTo(top, false, nullptr); +} + +PageManager::RES_TYPE PageManager::switchTo(PageBase* newNode, bool isEnterAct, const PageBase::PARAM* param) +{ + if (!newNode) { + PAGE_LOG_ERROR("newNode is nullptr"); + return RES_TYPE::ERR_PARAM; + } + + /* Whether page switching has been requested */ + if (_animState.isSwitchReq) { + PAGE_LOG_WARN("Page switch busy, reqire(%s) is ignore", newNode->_name); + return RES_TYPE::ERR_BUSY; + } + + _animState.isSwitchReq = true; + + /* Is there a parameter to pass */ + if (param != nullptr) { + PAGE_LOG_INFO("param is detect, %s >> param(%p) >> %s", getPagePrevName(), param, newNode->_name); + + void* buffer = nullptr; + + if (!newNode->_context.param.ptr) { + buffer = lv_malloc(param->size); + LV_ASSERT_MALLOC(buffer); + if (!buffer) { + PAGE_LOG_ERROR("param malloc failed"); + } else { + PAGE_LOG_INFO("param(%p) malloc[%d]", buffer, param->size); + } + } else if (newNode->_context.param.size == param->size) { + buffer = newNode->_context.param.ptr; + PAGE_LOG_INFO("param(%p) is exist", buffer); + } + + if (buffer != nullptr) { + memcpy(buffer, param->ptr, param->size); + PAGE_LOG_INFO("param memcpy[%d] %p >> %p", param->size, param->ptr, buffer); + newNode->_context.param.ptr = buffer; + newNode->_context.param.size = param->size; + } + } + + /* Record current page */ + _pageCurrent = newNode; + + /* If the current page has a cache */ + if (_pageCurrent->_context.isCached) { + /* Direct display, no need to load */ + PAGE_LOG_INFO("Page(%s) has cached, appear driectly", _pageCurrent->_name); + _pageCurrent->_context.state = PageBase::STATE::WILL_APPEAR; + } else { + /* Load page */ + _pageCurrent->_context.state = PageBase::STATE::LOAD; + } + + if (_pagePrev != nullptr) { + _pagePrev->_context.anim.isEnter = false; + } + + _pageCurrent->_context.anim.isEnter = true; + + _animState.isEntering = isEnterAct; + + if (_animState.isEntering) { + /* Update the animation configuration according to the current page */ + switchAnimTypeUpdate(_pageCurrent); + } + + /* Update the state machine of the previous page */ + stateNext(_pagePrev); + + /* Update the state machine of the current page */ + stateNext(_pageCurrent); + + /* Since page creation takes a certain amount of time, + * the animation is created uniformly after the state machine is executed, + * and the animation start and end times are aligned. + */ + switchAnimCreate(_pagePrev); + switchAnimCreate(_pageCurrent); + + /* Move the layer, move the new page to the front */ + if (_animState.isEntering) { + PAGE_LOG_INFO("Page ENTER is detect, move Page(%s) to foreground", _pageCurrent->_name); + if (_pagePrev) + lv_obj_move_foreground(_pagePrev->_root); + lv_obj_move_foreground(_pageCurrent->_root); + } else { + PAGE_LOG_INFO("Page EXIT is detect, move Page(%s) to foreground", getPagePrevName()); + lv_obj_move_foreground(_pageCurrent->_root); + if (_pagePrev) + lv_obj_move_foreground(_pagePrev->_root); + } + return RES_TYPE::OK; +} + +PageManager::RES_TYPE PageManager::fourceUnload(PageBase* base) +{ + if (!base) { + PAGE_LOG_ERROR("Page is nullptr, Unload failed"); + return RES_TYPE::ERR_PARAM; + } + + PAGE_LOG_INFO("Page(%s) Fource unloading...", base->_name); + + if (base->_context.state == PageBase::STATE::ACTIVITY) { + PAGE_LOG_INFO("Page state is ACTIVITY, Disappearing..."); + base->onViewWillDisappear(); + base->onViewDidDisappear(); + } + + base->_context.state = stateUnload(base); + + return RES_TYPE::OK; +} + +PageManager::RES_TYPE PageManager::backHome() +{ + /* Precheck event hook */ + auto res = sendEvent(EVENT_TYPE::PAGE_BACK_HOME); + if (res != RES_TYPE::OK) { + return res; + } + + /* Check whether the animation of switching pages is being executed */ + res = switchAnimStateCheck(); + if (res != RES_TYPE::OK) { + return res; + } + + clearStack(true); + + _pagePrev = nullptr; + + PageBase* home = getStackTop(); + + return switchTo(home, false); +} + +PageManager::RES_TYPE PageManager::switchAnimStateCheck() +{ + if (_animState.isSwitchReq || _animState.isBusy) { + PAGE_LOG_WARN( + "Page switch busy[AnimState.isSwitchReq = %d," + "AnimState.isBusy = %d]," + "request ignored", + _animState.isSwitchReq, + _animState.isBusy); + return RES_TYPE::ERR_BUSY; + } + + return RES_TYPE::OK; +} + +PageManager::RES_TYPE PageManager::switchReqCheck() +{ + auto res = RES_TYPE::ERR_BUSY; + bool lastNodeBusy = _pagePrev && _pagePrev->_context.anim.isBusy; + + if (!_pageCurrent->_context.anim.isBusy && !lastNodeBusy) { + PAGE_LOG_INFO("----Page switch was all finished----"); + _animState.isSwitchReq = false; + res = RES_TYPE::OK; + _pagePrev = _pageCurrent; + } else { + if (_pageCurrent->_context.anim.isBusy) { + PAGE_LOG_WARN("Page PageCurrent(%s) is busy", _pageCurrent->_name); + } else { + PAGE_LOG_WARN("Page PagePrev(%s) is busy", getPagePrevName()); + } + } + + return res; +} + +void PageManager::onSwitchAnimFinish(lv_anim_t* a) +{ + auto base = (PageBase*)lv_anim_get_user_data(a); + auto manager = base->_manager; + + PAGE_LOG_INFO("Page(%s) anim finish", base->_name); + + manager->stateNext(base); + base->_context.anim.isBusy = false; + auto res = manager->switchReqCheck(); + + if (!manager->_animState.isEntering && res == RES_TYPE::OK) { + manager->switchAnimTypeUpdate(manager->_pageCurrent); + } +} + +void PageManager::switchAnimCreate(PageBase* base) +{ + if (!base) { + return; + } + + LOAD_ANIM_ATTR animAttr; + if (getCurrentLoadAnimAttr(&animAttr) != RES_TYPE::OK) { + return; + } + + lv_anim_t a; + animDefaultInit(&a); + lv_anim_set_user_data(&a, base); + lv_anim_set_var(&a, base->_root); + lv_anim_set_ready_cb(&a, onSwitchAnimFinish); + lv_anim_set_exec_cb(&a, animAttr.setter); + + int32_t start = 0; + + if (animAttr.getter) { + start = animAttr.getter(base->_root); + } + + if (_animState.isEntering) { + if (base->_context.anim.isEnter) { + lv_anim_set_values( + &a, + animAttr.push.enter.start, + animAttr.push.enter.end); + } else /* Exit */ + { + lv_anim_set_values( + &a, + start, + animAttr.push.exit.end); + } + } else /* Pop */ + { + if (base->_context.anim.isEnter) { + lv_anim_set_values( + &a, + animAttr.pop.enter.start, + animAttr.pop.enter.end); + } else /* Exit */ + { + lv_anim_set_values( + &a, + start, + animAttr.pop.exit.end); + } + } + + lv_anim_start(&a); + base->_context.anim.isBusy = true; +} + +void PageManager::setGlobalLoadAnim(PAGE_ANIM anim, uint32_t time, lv_anim_path_cb_t path) +{ + _animState.global.type = anim; + _animState.global.duration = time; + _animState.global.path = path; + + PAGE_LOG_INFO("Set global load anim type = %d", anim); +} + +void PageManager::switchAnimTypeUpdate(PageBase* base) +{ + if (base->_context.anim.attr.type == PAGE_ANIM::GLOBAL) { + PAGE_LOG_INFO( + "Page(%s) anim.type was not set, use AnimState.global.type = %d", + base->_name, + _animState.global.type); + _animState.current = _animState.global; + } else { + PAGE_LOG_INFO( + "Page(%s) custom anim.type set = %d", + base->_name, + base->_context.anim.attr.type); + _animState.current = base->_context.anim.attr; + } +} + +void PageManager::animDefaultInit(lv_anim_t* a) +{ + lv_anim_init(a); + + uint32_t time = (getCurrentLoadAnimType() == PAGE_ANIM::NONE) ? 0 : _animState.current.duration; + lv_anim_set_time(a, time); + lv_anim_set_path_cb(a, _animState.current.path); +} diff --git a/x_track/src/Frameworks/PageManager/PageManagerState.cpp b/x_track/src/Frameworks/PageManager/PageManagerState.cpp new file mode 100644 index 0000000000000000000000000000000000000000..154edd8223916544a511279821c45726dec649e0 --- /dev/null +++ b/x_track/src/Frameworks/PageManager/PageManagerState.cpp @@ -0,0 +1,190 @@ +/* + * MIT License + * Copyright (c) 2021 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PageLog.h" +#include "PageManager.h" + +void PageManager::stateNext(PageBase* base) +{ + if (!base) { + return; + } + + sendEvent(EVENT_TYPE::PAGE_STATE_CHANGED, (void*)&base->_context.state); + + switch (base->_context.state) { + case PageBase::STATE::IDLE: + PAGE_LOG_INFO("Page(%s) state idle", base->_name); + break; + + case PageBase::STATE::LOAD: + base->_context.state = stateLoad(base); + stateNext(base); + break; + + case PageBase::STATE::WILL_APPEAR: + base->_context.state = stateWillAppear(base); + break; + + case PageBase::STATE::DID_APPEAR: + base->_context.state = stateDidAppear(base); + PAGE_LOG_INFO("Page(%s) state active", base->_name); + break; + + case PageBase::STATE::ACTIVITY: + PAGE_LOG_INFO("Page(%s) state active break", base->_name); + base->_context.state = PageBase::STATE::WILL_DISAPPEAR; + stateNext(base); + break; + + case PageBase::STATE::WILL_DISAPPEAR: + base->_context.state = stateWillDisappear(base); + break; + + case PageBase::STATE::DID_DISAPPEAR: + base->_context.state = stateDidDisappear(base); + if (base->_context.state == PageBase::STATE::UNLOAD) { + stateNext(base); + } + break; + + case PageBase::STATE::UNLOAD: + base->_context.state = stateUnload(base); + break; + + default: + PAGE_LOG_ERROR("Page(%s) state[%d] was NOT FOUND!", base->_name, base->_context.state); + break; + } +} + +PageBase::STATE PageManager::stateLoad(PageBase* base) +{ + PAGE_LOG_INFO("Page(%s) state load", base->_name); + + if (base->_root != nullptr) { + PAGE_LOG_ERROR("Page(%s) root must be nullptr", base->_name); + } + + lv_obj_t* parent = base->_manager->getRootParent(); + lv_obj_t* root_obj = lv_obj_create(parent); + + lv_obj_clear_flag(root_obj, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_user_data(root_obj, base); + + if (base->_context.backGestureDir != LV_DIR_NONE) { + lv_obj_remove_flag(root_obj, LV_OBJ_FLAG_GESTURE_BUBBLE); + lv_obj_add_event_cb( + root_obj, + [](lv_event_t* e) { + auto self = (PageBase*)lv_event_get_user_data(e); + auto dir = lv_indev_get_gesture_dir(lv_indev_active()); + if (dir == self->_context.backGestureDir) { + self->getManager()->pop(); + } + }, + LV_EVENT_GESTURE, + base); + } + + if (_rootDefaultStyle) { + lv_obj_add_style(root_obj, _rootDefaultStyle, LV_PART_MAIN); + } + + base->_root = root_obj; + base->onViewLoad(); + + base->onViewDidLoad(); + + if (base->_context.isDisableAutoCache) { + PAGE_LOG_INFO("Page(%s) disable auto cache, reqEnableCache = %d", base->_name, base->_context.reqEnableCache); + base->_context.isCached = base->_context.reqEnableCache; + } else { + PAGE_LOG_INFO("Page(%s) AUTO cached", base->_name); + base->_context.isCached = true; + } + + return PageBase::STATE::WILL_APPEAR; +} + +PageBase::STATE PageManager::stateWillAppear(PageBase* base) +{ + PAGE_LOG_INFO("Page(%s) state will appear", base->_name); + base->onViewWillAppear(); + lv_obj_clear_flag(base->_root, LV_OBJ_FLAG_HIDDEN); + return PageBase::STATE::DID_APPEAR; +} + +PageBase::STATE PageManager::stateDidAppear(PageBase* base) +{ + PAGE_LOG_INFO("Page(%s) state did appear", base->_name); + base->onViewDidAppear(); + return PageBase::STATE::ACTIVITY; +} + +PageBase::STATE PageManager::stateWillDisappear(PageBase* base) +{ + PAGE_LOG_INFO("Page(%s) state will disappear", base->_name); + base->onViewWillDisappear(); + return PageBase::STATE::DID_DISAPPEAR; +} + +PageBase::STATE PageManager::stateDidDisappear(PageBase* base) +{ + PAGE_LOG_INFO("Page(%s) state did disappear", base->_name); + lv_obj_add_flag(base->_root, LV_OBJ_FLAG_HIDDEN); + base->onViewDidDisappear(); + if (base->_context.isCached) { + PAGE_LOG_INFO("Page(%s) has cached", base->_name); + return PageBase::STATE::WILL_APPEAR; + } else { + return PageBase::STATE::UNLOAD; + } +} + +PageBase::STATE PageManager::stateUnload(PageBase* base) +{ + PAGE_LOG_INFO("Page(%s) state unload", base->_name); + if (!base->_root) { + PAGE_LOG_WARN("Page is unloaded!"); + return PageBase::STATE::IDLE; + } + + base->onViewUnload(); + if (base->_context.param.ptr != nullptr && base->_context.param.size != 0) { + PAGE_LOG_INFO("Page(%s) free param(%p)[%d]", base->_name, base->_context.param.ptr, base->_context.param.size); + lv_free(base->_context.param.ptr); + base->_context.param.ptr = nullptr; + base->_context.param.size = 0; + } + + /* Prevent another timer from modifying the style during async deletion */ + lv_obj_clean(base->_root); + lv_obj_remove_style_all(base->_root); + + /* Delete after the end of the root animation life cycle */ + lv_obj_del_async(base->_root); + base->_root = nullptr; + base->_context.isCached = false; + base->onViewDidUnload(); + return PageBase::STATE::IDLE; +} diff --git a/x_track/src/Frameworks/ResourceManager/RM_Log.h b/x_track/src/Frameworks/ResourceManager/RM_Log.h new file mode 100644 index 0000000000000000000000000000000000000000..39052383257a95952e5deb79ec74b800171dd5c3 --- /dev/null +++ b/x_track/src/Frameworks/ResourceManager/RM_Log.h @@ -0,0 +1,40 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __RM_LOG_H +#define __RM_LOG_H + +#define RESOURCE_MANAGER_USE_LOG 1 + +#if !defined(ARDUINO) && RESOURCE_MANAGER_USE_LOG +#include <stdio.h> +# define _RM_LOG(format, ...) printf("[RM]" format "\r\n", ##__VA_ARGS__) +# define RM_LOG_INFO(format, ...) //_RM_LOG("[Info] " format, ##__VA_ARGS__) +# define RM_LOG_WARN(format, ...) _RM_LOG("[Warn] " format, ##__VA_ARGS__) +# define RM_LOG_ERROR(format, ...) _RM_LOG("[Error] " format, ##__VA_ARGS__) +#else +# define RM_LOG_INFO(...) +# define RM_LOG_WARN(...) +# define RM_LOG_ERROR(...) +#endif + +#endif diff --git a/x_track/src/Frameworks/ResourceManager/ResourceManager.h b/x_track/src/Frameworks/ResourceManager/ResourceManager.h new file mode 100644 index 0000000000000000000000000000000000000000..ec047e9bf9f614f6008623c457f491963ea5a646 --- /dev/null +++ b/x_track/src/Frameworks/ResourceManager/ResourceManager.h @@ -0,0 +1,86 @@ +/* + * MIT License + * Copyright (c) 2021 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __RESOURCE_MANAGER_H +#define __RESOURCE_MANAGER_H + +#include <stddef.h> + +template <typename KEY_TYPE, typename VALUE_TYPE> +class ResourceManager { +public: + typedef struct { + KEY_TYPE key; + VALUE_TYPE value; + } KEY_PAIR; + + typedef bool (*COMPARE_CALLBACK)(KEY_TYPE key1, KEY_TYPE key2); + +public: + ResourceManager(KEY_PAIR* array, size_t size, COMPARE_CALLBACK compareCallback, VALUE_TYPE defaultValue) + : _array(array) + , _size(size) + , _compareCallback(compareCallback) + , _defaultValue(defaultValue) + { + } + ~ResourceManager() { } + + VALUE_TYPE* get(KEY_TYPE key) + { + for (size_t i = 0; i < _size; i++) { + if (_compareCallback(key, _array[i].key)) { + return &_array[i].value; + } + } + return &_defaultValue; + } + + bool set(KEY_TYPE key, VALUE_TYPE value) + { + for (size_t i = 0; i < _size; i++) { + if (_compareCallback(key, _array[i].key)) { + _array[i].value = value; + return true; + } + } + return false; + } + + void setDefault(VALUE_TYPE value) + { + _defaultValue = value; + } + + VALUE_TYPE getDefault() + { + return _defaultValue; + } + +private: + KEY_PAIR* _array; + size_t _size; + COMPARE_CALLBACK _compareCallback; + VALUE_TYPE _defaultValue; +}; + +#endif diff --git a/x_track/src/Frameworks/ResourceManager/ResourceManagerStatic.cpp b/x_track/src/Frameworks/ResourceManager/ResourceManagerStatic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87aa7e4f699fa39639d769298589e76d22a06b84 --- /dev/null +++ b/x_track/src/Frameworks/ResourceManager/ResourceManagerStatic.cpp @@ -0,0 +1,43 @@ +/* + * Created by W-Mai on 2022/10/17. + * + * MIT License + * Copyright (c) 2022 XCLZ STUDIO + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "ResourceManagerStatic.h" +#include <algorithm> +#include <cstring> + +template <typename KeyType, typename ValType, size_t NUM> +const ValType& ResourceManagerStatic<KeyType, ValType, NUM>::get(KeyType key) +{ + using KeyValType = std::pair<KeyType, ValType>; + auto res = std::find_if(__pool_, __pool_ + NUM, [&key](KeyValType node) { + return strcmp(node.first, key) == 0; + }); + + if (res == __pool_ + NUM) { + return __defaultValue_; + } else { + return res->second; + } +} diff --git a/x_track/src/Frameworks/ResourceManager/ResourceManagerStatic.h b/x_track/src/Frameworks/ResourceManager/ResourceManagerStatic.h new file mode 100644 index 0000000000000000000000000000000000000000..3976eb70377fb330ef911dd4dd1cac4c82e1b796 --- /dev/null +++ b/x_track/src/Frameworks/ResourceManager/ResourceManagerStatic.h @@ -0,0 +1,76 @@ +/* + * Created by W-Mai on 2022/10/15. + * + * MIT License + * Copyright (c) 2022 XCLZ STUDIO + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __RESOURCE_MANAGER_STATIC_H +#define __RESOURCE_MANAGER_STATIC_H + +#include <utility> +#include <vector> +#include <cstddef> + +template <typename KeyType, typename ValType, size_t NUM> +class ResourceManagerStatic { +public: + using KeyValueType = std::pair<KeyType, ValType>; + +private: + KeyValueType* __pool_; + + ValType __defaultValue_; + +public: + explicit ResourceManagerStatic(KeyValueType* init) + { + __pool_ = init; + } + /** + * @brief Set default resources + * @param defaultValue: Value to the default resource + */ + void setDefaultValue(ValType&& defaultValue) + { + __defaultValue_ = { + std::forward<ValType>(defaultValue) + }; + } + + /** + * @brief Get default resources + * @retval Value to the default resource + */ + const ValType& getDefaultValue() + { + return __defaultValue_; + } + + /** + * @brief Get resource associated with key + * @param key: Resource key + * @return Value resource associated with key + */ + const ValType& get(KeyType key); +}; + +#endif // __RESOURCE_MANAGER_STATIC_H diff --git a/x_track/src/Vendor/Simulator/HAL/HAL.cpp b/x_track/src/Vendor/Simulator/HAL/HAL.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55b96a0091348efa5ba458ce39d7903479889697 --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL.cpp @@ -0,0 +1,57 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" + +/* Import Device */ +#define HAL_DEF(name) extern DeviceObject DevObj_##name; +#include "HAL_DeviceTree.inc" +#undef HAL_DEF + +DeviceManager* HAL::Manager() +{ + /* Device Array */ + static DeviceObject* devObjArr[] = { +#define HAL_DEF(name) &(DevObj_##name), +#include "HAL_DeviceTree.inc" +#undef HAL_DEF + }; + + static DeviceManager manager(devObjArr, CM_ARRAY_SIZE(devObjArr)); + return &manager; +} + +void HAL::Init() +{ + HAL_Log_Init(); + HAL_LOG_INFO("begin"); + + Manager()->init([](DeviceManager* manager, DeviceObject* dev, int retval) { + if (retval < 0) { + HAL_LOG_ERROR("[%s] init fail: %d", dev->getName(), retval); + } else { + HAL_LOG_INFO("[%s] init success", dev->getName()); + } + }); + + HAL_LOG_INFO("end"); +} diff --git a/x_track/src/Vendor/Simulator/HAL/HAL.h b/x_track/src/Vendor/Simulator/HAL/HAL.h new file mode 100644 index 0000000000000000000000000000000000000000..713a219eb7f71bf2eb190091475eeef16daee77f --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL.h @@ -0,0 +1,30 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __HAL_H +#define __HAL_H + +#include "Service/HAL/HAL.h" +#include "Service/HAL/HAL_Log.h" +#include "Utils/CommonMacro/CommonMacro.h" + +#endif diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_Backlight.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_Backlight.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6d7cdfe7a5952d9353591a424b71869d0f07b58 --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_Backlight.cpp @@ -0,0 +1,105 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" + +#define BACKLIGHT_RESOLUTION 1000 + +namespace HAL { + +class Backlight : private DeviceObject { +public: + Backlight(const char* name) + : DeviceObject(name) + , _backlightValue(0) + { + } + +private: + int _backlightValue; + +private: + virtual int onInit(); + virtual int onRead(void* buffer, size_t size); + virtual int onWrite(const void* buffer, size_t size); + virtual int onIoctl(DeviceObject::IO_Cmd_t cmd, void* data); + int getValue(); + void setValue(int value); + void forceLit(); +}; + +int Backlight::onInit() +{ + setValue(0); + return DeviceObject::RES_OK; +} + +int Backlight::onRead(void* buffer, size_t size) +{ + if (size != sizeof(int)) { + return DeviceObject::RES_PARAM_ERROR; + } + *(int*)buffer = getValue(); + return sizeof(int); +} + +int Backlight::onWrite(const void* buffer, size_t size) +{ + if (size != sizeof(int)) { + return DeviceObject::RES_PARAM_ERROR; + } + setValue(*(int*)buffer); + return sizeof(int); +} + +int Backlight::onIoctl(DeviceObject::IO_Cmd_t cmd, void* data) +{ + int retval = DeviceObject::RES_UNKNOWN; + switch (cmd.full) { + case BACKLIGHT_IOCMD_FORCE_LIT: + forceLit(); + retval = DeviceObject::RES_OK; + break; + default: + break; + } + return retval; +} + +int Backlight::getValue() +{ + return _backlightValue; +} + +void Backlight::setValue(int value) +{ + CM_VALUE_LIMIT(value, 0, BACKLIGHT_RESOLUTION); + _backlightValue = value; +} + +void Backlight::forceLit() +{ +} + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(Backlight); diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_Clock.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_Clock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec3aad2da4a5829ba76bab28b01de393186222f5 --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_Clock.cpp @@ -0,0 +1,99 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" +#include <stdio.h> +#include <time.h> + +namespace HAL { + +class Clock : private DeviceObject { +public: + Clock(const char* name) + : DeviceObject(name) + { + } + +private: + virtual int onInit(); + virtual int onRead(void* buffer, size_t size); + virtual int onIoctl(DeviceObject::IO_Cmd_t cmd, void* data); + void getInfo(HAL::Clock_Info_t* info); + void calibrate(const HAL::Clock_Info_t* info); +}; + +int Clock::onInit() +{ + return DeviceObject::RES_OK; +} + +int Clock::onRead(void* buffer, size_t size) +{ + if (size != sizeof(HAL::Clock_Info_t)) { + return -1; + } + getInfo((HAL::Clock_Info_t*)buffer); + return sizeof(HAL::Clock_Info_t); +} + +int Clock::onIoctl(DeviceObject::IO_Cmd_t cmd, void* data) +{ + if (cmd.full != CLOCK_IOCMD_CALIBRATE) { + return -1; + } + + calibrate((HAL::Clock_Info_t*)data); + return DeviceObject::RES_OK; +} + +void Clock::getInfo(HAL::Clock_Info_t* info) +{ + struct tm* t; + time_t tt; + time(&tt); + t = localtime(&tt); + + info->year = t->tm_year + 1900; + info->month = t->tm_mon + 1; + info->day = t->tm_mday; + info->week = t->tm_wday; + info->hour = t->tm_hour; + info->minute = t->tm_min; + info->second = t->tm_sec; + info->millisecond = 0; +} + +void Clock::calibrate(const HAL::Clock_Info_t* info) +{ + HAL_LOG_INFO( + "Clock set: %04d-%02d-%02d %02d:%02d:%02d", + info->year, + info->month, + info->day, + info->hour, + info->minute, + info->second); +} + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(Clock); diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_DeviceTree.inc b/x_track/src/Vendor/Simulator/HAL/HAL_DeviceTree.inc new file mode 100644 index 0000000000000000000000000000000000000000..f723d1bb1f5de453807fdb653860214bbcac20b3 --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_DeviceTree.inc @@ -0,0 +1,30 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* HAL Device Tree Define */ + +HAL_DEF(Clock) +HAL_DEF(GNSS) +HAL_DEF(Power) +HAL_DEF(Backlight) +HAL_DEF(SdCard) diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_FaultHandle.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_FaultHandle.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e576e08c358f1c7a778634b3cc764cfc4688e074 --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_FaultHandle.cpp @@ -0,0 +1,69 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" +#include "Service/HAL/HAL_Assert.h" +#include "Version.h" +#include <stdlib.h> + +extern "C" { + +void HAL_Assert(const char* file, int line, const char* func, const char* expr) +{ + HAL_LOG_ERROR("Assert: %s:%d %s %s", file, line, func, expr); + HAL_Panic(); +} + +void HAL_Panic(void) +{ + HAL_LOG_ERROR("FXXK PANIC !!!"); + HAL_LOG_ERROR("Firmware: %s", VERSION_FIRMWARE_NAME); + HAL_LOG_ERROR("Software: %s", VERSION_SOFTWARE); + HAL_LOG_ERROR("Hardware: %s", VERSION_HARDWARE); + HAL_LOG_ERROR("Build Time: %s %s", __DATE__, __TIME__); + + exit(EXIT_FAILURE); +} + +} /* extern "C" */ + +namespace HAL { + +class FaultHandle : private DeviceObject { +public: + FaultHandle(const char* name) + : DeviceObject(name) + { + } + +private: + virtual int onInit(); +}; + +int FaultHandle::onInit() +{ + return DeviceObject::RES_OK; +} + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(FaultHandle); diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_GNSS.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_GNSS.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5419380c3432f8f93680991d5cfaeb578ca01f0a --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_GNSS.cpp @@ -0,0 +1,323 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "HAL.h" +#include "Utils/CommonMacro/CommonMacro.h" +#include "Utils/GPX_Parser/GPX_Parser.h" +#include "Utils/Geo/Geo.h" +#include "lvgl/lvgl.h" +#include <cstdlib> +#include <cstring> +#include <ctime> + +#define CONFIG_GPX_FILE_PATH RESOURCE_MAKE_PATH("/Track/TRK_EXAMPLE.gpx") +#define CONFIG_GPX_DELAY_INIT 5000 +#define CONFIG_RANDOM_GNSS 0 +#define CONFIG_NO_GNSS 0 + +namespace HAL { + +class GNSS : private DeviceObject { +public: + GNSS(const char* name) + : DeviceObject(name) + , _gnssInfo { 0 } + , _parser(parserAvaliable, parserReadByte, this) + , _file { 0 } + , _size { 0 } + , _prePoint { 0 } + , _isReset(false) + , _isUpdate(false) + { + _gnssInfo.longitude = CONFIG_GNSS_LONGITUDE_DEFAULT; + _gnssInfo.latitude = CONFIG_GNSS_LATITUDE_DEFAULT; + } + +private: + HAL::GNSS_Info_t _gnssInfo; + HAL::GNSS_GSV_Item_t _gsvItems[12]; + GPX_Parser _parser; + lv_fs_file_t _file; + uint32_t _size; + GPX_Parser::Point_t _prePoint; + bool _isReset; + bool _isUpdate; + +private: + virtual int onInit(); + virtual int onRead(void* buffer, size_t size); + virtual int onWrite(const void* buffer, size_t size); + virtual int onIoctl(DeviceObject::IO_Cmd_t cmd, void* data); + bool parserInit(); + void paserStart(); + void paserUpdate(); + static int parserReadByte(GPX_Parser* parser); + static int parserAvaliable(GPX_Parser* parser); + time_t makeTime(const GPX_Parser::Time_t* time); + double getDiffTime(const GPX_Parser::Time_t* time1, const GPX_Parser::Time_t* time2); +#if CONFIG_RANDOM_GNSS + void makeRandomGNSSInfo(HAL::GNSS_Info_t* gnssInfo); +#endif /* CONFIG_RANDOM_GNSS */ +}; + +int GNSS::onInit() +{ +#if !CONFIG_NO_GNSS + if (parserInit()) { + _gnssInfo.isVaild = true; + _gnssInfo.satellites = 10; + + /* Delay start GPX parser */ + lv_timer_t* timer = lv_timer_create( + [](lv_timer_t* tmr) { + auto ctx = (GNSS*)lv_timer_get_user_data(tmr); + ctx->paserStart(); + }, + CONFIG_GPX_DELAY_INIT, + this); + lv_timer_set_repeat_count(timer, 1); + } +#endif + + return DeviceObject::RES_OK; +} + +int GNSS::onRead(void* buffer, size_t size) +{ + if (size != sizeof(HAL::GNSS_Info_t)) { + return DeviceObject::RES_PARAM_ERROR; + } + + HAL::GNSS_Info_t* gnssInfo = (HAL::GNSS_Info_t*)buffer; + memset(gnssInfo, 0, sizeof(HAL::GNSS_Info_t)); + + if (_size) { + *gnssInfo = _gnssInfo; + } else { +#if CONFIG_RANDOM_GNSS + makeRandomGNSSInfo(gnssInfo); +#else + gnssInfo->longitude = CONFIG_GNSS_LONGITUDE_DEFAULT; + gnssInfo->latitude = CONFIG_GNSS_LATITUDE_DEFAULT; +#ifndef CONFIG_NO_GNSS + gnssInfo->isVaild = true; + gnssInfo->satellites = 10; +#endif /* CONFIG_NO_GNSS */ +#endif /* CONFIG_RANDOM_GNSS */ + } + + /* GPGSV Info */ + gnssInfo->gsv.items = _gsvItems; + gnssInfo->gsv.num = rand() % (CM_ARRAY_SIZE(_gsvItems) + 1); + gnssInfo->gsv.satsInView = rand() % 10; + + DeviceObject* devClock = HAL::Manager()->getDevice("Clock"); + if (devClock) { + devClock->read(&gnssInfo->clock, sizeof(gnssInfo->clock)); + } + + return sizeof(HAL::GNSS_Info_t); +} + +int GNSS::onWrite(const void* buffer, size_t size) +{ + return size; +} + +int GNSS::onIoctl(DeviceObject::IO_Cmd_t cmd, void* data) +{ + switch (cmd.full) { + case GNSS_IOCMD_UPDATE: { + if (_isUpdate) { + _isUpdate = false; + return DeviceObject::RES_OK; + } + + return DeviceObject::RES_UNSUPPORT; + } + + default: + break; + } + + return DeviceObject::RES_UNKNOWN; +} + +int GNSS::parserReadByte(GPX_Parser* parser) +{ + auto ctx = (GNSS*)parser->getUserData(); + uint8_t data; + uint32_t rd; + lv_fs_res_t res = lv_fs_read(&ctx->_file, &data, sizeof(data), &rd); + + if (res != LV_FS_RES_OK || rd != sizeof(data)) { + return 0; + } + + return data; +} + +int GNSS::parserAvaliable(GPX_Parser* parser) +{ + auto ctx = (GNSS*)parser->getUserData(); + + uint32_t cur; + lv_fs_res_t res = lv_fs_tell(&ctx->_file, &cur); + + if (res != LV_FS_RES_OK) { + return 0; + } + + return (ctx->_size - cur); +} + +bool GNSS::parserInit() +{ + lv_fs_res_t res = lv_fs_open(&_file, CONFIG_GPX_FILE_PATH, LV_FS_MODE_RD); + + if (res != LV_FS_RES_OK) { + return false; + } + + lv_fs_seek(&_file, 0, LV_FS_SEEK_END); + lv_fs_tell(&_file, &_size); + lv_fs_seek(&_file, 0, LV_FS_SEEK_SET); + return true; +} + +void GNSS::paserStart() +{ + lv_timer_create( + [](lv_timer_t* timer) { + auto ctx = (GNSS*)lv_timer_get_user_data(timer); + ctx->paserUpdate(); + }, + CONFIG_GNSS_UPDATE_PERIOD, + this); +} + +time_t GNSS::makeTime(const GPX_Parser::Time_t* time) +{ + struct tm t; + memset(&t, 0, sizeof(t)); + t.tm_year = time->year - 1900; + t.tm_mon = time->month; + t.tm_mday = time->day; + t.tm_hour = time->hour; + t.tm_min = time->minute; + t.tm_sec = time->second; + + return mktime(&t); +} + +double GNSS::getDiffTime(const GPX_Parser::Time_t* time1, const GPX_Parser::Time_t* time2) +{ + time_t t1 = makeTime(time1); + time_t t2 = makeTime(time2); + return difftime(t1, t2); +} + +void GNSS::paserUpdate() +{ + GPX_Parser::Point_t point = { 0 }; + int parserFlag = _parser.getNext(&point); + + if (parserFlag & GPX_Parser::FLAG_LATITUDE && parserFlag & GPX_Parser::FLAG_LONGITUDE) { + if (!_isReset) { + _gnssInfo.longitude = point.longitude; + _gnssInfo.latitude = point.latitude; + _gnssInfo.altitude = point.altitude; + + _prePoint = point; + _isReset = true; + return; + } + + double distance = Geo::distanceBetween( + _gnssInfo.latitude, _gnssInfo.longitude, + point.latitude, point.longitude); + + double diffTime = CONFIG_GNSS_UPDATE_PERIOD / 1000.0; + + if (parserFlag & GPX_Parser::FLAG_TIME) { + diffTime = getDiffTime(&point.time, &_prePoint.time); + } + + if (std::abs(diffTime) >= 0.0001) { + _gnssInfo.speed = (float)(distance / diffTime) * 3.6f; + } + + _gnssInfo.course = (float)Geo::courseTo( + _gnssInfo.latitude, + _gnssInfo.longitude, + point.latitude, + point.longitude); + + _gnssInfo.longitude = point.longitude; + _gnssInfo.latitude = point.latitude; + _gnssInfo.altitude = point.altitude; + _prePoint = point; + + /* Gererate random GSV info */ + int index = rand() % CM_ARRAY_SIZE(_gsvItems); + _gsvItems[index].id = rand() % 32; + _gsvItems[index].elevation = rand() % 90; + _gsvItems[index].azimuth = rand() % 360; + _gsvItems[index].snr = rand() % 100; + + _isUpdate = true; + } else if (parserFlag & GPX_Parser::FLAG_END_OF_FILE) { + lv_fs_seek(&_file, 0, LV_FS_SEEK_SET); + _isReset = false; + } +} + +#if CONFIG_RANDOM_GNSS + +void GNSS::makeRandomGNSSInfo(HAL::GNSS_Info_t* gnssInfo) +{ + static int cnt = 0; + static float speed = 0; + + cnt++; + float diff = rand() % 200 / 10.0f - 10; + speed += diff; + CM_VALUE_LIMIT(speed, 0, 200); + + if (cnt > 100) { + cnt = 0; + } + + gnssInfo->latitude = CONFIG_GNSS_LATITUDE_DEFAULT + (rand() % 2000 - 1000) / 100000.0f; + gnssInfo->longitude = CONFIG_GNSS_LONGITUDE_DEFAULT + (rand() % 2000 - 1000) / 100000.0f; + gnssInfo->speed = speed; + gnssInfo->course = rand() % 360; + gnssInfo->satellites = cnt < 30 ? 0 : rand() % 20 + 5; + gnssInfo->isVaild = cnt > 30; +} + +#endif + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(GNSS); diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_Log.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_Log.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29d8d8a5e6b9f3872ec5ed30f3a19e00ff51feee --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_Log.cpp @@ -0,0 +1,70 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> + +extern "C" { + +void HAL_Log_Init() +{ +} + +void HAL_Log_PrintString(const char* str) +{ + printf("%s", str); +} + +void HAL_Log(uint8_t level, const char* func, const char* fmt, ...) +{ + if (level >= _HAL_LOG_LEVEL_LAST) { + return; + } + + static const char* prompt[_HAL_LOG_LEVEL_LAST] = { + "Info", "Warn", "Error" + }; + + char buffer[256]; + + va_list ap; + va_start(ap, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, ap); + va_end(ap); + + printf("[HAL][%s] %s: %s\n", prompt[level], func, buffer); +} + +void HAL_Log_Printf(const char* fmt, ...) +{ + char buffer[256]; + + va_list ap; + va_start(ap, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, ap); + va_end(ap); + + printf("%s", buffer); +} +} /* extern "C" */ diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_Power.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_Power.cpp new file mode 100644 index 0000000000000000000000000000000000000000..25e6af5dbdccceb5cd7962d456be021616566bcf --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_Power.cpp @@ -0,0 +1,89 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" +#include <stdlib.h> + +namespace HAL { + +class Power : private DeviceObject { +public: + Power(const char* name) + : DeviceObject(name) + { + } + +private: + virtual int onInit(); + virtual int onRead(void* buffer, size_t size); + virtual int onIoctl(DeviceObject::IO_Cmd_t cmd, void* data); +}; + +int Power::onInit() +{ + return DeviceObject::RES_OK; +} + +int Power::onRead(void* buffer, size_t size) +{ + if (size != sizeof(HAL::Power_Info_t)) { + return DeviceObject::RES_PARAM_ERROR; + } + + HAL::Power_Info_t* info = (HAL::Power_Info_t*)buffer; + info->voltage = rand() % 1000 + 3200; + info->level = rand() % 100; + info->isReady = (rand() % 2) == 0; + info->isCharging = (rand() % 2) == 0; + + return sizeof(HAL::Power_Info_t); +} + +int Power::onIoctl(DeviceObject::IO_Cmd_t cmd, void* data) +{ + int retval = 0; + + switch (cmd.full) { + case POWER_IOCMD_POWER_ON: + HAL_LOG_INFO("Power: ON"); + break; + case POWER_IOCMD_POWER_OFF: + HAL_LOG_INFO("Power: OFF"); + retval = system("poweroff"); + break; + case POWER_IOCMD_REBOOT: + HAL_LOG_INFO("Power: Reboot"); + break; + case POWER_IOCMD_GAUGE_RESET: + HAL_LOG_INFO("Power: Reset Fuel Gauge"); + break; + case POWER_IOCMD_SET_SYS_VOLTAGE: + break; + default: + retval = -1; + } + return retval; +} + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(Power); diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_SdCard.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_SdCard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e897fcbdd36baaaa34f519f54884f4e9baaa8dee --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_SdCard.cpp @@ -0,0 +1,113 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 HanfG, _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "Config/Config.h" +#include "HAL.h" +#include <cstring> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#define SD_CARD_GB(byte) ((uint64_t)(byte)*1024 * 1024 * 1024) + +namespace HAL { + +class SdCard : private DeviceObject { +public: + SdCard(const char* name) + : DeviceObject(name) + { + } + +private: + HAL::SdCard_Info_t _info; + +private: + virtual int onInit(); + virtual int onRead(void* buffer, size_t size); + virtual int onIoctl(DeviceObject::IO_Cmd_t cmd, void* data); + const char* genRealPath(const char* path); +}; + +int SdCard::onInit() +{ + _info.isInsert = true; + _info.freeCapacity = SD_CARD_GB(16); + _info.totalCapacity = SD_CARD_GB(32); + return DeviceObject::RES_OK; +} + +int SdCard::onRead(void* buffer, size_t size) +{ + if (size != sizeof(_info)) { + return DeviceObject::RES_PARAM_ERROR; + } + + memcpy(buffer, &_info, sizeof(_info)); + + return sizeof(_info); +} + +int SdCard::onIoctl(DeviceObject::IO_Cmd_t cmd, void* data) +{ + switch (cmd.full) { + case SDCARD_IOCMD_MOUNT: + return DeviceObject::RES_OK; + + case SDCARD_IOCMD_UNMOUNT: + return DeviceObject::RES_OK; + + case SDCARD_IOCMD_MKDIR: { + const char* realPath = genRealPath((const char*)data); + int ret = access(realPath, F_OK); + if (ret == 0) { + HAL_LOG_INFO("%s already exits", realPath); + return DeviceObject::RES_OK; + } + return mkdir(realPath, 0755); + } + + case SDCARD_IOCMD_REMOVE: + return remove(genRealPath((const char*)data)); + + default: + break; + } + + return DeviceObject::RES_UNSUPPORT; +} + +const char* SdCard::genRealPath(const char* path) +{ + if (*path != '\0') { + path++; + if (*path == ':' || *path == '/') { + path++; + } + } + return path; +} + +} /* namespace HAL */ + +DEVICE_OBJECT_MAKE(SdCard); diff --git a/x_track/src/Vendor/Simulator/HAL/HAL_Tick.cpp b/x_track/src/Vendor/Simulator/HAL/HAL_Tick.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b023dde4a9df873062f27b593d05e22e881205df --- /dev/null +++ b/x_track/src/Vendor/Simulator/HAL/HAL_Tick.cpp @@ -0,0 +1,78 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "HAL.h" +#include <time.h> + +#ifdef WIN32 +#include <stdint.h> +#include <windows.h> + +#define CLOCK_MONOTONIC 0 +#define EPOCHFILETIME (116444736000000000ULL) + +static int clock_gettime(int, struct timespec* tv) +{ + if (!tv) { + return -1; + } + + FILETIME ft; + uint64_t tmpres = 0; + GetSystemTimeAsFileTime(&ft); + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + tmpres /= 10; // Convert 100 nanoseconds intervals to microseconds + tmpres -= EPOCHFILETIME; // Subtract time since epoch + + tv->tv_sec = static_cast<long>(tmpres / 1000000UL); + tv->tv_nsec = static_cast<long>(tmpres % 1000000UL) * 1000; + + return 0; +} +#endif + +uint32_t HAL::GetTick() +{ + struct timespec ts; + uint32_t ms; + clock_gettime(CLOCK_MONOTONIC, &ts); + ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + return ms; +} + +uint32_t HAL::GetTickElaps(uint32_t prevTick) +{ + uint32_t actTick = GetTick(); + + /*If there is no overflow in sys_time simple subtract*/ + if (actTick >= prevTick) { + prevTick = actTick - prevTick; + } else { + prevTick = UINT32_MAX - prevTick + 1; + prevTick += actTick; + } + + return prevTick; +} diff --git a/x_track/src/Vendor/Simulator/lv_port/lv_port.h b/x_track/src/Vendor/Simulator/lv_port/lv_port.h new file mode 100644 index 0000000000000000000000000000000000000000..0a363f700ebf69ebe83d28aa84483cc424f638b1 --- /dev/null +++ b/x_track/src/Vendor/Simulator/lv_port/lv_port.h @@ -0,0 +1,69 @@ +/* + * MIT License + * Copyright (c) 2023 - 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file lv_port.h + * + */ + +#ifndef LV_PORT_H +#define LV_PORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include <stdint.h> + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +int lv_port_init(void); + +uint32_t lv_port_tick_get(void); + +void lv_port_profiler_init(void); + +void lv_port_sleep(uint32_t ms); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_PORT_H*/ diff --git a/x_track/src/Vendor/Simulator/lv_port/lv_port_profiler.c b/x_track/src/Vendor/Simulator/lv_port/lv_port_profiler.c new file mode 100644 index 0000000000000000000000000000000000000000..3297e2e3fa979ecbfc50301a91579a203882885e --- /dev/null +++ b/x_track/src/Vendor/Simulator/lv_port/lv_port_profiler.c @@ -0,0 +1,60 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "lv_port.h" +#include "lvgl/lvgl.h" +#include <stdio.h> +#include <time.h> + +#if LV_USE_PROFILER + +static uint32_t profiler_get_tick_us(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000000 + ts.tv_nsec / 1000; +} + +static void profiler_flush(const char* buf) +{ + printf("%s", buf); +} + +void lv_port_profiler_init(void) +{ + lv_profiler_builtin_config_t config; + lv_profiler_builtin_config_init(&config); + config.buf_size = 64 * 1024; + config.tick_per_sec = 1000000; + config.tick_get_cb = profiler_get_tick_us; + config.flush_cb = profiler_flush; + lv_profiler_builtin_init(&config); +} + +#else + +void lv_port_profiler_init(void) +{ + /*Do nothing*/ +} + +#endif \ No newline at end of file diff --git a/x_track/src/Vendor/Simulator/lv_port/lv_port_sdl2.c b/x_track/src/Vendor/Simulator/lv_port/lv_port_sdl2.c new file mode 100644 index 0000000000000000000000000000000000000000..77bfe7aaa7e15d55e352ab8bec01656f83f301ad --- /dev/null +++ b/x_track/src/Vendor/Simulator/lv_port/lv_port_sdl2.c @@ -0,0 +1,133 @@ +/* + * MIT License + * Copyright (c) 2023 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file lv_port_sdl2.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lvgl/lvgl.h" + +#if LV_USE_SDL + +#include "lv_port.h" +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +/********************* + * DEFINES + *********************/ + +#ifndef LV_SCREEN_HOR_RES +#define LV_SCREEN_HOR_RES 240 +#endif + +#ifndef LV_SCREEN_VER_RES +#define LV_SCREEN_VER_RES 320 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void touchpad_cursor_init(lv_indev_t* indev, lv_coord_t size); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +int lv_port_init(void) +{ + lv_disp_t* disp = lv_sdl_window_create(LV_SCREEN_HOR_RES, LV_SCREEN_VER_RES); + lv_indev_t* mouse = lv_sdl_mouse_create(); + lv_indev_set_group(mouse, lv_group_get_default()); + lv_indev_set_disp(mouse, disp); + +#ifdef LV_INDEV_CURSOR_SIZE + touchpad_cursor_init(mouse, LV_INDEV_CURSOR_SIZE); + lv_indev_t* mousewheel = lv_sdl_mousewheel_create(); + lv_indev_set_disp(mousewheel, disp); + lv_indev_set_group(mousewheel, lv_group_get_default()); +#endif + + lv_indev_t* keyboard = lv_sdl_keyboard_create(); + lv_indev_set_disp(keyboard, disp); + lv_indev_set_group(keyboard, lv_group_get_default()); + + lv_port_profiler_init(); + + return 0; +} + +uint32_t lv_port_tick_get(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + +void lv_port_sleep(uint32_t ms) +{ + usleep(ms * 1000); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void touchpad_cursor_init(lv_indev_t* indev, lv_coord_t size) +{ + if (size <= 0) { + return; + } + + lv_obj_t* cursor = lv_obj_create(lv_layer_sys()); + lv_obj_remove_style_all(cursor); + + lv_obj_set_size(cursor, size, size); + lv_obj_set_style_translate_x(cursor, -size / 2, 0); + lv_obj_set_style_translate_y(cursor, -size / 2, 0); + lv_obj_set_style_radius(cursor, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_bg_opa(cursor, LV_OPA_50, 0); + lv_obj_set_style_bg_color(cursor, lv_color_black(), 0); + lv_obj_set_style_border_width(cursor, 2, 0); + lv_obj_set_style_border_color(cursor, lv_palette_main(LV_PALETTE_GREY), 0); + lv_indev_set_cursor(indev, cursor); +} + +#endif /*USE_SDL*/ diff --git a/x_track/x_track_main.cpp b/x_track/x_track_main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9a7cc25ea9503c78bc548e7911a4fbb14b2b2b7 --- /dev/null +++ b/x_track/x_track_main.cpp @@ -0,0 +1,102 @@ +/* + * MIT License + * Copyright (c) 2024 _VIFEXTech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "App/App.h" +#include "HAL/HAL.h" +#include "lvgl/lvgl.h" +#include <uv.h> + +static void lv_nuttx_uv_loop_run(uv_loop_t* loop, lv_nuttx_result_t* result) +{ + lv_nuttx_uv_t uv_info; + void* data; + + uv_loop_init(loop); + + lv_memset(&uv_info, 0, sizeof(uv_info)); + uv_info.loop = loop; + uv_info.disp = result->disp; + uv_info.indev = result->indev; +#ifdef CONFIG_UINPUT_TOUCH + uv_info.uindev = result->utouch_indev; +#endif + + data = lv_nuttx_uv_init(&uv_info); + uv_run(loop, UV_RUN_DEFAULT); + lv_nuttx_uv_deinit(&data); +} + +/** + * @brief Main Function + * @param argc: Argument count + * @param argv: Argument vector + * @retval error code + */ +extern "C" int main(int argc, const char* argv[]) +{ + lv_nuttx_dsc_t info; + lv_nuttx_result_t result; + uv_loop_t ui_loop; + lv_memzero(&ui_loop, sizeof(uv_loop_t)); + + if (lv_is_initialized()) { + LV_LOG_ERROR("LVGL already initialized! aborting."); + return -1; + } + + lv_init(); + lv_nuttx_dsc_init(&info); + lv_nuttx_init(&info, &result); + + if (result.disp == NULL) { + LV_LOG_ERROR("Display initialization failure!"); + return 1; + } + + HAL::Init(); + + AppContext_t* appCtx = App_CreateContext(argc, argv); + LV_LOG_USER("App context created: %p", appCtx); + + /* Create app timer */ + lv_timer_t* app_timer = lv_timer_create( + [](lv_timer_t* tmr) { + auto ctx = (AppContext_t*)lv_timer_get_user_data(tmr); + + /* Run app loop */ + uint32_t app_idle_time = App_RunLoopExecute(ctx); + + lv_timer_set_period(tmr, LV_MIN(app_idle_time, 1000)); + }, + 0, + appCtx); + + /* Run UI loop */ + lv_nuttx_uv_loop_run(&ui_loop, &result); + + /* Clean up */ + lv_timer_delete(app_timer); + App_DestroyContext(appCtx); + lv_nuttx_deinit(&result); + lv_deinit(); + return 0; +}