From 592c1e3b3293ab8446d87ff034644a6333373602 Mon Sep 17 00:00:00 2001 From: Daniel Kampert Date: Mon, 22 Apr 2024 15:20:36 +0200 Subject: [PATCH 01/26] Feature Generic History Storage for e.g. sensor data. - Adds a component that simpifies storage of sensor reading to flash. - Handles automaticallt removing old data etc. - Easy way to read out. --- app/CMakeLists.txt | 1 + app/Kconfig | 16 +- .../zswatch_nrf5340_cpuapp_5.conf | 2 - app/boards/debug.conf | 4 +- app/boards/native_posix.conf | 1 + app/boards/release.conf | 2 +- app/src/applications/battery/battery_app.c | 123 +++++----- app/src/applications/battery/battery_ui.c | 2 +- app/src/applications/battery/battery_ui.h | 2 + app/src/basic_battery/Kconfig | 3 + app/src/basic_battery/battery.c | 51 ++-- app/src/events/battery_event.c | 4 - app/src/history/CMakeLists.txt | 2 + app/src/history/Kconfig | 3 + app/src/history/zsw_history.c | 232 ++++++++++++++++++ app/src/history/zsw_history.h | 66 +++++ app/src/main.c | 2 +- app/src/sensors/zsw_light_sensor.c | 2 +- 18 files changed, 411 insertions(+), 107 deletions(-) create mode 100644 app/src/basic_battery/Kconfig create mode 100644 app/src/history/CMakeLists.txt create mode 100644 app/src/history/Kconfig create mode 100644 app/src/history/zsw_history.c create mode 100644 app/src/history/zsw_history.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 96633aaa..7abfb531 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -31,6 +31,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(ZSWatchFW) add_subdirectory(drivers) +add_subdirectory(src/history) add_subdirectory(src/applications) add_subdirectory(src/ui/watchfaces) add_subdirectory(src/sensors) diff --git a/app/Kconfig b/app/Kconfig index b870a3b3..7d86abcb 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -19,11 +19,6 @@ menu "ZSWatch" prompt "Activate the application 'Accelerometer'" default y - config APPLICATIONS_USE_BATTERY - bool - prompt "Activate the application 'Battery'" - default y - config APPLICATIONS_USE_COMPASS bool prompt "Activate the application 'Compass'" @@ -70,6 +65,7 @@ menu "ZSWatch" bool prompt "Activate the application 'PPT remote'" default n + endmenu menu "Watchface" @@ -224,10 +220,16 @@ menu "ZSWatch" endmenu menu "Misc" - config MENU_ENABLE_SYSTEM_RESET + config MISC_ENABLE_SYSTEM_RESET bool prompt "Enable a system reset via button 3" default n + + config MISC_HISTORY_MAX_LENGTH + int + range 10 65535 + prompt "The maximum history length in samples" + default 672 endmenu menu "Custom drivers" @@ -239,6 +241,8 @@ menu "ZSWatch" module-str = ZSW_APP source "subsys/logging/Kconfig.template.log_config" + rsource "src/basic_battery/Kconfig" + rsource "src/history/Kconfig" rsource "src/sensors/Kconfig" rsource "src/sensor_fusion/Kconfig" rsource "src/ble/Kconfig" diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf index c2368b48..5580bebd 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf @@ -42,8 +42,6 @@ CONFIG_MFD_NPM1300_INIT_PRIORITY=51 CONFIG_REGULATOR_NPM1300_COMMON_INIT_PRIORITY=52 CONFIG_REGULATOR_NPM1300_INIT_PRIORITY=53 -CONFIG_APPLICATIONS_USE_BATTERY=n - CONFIG_SETTINGS_NVS=y CONFIG_NVS=y diff --git a/app/boards/debug.conf b/app/boards/debug.conf index be0da1eb..d36a8897 100644 --- a/app/boards/debug.conf +++ b/app/boards/debug.conf @@ -24,7 +24,7 @@ CONFIG_ZSW_SENSORS_LOG_LEVEL_WRN=y CONFIG_ZSW_BLE_LOG_LEVEL_WRN=y CONFIG_ZSW_SETTINGS_APP_LOG_LEVEL_WRN=y CONFIG_ZSW_APP_LOG_LEVEL_DBG=y -CONFIG_MENU_ENABLE_SYSTEM_RESET=y +CONFIG_MISC_ENABLE_SYSTEM_RESET=y CONFIG_LV_USE_LOG=y -CONFIG_LV_LOG_LEVEL_WARN=y \ No newline at end of file +CONFIG_LV_LOG_LEVEL_WARN=y diff --git a/app/boards/native_posix.conf b/app/boards/native_posix.conf index 4d63cdac..0a1241bc 100644 --- a/app/boards/native_posix.conf +++ b/app/boards/native_posix.conf @@ -17,6 +17,7 @@ CONFIG_APDS9306_IS_APDS9306_065=n CONFIG_MAX30101_MULTI_LED_MODE=n CONFIG_APDS9306=n CONFIG_PINCTRL=n +CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_GPIO=y CONFIG_INPUT=y diff --git a/app/boards/release.conf b/app/boards/release.conf index 08704112..08bfe779 100644 --- a/app/boards/release.conf +++ b/app/boards/release.conf @@ -17,4 +17,4 @@ CONFIG_TASK_WDT=y CONFIG_TASK_WDT_MIN_TIMEOUT=1000 CONFIG_TASK_WDT_HW_FALLBACK=y -CONFIG_MENU_ENABLE_SYSTEM_RESET=n \ No newline at end of file +CONFIG_MISC_ENABLE_SYSTEM_RESET=n \ No newline at end of file diff --git a/app/src/applications/battery/battery_app.c b/app/src/applications/battery/battery_app.c index e85ba03f..50433449 100644 --- a/app/src/applications/battery/battery_app.c +++ b/app/src/applications/battery/battery_app.c @@ -4,6 +4,7 @@ #include #include +#include "history/zsw_history.h" #include "battery/battery_ui.h" #include "events/battery_event.h" #include "managers/zsw_app_manager.h" @@ -11,12 +12,10 @@ #include "fuel_gauge/zsw_pmic.h" #include "battery_ui.h" -LOG_MODULE_REGISTER(pmic_app, LOG_LEVEL_WRN); - -#define SETTING_BATTERY_HIST "battery/hist" - -#define MAX_SAMPLES (7 * 24 * 4) // 7 days of 15 minute samples -#define SAMPLE_INTERVAL (15 * 60 * 1000) // 15 minutes in milliseconds +#define SETTING_BATTERY_HIST "battery/hist" +#define SAMPLE_INTERVAL_MIN 15 +#define SAMPLE_INTERVAL_MS (SAMPLE_INTERVAL_MIN * 60 * 1000) +#define MAX_SAMPLES (7 * 24 * (60 / SAMPLE_INTERVAL_MIN)) // One week of 15 minute samples static void battery_app_start(lv_obj_t *root, lv_group_t *group); static void battery_app_stop(void); @@ -24,16 +23,8 @@ static void battery_app_stop(void); static void zbus_battery_sample_data_callback(const struct zbus_channel *chan); static void on_battery_hist_clear_cb(void); -typedef struct battery_sample_t { - uint8_t mv_with_decimals; // Calced by: 3.65V - 2 => 1.65 => 165 - uint8_t percent; -} battery_sample_t; - -typedef struct battery_storage_t { - uint16_t first_sample_index; - uint16_t num_samples; - battery_sample_t samples[MAX_SAMPLES]; -} battery_storage_t; +static uint8_t compresse_voltage_in_byte(int mV); +static int decompress_voltage_from_byte(uint8_t voltage_byte); ZBUS_CHAN_DECLARE(battery_sample_data_chan); ZBUS_LISTENER_DEFINE(battery_app_battery_event, zbus_battery_sample_data_callback); @@ -41,7 +32,15 @@ ZBUS_CHAN_ADD_OBS(battery_sample_data_chan, battery_app_battery_event, 1); ZSW_LV_IMG_DECLARE(battery_app_icon); -static battery_storage_t battery_context = {0}; +LOG_MODULE_REGISTER(pmic_app, LOG_LEVEL_WRN); + +typedef struct { + uint8_t mv_with_decimals; + uint8_t percent; +} zsw_battery_sample_t; + +static zsw_battery_sample_t samples[MAX_SAMPLES]; +static zsw_history_t battery_context; static uint64_t last_battery_sample_time = 0; static application_t app = { @@ -53,16 +52,18 @@ static application_t app = { static void battery_app_start(lv_obj_t *root, lv_group_t *group) { - battery_sample_t *sample; + zsw_battery_sample_t sample; struct battery_sample_event initial_sample; + #if CONFIG_DT_HAS_NORDIC_NPM1300_ENABLED - battery_ui_show(root, on_battery_hist_clear_cb, battery_context.num_samples + 1, true); + battery_ui_show(root, on_battery_hist_clear_cb, zsw_history_samples(&battery_context) + 1, true); #else - battery_ui_show(root, on_battery_hist_clear_cb, battery_context.num_samples + 1, false); + battery_ui_show(root, on_battery_hist_clear_cb, zsw_history_samples(&battery_context) + 1, false); #endif - for (int i = 0; i < battery_context.num_samples; i++) { - sample = &battery_context.samples[(battery_context.first_sample_index + i) % MAX_SAMPLES]; - battery_ui_add_measurement(sample->percent, (sample->mv_with_decimals * 10) + 2000); + + for (int i = 0; i < zsw_history_samples(&battery_context); i++) { + zsw_history_get(&battery_context, &sample, i); + battery_ui_add_measurement(sample.percent, decompress_voltage_from_byte(sample.mv_with_decimals)); } if (zbus_chan_read(&battery_sample_data_chan, &initial_sample, K_MSEC(100)) == 0) { @@ -77,31 +78,20 @@ static void battery_app_stop(void) battery_ui_remove(); } -static void add_battery_sample(const struct battery_sample_event *event) -{ - int next_battery_sample_index = (battery_context.first_sample_index + battery_context.num_samples) % MAX_SAMPLES; - battery_context.samples[next_battery_sample_index].mv_with_decimals = ((event->mV - 2000) / 1000) * 100 + (( - event->mV / 10) % 100); - battery_context.samples[next_battery_sample_index].percent = event->percent; - - battery_context.num_samples++; - if (battery_context.num_samples > MAX_SAMPLES) { - battery_context.first_sample_index = (battery_context.first_sample_index + 1) % MAX_SAMPLES; - battery_context.num_samples = MAX_SAMPLES; - } - LOG_DBG("%d, %d, %d", battery_context.first_sample_index, battery_context.num_samples, next_battery_sample_index); -} - static void zbus_battery_sample_data_callback(const struct zbus_channel *chan) { const struct battery_sample_event *event = zbus_chan_const_msg(chan); - if ((k_uptime_get() - last_battery_sample_time) >= SAMPLE_INTERVAL) { - add_battery_sample(event); - int ret = settings_save_one(SETTING_BATTERY_HIST, &battery_context, sizeof(battery_storage_t)); - if (ret) { - LOG_ERR("Error during saving of battery_context.samples %d", ret); + if ((k_uptime_get() - last_battery_sample_time) >= SAMPLE_INTERVAL_MS) { + zsw_battery_sample_t sample; + sample.mv_with_decimals = compresse_voltage_in_byte(event->mV); + sample.percent = event->percent; + + zsw_history_add(&battery_context, &sample); + if (zsw_history_save(&battery_context)) { + LOG_ERR("Error during saving of battery samples!"); } + last_battery_sample_time = k_uptime_get(); battery_ui_add_measurement(event->percent, event->mV); } @@ -110,36 +100,35 @@ static void zbus_battery_sample_data_callback(const struct zbus_channel *chan) static void on_battery_hist_clear_cb(void) { - memset(battery_context.samples, 0, sizeof(battery_context.samples)); + zsw_history_del(&battery_context); if (settings_delete(SETTING_BATTERY_HIST) != 0) { LOG_ERR("Error during settings_delete!"); } } -static int battery_load_state(const char *p_key, size_t len, - settings_read_cb read_cb, void *p_cb_arg, void *p_param) +static uint8_t compresse_voltage_in_byte(int mV) { - ARG_UNUSED(p_key); + uint8_t voltage_byte = 0; - if (len != sizeof(battery_storage_t)) { - return -EINVAL; + // Only support 3V to 5V + if (mV < 3000) { + mV = 3000; + } else if (mV >= 5000) { + mV = 5000; } - int num_bytes_read = read_cb(p_cb_arg, &battery_context, len); - LOG_DBG("Read %d bytes", num_bytes_read); - - LOG_DBG("Number samples: %d", battery_context.num_samples); - - if (num_bytes_read == 0) { - LOG_ERR("Currupt battery settings data"); - } else if (num_bytes_read != sizeof(battery_storage_t)) { - LOG_WRN("No battery settings data read"); - return -ENODATA; - } - - LOG_DBG("Loaded battery history data"); + // Voltage is always above 3000 mV and below 5000 mV + // Store first digit in the byte and the rest is decimals in 10mV resolution + voltage_byte = (mV / 1000); // Gives a 3 or a 4 + voltage_byte -= 3; // Gives a 0 or 1 representing 3V or 4V + voltage_byte *= 100; // Shifts the value to the left by 2 digits + voltage_byte += (mV / 10) % 100; // Adds the decimals + return voltage_byte; +} - return 0; +static int decompress_voltage_from_byte(uint8_t voltage_byte) +{ + return (voltage_byte * 10) + 3000; } static int battery_app_add(void) @@ -151,15 +140,13 @@ static int battery_app_add(void) return -EFAULT; } - if (settings_load_subtree_direct(SETTING_BATTERY_HIST, battery_load_state, NULL)) { + zsw_history_init(&battery_context, MAX_SAMPLES, sizeof(zsw_battery_sample_t), samples, SETTING_BATTERY_HIST); + + if (zsw_history_load(&battery_context)) { LOG_ERR("Error during settings_load_subtree!"); return -EFAULT; } - if (settings_delete(SETTING_BATTERY_HIST) != 0) { - LOG_ERR("Error during settings_delete!"); - } - return 0; } diff --git a/app/src/applications/battery/battery_ui.c b/app/src/applications/battery/battery_ui.c index e0817621..2a795a0b 100644 --- a/app/src/applications/battery/battery_ui.c +++ b/app/src/applications/battery/battery_ui.c @@ -238,7 +238,7 @@ void ui_Screen1_screen_init(lv_obj_t *ui_Screen1) lv_obj_set_x(ui_Label2, 20); lv_label_set_text(ui_Label2, "nPM1300"); } else { - lv_label_set_text(ui_Label2, "Battery (15 min)"); + lv_label_set_text_fmt(ui_Label2, "Battery (%d min)", BATTERY_APP_SAMPLE_INTERVAL_MIN); } lv_obj_set_style_text_color(ui_Label2, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT); lv_obj_set_style_text_opa(ui_Label2, 255, LV_PART_MAIN | LV_STATE_DEFAULT); diff --git a/app/src/applications/battery/battery_ui.h b/app/src/applications/battery/battery_ui.h index e74dd270..018e1d62 100644 --- a/app/src/applications/battery/battery_ui.h +++ b/app/src/applications/battery/battery_ui.h @@ -4,6 +4,8 @@ #include #include +#define BATTERY_APP_SAMPLE_INTERVAL_MIN 1 + typedef void(*on_clear_history)(void); void battery_ui_show(lv_obj_t *root, on_clear_history clear_hist_cb, int max_samples, bool include_pmic_ui); diff --git a/app/src/basic_battery/Kconfig b/app/src/basic_battery/Kconfig new file mode 100644 index 00000000..5698bb11 --- /dev/null +++ b/app/src/basic_battery/Kconfig @@ -0,0 +1,3 @@ +module = ZSW_BATTERY +module-str = ZSW_BATTERY +source "subsys/logging/Kconfig.template.log_config" \ No newline at end of file diff --git a/app/src/basic_battery/battery.c b/app/src/basic_battery/battery.c index 4e222a1e..1f9551a1 100644 --- a/app/src/basic_battery/battery.c +++ b/app/src/basic_battery/battery.c @@ -16,15 +16,14 @@ #include #include #include +#include #include "events/battery_event.h" -LOG_MODULE_REGISTER(BATTERY, LOG_LEVEL_WRN); +LOG_MODULE_REGISTER(BATTERY, CONFIG_ZSW_BATTERY_LOG_LEVEL); #define VBATT DT_PATH(vbatt) -#define BATTERY_SAMPLE_INTETRVAL_MINUTES 5 - struct battery_level_point { /** Remaining life at #lvl_mV. */ uint16_t lvl_pptt; @@ -33,6 +32,16 @@ struct battery_level_point { uint16_t lvl_mV; }; +/** A discharge curve specific to the power source. */ +static const struct battery_level_point levels[] = { + /* + Battery supervisor cuts power at 3500mA so treat that as 0% + This is very basic and the percentage will not be exact. + */ + { 10000, 4150 }, + { 0, 3500 }, +}; + static void handle_battery_sample_timeout(struct k_work *item); K_WORK_DELAYABLE_DEFINE(battery_sample_work, handle_battery_sample_timeout); @@ -40,6 +49,9 @@ K_WORK_DELAYABLE_DEFINE(battery_sample_work, handle_battery_sample_timeout); ZBUS_CHAN_DECLARE(battery_sample_data_chan); #if DT_IO_CHANNELS_INPUT(VBATT) + +#define BATTERY_SAMPLE_INTETRVAL_MINUTES 5 + /* This board uses a divider that reduces max voltage to * reference voltage (600 mV). */ @@ -189,11 +201,11 @@ static int battery_sample(void) if (dcp->output_ohm != 0) { rc = val * (uint64_t)dcp->full_ohm / dcp->output_ohm; - LOG_INF("raw %u ~ %u mV => %d mV\n", + LOG_INF("raw %u ~ %u mV => %d mV", ddp->raw, val, rc); } else { rc = val; - LOG_INF("raw %u ~ %u mV\n", ddp->raw, val); + LOG_INF("raw %u ~ %u mV", ddp->raw, val); } } } @@ -233,6 +245,8 @@ SYS_INIT(battery_setup, APPLICATION, CONFIG_DEFAULT_CONFIGURATION_DRIVER_INIT_PR #else +#define BATTERY_SAMPLE_INTETRVAL_MINUTES 1 + static int battery_measure_enable(bool enable) { return 0; @@ -240,50 +254,45 @@ static int battery_measure_enable(bool enable) static int battery_sample(void) { - return 4000; +#ifdef CONFIG_ARCH_POSIX + return (sys_rand32_get() % (levels[0].lvl_mV - levels[1].lvl_mV)) + levels[1].lvl_mV; +#else + // No random driver for nRF53DK available. So we return 0. + return 0; +#endif } static unsigned int battery_level_pptt(unsigned int batt_mV, const struct battery_level_point *curve) { - return 10000; + return ((float)batt_mV / levels[0].lvl_mV) * levels[0].lvl_pptt; } #endif // VBATT -/** A discharge curve specific to the power source. */ -static const struct battery_level_point levels[] = { - /* - Battery supervisor cuts power at 3500mA so treat that as 0% - This is very basic and the percentage will not be exact. - */ - { 10000, 4150 }, - { 0, 3500 }, -}; - static int get_battery_status(int *mV, int *percent) { unsigned int batt_pptt; int rc = battery_measure_enable(true); if (rc != 0) { - LOG_ERR("Failed initialize battery measurement: %d\n", rc); + LOG_ERR("Failed initialize battery measurement: %d", rc); return -1; } // From https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/boards/nrf/battery/src/main.c *mV = battery_sample(); if (*mV < 0) { - LOG_ERR("Failed to read battery voltage: %d\n", *mV); + LOG_ERR("Failed to read battery voltage: %d", *mV); return -1; } batt_pptt = battery_level_pptt(*mV, levels); - LOG_DBG("%d mV; %u pptt\n", *mV, batt_pptt); + LOG_DBG("%d mV; %u pptt", *mV, batt_pptt); *percent = batt_pptt / 100; rc = battery_measure_enable(false); if (rc != 0) { - LOG_ERR("Failed disable battery measurement: %d\n", rc); + LOG_ERR("Failed disable battery measurement: %d", rc); return -1; } return 0; diff --git a/app/src/events/battery_event.c b/app/src/events/battery_event.c index a0a3ebf6..e0e657d6 100644 --- a/app/src/events/battery_event.c +++ b/app/src/events/battery_event.c @@ -5,10 +5,6 @@ ZBUS_CHAN_DEFINE(battery_sample_data_chan, struct battery_sample_event, NULL, NULL, -#ifdef CONFIG_APPLICATIONS_USE_BATTERY - ZBUS_OBSERVERS(watchface_battery_event, zsw_phone_app_publisher_battery_event, battery_app_battery_event), -#else ZBUS_OBSERVERS(watchface_battery_event, zsw_phone_app_publisher_battery_event), -#endif ZBUS_MSG_INIT() ); \ No newline at end of file diff --git a/app/src/history/CMakeLists.txt b/app/src/history/CMakeLists.txt new file mode 100644 index 00000000..168d47bb --- /dev/null +++ b/app/src/history/CMakeLists.txt @@ -0,0 +1,2 @@ +FILE(GLOB sensor_sources *.c) +target_sources(app PRIVATE ${sensor_sources}) \ No newline at end of file diff --git a/app/src/history/Kconfig b/app/src/history/Kconfig new file mode 100644 index 00000000..fa2cef50 --- /dev/null +++ b/app/src/history/Kconfig @@ -0,0 +1,3 @@ +module = ZSW_HISTORY +module-str = ZSW_HISTORY +source "subsys/logging/Kconfig.template.log_config" \ No newline at end of file diff --git a/app/src/history/zsw_history.c b/app/src/history/zsw_history.c new file mode 100644 index 00000000..05ce2562 --- /dev/null +++ b/app/src/history/zsw_history.c @@ -0,0 +1,232 @@ +#include +#include +#include + +#include +#include +#include + +#include "zsw_history.h" + +#define ZSW_HISTORY_HEADER_EXTENSION "head" +#define ZSW_HISTORY_DATA_EXTENSION "data" + +// Text + 1 byte (_) + 6 byte extension (header) + 1 byte (\0) +static char key_data[ZSW_HISTORY_MAX_KEY_LENGTH + 8]; +static char key_header[ZSW_HISTORY_MAX_KEY_LENGTH + 8]; + +LOG_MODULE_REGISTER(zsw_history, CONFIG_ZSW_HISTORY_LOG_LEVEL); + +static int zsw_history_load_header_cb(const char *p_key, size_t len, settings_read_cb read_cb, void *p_cb_arg, + void *p_param) +{ + zsw_history_t *p_history; + zsw_history_t temp_stored_history; + uint32_t num_bytes_header; + + p_history = (zsw_history_t *)p_param; + + num_bytes_header = read_cb(p_cb_arg, &temp_stored_history, sizeof(zsw_history_t)); + LOG_DBG("Read %u header bytes, expecting: %d", num_bytes_header, sizeof(zsw_history_t)); + + // In case data structure or the user changed either sample size or number of max samples we need to handle that. + if ((num_bytes_header == 0) || (num_bytes_header != sizeof(zsw_history_t))) { + LOG_ERR("Invalid header. Struct size changed!"); + zsw_history_del(p_history); + } else if (temp_stored_history.max_samples != p_history->max_samples) { + LOG_ERR("max_samples does not match what's stored in settings. Erasing history."); + zsw_history_del(p_history); + } else if (temp_stored_history.sample_size != p_history->sample_size) { + LOG_ERR("sample_size does not match what's stored in settings. Erasing history."); + zsw_history_del(p_history); + } else { + // Everything is fine, we can load the history + p_history->write_index = temp_stored_history.write_index; + p_history->num_samples = temp_stored_history.num_samples; + } + + return 0; +} + +static int zsw_history_load_data_cb(const char *p_key, size_t len, settings_read_cb read_cb, void *p_cb_arg, + void *p_param) +{ + zsw_history_t *history; + uint32_t num_bytes_data; + + history = (zsw_history_t *)p_param; + + num_bytes_data = read_cb(p_cb_arg, history->samples, len); + LOG_DBG("Read %u data bytes", num_bytes_data); + + if ((num_bytes_data == 0) || (num_bytes_data != len) || + (num_bytes_data % history->sample_size) != 0) { + LOG_ERR("Invalid data!"); + return -EFAULT; + } + + return 0; +} + +int zsw_history_init(zsw_history_t *p_history, uint32_t max_samples, uint8_t sample_size, void *p_samples, + const char *p_key) +{ + int32_t error; + + __ASSERT((p_history != NULL) && (p_samples != NULL) && (p_key != NULL), "Invalid parameters for zsw_history_init"); + + p_history->write_index = 0; + p_history->num_samples = 0; + p_history->max_samples = max_samples; + p_history->sample_size = sample_size; + p_history->samples = p_samples; + + memset(p_samples, 0, max_samples * sample_size); + strcpy(p_history->key, p_key); + + error = settings_subsys_init(); + if (error) { + LOG_ERR("Error during settings initialization! Error: %i", error); + return -EFAULT; + } + + return 0; +} + +int zsw_history_del(zsw_history_t *p_history) +{ + int32_t error; + + __ASSERT(p_history != NULL, "Invalid parameter for zsw_history_del"); + + memset(p_history->samples, 0, p_history->max_samples * p_history->sample_size); + p_history->write_index = 0; + p_history->num_samples = 0; + + // First: Delete the header + sprintf(key_header, "%s/%s", p_history->key, ZSW_HISTORY_HEADER_EXTENSION); + error = settings_delete(key_header); + if (error) { + LOG_ERR("Error during erasing the header! Error: %i", error); + return -EFAULT; + } + + // Second: Delete the data + sprintf(key_data, "%s/%s", p_history->key, ZSW_HISTORY_DATA_EXTENSION); + error = settings_delete(key_data); + if (error) { + LOG_ERR("Error during erasing the data! Error: %i", error); + return -EFAULT; + } + + zsw_history_save(p_history); + + return 0; +} + +void zsw_history_add(zsw_history_t *p_history, const void *p_sample) +{ + uint8_t *start; + + __ASSERT((p_history != NULL) && (p_sample != NULL), "Invalid parameters for zsw_history_add"); + + start = p_history->samples; + start += p_history->sample_size * p_history->write_index; + + LOG_DBG("Add sample with size %d at index %d", p_history->sample_size, p_history->write_index); + memcpy(start, p_sample, p_history->sample_size); + + if (p_history->write_index < (p_history->max_samples - 1)) { + p_history->write_index++; + } else { + p_history->write_index = 0; + } + + p_history->num_samples = MIN(p_history->num_samples + 1, p_history->max_samples); +} + +void zsw_history_get(const zsw_history_t *p_history, void *p_sample, uint32_t index) +{ + uint8_t *start; + + __ASSERT((p_history != NULL) && (p_sample != NULL) && + index < p_history->max_samples, "Invalid parameters for zsw_history_get"); + + start = (uint8_t *)p_history->samples; + + if (p_history->num_samples == p_history->max_samples) { + start += ((p_history->write_index + index) % p_history->max_samples) * p_history->sample_size; + } else { + start += index * p_history->sample_size; + } + + memcpy(p_sample, start, p_history->sample_size); +} + +int zsw_history_load(zsw_history_t *p_history) +{ + int32_t error; + + __ASSERT((p_history != NULL) && + (strlen(p_history->key) <= ZSW_HISTORY_MAX_KEY_LENGTH), "Invalid parameters for zsw_history_load"); + + sprintf(key_header, "%s/%s", p_history->key, ZSW_HISTORY_HEADER_EXTENSION); + error = settings_load_subtree_direct(key_header, zsw_history_load_header_cb, p_history); + + if (error) { + LOG_ERR("Error during header loading! Error: %i. Erasing history.", error); + zsw_history_del(p_history); + } + + LOG_DBG("Load header with key %s", key_header); + LOG_DBG(" Num: %u", p_history->max_samples); + LOG_DBG(" Sample size: %u", p_history->sample_size); + LOG_DBG(" Write index: %u", p_history->write_index); + LOG_DBG(" Num samples: %u", p_history->num_samples); + + // Load the data + sprintf(key_data, "%s/%s", p_history->key, ZSW_HISTORY_DATA_EXTENSION); + error = settings_load_subtree_direct(key_data, zsw_history_load_data_cb, p_history); + LOG_DBG("Load data with key %s", key_data); + if (error) { + LOG_ERR("Error during data loading! Error: %i", error); + zsw_history_del(p_history); + return 0; + } + + return 0; +} + +int zsw_history_save(zsw_history_t *p_history) +{ + int32_t error; + + __ASSERT((p_history != NULL) && + (strlen(p_history->key) <= ZSW_HISTORY_MAX_KEY_LENGTH), "Invalid parameters for zsw_history_save"); + + // First: Store the header + sprintf(key_header, "%s/%s", p_history->key, ZSW_HISTORY_HEADER_EXTENSION); + LOG_DBG("Storing header with key %s", key_header); + error = settings_save_one(key_header, p_history, sizeof(zsw_history_t)); + if (error) { + LOG_ERR("Error during saving of history header! Error: %i", error); + return -EFAULT; + } + + // Second: Save the data + sprintf(key_data, "%s/%s", p_history->key, ZSW_HISTORY_DATA_EXTENSION); + error = settings_save_one(key_data, p_history->samples, p_history->write_index * p_history->sample_size); + if (error) { + LOG_ERR("Error during saving of history data! Error: %i", error); + return -EFAULT; + } + + return 0; +} + +int zsw_history_samples(zsw_history_t *p_history) +{ + __ASSERT(p_history != NULL, "Invalid parameters for zsw_history_samples"); + + return p_history->num_samples; +} \ No newline at end of file diff --git a/app/src/history/zsw_history.h b/app/src/history/zsw_history.h new file mode 100644 index 00000000..6d6ed4db --- /dev/null +++ b/app/src/history/zsw_history.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include + +#define ZSW_HISTORY_MAX_KEY_LENGTH 64 + +/** @brief ZSWatch history object definition. +*/ +typedef struct { + uint32_t write_index; + uint32_t max_samples; /**< Length of the sample storage in samples. */ + uint8_t sample_size; /**< Size of a sample in bytes. */ + uint32_t num_samples; /**< Number of valid samples stored. */ + char key[ZSW_HISTORY_MAX_KEY_LENGTH]; /**< */ + void *samples; /**< Pointer to sample storage. */ +} zsw_history_t; + +/** @brief Initialize a history object. + * @param p_history History object + * @param max_samples Length of the sample storage in samples + * @param sample_size Size of one sample in the sample storage + * @param p_samples Pointer to the sample storage + * @param p_key Pointer to the NVS key (max. length 64 bytes) + * @return 0 when successful +*/ +int zsw_history_init(zsw_history_t *p_history, uint32_t max_samples, uint8_t sample_size, void *samples, + const char *p_key); + +/** @brief Clear the sample storage and reset the sample counter. + * @param p_history History object + * @return 0 when successful +*/ +int zsw_history_del(zsw_history_t *p_history); + +/** @brief Add a sample to the history. + * @param p_history History object + * @param p_sample Pointer to sample object + * @return 0 when successful +*/ +void zsw_history_add(zsw_history_t *p_history, const void *p_sample); + +/** @brief Get a sample from the history. + * @param p_history History object + * @param p_sample Pointer to sample object + * @param index Sample index +*/ +void zsw_history_get(const zsw_history_t *p_history, void *p_sample, uint32_t index); + +/** @brief Load a history from the NVS. + * @param p_history History object + * @return 0 when successfulconst +*/ +int zsw_history_load(zsw_history_t *p_history); + +/** @brief Writes the history in the NVS. + * @param p_history History object + * @return 0 when successful +*/ +int zsw_history_save(zsw_history_t *p_history); + +/** @brief Get the number of samples stored in the history. + * @param p_history History object + * @return Number of samples +*/ +int zsw_history_samples(zsw_history_t *p_history); \ No newline at end of file diff --git a/app/src/main.c b/app/src/main.c index bf9c4513..a64c403f 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -137,7 +137,7 @@ static void run_input_work(struct k_work *item) switch (container->event.code) { // Button event case (INPUT_KEY_Y): { -#ifdef CONFIG_MENU_ENABLE_SYSTEM_RESET +#ifdef CONFIG_MISC_ENABLE_SYSTEM_RESET LOG_INF("Force restart"); retained.off_count += 1; diff --git a/app/src/sensors/zsw_light_sensor.c b/app/src/sensors/zsw_light_sensor.c index 81db5f47..19ef3f15 100644 --- a/app/src/sensors/zsw_light_sensor.c +++ b/app/src/sensors/zsw_light_sensor.c @@ -33,7 +33,7 @@ static const struct device *const apds9306 = DEVICE_DT_GET_OR_NULL(DT_NODELABEL( static void zbus_periodic_slow_callback(const struct zbus_channel *chan) { - float light; + float light = 0.0; if (zsw_light_sensor_get_light(&light)) { return; From edf2f8bda49efeaa66b30e87a43a1f7a4d7ff173 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Thu, 23 May 2024 19:57:13 +0200 Subject: [PATCH 02/26] v3: Remove minimal watchface to save flash. --- app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf index 87d102f6..25341799 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_3.conf @@ -39,3 +39,8 @@ CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y CONFIG_PM_PARTITION_SIZE_LITTLEFS=0x200000 CONFIG_DEBUG_COREDUMP_BACKEND_OTHER=y + +# Save flash +CONFIG_WATCHFACE_ANALOG=n +CONFIG_WATCHFACE_MINIMAL=n +CONFIG_APPLICATIONS_USE_2048=n \ No newline at end of file From 323e612b1fe252f6b129f4b87428285e74cb47ed Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Fri, 31 May 2024 12:32:46 +0200 Subject: [PATCH 03/26] README: Add some videos to demo watch fatures. --- README.md | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index fe4c25ac..2916ab87 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ Smartwatch built from scratch, both hardware and software. Built on the [Zephyr
-**Synced remote control over BLE** +**UI and features** -[https://user-images.githubusercontent.com/64562059/234390129-321d4f35-cb4b-45e8-89d9-20ae292f34fc.mp4](https://github.com/jakkra/ZSWatch/assets/4318648/8d0f40c2-d519-4db1-8634-b43caa502cbe) +https://github.com/jakkra/ZSWatch/assets/4318648/ec1a94fd-a682-4559-9e68-f3e5bfcbe682

@@ -64,7 +64,6 @@ If you are interested in a kit, or want to get notified when the missing parts a - [Android phone communication](#android-phone-communication) - [iOS device communication](#ios-device-communication) - [PCB](#pcb) -- [ZSWatch v1 in action (Note old, not updated for latest HW and SW).](#zswatch-v1-in-action-note-old-not-updated-for-latest-hw-and-sw) - [Environment, Compiling and running the code](#environment-compiling-and-running-the-code) - [Writing apps for the Application Manager](#writing-apps-for-the-application-manager) - [Other tools](#other-tools) @@ -126,30 +125,19 @@ See more at https://github.com/jakkra/ZSWatch-Dock There are almost endless of posiblities for features that could be implemented, see [here for full progress](https://github.com/users/jakkra/projects/1) and in GitHub issues. ## Watchfaces -Alternative watch faces can be chosen by selecting one or many of the appropriate Kconfig.
-Swiping left to right will change the watchface. -for something else, and can then be disabled. -`CONFIG_WATCHFACE_ANALOG=n`
-`CONFIG_WATCHFACE_DIGITAL=y`
-`CONFIG_WATCHFACE_MINIMAL=y`
+https://github.com/jakkra/ZSWatch/assets/4318648/13e43401-1c00-40ab-866f-e6518e61940d +## Smartphone communication -To select watchface background see below config in prj.conf: +### Android phone communication +Fortunately there is a great Android app called [GadgetBridge](https://codeberg.org/Freeyourgadget) which handles everything needed on the phone side, such as notifications management, music control and so much more... The ZSWatch right now pretends to be one of the supported Smart Watches in Gadgetbridge, following the same API as it does. In future there may be a point adding native support, we'll see. -`CONFIG_WATCHFACE_BACKGROUND_SPACE=y`
-`CONFIG_WATCHFACE_BACKGROUND_FLOWER=n`
-`CONFIG_WATCHFACE_BACKGROUND_PLANET=n`
-`CONFIG_WATCHFACE_BACKGROUND_NONE=n`
+**Demo of doing HTTP requests over BLE through Gadgetbridge.** -

- -

-## Smartphone communication +https://github.com/jakkra/ZSWatch/assets/4318648/12d6e754-ceb3-4efd-9a75-d207aaeb0e82 -### Android phone communication -Fortunately there is a great Android app called [GadgetBridge](https://codeberg.org/Freeyourgadget) which handles everything needed on the phone side, such as notifications management, music control and so much more... The ZSWatch right now pretends to be one of the supported Smart Watches in Gadgetbridge, following the same API as it does. In future there may be a point adding native support, we'll see. #### Pairing - In the watch go to Settings -> Bluetooth -> Enable pairing @@ -159,6 +147,7 @@ Fortunately there is a great Android app called [GadgetBridge](https://codeberg. ### iOS device communication Apple exposes [Apple Notification Center Service](https://developer.apple.com/library/archive/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html) GATT server which handles notifications management on the phone side, music control is done in the same fashion using [Apple Media Service](https://developer.apple.com/library/archive/documentation/CoreBluetooth/Reference/AppleMediaService_Reference/Specification/Specification.html)... The ZSWatch communicates straight to the iOS with no extra Apps. + #### Pairing - In the watch go to Settings -> Bluetooth -> Enable pairing - Now go to your device settings -> Bluetooth and choose "ZSWatch" @@ -176,16 +165,6 @@ More info here: https://github.com/jakkra/ZSWatch-HW

-## ZSWatch v1 in action (Note old, not updated for latest HW and SW). -|*Music control*|*Accelerometer for step count and tap detection*| -|---|---| -| | | -|*Notifications from phone (Gmail here)*|*Settings*| -| | | - - -https://github.com/jakkra/ZSWatch/assets/4318648/8d8ec724-8145-4a30-b241-e69a8c2853bf - ## Environment, Compiling and running the code See [GETTING_STARTED.md](GETTING_STARTED.md) From a309a330ff3ce7fe98fd19cff2df163de2dfb0ae Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Fri, 31 May 2024 16:48:12 +0200 Subject: [PATCH 04/26] Workaround for Linux build getting black screen on some computers. See issue for more details https://github.com/zephyrproject-rtos/zephyr/issues/71410 Workaround is to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD. --- app/boards/native_posix.conf | 1 + app/src/drivers/zsw_display_control.c | 4 ++++ app/src/main.c | 10 ++++++++++ 3 files changed, 15 insertions(+) diff --git a/app/boards/native_posix.conf b/app/boards/native_posix.conf index 0a1241bc..c9330954 100644 --- a/app/boards/native_posix.conf +++ b/app/boards/native_posix.conf @@ -53,3 +53,4 @@ CONFIG_SPI_FLASH_LOADER=n CONFIG_BT_EXT_ADV=n CONFIG_SDL_DISPLAY_ZOOM_PCT=200 +CONFIG_LV_Z_FLUSH_THREAD=n \ No newline at end of file diff --git a/app/src/drivers/zsw_display_control.c b/app/src/drivers/zsw_display_control.c index 37c0a649..a3f4b35f 100644 --- a/app/src/drivers/zsw_display_control.c +++ b/app/src/drivers/zsw_display_control.c @@ -262,12 +262,16 @@ void zsw_display_control_set_brightness(uint8_t percent) static void lvgl_render(struct k_work *item) { + // Workaround due to https://github.com/zephyrproject-rtos/zephyr/issues/71410 + // we need to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD +#ifndef CONFIG_BOARD_NATIVE_POSIX const int64_t next_update_in_ms = lv_task_handler(); if (first_render_since_poweron) { zsw_display_control_set_brightness(last_brightness); first_render_since_poweron = false; } k_work_schedule(&lvgl_work, K_MSEC(next_update_in_ms)); +#endif } static void set_brightness_level(uint8_t brightness) diff --git a/app/src/main.c b/app/src/main.c index a64c403f..23126fe6 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -297,6 +297,16 @@ int main(void) // it has the required amount of stack. k_work_submit(&init_work); + // Workaround due to https://github.com/zephyrproject-rtos/zephyr/issues/71410 + // we need to run lv_task_handler from main thread and disable CONFIG_LV_Z_FLUSH_THREAD +#ifdef CONFIG_BOARD_NATIVE_POSIX + int64_t next_update_in_ms; + while (true) { + next_update_in_ms = lv_task_handler(); + k_msleep(next_update_in_ms); + } +#endif + return 0; } From 70403bdcfb82be548564253f7ea215af74ddbb30 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Fri, 31 May 2024 17:26:10 +0200 Subject: [PATCH 05/26] App picker: Fix overwrite of last opened app index. Caused re-opening application picker not to select the previously selected app. Caused by LVGL sending focus events to all child when deleting them all. In the focus event we store the last highlighted application, to select in next time we open the app picker. --- app/src/managers/zsw_app_manager.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/managers/zsw_app_manager.c b/app/src/managers/zsw_app_manager.c index 3897c8af..10e46903 100644 --- a/app/src/managers/zsw_app_manager.c +++ b/app/src/managers/zsw_app_manager.c @@ -44,14 +44,20 @@ static on_app_manager_cb_fn close_cb_func; static lv_obj_t *grid; static uint8_t last_index; static bool app_launch_only; +static bool is_deleting_app_picker; static lv_timer_t *async_app_start_timer; static lv_timer_t *async_app_close_timer; static void delete_application_picker(void) { if (grid != NULL) { + // When deleting the grid, we get callbacks for each row being deleted. + // Because LVGL will refocus one a new row when one is deleted. + // This causes the wrong last opened app index to be changed. + is_deleting_app_picker = true; lv_obj_del(grid); grid = NULL; + is_deleting_app_picker = false; } } @@ -59,7 +65,7 @@ static void row_focused(lv_event_t *e) { lv_obj_t *row = lv_event_get_target(e); int app_id = (int)lv_event_get_user_data(e); - if (row && lv_obj_get_child_cnt(row) > 0) { + if (row && lv_obj_get_child_cnt(row) > 0 && !is_deleting_app_picker) { // Don't show close button as last focused row if (apps[app_id]->private_list_index != num_visible_apps - 1) { last_index = app_id; From ff4708cd04b5838209209a22100014360fdbaa87 Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:26:55 +0200 Subject: [PATCH 06/26] Replace AoA guard --- app/src/ble/ble_aoa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ble/ble_aoa.c b/app/src/ble/ble_aoa.c index 7db8b6d2..507f01b9 100644 --- a/app/src/ble/ble_aoa.c +++ b/app/src/ble/ble_aoa.c @@ -15,7 +15,7 @@ */ #include #include -#ifdef CONFIG_BT_EXT_ADV +#ifdef CONFIG_BT_DF #include #include #include From 34d96aa47439af26287512b7a1f74665503cbbda Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:34:28 +0200 Subject: [PATCH 07/26] typo --- app/src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 23126fe6..e358e26a 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -82,7 +82,7 @@ static void run_input_work(struct k_work *item); static void run_init_work(struct k_work *item); static void run_wdt_work(struct k_work *item); -static void enable_bluetoth(void); +static void enable_bluetooth(void); static void print_retention_ram(void); static void enocoder_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data); static void click_feedback(struct _lv_indev_drv_t *drv, uint8_t e); @@ -213,7 +213,7 @@ static void run_init_work(struct k_work *item) zsw_display_control_sleep_ctrl(true); print_retention_ram(); zsw_notification_manager_init(); - enable_bluetoth(); + enable_bluetooth(); zsw_imu_init(); zsw_magnetometer_init(); zsw_pressure_sensor_init(); @@ -310,7 +310,7 @@ int main(void) return 0; } -static void enable_bluetoth(void) +static void enable_bluetooth(void) { int err; From 7183239f67863882f3a7574a1e561c211739ae8f Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Wed, 19 Jun 2024 08:57:52 +0200 Subject: [PATCH 08/26] Update astyle_format_west_command.py --- app/scripts/astyle_format_west_command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/astyle_format_west_command.py b/app/scripts/astyle_format_west_command.py index cf9a094b..037c8603 100644 --- a/app/scripts/astyle_format_west_command.py +++ b/app/scripts/astyle_format_west_command.py @@ -14,7 +14,7 @@ def __init__(self): super().__init__( "format", "Format the codebase", - """Use to format all .c and .h giles""", + """Use to format all .c and .h files""", ) def do_add_parser(self, parser_adder): From b271ddf0f0f5cf526ab90f48a0818229dc588006 Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:52:11 +0200 Subject: [PATCH 09/26] Update checkout CI version v3 is deprecated --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0dc0535e..57e34187 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: board: [zswatch_nrf5340_cpuapp@1, zswatch_nrf5340_cpuapp@3, zswatch_nrf5340_cpuapp@4, zswatch_nrf5340_cpuapp@5, native_posix, nrf5340dk_nrf5340_cpuapp] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: ZSWatch submodules: recursive @@ -71,4 +71,4 @@ jobs: name: ${{ matrix.board }}_${{ matrix.built_type }} path: | ZSWatch/fw_images - if-no-files-found: ignore \ No newline at end of file + if-no-files-found: ignore From 07a030089a2bbb60d1a27af2befe376e27cde3a1 Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Sat, 22 Jun 2024 10:51:44 +0200 Subject: [PATCH 10/26] rename Netcore overlay --- .../{hci_rpmsg.conf => hci_ipc.conf} | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) rename app/child_image/{hci_rpmsg.conf => hci_ipc.conf} (96%) diff --git a/app/child_image/hci_rpmsg.conf b/app/child_image/hci_ipc.conf similarity index 96% rename from app/child_image/hci_rpmsg.conf rename to app/child_image/hci_ipc.conf index f0ba348d..09ae24e5 100644 --- a/app/child_image/hci_rpmsg.conf +++ b/app/child_image/hci_ipc.conf @@ -1,47 +1,47 @@ -CONFIG_BT_EXT_ADV=y - -CONFIG_BT_CTLR=y -CONFIG_BT_LL_SW_SPLIT=y - -CONFIG_BT_CTLR_ADV_EXT=y -CONFIG_BT_CTLR_ADV_PERIODIC=y - -CONFIG_BT_CTLR_DF=y - -CONFIG_BT_CTLR_DF_SCAN_CTE_RX=n -CONFIG_BT_CTLR_DF_ANT_SWITCH_RX=n -CONFIG_BT_CTLR_DF_CTE_RX=n - -# Limit number of possible connection to decrease memory usage -CONFIG_BT_MAX_CONN=1 - -# Enable chaining of multiple CTEs in periodic advertising -CONFIG_BT_CTLR_ADVANCED_FEATURES=y -CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y -CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX=16 - -CONFIG_BT_CTLR_TX_PWR_0=y -CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191 - -# Enable chaining of multiple CTEs in periodic advertising -CONFIG_BT_CTLR_ADVANCED_FEATURES=y -CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y -CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX=16 - -CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=n -CONFIG_BT_BROADCASTER=y - -CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 -CONFIG_BT_CTLR_ADV_AUX_SET=2 -CONFIG_BT_TICKER_UPDATE=y - -CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y -# DFU over BT requires -# increase of ble throughput -CONFIG_BT_BUF_ACL_RX_SIZE=502 -CONFIG_BT_BUF_ACL_TX_SIZE=502 -CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 - -# Temporary fix as there is a strange behaviour with some Android -# phones. -CONFIG_BT_DATA_LEN_UPDATE=n +CONFIG_BT_EXT_ADV=y + +CONFIG_BT_CTLR=y +CONFIG_BT_LL_SW_SPLIT=y + +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_ADV_PERIODIC=y + +CONFIG_BT_CTLR_DF=y + +CONFIG_BT_CTLR_DF_SCAN_CTE_RX=n +CONFIG_BT_CTLR_DF_ANT_SWITCH_RX=n +CONFIG_BT_CTLR_DF_CTE_RX=n + +# Limit number of possible connection to decrease memory usage +CONFIG_BT_MAX_CONN=1 + +# Enable chaining of multiple CTEs in periodic advertising +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y +CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX=16 + +CONFIG_BT_CTLR_TX_PWR_0=y +CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191 + +# Enable chaining of multiple CTEs in periodic advertising +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y +CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX=16 + +CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=n +CONFIG_BT_BROADCASTER=y + +CONFIG_BT_EXT_ADV_MAX_ADV_SET=2 +CONFIG_BT_CTLR_ADV_AUX_SET=2 +CONFIG_BT_TICKER_UPDATE=y + +CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y +# DFU over BT requires +# increase of ble throughput +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=502 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 + +# Temporary fix as there is a strange behaviour with some Android +# phones. +CONFIG_BT_DATA_LEN_UPDATE=n From 99571fd0c87bd1d62eecaf513c407204cb8e6973 Mon Sep 17 00:00:00 2001 From: LDAB Date: Mon, 24 Jun 2024 09:41:35 +0200 Subject: [PATCH 11/26] Do not include the BLE HID if PPT app is disabled --- app/src/ble/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/ble/CMakeLists.txt b/app/src/ble/CMakeLists.txt index bd53db10..9661c4ea 100644 --- a/app/src/ble/CMakeLists.txt +++ b/app/src/ble/CMakeLists.txt @@ -5,6 +5,9 @@ target_sources(app PRIVATE ble_ams.c) target_sources(app PRIVATE ble_ancs.c) target_sources(app PRIVATE ble_cts.c) target_sources(app PRIVATE gadgetbridge/ble_gadgetbridge.c) -target_sources(app PRIVATE ble_hid.c) target_sources(app PRIVATE ble_http.c) -target_sources(app PRIVATE zsw_gatt_sensor_server.c) \ No newline at end of file +target_sources(app PRIVATE zsw_gatt_sensor_server.c) + +if(CONFIG_APPLICATIONS_USE_PPT_REMOTE) + target_sources(app PRIVATE ble_hid.c) +endif() From 76394bd95d7951623e36fd8e0ea8ac5834c03013 Mon Sep 17 00:00:00 2001 From: LDAB Date: Mon, 24 Jun 2024 10:55:41 +0200 Subject: [PATCH 12/26] use astyle as default formatter --- .vscode/settings.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 91455006..393430f8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,8 @@ "terminal.integrated.env.linux": { "GTK_PATH": "" }, - "search.useIgnoreFiles": false + "search.useIgnoreFiles": false, + "[c]": { + "editor.defaultFormatter": "chiehyu.vscode-astyle" + } } From 9947a4fe8ab97148f24eb37971371682b05ddf63 Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:54:11 +0200 Subject: [PATCH 13/26] Check HTTP compatility for Trivia App (#303) --- app/src/applications/trivia/trivia_app.c | 5 ++++- app/src/applications/trivia/trivia_ui.c | 19 +++++++++++++++---- app/src/applications/trivia/trivia_ui.h | 4 +++- app/src/ble/ble_ams.c | 7 +++---- app/src/ble/ble_ancs.c | 4 ++-- app/src/ble/ble_cts.c | 22 +++++++++++----------- app/src/ble/ble_cts.h | 5 ++++- 7 files changed, 42 insertions(+), 24 deletions(-) diff --git a/app/src/applications/trivia/trivia_app.c b/app/src/applications/trivia/trivia_app.c index c1158f61..f9d861f6 100644 --- a/app/src/applications/trivia/trivia_app.c +++ b/app/src/applications/trivia/trivia_app.c @@ -89,7 +89,10 @@ static void http_rsp_cb(ble_http_status_code_t status, cJSON *response) static void request_new_question() { - zsw_ble_http_get(HTTP_REQUEST_URL, http_rsp_cb); + /// @todo create a more generic error code that would cover when GadgetBridge doesn't allow HTTP over BLE, potentially a Systemwide pop-up + if (zsw_ble_http_get(HTTP_REQUEST_URL, http_rsp_cb) == -EINVAL) { + trivia_ui_not_supported(); + } } static void on_button_click(trivia_button_t trivia_button) diff --git a/app/src/applications/trivia/trivia_ui.c b/app/src/applications/trivia/trivia_ui.c index cd9319b8..dc528463 100644 --- a/app/src/applications/trivia/trivia_ui.c +++ b/app/src/applications/trivia/trivia_ui.c @@ -1,5 +1,7 @@ #include "trivia_ui.h" +#define CLOSE_TXT "Close" + static lv_obj_t *root_page = NULL; static lv_obj_t *question_lb; static lv_obj_t *mbox; @@ -72,7 +74,7 @@ void trivia_ui_close_popup(void) void trivia_ui_guess_feedback(bool correct) { char msg[sizeof("Your answer is correct!")]; - static const char *btns[] = {"More", "Close", ""}; + static const char *btns[] = {"More", CLOSE_TXT, ""}; sprintf(msg, "Your answer is %s!", correct ? "Correct" : "Wrong"); @@ -81,15 +83,24 @@ void trivia_ui_guess_feedback(bool correct) lv_obj_center(mbox); } +void trivia_ui_not_supported() +{ + static const char *btns[] = {CLOSE_TXT, NULL}; + + mbox = lv_msgbox_create(NULL, NULL, "Your phone does not support this app", btns, false); + lv_obj_add_event_cb(mbox, click_popup_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_center(mbox); +} + static void click_popup_event_cb(lv_event_t *e) { lv_obj_t *obj = lv_event_get_current_target(e); trivia_button_t trivia_button; - if (lv_msgbox_get_active_btn(obj) == 0) { - trivia_button = PLAY_MORE_BUTTON; - } else { + if (strcmp(lv_msgbox_get_active_btn_text(obj), CLOSE_TXT) == 0) { trivia_button = CLOSE_BUTTON; + } else { + trivia_button = PLAY_MORE_BUTTON; } click_callback(trivia_button); diff --git a/app/src/applications/trivia/trivia_ui.h b/app/src/applications/trivia/trivia_ui.h index 3dcc5ec8..84096bbe 100644 --- a/app/src/applications/trivia/trivia_ui.h +++ b/app/src/applications/trivia/trivia_ui.h @@ -20,4 +20,6 @@ void trivia_ui_update_question(uint8_t *buff); void trivia_ui_guess_feedback(bool correct); -void trivia_ui_close_popup(void); \ No newline at end of file +void trivia_ui_close_popup(void); + +void trivia_ui_not_supported(void); \ No newline at end of file diff --git a/app/src/ble/ble_ams.c b/app/src/ble/ble_ams.c index 5ea477c1..4f0dddd3 100644 --- a/app/src/ble/ble_ams.c +++ b/app/src/ble/ble_ams.c @@ -93,7 +93,6 @@ static void music_control_event_callback(const struct zbus_channel *chan) // Nothing to do break; } - } static void notify_rc_cb(struct bt_ams_client *ams_c, @@ -170,7 +169,7 @@ static void notify_eu_cb(struct bt_ams_client *ams_c, msg_buff[notif->len] = '\0'; LOG_DBG("AMS EU: %s %s", str_hex, msg_buff); - static struct ble_data_event evt_music_inf = { 0 }; + static struct ble_data_event evt_music_inf = {0}; if (notif->ent_attr.entity == BT_AMS_ENTITY_ID_TRACK && attr_val == BT_AMS_TRACK_ATTRIBUTE_ID_ARTIST) { @@ -199,7 +198,7 @@ static void notify_eu_cb(struct bt_ams_client *ams_c, if (notif->ent_attr.entity == BT_AMS_ENTITY_ID_PLAYER && attr_val == BT_AMS_PLAYER_ATTRIBUTE_ID_PLAYBACK_INFO) { - struct ble_data_event evt_music_state = { 0 }; + struct ble_data_event evt_music_state = {0}; evt_music_state.data.type = BLE_COMM_DATA_TYPE_MUSIC_STATE; @@ -326,7 +325,7 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { if (!err) { - LOG_INF("Security changed: level %u", level); + LOG_DBG("Security changed: level %u", level); if (bt_conn_get_security(conn) >= BT_SECURITY_L2) { discover_gattp(conn); diff --git a/app/src/ble/ble_ancs.c b/app/src/ble/ble_ancs.c index f30c66e3..6388788f 100644 --- a/app/src/ble/ble_ancs.c +++ b/app/src/ble/ble_ancs.c @@ -306,7 +306,7 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (!err) { - LOG_INF("Security changed: %s level %u", addr, level); + LOG_DBG("Security changed: %s level %u", addr, level); if (bt_conn_get_security(conn) >= BT_SECURITY_L2) { discovery_flags = ATOMIC_INIT(0); @@ -398,7 +398,7 @@ static void notif_attr_print(const struct bt_ancs_attr *attr) static int parse_notify(const struct bt_ancs_attr *attr) { - static struct ble_data_event evt = { 0 }; + static struct ble_data_event evt = {0}; switch (attr->attr_id) { case ATTR_ID_TITLE: diff --git a/app/src/ble/ble_cts.c b/app/src/ble/ble_cts.c index 8b83855c..9a24f395 100644 --- a/app/src/ble/ble_cts.c +++ b/app/src/ble/ble_cts.c @@ -25,7 +25,7 @@ #include "ble/ble_cts.h" #include "events/ble_event.h" -LOG_MODULE_REGISTER(ble_cts, LOG_LEVEL_WRN); +LOG_MODULE_REGISTER(ble_cts, CONFIG_ZSW_BLE_LOG_LEVEL); ZBUS_CHAN_DECLARE(ble_comm_data_chan); static struct bt_cts_client cts_c; @@ -35,16 +35,16 @@ static bool has_cts; /* Local copy of the current connection. */ static struct bt_conn *current_conn; -static const char *day_of_week[] = { "Unknown", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", - "Saturday", "Sunday" +static const char *day_of_week[] = {"Unknown", "Monday", "Tuesday", + "Wednesday", "Thursday", "Friday", + "Saturday", "Sunday" }; -static const char *month_of_year[] = { "Unknown", "January", "February", - "March", "April", "May", - "June", "July", "August", - "September", "October", "November", - "December" +static const char *month_of_year[] = {"Unknown", "January", "February", + "March", "April", "May", + "June", "July", "August", + "September", "October", "November", + "December" }; static void read_current_time_cb(struct bt_cts_client *cts_c, struct bt_cts_current_time *current_time, int err); @@ -83,7 +83,7 @@ static void current_time_print(struct bt_cts_current_time *current_time) void publish_time_event(struct bt_cts_current_time *current_time) { - struct ble_data_event evt_time_inf = { 0 }; + struct ble_data_event evt_time_inf = {0}; struct tm tm = { .tm_sec = current_time->exact_time_256.seconds, @@ -256,4 +256,4 @@ void ble_cts_init(void) } LOG_INF("Starting Current Time client"); -} \ No newline at end of file +} diff --git a/app/src/ble/ble_cts.h b/app/src/ble/ble_cts.h index 89718f0a..78debdbd 100644 --- a/app/src/ble/ble_cts.h +++ b/app/src/ble/ble_cts.h @@ -2,4 +2,7 @@ #include -void ble_cts_init(void); \ No newline at end of file +/** + * @brief Init Central Time Service + */ +void ble_cts_init(void); From a44528eed11d69c32e33f34ff01716f3de794cc3 Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Thu, 20 Jun 2024 22:04:10 +0200 Subject: [PATCH 14/26] Use latest upload-artifact v3 is deprecated --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 57e34187..aa7eb33e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: west build app --build-dir ${{ matrix.board }}_${{ matrix.built_type }} -p -b ${{ matrix.board }} -- -DOVERLAY_CONFIG=boards/${{ matrix.built_type }}.conf - name : Upload Firmware - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.3.3 with: name: ${{ matrix.board }}_${{ matrix.built_type }} path: | From c2c803ee885c7a9d3d09f7454b37fe200160878d Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Thu, 4 Jul 2024 11:00:30 +0200 Subject: [PATCH 15/26] Debug app: cache the latest connection parameters. Fixes showing wrong connection parameters after re-opening the app. --- app/src/applications/info/info_app.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/applications/info/info_app.c b/app/src/applications/info/info_app.c index fdd62bc5..87af9807 100644 --- a/app/src/applications/info/info_app.c +++ b/app/src/applications/info/info_app.c @@ -120,9 +120,14 @@ static void timer_callback(lv_timer_t *timer) static void param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout) { + ble_info.connection_interval = interval; + ble_info.connection_latency = latency; + ble_info.connection_timeout = timeout; + if (!running) { return; } + LOG_INF("Updated => Interval: %d, latency: %d, timeout: %d", interval, latency, timeout); info_app_ui_set_conn_params(interval, latency, timeout); } From c415c42bb341f2cc663afe0b29fb9f70326c6390 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Thu, 4 Jul 2024 11:15:25 +0200 Subject: [PATCH 16/26] Fix charging status not being sent to phone correctly. --- app/src/managers/zsw_phone_app_publisher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/managers/zsw_phone_app_publisher.c b/app/src/managers/zsw_phone_app_publisher.c index 75f7b0a5..762c3473 100644 --- a/app/src/managers/zsw_phone_app_publisher.c +++ b/app/src/managers/zsw_phone_app_publisher.c @@ -58,7 +58,7 @@ static void zbus_battery_sample_data_callback(const struct zbus_channel *chan) { struct battery_sample_event *event = zbus_chan_msg(chan); bt_bas_set_battery_level(event->percent); - send_battery_state_update(event->mV, event->percent, false); + send_battery_state_update(event->mV, event->percent, event->is_charging); } static void connected(struct bt_conn *conn, uint8_t err) From fd039670827c6d7f9d3a084b5d09310a1b9943d9 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Mon, 8 Jul 2024 11:15:21 +0200 Subject: [PATCH 17/26] rev 5: Final Flash config. --- .vscode/launch.json | 4 +++- app/CMakeLists.txt | 8 ++++++++ .../zswatch_nrf5340_cpuapp_5.overlay | 18 ++++++++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 461055fd..655c21cf 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,9 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/app/build/zephyr/zephyr.exe", - "args": ["--bt-dev=hci0"], + "args": [ + "--bt-dev=hci0" + ], "stopAtEntry": false, "cwd": "${workspaceFolder}", "preLaunchTask": "Disable BT", diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 7abfb531..949a1061 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -27,9 +27,17 @@ if("nrf5340dk_nrf5340_cpuapp" STREQUAL "${BOARD}") endif() set(BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) + find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(ZSWatchFW) +# These are XIP related anomalies and aren't applicable for us and cause +# throughput issues and QSPI issues on NCS 2.6.0 +zephyr_compile_definitions( + -DNRF53_ERRATA_43_ENABLE_WORKAROUND=0 + -DNRF52_ERRATA_215_ENABLE_WORKAROUND=0 +) + add_subdirectory(drivers) add_subdirectory(src/history) add_subdirectory(src/applications) diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay index ed16b9ff..4fa2933a 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay @@ -105,12 +105,12 @@ / { chosen { - nordic,pm-ext-flash = &gd25lq128d; + nordic,pm-ext-flash = &mx25u51245g; zephyr,console = &cdc_acm_uart0; }; aliases { - spi-flash0 = &gd25lq128d; + spi-flash0 = &mx25u51245g; buzzer-pwm = &buzzer_pwm; }; @@ -286,12 +286,13 @@ pinctrl-0 = <&qspi_default>; pinctrl-1 = <&qspi_sleep>; pinctrl-names = "default", "sleep"; - gd25lq128d: gd25lq128d@0 { + mx25u51245g: mx25u51245g@0 { compatible = "nordic,qspi-nor"; reg = <0>; sck-frequency = <96000000>; - jedec-id = [c8 60 18]; - size = ; + jedec-id = [c2 25 3a]; + size = ; + /* has-dpd; // CS High to Power-Down Mode (tDP) - 3 us // Rev. S Table 26. AC Electrical Characteristic @@ -299,10 +300,11 @@ // CS High to Standby Mode without Electronic Signature Read (tRES1) 3 us // Rev. S Table 26. AC Electrical Characteristic t-exit-dpd = <20000>; + */ // Configure to actully use Quad SPI data. - writeoc = "pp4o"; + writeoc = "pp4io"; readoc = "read4io"; - quad-enable-requirements = "S2B1v1"; + quad-enable-requirements = "S1B6"; }; }; @@ -325,7 +327,7 @@ /delete-node/ &storage_partition; -&gd25lq128d { +&mx25u51245g { partitions { compatible = "fixed-partitions"; #address-cells = <1>; From 26d69529b2e5207ddd1049736ed63ce2f4614df2 Mon Sep 17 00:00:00 2001 From: LDAB Date: Sat, 13 Jul 2024 11:10:52 +0200 Subject: [PATCH 18/26] Initial HW tests --- .github/workflows/build.yml | 10 ++-- .github/workflows/ci.yml | 11 ++++ .github/workflows/test.yml | 51 ++++++++++++++++++ app/pytest/conftest.py | 15 ++++++ app/pytest/pytest.ini | 3 ++ app/pytest/requirements.txt | 25 +++++++++ app/pytest/test_basic.py | 21 ++++++++ app/pytest/utils.py | 104 ++++++++++++++++++++++++++++++++++++ 8 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/test.yml create mode 100644 app/pytest/conftest.py create mode 100644 app/pytest/pytest.ini create mode 100644 app/pytest/requirements.txt create mode 100644 app/pytest/test_basic.py create mode 100644 app/pytest/utils.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aa7eb33e..e581c7b3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,4 @@ -name: Build - -on: - push: - pull_request: +on: [workflow_call] jobs: build: @@ -26,7 +22,7 @@ jobs: wget https://sourceforge.net/projects/astyle/files/astyle/astyle%203.4/astyle-3.4.10.tar.bz2/download -O astyle.tar.bz2 tar -xf astyle.tar.bz2 cd astyle-3.4.10 - mkdir as-gcc-exe + mkdir -p as-gcc-exe cd as-gcc-exe cmake ../ make @@ -38,7 +34,7 @@ jobs: west init -l app west config manifest.group-filter +bsec2 west update -o=--depth=1 -n - mkdir fw_images + mkdir -p fw_images - name: Style working-directory: ZSWatch diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..4cd7f57f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,11 @@ +on: + pull_request: + workflow_dispatch: + +jobs: + build: + uses: ./.github/workflows/build.yml + + test: + needs: [build] + uses: ./.github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..f218e81e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,51 @@ +on: [workflow_call] + +jobs: + test: + runs-on: self-hosted + container: + image: ghcr.io/zephyrproject-rtos/zephyr-build:v0.26.2 + volumes: + - /dev/bus/usb/:/dev/bus/usb + options: --privileged + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install dependencies + continue-on-error: true # JLink install will fail + run: | + if [ ! -f "`which JLinkExe`" ]; then + echo "Installing JLink tools..." + wget -q --post-data 'accept_license_agreement=accepted&non_emb_ctr=confirmed&submit=Download+software' https://www.segger.com/downloads/jlink/JLink_Linux_V796t_x86_64.deb + sudo apt -qq update + sudo apt -y install ./JLink_Linux_V796t_x86_64.deb &>/dev/null + fi + + if [ ! -f "`which nrfjprog`" ]; then + echo "Installing Nordic command line tools..." + wget -q https://nsscprodmedia.blob.core.windows.net/prod/software-and-other-downloads/desktop-software/nrf-command-line-tools/sw/versions-10-x-x/10-24-2/nrf-command-line-tools_10.24.2_amd64.deb + sudo apt -y install ./nrf-command-line-tools_10.24.2_amd64.deb &>/dev/null + export PATH=$PATH:/opt + fi + + python -m pip install --upgrade pip + pip install -r app/pytest/requirements.txt + + - name: 'Download image' + uses: actions/download-artifact@v4 + with: + name: zswatch_nrf5340_cpuapp@3_debug + + - name: Display structure of downloaded files + run: ls + + - name: Test with pytest + run: | + pip install pytest + pytest app/pytest/ diff --git a/app/pytest/conftest.py b/app/pytest/conftest.py new file mode 100644 index 00000000..429d780e --- /dev/null +++ b/app/pytest/conftest.py @@ -0,0 +1,15 @@ +import pytest +import utils +import logging + +logging.basicConfig(level=logging.INFO) + + +def pytest_configure(): + utils.flash() + + +@pytest.fixture(autouse=True) +def reset(): + utils.reset() + yield diff --git a/app/pytest/pytest.ini b/app/pytest/pytest.ini new file mode 100644 index 00000000..e610b3c2 --- /dev/null +++ b/app/pytest/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +log_cli = True +log_cli_level = INFO diff --git a/app/pytest/requirements.txt b/app/pytest/requirements.txt new file mode 100644 index 00000000..be1bcea3 --- /dev/null +++ b/app/pytest/requirements.txt @@ -0,0 +1,25 @@ +# RUN-TEST: required to do run time tests of zephyr +# +# things used by twister or related in run time testing + +# used to flash & debug various boards +pyocd>=0.35.0 + +# used by twister for board/hardware map +tabulate +natsort + +# used by mcuboot +cbor>=1.0.0 + +# use for twister +psutil + +# Artifacts package creation +bz + +# used for CAN <=> host testing +python-can>=4.3.0 + +# RTT connection +pylink-square diff --git a/app/pytest/test_basic.py b/app/pytest/test_basic.py new file mode 100644 index 00000000..ddeaa5ff --- /dev/null +++ b/app/pytest/test_basic.py @@ -0,0 +1,21 @@ +import time +import logging +import utils + +log = logging.getLogger() + + +def test_flash(): + """Test flashing, don't need to assert as failing to flash throws exception""" + utils.flash() + + +def test_reset(): + """Test Reset, don't need to assert as failing to reset throws exception""" + utils.reset() + + +def test_boot(): + log.info("Wait for boot") + time.sleep(30) + assert utils.read_rtt(timeout_ms=20000).find("Enter inactive") != -1 diff --git a/app/pytest/utils.py b/app/pytest/utils.py new file mode 100644 index 00000000..babffcb0 --- /dev/null +++ b/app/pytest/utils.py @@ -0,0 +1,104 @@ +import subprocess +import logging +import time +import pylink + +SERIAL_NUMBER = "760208490" + +log = logging.getLogger() + + +def current_milli_time(): + """Get times in milliseconds""" + return round(time.time() * 1000) + + +def reset(): + """Reset DUT""" + log.info("Reset DUT") + subprocess.run( + [ + "nrfjprog", + "--family", + "nrf53", + "--snr", + SERIAL_NUMBER, + "--reset", + ], + shell=False, + stderr=subprocess.STDOUT, + text=True, + check=True, + ) + + +def flash(): + """Flash firmware""" + log.info("Flashing CP_APPLICATION.") + subprocess.run( + [ + "nrfjprog", + "--family", + "nrf53", + "--snr", + SERIAL_NUMBER, + "--recover", + "--program", + "./zswatch_nrf5340_cpuapp@3_debug.hex", + "--qspichiperase", + "--verify", + ], + shell=False, + stderr=subprocess.STDOUT, + text=True, + check=True, + ) + + log.info("Flashing CP_NETWORK.") + subprocess.run( + [ + "nrfjprog", + "--family", + "nrf53", + "--snr", + SERIAL_NUMBER, + "--reset", + "--program", + "./zswatch_nrf5340_CPUNET.hex", + "--coprocessor", + "CP_NETWORK", + "--qspisectorerase", + "--verify", + ], + shell=False, + stderr=subprocess.STDOUT, + text=True, + check=True, + ) + + +def read_rtt(target_device="nRF5340_XXAA", timeout_ms=10000): + """Read Segger RTT output""" + jlink = pylink.JLink() + log.info("Connecting to JLink...") + jlink.open(serial_no=SERIAL_NUMBER) + log.info("Connecting to %s..." % target_device) + jlink.set_tif(pylink.enums.JLinkInterfaces.SWD) + jlink.connect(target_device) + jlink.rtt_start(None) + start_time = current_milli_time() + read_data = "" + + while jlink.connected() and start_time + timeout_ms > current_milli_time(): + read_bytes = jlink.rtt_read(0, 1024) + + if read_bytes and read_bytes != "": + data = "".join(map(chr, read_bytes)) + read_data = read_data + data + + time.sleep(0.1) + + jlink.close() + log.debug(read_data) + + return read_data From 8217c7f9bb0fa4a346e573d378efc267a6bf35c8 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Wed, 29 May 2024 22:08:42 +0200 Subject: [PATCH 19/26] Weather app: Fetches GPS data from phone and uses it in a HTTP request over BLE to fetch forecast and current weather. --- app/prj.conf | 4 +- app/scripts/create_custom_resource_image.py | 2 +- app/src/applications/trivia/trivia_app.c | 32 +- app/src/applications/weather/CMakeLists.txt | 2 + app/src/applications/weather/weather_app.c | 145 +++ app/src/applications/weather/weather_ui.c | 245 +++++ app/src/applications/weather/weather_ui.h | 43 + app/src/ble/ble_comm.c | 9 + app/src/ble/ble_comm.h | 18 +- app/src/ble/ble_http.c | 15 +- app/src/ble/ble_http.h | 4 +- app/src/ble/gadgetbridge/ble_gadgetbridge.c | 41 + app/src/ble/gadgetbridge/ble_gadgetbridge.h | 2 +- app/src/filesystem/zsw_lvgl_spi_decoder.c | 2 +- app/src/images/CMakeLists.txt | 3 +- app/src/images/binaries/S/clear.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/dense_drizzle.bin | Bin 0 -> 4804 bytes .../binaries/S/dense_freezing_drizzle.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/fog.bin | Bin 0 -> 5164 bytes .../images/binaries/S/heavy_freezing_rain.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/heavy_rain.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/heavy_snowfall.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/light_drizzle.bin | Bin 0 -> 4804 bytes .../binaries/S/light_freezing_drizzle.bin | Bin 0 -> 4804 bytes .../images/binaries/S/light_freezing_rain.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/light_rain.bin | Bin 0 -> 4804 bytes .../images/binaries/S/moderate_drizzle.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/moderate_rain.bin | Bin 0 -> 4804 bytes .../images/binaries/S/moderate_snowfall.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/mostly_clear.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/overcast.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/partly_cloudy1.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/rime_fog.bin | Bin 0 -> 5164 bytes app/src/images/binaries/S/slight_snowfall.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/snowflake.bin | Bin 0 -> 4804 bytes app/src/images/binaries/S/thunderstorm.bin | Bin 0 -> 4804 bytes .../binaries/S/thunderstorm_with_hail.bin | Bin 0 -> 4804 bytes .../images/binaries/S/ui_img_water_16_png.bin | Bin 0 -> 772 bytes .../binaries/S/ui_img_weather_app_bg.bin | 1 + .../images/binaries/S/weather_app_icon.bin | Bin 0 -> 3076 bytes app/src/images/weather_app_icon.c | 174 ++++ app/src/images/weather_icons/CMakeLists.txt | 2 + app/src/images/weather_icons/clear.c | 206 ++++ app/src/images/weather_icons/dense_drizzle.c | 206 ++++ .../weather_icons/dense_freezing_drizzle.c | 206 ++++ app/src/images/weather_icons/fog.c | 218 ++++ .../weather_icons/heavy_freezing_rain.c | 206 ++++ app/src/images/weather_icons/heavy_rain.c | 206 ++++ app/src/images/weather_icons/heavy_snowfall.c | 206 ++++ app/src/images/weather_icons/light_drizzle.c | 206 ++++ .../weather_icons/light_freezing_drizzle.c | 206 ++++ .../weather_icons/light_freezing_rain.c | 206 ++++ app/src/images/weather_icons/light_rain.c | 206 ++++ .../images/weather_icons/moderate_drizzle.c | 206 ++++ app/src/images/weather_icons/moderate_rain.c | 206 ++++ .../images/weather_icons/moderate_snowfall.c | 206 ++++ app/src/images/weather_icons/mostly_clear.c | 206 ++++ app/src/images/weather_icons/overcast.c | 206 ++++ app/src/images/weather_icons/partly_cloudy1.c | 206 ++++ app/src/images/weather_icons/rime_fog.c | 218 ++++ .../images/weather_icons/slight_snowfall.c | 206 ++++ app/src/images/weather_icons/snowflake.c | 206 ++++ app/src/images/weather_icons/thunderstorm.c | 206 ++++ .../weather_icons/thunderstorm_with_hail.c | 206 ++++ .../weather_icons/ui_img_water_16_png.c | 40 + .../weather_icons/ui_img_weather_app_bg.c | 937 ++++++++++++++++++ app/src/managers/zsw_app_manager.c | 2 +- app/src/ui/utils/zsw_ui_utils.c | 200 ++++ app/src/ui/utils/zsw_ui_utils.h | 2 + 69 files changed, 6448 insertions(+), 33 deletions(-) create mode 100644 app/src/applications/weather/CMakeLists.txt create mode 100644 app/src/applications/weather/weather_app.c create mode 100644 app/src/applications/weather/weather_ui.c create mode 100644 app/src/applications/weather/weather_ui.h create mode 100644 app/src/images/binaries/S/clear.bin create mode 100644 app/src/images/binaries/S/dense_drizzle.bin create mode 100644 app/src/images/binaries/S/dense_freezing_drizzle.bin create mode 100644 app/src/images/binaries/S/fog.bin create mode 100644 app/src/images/binaries/S/heavy_freezing_rain.bin create mode 100644 app/src/images/binaries/S/heavy_rain.bin create mode 100644 app/src/images/binaries/S/heavy_snowfall.bin create mode 100644 app/src/images/binaries/S/light_drizzle.bin create mode 100644 app/src/images/binaries/S/light_freezing_drizzle.bin create mode 100644 app/src/images/binaries/S/light_freezing_rain.bin create mode 100644 app/src/images/binaries/S/light_rain.bin create mode 100644 app/src/images/binaries/S/moderate_drizzle.bin create mode 100644 app/src/images/binaries/S/moderate_rain.bin create mode 100644 app/src/images/binaries/S/moderate_snowfall.bin create mode 100644 app/src/images/binaries/S/mostly_clear.bin create mode 100644 app/src/images/binaries/S/overcast.bin create mode 100644 app/src/images/binaries/S/partly_cloudy1.bin create mode 100644 app/src/images/binaries/S/rime_fog.bin create mode 100644 app/src/images/binaries/S/slight_snowfall.bin create mode 100644 app/src/images/binaries/S/snowflake.bin create mode 100644 app/src/images/binaries/S/thunderstorm.bin create mode 100644 app/src/images/binaries/S/thunderstorm_with_hail.bin create mode 100644 app/src/images/binaries/S/ui_img_water_16_png.bin create mode 100644 app/src/images/binaries/S/ui_img_weather_app_bg.bin create mode 100644 app/src/images/binaries/S/weather_app_icon.bin create mode 100644 app/src/images/weather_app_icon.c create mode 100644 app/src/images/weather_icons/CMakeLists.txt create mode 100644 app/src/images/weather_icons/clear.c create mode 100644 app/src/images/weather_icons/dense_drizzle.c create mode 100644 app/src/images/weather_icons/dense_freezing_drizzle.c create mode 100644 app/src/images/weather_icons/fog.c create mode 100644 app/src/images/weather_icons/heavy_freezing_rain.c create mode 100644 app/src/images/weather_icons/heavy_rain.c create mode 100644 app/src/images/weather_icons/heavy_snowfall.c create mode 100644 app/src/images/weather_icons/light_drizzle.c create mode 100644 app/src/images/weather_icons/light_freezing_drizzle.c create mode 100644 app/src/images/weather_icons/light_freezing_rain.c create mode 100644 app/src/images/weather_icons/light_rain.c create mode 100644 app/src/images/weather_icons/moderate_drizzle.c create mode 100644 app/src/images/weather_icons/moderate_rain.c create mode 100644 app/src/images/weather_icons/moderate_snowfall.c create mode 100644 app/src/images/weather_icons/mostly_clear.c create mode 100644 app/src/images/weather_icons/overcast.c create mode 100644 app/src/images/weather_icons/partly_cloudy1.c create mode 100644 app/src/images/weather_icons/rime_fog.c create mode 100644 app/src/images/weather_icons/slight_snowfall.c create mode 100644 app/src/images/weather_icons/snowflake.c create mode 100644 app/src/images/weather_icons/thunderstorm.c create mode 100644 app/src/images/weather_icons/thunderstorm_with_hail.c create mode 100644 app/src/images/weather_icons/ui_img_water_16_png.c create mode 100644 app/src/images/weather_icons/ui_img_weather_app_bg.c diff --git a/app/prj.conf b/app/prj.conf index cecaecea..b1d77734 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -1,5 +1,5 @@ CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=6000 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=10000 CONFIG_HEAP_MEM_POOL_SIZE=32000 CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_DEBUG_THREAD_INFO=y @@ -81,7 +81,7 @@ CONFIG_LV_USE_MENU=y CONFIG_LV_USE_METER=y CONFIG_LV_USE_MSGBOX=y CONFIG_LV_USE_SPINBOX=n -CONFIG_LV_USE_SPINNER=n +CONFIG_LV_USE_SPINNER=y CONFIG_LV_USE_TABVIEW=n CONFIG_LV_USE_TILEVIEW=y CONFIG_LV_USE_WIN=n diff --git a/app/scripts/create_custom_resource_image.py b/app/scripts/create_custom_resource_image.py index b6583243..981cfc83 100644 --- a/app/scripts/create_custom_resource_image.py +++ b/app/scripts/create_custom_resource_image.py @@ -3,7 +3,7 @@ from struct import * MAX_FILE_NAME = 32 -FILE_TABLE_MAX_LEN = 25000 +FILE_TABLE_MAX_LEN = 32000 """ magic_number:uint32 header_len:uint32 diff --git a/app/src/applications/trivia/trivia_app.c b/app/src/applications/trivia/trivia_app.c index f9d861f6..3a3b8f86 100644 --- a/app/src/applications/trivia/trivia_app.c +++ b/app/src/applications/trivia/trivia_app.c @@ -71,19 +71,31 @@ static int trivia_app_add(void) return 0; } -static void http_rsp_cb(ble_http_status_code_t status, cJSON *response) +static void http_rsp_cb(ble_http_status_code_t status, char *response) { if (status == BLE_HTTP_STATUS_OK && active) { - cJSON *question = cJSON_GetObjectItem(response, "question"); - cJSON *correct_answer = cJSON_GetObjectItem(response, "correct_answer"); - if (question == NULL || correct_answer == NULL) { - LOG_ERR("Failed to parse JSON data"); - return; + cJSON *parsed_response = cJSON_Parse(response); + if (parsed_response == NULL) { + LOG_ERR("Failed to parse JSON rsp data from HTTP request"); + } else { + cJSON *results = cJSON_GetObjectItem(parsed_response, "results"); + if (cJSON_GetArraySize(results) == 1) { + cJSON *result = cJSON_GetArrayItem(results, 0); + cJSON *question = cJSON_GetObjectItem(result, "question"); + cJSON *correct_answer = cJSON_GetObjectItem(result, "correct_answer"); + if (question == NULL || correct_answer == NULL) { + LOG_ERR("Failed to parse JSON data"); + return; + } + memset(trivia_app_question.question, 0, sizeof(trivia_app_question.question)); + strncpy(trivia_app_question.question, question->valuestring, sizeof(trivia_app_question.question) - 1); + trivia_app_question.correct_answer = (correct_answer->valuestring[0] == 'F') ? false : true; + trivia_ui_update_question(trivia_app_question.question); + } else { + LOG_ERR("Unexpected number of results: %d, expected 1", cJSON_GetArraySize(results)); + } } - memset(trivia_app_question.question, 0, sizeof(trivia_app_question.question)); - strncpy(trivia_app_question.question, question->valuestring, sizeof(trivia_app_question.question)); - trivia_app_question.correct_answer = (correct_answer->valuestring[0] == 'F') ? false : true; - trivia_ui_update_question(trivia_app_question.question); + cJSON_Delete(parsed_response); } } diff --git a/app/src/applications/weather/CMakeLists.txt b/app/src/applications/weather/CMakeLists.txt new file mode 100644 index 00000000..f92d3fe4 --- /dev/null +++ b/app/src/applications/weather/CMakeLists.txt @@ -0,0 +1,2 @@ +FILE(GLOB app_sources *.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/app/src/applications/weather/weather_app.c b/app/src/applications/weather/weather_app.c new file mode 100644 index 00000000..fb82d32a --- /dev/null +++ b/app/src/applications/weather/weather_app.c @@ -0,0 +1,145 @@ +#include +#include +#include +#include "cJSON.h" + +#include "managers/zsw_app_manager.h" +#include "ui/utils/zsw_ui_utils.h" +#include "events/ble_event.h" +#include +#include "weather_ui.h" +#include + +#define HTTP_REQUEST_URL_FMT "https://api.open-meteo.com/v1/forecast?latitude=%f&longitude=%f¤t=wind_speed_10m,temperature_2m,apparent_temperature,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,precipitation_sum,rain_sum,precipitation_probability_max&wind_speed_unit=ms&timezone=auto&forecast_days=%d" + +#define MAX_GPS_AGED_TIME_MS 30 * 60 * 1000 + +// Functions needed for all applications +static void weather_app_start(lv_obj_t *root, lv_group_t *group); +static void weather_app_stop(void); +static void on_zbus_ble_data_callback(const struct zbus_channel *chan); + +ZBUS_CHAN_DECLARE(ble_comm_data_chan); +ZBUS_LISTENER_DEFINE(weather_ble_comm_lis, on_zbus_ble_data_callback); +ZBUS_CHAN_ADD_OBS(ble_comm_data_chan, weather_ble_comm_lis, 1); + +ZSW_LV_IMG_DECLARE(weather_app_icon); + +static bool active; +static uint64_t last_update_gps_time; +static uint64_t last_update_weather_time; +static double last_lat; +static double last_lon; + +static application_t app = { + .name = "Weather", + .icon = ZSW_LV_IMG_USE(weather_app_icon), + .start_func = weather_app_start, + .stop_func = weather_app_stop +}; + +static void http_rsp_cb(ble_http_status_code_t status, char *response) +{ + zsw_timeval_t time_now; + weather_ui_current_weather_data_t current_weather; + weather_ui_forecast_data_t forecasts[WEATHER_UI_NUM_FORECASTS]; + char *days[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; + + if (!active) { + return; + } + + if (status == BLE_HTTP_STATUS_OK) { + zsw_clock_get_time(&time_now); + cJSON *parsed_response = cJSON_Parse(response); + cJSON *current = cJSON_GetObjectItem(parsed_response, "current"); + cJSON *current_temperature_2m = cJSON_GetObjectItem(current, "temperature_2m"); + current_weather.temperature = current_temperature_2m->valuedouble; + cJSON *current_weather_code = cJSON_GetObjectItem(current, "weather_code"); + current_weather.icon = zsw_ui_utils_icon_from_wmo_weather_code(current_weather_code->valueint, ¤t_weather.color, + ¤t_weather.text); + cJSON *current_wind_speed = cJSON_GetObjectItem(current, "wind_speed_10m"); + current_weather.wind_speed = current_wind_speed->valuedouble; + cJSON *apparent_temperature = cJSON_GetObjectItem(current, "apparent_temperature"); + current_weather.apparent_temperature = apparent_temperature->valuedouble; + + cJSON *daily_forecasts = cJSON_GetObjectItem(parsed_response, "daily"); + + cJSON *weather_code_list = cJSON_GetObjectItem(daily_forecasts, "weather_code"); + cJSON *temperature_2m_max_list = cJSON_GetObjectItem(daily_forecasts, "temperature_2m_max"); + cJSON *temperature_2m_min_list = cJSON_GetObjectItem(daily_forecasts, "temperature_2m_min"); + cJSON *precipitation_probability_max_list = cJSON_GetObjectItem(daily_forecasts, "precipitation_probability_max"); + + for (int i = 0; i < cJSON_GetArraySize(weather_code_list); i++) { + forecasts[i].temperature = cJSON_GetArrayItem(temperature_2m_max_list, i)->valuedouble; + forecasts[i].low_temp = cJSON_GetArrayItem(temperature_2m_min_list, i)->valuedouble; + forecasts[i].high_temp = cJSON_GetArrayItem(temperature_2m_max_list, i)->valuedouble; + forecasts[i].rain_percent = cJSON_GetArrayItem(precipitation_probability_max_list, i)->valueint; + forecasts[i].icon = zsw_ui_utils_icon_from_wmo_weather_code(cJSON_GetArrayItem(weather_code_list, i)->valueint, + &forecasts[i].color, &forecasts[i].text); + sprintf(forecasts[i].day, "%s", days[(time_now.tm.tm_wday + i) % 7]); + } + + weather_ui_set_weather_data(current_weather, forecasts, cJSON_GetArraySize(weather_code_list)); + + cJSON_Delete(parsed_response); + last_update_weather_time = k_uptime_get(); + ble_comm_request_gps_status(false); + } else { + printk("HTTP request failed\n"); + } +} + +static void fetch_weather_data(double lat, double lon) +{ + char weather_url[512]; + snprintf(weather_url, sizeof(weather_url), HTTP_REQUEST_URL_FMT, lat, lon, WEATHER_UI_NUM_FORECASTS); + zsw_ble_http_get(weather_url, http_rsp_cb); +} + +static void on_zbus_ble_data_callback(const struct zbus_channel *chan) +{ + const struct ble_data_event *event = zbus_chan_const_msg(chan); + + if (event->data.type == BLE_COMM_DATA_TYPE_GPS) { + last_update_gps_time = k_uptime_get(); + printk("Got GPS data, fetch weather\n"); + printk("Latitude: %f\n", event->data.data.gps.lat); + printk("Longitude: %f\n", event->data.data.gps.lon); + last_lat = event->data.data.gps.lat; + last_lon = event->data.data.gps.lon; + fetch_weather_data(event->data.data.gps.lat, event->data.data.gps.lon); + } +} + +static void weather_app_start(lv_obj_t *root, lv_group_t *group) +{ + if (last_update_gps_time == 0 || k_uptime_delta(&last_update_gps_time) > MAX_GPS_AGED_TIME_MS) { + printk("GPS data is too old, request GPS\n"); + ble_comm_request_gps_status(true); + } else { + fetch_weather_data(last_lat, last_lon); + } + weather_ui_show(root); + + zsw_timeval_t time; + zsw_clock_get_time(&time); + weather_ui_set_time(time.tm.tm_hour, time.tm.tm_min, time.tm.tm_sec); + active = true; +} + +static void weather_app_stop(void) +{ + active = false; + weather_ui_remove(); + ble_comm_request_gps_status(false); +} + +static int weather_app_add(void) +{ + zsw_app_manager_add_application(&app); + + return 0; +} + +SYS_INIT(weather_app_add, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/applications/weather/weather_ui.c b/app/src/applications/weather/weather_ui.c new file mode 100644 index 00000000..b5b6f4d8 --- /dev/null +++ b/app/src/applications/weather/weather_ui.c @@ -0,0 +1,245 @@ +#include +#include +#include + +typedef struct { + lv_obj_t *ui_day; + lv_obj_t *ui_day_temp; + lv_obj_t *ui_day_icon; + lv_obj_t *ui_day_day; +} lv_obj_forecasts_t; + +static void add_forecast_day(lv_obj_t *parent, lv_obj_forecasts_t *storage); + +static lv_obj_t *root_page = NULL; + +static lv_obj_t *ui_bg_img; +static lv_obj_t *ui_root_container; +static lv_obj_t *ui_location; +static lv_obj_t *ui_forecast_widget; +static lv_obj_t *ui_time; +static lv_obj_t *ui_today_container; +static lv_obj_t *ui_today_icon; +static lv_obj_t *ui_today_temp; +static lv_obj_t *ui_today_min_max_temp; +static lv_obj_t *ui_today_rain; +static lv_obj_t *ui_water_drop_img; +static lv_obj_t *ui_loading_spinner; + +static lv_obj_forecasts_t ui_forecasts[WEATHER_UI_NUM_FORECASTS]; + +ZSW_LV_IMG_DECLARE(ui_img_weather_app_bg); +ZSW_LV_IMG_DECLARE(ui_img_water_16_png); + +void weather_ui_show(lv_obj_t *root) +{ + assert(root_page == NULL); + + // Create the root container + root_page = lv_obj_create(root); + // Remove the default border + lv_obj_set_style_border_width(root_page, 0, LV_PART_MAIN); + // Make root container fill the screen + lv_obj_set_size(root_page, LV_PCT(100), LV_PCT(100)); + // Don't want it to be scollable. Putting anything close the edges + // then LVGL automatically makes the page scrollable and shows a scroll bar. + // Does not loog very good on the round display. + lv_obj_set_scrollbar_mode(root_page, LV_SCROLLBAR_MODE_OFF); + + lv_obj_clear_flag(root_page, LV_OBJ_FLAG_SCROLLABLE); + + ui_bg_img = lv_img_create(root_page); + lv_img_set_src(ui_bg_img, ZSW_LV_IMG_USE(ui_img_weather_app_bg)); + lv_obj_set_width(ui_bg_img, LV_SIZE_CONTENT); + lv_obj_set_height(ui_bg_img, LV_SIZE_CONTENT); + lv_obj_set_align(ui_bg_img, LV_ALIGN_CENTER); + lv_obj_add_flag(ui_bg_img, LV_OBJ_FLAG_ADV_HITTEST); + lv_obj_clear_flag(ui_bg_img, LV_OBJ_FLAG_SCROLLABLE); + + ui_loading_spinner = lv_spinner_create(root_page, 1000, 90); + lv_obj_set_width(ui_loading_spinner, 60); + lv_obj_set_height(ui_loading_spinner, 60); + lv_obj_set_align(ui_loading_spinner, LV_ALIGN_CENTER); + lv_obj_clear_flag(ui_loading_spinner, LV_OBJ_FLAG_CLICKABLE); + lv_obj_set_style_arc_color(ui_loading_spinner, zsw_color_dark_gray(), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_arc_opa(ui_loading_spinner, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + + lv_obj_set_style_arc_color(ui_loading_spinner, zsw_color_blue(), LV_PART_INDICATOR | LV_STATE_DEFAULT); + lv_obj_set_style_arc_opa(ui_loading_spinner, 255, LV_PART_INDICATOR | LV_STATE_DEFAULT); + + ui_root_container = lv_obj_create(root_page); + lv_obj_remove_style_all(ui_root_container); + lv_obj_set_width(ui_root_container, lv_pct(100)); + lv_obj_set_height(ui_root_container, lv_pct(100)); + lv_obj_set_align(ui_root_container, LV_ALIGN_CENTER); + lv_obj_clear_flag(ui_root_container, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN); + + ui_location = lv_label_create(ui_root_container); + lv_obj_set_width(ui_location, LV_SIZE_CONTENT); + lv_obj_set_height(ui_location, LV_SIZE_CONTENT); + lv_obj_set_x(ui_location, 0); + lv_obj_set_y(ui_location, 25); + lv_obj_set_align(ui_location, LV_ALIGN_TOP_MID); + lv_label_set_text(ui_location, "Location..."); + lv_obj_set_style_text_font(ui_location, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT); + + ui_forecast_widget = lv_obj_create(ui_root_container); + lv_obj_remove_style_all(ui_forecast_widget); + lv_obj_set_width(ui_forecast_widget, lv_pct(100)); + lv_obj_set_height(ui_forecast_widget, LV_SIZE_CONTENT); + lv_obj_set_x(ui_forecast_widget, 3); + lv_obj_set_y(ui_forecast_widget, 55); + lv_obj_set_align(ui_forecast_widget, LV_ALIGN_CENTER); + lv_obj_set_flex_flow(ui_forecast_widget, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(ui_forecast_widget, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); + lv_obj_clear_flag(ui_forecast_widget, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_pad_row(ui_forecast_widget, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_pad_column(ui_forecast_widget, 5, LV_PART_MAIN | LV_STATE_DEFAULT); + + for (int i = 0; i < WEATHER_UI_NUM_FORECASTS; i++) { + add_forecast_day(ui_forecast_widget, &ui_forecasts[i]); + } + + ui_time = lv_label_create(root_page); + lv_obj_set_width(ui_time, LV_SIZE_CONTENT); + lv_obj_set_height(ui_time, LV_SIZE_CONTENT); + lv_obj_set_x(ui_time, 0); + lv_obj_set_y(ui_time, 10); + lv_obj_set_align(ui_time, LV_ALIGN_TOP_MID); + lv_obj_add_flag(ui_time, LV_OBJ_FLAG_HIDDEN); + + ui_today_container = lv_obj_create(root_page); + lv_obj_remove_style_all(ui_today_container); + lv_obj_set_pos(ui_today_container, 0, -10); + lv_obj_set_height(ui_today_container, 89); + lv_obj_set_width(ui_today_container, lv_pct(100)); + lv_obj_set_align(ui_today_container, LV_ALIGN_CENTER); + lv_obj_clear_flag(ui_today_container, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_flag(ui_today_container, LV_OBJ_FLAG_HIDDEN); + + ui_today_icon = lv_img_create(ui_today_container); + lv_obj_set_width(ui_today_icon, LV_SIZE_CONTENT); + lv_obj_set_height(ui_today_icon, LV_SIZE_CONTENT); + lv_obj_set_align(ui_today_icon, LV_ALIGN_CENTER); + lv_obj_add_flag(ui_today_icon, LV_OBJ_FLAG_ADV_HITTEST); + lv_obj_clear_flag(ui_today_icon, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t *ui_Label8 = lv_label_create(ui_today_container); + lv_obj_set_width(ui_Label8, LV_SIZE_CONTENT); + lv_obj_set_height(ui_Label8, LV_SIZE_CONTENT); + lv_obj_set_align(ui_Label8, LV_ALIGN_TOP_MID); + lv_label_set_text(ui_Label8, "NOW"); + lv_obj_set_style_text_font(ui_Label8, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT); + + ui_today_temp = lv_label_create(ui_today_container); + lv_obj_set_width(ui_today_temp, LV_SIZE_CONTENT); + lv_obj_set_height(ui_today_temp, LV_SIZE_CONTENT); + lv_obj_set_x(ui_today_temp, -40); + lv_obj_set_y(ui_today_temp, -10); + lv_obj_set_align(ui_today_temp, LV_ALIGN_CENTER); + lv_obj_set_style_text_font(ui_today_temp, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT); + + ui_today_min_max_temp = lv_label_create(ui_today_container); + lv_obj_set_width(ui_today_min_max_temp, LV_SIZE_CONTENT); + lv_obj_set_height(ui_today_min_max_temp, LV_SIZE_CONTENT); + lv_obj_set_x(ui_today_min_max_temp, 60); + lv_obj_set_y(ui_today_min_max_temp, 0); + lv_obj_set_align(ui_today_min_max_temp, LV_ALIGN_CENTER); + //lv_obj_set_style_text_color(ui_today_min_max_temp, lv_color_hex(0x808080), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_opa(ui_today_min_max_temp, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_font(ui_today_min_max_temp, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT); + + ui_today_rain = lv_label_create(ui_today_container); + lv_obj_set_width(ui_today_rain, LV_SIZE_CONTENT); + lv_obj_set_height(ui_today_rain, LV_SIZE_CONTENT); + lv_obj_set_x(ui_today_rain, -40); + lv_obj_set_y(ui_today_rain, 10); + lv_obj_set_align(ui_today_rain, LV_ALIGN_CENTER); + lv_obj_set_style_text_font(ui_today_rain, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT); + + ui_water_drop_img = lv_img_create(ui_today_container); + lv_img_set_src(ui_water_drop_img, ZSW_LV_IMG_USE(ui_img_water_16_png)); + lv_obj_set_width(ui_water_drop_img, LV_SIZE_CONTENT); + lv_obj_set_height(ui_water_drop_img, LV_SIZE_CONTENT); + lv_obj_set_x(ui_water_drop_img, -68); + lv_obj_set_y(ui_water_drop_img, 11); + lv_obj_set_align(ui_water_drop_img, LV_ALIGN_CENTER); + lv_obj_add_flag(ui_water_drop_img, LV_OBJ_FLAG_ADV_HITTEST); + lv_obj_clear_flag(ui_water_drop_img, LV_OBJ_FLAG_SCROLLABLE); +} + +static void add_forecast_day(lv_obj_t *parent, lv_obj_forecasts_t *storage) +{ + storage->ui_day = lv_obj_create(parent); + lv_obj_remove_style_all(storage->ui_day); + lv_obj_set_width(storage->ui_day, LV_SIZE_CONTENT); + lv_obj_set_height(storage->ui_day, LV_SIZE_CONTENT); + lv_obj_set_align(storage->ui_day, LV_ALIGN_CENTER); + lv_obj_set_flex_flow(storage->ui_day, LV_FLEX_FLOW_COLUMN); + lv_obj_set_flex_align(storage->ui_day, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START); + lv_obj_clear_flag(storage->ui_day, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE); + + storage->ui_day_temp = lv_label_create(storage->ui_day); + lv_obj_set_width(storage->ui_day_temp, LV_SIZE_CONTENT); + lv_obj_set_height(storage->ui_day_temp, LV_SIZE_CONTENT); + lv_obj_set_align(storage->ui_day_temp, LV_ALIGN_CENTER); + lv_obj_set_style_text_color(storage->ui_day_temp, lv_color_hex(0x5AA1EE), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_opa(storage->ui_day_temp, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + + storage->ui_day_icon = lv_img_create(storage->ui_day); + lv_obj_set_width(storage->ui_day_icon, LV_SIZE_CONTENT); + lv_obj_set_height(storage->ui_day_icon, LV_SIZE_CONTENT); + lv_obj_set_x(storage->ui_day_icon, 48); + lv_obj_set_y(storage->ui_day_icon, 53); + lv_obj_set_align(storage->ui_day_icon, LV_ALIGN_CENTER); + lv_obj_add_flag(storage->ui_day_icon, LV_OBJ_FLAG_ADV_HITTEST); + lv_obj_clear_flag(storage->ui_day_icon, LV_OBJ_FLAG_SCROLLABLE); + + storage->ui_day_day = lv_label_create(storage->ui_day); + lv_obj_set_width(storage->ui_day_day, LV_SIZE_CONTENT); + lv_obj_set_height(storage->ui_day_day, LV_SIZE_CONTENT); + lv_obj_set_align(storage->ui_day_day, LV_ALIGN_CENTER); + lv_obj_set_style_text_color(storage->ui_day_day, lv_color_hex(0x5AA1EE), LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_opa(storage->ui_day_day, 255, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_text_font(storage->ui_day_day, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT); +} + +void weather_ui_set_weather_data(weather_ui_current_weather_data_t current_weather, + weather_ui_forecast_data_t weather_ui_forecast_data_t[WEATHER_UI_NUM_FORECASTS], + int num_forecasts) +{ + if (root_page == NULL || num_forecasts == 0) { + return; + } + + if (lv_obj_has_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN)) { + lv_obj_clear_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(ui_today_container, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(ui_time, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(ui_loading_spinner, LV_OBJ_FLAG_HIDDEN); + } + + lv_label_set_text_fmt(ui_today_temp, "%.1f°", current_weather.temperature); + lv_label_set_text_fmt(ui_today_min_max_temp, "%.1f° / %.1f°", weather_ui_forecast_data_t[0].low_temp, + weather_ui_forecast_data_t[0].high_temp); + lv_label_set_text_fmt(ui_today_rain, "%d%%", weather_ui_forecast_data_t[0].rain_percent); + lv_img_set_src(ui_today_icon, current_weather.icon); + + for (int i = 0; i < num_forecasts; i++) { + lv_label_set_text_fmt(ui_forecasts[i].ui_day_temp, "%.1f°", weather_ui_forecast_data_t[i].temperature); + lv_label_set_text(ui_forecasts[i].ui_day_day, weather_ui_forecast_data_t[i].day); + lv_img_set_src(ui_forecasts[i].ui_day_icon, weather_ui_forecast_data_t[i].icon); + } +} + +void weather_ui_set_time(int hour, int min, int second) +{ + lv_label_set_text_fmt(ui_time, "%02d:%02d", hour, min); +} + +void weather_ui_remove(void) +{ + lv_obj_del(root_page); + root_page = NULL; +} diff --git a/app/src/applications/weather/weather_ui.h b/app/src/applications/weather/weather_ui.h new file mode 100644 index 00000000..3a6d2dc8 --- /dev/null +++ b/app/src/applications/weather/weather_ui.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#define WEATHER_UI_NUM_FORECASTS 4 + +typedef struct { + double temperature; + double apparent_temperature; + double wind_speed; + const void *icon; + char *text; + lv_color_t color; +} weather_ui_current_weather_data_t; + +typedef struct { + double temperature; + int rain_percent; + const void *icon; + double low_temp; + double high_temp; + char day[4]; // 3 Letter day name + char *text; + lv_color_t color; +} weather_ui_forecast_data_t; + +void weather_ui_show(lv_obj_t *root); +void weather_ui_remove(void); + +/* +* @brief Set the weather data to be displayed on the UI + +* @param weather_ui_forecast_data_t The weather data to be displayed. First one is the current weather. +* @param num_forecasts The number of forecasts in the array +* +* @return void +*/ +void weather_ui_set_weather_data(weather_ui_current_weather_data_t current_weather, + weather_ui_forecast_data_t weather_ui_forecast_data_t[WEATHER_UI_NUM_FORECASTS], + int num_forecasts); + +void weather_ui_set_time(int hour, int min, int second); diff --git a/app/src/ble/ble_comm.c b/app/src/ble/ble_comm.c index a830bc2c..4972f365 100644 --- a/app/src/ble/ble_comm.c +++ b/app/src/ble/ble_comm.c @@ -253,6 +253,15 @@ int ble_comm_get_mtu(void) return bt_gatt_get_mtu(current_conn); } +int ble_comm_request_gps_status(bool enable) +{ + char gps_status[50]; + int len = snprintf(gps_status, sizeof(gps_status), "{\"t\":\"gps_power\", \"status\":%s} \n", + enable ? "true" : "false"); + printk("Sending: %s", gps_status); + return ble_comm_send(gps_status, len); +} + static void update_conn_interval_slow_handler(struct k_work *item) { LOG_DBG("Change to long connection interval"); diff --git a/app/src/ble/ble_comm.h b/app/src/ble/ble_comm.h index 6d194f5e..63831410 100644 --- a/app/src/ble/ble_comm.h +++ b/app/src/ble/ble_comm.h @@ -20,7 +20,7 @@ #include #define MAX_MUSIC_FIELD_LENGTH 100 -#define MAX_HTTP_FIELD_LENGTH 512 +#define MAX_HTTP_FIELD_LENGTH 2000 #define MAX_WEATHER_REPORT_TEXT_LENGTH 25 typedef enum ble_comm_data_type { @@ -32,6 +32,7 @@ typedef enum ble_comm_data_type { BLE_COMM_DATA_TYPE_MUSIC_STATE, BLE_COMM_DATA_TYPE_REMOTE_CONTROL, BLE_COMM_DATA_TYPE_HTTP, + BLE_COMM_DATA_TYPE_GPS, BLE_COMM_DATA_TYPE_EMPTY } ble_comm_data_type_t; @@ -93,6 +94,18 @@ typedef struct ble_comm_http_response { int id; } ble_comm_http_response_t; +typedef struct ble_comm_gps { + double lat; + double lon; + double alt; + double speed; + uint64_t time; + uint8_t satellites; + float hdop; + bool externalSource; + char gpsSource[20]; +} ble_comm_gps_t; + typedef struct ble_comm_cb_data { ble_comm_data_type_t type; union { @@ -104,6 +117,7 @@ typedef struct ble_comm_cb_data { ble_comm_music_state_t music_state; ble_comm_remote_control_t remote_control; ble_comm_http_response_t http_response; + ble_comm_gps_t gps; } data; } ble_comm_cb_data_t; @@ -141,3 +155,5 @@ int ble_comm_long_connection_interval(void); * @return The MTU for current connection. 0 If no connection. */ int ble_comm_get_mtu(void); + +int ble_comm_request_gps_status(bool enable); diff --git a/app/src/ble/ble_http.c b/app/src/ble/ble_http.c index 3ca61ece..d82111a9 100644 --- a/app/src/ble/ble_http.c +++ b/app/src/ble/ble_http.c @@ -65,19 +65,8 @@ static void zbus_ble_comm_data_callback(const struct zbus_channel *chan) i++; } } - fixed_rsp[j - 1] = '\0'; // Remove the last " as it belongs not to the JSON - cJSON *gb_rsp = cJSON_Parse(fixed_rsp); - if (gb_rsp == NULL) { - LOG_ERR("Failed to parse JSON rsp data from GB"); - } else { - cJSON *results = cJSON_GetObjectItem(gb_rsp, "results"); - if (cJSON_GetArraySize(results) == 1) { - ble_http_cb(BLE_HTTP_STATUS_OK, cJSON_GetArrayItem(results, 0)); - } else { - LOG_ERR("Unexpected number of results: %d, expected 1", cJSON_GetArraySize(results)); - } - } - cJSON_Delete(gb_rsp); + fixed_rsp[j - 1] = '\0'; // Remove the last " as it belongs not to the data + ble_http_cb(BLE_HTTP_STATUS_OK, fixed_rsp); k_free(fixed_rsp); } } diff --git a/app/src/ble/ble_http.h b/app/src/ble/ble_http.h index 1d8d1a27..3cf72ccd 100644 --- a/app/src/ble/ble_http.h +++ b/app/src/ble/ble_http.h @@ -13,9 +13,9 @@ typedef enum { * This callback function is invoked when an HTTP GET request has been completed. * * @param status The status of the HTTP GET request. - * @param response The response data in JSON format. The cJSON object parameter will be deleted automatically after the callback function returns. + * @param response The response data. */ -typedef void (*ble_http_callback)(ble_http_status_code_t status, cJSON *response); +typedef void (*ble_http_callback)(ble_http_status_code_t status, char *response); /** * @brief Sends an HTTP GET request to the specified URL. diff --git a/app/src/ble/gadgetbridge/ble_gadgetbridge.c b/app/src/ble/gadgetbridge/ble_gadgetbridge.c index 79f2f8fa..330f629a 100644 --- a/app/src/ble/gadgetbridge/ble_gadgetbridge.c +++ b/app/src/ble/gadgetbridge/ble_gadgetbridge.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "ui/zsw_ui.h" #include "ble/ble_comm.h" @@ -552,6 +553,42 @@ static int parse_httpstate(char *data, int len) return 0; } +static int parse_gps_data(char *data, int len) +{ + //{"t":"gps","lat":55.6135542,"lon":12.9747185,"alt":41.900001525878906,"speed":0.1458607256412506,"time":1717002933835,"satellites":0,"hdop":16.215999603271484,"externalSource":true,"gpsSource":"network"} + ble_comm_cb_data_t cb; + memset(&cb, 0, sizeof(cb)); + + cb.type = BLE_COMM_DATA_TYPE_GPS; + + cJSON *root = cJSON_Parse(data); + if (root == NULL) { + return -EINVAL; + } + + cJSON *lat = cJSON_GetObjectItem(root, "lat"); + cJSON *lon = cJSON_GetObjectItem(root, "lon"); + cJSON *alt = cJSON_GetObjectItem(root, "alt"); + cJSON *speed = cJSON_GetObjectItem(root, "speed"); + cJSON *time = cJSON_GetObjectItem(root, "time"); + cJSON *satellites = cJSON_GetObjectItem(root, "satellites"); + cJSON *hdop = cJSON_GetObjectItem(root, "hdop"); + + cb.data.gps.lat = lat != NULL ? lat->valuedouble : -1; + cb.data.gps.lon = lon != NULL ? lon->valuedouble : -1; + cb.data.gps.alt = alt != NULL ? alt->valuedouble : -1; + cb.data.gps.speed = speed != NULL ? speed->valuedouble : -1; + cb.data.gps.time = time != NULL ? time->valuedouble : -1; + cb.data.gps.satellites = satellites != NULL ? satellites->valueint : -1; + cb.data.gps.hdop = hdop != NULL ? hdop->valuedouble : -1; + + cJSON_Delete(root); + + send_ble_data_event(&cb); + + return 0; +} + static int parse_data(char *data, int len) { int type_len; @@ -592,6 +629,10 @@ static int parse_data(char *data, int len) return parse_httpstate(data, len); } + if (strlen("gps") == type_len && strncmp(type, "gps", type_len) == 0) { + return parse_gps_data(data, len); + } + return 0; } diff --git a/app/src/ble/gadgetbridge/ble_gadgetbridge.h b/app/src/ble/gadgetbridge/ble_gadgetbridge.h index 57512184..53e35ef1 100644 --- a/app/src/ble/gadgetbridge/ble_gadgetbridge.h +++ b/app/src/ble/gadgetbridge/ble_gadgetbridge.h @@ -5,6 +5,6 @@ #include "events/ble_event.h" #include "events/music_event.h" -#define MAX_GB_PACKET_LENGTH 1000 +#define MAX_GB_PACKET_LENGTH 2000 void ble_gadgetbridge_input(const uint8_t *const data, uint16_t len); \ No newline at end of file diff --git a/app/src/filesystem/zsw_lvgl_spi_decoder.c b/app/src/filesystem/zsw_lvgl_spi_decoder.c index 53488f10..cb7290da 100644 --- a/app/src/filesystem/zsw_lvgl_spi_decoder.c +++ b/app/src/filesystem/zsw_lvgl_spi_decoder.c @@ -35,7 +35,7 @@ #define FLASH_PARTITION_DEVICE FIXED_PARTITION_DEVICE(FLASH_PARTITION_NAME) #define FLASH_PARTITION_OFFSET FIXED_PARTITION_OFFSET(FLASH_PARTITION_NAME) -#define FILE_TABLE_MAX_LEN 25000 +#define FILE_TABLE_MAX_LEN 32000 #define MAX_FILE_NAME_LEN 32 #define MAX_OPENED_FILES 64 diff --git a/app/src/images/CMakeLists.txt b/app/src/images/CMakeLists.txt index e51c78d8..5ba2ffc4 100644 --- a/app/src/images/CMakeLists.txt +++ b/app/src/images/CMakeLists.txt @@ -2,4 +2,5 @@ FILE(GLOB app_sources *.c) target_sources(app PRIVATE ${app_sources}) add_subdirectory(assets_watchfaces) -add_subdirectory(fonts) \ No newline at end of file +add_subdirectory(fonts) +add_subdirectory(weather_icons) \ No newline at end of file diff --git a/app/src/images/binaries/S/clear.bin b/app/src/images/binaries/S/clear.bin new file mode 100644 index 0000000000000000000000000000000000000000..fda56e597f4f9c073c77efcaef78576c25846b9c GIT binary patch literal 4804 zcmeHKOHUhD6t;OL>xgWS5Kdw!m}He??KqH!gaqOjmvA`y2 zO1CW8Fs4mhV3E)T5~;*v$fGbk7Bf)E_uSKSXU2nV90DmwUDTSz_1rV(o9{fnbEkaV zRqp!#cY+AOY(30|AsL1V?+MJ$#spL^%qlR85JiwuaHali{C>>~OoSnYkR(uq0D`CI zYfqfbK1|30G-`snk*y7$jbE3Gxk^B-0ksj-OGkY|N;V^mAV5)9l|1@$ec+b}x?$y)_x5bYPZ9s$Y{gj>iLVmBc=4bl!=NrStUSQL0D`WH5; zK~0OYv4SbhL+9;WOOQGsuqVhW1iGsy+VXazw;?(&Qh&z^$XjsN3x`{=>mV%%P>-Djrff5%(J?q?0kfAOIc=Bg9W>lT z3iY+2+(#f-YLrwNt}5m#%exaWlH8}9HAE>v^Aso>l#)0;>g*n~ z0BOVyFClg!3(o6uVR;<$IBii*4bOsL8bK|%sRdgtd){5n<4t^0;_*KIWPm@E_8WY3 z)7phVJGeI~?<|7Mzo7f`3gdW0XBRxz^|iPzk7)k(KgTQSKA*e6e;?zMt2}N?V0~6U{zEyR8@543Y|;3PhK2Y& z8uf%IF8vc~Z^qbbJJ%;f=cP2-dLTInNg1R;2(&@AG5Ie(KDlCr*N&|P`apo1aHzd9 zukKatp3g!QZQj)ZUH$M#hO07^grUS+@G|CTOW9L~WQrR9$}V_%t@bpl_rR>8EK{OM zpp~czj;K9HtsAv_sMQ^46%sk828X9%=-Puv2zSXFLJ8@c!j!zBDTerjBaF_VSt4;D zCp=~Gr*1`lu+P zbCYCHDAIkiYhIbvTW99<8CP34FX2s82;Ly+pO;;C=b(^2XTmujX9% ztr9}*5E_BzI9$8_4d_6}73<_cMeg1Nce~|;WRMg|tCO}q4ye!iRBtC0l9N;DZiUb$ zG$UL^C|zLdr<;Rxmb1@D9{cddl#!FXJcLFqP_~XNMG7#_5;srsAlX3l5=5u+jw=z8 znt1Nx{6d*fBoYU+!JRE=9uiDR5(zh9YK4EAxh^{f$1EV)2-3E5OcgrgUtscKvbYfZ zUg%m9ic}gV{dc^VoI-i2bqhm9ad|1v}0Cu0a6VF=(dk|Y?F-QWo-G4x7Bxn}27hw;!r;y-o4&udg zAqdWD!FVWXFLB*1I(u@w$Q%^6mWCOXYV5^DQZh}N&e!L8-<_X3JIR*Ni@rQ$X5M+` z`8?m}ecpGo=d+PLBma-o3IG}45bzrC9xw~kfV02^@B;8q>ZkYk64(tK13m(N1a1Nw z=nWV4D(v4J`zxpYPPcvN9sx<80Xg79;8&03U2VXIL)L~%qiT5((EPoUj^J$jW5D+vAn*^A8S(iFyOi0pCT4^x$b^qKC7`L3TBd4$yH| zP3!DpZFe--cAtR#z?TV7U#1W!iS(Dn$~1WXuWs#aK-n(L^8#0!EUt$ zKNORDNd%;FF;@=Z(4SbJOdm=&BrQ0-h1jMHCU*fVl49##I}PB{p&|R$Pb^y7FqH0z z66U@H{K;I&szvsoFIEaMWqu*CF^5!cOz$Z^B}6D{U5Y~zg_A0#&&CBWNfytgR`M~kbA{-k-?a{XDQirp}@H^O}d9Ebe}b4je&dPL!q zuq;leXp0h>UinGNB8%;rC@?(vgP}hW<*H7*B|C)0%A)BU-%lgbr8*x{dX>Re)(w+;mPZwssElhrs8+~@5Up}KuTu~;V6tCC`ieD&2CE?dg3yKL7=DIY2aUd%Y>GHb_De1>|ZUMs0BS8bA|afgbz z9cOjEq|UqQw5z;%U%AReNttk!BH8`r7GG70|0oB$%7It5Q=gsk$^5)8v-VcTnaZr~ L-Km)WsW|@v9_(_f literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/dense_freezing_drizzle.bin b/app/src/images/binaries/S/dense_freezing_drizzle.bin new file mode 100644 index 0000000000000000000000000000000000000000..347080f686d046427b5d7f014583e547d39110bf GIT binary patch literal 4804 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 literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/heavy_freezing_rain.bin b/app/src/images/binaries/S/heavy_freezing_rain.bin new file mode 100644 index 0000000000000000000000000000000000000000..cc6c1e93d91da5afcb5765e2d7a6eed88dfe2aac GIT binary patch literal 4804 zcmeH~e{54#6vz8Of@`8l%g?=Ttr)d&6XOyg?SApTo_lX!`?@~L;BQ_| zZr{DynbI{-+)df)|MFVF>qfc-!V@C;B<_R$A)0?UCdKp*f6 z@Ha4r+@(Uf1?9J_av_`8J)KzpfB>V%02}Zg@T{0Q`AOpyW(RLi z4}Lm5_~gBjJOVfXEEKr3r{V|+sDo`KgD$!hRt7uXx?tX!^NPoLPc-ltKf_v5kxHB* zKkF?W9>uSD^Pl-JEi$(e4k)b7FGtg>%cFtkfQei_%ElA2qf1b6V!;-Rt~`{&$UJ=O zDOlx}Mk+mm2&xe&I2C7>B#R_dVYw6y zJPn)&?i6wgrMz$AAhA4Ywta<57gK16%EA~fqPJ`^^2#DEUr{<2MxZjvWa~+Lo+0n)KMM* zZR&=z6-@&e;wzL**jYDQ*>#b7yIC-;=LHhztQ~zGG`q1Yz|b@uvVSq`TcsB(?xz#0 z#yscZX_kaajrefF4zCTiZEU0|GdD{@^2zjGif5JhxJ)9ZtAm56UIMD&emaStk*Vk%>EzCJOS%C8|j{mggd!>G0l5P zAVF#DOtaoLH=rYkjtIPA)GYkt4gcf~%(&_x%j1@bCrVpwa!Af?G0N;Z`hCCJ(ytzM zwN4V3#{P6qZ@Q=En@MVW&8bPcC(C=oYEQ&Y7V7l9?+stxIW^ZrXJhg#Xe8}q){`;oNzf>!<-9yaU&0y;?dinTX17{@37Z?> z9DuX#j;rm5x`j8q0prbOpjeCvjA`5>G4m0ak7(2J7`5FR)uzHLsxp}l`>lulXFB3D zJL9Nt&(ycixR}@(c_PF1u8X!fvZ33O)2ROt0*R{$G`GaeEugU=U+;Y_TJV}oZ+SMf zhsL*7-?24ZaRzpK!%0^+ta4I5`no*wBWzFs*;YkV`E!zf)+ed2Q6Z7E(&)2N=72Q1#V}sFR?chq$iqeI!2hw<|G@wN literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/heavy_rain.bin b/app/src/images/binaries/S/heavy_rain.bin new file mode 100644 index 0000000000000000000000000000000000000000..6146a1cf34990e38613a694fc9372e0c92414207 GIT binary patch literal 4804 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 literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/light_freezing_drizzle.bin b/app/src/images/binaries/S/light_freezing_drizzle.bin new file mode 100644 index 0000000000000000000000000000000000000000..d441da2e4245604944a5dd4be799c8821fcf5171 GIT binary patch literal 4804 zcmeH~e`s4(6vtcVa1AIVbueGsL>pwX41{%BT-yXR`p?#XblqfI5*Vv6?S|{znCp_) zKim++{UbwhO*)27P*(q`u`TWe1T)YXM6t80eNP3gf|x%xn*Pk!bMMW2dGF;lYlr@& zk3;kBy{G4MzUQ8M)2_Wxv$p2{r)mX&T3`e4BybSu17zR`up4+3sH^&`cen_w0k!~V zfNz06fO(XjBD9;(elBRA6f*nsnGJUcaQZc%0eB7gNoVPw8la&-mO)_<`N8?TJUT5u zLuGLav${E86Yw!m)M5Nn5DAwd95)%$WHGW|v{27g-@4Udtlq#Qz!w%G4Rno+sN=K{ z$gcY^4vZIX=F}sXddr+_IEVh8nh zT82xPhUi-(F>7tjP28(6Yb4Q}k7CfW)Dr1laKjl@0~rXmb_bpENI8&XSd>b(I9n zrdMD-o7!paE1(71uZ&A#`OzZ^y9s0bcCxl8p=rrTvQ%WHq>fevF&#z8j2u$evPzSc z>nUVLMTao4qG$?>Z=_-AQiWYgtQs-q!%9Io6LBbtOHrKlB3Z;xP$V#?BpmLmLZ&A# z&)PeLP7S4D)hmidta3HDSdy70i!#t9FV2L}6~w+cL(_1``(Zj-Zx$=w3z_=q*kwm` zgkYvuQr|2#$^1#I!fH!UCNqeX7w3vNRzx_CwtaXrSv)tDKCQOy)SUke(1IJsF+8p= zQ9yp3ni`Uz6RhKc*EaRurb*|oq+GFa zTs@Ifzso8&4P8}U*q(ADv842n%4*xyf$jvlQwS%~viN5>`E@ux8)$hvzOPhoQe{?8yyF1Y94t{HXs23$_Nzj0lIv_8;x zkE287>Y0ouAs;w|Z@PlT_AA)j0sjE}ZA*c@U$!m27>+w{Ze{R>ZAYcK3D4*&l}j{Z zTRk509FM)op-kIV*`*jZ_E#=i}LKHB0`^C`DuDBGkoanbV*T+d&y&5NPO zx_UU&9FZrsHZ3)DT=U2Ghm+aBDR`u;bn*ph>?_)0_l@t}3qHqCwn^8CEw0_YuGTHK zc`@XxM~v0O^4j*q_J+tyt^xL^V^?sbfqbPt@({waq&YZLMPSslIA+rc)s8U0>U{ jqJIplH&XRg8+TPh)+(*NuE&>eBwAgj%~l2aPdWb$;7!X^ literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/light_freezing_rain.bin b/app/src/images/binaries/S/light_freezing_rain.bin new file mode 100644 index 0000000000000000000000000000000000000000..424b253a43bbff1a68c18b5447f17c53905992ad GIT binary patch literal 4804 zcmeH~e{54#6vtPPz?x{%A~@c*R%r}|k{B35WLuj^^&i+j%2+aJn-FG#4kIJrV6@#I zj+hwv$1D+541B>bf} zCw=$6ci#Ej@44sRw#&{|EUWmx&6@$h1XKY}0SACCAOsu&T7bua%6VVC%ZI>HU=wf> z_#XHJm`0)HA>V}jb58ywm)bX;s=7;n(Q808@G9_=!cwj>AR|YXLara<{nO*2i#I~g zP+E+_+}S-~J@6rrS77`qh=fZKj#~&f$oyo#$nN&b_7!)ADfI>(1HLRF(m>J3hzd@2 zgY2puL%>k}W+r>+LTG7eu*HsmmB4!jP*o-uD2VjQ#ENOK`@fHeynuPJFvSm80=x`N z6uB~2DxfSfGXW*xl!TH-L-{YrpXTJNsKRP;sK_b_G$Qg!<1@_l z-x}|KXT1NBg^}C?=m2JmTv}66LIP@MOUa%nZtI$AW0!eqO^$P!UR0 zk)P$3ibwV!Va0u^Mj%6gY%<-CxDScJc`BxveG4}s93O@B~68r8=0Fg zJvryOWs%8FWwPzJ;{r86H*gJ@DRL=k0?KzvCd(#J(zH;T8$lH!IcJj0(qxfzCM=bs zfpx$jFjtHzl=8fZLSk{UZ25{!<5NsXp1CnxL~FTpYAunp-WD`b5!kHv_*hu3&{q_Mj?O2+4@~X~gOr=H=@2KFv-E9*Rnr z;*bQf_sg{u>Pm4g)RI9J>6D6L$@&7@>8o4?iA_fnVB5!C*c61L#ZB`1r2C@eN@k@g z-DD72Q!+4}j_lIb6;KEHSH>l=eCrW~orHdVI+d0vq3MxuR>kt|$rRC3L5%rOFm(=* zE9qoyDc71yT@)3<#EPUPS$uUGYLyDfM5J?xR)m&YK()lE4+B1&vLT#D)Fmb`l?)o3 zSGiRCcxbY`LPX95<0QGzEMmXO) z7VF7w-6b3U43J&xhA=pkofFbne2$<`qN`B4&(i2Z`zY!@L;Ec23p?d!xIhv;mvAJ@ zxqY_+-b7oZx5<{NAA5KGi1AlaCSNm@?Mx?sNJefJL@8Prog2H)MQxvfbr|&tmPyh` zb}-9w+uVq@Alf4Egi$y9rziZ4Cot)(ha?SKMjkFtwYWp)Njhs!26sn&$9e)E?;riU z$NN##6^i=0W8A1SVCxR&yPd70*3)pT8STxoVZ;_X=zGl*zPxj6x~UdTHZ%m_9L+oT zKx&<>JobfY&9kP&qW&CJOMTT6i8^aINo!}!+ye8~LG4pdu(sLtW|M8EVGJ9*aC{DF zWX3Z6R>ehwZ$Ryf#lGDnO(mpZSmTKbJ3CYzH7lIQS2??u3m@~A!{*i3%&QNnubfO- zgQ5Kg@m;ek-*5>V8sX@Jqkhi0=d1eJ7d!#u#Z_M~bnGVU=>%oc+^KL|I~?1FtEI!j zVM)t!(?6@0R26=rAN5<0`p>r|CwC^%;GJmjPCA*`Noi!lu?@~HTH?ss6Ba$iXl!md zZ{A9oJjWi|P1S2+(iEjVF68Upc*(ui8yenRJ6GL!#Sz%&38$SWV3pF+@#m$)*R;fz z>pxm%?7Fwa&~bc|gNfQGhUP6B&8s^qCpNJm$sbNweqziN}hb4t{FG2sQ*#80prqk&F literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/light_rain.bin b/app/src/images/binaries/S/light_rain.bin new file mode 100644 index 0000000000000000000000000000000000000000..00a142de6a7022eae426fb79a9c43237742bcc8c GIT binary patch literal 4804 zcmeH}&ubiI7{`;8(sn?Ft*z;9%pyT5=1`hy0}&Fi=s%z|Sa26K7a<3e9vTv|y9evV ze;@}l+ZGxRC8{c38 zpjuzI?6LX$zG$#Vy#o#dU&KItnM$A#>667u8a#iemVY169u?;K0Uf}{z`cO$D5V1B z$ZP^7;Z%gkpj+n;I5%DAtebzBF0HAwkU-PClniYe4yVEG9dcHcS#*Yac0>cus2=u$N+{`~EZ3Hr$H{t6 z{cqpR^K2|c8V=`qt!h8NJsNl&_@NPxqN#w~x&)Pu1y4qX4<$FUA+_}6TvukpvNtSy zbSo~<1r&hWz=MEGMH8snDVEI%L`E1&xe?SOlCx#7nPj?Y%_dvXz;R#^co@VKrK)by zNF2xJo7E2^hG+NxChg+fXM4$dy3wI>g zt&ZY{VsbC3fK)E#%1{oiiM7b|p>#pgg40`xU6Nq33s{keEqd*=1(yyD>03XsXl=t# zx+Y4P`x@{YbA^?U>_K0w2(cu;kk}@NZMjW)-{Mn3g`(D_I3z*#eyf&7UwO`rUW)0W zCZ%#4Szq7`{gnG4*>scuZ=a#YrXUvh2g9 z&|%~Pi&MQ}>M`e)TN$n8?>Bb{?HWoWs#jtXOR8bjRsC})c_s<8ps$&^nDg1K9A3-L z$EqU)D^iO~Mdq;dsq>_WrR!1#bAyFPg@dzempC@hTRp_CukB-cn^$ zL=n{}sjg04gDHd?UB#&~MpheWk9*hDubBD{zrR+!t7=bJ_V=c-?sF*u<1$$A%vU6j z76zerpF41w8Y#JP rH70H1PAq8`pbg)6%-ohnYN9{2Mrz_drABI^KFQliBRxsbe>?U+^BjCM literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/moderate_drizzle.bin b/app/src/images/binaries/S/moderate_drizzle.bin new file mode 100644 index 0000000000000000000000000000000000000000..6de38b194a346132c88c2767d3c18f2002971d3b GIT binary patch literal 4804 zcmeH}&u<%55XTd@6|fSJZhs|BiG|!Bs6AAo&`2P~5^eGifErPWSb|#BcfeEK;VK8DQugj`(@@m@9tag+G&Dv%WC9( z`*u8^`Ocg7?0sMK?CaURx>f+_1^R(EfUCd^Py(iaao{ZQOxLe&^Chqccp3N<_yPC} zSV!yf;jY2`#dE*%>hCt|{o4ejeGM1{J^_9XSi#)|TzF)4coj4&>&?>QYH5thk``ub zbHHif7T^akahF8G)d?r8gjKQv*{^PX^1JNQTf@Y?ftP@9V?=rgG%_*3xp|P?&7uJ` z{59K|S}5&_2Yb>d-~jMt3N(}{1WF=(vRIi0&;Qvhy#r`Z3Jd&z4DdeiZ^U(lQVHeA zY!XVssR*%)9^Jp;-uB!}Ug^0Y>gIRg1aP-4RBJT_R92M)rV&M_i448U{buEQv-0BR zNZ|o|0Bl5DT2t9V5}M_uWN6#vavI#;inFLp)y?NNMFY=@9u9)aP_l~(Tw7`$w-CGy z@1a}Z*;uQo5*3 zseFvBFK~f=%0rOcbd&&ZpL}am5RMkt6#Yr_vgMLlbrrjA8E>h51)PKXJ99~_*m^|a zldvF8r+AAJnqGxT$|8&HnJQ47{N6HOh;wzXz9>6{#mb_Y96wAW)}Ss1{fnptCKE`YZ&<~Y^VzE(SS>81 zsv`uOsaA}~G%3YWh>=kDOjN(&uu?_0)o%h=@i*Y=M!oN3$n(K6SRY+G%t&d4zE?+Lr%cb;_#Cygq$f8;3Sr?c%egS9`OW+~xhb&-;3^(b1ZW zpq>9vJA6+&GL?L_y_ww1@!aKaa<4574xH=~Av69|?>~n!{r~G9yBdFR;NsxG#?fV8 zUmjKGcY3TZkLioPKI`k#V>``Kiq6_w*sjZ_z&JQT7>`r literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/moderate_rain.bin b/app/src/images/binaries/S/moderate_rain.bin new file mode 100644 index 0000000000000000000000000000000000000000..ca03ddd665be33a9910d1a5c89676537ada08b05 GIT binary patch literal 4804 zcmeH}PiP!f9LKXMrR{(UTbqPU%wiX*n1k3=7ZS{Z|4zLrjRc#3%|*z;q!dGfyL&KR zB*#b*J6j9JLrE)=Zn6PqPmUMagTf{u%Z!Q|y|_q9rkl3&_4j*kW_D+Hk~B5Fh{I$4 zy!Yn!`F(%y`)2p>m6pRT{~xV{NuRh=)a0oaJd<6Ue z{0VHsIc%7lFn_kpn^xhSN}=Nc0YR?;oxq2{PcF;7nt%z5S^-uTmF#vUo!>~mPGt!S zv%fyz8Q=zByD)K;M8XvaCt4aC)P|}3VkSqwiyqw{#y=Z)8u->nqz6|c6J4B{1hthY zNeuK)GL-I}d0D-UGI3TvI5O zP>#$^LPeCHT{O(KCG(iW z?x=V5rnxhng^0rBJg=3E$9G2qF97RKJc=d)vULe69SiRC9UhdXQA>)Yr^&Wx28u?t zXpHW}1-gI?unOF%aj9q$Dt1cI-~@a}J(O}Is7s{DMU9(IP1TE+Bh6^w6tDo?tHqQ` zMct&4IF7-~S3BzF)CywrG{&j*&C=C38n{3hn6E{nI|@k6T`VbqqS4~kJlqToCVKRb zo46yj-D(PcT}<|p2uS5(t~|tq=ERz0dQiF{X|=Dn5W6IU$z8yTq}Z%$ryaQT(U89N z67$!#9!mE_spmcq{LWm-O8fSpCsqn6%KYlYdJ}|s8bA$?4SHYWuY?Fi)}=TkLGJx# zEsn3;$`U0=ePq_z@n~oCT?UQsig%_E^QoppEmlZ=($ffu!TM&I) zSKqAn6%dE{8*@pl*m^|aFX6EGI@MW}6{UE{OOoz&gJoVH;+CT((E-B0*R?17+^|*1 zONX#n!`bN+(@VoCqZ^Y_;v|!x<<>MN&U}N>yL^^(O3yF3s;dFtE2}VCN#FJy;_L<5 zH6+${6p;{?BNUNFn!J+aA?ly&$C&2Nqz9)1O_nMvx_&!^O;~T^Co;u$i)L4-W ze%W@y5}hg_#m)_3)<)ktB2_+r(#>QC|GjDh$v!g<6$2duyQ^eO6pbHsZIih4B5^4K z#ZkNQY9~4)=(~d%n?*@Foe4CpAwCIZg3q%C=DKg^hJMvjH^{(R>alt+?Q~DylcEvT z)w8-fsiiWxROb3nX0AIkYiD{U%T&pp!Sb|`nX%Is&wV{o{`=xfU(FclX)SZIT2=;d zaUR1#3y76RYhS7)s2 zXwT${o~a}JRx}j8ln+lJ{MHiPQ|pW@Q`sZcWqxdFQQ9sj?W>`!v3(%|C&vcIV}on4 z!3#VZ4JiZ5R7oWvK+#a7nvbj@yq1^T)`24->qKkEzxu~6L9yPPsH6}`iV|Na?NrIn zvK(nPQ#rCk`wIsha2)~CTpzA=6{Fe5cZW+PE0rIDIOA6^F;skMDPB#rd&F#q+) F{{U_YewhFO literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/moderate_snowfall.bin b/app/src/images/binaries/S/moderate_snowfall.bin new file mode 100644 index 0000000000000000000000000000000000000000..0ac2260db3027fab7d91daf1c1cbb52c2949265a GIT binary patch literal 4804 zcmeH}Uu;u#6vsD~B@O}YHWIko+R(*dD2b6y6IkgInLL;h65KS|cDrb{2hFzdKRDLb z2R0wfcrhai>#Y!nF=XQfCv@wrF<27+R0C$nMtdDmk(k&hgpO{#U(fIU`gdz#4BqsY zliquO_uTXOea|_+dt3Z*L2<$Vfh9@2llkE*W3w)hLq>H3RMoi+A zI*?s8U;>y>ZwJGBhFwM3!4`W3lmVaSfTm<>0y&X>nOMFIHvdP&B?8MA3rqR|%Yfa$ z-85IxlyWGG%#1@xI3*!#(53PhlrN&nYf;y#WYh;AfoFiL^Fk%6sX=*GNnkFb)@j-b zqnJrjj6Kw;}VGZ8MoKN@%em`cQ>Xj(wlx&-AN3pSZGQc!Xu ztJ6wP&Z=f%1jF}&;f{P=TpnwyxSzrTRnmfo$3#?Oe!dPxgN>0(?yG>3%?(^8rO%{w7!>9@Bg_B;>9 zcL7tx#d?zMG>=PnxdSh~A!lOeLFtkxncN!Scg9VI;&lE7PKo993Tkf5llslWHWck; z%0HJWI~TGtXXfdBnY|@=C>Lu;>JT25wMs^kW$F{Huh?DkY-MRD;;2(IJ4WpwbbfkP zeSvNCDNlj;rlYWI`_v^i1y@8|GFnVZsq9BzD?05M2xG*`EI&FHkQy@k3NSIS97y|VC)#D0$FV;ScN{}1M)Vl9Le_+5@1ySma#c3BH0r-V z5-3`#Z&~ZAiP~kBkK~LvF`{6^&(?6v3egEu3)-t0JSP4o;w>D;Zt;Y3Ru4RHpw_^`1G)jbfpv1t+= zJs5CfSmmj{6Oc{?qz8O|15#x`Ixy-Cj#&SZ^l*|WAGVESAjC>WJ#$*mjJW+FIAkWa zp2WIgile$2rdqW0pm%HB?TZepzm8hZ%FYJa`BY{vR9amtAnlUx(wIarCHH_sa<-bJ$$jAv%OA$(e|Vyo90-fQqP#0W9G4d`TEW#f0h=TyvkJBq8qapHm_U)kv~Fx z)ro6173NUP9Fi?9)22ZP&C|m1FO9Jn>zTt>gj&Or=5-r9wEdyHxnTr2C|H qhgLjF@Wnh!e@JZdka3C{_2gpwAEQrg=y{=eZ%Nap#~AZJ80uf}Nz;=6 literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/mostly_clear.bin b/app/src/images/binaries/S/mostly_clear.bin new file mode 100644 index 0000000000000000000000000000000000000000..15d9d648f181e9d5585983f19610a940e58997d9 GIT binary patch literal 4804 zcmeH~T})I*6vr19)LLSxMAO)`tbmmEr74A2iUzD`c(bG*4^2}(6eO)SF->fuHQ=h% z#K&ryGe%U((q(wQZl`zU;o`cKfIHQWdI%w{R?0{u0_tefD@O3w=s^*!A2RCKC-)5G zmiq(eG|%`nnkV!}t+$-=pCspNlwVHU7a3=!;6|F!R}yV)j=G9@eiO^H@1wdU$wOU48OK-3(Iz?Ilih#H z=81UGxEYC&WV5Peqe_(k+Rn+l6gKTW<;>dgCBh_KuxN4w>~ zr0j+~hIlpNMKB{UyI}52m|MHdtuD4t&SnuJ(E)J~qK-uCm*jeKUM~4okoRly-lonQ zUk39M%%d=yU~Yw3*lq4yNqNPh@3Lrxs2mY4x2RNG ze%?gh3i6JUn|CYd4bHdejSbvOj_#HNiDanq)Q0Y~p)i+B8n>Ew0f=C!Xss2lGU3RW zmuNSjLxtoXRKz?`8bokX1gr5;mK^B64`nxJpzP)n7`Lo^5ylapk&&GuE4dkumKw?^ z@1&Wg8NuI;;8#XFN4QiDjPRV=;hmmS%S{`421cWmw?v{_%99N)v}~rYGJ=JFSxZ6= z)X45}*{l{)e5t*VrlA`9Xc5=JSO@)POutaGP}W@SWp|Bi9#_uJEF?R;Hgt<3-n}XH z)6h?k>xUJWE-t02LfXD+E}N;;%VXuTI&y#4@apC8PD7)a&@V6%`VQz-BYHt89m%1p zFKF`+V{s__6GGkxxbV5^q)BFEdc7pi@NX`4|iLU+43@s+u-Wk`t5; z;e+V(i_W4{9OO3AkwN`@6V*|}dOj!3NTYe_p4zH*gwIUPsq&QFERbVijP)nR`ge0* zbu2soQbhaoIH-$`%2c=%UPGO3a*tTMc!<^($CqWBN6$_{&njqCtsfqe?wH>7ImHC{L}Mt`G6w#3G0^U{mW;p5FO3j%Pd@L-0CvU zB%(HS#ENhgEa<&4@7d7ywaLasdzPrr7nP;Lu`;=St}=O_p@xfmZWtXfHgW#Vs4TG? z->q8_t@<#U>C#n82H+vynP}#VbtG_I@rwEz(#Vz?SHieLag}louw1{EXlsqNJjbR)xI~0P>Z0fCuQev>%2KgE zR~z6d;1|Z)YI%rh75t?V*C^Rs!K(FJ7I>5GPEqexw|pgpYeKlx)w#F?6aokMk!34$ zR?AA6w^>k2GplC^zX*EnXr8wi!S}nUJ0V;Hf8W?A9E*%IunzFq&jD8E?3YsJJ?eF! ze79Z%(*ly^>weoc;aINdj>W4uU=Q23XOrW}&N7rU`^%pX3TDzgA1^MXvwI=1hgT7Y zku%e0K>RdNzVjG7Gx?g<^Vr_kvECQ1KHp~>x9L+L9*Grj>r-f+KQvG6>|sAjjemHZ a=GmipTIbHYG*9u-$NHRqlmY+8`~CweF#$OM literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/overcast.bin b/app/src/images/binaries/S/overcast.bin new file mode 100644 index 0000000000000000000000000000000000000000..51178eb6e9ec38e71e06fb45e9446e49492a57ea GIT binary patch literal 4804 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 ZJY)AfoPTIX%eMa4+al|Z+yA!${{ayag;oFn literal 0 HcmV?d00001 diff --git a/app/src/images/binaries/S/snowflake.bin b/app/src/images/binaries/S/snowflake.bin new file mode 100644 index 0000000000000000000000000000000000000000..78057176efd8804235a84d72036d7d60c9310805 GIT binary patch literal 4804 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 xpyCrMv)M7#14UG0`Bh^Us>b|ÿÇ_ÿÏÿ×ÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¯ÿ·>ÿÇ?ÿÏ_ÿ×ÿߟÿç¿ÿç¿ÿç¿ÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ®þÿ¿>ÿÇ?ÿÏ_ÿ×ÿߟÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ·ÿ¿>ÿÏ_ÿ×ÿߟÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ®þÿ·ÿÇ_ÿ×ÿߟÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ®þÿ·ÿÇ_ÿ×ÿߟÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ·ÿÇ?ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¦þÿ¯ÿ¿>ÿÏÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿÏ_ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ·ÿÇ_ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿÏÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿÇ>ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ·ÿÇ_ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ·ÿÏ_ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿÏ_ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ¯ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¯ÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¿>ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ×ÿ×ÿ×ÿߟÿߟÿ×ÿ×ÿ×ÿ×ÿÏ_ÿÇ_ÿÇ?ÿ¿>ÿ·ÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ·ÿ×ÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿç¿ÿߟÿ×ÿÏÿÇ_ÿ¿?ÿ·ÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ·ÿÏÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿç¿ÿߟÿÏÿÇ_ÿ·ÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ®þÿ¯ÿ·ÿ·ÿ·ÿ¿>ÿ¿?ÿ¿?ÿ¿?ÿ¿?ÿ¿>ÿ·ÿ·ÿÏ_ÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿןÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿߟÿÏÿ¿?ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ¿>ÿÇ_ÿÏÿ×ÿ×ÿߟÿߟÿߟÿçŸÿç¿ÿç¿ÿçŸÿߟÿߟÿߟÿç¿ÿç¿ÿߟÿߟÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿç¿ÿÏÿ¿>ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ¿?ÿÏ_ÿ×ÿçŸÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿ÷ßÿ÷ßÿïßÿç¿ÿç¿ÿߟÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿߟÿÏ_ÿ¿>ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ¿>ÿÇ?ÿÇ_ÿÏ_ÿÏÿ×ÿ×ÿ×ÿןÿߟÿߟÿߟÿןÿ×ÿ×ÿÏÿÏ_ÿÇ_ÿ¿>ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ_ÿ×ÿçŸÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿç¿ÿߟÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿߟÿÇ_ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ?ÿÏ_ÿ×ÿߟÿç¿ÿï¿ÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿï¿ÿߟÿ×ÿÏ_ÿÇ?ÿ¿ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ_ÿ×ÿç¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿïßÿç¿ÿߟÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿç¿ÿ×ÿ¿>ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ?ÿÏÿߟÿç¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿç¿ÿߟÿÏÿÇ?ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¿>ÿ×ÿç¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿç¿ÿߟÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿߟÿÇ_ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ·ÿ¿>ÿ¿?ÿÇ_ÿÏ_ÿÏ_ÿÏÿÏÿÏÿÏÿÏ_ÿÏ_ÿÏ_ÿÇ_ÿÇ?ÿ¿>ÿ·ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ_ÿ×ÿçŸÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿç¿ÿ×ÿÏ_ÿ¿?ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ_ÿߟÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿï¿ÿߟÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿߟÿߟÿç¿ÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿç¿ÿÏ_ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ¿>ÿÇ_ÿÏÿ×ÿߟÿߟÿç¿ÿç¿ÿï¿ÿïßÿïßÿïßÿïßÿï¿ÿï¿ÿç¿ÿç¿ÿçŸÿߟÿ×ÿ×ÿÏ_ÿÇ_ÿ¿>ÿ·ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ_ÿןÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿߟÿÏÿ¿>ÿ¯ÿ¯ÿ¯ÿ·ÿÏÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿïßÿçŸÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿןÿߟÿç¿ÿï¿ÿïßÿ÷ßÿ÷ÿÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿç¿ÿÏÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿ¿?ÿÏ_ÿ×ÿߟÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿç¿ÿߟÿ×ÿÏÿÇ_ÿ¿>ÿ·ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ¯ÿ·ÿÇ_ÿןÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿߟÿÏ_ÿ¿>ÿ¿>ÿ×ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿç¿ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿߟÿç¿ÿï¿ÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿÏÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¿>ÿÏ_ÿ×ÿߟÿç¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿçŸÿןÿÏÿÇ_ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿÇ_ÿ×ÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿߟÿߟÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿߟÿç¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿÏÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿÇ?ÿÏÿߟÿç¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿçŸÿ×ÿÇ_ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿÏ_ÿç¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿߟÿç¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿç¿ÿÏ_ÿ·ÿ·ÿ·ÿ·ÿ¿>ÿÏÿߟÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿçŸÿ×ÿÇ_ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¿>ÿ×ÿç¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿ×ÿ×ÿ×ÿߟÿç¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿçŸÿÇ?ÿ·ÿ¿ÿÏ_ÿߟÿç¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿߟÿÏÿ¿>ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¿>ÿ×ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿߟÿ×ÿߟÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿߟÿÇ_ÿ×ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿߟÿÏ_ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿÇ?ÿߟÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿç¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿߟÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿÏÿ¿>ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿÇ?ÿߟÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿ×ÿ¿>ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¿>ÿ¿>ÿÇ_ÿÏÿ×ÿ×ÿ×ÿ×ÿ×ÿ×ÿÏÿÏ_ÿÇ_ÿ¿>ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿÇ>ÿߟÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿï¿ÿï¿ÿï¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿןÿÇ>ÿ·ÿ¿>ÿÏ_ÿ×ÿߟÿçŸÿï¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿç¿ÿߟÿ×ÿÏ_ÿ¿>ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ¿>ÿߟÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿï¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿߟÿ×ÿߟÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿߟÿ×ÿÇ_ÿ·>ÿ·ÿ·ÿ·ÿ·ÿ·ÿ·ÿ×ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿïßÿïßÿï¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿïßÿ÷ßÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿߟÿÇ_ÿ·ÿ·ÿ·ÿ·ÿÏ_ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿï¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿ×ÿ¿>ÿ·ÿ¿>ÿߟÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿç¿ÿç¿ÿç¿ÿï¿ÿï¿ÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿï¿ÿç¿ÿç¿ÿç¿ÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿç¿ÿï¿ÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿï¿ÿç¿ÿçŸÿçŸÿç¿ÿïßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿߟÿÇ_ÿ×ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿçŸÿç¿ÿç¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿïßÿï¿ÿç¿ÿç¿ÿçŸÿçŸÿçŸÿçŸÿç¿ÿï¿ÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿï¿ÿç¿ÿïßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿç¿ÿï¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿï¿ÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿçŸÿç¿ÿï¿ÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿïßÿç¿ÿçŸÿç¿ÿïßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿç¿ÿïßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿïßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿ÷ßÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ßÿç¿ÿçŸÿçŸÿçŸÿç¿ÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿï¿ÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿç¿ÿç¿ÿï¿ÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿïßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿïßÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿï¿ÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿïßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿï¿ÿï¿ÿï¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿ÷ßÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿçŸÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿߟÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿç¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿߟÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿç¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿߟÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿߟÿߟÿߟÿߟÿç¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿç¿ÿߟÿߟÿߟÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿïßÿï¿ÿï¿ÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿïßÿïßÿïßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿïßÿïßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿïßÿïßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿ÷ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/app/src/images/binaries/S/weather_app_icon.bin b/app/src/images/binaries/S/weather_app_icon.bin new file mode 100644 index 0000000000000000000000000000000000000000..219b4f1b6c8cf95c67e2623df781259c0bd5a256 GIT binary patch literal 3076 zcmb`JO>7fK7>0A8CXs*}C=|LY;UrLH8>!N&;;{B!2!|FQO%jmpQ(P&B?WNg>R_q4{ zf`m|y6hdO(khpL`aLkGeLE%S89N^H{5)rsb)TUA$IS$Icot@pCHU7g*h#p1n%zpEH zGqaYHFD`ZM>1z9Yv8Z!9T3C!0R-=V24hw8J6Lm%hm-e?6w0zhn4GcPSgU-gF zgSN1O*{IXsQq=IEZ?;E~t}D_9MMB4HDblsRqumX%`Uxf8uf$&|aqNf%ML%3`tQo86 zZ`Jgwn#L|zR;{5LWf)bfU$s_M3%h1nqu$WV(9jKQJtB49oCH#^97{>iQ z3TL`W3-?gJgl5sAWMSM6mkUo2ZY45{i3|iAe`5O`oYVXjMBKY_{sF#2<$M#l*X4B_ z2?`BD#lu2^*4(E7f33KF59e!Cer>50M_|E{LxWK9u#(JIlX(c9zX;?JRL*@uzJ3ww zDIfMOl6L3`gqumb>dpsTdBg8#0+mDU_O%?NG&?D=93d0Kvn;&gINs(n1w?E~Mp|vlAE$_=_%GnG&I^F-rdlp?@f8~3)t<2=?D=15|S%Sws=TrCJ!tAxM z^1g@LX1uRxBj0b(mO=2arRFWzyA%6t5@MLPeFOJYvvf@S2{7{4j64LUjo*qcIk?<$ zz|Pf_9IGk9V&3%n Date: Fri, 31 May 2024 19:45:31 +0200 Subject: [PATCH 20/26] watchface app: Save some RAM by not storing a copy of last BLE message. Also fixes possible loss of data if let's say one music and one weather come fast after eachother before workqueue been processed. --- .../applications/watchface/watchface_app.c | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/app/src/applications/watchface/watchface_app.c b/app/src/applications/watchface/watchface_app.c index ba98d1a0..34090d11 100644 --- a/app/src/applications/watchface/watchface_app.c +++ b/app/src/applications/watchface/watchface_app.c @@ -108,7 +108,7 @@ static delayed_work_item_t general_work_item; static struct k_work_sync canel_work_sync; static K_WORK_DEFINE(update_ui_work, update_ui_from_event); -static ble_comm_cb_data_t last_data_update; +static ble_comm_data_type_t last_data_update_type; static ble_comm_weather_t last_weather_data; static ble_comm_music_info_t last_music_info; static struct battery_sample_event last_batt_evt = {.percent = 100, .mV = 4300}; @@ -354,19 +354,18 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) static void update_ui_from_event(struct k_work *item) { if (running && !is_suspended) { - if (last_data_update.type == BLE_COMM_DATA_TYPE_WEATHER) { - LOG_DBG("Weather: %s t: %d hum: %d code: %d wind: %d dir: %d", last_data_update.data.weather.report_text, - last_data_update.data.weather.temperature_c, last_data_update.data.weather.humidity, - last_data_update.data.weather.weather_code, - last_data_update.data.weather.wind, - last_data_update.data.weather.wind_direction); - watchfaces[watchface_settings.watchface_index]->set_weather(last_data_update.data.weather.temperature_c, - last_data_update.data.weather.weather_code); - } else if (last_data_update.type == BLE_COMM_DATA_TYPE_SET_TIME) { + if (last_data_update_type == BLE_COMM_DATA_TYPE_WEATHER) { + LOG_DBG("Weather: %s t: %d hum: %d code: %d wind: %d dir: %d", last_weather_data.report_text, + last_weather_data.temperature_c, last_weather_data.humidity, + last_weather_data.weather_code, + last_weather_data.wind, + last_weather_data.wind_direction); + watchfaces[watchface_settings.watchface_index]->set_weather(last_weather_data.temperature_c, + last_weather_data.weather_code); + } else if (last_data_update_type == BLE_COMM_DATA_TYPE_SET_TIME) { k_work_reschedule(&date_work.work, K_NO_WAIT); - } else if (last_data_update.type == BLE_COMM_DATA_TYPE_MUSIC_INFO) { - zsw_watchface_dropdown_ui_set_music_info(last_data_update.data.music_info.track_name, - last_data_update.data.music_info.artist); + } else if (last_data_update_type == BLE_COMM_DATA_TYPE_MUSIC_INFO) { + zsw_watchface_dropdown_ui_set_music_info(last_music_info.track_name, last_music_info.artist); } return; } @@ -375,14 +374,12 @@ static void update_ui_from_event(struct k_work *item) static void zbus_ble_comm_data_callback(const struct zbus_channel *chan) { const struct ble_data_event *event = zbus_chan_const_msg(chan); - // TODO getting this callback again before workqueue has ran will - // cause previous to be lost. - memcpy(&last_data_update, &event->data, sizeof(ble_comm_cb_data_t)); + last_data_update_type = event->data.type; if (event->data.type == BLE_COMM_DATA_TYPE_WEATHER) { - memcpy(&last_weather_data, &last_data_update.data.weather, sizeof(last_data_update.data.weather)); + memcpy(&last_weather_data, &event->data.data.weather, sizeof(event->data.data.weather)); } if (event->data.type == BLE_COMM_DATA_TYPE_MUSIC_INFO) { - memcpy(&last_music_info, &last_data_update.data.music_info, sizeof(last_data_update.data.music_info)); + memcpy(&last_music_info, &event->data.data.music_info, sizeof(event->data.data.music_info)); } if (running && !is_suspended) { k_work_submit(&update_ui_work); From 1dfbd5dedcd44b7576655e482880d900be74e17d Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Fri, 31 May 2024 20:00:43 +0200 Subject: [PATCH 21/26] ble_gadgetbridge: Refactor code to save stack. Stored pretty much same struct twice causing large stack usage. --- app/child_image/hci_ipc.conf | 2 +- app/src/applications/weather/CMakeLists.txt | 6 +- app/src/applications/weather/weather_app.c | 22 ++- app/src/applications/weather/weather_ui.c | 2 +- app/src/ble/ble_comm.c | 2 +- app/src/ble/ble_http.c | 1 + app/src/ble/gadgetbridge/ble_gadgetbridge.c | 147 ++++++++++---------- 7 files changed, 96 insertions(+), 86 deletions(-) diff --git a/app/child_image/hci_ipc.conf b/app/child_image/hci_ipc.conf index 09ae24e5..a4b4e04c 100644 --- a/app/child_image/hci_ipc.conf +++ b/app/child_image/hci_ipc.conf @@ -40,8 +40,8 @@ CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y # increase of ble throughput CONFIG_BT_BUF_ACL_RX_SIZE=502 CONFIG_BT_BUF_ACL_TX_SIZE=502 -CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 # Temporary fix as there is a strange behaviour with some Android # phones. CONFIG_BT_DATA_LEN_UPDATE=n +#CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/app/src/applications/weather/CMakeLists.txt b/app/src/applications/weather/CMakeLists.txt index f92d3fe4..ad8bd86c 100644 --- a/app/src/applications/weather/CMakeLists.txt +++ b/app/src/applications/weather/CMakeLists.txt @@ -1,2 +1,4 @@ -FILE(GLOB app_sources *.c) -target_sources(app PRIVATE ${app_sources}) +if (CONFIG_ZSWATCH_PCB_REV GREATER_EQUAL 4) + FILE(GLOB app_sources *.c) + target_sources(app PRIVATE ${app_sources}) +endif() \ No newline at end of file diff --git a/app/src/applications/weather/weather_app.c b/app/src/applications/weather/weather_app.c index fb82d32a..40e16c1a 100644 --- a/app/src/applications/weather/weather_app.c +++ b/app/src/applications/weather/weather_app.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "cJSON.h" #include "managers/zsw_app_manager.h" @@ -10,6 +11,8 @@ #include "weather_ui.h" #include +LOG_MODULE_REGISTER(weather_app, LOG_LEVEL_DBG); + #define HTTP_REQUEST_URL_FMT "https://api.open-meteo.com/v1/forecast?latitude=%f&longitude=%f¤t=wind_speed_10m,temperature_2m,apparent_temperature,weather_code&daily=weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,precipitation_sum,rain_sum,precipitation_probability_max&wind_speed_unit=ms&timezone=auto&forecast_days=%d" #define MAX_GPS_AGED_TIME_MS 30 * 60 * 1000 @@ -86,7 +89,7 @@ static void http_rsp_cb(ble_http_status_code_t status, char *response) last_update_weather_time = k_uptime_get(); ble_comm_request_gps_status(false); } else { - printk("HTTP request failed\n"); + LOG_ERR("HTTP request failed\n"); } } @@ -95,6 +98,7 @@ static void fetch_weather_data(double lat, double lon) char weather_url[512]; snprintf(weather_url, sizeof(weather_url), HTTP_REQUEST_URL_FMT, lat, lon, WEATHER_UI_NUM_FORECASTS); zsw_ble_http_get(weather_url, http_rsp_cb); + // TODO Handle if HTTP requests are not enabled or supported on phone. } static void on_zbus_ble_data_callback(const struct zbus_channel *chan) @@ -103,9 +107,9 @@ static void on_zbus_ble_data_callback(const struct zbus_channel *chan) if (event->data.type == BLE_COMM_DATA_TYPE_GPS) { last_update_gps_time = k_uptime_get(); - printk("Got GPS data, fetch weather\n"); - printk("Latitude: %f\n", event->data.data.gps.lat); - printk("Longitude: %f\n", event->data.data.gps.lon); + LOG_DBG("Got GPS data, fetch weather\n"); + LOG_DBG("Latitude: %f\n", event->data.data.gps.lat); + LOG_DBG("Longitude: %f\n", event->data.data.gps.lon); last_lat = event->data.data.gps.lat; last_lon = event->data.data.gps.lon; fetch_weather_data(event->data.data.gps.lat, event->data.data.gps.lon); @@ -115,8 +119,12 @@ static void on_zbus_ble_data_callback(const struct zbus_channel *chan) static void weather_app_start(lv_obj_t *root, lv_group_t *group) { if (last_update_gps_time == 0 || k_uptime_delta(&last_update_gps_time) > MAX_GPS_AGED_TIME_MS) { - printk("GPS data is too old, request GPS\n"); - ble_comm_request_gps_status(true); + LOG_DBG("GPS data is too old, request GPS\n"); + int res = ble_comm_request_gps_status(true); + if (res != 0) { + LOG_ERR("Failed to request GPS data\n"); + } + // TODO Show GPS fetching in progress in app } else { fetch_weather_data(last_lat, last_lon); } @@ -139,6 +147,8 @@ static int weather_app_add(void) { zsw_app_manager_add_application(&app); + // TODO Add periodic GPS and weather polling in backgrund. + return 0; } diff --git a/app/src/applications/weather/weather_ui.c b/app/src/applications/weather/weather_ui.c index b5b6f4d8..6af51852 100644 --- a/app/src/applications/weather/weather_ui.c +++ b/app/src/applications/weather/weather_ui.c @@ -81,7 +81,7 @@ void weather_ui_show(lv_obj_t *root) lv_obj_set_x(ui_location, 0); lv_obj_set_y(ui_location, 25); lv_obj_set_align(ui_location, LV_ALIGN_TOP_MID); - lv_label_set_text(ui_location, "Location..."); + lv_label_set_text(ui_location, ""); lv_obj_set_style_text_font(ui_location, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT); ui_forecast_widget = lv_obj_create(ui_root_container); diff --git a/app/src/ble/ble_comm.c b/app/src/ble/ble_comm.c index 4972f365..9fa23587 100644 --- a/app/src/ble/ble_comm.c +++ b/app/src/ble/ble_comm.c @@ -258,7 +258,7 @@ int ble_comm_request_gps_status(bool enable) char gps_status[50]; int len = snprintf(gps_status, sizeof(gps_status), "{\"t\":\"gps_power\", \"status\":%s} \n", enable ? "true" : "false"); - printk("Sending: %s", gps_status); + LOG_DBG("Request GPS: %s", gps_status); return ble_comm_send(gps_status, len); } diff --git a/app/src/ble/ble_http.c b/app/src/ble/ble_http.c index d82111a9..0b498762 100644 --- a/app/src/ble/ble_http.c +++ b/app/src/ble/ble_http.c @@ -78,6 +78,7 @@ int zsw_ble_http_get(char *url, ble_http_callback cb) char *request; if (request_pending) { + // TODO implement a queue for requests return -EBUSY; } diff --git a/app/src/ble/gadgetbridge/ble_gadgetbridge.c b/app/src/ble/gadgetbridge/ble_gadgetbridge.c index 330f629a..422a3378 100644 --- a/app/src/ble/gadgetbridge/ble_gadgetbridge.c +++ b/app/src/ble/gadgetbridge/ble_gadgetbridge.c @@ -37,12 +37,9 @@ static void parse_time_zone(char *offset); ZBUS_CHAN_DECLARE(ble_comm_data_chan); ZBUS_LISTENER_DEFINE(android_music_control_lis, music_control_event_callback); -static void send_ble_data_event(ble_comm_cb_data_t *data) +static void send_ble_data_event(struct ble_data_event *evt) { - struct ble_data_event evt; - memcpy(&evt.data, data, sizeof(ble_comm_cb_data_t)); - - zbus_chan_pub(&ble_comm_data_chan, &evt, K_MSEC(250)); + zbus_chan_pub(&ble_comm_data_chan, evt, K_MSEC(250)); } static void music_control_event_callback(const struct zbus_channel *chan) @@ -78,15 +75,15 @@ static void music_control_event_callback(const struct zbus_channel *chan) static void parse_time(char *start_time) { char *end_time; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); end_time = strstr(start_time, ")"); if (end_time) { errno = 0; - cb.data.notify.id = strtol(start_time, &end_time, 10); + cb.data.data.notify.id = strtol(start_time, &end_time, 10); if (start_time != end_time && errno == 0) { - cb.type = BLE_COMM_DATA_TYPE_SET_TIME; + cb.data.type = BLE_COMM_DATA_TYPE_SET_TIME; send_ble_data_event(&cb); } else { LOG_WRN("Failed parsing time"); @@ -104,16 +101,16 @@ static void parse_time(char *start_time) static void parse_time_zone(char *offset) { char *end_timezone; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); end_timezone = strstr(offset, ")"); if (end_timezone) { - cb.data.time.tz_offset = strtof(offset, &end_timezone); + cb.data.data.time.tz_offset = strtof(offset, &end_timezone); if (offset != end_timezone) { - cb.type = BLE_COMM_DATA_TYPE_SET_TIME; - LOG_DBG("set time offset: %.1f", cb.data.time.tz_offset); + cb.data.type = BLE_COMM_DATA_TYPE_SET_TIME; + LOG_DBG("set time offset: %.1f", cb.data.data.time.tz_offset); send_ble_data_event(&cb); } else { LOG_WRN("Failed parsing time"); @@ -384,35 +381,35 @@ static void convert_to_encoded_text(char *data, int len, char *out_data, int out static int parse_notify(char *data, int len) { - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_NOTIFY; - cb.data.notify.id = extract_value_uint32("\"id\":", data); - cb.data.notify.src = extract_value_str("\"src\":", data, &cb.data.notify.src_len); - cb.data.notify.sender = extract_value_str("\"sender\":", data, &cb.data.notify.sender_len); - cb.data.notify.title = extract_value_str("\"title\":", data, &cb.data.notify.title_len); - cb.data.notify.subject = extract_value_str("\"subject\":", data, &cb.data.notify.subject_len); - cb.data.notify.body = extract_value_str("\"body\":", data, &cb.data.notify.body_len); + cb.data.type = BLE_COMM_DATA_TYPE_NOTIFY; + cb.data.data.notify.id = extract_value_uint32("\"id\":", data); + cb.data.data.notify.src = extract_value_str("\"src\":", data, &cb.data.data.notify.src_len); + cb.data.data.notify.sender = extract_value_str("\"sender\":", data, &cb.data.data.notify.sender_len); + cb.data.data.notify.title = extract_value_str("\"title\":", data, &cb.data.data.notify.title_len); + cb.data.data.notify.subject = extract_value_str("\"subject\":", data, &cb.data.data.notify.subject_len); + cb.data.data.notify.body = extract_value_str("\"body\":", data, &cb.data.data.notify.body_len); // Little hack since we know it's JSON, we can terminate all values in the data // which saves us some hassle and we can just pass all values null terminated // to the callback. Make sure to do it after finish parsing! - if (cb.data.notify.src) { - cb.data.notify.src[cb.data.notify.src_len] = '\0'; + if (cb.data.data.notify.src) { + cb.data.data.notify.src[cb.data.data.notify.src_len] = '\0'; } - if (cb.data.notify.sender) { - cb.data.notify.sender[cb.data.notify.sender_len] = '\0'; + if (cb.data.data.notify.sender) { + cb.data.data.notify.sender[cb.data.data.notify.sender_len] = '\0'; } - if (cb.data.notify.title) { - cb.data.notify.title[cb.data.notify.title_len] = '\0'; + if (cb.data.data.notify.title) { + cb.data.data.notify.title[cb.data.data.notify.title_len] = '\0'; } - if (cb.data.notify.subject) { - cb.data.notify.subject[cb.data.notify.subject_len] = '\0'; + if (cb.data.data.notify.subject) { + cb.data.data.notify.subject[cb.data.data.notify.subject_len] = '\0'; } - if (cb.data.notify.body) { - cb.data.notify.body[cb.data.notify.body_len] = '\0'; + if (cb.data.data.notify.body) { + cb.data.data.notify.body[cb.data.data.notify.body_len] = '\0'; } send_ble_data_event(&cb); @@ -422,11 +419,11 @@ static int parse_notify(char *data, int len) static int parse_notify_delete(char *data, int len) { - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_NOTIFY_REMOVE; - cb.data.notify.id = extract_value_uint32("\"id\":", data); + cb.data.type = BLE_COMM_DATA_TYPE_NOTIFY_REMOVE; + cb.data.data.notify.id = extract_value_uint32("\"id\":", data); send_ble_data_event(&cb); @@ -439,22 +436,22 @@ static int parse_weather(char *data, int len) int temp_len; char *temp_value; float temperature; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_WEATHER; + cb.data.type = BLE_COMM_DATA_TYPE_WEATHER; int32_t temperature_k = extract_value_uint32("\"temp\":", data); - cb.data.weather.humidity = extract_value_uint32("\"hum\":", data); - cb.data.weather.weather_code = extract_value_uint32("\"code\":", data); - cb.data.weather.wind = extract_value_uint32("\"wind\":", data); - cb.data.weather.wind_direction = extract_value_uint32("\"wdir\":", data); + cb.data.data.weather.humidity = extract_value_uint32("\"hum\":", data); + cb.data.data.weather.weather_code = extract_value_uint32("\"code\":", data); + cb.data.data.weather.wind = extract_value_uint32("\"wind\":", data); + cb.data.data.weather.wind_direction = extract_value_uint32("\"wdir\":", data); temp_value = extract_value_str("\"txt\":", data, &temp_len); - strncpy(cb.data.weather.report_text, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); + strncpy(cb.data.data.weather.report_text, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); // App sends temperature in Kelvin temperature = temperature_k - 273.15f; - cb.data.weather.temperature_c = (int8_t)roundf(temperature); + cb.data.data.weather.temperature_c = (int8_t)roundf(temperature); send_ble_data_event(&cb); @@ -466,19 +463,19 @@ static int parse_musicinfo(char *data, int len) // {t:"musicinfo",artist:"Ava Max",album:"Heaven & Hell",track:"Sweet but Psycho",dur:187,c:-1,n:-1} char *temp_value; int temp_len; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_MUSIC_INFO; - cb.data.music_info.duration = extract_value_int32("\"dur\":", data); - cb.data.music_info.track_count = extract_value_int32("\"c\":", data); - cb.data.music_info.track_num = extract_value_int32("\"n\":", data); + cb.data.type = BLE_COMM_DATA_TYPE_MUSIC_INFO; + cb.data.data.music_info.duration = extract_value_int32("\"dur\":", data); + cb.data.data.music_info.track_count = extract_value_int32("\"c\":", data); + cb.data.data.music_info.track_num = extract_value_int32("\"n\":", data); temp_value = extract_value_str("\"artist\":", data, &temp_len); - strncpy(cb.data.music_info.artist, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); + strncpy(cb.data.data.music_info.artist, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); temp_value = extract_value_str("\"album\":", data, &temp_len); - strncpy(cb.data.music_info.album, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); + strncpy(cb.data.data.music_info.album, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); temp_value = extract_value_str("\"track\":", data, &temp_len); - strncpy(cb.data.music_info.track_name, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); + strncpy(cb.data.data.music_info.track_name, temp_value, MIN(temp_len, MAX_MUSIC_FIELD_LENGTH)); send_ble_data_event(&cb); @@ -490,19 +487,19 @@ static int parse_musicstate(char *data, int len) // {t:"musicinfo",artist:"Ava Max",album:"Heaven & Hell",track:"Sweet but Psycho",dur:187,c:-1,n:-1} char *temp_value; int temp_len; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_MUSIC_STATE; - cb.data.music_state.position = extract_value_int32("\"position\":", data); - cb.data.music_state.shuffle = extract_value_int32("\"shuffle\":", data); - cb.data.music_state.repeat = extract_value_int32("\"repeat\":", data); + cb.data.type = BLE_COMM_DATA_TYPE_MUSIC_STATE; + cb.data.data.music_state.position = extract_value_int32("\"position\":", data); + cb.data.data.music_state.shuffle = extract_value_int32("\"shuffle\":", data); + cb.data.data.music_state.repeat = extract_value_int32("\"repeat\":", data); temp_value = extract_value_str("\"state\":", data, &temp_len); if (strncmp(temp_value, "play", temp_len) == 0) { - cb.data.music_state.playing = true; + cb.data.data.music_state.playing = true; } else { - cb.data.music_state.playing = false; + cb.data.data.music_state.playing = false; } send_ble_data_event(&cb); @@ -515,22 +512,22 @@ static int parse_httpstate(char *data, int len) // {"t":"http","resp":"{\"response_code\":0,\"results\":[{\"type\":\"boolean\",\"difficulty\":\"easy\",\"category\":\"Geography\",\"question\":\"Hungary is the only country in the world beginning with H.\",\"correct_answer\":\"False\",\"incorrect_answers\":[\"True\"]}]}"} char *temp_value; int temp_len; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_HTTP; + cb.data.type = BLE_COMM_DATA_TYPE_HTTP; temp_value = extract_value_str("\"id\":", data, &temp_len); if (temp_value) { errno = 0; char *end_data; - cb.data.http_response.id = strtol(temp_value, &end_data, 10); + cb.data.data.http_response.id = strtol(temp_value, &end_data, 10); if (temp_value == end_data || errno != 0) { LOG_WRN("Failed parsing http request id"); - cb.data.http_response.id = -1; + cb.data.data.http_response.id = -1; } } else { - cb.data.http_response.id = -1; + cb.data.data.http_response.id = -1; } // {"t":"http","err":"Internet access not enabled in this Gadgetbridge build"} @@ -538,13 +535,13 @@ static int parse_httpstate(char *data, int len) if (temp_value != NULL) { LOG_ERR("HTTP err: %s", temp_value); - memcpy(cb.data.http_response.err, temp_value, temp_len); + memcpy(cb.data.data.http_response.err, temp_value, temp_len); send_ble_data_event(&cb); } else { temp_value = extract_value_str("\"resp\":", data, &temp_len); if (temp_value) { LOG_DBG("HTTP response: %s", temp_value); - memcpy(cb.data.http_response.response, temp_value, + memcpy(cb.data.data.http_response.response, temp_value, (strlen(temp_value) > MAX_HTTP_FIELD_LENGTH) ? MAX_HTTP_FIELD_LENGTH : strlen(temp_value)); /// @todo cast? send_ble_data_event(&cb); } @@ -556,10 +553,10 @@ static int parse_httpstate(char *data, int len) static int parse_gps_data(char *data, int len) { //{"t":"gps","lat":55.6135542,"lon":12.9747185,"alt":41.900001525878906,"speed":0.1458607256412506,"time":1717002933835,"satellites":0,"hdop":16.215999603271484,"externalSource":true,"gpsSource":"network"} - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); - cb.type = BLE_COMM_DATA_TYPE_GPS; + cb.data.type = BLE_COMM_DATA_TYPE_GPS; cJSON *root = cJSON_Parse(data); if (root == NULL) { @@ -574,13 +571,13 @@ static int parse_gps_data(char *data, int len) cJSON *satellites = cJSON_GetObjectItem(root, "satellites"); cJSON *hdop = cJSON_GetObjectItem(root, "hdop"); - cb.data.gps.lat = lat != NULL ? lat->valuedouble : -1; - cb.data.gps.lon = lon != NULL ? lon->valuedouble : -1; - cb.data.gps.alt = alt != NULL ? alt->valuedouble : -1; - cb.data.gps.speed = speed != NULL ? speed->valuedouble : -1; - cb.data.gps.time = time != NULL ? time->valuedouble : -1; - cb.data.gps.satellites = satellites != NULL ? satellites->valueint : -1; - cb.data.gps.hdop = hdop != NULL ? hdop->valuedouble : -1; + cb.data.data.gps.lat = lat != NULL ? lat->valuedouble : -1; + cb.data.data.gps.lon = lon != NULL ? lon->valuedouble : -1; + cb.data.data.gps.alt = alt != NULL ? alt->valuedouble : -1; + cb.data.data.gps.speed = speed != NULL ? speed->valuedouble : -1; + cb.data.data.gps.time = time != NULL ? time->valuedouble : -1; + cb.data.data.gps.satellites = satellites != NULL ? satellites->valueint : -1; + cb.data.data.gps.hdop = hdop != NULL ? hdop->valuedouble : -1; cJSON_Delete(root); @@ -639,7 +636,7 @@ static int parse_data(char *data, int len) static void parse_remote_control(char *data, int len) { int button; - ble_comm_cb_data_t cb; + struct ble_data_event cb; memset(&cb, 0, sizeof(cb)); button = atoi(data); @@ -648,8 +645,8 @@ static void parse_remote_control(char *data, int len) return; } - cb.type = BLE_COMM_DATA_TYPE_REMOTE_CONTROL; - cb.data.remote_control.button = button; + cb.data.type = BLE_COMM_DATA_TYPE_REMOTE_CONTROL; + cb.data.data.remote_control.button = button; send_ble_data_event(&cb); } From ca4e90420a4f35e28c7ea9daa1f982a09c5319cc Mon Sep 17 00:00:00 2001 From: Leonardo Bispo <34199302+ldab@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:01:52 +0200 Subject: [PATCH 22/26] update nrfjprog command on hw test (#310) * update nrfjprog command on hw test * chiperase --- app/pytest/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/pytest/utils.py b/app/pytest/utils.py index babffcb0..7dd72863 100644 --- a/app/pytest/utils.py +++ b/app/pytest/utils.py @@ -42,10 +42,9 @@ def flash(): "nrf53", "--snr", SERIAL_NUMBER, - "--recover", "--program", "./zswatch_nrf5340_cpuapp@3_debug.hex", - "--qspichiperase", + "--chiperase", "--verify", ], shell=False, @@ -62,13 +61,13 @@ def flash(): "nrf53", "--snr", SERIAL_NUMBER, - "--reset", "--program", "./zswatch_nrf5340_CPUNET.hex", "--coprocessor", "CP_NETWORK", - "--qspisectorerase", + "--sectorerase", "--verify", + "--reset", ], shell=False, stderr=subprocess.STDOUT, @@ -99,6 +98,7 @@ def read_rtt(target_device="nRF5340_XXAA", timeout_ms=10000): time.sleep(0.1) jlink.close() + print(read_data) log.debug(read_data) return read_data From 9ef38c3f83f68a0a4fc0ed9101a67359eb2f4ffe Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Sat, 13 Jul 2024 23:52:30 +0200 Subject: [PATCH 23/26] nPM1300: Fuel Guage: Fix missed changed in the fuel guage API since NCS 2.6 --- app/src/fuel_gauge/zsw_pmic.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/fuel_gauge/zsw_pmic.c b/app/src/fuel_gauge/zsw_pmic.c index 339906ce..beeb0b29 100755 --- a/app/src/fuel_gauge/zsw_pmic.c +++ b/app/src/fuel_gauge/zsw_pmic.c @@ -23,6 +23,9 @@ LOG_MODULE_REGISTER(zsw_pmic, LOG_LEVEL_WRN); #define ZSW_NOT_WORN_STATIONARY_CURRENT 0.0005 // 50uA. TODO remeasure this value and make Kconfig +/* nPM1300 CHARGER.BCHGCHARGESTATUS.CONSTANTCURRENT register bitmask */ +#define NPM1300_CHG_STATUS_CC_MASK BIT_MASK(3) + typedef enum { CHG_STATUS_BATTERYDETECTED = 1, // Battery is connected CHG_STATUS_COMPLETED = 2, // Charging completed (Battery Full) @@ -54,6 +57,7 @@ static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_char static float max_charge_current; static float term_charge_current; static int64_t ref_time; +static bool vbus_connected; static const struct battery_model battery_model = { #include "battery_model.inc" @@ -142,7 +146,7 @@ static int read_sensors(const struct device *charger, float *voltage, float *cur static int fuel_gauge_init(const struct device *charger) { struct sensor_value value; - struct nrf_fuel_gauge_init_parameters parameters = { .model = &battery_model }; + struct nrf_fuel_gauge_init_parameters parameters = { .model = &battery_model, .opt_params = NULL }; int ret; ret = read_sensors(charger, ¶meters.v0, ¶meters.i0, ¶meters.t0, NULL, NULL); @@ -177,9 +181,11 @@ static void event_callback(const struct device *dev, struct gpio_callback *cb, u LOG_DBG("Charging completed\n"); } if (BIT(NPM1300_EVENT_VBUS_DETECTED) & pins) { + vbus_connected = true; LOG_DBG("VBUS detected\n"); } if (BIT(NPM1300_EVENT_VBUS_REMOVED) & pins) { + vbus_connected = false; LOG_DBG("VBUS removed\n"); } if (BIT(NPM1300_EVENT_CHG_ERROR) & pins) { @@ -199,6 +205,7 @@ int zsw_pmic_get_full_state(struct battery_sample_event *sample) float tte; float ttf; float delta; + bool cc_charging; ret = read_sensors(charger, &voltage, ¤t, &temp, &status, &error); if (ret < 0) { @@ -206,11 +213,13 @@ int zsw_pmic_get_full_state(struct battery_sample_event *sample) return ret; } + cc_charging = (status & NPM1300_CHG_STATUS_CC_MASK) != 0; + delta = (float) k_uptime_delta(&ref_time) / 1000.f; soc = nrf_fuel_gauge_process(voltage, current, temp, delta, NULL); tte = nrf_fuel_gauge_tte_get(); - ttf = nrf_fuel_gauge_ttf_get(-max_charge_current, -term_charge_current); + ttf = nrf_fuel_gauge_ttf_get(cc_charging, -term_charge_current); LOG_DBG("V: %.3f, I: %.3f, T: %.2f, ", voltage, current, temp); LOG_DBG("SoC: %.2f, TTE: %.0f, TTF: %.0f\n", soc, tte, ttf); From 6bba8df88ff11c62cca1d9b766fa77207ea36243 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Sat, 13 Jul 2024 23:55:46 +0200 Subject: [PATCH 24/26] nPM1300: Fuel Guage: Support enter ship mode and battery cutoff. Ship mode turns off all power and enters lowest possible state. To exit ship mode BTN 3 needs to be pressed. Added safety for battery to enter ship mode when the battery is low voltage, but not low enough to trigger the battery protection circuit (typically at 3.0V). --- app/Kconfig | 2 + .../zswatch_nrf5340_cpuapp_5.overlay | 14 +++--- app/boards/npm1300_ek.overlay | 14 +++--- app/src/fuel_gauge/Kconfig | 7 +++ app/src/fuel_gauge/zsw_pmic.c | 45 ++++++++++++++----- app/src/fuel_gauge/zsw_pmic.h | 12 +++++ app/src/main.c | 6 ++- 7 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 app/src/fuel_gauge/Kconfig diff --git a/app/Kconfig b/app/Kconfig index 7d86abcb..32159cdd 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -135,6 +135,8 @@ menu "ZSWatch" int prompt "Idle timeout in seconds" default 20 + + rsource "src/fuel_gauge/Kconfig" endmenu endmenu diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay index 4fa2933a..93fc7f3d 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay @@ -200,23 +200,23 @@ resolution = <0>; frequency = <0>; }; - npm1300_ek_pmic: pmic@6b { + npm1300_pmic: pmic@6b { compatible = "nordic,npm1300"; reg = <0x6b>; host-int-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; pmic-int-pin = <4>; - npm1300_ek_gpio: gpio-controller { + npm1300_gpio: gpio-controller { compatible = "nordic,npm1300-gpio"; gpio-controller; #gpio-cells = <2>; ngpios = <5>; }; - npm1300_ek_regulators: regulators { + npm1300_regulators: regulators { compatible = "nordic,npm1300-regulator"; - npm1300_ek_buck1: BUCK1 { + npm1300_buck1: BUCK1 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; @@ -237,12 +237,12 @@ }; // LDO2 is not used - npm1300_ek_ldo2: LDO2 { + npm1300_ldo2: LDO2 { status = "disabled"; }; }; - npm1300_ek_charger: charger { + npm1300_charger: charger { compatible = "nordic,npm1300-charger"; term-microvolt = <4150000>; term-warm-microvolt = <4000000>; @@ -253,7 +253,7 @@ thermistor-beta = <3380>; charging-enable; }; - npm1300_ek_buttons: buttons { + npm1300_buttons: buttons { compatible = "gpio-keys"; status = "disabled"; }; diff --git a/app/boards/npm1300_ek.overlay b/app/boards/npm1300_ek.overlay index b30537cd..4a17b08c 100644 --- a/app/boards/npm1300_ek.overlay +++ b/app/boards/npm1300_ek.overlay @@ -15,36 +15,36 @@ &i2c3 { status = "okay"; - npm1300_ek_pmic: pmic@6b { + npm1300_pmic: pmic@6b { compatible = "nordic,npm1300"; reg = <0x6b>; host-int-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; pmic-int-pin = <4>; - npm1300_ek_gpio: gpio-controller { + npm1300_gpio: gpio-controller { compatible = "nordic,npm1300-gpio"; gpio-controller; #gpio-cells = <2>; ngpios = <5>; }; - npm1300_ek_regulators: regulators { + npm1300_regulators: regulators { compatible = "nordic,npm1300-regulator"; - npm1300_ek_buck1: BUCK1 { + npm1300_buck1: BUCK1 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; regulator-always-on; }; - npm1300_ek_buck2: regulator-buzzer-usb { + npm1300_buck2: regulator-buzzer-usb { regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; regulator-init-microvolt = <3000000>; }; - npm1300_ek_ldo1: regulator-3v3-ctrl { + npm1300_ldo1: regulator-3v3-ctrl { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-initial-mode = ; @@ -54,7 +54,7 @@ // LDO2 is not used }; - npm1300_ek_charger: charger { + npm1300_charger: charger { compatible = "nordic,npm1300-charger"; term-microvolt = <4150000>; term-warm-microvolt = <4000000>; diff --git a/app/src/fuel_gauge/Kconfig b/app/src/fuel_gauge/Kconfig new file mode 100644 index 00000000..3c39cbaf --- /dev/null +++ b/app/src/fuel_gauge/Kconfig @@ -0,0 +1,7 @@ + +config ZSW_PMIC_BATTERY_CUTOFF_VOLTAGE_MV + int "The voltage at which the system will be powered off. Running batteries as low as possible (until battery protection circuit triggers) will reduce the battery life." + depends on DT_HAS_NORDIC_NPM1300_ENABLED + default 3300 + help + Voltage in mV at which the system will be powered off. \ No newline at end of file diff --git a/app/src/fuel_gauge/zsw_pmic.c b/app/src/fuel_gauge/zsw_pmic.c index beeb0b29..1d751ceb 100755 --- a/app/src/fuel_gauge/zsw_pmic.c +++ b/app/src/fuel_gauge/zsw_pmic.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -51,8 +52,9 @@ ZBUS_LISTENER_DEFINE(zsw_pmic_slow_lis, zbus_periodic_slow_10s_callback); ZBUS_CHAN_DECLARE(battery_sample_data_chan); -static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_pmic)); -static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger)); +static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_pmic)); +static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_charger)); +static const struct device *regulators = DEVICE_DT_GET(DT_NODELABEL(npm1300_regulators)); static float max_charge_current; static float term_charge_current; @@ -96,6 +98,14 @@ static bool is_charging_from_status(int status) (status & CHG_STATUS_TRICKLECHARGE); } +static void check_battery_voltage_cutoff(int mV) +{ + if (mV <= CONFIG_ZSW_PMIC_BATTERY_CUTOFF_VOLTAGE_MV) { + LOG_WRN("Battery voltage below cutoff, entering power down mode\n"); + zsw_pmic_power_down(); + } +} + static void zbus_periodic_slow_10s_callback(const struct zbus_channel *chan) { int ret; @@ -108,6 +118,8 @@ static void zbus_periodic_slow_10s_callback(const struct zbus_channel *chan) } zbus_chan_pub(&battery_sample_data_chan, &evt, K_MSEC(50)); + + check_battery_voltage_cutoff(evt.mV); } static int read_sensors(const struct device *charger, float *voltage, float *current, float *temp, int *status, @@ -161,15 +173,9 @@ static int fuel_gauge_init(const struct device *charger) nrf_fuel_gauge_init(¶meters, NULL); - ref_time = k_uptime_get(); + LOG_WRN("nRF Fuel Gauge version: %s", nrf_fuel_gauge_version); - struct battery_sample_event evt; - ret = zsw_pmic_get_full_state(&evt); - if (ret == 0) { - zbus_chan_pub(&battery_sample_data_chan, &evt, K_MSEC(50)); - } else { - LOG_ERR("Error: Could not publish inital battery data.\n"); - } + ref_time = k_uptime_get(); return 0; } @@ -239,6 +245,14 @@ int zsw_pmic_get_full_state(struct battery_sample_event *sample) return ret; } +int zsw_pmic_power_down(void) +{ + if (vbus_connected) { + LOG_WRN("Can't enter power down/shipping mode while VBUS is connected"); + } + return regulator_parent_ship_mode(regulators); +} + static int zsw_pmic_init(void) { static struct gpio_callback event_cb; @@ -262,6 +276,17 @@ static int zsw_pmic_init(void) mfd_npm1300_add_callback(pmic, &event_cb); zsw_periodic_chan_add_obs(&periodic_event_10s_chan, &zsw_pmic_slow_lis); + + struct battery_sample_event evt; + int ret = zsw_pmic_get_full_state(&evt); + if (ret == 0) { + zbus_chan_pub(&battery_sample_data_chan, &evt, K_MSEC(50)); + } else { + LOG_ERR("Error: Could not publish inital battery data.\n"); + } + + check_battery_voltage_cutoff(evt.mV); + return 0; } diff --git a/app/src/fuel_gauge/zsw_pmic.h b/app/src/fuel_gauge/zsw_pmic.h index 201641e6..0be270c9 100755 --- a/app/src/fuel_gauge/zsw_pmic.h +++ b/app/src/fuel_gauge/zsw_pmic.h @@ -4,4 +4,16 @@ int zsw_pmic_get_full_state(struct battery_sample_event *sample); +/** + * @brief Powers down everything. Enter lowest power mode. + * + * This function is used to power down the PMIC and enter it's "ship mode". + * This consumes the least amount of power possible. + * + * To wakeup after this, the SW3 (Bottom right) needs to be held down for 10s. + * + * @return 0 if successful, otherwise an error code. + */ +int zsw_pmic_power_down(void); + #endif /* __ZSW_PMIC__H__ */ diff --git a/app/src/main.c b/app/src/main.c index e358e26a..aa80c2a4 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -60,6 +60,7 @@ #include "ble/ble_ancs.h" #include "ble/ble_cts.h" #include +#include "fuel_gauge/zsw_pmic.h" LOG_MODULE_REGISTER(main, CONFIG_ZSW_APP_LOG_LEVEL); @@ -551,7 +552,10 @@ static void on_watchface_app_event_callback(watchface_app_evt_t evt) sys_reboot(SYS_REBOOT_COLD); break; case WATCHFACE_APP_EVENT_SHUTDOWN: - // TODO enter nPM1300 ship mode or hibernate + int ret = zsw_pmic_power_down(); + if (ret) { + LOG_ERR("Failed to power down the system"); + } break; } } From b45498a0a1a5fc0a151e2b2b824c665be6aa77ac Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Mon, 15 Jul 2024 11:05:26 +0200 Subject: [PATCH 25/26] Add new battery model for v5 battery. --- .../zswatch_nrf5340_cpuapp_5.conf | 1 - .../zswatch_nrf5340_cpuapp_5.overlay | 9 +++++---- app/src/fuel_gauge/Kconfig | 2 +- app/src/fuel_gauge/battery_model.inc | 19 ------------------- app/src/fuel_gauge/ld403533.inc | 19 +++++++++++++++++++ app/src/fuel_gauge/zsw_pmic.c | 18 +++++++++++++++--- app/src/main.c | 2 ++ 7 files changed, 42 insertions(+), 28 deletions(-) delete mode 100755 app/src/fuel_gauge/battery_model.inc create mode 100644 app/src/fuel_gauge/ld403533.inc diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf index 5580bebd..65296226 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.conf @@ -46,4 +46,3 @@ CONFIG_SETTINGS_NVS=y CONFIG_NVS=y CONFIG_DEBUG_COREDUMP_BACKEND_OTHER=y - diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay index 93fc7f3d..4da685b1 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay @@ -244,13 +244,14 @@ npm1300_charger: charger { compatible = "nordic,npm1300-charger"; - term-microvolt = <4150000>; + term-microvolt = <4400000>; term-warm-microvolt = <4000000>; - current-microamp = <150000>; + current-microamp = <200000>; // 0.2C CC (constant current) charge to 4.4V, + term-current-percent = <10>; // then 4.4V CV(constant voltage) charge till charge current decline to ≤ 0.02C dischg-limit-microamp = <1000000>; vbus-limit-microamp = <500000>; - thermistor-ohms = <10000>; - thermistor-beta = <3380>; + thermistor-ohms = <10000>; // Not used + thermistor-beta = <3380>; // Not used charging-enable; }; npm1300_buttons: buttons { diff --git a/app/src/fuel_gauge/Kconfig b/app/src/fuel_gauge/Kconfig index 3c39cbaf..f7a273f9 100644 --- a/app/src/fuel_gauge/Kconfig +++ b/app/src/fuel_gauge/Kconfig @@ -4,4 +4,4 @@ config ZSW_PMIC_BATTERY_CUTOFF_VOLTAGE_MV depends on DT_HAS_NORDIC_NPM1300_ENABLED default 3300 help - Voltage in mV at which the system will be powered off. \ No newline at end of file + Voltage in mV at which the system will be powered off. diff --git a/app/src/fuel_gauge/battery_model.inc b/app/src/fuel_gauge/battery_model.inc deleted file mode 100755 index 7750e4f6..00000000 --- a/app/src/fuel_gauge/battery_model.inc +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -.param_1 = {0.0, 0.005, 0.01, 0.015, 0.02, 0.025, 0.03, 0.035, 0.04, 0.045, 0.05, 0.055, 0.06, 0.065, 0.07, 0.075, 0.08, 0.085, 0.09, 0.095, 0.1, 0.105, 0.11, 0.115, 0.12, 0.125, 0.13, 0.135, 0.14, 0.145, 0.15, 0.155, 0.16, 0.165, 0.17, 0.17500000000000002, 0.18, 0.185, 0.19, 0.195, 0.2, 0.20500000000000002, 0.21, 0.215, 0.22, 0.225, 0.23, 0.23500000000000001, 0.24, 0.245, 0.25, 0.255, 0.26, 0.265, 0.27, 0.275, 0.28, 0.28500000000000003, 0.29, 0.295, 0.3, 0.305, 0.31, 0.315, 0.32, 0.325, 0.33, 0.335, 0.34, 0.34500000000000003, 0.35000000000000003, 0.355, 0.36, 0.365, 0.37, 0.375, 0.38, 0.385, 0.39, 0.395, 0.4, 0.405, 0.41000000000000003, 0.41500000000000004, 0.42, 0.425, 0.43, 0.435, 0.44, 0.445, 0.45, 0.455, 0.46, 0.465, 0.47000000000000003, 0.47500000000000003, 0.48, 0.485, 0.49, 0.495, 0.5, 0.505, 0.51, 0.515, 0.52, 0.525, 0.53, 0.535, 0.54, 0.545, 0.55, 0.555, 0.56, 0.5650000000000001, 0.5700000000000001, 0.5750000000000001, 0.58, 0.585, 0.59, 0.595, 0.6, 0.605, 0.61, 0.615, 0.62, 0.625, 0.63, 0.635, 0.64, 0.645, 0.65, 0.655, 0.66, 0.665, 0.67, 0.675, 0.68, 0.685, 0.6900000000000001, 0.6950000000000001, 0.7000000000000001, 0.705, 0.71, 0.715, 0.72, 0.725, 0.73, 0.735, 0.74, 0.745, 0.75, 0.755, 0.76, 0.765, 0.77, 0.775, 0.78, 0.785, 0.79, 0.795, 0.8, 0.805, 0.81, 0.8150000000000001, 0.8200000000000001, 0.8250000000000001, 0.8300000000000001, 0.835, 0.84, 0.845, 0.85, 0.855, 0.86, 0.865, 0.87, 0.875, 0.88, 0.885, 0.89, 0.895, 0.9, 0.905, 0.91, 0.915, 0.92, 0.925, 0.93, 0.935, 0.9400000000000001, 0.9450000000000001, 0.9500000000000001, 0.9550000000000001, 0.96, 0.965, 0.97, 0.975, 0.98, 0.985, 0.99, 0.995, 1.0}, -.temps = {25.0}, -.param_2 = {2.99, 3.0, 3.0100000000000002, 3.02, 3.0300000000000002, 3.04, 3.0500000000000003, 3.06, 3.0700000000000003, 3.08, 3.0900000000000003, 3.1, 3.1100000000000003, 3.12, 3.1300000000000003, 3.14, 3.1500000000000004, 3.16, 3.1700000000000004, 3.18, 3.1900000000000004, 3.2, 3.2100000000000004, 3.22, 3.2300000000000004, 3.24, 3.25, 3.2600000000000002, 3.2700000000000005, 3.2800000000000002, 3.29, 3.3000000000000003, 3.31, 3.3200000000000003, 3.33, 3.3400000000000003, 3.35, 3.3600000000000003, 3.37, 3.3800000000000003, 3.39, 3.4000000000000004, 3.41, 3.4200000000000004, 3.43, 3.4400000000000004, 3.45, 3.4600000000000004, 3.47, 3.4800000000000004, 3.49, 3.5, 3.5100000000000002, 3.5200000000000005, 3.5300000000000002, 3.54, 3.5500000000000003, 3.5600000000000005, 3.5700000000000003, 3.58, 3.5900000000000003, 3.6, 3.6100000000000003, 3.62, 3.6300000000000003, 3.64, 3.6500000000000004, 3.66, 3.6700000000000004, 3.68, 3.6900000000000004, 3.7, 3.71, 3.72, 3.7300000000000004, 3.74, 3.75, 3.7600000000000002, 3.7700000000000005, 3.7800000000000002, 3.79, 3.8000000000000003, 3.8100000000000005, 3.8200000000000003, 3.83, 3.8400000000000003, 3.85, 3.8600000000000003, 3.87, 3.8800000000000003, 3.89, 3.9000000000000004, 3.91, 3.9200000000000004, 3.93, 3.9400000000000004, 3.95, 3.96, 3.97, 3.9800000000000004, 3.99, 4.0, 4.01, 4.0200000000000005, 4.03, 4.04, 4.050000000000001, 4.0600000000000005, 4.07, 4.08, 4.09, 4.1000000000000005, 4.11, 4.12, 4.130000000000001, 4.140000000000001, 4.15, 4.16, 4.17, 4.18, 4.19, 4.2}, -.param_3 = {0.1299220770568989, 0.1318970152283605, 0.1336137475016624, 0.1351049342434311, 0.13640323582029273, 0.1375413125988738, 0.13855182494580062, 0.13946722684278498, 0.14030768660030082, 0.14107438554674245, 0.14176777627266265, 0.14239482070597537, 0.1429653697347046, 0.1434912207255421, 0.14398765275569309, 0.14446778746313177, 0.14492546019369276, 0.1453456626623033, 0.1457199695693217, 0.14605242191718198, 0.14634765790625323, 0.14660314542107486, 0.14681249480701472, 0.14697039377791946, 0.14707398248570006, 0.14712310655848906, 0.147140822453063, 0.1471632268074566, 0.1472109454355584, 0.1472685636051096, 0.14731697892381013, 0.1473513932798648, 0.14737547686097363, 0.1473930104567189, 0.147407774856683, 0.1474234138002302, 0.1474420206954329, 0.14746470872712225, 0.1474925756181666, 0.1475267190914343, 0.14756822797319452, 0.14761808094840934, 0.14767718231718518, 0.14774643498150958, 0.14782674184337025, 0.14791877715019636, 0.148020114453046, 0.14812609443361152, 0.14823200857136296, 0.14833314834577052, 0.14842507842161412, 0.1485074223067443, 0.14858291334050872, 0.14865436401491425, 0.1487245868219676, 0.14879628722790905, 0.14887042704967898, 0.14894654916322644, 0.14902415522610227, 0.14910274689585734, 0.14918181680537904, 0.14926069595069513, 0.14933857571527928, 0.14941464289245174, 0.14948808427553284, 0.1495581255383171, 0.14962475964518676, 0.14968868231631552, 0.1497506152141534, 0.14981128000115063, 0.14987140349167438, 0.14993182503501065, 0.14999349330101894, 0.15005736146843715, 0.15012438271600329, 0.1501954623646621, 0.15027034381359963, 0.1503475734920229, 0.15042564295976094, 0.1505030437766423, 0.1505783273790346, 0.15065167321850276, 0.15072504167245543, 0.15080048365425014, 0.15088005007724437, 0.15096570929369338, 0.15105689997557956, 0.1511501214123438, 0.15124170781266708, 0.15132799338523056, 0.15140540067868385, 0.1514734299752179, 0.15153538483067783, 0.1515948042899758, 0.15165522739802356, 0.15172014209853235, 0.15179099590234907, 0.15186655413100122, 0.15194539963693887, 0.1520261152726121, 0.1521072883802784, 0.1521877134367661, 0.1522664745330155, 0.15234267732883552, 0.152415427484035, 0.1524838508389288, 0.1525481618553443, 0.15261019560569125, 0.1526719190495844, 0.15273529914663883, 0.15280228635838922, 0.1528737764921855, 0.15294899226963507, 0.15302700791086266, 0.1531068976359927, 0.15318773404259572, 0.15326846495464183, 0.15334782712688122, 0.15342453692277158, 0.15349731070577083, 0.1535648804807836, 0.15362745931949606, 0.1536879383397783, 0.15374949035647775, 0.1538152881844414, 0.15388848165997263, 0.15397029602987441, 0.15405860825026377, 0.1541509598926527, 0.15424489252855297, 0.15433795764695038, 0.1544287486019324, 0.15451780227409756, 0.1546058680776624, 0.15469369542684355, 0.15478203079768288, 0.15487122361456437, 0.15496082875473038, 0.15505030645216672, 0.15513911694085925, 0.15522672360691653, 0.155313156146518, 0.1553996610372542, 0.15548764238801308, 0.1555785043076826, 0.15567364730427266, 0.1557735751613931, 0.15587672113064513, 0.1559812271564549, 0.15608523518324866, 0.15618689321388138, 0.1562855984343868, 0.15638351803043957, 0.15648319135194694, 0.15658715774881618, 0.15669795232263672, 0.15681687473561953, 0.15694228219961673, 0.15707210327009066, 0.15720426650250363, 0.15733670147816864, 0.1574677859907665, 0.15759704594114265, 0.15772418846801153, 0.15784892071008727, 0.15797095097895394, 0.15809082255076992, 0.15821137981404557, 0.15833586017217285, 0.1584675010285439, 0.1586095392127628, 0.15876445680061327, 0.1589324953309709, 0.1591134825086583, 0.15930724603849794, 0.15951361361634245, 0.15973240478769357, 0.1599634159136927, 0.16020643926065334, 0.16046126709488862, 0.16072769077037916, 0.16100387158494234, 0.16128297939358363, 0.16155723190552868, 0.16181884683000328, 0.16206004241861355, 0.16227543418538273, 0.16246753753885523, 0.16264049284150792, 0.16279844045581784, 0.16294552074426188, 0.16308587406931715, 0.16322364079346047, 0.16336296127916894, 0.1635079758889195, 0.16366282498518916, 0.1638316489304548, 0.16401858808719347, 0.16422778281788206, 0.16446337348499768, 0.16472950045101722}, -.param_4 = {0.005196883082275956, 0.005275880609134421, 0.0053445499000664975, 0.005404197369737245, 0.005456129432811711, 0.005501652503954953, 0.005542072997832026, 0.0055786890737114, 0.005612307464012034, 0.0056429754218696995, 0.0056707110509065075, 0.0056957928282390154, 0.005718614789388186, 0.005739648829021685, 0.005759506110227725, 0.005778711498525272, 0.005797018407747712, 0.005813826506492133, 0.005828798782772869, 0.005842096876687281, 0.00585390631625013, 0.005864125816842996, 0.00587249979228059, 0.005878815751116779, 0.005882959299428004, 0.005884924262339564, 0.005885632898122522, 0.005886529072298266, 0.005888437817422338, 0.005890742544204385, 0.005892679156952406, 0.005894055731194593, 0.005895019074438946, 0.005895720418268757, 0.005896310994267321, 0.0058969365520092085, 0.005897680827817318, 0.005898588349084891, 0.005899703024726664, 0.005901068763657373, 0.005902729118927782, 0.005904723237936375, 0.005907087292687408, 0.0059098573992603836, 0.005913069673734811, 0.005916751086007856, 0.005920804578121841, 0.005925043777344462, 0.005929280342854519, 0.005933325933830822, 0.005937003136864566, 0.005940296892269773, 0.00594331653362035, 0.005946174560596571, 0.0059489834728787055, 0.005951851489116363, 0.005954817081987161, 0.005957861966529058, 0.005960966209044092, 0.005964109875834295, 0.005967272672215162, 0.005970427838027807, 0.005973543028611172, 0.005976585715698071, 0.005979523371021315, 0.0059823250215326855, 0.005984990385807472, 0.005987547292652621, 0.005990024608566137, 0.005992451200046027, 0.0059948561396669766, 0.0059972730014004275, 0.005999739732040758, 0.006002294458737487, 0.006004975308640133, 0.006007818494586485, 0.006010813752543987, 0.006013902939680918, 0.006017025718390438, 0.006020121751065694, 0.006023133095161385, 0.006026066928740112, 0.006029001666898219, 0.006032019346170006, 0.006035202003089776, 0.006038628371747737, 0.006042275999023184, 0.0060460048564937524, 0.006049668312506684, 0.006053119735409223, 0.006056216027147356, 0.006058937199008717, 0.006061415393227115, 0.006063792171599033, 0.006066209095920943, 0.006068805683941296, 0.006071639836093964, 0.006074662165240051, 0.006077815985477556, 0.006081044610904485, 0.006084291535211137, 0.0060875085374706445, 0.006090658981320621, 0.006093707093153422, 0.0060966170993614005, 0.006099354033557153, 0.006101926474213774, 0.0061044078242276515, 0.006106876761983378, 0.0061094119658655546, 0.00611209145433557, 0.006114951059687421, 0.006117959690785405, 0.006121080316434507, 0.0061242759054397095, 0.00612750936170383, 0.006130738598185674, 0.00613391308507525, 0.006136981476910865, 0.0061398924282308346, 0.006142595219231346, 0.006145098372779843, 0.006147517533591134, 0.006149979614259111, 0.006152611527377658, 0.006155539266398906, 0.0061588118411949775, 0.006162344330010552, 0.00616603839570611, 0.0061697957011421205, 0.006173518305878017, 0.006177149944077297, 0.006180712090963904, 0.006184234723106497, 0.006187747817073743, 0.006191281231907316, 0.0061948489445825755, 0.006198433150189216, 0.00620201225808667, 0.006205564677634372, 0.006209068944276662, 0.006212526245860721, 0.006215986441490169, 0.006219505695520524, 0.006223140172307305, 0.006226945892170908, 0.006230943006455725, 0.006235068845225807, 0.006239249086258197, 0.006243409407329948, 0.006247475728555257, 0.006251423937375473, 0.006255340721217585, 0.006259327654077879, 0.006263486309952648, 0.006267918092905471, 0.006272674989424782, 0.00627769128798467, 0.006282884130803627, 0.006288170660100147, 0.006293468059126747, 0.00629871143963066, 0.006303881837645707, 0.006308967538720463, 0.006313956828403492, 0.006318838039158159, 0.006323632902030798, 0.0063284551925618234, 0.0063334344068869146, 0.006338700041141758, 0.0063443815685105135, 0.006350578272024531, 0.006357299813238837, 0.0063645393003463335, 0.006372289841539918, 0.006380544544653699, 0.006389296191507744, 0.006398536636547709, 0.006408257570426135, 0.006418450683795545, 0.006429107630815167, 0.006440154863397695, 0.006451319175743347, 0.006462289276221148, 0.006472753873200132, 0.006482401696744544, 0.006491017367415311, 0.0064987015015542104, 0.006505619713660317, 0.006511937618232715, 0.006517820829770477, 0.006523434962772687, 0.00652894563173842, 0.006534518451166759, 0.006540319035556782, 0.006546512999407568, 0.006553265957218193, 0.00656074352348774, 0.006569111312715283, 0.006578534939399909, 0.00658918001804069}, -.param_5 = {0.015799505371692953, 0.01476668177905413, 0.012831676060282363, 0.011157953274521307, 0.009745513421770876, 0.008594356502031504, 0.007703656975644683, 0.007023446618000841, 0.006428634815829927, 0.00584035868944734, 0.005281740636931594, 0.004790373848167877, 0.004385600078266917, 0.004089132083953846, 0.003906266950358742, 0.0037512297519986908, 0.003511500796686117, 0.003178037502515711, 0.0028270370195147485, 0.0025107533477261405, 0.002202894015571489, 0.001859347603045975, 0.0014689934273783359, 0.001045950714741433, 0.000610851122278492, 0.00026735986945174844, 0.00016048099587022066, 0.00028049192998163067, 0.00042134719061186557, 0.00042413395300684373, 0.00033131869902084873, 0.0002339917486539507, 0.00016646870741642353, 0.00012919198283754124, 0.00012161337404510697, 0.00013698335499965839, 0.000165179707568245, 0.00020221969093464284, 0.0002480414572482263, 0.00030260942011179834, 0.0003654474279001993, 0.00043581737596259246, 0.000513416132400836, 0.0005982381047402695, 0.0006893686747472261, 0.0007734904387030235, 0.000829269133660604, 0.00084757647326782, 0.0008282156486360409, 0.0007722794010046885, 0.000697095843895084, 0.0006313396755783587, 0.0005877668326798036, 0.0005666939258355645, 0.0005676928519791902, 0.0005833609108455741, 0.0006010477412695184, 0.0006149127056930513, 0.0006247909305237033, 0.0006306463171070267, 0.0006317962193511974, 0.0006270356396009986, 0.0006157877670263413, 0.0005980342410142822, 0.0005739305834614843, 0.0005467014786156993, 0.0005222271119935569, 0.0005034222758664927, 0.0004903907393405751, 0.0004831531100839802, 0.00048218013544007107, 0.0004883592373781769, 0.0005021457337059734, 0.0005235576599374285, 0.0005524035848998056, 0.0005838443903853976, 0.0006084445094432615, 0.0006211965846451319, 0.0006218811384775882, 0.0006107376770946894, 0.0005945177674417969, 0.0005868571736834111, 0.000595241742989451, 0.0006200336191556841, 0.000660902557773034, 0.0007073995933408461, 0.0007376484746015807, 0.0007392313483499738, 0.000711487891547069, 0.0006547714640672136, 0.0005817463599493838, 0.0005199366079758523, 0.00048549725903158925, 0.0004793702693828804, 0.0005013512342263125, 0.0005430740173020809, 0.0005856481298754587, 0.0006176149383591532, 0.0006382445664434265, 0.0006475549733581283, 0.000646392656615969, 0.0006367446109483733, 0.0006198555682777364, 0.000595811804077976, 0.0005646940403731225, 0.0005309374852373316, 0.0005053790670498347, 0.0004950287769604246, 0.0005004141637903088, 0.0005214692352191984, 0.000553909382186666, 0.0005868236449834557, 0.0006129256747085948, 0.0006316214654304882, 0.0006429045269322649, 0.0006462692745964373, 0.0006403723371420367, 0.0006242878725190755, 0.0005979343155584384, 0.0005613742320480924, 0.0005205944549008766, 0.0004922314359788287, 0.0004881241479267988, 0.0005093993786523844, 0.0005559652139794889, 0.0006200313817319829, 0.0006805063611645817, 0.0007226554511132258, 0.0007451371131568518, 0.0007479910171906932, 0.000735424293517653, 0.0007193785085886882, 0.0007084779029199739, 0.0007035726109839643, 0.000704650880081932, 0.0007101127508832294, 0.0007151918281899684, 0.0007163313504094347, 0.0007131527445155758, 0.0007056686189992056, 0.0006961568226349427, 0.000691749721350686, 0.0006979449659803155, 0.0007153730817136168, 0.0007440196650383528, 0.0007802834148419938, 0.0008122953054899053, 0.0008306079802472381, 0.0008340562104140921, 0.0008226642297059356, 0.0008014530045525464, 0.0007864992662327992, 0.0007903716702405833, 0.0008145588735063505, 0.0008590438827591612, 0.0009188679472134191, 0.000977319507919957, 0.0010209141378845002, 0.001047937211547719, 0.0010583928323119537, 0.0010540779530512911, 0.0010413778518960151, 0.001025609908980249, 0.0010074990757785382, 0.0009870500437695988, 0.000967607362730577, 0.000961715340366473, 0.0009801504856116368, 0.001024484857993415, 0.001094716162359892, 0.0011878230882773726, 0.0012918244728323328, 0.0013961028321802203, 0.0014990028301081412, 0.0016005244307365496, 0.0017006349967825518, 0.0017992091894010291, 0.0018961378918391086, 0.001991404724783607, 0.0020850060389032525, 0.0021704179602149987, 0.002221154492817925, 0.002213441282345255, 0.0021434697456785765, 0.00201124205233957, 0.0018263494215178463, 0.0016299804809666828, 0.0014602346245006469, 0.0013236116678504335, 0.001220111611015956, 0.0011497344539972143, 0.0011124801967942952, 0.0011083488394071986, 0.0011373403818361848, 0.0011994548240809068, 0.0012946921661411044, 0.0014230524080172113, 0.001584535549709054, 0.0017791415912168929, 0.002006870532540641, 0.0021290157281561237}, -.param_6 = {0.39498763429232087, 0.3691670444763512, 0.3207919015070587, 0.2789488318630323, 0.24363783554427199, 0.21485891255078882, 0.19259142439111698, 0.17558616545002015, 0.1607158703957473, 0.14600896723618306, 0.13204351592329133, 0.1197593462041957, 0.10964000195667345, 0.10222830209884737, 0.0976566737589668, 0.0937807437999677, 0.08778751991715406, 0.07945093756289434, 0.0706759254878675, 0.06276883369315256, 0.05507235038928748, 0.04648369007614894, 0.03672483568445961, 0.026148767868533485, 0.015271278056960824, 0.006683996736295272, 0.004012024896754562, 0.007012298249539639, 0.010533679765298287, 0.01060334882517222, 0.008282967475520264, 0.0058497937163504155, 0.004161717685410848, 0.003229799570936276, 0.003040334351128715, 0.0034245838749918933, 0.004129492689206038, 0.005055492273367546, 0.006201036431205398, 0.0075652355027933105, 0.009136185697503074, 0.010895434399066373, 0.012835403310024196, 0.01495595261850613, 0.017234216868677876, 0.019337260967575154, 0.020731728341516487, 0.02118941183169576, 0.020705391215899982, 0.01930698502511652, 0.017427396097377534, 0.01578349188945949, 0.014694170816995089, 0.014167348145888159, 0.014192321299480448, 0.014584022771138572, 0.015026193531739174, 0.015372817642328451, 0.01561977326308972, 0.015766157927676883, 0.015794905483779154, 0.015675890990024532, 0.015394694175660528, 0.014950856025355841, 0.014348264586536152, 0.013667536965392135, 0.013055677799841958, 0.012585556896663186, 0.012259768483510736, 0.012078827752098897, 0.012054503386002557, 0.012208980934455549, 0.012553643342649856, 0.013088941498434759, 0.013810089622495747, 0.014596109759634768, 0.01521111273607989, 0.015529914616130291, 0.015547028461940227, 0.015268441927365761, 0.014862944186044835, 0.014671429342083542, 0.014881043574738184, 0.015500840478893663, 0.016522563944323942, 0.01768498983351907, 0.018441211865041773, 0.018480783708751947, 0.017787197288676726, 0.016369286601677913, 0.014543658998733555, 0.012998415199397262, 0.012137431475789384, 0.011984256734573484, 0.012533780855655818, 0.013576850432550636, 0.014641203246887335, 0.015440373458980305, 0.015956114161086443, 0.016188874333952774, 0.016159816415400874, 0.015918615273710635, 0.015496389206942629, 0.014895295101949313, 0.014117351009326762, 0.01327343713093121, 0.012634476676245954, 0.012375719424009834, 0.01251035409475798, 0.01303673088048074, 0.013847734554667257, 0.014670591124585353, 0.015323141867715218, 0.015790536635762464, 0.016072613173306882, 0.01615673186491362, 0.01600930842854953, 0.015607196812975066, 0.014948357888960873, 0.01403435580120127, 0.01301486137252339, 0.012305785899471844, 0.012203103698169016, 0.01273498446630883, 0.01389913034948731, 0.015500784543301394, 0.017012659029114197, 0.018066386277829083, 0.018628427828920602, 0.018699775429767418, 0.018385607337942367, 0.017984462714717986, 0.01771194757300143, 0.017589315274599282, 0.01761627200204674, 0.017752818772082124, 0.017879795704750512, 0.017908283760234567, 0.0178288186128861, 0.017641715474980835, 0.017403920565875475, 0.01729374303376663, 0.01744862414950754, 0.017884327042841375, 0.01860049162595856, 0.019507085371048283, 0.02030738263724685, 0.020765199506181387, 0.020851405260352562, 0.020566605742647348, 0.0200363251138147, 0.019662481655818853, 0.01975929175601354, 0.020363971837661365, 0.021476097068978683, 0.022971698680335217, 0.024432987698000397, 0.025522853447113025, 0.02619843028869029, 0.02645982080779763, 0.026351948826286442, 0.026034446297401592, 0.025640247724503795, 0.025187476894461547, 0.024676251094241097, 0.02419018406826512, 0.024042883509162172, 0.02450376214029326, 0.02561212144983338, 0.027367904058994696, 0.02969557720693683, 0.03229561182080953, 0.03490257080450421, 0.0374750707527044, 0.04001311076841374, 0.0425158749195631, 0.04498022973502547, 0.047403447295976675, 0.0497851181195913, 0.052125150972581746, 0.05426044900537219, 0.055528862320447514, 0.0553360320586338, 0.053586743641964585, 0.05028105130848726, 0.04565873553794564, 0.040749512024168544, 0.03650586561251834, 0.0330902916962611, 0.03050279027539682, 0.02874336134993105, 0.027812004919858246, 0.027708720985178403, 0.028433509545902624, 0.029986370602022583, 0.03236730415352995, 0.03557631020043028, 0.03961338874272635, 0.044478539780420934, 0.050171763313516804, 0.05322539320390951}, -.param_7 = {-0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, 2.726014827871891e-05, 6.763843163170183e-05, 0.00010801671498468301, 0.00014839499833766415, 0.00018877328169064704, 0.00023358417230008108, 0.00028003556972066917, 0.0003264869671412552, 0.0003729383645618432, 0.00042241915635444024, 0.000475896437809689, 0.0005293737192649355, 0.0005828510007201843, 0.000641867873889981, 0.000703290130870259, 0.0007647123878505347, 0.0008299939436096057, 0.0009000635686056611, 0.0009701331936017197, 0.0010454795742642579, 0.0011243946051735, 0.0012038526777018784, 0.0012909669969474492, 0.0013780813161930155, 0.0014712084190221261, 0.0015660905503541477, 0.0016670844945574233, 0.0017710948280292569, 0.0018833495984950735, 0.001998520480445669, 0.002125695858864398, 0.0022584545052075702, 0.002398397520936245, 0.002550046209407664, 0.002707967550307293, 0.0028710834940602376, 0.0030392310231441674, 0.003215127416459396, 0.0034061713264827496, 0.0036223607954924725, 0.003870838099874473, 0.004163864585117863, 0.004585648922486361, 0.006296421287985141, 0.008628888245639727, 0.009454447851039889, 0.01032886330408122, 0.01142067279467966, 0.012439115377603142, 0.013610427080704361, 0.01487569766744738, 0.015923457038514683, 0.016955959639753108, 0.017848525769070343, 0.019074052894390327, 0.02009035740114929, 0.021191076445437114, 0.022380289068091943, 0.02338033485905311, 0.02457436916253643, 0.02556419613157401, 0.026436990118674997, 0.027336726471229904, 0.02824331794870222, 0.02910784168771883, 0.029879923420794284, 0.030678512175237028, 0.0313599912226432, 0.031966462655816125, 0.03258540835578722, 0.033239954062758106, 0.033856820157485666, 0.034359601989925936, 0.034780985910752245, 0.03515414607610232, 0.03549163866863326, 0.03580416725189261, 0.03609779469719258, 0.03638471834477571, 0.03668195997738435, 0.03701555296073624, 0.03742384124540005, 0.03793084775610587, 0.03850350629421154, 0.039026637378912564, 0.03945045011795685, 0.03979147103445483, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217}, -.param_8 = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0904059311487566e-06, 2.7055372652680742e-06, 4.320668599387321e-06, 5.935799933506567e-06, 7.550931267625884e-06, 9.343366892003246e-06, 1.1201422788826769e-05, 1.305947868565021e-05, 1.4917534582473731e-05, 1.6896766254177614e-05, 1.9035857512387564e-05, 2.1174948770597423e-05, 2.3314040028807377e-05, 2.5674714955599245e-05, 2.8131605234810368e-05, 3.0588495514021395e-05, 3.319975774438423e-05, 3.600254274422645e-05, 3.8805327744068794e-05, 4.181918297057032e-05, 4.497578420694001e-05, 4.815410710807515e-05, 5.1638679877897974e-05, 5.512325264772063e-05, 5.884833676088506e-05, 6.264362201416593e-05, 6.668337978229694e-05, 7.084379312117029e-05, 7.533398393980294e-05, 7.994081921782678e-05, 8.502783435457593e-05, 9.033818020830283e-05, 9.593590083744982e-05, 0.0001020018483763066, 0.00010831870201229175, 0.00011484333976240952, 0.00012156924092576671, 0.00012860509665837586, 0.00013624685305931, 0.00014489443181969893, 0.00015483352399497894, 0.00016655458340471456, 0.00018342595689945448, 0.00025185685151940567, 0.00034515552982558915, 0.0003781779140415956, 0.0004131545321632488, 0.0004568269117871865, 0.0004975646151041258, 0.0005444170832281745, 0.0005950279066978954, 0.0006369382815405874, 0.0006782383855901245, 0.0007139410307628138, 0.0007629621157756132, 0.0008036142960459718, 0.0008476430578174847, 0.0008952115627236778, 0.0009352133943621246, 0.0009829747665014573, 0.0010225678452629606, 0.001057479604747, 0.0010934690588491965, 0.001129732717948089, 0.0011643136675087533, 0.0011951969368317716, 0.0012271404870094814, 0.0012543996489057284, 0.001278658506232645, 0.001303416334231489, 0.0013295981625103246, 0.0013542728062994269, 0.0013743840795970377, 0.00139123943643009, 0.001406165843044093, 0.0014196655467453307, 0.0014321666900757046, 0.0014439117878877034, 0.0014553887337910288, 0.001467278399095374, 0.0014806221184294499, 0.0014969536498160023, 0.001517233910244235, 0.0015401402517684617, 0.0015610654951565028, 0.0015780180047182744, 0.0015916588413781936, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685}, -.param_9 = {1.8232226292464735}, -.param_10 = {1110.7214904863413, 9.285274962677075}, -.param_11 = {2.1819044922278756, 0.016907295574778852}, -.param_12 = {0.29978963276131065}, -.name = {'z', 's', 'w', 'a', 't', 'c', 'h', '1'}, diff --git a/app/src/fuel_gauge/ld403533.inc b/app/src/fuel_gauge/ld403533.inc new file mode 100644 index 00000000..f99b99e8 --- /dev/null +++ b/app/src/fuel_gauge/ld403533.inc @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +.param_1 = {0.0, 0.005, 0.01, 0.015, 0.02, 0.025, 0.03, 0.035, 0.04, 0.045, 0.05, 0.055, 0.06, 0.065, 0.07, 0.075, 0.08, 0.085, 0.09, 0.095, 0.1, 0.105, 0.11, 0.115, 0.12, 0.125, 0.13, 0.135, 0.14, 0.145, 0.15, 0.155, 0.16, 0.165, 0.17, 0.17500000000000002, 0.18, 0.185, 0.19, 0.195, 0.2, 0.20500000000000002, 0.21, 0.215, 0.22, 0.225, 0.23, 0.23500000000000001, 0.24, 0.245, 0.25, 0.255, 0.26, 0.265, 0.27, 0.275, 0.28, 0.28500000000000003, 0.29, 0.295, 0.3, 0.305, 0.31, 0.315, 0.32, 0.325, 0.33, 0.335, 0.34, 0.34500000000000003, 0.35000000000000003, 0.355, 0.36, 0.365, 0.37, 0.375, 0.38, 0.385, 0.39, 0.395, 0.4, 0.405, 0.41000000000000003, 0.41500000000000004, 0.42, 0.425, 0.43, 0.435, 0.44, 0.445, 0.45, 0.455, 0.46, 0.465, 0.47000000000000003, 0.47500000000000003, 0.48, 0.485, 0.49, 0.495, 0.5, 0.505, 0.51, 0.515, 0.52, 0.525, 0.53, 0.535, 0.54, 0.545, 0.55, 0.555, 0.56, 0.5650000000000001, 0.5700000000000001, 0.5750000000000001, 0.58, 0.585, 0.59, 0.595, 0.6, 0.605, 0.61, 0.615, 0.62, 0.625, 0.63, 0.635, 0.64, 0.645, 0.65, 0.655, 0.66, 0.665, 0.67, 0.675, 0.68, 0.685, 0.6900000000000001, 0.6950000000000001, 0.7000000000000001, 0.705, 0.71, 0.715, 0.72, 0.725, 0.73, 0.735, 0.74, 0.745, 0.75, 0.755, 0.76, 0.765, 0.77, 0.775, 0.78, 0.785, 0.79, 0.795, 0.8, 0.805, 0.81, 0.8150000000000001, 0.8200000000000001, 0.8250000000000001, 0.8300000000000001, 0.835, 0.84, 0.845, 0.85, 0.855, 0.86, 0.865, 0.87, 0.875, 0.88, 0.885, 0.89, 0.895, 0.9, 0.905, 0.91, 0.915, 0.92, 0.925, 0.93, 0.935, 0.9400000000000001, 0.9450000000000001, 0.9500000000000001, 0.9550000000000001, 0.96, 0.965, 0.97, 0.975, 0.98, 0.985, 0.99, 0.995, 1.0}, +.temps = {25.0}, +.param_2 = {2.99, 3.001652892561984, 3.013305785123967, 3.0249586776859507, 3.036611570247934, 3.0482644628099176, 3.0599173553719012, 3.0715702479338844, 3.083223140495868, 3.0948760330578513, 3.106528925619835, 3.118181818181818, 3.129834710743802, 3.1414876033057855, 3.1531404958677687, 3.1647933884297523, 3.176446280991736, 3.188099173553719, 3.199752066115703, 3.211404958677686, 3.2230578512396697, 3.234710743801653, 3.2463636363636366, 3.25801652892562, 3.2696694214876034, 3.281322314049587, 3.2929752066115707, 3.304628099173554, 3.3162809917355376, 3.327933884297521, 3.3395867768595044, 3.3512396694214877, 3.3628925619834713, 3.374545454545455, 3.386198347107438, 3.397851239669422, 3.409504132231405, 3.4211570247933887, 3.432809917355372, 3.4444628099173555, 3.456115702479339, 3.4677685950413224, 3.479421487603306, 3.4910743801652897, 3.502727272727273, 3.5143801652892566, 3.5260330578512398, 3.5376859504132234, 3.5493388429752066, 3.5609917355371903, 3.572644628099174, 3.584297520661157, 3.595950413223141, 3.6076033057851244, 3.6192561983471077, 3.6309090909090913, 3.6425619834710745, 3.654214876033058, 3.6658677685950414, 3.677520661157025, 3.6891735537190087, 3.700826446280992, 3.7124793388429755, 3.724132231404959, 3.7357851239669424, 3.7474380165289256, 3.7590909090909093, 3.770743801652893, 3.782396694214876, 3.7940495867768598, 3.8057024793388434, 3.8173553719008266, 3.8290082644628103, 3.8406611570247935, 3.852314049586777, 3.8639669421487604, 3.875619834710744, 3.8872727272727277, 3.898925619834711, 3.9105785123966945, 3.922231404958678, 3.9338842975206614, 3.945537190082645, 3.9571900826446282, 3.968842975206612, 3.980495867768595, 3.9921487603305787, 4.003801652892562, 4.015454545454546, 4.027107438016529, 4.038760330578513, 4.050413223140496, 4.062066115702479, 4.073719008264463, 4.085371900826447, 4.09702479338843, 4.108677685950413, 4.120330578512397, 4.13198347107438, 4.1436363636363645, 4.155289256198348, 4.166942148760331, 4.178595041322314, 4.190247933884297, 4.201900826446281, 4.213553719008265, 4.225206611570249, 4.236859504132232, 4.248512396694215, 4.260165289256198, 4.271818181818182, 4.283471074380166, 4.295123966942149, 4.306776859504133, 4.318429752066116, 4.330082644628099, 4.3417355371900825, 4.353388429752067, 4.36504132231405, 4.376694214876033, 4.388347107438017, 4.4}, +.param_3 = {0.08465246112468988, 0.10965559917312581, 0.12522898158821613, 0.13364875650000183, 0.13719107203852376, 0.13813207633382288, 0.13868872163556392, 0.13970963043177667, 0.1406911096550949, 0.1414455157200681, 0.14211594182945242, 0.14276789332677572, 0.14339471136819607, 0.14397731296248933, 0.14449116580178709, 0.1449340142179776, 0.14531886678943323, 0.1456691184411909, 0.14601031887981292, 0.14633804377407653, 0.14663284446054906, 0.14687516071778295, 0.14704950259613442, 0.14716431511747186, 0.14723676355018248, 0.14728402578148683, 0.14732102730477042, 0.14735327365512313, 0.14738380815195196, 0.14741567313136292, 0.1474505275567393, 0.1474858909896273, 0.14751851207339264, 0.14754515973987453, 0.14756642136127732, 0.14759117808226876, 0.14762939908715753, 0.14769093915246476, 0.1477782125766674, 0.14788175692134634, 0.14799104680266542, 0.14809578339647828, 0.14819291027801726, 0.1482879622849199, 0.1483869730563807, 0.14849561889505478, 0.14861291346086658, 0.1487319723449963, 0.1488457074294358, 0.14894780922901826, 0.14904129592338036, 0.14913533727111988, 0.14923921173630667, 0.1493606948817769, 0.14949532388313644, 0.14963267453369686, 0.14976228265498237, 0.14987562021185705, 0.14997524139651064, 0.15006763667800505, 0.1501593012277985, 0.15025526916648824, 0.1503545932798249, 0.15045479593638664, 0.15055340057013983, 0.15064924301688148, 0.15074502710151708, 0.15084416572587206, 0.15095005882918242, 0.15106375875884331, 0.1511812642862192, 0.1512979180683621, 0.15140910114879624, 0.1515126841851651, 0.15161050792926262, 0.15170476798114593, 0.1517976624724549, 0.15189147118652357, 0.15198857118354053, 0.15209134521037476, 0.15220197351742412, 0.1523187995012039, 0.15243673680125785, 0.1525505783012739, 0.15265561033666086, 0.15275314283949293, 0.15284851281232906, 0.15294713099851295, 0.15305375470602423, 0.15316770187852358, 0.15328559149757556, 0.15340402310334764, 0.15352015992528753, 0.1536344668332435, 0.1537486071235159, 0.1538642457801462, 0.15398226653651226, 0.15410027637733467, 0.15421502333950704, 0.1543232565979709, 0.15442348606448336, 0.15451953604121374, 0.15461622952950937, 0.15471837828442872, 0.15482855523129288, 0.15494440774683493, 0.15506292740018135, 0.15518112512710552, 0.15529733911506935, 0.15541206589660655, 0.15552600000962305, 0.15563983004471993, 0.15575404506932436, 0.1558688919313379, 0.15598460289130386, 0.15610136242175815, 0.15621842269885886, 0.15633418782483163, 0.1564470310057364, 0.15655568187891286, 0.156663330032997, 0.1567762001966348, 0.15690057526826548, 0.15704152457980727, 0.15719381266217541, 0.1573470054660149, 0.15749062907952674, 0.15761639410216877, 0.15772903141242534, 0.157838075862973, 0.15795306991432084, 0.15808180667691832, 0.15822463893666971, 0.15837994174701134, 0.15854608997062328, 0.15872115432475284, 0.15890227657694997, 0.1590864217618659, 0.15927056008150917, 0.15945272972951183, 0.15963333837011764, 0.15981311221212408, 0.15999277441714319, 0.16017283656592904, 0.16035346459376937, 0.1605347925341409, 0.16071702036052576, 0.1609025585556567, 0.16109650017694713, 0.16130409974506066, 0.16153043386058902, 0.16177713741302277, 0.16204273030244817, 0.16232562005707638, 0.16262374188819095, 0.16292919652580665, 0.16323015056622517, 0.16351469696039792, 0.16377255132119423, 0.1640069774804709, 0.16422797873525002, 0.16444560739774614, 0.16466782078312459, 0.16489033385049603, 0.16510442752379584, 0.16530137658211025, 0.1654757465644344, 0.16563579147675633, 0.16579332399982902, 0.1659601538963667, 0.16614417582628768, 0.16634164080156766, 0.16654664508608902, 0.16675329236470898, 0.16695703624398806, 0.16715623926686946, 0.16734964210275782, 0.1675360178221507, 0.16771620903602608, 0.16789434045007992, 0.1680748279677435, 0.1682619796680133, 0.1684566957012051, 0.1686558557501551, 0.16885610811529198, 0.1690542614215438, 0.1692500894417557, 0.16944597792620264, 0.1696444019592529, 0.16984771591806003, 0.17005684019137424, 0.17027175519205892, 0.17049242498712738, 0.17071881364359318, 0.17095088522846968, 0.17118860380877043, 0.17143193345150873, 0.17168083822369806, 0.17193528219235188, 0.1721952294244837, 0.1724606439871068}, +.param_4 = {0.0033860984449875955, 0.004386223966925033, 0.005009159263528646, 0.005345950260000074, 0.005487642881540951, 0.005525283053352916, 0.005547548865422558, 0.005588385217271068, 0.005627644386203797, 0.005657820628802726, 0.0056846376731780985, 0.00571071573307103, 0.005735788454727844, 0.005759092518499574, 0.005779646632071485, 0.005797360568719105, 0.00581275467157733, 0.005826764737647638, 0.005840412755192518, 0.005853521750963062, 0.005865313778421964, 0.0058750064287113185, 0.005881980103845378, 0.005886572604698875, 0.0058894705420073, 0.0058913610312594745, 0.005892841092190819, 0.005894130946204926, 0.00589535232607808, 0.005896626925254518, 0.005898021102269573, 0.005899435639585094, 0.005900740482935706, 0.005901806389594983, 0.005902656854451093, 0.0059036471232907515, 0.005905175963486302, 0.005907637566098591, 0.0059111285030666975, 0.005915270276853854, 0.005919641872106618, 0.005923831335859132, 0.005927716411120691, 0.005931518491396797, 0.00593547892225523, 0.005939824755802192, 0.005944516538434664, 0.005949278893799852, 0.005953828297177433, 0.005957912369160732, 0.005961651836935216, 0.005965413490844796, 0.005969568469452268, 0.005974427795271077, 0.005979812955325459, 0.0059853069813478755, 0.005990491306199296, 0.005995024808474284, 0.005999009655860427, 0.006002705467120203, 0.0060063720491119405, 0.00601021076665953, 0.006014183731192997, 0.006018191837455466, 0.006022136022805594, 0.00602596972067526, 0.006029801084060684, 0.0060337666290348835, 0.006038002353167298, 0.006042550350353734, 0.006047250571448769, 0.006051916722734484, 0.006056364045951851, 0.006060507367406605, 0.006064420317170506, 0.006068190719245839, 0.006071906498898197, 0.006075658847460945, 0.0060795428473416225, 0.006083653808414992, 0.006088078940696966, 0.006092751980048158, 0.006097469472050315, 0.006102023132050957, 0.006106224413466436, 0.006110125713579718, 0.006113940512493164, 0.00611788523994052, 0.0061221501882409695, 0.0061267080751409445, 0.006131423659903024, 0.006136160924133906, 0.006140806397011502, 0.006145378673329741, 0.006149944284940637, 0.006154569831205849, 0.006159290661460492, 0.006164011055093389, 0.006168600933580282, 0.0061729302639188365, 0.006176939442579336, 0.006180781441648551, 0.006184649181180377, 0.0061887351313771495, 0.006193142209251716, 0.006197776309873398, 0.006202517096007255, 0.006207245005084222, 0.006211893564602775, 0.006216482635864264, 0.006221040000384924, 0.006225593201788799, 0.006230161802772975, 0.006234755677253517, 0.006239384115652156, 0.006244054496870328, 0.006248736907954355, 0.006253367512993267, 0.006257881240229457, 0.006262227275156515, 0.006266533201319882, 0.006271048007865394, 0.00627602301073062, 0.006281660983192292, 0.006287752506487018, 0.006293880218640597, 0.00629962516318107, 0.0063046557640867515, 0.006309161256497014, 0.00631352303451892, 0.006318122796572834, 0.006323272267076734, 0.00632898555746679, 0.006335197669880454, 0.006341843598824932, 0.006348846172990114, 0.006356091063078, 0.006363456870474637, 0.006370822403260368, 0.006378109189180475, 0.0063853335348047074, 0.0063925244884849635, 0.006399710976685729, 0.006406913462637162, 0.006414138583750776, 0.006421391701365638, 0.0064286808144210315, 0.006436102342226269, 0.006443860007077887, 0.006452163989802427, 0.006461217354423562, 0.006471085496520913, 0.006481709212097928, 0.006493024802283057, 0.006504949675527639, 0.006517167861032267, 0.006529206022649008, 0.006540587878415918, 0.00655090205284777, 0.006560279099218838, 0.006569119149410002, 0.006577824295909847, 0.006586712831324984, 0.006595613354019842, 0.006604177100951835, 0.006612055063284411, 0.006619029862577377, 0.006625431659070254, 0.006631732959993163, 0.006638406155854669, 0.006645767033051509, 0.006653665632062707, 0.006661865803443562, 0.006670131694588361, 0.006678281449759523, 0.006686249570674779, 0.006693985684110315, 0.006701440712886029, 0.006708648361441044, 0.0067157736180031985, 0.006722993118709742, 0.006730479186720532, 0.0067382678280482056, 0.006746234230006205, 0.00675424432461168, 0.006762170456861754, 0.0067700035776702295, 0.006777839117048107, 0.006785776078370118, 0.006793908636722402, 0.00680227360765497, 0.0068108702076823575, 0.006819696999485096, 0.006828752545743728, 0.006838035409138789, 0.006847544152350818, 0.00685727733806035, 0.006867233528947923, 0.006877411287694077, 0.006887809176979349, 0.006898425759484273}, +.param_5 = {0.20002510438748747, 0.16230608185410503, 0.0959726293075041, 0.047848361801230546, 0.01793327933528417, 0.005990598388160625, 0.0063102163918152265, 0.008009552078123896, 0.006943541153165821, 0.0056993286974301935, 0.005289510426830391, 0.0051150781549745734, 0.00483767854285444, 0.004385817734364056, 0.0038268050219530947, 0.003310803950584522, 0.0029404168928532856, 0.002765808361518754, 0.0026757013315423933, 0.002490102322944606, 0.002148467774825639, 0.001666632542341416, 0.0011566175987556306, 0.0007490438161922297, 0.0004788426560599704, 0.0003370550183518471, 0.00027699149454515556, 0.0002511233887261301, 0.0002495979049592194, 0.0002668776191492965, 0.0002808714330575571, 0.0002719380666133149, 0.00023707500098890666, 0.00019163715153872746, 0.0001840733695768551, 0.0002519109035209119, 0.00039904428078395976, 0.0005952539580395162, 0.0007632710755263276, 0.0008513369039920074, 0.0008561059005277906, 0.0008074539014073234, 0.000768715553766449, 0.0007762511134538908, 0.0008306264405395607, 0.0009037616179434667, 0.000945413799766006, 0.0009311758742768829, 0.000863347536087921, 0.0007823539757782424, 0.000750112168406477, 0.0007916632517051929, 0.0009014304426280956, 0.0010244485873191038, 0.0010879186076798164, 0.0010678350873837006, 0.0009717827126408396, 0.000851834966113154, 0.0007680658645919415, 0.0007362393251513291, 0.0007505299539327034, 0.0007811682081056495, 0.0007981070795935741, 0.0007952291612597223, 0.0007777883219793787, 0.0007665061255089992, 0.0007796908359623649, 0.0008201269106613944, 0.0008783721318850191, 0.0009248218281470919, 0.0009366372380750602, 0.0009113474503081621, 0.0008590644672120534, 0.0008056271218655382, 0.0007683351839234479, 0.000748618172769118, 0.0007468128215105257, 0.0007636348443425256, 0.0007994960954047121, 0.0008536093355343381, 0.0009098171633165932, 0.0009390531353349087, 0.0009271152002799168, 0.000875494141612098, 0.0008102581528761192, 0.0007716099026728283, 0.0007759526360801711, 0.0008209675747805276, 0.0008822835200424789, 0.0009273471662054646, 0.0009452848992961942, 0.0009382737108478041, 0.0009217749195834443, 0.000913788792913494, 0.0009191157876108427, 0.0009346376519854711, 0.0009441223887539374, 0.0009310272119790464, 0.0008919208825447847, 0.0008338508999053938, 0.0007851177729714318, 0.0007709738601040413, 0.0007953689728598667, 0.0008493028071339566, 0.0009041178496248595, 0.0009374886755539151, 0.0009468695210824128, 0.0009376468595519334, 0.0009237630780041528, 0.0009146435782148889, 0.0009110565924535206, 0.000912180238805179, 0.0009162475464718003, 0.00092223128791806, 0.0009298819616810651, 0.0009352792302199341, 0.0009313016122939298, 0.0009144332275101523, 0.0008859762163248262, 0.0008651961090425271, 0.0008820732708878475, 0.0009489809410737765, 0.001061297532689836, 0.0011729495756397992, 0.0012219235448304895, 0.0011872656694052013, 0.0010775545446154583, 0.0009536093315944474, 0.0008867270432168922, 0.0008961540075820042, 0.0009749232557814021, 0.0010862760893955853, 0.0011925402803719502, 0.0012858041358141878, 0.0013648503109660488, 0.001424746425306763, 0.0014610697484522366, 0.0014731340182367984, 0.0014652318705838177, 0.0014511131544339695, 0.0014415299304488573, 0.001437744188102167, 0.0014388974152198739, 0.0014427607065046685, 0.0014478238728475416, 0.0014542230670255667, 0.00147106408606313, 0.001517919265685546, 0.0016061647576158002, 0.0017357347345674755, 0.0018921506718485616, 0.002049185767436651, 0.0021939305762144236, 0.0023240463429711165, 0.0024143058749210265, 0.0024256347121368385, 0.0023420017383650633, 0.002169603019876263, 0.001969122080291985, 0.001821709656223136, 0.001754519669100972, 0.001759368191498259, 0.001778905810999494, 0.0017464269626850382, 0.0016441709264568803, 0.0014852761625542242, 0.0013376595785843243, 0.00127030974157857, 0.0012974496784414619, 0.0014034073058346273, 0.0015259476208038386, 0.0016098770392053083, 0.0016466062525653628, 0.0016415646315961346, 0.001611787608641821, 0.0015704234350791442, 0.0015191142211250057, 0.0014662677330729186, 0.0014332905117169295, 0.0014344757268697737, 0.0014705568717333917, 0.0015274709338463852, 0.0015755043285672898, 0.0015976496563474378, 0.0015936226855548484, 0.0015759253058549548, 0.0015668660186353434, 0.0015772500699888503, 0.0016069519674294548, 0.0016497529284851924, 0.0016961570959955763, 0.0017423391830126422, 0.0017882338061370878, 0.00183384096536926, 0.0018791606607089853, 0.0019241928921560902, 0.001968937659710488, 0.0020133949633726993, 0.0020575648031425503, 0.0021014471790196075, 0.002123316500984851}, +.param_6 = {5.000627609687186, 4.057652046352625, 2.3993157326876013, 1.1962090450307632, 0.44833198338210534, 0.1497649597040157, 0.15775540979537928, 0.20023880195309818, 0.17358852882914388, 0.14248321743575154, 0.13223776067076143, 0.1278769538743646, 0.120941963571361, 0.10964544335910209, 0.09567012554882737, 0.08277009876461461, 0.07351042232132954, 0.0691452090379685, 0.06689253328856226, 0.06225255807361385, 0.05371169437064227, 0.04166581355853627, 0.028915439968890677, 0.018726095404805743, 0.011971066401497699, 0.008426375458794877, 0.00692478736362967, 0.006278084718153165, 0.0062399476239788365, 0.00667194047873354, 0.007021785826438753, 0.0067984516653352145, 0.0059268750247226665, 0.004790928788467319, 0.004601834239423286, 0.006297772588020889, 0.009976107019599167, 0.014881348950987472, 0.01908177688815793, 0.021283422599802093, 0.021402647513193984, 0.02018634753518378, 0.019217888844161313, 0.019406277836345187, 0.020765661013488756, 0.022594040448586927, 0.02363534499415232, 0.023279396856920598, 0.021583688402196377, 0.019558849394457622, 0.01875280421016201, 0.019791581292630256, 0.022535761065700655, 0.025611214682977335, 0.027197965191996798, 0.02669587718459321, 0.024294567816018908, 0.021295874152826855, 0.01920164661479984, 0.01840598312878583, 0.018763248848319147, 0.019529205202639677, 0.019952676989840046, 0.019880729031493405, 0.019444708049484727, 0.019162653137724805, 0.019492270899057473, 0.020503172766533906, 0.021959303297125476, 0.023120545703678164, 0.023415930951878328, 0.02278368625770466, 0.021476611680298907, 0.020140678046637328, 0.019208379598084635, 0.018715454319229163, 0.018670320537764185, 0.019090871108562446, 0.019987402385118758, 0.021340233388358887, 0.02274542908291266, 0.023476328383373324, 0.02317788000699983, 0.021887353540300802, 0.020256453821904108, 0.019290247566819407, 0.019398815902002542, 0.020524189369516832, 0.02205708800106232, 0.023183679155133752, 0.02363212248240598, 0.02345684277119675, 0.02304437298958628, 0.02284471982283709, 0.022977894690270895, 0.02336594129963565, 0.023603059718846353, 0.02327568029947824, 0.022298022063621525, 0.020846272497632157, 0.019627944324285274, 0.01927434650260129, 0.019884224321498056, 0.021232570178350563, 0.022602946240621313, 0.023437216888846923, 0.02367173802705902, 0.023441171488799983, 0.023094076950103126, 0.022866089455370053, 0.02277641481133741, 0.02280450597013095, 0.02290618866179761, 0.02305578219795046, 0.02324704904202446, 0.023381980755499132, 0.02328254030734833, 0.02286083068775424, 0.022149405408122824, 0.021629902726061356, 0.022051831772193498, 0.02372452352684684, 0.02653243831724772, 0.02932373939099342, 0.030548088620763192, 0.029681641735132547, 0.02693886361538611, 0.023840233289859625, 0.022168176080422652, 0.02240385018955071, 0.024373081394532536, 0.027156902234887204, 0.029813507009301965, 0.032145103395356256, 0.03412125777415009, 0.035618660632669163, 0.03652674371130704, 0.0368283504559197, 0.0366307967645918, 0.03627782886084785, 0.036038248261224815, 0.03594360470255409, 0.035972435380496326, 0.036069017662618275, 0.03619559682118689, 0.0363555766756396, 0.036776602151578075, 0.03794798164213631, 0.040154118940397, 0.043393368364189056, 0.04730376679621118, 0.05122964418591558, 0.0548482644053605, 0.058101158574278, 0.06035764687302714, 0.06064086780342148, 0.058550043459126844, 0.05424007549690579, 0.04922805200729963, 0.04554274140557979, 0.043862991727522394, 0.04398420478745613, 0.04447264527498995, 0.04366067406712526, 0.0411042731614214, 0.03713190406385569, 0.033441489464608454, 0.03175774353946226, 0.032436241961036893, 0.035085182645866464, 0.03814869052009562, 0.040246925980133574, 0.04116515631413242, 0.04103911578990371, 0.04029469021604726, 0.039260585876976783, 0.037977855528123494, 0.03665669332682531, 0.035832262792923064, 0.03586189317174304, 0.03676392179333687, 0.038186773346160496, 0.03938760821418086, 0.03994124140868638, 0.0398405671388713, 0.03939813264637326, 0.03917165046588289, 0.039431251749719176, 0.04017379918573871, 0.04124382321213371, 0.04240392739988941, 0.04355847957531467, 0.04470584515342546, 0.04584602413423011, 0.04697901651772585, 0.04810482230390434, 0.04922344149276281, 0.05033487408431514, 0.051439120078564105, 0.05253617947549305, 0.05308291252462127}, +.param_7 = {0.0003247370445476355, 0.000330703991123457, 0.0003366709376992783, 0.00034263788427509983, 0.0003486048308509212, 0.0003545717774267426, 0.0003605387240025642, 0.00036650567057838545, 0.000372472617154207, 0.00037843956373002837, 0.00038440651030584983, 0.00039037345688167123, 0.00039634040345749264, 0.000404810608367613, 0.00041584719091872186, 0.0004268837734698312, 0.0004379203560209405, 0.0004489569385720494, 0.0004599935211231587, 0.00047103010367426757, 0.0004820666862253769, 0.0004931032687764857, 0.000504139851327595, 0.0005151764338787045, 0.0005262130164298134, 0.0005372495989809225, 0.000548286181532032, 0.000559322764083141, 0.00057035934663425, 0.000581395929185359, 0.0005924325117364685, 0.0006095654590532987, 0.0006357984526602025, 0.0006620314462671063, 0.0006882644398740094, 0.0007144974334809132, 0.0007407304270878161, 0.0007669634206947199, 0.0007931964143016229, 0.0008766728200023608, 0.0009754242724026358, 0.0011264964734790939, 0.0012500732155466053, 0.0013410955881820483, 0.0014334981007109616, 0.001528177171513416, 0.0016305051970074529, 0.0017536822831818312, 0.0018868472296767315, 0.002026265747822937, 0.002168800186745477, 0.0023159397138327203, 0.002469351950389313, 0.0026332688963334313, 0.002817089101483791, 0.0030317048018564537, 0.0032808949070624854, 0.003550228251441085, 0.0038362135321426956, 0.0041856109119336885, 0.0052547617281141065, 0.007623286555370048, 0.008531625970439733, 0.009377190593477447, 0.01029396944335623, 0.011021550130760853, 0.011902708696191354, 0.012853325530704377, 0.013761134891474135, 0.01459069647130073, 0.015567578203663043, 0.01639758225400037, 0.017308493667188982, 0.018132170374422312, 0.018938846485766554, 0.019747195187846248, 0.020673608182103596, 0.02147130604846533, 0.022283528784520192, 0.02308590670213684, 0.023915852475080556, 0.024642628002432075, 0.02528477396772731, 0.026085154926760824, 0.026701939377919225, 0.027225095836704825, 0.027731620255478942, 0.02824733339048156, 0.028762955999735062, 0.029271689680214975, 0.02974109026797371, 0.0301360380713297, 0.030478744731176118, 0.030793105185076206, 0.03109952161845395, 0.03143076742223823, 0.03181931010075292, 0.03224231827522752, 0.032664489906149244, 0.03315312686992857, 0.03372913313203759, 0.034213341975821515, 0.03466577169332086, 0.03513605520759988, 0.0356455116502536, 0.03615338369011613, 0.03662372562051686, 0.037093226446298325, 0.037564119521184484, 0.03801135580105009, 0.03843333708110238, 0.03883399064195827, 0.03921646179324576, 0.03958329064226569, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217, 0.0399361022364217}, +.param_8 = {1.2989481781905422e-05, 1.3228159644938283e-05, 1.3466837507971134e-05, 1.3705515371003996e-05, 1.3944193234036849e-05, 1.4182871097069706e-05, 1.4421548960102571e-05, 1.4660226823135422e-05, 1.4898904686168283e-05, 1.5137582549201136e-05, 1.5376260412233996e-05, 1.5614938275266852e-05, 1.5853616138299708e-05, 1.6192424334704524e-05, 1.6633887636748878e-05, 1.707535093879325e-05, 1.7516814240837623e-05, 1.7958277542881977e-05, 1.839974084492635e-05, 1.8841204146970705e-05, 1.928266744901508e-05, 1.9724130751059434e-05, 2.0165594053103805e-05, 2.0607057355148183e-05, 2.104852065719254e-05, 2.1489983959236908e-05, 2.1931447261281282e-05, 2.237291056332564e-05, 2.2814373865370007e-05, 2.3255837167414364e-05, 2.3697300469458742e-05, 2.438261836213195e-05, 2.5431938106408108e-05, 2.6481257850684258e-05, 2.7530577594960378e-05, 2.8579897339236532e-05, 2.9629217083512648e-05, 3.0678536827788806e-05, 3.172785657206492e-05, 3.506691280009444e-05, 3.9016970896105436e-05, 4.505985893916376e-05, 5.000292862186422e-05, 5.364382352728194e-05, 5.733992402843847e-05, 6.112708686053665e-05, 6.522020788029813e-05, 7.014729132727326e-05, 7.547388918706927e-05, 8.105062991291749e-05, 8.67520074698191e-05, 9.263758855330882e-05, 9.877407801557254e-05, 0.00010533075585333727, 0.00011268356405935167, 0.00012126819207425817, 0.00013123579628249944, 0.0001420091300576434, 0.00015344854128570786, 0.00016742443647734757, 0.0002101904691245643, 0.00030493146221480195, 0.0003412650388175894, 0.00037508762373909794, 0.00041175877773424926, 0.00044086200523043423, 0.00047610834784765426, 0.0005141330212281752, 0.0005504453956589655, 0.0005836278588520293, 0.0006227031281465219, 0.0006559032901600149, 0.0006923397466875594, 0.0007252868149768926, 0.0007575538594306623, 0.00078988780751385, 0.000826944327284144, 0.0008588522419386135, 0.0008913411513808078, 0.0009234362680854738, 0.0009566340990032224, 0.0009857051200972832, 0.0010113909587090926, 0.001043406197070433, 0.0010680775751167693, 0.0010890038334681932, 0.001109264810219158, 0.0011298933356192627, 0.0011505182399894026, 0.0011708675872085992, 0.0011896436107189487, 0.0012054415228531883, 0.001219149789247045, 0.0012317242074030483, 0.0012439808647381582, 0.0012572306968895294, 0.0012727724040301172, 0.0012896927310091012, 0.0013065795962459701, 0.0013261250747971431, 0.0013491653252815038, 0.0013685336790328607, 0.0013866308677328344, 0.0014054422083039954, 0.0014258204660101443, 0.0014461353476046452, 0.0014649490248206747, 0.0014837290578519334, 0.0015025647808473797, 0.0015204542320420037, 0.0015373334832440957, 0.001553359625678331, 0.0015686584717298309, 0.001583331625690628, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685, 0.0015974440894568685}, +.param_9 = {1.4290269653020227}, +.param_10 = {26.88096707375469, 2.653339696896445}, +.param_11 = {0.5143583976566883, 0.013947249693586983}, +.param_12 = {0.37422055555861733}, +.name = {'L', 'D', '4', '0', '3', '5', '3', '3'}, diff --git a/app/src/fuel_gauge/zsw_pmic.c b/app/src/fuel_gauge/zsw_pmic.c index 1d751ceb..411a94a2 100755 --- a/app/src/fuel_gauge/zsw_pmic.c +++ b/app/src/fuel_gauge/zsw_pmic.c @@ -1,6 +1,18 @@ /* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + * This file is part of ZSWatch project . + * Copyright (c) 2023 Jakob Krantz. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include @@ -62,7 +74,7 @@ static int64_t ref_time; static bool vbus_connected; static const struct battery_model battery_model = { -#include "battery_model.inc" +#include "ld403533.inc" }; static void zbus_activity_event_callback(const struct zbus_channel *chan) diff --git a/app/src/main.c b/app/src/main.c index aa80c2a4..9fc95e39 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -552,10 +552,12 @@ static void on_watchface_app_event_callback(watchface_app_evt_t evt) sys_reboot(SYS_REBOOT_COLD); break; case WATCHFACE_APP_EVENT_SHUTDOWN: +#if CONFIG_DT_HAS_NORDIC_NPM1300_ENABLED int ret = zsw_pmic_power_down(); if (ret) { LOG_ERR("Failed to power down the system"); } +#endif break; } } From c01767d4e65b435446ad144a7adb6a59aa2756f9 Mon Sep 17 00:00:00 2001 From: Jakob Krantz Date: Mon, 15 Jul 2024 16:40:17 +0200 Subject: [PATCH 26/26] Final v5 does not have USB switch powered by 3V0. Rename accordingly. --- app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay | 2 +- app/src/drivers/zsw_buzzer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay index 4da685b1..eea3d212 100644 --- a/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay +++ b/app/boards/arm/zswatch_nrf5340/zswatch_nrf5340_cpuapp_5.overlay @@ -223,7 +223,7 @@ regulator-always-on; }; - regulator_buzzer_usb: BUCK2 { + regulator_buzzer: BUCK2 { regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; regulator-init-microvolt = <3000000>; diff --git a/app/src/drivers/zsw_buzzer.c b/app/src/drivers/zsw_buzzer.c index f5fcc1d5..0478acb2 100644 --- a/app/src/drivers/zsw_buzzer.c +++ b/app/src/drivers/zsw_buzzer.c @@ -134,7 +134,7 @@ struct note_duration_t beep_song[] = { }; static const struct pwm_dt_spec buzzer_dt = PWM_DT_SPEC_GET(DT_ALIAS(buzzer_pwm)); -static const struct device *const reg_dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(regulator_buzzer_usb)); +static const struct device *const reg_dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(regulator_buzzer)); K_TIMER_DEFINE(buzzer_timer, pattern_timer_timeout, NULL);