diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86e850844b8..7baf5cb245c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,6 +32,7 @@ repos: .*.yuv| .*.rgb| .*.gray| + .*.ppm| .*COPYING.*| docs/sphinx-known-warnings\.txt )$ diff --git a/docs/en/api-reference/peripherals/ppa.rst b/docs/en/api-reference/peripherals/ppa.rst index 895b03ae439..9414289b5bf 100644 --- a/docs/en/api-reference/peripherals/ppa.rst +++ b/docs/en/api-reference/peripherals/ppa.rst @@ -176,6 +176,7 @@ Application Examples ^^^^^^^^^^^^^^^^^^^^ * :example:`peripherals/ppa/ppa_transform` - PPA transform image processing example. The embedded RGB565 image is transformed by SRM, highlighted with blend, framed with fill, and emitted as base64 for host-side PPM reconstruction and golden-image comparison. +* :example:`peripherals/ppa/ppa_color_key` - PPA blend color-keying example. The example generates a centered RGB888 glow foreground in software, then demonstrates two blend effects on the embedded RGB565 image: replacing the keyed red `ESP32` text with the glow, and preserving the keyed text while blending the glow into the non-key area. Both results are emitted as base64 for host-side PPM reconstruction and golden-image comparison. API Reference ------------- diff --git a/docs/zh_CN/api-reference/peripherals/ppa.rst b/docs/zh_CN/api-reference/peripherals/ppa.rst index 63af1e6536f..58f4001603f 100644 --- a/docs/zh_CN/api-reference/peripherals/ppa.rst +++ b/docs/zh_CN/api-reference/peripherals/ppa.rst @@ -176,6 +176,7 @@ PPA 操作作用于输入图片的目标块。因此,完成一次 PPA 事务 ^^^^^^^^^ * :example:`peripherals/ppa/ppa_transform` - PPA transform 图像处理示例。嵌入的 RGB565 图像会经过 SRM 变换、blend 高亮和 fill 边框处理,然后以 base64 输出,供主机端重建为 PPM 并与 golden 图像比对。 +* :example:`peripherals/ppa/ppa_color_key` - PPA blend color key 示例。示例先在软件中生成居中的 RGB888 glow 前景,然后在嵌入式 RGB565 图片上演示两种 blend 效果:一种是通过 blend color key 将命中的红色 `ESP32` 文本像素替换为 glow,另一种是在保留命中文本的同时,将 glow 混合到非 key 区域。两种结果都会以 base64 输出,供主机端重建为 PPM 并与 golden 图像比对。 API 参考 -------- diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 172fac47165..10e1829a3b8 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -519,6 +519,16 @@ examples/peripherals/pcnt: - esp_driver_pcnt - soc +examples/peripherals/ppa/ppa_color_key: + disable: + - if: SOC_PPA_SUPPORTED != 1 + depends_components: + - esp_driver_dma + - esp_driver_ppa + - esp_hal_ppa + - mbedtls + - soc + examples/peripherals/ppa/ppa_transform: disable: - if: SOC_PPA_SUPPORTED != 1 diff --git a/examples/peripherals/ppa/ppa_color_key/CMakeLists.txt b/examples/peripherals/ppa/ppa_color_key/CMakeLists.txt new file mode 100644 index 00000000000..507da8f89fb --- /dev/null +++ b/examples/peripherals/ppa/ppa_color_key/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.22) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(ppa_color_key) diff --git a/examples/peripherals/ppa/ppa_color_key/README.md b/examples/peripherals/ppa/ppa_color_key/README.md new file mode 100644 index 00000000000..f6fb5a390d9 --- /dev/null +++ b/examples/peripherals/ppa/ppa_color_key/README.md @@ -0,0 +1,81 @@ +| Supported Targets | ESP32-P4 | ESP32-S31 | +| ----------------- | -------- | --------- | + +# PPA Color Key Example + +## Overview + +This example demonstrates two common color-keying effects of the PPA blend engine without any display hardware. + +The example is intentionally tailored to its embedded demo asset. It embeds a pre-generated raw RGB565 image, generates a centered RGB888 glow-style foreground image in software, then runs two PPA blend color-keying passes. The first pass replaces the red `ESP32` text with the generated glow. The second pass keeps the red keyed text untouched while the remaining area blends with the same generated effect. The glow geometry is fixed because the demo asset keeps the text near the center of the frame. Both final RGB565 buffers are base64-encoded and printed to the serial console. The accompanying pytest script reconstructs the images as PPM files and compares them with two golden reference images. + +The processing pipeline demonstrates: + +- Software preprocessing: generate a fixed centered RGB888 glow foreground +- Blend color key effect 1: replace the red keyed text with the generated RGB888 glow +- Blend color key effect 2: preserve the red keyed text while blending the generated RGB888 glow into the non-key area + +## Hardware Required + +* An ESP development board with PPA support +* An USB cable for power supply and programming + +## Build and Flash + +Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```text +I (1555) main_task: Calling app_main() +Loading embedded RGB565 image from flash... +Embedded raw image size: 153600 bytes +Generating shared glow foreground... +Replacing keyed red text with glow foreground... +IMAGE_META effect=replace_keyed_text_with_glow width=320 height=240 format=RGB565 encoding=base64 +IMAGE_BASE64_BEGIN +IMAGE_BASE64 ... +IMAGE_BASE64 ... +IMAGE_BASE64_END +Blending glow around keyed red text... +IMAGE_META effect=blend_glow_around_keyed_text width=320 height=240 format=RGB565 encoding=base64 +IMAGE_BASE64_BEGIN +IMAGE_BASE64 ... +IMAGE_BASE64 ... +IMAGE_BASE64_END +PPA color key demo done. +I (10085) main_task: Returned from app_main() +``` + +## Pytest Visual Check + +The accompanying `pytest_ppa_color_key.py` script captures each `IMAGE_META` and `IMAGE_BASE64` payload, reconstructs both processed images, and saves them as: + +- `dut.logdir/ppa_color_key_replace_keyed_text_with_glow.ppm` +- `dut.logdir/ppa_color_key_blend_glow_around_keyed_text.ppm` + +It also compares the generated images with `golden_replace_keyed_text_with_glow.ppm` and `golden_blend_glow_around_keyed_text.ppm` by hashing the decoded RGB pixel content. This turns the example into a functional regression test and a visual artifact generator for CI logs. + +### Getting The PPM Result Locally + +If you want to inspect the processed image on your computer, first build the example for your target, then run pytest from the ESP-IDF root directory with the matching target and serial port: + +```bash +pytest -k test_ppa_color_key --target esp32p4 --port PORT +``` + +Replace `esp32p4` with another supported target such as `esp32s31`, and set `PORT` to your board's serial device. + +`pytest-embedded` stores per-test logs under `$IDF_PATH/pytest-embedded/`. When the test finishes, pytest prints a log line similar to: + +```text +Saved PPA artifact to .../pytest-embedded//esp32p4.default.test_ppa_color_key/ppa_color_key_replace_keyed_text_with_glow.ppm +Saved PPA artifact to .../pytest-embedded//esp32p4.default.test_ppa_color_key/ppa_color_key_blend_glow_around_keyed_text.ppm +``` + +You can open both generated PPM files from that log directory with any image viewer to inspect the two PPA color-key effects locally. + diff --git a/examples/peripherals/ppa/ppa_color_key/golden_blend_glow_around_keyed_text.ppm b/examples/peripherals/ppa/ppa_color_key/golden_blend_glow_around_keyed_text.ppm new file mode 100644 index 00000000000..622a0ea076c --- /dev/null +++ b/examples/peripherals/ppa/ppa_color_key/golden_blend_glow_around_keyed_text.ppm @@ -0,0 +1,4 @@ +P6 +320 240 +255 +ZZZZZZZZZZZZZZZZZZckޥޥ祶ޥZZZZZZZZZZZZZZZZZZZZkZcc֜ޥ眺眶cZZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺ޥ眾sZZZZZZZZZZZZZZZZZcZZZZքΜ梁祾kZZcZZZZZZZZZZZZZZZZZZZ֌ޜ祺祾猾cZZZZZZZZZZZZZZZZZZZZZZ֔֜祺ޜތZZZZZZZZZZZZZZZZZZZZ}ZyZ}cΜޜޥޥkZZccZZZZZZZZZZZZZZZZZkƄޜޜޜޥscZZZZZZZZZZZZZZZZZZZZk祦֥֔ތcZZZZZZZZZZZZZZZZZZZZZk}眢֜֜猞Z}Z}ZZZ}Zyc}kcckkssssssss{s֥֜cZZZZZ}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZck֜ޥޥޥZZZZccZZZccZZZZZZZZccZZcΜ֥ޥޥkZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޜ{ccZZZZZZZZZZZZZZZZZZZc΄Μ眶ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֌֜ޥޥބcZZZZZZZZZZZZZZZZZZZZZZΔ֜ޜ֥scZZZZZcZZZZZZZZZ}Z}Z}Z}ZyZyZycƜ֥֥ޥcZccccZZZZZZZZZZZZZZZZk֥֜֜֜kcZZZZZZZZZZZZZZZZZZZZk}֜ΥΔބZZZZZZZZZZZZZZZZZZZZZZky֜ΜΔތZ}Z}Z}Z}Z}Z}Z}c}Z}Z}c}c}Z}Z}Z}Z}Z}Z}Z}Z}Z}c}ƜZ}Z}Z}cZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZck֥֥ޥ֥cZZZccccZckcZZZZZZZZZZZc֜֜ޥޥkZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޜsZZZZZZZZZZZZZZZZZZZZZZ{Μ祺ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֌֜祺ޥބcZZZZZZZZZZZZZZZZZZZZZZ֔֜ޥޥkZZZZZZZZZZZZZZZ}Z}Z}Z}Z}Z}ZyZ}cΥ֜֜ޥcZZZZZZZZZZZZZZZZZZZZZkޜ֜֜֜kcZcZZZZZZZZZZZZZZZZZZk}֜Μ֔{ZZcZZZZZZZZZZZZZZZZZ}ZZcy֜ΜΜބZ}Z}ZZ}Z}Z}Z}Z}Z}Z}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZyƄƜZ}ZZ}cZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZck֥֜ޥ֥cZZcccccZZckkccckkcZZZckΜ֥֥ޥkZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޜkZZZZZZZZZZZZZZZZZZZZZZ{ƜޜޥޔsZZZZZZZZZZZZZZZZZZZZZZ֌֜ޥޥބcZZZZZZZZZZZZZZZZZZZZZZΔ֜ޜޥsZZZZZZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}cƜ֜֜ޥcZZZZZZZZZZZZZZZZZZZZZc֥֜֜֜kcZZZZZZZZZZZZZZZZZZZZk}֜֜֔kZZcZZZZZZZZZZZZ}ZZZZZ}ZZcy֜ΜΔބZZ}ZcZ}Z}Z}Z}Z}ZZ}Z}Zyc}c}c}Z}Z}Z}Z}Z}ZyƄƜZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZck֜ޥޥ֥cZZZcZZZZZZZccccZZZZZZck֜֜ޜޥkZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޜkZZZZZZZZZZZZZZZZZZZZZZ{Ɯ祺ޜތkZZZZZZZZZZZZZZZZZZZZZZ֔֜祺ޥބcZZZZZZZZZZZZZZZZZZZZZZ֔֜ޥޥ{ZZZZZZZZZZZZZ}ZZ}Z}Z}Z}Z}Z}ZyZ}cΜ֥֜ޜZZZZZZZZZZZZZZZZZZZZZZc{֜֜ޜ֜cZZZZZZZZZZZZZZZZZZZZZc}֜Μ֔kZZcZZZZZZZZZZZZ}ZZZZZ}ZZcy֜ΜΔ{ZZ}ZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZyƄƔZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZck֜ޥޥޥZZZZZZZZZZZZZcZZZZZZZZck֜ޥޜޥkZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޔsZZZZZZZZZZZZZZZZZZZZZZ{Μ祺ޥތkZZZZZZZZZZZZZZZZZZZZZZ֔ޜޥޥބcZZZZZZZZZZZZZZZZZZZZZZΔ֥֜ޥ{ZZZZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}cƜ֜֜ޜZZZZZZZZZZZZZZZZZZZZZZc֔֜֜֜ccZZZZZZZZZZZZZZZZZZZZc}֜Μ֌kZZcZZZZZZZZZZZZ}ZZZZZ}ZZcy֜֜֔{Z}ZZZ}Z}Z}Z}c}Z}Z}Z}cZ}ZZ}Z}Z}Z}Z}Z}Z}Z}ƄƔZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZckޥޥ祶ޥZZZZZZZZZZZZZZZZZZZZZZZkޜޜ祺ޥkZZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺ޥ眾sZZZZZZZZZZZZZZZZZZZZZZ{Δ眾kZZZZZZZZZZZZZZZZZZZZZZޔޜ祺祾然ccZZZZZZZZZZZZZZZZZZZZZ֔֜眶ޥ{ZZZZZZZZZZZZZZZZZZZZZ}ZcΜޜޜ眲ZZZZZZZZZZZZZZZZZZZZZZc{ޜޜޜޜccZZZZZZZZZZZZZZZZZZZZk{ޜ֜ޔkZZZZZZZZZZZZZZZZZZZZZZc}ޜ֜֔sZZZZZZZZZZZ}ZZZZZZZZZZcΌΔZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZck֜ޥޥޥZcZZZcZZZZZZZZZZZZZZZZZkޜޥޥ祺kZZZZZZZZZZZZZZZZZZZZZZZΔޥ祺祺眾{ZZZZZZZZZZZZZZZZZZZZZcք֜祾sZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺祾{cZZZZZZZZZZZZZZZZZZZZZZ֔ޜ眶ޥބZZZZZZZZZZZZZZZZZZZZ}Z}Z}cƜޜޜ眲ZZZZZZZZZZZZZZZZZZZZZZcƄޜޜޜޥccZZZZZZZZZZZZZZZZZZZZk{֜֜֔sZZZZZZZZZZZZZZZZZZZZZZcyޜ֜֔{ZZZZZZZZZZZZZZZZZZZ}cZ}cΌ֜ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZckޥޥ祶ޥcZZZZZZZZZZZZZZZZZZZZZckޜޥ祶祶sZZZZZZZZZZZZZZZZZZZZZZZΜޥ祺祺眾kZZZZZZZZZZZZZZZZZZZZZZ{Μ梁眺kZZZZZZZZZZZZZZZZZZZZZZތޜ祾祾然cZZZZZZZZZZZZZZZZZZZZZZ֔֜祶ޥsZZZZZZZZZZZZZZZ}ZZZZZZZ}Z}ΜޜޥޜZZZZZZZZZZZZZZZZZZZZZZc{ޜޜޜޜcZZZZZZZZZZZZZZZZZZZZZc{ޜ֜֌sZZZZZZZZZZZZZZZZZZZZZZcyޜ֜֌kZZZZZZZZZZZZZZZZZZZZcZyƌΔcZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZcs֜ޥޥޥZZZZZZZZZZZZZZZZZZZZZZck֜ޥޥ祺scZZZZZZZZZZZZZZZZZZZZZZΜޥޥ祺眾sZZZZZZZZZccZZZZZZZZZZZ{Μ梁祺kZZZZZZZZZZZZZZZZZZZZZZ֌ޜ眺祾然cZZZZZZZZZZZZZZZZZZZZZZ֌֜ޥޥsZZZZZZZZZZZZZZ}ZZZZZZZZ}c}Μޥޜ眲ZZZZZZZZZZZZZZZZZZZZZZcƄޜޥޜޥccZZZZZZZZZZZZZZZZZZZZc{ޜ֥֌sZZZZZZZZZZZZZZZZZZZZZZcyޜ֜֌kZZZZZZZZZZZZZZZZZZZ}Zc}sޔ֔cZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZcsޥޥޥޜZZZZZZZZZZZZZZZZZZZZZZck֜ޜޥ祺kZZZZZZZZZZZZZZZZZZZZZZZ֜ޜ祺ޥsZZZZZZZZZZZZZZZZZZZZZZ{Δ量祺kZZZZZZZZZZZZZZZZZZZZZZޔޜ祾祾焺cZZZZZZZZZZZZZZZZZZZZZZ֌֜祺ޥsZZZZZZZZZZZZZZZZZZZZZZ}Z}ΜޜޜޜZZZZZZZZZZZZZZZZZZZZZZc{ޜޜޜޜcZZZZZZZZZZZZZZZZZZZZZc{ޜ֜֌sZZZZZZZZZZZZZZZZZZZZZZcyޜ֜֌kZZZZZZZZZZZZZZZZZZZZck֔֜cZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZcƄޜ֭ޥޥZZZZZZZZZZZZZZZZZZZZZZck֥֜ޥޥkZZZZZZZZZZZZZZZZZZZZZZcΜ֥ޥޥޜsZZZZZZZZZZZZZZZZZZZZZZ{Μ祺ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֔ޜޥޥބcZZZZZZZZZZZZZZZZZZZZZZΌ֜ޥޥscZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Ɯ֜ޜޜZZZZZZZZZZZZZZZZZZZZZZc{֥֜֜֜cZZZZZZZZZZZZZZZZZZZZZc{֜ΜΌsZZZZZZZZZZZZZZZZZ}ZZZZ}Z}cu֜֜Όk}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}c}c}ƔΔcZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZcs֥ޥޥ֥cZZZZZZZZZZZZZZZZZZZZZcsޜ֜ޥޥsZZZZZZZZZZZZZZZZZZZZZZcΜ֜ޥޥޜkZZZZZZZZZZZZZZZZZZZZZZ{Μ祺ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֔֜祺ޥ{cZZZZZZZZZZZZZZZZZZZZZZ֌֜ޜޥsZZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Μ֜ޜޜZZZZZZZZZZZZZZZZZZZZZZc{ޜ֜֜ޜcZZZZZZZZZZZZZZZZZZZZZc}{֜Μ֌sZZZZZZZZZZZZZZZZZZZZZ}Z}cyޜΜ֔k}ZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}c}c}Ɣ֔cZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZcZc}{֥ޭޥޥcZZZZZZZZZZZZZZZZZZZZZcs֥֜ޥޥscZZZZZZZZZZZZZZZZZZZZZcΜ֥ޥޥޜsZZZZZZZZZZZZZZZZZZZZZZ{Ɯ眶ޥތkZZZZZZZZZZZZZZZZZZZZZZ֔ޜޥޥ{ccZZZZZZZZZZZZZZZZZZZZZΌΜޜޥsZZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Ɯ֜ޜޜZZZZZZZZZZZZZZZZZZZZZZc{֥֜֜ޥccZZZZZZZZZZZZZZZZZZZZc}{֜ΜΌsZZZZZZZZZZZZZZZZZ}ZZZZ}Z}cyޜΜΌk}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}cykƔΜc}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZcƄޥ֥ޥ֥cZZZZZZZZZZZZZZZZZZZcZks֜ޜޥޥsZZZZZZZZZZZZZZZZZZZZZZc֜ޜޥޥޜkZZZZZZZZZZZZZZZZZZZZZZsƜ祺ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺ޥ{ccZZZZZZZZZZZZZZZZZZZZZ֌ΜޜޥkZZZZZZZZZZ}Z}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZyƜ֜ޜޜZZZZZZZZZZZZZZZZZZZZZZc{֜֜֜֜cZZZZZZZZZZZZZZZZZZZZZks֜ΜΌkZZZZZZZZZZZZZZZZZZZZZZ}kyޜ֜֌c}ZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}cyk֜֔cZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZc}{ޥ֥ޥޥcZZZZZZZZZZZZZZZZZZZccs{֜ޥޥޥsZZZZZZZZZZZZZZZZZZZZZZc֜֜ޥޥޜkZZZZZZZZZZZZZZZZZZZZZZsƜ祺ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֔ޜޜޥ{cZZZZZZZZZZZZZZZZZZZZZZ֌ΜޜޥkZZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZyƜ֥֜ޜZZZZZZZZZZZZZZZZZZZZZZc{֥֜֜֜ZZZcZZZZZZZZZZZZZZZZZZksΜΜΌkZZZZZZZZZZZZZZZZZ}ZZZZ}Z}cyޜ֜֌c}Z}ZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}c}kƜ֜c}c}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZZZZZZZZZZZZZZZZZcƄ眮ޥ祲祶kcZZZZZZZZcZZZZZZZZZZcss֜ޜޥޥsZcZccZZZZZZZZZZZZZZcZZZ֥ޥޥ祺町kZZZZZcZZZZZZZZZZcZZZZZsޜkZZZZZZZZZZZZZZZZZZZZcZޜޜ眾{ccZZZZZZZZZZZZZZZZZZZZZ֌֜祶ޥcZZZZZZZZZZZZZZZZZcZcZ}ZZ֔֜ޥ眲ZZZZZZZZZZZZZZZZcZZZZZc{ޜ֥ޜޔZZckZZZZZZZZZZZZZZZZZZcs֜Μ֌kZZkZZZZZZZZZZZZZZZZZZZcy眢֜֌cZZZZZZZZZZZZZZZ}ZZ}ZZZc}k֜֜ZZZZZZ}ZZZZ}ZZZZZZZZZZZZZZZZZZZZZZZZZZZZc{ޜޥޥޭkcZZZZZcZZZZZZZZZZZZZZcsޜޥޥޥ{cZZZcZZZZZZZZZZZZccZZZZ֥ޥޥ眺ޔkZZZZZZZZZZZcZZZZZZZZcZsƜ甾scZZZZZZZZZZZZZZZZZZZZZޔޥ眺祾{cZZZZZZZZZZZZZZZZZZZZZc֌֜ޜޥcZZZZZZZZZZ}ZZZZZZZZZZZZZΜޥޜޥZZZZZZZZZZZZZZZZZZZZZZc{ޜ֥ޔޔZZZcZZZZZZZZZcZZZZZZZZcs֜֜֌kZZkcZZZcZZZZZZZZZZZZZ}cky眢ޜތkZcZZZZZZZZZcZZZ}Z}Z}Z}Z}ZcykΜޜZcZZZZZZZZZ}ZZ}cZZ}Z}ZZZ}ZZZZZZZZZZZZZZZZZZc{ޥޜޥޥkcZZZZZZZZZZZZZZZZZZZZcs眲ޥ祶ޥsZZZZZZZZZZZZZZZZZZZZZZZ֜ޜ祾眺町kZZZZZZZZZZZZZZZZZZZZZZ{Ɣ眾猾kccccZZZZZZZZZZZZZZZZZZ֔֜眾{ccZZZZZZZZZZZZZZZZZZZZZ֌֜眲ޥkZZZZZZZZZZZZZZZZZZZZZ}ZZ}Μ֜ޜ֜ZZZZZZZZZZZZZZZZZZZZZZk{眪֜ޔތZZZZZZZZZZZZZZZZZZZZcZck֜֜֌scZccZZZZZZZZZZZZZZZZZZcyޜ֜ތkZZZZZZZZZZZZZZZZZZ}Z}Z}c}kΜ֜cZZZZZ}Z}Z}Z}ZZZ}ZZZyZcZycZ}ZcZZZZZZZZZZZZZZcZc{֜祲祲祶scccZZcZZZZZcZZZZZZZZZc{ޜޥޥ祶ބcZZZZZZZZZcZZZZZZZcccck֜ޜޥޥޔkZZZZZcZZZZZZZZZZccZZZZ{֥梁祺猺kckccccccccccZccZccZcZZ֔ޥ祺祾{cZcZZZZccZZZZZZZZZZZZZZ֌֜ޜ祶kZcZZZZZZZZZccZZZZZZZZZZ}Ɯޜ祲眮ZZZZZZZZZZZZZZZZccZZcZc{ޜޜޜ甦ccZZZZZZZZZZZZZZZZZZZZkkΜ֥֌kZZZZZZZZZZZZZZZZZZZZZZkyޜ֜քcZZZZZ}c}ZZZZZZZZZZZ}ZZ}ZcysΜ֜kcZZZZZZZZZZZ}ZZZZ}ZZ}Z}Μޜޜޜޜޜޜޜޜޔޜޜޜޜޜޜޔ֔ޜ֜ޥ֥ޭޥޜ焞{s{քބބ{s{{{s{s{{{s{{քΌޜޜ祶ޜ甶{{ssskkkkkkksskkkkckks΄ޜޜޥޥ町scckcZZZks{skkkccZZcksތ֜祾ޥcZZZZZZZZZZZZccZcZcZcZ֔町眾眾焾ccckkcckccccccccccccccZ֌֜ޜ眶sZZZZZZZZZZZZZZZZZZZZZZZƜޜ祲ޜcZZZZZZZZZZZZZZZZZZZZZcsޜ֜ޜޜccZZZZZZZZZZZZZZZZZZZZck֔֜֌sZZZZZZZZZZZZZZZZZZZZZZkyޜ֜քcZZZZZZ}ZZZZZZZZZZZ}ZZZ}c}s֜ޜkc}ZZZZZZ}Z}Z}ZZZZZcccccΥ֥֥֥֥֥֥֥֥֥֥֥֥֥֥ޥ֥ޥޥޥޜ֥ޥޥޥޜ֥ޥ֥ޜ֥֥ޥޥޥޥޥޥޥޥ֥ޥޜޥޜޜޥޥޥޥޥ֥֥ޥޥޥޥޥޜޥޜޜޜޜޥޥޥޥޜޜޜޥޜޜޜޜޜ֥֜ޥޥ֥֜ޜޜޜޜޥޜޜޜ֜֜ޥޜޥޜ眺ޜޜޜޜޔ֜֜ޥޜޥޜޜޔޔޔޜޜ眺ޜ甶ޔޔޔ֔֌֔ޔތ֌֌֌ތތތޥޥޥޥޜ焦sssskkkkcccccZZZZccZZcΜ֥֥֜֔{sƄkkcccZyZycZ}Z}ZZ}Z}Z}Z}Z}Z}c}csΜޜޜޥZccccZZZZZZZZZZcZZZZcZc{֔֜֔֔kkZZccccccccccckcccckkk}ΜΜΌsZZZZZZZZZZZZZ}ZZ}Z}Z}cZ}Z}ZZ}cuޜΜ΄k}ZZZZZZZ}Z}Z}Z}Z}Z}Z}c}Z}Z}ZyZ}Z}Z}cysƔ֔քskkc}k}c}k}c}k}kkkkkk}cykcycu֥֥֥֥֥֥֥֥֥֥֥ޥ֥ޥޥޥ֥֥֜֜֜ޥ֥ޥ֥֜ޥޥ֥֜ޥޥޥޥޥޥޥޥޜޥޥޥޥޥޜޥޥޥޥޥޥޥޥޥޜޥޥޥ֥֥֥֥֥ޥ֥ޥ֥֥֥֥֥֜֜֜ޥޜޜޥޥޥޥޜޜޜޜޜޜޜޜޜޜޜޜޜޜޜޜޥ֥֥ޥޜ֜ޥޥޥ祺眺ޜޥޜޜޜޥޜޥޜޜޜޥޜޜޜޥޜޥޥޜޜޜޜޜޜޥޥޥޜޥޜޥޜޥޜ֜ޜޜޜޜޜޜޜޜޜޜޜޜޜޜ֥֥֥֜ޜ֥ޥޥޜޜޜޜ֜֜֔֜֜ޜ֜֜֔֜֜֔֔ޜޔޔ֔ޥޜޜ֜skcckkkkkkkkkccckckkkks֜֜֜֜΄΄{{ssssssssssssss{{΄΄΄Ό֜Μ֔scZZZZZZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}cyޜΜΜބkc}ckc}c}c}cyc}c}Z}Zyc}Zyc}Z}c}cyc}Zycu{ƜΜΜΜΜ֔ΜΜΜΜΜΜΜΜΜΜΜΜΜΜΜΔΜ֜֜֜֜ޥޥޥޥޥޥޥޥޥޥޥޜޥޥޥ֥ޥޥޥޥޭޥޥޥ祲ޭޭޭޥޥޥޥޥޥޥޥޥޥޥ֜ޜ֥֥֥ޥ֥ޜ֥ޥޥޥޥ祶祲ޥޜ֥֥ޥޜޜޥޥޜޜޥޥޜޜޥޥ֜ޜޥ֥֥ޥޥޥޜޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޜ眺眺ޜޥޥޜޥޥޜ֥ޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥ֥ޥޜ眺ޥޥޥޥޥޜޜޜ֜ޜޜޥޥޥޥޥޥޥޜޜޜޥޜޜ֜֜֜ޜޜޜޜ֥֜ޥޜޜޥޥ֜֜֜ޜޥޥޜޜ֥֥֥֥֜֜֜֜Υޥ֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜ޜ֥֥֥֥֥֥֜֜֜֔֜֜֜֜Μ֥֥֜֜֜֜֜Μ֥֜֜֜֜֜֜֜ΜΔΔΥΥΜΜΔ֔Δ֔֔֔Δ֔֔ΔΌΌΔΔΔΔΌΔΌ֌ΌΌ֔Μ֜Μ֥֥Υ֜ΜΜ֜֜֜֜֜֔ΔΔ֔ΔΔΔ֌Ƅ{΄Ɣ֜ΜΜΥ֜֜֜֜ΜΜΜΜΜΜΜΜΜΜΜΜΜΜZZZZZZZZZZZZcZccccs{ޭ֥֥֥skcccckkkckkkkss{{ބքތތޔޔ眲ޥޥ֥֜眲眲ޜ眲ޜޜޜޜޜޜޜޜޜޜ甲眲ޜޔޔ֔ތޔޔ祶֥֥ޜޥ֥ޜ眾祶ޥ祺祶祺ޜޜޜޥޜޥޥޜޜޥޥޜޜ眺֜ޥޥޜޜ祾ޜޥޥ眺ޜޜ眺眾祾祾眾祾眾眾ޜ眾ޜ祾ޥޜޜ祺ޥ眶祺祾ޥޥޥޜޜ眺ޜ祲ޥޥޜޥޥޥޥޥޜޥޜޥޥޥޜޥޜ֥֥֜ޜޥ֥֥ޜޥ֜֜ޜޜ֜ޥޜޜޜޥޥޥޥޜ֥֜֜ޥ֥֜ޥޥ֥֥֜ޔ֜ޜ֜ޥ֥֜֜֜ޜޜ֜֜֜ޥ֥֥֥֥֥֥֥֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜ΜΜΜΜ֜֜Μ֜Υ֜Μ֜ΜΜΜΜ֜֜Μ֜Μ֜֜֜֜֜Μ֜ΜΜΜΜΜΜ֜֜Μ֜Μ֜ΔΜΜΜΜΜΜ֜ƜΜƜΜΜΜΜ֜ƜΜΜΜΜΜΥΜ֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜ZZZZZZZZZZZZZZZZZcck֥֜֜ޜccZZZZZZZZZZZZZZZZZZZZccΥޥޥޥscccZZZZZZZcZcZZZZZZccks֜ޥޥޥޥ猪kkckkkkksssssss{քބ{{քΔ祺祶ޜ祺猲{{{ބ{{{ބބބքބތ献ބބތ献ތތޔޔޜޜޥޥޥ眺ޔޔޔ町甲ޔޔ眶眶眶ޜ眺ޜ眺ޜޜޜޜޥޥޜޥޜޜ֜ޥޜ眶ޜ眶祺祶ޥ祶ޥޥޥޥޜޥޥޥޥ祲ޜ眲ޜޜ眮ޜޜޜޜޥޥ֥֜ޥޜ֥ޥ֥Μ֜֜ޥޥ֥֜֜֜ޜޥ֜֜ޜ֥֥֥֜֜֜֜֜֜ޥޜ֜֜ޜ֥֥֥֜֜֜֜֜֜֜֜֜֜֜֜֜Μ֥֥֥֥֜֜֜֜֜֜֜֜֜֜ΥΥΥΜ֥֥֥֜ΜΔΜΜΔΥΜΜ֥֥֥ΥΥΥޥ֜ޜ֜֜֔ޔޜޜ֜֜֜֜֜֜֜ΜΜ֥֥֜ޜޜ֥֜֜֜֜֜֜֜֜ΜΜ֜Μ֜ΜΜcZcckkkcccZZZZZZZZcc֜ޥ祶甮ZZZZZZZZZZZZZZZZZZZZZZZZ֜ޜޥ祺{cccZZZZZZZcZZZZZZZZZZcc֜ޜ祺ޥޔsZZZZZZZZZZZZZZZZcZZZckޔޜkZZZZZZZZZZZZZZZZZZZZcc֔眺眾kZZZZZZZZZZZZccccckkcksޜޜޜ眶猶kcccZZZZZcccccckckkkk{֌眲眲祶眮ޜ{{{{ބքքބބބ焦ބބބ猪ތޔތޔޔ甦֔ޜ֜ޜ֥֜ޔޔ甮眮ޜޜޜޜޜޜޜޜޜޜޜޜޜޜޜޜޔޔ֥֥֥֔֜ޥޜޥޜ祦ޜޜޜޜޜޜޜޜޜޜޜޜޜޜޜޜ֜֜Μ֥֜ޜ֜ޜ֥֥֜֜֜֜ޜޥ֜֜֜֜ޜޜ֜֜֜֜֜ޔ֜֜ޜބssssss{΄֌ތތޔޔޜޜ眦眦眦ޜcccccckkckccccZZZZcc֜ޥޥ眮ZcZZZZZcZZccZZZZZZZZZZZZΔޜ眺眺sZZZZZcZZZZckcZZZZZZZccc֜ޥޥ祺kccZZZZZZZZZZZZZZZZZZccք֜町ޜkccZZZZZZZZZZZZZZZZZcZZ֔眾祺祾甾kccZZZZZZZZZZZZZZZccccc֜ޜޜ眺scZcZZZcZZZcZZZZZZZZZcckΜޜޜ֥ތkZZZZZZZZZZZZZZccccZZkΌ眪ޜޥ祮scccZcZcZZZZZZZZZZZccck{֜ޥޔ猞ccZccccccccccccccckkks{Μ眢֥֜猚քΌքΔ֌֔֜ޜޥ֥֥֥֥֥֥֥֥֜֜ޜ֜ޜ֜ޜZycyZyc}Z}ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZcccZZZZZZZcc֜ޥޥ眮ZZZZcZZZZZcZZZZZZZZZZZcZ֜ޥ祺祺sZZZZZcZZZZZcZZZZcccZZcc֜ޜޥ祺kZZZZZcZZZZZZZZZZZZZZcZ֌֜祾cZZcZZZZZZZZZZZZZZZZZZZޔޜ祾祾猾cZkkcZZZZZZZZZZZZZZZZZZ֜ޜޜ祺ccZZZZZZZZZZcZcZZZZZZZccΜޜޜޥބcZZZZZZZZZZZZZZZZZZZZc{ޜޜޥޥkZZZZZZZZZZZZZZZZZZZZZcs֜֜֔sZcZZZZZZZZZZZZZZZZZZcZc}ޜ֜ބkZZZZZZcckks{ބބބބބ{{s{ΌޜޥcZyZyZyc}Zyc}ZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZZcZZZZZZZZZc֥֜ޜ眲ZZZZZZZZZZZZZZZZZZZZZZZZΜޥ祶祺scZcZZZZZZZZZZZZZZZZZZZZ֜ޜޥ祺kZcZcZcZZZZcckskskcZZccބ֜梁祺sZZcZZZZZZZZZZZZZZZZZZcޜ祺祺祾猾kZcksskZZZZZZZZZkkcZZZZ֜ޥޜޥkZZcccccZZZZZZZZZZZZZZcc֜ޥޜ祲焲cZZZZZZZZZZZZZZZZZZZZcƄޔ֥ޜޜcZZkkcccccZZZZcccckkZZckΜ֜ތsZcZcZcZcZZZZZZZZZZZZZZc}ޜ֜{cZZZZZZZZZZZ}ZZZZZZZZZ}c}kƜޜcZ}Z}Z}Z}ZyZyZyZyZyZyZyZuZyZyZyZyZyZyZyZZZZZZZZcZZZZZcZZZZZ֥֜ޥ眲ZZZZZZZZZZZZZZZZZZZZZZZZ֜ޥ眶眺kcZcZZZZZZZZZZZZZZZZZZZZ֜ޜޥ眺scccZZZZZZZZcssskcZZZZZք֜梁祾甾kZZZZZZZZZZZZZZZZZZccZZޔޜ眺猾cckcccZZZZZZZZZZZZZZZZZ֜ޜޥޥZZZZZZZZZZZZZZZZZZZZZZcZ֜ޥޜޜ猶cZZZZZZZZZZZZZZZZZZZZksޜޜޜޜZZcZskccccZZZZcZZZcZcZkkΜ֜֌{ZcZZZZZZZZZZZZZZZZZZcZkyޜ֜scZZcZZZZZZZZZZZZZZZ}ZZcyc}ƔΜkZ}ZyZ}cyZycyZyZyZuZyZyZyZyZyZyZyZyZyZyZZZZZZZZZZZZZZZZZZZcΜ֥ޥޥZZZZZZZZZZZZZZZZZZZZZZZZΜ֥֥ޥZZZZZZZZZZZZZZZZZZZZZZZZΥ֥֥֥֔{ZZZZZZZZZcZZZZZZZZZZcZ΄ΔޥޥތkZZZZZZZZZZZZZZZZZZZZZZ֔֜ޜޜބcZcZZcZZZZZZZZZccZcZccZΜޜޜ֥ZZZZZZZcZZZZZZZcZZZcZZcZΜ֜֜ޜތkZZZZZZZZZZZZZZZZZZZZk{֥֜֜֜ZZZZZZZZZZZZZZZZZZZZZZc}cƜΥΔ{ZZZZZZZZZZZZZZZcccZZZZc}֜֜{c}ZZZcZ}ZcZ}Z}Z}Z}Z}Z}Z}Z}c}Z}Z}Z}Z}cyc}Ɯ֥cZyZuZyZyZyZyZyZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZZZ֥֜ޥޥZZZZZZZZZZZZZZZZZZZZZZZZΜ֥ޥޥcZZZZZZZZZZZZZZZZZZZZZZZ֜֜ޥޥޔsZZZZZZZZZZZZZZZZZZZZZZքΔ眺ޜ甾kZZZZZZZZZZZZZZZZZZZZZZ֔֜ޜޜބcZcZZcZZZZZZZZZZZZZZZZZΜ֜ޜ֜ZZZZZZZZZZZZZZZZZZZZZZcZΜ֥֥֜ބcZZZZZZZZZZZZZZZZZZZZcs֥֜֜֜ZZZZZZZZZZZZZZZZZZZZZZccƜΜΔ{ZZZZZZZZZZZZZZZZZZZZZZcyޜΥ{cZZZcZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Zycyc}Ɣ֔cZuZyZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZZcΜ֥֥ޥZcZZZZZZZZZZZZZZZZZZZZZZΜ֥ޥޥcZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޔsZZZZZZZZZZZZZZZZZZZZZZ΄Μ眺ޥޔkZZZZZZZZZZZZZZZZZZZZZZ֔֜ޜޥ{kZcZcZZZZZZZZZZZZZZZZZZΜ֜֜ޥccZZZZZZZZZZZZZZZZZZZZZZΜ֥ޜ֥ބcZZZZZZZZZZZZZZZZZZZZc{֥֜֜֜ZZZZZZZZZZZZZZZZZZZZZZccΜΥΔ{ZZZZZZZZZZZZZZZZZZZZZZcyޜΥ{cZZZZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}cukƔ֔c}ZuZuZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZZZ֥֥֜ޥZZZZZZZZZZZZZZZZZZZZZZZZΜ֜ޥޥcZZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޜsZZZZZZZZZZZZZZZZZZZZZZքΔ眺ޜ甾kZZZZZZZZZZZZZZZZZZZZZZ֔֜ޥޥ{kZcZcZZZZZZZZZZZZZZZZZZΜ֜ޜޜkZZZZZZZZZZZZZZZZZZZZZZZΜ֜ޥޜބcZZZZZZZZZZZZZZZZZZZZcs֥֜֜֜ZZZZZZZZZZZZZZZZZZZZZZccΜΜΔ{ZZZZZZZZZZZZZZZZZZZZZZcyޜΜsZ}ZZZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}c}kΔ֔c}ZuZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZZcΜ֥֥ޥZcZZZZZZZZZZZZZZZZZZZZZZΜ֥ޥޥcZZZZZZZZZZZZZZZZZZZZZZZΔ֥ޥޥޔsZZZZZZZZZZZZZZZZZZZZZZքΜ眺祾甾kZZZZZZZZZZZZZZZZZZZZZZ֔ޜޜޥscZcZZZZZZZZZZZZZZZZZZZZΜ֥֜ޥZZZZZZZZZZZZZZZZZZZZZZZZΜ֥֜ޥބcZZZZZZZZZZZZZZZZZZZZc{֥֜֜֜ZZZZZZZZZZZZZZZZZZZZZZckΜΜΌ{ZZZZZZZZZZZZZZZZZZZ}ZZZcyޜ֜sc}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZZ}Z}Z}Z}Z}Z}cykΔ֜ZyZuZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZZcޥ֥ޥ祶cZZZZZZZZZZZZZZZZZZZZZZZ֜ޜ祶祺kZZZZZZZZZZZZZZZZZZZZZZZ֜ޜ祺ޥޔsZZZZZZZZZZZZZZZZZZZZZZք֜祾kZZZZZZZZZZZZZZZZZZZZZZޔޜ眾眾sccZZZZZZZZZZZZZZZZZZZZZ֜ޜޜޥZZZZZZZZZZZZZZZZZZZZZZZZ֜֜ޜޜބcZZZZZZZZZZZZZZZZZZZZc{ޜ֜ޥޥcZZZZZZZZZZZZZZZZZZZZZccΜ֜֔{ZZZZZZZZZZZZZZZZZZZZZZc}眢֜{cZZZZZZZZZZZZZZZZZZZZ}c}k֔֔ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZZZZZZZZZZZZcޥޥޥ祲ccZZZZZZZZZZZZZZZZZZZZZZ֜ޥޥ祺cZZZZZZZZZZZZZZZZZZZZZZZ֜ޥ祺祺ޔsZcZZZZZZZZZZZZZZZZZZZZք֜眺祾kZZZZZZZZZZZZZZZZZZZZZZޔޜ眺祾{cZcZZZZZZZZZZZZZZZZZZZZ֜ޥޜޥkcZZZZZZZZZZZcckcZZZZZZZΜ֜ޜޥ{cZZZZZZZZZZZZZZZZZZZZc{ޜޥޥޥcZZZZZZZZZZZZZZZZZZZZZccΜ֜֔{ZZZZZZZZZZZZZZZZZZZZZZc}眢֥{cZZZZZZZZZZZZZZZZZZZ}ZcykΔޜZycyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZZZZZZZZZZZZcޥ֥ޥ祲ZZZZZZZZZZZZZZZZZZZZZZZZ֜ޜ祶祶cZZZZZZZZZZZZZZZZZZZZZZZ֜ޜ祺ޥsZZZZZZZZZZZZZZZZZZZZZZք֜眾kZZccZZZZZZZZZZZZZZZZZZޔޜ眾眾{cZZZZZZZZZZZZZZZZZZZZZZ֜ޜޜޜkZZZZZZZZZZZZZZZZZZZZZcZΜޜޥޜ{cZZZZZZZZZZZZZZZZZZZZc{ޜޜޥޥcZcZZZZZZZZZZZZZZZZZZZccΜΜ֔{ZZZZZZZZZZZZZZZZZZZZZZc}眢֜kcZZZZZZZZZZZZZZZZZZZZ}cycΔޔZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZZZZZZZZZZZZcޜ֥ޥ祶ZZZZZZZZZZZZZZZZZZZZZZZc֜ޥ祶祺cZZZZZZZZZZZZZZZZZZZZZZZ֔ޜޥޥ甾sZZZZZZZZZZZZZZZZZZZZZZք֜祾kZZcccZZZZZcZZZZZZZZZZZޔޜ眾祾{cZcZZZZZZZZZZZZcZZZZZZZΜޥޜޥcZZZZZZZZZZZZZZZZZZZZZZZ֜ޥޜޥscZZZZZZZZZZZZZZZZZZZZc{ޜޜޜޥcZcZZZZZZZZZZZZZZZZZZZccΜΜ֔ބZZZZZZZZZZZZZZZZZZZZZZc}眢֜ccZZZZZZZZZZZZZZZZZZZ}Zc}cΔޔZycyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZZZZZZZZZZZckޜޥ祶ޥZZZZZZZZZZZZZZZZZZZZZZZZ֥ޥ祶祺kZZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺祺kZZZZZZZZZZZZZZZZZZZZZZތ֜梁祾cZZccZZZZZZZZZZZZZZZZZZޜޜ眾眾scZcZZZZZZZZZZZZZZZZZZZZ֜ޜ眶ޥkcZZZZZZZZZZZZZZZZZZZZZZ֜ޜޥޜkZZZZZZZZZZZZZZZZZZZZZk{ޜޜޜޜkcZZZZZZZZZZZZZZZZZZZZccΜ֔֔քZZZZZZZZZZZZZZZZZZZZZZk}眢֜cZZZZZZZZZZZZZZcZZZZZcZ}cΔ֜ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZZZZZZZZZZZZZZZZZZck֥֜ޥ֥ZZZZZZZZZZZZZZZZZZZZZZZcΜ֥ޜޥkcZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޔsZcZZZZZZZZZZZZZZZZZZZZΌ֜祶ޥތkZZZcZZZZZZZZZZZZZZZZZZ֜ޜޜޥscccZZZZZZZZZZZZZZZZZZZZΜޜ֜ޥscZZZZZZZZZZZZZZZZZZZZZZΜ֜֜ޜcZZZZZZZZZZZZZZZZZZZZZk֥֜֜ޥkcZZZZZZZZZZZZZZZZZZZZckΜΜΌքZZZZZZZZZZZZZZZZZZZZZZkyޜ֜cZZ}Z}Z}ZZ}Z}Z}Z}Z}Z}Z}Z}Z}cZ}Z}Z}Z}Z}Z}Zyc}ƔΜZuZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZcsޜ֥ޥ֥ZZZZZZZZZZZZZZZZZZZZZZZc֥֜ޜޜscZZZZZZZZZZZZZZZZZZZZZZ֔֜ޥޥޜsccZZZZZZZZZZZZZZZZZZZZ֌Μ祺ޥތcZZZZZZZZZZZZZZZZZZZZZZ֜ޜޜޜscccZZZZZZZZZZZZZZZZZZZZΜ֜ޜ֥kcZZZZZZZZZZZZZZZZZZZZZZΜ֜ޜ֜kZZZZZZZZZZZZZZZZZZZZZkޜ֜֜֜cZZZZZZZZZZZZZZZZZZZZZccΜΜ֔քZZZZZZZZZZZZZZZZZZZZZZkyޜΜcZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}ZZ}Z}Z}Z}Z}Z}Z}Z}ƔΜZyZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZcs֥֜ޥޥZZZZZZZZZZZZZZZZZZZZZZZcΜ֥֜ޜscZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޔsZcZZZZZZZZZZZZZZZZZZZZΌ֜ޥޥތkZZZZZZZZZZZZZZZZZZZZZZ֜ޜޜޥ{cZcZZZZZZZZZZZZZZZZZZZZΜ֥֥֜kcZZZZZZZZZZZZZZZZZZZZZZΜ֜֜ޥkcZZZZZZZZZZZZZZZZZZZZkޜ֥֜֜ccZZZZZZZZZZZZZZZZZZZZccƜΥ֔քZZZZZZZZZZZZZZZZZZZZZZkyޜ֥cZZZZZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZyZ}ΜZuZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZZZZZZZZZZZZZZZZZZck֥֜ޥޜZZZZZZZZZZZZZZZZZZZZZZZc֥ޥޥޜ{cZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޜޔkZZZZZZZZZZZZZZZZZZZZZZΌΔޜޜތcZZZZZZZZZZZZZZZZZZZZZZ֜ޜޜޜ{cZccZZZZZZZZZZZZZZZZZZZ֜֜ޥޥscZZZZZZZZZZZZZZZZZZZZZZΜ֜ޜޜscZZZZZZZZZZZZZZZZZZZZkޜ֜֜֜kZZZZZZZZZZZZZZZZZZZZZccΥ֜֔քZZZZZZZZZZZZZZZZZZZZZZkyޜ֜cZZZcZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}ZyƔΜZyZyZyZuZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuccccZZZZZZZZZZZZZZcs֥֥֜ޥZZZZZZZZZZZZZZZZZZZZZZZk֥ޥޥޥބcZZZZZZZZZZZZZZZZZZZZZZΔ֜ޥޥޜ{ckZZZcZZZZZZZZZZZZZZZZ΄ΜޜޥތkZZZZZZZZZZZZZZZZZZZZZZ֜ޥޜޥ{cccZZZZZZZZZZZZZZZZZZZZΜ֥ޜ֥scZZZZZZZZZZZZZZZZZZZZZZƜ֜֜ޥscZZZZZZZZZZZZZZZZZZZZkޜ֥֜֜ccZZZZZZZZZZZZZZZZZZZZccΜ֜ΔքZZZZZZZZZZZZZZZZZZZZZZkyޜ֜cZZ}ZcZZ}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}Z}֜ZyZyZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuccccccZZZZZZcccccZcsޜޜޥޜZZZZZZZZZZZZZZZZZZZZZZZkޥޜޥ祶焮ccZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺眺眺sckcccccZZZZZZZZZZZcZZZ֌֜眺眾cZZZZZZZZZZZZZZZZZZZZZZޜ眺眾眾sccZZZZZZZZZZZZZZZZZZZZZ֜ޜ眶ޜscZZZZZZZZZZZZZZZZZZZZZZΜ֜ޥޥscZZZZZZZZZZZZZZZZZZZZk眪ޜޜޜkZZZZZZZZZZZZZZZZZZZZZccΜ֜֔{ZZZZZZZZZZZZZZZZZZZZZZk}眢֜cZZZcZZZZZZZZZZZZZZZZZ}Z}ZyƜ֜ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyccZcZZZZZZZcckckkck{ޥޥޥޥZZZZZZZZZZZZZZZZZZZZZcZkޥޥޥ祶焮cZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺祺ޔsckkkkskkkkcccccccccccc֌ޜ祺祺kccZccZZcZZZZZcccZZZZZZ֜祺眾祾scZcZZZZZZZZZZZZZZZZZZZZ֜ޜޜޥ{cZZZZZZZZZZZZZZZZZZZZZZΜ֥ޥޥ{cZZZZZZZZZZZZZZZZZZZZc眪ޜޜޜccZZZZZZZZZZZZZZZZZZZZck֜֜֔ތZZZZZZZZZZZZZZZZZZZZZZk}眢ޜcZZcZZZZZZZZZZZZZZZZZ}Z}Z}ZyƜޜZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyΥޥޥޥޜޜޜޜޔޔތތބ{{{ss{Όޥ祲祲眲甮ބΌތޔޔ猪ބބބތތ眪眪焦sss{ssk{֌眶眶祶祶甲skkccccccZZZZcZZZccZZZZΜޥ祺祺眺町焪kZZcZZZZZcccZcZcZZZckޔ眺祾眺sccZZZZZZZZZZZZZZZZZZcc֜眺ޜ{ccccccZcccckkcccccccccZΜޜޜޥ焪scckccccckckkcccccZccccΜ֔֜ޜތcccZZZZZZZZZZZZZZccZZk眮ޜޜޜkccZZZZZZZZZZZZZZZZZZZccΥ֜֔ތZZZZZZZZZZZZZZZZcZZZc}c}k}ޜ֜cZZZcZZZZZZZZZZZZZZZc}Z}c}ZyΥ֜ZyZZ}Z}ZyZyZyZyZyZyZyZyZyZyZ}ZyZyZyZyZyƥ֥֥֥֥ޥ֥ޭޥޥޥޥޥޥޜޥޥޥޜ֥ޥޥޥޥޥޥޥޥޜޥޜޜޜޜޥޥ֥֥֥ޥޜޜޥ祲ޥޥޥ֥֥ޥޥޥ֥ޥޜޥޥ祶ޥ祶ޥ祲ޜޥޜ眶ޜ眲ޔ甲ޔޔތ献ތ猲祶ޥޥޥޥޥޥ祶ޜ眺眺眶ޜ眶眶眶眶ޥޜ眶ޜ眶眶ޜޔޔޔޜ眺ޜޜޥޜ祾眶眺町町甶町町甶ޔޔޔ町町町猶猶ތތތ献献猲祺祺祾祾ތsccZcccZZZcccZcccZZZcZk֜ޜޜޜތsccccZZZZZZZZZZZZZcZZk{֜ޜޥޥތkccZcZZZZZZZZckcccccZkޜޜޜޥscccZZZZZcccZcZcZZZZZZck֥֜֜ތZZZZZZZZZZZZZZZZZZZZZZc}ޜ֥ccZZZZZZZ}Z}ZZZZZ}c}c}c}Z}Z}Z}Z}Z}ZΔ֔cZyZucyZuZyZyZuZuZuZuZuZyZuZuZyZyZuZuZuƥޥޥޥޥޥޥޥޥޥޥޥޥޥ祲ޥޥޥޥޥޜ眮祶祶祲ޥ祲ޭ筲ޭޭޥޜޜ祶祲祲ޥ祶眲祲ޜ祶祲ޥޥޜޜޜޥ祶ޥޥޜ֜֜ޥޥ祲ޥ祶ޜޥޥޥޥޥޥޥޜޥޥޜޥޜޜޜޥޥޥ眺ޜ祺祺祺ޥ祺ޥޥ祺祺眺祺ޜޜ眺祺ޥޜޥ祾祺祺眶眺眺祾祾祾眺ޥ祺祺眺眺眾眾眺眾眾眾眾眾眺眺眾眾ޜ眺ޜ祶ޥ祺祺眾眾祾眺眾眾眺眺眺眺祺眺眺眶眶眶眶眺祺祺眶ޜޥޜޜޥ眶ޜޜ眺眶ޜޜޜޜޜޜ֥֜ޜޜޜޜޜޜޜޜޜޔޔޔޔ眲ޜޜޥ眲ޜޜޜޜޜޔޔޔތތތބބ{{sskkksΌΜޜޜޥޥބ{skcccZZZZZZZZZZZZZZZk{ޜ֜֔֔ccZZZZZZZZZZZ}Z}c}Z}Z}Z}ZZc}csޜ֜kccZZZZZcZZZZZZZccccZZ}c}c}ΜΜ֜ޜ֜ޔޔޔ֔֔֔֔֔֔֌֔֌֌ΌΌΌ֥ޥޥޥ֥ޥޥ֥ޥޥޥ֥֥֥ޥޥޥ֥֥ޥޥޥ֥ޥޥ祮ޜޥޥޥޥޭޥޥޥޥޥޥޥޥ֥֥֥֥֜ޥ֥֥֜ޥޥޥޥޥޥޥޥ祲祲祲ޜޜ֜ޥޜޜޜޜޜޥޜޜ֥ޥ֜ޥޥޥޜޥޜޥޥޥޜޥޜޥޜޥޜޥޜޥ֜ޜޥޥޜޜޥޥޥޥޜޜޥޥޜޥޜޜޜޜޜޜޜޜޜޜޜޥޜޜޜޥޜޜޜޥޜޜޜޥޜޥޜޥޥ֥֥֥֥֜֜ޥޜޜ֥֜֜ޜ֜ޜޜޜ֜ޜ֥֜֜֜֜ޜޜޜޥޥ֥ޥޜޥޜޜ֜ޜޜ֥֜ޜ֥֥֥ޥ֜ΥΜ֜Υ֥ޥޜޥ֥ޥޥ֜ޜ֜ޜޜ֥֜ޥ֥ޥ֜ޜޜ֜֜ޜޜ֥֥֔֜֜ޥ֥֜ޜޔޜޜ֥֥֥֥֥֜֜֜֜֜֜֜֜֜֜֔֜Δ֔֔ΜΜΜΜ֜֜֜Δ֔֔֔֔ΔΔ֜֔֜֔֜ΔΔΌΔΔƔƜΥ֥֜ք{{skskkk}k}k}k}c}cyc}c}cycycycycyc}ky{Ɯ֜֜֜ΜΥΜΜΔƥΜΜΜΜΜΜƜΜΜΜΜΜƜ֜ޜޔ֔֔ޔ֔ޜޔޔ֔֔֔ތ֌֌ތތ֔ޥ֥֥ޥތބss{{֌֌眮ޜޜޜ眲眲祲ޥ祶ޥޥޜޥޥޜޥޥ֥ޭޥޥޥޥ֥ޥޥޥ֥֥֥ޜޜޥޥޥޥޥ眶眶ޜޜޜޜޜޥޥޥޥޥ֥ޜޥޥޥޜޜޥޜޥޥޥޥޥޥޥ祲祺祺祺ޥޥ֥ޜ眺祾眶ޥ祾眾祾祾祺祾眺祺ޥ祾ޜޥޥޥޥޥޥޥޥޥ祶ޥޜޜޥޜޜޜޜޥޜޜޜޜޜޥޥޥޥޥޥޥޥޥޜޜޜޥޥޜ֜ޥ֜֜ޜޥޜޥ֥֥ޥޜޜޜ֜ޜޜޜޜޜޜޥޜ֜ޜޜ֜֜ޜޥޜޜޜ祲֥֜ޥޥ֥֥ޜ֥֥֥֜֜֜֜֜֜֜֜ޜޜ֜֜֜֜ޜޥ֥֥֥֥֥֥֥֥֥֥֥֥֥֜֜֜֜֜֜֜֜֜ΜΜ֥֜ΜΜΜΜΜ֜Μ֜Μ֜ΜΜΜΜ֜֜֜֜Μ֜Μ֜ΔΜΔΔΜ֜Μ֜ΔΥΥΜΜΔΔΜΜ֜֜֜֜֜ΔΜƜΜΜ֜֔֜Μ֜֜֜֜֜Μ֜֜֔Ɯ֜֜֜֜֜Μ֜֜֜֜֜֜ZcZZZZZZZZZZZZZZckkΌޜޥޜޜkcZZZZZZcccccckkkkkkkssΌ眶֜֜ޥޜ猢{{{΄֔甲猪ބ{{{΄΄ք{{{{{s{Όޜޥޥޥޥ甮sssss{sss{{{{ބބބքބքք֌֔ޥޥޜޥޜ甲sss{քބބք֌ތޔޔ眶眶甶眺眾眾眺ޜޜ眺眶ޥޜޥޥ眺ޜ眺眺眺眶祺眺眺眺眺ޜޜޜޜޜޜޜޥ眶ޥޥޜ֥֥֥֜֜ޥޜޜޜޥޥޥޥޥޥޥޥޥޜޥޜޥޥޥޜޜ֜ޜޜ֥֜ޜޜޜ֜ޥޜޜޜޥޜޜޜޜޜޜޜޜ֥ޜ֥ޥ֥֜֜ޜ֜ޜ֜֜Μ֥֥ޥ֥֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜Μ֜ΜΥ֥֜Μ֜֜֜֜ΜΜΜΜ֜Μ֜ΜΜΜΜΜΥ֥֥Μ֜Μ֥֜֜֜֜ΜΥΥΥΜ֜֜Μ֜֜֜ΜΜޜ֜ΜΜΜΜΔΜΜΜΥ֥֜֜ΜΜ֜֜֜֜֜֜֜ΜΜΜ֜֔ΜΜΜZZZZZZZZZZZZZZZZcZc{ޜ֥ޥޜccZZccccZZZZZZZZZZZZcZc{祲֜ޥޥޜc}Z}Z}ZZ}Z}Z}ZZZZZZZZZZZZZZZkΜޜޜޜޜ焚cZZZccZZZZZZZZZZZZZZksޔޜ祶ޥޜkcZZZZZZZZZZZZZZZZZZZccΜޜޥޜޔcZZZZcZZZZZZZZZcZcccccsޜ֥֜֜֔skccZZZZZcckkskks{{{{֌֌祲֥֥֭ޥ猦քބ{ބ{{΄Όޜޜޜޥޥ֥֜ޜޥ֥֥֥֥֥֜֜ޜ֥֜ބ΄΄֔ޔޔޔޔ֔ޔ֔֜ޜޜޜޜ֜ޜޜޜޜޜ֥֥֥֥֥֥֜֜֜֜֜֜ޜޜ֥֜֜֜֜֔Δ֜֜֜֜֜֜֜ΜΥΜ֥֜֜֜֜֜֜Μ֜Μ֥֜֜Μ֜֜֜֜֜֜֜Μ֜Υ֜֜ք{΄{{{{s}k}k}{{{kuku{΄քބ{cccccZZZZZZZZZZZccc{ޥ֥֥眮ZcZZZZZZccZZZZZZZZZZZZc{ޥޥޥ֥֔kZcZZZZZZZZZZZZZZccZZZcΜޥޥޥޜ{ZZZZckZZZZZZZZZcZcZZck֌֜ޜޥޔcccZZZZZZZcZZZZZZZZckZZΔޥ祺ޥބZZZZZZZZZZZZZZZZZZZZcccΜޜޜޥބsZcZZZZZZZcZZZZZZZZZccs֜ޜ֜ޥތcZcZZccZZZZZks΄֌֔ޥ֥֥֥֜֜֔֔֜ޜ{cZZZZZZZZZ}ZZ}Z}Z}Z}Z}Z}Z}Z}ZZks֥֔ތcccccccccksss{sss{{{΄΄΄Ɯ֜֜֔ބ{ss{΄ΌքƄƄΌքΌ֔ΔΔ֔֔֔֔ΜΜ֜֜֜cuZqZmZqZmZmZmZmZmZmZiZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZc{ޥޥ祶甪ZZZZZZZZZZZZZZZZZZZZZZcs祲ޥ祶ޜތcZZZZZZZZZZZZZZZZZZZZZc֜ޜޥ祺kZZZZZZZZZZZZZZZZZZZZccތޜ眾甾cZZcZZZZccZZZZZZZZZZZZZ֔ޜ眾焲ZZZZZcZZZZZZZZZZZZZZZZZΜޜޥ祺scZZZZZZZZZZZZZZZZZZZZck֜ޜޥ眲猶cZZZZZZZZZZZZZZZZcsskc{ޜޜޥޜkZZZZZZZZZZZZZZZZZZZZZccΜ֜ޔ焞ZZZZZZZZZZZZZZZZZZZZZZ}k}ޜ֜kZyZyZ}Z}ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZucy{ޜޜcyZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqZZZZZZZZZZZZZZZZZZc{祮ޥޜ甪ZZZZZZZZZZZZZZZZZZZZZZcsޥޥޜޜޔcZZZZZZZZZZZZZZZZZZZZZk֜ޥޥ祺甾sZcZZZZZZZZZZZZZZZZZZZc֌ޜ眾町cZZZZZZZZZZZZZZZZZZZZZZ֌ޜ祾祾焲cZZZZZZZZZZZZZZZZZZZZZZΜޥޥ祶skZZZZZZZZZZZZZZZZZZZZck֜ޥޥ祶{cZZZZZZZZZZZZZZZZZZZcc{֜ޜޜޥsZZZZZZZZZZZZZZZZZZZZZc}cƜ֜֔猞ZcccZZZZZZZZZZZZZZZZZZ}cyޜޥccyZyZyZycyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZycycy֜c}ZqZqcuZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqZqcZZZZZZZZZZZZZZZZZcsޥޥ眶猞ZZZZZZZZZZZZZZZZZZZZZZcsޜ֔֜ޥޔcZZZZZZZZZZZZZZZZZZZZZsޜޜޥޥ甾kZZZZZZZZZZZZZZZZZZZZZZތ֜量祾町cZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祾祾焮cZZZZZZZZZZZZZZZZZZZZZZ֜ޜޥ祺{kZZZZZZZZZZZZZZZZZZZZck֜ޜޥ祶sZZZZZZZZZZZZZZZZZZZZZcs֜ޜޜޜcZZZZZZZZZZZZZZZZZZZZZc}cΜ֜ޜ猞ZZccZZZZZZZZZZZZZZZZZZ}cyޜ֜{ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZuZuƔޔZuZuZqZmZqZqZqZqZqZqZqZqZqZqZqZmZqZmZqZmccZcZZZZZZZZZZZZZZc{ޥޥޜ猦ZZZZZZZZZZZZZZZZZZZZZZck֜֜ޜޥތcZZZZZZZZZZZZZZZZZZZZZsޜޜޥޥޔsZcZZZZZZZZZZZZZZZZZZZcք֜眾祾町cZZZZZZZZZZZZZZZZZZZZZZ֔ޜ祺祾焪cZZZZZZZZZZZZZZZZZZZZZcΜޥޥ祶skZZZZZZZZZZZZZZZZZZZZck֜ޥޥ祶scZZZZZZZZZZZZZZZZZZZZcs֜ޜޜޜcZZcZZZZZZZZZZZZZZZZZZc}cΜޥޔ焚ZZZZZZZZZZZZZZZZZZZZZZcyޜ֜{ZyZyZyZyZyZyZyZuZyZyZyZyZyZyZyZyZyZyZyZyZycycuƌ֜ZuZqZmcqZmZqZmZqZmZmZmZqZqZqZmZmZmZmZmZmkcZZZZZZZZZZZZZZZZcs祮ޥޜ猦ZZZZZZZZZZZZZZZZZZZZZZck֜ޜޥޥ猪cZZZZZZZZZZZZZZZZZZZZZkޜޜޥ祺sZZZZZZZZZZZZZZZZZZZZZZތ֜眾町cZZZZZZZZZZZZZZZZZZZZZZ֔ޜ眺祾{cZZZZZZZZZZZZZZZZZZZZZZ֜ޜޥ眶kcZZZZZZZZZZZZZZZZZZZZck֜ޜޥ祶sZZZZZZZZZZZZZZZZZZZZZcsޜޜޜޜkZZZZZZZZZZZZZZZZZZZZZc}cΜޜޔ{ZZZZZZZZZZZZZZZZZZZZZZ}kyޜ֜kZyZ}ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZuZuƔ֔cyZqcqZmZqZqZqZmZqZmZqZmZqZmZmZmZqZmZmZmkcZZZZZZZZZZZZZZZZcs֥֜ޥ產ZZZZZZZZZZZZZZZZZZZZZZckΜ֥ޜޥތc}ZZZZZZ}Z}Z}ZZZ}ZZZZZZZZZZk֥֜֜ޥޔsZZZZZZZZZZZZZZZZZZZZZc֌֜眺ޥޔcZZZZZZZZZZZZZZZZZZZZZZΔޜޜޥ{cZZZZZZZZZZZZZZZZZZZZZcΜޜ֥祺scZZZZZZZZZZZZZZZZZZZZckΜ֥֥ޥsZZZZZZZZZZZZZZZZZZZZZc}{֥֥֜֜kccZ}ZZZZZ}ZZZZZZZZZZ}Z}ZZZ}c}Ɯ֜֔sZZZZZZZZZZZZZZZ}ZZ}Z}Z}Z}Z}Z}ku֜֜kZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZu֔ZuZqZmZmZmZmZmZmZiZmZmZmZmZmZmZmZmZmZmZmccZZZZZZZZZZZZZZZZcsޥ֥ޥޜZZZZZZZZZZZZZZZZZZZZZZcc֥ޜޥޥތc}ZZZZZZZZZZZZZZZZZZZZZk֜֜ޥޥޔsZZZZZZZZZZZZZZZZZZZZZZ֌֜眾ޜޔcZZZZZZZZZZZZZZZZZZZZZZΔޜ眾ޥ{ZZZZZZZZZZZZZZZZZZZZZZZ֜ޜޥޥscZZZZZZZZZZZZZZZZZZZZck֜֜ޥޥkcZZZZZZZZZZZZZZZZZZZZc}{ޜ֥֥֜{ZZZ}ZZZZZZ}ZZZZZZZZ}ZZ}ZZc}c}Ɯ֜֔sZZZZZZZZZZZZZZZZ}Z}Z}ZZ}Z}Z}kyޜ֜sZuZyZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuƔ֌ZqZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmccZZZZZZZZZZZZZZZZcs֥֥ޥ眪ZcccZcZZZZZZZZZZZZZZZZck֜ޥޜޥތcZZZZZZZZZccZZZZZZZZZZk֥֥֜ޥޔsZcZZZZZZZZZZZZZZZZZZZc֌֜眺ޜޔcZZZZZZZZZZZZZZZZZZZZZZΔޜ眾ޥބZZZZZZZZZZZZZZZZZZZZZZZΜޜޜ眺scZZZZZZZZZZZZZZZZZZZZck֜ޥ֥ޥccZZZZZZZZZZZZZZZZZZZZc}{ޜ֥֥֜sZZZZ}ZZZZ}Z}Z}Z}Z}ZZZZ}Z}Z}Z}Z}Zc}c}Ɯ֜֔sZZZZZZZZZZZZZZZZZ}ZZZ}Z}Z}cy֜֜kZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZqZu֔ZqZmZmZmZmZmZmZmZiZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZck֜ޥޥ甦ZccZZZZZZZZZZZcZZZZZZZck֥֥֥ޥތcZZZZ}ZZcZZZZZZZZZZZZZZc֜֜ޥ֥ތsZZZZZZZZZZZZZZZZZZZZcc֌֜祺ޥ猶ZZZZZZZZZZZZZZZZZZZZZZZ֔ޜޜ然ZZZZZZZZZZZZZZZZZZZZZZZΜޜޜ眾sZZZZZZZZZZZZZZZZZZZZZck֜ޜޜޜcZZZZZZZZZZZZZZZZZZZZZc{ޜ֥֜ޥsZZZZZZZZZ}ZZ}Z}Z}ZZZZ}Z}Z}Z}Z}Z}Z}ƜΜ֔sZZZZZZZZZZZZZZZZ}ZZZZ}Z}Z}cuޜΜcZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZucuZu֌ZuZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZck֥֥֜ޜ{cZZZZZZZZZZZcccZZZZZZck֥ޥޥޥތkZZZ}Z}ZZZZZZZZZZZZZZZZZcΜ֜ޜ֥֌sZZZZZZZZZZZZZZZZZZZZcc֌֜眺ޥބcZZZZZZZZZZZZZZZZZZZZZZΔޜޥ{ZZZZZZZZZRRRRRRRRRZZZRRΜޜޜsZZZRRRRRZRZRZZRRZRRRZZk֜ޜޜޜkZZZZZZZZZZZZZZZZZZZZZc{ޜޜ֜ޥkZZZZZZZZ}ZZ}ZZ}Z}ZZZ}Z}Z}Z}ZyZ}Z}c}ƜΜ֔sZZZZZZZZZZZZZZZ}Z}Z}ZZ}Z}Z}Z}cuޜ֜cZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZucu֔ZqZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZZcޥ֥ޥ祲ޔcZZZZZZZZZZZcccZZZZZZckޜޥ祶眲献ZZZZZZZZZZZZZZZZZZZZZZc֜ޜޥޥބkZZZZZZZZZZZZZZZZZZZZcZތޜ焺ZZZZZZZZZZZZZZZZZZZZZZZޔ{ZZRRRZRRRRRRRRRRRRRZRZR֔sZRRRRRRRRRRRRRRZRRRRRZkޜޜkRZRRRRZZZRRZZZZZZZZZZc{ޜޜޜޥsZZZZZZZZZZZZZZZZZZZ}Z}Z}ZZΜ֜ޔsZZZZZZZZZZZZZZZZZZZZZZky眢֜cZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZuZucyƔޔcyZqZqZmZqZqZqZmZqZmZqZqZqZqZqZqZqZqZqZmZZZZZZZZZZZZZZZZZZZcޥޥޥޥތkZcZZZZZZZZZZZcZZZZZZckޥޥޜ祺{cZcZZZZZZZZZZZZZZZZZZZc֜ޜޥޥބkZZZZZZZZZZZZZZZZZZZZZcބ֜焺ZZZZZZZRZZZZZZRRRRRRRZZ֔sZZRRRRZRRRZRZRRRRRRRZRRޔkZRZRRRRRRRRRZRRZZRRRRZk眾kZZZRZRRRRRZRRRRRZZZZRZ{眲ޜޜޥsZZZZZZZZZZZZZZZZZZ}ZZ}Z}ZZ}Ɯ֜֔{ZZZZZZZZZZZZZZZZZZZZZ}Zcyޜ֜cZ}ZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZucyƔޔZuZuZqZqZmZqZmZqZmZqZqZqZqZqZqZqZqZqZmZmZZZZZZZZZZZZZZZZZZccޜޥ祲ޜkcZZZZcZZZZZZZZZZZZZZZckޜޜޥ眶焪ZZZZZZZZZZZZZZZZZZZZZZc֜ޜޥޜބkZZZZZZZZZZZZZZZZZZZZZZތޔZZRRRRRRRRRRRRRRRRRRRZRތsZRRZRZRRRZRRRRRRRRRRRZRޔkZZRRRRRRRRRRRRRZRRRRRZkkZZRRRRRRRRRRRRRZRRRRRc{眺ޜޜޜsZZZZZZZZZZZZZZZZZZZZ}Z}ZZ}Ɯ֜ޔsZZZZZZZZZZZZZZZZZZZZZZky眢֜cZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZycucyΔތZuZuZqZqZqZmZqZmZqZqZqZqZqZqZqZqZqZmZqZmZZZZZZZZZZZZZZZZZZcc֜ޥ祲甦ZcZZZZZZZZZZZZZcZZZZZZckޜޥޜ祶{cZcZZZZZZZZZZZZZZZZZZZc֜ޜޥޥބcZZZZZZZZZZZZZZZZZZZZZZބޜ{ZRRRZRRRRRZRRRRRRRRRRZRތsZRRZZZZRZRZRRRRRZRRRRRRޔkZRZRRRRRZRRRRRRRZRZRRZkcZZZRZRRRRRZRRRRRZRRRZZ{ޜޜޜ眶kZRZZRRZZZZZZZZZZZZZZ}ZZZ}Ɯ֜֔{ZZZZZZZZZZZZZZZZZZZZZZkyޜ֜cZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZycuk}ΔތZuZuZqZqZmZqZmZqZmZqZqZqZqZqZqZqZmZqZmZmZZZZZZZZZZZZccZZZZccޜ֥ޥ猦cccZZZZZZZZZZZZZZZZZZZckޜޥ祶眶猲cZZZZZZZZZZZZZZZZZZZZZc֜眶祾ޜ猾cZZZZZZZZZZZZZZZZZRRRZZބޔsZRRRRRRRRRRRRRRRRRRRRZRތkRRRRRRRRRRRRRRRRRRRRRRRޔkZRRRRRRRRRRRRRRRRRRRRZccRZRRRZRRRRRRRRRRRRRRRZs町町眺眾kZRRRRRRRRZZZZZZZZZZZZZZΜ֜ޔ{ZZZZZZZZZZZZZZZZZZZZZZky眢֜cZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZyZycuk֔֌cyZqZqZmZqZmZqZqZqZqZqZqZqZqZqZqZqZmZqZmZZZZZZZZZccckkccZZck֥Υ֥猢ckcZZcZZZZZZZZZZZZZZZZckΜޥ֜ޥބcZcZ}Z}Z}Z}Z}ZZZZZZZZZZZZZZcΜޜޥޥތcZZZZZZZZZZRRRRZZRZRRZZք֔kZZRRZRRRRRZRRRZRZRRRRRR֌ޜkZRRRRRRRRRRRRRRRRRRRRRR֔kZRRRRRRRRRRRRRRRRRRRRZcޜcZRRRRRRRRRRRRRRRZRZRRZ{町ޔޜޜcZRRRRRRRZRRRRZZRZZZZZZZƜ֜֔ބZZZZZZZZZZZZZZZ}ZZZZ}Z}Z}Zkuޜ֜kZyZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZuZucuZuZucq{ΔΔcuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZcckcZZZZZkޜ֥֥ޔccccZZcZZZZZZZZZZZZZZZcc֥ޜޥ֥քcZZZ}Z}Z}Z}ZZZ}Z}ZZZZZZZZZZZcޥޥޜ眾kZZZZZZZZRRRRRRZZZRRRZZބΔsRZRRRRRRRRRRRRRRRRRRRRRތޔkRZRRRRRRRRRRRRRRRRRRRRR֔cRRRRRRRRRRRRRRRRRRRRRRZޜcRRRRRRRRRRRRRRRRRRRZRcs眾ޔޜޜcZZRRRRRRRRRRRRRRRRRZZZZΜ֜֜֔ZZZZZZZZZZZZZZZ}Z}ZZZZ}ZZkyޜ֜cZyZyZuZuZucuZuZuZuZuZuZuZuZuZuZuZuZyZucqcqcqsΜ֌c}ZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiZZZZZZZZZZccccZZccZk֜֜֜ޔZcZZZZZZZZZZZcZZZZZcccck֥֥֜֜քcZZZ}Z}Z}Z}ZZZZZZZZZZZZZZZc֜ޜޜ眾猾kZZRRZZRRRRZZZZRRRZRRZZބ֔kZZRRRRRRRRRRRRRRRRRRRRR֌ޔcRRRRRRRRRRRRRRRRRRRRRRR֌cRRRRRRRRRRRRRRRRRRRRRRZޔZRRRRRRRRRRRRRRRRRRRRRZs甾ޜޔޜZZZRRZRZRRRZRZRZRZRZRRZZƜ֜֔ޔZZZZZZZZZZZZZZZZZZZ}ZZZkyޥ֜kcuZyZyZuZuZuZuZuZuZuZyZuZuZuZuZuZuZuZucqcucqsΔ֌c}ZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZcZck֥֜֜ޔccZZcZccZZZZZZZZZZZZcZck֥֥ޥ֥ތc}ZZZ}Z}ZZZZZZZZZZZZZZZZZc֥ޜޜޜcZZRRRRZZZRZZZZRRRRRRZZބ֔kZRRRRZRRRRRRRRRRRRRRRRR֌ޜcRRRRRRRRRRRRRRRRRRRRRRRތޔcRRRRRRRRRRRRRRRRRRRRRRZޔcRRRRRRRRRRRRRRRRRRRRRZk甾ޔޜޔcRZRRRRRRRRRRRRRRRRRZRZZƜ֜֔焢RRZZZZZZZZZZZZZZZZ}ZZZZkyޥ֜kZuZyZuZuZuZuZuZuZuZuZuZuZuZuZqZuZuZuZucuZqcqs֜֌ZuZqZmZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmccccccccccccZccccccs֥֜֜֜kskkkkkkkskkkkckcccccccs֜ޥޜޥތcZZZZZZZZZZZZZZZZZZZZZc֜ޜޜތkckcckkkkccZZRRZZZZRRZcތޜkZRRRRRRRZRRRRRRRRRRRRRR֌cZRRRRRRRRRRRRRRRRRRRRRR֌ޔcZRRRRRRRRRRRRRRRRRRRRRZތcRRRRRRRRRRRRRRRRRRRRRZsޔޜޔޜZRRRRRRRRZRZRZRZZZRZRRccƔ֜ޔ焢ZZZZZZZZZZZZZZZZZZZZZ}Zkyޜ֜kZuZuZyZyZyZuZuZuZuZuZuZuZuZyZuZuZuZuZuZuZucq{Μ֔cucqZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm{{sssssssskkkkskss{֌祮֥ޥޥބkccZZZZcZZZZZZZcccccck{祲ޥޥޜޔskccccccZccZZZZZRZZZRZ{kkccZRRRRRRRRRZZZZZRZksRRRRRRRRRRRRRRRRRRRRRRR֌kZRRRRRRRRRRRRRRRRRRRRRRޔcZRRRRRRRRRRRRRRRRRRRRZccRRRRRRRRRRRRRRRRRRRRRZscRRRRRRRRRRRRRRRZRRRRRZc֜眶ޔ{ZRRRZZRZZZZZZZZZZZcZZZk}眢֜kZyZyZyZyZyZyZyZyZyZyZyZyZuZyZyZyZyZyZuZuZucu{֔֌k}ZqZqZqZuZqZqZqZqZqZqZqZuZqZuZqZqZqZqZqƥ֥֥֥֥֥֥ޥޥޥޜޥ֜ޥޥޥ֥ޜޜޥޭޭޭޭޜޜ֜ޜ֜ޜޜޜ眮ޜޜޜޜޜޔޜޜޔޔޔޔޔތ֜ޥ祲祲祲ޥ眶ޜ祺眺眺眶眺眺眺眾眾眾眾眾眾甾甾甾甾猾ޔsskccccZcZZZZZZZZZZZZZksZZZZRZRRRRRRRRRRRRRRRckZRRRRRRRRRRRRRRRRRRRRZkcZRRRRRRRRRRRRRRRRRRRRZ{cRRRRRRRRRRRRRRRRRRRRRZcΔ֔ތބZZRRRRRRZZZZZZZZZZZZZZk}眢֜kcyZycyZyZyZyZyZyZyZyZyZyZ}ZycyZyZuZyZyZucucq֔ޔskycucqZqcqZqZmZmZmZmZmZmZmZmZmZmZmZmZmޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥ֥֥ޥޥޜޥޥޥޜޥޜޥޥޥޥ祲祲祲ޥ祲ޥ祲ޥޥ祲ޥޜޥޥޜ֜ޜ֥ޥޥޥޥޥޜޜޜ眾眾祾眾ޜ{kkkckkksskksskkkcckksք{skccccZZZRZRZRRRRRRRZk֔ޔ町焮ZZRRZZZZZZZZZZZZZZZZZZkޜޔscycyZuZyZyZyZyZyZuZyZyZyZyZyZyZ}ZyZ}Zycucyޜ֜Μ֜֜֜֜ޜޜޔޔ֔ޜ֔ޔ֔֔֔֌֌֌Ό֥ޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޥޜޥޥޥޥޥޥޥޥޥ֜ޥޥ祶ޥޥޥޥޥޥޥ祶祲祲ޥ祶ޜޜޜ祺眶祾祾祾眾眾眾ޔ甾甾甾甾町町ޔޔޔޔޔޜޔ甶甶甲ޔ֔֌献ތތތޔތތքքքք{{{{{{Δƥ֜ΥΔ猚֌ތ֌֌֌֌ք΄΄ք{sk}k}cycyc}cysƌޜ֥֜֜֜ޜ֜ΜΜ֜֜֜֜֜֜֜֜֜Μ֜֜֜֜֜քބތބތތޔޔ甦ޔޥޥ祮ޥ祲ޥޥ祲祲ޥޥ֥ޭޥޥ眶祶ޥ祲祮眶眶眲眲祶祲眲眲祲眲祲眮眲眶略眶祺ޥޜޥ祺眺甾甾ޔ眾ޔޔޜ甾ޔ町町眺眺ޜޔޜ眶甶ޔޜޜޔޔޜޜޔޔޔޔޜ֜֔֜ޜޜޜ֜֜֜֜֜֜֜ޜ֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜ޜ֥֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜ZZZZZZZZcZcs{ssskksƔޥ֥֥ޥkkcckkkcccccccccccckkkkΌ眺ޜ֜祾猶skkss{{{{{{{{{{{{{{s{{{kks{{{{{{sssskskkkkkkkkkkkkkkksޔޔޔޔޔޔޔޔ֔ޔ֔ޔޔޔޜޜޜޜ֔ޜޔޜޜޜ֜֜֜֜֜֜֔ޜ֜֜֜֜֔֔֔֜ΜΜΜ֜֜֜֜ΜΜ֜Μ֜֜֜֜ΜΜΜΜΜΜΜΜΥΜ֥֜ޥ֜֜Μ֜֜֜֜֜֜֜֜֜֜֜֜֜cZZZZZZZZccZZZZZZZkޥ֥֥ޥcZZZZZZZZZZZZZZZZZZZZZZ眺ޜޜ眾sZZRRRRRRRZZZZRRZRRRRRZZޔZRRRRRRRRRRRRRRRRRRRRZksZRRRRRJRJRJRJRJJJRJJJRRcRJRRRJJJJJJJJJJJJJRJRc{ZRJRRJJJJRRZZcccccckks{{ssss{{{{{{{{{{ޔޔތތ甾ޔޜޜޜ眺町眾町ޔޔޜޜޜޜޔ֔֜ޜޜޔޔޔޜޜޜ֥֥֥֔֜֜֜֜֜֜֜֜֜֜֜֜֜֜֔֜֜֜ΔΜΜΔΜ֜ΜΌsk}kkcycycucucucucukk}kykyk}s{{ckkcZZccZcckskkkZZcޥ֥֥ޥZcZZZZZZZZZcZZZZZZZZZZZƄ眶ޥޜkcZZRRRRRRRRZZRRRRRRRRZRޔ{ZRRRRRRRRRRRRRRRRRRRRRckRJRRRRRRRRJJJJJJJJJJJJJ{sRJJJJJJJJJJJJJJJRJJRRJRތcRJJJJJJJJJJJJJJJJJJRRRc{ZJJJJJRJJJJJJJJRRRRJJRscRRRRRRRZZZRZZZkkcZZZckΌ甾ޜޔcZZcZcssZccckss{{{ք{{΄֔֜֜ޔ֔ޔ֌ք΄ք{{{{΄֌֌ތքΌ֔ޔ֌΄ΌΌΌ֔֜֜c}cuZqZqZqZqZqZqZmZqZmZmZmcmZmcmZmZmZmZicZZZZZZZZZZZccZZZZcƄޜޜޥޜcZZZZZZZZZZZZZZZZZZZZRZ{眺ޜsZZRRRRRRRZZRRRRRRRRRRRRތ{ZRRRRRRRRRRRRRRRRZRRRRZcRRJRRRRJJRJJRJJJJJJJJJJsތkRJJJJJJJJJJRRRRJJJJJJJJZJJJJJJJJJRJJJJJJJJJRJRZ{RRJJJJJJJRJJJJJJJJJJJRcޔRRJRRJJRRRRRRRRRRRRRRRZc֔ޔ猺RRRRRRRRRRRRRRZRZZRRZRk眮ޔތcR}RZZ}Z}Z}Z}Z}Z}ccZycyZuZuZuZuZuZuZuZuZuƔ֔ZuZqcuZiZmZqZqZmZmZqZqZmZmZmZqZmZmZmZmZmZccZZZZZZZZZZZZZZZcޜ֜֜ޥZZZZZZZcZZZZZZZZZZZZZZZ{町ޜkZZZZZRZRRRRRRRRRRRRRRRRތcRRRRRRRRRRRRRRRRRRJRRZkRRRJJJJJJJJJJJJJJJJJJJJskRJRJRJRJJRJRcZcZRJRJJJJZRJJJJJRJJJJJJJJJJJJJJRZsRJJJJJJJRRRJRJJJJJJJJRcRRRRRRJJRRRRRRRRRRRRRRRc֔ޔތ猺RRRZRRRRRRRRRRRRZZZZRRkޥޜ֌kZZRZZ}Z}Z}Z}Z}Z}ZyZyZyZyZuZuZuZuZuZyZuZuƔΜk}ZqZmcqcqcqZmZmZmZmZqZmZmZmZmZmZmcqZmZmZZZZZZZZZZcZZZZZZZkƌ祲ޥޥޥcZZZZZcZZZZZZZZZZZRRZRZ{cZZZRRRRRRRRRRRRRRRRRRRRZRRRRRRRRRRRJRRRRRRRJRckJJJJJJJJJJJJJJJJJJJJJJJskRRRRZZZJJJJRZZRRRJJJJRJRJJJRJJJJJJJJJJJJJJJJJRZ{RJJJJJJJJJJJJJJJJJJJJRcRJRJJJRJRJJJRRRRRRRRRRRRތRRRRRRRRRRRRRRRRRRRRRRcƌޜތcZRRRZZZZZZZ}ZZ}Z}Z}Z}ZyZyZyZyZyZuΔ֜kZyZyZuZqZqZuZuZuZqZqZqZqZqZqZqZqZqZqZmZZZZZZZZZcZcZZZZZZc΄眮ޜޜޥccZZZZZZZZZZZZRZZZZZRZZscZZZRRRRRRRRRRRRRRRRRRRRތ{ZRRRRRRRRJRJJJJJJJJJJJckRJJJJJJJJJJJJJJJJJJJJRJscRJJJJJJJJJJJRJJJJJJJJJJRJJJJJJJJJJJJJJJJJJJJJRRsRJJJJJJJJJJJJJJRJJJJJRcJJJRRJJJJRJRJJRRJJRRRRRZޔRRRRRRRRRRRRRRRRZZRRRZk甲甲猶cZZRZRZRZZZZ}Z}Z}Z}ZyZ}ZyZyZyZyZyZuΔΥkZqZmZqZqZqZqZqZmZqZmZqZmZqZmZqZmZmZmZmZZZZZZZZZZZZZZZZZZcƌ祮֥ޥޥcZZZZZZZZZZZZRRRZRRRZRZ{kZRRRRRRRRRRRRRRRRRRRRRR{RRRRRRRRRJJJJRRJJRJJJRZcJJJJJJJJJJJJJJJJJJJJJRJscJRRJJJJJJJJJJJJJJJJJJJJRJJJJJJJJJJJJJJJJJJJJJJRsRJJRJJJJJJJJJRJRJJJJJRcJJJJRRJJJJJJRRRJRJJJRRRZޔRRRRRRRRRRRRRRRRRRRRZRc眲ޜބcRRZRRRRRRZZZZ}Z}Z}ZyZ}Z}Z}ZyZyZuΔΜcZuZuZqZqZqZqZqZqZmZqZqZqZmZqZmZqZqZqZqZZZZZZZZZZZZZZZZZZcƌ眪֥֥ޥccZZZZZZZZZRRRRRZZRRZZZ{kZZRRRRRRRRRRRRRRRRRRRRRZRRRRJRRRJJJJRRJJRRJJJZcRJJJJJJJJJJJJJJJJJJJJJJscRJJJRJJRRJJJJJJJJJJJJJJRJRRJJJJJJJJJJJJJJJJJJRRsRJJRRJJJJJJJJJJJJJJJRRcJJRJJJJJJJJJRRJJRRRRJJRZޔ{RRRRRRRRRRRRRRRRRRRRRZcƔ甲ބZZZRRRRRRRZZ}Z}Z}Z}Z}Z}Z}Z}Z}ZyZuZuƌΜcZuZuZuZqZqZqZqZmZqZmZqZmZmZmZmZmZqZmZqZZZZZZZZZZZZZZZZZZcƄ眮֥֜ޥcZZZZZZZZRZRRRRRZRRRZRZ{cZZRRRRRRRRRRRRRRRRRRRRRZRJJJRJJJJJJJJJJJJJJJRZkRRJJJJJJJJJJJJJJJJJJRJJskRRJJJJJJJJJJJJJJJJJJJJJRJJJJJJJJJJJJJJJJJJJJJRRkRJJJJJJJJJJJJJJJJJJJJRZJJJJJJJJJJJJJJJJRRRRRRRZޔRRRRRRRRRRRRRRRRRRRRRRZ町{RZRZZZRZZRRZRRZZZ}Z}Z}Z}Z}ZyZuΌΜkZuZuZuZqZqZqZqZqZqZqZqZmZmZmZmZqZmZqZmZZZZZZZZZZZZZZZZZZcƄ眮ޥޥ祶ZZZZZZZZRRRZRRRRRRRRRRZ{cZRRRRRRRRRRRRRRRRRRRRRRތ{ZJJJJJRJRRRJJJJJRJJJJJR{sZJJJJRRRRZZRRRRJJJJJJJJskRRRJRJJRRJRJJJRJJJJJJJJcZRRJJJJJJJJJJJJJJJJJJJRcRJJJJJJJJJJJJJJJJJJRRRkRRJJJJRRJJJJJRJJJJJJRRRZޔޔތJRRRRRZZRRRRRRRRZZZZcZk眲ޜބZRZZZZZRRRRRRRZZZZ}Z}Z}Z}ZyZyƌΜcZuZuZqZmZqZqZqZmZqZmZqZmZmZmZqZmZqZqZqZZZZZZZZZZZZZZZZZZcƄ祮ޥ祶祶ZZZZZZZRRRZRRRRRRRRRZRZ{cRcZsssssssssssskkkkkkssyk֜֔֌skkkkkkskccJJJJJJJJJJRZsRZR,R{  !ssZZJJskRJJRRJJJJJJRRccss)1 !(J(RkcJJJBJJJJJJJRZJJJJJcccccckckkkkkkkkk{qk֔֔kkkkkkkkkkkkkkkkJJJJJJRZsRJRRRRRRRRkc{{ ! ),1sZZZZRRZRRRRRRRRRZZZ}Z}Z}ZyΌΜcZuZqZqZqZqZqZqZqZqZqZmZmZmZqZmZqZqZqZqZZZZZZZZZZZZZZZZZZc{眲ޥޥ祺ZZZZZZRZRRZZRRRRRZRRRRZ{ZZskB BRRRRJJJJJJRZs !{ƥ(B{֔cRJJJJJJJJJJ1) 11RRJJJJBBJRZJJJJJ11  !RRJJJJRckRRJJRRck  99ZcRRRRZZZZRRRRRZZZ}Z}ZyΌΜcZyZqZqZqZqZqZqZmZqZmZmZmZmZmZqZqZqZqZqZZZZZZZZZZZZZZZZZZc{眲ޥ眶眺ZZZRRRZRRRZRRRRRZRRRRRZ{ZRsk ! )JJJJJJJJJJRZmZ!! iZcRJJJJJJJJJJ!! !)ccBBBBJJRBBBJJ!) JJJJJJRZcJJZZ{s  ccZZRRZZRRRRRRRZ}Z}Z}ΌΜkZyZuZuZqZqZqZqZqZmZqZmZmZmZqZqZqZqZqZqZZZZZZZZZZZZZZZZZZc{ޜޥޜޜZZZRRRRZRRZZRRRRRZRRRRR{cRss) )JJJJJJJJRRJZ RRJJJJJJJRJJ! ZcBBJRcRBJBB!!JJJJJRRcތcJR{{))ZZRZRRRZRRRZ}R}R}ZyZyƄƜkZuZqZqZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZcsޜޜޜޜZZRRRRRRZRZRRRRRRRRRRRRscRsk   )1JJJJJJJJJJRZec() ZRJJRJJJJJJJ9 1 JJJJZJBBBB11 RJJJJJRcsJJ{$R {s}RRZRRRRRRRR}R}R}R}ƄƔsZuZuZqZqZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZc{ޜޥޜޜZZRRRRRZRRRRRRRRRRRRRRRsZRkk 99JJJJJJRJJJZc cRJJJJJJRRJJ! !ksBJZJJBBJJJJJJJRs{JJ{(J1)RZRRRRRRRRRR}R}Z}{ƜkZuZuZuZqZqZqZmZmZmZmZmZiZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZcsޜޜޜޜZZRRRRZRRRRRRRRRRRRRRRRs{ZRck ) 1JJJJJJRJJJsk cRJJJJRJJJJJ RJބZJJBBBJJJJJJRssRJ{$Jkk}RRRRRRRRRRZR}{ƔkZuZuZuZuZqZqZqZmZmZmZmZmZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZc{ޜ֜ޜޜZZRRRRRZRRRRRRRRRRRRRRZ{{cRcs) )JJJJJRJRJJ!!   cRJJJJJJRJJJkkΌRJJBBJ JJJRJRZssRR{1  91RZRZRRRRRRRR}{ƜsZuZyZuZqZqZqZqZmZmZmZmZiZmZmZmZmZmZmZmZZZZZZZZZZZZZZZZZZc{眶ޜ眾町ZZZRRRRRZRRRRRRRRRRRRRZs{cZks9BJJJJJJRJRJ!{s{{ ZRJJJJJJRJJJ !){sss !)!1 1JJJBJJƽ1 JJRRJJZsZJJ{1  ZRRRRRRRRRZR{ΔsRyZ}ZyZuZuZuZuZqZqZqZqZqZqZqZqZqZqZqZmZZZZZZZZZZZZZZZZZZZ{眺ޜ眾眺ZZRZRRRRZRRRRRRRRRRRRRRk{cZck {{!!!!!! {)s{kkJJJRJJJJccssRRRRJJRRRZkk cRJJJRJJJJJJZcccRJJJJJJJ{RJJBBJkkƥ! !s  ! !s! s!!)!s91JJJJJJZscJJs )kkZZZZck!ccRRRRRRRRRZ{ƔkZyRyZyZuZuZuZuZuZuZqZqZmZqZqZqZmZqZmZqcZcccckkcccccZZZZZc{眺ޜ眾ZZRRRRRRRRRRRRRRRRRRRRRkscRck cZJJRJJJJJccccRJJJJJJJJJJJJJJJJJRJks JýJJJJJJJJJRRJJRR{)cRJJJRRJJJJJ!sccccRJJJJJJJJJ{9 ޔRJRJBBJJJJJBBBBBBBBBJBBJZccZZZ kcJJJJJJRsZJJ{ 1ccJJRJJJJRRRRc !)ssRRRRRRRRRRsƔsR}R}RyZyZuZyZuZuZuZuZuZqZqZqZqZqZqZqZmkkkssskkkkkkkkccZZc{眺ޜޜZZRZZZZRRRRRRRRRRRRRRRZksZZckkcJJJJJJJJccccZRJJJJJRRRJRRRJJJRZJs$skRRJRRRJJJRJJJJJJRR]Z !kRJRRRRZRJJJ 1sZZccRJJJJJJJJJJJ EJRBJBBBBJBBBBBBBJBBJJBBJRZZckν)  JJJJJJJRR{{ZJJs) RRJJJJJJJJRRRRRcks{RRRRRRRZRZ{Ɣ{Z}R}R}RyZyZuZuZuZuZqZqZqZqZqZqZmZqZmZmZZZZZZZZZZZZZZZRZZkƄ眾眺ZZRRRRRRRRRRRRRRRRRRRRZsscRckcZJJRRJJJJcckcZRJJJJJJRJJJJJJJRRRJέ!RRRJJJJJJJJJJJJJJJJJƄi{kRZkscRJJJ$)sZcZZRJJJJJJJJJJJck()ތcRJBJBJBBBBBBBBBBBBBBBJRZZ֥49s ccJJJJJJJJZ{{ZJJs99sRJJJJJJJJJRJRJRRRZkk{$9$B}RRRRRRRRRR΄Ɣ{Z}R}RyZ}ZyZ}Z}ZyZyZyZuZuZuZqZqZqZqcqZqƜΜ֜֜֜֜֜֜֜֜֜֜֜֜֜֜֜ޜޔ֜ޜޥޥ眺ޔ猶ބބބބ{然焲ބքބބ焾ބތތތބ֔skcsskkRZccZcZZckckcZRRRRJZccZZZcccZZRRZZZccZZZJRRRRRRRRRRRƄkkkkkRRRJJJ!sssscRJJJJJJJJJJRZ !q{sRJBBJJJJJBBJJJJJJBBJBJZcýc  1JRJJJJJJJJZƄRJJZZJRJJJJJJJJJJJJJJJRJZkkksB1RRRRRRRRRR{{cZZ}ZuZ}ZuZuZyZuZqZuZqZqZqZqZqZqZmZqƥ֥֥֥֥֥֥֥ޥ֥ޥޜޥޜޜޜޜޜޜޔޜ眾眾ޜޜޜޜޜޜޜޜޔޔskk{s{uksssssksssssssssssss{ތkcc 01skcccccccƌkccc $)ekscZZcZZcZZMZsckkkcccZZZRRRRRRRRJZkMB41 ZRJJJJJJJJJZsތ{ZRJRRJJRJJJRRRRRJRRRJRJRcckcZ) )RRRRRRZZZZƄ֔֔֔ΔΔ֔֔֔֌֌ΌΌ΄΄΄{{{ssƥޥ֥֥֥֥֥ޥޥޥޥޥޥޜޜޜޜޜޜޥޥޜޜޜޜޜޜޜޜޜޜޜ{kk{{Μkck UR{sZcckƌkccc !u{kccccZc 41 cք{ccccccss{ބ{{{{ބބ{cckckcc!ZZZZZZZZZcƌ֔֔֔֔ΜΜ֜֜ΜΜΜΜΜΜΥΜΜΜΜΜƜΜ֜ޥޥޥޜޜޜޥޜޜޜޥޜޜޜޜ町甶ޜ眾眾祾ޥޥޜޜskk{{֜ccc  QRskcƌsccciscZcZccέ4!,!!ֵ(! ksΌ{cccksތބތތތތތkccckk (1֔ޔ֔֔֔֔֔֔֔֔Μ֔֔֔֔֜ޔ֜֔֜֔֜֜֜֜֜Μ֜ΜΜƜZZZZZZZZZZZZZZRZZZk΄眾眾ޜ{{{{{{{焾{{{{{{{{skcss{քs{ss{s{ccccks{{{kcc ,!sތkccc $1֌ccccc{0) $)0)kքcs΄ތތތތ猾kcckk 89ޔޔޔ֔֔֔֔֔֜֜֜֔ޜ֜ޔޔޜޜ֜֜֜֜֜֜֜֔֜֜֜ΜΜZZZZZZZZZZZZZZRRZRcscZRRRRRRRRRRRRRRRRRRRRZsscRckccJJJJJJRRZJJJJJJJJJJJJJRRJJJέ!ZZRRJJJJJJRRRRRRJJZZkRRZZkkZRZR )EZssssccccΥ89s{{ek c{skcck yY־ۭ5 ++#U;;\S[[7\T\9\d\z$v 6W7V7www wv Wv w :9 9 87;=\[x w z y  y 8 X Xx Yy Y # +W#z<;y+t +yW +7lxw  + |ֻ_; x W 6 w޺S#   Ww76wޚ<\TSW +6XX6 U TQ4"޹ :$XWXW7WXx XWWWXW7*ZzޚD5w WwxwWwWwxw xwWwWww v *ܕ9y޾V v x W 7VWw8W XWWv8 W WV76 V52Yxޞx6 55  + +V U4443 + +Z6 5 6  6 7676666665 : 999W8<=[\W y z #Yy \,x WX y Y + +#ޛ\<;UX +8 +rKW7 6 + s翿;9 W 7柎T xwxW 7;w +7X +z +X + U U"޻Z wxwXxxxXwWWWW*Yz֙z+Wx 889X 8WXyY78 + + 3z{   6777787 77  8 Rl<\3S#Xx  Y7x vx y8YTd +W 875 +6 + + + + + +Z* +Xw +6 + 865X7 + K;TC:   xy9X x?vT x xw x x xwxWW w W VyV + u  ֻz  yxYxYxXxxxXXXwYy"l֙YYy x 8 X 8X X X Y xX x Xx xw X XL8֟C <#w 8 7 Xx X W 8    +7q2{ֿ֛35vU7W WV6U  6;{9Η V  7 6  W7 +  WXxxyx XwxXe;;;}DT  xwX x y v 6W X 98 R\^]u + +xy +9Vx5v|*v +w +w +w +vvvV +6WW +pc:;  x wxwW  ֽ;ߟvtwXYy  xwxy޻w+37 +    u s͛ޘޙ wwXwXWWW Xw x x Xw7Xy *m8z:xXW7WXWX78wx xwWW7 "C9Kx #5xXX Y vVvVW8WWx6 N*ݝZ{ߦS34UUV7WXwWV 67   ";ZΛ7  W 6 VV + 7   7    +1"l^?_\#YX  8    + pmz</Uu +5 +4 +6vv +v +W +w +4VwU +wUu6;Zz޺1;V +v +xwvU4T +U +9y +YXxw5s柞R34  V żv2 x  w ww xwx w 7W 7[|+W6 +6 +4    r|޼9ַ xwXXXxXWXxXWW67 6  "lZޝ;Wx V xwxwxw xwWwwwVv36D8~qC WVyyYX 66 WwWv877 7  O2Z֚ޟ2+Ww 8 7 +7W wV7 67  + q"SY֚u+57W 7676 ޼ֻּּλΛƻΛֻ֛yƚƘ:\\l[t|;m\ldZu\d\tld\dd|;>>^?>\=_^>~<=]^=^==;:;:ߺ<<[><޼޻޻<<ֽ޻޻;;޹޺ޚޚޙzֹ޼֛޹߻ֻ޼ޛ޻zޚyޙxwֹֻx8yzYY֚Yyֹ֙޺޹ޚֺޜZֻyx޸YyzYy[z7Zyzޚz9ZyzyZyYy9XWY7|ڽڽٽ٭ح׽WڭYڭy:9wZ:9[Y;|t|{7zz֚zY9yyxYxyxYYYY9    8z$8L~m[T3Wxx+3+#33;D\\l\u:[9:?ֻ޼־{֛:}\{>\=߼=;=޼zޗ޻޼޺޻{޺xy9֚ޛ֘zֻ޻ֺޚֺޚ9zΙ8zzzޛ޺Yzz޻zޚzޚz֚zֺޛֺֻ֚89zx֚XXzXXwx޺֚YZYzzzZ{YZYXX֚zXzΙ֚yyƘxWXYzVWvW9ZVΘ֘Xι޹֘޹{zZΚZzZΚzzZZ[Z[9 9  9    9vY<]8 W 87  Z98  + +<\#5UU 7  + + + + + *9\=瘭33#++<3;CYTT\wTvT\d}ud||dlt|ttt|tttݝ|::;9]<;{ƽν==>^=ߜ޼ޛz޻Wޙ޻zޚ[Z޼޻YYޚ޹ޚֺֻּ޼޻{Y{ޛޛzZޚz:Z:9{ֻZ֛޻޻֚{z֚޺YyYYZzzx֘ƸιwY8zޚX98}|}||֜}Ɲ}|ޜΛ;;[yXZ޻;]\{::Z{Zzޚ9Yz֙zyYX |>=_=4{$  : : ; : y YY99    + +9z\]e88: +:Wyzy9xY88w#M XX xwy yxw +5  8 x 8z;;;  V46={ߟ0+ xXyxy yy yX Y x Z?33X7V w7WWw W V V vU#U޺^ߙDSx  z  Y XYzyYXy v "t;޺x3V XW V XW X W     + +2_\|8L" + + 6 6  U 5 5 U u65*t޻w## t#VuV###U#V+3CS{_ZzΘWZڭ\ּzzZyZzޚ޻Y|ּޓ +vTu +Tt + +ss [:  Z${  =   Z  9 + + + + + +V9\]D +x 7W9Y Z yY ;$ ߿3 y  V +;_Q#zx xWx7ߖ {,4 xxxyx W68z>7$   x X8 WXxywֺֻߎ3 xyyWXxy w xX[mZw,S xy XxyW 6 7 7X "LY9Μ[xvwuvwwWUv V V6t"֛^S3U U 5v V uVT+;YTd{[}twl\t{;5 + + + +V +v +vuu x   \]Y YX  9 + + + +u\[D Vw V 8X 9y898Y 8 8W  + + + +pCx     Y$D];>_< +8   +:  +8 9 + +wyλ޿ϱK  yL]L;<x V_z*   y XxX8X 8ص=ߞ#w#+9$w y x 79֛ X z z y Y  +Yּ#w w wx Xx xW W WXy W 2[\:[ֺֻ X8 L:<+www W  Vw6 U+v+Z]Vl u v wxYwxYyxywwWxy96 p2}Z]s#v5V wuVU5565 w|, +uv +U +u +5v +v + +vvvu  =  + + + + +:  + +8޺]}X  zYYX9 + + + + +;Ǘl    9  Z 9  +|U+y yy xY x 6;_~2# 8$ yxx x x ;$w 6 U6֛ޚ  8 X X Y xW V8 +Xָ޻2+x w Yxw yWXW7W 8xW V Ut+dz v x W xxxy y y x W T#x}cwxwxX V 6768x55*<|u4#w 6v X 7 7W X WX75#[Z +UvvvVvvuvu =^7 8 :::9 y^8 898  yK  yw 6t|13yyxؽ~5 : yyyxXy xV yֺ֛VW w xy xxXVyޚ޺ߖ3#X y wxxxxXwxX8XY WX Y"\Yz xxYxYxYxyxxxxx8Y4UΙ}cx xxXwXxxX 9wxV7vW*ޕyz~tx wWvWW8V 7VWW 76 +U#z[Ƙ#vvvvvvvvvVuv  ]8 + +  :9 +Y=x 8   + +9DzK   W5T|_3y    yWw Y7ؽm+ 9 yxy yX xxx W6z֚޻:$w Ww yx yxy x WXw6 z2#w Xx xw XxXx Ww8WXx xV8X "d9Κ޻޻ Yx YX XXXxyxxxxwXW8X #Θ~TtxXWXxXW xxww88 Ww76 WVp*Y޺nsw x w WwVV8W76 7V5 +u+:Z8 +vvvvvvvvVuvu =>8 : +9::9 z=89 +9ϳK   w 6t|3 yy  Xy 8}e+  [ zyyxyw XV ֛ߛ,  xxyyxyxxxy xXV Yֻ޻_3#xXyw xxxXXwxXXxy WX 8"\9Λֻ޷  xYxYxYxyyyxxxXX84#7X]Ul9 xw7xyWXxxwX 8wx67vW*Yޛޜ]4 w 7wXVWW8W7VW76 3Z[vvvvvvvv >] +7 + +9 +=# 8 xwx + +9DzS  y  W 6T|=1; yxy xwwYٽT#  Y yyxy y yXXx 7 z޺ v yxyxXxXw x x w xWW Z֚޻?S#Xx xw xxXX WW8Wxx xV87 "lΚޛ޻vwXX XXXxXxyxyxYXXX87+7Utx XW XX7W xxww8 X Ww6 WV*Zy\U3wVX W 8W7677Ww7 7 6 + +;:zζ +t +v +v +vv +vvVuvv +vu  ]^X  +::9  +<]:,X9xXY_dzK  zw 6t|3  y  xwWy 9֚etWw 8  876 76 76 3[{Ζ +vuvvv +vvVuVuVu  {$<=>8 Z:   + + +<=$7X989 +  +YK  w +:   x yw Wy Ƽmv  zy X wxV ޻4  YxX y xyxyw WxXwy֛ޝeuyY XxXX8WWX YxXwWW ";myzֻZ$wxyyxyyxXxyx yxXX 84v#8]v|yWXxXWXxXww8 8wX67v6*?YzDuwxX 8X8677776[; + +vvvvwvvvvvvuv wz$y;] +:9 + + + + +z]6 9X 8  9 8    9ƻ_Kw 5ּ_3$z$ x \ yyw V Y ƻe# y y  }$ xW 6޺:$v x yXXXx XX yyYyxx Xx7V 9TT9y x WXW87WW8X xWwV8":m9YޛZ$Vwy yxxxxxXwXxxx XW87u#7]y X 7 XXXW Xwww88 WwV W6*>zy#Ww8W 87767777 76 5#|ZƖ +v +vvvVvVvvv +vuvu +   v:4>\] + +z=^, 8 9 Y 9 + +<߿D    w8 |$    X 9μ|]  yy  xw xW z޺:4xwxy Z y yyy xxXV Yֻޚ, yyx Yx XxXXXx XwxWXX*lY{֚DWxxyyxYxYXYxyx YX8w76͗Z xxxX 8xXwW8 8wXW7V62_z:9$vX 8 78 67W778 ;$ 7W77 X +Vٽ\εvvvvvvvvvvv   VD<\  + + + +z]Z<4  8  +ٽ_DzS   vuֻ֔?*xwx  x8 λM$y yyy  xxx x w 7zD6 xw9 X Xxx x yxyxw Xw6  Yκ޻޺8$u yXXx 8 W 8W8W7W Xx XW W *Z}9z<=瞶B5+6+4#4VW 6  5 7 69 +:=:}S;T 5  V645T +4 +U;ƽ_rC4V 6V 6V V5 6  +6  6 6s t }ξ\\vvw,:,#x$9$ZΛֺ晅K$+##$$3#++ ""θƚY2   y yXyU 5Ux#XV 6-*~ֻ֚y4v8 xXxXXXxXWXWX6x v#ݜywX 8ww8 Y X8x85v5Z :=yyyY5VW 8 vwVVUV5  + +Z:޵  + +t + +:x:99;{ޛֻ|{|{:}<|yֻ֚|֛ޛֻzޚzֽޜzXY8Ιֹޙ;μZZ:ZZ9[z[Z٥ZzzK7#7# +X75 4 5 v4 565  +4 +7D޹޹޼St#43 U + +T   + +2Xl޹zC"# + SR4u  +v#x#7#vT n:\zΚ֚Lt#    wvw 5;XΗ  yxWv UT 6V Vvu t u t wv S*ܮ8yY,YY Ww WW + +6V8 +6 Z6r2 +RT +U + + +t +3S +T +2\];<\<]<<;;<=}=;]<=<<<ֺޚθֹ[zy޻޼ֻ޻ֻ޼޼ּy9ֻ޻޻ֻ޻ޛ޼Z{ޛ:Y޻ֺzΛ[֙ޚޘxYYYzޛ{Z:[;yZ[Ɯƹy=޺::{:ڭZzud4\SSCTC;4L9֛ޚXUdVLS+u4 4   4  *lYytS55 +3  +s + +5 [ݵ֚֘< wV6 uVxYW ###UwWz{:;{[ص::ZZƸW^========?^]\><^<<{޼=޻9޻޺޺޺[ּޚ֛y޺ޙޙ޹޹ޙκyzޚ{{ֺޜ޼޺ޚy{Zwַ7zޚޙޛZ֚[;Z[֙|μκXޘ:޼8޼]zޚޚ޺ޚzzz֚z֚֚ƹvΘ[:صy96xZ{滕tl[CK3t+3;3;23+""4""":TlzΚκyxux87X8X8ռ|ƜƽƼƽƼ\|\;::;|]Teym۝ֽ??_^^]]==;|=:[;޽ޜޜ:|<\<;}]=>ޚޙޚ޻ޚ|޼޽[[޸޻X޹޹޼޻zΚޚֽΝ޺Z[zޚzyzޚ޻yZ֘:֙Wιޙzyzޙz7yYZ[޺zXκ9֛ޙΙx\֙zXxxΙyyΚκ֚λּιvw֚֙[;;Μޚ{yzzZ֖z{z{:z{Zּz Y9  9   ,C}޼Z4: v##+3;D8DS[Swt|؄9z]}Ν׼֛ޛ<^޽ޞ߽޽^z8޺޺]\<;;<{λ֙<޼|޻ޛ֛|{{޻ޜ{ޚ޺ޛ޻޻޻ޛ޻ֻޛ޻ޛ֚ޚֺzY:9ֻ֚֙Ιw֗zyZY޹֘WY޺YZYޜ|ޜzYxyzz9֚zz9}|9YYy9X7ywΚֺzκ֛֚֚YYyz֚řYX 8 9 99  :tm}^$$9:Y  U"u=ή  +78X8 +VwV+V|9   y5+D޺O*5V +2s"|;"  4v +UU +V +v +VvV +TU3Tޙ>t\8, 7  v#]=矮7x +X9 + *K     ֔߿8 +ٽ} x +  + + |]  zyz yXY43ޛZ<8  + + + +Qlzֺe +xwZ֜?KwVWyxWWwxw 77 5 o2ݝּ֛LuUwWU +VU5UVU +VVVvvvV2 +t +X + +t uutuu[  9  tL     vy<>ux      6ֺ֚_+     V_}   t;lt97 + +  + +   9ƺޜDt y yyxy  xxyDy޺< + + + + + +zlzzޛ޻L + +ww +wv6v +t +S +ZκlXWXw xWXx XWVV 76  5 o2=ָ֙#u +Wv +vwv +vv +wvwVuuu2{w + uuuuutZ: <繭;z   u94ߟs    Wޛ+:  y  yvwՌޜd  U||TT +Y +yΛ}Uu zyy49<޺z4 + +w1{dz{ֻzD +wwV +V +t +yֻƶ|xXwxwXxXxXvV7 W76 5o2֚, +wv +WvwvvvwU +VuxCإvuuuu 99,,{,٭+Z x    5,޺=8 +X     Vޚr+       x6vՌ׻u2vwV +7V +7V +76667V +767667{|λ>dTV +vwu +V +u +v + +vu +v +vU +v +u +37y߻LVv xX X 6<޺<   + +0lZޛ޻ޛE4 + + +vv +uu*{t|v vvWX Y yYWXW7V6 WvU 5 :^μ3 +VvTu + +vS3TUw +656/l92  {xΘYκ\ּޛֺzΙΚκ9Λz{Z9|޼ޛ޺ޚ޺ޛz[:;;||֛Yֺyޚ޹zZY98ZzڥڝxW{Yֹ]>td[6C:22*2s"r****s*S"s*t"*Tt"P"SZX4t32RQ"Ss   pV;[޿~SCKTy\t}\u\utt}z}܍|[{{uz\?XTWTwl}{[}>~^}^~}޼{YY}X;uululldldmld\llllmlu{zּνƼμ?߾Μ{λz޻=<ߟƽ=<ֽ޼ֺY>޻޻޻޺ޚ{Zzzֻ{ޛ֛ZYֻޚޚֺ޻޺{ޚޙ֘y8޺֚֘޺ޚ޸ޛ{ֻޛ޹Yyzzޛ֚9yYY֛ΛYΙֹ֙޻ޚzֹ֚޺޹z֚ZzYY78x8W޸[{9Zλޜޛ{֛[Z:{{zZZޚ  xw Xx+7: + +ߕ;~>U4W 7z[ + + +X Y  w#;_#     W v Q#Z]{Μ}U#v       v6 Λ6Lt V +67V 6 7 XWx6 7U3TZλ_ߝ+V vv w 33C7LTTTLll|;?X:t||۝۝[:;Ŝ7X߸|Λ֛֜[{ּ޻ֻּޛֻZyz|?޻{|޻y֚޻{ֻμΛ{zZ֚޻ޚz[޺֚֚ޛ|;ֻλ֛y9YY9Ƽ֘֘Ξ6LU;Cv3R"vC63**5CKzlzl9$<<9$  8<Mz<{DZDw"=; +8W 9X + + +  + +w +Dw# [{ZzZY +9 8ZYZ Z  +[ߖS#   x x X W 6<~}]t 9     : : VZu3#    w5 uޚLs Xz 8ZY9XXWXW55"wTzֻ޼+5U w V 6 U56UUTUU +W"u[z޼=ZTQvSW+v3V+yTT3"4+T+D[y޹|C++53#Ctt#3v3u;L\l[||Z9vX:ZޛzZۥ8||t|:{y=Y8y<ֺ5# +   s t 2  ;    W "?< +78 { :Rm^_U8 X99X 8 89 w 78  +:ƽ:_+   :{[$ t8$;2#W x 8W   w xy 9Wx9D6 +vu + +qU3>7 T + + +TS + +tt2Bޜ3ruv +XWVV +7 +w +4t +T}U +:"7 +   y   "_޽^ + + + + + + + + + + + +Su\]\m=3jQ @ aA`@ @@A" @` y Y Y;D,E@!A@@ !`@B w<8 x wf !@@@  `@ @@!  X ֙y}E zȆ@ !@! !  ``" + + +S;Tyy6 *aB  @ @ !!+qvwV +vvvvvVUV3TT\Tuutut  x\m= + + + + +u#OYa   @`` @![z x wvy XB3K ` "! "@! !LT# yWyy 6 +Dd   "! AAlyUu Zλ޻߻uQm"jHJa !@@`@@A@   @@ə y W W y  y aA! @A @ @A"]5#xY KlC !!!@A!a!@@@  !@ C3#:Μ޻Ι;ZZZy޹jRbAa@ЪWγ{BJZbՙ;׻޻z{ZZZ`!A@ޘޙ޹yz5 sjRZJRbJR!!cئ޺Y޹Xޚzޙzޚz޺ޙޛzY2ţa"CB @ Ȣ/c;[zy9yκ֘UbjJR+RJR,Z{s6;{;ٽyyy3*JIJZjJZJB9  Cؤ"***"r"22xZW֗88XX8W8X޶=>=~ϛ]<޽<;=\:;Z[bZ  :;޻?ߜjRRZbc"!؊޼޼޼bZ[޽;0RZR A!Nzּz΍cJRBZZd !  Azޛ޼޻ޛֻ޼޻ޛ޻ޛYPD@ aAjnޚޚޛֹκƻƹΚΙ9Κֺֻ޻ޕJRJ-cՔYηƛ:zZy9ΙYxXΘxΘZhJRRZkR` ! @!F9X9XY֙yΙyֹyzXY޻֚ZzZz{zΛYZxYxx x x Xx y 7X x y x 8X UUuCޕ<ڥz}:}9zzY:~μߝּޛ޻zr=Ν\߼ޱ{ZlZkZa &{=y޻<ޛzֻ cZbKbKb@A !޻ֺֻ]|޺|CB"! a%lWW{޻ֽ{zΛ9[Z\֜wZUޙzޙYY޹ޘޚޙ:zΛ::޷jZRiRKZb!@  bZYYXXXXXΙ8X[zޝ\֛޻ޚzy{֛[Z:Zz9ՙ yxXxXxY Yx yy xY ">m;\<;9   Y ;+?v]qmB"H'a AQQt"֛tL  w x wwxx wLi İ 434+ 7 + 6Wx8 U+3֙׶k"u*CCld:! 2)aЃ ! !!+?7Z{z^]=(RZlZmRǡ@A !@֛:|<[|[\Μ\޹-@@ aAC#B,j]^{ƹ{[\ߛƚ֛֚޶ŷޚ\];}{\9X֚y֚޺ޛZΚޏsZjRRRAB  a:;zZ{{|\9|޻ּ]=٭ޜΚ{Z֛޼ޜּ\Ƽ֝Λ:xxX y yx XXYx X x76[L]=<++:Y  8  7 sze=0 2ePGi `IQ9 +t +S +:<ϔlY y< :Z  /Kh "A@@P:B"* + +   + 6 + +{= 6 +UVV Ȃ !A氄֚޿2 +  +3Mfc`%!a@@!}" + + + + + + + + +tRR ! !ŐB 4++++3;33t#3ԃ]ZZ֛֚]]L\DX[_~$    T "' $H(qaatSS{XX߶SV5Xx w z   +"Ђ @!A#"2:2B + + +  +|λl + +  b %ٽ{ֻ޺L487 + + +*) @! ߙ +w + +98 lqy ! @yXwxw;{;:XwWV"[}{ZZwv Ww x xx xw98 WWXx XwXWW6:< kZƑD" qqX u y\޽u67V 6  7 6 66668 ;<>$    3#ַ    #u+"$H)i !!BC" ! !B!!8YvV V3i I( I d!``aB @ @@ cS242 + +_   c  Ǹ%w|ޚzY,5z + + +Q*-A  A+T +v +w +y + + R !! "`! "yy zx8 9 V *~77777877777769 ZL ;    u#mi ( DH'i @ @@@@@ @! Y y y  +GGH 1RHbhjFE@!  @aihUƽ[vqiB "eCUĺ9֖#ii#C!  @&yޙ{ޚޟuuWw +w +v +n I  `` i-ryxv 8 7 6 *ݍYֹxwwXWWw YXXW8X 8X YX6y7 5j1MR!A @ @A r)Q) uU t ut? 66677777 7688; [  u#=]H (dH(aA!  XY Y  Hf1JJR+jAC ! !@@A!@@!h[Dt C !"C#BCD!@@ !  ! A!aYκΜm +  +u !B! @ !B"""  w x xw XW 7"\uyֻ8wW8WWX9wwX8Y9xX7 +x V6d`h  ! !C% u us7 6777778W87768898;= [     5#\) ( DHGi@`! ! @  $#%v yxyx )JRb:dPa! ! @ ` =c utB  " @!@ A`@! + +Z^e + + +K*$Ȅ"!A@` @  *2x X W X 7 "l7w777V 87 WW 9X88 v98 V !  i` uut ut֬ 6 66777 77689899YZ53 ; U#Ti cHHi DfFDExxefEFĐxŀ́΁yy  y WujAZ +[JNZ i@ID A  !!B 9t   c !@ a! !"#!!@@"J*tTZ{ֻޛ޿ + + + +K )*``I@XP'xDĸBB qqX 878+d֚8wW7V78YYX 8wXwyy89.RAA  !!!3դ;ߞ7777778W877677888;=   U#]( DHGihX + jJRJRi i h J kv  { xwX7H9KZkZjZnJ!*J F1d@`A @+_mxb @@`@ @ "AB!ABTt"Vu9y"Y7)I '& :hZbIjhr$D `!Ȱ X 7 7 *lzֺwv777V 7 : Ww w8X WV 8c !A HU 4 u u u դZߦ+5 77 76777 776676 88989:D^y,  T#UЃ(CHHi`'Qe8HIZjRRR!L jJ , M { y Y4+:JRZB(IK  cŐ!A!A! `aB` V yY c!  "# !"  !" BaKY +y֚޻~ +W7 + ,"jRRZRi g!!"dw WW 7"dֻζwW7WW889xwX8 87 QZ1R@AA@A11u U u v  [߮S3 77777777777777788   + +98 9L]4    T#;eσ!( #HGi`P +  RRkRZ   j YYy y x Z9vu 87u|+cZ*f) ** (e`yA  "jOA6 b! @!  B! @ +{ƻ<;" + +JI  +*:GbGbkJZI H $!) !AZyV V 6 "l9ΙՌWv7W7W 88 6V  7W: 氀`  a`Ж u 6u ut ZֿC 6 76 667777 76788899 9 "\\D# W UUZ.*$H)i  !I%0 ) +JJbZ "J j Jm  y yvw77 քƸ0K' + J pLj@ !  Ȅ!!" A B A!! !!"!,  +[νޛޜߍ29Z +vvW +m-( *)  9hR(JZRIi) !@ @@@A!"2*yU5"Y\8YlWuxYz: ; vvwW7RB3B !  " @.qlXvV uuuv S<37V666wX777879 Y : 9   + + 9 9  "[\=ƽܾǞƞ߽{~;}ޜ׾ZRjJZѣ ay|{ZJJba 9<]ޚޙ޻޺ֺz֘ޚ֜{ޙָ޼ֻ֛}|κ|{;[Yy޺BB @ zֺ{Zzx[{9y޸ޚκֳIA@  r88ֺyyyޙz֚:z[ZΜ{Zyֶw՚ֺ{֛yֺ[֜{ΛzyyyYyz޺ޚy֛֚{z[ΛyYYYYYyYy9X9XYY Y672C|}Y<#      Z$K2XFa  ;2; y 3\]ߦwT+w#7XWV73:4:NrYdx  vwW3X3;!*"D؅ "څ|<{};mK,*j*K"Ab !ֺ=}܅}z۝^Ɵ;;<[<\}zιޝZ]ƻּ[}޿}~پXyzޔkblbcC !AA! y֛|޽{{ܾ{;y4 ! @ 'WΙ֜λ{\yz޻Z:{ֻ{yYZ֙zZ|ֻZμ[wYֽ}\]}]|}ƝƝ]|m\UTy X Y x Y 8 Y X 8 8 8X Y x99"<w:Z$Y$  {$$Z   V0' @aBR zy 3z֚e"W +X8 2*Doz?# +X +  9W* +1edض xxj  Ȃ ŰGɹ=5#5 VV 6 5   +55 5 6U  +*4;[ֻzYTCw v U Tlr*2Uu+;3; t TT#Q[\ޛZ޸u Py  #edS+CXTu+t+2[޻y濕8l9u\ A @ '0K;\|ZΚ޻޸{|=ׄ|z8LK;;U#T+U#u+v;d֞/;S2SsSst +TSX#u + + +Uu +z ZyzyZyYY97 ";; 9 ,,  ;{$;   Ha @!RRW76#+Z]  z#zz|x8W7z :4 5 2s*@@chqߦt9 +T5Uv"l!A   liȃ !"ư8ֻޜ7Xx xxwwwWWXyYYZXYYZx {Y֛ޞ 8-bc/RPR +X8Yzwww "ޅ:\&G " +8 P<}޺CUMbNb@` ! c*)3+\zZdx\deCD\v3U#<#6 5 V W7V WWޮM +4uUuu +u +UX#u +UT +5 + +5 +8X888X 88y Y888X *_<==9   7x x W zi@fa!PRb X U##;ZޝޚT4+X + +7 + +u*t* b1qu +87 + +lYY" ʑYx  .ȃ  &ֻx w x W XxWw Ww W w   vv6 Yκ{~e+ U7k*A'*3x W6 58 x"\[޼xθh ""   +VLYκZr"## !iaH2 +mBŚޝB#"657  X XXXW8xwV + +sY,w wX 8XYwXXXwWX8X8W777 +68Z-o +Kj JI JI I I I I IHIH H !IRjZRIJJ +r + + +*u81ZjJi )(''  * * :ZiRJ(G(j JhHI6660S~*u +uvuVvvvWvwvvuVuV88888 p*>=" T5 6wU 6 7989 yV v6qCyƹzy?2##$#xw Tw V *tZ;:x=;zޚZ޹޺x֛޹޺޼ޚޛ޻޼ޛޛ޺׺{;޻ޛ޼޺޻޺ޛޚ޺޺ޚֺޚޙ޹޻ޙ֙ޚy޻yιxzֹߛ޻޺ޘy޺޺XzιzyZֻޚޛޚֺY֚z޺zyZyZZzzX9Κ޺ֹ֚޺޺zyZyYXzyZZZY:YޛYYy{ƛΛλΚΙ99Y9ZxxYY986Ӭ8Zz[ֻZ9ZZYZ֚9zZ99$9$ ##5\;~K3;4849,Z<4CDyTeە9}:}[}\}]}{ݝֹ=]VDWDxDTLT\_~=:;Ɲֽ<[ΝƼ޽ֽֽκƛz~ٕۍڍۍ;<<};[{|ޛ޼>>><\<==߹z֛޸|yǚƻּ[ƛ{ޚ֚{׺ΚΚֻ֛{޼zμּ[YZֺλκޚ֛{[zZ֙zyz֚zzޛYYκzXzyYzޛ֚z{{zyzyZ::;;[[[5[{֜|֚֝zyzΚZyzΙλ֚YYzyY     "mr:7  78X8,##,4Kֺ־<5zXXWXx W6U Vv 7V V<[:|<_13X W yxw 7VW w U u v##8$,64K]ƙYlt\\\ly׽ξ;Y}ddlttZ\|C+# ##++L4#<      u,z?~Uww 7vw  wxv 6zDŜ߾5d   +uzmT xvw  V56 Y֛}Swwv1K޺ޚ?3w 6 WW77XwW 767vV6+V{ߖ4W 7VW6W6 6 T U *9{|ƚ<5 w#v$;;e}\uu3 u 50C=:ǷtD5U U337<84W}Y,   ;$:$:9;:  mz xx yxXxyxwWvxw 54zz=]u+ WwX 7x{Zwxww W V 9<śYǶt +9 X8 X8 7   8  + +tƼޚes#xwxwxwx Wwxw xw7V   Zzֺer +v +  + + + + + + + +2KYΙޛ_Cw v Xxw w XW X  W 6U#՜:z~Ww xWWW 6 X w 6w W 6W w 5 ";u9ޚƸ5 4 6  5U +4U#3w655 6 :9֙߶S W 5 + + + +    + + + +wνs;# + + + + + +6 +2#~<~Y$    }m޸  yxyxXwxYYwxwW x4+z{^e3 w x yy Y xywXxyw W4?RC9 YY 8   +uٽ|eTxyxX yxXxXxW X7 {:D +vwvwwWwwWvvRW;YΚS3w Ww Xx xxXW 7WXxy WvWW 6#դ|Y֛LT xW7WxW W WXx 8X 88V"\Y{5V X77wXW76 x W 7 W7V 6 2Xκ߮C 5Ww W67777 5   +\ƺT6  + + +      #]Y$    uz yx YxxYxxwYy xw Xw XW +:Z޻^]9< Y y x Wwx yxXx xwWW <ޚQC  + + +t\]3xwxwy XXxx Xx XXXxXwXW; + +w +x +w +w +x + + + +v3VC9Κ_1+Ww 87 87XxW W XxXWWVWv7 "C7:֚uSxXw XWXW XW xWxx 8WX XTλwv U 7W77 8X7xXW 7X7XXW V 6 o*9ΙߦTU 7W768W8798WWV66[\u + 2#}=9 xu޸ xyyyyxxyYxxy ZxxwXwX5+ZZޙ49,  yxxW Xx8xxWW4yֻsC8  + + +uw\κ޻ޝeUXxyxyxXxxxXxXxxwxwX7ؽǘvV7Xw X7778W8V7  W675:yY֟WXW W77777777V7W76U6sL4   "     *߮z޸  YyyxYXXx yyXw Xx yX ]Yy޻ xXXxxxXxXxYX XxXW8LٽZΚ柞"9  + + + + +3?u+XWW V Y X xxxxxxXXXx 7W ƙ֛z濖w +v +xwvxx +www +Vut8κ޻v w x 7wWW7WXxyxXX XWm:y w Xx XWXX8W7W8W8777 +D:zݾVU7W xw 768W 876 + +8V :9yޟ#W7V 7666 7777777w[־e + +    *_<<9{ x w*Z  xyZx YyzxxxYXy Y*d[ƜΛ$$4wx xyyy yX Y vWXX 8C׽ZZޜ"Y + + + + +uƙߦ3+wYzxxxXxxxWxw7wx6ƻy,wxwv +w +Wx +XWxv]yֺ޹z4 w6x XxXWX77W Ww 7uVx5\ZΙ9,6 yxyxYxY8989887 +"Lzv|W WW 8 XWX8 7 8 W7:{|"WXYx878W 8  +V WXW7  X |Z46TU    *\\C#w y x x xy z 9 8 p2޺; w 5 wwYyXX7ww 6 5 Vv W qlyyzwyxXxxwx Xy y 87CحΛ޻?*  + + + + + +ڵ_s+  X W 8W Xx Xx XX X7W X 6z{޻v + +7W +Xw8 +7 +5 + +46V +6 +ut[μ|D#6xx XxXx yxXXY 8   +t{Tڽ[{{4U6W w 767W 7w WV 66V 656U "8TzS|6Uxv5V6     V VvCۥYΚ~: +U65  7 7W 66 7776 + + +T +7    2ZeWu 589787887XW Xx8 z޼~m + + +v":{]2C;C;3;#+w#W V 6yL׽ֻ{ޙ];63++6+#vx + + +q +#ƙֻ13 ut s 5v V V VvVv v u 5U54X{*u + +v +U + + + +ֻ޼ߞ3R#3s# +#5####Wv34v"{y޺Zu*#+ w v V v6 ##w 6  O"lYx5UYx 7WuT VV4 +665V +1[8x߶:7 6W65656|ލ3  + + + +|ֺ:;:μƛ|֚޻ֺκƜּ֛֝޻{ޜƜ8֛޼[ڭ:ڥx8ڥ<ٵzy|cxx޺ֻ{[cݕtCT3U3t+u++3<43+;;DDTTt\z{ح]ڽx٭;ڭڭ7֌vtZՌXt|t5dSS6dt|t6dvlwltZX֚޻ֻ֝Yڄ|6l||tcܝtt\K3;*2s=x޼;;X|tWl6dSK53K+"":|yƚzvtdS\WLCt3s;;CLw\WTWTXTTXL;t+5;s":y9}Y3+3LCU35+K\xdK7T\V\CKLDu3+4;8D|yy[[R;33S3+3+##U+KXT#3++"5 UVU6U6UV5   =<޹9<;z޺xXW9y޺޹ֻ|:{Wxֺ޻ֺֻz֚ޚޚZY<\zޙ޹θżYyYy{zz޼ޛ޻޼zֻ֛ޜּޜ֛֙[ZyޚXxޚޛzz֙z޻ޙyXY֙{Yzֺ{xZYwyֺYΙ:{8XzYz֚ޝ:7޸޺޺zޙޚzY֚X֚ޙޚ֙y;|8ֽ6x[WƘz9:8x99ٽ98xW:Z9׵͹ٵ9:ؽڽ8YyӴXxZ9ٽؽٽ8X;ٽyZyvŶ՞q[3S#""3+T3S33332;3;S;^>=>=<::[~>׽}ν޾־֞νΝν\Z֜;??=޽޽۽[xޙ֝ƽ֝Μޝ޽Zyy}ƜΝƜ|{|ƜΜƼμλμλּλּޚYz޺ּޝֻֻֻޜ޼{֚֜zyz־޾޼ֹֻ֛֛֘z[Κz޻߼޼Κֺֻޚֺ޻֝޻ֽ[\YZΜ֚zYֻ{{ֻ9yzYzYZֺ9֚9::77yΙY޹y͚9ֹΙyzzZ֙9ƻ{Y֛֚ZZxXVޗޙy֚9XYzΛzZyz֜|:9:ƶyֺ988:X889X4W4,44XDyDLDLxDLxLL\;exwY\=}_dLL8<7<9,#Y88X$8 $4{]wLWLwLLWD433=λܭ=ۭ9y[z֛֛[[988X{{}||9utttw:Zyx{Μּޚֺ|[޺κyxxwx֘WVY֙YYΛλZX{y9YZy9YŚ:ΛY{ ;     ;x$$7ל      y$,z[X3޼y+u + +8 +XYyy +y +77)ބ98v89   7 +85[O" +VV;}]ט7 5  + + rCz{4w ; w XwxxxX8Vx"9[ֽߍ u uu )k޻|\Ɣ +t +vvTuu +U +#uvT +uuU/"txxƚإs t v6UU66677 + 6إ# +5   7 V 6w     =,y x   Www      x x w3zw+W5 + 8 + + +8 + )܌YμΛxV  sVY|ߍr8 + +vv +VU͛޻޼L + + + + + +qX\Yyֹu  ttu t u u uuOtXΛƔ +s + + + +tv +T5u +T\D5 +5u +Utv +U +0"|Y}t8X 56 6 76 + wv + +؜} +5 +  v       =׼  z   z zy  x y        1#=\< +   +t +d9ּ;w + +V +      tz{֜u + +w + +w +x +x +wxwV +w +U +yޚޛ֝m + + + + + + +dZ{LU6 wxxx XwxxxxywX7 8 U  ";u9:z{߅ ut t U U  u /||8ƻטst + +Tuvv +VTvwUt +U0"t:{}tx9 7 7  + +wxU5W Քv U8X78W76777V  x ޘ ;  Y   yxxWwV:;  "֝޼l3    Sz6 + + +s޻my + +zy +x +Yxy +wxVv +5XW|ֽ<] + + +r\:ΛDvW V yXyyyX 8W xw Xwxx:Y 6 6 *[}Y9޺}1 + v uUuUu vu U QR)k:֛ƕtV +v +U +uUu +5vuTvvU +4 +u +4 +"|Ź}Քv X6V V566 wUT WW + +6vY+7V5 5      U6 + 5     xVX Z    3+ޅֺֻ濍2X +  y;V +X   zֻ֚ut + +w + +xww +xxwVwU +Z[Ι޺; + + + +rK8Κ֚LT yyYxxy YxyxxYX Yx 8 =mz֚{_u +UvuvuvuvuvuvSTNwc8yw +wvvvvuuv +VvVuUVVtU!t89μxW6767777 W 56W46W666776    y x Z,Z z yyyyxw7Wy   y +y޺濍0x    Kz5 +y      yޛֺ޿}* +7w +WVw +xwxwW +6V +5:zy<7  + + +RKιޛetX79yxx YX yxxwYX87 877 6 ;mY{z޹C v vuvuUuuuUuUu Uu SO8y֌W +v +vvvvvuuV +V +VuUU6U +TTt8֜6V 7676 7 87 X 6 56V֜:κD366 6667 6  yؽ]^M  xXw|7Z [3+}ߕxX + + +    KZΜֻvX s9κ֛S +5 + + +9VWwxwWxwxVV5 +ZΛxֺzD + +rC8κ?vtX xY yx YxyxXYX 8x8 "uZֻޛ֘;uutuuuuuuuuuSTN8ݾքv +WvvvvvuvV +VvVUUV6tu"zlΜڥ66V 67777X86 7 677XmR +Ww +x +x +xw +x +xxV +U +54 +z֚޹3 + + + + 2~8Ιޛ޻濮2L87 XWyxYXXW7 8X 8W6 L5śޛ߅ utttt ttTtut Uuo5SYΙƘv +v +uuVuVvvu65 +VuUTVv +tS!ڄΜ656V 6  7V7665 ;vSW    Z =֗Z$x y y xWt  yz x   xs+u޻x޺W +7   xC9ƛ:678 +   YΚzο}S +xwxxxxxx +wv +V5 +9Zֻ + +/<}Ŝޚ޻?":xWX7X 8x77 YY8 8W<ߝp vuUtuuUtuuuuuvtTKYz޼7vvvvWvWU +6VWVvvU!|{v V777W7W7777  _#7 66667766  yxޚ#M y   y xXwXw xl9  y zy  T+|mzֺޙޙ߾.*6 +     XKΜ    yޛޚޟ}s +x +w + +xw +xw +x +wwwV5UTy֚w + + + + + + +}{ޚ* w Ww 8x y x X X 8 YX 7 7YLY?uuuuutut u vu vut o d|Ƹt +vv +vuVuVu5T +VvvUvuUT!{w5 77 76 77  6 +  7>37 6 666{Z R3V   Z = xx  W$4  xXV>t  w 33\}y27\9{ּv +   z֚޻ޟ + +ww +x +xwWwwwwwu +V5Zλ޼x8 + + +/"Z{ֺ޺?K WXX 87y x xX yX 8 W7 +6#Ԝ8λO uv  vuuuu O CZ޼[vvuVvVvVu +Uvwvv +UTU!:ΛWUV76787 677S\~2#Vw   v X+#ߛ# y  y   xwxyx6tY   zX 62;֜޿:6V +    dΚ޼ޚVv +    v    4Ιޚ޺?1Wv +VV6VWvWVwwvU +U +4 +tz֛޻W   + + + + + +ݝzޚ޹߶Sw WWX 6 ^M WVW6 W76;7z[l" utu ut ut ttttt :֜صt +vu +uuvuVuUT +VUVUUT44!;Y[V55 66 + t;#w 669$9$9$8$#4>[dxֺ޼7,8,z4z49$ x  w w x xwxwWWtl   x y  5V[ֻ߶*vV7 + +V +6 +65 + + + + + +6 +W +5 o wK9y֛uV6 V8֚yޚޟ27 vwuv + +vvUt +TS +t +y֛w7  WXW +  .9{ֹK WW 76 xw5WV v 6V 6 6W3:z}tuo:9֛ƘvuvuvuT +TUUuUTUT4)[9zح$5 5 5 6666  +;~2+v 666מ;;{޼ޜ֛xyֹּ޾־֝}ޝޞ;:Λלz|ƻΜλƺƝ]߾Ν֛{9:}^}]۝<<}}\ڭ]\ΚYޙzuz}ޅY۝\<;}}}}}|}ƺֺy>==߼|ֽΟ֞{Yޙz޺ߺΚ޹޺x{Κ[zyxy֘[Ɯ\ν֛y7:9޼ޜΛΜּ֛֜ޜ֛֛֛֜֜|{ֻ֜|ּ<|:9֛X޺ֺֻ֛ΚּΛ޸Z֙WY֙[99Y[9z֙7Z{Y8֙ޚޙyy8y878Zy:99ΚZ9֛yzޛz:99Yzy8X8WXXX7ι] + +7 +1[z֛z?QKw + +X +w +vvWw +wvuWv +U4S<9ƚKUuuuUtUtutTtutTtTt Q9Zz+ +v + +VVu7WV +V +Vvvuw +v +VUp2{x_23 +t4T +5T +UU5T +Uu +UuUuvuUUSspBܭD +  + \ No newline at end of file diff --git a/examples/peripherals/ppa/ppa_color_key/main/ppa_color_key_example_main.c b/examples/peripherals/ppa/ppa_color_key/main/ppa_color_key_example_main.c new file mode 100644 index 00000000000..0350cf73821 --- /dev/null +++ b/examples/peripherals/ppa/ppa_color_key/main/ppa_color_key_example_main.c @@ -0,0 +1,296 @@ +/* + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include "driver/ppa.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "mbedtls/base64.h" + +#define EXAMPLE_IMAGE_WIDTH 320 +#define EXAMPLE_IMAGE_HEIGHT 240 +#define EXAMPLE_RGB565_PIXEL_SIZE 2 +#define EXAMPLE_RGB888_PIXEL_SIZE 3 +#define EXAMPLE_RGB565_IMAGE_SIZE (EXAMPLE_IMAGE_WIDTH * EXAMPLE_IMAGE_HEIGHT * EXAMPLE_RGB565_PIXEL_SIZE) +#define EXAMPLE_RGB888_IMAGE_SIZE (EXAMPLE_IMAGE_WIDTH * EXAMPLE_IMAGE_HEIGHT * EXAMPLE_RGB888_PIXEL_SIZE) +#define EXAMPLE_BASE64_CHUNK_LEN 96 +#define EXAMPLE_RED_KEY_MIN_R 0xA0 +#define EXAMPLE_RED_KEY_MAX_G 0x78 +#define EXAMPLE_RED_KEY_MAX_B 0x78 +#define EXAMPLE_GLOW_BLEND_ALPHA 176 +#define EXAMPLE_GLOW_CENTER_X 160 +#define EXAMPLE_GLOW_CENTER_Y 120 +#define EXAMPLE_GLOW_RADIUS_X 160 +#define EXAMPLE_GLOW_RADIUS_Y 60 +#define EXAMPLE_GLOW_HIGHLIGHT_X 120 +#define EXAMPLE_GLOW_PHASE_Y 90 + +/* The raw RGB565 asset is embedded by target_add_binary_data() in CMakeLists.txt. + * RENAME_TO "image_rgb" gives the linker symbols below. */ +extern const uint8_t image_rgb_start[] asm("_binary_image_rgb_start"); +extern const uint8_t image_rgb_end[] asm("_binary_image_rgb_end"); + +static uint8_t clamp_u8(int value) +{ + if (value < 0) { + return 0; + } + if (value > 0xFF) { + return 0xFF; + } + return (uint8_t)value; +} + +static uint8_t *alloc_ppa_buffer(size_t size) +{ + /* PPA uses DMA underneath, so input and output buffers must be DMA-capable + * and cache-line aligned. PSRAM keeps the example friendly to boards with + * limited internal RAM. */ + uint8_t *buffer = heap_caps_aligned_calloc(64, 1, size, MALLOC_CAP_DMA | MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + assert(buffer); + return buffer; +} + +static void print_base64_payload(const unsigned char *encoded, size_t encoded_len) +{ + printf("IMAGE_BASE64_BEGIN\n"); + size_t chunk_count = 0; + for (size_t offset = 0; offset < encoded_len; offset += EXAMPLE_BASE64_CHUNK_LEN) { + size_t chunk_len = encoded_len - offset; + if (chunk_len > EXAMPLE_BASE64_CHUNK_LEN) { + chunk_len = EXAMPLE_BASE64_CHUNK_LEN; + } + printf("IMAGE_BASE64 %.*s\n", (int)chunk_len, (const char *)&encoded[offset]); + chunk_count++; + if ((chunk_count % 16) == 0) { + /* The complete payload is large. Yield periodically so the serial + * monitor used by pytest can consume every line reliably. */ + vTaskDelay(pdMS_TO_TICKS(10)); + } + } + printf("IMAGE_BASE64_END\n"); +} + +static void prepare_glow_foreground(uint8_t *fg_buf) +{ + /* The foreground is generated in software so the example can blend a + * modern glow effect into the whole scene without needing a second image + * asset. The text is centered in this demo image, so the glow shape can + * use fixed geometry instead of dynamically scanning the picture. */ + uint8_t *pixels = fg_buf; + + for (int y = 0; y < EXAMPLE_IMAGE_HEIGHT; y++) { + for (int x = 0; x < EXAMPLE_IMAGE_WIDTH; x++) { + const int dx = x - EXAMPLE_GLOW_CENTER_X; + const int dy = y - EXAMPLE_GLOW_CENTER_Y; + const int ellipse_x = (dx * dx * 255) / (EXAMPLE_GLOW_RADIUS_X * EXAMPLE_GLOW_RADIUS_X); + const int ellipse_y = (dy * dy * 255) / (EXAMPLE_GLOW_RADIUS_Y * EXAMPLE_GLOW_RADIUS_Y); + int halo = 255 - ellipse_x - ellipse_y; + if (halo < 0) { + halo = 0; + } + if (halo > 255) { + halo = 255; + } + + const int shimmer_dx = abs(x - EXAMPLE_GLOW_HIGHLIGHT_X); + int shimmer = 255 - (shimmer_dx * 255) / EXAMPLE_GLOW_RADIUS_X; + if (shimmer < 0) { + shimmer = 0; + } + + int intensity = halo + shimmer / 3; + if (intensity > 255) { + intensity = 255; + } + + int red = 96 + (255 - intensity) * 36 / 255 + shimmer / 18; + int green = 138 + intensity * 110 / 255; + int blue = 208 + intensity * 47 / 255; + if ((((y - EXAMPLE_GLOW_PHASE_Y) / 5) & 1) == 0) { + green += 4; + blue += 8; + } + + /* PPA_BLEND_COLOR_MODE_RGB888 maps to BGR24 in memory. */ + size_t pixel_index = (y * EXAMPLE_IMAGE_WIDTH + x) * EXAMPLE_RGB888_PIXEL_SIZE; + pixels[pixel_index] = clamp_u8(blue); + pixels[pixel_index + 1] = clamp_u8(green); + pixels[pixel_index + 2] = clamp_u8(red); + } + } +} + +static void replace_keyed_text_with_glow(ppa_client_handle_t ppa_blend_handle, const void *bg_buf, + const void *fg_buf, void *out_buf) +{ + /* Background color-keying searches the red ESP32 text. With + * ck_reverse_bg2fg enabled, keyed background pixels are replaced by the + * generated glow foreground while non-key pixels stay unchanged. */ + ppa_blend_oper_config_t blend_config = { + .in_bg = { + .buffer = bg_buf, + .pic_w = EXAMPLE_IMAGE_WIDTH, + .pic_h = EXAMPLE_IMAGE_HEIGHT, + .block_w = EXAMPLE_IMAGE_WIDTH, + .block_h = EXAMPLE_IMAGE_HEIGHT, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB565, + }, + .in_fg = { + .buffer = fg_buf, + .pic_w = EXAMPLE_IMAGE_WIDTH, + .pic_h = EXAMPLE_IMAGE_HEIGHT, + .block_w = EXAMPLE_IMAGE_WIDTH, + .block_h = EXAMPLE_IMAGE_HEIGHT, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB888, + }, + .out = { + .buffer = out_buf, + .buffer_size = EXAMPLE_RGB565_IMAGE_SIZE, + .pic_w = EXAMPLE_IMAGE_WIDTH, + .pic_h = EXAMPLE_IMAGE_HEIGHT, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB565, + }, + .bg_alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .fg_alpha_update_mode = PPA_ALPHA_FIX_VALUE, + .fg_alpha_fix_val = 0, + .bg_ck_en = true, + .bg_ck_rgb_low_thres = { + .r = EXAMPLE_RED_KEY_MIN_R, + .g = 0x00, + .b = 0x00, + }, + .bg_ck_rgb_high_thres = { + .r = 0xff, + .g = EXAMPLE_RED_KEY_MAX_G, + .b = EXAMPLE_RED_KEY_MAX_B, + }, + .ck_reverse_bg2fg = true, + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + ESP_ERROR_CHECK(ppa_do_blend(ppa_blend_handle, &blend_config)); +} + +static void blend_glow_around_keyed_text(ppa_client_handle_t ppa_blend_handle, const void *bg_buf, + const void *fg_buf, void *out_buf) +{ + /* Background color-keying searches the red ESP32 text. With + * ck_reverse_bg2fg disabled, keyed background pixels stay unchanged while + * all non-key pixels alpha-blend with the generated glow foreground. */ + ppa_blend_oper_config_t blend_config = { + .in_bg = { + .buffer = bg_buf, + .pic_w = EXAMPLE_IMAGE_WIDTH, + .pic_h = EXAMPLE_IMAGE_HEIGHT, + .block_w = EXAMPLE_IMAGE_WIDTH, + .block_h = EXAMPLE_IMAGE_HEIGHT, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB565, + }, + .in_fg = { + .buffer = fg_buf, + .pic_w = EXAMPLE_IMAGE_WIDTH, + .pic_h = EXAMPLE_IMAGE_HEIGHT, + .block_w = EXAMPLE_IMAGE_WIDTH, + .block_h = EXAMPLE_IMAGE_HEIGHT, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB888, + }, + .out = { + .buffer = out_buf, + .buffer_size = EXAMPLE_RGB565_IMAGE_SIZE, + .pic_w = EXAMPLE_IMAGE_WIDTH, + .pic_h = EXAMPLE_IMAGE_HEIGHT, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_RGB565, + }, + .bg_alpha_update_mode = PPA_ALPHA_NO_CHANGE, + .fg_alpha_update_mode = PPA_ALPHA_FIX_VALUE, + .fg_alpha_fix_val = EXAMPLE_GLOW_BLEND_ALPHA, + .bg_ck_en = true, + .bg_ck_rgb_low_thres = { + .r = EXAMPLE_RED_KEY_MIN_R, + .g = 0x00, + .b = 0x00, + }, + .bg_ck_rgb_high_thres = { + .r = 0xff, + .g = EXAMPLE_RED_KEY_MAX_G, + .b = EXAMPLE_RED_KEY_MAX_B, + }, + .ck_reverse_bg2fg = false, + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + ESP_ERROR_CHECK(ppa_do_blend(ppa_blend_handle, &blend_config)); +} + +static void encode_and_print_image(const char *effect_name, const uint8_t *image, size_t image_size) +{ + /* Binary image data is not safe to print directly on the serial console. + * Base64 turns it into ASCII that pytest can capture and decode. */ + size_t encoded_len = 0; + int ret = mbedtls_base64_encode(NULL, 0, &encoded_len, image, image_size); + ESP_ERROR_CHECK((ret == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) ? ESP_OK : ESP_FAIL); + + unsigned char *encoded = calloc(encoded_len + 1, 1); + assert(encoded); + ESP_ERROR_CHECK(mbedtls_base64_encode(encoded, encoded_len + 1, &encoded_len, image, image_size) == 0 ? ESP_OK : ESP_FAIL); + + printf("IMAGE_META effect=%s width=%u height=%u format=RGB565 encoding=base64\n", + effect_name, EXAMPLE_IMAGE_WIDTH, EXAMPLE_IMAGE_HEIGHT); + print_base64_payload(encoded, encoded_len); + free(encoded); +} + +void app_main(void) +{ + const size_t embedded_size = image_rgb_end - image_rgb_start; + + printf("Loading embedded RGB565 image from flash...\n"); + printf("Embedded raw image size: %zu bytes\n", embedded_size); + assert(embedded_size == EXAMPLE_RGB565_IMAGE_SIZE); + + uint8_t *result_buf = alloc_ppa_buffer(EXAMPLE_RGB565_IMAGE_SIZE); + uint8_t *foreground_buf = alloc_ppa_buffer(EXAMPLE_RGB888_IMAGE_SIZE); + printf("Generating shared glow foreground...\n"); + prepare_glow_foreground(foreground_buf); + + ppa_client_handle_t ppa_blend_handle = NULL; + ppa_client_config_t ppa_blend_config = { + .oper_type = PPA_OPERATION_BLEND, + .max_pending_trans_num = 1, + }; + ESP_ERROR_CHECK(ppa_register_client(&ppa_blend_config, &ppa_blend_handle)); + + printf("Replacing keyed red text with glow foreground...\n"); + replace_keyed_text_with_glow(ppa_blend_handle, image_rgb_start, foreground_buf, result_buf); + encode_and_print_image("replace_keyed_text_with_glow", result_buf, EXAMPLE_RGB565_IMAGE_SIZE); + + printf("Blending glow around keyed red text...\n"); + blend_glow_around_keyed_text(ppa_blend_handle, image_rgb_start, foreground_buf, result_buf); + encode_and_print_image("blend_glow_around_keyed_text", result_buf, EXAMPLE_RGB565_IMAGE_SIZE); + printf("PPA color key demo done.\n"); + + ESP_ERROR_CHECK(ppa_unregister_client(ppa_blend_handle)); + free(result_buf); + free(foreground_buf); +} diff --git a/examples/peripherals/ppa/ppa_color_key/pytest_ppa_color_key.py b/examples/peripherals/ppa/ppa_color_key/pytest_ppa_color_key.py new file mode 100644 index 00000000000..76094cb12e5 --- /dev/null +++ b/examples/peripherals/ppa/ppa_color_key/pytest_ppa_color_key.py @@ -0,0 +1,205 @@ +# SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import base64 +import hashlib +import logging +import re +from dataclasses import dataclass +from pathlib import Path + +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets + +IMAGE_META_PATTERN = ( + r'IMAGE_META effect=(?P\w+) width=(?P\d+) height=(?P\d+) ' + r'format=(?P\w+) encoding=(?P\w+)' +) +IMAGE_META_RE = re.compile(IMAGE_META_PATTERN) +IMAGE_CHUNK_PATTERN = r'IMAGE_BASE64 (?P[A-Za-z0-9+/=]+)' +IMAGE_CHUNK_RE = re.compile(IMAGE_CHUNK_PATTERN) +REPLACE_EFFECT_NAME = 'replace_keyed_text_with_glow' +BLEND_EFFECT_NAME = 'blend_glow_around_keyed_text' +EXPECTED_PIXEL_FORMAT = 'RGB565' +EXPECTED_ENCODING = 'base64' +RGB565_BYTES_PER_PIXEL = 2 +RGB888_BYTES_PER_PIXEL = 3 +PPM_MAGIC = b'P6' +PPM_MAX_VALUE = b'255' +PPM_HEADER_RE = re.compile(rb'^P6\s+(?P\d+)\s+(?P\d+)\s+(?P\d+)\s') + + +@dataclass(frozen=True) +class ImageMetadata: + effect: str + width: int + height: int + pixel_format: str + encoding: str + + @property + def rgb565_size(self) -> int: + return self.width * self.height * RGB565_BYTES_PER_PIXEL + + +@dataclass(frozen=True) +class RgbImage: + width: int + height: int + pixels_rgb888: bytes + + def __post_init__(self) -> None: + expected_size = self.width * self.height * RGB888_BYTES_PER_PIXEL + if len(self.pixels_rgb888) != expected_size: + raise ValueError(f'Expected {expected_size} RGB bytes, got {len(self.pixels_rgb888)}') + + +def parse_image_metadata(meta_line: str) -> ImageMetadata: + match = IMAGE_META_RE.fullmatch(meta_line) + if not match: + raise ValueError(f'Invalid image metadata line: {meta_line}') + + return ImageMetadata( + effect=match.group('effect'), + width=int(match.group('width')), + height=int(match.group('height')), + pixel_format=match.group('format'), + encoding=match.group('encoding'), + ) + + +def collect_base64_payload(dut: Dut) -> list[str]: + payload_lines: list[str] = [] + while True: + match = dut.expect(rf'(?PIMAGE_BASE64_END|{IMAGE_CHUNK_PATTERN}\r?\n)') + line = match.group('line').decode('utf-8').strip() + if line == 'IMAGE_BASE64_END': + return payload_lines + + chunk_match = IMAGE_CHUNK_RE.fullmatch(line) + assert chunk_match is not None + payload_lines.append(chunk_match.group('payload')) + + +def _rgb565_to_rgb888(raw_bytes: bytes) -> bytes: + # PPM stores 8-bit RGB triplets, so expand each RGB565 pixel before writing the artifact. + rgb_bytes = bytearray(len(raw_bytes) // 2 * 3) + for pixel_index, offset in enumerate(range(0, len(raw_bytes), 2)): + pixel = raw_bytes[offset] | (raw_bytes[offset + 1] << 8) + red = (pixel >> 11) & 0x1F + green = (pixel >> 5) & 0x3F + blue = pixel & 0x1F + rgb_offset = pixel_index * 3 + rgb_bytes[rgb_offset : rgb_offset + 3] = ( + (red << 3) | (red >> 2), + (green << 2) | (green >> 4), + (blue << 3) | (blue >> 2), + ) + return bytes(rgb_bytes) + + +def _encode_ppm(image: RgbImage) -> bytes: + header = b'%s\n%d %d\n%s\n' % (PPM_MAGIC, image.width, image.height, PPM_MAX_VALUE) + return header + image.pixels_rgb888 + + +def _load_ppm(path: Path) -> RgbImage: + ppm_bytes = path.read_bytes() + header_match = PPM_HEADER_RE.match(ppm_bytes) + if not header_match: + raise ValueError('Invalid PPM header') + + width = int(header_match.group('width')) + height = int(header_match.group('height')) + max_value = header_match.group('max_value') + if width <= 0 or height <= 0: + raise ValueError('Unsupported PPM dimensions') + if max_value != PPM_MAX_VALUE: + raise ValueError(f'Unsupported PPM max value: {max_value.decode("ascii", errors="replace")}') + + pixel_data = ppm_bytes[header_match.end() :] + expected_size = width * height * RGB888_BYTES_PER_PIXEL + if len(pixel_data) != expected_size: + raise ValueError(f'Expected {expected_size} PPM pixel bytes, got {len(pixel_data)}') + + return RgbImage(width=width, height=height, pixels_rgb888=pixel_data) + + +def decode_rgb565_base64_image(metadata: ImageMetadata, payload_lines: list[str]) -> RgbImage: + if metadata.pixel_format != EXPECTED_PIXEL_FORMAT: + raise ValueError(f'Unsupported pixel format: {metadata.pixel_format}') + if metadata.encoding != EXPECTED_ENCODING: + raise ValueError(f'Unsupported payload encoding: {metadata.encoding}') + + raw_bytes = base64.b64decode(''.join(payload_lines), validate=True) + if len(raw_bytes) != metadata.rgb565_size: + raise ValueError(f'Expected {metadata.rgb565_size} decoded bytes, got {len(raw_bytes)}') + + return RgbImage(width=metadata.width, height=metadata.height, pixels_rgb888=_rgb565_to_rgb888(raw_bytes)) + + +def save_ppm_artifact(image: RgbImage, output_path: Path) -> None: + output_path.parent.mkdir(parents=True, exist_ok=True) + try: + output_path.write_bytes(_encode_ppm(image)) + except OSError: + logging.exception('Failed to save PPA artifact to %s', output_path) + return + + logging.info('Saved PPA artifact to %s', output_path) + + +def image_digest(image: RgbImage) -> str: + digest = hashlib.sha256() + digest.update(image.width.to_bytes(4, 'big')) + digest.update(image.height.to_bytes(4, 'big')) + digest.update(image.pixels_rgb888) + return digest.hexdigest() + + +def assert_image_matches_golden(result_image: RgbImage, golden_path: Path) -> None: + assert golden_path.is_file(), f'Golden image not found: {golden_path}' + golden_image = _load_ppm(golden_path) + + assert image_digest(result_image) == image_digest(golden_image), ( + f'Generated image does not match golden file: {golden_path.name}' + ) + + +def effect_output_name(effect: str) -> str: + return f'ppa_color_key_{effect}.ppm' + + +def effect_golden_name(effect: str) -> str: + return f'golden_{effect}.ppm' + + +def expect_and_check_effect_image(dut: Dut, effect: str) -> None: + metadata_line = dut.expect(IMAGE_META_PATTERN).group(0).decode('utf-8') + metadata = parse_image_metadata(metadata_line) + assert metadata.effect == effect, f'Expected effect {effect}, got {metadata.effect}' + + dut.expect_exact('IMAGE_BASE64_BEGIN') + base64_chunks = collect_base64_payload(dut) + + result_image = decode_rgb565_base64_image(metadata, base64_chunks) + output_path = Path(dut.logdir) / effect_output_name(effect) + save_ppm_artifact(result_image, output_path) + assert_image_matches_golden(result_image, Path(__file__).with_name(effect_golden_name(effect))) + + +@pytest.mark.generic +@idf_parametrize('target', soc_filtered_targets('SOC_PPA_SUPPORTED == 1'), indirect=['target']) +def test_ppa_color_key(dut: Dut) -> None: + dut.expect_exact('Loading embedded RGB565 image from flash...') + dut.expect(r'Embedded raw image size: \d+ bytes') + dut.expect_exact('Generating shared glow foreground...') + + dut.expect_exact('Replacing keyed red text with glow foreground...') + expect_and_check_effect_image(dut, REPLACE_EFFECT_NAME) + + dut.expect_exact('Blending glow around keyed red text...') + expect_and_check_effect_image(dut, BLEND_EFFECT_NAME) + + dut.expect_exact('PPA color key demo done.') diff --git a/examples/peripherals/ppa/ppa_color_key/sdkconfig.defaults b/examples/peripherals/ppa/ppa_color_key/sdkconfig.defaults new file mode 100644 index 00000000000..cc641ea6033 --- /dev/null +++ b/examples/peripherals/ppa/ppa_color_key/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_SPIRAM=y