diff --git a/components/esp_driver_isp/CMakeLists.txt b/components/esp_driver_isp/CMakeLists.txt index de3a6990493..1953755a817 100644 --- a/components/esp_driver_isp/CMakeLists.txt +++ b/components/esp_driver_isp/CMakeLists.txt @@ -9,11 +9,12 @@ set(priv_requires "esp_driver_gpio") if(${target} STREQUAL "linux") set(requires "") else() - set(requires "esp_hal_cam" "esp_mm") + set(requires "esp_hal_cam" "esp_mm" "esp_driver_dma") endif() if(CONFIG_SOC_ISP_SUPPORTED) list(APPEND srcs "src/isp_core.c" + "src/isp_dma.c" "src/isp_af.c" "src/isp_ccm.c" "src/isp_awb.c" diff --git a/components/esp_driver_isp/include/driver/isp_core.h b/components/esp_driver_isp/include/driver/isp_core.h index bcc2c4de5cd..6869fac72cb 100644 --- a/components/esp_driver_isp/include/driver/isp_core.h +++ b/components/esp_driver_isp/include/driver/isp_core.h @@ -32,6 +32,7 @@ typedef struct { uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame color_raw_element_order_t bayer_order; ///< Bayer order + uint32_t dma_burst_size; ///< DMA output burst length in units of 64-bit beats. Set to 0 to use default value 16 int intr_priority; ///< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) struct { uint32_t bypass_isp : 1; ///< Bypass ISP pipelines diff --git a/components/esp_driver_isp/include/driver/isp_dma.h b/components/esp_driver_isp/include/driver/isp_dma.h new file mode 100644 index 00000000000..7bb2cc8585d --- /dev/null +++ b/components/esp_driver_isp/include/driver/isp_dma.h @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "driver/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Process one ISP DMA frame: feed the input buffer through the ISP and wait for completion + * + * @note Input buffer content should be ready before calling this function. If the buffers are in + * cacheable memory, the caller should synchronize them around DMA access. Buffer sizes are + * derived from the ISP processor resolution and pixel formats. Both buffers must be 8-byte + * aligned. This function blocks until both input and output DMA channels finish. + * + * @param[in] proc Processor handle + * @param[in] output_buffer Destination buffer for ISP output (8-byte aligned) + * @param[in] input_buffer Source input buffer for RAW frame data (8-byte aligned) + * @param[in] timeout_ms Timeout in milliseconds for waiting transfer completion + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid argument + * - ESP_ERR_TIMEOUT Wait timeout + */ +esp_err_t esp_isp_dma_process_frame(isp_proc_handle_t proc, void *output_buffer, const void *input_buffer, uint32_t timeout_ms); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/include/esp_private/isp_private.h b/components/esp_driver_isp/include/esp_private/isp_private.h index 076ef6ab894..140f9b9f261 100644 --- a/components/esp_driver_isp/include/esp_private/isp_private.h +++ b/components/esp_driver_isp/include/esp_private/isp_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -58,6 +58,8 @@ typedef enum { /*--------------------------------------------------------------- Driver Context ---------------------------------------------------------------*/ +typedef struct esp_isp_dma_frame_ctx_t esp_isp_dma_frame_ctx_t; + typedef struct isp_processor_t { int proc_id; isp_clk_src_t clk_src; @@ -70,10 +72,14 @@ typedef struct isp_processor_t { DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock); isp_color_t in_color_format; isp_color_t out_color_format; + isp_input_data_source_t input_data_source; uint32_t h_res; uint32_t v_res; color_raw_element_order_t bayer_order; bool bypass_isp; + uint32_t dma_in_burst_len; // ISP DMA input burst length (64-bit beats), kept in sync with the input GDMA dst MSIZE + uint32_t dma_out_burst_len; // ISP DMA output burst length (64-bit beats) + esp_isp_dma_frame_ctx_t *dma_frame_ctx; /* sub module contexts */ isp_af_ctlr_t af_ctlr[ISP_LL_AF_CTLR_NUMS]; isp_awb_ctlr_t awb_ctlr; @@ -131,6 +137,45 @@ bool esp_isp_awb_isr(isp_proc_handle_t proc, uint32_t awb_events); bool esp_isp_sharpen_isr(isp_proc_handle_t proc, uint32_t sharp_events); bool esp_isp_hist_isr(isp_proc_handle_t proc, uint32_t hist_events); +/*--------------------------------------------------------------- + DMA INPUT +---------------------------------------------------------------*/ +/** + * @brief Configure the ISP DMA input path (frame size, burst length, data type) + * + * @note Internal helper invoked while creating a processor whose input source is DWGDMA. + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid input color format or frame size + */ +esp_err_t isp_dma_configure_input(isp_proc_handle_t proc); + +/** + * @brief Create the ISP DMA frame context + * + * @note Internal helper invoked while creating a processor whose input source is DWGDMA. + * + * @param[in] proc Processor handle + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Invalid processor, burst length, or frame size + * - ESP_ERR_INVALID_STATE Processor input source is not DWGDMA or the context already exists + * - ESP_ERR_NO_MEM Failed to allocate the context or synchronization objects + * - Other errors returned by the underlying DMA driver + */ +esp_err_t isp_dma_new_frame_ctx(isp_proc_handle_t proc); + +/** + * @brief Delete the ISP DMA frame context + * + * @param[in] proc Processor handle + */ +void isp_dma_del_frame_ctx(isp_proc_handle_t proc); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_isp/src/isp_core.c b/components/esp_driver_isp/src/isp_core.c index c97423cc29c..13d0ee28cdf 100644 --- a/components/esp_driver_isp/src/isp_core.c +++ b/components/esp_driver_isp/src/isp_core.c @@ -18,6 +18,7 @@ #include "esp_private/mipi_csi_share_hw_ctrl.h" #include "hal/hal_utils.h" #include "hal/color_hal.h" +#include "hal/mipi_csi_brg_ll.h" #include "soc/mipi_csi_bridge_struct.h" #include "hal/isp_periph.h" #include "soc/soc_caps.h" @@ -79,7 +80,17 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ esp_err_t ret = ESP_FAIL; ESP_RETURN_ON_FALSE(proc_config && ret_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(proc_config->h_res <= ISP_LL_HSIZE_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid h_res"); - ESP_RETURN_ON_FALSE(proc_config->input_data_source != ISP_INPUT_DATA_SOURCE_DWGDMA, ESP_ERR_NOT_SUPPORTED, TAG, "input source not supported yet"); + if (proc_config->input_data_source == ISP_INPUT_DATA_SOURCE_DWGDMA) { + ESP_RETURN_ON_FALSE((proc_config->input_data_color_type == ISP_COLOR_RAW8) || + (proc_config->input_data_color_type == ISP_COLOR_RAW10) || + (proc_config->input_data_color_type == ISP_COLOR_RAW12), + ESP_ERR_INVALID_ARG, TAG, "dma input only supports RAW8/RAW10/RAW12"); + uint32_t in_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(proc_config->input_data_color_type); + uint64_t frame_bits = (uint64_t)proc_config->h_res * proc_config->v_res * in_bits_per_pixel; + ESP_RETURN_ON_FALSE((frame_bits % 64) == 0, ESP_ERR_INVALID_ARG, TAG, "frame bits should be 64-bit aligned"); + ESP_RETURN_ON_FALSE((frame_bits / 64) <= ((1UL << 22) - 1), ESP_ERR_INVALID_ARG, TAG, "frame size exceeds hardware limit"); + ESP_RETURN_ON_FALSE(proc_config->dma_burst_size <= 16, ESP_ERR_INVALID_ARG, TAG, "dma burst size out of range"); + } if (proc_config->flags.bypass_isp) { ESP_RETURN_ON_FALSE(proc_config->input_data_color_type == proc_config->output_data_color_type, ESP_ERR_INVALID_ARG, TAG, "isp is bypassed, input and output data color type should be same"); } @@ -173,7 +184,9 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ isp_ll_yuv_set_range(proc->hal.hw, proc_config->yuv_range); } - if ((out_color_format == ISP_COLOR_RGB888 || out_color_format == ISP_COLOR_RGB565) && proc_config->input_data_source == ISP_INPUT_DATA_SOURCE_DVP) { + if ((out_color_format == ISP_COLOR_RGB888 || out_color_format == ISP_COLOR_RGB565) && + (proc_config->input_data_source == ISP_INPUT_DATA_SOURCE_DVP || + proc_config->input_data_source == ISP_INPUT_DATA_SOURCE_DWGDMA)) { isp_ll_color_enable(proc->hal.hw, true); // workaround for DIG-474 } if (proc_config->flags.byte_swap_en) { @@ -184,16 +197,23 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ proc->in_color_format = in_color_format; proc->out_color_format = out_color_format; + proc->input_data_source = proc_config->input_data_source; proc->h_res = proc_config->h_res; proc->v_res = proc_config->v_res; proc->bayer_order = proc_config->bayer_order; proc->bypass_isp = proc_config->flags.bypass_isp; + proc->dma_out_burst_len = proc_config->dma_burst_size; + if (proc->input_data_source == ISP_INPUT_DATA_SOURCE_DWGDMA) { + ESP_GOTO_ON_ERROR(isp_dma_configure_input(proc), err, TAG, "configure dma input failed"); + ESP_GOTO_ON_ERROR(isp_dma_new_frame_ctx(proc), err, TAG, "create dma frame context failed"); + } *ret_proc = proc; return ESP_OK; err: + isp_dma_del_frame_ctx(proc); if (proc->intr_hdl) { esp_isp_deregister_isr(proc, ISP_SUBMODULE_GENERAL); } @@ -207,6 +227,8 @@ esp_err_t esp_isp_del_processor(isp_proc_handle_t proc) ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(atomic_load(&proc->isp_fsm) == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "processor isn't in init state"); + isp_dma_del_frame_ctx(proc); + //declaim first, then do free ESP_RETURN_ON_ERROR(s_isp_declaim_processor(proc), TAG, "declaim processor fail"); #if SOC_ISP_SHARE_CSI_BRG @@ -338,20 +360,26 @@ static void IRAM_ATTR s_isp_isr_dispatcher(void *arg) do_dispatch = false; } - if ((error_events & ISP_LL_EVENT_DATA_TYPE_ERR) || (error_events & ISP_LL_EVENT_DATA_TYPE_SETTING_ERR)) { - ESP_EARLY_LOGE(TAG, "data type error"); - } - if ((error_events & ISP_LL_EVENT_ASYNC_FIFO_OVF) || (error_events & ISP_LL_EVENT_BUF_FULL)) { - ESP_EARLY_LOGE(TAG, "fifo overflow"); - } - if ((error_events & ISP_LL_EVENT_HVNUM_SETTING_ERR) || (error_events & ISP_LL_EVENT_MIPI_HNUM_UNMATCH)) { - ESP_EARLY_LOGE(TAG, "hnum / vnum setting error"); - } - if (error_events & ISP_LL_EVENT_GAMMA_XCOORD_ERR) { - ESP_EARLY_LOGE(TAG, "gamma xcoord error"); - } - if (error_events & ISP_LL_EVENT_CROP_ERR) { - ESP_EARLY_LOGE(TAG, "crop error"); + if (error_events) { + if ((error_events & ISP_LL_EVENT_DATA_TYPE_ERR) || (error_events & ISP_LL_EVENT_DATA_TYPE_SETTING_ERR)) { + ESP_EARLY_LOGE(TAG, "data type error"); + } + if ((error_events & ISP_LL_EVENT_ASYNC_FIFO_OVF)) { + ESP_EARLY_LOGE(TAG, "fifo overflow"); + } + if ((error_events & ISP_LL_EVENT_BUF_FULL)) { + //This error does not affect the operation of the ISP + ESP_EARLY_LOGD(TAG, "buffer full"); + } + if ((error_events & ISP_LL_EVENT_HVNUM_SETTING_ERR) || (error_events & ISP_LL_EVENT_MIPI_HNUM_UNMATCH)) { + ESP_EARLY_LOGE(TAG, "hnum / vnum setting error"); + } + if (error_events & ISP_LL_EVENT_GAMMA_XCOORD_ERR) { + ESP_EARLY_LOGE(TAG, "gamma xcoord error"); + } + if (error_events & ISP_LL_EVENT_CROP_ERR) { + ESP_EARLY_LOGE(TAG, "crop error"); + } } if (need_yield) { diff --git a/components/esp_driver_isp/src/isp_dma.c b/components/esp_driver_isp/src/isp_dma.c new file mode 100644 index 00000000000..a22bed0863a --- /dev/null +++ b/components/esp_driver_isp/src/isp_dma.c @@ -0,0 +1,265 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "driver/isp_dma.h" +#include "esp_private/dw_gdma.h" +#include "esp_private/isp_private.h" +#include "hal/color_hal.h" +#include "hal/isp_ll.h" +#include "hal/mipi_csi_brg_ll.h" + +#define ISP_DMA_IN_BURST_LEN_DFT 8 +#define ISP_DMA_OUT_BURST_LEN_DFT 16 + +struct esp_isp_dma_frame_ctx_t { + isp_proc_handle_t proc; + csi_brg_dev_t *csi_brg_hw; + dw_gdma_channel_handle_t dma_in_chan; + dw_gdma_channel_handle_t dma_out_chan; + SemaphoreHandle_t in_done_sem; + SemaphoreHandle_t out_done_sem; + dw_gdma_block_transfer_config_t dma_out_trans; + dw_gdma_block_transfer_config_t dma_in_trans; + uint32_t input_frame_size_64bit; + uint32_t output_frame_size_64bit; +}; + +static const char *TAG = "ISP_DMA"; + +static bool IRAM_ATTR s_isp_dma_done_cb(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data) +{ + (void)chan; + (void)event_data; + BaseType_t high_task_woken = pdFALSE; + xSemaphoreGiveFromISR(*(SemaphoreHandle_t *)user_data, &high_task_woken); + return high_task_woken == pdTRUE; +} + +static dw_gdma_burst_items_t s_isp_dma_burst_len_to_items(uint32_t burst_len) +{ + switch (burst_len) { + case 1: return DW_GDMA_BURST_ITEMS_1; + case 4: return DW_GDMA_BURST_ITEMS_4; + case 8: return DW_GDMA_BURST_ITEMS_8; + default: return DW_GDMA_BURST_ITEMS_8; + } +} + +static void s_isp_dma_frame_ctx_destroy(struct esp_isp_dma_frame_ctx_t *ctx) +{ + if (!ctx) { + return; + } + if (ctx->csi_brg_hw) { + mipi_csi_brg_ll_enable(ctx->csi_brg_hw, false); + } + if (ctx->dma_in_chan) { + dw_gdma_channel_enable_ctrl(ctx->dma_in_chan, false); + dw_gdma_del_channel(ctx->dma_in_chan); + } + if (ctx->dma_out_chan) { + dw_gdma_channel_enable_ctrl(ctx->dma_out_chan, false); + dw_gdma_del_channel(ctx->dma_out_chan); + } + if (ctx->in_done_sem) { + vSemaphoreDelete(ctx->in_done_sem); + } + if (ctx->out_done_sem) { + vSemaphoreDelete(ctx->out_done_sem); + } + free(ctx); +} + +esp_err_t isp_dma_configure_input(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(proc->input_data_source == ISP_INPUT_DATA_SOURCE_DWGDMA, ESP_ERR_INVALID_ARG, TAG, "processor input source is not dwgdma"); + + bool valid_format = isp_ll_dma_set_data_type(proc->hal.hw, proc->in_color_format); + ESP_RETURN_ON_FALSE(valid_format, ESP_ERR_INVALID_ARG, TAG, "dma input only supports RAW8/RAW10/RAW12"); + + uint32_t in_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(proc->in_color_format); + uint64_t frame_bits = (uint64_t)proc->h_res * proc->v_res * in_bits_per_pixel; + ESP_RETURN_ON_FALSE((frame_bits % 64) == 0, ESP_ERR_INVALID_ARG, TAG, "frame bits should be 64-bit aligned"); + + uint64_t frame_size_in_64bit = frame_bits / 64; + ESP_RETURN_ON_FALSE(frame_size_in_64bit <= ((1UL << 22) - 1), ESP_ERR_INVALID_ARG, TAG, "frame size exceeds hardware limit"); + + /* + * The input burst length is fixed at ISP_DMA_IN_BURST_LEN_DFT: it must be representable as a + * DW-GDMA MSIZE (1/4/8) and not exceed the ISP input async FIFO capacity (8 x 64-bit). It also + * has to equal the input GDMA dst MSIZE (derived from proc->dma_in_burst_len in + * isp_dma_new_frame_ctx), otherwise the async FIFO overflows. + */ + isp_ll_dma_set_frame_size(proc->hal.hw, (uint32_t)frame_size_in_64bit); + isp_ll_dma_set_burst_len(proc->hal.hw, ISP_DMA_IN_BURST_LEN_DFT); + isp_ll_dma_apply_config(proc->hal.hw); + proc->dma_in_burst_len = ISP_DMA_IN_BURST_LEN_DFT; + + return ESP_OK; +} + +esp_err_t isp_dma_new_frame_ctx(isp_proc_handle_t proc) +{ + esp_err_t ret = ESP_FAIL; + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(proc->input_data_source == ISP_INPUT_DATA_SOURCE_DWGDMA, ESP_ERR_INVALID_STATE, TAG, "processor input source is not dwgdma"); + ESP_RETURN_ON_FALSE(!proc->dma_frame_ctx, ESP_ERR_INVALID_STATE, TAG, "dma frame context already exists"); + + uint32_t output_burst_len = proc->dma_out_burst_len ? proc->dma_out_burst_len : ISP_DMA_OUT_BURST_LEN_DFT; + ESP_RETURN_ON_FALSE(output_burst_len > 0 && output_burst_len <= 16, ESP_ERR_INVALID_ARG, TAG, "output burst len out of range"); + + uint32_t in_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(proc->in_color_format); + uint32_t out_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(proc->out_color_format); + uint64_t input_frame_bits = (uint64_t)proc->h_res * proc->v_res * in_bits_per_pixel; + uint64_t output_frame_bits = (uint64_t)proc->h_res * proc->v_res * out_bits_per_pixel; + ESP_RETURN_ON_FALSE((input_frame_bits % 64) == 0, ESP_ERR_INVALID_ARG, TAG, "input frame bits should be 64-bit aligned"); + ESP_RETURN_ON_FALSE((output_frame_bits % 64) == 0, ESP_ERR_INVALID_ARG, TAG, "output frame bits should be 64-bit aligned"); + + struct esp_isp_dma_frame_ctx_t *ctx = heap_caps_calloc(1, sizeof(struct esp_isp_dma_frame_ctx_t), ISP_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(ctx, ESP_ERR_NO_MEM, err, TAG, "no mem for dma frame context"); + + ctx->proc = proc; + ctx->input_frame_size_64bit = input_frame_bits / 64; + ctx->output_frame_size_64bit = output_frame_bits / 64; + + csi_brg_dev_t *csi_brg_hw = MIPI_CSI_BRG_LL_GET_HW(proc->csi_brg_id); + ctx->csi_brg_hw = csi_brg_hw; + mipi_csi_brg_ll_set_intput_data_h_pixel_num(csi_brg_hw, proc->h_res); + mipi_csi_brg_ll_set_intput_data_v_row_num(csi_brg_hw, proc->v_res); + mipi_csi_brg_ll_set_burst_len(csi_brg_hw, 512); + mipi_csi_brg_ll_enable(csi_brg_hw, true); + + ctx->out_done_sem = xSemaphoreCreateBinary(); + ESP_GOTO_ON_FALSE(ctx->out_done_sem, ESP_ERR_NO_MEM, err, TAG, "no mem for output semaphore"); + ctx->in_done_sem = xSemaphoreCreateBinary(); + ESP_GOTO_ON_FALSE(ctx->in_done_sem, ESP_ERR_NO_MEM, err, TAG, "no mem for input semaphore"); + + dw_gdma_channel_alloc_config_t dma_out_alloc = { + .src = { + .block_transfer_type = DW_GDMA_BLOCK_TRANSFER_CONTIGUOUS, + .role = DW_GDMA_ROLE_PERIPH_CSI, + .handshake_type = DW_GDMA_HANDSHAKE_HW, + .num_outstanding_requests = 5, + .status_fetch_addr = MIPI_CSI_BRG_MEM_BASE, + }, + .dst = { + .block_transfer_type = DW_GDMA_BLOCK_TRANSFER_CONTIGUOUS, + .role = DW_GDMA_ROLE_MEM, + .handshake_type = DW_GDMA_HANDSHAKE_HW, + .num_outstanding_requests = 5, + }, + .flow_controller = DW_GDMA_FLOW_CTRL_SRC, + .chan_priority = 1, + }; + ESP_GOTO_ON_ERROR(dw_gdma_new_channel(&dma_out_alloc, &ctx->dma_out_chan), err, TAG, "create output dma channel failed"); + + dw_gdma_channel_alloc_config_t dma_in_alloc = { + .src = { + .block_transfer_type = DW_GDMA_BLOCK_TRANSFER_CONTIGUOUS, + .role = DW_GDMA_ROLE_MEM, + .handshake_type = DW_GDMA_HANDSHAKE_SW, + .num_outstanding_requests = 2, + }, + .dst = { + .block_transfer_type = DW_GDMA_BLOCK_TRANSFER_CONTIGUOUS, + .role = DW_GDMA_ROLE_PERIPH_ISP, + .handshake_type = DW_GDMA_HANDSHAKE_HW, + .num_outstanding_requests = 1, + }, + .flow_controller = DW_GDMA_FLOW_CTRL_DST, + .chan_priority = 1, + }; + ESP_GOTO_ON_ERROR(dw_gdma_new_channel(&dma_in_alloc, &ctx->dma_in_chan), err, TAG, "create input dma channel failed"); + + ctx->dma_out_trans = (dw_gdma_block_transfer_config_t) { + .src = { + .addr = MIPI_CSI_BRG_MEM_BASE, + .width = DW_GDMA_TRANS_WIDTH_64, + .burst_mode = DW_GDMA_BURST_MODE_FIXED, + .burst_items = DW_GDMA_BURST_ITEMS_512, + .burst_len = output_burst_len, + }, + .dst = { + .width = DW_GDMA_TRANS_WIDTH_64, + .burst_mode = DW_GDMA_BURST_MODE_INCREMENT, + .burst_items = DW_GDMA_BURST_ITEMS_512, + .burst_len = output_burst_len, + }, + .size = ctx->output_frame_size_64bit, + }; + ctx->dma_in_trans = (dw_gdma_block_transfer_config_t) { + .src = { + .width = DW_GDMA_TRANS_WIDTH_64, + .burst_mode = DW_GDMA_BURST_MODE_INCREMENT, + .burst_items = DW_GDMA_BURST_ITEMS_32, + }, + .dst = { + .addr = MIPI_CSI_BRG_MEM_BASE, + .width = DW_GDMA_TRANS_WIDTH_64, + .burst_mode = DW_GDMA_BURST_MODE_FIXED, + .burst_items = s_isp_dma_burst_len_to_items(proc->dma_in_burst_len), + }, + .size = ctx->input_frame_size_64bit, + }; + + dw_gdma_event_callbacks_t dma_cbs = { + .on_full_trans_done = s_isp_dma_done_cb, + }; + ESP_GOTO_ON_ERROR(dw_gdma_channel_register_event_callbacks(ctx->dma_out_chan, &dma_cbs, &ctx->out_done_sem), err, TAG, "register output dma callback failed"); + ESP_GOTO_ON_ERROR(dw_gdma_channel_register_event_callbacks(ctx->dma_in_chan, &dma_cbs, &ctx->in_done_sem), err, TAG, "register input dma callback failed"); + + proc->dma_frame_ctx = ctx; + return ESP_OK; +err: + s_isp_dma_frame_ctx_destroy(ctx); + return ret; +} + +void isp_dma_del_frame_ctx(isp_proc_handle_t proc) +{ + if (!proc || !proc->dma_frame_ctx) { + return; + } + s_isp_dma_frame_ctx_destroy(proc->dma_frame_ctx); + proc->dma_frame_ctx = NULL; +} + +esp_err_t esp_isp_dma_process_frame(isp_proc_handle_t proc, void *output_buffer, const void *input_buffer, uint32_t timeout_ms) +{ + ESP_RETURN_ON_FALSE(proc && proc->dma_frame_ctx && output_buffer && input_buffer, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE((((uintptr_t)output_buffer) % 8) == 0, ESP_ERR_INVALID_ARG, TAG, "output buffer not 8-byte aligned"); + ESP_RETURN_ON_FALSE((((uintptr_t)input_buffer) % 8) == 0, ESP_ERR_INVALID_ARG, TAG, "input buffer not 8-byte aligned"); + + esp_isp_dma_frame_ctx_t *ctx = proc->dma_frame_ctx; + ctx->dma_out_trans.dst.addr = (uint32_t)output_buffer; + ctx->dma_in_trans.src.addr = (uint32_t)input_buffer; + + ESP_RETURN_ON_ERROR(dw_gdma_channel_config_transfer(ctx->dma_out_chan, &ctx->dma_out_trans), TAG, "configure output transfer failed"); + ESP_RETURN_ON_ERROR(dw_gdma_channel_config_transfer(ctx->dma_in_chan, &ctx->dma_in_trans), TAG, "configure input transfer failed"); + dw_gdma_channel_enable_ctrl(ctx->dma_out_chan, true); + dw_gdma_channel_enable_ctrl(ctx->dma_in_chan, true); + + isp_ll_dma_trigger_frame(ctx->proc->hal.hw); + + if (xSemaphoreTake(ctx->in_done_sem, pdMS_TO_TICKS(timeout_ms)) != pdTRUE) { + ESP_LOGE(TAG, "wait input done timeout"); + return ESP_ERR_TIMEOUT; + } + if (xSemaphoreTake(ctx->out_done_sem, pdMS_TO_TICKS(timeout_ms)) != pdTRUE) { + ESP_LOGE(TAG, "wait output done timeout"); + return ESP_ERR_TIMEOUT; + } + return ESP_OK; +} diff --git a/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h b/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h index 5749c95d4b7..d6599b607b3 100644 --- a/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h +++ b/components/esp_hal_cam/esp32p4/include/hal/isp_ll.h @@ -28,7 +28,7 @@ extern "C" { #define ISP_LL_PERIPH_NUMS 1U #define ISP_LL_HSIZE_MAX 1920 -#define ISP_LL_VSIZE_MAX 1080 +#define ISP_LL_VSIZE_MAX 1280 /*--------------------------------------------------------------- Clock @@ -535,6 +535,82 @@ static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) hw->frame_cfg.hsync_end_exist = en; } +/** + * @brief Set DMA input data type + * + * @param[in] hw Hardware instance address + * @param[in] format color format, see `isp_color_t` + * + * @return true for valid format, false for invalid format + */ +static inline bool isp_ll_dma_set_data_type(isp_dev_t *hw, isp_color_t format) +{ + bool valid = false; + + switch (format) { + case ISP_COLOR_RAW8: + hw->dma_cntl.dma_data_type = 0x2A; + valid = true; + break; + case ISP_COLOR_RAW10: + hw->dma_cntl.dma_data_type = 0x2B; + valid = true; + break; + case ISP_COLOR_RAW12: + hw->dma_cntl.dma_data_type = 0x2C; + valid = true; + break; + default: + break; + } + + return valid; +} + +/** + * @brief Set DMA input burst length in units of 64-bit + * + * @param[in] hw Hardware instance address + * @param[in] burst_len Number of 64-bit beats in one DMA burst + */ +static inline void isp_ll_dma_set_burst_len(isp_dev_t *hw, uint32_t burst_len) +{ + hw->dma_cntl.dma_burst_len = burst_len; +} + +/** + * @brief Set DMA input total frame size in units of 64-bit + * + * @param[in] hw Hardware instance address + * @param[in] num64b Number of 64-bit words in one frame + */ +static inline void isp_ll_dma_set_frame_size(isp_dev_t *hw, uint32_t num64b) +{ + hw->dma_raw_data.dma_raw_num_total = num64b; + hw->dma_raw_data.dma_raw_num_total_set = 1; +} + +/** + * @brief Apply DMA input registers + * + * @param[in] hw Hardware instance address + */ +static inline void isp_ll_dma_apply_config(isp_dev_t *hw) +{ + hw->dma_cntl.dma_update_reg = 1; + while (hw->dma_cntl.dma_update_reg); +} + +/** + * @brief Trigger one DMA input frame transfer + * + * @param[in] hw Hardware instance address + */ +static inline void isp_ll_dma_trigger_frame(isp_dev_t *hw) +{ + hw->dma_cntl.dma_en = 1; +} + /** * @brief Get if demosaic is enabled * diff --git a/components/esp_hal_dma/esp32p4/include/hal/dw_gdma_ll.h b/components/esp_hal_dma/esp32p4/include/hal/dw_gdma_ll.h index 0295fee38cc..fe183849be0 100644 --- a/components/esp_hal_dma/esp32p4/include/hal/dw_gdma_ll.h +++ b/components/esp_hal_dma/esp32p4/include/hal/dw_gdma_ll.h @@ -415,6 +415,8 @@ static inline void dw_gdma_ll_channel_set_dst_master_port(dw_gdma_dev_t *dev, ui { if (mem_addr == MIPI_DSI_BRG_MEM_BASE) { dev->ch[channel].ctl0.dms = DW_GDMA_LL_MASTER_PORT_MIPI_DSI; + } else if (mem_addr == MIPI_CSI_BRG_MEM_BASE) { + dev->ch[channel].ctl0.dms = DW_GDMA_LL_MASTER_PORT_MIPI_CSI; } else { dev->ch[channel].ctl0.dms = DW_GDMA_LL_MASTER_PORT_MEMORY; } diff --git a/docs/doxygen/Doxyfile_esp32p4 b/docs/doxygen/Doxyfile_esp32p4 index 8ae3c77644e..f207c7181fa 100644 --- a/docs/doxygen/Doxyfile_esp32p4 +++ b/docs/doxygen/Doxyfile_esp32p4 @@ -16,6 +16,7 @@ INPUT += \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_ccm.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_color.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_core.h \ + $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_dma.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_crop.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_demosaic.h \ $(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_gamma.h \ diff --git a/docs/en/api-reference/peripherals/isp.rst b/docs/en/api-reference/peripherals/isp.rst index f53ce1d440d..da3478ff5b8 100644 --- a/docs/en/api-reference/peripherals/isp.rst +++ b/docs/en/api-reference/peripherals/isp.rst @@ -67,6 +67,7 @@ The ISP driver offers following services: - :ref:`isp-resource-allocation` - covers how to allocate ISP resources with properly set of configurations. It also covers how to recycle the resources when they finished working. - :ref:`isp-enable-disable` - covers how to enable and disable an ISP processor. +- :ref:`isp-dma-input` - covers how to feed image frames stored in memory into the ISP through DW-GDMA. - :ref:`isp-af-statistics` - covers how to get AF statistics one-shot or continuously. - :ref:`isp-awb-statistics` - covers how to get AWB white patches statistics one-shot or continuously. - :ref:`isp-ae-statistics` - covers how to get AE statistics one-shot or continuously. @@ -240,6 +241,15 @@ Before doing ISP pipeline, you need to enable the ISP processor first, by callin Calling :cpp:func:`esp_isp_disable` does the opposite, that is, put the driver back to the **init** state. +.. _isp-dma-input: + +ISP DMA Input +~~~~~~~~~~~~~ + +Besides image streams from camera controllers, the ISP can also read image frames from system memory through DW-GDMA. To use DMA input, set :cpp:member:`esp_isp_processor_cfg_t::input_data_source` in :cpp:type:`esp_isp_processor_cfg_t` to :cpp:enumerator:`ISP_INPUT_DATA_SOURCE_DWGDMA`, and configure the input format, output format, and resolution according to the image frame. + +DMA input is useful for feeding software-generated data, offline RAW images, or other test images in memory into the ISP. It can be used to validate an ISP pipeline without a camera sensor, reproduce issues with a specific input image. Call :cpp:func:`esp_isp_dma_process_frame` to send one input buffer to the ISP and write the processed image into an output buffer. The input and output buffers must be accessible by DMA; if cacheable memory is used, perform the required cache synchronization before and after the DMA transfer. + ISP AF Controller ~~~~~~~~~~~~~~~~~ @@ -958,6 +968,7 @@ Application Examples -------------------- * :example:`peripherals/isp/multi_pipelines` demonstrates how to use the ISP pipelines to process the image signals from camera sensors and display the video on LCD screen via DSI peripheral. +* :example:`peripherals/isp/dma_input` demonstrates how to feed a RAW8 BGGR image in memory into the ISP through DW-GDMA. ``pytest_isp_dma_input.py`` saves the processed RGB888 frames as PPM images and compares them pixel by pixel with the checked-in golden image. * `esp_video/examples `_ provides some examples of enabling ISP control algorithms. API Reference @@ -978,5 +989,6 @@ API Reference .. include-build-file:: inc/isp_color.inc .. include-build-file:: inc/isp_crop.inc .. include-build-file:: inc/isp_core.inc +.. include-build-file:: inc/isp_dma.inc .. include-build-file:: inc/components/esp_driver_isp/include/driver/isp_types.inc .. include-build-file:: inc/components/esp_hal_cam/include/hal/isp_types.inc diff --git a/docs/zh_CN/api-reference/peripherals/isp.rst b/docs/zh_CN/api-reference/peripherals/isp.rst index 25edb05f509..e42060cf39e 100644 --- a/docs/zh_CN/api-reference/peripherals/isp.rst +++ b/docs/zh_CN/api-reference/peripherals/isp.rst @@ -67,6 +67,7 @@ ISP 驱动程åº�æ��供以下æœ�务: - :ref:`isp-resource-allocation` - 涵盖如何通过正确的é…�ç½®æ�¥åˆ†é…� ISP 资æº�,以å�Šå®Œæˆ�工作å�Žå¦‚何回收资æº�。 - :ref:`isp-enable-disable` - 涵盖如何å�¯ç”¨å’Œç¦�用 ISP 处ç�†å™¨ã€‚ +- :ref:`isp-dma-input` - 涵盖如何通过 DW-GDMA 将存储在内存中的图åƒ�帧é€�å…¥ ISP。 - :ref:`isp-af-statistics` - 涵盖如何å�•次或连续获å�– AF 统计信æ�¯ã€‚ - :ref:`isp-awb-statistics` - 涵盖如何å�•次或连续获å�– AWB 白å�—统计信æ�¯ã€‚ - :ref:`isp-ae-statistics` - 涵盖如何å�•次或连续获å�– AE 统计信æ�¯ã€‚ @@ -240,6 +241,15 @@ ISP 调用 :cpp:func:`esp_isp_disable` 函数会执行相å��çš„æ“�作,å�³å°†é©±åŠ¨ç¨‹åº�æ�¢å¤�到 **init** 状æ€�。 +.. _isp-dma-input: + +ISP DMA 输入 +~~~~~~~~~~~~ + +除æ�¥è‡ªæ‘„åƒ�头控制器的数æ�®æµ�外,ISP 还å�¯ä»¥é€šè¿‡ DW-GDMA 从系统存储中读å�–图åƒ�帧作为输入。使用 DMA 输入时,应在 :cpp:type:`esp_isp_processor_cfg_t` 中将 :cpp:member:`esp_isp_processor_cfg_t::input_data_source` é…�置为 :cpp:enumerator:`ISP_INPUT_DATA_SOURCE_DWGDMA`,并根æ�®è¾“入图åƒ�æ ¼å¼�设置输入ã€�输出格å¼�å�Šåˆ†è¾¨çŽ‡ã€‚ + +DMA 输入适用于将软件生æˆ�的数æ�®ã€�离线ä¿�存的 RAW 图åƒ�或其他内存中的测试图åƒ�é€�å…¥ ISP 进行处ç�†ã€‚它å�¯ç”¨äºŽæ— æ‘„åƒ�头传感器å�‚与时验è¯� ISP æµ�水线ã€�å¤�现特定输入图åƒ�的问题。调用 :cpp:func:`esp_isp_dma_process_frame` å�¯ä»¥å°†ä¸€å¸§è¾“入缓冲区é€�å…¥ ISP,并将处ç�†å�Žçš„图åƒ�写入输出缓冲区。输入和输出缓冲区需è¦�满足 DMA 访问è¦�求;若使用带 cache 的内存,请在 DMA 传输å‰�å�Žæ‰§è¡Œå¿…è¦�çš„ cache å�Œæ­¥ã€‚ + ISP AF 控制器 ~~~~~~~~~~~~~ @@ -958,6 +968,7 @@ Kconfig 选项 :ref:`CONFIG_ISP_CTRL_FUNC_IN_IRAM` 支æŒ�: -------- * :example:`peripherals/isp/multi_pipelines` 演示了如何使用 ISP æµ�水线处ç�†æ�¥è‡ªæ‘„åƒ�头传感器的图åƒ�ä¿¡å�·ï¼Œå¹¶é€šè¿‡ DSI 外设在 LCD å±�幕上显示视频。 +* :example:`peripherals/isp/dma_input` 演示了如何通过 DW-GDMA 将内存中的 RAW8 BGGR 图åƒ�é€�å…¥ ISP。``pytest_isp_dma_input.py`` 会将处ç�†å�Žçš„ RGB888 帧ä¿�存为 PPM 图片,并与示例中æ��交的 golden 图片进行é€�åƒ�素比较。 * `esp_video/examples `_ 中包å�«è‡ªåЍå�¯ç”¨ ISP 控制算法的一些示例。 API å�‚考 @@ -978,5 +989,6 @@ API å�‚考 .. include-build-file:: inc/isp_color.inc .. include-build-file:: inc/isp_crop.inc .. include-build-file:: inc/isp_core.inc +.. include-build-file:: inc/isp_dma.inc .. include-build-file:: inc/components/esp_driver_isp/include/driver/isp_types.inc .. include-build-file:: inc/components/esp_hal_cam/include/hal/isp_types.inc diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 10e1829a3b8..3c7d010ef71 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -283,6 +283,14 @@ examples/peripherals/i3c/i3c_lsm6dscx: - esp_hal_i3c - soc +examples/peripherals/isp/dma_input: + disable: + - if: SOC_ISP_SUPPORTED != 1 + depends_components: + - esp_driver_dma + - esp_driver_isp + - soc + examples/peripherals/isp/multi_pipelines: disable: - if: SOC_MIPI_CSI_SUPPORTED != 1 diff --git a/examples/peripherals/isp/dma_input/CMakeLists.txt b/examples/peripherals/isp/dma_input/CMakeLists.txt new file mode 100644 index 00000000000..813a03e8521 --- /dev/null +++ b/examples/peripherals/isp/dma_input/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(isp_dma_input) diff --git a/examples/peripherals/isp/dma_input/README.md b/examples/peripherals/isp/dma_input/README.md new file mode 100644 index 00000000000..b554725300c --- /dev/null +++ b/examples/peripherals/isp/dma_input/README.md @@ -0,0 +1,49 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + +# ISP DMA Input Visual Test Example + +## Overview + +This example embeds a 240 x 280 RAW8 Bayer image of a real scene in flash, copies it into a DMA-capable PSRAM input buffer, feeds it into the ISP through DW-GDMA, and prints the RGB888 output as base64. The pytest script decodes the output into a PPM image and compares it with the checked-in golden image. + +The data flow is: + +1. The embedded BGGR RAW8 image is copied from flash into the ISP DMA input buffer. +2. The image is transferred into the ISP via `DW-GDMA → ISP DMA input`. +3. The ISP processes the data (demosaic, color adjustment) and outputs RGB888 (BGR24 byte layout). +4. The RGB888 frame is base64-encoded and printed with machine-parseable markers. +5. pytest decodes the payload, swaps BGR→RGB, saves one PPM file per frame, and compares it with the golden image. + +## Hardware Required + +- An ESP32-P4 devkit with PSRAM (this example allocates the ISP DMA input/output buffers from PSRAM). + +## How to Use + +Run the test locally. It builds and flashes the example, captures the serial output, and saves one PPM artifact per frame: + +``` +cd examples/peripherals/isp/dma_input +pytest pytest_isp_dma_input.py --target esp32p4 --port PORT +``` + +The pytest log directory (`dut.logdir`) contains `isp_dma_input_frame00.ppm`, the decoded RGB888 ISP output from the current hardware run. The repository includes [golden/golden.ppm](golden/golden.ppm), the checked-in reference image. The test compares the decoded RGB888 pixels with this reference image, making image-quality regressions visible in review and detectable in CI. + +## Example Output + +The example processes one embedded 240 x 280 BGGR RAW8 frame. + +```text +Feeding 1 frames through ISP DMA input... +IMAGE_META frame=0 width=240 height=280 format=BGR24 encoding=base64 +IMAGE_BASE64_BEGIN +IMAGE_BASE64 ... +IMAGE_BASE64_END +Frame 0 done +ISP DMA visual demo done. +``` + +## Reference + +- [ESP-IDF: Image Signal Processor](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/isp.html) diff --git a/examples/peripherals/isp/dma_input/golden/golden.ppm b/examples/peripherals/isp/dma_input/golden/golden.ppm new file mode 100644 index 00000000000..ba31afa2173 Binary files /dev/null and b/examples/peripherals/isp/dma_input/golden/golden.ppm differ diff --git a/examples/peripherals/isp/dma_input/main/CMakeLists.txt b/examples/peripherals/isp/dma_input/main/CMakeLists.txt new file mode 100644 index 00000000000..8d7c2262783 --- /dev/null +++ b/examples/peripherals/isp/dma_input/main/CMakeLists.txt @@ -0,0 +1,7 @@ +idf_component_register(SRCS "isp_dma_main.c" + PRIV_REQUIRES esp_driver_isp esp_mm esp_psram mbedtls + INCLUDE_DIRS ".") + +target_add_binary_data(${COMPONENT_LIB} + "${CMAKE_CURRENT_LIST_DIR}/assets/sensor_240x280_bggr.raw" + BINARY RENAME_TO "sensor_raw") diff --git a/examples/peripherals/isp/dma_input/main/assets/sensor_240x280_bggr.raw b/examples/peripherals/isp/dma_input/main/assets/sensor_240x280_bggr.raw new file mode 100644 index 00000000000..d6415e3b273 --- /dev/null +++ b/examples/peripherals/isp/dma_input/main/assets/sensor_240x280_bggr.raw @@ -0,0 +1,470 @@ +0/>Ly‚¡«»°¸µ¾ºÈ¾Ä¹ÊÂÃÂÉÄÏÀÌ¿ÇÄÍÆÑÁËÁÎÅÔÁÑÆÒÂÌÁËÇÕÌÐÈÆÅÕÊÝÉÓÈÕÈØÇàÍÞÊÜÌÝÎÚÍÜÊÛÈÖÈÕÉØËÚÅØÆãËßÏÞÐÝÊàÊØÒàËØÆÕÌÞËØÇ×ÉàÎÝÈâÊÜÅÝÅÖÆÕÊÓÇÕÇßÎÚÃ×ÅáÄàÌàÉßÇØÄÖÊÐÄÛÆÚÄÓÅÞÉÕÇ×ÅÌÅϽÊÀÉÀÖÄÓÆÏÌÛËÔÆÎÇÑÃÓÃ̾ÍÄËÃËÃȿͽ»½´»¯­—�n]=>'&À9Â8Ã=Â;È;Æ9Î7Ì7É4Ä9Ë4Å4Ë;Ê:È7Í7Ë9È6Í5Ê6È3Ç5Ì<Â8Å4Ä6É7Ë;Î<Ì5Í9Î<Í;Í9Ê7É=Ë6Ç9Ê7Ç=É>Ê/Ä;Â@Ä9Á=Ä8Á6¾8Ê7Æ;É8Ä6È6Ä9Ç6¿6Â<Í8Æ6¿9Æ8Ã1¾4Á8Ä7Æ3É4Ë8É5Â1È5Á4Ã<Ã9Ä9Â7½;Ã7½8¿:º.·0§.‚U +,  @#j= * +,'o…™¤³°¼¹½¹Ã¾È¿Ä¿È¼Ç½Å½ÇÀÉÉ˾ÎÃÌÃÊÄÍÂÍÀÍÁɿоÉÁпÑÄÓÄÎËÏÁÒÃÖÇÛÁÍÆÕÉÞÌÞÆÜÉÛÈÛÌÞÊÚÅßÈÝËâÎÛÊÛËÛÉØÄÙÍÖÅâÅÚÊÝÄÜÊßÇÚÊÕÇÞÇØÆÝÇÞÈßÅÞÂÙÆÐÅÚÂÐÂÙÆÖÊ×ÅÓÃÒÅÓ½ÒÇÔÀׯÑÀÑÂÑÂ×Ê×ÄÎÃÎÁÔÁÒÂÍÅÕÁËÈ×ÈØÊÓËÖÉ×ÃÊÅÏÈË¿ÇÂÅÊÊ¹ÉÆÅºÅ¿Ä¹Àº¿±©—�r\;3"9x‹��IE41-+&&! œ0­2³1»0º8Á6½6Â7Á9À4È9Ä9Ã%È7È:Ä:Â5À;Ç7Á;Ç4Å4¿5¿;Â9Å:Ä:Ã;¾7Á;È9Æ5Æ=Ì<Ç9Ç'É8É4Ê7Ç:Ë7Ç5Ì8È9É;È3Â8É7Ì6Î8Ä9Æ4Ç<È9È:ÉAÇ9Á=Ä<Ç;Æ<Ç;Æ8Ç7Ã8Â9Å8Ç8À8Â=Ã7À;À7Ä5Ä7¿5Â4¿4Ã7Ã7Ä;È9Ã8Ä3¼9À5Ã<Ã5Ç8Ì6Ê9Ê7Ç6À>Ã<Ç<Ç9Ä9Â3À4½4º8½6¾8º5§/†M $/°5• X8 / % "¿°·´¶¹ÁÄÿÀ¿ÃÀ̿˻ÑÃËÈÍÁÊÂËÁÏÄÍÁÒÂËÉлſÌÄÑÃÑÅÏÂ˾ÌÀÏÆÔÃÔÂÖÅ×ÉÕÁØÅÚÈÖÆÙÆÛÉÝÍÙÇÚÈÝÆÔÇÖÎÙÈàÊÛÅÖÈÕËßÎÜÆÖÉßÊãÄÝÈ×ÇÙÆÛÃÖÅÖÃÑÈÛÁÕÆ×ÃÒ¿Õ¾ÖÁÓÀÒÁÓÃÒÃÔÂÔÇØ¼ÔÂÎÄÔÅÐÃÑÃÕÂ×ÂØÉÒÁÏÀξÊÂÐÄÏÆÒÁÓÍÏÉÓÈÑÆÎÇÏÆÑÃÓÅÉÂÎÄÉ¿ÉÃʾ¾¹ÅºÁ½Á¹µ¯¨™�iU1,(c¬ÑÄ£�mV@9-.)%$´/³1¸1º4Ã7Ã6Ã8·5À6Ã7¾9Ä4Ä5Á8Ä9Á9Â7Ä7º:º?¼9¿8À8À@¼<¿6À:À9Ä9Â9Å;Å7À6Ã8Æ:Á4Ç6Ê?Ç9É4Æ8È5È5È5É8Ê9Ã=Ê6È7Ê9Æ;É7Å:Æ9Ä8Ç<Å9Ê8È:Â>Â:Á:Ã;Â;½;Â8Â5Á;Ä-»7Á0¿6Ã7Ä;Á<Æ5Æ9Ã7Â9Â7¿;Ã3½6½4À4Á0À7Ä7Æ8Æ;Ä6Ã>Ë5Å6Ã9Á9À5Á:Â<Ã2¾9¼7¿5À4¸7¸5·4¯0}I *¯OéA³'}G +0)!½µ¸º¼»¾¿ÈÂÊÅǽÈÃÅÃËÀϾ̿ͻȼÇÀÎÁÉÄÆºÍ½Ç¹Ê»ÌºÓÀֺ̺μÑÃÑÂѾÕÃÕÃ×ÇÛÈ×ÄÕÇÙÅÛÃÛÀÏÉ×ÅÔÇÓÌÖÂÙÇãÉàÅÖÉÜÆÝÉÚÉÝÂÜÃßÈÚÅØÂÔÊÎÅÓÂÌÁÑÀÒÁÒÃÑÂÙÆÙ½Ñ¼ÏÀÐÂ׼ѽ;ϽÓÅÓÂÕÅÑÉÖÄÐÂÐÁÓ¼Õ¾ÌÁ˿ŻʾǼÇÁÎÄÏÂÓ¿ËÆÏÅËÄÊÂÉ¿ÉÁÈÀÊÁÉÃËÀÁÀƾÆÀǾŹƼÀº»µ¨’�ZEAŽæçêØ·±•{TD4/))%"º4·.¹5¿6À7¾2¾4½4Â3Á8À0¿5¾;½9¼=Ã:Ä8¼7Â:¿9¿4»7Â<Â4¼6À4¼3Ã:Å;À4Ç6Â6Ä8Â6Â6Æ5Ç1Ã8Ã:Â3È9Á8Ä=Ä7Ì5Ã=Ê:Ç*É8É5Æ8Ã3Ã9Å8Æ9Ã;Å;Å:½;Á4¾;Â6¾<À7Ã9¼9Á8½>¼:¾<À:¼:Á7¼7¾2¿:Ä3½4Á5Á8¹7¼=À6½7¼4¾2½1º3Â7Á3¾7Ã0¿8Ã6¼<Â9À9½<Á8½:¿9¿9¼;Ä;Â>º;Á8»5µ;«&qŒFõNæ:Ì0œ!a4 ) +' +¾·½´½·Ã½ÀºÂ»ÆÀ˼ŻȾȿǻËÂÇÂοι̺̼ɺʿʾ˾ȾμÐÀÏÃͼϺϽվÓÃÕÃÛÃØÁØÀÖÆÓÃÔÃÓÅÕÆÖÇÓÆÏÂÕÈâÉàÄÛÂÕÄÔÆØÃÚÅÕÁÓÄÔÁÎÄÕÂ×ÄӾԿοҾϾѻѽÎÄÎÀλлɽӽÏÀÐÀѽҿ;ÍÁÓ¿ÐÁнÐÀп˻ѽʾ˷ÁºÅ»ÑÀÌÁɼÁ¼Ê½ËÁǻ˺ÊÂÌ¿ÁÀȾͿȼÊÃÈÁÈÂÉÀÅÃÇĺ½¸¹´§’›ÐäôïîåÒÆ­—n[=6)'#³/·5½5¾4½3º4»:½7¾9Á4À0¾3Ã9¾9Ä7Á3¸8À6¿5½6»8¿5»>¿;º<¿4¾7¼6¾2¾4¾5Â6¿8¾7Ã2Ç:À7¿4À<Å6Å1¿3Â;Å5É8È+À8Å8É7Å7Å9Ä8Á9¼7Å7¿8Á5¼6¼5¼6¹3½8¼:Á0½2¸3¿9º7¼7¿4À>»5¾/·4À6Á7¿:À3½2Â7Ã4µ9¾2º5½5½2·3º8¼4»2¾7º6½7½6Á;¿8¾7Â5¿.¿;Á6Á;¿=Ç9Ã>Å?Ç9Á9À8¼3¹1¨3ÙLôQòIÝ9¹)€D+º·Á¸Â¼Å¾Ã¾Ãº¼¼Ä¿È½È»Â¿Â»Õ¸ËÂ˾ƾżȼʿÀ¼Á·É¿Ë½ÌºÌ»ÌºÍ¼Í¾Ë»Î¿ÐÁÑÀÔÂÑ¿ÙÅÎÅÒ¾ÒÃÕÅÒÄÕ½ÏÄÕÂÜÁÚÅØÄÙ¿Õ¿ÚÉÚÁÑ¿ÑÄпÕÂÒ¾ÕÅнӼнÓÂ׻Ͻɼн˹ͻͿʿ̻־ѾӺϽּÑÁÒÂÒ¾ÔÂÒÀÐÀмӸÑÁ̼ľǷķ»ɼǹŹǻź˻ÉÀŻúÃÂÈÆÆ»ÈºÅ½ÈÃÌÃÄÅÌÅÅÄÌÂÄ¿À¸Àº¾´¿ÌÔíïôèÜÍ¿¬‰rJ>/º5º1¶4Â5»7»3¶3¼5µ2º8¹8½:²6º3½6¼9»7·6¾4»7¹9»:»8¼4»:¶9º4º8À8º8¾4Å5Ä=À9¿6Æ:Â5Â7Ã4À3¼3Å2Â5¼/Ã6Å6Å6Ã9À6Å6Â5¿7Á4Ã6¾9Á5»?¿9½:º:¸:¾8¿7º8¹1¼9»2»7½7¼6½;·6¼8µ1»8¾4¼7¼2·3½9»6º8Á9À7¸5¶<µ6¶8¾:½5½2º:¹7º6¹7¹9¿4¿5Á9Á9¼8¾7¿4Á:À:Ä6¾8À5Ä3¿6½8¾6´1Â.áNñEâ:È3•UǺȶŹÀ»Æ»Â»Á¸Â¸Æ¹Áµ²¹Æ³Å¼Ç·Å·¿¼Ä·Å»ÄµÀ¹Ä³Å²ÄºÆ¹ËµÉ¸ÍºÊ·ÈºÌ»Ê¿ÏÀѽÎÁνԼÔÂк׾ϽÒÁϾ׿ÝÁÓÅԿѾպڽԻֻӵ×ÀÔÀÓ»ÑÃԼҽҿѷϻμ̸βй̸Ի˻˸ӿȾҼɸȵÃÁѽ̸̿˹̼ѻ×Ãο̻źɷʶ˷ǸɼŻƹɾ̷ʱ˺ÍÀÈ¿ÆÂ˽ȿÈÃÆ»Ç¾ÅÀÊÆÆÂÌÁÇ¿ÅÃÃÀÁ¼¹¶µ¸¾ÑÞðêêÕË´Ÿ…e¼5´2±6¸3·0º8º4´7½4¸2¸6¹6¶4¶1º2¶6µ5µ4¶4³4³:¶5¹4¶7µ5µ8¼3º6¶8³6½2¾8¼3º6¼7¹4À1¼8À6·4À6º5¼;Á4¿;¿3¿2Á6Â7Â.´5º7»4¼1½2½8»1¸5¸8½;¹:¼2¼9»5¶5·3¸3´6·6¼6¹:º2µ5·4¶4º8½8¼8¹4½7À4Ã4º8¼1¾/¸4µ8»5»2¸3¾9¼;¼6½6À6¶:½8½5Á6½3º4¾1½7½:Ã<Å;Â4Â8¾7Á5À7Á8¸8»1´/Å=êFë?È4§$Á¸Àµ¼³»µÂ·¾»¿¶Å·Ã¼Ä³Å»Æ·Ä¶¾´Ã¼Ã´Å²Ä¸Á´Ä³À¹Á¶ÂµÁ¶Æ´É´Í»Ê¶ÃµÂ¹Å¹É¾Ò¹ÑÁζιҼʼԻ͹ÏÁϿ̺׺ι˾ÓÀؾϾεѽǿƻοԸκ̻ϵϴͺϺʶʺҺѹϵʹÇÀȴѸʺµƺȹȹǾʿͽǹÊÃÖ»ÎÁƷʽ̯Ǹ¸¿¹Ä¶Ã·Â·É·»¾Å¹ÆºÀ¶ÅÁ̿ĸɿʸ˽¿¼Å¸Ã»Æ¸ÇÀɼļÈÁÈ¿ÀÀ¾¿»º¶¹µºÀÝßåÐʾ¨³.¶3µ5·1¹3¶/±1º4¶2²4±3¸1«7°6²4»/³6·1³6±0²3¸4µ0±5º2´-³7¶5»7·5¹4´2¹4¹6º.¶5º6¶<¾5¶1À1»8»6·3¶6¸5¿6À5¾1·2»3³2º>¸7¼5¸6¼1¶4¶9¹5¸0¹6¹4·9¸6³5µ2¹1¹5²5´8¸4¹7¶0±,·0½3º4·3¹6¼2»3¹4»9º6µ3´5·4³6´5³6¶4µ6¾6¸6¾:¸9¼8À3¿2½6º6À1·5¹7º8¹/½4Ä5½7Á6À;À7¿%¶3´4´1ÍBã?Í3º³º¶»¶½µ½¸ÁµÀµÀ¸¼³¼³À±¿¸½´½µÁ¶À¸Å¯º·½«½³½´Á¶»±»¶ÁµË´È´¾´Ç¸Ä³ÄµÅ·Ñ´Í¶ÈºÌ¹Í¸ÇµËÀͺÊÀθʺйп˹Ȼ̶Һ̻ҼҺɺʼ˻Ʒκ͹ƾͺηʹȷɵƵȳʱȴмͶȶƻŲö̵ζǺȶȸ͹Ҹ̻͹¿¸Ë±È¸ÈµÆ´Á¶É²À´Ã³Á´Ä·Ã·ÃµÅ·Ä¹È½Å¶Á¼Ã¼ÂÁú¾¸ÃÁȽÆÀÄÀ¿¿ÁÀ¼ĸ¾½Ä¸¶³±¬³ÄÇàÑÈ´/±3¸4²5¯2²3¸0³5¶2´/³2³4¶2³1±3°4±4³4´8±3±5±0²1²4²5²1³:µ4¸0³6·2¶6±/¶4µ7¸4´6·4¶8µ6¸7½9¶2½5·6·6¿4¹:·;¸8´3·1·0·/·2³7¹7¸2¾3»3»3¶2µ2¹9¸2²7´5²6²2·2­6¶6´5´/²;¶7µ1·4´4³6¹1´5µ2¶3º0±6²5²6²2µ4´8µ4·7·3µ3»6´6½6¹8¹4Á4½3¸3·3¹3»3¹5»7º4¼3¸7¼;¿3¹/»2¸4µ.¬(®0È=½²³°¹¸¶°¶³¾´Ã±¾µ¶¶¼²¾±ÁµÀ·À´¿­¼°¾²¾¯Ä²Ã²»²½¯½±À°¿¯Á°Ã²¿´¾°À³È²Æ±Ê·Í·¿´Ì´Ç´É´Ì²ÂµÎ¹Ë¹Ë´Ì¶ÐºÒ·Õ·Ì¸ÄºÍ·Ø¸Ï½Í´Ë±Ð¶Í³Í¶Í´Å»Ê¹È¶Í°Ò´ÍºÊ¸Ï¹É°À´Ç²É¯Í±Ä³Ç´Å·ÇµÅ¯Ê´È¸Ë±ÇºÄ³Ä¶Æ´ÆµÄ²À¯Ä²Ä¯Â±É±¼¹Â´Á¶½°¼·À·¾·´¿Æ¹Â¼Ã¼À»¼¶Ã»Å·Å·¾¼¿¶ÃºÀ·¾¹½¸Á¸Àº½»À¸µ°­§­§­º®0³/ª.¯5ª2±0°5±4¯7±2²5´2´/®1¯,­/¬.±1±.ª0¯.°.®.«2«1«.«8®0³3°4´1¶1²5±4´.´5³5²1´5·5»5»0³4µ2²8·5´3º2·3¶1µ1´1º3°4¶3²3°8¸4³1·:¶3´3´4¯6¶7µ7±4®3°3²4²4´4¯6¶8²2µ6±0°5³4·-°6³9´2¹6·6´3¯0¬4³2°3´3´0²6³5¸1³4µ3¸.·4·6½6¼8½5º7¸5·5·4¸6¸1µ9º5¹4·+²3¹3¶0°.°.¨'š&´ª®®³®³­¶°Á°¿¬¾«º³»°º´º®º­¿­¾¬¿°´«¹­Â¯À­»©¼¬¸«¸°Ã¬Á­¼ª»°½­Ä¯Ä¯¼±Ã¯Á´È²É´ÆµÌ³ÉµÄ¶Ì®È¹Ë·Ã¶Ç¶ÐµÈ¸Ë¶É·Ê´Ç¸Ê¶É²Ì¯ÇµÈ·Ç³Ç³È·Ç³É·ÉµÈ±Æ±É°Æ±Æ²Á¯À²Ä³Ç­Â¯É±Å·Æ´Ã®ÃµÄ¯Ä°Ä±Á³Å·ÉµÅ³Ã»Æ²¾±º¬»¯½¯¿³¹´À²¾±Á´¿µ¾¶¼°Â¶Ä´¿ºÃ¸¿º»ºÁºÆµ»¸¿´Å·À¸´´·µµ´¹¶·º¶®±®°¯¯¤¨˜¯5¨4±/¬2°.°6­4¬-±5²3­1®0±+¯4¬0«1¨3«/©0ª.§2¥0©2¬0©1¬3¨/¬2­1±1«2±0³/²1°2®4¶2²4µ0¶1²3¶0¶7µ5³/·+¶8µ7¸2²'µ5³7²:º6µ7¶6·4´2±:³6¶2³3·9±6³1¯0µ4³4¯6´3¯4­3µ1·5´7²8²3´7±4¯/°2¸1´3­3´/²3±/«4¯0±3´/¯.´1±1±5µ1±4¬3²3°7³3·1¶7¯6·3¹4»9°3³3¶2µ0²3±2¬0²0³2¯-®,¬-¢(½©·­¿ª¹¯µ¦¸³´¨²°³­µ®¾«¾ªº¬º­»ª½±³¬¶­¸©¹¦¹©¾¨º©¼¯¿¦»®»¬¼®À®Ã®Æ©½­Á®Ä²Ç²ÇµÈ°È³Ä´É¶Æ¶Ì°É°Ã²ÊµÍ·Î±Ê±Â°È´Å¶Ë³Ê·Í³Ë´Ï±ÐµÆ°Ä¯¿·Î³Ê¸Ä´Â²Ì±Ç³Ç®Ä­À«Ä¬¿¯Ã¬Å­Ê±Å­Á¶Â°Ã¯¾«Â²Ä²¿´È°È°Ä¶Ä¬Ä±½¬»³¿°Â°Ã°Â±Ä¯¼«¶°½´º´Æ¶¸±½´»°»³»³Ãµ¿¼À³¼´´«±°¸³µ²³²´¯³¬±®©¬±§¦¥£™¥1¯+®0ª-©/­0¬/¨.®,¬/­/ª3¨0©1¬4®+©+«2ª/¨/­5¨+¥.ª2­6­/¯1©1®.¬1°1±.«0­1«1±1¬/³0°1­6®3±4¬6®4³/²4³5¬6­3´2²0¹5­0µ2´5±3²4´8¯5µ7²4¯5²/¯4´3®5­8¯4°0±1±5«1©6².«3³1­4«3­1®/±6¯/±/®.´3°1±5¯5±3®4­1¬.®/¯2¨2±4¯4­0«6¯2·1³6±8²2´4µ5¶2µ2¶/®2®/¯.¯/®+¬/­0®*¤+Ÿ(œ*²«ª¦µ©º¬¶¬´«¶§²¦µª¸ª²«º§¸¬²¥®«·¬¾©¸«½§¾¨¹®¸¦¼¨¾ªº£¶¬·§¼°Â¬¿®¿©Â®Â³À«Ç«À®Â°Å±À°Æ³Å±É®Ì«È±È³Ã²È²É°Æ­È´Ê¹Å°É°Ê²ËµÁ¯À³Â±Å®Â²Í³ÂªÉ«Æ¯Ä¯Å°Ä¬Ã¯¾«Å°Å°Â¬Â®¿¬À®Â«¿°Ã©½°Ã®Ãª¾¬Â­Á­Ã­½°º­¸±¼²»«Â©»¨»¯±ªÀ¯¿°»«»°¹«¾®¼¬¼¯¼±½°º±¿´¼¯½³»´³­·°¶¯³«®©ª¦§¦¦§¥œ¢œš—¨2£,«+«.ª-©1§-©.¨*¨1§,¥2¤.¦,¥0¥,§0©.ª2ª0«0¦.¦1©.§.¤2§2ª/«4©/¥/¯4«5«9¬/¬2­2±1«0­4­3±4®2­3µ0«5®1´2°1®7±4²1³1®0±1°4³5µ1®3¯1²5³5®3­5¯7±/¨2®2©8®3­3ª-­0­3°4ª2«3¬.©5­0©3®0¬3°-±2«2­1§/ª.¯3­3«.ª/¦3©1¥2«3¬2«6¬2®1±3®.°1°2¯3³2°1²3«2°2«/ª.§,¢-¡* &¤)�*œ'²¢±©°¥²¢³§±£³©´¢¬£¬£¬¡±§²¤¸¤¸¨±¢²£º©µ¤¶¥¹§¶¦´¥´ž¹¥µŸ²£¹¥¹©¸¨¼¨À¨¾§½¬¾©ÃªÂ³¾¬Ä²Æ®Ì¯É¯Ä¥È²Ê²Å«Ã°Ë²Ê®Ä°Ì¯Í°Æ¬Ñ²Ã²Å³Î­Ä¯Ä¯Æ«Ç±Ç±¿§·­À«Ç¬Ä°Ç¬Á¯Ã«¾­Ä«½«¼¬Ã§½¬¿§Ã¨ÂªÃ¬¾ªÂ«»¯½«¾©»©¸­¹©¹¬¹¬¸ª¼©¸¦»«¶¨·¦´¨³ª¯¦¹«·©³¥·¬¹¬³¨¶«²®°¯µ¨³¬¯ª¯¨©¢£¤¨ž©¡¢œŸ——–˜– .Ÿ,©,§,¡-¡/Ÿ+¥, ,£,¥, /ž9¤0¢1¥2¡.¤.¤0¦-ž1¡/£/Ÿ3¥/¡.¢-§0¥/¤2©.§1©1¨2©2ª0­.¯6®1³2¯0±2ª/³-°1°.°0±.ª/®2­1«3§2­1®6±.­4±2ª/­1¯1®1­/°6ª5­6­5±2¬0«8«3©1¬2¯2«/¬/¨4­-¬2¬1¬0¥+¬,¨/¬.¦0©0¯.©.¥1©4§1©/¦,©4¦-¤2§0¢5¢2§4§-¨.«2©2ª/¬/¯/¦0®-§1¦,œ-Ÿ-œ(œ'ž'—(”$’(²¦©Ÿ­¡¬£°¢© ©¡¬›° ® ¯¢´ž¬›®ž®¢¬£­ž²¡³¢µ¤µ ·¦·¢² µ¦´¤²¤¼«º¡»¥º¨»¦·§Á¨»¨¼§»©½ªÁªÂ­Á°Ã¬ÃªÃ¯È©Ë°Æ²Æ¯Å¬Ê®Ë°ËªÂ®Ê´À­Á®Â¬Áª¿­½¬½¬½¤À¬¿²ÅªÅªÄ§ÆªÂ©À¨¿¬ÁªÁ§Ã¬Â©»¬¹©¶¥µ¨´£»©¸¦»©¼©½­¹¥»©¿¨¾«¸¤±­³¦¬¤¸¥³¤»¤²¦µ§´¢¹¥·§µ¢°¤°¦°¨®¬¯§µ¥®¤®¡ª¢ª›£œŸ�ž™¡–˜——•–“”ŒŸ,£-¤, -œ0 .¡/¢,™.¢/¡0ž+ /œ,�-ž+¡,Ÿ+£+¦/£/Ÿ0 +¢-£,¡/ž0¦/Ÿ.¢0¢3¤/£1¨,§.©)ª-¨+§,¬0§1ª3ª/­.­3­2®,­/­0ª2³5­.ª.¯.­2¯0ª-ª4­1«/¬4«6¨3¬0«:©*§6¯-¬,¨0ª1¨0®/¦+©0«1©0¨*¥-¦/¢/ª(§/¨-¦,ª0§/¥.¦-¡1¤/¦/£0¨,£0§- +¡-¢0¦0¦2£+£,¦,§,©/¢-¢-œ,ž+Ÿ%¢,—(›.œ(—%“+‘$�%‹$¥¡¬�ªœ Ÿ«žªŸ­¤­Ÿ¦¡¨œ®�ªž¦¡«ž­¢­£²ž¬¤­ ±�±¥¹ ´¤µ¤¶ ·›²¢±¦¸¥¹ ·¤¶¦µ¦¼¬½¦Áª¼¬»§Ã«Ç§À¬¿¦Â¬¿¦¿«»§Â­Å¬Ê§Ä©ÉªÀ¬Ä¬Ä«À°¿ªÃ©Á¤Ä¦Å®¼¨Ã¬Ã­Ã¬¾¬Â§Å­Ä¨ÈªÄ«¹§¾¤¹§¸©º¦º©»¦¹¨»§¹¨º£½¨®§»¨¹¨º¥·ª·¥¶¥´£³¢´¥³§¯¤²¡·£·£¯¤¯ ª¢´ ¨£­§­�­¦«¥¬¢­Ÿ¤œ¤œ¨ž¡” ™›™š••‘‘Ž“Œ’Œ‹‰£(�,œ+œ-›,œ+ -œ+¢-š.ž/¡)�-ž)¢-�-¢, -ž*Ÿ/™/�- .ž/œ.¡.¡1¢-¢,¦0¥-¢+¦1©3­1¨3¥1¬*©.«2­3ª:­-¬3¯-®/­4­2®1©/­/­0¬0­/«5®.ª2°/ª2¬2ª5¬/¦3¨3°8«-©0¦0ª1­7¦1¥5¥3¬.«.¡1¥0£0¦2£3¥0¤-¡*¥/¦-¦-¥0£/£.¡3¤1 0¡/¥+¡(¥.©0Ÿ1Ÿ&¢,¢0ž.£)¢+¡,ž.œ1œ/™-›+›*˜)•.•%‘(�(�*ˆ*Š"†ª™ª ¨—¦š«™ª›§Ÿ¨š©—ªŸ«šª�§š¨ž®™¬¡«�¯¡ªž±Ÿ³Ÿ¬œ®�°�± ³¡· ¸¡»¤»¤· ¾£º¡¼«¾ª¾©¹¦¹©½¥Â§¿«Â¨Á©Ã§Ã­º°Ä«Â¯¿ªÃ¨Î®É¬Ì©À²Ç¬Ç¬½¦È§Â¤Ä¬Á¥Á­½¨¾§¾­Æ§À©½¯¿¨¿¤À©Á¦Æ¤·¦»£¶¢¼¦»¤¶¢¬¦¸¢º£¸¢¸¦¾¤¶¦¶¢¸¢²¢µ¡®Ÿ±¡³¤®¥¬¡­¥°£´¢¨ ¯¡¤¡¥�¨¢©žª�©—¢›¨˜£˜œ–›–¡•žŽ—��Ž�‰”‰Š†Šƒ†€™(—/–,˜*—*™(™(–(˜)š,Ÿ/™(œ+š*™'™+›'š)¢,ž,�,�.˜0˜2œ.�*›+œ+£-¥2¥,¢+£.¢2§0¨+¦+§1¦/§.«1¦-¦0¦0©2¦/ª/­/«0¨1§1­1«.«*§.¬2¦0ª/¥6®/©2¨2§1§2©3ª2©4«/§2¦2¦1§+£+¨0 -¥,¤0¢.¤0£/ ,Ÿ/£,§2©1¡/£3¤-Ÿ/Ÿ.™2�.œ1¢*�+Ÿ,¤,ž3�.ž*›.�'ž'™+œ,–+•(—/—+’*’*�(�$�Œ(‡+‰"ƒ‚"|"£” ’ —£‘¡™¨•¤–¢š¥˜¡œ¢›¨›¥š­œ©•¦š¬š¨—¨™°›¯�ª�®ž¯š°ž¯šµž³ž³œ¼£»ž¹£¹¦»£¿¡¹¥¾¦¼«·¨À¦Æ¨¿ªÂ¤Ã©¿¥Å¨Å§ÃªÆ¨Ç©Æ«Ä©À«Â¦Â¬¾«¸¨Ã¨Ç¡¿§À¨¿©¾£¼¨¾§Á¨Â¤ÁªÂ¦Á§Ä§¾¨º¥º¤·¤À¥³£±§±¤³ ´Ÿ¹ ´¡²¥´£³¡¬Ÿ¶£±œ¯Ÿ±œ´Ÿ°Ÿ¬¡ªž«Ÿ­�­�¬›­ £œ¦ž§–¦š¡—ž—¢”Ÿ—œ”—�—Ž—�—Œ�‡�‡ˆ„‚‰€‰z�z“,˜'–)”*˜,™-–.™)›+“(•-œ-›)”.š-–+›*›*œ*™*œ)”*–)¡.œ/›.Ÿ, +ž2¢-¥/¡+£4¦0¥-§,¨,¨+£,ª.Ÿ.«.§0«1«/§.¡/©3«1©0­+­1®/«4¨1¨4£0ª4¬0¥+§3ª3¦3§/¦4©1­.¡2©0¨.©-¢,£1¤.¥*¦1¢2 .ž,œ,¤-£.£+¢,¤1 , 3¡, *š/ž(™+š2œ.˜,›-�*›-›+›+™-œ/•-–.–+‘$“(–$’-�'Š*‰&Š%…"†#‚� �"z x ˜Ÿ—£—¤–¢—�˜¡”£”¤—¤’¡—§™ª—£“§˜¦š«™­�¬œ±–²š±–«ž¯œ¯œ®�¶›®›°ž­¡·£ºŸ·¤º¥º§º£¸ ¶¦³«¿©½¦¿¨»¥»¨Á§¿¦Å¨È¦Å¬½¨Á§Ã¨¿®Ã§¼§À§Ã¨¹©Ä§¼¨Ã©Ã«Ã¥¼¨Â¤Ã¥Ä¨Á¨¾¥Ä§Ä¤Â¬»¥·§¾£¾§º¥µ ¸£®£®Ÿ³�¶¡±›¯œ°¡° ¬›®¡§›«š¬™­ž¬œª˜¯—¬›¤™§—©“ • ‘ž˜™‘œ“œ‘¢•��•ޓВ�–…‘‡‰„‹‚Š�‰}‚z‚x�t‘(“-�)‘+�&•+‘)“&“/“(–)•*˜0™*—(˜+•*—.›+˜,™)œ/–)›/™6œ+œ(›-ž1ž.¢.Ÿ.©3¢0Ÿ2¤/¥0£1¢2£1§1¬,§,£4©-¦0¥2©,ª/¥5§0«/¦1©/¦2¦1¦1¨/§0©0¨0©.¤1§/¥- 1¦1©1¤2¤0¬/¦-¨-¢.¤+¢.¥1¢)¦-§-Ÿ0¡0¡/ .�/Ÿ- -ž+œ-ž+Ÿ/š3›,™,˜)Ÿ,˜-•(˜,‘&•)’(’*‘)’*�+�"Š#‘'…+‹%‡%‚"€&�$} yzvu£�¡Žž‹›�Ÿ“ŸŽŸ’Ÿ‘¥•£”¢“¢“¤— ”¥’«—¦˜ª—¬�¬—¬™­™ªš¨�¨™±ž¬š®›±ž² ²�¶ ¸¥µ£·¢·¤¹§¹ »§¾¥½¨Â¦¼¦¼¡¾¨Ã­Â£¾§Ã¨½ Á§Ã§»©À£¶¤µ§À¬Ã©À¨»¨¼¨¿¥½¢»§Á¤Ä ¾¤¿£Ã¤¿¥·¨¹¥¼¥º¥µ¤Á¦µ µ¡³¤·ŸºŸ®¢³Ÿ·¡¬Ÿµ¡­ž°žªœ­�¥š©�¯”¥–£™¦”¤–¦”§ž¥—Ÿ�ž’�’›Ž™‹—•”ˆ–†�‰Š„‹†Š„„�„€€|€y{w�ywruo‹"�%�#�%“(Ž"�&“)•(“-—+’+‘)“+”+”(”,˜2™*˜,š*–-–-—.˜0—/�)—,š*›)›3˜-ž-ž,£,¥,¡,¡0¤/©2¥0¥)£.¦2©-¬0¨2ª3¥,¥/¥3¦/¦4ª-§1ª1¬.¨3©(¡/¦1£3¨0§-©, +¢.¤1¤1 1£1¦/£0¦/¡,¥-ž7§.¦. .¢,�-œ,˜,œ-ž.Ÿ*œ*œ)–+˜)•'–*œ+˜*˜+”+š,˜)“+”(�'“&�(‘&Œ'�$‡#…%„ �&†#‚&z'~v y"xtn ˜ˆš�˜Œœ�Ÿ�™‰–‘Ÿ‹¡”Ÿ•¢�¤“¥”¦“�“§—¥‘¦“ª•©˜¦—¦—©•¨›²”­š¬–ªšµœ®˜¯�´š¹ž»£¸œ·¡¹¢º¢Ã£¿¡Ã À£À¡¿¨Á©¿¢¾¥¾§¿£Â§¿£¼¦½¨¿£É¨Â¤¿§¼¦À¥»£¾¥¿¤»¢¿¤½§¿£Â§¼¢¿¤½§½£À¢¿¢¸ ½ž·ž¹¡²¦´¢µœµ¢¶ ³Ÿ«›°š±œ¯š¯™©™¨•­•«œ©•§˜¥“¥’�—ž•¥”™”ž�ž�˜�‘‘šŠ•Ž“†‘…�†�‚ˆ‚ˆ…�zƒzzy{s{sxnsmˆ"Œ%‹&Ž)‹'�%�$’)�/‘'’&‘&”(�*“-‘-”+–(’+–*–&˜.”+—1¡)‘0™,›,›1œ-œ-œ- ,¡/ )Ÿ.¢.ž2£/£-¤1›,�+¦.¦1¤1¡+£0¥.¦*£2£1¡1ª.§.¥+¥2¨.¥+£-¤2¨0¢0¦1¤0¥/¨/¤/ 1¥.ž-¤/¦.ž.£.Ÿ* / 0›-Ÿ0£.¢-œ/—2™/�*ž-–+—,›,—,—+–2•&’-•&�.�)–#�$�%�)Š"Š(‹%†(‡)‚'…#�#€!x$|%y$yqrppp™Œ¢�—„œŠ’��Œ›�ž�“�›ŠŸ‘œ��‘Ÿ“£�¨”§�©–¦™¥’¦™©—ª—¥—¨™¤‘¨˜°œµœ·ž¶�· ´¡µ�´¢¹›·¢º£¼¢¿¥À£¿¢¾©Á¥»¤¾¦Á¨Á¥»ªÇ©º£¿£À£¿§º£¿¦¼©¾¦Å¦Ä©¿¨Å¢½¨¿¥Ã¦»¥¼¦º£½£½¥»¤¼¦¶ ¼£¹¦¹Ÿµž² ±�­£«ž¯�±�³–±™­œ®˜¦”¥”ª’¥™¥—¢—£“¥‘ ”ž�š‘ �˜‘Ÿ‹›Šš†–‹•…‘…Œ‰‰~†‚ˆy‹}„z„w}yxpxrznwnrmsjŽ'…&„(‰%…'‹'�+�%‹)�*�%Š*�%�'�)“'’)”.‘)“+–+”)™*“-•+™-•+›,–-›/š.�-�2›.¡/ -£-¢0 ,ž/ž/¢.£$ /¢,£+¢+¨*¥.©2©0¡3§-¥0£2§.¤+ - 2¤4¢2¡3¡-Ÿ0¥/¦1¢5¨+¢+ž0¤,¡1ž-¡-¤*¡+œ-Ÿ1™/ž*Ÿ,—4�1˜,•0•&”,–-›+–)”$�*’-–'’%Ž(�*Š&Œ%�%Œ'ˆ%†&ˆ*„$…&‚)‚(‚#€$~x#} ss#o!pnol�‡˜Œ•Š’…–‹—†˜ˆšŠ”‹ ‹ ‰œ�œ�ž���¤“¤�ª�«™¬’¨’¨–§™¦–­’©•­“¬›¯œ²š±–º ±™µ™¶ž·�¸ŸÁ¢¸£¹Ÿº�»£Ã£ÂŸ¼¢¼¡À£¾¥Á¥Ã¥»£¿¢Ã¥ÃŸÂ¡À§Ã¤Ã¤¾¦Á¨Â¤Ä£½£¿¥º¦¾¡²¤¾¡½ Á¥¹ º¡²œ·¥¹¢»Ÿ³ ° ³¢¶£®š©œ²š¬—­”µ•¬˜¬—©–¬•§’�‘¦“¢• Ž›Ž��š‘™ˆ›‰”Œ•…“†—„�†‘€Œ}ƒˆ|ˆ{‚y~w�r~myrur{kuelkkg‰"…&ƒ&…#†&†#ˆ(‡%Ž'�*‰%‹*Ž'�,�%�*�%�$’+�)•-”*—*’,“)”,”-—,—,˜.›-›,ž+œ-ž,�- -�-Ÿ0£-Ÿ/¦.¤.¢-¤0¤4¤+¤1¤-¥-¢.¤1§,£2¥1¥1¡,£0¤0¤.¢/¡6¦.¥/«,¡1¡)¤/¡2¤2¡-¡0¢-£, /�,›,¢.ž- *�*”/�0—2—-–&˜(—-”-˜(�/•)•)”(‘*‹*“*�)‹*ˆ(†(‰&†&„#&�&€#z z!w#uu!pqlkgge’†”ˆ’ˆ”„Œ…”ˆ‘Œ–‰šˆ•‰¡‰›�˜Œ¢‹œŽžŽ¥’¥‘£•ª‘£’­“©–«™­•§’­™­•¬•±—´š¶œ´ž¯›µ ¹�´¡µ¡·£¼£Á¡¹£¸¡¶§¼¦¹Ÿº¤»¤Á¨¿¦Á¨Á¦Ç§Á¥½¤¾¥Ã©Ã¨Á¦Â¦º¡Á¤¿¢¼£¹ŸÃ£¼ À§»¡·œ´£º¦¹ ¸ ¾¡¸œ±ž¸Ÿ¹›·š¯›¯š®•­—°—¦—ª›¨”ª‘ª“¨–¥�šŽœ“Ÿ“ �–Ž™‹™ˆ–‚“…��•„Œ�Š�‹|†}„~‡yƒvt~synsoskplkhjikfld…!†!„$†'‚)…(ˆ(†%…*‰'ˆ*�$…%Š&Š)Œ/Ž'Ž)”/�*“+‘+“)’(“)”,š+“+›,�-™/™*Ÿ.Ÿ-Ÿ*š)Ÿ.¤/£/Ÿ+ /£0 /Ÿ3¤/£1¥2¦/¢2§+¢-¦-¥.©-¦1¢.¤2¨,©3¨0¦0¤0¥2¢0¤*¦1¥-¦,¢- 1¢-ž*œ.¡-š-š+ž+›.š+˜0—-™-–(”)–*‘-˜+—)’)’)�)‘/Œ&�&�%‹'Š+Œ*†$†*†#‚&(�$€${#y{y!t!t!pooiefh)d_�}Ž€”�Ž„’��‡‘ƒ’ƒ’„™‹–ˆ˜‰�†›Œ›ŒŸ‰ Žž”œ’¤Œ¤“¨�¤�¥“¤’§”«“°š®—­˜¯•³—°Ÿ²š³�²”¶¡·¢¸œ½¡¿Ÿ»�¸¢¾£»£¿¥Ä£¾¢¾¥¾¤¼¥½ ¹¤¼¥¾¤Â¥»¥Á¨»¥Á¥´£»¦¾¢º¢¶Ÿ¾£¹¢» ½¡¹Ÿ¼¥¸›²�³›·ŸµŸ±›°œ°™¯˜­�°˜«•®•­–¦—¨“©�§�¢�¡Ž�’ž�œ�œ�•Š•‹˜‚˜†”ƒ”‡Œ‚‹}ˆ†{‚vƒyƒv‚v~r|sznumulrjuneegde_h]€"}#�'|&†$�%„$‚)„#�#Œ$„)Š&‡)�*ˆ.�'�$�&‘)�'�(�*’)Ž,–-”+˜0—,–(–*š+›-ž.ž,›.ž+›-œ- .¡,›+£1Ÿ/Ÿ.£+¢,¦+œ1£0§,¦-¥.Ÿ-Ÿ/£.¤-¦/ / +¦,£0¨4¥,�0£1¢0£0¥5¢, /ž.ž2œ+›.œ5Ÿ(™'•.–/›,’-–*˜/•-’)’)”'‘'’%˜$Œ*Ž$�(Ž'„$Š(‹%ƒ#‚%ƒ%€#€$€"{"zu!txrq"p l!ogk#ncb\Šˆ}�€�„Œ€‹€Œ€��—†•‚”†šˆ›†šƒŸ‰ �œŽœ‹��£�¥‘£•¦‘©—¥�©“¡˜®‘¬–®—´–¶œ¬—­œ¹•¸œµ›¶ž¶¢¾ ½¡½ Á¡»Ÿ¿¡¼¡À¦Å§½¢¼žº¡Ã¤»§Á À ½¦Á¥À¤»£Ä ¹¢¿ ¿¥» ¿›¶¢³ŸÄž¸�¼�°›¶Ÿ°Ÿ¶š´˜¯š­œªž­™³–±˜°”¦˜ª˜ª•¤’®‘£�¡”¢���ž‰ŸŒœŠ˜ˆšˆž‚“Š�•‚ŽŽ~’y†{…z…w€q~uvnsktjtktkslofobjfjce_fWz$} ~#€(~ }!€"„*ƒ)ƒ%…%Š%Œ'Š(ˆ+Š&Š#�'�,‹'�%’'“+’*“)‘&™)”+—˜.š-™.•*”3–,ž3–/Ÿ,›,�2Ÿ+ - 7ž-¤- ,ž2 0§,¦.¥5¦.¦,¦+¢0¨/¤4¤2¡0¦/ž.£/¢/£2¡2 3ž-¥*Ÿ.¡*˜/š1Ÿ5›+”-›-š.š+˜*š*™*–,˜+›,–(”(’)�(’*Œ,�'‹)�(…(‡#‡$„&‚&„$�"€#‚#|%z)w&y!v rrn!kklhfefb`_†„zŠ‹’�‡‚�…�€‹…‘…•‚•„—‡š†œ‰�†��Ÿ�œŽ£Œž�§’£—¦“°™©“§–«˜¯–±–­˜±–°›²ž±›´ž³œ¨œ½¥À�·¢¿Ÿ·�¹¡Á ·Ÿ¾¤¼¤ºž´¨Á¤À£½£Ä¤¼¤¼¤¾¨º¤Á¦½£¼¨Ä Á »¤Á¡½¡¼ŸÁ · ½œ¯¡³œ¸ž¸š· ¶™ºš¯›©–¯—²šª–­—ª•¤•£’ª�¡�¡ŽŸ�¤Œ �™ˆ›‰—†˜…”…”‚Ž…Š‹}‰z…}{€t€ro�r~pyprksmqimeldobhbk_fZe`v$z|}#)€!&ƒ$„"ƒ%†$…'†%Š+ˆ(†)Œ&ˆ'�"Ž-�&Œ(‘*�)‘*“)˜.•*—-•-–.™/˜-–3Ÿ*—/�. ,Ÿ0�(Ÿ/œ-�0£/�/›) .£/Ÿ1¤0¦0 1¢/¥0£+§-¤.£0 -£1¡.¦.ž0 -¦/Ÿ-Ÿ/¥/ 0œ0¢1Ÿ/›1Ÿ1œ,˜,›*›.œ/˜)˜)—,•-’-”+”+�-‘)�+Ž+’&‹&ˆ&‹)…'€'‚%…$~$„""~%y y'ww"p p!pnmiji``bb_Y�w‡w‰|†~‹x�|Ž��Š‚—†–†�ƒ•†˜‰Ÿ†�Œ ‰¡‰žŽ ‹¥Ž¥�¨�§’©‘ª•¬”¯—¯—¯“±•´—³™±œ¸ž°š°œ´›´ ¿ŸÁ ¿ ¸¢¹ ¿ŸÂ�¼ ÀŸ¾œ»¨Â¦º£Â¡Â¢¼¤À¢Á Ã¢À¤¿£½§¿¢½ ¼¥Ã¤ÂŸ¿¢¾¡Àž¼ž¶œ·žµž¸›¸�´™´œ®˜­•¯•®˜¯”ª‘ª‘¥•¤’¥�¤�¥Ž¡��‹¡‰žˆ›†™„˜†’�ŠŠ‚�}ŒzŠx‡y‰x€zxq}rzqymxjtitfldkfieked`cbg[bY|z${"z"{#z }&!{$„"…$%ˆ(…$‡&‚*‰&‹"Ž&�(‹'Ž&Ž&Ž,‘)•(–,’/‘+•)•(—.•0›.™,˜1Ÿ2œ*š2 +œ+¢0›2¤0£4¢0¡1Ÿ0¥,¦-§1 /¦0£/¢2¤4¥-¢/¡,¡.¤+ . 0¢-¡-œ,œ0ž/¢+œ,œ)¢0�/š/š-�&–*š(™*•,—#”*‘+’-Ž)�(�%�,†*Ž'‰(‰(Š&ƒ"„$‡*…$~""y!z%u${"wu!n&q n!ogmgedcb]]_Z~w„vŠy‹yˆ|‡�€Ž€Ž}Ž„��”~•†›…œƒ˜„—Šœ� ‰Ÿ�¤�¢‘¦˜¦�§�¦—§’¬�¤�¦–¬œ¯•±™¹˜³œ°Ÿ´˜·œµž¼ŸÁ¡¹¡¼›¾¡À¡¼¢» »¡¿§Â¤¾Ÿ·£ÁŸÅ£Ä¡½¤¾š¾žÁ¤Ä¢¾�Á¥¿¡Ã¢Áž¿™¾ž¸Ÿ·Ÿµš·Ÿ·Ÿ±›¶™³›®—¬š²—­˜±—²“®�®“¨’¤�¢‹Ÿ���¡‰›‰ž‰�‰–ƒ–‚—‡”‚—~Ž}Ž|�yˆy†z„wƒr€q|q~oyotjrhqgnelejcl`eag_`[bYc]qv#y!|"}y#}#€%ƒ ‚%‚#‚"�'‚%‚&„&†)Š%ˆ(‰'�)�/‘)“*�,•'“,”+–(“,˜/•0ž,™(™,™-™/Ÿ.£1›3ž)œ/¡) -Ÿ0Ÿ1Ÿ1¡0¥.¤.Ÿ/¢2¢1¢/£1 2£0¤.£0£. /œ1¥.Ÿ'¡1ž2›0¡-›-Ÿ0Ÿ.¡.œ.š,�/–,–*›(›)–/”+—-“*�&Ž(�*Š&�)�-‹*‡&‹,�)�$…&‚$€')|$y#~%y!u x!ps mnllhecb]_^^[\t„s„vƒ|‹z“zŒxŠ}Ž~�ƒ��’‚�ˆ—�š…™‡’‹¢„£‰Ÿ�¤Œœ�œ‘¢�¥“¤“£•²“°˜­–«“±˜µ�µœ·˜­˜±™·›·œ¹�ºš¼ · ¼œ¹Ÿ¶¢¿§À¢¼¤¹¤¼�£¿ŸÃ¢Ä¤Ã¥¿šÆ¤ÄžÁž¾¤¼œ¿ »¥½§ºž¼Ÿ¾¤¾šºœ®œ»šµœ¶�®�®˜³—±”¨–«“­–©’£’¥�¥‘¢Œ©�Ÿ‹¤Š�‡š…•†’„—Š’�•€‘x�~‹y„r„{†wq~x~t{sxlvnqiwhqflkh^l_hbc`h`e\a\aYwrr$x x!x#z"{"}&!�"€!† �$…)…'…(„'‰'Š'Ž(’)�)•(‘%�(•+—*“+–&�)•'’(—/œ0œ)�- +œ+ž-¢-¡0œ4¦0£0 /£.¤*£1¡.Ÿ.¤0£4¥,£.¡- /¢/ 1�0�0¢.Ÿ/¦.¢-£3¡.�-�,›0›-œ*›,•-›-š(—*—)“,”0‘,•)�.•*�%Œ'�)Š(�%�'„#ˆ"�#€&ƒ'z)~!~%{'x%xvrq!ponmihida`_`]^]Z‚n|s‚uƒvƒ{‡|‰z�{†y�~�}�}’€’„•‡˜†šŠ—Š›‰š‹¡Š¦Ž¦�¥“ª˜¨•¨–§•¯’°”­–­—²–¸™·œ½œº›´œ¶ž¸¢¶žº�¾ž¾£Â�Äœ¾¢¿¦¸¢ÆŸ¸£¾£ÀžË¤Ä£Â¡½žÄ£À¡¿œ¼£¿§¾ŸÁ§¼ž´Ÿº¢¾ž·š¶¡µ ¸�²›¸–°›µ•¶˜²•¬–®™¦–®”¨“¥� Ž¡‘ ‹�‡šˆž‡�‡ž„œ‚˜~�{‹{ˆ}‰�y�xŠx€t‚q}rzo{mvkslujrjncjbk_k^dbc_eZa[\]^Wp"p s#w ty u#y$y#{$x%|'}&…#�%…&†&‰$Œ'Š'…(‰-�'Ž)�1‘*‘)’&’*‘)•+“)˜-–)š)š(�*œ.ž/�/œ.¢/�-¢+¢,�-š.£/¦, 0Ÿ+¥+¤0£1¡1£1£,¦+Ÿ.¢-¡- 1¦-¢5�.œ.¢2¢0ž+ž.Ÿ+š)›,–,š.”*”/•,�+š)‘'“(Ž*Ž,Ž'�(Ž$‰#‰&‚'ˆ(†!�!~%{$&{"|"wr#ts"qu!rkg#h"gd"dcde`\XXZX{nyrv„x„r†v‡wˆyŒy�€�}Œ�ŽƒŽ‚Ž…–‡�€›‡�Œš‡��ŸŒ¢“§Ž¤”¦’©�©’°’­–³”µ™²”±˜°—¼›³œµœ¹œ·›°œ»¢Â¡À ¼�¢Á¤¾¤Á§Â¢»¦º£Ã£Ã£¿¥Ã¡Â¥»¡¾ ¾£¿¢½¢ÁŸ¼œ¼ž´Ÿ¿�»¢³¤¸�¶š¶œ»–·”¬›°–³”¬’±—¬”­”®‘¤�¥�¥Ž�ˆ¥Œ£…ž‡˜†‘‰™„•ƒ�…’}�‡|†{…t‚vr~r}r|onzhojvhrhm`majcjk]aa]i]`Z_Xc[]Ol!tqtu yt&v$z#z$‚"}#�$‚%�#ƒ%ƒ(…'ˆ)ˆ)‰+‰)�)�+�,‘+Ž&“%�.‘'–.”-–.—)›&›'˜,ž3›0�2ž-¡3¥4Ÿ* 1Ÿ2¢,Ÿ0¦. 2¤.¢/¡1 ,£3¬, .Ÿ1¤/¢,ž0¨-§-ž0 1š1›0Ÿ/ 1 *›.›*›+™,˜.™+˜)’)‘/“,”(Ž$‘(Œ!�(ˆ*‹%ˆ$‚)†)„,€"�%�'"!w!}"z#z"k"z omoltm fia_]cb\]X\V~o{n~q€x…t‚v…t„{‰wŠy‹~•€‘€Ž~•�–‚ž�™€–…›†™…¤‰ž† Œ �¨�«’°”°’®’«�®•¯“°™²˜·™³›µ™º�¼ŸµŸ¹œÂ£¼ ÆŸÂ¡Á¡½ Â¡»§»¢Ã ¸¢À¢Å¥Ë¦Ç¥Ç¢Á£¼£º¡À¥¿¡Á¢Ä¥¾ ¾ ¹ž»�º�·�¶š±˜¶œµ“­›¶˜«”«•¤’®�¨‹¨Œª�¤�£Š¤‰Ÿ‡œ…š†—„•~š€���~�z‘Œƒx†v…uƒt|o|n�l}kvi{irdobn`eghcmbbf[X`[]\dX^Rmllutu v$x#y!v$x }#"}"€$„%‡#ƒ"ƒ*ˆ#‡%Œ(ˆ,Š'�+‘'�-�.’+—+”0“/•1—(›/š-–,š+™-Ÿ+ž1¤,ž/š/�2¢3Ÿ2¤.Ÿ-¡-¤1Ÿ/¡0¢0§.£+¢/©/¤3 /¤,¡/ 1¥0 0ž, -Ÿ0œ-œ,Ÿ.Ÿ2œ-�+œ/›2˜,š-”*”+”)Œ'�'Œ*‡(Œ'ˆ"„$‡)‰%…$�'‚%}%#z!~"{ s!v!p%r!o!p"nkjfhbdfc_[\WYWXvk|mƒo~t~q‚qˆr‚wŠuˆw‰z’{”~�€“‚”„™ƒœ„ž„™‡›…Ÿ‰ž‰¥‹«‘¥”°Ž¦Šª�¬”¥“¸�°š¯—¶�´•·˜·—¹�¼œ¾�ºŸ¿¡ºŸ¼Ÿ½ ÀŸ¿¢Ã¢Â À�ģĥ¿ŸÂ¢Ã¤Ã¢Ä¤¾¡À¡ÁŸ¿ Ä¤¾¢½ž¼¢À¢¹¡µ�¹�¶œ³œ¯›¹™´™±™²•¶–­•¤“ª“¨Œ£“ ‹œ‰œŠžŒ™‰›…œ…”�•€�}Œ€‹|‹xˆx‡s‚sƒw�qzn}ro~nwiqfrftcoefem_gbc[`\cZ^XaW^UZWilnn s nq!w&x"x#y!{$x!&}'�"ƒ&€#† …(†'ˆ,‰(‰'Ž%�+�)’)�(’)Ž,’-š-œ*™-•,Ÿ.�+œ/—0š,Ÿ-Ÿ'�.¡2 -¡+ž+�1¡0¤0Ÿ2¡2Ÿ3¢. +£0¦/¤1¢0£0¢-¢. 1£/ž-Ÿ.Ÿ/Ÿ+Ÿ(˜1ž+“*�*š)š(˜%‘+“,•(”(‘(Ž+�'�(‡(†'‡(‚'…'…$�&'…"!|#z#z&uvso$l#s lmf!dfg_aa`_XZWcSzezp~mzp€q‚t†pˆu‰vˆzˆy�z�~’}”Žƒ“„™ˆœƒŸƒ�‡˜‡¡�¢Œ �ª‹§�°�¦’¬–±‘¸•°—µ›¹—³˜¸œ±œ»š´œ¼œº¢Á¥¾¢È¡»¢Ä£Á¡¿¢Â ÀžÅ£Ä¢Ä¤¿¡Á¡Ã¡Å¤Ä¢¾£Ã£ÄžÁ ¾£¼ŸÀ¢¾£ÀžÀ¢»�³—·�¼ž¶›®™³™´�³‘¬˜§‘£“¦�¦Ž¨‡¡Š™†œ‡ž†–…–ƒ”‚’|’€�€Žz‰y‰|‡v„t€v}r}m|kumtisisirbthsam_l]nbhZf[a[bX^U\^ZXiio!mr!oq$u&r!u$v!{#~"}%~%~(…'…&ƒ"†&‹%„'Š%‰)‹&�-�)�*‘*�,”)—+–,”,˜0—2˜,�-œ4œ.ž+�0¡(�*¢(Ÿ-Ÿ/¡2¤.£.¥3£4¦-¢,¤/£1¦/¡3¢2¡1 0Ÿ0¡/£,¡,¡,£-Ÿ-œ0ž-�-œ.š.™.“*•1˜,•'–-“)�)�&‘*Ž,�%‡$‡(Š$„(‚'�$&}$~"|"w"v'v!tp"sp"qmkk!fifd___][[ZWTVzhskwk{l{mˆp€s„u|q…u‰vŠ}Ž|Œ}”}•€�ƒ‘€”‚˜†�†—‡£‹£‹ �Ÿ�¨�¨‘­�ª�¬�²–®•±‘µ–´œ´˜·—µœ´ž¼�»›½œÂ Ä » ÁŸ¼¤Â£Ã£¿¤Á©Á£Æ£Ç¢Å¦À£Ç¢À¤Ã¡À¡Â£Ä£Ã ÁŸ»¢¹�¹�³¢½šºš¶—¸—­š¯•²–°–¬‘¯Žª“¦’­�¥‹¦Ž †¤„ž‡›‡”‚�€‘~‘“|�€�€‰x�u†v‚q{q~q{l{rwmuhvgqaphp_l_f[k`i`eXf\]T]V_WZS\Ugten l!mp o$q"y#u"x#z"y#~%€'�,ƒ$ƒ$€%‡(„%†(‰+�*Œ%‘)“$‘*‘/‘1˜(•-—&š,—-›-œ+˜+—*›.š+œ(�+ ,¤,¡+¥2¡3¢-š0£,£1ž-¡,¥+¤1 .£/¡0ž.£+¦*¤/£/ -œ.ž/Ÿ1›-ž-�,�.˜-–,”*—&“%‘-“*‹)Š)�)‡*�)ˆ(‡)‡%„(†%�&}~#}{$x#rrs$qt"l!r!hlggdf`_`[XZWUTVVrgshxmyj~m|q{rs~x‡u„w†y‹x�y‹�‹’ƒŸƒ›ƒ�†¢†�Œ›†¡Œ§Š��¨�§“«š¨‘©‘±˜¶�±˜²œ»›¸š·›Â›¿ž¹�¡Á£¾ Á¢¼¤¼¤Á¢À ÃŸÇ¢Â¡Ä¨Å¤Ã§Å£ÁŸÁ¢Ã ÀŸÃ¨Â£½ŸÀŸÄ�¾Ÿ½ž¶œ½�¶˜³œ¹›³™±œ³˜®–­“¬‘¬�©�¤�ž‰žŠ�‰Ÿˆ¢†š�“‚•�•���’}–|Œy‡w…vˆvs~p~izl{kykxjrbmemco\lak`g]oYfY`YcV\Z]UWUXVfhdkn!p#qrq$u q#s!x#x#€ {${*-†&�'†(ƒ)‰*ˆ+�'‡*Š-Ž(“+‘+�2‘-•.›)—-–*�2�/ž,Ÿ/œ-›5¡/¢.¤2¡1¢-¥-�,�0¤0£.Ÿ2£1¨5£4¢2ª0¡3¤4 2¥3¢,Ÿ. 2 2£)ž*Ÿ+™/š+™-›(™*˜)–*˜(•(”+�*�)Ž,‹.ˆ+Œ&‰)Š$…#‡'ƒ$€${(|'zu%u"s!s p!r"h%kl jhief]c_Zd]XV_XTU|dthsfwnyl}l|o�ws‡uˆzˆyˆx‹y‘}�|˜|˜›‚–„™†�ˆ›Š Š¥ˆ¦‹£Œ¨�¨�ª�­“¬“¬•´š¶š¸š³–¸›º�»œÁŸÁ¢Âœ¾ Ä¢Å¢È¥ÃŸÁŸÅ Â¦È¡Ã£Æ¦Ä¨Å¦¿¤Ã¥Â¢¾£Â¢À¢Â¡Á¥Á ¼¢²ž¿ž»›·™µ™³›³š³˜·–­›­œ©�ª�¥�¬�¥“¥�žŒŸ‡Ÿ†—‚–…�ƒ”’�Œ~ŽyŽ{Št‡vƒt…v‚n€nzm}n~lxewethjbpdpcoee`l]j[cZdZ]Y\U]VYR\Qejh knq!m"or q#v$z#u#w{$#€'|$"ƒ)‡&‰%Ž!†.ˆ$‹(�'Ž+”&’*�/”+”,–(–-˜-�,š-›,ž/ž.¢,Ÿ.¢/¡-Ÿ,¡+ž0�*ž*¢,§-¡,£.¡1¢-¡-¥,£0 1 4¨.¢1 /Ÿ/¡1 0�,ž-œ0›-˜1›/›)“/–%–&�)�-�+Ž/�&�(Œ&ˆ&‚&…'�&„$€!|(y"{{t$u"v!s!q&sno"ihhg fc`_g^\X\XUURQyjukxg�lzp}l}o}o�v‰q‡qƒu†v‹zŒy��’‚šƒ•…œ‚�ˆ›…¥‡¢‰¤Š©�¦�§�ª“²”°’²”³˜®•¸˜´˜º˜·š¼œÀŸ¶™°ž»£À¡¿žÅŸÅžÆ¢Â¦¿¥À Â¤Â¦Ä À¥È¤Á£Â¡ÆŸÅ�Ä£¿¥¿£Á�¡ğ¾–¸ ¹œ±›µ˜²™¶›°”±—©“¯”¯’¦‘«‘§‹ Ž¡‡¢…¡†—€˜~˜‚”}•}Š|“zŒx‰tƒtt‚u�qxo{ozktkteqjvhnemeagn`h\dYcZa[bZ_UWZZS]RWSffkjkpn"nqr q u!x!v'x#}#{&&�(€&„'…(‡$ƒ'ˆ(ˆ)Œ,�&Œ)‘*’*“*•,–+“.˜*š0™+ ,˜- -Ÿ/Ÿ/ /¡+¡/ž6¥3Ÿ1 1§0¥3�1¤.§2¤.£. /£2£2¡0¤/Ÿ.¦/ž0¡+�/š-›0Ÿ0š2™,š(�+—0˜&’,”'“,�%‹.�&‹*Š&Š%„(�'‚$~%|&#~"|%s w"u t p"v l"o!k hmeggfgb_][][WdSTPxgrfrewiwl|mzi}m€s‰r�tˆx‡vˆw‹w•x’z•}“~–™ˆ „›„ž…Ÿ…¢Š¨�§’ �®Ž«–©–¯˜­“®™²–º™¹Ÿºš¼ž¼¡»›¼ž¾¢ºŸÃ¡¿ ¾¤Á£½¡À Ç¦À¡Ì«Á¦Â§Ã©Â¡Ä¦È¤Æœ¾£Å¢Ä ¿¡Áž¿Ÿ¿œ¼œÀ™µ˜¸›¶˜´”¶—¶“¬�©�«�«�©�¤�¥Œ¤‹¡Š›‚–…�–}�€’}Ž}‰z†z‰t‰r„uƒu€n€p|lxivgwgrjqdtcoci^jam^f^f[_]^Y^R\W]SZRYSdgc!ilhmmqv#qt"zu v#u{"}(y"‚$ƒ$„&�$‚(‡#Š$‰)’'Š)Œ'‘+•*“,–.•.•*š-˜*—(�*�0œ,ž.œ7¢/œ2œ1 /§/£6£- 2¦-£2§+¢/ 1ž.§2ž1¥1£-¡6¢/š,¡-›/œ.›-�-›-™(™-•*�-’(“+“-�)‘*“)�%Š(‰&ˆ(†&€&ƒ'�'~$|"y!w&~$w u#r tq qlh ki!fcdaadb`][WXSUPRrfohrb}n|i|m€j€p‰v†l„r„wŠxŽvŽv“}Ž~’w“€˜~˜€š…”…›…¤‰œˆ£Ž§‹ŸŒ§‘ª‘³’«�¬”®•´›¹™¶˜µœµ›¼›·¡¼œ¿¡À§¾ž¼Ÿ¿¡Â£È¥È§ÅŸÀ¥À¡Ä¥Æ¢À Â¤½¤»žÂ¦Â¢¼ž½ ½ Á ¹˜»›¹¡¹�·œ¹™¶™³—®“¬�®•­—§“¦�¦Œž‹ Š¢ˆ …š†”~—‚“}—~‘{�{Ž~Šu†xƒq…r…qƒoƒlxkwkwmuhvgjepdp`jblbi\f`d_]V^X]TVVYQ\TYPfbfhkp!lm#nr m!v&u sw x){$}&%'|$�%�(ƒ+ƒ,�(‡%Ž&‹(Œ+‹+—.“*“+•-™'›/™-›)™0›2Ÿ,š- %£.¥/›3 / 3¢7¢2£1¡,Ÿ.ž1¦0¢0ž0¢2¢4Ÿ2¡2£.ž4ž5 -�3œ0�- ,™.—0—.™)•,”*�.‘*‘*�,Ž(Œ'‘%‰'‚)„(„&ƒ(‚"~"z'~*|#yw!t!rn"l!j"jkeg ewdad_a][[YSgTRPldqevgwixj|kƒm~m„mp„r‚p�€~tˆsŒu‹w�xŽx�|Œ}Œ„’|’~–‚’~—ƒœ‚�ƒ�‡£ˆ©Œ¢‹¥Ž¨�«“µ’­–¯˜¯š´�¹˜¾�»Ÿ½œ¿œÃ Á¡º¤Ã¡Â¤¾ Ã¢À¡ÇžÈ¤Æ¢ÊžÂŸÇ¤ÈŸÂ¡» º—¼Ÿ¸œµ—¾Ÿ¶š¹œ·›¶™´˜®�±–±’ª’©‘«�§�¦‘¤‹£‹¤‡›‡—€’—‚Œ~”{‹}�|Žy‰xŒu„r…r}qn|kzhykvgvfvgnbqbkcf^c]lZfYe[bZ]X_TYYhTaOZM_edhjj#i klq&uu t]VNLIHKDBFACGFFCLKOR U_"^%d!k%s&w(x,…)„2‰5Œ4“5”5˜0˜2—-Ÿ0ž4�3ž0¦0¥7¡1¢. 0¤0Ÿ/™(¢2š-�,—-š.œ/›+›*˜*™+š0•)“-‘-‘-�'�,‘'Œ(�)‹(‰'„%†''~&"~(~"w#x"v$s"s$rv qmnig jhdba^\[^WXUVUQNPkci^sgzgzhxe~nwlnp„r„t‚J0+!(#&!% %!%&"" % % %!$ )!-#-&,%0'2-0+5.7*;-:.<3;1?9B7F?IAWHZRZUi[sfzg�r†zˆ|ˆ„”‡¢“¡�¦‘¦“«—±•®›¶–´—ª—´›²›µ�·š¸šµœ¸™µœ«“­’¦�­Ž«“£‘¥‹¦Œ¢ŒŸˆ¥ŠŸ„›€˜�”~š€‘~‹|ŠuŽu‰tŽu‰q†qzmyq{pzkzixhvfscq_jdh_j]d]b\h\dY`X_U_[pQ\QZQTNc`bghj#lljio o o      ! " ! " +$ " '& %" +' & ( ' +'+ * *.+1 0146<CGL!T#b#d!i*r/r+x-,„3ƒ/ˆ,�/Ž+•.Ž+�+�*�&�%‘*‹/Š#Š%ˆ$…%„&„%~%€$$|$z zx!q sr"m#ƒmm njkgcdbaaaZ^YYUUSPPLshqgofscyh{jyjwj~l‚ml|p}L  #&!$(!" ("(!,(,$+&0%,#*",%*%.$2$/'.',&,(1(1'1'/'0$0$2%1%,'-&/*0+9*5+405.81:3D7H;L@NGWKaTi\kdtkxlyt‚uŒ}�~˜‚˜†•„—~“ƒ‘‚Ž€•~’~‘z‘{�}‹w‡x†t„q‚pn|j|lzgwesgtbscjZpamcl_h[eWdYbUZfZTXU[Q\RbPUIbadckhkjk!m"ls!r     + +  +!    + ! %" # " $'& &' ' ) ) * ' +*$ $ & & & - &$ ) ( * +$ &) ( %( % " " +! +&' & ) ,-69@HN#V!_"h*q(v+{&{#|$z"{&z tp suq kngg d f_`a_``YYZWVRUOLRi`mcr`tfvcwi|l~o}k|k†m‚p}T !!'##&$)#!($-$% ,$*"-$0&0#-&+'(',&+%.&1'-%*$)&-"**+&,()(.'.)-&/%,$0$.$/'+*-#0)/#("($.#+$*"& )"'("&*$!#"+%-,65@AHLUT^_njvp‚wƒp„q„q€m}m|mvmygqfqcubtascqem^i]h^bXWhVY`Z_SZRZR\N[OSed`ehfjfhl k"m%mq'         + +#   " +! +! " " " # #$ && +# # & $$ ) +% $$ +( ' +% % *# +%#! ' % # $ ' ! " % %"! +      $,7D Sq"n qkjlg"bdhcbb_^WYVXTYRNTNo`m^ldqetg|iwhskzl€k€k~m‚b*!"#""&&(!'&) % %!%( (#+$,#2%+%.$+$*%&"+%-'1!+*%-)+%,&+#.',(*$)$)",%,!+%*$/%)"%"(!*!'$*"##""# $7tq�o|q~lxkwjthrcpfxejdk_n^k_e\gZ_ZaX_U]T_XWRXNVRSNb^*gbddhgml#o!jn.#   +!  + # ! + $ $$ % ( +" "$ $ +$  +!%& # $% % %$ #! "# # $!" # ! +          f s!uj!i higdfda\]]WVXVURVRPMnbobgbsetgxgyj{ixk€p€g„l~d4*  :&=&='8"1#4$:$8%5!5#4)$!&!% )!%$)$&&#)"#$&")$&!(!*%+ &"("(#(!'"# (")!&")%)!)!'!& %!'$$"!!   5moƒp€rxkxkwfudvencqdm`kco_mYfWaYbVbV]UWRYQZT[SQQUJ_b!afcb jfhmn l$h: +  $VSQNJIEE EE G" $ % "! " !  " + ! + +! + "  +!       lonmijdfdc_ccXYYSVURVRLNIp\idtbtcrcu`zhvgyk~i€klwdC0&8$<=#<$8#9#>(9%8!# ;›uÉrÉuÌnËnÎqËnËsÆkÈpÁaD%':A<><@87:6=7:44303,/1&%$!#!& ! "$ "#,)(( (%$     Ktl~mxm|iyhviufogmalag_i\lWh]e\_ZcY^W^QfW`QULURSMVJ`cc`eceh hl!okjE +  " $#%$ $ &$&% iostwqsuxvx.E#K$IIGLIJ JF F$  // +0 * +0 +,))) +& +% + 8--*($%    h"i!llg fik)haa[_\\Z#`VSVQPPJNpbqaparbrbzdzf{kyl~l~nxn|hQ  5!5!6#9#:$7#;!:&<&:""2‘rÈnÖsÌrÖnÛvÙtÙyÝuß}álK(0IJKKIJEMJJLKIGGLLKJJIC'#-7:;5998:89768-8365414+&DeUmMgOfJcKcGYDS>V?Q:A A4E1800(*$ !(#Xup�jmujyfqvlewdpbp_p\k]x`k\aWc[eW^Y_U\PXRXRVISLPJ\_bdacfjjl"mneQ +   "  ""$# %%"& bonooputz{x2E$L!M J J"H I!NK#M K# 5 7 ; +79 +6 ;97 2 9(&[$V(U(Z'W$X+^)Q'T!U!I @)|$x!ne f]VF< 4  0lookgg ke da`_`\%bWXVRORQOOMr^mhkbscrgpexfvdzn{i‚kzg‚gY$  2 6"7#:#<#5";$;&>$B%')‰pÈoÇmÐtØrßvÞvÙx×vàwálN")EHJKQKJJIKGJJMLPJMJOJA# +89;;?:=8;::69;677677:) .JqUzW{WtVyU{SmTnXjUpRZ#;€[†_†X~V|W€T{UvNwKjIO >b|lo{kzhwgxguds`penck^l`jZcZcYfWcU[UXTYPWQWLYJXMQIU_!_`agifgn#lkj W +   ! +"$# + "' +& + Xoq stuwsqyv5BK"KJIH!PK!P$SK"! 6 +7: 8 9: 7 77 7 4-$T*W%W%W$U'U$U T#Q$P"D + Y'‡(…'„'ƒ'&�'}%x)z'{ + +F#pml$hgkbcaa^^]W]YWSSU JMNJJo\r^o`pgsfugxfshwmwh}k}lzjh, 4"7$8"9$9 @"B%9%;&9&/{nÌsÍqÍpÒt×qÕuÖvÝxàuÜsZ'GKHJJJMNKJJKLKDNMPLRJ=# -86787777<897779<67746 4Tt[[yUsUvSwRoTtRsToUQ$I„W…Y…Z‰qŠ\~S~T}R|T|OF  Vetnwozg}iyirhpdmci`q\k_k\eYbXaWbWbVfTmQ^PYMXPTLPMSHX[acec#cfg h giib  "#$ +# %"##  +Spnttqrs|wu8BK$K"KJ#M L!J#M J!M  +6 7 +7 7 7 6 : : 86 0 7&]$W#S#V#U$U,c$T#N"R!7q+‰(ƒ+‡)†'~''~$}(}!s  ] jiikjg f``a^^XX ZXWT!USPSILImXm^ncjan`sgxfxdunzg‡g|l~iu:  +!3 83%15!9$3"="9&.hkÃp×qÚpÖrÓrÙsÞvÛuávØud#EEDHJHJKHNIHJJNLKLLPI=" -77688;868978979685971BWvYxWwVvVuVkUlVqToSuN;.V‡Z‰^‚W…VXƒS€SQzR|J/ +0df}jzkvj{hweyfmasbnan^l`l]k[bWaX`W^S]TgT]SUQVLVLUFOJYZb^bdgbjji!lg!b "%! !" "# ! Eqrrvotstx"y@ +BFI$IJNL LJ"M#K 69 < : 6 9 <4 65 . <'T#V,X%T$W"T#R%O&S$T* �*…'„*‡%‚'„'‚%€$z'x"g b$hkke"lgdc`^_[[XXVWTSS`NIHKf]lat]rrkeqdvbtezdugyiwovluF '7#8$7"7%9$<&=$=&5%7RmÃqÓpÉsÕrÔmÒuÖyÚvÝyÛ{m!AI@FHHKLGMIKKHMKLNJMH9 -6;;8:95287688:967830,LY~VyV}WzYyR…WsPmTmUnH.K\‡\ˆZ‡X‚Y~U�R�U}SxPvB  Ksg~m€nzjyh{eqrtex_t^k\i_fVhZbW`^bWbQcQ_S`SYNWNWPSMQM\_\dbhcdjifh*qg   $ "! '$!($4"trrqnr!twxzH ="H!H"JL!L!H!KMO!K  9 : :7 5 74 7 4 4 +G'X$T'[#T$R#Q#Q'R#V#M"+‡(†)„*„(‚&€$}&{$u#T  !h$ljkhgcb^a_^^XWS[SR#RQMPKKJi[o]iZk_nbueudxdvjyjuj{lxhvW   !/4$8$5!6$5%7 9$>$9=e½kÍnÎsÖsØrÚsÝuÜrätàxr>FGGEIKIEKFHIKJKJIJIC9!.7534<897398693469571*SW~T{Zx_wWoWrQpSpUqQiC"\[…`€Z…U€[~OS}TzPyOr, +\uh|j�hxhxgyhseo_q`i_j]ieh[gVdU^U^U]U^NiO]RVOTHOJPIRG]_^^cbb efgg"l ih" !  "!!#$ )qmqppsou tzN<E I!KH!K LM M%MI6 +3 7 7 5 +8 2 +3 2 2 +$M*S&U&[#[!U$U QN"QM"'„)„+†&„'�(€'z)|$|&w 5 + :hkgf chfdl_f`[^ZYSTPQMOKIJKiYk\j[giharewc~iugsfsgwhyeua)   1 9 55#6#7$7#7":"42_¸mÍmÑq×mÔp×tÙrÛuàtãx‚?IHGGIEJGKLFIIFIKKJIF80748984779=:864979436' _XtWqTrZyStSsSwPvPqQd= #uTƒZ‡Z‰W…SU|Q|R~P}Pe + Biyh~hzkviyfserbrbnbn[lbiYe\h[dW]VbSYPWNZRYOSOUKTKPGOI[XXa!^`ffefhgf"g0 #"% +"#%  +! nnmptsrwvyS :IIH"G!J#LH J#L G4 7 +9 2 +8 8 +8 +6 8 +2#N(Y&T$W,X%O(T&P%T$T%S1%†(ƒ%‚%€(€(({#y$|%s"  Pgikhgfb]b]]bY^WUXSPQNJLHGEj]l\o[iap^ofxdvdsftg{fhykx`9 2 54 :"5!3#5"6"4#;#Q³kÎnÒmÐoÔrÖsÙtÜpÜuãu“9H?GEKFKGHIGHFFIIMNLE3.9166:6756557;6825761,c[xUpRrYqSpSsSpQnPmSd%-zZ„\†UY‚U}W~S{QzTwLS + "[hvg|hkzjx`rdrcrco`n`jYmYbZaXfT_SZS\S^QSOTLTLSNTGkDMC[ \Z_^^_dagfml!h#@    " $ !#% %ykmplppxrz[ 8FF"G!IF F IFHH7 4 7 +93 3 235 5 Q(Z(U!S&Z"R$STP&Q&E b&‚*†'ˆ&|({)x$z%t%v$u \k gkgfecbca]^SXUWVQORMLKENDaZeYi\afoarat_scparhtdwlykubP + ..!765 4"9 4":$= I®iÍnÒoÒoÞqÚo×pÞzßuàxš4EDDHGFKEH?DBIGFIJHGF1!-66738487678444558441!5nZwWz`rQtPlQlSpPkNuKT<„X„W„UƒN~UxQzQxRwNuIA +   Rmfwiyj{gqewes`q]v^o_l`iZfd^SaVcZ`P]PXQZTYMTKUIRHUI^GQFY[X\^eb i`fe d!ihZ +  + ! [ egk inlpqpg +,H AEHEIF!EFE 77 5 +22 3 2 +3 4 5#Q'WTS&S"O&P$P)P!P - o&ˆ+�$ƒ%‚"}+…$|%v"u$V &fm lfffb^_]]j\WYYTUQNOKJJJLFd[jWj]n^gYmas^iaqaucxdzd€lvdi4  +  ! 7+S1b9e:p>uJ‰KŒR˜V¤V‡+CFGHHF3/45:6756654233344032( EjYyTwTsTuRpTsMqQlMqNV 8V‰T‚[TƒWƒRWzNwPvNs2 6bƒd{j}hvjvesdvbrcp`iZoacZgWdXeVbU\S]R[NWLXKZNYMRJRJXDMGSX\]\^_dbffdki]    +  +     + +    +   $%* +/064:  1 3. 1 0 3 0 . 1 . +R%V%W%S"W(P&M%N$R%K!w+ƒ%y"}'€*�%}({#y(v#7  ;ighh!hbab__[[XWXXW PSNOMOJGIDfVc_dXj]j]nao\p`odvexbzixh~itE 2-)#!     +       !%!&& ' /A7L=S=[?]ER?[BYGaE\<% +KNzSxUvV|V{QxWvNoNvLf  Mb{exh}fzguex`u_kZkdh^i\iZdn\WdU`VYZXSVP_OWLYQTKOJSGQGLDZX[U[[^b`eehhc`  1A <A;=85 7 +7( +  +                + +   + .:@IOOU"Y'[&^ + Thefgeda]ba^bY[V%UTSNRMJNHGGG_[gXiYjZgZk]kcmcqarctexk~a}jsT MQµO¼P¸U½S¸U¶UÂS¼TÂX… '% !#"!! " +#+f(^ WPE7741(     +    +         + + .\dri|izg{`sdq`qal]gZj]h^`YjWcWfW\X[V^QZOZMVPSJOHQMPINFLEf WW[]X^]baacffd%  0P R W V _ T X +W +ZO ++'+$(,+%+* B>89<< 9 3 6 2 +  .$ "     +     + bi!iead_b__`^XYURT_TPLLKKHHFF\TgWeVh\e\l]m_jaoapcsatgxexc}Z. GN²R¹K½TÆUÊRÊWÐZÏUÎW¤" &'*%)('"'&'&$))+*-*) 1FÈAÓBØCØ@ÙBÕAÖEÖAÓ@¼# .($"#&'!%"  @ustrniic`d^]Z_YSTQOI% &7e8[4S,J&C#:#4 5(% + @lhxgpvqcwew^qbs`q_h]icfWbV`UcX_S`R_RZP\OWITHRMSGOFOGOCF=S[TYY_\`b`b c!fec4 % Q ORR SQ Z S ^ +S +)'()'%(*+& + A@@ ?D FBAC >    +   +]™�‘ŽŠ‹ˆƒ‚z <v r m c b[X U QD + ad!edbdac_]["`TSNVRQRQNJNIEDHDaVdZd\gZhXg^l^m`r`nctdocrdzdz[> + +,H±N¾PÅRÂRÆQÄTÈWÇ[È[·( #!"%)''"*#*(*&())%(* 3FÆ?ÏBÓA×AâEÖ=ØCßFÙBÁ" *.-(%,/+,&d”““�“Ž’Š“‡Ž‹�‡��ŒƒŒy5h|Ü|á|Ùv×vÓyÈ}¿rÊpÄoŒ "Tkongtgtbsfuftap]uah^fYfWgUhT_R^S\RZOZRSKULVKVFOFKHMENDIERUVXXY__^_eboheF  UP V P S T U TU +X $)&*()))++@@@BE=?@DC +       + n“—““�‘Ž‹‹o + `|x xyxs s p o P  *"cef"j!ce^b[i_XZ^TUSONKJIKGHED@hYiSfRfZgZgZkam]o\sbqavdnhtcraQ  ?žR¹P¼N¿SÆRÈQÄVÇTÍTÄ7 %!*#'*&!)&&&)$'$)$+)  +);ÁBÝAÙAÚBÙ=Õ?ÜCÔCÝC¼.+//-.-)1$ "p”’˜�–Ž’‰’Œ’Ž��‹…‹„…g †}Ý|èwÚwàyÖxÐsÏsÕoÍji ;_pexeyexkxcrbm_o^k^o\n\jYaXqQ`S_UaS`MrWbLXJYKQLKKMIMHRBJEUWTYVZ[Y]bc'da`dW  R Q M +N Q W U T ZU$$%%&*+*,* C@>C<@BD>=        +   y˜••“ŽŒ�‹Š\n~z w w t s pt n 1  Bfga eda]^^YXVWWWTNSPKJIJEHDB?aTaUeUfZiXj^i\f_qbq`rdrbubu`ybb- + .�O·MÀPÁPÄRÀUÉWÌcÁ]ÆB"$&%('&$($%'+'*%)'*(!'1½>Ô?ÕC×<ÛGÕAÜAß@ÙCº .,+-/+',' 2{•’”�–Œ–�’ŽŽŒŒ‰�†‡‡„U $£}â{ãtãqâwÚrËnÒpÄmÆbG T`uascwcwbuhu^p[o`m\eWe]jWeYdS[S`P[OQPWOYKXLTDRHOFPHOFKCJFTTUU\[[^^cedhb%bV   MQ P Q U M U +T X Y + %($('%)),) E@@ ? F>DC ?=          …™—•’Ž‹ˆŽˆG }{xwxv vs {m + U`ecfdc\]]Y^\UVRUMaJKJKGCHGBAfQgT_TeYeVgec]f^m]per_vbxjs`qcl; |P¶O¶QÁSÃT¼RÇTÐUÇXÅO3 &&'&%'%($)((')''&(,# "7ºBÓ9×BÚAØ@ß?ÚCÜAÚBª*&)+),+-' C„”Ž˜”��•��ŒŒ…ކބ‰ˆ{; O¶}àyávãuâxÕsÊrÌlÂu½J* 1abvhygxfpalaq\j[dYoZiZf[c[bU_X`U[N^MRPcP^LRHRKUHLGPEODGAHASRUSV[`]__^%dec`_  @ MP +Q VQ U X T U  !(')&&' (*+E?@ ?A@?C C <   +        +‹“”””Ž��ˆŠ,x{ +| w q r o r n l  \dfddc_aXYX\ZUXT^NNPDKGIIDEAA]OdQeYcYjXgXiXe\n]o^nkndshv_vesK + aP·O½NºR¼R¿R¾V¾TÌVÇTJ + "&$#%&$'#("%*'(&)%(! 9¼AÑ?ÙEÓ>Ù?Ù@ÖDÖ>áA¦.)))-/+.,QޓЖ�ŽŠ��ކ‡ˆŽŠ‹ˆ†ƒl$ 'dÊ|áw×{×rÙsÕrØpÑoÉm¯. +Hl`zfrcsarcsdp^q_mZgZdWd[dXhVbR_P\Ne[oMXIWHPEQHNFMHPEKDG@JBOSUWVYZ[\\__u b!b a +5N P OM O Q +X T +R , &%%'!'%*(('I=?ABB;@<7  + +     ‹�•�•Š�‡‹„ *|| xut +u u ps ]  aad!cb `^l]^Y\UXQRRSLIIGDHECCD=\Oj[nPgVdXbVd[i\n[q[n^ubl`pbtbuX+  HO®NºP¼O»OÁSÀTÇWÄQÅSe +%!%'&'&"+#'$(%)$'%& 7±CÉ@Ú?Ò=Ð@×@Ö@Ñ@Ú@¥ +&*-*-&+( a…�‡�Š�ˆ�Š‹ƒ�……ˆ††Š€W +>pÍzÞyÛwÔxËtÔrÖrÍm¸p� + +Yeescubseobn_l_o_lXgZd]hYeUdU`S_P[OVLWORKPHUJTHODOAIDK>GBE>SNMSYZY[[^` `^!dad5 + &OL NO MV +R N U ; ")'()&')(C@@AA@AA?;   +    �‘•‘‘�Œ‡ˆ~ + C |uus v pl lG  +:_c g^d^]\]XZYVVMONQNFIKFGBAC?AYP[O\PcYdVeXhXe\lXl\pZuaubt_v`uZ? .I¨LºL¾M¿O¶O½SÄRÃTÇQ| !#$)$'#''+$'%)%()'$$ 0­=ÓCÖ>Ï@Ô<Ñ?×E×=ÔB¥ +)%(+'*,% #p‡‘‰‘Ž�Š�Š�‰�†‹ƒ†€…y9_yÚ€ÙwÓt×xÑvÌsÏqÉoÄj` E[pdvd{dubsbpfo\k\i^dXbWfUgU`TaQ_P\OULULQGUHVHQIQFOCLEH?IBGBOTSQXVY[]X^^c^baD  M QNO e P R T V +A%&#&'%&&)C >@ 9@ > A?@3 +    +    +Ž�‘‹ŒŒ‰„ˆw +Ux z r t s +r +p +nm -  + ^e_ae]a`][\X\UPRPQUNJMJIECBA?C\MaSaXaUcVbUdZg[m]k]mcn\u`obvbzaT + + 8�L§K®KªLµN·PµTÁS¾Wˆ +$#'!##'#%#$&'%'!+'' .ªAÈ?Ë=Ö>Õ>ÇAÓAÕ:Ë@� (**,.,-(&*|Œ’Œ�‰‘‹‡ˆ‹„Œ€ƒ……{ƒr) |{ÙsÛwÔv×rÐuÍnËnÀk»[> + )\`pexeu^n`o\oZpYj\j\dZeVuP_V\Q`N[RXMUPXOUITJOJQCIHOCE@JAF?I@MRSTUTZ\\^e!_ca^bU  #' +,)/ +5)< >:##!#"$%' F<@6? ><C?2  +  +  + 3�ŒŽŽ‡„Š…† d +iw s +t u q pn +m f Y ige_e]`[_Y VWRQTQNKMJFFGGD>A?>[ObQ`P^RbUfYdZf_mYm`m]m^p`naqar^_*     +! !! b0„5™7­0«:¸7¶9¸;½;� (++*+*')# 9�‡�‹Œ‡ˆƒ‡……„†‹‡……„�W3“{×sÒrÏtÐpÊrËpÊoÆg´D! +Accneub{bsbr_jbi[iYk\kWbWbYbSaO`R^PZMRKTJULXJPHLJODJC?FC@IRN[NZP^R]UgV\WfWhTk[k_t\n_t]o`s`d; +    + +   +  +          + +       + *+/.0256897;;B@?( *fJ�L�Q–QœU VšSŸW¢]†! "Ojbxdoctam^n_g_k[jXcWfV`TYP_PcTcO[MWNWOUISH\HQBLGPCIDG?D?D<@>JLPORWSZYZ]^[]`]_    +    +  7 77 33 1. / -    !   +   +   +  +   +  " +2Zc`d^b]\[YZTQSPNNOMOJFHCCE@?><VOWO\Q`QcShN^Q_eaWkUe_d]lWoak_kt_I  +   7+G/D)C&F)H+D-G)E1G `'�$’$Ž#�"… �~{P "t�ª|¦n•jŒc†[zVsRoQ[ !<5-'##    + +  + + 8VeZsgs`s`r_n`p\mZhYcYdWbPeWfQ\PbTcK\QZJVKTFPFOGSBMEI@L@C@D=G9LONOOVOWXXW[ZZ^^`$ +      ? FE H D FMKI2 + +%''( +& %+"  Ÿ¶¶¹´´°¨©› + ,810 -+ ,')& +!   + + +   C'dcb]^][XYVWTUTLNFMKFKJGFAD@?>>YL[PaRdK`QqP_ViQhViVdXi\lZl^s^q^mX, +     2%D%B*I+F*B,M1I*E0I o+ )¢%¦'¨%«'ª'®'©%v 9ƾñ¹ò¾õ¼ñ½ô·ô¹ð¾ñ´Õ9UC®;´8²7®7¢6¦6­6ž8”) ,87411-..& P_h`kct]o]o]l[m[nUjWfZ\ScS_P^RULWNQHYLZHUJRIQKOJKDLCJBJ=E?E?C;OLNTOQRUWYUWX]^]a4  +     +A @ F JH KHMM 7 ) (% ( * +&"'&  ¤¹¿Á¸¹´ººž + 6?;99=>:69 + 9>:789576 +T`d`\]^][XWaVQTNOMNOHJFEFC;>? :@ ]M^MXNeM\R`Q_WcTeRdVcYmXiXh\l^kjbYB + +      .+A(G-I/J)H,J.G,I*I'n*¨&£&©'«(¤%§+«$¬$s @̾ì¶ô»óºí³ó·ô¼ñ¸ñ¶Ê(j@²7¶:²:²:³:­:¬7®8˜ 59=!999":$5!7,   5\]hanck]r^p]n[jWg\iXgW[X_R\T\O[QZMYMSKWGVHODMDKBHFE>K@F;H?A=F9JKKMVPURRVY\V[]_]E    +  @DG J FH KH I6( #&&$ & $ +'( §Âº·²¸½¼½� +;755775571 )::8747344  \]a`^XZZXZTSVOLLJOLDFGBG C@A?<;= [HWKTMaO\QaSaVbWdUgZbZeYk]m[n^k^pZV +     #)E'C.H.G+H/F,K,J+J, g' %£(¥%¥)«(¥%©$§'jEѹõ»ó½ò·ó´ò·ñ¶óµö±¯y=º9´5°8±4®3¨5ª6©6~::;8354"53 Kd^l]m]oan_jZkZl]hXgVfUXU_T]N[ShOVMZG_ESFPIOEMBLEOBF@I?CD;A?D;>6IINNNLLRSVVYX\[`]W      ; AC D E E CFG ; $ +% %%($ % % $­±µµ¸±³³®e B69895744  4<;893466#  +@]]^^Z]ZUXTVQOPMNLNIGFH@C@==@ ;:7 WHYIYM^L^P\NYOaV`SfTeXa^n]iYe[m]n\gD  +     (C-D,C,D-D*G*D.H*F& W'Ÿ$ž$ %ž$§'¥&¦ Ÿ'dK϶ñ¹ôªó°ô±ô°ô­ô®ô©z(“8°7¯6¬8±5®7§4ª5¢3N % 956875630 N[m\gZkak^nYkXcTbUfW_b^T]S^P`N_N^KXIZMNJRESAR?MAJ@I>GBF:8736325 655747321 QY[[[\[]UXSUNQPLPHNHIGCBA<A?==6= \NYHWKZJZKZPWR_PfWjQeYaUcXfTkVm[nZjO!     -A,A.C-G)G/D'C+G/F* +T(¢$œ#œ&š"˜$¥%ž'¢&] Tϳò±ò±ò²ó²ñ®ó®ó¬ò¢a-•7®9°:¬8¬5«5¦3¢5”/6, 7; 969825-  ,VXlYo[o^n^cchXgWb[YZcO_P[P[PUMYJ_HUJWLVDOEJCMDFBG@I>E:E;I=A9?<:9HIGQMPOLNMU\UZSYVZ)      ,?ADE >>G F? !((#''$ +# +§±¯´¨±­«¬;=9;283446954574532 UY_[[\ZZTRQTRNLLKMKEBEC?C?>:<= :9QFWNRKVKYNXN\RsNcMePeUeScVfWcYi[jZiT5  +  +  '<*B(C)C*E1?)D(C-F) J)›"œ#œ&�'¡&Ÿ!›%˜%T WÖ°ñ¯ô¯õ¯ò­ô¬ô¬ò¬ñ–G 4›8¬7§3ª2¤5�3¦3¡2™'!2 73877414! + A]YeXh]k[hVkWfZaUaTbT^OaRZPZMWJXKSIQHRJRGNHPCJBGBICF@D;D6?8=6IHHRMPNPNPSTWWWZYX:     + +     %> @ ;BCD B E?  $!# " +$!$#§¬¬®¬¯«ª¨)<26762543 6945610.1  !YZY[XYWUQURTNOQNLJJCDBCCA@>< ;969\ISIRLTLZKUJYPaP]S^QcS_W_UiUkWjWgZgYH  +       */$0(8&7%9'6%:)=+! + :*�$‘!Š#�"“(’%˜$“$T WÎ¥î¡ó¦ô¤ï§õªô§ô¦ð‰2 + 7š6¬3¨5¨6©1§4�5 6‹ +4 6!6"023510 + -RcZnWn[nWcYhWeYhQ^S`P\Q[O\OVPUOTNVIVONFODSCl:OBHCK?E?E;E:E:@9<6?8GJILJLMPNUNSQV[YY[H      +  +        +lw ‚"…%‰%�!”—”:47664334 $76252122%  9V_Z ZYTVVTSOQMQOLGDGJJFC==A>8?863LGPFSHRKTNYJXO[OZO`OaT_R_UcVkWiViXjYS% *KEL?B757440./.--+ +!    + +  +   )/57#:,C1N2Y0Q"] f$m%k)w(},�(k0-10/12,) + +EV_^g[iYf[eXeSg_jW\R_R[M[O_LWJXJ[JUAYKQEMGS@M@A=B>G@D;D=A8??:98 7PBTDRDUHWIUJXL[N]L_UaR`QhVcTdYfZbWhWc5 PÌÂéÄëÈíÆíÄìÏîËðÐí³I 0q Š§‰ ˆ²Š­Š§�­Ž«’—Q@\fVjRkVdU_T^O^P\L4 ('0#+ ( )&!   +   +   +   + + +  'WSgVjZfUlXlXeSdSaRbO_QbQ]N[JZJYJWGMFRERFMCMCNAJ@K?F8H6CF>@>F8?;>:=5=7=7:4HDAKJGLIPPQRRSTUSZV"  Œ7Â6Ã8Ë;É@Ë@Ë;Ë>Õ:h$Ž+’,•-–-˜.œ.�*˜-–@c%g df ggi"e> +75 4797:75  +          +UXYZYRRUMNPNOJHKFEEAEB>><<>995 5 47 SDMDSDVJZJWLYJZN\O^N\P\S~OhU`VgQfYkVbO0 ”»êÅîÄìÄïÇíÑñÍïÐîÊyb¥“³“²“±˜º–º”½™µ˜´jK`ud{gyfwdsfsa|f}_E&98?7A9B8B9H9D;=5; !  + + +  +  $K^[iWnZeVjUdRcP[S[M[YNL^IZJVGTJWJPIQFJGIALAPAJ>D@?5?4:794G>EEDJHKOKOOSORSaUR8 + + i3À9»:È8Ä>Ë9Í:Í;Í=„Ž,�$’+–.™.™)—-˜-—;cgcid `!d d!=:9576: 753   + +  + +     4TW[XWRQQPPNWJJIJFEEC@=>@<>89<5640 KCODUFSFTKUJVJULWH[L^LYLcP_R_RbS_UbRiSE ^¬à¿åÁêÄëÇîÈíËïÇôÅ™Qž�¬’°—²’¹™¶–¾š¸–¯h@Zwvdcu`{dq`sioezaC(>5?5B4@5B8@4>7B5; !   + +  ;SbVhXjXcTbV[X[SaP]QcP`NdHSGVKRJQILDLCLCLBJBE?@>H>F=<6E8@;>5>7?5=670FDCHDJHJLILMOMRSXPRH + +94¾<¿6À7Ä3Ê=Ã:ÄCÎ;• +†.�,™-”.—.˜,š,—.’8cg#`]dk+d`4666986981  +         +     GSVVUWXRMPRJKJKGFEGCB>?;=<6:9975 72QAOEPEQIQHRJRIWHXLVNWP\OsL`SdR`S^SfSfRT% + +>—àºêÀçÃî½òÅîÇðÊó˯0<—Ь“«“°—¶–¼–¸—¯—¯n6[nbv_kbr]sgud{hqb= .>2D6;9D3D3B5>5>72 !    + +  + 'NT_TbReXbO^S`Q_P_T^Q[MZLZHTJSGQHMEKDKBLEGAJ=J=B=F=>=?9@:?8<7<7<6<4<4ADAEIBHEGJLMOLVQRUOM   '³5½9Â8Ä3Â:¾8Ä>É<¦ +y,’)‘-‘)“,”.•,”*� +3!adb_]bcf1725 94 35 6% +   +   + +  + +  + + PRTSUSRLPMMMQEIEH?ADA>=><797 887 5 4 1 IGIAGANGTDPKTHOKWGVNUMVI^O`NaPgLcTbT^OY4 $hεé¼å½ì¾îÀðÃðÃòÅÉH-†ƒ¦Š¦Žª‘­Ž®Ž±’²‘¥t 6Us^ndwcw`s`sbp\q[7 -?4C3B7A5>5>3>7@3-  + + + + + + >\RfXbXbU`V_PXR[O]NWO\KXLhGYFOGMFNFNENBJAI@HAI=I:A6@8E5A8C8@5>5:3G@?DHCKIHFILQNKP!KTSQ ¨3µ3·7¸7¼6¿9¿=Ä;±l&‡(„&Š+Š)�-‘)‘)Š"$,\__Z`aY`. 65 3 635, 2#    + +       + +OSTRQPXPOKMFKJECEGDAC@=<88;87 3 8 44.S?S@JBLEPDQFRFRJRHQLXJTLTMXN_NdOiS^R_S\C AÁ°ß²Ü®å·ì¿è»é¿ëÁÕ\{†¥‹¦‡¡‡Ÿ‡¬�®Œ­ˆªq&2QgXj[mZn[jYj]obqT,*;3=1<2<0>0=2>280(  +   + + + + 'J]RaQ_QbXxO^O^N]LXRUK]JSFNIQFOJQCMAMAKF;D:D5E7@8A9?6;5<3=/;5828.>J>DFBCHJGLNLOPKMRPM!  �5£1¯6±2º5·3·7·9µ +`%„+ƒ(†'‚)„&‡(Š!„!$)UXT][]WY)340/2. 01!         + +   + .SPOSPLQJIJLFDAHDDD>A><<:3 7=9635 1, 2 J?S@J@QBRGREPESBQIVJTLXKWMYOYJ\L_McN_Q^H*  $b_…i–z•|¨„®Š´�¾”¹\Tj�u“w—{“y–}›–€œm- *JaXdVeThSiYi\iXgM.$:08/91;29/80639-#  + + + + +   + + =Q\OaO^PZN`OWP[J\LYDTJTIPHTFPHPDODODN?ICF@I@D>A:@9G:>:>7<795949281705.;?BCCDEGILHIKMIMJLNN0    +' #$(+2. *18;;BBE2978:BDD'+ *,.+0.    + +   +     AUOONQKOJGFIHJDDD@?><=::9 : 85566 2 4 3 0 J>NBJBM@NDN@KFQEPFQHSKVIUJXIYNeSiM^M`R]I?  *'%      "! +!$%  + +   + + + +$JKVM[Q]OYLZNYP\IZHXGUJSFRGRGPENAH?JCI=F?8A5>8@6=8:2;282:54/21;<A>=ECGIHGJJNGKKRRM>   ! &                   +       +   +      +    + + +     + JOONPHNNKMJGIDFEC??>@?:;8397522 2/ 1 -C9FAL=H=MDJBRAPCSHVIQKQFSLVJZJVM\NZL_MZKI$ +  +!,%$        +     $!$"    +          +  + +  6SNYNYK\P]NVNYNVJRGUJPFOAOCMGR=MDF?E>FAF=F;H;A7=;B8>6=6;5:27182509-3.7.><=BBBDCMFHIGJKKLNLMJ       +             +      + +    +   KMNMPSPGKIJDFAB<@@=<9 :<787 +595 221 / /- D;G;J@M@MBKAMCKCRDSFOGPITHSHUJYI\M[O^N_MW5$!"!!$ %! !!       + +   +      ! + + + + CXN^JYO]NXLZMWGXGRDNCUJPCSDL@N?QAO@F9=>@C@CADGDJFJHKLMNGB:><;>?:> ;;: 9:7754 44 3 +. )( ) & +& & +             + +      +   4KKNLJJIHIBHDC@?BB@=8=8888755 4 510 //)C=B:D=I>H?MBRDPDLANDSITFRHTHUJTLYLYHTO\JUIVENGRBPCTDTGRCPHVGUHUDSGOJRHWGZFXKTLUMTKVHWJTEUGREUFQFXHNFJ@IBF=A3GLJMKIJFJGDEEEDAAA@:><; 97 58 5703 10 /+ - , H8C;B>F=L@IANDPANCNCSENEOHTJUIWL[IWLZMVM]N]MXJYJTKTJ^LdOfKYI[JXKZLWMXJ[J[OXKYO`P^O[J\P\NfQcNeNaMaR_M]KcNbL[N[MWQaHaIZOTK]HYM]JSN[H\ITJWKYHTHQ=K>E:D?>86.7-0(1'+"%&#+BQHYG]JYNVKVJSHTKUIQGQBQHJHOBIAMCMBL?I;C=F>C;A6?9A6<5A6;8;4:0:55150713.5+5-:=@<@@GCEF?CHGKHGIHMNMQSPNKOOQNORRPRQRSRQQRO!VSPTOUOOQPSNOOMMQOLLOLMNLLFGJHGDE@@@@@@JFENJJFLFCGFFA@D?@@<= ;9789444 2 0 42 * 0, , DTALHPHQJXIXHTFWGUL`IXI\L]R[L\PdXyNaObMbScTpVeP`QaSaTaS`OaWeQgVdQbRgVpQfShRfT`QfRfSaWeQaSsOeRpPfNcSeUhScQ_QeR]P_P]U_Q`L^M]O`NWO\IXJWGTGSISGSERKOGRDTIVIUGTJZIVJSEWHSBQFRARCJDI=KDLBJ>H=H=G;C8=4=49684726.7/6-3/1,-.0'?<<>??=>DDFADHIDHGEVKIVSRQOOQTRYPRQUTVPROUUTTTTURTVQUPXSQRTRSTUQSRKTPPOTOQRPMNILKNGHHHIEFDBE@ADC@<A?@;9:68:56 6341/0 . 0. ,,G;F9ETAKAI@F@K=J@J>I;E7C=B8@5?6>6>3,6:37082833.4/7.3+0*0)698;=<>>?@E@CHEHDIIFS%®5Ì5Ö0Ò2Ø0Ô1Ö*Ð#Á%º&¹'¶&­"£�~wpogVUQTSTQRORRQOQNKSPPPORPPPQPUSNQKPMKMKHLIMGGHHFGDEED?F?C?=>;@; :: 7575535 1 2 2 0 + + - +* , +@8D:G:C=CF@IAKD9?:@6@5=7;8=5;6719180502.6,1*3).*,-**:77;:=??@BABDDECEGFV0Ê8Ü,Õ1Ý0ã3ä1â1æ1ê4ã8é6î5ï7ñ8ò8ì2ä2ê6é2Ý,Ô/Ê,Æ.Ë1Ò)Ä(¾(¿%½%·*­—‰ˆ�|ul�`k`\\ZUSVSRTRSPPKLNLLLJKEEFHGDAADCA@?@:><=9: 5677 454/. 2 + .,- , +*'A:C4H>E>E;JAG;I>K?J?MBLCLFNBPGOEQFUIU\«ÍíØðÖòÜôåòåïáõéóîñîîèóðóïòðóóóìîâðáñæñÜòÛó×ðÕò×òÕïÑòÐõÓóÑñÙôÔôÄô¸ù¿õ½ôµë´ë¸é³ä¨Ü§Û°Þ®Þ©×§×¢Ð�˺ƒ§|ªƒ¨�¬ˆœ‰”q~`q[pZlTmRiSYHVGvGZGQGSBO@PBNDMEKEKBO?H>H?J?G?J=G>F;D;A6C8@8A8>9?8=5:581;091501-2*/*/..*/).%:58< 9?<==?BCC@ECCFk0È3Ó/Ò-Ý1à5á3á.é6ë3ï5ê3í3ñ:ñ8ñ7ë-Ü0á-Ü/ß2ã+à0â-á.Þ+Ò-Ø,Õ-Û'Õ'Ù/Õ(Ï'Ë%Ê%È'Ê#Æ)È(Å'Ã)Ç%Ï,Ô)Õ,Ü.Ñ,Ë.Ó*É)Ê7é7é5æ7æ5Ï,¿/Â1¹&¤£VZQIFHAGBHFDA?A?:>??87/7866 33 3 0 2 ,/ . + +-+) ) =9?:C8B9D;B=F@D>JC8@;D:A5B7>6@6@293;4;39381;05.5+/,.*1-/).%-&9768:=@<<?;BADFBC{6Î0Ó-Ô0Ú3Ý0Ý0Ý4ã2á/Ú2ã2æ1ç3ê/í3î.Ö+Ù0Ü/ß/Û-Û,æ.ß1æ,â*Û,Ú-ß1ß+Ð,Ý,Ý+Ü)Ö(Ø'Ø'Ö)Û-â/Þ-Ü,Ù-ã1á.Ý-à.Þ(Ú*Ü*Ú(Ò1ï8ò5ð1î,í1î1í0é/ë3å0Íy3ÀGFDDCF@A@?@==8;;8:6 88 666 2 33. 0 + .-. ) ,))@5C;@8?9C7K:A9C=JBI>O?KBODNCMDOEj�ÕÐñÌñÓòÓôÜñÚòàñãóçîÜóàóèóâóçðæòðòÛðÐñÓðãñÚóÝóßðÝðÙñÜñÞñÛòàñÝòÝñÙðàòßñßñßöèó×ðàñäóãóÚöáóÛñàòÝòÛóÚóßîâñßñÔðÑøðòòóñòìðíóçíàîèôæñæóε~Ý™eIRCRFOCK@I@K=K@KAJ?DALAF=E:D:B9B8D5?9B9<7@2=38374:3B;DI ˜8Ö+Í/Ñ5Õ.Ú/ß.Ú0Ú1ä.Ù4â2ä2â.å.ä.æ3â/Õ&Ö)Ö*Þ.ß-Ý%Ö'Ó+Ö.é(Ú-Û2Ý3â$Þ)Û1ç2Ý4Û-Þ.å.Ø.Ú,Þ*æ*Û*Ú+Ü*â)Ö'Ò(Ñ1à*ß.Û,Õ(ß3ò3ò6ï/ç.í1è1ä3î1ã/ê1ÍŠ+qFEB?>B@@C@@?:=;964772242320/ +/ , ) + ++ & '@4>9<4A6E;>7C>D;KKEQIuŸãÏôÐíÍòÎðÒóÐòÞïÞóâðÝñÞõãôèïÞñÞòçòæôÜðÓôÛñÝòÞöÜðØîÛõØðàìãôØòÖðãòÑ÷âñáñàóâðÙñÔòÞòáñÝôáôàðàôÜñßôÜñÏòÖõ×õÞòÒóÕîÔ÷îóóóðòëïêñìòæïåöêõäóâ󿻉°JTDMAK@KBLDK?K=H?I=KBF=E=D9C:C;@8A6>7@9<7:4=69575645/1/5+000+-+**+*,((%.-47 79;4:<9<?AC@J#£4É.Ð,Å.Î.Ñ-Ñ)Ô.Ü5å/ã-å2ç-Ù.ß.á0æ3æ2Ú*Ð&Õ-â+Ö)Þ%×/Ù1ß,Ö/Õ0Ù(Ø0Ù.à/Ý1ç1å2ã/Ü-Õ+Þ/Ý+ß,×)Þ/ã-ã1à+Þ%à,Ö)Ô(Ø+Ô-Î)Í,Ü.ï2î3ð2ë4î2é2ì4ë+Þ.á,à.²yEC<??>>=A<=@7<89 ;54416 3 +3 11 ++ - +0 / * ) (% , ;6=7A6A;>6?8B9F=C>F>E=HCNANP•³êÍñÍñÇöÌóÐöÓóÔóÚòÞîãòåòéòâîÜöêõìñäð×ïÏñÌóÒó×î×óÛñÜðÒòÞï×î×òÕòÞðâóÞíàòâîÜñÜôßñÞôÜòÛñÔò×ñÚò×îßïÖõÙó×óØòÐñÐðÓóÍðÕñßõêóðñëðåñæõäóëòåîÙóÞòßò°ÆcRAN=RBL@L>F;I=E@G>C?E<@=A:@6?;>8@6@3<584;2<59.4421606-500)/,.+2'0)*'(-+*4 675 7;< <9?9A@X+¶1È.Â+Ç2Ì.Ô.Ù.Ø-Ô/Ú-Ý/â6à1â1Ý/ä5ì4é.Þ*Ó%Ì(Ì&Ê+Ö*Õ,×*Ò,Û,Ö(Õ.×,Û)Ý.â,Ý,Û,Ù+Þ*ß+Û)Ú+Ù-Í+ß+Û%Ï)Ð,Ö&Ô-Ø'×+Ø.Ö,Ø.Õ.Ô+Ê*á6ï2î2ç-ß3ä3æ7ä1æ+Ý,Ü2Þ%¹WAD@=@>><=;<;7;978 6151 3 0 0 +- 1 +/ (* +( ) & ') ) +=6>6<8?3A8=;@:C:BOAJ@JAF@D?FÚ,×)×)Ü(Ñ,×.Ú)Ú-Ö*Ô)×(Õ)Õ)Ð*Ï'Õ&Ó,Ö*Î+Ú.ä1è1Û)Û.à/é3â.à.×.×3Ú,Û+­FBCB>:<?7:;97 53 6352014 - 4-2 , ++ +) & '&() 7217<6@7>7A7>:@;E9FXo¿óÂò¿óÁòÉôÏõÆðÍðÒóÕîÏðÏô×ðßòÛóØñàóáôÎôÇñÈòÉõËóÌïÎñÉñÐïÐðËóÔõÐôÓðÓñÐ÷ÑñÏñÎðÍîÛðÑòÕðÖóÛñÕòÜî×ôÕñÑóÞñÔïÓïÎðÜïÌðÖôÑñÐñÐòÖðÙðæóæòãìÛïæóæöãòÞòÐôÏñÒïÑèŸrBI?IAH>GD:D;E8B9A8E:<6@5:6;1=5>1;084528/5.4.1+2,/.2)+(-%+%(%)++'(*433 357 9 :; 8Cƒ3¶)¾&Á(È'À*Æ,Â,Ë4Ó+Õ,Î+Ñ*Ñ,Ù3ß/Ñ,Û/á-Í'É"Æ' È'Ë,Í,Î,Ð)Í&È+Õ+Ñ+Î(Í'Î'È.Ê*Í,Ó0Ú+Î%Ñ)×'Õ+Ú)Õ*Ò*Ö&Ö(Ù*Õ)Ï'Ò(Ì'Ê'Ê)Ð-Î+Í&È'Ò/ä,î6ì1Ü3ß2ã4ê2à/×(Ð,Ð,Ñ-Î(ƒC?> ?9<;=:9962 9 541/ 0 0 . 4- ) ) , , +(*& $ + . ( A4>883<4A6?:=7B;C:FBl›Õ¹ð»ô¼ñ¿ôÄóÄòËìºóÍó×ôÒðÎòÍòÛò×óÐòÖóÜôØí¿ïÀðÈôÇôÈóÌðÄõÆòÏðÈòÎôÔòÓóÆóËôÇñÉóÏóÐïÙñÚñÔôÖô×ëÖñÛðÓñØöÜñØõÝîØóÚóÓôÎðÍòÑòÏóÎòÇïÉóÎòìóæòèòèðàóØñÚðßðÏôËðÎðÍôÈÙkX;J=K@J=E:E8E:@;B9C8@6@3>6<6;3<0:393404/5040212,3*.*,&.(,','#!+&,-'(1 22 38; 577D‹.«)¶&²#¹)Ì%Á*É+°.Æ+Ë+Ó,Ë*Å*Õ/Ñ-Ð,Î,Ü2×(À*º!À+È,Æ(É%Æ'½&È(Ä#Æ+Î'×)Å%Æ!Ð%Ë%Í)Í.×-Ö)Ö'Ô#Ö*Ç1Ô+×'Ö,Ô(Ó'Ô'Ñ*Ô+Ô.Ñ(Ð*Ï&Å)Ï)Í'É#Ç'Ò4ê3æ+Ü1à0×-Ö0â+Ü*Í.È4Ð-Í3Ë![>==979<=76;68 61+3 2 . - 3 +0) +( . % $'% , &(7/:/61<7A6D3@8A9@:y�Ø­ñ®óªð³ò·÷¿ó¹ñ°òº÷ÍóÉóÍóÊòÎòÓðÏòÍðÓöØïÁð¾ô±õÂñÅõ¿ôÇóÂòÆñÅõ¾õÊïÌóÉñÊöËóÖõËðÌòÌòÙðÏôÙóÉòÏïÑôÙðÙóÍñÐñÐóÌñÕðÚïÐóÑóËðÇïÏðÎòÉòÇíÆñÕòÞòáòÞôÝõØôÚõâî×ðÉóÏòÐôØòǪOL8=5;1:38191;1742240/03-2(-,0(,$+'('+$(%*(,).(,+1122 +74 57E%”+ª$«'©$¬)·)¹)°+®%µ*¸)µ&½'Á.Ç,Ï*Ì+Ô-Ð.Ú,Ä%½$¼,¾(¹&Ä)Å'À'Â'Æ&Ã(¾)Ç+Ì&Å.Í&Ì*Í*Æ$Ï,Ñ(Ð+Ò.Î$Ï-Ð(×+Ñ-Ð(É&Ð-Ï*Ì,Ó)Ï(Ô-Ë&Ë(Î,Ë)Í)Ã)Å*¿,Û0Û*Ù1Þ4Ý1Ó0â4Ú,Ð/Ï+Ë-Ý.Ñ+·B ?<=2; :6976 7 141222/. - (' .)) ( & ! & %, '<4<2>1:3>8?4>8;R~—ä¦ñªò¬ì¢ò¯ó´ï¨ë¤ò¸ö¾ó³ó®ñ±ñ¸ñÅòÈóÉðÏóÓôÄò¾ô»ñ½óÂñ»ï·óÄïÂñÆòÀîÃõÂôÅöÅóËñÍñËñÍòÃõÕòÚðÎïÑóÍóÎòÐôÉòÌïÈõÏñÉóÇîÌñÈôÆóÎòËòÏðÌðÄóÎñÃóÃñÈ÷àëÒñÛðàôÞòßðÚôÛóÙïÊñÍïÐóÎî¢sAD9E9@7;295;6=4:2;14052704,3/2+2*/+0'/&-&+&+$'&.(0+/)2)6 3344 78Xœ0¨&©"¦&©'ª$±(¡ ¡!³(¾(º%»%¹)º'¾,¿)À*À+Ã'º'·(¶"·'½(¿$¸'¾(Ã(½'À&Å'É&Â'Ã#Æ)Î+Ë&Ã,Ç)Ä(Ï)Ò)Ç&Æ#È+Æ*Ã+Ç+Ê$È&È)Í%Å+Ê,Æ)Æ)È"Æ'Ë%Å%Ì'À'É)¿(Ô-Ý1Ø3ç2Û.Ý/Ó-Ø.Ó+Ö)Ê*Ä-Ï.Ò.–9:9:93 : 35117 +1. //1 , 1 ) / '( & & $ #% & ' ( + +<492825195=4FVœšÛ¬ô­ò¨ñ¦ôªñªë¢åŸí¯õ¹ñ²ñ´ñ¶ò²ï¼ò¿ô¾ñ¸ó¼ô´ñµñ°ðµñ»ñ·îµïµ÷¾òÄó¿ôÀõËóÇóÀïÄôÉóÌñÃóÇñÍõÉòÇñÄðÇôÇ÷ÍïÀò¾ñÆòËôÍôÐðÆñÈòÆñÄôËôËòËðÇòÊôÅðÁõÁï½ó×òÔñÙóÝñ×òØðÐñÑóÒôÍñÊóÎòÌðÏ߇c>E9G8@8=6=7@7?5=3;6:1>1;3:070506/3-0-1,/&+'-),%)&*'&")%*%('*)+)2 421 35Y%�&¨&¯"¯"«#§$¨œ ™(²,³(´%³+³%·%À+¿*¾$µ&¿$³$°'­&µ$¹&¶ ¸)·&µ(Å*±%¼$Â&Â&½$Á"Á$Ä+Ì)Ë+Ë(Ê%Á)Ê0É,Ë*Ì'À&¾&½+Å)Ê&Ë'¾#Ä&Ä*Â(È#À"Ç%Æ&Î&É#½/Å(´)¾)Ô/Ò)Ò/Þ,Ö.Ð.Ò+Ð*Ð(Ô/Ð-É0È0Ì)| 9858887456011 +01. .+, )) ) ( +) (" ) +) ' '( +>-64:3:4;5Mh°¤ç¦ñ©ò¥î©ò©õ£î–Þ™ê³ó»ñ¸î²òµñ·òÄô¿ò»ô¼ñºõµò°ð³ôµð·õ´ð³ö¿ñºîºð»ó¿ð¶ôÂôÀî¾õ¾ó½öÆîÈôÁóÃòÀñÆïÅïÅôÅò¶ó¼óÅòÅðÀõÇóÊñÉòÈñÆñÈñÃñÂõÉòÊóÃñÁï¹ñ¸ô½òÇôÐóÊóàòÖðÑóÔñÒòÎóÏóÒïÐñÉñÊòÇËhS;L8A8>8<:;7B7<5:3817251705/6/4-3.1*6)3)0&,()#)*+&(%'%,&+'+).(-1/38j&ž$©"¦ ©$ª'¯%¨"� Ÿ%­'»%¸&¶&±.µ)¿%½#´%Á,¾#´$¯!¬"³!±#±#ª%¸%·(¾)¸"½&¹'·"À%¼!º"¾(À$¼!¾(º#À"Â'¼'Ã*Â'¹"³%À&Å&Ç*Á*Ä%½+È+Ï)É(Á$º$¾%Ã)Æ)Æ$Á$¸¸(±&Ä/Ä)È1Ö-Õ-×1Õ-Ï.Ç-Ê+Ë+Î%Ç+È*Ç \:7 62958 225 03 /2 / ' +* ) ) ( +$) +'% & +% (% ( +92919185Qu½¡é¢î ë¢ô¬ò°ò¬íŸÞ™ð°ó¯ô¶ï²ò±ò°ò¹ô½î¹óÀñ½ï³ð­ô°ðµõ¹ó¶ðµò´ó»ôºóºñ¾ó¼ò³ò·ò»ñ¸ñ½ô¶ó¾ò¹ð¾óÄðÄó¿ð»ñ¿ð¼ó½ñÁò½ñÆòÉôÌñÅïÂòÊôÌòÁî¼òÂïÀóÄóÃó¹ð½ñ·ñ½î±õ²öÄóÍòÒõÜðÒñÏñÊóÈñÎïÉóÍîÂïÄòǰIE9D9?4@6>4<5;57283:2621.3,4,4.0-0)/)/'.*+()%+$)#(%&')*+)&**%/009v)¤'¢!›¡©%«'© �"–'¯+¹(µ'°%±&­&µ,Á'¼'½%¼*¯$«&°"°'¸(º&¶"·&»)¶%½%½'»#­ µ%¼$»"º+º&¼,¾!µ)Ê&Ç%Å$À*À"·)À*Æ*Å%Å%Â%É&Æ'Ç+Ä&É,Å'»$Â'¼%Ã'»'À#¿(¿!À(¶%µ&Ä'Å)É+Ò-Ï+Í0Ì-Î)È-Ç(Ã-Æ'Æ)Ê(¸H 8466444241.1 + , , +(% &) %# " ( &)( * +) +306.7:f|Ã¥êŸïží¤ì¦ó¦ò§ç–å–ç©ô¸ó´ô±ó°ò±ó¯ö¿ðÃð¼óºó³ñ¬ó®õ´õ±ï·ð´ó¶ò»ñ¹óµö¼ò¸ð±ñ´ï¹ò¾óºïÀô½í¹óÁòÈñÈôÁô»ôÀôÂôÂòÇôÂî¾óÉð¿õÊòÆðÄòÆòÅö¾ó¸õ¿ïÁñÃôÁó¿ñÆõµð´÷´õ¿óºóÈõÌóÐñÏòÑòÌóËôÅðÃôÐïÇðÉñÃñµ’BF9?2@6>3=7@78292<08.6/6-3,0*0,/&-')&***$+%%!+()(-&0*/(,',). 09…&¡ ™#œ#£!¦'ª%¢!› ™¤­&¶!«¬$©'¶&À*À-Ã+»%µ(±"¦!ª$²$¸'±!µ¸$»%»#·#¶$±$¶/Á'Å'À(½)¾'¾)Á)À*Ç)Ê$½*·%É#½'Ç+Â+À#Æ%Ç!Á#Ã%¾'Ä'¾&·!½$¾%À)¼%¹(Å%¾%»&¶,½$±$¿(Ä(Å-Ê+Ë.Ç-Ð)É,Å(Â-Ì'Ä&½*¾/Å+¦ =35 346 121 /.0/ + +, '( +('$ & +" ' +% ) & ' % & 7-8;n‡Ôšæ›à–ß“í¤ç¥ìœã–ã›ë¨ñ­ó±ó°ô©òªõ±ó»ô¹ñÆîÁó¹òµó®ï¤ñ³õª÷ªò­ôµñ»ô´ñ½ò¹ï³ò¶ï´õÀòÅñÄó½ô¹õÃöÂñ¹ðÈð½ò¼ñÂôÊñ¹ñÂñ°ôÃòÄðÍñÂò»ôÃðÃð¹ð³ð¸òµò¼ñ¼ñ»ó¾ñ½ò¾ð»ð·ò´ðÀôÅòÁð¾ðÊñÀñËôÇñÄòÈôÍñ½ñ¼ðÃó½ë–f:@4>3 3 12, , / * , ++ ) ) '% $ "! +& +'& & %$ % " +& æ™Ú›Ú–×£ê—Ù�ӕܘè ò é£ì¤ë£ê¥ï ï©ó®ô«ó°õ­ô¬ô¨ñ¥ò§ñ¥õªï¦ô¢ñ¢ñ¥ô©ôªô´ï©ó¥ô³ñ¯ô¶ó»ñµò´ó­ò·ò¶ó¼ò¹óºî¾ïºó¼ðÂõ¾ôÀò³ò¸ï¸ó¹ô³ð½ôºñ¾ò·ò·ó®ò´ó¹ô¹ó¼ï³ï«ö±ð¹ð·ò²ñ´ñ¯ð¿ï»ô¹òµõ²óÂó½òÁó¿ñºñÀó¼î¸ò±ó«ó·ñ¯è–v5:/4,3-5.1.0-/,1)1+0',+(%)%%" #''%(%+&*$'$&')"%#($” šž#›!�“”"ž! ¡!¢  §$¥¡ž%®!«$¨(®&¦!¨$­#§ž¨"¥£§"¥!¥!©#©'¬ ©!¯%¬!®²(´!¶#®!¶)¼'¹%¼%³·"¸'»"·)»(¼'¹%¶#²#¶!´!²#¸$¸#º$¹µ%¯%¯&º$·&±/´!¯$®#¶(´*·*¸+¯)¼+½(²&µ(º(Â*»&¾)Â-Ã(À%´!´%®$®#·%­#…20. , 00( ) *) ( ' ' # ! # +' +' ! '% % ' +%"Ú•à�í›â™á™Ü™Ú”æŸëžò¡ë¡å ì¥ë ì§ñ©ö¬ð¤ð¨ô©ï©ô¤ò¤òšó¡ò¢ï¥ó¡ñ¦ô¥ó¥ó¦î¥ó¥ò§ó©öµô®ð°õ²ô¯ó®ó·õ¹ó¼ô»òµó·ó¶ð´ñ¯ð·ò·ô¸ó®ò¹ó¶ò¸õ´ñ´ó¸ò±ñ´ó³ò·ð¯ô¹ò°ï³ó°òªð°ò²óµò°ó¶ð´õÅð¸õ¸ò¸õ¾ôÄò¼ôÂî¼ñÂ÷¼õ¹ôµñ«ð®õ¯ð¦ÚtX081803,0.2,2)0)/)1(0)' '%"$$)#$'*('#+&%"$%*#&$%%˜™ ™ š!œ œ"œ™”"Ÿ�§!¢! !¡$¨&­!¤¥&¤%©¦&Ÿ—œ ¨!¦!ž ¤«¨$§"�!§!ª$¬&°$® ©!°$°%¯(° ¶$¼'º'»ª(¶$²%µ$µ ³#°'®"®&µ!´#¿'¶%¶%³'·#¸ °&°$´#¶'³*³$²-´©&µ ª%¬$«"µ,Á&² ±%¶$¸)Â(Â(½(¼*Â*¹#´$ª!¢ «"©¤k-. - - , , +' ( $ & +# % +"#$$&$%' +$ & $ $Ԓٖגқܧê¥îœêžá¢æ”Þ™êŸè¡ïŸé¥ï£ñ¬ï©ó¡ð¦ó£îží›ô›ó¡õ¦éžð¢íŸð¦îª÷¦ò¥ô¦ó¨ó©ó­ñ®ò¬ð«ó§ò®ò¬ñ³ô·ó¶÷µöµó­ôµñµó·ó´ò³ñ¨óµó³ò´ð±ð©î¶ï±ò´ò°õªñ¯ó³ò¯ó«ô²ò³ï¬ô¬ô¬ïªó«ó§ô¸ô¶ï³óµò°ïºô½ðÀó½ñµòµïµô©ìªó¥ï¨ô¨ñ¤ÁZE-3-6,3+/*.+,&.+.%-')&-56.&$%'%%*'$"'%%!"$*#*&'%•” —#œ¡   Ÿ�$§ ¦# ™!�&£#§$ª%¦"¨¦"Ÿ(¤$™” šœ£Ÿ!¢"¡œ'£# ¡&¨#¦!¤ª¦©#¬­$ª%ª ¥#´ ±!©'µ(° ±« ²&³$® ¨#­"¯$±%±$¦"­"«$µ °!° ©%¬,¬&«#°$¹&ª$©"± ®"¨$¨¨%²#§$¯$¶#³*½.¼)Å'´$²!­#²"®$­#§!¢¥!£N/- , , ' ) & (+ 3 5 +2 (% % " # $  % ( "Ғ՜ٚךߞå�ç˜ëŸñ¥ížô§í¨è¦í¤ê¦ô£ê§ñ¨ð¦î¤í¢è•ì™ïœñ�ó¡ó�ò¡ð ðŸð ó¦ï£ôªô§ó®ò¥ô¥òªõ­ò©ò¬ó©ò¤ó¶ñ­ò³ò¬ñ±ô¨ó¡ó²õ³õ­ñ¦ó¨ô°ó´ó³ò«ðªò¬ó®ñ®ô¬ò¦ò§ó§õ¯õ²ò±ò¦ð§ó¯ó®ò¦ô¨î¦õ³ô°óªó±ó¯ò¼ñ¸ó´ï®ð¬ñ¯õ­òªì¬ó«ò£í§ì¡™A9)5+1.-(,-+*0-7*::@8?6975*%('&(%'"$$&"*('!&&“‘”œš!›%›%  ¥$ %©%¥"«$©¡!¤$ #©#¨"žš!š ¢ �!›ž ¡#Ÿž £"©"¢¤¬!©(¦© !£"¤!ª §©"¥#¨$®(­!¨"©!©¢¨'¯#°¤!«"©%±%³&°¤!©!­%­¬!® £&¤&«&«(± §"¬!©$±ª!¦ £#±'³"®"¨&± ±!µ'¶#±$®$±"¯$ª$§#¦"¯%©#¦$–6 , +, +0 -18778;8 7&# & +%% #! +%% Ò•Õ•Ô’Û–Þ�֙؞ë£í£ï¥ñ©í¡ó¤ìªë¤ï¦ñ«ð©ðœä•êšïŸñ ð›ï¤ñŸóŸïžíœð¤ñ©õ¬ô¦ò¤ñ¢ð¦ð£ð¤ó¤ñ¢ô¡ñ¥õ¢ó°ñ¦ð«ó§óªô£ô¤ò¤ó§ò¥ô¥ó§ö¬ò¬ó´ò¨ò¬ó©ô«ò¯ô±ñ¬ó©ð§ò¤òªò§ó§ð©ò«ô®ó¨òŸò ñ�õ¯ô¯ò¬òªó¯ô­ñ±òµñ±ñ±ò­ò¨ð¨ò©î§ï­ñ±ñ¦ã’q36040<7?>06A:;;<6:0.%&$%&'"* &"#"$$$%#%–!”Ž �–"š Ÿ$¡�%§&¦!£!›$¡&£"¬$¥$­#¦›› š› š  £%œ !Ÿ˜¤ ¨¦ ¢!¡!ª £¥¥Ÿ¦›!§#¦!¢£&¨¥# ¢"¤¡­ ©«©¢ § «!¦ª"ª « «"°!«"¤ž#ª(­«#§#¦"¢$ª£™› ¡%«$®#«"°$¯&¬'³)´"°%¯%°'«(®$¢®£¡$¨&‰ ;<=;=<7;9974 3 $ +" +&! $$ +# !Ó’ÍŽÓ�Ü“Ù�à™Þ–â�ã�ç¡å í¡ïžâ›ì í©ðªõ«òžè—î™ï�ñœñšîŸðŸñšðŸñ�ñŸô£ò¥ò¡ï¢õ¥ô¥ó¦ö£ó¡íŸò�ò¡ô ò¤ð ñ¨õ¨ò¢ïžõ¢ñžò™ô«ò©ó¦ô©ñ£õ©ñªò¨ò­ò°óªô¯ð«ö¨óžò�ó§ô¥õ©ï§ò˜òžñ£ñ¢ñžòœï¨ô©õ§ñ¨ó®ôµô²ð±ò³ï®î¬ï¬ô³ð°î§ð£ê¦é¦ñ¨×}XAKA:>?=E;B;CC=@9@;A9@<97=6;7<5867-$"###*$&#$%$""$‹‹‰�"�Š • š"ž!—!œ#›!œ�§ž£ª%–† •šš#›š• šœ“›•œ›¨žœš˜™!¡¥$ª"£ $Ÿ& šŸ Ÿ$ž#¡!œŸ�¦¨ «$¦!¤¥$©!ª §#¨"ª!š"¢% !¡!žŸ"¥$¢£Ÿ#¢¢žž §#§£ ¨*®&¬¥"¯#®$ª#¨)¤%¦¢"¥ ž!¦&ž%£$ R@==;;:;9 566 7* % ! !!$¹‡ÁŠÈŠÉ‹ÖˆÓ’Î’àœß�Ú›â–ß—ë™ìžð£ç›ìžé—Ð‰ÜŒè–æ•îœî˜ê“ë¡î›ë—æ”ï“ë–ê˜ï ô¡ò�ñžñ˜ðœòœñ£ó£ó�ô¤í£ðŸì•â™ñ¤ôšî™ó¡ò¨ð¤ñ©ò¦ô­î«ñ©ó©ò¦ñ©ó¤ò¦ò¥õ ï ñžê¡ïœï¢ò¤ó¢ñ¦ò£ó£ó¦ð¢ó�ó ð¦ï¥î¬ï°ò­ò¦ñ­î¬ô®ñ­ðªï£ð¥ï¤ï é¡Ú¢åžéžÞ˜”RLBF?A=?:A<<:>9?9;6;796=45)(#)%"$###%$"'ˆƒƒ„‰–”˜˜•“›�!œ�›š ”�Ž—“›–”™$š—”—�–ž�™—š ¤Ÿ!¡#¡  !¢$£•“Ÿž¢ ž!§Ÿ¡#­!ª§«!ª £#¦"¤ Ÿ$¢¤˜œ ¤œ�¦Ÿž!¤$­ ¥#¦œŸ& ! #ª#¯%¨#¯%«!®$®"§&¥ «$­¦'©$¥ž!¤#�¡"’K?: =9 897: 76 3 0 +$$ "&%'! +ȇćÀˆÃŠÇŠÍ’Ô•ß™ášßšÜ”×™Þœé™åšç”è•Ü‘âŽç–ã‘æ–ê‘ãˆé˜èšî“ë•êŒì”ëšñ�ô˜ïŸð™ìšð˜ð›ñ˜ð ð¢ñ¢ñ£õ¥ò�ìžï¢òŸõ¢ô¤ó¡ï¡ò¥òŸò ó£ò¢ò ô¤ò ò¤ë—ñ˜í¢ô›õ ð›ò ó˜í—õ¢ë–í¤ò ñ¢ð¢ðœóšó¡ñ«ò§ö¨ò¨ð§ò¯ï¯ó«ò®ï¢ï¥ì¡ï¨êžè¥ð¢æžç¡æœå�ÝŽ€DE:F>D9C9A9B:<689:59264721%%"%$'#$!$""†"‡Š‹†Ž‰’”““–›œ•Ÿ�Ž���’˜�’’“‘!˜ ˜�“› ¢¡™“!—!ššœŸ �¡ Ÿ™¡ ¤™ž%¥ ž¦žžžž Ÿ¡"¦¢"œš � œ!¢¡!Ÿ œ•›# ž ž¢›™ Ÿ�"­ ¡#§#¦%©"¤$¨#¦"¬ ­!¢¥£žž›Ÿ$Ÿ*¢"–"„C> : 9 9: 7 8 6 +53 32 +" "!"! +ȇĉÌ�ˌ͈ʋË�ÑŽÒ�Õ—ã—ä’ä�ä—Þ“ä™ÉˆØ�ÞŒÜ�â“æ–ë–è’Ü•ëŽê™é�èžìœí›ï–íœö¥ñŸå•ê˜æ‘ï–ñšõœô óœî�ë ô›ó�õ¡ï˜ó¦ô¤ò¦ô¢ó§ïžê•ñžö¢í�ó›ñ ñ—ïžñ¡ó§ï¡ï¥òŸë¢ï¡ë¦ñ£ó–ïŸïžòŸñ˜ð›ï˜ñ¤ñ£ñ£ð¬ñªò¦óªó ò©ó¬ñ ïžìžë�ç™ã—å”ã ç–ܓۖÆ|fAK=F:A:<4859:93316/50) "%#!#$#& …†�Š ŒŠ�Ž � “"�"“”"�—˜‹Š�‘’‘ �•” •Ž’™� ¤–—"˜Ÿ™�”—•™!œž›¢ ž›ŸŸ�%¤#¤ ¦¨§ ›  ¡!›(� œœ¥"¤œ"¢ž¦£œ¢  ›™œ –›�– Ÿž"£§$§$¬¦#§"¦'¥" # "¡ ž #š“—““ ›”s<> <=;677 3 3 2 . .  $" +½€½†Æ�ŠʌÉ�ÏŽÒ�˔Б֑ޕؒۖޚÚ�Ó�àŒàŽà’ã’â™åŽè’Þ”Ú�ä‘ë™ì™ìžì”â‘å”í’ã™ð•ì™ëší›í›ñ—æ“ï”ð¡ïžóœì—ìšëœñ¥ôœó¢ô¥ò©ìžîŸò˜î�ñ˜ñ•îžð¤ð£ô¡í¢ó©í¢ò©ò¨í¢ðžîŸéœî�ìšò™íšï’è�òšè¥ô¥ò¦í©ð¥îŸâ î ð£ì¡äžêžïžèœå›ãšÞ‘àšÜ”×�Ζ»g[;D681910350313-/..($! ~‚~z„„ˆ�‡‹Š…„‚Š$Œ†ƒˆ‡…Ž�‡ˆ�!‡†Š†‰Œ�Œ“– ‹�’Š��!™!›˜!—“�‘“�—”–Ž•˜ 𔕕‘•‘”•˜’� –“!”’•˜ ˜‹—��™˜™!š!™”›š˜ �‘–Ž‘—�”Љ‹Š!Žo6 9864424 2 1 , ,##§x§€®x³}·‡¾€¼�ÆŠ¿„¾‹É…ʑNJÅ�ÄɅÇ�Ò‡ÑЃÕ�̂ɉҋÓ�ڑ؋ъχ҇؉ڌÚ�ãŠä�Þ�ã“Û�àŽâŠÝ�ã‰è’àŽè•é”ê—èœåŒäŽã“æ›ã�è–è’ä“ã”è–î˜ò›ë“á™éŽä’ã’äŒä•ç•æ�äŽç‘ç�êšê”à”çŒä‘ç“á•ä”àŠÙ‘ã›å“ߑޗãšã–å—á™â‘ÙŽÑ�ܑՑՑӒΒьĄ¿ˆÈ‡¼�Ç…¬bQ::9>7<64376513/704/1)2))" su€~|ƒ‡�‡ˆ‹‹‰~�‰…„„„†�…�‹ŠŒ‹ƒ‰‹�ŠŠŽ��ˆ!�‰Ž�Œ”!••›•‘‡—��–�™‘Œ#——Œ’Š‘�Œ�‘”’““‘’Œ“�–•”�Š•‘�‹ ›œ–“˜‘ ��‘�‘!��††…ˆ ЉU 585 355 22 2- - ( ‘l©z³€±�®}»yÁ‚¼ˆ¼‡Ç�·‚¾€Àǀdž¿†É„À€È…ǃĄґЋ׌Ӏʇ͆̈ғێ؇׊Þ�Ý�Þ�׈Ô�ىؒã�ã�êŽÝŠç“è–ۉ݆ã�ç˜ä�Û�æ�åŽç‘á�â‹Ý‘ã“ß’ç�Ù‰Ü�ÕŠäŽç�ë—ì’ß“ê“æ�Ø‹á‹Ó�ß‹ášæ’ë•ç”Û‹Ø“æšåŽÝ‹Ü™è Ü–Ø�ΌĊ̎·֒Ñ�Õ‘Ë�ŊƆŅŃ»†Ã‡Èˆ¿†‚HE7;8;6559636534-0-0-)*+( _‹}€�~{}…‚‚}‚€€…ƒ�ƒ‚„Œ‰‹‚‚…‡†Œ‰€ƒŒ�ˆŠ’ˆ��‹ �Š�}}Š™!‘Œ�’’� ��‘�’‘ˆ†��ŽŠ ”“‘މ’Ž‘”�“�‘” �–––˜Œ‰ZŠŒ�Ž‹ˆ‰†‚ ‰‚††…€=397 3 40 - /,- ,%œ«Âr }±}³~¶~±}µ|½€Á‚¾¶yµ�½~ÃʈʃÆ�ËÃňΊΊӄ˃Ï{Î�ȂӃ΂ʌ֌Ú�Ê�ÈωҋԖ܎âŽ×ˆÛŒß†á‡ßˆß‘؃͊ԅێä�Ü�â�è�ç”ã‘ß�Ü”âŽÝ‹ÒŽâŠå”ä�áŒçŽßŽá“Þ�ã˜ßŽà‹æ’݉áŽä�ØŠà‹ß�â•Õ•â’å™ä•ږݚ֗ђψÆzœy‰ωÐ�̉Ɉʄƈń¿ƒÃ†Âƒ½ƒ»„´…¯ud=9:;4<2324/4-/00/-.,(-*($ Ñ+‰~€upy|�€‚yyx~~ˆŠ€�ˆ‡Ž„€„ˆ‡‚#Œ‡‹�‡†�‰‹��Ž„ŒŒŠˆ‰ŠŒ�…�‹”Œ�Œ‹�“ŠŠ‘˜‹Œ�‘•—!”�‡�‹“Ž�‰Ž–”�‘–™!•”‹ˆ€#ŒŠ‚�Š!�„ƒ|†‰&ˆ‰†ˆl95731 +1 2 -1 1+ +' Û‰©w™‚¥s›nžv¥v³‚¸~¹‚½{²u§w²{¼‚¼€¹†Ê‡Æ‚Ç„Ê~ÆȇË�Ë|ÆÖˆË�ɅφȇЈÉ҈Î�³„Ó‡ÓˆÖ�،ӎۈß�ã“Ô�݇܆Հ҇҅Ԅ؇ݎݎà’ÝŠß�äŽÜ‰Ü“Û‘è�ã�â†Ù‹Þ‹Ú�ä’ޑՑޙܕ֑Ú�Û�ۊ؈ß�ߊӉÞ�ׇٕ̓֗ӖӔÑ�Ñ�ΈƊȃÁ‡Â€Ç…Èʈ…Á‚»…¼‡ºŠ¹‚¼‡¹‡¸�›]I6;4416.00/112-,---*'(&$#{wym_rm€}}€usx~!ƒ€ƒ€ƒ‰…}‡ƒ‚„ƒ‚{…�†ˆ�„�’‘‡ŒˆŠ„‚„†…„‰ŽŠŒ�ŒŽ�Ž��‘ŠŒŒŠŒ†–”’ŠŠ��‰ Œ‰„†ŒŒ�‘�ŒŠŠ‡ˆ�€�‰ˆ€�‚Š„�ˆ�}O +7 -51110 ) ) +% ( $ ”išr™c†Ws\•w¬€¶{³}µ€®v®u²x±{±vº‚Ã|Ày¿½€¿�¾…͋ɄÁ̀̀ƀłÀ�ƒɃ¾„Ë�Ï…Ò‡Ò…Ñ�ɋψ܋چĉÐ�ՃЅ҅̀ͅ؈քԈيۊޅ߆؈׎׌׎Ô�ÞˆÝ�ڈ׃҆ӅȄÖ�ב×�Ô�ΈъԊԆ̃ӋԇчÌ�̋ωВχό͌̇É�хdžɆ»x¸�À‡Ã�ƒ¹€¾�Àеƒ³‚°‚°{ª|¤}¬w~J?36381202/0.-*-*-'($*%$!_o[cdy}�w}rwtrs}yz{{}{‚†‚}~{|y‹„ƒ�Œ‹‰‹‰‹…‡ƒ„„‡€Ž†‰‘‹‰�„‹Š‰ŽŠ‰�…}…‹‹Š�ˆˆˆ�ˆŒˆŠ…ƒƒ�‰ˆŠ†Š‡‹�†€††|†€€€z€xy}r? 6 12 , - . (* %& %|`‡b…cŒj—}¯‚­{³~«{§p£u¨v®q§o­w±{µz»}¼}¶zºz¹|½{Á‚¶zºyÅ�¼}ÆÁ�Æ~Â{´‚ÂŽÒ�Î�ӂӉև̃ҋ։Î�ʀĀ̈́ՅЃˉ҂ЇЈÔ�Պ։؃ʃ׋Ú�Õ�ممӋÇ҈ϋՋÒ�ԌҎΎχΌÒ�Ð�ӆɇψÎʇńÇ͈ˀ͊ъȊÇĈÆÈÆ�¹ˆ¸�¼„¼{«€¸†¿‰¸~¹€®~­w«z«v¦y¥{šoa3?22/.01////-,((%&&##!SZYis|yyyutvsprw„{{xxx}vy€�‡ƒ„~†‰Ž‰‚‡‰€Ž„„†Š‚„~‡‰!‰‹…{ƒˆ‚ˆŒˆƒ!�„‘‰ˆŽ‹†ƒ‡Šƒ�…‚�†‚ŠŠ‹ˆ‰‡„†„ƒ€��…‚zy€zxy{xf 5 0, 1 /*( ( '%!{\|`…j“m£~®y¤|¨x¤r¤t«s¨t­s²q³|µy±|»~¹x½z¸yº{»}´¶|»z¾¾‚ÁɃʆÈ�Ñ�ІчԊDŽͅΆÃ|ʅ؆ԃ̂†Ì�˃΅Æ�Ó�Ç…Ô‹Ò†Ô�Պ׊σ˄Ԉʀ̃Ӈσ΋ԇÅ�Ô�Ѕ̓ϊτŅʀǀÆ~DŽ̊ɃɇςȈÉ|É„Æ~̇ŃłɉĊņƉ‰»~¸…¼‚»{¶…±‚®ƒ¸{¯{«­~§|®w¨xªw�rŠ^M430110/+-,)(%.)%%$"$cjiruzvrrsqtspt|uxx~~{}}{zzy}{„}†€x‡…‡�‚€‡}}‚…†‚Š‚‰ …‘��‡ˆˆ†ƒ†‹‡�Š‹…„†‡„€z}�…‚‡ƒƒƒy}€€ƒ‚…‚‹�€…ƒy‚|v~{||vusqU0 .. +* - *)"# �k�kŽj u¡v v£t r¦o¦r¥p©r§t£pªv²{²u²zµy¯y¶{µ|¸z¸uµq¶}¹‚¸z¹xÂ�ÂÀ~Ç~Ãw¸xÁ†Ç‡ÊƒÐ�Ä{À€Ì…̆ÆȇÊ�ÂĀȆʆфΉ҆ы׌ЉՌш̓Ѐʆ͂̃φӋÚ�ԈȀÁ€À~χ¿Á„ÀʀĄDžDžƆ΄ÇÇÄÉy¿ƒÁ„½ƒ¼‚ĉÁÁ}¹~¶y´€¿„¹�°w³}µz®r¨x«x£x¨€¤y¥s¥q t˜nyH<-2/0*+),+)%*!$"##kiimvsuqrnp|xprsu{x|vy~{ru~w||�€xwy|ƒ€…}y‹ˆ‡…‡ƒ�€‚~ˆƒ†„„‰}z~}ƒƒ‡�ƒ‚|y†~‚†‰†…‚�~ˆ „|}€†‚‚ƒ€{}€ƒ}zzu|zxvxvrunqm? +. 1-%& &! ‘i‘j”h–nžs£tšzžp£q¤q¥s®u³q§t¤p©s¬p¥x±v®p²w´{µx´²u¶w¹|ºzºzÀ~Ä€¾Ä~»}¹}Á�ÁƒÁ€È€Ð‡¿�ԉlj҅΃ÊÁzÉ~Î…Ë€ÅËŒÓ�ֈυǃƄÿƒÄƒÀƒÍ‚΀ˈՅÁ�ˇ¾ˆ¹}½}Ä‚¾uÅΈ΃Ê�΂Á}½|É�Ä€À†¼‚Á{¶}»Š¿€¼�¶z·}¶¶�¬{·‚·|ºz±x¨z¨ª~ªv¤t¥t¥wšu›w¡jšnœq’eY71,+-))-'(&(!"$ %ggcirsuoemlovkosroupswtur{x{vq|yƒ~�~�z|ƒ|†}„~|�ƒ~� ŒŽ‹ ‚~‚†‰}��Љ‚‡�‚}�x}‚�}~}||�||‡|�€y‚€z}yyx{}xxvttztpulm[0 .'' '## "‚b†b’h—h�j˜p•l�d—e—oŸqœm£n¦q£qªq¨m�o«r­t¶u´w°y¯u¬w¬k«}±qµn«€¼w²w¹}·{¶}¼~¾ºzÃ}Æ€¼|¿}ÅxÁy¸w½À~¿zÀ}Ã}Á‚½~ȇ҄ςÅË�ȀǀʆÅÎzˇÈ|É~À„ƃ¾ƒº|»z½xÁ�Ç~È~Á€¿}ºz½‚º„Â�Ńº‚³‰¾�¾€»z³|ºz±x°„·}´z®{²y«x±r¨x§v¤p¤z£oœw£l¢x�t˜n–l–p”i”mP<-,%,*&$&!#%!! "^hjlkjk hg `sohmhnqproqp{|tpxz}z"€pzzzxz€zxvrwt€|wzwtzvzƒ‚„ƒwzxy~{z~„xsz�~|„„w}‚��ƒ}~{z…"��x{zyqxlxopmosngiehbA , +'*! #  \ No newline at end of file diff --git a/examples/peripherals/isp/dma_input/main/isp_dma_main.c b/examples/peripherals/isp/dma_input/main/isp_dma_main.c new file mode 100644 index 00000000000..4460e7502ac --- /dev/null +++ b/examples/peripherals/isp/dma_input/main/isp_dma_main.c @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "mbedtls/base64.h" +#include "esp_check.h" +#include "esp_cache.h" +#include "esp_heap_caps.h" +#include "driver/isp_dma.h" +#include "driver/isp_core.h" +#include "driver/isp_color.h" + +#define EXAMPLE_WIDTH 240 +#define EXAMPLE_HEIGHT 280 +#define EXAMPLE_BASE64_CHUNK_LEN 384 +#define EXAMPLE_BASE64_DELAY_MS 10 +#define EXAMPLE_DMA_ALIGN 64 +#define EXAMPLE_FRAME_COUNT 1 + +extern const uint8_t sensor_raw_start[] asm("_binary_sensor_raw_start"); +extern const uint8_t sensor_raw_end[] asm("_binary_sensor_raw_end"); + +static void *s_alloc_dma_buffer(size_t size) +{ + return heap_caps_aligned_calloc(EXAMPLE_DMA_ALIGN, 1, size, + MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT); +} + +static void s_configure_neutral_color(isp_proc_handle_t isp_proc) +{ + esp_isp_color_config_t color_cfg = { + .color_contrast = { .integer = 1, .decimal = 0 }, + .color_saturation = { .integer = 1, .decimal = 0 }, + .color_hue = 0, + .color_brightness = 0, + }; + + ESP_ERROR_CHECK(esp_isp_color_configure(isp_proc, &color_cfg)); + ESP_ERROR_CHECK(esp_isp_color_enable(isp_proc)); +} + +static void s_print_base64_payload(const unsigned char *encoded, size_t encoded_len) +{ + printf("IMAGE_BASE64_BEGIN\n"); + fflush(stdout); + 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]); + fflush(stdout); + vTaskDelay(pdMS_TO_TICKS(EXAMPLE_BASE64_DELAY_MS)); + } + printf("IMAGE_BASE64_END\n"); + fflush(stdout); +} + +void app_main(void) +{ + const uint32_t h_res = EXAMPLE_WIDTH; + const uint32_t v_res = EXAMPLE_HEIGHT; + const size_t in_size = (size_t)h_res * v_res; // RAW8: 1 byte/pixel + const size_t out_size = (size_t)h_res * v_res * 3; // RGB888: 3 bytes/pixel + + isp_proc_handle_t isp_proc = NULL; + esp_isp_processor_cfg_t isp_cfg = { + .clk_hz = 240 * 1000 * 1000, + .input_data_source = ISP_INPUT_DATA_SOURCE_DWGDMA, + .input_data_color_type = ISP_COLOR_RAW8, + .output_data_color_type = ISP_COLOR_RGB888, + .bayer_order = COLOR_RAW_ELEMENT_ORDER_BGGR, + .has_line_start_packet = false, + .has_line_end_packet = false, + .h_res = h_res, + .v_res = v_res, + .dma_burst_size = 8, + }; + ESP_ERROR_CHECK(esp_isp_new_processor(&isp_cfg, &isp_proc)); + ESP_ERROR_CHECK(esp_isp_enable(isp_proc)); + s_configure_neutral_color(isp_proc); + + uint8_t *isp_in_buf = s_alloc_dma_buffer(in_size); + uint8_t *isp_out_buf = s_alloc_dma_buffer(out_size); + assert(isp_in_buf && isp_out_buf); + + size_t embedded_raw_size = sensor_raw_end - sensor_raw_start; + assert(embedded_raw_size == in_size); + memcpy(isp_in_buf, sensor_raw_start, embedded_raw_size); + + size_t encoded_len = 0; + int ret = mbedtls_base64_encode(NULL, 0, &encoded_len, isp_out_buf, out_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); + + printf("Feeding %d frames through ISP DMA input...\n", EXAMPLE_FRAME_COUNT); + for (int frame = 0; frame < EXAMPLE_FRAME_COUNT; frame++) { + ESP_ERROR_CHECK(esp_cache_msync(isp_in_buf, in_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + ESP_ERROR_CHECK(esp_isp_dma_process_frame(isp_proc, isp_out_buf, isp_in_buf, 1000)); + ESP_ERROR_CHECK(esp_cache_msync(isp_out_buf, out_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); + + size_t out_len = 0; + ESP_ERROR_CHECK(mbedtls_base64_encode(encoded, encoded_len + 1, &out_len, isp_out_buf, out_size) == 0 ? ESP_OK : ESP_FAIL); + + printf("IMAGE_META frame=%d width=%u height=%u format=BGR24 encoding=base64\n", + frame, (unsigned)h_res, (unsigned)v_res); + s_print_base64_payload(encoded, out_len); + printf("Frame %d done\n", frame); + } + printf("ISP DMA visual demo done.\n"); + + free(encoded); + ESP_ERROR_CHECK(esp_isp_color_disable(isp_proc)); + ESP_ERROR_CHECK(esp_isp_disable(isp_proc)); + ESP_ERROR_CHECK(esp_isp_del_processor(isp_proc)); + heap_caps_free(isp_in_buf); + heap_caps_free(isp_out_buf); +} diff --git a/examples/peripherals/isp/dma_input/pytest_isp_dma_input.py b/examples/peripherals/isp/dma_input/pytest_isp_dma_input.py new file mode 100644 index 00000000000..e5603445560 --- /dev/null +++ b/examples/peripherals/isp/dma_input/pytest_isp_dma_input.py @@ -0,0 +1,181 @@ +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import base64 +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 frame=(?P\d+) 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+/=]+?)' + r'(?=\r?\n|IMAGE_BASE64|IMAGE_BASE64_END|Frame )' +) +IMAGE_OUTPUT_TEMPLATE = 'isp_dma_input_frame{frame:02d}.ppm' +REFERENCE_IMAGE_PATH = Path(__file__).parent / 'golden' / 'golden.ppm' +EXPECTED_PIXEL_FORMAT = 'BGR24' +EXPECTED_ENCODING = 'base64' +RGB888_BYTES_PER_PIXEL = 3 +PPM_MAGIC = b'P6' +PPM_MAX_VALUE = b'255' + + +@dataclass(frozen=True) +class ImageMetadata: + frame: int + width: int + height: int + pixel_format: str + encoding: str + + +@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( + frame=int(match.group('frame')), + 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'IMAGE_BASE64_END|{IMAGE_CHUNK_PATTERN}', timeout=60) + if match.group(0).decode('utf-8') == 'IMAGE_BASE64_END': + return payload_lines + + payload_lines.append(match.group('payload').decode('utf-8')) + + +def _bgr24_to_rgb888(raw_bytes: bytes) -> bytes: + rgb_bytes = bytearray(len(raw_bytes)) + for offset in range(0, len(raw_bytes), 3): + blue, green, red = raw_bytes[offset : offset + 3] + rgb_bytes[offset : offset + 3] = (red, green, blue) + 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 decode_bgr24_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) + expected_size = metadata.width * metadata.height * RGB888_BYTES_PER_PIXEL + if len(raw_bytes) != expected_size: + raise ValueError(f'Expected {expected_size} decoded bytes, got {len(raw_bytes)}') + + return RgbImage(width=metadata.width, height=metadata.height, pixels_rgb888=_bgr24_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 ISP DMA artifact to %s', output_path) + return + + logging.info('Saved ISP DMA artifact to %s', output_path) + + +def load_ppm_image(image_path: Path) -> RgbImage: + ppm_data = image_path.read_bytes() + try: + magic, dimensions, max_value, pixels_rgb888 = ppm_data.split(b'\n', 3) + width, height = (int(value) for value in dimensions.split()) + except ValueError as error: + raise ValueError(f'Invalid PPM image: {image_path}') from error + + if magic != PPM_MAGIC or max_value != PPM_MAX_VALUE: + raise ValueError(f'Unsupported PPM image: {image_path}') + + return RgbImage(width=width, height=height, pixels_rgb888=pixels_rgb888) + + +def assert_image_matches_reference(result_image: RgbImage, reference_image: RgbImage) -> None: + assert (result_image.width, result_image.height) == (reference_image.width, reference_image.height), ( + f'ISP output dimensions do not match reference image: ' + f'{result_image.width}x{result_image.height} != {reference_image.width}x{reference_image.height}' + ) + + if result_image.pixels_rgb888 == reference_image.pixels_rgb888: + return + + mismatch_offset = next( + offset + for offset, (actual, expected) in enumerate(zip(result_image.pixels_rgb888, reference_image.pixels_rgb888)) + if actual != expected + ) + pixel_index, channel = divmod(mismatch_offset, RGB888_BYTES_PER_PIXEL) + raise AssertionError( + f'ISP output does not match reference image at pixel {pixel_index}, channel {channel}: ' + f'{result_image.pixels_rgb888[mismatch_offset]} != {reference_image.pixels_rgb888[mismatch_offset]}' + ) + + +@pytest.mark.generic +@idf_parametrize('target', soc_filtered_targets('SOC_ISP_SUPPORTED == 1'), indirect=['target']) +def test_isp_dma_input_example(dut: Dut) -> None: + reference_image = load_ppm_image(REFERENCE_IMAGE_PATH) + frame_count_match = dut.expect(r'Feeding (?P\d+) frames through ISP DMA input...') + expected_frame_count = int(frame_count_match.group('frame_count').decode('utf-8')) + logging.info('Expecting %d ISP DMA frame(s)', expected_frame_count) + + for expected_frame in range(expected_frame_count): + metadata = parse_image_metadata(dut.expect(IMAGE_META_PATTERN).group(0).decode('utf-8')) + assert metadata.frame == expected_frame, f'Out-of-order frame: expected {expected_frame}, got {metadata.frame}' + logging.info( + 'Received frame metadata: frame=%d size=%dx%d format=%s', + metadata.frame, + metadata.width, + metadata.height, + metadata.pixel_format, + ) + dut.expect_exact('IMAGE_BASE64_BEGIN') + logging.info('Receiving base64 image payload for frame %d', metadata.frame) + payload_lines = collect_base64_payload(dut) + logging.info('Received %d base64 chunk(s) for frame %d', len(payload_lines), metadata.frame) + + result_image = decode_bgr24_base64_image(metadata, payload_lines) + logging.info('Decoded frame %d to RGB888 image', metadata.frame) + output_path = Path(dut.logdir) / IMAGE_OUTPUT_TEMPLATE.format(frame=metadata.frame) + save_ppm_artifact(result_image, output_path) + assert_image_matches_reference(result_image, reference_image) + dut.expect_exact(f'Frame {expected_frame} done') + + dut.expect_exact('ISP DMA visual demo done.') diff --git a/examples/peripherals/isp/dma_input/sdkconfig.defaults b/examples/peripherals/isp/dma_input/sdkconfig.defaults new file mode 100644 index 00000000000..cc641ea6033 --- /dev/null +++ b/examples/peripherals/isp/dma_input/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_SPIRAM=y