From dfbb108ab4c98f97946aae6f4184aea137962594 Mon Sep 17 00:00:00 2001 From: fuzhibo Date: Tue, 18 Feb 2020 20:29:20 +0800 Subject: [PATCH 1/2] Driver(touch): fix touch sensor driver for esp32s2. 1.update touch sensor driver for esp32s2; 2.update unit test for touch sensor; 3.update register files about touch sensor; --- .../driver/test/esp32/test_touch_sensor.c | 330 +++ .../driver/test/esp32s2/test_touch_sensor.c | 2200 +++++++++++++++++ components/driver/test/esp32s2/touch_scope.c | 186 ++ components/driver/test/esp32s2/touch_scope.h | 4 + .../esp32s2/include/hal/touch_sensor_hal.h | 6 + .../src/esp32s2/include/hal/touch_sensor_ll.h | 20 + 6 files changed, 2746 insertions(+) create mode 100644 components/driver/test/esp32/test_touch_sensor.c create mode 100644 components/driver/test/esp32s2/test_touch_sensor.c create mode 100644 components/driver/test/esp32s2/touch_scope.c create mode 100644 components/driver/test/esp32s2/touch_scope.h diff --git a/components/driver/test/esp32/test_touch_sensor.c b/components/driver/test/esp32/test_touch_sensor.c new file mode 100644 index 000000000..c713d1d7b --- /dev/null +++ b/components/driver/test/esp32/test_touch_sensor.c @@ -0,0 +1,330 @@ +/* + Tests for the touch sensor device driver +*/ +#include "esp_system.h" +#include "driver/touch_pad.h" +#include "unity.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc_cntl_struct.h" +#include "soc/sens_reg.h" +#include "soc/sens_struct.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc_cntl_struct.h" +#include "soc/rtc_io_reg.h" +#include "soc/rtc_io_struct.h" + +static const char *TAG = "test_touch"; + +#define TOUCH_READ_INVALID_VAL (0) +#define TOUCHPAD_FILTER_TOUCH_PERIOD (10) + +#define TOUCH_REG_BASE_TEST() ({ \ + TEST_ASSERT_EQUAL_UINT32(RTC_CNTL_BROWN_OUT_REG, &RTCCNTL.brown_out.val); \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ +}) + +#define TOUCH_READ_ERROR (50) +#define TEST_TOUCH_COUNT_NUM (10) +#define TEST_TOUCH_CHANNEL (9) +static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { + TOUCH_PAD_NUM0, + // TOUCH_PAD_NUM1 is GPIO0, for download. + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3, + TOUCH_PAD_NUM4, + TOUCH_PAD_NUM5, + TOUCH_PAD_NUM6, + TOUCH_PAD_NUM7, + TOUCH_PAD_NUM8, + TOUCH_PAD_NUM9, +}; + +static void printf_touch_hw_read(const char *str) +{ + uint16_t touch_value; + printf("[%s] ", str); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + while (!touch_pad_meas_is_done()) ; + touch_pad_read_raw_data(touch_list[i], &touch_value); + printf("[%d]%d ", touch_list[i], touch_value); + } + printf("\r\n"); +} + +/* + * Change the slope to get larger value from touch sensor. + */ +static void test_push_fake(touch_pad_t pad_num) +{ + touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_2, TOUCH_PAD_TIE_OPT_DEFAULT); +} + +/* + * Change the slope to get larger value from touch sensor. + */ +static void test_release_fake(touch_pad_t pad_num) +{ + touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); +} + +static esp_err_t test_touch_sw_read(void) +{ + ESP_LOGI(TAG, "%s", __func__); + uint16_t touch_value; + + TEST_ESP_OK( touch_pad_init() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); + } + + // Start task to read values sensed by pads + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) ); + printf("T%d:[%4d] ", touch_list[i], touch_value); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); + } + printf("\n"); + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +static esp_err_t test_touch_timer_read(void) +{ + ESP_LOGI(TAG, "%s", __func__); + uint16_t touch_value[TEST_TOUCH_CHANNEL], touch_temp[TEST_TOUCH_CHANNEL]; + int t_cnt = TEST_TOUCH_COUNT_NUM; + + TEST_ESP_OK( touch_pad_init() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); + } + // Start task to read values sensed by pads + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value[i]) ); + printf("T%d:[%4d] ", touch_list[i], touch_value[i]); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); + } + while (t_cnt--) { + // Start task to read values sensed by pads + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_temp[i]) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + } + vTaskDelay(50 / portTICK_PERIOD_MS); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +static esp_err_t test_touch_filtered_read(void) +{ + ESP_LOGI(TAG, "%s", __func__); + uint16_t touch_value, touch_temp; + int t_cnt = TEST_TOUCH_COUNT_NUM; + + TEST_ESP_OK( touch_pad_init() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); + } + // Initialize and start a software filter to detect slight change of capacitance. + touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD); + vTaskDelay(10 / portTICK_PERIOD_MS); + + while (t_cnt--) { + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); + TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_temp) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); + printf("T%d:[%4d] ", touch_list[i], touch_value); + } + vTaskDelay(50 / portTICK_PERIOD_MS); + } + printf("\n"); + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +// test the basic configuration function with right parameters and error parameters +TEST_CASE("Touch Sensor all channel read test", "[touch]") +{ + TOUCH_REG_BASE_TEST(); + TEST_ESP_OK( test_touch_sw_read() ); + TEST_ESP_OK( test_touch_timer_read() ); + TEST_ESP_OK( test_touch_filtered_read() ); +} + +static int test_touch_parameter(touch_pad_t pad_num, int meas_time, int slp_time, int vol_h, int vol_l, int vol_a, int slope) +{ + ESP_LOGI(TAG, "%s", __func__); + uint16_t touch_value; + TEST_ESP_OK( touch_pad_init() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_config(pad_num, TOUCH_READ_INVALID_VAL) ); + + touch_pad_set_meas_time(slp_time, meas_time); + touch_pad_set_voltage(vol_h, vol_l, vol_a); + touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT); + + // Initialize and start a software filter to detect slight change of capacitance. + touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD); + vTaskDelay(500 / portTICK_PERIOD_MS); + + // Start task to read values sensed by pads + TEST_ESP_OK( touch_pad_read(pad_num, &touch_value) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); + printf("T%d:[%4d] ", pad_num, touch_value); + TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); + printf("T%d:[%4d] ", pad_num, touch_value); + TEST_ESP_OK( touch_pad_read_filtered(pad_num, &touch_value) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); + printf("T%d:[%4d] \n", pad_num, touch_value); + + TEST_ESP_OK( touch_pad_deinit() ); + + return touch_value; +} + +TEST_CASE("Touch Sensor parameters test", "[touch]") +{ + int touch_val[5] = {0}; + + ESP_LOGI(TAG, "Charge / incharge voltage level test"); + touch_val[0] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V, + TOUCH_PAD_SLOPE_DEFAULT); + touch_val[1] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V, + TOUCH_PAD_SLOPE_DEFAULT); + touch_val[2] = test_touch_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5, + TOUCH_PAD_SLOPE_DEFAULT); + + TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]); + TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]); + + ESP_LOGI(TAG, "Measure time / sleep time test"); + touch_val[0] = test_touch_parameter(touch_list[0], 0xff, 0xa, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT); + touch_val[1] = test_touch_parameter(touch_list[0], 0x1ff, 0xf, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT); + touch_val[2] = test_touch_parameter(touch_list[0], 0x2fff, 0x1f, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT); + + TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]); + TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]); + + ESP_LOGI(TAG, "Charge / incharge slope level test"); + touch_val[0] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 1); + touch_val[1] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3); + touch_val[2] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7); + + TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]); + TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]); +} + +static bool s_pad_activated[TOUCH_PAD_MAX]; + +static void test_touch_intr_cb(void *arg) +{ + uint32_t pad_intr = touch_pad_get_status(); + ets_printf("T%x ", pad_intr); + //clear interrupt + touch_pad_clear_status(); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if ((pad_intr >> touch_list[i]) & 0x1) { + s_pad_activated[touch_list[i]] = true; + } + } +} + +static esp_err_t test_touch_interrupt(void) +{ + ESP_LOGI(TAG, "%s", __func__); + uint16_t touch_value; + + TEST_ESP_OK( touch_pad_init() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); + } + // Initialize and start a software filter to detect slight change of capacitance. + touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD); + vTaskDelay(10 / portTICK_PERIOD_MS); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + //read filtered value + TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_value) ); + ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", touch_list[i], touch_value); + //set interrupt threshold. + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * 2 / 3) ); + } + + // Register touch interrupt ISR + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL) ); + TEST_ESP_OK( touch_pad_clear_status() ); + TEST_ESP_OK( touch_pad_intr_enable() ); + + int test_cnt = TEST_TOUCH_COUNT_NUM; + while (test_cnt--) { + ESP_LOGI(TAG, "touch push"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + test_push_fake(touch_list[i]); + } + vTaskDelay(100 / portTICK_PERIOD_MS); + printf_touch_hw_read("push"); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if (s_pad_activated[touch_list[i]] == false) { + ESP_LOGE(TAG, "touch%d not active", touch_list[i]); + TEST_FAIL(); + } + } + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + s_pad_activated[touch_list[i]] = 0; + } + + ESP_LOGI(TAG, "touch release"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + test_release_fake(touch_list[i]); + } + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor interrupt test", "[touch]") +{ + TEST_ESP_OK( test_touch_interrupt() ); +} \ No newline at end of file diff --git a/components/driver/test/esp32s2/test_touch_sensor.c b/components/driver/test/esp32s2/test_touch_sensor.c new file mode 100644 index 000000000..49a622f02 --- /dev/null +++ b/components/driver/test/esp32s2/test_touch_sensor.c @@ -0,0 +1,2200 @@ +/* + Tests for the touch sensor device driver +*/ +#include +#include "esp_system.h" +#include "driver/touch_pad.h" +#include "unity.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +// #include "esp_event.h" +// #include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc_cntl_struct.h" +#include "soc/sens_reg.h" +#include "soc/sens_struct.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc_cntl_struct.h" +#include "soc/rtc_io_reg.h" +#include "soc/rtc_io_struct.h" +#include "soc/apb_ctrl_reg.h" +#include "driver/rtc_io.h" + +static const char *TAG = "test_touch"; + +#define PLATFORM_SELECT (1) //0: pxp; 1: chip +#if (PLATFORM_SELECT == 0) //PXP platform +#define SET_BREAK_POINT(flag) REG_WRITE(APB_CTRL_DATE_REG, flag) +//PXP clk is slower. +#define SYS_DELAY_TIME_MOM (1/40) +#define RTC_SLOW_CLK_FLAG 1 // Slow clock is 32KHz. +void test_pxp_deinit_io(void) +{ + for (int i = 0; i < 22; i++) { + rtc_gpio_init(i); + } +} +#else +//PXP clk is slower. +#define SET_BREAK_POINT(flag) +#define SYS_DELAY_TIME_MOM (1) +#define RTC_SLOW_CLK_FLAG 0 // Slow clock is 32KHz. +void test_pxp_deinit_io(void) +{ + ; +} +#endif + +#define TOUCH_READ_INVALID_VAL (SOC_TOUCH_PAD_THRESHOLD_MAX) +#define TOUCH_READ_ERROR (100) +#define TOUCH_INTR_THRESHOLD (0.1) +#define TOUCH_EXCEED_TIME_MS (1000) + +#define TOUCH_REG_BASE_TEST() ({ \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_CNTL_DATE), RTCCNTL.date.date); \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ +}) + +#define TEST_TOUCH_COUNT_NUM (10) +#define TEST_TOUCH_CHANNEL (14) +static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { + // TOUCH_PAD_NUM0, is GPIO0, for download. + TOUCH_PAD_NUM1, + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3, + TOUCH_PAD_NUM4, + TOUCH_PAD_NUM5, + TOUCH_PAD_NUM6, + TOUCH_PAD_NUM7, + TOUCH_PAD_NUM8, + TOUCH_PAD_NUM9, + TOUCH_PAD_NUM10, + TOUCH_PAD_NUM11, + TOUCH_PAD_NUM12, + TOUCH_PAD_NUM13, + TOUCH_PAD_NUM14 +}; +// static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { +// // TOUCH_PAD_NUM0, is GPIO0, for download. +// TOUCH_PAD_NUM2, +// TOUCH_PAD_NUM4, +// TOUCH_PAD_NUM6, +// TOUCH_PAD_NUM10, +// TOUCH_PAD_NUM11, +// TOUCH_PAD_NUM12, +// TOUCH_PAD_NUM13, +// }; +#define TOUCH_WATERPROOF_RING_PAD TOUCH_PAD_NUM1 +static touch_pad_t proximity_pad[3] = { + TOUCH_PAD_NUM2, + TOUCH_PAD_NUM3, + TOUCH_PAD_NUM4, +}; + +static QueueHandle_t que_touch = NULL; +typedef struct touch_msg { + touch_pad_intr_mask_t intr_mask; + uint32_t pad_num; + uint32_t pad_status; + uint32_t pad_val; + uint32_t slp_proxi_cnt; + uint32_t slp_proxi_base; +} touch_event_t; + +static uint32_t s_touch_timeout_mask = 0; + +static void printf_touch_hw_read(const char *str) +{ + uint32_t touch_value; + printf("[%s] ", str); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + touch_pad_read_raw_data(touch_list[i], &touch_value); + printf("[%d]%d ", touch_list[i], touch_value); + } + printf("\r\n"); +} + +static void printf_touch_baseline_read(const char *str) +{ + uint32_t touch_value; + printf("[%s] ", str); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + printf("[%d]%d ", touch_list[i], touch_value); + } + printf("\r\n"); +} + +static void printf_touch_smooth_read(const char *str) +{ + uint32_t touch_value; + printf("[%s] ", str); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + touch_pad_filter_read_smooth(touch_list[i], &touch_value); + printf("[%d]%d ", touch_list[i], touch_value); + } + printf("\r\n"); +} + + +static void test_timeout_trigger_fake(touch_pad_t pad_num) +{ + touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_0, TOUCH_PAD_TIE_OPT_DEFAULT); +} + +static void test_timeout_normal(touch_pad_t pad_num) +{ + touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); +} + +/* + * Change the slope to get larger value from touch sensor. + */ +static void test_push_fake(touch_pad_t pad_num) +{ + touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); +} + +/* + * Change the slope to get larger value from touch sensor. + */ +static void test_release_fake(touch_pad_t pad_num) +{ + touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); +} + +static void test_touch_push_all(void) +{ + ESP_LOGI(TAG, "touch push"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + test_push_fake(touch_list[i]); + } +} + +static void test_touch_release_all(void) +{ + ESP_LOGI(TAG, "touch release"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + test_release_fake(touch_list[i]); + } +} + +/* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ +static void test_touch_baseline_not_update(void) +{ + uint32_t touch_val[TEST_TOUCH_CHANNEL] = {0}; + uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_val[i]) ); + } + for (int i = 0; i < 10; i++) { + vTaskDelay(20 / portTICK_PERIOD_MS); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_temp[i]) ); + TEST_ASSERT_EQUAL(touch_temp[i], touch_val[i]); + } + } +} + +/* + * Test the stable and change of touch sensor reading in SW mode. + */ +esp_err_t test_touch_sw_read(void) +{ + uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; + uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; + uint32_t touch_push[TEST_TOUCH_CHANNEL] = {0}; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + while (test_cnt--) { + test_touch_release_all(); + + /* Read the touch sensor raw data in SW mode. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_sw_start() ); + while (!touch_pad_meas_is_done()) ; + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); + printf("T%d:[%4d] ", touch_list[i], touch_value[i]); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); + } + printf("\n"); + /* Check the stable of reading. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if (touch_temp[i]) { + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + } + touch_temp[i] = touch_value[i]; + } + + test_touch_push_all(); + + /* Read the touch sensor raw data in SW mode. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_sw_start() ); + while (!touch_pad_meas_is_done()) ; + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_push[i]) ); + printf("T%d:[%4d] ", touch_list[i], touch_push[i]); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_push[i]); + } + printf("\n"); + /* Check the change of reading. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ASSERT_GREATER_THAN(touch_value[i], touch_push[i]); + } + } + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +/* + * Test the stable and change of touch sensor reading in timer mode. + * TEST POINT: + * 1. Timer mode for FSM. + * 2. Touch channel slope setting. + * 3. Touch reading stable. + */ +esp_err_t test_touch_timer_read(void) +{ + uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; + uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; + uint32_t touch_push[TEST_TOUCH_CHANNEL] = {0}; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + TEST_ESP_OK( touch_pad_init() ); + /* Set different slope for channels to test slope function. */ + printf("Set slope for channel: "); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + TEST_ESP_OK( touch_pad_set_cnt_mode(touch_list[i], i % 7 ? i % 7 : 1, TOUCH_PAD_TIE_OPT_DEFAULT) ); + printf("[ch%d-%d] ", touch_list[i], i % 7 ? i % 7 : 1); + } + printf("\n"); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + /* Wait touch sensor stable */ + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + while (test_cnt--) { + test_touch_release_all(); + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + // Start task to read values sensed by pads + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); + printf("T%d:[%4d] ", touch_list[i], touch_value[i]); + } + printf("\n"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if (touch_temp[i]) { + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + } + touch_temp[i] = touch_value[i]; + } + + test_touch_push_all(); + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + /* Read the touch sensor raw data in FSM mode. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_push[i]) ); + printf("T%d:[%4d] ", touch_list[i], touch_push[i]); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_push[i]); + } + printf("\n"); + /* Check the change of reading. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ASSERT_GREATER_THAN(touch_value[i], touch_push[i]); + } + } + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +/* + * Test the filter mode. + * TEST POINT: + * 1. Timer mode for FSM. + * 2. Touch reading stable. + * 3. Touch reading init value. + * 4. Touch reading filtered value equal to raw data. + */ +esp_err_t test_touch_filtered_read(void) +{ + uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; + uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + /* Wait touch pad init done. */ + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + /* Test the stable for init value of touch reading. + * Ideal: baseline == raw data == smooth data. + */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value[i]) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_temp[i]) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &touch_temp[i]) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + } + printf("touch filter init value:\n"); + printf_touch_hw_read("raw "); + printf_touch_baseline_read("base "); + printf_touch_smooth_read("smooth"); + printf("\n"); + + int test_cnt = TEST_TOUCH_COUNT_NUM; + while (test_cnt--) { + /* Touch reading filtered value equal to raw data. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_temp[i]) ); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &touch_temp[i]) ); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + } + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if (touch_temp[i]) { + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); + } + touch_temp[i] = touch_value[i]; + } + vTaskDelay(20 / portTICK_PERIOD_MS); + } + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor reading test (SW, Timer, filter)", "[touch]") +{ + TOUCH_REG_BASE_TEST(); + TEST_ESP_OK( test_touch_sw_read() ); + TEST_ESP_OK( test_touch_timer_read() ); + TEST_ESP_OK( test_touch_filtered_read() ); +} + +/* + * Test the base patameter mode. + * TEST POINT: + * 1. measure time and sleep time setting. + * 2. Charge / incharge voltage threshold setting. + * 3. Touch slope setting. + * 4. Touch reading filtered value equal to raw data. + */ +int test_touch_base_parameter(touch_pad_t pad_num, int meas_time, int slp_time, + int vol_h, int vol_l, int vol_a, int slope, bool is_conn_gnd) +{ + uint32_t touch_value = 0; + uint32_t touch_temp = 0, touch_filter; + uint64_t val_sum = 0; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + TEST_ESP_OK( touch_pad_init() ); + /* Note: init all channel, but test one channel. */ + // TEST_ESP_OK( touch_pad_config(pad_num) ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + + TEST_ESP_OK( touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT) ); + TEST_ESP_OK( touch_pad_set_meas_time(slp_time, meas_time) ); + TEST_ESP_OK( touch_pad_set_voltage(vol_h, vol_l, vol_a) ); + TEST_ESP_OK( touch_pad_set_inactive_connect(is_conn_gnd) ); + ESP_LOGI(TAG, "meas_time[%d]_slp_time[%d]_vol_h[%d]_vol_l[%d]_vol_a[%d]_slope[%d]_is_conn_gnd[%d]", + meas_time, slp_time, vol_h, vol_l, vol_a, slope, is_conn_gnd); + + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + /* Some parameters will delay the init time. so wait longger time */ + vTaskDelay(100 / portTICK_PERIOD_MS); + + while (test_cnt--) { + /* Correctness of reading. Ideal: baseline == raw data == smooth data. */ + TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_baseline(pad_num, &touch_filter) ); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_filter, touch_value); + TEST_ESP_OK( touch_pad_filter_read_smooth(pad_num, &touch_filter) ); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_filter, touch_value); + + /* Stable of reading */ + TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); + TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); + TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); + if (touch_temp) { + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); + } + touch_temp = touch_value; + + printf("T%d:[%4d] ", pad_num, touch_value); + val_sum += touch_value; // For check. + vTaskDelay(20 / portTICK_PERIOD_MS); + } + printf("\n"); + + TEST_ESP_OK( touch_pad_deinit() ); + return (uint32_t)(val_sum / TEST_TOUCH_COUNT_NUM); +} + +TEST_CASE("Touch Sensor base parameters test (meas_time, voltage, slope, inv_conn)", "[touch]") +{ + int touch_val[5] = {0}; + + ESP_LOGI(TAG, "Charge / incharge voltage level test"); + touch_val[0] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5, + TOUCH_PAD_SLOPE_DEFAULT, true); + touch_val[1] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V, + TOUCH_PAD_SLOPE_DEFAULT, true); + touch_val[2] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V, + TOUCH_PAD_SLOPE_DEFAULT, true); + + TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); + TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); + + ESP_LOGI(TAG, "Measure time / sleep time test"); + touch_val[0] = test_touch_base_parameter(touch_list[1], 0xff, 0x1ff, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); + touch_val[1] = test_touch_base_parameter(touch_list[1], 0xfff, 0xff, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); + touch_val[2] = test_touch_base_parameter(touch_list[1], 0x1fff, 0xf, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); + + TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); + TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); + + ESP_LOGI(TAG, "Charge / incharge slope level test"); + touch_val[0] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7, true); + touch_val[1] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 5, true); + touch_val[2] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3, true); + + TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); + TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); + + /* The GND option causes larger parasitic capacitance and larger reading */ + ESP_LOGI(TAG, "Inactive connect test"); + touch_val[0] = test_touch_base_parameter(touch_list[3], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, + false); + touch_val[1] = test_touch_base_parameter(touch_list[3], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, + TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, + true); + TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); +} + +/* + * Check active interrupt of touch channels. + */ +static esp_err_t test_touch_check_ch_touched(uint32_t test_ch_num, uint32_t exceed_time_ms) +{ + touch_event_t evt = {0}; + int ret = ESP_FAIL; + printf("Active: "); + while (1) { + if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { + printf("0x%x, ", evt.pad_status); + if (test_ch_num == __builtin_popcount(evt.pad_status)) { + ret = ESP_OK; + break; + } + } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { + continue; + } else { // If the interrupt type error, test error. + ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); + break; + } + } else { + ESP_LOGI(TAG, "Touch intr exceed time"); + break; + } + } + printf("\n"); + return (esp_err_t)ret; +} + +/* + * Check inactive interrupt of touch channels. + */ +static esp_err_t test_touch_check_ch_released(uint32_t test_ch_num, uint32_t exceed_time_ms) +{ + touch_event_t evt = {0}; + int ret = ESP_FAIL; + printf("Inactive: "); + while (1) { + if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) { + printf("0x%x, ", evt.pad_status); + if ((TEST_TOUCH_CHANNEL - test_ch_num) == __builtin_popcount(evt.pad_status)) { + ret = ESP_OK; + break; + } + } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { + continue; + } else { // If the interrupt type error, test error. + ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); + break; + } + } else { + ESP_LOGI(TAG, "Touch intr exceed time"); + break; + } + } + printf("\n"); + return (esp_err_t)ret; +} + +static esp_err_t test_touch_check_ch_touched_with_proximity(uint32_t test_ch_num, uint32_t exceed_time_ms) +{ + touch_pad_proximity_t proximity; + uint16_t ch_mask = 0; + touch_event_t evt = {0}; + int ret = ESP_FAIL; + + TEST_ESP_OK( touch_pad_proximity_get_config(&proximity) ); + printf("Active: "); + while (1) { + if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { + printf("0x%x, ", evt.pad_status); + if (test_ch_num == __builtin_popcount(evt.pad_status)) { + ret = ESP_OK; + break; + } + } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_SCAN_DONE)) { + touch_pad_get_channel_mask(&ch_mask); + for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { + if (BIT(i) & ch_mask) { + if (evt.pad_num == i) { + if (proximity.meas_num == evt.slp_proxi_cnt) { + ets_printf("priximity base(%d) cnt(%d)\n", evt.slp_proxi_base, evt.slp_proxi_cnt); + } + } + } + } + continue; + } else { // If the interrupt type error, test error. + ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); + continue;; + } + } else { + ESP_LOGI(TAG, "Touch intr exceed time"); + break; + } + } + printf("\n"); + return (esp_err_t)ret; +} + +static esp_err_t test_touch_check_ch_released_with_proximity(uint32_t test_ch_num, uint32_t exceed_time_ms) +{ + touch_pad_proximity_t proximity; + uint16_t ch_mask = 0; + touch_event_t evt = {0}; + int ret = ESP_FAIL; + + touch_pad_proximity_get_config(&proximity); + printf("Inactive: "); + while (1) { + if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) { + printf("0x%x, ", evt.pad_status); + if ((TEST_TOUCH_CHANNEL - test_ch_num) == __builtin_popcount(evt.pad_status)) { + ret = ESP_OK; + break; + } + } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_SCAN_DONE)) { + touch_pad_get_channel_mask(&ch_mask); + for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { + if (BIT(i) & ch_mask) { + if (evt.pad_num == i) { + if (proximity.meas_num == evt.slp_proxi_cnt) { + ets_printf("priximity base(%d) cnt(%d)\n", evt.slp_proxi_base, evt.slp_proxi_cnt); + } + } + } + } + continue; + } else { // If the interrupt type error, test error. + ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); + continue;; + } + } else { + ESP_LOGI(TAG, "Touch intr exceed time"); + break; + } + } + printf("\n"); + return (esp_err_t)ret; +} + +/* + * Check scan done interrupt of touch channels. + */ +static esp_err_t test_touch_check_ch_intr_scan_done(void) +{ + touch_event_t evt = {0}; + uint16_t ch_mask = 0; + int ret = ESP_FAIL; + /* Check the scan done interrupt. */ + while (1) { + if (pdTRUE == xQueueReceive(que_touch, &evt, 1000 / portTICK_PERIOD_MS)) { + /* Scan done interrupt have bug that be trigger by last two channel. */ + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) { + touch_pad_get_channel_mask(&ch_mask); + for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { + if (BIT(i) & ch_mask) { + if (evt.pad_num == i) { + ESP_LOGI(TAG, "touch _SCAN_DONE INTR be triggered"); + ret = ESP_OK; + } + goto NEXT_TEST; + } + } + } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { + continue; + } else { // If the interrupt type error, test error. + ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); + break; + } + } else { + ESP_LOGI(TAG, "Touch intr exceed time"); + break; + } + } +NEXT_TEST: + printf("\n"); + return (esp_err_t)ret; +} + +/* + * Check timeout interrupt of touch channels. + */ +static esp_err_t test_touch_check_ch_intr_timeout(touch_pad_t pad_num) +{ + int ret = ESP_FAIL; + touch_event_t evt = {0}; + + while (1) { + if (pdTRUE == xQueueReceive(que_touch, &evt, 1000 / portTICK_PERIOD_MS)) { + /* Scan done interrupt have bug that be trigger by last two channel. */ + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { + if (pad_num == evt.pad_num) { + ESP_LOGI(TAG, "touch TIMEOUT be triggered"); + s_touch_timeout_mask = 0; + ret = ESP_OK; + break; + } else { + ets_printf("-timeout %x T[%d] status %d, evt_msk %x -\n", + s_touch_timeout_mask, evt.pad_num, evt.pad_status, evt.intr_mask); + } + } else { + continue; + } + } else { + ESP_LOGI(TAG, "Touch intr exceed time"); + break; + } + } + printf("\n"); + return (esp_err_t)ret; +} + +static void test_touch_intr_cb(void *arg) +{ + uint32_t cnt, touch_value; + int task_awoken = pdFALSE; + touch_event_t evt; + evt.intr_mask = touch_pad_read_intr_status_mask(); + evt.pad_status = touch_pad_get_status(); + evt.pad_num = touch_pad_get_current_meas_channel(); + + if (!evt.intr_mask) { + ets_printf("."); + return; + } + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) { + touch_pad_filter_read_baseline(evt.pad_num, &evt.pad_val); + touch_pad_sleep_channel_read_baseline(&touch_value); + touch_pad_sleep_channel_read_proximity_cnt(&cnt); + evt.slp_proxi_cnt = cnt; + evt.slp_proxi_base = touch_value; + // ets_printf("[intr] base(%d) cnt(%d)\n", touch_value, cnt); + } + if (evt.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { + s_touch_timeout_mask |= (BIT(evt.pad_num)); + ets_printf("-%dtout-", SENS.sar_touch_status0.touch_scan_curr); + } + + xQueueSendFromISR(que_touch, &evt, &task_awoken); + if (task_awoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +/* + * Test the touch active/inactive interrupt. + * TEST POINT: + * 1. Touch interrupt. + * 2. Raw data noise. + * 3. smooth data and baseline data. + */ +esp_err_t test_touch_interrupt(void) +{ + uint32_t touch_value, smooth; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + // Initialize and start a software filter to detect slight change of capacitance. + vTaskDelay(50 / portTICK_PERIOD_MS); + + /* Set threshold of touch sensor */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + while (test_cnt--) { + test_touch_push_all(); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + + /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ + test_touch_baseline_not_update(); + + test_touch_release_all(); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +/* + * Test the touch active/inactive, scan_done interrupt. + * TEST POINT: + * 1. Touch interrupt. + * 2. Raw data noise. + * 3. smooth data and baseline data. + */ +esp_err_t test_touch_scan_done_interrupt(void) +{ + ESP_LOGI(TAG, " >> %s << \n", __func__); + uint32_t touch_value, smooth; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_SCAN_DONE | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + /* Check the scan done interrupt */ + TEST_ESP_OK( test_touch_check_ch_intr_scan_done() ); + + vTaskDelay(50 / portTICK_PERIOD_MS); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + while (test_cnt--) { + test_touch_push_all(); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + + /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ + test_touch_baseline_not_update(); + + test_touch_release_all(); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +/* + * Test the touch active/inactive, timeout interrupt. + * TEST POINT: + * 1. Touch interrupt. + * 2. Raw data noise. + * 3. smooth data and baseline data. + */ +esp_err_t test_touch_timeout_interrupt(void) +{ + ESP_LOGI(TAG, " >> %s << \n", __func__); + uint32_t touch_value, smooth; + + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_TIMEOUT | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + // Initialize and start a software filter to detect slight change of capacitance. + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + /* Set timeout parameter */ + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[0], &touch_value) ); + TEST_ESP_OK( touch_pad_timeout_disable() ); + TEST_ESP_OK( touch_pad_timeout_set_threshold(touch_value * 10) ); + TEST_ESP_OK( touch_pad_timeout_enable() ); + + // Only fake push one touch pad. + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + test_timeout_trigger_fake(touch_list[0]); + TEST_ESP_OK( test_touch_check_ch_intr_timeout(touch_list[0]) ); + test_timeout_normal(touch_list[0]); + + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + printf_touch_hw_read("raw "); + printf_touch_baseline_read("base "); + printf_touch_smooth_read("smooth"); + + int test_cnt = TEST_TOUCH_COUNT_NUM; + while (test_cnt--) { + test_touch_push_all(); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + + /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ + test_touch_baseline_not_update(); + + test_touch_release_all(); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor interrupt test (active, inactive, scan_done, timeout)", "[touch]") +{ + TEST_ESP_OK( test_touch_interrupt() ); + TEST_ESP_OK( test_touch_scan_done_interrupt() ); + TEST_ESP_OK( test_touch_timeout_interrupt() ); +} + +static void test_touch_measure_step(uint32_t step) +{ + /* Fake the process of debounce. */ + // printf("measure cnt %d: [ ", step); + for (int i = 0; i < step; i++) { + for (int j = 0; j < TEST_TOUCH_CHANNEL; j++) { + TEST_ESP_OK( touch_pad_sw_start() ); + while (!touch_pad_meas_is_done()) ; + } + // printf("."); + } + // printf(" ]\n"); +} + +/* + * Test the touch active/inactive, scan_done interrupt. + * TEST POINT: + * 1. Touch interrupt. + * 2. Raw data noise. + * 3. smooth data and baseline data. + */ +esp_err_t test_touch_filter_parameter_debounce(int deb_cnt) +{ + uint32_t touch_value; + int test_cnt = 2; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_128, // Test jitter and filter 1/4. + .debounce_cnt = ((deb_cnt < 0) ? 1 : deb_cnt) , // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_OFF, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + /* Run to wait the data become stable. */ + test_touch_measure_step(20); // 2 scan loop + + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ + touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + while (test_cnt--) { + test_touch_push_all(); + /* Fake the process of push debounce. */ + test_touch_measure_step(deb_cnt); // measure n times. touch state not changed. + TEST_ESP_ERR( ESP_FAIL, test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + test_touch_measure_step(1); // measure n+1 times. touch state changed. + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + + test_touch_release_all(); + /* Fake the process of release debounce. */ + test_touch_measure_step(deb_cnt); // measure n times. touch state not changed. + TEST_ESP_ERR( ESP_FAIL, test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + test_touch_measure_step(1); // measure n+1 times. touch state changed. + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +esp_err_t test_touch_filter_parameter_neg_reset(int reset_cnt) +{ + uint32_t touch_value, base_value; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + reset_cnt = ((reset_cnt < 0) ? 10 : reset_cnt); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = reset_cnt, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_OFF, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + /* Run to wait the data become stable. */ + test_touch_measure_step(20); // 2 scan loop + + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ + touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + /* 1. Fake init status is touched. */ + test_touch_push_all(); + TEST_ESP_OK( touch_pad_filter_reset_baseline(TOUCH_PAD_MAX) ); + /* Run to wait the data become stable. */ + test_touch_measure_step(20); // 2 scan loop + printf_touch_hw_read("[raw ] reset:"); + printf_touch_baseline_read("[base] reset:"); + + /* 2. Fake the touch status is released. */ + test_touch_release_all(); + /* 3. Fake measure `reset_cnt + 1` times to reset the baseline. */ + test_touch_measure_step(reset_cnt); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); + if ((base_value - touch_value) < (base_value * TOUCH_INTR_THRESHOLD)) { + ESP_LOGE(TAG, "neg reset cnt err"); + TEST_FAIL(); + } + } + printf_touch_hw_read("[raw ] neg_cnt:"); + printf_touch_baseline_read("[base] neg_cnt:"); + + test_touch_measure_step(1); + /* ESP32S2 neg reset baseline to raw data */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); + TEST_ASSERT_EQUAL_UINT32(base_value, touch_value); + } + printf_touch_hw_read("[raw ] neg_cnt+1:"); + printf_touch_baseline_read("[base] neg_cnt+1:"); + + int test_cnt = 2; + while (test_cnt--) { + test_touch_push_all(); + /* Fake the process of push debounce. */ + test_touch_measure_step(filter_info.debounce_cnt + 1); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + + test_touch_release_all(); + /* Fake the process of release debounce. */ + test_touch_measure_step(filter_info.debounce_cnt + 1); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +esp_err_t test_touch_filter_parameter_jitter(int jitter_step) +{ + uint32_t touch_value, base_value = 0; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + jitter_step = ((jitter_step < 0) ? 4 : jitter_step); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_JITTER, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = jitter_step, // use for jitter mode. + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + /* Run to wait the data become stable. */ + test_touch_measure_step(20); // 2 scan loop + + /* Check the jitter step. */ + printf_touch_baseline_read("[smooth] t1:"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + test_touch_measure_step(1); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + test_push_fake(touch_list[i]); + test_touch_measure_step(1); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); + TEST_ASSERT_EQUAL_UINT32(jitter_step, (base_value - touch_value)); + } + printf_touch_baseline_read("[smooth] t2:"); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + test_touch_measure_step(1); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + test_release_fake(touch_list[i]); + test_touch_measure_step(1); + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); + TEST_ASSERT_EQUAL_UINT32(jitter_step, (touch_value - base_value)); + } + printf_touch_baseline_read("[smooth] t3:"); + + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + //read baseline value + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + //set interrupt threshold. + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ + touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + int test_cnt = 2; + while (test_cnt--) { + test_touch_push_all(); + /* Fake the process of push debounce. */ + test_touch_measure_step(filter_info.debounce_cnt + 1); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_smooth_read("push"); + + test_touch_release_all(); + /* Fake the process of release debounce. */ + test_touch_measure_step(filter_info.debounce_cnt + 1); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_smooth_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor filter paramter test (debounce, neg_reset, jitter)", "[touch]") +{ + ESP_LOGI(TAG, "*********** touch filter debounce test ********************"); + TEST_ESP_OK( test_touch_filter_parameter_debounce(0) ); + TEST_ESP_OK( test_touch_filter_parameter_debounce(3) ); + TEST_ESP_OK( test_touch_filter_parameter_debounce(7) ); + + ESP_LOGI(TAG, "*********** touch filter neg threshold reset limit test ********************"); + TEST_ESP_OK( test_touch_filter_parameter_neg_reset(1) ); + TEST_ESP_OK( test_touch_filter_parameter_neg_reset(5) ); + TEST_ESP_OK( test_touch_filter_parameter_neg_reset(15) ); + + ESP_LOGI(TAG, "*********** touch filter jitter test ********************"); + TEST_ESP_OK( test_touch_filter_parameter_jitter(1) ); + TEST_ESP_OK( test_touch_filter_parameter_jitter(5) ); + TEST_ESP_OK( test_touch_filter_parameter_jitter(15) ); +} + +esp_err_t test_touch_denoise(uint32_t out_val[], uint32_t *denoise_val, touch_pad_denoise_grade_t grade, touch_pad_denoise_cap_t cap) +{ + uint32_t touch_value; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + ESP_LOGI(TAG, "Denoise level (%d), cap level (%d) \n", grade, cap); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = (grade < 0) ? TOUCH_PAD_DENOISE_BIT4 : grade, + .cap_level = (cap < 0) ? TOUCH_PAD_DENOISE_CAP_L4 : cap, + }; + TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); + TEST_ESP_OK( touch_pad_denoise_enable() ); + ESP_LOGI(TAG, "Denoise function init"); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + /* Run to wait the data become stable. */ + test_touch_measure_step(20); // 2 scan loop + + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + if (out_val) { + /* Output value for check. */ + out_val[i] = touch_value; + } + } + printf_touch_baseline_read("Denoise"); + if (denoise_val) { + touch_pad_denoise_read_data(denoise_val); + } + + int test_cnt = 1; + while (test_cnt--) { + test_touch_push_all(); + /* Fake the process of push debounce. */ + test_touch_measure_step(filter_info.debounce_cnt + 1); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + + test_touch_release_all(); + /* Fake the process of release debounce. */ + test_touch_measure_step(filter_info.debounce_cnt + 1); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor denoise test (cap, level)", "[touch]") +{ + uint32_t val_1[TEST_TOUCH_CHANNEL]; + uint32_t val_2[TEST_TOUCH_CHANNEL]; + uint32_t val_3[TEST_TOUCH_CHANNEL]; + uint32_t denoise_val[TOUCH_PAD_DENOISE_CAP_MAX]; + + ESP_LOGI(TAG, "*********** touch filter denoise level test ********************"); + TEST_ESP_OK( test_touch_denoise(val_1, NULL, TOUCH_PAD_DENOISE_BIT4, TOUCH_PAD_DENOISE_CAP_L0) ); + TEST_ESP_OK( test_touch_denoise(val_2, NULL, TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L0) ); + TEST_ESP_OK( test_touch_denoise(val_3, NULL, TOUCH_PAD_DENOISE_BIT12, TOUCH_PAD_DENOISE_CAP_L0) ); + + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ASSERT_GREATER_OR_EQUAL(val_3[i], val_2[i]); + TEST_ASSERT_GREATER_OR_EQUAL(val_2[i], val_1[i]); + } + + ESP_LOGI(TAG, "*********** touch filter denoise cap level test ********************"); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[0], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L0) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[1], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L1) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[2], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L2) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[3], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L3) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[4], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L4) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[5], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L5) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[6], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L6) ); + TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[7], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L7) ); + + printf("denoise read: "); + for (int i = 0; i < TOUCH_PAD_DENOISE_CAP_MAX - 1; i++) { + TEST_ASSERT_GREATER_OR_EQUAL(denoise_val[i], denoise_val[i + 1]); + printf("%d ", denoise_val[i]); + } + printf("\n"); +} + +esp_err_t test_touch_waterproof(void) +{ + uint32_t touch_value; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); + TEST_ESP_OK( touch_pad_denoise_enable() ); + ESP_LOGI(TAG, "Denoise function init"); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + /* Waterproof function */ + touch_pad_waterproof_t waterproof = { + .guard_ring_pad = TOUCH_WATERPROOF_RING_PAD, // If no ring pad, set 0; + /* It depends on the number of the parasitic capacitance of the shield pad. */ + .shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf + }; + TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); + TEST_ESP_OK( touch_pad_waterproof_enable() ); + ESP_LOGI(TAG, "touch pad waterproof init"); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + vTaskDelay(50 / portTICK_PERIOD_MS); + + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + } + + while (test_cnt--) { + test_touch_push_all(); + vTaskDelay(20 / portTICK_PERIOD_MS); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL - 1, TOUCH_EXCEED_TIME_MS) ); // take off shield pad + printf_touch_hw_read("push"); + + test_touch_release_all(); + vTaskDelay(20 / portTICK_PERIOD_MS); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor waterproof guard test", "[touch]") +{ + ESP_LOGI(TAG, "*********** touch filter waterproof guard test ********************"); + TEST_ESP_OK( test_touch_waterproof() ); +} + +esp_err_t test_touch_proximity(int meas_num) +{ + ESP_LOGI(TAG, " >> %s << \n", __func__); + + uint32_t touch_value; + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); + TEST_ESP_OK( touch_pad_denoise_enable() ); + ESP_LOGI(TAG, "Denoise function init"); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + /* Waterproof function */ + touch_pad_waterproof_t waterproof = { + .guard_ring_pad = TOUCH_WATERPROOF_RING_PAD,// If no ring pad, set 0; + /* It depends on the number of the parasitic capacitance of the shield pad. */ + .shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf + }; + TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); + TEST_ESP_OK( touch_pad_waterproof_enable() ); + ESP_LOGI(TAG, "touch pad waterproof init"); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + vTaskDelay(50 / portTICK_PERIOD_MS); + + touch_pad_proximity_t proximity = { + .select_pad[0] = proximity_pad[0], + .select_pad[1] = proximity_pad[1], + .select_pad[2] = proximity_pad[2], + .meas_num = meas_num < 0 ? 16 : meas_num, + }; + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + if (touch_list[i] == proximity.select_pad[0] || + touch_list[i] == proximity.select_pad[1] || + touch_list[i] == proximity.select_pad[2]) { + /* The threshold of proximity pad is the sum of touch reading `meas_num` times */ + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], + proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)) ); + ESP_LOGI(TAG, "proximity pad [%d] base %d, thresh %d", touch_list[i], touch_value, + (uint32_t)(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); + } else { + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "touch pad [%d] base %d, thresh %d", \ + touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + } + /* Should stop the measure, then change the config. */ + while (!touch_pad_meas_is_done()); + TEST_ESP_OK( touch_pad_fsm_stop() ); + /* Proximity function */ + TEST_ESP_OK( touch_pad_proximity_set_config(&proximity) ); + ESP_LOGI(TAG, "touch pad proximity init"); + TEST_ESP_OK( touch_pad_fsm_start() ); + + vTaskDelay(20 / portTICK_PERIOD_MS); + int test_cnt = TEST_TOUCH_COUNT_NUM; + while (test_cnt--) { + test_touch_push_all(); + vTaskDelay(20 / portTICK_PERIOD_MS); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL - 1, TOUCH_EXCEED_TIME_MS) ); // take off shield pad + printf_touch_hw_read("push"); + + test_touch_release_all(); + vTaskDelay(20 / portTICK_PERIOD_MS); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ESP_OK; +} + +TEST_CASE("Touch Sensor proximity test", "[touch]") +{ + ESP_LOGI(TAG, "*********** touch proximity test ********************"); + + TEST_ESP_OK( test_touch_proximity(5) ); + TEST_ESP_OK( test_touch_proximity(1) ); +} + +esp_err_t test_touch_sleep_reading_stable(touch_pad_t sleep_pad) +{ + uint32_t touch_temp = 0; + uint32_t touch_value, smooth, ret_val; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + // /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); + TEST_ESP_OK( touch_pad_denoise_enable() ); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_OFF, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + touch_pad_sleep_channel_t slp_config = { + .touch_num = sleep_pad, + .en_proximity = false, + }; + TEST_ESP_OK( touch_pad_sleep_channel_set_config(&slp_config) ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + // Initialize and start a software filter to detect slight change of capacitance. + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + /* Set threshold of touch sensor */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + /* Sleep channel setting */ + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); + TEST_ESP_OK( touch_pad_sleep_set_threshold(touch_value * TOUCH_INTR_THRESHOLD) ); + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + while (test_cnt--) { + /* Touch reading filtered value equal to raw data. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_sleep_channel_read_data(&touch_value) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_temp) ); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&touch_temp) ); + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); + } + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if (touch_temp) { + TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); + } + touch_temp = touch_value; + } + vTaskDelay(20 / portTICK_PERIOD_MS); + } + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&ret_val) ); + + TEST_ESP_OK( touch_pad_deinit() ); + + return ret_val; +} + + +TEST_CASE("Touch Sensor sleep pad reading stable test", "[touch]") +{ + ESP_LOGI(TAG, "*********** touch sleep pad low power (wakeup) test ********************"); + test_touch_sleep_reading_stable(touch_list[0]); +} + +/* + * Test the touch sleep pad interrupt in normal mode. + * TEST POINT: + * 1. Touch sleep pad interrupt. + * 2. sleep pad reading. + * 3. sleep pad enable proximity. + */ +uint32_t test_touch_sleep_pad_proximity(touch_pad_t sleep_pad, bool is_proximity, uint32_t meas_num) +{ + uint32_t touch_value, smooth, ret_val, dbc; + uint32_t measure_out; + uint32_t proximity_cnt; + uint32_t touch_thres; + int test_cnt = TEST_TOUCH_COUNT_NUM; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); + TEST_ESP_OK( touch_pad_denoise_enable() ); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_OFF, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Sleep channel setting */ + touch_pad_sleep_channel_t slp_config = { + .touch_num = sleep_pad, + .en_proximity = is_proximity, + }; + TEST_ESP_OK( touch_pad_sleep_channel_set_config(&slp_config) ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_SCAN_DONE | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + // Initialize and start a software filter to detect slight change of capacitance. + vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + if (is_proximity) { + touch_pad_proximity_t proximity = { + .select_pad[0] = sleep_pad, + .select_pad[1] = 0, + .select_pad[2] = 0, + .meas_num = meas_num == 0 ? 16 : meas_num, + }; + /* Set the threshold. */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + if (touch_list[i] == sleep_pad) { + touch_pad_sleep_channel_read_smooth(&touch_value); + touch_pad_sleep_set_threshold(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)); + ESP_LOGI(TAG, "Sleep pad [%d] base %d, thresh %d", touch_list[i], touch_value, + (uint32_t)(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); + } else if (touch_list[i] == proximity.select_pad[0] || + touch_list[i] == proximity.select_pad[1] || + touch_list[i] == proximity.select_pad[2]) { + // TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + touch_pad_sleep_channel_read_smooth(&touch_value); + /* The threshold of proximity pad is the sum of touch reading `meas_num` times */ + touch_pad_sleep_set_threshold( proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)); + ESP_LOGI(TAG, "proximity pad [%d] base %d, thresh %d", touch_list[i], touch_value, + (uint32_t)(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); + } else { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "touch pad [%d] base %d, thresh %d", \ + touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + } + /* Should stop the measure, then change the config. */ + while (!touch_pad_meas_is_done()); + TEST_ESP_OK( touch_pad_fsm_stop() ); + /* Proximity function */ + TEST_ESP_OK( touch_pad_proximity_set_config(&proximity) ); + ESP_LOGI(TAG, "touch pad proximity init"); + TEST_ESP_OK( touch_pad_fsm_start() ); + vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + } else { + /* Set threshold of touch sensor */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + /* Sleep channel setting */ + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&touch_value) ); + TEST_ESP_OK( touch_pad_sleep_set_threshold(touch_value * TOUCH_INTR_THRESHOLD) ); + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + } + + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&ret_val) ); + + while (test_cnt--) { + test_touch_push_all(); + TEST_ESP_OK( test_touch_check_ch_touched_with_proximity(TEST_TOUCH_CHANNEL, 5000) ); + printf_touch_hw_read("push"); + if (is_proximity) { + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); + TEST_ESP_OK( touch_pad_proximity_data_get(sleep_pad, &measure_out) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_proximity_cnt(&proximity_cnt) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_debounce(&dbc) ); + TEST_ESP_OK( touch_pad_sleep_get_threshold(&touch_thres) ); + printf("touch slp smooth %d, base %d, proxi %d cnt %d dbc %d thres%d status 0x%x\n", + smooth, touch_value, measure_out, proximity_cnt, dbc, + touch_thres, touch_pad_get_status()); + } + test_touch_release_all(); + TEST_ESP_OK( test_touch_check_ch_released_with_proximity(TEST_TOUCH_CHANNEL, 5000) ); + printf_touch_hw_read("release"); + if (is_proximity) { + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); + TEST_ESP_OK( touch_pad_proximity_data_get(sleep_pad, &measure_out) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_proximity_cnt(&proximity_cnt) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_debounce(&dbc) ); + printf("touch slp smooth %d, base %d, proxi %d cnt %d dbc %d status 0x%x\n", + smooth, touch_value, measure_out, proximity_cnt, dbc, touch_pad_get_status()); + } + } + + TEST_ESP_OK( touch_pad_deinit() ); + + return ret_val; +} + +TEST_CASE("Touch Sensor sleep pad and proximity interrupt test", "[touch]") +{ + ESP_LOGI(TAG, "*********** touch sleep pad interrupt test ********************"); + test_touch_sleep_pad_proximity(touch_list[0], false, 0); + test_touch_sleep_pad_proximity(touch_list[0], false, 0); + test_touch_sleep_pad_proximity(touch_list[0], false, 0); + + ESP_LOGI(TAG, "*********** touch sleep pad interrupt (proximity) test ********************"); + test_touch_sleep_pad_proximity(touch_list[0], true, 1); + test_touch_sleep_pad_proximity(touch_list[0], true, 3); + test_touch_sleep_pad_proximity(touch_list[0], true, 5); +} + +/* + * Test the touch sleep pad interrupt in normal mode. + * TEST POINT: + * 1. Touch sleep pad interrupt. + * 2. sleep pad reading. + * 3. denoise, waterproof + */ +esp_err_t test_touch_sleep_pad_interrupt_wakeup_deep_sleep(touch_pad_t sleep_pad) +{ + uint32_t touch_value, smooth, raw; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + // /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); + TEST_ESP_OK( touch_pad_denoise_disable() ); + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 3, // 0% + .noise_thr = 0, // 50% + .noise_neg_thr = 0, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_OFF, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Sleep channel setting */ + touch_pad_sleep_channel_t slp_config = { + .touch_num = sleep_pad, + .en_proximity = false, + }; + TEST_ESP_OK( touch_pad_sleep_channel_set_config(&slp_config) ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + + // Initialize and start a software filter to detect slight change of capacitance. + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + /* Set threshold of touch sensor */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); + } + + /* Sleep channel setting */ + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); + TEST_ESP_OK( touch_pad_sleep_set_threshold(touch_value * TOUCH_INTR_THRESHOLD) ); + + vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + test_touch_push_all(); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_data(&raw) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); + printf("touch slp raw %d, smooth %d, base %d, status 0x%x\n", raw, smooth, touch_value, touch_pad_get_status()); + + test_touch_release_all(); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_data(&raw) ); + TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); + printf("touch slp raw %d, smooth %d, base %d, status 0x%x\n", raw, smooth, touch_value, touch_pad_get_status()); + + return ESP_OK; +} + +#include +#include "esp_sleep.h" + +static RTC_DATA_ATTR struct timeval sleep_enter_time; + +static void test_deep_sleep_init(void) +{ + struct timeval now; + gettimeofday(&now, NULL); + int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; + printf("RTC_CNTL_SLP_WAKEUP_CAUSE_REG %x\n", REG_READ(RTC_CNTL_SLP_WAKEUP_CAUSE_REG)); + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_EXT1: { + uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_pin_mask != 0) { + int pin = __builtin_ffsll(wakeup_pin_mask) - 1; + printf("Wake up from GPIO %d\n", pin); + } else { + printf("Wake up from GPIO\n"); + } + break; + } + case ESP_SLEEP_WAKEUP_TIMER: { + printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms); + break; + } + case ESP_SLEEP_WAKEUP_TOUCHPAD: { + printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status()); + break; + } + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: { + printf("Not a deep sleep reset\n"); + ESP_LOGI(TAG, "*********** touch sleep pad wakeup test ********************"); + /* Sleep pad should be init once. */ + test_touch_sleep_pad_interrupt_wakeup_deep_sleep(touch_list[0]); + } + } + + vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); + + // const int wakeup_time_sec = 10; + // printf("Enabling timer wakeup, %ds\n", wakeup_time_sec); + // esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000); + + // const int ext_wakeup_pin_1 = 2; + // const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; + // const int ext_wakeup_pin_2 = 4; + // const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2; + + // printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2); + // esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH); + + printf("Enabling touch pad wakeup\n"); + esp_sleep_enable_touchpad_wakeup(); + // esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + printf("Entering deep sleep\n"); + gettimeofday(&sleep_enter_time, NULL); +} + +// TEST_CASE("Touch Sensor sleep pad wakeup deep sleep test", "[touch]") +void test_touch_sleep_wakeup(void) +{ + test_deep_sleep_init(); + + /* Change the work duty of touch sensor to reduce current. */ + touch_pad_set_meas_time(100, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); + + /* Close PD current in deep sleep. */ + RTCCNTL.bias_conf.pd_cur_deep_slp = 1; + RTCCNTL.bias_conf.pd_cur_monitor = 1; + RTCCNTL.bias_conf.bias_sleep_deep_slp = 1; + RTCCNTL.bias_conf.bias_sleep_monitor = 1; + + esp_deep_sleep_start(); +} + +#include "touch_scope.h" +/* + * 0: 10 channels raw/smooth/baseline data debug. + * 1: 5 channges smooth + baseline data debug. + * 2: 1 channels filter data. + */ +#define SCOPE_DEBUG_TYPE 2 +#define TOUCH_THRESHOLD 0.5 +#define TOUCH_SHELD_PAD (1) +#define SCOPE_DEBUG_CHANNEL_MAX (10) +#define SCOPE_DEBUG_ENABLE (0) +#define SCOPE_UART_BUADRATE (256000) +#define SCOPE_DEBUG_FREQ_MS (50) + +void test_touch_slope_debug(int pad_num) +{ + touch_event_t evt; + uint32_t touch_value, smooth; + + ESP_LOGI(TAG, " >> %s << \n", __func__); + if (que_touch == NULL) { + que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); + /* Should register once. */ + touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); + } else { + xQueueReset(que_touch); + } + TEST_ESP_OK( touch_pad_init() ); + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_config(touch_list[i]) ); + } + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. + .debounce_cnt = 1, // 1 time count. + .hysteresis_thr = 2, // 6.25% + .noise_thr = 3, // 50% + .noise_neg_thr = 3, // 50% + .neg_noise_limit = 10, // 10 time count. + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); + TEST_ESP_OK( touch_pad_filter_enable() ); + /* Register touch interrupt ISR, enable intr type. */ + TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); + TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); + TEST_ESP_OK( touch_pad_fsm_start() ); + /* Waterproof function */ + touch_pad_waterproof_t waterproof = { + .guard_ring_pad = 0, // If no ring pad, set 0; + /* It depends on the number of the parasitic capacitance of the shield pad. */ + .shield_driver = TOUCH_PAD_SHIELD_DRV_L2, //40pf + }; + TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); + TEST_ESP_OK( touch_pad_waterproof_enable() ); + ESP_LOGI(TAG, "touch pad waterproof init"); + + // Initialize and start a software filter to detect slight change of capacitance. + vTaskDelay(50 / portTICK_PERIOD_MS); + + /* Set threshold of touch sensor */ + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); + TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); + TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_THRESHOLD) ); + ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ + touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_THRESHOLD)); + } + + float scope_temp[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. + uint32_t scope_data[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. + test_tp_scope_debug_init(0, -1, -1, SCOPE_UART_BUADRATE); + +#if SCOPE_DEBUG_TYPE == 0 + while (1) { + for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { + touch_pad_read_raw_data(touch_list[i], &scope_data[i]); + // touch_pad_filter_read_smooth(touch_list[i], &scope_data[i]); + // touch_pad_filter_read_baseline(touch_list[i], &scope_data[i]); + scope_temp[i] = scope_data[i]; + } + test_tp_print_to_scope(scope_temp, TEST_TOUCH_CHANNEL); + vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); + } +#elif SCOPE_DEBUG_TYPE == 1 + while (1) { + int cnt = 0; + for (int i = 0; i < 5; i++) { + touch_pad_read_raw_data(touch_list[i], &scope_data[i]); + scope_temp[i] = scope_data[i]; + } + for (int i = 0; i < 5; i++) { + touch_pad_filter_read_smooth(touch_list[i], &scope_data[i]); + scope_temp[i + SCOPE_DEBUG_CHANNEL_MAX / 2] = scope_data[i]; + } + test_tp_print_to_scope(scope_temp, SCOPE_DEBUG_CHANNEL_MAX); + vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); + } +#elif SCOPE_DEBUG_TYPE == 2 + uint32_t status; + touch_pad_filter_read_baseline(pad_num, &status); + while (1) { + xQueueReceive(que_touch, &evt, SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); + //read filtered value + touch_pad_read_raw_data(pad_num, &scope_data[0]); + touch_pad_filter_read_baseline(pad_num, &scope_data[1]); + touch_pad_get_thresh(pad_num, &scope_data[2]); + touch_pad_filter_read_smooth(pad_num, &scope_data[8]); + // raw data + scope_temp[0] = scope_data[0]; + // baseline + scope_temp[1] = scope_data[1]; + // smooth data + scope_temp[8] = scope_data[8]; + // noise neg thr + scope_temp[2] = scope_temp[1] - scope_data[2] * 0.5; + // noise thr + scope_temp[3] = scope_temp[1] + scope_data[2] * 0.5; + // touch thr + scope_temp[4] = scope_temp[1] + scope_data[2]; + // hysteresis_thr thr + scope_temp[5] = scope_temp[4] - scope_data[2] * 0.0625; + // hysteresis_thr thr + scope_temp[6] = scope_temp[4] + scope_data[2] * 0.0625; + // touch status + if (touch_pad_get_status() & BIT(pad_num)) { + scope_temp[7] = status + 100; + } else { + scope_temp[7] = status - 100; //0:release; 1:push; + } + test_tp_print_to_scope(scope_temp, 9); + } +#elif SCOPE_DEBUG_TYPE == 3 + while (1) { + test_touch_push_all(); + TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("push"); + + /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ + test_touch_baseline_not_update(); + + test_touch_release_all(); + TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); + printf_touch_hw_read("release"); + } +#endif + TEST_ESP_OK( touch_pad_deinit() ); +} \ No newline at end of file diff --git a/components/driver/test/esp32s2/touch_scope.c b/components/driver/test/esp32s2/touch_scope.c new file mode 100644 index 000000000..cc9a4d375 --- /dev/null +++ b/components/driver/test/esp32s2/touch_scope.c @@ -0,0 +1,186 @@ +#include "esp_err.h" +#include "driver/uart.h" +#include "esp32s2/rom/uart.h" + +#define ROM_UART_DRIVER_ENABLE 0 + +#if ROM_UART_DRIVER_ENABLE +static uint8_t scope_uart_num = 0; +static int8_t uart_used = 0; +#else +static uint8_t scope_uart_num = 255; +static int8_t uart_used = -1; +#endif +static int scope_tx_io_num = 0; +static int scope_rx_io_num = 0; +static int scope_debug_baud_rate = 256000; +static unsigned char datascope_output_buffer[42] = {0}; // Data buff. + +/** + * @brief Translate a float data to four unsigned char data for uart TX. + * @param target target float data address. + * @param buf save translated data. + * @param offset the start position in buf. + * @return + * - void + */ +static void Float2Byte(float *target, unsigned char *buf, unsigned char offset) +{ + unsigned char *point; + point = (unsigned char*)target; //Get the address of float. + buf[offset] = point[0]; + buf[offset+1] = point[1]; + buf[offset+2] = point[2]; + buf[offset+3] = point[3]; +} + +/** + * @brief Add data to channal buff. + * @param Data target data. + * @param Channel target channel (1 - 10). + * @return + * - void + */ +static void datascope_get_channel_data(float data, unsigned char channel) +{ + if ( (channel > 10) || (channel == 0) ) { + return; + } else { + switch (channel) { + case 1: Float2Byte(&data,datascope_output_buffer,1); break; + case 2: Float2Byte(&data,datascope_output_buffer,5); break; + case 3: Float2Byte(&data,datascope_output_buffer,9); break; + case 4: Float2Byte(&data,datascope_output_buffer,13); break; + case 5: Float2Byte(&data,datascope_output_buffer,17); break; + case 6: Float2Byte(&data,datascope_output_buffer,21); break; + case 7: Float2Byte(&data,datascope_output_buffer,25); break; + case 8: Float2Byte(&data,datascope_output_buffer,29); break; + case 9: Float2Byte(&data,datascope_output_buffer,33); break; + case 10: Float2Byte(&data,datascope_output_buffer,37); break; + } + } +} + +/** + * @brief Transform float data to DataScopeV1.0 data format. + * @param channel_num the number of channel that wait to be translated. + * @return + * - The number of the UART TX data. + */ +static unsigned char datascope_data_generate(unsigned char channel_num) +{ + if ( (channel_num > 10) || (channel_num == 0) ) { + return 0; + } else { + datascope_output_buffer[0] = '$'; //frame header + switch(channel_num) { + case 1: datascope_output_buffer[5] = 5; return 6; break; + case 2: datascope_output_buffer[9] = 9; return 10; break; + case 3: datascope_output_buffer[13] = 13; return 14; break; + case 4: datascope_output_buffer[17] = 17; return 18; break; + case 5: datascope_output_buffer[21] = 21; return 22; break; + case 6: datascope_output_buffer[25] = 25; return 26; break; + case 7: datascope_output_buffer[29] = 29; return 30; break; + case 8: datascope_output_buffer[33] = 33; return 34; break; + case 9: datascope_output_buffer[37] = 37; return 38; break; + case 10: datascope_output_buffer[41] = 41; return 42; break; + } + } + return 0; +} + +/** + * @brief Send touch sensor data to HMI in PC via UART. + * @param uart_num Choose uart port (0, 1, 2). + * @param data The addr of the touch sensor data. + * @param channel_num The number of channel that wait to be translated. + * @return + * - ESP_FAIL Error + * - The number of the UART TX data. + */ +int test_tp_print_to_scope(float *data, unsigned char channel_num) +{ + uint8_t uart_num = scope_uart_num; + + if (uart_num >= UART_NUM_MAX) { + return ESP_FAIL; + } + if ( (channel_num > 10) || (channel_num == 0) || (NULL == data) ) { + return ESP_FAIL; + } + for(uint8_t i = 0 ; i < channel_num; i++) { + datascope_get_channel_data(data[i] , i+1); // write data x into channel 1~10. + } + unsigned char out_len = datascope_data_generate(channel_num); // Generate n number data. + unsigned char *out_data = datascope_output_buffer; + // Init uart. + if(uart_num != uart_used) { + return 0; + } else { +#if ROM_UART_DRIVER_ENABLE + uart_tx_wait_idle(uart_num); // Default print uart mumber is 0. + for(int i=0; i= UART_NUM_MAX) { + return ESP_FAIL; + } + scope_uart_num = uart_num; + scope_tx_io_num = tx_io_num; + scope_rx_io_num = rx_io_num; + scope_debug_baud_rate = baud_rate; + uart_config_t uart_config = { + .baud_rate = scope_debug_baud_rate, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + }; + uart_param_config(uart_num, &uart_config); + // Set UART pins using UART0 default pins i.e. no changes + uart_set_pin(uart_num, scope_tx_io_num, scope_rx_io_num, + UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + uart_driver_install(uart_num, 1024, 2048, 0, NULL, 0); + uart_used = uart_num; +#endif + return ESP_OK; +} diff --git a/components/driver/test/esp32s2/touch_scope.h b/components/driver/test/esp32s2/touch_scope.h new file mode 100644 index 000000000..936d6ada2 --- /dev/null +++ b/components/driver/test/esp32s2/touch_scope.h @@ -0,0 +1,4 @@ +#pragma once + +int test_tp_print_to_scope(float *data, unsigned char channel_num); +esp_err_t test_tp_scope_debug_init(uint8_t uart_num, int tx_io_num, int rx_io_num, int baud_rate); \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h b/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h index 5aab11106..9074d6b4b 100644 --- a/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h +++ b/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h @@ -623,6 +623,12 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable); */ #define touch_hal_sleep_read_baseline(baseline) touch_ll_sleep_read_baseline(baseline) +#define touch_hal_sleep_read_smooth(smooth_data) touch_ll_sleep_read_smooth(smooth_data) + +#define touch_hal_sleep_read_data(raw_data) touch_ll_sleep_read_data(raw_data) + +#define touch_hal_sleep_reset_baseline() touch_ll_sleep_reset_baseline() + /** * Read smooth data of touch sensor for sleep pad. */ diff --git a/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h b/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h index 992066c5a..d4bfece45 100644 --- a/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h +++ b/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h @@ -231,6 +231,26 @@ static inline void touch_ll_get_fsm_mode(touch_fsm_mode_t *mode) *mode = (touch_fsm_mode_t)RTCCNTL.touch_ctrl2.touch_start_force; } +static inline void touch_ll_clk_enable(void) +{ + RTCCNTL.touch_ctrl2.touch_clkgate_en = 1; //enable touch clock for FSM. or force enable. +} + +static inline void touch_ll_clk_disable(void) +{ + RTCCNTL.touch_ctrl2.touch_clkgate_en = 0; //enable touch clock for FSM. or force enable. +} + +/** + * Touch timer trigger measurement and always wait measurement done. + * Force done for touch timer ensures that the timer always can get the measurement done signal. + */ +static inline void touch_ll_timer_force_done(void) +{ + RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_FORCE_DONE; + RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_DONE; +} + /** * Enable/disable clock gate of touch sensor. * From baa7898e35102a8106b58b9d0b01e7b69f72e00a Mon Sep 17 00:00:00 2001 From: fuzhibo Date: Tue, 25 Feb 2020 22:19:48 +0800 Subject: [PATCH 2/2] driver(adc/dac): fix adc dac driver for esp32s2 1. update register file about adc; 2. fix adc driver; 3. add UT for adc/dac; See merge request espressif/esp-idf!7776 --- components/driver/CMakeLists.txt | 8 +- .../{adc1_i2s_private.h => adc1_private.h} | 13 +- ...c2_wifi_internal.h => adc2_wifi_private.h} | 5 +- components/driver/{adc.c => adc_common.c} | 386 +- components/driver/component.mk | 2 +- components/driver/esp32/adc.c | 181 + components/driver/esp32/include/driver/adc.h | 88 + .../esp32/include/{ => driver}/touch_sensor.h | 0 components/driver/esp32s2/adc.c | 380 ++ .../driver/esp32s2/include/driver/adc.h | 277 + .../include/{ => driver}/temp_sensor.h | 8 +- .../include/{ => driver}/touch_sensor.h | 14 +- components/driver/esp32s2/rtc_tempsensor.c | 31 +- components/driver/i2s.c | 4 +- .../include/driver/{adc.h => adc_common.h} | 248 +- components/driver/include/driver/dac.h | 2 +- components/driver/include/driver/touch_pad.h | 2 +- components/driver/test/CMakeLists.txt | 4 +- .../driver/test/adc_dma_test/test_esp32.c | 142 + .../driver/test/adc_dma_test/test_esp32s2.c | 494 ++ components/driver/test/component.mk | 2 +- .../test/dac_dma_test/test_dac_audio_file.h | 4989 +++++++++++++++++ .../driver/test/dac_dma_test/test_esp32.c | 176 + .../driver/test/esp32/test_touch_sensor.c | 330 -- .../driver/test/esp32s2/test_touch_sensor.c | 2200 -------- components/driver/test/esp32s2/touch_scope.c | 186 - components/driver/test/esp32s2/touch_scope.h | 4 - .../{test_adc2.c => test_adc2_with_wifi.c} | 59 +- components/driver/test/test_adc_common.c | 266 + components/driver/test/test_dac.c | 120 + components/driver/test/test_i2s.c | 2 +- components/soc/include/hal/adc_hal.h | 106 +- components/soc/include/hal/adc_types.h | 295 +- components/soc/include/hal/dac_types.h | 8 +- .../soc/include/hal/touch_sensor_types.h | 3 +- .../soc/soc/esp32/include/soc/adc_caps.h | 6 +- .../soc/soc/esp32s2/include/soc/adc_caps.h | 14 +- .../soc/esp32s2/include/soc/apb_ctrl_struct.h | 146 +- .../esp32s2/include/soc/apb_saradc_struct.h | 7 - .../soc/esp32s2/include/soc/rtc_i2c_struct.h | 6 +- components/soc/src/esp32/CMakeLists.txt | 3 +- components/soc/src/esp32/adc_hal.c | 87 + .../soc/src/esp32/include/hal/adc_hal.h | 118 + components/soc/src/esp32/include/hal/adc_ll.h | 244 +- components/soc/src/esp32/include/hal/dac_ll.h | 2 + components/soc/src/esp32/touch_sensor_hal.c | 2 +- components/soc/src/esp32s2/CMakeLists.txt | 3 +- components/soc/src/esp32s2/adc_hal.c | 252 + .../soc/src/esp32s2/include/hal/adc_hal.h | 262 + .../soc/src/esp32s2/include/hal/adc_ll.h | 1033 +++- .../soc/src/esp32s2/include/hal/dac_ll.h | 23 + .../esp32s2/include/hal/touch_sensor_hal.h | 6 - .../src/esp32s2/include/hal/touch_sensor_ll.h | 20 - components/soc/src/hal/adc_hal.c | 68 +- docs/Doxyfile | 7 +- .../peripherals/adc/main/adc1_example_main.c | 8 +- .../peripherals/adc2/main/adc2_example_main.c | 8 +- .../peripherals/i2s_adc_dac/main/app_main.c | 5 +- .../main/temp_sensor_main.c | 2 +- .../main/app_trace_to_host_example_main.c | 4 + .../ulp_adc/main/ulp_adc_example_main.c | 4 + tools/ci/config/target-test.yml | 2 +- 62 files changed, 9686 insertions(+), 3691 deletions(-) rename components/driver/{adc1_i2s_private.h => adc1_private.h} (86%) rename components/driver/{include/driver/adc2_wifi_internal.h => adc2_wifi_private.h} (93%) rename components/driver/{adc.c => adc_common.c} (56%) create mode 100644 components/driver/esp32/adc.c create mode 100644 components/driver/esp32/include/driver/adc.h rename components/driver/esp32/include/{ => driver}/touch_sensor.h (100%) create mode 100644 components/driver/esp32s2/adc.c create mode 100644 components/driver/esp32s2/include/driver/adc.h rename components/driver/esp32s2/include/{ => driver}/temp_sensor.h (95%) rename components/driver/esp32s2/include/{ => driver}/touch_sensor.h (99%) rename components/driver/include/driver/{adc.h => adc_common.h} (59%) create mode 100644 components/driver/test/adc_dma_test/test_esp32.c create mode 100644 components/driver/test/adc_dma_test/test_esp32s2.c create mode 100644 components/driver/test/dac_dma_test/test_dac_audio_file.h create mode 100644 components/driver/test/dac_dma_test/test_esp32.c delete mode 100644 components/driver/test/esp32/test_touch_sensor.c delete mode 100644 components/driver/test/esp32s2/test_touch_sensor.c delete mode 100644 components/driver/test/esp32s2/touch_scope.c delete mode 100644 components/driver/test/esp32s2/touch_scope.h rename components/driver/test/{test_adc2.c => test_adc2_with_wifi.c} (65%) create mode 100644 components/driver/test/test_adc_common.c create mode 100644 components/driver/test/test_dac.c create mode 100644 components/soc/src/esp32/adc_hal.c create mode 100644 components/soc/src/esp32/include/hal/adc_hal.h create mode 100644 components/soc/src/esp32s2/adc_hal.c create mode 100644 components/soc/src/esp32s2/include/hal/adc_hal.h diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 0ad0df9a2..9fd9b8be9 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -1,5 +1,5 @@ set(srcs - "adc.c" + "adc_common.c" "can.c" "dac.c" "gpio.c" @@ -31,13 +31,15 @@ if(IDF_TARGET STREQUAL "esp32") "sdio_slave.c" "sdmmc_host.c" "sdmmc_transaction.c" - "esp32/touch_sensor.c") + "esp32/touch_sensor.c" + "esp32/adc.c") list(APPEND includes "esp32/include") endif() if(IDF_TARGET STREQUAL "esp32s2") list(APPEND srcs "esp32s2/rtc_tempsensor.c" - "esp32s2/touch_sensor.c") + "esp32s2/touch_sensor.c" + "esp32s2/adc.c") # currently only S2 beta has its own target-specific includes list(APPEND includes "esp32s2/include") endif() diff --git a/components/driver/adc1_i2s_private.h b/components/driver/adc1_private.h similarity index 86% rename from components/driver/adc1_i2s_private.h rename to components/driver/adc1_private.h index 76da3da02..40b5ee685 100644 --- a/components/driver/adc1_i2s_private.h +++ b/components/driver/adc1_private.h @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _DRIVER_ADC1_I2S_PRIVATE_H_ -#define _DRIVER_ADC1_I2S_PRIVATE_H_ +#pragma once #ifdef __cplusplus extern "C" { @@ -34,26 +33,26 @@ void adc_power_always_on(void); /** * @brief For I2S dma to claim the usage of ADC1. * - * Other tasks will be forbidden to use ADC1 between ``adc1_i2s_mode_acquire`` and ``adc1_i2s_release``. + * Other tasks will be forbidden to use ADC1 between ``adc1_dma_mode_acquire`` and ``adc1_i2s_release``. * The I2S module may have to wait for a short time for the current conversion (if exist) to finish. * * @return * - ESP_OK success * - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success. */ -esp_err_t adc1_i2s_mode_acquire(void); +esp_err_t adc1_dma_mode_acquire(void); /** * @brief For ADC1 to claim the usage of ADC1. * - * Other tasks will be forbidden to use ADC1 between ``adc1_adc_mode_acquire`` and ``adc1_i2s_release``. + * Other tasks will be forbidden to use ADC1 between ``adc1_rtc_mode_acquire`` and ``adc1_i2s_release``. * The ADC1 may have to wait for some time for the I2S read operation to finish. * * @return * - ESP_OK success * - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success. */ -esp_err_t adc1_adc_mode_acquire(void); +esp_err_t adc1_rtc_mode_acquire(void); /** * @brief to let other tasks use the ADC1 when I2S is not work. @@ -69,5 +68,3 @@ esp_err_t adc1_lock_release(void); } #endif -#endif /*_DRIVER_ADC1_I2S_PRIVATE_H_*/ - diff --git a/components/driver/include/driver/adc2_wifi_internal.h b/components/driver/adc2_wifi_private.h similarity index 93% rename from components/driver/include/driver/adc2_wifi_internal.h rename to components/driver/adc2_wifi_private.h index 833d97d96..f01e126a7 100644 --- a/components/driver/include/driver/adc2_wifi_internal.h +++ b/components/driver/adc2_wifi_private.h @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _DRIVER_ADC2_INTERNAL_H_ -#define _DRIVER_ADC2_INTERNAL_H_ +#pragma once #ifdef __cplusplus extern "C" { @@ -48,5 +47,3 @@ esp_err_t adc2_wifi_release(void); } #endif -#endif /*_DRIVER_ADC2_INTERNAL_H_*/ - diff --git a/components/driver/adc.c b/components/driver/adc_common.c similarity index 56% rename from components/driver/adc.c rename to components/driver/adc_common.c index afb7cb86a..a2c626219 100644 --- a/components/driver/adc.c +++ b/components/driver/adc_common.c @@ -20,25 +20,18 @@ #include "freertos/semphr.h" #include "freertos/timers.h" #include "esp_log.h" +#include "esp_pm.h" #include "soc/rtc.h" #include "rtc_io.h" -#include "adc.h" -#include "dac.h" +#include "driver/dac.h" #include "sys/lock.h" #include "driver/gpio.h" -#include "adc1_i2s_private.h" +#include "driver/adc.h" +#include "adc1_private.h" #include "hal/adc_types.h" #include "hal/adc_hal.h" -#define ADC_MAX_MEAS_NUM_DEFAULT (255) -#define ADC_MEAS_NUM_LIM_DEFAULT (1) -#define SAR_ADC_CLK_DIV_DEFUALT (2) - -#define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIG_FORMAT_12BIT) -#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11) -#define DIG_ADC_BIT_WIDTH_DEFUALT (ADC_WIDTH_BIT_12) - #define ADC_CHECK_RET(fun_ret) ({ \ if (fun_ret != ESP_OK) { \ ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \ @@ -65,9 +58,11 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi /* In ADC2, there're two locks used for different cases: -1. lock shared with app and WIFI: - when wifi using the ADC2, we assume it will never stop, - so app checks the lock and returns immediately if failed. +1. lock shared with app and Wi-Fi: + ESP32: + When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed. + ESP32S2: + The controller's control over the ADC is determined by the arbiter. There is no need to control by lock. 2. lock shared between tasks: when several tasks sharing the ADC2, we want to guarantee @@ -77,13 +72,40 @@ In ADC2, there're two locks used for different cases: adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock. */ +#ifdef CONFIG_IDF_TARGET_ESP32 //prevent ADC2 being used by wifi and other tasks at the same time. static _lock_t adc2_wifi_lock; +/** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock. */ +#define ADC2_WIFI_LOCK_ACQUIRE() _lock_acquire( &adc2_wifi_lock ) +#define ADC2_WIFI_LOCK_RELEASE() _lock_release( &adc2_wifi_lock ) +#define ADC2_WIFI_LOCK_TRY_ACQUIRE() _lock_try_acquire( &adc2_wifi_lock ) +#define ADC2_WIFI_LOCK_CHECK() ((uint32_t *)adc2_wifi_lock != NULL) + +#elif defined CONFIG_IDF_TARGET_ESP32S2 + +#define ADC2_WIFI_LOCK_ACQUIRE() +#define ADC2_WIFI_LOCK_RELEASE() +#define ADC2_WIFI_LOCK_TRY_ACQUIRE() (0) //WIFI controller and rtc controller have independent parameter configuration. +#define ADC2_WIFI_LOCK_CHECK() (true) + +#endif + //prevent ADC2 being used by tasks (regardless of WIFI) static portMUX_TYPE adc2_spinlock = portMUX_INITIALIZER_UNLOCKED; +#define ADC2_ENTER_CRITICAL() portENTER_CRITICAL( &adc2_spinlock ) +#define ADC2_EXIT_CRITICAL() portEXIT_CRITICAL( &adc2_spinlock ) //prevent ADC1 being used by I2S dma and other tasks at the same time. -static _lock_t adc1_i2s_lock; +static _lock_t adc1_dma_lock; +#define ADC1_DMA_LOCK_ACQUIRE() _lock_acquire( &adc1_dma_lock ) +#define ADC1_DMA_LOCK_RELEASE() _lock_release( &adc1_dma_lock ) + +#ifdef CONFIG_IDF_TARGET_ESP32S2 +#ifdef CONFIG_PM_ENABLE +static esp_pm_lock_handle_t s_adc2_arbiter_lock; +#endif //CONFIG_PM_ENABLE +#endif //CONFIG_IDF_TARGET_ESP32S2 + /*--------------------------------------------------------------- ADC Common ---------------------------------------------------------------*/ @@ -121,16 +143,7 @@ void adc_power_off(void) esp_err_t adc_set_clk_div(uint8_t clk_div) { ADC_ENTER_CRITICAL(); - adc_hal_set_clk_div(clk_div); - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - -esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) -{ - ADC_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG); - ADC_ENTER_CRITICAL(); - adc_hal_dig_set_data_source(src); + adc_hal_digi_set_clk_div(clk_div); ADC_EXIT_CRITICAL(); return ESP_OK; } @@ -141,18 +154,14 @@ esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel) if (adc_unit & ADC_UNIT_1) { ADC_CHANNEL_CHECK(ADC_NUM_1, channel); gpio_num = ADC_GET_IO_NUM(ADC_NUM_1, channel); - - ADC_CHECK_RET(rtc_gpio_init(gpio_num)); - ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); - ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); } if (adc_unit & ADC_UNIT_2) { ADC_CHANNEL_CHECK(ADC_NUM_2, channel); gpio_num = ADC_GET_IO_NUM(ADC_NUM_2, channel); - ADC_CHECK_RET(rtc_gpio_init(gpio_num)); - ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); - ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); } + ADC_CHECK_RET(rtc_gpio_init(gpio_num)); + ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); + ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); return ESP_OK; } @@ -160,18 +169,24 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en) { ADC_ENTER_CRITICAL(); if (adc_unit & ADC_UNIT_1) { - adc_hal_output_invert(ADC_NUM_1, inv_en); + adc_hal_rtc_output_invert(ADC_NUM_1, inv_en); } if (adc_unit & ADC_UNIT_2) { - adc_hal_output_invert(ADC_NUM_1, inv_en); + adc_hal_rtc_output_invert(ADC_NUM_1, inv_en); } ADC_EXIT_CRITICAL(); + return ESP_OK; } esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits) { - ADC_CHECK(bits < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG); +#ifdef CONFIG_IDF_TARGET_ESP32 + ADC_CHECK(bits < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); +#elif defined CONFIG_IDF_TARGET_ESP32S2 + ADC_CHECK(bits == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG); +#endif + ADC_ENTER_CRITICAL(); if (adc_unit & ADC_UNIT_1) { adc_hal_rtc_set_output_format(ADC_NUM_1, bits); @@ -181,68 +196,41 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits) adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT); } ADC_EXIT_CRITICAL(); + return ESP_OK; } -/* this function should be called in the critical section. */ -static int adc_convert(adc_ll_num_t adc_n, int channel) +/** + * @brief Reset RTC controller FSM. + * + * @return + * - ESP_OK Success + */ +#ifdef CONFIG_IDF_TARGET_ESP32S2 +esp_err_t adc_rtc_reset(void) { - return adc_hal_convert(adc_n, channel); -} - -/*------------------------------------------------------------------------------------- - * ADC I2S - *------------------------------------------------------------------------------------*/ -esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) -{ - if (adc_unit & ADC_UNIT_1) { - ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_1)), "ADC1 not support DMA for now.", ESP_ERR_INVALID_ARG); - ADC_CHANNEL_CHECK(ADC_NUM_1, channel); - } - if (adc_unit & ADC_UNIT_2) { - ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_2)), "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG); - ADC_CHANNEL_CHECK(ADC_NUM_2, channel); - } - - adc_ll_pattern_table_t adc1_pattern[1]; - adc_ll_pattern_table_t adc2_pattern[1]; - adc_hal_dig_config_t dig_cfg = { - .conv_limit_en = ADC_MEAS_NUM_LIM_DEFAULT, - .conv_limit_num = ADC_MAX_MEAS_NUM_DEFAULT, - .clk_div = SAR_ADC_CLK_DIV_DEFUALT, - .format = DIG_ADC_OUTPUT_FORMAT_DEFUALT, - .conv_mode = (adc_ll_convert_mode_t)adc_unit, - }; - - if (adc_unit & ADC_UNIT_1) { - adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT; - adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT; - adc1_pattern[0].channel = channel; - dig_cfg.adc1_pattern_len = 1; - dig_cfg.adc1_pattern = adc1_pattern; - } - if (adc_unit & ADC_UNIT_2) { - adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT; - adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT; - adc2_pattern[0].channel = channel; - dig_cfg.adc2_pattern_len = 1; - dig_cfg.adc2_pattern = adc2_pattern; - } - ADC_ENTER_CRITICAL(); - adc_hal_init(); - adc_hal_dig_controller_config(&dig_cfg); + adc_hal_rtc_reset(); ADC_EXIT_CRITICAL(); - return ESP_OK; } +static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel) +{ + adc_atten_t atten = adc_hal_get_atten(adc_n, channel); + uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false); + adc_hal_set_calibration_param(adc_n, cal_val); + ESP_LOGD(ADC_TAG, "Set cal adc %d\n", cal_val); +} +#endif + /*------------------------------------------------------------------------------------- * ADC1 *------------------------------------------------------------------------------------*/ esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num) { ADC_CHANNEL_CHECK(ADC_NUM_1, channel); + int io = ADC_GET_IO_NUM(ADC_NUM_1, channel); if (io < 0) { return ESP_ERR_INVALID_ARG; @@ -257,71 +245,91 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) { ADC_CHANNEL_CHECK(ADC_NUM_1, channel); ADC_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG); + adc_gpio_init(ADC_UNIT_1, channel); + ADC_ENTER_CRITICAL(); adc_hal_set_atten(ADC_NUM_1, channel, atten); + ADC_EXIT_CRITICAL(); + return ESP_OK; } esp_err_t adc1_config_width(adc_bits_width_t width_bit) { - ADC_CHECK(width_bit < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG); +#ifdef CONFIG_IDF_TARGET_ESP32 + ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); +#elif defined CONFIG_IDF_TARGET_ESP32S2 + ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG); +#endif + + ADC_ENTER_CRITICAL(); adc_hal_rtc_set_output_format(ADC_NUM_1, width_bit); - adc_hal_output_invert(ADC_NUM_1, true); + adc_hal_rtc_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT); + adc_hal_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1)); + ADC_EXIT_CRITICAL(); + return ESP_OK; } -esp_err_t adc1_i2s_mode_acquire(void) +esp_err_t adc1_dma_mode_acquire(void) { /* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */ - _lock_acquire( &adc1_i2s_lock ); - ESP_LOGD( ADC_TAG, "i2s mode takes adc1 lock." ); + ADC1_DMA_LOCK_ACQUIRE(); + ESP_LOGD( ADC_TAG, "dma mode takes adc1 lock." ); + ADC_ENTER_CRITICAL(); adc_hal_set_power_manage(ADC_POWER_SW_ON); /* switch SARADC into DIG channel */ adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_DIG); ADC_EXIT_CRITICAL(); + return ESP_OK; } -esp_err_t adc1_adc_mode_acquire(void) +esp_err_t adc1_rtc_mode_acquire(void) { /* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */ - _lock_acquire( &adc1_i2s_lock ); + ADC1_DMA_LOCK_ACQUIRE(); + ADC_ENTER_CRITICAL(); /* switch SARADC into RTC channel. */ adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); ADC_EXIT_CRITICAL(); + return ESP_OK; } esp_err_t adc1_lock_release(void) { - ADC_CHECK((uint32_t *)adc1_i2s_lock != NULL, "adc1 lock release called before acquire", ESP_ERR_INVALID_STATE ); - /* Use locks to avoid digtal and RTC controller conflicts. - for adc1, block until acquire the lock. */ - _lock_release( &adc1_i2s_lock ); + ADC_CHECK((uint32_t *)adc1_dma_lock != NULL, "adc1 lock release called before acquire", ESP_ERR_INVALID_STATE ); + /* Use locks to avoid digtal and RTC controller conflicts. for adc1, block until acquire the lock. */ + ADC1_DMA_LOCK_RELEASE(); return ESP_OK; } int adc1_get_raw(adc1_channel_t channel) { - uint16_t adc_value; + int adc_value; ADC_CHANNEL_CHECK(ADC_NUM_1, channel); - adc1_adc_mode_acquire(); - + adc1_rtc_mode_acquire(); adc_power_on(); + ADC_ENTER_CRITICAL(); - /* disable other peripherals. */ - adc_hal_hall_disable(); - /* currently the LNA is not open, close it by default. */ - adc_hal_amp_disable(); - /* set controller */ - adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); - /* start conversion */ - adc_value = adc_convert(ADC_NUM_1, channel); +#ifdef CONFIG_IDF_TARGET_ESP32 + adc_hal_hall_disable(); //Disable other peripherals. + adc_hal_amp_disable(); //Currently the LNA is not open, close it by default. +#endif +#ifdef CONFIG_IDF_TARGET_ESP32S2 + adc_set_init_code(ADC_NUM_1, channel); // calibration for adc +#endif + adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC); //Set controller + adc_hal_convert(ADC_NUM_1, channel, &adc_value); //Start conversion, For ADC1, the data always valid. ADC_EXIT_CRITICAL(); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + adc_hal_rtc_reset(); //Reset FSM of rtc controller +#endif adc1_lock_release(); return adc_value; @@ -340,9 +348,11 @@ void adc1_ulp_enable(void) adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_ULP); /* since most users do not need LNA and HALL with uLP, we disable them here open them in the uLP if needed. */ +#ifdef CONFIG_IDF_TARGET_ESP32 /* disable other peripherals. */ adc_hal_hall_disable(); adc_hal_amp_disable(); +#endif ADC_EXIT_CRITICAL(); } @@ -352,6 +362,7 @@ void adc1_ulp_enable(void) esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num) { ADC_CHANNEL_CHECK(ADC_NUM_2, channel); + int io = ADC_GET_IO_NUM(ADC_NUM_2, channel); if (io < 0) { return ESP_ERR_INVALID_ARG; @@ -362,20 +373,21 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num) return ESP_OK; } +/** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/ esp_err_t adc2_wifi_acquire(void) { /* Wi-Fi module will use adc2. Use locks to avoid conflicts. */ - _lock_acquire( &adc2_wifi_lock ); + ADC2_WIFI_LOCK_ACQUIRE(); ESP_LOGD( ADC_TAG, "Wi-Fi takes adc2 lock." ); return ESP_OK; } esp_err_t adc2_wifi_release(void) { - ADC_CHECK((uint32_t *)adc2_wifi_lock != NULL, "wifi release called before acquire", ESP_ERR_INVALID_STATE ); - - _lock_release( &adc2_wifi_lock ); + ADC_CHECK(ADC2_WIFI_LOCK_CHECK(), "wifi release called before acquire", ESP_ERR_INVALID_STATE ); + ADC2_WIFI_LOCK_RELEASE(); ESP_LOGD( ADC_TAG, "Wi-Fi returns adc2 lock." ); + return ESP_OK; } @@ -395,119 +407,123 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) ADC_CHECK(atten <= ADC_ATTEN_11db, "ADC2 Atten Err", ESP_ERR_INVALID_ARG); adc2_pad_init(channel); - portENTER_CRITICAL( &adc2_spinlock ); - - //lazy initialization + ADC2_ENTER_CRITICAL(); //avoid collision with other tasks - if ( _lock_try_acquire( &adc2_wifi_lock ) == -1 ) { + if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) { //try the lock, return if failed (wifi using). - portEXIT_CRITICAL( &adc2_spinlock ); + ADC2_EXIT_CRITICAL(); return ESP_ERR_TIMEOUT; } adc_hal_set_atten(ADC_NUM_2, channel, atten); - _lock_release( &adc2_wifi_lock ); + ADC2_WIFI_LOCK_RELEASE(); + ADC2_EXIT_CRITICAL(); - portEXIT_CRITICAL( &adc2_spinlock ); return ESP_OK; } static inline void adc2_config_width(adc_bits_width_t width_bit) { +#ifdef CONFIG_IDF_TARGET_ESP32S2 +#ifdef CONFIG_PM_ENABLE + /* Lock APB clock. */ + if (s_adc2_arbiter_lock == NULL) { + esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc2", &s_adc2_arbiter_lock); + } +#endif //CONFIG_PM_ENABLE +#endif //CONFIG_IDF_TARGET_ESP32S2 ADC_ENTER_CRITICAL(); adc_hal_rtc_set_output_format(ADC_NUM_2, width_bit); adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT); - adc_hal_output_invert(ADC_NUM_2, true); + adc_hal_rtc_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT); + adc_hal_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2)); ADC_EXIT_CRITICAL(); } static inline void adc2_dac_disable( adc2_channel_t channel) { +#ifdef CONFIG_IDF_TARGET_ESP32 if ( channel == ADC2_CHANNEL_8 ) { // the same as DAC channel 1 dac_output_disable(DAC_CHANNEL_1); } else if ( channel == ADC2_CHANNEL_9 ) { dac_output_disable(DAC_CHANNEL_2); } +#elif defined CONFIG_IDF_TARGET_ESP32S2 + if ( channel == ADC2_CHANNEL_6 ) { // the same as DAC channel 1 + dac_output_disable(DAC_CHANNEL_1); + } else if ( channel == ADC2_CHANNEL_7 ) { + dac_output_disable(DAC_CHANNEL_2); + } +#endif } -//registers in critical section with adc1: -//SENS_SAR_START_FORCE_REG, +/** + * @note For ESP32S2: + * The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. + * Or, the RTC controller will fail when get raw data. + * This issue does not occur on digital controllers (DMA mode), and the hardware guarantees that there will be no errors. + */ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out) { - uint16_t adc_value = 0; + int adc_value = 0; + + ADC_CHECK(raw_out != NULL, "ADC out value err", ESP_ERR_INVALID_ARG); ADC_CHECK(channel < ADC2_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); +#ifdef CONFIG_IDF_TARGET_ESP32 + ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); +#elif defined CONFIG_IDF_TARGET_ESP32S2 + ADC_CHECK(width_bit == ADC_WIDTH_BIT_13, "WIDTH ERR: ESP32S2 support 13 bit width", ESP_ERR_INVALID_ARG); +#endif - //in critical section with whole rtc module - adc_power_on(); + adc_power_on(); //in critical section with whole rtc module - //avoid collision with other tasks - portENTER_CRITICAL(&adc2_spinlock); - //lazy initialization - //try the lock, return if failed (wifi using). - if ( _lock_try_acquire( &adc2_wifi_lock ) == -1 ) { - portEXIT_CRITICAL( &adc2_spinlock ); + ADC2_ENTER_CRITICAL(); //avoid collision with other tasks + + if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) { //try the lock, return if failed (wifi using). + ADC2_EXIT_CRITICAL(); return ESP_ERR_TIMEOUT; } - - //disable other peripherals #ifdef CONFIG_ADC_DISABLE_DAC - adc2_dac_disable(channel); + adc2_dac_disable(channel); //disable other peripherals #endif - // set controller - // in critical section with whole rtc module - // because the PWDET use the same registers, place it here. - adc2_config_width(width_bit); - adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC); - //start converting - adc_value = adc_convert(ADC_NUM_2, channel); - _lock_release( &adc2_wifi_lock ); - portEXIT_CRITICAL(&adc2_spinlock); + adc2_config_width(width_bit); // in critical section with whole rtc module. because the PWDET use the same registers, place it here. +#ifdef CONFIG_IDF_TARGET_ESP32S2 + adc_set_init_code(ADC_NUM_2, channel); // calibration for adc +#endif + adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller - *raw_out = (int)adc_value; +#ifdef CONFIG_IDF_TARGET_ESP32S2 +#ifdef CONFIG_PM_ENABLE + if (s_adc2_arbiter_lock) { + esp_pm_lock_acquire(s_adc2_arbiter_lock); + } +#endif //CONFIG_PM_ENABLE +#endif //CONFIG_IDF_TARGET_ESP32 + + if (adc_hal_convert(ADC_NUM_2, channel, &adc_value)) { + adc_value = -1; + } + +#ifdef CONFIG_IDF_TARGET_ESP32S2 +#ifdef CONFIG_PM_ENABLE + /* Release APB clock. */ + if (s_adc2_arbiter_lock) { + esp_pm_lock_release(s_adc2_arbiter_lock); + } +#endif //CONFIG_PM_ENABLE +#endif //CONFIG_IDF_TARGET_ESP32 + + ADC2_WIFI_LOCK_RELEASE(); + ADC2_EXIT_CRITICAL(); + +#ifdef CONFIG_IDF_TARGET_ESP32S2 + adc_rtc_reset(); +#endif + + if (adc_value < 0) { + ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." ); + return ESP_ERR_INVALID_STATE; + } + *raw_out = adc_value; return ESP_OK; } -esp_err_t adc2_vref_to_gpio(gpio_num_t gpio) -{ - adc_power_always_on(); //Select power source of ADC - if (adc_hal_vref_output(gpio) != true) { - return ESP_ERR_INVALID_ARG; - } else { - //Configure RTC gpio - rtc_gpio_init(gpio); - rtc_gpio_set_direction(gpio, RTC_GPIO_MODE_DISABLED); - rtc_gpio_pullup_dis(gpio); - rtc_gpio_pulldown_dis(gpio); - return ESP_OK; - } -} - -/*--------------------------------------------------------------- - HALL SENSOR ----------------------------------------------------------------*/ - -static int hall_sensor_get_value(void) //hall sensor without LNA -{ - int hall_value; - - adc_power_on(); - - ADC_ENTER_CRITICAL(); - /* disable other peripherals. */ - adc_hal_amp_disable(); - adc_hal_hall_enable(); - // set controller - adc_hal_set_controller( ADC_NUM_1, ADC_CTRL_RTC ); - hall_value = adc_hal_hall_convert(); - ADC_EXIT_CRITICAL(); - - return hall_value; -} - -int hall_sensor_read(void) -{ - adc_gpio_init(ADC_NUM_1, ADC1_CHANNEL_0); - adc_gpio_init(ADC_NUM_1, ADC1_CHANNEL_3); - adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0); - adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0); - return hall_sensor_get_value(); -} diff --git a/components/driver/component.mk b/components/driver/component.mk index 13ae795cf..8491f63d9 100644 --- a/components/driver/component.mk +++ b/components/driver/component.mk @@ -3,7 +3,7 @@ # COMPONENT_SRCDIRS := . $(IDF_TARGET) -COMPONENT_ADD_INCLUDEDIRS := include $(IDF_TARGET)/include +COMPONENT_ADD_INCLUDEDIRS := include $(IDF_TARGET)/include $(IDF_TARGET)/include/driver COMPONENT_PRIV_INCLUDEDIRS := include/driver diff --git a/components/driver/esp32/adc.c b/components/driver/esp32/adc.c new file mode 100644 index 000000000..19fb9031f --- /dev/null +++ b/components/driver/esp32/adc.c @@ -0,0 +1,181 @@ +// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include "esp_log.h" +#include "sys/lock.h" +#include "soc/rtc.h" +#include "soc/periph_defs.h" +#include "freertos/FreeRTOS.h" +#include "freertos/xtensa_api.h" +#include "freertos/semphr.h" +#include "freertos/timers.h" +#include "esp_intr_alloc.h" +#include "driver/rtc_io.h" +#include "driver/rtc_cntl.h" +#include "driver/gpio.h" +#include "driver/adc.h" +#include "sdkconfig.h" + +#include "esp32/rom/ets_sys.h" + +#ifndef NDEBUG +// Enable built-in checks in queue.h in debug builds +#define INVARIANTS +#endif +#include "sys/queue.h" +#include "hal/adc_types.h" +#include "hal/adc_hal.h" + +#define ADC_MAX_MEAS_NUM_DEFAULT (255) +#define ADC_MEAS_NUM_LIM_DEFAULT (1) +#define SAR_ADC_CLK_DIV_DEFUALT (2) + +#define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT) +#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11) +#define DIG_ADC_BIT_WIDTH_DEFUALT (ADC_WIDTH_BIT_12) + +#define ADC_CHECK_RET(fun_ret) ({ \ + if (fun_ret != ESP_OK) { \ + ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \ + return ESP_FAIL; \ + } \ +}) + +static const char *ADC_TAG = "ADC"; + +#define ADC_CHECK(a, str, ret_val) ({ \ + if (!(a)) { \ + ESP_LOGE(ADC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ + return (ret_val); \ + } \ +}) + +#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) + +#define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG) + +extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. +#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) +#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) +{ + ADC_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG); + ADC_ENTER_CRITICAL(); + adc_hal_digi_set_data_source(src); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) +{ + if (adc_unit & ADC_UNIT_1) { + ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_1)), "ADC1 not support DMA for now.", ESP_ERR_INVALID_ARG); + ADC_CHANNEL_CHECK(ADC_NUM_1, channel); + } + if (adc_unit & ADC_UNIT_2) { + ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_2)), "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG); + ADC_CHANNEL_CHECK(ADC_NUM_2, channel); + } + + adc_hal_digi_pattern_table_t adc1_pattern[1]; + adc_hal_digi_pattern_table_t adc2_pattern[1]; + adc_hal_digi_config_t dig_cfg = { + .conv_limit_en = ADC_MEAS_NUM_LIM_DEFAULT, + .conv_limit_num = ADC_MAX_MEAS_NUM_DEFAULT, + .clk_div = SAR_ADC_CLK_DIV_DEFUALT, + .format = DIG_ADC_OUTPUT_FORMAT_DEFUALT, + .conv_mode = (adc_hal_digi_convert_mode_t)adc_unit, + }; + + if (adc_unit & ADC_UNIT_1) { + adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT; + adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT; + adc1_pattern[0].channel = channel; + dig_cfg.adc1_pattern_len = 1; + dig_cfg.adc1_pattern = adc1_pattern; + } + if (adc_unit & ADC_UNIT_2) { + adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT; + adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT; + adc2_pattern[0].channel = channel; + dig_cfg.adc2_pattern_len = 1; + dig_cfg.adc2_pattern = adc2_pattern; + } + + ADC_ENTER_CRITICAL(); + adc_hal_digi_init(); + adc_hal_digi_controller_config(&dig_cfg); + ADC_EXIT_CRITICAL(); + + return ESP_OK; +} + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ + +esp_err_t adc2_vref_to_gpio(gpio_num_t gpio) +{ + ADC_ENTER_CRITICAL(); + adc_hal_set_power_manage(ADC_POWER_SW_ON); + ADC_EXIT_CRITICAL(); + if (adc_hal_vref_output(gpio) != true) { + return ESP_ERR_INVALID_ARG; + } + //Configure RTC gpio + rtc_gpio_init(gpio); + rtc_gpio_set_direction(gpio, RTC_GPIO_MODE_DISABLED); + rtc_gpio_pullup_dis(gpio); + rtc_gpio_pulldown_dis(gpio); + return ESP_OK; +} + +/*--------------------------------------------------------------- + HALL SENSOR +---------------------------------------------------------------*/ + +static int hall_sensor_get_value(void) //hall sensor without LNA +{ + int hall_value; + + adc_power_on(); + + ADC_ENTER_CRITICAL(); + /* disable other peripherals. */ + adc_hal_amp_disable(); + adc_hal_hall_enable(); + // set controller + adc_hal_set_controller( ADC_NUM_1, ADC_CTRL_RTC ); + hall_value = adc_hal_hall_convert(); + ADC_EXIT_CRITICAL(); + + return hall_value; +} + +int hall_sensor_read(void) +{ + adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_0); + adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_3); + adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0); + return hall_sensor_get_value(); +} \ No newline at end of file diff --git a/components/driver/esp32/include/driver/adc.h b/components/driver/esp32/include/driver/adc.h new file mode 100644 index 000000000..4f07a6b51 --- /dev/null +++ b/components/driver/esp32/include/driver/adc.h @@ -0,0 +1,88 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "driver/adc_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +/** + * @brief Set I2S data source + * @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC. + * @return + * - ESP_OK success + */ +esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src); + +/** + * @brief Initialize I2S ADC mode + * @param adc_unit ADC unit index + * @param channel ADC channel index + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel); + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ + +/** + * @brief Output ADC2 reference voltage to GPIO 25 or 26 or 27 + * + * This function utilizes the testing mux exclusive to ADC 2 to route the + * reference voltage one of ADC2's channels. Supported GPIOs are GPIOs + * 25, 26, and 27. This refernce voltage can be manually read from the pin + * and used in the esp_adc_cal component. + * + * @param[in] gpio GPIO number (GPIOs 25, 26 and 27 are supported) + * + * @return + * - ESP_OK: v_ref successfully routed to selected GPIO + * - ESP_ERR_INVALID_ARG: Unsupported GPIO + */ +esp_err_t adc2_vref_to_gpio(gpio_num_t gpio); + +/** + * @brief Read Hall Sensor + * + * @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, + * the input of GPIO36 and GPIO39 will be pulled down for about 80ns. + * When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39. + * Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue. + * + * @note The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure + * these channels for use as ADC channels. + * + * @note The ADC1 module must be enabled by calling + * adc1_config_width() before calling hall_sensor_read(). ADC1 + * should be configured for 12 bit readings, as the hall sensor + * readings are low values and do not cover the full range of the + * ADC. + * + * @return The hall sensor reading. + */ +int hall_sensor_read(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/driver/esp32/include/touch_sensor.h b/components/driver/esp32/include/driver/touch_sensor.h similarity index 100% rename from components/driver/esp32/include/touch_sensor.h rename to components/driver/esp32/include/driver/touch_sensor.h diff --git a/components/driver/esp32s2/adc.c b/components/driver/esp32s2/adc.c new file mode 100644 index 000000000..35bbb84f0 --- /dev/null +++ b/components/driver/esp32s2/adc.c @@ -0,0 +1,380 @@ +// Copyright 2016-2018 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include "esp_log.h" +#include "sys/lock.h" +#include "freertos/FreeRTOS.h" +#include "freertos/xtensa_api.h" +#include "freertos/semphr.h" +#include "freertos/timers.h" +#include "esp_intr_alloc.h" +#include "driver/periph_ctrl.h" +#include "driver/rtc_io.h" +#include "driver/rtc_cntl.h" +#include "driver/gpio.h" +#include "driver/adc.h" +#include "sdkconfig.h" + +#include "esp32s2/rom/ets_sys.h" +#include "hal/adc_types.h" +#include "hal/adc_hal.h" + +#define ADC_CHECK_RET(fun_ret) ({ \ + if (fun_ret != ESP_OK) { \ + ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \ + return ESP_FAIL; \ + } \ +}) + +static const char *ADC_TAG = "ADC"; + +#define ADC_CHECK(a, str, ret_val) ({ \ + if (!(a)) { \ + ESP_LOGE(ADC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ + return (ret_val); \ + } \ +}) + +#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) + +#define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG) + +extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. +#define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) +#define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ +esp_err_t adc_digi_init(void) +{ + adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); + ADC_ENTER_CRITICAL(); + adc_hal_digi_init(); + adc_hal_arbiter_config(&config); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_deinit(void) +{ + ADC_ENTER_CRITICAL(); + adc_hal_digi_init(); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_controller_config(const adc_digi_config_t *config) +{ + ADC_ENTER_CRITICAL(); + adc_hal_digi_controller_config(config); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config) +{ + if (adc_unit & ADC_UNIT_1) { + return ESP_ERR_NOT_SUPPORTED; + } + ADC_ENTER_CRITICAL(); + adc_hal_arbiter_config(config); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +/** + * @brief Set ADC module controller. + * There are five SAR ADC controllers: + * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes; + * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep; + * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2. + * + * @note Only ADC2 support arbiter to switch controllers automatically. Access to the ADC is based on the priority of the controller. + * @note For ADC1, Controller access is mutually exclusive. + * + * @param adc_unit ADC unit. + * @param ctrl ADC controller, Refer to `adc_controller_t`. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl) +{ + adc_arbiter_t config = {0}; + adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT(); + + if (adc_unit & ADC_UNIT_1) { + adc_hal_set_controller(ADC_NUM_1, ctrl); + } + if (adc_unit & ADC_UNIT_2) { + adc_hal_set_controller(ADC_NUM_2, ctrl); + switch (ctrl) { + case ADC2_CTRL_FORCE_PWDET: + config.pwdet_pri = 2; + config.mode = ADC_ARB_MODE_SHIELD; + adc_hal_arbiter_config(&config); + adc_hal_set_controller(ADC_NUM_2, ADC2_CTRL_PWDET); + break; + case ADC2_CTRL_FORCE_RTC: + config.rtc_pri = 2; + config.mode = ADC_ARB_MODE_SHIELD; + adc_hal_arbiter_config(&config); + adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC); + break; + case ADC2_CTRL_FORCE_ULP: + config.rtc_pri = 2; + config.mode = ADC_ARB_MODE_SHIELD; + adc_hal_arbiter_config(&config); + adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_ULP); + break; + case ADC2_CTRL_FORCE_DIG: + config.dig_pri = 2; + config.mode = ADC_ARB_MODE_SHIELD; + adc_hal_arbiter_config(&config); + adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_DIG); + break; + default: + adc_hal_arbiter_config(&cfg); + break; + } + } + return ESP_OK; +} + +esp_err_t adc_digi_start(void) +{ + ADC_ENTER_CRITICAL(); + adc_hal_digi_enable(); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_stop(void) +{ + ADC_ENTER_CRITICAL(); + adc_hal_digi_disable(); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +/** + * @brief Reset FSM of adc digital controller. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_reset(void) +{ + ADC_ENTER_CRITICAL(); + adc_hal_digi_reset(); + adc_hal_digi_clear_pattern_table(ADC_NUM_1); + adc_hal_digi_clear_pattern_table(ADC_NUM_2); + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +/*************************************/ +/* Digital controller filter setting */ +/*************************************/ + +esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx) +{ + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + adc_hal_digi_filter_reset(ADC_NUM_1); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + adc_hal_digi_filter_reset(ADC_NUM_2); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config) +{ + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + adc_hal_digi_filter_set_factor(ADC_NUM_1, config->mode); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + adc_hal_digi_filter_set_factor(ADC_NUM_2, config->mode); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config) +{ + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + config->adc_unit = ADC_UNIT_1; + config->channel = ADC_CHANNEL_MAX; + adc_hal_digi_filter_get_factor(ADC_NUM_1, &config->mode); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + config->adc_unit = ADC_UNIT_2; + config->channel = ADC_CHANNEL_MAX; + adc_hal_digi_filter_get_factor(ADC_NUM_2, &config->mode); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable) +{ + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + adc_hal_digi_filter_enable(ADC_NUM_1, enable); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + adc_hal_digi_filter_enable(ADC_NUM_2, enable); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +/** + * @brief Get the filtered data of adc digital controller filter. For debug. + * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API. + * + * @note For ESP32S2, The filter will filter all the enabled channel data of the each ADC unit at the same time. + * @param idx Filter index. + * @return Filtered data. if <0, the read data invalid. + */ +int adc_digi_filter_read_data(adc_digi_filter_idx_t idx) +{ + if (idx == ADC_DIGI_FILTER_IDX0) { + return adc_hal_digi_filter_read_data(ADC_NUM_1); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + return adc_hal_digi_filter_read_data(ADC_NUM_2); + } else { + return -1; + } +} + +/**************************************/ +/* Digital controller monitor setting */ +/**************************************/ + +esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config) +{ + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_MONITOR_IDX0) { + adc_hal_digi_monitor_config(ADC_NUM_1, config); + } else if (idx == ADC_DIGI_MONITOR_IDX1) { + adc_hal_digi_monitor_config(ADC_NUM_2, config); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable) +{ + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_MONITOR_IDX0) { + adc_hal_digi_monitor_enable(ADC_NUM_1, enable); + } else if (idx == ADC_DIGI_MONITOR_IDX1) { + adc_hal_digi_monitor_enable(ADC_NUM_2, enable); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +/**************************************/ +/* Digital controller intr setting */ +/**************************************/ + +esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask) +{ + ADC_ENTER_CRITICAL(); + if (adc_unit & ADC_UNIT_1) { + adc_hal_digi_intr_enable(ADC_NUM_1, intr_mask); + } + if (adc_unit & ADC_UNIT_2) { + adc_hal_digi_intr_enable(ADC_NUM_2, intr_mask); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask) +{ + ADC_ENTER_CRITICAL(); + if (adc_unit & ADC_UNIT_1) { + adc_hal_digi_intr_disable(ADC_NUM_1, intr_mask); + } + if (adc_unit & ADC_UNIT_2) { + adc_hal_digi_intr_disable(ADC_NUM_2, intr_mask); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask) +{ + ADC_ENTER_CRITICAL(); + if (adc_unit & ADC_UNIT_1) { + adc_hal_digi_intr_clear(ADC_NUM_1, intr_mask); + } + if (adc_unit & ADC_UNIT_2) { + adc_hal_digi_intr_clear(ADC_NUM_2, intr_mask); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; +} + +uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit) +{ + uint32_t ret = 0; + ADC_ENTER_CRITICAL(); + if (adc_unit & ADC_UNIT_1) { + ret = adc_hal_digi_get_intr_status(ADC_NUM_1); + } + if (adc_unit & ADC_UNIT_2) { + ret = adc_hal_digi_get_intr_status(ADC_NUM_2); + } + ADC_EXIT_CRITICAL(); + return ret; +} + +static uint8_t s_isr_registered = 0; +static intr_handle_t s_adc_isr_handle = NULL; + +esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags) +{ + ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG); + ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL); + + esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle); + if (ret == ESP_OK) { + s_isr_registered = 1; + } + return ret; +} + +esp_err_t adc_digi_isr_deregister(void) +{ + esp_err_t ret = ESP_FAIL; + if (s_isr_registered) { + ret = esp_intr_free(s_adc_isr_handle); + if (ret == ESP_OK) { + s_isr_registered = 0; + } + } + return ret; +} + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ diff --git a/components/driver/esp32s2/include/driver/adc.h b/components/driver/esp32s2/include/driver/adc.h new file mode 100644 index 000000000..65bda25c2 --- /dev/null +++ b/components/driver/esp32s2/include/driver/adc.h @@ -0,0 +1,277 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "driver/adc_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ + +/** + * @brief Config ADC module arbiter. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. + * + * @note Only ADC2 support arbiter. + * @note Default priority: Wi-Fi > RTC > Digital; + * @note In normal use, there is no need to call this interface to config arbiter. + * + * @param adc_unit ADC unit. + * @param config Refer to `adc_arbiter_t`. + * + * @return + * - ESP_OK Success + * - ESP_ERR_NOT_SUPPORTED ADC unit not support arbiter. + */ +esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config); + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ +/** + * @brief ADC digital controller initialization. + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_init(void); + +/** + * @brief ADC digital controller deinitialization. + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_deinit(void); + +/** + * @brief Setting the digital controller. + * + * @param config Pointer to digital controller paramter. Refer to `adc_digi_config_t`. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_controller_config(const adc_digi_config_t *config); + +/** + * @brief Enable digital controller to trigger the measurement. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_start(void); + +/** + * @brief Disable digital controller to trigger the measurement. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_stop(void); + +/*************************************/ +/* Digital controller filter setting */ +/*************************************/ +/** + * @brief Reset adc digital controller filter. + * + * @param idx Filter index. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx); + +/** + * @brief Set adc digital controller filter configuration. + * + * @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. + * + * @param idx Filter index. + * @param config See ``adc_digi_filter_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config); + +/** + * @brief Get adc digital controller filter configuration. + * + * @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. + * + * @param idx Filter index. + * @param config See ``adc_digi_filter_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config); + +/** + * @brief Enable/disable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @note For ESP32S2, Filter IDX0/IDX1 can only be used to filter all enabled channels of ADC1/ADC2 unit at the same time. + * + * @param idx Filter index. + * @param enable Enable/Disable filter. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable); + +/**************************************/ +/* Digital controller monitor setting */ +/**************************************/ + +/** + * @brief Config monitor of adc digital controller. + * + * @note For ESP32S2, The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * + * @param idx Monitor index. + * @param config See ``adc_digi_monitor_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config); + +/** + * @brief Enable/disable monitor of adc digital controller. + * + * @note For ESP32S2, The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * + * @param idx Monitor index. + * @param enable True or false enable monitor. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable); + +/**************************************/ +/* Digital controller intr setting */ +/**************************************/ + +/** + * @brief Enable interrupt of adc digital controller by bitmask. + * + * @param adc_unit ADC unit. + * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); + +/** + * @brief Disable interrupt of adc digital controller by bitmask. + * + * @param adc_unit ADC unit. + * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); + +/** + * @brief Clear interrupt of adc digital controller by bitmask. + * + * @param adc_unit ADC unit. + * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. + * + * @return + * - ESP_OK Success + */ +esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); + +/** + * @brief Get interrupt status mask of adc digital controller. + * + * @param adc_unit ADC unit. + * @return + * - intr Interrupt bitmask, See ``adc_digi_intr_t``. + */ +uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit); + +/** + * @brief Register ADC interrupt handler, the handler is an ISR. + * The handler will be attached to the same CPU core that this function is running on. + * + * @param fn Interrupt handler function. + * @param arg Parameter for handler function + * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) + * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. + * + * @return + * - ESP_OK Success + * - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags. + * - ESP_ERR_INVALID_ARG Function pointer error. + */ +esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags); + +/** + * @brief Deregister ADC interrupt handler, the handler is an ISR. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG hander error. + * - ESP_FAIL ISR not be registered. + */ +esp_err_t adc_digi_isr_deregister(void); + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ + +/*--------------------------------------------------------------- + Deprecated API +---------------------------------------------------------------*/ +/** + * @brief Set I2S data source + * + * @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC. + * + * @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_controller_config`` instead. + * + * @return + * - ESP_OK success + */ +esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) __attribute__((deprecated)); + +/** + * @brief Initialize I2S ADC mode + * + * @param adc_unit ADC unit index + * @param channel ADC channel index + * + * @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_controller_config`` instead. + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) __attribute__((deprecated)); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/driver/esp32s2/include/temp_sensor.h b/components/driver/esp32s2/include/driver/temp_sensor.h similarity index 95% rename from components/driver/esp32s2/include/temp_sensor.h rename to components/driver/esp32s2/include/driver/temp_sensor.h index 09d2a6c5f..56907b236 100644 --- a/components/driver/esp32s2/include/temp_sensor.h +++ b/components/driver/esp32s2/include/driver/temp_sensor.h @@ -21,6 +21,9 @@ extern "C" { #endif +/** + * @brief temperature sensor range option. + */ typedef enum { TSENS_DAC_L0 = 0, /*!< offset = -2, measure range: 50℃ ~ 125℃, error < 3℃. */ TSENS_DAC_L1, /*!< offset = -1, measure range: 20℃ ~ 100℃, error < 2℃. */ @@ -39,6 +42,9 @@ typedef struct { uint8_t clk_div; /*!< Default: 6 */ } temp_sensor_config_t; +/** + * @brief temperature sensor default setting. + */ #define TSENS_CONFIG_DEFAULT() {.dac_offset = TSENS_DAC_L2, \ .clk_div = 6} @@ -74,7 +80,7 @@ esp_err_t temp_sensor_start(void); esp_err_t temp_sensor_stop(void); /** - * @brief Read temperature sensor raw data. + * @brief Read temperature sensor raw data. * @param tsens_out Pointer to raw data, Range: 0 ~ 255 * @return * - ESP_OK Success diff --git a/components/driver/esp32s2/include/touch_sensor.h b/components/driver/esp32s2/include/driver/touch_sensor.h similarity index 99% rename from components/driver/esp32s2/include/touch_sensor.h rename to components/driver/esp32s2/include/driver/touch_sensor.h index 16140b520..999235c14 100644 --- a/components/driver/esp32s2/include/touch_sensor.h +++ b/components/driver/esp32s2/include/driver/touch_sensor.h @@ -233,7 +233,7 @@ esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg, touch_pad_intr_ma * * @param enable true(default): Enable the timeout check; false: Disable the timeout check. * @param threshold For all channels, the maximum value that will not be exceeded during normal operation. - * + * * @return * - ESP_OK Success */ @@ -244,7 +244,7 @@ esp_err_t touch_pad_timeout_set(bool enable, uint32_t threshold); * If this API is not called, the touch FSM will stop the measurement after timeout interrupt. * * @note Call this API after finishes the exception handling by user. - * + * * @return * - ESP_OK Success */ @@ -491,7 +491,7 @@ esp_err_t touch_pad_sleep_channel_get_info(touch_pad_sleep_channel_t *slp_config * e.g. The user should uses `touch_pad_sleep_channel_read_data` instead of `touch_pad_read_raw_data` to obtain the sleep channel reading. * * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. - * @param enable true: enable sleep pad for touch sensor; false: disable sleep pad for touch sensor; + * @param enable true: enable sleep pad for touch sensor; false: disable sleep pad for touch sensor; * @return * - ESP_OK Success */ @@ -502,9 +502,9 @@ esp_err_t touch_pad_sleep_channel_enable(touch_pad_t pad_num, bool enable); * The touch sensor can works in sleep mode to wake up sleep. * * @note ESP32S2 only support one sleep channel. - * + * * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. - * @param enable true: enable proximity for sleep channel; false: disable proximity for sleep channel; + * @param enable true: enable proximity for sleep channel; false: disable proximity for sleep channel; * @return * - ESP_OK Success */ @@ -515,7 +515,7 @@ esp_err_t touch_pad_sleep_channel_enable_proximity(touch_pad_t pad_num, bool ena * The threshold determines the sensitivity of the touch sensor. * * @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep. - * + * * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. * @param touch_thres touch sleep pad threshold * @return @@ -528,7 +528,7 @@ esp_err_t touch_pad_sleep_set_threshold(touch_pad_t pad_num, uint32_t touch_thre * The threshold determines the sensitivity of the touch sensor. * * @note In general, the touch threshold during sleep can use the threshold parameter parameters before sleep. - * + * * @param pad_num Set touch channel number for sleep pad. Only one touch sensor channel is supported in deep sleep mode. * @param touch_thres touch sleep pad threshold * @return diff --git a/components/driver/esp32s2/rtc_tempsensor.c b/components/driver/esp32s2/rtc_tempsensor.c index da5863b24..cb92253d9 100644 --- a/components/driver/esp32s2/rtc_tempsensor.c +++ b/components/driver/esp32s2/rtc_tempsensor.c @@ -18,11 +18,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "esp_log.h" +#include "soc/rtc_cntl_reg.h" #include "soc/rtc_io_reg.h" #include "soc/rtc_io_struct.h" #include "soc/sens_reg.h" #include "soc/sens_struct.h" -#include "temp_sensor.h" +#include "driver/temp_sensor.h" #include "esp32s2/rom/ets_sys.h" static const char *TAG = "tsens"; @@ -38,6 +39,18 @@ static const char *TAG = "tsens"; #define TSENS_DAC_FACTOR (27.88) #define TSENS_SYS_OFFSET (20.52) +#include "i2c_rtc_clk.h" + +#define ANA_CONFIG2_REG 0x6000E048 +#define ANA_CONFIG2_M (BIT(18)) + +#define I2C_ADC 0X69 +#define I2C_ADC_HOSTID 1 + +#define I2C_SARADC_TSENS_DAC 6 +#define I2C_SARADC_TSENS_DAC_MSB 3 +#define I2C_SARADC_TSENS_DAC_LSB 0 + typedef struct { int index; int offset; @@ -60,7 +73,11 @@ static SemaphoreHandle_t rtc_tsens_mux = NULL; esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens) { - // SENS.sar_tctrl.tsens_dac = dac_offset[tsens.dac_offset].set_val; // TODO: others MR resolve it. + CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); + SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18)); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16)); + I2C_WRITEREG_MASK_RTC(I2C_ADC, I2C_SARADC_TSENS_DAC, dac_offset[tsens.dac_offset].set_val); SENS.sar_tctrl.tsens_clk_div = tsens.clk_div; SENS.sar_tctrl.tsens_power_up_force = 1; SENS.sar_tctrl2.tsens_xpd_wait = TSENS_XPD_WAIT_DEFAULT; @@ -77,9 +94,13 @@ esp_err_t temp_sensor_set_config(temp_sensor_config_t tsens) esp_err_t temp_sensor_get_config(temp_sensor_config_t *tsens) { TSENS_CHECK(tsens != NULL, ESP_ERR_INVALID_ARG); - // tsens->dac_offset = SENS.sar_tctrl.tsens_dac; // TODO: others MR resolve it. - for(int i=TSENS_DAC_L0; idac_offset == dac_offset[i].set_val) { + CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); + SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18)); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16)); + tsens->dac_offset = I2C_READREG_MASK_RTC(I2C_ADC, I2C_SARADC_TSENS_DAC); + for (int i = TSENS_DAC_L0; i < TSENS_DAC_MAX; i++) { + if (tsens->dac_offset == dac_offset[i].set_val) { tsens->dac_offset = dac_offset[i].index; break; } diff --git a/components/driver/i2s.c b/components/driver/i2s.c index ed5bd1147..bde7e3c2a 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -28,7 +28,7 @@ #if SOC_I2S_SUPPORTS_ADC_DAC #include "driver/dac.h" #include "hal/i2s_hal.h" -#include "adc1_i2s_private.h" +#include "adc1_private.h" #endif #include "esp_intr_alloc.h" @@ -1061,7 +1061,7 @@ esp_err_t i2s_adc_enable(i2s_port_t i2s_num) I2S_CHECK((p_i2s_obj[i2s_num] != NULL), "Not initialized yet", ESP_ERR_INVALID_STATE); I2S_CHECK((p_i2s_obj[i2s_num]->mode & I2S_MODE_ADC_BUILT_IN), "i2s built-in adc not enabled", ESP_ERR_INVALID_STATE); - adc1_i2s_mode_acquire(); + adc1_dma_mode_acquire(); _i2s_adc_mode_recover(); i2s_hal_start_rx(&(p_i2s_obj[i2s_num]->hal)); i2s_hal_reset(&(p_i2s_obj[i2s_num]->hal)); diff --git a/components/driver/include/driver/adc.h b/components/driver/include/driver/adc_common.h similarity index 59% rename from components/driver/include/driver/adc.h rename to components/driver/include/driver/adc_common.h index f3ad9d1d6..25dc7055b 100644 --- a/components/driver/include/driver/adc.h +++ b/components/driver/include/driver/adc_common.h @@ -12,30 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef _DRIVER_ADC_H_ -#define _DRIVER_ADC_H_ - -#ifdef __cplusplus -extern "C" { -#endif +#pragma once #include #include #include "esp_err.h" #include "driver/gpio.h" -#include "soc/adc_periph.h" #include "hal/adc_types.h" -//this definitions are only for being back-compatible -#define ADC_ATTEN_0db ADC_ATTEN_DB_0 -#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5 -#define ADC_ATTEN_6db ADC_ATTEN_DB_6 -#define ADC_ATTEN_11db ADC_ATTEN_DB_11 -//this definitions are only for being back-compatible -#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9 -#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10 -#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11 -#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12 +#ifdef __cplusplus +extern "C" { +#endif /**** `adc1_channel_t` will be deprecated functions, combine into `adc_channel_t` ********/ typedef enum { @@ -71,17 +58,29 @@ typedef enum { ADC2_CHANNEL_MAX, } adc2_channel_t; -typedef enum { - ADC_UNIT_1 = 1, /*!< SAR ADC 1*/ - ADC_UNIT_2 = 2, /*!< SAR ADC 2, not supported yet*/ - ADC_UNIT_BOTH = 3, /*!< SAR ADC 1 and 2, not supported yet */ - ADC_UNIT_ALTER = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */ - ADC_UNIT_MAX, -} adc_unit_t; +/** + * @brief ADC rtc controller attenuation option. + * + * @note This definitions are only for being back-compatible + */ +#define ADC_ATTEN_0db ADC_ATTEN_DB_0 +#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5 +#define ADC_ATTEN_6db ADC_ATTEN_DB_6 +#define ADC_ATTEN_11db ADC_ATTEN_DB_11 +//this definitions are only for being back-compatible +#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9 +#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10 +#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11 +#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12 +/** + * @brief ADC digital controller encode option. + * + * @deprecated The ESP32S2 don't use I2S DMA. Call ``adc_digi_output_format_t`` instead. + */ typedef enum { - ADC_ENCODE_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data */ - ADC_ENCODE_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data */ + ADC_ENCODE_12BIT, /*!< ADC to DMA data format, , [15:12]-channel [11:0]-12 bits ADC data */ + ADC_ENCODE_11BIT, /*!< ADC to DMA data format, [15]-unit, [14:11]-channel [10:0]-11 bits ADC data */ ADC_ENCODE_MAX, } adc_i2s_encode_t; @@ -89,7 +88,6 @@ typedef enum { * @brief Get the GPIO number of a specific ADC1 channel. * * @param channel Channel to get the GPIO number - * * @param gpio_num output buffer to hold the GPIO number * * @return @@ -99,60 +97,38 @@ typedef enum { esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num); /** - * @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1. - * The configuration is for all channels of ADC1 - * @param width_bit Bit capture width for ADC1 + * @brief Set the attenuation of a particular channel on ADC1, and configure its associated GPIO pin mux. * - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc1_config_width(adc_bits_width_t width_bit); - -/** - * @brief Configure ADC capture width. - * @param adc_unit ADC unit index - * @param width_bit Bit capture width for ADC unit. - * @return - * - ESP_OK success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit); - -/** - * @brief Set the attenuation of a particular channel on ADC1, and configure its - * associated GPIO pin mux. + * The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage, + * usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel. * - * @note For any given channel, this function must be called before the first time - * adc1_get_raw() is called for that channel. + * When VDD_A is 3.3 V: * - * @note This function can be called multiple times to configure multiple - * ADC channels simultaneously. adc1_get_raw() can then be called for any configured - * channel. + * - 0 dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1 V + * - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5 V + * - 6 dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2 V + * - 11 dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9 V (see note below) * - * The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage, - * usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel. - * - * When VDD_A is 3.3 V: - * - * - 0 dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1 V - * - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5 V - * - 6 dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2 V - * - 11 dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9 V (see note below) - * - * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured - * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) + * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured bit width, + * this value in ESP32 is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits. + * this value in ESP32S2 is: 8191 for 13-bits.) * * @note At 11 dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. * - * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: + * @note For ESP32: + * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: * - * - 0 dB attenuation (ADC_ATTEN_DB_0) between 100 and 950 mV - * - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250 mV - * - 6 dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750 mV - * - 11 dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450 mV + * - 0 dB attenuation (ADC_ATTEN_DB_0) between 100 and 950 mV + * - 2.5 dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250 mV + * - 6 dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750 mV + * - 11 dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450 mV * - * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. + * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. + * + * @note For any given channel, this function must be called before the first time ``adc1_get_raw()`` is called for that channel. + * + * @note This function can be called multiple times to configure multiple + * ADC channels simultaneously. ``adc1_get_raw()`` can then be called for any configured channel. * * @param channel ADC1 channel to configure * @param atten Attenuation level @@ -163,19 +139,31 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit); */ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten); +/** + * @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1. + * The configuration is for all channels of ADC1 + * @param width_bit Bit capture width for ADC1 + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t adc1_config_width(adc_bits_width_t width_bit); + /** * @brief Take an ADC1 reading from a single channel. - * @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, + * @note ESP32: + * When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, * the input of GPIO36 and GPIO39 will be pulled down for about 80ns. * When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39. * Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue. * * @note Call adc1_config_width() before the first time this - * function is called. + * function is called. * * @note For any given channel, adc1_config_channel_atten(channel) - * must be called before the first time this function is called. Configuring - * a new channel does not prevent a previously configured channel from being read. + * must be called before the first time this function is called. Configuring + * a new channel does not prevent a previously configured channel from being read. * * @param channel ADC1 channel to read * @@ -225,22 +213,18 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en); esp_err_t adc_set_clk_div(uint8_t clk_div); /** - * @brief Set I2S data source - * @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC. - * @return - * - ESP_OK success - */ -esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src); - -/** - * @brief Initialize I2S ADC mode + * @brief Configure ADC capture width. + * + * @note For ESP32S2, only support ``ADC_WIDTH_BIT_13``. + * * @param adc_unit ADC unit index - * @param channel ADC channel index + * @param width_bit Bit capture width for ADC unit. For ESP32S2, only support ``ADC_WIDTH_BIT_13``. + * * @return * - ESP_OK success * - ESP_ERR_INVALID_ARG Parameter error */ -esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel); +esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit); /** * @brief Configure ADC1 to be usable by the ULP @@ -253,27 +237,6 @@ esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel); */ void adc1_ulp_enable(void); -/** - * @brief Read Hall Sensor - * - * @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, - * the input of GPIO36 and GPIO39 will be pulled down for about 80ns. - * When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39. - * Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue. - * - * @note The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure - * these channels for use as ADC channels. - * - * @note The ADC1 module must be enabled by calling - * adc1_config_width() before calling hall_sensor_read(). ADC1 - * should be configured for 12 bit readings, as the hall sensor - * readings are low values and do not cover the full range of the - * ADC. - * - * @return The hall sensor reading. - */ -int hall_sensor_read(void); - /** * @brief Get the GPIO number of a specific ADC2 channel. * @@ -290,23 +253,24 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num); /** * @brief Configure the ADC2 channel, including setting attenuation. * + * The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage, + * usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel. + * + * When VDD_A is 3.3 V: + * + * - 0 dB attenuation (ADC_ATTEN_0db) gives full-scale voltage 1.1 V + * - 2.5 dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5 V + * - 6 dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2 V + * - 11 dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9 V (see note below) + * * @note This function also configures the input GPIO pin mux to - * connect it to the ADC2 channel. It must be called before calling - * ``adc2_get_raw()`` for this channel. - * - * The default ADC full-scale voltage is 1.1 V. To read higher voltages (up to the pin maximum voltage, - * usually 3.3 V) requires setting >0 dB signal attenuation for that ADC channel. - * - * When VDD_A is 3.3 V: - * - * - 0 dB attenuation (ADC_ATTEN_0db) gives full-scale voltage 1.1 V - * - 2.5 dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5 V - * - 6 dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2 V - * - 11 dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9 V (see note below) + * connect it to the ADC2 channel. It must be called before calling + * ``adc2_get_raw()`` for this channel. * * @note The full-scale voltage is the voltage corresponding to a maximum reading - * (depending on ADC2 configured bit width, this value is: 4095 for 12-bits, 2047 - * for 11-bits, 1023 for 10-bits, 511 for 9 bits.) + * (depending on ADC2 configured bit width, + * this value of ESP32 is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits. + * this value of ESP32S2 is: 8191 for 13-bits.) * * @note At 11 dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. * @@ -322,46 +286,32 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten); /** * @brief Take an ADC2 reading on a single channel * - * @note When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, + * @note ESP32: + * When the power switch of SARADC1, SARADC2, HALL sensor and AMP sensor is turned on, * the input of GPIO36 and GPIO39 will be pulled down for about 80ns. * When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39. * Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue. * - * @note For a given channel, ``adc2_config_channel_atten()`` - * must be called before the first time this function is called. If Wi-Fi is started via ``esp_wifi_start()``, this - * function will always fail with ``ESP_ERR_TIMEOUT``. + * @note ESP32: + * For a given channel, ``adc2_config_channel_atten()`` + * must be called before the first time this function is called. If Wi-Fi is started via ``esp_wifi_start()``, this + * function will always fail with ``ESP_ERR_TIMEOUT``. * - * @param channel ADC2 channel to read - * - * @param width_bit Bit capture width for ADC2 + * @note ESP32S2: + * ADC2 support hardware arbiter. The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC2 data. Default priority: Wi-Fi > RTC > Digital; * + * @param channel ADC2 channel to read + * @param width_bit Bit capture width for ADC2. For ESP32S2, only support ``ADC_WIDTH_BIT_13``. * @param raw_out the variable to hold the output data. * * @return * - ESP_OK if success - * - ESP_ERR_TIMEOUT the WIFI is started, using the ADC2 + * - ESP_ERR_TIMEOUT ADC2 is being used by other controller and the request timed out. + * - ESP_ERR_INVALID_STATE The controller status is invalid. Please try again. */ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out); -/** - * @brief Output ADC2 reference voltage to GPIO 25 or 26 or 27 - * - * This function utilizes the testing mux exclusive to ADC 2 to route the - * reference voltage one of ADC2's channels. Supported GPIOs are GPIOs - * 25, 26, and 27. This refernce voltage can be manually read from the pin - * and used in the esp_adc_cal component. - * - * @param[in] gpio GPIO number (GPIOs 25, 26 and 27 are supported) - * - * @return - * - ESP_OK: v_ref successfully routed to selected GPIO - * - ESP_ERR_INVALID_ARG: Unsupported GPIO - */ -esp_err_t adc2_vref_to_gpio(gpio_num_t gpio); - #ifdef __cplusplus } #endif - -#endif /*_DRIVER_ADC_H_*/ - diff --git a/components/driver/include/driver/dac.h b/components/driver/include/driver/dac.h index 17d04f140..86699dd0a 100644 --- a/components/driver/include/driver/dac.h +++ b/components/driver/include/driver/dac.h @@ -24,7 +24,7 @@ extern "C" { #include "hal/dac_types.h" /** - * @brief Get the gpio number of a specific DAC channel. + * @brief Get the GPIO number of a specific DAC channel. * * @param channel Channel to get the gpio number * @param gpio_num output buffer to hold the gpio number diff --git a/components/driver/include/driver/touch_pad.h b/components/driver/include/driver/touch_pad.h index 8a065dcc6..1f427ff0b 100644 --- a/components/driver/include/driver/touch_pad.h +++ b/components/driver/include/driver/touch_pad.h @@ -14,4 +14,4 @@ #pragma once -#include "touch_sensor.h" \ No newline at end of file +#include "driver/touch_sensor.h" \ No newline at end of file diff --git a/components/driver/test/CMakeLists.txt b/components/driver/test/CMakeLists.txt index a0e2f5d14..f099b0b6b 100644 --- a/components/driver/test/CMakeLists.txt +++ b/components/driver/test/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRC_DIRS . param_test touch_sensor_test +idf_component_register(SRC_DIRS . param_test touch_sensor_test adc_dma_test dac_dma_test PRIV_INCLUDE_DIRS include param_test/include - PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools) + PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools) \ No newline at end of file diff --git a/components/driver/test/adc_dma_test/test_esp32.c b/components/driver/test/adc_dma_test/test_esp32.c new file mode 100644 index 000000000..7887f7522 --- /dev/null +++ b/components/driver/test/adc_dma_test/test_esp32.c @@ -0,0 +1,142 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + Tests for the adc device driver +*/ +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" + +#if !DISABLED_FOR_TARGETS(ESP8266, ESP32S2) // This testcase for ESP32 + +/* + * ADC DMA testcase + */ +#include "driver/i2s.h" + +//i2s number +#define EXAMPLE_I2S_NUM (0) +//i2s sample rate +#define EXAMPLE_I2S_SAMPLE_RATE (16000) +//i2s data bits +#define EXAMPLE_I2S_SAMPLE_BITS (16) +//enable display buffer for debug +#define EXAMPLE_I2S_BUF_DEBUG (0) +//I2S read buffer length +#define EXAMPLE_I2S_READ_LEN (16 * 1024) +//I2S data format +#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT) +//I2S channel number +#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1)) +//I2S built-in ADC unit +#define I2S_ADC_UNIT ADC_UNIT_1 +//I2S built-in ADC channel +//#define I2S_ADC_CHANNEL //adc1_ch[0] + +//flash record size, for recording 5 seconds' data +#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5) +#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE) +//sector size of flash +#define FLASH_SECTOR_SIZE (0x1000) + +#define ADC1_TEST_CHANNEL_NUM 3 +#define ADC2_TEST_CHANNEL_NUM 3 + +static const int adc1_ch[ADC1_TEST_CHANNEL_NUM] = { + ADC1_CHANNEL_2, + ADC1_CHANNEL_3, + ADC1_CHANNEL_4, +}; + +/** + * @brief I2S ADC/DAC mode init. + */ +static void example_i2s_init(void) +{ + int i2s_num = EXAMPLE_I2S_NUM; + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN, + .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, + .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, + .communication_format = I2S_COMM_FORMAT_PCM, + .channel_format = EXAMPLE_I2S_FORMAT, + .intr_alloc_flags = 0, + .dma_buf_count = 2, + .dma_buf_len = 1024, + .use_apll = 1, + }; + //install and start i2s driver + TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); + //init ADC pad + TEST_ESP_OK( i2s_set_adc_mode(I2S_ADC_UNIT, adc1_ch[0]) ); +} + +static void example_i2s_deinit(void) +{ + TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); +} + +/** + * @brief debug buffer data + */ +static void example_disp_buf(uint8_t *buf, int length) +{ + printf("======\n"); + for (int i = 0; i < length; i++) { + printf("%02x ", buf[i]); + if ((i + 1) % 8 == 0) { + printf("\n"); + } + } + printf("======\n"); +} + +TEST_CASE("ADC DMA read", "[adc dma]") +{ + example_i2s_init(); + + int i2s_read_len = EXAMPLE_I2S_READ_LEN; + int flash_wr_size = 0; + size_t bytes_read; + + char *i2s_read_buff = (char *) calloc(i2s_read_len, sizeof(char)); + TEST_ESP_OK( i2s_adc_enable(EXAMPLE_I2S_NUM) ); + while (flash_wr_size < FLASH_RECORD_SIZE) { + //read data from I2S bus, in this case, from ADC. + TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY) ); + example_disp_buf((uint8_t *) i2s_read_buff, 64); + //save original data from I2S(ADC) into flash. + flash_wr_size += i2s_read_len; + ets_printf("Sound recording %u%%\n", flash_wr_size * 100 / FLASH_RECORD_SIZE); + } + TEST_ESP_OK( i2s_adc_disable(EXAMPLE_I2S_NUM) ); + if (i2s_read_buff) { + free(i2s_read_buff); + i2s_read_buff = NULL; + } + + example_i2s_deinit(); +} + +#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32S2) \ No newline at end of file diff --git a/components/driver/test/adc_dma_test/test_esp32s2.c b/components/driver/test/adc_dma_test/test_esp32s2.c new file mode 100644 index 000000000..14787d819 --- /dev/null +++ b/components/driver/test/adc_dma_test/test_esp32s2.c @@ -0,0 +1,494 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + Tests for the adc device driver +*/ + +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" +#include "soc/spi_reg.h" +#include "soc/adc_periph.h" + +#if !DISABLED_FOR_TARGETS(ESP8266, ESP32) // This testcase for ESP32S2 + +#include "soc/system_reg.h" + +static const char *TAG = "test_adc"; + +#define PLATFORM_SELECT (1) //0: pxp; 1: chip +#if (PLATFORM_SELECT == 0) //PXP platform +#include "soc/apb_ctrl_reg.h" +#define SET_BREAK_POINT(flag) REG_WRITE(APB_CTRL_DATE_REG, flag) +//PXP clk is slower. +#define SYS_DELAY_TIME_MOM (1/40) +#define RTC_SLOW_CLK_FLAG 1 // Slow clock is 32KHz. +static void test_pxp_deinit_io(void) +{ + for (int i = 0; i < 22; i++) { + rtc_gpio_init(i); + } +} +#else +//PXP clk is slower. +#define SET_BREAK_POINT(flag) +#define SYS_DELAY_TIME_MOM (1) +#define RTC_SLOW_CLK_FLAG 0 // Slow clock is 32KHz. +#endif + +#define ADC_REG_BASE_TEST() ({ \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(APB_SARADC_APB_CTRL_DATE_REG, APB_SARADC_APB_CTRL_DATE), APB_SARADC.apb_ctrl_date); \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ + TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ +}) +#define TEST_ADC_TRIGGER_INTERVAL_DEFAULT (40) +#define TEST_ADC_COUNT_NUM (10) +#define TEST_ADC_CHANNEL (10) +static adc_channel_t adc_list[TEST_ADC_CHANNEL] = { + ADC_CHANNEL_0, + ADC_CHANNEL_1, + ADC_CHANNEL_2, + ADC_CHANNEL_3, + ADC_CHANNEL_4, + ADC_CHANNEL_5, + ADC_CHANNEL_6, + ADC_CHANNEL_7, + ADC_CHANNEL_8, + ADC_CHANNEL_9, +}; +/* For ESP32S2, it should use same atten, or, it will have error. */ +// #define TEST_ADC_ATTEN_DEFAULT (ADC_ATTEN_11db) +static adc_atten_t adc_atten[ADC_ATTEN_MAX] = { + ADC_ATTEN_DB_0, + ADC_ATTEN_DB_2_5, + ADC_ATTEN_DB_6, + ADC_ATTEN_DB_11 +}; +/*******************************************/ +/** SPI DMA INIT CODE */ +/*******************************************/ +extern esp_err_t adc_digi_reset(void); + +typedef struct dma_link { + struct { + uint32_t size : 12; //the size of buf, must be able to be divisible by 4 + uint32_t length: 12; //in link, + uint32_t reversed: 6; //reversed + uint32_t eof: 1; //if this dma link is the last one, you shoule set this bit 1. + uint32_t owner: 1; //the owner of buf, bit 1 : DMA, bit 0 : CPU. + } des; + uint8_t *buf; //the pointer of buf + struct dma_link *pnext; //point to the next dma linker, if this link is the last one, set it NULL. +} dma_link_t; +/* Work mode. + * sigle: eof_num; + * double: SAR_EOF_NUMBER/2; + * alter: eof_num; + * */ +#define SAR_SIMPLE_NUM 64 +#define SAR_DMA_DATA_SIZE(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num) * 2) // 1 adc -> 2 byte +#define SAR_EOF_NUMBER(unit, sample_num) ((sample_num) * (unit)) +#define SAR_MEAS_LIMIT_NUM(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num) / unit) + +static uint8_t link_buf[2][SAR_DMA_DATA_SIZE(2, SAR_SIMPLE_NUM)] = {0}; +static dma_link_t dma1; +static dma_link_t dma2; + +static void dma_linker_init(adc_unit_t adc, bool is_loop) +{ + dma1.des.eof = 0; + dma1.des.owner = 1; + dma1.pnext = &dma2; + dma1.des.size = SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); + dma1.des.length = 0; //For input buffer, this field is no use. + dma1.buf = &link_buf[0][0]; + + dma2.des.eof = 1; + dma2.des.owner = 1; + if (is_loop) { + dma2.pnext = &dma1; + } else { + dma2.pnext = NULL; + } + dma2.des.size = SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); + dma2.des.length = 0; //For input buffer, this field is no use. + dma2.buf = &link_buf[1][0]; + + REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_APB_SARADC_CLK_EN_M); + REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_DMA_CLK_EN_M); + REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN); + REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_DMA_RST_M); + REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST_M); + uint32_t dma_pointer = (uint32_t)&dma1; + SET_PERI_REG_BITS(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_ADDR, dma_pointer, 0); + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); + REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); + REG_SET_BIT(SPI_DMA_INT_ENA_REG(3), SPI_IN_SUC_EOF_INT_ENA); + printf("reg addr 0x%08x 0x%08x \n", SPI_DMA_IN_LINK_REG(3), dma_pointer); +} + +static void dma_linker_restart(void) +{ + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); + REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_RESTART_M); + REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_RESTART_M); + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); + REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); + adc_digi_reset(); +} + +/*******************************************/ +/** SPI DMA INIT CODE END */ +/*******************************************/ + +/** + * TEST TOOLS + * Note: internal pullup/pulldown is weak energy. if enabled WiFi, it should be need outside pullup/pulldown. + */ +#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) + +static void adc_fake_tie_middle(adc_unit_t adc) +{ + if (adc & ADC_UNIT_1) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_1, adc_list[i]); + TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(0, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(0, adc_list[i]))); + } + } + if (adc & ADC_UNIT_2) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_2, adc_list[i]); + TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(1, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(1, adc_list[i]))); + } + } + vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. +} + +static void adc_fake_tie_high(adc_unit_t adc) +{ + if (adc & ADC_UNIT_1) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_1, adc_list[i]); + TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(0, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_pulldown_dis(ADC_GET_IO_NUM(0, adc_list[i]))); + } + } + if (adc & ADC_UNIT_2) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_2, adc_list[i]); + TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(1, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_pulldown_dis(ADC_GET_IO_NUM(1, adc_list[i]))); + } + } + vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. +} + +static void adc_fake_tie_low(adc_unit_t adc) +{ + if (adc & ADC_UNIT_1) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_1, adc_list[i]); + TEST_ESP_OK(rtc_gpio_pullup_dis(ADC_GET_IO_NUM(0, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(0, adc_list[i]))); + } + } + if (adc & ADC_UNIT_2) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_2, adc_list[i]); + TEST_ESP_OK(rtc_gpio_pullup_dis(ADC_GET_IO_NUM(1, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(1, adc_list[i]))); + } + } + vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. +} + +static void adc_io_normal(adc_unit_t adc) +{ + if (adc & ADC_UNIT_1) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_1, adc_list[i]); + } + } + if (adc & ADC_UNIT_2) { + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc_gpio_init(ADC_UNIT_2, adc_list[i]); + } + } + vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. +} + +#define DEBUG_CHECK_ENABLE 0 +#define DEBUG_PRINT_ENABLE 1 +#define DEBUG_CHECK_ERROR 100 + +static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level) +{ +#if DEBUG_CHECK_ENABLE + int unit_old = 1; + int ch_cnt = 0; +#endif + for (int cnt = 0; cnt < 2; cnt++) { + ets_printf("\n[%s] link_buf[%d]: \n", __func__, cnt % 2); + for (int i = 0; i < SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); i++, i++) { + uint16_t h = link_buf[cnt % 2][i + 1], l = link_buf[cnt % 2][i]; + uint16_t temp = (h << 8 | l); + adc_digi_output_data_t *data = (adc_digi_output_data_t *)&temp; + + if (adc > ADC_UNIT_2) { //ADC_ENCODE_11BIT +#if DEBUG_PRINT_ENABLE + if (i % 16 == 0) { + ets_printf("\n"); + } + ets_printf("[%d_%d_%04x] ", data->type2.unit, data->type2.channel, data->type2.data); +#endif +#if DEBUG_CHECK_ENABLE + TEST_ASSERT_NOT_EQUAL(unit_old, data->type2.unit); + unit_old = data->type2.unit; + if (data->type2.channel > ADC_CHANNEL_MAX) { + printf("Data invalid [%d]\n", data->type2.channel); + continue; + } + int cur_ch = ((ch_cnt++ / 2) % TEST_ADC_CHANNEL); + TEST_ASSERT_EQUAL( data->type2.channel, adc_list[cur_ch] ); + /*Check data channel unit*/ + if (ideal_level == 1) { + TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0x7FF, data->type2.data ); + } else if (ideal_level == 0) { + TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0, data->type2.data ); + } else { + // middle vol + } +#endif + } else { //ADC_ENCODE_12BIT +#if DEBUG_PRINT_ENABLE + if (i % 16 == 0) { + ets_printf("\n"); + } + ets_printf("[%d_%04x] ", data->type1.channel, data->type1.data); +#endif +#if DEBUG_CHECK_ENABLE + /*Check data channel */ + if (ideal_level == 1) { + if (data->type1.data != 0XFFF) { + return ESP_FAIL; + } + } else if (ideal_level == 0) { + if (data->type1.data != 0) { + return ESP_FAIL; + } + } else { + if (data->type1.data == 0 || data->type1.data == 0XFFF) { + return ESP_FAIL; + } + } + int cur_ch = ((i / 2) % TEST_ADC_CHANNEL); + if (data->type1.channel != adc_list[cur_ch] ) { + return ESP_FAIL; + } +#endif + } + link_buf[cnt % 2][i] = 0; + link_buf[cnt % 2][i + 1] = 0; + } + ets_printf("\n"); + } + return ESP_OK; +} + +static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc) +{ + ESP_LOGI(TAG, "adc IO fake tie low, test ..."); + adc_fake_tie_low(adc); + TEST_ESP_OK( adc_digi_stop() ); + dma_linker_restart(); + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + TEST_ESP_OK( adc_digi_start() ); + while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {}; + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + if ( ESP_OK != adc_dma_data_check(adc, 0)) { + return ESP_FAIL; + } + + ESP_LOGI(TAG, "adc IO fake tie high, test ..."); + adc_fake_tie_high(adc); + TEST_ESP_OK( adc_digi_stop() ); + dma_linker_restart(); + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + TEST_ESP_OK( adc_digi_start() ); + while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {}; + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + if ( ESP_OK != adc_dma_data_check(adc, 1)) { + return ESP_FAIL; + } + + ESP_LOGI(TAG, "adc IO fake tie middle, test ..."); + adc_fake_tie_middle(adc); + TEST_ESP_OK( adc_digi_stop() ); + dma_linker_restart(); + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + TEST_ESP_OK( adc_digi_start() ); + while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {}; + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + if ( ESP_OK != adc_dma_data_check(adc, 2)) { + return ESP_FAIL; + } + + TEST_ESP_OK( adc_digi_stop() ); + adc_io_normal(adc); + + return ESP_OK; +} + +#include "soc/apb_saradc_struct.h" +/** + * @brief Test the partten table setting. It's easy wrong. + * + * @param adc_n ADC unit. + * @param in_partten_len The length of partten be set. + * @param in_partten_len The channel number of the last message. + */ +static esp_err_t adc_check_patt_table(adc_unit_t adc, uint32_t in_partten_len, adc_channel_t in_last_ch) +{ + esp_err_t ret = ESP_FAIL; + uint8_t index = (in_partten_len - 1) / 4; + uint8_t offset = 24 - ((in_partten_len - 1) % 4) * 8; + uint32_t temp = 0, len; + + if (adc & ADC_UNIT_1) { + len = APB_SARADC.ctrl.sar1_patt_len + 1; + temp = APB_SARADC.sar1_patt_tab[index]; + printf("patt1 len %d\n", len); + printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[0]); + printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[1]); + printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[2]); + printf("patt1 0x%08x\n", APB_SARADC.sar1_patt_tab[3]); + if (in_partten_len == len) { + if (in_last_ch == (((temp >> (offset + 4))) & 0xf)) { + ret = ESP_OK; + } + } + } + if (adc & ADC_UNIT_2) { + len = APB_SARADC.ctrl.sar2_patt_len + 1; + temp = APB_SARADC.sar2_patt_tab[index]; + printf("patt2 len %d\n", len); + printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[0]); + printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[1]); + printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[2]); + printf("patt2 0x%08x\n", APB_SARADC.sar2_patt_tab[3]); + if (in_partten_len == len) { + if (in_last_ch == (((temp >> (offset + 4))) & 0xf)) { + ret = ESP_OK; + } + } + } + return ret; +} + +int test_adc_dig_dma_single_unit(adc_unit_t adc) +{ + ESP_LOGI(TAG, " >> %s << ", __func__); + ESP_LOGI(TAG, " >> adc unit: %x << ", adc); + + TEST_ESP_OK( adc_digi_init() ); + /* arbiter config */ + adc_arbiter_t arb_cfg = { + .mode = ADC_ARB_MODE_FIX, + .dig_pri = 0, + .pwdet_pri = 2, + .rtc_pri = 1, + }; + TEST_ESP_OK( adc_arbiter_config(ADC_UNIT_2, &arb_cfg) ); // If you want use force + + adc_digi_config_t config = { + .conv_limit_en = false, + .conv_limit_num = 0, + .interval = TEST_ADC_TRIGGER_INTERVAL_DEFAULT, + .dig_clk.use_apll = 0, // APB clk + .dig_clk.div_num = 2, // 80 MHz / 160 = 500 KHz + .dig_clk.div_b = 1, + .dig_clk.div_a = 1, + .dma_eof_num = SAR_EOF_NUMBER((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM), + }; + /* Config pattern table */ + adc_digi_pattern_table_t adc1_patt[TEST_ADC_CHANNEL] = {0}; + adc_digi_pattern_table_t adc2_patt[TEST_ADC_CHANNEL] = {0}; + if (adc & ADC_UNIT_1) { + config.adc1_pattern_len = TEST_ADC_CHANNEL; + config.adc1_pattern = adc1_patt; + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc1_patt[i].atten = adc_atten[i%ADC_ATTEN_MAX]; + adc1_patt[i].channel = adc_list[i]; + adc_gpio_init(ADC_UNIT_1, adc_list[i]); + } + } + if (adc & ADC_UNIT_2) { + config.adc2_pattern_len = TEST_ADC_CHANNEL; + config.adc2_pattern = adc2_patt; + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc2_patt[i].atten = adc_atten[i%ADC_ATTEN_MAX]; + adc2_patt[i].channel = adc_list[i]; + adc_gpio_init(ADC_UNIT_2, adc_list[i]); + } + } + if (adc == ADC_UNIT_1) { + config.conv_mode = ADC_CONV_SINGLE_UNIT_1; + config.format = ADC_DIGI_FORMAT_12BIT; + } else if (adc == ADC_UNIT_2) { + config.conv_mode = ADC_CONV_SINGLE_UNIT_2; + config.format = ADC_DIGI_FORMAT_12BIT; + } else if (adc == ADC_UNIT_BOTH) { + config.conv_mode = ADC_CONV_BOTH_UNIT; + config.format = ADC_DIGI_FORMAT_11BIT; + } else if (adc == ADC_UNIT_ALTER) { + config.conv_mode = ADC_CONV_ALTER_UNIT; + config.format = ADC_DIGI_FORMAT_11BIT; + } + TEST_ESP_OK( adc_digi_controller_config(&config) ); + + dma_linker_init(adc, false); + TEST_ESP_OK( adc_check_patt_table(adc, TEST_ADC_CHANNEL, adc_list[TEST_ADC_CHANNEL - 1]) ); + + TEST_ESP_OK( adc_digi_start() ); + + adc_dma_data_multi_st_check(adc); + + return 0; +} + +TEST_CASE("ADC DMA single read", "[ADC]") +{ + test_adc_dig_dma_single_unit(ADC_UNIT_BOTH); + + test_adc_dig_dma_single_unit(ADC_UNIT_ALTER); + + test_adc_dig_dma_single_unit(ADC_UNIT_1); + + test_adc_dig_dma_single_unit(ADC_UNIT_2); +} + +#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32) \ No newline at end of file diff --git a/components/driver/test/component.mk b/components/driver/test/component.mk index 2f9f42ccd..4ad0b5cee 100644 --- a/components/driver/test/component.mk +++ b/components/driver/test/component.mk @@ -2,7 +2,7 @@ #Component Makefile # -COMPONENT_SRCDIRS += param_test +COMPONENT_SRCDIRS += param_test touch_sensor_test adc_test COMPONENT_PRIV_INCLUDEDIRS += param_test/include COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/driver/test/dac_dma_test/test_dac_audio_file.h b/components/driver/test/dac_dma_test/test_dac_audio_file.h new file mode 100644 index 000000000..42158a6c6 --- /dev/null +++ b/components/driver/test/dac_dma_test/test_dac_audio_file.h @@ -0,0 +1,4989 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +const unsigned char audio_table[] = { + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x7a, 0x79, 0x79, 0x7c, 0x81, 0x82, 0x82, + 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7e, 0x82, 0x84, 0x84, 0x85, 0x84, 0x80, 0x7d, 0x7a, + 0x78, 0x78, 0x7a, 0x80, 0x84, 0x87, 0x86, 0x80, 0x7a, 0x77, 0x79, 0x7d, 0x82, 0x85, 0x84, 0x82, + 0x7d, 0x7a, 0x77, 0x76, 0x77, 0x79, 0x80, 0x84, 0x86, 0x88, 0x87, 0x84, 0x7e, 0x77, 0x74, 0x75, + 0x79, 0x81, 0x88, 0x8b, 0x89, 0x87, 0x84, 0x7e, 0x78, 0x73, 0x72, 0x78, 0x82, 0x8b, 0x8f, 0x8e, + 0x88, 0x7e, 0x71, 0x69, 0x6d, 0x79, 0x88, 0x8f, 0x8c, 0x85, 0x80, 0x80, 0x81, 0x7d, 0x77, 0x73, + 0x76, 0x7e, 0x88, 0x8f, 0x8d, 0x85, 0x7e, 0x7b, 0x7b, 0x7e, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x80, + 0x83, 0x82, 0x80, 0x7d, 0x7d, 0x80, 0x82, 0x84, 0x83, 0x80, 0x7c, 0x7b, 0x7d, 0x81, 0x84, 0x84, + 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, 0x7a, 0x79, 0x7c, 0x83, 0x87, 0x87, 0x83, 0x7e, 0x79, 0x78, + 0x78, 0x79, 0x7b, 0x7c, 0x7d, 0x81, 0x82, 0x83, 0x84, 0x83, 0x7e, 0x7a, 0x77, 0x78, 0x7b, 0x7e, + 0x81, 0x82, 0x80, 0x7e, 0x7e, 0x81, 0x82, 0x80, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7b, + 0x7b, 0x7c, 0x80, 0x83, 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7a, 0x77, 0x77, 0x78, 0x7c, 0x82, 0x85, + 0x86, 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x77, 0x75, 0x78, 0x7e, 0x83, 0x85, 0x85, 0x85, 0x84, 0x83, + 0x81, 0x7c, 0x7a, 0x7a, 0x7c, 0x7e, 0x81, 0x82, 0x83, 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7c, 0x7a, + 0x7a, 0x7c, 0x80, 0x83, 0x86, 0x87, 0x84, 0x80, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, + 0x83, 0x87, 0x88, 0x87, 0x82, 0x7c, 0x78, 0x79, 0x7b, 0x7c, 0x7d, 0x81, 0x85, 0x8a, 0x8a, 0x85, + 0x7e, 0x79, 0x78, 0x79, 0x7a, 0x7c, 0x7c, 0x7e, 0x81, 0x82, 0x83, 0x81, 0x7e, 0x7d, 0x7c, 0x7d, + 0x80, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x81, 0x83, 0x83, 0x84, 0x81, 0x7d, 0x7a, 0x77, 0x78, 0x7a, + 0x7d, 0x80, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7a, 0x7c, 0x80, 0x82, 0x81, 0x7e, 0x7c, 0x7c, 0x7e, + 0x81, 0x82, 0x84, 0x84, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, + 0x7d, 0x82, 0x86, 0x89, 0x89, 0x85, 0x7a, 0x6f, 0x69, 0x64, 0x62, 0x6f, 0x8f, 0xb2, 0xc9, 0xcc, + 0xb1, 0x80, 0x4f, 0x2c, 0x18, 0x24, 0x53, 0x8c, 0xb3, 0xc9, 0xd0, 0xbe, 0x9c, 0x78, 0x5b, 0x4b, + 0x4e, 0x5d, 0x76, 0x8b, 0x92, 0x9d, 0x9d, 0x90, 0x87, 0x7a, 0x70, 0x6c, 0x70, 0x7a, 0x86, 0x8b, + 0x8e, 0x8b, 0x83, 0x7b, 0x77, 0x78, 0x7a, 0x80, 0x82, 0x82, 0x83, 0x81, 0x7a, 0x79, 0x7e, 0x84, + 0x89, 0x8b, 0x85, 0x7b, 0x71, 0x6f, 0x71, 0x73, 0x79, 0x88, 0x94, 0x99, 0x96, 0x8f, 0x82, 0x6c, + 0x5f, 0x60, 0x67, 0x77, 0x8f, 0xa1, 0xa6, 0x9c, 0x85, 0x67, 0x56, 0x58, 0x69, 0x83, 0x99, 0xa7, + 0xa7, 0x97, 0x82, 0x6a, 0x57, 0x54, 0x5e, 0x74, 0x90, 0xa5, 0xa9, 0x9c, 0x86, 0x6f, 0x60, 0x5d, + 0x67, 0x7b, 0x8f, 0x98, 0x98, 0x8e, 0x7d, 0x6b, 0x60, 0x63, 0x70, 0x84, 0x99, 0xa5, 0xa4, 0x94, + 0x7d, 0x67, 0x58, 0x59, 0x63, 0x75, 0x89, 0x93, 0x96, 0x98, 0x96, 0x90, 0x86, 0x77, 0x69, 0x5f, + 0x5d, 0x69, 0x7c, 0x8d, 0x99, 0x9a, 0x92, 0x86, 0x74, 0x68, 0x68, 0x74, 0x84, 0x93, 0x9b, 0x98, + 0x8d, 0x7a, 0x69, 0x60, 0x61, 0x6a, 0x7a, 0x8d, 0x9e, 0xa4, 0x98, 0x83, 0x6c, 0x5e, 0x60, 0x6c, + 0x7d, 0x91, 0x98, 0x94, 0x8b, 0x79, 0x6c, 0x67, 0x6a, 0x78, 0x88, 0x92, 0x98, 0x8e, 0x7b, 0x69, + 0x61, 0x69, 0x7a, 0x8f, 0x9e, 0xa1, 0x97, 0x87, 0x78, 0x6d, 0x6a, 0x6e, 0x74, 0x7c, 0x82, 0x80, + 0x7c, 0x7d, 0x81, 0x85, 0x8b, 0x91, 0x92, 0x8b, 0x7d, 0x70, 0x64, 0x5d, 0x5c, 0x67, 0x80, 0x9a, + 0xb1, 0xbd, 0xb7, 0x9f, 0x7a, 0x53, 0x36, 0x31, 0x45, 0x6a, 0x99, 0xc5, 0xd8, 0xca, 0xa4, 0x73, + 0x46, 0x2a, 0x2d, 0x50, 0x83, 0xad, 0xc1, 0xba, 0xa3, 0x8a, 0x70, 0x5c, 0x53, 0x57, 0x67, 0x79, + 0x89, 0x9b, 0xa7, 0xa3, 0x93, 0x81, 0x71, 0x6a, 0x68, 0x69, 0x6d, 0x75, 0x78, 0x78, 0x80, 0x8c, + 0x9b, 0xaa, 0xb0, 0xa7, 0x91, 0x71, 0x4c, 0x34, 0x35, 0x4d, 0x78, 0xa9, 0xcc, 0xd8, 0xcd, 0xa7, + 0x73, 0x41, 0x19, 0xf, 0x29, 0x5f, 0xa5, 0xe3, 0xff, 0xf8, 0xc1, 0x6c, 0x22, 0x0, 0x9, 0x34, + 0x74, 0xb3, 0xdc, 0xe3, 0xca, 0x98, 0x64, 0x42, 0x36, 0x44, 0x6a, 0x96, 0xb6, 0xbb, 0xa5, 0x83, + 0x64, 0x57, 0x57, 0x5e, 0x71, 0x8d, 0x9f, 0xa4, 0x98, 0x85, 0x75, 0x6b, 0x6a, 0x73, 0x81, 0x8d, + 0x97, 0x94, 0x7a, 0x5e, 0x53, 0x5e, 0x7a, 0x91, 0xa1, 0xa6, 0x9c, 0x91, 0x78, 0x66, 0x66, 0x6c, + 0x7b, 0x82, 0x84, 0x93, 0x9c, 0x93, 0x85, 0x74, 0x62, 0x58, 0x62, 0x7a, 0x8f, 0xa3, 0xb3, 0xaf, + 0x92, 0x63, 0x40, 0x3c, 0x55, 0x81, 0xa8, 0xbb, 0xb4, 0x90, 0x65, 0x50, 0x58, 0x74, 0x8a, 0x95, + 0x96, 0x91, 0x87, 0x80, 0x7a, 0x70, 0x68, 0x68, 0x6f, 0x7e, 0x95, 0xa8, 0xa7, 0x98, 0x7d, 0x60, + 0x54, 0x5c, 0x6d, 0x81, 0x95, 0xa3, 0xa4, 0x99, 0x7d, 0x68, 0x5d, 0x5d, 0x67, 0x76, 0x88, 0x96, + 0x9f, 0xa2, 0x9d, 0x87, 0x6a, 0x53, 0x4d, 0x5e, 0x7a, 0x99, 0xad, 0xb1, 0xa3, 0x81, 0x62, 0x59, + 0x5d, 0x67, 0x77, 0x8d, 0x9c, 0x9b, 0x91, 0x83, 0x70, 0x64, 0x69, 0x7b, 0x93, 0xa1, 0x9e, 0x89, + 0x74, 0x64, 0x50, 0x4d, 0x69, 0x96, 0xbd, 0xc5, 0xad, 0x8a, 0x5c, 0x3d, 0x38, 0x46, 0x6c, 0x99, + 0xbb, 0xce, 0xc8, 0xa7, 0x72, 0x3e, 0x21, 0x27, 0x4f, 0x8b, 0xbc, 0xd1, 0xc7, 0xa5, 0x76, 0x50, + 0x3d, 0x41, 0x5e, 0x84, 0xa9, 0xc0, 0xb7, 0xa0, 0x82, 0x66, 0x58, 0x58, 0x60, 0x6e, 0x7e, 0x8e, + 0x9b, 0xa1, 0x9e, 0x97, 0x87, 0x71, 0x62, 0x57, 0x54, 0x61, 0x7c, 0xa1, 0xbb, 0xbd, 0xa9, 0x84, + 0x59, 0x3c, 0x3b, 0x57, 0x81, 0xa8, 0xc2, 0xc4, 0xac, 0x81, 0x58, 0x3d, 0x3a, 0x52, 0x75, 0x98, + 0xb4, 0xc2, 0xbb, 0xa1, 0x7b, 0x5a, 0x44, 0x3c, 0x4d, 0x6e, 0x93, 0xb0, 0xbc, 0xba, 0xa4, 0x80, + 0x5c, 0x45, 0x42, 0x52, 0x72, 0x98, 0xb2, 0xba, 0xaf, 0x92, 0x6e, 0x52, 0x45, 0x48, 0x5a, 0x7a, + 0x9c, 0xb1, 0xb8, 0xaf, 0x99, 0x7b, 0x60, 0x51, 0x51, 0x63, 0x7b, 0x96, 0xa8, 0xa8, 0x99, 0x82, + 0x6c, 0x5e, 0x59, 0x61, 0x76, 0x90, 0xa3, 0xa6, 0x9c, 0x89, 0x6f, 0x5a, 0x4d, 0x4f, 0x64, 0x82, + 0xa0, 0xb5, 0xb8, 0xad, 0x93, 0x72, 0x58, 0x49, 0x4d, 0x64, 0x83, 0x9f, 0xb3, 0xb5, 0xa5, 0x8b, + 0x6f, 0x59, 0x54, 0x5b, 0x67, 0x77, 0x8b, 0x98, 0x9d, 0x97, 0x8c, 0x7e, 0x71, 0x6a, 0x68, 0x6c, + 0x76, 0x86, 0x92, 0x9a, 0x9d, 0x98, 0x8a, 0x75, 0x61, 0x54, 0x55, 0x65, 0x83, 0xa0, 0xaf, 0xaa, + 0x99, 0x86, 0x75, 0x69, 0x5f, 0x5e, 0x67, 0x79, 0x8c, 0x96, 0x95, 0x8b, 0x80, 0x78, 0x76, 0x78, + 0x79, 0x76, 0x77, 0x80, 0x88, 0x89, 0x86, 0x86, 0x86, 0x84, 0x81, 0x7b, 0x78, 0x78, 0x7e, 0x83, + 0x81, 0x7c, 0x79, 0x7b, 0x84, 0x88, 0x86, 0x83, 0x80, 0x80, 0x82, 0x7e, 0x77, 0x74, 0x7b, 0x89, + 0x91, 0x89, 0x7a, 0x6f, 0x6c, 0x70, 0x7a, 0x84, 0x85, 0x81, 0x84, 0x89, 0x8e, 0x90, 0x8e, 0x8a, + 0x84, 0x7b, 0x6e, 0x63, 0x62, 0x71, 0x8c, 0xa5, 0xad, 0xa1, 0x8a, 0x73, 0x62, 0x58, 0x57, 0x5f, + 0x70, 0x8d, 0xa7, 0xb3, 0xae, 0x9c, 0x83, 0x68, 0x51, 0x41, 0x3e, 0x4f, 0x75, 0xa3, 0xc6, 0xd2, + 0xc3, 0x9b, 0x6b, 0x46, 0x35, 0x3a, 0x55, 0x7d, 0xa9, 0xc3, 0xc4, 0xb4, 0x95, 0x73, 0x5b, 0x4a, + 0x44, 0x4b, 0x5c, 0x79, 0x9b, 0xb7, 0xc2, 0xb5, 0x99, 0x7a, 0x5f, 0x4b, 0x45, 0x4d, 0x62, 0x7d, + 0x9a, 0xae, 0xb1, 0xaa, 0x9a, 0x8a, 0x7b, 0x64, 0x4d, 0x45, 0x50, 0x6b, 0x8e, 0xaa, 0xb4, 0xad, + 0x9d, 0x82, 0x68, 0x58, 0x53, 0x5b, 0x6d, 0x85, 0x97, 0xa4, 0xa9, 0xa4, 0x97, 0x81, 0x66, 0x56, + 0x54, 0x62, 0x78, 0x8e, 0x9d, 0xa3, 0x9c, 0x8e, 0x80, 0x75, 0x6d, 0x65, 0x63, 0x6a, 0x77, 0x89, + 0x97, 0x9d, 0x98, 0x8c, 0x7c, 0x6f, 0x67, 0x65, 0x67, 0x6e, 0x7d, 0x92, 0xa3, 0xa8, 0xa2, 0x95, + 0x84, 0x71, 0x63, 0x5d, 0x5f, 0x68, 0x78, 0x8a, 0x95, 0x98, 0x93, 0x88, 0x7e, 0x79, 0x76, 0x76, + 0x77, 0x7a, 0x81, 0x84, 0x85, 0x84, 0x82, 0x80, 0x7e, 0x81, 0x82, 0x81, 0x7b, 0x77, 0x75, 0x77, + 0x7c, 0x85, 0x8e, 0x96, 0x96, 0x8c, 0x7e, 0x6f, 0x64, 0x61, 0x66, 0x75, 0x85, 0x8c, 0x91, 0x90, + 0x8b, 0x86, 0x80, 0x7a, 0x78, 0x78, 0x7c, 0x81, 0x81, 0x7b, 0x79, 0x79, 0x7d, 0x82, 0x83, 0x80, + 0x79, 0x76, 0x79, 0x82, 0x8a, 0x90, 0x92, 0x8e, 0x88, 0x7c, 0x6e, 0x66, 0x66, 0x6b, 0x7b, 0x8f, + 0x99, 0x97, 0x8e, 0x86, 0x7e, 0x79, 0x75, 0x71, 0x6f, 0x73, 0x7b, 0x85, 0x8b, 0x8d, 0x8b, 0x88, + 0x82, 0x7a, 0x72, 0x6f, 0x72, 0x78, 0x7d, 0x81, 0x79, 0x69, 0x5b, 0x56, 0x64, 0x83, 0xa7, 0xc6, + 0xce, 0xc2, 0xa4, 0x7e, 0x5d, 0x48, 0x45, 0x52, 0x67, 0x7e, 0x91, 0x9c, 0xa1, 0x9d, 0x91, 0x7e, + 0x66, 0x4f, 0x3f, 0x3f, 0x51, 0x75, 0xa0, 0xc1, 0xd2, 0xc7, 0xa7, 0x80, 0x5b, 0x49, 0x4c, 0x5d, + 0x7b, 0x97, 0xa9, 0xaf, 0xa7, 0x9a, 0x87, 0x72, 0x60, 0x52, 0x49, 0x4b, 0x58, 0x71, 0x92, 0xaa, + 0xb4, 0xac, 0x97, 0x7c, 0x65, 0x5a, 0x5f, 0x6e, 0x82, 0x93, 0x9f, 0xa0, 0x9a, 0x90, 0x85, 0x7a, + 0x6f, 0x64, 0x5d, 0x5b, 0x61, 0x70, 0x84, 0x93, 0x9b, 0x9d, 0x97, 0x8b, 0x80, 0x76, 0x70, 0x70, + 0x6e, 0x6c, 0x6c, 0x6f, 0x7b, 0x8c, 0x9d, 0xa6, 0xa3, 0x98, 0x89, 0x7a, 0x6b, 0x5f, 0x5c, 0x62, + 0x6e, 0x80, 0x8e, 0x99, 0xa2, 0xa5, 0x9c, 0x84, 0x66, 0x53, 0x50, 0x5d, 0x74, 0x8e, 0x9e, 0xa2, + 0x9a, 0x8e, 0x84, 0x80, 0x7d, 0x7b, 0x74, 0x65, 0x5a, 0x5d, 0x72, 0x90, 0xa7, 0xb1, 0xa9, 0x95, + 0x7b, 0x69, 0x62, 0x64, 0x6c, 0x78, 0x84, 0x89, 0x8b, 0x8d, 0x8e, 0x8c, 0x8a, 0x84, 0x7a, 0x73, + 0x6d, 0x6b, 0x6f, 0x72, 0x6e, 0x66, 0x5d, 0x5b, 0x6b, 0x89, 0xab, 0xc3, 0xc7, 0xba, 0xa1, 0x83, + 0x6d, 0x63, 0x62, 0x67, 0x6d, 0x70, 0x72, 0x77, 0x7d, 0x85, 0x8b, 0x8a, 0x84, 0x7b, 0x72, 0x6a, + 0x67, 0x69, 0x6e, 0x75, 0x7a, 0x7c, 0x82, 0x8c, 0x96, 0x9e, 0xa2, 0x9e, 0x95, 0x8a, 0x81, 0x7b, + 0x7a, 0x7b, 0x79, 0x75, 0x71, 0x6e, 0x71, 0x79, 0x7d, 0x7e, 0x7a, 0x72, 0x70, 0x72, 0x76, 0x83, + 0x8e, 0x93, 0x93, 0x8c, 0x80, 0x77, 0x71, 0x70, 0x76, 0x7e, 0x87, 0x8d, 0x92, 0x95, 0x93, 0x8c, + 0x80, 0x71, 0x66, 0x60, 0x60, 0x66, 0x72, 0x81, 0x8d, 0x93, 0x96, 0x96, 0x94, 0x8f, 0x87, 0x7e, + 0x74, 0x69, 0x61, 0x62, 0x6e, 0x7c, 0x86, 0x8d, 0x8f, 0x8c, 0x89, 0x89, 0x8c, 0x8d, 0x8a, 0x82, + 0x78, 0x6c, 0x67, 0x6a, 0x70, 0x78, 0x81, 0x86, 0x8c, 0x90, 0x92, 0x93, 0x8e, 0x85, 0x79, 0x6e, + 0x67, 0x66, 0x6b, 0x75, 0x84, 0x90, 0x96, 0x96, 0x91, 0x8c, 0x85, 0x79, 0x6f, 0x66, 0x63, 0x67, + 0x6f, 0x7c, 0x8c, 0x99, 0x9e, 0x9d, 0x96, 0x89, 0x79, 0x6f, 0x69, 0x67, 0x6b, 0x74, 0x7e, 0x88, + 0x8b, 0x8a, 0x85, 0x7b, 0x71, 0x6a, 0x6a, 0x71, 0x80, 0x8e, 0x98, 0x9f, 0x9f, 0x95, 0x8b, 0x7c, + 0x6f, 0x69, 0x66, 0x68, 0x70, 0x78, 0x83, 0x8b, 0x90, 0x92, 0x8e, 0x87, 0x7c, 0x72, 0x6d, 0x6c, + 0x70, 0x78, 0x83, 0x8d, 0x93, 0x94, 0x90, 0x8a, 0x83, 0x7a, 0x73, 0x6f, 0x6f, 0x73, 0x79, 0x82, + 0x88, 0x8b, 0x8c, 0x8a, 0x85, 0x80, 0x7c, 0x78, 0x76, 0x76, 0x77, 0x7a, 0x7d, 0x80, 0x83, 0x87, + 0x8b, 0x8b, 0x8c, 0x8a, 0x84, 0x7c, 0x74, 0x6d, 0x6c, 0x6f, 0x76, 0x82, 0x8b, 0x93, 0x96, 0x95, + 0x8f, 0x87, 0x7b, 0x70, 0x69, 0x66, 0x69, 0x70, 0x7a, 0x86, 0x8e, 0x93, 0x94, 0x8d, 0x85, 0x7c, + 0x75, 0x72, 0x72, 0x74, 0x77, 0x7b, 0x80, 0x83, 0x87, 0x87, 0x87, 0x84, 0x80, 0x7d, 0x7a, 0x77, + 0x77, 0x7a, 0x7d, 0x80, 0x83, 0x83, 0x81, 0x7d, 0x7b, 0x7a, 0x7c, 0x7d, 0x82, 0x85, 0x87, 0x87, + 0x85, 0x82, 0x7c, 0x78, 0x75, 0x75, 0x78, 0x80, 0x86, 0x8a, 0x8e, 0x8e, 0x89, 0x83, 0x7b, 0x72, + 0x6e, 0x6e, 0x70, 0x77, 0x80, 0x88, 0x8e, 0x90, 0x8d, 0x87, 0x7e, 0x74, 0x6e, 0x6c, 0x70, 0x79, + 0x85, 0x8a, 0x8e, 0x8e, 0x88, 0x83, 0x7c, 0x77, 0x74, 0x75, 0x77, 0x7b, 0x83, 0x87, 0x88, 0x87, + 0x82, 0x7d, 0x7d, 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7a, 0x7a, 0x7d, 0x80, 0x83, + 0x85, 0x86, 0x83, 0x81, 0x7c, 0x7a, 0x7a, 0x7a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x81, + 0x83, 0x84, 0x83, 0x83, 0x82, 0x7e, 0x7a, 0x77, 0x73, 0x73, 0x76, 0x79, 0x80, 0x87, 0x8b, 0x8d, + 0x8a, 0x85, 0x81, 0x7a, 0x75, 0x74, 0x74, 0x76, 0x7a, 0x7e, 0x84, 0x88, 0x8a, 0x8a, 0x88, 0x84, + 0x7d, 0x77, 0x73, 0x72, 0x75, 0x7b, 0x83, 0x88, 0x8c, 0x8b, 0x86, 0x81, 0x7a, 0x76, 0x75, 0x76, + 0x78, 0x7b, 0x81, 0x86, 0x89, 0x89, 0x87, 0x82, 0x7b, 0x76, 0x74, 0x75, 0x78, 0x7d, 0x83, 0x84, + 0x85, 0x84, 0x82, 0x80, 0x7c, 0x7b, 0x7c, 0x7b, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x82, 0x83, 0x82, 0x82, 0x80, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x81, 0x81, 0x7e, 0x7e, + 0x7e, 0x7c, 0x7d, 0x7d, 0x7d, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7b, 0x7a, 0x7c, 0x7e, 0x83, + 0x83, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83, 0x85, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x79, 0x78, 0x78, + 0x7a, 0x7d, 0x82, 0x87, 0x88, 0x87, 0x83, 0x7d, 0x79, 0x79, 0x79, 0x7c, 0x80, 0x83, 0x83, 0x82, + 0x81, 0x7c, 0x7c, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x82, 0x82, 0x7e, 0x7c, 0x7c, 0x7c, 0x7e, + 0x80, 0x81, 0x82, 0x83, 0x81, 0x7e, 0x7c, 0x7b, 0x7c, 0x7d, 0x81, 0x85, 0x86, 0x85, 0x83, 0x80, + 0x7b, 0x78, 0x77, 0x77, 0x76, 0x79, 0x81, 0x86, 0x8a, 0x8b, 0x88, 0x81, 0x7b, 0x79, 0x78, 0x7b, + 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x82, 0x87, 0x88, 0x86, 0x81, 0x7c, 0x7a, 0x7b, 0x7e, 0x82, 0x83, + 0x81, 0x7d, 0x7c, 0x7d, 0x81, 0x82, 0x81, 0x80, 0x81, 0x80, 0x7d, 0x7c, 0x7b, 0x7a, 0x7c, 0x80, + 0x81, 0x7e, 0x7b, 0x7c, 0x7c, 0x79, 0x78, 0x7b, 0x7d, 0x80, 0x83, 0x84, 0x84, 0x83, 0x7e, 0x7a, + 0x79, 0x78, 0x76, 0x77, 0x7b, 0x84, 0x88, 0x87, 0x85, 0x83, 0x80, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, + 0x7c, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x82, 0x86, 0x88, 0x86, 0x81, 0x7b, 0x79, 0x79, 0x78, + 0x79, 0x7a, 0x7c, 0x80, 0x84, 0x87, 0x86, 0x87, 0x85, 0x81, 0x7a, 0x75, 0x74, 0x77, 0x7b, 0x81, + 0x84, 0x84, 0x84, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x80, 0x7b, 0x7b, 0x7b, 0x7a, 0x7c, 0x80, + 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x80, + 0x7e, 0x7e, 0x7d, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x83, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x79, + 0x77, 0x76, 0x77, 0x7b, 0x83, 0x8a, 0x8f, 0x8f, 0x87, 0x80, 0x78, 0x74, 0x73, 0x74, 0x7b, 0x80, + 0x83, 0x86, 0x85, 0x85, 0x84, 0x83, 0x80, 0x7c, 0x7a, 0x7b, 0x7c, 0x81, 0x85, 0x87, 0x87, 0x88, + 0x87, 0x83, 0x7e, 0x78, 0x77, 0x77, 0x77, 0x7b, 0x7e, 0x85, 0x89, 0x8b, 0x8c, 0x89, 0x82, 0x79, + 0x71, 0x70, 0x73, 0x76, 0x76, 0x76, 0x78, 0x80, 0x88, 0x8e, 0x90, 0x8b, 0x83, 0x78, 0x70, 0x6f, + 0x70, 0x77, 0x83, 0x88, 0x8a, 0x89, 0x85, 0x82, 0x81, 0x7e, 0x7a, 0x77, 0x7b, 0x82, 0x88, 0x87, + 0x7e, 0x76, 0x72, 0x75, 0x7b, 0x84, 0x8b, 0x8c, 0x87, 0x81, 0x79, 0x78, 0x7c, 0x81, 0x83, 0x7d, + 0x7a, 0x79, 0x7c, 0x85, 0x88, 0x85, 0x7e, 0x77, 0x74, 0x79, 0x7d, 0x81, 0x84, 0x83, 0x80, 0x7e, + 0x7d, 0x7a, 0x7c, 0x82, 0x80, 0x7c, 0x79, 0x78, 0x7e, 0x84, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7d, + 0x7c, 0x7d, 0x7e, 0x7a, 0x7b, 0x7e, 0x7e, 0x80, 0x82, 0x84, 0x87, 0x89, 0x86, 0x82, 0x81, 0x7d, + 0x7a, 0x78, 0x7a, 0x7e, 0x81, 0x82, 0x84, 0x83, 0x82, 0x82, 0x82, 0x80, 0x80, 0x7e, 0x79, 0x78, + 0x79, 0x7c, 0x7e, 0x7e, 0x7e, 0x81, 0x80, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x81, 0x83, 0x83, 0x82, + 0x82, 0x7e, 0x7d, 0x7b, 0x79, 0x7b, 0x80, 0x83, 0x84, 0x88, 0x86, 0x82, 0x7d, 0x77, 0x76, 0x79, + 0x7d, 0x82, 0x85, 0x87, 0x89, 0x88, 0x87, 0x84, 0x79, 0x74, 0x6f, 0x6c, 0x74, 0x7c, 0x87, 0x8d, + 0x8b, 0x8a, 0x84, 0x7d, 0x7a, 0x77, 0x74, 0x74, 0x76, 0x77, 0x7d, 0x84, 0x87, 0x87, 0x85, 0x80, + 0x7d, 0x81, 0x81, 0x81, 0x7e, 0x78, 0x78, 0x77, 0x79, 0x7e, 0x84, 0x85, 0x83, 0x82, 0x7e, 0x7e, + 0x84, 0x87, 0x87, 0x86, 0x81, 0x79, 0x76, 0x7a, 0x7c, 0x80, 0x82, 0x80, 0x80, 0x82, 0x88, 0x8e, + 0x8e, 0x8b, 0x83, 0x7a, 0x72, 0x6e, 0x6d, 0x72, 0x7c, 0x86, 0x8a, 0x8c, 0x8d, 0x8a, 0x88, 0x83, + 0x7b, 0x72, 0x6b, 0x6a, 0x6d, 0x77, 0x84, 0x8c, 0x91, 0x8f, 0x87, 0x80, 0x7d, 0x7c, 0x7d, 0x7e, + 0x7a, 0x78, 0x77, 0x77, 0x7b, 0x82, 0x85, 0x87, 0x88, 0x85, 0x86, 0x86, 0x85, 0x84, 0x80, 0x7b, + 0x78, 0x76, 0x77, 0x7a, 0x80, 0x80, 0x81, 0x83, 0x83, 0x85, 0x87, 0x87, 0x85, 0x80, 0x7b, 0x76, + 0x75, 0x77, 0x76, 0x78, 0x7c, 0x7e, 0x81, 0x84, 0x86, 0x87, 0x8a, 0x8a, 0x87, 0x81, 0x7c, 0x78, + 0x73, 0x74, 0x75, 0x78, 0x84, 0x8d, 0x8e, 0x8c, 0x87, 0x7e, 0x79, 0x7a, 0x7c, 0x81, 0x80, 0x7d, + 0x7a, 0x7a, 0x7e, 0x83, 0x87, 0x89, 0x86, 0x84, 0x80, 0x7b, 0x78, 0x73, 0x72, 0x74, 0x77, 0x81, + 0x8b, 0x8f, 0x8e, 0x86, 0x7b, 0x73, 0x6e, 0x71, 0x78, 0x7b, 0x7e, 0x81, 0x80, 0x82, 0x86, 0x89, + 0x8a, 0x86, 0x7c, 0x75, 0x74, 0x77, 0x7b, 0x81, 0x84, 0x83, 0x82, 0x7e, 0x81, 0x85, 0x87, 0x88, + 0x86, 0x80, 0x7a, 0x77, 0x77, 0x7b, 0x7e, 0x82, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x7d, + 0x7c, 0x7b, 0x7c, 0x81, 0x83, 0x83, 0x80, 0x79, 0x74, 0x70, 0x70, 0x74, 0x7a, 0x86, 0x8f, 0x92, + 0x90, 0x89, 0x7d, 0x74, 0x71, 0x70, 0x74, 0x78, 0x7a, 0x7c, 0x7d, 0x7c, 0x7d, 0x82, 0x86, 0x8c, + 0x8f, 0x8d, 0x88, 0x7d, 0x74, 0x73, 0x72, 0x76, 0x7a, 0x7b, 0x82, 0x86, 0x89, 0x8e, 0x8e, 0x8b, + 0x86, 0x7b, 0x76, 0x75, 0x78, 0x7e, 0x85, 0x86, 0x83, 0x80, 0x7c, 0x7c, 0x80, 0x84, 0x87, 0x87, + 0x84, 0x82, 0x80, 0x80, 0x7e, 0x7a, 0x75, 0x73, 0x72, 0x76, 0x7c, 0x82, 0x86, 0x87, 0x85, 0x86, + 0x88, 0x86, 0x81, 0x7b, 0x75, 0x6f, 0x6e, 0x72, 0x7a, 0x82, 0x8a, 0x90, 0x91, 0x8e, 0x88, 0x84, + 0x7b, 0x76, 0x72, 0x6f, 0x70, 0x78, 0x84, 0x8b, 0x8e, 0x8a, 0x7d, 0x73, 0x71, 0x76, 0x82, 0x8e, + 0x92, 0x8b, 0x7e, 0x71, 0x6c, 0x70, 0x78, 0x81, 0x82, 0x7e, 0x7a, 0x7b, 0x80, 0x89, 0x92, 0x92, + 0x89, 0x7c, 0x70, 0x6b, 0x6f, 0x76, 0x7b, 0x7e, 0x80, 0x82, 0x87, 0x8d, 0x92, 0x91, 0x8c, 0x82, + 0x75, 0x6f, 0x6d, 0x6f, 0x73, 0x79, 0x80, 0x86, 0x8d, 0x93, 0x93, 0x8d, 0x84, 0x76, 0x6b, 0x6a, + 0x73, 0x7c, 0x88, 0x8d, 0x8b, 0x88, 0x83, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7c, 0x7a, 0x78, 0x78, + 0x78, 0x76, 0x78, 0x7c, 0x85, 0x91, 0x96, 0x91, 0x85, 0x72, 0x67, 0x68, 0x6f, 0x77, 0x80, 0x82, + 0x80, 0x7e, 0x81, 0x88, 0x93, 0x99, 0x94, 0x88, 0x78, 0x69, 0x66, 0x6e, 0x78, 0x80, 0x84, 0x82, + 0x82, 0x86, 0x8d, 0x91, 0x92, 0x8e, 0x84, 0x7b, 0x74, 0x6e, 0x71, 0x77, 0x7c, 0x7e, 0x80, 0x81, + 0x82, 0x86, 0x87, 0x87, 0x85, 0x83, 0x80, 0x7c, 0x7b, 0x7b, 0x7a, 0x77, 0x76, 0x77, 0x79, 0x7b, + 0x7e, 0x81, 0x84, 0x86, 0x86, 0x85, 0x86, 0x85, 0x81, 0x80, 0x79, 0x75, 0x73, 0x71, 0x75, 0x7a, + 0x80, 0x88, 0x8f, 0x95, 0x93, 0x85, 0x74, 0x67, 0x65, 0x74, 0x8c, 0x9c, 0x9e, 0x89, 0x69, 0x53, + 0x50, 0x66, 0x89, 0xa6, 0xae, 0x9d, 0x81, 0x6a, 0x65, 0x76, 0x8d, 0x97, 0x8b, 0x6f, 0x5b, 0x5a, + 0x6c, 0x88, 0x9e, 0xa2, 0x91, 0x7e, 0x74, 0x76, 0x83, 0x8f, 0x8f, 0x83, 0x71, 0x65, 0x64, 0x73, + 0x89, 0x97, 0x9a, 0x90, 0x80, 0x76, 0x76, 0x7b, 0x7e, 0x7d, 0x77, 0x74, 0x78, 0x81, 0x8a, 0x8f, + 0x8c, 0x83, 0x77, 0x70, 0x6e, 0x76, 0x84, 0x8e, 0x94, 0x92, 0x8c, 0x87, 0x84, 0x84, 0x83, 0x7c, + 0x72, 0x66, 0x58, 0x4b, 0x44, 0x46, 0x5b, 0x81, 0xad, 0xce, 0xd4, 0xba, 0x93, 0x73, 0x66, 0x66, + 0x6b, 0x6c, 0x67, 0x66, 0x69, 0x72, 0x84, 0x9e, 0xba, 0xc7, 0xb8, 0x93, 0x67, 0x54, 0x57, 0x68, + 0x73, 0x6d, 0x60, 0x57, 0x62, 0x7c, 0x98, 0xa6, 0xa9, 0xa2, 0x92, 0x7b, 0x68, 0x63, 0x6b, 0x78, + 0x83, 0x85, 0x80, 0x7d, 0x86, 0x92, 0x98, 0x94, 0x87, 0x7c, 0x77, 0x76, 0x78, 0x7a, 0x7b, 0x7a, + 0x7b, 0x7d, 0x7c, 0x7a, 0x79, 0x7d, 0x80, 0x80, 0x80, 0x7c, 0x7c, 0x83, 0x8a, 0x8d, 0x8c, 0x8a, + 0x87, 0x86, 0x85, 0x80, 0x7a, 0x79, 0x7b, 0x7c, 0x7b, 0x7c, 0x80, 0x84, 0x8a, 0x8b, 0x89, 0x84, + 0x77, 0x68, 0x59, 0x53, 0x55, 0x64, 0x81, 0x9b, 0xa9, 0xab, 0xa5, 0x9a, 0x8e, 0x87, 0x7c, 0x73, + 0x6d, 0x6b, 0x69, 0x6d, 0x76, 0x83, 0x91, 0x96, 0x94, 0x89, 0x77, 0x6e, 0x6c, 0x6e, 0x72, 0x73, + 0x76, 0x7a, 0x7d, 0x86, 0x8d, 0x8e, 0x8f, 0x8a, 0x84, 0x7c, 0x75, 0x76, 0x7e, 0x88, 0x8f, 0x90, + 0x8a, 0x85, 0x7e, 0x79, 0x76, 0x73, 0x74, 0x77, 0x79, 0x81, 0x86, 0x87, 0x89, 0x88, 0x85, 0x83, + 0x80, 0x7a, 0x75, 0x70, 0x69, 0x5f, 0x56, 0x54, 0x60, 0x7e, 0xa4, 0xc7, 0xd1, 0xc3, 0xa9, 0x86, + 0x6b, 0x5d, 0x57, 0x56, 0x57, 0x5e, 0x68, 0x75, 0x86, 0x95, 0xa1, 0xa5, 0x9a, 0x84, 0x68, 0x53, + 0x50, 0x59, 0x6c, 0x7b, 0x83, 0x8c, 0x97, 0xa3, 0xab, 0xa6, 0x9b, 0x8d, 0x79, 0x6b, 0x5e, 0x5b, + 0x66, 0x76, 0x85, 0x8e, 0x8f, 0x8c, 0x86, 0x81, 0x7b, 0x70, 0x64, 0x5f, 0x64, 0x71, 0x85, 0x96, + 0xa1, 0xa5, 0xa1, 0x93, 0x81, 0x6f, 0x62, 0x5e, 0x63, 0x6f, 0x79, 0x87, 0x94, 0x99, 0x98, 0x93, + 0x8b, 0x82, 0x7c, 0x79, 0x75, 0x71, 0x68, 0x5d, 0x5a, 0x63, 0x73, 0x8a, 0xa2, 0xb6, 0xba, 0xae, + 0x99, 0x7a, 0x5a, 0x40, 0x30, 0x2c, 0x3b, 0x5e, 0x8b, 0xb8, 0xd9, 0xe6, 0xdd, 0xc1, 0x99, 0x6a, + 0x43, 0x2e, 0x2c, 0x3c, 0x59, 0x77, 0x92, 0xa8, 0xb5, 0xb8, 0xaf, 0x9a, 0x7c, 0x5d, 0x42, 0x34, + 0x38, 0x50, 0x75, 0xa6, 0xd0, 0xe1, 0xd9, 0xba, 0x90, 0x64, 0x47, 0x3b, 0x3c, 0x4b, 0x5f, 0x77, + 0x91, 0xa7, 0xb3, 0xad, 0x9d, 0x86, 0x68, 0x51, 0x48, 0x4f, 0x64, 0x7e, 0x9b, 0xb2, 0xbb, 0xba, + 0xb1, 0x9c, 0x82, 0x6a, 0x55, 0x4b, 0x49, 0x4f, 0x5a, 0x69, 0x75, 0x7c, 0x7e, 0x87, 0x9b, 0xb3, + 0xc4, 0xbe, 0x9d, 0x70, 0x53, 0x4d, 0x5b, 0x74, 0x85, 0x8e, 0x95, 0x99, 0x9a, 0x91, 0x81, 0x76, + 0x6c, 0x62, 0x57, 0x4e, 0x53, 0x69, 0x8a, 0xa5, 0xb0, 0xa9, 0x9b, 0x8c, 0x83, 0x80, 0x74, 0x6d, + 0x6f, 0x73, 0x78, 0x7e, 0x87, 0x91, 0x97, 0x98, 0x90, 0x7e, 0x6e, 0x61, 0x60, 0x68, 0x71, 0x7a, + 0x84, 0x8f, 0x99, 0x9d, 0x9b, 0x93, 0x89, 0x80, 0x74, 0x6b, 0x64, 0x63, 0x6d, 0x7c, 0x8c, 0x96, + 0x9a, 0x99, 0x91, 0x89, 0x7d, 0x72, 0x6f, 0x72, 0x79, 0x83, 0x8a, 0x8b, 0x87, 0x82, 0x7a, 0x6f, + 0x64, 0x5e, 0x61, 0x70, 0x83, 0x97, 0xab, 0xbb, 0xc1, 0xb5, 0x93, 0x61, 0x39, 0x28, 0x30, 0x4e, + 0x79, 0xa2, 0xbd, 0xc9, 0xc2, 0xaa, 0x86, 0x62, 0x4a, 0x40, 0x44, 0x57, 0x72, 0x94, 0xb5, 0xcb, + 0xcd, 0xb5, 0x90, 0x6a, 0x4a, 0x39, 0x3a, 0x4b, 0x65, 0x8a, 0xaa, 0xbb, 0xbe, 0xb2, 0x98, 0x7a, + 0x5d, 0x43, 0x39, 0x40, 0x5b, 0x83, 0xac, 0xca, 0xd3, 0xc5, 0xa3, 0x79, 0x53, 0x36, 0x30, 0x3d, + 0x5a, 0x81, 0xa1, 0xb8, 0xc4, 0xba, 0xa6, 0x89, 0x67, 0x50, 0x45, 0x45, 0x50, 0x5f, 0x73, 0x84, + 0x97, 0xab, 0xbd, 0xc7, 0xbf, 0xa4, 0x74, 0x48, 0x33, 0x36, 0x53, 0x78, 0x93, 0xa5, 0xac, 0xa9, + 0x9a, 0x86, 0x6f, 0x5d, 0x52, 0x51, 0x56, 0x64, 0x7b, 0x98, 0xaf, 0xb8, 0xb1, 0x99, 0x7a, 0x64, + 0x5a, 0x5c, 0x66, 0x72, 0x82, 0x92, 0x9a, 0x98, 0x92, 0x88, 0x81, 0x77, 0x6b, 0x64, 0x62, 0x67, + 0x78, 0x8a, 0x94, 0x97, 0x92, 0x8d, 0x86, 0x7d, 0x77, 0x76, 0x78, 0x7c, 0x81, 0x81, 0x7e, 0x7b, + 0x7a, 0x7c, 0x7e, 0x7e, 0x84, 0x88, 0x89, 0x88, 0x85, 0x84, 0x85, 0x89, 0x8d, 0x8e, 0x87, 0x75, + 0x63, 0x57, 0x5a, 0x6a, 0x80, 0x93, 0x9d, 0x98, 0x8c, 0x83, 0x80, 0x85, 0x8c, 0x8b, 0x78, 0x59, + 0x3f, 0x39, 0x51, 0x81, 0xb8, 0xde, 0xe0, 0xc2, 0x92, 0x60, 0x3a, 0x2a, 0x33, 0x4e, 0x6e, 0x8f, + 0xa9, 0xba, 0xc1, 0xb6, 0x9b, 0x75, 0x51, 0x38, 0x38, 0x50, 0x76, 0xa0, 0xbd, 0xc9, 0xc0, 0xa5, + 0x84, 0x62, 0x4d, 0x44, 0x4a, 0x5d, 0x75, 0x8f, 0xa7, 0xb1, 0xab, 0x9c, 0x83, 0x6c, 0x5e, 0x5a, + 0x5f, 0x6d, 0x82, 0x94, 0xa0, 0xa3, 0x9c, 0x8f, 0x7c, 0x6a, 0x61, 0x5f, 0x65, 0x6c, 0x75, 0x7d, + 0x81, 0x84, 0x82, 0x85, 0x90, 0x99, 0xa0, 0x99, 0x88, 0x73, 0x65, 0x68, 0x73, 0x7c, 0x83, 0x85, + 0x86, 0x89, 0x88, 0x83, 0x7a, 0x72, 0x6f, 0x6d, 0x6c, 0x70, 0x7a, 0x8a, 0x98, 0x9d, 0x96, 0x8a, + 0x7d, 0x73, 0x6f, 0x70, 0x74, 0x7a, 0x82, 0x89, 0x8c, 0x89, 0x84, 0x80, 0x7c, 0x76, 0x6e, 0x66, + 0x67, 0x73, 0x81, 0x8f, 0x97, 0x93, 0x8c, 0x85, 0x81, 0x7a, 0x76, 0x79, 0x81, 0x87, 0x89, 0x87, + 0x82, 0x7b, 0x73, 0x6c, 0x69, 0x6c, 0x72, 0x82, 0x90, 0x96, 0x96, 0x94, 0x94, 0x96, 0x90, 0x82, + 0x73, 0x68, 0x65, 0x66, 0x68, 0x6b, 0x6f, 0x72, 0x73, 0x71, 0x6f, 0x7c, 0x99, 0xb2, 0xb6, 0xa5, + 0x8d, 0x77, 0x66, 0x5f, 0x60, 0x64, 0x6c, 0x81, 0x9c, 0xab, 0xa7, 0x97, 0x7b, 0x5b, 0x46, 0x45, + 0x55, 0x71, 0x8f, 0xa2, 0xac, 0xaa, 0x9e, 0x8e, 0x7c, 0x6f, 0x63, 0x61, 0x6e, 0x87, 0xa0, 0xad, + 0xa8, 0x96, 0x78, 0x5b, 0x4c, 0x49, 0x55, 0x69, 0x85, 0x9f, 0xab, 0xa7, 0x97, 0x82, 0x6d, 0x63, + 0x65, 0x71, 0x83, 0x92, 0x9c, 0x9c, 0x92, 0x82, 0x74, 0x6a, 0x63, 0x60, 0x64, 0x6d, 0x77, 0x7b, + 0x78, 0x6e, 0x69, 0x7b, 0xa2, 0xc6, 0xcf, 0xb0, 0x7a, 0x4f, 0x45, 0x59, 0x7c, 0x99, 0xa1, 0x9b, + 0x8e, 0x7a, 0x66, 0x58, 0x53, 0x5e, 0x70, 0x80, 0x87, 0x90, 0x9d, 0xa5, 0x9f, 0x87, 0x69, 0x57, + 0x56, 0x68, 0x81, 0x97, 0xab, 0xb1, 0xac, 0x9e, 0x7b, 0x55, 0x41, 0x46, 0x5b, 0x74, 0x90, 0xa5, + 0xaf, 0xac, 0x98, 0x79, 0x5d, 0x4d, 0x50, 0x62, 0x7e, 0x9c, 0xb1, 0xbe, 0xba, 0x9c, 0x6f, 0x48, + 0x38, 0x3e, 0x57, 0x78, 0x95, 0xac, 0xb6, 0xb3, 0xa2, 0x84, 0x63, 0x4d, 0x4b, 0x5b, 0x78, 0x99, + 0xb0, 0xb3, 0xa1, 0x7e, 0x5a, 0x45, 0x4c, 0x65, 0x81, 0x8f, 0x94, 0x9b, 0xa2, 0x9d, 0x8b, 0x73, + 0x5c, 0x48, 0x46, 0x5b, 0x7e, 0xa6, 0xc0, 0xc3, 0xa7, 0x7d, 0x5e, 0x57, 0x62, 0x73, 0x82, 0x8a, + 0x91, 0x92, 0x8f, 0x83, 0x70, 0x63, 0x5e, 0x6a, 0x7c, 0x92, 0x9e, 0xa2, 0x9d, 0x89, 0x6f, 0x60, + 0x61, 0x6f, 0x80, 0x8e, 0x98, 0x9c, 0x9a, 0x91, 0x82, 0x6c, 0x5d, 0x5c, 0x65, 0x74, 0x85, 0x91, + 0x96, 0x93, 0x8e, 0x83, 0x77, 0x70, 0x6a, 0x6a, 0x75, 0x84, 0x90, 0x9a, 0x9d, 0x95, 0x89, 0x77, + 0x68, 0x61, 0x5a, 0x5d, 0x6c, 0x86, 0xa5, 0xbc, 0xbd, 0xa1, 0x73, 0x50, 0x41, 0x4e, 0x70, 0x95, + 0xab, 0xac, 0xa0, 0x8e, 0x79, 0x69, 0x61, 0x5e, 0x62, 0x6f, 0x82, 0x93, 0xa0, 0xa5, 0x9d, 0x88, + 0x6b, 0x51, 0x46, 0x51, 0x70, 0x97, 0xb4, 0xbe, 0xb2, 0x96, 0x72, 0x57, 0x53, 0x5d, 0x6d, 0x81, + 0x8e, 0x93, 0x8d, 0x84, 0x7a, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x86, 0x87, 0x86, 0x83, 0x7d, 0x79, + 0x76, 0x76, 0x7b, 0x83, 0x87, 0x89, 0x87, 0x7e, 0x76, 0x73, 0x72, 0x76, 0x7b, 0x82, 0x88, 0x8d, + 0x93, 0x93, 0x8d, 0x82, 0x74, 0x6c, 0x6a, 0x6d, 0x76, 0x84, 0x8c, 0x8c, 0x82, 0x75, 0x71, 0x75, + 0x7c, 0x86, 0x8b, 0x8c, 0x89, 0x80, 0x79, 0x7c, 0x83, 0x89, 0x8d, 0x89, 0x81, 0x7b, 0x73, 0x6e, + 0x6d, 0x6e, 0x73, 0x80, 0x8f, 0x97, 0x96, 0x8f, 0x83, 0x76, 0x6d, 0x6a, 0x70, 0x7a, 0x88, 0x91, + 0x93, 0x92, 0x89, 0x7b, 0x72, 0x6d, 0x6d, 0x71, 0x7a, 0x87, 0x8f, 0x8f, 0x8f, 0x89, 0x80, 0x79, + 0x75, 0x72, 0x71, 0x70, 0x71, 0x79, 0x87, 0x98, 0xa5, 0xa6, 0x96, 0x79, 0x5a, 0x4d, 0x59, 0x74, + 0x94, 0xa6, 0xa2, 0x91, 0x7a, 0x67, 0x61, 0x67, 0x72, 0x7e, 0x89, 0x90, 0x94, 0x8f, 0x88, 0x7e, + 0x74, 0x6d, 0x6c, 0x74, 0x82, 0x8d, 0x97, 0x95, 0x86, 0x73, 0x68, 0x68, 0x71, 0x82, 0x8d, 0x94, + 0x92, 0x8a, 0x81, 0x77, 0x70, 0x6c, 0x6d, 0x75, 0x81, 0x8b, 0x91, 0x8f, 0x86, 0x7b, 0x74, 0x70, + 0x70, 0x77, 0x82, 0x88, 0x8c, 0x8b, 0x85, 0x7b, 0x74, 0x70, 0x6f, 0x73, 0x7c, 0x85, 0x8b, 0x91, + 0x8e, 0x88, 0x81, 0x76, 0x72, 0x71, 0x73, 0x7b, 0x84, 0x89, 0x89, 0x87, 0x86, 0x81, 0x7a, 0x76, + 0x77, 0x77, 0x76, 0x77, 0x7a, 0x7c, 0x7d, 0x81, 0x87, 0x8b, 0x8c, 0x87, 0x81, 0x7a, 0x73, 0x70, + 0x72, 0x79, 0x82, 0x86, 0x86, 0x83, 0x80, 0x80, 0x83, 0x85, 0x80, 0x7b, 0x7c, 0x7e, 0x85, 0x88, + 0x84, 0x79, 0x67, 0x4f, 0x43, 0x55, 0x8c, 0xca, 0xef, 0xe4, 0x9c, 0x44, 0x13, 0x1c, 0x55, 0x99, + 0xbf, 0xc4, 0xb0, 0x94, 0x77, 0x5c, 0x4b, 0x4a, 0x5c, 0x75, 0x8e, 0x9f, 0xa9, 0xae, 0xa5, 0x88, + 0x60, 0x48, 0x4c, 0x6b, 0x91, 0xa8, 0xac, 0x9e, 0x8b, 0x77, 0x69, 0x63, 0x67, 0x73, 0x80, 0x8a, + 0x8f, 0x87, 0x7d, 0x7a, 0x78, 0x76, 0x77, 0x83, 0x8c, 0x8d, 0x89, 0x81, 0x77, 0x73, 0x76, 0x7d, + 0x88, 0x8c, 0x8c, 0x8d, 0x8a, 0x81, 0x73, 0x6c, 0x6f, 0x76, 0x81, 0x8b, 0x92, 0x92, 0x8a, 0x7a, + 0x69, 0x64, 0x6c, 0x7e, 0x8f, 0x97, 0x96, 0x90, 0x88, 0x7a, 0x6b, 0x65, 0x6a, 0x74, 0x80, 0x8a, + 0x95, 0x98, 0x92, 0x88, 0x78, 0x68, 0x5c, 0x5a, 0x67, 0x81, 0x96, 0xa8, 0xaf, 0xa4, 0x89, 0x6a, + 0x57, 0x52, 0x5c, 0x72, 0x90, 0xa5, 0xac, 0xa5, 0x90, 0x76, 0x60, 0x53, 0x5c, 0x72, 0x8c, 0x9f, + 0xa7, 0xa2, 0x91, 0x7d, 0x6b, 0x60, 0x62, 0x6e, 0x81, 0x91, 0x97, 0x94, 0x8e, 0x83, 0x77, 0x71, + 0x72, 0x74, 0x74, 0x72, 0x6e, 0x6a, 0x6f, 0x82, 0x9e, 0xb6, 0xb8, 0x9f, 0x6f, 0x44, 0x37, 0x50, + 0x85, 0xb3, 0xc1, 0xaa, 0x7d, 0x58, 0x4f, 0x5a, 0x72, 0x89, 0x91, 0x90, 0x8d, 0x89, 0x83, 0x79, + 0x71, 0x6d, 0x6f, 0x77, 0x86, 0x95, 0xa2, 0xa1, 0x8f, 0x75, 0x5f, 0x59, 0x63, 0x75, 0x8a, 0x98, + 0x97, 0x8d, 0x81, 0x75, 0x72, 0x73, 0x75, 0x7b, 0x7d, 0x80, 0x88, 0x90, 0x91, 0x88, 0x7c, 0x74, + 0x72, 0x76, 0x7e, 0x87, 0x89, 0x86, 0x81, 0x7b, 0x78, 0x75, 0x75, 0x7b, 0x83, 0x85, 0x83, 0x7e, + 0x7b, 0x77, 0x76, 0x79, 0x7e, 0x86, 0x8d, 0x92, 0x8f, 0x85, 0x75, 0x6a, 0x69, 0x6d, 0x77, 0x85, + 0x8b, 0x86, 0x7d, 0x77, 0x7a, 0x81, 0x86, 0x88, 0x81, 0x79, 0x71, 0x6c, 0x6f, 0x79, 0x86, 0x8c, + 0x89, 0x83, 0x81, 0x82, 0x84, 0x81, 0x78, 0x71, 0x74, 0x80, 0x8e, 0x96, 0x92, 0x86, 0x75, 0x6a, + 0x69, 0x73, 0x85, 0x92, 0x95, 0x8e, 0x81, 0x75, 0x72, 0x74, 0x79, 0x81, 0x86, 0x8c, 0x90, 0x90, + 0x8a, 0x7d, 0x6e, 0x5e, 0x53, 0x59, 0x72, 0x9e, 0xc5, 0xd3, 0xbc, 0x82, 0x41, 0x1c, 0x2a, 0x62, + 0xab, 0xdb, 0xd9, 0xad, 0x6c, 0x3b, 0x32, 0x45, 0x69, 0x8e, 0xa2, 0xab, 0xa7, 0x9a, 0x83, 0x6a, + 0x56, 0x50, 0x5c, 0x75, 0x94, 0xac, 0xb4, 0xa4, 0x84, 0x61, 0x4b, 0x50, 0x67, 0x85, 0x9b, 0xa4, + 0x9e, 0x8b, 0x73, 0x65, 0x5e, 0x65, 0x77, 0x8a, 0x97, 0x9d, 0x97, 0x8a, 0x78, 0x6a, 0x65, 0x6b, + 0x78, 0x89, 0x93, 0x93, 0x8c, 0x80, 0x74, 0x6e, 0x6f, 0x76, 0x81, 0x8b, 0x91, 0x90, 0x85, 0x78, + 0x6f, 0x6e, 0x73, 0x7c, 0x87, 0x8e, 0x8f, 0x8a, 0x81, 0x77, 0x71, 0x73, 0x7b, 0x83, 0x88, 0x8a, + 0x86, 0x7e, 0x7a, 0x7a, 0x7c, 0x7b, 0x79, 0x7a, 0x7e, 0x84, 0x89, 0x8b, 0x84, 0x7a, 0x75, 0x77, + 0x7b, 0x7a, 0x76, 0x76, 0x79, 0x7d, 0x82, 0x86, 0x8c, 0x8b, 0x85, 0x81, 0x7c, 0x7a, 0x7d, 0x84, + 0x86, 0x85, 0x84, 0x83, 0x83, 0x82, 0x7c, 0x78, 0x76, 0x77, 0x7b, 0x80, 0x87, 0x8a, 0x86, 0x82, + 0x7c, 0x78, 0x77, 0x76, 0x77, 0x76, 0x75, 0x7a, 0x88, 0x98, 0xa5, 0xa7, 0x95, 0x71, 0x51, 0x47, + 0x58, 0x7e, 0xa9, 0xc3, 0xbb, 0x97, 0x67, 0x45, 0x3f, 0x53, 0x79, 0x9a, 0xa7, 0xa4, 0x96, 0x88, + 0x7a, 0x6f, 0x69, 0x67, 0x6e, 0x7c, 0x8e, 0x9b, 0x9b, 0x90, 0x7d, 0x6b, 0x63, 0x68, 0x77, 0x88, + 0x93, 0x96, 0x8d, 0x7e, 0x72, 0x6c, 0x6e, 0x74, 0x7e, 0x87, 0x8d, 0x90, 0x8d, 0x83, 0x7a, 0x74, + 0x73, 0x79, 0x81, 0x86, 0x86, 0x83, 0x7d, 0x79, 0x7a, 0x7e, 0x83, 0x85, 0x84, 0x82, 0x82, 0x7e, + 0x7a, 0x76, 0x75, 0x7a, 0x80, 0x85, 0x89, 0x8a, 0x85, 0x7c, 0x74, 0x71, 0x75, 0x7e, 0x89, 0x8d, + 0x8d, 0x86, 0x7a, 0x74, 0x73, 0x76, 0x7c, 0x82, 0x8b, 0x92, 0x92, 0x8a, 0x7a, 0x6f, 0x6d, 0x72, + 0x75, 0x79, 0x82, 0x89, 0x89, 0x84, 0x7e, 0x7d, 0x7d, 0x7d, 0x80, 0x84, 0x85, 0x7d, 0x70, 0x57, + 0x42, 0x4b, 0x7e, 0xc4, 0xef, 0xde, 0x9b, 0x4c, 0x1f, 0x2c, 0x5b, 0x93, 0xb7, 0xc2, 0xbd, 0x9d, + 0x6b, 0x46, 0x40, 0x54, 0x6c, 0x7d, 0x8f, 0xa3, 0xae, 0xa6, 0x89, 0x62, 0x4a, 0x4a, 0x63, 0x8b, + 0xab, 0xb8, 0xae, 0x92, 0x6f, 0x56, 0x50, 0x5b, 0x74, 0x91, 0xa1, 0x9e, 0x90, 0x80, 0x6e, 0x5e, + 0x58, 0x61, 0x73, 0x8c, 0xa5, 0xac, 0x9a, 0x7c, 0x68, 0x60, 0x5e, 0x6a, 0x86, 0xa3, 0xab, 0x9f, + 0x8e, 0x7c, 0x6e, 0x67, 0x6c, 0x74, 0x7a, 0x84, 0x8b, 0x86, 0x7a, 0x73, 0x76, 0x7a, 0x80, 0x87, + 0x8d, 0x8e, 0x87, 0x7c, 0x76, 0x75, 0x7a, 0x84, 0x8d, 0x90, 0x8d, 0x81, 0x72, 0x6b, 0x6a, 0x72, + 0x80, 0x89, 0x8d, 0x8b, 0x85, 0x79, 0x6e, 0x6a, 0x70, 0x7d, 0x89, 0x93, 0x96, 0x93, 0x87, 0x79, + 0x71, 0x6e, 0x72, 0x7c, 0x86, 0x8a, 0x8a, 0x85, 0x7e, 0x7b, 0x77, 0x77, 0x7a, 0x7a, 0x7a, 0x7b, + 0x7c, 0x7b, 0x7d, 0x7d, 0x81, 0x84, 0x86, 0x85, 0x82, 0x7c, 0x7a, 0x78, 0x7a, 0x80, 0x87, 0x8b, + 0x89, 0x7e, 0x6e, 0x61, 0x5f, 0x6f, 0x8d, 0xa9, 0xb3, 0xa1, 0x78, 0x4f, 0x40, 0x55, 0x81, 0xa9, + 0xb8, 0xa9, 0x89, 0x6a, 0x5e, 0x63, 0x6d, 0x79, 0x84, 0x8c, 0x91, 0x93, 0x90, 0x87, 0x78, 0x6b, + 0x65, 0x66, 0x73, 0x8c, 0x9e, 0xa1, 0x91, 0x78, 0x67, 0x65, 0x6d, 0x7a, 0x89, 0x8f, 0x8f, 0x8a, + 0x83, 0x7a, 0x72, 0x6b, 0x6c, 0x73, 0x7e, 0x8a, 0x92, 0x94, 0x8b, 0x7d, 0x71, 0x6b, 0x6d, 0x77, + 0x85, 0x8d, 0x8d, 0x86, 0x83, 0x7e, 0x78, 0x75, 0x75, 0x7b, 0x82, 0x89, 0x8e, 0x8e, 0x86, 0x79, + 0x6e, 0x6a, 0x6e, 0x79, 0x87, 0x8f, 0x8f, 0x87, 0x7a, 0x74, 0x72, 0x76, 0x80, 0x87, 0x8a, 0x89, + 0x85, 0x7c, 0x75, 0x6f, 0x6e, 0x73, 0x7c, 0x86, 0x8b, 0x89, 0x7e, 0x72, 0x69, 0x6b, 0x77, 0x85, + 0x90, 0x96, 0x93, 0x89, 0x7d, 0x76, 0x71, 0x70, 0x76, 0x83, 0x8d, 0x91, 0x8d, 0x87, 0x7e, 0x75, + 0x6f, 0x70, 0x76, 0x7c, 0x83, 0x86, 0x86, 0x85, 0x82, 0x7e, 0x7a, 0x75, 0x70, 0x6f, 0x77, 0x85, + 0x97, 0xa4, 0xa7, 0x97, 0x79, 0x5e, 0x52, 0x5e, 0x7a, 0x98, 0xa7, 0x9e, 0x81, 0x64, 0x59, 0x65, + 0x81, 0x9b, 0xa0, 0x94, 0x7e, 0x6e, 0x6a, 0x6b, 0x70, 0x74, 0x77, 0x83, 0x94, 0xa6, 0xae, 0xa2, + 0x86, 0x66, 0x54, 0x53, 0x62, 0x7c, 0x97, 0xa4, 0xa0, 0x90, 0x7b, 0x6c, 0x67, 0x6a, 0x71, 0x77, + 0x7c, 0x85, 0x8c, 0x8d, 0x86, 0x7c, 0x72, 0x70, 0x77, 0x85, 0x92, 0x94, 0x8b, 0x7d, 0x6f, 0x6c, + 0x70, 0x7a, 0x87, 0x8b, 0x8a, 0x84, 0x7a, 0x73, 0x71, 0x74, 0x7a, 0x84, 0x8e, 0x94, 0x91, 0x88, + 0x78, 0x69, 0x65, 0x6b, 0x77, 0x85, 0x8e, 0x91, 0x8e, 0x89, 0x83, 0x7d, 0x77, 0x71, 0x70, 0x74, + 0x7e, 0x89, 0x8d, 0x8a, 0x85, 0x81, 0x7b, 0x77, 0x7a, 0x80, 0x82, 0x7e, 0x7a, 0x79, 0x7b, 0x7d, + 0x82, 0x88, 0x8c, 0x8d, 0x89, 0x80, 0x6f, 0x58, 0x43, 0x43, 0x6a, 0xad, 0xe6, 0xeb, 0xb4, 0x60, + 0x24, 0x23, 0x50, 0x87, 0xad, 0xba, 0xb5, 0xa5, 0x8d, 0x6f, 0x55, 0x47, 0x4b, 0x5e, 0x7b, 0x9b, + 0xae, 0xb1, 0xa2, 0x81, 0x5b, 0x44, 0x47, 0x69, 0x96, 0xb3, 0xb7, 0x9f, 0x82, 0x6e, 0x66, 0x66, + 0x6e, 0x7c, 0x8d, 0x97, 0x99, 0x92, 0x81, 0x69, 0x59, 0x57, 0x64, 0x7b, 0x95, 0xa4, 0xa4, 0x96, + 0x7e, 0x67, 0x5b, 0x5b, 0x6b, 0x83, 0x94, 0x9c, 0x9e, 0x9c, 0x8f, 0x7b, 0x6b, 0x64, 0x6b, 0x77, + 0x89, 0x95, 0x95, 0x8a, 0x78, 0x6b, 0x68, 0x70, 0x7b, 0x86, 0x8d, 0x90, 0x8e, 0x8a, 0x84, 0x79, + 0x70, 0x6d, 0x70, 0x7a, 0x87, 0x91, 0x94, 0x8e, 0x85, 0x79, 0x72, 0x70, 0x6f, 0x73, 0x79, 0x7e, + 0x82, 0x87, 0x8d, 0x90, 0x8b, 0x81, 0x76, 0x71, 0x72, 0x7d, 0x8c, 0x93, 0x92, 0x89, 0x7e, 0x77, + 0x77, 0x7c, 0x83, 0x85, 0x84, 0x81, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x80, 0x83, 0x82, 0x82, 0x82, + 0x81, 0x7d, 0x78, 0x74, 0x76, 0x7c, 0x87, 0x8f, 0x94, 0x92, 0x8a, 0x7b, 0x69, 0x5b, 0x53, 0x5c, + 0x76, 0x9e, 0xc3, 0xce, 0xb1, 0x74, 0x37, 0x1b, 0x36, 0x7a, 0xbb, 0xdd, 0xc7, 0x8d, 0x5b, 0x48, + 0x58, 0x72, 0x81, 0x7b, 0x75, 0x81, 0x9a, 0xaf, 0xab, 0x8a, 0x5f, 0x43, 0x44, 0x63, 0x8f, 0xab, + 0xb1, 0xa2, 0x8a, 0x70, 0x60, 0x5f, 0x68, 0x77, 0x85, 0x8d, 0x90, 0x90, 0x8c, 0x84, 0x77, 0x6a, + 0x64, 0x69, 0x79, 0x8d, 0x9a, 0x99, 0x8d, 0x7a, 0x6d, 0x69, 0x70, 0x7e, 0x8a, 0x8f, 0x8e, 0x8b, + 0x88, 0x81, 0x78, 0x71, 0x71, 0x78, 0x84, 0x8f, 0x94, 0x91, 0x83, 0x70, 0x66, 0x69, 0x77, 0x88, + 0x93, 0x96, 0x90, 0x84, 0x76, 0x6d, 0x6b, 0x70, 0x78, 0x84, 0x8f, 0x97, 0x99, 0x93, 0x83, 0x71, + 0x62, 0x5b, 0x62, 0x71, 0x86, 0x94, 0x97, 0x93, 0x87, 0x78, 0x6f, 0x6c, 0x6f, 0x74, 0x7e, 0x87, + 0x8b, 0x8c, 0x88, 0x84, 0x7e, 0x7e, 0x83, 0x84, 0x82, 0x78, 0x6e, 0x67, 0x6a, 0x7c, 0x96, 0xad, + 0xb1, 0x9b, 0x74, 0x4d, 0x41, 0x59, 0x82, 0xa9, 0xb5, 0xa1, 0x80, 0x65, 0x62, 0x72, 0x87, 0x8c, + 0x7c, 0x6d, 0x6c, 0x82, 0x9e, 0xad, 0xa1, 0x7b, 0x57, 0x49, 0x5b, 0x81, 0xa0, 0xa7, 0x9a, 0x82, + 0x72, 0x73, 0x79, 0x81, 0x81, 0x79, 0x74, 0x76, 0x81, 0x8d, 0x91, 0x8b, 0x7c, 0x71, 0x6f, 0x79, + 0x88, 0x90, 0x8e, 0x84, 0x77, 0x6f, 0x70, 0x7b, 0x87, 0x8e, 0x8b, 0x86, 0x83, 0x82, 0x81, 0x7c, + 0x77, 0x73, 0x74, 0x7d, 0x89, 0x91, 0x93, 0x8a, 0x7a, 0x6e, 0x6b, 0x6f, 0x79, 0x83, 0x87, 0x85, + 0x83, 0x82, 0x83, 0x83, 0x80, 0x7a, 0x75, 0x75, 0x7b, 0x84, 0x8a, 0x8c, 0x87, 0x80, 0x7a, 0x7a, + 0x7e, 0x82, 0x83, 0x7d, 0x77, 0x76, 0x7a, 0x84, 0x8c, 0x8e, 0x8a, 0x81, 0x7a, 0x77, 0x78, 0x7a, + 0x7b, 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x88, 0x85, 0x80, 0x7b, 0x77, 0x74, 0x73, 0x74, 0x79, 0x7e, + 0x86, 0x8f, 0x94, 0x90, 0x83, 0x73, 0x66, 0x66, 0x71, 0x80, 0x8d, 0x8e, 0x88, 0x80, 0x7b, 0x7c, + 0x7e, 0x7e, 0x7b, 0x77, 0x75, 0x79, 0x82, 0x8a, 0x8e, 0x8c, 0x86, 0x7b, 0x74, 0x73, 0x77, 0x80, + 0x85, 0x86, 0x85, 0x83, 0x82, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x80, 0x7c, + 0x79, 0x78, 0x79, 0x7c, 0x82, 0x86, 0x87, 0x83, 0x7d, 0x79, 0x77, 0x77, 0x79, 0x7c, 0x7e, 0x7e, + 0x80, 0x82, 0x83, 0x83, 0x82, 0x80, 0x7a, 0x78, 0x78, 0x79, 0x7d, 0x83, 0x84, 0x84, 0x83, 0x81, + 0x80, 0x7e, 0x7c, 0x7a, 0x7a, 0x7a, 0x81, 0x87, 0x8c, 0x8b, 0x85, 0x7e, 0x78, 0x75, 0x76, 0x7a, + 0x7d, 0x81, 0x84, 0x86, 0x87, 0x86, 0x82, 0x7e, 0x79, 0x78, 0x78, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, + 0x85, 0x86, 0x87, 0x84, 0x7d, 0x77, 0x74, 0x76, 0x79, 0x7e, 0x84, 0x89, 0x8b, 0x89, 0x82, 0x7c, + 0x7a, 0x79, 0x78, 0x79, 0x7d, 0x85, 0x8b, 0x8d, 0x8c, 0x86, 0x80, 0x7b, 0x75, 0x74, 0x75, 0x79, + 0x80, 0x85, 0x8c, 0x8e, 0x89, 0x82, 0x77, 0x75, 0x77, 0x7d, 0x83, 0x82, 0x7d, 0x78, 0x76, 0x79, + 0x81, 0x8a, 0x90, 0x8c, 0x80, 0x74, 0x71, 0x74, 0x7d, 0x84, 0x83, 0x80, 0x79, 0x7a, 0x80, 0x85, + 0x89, 0x87, 0x80, 0x73, 0x70, 0x76, 0x80, 0x89, 0x8b, 0x85, 0x80, 0x7d, 0x7e, 0x82, 0x82, 0x7d, + 0x78, 0x75, 0x78, 0x80, 0x86, 0x8c, 0x8e, 0x88, 0x7d, 0x74, 0x6f, 0x72, 0x78, 0x80, 0x85, 0x88, + 0x87, 0x83, 0x80, 0x80, 0x7d, 0x7a, 0x77, 0x79, 0x7d, 0x81, 0x84, 0x84, 0x82, 0x7e, 0x7a, 0x77, + 0x78, 0x7c, 0x81, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7d, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x81, 0x82, 0x83, 0x81, 0x7d, 0x79, 0x77, 0x78, 0x7b, 0x7d, 0x80, + 0x81, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x77, 0x75, 0x77, 0x7a, 0x7c, 0x7e, 0x80, 0x84, 0x88, + 0x88, 0x85, 0x7c, 0x77, 0x76, 0x79, 0x81, 0x89, 0x8a, 0x85, 0x7d, 0x77, 0x78, 0x80, 0x86, 0x8a, + 0x87, 0x7d, 0x79, 0x7a, 0x82, 0x8a, 0x8a, 0x85, 0x7a, 0x72, 0x71, 0x76, 0x80, 0x86, 0x86, 0x82, + 0x7a, 0x79, 0x80, 0x85, 0x88, 0x85, 0x7c, 0x76, 0x74, 0x77, 0x7e, 0x86, 0x89, 0x87, 0x80, 0x78, + 0x77, 0x7b, 0x81, 0x82, 0x7d, 0x7b, 0x7c, 0x80, 0x83, 0x85, 0x82, 0x7b, 0x76, 0x75, 0x78, 0x80, + 0x85, 0x87, 0x84, 0x80, 0x7c, 0x79, 0x7b, 0x7d, 0x82, 0x83, 0x80, 0x7c, 0x7b, 0x7e, 0x81, 0x80, + 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x86, 0x86, 0x83, 0x7d, 0x7b, 0x78, 0x78, 0x7a, 0x7c, 0x83, 0x87, + 0x8a, 0x8b, 0x87, 0x82, 0x7d, 0x7a, 0x79, 0x77, 0x77, 0x7b, 0x82, 0x87, 0x87, 0x84, 0x82, 0x7e, + 0x7a, 0x78, 0x77, 0x77, 0x79, 0x7b, 0x80, 0x86, 0x8b, 0x8c, 0x88, 0x83, 0x7d, 0x79, 0x76, 0x72, + 0x71, 0x75, 0x7b, 0x85, 0x8d, 0x90, 0x8c, 0x84, 0x7b, 0x77, 0x78, 0x7b, 0x7e, 0x80, 0x80, 0x7d, + 0x7d, 0x81, 0x85, 0x88, 0x88, 0x86, 0x82, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7c, 0x7b, 0x7d, 0x82, + 0x88, 0x8b, 0x89, 0x83, 0x7b, 0x76, 0x74, 0x75, 0x79, 0x80, 0x83, 0x84, 0x84, 0x85, 0x87, 0x85, + 0x82, 0x7c, 0x78, 0x76, 0x77, 0x7a, 0x80, 0x85, 0x85, 0x82, 0x7e, 0x7c, 0x7c, 0x7e, 0x7d, 0x7b, + 0x79, 0x78, 0x7a, 0x7e, 0x84, 0x88, 0x88, 0x85, 0x81, 0x7b, 0x78, 0x7a, 0x7c, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7c, 0x7c, 0x7e, 0x83, 0x86, 0x88, 0x8a, 0x87, 0x82, 0x7b, 0x77, 0x77, 0x77, 0x78, 0x7c, + 0x84, 0x8a, 0x8e, 0x8e, 0x89, 0x81, 0x77, 0x72, 0x71, 0x74, 0x7b, 0x83, 0x89, 0x8a, 0x88, 0x83, + 0x7d, 0x7b, 0x7a, 0x78, 0x76, 0x77, 0x7c, 0x82, 0x86, 0x87, 0x86, 0x83, 0x7d, 0x79, 0x78, 0x7a, + 0x7e, 0x82, 0x84, 0x84, 0x86, 0x86, 0x84, 0x82, 0x7d, 0x7a, 0x77, 0x78, 0x7d, 0x84, 0x89, 0x89, + 0x84, 0x7e, 0x7a, 0x79, 0x7c, 0x82, 0x85, 0x83, 0x7b, 0x77, 0x77, 0x7d, 0x83, 0x85, 0x86, 0x82, + 0x80, 0x80, 0x81, 0x84, 0x83, 0x7e, 0x79, 0x74, 0x74, 0x7a, 0x84, 0x8a, 0x8b, 0x87, 0x7e, 0x79, + 0x77, 0x7a, 0x7e, 0x81, 0x81, 0x7e, 0x7c, 0x7c, 0x82, 0x87, 0x87, 0x85, 0x80, 0x7a, 0x78, 0x79, + 0x7d, 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7e, 0x82, 0x84, 0x83, 0x82, 0x7e, 0x7b, 0x7b, 0x7d, 0x82, + 0x84, 0x83, 0x7e, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x81, 0x80, 0x81, 0x82, 0x83, + 0x81, 0x81, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x7a, 0x79, 0x7d, 0x82, 0x84, 0x84, 0x82, 0x81, + 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x80, 0x82, 0x83, 0x82, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7c, 0x7b, 0x7a, 0x7b, 0x7e, 0x84, 0x88, 0x88, 0x84, 0x7c, 0x74, 0x6f, 0x70, 0x77, + 0x80, 0x87, 0x88, 0x87, 0x83, 0x80, 0x7d, 0x7c, 0x7b, 0x79, 0x77, 0x78, 0x7d, 0x86, 0x8b, 0x8d, + 0x8b, 0x83, 0x79, 0x72, 0x74, 0x78, 0x7d, 0x82, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x80, 0x7a, + 0x76, 0x74, 0x76, 0x7d, 0x85, 0x8b, 0x8b, 0x88, 0x82, 0x7b, 0x78, 0x78, 0x79, 0x7c, 0x7e, 0x80, + 0x81, 0x83, 0x83, 0x81, 0x7e, 0x7c, 0x79, 0x77, 0x79, 0x7d, 0x83, 0x86, 0x84, 0x80, 0x7d, 0x7b, + 0x7b, 0x7e, 0x82, 0x82, 0x81, 0x7e, 0x7b, 0x7b, 0x7c, 0x7e, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7b, 0x7a, 0x7a, 0x7c, 0x81, 0x84, + 0x85, 0x85, 0x84, 0x80, 0x7c, 0x79, 0x77, 0x77, 0x7a, 0x7c, 0x80, 0x83, 0x83, 0x82, 0x7d, 0x7b, + 0x7a, 0x79, 0x7a, 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x7b, 0x7d, 0x80, 0x82, 0x80, 0x7c, 0x7c, 0x7c, + 0x7e, 0x81, 0x84, 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x7a, 0x77, 0x77, 0x7b, 0x83, 0x86, 0x85, 0x82, + 0x7d, 0x7b, 0x7c, 0x7d, 0x7d, 0x7c, 0x79, 0x78, 0x7b, 0x80, 0x85, 0x87, 0x87, 0x84, 0x80, 0x7b, + 0x78, 0x7a, 0x7e, 0x83, 0x85, 0x82, 0x80, 0x7e, 0x7e, 0x81, 0x84, 0x84, 0x81, 0x7e, 0x7b, 0x7b, + 0x80, 0x84, 0x84, 0x83, 0x80, 0x7d, 0x7d, 0x7e, 0x82, 0x84, 0x84, 0x83, 0x7e, 0x7a, 0x79, 0x7a, + 0x7d, 0x80, 0x82, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7a, 0x75, 0x72, 0x73, 0x78, 0x80, 0x86, 0x89, + 0x86, 0x81, 0x7c, 0x7b, 0x7a, 0x7a, 0x7c, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7d, 0x7c, + 0x7c, 0x7e, 0x81, 0x83, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x83, 0x83, + 0x82, 0x81, 0x80, 0x7c, 0x7a, 0x7a, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x82, 0x82, 0x81, 0x7c, + 0x76, 0x71, 0x72, 0x78, 0x81, 0x87, 0x88, 0x86, 0x80, 0x78, 0x74, 0x76, 0x7c, 0x81, 0x83, 0x83, + 0x81, 0x7e, 0x7d, 0x7c, 0x7d, 0x7b, 0x7a, 0x7c, 0x80, 0x86, 0x8c, 0x90, 0x8e, 0x85, 0x7a, 0x72, + 0x6f, 0x71, 0x77, 0x80, 0x89, 0x8d, 0x8e, 0x8e, 0x8b, 0x85, 0x78, 0x68, 0x67, 0x75, 0x95, 0xae, + 0xaa, 0x8c, 0x5f, 0x3f, 0x41, 0x66, 0x95, 0xb2, 0xb9, 0xad, 0x99, 0x87, 0x78, 0x6c, 0x5e, 0x53, + 0x51, 0x60, 0x79, 0x92, 0xa0, 0x9e, 0x92, 0x86, 0x7b, 0x79, 0x7a, 0x79, 0x75, 0x6c, 0x65, 0x67, + 0x73, 0x88, 0x9d, 0xa8, 0xa6, 0x97, 0x7b, 0x63, 0x53, 0x54, 0x63, 0x7b, 0x93, 0xa3, 0xa7, 0x9d, + 0x8a, 0x75, 0x64, 0x5e, 0x63, 0x73, 0x88, 0x98, 0x9f, 0x9a, 0x8f, 0x80, 0x70, 0x64, 0x60, 0x66, + 0x72, 0x87, 0x97, 0x9d, 0x9a, 0x8a, 0x78, 0x6c, 0x69, 0x71, 0x7d, 0x86, 0x88, 0x84, 0x7e, 0x7b, + 0x7c, 0x7d, 0x7c, 0x7b, 0x7a, 0x7b, 0x7d, 0x80, 0x82, 0x84, 0x84, 0x82, 0x7e, 0x7b, 0x79, 0x7a, + 0x7a, 0x79, 0x79, 0x7a, 0x7c, 0x80, 0x87, 0x90, 0x93, 0x8d, 0x81, 0x71, 0x6c, 0x6f, 0x79, 0x88, + 0x91, 0x92, 0x8c, 0x83, 0x7d, 0x7c, 0x7d, 0x7b, 0x77, 0x75, 0x76, 0x7b, 0x84, 0x89, 0x89, 0x84, + 0x7b, 0x75, 0x74, 0x77, 0x80, 0x87, 0x8a, 0x89, 0x82, 0x7a, 0x76, 0x74, 0x76, 0x7b, 0x80, 0x82, + 0x80, 0x7e, 0x83, 0x89, 0x89, 0x85, 0x7c, 0x71, 0x6b, 0x6f, 0x7a, 0x87, 0x8c, 0x8a, 0x84, 0x7e, + 0x7a, 0x78, 0x78, 0x78, 0x7b, 0x81, 0x85, 0x86, 0x86, 0x83, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, + 0x7c, 0x7c, 0x7c, 0x7d, 0x80, 0x85, 0x87, 0x86, 0x7e, 0x72, 0x6d, 0x73, 0x7e, 0x8a, 0x8b, 0x88, + 0x84, 0x84, 0x8a, 0x8a, 0x7e, 0x6f, 0x61, 0x60, 0x6f, 0x86, 0x96, 0x95, 0x87, 0x79, 0x73, 0x7b, + 0x8a, 0x91, 0x8b, 0x7d, 0x72, 0x72, 0x78, 0x7b, 0x71, 0x5a, 0x47, 0x4a, 0x6e, 0xa4, 0xd5, 0xe1, + 0xbd, 0x7e, 0x42, 0x25, 0x2e, 0x53, 0x7d, 0x9d, 0xab, 0xaf, 0xb0, 0xaa, 0x9a, 0x82, 0x62, 0x47, + 0x42, 0x55, 0x7c, 0xa6, 0xc0, 0xc6, 0xb4, 0x8c, 0x5e, 0x3d, 0x32, 0x3e, 0x5d, 0x87, 0xad, 0xc1, + 0xbc, 0xa5, 0x86, 0x67, 0x51, 0x48, 0x4e, 0x62, 0x80, 0x9a, 0xb0, 0xb7, 0xaa, 0x8f, 0x6d, 0x53, + 0x4a, 0x50, 0x63, 0x81, 0x99, 0xa8, 0xab, 0xa1, 0x8d, 0x74, 0x5f, 0x54, 0x56, 0x63, 0x77, 0x8b, + 0x9a, 0xa1, 0x9e, 0x96, 0x8b, 0x7e, 0x74, 0x68, 0x5f, 0x60, 0x69, 0x7d, 0x94, 0xa3, 0xa7, 0x97, + 0x7c, 0x63, 0x55, 0x59, 0x6c, 0x8c, 0xa8, 0xb3, 0xac, 0x96, 0x76, 0x5e, 0x58, 0x61, 0x72, 0x81, + 0x89, 0x8b, 0x8b, 0x88, 0x83, 0x7a, 0x72, 0x70, 0x76, 0x7d, 0x81, 0x81, 0x80, 0x81, 0x87, 0x8d, + 0x8c, 0x83, 0x75, 0x6c, 0x6b, 0x74, 0x84, 0x92, 0x97, 0x8f, 0x83, 0x79, 0x74, 0x75, 0x79, 0x80, + 0x84, 0x85, 0x88, 0x89, 0x88, 0x85, 0x81, 0x7a, 0x74, 0x6c, 0x65, 0x63, 0x6e, 0x89, 0xa5, 0xb7, + 0xb1, 0x90, 0x66, 0x47, 0x41, 0x5a, 0x81, 0xa1, 0xab, 0xa0, 0x91, 0x84, 0x7c, 0x7a, 0x74, 0x6b, + 0x65, 0x66, 0x72, 0x86, 0x96, 0x9d, 0x9b, 0x92, 0x85, 0x72, 0x64, 0x5d, 0x60, 0x6f, 0x86, 0x99, + 0x9f, 0x97, 0x87, 0x76, 0x6e, 0x6e, 0x73, 0x78, 0x7d, 0x7e, 0x82, 0x86, 0x8a, 0x8b, 0x88, 0x81, + 0x7a, 0x78, 0x79, 0x7c, 0x80, 0x84, 0x87, 0x88, 0x86, 0x82, 0x7b, 0x76, 0x76, 0x79, 0x81, 0x88, + 0x8a, 0x86, 0x80, 0x79, 0x76, 0x76, 0x77, 0x7b, 0x81, 0x84, 0x88, 0x89, 0x87, 0x82, 0x7c, 0x77, + 0x77, 0x7a, 0x7e, 0x82, 0x86, 0x86, 0x86, 0x86, 0x85, 0x80, 0x78, 0x73, 0x74, 0x7b, 0x85, 0x89, + 0x8a, 0x87, 0x82, 0x81, 0x83, 0x88, 0x89, 0x81, 0x6d, 0x54, 0x3f, 0x42, 0x65, 0x9d, 0xd1, 0xec, + 0xda, 0xa0, 0x55, 0x20, 0x13, 0x32, 0x6a, 0xa0, 0xc8, 0xd6, 0xc6, 0xa8, 0x82, 0x60, 0x4b, 0x46, + 0x55, 0x6a, 0x81, 0x93, 0xa1, 0xa9, 0xa9, 0x9f, 0x8b, 0x6c, 0x4e, 0x3b, 0x3f, 0x5e, 0x87, 0xaa, + 0xbd, 0xb9, 0xa2, 0x80, 0x5e, 0x4b, 0x49, 0x57, 0x72, 0x92, 0xa8, 0xaf, 0xa7, 0x94, 0x7e, 0x6c, + 0x62, 0x62, 0x68, 0x73, 0x80, 0x8e, 0x9c, 0xa3, 0x9e, 0x8f, 0x79, 0x65, 0x5b, 0x5b, 0x65, 0x77, + 0x88, 0x95, 0x9c, 0x9a, 0x90, 0x80, 0x71, 0x6b, 0x6d, 0x76, 0x80, 0x85, 0x82, 0x7b, 0x78, 0x7a, + 0x83, 0x89, 0x89, 0x85, 0x82, 0x81, 0x83, 0x87, 0x89, 0x87, 0x82, 0x7c, 0x78, 0x76, 0x74, 0x73, + 0x72, 0x76, 0x7d, 0x86, 0x8a, 0x89, 0x82, 0x7a, 0x76, 0x74, 0x75, 0x79, 0x81, 0x89, 0x8b, 0x8a, + 0x85, 0x7c, 0x76, 0x74, 0x79, 0x82, 0x89, 0x8b, 0x89, 0x85, 0x81, 0x7e, 0x7c, 0x7d, 0x7d, 0x7d, + 0x80, 0x81, 0x82, 0x81, 0x7d, 0x7b, 0x7d, 0x81, 0x84, 0x87, 0x87, 0x82, 0x74, 0x68, 0x5f, 0x5f, + 0x6e, 0x8a, 0xa6, 0xb9, 0xb1, 0x92, 0x67, 0x46, 0x40, 0x57, 0x7b, 0x9d, 0xb0, 0xb2, 0xa3, 0x8c, + 0x74, 0x60, 0x57, 0x5b, 0x6d, 0x88, 0x9e, 0xa4, 0x98, 0x86, 0x77, 0x6f, 0x70, 0x76, 0x78, 0x77, + 0x77, 0x7a, 0x83, 0x8a, 0x8d, 0x8c, 0x86, 0x7e, 0x78, 0x71, 0x6c, 0x6d, 0x73, 0x7e, 0x8e, 0x99, + 0x98, 0x8e, 0x80, 0x73, 0x6c, 0x6e, 0x76, 0x80, 0x88, 0x8d, 0x8f, 0x8b, 0x84, 0x78, 0x70, 0x6f, + 0x76, 0x80, 0x89, 0x8d, 0x8b, 0x86, 0x81, 0x7c, 0x7a, 0x76, 0x75, 0x77, 0x7b, 0x82, 0x88, 0x8a, + 0x88, 0x84, 0x80, 0x7c, 0x78, 0x77, 0x78, 0x7c, 0x84, 0x8c, 0x91, 0x8e, 0x86, 0x7a, 0x71, 0x6d, + 0x72, 0x7a, 0x84, 0x8d, 0x93, 0x93, 0x8e, 0x83, 0x70, 0x58, 0x42, 0x3d, 0x51, 0x7b, 0xae, 0xd1, + 0xdd, 0xc6, 0x92, 0x5a, 0x2e, 0x1d, 0x2a, 0x56, 0x94, 0xcb, 0xeb, 0xe7, 0xc1, 0x83, 0x48, 0x24, + 0x23, 0x40, 0x6f, 0x9d, 0xbc, 0xc7, 0xbb, 0x9e, 0x7a, 0x5b, 0x47, 0x45, 0x55, 0x6d, 0x84, 0x96, + 0x9f, 0xa1, 0x9c, 0x92, 0x84, 0x71, 0x5f, 0x56, 0x5a, 0x66, 0x7b, 0x92, 0xa2, 0xad, 0xa9, 0x98, + 0x80, 0x66, 0x57, 0x53, 0x5e, 0x76, 0x93, 0xa7, 0xad, 0xa5, 0x91, 0x77, 0x61, 0x55, 0x56, 0x64, + 0x7a, 0x90, 0x9f, 0xa0, 0x95, 0x86, 0x78, 0x70, 0x6f, 0x71, 0x75, 0x79, 0x7c, 0x80, 0x82, 0x83, + 0x86, 0x8a, 0x8d, 0x8d, 0x88, 0x7d, 0x74, 0x6e, 0x6f, 0x7a, 0x8d, 0x9a, 0x9e, 0x97, 0x87, 0x72, + 0x5f, 0x58, 0x5e, 0x70, 0x88, 0x9c, 0xa8, 0xa2, 0x8c, 0x6f, 0x5a, 0x55, 0x5f, 0x74, 0x8d, 0xa2, + 0xa8, 0x9d, 0x88, 0x70, 0x60, 0x5c, 0x65, 0x7a, 0x90, 0x9e, 0xa2, 0x99, 0x8a, 0x7a, 0x6e, 0x69, + 0x6f, 0x79, 0x84, 0x8c, 0x8d, 0x89, 0x83, 0x7d, 0x7c, 0x7c, 0x80, 0x81, 0x80, 0x79, 0x6f, 0x67, + 0x65, 0x6c, 0x7e, 0x94, 0xa5, 0xa9, 0x9b, 0x81, 0x64, 0x50, 0x4e, 0x61, 0x80, 0x9f, 0xb2, 0xb2, + 0xa5, 0x8d, 0x6e, 0x56, 0x4e, 0x56, 0x6e, 0x8e, 0xa7, 0xb0, 0xa7, 0x92, 0x78, 0x65, 0x5b, 0x5d, + 0x69, 0x78, 0x89, 0x95, 0x9a, 0x93, 0x86, 0x77, 0x70, 0x6f, 0x73, 0x78, 0x7b, 0x7d, 0x7e, 0x81, + 0x84, 0x86, 0x88, 0x89, 0x87, 0x84, 0x7d, 0x76, 0x72, 0x72, 0x77, 0x7e, 0x8a, 0x90, 0x90, 0x8b, + 0x80, 0x76, 0x71, 0x6e, 0x72, 0x7a, 0x85, 0x8e, 0x90, 0x8c, 0x83, 0x76, 0x6e, 0x6c, 0x71, 0x79, + 0x84, 0x8c, 0x90, 0x8e, 0x88, 0x7e, 0x76, 0x71, 0x72, 0x78, 0x81, 0x87, 0x88, 0x87, 0x83, 0x80, + 0x7e, 0x7c, 0x7c, 0x7c, 0x7d, 0x81, 0x86, 0x87, 0x7e, 0x6e, 0x5d, 0x54, 0x5a, 0x71, 0x92, 0xb0, + 0xc0, 0xba, 0xa0, 0x7c, 0x56, 0x3b, 0x37, 0x48, 0x72, 0xa5, 0xcd, 0xdd, 0xcd, 0xa2, 0x6d, 0x40, + 0x29, 0x2e, 0x4c, 0x7c, 0xab, 0xcc, 0xd3, 0xbc, 0x93, 0x63, 0x41, 0x35, 0x3e, 0x5c, 0x81, 0xa0, + 0xb3, 0xb5, 0xa7, 0x8d, 0x72, 0x5f, 0x56, 0x5c, 0x6a, 0x7b, 0x8b, 0x94, 0x98, 0x97, 0x91, 0x88, + 0x7e, 0x75, 0x6f, 0x6e, 0x73, 0x78, 0x80, 0x88, 0x90, 0x96, 0x96, 0x8e, 0x82, 0x73, 0x67, 0x62, + 0x65, 0x71, 0x80, 0x8d, 0x9a, 0x9e, 0x97, 0x8a, 0x76, 0x67, 0x5f, 0x60, 0x6b, 0x7a, 0x89, 0x93, + 0x98, 0x95, 0x8e, 0x83, 0x78, 0x71, 0x6d, 0x6d, 0x73, 0x7c, 0x87, 0x90, 0x97, 0x99, 0x93, 0x88, + 0x77, 0x69, 0x62, 0x61, 0x6a, 0x77, 0x86, 0x92, 0x97, 0x94, 0x8a, 0x7a, 0x6e, 0x69, 0x6b, 0x74, + 0x80, 0x89, 0x8e, 0x8d, 0x8a, 0x83, 0x7b, 0x78, 0x76, 0x79, 0x7e, 0x83, 0x87, 0x88, 0x85, 0x82, + 0x7e, 0x7e, 0x82, 0x83, 0x83, 0x83, 0x82, 0x7e, 0x7a, 0x76, 0x73, 0x73, 0x75, 0x7c, 0x85, 0x8e, + 0x94, 0x92, 0x87, 0x77, 0x69, 0x63, 0x66, 0x71, 0x82, 0x92, 0x9c, 0x9b, 0x92, 0x85, 0x73, 0x66, + 0x62, 0x68, 0x78, 0x8a, 0x96, 0x9c, 0x98, 0x8c, 0x7d, 0x6e, 0x66, 0x67, 0x6f, 0x7c, 0x8b, 0x94, + 0x95, 0x90, 0x85, 0x78, 0x70, 0x6d, 0x70, 0x76, 0x7d, 0x83, 0x86, 0x86, 0x85, 0x84, 0x83, 0x82, + 0x82, 0x81, 0x7e, 0x7c, 0x79, 0x78, 0x79, 0x79, 0x7c, 0x81, 0x85, 0x88, 0x88, 0x86, 0x82, 0x7c, + 0x78, 0x76, 0x77, 0x7a, 0x80, 0x83, 0x84, 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x7d, 0x7e, 0x80, + 0x81, 0x7e, 0x7c, 0x7a, 0x7b, 0x7d, 0x81, 0x85, 0x86, 0x85, 0x82, 0x7c, 0x78, 0x77, 0x7a, 0x82, + 0x8a, 0x8e, 0x89, 0x79, 0x65, 0x54, 0x4e, 0x5c, 0x78, 0x9d, 0xbd, 0xcb, 0xc2, 0xa1, 0x74, 0x46, + 0x24, 0x23, 0x3f, 0x74, 0xb2, 0xde, 0xf0, 0xdc, 0xa9, 0x6c, 0x35, 0x13, 0x10, 0x35, 0x70, 0xac, + 0xdc, 0xee, 0xd7, 0xa6, 0x6b, 0x39, 0x1b, 0x1d, 0x3c, 0x6e, 0xa5, 0xca, 0xd6, 0xc8, 0xa3, 0x74, + 0x51, 0x3b, 0x3b, 0x51, 0x72, 0x94, 0xad, 0xb8, 0xad, 0x96, 0x7c, 0x65, 0x5c, 0x5e, 0x68, 0x78, + 0x88, 0x94, 0x9a, 0x97, 0x8d, 0x80, 0x74, 0x6e, 0x6d, 0x6d, 0x6f, 0x70, 0x72, 0x79, 0x84, 0x8c, + 0x93, 0x94, 0x90, 0x86, 0x77, 0x69, 0x5d, 0x5a, 0x5f, 0x70, 0x87, 0x9c, 0xa9, 0xaa, 0x9e, 0x8b, + 0x73, 0x5e, 0x55, 0x58, 0x68, 0x83, 0x9c, 0xad, 0xb0, 0xa1, 0x89, 0x6d, 0x57, 0x4c, 0x52, 0x65, + 0x81, 0x9b, 0xac, 0xae, 0x9f, 0x87, 0x6c, 0x58, 0x51, 0x59, 0x6b, 0x83, 0x9a, 0xa7, 0xa7, 0x9c, + 0x87, 0x70, 0x60, 0x59, 0x5b, 0x64, 0x74, 0x88, 0x9b, 0xaa, 0xaf, 0xa7, 0x94, 0x7b, 0x65, 0x56, + 0x4f, 0x55, 0x69, 0x86, 0xa3, 0xb8, 0xbc, 0xaf, 0x93, 0x73, 0x56, 0x44, 0x43, 0x52, 0x6e, 0x92, + 0xaf, 0xbd, 0xb8, 0xa2, 0x82, 0x61, 0x4b, 0x43, 0x4d, 0x65, 0x83, 0xa0, 0xb3, 0xb4, 0xa6, 0x8c, + 0x6f, 0x5a, 0x52, 0x57, 0x65, 0x7c, 0x95, 0xa6, 0xac, 0xa4, 0x91, 0x79, 0x66, 0x5c, 0x5f, 0x6b, + 0x7a, 0x8b, 0x98, 0x9c, 0x99, 0x8e, 0x7e, 0x72, 0x6a, 0x6a, 0x6f, 0x77, 0x7e, 0x86, 0x8b, 0x8c, + 0x8a, 0x85, 0x7e, 0x79, 0x76, 0x75, 0x76, 0x78, 0x7b, 0x82, 0x87, 0x8a, 0x8b, 0x88, 0x84, 0x7e, + 0x79, 0x74, 0x71, 0x72, 0x77, 0x81, 0x8a, 0x8f, 0x90, 0x8b, 0x82, 0x78, 0x72, 0x71, 0x74, 0x7b, + 0x84, 0x88, 0x85, 0x79, 0x69, 0x5c, 0x5a, 0x66, 0x80, 0x9d, 0xb4, 0xbf, 0xb5, 0x9b, 0x75, 0x4d, + 0x33, 0x2f, 0x47, 0x75, 0xa8, 0xd4, 0xe7, 0xdb, 0xb7, 0x7e, 0x44, 0x1e, 0x14, 0x29, 0x5d, 0x9b, + 0xd2, 0xed, 0xe5, 0xc0, 0x87, 0x4b, 0x20, 0x10, 0x22, 0x4f, 0x88, 0xbc, 0xdb, 0xdc, 0xc0, 0x90, + 0x5e, 0x39, 0x26, 0x33, 0x53, 0x7e, 0xac, 0xc7, 0xcc, 0xbb, 0x99, 0x74, 0x56, 0x47, 0x49, 0x5b, + 0x76, 0x93, 0xa8, 0xaf, 0xa8, 0x96, 0x81, 0x6c, 0x5f, 0x5b, 0x5f, 0x6b, 0x7b, 0x8c, 0x97, 0x9a, + 0x97, 0x8f, 0x85, 0x78, 0x6e, 0x66, 0x64, 0x67, 0x70, 0x7d, 0x8c, 0x96, 0x9b, 0x99, 0x91, 0x83, + 0x73, 0x66, 0x5e, 0x61, 0x6e, 0x83, 0x96, 0xa5, 0xa8, 0xa0, 0x8e, 0x76, 0x60, 0x51, 0x51, 0x5e, + 0x75, 0x93, 0xaa, 0xb1, 0xa8, 0x94, 0x74, 0x58, 0x48, 0x49, 0x5c, 0x7c, 0x9d, 0xb5, 0xba, 0xa8, + 0x86, 0x5d, 0x42, 0x38, 0x47, 0x6b, 0x9a, 0xc3, 0xd8, 0xcf, 0xad, 0x78, 0x47, 0x28, 0x22, 0x3d, + 0x6b, 0xa4, 0xd3, 0xe6, 0xda, 0xb5, 0x7b, 0x43, 0x1e, 0x17, 0x30, 0x61, 0x99, 0xc9, 0xe0, 0xd9, + 0xb8, 0x85, 0x4d, 0x29, 0x20, 0x34, 0x5e, 0x8f, 0xba, 0xd1, 0xd0, 0xb6, 0x8c, 0x61, 0x40, 0x35, + 0x41, 0x5f, 0x85, 0xa5, 0xba, 0xbb, 0xa9, 0x8c, 0x6f, 0x58, 0x4e, 0x53, 0x65, 0x7e, 0x97, 0xa2, + 0xa4, 0x9a, 0x88, 0x77, 0x68, 0x63, 0x68, 0x72, 0x81, 0x8c, 0x90, 0x8e, 0x86, 0x7b, 0x75, 0x73, + 0x75, 0x7b, 0x84, 0x89, 0x8a, 0x86, 0x7d, 0x74, 0x6f, 0x6f, 0x76, 0x82, 0x8e, 0x97, 0x9a, 0x94, + 0x89, 0x7a, 0x6e, 0x66, 0x66, 0x6f, 0x7e, 0x8d, 0x99, 0x9d, 0x99, 0x8e, 0x81, 0x70, 0x60, 0x53, + 0x4d, 0x53, 0x64, 0x7e, 0x9b, 0xb2, 0xbe, 0xba, 0xa7, 0x89, 0x63, 0x42, 0x2f, 0x34, 0x50, 0x78, + 0xa8, 0xcf, 0xe0, 0xdb, 0xbb, 0x8c, 0x56, 0x2c, 0x1a, 0x22, 0x46, 0x79, 0xac, 0xd2, 0xe4, 0xd7, + 0xb2, 0x80, 0x4c, 0x28, 0x1a, 0x27, 0x4b, 0x7b, 0xab, 0xcb, 0xd5, 0xc5, 0xa3, 0x78, 0x50, 0x36, + 0x30, 0x41, 0x60, 0x87, 0xa7, 0xbc, 0xbf, 0xb0, 0x95, 0x76, 0x5d, 0x51, 0x51, 0x5e, 0x72, 0x86, + 0x97, 0xa0, 0xa0, 0x98, 0x8a, 0x7b, 0x6f, 0x66, 0x65, 0x69, 0x71, 0x7b, 0x85, 0x8e, 0x93, 0x93, + 0x90, 0x89, 0x80, 0x76, 0x6f, 0x6b, 0x6b, 0x6f, 0x76, 0x81, 0x8a, 0x91, 0x95, 0x94, 0x8e, 0x85, + 0x7a, 0x71, 0x6d, 0x6e, 0x72, 0x79, 0x81, 0x86, 0x88, 0x87, 0x83, 0x7e, 0x7b, 0x78, 0x79, 0x7b, + 0x7e, 0x81, 0x82, 0x81, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x80, 0x83, 0x83, 0x81, 0x7a, 0x74, 0x70, + 0x72, 0x78, 0x82, 0x8c, 0x94, 0x99, 0x97, 0x8e, 0x7e, 0x6f, 0x62, 0x5e, 0x64, 0x72, 0x87, 0x98, + 0xa4, 0xa7, 0x9e, 0x8d, 0x77, 0x63, 0x56, 0x55, 0x5f, 0x72, 0x87, 0x9a, 0xa7, 0xa8, 0x9f, 0x8d, + 0x76, 0x62, 0x57, 0x58, 0x62, 0x72, 0x88, 0x97, 0xa0, 0xa0, 0x97, 0x88, 0x78, 0x6b, 0x64, 0x64, + 0x6b, 0x75, 0x83, 0x8c, 0x92, 0x95, 0x91, 0x8a, 0x82, 0x79, 0x74, 0x72, 0x73, 0x75, 0x7a, 0x7d, + 0x83, 0x86, 0x87, 0x88, 0x89, 0x89, 0x89, 0x88, 0x84, 0x7d, 0x77, 0x72, 0x70, 0x71, 0x77, 0x80, + 0x8a, 0x91, 0x96, 0x95, 0x8d, 0x82, 0x76, 0x6c, 0x66, 0x67, 0x70, 0x7c, 0x8a, 0x96, 0x9b, 0x99, + 0x90, 0x84, 0x75, 0x69, 0x64, 0x65, 0x6d, 0x7b, 0x8c, 0x98, 0x9b, 0x93, 0x80, 0x67, 0x52, 0x47, + 0x4b, 0x61, 0x82, 0xa5, 0xc2, 0xcb, 0xc1, 0xa4, 0x7b, 0x51, 0x35, 0x2e, 0x3b, 0x5b, 0x87, 0xb1, + 0xd1, 0xdc, 0xcf, 0xae, 0x84, 0x5a, 0x3b, 0x2f, 0x36, 0x50, 0x75, 0x9a, 0xb8, 0xc5, 0xbe, 0xa9, + 0x8b, 0x6b, 0x54, 0x48, 0x49, 0x57, 0x6b, 0x83, 0x95, 0x9d, 0x9c, 0x96, 0x8b, 0x80, 0x78, 0x74, + 0x72, 0x74, 0x76, 0x79, 0x7a, 0x7a, 0x7b, 0x7d, 0x82, 0x88, 0x8e, 0x92, 0x93, 0x91, 0x8b, 0x81, + 0x73, 0x67, 0x5f, 0x5f, 0x68, 0x79, 0x8d, 0x9e, 0xa9, 0xaa, 0x9f, 0x8a, 0x72, 0x5d, 0x52, 0x52, + 0x5e, 0x71, 0x84, 0x94, 0x9e, 0xa0, 0x9b, 0x8e, 0x7e, 0x71, 0x6b, 0x6d, 0x74, 0x7e, 0x89, 0x91, + 0x93, 0x8f, 0x84, 0x75, 0x68, 0x64, 0x68, 0x72, 0x80, 0x8d, 0x94, 0x94, 0x8e, 0x82, 0x73, 0x68, + 0x63, 0x68, 0x72, 0x80, 0x8d, 0x95, 0x98, 0x95, 0x8d, 0x80, 0x6f, 0x60, 0x58, 0x59, 0x62, 0x71, + 0x85, 0x96, 0xa2, 0xaa, 0xa9, 0xa0, 0x90, 0x7d, 0x6c, 0x5f, 0x5b, 0x5f, 0x6a, 0x78, 0x88, 0x95, + 0x9e, 0x9f, 0x9a, 0x91, 0x84, 0x79, 0x71, 0x6d, 0x6d, 0x71, 0x76, 0x7a, 0x7c, 0x7d, 0x7d, 0x7e, + 0x83, 0x87, 0x89, 0x8a, 0x88, 0x84, 0x7e, 0x79, 0x73, 0x6e, 0x6e, 0x71, 0x77, 0x7d, 0x84, 0x89, + 0x8d, 0x8d, 0x8b, 0x86, 0x81, 0x7c, 0x7a, 0x7a, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x82, + 0x84, 0x82, 0x80, 0x7b, 0x77, 0x75, 0x74, 0x77, 0x80, 0x8a, 0x93, 0x98, 0x95, 0x8d, 0x81, 0x73, + 0x68, 0x63, 0x64, 0x6b, 0x78, 0x87, 0x92, 0x97, 0x95, 0x90, 0x87, 0x7d, 0x76, 0x72, 0x74, 0x79, + 0x80, 0x85, 0x87, 0x86, 0x84, 0x81, 0x7b, 0x7a, 0x7b, 0x80, 0x84, 0x85, 0x7e, 0x72, 0x66, 0x5f, + 0x5e, 0x67, 0x76, 0x88, 0x99, 0xa5, 0xa9, 0xa3, 0x94, 0x81, 0x6f, 0x63, 0x5f, 0x62, 0x6b, 0x76, + 0x82, 0x8a, 0x8d, 0x8b, 0x88, 0x82, 0x7d, 0x7c, 0x7e, 0x82, 0x86, 0x89, 0x89, 0x84, 0x7d, 0x76, + 0x71, 0x6f, 0x70, 0x75, 0x7b, 0x83, 0x88, 0x8b, 0x8b, 0x88, 0x83, 0x7d, 0x79, 0x76, 0x75, 0x77, + 0x7a, 0x7d, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x80, 0x7e, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x7d, + 0x80, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x79, 0x78, 0x78, 0x7b, 0x7e, 0x83, 0x86, 0x86, 0x85, + 0x82, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x85, 0x83, 0x81, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x83, 0x83, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7a, 0x79, 0x79, + 0x7a, 0x7c, 0x80, 0x82, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x83, 0x82, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x82, 0x82, 0x81, 0x7e, + 0x7d, 0x7c, 0x7d, 0x7e, 0x81, 0x83, 0x83, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x7e, + 0x81, 0x84, 0x85, 0x85, 0x84, 0x82, 0x7e, 0x7c, 0x7a, 0x7a, 0x7b, 0x7e, 0x82, 0x85, 0x86, 0x84, + 0x81, 0x7c, 0x79, 0x79, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7e, 0x81, + 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7c, 0x7b, 0x7b, + 0x7b, 0x7c, 0x80, 0x83, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, + 0x81, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x82, 0x81, 0x7e, + 0x7c, 0x7b, 0x7b, 0x7b, 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x85, 0x84, 0x83, 0x82, 0x7e, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, + 0x83, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7e, 0x82, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7c, 0x7a, + 0x7a, 0x7a, 0x7b, 0x7e, 0x82, 0x84, 0x85, 0x85, 0x83, 0x82, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x82, 0x84, 0x85, 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x80, 0x84, 0x86, + 0x85, 0x83, 0x7e, 0x7c, 0x7b, 0x7a, 0x7a, 0x7d, 0x81, 0x84, 0x86, 0x88, 0x87, 0x83, 0x7e, 0x79, + 0x77, 0x77, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x85, 0x83, 0x80, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, + 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x82, 0x83, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, + 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7b, 0x80, 0x83, 0x84, 0x85, + 0x84, 0x81, 0x7d, 0x7b, 0x7a, 0x7b, 0x7e, 0x82, 0x85, 0x85, 0x83, 0x80, 0x7b, 0x78, 0x77, 0x78, + 0x7c, 0x80, 0x84, 0x86, 0x85, 0x84, 0x80, 0x7c, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, 0x82, 0x83, 0x83, + 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x80, + 0x81, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x83, 0x83, 0x83, 0x81, + 0x7d, 0x7b, 0x7b, 0x7b, 0x7c, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, + 0x80, 0x82, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x82, 0x82, 0x82, 0x82, + 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x80, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x83, 0x82, 0x7f, 0x7c, 0x7a, 0x78, 0x79, 0x7b, + 0x7d, 0x80, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x79, 0x78, 0x79, 0x7b, 0x7e, 0x82, 0x84, + 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7d, 0x80, 0x83, 0x84, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, + 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7c, + 0x7b, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, + 0x7d, 0x80, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7b, 0x7a, 0x79, 0x79, 0x7b, 0x7d, 0x80, 0x81, 0x82, + 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x80, 0x7d, 0x7c, 0x7b, 0x7a, 0x7b, 0x7d, 0x7e, 0x80, + 0x82, 0x83, 0x85, 0x85, 0x83, 0x80, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, + 0x83, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83, 0x83, 0x83, 0x82, 0x7e, 0x7c, 0x7a, 0x79, 0x7b, + 0x7d, 0x82, 0x84, 0x84, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x84, 0x84, 0x82, + 0x80, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x83, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, + 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7e, 0x80, 0x82, 0x83, 0x83, 0x82, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x85, 0x88, 0x86, 0x82, 0x7c, 0x78, + 0x77, 0x7a, 0x7d, 0x81, 0x84, 0x87, 0x89, 0x87, 0x82, 0x7b, 0x79, 0x79, 0x7b, 0x7d, 0x7e, 0x80, + 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, + 0x81, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, + 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x7e, + 0x7d, 0x7c, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, + 0x81, 0x82, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x83, 0x81, 0x7d, + 0x7b, 0x7a, 0x7b, 0x7c, 0x80, 0x82, 0x84, 0x84, 0x83, 0x81, 0x7e, 0x7c, 0x7b, 0x7b, 0x7c, 0x7e, + 0x81, 0x83, 0x83, 0x83, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x83, 0x83, 0x82, 0x80, + 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7d, 0x7c, + 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x83, + 0x83, 0x80, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7e, 0x7d, + 0x7e, 0x80, 0x81, 0x81, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, + 0x7c, 0x7d, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, + 0x81, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x83, 0x82, 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x82, 0x83, + 0x83, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x83, 0x84, 0x83, 0x81, 0x7e, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x7e, + 0x7c, 0x7a, 0x78, 0x79, 0x80, 0x88, 0x8d, 0x8d, 0x86, 0x7b, 0x71, 0x6c, 0x6d, 0x73, 0x7b, 0x85, + 0x8c, 0x8e, 0x8d, 0x87, 0x80, 0x77, 0x71, 0x70, 0x72, 0x77, 0x7e, 0x86, 0x8a, 0x8c, 0x8b, 0x86, + 0x80, 0x79, 0x77, 0x75, 0x77, 0x7b, 0x7e, 0x83, 0x86, 0x87, 0x87, 0x85, 0x83, 0x7e, 0x78, 0x75, + 0x76, 0x7a, 0x81, 0x85, 0x88, 0x89, 0x86, 0x83, 0x7e, 0x7b, 0x78, 0x78, 0x7a, 0x7c, 0x80, 0x83, + 0x85, 0x85, 0x84, 0x82, 0x7e, 0x7c, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x80, 0x7c, + 0x7a, 0x79, 0x79, 0x7a, 0x7d, 0x81, 0x85, 0x87, 0x88, 0x85, 0x80, 0x7a, 0x74, 0x71, 0x73, 0x79, + 0x80, 0x85, 0x88, 0x8a, 0x88, 0x84, 0x80, 0x7b, 0x78, 0x75, 0x75, 0x76, 0x7b, 0x81, 0x86, 0x89, + 0x89, 0x86, 0x81, 0x7b, 0x76, 0x73, 0x74, 0x79, 0x7e, 0x86, 0x8a, 0x8c, 0x88, 0x83, 0x7d, 0x79, + 0x78, 0x7c, 0x80, 0x82, 0x82, 0x80, 0x7c, 0x7b, 0x7a, 0x7c, 0x80, 0x83, 0x85, 0x85, 0x82, 0x7c, + 0x78, 0x76, 0x79, 0x7c, 0x80, 0x83, 0x83, 0x83, 0x82, 0x80, 0x7c, 0x7a, 0x7a, 0x7b, 0x7e, 0x81, + 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x82, 0x84, 0x84, 0x83, 0x80, 0x7d, + 0x7b, 0x7b, 0x7e, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7d, 0x80, 0x83, 0x85, 0x84, 0x82, + 0x7e, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x81, 0x81, 0x80, 0x81, 0x7e, 0x7b, + 0x79, 0x77, 0x78, 0x7a, 0x7d, 0x82, 0x85, 0x86, 0x85, 0x83, 0x80, 0x7c, 0x79, 0x77, 0x79, 0x7c, + 0x82, 0x85, 0x86, 0x85, 0x82, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, + 0x7d, 0x7e, 0x80, 0x83, 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7a, 0x7c, 0x80, 0x83, 0x85, + 0x85, 0x84, 0x82, 0x7e, 0x7c, 0x7a, 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x82, 0x83, 0x83, 0x82, 0x80, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x84, 0x83, 0x81, 0x7d, 0x7c, 0x7c, + 0x7b, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7b, 0x79, 0x7a, 0x7b, 0x7c, + 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x80, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, + 0x80, 0x81, 0x82, 0x82, 0x80, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x80, 0x83, 0x83, 0x83, 0x82, 0x80, + 0x7d, 0x7b, 0x7a, 0x79, 0x7b, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7c, 0x7a, + 0x79, 0x7a, 0x7b, 0x7d, 0x81, 0x83, 0x84, 0x84, 0x83, 0x81, 0x7c, 0x7a, 0x78, 0x78, 0x7a, 0x7d, + 0x81, 0x84, 0x85, 0x85, 0x84, 0x81, 0x7d, 0x7a, 0x79, 0x7a, 0x7b, 0x7e, 0x82, 0x83, 0x85, 0x85, + 0x83, 0x81, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x81, + 0x81, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x7d, 0x7c, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7e, 0x81, 0x82, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, + 0x81, 0x82, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x81, + 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7e, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x82, 0x82, + 0x82, 0x81, 0x80, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7d, + 0x7d, 0x7d, 0x80, 0x82, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x82, + 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7c, + 0x7c, 0x7d, 0x80, 0x80, 0x81, 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x7d, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7b, 0x7d, 0x81, 0x83, + 0x84, 0x84, 0x83, 0x7e, 0x7c, 0x7a, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x83, 0x81, 0x7e, 0x7d, 0x7d, + 0x7e, 0x80, 0x82, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x83, + 0x83, 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7c, 0x7c, + 0x7e, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7a, 0x7b, 0x7d, 0x82, 0x85, + 0x87, 0x87, 0x84, 0x81, 0x7d, 0x7a, 0x78, 0x78, 0x79, 0x7e, 0x83, 0x87, 0x89, 0x88, 0x84, 0x80, + 0x7a, 0x77, 0x76, 0x77, 0x7a, 0x7e, 0x83, 0x86, 0x87, 0x86, 0x83, 0x7d, 0x7a, 0x78, 0x78, 0x7a, + 0x7d, 0x81, 0x83, 0x84, 0x84, 0x84, 0x82, 0x7e, 0x7b, 0x79, 0x77, 0x78, 0x7c, 0x80, 0x84, 0x86, + 0x86, 0x83, 0x7e, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x85, 0x86, 0x84, 0x82, 0x80, 0x7d, 0x7c, + 0x7d, 0x7d, 0x7e, 0x81, 0x83, 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7e, 0x81, 0x81, 0x81, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x82, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x81, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x80, 0x81, + 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7d, 0x7e, 0x81, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7e, 0x81, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x79, 0x76, 0x76, 0x79, 0x7e, 0x84, 0x87, 0x86, 0x83, + 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x83, 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, + 0x7d, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7e, + 0x81, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, + 0x7e, 0x7d, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x80, 0x81, + 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, + 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, + 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, + 0x81, 0x81, 0x7e, 0x7b, 0x78, 0x77, 0x78, 0x7c, 0x82, 0x87, 0x88, 0x86, 0x81, 0x79, 0x74, 0x71, + 0x73, 0x7a, 0x83, 0x89, 0x8e, 0x8e, 0x87, 0x7e, 0x76, 0x72, 0x73, 0x78, 0x7e, 0x86, 0x88, 0x88, + 0x84, 0x81, 0x7d, 0x7a, 0x7a, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x7e, 0x7b, 0x79, 0x77, 0x79, 0x7c, 0x81, 0x85, 0x87, 0x86, 0x82, 0x7c, 0x78, 0x78, 0x7b, 0x81, + 0x85, 0x87, 0x85, 0x81, 0x7b, 0x77, 0x76, 0x78, 0x7b, 0x82, 0x86, 0x88, 0x87, 0x83, 0x7c, 0x78, + 0x76, 0x76, 0x7b, 0x81, 0x86, 0x8a, 0x8a, 0x87, 0x81, 0x7a, 0x75, 0x72, 0x73, 0x78, 0x80, 0x87, + 0x8a, 0x89, 0x84, 0x7c, 0x77, 0x75, 0x76, 0x7a, 0x80, 0x84, 0x86, 0x85, 0x82, 0x7d, 0x7c, 0x7b, + 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x83, 0x80, 0x7b, 0x78, 0x76, 0x77, 0x7b, 0x82, + 0x87, 0x89, 0x86, 0x81, 0x7a, 0x77, 0x76, 0x78, 0x7d, 0x82, 0x84, 0x83, 0x80, 0x7d, 0x7a, 0x7a, + 0x7c, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x82, 0x81, 0x7d, 0x79, 0x77, 0x77, 0x7c, 0x82, 0x83, 0x83, + 0x81, 0x7e, 0x7d, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x83, 0x86, 0x86, 0x87, 0x85, 0x81, 0x7c, 0x79, + 0x75, 0x75, 0x78, 0x80, 0x86, 0x8a, 0x88, 0x81, 0x78, 0x74, 0x77, 0x7d, 0x84, 0x87, 0x86, 0x83, + 0x7d, 0x79, 0x74, 0x72, 0x74, 0x78, 0x80, 0x85, 0x89, 0x8b, 0x8a, 0x85, 0x7d, 0x74, 0x70, 0x71, + 0x77, 0x82, 0x8c, 0x8f, 0x8d, 0x8a, 0x85, 0x7e, 0x75, 0x6e, 0x6d, 0x76, 0x83, 0x8f, 0x95, 0x93, + 0x8c, 0x7d, 0x6c, 0x61, 0x65, 0x77, 0x8b, 0x95, 0x91, 0x87, 0x80, 0x80, 0x81, 0x7c, 0x74, 0x6e, + 0x72, 0x7e, 0x8c, 0x96, 0x93, 0x88, 0x7e, 0x79, 0x7a, 0x7e, 0x82, 0x80, 0x7d, 0x7b, 0x7c, 0x81, + 0x84, 0x83, 0x80, 0x7b, 0x7c, 0x81, 0x83, 0x85, 0x84, 0x81, 0x7b, 0x7a, 0x7d, 0x82, 0x85, 0x85, + 0x80, 0x7c, 0x7b, 0x7b, 0x7d, 0x7b, 0x78, 0x77, 0x7b, 0x84, 0x8a, 0x8a, 0x85, 0x7d, 0x78, 0x75, + 0x76, 0x77, 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x84, 0x86, 0x85, 0x80, 0x79, 0x75, 0x75, 0x79, 0x7d, + 0x81, 0x82, 0x7e, 0x7d, 0x7e, 0x81, 0x83, 0x81, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x7d, 0x7b, 0x7a, + 0x7a, 0x7b, 0x80, 0x85, 0x85, 0x85, 0x83, 0x81, 0x7e, 0x78, 0x75, 0x74, 0x76, 0x7b, 0x83, 0x88, + 0x89, 0x86, 0x84, 0x82, 0x7e, 0x7a, 0x74, 0x72, 0x76, 0x7e, 0x85, 0x87, 0x86, 0x86, 0x85, 0x84, + 0x81, 0x7c, 0x79, 0x7a, 0x7c, 0x7e, 0x82, 0x82, 0x84, 0x85, 0x85, 0x83, 0x81, 0x80, 0x7c, 0x79, + 0x78, 0x7a, 0x80, 0x84, 0x87, 0x89, 0x85, 0x80, 0x7c, 0x7b, 0x7d, 0x80, 0x7d, 0x7a, 0x79, 0x7c, + 0x83, 0x8a, 0x8c, 0x8b, 0x85, 0x7c, 0x77, 0x77, 0x79, 0x79, 0x7c, 0x81, 0x86, 0x8d, 0x8e, 0x88, + 0x81, 0x78, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x81, 0x84, 0x86, 0x84, 0x81, 0x7d, 0x7b, 0x7b, + 0x7d, 0x7c, 0x7a, 0x78, 0x7a, 0x7c, 0x83, 0x86, 0x85, 0x85, 0x81, 0x7b, 0x76, 0x73, 0x75, 0x79, + 0x7e, 0x83, 0x86, 0x88, 0x86, 0x81, 0x7b, 0x77, 0x7a, 0x81, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x7d, + 0x81, 0x83, 0x84, 0x84, 0x84, 0x85, 0x86, 0x85, 0x81, 0x7d, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x7b, + 0x7e, 0x85, 0x8b, 0x8e, 0x8e, 0x89, 0x7e, 0x72, 0x6b, 0x67, 0x6c, 0x74, 0x7d, 0x89, 0x92, 0x97, + 0x94, 0x8c, 0x81, 0x75, 0x6c, 0x6a, 0x6c, 0x73, 0x7c, 0x87, 0x8f, 0x92, 0x90, 0x8b, 0x82, 0x75, + 0x71, 0x73, 0x78, 0x7d, 0x7e, 0x81, 0x85, 0x88, 0x89, 0x88, 0x81, 0x79, 0x75, 0x78, 0x81, 0x8c, + 0x92, 0x8f, 0x84, 0x75, 0x6d, 0x6d, 0x72, 0x7b, 0x88, 0x91, 0x93, 0x8e, 0x83, 0x78, 0x74, 0x74, + 0x77, 0x7b, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x89, 0x8d, 0x8a, 0x83, 0x7b, 0x76, 0x75, 0x75, 0x7a, + 0x80, 0x82, 0x81, 0x81, 0x85, 0x89, 0x8b, 0x87, 0x7d, 0x76, 0x74, 0x76, 0x79, 0x7d, 0x80, 0x82, + 0x83, 0x85, 0x8a, 0x8b, 0x84, 0x7b, 0x72, 0x70, 0x74, 0x78, 0x7e, 0x83, 0x84, 0x85, 0x85, 0x85, + 0x87, 0x85, 0x7d, 0x75, 0x71, 0x74, 0x79, 0x80, 0x85, 0x86, 0x83, 0x7d, 0x7c, 0x7c, 0x80, 0x82, + 0x83, 0x81, 0x7b, 0x78, 0x76, 0x76, 0x7b, 0x81, 0x85, 0x8a, 0x8e, 0x8e, 0x8a, 0x7c, 0x6d, 0x63, + 0x60, 0x6d, 0x81, 0x91, 0x9c, 0x9c, 0x92, 0x85, 0x75, 0x69, 0x66, 0x68, 0x70, 0x7e, 0x8f, 0x98, + 0x99, 0x93, 0x87, 0x79, 0x6c, 0x65, 0x68, 0x72, 0x81, 0x8f, 0x95, 0x93, 0x8a, 0x7c, 0x71, 0x6d, + 0x6e, 0x76, 0x7e, 0x86, 0x8b, 0x89, 0x87, 0x81, 0x77, 0x74, 0x74, 0x7a, 0x83, 0x88, 0x89, 0x85, + 0x80, 0x7c, 0x77, 0x78, 0x7b, 0x7d, 0x80, 0x84, 0x88, 0x8a, 0x89, 0x82, 0x7a, 0x75, 0x70, 0x6c, + 0x71, 0x7b, 0x86, 0x90, 0x96, 0x98, 0x92, 0x85, 0x75, 0x67, 0x61, 0x69, 0x77, 0x84, 0x8e, 0x96, + 0x9a, 0x97, 0x8b, 0x80, 0x75, 0x6b, 0x65, 0x64, 0x6c, 0x7a, 0x8a, 0x99, 0xa0, 0x9c, 0x8f, 0x7b, + 0x6b, 0x63, 0x60, 0x69, 0x75, 0x84, 0x90, 0x99, 0x9d, 0x98, 0x8a, 0x76, 0x67, 0x5f, 0x60, 0x69, + 0x7a, 0x8c, 0x96, 0x9a, 0x98, 0x91, 0x83, 0x77, 0x73, 0x6d, 0x66, 0x68, 0x71, 0x7d, 0x8c, 0x98, + 0xa0, 0xa3, 0x9b, 0x89, 0x75, 0x63, 0x57, 0x59, 0x67, 0x76, 0x8a, 0xa0, 0xaa, 0xa7, 0x9b, 0x89, + 0x73, 0x60, 0x55, 0x52, 0x58, 0x67, 0x7e, 0x97, 0xa9, 0xb0, 0xaa, 0x98, 0x80, 0x67, 0x58, 0x54, + 0x59, 0x62, 0x72, 0x88, 0x9b, 0xa6, 0xaa, 0xa0, 0x8c, 0x76, 0x65, 0x5a, 0x5c, 0x6c, 0x7d, 0x8d, + 0x9a, 0x9f, 0x9c, 0x90, 0x78, 0x65, 0x5c, 0x5b, 0x65, 0x77, 0x8f, 0xa0, 0xa7, 0xa3, 0x93, 0x7b, + 0x68, 0x5b, 0x58, 0x60, 0x70, 0x82, 0x91, 0x9a, 0x9c, 0x99, 0x91, 0x84, 0x76, 0x6d, 0x69, 0x6a, + 0x73, 0x7b, 0x86, 0x8e, 0x92, 0x94, 0x90, 0x88, 0x7e, 0x76, 0x6f, 0x6d, 0x6d, 0x75, 0x83, 0x8d, + 0x95, 0x98, 0x93, 0x88, 0x7a, 0x6b, 0x66, 0x69, 0x6e, 0x7b, 0x84, 0x8b, 0x92, 0x8e, 0x8a, 0x87, + 0x84, 0x7c, 0x74, 0x75, 0x76, 0x74, 0x77, 0x7c, 0x80, 0x81, 0x86, 0x8c, 0x8b, 0x8a, 0x88, 0x80, + 0x7a, 0x7b, 0x7b, 0x75, 0x76, 0x80, 0x83, 0x81, 0x81, 0x82, 0x81, 0x7d, 0x81, 0x82, 0x7d, 0x81, + 0x85, 0x85, 0x7d, 0x78, 0x7a, 0x7c, 0x7c, 0x7b, 0x7b, 0x83, 0x85, 0x82, 0x84, 0x89, 0x8a, 0x85, + 0x7d, 0x79, 0x73, 0x72, 0x73, 0x79, 0x82, 0x8a, 0x93, 0x96, 0x90, 0x87, 0x79, 0x6a, 0x62, 0x65, + 0x73, 0x84, 0x93, 0x9a, 0x99, 0x94, 0x86, 0x75, 0x6a, 0x67, 0x69, 0x6d, 0x79, 0x88, 0x8e, 0x8e, + 0x8f, 0x8b, 0x86, 0x80, 0x77, 0x72, 0x70, 0x6d, 0x6f, 0x77, 0x82, 0x8a, 0x8f, 0x94, 0x91, 0x89, + 0x7e, 0x75, 0x6f, 0x6a, 0x6b, 0x74, 0x80, 0x8e, 0x99, 0xa0, 0xa0, 0x91, 0x7c, 0x6b, 0x5c, 0x55, + 0x5b, 0x6f, 0x87, 0x9b, 0xab, 0xaf, 0xa7, 0x92, 0x73, 0x5a, 0x52, 0x54, 0x62, 0x78, 0x8e, 0x9f, + 0xa8, 0xa6, 0x9d, 0x89, 0x73, 0x67, 0x61, 0x5f, 0x68, 0x78, 0x87, 0x91, 0x96, 0x95, 0x91, 0x85, + 0x79, 0x71, 0x6a, 0x6e, 0x77, 0x82, 0x8d, 0x94, 0x92, 0x88, 0x7c, 0x74, 0x6d, 0x6b, 0x74, 0x82, + 0x8c, 0x93, 0x93, 0x8b, 0x7d, 0x73, 0x6b, 0x6d, 0x78, 0x84, 0x8a, 0x8a, 0x8a, 0x85, 0x78, 0x74, + 0x75, 0x73, 0x75, 0x7e, 0x8b, 0x91, 0x8f, 0x8f, 0x8a, 0x7b, 0x6f, 0x6b, 0x6d, 0x74, 0x76, 0x79, + 0x88, 0x96, 0x93, 0x8e, 0x8f, 0x8c, 0x80, 0x70, 0x69, 0x65, 0x61, 0x66, 0x75, 0x86, 0x95, 0x9c, + 0xa2, 0xa4, 0x94, 0x7c, 0x6a, 0x63, 0x5d, 0x59, 0x69, 0x86, 0x99, 0x9e, 0xa2, 0xa3, 0x8e, 0x72, + 0x63, 0x5f, 0x66, 0x70, 0x7c, 0x8f, 0x9d, 0x9a, 0x8e, 0x84, 0x7b, 0x6d, 0x61, 0x6b, 0x7d, 0x86, + 0x87, 0x91, 0x9a, 0x8f, 0x7d, 0x79, 0x78, 0x6f, 0x6a, 0x72, 0x7b, 0x80, 0x83, 0x8a, 0x90, 0x8e, + 0x88, 0x84, 0x7e, 0x78, 0x74, 0x75, 0x79, 0x7e, 0x7d, 0x7c, 0x80, 0x82, 0x83, 0x82, 0x83, 0x84, + 0x80, 0x7c, 0x7e, 0x82, 0x82, 0x86, 0x88, 0x81, 0x77, 0x74, 0x74, 0x76, 0x7c, 0x86, 0x8f, 0x8f, + 0x8b, 0x89, 0x80, 0x71, 0x6c, 0x6d, 0x71, 0x7a, 0x86, 0x90, 0x96, 0x94, 0x8c, 0x7e, 0x73, 0x6e, + 0x6e, 0x70, 0x7a, 0x86, 0x8c, 0x90, 0x91, 0x89, 0x7c, 0x76, 0x76, 0x75, 0x75, 0x7d, 0x87, 0x8b, + 0x8c, 0x8a, 0x85, 0x7c, 0x72, 0x70, 0x7a, 0x7e, 0x84, 0x8c, 0x8f, 0x8b, 0x7d, 0x74, 0x70, 0x68, + 0x65, 0x75, 0x89, 0x91, 0x97, 0x9b, 0x99, 0x88, 0x6e, 0x60, 0x5e, 0x61, 0x6d, 0x83, 0x96, 0x9f, + 0x9f, 0x96, 0x8a, 0x75, 0x61, 0x5f, 0x67, 0x70, 0x7d, 0x8d, 0x9a, 0xa2, 0x95, 0x85, 0x80, 0x74, + 0x65, 0x5e, 0x68, 0x77, 0x7a, 0x82, 0x96, 0xa1, 0x9c, 0x91, 0x8a, 0x80, 0x6d, 0x5e, 0x5d, 0x64, + 0x6a, 0x71, 0x83, 0x9b, 0xa5, 0xa4, 0x9e, 0x93, 0x83, 0x65, 0x50, 0x55, 0x64, 0x6a, 0x76, 0x94, + 0xa8, 0xa4, 0x99, 0x96, 0x8a, 0x6b, 0x5c, 0x65, 0x70, 0x75, 0x7a, 0x89, 0x9a, 0x95, 0x89, 0x8a, + 0x8c, 0x7b, 0x66, 0x68, 0x7a, 0x7d, 0x7a, 0x8a, 0x9d, 0x98, 0x87, 0x83, 0x7c, 0x6e, 0x60, 0x64, + 0x7a, 0x8c, 0x8a, 0x8b, 0x98, 0x99, 0x87, 0x77, 0x78, 0x77, 0x66, 0x5e, 0x6d, 0x7e, 0x83, 0x8a, + 0x97, 0xa1, 0x9b, 0x8b, 0x83, 0x74, 0x61, 0x55, 0x5f, 0x6f, 0x76, 0x85, 0x9f, 0xaa, 0x9f, 0x95, + 0x90, 0x7c, 0x60, 0x57, 0x61, 0x69, 0x6b, 0x7d, 0x9f, 0xab, 0x9e, 0x94, 0x91, 0x82, 0x61, 0x4f, + 0x59, 0x6c, 0x71, 0x7b, 0x9f, 0xb4, 0xa5, 0x90, 0x8e, 0x83, 0x5e, 0x48, 0x55, 0x69, 0x6d, 0x72, + 0x96, 0xb4, 0xa8, 0x94, 0x99, 0x95, 0x70, 0x53, 0x5e, 0x70, 0x68, 0x64, 0x83, 0xa1, 0x9a, 0x8d, + 0x94, 0x96, 0x7d, 0x66, 0x6b, 0x80, 0x7d, 0x6d, 0x7d, 0x99, 0x8f, 0x76, 0x79, 0x89, 0x7b, 0x68, + 0x75, 0x8e, 0x90, 0x87, 0x8c, 0x96, 0x88, 0x68, 0x5f, 0x6a, 0x6f, 0x73, 0x80, 0x92, 0x9c, 0x99, + 0x93, 0x87, 0x75, 0x6c, 0x67, 0x60, 0x68, 0x78, 0x84, 0x91, 0x9a, 0x9a, 0x94, 0x86, 0x7b, 0x70, + 0x63, 0x64, 0x69, 0x70, 0x7d, 0x8c, 0x94, 0x93, 0x8e, 0x8b, 0x89, 0x7d, 0x72, 0x6d, 0x6d, 0x67, + 0x64, 0x6c, 0x7c, 0x90, 0xa0, 0xaa, 0xa7, 0x9b, 0x86, 0x69, 0x54, 0x4c, 0x4d, 0x59, 0x73, 0x8f, + 0xa8, 0xae, 0xac, 0xab, 0x9a, 0x7c, 0x67, 0x59, 0x54, 0x57, 0x64, 0x7a, 0x8c, 0x99, 0xa8, 0xac, + 0xa0, 0x89, 0x6f, 0x5e, 0x56, 0x54, 0x5c, 0x77, 0x98, 0xa7, 0xa4, 0xa1, 0x9f, 0x87, 0x61, 0x52, + 0x55, 0x5b, 0x68, 0x7c, 0x97, 0xb0, 0xb3, 0xa2, 0x8f, 0x7c, 0x67, 0x52, 0x52, 0x5d, 0x66, 0x7d, + 0x9c, 0xa7, 0xa0, 0x9f, 0x9f, 0x89, 0x6f, 0x63, 0x62, 0x67, 0x6d, 0x74, 0x83, 0x94, 0x9e, 0x97, + 0x95, 0x98, 0x85, 0x69, 0x65, 0x75, 0x77, 0x6d, 0x74, 0x8a, 0x92, 0x8b, 0x87, 0x88, 0x7e, 0x73, + 0x73, 0x7a, 0x7a, 0x79, 0x7c, 0x85, 0x8a, 0x81, 0x77, 0x7c, 0x89, 0x8e, 0x8d, 0x8b, 0x84, 0x7b, + 0x6e, 0x66, 0x69, 0x6f, 0x74, 0x7e, 0x91, 0xa7, 0xaa, 0x9b, 0x8c, 0x76, 0x65, 0x5a, 0x54, 0x5c, + 0x6e, 0x85, 0x9a, 0xa3, 0xa5, 0xa9, 0x9c, 0x80, 0x6f, 0x63, 0x57, 0x58, 0x65, 0x75, 0x7b, 0x80, + 0x96, 0xab, 0xa3, 0x91, 0x86, 0x7a, 0x6d, 0x64, 0x60, 0x60, 0x62, 0x6d, 0x86, 0x9a, 0x9a, 0x93, + 0x99, 0x9b, 0x88, 0x74, 0x6c, 0x68, 0x63, 0x67, 0x72, 0x7b, 0x7d, 0x85, 0x9b, 0xa2, 0x94, 0x87, + 0x84, 0x7e, 0x6e, 0x66, 0x6d, 0x73, 0x77, 0x81, 0x8d, 0x8f, 0x82, 0x76, 0x80, 0x88, 0x84, 0x80, + 0x80, 0x84, 0x89, 0x7d, 0x71, 0x77, 0x77, 0x73, 0x7c, 0x89, 0x8a, 0x80, 0x7e, 0x8a, 0x89, 0x78, + 0x70, 0x7a, 0x83, 0x85, 0x88, 0x8b, 0x88, 0x7a, 0x73, 0x75, 0x6f, 0x6a, 0x75, 0x83, 0x93, 0x98, + 0x92, 0x92, 0x88, 0x7b, 0x75, 0x6f, 0x68, 0x68, 0x72, 0x83, 0x8f, 0x8f, 0x90, 0x92, 0x98, 0x8a, + 0x71, 0x6e, 0x72, 0x72, 0x6d, 0x72, 0x80, 0x85, 0x85, 0x90, 0x98, 0x8b, 0x82, 0x84, 0x80, 0x74, + 0x66, 0x69, 0x72, 0x6f, 0x75, 0x8b, 0x9b, 0x98, 0x8d, 0x8b, 0x8f, 0x7d, 0x65, 0x64, 0x69, 0x6b, + 0x6f, 0x76, 0x8c, 0xa3, 0xa0, 0x98, 0x90, 0x84, 0x73, 0x63, 0x62, 0x6b, 0x6e, 0x75, 0x8b, 0x99, + 0x96, 0x95, 0x95, 0x8d, 0x75, 0x62, 0x67, 0x6a, 0x6e, 0x7d, 0x87, 0x95, 0x9d, 0x8b, 0x88, 0x87, + 0x77, 0x6b, 0x68, 0x74, 0x7a, 0x78, 0x81, 0x8b, 0x8e, 0x8a, 0x8b, 0x88, 0x7b, 0x75, 0x74, 0x6e, + 0x71, 0x7d, 0x84, 0x87, 0x92, 0x99, 0x8c, 0x81, 0x7e, 0x73, 0x6f, 0x72, 0x71, 0x75, 0x7b, 0x89, + 0x91, 0x8a, 0x87, 0x90, 0x88, 0x7c, 0x80, 0x77, 0x71, 0x6e, 0x6f, 0x79, 0x7e, 0x7d, 0x86, 0x90, + 0x93, 0x95, 0x94, 0x89, 0x82, 0x76, 0x66, 0x62, 0x63, 0x67, 0x75, 0x8f, 0x9b, 0x9b, 0x99, 0x9c, + 0x94, 0x7e, 0x6e, 0x6e, 0x67, 0x5e, 0x65, 0x70, 0x7d, 0x85, 0x8e, 0x99, 0x99, 0x93, 0x8c, 0x7d, + 0x74, 0x70, 0x6e, 0x71, 0x70, 0x74, 0x86, 0x8a, 0x88, 0x86, 0x8b, 0x8c, 0x7b, 0x73, 0x7c, 0x7b, + 0x7a, 0x7a, 0x7b, 0x82, 0x85, 0x81, 0x7d, 0x79, 0x7b, 0x7b, 0x78, 0x80, 0x85, 0x87, 0x89, 0x89, + 0x85, 0x7c, 0x7a, 0x7b, 0x71, 0x6d, 0x7b, 0x83, 0x84, 0x86, 0x90, 0x97, 0x86, 0x80, 0x82, 0x76, + 0x6a, 0x65, 0x73, 0x80, 0x7c, 0x7c, 0x8e, 0x9b, 0x8e, 0x7a, 0x7a, 0x7d, 0x71, 0x5e, 0x65, 0x87, + 0x8a, 0x7d, 0x8d, 0xa4, 0x94, 0x7a, 0x7b, 0x7a, 0x6d, 0x63, 0x70, 0x7e, 0x81, 0x8c, 0x94, 0x8b, + 0x7c, 0x7d, 0x84, 0x7d, 0x76, 0x7d, 0x83, 0x7b, 0x7c, 0x7b, 0x78, 0x79, 0x78, 0x77, 0x82, 0x8f, + 0x89, 0x7c, 0x85, 0x8e, 0x80, 0x6c, 0x75, 0x82, 0x7b, 0x76, 0x7a, 0x84, 0x85, 0x80, 0x7a, 0x84, + 0x8b, 0x83, 0x7e, 0x7d, 0x87, 0x86, 0x72, 0x70, 0x72, 0x75, 0x78, 0x75, 0x80, 0x90, 0x94, 0x8a, + 0x89, 0x87, 0x84, 0x7b, 0x6e, 0x72, 0x76, 0x6f, 0x74, 0x85, 0x88, 0x84, 0x91, 0x94, 0x83, 0x82, + 0x7e, 0x76, 0x6b, 0x68, 0x7b, 0x7e, 0x7d, 0x8c, 0x91, 0x91, 0x84, 0x78, 0x7d, 0x7a, 0x70, 0x6e, + 0x75, 0x7c, 0x85, 0x87, 0x86, 0x91, 0x8d, 0x78, 0x76, 0x7c, 0x76, 0x69, 0x6e, 0x82, 0x93, 0x82, + 0x75, 0x92, 0x9b, 0x78, 0x64, 0x87, 0x8f, 0x6f, 0x69, 0x8b, 0x8f, 0x76, 0x7a, 0x81, 0x88, 0x86, + 0x7b, 0x6e, 0x76, 0x90, 0x83, 0x71, 0x7e, 0x91, 0x8a, 0x6f, 0x7a, 0x8e, 0x7e, 0x6a, 0x77, 0x8a, + 0x7b, 0x73, 0x83, 0x86, 0x7c, 0x81, 0x85, 0x7c, 0x7a, 0x83, 0x7e, 0x78, 0x7d, 0x80, 0x7c, 0x83, + 0x88, 0x83, 0x7c, 0x7c, 0x85, 0x83, 0x85, 0x84, 0x87, 0x86, 0x7a, 0x82, 0x80, 0x72, 0x71, 0x79, + 0x80, 0x84, 0x81, 0x84, 0x8d, 0x88, 0x80, 0x78, 0x77, 0x79, 0x7c, 0x82, 0x7c, 0x7c, 0x85, 0x87, + 0x7c, 0x78, 0x81, 0x7d, 0x75, 0x7d, 0x8c, 0x85, 0x7c, 0x81, 0x86, 0x82, 0x76, 0x77, 0x86, 0x83, + 0x7b, 0x80, 0x84, 0x85, 0x7e, 0x74, 0x77, 0x82, 0x80, 0x7e, 0x82, 0x8c, 0x8f, 0x84, 0x7d, 0x7e, + 0x7a, 0x6f, 0x73, 0x7c, 0x7e, 0x7e, 0x83, 0x8c, 0x89, 0x7d, 0x80, 0x86, 0x82, 0x7a, 0x77, 0x7b, + 0x7c, 0x78, 0x79, 0x80, 0x83, 0x82, 0x88, 0x89, 0x7e, 0x7e, 0x82, 0x7a, 0x76, 0x7e, 0x83, 0x7b, + 0x75, 0x82, 0x8d, 0x81, 0x75, 0x80, 0x88, 0x80, 0x77, 0x7a, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, + 0x82, 0x82, 0x7a, 0x78, 0x7e, 0x82, 0x7d, 0x78, 0x7b, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x7e, 0x7d, + 0x83, 0x80, 0x78, 0x79, 0x7e, 0x81, 0x7c, 0x7c, 0x84, 0x85, 0x7d, 0x7c, 0x84, 0x87, 0x80, 0x7a, + 0x7a, 0x7d, 0x79, 0x75, 0x7a, 0x7e, 0x81, 0x82, 0x83, 0x88, 0x87, 0x81, 0x7d, 0x7b, 0x7b, 0x77, + 0x75, 0x79, 0x80, 0x82, 0x84, 0x86, 0x86, 0x85, 0x83, 0x80, 0x7d, 0x7b, 0x79, 0x79, 0x7d, 0x7e, + 0x80, 0x82, 0x84, 0x82, 0x84, 0x82, 0x80, 0x80, 0x81, 0x81, 0x7d, 0x80, 0x7e, 0x7b, 0x7b, 0x7d, + 0x7e, 0x7e, 0x7e, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x82, 0x84, 0x83, 0x84, 0x82, 0x7e, 0x7b, + 0x78, 0x79, 0x7a, 0x7b, 0x80, 0x7e, 0x7d, 0x81, 0x85, 0x88, 0x8b, 0x8a, 0x86, 0x80, 0x7a, 0x74, + 0x70, 0x70, 0x74, 0x7a, 0x82, 0x8b, 0x91, 0x91, 0x8e, 0x89, 0x82, 0x7c, 0x75, 0x71, 0x74, 0x74, + 0x78, 0x7e, 0x81, 0x84, 0x88, 0x89, 0x87, 0x84, 0x81, 0x7e, 0x7d, 0x80, 0x80, 0x7d, 0x7d, 0x81, + 0x82, 0x83, 0x83, 0x7e, 0x7d, 0x7b, 0x7a, 0x7c, 0x7d, 0x84, 0x88, 0x87, 0x88, 0x86, 0x80, 0x7b, + 0x76, 0x73, 0x73, 0x75, 0x78, 0x7e, 0x82, 0x85, 0x87, 0x85, 0x82, 0x7e, 0x7d, 0x7b, 0x7b, 0x7e, + 0x7d, 0x7e, 0x82, 0x82, 0x84, 0x84, 0x81, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7e, 0x81, 0x82, 0x82, + 0x80, 0x7d, 0x7c, 0x7b, 0x79, 0x77, 0x7a, 0x7c, 0x7e, 0x83, 0x83, 0x83, 0x83, 0x82, 0x7e, 0x78, + 0x77, 0x78, 0x7b, 0x82, 0x83, 0x84, 0x85, 0x81, 0x7e, 0x7e, 0x7a, 0x76, 0x79, 0x7e, 0x84, 0x86, + 0x86, 0x83, 0x81, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x81, 0x83, 0x82, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, + 0x7b, 0x7e, 0x82, 0x81, 0x84, 0x84, 0x81, 0x81, 0x7e, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x81, 0x82, + 0x81, 0x81, 0x82, 0x83, 0x80, 0x7e, 0x81, 0x7e, 0x7d, 0x7e, 0x80, 0x7d, 0x7e, 0x80, 0x7d, 0x7e, + 0x81, 0x81, 0x80, 0x81, 0x80, 0x81, 0x7e, 0x7a, 0x77, 0x76, 0x79, 0x80, 0x84, 0x89, 0x8a, 0x89, + 0x86, 0x7e, 0x7b, 0x77, 0x74, 0x76, 0x7b, 0x7e, 0x82, 0x89, 0x88, 0x85, 0x83, 0x7b, 0x78, 0x78, + 0x7a, 0x7b, 0x82, 0x87, 0x8a, 0x87, 0x84, 0x82, 0x79, 0x78, 0x76, 0x74, 0x78, 0x7b, 0x82, 0x88, + 0x89, 0x8c, 0x87, 0x7e, 0x7b, 0x78, 0x75, 0x77, 0x7a, 0x7a, 0x7e, 0x83, 0x85, 0x85, 0x87, 0x83, + 0x81, 0x83, 0x7d, 0x7c, 0x7a, 0x77, 0x7a, 0x7b, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x83, 0x81, 0x7e, + 0x81, 0x81, 0x80, 0x81, 0x84, 0x80, 0x7e, 0x81, 0x7c, 0x7a, 0x79, 0x78, 0x7c, 0x82, 0x88, 0x8b, + 0x8a, 0x87, 0x84, 0x81, 0x7b, 0x79, 0x76, 0x76, 0x7d, 0x84, 0x86, 0x89, 0x8a, 0x84, 0x81, 0x7d, + 0x79, 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x85, 0x87, 0x88, 0x86, 0x81, 0x7c, 0x7c, 0x79, 0x78, 0x78, + 0x79, 0x7e, 0x84, 0x84, 0x86, 0x86, 0x83, 0x82, 0x81, 0x7a, 0x79, 0x79, 0x79, 0x7d, 0x7e, 0x83, + 0x85, 0x86, 0x85, 0x82, 0x81, 0x7b, 0x79, 0x7a, 0x79, 0x7c, 0x81, 0x83, 0x84, 0x83, 0x83, 0x7d, + 0x7c, 0x7d, 0x79, 0x78, 0x7c, 0x7c, 0x7c, 0x80, 0x82, 0x84, 0x88, 0x89, 0x88, 0x83, 0x81, 0x80, + 0x7a, 0x7a, 0x78, 0x76, 0x7d, 0x83, 0x84, 0x87, 0x89, 0x86, 0x83, 0x82, 0x7e, 0x7d, 0x7b, 0x79, + 0x7b, 0x7d, 0x81, 0x81, 0x82, 0x86, 0x85, 0x84, 0x82, 0x7e, 0x7d, 0x79, 0x79, 0x7c, 0x7b, 0x7d, + 0x80, 0x7e, 0x81, 0x80, 0x7e, 0x81, 0x7d, 0x7d, 0x7d, 0x7a, 0x7d, 0x82, 0x82, 0x82, 0x84, 0x83, + 0x81, 0x7e, 0x79, 0x77, 0x78, 0x7b, 0x7b, 0x7e, 0x82, 0x85, 0x86, 0x83, 0x84, 0x83, 0x80, 0x7d, + 0x7c, 0x79, 0x78, 0x78, 0x77, 0x7b, 0x7d, 0x82, 0x85, 0x86, 0x87, 0x86, 0x84, 0x82, 0x7d, 0x79, + 0x77, 0x75, 0x76, 0x7a, 0x7d, 0x81, 0x83, 0x83, 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7e, 0x82, 0x82, + 0x81, 0x7e, 0x7b, 0x7c, 0x80, 0x80, 0x82, 0x82, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, + 0x81, 0x82, 0x84, 0x82, 0x7d, 0x7e, 0x7b, 0x7c, 0x7e, 0x7c, 0x82, 0x84, 0x82, 0x84, 0x81, 0x7e, + 0x7e, 0x7b, 0x7b, 0x7d, 0x80, 0x83, 0x87, 0x89, 0x88, 0x86, 0x81, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, + 0x7d, 0x7e, 0x81, 0x83, 0x85, 0x81, 0x7c, 0x7a, 0x77, 0x77, 0x7c, 0x81, 0x83, 0x84, 0x80, 0x7e, + 0x81, 0x7d, 0x79, 0x78, 0x77, 0x78, 0x7c, 0x82, 0x88, 0x89, 0x89, 0x89, 0x86, 0x80, 0x78, 0x76, + 0x73, 0x76, 0x79, 0x7c, 0x81, 0x87, 0x8a, 0x87, 0x86, 0x82, 0x7b, 0x79, 0x7b, 0x7a, 0x7b, 0x7e, + 0x81, 0x81, 0x83, 0x83, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x7b, 0x80, 0x7e, 0x80, 0x82, 0x81, + 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7d, 0x82, 0x85, 0x87, 0x85, 0x82, 0x80, 0x7a, + 0x75, 0x74, 0x76, 0x79, 0x7b, 0x82, 0x88, 0x88, 0x88, 0x87, 0x82, 0x7b, 0x79, 0x76, 0x73, 0x78, + 0x80, 0x83, 0x88, 0x8a, 0x89, 0x87, 0x83, 0x7c, 0x78, 0x75, 0x75, 0x79, 0x7b, 0x7e, 0x81, 0x84, + 0x84, 0x82, 0x84, 0x82, 0x7e, 0x80, 0x80, 0x7e, 0x81, 0x7e, 0x7c, 0x7d, 0x7a, 0x79, 0x7d, 0x82, + 0x83, 0x86, 0x85, 0x85, 0x86, 0x83, 0x7c, 0x7c, 0x7d, 0x7a, 0x7a, 0x7d, 0x7e, 0x83, 0x87, 0x86, + 0x84, 0x82, 0x81, 0x7c, 0x7b, 0x7b, 0x79, 0x7e, 0x83, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7b, 0x78, + 0x77, 0x78, 0x7a, 0x80, 0x83, 0x85, 0x84, 0x80, 0x7e, 0x80, 0x7e, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, + 0x7c, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x82, 0x83, 0x82, 0x83, 0x80, 0x7e, 0x7e, 0x7a, 0x7b, 0x7b, + 0x7b, 0x7d, 0x7e, 0x84, 0x85, 0x82, 0x85, 0x83, 0x80, 0x7e, 0x7a, 0x79, 0x7d, 0x7d, 0x7c, 0x7e, + 0x81, 0x83, 0x82, 0x82, 0x83, 0x82, 0x82, 0x80, 0x7e, 0x81, 0x82, 0x82, 0x7e, 0x7b, 0x7c, 0x80, + 0x81, 0x81, 0x85, 0x85, 0x80, 0x7d, 0x7c, 0x7a, 0x7c, 0x7e, 0x7d, 0x7e, 0x81, 0x83, 0x83, 0x81, + 0x7e, 0x7b, 0x7a, 0x7c, 0x7c, 0x7c, 0x7e, 0x82, 0x83, 0x83, 0x81, 0x81, 0x80, 0x7c, 0x7a, 0x7b, + 0x7e, 0x81, 0x83, 0x83, 0x7d, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x81, 0x84, 0x86, 0x87, 0x84, 0x81, + 0x7b, 0x78, 0x75, 0x76, 0x7c, 0x81, 0x84, 0x86, 0x84, 0x85, 0x86, 0x82, 0x7e, 0x7d, 0x7b, 0x7a, + 0x7c, 0x7a, 0x78, 0x7a, 0x7c, 0x80, 0x82, 0x83, 0x86, 0x86, 0x83, 0x82, 0x7e, 0x7d, 0x7e, 0x7e, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x82, 0x86, 0x86, 0x85, 0x84, 0x82, 0x81, 0x7e, 0x7c, 0x7c, 0x7c, + 0x7e, 0x81, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x80, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x81, 0x83, 0x81, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x82, 0x84, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7e, + 0x80, 0x82, 0x83, 0x82, 0x82, 0x80, 0x80, 0x80, 0x81, 0x83, 0x81, 0x80, 0x82, 0x81, 0x83, 0x84, + 0x81, 0x7e, 0x7d, 0x80, 0x80, 0x7c, 0x7e, 0x80, 0x7e, 0x80, 0x82, 0x7e, 0x7e, 0x7e, 0x7d, 0x7a, + 0x7b, 0x7e, 0x7d, 0x81, 0x82, 0x82, 0x83, 0x7e, 0x80, 0x80, 0x79, 0x78, 0x79, 0x78, 0x7b, 0x7d, + 0x82, 0x87, 0x84, 0x84, 0x83, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7c, 0x80, 0x83, 0x84, 0x86, 0x85, + 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7d, 0x80, 0x80, 0x7b, 0x7e, 0x81, 0x80, 0x82, 0x82, 0x7e, 0x7d, + 0x80, 0x7d, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7e, 0x7e, 0x7e, 0x7b, + 0x7b, 0x7a, 0x7a, 0x75, 0x70, 0x7d, 0x8a, 0x83, 0x82, 0x89, 0x80, 0x6b, 0x63, 0x75, 0x91, 0x9c, + 0x91, 0x75, 0x6f, 0x7e, 0x81, 0x79, 0x74, 0x75, 0x7b, 0x80, 0x90, 0x9c, 0x8a, 0x74, 0x71, 0x7b, + 0x7c, 0x72, 0x76, 0x89, 0x8d, 0x84, 0x7d, 0x81, 0x83, 0x72, 0x68, 0x78, 0x90, 0x96, 0x83, 0x70, + 0x7a, 0x8e, 0x8c, 0x73, 0x70, 0x7e, 0x7c, 0x71, 0x75, 0x88, 0x89, 0x78, 0x76, 0x8a, 0x99, 0x8e, + 0x7b, 0x74, 0x77, 0x73, 0x6e, 0x70, 0x72, 0x72, 0x85, 0xa2, 0xa9, 0x8e, 0x77, 0x7e, 0x7e, 0x6f, + 0x6a, 0x73, 0x79, 0x7c, 0x82, 0x87, 0x82, 0x76, 0x76, 0x83, 0x8f, 0x8d, 0x85, 0x7e, 0x79, 0x70, + 0x6d, 0x77, 0x82, 0x82, 0x86, 0x8f, 0x90, 0x85, 0x79, 0x79, 0x7b, 0x73, 0x6e, 0x76, 0x81, 0x88, + 0x8a, 0x85, 0x79, 0x73, 0x7b, 0x83, 0x82, 0x86, 0x8a, 0x7d, 0x71, 0x76, 0x83, 0x86, 0x7c, 0x78, + 0x78, 0x7b, 0x81, 0x89, 0x90, 0x86, 0x7a, 0x7d, 0x81, 0x7a, 0x77, 0x80, 0x88, 0x82, 0x73, 0x77, + 0x8a, 0x8a, 0x81, 0x81, 0x84, 0x82, 0x7b, 0x7a, 0x7d, 0x7a, 0x75, 0x74, 0x7b, 0x86, 0x8e, 0x8b, + 0x83, 0x80, 0x7c, 0x78, 0x78, 0x76, 0x7b, 0x85, 0x85, 0x83, 0x85, 0x89, 0x88, 0x7c, 0x75, 0x7d, + 0x83, 0x7c, 0x79, 0x7b, 0x81, 0x7e, 0x79, 0x80, 0x87, 0x83, 0x80, 0x7c, 0x7a, 0x7e, 0x7e, 0x80, + 0x83, 0x82, 0x81, 0x82, 0x83, 0x84, 0x82, 0x80, 0x7d, 0x7c, 0x83, 0x84, 0x81, 0x80, 0x82, 0x85, + 0x83, 0x80, 0x7e, 0x80, 0x80, 0x7c, 0x7d, 0x82, 0x86, 0x88, 0x87, 0x86, 0x82, 0x7c, 0x79, 0x79, + 0x80, 0x82, 0x7e, 0x80, 0x85, 0x86, 0x87, 0x87, 0x84, 0x81, 0x7e, 0x7c, 0x79, 0x7c, 0x83, 0x85, + 0x86, 0x84, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7a, 0x7c, 0x7e, 0x81, 0x82, 0x84, 0x86, 0x84, 0x81, + 0x7e, 0x7d, 0x7d, 0x81, 0x82, 0x80, 0x7d, 0x7c, 0x7d, 0x80, 0x83, 0x88, 0x88, 0x88, 0x87, 0x87, + 0x86, 0x7d, 0x72, 0x69, 0x64, 0x68, 0x76, 0x8e, 0x9e, 0x9f, 0x91, 0x7b, 0x70, 0x71, 0x75, 0x7e, + 0x82, 0x80, 0x80, 0x7d, 0x7c, 0x7e, 0x82, 0x85, 0x87, 0x89, 0x8e, 0x8f, 0x84, 0x73, 0x68, 0x60, + 0x63, 0x74, 0x89, 0x97, 0x9a, 0x92, 0x88, 0x7b, 0x6e, 0x6b, 0x6d, 0x6e, 0x71, 0x7d, 0x8e, 0x90, + 0x8f, 0x91, 0x8c, 0x85, 0x81, 0x82, 0x7b, 0x71, 0x6d, 0x6c, 0x6f, 0x76, 0x85, 0x96, 0x9c, 0x99, + 0x8e, 0x7a, 0x6b, 0x60, 0x5f, 0x66, 0x70, 0x83, 0x91, 0x95, 0x91, 0x89, 0x7d, 0x73, 0x70, 0x75, + 0x7b, 0x82, 0x86, 0x84, 0x82, 0x86, 0x87, 0x86, 0x84, 0x7e, 0x7c, 0x7d, 0x7d, 0x81, 0x81, 0x7c, + 0x7e, 0x81, 0x7c, 0x79, 0x76, 0x77, 0x76, 0x76, 0x7d, 0x88, 0x8a, 0x84, 0x7a, 0x75, 0x78, 0x7e, + 0x83, 0x89, 0x8e, 0x8d, 0x8b, 0x83, 0x79, 0x77, 0x7b, 0x83, 0x8b, 0x8f, 0x8d, 0x87, 0x7e, 0x75, + 0x73, 0x75, 0x7a, 0x82, 0x87, 0x89, 0x89, 0x84, 0x7b, 0x71, 0x6a, 0x6c, 0x73, 0x7b, 0x85, 0x8a, + 0x8b, 0x84, 0x7e, 0x80, 0x81, 0x83, 0x83, 0x7e, 0x7b, 0x78, 0x75, 0x6c, 0x60, 0x5d, 0x73, 0xa3, + 0xcd, 0xd0, 0xa2, 0x54, 0x1d, 0x23, 0x62, 0xb0, 0xcd, 0xb6, 0x89, 0x68, 0x67, 0x77, 0x78, 0x6c, + 0x69, 0x78, 0x94, 0xa5, 0xa3, 0x8b, 0x66, 0x4b, 0x50, 0x75, 0xa8, 0xc2, 0xac, 0x80, 0x60, 0x56, + 0x5a, 0x6c, 0x8a, 0x9d, 0x9c, 0x93, 0x8f, 0x8b, 0x73, 0x5a, 0x5d, 0x70, 0x7c, 0x8b, 0xa4, 0xa5, + 0x7c, 0x5d, 0x5f, 0x6d, 0x76, 0x8b, 0xa3, 0x9b, 0x7d, 0x70, 0x70, 0x6c, 0x6e, 0x81, 0x90, 0x8c, + 0x8b, 0x92, 0x8a, 0x77, 0x72, 0x78, 0x7e, 0x84, 0x8d, 0x8d, 0x7a, 0x6c, 0x6d, 0x72, 0x78, 0x87, + 0x96, 0x92, 0x85, 0x79, 0x70, 0x66, 0x61, 0x6a, 0x7b, 0x8c, 0x99, 0xa0, 0x9a, 0x88, 0x79, 0x69, + 0x5c, 0x5e, 0x6d, 0x84, 0x94, 0x94, 0x92, 0x8b, 0x80, 0x75, 0x71, 0x79, 0x83, 0x88, 0x89, 0x84, + 0x7e, 0x7b, 0x7a, 0x78, 0x7b, 0x82, 0x82, 0x82, 0x81, 0x7d, 0x7c, 0x7c, 0x7e, 0x82, 0x83, 0x82, + 0x82, 0x7a, 0x76, 0x79, 0x7e, 0x86, 0x8b, 0x8c, 0x86, 0x75, 0x60, 0x56, 0x60, 0x82, 0xb3, 0xcd, + 0xb5, 0x7a, 0x40, 0x27, 0x44, 0x86, 0xc0, 0xcf, 0xad, 0x73, 0x4e, 0x4d, 0x69, 0x85, 0x89, 0x81, + 0x7e, 0x8d, 0x9e, 0x9c, 0x81, 0x58, 0x42, 0x52, 0x7e, 0xac, 0xba, 0xab, 0x87, 0x62, 0x58, 0x63, + 0x7d, 0x97, 0x98, 0x88, 0x78, 0x70, 0x73, 0x76, 0x7c, 0x87, 0x8d, 0x93, 0x93, 0x88, 0x71, 0x5c, + 0x55, 0x5e, 0x75, 0x92, 0xab, 0xb1, 0x99, 0x74, 0x5c, 0x52, 0x59, 0x6c, 0x84, 0x97, 0x9d, 0x9c, + 0x97, 0x8a, 0x77, 0x6d, 0x68, 0x66, 0x69, 0x75, 0x83, 0x8a, 0x91, 0x95, 0x96, 0x92, 0x8b, 0x80, + 0x6e, 0x5e, 0x56, 0x5d, 0x6d, 0x88, 0xa6, 0xb1, 0xa9, 0x9c, 0x88, 0x6b, 0x54, 0x4c, 0x54, 0x65, + 0x7b, 0x97, 0xae, 0xb3, 0xa9, 0x91, 0x75, 0x64, 0x5b, 0x5a, 0x62, 0x6f, 0x83, 0x9a, 0xa8, 0xa7, + 0x9e, 0x8d, 0x76, 0x64, 0x5b, 0x5a, 0x61, 0x73, 0x8f, 0xa6, 0xa3, 0x80, 0x5b, 0x5e, 0x88, 0xb3, + 0xb6, 0x7d, 0x36, 0x1e, 0x53, 0xb6, 0xef, 0xdf, 0x9f, 0x5d, 0x3a, 0x3d, 0x55, 0x67, 0x74, 0x8a, + 0xaa, 0xc0, 0xbb, 0x9d, 0x6d, 0x40, 0x27, 0x33, 0x61, 0xa2, 0xca, 0xca, 0xac, 0x82, 0x64, 0x5a, + 0x5f, 0x6c, 0x81, 0x91, 0x91, 0x88, 0x88, 0x88, 0x7e, 0x71, 0x72, 0x7d, 0x83, 0x89, 0x92, 0x89, + 0x6b, 0x57, 0x65, 0x7c, 0x87, 0x90, 0x9a, 0x94, 0x7d, 0x71, 0x74, 0x79, 0x7c, 0x84, 0x8b, 0x87, + 0x7c, 0x7c, 0x81, 0x81, 0x86, 0x90, 0x94, 0x8c, 0x80, 0x76, 0x6e, 0x63, 0x64, 0x77, 0x8b, 0x98, + 0x9f, 0x99, 0x86, 0x6a, 0x5b, 0x5f, 0x69, 0x7a, 0x91, 0x9c, 0x96, 0x89, 0x7a, 0x6c, 0x6d, 0x77, + 0x87, 0x9b, 0x9a, 0x8b, 0x77, 0x6e, 0x73, 0x7c, 0x83, 0x85, 0x88, 0x8a, 0x7d, 0x71, 0x72, 0x79, + 0x81, 0x84, 0x88, 0x8b, 0x88, 0x80, 0x75, 0x71, 0x76, 0x7e, 0x86, 0x8c, 0x93, 0x92, 0x85, 0x71, + 0x5f, 0x55, 0x5b, 0x6f, 0x83, 0x91, 0x9d, 0xa6, 0x9e, 0x83, 0x6c, 0x63, 0x6c, 0x85, 0x99, 0x9b, + 0x8a, 0x76, 0x6b, 0x69, 0x6f, 0x7e, 0x90, 0x99, 0x95, 0x87, 0x73, 0x61, 0x5a, 0x5b, 0x65, 0x79, + 0x91, 0x9f, 0xa3, 0x98, 0x84, 0x73, 0x6a, 0x6b, 0x7a, 0x8f, 0x96, 0x93, 0x8a, 0x7e, 0x72, 0x6e, + 0x78, 0x87, 0x8b, 0x86, 0x82, 0x79, 0x6a, 0x60, 0x6a, 0x7a, 0x86, 0x92, 0x9c, 0x96, 0x83, 0x74, + 0x6f, 0x6c, 0x6a, 0x75, 0x8a, 0x93, 0x95, 0x99, 0x95, 0x84, 0x7a, 0x78, 0x76, 0x77, 0x77, 0x7a, + 0x7b, 0x7a, 0x7d, 0x87, 0x8b, 0x88, 0x85, 0x80, 0x78, 0x74, 0x73, 0x74, 0x77, 0x7d, 0x88, 0x90, + 0x90, 0x8f, 0x86, 0x78, 0x6d, 0x6d, 0x76, 0x80, 0x82, 0x82, 0x80, 0x7b, 0x7d, 0x81, 0x84, 0x8a, + 0x88, 0x80, 0x7c, 0x7b, 0x7a, 0x7b, 0x83, 0x8a, 0x8c, 0x8b, 0x89, 0x81, 0x74, 0x70, 0x75, 0x7a, + 0x81, 0x86, 0x86, 0x83, 0x7c, 0x76, 0x74, 0x77, 0x7d, 0x84, 0x89, 0x8a, 0x88, 0x80, 0x7a, 0x78, + 0x79, 0x7b, 0x7b, 0x79, 0x75, 0x76, 0x89, 0x9d, 0xa3, 0x98, 0x7a, 0x57, 0x49, 0x61, 0x8b, 0xb3, + 0xc0, 0xa4, 0x74, 0x50, 0x4b, 0x5c, 0x75, 0x8b, 0x93, 0x90, 0x8b, 0x86, 0x7e, 0x75, 0x6d, 0x68, + 0x6a, 0x78, 0x8e, 0x9d, 0xa0, 0x96, 0x7d, 0x65, 0x5c, 0x66, 0x79, 0x8c, 0x94, 0x8a, 0x7c, 0x7a, + 0x7b, 0x82, 0x87, 0x84, 0x81, 0x7a, 0x74, 0x74, 0x73, 0x76, 0x7d, 0x87, 0x90, 0x91, 0x8f, 0x86, + 0x77, 0x69, 0x61, 0x64, 0x71, 0x83, 0x92, 0x99, 0x95, 0x88, 0x79, 0x6f, 0x71, 0x77, 0x7b, 0x7c, + 0x78, 0x78, 0x80, 0x86, 0x87, 0x83, 0x7d, 0x7c, 0x81, 0x84, 0x80, 0x7c, 0x7b, 0x7b, 0x7d, 0x7e, + 0x7e, 0x83, 0x88, 0x87, 0x82, 0x78, 0x74, 0x75, 0x7b, 0x89, 0x8c, 0x83, 0x7d, 0x7a, 0x7a, 0x80, + 0x83, 0x85, 0x85, 0x80, 0x7a, 0x74, 0x61, 0x3f, 0x2b, 0x51, 0xa5, 0xe5, 0xee, 0xcc, 0x8f, 0x47, + 0x26, 0x48, 0x8d, 0xbb, 0xc4, 0xb2, 0x92, 0x64, 0x43, 0x49, 0x68, 0x89, 0x97, 0x90, 0x82, 0x7a, + 0x71, 0x58, 0x4b, 0x5f, 0x81, 0x9a, 0xb6, 0xcf, 0xbb, 0x7a, 0x45, 0x3d, 0x4c, 0x66, 0x97, 0xcf, + 0xdc, 0xb4, 0x81, 0x5f, 0x4a, 0x41, 0x55, 0x84, 0xa2, 0xa3, 0xa3, 0x9e, 0x81, 0x5b, 0x4f, 0x5a, + 0x64, 0x75, 0x93, 0xab, 0xa5, 0x8d, 0x79, 0x6c, 0x62, 0x6e, 0x8c, 0xa3, 0xa2, 0x93, 0x86, 0x74, + 0x68, 0x6d, 0x82, 0x91, 0x8b, 0x81, 0x78, 0x67, 0x5f, 0x6b, 0x7d, 0x8a, 0x90, 0x95, 0x94, 0x87, + 0x77, 0x6f, 0x6b, 0x6c, 0x7e, 0x94, 0x9f, 0x9d, 0x8d, 0x7b, 0x69, 0x5d, 0x66, 0x7d, 0x8d, 0x90, + 0x8b, 0x84, 0x7e, 0x84, 0x8c, 0x8d, 0x84, 0x72, 0x69, 0x6d, 0x7a, 0x8a, 0x99, 0x9b, 0x8d, 0x7c, + 0x71, 0x6b, 0x6b, 0x76, 0x80, 0x82, 0x81, 0x80, 0x82, 0x83, 0x83, 0x81, 0x7c, 0x76, 0x77, 0x7d, + 0x83, 0x85, 0x84, 0x7a, 0x6b, 0x62, 0x67, 0x78, 0x94, 0xaf, 0xb8, 0xa4, 0x79, 0x4c, 0x38, 0x4a, + 0x79, 0xae, 0xc5, 0xb8, 0x8d, 0x61, 0x51, 0x5b, 0x71, 0x85, 0x87, 0x84, 0x83, 0x86, 0x8c, 0x87, + 0x76, 0x6c, 0x70, 0x7d, 0x92, 0xa0, 0x9c, 0x8c, 0x70, 0x58, 0x54, 0x66, 0x86, 0xa2, 0xb0, 0xa6, + 0x8b, 0x6d, 0x59, 0x59, 0x68, 0x7a, 0x8e, 0x9a, 0x99, 0x8b, 0x7c, 0x75, 0x71, 0x6f, 0x71, 0x77, + 0x79, 0x7c, 0x83, 0x85, 0x83, 0x80, 0x84, 0x89, 0x89, 0x85, 0x7a, 0x6c, 0x63, 0x64, 0x72, 0x87, + 0x98, 0xa3, 0xa2, 0x90, 0x75, 0x5e, 0x56, 0x62, 0x78, 0x92, 0xa0, 0x9e, 0x92, 0x7b, 0x65, 0x5d, + 0x5e, 0x6a, 0x7c, 0x92, 0x9d, 0x97, 0x8a, 0x80, 0x77, 0x78, 0x87, 0x93, 0x8d, 0x78, 0x5f, 0x4e, + 0x52, 0x60, 0x5e, 0x56, 0x73, 0xb5, 0xe4, 0xd9, 0xb9, 0x87, 0x42, 0x22, 0x4d, 0xa4, 0xd3, 0xd5, + 0xc9, 0x9f, 0x52, 0x1a, 0x27, 0x59, 0x85, 0x99, 0x9d, 0x95, 0x82, 0x68, 0x55, 0x5d, 0x71, 0x78, + 0x87, 0xa9, 0xc2, 0xaa, 0x78, 0x62, 0x5f, 0x50, 0x5b, 0x97, 0xc7, 0xc0, 0xa1, 0x8c, 0x6c, 0x45, + 0x40, 0x68, 0x91, 0x98, 0x95, 0x97, 0x82, 0x58, 0x45, 0x57, 0x6a, 0x7b, 0x96, 0xa8, 0xa0, 0x86, + 0x74, 0x6d, 0x6d, 0x76, 0x89, 0x9d, 0xa2, 0x97, 0x89, 0x77, 0x66, 0x61, 0x70, 0x85, 0x95, 0x9b, + 0x94, 0x82, 0x67, 0x58, 0x59, 0x69, 0x7e, 0x93, 0x9c, 0x96, 0x89, 0x7d, 0x78, 0x77, 0x7b, 0x84, + 0x8a, 0x86, 0x7d, 0x74, 0x69, 0x63, 0x6f, 0x89, 0x9e, 0xa7, 0x9d, 0x83, 0x5e, 0x41, 0x41, 0x61, + 0x95, 0xc1, 0xd7, 0xc4, 0x8b, 0x49, 0x22, 0x28, 0x5b, 0x9d, 0xcf, 0xda, 0xba, 0x86, 0x55, 0x3c, + 0x42, 0x5d, 0x85, 0xa9, 0xb9, 0xb3, 0x98, 0x73, 0x57, 0x46, 0x45, 0x53, 0x6b, 0x8e, 0xb5, 0xce, + 0xcd, 0xa9, 0x68, 0x2a, 0x1f, 0x52, 0xa0, 0xde, 0xe5, 0xb4, 0x6d, 0x3a, 0x37, 0x55, 0x75, 0x8f, + 0x9d, 0xa1, 0x97, 0x7e, 0x67, 0x5b, 0x5f, 0x6f, 0x83, 0x91, 0x9e, 0xa7, 0x9d, 0x7d, 0x5a, 0x4c, + 0x5a, 0x7e, 0xa9, 0xbf, 0xb8, 0x9c, 0x75, 0x56, 0x49, 0x51, 0x6f, 0x99, 0xb1, 0xb0, 0x9d, 0x82, + 0x68, 0x5b, 0x5e, 0x6c, 0x7c, 0x8a, 0x92, 0x8f, 0x7c, 0x6c, 0x68, 0x6f, 0x7c, 0x8f, 0x9c, 0x9b, + 0x90, 0x81, 0x72, 0x66, 0x65, 0x74, 0x89, 0x93, 0x8e, 0x86, 0x7c, 0x79, 0x78, 0x79, 0x84, 0x8f, + 0x95, 0x8f, 0x7e, 0x6f, 0x6b, 0x6c, 0x70, 0x7d, 0x8f, 0x9a, 0x99, 0x91, 0x87, 0x7a, 0x74, 0x6f, + 0x68, 0x5c, 0x53, 0x56, 0x55, 0x4e, 0x5f, 0x9b, 0xd7, 0xe9, 0xcf, 0x99, 0x56, 0x2b, 0x3d, 0x85, + 0xc3, 0xd5, 0xcb, 0xae, 0x72, 0x33, 0x23, 0x44, 0x6f, 0x8e, 0x9e, 0xa1, 0x91, 0x75, 0x5c, 0x55, + 0x59, 0x5f, 0x72, 0x96, 0xb9, 0xb9, 0x9a, 0x80, 0x6d, 0x57, 0x4f, 0x73, 0xa3, 0xb2, 0xaa, 0x9e, + 0x89, 0x62, 0x4c, 0x5c, 0x7a, 0x86, 0x89, 0x92, 0x89, 0x6c, 0x5a, 0x61, 0x6b, 0x6f, 0x82, 0x9c, + 0xa4, 0x98, 0x87, 0x7a, 0x6b, 0x60, 0x6d, 0x8c, 0x9d, 0xa1, 0x9f, 0x91, 0x79, 0x65, 0x63, 0x6e, + 0x7a, 0x86, 0x90, 0x8c, 0x7b, 0x6f, 0x6a, 0x68, 0x6c, 0x7b, 0x8d, 0x93, 0x8f, 0x88, 0x7b, 0x6f, + 0x6e, 0x7b, 0x8d, 0x94, 0x92, 0x88, 0x77, 0x6c, 0x6c, 0x76, 0x7d, 0x83, 0x83, 0x82, 0x80, 0x7c, + 0x7c, 0x7d, 0x80, 0x82, 0x86, 0x88, 0x84, 0x81, 0x7d, 0x79, 0x79, 0x7d, 0x88, 0x93, 0x95, 0x8e, + 0x80, 0x72, 0x6b, 0x6b, 0x6f, 0x71, 0x6d, 0x71, 0x84, 0x9f, 0xb4, 0xac, 0x86, 0x56, 0x3d, 0x4b, + 0x7e, 0xac, 0xbe, 0xb4, 0x94, 0x73, 0x5c, 0x54, 0x5b, 0x6e, 0x8b, 0x9f, 0xa2, 0x98, 0x88, 0x76, + 0x6a, 0x5e, 0x5b, 0x66, 0x7d, 0x98, 0xa7, 0xa2, 0x8b, 0x71, 0x60, 0x61, 0x6f, 0x80, 0x8c, 0x93, + 0x8f, 0x7e, 0x72, 0x72, 0x79, 0x82, 0x8c, 0x93, 0x8a, 0x78, 0x71, 0x6f, 0x6b, 0x6b, 0x7a, 0x8d, + 0x93, 0x90, 0x86, 0x78, 0x68, 0x65, 0x71, 0x80, 0x87, 0x8e, 0x91, 0x8a, 0x7e, 0x7c, 0x81, 0x85, + 0x8b, 0x8f, 0x8d, 0x83, 0x7b, 0x76, 0x72, 0x71, 0x76, 0x7c, 0x80, 0x83, 0x84, 0x7e, 0x74, 0x75, + 0x7a, 0x79, 0x75, 0x7e, 0x90, 0x9c, 0x9d, 0x91, 0x7c, 0x67, 0x5d, 0x61, 0x60, 0x51, 0x4b, 0x73, + 0xbb, 0xe5, 0xdc, 0xb0, 0x6a, 0x29, 0x1a, 0x49, 0x98, 0xc8, 0xd1, 0xc2, 0x90, 0x53, 0x2b, 0x34, + 0x5e, 0x83, 0x9a, 0xa1, 0x9e, 0x8f, 0x73, 0x60, 0x5d, 0x66, 0x6d, 0x81, 0xa9, 0xc3, 0xb0, 0x86, + 0x68, 0x54, 0x3f, 0x4c, 0x88, 0xbb, 0xbd, 0xa9, 0x96, 0x72, 0x47, 0x42, 0x6b, 0x8a, 0x8a, 0x92, + 0xa1, 0x8d, 0x66, 0x5b, 0x67, 0x67, 0x67, 0x84, 0xa3, 0xa1, 0x90, 0x89, 0x7c, 0x62, 0x5e, 0x76, + 0x8f, 0x98, 0x9a, 0x99, 0x88, 0x6f, 0x66, 0x6b, 0x6f, 0x75, 0x87, 0x94, 0x8f, 0x87, 0x82, 0x77, + 0x69, 0x68, 0x75, 0x83, 0x8a, 0x8d, 0x8b, 0x82, 0x78, 0x7b, 0x86, 0x8c, 0x89, 0x82, 0x76, 0x6a, + 0x67, 0x74, 0x89, 0x96, 0x95, 0x89, 0x76, 0x67, 0x62, 0x6b, 0x7b, 0x89, 0x8f, 0x90, 0x8f, 0x90, + 0x96, 0x99, 0x8f, 0x80, 0x70, 0x64, 0x60, 0x5e, 0x63, 0x6e, 0x7a, 0x92, 0xac, 0xb7, 0xad, 0x8d, + 0x68, 0x50, 0x4d, 0x61, 0x7c, 0x91, 0x9d, 0x9d, 0x95, 0x88, 0x79, 0x70, 0x71, 0x76, 0x7c, 0x7e, + 0x7c, 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7b, 0x81, 0x88, 0x8c, 0x8d, 0x83, 0x74, 0x6d, 0x6b, 0x71, + 0x7d, 0x8b, 0x95, 0x92, 0x88, 0x7c, 0x6e, 0x66, 0x6b, 0x7a, 0x8c, 0x99, 0x9f, 0x99, 0x85, 0x6e, + 0x5d, 0x59, 0x64, 0x79, 0x8d, 0x95, 0x91, 0x87, 0x7b, 0x76, 0x76, 0x7e, 0x87, 0x88, 0x86, 0x7e, + 0x79, 0x74, 0x73, 0x79, 0x87, 0x95, 0x98, 0x92, 0x86, 0x79, 0x6e, 0x66, 0x69, 0x72, 0x84, 0x92, + 0x97, 0x92, 0x84, 0x73, 0x68, 0x68, 0x74, 0x86, 0x94, 0x96, 0x92, 0x85, 0x6a, 0x40, 0x22, 0x3c, + 0x8c, 0xd5, 0xf1, 0xdd, 0x9e, 0x53, 0x24, 0x30, 0x68, 0xa3, 0xc6, 0xc8, 0xa7, 0x74, 0x4a, 0x3b, + 0x45, 0x5e, 0x81, 0x9c, 0xae, 0xaf, 0x9e, 0x7e, 0x5b, 0x45, 0x43, 0x56, 0x81, 0xb7, 0xd4, 0xc1, + 0x9a, 0x72, 0x50, 0x40, 0x51, 0x7d, 0x9d, 0xa4, 0xa2, 0x95, 0x7c, 0x63, 0x62, 0x70, 0x79, 0x83, + 0x93, 0x99, 0x8d, 0x78, 0x6e, 0x68, 0x5d, 0x60, 0x78, 0x96, 0xa1, 0xa3, 0x9f, 0x8b, 0x6f, 0x5f, + 0x66, 0x77, 0x8a, 0x9c, 0xa1, 0x93, 0x7e, 0x6e, 0x6b, 0x6c, 0x75, 0x86, 0x91, 0x92, 0x8a, 0x7b, + 0x6d, 0x63, 0x61, 0x6f, 0x86, 0x99, 0xa4, 0xa4, 0x98, 0x7d, 0x66, 0x5d, 0x5d, 0x6b, 0x81, 0x92, + 0x99, 0x92, 0x85, 0x7a, 0x77, 0x7b, 0x86, 0x8d, 0x8c, 0x86, 0x81, 0x7a, 0x78, 0x7a, 0x81, 0x86, + 0x8b, 0x8d, 0x8a, 0x7c, 0x69, 0x59, 0x59, 0x72, 0x96, 0xb3, 0xb6, 0x9b, 0x73, 0x55, 0x55, 0x6e, + 0x8c, 0x9a, 0x95, 0x86, 0x78, 0x75, 0x77, 0x79, 0x7c, 0x82, 0x85, 0x86, 0x86, 0x87, 0x83, 0x7c, + 0x71, 0x67, 0x69, 0x75, 0x89, 0x9a, 0x9c, 0x8f, 0x7a, 0x69, 0x65, 0x6e, 0x7e, 0x8c, 0x91, 0x8b, + 0x82, 0x7b, 0x7b, 0x7a, 0x7b, 0x7d, 0x7c, 0x78, 0x77, 0x79, 0x84, 0x89, 0x85, 0x7c, 0x6f, 0x68, + 0x6e, 0x80, 0x93, 0x9d, 0x98, 0x89, 0x73, 0x65, 0x66, 0x70, 0x7d, 0x8b, 0x93, 0x91, 0x89, 0x81, + 0x7d, 0x79, 0x77, 0x78, 0x7b, 0x7e, 0x83, 0x88, 0x8b, 0x87, 0x83, 0x80, 0x7b, 0x78, 0x74, 0x73, + 0x73, 0x77, 0x7e, 0x8d, 0x9b, 0xa1, 0x97, 0x77, 0x4a, 0x28, 0x32, 0x6f, 0xc3, 0xf7, 0xee, 0xb2, + 0x63, 0x2f, 0x2b, 0x4e, 0x7e, 0xa6, 0xb8, 0xaf, 0x95, 0x7a, 0x6d, 0x67, 0x5f, 0x5e, 0x6a, 0x7e, + 0x90, 0x99, 0x97, 0x84, 0x67, 0x53, 0x56, 0x74, 0x99, 0xb6, 0xbc, 0xa0, 0x74, 0x50, 0x4a, 0x5a, + 0x77, 0x98, 0xaf, 0xb0, 0x9c, 0x87, 0x73, 0x63, 0x56, 0x57, 0x68, 0x82, 0x99, 0xa9, 0xa9, 0x95, + 0x74, 0x59, 0x4c, 0x52, 0x6b, 0x8e, 0xa6, 0xa8, 0x9b, 0x85, 0x72, 0x66, 0x65, 0x6f, 0x83, 0x95, + 0xa0, 0xa2, 0x96, 0x83, 0x6f, 0x64, 0x66, 0x73, 0x87, 0x92, 0x92, 0x85, 0x74, 0x69, 0x68, 0x74, + 0x88, 0x98, 0x9c, 0x95, 0x86, 0x75, 0x6c, 0x68, 0x69, 0x73, 0x7e, 0x89, 0x8f, 0x92, 0x92, 0x8e, + 0x87, 0x78, 0x70, 0x6b, 0x71, 0x80, 0x93, 0x9e, 0x94, 0x77, 0x58, 0x54, 0x72, 0xa0, 0xc0, 0xb3, + 0x83, 0x4c, 0x35, 0x50, 0x85, 0xb1, 0xbd, 0xa6, 0x7c, 0x60, 0x61, 0x6c, 0x76, 0x79, 0x74, 0x72, + 0x7d, 0x92, 0xa2, 0xa1, 0x8b, 0x68, 0x51, 0x52, 0x6b, 0x91, 0xad, 0xb2, 0x9e, 0x7e, 0x65, 0x5e, + 0x69, 0x7b, 0x88, 0x8a, 0x86, 0x84, 0x86, 0x8a, 0x8a, 0x82, 0x74, 0x6d, 0x70, 0x7d, 0x8e, 0x94, + 0x8d, 0x7c, 0x6c, 0x69, 0x70, 0x7c, 0x8c, 0x90, 0x8b, 0x81, 0x77, 0x72, 0x71, 0x77, 0x80, 0x83, + 0x83, 0x84, 0x87, 0x89, 0x89, 0x86, 0x7b, 0x73, 0x71, 0x74, 0x7d, 0x86, 0x8a, 0x88, 0x84, 0x84, + 0x80, 0x7a, 0x74, 0x73, 0x76, 0x79, 0x80, 0x8a, 0x92, 0x94, 0x8e, 0x81, 0x67, 0x45, 0x2b, 0x35, + 0x6d, 0xb5, 0xe1, 0xdf, 0xb9, 0x77, 0x38, 0x25, 0x4c, 0x8b, 0xb6, 0xc7, 0xbf, 0xa1, 0x74, 0x59, + 0x54, 0x54, 0x57, 0x67, 0x86, 0x9f, 0xa8, 0xa8, 0x9a, 0x77, 0x4f, 0x3e, 0x4d, 0x6b, 0x8c, 0xab, + 0xb8, 0xa2, 0x7d, 0x66, 0x5b, 0x5a, 0x64, 0x7c, 0x8e, 0x91, 0x96, 0x9d, 0x98, 0x88, 0x78, 0x6b, + 0x63, 0x66, 0x76, 0x8e, 0x99, 0x96, 0x8e, 0x82, 0x71, 0x6a, 0x6b, 0x73, 0x7a, 0x82, 0x8b, 0x8d, + 0x89, 0x82, 0x7a, 0x74, 0x72, 0x78, 0x82, 0x8c, 0x90, 0x91, 0x8b, 0x80, 0x73, 0x6b, 0x6a, 0x72, + 0x83, 0x91, 0x9d, 0x9e, 0x91, 0x7b, 0x66, 0x5e, 0x60, 0x6b, 0x80, 0x96, 0xa3, 0x9f, 0x8e, 0x7a, + 0x6b, 0x66, 0x66, 0x6e, 0x7b, 0x8b, 0x98, 0x9c, 0x99, 0x8e, 0x81, 0x6d, 0x55, 0x4b, 0x57, 0x81, + 0xaf, 0xc9, 0xc3, 0x98, 0x61, 0x3d, 0x41, 0x68, 0x94, 0xae, 0xad, 0x97, 0x7d, 0x70, 0x70, 0x74, + 0x77, 0x77, 0x77, 0x7a, 0x82, 0x8e, 0x93, 0x8f, 0x83, 0x72, 0x66, 0x66, 0x73, 0x89, 0x9a, 0x9d, + 0x92, 0x7e, 0x6b, 0x5f, 0x62, 0x72, 0x84, 0x90, 0x91, 0x8b, 0x87, 0x86, 0x87, 0x86, 0x7d, 0x72, + 0x6a, 0x6d, 0x78, 0x89, 0x94, 0x98, 0x94, 0x87, 0x77, 0x6b, 0x67, 0x6e, 0x76, 0x7e, 0x87, 0x8c, + 0x8c, 0x87, 0x82, 0x7d, 0x76, 0x70, 0x6e, 0x75, 0x80, 0x88, 0x8c, 0x8a, 0x85, 0x7e, 0x7a, 0x75, + 0x77, 0x7c, 0x82, 0x83, 0x82, 0x7e, 0x7a, 0x77, 0x78, 0x7c, 0x7e, 0x82, 0x86, 0x8a, 0x88, 0x7e, + 0x71, 0x65, 0x62, 0x67, 0x75, 0x88, 0x94, 0x92, 0x82, 0x72, 0x6d, 0x74, 0x85, 0x97, 0x99, 0x8a, + 0x77, 0x6d, 0x73, 0x7e, 0x8f, 0x97, 0x8b, 0x73, 0x63, 0x65, 0x75, 0x8a, 0x9b, 0x9c, 0x90, 0x7e, + 0x73, 0x72, 0x78, 0x86, 0x8d, 0x86, 0x78, 0x74, 0x74, 0x78, 0x83, 0x89, 0x85, 0x7c, 0x79, 0x7e, + 0x85, 0x89, 0x8e, 0x89, 0x7b, 0x74, 0x71, 0x73, 0x77, 0x82, 0x8a, 0x86, 0x7c, 0x77, 0x75, 0x73, + 0x75, 0x7e, 0x88, 0x88, 0x86, 0x86, 0x83, 0x7e, 0x7c, 0x7a, 0x75, 0x75, 0x7c, 0x86, 0x8b, 0x8a, + 0x8a, 0x87, 0x7c, 0x74, 0x71, 0x77, 0x83, 0x8c, 0x90, 0x8b, 0x81, 0x75, 0x71, 0x72, 0x76, 0x80, + 0x84, 0x84, 0x80, 0x7d, 0x7d, 0x7c, 0x80, 0x83, 0x86, 0x88, 0x82, 0x7a, 0x6e, 0x67, 0x67, 0x6d, + 0x7e, 0x8d, 0x93, 0x8d, 0x82, 0x77, 0x72, 0x78, 0x85, 0x90, 0x8f, 0x82, 0x75, 0x6d, 0x73, 0x83, + 0x91, 0x96, 0x8a, 0x7c, 0x76, 0x76, 0x80, 0x88, 0x88, 0x83, 0x7c, 0x7a, 0x7d, 0x86, 0x90, 0x93, + 0x88, 0x76, 0x67, 0x61, 0x66, 0x74, 0x85, 0x91, 0x96, 0x93, 0x89, 0x82, 0x7d, 0x7c, 0x7a, 0x74, + 0x6f, 0x71, 0x78, 0x86, 0x91, 0x95, 0x91, 0x86, 0x7a, 0x73, 0x73, 0x77, 0x7a, 0x7c, 0x7c, 0x7b, + 0x7d, 0x83, 0x8b, 0x90, 0x8f, 0x8a, 0x81, 0x78, 0x75, 0x78, 0x7c, 0x80, 0x81, 0x80, 0x83, 0x86, + 0x8b, 0x8d, 0x89, 0x82, 0x78, 0x72, 0x6f, 0x71, 0x78, 0x83, 0x8a, 0x8d, 0x8b, 0x82, 0x76, 0x69, + 0x65, 0x6b, 0x76, 0x85, 0x8d, 0x89, 0x81, 0x7b, 0x79, 0x7b, 0x85, 0x8d, 0x8d, 0x84, 0x79, 0x73, + 0x71, 0x74, 0x7e, 0x85, 0x81, 0x7a, 0x7c, 0x85, 0x8e, 0x94, 0x94, 0x8b, 0x77, 0x69, 0x6a, 0x77, + 0x86, 0x8e, 0x8f, 0x86, 0x76, 0x6f, 0x79, 0x85, 0x88, 0x87, 0x81, 0x73, 0x6d, 0x75, 0x83, 0x89, + 0x8b, 0x8c, 0x87, 0x7d, 0x7b, 0x83, 0x84, 0x7c, 0x75, 0x71, 0x6e, 0x71, 0x83, 0x95, 0x95, 0x8d, + 0x84, 0x79, 0x71, 0x6f, 0x77, 0x81, 0x84, 0x84, 0x85, 0x82, 0x81, 0x88, 0x8c, 0x86, 0x7c, 0x77, + 0x77, 0x79, 0x82, 0x8d, 0x92, 0x8b, 0x82, 0x7b, 0x76, 0x76, 0x7c, 0x80, 0x7e, 0x7b, 0x78, 0x7a, + 0x7d, 0x84, 0x89, 0x87, 0x7e, 0x78, 0x78, 0x79, 0x7d, 0x83, 0x83, 0x7c, 0x73, 0x6e, 0x75, 0x82, + 0x8e, 0x91, 0x88, 0x79, 0x6e, 0x6d, 0x77, 0x84, 0x8c, 0x8c, 0x86, 0x7e, 0x7c, 0x82, 0x88, 0x89, + 0x80, 0x74, 0x6b, 0x6d, 0x7a, 0x8d, 0x97, 0x94, 0x8b, 0x7e, 0x73, 0x76, 0x80, 0x8b, 0x8e, 0x88, + 0x7c, 0x73, 0x70, 0x73, 0x7a, 0x82, 0x84, 0x81, 0x7c, 0x7d, 0x84, 0x8a, 0x8a, 0x85, 0x7a, 0x74, + 0x75, 0x79, 0x82, 0x8a, 0x8e, 0x88, 0x7d, 0x77, 0x77, 0x79, 0x7e, 0x82, 0x7e, 0x7b, 0x7d, 0x84, + 0x8b, 0x8e, 0x8d, 0x87, 0x7d, 0x77, 0x78, 0x80, 0x85, 0x87, 0x85, 0x7e, 0x78, 0x76, 0x7d, 0x85, + 0x89, 0x87, 0x81, 0x79, 0x73, 0x76, 0x7d, 0x86, 0x8a, 0x88, 0x80, 0x70, 0x68, 0x6d, 0x77, 0x82, + 0x89, 0x8c, 0x85, 0x79, 0x73, 0x76, 0x7e, 0x89, 0x94, 0x91, 0x81, 0x73, 0x6a, 0x67, 0x6d, 0x7c, + 0x87, 0x88, 0x84, 0x81, 0x82, 0x84, 0x89, 0x8a, 0x83, 0x77, 0x6e, 0x6e, 0x7a, 0x8b, 0x94, 0x95, + 0x8e, 0x7b, 0x6e, 0x6f, 0x7a, 0x83, 0x86, 0x85, 0x7d, 0x75, 0x79, 0x85, 0x89, 0x88, 0x83, 0x77, + 0x6c, 0x68, 0x73, 0x82, 0x89, 0x8c, 0x8c, 0x86, 0x7d, 0x7e, 0x84, 0x81, 0x79, 0x77, 0x76, 0x73, + 0x79, 0x87, 0x8c, 0x85, 0x7c, 0x78, 0x72, 0x70, 0x7c, 0x89, 0x8e, 0x8b, 0x84, 0x7c, 0x77, 0x7a, + 0x85, 0x8a, 0x88, 0x84, 0x7d, 0x77, 0x74, 0x79, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x83, 0x87, + 0x85, 0x80, 0x7a, 0x7a, 0x7d, 0x84, 0x86, 0x82, 0x7b, 0x75, 0x76, 0x7a, 0x7d, 0x81, 0x82, 0x81, + 0x7c, 0x7b, 0x80, 0x85, 0x87, 0x83, 0x7a, 0x71, 0x71, 0x77, 0x80, 0x86, 0x87, 0x85, 0x7e, 0x79, + 0x7a, 0x7e, 0x83, 0x83, 0x80, 0x7a, 0x75, 0x75, 0x7e, 0x8b, 0x90, 0x8d, 0x83, 0x75, 0x70, 0x72, + 0x7c, 0x86, 0x8b, 0x89, 0x83, 0x7d, 0x7b, 0x80, 0x80, 0x7a, 0x73, 0x71, 0x75, 0x7c, 0x86, 0x8d, + 0x8e, 0x88, 0x7e, 0x76, 0x6f, 0x6f, 0x73, 0x79, 0x81, 0x84, 0x85, 0x85, 0x84, 0x84, 0x84, 0x7e, + 0x76, 0x72, 0x73, 0x79, 0x82, 0x8a, 0x8d, 0x8b, 0x85, 0x81, 0x7e, 0x7e, 0x81, 0x81, 0x7b, 0x75, + 0x76, 0x7b, 0x83, 0x8e, 0x93, 0x93, 0x8e, 0x84, 0x7b, 0x73, 0x70, 0x71, 0x73, 0x76, 0x79, 0x7d, + 0x81, 0x81, 0x81, 0x82, 0x81, 0x82, 0x87, 0x86, 0x81, 0x7b, 0x76, 0x74, 0x75, 0x7b, 0x83, 0x84, + 0x83, 0x7d, 0x7a, 0x7c, 0x80, 0x81, 0x80, 0x7e, 0x7b, 0x7b, 0x80, 0x85, 0x89, 0x8b, 0x88, 0x7e, + 0x79, 0x78, 0x7a, 0x7e, 0x81, 0x84, 0x82, 0x7b, 0x7a, 0x7b, 0x80, 0x83, 0x84, 0x82, 0x7c, 0x7b, + 0x7e, 0x84, 0x85, 0x83, 0x7d, 0x76, 0x71, 0x75, 0x7d, 0x83, 0x86, 0x86, 0x84, 0x82, 0x81, 0x81, + 0x7c, 0x76, 0x73, 0x72, 0x73, 0x79, 0x84, 0x8c, 0x8e, 0x8a, 0x81, 0x79, 0x75, 0x78, 0x80, 0x86, + 0x88, 0x85, 0x7c, 0x74, 0x75, 0x7a, 0x81, 0x85, 0x85, 0x81, 0x7e, 0x83, 0x88, 0x87, 0x84, 0x7c, + 0x70, 0x64, 0x64, 0x75, 0x90, 0x9e, 0x9d, 0x94, 0x89, 0x82, 0x74, 0x5f, 0x5b, 0x72, 0x94, 0x96, + 0x7b, 0x6b, 0x78, 0x92, 0x97, 0x89, 0x77, 0x6d, 0x6f, 0x77, 0x8a, 0xa2, 0xad, 0x97, 0x6c, 0x4d, + 0x4e, 0x69, 0x8b, 0xa2, 0xa6, 0x95, 0x7a, 0x68, 0x69, 0x7b, 0x8a, 0x86, 0x79, 0x74, 0x78, 0x84, + 0x8f, 0x94, 0x8c, 0x74, 0x5f, 0x60, 0x74, 0x93, 0xa2, 0x9a, 0x87, 0x71, 0x64, 0x63, 0x70, 0x84, + 0x8e, 0x88, 0x7a, 0x76, 0x7c, 0x86, 0x8c, 0x8a, 0x82, 0x77, 0x70, 0x76, 0x84, 0x8c, 0x85, 0x72, + 0x64, 0x6b, 0x84, 0x97, 0x9b, 0x90, 0x83, 0x81, 0x7c, 0x74, 0x6f, 0x79, 0x88, 0x8a, 0x83, 0x84, + 0x8d, 0x89, 0x67, 0x3c, 0x2f, 0x57, 0x9b, 0xce, 0xdf, 0xc9, 0x92, 0x4a, 0x19, 0x17, 0x48, 0x90, + 0xbf, 0xc5, 0xad, 0x91, 0x7d, 0x70, 0x66, 0x60, 0x5d, 0x67, 0x81, 0x9b, 0xba, 0xc9, 0xb2, 0x75, + 0x3a, 0x2c, 0x4a, 0x7c, 0xb4, 0xce, 0xc3, 0x97, 0x63, 0x46, 0x46, 0x5b, 0x74, 0x82, 0x86, 0x91, + 0x9b, 0x9a, 0x8f, 0x7c, 0x67, 0x56, 0x5b, 0x79, 0x97, 0xa5, 0x9e, 0x84, 0x65, 0x58, 0x63, 0x79, + 0x8f, 0x9c, 0x9c, 0x8f, 0x7c, 0x73, 0x6d, 0x6a, 0x6e, 0x76, 0x80, 0x88, 0x91, 0x94, 0x8c, 0x7e, + 0x71, 0x69, 0x6b, 0x77, 0x88, 0x94, 0x94, 0x8c, 0x80, 0x73, 0x70, 0x77, 0x7a, 0x7b, 0x7b, 0x7d, + 0x83, 0x87, 0x89, 0x85, 0x7a, 0x70, 0x6b, 0x72, 0x82, 0x91, 0x99, 0x96, 0x85, 0x65, 0x40, 0x37, + 0x58, 0x9b, 0xd2, 0xd5, 0xa5, 0x68, 0x42, 0x3f, 0x54, 0x6b, 0x8a, 0xa7, 0xb4, 0xa9, 0x90, 0x7a, + 0x72, 0x69, 0x58, 0x4f, 0x62, 0x94, 0xbd, 0xbf, 0x9c, 0x6f, 0x52, 0x46, 0x4a, 0x66, 0x96, 0xb8, + 0xb3, 0x8e, 0x6a, 0x60, 0x6b, 0x74, 0x70, 0x70, 0x7a, 0x89, 0x93, 0x93, 0x8f, 0x86, 0x73, 0x60, + 0x61, 0x7a, 0x98, 0xa4, 0x9b, 0x85, 0x71, 0x68, 0x6b, 0x78, 0x84, 0x89, 0x85, 0x7c, 0x7b, 0x84, + 0x8b, 0x87, 0x79, 0x6c, 0x65, 0x69, 0x78, 0x8e, 0x98, 0x92, 0x85, 0x75, 0x6f, 0x71, 0x7c, 0x87, + 0x8d, 0x8d, 0x86, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x80, 0x85, 0x8c, 0x8e, 0x87, 0x6f, 0x45, 0x27, + 0x38, 0x77, 0xc1, 0xe1, 0xcc, 0x94, 0x58, 0x2f, 0x29, 0x51, 0x8f, 0xb9, 0xbe, 0xab, 0x94, 0x81, + 0x70, 0x65, 0x5d, 0x5f, 0x70, 0x93, 0xba, 0xc4, 0xae, 0x88, 0x58, 0x35, 0x38, 0x64, 0x99, 0xb5, + 0xb2, 0x99, 0x79, 0x5e, 0x54, 0x5f, 0x70, 0x81, 0x8e, 0x92, 0x8d, 0x88, 0x83, 0x78, 0x6c, 0x68, + 0x6d, 0x7c, 0x96, 0xac, 0xa8, 0x8f, 0x71, 0x60, 0x5e, 0x6c, 0x87, 0x9c, 0xa0, 0x97, 0x89, 0x79, + 0x6f, 0x6d, 0x72, 0x79, 0x7d, 0x83, 0x85, 0x84, 0x83, 0x80, 0x7a, 0x75, 0x77, 0x7e, 0x84, 0x87, + 0x86, 0x81, 0x7e, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x82, 0x82, 0x81, 0x7d, 0x80, + 0x89, 0x91, 0x8e, 0x6f, 0x3d, 0x23, 0x47, 0x9b, 0xe2, 0xea, 0xb9, 0x75, 0x43, 0x2e, 0x36, 0x5c, + 0x95, 0xc0, 0xc1, 0xa2, 0x87, 0x82, 0x80, 0x6c, 0x50, 0x49, 0x69, 0x9a, 0xb9, 0xba, 0xa7, 0x85, + 0x5a, 0x3d, 0x46, 0x73, 0xa1, 0xb4, 0xa6, 0x85, 0x69, 0x5e, 0x60, 0x67, 0x74, 0x8a, 0x9b, 0x9d, + 0x93, 0x88, 0x79, 0x66, 0x58, 0x5c, 0x75, 0x9a, 0xb4, 0xb4, 0x9b, 0x7a, 0x60, 0x56, 0x5e, 0x78, + 0x94, 0xa0, 0x9c, 0x8b, 0x79, 0x6c, 0x69, 0x6e, 0x76, 0x80, 0x8c, 0x94, 0x8e, 0x83, 0x75, 0x6b, + 0x6b, 0x76, 0x8a, 0x99, 0x9c, 0x94, 0x81, 0x6c, 0x63, 0x67, 0x76, 0x89, 0x95, 0x96, 0x8d, 0x86, + 0x7c, 0x75, 0x70, 0x71, 0x76, 0x82, 0x93, 0xa1, 0x9a, 0x72, 0x3d, 0x29, 0x51, 0xa2, 0xe2, 0xe7, + 0xa9, 0x4e, 0x1d, 0x2d, 0x64, 0x9d, 0xb4, 0xab, 0x9a, 0x8e, 0x86, 0x7e, 0x72, 0x65, 0x58, 0x57, + 0x6d, 0x95, 0xbc, 0xc6, 0xa5, 0x6a, 0x3a, 0x34, 0x59, 0x8d, 0xae, 0xb0, 0x9c, 0x81, 0x6a, 0x61, + 0x67, 0x77, 0x83, 0x85, 0x84, 0x87, 0x92, 0x95, 0x88, 0x71, 0x60, 0x63, 0x7b, 0x96, 0xa5, 0xa3, + 0x8e, 0x70, 0x5c, 0x5a, 0x6b, 0x86, 0x9a, 0x9e, 0x92, 0x84, 0x77, 0x70, 0x6d, 0x6c, 0x70, 0x77, + 0x83, 0x8e, 0x91, 0x8c, 0x83, 0x76, 0x71, 0x76, 0x83, 0x90, 0x94, 0x8f, 0x84, 0x78, 0x71, 0x72, + 0x78, 0x82, 0x8b, 0x8c, 0x87, 0x7d, 0x73, 0x63, 0x4f, 0x4a, 0x65, 0x94, 0xba, 0xc1, 0xab, 0x85, + 0x58, 0x3f, 0x49, 0x6b, 0x91, 0xae, 0xb7, 0xa8, 0x8c, 0x76, 0x6e, 0x69, 0x65, 0x6f, 0x85, 0x99, + 0xa5, 0xa1, 0x8e, 0x6f, 0x54, 0x4d, 0x5c, 0x7b, 0x9d, 0xae, 0xa8, 0x8e, 0x6f, 0x5a, 0x53, 0x5c, + 0x72, 0x86, 0x94, 0x9b, 0x98, 0x8b, 0x7a, 0x71, 0x6e, 0x6f, 0x79, 0x8a, 0x99, 0x9e, 0x94, 0x82, + 0x70, 0x66, 0x69, 0x75, 0x88, 0x97, 0x9d, 0x94, 0x82, 0x71, 0x6a, 0x68, 0x6d, 0x79, 0x86, 0x8d, + 0x90, 0x8c, 0x83, 0x75, 0x6b, 0x69, 0x6f, 0x7d, 0x90, 0x9a, 0x9a, 0x8d, 0x77, 0x67, 0x64, 0x6f, + 0x81, 0x91, 0x9a, 0x94, 0x85, 0x76, 0x74, 0x7d, 0x84, 0x76, 0x55, 0x3a, 0x4d, 0x8f, 0xcf, 0xdd, + 0xb2, 0x73, 0x45, 0x36, 0x48, 0x70, 0xa5, 0xc4, 0xb8, 0x91, 0x71, 0x6f, 0x78, 0x75, 0x6b, 0x68, + 0x74, 0x8e, 0xa8, 0xae, 0x9b, 0x76, 0x54, 0x47, 0x54, 0x7b, 0xa8, 0xbe, 0xae, 0x84, 0x5f, 0x51, + 0x5a, 0x6a, 0x7a, 0x8b, 0x96, 0x9c, 0x9a, 0x8f, 0x7c, 0x68, 0x5a, 0x5c, 0x70, 0x91, 0xac, 0xb0, + 0x9d, 0x79, 0x5b, 0x53, 0x61, 0x78, 0x8e, 0x9b, 0x98, 0x8a, 0x7a, 0x71, 0x72, 0x76, 0x79, 0x7a, + 0x7e, 0x88, 0x8f, 0x90, 0x88, 0x7a, 0x71, 0x6f, 0x77, 0x85, 0x8c, 0x8b, 0x82, 0x75, 0x6e, 0x73, + 0x80, 0x8b, 0x91, 0x8e, 0x87, 0x82, 0x83, 0x80, 0x69, 0x44, 0x2e, 0x4a, 0x8f, 0xd4, 0xec, 0xc6, + 0x81, 0x45, 0x27, 0x30, 0x5c, 0x9a, 0xc7, 0xc5, 0xa5, 0x83, 0x71, 0x6d, 0x67, 0x61, 0x61, 0x75, + 0x97, 0xb7, 0xc0, 0xa8, 0x76, 0x48, 0x32, 0x40, 0x6f, 0xa7, 0xc6, 0xbf, 0x9d, 0x71, 0x54, 0x4f, + 0x5c, 0x6e, 0x7d, 0x8a, 0x95, 0x9b, 0x98, 0x8b, 0x77, 0x66, 0x60, 0x6a, 0x82, 0x9b, 0xab, 0xa7, + 0x8e, 0x6e, 0x5a, 0x5b, 0x6d, 0x89, 0x9f, 0xa3, 0x96, 0x81, 0x71, 0x6c, 0x6e, 0x76, 0x7d, 0x84, + 0x89, 0x8a, 0x87, 0x7d, 0x74, 0x6d, 0x6a, 0x74, 0x87, 0x97, 0x9d, 0x94, 0x85, 0x74, 0x69, 0x69, + 0x73, 0x82, 0x8b, 0x8d, 0x89, 0x83, 0x7d, 0x7b, 0x81, 0x85, 0x87, 0x81, 0x6e, 0x58, 0x53, 0x6e, + 0x9a, 0xb6, 0xac, 0x87, 0x65, 0x56, 0x59, 0x6f, 0x8a, 0x9e, 0xa3, 0x97, 0x85, 0x7a, 0x76, 0x75, + 0x73, 0x71, 0x71, 0x78, 0x89, 0x9a, 0xa0, 0x97, 0x82, 0x6b, 0x60, 0x65, 0x79, 0x90, 0x99, 0x94, + 0x87, 0x75, 0x6e, 0x72, 0x7b, 0x81, 0x81, 0x81, 0x83, 0x87, 0x88, 0x84, 0x7c, 0x76, 0x72, 0x74, + 0x7b, 0x84, 0x8c, 0x8d, 0x87, 0x7d, 0x77, 0x73, 0x77, 0x7d, 0x80, 0x7e, 0x7d, 0x7e, 0x81, 0x82, + 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7e, 0x81, 0x84, 0x83, 0x81, 0x81, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7e, 0x84, 0x86, 0x86, 0x83, 0x7d, 0x79, 0x77, 0x79, 0x7c, 0x80, 0x81, 0x81, 0x80, 0x7e, + 0x7e, 0x80, 0x81, 0x81, 0x7d, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, 0x7d, + 0x7e, 0x80, 0x82, 0x84, 0x84, 0x84, 0x84, 0x81, 0x7d, 0x7c, 0x7c, 0x7c, 0x7a, 0x7b, 0x80, 0x82, + 0x84, 0x86, 0x85, 0x82, 0x80, 0x80, 0x7e, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7e, 0x82, 0x84, 0x84, + 0x83, 0x80, 0x7d, 0x7d, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x80, 0x80, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7a, 0x78, 0x7a, 0x7d, 0x82, 0x84, + 0x83, 0x7e, 0x7b, 0x7b, 0x7d, 0x80, 0x80, 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x83, 0x86, 0x87, 0x86, + 0x81, 0x7c, 0x79, 0x78, 0x77, 0x78, 0x7b, 0x80, 0x84, 0x88, 0x89, 0x87, 0x83, 0x7e, 0x7a, 0x7a, + 0x7a, 0x7c, 0x80, 0x82, 0x83, 0x83, 0x83, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7e, + 0x80, 0x83, 0x86, 0x86, 0x83, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x80, 0x7e, 0x80, + 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x80, 0x82, 0x81, + 0x82, 0x82, 0x83, 0x81, 0x7c, 0x7b, 0x7b, 0x7b, 0x7d, 0x7e, 0x82, 0x84, 0x85, 0x84, 0x83, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7c, 0x7a, 0x7a, 0x7d, 0x84, 0x88, + 0x8b, 0x88, 0x80, 0x78, 0x73, 0x72, 0x75, 0x78, 0x7c, 0x80, 0x83, 0x84, 0x85, 0x85, 0x85, 0x82, + 0x7d, 0x77, 0x75, 0x76, 0x7a, 0x80, 0x84, 0x86, 0x86, 0x86, 0x85, 0x83, 0x7e, 0x7b, 0x78, 0x76, + 0x78, 0x7b, 0x80, 0x83, 0x85, 0x84, 0x80, 0x7d, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, 0x83, 0x84, + 0x84, 0x82, 0x7e, 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x80, + 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7a, + 0x7b, 0x7e, 0x81, 0x82, 0x84, 0x83, 0x80, 0x7b, 0x78, 0x77, 0x79, 0x7b, 0x81, 0x88, 0x8b, 0x8a, + 0x86, 0x7d, 0x77, 0x75, 0x76, 0x7a, 0x7d, 0x81, 0x81, 0x81, 0x81, 0x82, 0x83, 0x83, 0x80, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7e, 0x7b, 0x78, 0x76, 0x78, 0x7c, 0x82, 0x85, 0x83, 0x81, 0x7d, 0x79, 0x77, + 0x76, 0x76, 0x79, 0x7a, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x83, 0x7e, 0x7b, 0x79, 0x79, 0x7b, 0x81, + 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7b, 0x7b, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x7e, + 0x7b, 0x7c, 0x7e, 0x81, 0x82, 0x83, 0x80, 0x7b, 0x7a, 0x7c, 0x80, 0x83, 0x87, 0x87, 0x82, 0x7e, + 0x7c, 0x7c, 0x7e, 0x82, 0x84, 0x82, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7a, 0x77, 0x76, + 0x77, 0x7a, 0x81, 0x85, 0x87, 0x87, 0x83, 0x7e, 0x7c, 0x7b, 0x7a, 0x7c, 0x7d, 0x7c, 0x7e, 0x83, + 0x87, 0x89, 0x87, 0x82, 0x7c, 0x79, 0x79, 0x7b, 0x84, 0x88, 0x87, 0x82, 0x7e, 0x7c, 0x7b, 0x7d, + 0x7e, 0x7e, 0x81, 0x82, 0x81, 0x82, 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x82, 0x85, 0x85, + 0x83, 0x80, 0x80, 0x81, 0x82, 0x83, 0x80, 0x7a, 0x79, 0x7a, 0x7d, 0x81, 0x82, 0x80, 0x7b, 0x79, + 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x81, 0x7e, 0x80, 0x80, 0x83, 0x83, 0x80, 0x7c, 0x79, 0x78, 0x7a, + 0x7e, 0x80, 0x81, 0x80, 0x80, 0x83, 0x84, 0x84, 0x84, 0x81, 0x7b, 0x76, 0x76, 0x78, 0x7c, 0x82, + 0x86, 0x87, 0x84, 0x81, 0x79, 0x74, 0x75, 0x79, 0x81, 0x86, 0x88, 0x83, 0x7c, 0x7a, 0x7d, 0x83, + 0x87, 0x86, 0x80, 0x79, 0x78, 0x7a, 0x7e, 0x83, 0x81, 0x7a, 0x76, 0x77, 0x7e, 0x89, 0x8f, 0x8d, + 0x85, 0x7c, 0x79, 0x7a, 0x80, 0x84, 0x83, 0x80, 0x7c, 0x7c, 0x80, 0x84, 0x85, 0x7e, 0x78, 0x74, + 0x76, 0x7e, 0x86, 0x8c, 0x8b, 0x82, 0x78, 0x78, 0x7c, 0x80, 0x83, 0x84, 0x7e, 0x79, 0x7a, 0x7d, + 0x81, 0x83, 0x82, 0x7c, 0x7c, 0x82, 0x87, 0x89, 0x86, 0x7e, 0x74, 0x6f, 0x72, 0x79, 0x7e, 0x82, + 0x82, 0x82, 0x84, 0x87, 0x89, 0x89, 0x85, 0x7e, 0x78, 0x77, 0x7a, 0x7e, 0x82, 0x82, 0x80, 0x7e, + 0x7e, 0x80, 0x7e, 0x76, 0x6e, 0x6b, 0x70, 0x7b, 0x85, 0x8d, 0x89, 0x80, 0x7a, 0x7c, 0x82, 0x86, + 0x87, 0x81, 0x77, 0x74, 0x79, 0x83, 0x8a, 0x8a, 0x80, 0x74, 0x70, 0x73, 0x80, 0x8c, 0x8f, 0x8a, + 0x85, 0x82, 0x83, 0x88, 0x89, 0x82, 0x76, 0x70, 0x70, 0x77, 0x86, 0x8f, 0x8d, 0x85, 0x7b, 0x77, + 0x79, 0x81, 0x86, 0x83, 0x7a, 0x76, 0x79, 0x82, 0x89, 0x8a, 0x84, 0x79, 0x72, 0x74, 0x7a, 0x82, + 0x87, 0x84, 0x7b, 0x78, 0x7d, 0x86, 0x8d, 0x8e, 0x87, 0x7d, 0x75, 0x75, 0x77, 0x7b, 0x7d, 0x7c, + 0x7b, 0x7e, 0x86, 0x8c, 0x8f, 0x8b, 0x81, 0x76, 0x72, 0x76, 0x7a, 0x7e, 0x80, 0x7e, 0x81, 0x82, + 0x86, 0x87, 0x82, 0x79, 0x6b, 0x64, 0x65, 0x72, 0x85, 0x8d, 0x8e, 0x87, 0x7b, 0x78, 0x7d, 0x84, + 0x84, 0x80, 0x77, 0x6f, 0x73, 0x7d, 0x89, 0x8e, 0x89, 0x7d, 0x74, 0x77, 0x80, 0x8c, 0x90, 0x8a, + 0x80, 0x79, 0x80, 0x87, 0x8c, 0x8c, 0x84, 0x77, 0x6f, 0x73, 0x7e, 0x88, 0x8a, 0x86, 0x7e, 0x78, + 0x7b, 0x84, 0x87, 0x83, 0x7a, 0x72, 0x70, 0x75, 0x80, 0x86, 0x82, 0x7d, 0x7a, 0x7a, 0x82, 0x88, + 0x89, 0x85, 0x7e, 0x7a, 0x79, 0x7d, 0x82, 0x81, 0x79, 0x75, 0x73, 0x77, 0x80, 0x86, 0x89, 0x87, + 0x84, 0x85, 0x84, 0x85, 0x83, 0x7e, 0x79, 0x75, 0x76, 0x78, 0x7b, 0x7e, 0x80, 0x81, 0x82, 0x83, + 0x82, 0x7a, 0x70, 0x68, 0x68, 0x72, 0x7e, 0x86, 0x86, 0x7e, 0x78, 0x7c, 0x85, 0x8e, 0x8f, 0x84, + 0x72, 0x65, 0x69, 0x76, 0x85, 0x8d, 0x88, 0x7b, 0x75, 0x7a, 0x85, 0x90, 0x91, 0x84, 0x76, 0x73, + 0x79, 0x84, 0x8e, 0x8e, 0x81, 0x74, 0x73, 0x79, 0x83, 0x88, 0x86, 0x7c, 0x75, 0x79, 0x84, 0x8b, + 0x8d, 0x85, 0x79, 0x71, 0x71, 0x79, 0x82, 0x82, 0x7d, 0x77, 0x74, 0x7b, 0x86, 0x87, 0x83, 0x7b, + 0x76, 0x75, 0x7d, 0x88, 0x8b, 0x85, 0x7c, 0x76, 0x75, 0x79, 0x83, 0x84, 0x81, 0x7e, 0x7d, 0x81, + 0x86, 0x8a, 0x88, 0x83, 0x7e, 0x7e, 0x81, 0x82, 0x82, 0x7e, 0x7a, 0x79, 0x7b, 0x84, 0x89, 0x86, + 0x7d, 0x6e, 0x64, 0x67, 0x75, 0x82, 0x88, 0x85, 0x7a, 0x75, 0x7b, 0x89, 0x91, 0x90, 0x87, 0x74, + 0x6a, 0x6e, 0x7a, 0x88, 0x8a, 0x82, 0x78, 0x75, 0x7d, 0x89, 0x92, 0x8f, 0x81, 0x74, 0x72, 0x7b, + 0x87, 0x8d, 0x8b, 0x7d, 0x74, 0x76, 0x80, 0x89, 0x8b, 0x85, 0x7b, 0x76, 0x78, 0x83, 0x89, 0x86, + 0x80, 0x7a, 0x78, 0x80, 0x89, 0x8b, 0x86, 0x7d, 0x76, 0x74, 0x78, 0x80, 0x82, 0x80, 0x80, 0x83, + 0x85, 0x89, 0x8d, 0x89, 0x7e, 0x78, 0x76, 0x78, 0x79, 0x7c, 0x80, 0x7e, 0x81, 0x86, 0x89, 0x89, + 0x88, 0x85, 0x81, 0x80, 0x81, 0x81, 0x7e, 0x7c, 0x7b, 0x7a, 0x7d, 0x83, 0x85, 0x81, 0x76, 0x6c, + 0x65, 0x6a, 0x77, 0x82, 0x87, 0x86, 0x7c, 0x77, 0x80, 0x8b, 0x91, 0x8e, 0x82, 0x73, 0x6b, 0x6f, + 0x7b, 0x85, 0x87, 0x80, 0x77, 0x78, 0x82, 0x8a, 0x90, 0x8a, 0x7b, 0x73, 0x76, 0x81, 0x8a, 0x8f, + 0x8b, 0x7e, 0x77, 0x78, 0x7c, 0x82, 0x82, 0x7c, 0x78, 0x78, 0x7e, 0x89, 0x8b, 0x88, 0x82, 0x7b, + 0x79, 0x7c, 0x81, 0x80, 0x7a, 0x77, 0x76, 0x78, 0x80, 0x86, 0x86, 0x83, 0x82, 0x82, 0x83, 0x85, + 0x84, 0x7c, 0x77, 0x78, 0x7a, 0x7e, 0x82, 0x82, 0x7c, 0x7a, 0x7b, 0x7d, 0x82, 0x84, 0x83, 0x83, + 0x84, 0x86, 0x88, 0x87, 0x82, 0x7d, 0x7b, 0x7b, 0x7e, 0x81, 0x81, 0x7e, 0x78, 0x6f, 0x6d, 0x73, + 0x7c, 0x85, 0x87, 0x82, 0x79, 0x77, 0x80, 0x89, 0x8e, 0x8c, 0x81, 0x73, 0x6e, 0x72, 0x7c, 0x83, + 0x81, 0x7b, 0x77, 0x7a, 0x85, 0x8e, 0x91, 0x89, 0x7c, 0x77, 0x79, 0x81, 0x8a, 0x8b, 0x85, 0x7b, + 0x79, 0x7d, 0x82, 0x84, 0x82, 0x7b, 0x75, 0x78, 0x81, 0x84, 0x86, 0x82, 0x7c, 0x79, 0x7c, 0x83, + 0x84, 0x7e, 0x7a, 0x77, 0x75, 0x7a, 0x81, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x82, 0x85, 0x84, 0x82, + 0x81, 0x80, 0x7e, 0x7d, 0x7b, 0x79, 0x78, 0x7b, 0x81, 0x85, 0x89, 0x88, 0x86, 0x84, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7a, 0x74, 0x6e, 0x6d, 0x73, 0x7c, 0x85, + 0x88, 0x87, 0x83, 0x82, 0x84, 0x85, 0x83, 0x7a, 0x73, 0x70, 0x73, 0x7c, 0x83, 0x84, 0x80, 0x7b, + 0x7a, 0x7e, 0x84, 0x87, 0x84, 0x7c, 0x7a, 0x7c, 0x80, 0x85, 0x86, 0x85, 0x83, 0x83, 0x85, 0x84, + 0x80, 0x7b, 0x79, 0x78, 0x7c, 0x83, 0x85, 0x85, 0x83, 0x80, 0x7c, 0x7c, 0x7e, 0x7c, 0x7a, 0x7c, + 0x7e, 0x81, 0x83, 0x82, 0x80, 0x7d, 0x7d, 0x80, 0x7d, 0x7a, 0x7a, 0x7a, 0x7c, 0x81, 0x84, 0x84, + 0x81, 0x7d, 0x7a, 0x78, 0x79, 0x79, 0x7b, 0x80, 0x83, 0x87, 0x88, 0x87, 0x85, 0x82, 0x80, 0x7e, + 0x7d, 0x7c, 0x79, 0x76, 0x76, 0x7a, 0x7d, 0x7e, 0x7c, 0x74, 0x6e, 0x6f, 0x75, 0x7e, 0x85, 0x8a, + 0x8a, 0x86, 0x84, 0x81, 0x79, 0x76, 0x76, 0x76, 0x79, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x81, 0x83, + 0x83, 0x7e, 0x7a, 0x76, 0x77, 0x7e, 0x85, 0x8a, 0x8d, 0x8b, 0x86, 0x7e, 0x79, 0x76, 0x76, 0x79, + 0x81, 0x84, 0x84, 0x84, 0x83, 0x83, 0x85, 0x8a, 0x89, 0x83, 0x7c, 0x78, 0x76, 0x77, 0x7b, 0x82, + 0x85, 0x86, 0x87, 0x83, 0x7c, 0x7a, 0x79, 0x79, 0x7b, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x86, 0x88, + 0x87, 0x83, 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x83, 0x85, 0x87, 0x86, 0x83, 0x81, 0x7e, 0x7c, 0x7c, + 0x7b, 0x78, 0x77, 0x77, 0x77, 0x7a, 0x7e, 0x82, 0x82, 0x80, 0x7b, 0x77, 0x77, 0x7c, 0x84, 0x8b, + 0x8e, 0x8b, 0x83, 0x79, 0x73, 0x70, 0x70, 0x74, 0x79, 0x7c, 0x7e, 0x7d, 0x7c, 0x7e, 0x85, 0x8a, + 0x8d, 0x8b, 0x84, 0x7b, 0x77, 0x79, 0x80, 0x86, 0x89, 0x88, 0x83, 0x7d, 0x7b, 0x7a, 0x7c, 0x7e, + 0x80, 0x80, 0x7e, 0x7c, 0x7c, 0x82, 0x89, 0x8e, 0x8d, 0x88, 0x80, 0x77, 0x76, 0x78, 0x7d, 0x83, + 0x86, 0x86, 0x84, 0x82, 0x81, 0x82, 0x83, 0x83, 0x81, 0x7b, 0x77, 0x76, 0x7b, 0x82, 0x88, 0x89, + 0x86, 0x81, 0x7b, 0x79, 0x79, 0x7c, 0x80, 0x80, 0x7e, 0x7c, 0x7b, 0x7c, 0x7c, 0x7e, 0x80, 0x81, + 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x82, 0x81, 0x7b, 0x73, 0x6e, 0x6e, + 0x72, 0x79, 0x83, 0x89, 0x89, 0x86, 0x80, 0x7b, 0x78, 0x78, 0x7c, 0x80, 0x83, 0x83, 0x81, 0x80, + 0x82, 0x85, 0x86, 0x83, 0x7d, 0x77, 0x74, 0x75, 0x79, 0x81, 0x88, 0x8c, 0x8a, 0x86, 0x82, 0x7e, + 0x7e, 0x80, 0x81, 0x7e, 0x7c, 0x7a, 0x7a, 0x7d, 0x83, 0x86, 0x86, 0x85, 0x81, 0x7d, 0x7b, 0x7c, + 0x80, 0x82, 0x84, 0x84, 0x81, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x7d, 0x7a, 0x79, 0x7c, 0x81, 0x87, + 0x89, 0x88, 0x85, 0x7e, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x7d, 0x7a, 0x7a, 0x7b, 0x7e, 0x83, 0x84, + 0x84, 0x80, 0x7b, 0x7b, 0x7d, 0x81, 0x83, 0x84, 0x85, 0x86, 0x85, 0x85, 0x85, 0x84, 0x83, 0x81, + 0x7d, 0x79, 0x77, 0x78, 0x7c, 0x81, 0x84, 0x86, 0x85, 0x82, 0x7d, 0x7a, 0x78, 0x7a, 0x80, 0x82, + 0x81, 0x7d, 0x7a, 0x7b, 0x80, 0x84, 0x87, 0x87, 0x83, 0x7d, 0x79, 0x79, 0x7d, 0x82, 0x85, 0x85, + 0x83, 0x82, 0x81, 0x82, 0x82, 0x82, 0x7e, 0x7b, 0x78, 0x76, 0x77, 0x7d, 0x84, 0x88, 0x88, 0x84, + 0x80, 0x7b, 0x79, 0x79, 0x7a, 0x7b, 0x7b, 0x7c, 0x7e, 0x82, 0x84, 0x84, 0x82, 0x80, 0x7c, 0x7a, + 0x79, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7b, + 0x7d, 0x80, 0x83, 0x85, 0x86, 0x85, 0x83, 0x7e, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x81, 0x83, + 0x83, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x79, 0x7b, 0x7e, 0x83, 0x85, 0x85, 0x83, + 0x80, 0x7c, 0x78, 0x77, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x84, 0x84, 0x83, 0x81, 0x7d, 0x7a, + 0x78, 0x77, 0x79, 0x7c, 0x80, 0x83, 0x84, 0x84, 0x84, 0x85, 0x84, 0x83, 0x83, 0x7e, 0x7c, 0x7c, + 0x7c, 0x7d, 0x81, 0x83, 0x84, 0x85, 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7c, 0x7c, 0x7b, 0x7d, 0x81, + 0x82, 0x85, 0x87, 0x87, 0x85, 0x82, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x83, 0x85, 0x85, 0x84, + 0x81, 0x7e, 0x7c, 0x79, 0x78, 0x78, 0x7a, 0x7e, 0x81, 0x83, 0x83, 0x82, 0x7e, 0x7b, 0x78, 0x77, + 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x80, 0x81, 0x82, 0x82, + 0x7e, 0x7b, 0x7b, 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x78, 0x77, + 0x79, 0x7c, 0x82, 0x86, 0x87, 0x87, 0x85, 0x80, 0x7c, 0x79, 0x75, 0x75, 0x77, 0x7a, 0x80, 0x84, + 0x87, 0x89, 0x87, 0x85, 0x81, 0x7a, 0x76, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x85, 0x86, 0x85, 0x83, + 0x81, 0x7c, 0x7a, 0x7a, 0x7b, 0x7d, 0x80, 0x82, 0x85, 0x86, 0x85, 0x84, 0x82, 0x80, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x83, 0x81, 0x7e, 0x7d, 0x7a, 0x7a, + 0x7b, 0x7b, 0x7c, 0x80, 0x83, 0x84, 0x84, 0x83, 0x82, 0x7e, 0x7a, 0x78, 0x78, 0x79, 0x7b, 0x7e, + 0x82, 0x84, 0x85, 0x84, 0x80, 0x7c, 0x7a, 0x78, 0x77, 0x75, 0x75, 0x77, 0x7b, 0x7e, 0x82, 0x84, + 0x83, 0x81, 0x7d, 0x7b, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7b, 0x7e, 0x82, 0x85, 0x87, 0x86, + 0x82, 0x7c, 0x77, 0x76, 0x76, 0x77, 0x79, 0x7b, 0x80, 0x83, 0x86, 0x88, 0x87, 0x83, 0x7d, 0x77, + 0x74, 0x75, 0x79, 0x7e, 0x85, 0x87, 0x87, 0x84, 0x80, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7c, + 0x7e, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7e, + 0x81, 0x83, 0x84, 0x83, 0x83, 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x84, + 0x85, 0x86, 0x85, 0x82, 0x80, 0x7d, 0x7a, 0x79, 0x7b, 0x7d, 0x81, 0x84, 0x85, 0x85, 0x84, 0x83, + 0x81, 0x7e, 0x7b, 0x79, 0x78, 0x76, 0x78, 0x7a, 0x7e, 0x82, 0x83, 0x82, 0x81, 0x80, 0x7d, 0x7a, + 0x79, 0x7b, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x82, 0x83, 0x83, 0x80, 0x7d, 0x7d, 0x7e, 0x80, 0x81, + 0x81, 0x80, 0x7d, 0x7d, 0x80, 0x84, 0x87, 0x89, 0x88, 0x85, 0x81, 0x7c, 0x79, 0x77, 0x78, 0x7d, + 0x84, 0x88, 0x8a, 0x89, 0x87, 0x85, 0x83, 0x82, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, + 0x80, 0x81, 0x83, 0x83, 0x83, 0x81, 0x7e, 0x7a, 0x77, 0x77, 0x78, 0x7b, 0x7e, 0x83, 0x86, 0x86, + 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x78, 0x75, 0x76, 0x7b, 0x7e, 0x84, 0x8a, 0x8c, 0x8b, 0x87, 0x80, + 0x7a, 0x76, 0x75, 0x76, 0x79, 0x7d, 0x83, 0x86, 0x87, 0x87, 0x85, 0x82, 0x80, 0x7e, 0x7d, 0x7b, + 0x7a, 0x79, 0x78, 0x79, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x84, 0x82, 0x7e, 0x7d, 0x7c, 0x7a, 0x7a, + 0x7c, 0x7d, 0x81, 0x84, 0x87, 0x88, 0x87, 0x84, 0x7e, 0x7b, 0x7a, 0x78, 0x79, 0x7b, 0x7d, 0x81, + 0x84, 0x87, 0x88, 0x88, 0x86, 0x82, 0x7c, 0x79, 0x78, 0x79, 0x7b, 0x7d, 0x81, 0x83, 0x84, 0x84, + 0x85, 0x84, 0x82, 0x80, 0x7c, 0x7b, 0x79, 0x79, 0x78, 0x7b, 0x88, 0x90, 0x8e, 0x89, 0x82, 0x7a, + 0x76, 0x77, 0x79, 0x7b, 0x81, 0x86, 0x89, 0x89, 0x82, 0x7b, 0x79, 0x7a, 0x7d, 0x80, 0x81, 0x82, + 0x81, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x78, 0x78, 0x87, 0x94, 0x92, 0x83, 0x7a, 0x78, 0x75, 0x74, + 0x73, 0x7c, 0x8b, 0x90, 0x8f, 0x8e, 0x89, 0x81, 0x7a, 0x77, 0x78, 0x77, 0x6e, 0x63, 0x60, 0x66, + 0x77, 0x8f, 0xa3, 0xa9, 0xa3, 0x95, 0x83, 0x70, 0x64, 0x60, 0x5e, 0x58, 0x53, 0x5c, 0x74, 0x95, + 0xb6, 0xc8, 0xc1, 0xa5, 0x85, 0x66, 0x51, 0x4f, 0x5c, 0x6f, 0x80, 0x8a, 0x97, 0xa9, 0xb6, 0xb8, + 0xaa, 0x85, 0x54, 0x33, 0x30, 0x3e, 0x59, 0x80, 0xa0, 0xaf, 0xae, 0xa9, 0xa2, 0x96, 0x89, 0x74, + 0x56, 0x3b, 0x3b, 0x56, 0x78, 0x9e, 0xbb, 0xbe, 0xaa, 0x93, 0x7c, 0x67, 0x60, 0x63, 0x63, 0x61, + 0x68, 0x83, 0xa8, 0xc1, 0xc5, 0xae, 0x81, 0x52, 0x38, 0x33, 0x43, 0x64, 0x8a, 0xa4, 0xb0, 0xb0, + 0xaa, 0x9c, 0x87, 0x71, 0x5f, 0x57, 0x5d, 0x6c, 0x7d, 0x8c, 0x96, 0x97, 0x90, 0x84, 0x77, 0x72, + 0x70, 0x71, 0x72, 0x73, 0x7b, 0x8e, 0xa3, 0xa9, 0x92, 0x64, 0x33, 0x1e, 0x39, 0x79, 0xb4, 0xd1, + 0xd3, 0xbe, 0xa1, 0x88, 0x71, 0x65, 0x61, 0x5c, 0x53, 0x53, 0x6d, 0xa1, 0xd2, 0xdd, 0xbf, 0x87, + 0x53, 0x35, 0x32, 0x43, 0x5d, 0x79, 0x8d, 0x97, 0x9e, 0xa7, 0xb0, 0xb0, 0x95, 0x67, 0x3f, 0x33, + 0x4b, 0x78, 0xa3, 0xba, 0xbb, 0xb0, 0xa0, 0x8b, 0x77, 0x6d, 0x63, 0x54, 0x4b, 0x53, 0x6f, 0x97, + 0xb8, 0xbc, 0xa2, 0x7c, 0x5c, 0x4d, 0x4d, 0x5b, 0x72, 0x8a, 0x9b, 0xa1, 0xa2, 0xa3, 0x9f, 0x92, + 0x79, 0x5e, 0x52, 0x5e, 0x78, 0x94, 0xa3, 0xa2, 0x92, 0x79, 0x69, 0x65, 0x6c, 0x75, 0x76, 0x73, + 0x76, 0x83, 0x91, 0x9d, 0x9c, 0x8b, 0x75, 0x67, 0x63, 0x6d, 0x81, 0x99, 0xae, 0xb5, 0xa1, 0x66, + 0x1f, 0x8, 0x2d, 0x74, 0xbb, 0xda, 0xce, 0xb5, 0x9f, 0x88, 0x6e, 0x5d, 0x55, 0x51, 0x4d, 0x54, + 0x72, 0xa6, 0xd0, 0xd6, 0xb5, 0x7b, 0x4a, 0x34, 0x35, 0x4b, 0x66, 0x7e, 0x90, 0x9d, 0xa8, 0xb2, + 0xb6, 0xa6, 0x81, 0x53, 0x39, 0x3f, 0x5c, 0x84, 0xaa, 0xc0, 0xb7, 0x9a, 0x84, 0x77, 0x6b, 0x5e, + 0x55, 0x54, 0x58, 0x6c, 0x91, 0xab, 0xb4, 0xad, 0x94, 0x6f, 0x52, 0x50, 0x61, 0x75, 0x86, 0x93, + 0x9c, 0xa1, 0xa4, 0x9f, 0x8d, 0x70, 0x5b, 0x50, 0x55, 0x68, 0x84, 0x9a, 0x9e, 0x93, 0x84, 0x76, + 0x6f, 0x6f, 0x75, 0x79, 0x7c, 0x85, 0x8d, 0x90, 0x8d, 0x88, 0x7e, 0x71, 0x67, 0x68, 0x73, 0x84, + 0x93, 0x9f, 0xa0, 0x93, 0x6c, 0x35, 0x17, 0x26, 0x57, 0x9b, 0xd4, 0xf0, 0xe9, 0xc5, 0x98, 0x6c, + 0x4d, 0x3f, 0x3b, 0x40, 0x56, 0x7c, 0xaf, 0xdb, 0xe1, 0xba, 0x76, 0x3d, 0x1e, 0x1e, 0x39, 0x60, + 0x91, 0xb9, 0xc6, 0xc2, 0xc0, 0xb9, 0x9a, 0x6a, 0x44, 0x38, 0x42, 0x69, 0xa0, 0xc2, 0xc5, 0xb5, + 0x9b, 0x71, 0x4a, 0x3f, 0x46, 0x4a, 0x54, 0x6d, 0x90, 0xaf, 0xc1, 0xc0, 0xa7, 0x7e, 0x5f, 0x55, + 0x56, 0x66, 0x83, 0x9e, 0xa8, 0xa6, 0xa2, 0x9a, 0x88, 0x6c, 0x54, 0x40, 0x3d, 0x4e, 0x6e, 0x8e, + 0xa5, 0xb1, 0xab, 0x9a, 0x86, 0x79, 0x75, 0x72, 0x70, 0x70, 0x71, 0x79, 0x86, 0x90, 0x91, 0x89, + 0x7d, 0x72, 0x67, 0x64, 0x6b, 0x75, 0x7b, 0x82, 0x8a, 0x93, 0x98, 0x99, 0x94, 0x89, 0x79, 0x61, + 0x40, 0x2a, 0x3c, 0x7a, 0xc5, 0xf6, 0xed, 0xb9, 0x7d, 0x56, 0x49, 0x46, 0x41, 0x45, 0x5a, 0x7e, + 0xa8, 0xc4, 0xcd, 0xbe, 0x97, 0x61, 0x33, 0x21, 0x3a, 0x6d, 0x9e, 0xb3, 0xb5, 0xb3, 0xad, 0x9d, + 0x81, 0x5d, 0x41, 0x3b, 0x4b, 0x6e, 0x9a, 0xbf, 0xc9, 0xad, 0x80, 0x54, 0x3f, 0x47, 0x59, 0x6b, + 0x7c, 0x94, 0xac, 0xb7, 0xb0, 0xa0, 0x89, 0x6c, 0x52, 0x49, 0x54, 0x6d, 0x8a, 0x99, 0x99, 0x94, + 0x90, 0x8b, 0x80, 0x71, 0x68, 0x67, 0x6a, 0x74, 0x85, 0x93, 0x9b, 0x99, 0x91, 0x85, 0x7b, 0x78, + 0x76, 0x72, 0x72, 0x77, 0x82, 0x89, 0x8b, 0x89, 0x83, 0x7a, 0x74, 0x6f, 0x6f, 0x76, 0x85, 0x91, + 0x91, 0x89, 0x82, 0x7c, 0x7c, 0x80, 0x8a, 0x94, 0x99, 0x8c, 0x54, 0x20, 0x1c, 0x43, 0x92, 0xda, + 0xef, 0xd6, 0xb0, 0x90, 0x71, 0x53, 0x3f, 0x44, 0x56, 0x61, 0x71, 0x9a, 0xca, 0xd8, 0xb0, 0x66, + 0x2c, 0x25, 0x3f, 0x63, 0x83, 0x9f, 0xb7, 0xc2, 0xb8, 0xa3, 0x8f, 0x7b, 0x61, 0x41, 0x32, 0x4b, + 0x8a, 0xc0, 0xc3, 0xa9, 0x8d, 0x73, 0x57, 0x43, 0x49, 0x5f, 0x74, 0x84, 0x96, 0xa7, 0xb4, 0xbb, + 0xad, 0x85, 0x5c, 0x53, 0x5d, 0x63, 0x6b, 0x81, 0x94, 0x9a, 0x96, 0x92, 0x8c, 0x80, 0x6f, 0x5b, + 0x4d, 0x53, 0x74, 0x95, 0xa1, 0xa0, 0x9d, 0x94, 0x83, 0x73, 0x6d, 0x6f, 0x71, 0x78, 0x83, 0x8a, + 0x91, 0x96, 0x8b, 0x74, 0x63, 0x61, 0x69, 0x72, 0x7d, 0x8b, 0x91, 0x8e, 0x87, 0x7e, 0x7e, 0x84, + 0x87, 0x84, 0x81, 0x81, 0x84, 0x85, 0x86, 0x89, 0x8b, 0x85, 0x6b, 0x47, 0x31, 0x40, 0x77, 0xbc, + 0xe3, 0xda, 0xae, 0x7e, 0x64, 0x5f, 0x62, 0x5a, 0x50, 0x57, 0x73, 0x9b, 0xba, 0xc3, 0xb0, 0x89, + 0x5a, 0x39, 0x34, 0x4f, 0x7a, 0x9a, 0xa3, 0x9f, 0xa0, 0xa4, 0x9e, 0x88, 0x6a, 0x57, 0x51, 0x58, + 0x6d, 0x8b, 0xa0, 0xa4, 0x95, 0x7e, 0x6d, 0x68, 0x6f, 0x72, 0x6d, 0x6b, 0x77, 0x8e, 0x9e, 0xa2, + 0x9e, 0x93, 0x7e, 0x6e, 0x69, 0x6f, 0x78, 0x7e, 0x81, 0x7b, 0x7a, 0x85, 0x8d, 0x8b, 0x83, 0x7a, + 0x75, 0x73, 0x75, 0x7d, 0x87, 0x87, 0x84, 0x81, 0x81, 0x84, 0x88, 0x88, 0x81, 0x7a, 0x7b, 0x80, + 0x82, 0x7e, 0x7a, 0x75, 0x72, 0x74, 0x7a, 0x83, 0x89, 0x8b, 0x86, 0x81, 0x7c, 0x7b, 0x7a, 0x76, + 0x71, 0x74, 0x82, 0x92, 0x9e, 0x9f, 0x92, 0x7b, 0x6b, 0x6a, 0x75, 0x7e, 0x75, 0x56, 0x3f, 0x4b, + 0x81, 0xc9, 0xf2, 0xe0, 0xa2, 0x61, 0x44, 0x51, 0x6a, 0x72, 0x6b, 0x65, 0x72, 0x92, 0xab, 0xaf, + 0x9e, 0x7a, 0x55, 0x3c, 0x41, 0x60, 0x92, 0xb3, 0xb4, 0xa1, 0x8e, 0x8d, 0x8f, 0x84, 0x6a, 0x55, + 0x53, 0x63, 0x7d, 0x99, 0xa8, 0xa5, 0x8d, 0x70, 0x5f, 0x5f, 0x6b, 0x78, 0x80, 0x80, 0x83, 0x92, + 0xa2, 0xa2, 0x91, 0x7c, 0x6d, 0x64, 0x65, 0x72, 0x82, 0x87, 0x83, 0x78, 0x72, 0x74, 0x7d, 0x84, + 0x82, 0x7c, 0x7c, 0x85, 0x8c, 0x8d, 0x8b, 0x86, 0x7a, 0x72, 0x72, 0x78, 0x7e, 0x81, 0x80, 0x7a, + 0x77, 0x7d, 0x87, 0x8a, 0x86, 0x7d, 0x77, 0x73, 0x73, 0x7a, 0x82, 0x86, 0x84, 0x82, 0x80, 0x7b, + 0x79, 0x78, 0x76, 0x76, 0x7d, 0x84, 0x87, 0x86, 0x83, 0x7e, 0x7d, 0x80, 0x84, 0x85, 0x82, 0x7b, + 0x76, 0x75, 0x79, 0x80, 0x87, 0x8a, 0x84, 0x73, 0x61, 0x58, 0x60, 0x7b, 0x9e, 0xb5, 0xb5, 0xa0, + 0x83, 0x6a, 0x60, 0x65, 0x6f, 0x74, 0x73, 0x74, 0x80, 0x91, 0xa0, 0x9f, 0x8a, 0x6c, 0x5a, 0x5b, + 0x6b, 0x83, 0x95, 0x9e, 0x9a, 0x92, 0x8b, 0x85, 0x80, 0x78, 0x6d, 0x66, 0x67, 0x75, 0x8c, 0x9c, + 0x9f, 0x94, 0x81, 0x71, 0x6a, 0x6c, 0x74, 0x7b, 0x82, 0x87, 0x8d, 0x92, 0x95, 0x91, 0x87, 0x76, + 0x6a, 0x68, 0x6f, 0x79, 0x81, 0x83, 0x81, 0x7c, 0x7b, 0x80, 0x85, 0x89, 0x8a, 0x88, 0x85, 0x82, + 0x81, 0x80, 0x7a, 0x75, 0x73, 0x74, 0x7a, 0x83, 0x88, 0x87, 0x82, 0x7d, 0x79, 0x78, 0x7a, 0x7d, + 0x7d, 0x7e, 0x83, 0x85, 0x84, 0x80, 0x7c, 0x7c, 0x7b, 0x78, 0x76, 0x7b, 0x84, 0x89, 0x8b, 0x86, + 0x81, 0x7e, 0x81, 0x83, 0x84, 0x85, 0x8b, 0x91, 0x92, 0x8d, 0x81, 0x5e, 0x30, 0x25, 0x3e, 0x65, + 0xa8, 0xe9, 0xf8, 0xda, 0xac, 0x83, 0x5b, 0x3a, 0x28, 0x30, 0x4a, 0x6a, 0x91, 0xbd, 0xdc, 0xd4, + 0x9a, 0x52, 0x24, 0x1f, 0x3c, 0x69, 0x93, 0xb0, 0xc4, 0xc7, 0xbb, 0xa5, 0x85, 0x5f, 0x40, 0x32, + 0x3a, 0x58, 0x8a, 0xb8, 0xc3, 0xa8, 0x88, 0x77, 0x66, 0x52, 0x4f, 0x61, 0x75, 0x86, 0x9a, 0xb3, + 0xbd, 0xb1, 0x98, 0x77, 0x55, 0x46, 0x52, 0x69, 0x79, 0x87, 0x94, 0x9d, 0x95, 0x85, 0x7b, 0x71, + 0x63, 0x5d, 0x68, 0x7e, 0x96, 0xa8, 0xb2, 0xa5, 0x8d, 0x79, 0x6b, 0x5f, 0x58, 0x61, 0x71, 0x7c, + 0x85, 0x90, 0x96, 0x91, 0x85, 0x78, 0x6f, 0x6e, 0x77, 0x86, 0x8e, 0x8c, 0x89, 0x86, 0x80, 0x78, + 0x76, 0x75, 0x72, 0x71, 0x75, 0x7c, 0x84, 0x88, 0x88, 0x83, 0x7d, 0x7d, 0x86, 0x8c, 0x8e, 0x8c, + 0x89, 0x82, 0x78, 0x72, 0x6f, 0x70, 0x72, 0x76, 0x80, 0x86, 0x8a, 0x8c, 0x89, 0x82, 0x7a, 0x73, + 0x67, 0x5a, 0x57, 0x65, 0x85, 0xb0, 0xcf, 0xcf, 0xaf, 0x7a, 0x4f, 0x3f, 0x47, 0x5f, 0x76, 0x81, + 0x85, 0x8f, 0x9e, 0xa9, 0xa2, 0x86, 0x63, 0x4b, 0x4c, 0x66, 0x8a, 0xa5, 0xb0, 0xaa, 0x97, 0x83, + 0x76, 0x71, 0x6c, 0x63, 0x5e, 0x63, 0x75, 0x8f, 0xa3, 0xa5, 0x96, 0x80, 0x6b, 0x63, 0x69, 0x76, + 0x84, 0x8a, 0x8e, 0x91, 0x93, 0x92, 0x8c, 0x81, 0x6e, 0x60, 0x62, 0x6d, 0x79, 0x82, 0x85, 0x83, + 0x80, 0x80, 0x84, 0x87, 0x84, 0x7c, 0x79, 0x7c, 0x84, 0x8d, 0x91, 0x8c, 0x80, 0x74, 0x6f, 0x6f, + 0x72, 0x78, 0x7d, 0x81, 0x83, 0x85, 0x87, 0x86, 0x83, 0x80, 0x7e, 0x80, 0x84, 0x88, 0x8a, 0x88, + 0x82, 0x77, 0x6f, 0x6c, 0x6f, 0x77, 0x82, 0x8a, 0x8c, 0x8d, 0x8d, 0x88, 0x7c, 0x72, 0x6f, 0x73, + 0x7c, 0x87, 0x8e, 0x91, 0x8e, 0x87, 0x80, 0x7a, 0x76, 0x76, 0x76, 0x76, 0x79, 0x81, 0x88, 0x88, + 0x7c, 0x6a, 0x5c, 0x5b, 0x6f, 0x93, 0xb4, 0xc5, 0xb9, 0x97, 0x6d, 0x55, 0x55, 0x64, 0x73, 0x79, + 0x77, 0x78, 0x84, 0x97, 0xa3, 0x9c, 0x83, 0x61, 0x50, 0x58, 0x71, 0x92, 0xa5, 0xa4, 0x98, 0x8b, + 0x85, 0x83, 0x7b, 0x6f, 0x63, 0x5d, 0x66, 0x7d, 0x96, 0xa4, 0xa2, 0x8e, 0x74, 0x64, 0x65, 0x71, + 0x81, 0x89, 0x8e, 0x8f, 0x90, 0x92, 0x91, 0x8a, 0x7a, 0x6b, 0x66, 0x6b, 0x78, 0x87, 0x92, 0x94, + 0x8b, 0x7d, 0x73, 0x6f, 0x70, 0x73, 0x7a, 0x85, 0x90, 0x95, 0x93, 0x8b, 0x7e, 0x73, 0x6d, 0x6e, + 0x75, 0x80, 0x86, 0x88, 0x85, 0x82, 0x81, 0x80, 0x7d, 0x7a, 0x77, 0x77, 0x78, 0x7e, 0x85, 0x8c, + 0x8e, 0x8b, 0x85, 0x82, 0x83, 0x82, 0x7d, 0x76, 0x73, 0x78, 0x7e, 0x82, 0x82, 0x84, 0x87, 0x86, + 0x82, 0x7b, 0x77, 0x79, 0x7b, 0x79, 0x79, 0x83, 0x92, 0x9b, 0x98, 0x87, 0x65, 0x38, 0x24, 0x38, + 0x66, 0xb3, 0xf1, 0xfe, 0xd9, 0xa3, 0x78, 0x56, 0x37, 0x21, 0x24, 0x41, 0x68, 0x95, 0xc5, 0xe6, + 0xdd, 0xa3, 0x51, 0x1b, 0x17, 0x3b, 0x73, 0xa4, 0xc6, 0xd2, 0xcc, 0xb9, 0x9a, 0x73, 0x4b, 0x30, + 0x2e, 0x41, 0x64, 0x99, 0xc9, 0xcd, 0xa8, 0x7e, 0x67, 0x5c, 0x51, 0x55, 0x71, 0x8d, 0x9d, 0xa9, + 0xb2, 0xab, 0x93, 0x76, 0x5c, 0x49, 0x49, 0x62, 0x82, 0x8f, 0x8f, 0x92, 0x92, 0x88, 0x77, 0x6f, + 0x6f, 0x6d, 0x6c, 0x7a, 0x90, 0x9e, 0xa3, 0xa1, 0x90, 0x75, 0x68, 0x6a, 0x6c, 0x6c, 0x74, 0x82, + 0x8a, 0x8b, 0x8b, 0x8b, 0x87, 0x7d, 0x76, 0x76, 0x7d, 0x86, 0x8f, 0x93, 0x8e, 0x85, 0x80, 0x7d, + 0x78, 0x74, 0x76, 0x78, 0x77, 0x79, 0x7e, 0x82, 0x85, 0x87, 0x89, 0x88, 0x86, 0x83, 0x80, 0x7b, + 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x87, 0x8d, 0x8d, 0x86, 0x7e, 0x74, 0x6c, 0x6c, 0x71, 0x78, 0x81, + 0x89, 0x8c, 0x89, 0x86, 0x85, 0x84, 0x81, 0x7a, 0x78, 0x7a, 0x80, 0x87, 0x8c, 0x8e, 0x88, 0x7e, + 0x75, 0x70, 0x6f, 0x72, 0x71, 0x68, 0x5f, 0x64, 0x7d, 0xa7, 0xcc, 0xd9, 0xc0, 0x8a, 0x51, 0x2d, + 0x2f, 0x53, 0x80, 0x9f, 0xa9, 0xa0, 0x92, 0x88, 0x7e, 0x72, 0x61, 0x52, 0x52, 0x66, 0x8b, 0xae, + 0xbf, 0xb8, 0x9b, 0x77, 0x5f, 0x5a, 0x62, 0x6f, 0x79, 0x81, 0x86, 0x8e, 0x97, 0x98, 0x8e, 0x78, + 0x63, 0x59, 0x60, 0x74, 0x8e, 0x9d, 0xa0, 0x99, 0x8c, 0x81, 0x77, 0x6f, 0x69, 0x65, 0x68, 0x73, + 0x84, 0x92, 0x97, 0x92, 0x83, 0x71, 0x68, 0x68, 0x70, 0x7c, 0x88, 0x8f, 0x91, 0x8e, 0x87, 0x7d, + 0x74, 0x6c, 0x6a, 0x73, 0x83, 0x92, 0x9a, 0x98, 0x8b, 0x79, 0x6b, 0x65, 0x67, 0x6f, 0x7b, 0x87, + 0x8f, 0x92, 0x92, 0x8f, 0x86, 0x79, 0x6c, 0x65, 0x67, 0x72, 0x83, 0x90, 0x97, 0x96, 0x8e, 0x7e, + 0x6e, 0x67, 0x66, 0x6a, 0x73, 0x7e, 0x8c, 0x99, 0xa1, 0x9f, 0x94, 0x82, 0x6e, 0x5f, 0x5a, 0x63, + 0x78, 0x92, 0x9e, 0x9b, 0x8f, 0x82, 0x75, 0x6b, 0x68, 0x6a, 0x72, 0x82, 0x92, 0x9b, 0x97, 0x81, + 0x5c, 0x3d, 0x44, 0x76, 0xbf, 0xef, 0xe6, 0xa9, 0x61, 0x38, 0x3d, 0x5c, 0x74, 0x72, 0x64, 0x65, + 0x82, 0xaf, 0xcb, 0xbb, 0x87, 0x50, 0x37, 0x48, 0x74, 0x9d, 0xb2, 0xb0, 0xa0, 0x8c, 0x7c, 0x78, + 0x77, 0x70, 0x5e, 0x4e, 0x53, 0x71, 0x9a, 0xb0, 0xa9, 0x92, 0x77, 0x66, 0x62, 0x6a, 0x78, 0x80, + 0x81, 0x85, 0x91, 0x9b, 0x9e, 0x94, 0x81, 0x64, 0x4c, 0x50, 0x70, 0x8d, 0x96, 0x99, 0x93, 0x84, + 0x74, 0x72, 0x79, 0x79, 0x78, 0x7b, 0x84, 0x8c, 0x91, 0x94, 0x8c, 0x78, 0x68, 0x68, 0x74, 0x7d, + 0x83, 0x87, 0x83, 0x79, 0x75, 0x7b, 0x82, 0x87, 0x8a, 0x86, 0x7e, 0x78, 0x7b, 0x7e, 0x81, 0x83, + 0x84, 0x84, 0x81, 0x7b, 0x76, 0x74, 0x76, 0x7a, 0x83, 0x8c, 0x91, 0x8f, 0x85, 0x76, 0x68, 0x65, + 0x6c, 0x76, 0x81, 0x8b, 0x92, 0x95, 0x93, 0x8e, 0x85, 0x79, 0x6e, 0x66, 0x65, 0x6e, 0x7e, 0x90, + 0x98, 0x95, 0x8b, 0x7c, 0x70, 0x6c, 0x6d, 0x74, 0x7b, 0x82, 0x88, 0x8a, 0x88, 0x85, 0x82, 0x7c, + 0x78, 0x76, 0x78, 0x7a, 0x7d, 0x81, 0x86, 0x89, 0x8a, 0x86, 0x80, 0x77, 0x6f, 0x6e, 0x73, 0x7e, + 0x8c, 0x94, 0x93, 0x87, 0x75, 0x65, 0x5b, 0x5c, 0x6b, 0x86, 0xa0, 0xad, 0xaa, 0x98, 0x7c, 0x62, + 0x57, 0x59, 0x63, 0x72, 0x81, 0x8d, 0x95, 0x97, 0x93, 0x88, 0x78, 0x6a, 0x64, 0x69, 0x75, 0x87, + 0x95, 0x9b, 0x98, 0x90, 0x85, 0x78, 0x6f, 0x6c, 0x6c, 0x71, 0x7a, 0x85, 0x8d, 0x91, 0x8b, 0x81, + 0x75, 0x6d, 0x6d, 0x74, 0x7d, 0x87, 0x8d, 0x8d, 0x8a, 0x85, 0x7d, 0x77, 0x74, 0x73, 0x74, 0x78, + 0x7e, 0x85, 0x89, 0x89, 0x86, 0x81, 0x7a, 0x76, 0x76, 0x77, 0x7c, 0x83, 0x88, 0x89, 0x88, 0x84, + 0x7d, 0x7a, 0x78, 0x77, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x83, 0x7e, 0x79, 0x74, 0x72, 0x76, 0x80, + 0x8a, 0x92, 0x95, 0x93, 0x8b, 0x81, 0x79, 0x73, 0x6f, 0x6e, 0x70, 0x76, 0x7d, 0x88, 0x8f, 0x8f, + 0x8a, 0x82, 0x7b, 0x79, 0x79, 0x7d, 0x83, 0x85, 0x86, 0x88, 0x83, 0x7a, 0x78, 0x7e, 0x81, 0x80, + 0x82, 0x86, 0x86, 0x83, 0x7d, 0x76, 0x6f, 0x6d, 0x74, 0x81, 0x8e, 0x99, 0x9e, 0x99, 0x86, 0x73, + 0x69, 0x66, 0x6a, 0x75, 0x88, 0x99, 0x9f, 0x95, 0x72, 0x3e, 0x20, 0x3f, 0x90, 0xdb, 0xf9, 0xe4, + 0xad, 0x78, 0x57, 0x48, 0x3d, 0x3e, 0x50, 0x71, 0x8f, 0x9f, 0xaf, 0xb5, 0xa4, 0x76, 0x47, 0x3c, + 0x55, 0x80, 0xa5, 0xb3, 0xad, 0xa0, 0x90, 0x7a, 0x6a, 0x64, 0x61, 0x5d, 0x61, 0x76, 0x92, 0xa4, + 0xa8, 0x9e, 0x82, 0x5d, 0x4e, 0x5f, 0x79, 0x88, 0x92, 0xa4, 0xaa, 0x9a, 0x87, 0x7d, 0x74, 0x62, + 0x57, 0x62, 0x76, 0x87, 0x97, 0xa0, 0x98, 0x81, 0x71, 0x6c, 0x67, 0x63, 0x6b, 0x83, 0x94, 0x9b, + 0xa0, 0xa2, 0x95, 0x79, 0x64, 0x5c, 0x5e, 0x66, 0x77, 0x88, 0x8e, 0x8d, 0x8e, 0x8c, 0x81, 0x73, + 0x71, 0x73, 0x72, 0x76, 0x85, 0x93, 0x96, 0x91, 0x89, 0x7e, 0x74, 0x72, 0x74, 0x75, 0x75, 0x79, + 0x7c, 0x7e, 0x80, 0x82, 0x86, 0x85, 0x82, 0x7e, 0x7b, 0x78, 0x79, 0x7c, 0x81, 0x85, 0x85, 0x82, + 0x7d, 0x76, 0x72, 0x75, 0x7a, 0x82, 0x89, 0x8b, 0x87, 0x81, 0x7a, 0x76, 0x76, 0x79, 0x7c, 0x7d, + 0x7d, 0x7d, 0x7e, 0x81, 0x83, 0x85, 0x85, 0x85, 0x84, 0x81, 0x7d, 0x79, 0x77, 0x75, 0x74, 0x77, + 0x7c, 0x82, 0x87, 0x88, 0x84, 0x7d, 0x77, 0x73, 0x73, 0x7a, 0x84, 0x8b, 0x90, 0x8f, 0x8b, 0x85, + 0x7d, 0x79, 0x76, 0x74, 0x74, 0x78, 0x7d, 0x84, 0x88, 0x8b, 0x89, 0x84, 0x7e, 0x7b, 0x7a, 0x77, + 0x6e, 0x62, 0x5a, 0x62, 0x7a, 0xa2, 0xc5, 0xcb, 0xae, 0x77, 0x45, 0x31, 0x42, 0x6a, 0x8f, 0x9a, + 0x94, 0x87, 0x84, 0x8c, 0x93, 0x88, 0x6a, 0x50, 0x4f, 0x6a, 0x97, 0xb9, 0xbf, 0xa8, 0x85, 0x65, + 0x57, 0x5c, 0x69, 0x77, 0x80, 0x82, 0x86, 0x92, 0x9e, 0x9e, 0x8b, 0x6d, 0x58, 0x56, 0x67, 0x83, + 0x9a, 0xa6, 0xa3, 0x91, 0x81, 0x77, 0x71, 0x6b, 0x68, 0x6c, 0x76, 0x82, 0x8e, 0x97, 0x97, 0x86, + 0x71, 0x68, 0x6b, 0x73, 0x7d, 0x88, 0x8d, 0x88, 0x84, 0x84, 0x85, 0x81, 0x7a, 0x75, 0x72, 0x74, + 0x7a, 0x84, 0x8b, 0x89, 0x81, 0x7b, 0x79, 0x78, 0x79, 0x81, 0x87, 0x88, 0x87, 0x87, 0x86, 0x81, + 0x7b, 0x78, 0x77, 0x7a, 0x81, 0x87, 0x8a, 0x85, 0x7c, 0x77, 0x74, 0x75, 0x7b, 0x84, 0x88, 0x86, + 0x83, 0x7e, 0x7b, 0x79, 0x77, 0x78, 0x7d, 0x87, 0x8f, 0x91, 0x89, 0x7b, 0x71, 0x6a, 0x69, 0x6f, + 0x7d, 0x8e, 0x96, 0x95, 0x8f, 0x87, 0x7c, 0x72, 0x6d, 0x6c, 0x71, 0x7d, 0x88, 0x8b, 0x88, 0x85, + 0x82, 0x7b, 0x74, 0x73, 0x7c, 0x88, 0x8e, 0x8e, 0x8a, 0x84, 0x7a, 0x74, 0x73, 0x78, 0x83, 0x8c, + 0x8e, 0x7e, 0x60, 0x45, 0x45, 0x6b, 0xac, 0xe2, 0xec, 0xc1, 0x77, 0x3e, 0x34, 0x52, 0x72, 0x7d, + 0x75, 0x70, 0x7e, 0x9d, 0xb2, 0xa9, 0x85, 0x59, 0x44, 0x49, 0x67, 0x91, 0xb2, 0xbc, 0xad, 0x8e, + 0x71, 0x67, 0x69, 0x6c, 0x68, 0x60, 0x67, 0x81, 0x9f, 0xae, 0xa5, 0x8d, 0x6e, 0x57, 0x51, 0x66, + 0x89, 0x9d, 0x9c, 0x91, 0x8a, 0x86, 0x81, 0x81, 0x80, 0x72, 0x63, 0x63, 0x76, 0x88, 0x8c, 0x8e, + 0x8b, 0x7b, 0x6c, 0x6f, 0x7e, 0x89, 0x8a, 0x88, 0x85, 0x80, 0x7d, 0x84, 0x8a, 0x86, 0x7b, 0x76, + 0x7a, 0x7c, 0x7e, 0x87, 0x8b, 0x83, 0x78, 0x78, 0x7d, 0x82, 0x85, 0x87, 0x84, 0x7b, 0x76, 0x78, + 0x7d, 0x7e, 0x80, 0x83, 0x86, 0x86, 0x88, 0x8b, 0x87, 0x79, 0x6b, 0x66, 0x66, 0x6b, 0x76, 0x84, + 0x8f, 0x93, 0x94, 0x93, 0x8d, 0x81, 0x74, 0x6a, 0x63, 0x63, 0x6d, 0x7c, 0x8c, 0x97, 0x9b, 0x96, + 0x87, 0x75, 0x6b, 0x69, 0x6e, 0x77, 0x81, 0x86, 0x86, 0x87, 0x89, 0x8a, 0x88, 0x83, 0x7c, 0x76, + 0x73, 0x75, 0x7b, 0x82, 0x85, 0x84, 0x81, 0x80, 0x80, 0x81, 0x84, 0x84, 0x82, 0x80, 0x7e, 0x7c, + 0x79, 0x77, 0x75, 0x77, 0x7e, 0x87, 0x90, 0x94, 0x90, 0x89, 0x7d, 0x73, 0x6b, 0x68, 0x6a, 0x71, + 0x79, 0x86, 0x90, 0x97, 0x96, 0x8f, 0x82, 0x74, 0x6d, 0x6f, 0x77, 0x82, 0x8b, 0x8f, 0x8c, 0x84, + 0x7b, 0x76, 0x76, 0x76, 0x77, 0x79, 0x7c, 0x81, 0x87, 0x8a, 0x8a, 0x87, 0x81, 0x75, 0x63, 0x53, + 0x51, 0x68, 0x99, 0xcc, 0xe8, 0xd5, 0x98, 0x51, 0x29, 0x2b, 0x4e, 0x7b, 0x93, 0x92, 0x86, 0x84, + 0x90, 0x98, 0x8d, 0x6f, 0x54, 0x4d, 0x64, 0x90, 0xb5, 0xc4, 0xb0, 0x8a, 0x66, 0x4e, 0x50, 0x62, + 0x79, 0x89, 0x8a, 0x89, 0x8e, 0x93, 0x91, 0x82, 0x6b, 0x5a, 0x59, 0x69, 0x86, 0xa3, 0xb2, 0xad, + 0x94, 0x77, 0x67, 0x61, 0x62, 0x69, 0x75, 0x80, 0x85, 0x8c, 0x96, 0x98, 0x89, 0x75, 0x6b, 0x69, + 0x6d, 0x7b, 0x8e, 0x96, 0x91, 0x87, 0x7e, 0x7a, 0x79, 0x7a, 0x7c, 0x7c, 0x7b, 0x7d, 0x84, 0x88, + 0x84, 0x7c, 0x77, 0x75, 0x77, 0x7e, 0x8a, 0x90, 0x8d, 0x86, 0x7d, 0x78, 0x75, 0x76, 0x79, 0x7c, + 0x7e, 0x80, 0x83, 0x86, 0x84, 0x7d, 0x77, 0x72, 0x70, 0x74, 0x7c, 0x84, 0x87, 0x89, 0x8a, 0x8a, + 0x89, 0x87, 0x82, 0x79, 0x70, 0x6a, 0x6b, 0x71, 0x79, 0x80, 0x86, 0x87, 0x85, 0x84, 0x83, 0x81, + 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x78, 0x73, 0x73, 0x77, 0x7e, 0x85, 0x8c, 0x8f, 0x8d, + 0x86, 0x7c, 0x76, 0x77, 0x7b, 0x83, 0x88, 0x87, 0x82, 0x7b, 0x77, 0x76, 0x79, 0x7e, 0x82, 0x82, + 0x81, 0x82, 0x86, 0x88, 0x86, 0x80, 0x78, 0x74, 0x74, 0x77, 0x7d, 0x85, 0x88, 0x86, 0x80, 0x78, + 0x75, 0x78, 0x7d, 0x83, 0x88, 0x8d, 0x91, 0x94, 0x91, 0x87, 0x73, 0x58, 0x40, 0x3e, 0x5c, 0x94, + 0xcf, 0xe9, 0xd4, 0x99, 0x54, 0x30, 0x34, 0x54, 0x78, 0x90, 0x9a, 0x9a, 0x9d, 0x9e, 0x93, 0x74, + 0x4f, 0x38, 0x3c, 0x5f, 0x92, 0xbe, 0xcc, 0xbc, 0x98, 0x6e, 0x53, 0x4c, 0x58, 0x6c, 0x7b, 0x87, + 0x90, 0x9a, 0x9e, 0x98, 0x83, 0x68, 0x57, 0x55, 0x62, 0x7e, 0x9b, 0xab, 0xa5, 0x90, 0x7c, 0x6f, + 0x6b, 0x6c, 0x73, 0x7b, 0x7d, 0x7e, 0x85, 0x8c, 0x8a, 0x82, 0x79, 0x72, 0x6d, 0x6f, 0x7d, 0x8d, + 0x92, 0x8d, 0x86, 0x7d, 0x77, 0x76, 0x78, 0x7d, 0x7e, 0x7d, 0x80, 0x85, 0x86, 0x82, 0x7d, 0x78, + 0x72, 0x70, 0x78, 0x85, 0x8e, 0x90, 0x8c, 0x84, 0x7c, 0x78, 0x77, 0x7a, 0x7a, 0x79, 0x7b, 0x82, + 0x86, 0x88, 0x88, 0x83, 0x79, 0x72, 0x73, 0x7a, 0x82, 0x87, 0x88, 0x86, 0x82, 0x7c, 0x79, 0x7a, + 0x7a, 0x7c, 0x81, 0x85, 0x87, 0x87, 0x83, 0x7c, 0x78, 0x76, 0x77, 0x7c, 0x82, 0x83, 0x83, 0x83, + 0x84, 0x85, 0x87, 0x89, 0x88, 0x86, 0x82, 0x7b, 0x76, 0x71, 0x6f, 0x73, 0x7b, 0x84, 0x8c, 0x91, + 0x8e, 0x88, 0x82, 0x7c, 0x79, 0x76, 0x71, 0x6d, 0x6a, 0x6f, 0x7b, 0x8b, 0x9a, 0xa0, 0x9a, 0x8c, + 0x77, 0x67, 0x5f, 0x61, 0x6c, 0x7b, 0x8c, 0x99, 0x9d, 0x98, 0x8b, 0x79, 0x6c, 0x66, 0x69, 0x76, + 0x88, 0x95, 0x97, 0x90, 0x84, 0x75, 0x6b, 0x6a, 0x6e, 0x76, 0x81, 0x89, 0x8d, 0x8c, 0x8c, 0x88, + 0x81, 0x7a, 0x78, 0x7a, 0x7e, 0x82, 0x84, 0x80, 0x78, 0x74, 0x76, 0x7c, 0x86, 0x8d, 0x8f, 0x85, + 0x6e, 0x51, 0x44, 0x54, 0x85, 0xbf, 0xdf, 0xda, 0xab, 0x6a, 0x3d, 0x37, 0x4e, 0x69, 0x7c, 0x86, + 0x8a, 0x96, 0xa3, 0xa7, 0x95, 0x72, 0x53, 0x4a, 0x5b, 0x7e, 0xa5, 0xbd, 0xbd, 0xa2, 0x7c, 0x60, + 0x59, 0x64, 0x74, 0x7e, 0x80, 0x7e, 0x84, 0x8a, 0x8a, 0x84, 0x79, 0x70, 0x6d, 0x73, 0x87, 0x9c, + 0xa2, 0x97, 0x83, 0x70, 0x65, 0x65, 0x6c, 0x7b, 0x8a, 0x8e, 0x8a, 0x88, 0x85, 0x7b, 0x73, 0x70, + 0x71, 0x73, 0x79, 0x89, 0x96, 0x97, 0x8d, 0x81, 0x75, 0x71, 0x70, 0x76, 0x81, 0x84, 0x83, 0x83, + 0x86, 0x85, 0x7d, 0x78, 0x76, 0x74, 0x78, 0x81, 0x8c, 0x93, 0x8e, 0x83, 0x7a, 0x75, 0x72, 0x76, + 0x81, 0x87, 0x86, 0x85, 0x85, 0x81, 0x7a, 0x74, 0x70, 0x70, 0x74, 0x7c, 0x89, 0x90, 0x8f, 0x8a, + 0x82, 0x79, 0x75, 0x74, 0x78, 0x7e, 0x81, 0x82, 0x84, 0x83, 0x81, 0x7e, 0x7c, 0x7b, 0x7b, 0x7a, + 0x79, 0x7b, 0x7b, 0x7e, 0x85, 0x89, 0x89, 0x87, 0x81, 0x7d, 0x7e, 0x7c, 0x7d, 0x80, 0x7d, 0x79, + 0x78, 0x7c, 0x80, 0x82, 0x84, 0x86, 0x84, 0x81, 0x81, 0x81, 0x81, 0x80, 0x79, 0x70, 0x65, 0x62, + 0x6a, 0x7b, 0x91, 0xa4, 0xaa, 0xa0, 0x8d, 0x71, 0x5e, 0x59, 0x61, 0x74, 0x89, 0x96, 0x9c, 0x99, + 0x8d, 0x7b, 0x6b, 0x60, 0x5f, 0x69, 0x7c, 0x95, 0xa6, 0xa6, 0x98, 0x81, 0x6d, 0x63, 0x62, 0x6c, + 0x7b, 0x86, 0x8a, 0x8c, 0x8b, 0x84, 0x7b, 0x74, 0x71, 0x75, 0x7e, 0x88, 0x8d, 0x8b, 0x82, 0x75, + 0x6b, 0x6c, 0x77, 0x88, 0x94, 0x94, 0x84, 0x64, 0x45, 0x3b, 0x59, 0x90, 0xc3, 0xdd, 0xca, 0x92, + 0x5a, 0x47, 0x53, 0x6f, 0x82, 0x81, 0x76, 0x71, 0x7c, 0x8e, 0x95, 0x8c, 0x79, 0x68, 0x69, 0x7b, + 0x95, 0xa9, 0xab, 0x97, 0x74, 0x57, 0x53, 0x64, 0x7e, 0x95, 0x9b, 0x93, 0x89, 0x82, 0x78, 0x6b, + 0x61, 0x5f, 0x65, 0x73, 0x8c, 0xa7, 0xb6, 0xad, 0x91, 0x72, 0x60, 0x5e, 0x65, 0x73, 0x85, 0x8b, + 0x8b, 0x89, 0x88, 0x89, 0x83, 0x78, 0x71, 0x6e, 0x6d, 0x77, 0x87, 0x93, 0x94, 0x8b, 0x82, 0x7d, + 0x79, 0x7a, 0x80, 0x85, 0x86, 0x82, 0x7d, 0x7b, 0x79, 0x77, 0x7a, 0x80, 0x84, 0x86, 0x87, 0x87, + 0x83, 0x7b, 0x76, 0x76, 0x78, 0x7b, 0x81, 0x87, 0x8a, 0x8a, 0x87, 0x83, 0x7b, 0x74, 0x71, 0x73, + 0x78, 0x7e, 0x84, 0x87, 0x89, 0x86, 0x81, 0x7d, 0x7b, 0x79, 0x7a, 0x7e, 0x84, 0x86, 0x86, 0x85, + 0x83, 0x7d, 0x7a, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x81, 0x7c, 0x79, 0x79, 0x7a, 0x78, 0x78, 0x81, + 0x8b, 0x92, 0x93, 0x8d, 0x82, 0x74, 0x68, 0x63, 0x68, 0x75, 0x84, 0x90, 0x98, 0x96, 0x8b, 0x7b, + 0x70, 0x67, 0x63, 0x6c, 0x7b, 0x8a, 0x96, 0x9f, 0x9e, 0x93, 0x7e, 0x66, 0x4e, 0x41, 0x48, 0x60, + 0x88, 0xae, 0xc4, 0xc4, 0xb0, 0x90, 0x6b, 0x54, 0x4e, 0x57, 0x68, 0x7d, 0x95, 0xa3, 0xa4, 0x98, + 0x83, 0x68, 0x57, 0x58, 0x66, 0x7a, 0x8f, 0x9b, 0x99, 0x8d, 0x7d, 0x75, 0x75, 0x7a, 0x83, 0x86, + 0x84, 0x7e, 0x76, 0x6f, 0x6b, 0x6b, 0x70, 0x7d, 0x8c, 0x97, 0x9e, 0x9a, 0x8b, 0x76, 0x63, 0x56, + 0x59, 0x68, 0x7c, 0x92, 0xa1, 0xa7, 0xa1, 0x94, 0x7d, 0x60, 0x44, 0x35, 0x41, 0x6d, 0xa8, 0xd7, + 0xe2, 0xbf, 0x81, 0x45, 0x29, 0x3a, 0x67, 0x93, 0xa7, 0xa6, 0x99, 0x8c, 0x82, 0x78, 0x69, 0x58, + 0x54, 0x64, 0x84, 0xa7, 0xbe, 0xb9, 0x9c, 0x71, 0x4d, 0x43, 0x57, 0x78, 0x97, 0xa2, 0x9b, 0x8f, + 0x84, 0x77, 0x6c, 0x64, 0x64, 0x6a, 0x78, 0x8c, 0x9d, 0xa2, 0x96, 0x7d, 0x65, 0x5e, 0x66, 0x77, + 0x8b, 0x97, 0x94, 0x89, 0x7a, 0x71, 0x6e, 0x70, 0x73, 0x7b, 0x85, 0x8a, 0x8f, 0x91, 0x8d, 0x80, + 0x71, 0x66, 0x67, 0x72, 0x85, 0x95, 0x9d, 0x9a, 0x8e, 0x7d, 0x70, 0x69, 0x65, 0x68, 0x71, 0x7c, + 0x87, 0x90, 0x96, 0x97, 0x8f, 0x82, 0x73, 0x69, 0x66, 0x6b, 0x76, 0x81, 0x87, 0x8a, 0x8c, 0x8a, + 0x88, 0x84, 0x7e, 0x77, 0x72, 0x6e, 0x70, 0x75, 0x7c, 0x84, 0x89, 0x8b, 0x8b, 0x88, 0x82, 0x7b, + 0x74, 0x6f, 0x70, 0x78, 0x83, 0x8c, 0x91, 0x90, 0x88, 0x7b, 0x71, 0x6c, 0x6d, 0x73, 0x7d, 0x89, + 0x8f, 0x91, 0x8d, 0x87, 0x80, 0x78, 0x6f, 0x66, 0x68, 0x7a, 0x91, 0xa1, 0xa9, 0xa3, 0x8b, 0x6a, + 0x56, 0x53, 0x60, 0x78, 0x91, 0xa0, 0x9f, 0x95, 0x86, 0x79, 0x70, 0x68, 0x6a, 0x73, 0x83, 0x93, + 0x9b, 0x9a, 0x8f, 0x7a, 0x6a, 0x63, 0x63, 0x69, 0x70, 0x77, 0x82, 0x8c, 0x95, 0x9a, 0x93, 0x80, + 0x6a, 0x5f, 0x63, 0x76, 0x94, 0xae, 0xb6, 0xaa, 0x8f, 0x6f, 0x55, 0x47, 0x47, 0x52, 0x66, 0x7e, + 0x97, 0xab, 0xb3, 0xac, 0x98, 0x7e, 0x69, 0x5e, 0x5d, 0x68, 0x78, 0x86, 0x8f, 0x95, 0x92, 0x8d, + 0x87, 0x7e, 0x76, 0x72, 0x72, 0x72, 0x75, 0x79, 0x7e, 0x84, 0x89, 0x8c, 0x90, 0x95, 0x96, 0x94, + 0x8b, 0x77, 0x5f, 0x45, 0x34, 0x3b, 0x5f, 0x9b, 0xd2, 0xed, 0xdc, 0xab, 0x6e, 0x3e, 0x30, 0x43, + 0x68, 0x89, 0x9b, 0x9e, 0x99, 0x91, 0x87, 0x7a, 0x68, 0x59, 0x58, 0x67, 0x82, 0x98, 0xa3, 0x9e, + 0x8d, 0x78, 0x6e, 0x71, 0x7e, 0x90, 0x97, 0x8f, 0x7d, 0x69, 0x5d, 0x5b, 0x63, 0x74, 0x89, 0x9d, + 0xab, 0xad, 0xa4, 0x90, 0x71, 0x53, 0x42, 0x47, 0x61, 0x8a, 0xb0, 0xc7, 0xc1, 0xa1, 0x7c, 0x5b, + 0x4a, 0x48, 0x57, 0x70, 0x8a, 0x9f, 0xab, 0xab, 0xa0, 0x89, 0x6a, 0x55, 0x53, 0x65, 0x7e, 0x98, + 0xa6, 0xa4, 0x93, 0x7c, 0x6c, 0x66, 0x67, 0x6e, 0x79, 0x84, 0x89, 0x8d, 0x8c, 0x87, 0x7c, 0x71, + 0x6d, 0x71, 0x7b, 0x8b, 0x96, 0x98, 0x93, 0x83, 0x72, 0x68, 0x66, 0x6c, 0x75, 0x80, 0x8a, 0x90, + 0x94, 0x94, 0x8d, 0x81, 0x74, 0x6c, 0x69, 0x6d, 0x76, 0x80, 0x89, 0x8f, 0x93, 0x92, 0x8c, 0x83, + 0x79, 0x71, 0x6d, 0x6e, 0x73, 0x7b, 0x85, 0x8c, 0x91, 0x92, 0x8d, 0x85, 0x79, 0x72, 0x70, 0x73, + 0x79, 0x80, 0x85, 0x87, 0x85, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7c, 0x7a, 0x77, 0x75, 0x6f, 0x66, + 0x6f, 0x8f, 0xaf, 0xbe, 0xb9, 0x9c, 0x72, 0x47, 0x33, 0x3f, 0x5d, 0x83, 0xa7, 0xb9, 0xb9, 0xa9, + 0x8c, 0x70, 0x58, 0x49, 0x4d, 0x65, 0x87, 0xa3, 0xb0, 0xac, 0x94, 0x75, 0x5f, 0x5a, 0x65, 0x7a, + 0x91, 0x99, 0x90, 0x78, 0x64, 0x5d, 0x60, 0x6d, 0x7e, 0x92, 0xa0, 0xa5, 0xa2, 0x96, 0x86, 0x72, + 0x63, 0x61, 0x6a, 0x7a, 0x8a, 0x92, 0x8e, 0x7b, 0x6a, 0x61, 0x62, 0x6d, 0x81, 0x96, 0xa4, 0xa7, + 0x9d, 0x8c, 0x76, 0x66, 0x5d, 0x5b, 0x65, 0x78, 0x8e, 0xa1, 0xa7, 0x9e, 0x8d, 0x7a, 0x6c, 0x66, + 0x68, 0x73, 0x80, 0x86, 0x85, 0x7d, 0x76, 0x73, 0x75, 0x7d, 0x87, 0x8d, 0x8f, 0x8e, 0x89, 0x83, + 0x7b, 0x73, 0x67, 0x59, 0x57, 0x6d, 0x94, 0xb4, 0xbe, 0xac, 0x89, 0x67, 0x58, 0x59, 0x65, 0x77, + 0x8a, 0x99, 0x9d, 0x93, 0x82, 0x70, 0x64, 0x5e, 0x5f, 0x6b, 0x80, 0x98, 0xa9, 0xaa, 0x98, 0x7c, + 0x6a, 0x64, 0x69, 0x74, 0x82, 0x8f, 0x94, 0x8f, 0x82, 0x77, 0x72, 0x71, 0x70, 0x72, 0x7c, 0x8b, + 0x93, 0x93, 0x88, 0x78, 0x6d, 0x66, 0x68, 0x73, 0x86, 0x96, 0x9e, 0x9b, 0x91, 0x7d, 0x6e, 0x68, + 0x69, 0x6c, 0x71, 0x7d, 0x8d, 0x96, 0x95, 0x90, 0x88, 0x7d, 0x73, 0x6f, 0x71, 0x78, 0x82, 0x87, + 0x87, 0x83, 0x7d, 0x7c, 0x80, 0x83, 0x85, 0x85, 0x84, 0x81, 0x7b, 0x76, 0x74, 0x74, 0x76, 0x7b, + 0x84, 0x8b, 0x90, 0x90, 0x8a, 0x81, 0x78, 0x74, 0x73, 0x77, 0x7d, 0x84, 0x89, 0x8c, 0x89, 0x81, + 0x79, 0x75, 0x74, 0x77, 0x7e, 0x84, 0x88, 0x88, 0x84, 0x7e, 0x7b, 0x79, 0x78, 0x7c, 0x81, 0x86, + 0x89, 0x88, 0x85, 0x7e, 0x76, 0x72, 0x73, 0x77, 0x7d, 0x83, 0x87, 0x87, 0x85, 0x82, 0x80, 0x7d, + 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7e, 0x81, 0x83, 0x85, 0x84, 0x81, 0x7b, 0x77, 0x76, + 0x78, 0x7c, 0x81, 0x86, 0x88, 0x82, 0x75, 0x6f, 0x74, 0x80, 0x8b, 0x92, 0x92, 0x8a, 0x7b, 0x72, + 0x72, 0x76, 0x79, 0x7b, 0x7e, 0x7e, 0x7e, 0x83, 0x86, 0x83, 0x7a, 0x74, 0x7a, 0x87, 0x90, 0x92, + 0x8e, 0x81, 0x70, 0x67, 0x6c, 0x77, 0x87, 0x92, 0x93, 0x8a, 0x7a, 0x71, 0x70, 0x73, 0x78, 0x7d, + 0x82, 0x85, 0x89, 0x8c, 0x8c, 0x86, 0x79, 0x6e, 0x6a, 0x6f, 0x7b, 0x8a, 0x94, 0x95, 0x8b, 0x7e, + 0x75, 0x70, 0x6b, 0x68, 0x68, 0x6b, 0x71, 0x7d, 0x8f, 0x9e, 0xa4, 0xa0, 0x93, 0x82, 0x73, 0x6c, + 0x6d, 0x76, 0x80, 0x87, 0x8a, 0x88, 0x82, 0x7b, 0x76, 0x73, 0x72, 0x74, 0x7a, 0x84, 0x8c, 0x8f, + 0x8d, 0x88, 0x81, 0x7a, 0x78, 0x7c, 0x84, 0x8b, 0x8d, 0x8a, 0x82, 0x78, 0x71, 0x70, 0x73, 0x77, + 0x7d, 0x86, 0x8a, 0x8a, 0x88, 0x82, 0x7a, 0x76, 0x78, 0x7d, 0x86, 0x8d, 0x8f, 0x8c, 0x85, 0x7e, + 0x7b, 0x7a, 0x79, 0x79, 0x7c, 0x81, 0x84, 0x83, 0x81, 0x7c, 0x77, 0x77, 0x7a, 0x7d, 0x80, 0x7d, + 0x7a, 0x79, 0x80, 0x8b, 0x91, 0x90, 0x88, 0x7c, 0x75, 0x75, 0x77, 0x79, 0x7c, 0x80, 0x82, 0x82, + 0x7e, 0x7b, 0x77, 0x76, 0x76, 0x78, 0x7c, 0x83, 0x89, 0x8b, 0x87, 0x7e, 0x75, 0x6f, 0x70, 0x78, + 0x85, 0x92, 0x9a, 0x97, 0x8b, 0x7b, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x84, 0x93, 0x9e, 0xa1, 0x9a, + 0x8b, 0x78, 0x69, 0x63, 0x68, 0x73, 0x7e, 0x8a, 0x91, 0x93, 0x91, 0x8d, 0x85, 0x7a, 0x70, 0x6c, + 0x6d, 0x74, 0x7e, 0x88, 0x8d, 0x8f, 0x8b, 0x83, 0x7c, 0x77, 0x74, 0x73, 0x75, 0x79, 0x7b, 0x82, + 0x8d, 0x95, 0x94, 0x8b, 0x7c, 0x6d, 0x62, 0x64, 0x74, 0x89, 0x96, 0x9b, 0x97, 0x88, 0x76, 0x6b, + 0x68, 0x69, 0x6f, 0x7a, 0x86, 0x8f, 0x93, 0x91, 0x8c, 0x83, 0x77, 0x6e, 0x6d, 0x73, 0x7c, 0x87, + 0x8d, 0x8c, 0x85, 0x7a, 0x75, 0x72, 0x72, 0x74, 0x79, 0x7d, 0x82, 0x87, 0x8a, 0x89, 0x84, 0x7c, + 0x77, 0x76, 0x7b, 0x80, 0x84, 0x85, 0x82, 0x7d, 0x7c, 0x81, 0x85, 0x86, 0x84, 0x80, 0x79, 0x75, + 0x77, 0x7b, 0x82, 0x87, 0x89, 0x8a, 0x89, 0x86, 0x84, 0x80, 0x7a, 0x74, 0x70, 0x72, 0x76, 0x79, + 0x7d, 0x82, 0x85, 0x86, 0x84, 0x83, 0x84, 0x82, 0x81, 0x78, 0x68, 0x5d, 0x65, 0x85, 0xa9, 0xc3, + 0xca, 0xb2, 0x84, 0x54, 0x37, 0x35, 0x47, 0x68, 0x8a, 0x9e, 0xa2, 0x9d, 0x92, 0x85, 0x74, 0x6b, + 0x6e, 0x7d, 0x92, 0x9f, 0xa1, 0x95, 0x7d, 0x66, 0x5b, 0x5f, 0x6f, 0x83, 0x94, 0x9c, 0x95, 0x87, + 0x78, 0x6e, 0x68, 0x6c, 0x77, 0x87, 0x92, 0x97, 0x95, 0x89, 0x7a, 0x6f, 0x69, 0x71, 0x80, 0x91, + 0x9d, 0x9e, 0x90, 0x76, 0x60, 0x54, 0x58, 0x6a, 0x86, 0x9d, 0xaa, 0xa7, 0x98, 0x81, 0x68, 0x59, + 0x55, 0x5e, 0x72, 0x8b, 0xa1, 0xad, 0xa9, 0x97, 0x80, 0x68, 0x5a, 0x57, 0x5f, 0x6d, 0x7d, 0x8c, + 0x94, 0x96, 0x92, 0x88, 0x7d, 0x76, 0x73, 0x76, 0x7c, 0x83, 0x86, 0x85, 0x81, 0x7a, 0x78, 0x79, + 0x7b, 0x82, 0x85, 0x84, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x7e, 0x7e, 0x80, 0x82, 0x84, 0x87, 0x86, + 0x82, 0x7e, 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x78, 0x78, 0x7a, 0x81, 0x86, 0x88, 0x8a, 0x88, 0x85, + 0x80, 0x7b, 0x77, 0x74, 0x75, 0x77, 0x7b, 0x80, 0x85, 0x87, 0x88, 0x89, 0x88, 0x86, 0x84, 0x80, + 0x79, 0x75, 0x72, 0x72, 0x77, 0x7e, 0x86, 0x8a, 0x8d, 0x8d, 0x88, 0x81, 0x7b, 0x74, 0x6f, 0x70, + 0x74, 0x7b, 0x81, 0x87, 0x8a, 0x8a, 0x88, 0x85, 0x82, 0x7e, 0x7c, 0x76, 0x72, 0x72, 0x77, 0x83, + 0x8e, 0x92, 0x8d, 0x81, 0x75, 0x71, 0x74, 0x7b, 0x82, 0x86, 0x86, 0x88, 0x89, 0x8a, 0x87, 0x81, + 0x7a, 0x76, 0x77, 0x7b, 0x80, 0x81, 0x81, 0x81, 0x82, 0x83, 0x81, 0x7e, 0x7d, 0x7e, 0x81, 0x83, + 0x82, 0x7e, 0x7a, 0x78, 0x7b, 0x82, 0x88, 0x8a, 0x89, 0x85, 0x80, 0x7d, 0x7c, 0x7a, 0x74, 0x6e, + 0x6a, 0x6e, 0x7c, 0x8d, 0x9b, 0xa2, 0x9e, 0x93, 0x83, 0x70, 0x64, 0x5e, 0x60, 0x6d, 0x7d, 0x8d, + 0x98, 0x9a, 0x94, 0x87, 0x7a, 0x73, 0x70, 0x71, 0x75, 0x7b, 0x81, 0x85, 0x85, 0x84, 0x81, 0x7b, + 0x78, 0x76, 0x79, 0x80, 0x88, 0x8d, 0x8c, 0x86, 0x7d, 0x76, 0x74, 0x76, 0x7c, 0x85, 0x8b, 0x8d, + 0x8b, 0x84, 0x7a, 0x70, 0x6d, 0x72, 0x7c, 0x89, 0x93, 0x96, 0x91, 0x87, 0x7a, 0x6e, 0x69, 0x6c, + 0x77, 0x86, 0x91, 0x95, 0x90, 0x88, 0x7e, 0x76, 0x73, 0x75, 0x78, 0x7d, 0x83, 0x87, 0x89, 0x87, + 0x82, 0x7b, 0x79, 0x78, 0x78, 0x7a, 0x7e, 0x7d, 0x7b, 0x7c, 0x7e, 0x82, 0x88, 0x8d, 0x8e, 0x8a, + 0x83, 0x7a, 0x71, 0x6d, 0x6e, 0x75, 0x81, 0x8d, 0x95, 0x99, 0x95, 0x89, 0x78, 0x6a, 0x65, 0x69, + 0x76, 0x88, 0x95, 0x9b, 0x97, 0x8c, 0x7d, 0x6f, 0x67, 0x67, 0x6d, 0x77, 0x84, 0x8e, 0x93, 0x93, + 0x8e, 0x85, 0x7b, 0x73, 0x6f, 0x6f, 0x73, 0x7a, 0x81, 0x85, 0x87, 0x88, 0x87, 0x86, 0x82, 0x7e, + 0x7c, 0x7a, 0x7a, 0x79, 0x79, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x82, 0x84, + 0x85, 0x83, 0x80, 0x7b, 0x79, 0x7a, 0x7a, 0x7a, 0x7c, 0x80, 0x85, 0x8a, 0x8c, 0x88, 0x7e, 0x75, + 0x6f, 0x6d, 0x71, 0x7a, 0x84, 0x8b, 0x8f, 0x8e, 0x8a, 0x84, 0x7a, 0x71, 0x6b, 0x69, 0x6e, 0x7b, + 0x8a, 0x95, 0x98, 0x94, 0x8c, 0x80, 0x75, 0x6e, 0x6c, 0x6f, 0x76, 0x7e, 0x86, 0x89, 0x8a, 0x89, + 0x86, 0x80, 0x78, 0x71, 0x6d, 0x6e, 0x78, 0x89, 0x98, 0xa1, 0x9d, 0x8f, 0x7e, 0x6f, 0x67, 0x66, + 0x6b, 0x74, 0x7a, 0x7d, 0x7e, 0x7e, 0x81, 0x86, 0x8c, 0x91, 0x92, 0x90, 0x8c, 0x83, 0x77, 0x69, + 0x5f, 0x5f, 0x69, 0x7d, 0x92, 0xa0, 0xa0, 0x95, 0x83, 0x6f, 0x62, 0x5c, 0x5f, 0x69, 0x78, 0x8b, + 0x9a, 0xa2, 0x9e, 0x90, 0x7b, 0x69, 0x60, 0x64, 0x70, 0x80, 0x8c, 0x90, 0x8d, 0x87, 0x80, 0x79, + 0x76, 0x78, 0x80, 0x89, 0x8f, 0x8f, 0x86, 0x79, 0x6e, 0x6a, 0x6e, 0x77, 0x82, 0x89, 0x8d, 0x8c, + 0x87, 0x7e, 0x75, 0x71, 0x73, 0x7b, 0x86, 0x8b, 0x89, 0x84, 0x80, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, + 0x7c, 0x7e, 0x7e, 0x7a, 0x78, 0x7a, 0x7e, 0x84, 0x88, 0x89, 0x88, 0x81, 0x74, 0x69, 0x68, 0x70, + 0x80, 0x8e, 0x95, 0x93, 0x8c, 0x83, 0x79, 0x70, 0x6c, 0x6c, 0x73, 0x7c, 0x88, 0x94, 0x99, 0x96, + 0x89, 0x79, 0x6b, 0x65, 0x66, 0x6e, 0x7a, 0x86, 0x90, 0x97, 0x96, 0x8f, 0x83, 0x75, 0x6f, 0x6c, + 0x6f, 0x77, 0x82, 0x8d, 0x94, 0x93, 0x8b, 0x7b, 0x6d, 0x67, 0x6a, 0x74, 0x82, 0x90, 0x97, 0x95, + 0x8c, 0x7e, 0x73, 0x6d, 0x6e, 0x73, 0x7d, 0x88, 0x8f, 0x8f, 0x88, 0x7d, 0x78, 0x79, 0x7b, 0x7b, + 0x79, 0x78, 0x7a, 0x7e, 0x85, 0x89, 0x8c, 0x8c, 0x89, 0x83, 0x79, 0x73, 0x71, 0x70, 0x72, 0x78, + 0x81, 0x8a, 0x8e, 0x8e, 0x88, 0x80, 0x78, 0x74, 0x76, 0x7c, 0x82, 0x84, 0x82, 0x7c, 0x7b, 0x80, + 0x86, 0x87, 0x85, 0x81, 0x78, 0x71, 0x6d, 0x70, 0x7a, 0x88, 0x92, 0x97, 0x94, 0x8a, 0x7c, 0x6d, + 0x61, 0x5e, 0x66, 0x77, 0x8a, 0x98, 0x9d, 0x99, 0x8d, 0x7d, 0x6e, 0x64, 0x64, 0x6c, 0x78, 0x84, + 0x8d, 0x92, 0x91, 0x8b, 0x83, 0x7a, 0x74, 0x73, 0x76, 0x7a, 0x81, 0x89, 0x8d, 0x88, 0x7d, 0x77, + 0x77, 0x7d, 0x85, 0x89, 0x86, 0x80, 0x7a, 0x77, 0x79, 0x7c, 0x81, 0x84, 0x83, 0x81, 0x7c, 0x7a, + 0x76, 0x72, 0x6f, 0x73, 0x7c, 0x8a, 0x93, 0x95, 0x8e, 0x81, 0x72, 0x6a, 0x6b, 0x71, 0x7c, 0x87, + 0x8f, 0x91, 0x8c, 0x84, 0x7a, 0x73, 0x70, 0x74, 0x7b, 0x83, 0x89, 0x8d, 0x8d, 0x88, 0x81, 0x77, + 0x71, 0x71, 0x74, 0x7b, 0x83, 0x87, 0x87, 0x82, 0x7d, 0x7c, 0x7d, 0x80, 0x81, 0x80, 0x81, 0x83, + 0x85, 0x84, 0x80, 0x7a, 0x76, 0x75, 0x78, 0x7c, 0x82, 0x88, 0x8b, 0x8b, 0x8a, 0x85, 0x81, 0x7e, + 0x7c, 0x7b, 0x7a, 0x79, 0x77, 0x77, 0x7c, 0x82, 0x85, 0x88, 0x89, 0x86, 0x83, 0x7e, 0x78, 0x75, + 0x77, 0x7c, 0x85, 0x8c, 0x8e, 0x89, 0x7e, 0x77, 0x73, 0x74, 0x7a, 0x83, 0x88, 0x88, 0x89, 0x88, + 0x87, 0x85, 0x80, 0x79, 0x72, 0x6d, 0x70, 0x7a, 0x85, 0x90, 0x95, 0x94, 0x8d, 0x82, 0x76, 0x69, + 0x5f, 0x5f, 0x68, 0x79, 0x8e, 0x9f, 0xa6, 0xa1, 0x92, 0x7d, 0x6a, 0x5e, 0x5b, 0x60, 0x6d, 0x7c, + 0x8b, 0x95, 0x97, 0x94, 0x8d, 0x84, 0x79, 0x71, 0x6e, 0x6e, 0x71, 0x76, 0x7d, 0x85, 0x8b, 0x8d, + 0x8f, 0x8c, 0x86, 0x7e, 0x77, 0x71, 0x70, 0x73, 0x7a, 0x84, 0x8c, 0x90, 0x91, 0x90, 0x88, 0x7c, + 0x70, 0x67, 0x66, 0x6f, 0x7e, 0x8f, 0x9a, 0x9c, 0x93, 0x84, 0x73, 0x66, 0x62, 0x68, 0x74, 0x87, + 0x96, 0x9c, 0x9b, 0x92, 0x85, 0x78, 0x6f, 0x6c, 0x6e, 0x74, 0x7c, 0x85, 0x8b, 0x8d, 0x89, 0x82, + 0x7c, 0x7a, 0x7c, 0x7d, 0x7e, 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x81, 0x84, 0x85, 0x85, 0x83, 0x80, + 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, 0x7d, 0x80, 0x83, 0x84, 0x83, 0x80, 0x7d, 0x7e, + 0x83, 0x86, 0x86, 0x83, 0x80, 0x7a, 0x74, 0x6e, 0x6b, 0x6f, 0x7c, 0x8c, 0x9a, 0xa0, 0x9b, 0x8c, + 0x79, 0x6b, 0x67, 0x69, 0x71, 0x7b, 0x82, 0x87, 0x8a, 0x8b, 0x88, 0x80, 0x77, 0x74, 0x76, 0x7a, + 0x81, 0x84, 0x83, 0x7e, 0x79, 0x78, 0x7a, 0x7d, 0x83, 0x87, 0x8a, 0x88, 0x82, 0x7a, 0x75, 0x73, + 0x76, 0x7a, 0x7e, 0x82, 0x84, 0x85, 0x83, 0x81, 0x80, 0x7d, 0x7b, 0x78, 0x77, 0x77, 0x7a, 0x7c, + 0x80, 0x81, 0x83, 0x86, 0x87, 0x87, 0x85, 0x81, 0x7c, 0x7a, 0x79, 0x7b, 0x7c, 0x7e, 0x81, 0x83, + 0x85, 0x87, 0x84, 0x7e, 0x7a, 0x7a, 0x7d, 0x80, 0x81, 0x7d, 0x78, 0x75, 0x76, 0x7c, 0x86, 0x8b, + 0x8a, 0x85, 0x7e, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x84, 0x88, 0x89, 0x86, 0x81, 0x7b, + 0x78, 0x77, 0x78, 0x7c, 0x80, 0x83, 0x85, 0x85, 0x83, 0x82, 0x7e, 0x7b, 0x7a, 0x7d, 0x82, 0x87, + 0x89, 0x88, 0x86, 0x82, 0x7d, 0x7a, 0x78, 0x78, 0x79, 0x7e, 0x83, 0x86, 0x86, 0x85, 0x84, 0x82, + 0x7d, 0x7a, 0x76, 0x74, 0x76, 0x7a, 0x80, 0x83, 0x83, 0x82, 0x81, 0x80, 0x82, 0x85, 0x85, 0x82, + 0x7d, 0x7a, 0x79, 0x7a, 0x7d, 0x80, 0x82, 0x84, 0x85, 0x83, 0x81, 0x7d, 0x79, 0x77, 0x77, 0x7a, + 0x80, 0x86, 0x89, 0x8a, 0x88, 0x84, 0x7e, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x82, 0x85, 0x87, + 0x87, 0x83, 0x7d, 0x78, 0x75, 0x75, 0x78, 0x7e, 0x86, 0x8d, 0x90, 0x8d, 0x85, 0x7b, 0x73, 0x6f, + 0x70, 0x76, 0x7e, 0x87, 0x8d, 0x8e, 0x8a, 0x82, 0x79, 0x73, 0x70, 0x70, 0x74, 0x7b, 0x84, 0x8b, + 0x8f, 0x8d, 0x86, 0x7c, 0x75, 0x72, 0x73, 0x78, 0x7d, 0x83, 0x87, 0x8a, 0x8b, 0x88, 0x83, 0x7b, + 0x73, 0x70, 0x70, 0x72, 0x77, 0x7e, 0x85, 0x8c, 0x8f, 0x8f, 0x8a, 0x82, 0x79, 0x71, 0x6e, 0x6f, + 0x75, 0x7c, 0x84, 0x89, 0x8b, 0x8b, 0x88, 0x83, 0x7e, 0x7a, 0x7a, 0x7b, 0x7c, 0x7c, 0x7a, 0x78, + 0x78, 0x78, 0x7b, 0x80, 0x84, 0x87, 0x8a, 0x8a, 0x89, 0x84, 0x7c, 0x75, 0x70, 0x71, 0x76, 0x7c, + 0x84, 0x88, 0x88, 0x86, 0x83, 0x80, 0x7c, 0x7b, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x82, 0x85, 0x86, + 0x85, 0x81, 0x7c, 0x79, 0x77, 0x77, 0x7a, 0x7e, 0x83, 0x88, 0x8a, 0x89, 0x85, 0x7e, 0x79, 0x77, + 0x77, 0x7a, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x80, 0x80, 0x84, 0x88, 0x89, 0x88, 0x83, 0x7a, 0x75, + 0x73, 0x73, 0x77, 0x7c, 0x82, 0x87, 0x8a, 0x89, 0x85, 0x7e, 0x79, 0x75, 0x71, 0x72, 0x77, 0x7d, + 0x86, 0x8c, 0x90, 0x8e, 0x89, 0x82, 0x79, 0x74, 0x73, 0x75, 0x7a, 0x81, 0x87, 0x8b, 0x8a, 0x85, + 0x80, 0x79, 0x75, 0x73, 0x76, 0x7c, 0x82, 0x88, 0x8d, 0x8f, 0x8d, 0x86, 0x7c, 0x73, 0x6d, 0x6d, + 0x72, 0x7a, 0x83, 0x8a, 0x90, 0x92, 0x8f, 0x87, 0x7d, 0x75, 0x70, 0x6f, 0x72, 0x77, 0x7d, 0x84, + 0x88, 0x89, 0x88, 0x86, 0x84, 0x81, 0x7d, 0x7a, 0x78, 0x77, 0x78, 0x7b, 0x7e, 0x82, 0x84, 0x84, + 0x82, 0x81, 0x81, 0x82, 0x83, 0x83, 0x80, 0x7b, 0x77, 0x77, 0x78, 0x7b, 0x80, 0x80, 0x7d, 0x7b, + 0x7b, 0x80, 0x86, 0x8c, 0x8d, 0x8b, 0x83, 0x79, 0x72, 0x6e, 0x6f, 0x73, 0x79, 0x7e, 0x86, 0x8d, + 0x92, 0x94, 0x8f, 0x87, 0x7d, 0x74, 0x6e, 0x6c, 0x6d, 0x72, 0x7a, 0x83, 0x8a, 0x90, 0x91, 0x8d, + 0x86, 0x7d, 0x76, 0x72, 0x72, 0x74, 0x78, 0x7b, 0x7d, 0x82, 0x87, 0x8b, 0x8b, 0x86, 0x7e, 0x78, + 0x75, 0x76, 0x79, 0x7b, 0x7e, 0x81, 0x83, 0x83, 0x83, 0x80, 0x7c, 0x7b, 0x7a, 0x7a, 0x7e, 0x83, + 0x85, 0x86, 0x85, 0x81, 0x7c, 0x78, 0x75, 0x77, 0x7b, 0x82, 0x87, 0x89, 0x87, 0x81, 0x79, 0x75, + 0x75, 0x78, 0x7e, 0x84, 0x88, 0x88, 0x85, 0x83, 0x80, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, + 0x80, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7d, 0x7b, 0x78, 0x78, 0x7a, 0x7e, 0x86, + 0x8c, 0x8d, 0x89, 0x81, 0x79, 0x74, 0x72, 0x75, 0x7a, 0x80, 0x84, 0x88, 0x88, 0x86, 0x83, 0x7b, + 0x74, 0x71, 0x71, 0x76, 0x80, 0x87, 0x8b, 0x8c, 0x8b, 0x87, 0x80, 0x79, 0x74, 0x72, 0x73, 0x77, + 0x7d, 0x83, 0x87, 0x88, 0x85, 0x82, 0x7e, 0x7b, 0x7b, 0x7a, 0x78, 0x79, 0x7d, 0x81, 0x84, 0x85, + 0x84, 0x82, 0x7e, 0x7c, 0x7a, 0x79, 0x78, 0x79, 0x7d, 0x81, 0x83, 0x84, 0x82, 0x7d, 0x7b, 0x7a, + 0x7c, 0x80, 0x83, 0x84, 0x83, 0x80, 0x7d, 0x7b, 0x7a, 0x7b, 0x7e, 0x82, 0x84, 0x87, 0x88, 0x86, + 0x84, 0x7d, 0x78, 0x75, 0x73, 0x75, 0x7a, 0x82, 0x88, 0x8c, 0x8e, 0x8b, 0x85, 0x7d, 0x74, 0x70, + 0x6e, 0x70, 0x79, 0x83, 0x8b, 0x8f, 0x8b, 0x86, 0x83, 0x7e, 0x7d, 0x7a, 0x78, 0x76, 0x74, 0x74, + 0x77, 0x7d, 0x86, 0x8d, 0x8f, 0x8f, 0x8b, 0x86, 0x7e, 0x75, 0x6e, 0x6a, 0x6a, 0x71, 0x7b, 0x88, + 0x92, 0x98, 0x97, 0x8f, 0x83, 0x76, 0x6e, 0x6c, 0x6f, 0x78, 0x82, 0x8a, 0x8f, 0x8e, 0x8a, 0x83, + 0x7c, 0x75, 0x72, 0x72, 0x78, 0x81, 0x8a, 0x91, 0x92, 0x8d, 0x84, 0x78, 0x71, 0x6c, 0x6b, 0x70, + 0x79, 0x85, 0x8c, 0x90, 0x8e, 0x86, 0x7d, 0x77, 0x74, 0x75, 0x76, 0x78, 0x7c, 0x84, 0x8a, 0x8d, + 0x8a, 0x85, 0x7d, 0x76, 0x74, 0x75, 0x77, 0x7a, 0x7e, 0x82, 0x85, 0x85, 0x84, 0x83, 0x82, 0x7d, + 0x7a, 0x78, 0x76, 0x77, 0x79, 0x7c, 0x80, 0x81, 0x84, 0x85, 0x82, 0x80, 0x7c, 0x7b, 0x7b, 0x7b, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x82, 0x81, 0x7d, 0x79, 0x76, + 0x75, 0x78, 0x7b, 0x7d, 0x81, 0x84, 0x86, 0x8a, 0x8c, 0x8c, 0x84, 0x7a, 0x70, 0x6a, 0x6b, 0x70, + 0x78, 0x83, 0x8b, 0x91, 0x94, 0x90, 0x88, 0x7d, 0x71, 0x6a, 0x69, 0x6e, 0x77, 0x81, 0x8a, 0x8e, + 0x8c, 0x88, 0x84, 0x80, 0x7a, 0x76, 0x75, 0x77, 0x7d, 0x83, 0x86, 0x85, 0x81, 0x7c, 0x7b, 0x7d, + 0x82, 0x84, 0x83, 0x81, 0x7c, 0x7a, 0x7a, 0x7c, 0x7c, 0x7d, 0x80, 0x84, 0x88, 0x89, 0x84, 0x7a, + 0x73, 0x70, 0x73, 0x78, 0x7e, 0x84, 0x86, 0x87, 0x87, 0x86, 0x83, 0x7e, 0x7a, 0x7a, 0x7b, 0x7c, + 0x7b, 0x78, 0x78, 0x78, 0x7b, 0x81, 0x85, 0x87, 0x88, 0x87, 0x85, 0x80, 0x79, 0x75, 0x73, 0x74, + 0x77, 0x7b, 0x81, 0x86, 0x88, 0x89, 0x86, 0x81, 0x7b, 0x77, 0x75, 0x77, 0x79, 0x7b, 0x7e, 0x84, + 0x89, 0x8c, 0x8c, 0x88, 0x81, 0x79, 0x74, 0x72, 0x73, 0x78, 0x7d, 0x83, 0x88, 0x8a, 0x88, 0x84, + 0x80, 0x7a, 0x77, 0x76, 0x79, 0x7c, 0x7d, 0x80, 0x83, 0x86, 0x88, 0x87, 0x85, 0x81, 0x7b, 0x78, + 0x75, 0x75, 0x78, 0x7c, 0x82, 0x88, 0x8b, 0x8b, 0x87, 0x7e, 0x76, 0x72, 0x70, 0x72, 0x77, 0x7c, + 0x82, 0x86, 0x88, 0x87, 0x83, 0x7c, 0x78, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7e, 0x83, 0x88, 0x8c, + 0x8b, 0x86, 0x7d, 0x74, 0x71, 0x74, 0x77, 0x7b, 0x80, 0x82, 0x82, 0x83, 0x86, 0x87, 0x85, 0x83, + 0x81, 0x80, 0x7e, 0x7c, 0x7b, 0x79, 0x79, 0x7d, 0x82, 0x86, 0x88, 0x87, 0x85, 0x82, 0x7e, 0x7b, + 0x78, 0x78, 0x7a, 0x7d, 0x81, 0x84, 0x85, 0x84, 0x82, 0x83, 0x84, 0x84, 0x82, 0x7b, 0x75, 0x71, + 0x71, 0x77, 0x80, 0x87, 0x8c, 0x8f, 0x90, 0x8b, 0x83, 0x77, 0x6d, 0x67, 0x67, 0x6c, 0x78, 0x86, + 0x91, 0x98, 0x99, 0x94, 0x8a, 0x7b, 0x6e, 0x66, 0x64, 0x6b, 0x76, 0x84, 0x8d, 0x94, 0x96, 0x93, + 0x8d, 0x83, 0x78, 0x70, 0x6d, 0x6e, 0x74, 0x7a, 0x82, 0x88, 0x8d, 0x8e, 0x8a, 0x84, 0x7b, 0x77, + 0x76, 0x77, 0x78, 0x7a, 0x7d, 0x81, 0x83, 0x84, 0x83, 0x81, 0x82, 0x83, 0x82, 0x80, 0x7d, 0x7b, + 0x7b, 0x7b, 0x7c, 0x7e, 0x82, 0x84, 0x85, 0x85, 0x81, 0x7c, 0x79, 0x79, 0x7c, 0x7d, 0x7e, 0x81, + 0x83, 0x83, 0x85, 0x84, 0x82, 0x7c, 0x78, 0x79, 0x7c, 0x80, 0x83, 0x83, 0x82, 0x83, 0x83, 0x82, + 0x7d, 0x78, 0x74, 0x73, 0x76, 0x7b, 0x80, 0x84, 0x87, 0x89, 0x8a, 0x89, 0x83, 0x7b, 0x76, 0x75, + 0x78, 0x7a, 0x7c, 0x7e, 0x81, 0x84, 0x88, 0x8a, 0x8a, 0x85, 0x80, 0x7a, 0x77, 0x76, 0x75, 0x77, + 0x7b, 0x83, 0x8a, 0x8e, 0x8c, 0x87, 0x80, 0x79, 0x76, 0x74, 0x73, 0x74, 0x78, 0x7d, 0x84, 0x89, + 0x8d, 0x8d, 0x8a, 0x87, 0x81, 0x7a, 0x72, 0x6e, 0x70, 0x76, 0x80, 0x88, 0x8f, 0x91, 0x8e, 0x88, + 0x81, 0x77, 0x70, 0x6f, 0x72, 0x78, 0x7e, 0x84, 0x88, 0x8b, 0x8e, 0x8e, 0x8b, 0x81, 0x73, 0x69, + 0x63, 0x67, 0x75, 0x84, 0x92, 0x9a, 0x9a, 0x96, 0x8c, 0x80, 0x72, 0x67, 0x62, 0x64, 0x6c, 0x79, + 0x88, 0x94, 0x99, 0x98, 0x92, 0x87, 0x7b, 0x70, 0x68, 0x67, 0x6d, 0x76, 0x80, 0x89, 0x8d, 0x8e, + 0x8c, 0x8a, 0x86, 0x82, 0x7d, 0x78, 0x75, 0x73, 0x73, 0x74, 0x77, 0x7e, 0x87, 0x8d, 0x8f, 0x8e, + 0x89, 0x83, 0x7b, 0x74, 0x71, 0x70, 0x72, 0x78, 0x80, 0x86, 0x88, 0x86, 0x85, 0x84, 0x82, 0x80, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7b, 0x7b, 0x7c, 0x7e, 0x83, 0x85, 0x84, 0x83, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x82, 0x86, 0x88, 0x86, + 0x82, 0x7e, 0x7a, 0x79, 0x7a, 0x7b, 0x7d, 0x81, 0x82, 0x82, 0x81, 0x7c, 0x7a, 0x7b, 0x81, 0x87, + 0x8a, 0x89, 0x85, 0x7d, 0x78, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x85, 0x89, 0x8b, 0x89, 0x84, 0x7d, + 0x78, 0x76, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x80, 0x85, 0x89, 0x89, 0x88, 0x86, 0x82, 0x7c, 0x78, + 0x74, 0x73, 0x75, 0x7a, 0x82, 0x88, 0x8a, 0x8a, 0x88, 0x83, 0x7d, 0x7a, 0x78, 0x77, 0x77, 0x79, + 0x7d, 0x83, 0x89, 0x8b, 0x89, 0x84, 0x7c, 0x75, 0x71, 0x71, 0x77, 0x82, 0x8a, 0x8f, 0x8d, 0x86, + 0x7d, 0x77, 0x74, 0x75, 0x78, 0x7d, 0x84, 0x87, 0x89, 0x86, 0x82, 0x7d, 0x7b, 0x78, 0x79, 0x7b, + 0x7c, 0x7b, 0x7b, 0x7d, 0x7e, 0x81, 0x83, 0x85, 0x85, 0x83, 0x80, 0x7b, 0x78, 0x77, 0x79, 0x79, + 0x80, 0x86, 0x84, 0x86, 0x87, 0x81, 0x7c, 0x7a, 0x7b, 0x7e, 0x7c, 0x7e, 0x80, 0x7b, 0x7b, 0x7b, + 0x7c, 0x82, 0x82, 0x81, 0x82, 0x82, 0x83, 0x82, 0x7c, 0x7a, 0x78, 0x77, 0x7a, 0x80, 0x83, 0x81, + 0x80, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7e, 0x7e, 0x7e, 0x81, 0x80, 0x7d, 0x7d, 0x80, 0x81, 0x80, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7e, 0x81, 0x81, 0x7d, 0x7b, 0x7b, 0x7d, 0x80, 0x82, 0x83, 0x86, 0x86, + 0x85, 0x81, 0x7b, 0x77, 0x72, 0x73, 0x75, 0x7a, 0x80, 0x84, 0x8a, 0x8e, 0x90, 0x8b, 0x81, 0x75, + 0x6d, 0x68, 0x69, 0x71, 0x7b, 0x86, 0x8f, 0x91, 0x90, 0x89, 0x7d, 0x72, 0x6c, 0x6e, 0x73, 0x7a, + 0x82, 0x87, 0x89, 0x87, 0x85, 0x83, 0x80, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x81, 0x83, 0x84, + 0x84, 0x84, 0x84, 0x82, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7c, 0x7e, 0x81, 0x82, 0x82, 0x81, + 0x80, 0x7e, 0x7c, 0x7b, 0x7a, 0x7b, 0x7b, 0x7e, 0x84, 0x87, 0x87, 0x85, 0x82, 0x7e, 0x79, 0x76, + 0x75, 0x77, 0x79, 0x7d, 0x83, 0x88, 0x8b, 0x8b, 0x8a, 0x86, 0x7d, 0x75, 0x72, 0x73, 0x76, 0x7c, + 0x84, 0x89, 0x8b, 0x87, 0x84, 0x80, 0x7a, 0x75, 0x74, 0x79, 0x7e, 0x83, 0x86, 0x88, 0x86, 0x81, + 0x7d, 0x7a, 0x76, 0x75, 0x78, 0x7c, 0x82, 0x86, 0x88, 0x86, 0x81, 0x7e, 0x7c, 0x79, 0x78, 0x7b, + 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x80, 0x7e, 0x7b, 0x77, 0x75, 0x75, + 0x77, 0x7d, 0x85, 0x8a, 0x8c, 0x8b, 0x88, 0x82, 0x79, 0x72, 0x6f, 0x71, 0x75, 0x7d, 0x86, 0x8a, + 0x8c, 0x8d, 0x8b, 0x86, 0x7e, 0x77, 0x72, 0x70, 0x72, 0x79, 0x81, 0x85, 0x89, 0x8c, 0x8c, 0x89, + 0x86, 0x82, 0x7c, 0x77, 0x73, 0x73, 0x74, 0x78, 0x80, 0x86, 0x88, 0x87, 0x85, 0x82, 0x7d, 0x7a, + 0x79, 0x79, 0x7a, 0x7e, 0x84, 0x86, 0x85, 0x82, 0x80, 0x80, 0x81, 0x82, 0x80, 0x7c, 0x79, 0x7a, + 0x7e, 0x82, 0x84, 0x85, 0x86, 0x85, 0x84, 0x81, 0x7d, 0x78, 0x75, 0x78, 0x7e, 0x84, 0x88, 0x8b, + 0x8c, 0x88, 0x83, 0x7e, 0x77, 0x72, 0x72, 0x74, 0x78, 0x81, 0x88, 0x8b, 0x8c, 0x8b, 0x86, 0x82, + 0x7d, 0x77, 0x73, 0x71, 0x70, 0x72, 0x79, 0x82, 0x8c, 0x93, 0x94, 0x90, 0x89, 0x7d, 0x75, 0x70, + 0x6e, 0x70, 0x74, 0x7a, 0x84, 0x8d, 0x92, 0x93, 0x8f, 0x88, 0x7e, 0x75, 0x6f, 0x6e, 0x72, 0x79, + 0x82, 0x89, 0x8e, 0x8f, 0x8c, 0x84, 0x7b, 0x74, 0x70, 0x6f, 0x74, 0x7a, 0x82, 0x88, 0x8b, 0x89, + 0x85, 0x81, 0x7b, 0x76, 0x73, 0x72, 0x74, 0x79, 0x80, 0x86, 0x8b, 0x8d, 0x8b, 0x89, 0x83, 0x7b, + 0x75, 0x72, 0x71, 0x73, 0x78, 0x80, 0x87, 0x8d, 0x91, 0x90, 0x8c, 0x86, 0x7b, 0x72, 0x6f, 0x6f, + 0x72, 0x76, 0x7c, 0x82, 0x86, 0x88, 0x88, 0x86, 0x84, 0x82, 0x80, 0x7c, 0x78, 0x76, 0x74, 0x75, + 0x79, 0x7d, 0x83, 0x87, 0x8b, 0x8b, 0x88, 0x84, 0x7d, 0x75, 0x70, 0x6f, 0x71, 0x78, 0x80, 0x88, + 0x8d, 0x8d, 0x8b, 0x86, 0x82, 0x7c, 0x7a, 0x7a, 0x79, 0x79, 0x7a, 0x7a, 0x7d, 0x84, 0x89, 0x8b, + 0x8c, 0x89, 0x84, 0x7d, 0x77, 0x73, 0x72, 0x74, 0x78, 0x7c, 0x82, 0x87, 0x8c, 0x90, 0x91, 0x8d, + 0x85, 0x79, 0x6f, 0x69, 0x69, 0x6d, 0x75, 0x80, 0x8a, 0x92, 0x97, 0x95, 0x8d, 0x82, 0x75, 0x6e, + 0x6c, 0x6e, 0x75, 0x7c, 0x84, 0x89, 0x8d, 0x8f, 0x8c, 0x85, 0x7c, 0x73, 0x6d, 0x6d, 0x72, 0x7b, + 0x86, 0x8f, 0x92, 0x91, 0x8c, 0x84, 0x79, 0x71, 0x6f, 0x70, 0x75, 0x7d, 0x86, 0x8b, 0x8c, 0x88, + 0x82, 0x7d, 0x7a, 0x78, 0x77, 0x76, 0x77, 0x7b, 0x80, 0x83, 0x83, 0x82, 0x81, 0x82, 0x83, 0x82, + 0x83, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7a, 0x7b, 0x7e, 0x82, 0x86, 0x89, 0x89, 0x85, 0x80, 0x78, + 0x74, 0x73, 0x75, 0x79, 0x7e, 0x84, 0x88, 0x8b, 0x8b, 0x89, 0x83, 0x7b, 0x76, 0x73, 0x73, 0x76, + 0x7b, 0x81, 0x84, 0x87, 0x88, 0x89, 0x87, 0x83, 0x7e, 0x7a, 0x77, 0x78, 0x7a, 0x7d, 0x80, 0x82, + 0x82, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, + 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x79, 0x7a, 0x7b, 0x7a, 0x79, 0x78, + 0x78, 0x79, 0x7a, 0x7a, 0x78, 0x77, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7e, 0x7c, 0x7b, 0x7b, + 0x7d, 0x81, 0x83, 0x85, 0x85, 0x84, 0x83, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83, + 0x84, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x85, 0x87, 0x87, 0x85, 0x80, 0x75, 0x77, 0x80, 0x85, + 0x88, 0x87, 0x85, 0x82, 0x7e, 0x7e, 0x7e, 0x81, 0x84, 0x86, 0x84, 0x83, 0x85, 0x88, 0x89, 0x8a, + 0x8a, 0x87, 0x81, 0x7a, 0x78, 0x77, 0x77, 0x79, 0x79, 0x75, 0x70, 0x6d, 0x6b, 0x6f, 0x73, 0x77, + 0x79, 0x77, 0x75, 0x74, 0x71, 0x70, 0x71, 0x7a, 0x83, 0x7d, 0x76, 0x76, 0x7c, 0x7d, 0x7c, 0x7a, + 0x77, 0x75, 0x72, 0x77, 0x7a, 0x83, 0x8b, 0x8a, 0x8b, 0x87, 0x85, 0x87, 0x8c, 0x94, 0x9e, 0xa8, + 0xac, 0xa8, 0xa3, 0x9d, 0x98, 0x92, 0x89, 0x87, 0x86, 0x7e, 0x79, 0x7e, 0x81, 0x7d, 0x72, 0x6a, + 0x67, 0x61, 0x66, 0x6c, 0x70, 0x74, 0x71, 0x6a, 0x67, 0x69, 0x6a, 0x6c, 0x6e, 0x71, 0x70, 0x6b, + 0x68, 0x69, 0x6b, 0x6e, 0x6f, 0x6f, 0x6a, 0x64, 0x61, 0x5e, 0x6c, 0x7a, 0x82, 0x84, 0x86, 0x89, + 0x8a, 0x8e, 0x97, 0x9f, 0xa6, 0xa4, 0xa5, 0xa7, 0xa3, 0x9d, 0xa0, 0xa2, 0xa3, 0xb1, 0xb1, 0xab, + 0xa8, 0xa4, 0xa0, 0x9a, 0x93, 0x8a, 0x83, 0x7e, 0x76, 0x7b, 0x86, 0x8c, 0x8b, 0x83, 0x7d, 0x7d, + 0x7e, 0x82, 0x86, 0x89, 0x85, 0x7d, 0x7e, 0x7c, 0x79, 0x7c, 0x78, 0x71, 0x6f, 0x69, 0x68, 0x66, + 0x62, 0x63, 0x63, 0x5f, 0x5a, 0x4c, 0x49, 0x5e, 0x64, 0x6c, 0x74, 0x74, 0x6d, 0x6e, 0x76, 0x81, + 0x89, 0x8e, 0x90, 0x8e, 0x88, 0x87, 0x86, 0x86, 0x88, 0x86, 0x7b, 0x7e, 0x84, 0x8a, 0x92, 0x99, + 0xa2, 0xa5, 0x9c, 0x91, 0x88, 0x7c, 0x7e, 0x81, 0x73, 0x70, 0x69, 0x61, 0x5e, 0x5c, 0x58, 0x5e, + 0x5b, 0x5f, 0x67, 0x6a, 0x71, 0x76, 0x83, 0x8a, 0x8d, 0x8a, 0x81, 0x84, 0x89, 0x8c, 0x90, 0x8f, + 0x8d, 0x85, 0x79, 0x75, 0x70, 0x72, 0x7e, 0x70, 0x68, 0x6d, 0x6e, 0x72, 0x7c, 0x87, 0x8b, 0x8a, + 0x87, 0x7d, 0x72, 0x78, 0x82, 0x8a, 0x8d, 0x86, 0x77, 0x69, 0x67, 0x7a, 0x8c, 0x92, 0x98, 0xa3, + 0xa2, 0x97, 0x89, 0x80, 0x7b, 0x88, 0x95, 0x8e, 0x92, 0x96, 0x98, 0x9b, 0x9c, 0x9a, 0x9e, 0x9b, + 0x95, 0x93, 0x94, 0x94, 0x96, 0x93, 0x8c, 0x83, 0x78, 0x6d, 0x6f, 0x72, 0x6d, 0x68, 0x67, 0x66, + 0x63, 0x5f, 0x59, 0x5a, 0x63, 0x6b, 0x67, 0x68, 0x70, 0x7a, 0x7a, 0x7c, 0x7a, 0x79, 0x7b, 0x7a, + 0x76, 0x6c, 0x68, 0x70, 0x6a, 0x67, 0x6e, 0x74, 0x71, 0x78, 0x8e, 0x91, 0x87, 0x86, 0x8d, 0x8c, + 0x84, 0x7b, 0x7e, 0x80, 0x72, 0x5f, 0x63, 0x71, 0x7e, 0x85, 0x88, 0x83, 0x74, 0x72, 0x70, 0x74, + 0x82, 0x8d, 0x8f, 0x89, 0x82, 0x7b, 0x7a, 0x80, 0x88, 0x95, 0x96, 0x90, 0x90, 0x91, 0x8d, 0x8a, + 0x8c, 0x8b, 0x8f, 0x93, 0x90, 0x98, 0xa9, 0xa6, 0x9a, 0x8f, 0x89, 0x83, 0x74, 0x6a, 0x68, 0x6e, + 0x7a, 0x7a, 0x76, 0x6c, 0x67, 0x80, 0x88, 0x80, 0x83, 0x8d, 0x91, 0x91, 0x8d, 0x8b, 0x89, 0x8b, + 0x8b, 0x83, 0x7a, 0x72, 0x6c, 0x76, 0x7c, 0x7b, 0x81, 0x87, 0x86, 0x89, 0x8e, 0x94, 0xa2, 0xb7, + 0xb1, 0x97, 0x86, 0x81, 0x8a, 0x82, 0x7a, 0x80, 0x7d, 0x77, 0x78, 0x6d, 0x66, 0x6e, 0x75, 0x7b, + 0x6a, 0x5c, 0x5d, 0x69, 0x79, 0x80, 0x7b, 0x77, 0x77, 0x76, 0x73, 0x74, 0x72, 0x77, 0x7a, 0x72, + 0x63, 0x60, 0x62, 0x64, 0x6b, 0x6d, 0x69, 0x68, 0x6d, 0x82, 0x80, 0x75, 0x6e, 0x74, 0x7a, 0x67, + 0x66, 0x6d, 0x67, 0x74, 0x8d, 0x8f, 0x8d, 0x8e, 0x89, 0x84, 0x78, 0x73, 0x78, 0x87, 0x85, 0x77, + 0x74, 0x76, 0x76, 0x7c, 0x83, 0x7a, 0x71, 0x70, 0x72, 0x73, 0x78, 0x83, 0x9d, 0xa6, 0x91, 0x86, + 0x86, 0x87, 0x9e, 0xad, 0xa6, 0xa2, 0xa2, 0xa0, 0x95, 0x90, 0x8d, 0x81, 0x7d, 0x94, 0x90, 0x83, + 0x8a, 0x94, 0x9f, 0x9c, 0x88, 0x7d, 0x8c, 0x8f, 0x83, 0x89, 0x93, 0x8a, 0x7d, 0x73, 0x72, 0x78, + 0x70, 0x6b, 0x75, 0x72, 0x6f, 0x71, 0x79, 0x83, 0x8a, 0x82, 0x91, 0x9a, 0x82, 0x6d, 0x63, 0x70, + 0x77, 0x6a, 0x6b, 0x6a, 0x69, 0x71, 0x72, 0x6c, 0x78, 0x89, 0x88, 0x7b, 0x74, 0x6e, 0x6a, 0x6a, + 0x80, 0x95, 0x8a, 0x7a, 0x6e, 0x5f, 0x5b, 0x64, 0x65, 0x65, 0x69, 0x6b, 0x67, 0x68, 0x6f, 0x78, + 0x82, 0x86, 0x7d, 0x85, 0x89, 0x79, 0x76, 0x82, 0x79, 0x70, 0x64, 0x5e, 0x61, 0x6b, 0x73, 0x65, + 0x6e, 0x85, 0x87, 0x87, 0x88, 0x8a, 0x8b, 0x8d, 0x99, 0xac, 0xbc, 0xba, 0xaf, 0xa4, 0x9d, 0xa0, + 0x9a, 0x7e, 0x75, 0x7c, 0x77, 0x81, 0x9b, 0x9d, 0x95, 0x8b, 0x89, 0x85, 0x8f, 0x96, 0x86, 0x80, + 0x7e, 0x77, 0x6b, 0x68, 0x6b, 0x65, 0x61, 0x70, 0x7b, 0x83, 0x8e, 0x90, 0x91, 0x8e, 0x85, 0x7d, + 0x7a, 0x7c, 0x82, 0x8e, 0xa8, 0x9c, 0x91, 0x9b, 0x93, 0x88, 0x7b, 0x78, 0x74, 0x68, 0x74, 0x74, + 0x63, 0x5d, 0x68, 0x69, 0x6a, 0x82, 0x86, 0x78, 0x77, 0x77, 0x77, 0x73, 0x70, 0x7b, 0x85, 0x83, + 0x81, 0x87, 0x98, 0xac, 0xab, 0xad, 0xa0, 0x98, 0x99, 0x96, 0x97, 0x87, 0x71, 0x77, 0x6f, 0x6c, + 0x75, 0x7c, 0x79, 0x71, 0x7e, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7a, 0x6f, 0x5e, 0x61, 0x68, 0x5f, + 0x5f, 0x73, 0x76, 0x5f, 0x48, 0x4a, 0x53, 0x53, 0x55, 0x56, 0x48, 0x48, 0x62, 0x67, 0x62, 0x61, + 0x64, 0x68, 0x7d, 0x91, 0x87, 0x81, 0x95, 0xa3, 0x9d, 0x83, 0x6d, 0x64, 0x62, 0x65, 0x6e, 0x71, + 0x6e, 0x86, 0x8c, 0x8f, 0x8f, 0x89, 0x91, 0x9a, 0x92, 0x80, 0x73, 0x79, 0x78, 0x73, 0x82, 0x99, + 0xa7, 0xab, 0xa3, 0x95, 0xa6, 0xbc, 0xbe, 0xb9, 0xb3, 0xae, 0xab, 0xa4, 0xa6, 0xa7, 0xae, 0xb4, + 0xc5, 0xc8, 0xb6, 0xb3, 0xb6, 0xb1, 0xae, 0x9b, 0x7a, 0x73, 0x79, 0x83, 0x86, 0x82, 0x78, 0x81, + 0x86, 0x7d, 0x84, 0x8c, 0x88, 0x77, 0x6f, 0x65, 0x59, 0x57, 0x5a, 0x5c, 0x68, 0x83, 0x8a, 0x7a, + 0x68, 0x5f, 0x59, 0x57, 0x60, 0x6b, 0x6c, 0x5c, 0x4c, 0x54, 0x4d, 0x41, 0x3f, 0x40, 0x55, 0x6d, + 0x68, 0x6f, 0x76, 0x78, 0x79, 0x73, 0x6a, 0x74, 0x80, 0x7e, 0x7e, 0x84, 0x85, 0x84, 0x78, 0x78, + 0x81, 0x84, 0x83, 0x7e, 0x71, 0x62, 0x5c, 0x64, 0x6c, 0x7b, 0x8b, 0x90, 0x94, 0xa3, 0x9e, 0x98, + 0x99, 0x93, 0x95, 0x99, 0x93, 0x89, 0x92, 0x99, 0x9b, 0x90, 0x8f, 0xa1, 0xa0, 0xa3, 0xa1, 0xa2, + 0xaf, 0xb5, 0xa8, 0x99, 0x97, 0x8a, 0x7a, 0x73, 0x7a, 0x83, 0x83, 0x88, 0x88, 0x79, 0x70, 0x83, + 0x9e, 0x9a, 0x8a, 0x7d, 0x79, 0x6b, 0x65, 0x78, 0x78, 0x79, 0x73, 0x62, 0x5b, 0x5d, 0x5f, 0x6b, + 0x6e, 0x6b, 0x68, 0x67, 0x64, 0x64, 0x64, 0x66, 0x62, 0x77, 0x94, 0x8b, 0x84, 0x83, 0x87, 0x84, + 0x72, 0x66, 0x73, 0x7e, 0x81, 0x8b, 0x7c, 0x68, 0x70, 0x88, 0x92, 0x8d, 0x8c, 0x8a, 0x8a, 0x80, + 0x73, 0x72, 0x6c, 0x5a, 0x4d, 0x4f, 0x66, 0x6f, 0x72, 0x80, 0x8c, 0x8e, 0x86, 0x86, 0x92, 0x91, + 0x8c, 0x93, 0x98, 0x94, 0x91, 0x88, 0x85, 0x87, 0x6c, 0x5a, 0x69, 0x74, 0x79, 0x7c, 0x6e, 0x67, + 0x61, 0x64, 0x6d, 0x7b, 0x8b, 0x8e, 0x88, 0x9b, 0xa4, 0xa3, 0xa4, 0xac, 0xad, 0xa0, 0x94, 0x9f, + 0xa1, 0x99, 0x9f, 0x9d, 0xa3, 0xad, 0xa5, 0x90, 0x9c, 0xae, 0xb3, 0xb5, 0x9d, 0x97, 0x94, 0x84, + 0x6d, 0x5a, 0x67, 0x79, 0x83, 0x90, 0x9a, 0x91, 0x7b, 0x6c, 0x83, 0x97, 0x93, 0xa0, 0xaf, 0xa6, + 0xa1, 0x9a, 0x90, 0x8d, 0x86, 0x87, 0x6e, 0x5a, 0x60, 0x61, 0x58, 0x59, 0x6b, 0x6a, 0x57, 0x46, + 0x49, 0x56, 0x62, 0x7a, 0x86, 0x79, 0x71, 0x66, 0x5d, 0x54, 0x43, 0x3e, 0x46, 0x46, 0x4b, 0x43, + 0x39, 0x3d, 0x46, 0x62, 0x68, 0x5d, 0x5b, 0x6f, 0x67, 0x4f, 0x48, 0x57, 0x68, 0x6b, 0x72, 0x82, + 0x7a, 0x6d, 0x68, 0x80, 0x97, 0x94, 0x88, 0x81, 0x89, 0x86, 0x89, 0x9a, 0xb7, 0xbb, 0xae, 0xa5, + 0x91, 0x8b, 0x84, 0x78, 0x86, 0x8f, 0x90, 0x89, 0x72, 0x68, 0x65, 0x60, 0x68, 0x7b, 0x90, 0x9c, + 0xa1, 0x9c, 0x92, 0x8d, 0x92, 0x9d, 0x9e, 0x94, 0x8d, 0x81, 0x78, 0x92, 0xaf, 0xc4, 0xc1, 0xaa, + 0x98, 0x9b, 0xa3, 0xa5, 0x99, 0xa7, 0xa2, 0x91, 0x8b, 0x84, 0x7d, 0x70, 0x6b, 0x6d, 0x72, 0x70, + 0x7b, 0x85, 0x7b, 0x6e, 0x64, 0x69, 0x6d, 0x75, 0x77, 0x78, 0x73, 0x74, 0x94, 0xa5, 0xa2, 0x94, + 0x81, 0x76, 0x67, 0x55, 0x5c, 0x70, 0x7a, 0x7a, 0x8a, 0x9d, 0xa2, 0xa2, 0x98, 0x9b, 0x9c, 0x9a, + 0x99, 0x90, 0x8c, 0x83, 0x6e, 0x6a, 0x75, 0x79, 0x75, 0x6a, 0x6d, 0x71, 0x68, 0x55, 0x5c, 0x80, + 0x8d, 0x84, 0x78, 0x64, 0x66, 0x74, 0x81, 0x8d, 0x9a, 0xa3, 0xa8, 0xa1, 0x9f, 0x8c, 0x81, 0x89, + 0x91, 0x99, 0x99, 0x8a, 0x8e, 0x9c, 0xb4, 0xb4, 0xb1, 0xb4, 0x9b, 0x77, 0x5e, 0x5c, 0x60, 0x5b, + 0x53, 0x4c, 0x42, 0x3b, 0x37, 0x33, 0x2f, 0x41, 0x61, 0x78, 0x83, 0x76, 0x6c, 0x75, 0x89, 0x96, + 0x95, 0x88, 0x84, 0x84, 0x85, 0x7e, 0x77, 0x8f, 0xad, 0xb4, 0xab, 0x91, 0x7e, 0x79, 0x84, 0x89, + 0x70, 0x5c, 0x68, 0x6b, 0x6e, 0x6f, 0x6b, 0x66, 0x64, 0x6b, 0x6f, 0x74, 0x76, 0x6f, 0x6b, 0x69, + 0x74, 0x89, 0x9d, 0x97, 0x7e, 0x76, 0x77, 0x80, 0x87, 0x83, 0x76, 0x6f, 0x6f, 0x68, 0x56, 0x4c, + 0x50, 0x67, 0x75, 0x7b, 0x80, 0x8b, 0x97, 0xb7, 0xc5, 0x9b, 0x77, 0x6f, 0x74, 0x6c, 0x4d, 0x37, + 0x3f, 0x5f, 0x6d, 0x78, 0x79, 0x65, 0x50, 0x3b, 0x39, 0x5c, 0x81, 0x84, 0x75, 0x71, 0x6e, 0x6a, + 0x73, 0x79, 0x8e, 0x90, 0x90, 0xa0, 0xa6, 0x9b, 0x8a, 0x80, 0x98, 0xb4, 0xb5, 0xa8, 0xa7, 0xc4, + 0xda, 0xd4, 0xc6, 0xb8, 0xa9, 0xa9, 0x8b, 0x6e, 0x6c, 0x6e, 0x76, 0x78, 0x7e, 0x84, 0x80, 0x79, + 0x7b, 0x8c, 0x9f, 0xa3, 0xa8, 0xa9, 0x99, 0x8f, 0x96, 0xa5, 0xab, 0xad, 0xa2, 0x9f, 0xa4, 0x93, + 0x8a, 0x8c, 0x90, 0x93, 0x91, 0x88, 0x7b, 0x77, 0x86, 0x96, 0x83, 0x6e, 0x65, 0x64, 0x6d, 0x74, + 0x74, 0x70, 0x81, 0x97, 0x90, 0x84, 0x79, 0x78, 0x6e, 0x57, 0x4a, 0x5a, 0x81, 0x92, 0x8d, 0x8a, + 0x83, 0x7b, 0x79, 0x77, 0x71, 0x74, 0x7a, 0x72, 0x5b, 0x59, 0x66, 0x66, 0x67, 0x76, 0x8a, 0x86, + 0x85, 0xa1, 0xbb, 0xa4, 0x7d, 0x68, 0x5d, 0x53, 0x50, 0x4d, 0x5b, 0x75, 0x80, 0x87, 0x8f, 0x93, + 0x94, 0x79, 0x4d, 0x3c, 0x4c, 0x5f, 0x64, 0x59, 0x62, 0x62, 0x5b, 0x67, 0x83, 0x95, 0x80, 0x6a, + 0x6d, 0x77, 0x6d, 0x69, 0x7b, 0x7d, 0x7c, 0x8a, 0x8e, 0xad, 0xd1, 0xcd, 0xaf, 0x9b, 0x86, 0x70, + 0x4f, 0x3b, 0x38, 0x2e, 0x21, 0x16, 0x2a, 0x49, 0x56, 0x57, 0x59, 0x64, 0x63, 0x71, 0x9f, 0xab, + 0xac, 0xa0, 0x95, 0x99, 0x9b, 0xa0, 0xa4, 0xa9, 0xb4, 0xb8, 0xc1, 0xc6, 0xbc, 0xb1, 0xa3, 0x8b, + 0x86, 0x96, 0xb1, 0xc2, 0xb3, 0xa8, 0x9e, 0x94, 0x86, 0x7c, 0x8f, 0x8b, 0x87, 0x89, 0x8d, 0x96, + 0x9b, 0x93, 0x75, 0x5a, 0x4d, 0x5e, 0x82, 0xa0, 0xae, 0xb2, 0xa1, 0x91, 0x95, 0x86, 0x6a, 0x5f, + 0x5a, 0x5e, 0x56, 0x53, 0x6e, 0x80, 0x8d, 0x95, 0x9d, 0x9f, 0x9e, 0xb8, 0xbc, 0xaf, 0xb0, 0xa7, + 0x9b, 0x84, 0x6f, 0x67, 0x6a, 0x68, 0x64, 0x64, 0x67, 0x75, 0x78, 0x63, 0x43, 0x2b, 0x27, 0x27, + 0x37, 0x3b, 0x40, 0x54, 0x5a, 0x5b, 0x5e, 0x65, 0x5c, 0x60, 0x6f, 0x6c, 0x70, 0x75, 0x77, 0x75, + 0x73, 0x6d, 0x71, 0x8a, 0xac, 0xaf, 0xa6, 0xa2, 0x93, 0x83, 0x6b, 0x4f, 0x46, 0x4f, 0x57, 0x5b, + 0x68, 0x86, 0xa3, 0xac, 0xad, 0xa6, 0x9c, 0x99, 0xa3, 0xac, 0xb9, 0xb6, 0xa8, 0x95, 0x82, 0x7c, + 0x77, 0x84, 0x91, 0x91, 0x8e, 0x91, 0x9e, 0xaf, 0xa8, 0x90, 0x79, 0x75, 0x85, 0x96, 0x7e, 0x7c, + 0x88, 0x89, 0x84, 0x82, 0x92, 0x88, 0x7b, 0x74, 0x6a, 0x6a, 0x68, 0x73, 0x74, 0x69, 0x62, 0x65, + 0x6f, 0x6e, 0x71, 0x7b, 0x81, 0x7a, 0x74, 0x6e, 0x59, 0x3e, 0x39, 0x37, 0x2c, 0x2e, 0x4c, 0x68, + 0x83, 0x93, 0x9c, 0x94, 0x98, 0xb7, 0xac, 0x9f, 0x9d, 0x97, 0x91, 0x77, 0x6d, 0x7d, 0x8c, 0x91, + 0x95, 0x9b, 0xa8, 0xb4, 0xb7, 0xa0, 0x81, 0x5e, 0x4c, 0x5a, 0x72, 0x74, 0x84, 0x8f, 0x91, 0x92, + 0x85, 0x82, 0x6f, 0x6d, 0x7d, 0x84, 0x93, 0x9f, 0xa5, 0xa2, 0xa4, 0xa5, 0xac, 0xbd, 0xc7, 0xc4, + 0xbe, 0xb7, 0xc2, 0xb4, 0x88, 0x65, 0x55, 0x4f, 0x3e, 0x34, 0x2a, 0x34, 0x4d, 0x57, 0x5c, 0x6e, + 0x71, 0x6e, 0x89, 0x92, 0x97, 0xa2, 0x9a, 0x96, 0xa4, 0xa3, 0x98, 0xa1, 0xa0, 0x96, 0x91, 0x9b, + 0xae, 0xb0, 0xa2, 0x97, 0x81, 0x7a, 0x8e, 0x8b, 0x79, 0x79, 0x90, 0xa5, 0xa0, 0xa9, 0xb9, 0xb5, + 0xae, 0xa6, 0x8e, 0x7e, 0x84, 0x83, 0x70, 0x60, 0x5c, 0x67, 0x80, 0x80, 0x7a, 0x80, 0x88, 0x8b, + 0x71, 0x54, 0x3c, 0x1b, 0x1b, 0x2e, 0x42, 0x53, 0x57, 0x60, 0x5f, 0x57, 0x56, 0x55, 0x53, 0x65, + 0x62, 0x4c, 0x53, 0x5f, 0x53, 0x3b, 0x36, 0x42, 0x54, 0x4c, 0x3a, 0x36, 0x45, 0x6a, 0x7b, 0x6d, + 0x59, 0x3c, 0x37, 0x4e, 0x51, 0x52, 0x5c, 0x66, 0x72, 0x80, 0x97, 0x95, 0x82, 0x7c, 0x82, 0x82, + 0x82, 0x8c, 0x95, 0x96, 0x98, 0xa7, 0xbb, 0xd5, 0xce, 0xb1, 0x9a, 0x9c, 0xbc, 0xc3, 0xb6, 0xac, + 0x97, 0x90, 0x89, 0x80, 0x7c, 0x7a, 0x87, 0x99, 0xa4, 0x9f, 0x9b, 0xaf, 0xb1, 0xa9, 0xa4, 0xad, + 0xb2, 0x9c, 0x84, 0x81, 0x7c, 0x7d, 0x84, 0x8d, 0x9f, 0xab, 0xbd, 0xcd, 0xbd, 0x9f, 0x86, 0x7a, + 0x8a, 0x87, 0x7e, 0x80, 0x81, 0x8c, 0x94, 0x98, 0x95, 0x8b, 0x88, 0x8a, 0x8e, 0x8e, 0x99, 0x9a, + 0x91, 0x8e, 0x86, 0x85, 0x92, 0x89, 0x7c, 0x79, 0x89, 0xa3, 0x9f, 0x7e, 0x64, 0x4b, 0x3a, 0x35, + 0x34, 0x3e, 0x47, 0x55, 0x69, 0x83, 0x97, 0xa1, 0xab, 0xac, 0x90, 0x75, 0x70, 0x78, 0x7e, 0x7e, + 0x80, 0x86, 0x8e, 0x82, 0x67, 0x53, 0x47, 0x44, 0x57, 0x6b, 0x6f, 0x63, 0x4f, 0x52, 0x59, 0x55, + 0x52, 0x57, 0x59, 0x68, 0x73, 0x7e, 0x84, 0x80, 0x82, 0x77, 0x74, 0x89, 0x95, 0x8f, 0x93, 0x97, + 0xa1, 0xbc, 0xbd, 0xa8, 0x9d, 0x99, 0x9b, 0xab, 0xac, 0xa0, 0x86, 0x75, 0x7a, 0x76, 0x5e, 0x5e, + 0x6a, 0x5f, 0x61, 0x6a, 0x61, 0x55, 0x5d, 0x66, 0x66, 0x69, 0x72, 0x7e, 0x80, 0x76, 0x76, 0x7d, + 0x82, 0x8c, 0x8a, 0x9b, 0xa4, 0xa8, 0xb2, 0xa8, 0x9c, 0x98, 0x9e, 0x93, 0x83, 0x78, 0x7c, 0x76, + 0x80, 0xa2, 0xaa, 0xa0, 0x95, 0x91, 0x7d, 0x6e, 0x73, 0x7e, 0x83, 0x80, 0x78, 0x80, 0x88, 0x7d, + 0x6a, 0x5e, 0x50, 0x4c, 0x62, 0x71, 0x6c, 0x5e, 0x47, 0x42, 0x45, 0x45, 0x45, 0x4e, 0x56, 0x67, + 0x83, 0x98, 0x9c, 0x90, 0x7a, 0x6f, 0x73, 0x7a, 0x74, 0x74, 0x8a, 0x95, 0x92, 0x87, 0x87, 0x79, + 0x71, 0x75, 0x77, 0x78, 0x72, 0x62, 0x54, 0x57, 0x5e, 0x60, 0x5f, 0x66, 0x69, 0x6c, 0x66, 0x68, + 0x69, 0x64, 0x6e, 0x7b, 0x87, 0x8d, 0x99, 0xa8, 0xa9, 0xab, 0xaf, 0xc0, 0xc2, 0xb5, 0xb7, 0xbf, + 0xb3, 0xa8, 0xac, 0xb8, 0xb2, 0x99, 0x83, 0x86, 0x8e, 0x99, 0xa6, 0xaa, 0xae, 0xb4, 0xb7, 0xb5, + 0xb4, 0xaa, 0x9b, 0x94, 0x8f, 0x90, 0x94, 0x91, 0x88, 0x8d, 0x8f, 0x80, 0x6c, 0x68, 0x65, 0x6a, + 0x7c, 0x81, 0x7d, 0x75, 0x76, 0x6f, 0x62, 0x5b, 0x5b, 0x63, 0x6b, 0x7c, 0x9c, 0x99, 0x76, 0x5b, + 0x49, 0x53, 0x6d, 0x71, 0x72, 0x78, 0x7a, 0x84, 0x90, 0x8b, 0x89, 0x84, 0x78, 0x67, 0x61, 0x63, + 0x5a, 0x48, 0x46, 0x47, 0x40, 0x41, 0x48, 0x56, 0x5b, 0x56, 0x55, 0x62, 0x6d, 0x77, 0x74, 0x6d, + 0x75, 0x88, 0x90, 0x8e, 0x8d, 0x90, 0x8c, 0x7d, 0x75, 0x81, 0x8f, 0x8e, 0x86, 0x80, 0x74, 0x7a, + 0x82, 0x82, 0x72, 0x72, 0x77, 0x71, 0x6a, 0x66, 0x73, 0x73, 0x6f, 0x7b, 0x87, 0x85, 0x7e, 0x85, + 0x98, 0xa0, 0xa8, 0xb1, 0xc0, 0xce, 0xc6, 0xab, 0x92, 0x91, 0x97, 0x9b, 0x9d, 0x9a, 0x9b, 0x99, + 0x86, 0x6c, 0x6a, 0x65, 0x6c, 0x7d, 0x8b, 0x9d, 0x8c, 0x73, 0x6c, 0x6b, 0x6a, 0x71, 0x78, 0x74, + 0x77, 0x8a, 0x9a, 0xaa, 0xbf, 0xbc, 0xa5, 0x9f, 0xa3, 0xa3, 0x9e, 0x9f, 0xa0, 0xa5, 0xb3, 0xa9, + 0x9b, 0x97, 0x91, 0x96, 0x93, 0x8e, 0x84, 0x83, 0x88, 0x84, 0x7c, 0x7a, 0x7e, 0x8c, 0x8a, 0x87, + 0x77, 0x6b, 0x73, 0x78, 0x84, 0x90, 0x83, 0x5f, 0x45, 0x40, 0x44, 0x3d, 0x3d, 0x4b, 0x44, 0x39, + 0x3b, 0x4a, 0x5d, 0x60, 0x64, 0x6b, 0x71, 0x81, 0x7e, 0x70, 0x61, 0x68, 0x73, 0x6e, 0x74, 0x78, + 0x7e, 0x7e, 0x6f, 0x5e, 0x53, 0x56, 0x65, 0x6c, 0x71, 0x69, 0x63, 0x6e, 0x6b, 0x64, 0x5c, 0x58, + 0x5c, 0x5f, 0x77, 0x91, 0x77, 0x5e, 0x73, 0x7d, 0x74, 0x6b, 0x80, 0x93, 0x95, 0x9c, 0xa8, 0xc0, + 0xc8, 0xb1, 0xa6, 0xaa, 0xb8, 0xb7, 0xad, 0x9d, 0x8b, 0x9e, 0xa5, 0x93, 0x79, 0x66, 0x65, 0x71, + 0x82, 0x8c, 0x7e, 0x6a, 0x75, 0x83, 0x89, 0x86, 0x84, 0x77, 0x5a, 0x5a, 0x75, 0x8d, 0x99, 0xa4, + 0xac, 0xa0, 0x8c, 0x88, 0x87, 0x84, 0x79, 0x6a, 0x81, 0x96, 0x8d, 0x76, 0x73, 0x8a, 0x8c, 0x89, + 0x95, 0x8c, 0x82, 0x8b, 0x88, 0x75, 0x6e, 0x80, 0x93, 0x91, 0x91, 0x8e, 0x8b, 0x89, 0x83, 0x76, + 0x62, 0x53, 0x47, 0x3e, 0x3c, 0x48, 0x53, 0x4c, 0x52, 0x55, 0x44, 0x50, 0x67, 0x7d, 0x90, 0x8e, + 0x78, 0x7e, 0xa0, 0xa4, 0x8f, 0x76, 0x7d, 0x82, 0x80, 0x8f, 0x9c, 0xad, 0xa9, 0x98, 0x8d, 0x87, + 0x8c, 0x91, 0x8c, 0x77, 0x79, 0x8f, 0x9d, 0x9e, 0x8d, 0x7c, 0x7c, 0x77, 0x81, 0x89, 0x84, 0x74, + 0x6f, 0x8e, 0xa3, 0x9f, 0x9b, 0x93, 0x92, 0x9d, 0xaf, 0xc5, 0xd9, 0xe3, 0xd1, 0xb2, 0x9d, 0x9b, + 0x98, 0x82, 0x6b, 0x62, 0x77, 0x93, 0x93, 0x74, 0x6a, 0x6f, 0x6c, 0x75, 0x77, 0x68, 0x63, 0x6b, + 0x71, 0x6d, 0x72, 0x73, 0x69, 0x5f, 0x60, 0x6b, 0x7c, 0x85, 0x8c, 0x8b, 0x7e, 0x77, 0x7b, 0x87, + 0x7e, 0x7d, 0x80, 0x87, 0x92, 0x82, 0x78, 0x7b, 0x7b, 0x7e, 0x6d, 0x54, 0x45, 0x4d, 0x6d, 0x77, + 0x5e, 0x53, 0x58, 0x65, 0x6f, 0x70, 0x78, 0x8f, 0x8f, 0x81, 0x78, 0x70, 0x62, 0x4f, 0x37, 0x2e, + 0x42, 0x4f, 0x51, 0x54, 0x4a, 0x43, 0x3e, 0x49, 0x61, 0x62, 0x53, 0x54, 0x74, 0x97, 0x96, 0x96, + 0x95, 0x91, 0x88, 0x82, 0x8a, 0x92, 0xa3, 0xae, 0xa4, 0x96, 0x93, 0x94, 0x92, 0x87, 0x74, 0x75, + 0x84, 0x94, 0x86, 0x79, 0x7b, 0x78, 0x74, 0x6e, 0x71, 0x7a, 0x82, 0x86, 0x99, 0xa4, 0xa9, 0xa9, + 0xa8, 0xaa, 0xb2, 0xb1, 0xb3, 0xc4, 0xc3, 0xac, 0x96, 0x93, 0x9b, 0x89, 0x6d, 0x6a, 0x6d, 0x7b, + 0x92, 0x92, 0x94, 0x96, 0x92, 0x8e, 0x87, 0x7b, 0x79, 0x84, 0x95, 0x95, 0x82, 0x6c, 0x62, 0x5c, + 0x5a, 0x64, 0x74, 0x8f, 0x88, 0x82, 0x8f, 0x88, 0x7d, 0x77, 0x79, 0x85, 0x95, 0x93, 0x90, 0x8a, + 0x77, 0x6f, 0x6a, 0x6c, 0x67, 0x56, 0x45, 0x50, 0x7b, 0x9c, 0xa2, 0x95, 0x8f, 0x8d, 0x86, 0x92, + 0xa0, 0xa7, 0xb3, 0xb1, 0xa5, 0x98, 0x89, 0x7e, 0x6a, 0x54, 0x4b, 0x51, 0x52, 0x4b, 0x4d, 0x5f, + 0x68, 0x63, 0x62, 0x6c, 0x72, 0x75, 0x7d, 0x8f, 0x9a, 0x9e, 0x9d, 0x9a, 0x8b, 0x7a, 0x76, 0x71, + 0x73, 0x7d, 0x8c, 0x95, 0x7e, 0x73, 0x7e, 0x7a, 0x79, 0x7c, 0x7d, 0x76, 0x78, 0x82, 0x89, 0x90, + 0x92, 0x7b, 0x61, 0x5d, 0x6c, 0x80, 0x7b, 0x7c, 0x84, 0x81, 0x74, 0x70, 0x80, 0x91, 0x9f, 0xa4, + 0xa6, 0xa8, 0xa3, 0x9b, 0x9b, 0x99, 0x93, 0x92, 0x8f, 0x82, 0x73, 0x75, 0x82, 0x7a, 0x75, 0x6c, + 0x63, 0x6b, 0x6b, 0x70, 0x77, 0x73, 0x6c, 0x5f, 0x57, 0x57, 0x4e, 0x5c, 0x76, 0x98, 0xac, 0x9b, + 0x91, 0x94, 0x94, 0x93, 0x8f, 0x8f, 0x8e, 0x89, 0x75, 0x6f, 0x7d, 0x90, 0x9a, 0x97, 0x85, 0x6d, + 0x69, 0x73, 0x7e, 0x8f, 0xae, 0xc6, 0xb8, 0xac, 0x9e, 0x8e, 0x8d, 0x89, 0x8b, 0x79, 0x76, 0x7a, + 0x69, 0x58, 0x4c, 0x37, 0x2f, 0x37, 0x3f, 0x3d, 0x2c, 0x3b, 0x57, 0x64, 0x68, 0x59, 0x53, 0x60, + 0x6e, 0x85, 0x95, 0x99, 0x95, 0x91, 0x8e, 0x8a, 0x8c, 0x88, 0x8f, 0x93, 0x8c, 0x9d, 0xa6, 0x98, + 0x95, 0x91, 0x93, 0xa5, 0xa5, 0x92, 0x75, 0x62, 0x64, 0x66, 0x67, 0x5d, 0x48, 0x4d, 0x5d, 0x6c, + 0x7c, 0x78, 0x7d, 0x81, 0x83, 0x87, 0x86, 0x94, 0x9e, 0xb6, 0xc3, 0xb6, 0xa3, 0x94, 0x94, 0x9d, + 0x95, 0x86, 0x7a, 0x6f, 0x5f, 0x64, 0x80, 0x99, 0x92, 0x86, 0x7d, 0x6e, 0x82, 0x96, 0x9f, 0xa5, + 0xad, 0xb4, 0xa8, 0x9f, 0x86, 0x5f, 0x49, 0x56, 0x78, 0x72, 0x61, 0x62, 0x55, 0x49, 0x49, 0x4e, + 0x5a, 0x5a, 0x5a, 0x62, 0x69, 0x76, 0x83, 0x86, 0x8f, 0x88, 0x6b, 0x67, 0x76, 0x8d, 0xa3, 0xbb, + 0xbd, 0xa5, 0x98, 0x90, 0x92, 0x9b, 0xae, 0xb4, 0x9d, 0x8a, 0x8a, 0x91, 0x8b, 0x74, 0x61, 0x61, + 0x61, 0x5c, 0x4c, 0x34, 0x36, 0x3e, 0x44, 0x50, 0x5e, 0x65, 0x5e, 0x66, 0x84, 0x94, 0x9c, 0x8f, + 0x8c, 0x98, 0x91, 0x7b, 0x73, 0x8b, 0x9a, 0x9b, 0x9f, 0xa2, 0x9b, 0x94, 0x91, 0x96, 0xa2, 0x9b, + 0x82, 0x6f, 0x72, 0x7e, 0x82, 0x7d, 0x73, 0x5e, 0x63, 0x83, 0xa1, 0xa5, 0x97, 0xa0, 0x9b, 0x9a, + 0x97, 0x8c, 0x82, 0x92, 0xb4, 0xbc, 0xc0, 0xb3, 0x99, 0x8a, 0x8e, 0x90, 0x87, 0x75, 0x6d, 0x7a, + 0x8b, 0x9d, 0xa3, 0x9c, 0xa4, 0x9f, 0x90, 0x92, 0x9d, 0xa0, 0x91, 0x83, 0x7e, 0x78, 0x72, 0x63, + 0x55, 0x55, 0x78, 0x85, 0x7a, 0x6a, 0x75, 0x89, 0x87, 0x84, 0x85, 0x87, 0x7b, 0x74, 0x74, 0x72, + 0x67, 0x60, 0x6a, 0x78, 0x7d, 0x69, 0x4e, 0x53, 0x6b, 0x7a, 0x90, 0x8a, 0x82, 0x8a, 0x88, 0x77, + 0x82, 0x96, 0x93, 0x7b, 0x61, 0x5c, 0x5e, 0x51, 0x3b, 0x24, 0x29, 0x34, 0x33, 0x31, 0x38, 0x46, + 0x4b, 0x45, 0x4a, 0x54, 0x5e, 0x68, 0x81, 0x94, 0x9e, 0x9a, 0x93, 0x99, 0x9a, 0x8a, 0x6b, 0x6e, + 0x8a, 0x94, 0xa2, 0xa8, 0x92, 0x76, 0x75, 0x7a, 0x7a, 0x78, 0x72, 0x6a, 0x5a, 0x57, 0x5c, 0x64, + 0x6c, 0x60, 0x50, 0x5c, 0x77, 0x8a, 0x85, 0x77, 0x77, 0x82, 0x84, 0x87, 0x91, 0x98, 0xa6, 0xa0, + 0xa1, 0xad, 0xa3, 0x9a, 0x9b, 0x9e, 0x8f, 0x89, 0x89, 0x87, 0x8a, 0x8d, 0x9a, 0x95, 0x8a, 0x92, + 0xa2, 0x9f, 0x96, 0x91, 0x95, 0x92, 0x94, 0x93, 0x9c, 0xa0, 0x93, 0x7e, 0x8b, 0xa1, 0x9e, 0x8c, + 0x79, 0x76, 0x77, 0x75, 0x6d, 0x6b, 0x72, 0x76, 0x74, 0x79, 0x89, 0x8e, 0x84, 0x80, 0x8d, 0x8a, + 0x7e, 0x81, 0x93, 0xa1, 0xa2, 0xa2, 0x98, 0x8c, 0x84, 0x86, 0x8a, 0x9d, 0xa2, 0x99, 0x99, 0x8e, + 0x76, 0x66, 0x67, 0x60, 0x60, 0x63, 0x64, 0x61, 0x54, 0x59, 0x69, 0x6e, 0x77, 0x81, 0x82, 0x88, + 0x92, 0x9a, 0x9f, 0x9d, 0x8d, 0x8d, 0x91, 0x95, 0x93, 0x8a, 0x8c, 0x8a, 0x8c, 0x95, 0x9a, 0x90, + 0x89, 0x7e, 0x78, 0x79, 0x76, 0x74, 0x69, 0x69, 0x75, 0x75, 0x71, 0x7a, 0x7e, 0x6d, 0x62, 0x61, + 0x6a, 0x73, 0x75, 0x75, 0x87, 0x8a, 0x85, 0x87, 0x99, 0xa5, 0xa2, 0xa2, 0xa2, 0x92, 0x88, 0x86, + 0x7c, 0x73, 0x66, 0x65, 0x6b, 0x6c, 0x84, 0x9f, 0x93, 0x86, 0x90, 0x96, 0x90, 0xa2, 0xab, 0x95, + 0x80, 0x6c, 0x64, 0x62, 0x59, 0x4d, 0x4c, 0x5c, 0x5f, 0x5f, 0x64, 0x5c, 0x4a, 0x44, 0x4d, 0x56, + 0x63, 0x68, 0x6c, 0x6c, 0x72, 0x84, 0x82, 0x82, 0x8d, 0x89, 0x72, 0x60, 0x6f, 0x74, 0x72, 0x76, + 0x79, 0x7a, 0x76, 0x7a, 0x87, 0x9b, 0xa9, 0x9f, 0x99, 0x96, 0x90, 0x94, 0x8e, 0x76, 0x62, 0x5a, + 0x59, 0x56, 0x51, 0x54, 0x52, 0x48, 0x4e, 0x5c, 0x69, 0x64, 0x65, 0x70, 0x79, 0x96, 0x9f, 0x91, + 0x92, 0x9b, 0xa0, 0x9e, 0xa2, 0xac, 0xaf, 0xa3, 0x99, 0x8e, 0x8a, 0x83, 0x7c, 0x71, 0x68, 0x69, + 0x66, 0x60, 0x6c, 0x77, 0x79, 0x7b, 0x78, 0x73, 0x7a, 0x98, 0xa3, 0x9c, 0x99, 0x90, 0x92, 0x9a, + 0xa6, 0xad, 0xad, 0xaa, 0xa6, 0xa1, 0xac, 0x9e, 0x86, 0x85, 0x93, 0x9f, 0x90, 0x7b, 0x76, 0x73, + 0x6a, 0x6f, 0x7c, 0x88, 0x95, 0x92, 0x88, 0x86, 0x93, 0x97, 0x95, 0x8a, 0x89, 0x8d, 0x8a, 0x86, + 0x91, 0x9f, 0x9e, 0x87, 0x77, 0x64, 0x4d, 0x59, 0x61, 0x55, 0x50, 0x4d, 0x50, 0x51, 0x54, 0x60, + 0x5b, 0x50, 0x5d, 0x68, 0x6f, 0x68, 0x6a, 0x72, 0x7c, 0x84, 0x8e, 0x99, 0x9c, 0x9c, 0xa1, 0xa9, + 0xb4, 0xb8, 0xb1, 0x9e, 0x88, 0x77, 0x7d, 0x8a, 0x83, 0x72, 0x74, 0x74, 0x6e, 0x6d, 0x6b, 0x64, + 0x6e, 0x77, 0x72, 0x6f, 0x7b, 0x87, 0x87, 0x83, 0x87, 0x86, 0x85, 0x8b, 0x96, 0xa2, 0x9d, 0x94, + 0x89, 0x7c, 0x72, 0x67, 0x63, 0x65, 0x6c, 0x74, 0x75, 0x7a, 0x7a, 0x72, 0x6a, 0x6b, 0x75, 0x8b, + 0x94, 0x7d, 0x6a, 0x6a, 0x6f, 0x82, 0x85, 0x73, 0x6e, 0x74, 0x78, 0x7e, 0x96, 0xa5, 0x9d, 0x8a, + 0x7d, 0x84, 0x81, 0x87, 0x96, 0x98, 0x93, 0x90, 0x97, 0x97, 0x8d, 0x83, 0x7c, 0x7d, 0x83, 0x83, + 0x84, 0x84, 0x82, 0x80, 0x89, 0x88, 0x89, 0x8b, 0x87, 0x84, 0x85, 0x92, 0x9e, 0xa4, 0xa9, 0x92, + 0x68, 0x55, 0x65, 0x7d, 0x7d, 0x7b, 0x80, 0x80, 0x74, 0x70, 0x8f, 0x9a, 0xa1, 0xa2, 0x9d, 0x96, + 0x89, 0x86, 0x89, 0x7a, 0x6c, 0x77, 0x82, 0x84, 0x88, 0x95, 0x9b, 0x88, 0x79, 0x6f, 0x5f, 0x53, + 0x52, 0x54, 0x53, 0x4d, 0x50, 0x54, 0x4f, 0x48, 0x42, 0x3b, 0x48, 0x6e, 0x84, 0x72, 0x60, 0x5f, + 0x69, 0x7e, 0x84, 0x95, 0xa1, 0xa2, 0xa0, 0xa1, 0xae, 0xae, 0xa2, 0x90, 0x74, 0x62, 0x63, 0x6b, + 0x6b, 0x5f, 0x64, 0x6e, 0x71, 0x71, 0x66, 0x63, 0x65, 0x6f, 0x79, 0x7b, 0x72, 0x6a, 0x64, 0x68, + 0x76, 0x73, 0x6d, 0x6b, 0x71, 0x71, 0x74, 0x84, 0x8d, 0x92, 0x91, 0x78, 0x76, 0x82, 0x8f, 0x93, + 0x8d, 0x89, 0x81, 0x81, 0x73, 0x63, 0x75, 0x93, 0xa3, 0x9d, 0x98, 0x94, 0x88, 0x8b, 0x98, 0x90, + 0x8d, 0xa0, 0xad, 0xae, 0xab, 0xb3, 0xb8, 0xa5, 0x97, 0x8e, 0x7b, 0x6e, 0x6b, 0x73, 0x75, 0x70, + 0x6e, 0x6a, 0x61, 0x56, 0x5c, 0x72, 0x8b, 0x9e, 0x9e, 0x83, 0x6c, 0x60, 0x71, 0x7c, 0x74, 0x80, + 0x94, 0x96, 0x8d, 0x96, 0xb5, 0xc3, 0xb2, 0x9b, 0x80, 0x72, 0x73, 0x77, 0x77, 0x6f, 0x71, 0x75, + 0x78, 0x70, 0x5e, 0x56, 0x4f, 0x53, 0x64, 0x67, 0x5f, 0x5a, 0x60, 0x6e, 0x7c, 0x90, 0xa4, 0xa7, + 0x9d, 0x97, 0xa6, 0xb7, 0xb5, 0xb3, 0xa0, 0x78, 0x71, 0x72, 0x70, 0x71, 0x76, 0x77, 0x75, 0x76, + 0x6c, 0x62, 0x7e, 0xa1, 0xa9, 0xa2, 0x93, 0x88, 0x7c, 0x85, 0x93, 0x9b, 0x9f, 0x90, 0x91, 0x95, + 0x8e, 0x8e, 0x8e, 0x80, 0x77, 0x76, 0x7e, 0x92, 0x90, 0x89, 0x8f, 0x98, 0x9b, 0x97, 0x90, 0x7c, + 0x7c, 0x97, 0xad, 0xb2, 0xa8, 0x90, 0x75, 0x6b, 0x7d, 0x85, 0x83, 0x85, 0x86, 0x7c, 0x6e, 0x70, + 0x8d, 0x97, 0x85, 0x79, 0x72, 0x64, 0x54, 0x53, 0x5b, 0x64, 0x63, 0x64, 0x67, 0x64, 0x5c, 0x69, + 0x82, 0x87, 0x81, 0x75, 0x6d, 0x5e, 0x60, 0x6b, 0x6a, 0x7b, 0x89, 0x82, 0x72, 0x6b, 0x7b, 0x82, + 0x77, 0x77, 0x69, 0x52, 0x4c, 0x52, 0x51, 0x4e, 0x4d, 0x4c, 0x4e, 0x4d, 0x4b, 0x4e, 0x62, 0x6f, + 0x72, 0x6e, 0x66, 0x57, 0x4b, 0x59, 0x6a, 0x7e, 0xa5, 0xb0, 0x9f, 0x90, 0x8c, 0x90, 0x85, 0x7b, + 0x77, 0x72, 0x7b, 0x8a, 0x8d, 0x7e, 0x84, 0x8f, 0x8b, 0x86, 0x77, 0x62, 0x65, 0x7e, 0x9b, 0xaa, + 0x9e, 0x82, 0x71, 0x6e, 0x7a, 0x8c, 0x99, 0x9a, 0x83, 0x7c, 0x8c, 0x9c, 0xa8, 0xaf, 0xa5, 0x95, + 0x99, 0xa2, 0x9a, 0x84, 0x77, 0x81, 0x8c, 0x8d, 0x8a, 0x78, 0x68, 0x73, 0x87, 0x92, 0x90, 0x92, + 0x93, 0x96, 0x9d, 0x9d, 0x99, 0xaa, 0xb3, 0xaa, 0xa2, 0x9f, 0xa0, 0x9d, 0x96, 0x97, 0x9b, 0x8e, + 0x74, 0x60, 0x5a, 0x62, 0x60, 0x5a, 0x58, 0x57, 0x57, 0x72, 0xa1, 0xb5, 0x9f, 0x82, 0x6b, 0x5f, + 0x56, 0x5e, 0x6a, 0x76, 0x8d, 0x8f, 0x81, 0x7c, 0x86, 0x87, 0x82, 0x7e, 0x7b, 0x7d, 0x86, 0x91, + 0x8e, 0x79, 0x76, 0x73, 0x69, 0x61, 0x57, 0x5b, 0x6c, 0x75, 0x7a, 0x8a, 0x8a, 0x6e, 0x5b, 0x57, + 0x67, 0x7a, 0x88, 0x9a, 0x92, 0x84, 0x8b, 0x9f, 0xad, 0xa7, 0x97, 0x88, 0x82, 0x81, 0x73, 0x63, + 0x6d, 0x89, 0x91, 0x90, 0x8d, 0x81, 0x77, 0x80, 0x96, 0xa2, 0x9d, 0x90, 0x8d, 0x94, 0x93, 0x90, + 0x98, 0xa0, 0x89, 0x6a, 0x6d, 0x81, 0x84, 0x80, 0x7d, 0x90, 0x9e, 0x9f, 0xa6, 0x99, 0x89, 0x88, + 0x7b, 0x77, 0x76, 0x73, 0x6e, 0x80, 0x9d, 0xaa, 0xa2, 0x94, 0x86, 0x7b, 0x72, 0x72, 0x7b, 0x88, + 0x93, 0x8d, 0x81, 0x80, 0x77, 0x66, 0x5e, 0x58, 0x5c, 0x6a, 0x70, 0x66, 0x50, 0x4a, 0x5d, 0x66, + 0x5a, 0x52, 0x4e, 0x58, 0x73, 0x96, 0x9c, 0x9a, 0x87, 0x68, 0x5b, 0x53, 0x59, 0x58, 0x57, 0x5f, + 0x55, 0x52, 0x65, 0x7b, 0x82, 0x7d, 0x75, 0x70, 0x6b, 0x68, 0x62, 0x63, 0x70, 0x7c, 0x7e, 0x78, + 0x6d, 0x5f, 0x61, 0x69, 0x6e, 0x73, 0x75, 0x72, 0x7a, 0x82, 0x80, 0x84, 0x9d, 0xb7, 0xbb, 0x9f, + 0x94, 0x9d, 0xa6, 0xa7, 0x9c, 0xaa, 0xae, 0xa3, 0x9b, 0x87, 0x7d, 0x76, 0x71, 0x72, 0x73, 0x70, + 0x72, 0x84, 0x9f, 0xb1, 0xa8, 0x91, 0x7c, 0x75, 0x76, 0x81, 0x8e, 0xa5, 0xa8, 0x95, 0x84, 0x8c, + 0x92, 0x85, 0x70, 0x67, 0x6f, 0x7a, 0x88, 0x8c, 0x6d, 0x59, 0x5d, 0x67, 0x64, 0x4f, 0x4b, 0x5b, + 0x75, 0x93, 0xa2, 0xa7, 0x94, 0x84, 0x82, 0x83, 0x86, 0x83, 0x83, 0x88, 0x90, 0x91, 0xa1, 0xa8, + 0x9f, 0x8f, 0x83, 0x83, 0x80, 0x73, 0x5d, 0x5d, 0x6b, 0x7a, 0x83, 0x7e, 0x6e, 0x67, 0x70, 0x88, + 0x9f, 0x98, 0x80, 0x76, 0x86, 0x8a, 0x75, 0x6d, 0x81, 0x91, 0x8b, 0x80, 0x7e, 0x87, 0x8b, 0x8c, + 0x8a, 0x96, 0x92, 0x7e, 0x6b, 0x5f, 0x5e, 0x5a, 0x51, 0x56, 0x54, 0x49, 0x54, 0x6f, 0x82, 0x81, + 0x78, 0x6c, 0x6a, 0x72, 0x79, 0x82, 0x91, 0xa8, 0xb6, 0xbf, 0xaa, 0x94, 0x97, 0x99, 0x89, 0x7c, + 0x87, 0x90, 0x97, 0x8f, 0x77, 0x68, 0x6b, 0x76, 0x77, 0x6e, 0x72, 0x7e, 0x95, 0xad, 0xbd, 0xc7, + 0xbb, 0xac, 0x9e, 0x9c, 0x98, 0x94, 0x95, 0x97, 0x91, 0x8b, 0x9e, 0xb2, 0xac, 0x9c, 0x97, 0x94, + 0x8f, 0x93, 0x95, 0x81, 0x78, 0x85, 0x92, 0x80, 0x61, 0x62, 0x6f, 0x85, 0x91, 0x90, 0x7a, 0x6e, + 0x77, 0x7d, 0x75, 0x6d, 0x72, 0x6f, 0x67, 0x61, 0x5f, 0x6b, 0x6a, 0x62, 0x6f, 0x89, 0x87, 0x76, + 0x63, 0x43, 0x34, 0x3b, 0x46, 0x52, 0x49, 0x41, 0x4f, 0x6e, 0x8d, 0x98, 0x7d, 0x62, 0x64, 0x70, + 0x71, 0x69, 0x6c, 0x79, 0x7c, 0x7b, 0x76, 0x69, 0x68, 0x67, 0x6b, 0x76, 0x82, 0x89, 0x85, 0x76, + 0x61, 0x61, 0x6f, 0x72, 0x68, 0x60, 0x65, 0x73, 0x88, 0x92, 0x8f, 0x8c, 0x80, 0x7a, 0x79, 0x7c, + 0x77, 0x75, 0x7d, 0x98, 0xa4, 0x91, 0x9b, 0xaf, 0xa6, 0x8e, 0x88, 0x89, 0x87, 0x89, 0x86, 0x7e, + 0x76, 0x72, 0x72, 0x6b, 0x61, 0x64, 0x6f, 0x7a, 0x87, 0x8c, 0x86, 0x8a, 0x8f, 0x90, 0x8a, 0x84, + 0x8b, 0x90, 0x8e, 0x84, 0x7a, 0x85, 0x8c, 0x8d, 0x9c, 0xa8, 0x9b, 0x89, 0x82, 0x71, 0x58, 0x57, + 0x60, 0x61, 0x4d, 0x48, 0x5e, 0x77, 0x8b, 0x90, 0x8b, 0x78, 0x75, 0x83, 0x98, 0xa2, 0xa1, 0x9d, + 0x97, 0x97, 0x95, 0x98, 0x98, 0x86, 0x81, 0x8b, 0x8f, 0x8d, 0x84, 0x6c, 0x48, 0x47, 0x5d, 0x67, + 0x66, 0x6a, 0x6b, 0x78, 0x8b, 0xa6, 0xbb, 0xac, 0x92, 0x8b, 0x81, 0x71, 0x70, 0x68, 0x73, 0x86, + 0x8b, 0x98, 0xa0, 0x96, 0x8f, 0x91, 0x9b, 0xa8, 0x9f, 0x92, 0x8c, 0x87, 0x90, 0x8f, 0x82, 0x7d, + 0x78, 0x77, 0x81, 0x84, 0x85, 0x7a, 0x75, 0x7c, 0x82, 0x83, 0x82, 0x7e, 0x7d, 0x82, 0x8e, 0x8d, + 0x89, 0x8b, 0x8a, 0x85, 0x88, 0x92, 0x82, 0x6e, 0x5f, 0x50, 0x51, 0x52, 0x55, 0x5e, 0x6a, 0x7b, + 0x91, 0x98, 0x98, 0x98, 0x9f, 0xaa, 0xa4, 0x9c, 0xa4, 0xa4, 0x9b, 0x97, 0x98, 0x8e, 0x7c, 0x80, + 0x7d, 0x76, 0x76, 0x7b, 0x83, 0x7e, 0x74, 0x72, 0x60, 0x5a, 0x68, 0x6d, 0x64, 0x5b, 0x5c, 0x67, + 0x75, 0x90, 0xa7, 0xa3, 0x8b, 0x75, 0x6a, 0x6c, 0x71, 0x6c, 0x66, 0x67, 0x65, 0x7d, 0x97, 0x86, + 0x73, 0x6c, 0x77, 0x82, 0x7b, 0x72, 0x62, 0x52, 0x57, 0x5f, 0x5e, 0x62, 0x60, 0x5d, 0x63, 0x6b, + 0x84, 0x7d, 0x70, 0x74, 0x74, 0x75, 0x6d, 0x6c, 0x6e, 0x75, 0x86, 0x92, 0x9d, 0x95, 0x8b, 0x95, + 0xab, 0xba, 0xaa, 0x8d, 0x72, 0x69, 0x73, 0x79, 0x6f, 0x68, 0x6a, 0x72, 0x7e, 0x83, 0x84, 0x7e, + 0x75, 0x7c, 0x85, 0x87, 0x8f, 0x92, 0x92, 0x90, 0x97, 0xa9, 0xa8, 0xa9, 0x99, 0x8b, 0x86, 0x7c, + 0x72, 0x68, 0x62, 0x60, 0x61, 0x66, 0x61, 0x56, 0x5c, 0x6a, 0x6f, 0x76, 0x7a, 0x84, 0x92, 0x98, + 0x8e, 0x7e, 0x71, 0x74, 0x80, 0x79, 0x70, 0x74, 0x72, 0x87, 0x99, 0x8a, 0x82, 0x7b, 0x84, 0x88, + 0x83, 0x7e, 0x87, 0x86, 0x87, 0x86, 0x83, 0x85, 0x76, 0x6d, 0x6c, 0x79, 0x90, 0x96, 0x90, 0x8e, + 0x8d, 0x94, 0x9e, 0xa9, 0xa3, 0x96, 0x96, 0xa1, 0xb8, 0xaf, 0xa0, 0xa0, 0xa0, 0x9b, 0x85, 0x6e, + 0x55, 0x4b, 0x51, 0x54, 0x4c, 0x4f, 0x59, 0x64, 0x6c, 0x73, 0x83, 0x8e, 0x87, 0x90, 0x97, 0x91, + 0x8f, 0x89, 0x82, 0x72, 0x7a, 0x8a, 0x96, 0x93, 0x76, 0x6f, 0x78, 0x82, 0x84, 0x82, 0x73, 0x67, + 0x71, 0x88, 0x87, 0x75, 0x6e, 0x69, 0x67, 0x69, 0x76, 0x7e, 0x7b, 0x76, 0x6f, 0x69, 0x68, 0x6a, + 0x6c, 0x5d, 0x57, 0x71, 0x8c, 0xa7, 0xb0, 0xa1, 0x9a, 0x92, 0x88, 0x82, 0x7e, 0x80, 0x87, 0x92, + 0x8f, 0x7d, 0x76, 0x7e, 0x82, 0x85, 0x8b, 0x8f, 0x96, 0xa5, 0xb1, 0xb2, 0xad, 0xa6, 0x9f, 0x97, + 0x82, 0x7b, 0x7b, 0x83, 0x98, 0x98, 0x98, 0x9e, 0xa2, 0x95, 0x79, 0x6b, 0x68, 0x70, 0x71, 0x65, + 0x5b, 0x65, 0x6f, 0x76, 0x7a, 0x7a, 0x84, 0x86, 0x83, 0x81, 0x7b, 0x79, 0x83, 0x8f, 0x8c, 0x83, + 0x80, 0x85, 0x9c, 0xa3, 0x92, 0x84, 0x82, 0x7b, 0x6b, 0x64, 0x61, 0x5b, 0x5c, 0x66, 0x60, 0x5d, + 0x62, 0x63, 0x68, 0x72, 0x83, 0x8a, 0x8d, 0x88, 0x7d, 0x79, 0x81, 0x87, 0x77, 0x5a, 0x55, 0x6f, + 0x90, 0xa5, 0x98, 0x88, 0x7b, 0x78, 0x7c, 0x7d, 0x7b, 0x6f, 0x74, 0x8b, 0x90, 0x85, 0x7b, 0x73, + 0x6b, 0x6a, 0x68, 0x6b, 0x6c, 0x63, 0x6a, 0x74, 0x7e, 0x8a, 0x8b, 0x81, 0x76, 0x78, 0x81, 0x96, + 0xa0, 0xa1, 0xa4, 0x9c, 0x91, 0x76, 0x58, 0x51, 0x5e, 0x67, 0x61, 0x48, 0x3f, 0x49, 0x5e, 0x71, + 0x7e, 0x80, 0x75, 0x73, 0x81, 0x90, 0x97, 0x99, 0x99, 0x91, 0x85, 0x78, 0x74, 0x74, 0x7a, 0x80, + 0x7a, 0x7e, 0x86, 0x7c, 0x6f, 0x6c, 0x6f, 0x73, 0x7c, 0x80, 0x7c, 0x7d, 0x7d, 0x78, 0x7d, 0x8c, + 0x9b, 0xa3, 0xa1, 0x9a, 0x8f, 0x89, 0x8b, 0x8c, 0x7e, 0x6e, 0x71, 0x83, 0xa4, 0xb7, 0xb0, 0xa9, + 0x98, 0x82, 0x72, 0x6e, 0x6e, 0x6a, 0x6e, 0x76, 0x7b, 0x77, 0x79, 0x7c, 0x7a, 0x7e, 0x80, 0x7d, + 0x81, 0x86, 0x8f, 0x98, 0xa1, 0x9f, 0x8e, 0x7b, 0x73, 0x80, 0x8a, 0x92, 0x97, 0x99, 0x96, 0x86, + 0x80, 0x70, 0x69, 0x6a, 0x6d, 0x79, 0x78, 0x6c, 0x6c, 0x72, 0x7a, 0x7e, 0x85, 0x81, 0x75, 0x69, + 0x6e, 0x81, 0x8c, 0x93, 0xa0, 0xa0, 0x96, 0x8e, 0x8e, 0x97, 0xa6, 0xa5, 0xa4, 0xa6, 0x9d, 0x86, + 0x73, 0x79, 0x8c, 0x91, 0x86, 0x7e, 0x7d, 0x71, 0x69, 0x72, 0x81, 0x94, 0x94, 0x90, 0x9c, 0xa5, + 0xa0, 0x9b, 0x96, 0x8d, 0x79, 0x66, 0x70, 0x7e, 0x87, 0x8f, 0x8c, 0x8e, 0x8b, 0x79, 0x69, 0x65, + 0x67, 0x66, 0x73, 0x81, 0x7d, 0x77, 0x76, 0x76, 0x6c, 0x65, 0x6f, 0x7b, 0x7e, 0x7a, 0x84, 0x87, + 0x86, 0x83, 0x77, 0x6e, 0x6d, 0x71, 0x6f, 0x7c, 0x8c, 0x8d, 0x89, 0x79, 0x70, 0x5e, 0x4a, 0x48, + 0x49, 0x45, 0x3a, 0x3c, 0x4c, 0x5f, 0x6f, 0x78, 0x7e, 0x7b, 0x6d, 0x70, 0x7d, 0x89, 0x8d, 0x8e, + 0x91, 0x88, 0x75, 0x76, 0x8b, 0x92, 0x91, 0x8e, 0x8a, 0x8a, 0x7e, 0x70, 0x68, 0x6f, 0x76, 0x77, + 0x74, 0x75, 0x7a, 0x76, 0x74, 0x7e, 0x8e, 0x95, 0x8d, 0x84, 0x8d, 0x87, 0x79, 0x78, 0x81, 0x83, + 0x7a, 0x72, 0x78, 0x77, 0x85, 0x97, 0x94, 0x97, 0x8d, 0x6c, 0x4f, 0x4e, 0x60, 0x6f, 0x77, 0x75, + 0x72, 0x69, 0x66, 0x70, 0x70, 0x70, 0x72, 0x70, 0x73, 0x7d, 0x8f, 0x9a, 0x97, 0x8d, 0x82, 0x7a, + 0x77, 0x7a, 0x7b, 0x83, 0x84, 0x88, 0x92, 0x98, 0x9f, 0x91, 0x82, 0x83, 0x83, 0x92, 0x9b, 0x99, + 0x9c, 0x99, 0x92, 0x8c, 0x93, 0xa0, 0x9e, 0x99, 0x9d, 0xa2, 0x99, 0x95, 0x9b, 0x9b, 0x91, 0x8d, + 0x92, 0x98, 0x98, 0x96, 0x9b, 0x98, 0x88, 0x76, 0x74, 0x78, 0x7a, 0x71, 0x5f, 0x50, 0x4c, 0x51, + 0x61, 0x69, 0x6b, 0x68, 0x5e, 0x5e, 0x85, 0x8a, 0x77, 0x6f, 0x6c, 0x68, 0x5c, 0x5b, 0x71, 0x76, + 0x7b, 0x88, 0x95, 0x98, 0x89, 0x79, 0x6d, 0x6c, 0x71, 0x77, 0x80, 0x83, 0x84, 0x84, 0x8a, 0x95, + 0x90, 0x8d, 0x89, 0x87, 0x89, 0x8c, 0x8c, 0x91, 0x97, 0x97, 0x91, 0x88, 0x86, 0x88, 0x88, 0x9c, + 0xa1, 0x9f, 0x9d, 0x95, 0x89, 0x6c, 0x63, 0x6a, 0x6d, 0x75, 0x7c, 0x78, 0x76, 0x7b, 0x83, 0x89, + 0x8d, 0x8c, 0x86, 0x87, 0x8f, 0x95, 0x97, 0x91, 0x95, 0x94, 0x88, 0x84, 0x85, 0x8a, 0x7d, 0x6c, + 0x71, 0x73, 0x6f, 0x63, 0x61, 0x65, 0x69, 0x63, 0x6a, 0x6f, 0x6d, 0x73, 0x74, 0x66, 0x5f, 0x61, + 0x6a, 0x76, 0x8d, 0x93, 0x8a, 0x7d, 0x7b, 0x85, 0x7e, 0x6d, 0x6f, 0x74, 0x7c, 0x82, 0x8b, 0x8f, + 0x82, 0x74, 0x68, 0x67, 0x67, 0x69, 0x6f, 0x6b, 0x6a, 0x77, 0x89, 0x92, 0x88, 0x80, 0x82, 0x85, + 0x8a, 0xa5, 0xb2, 0xad, 0xa2, 0x8f, 0x80, 0x78, 0x7e, 0x8a, 0x8a, 0x8d, 0x8e, 0x8b, 0x82, 0x7d, + 0x7e, 0x69, 0x5c, 0x60, 0x66, 0x69, 0x6a, 0x68, 0x74, 0x7d, 0x80, 0x80, 0x80, 0x79, 0x73, 0x72, + 0x70, 0x6e, 0x72, 0x76, 0x86, 0x8b, 0x88, 0x8e, 0x8f, 0x96, 0xa3, 0x9e, 0x98, 0x8f, 0x7c, 0x69, + 0x66, 0x74, 0x74, 0x60, 0x57, 0x5e, 0x67, 0x6b, 0x69, 0x65, 0x60, 0x5a, 0x63, 0x73, 0x85, 0x87, + 0x89, 0x89, 0x87, 0x90, 0x8d, 0x82, 0x85, 0x87, 0x93, 0x8f, 0x8b, 0x8d, 0x81, 0x75, 0x67, 0x61, + 0x63, 0x65, 0x73, 0x91, 0x9b, 0x9d, 0xa0, 0x97, 0x84, 0x79, 0x84, 0x8e, 0x8d, 0x8d, 0x99, 0xa2, + 0x98, 0x89, 0x8c, 0x8a, 0x8a, 0x8f, 0x92, 0x96, 0x8d, 0x8c, 0x91, 0x8c, 0x8d, 0x7c, 0x71, 0x6d, + 0x69, 0x69, 0x5f, 0x5f, 0x70, 0x79, 0x7d, 0x7a, 0x73, 0x6d, 0x69, 0x6f, 0x85, 0x88, 0x7c, 0x74, + 0x79, 0x7c, 0x79, 0x8a, 0x93, 0x95, 0x8c, 0x87, 0x8c, 0x84, 0x7a, 0x7a, 0x78, 0x79, 0x7b, 0x6f, + 0x6a, 0x6f, 0x7c, 0x8a, 0x88, 0x82, 0x79, 0x75, 0x78, 0x7e, 0x8a, 0x7d, 0x76, 0x7b, 0x83, 0x8c, + 0x81, 0x73, 0x76, 0x7e, 0x9e, 0xb6, 0xb0, 0xa0, 0x84, 0x75, 0x6f, 0x66, 0x6f, 0x78, 0x79, 0x7e, + 0x8e, 0x97, 0x98, 0x90, 0x86, 0x7d, 0x7a, 0x88, 0x92, 0x96, 0x9f, 0xa8, 0xa6, 0x9c, 0x9b, 0x94, + 0x93, 0x92, 0x91, 0x8f, 0x79, 0x76, 0x80, 0x7e, 0x83, 0x75, 0x5f, 0x5a, 0x5e, 0x69, 0x7b, 0x7e, + 0x74, 0x6e, 0x76, 0x7e, 0x78, 0x79, 0x78, 0x73, 0x75, 0x7e, 0x84, 0x8a, 0x96, 0x99, 0x90, 0x93, + 0x9f, 0xa2, 0x97, 0x8f, 0x94, 0x8f, 0x83, 0x83, 0x82, 0x79, 0x6f, 0x61, 0x5f, 0x63, 0x71, 0x7c, + 0x79, 0x70, 0x69, 0x62, 0x67, 0x76, 0x93, 0x9c, 0x8f, 0x82, 0x7c, 0x86, 0x7b, 0x6f, 0x74, 0x81, + 0x8c, 0x88, 0x80, 0x74, 0x64, 0x5a, 0x5d, 0x57, 0x5f, 0x71, 0x73, 0x77, 0x88, 0x94, 0x93, 0x83, + 0x79, 0x72, 0x6a, 0x66, 0x69, 0x6e, 0x6e, 0x76, 0x77, 0x76, 0x7c, 0x78, 0x76, 0x7a, 0x83, 0x8d, + 0x8f, 0x86, 0x79, 0x6e, 0x74, 0x6a, 0x57, 0x5c, 0x5b, 0x52, 0x51, 0x57, 0x62, 0x6e, 0x75, 0x79, + 0x6c, 0x68, 0x6c, 0x6d, 0x7b, 0x92, 0x9d, 0xa0, 0xa6, 0xa6, 0xa6, 0xa5, 0xa1, 0xa6, 0x9d, 0x8a, + 0x87, 0x8a, 0x8a, 0x8d, 0x8a, 0x82, 0x7e, 0x77, 0x85, 0x9c, 0x99, 0x88, 0x74, 0x6e, 0x6b, 0x68, + 0x73, 0x7c, 0x88, 0x86, 0x83, 0x86, 0x8b, 0x91, 0x85, 0x73, 0x7d, 0x9b, 0xa3, 0x9e, 0x96, 0x8f, + 0x80, 0x6e, 0x71, 0x75, 0x72, 0x71, 0x6f, 0x72, 0x77, 0x81, 0x85, 0x7b, 0x77, 0x6e, 0x67, 0x69, + 0x7d, 0x9a, 0xab, 0xa0, 0x8c, 0x87, 0x8d, 0x88, 0x81, 0x80, 0x7e, 0x78, 0x71, 0x71, 0x74, 0x70, + 0x74, 0x71, 0x65, 0x6b, 0x6e, 0x67, 0x69, 0x6f, 0x84, 0x93, 0x90, 0x8e, 0x83, 0x74, 0x6a, 0x73, + 0x83, 0x84, 0x89, 0x96, 0xa3, 0xa0, 0xa0, 0xa1, 0xa5, 0xb3, 0xb8, 0xb5, 0x9f, 0x8b, 0x88, 0x8c, + 0x8c, 0x89, 0x84, 0x73, 0x74, 0x7b, 0x7d, 0x82, 0x78, 0x73, 0x75, 0x72, 0x79, 0x83, 0x94, 0x9a, + 0x9b, 0xa3, 0xa7, 0xa3, 0x94, 0x89, 0x8b, 0x99, 0x9d, 0x8c, 0x77, 0x6c, 0x61, 0x5c, 0x65, 0x6c, + 0x6c, 0x69, 0x6e, 0x84, 0x9b, 0x97, 0x91, 0x88, 0x82, 0x79, 0x74, 0x77, 0x82, 0x8d, 0x8f, 0x8f, + 0x8f, 0x8b, 0x88, 0x7b, 0x70, 0x78, 0x81, 0x7b, 0x7c, 0x80, 0x7c, 0x76, 0x78, 0x72, 0x6c, 0x5f, + 0x4f, 0x4f, 0x54, 0x52, 0x68, 0x77, 0x74, 0x6e, 0x64, 0x5a, 0x59, 0x70, 0x8d, 0x9a, 0x8e, 0x88, + 0x88, 0x86, 0x89, 0x8a, 0x8e, 0x8d, 0x7a, 0x70, 0x6b, 0x61, 0x61, 0x68, 0x6d, 0x6c, 0x65, 0x59, + 0x5b, 0x64, 0x6d, 0x7b, 0x70, 0x64, 0x63, 0x60, 0x5b, 0x6a, 0x89, 0x8c, 0x7b, 0x79, 0x7b, 0x79, + 0x71, 0x6f, 0x7b, 0x92, 0x9c, 0x99, 0x9a, 0x84, 0x6d, 0x6b, 0x74, 0x7e, 0x7c, 0x70, 0x69, 0x73, + 0x82, 0x90, 0x93, 0x87, 0x82, 0x78, 0x70, 0x7b, 0x95, 0xa8, 0xad, 0xac, 0xaf, 0xa3, 0x92, 0x83, + 0x80, 0x8b, 0x92, 0x91, 0x8f, 0x8c, 0x83, 0x84, 0x97, 0x97, 0x8f, 0x76, 0x62, 0x69, 0x77, 0x80, + 0x84, 0x7e, 0x6b, 0x63, 0x5f, 0x5b, 0x64, 0x73, 0x82, 0x8b, 0x8f, 0x96, 0x96, 0x95, 0x93, 0x96, + 0x9f, 0x9f, 0x92, 0x8b, 0x8c, 0x89, 0x85, 0x85, 0x84, 0x80, 0x6c, 0x55, 0x57, 0x5a, 0x58, 0x63, + 0x60, 0x5e, 0x5d, 0x58, 0x59, 0x74, 0x9a, 0xa3, 0xa0, 0x8f, 0x87, 0x7e, 0x77, 0x78, 0x89, 0x99, + 0x8e, 0x7e, 0x84, 0x83, 0x76, 0x7a, 0x86, 0x8b, 0x85, 0x75, 0x78, 0x88, 0x91, 0x9f, 0xa0, 0x8f, + 0x7c, 0x6a, 0x65, 0x77, 0x8a, 0x95, 0x99, 0x95, 0x9b, 0x94, 0x8c, 0x88, 0x8d, 0x98, 0x9f, 0xa0, + 0xa0, 0xa9, 0x98, 0x90, 0xa1, 0xa0, 0x91, 0x76, 0x5f, 0x61, 0x65, 0x6f, 0x82, 0x83, 0x6f, 0x63, + 0x5c, 0x5d, 0x6e, 0x84, 0x8f, 0x94, 0x9c, 0xa6, 0x9d, 0x91, 0x8a, 0x8f, 0x97, 0x8e, 0x7a, 0x6d, + 0x66, 0x64, 0x65, 0x6c, 0x6b, 0x66, 0x53, 0x46, 0x54, 0x65, 0x7c, 0x7d, 0x6d, 0x63, 0x60, 0x60, + 0x61, 0x76, 0x8e, 0x88, 0x7e, 0x7b, 0x79, 0x73, 0x71, 0x74, 0x86, 0x92, 0x84, 0x79, 0x78, 0x77, + 0x71, 0x70, 0x76, 0x79, 0x73, 0x6a, 0x6c, 0x77, 0x81, 0x86, 0x89, 0x83, 0x77, 0x6c, 0x6f, 0x80, + 0x9b, 0xa7, 0xac, 0xb8, 0xa9, 0x90, 0x88, 0x8e, 0x97, 0x9e, 0x98, 0x86, 0x7e, 0x85, 0x82, 0x85, + 0x94, 0x90, 0x82, 0x72, 0x68, 0x74, 0x7c, 0x83, 0x92, 0x8d, 0x78, 0x6a, 0x62, 0x65, 0x6e, 0x79, + 0x7d, 0x7d, 0x7a, 0x82, 0x83, 0x80, 0x84, 0x8e, 0x99, 0x98, 0x8b, 0x8e, 0xa0, 0x94, 0x83, 0x81, + 0x82, 0x7d, 0x63, 0x4a, 0x50, 0x60, 0x72, 0x7b, 0x70, 0x64, 0x5c, 0x5b, 0x62, 0x87, 0xad, 0xa5, + 0x92, 0x8d, 0x89, 0x80, 0x77, 0x76, 0x86, 0x88, 0x78, 0x72, 0x6f, 0x66, 0x60, 0x5e, 0x65, 0x70, + 0x6e, 0x66, 0x68, 0x74, 0x8c, 0x9d, 0x90, 0x79, 0x67, 0x61, 0x65, 0x6d, 0x79, 0x7c, 0x7b, 0x88, + 0x8c, 0x7e, 0x79, 0x80, 0x87, 0x90, 0x97, 0x99, 0x98, 0x91, 0x88, 0x8c, 0x95, 0x8c, 0x81, 0x6f, + 0x5c, 0x5f, 0x69, 0x6e, 0x6d, 0x68, 0x5e, 0x52, 0x53, 0x5a, 0x69, 0x7a, 0x84, 0x9c, 0xa9, 0x9a, + 0x8c, 0x89, 0x90, 0x95, 0x95, 0x8d, 0x80, 0x7e, 0x89, 0x8b, 0x7d, 0x74, 0x75, 0x79, 0x68, 0x5d, + 0x72, 0x82, 0x83, 0x82, 0x7b, 0x75, 0x6f, 0x6e, 0x75, 0x8c, 0x9f, 0x9b, 0x95, 0x8b, 0x8b, 0x94, + 0x98, 0x9b, 0xa7, 0xa9, 0xa0, 0x9e, 0xb0, 0xb0, 0x95, 0x7d, 0x78, 0x8a, 0x83, 0x6b, 0x6b, 0x73, + 0x7d, 0x8d, 0x96, 0x8b, 0x76, 0x6e, 0x76, 0x85, 0x98, 0xa1, 0x9c, 0x9e, 0xa0, 0x96, 0x9a, 0x9a, + 0x94, 0x93, 0x8a, 0x83, 0x84, 0x79, 0x68, 0x72, 0x80, 0x81, 0x80, 0x6e, 0x69, 0x73, 0x81, 0x98, + 0x9e, 0x86, 0x69, 0x5d, 0x63, 0x6a, 0x6f, 0x72, 0x74, 0x83, 0x93, 0x9d, 0x9b, 0x97, 0x92, 0x9a, + 0xa2, 0xa2, 0xa3, 0xa1, 0x98, 0x91, 0x88, 0x7c, 0x7b, 0x78, 0x65, 0x58, 0x63, 0x6e, 0x6d, 0x65, + 0x64, 0x65, 0x66, 0x63, 0x6d, 0x8a, 0x9c, 0x9b, 0xa1, 0x98, 0x7d, 0x73, 0x6f, 0x6d, 0x72, 0x6a, + 0x5d, 0x55, 0x5d, 0x65, 0x66, 0x5d, 0x60, 0x72, 0x6e, 0x66, 0x76, 0x84, 0x87, 0x87, 0x88, 0x7e, + 0x76, 0x70, 0x70, 0x79, 0x79, 0x73, 0x71, 0x74, 0x6d, 0x64, 0x70, 0x71, 0x6b, 0x73, 0x79, 0x7e, + 0x89, 0x91, 0x8c, 0x89, 0x85, 0x7e, 0x81, 0x68, 0x56, 0x55, 0x4f, 0x56, 0x64, 0x62, 0x53, 0x4f, + 0x57, 0x63, 0x6c, 0x7c, 0x92, 0x94, 0x8c, 0x91, 0x95, 0x94, 0x8b, 0x92, 0x9a, 0x8f, 0x86, 0x87, + 0x83, 0x78, 0x73, 0x6d, 0x75, 0x78, 0x6a, 0x68, 0x77, 0x8a, 0x95, 0x8e, 0x76, 0x68, 0x66, 0x6b, + 0x75, 0x89, 0x98, 0x8d, 0x87, 0x8e, 0x93, 0x90, 0x8c, 0x89, 0x95, 0x92, 0x8e, 0x96, 0x94, 0x8a, + 0x8c, 0x8c, 0x8b, 0x91, 0x87, 0x80, 0x7b, 0x74, 0x79, 0x7d, 0x74, 0x6c, 0x6e, 0x70, 0x72, 0x7a, + 0x84, 0x94, 0xa3, 0xae, 0xa7, 0x8f, 0x8d, 0x90, 0x95, 0x99, 0x93, 0x86, 0x75, 0x75, 0x88, 0x9d, + 0x9f, 0x92, 0x8d, 0x7e, 0x76, 0x7b, 0x82, 0x84, 0x80, 0x7b, 0x7c, 0x85, 0x84, 0x86, 0x8a, 0x86, + 0x8e, 0x95, 0x8f, 0x91, 0x93, 0x92, 0x92, 0x98, 0xa0, 0xa0, 0xa2, 0xa8, 0xaf, 0xa2, 0x89, 0x78, + 0x82, 0x89, 0x74, 0x66, 0x65, 0x63, 0x6b, 0x74, 0x72, 0x67, 0x60, 0x6c, 0x86, 0x9b, 0xb0, 0xac, + 0x98, 0x90, 0x98, 0x9a, 0x93, 0x8b, 0x8a, 0x7e, 0x6c, 0x6b, 0x6c, 0x6b, 0x64, 0x5b, 0x5f, 0x68, + 0x5e, 0x63, 0x73, 0x7a, 0x86, 0x97, 0x8c, 0x75, 0x6b, 0x6f, 0x75, 0x72, 0x6d, 0x6b, 0x69, 0x69, + 0x70, 0x72, 0x6e, 0x6f, 0x82, 0x89, 0x82, 0x79, 0x7a, 0x7d, 0x87, 0x98, 0xa3, 0x96, 0x86, 0x76, + 0x69, 0x5f, 0x5b, 0x5c, 0x5d, 0x53, 0x4f, 0x54, 0x52, 0x5a, 0x6b, 0x7a, 0x89, 0x92, 0x98, 0x96, + 0x88, 0x77, 0x80, 0x8f, 0x85, 0x74, 0x6d, 0x6c, 0x70, 0x75, 0x73, 0x6e, 0x74, 0x7a, 0x79, 0x76, + 0x7c, 0x83, 0x7e, 0x79, 0x7a, 0x79, 0x75, 0x7b, 0x8d, 0x93, 0x96, 0x91, 0x8d, 0x8a, 0x80, 0x78, + 0x75, 0x7b, 0x82, 0x84, 0x8a, 0x90, 0x96, 0xa3, 0x9c, 0x8c, 0x89, 0x8a, 0x7d, 0x74, 0x71, 0x6b, + 0x66, 0x6b, 0x71, 0x72, 0x6b, 0x6f, 0x82, 0x8c, 0x8d, 0x98, 0x9e, 0x92, 0x8a, 0x90, 0x97, 0x97, + 0x9c, 0x90, 0x78, 0x65, 0x67, 0x78, 0x83, 0x85, 0x8a, 0x85, 0x78, 0x6d, 0x6e, 0x79, 0x7b, 0x7a, + 0x86, 0x7d, 0x6c, 0x67, 0x6f, 0x7c, 0x7c, 0x7c, 0x81, 0x7e, 0x7e, 0x89, 0x8d, 0x84, 0x92, 0xa5, + 0x9e, 0x92, 0x8b, 0x8e, 0x88, 0x81, 0x89, 0x92, 0x8d, 0x7b, 0x6f, 0x66, 0x67, 0x6b, 0x6a, 0x68, + 0x5c, 0x51, 0x56, 0x6a, 0x80, 0x9a, 0xb0, 0xab, 0xa8, 0xaa, 0x99, 0x8d, 0x87, 0x90, 0x8e, 0x79, + 0x6d, 0x6b, 0x70, 0x79, 0x84, 0x85, 0x83, 0x84, 0x83, 0x87, 0x88, 0x84, 0x7d, 0x76, 0x71, 0x77, + 0x7b, 0x7b, 0x84, 0x83, 0x7c, 0x7d, 0x83, 0x87, 0x8b, 0x89, 0x86, 0x86, 0x8a, 0x7e, 0x7d, 0x7d, + 0x85, 0x98, 0xaa, 0xaa, 0xa9, 0x97, 0x84, 0x74, 0x65, 0x66, 0x64, 0x56, 0x59, 0x5a, 0x54, 0x57, + 0x6d, 0x87, 0x90, 0x8f, 0x8e, 0x8b, 0x81, 0x81, 0x92, 0x96, 0x99, 0x93, 0x7c, 0x6d, 0x65, 0x70, + 0x74, 0x70, 0x6b, 0x68, 0x64, 0x5a, 0x66, 0x77, 0x85, 0x7e, 0x7c, 0x8b, 0x80, 0x71, 0x6f, 0x84, + 0x94, 0x99, 0xa4, 0x9b, 0x8b, 0x84, 0x84, 0x89, 0x8d, 0x9c, 0x9d, 0x90, 0x85, 0x87, 0x91, 0x8f, + 0x97, 0xa3, 0xa3, 0x96, 0x87, 0x83, 0x80, 0x7b, 0x77, 0x76, 0x73, 0x67, 0x63, 0x6c, 0x76, 0x7a, + 0x82, 0x8a, 0x89, 0x92, 0xa6, 0xa1, 0x94, 0x85, 0x84, 0x75, 0x66, 0x61, 0x65, 0x6e, 0x79, 0x89, + 0x92, 0x8b, 0x7e, 0x77, 0x73, 0x75, 0x70, 0x63, 0x5d, 0x59, 0x5e, 0x67, 0x72, 0x79, 0x7a, 0x75, + 0x75, 0x7b, 0x7b, 0x78, 0x79, 0x77, 0x81, 0x7e, 0x76, 0x7b, 0x83, 0x8a, 0x93, 0x9a, 0x8e, 0x84, + 0x74, 0x6e, 0x77, 0x74, 0x73, 0x62, 0x53, 0x57, 0x5a, 0x5a, 0x66, 0x83, 0x95, 0x9c, 0xa6, 0xa0, + 0x90, 0x7b, 0x79, 0x86, 0x89, 0x85, 0x72, 0x5c, 0x56, 0x60, 0x6e, 0x73, 0x76, 0x77, 0x75, 0x70, + 0x69, 0x72, 0x82, 0x87, 0x81, 0x86, 0x8e, 0x81, 0x78, 0x75, 0x7a, 0x77, 0x71, 0x73, 0x70, 0x71, + 0x7b, 0x7e, 0x81, 0x86, 0x8c, 0x84, 0x7a, 0x73, 0x77, 0x80, 0x82, 0x89, 0x9e, 0x9a, 0x82, 0x6d, + 0x69, 0x6f, 0x6c, 0x62, 0x5c, 0x56, 0x55, 0x5c, 0x6c, 0x7b, 0x8a, 0x91, 0x96, 0x9a, 0xa1, 0xaa, + 0xa2, 0xa0, 0x9f, 0x98, 0x88, 0x80, 0x84, 0x81, 0x7d, 0x7b, 0x84, 0x8c, 0x8c, 0x95, 0x9e, 0x99, + 0x91, 0x82, 0x76, 0x72, 0x74, 0x76, 0x86, 0x98, 0x9d, 0xa1, 0xaa, 0xa6, 0x9d, 0x8c, 0x86, 0x8b, + 0x8e, 0x86, 0x7c, 0x7b, 0x81, 0x8d, 0x93, 0xa1, 0xad, 0xa3, 0x95, 0x86, 0x81, 0x7e, 0x80, 0x7d, + 0x6f, 0x67, 0x6e, 0x77, 0x7e, 0x8c, 0x9b, 0x9c, 0x9c, 0x9b, 0x9a, 0x9d, 0x99, 0x90, 0x96, 0xa2, + 0x9d, 0x8f, 0x81, 0x76, 0x7d, 0x86, 0x86, 0x8d, 0x9a, 0x85, 0x6e, 0x67, 0x73, 0x81, 0x7b, 0x6c, + 0x6e, 0x71, 0x62, 0x5e, 0x66, 0x74, 0x78, 0x72, 0x6f, 0x6d, 0x66, 0x66, 0x6d, 0x7e, 0x90, 0x95, + 0x90, 0x8b, 0x89, 0x84, 0x7d, 0x78, 0x80, 0x86, 0x85, 0x84, 0x77, 0x67, 0x5f, 0x59, 0x55, 0x54, + 0x52, 0x4d, 0x50, 0x5c, 0x6e, 0x8e, 0xa4, 0x9e, 0x90, 0x88, 0x8c, 0x87, 0x8a, 0x7e, 0x74, 0x67, + 0x5d, 0x63, 0x69, 0x6f, 0x75, 0x77, 0x73, 0x73, 0x74, 0x73, 0x79, 0x79, 0x71, 0x6b, 0x65, 0x6b, + 0x76, 0x7c, 0x79, 0x72, 0x73, 0x74, 0x81, 0x86, 0x7c, 0x6c, 0x6c, 0x6f, 0x6a, 0x6d, 0x73, 0x75, + 0x7e, 0x82, 0x94, 0xb0, 0xad, 0x93, 0x7e, 0x71, 0x6f, 0x6f, 0x67, 0x5a, 0x54, 0x4f, 0x53, 0x61, + 0x77, 0x89, 0x91, 0x90, 0x92, 0x90, 0x80, 0x74, 0x77, 0x8e, 0x98, 0x88, 0x75, 0x6e, 0x70, 0x76, + 0x77, 0x77, 0x79, 0x77, 0x73, 0x7a, 0x7e, 0x82, 0x81, 0x82, 0x80, 0x84, 0x8b, 0x7b, 0x78, 0x7d, + 0x90, 0xa6, 0xa8, 0x99, 0x88, 0x79, 0x78, 0x85, 0x96, 0x96, 0x94, 0x89, 0x81, 0x88, 0x8d, 0x90, + 0x90, 0x8f, 0x90, 0x93, 0x88, 0x78, 0x7e, 0x81, 0x83, 0x7e, 0x73, 0x77, 0x79, 0x76, 0x80, 0x8f, + 0x9f, 0xa3, 0xa7, 0xa5, 0xa8, 0x9e, 0x91, 0x96, 0x88, 0x82, 0x75, 0x6b, 0x6d, 0x72, 0x86, 0x99, + 0x9d, 0x92, 0x8e, 0x88, 0x8b, 0x8f, 0x87, 0x7a, 0x69, 0x5f, 0x68, 0x7a, 0x8e, 0x93, 0x8f, 0x88, + 0x84, 0x87, 0x80, 0x75, 0x78, 0x86, 0x86, 0x84, 0x89, 0x8d, 0x8f, 0x8f, 0x8e, 0x9d, 0xa6, 0x95, + 0x8e, 0x89, 0x83, 0x79, 0x6d, 0x67, 0x61, 0x5b, 0x5a, 0x5d, 0x6d, 0x83, 0x9e, 0xb3, 0xb3, 0xa0, + 0x8a, 0x77, 0x77, 0x88, 0x9a, 0x95, 0x83, 0x70, 0x66, 0x6b, 0x76, 0x7c, 0x77, 0x6a, 0x60, 0x5f, + 0x5f, 0x62, 0x71, 0x74, 0x73, 0x69, 0x6a, 0x73, 0x6a, 0x69, 0x6b, 0x77, 0x79, 0x75, 0x71, 0x6a, + 0x6c, 0x6b, 0x7a, 0x8e, 0x8b, 0x89, 0x82, 0x7d, 0x83, 0x8a, 0x93, 0x9e, 0x9e, 0x92, 0x89, 0x70, + 0x6c, 0x70, 0x67, 0x62, 0x56, 0x49, 0x48, 0x53, 0x62, 0x75, 0x82, 0x85, 0x89, 0x88, 0x7e, 0x84, + 0x8f, 0x95, 0x93, 0x85, 0x81, 0x7c, 0x7b, 0x7b, 0x7e, 0x86, 0x88, 0x86, 0x8c, 0x8d, 0x8e, 0x92, + 0x90, 0x8a, 0x79, 0x67, 0x65, 0x6b, 0x7d, 0x92, 0x9a, 0xa0, 0xa0, 0x91, 0x80, 0x71, 0x6a, 0x74, + 0x7e, 0x75, 0x72, 0x76, 0x79, 0x82, 0x8f, 0x94, 0x9c, 0x97, 0x88, 0x87, 0x7b, 0x76, 0x79, 0x74, + 0x6d, 0x66, 0x63, 0x69, 0x74, 0x80, 0x89, 0x90, 0x91, 0x95, 0x92, 0x82, 0x78, 0x7b, 0x8b, 0x91, + 0x85, 0x73, 0x63, 0x5d, 0x69, 0x7d, 0x84, 0x87, 0x7e, 0x71, 0x6b, 0x65, 0x75, 0x80, 0x74, 0x6c, + 0x62, 0x69, 0x6d, 0x6e, 0x77, 0x7b, 0x7b, 0x78, 0x7b, 0x75, 0x71, 0x72, 0x82, 0x98, 0x99, 0x90, + 0x8c, 0x8b, 0x8c, 0x8e, 0x89, 0x83, 0x85, 0x81, 0x83, 0x84, 0x81, 0x86, 0x7e, 0x76, 0x73, 0x63, + 0x59, 0x5d, 0x75, 0x8a, 0x96, 0xab, 0xb1, 0xa5, 0x91, 0x83, 0x92, 0x9f, 0x96, 0x86, 0x7d, 0x78, + 0x72, 0x78, 0x85, 0x8c, 0x88, 0x86, 0x88, 0x8c, 0x87, 0x87, 0x90, 0x8c, 0x85, 0x71, 0x68, 0x76, + 0x84, 0x90, 0x95, 0x8e, 0x8b, 0x86, 0x7b, 0x78, 0x7a, 0x7c, 0x82, 0x87, 0x7d, 0x76, 0x76, 0x7a, + 0x8c, 0x94, 0x95, 0xa7, 0x9f, 0x8c, 0x7c, 0x6d, 0x73, 0x72, 0x63, 0x5e, 0x5c, 0x5a, 0x67, 0x79, + 0x8a, 0x90, 0x90, 0x97, 0x9b, 0x90, 0x80, 0x79, 0x8e, 0x9e, 0xa0, 0x96, 0x8f, 0x8e, 0x8e, 0x90, + 0x90, 0x87, 0x77, 0x6a, 0x6f, 0x70, 0x79, 0x8b, 0x84, 0x77, 0x6c, 0x5e, 0x64, 0x6e, 0x80, 0x87, + 0x88, 0x95, 0x97, 0x8a, 0x76, 0x71, 0x7b, 0x90, 0x90, 0x86, 0x82, 0x7d, 0x83, 0x8c, 0x90, 0x87, + 0x7d, 0x82, 0x82, 0x87, 0x80, 0x79, 0x7b, 0x76, 0x73, 0x6b, 0x5e, 0x5f, 0x6a, 0x7b, 0x7d, 0x80, + 0x8b, 0x8d, 0x87, 0x82, 0x8f, 0xa6, 0x9e, 0x8f, 0x7a, 0x6a, 0x64, 0x6d, 0x7e, 0x85, 0x87, 0x93, + 0x95, 0x8a, 0x7e, 0x78, 0x80, 0x84, 0x75, 0x6c, 0x5d, 0x54, 0x62, 0x72, 0x80, 0x82, 0x7d, 0x80, + 0x7e, 0x78, 0x71, 0x65, 0x68, 0x75, 0x7c, 0x6c, 0x6a, 0x77, 0x80, 0x83, 0x83, 0x85, 0x89, 0x77, + 0x6f, 0x6e, 0x75, 0x7b, 0x6c, 0x5d, 0x51, 0x43, 0x47, 0x63, 0x76, 0x7c, 0x82, 0x94, 0x9a, 0x8c, + 0x7c, 0x70, 0x74, 0x7e, 0x7a, 0x77, 0x6e, 0x67, 0x6a, 0x6e, 0x76, 0x75, 0x69, 0x65, 0x6c, 0x77, + 0x6e, 0x6d, 0x7a, 0x81, 0x81, 0x76, 0x7b, 0x8f, 0x90, 0x8d, 0x84, 0x81, 0x7c, 0x73, 0x71, 0x78, + 0x84, 0x93, 0x95, 0x8b, 0x7c, 0x74, 0x82, 0x97, 0x9f, 0x9a, 0x92, 0x9c, 0xa0, 0x9c, 0x95, 0x8d, + 0x8e, 0x8a, 0x7d, 0x7b, 0x74, 0x6a, 0x71, 0x83, 0x90, 0x86, 0x85, 0x91, 0x92, 0x92, 0x8c, 0x93, + 0xa2, 0xa0, 0x94, 0x82, 0x83, 0x8f, 0x91, 0x91, 0x90, 0x8a, 0x86, 0x85, 0x88, 0x8f, 0x9c, 0xa5, + 0x99, 0x85, 0x6f, 0x5c, 0x65, 0x82, 0x93, 0x94, 0x93, 0x9d, 0x98, 0x8a, 0x7e, 0x72, 0x71, 0x76, + 0x79, 0x7b, 0x6a, 0x6d, 0x81, 0x8a, 0x8e, 0x8c, 0x96, 0x97, 0x8c, 0x82, 0x71, 0x6b, 0x6b, 0x6b, + 0x6b, 0x67, 0x67, 0x75, 0x82, 0x84, 0x83, 0x84, 0x86, 0x83, 0x83, 0x84, 0x87, 0x8d, 0x8b, 0x84, + 0x72, 0x66, 0x74, 0x86, 0x8a, 0x88, 0x83, 0x84, 0x7d, 0x7d, 0x73, 0x60, 0x63, 0x67, 0x63, 0x65, + 0x63, 0x71, 0x7e, 0x81, 0x80, 0x7a, 0x7c, 0x7b, 0x74, 0x79, 0x78, 0x78, 0x86, 0x8a, 0x83, 0x7e, + 0x86, 0x99, 0xa1, 0x99, 0x8e, 0x83, 0x79, 0x7e, 0x89, 0x8a, 0x91, 0x8d, 0x7e, 0x72, 0x65, 0x5a, + 0x66, 0x7e, 0x8d, 0x89, 0x84, 0x93, 0x8f, 0x88, 0x82, 0x7c, 0x91, 0x8c, 0x77, 0x6b, 0x60, 0x67, + 0x71, 0x71, 0x75, 0x74, 0x73, 0x74, 0x77, 0x76, 0x73, 0x73, 0x79, 0x7e, 0x77, 0x6d, 0x68, 0x70, + 0x80, 0x80, 0x7b, 0x78, 0x73, 0x6e, 0x6f, 0x75, 0x7b, 0x81, 0x77, 0x6d, 0x5e, 0x53, 0x67, 0x7c, + 0x83, 0x82, 0x8d, 0xa6, 0x98, 0x8d, 0x79, 0x6a, 0x6d, 0x63, 0x5b, 0x5a, 0x57, 0x60, 0x73, 0x80, + 0x85, 0x8a, 0x8f, 0x93, 0x8e, 0x8f, 0x8e, 0x83, 0x81, 0x88, 0x88, 0x84, 0x88, 0x94, 0x95, 0x8d, + 0x88, 0x82, 0x7d, 0x84, 0x8c, 0x88, 0x86, 0x81, 0x79, 0x76, 0x6e, 0x79, 0x99, 0x9f, 0x9d, 0x92, + 0x95, 0xa4, 0x94, 0x86, 0x7d, 0x77, 0x80, 0x81, 0x77, 0x74, 0x78, 0x86, 0x97, 0x9b, 0x9c, 0x9a, + 0x91, 0x89, 0x92, 0x94, 0x8a, 0x81, 0x7c, 0x81, 0x7d, 0x72, 0x78, 0x86, 0x91, 0x8d, 0x7e, 0x71, + 0x6b, 0x6b, 0x72, 0x81, 0x94, 0x9b, 0x80, 0x6b, 0x61, 0x69, 0x7c, 0x81, 0x80, 0x7e, 0x86, 0x95, + 0x94, 0x8f, 0x7c, 0x72, 0x71, 0x6c, 0x68, 0x65, 0x63, 0x68, 0x73, 0x87, 0x90, 0x94, 0x94, 0x8d, + 0x83, 0x7c, 0x7a, 0x7a, 0x83, 0x88, 0x86, 0x80, 0x7b, 0x86, 0x8b, 0x8c, 0x8a, 0x8e, 0x90, 0x87, + 0x85, 0x83, 0x84, 0x79, 0x67, 0x60, 0x5c, 0x68, 0x7d, 0x92, 0x96, 0x92, 0x9d, 0xac, 0xa4, 0x95, + 0x8e, 0x8d, 0x84, 0x76, 0x72, 0x77, 0x7e, 0x86, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8e, 0x8e, 0x87, + 0x73, 0x5f, 0x5d, 0x6b, 0x71, 0x6a, 0x7b, 0x8d, 0x8a, 0x81, 0x76, 0x75, 0x6f, 0x65, 0x67, 0x76, + 0x81, 0x7e, 0x72, 0x66, 0x69, 0x76, 0x85, 0x8f, 0x94, 0x95, 0x98, 0x9a, 0x8e, 0x8c, 0x81, 0x79, + 0x73, 0x6a, 0x65, 0x5e, 0x65, 0x7a, 0x8b, 0x97, 0x97, 0x90, 0x87, 0x7f, 0x7d, 0x80, 0x82, 0x8a, + 0x8c, 0x7e, 0x79, 0x78, 0x80, 0x84, 0x7b, 0x77, 0x72, 0x6c, 0x6c, 0x79, 0x81, 0x85, 0x82, 0x78, + 0x6e, 0x6b, 0x6a, 0x6f, 0x75, 0x83, 0x90, 0x8f, 0x99, 0xa0, 0x8b, 0x74, 0x66, 0x6e, 0x73, 0x68, + 0x61, 0x64, 0x68, 0x69, 0x6e, 0x7a, 0x84, 0x81, 0x8b, 0x87, 0x79, 0x71, 0x69, 0x63, 0x61, 0x62, + 0x60, 0x60, 0x6b, 0x79, 0x88, 0x82, 0x7c, 0x78, 0x75, 0x77, 0x7d, 0x8d, 0x8e, 0x7c, 0x6b, 0x71, + 0x7e, 0x86, 0x87, 0x87, 0x86, 0x84, 0x93, 0x9d, 0x90, 0x85, 0x77, 0x6b, 0x5d, 0x56, 0x62, 0x65, + 0x70, 0x8f, 0x99, 0x96, 0x91, 0x8f, 0x8f, 0x81, 0x74, 0x72, 0x74, 0x72, 0x77, 0x82, 0x87, 0x8e, + 0x8f, 0x93, 0x93, 0x93, 0x90, 0x87, 0x7e, 0x8c, 0x9a, 0x9e, 0x95, 0x83, 0x75, 0x73, 0x75, 0x8d, + 0x9c, 0xa4, 0xa4, 0x99, 0x9d, 0x9a, 0x85, 0x83, 0x81, 0x86, 0x8e, 0x79, 0x6c, 0x70, 0x7c, 0x88, + 0x87, 0x86, 0x8a, 0x86, 0x7e, 0x83, 0x89, 0x82, 0x7b, 0x6d, 0x6d, 0x77, 0x79, 0x7a, 0x84, 0x84, + 0x89, 0x8c, 0x8a, 0x88, 0x7e, 0x7c, 0x7d, 0x85, 0x8a, 0x84, 0x79, 0x7e, 0x87, 0x85, 0x80, 0x86, + 0x94, 0x94, 0xa2, 0xab, 0x94, 0x82, 0x76, 0x75, 0x6b, 0x5d, 0x5b, 0x5c, 0x6f, 0x84, 0x94, 0x9e, + 0x9b, 0x98, 0x93, 0x8e, 0x8c, 0x8f, 0x8a, 0x7c, 0x77, 0x81, 0x8f, 0x94, 0x93, 0x8a, 0x80, 0x79, + 0x7b, 0x7b, 0x78, 0x81, 0x82, 0x78, 0x68, 0x56, 0x55, 0x61, 0x6a, 0x86, 0x96, 0x91, 0x8a, 0x83, + 0x91, 0x8c, 0x74, 0x6b, 0x67, 0x66, 0x64, 0x63, 0x66, 0x6f, 0x7d, 0x88, 0x8f, 0x95, 0x99, 0x94, + 0x88, 0x82, 0x84, 0x84, 0x81, 0x74, 0x6e, 0x74, 0x76, 0x88, 0x9a, 0x97, 0x92, 0x8b, 0x7d, 0x74, + 0x6e, 0x72, 0x84, 0x85, 0x87, 0x88, 0x75, 0x6e, 0x74, 0x7b, 0x7b, 0x7a, 0x7b, 0x77, 0x7e, 0x7b, + 0x7a, 0x71, 0x66, 0x67, 0x5c, 0x56, 0x57, 0x5e, 0x74, 0x81, 0x85, 0x8a, 0x88, 0x86, 0x80, 0x74, + 0x70, 0x74, 0x6f, 0x69, 0x6a, 0x70, 0x76, 0x72, 0x6e, 0x68, 0x6a, 0x73, 0x75, 0x7d, 0x80, 0x77, + 0x6d, 0x6d, 0x6b, 0x63, 0x5b, 0x56, 0x62, 0x71, 0x7a, 0x8a, 0x89, 0x83, 0x91, 0x8d, 0x7e, 0x7e, + 0x7d, 0x76, 0x73, 0x6d, 0x6e, 0x78, 0x87, 0x8d, 0x8c, 0x8c, 0x90, 0x93, 0x8d, 0x8b, 0x87, 0x7d, + 0x6f, 0x63, 0x61, 0x70, 0x83, 0x99, 0xaf, 0xaa, 0x9c, 0x93, 0x8e, 0x8f, 0x8b, 0x89, 0x8e, 0x85, + 0x7c, 0x85, 0x89, 0x89, 0x92, 0x9a, 0x9b, 0x9c, 0x99, 0x9c, 0xa6, 0x9c, 0x93, 0x8a, 0x85, 0x82, + 0x74, 0x66, 0x63, 0x78, 0x97, 0xa2, 0xa2, 0xa2, 0x97, 0x83, 0x7c, 0x76, 0x7e, 0x89, 0x80, 0x88, + 0x88, 0x82, 0x82, 0x89, 0x8d, 0x84, 0x7d, 0x78, 0x74, 0x73, 0x79, 0x85, 0x84, 0x82, 0x7c, 0x79, + 0x70, 0x6d, 0x7e, 0x8c, 0x92, 0x94, 0x92, 0x95, 0x9f, 0x94, 0x86, 0x86, 0x84, 0x7c, 0x75, 0x6b, + 0x6d, 0x72, 0x76, 0x7c, 0x7a, 0x82, 0x8a, 0x8f, 0x96, 0x8d, 0x7c, 0x71, 0x6a, 0x64, 0x61, 0x66, + 0x6e, 0x7c, 0x83, 0x85, 0x89, 0x87, 0x83, 0x81, 0x81, 0x86, 0x8e, 0x8a, 0x88, 0x91, 0x89, 0x83, + 0x8a, 0x8f, 0x89, 0x80, 0x7d, 0x85, 0x89, 0x82, 0x7c, 0x77, 0x6a, 0x5d, 0x56, 0x4c, 0x52, 0x6c, + 0x89, 0x9d, 0x91, 0x85, 0x7b, 0x78, 0x77, 0x70, 0x73, 0x6a, 0x5d, 0x5f, 0x67, 0x73, 0x80, 0x88, + 0x88, 0x80, 0x78, 0x7a, 0x80, 0x7e, 0x80, 0x7c, 0x7d, 0x7e, 0x81, 0x82, 0x78, 0x7b, 0x91, 0x9f, + 0xa1, 0x9a, 0x91, 0x82, 0x75, 0x71, 0x76, 0x89, 0x89, 0x8a, 0x89, 0x71, 0x68, 0x6d, 0x81, 0x83, + 0x78, 0x76, 0x71, 0x6e, 0x6d, 0x71, 0x72, 0x6f, 0x68, 0x66, 0x64, 0x61, 0x74, 0x86, 0x8b, 0x86, + 0x78, 0x75, 0x73, 0x6f, 0x69, 0x72, 0x7e, 0x82, 0x8c, 0x8c, 0x85, 0x7c, 0x78, 0x7a, 0x75, 0x73, + 0x7c, 0x82, 0x88, 0x8a, 0x80, 0x7a, 0x73, 0x74, 0x70, 0x61, 0x60, 0x72, 0x83, 0x8d, 0x8f, 0x8d, + 0x8c, 0x88, 0x87, 0x87, 0x8a, 0x89, 0x86, 0x84, 0x82, 0x83, 0x8d, 0x94, 0x8e, 0x7a, 0x74, 0x79, + 0x7e, 0x84, 0x88, 0x85, 0x7d, 0x75, 0x79, 0x7d, 0x72, 0x7c, 0x92, 0xa5, 0xa8, 0x97, 0x8c, 0x85, + 0x87, 0x82, 0x89, 0x8c, 0x80, 0x78, 0x6e, 0x6b, 0x75, 0x84, 0x92, 0x90, 0x85, 0x82, 0x87, 0x88, + 0x88, 0x84, 0x78, 0x75, 0x6f, 0x6c, 0x68, 0x6a, 0x83, 0x94, 0x9d, 0x99, 0x89, 0x7c, 0x74, 0x74, + 0x77, 0x82, 0x87, 0x91, 0xa0, 0x90, 0x7e, 0x7a, 0x82, 0x90, 0x85, 0x80, 0x7b, 0x71, 0x6c, 0x72, + 0x78, 0x7a, 0x78, 0x70, 0x6f, 0x63, 0x65, 0x82, 0x90, 0x98, 0x91, 0x85, 0x87, 0x86, 0x7e, 0x80, + 0x86, 0x86, 0x85, 0x7e, 0x78, 0x7d, 0x81, 0x83, 0x81, 0x73, 0x71, 0x77, 0x80, 0x8e, 0x87, 0x77, + 0x74, 0x7d, 0x8d, 0x85, 0x77, 0x7b, 0x82, 0x8a, 0x94, 0x92, 0x90, 0x8c, 0x87, 0x8d, 0x96, 0x97, + 0x98, 0x95, 0x87, 0x7a, 0x7c, 0x89, 0x90, 0x84, 0x79, 0x7d, 0x81, 0x83, 0x88, 0x81, 0x73, 0x68, + 0x5d, 0x5f, 0x61, 0x6a, 0x80, 0x91, 0x96, 0x81, 0x6e, 0x66, 0x6d, 0x77, 0x71, 0x73, 0x74, 0x78, + 0x7d, 0x75, 0x72, 0x76, 0x7a, 0x82, 0x87, 0x86, 0x85, 0x84, 0x86, 0x8c, 0x8b, 0x87, 0x89, 0x87, + 0x80, 0x7b, 0x85, 0x92, 0x9a, 0x9d, 0x97, 0x8d, 0x86, 0x85, 0x85, 0x85, 0x86, 0x87, 0x8d, 0x8e, + 0x7d, 0x79, 0x79, 0x81, 0x80, 0x6f, 0x6d, 0x6c, 0x6b, 0x6e, 0x6c, 0x69, 0x73, 0x81, 0x8f, 0x90, + 0x84, 0x7b, 0x7a, 0x7c, 0x81, 0x83, 0x7c, 0x75, 0x6f, 0x67, 0x6b, 0x76, 0x7c, 0x7c, 0x78, 0x70, + 0x6c, 0x6a, 0x6d, 0x6f, 0x6f, 0x70, 0x77, 0x86, 0x85, 0x73, 0x67, 0x60, 0x67, 0x6d, 0x67, 0x6c, + 0x6d, 0x6a, 0x68, 0x62, 0x63, 0x68, 0x6f, 0x76, 0x76, 0x78, 0x84, 0x91, 0x97, 0x91, 0x8a, 0x85, + 0x83, 0x7b, 0x79, 0x81, 0x85, 0x82, 0x83, 0x83, 0x7d, 0x79, 0x78, 0x7e, 0x83, 0x81, 0x83, 0x88, + 0x96, 0x95, 0x8c, 0x89, 0x89, 0x91, 0x8b, 0x81, 0x81, 0x7e, 0x7b, 0x79, 0x76, 0x78, 0x7e, 0x83, + 0x82, 0x7c, 0x79, 0x7a, 0x7e, 0x7e, 0x7a, 0x7a, 0x80, 0x89, 0x8b, 0x86, 0x86, 0x86, 0x85, 0x88, + 0x90, 0x90, 0x87, 0x80, 0x81, 0x81, 0x86, 0x8a, 0x93, 0x9b, 0x91, 0x82, 0x7a, 0x7b, 0x86, 0x7e, + 0x7a, 0x81, 0x84, 0x83, 0x7c, 0x73, 0x70, 0x74, 0x7d, 0x8a, 0x8d, 0x8d, 0x8a, 0x8a, 0x87, 0x83, + 0x83, 0x82, 0x83, 0x7b, 0x7c, 0x8d, 0x9d, 0xa7, 0xa9, 0xa3, 0x94, 0x86, 0x84, 0x85, 0x8b, 0x90, + 0x8d, 0x8f, 0x95, 0x8a, 0x7e, 0x79, 0x7b, 0x8a, 0x84, 0x7d, 0x81, 0x81, 0x7e, 0x7b, 0x7b, 0x82, + 0x8b, 0x8e, 0x8c, 0x8a, 0x88, 0x88, 0x89, 0x88, 0x88, 0x86, 0x81, 0x7b, 0x71, 0x6d, 0x70, 0x73, + 0x73, 0x74, 0x76, 0x78, 0x78, 0x7e, 0x87, 0x84, 0x80, 0x78, 0x78, 0x80, 0x81, 0x81, 0x7c, 0x75, + 0x74, 0x71, 0x73, 0x78, 0x78, 0x74, 0x6d, 0x68, 0x68, 0x70, 0x74, 0x76, 0x7c, 0x83, 0x87, 0x86, + 0x80, 0x78, 0x74, 0x76, 0x7d, 0x83, 0x84, 0x85, 0x82, 0x7d, 0x7d, 0x7c, 0x7b, 0x78, 0x77, 0x76, + 0x7a, 0x84, 0x88, 0x8a, 0x8a, 0x85, 0x7a, 0x70, 0x6e, 0x6e, 0x71, 0x70, 0x6e, 0x6a, 0x69, 0x67, + 0x65, 0x6a, 0x73, 0x7b, 0x7d, 0x7c, 0x7c, 0x79, 0x77, 0x75, 0x78, 0x7d, 0x7b, 0x74, 0x6d, 0x6c, + 0x6c, 0x6c, 0x6b, 0x6d, 0x71, 0x6c, 0x65, 0x66, 0x67, 0x6b, 0x71, 0x73, 0x74, 0x74, 0x73, 0x75, + 0x7a, 0x82, 0x8a, 0x89, 0x85, 0x82, 0x7d, 0x7c, 0x7d, 0x7b, 0x7e, 0x7e, 0x81, 0x87, 0x8c, 0x91, + 0x8f, 0x8d, 0x8c, 0x8a, 0x86, 0x87, 0x89, 0x88, 0x8c, 0x8e, 0x8d, 0x87, 0x80, 0x7c, 0x7a, 0x7d, + 0x85, 0x88, 0x8c, 0x91, 0x8d, 0x87, 0x84, 0x80, 0x81, 0x82, 0x82, 0x85, 0x89, 0x8b, 0x8d, 0x90, + 0x92, 0x90, 0x8b, 0x87, 0x89, 0x89, 0x8c, 0x8e, 0x8e, 0x89, 0x87, 0x84, 0x83, 0x84, 0x84, 0x85, + 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x82, 0x8a, 0x8e, 0x8b, 0x88, 0x86, 0x88, 0x8b, 0x8a, 0x87, 0x84, + 0x84, 0x81, 0x7b, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7b, 0x7b, 0x79, 0x7b, 0x84, 0x8d, 0x90, 0x8f, + 0x90, 0x8d, 0x85, 0x82, 0x84, 0x85, 0x81, 0x7d, 0x82, 0x85, 0x89, 0x8b, 0x89, 0x86, 0x85, 0x85, + 0x7c, 0x78, 0x7b, 0x82, 0x8a, 0x8e, 0x8b, 0x80, 0x72, 0x6d, 0x6e, 0x71, 0x71, 0x72, 0x76, 0x79, + 0x76, 0x75, 0x76, 0x74, 0x74, 0x7a, 0x81, 0x85, 0x86, 0x8c, 0x90, 0x90, 0x93, 0x92, 0x8c, 0x81, + 0x7a, 0x79, 0x7a, 0x79, 0x76, 0x72, 0x70, 0x6e, 0x70, 0x70, 0x70, 0x72, 0x73, 0x77, 0x77, 0x76, + 0x75, 0x75, 0x76, 0x76, 0x74, 0x6e, 0x6d, 0x70, 0x71, 0x6f, 0x70, 0x72, 0x73, 0x72, 0x71, 0x75, + 0x78, 0x78, 0x7b, 0x7e, 0x7e, 0x80, 0x81, 0x86, 0x8c, 0x93, 0x97, 0x98, 0x99, 0x94, 0x8e, 0x8a, + 0x8c, 0x8e, 0x8a, 0x88, 0x8b, 0x8c, 0x90, 0x93, 0x8f, 0x8a, 0x85, 0x7d, 0x78, 0x78, 0x79, 0x7e, + 0x80, 0x7b, 0x77, 0x71, 0x6b, 0x6a, 0x6c, 0x73, 0x79, 0x7b, 0x80, 0x83, 0x7e, 0x78, 0x78, 0x74, + 0x73, 0x72, 0x72, 0x73, 0x74, 0x78, 0x7a, 0x7a, 0x7b, 0x7e, 0x7c, 0x74, 0x72, 0x76, 0x7b, 0x7d, + 0x7b, 0x79, 0x76, 0x71, 0x71, 0x75, 0x79, 0x77, 0x79, 0x7d, 0x80, 0x82, 0x83, 0x85, 0x84, 0x82, + 0x83, 0x83, 0x83, 0x83, 0x87, 0x86, 0x84, 0x88, 0x8a, 0x85, 0x7e, 0x82, 0x87, 0x82, 0x7d, 0x7a, + 0x78, 0x74, 0x75, 0x7c, 0x83, 0x8a, 0x8f, 0x94, 0x97, 0x94, 0x8f, 0x8a, 0x88, 0x84, 0x81, 0x7d, + 0x7c, 0x7d, 0x80, 0x82, 0x7e, 0x7d, 0x7c, 0x78, 0x76, 0x7d, 0x86, 0x89, 0x86, 0x84, 0x7e, 0x76, + 0x72, 0x71, 0x73, 0x75, 0x79, 0x7c, 0x7e, 0x7c, 0x78, 0x78, 0x76, 0x74, 0x76, 0x78, 0x7a, 0x80, + 0x87, 0x90, 0x94, 0x91, 0x92, 0x91, 0x8b, 0x85, 0x7e, 0x7e, 0x81, 0x7d, 0x7b, 0x78, 0x75, 0x72, + 0x71, 0x76, 0x7e, 0x82, 0x82, 0x83, 0x84, 0x86, 0x87, 0x89, 0x88, 0x82, 0x7b, 0x78, 0x7b, 0x7e, + 0x80, 0x7c, 0x7b, 0x7e, 0x80, 0x7e, 0x7a, 0x7b, 0x7b, 0x78, 0x7a, 0x7d, 0x7a, 0x76, 0x76, 0x78, + 0x7e, 0x7d, 0x7e, 0x86, 0x8b, 0x8c, 0x8a, 0x8a, 0x8a, 0x86, 0x84, 0x88, 0x8e, 0x8f, 0x90, 0x91, + 0x8c, 0x8a, 0x8b, 0x87, 0x85, 0x86, 0x8a, 0x88, 0x7e, 0x78, 0x74, 0x6c, 0x66, 0x6a, 0x72, 0x74, + 0x76, 0x78, 0x7d, 0x81, 0x7e, 0x7b, 0x78, 0x73, 0x6f, 0x6e, 0x6e, 0x72, 0x78, 0x80, 0x84, 0x84, + 0x8b, 0x90, 0x8d, 0x8f, 0x93, 0x96, 0x91, 0x89, 0x88, 0x85, 0x82, 0x81, 0x83, 0x87, 0x86, 0x89, + 0x8b, 0x8a, 0x8a, 0x8c, 0x8a, 0x86, 0x83, 0x80, 0x7c, 0x7b, 0x80, 0x87, 0x88, 0x84, 0x80, 0x7e, + 0x7b, 0x77, 0x76, 0x72, 0x6e, 0x68, 0x68, 0x6c, 0x68, 0x67, 0x68, 0x6c, 0x77, 0x84, 0x8d, 0x90, + 0x8d, 0x8e, 0x8b, 0x89, 0x86, 0x80, 0x78, 0x76, 0x7e, 0x82, 0x83, 0x82, 0x7c, 0x7a, 0x77, 0x75, + 0x78, 0x7c, 0x7e, 0x80, 0x7e, 0x7d, 0x78, 0x70, 0x6e, 0x71, 0x71, 0x73, 0x71, 0x71, 0x72, 0x77, + 0x7a, 0x78, 0x77, 0x6f, 0x6a, 0x6d, 0x76, 0x82, 0x85, 0x89, 0x8e, 0x8d, 0x8f, 0x8e, 0x8b, 0x86, + 0x82, 0x84, 0x81, 0x7b, 0x77, 0x74, 0x73, 0x70, 0x71, 0x74, 0x75, 0x76, 0x79, 0x7d, 0x82, 0x85, + 0x84, 0x81, 0x7b, 0x76, 0x70, 0x6c, 0x6f, 0x76, 0x7c, 0x7a, 0x76, 0x76, 0x70, 0x70, 0x75, 0x7b, + 0x7d, 0x74, 0x71, 0x72, 0x70, 0x70, 0x75, 0x80, 0x87, 0x8a, 0x91, 0x91, 0x8d, 0x8e, 0x8f, 0x8e, + 0x87, 0x81, 0x7c, 0x7e, 0x8a, 0x94, 0x9a, 0x99, 0x94, 0x91, 0x8e, 0x8e, 0x92, 0x92, 0x8c, 0x87, + 0x83, 0x84, 0x80, 0x7b, 0x7d, 0x80, 0x82, 0x86, 0x8b, 0x8c, 0x86, 0x85, 0x87, 0x86, 0x84, 0x7e, + 0x7d, 0x79, 0x78, 0x80, 0x84, 0x8b, 0x8f, 0x92, 0x94, 0x90, 0x8d, 0x8c, 0x8c, 0x8d, 0x8a, 0x84, + 0x7d, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x7e, 0x7a, 0x77, 0x7b, 0x86, 0x8a, 0x87, 0x85, 0x7c, 0x78, + 0x7b, 0x85, 0x8d, 0x92, 0x93, 0x8e, 0x85, 0x7e, 0x7d, 0x82, 0x7d, 0x7b, 0x7a, 0x6f, 0x69, 0x68, + 0x6a, 0x6d, 0x6e, 0x73, 0x7b, 0x82, 0x88, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x7d, 0x75, 0x72, 0x72, + 0x77, 0x7b, 0x80, 0x84, 0x80, 0x7c, 0x7c, 0x7c, 0x83, 0x8a, 0x93, 0x92, 0x89, 0x83, 0x81, 0x82, + 0x82, 0x86, 0x89, 0x87, 0x85, 0x85, 0x83, 0x86, 0x87, 0x87, 0x83, 0x78, 0x72, 0x72, 0x75, 0x7e, + 0x8b, 0x93, 0x92, 0x90, 0x8f, 0x8a, 0x86, 0x82, 0x7d, 0x78, 0x6d, 0x66, 0x6a, 0x6d, 0x74, 0x72, + 0x6d, 0x70, 0x75, 0x77, 0x76, 0x75, 0x78, 0x78, 0x74, 0x70, 0x6d, 0x6a, 0x66, 0x67, 0x6d, 0x71, + 0x70, 0x6d, 0x6c, 0x67, 0x64, 0x67, 0x69, 0x69, 0x69, 0x64, 0x63, 0x65, 0x68, 0x6c, 0x6f, 0x72, + 0x79, 0x79, 0x77, 0x75, 0x76, 0x79, 0x7b, 0x7e, 0x7a, 0x74, 0x77, 0x81, 0x8d, 0x91, 0x91, 0x90, + 0x8b, 0x84, 0x82, 0x87, 0x8a, 0x85, 0x82, 0x7e, 0x75, 0x74, 0x79, 0x83, 0x84, 0x7d, 0x7b, 0x7e, + 0x80, 0x80, 0x84, 0x89, 0x8a, 0x8a, 0x87, 0x7e, 0x79, 0x78, 0x79, 0x80, 0x89, 0x8f, 0x91, 0x90, + 0x91, 0x8f, 0x8c, 0x8c, 0x8e, 0x91, 0x88, 0x7e, 0x82, 0x89, 0x8d, 0x89, 0x8a, 0x8e, 0x8d, 0x89, + 0x8a, 0x8a, 0x8d, 0x8f, 0x90, 0x8d, 0x85, 0x7d, 0x7e, 0x86, 0x8f, 0x97, 0x98, 0x93, 0x8d, 0x89, + 0x88, 0x8b, 0x88, 0x83, 0x7b, 0x6f, 0x6e, 0x75, 0x7a, 0x83, 0x84, 0x86, 0x8d, 0x92, 0x91, 0x8c, + 0x88, 0x87, 0x88, 0x87, 0x82, 0x81, 0x81, 0x81, 0x86, 0x88, 0x87, 0x82, 0x7b, 0x7c, 0x80, 0x7e, + 0x80, 0x81, 0x82, 0x80, 0x79, 0x7a, 0x7c, 0x7b, 0x77, 0x72, 0x75, 0x7c, 0x79, 0x74, 0x74, 0x79, + 0x7a, 0x79, 0x76, 0x70, 0x6f, 0x75, 0x80, 0x8c, 0x8f, 0x8f, 0x8c, 0x8a, 0x88, 0x87, 0x87, 0x84, + 0x7c, 0x78, 0x70, 0x6d, 0x72, 0x78, 0x7b, 0x76, 0x70, 0x71, 0x75, 0x78, 0x7d, 0x81, 0x83, 0x82, + 0x7c, 0x76, 0x6f, 0x6d, 0x6d, 0x70, 0x74, 0x79, 0x7d, 0x7d, 0x7a, 0x7a, 0x7d, 0x82, 0x82, 0x83, + 0x7e, 0x75, 0x78, 0x84, 0x8d, 0x91, 0x91, 0x93, 0x96, 0x92, 0x8f, 0x8d, 0x87, 0x85, 0x86, 0x86, + 0x83, 0x7c, 0x7b, 0x82, 0x89, 0x8c, 0x8d, 0x88, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x7a, 0x74, 0x6e, + 0x69, 0x6c, 0x6f, 0x6e, 0x6c, 0x6c, 0x72, 0x79, 0x79, 0x77, 0x75, 0x77, 0x77, 0x75, 0x6f, 0x6a, + 0x6c, 0x6f, 0x75, 0x7e, 0x83, 0x81, 0x7e, 0x7e, 0x83, 0x83, 0x7a, 0x76, 0x79, 0x7b, 0x7b, 0x7c, + 0x80, 0x7e, 0x79, 0x71, 0x70, 0x75, 0x74, 0x73, 0x75, 0x75, 0x79, 0x7a, 0x79, 0x78, 0x76, 0x78, + 0x7b, 0x82, 0x87, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, 0x88, 0x88, 0x84, 0x7b, 0x72, 0x6e, 0x70, 0x78, + 0x83, 0x8b, 0x88, 0x84, 0x87, 0x8c, 0x90, 0x91, 0x8f, 0x8c, 0x89, 0x85, 0x82, 0x81, 0x81, 0x80, + 0x81, 0x83, 0x83, 0x82, 0x81, 0x83, 0x84, 0x85, 0x86, 0x84, 0x81, 0x7c, 0x7a, 0x79, 0x7c, 0x7e, + 0x7c, 0x80, 0x86, 0x89, 0x87, 0x85, 0x82, 0x82, 0x80, 0x7b, 0x78, 0x74, 0x73, 0x7b, 0x89, 0x94, + 0x96, 0x93, 0x91, 0x8e, 0x8e, 0x8b, 0x86, 0x83, 0x82, 0x80, 0x81, 0x83, 0x84, 0x84, 0x81, 0x7d, + 0x80, 0x83, 0x84, 0x86, 0x85, 0x85, 0x87, 0x84, 0x80, 0x7c, 0x79, 0x76, 0x75, 0x77, 0x7c, 0x7e, + 0x7d, 0x7e, 0x80, 0x82, 0x7c, 0x77, 0x78, 0x78, 0x76, 0x76, 0x78, 0x7b, 0x7a, 0x77, 0x76, 0x79, + 0x7c, 0x7e, 0x82, 0x84, 0x83, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x83, 0x87, 0x8a, 0x8a, 0x8a, + 0x8b, 0x8a, 0x88, 0x87, 0x86, 0x81, 0x77, 0x73, 0x72, 0x71, 0x74, 0x78, 0x79, 0x76, 0x79, 0x7e, + 0x83, 0x84, 0x83, 0x82, 0x7c, 0x71, 0x6b, 0x6a, 0x6e, 0x76, 0x7d, 0x86, 0x88, 0x87, 0x89, 0x8b, + 0x8d, 0x8d, 0x89, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x8f, 0x92, 0x93, 0x92, 0x96, 0x99, 0x96, 0x90, + 0x8c, 0x8a, 0x89, 0x84, 0x81, 0x80, 0x79, 0x77, 0x7d, 0x85, 0x8a, 0x8c, 0x8b, 0x89, 0x82, 0x7b, + 0x77, 0x77, 0x73, 0x6c, 0x6a, 0x6e, 0x73, 0x79, 0x7c, 0x7a, 0x76, 0x77, 0x7a, 0x7d, 0x81, 0x80, + 0x7c, 0x79, 0x78, 0x76, 0x75, 0x73, 0x73, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7b, 0x7c, 0x7a, 0x74, + 0x71, 0x71, 0x70, 0x70, 0x6f, 0x6d, 0x69, 0x63, 0x66, 0x6e, 0x74, 0x73, 0x70, 0x6d, 0x6d, 0x70, + 0x6c, 0x65, 0x62, 0x65, 0x6e, 0x7b, 0x84, 0x89, 0x89, 0x86, 0x86, 0x87, 0x89, 0x88, 0x84, 0x81, + 0x81, 0x7a, 0x78, 0x78, 0x76, 0x79, 0x80, 0x81, 0x82, 0x85, 0x86, 0x86, 0x83, 0x82, 0x7e, 0x72, + 0x6a, 0x6a, 0x74, 0x7a, 0x7b, 0x7e, 0x85, 0x88, 0x89, 0x89, 0x87, 0x80, 0x78, 0x7b, 0x7e, 0x7b, + 0x79, 0x7d, 0x84, 0x88, 0x8a, 0x89, 0x8c, 0x91, 0x94, 0x93, 0x8f, 0x8f, 0x8e, 0x8b, 0x8b, 0x8d, + 0x8b, 0x87, 0x89, 0x91, 0x98, 0x9c, 0x9c, 0x99, 0x94, 0x8a, 0x87, 0x81, 0x78, 0x7d, 0x7c, 0x79, + 0x7a, 0x7c, 0x7e, 0x7d, 0x79, 0x7a, 0x83, 0x87, 0x86, 0x84, 0x82, 0x82, 0x78, 0x6d, 0x6c, 0x74, + 0x7c, 0x82, 0x84, 0x84, 0x89, 0x87, 0x85, 0x87, 0x8e, 0x91, 0x8d, 0x88, 0x8f, 0x91, 0x8d, 0x87, + 0x84, 0x86, 0x81, 0x7a, 0x7a, 0x7d, 0x79, 0x81, 0x89, 0x89, 0x84, 0x7b, 0x75, 0x70, 0x70, 0x79, + 0x82, 0x85, 0x89, 0x8c, 0x8e, 0x8e, 0x88, 0x81, 0x7c, 0x79, 0x71, 0x6e, 0x70, 0x79, 0x7c, 0x7b, + 0x7d, 0x7e, 0x78, 0x72, 0x72, 0x76, 0x78, 0x81, 0x86, 0x82, 0x7a, 0x76, 0x74, 0x70, 0x71, 0x76, + 0x77, 0x7d, 0x8d, 0x92, 0x95, 0x98, 0x93, 0x8d, 0x8c, 0x83, 0x7e, 0x86, 0x8c, 0x92, 0x97, 0x98, + 0x96, 0x96, 0x98, 0x95, 0x8c, 0x86, 0x8a, 0x87, 0x7d, 0x79, 0x7b, 0x7c, 0x7a, 0x83, 0x89, 0x8a, + 0x88, 0x83, 0x85, 0x85, 0x86, 0x84, 0x78, 0x76, 0x72, 0x60, 0x5e, 0x5d, 0x67, 0x71, 0x75, 0x76, + 0x76, 0x72, 0x6e, 0x6f, 0x6e, 0x6c, 0x6a, 0x64, 0x60, 0x61, 0x62, 0x62, 0x69, 0x6c, 0x6b, 0x73, + 0x77, 0x7a, 0x81, 0x7d, 0x79, 0x79, 0x73, 0x75, 0x7a, 0x6e, 0x6e, 0x6f, 0x6b, 0x6c, 0x72, 0x70, + 0x6c, 0x68, 0x67, 0x66, 0x6c, 0x67, 0x6e, 0x7b, 0x77, 0x7b, 0x80, 0x7d, 0x84, 0x8a, 0x8c, 0x8b, + 0x8a, 0x8b, 0x8b, 0x89, 0x8b, 0x85, 0x7b, 0x80, 0x75, 0x6f, 0x81, 0x86, 0x88, 0x8b, 0x87, 0x84, + 0x87, 0x8e, 0x91, 0x8a, 0x7b, 0x71, 0x70, 0x73, 0x76, 0x78, 0x75, 0x76, 0x84, 0x89, 0x8a, 0x8b, + 0x9a, 0xa1, 0x9a, 0x93, 0x8e, 0x7e, 0x89, 0x93, 0x8b, 0x94, 0x9a, 0x98, 0x93, 0x8c, 0x88, 0x87, + 0x84, 0x87, 0x86, 0x85, 0x89, 0x8d, 0x8b, 0x8d, 0x94, 0x9c, 0x99, 0x91, 0x8f, 0x8b, 0x86, 0x84, + 0x88, 0x8a, 0x87, 0x7d, 0x78, 0x85, 0x85, 0x74, 0x7e, 0x86, 0x8d, 0x8b, 0x87, 0x88, 0x8a, 0x89, + 0x87, 0x81, 0x74, 0x6a, 0x66, 0x63, 0x75, 0x86, 0x8a, 0x82, 0x7b, 0x7c, 0x7a, 0x75, 0x76, 0x7c, + 0x84, 0x8d, 0x7e, 0x74, 0x76, 0x6f, 0x65, 0x62, 0x6b, 0x6f, 0x6b, 0x67, 0x6b, 0x6e, 0x6a, 0x73, + 0x82, 0x7e, 0x79, 0x79, 0x87, 0x8e, 0x91, 0x8f, 0x86, 0x7d, 0x86, 0x89, 0x84, 0x85, 0x89, 0x89, + 0x83, 0x78, 0x72, 0x77, 0x77, 0x7a, 0x7e, 0x88, 0x85, 0x85, 0x8b, 0x86, 0x80, 0x7b, 0x78, 0x72, + 0x65, 0x68, 0x6d, 0x6f, 0x78, 0x7b, 0x71, 0x7a, 0x86, 0x89, 0x89, 0x81, 0x82, 0x89, 0x93, 0x8f, + 0x8b, 0x8c, 0x88, 0x8e, 0x91, 0x86, 0x8b, 0x8f, 0x8a, 0x87, 0x86, 0x8a, 0x8e, 0x8e, 0x8b, 0x87, + 0x87, 0x80, 0x81, 0x8c, 0x9e, 0x9c, 0x8f, 0x7d, 0x7a, 0x74, 0x6f, 0x7a, 0x7a, 0x71, 0x66, 0x62, + 0x70, 0x7c, 0x80, 0x81, 0x75, 0x6e, 0x6c, 0x70, 0x79, 0x76, 0x7a, 0x7d, 0x78, 0x6d, 0x6a, 0x71, + 0x78, 0x7e, 0x7c, 0x75, 0x6f, 0x72, 0x72, 0x71, 0x74, 0x74, 0x7c, 0x7d, 0x83, 0x80, 0x74, 0x76, + 0x71, 0x70, 0x6c, 0x65, 0x67, 0x6b, 0x64, 0x5a, 0x5e, 0x62, 0x70, 0x7d, 0x7a, 0x75, 0x72, 0x6e, + 0x72, 0x84, 0x8d, 0x8b, 0x8d, 0x8f, 0x80, 0x77, 0x7e, 0x8e, 0x8f, 0x84, 0x7e, 0x92, 0x98, 0x8c, + 0x87, 0x83, 0x7b, 0x73, 0x7b, 0x8a, 0x85, 0x82, 0x87, 0x8a, 0x89, 0x74, 0x66, 0x76, 0x8f, 0x90, + 0x84, 0x71, 0x79, 0x96, 0x9c, 0x8d, 0x83, 0x89, 0x88, 0x7e, 0x89, 0x9d, 0x98, 0x93, 0x8e, 0x89, + 0x83, 0x7b, 0x7c, 0x88, 0x84, 0x83, 0x84, 0x87, 0x92, 0x91, 0x8a, 0x99, 0x97, 0x93, 0x99, 0x85, + 0x7f, 0x85, 0x80, 0x80, 0x76, 0x79, 0x87, 0x89, 0x7d, 0x6a, 0x6b, 0x81, 0x91, 0x93, 0x8a, 0x7e, + 0x6f, 0x6e, 0x74, 0x70, 0x7d, 0x88, 0x82, 0x80, 0x79, 0x6a, 0x6f, 0x72, 0x76, 0x7d, 0x7a, 0x75, + 0x7c, 0x84, 0x83, 0x7d, 0x7a, 0x81, 0x81, 0x89, 0x8c, 0x85, 0x8a, 0x81, 0x73, 0x67, 0x65, 0x66, + 0x5b, 0x5d, 0x6a, 0x72, 0x7e, 0x8d, 0x92, 0x88, 0x82, 0x8b, 0x92, 0x94, 0x8c, 0x86, 0x8a, 0x88, + 0x91, 0x93, 0x85, 0x7c, 0x83, 0x7b, 0x75, 0x7c, 0x80, 0x86, 0x84, 0x86, 0x85, 0x81, 0x7c, 0x77, + 0x83, 0x88, 0x88, 0x85, 0x85, 0x80, 0x6d, 0x77, 0x8d, 0x88, 0x7e, 0x79, 0x74, 0x79, 0x85, 0x8e, + 0x91, 0x8c, 0x8d, 0x97, 0x94, 0x96, 0x8b, 0x93, 0xa9, 0xa3, 0x99, 0x92, 0x83, 0x76, 0x6d, 0x7b, + 0x85, 0x89, 0x88, 0x8e, 0x89, 0x7e, 0x82, 0x81, 0x8d, 0x94, 0x85, 0x80, 0x7c, 0x73, 0x6f, 0x72, + 0x7a, 0x78, 0x79, 0x7b, 0x7a, 0x76, 0x7d, 0x7d, 0x76, 0x6f, 0x6c, 0x6c, 0x67, 0x63, 0x72, 0x71, + 0x72, 0x7e, 0x7b, 0x66, 0x5d, 0x75, 0x86, 0x80, 0x73, 0x72, 0x6c, 0x67, 0x64, 0x69, 0x78, 0x78, + 0x71, 0x7d, 0x7e, 0x6e, 0x59, 0x54, 0x5c, 0x5b, 0x5e, 0x64, 0x5f, 0x54, 0x53, 0x5f, 0x67, 0x7a, + 0x7e, 0x76, 0x70, 0x81, 0x87, 0x80, 0x7e, 0x83, 0x80, 0x77, 0x78, 0x88, 0x84, 0x85, 0x92, 0x97, + 0x8e, 0x81, 0x8d, 0x89, 0x8b, 0x8a, 0x8e, 0x8c, 0x85, 0x83, 0x84, 0x7e, 0x8b, 0x8c, 0x84, 0x7a, + 0x72, 0x6d, 0x6e, 0x73, 0x6e, 0x6e, 0x79, 0x87, 0x94, 0x95, 0x93, 0x90, 0x89, 0x8f, 0x96, 0xa1, + 0xa3, 0xa1, 0x92, 0x84, 0x86, 0x81, 0x81, 0x88, 0x88, 0x82, 0x88, 0x93, 0x93, 0x8a, 0x7c, 0x78, + 0x8b, 0x97, 0xa4, 0xae, 0xa3, 0x98, 0x8c, 0x83, 0x7c, 0x74, 0x7d, 0x89, 0x82, 0x7d, 0x83, 0x83, + 0x7e, 0x87, 0x8b, 0x83, 0x76, 0x78, 0x81, 0x87, 0x81, 0x80, 0x84, 0x76, 0x6a, 0x6f, 0x71, 0x75, + 0x80, 0x82, 0x81, 0x79, 0x7b, 0x80, 0x7c, 0x7c, 0x80, 0x80, 0x83, 0x8e, 0x8e, 0x79, 0x7c, 0x78, + 0x7c, 0x73, 0x68, 0x6d, 0x6c, 0x6e, 0x6e, 0x66, 0x5d, 0x6b, 0x8b, 0x8e, 0x7e, 0x76, 0x80, 0x81, + 0x87, 0x91, 0x8d, 0x84, 0x80, 0x7c, 0x83, 0x95, 0x97, 0x9f, 0x9c, 0x84, 0x85, 0x81, 0x7a, 0x82, + 0x80, 0x85, 0x84, 0x7c, 0x88, 0x99, 0x96, 0x8f, 0x8b, 0x84, 0x76, 0x6b, 0x77, 0x83, 0x86, 0x87, + 0x83, 0x7c, 0x79, 0x8a, 0x91, 0x90, 0x87, 0x84, 0x9a, 0x96, 0x88, 0x85, 0x7a, 0x6f, 0x70, 0x74, + 0x84, 0x8c, 0x80, 0x7e, 0x85, 0x7b, 0x81, 0x85, 0x81, 0x77, 0x80, 0x83, 0x7b, 0x7c, 0x6e, 0x6e, + 0x75, 0x72, 0x70, 0x72, 0x7d, 0x84, 0x8d, 0x8c, 0x69, 0x5c, 0x68, 0x6f, 0x77, 0x76, 0x75, 0x76, + 0x70, 0x6d, 0x7b, 0x7e, 0x6b, 0x5c, 0x5c, 0x66, 0x5c, 0x56, 0x63, 0x69, 0x6a, 0x60, 0x5b, 0x68, + 0x6b, 0x6a, 0x70, 0x77, 0x82, 0x9c, 0x91, 0x74, 0x73, 0x5b, 0x50, 0x59, 0x5b, 0x66, 0x6e, 0x69, + 0x73, 0x7c, 0x79, 0x73, 0x7b, 0x89, 0x84, 0x83, 0x93, 0x9b, 0x9b, 0x9a, 0x94, 0x88, 0x8c, 0x93, + 0x9d, 0x9e, 0x94, 0x97, 0x93, 0x88, 0x83, 0x87, 0x77, 0x7c, 0x8e, 0x90, 0x95, 0x91, 0xa7, 0xb1, + 0xa2, 0x8e, 0x82, 0x87, 0x7a, 0x77, 0x87, 0x86, 0x83, 0x7e, 0x72, 0x74, 0x7b, 0x78, 0x8f, 0xa0, + 0xa4, 0xb2, 0xb4, 0xa1, 0x91, 0x88, 0x8c, 0x82, 0x77, 0x83, 0x88, 0x78, 0x77, 0x90, 0x95, 0x8e, + 0x81, 0x75, 0x72, 0x76, 0x77, 0x73, 0x82, 0x9b, 0x95, 0x85, 0x7c, 0x74, 0x6a, 0x69, 0x6f, 0x81, + 0x89, 0x7d, 0x71, 0x65, 0x6c, 0x6b, 0x63, 0x64, 0x6f, 0x7c, 0x78, 0x7c, 0x8b, 0x93, 0x90, 0x87, + 0x85, 0x85, 0x84, 0x75, 0x6c, 0x72, 0x7b, 0x7b, 0x6d, 0x6f, 0x77, 0x7c, 0x88, 0x95, 0x9a, 0x97, + 0x96, 0x83, 0x74, 0x71, 0x72, 0x72, 0x66, 0x6a, 0x74, 0x6f, 0x74, 0x7b, 0x81, 0x81, 0x77, 0x78, + 0x84, 0x85, 0x7d, 0x88, 0x90, 0x8b, 0x8a, 0x89, 0x83, 0x81, 0x88, 0x92, 0xa1, 0xa1, 0x95, 0x8e, + 0x81, 0x72, 0x73, 0x7a, 0x7d, 0x71, 0x75, 0x82, 0x8a, 0x93, 0x92, 0x8f, 0x7e, 0x70, 0x6f, 0x70, + 0x6d, 0x71, 0x78, 0x76, 0x74, 0x75, 0x75, 0x6e, 0x6e, 0x72, 0x7d, 0x8b, 0x89, 0x85, 0x7e, 0x76, + 0x73, 0x79, 0x7a, 0x75, 0x75, 0x81, 0x8b, 0x90, 0x91, 0x95, 0x9b, 0x96, 0x92, 0x94, 0x8d, 0x85, + 0x86, 0x8b, 0x8f, 0x8c, 0x83, 0x7b, 0x77, 0x7b, 0x7d, 0x82, 0x7d, 0x71, 0x68, 0x65, 0x65, 0x6d, + 0x74, 0x71, 0x6c, 0x6e, 0x73, 0x78, 0x80, 0x81, 0x84, 0x85, 0x7d, 0x76, 0x73, 0x72, 0x75, 0x79, + 0x7a, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x83, 0x87, 0x88, 0x84, 0x81, 0x82, 0x7c, 0x75, 0x6e, 0x69, + 0x69, 0x68, 0x69, 0x6e, 0x71, 0x70, 0x70, 0x75, 0x75, 0x6d, 0x69, 0x68, 0x6b, 0x72, 0x7a, 0x7e, + 0x82, 0x84, 0x84, 0x84, 0x83, 0x83, 0x84, 0x84, 0x83, 0x79, 0x76, 0x7a, 0x82, 0x88, 0x8a, 0x8c, + 0x8f, 0x90, 0x90, 0x93, 0x96, 0x9e, 0xa0, 0x94, 0x8a, 0x85, 0x7c, 0x7c, 0x7e, 0x7a, 0x75, 0x70, + 0x74, 0x7e, 0x80, 0x7a, 0x78, 0x78, 0x77, 0x76, 0x77, 0x7a, 0x82, 0x84, 0x85, 0x83, 0x84, 0x89, + 0x8d, 0x90, 0x8e, 0x8c, 0x8d, 0x8c, 0x89, 0x85, 0x84, 0x85, 0x89, 0x8a, 0x8d, 0x8f, 0x90, 0x8d, + 0x85, 0x7e, 0x7d, 0x7e, 0x81, 0x7e, 0x7b, 0x76, 0x74, 0x7c, 0x80, 0x7b, 0x76, 0x70, 0x71, 0x78, + 0x7b, 0x7d, 0x81, 0x81, 0x7b, 0x74, 0x70, 0x72, 0x76, 0x7a, 0x7e, 0x80, 0x7d, 0x80, 0x84, 0x87, + 0x89, 0x88, 0x83, 0x81, 0x7d, 0x76, 0x77, 0x7d, 0x80, 0x7a, 0x78, 0x7b, 0x7c, 0x80, 0x81, 0x81, + 0x81, 0x85, 0x8d, 0x91, 0x90, 0x89, 0x84, 0x83, 0x84, 0x89, 0x89, 0x89, 0x8b, 0x8b, 0x8a, 0x87, + 0x85, 0x83, 0x82, 0x7c, 0x77, 0x79, 0x7e, 0x85, 0x86, 0x86, 0x8b, 0x8f, 0x91, 0x93, 0x91, 0x8f, + 0x8c, 0x83, 0x7a, 0x76, 0x75, 0x7a, 0x7d, 0x7d, 0x79, 0x74, 0x77, 0x7d, 0x83, 0x83, 0x80, 0x7c, + 0x7c, 0x80, 0x81, 0x85, 0x89, 0x8b, 0x89, 0x86, 0x83, 0x86, 0x8b, 0x8e, 0x90, 0x8d, 0x89, 0x87, + 0x86, 0x85, 0x85, 0x87, 0x8b, 0x8a, 0x87, 0x87, 0x87, 0x86, 0x80, 0x7c, 0x7d, 0x7b, 0x76, 0x72, + 0x6b, 0x62, 0x64, 0x6b, 0x75, 0x79, 0x75, 0x73, 0x72, 0x71, 0x76, 0x79, 0x7b, 0x82, 0x82, 0x7d, + 0x78, 0x74, 0x74, 0x74, 0x70, 0x6c, 0x67, 0x66, 0x66, 0x69, 0x6d, 0x6d, 0x6a, 0x66, 0x61, 0x5b, + 0x5d, 0x61, 0x62, 0x61, 0x5f, 0x63, 0x69, 0x6c, 0x6c, 0x69, 0x63, 0x61, 0x66, 0x6a, 0x6e, 0x6e, + 0x70, 0x72, 0x75, 0x79, 0x7d, 0x80, 0x85, 0x8a, 0x8b, 0x8c, 0x8b, 0x8f, 0x92, 0x91, 0x90, 0x8f, + 0x8f, 0x90, 0x8e, 0x8c, 0x8d, 0x8f, 0x8f, 0x91, 0x92, 0x8f, 0x8b, 0x86, 0x7e, 0x7d, 0x81, 0x83, + 0x85, 0x87, 0x84, 0x81, 0x81, 0x84, 0x8a, 0x8b, 0x89, 0x83, 0x7c, 0x7a, 0x7c, 0x81, 0x8a, 0x92, + 0x93, 0x91, 0x8d, 0x8f, 0x94, 0x96, 0x9b, 0x9b, 0x98, 0x98, 0x98, 0x99, 0x9b, 0x9b, 0x99, 0x98, + 0x95, 0x91, 0x8a, 0x83, 0x7d, 0x78, 0x7a, 0x7b, 0x78, 0x73, 0x71, 0x6f, 0x6f, 0x72, 0x79, 0x7c, + 0x7c, 0x80, 0x81, 0x80, 0x7d, 0x82, 0x83, 0x83, 0x81, 0x7d, 0x7c, 0x7b, 0x7c, 0x83, 0x86, 0x84, + 0x82, 0x81, 0x82, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8b, 0x88, 0x88, 0x89, 0x85, 0x80, 0x77, 0x74, + 0x76, 0x78, 0x78, 0x79, 0x79, 0x75, 0x74, 0x74, 0x79, 0x7c, 0x7a, 0x7b, 0x7c, 0x7e, 0x83, 0x86, + 0x88, 0x87, 0x84, 0x81, 0x80, 0x7a, 0x77, 0x78, 0x78, 0x7b, 0x80, 0x84, 0x86, 0x85, 0x85, 0x85, + 0x88, 0x89, 0x87, 0x86, 0x89, 0x8d, 0x88, 0x83, 0x81, 0x82, 0x81, 0x7c, 0x75, 0x71, 0x6f, 0x6c, + 0x6c, 0x6d, 0x6f, 0x6b, 0x63, 0x60, 0x64, 0x6a, 0x72, 0x78, 0x7c, 0x80, 0x80, 0x7e, 0x7e, 0x83, + 0x87, 0x8b, 0x87, 0x85, 0x82, 0x83, 0x86, 0x87, 0x8a, 0x8a, 0x89, 0x88, 0x85, 0x85, 0x82, 0x7c, + 0x76, 0x77, 0x7a, 0x7a, 0x7a, 0x78, 0x75, 0x72, 0x72, 0x73, 0x72, 0x73, 0x70, 0x69, 0x68, 0x6c, + 0x71, 0x74, 0x75, 0x74, 0x73, 0x70, 0x6e, 0x72, 0x75, 0x76, 0x7a, 0x79, 0x76, 0x75, 0x76, 0x79, + 0x79, 0x74, 0x6f, 0x6d, 0x6b, 0x6f, 0x71, 0x72, 0x72, 0x70, 0x76, 0x7a, 0x79, 0x7c, 0x7a, 0x78, + 0x7d, 0x83, 0x8a, 0x8f, 0x8e, 0x8a, 0x86, 0x80, 0x82, 0x8a, 0x8c, 0x8c, 0x89, 0x88, 0x89, 0x89, + 0x89, 0x8b, 0x8b, 0x88, 0x8b, 0x8f, 0x94, 0x9a, 0x9c, 0x9f, 0x9d, 0x9a, 0x98, 0x94, 0x92, 0x90, + 0x8a, 0x87, 0x84, 0x82, 0x88, 0x8b, 0x88, 0x84, 0x81, 0x80, 0x82, 0x85, 0x85, 0x84, 0x7c, 0x73, + 0x79, 0x81, 0x86, 0x88, 0x86, 0x82, 0x7e, 0x7b, 0x78, 0x76, 0x79, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, + 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x82, 0x85, 0x87, 0x86, 0x81, 0x7c, 0x7c, 0x7a, 0x78, 0x75, + 0x71, 0x71, 0x73, 0x81, 0x8a, 0x8b, 0x86, 0x81, 0x7e, 0x81, 0x8e, 0x95, 0x93, 0x90, 0x8f, 0x8b, + 0x87, 0x87, 0x86, 0x84, 0x82, 0x80, 0x79, 0x77, 0x78, 0x78, 0x77, 0x75, 0x75, 0x74, 0x70, 0x6c, + 0x6e, 0x6f, 0x6e, 0x6d, 0x6f, 0x73, 0x73, 0x75, 0x79, 0x77, 0x76, 0x75, 0x78, 0x7b, 0x7c, 0x7c, + 0x7e, 0x7b, 0x7a, 0x86, 0x8b, 0x8f, 0x8f, 0x8d, 0x8a, 0x83, 0x82, 0x85, 0x85, 0x83, 0x83, 0x84, + 0x85, 0x86, 0x88, 0x88, 0x80, 0x7d, 0x7e, 0x7d, 0x7c, 0x7e, 0x80, 0x7d, 0x7a, 0x79, 0x7d, 0x81, + 0x80, 0x7d, 0x7d, 0x78, 0x70, 0x72, 0x75, 0x74, 0x71, 0x6d, 0x6d, 0x6d, 0x6c, 0x73, 0x74, 0x78, + 0x82, 0x83, 0x82, 0x8d, 0x91, 0x95, 0x94, 0x92, 0x92, 0x91, 0x95, 0x9a, 0x9e, 0x9d, 0x9b, 0x96, + 0x92, 0x91, 0x8d, 0x83, 0x7d, 0x80, 0x87, 0x87, 0x85, 0x85, 0x76, 0x6d, 0x6f, 0x73, 0x7a, 0x7d, + 0x80, 0x7c, 0x7b, 0x7c, 0x7a, 0x77, 0x6f, 0x6f, 0x6f, 0x73, 0x7e, 0x83, 0x85, 0x89, 0x89, 0x85, + 0x81, 0x74, 0x71, 0x77, 0x81, 0x86, 0x88, 0x85, 0x81, 0x7a, 0x78, 0x77, 0x71, 0x6c, 0x6e, 0x70, + 0x71, 0x73, 0x74, 0x71, 0x69, 0x63, 0x6a, 0x69, 0x65, 0x68, 0x6f, 0x78, 0x82, 0x89, 0x8e, 0x8d, + 0x81, 0x78, 0x70, 0x66, 0x70, 0x75, 0x77, 0x7c, 0x84, 0x83, 0x7e, 0x83, 0x89, 0x87, 0x7d, 0x7b, + 0x7d, 0x76, 0x7e, 0x86, 0x82, 0x7e, 0x7e, 0x81, 0x8c, 0x90, 0x8d, 0x8b, 0x8a, 0x89, 0x85, 0x81, + 0x80, 0x81, 0x74, 0x73, 0x73, 0x6e, 0x68, 0x6b, 0x6e, 0x71, 0x77, 0x7a, 0x7c, 0x7c, 0x86, 0x8e, + 0x8f, 0x91, 0x93, 0x8b, 0x82, 0x84, 0x8c, 0x91, 0x91, 0x8e, 0x91, 0x95, 0x92, 0x90, 0x85, 0x7c, + 0x83, 0x88, 0x85, 0x8c, 0x89, 0x86, 0x84, 0x80, 0x7a, 0x80, 0x83, 0x7d, 0x76, 0x75, 0x7c, 0x7e, + 0x7e, 0x80, 0x81, 0x79, 0x6e, 0x6f, 0x75, 0x76, 0x86, 0x96, 0x9f, 0x9d, 0x95, 0x89, 0x86, 0x8f, + 0x94, 0x88, 0x84, 0x7c, 0x77, 0x76, 0x76, 0x75, 0x75, 0x79, 0x82, 0x85, 0x86, 0x87, 0x83, 0x7b, + 0x85, 0x93, 0x90, 0x81, 0x80, 0x82, 0x79, 0x77, 0x7c, 0x87, 0x8d, 0x8c, 0x85, 0x7d, 0x78, 0x73, + 0x6f, 0x71, 0x78, 0x78, 0x72, 0x74, 0x7b, 0x82, 0x89, 0x8b, 0x89, 0x81, 0x78, 0x7b, 0x82, 0x7b, + 0x75, 0x72, 0x70, 0x6f, 0x76, 0x78, 0x7a, 0x82, 0x8f, 0x9a, 0x90, 0x7a, 0x6e, 0x73, 0x6d, 0x67, + 0x71, 0x7b, 0x7e, 0x80, 0x7d, 0x77, 0x6e, 0x76, 0x8e, 0x8e, 0x84, 0x7e, 0x86, 0x86, 0x83, 0x83, + 0x80, 0x7e, 0x84, 0x8e, 0x91, 0x90, 0x9c, 0xa0, 0x9c, 0x9c, 0x98, 0x92, 0x87, 0x7b, 0x72, 0x6b, + 0x6a, 0x6d, 0x7d, 0x73, 0x71, 0x74, 0x77, 0x73, 0x61, 0x67, 0x7b, 0x78, 0x75, 0x6f, 0x66, 0x70, + 0x83, 0x80, 0x7b, 0x72, 0x66, 0x70, 0x7d, 0x7d, 0x77, 0x75, 0x6f, 0x68, 0x67, 0x5f, 0x50, 0x5a, + 0x69, 0x6a, 0x63, 0x66, 0x74, 0x7e, 0x82, 0x86, 0x7e, 0x73, 0x6d, 0x6f, 0x7b, 0x74, 0x67, 0x6f, + 0x73, 0x71, 0x77, 0x86, 0x8e, 0x80, 0x87, 0x8d, 0x8d, 0xa1, 0x9e, 0x93, 0x88, 0x7e, 0x7d, 0x88, + 0x8e, 0x85, 0x81, 0x87, 0x8d, 0x8e, 0x89, 0x86, 0x89, 0x87, 0x7d, 0x71, 0x6e, 0x75, 0x86, 0x96, + 0x9a, 0x96, 0x8f, 0x8c, 0x8d, 0x93, 0x92, 0x85, 0x85, 0x83, 0x7d, 0x7b, 0x6f, 0x6e, 0x7c, 0x77, + 0x75, 0x72, 0x83, 0x94, 0x97, 0x9a, 0x9a, 0x98, 0x94, 0x99, 0x96, 0x8d, 0x95, 0x9b, 0x94, 0x85, + 0x87, 0x91, 0x99, 0x91, 0x86, 0x83, 0x88, 0x8b, 0x8a, 0x83, 0x7c, 0x6d, 0x64, 0x82, 0x88, 0x7c, + 0x74, 0x75, 0x75, 0x76, 0x81, 0x82, 0x83, 0x87, 0x7e, 0x6b, 0x66, 0x7e, 0x92, 0x94, 0x8f, 0x8a, + 0x88, 0x81, 0x7c, 0x93, 0xa4, 0x98, 0x8e, 0x84, 0x70, 0x63, 0x5d, 0x63, 0x6e, 0x69, 0x6a, 0x72, + 0x80, 0x81, 0x79, 0x6e, 0x68, 0x70, 0x7e, 0x73, 0x5d, 0x64, 0x77, 0x7b, 0x7c, 0x7c, 0x83, 0x89, + 0x82, 0x7c, 0x7c, 0x85, 0x87, 0x85, 0x85, 0x85, 0x76, 0x68, 0x65, 0x6e, 0x81, 0x8d, 0x89, 0x83, + 0x81, 0x87, 0x88, 0x86, 0x83, 0x87, 0x82, 0x71, 0x6e, 0x83, 0x8c, 0x85, 0x7c, 0x7e, 0x8b, 0x88, + 0x76, 0x6c, 0x65, 0x61, 0x60, 0x5c, 0x5c, 0x62, 0x6b, 0x6e, 0x70, 0x75, 0x81, 0x8b, 0x92, 0xa1, + 0x9d, 0x8e, 0x8a, 0x8b, 0x8b, 0x89, 0x8e, 0x92, 0x94, 0x99, 0x9a, 0x93, 0x86, 0x82, 0x88, 0x94, + 0xa9, 0xa8, 0x9e, 0x97, 0x8e, 0x7c, 0x6b, 0x66, 0x74, 0x7a, 0x72, 0x6e, 0x72, 0x75, 0x6a, 0x5f, + 0x5f, 0x63, 0x68, 0x70, 0x68, 0x6b, 0x7e, 0x82, 0x84, 0x85, 0x7d, 0x78, 0x79, 0x81, 0x8e, 0x8f, + 0x88, 0x81, 0x7b, 0x7b, 0x69, 0x5e, 0x60, 0x5c, 0x61, 0x6c, 0x6e, 0x6f, 0x7b, 0x87, 0x87, 0x88, + 0x93, 0x94, 0x7d, 0x6e, 0x6b, 0x6c, 0x6b, 0x78, 0x8d, 0x8d, 0x87, 0x8b, 0x8f, 0x89, 0x7d, 0x7c, + 0x7c, 0x7e, 0x82, 0x85, 0x87, 0x87, 0x81, 0x7a, 0x76, 0x81, 0x89, 0x92, 0x97, 0x95, 0x97, 0x93, + 0x89, 0x86, 0x81, 0x85, 0x8e, 0x8c, 0x8d, 0x93, 0x94, 0x92, 0x95, 0x9d, 0x9d, 0x91, 0x87, 0x7e, + 0x78, 0x76, 0x75, 0x74, 0x6e, 0x6a, 0x7c, 0x8d, 0x8b, 0x89, 0x86, 0x7a, 0x78, 0x80, 0x80, 0x72, + 0x72, 0x7b, 0x87, 0x91, 0x87, 0x80, 0x84, 0x84, 0x87, 0x9a, 0x98, 0x8d, 0x7b, 0x74, 0x77, 0x75, + 0x69, 0x6d, 0x7b, 0x71, 0x6a, 0x6c, 0x6d, 0x63, 0x6a, 0x80, 0x85, 0x87, 0x85, 0x7d, 0x74, 0x79, + 0x8e, 0x91, 0x87, 0x85, 0x8f, 0x8f, 0x8f, 0x86, 0x89, 0x8a, 0x79, 0x6d, 0x72, 0x70, 0x6c, 0x6f, + 0x7a, 0x7d, 0x71, 0x6a, 0x6d, 0x6b, 0x6e, 0x73, 0x78, 0x75, 0x7a, 0x83, 0x7c, 0x73, 0x73, 0x78, + 0x75, 0x75, 0x7d, 0x82, 0x76, 0x6e, 0x82, 0x9a, 0x9c, 0x9c, 0x9a, 0x8f, 0x85, 0x84, 0x88, 0x8a, + 0x82, 0x70, 0x66, 0x6f, 0x6d, 0x6b, 0x75, 0x77, 0x79, 0x83, 0x81, 0x7e, 0x7c, 0x7e, 0x81, 0x85, + 0x84, 0x7c, 0x7a, 0x89, 0x9a, 0x8c, 0x82, 0x81, 0x71, 0x69, 0x67, 0x73, 0x7a, 0x84, 0x8c, 0x8c, + 0x79, 0x72, 0x8a, 0x9b, 0xa5, 0xa6, 0xa2, 0xa5, 0xa1, 0x97, 0x9b, 0x9e, 0x99, 0x91, 0x91, 0x93, + 0x92, 0x9b, 0x9e, 0x8b, 0x7c, 0x86, 0x7b, 0x72, 0x76, 0x74, 0x77, 0x6d, 0x6f, 0x6b, 0x63, 0x57, + 0x51, 0x5e, 0x6a, 0x6e, 0x71, 0x77, 0x6d, 0x68, 0x65, 0x5c, 0x69, 0x7b, 0x83, 0x82, 0x7e, 0x79, + 0x79, 0x83, 0x86, 0x86, 0x84, 0x6e, 0x58, 0x52, 0x67, 0x7c, 0x7c, 0x70, 0x6c, 0x62, 0x51, 0x52, + 0x5e, 0x60, 0x63, 0x6a, 0x79, 0x75, 0x60, 0x5b, 0x63, 0x6e, 0x75, 0x6d, 0x6e, 0x79, 0x87, 0xa8, + 0xb8, 0x9c, 0x92, 0x8c, 0x8f, 0x8a, 0x8c, 0x91, 0x9d, 0xa0, 0xa4, 0xaf, 0xa8, 0x8f, 0x87, 0x8d, + 0x9d, 0xa5, 0xa8, 0x9c, 0x8e, 0x8a, 0x88, 0x89, 0x97, 0x99, 0x93, 0x95, 0x86, 0x8d, 0xa3, 0x92, + 0x82, 0x80, 0x71, 0x62, 0x66, 0x70, 0x79, 0x83, 0x84, 0x88, 0x80, 0x6e, 0x68, 0x86, 0x9a, 0x9c, + 0x94, 0x8b, 0x83, 0x7b, 0x73, 0x6f, 0x71, 0x81, 0x89, 0x8f, 0x95, 0x8f, 0x90, 0x8f, 0x91, 0x94, + 0x8d, 0x70, 0x68, 0x78, 0x7c, 0x7e, 0x7d, 0x81, 0x7e, 0x6c, 0x5a, 0x55, 0x5a, 0x64, 0x6c, 0x6e, + 0x6e, 0x6f, 0x6b, 0x63, 0x68, 0x72, 0x74, 0x7b, 0x8c, 0x92, 0x9f, 0xab, 0xa0, 0x92, 0x89, 0x80, + 0x6e, 0x64, 0x72, 0x7b, 0x79, 0x7c, 0x8a, 0x90, 0x85, 0x71, 0x75, 0x82, 0x8c, 0x8a, 0x7e, 0x7d, + 0x80, 0x7c, 0x7a, 0x85, 0x8a, 0x82, 0x81, 0x84, 0x8c, 0x92, 0x8e, 0x85, 0x7b, 0x75, 0x6d, 0x6b, + 0x6d, 0x75, 0x82, 0x7d, 0x7c, 0x82, 0x87, 0x85, 0x82, 0x89, 0x8c, 0x8e, 0x87, 0x80, 0x80, 0x81, + 0x80, 0x7c, 0x7a, 0x7a, 0x7d, 0x7d, 0x7d, 0x7d, 0x7a, 0x7a, 0x79, 0x7a, 0x79, 0x75, 0x72, 0x72, + 0x76, 0x7a, 0x7b, 0x80, 0x7d, 0x79, 0x75, 0x74, 0x79, 0x7d, 0x82, 0x7e, 0x7a, 0x79, 0x7d, 0x84, + 0x88, 0x86, 0x82, 0x7e, 0x7e, 0x87, 0x95, 0x99, 0x97, 0x93, 0x8e, 0x8b, 0x89, 0x89, 0x85, 0x7b, + 0x74, 0x72, 0x72, 0x73, 0x77, 0x78, 0x77, 0x78, 0x79, 0x7a, 0x76, 0x75, 0x77, 0x77, 0x74, 0x71, + 0x71, 0x72, 0x70, 0x6f, 0x6e, 0x6e, 0x6f, 0x72, 0x73, 0x71, 0x70, 0x6e, 0x6e, 0x6f, 0x72, 0x76, + 0x7d, 0x7e, 0x80, 0x86, 0x87, 0x87, 0x84, 0x85, 0x85, 0x7c, 0x79, 0x79, 0x7b, 0x82, 0x82, 0x80, + 0x82, 0x80, 0x7d, 0x81, 0x85, 0x8b, 0x90, 0x8e, 0x89, 0x8b, 0x90, 0x91, 0x91, 0x8f, 0x8c, 0x8d, + 0x8f, 0x92, 0x92, 0x8c, 0x86, 0x83, 0x83, 0x83, 0x82, 0x81, 0x80, 0x81, 0x83, 0x86, 0x87, 0x87, + 0x87, 0x86, 0x84, 0x7d, 0x7a, 0x83, 0x8c, 0x8f, 0x90, 0x8b, 0x83, 0x7e, 0x7c, 0x7e, 0x83, 0x84, + 0x84, 0x80, 0x7d, 0x80, 0x84, 0x82, 0x7c, 0x79, 0x79, 0x7b, 0x7e, 0x81, 0x7d, 0x79, 0x78, 0x76, + 0x74, 0x78, 0x7c, 0x80, 0x80, 0x7b, 0x79, 0x79, 0x77, 0x77, 0x74, 0x70, 0x70, 0x73, 0x7c, 0x82, + 0x81, 0x7b, 0x77, 0x7a, 0x7a, 0x7a, 0x7e, 0x7c, 0x7b, 0x79, 0x7a, 0x7c, 0x80, 0x82, 0x7e, 0x7d, + 0x82, 0x87, 0x8c, 0x8c, 0x89, 0x86, 0x81, 0x7b, 0x7b, 0x7a, 0x7c, 0x86, 0x8a, 0x89, 0x80, 0x77, + 0x76, 0x76, 0x76, 0x72, 0x6f, 0x6f, 0x6f, 0x6f, 0x75, 0x7a, 0x79, 0x7a, 0x80, 0x81, 0x7b, 0x78, + 0x7d, 0x83, 0x84, 0x83, 0x84, 0x84, 0x81, 0x80, 0x7e, 0x7d, 0x86, 0x8d, 0x8d, 0x89, 0x88, 0x88, + 0x85, 0x83, 0x83, 0x85, 0x87, 0x87, 0x87, 0x85, 0x82, 0x80, 0x7e, 0x7c, 0x77, 0x71, 0x6f, 0x72, + 0x74, 0x75, 0x72, 0x74, 0x75, 0x74, 0x75, 0x78, 0x7e, 0x88, 0x91, 0x8e, 0x89, 0x86, 0x86, 0x8c, + 0x90, 0x91, 0x94, 0x97, 0x9a, 0x9a, 0x9a, 0x98, 0x96, 0x94, 0x93, 0x93, 0x98, 0x97, 0x95, 0x92, + 0x8c, 0x86, 0x84, 0x83, 0x82, 0x7d, 0x77, 0x76, 0x78, 0x76, 0x72, 0x70, 0x71, 0x6f, 0x6b, 0x63, + 0x5f, 0x64, 0x6a, 0x6b, 0x6a, 0x6b, 0x6d, 0x70, 0x73, 0x72, 0x6e, 0x6d, 0x6f, 0x72, 0x75, 0x75, + 0x74, 0x72, 0x75, 0x78, 0x79, 0x7c, 0x84, 0x85, 0x82, 0x7e, 0x7d, 0x7a, 0x7a, 0x7a, 0x73, 0x6c, + 0x6b, 0x70, 0x73, 0x75, 0x7b, 0x80, 0x80, 0x7b, 0x75, 0x74, 0x7a, 0x7d, 0x79, 0x76, 0x7c, 0x81, + 0x82, 0x86, 0x89, 0x8a, 0x90, 0x96, 0x99, 0x95, 0x8d, 0x89, 0x8a, 0x8c, 0x8b, 0x8a, 0x8b, 0x8c, + 0x8c, 0x8d, 0x8a, 0x85, 0x83, 0x82, 0x81, 0x7e, 0x79, 0x74, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7b, + 0x7a, 0x77, 0x78, 0x7e, 0x85, 0x81, 0x79, 0x78, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x7a, 0x80, + 0x82, 0x84, 0x86, 0x89, 0x88, 0x84, 0x86, 0x8d, 0x8f, 0x8d, 0x8a, 0x8a, 0x8c, 0x8b, 0x8c, 0x8a, + 0x87, 0x86, 0x81, 0x7c, 0x7d, 0x82, 0x84, 0x83, 0x82, 0x7e, 0x79, 0x76, 0x79, 0x81, 0x83, 0x81, + 0x84, 0x8a, 0x88, 0x85, 0x82, 0x81, 0x82, 0x82, 0x81, 0x7d, 0x7c, 0x80, 0x82, 0x83, 0x80, 0x85, + 0x8a, 0x8b, 0x86, 0x7e, 0x7b, 0x7d, 0x7e, 0x80, 0x7e, 0x79, 0x74, 0x74, 0x73, 0x74, 0x7b, 0x81, + 0x86, 0x85, 0x84, 0x87, 0x87, 0x86, 0x83, 0x7a, 0x79, 0x7d, 0x82, 0x86, 0x89, 0x8a, 0x8a, 0x8d, + 0x8d, 0x87, 0x83, 0x81, 0x7d, 0x7d, 0x80, 0x81, 0x83, 0x85, 0x85, 0x82, 0x7e, 0x7e, 0x7e, 0x7c, + 0x78, 0x73, 0x6d, 0x6b, 0x6b, 0x67, 0x65, 0x69, 0x70, 0x77, 0x7a, 0x7c, 0x7b, 0x7b, 0x83, 0x87, + 0x85, 0x84, 0x84, 0x82, 0x82, 0x85, 0x86, 0x8a, 0x8d, 0x92, 0x93, 0x93, 0x92, 0x8c, 0x88, 0x86, + 0x86, 0x89, 0x88, 0x84, 0x80, 0x7c, 0x7a, 0x7b, 0x7c, 0x7a, 0x7a, 0x77, 0x73, 0x6f, 0x6b, 0x69, + 0x6c, 0x72, 0x75, 0x71, 0x6a, 0x66, 0x6a, 0x70, 0x71, 0x71, 0x71, 0x6e, 0x6c, 0x6a, 0x6c, 0x6f, + 0x6f, 0x6d, 0x6c, 0x6c, 0x6a, 0x6c, 0x71, 0x73, 0x78, 0x81, 0x83, 0x81, 0x7e, 0x79, 0x75, 0x73, + 0x72, 0x77, 0x78, 0x75, 0x75, 0x76, 0x75, 0x76, 0x7e, 0x89, 0x8c, 0x8b, 0x88, 0x84, 0x85, 0x88, + 0x8c, 0x8c, 0x8a, 0x8b, 0x8c, 0x8f, 0x93, 0x96, 0x95, 0x94, 0x92, 0x94, 0x94, 0x93, 0x91, 0x90, + 0x90, 0x8d, 0x8c, 0x90, 0x90, 0x91, 0x93, 0x93, 0x92, 0x8c, 0x87, 0x83, 0x7b, 0x74, 0x71, 0x72, + 0x73, 0x78, 0x7e, 0x8a, 0x90, 0x8c, 0x8a, 0x8b, 0x8d, 0x8e, 0x8e, 0x8d, 0x90, 0x91, 0x8d, 0x8c, + 0x8c, 0x85, 0x81, 0x81, 0x84, 0x85, 0x82, 0x7d, 0x7a, 0x79, 0x76, 0x75, 0x78, 0x75, 0x72, 0x70, + 0x6e, 0x6d, 0x70, 0x70, 0x69, 0x6b, 0x74, 0x73, 0x6b, 0x68, 0x6c, 0x72, 0x76, 0x78, 0x74, 0x6b, + 0x68, 0x6e, 0x76, 0x7b, 0x79, 0x77, 0x78, 0x7b, 0x81, 0x82, 0x7d, 0x7c, 0x7d, 0x84, 0x87, 0x87, + 0x8a, 0x8f, 0x91, 0x92, 0x97, 0x9a, 0x96, 0x91, 0x8f, 0x8b, 0x87, 0x84, 0x81, 0x79, 0x73, 0x73, + 0x76, 0x74, 0x77, 0x7b, 0x7d, 0x81, 0x82, 0x7d, 0x77, 0x77, 0x79, 0x7d, 0x80, 0x80, 0x80, 0x83, + 0x87, 0x8a, 0x8c, 0x8a, 0x82, 0x7c, 0x86, 0x8b, 0x87, 0x84, 0x83, 0x81, 0x80, 0x82, 0x83, 0x82, + 0x84, 0x80, 0x79, 0x71, 0x6e, 0x6f, 0x6a, 0x64, 0x64, 0x5c, 0x5b, 0x60, 0x68, 0x71, 0x76, 0x77, + 0x78, 0x79, 0x7d, 0x83, 0x86, 0x84, 0x84, 0x84, 0x86, 0x8c, 0x90, 0x91, 0x91, 0x95, 0x9c, 0xa1, + 0xa2, 0x9d, 0x98, 0x98, 0x96, 0x90, 0x8d, 0x8d, 0x92, 0x8f, 0x87, 0x81, 0x84, 0x81, 0x7e, 0x7c, + 0x77, 0x6e, 0x66, 0x62, 0x65, 0x76, 0x82, 0x84, 0x81, 0x79, 0x6e, 0x6d, 0x6f, 0x70, 0x6f, 0x6e, + 0x72, 0x74, 0x76, 0x78, 0x72, 0x6d, 0x6d, 0x6b, 0x6e, 0x70, 0x71, 0x7b, 0x83, 0x87, 0x88, 0x85, + 0x85, 0x86, 0x82, 0x82, 0x80, 0x79, 0x75, 0x77, 0x7b, 0x78, 0x76, 0x7a, 0x79, 0x7b, 0x79, 0x87, + 0x8b, 0x80, 0x7d, 0x84, 0x8b, 0x8e, 0x92, 0x95, 0x90, 0x87, 0x8d, 0x99, 0x9c, 0x97, 0x93, 0x91, + 0x8f, 0x8e, 0x8f, 0x93, 0x96, 0x91, 0x8b, 0x89, 0x8b, 0x8d, 0x8b, 0x84, 0x79, 0x79, 0x77, 0x70, + 0x69, 0x68, 0x6b, 0x6a, 0x6a, 0x70, 0x71, 0x70, 0x61, 0x5c, 0x74, 0x7d, 0x74, 0x7e, 0x85, 0x7d, + 0x7a, 0x79, 0x78, 0x7c, 0x80, 0x79, 0x76, 0x75, 0x76, 0x7a, 0x76, 0x71, 0x75, 0x79, 0x74, 0x70, + 0x75, 0x81, 0x89, 0x88, 0x88, 0x88, 0x82, 0x82, 0x7e, 0x81, 0x84, 0x81, 0x80, 0x7c, 0x7b, 0x78, + 0x74, 0x74, 0x75, 0x7c, 0x85, 0x87, 0x8f, 0x98, 0x9b, 0x94, 0x8a, 0x87, 0x82, 0x84, 0x81, 0x82, + 0x8f, 0x99, 0x9b, 0x9a, 0x9a, 0x8d, 0x89, 0x8e, 0x83, 0x87, 0x8b, 0x82, 0x74, 0x6c, 0x6c, 0x74, + 0x7a, 0x76, 0x71, 0x69, 0x65, 0x68, 0x6a, 0x72, 0x7b, 0x7d, 0x75, 0x76, 0x7a, 0x7c, 0x8c, 0x8f, + 0x91, 0x9a, 0x99, 0x93, 0x8d, 0x8c, 0x9d, 0x95, 0x85, 0x8c, 0x8f, 0x89, 0x89, 0x88, 0x83, 0x86, + 0x83, 0x79, 0x84, 0x8e, 0x8f, 0x8c, 0x8a, 0x8e, 0x88, 0x70, 0x62, 0x63, 0x5f, 0x5b, 0x5a, 0x60, + 0x70, 0x77, 0x75, 0x71, 0x6d, 0x79, 0x80, 0x74, 0x85, 0x89, 0x7b, 0x72, 0x72, 0x79, 0x7e, 0x88, + 0x8e, 0x89, 0x88, 0x91, 0x9c, 0x9c, 0x95, 0x8d, 0x88, 0x82, 0x86, 0x91, 0x93, 0x8f, 0x90, 0x90, + 0x82, 0x75, 0x6e, 0x64, 0x74, 0x7c, 0x6f, 0x70, 0x7b, 0x7a, 0x70, 0x69, 0x60, 0x6e, 0x76, 0x70, + 0x6c, 0x73, 0x78, 0x72, 0x72, 0x71, 0x6d, 0x71, 0x6b, 0x60, 0x68, 0x72, 0x76, 0x7d, 0x88, 0x85, + 0x81, 0x86, 0x8a, 0x92, 0x93, 0x87, 0x83, 0x8b, 0x84, 0x75, 0x71, 0x6b, 0x67, 0x64, 0x64, 0x6d, + 0x71, 0x72, 0x78, 0x73, 0x6c, 0x76, 0x8c, 0x92, 0x88, 0x86, 0x87, 0x89, 0x8a, 0x85, 0x81, 0x83, + 0x8d, 0x92, 0x8f, 0x8c, 0x89, 0x85, 0x86, 0x84, 0x7c, 0x79, 0x88, 0x93, 0x9a, 0x9c, 0x99, 0x94, + 0x8b, 0x8c, 0x88, 0x80, 0x7c, 0x7d, 0x79, 0x6b, 0x6d, 0x73, 0x72, 0x70, 0x6e, 0x69, 0x75, 0x91, + 0x99, 0x95, 0x8d, 0x79, 0x61, 0x6f, 0x7b, 0x75, 0x81, 0x8b, 0x8a, 0x84, 0x7d, 0x77, 0x74, 0x77, + 0x72, 0x6d, 0x72, 0x75, 0x79, 0x84, 0x84, 0x83, 0x83, 0x7e, 0x8c, 0x89, 0x7c, 0x76, 0x75, 0x85, + 0x81, 0x7a, 0x82, 0x8a, 0x8d, 0x8d, 0x81, 0x77, 0x8c, 0x98, 0x96, 0x8e, 0x81, 0x77, 0x81, 0x91, + 0x8e, 0x8c, 0x91, 0x88, 0x8d, 0x9c, 0x99, 0x96, 0x91, 0x92, 0x94, 0x8d, 0x83, 0x85, 0x97, 0x92, + 0x86, 0x78, 0x6d, 0x6e, 0x6c, 0x66, 0x60, 0x65, 0x6a, 0x65, 0x63, 0x64, 0x6c, 0x70, 0x6c, 0x5e, + 0x68, 0x87, 0x94, 0x9c, 0xa9, 0x9a, 0x83, 0x78, 0x87, 0x88, 0x84, 0x81, 0x8b, 0x8b, 0x7c, 0x7a, + 0x7a, 0x6d, 0x60, 0x67, 0x7e, 0x8b, 0x96, 0x95, 0x91, 0x87, 0x72, 0x7c, 0x8a, 0x79, 0x69, 0x5e, + 0x5c, 0x60, 0x65, 0x6e, 0x6f, 0x6d, 0x70, 0x65, 0x61, 0x7e, 0x98, 0x92, 0x88, 0x82, 0x81, 0x7c, + 0x6e, 0x70, 0x87, 0x8c, 0x8c, 0x98, 0xa3, 0x9f, 0x96, 0x86, 0x87, 0x8c, 0x89, 0x84, 0x84, 0x91, + 0x9c, 0x98, 0x92, 0x88, 0x84, 0x96, 0x94, 0x89, 0x8d, 0x92, 0x7a, 0x63, 0x5d, 0x65, 0x63, 0x54, + 0x4c, 0x60, 0x78, 0x82, 0x85, 0x8c, 0x89, 0x7e, 0x6f, 0x68, 0x64, 0x68, 0x72, 0x6f, 0x74, 0x87, + 0x88, 0x80, 0x74, 0x6b, 0x6e, 0x73, 0x88, 0x9f, 0x99, 0x8a, 0x7b, 0x74, 0x6e, 0x70, 0x72, 0x69, + 0x6f, 0x75, 0x71, 0x70, 0x77, 0x79, 0x7a, 0x86, 0x8d, 0x8c, 0x86, 0x89, 0x86, 0x7c, 0x7e, 0x8d, + 0x8c, 0x83, 0x84, 0x90, 0x8f, 0x9a, 0xa8, 0xa0, 0x96, 0x8d, 0x82, 0x7c, 0x7d, 0x77, 0x70, 0x7d, + 0x8d, 0x90, 0x8d, 0x91, 0x8b, 0x7b, 0x8d, 0x96, 0x83, 0x7a, 0x73, 0x71, 0x6f, 0x67, 0x67, 0x69, + 0x68, 0x6b, 0x76, 0x7c, 0x96, 0x97, 0x89, 0x90, 0x8f, 0x85, 0x75, 0x71, 0x6a, 0x57, 0x61, 0x72, + 0x81, 0x80, 0x81, 0x85, 0x85, 0x85, 0x80, 0x70, 0x6b, 0x7b, 0x87, 0x89, 0x82, 0x7a, 0x83, 0x83, + 0x7a, 0x7e, 0x8b, 0x99, 0x8c, 0x78, 0x7d, 0x8c, 0x8a, 0x80, 0x78, 0x71, 0x7b, 0x8e, 0x86, 0x7d, + 0x82, 0x86, 0x89, 0x88, 0x8c, 0x7d, 0x6f, 0x80, 0x9b, 0xa7, 0xa0, 0x9a, 0x96, 0x92, 0x8d, 0x88, + 0x80, 0x8d, 0x9b, 0x92, 0x88, 0x82, 0x79, 0x76, 0x72, 0x61, 0x4f, 0x51, 0x60, 0x5b, 0x56, 0x5a, + 0x63, 0x62, 0x5e, 0x63, 0x64, 0x71, 0x80, 0x8b, 0x9a, 0x9a, 0x8e, 0x85, 0x82, 0x88, 0x8c, 0x86, + 0x7a, 0x8a, 0x86, 0x7a, 0x75, 0x78, 0x77, 0x7c, 0x86, 0x88, 0x8f, 0x98, 0x8e, 0x88, 0x84, 0x80, + 0x81, 0x78, 0x70, 0x7a, 0x7e, 0x7c, 0x78, 0x7c, 0x80, 0x76, 0x6a, 0x5f, 0x61, 0x66, 0x87, 0xa6, + 0xa6, 0x93, 0x8b, 0x8b, 0x87, 0x85, 0x90, 0x92, 0x8f, 0x93, 0x96, 0x99, 0x96, 0x8f, 0x93, 0x90, + 0x7a, 0x75, 0x79, 0x82, 0x8d, 0x8d, 0x83, 0x76, 0x87, 0xa4, 0x9c, 0x89, 0x86, 0x8b, 0x7c, 0x62, + 0x5c, 0x62, 0x62, 0x60, 0x6d, 0x73, 0x6d, 0x79, 0x8b, 0x88, 0x75, 0x74, 0x77, 0x6c, 0x61, 0x60, + 0x61, 0x62, 0x63, 0x66, 0x77, 0x83, 0x82, 0x89, 0x8c, 0x90, 0x87, 0x80, 0x84, 0x86, 0x74, 0x6b, + 0x5f, 0x5f, 0x6e, 0x72, 0x73, 0x74, 0x6f, 0x65, 0x5c, 0x69, 0x7c, 0x89, 0x84, 0x85, 0x78, 0x6e, + 0x82, 0x95, 0x9a, 0x99, 0x90, 0x94, 0xa4, 0xa3, 0xa2, 0x9d, 0x8e, 0x92, 0x83, 0x77, 0x87, 0x8c, + 0x8a, 0x7c, 0x7b, 0x84, 0x92, 0x90, 0x8c, 0x8d, 0x91, 0xa0, 0xa1, 0x89, 0x6b, 0x60, 0x62, 0x64, + 0x5c, 0x5a, 0x6c, 0x7a, 0x8a, 0x96, 0x90, 0x8d, 0x7a, 0x87, 0xa4, 0xa3, 0x99, 0x93, 0x90, 0x8a, + 0x80, 0x74, 0x76, 0x82, 0x7a, 0x71, 0x6d, 0x87, 0x98, 0x88, 0x75, 0x72, 0x74, 0x76, 0x78, 0x80, + 0x86, 0x7c, 0x7e, 0x8b, 0x87, 0x84, 0x82, 0x74, 0x70, 0x74, 0x77, 0x6d, 0x68, 0x6c, 0x73, 0x70, + 0x62, 0x61, 0x77, 0x84, 0x8a, 0x96, 0x96, 0x90, 0x84, 0x7c, 0x85, 0x87, 0x8c, 0x8d, 0x8b, 0x81, + 0x7c, 0x8b, 0x8d, 0x88, 0x92, 0x95, 0x8a, 0x7e, 0x83, 0x87, 0x81, 0x84, 0x8d, 0x82, 0x76, 0x72, + 0x67, 0x5a, 0x54, 0x5f, 0x6c, 0x6f, 0x71, 0x70, 0x6d, 0x72, 0x81, 0x8a, 0x90, 0x8e, 0x91, 0x98, + 0x95, 0x8c, 0x87, 0x87, 0x8b, 0x92, 0x95, 0x93, 0x81, 0x6f, 0x71, 0x7d, 0x85, 0x86, 0x86, 0x81, + 0x7d, 0x7c, 0x81, 0x88, 0x99, 0x98, 0x83, 0x79, 0x71, 0x6b, 0x67, 0x60, 0x63, 0x6b, 0x73, 0x77, + 0x74, 0x6b, 0x6b, 0x6b, 0x76, 0x83, 0x81, 0x7d, 0x7e, 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, + 0x8f, 0x8e, 0x84, 0x7e, 0x87, 0x8d, 0x8b, 0x86, 0x84, 0x88, 0x8e, 0x8d, 0x8b, 0x8c, 0x89, 0x84, + 0x83, 0x7b, 0x77, 0x77, 0x74, 0x71, 0x70, 0x6c, 0x6d, 0x6f, 0x71, 0x73, 0x72, 0x73, 0x77, 0x81, + 0x87, 0x84, 0x7a, 0x6d, 0x64, 0x65, 0x67, 0x68, 0x6d, 0x73, 0x78, 0x79, 0x75, 0x78, 0x83, 0x86, + 0x82, 0x82, 0x87, 0x8b, 0x8a, 0x8a, 0x89, 0x87, 0x86, 0x88, 0x86, 0x84, 0x84, 0x87, 0x8c, 0x8b, + 0x86, 0x84, 0x82, 0x80, 0x80, 0x7e, 0x81, 0x85, 0x8c, 0x8f, 0x91, 0x8d, 0x89, 0x87, 0x85, 0x81, + 0x80, 0x7c, 0x78, 0x74, 0x72, 0x75, 0x7c, 0x80, 0x80, 0x7d, 0x7c, 0x80, 0x86, 0x8d, 0x8d, 0x84, + 0x7c, 0x78, 0x72, 0x70, 0x70, 0x72, 0x7b, 0x82, 0x7d, 0x7c, 0x7b, 0x80, 0x81, 0x7b, 0x7b, 0x81, + 0x84, 0x84, 0x80, 0x7e, 0x81, 0x81, 0x80, 0x7b, 0x78, 0x7a, 0x7e, 0x81, 0x82, 0x7d, 0x7a, 0x7a, + 0x79, 0x75, 0x73, 0x75, 0x7a, 0x83, 0x8b, 0x8f, 0x8c, 0x85, 0x83, 0x83, 0x81, 0x83, 0x87, 0x8b, + 0x8d, 0x86, 0x81, 0x82, 0x88, 0x90, 0x91, 0x8f, 0x91, 0x8e, 0x8b, 0x8b, 0x88, 0x85, 0x82, 0x7e, + 0x7d, 0x7b, 0x7c, 0x7e, 0x80, 0x7c, 0x7c, 0x7d, 0x7d, 0x80, 0x82, 0x7e, 0x7b, 0x79, 0x79, 0x79, + 0x79, 0x74, 0x6c, 0x68, 0x66, 0x65, 0x6a, 0x76, 0x7a, 0x78, 0x75, 0x71, 0x71, 0x77, 0x7a, 0x7a, + 0x7a, 0x7e, 0x85, 0x87, 0x8c, 0x93, 0x93, 0x90, 0x8f, 0x8b, 0x88, 0x87, 0x87, 0x85, 0x7e, 0x7b, + 0x7d, 0x82, 0x84, 0x85, 0x80, 0x7e, 0x84, 0x88, 0x8c, 0x8b, 0x88, 0x81, 0x78, 0x71, 0x6e, 0x70, + 0x72, 0x70, 0x6c, 0x69, 0x68, 0x6b, 0x76, 0x7e, 0x7a, 0x75, 0x71, 0x6e, 0x6f, 0x76, 0x80, 0x83, + 0x85, 0x89, 0x8a, 0x8a, 0x92, 0x9a, 0x9a, 0x98, 0x92, 0x8d, 0x8d, 0x8c, 0x87, 0x84, 0x84, 0x89, + 0x8d, 0x8e, 0x8b, 0x86, 0x82, 0x80, 0x7d, 0x79, 0x78, 0x76, 0x74, 0x74, 0x73, 0x77, 0x7a, 0x78, + 0x79, 0x77, 0x75, 0x79, 0x81, 0x85, 0x85, 0x87, 0x85, 0x7e, 0x77, 0x6d, 0x69, 0x6b, 0x70, 0x79, + 0x80, 0x7e, 0x7e, 0x82, 0x82, 0x84, 0x87, 0x8a, 0x89, 0x86, 0x88, 0x86, 0x82, 0x7c, 0x77, 0x74, + 0x74, 0x77, 0x7d, 0x7e, 0x79, 0x71, 0x6b, 0x68, 0x6a, 0x69, 0x68, 0x67, 0x6c, 0x70, 0x73, 0x7a, + 0x7d, 0x81, 0x85, 0x83, 0x84, 0x87, 0x85, 0x82, 0x85, 0x87, 0x86, 0x83, 0x83, 0x86, 0x8c, 0x90, + 0x93, 0x95, 0x99, 0x97, 0x92, 0x8b, 0x84, 0x80, 0x79, 0x75, 0x75, 0x79, 0x7d, 0x7d, 0x7a, 0x7b, + 0x81, 0x87, 0x86, 0x80, 0x77, 0x71, 0x70, 0x74, 0x78, 0x79, 0x77, 0x74, 0x73, 0x75, 0x79, 0x7c, + 0x7e, 0x83, 0x82, 0x81, 0x83, 0x83, 0x85, 0x87, 0x8a, 0x8c, 0x8b, 0x8c, 0x8e, 0x8c, 0x89, 0x8c, + 0x90, 0x8d, 0x89, 0x88, 0x88, 0x87, 0x86, 0x85, 0x87, 0x8b, 0x89, 0x85, 0x84, 0x84, 0x82, 0x82, + 0x87, 0x86, 0x80, 0x7c, 0x79, 0x77, 0x7a, 0x7b, 0x7b, 0x7a, 0x78, 0x79, 0x7c, 0x83, 0x8c, 0x91, + 0x8f, 0x8a, 0x87, 0x84, 0x85, 0x86, 0x85, 0x83, 0x7c, 0x74, 0x70, 0x71, 0x73, 0x75, 0x75, 0x76, + 0x78, 0x79, 0x7b, 0x79, 0x74, 0x73, 0x78, 0x7c, 0x7d, 0x84, 0x8b, 0x89, 0x88, 0x88, 0x86, 0x7e, + 0x79, 0x77, 0x76, 0x76, 0x77, 0x76, 0x72, 0x72, 0x77, 0x7e, 0x89, 0x8b, 0x8b, 0x8d, 0x8c, 0x8a, + 0x83, 0x75, 0x6d, 0x6b, 0x72, 0x7c, 0x80, 0x7d, 0x7a, 0x77, 0x75, 0x75, 0x74, 0x70, 0x65, 0x62, + 0x6a, 0x6f, 0x76, 0x7e, 0x82, 0x7e, 0x7a, 0x7b, 0x81, 0x87, 0x8a, 0x8a, 0x87, 0x81, 0x7c, 0x7b, + 0x78, 0x78, 0x7d, 0x83, 0x84, 0x84, 0x86, 0x86, 0x87, 0x87, 0x86, 0x82, 0x7d, 0x7e, 0x83, 0x87, + 0x86, 0x85, 0x85, 0x89, 0x8d, 0x8e, 0x8e, 0x8e, 0x8b, 0x8a, 0x88, 0x86, 0x82, 0x7a, 0x73, 0x6b, + 0x65, 0x66, 0x69, 0x69, 0x6b, 0x6a, 0x68, 0x6e, 0x76, 0x7c, 0x81, 0x83, 0x81, 0x82, 0x81, 0x80, + 0x82, 0x7c, 0x76, 0x71, 0x6e, 0x72, 0x76, 0x79, 0x7a, 0x77, 0x72, 0x6b, 0x67, 0x67, 0x65, 0x66, + 0x6a, 0x6c, 0x70, 0x7a, 0x87, 0x90, 0x9b, 0xa0, 0x9e, 0x9a, 0x97, 0x95, 0x93, 0x8f, 0x8f, 0x91, + 0x92, 0x96, 0x9d, 0xa4, 0xa3, 0x9f, 0x9f, 0x9e, 0x9a, 0x92, 0x8b, 0x84, 0x79, 0x73, 0x71, 0x71, + 0x75, 0x7b, 0x7d, 0x81, 0x8a, 0x94, 0x95, 0x90, 0x8a, 0x84, 0x81, 0x7c, 0x7b, 0x80, 0x88, 0x8a, + 0x84, 0x83, 0x81, 0x7d, 0x7b, 0x7a, 0x73, 0x6d, 0x6c, 0x6c, 0x71, 0x78, 0x7a, 0x79, 0x7a, 0x7c, + 0x80, 0x85, 0x87, 0x88, 0x86, 0x84, 0x85, 0x86, 0x87, 0x88, 0x86, 0x80, 0x7c, 0x7b, 0x78, 0x76, + 0x77, 0x7b, 0x7e, 0x84, 0x89, 0x8a, 0x8a, 0x85, 0x7e, 0x78, 0x72, 0x6d, 0x6b, 0x69, 0x67, 0x69, + 0x6e, 0x70, 0x73, 0x74, 0x7c, 0x84, 0x85, 0x86, 0x81, 0x81, 0x80, 0x7e, 0x7b, 0x73, 0x6e, 0x71, + 0x75, 0x79, 0x80, 0x80, 0x78, 0x74, 0x6f, 0x6d, 0x6f, 0x6c, 0x68, 0x66, 0x68, 0x6c, 0x74, 0x83, + 0x88, 0x88, 0x8b, 0x8e, 0x90, 0x91, 0x8e, 0x88, 0x83, 0x7d, 0x78, 0x7a, 0x7d, 0x7e, 0x87, 0x90, + 0x92, 0x94, 0x91, 0x8a, 0x8a, 0x88, 0x83, 0x80, 0x7b, 0x7a, 0x7a, 0x7a, 0x7c, 0x80, 0x80, 0x7c, + 0x7c, 0x7e, 0x7e, 0x7b, 0x78, 0x77, 0x7b, 0x83, 0x89, 0x88, 0x88, 0x8d, 0x92, 0x91, 0x8c, 0x87, + 0x84, 0x7c, 0x77, 0x7b, 0x81, 0x83, 0x87, 0x84, 0x80, 0x79, 0x77, 0x7d, 0x81, 0x83, 0x81, 0x7c, + 0x79, 0x7b, 0x80, 0x83, 0x85, 0x83, 0x82, 0x80, 0x7b, 0x7c, 0x7d, 0x7e, 0x7c, 0x79, 0x77, 0x79, + 0x7b, 0x7a, 0x7c, 0x7b, 0x79, 0x76, 0x73, 0x6e, 0x69, 0x69, 0x70, 0x78, 0x7e, 0x87, 0x8b, 0x8c, + 0x8a, 0x87, 0x89, 0x8e, 0x91, 0x93, 0x93, 0x8d, 0x84, 0x80, 0x79, 0x7a, 0x7c, 0x77, 0x6e, 0x6d, + 0x72, 0x73, 0x74, 0x72, 0x71, 0x71, 0x71, 0x76, 0x80, 0x8b, 0x90, 0x90, 0x90, 0x90, 0x8d, 0x87, + 0x80, 0x79, 0x75, 0x73, 0x79, 0x80, 0x86, 0x8c, 0x8c, 0x8b, 0x8d, 0x8f, 0x8f, 0x8e, 0x8f, 0x8b, + 0x7e, 0x74, 0x72, 0x79, 0x80, 0x80, 0x80, 0x7c, 0x79, 0x79, 0x77, 0x76, 0x76, 0x75, 0x75, 0x73, + 0x76, 0x7c, 0x86, 0x8c, 0x89, 0x8a, 0x8d, 0x8d, 0x8d, 0x87, 0x7d, 0x76, 0x71, 0x74, 0x7a, 0x7c, + 0x7a, 0x78, 0x78, 0x7a, 0x80, 0x8a, 0x8d, 0x8c, 0x8d, 0x86, 0x7e, 0x7e, 0x84, 0x88, 0x88, 0x80, + 0x77, 0x75, 0x73, 0x76, 0x7c, 0x7d, 0x7d, 0x7b, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x79, 0x79, 0x78, + 0x75, 0x77, 0x7a, 0x7a, 0x7b, 0x7a, 0x7d, 0x84, 0x89, 0x8a, 0x86, 0x83, 0x89, 0x8d, 0x8a, 0x86, + 0x87, 0x84, 0x7a, 0x78, 0x7c, 0x83, 0x85, 0x81, 0x7c, 0x75, 0x70, 0x6d, 0x6f, 0x74, 0x78, 0x77, + 0x76, 0x77, 0x7d, 0x89, 0x90, 0x95, 0x94, 0x90, 0x8f, 0x8c, 0x86, 0x86, 0x80, 0x74, 0x72, 0x74, + 0x77, 0x81, 0x87, 0x87, 0x83, 0x83, 0x85, 0x8a, 0x8c, 0x8b, 0x86, 0x7d, 0x76, 0x76, 0x79, 0x79, + 0x7b, 0x7c, 0x77, 0x75, 0x77, 0x76, 0x73, 0x72, 0x72, 0x6f, 0x6e, 0x75, 0x7d, 0x84, 0x86, 0x85, + 0x87, 0x89, 0x85, 0x80, 0x7b, 0x7a, 0x7a, 0x7b, 0x80, 0x84, 0x85, 0x82, 0x79, 0x75, 0x79, 0x82, + 0x86, 0x88, 0x8c, 0x8d, 0x87, 0x85, 0x84, 0x82, 0x83, 0x83, 0x80, 0x77, 0x75, 0x74, 0x77, 0x81, + 0x86, 0x84, 0x7b, 0x76, 0x7d, 0x85, 0x85, 0x82, 0x80, 0x7d, 0x77, 0x72, 0x71, 0x73, 0x73, 0x73, + 0x71, 0x6d, 0x6d, 0x71, 0x76, 0x7b, 0x7d, 0x83, 0x8d, 0x8d, 0x85, 0x82, 0x80, 0x7c, 0x80, 0x84, + 0x7c, 0x75, 0x77, 0x79, 0x75, 0x72, 0x72, 0x6f, 0x6e, 0x6e, 0x6c, 0x6f, 0x78, 0x84, 0x8f, 0x97, + 0x98, 0x95, 0x93, 0x92, 0x91, 0x8f, 0x8e, 0x91, 0x93, 0x91, 0x8e, 0x8d, 0x92, 0x97, 0x95, 0x8f, + 0x89, 0x87, 0x87, 0x83, 0x83, 0x84, 0x83, 0x86, 0x85, 0x83, 0x84, 0x83, 0x7e, 0x77, 0x74, 0x73, + 0x74, 0x7b, 0x82, 0x80, 0x7b, 0x7d, 0x82, 0x7e, 0x7b, 0x7c, 0x7e, 0x82, 0x86, 0x88, 0x88, 0x88, + 0x85, 0x82, 0x80, 0x7c, 0x79, 0x7e, 0x82, 0x83, 0x84, 0x87, 0x89, 0x87, 0x83, 0x82, 0x7d, 0x79, + 0x7b, 0x7b, 0x74, 0x72, 0x77, 0x76, 0x6f, 0x6d, 0x72, 0x79, 0x7e, 0x7d, 0x7a, 0x74, 0x72, 0x78, + 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x7b, 0x7b, 0x81, 0x87, 0x88, 0x87, 0x86, 0x83, 0x82, 0x85, 0x8a, + 0x8b, 0x8a, 0x8a, 0x8b, 0x89, 0x84, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x77, 0x6f, 0x6c, 0x69, 0x67, + 0x67, 0x66, 0x66, 0x67, 0x69, 0x6e, 0x71, 0x78, 0x85, 0x89, 0x88, 0x87, 0x83, 0x7d, 0x76, 0x6f, + 0x73, 0x7b, 0x7d, 0x7c, 0x78, 0x75, 0x7a, 0x83, 0x88, 0x8d, 0x8b, 0x89, 0x8c, 0x88, 0x85, 0x85, + 0x84, 0x85, 0x87, 0x87, 0x88, 0x86, 0x81, 0x7a, 0x74, 0x72, 0x70, 0x6c, 0x6c, 0x69, 0x69, 0x6d, + 0x77, 0x7d, 0x7d, 0x7c, 0x7c, 0x80, 0x81, 0x80, 0x80, 0x80, 0x83, 0x86, 0x86, 0x80, 0x77, 0x75, + 0x7a, 0x83, 0x89, 0x8e, 0x92, 0x91, 0x8d, 0x89, 0x89, 0x8d, 0x8e, 0x88, 0x82, 0x7e, 0x7e, 0x80, + 0x7e, 0x7c, 0x80, 0x82, 0x84, 0x89, 0x8a, 0x81, 0x7d, 0x82, 0x8b, 0x8c, 0x86, 0x85, 0x84, 0x84, + 0x85, 0x86, 0x87, 0x87, 0x87, 0x83, 0x7c, 0x7c, 0x83, 0x83, 0x80, 0x83, 0x89, 0x8b, 0x87, 0x82, + 0x7e, 0x81, 0x85, 0x88, 0x8a, 0x81, 0x76, 0x72, 0x6e, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6c, 0x6f, + 0x77, 0x7a, 0x7c, 0x84, 0x88, 0x8a, 0x8a, 0x87, 0x81, 0x7b, 0x80, 0x86, 0x8a, 0x89, 0x89, 0x87, + 0x86, 0x8a, 0x8e, 0x8e, 0x8b, 0x8a, 0x8a, 0x88, 0x86, 0x82, 0x81, 0x84, 0x85, 0x83, 0x7b, 0x77, + 0x73, 0x6f, 0x6f, 0x74, 0x79, 0x7c, 0x76, 0x6e, 0x70, 0x73, 0x77, 0x7e, 0x81, 0x80, 0x81, 0x84, + 0x88, 0x8a, 0x89, 0x88, 0x8d, 0x94, 0x95, 0x90, 0x85, 0x7e, 0x83, 0x88, 0x89, 0x8e, 0x91, 0x8f, + 0x8a, 0x89, 0x88, 0x83, 0x7c, 0x78, 0x70, 0x6a, 0x69, 0x6b, 0x6c, 0x68, 0x65, 0x6a, 0x6d, 0x66, + 0x60, 0x60, 0x63, 0x67, 0x6d, 0x6e, 0x6a, 0x68, 0x68, 0x6a, 0x70, 0x73, 0x72, 0x72, 0x76, 0x7a, + 0x80, 0x85, 0x89, 0x8d, 0x90, 0x92, 0x98, 0x9c, 0x9c, 0x9b, 0x97, 0x90, 0x92, 0x99, 0x97, 0x8f, + 0x89, 0x83, 0x7c, 0x77, 0x73, 0x6d, 0x68, 0x67, 0x6b, 0x71, 0x78, 0x7d, 0x83, 0x88, 0x87, 0x85, + 0x83, 0x83, 0x84, 0x83, 0x83, 0x84, 0x89, 0x90, 0x94, 0x90, 0x8c, 0x93, 0x9b, 0x97, 0x94, 0x93, + 0x92, 0x92, 0x92, 0x91, 0x8d, 0x8d, 0x8e, 0x8c, 0x87, 0x7d, 0x73, 0x6c, 0x6a, 0x6a, 0x68, 0x64, + 0x5c, 0x56, 0x53, 0x56, 0x5e, 0x62, 0x64, 0x62, 0x62, 0x65, 0x6f, 0x79, 0x77, 0x74, 0x73, 0x71, + 0x71, 0x72, 0x72, 0x72, 0x76, 0x79, 0x7e, 0x81, 0x81, 0x80, 0x81, 0x83, 0x83, 0x82, 0x7c, 0x77, + 0x77, 0x75, 0x75, 0x77, 0x7c, 0x82, 0x83, 0x83, 0x84, 0x84, 0x81, 0x82, 0x88, 0x8a, 0x8d, 0x96, + 0x97, 0x94, 0x93, 0x94, 0x97, 0x98, 0x96, 0x91, 0x90, 0x93, 0x97, 0x99, 0x97, 0x94, 0x8f, 0x8b, + 0x8d, 0x90, 0x95, 0x97, 0x97, 0x95, 0x96, 0x9b, 0x9e, 0x99, 0x8e, 0x84, 0x7c, 0x7b, 0x79, 0x75, + 0x72, 0x6f, 0x6c, 0x6d, 0x72, 0x75, 0x76, 0x7c, 0x84, 0x82, 0x7b, 0x77, 0x7a, 0x7c, 0x7e, 0x82, + 0x85, 0x88, 0x88, 0x88, 0x89, 0x8e, 0x90, 0x8d, 0x87, 0x84, 0x85, 0x84, 0x82, 0x82, 0x7e, 0x79, + 0x76, 0x74, 0x73, 0x6f, 0x6a, 0x66, 0x6a, 0x70, 0x71, 0x6b, 0x64, 0x5e, 0x5c, 0x5d, 0x64, 0x6e, + 0x76, 0x79, 0x7b, 0x79, 0x7c, 0x85, 0x8b, 0x88, 0x80, 0x7c, 0x80, 0x85, 0x8a, 0x8d, 0x8f, 0x8f, + 0x8c, 0x8a, 0x8d, 0x91, 0x90, 0x8f, 0x8a, 0x84, 0x81, 0x7b, 0x76, 0x74, 0x72, 0x6f, 0x71, 0x75, + 0x77, 0x7a, 0x7c, 0x7d, 0x80, 0x80, 0x7a, 0x7b, 0x82, 0x86, 0x87, 0x82, 0x7e, 0x80, 0x84, 0x85, + 0x84, 0x80, 0x7b, 0x7d, 0x85, 0x89, 0x89, 0x86, 0x82, 0x7c, 0x79, 0x7d, 0x84, 0x88, 0x8a, 0x87, + 0x86, 0x8b, 0x8d, 0x8b, 0x85, 0x7c, 0x72, 0x66, 0x62, 0x64, 0x67, 0x69, 0x6a, 0x69, 0x69, 0x6a, + 0x6c, 0x71, 0x78, 0x7b, 0x75, 0x6d, 0x70, 0x78, 0x79, 0x76, 0x72, 0x6e, 0x70, 0x79, 0x7e, 0x7e, + 0x7e, 0x84, 0x85, 0x83, 0x86, 0x8b, 0x8b, 0x8b, 0x8d, 0x90, 0x8f, 0x8c, 0x8d, 0x8d, 0x8a, 0x86, + 0x83, 0x83, 0x81, 0x7a, 0x72, 0x6c, 0x67, 0x62, 0x5e, 0x5f, 0x66, 0x6e, 0x72, 0x70, 0x70, 0x7a, + 0x83, 0x81, 0x79, 0x78, 0x7a, 0x7c, 0x83, 0x8c, 0x92, 0x8e, 0x88, 0x87, 0x8a, 0x8f, 0x96, 0x98, + 0x92, 0x8f, 0x8b, 0x85, 0x87, 0x8d, 0x8f, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, 0x9c, 0xa0, 0x9f, + 0x9c, 0x9b, 0x9b, 0x9c, 0x9d, 0x98, 0x90, 0x8a, 0x85, 0x82, 0x83, 0x7e, 0x7d, 0x82, 0x82, 0x81, + 0x7e, 0x76, 0x6a, 0x66, 0x6a, 0x72, 0x78, 0x7e, 0x82, 0x80, 0x78, 0x73, 0x74, 0x77, 0x76, 0x76, + 0x73, 0x70, 0x6e, 0x6d, 0x72, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x7c, 0x7c, 0x78, 0x73, + 0x6f, 0x71, 0x78, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x81, 0x83, 0x8a, 0x8e, + 0x8a, 0x82, 0x7c, 0x7a, 0x7a, 0x79, 0x7c, 0x81, 0x83, 0x7d, 0x75, 0x6f, 0x6a, 0x66, 0x66, 0x67, + 0x68, 0x6e, 0x74, 0x7c, 0x87, 0x8d, 0x91, 0x90, 0x8e, 0x8f, 0x92, 0x92, 0x90, 0x92, 0x92, 0x93, + 0x93, 0x95, 0x96, 0x90, 0x8a, 0x87, 0x86, 0x86, 0x86, 0x80, 0x76, 0x74, 0x76, 0x78, 0x75, 0x71, + 0x74, 0x74, 0x71, 0x6e, 0x6c, 0x6b, 0x6b, 0x6d, 0x75, 0x76, 0x76, 0x76, 0x74, 0x76, 0x7c, 0x7e, + 0x7c, 0x7a, 0x7b, 0x82, 0x8a, 0x8d, 0x89, 0x85, 0x83, 0x85, 0x86, 0x81, 0x7b, 0x78, 0x79, 0x80, + 0x8a, 0x93, 0x96, 0x91, 0x8d, 0x8f, 0x91, 0x8e, 0x86, 0x85, 0x87, 0x84, 0x7e, 0x79, 0x77, 0x77, + 0x73, 0x70, 0x70, 0x71, 0x70, 0x6e, 0x70, 0x77, 0x80, 0x7e, 0x76, 0x72, 0x71, 0x72, 0x75, 0x7a, + 0x7d, 0x7e, 0x7a, 0x7a, 0x81, 0x85, 0x85, 0x85, 0x8b, 0x91, 0x94, 0x93, 0x90, 0x8d, 0x8b, 0x8a, + 0x8b, 0x8d, 0x8d, 0x8a, 0x82, 0x79, 0x71, 0x6a, 0x66, 0x61, 0x5d, 0x5b, 0x5c, 0x63, 0x69, 0x6e, + 0x70, 0x6e, 0x69, 0x6a, 0x6d, 0x6f, 0x75, 0x7b, 0x85, 0x8c, 0x8a, 0x85, 0x82, 0x84, 0x82, 0x83, + 0x8a, 0x92, 0x97, 0x9a, 0x9d, 0x9c, 0x97, 0x8f, 0x8b, 0x88, 0x85, 0x89, 0x8d, 0x8d, 0x87, 0x82, + 0x7d, 0x81, 0x88, 0x87, 0x86, 0x8c, 0x91, 0x90, 0x8d, 0x8b, 0x89, 0x87, 0x89, 0x8b, 0x89, 0x88, + 0x83, 0x7a, 0x71, 0x6c, 0x69, 0x65, 0x62, 0x62, 0x64, 0x69, 0x71, 0x77, 0x7c, 0x7c, 0x79, 0x76, + 0x76, 0x7a, 0x7e, 0x85, 0x8e, 0x90, 0x87, 0x7b, 0x74, 0x70, 0x73, 0x7c, 0x7e, 0x7e, 0x7c, 0x7a, + 0x77, 0x76, 0x7a, 0x7b, 0x7c, 0x7c, 0x7a, 0x7a, 0x7d, 0x81, 0x83, 0x88, 0x8c, 0x8a, 0x8b, 0x8e, + 0x8e, 0x8d, 0x90, 0x94, 0x95, 0x93, 0x92, 0x91, 0x8e, 0x8f, 0x93, 0x92, 0x92, 0x8e, 0x88, 0x7e, + 0x76, 0x72, 0x72, 0x76, 0x77, 0x77, 0x77, 0x78, 0x79, 0x7c, 0x83, 0x81, 0x7a, 0x7c, 0x80, 0x80, + 0x80, 0x84, 0x88, 0x89, 0x89, 0x8c, 0x8d, 0x8e, 0x93, 0x92, 0x8c, 0x8a, 0x88, 0x85, 0x85, 0x85, + 0x84, 0x7c, 0x71, 0x69, 0x68, 0x6b, 0x6c, 0x6d, 0x6f, 0x6e, 0x6c, 0x6c, 0x6d, 0x6d, 0x72, 0x74, + 0x75, 0x76, 0x79, 0x80, 0x84, 0x83, 0x83, 0x85, 0x85, 0x85, 0x87, 0x83, 0x7d, 0x7a, 0x7c, 0x80, + 0x7e, 0x7c, 0x7c, 0x80, 0x85, 0x8d, 0x93, 0x96, 0x95, 0x91, 0x8c, 0x89, 0x89, 0x8d, 0x8f, 0x8e, + 0x85, 0x77, 0x6b, 0x62, 0x5a, 0x5a, 0x59, 0x57, 0x58, 0x5f, 0x65, 0x6a, 0x6f, 0x71, 0x70, 0x69, + 0x65, 0x69, 0x6f, 0x75, 0x7b, 0x80, 0x80, 0x7b, 0x7a, 0x7c, 0x7d, 0x7c, 0x7e, 0x82, 0x87, 0x8d, + 0x90, 0x90, 0x8c, 0x8c, 0x8e, 0x8d, 0x8c, 0x8f, 0x8c, 0x83, 0x78, 0x73, 0x70, 0x69, 0x63, 0x61, + 0x61, 0x5f, 0x5e, 0x60, 0x62, 0x62, 0x5f, 0x5d, 0x5e, 0x61, 0x69, 0x75, 0x81, 0x84, 0x83, 0x7e, + 0x80, 0x89, 0x93, 0x98, 0x96, 0x94, 0x9b, 0x9e, 0x9e, 0xa2, 0xa6, 0xa2, 0x9a, 0x95, 0x94, 0x9a, + 0x9e, 0x9c, 0x9a, 0x95, 0x91, 0x90, 0x92, 0x91, 0x92, 0x98, 0x9b, 0x9e, 0x9e, 0xa0, 0xa2, 0xa0, + 0xa2, 0xa1, 0x9b, 0x95, 0x92, 0x91, 0x88, 0x7d, 0x7b, 0x7d, 0x7d, 0x7e, 0x7d, 0x76, 0x72, 0x71, + 0x71, 0x76, 0x7e, 0x82, 0x7e, 0x7a, 0x78, 0x7a, 0x7e, 0x80, 0x7c, 0x74, 0x6b, 0x67, 0x6b, 0x72, + 0x71, 0x6f, 0x6d, 0x6c, 0x6e, 0x70, 0x6f, 0x71, 0x74, 0x70, 0x6c, 0x6d, 0x71, 0x75, 0x77, 0x7b, + 0x7e, 0x82, 0x85, 0x87, 0x88, 0x86, 0x82, 0x7e, 0x7d, 0x80, 0x86, 0x8d, 0x91, 0x8a, 0x83, 0x84, + 0x81, 0x7c, 0x7c, 0x7c, 0x76, 0x71, 0x6e, 0x6e, 0x6e, 0x6d, 0x6e, 0x6d, 0x6d, 0x6f, 0x73, 0x7c, + 0x81, 0x82, 0x7d, 0x7c, 0x82, 0x8a, 0x93, 0x94, 0x8e, 0x8b, 0x8c, 0x90, 0x97, 0x9c, 0x99, 0x94, + 0x90, 0x8d, 0x90, 0x91, 0x8a, 0x7d, 0x70, 0x5e, 0x5c, 0x6d, 0x71, 0x71, 0x72, 0x6f, 0x64, 0x60, + 0x61, 0x5f, 0x5e, 0x61, 0x69, 0x70, 0x6f, 0x6d, 0x71, 0x79, 0x7c, 0x79, 0x77, 0x77, 0x79, 0x80, + 0x82, 0x80, 0x80, 0x7e, 0x81, 0x88, 0x8d, 0x8d, 0x8a, 0x8b, 0x91, 0x9a, 0xa1, 0xa4, 0x9d, 0x96, + 0x97, 0x99, 0x93, 0x95, 0x96, 0x8b, 0x7a, 0x6f, 0x6a, 0x67, 0x6b, 0x6f, 0x68, 0x65, 0x67, 0x64, + 0x60, 0x62, 0x61, 0x5e, 0x60, 0x65, 0x6a, 0x71, 0x77, 0x7a, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x87, + 0x8c, 0x88, 0x85, 0x87, 0x8a, 0x8d, 0x92, 0x97, 0x95, 0x8f, 0x86, 0x84, 0x86, 0x83, 0x8b, 0x89, + 0x7d, 0x77, 0x74, 0x71, 0x70, 0x6b, 0x6a, 0x69, 0x67, 0x6a, 0x73, 0x7b, 0x76, 0x7a, 0x8b, 0x93, + 0x97, 0x97, 0x95, 0x93, 0x97, 0xa1, 0xaa, 0xaf, 0xab, 0x9f, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, + 0x97, 0x98, 0x98, 0x94, 0x90, 0x90, 0x93, 0x8e, 0x93, 0x94, 0x8e, 0x8a, 0x88, 0x8f, 0x91, 0x8f, + 0x8b, 0x84, 0x81, 0x80, 0x80, 0x79, 0x6f, 0x64, 0x5c, 0x5a, 0x5b, 0x57, 0x55, 0x5d, 0x5a, 0x57, + 0x66, 0x6b, 0x66, 0x64, 0x70, 0x7e, 0x89, 0x90, 0x90, 0x8e, 0x8e, 0x8c, 0x84, 0x86, 0x83, 0x75, + 0x6d, 0x67, 0x63, 0x6d, 0x70, 0x71, 0x74, 0x75, 0x73, 0x71, 0x78, 0x7e, 0x7e, 0x74, 0x6e, 0x71, + 0x70, 0x6f, 0x6c, 0x6e, 0x74, 0x77, 0x7a, 0x80, 0x85, 0x86, 0x90, 0x8f, 0x87, 0x8f, 0x90, 0x8b, + 0x89, 0x85, 0x8c, 0x8e, 0x8b, 0x8d, 0x94, 0x94, 0x89, 0x7d, 0x73, 0x6b, 0x66, 0x66, 0x60, 0x65, + 0x71, 0x75, 0x72, 0x76, 0x87, 0x8a, 0x88, 0x8f, 0x92, 0x9a, 0xa0, 0x91, 0x91, 0x95, 0x90, 0x92, + 0x9d, 0xa2, 0x9e, 0x9a, 0x95, 0x94, 0x92, 0x8d, 0x8c, 0x84, 0x77, 0x73, 0x6f, 0x62, 0x61, 0x6d, + 0x70, 0x6b, 0x6f, 0x6d, 0x6c, 0x7a, 0x87, 0x9b, 0xa0, 0xa0, 0x92, 0x81, 0x80, 0x7e, 0x7e, 0x7c, + 0x78, 0x76, 0x76, 0x74, 0x78, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, 0x7d, 0x86, 0x83, 0x74, 0x7d, 0x8d, + 0x92, 0x95, 0x99, 0x96, 0x92, 0x8c, 0x81, 0x76, 0x7a, 0x73, 0x60, 0x5c, 0x59, 0x4f, 0x4e, 0x50, + 0x51, 0x5a, 0x54, 0x50, 0x54, 0x57, 0x60, 0x6e, 0x6f, 0x72, 0x72, 0x6e, 0x62, 0x66, 0x73, 0x72, + 0x74, 0x84, 0x95, 0x9a, 0x9a, 0x95, 0x92, 0x9a, 0x9a, 0x88, 0x8a, 0x88, 0x87, 0x82, 0x7a, 0x7e, + 0x8d, 0x9c, 0xa4, 0xa0, 0x8e, 0x79, 0x84, 0x8d, 0x87, 0x7a, 0x70, 0x6a, 0x62, 0x5f, 0x5d, 0x5d, + 0x65, 0x6b, 0x73, 0x7c, 0x7b, 0x71, 0x72, 0x75, 0x72, 0x89, 0x9d, 0xa0, 0x94, 0x8e, 0x92, 0x96, + 0xa9, 0xb8, 0xae, 0xa2, 0x98, 0x8e, 0x8c, 0x8a, 0x8a, 0x8d, 0x8d, 0x8b, 0x83, 0x71, 0x85, 0x9e, + 0xa7, 0xaa, 0xa8, 0x9a, 0x93, 0x8c, 0x85, 0x83, 0x80, 0x85, 0x86, 0x7a, 0x70, 0x71, 0x6f, 0x6d, + 0x70, 0x69, 0x6b, 0x70, 0x6f, 0x6c, 0x6a, 0x66, 0x75, 0x81, 0x8f, 0x97, 0x89, 0x85, 0x84, 0x80, + 0x77, 0x77, 0x80, 0x7d, 0x6f, 0x6b, 0x64, 0x60, 0x75, 0x81, 0x7c, 0x71, 0x67, 0x68, 0x7a, 0x80, + 0x79, 0x81, 0x85, 0x80, 0x79, 0x7e, 0x85, 0x7e, 0x80, 0x75, 0x6c, 0x76, 0x86, 0x90, 0x96, 0x98, + 0x91, 0x95, 0x9a, 0x9e, 0x9b, 0x8b, 0x75, 0x8a, 0x99, 0x8c, 0x82, 0x85, 0x91, 0x8d, 0x7c, 0x6a, + 0x61, 0x74, 0x7e, 0x78, 0x6f, 0x68, 0x67, 0x74, 0x83, 0x81, 0x8b, 0x9d, 0xa0, 0x94, 0x90, 0x8f, + 0x93, 0x8f, 0x87, 0x88, 0x8a, 0x83, 0x90, 0x9d, 0x8a, 0x7e, 0x7c, 0x8c, 0x9c, 0x89, 0x73, 0x71, + 0x75, 0x73, 0x64, 0x61, 0x68, 0x63, 0x65, 0x67, 0x5b, 0x72, 0x93, 0x93, 0x82, 0x78, 0x75, 0x5e, + 0x4e, 0x58, 0x69, 0x6c, 0x66, 0x70, 0x71, 0x65, 0x6c, 0x79, 0x82, 0x87, 0x81, 0x77, 0x73, 0x7a, + 0x82, 0x81, 0x80, 0x8b, 0x97, 0x98, 0x8d, 0x86, 0x9b, 0xa4, 0x92, 0x86, 0x8e, 0x83, 0x6b, 0x5b, + 0x4c, 0x51, 0x66, 0x66, 0x63, 0x5e, 0x51, 0x4f, 0x61, 0x6c, 0x75, 0x7e, 0x79, 0x6f, 0x67, 0x66, + 0x64, 0x5d, 0x5c, 0x6b, 0x76, 0x75, 0x75, 0x8b, 0x9d, 0x9e, 0x9e, 0x99, 0x88, 0x84, 0x8c, 0x8f, + 0x93, 0x9e, 0xa2, 0x9c, 0x97, 0x96, 0x95, 0x92, 0x92, 0x92, 0x8c, 0x93, 0x94, 0x90, 0x89, 0x7a, + 0x6f, 0x66, 0x66, 0x66, 0x6d, 0x73, 0x7e, 0x88, 0x86, 0x90, 0x93, 0x88, 0x85, 0x83, 0x83, 0x87, + 0x8a, 0x91, 0x93, 0x94, 0x96, 0x95, 0xa1, 0xae, 0xa9, 0xa1, 0x9f, 0xa1, 0x9e, 0x95, 0x95, 0x92, + 0x87, 0x84, 0x8b, 0x8e, 0x98, 0xa5, 0xaa, 0x9e, 0x94, 0x8b, 0x79, 0x6d, 0x68, 0x6e, 0x83, 0x8c, + 0x78, 0x69, 0x70, 0x6f, 0x6e, 0x6c, 0x64, 0x57, 0x56, 0x6f, 0x8a, 0x8b, 0x81, 0x7c, 0x7a, 0x7c, + 0x6e, 0x62, 0x6c, 0x76, 0x7c, 0x82, 0x8a, 0x8c, 0x75, 0x67, 0x61, 0x63, 0x6d, 0x7c, 0x85, 0x75, + 0x67, 0x6d, 0x70, 0x71, 0x71, 0x72, 0x69, 0x6f, 0x7b, 0x84, 0x7d, 0x75, 0x7c, 0x84, 0x83, 0x79, + 0x70, 0x70, 0x81, 0x8e, 0x93, 0x94, 0x82, 0x6e, 0x6d, 0x83, 0x98, 0xa5, 0xa7, 0x9a, 0x85, 0x84, + 0x85, 0x74, 0x67, 0x60, 0x60, 0x6f, 0x84, 0x8a, 0x85, 0x7a, 0x79, 0x7d, 0x7c, 0x79, 0x78, 0x6f, + 0x73, 0x87, 0x9a, 0x9d, 0x99, 0x92, 0x83, 0x7d, 0x7e, 0x7c, 0x87, 0x92, 0x8c, 0x86, 0x8d, 0x91, + 0x99, 0x9b, 0x88, 0x7b, 0x71, 0x72, 0x6c, 0x5f, 0x65, 0x73, 0x87, 0x8b, 0x81, 0x77, 0x80, 0x8b, + 0x85, 0x7d, 0x81, 0x73, 0x67, 0x6a, 0x7a, 0x81, 0x7a, 0x75, 0x83, 0x81, 0x70, 0x74, 0x7c, 0x75, + 0x6f, 0x70, 0x74, 0x79, 0x7b, 0x77, 0x78, 0x81, 0x89, 0x98, 0x96, 0x92, 0x90, 0x88, 0x81, 0x78, + 0x7d, 0x87, 0x73, 0x5d, 0x55, 0x56, 0x57, 0x5c, 0x68, 0x6a, 0x62, 0x6a, 0x75, 0x79, 0x74, 0x70, + 0x65, 0x52, 0x48, 0x4d, 0x5c, 0x66, 0x6d, 0x88, 0x99, 0x8f, 0x88, 0x96, 0x9c, 0x9e, 0x9f, 0x92, + 0x8d, 0x8b, 0x9b, 0xac, 0xaa, 0xa9, 0x9f, 0x96, 0x89, 0x86, 0x84, 0x94, 0xa1, 0x9a, 0x8d, 0x7d, + 0x87, 0xa2, 0x9e, 0x91, 0x93, 0x97, 0x94, 0x8c, 0x7b, 0x74, 0x71, 0x6c, 0x81, 0x80, 0x80, 0x79, + 0x64, 0x5e, 0x61, 0x6a, 0x78, 0x80, 0x79, 0x78, 0x87, 0x81, 0x88, 0x99, 0x99, 0x93, 0x8d, 0x85, + 0x72, 0x69, 0x6e, 0x7b, 0x8e, 0x98, 0x92, 0x7e, 0x76, 0x81, 0x96, 0xa1, 0x95, 0x88, 0x7d, 0x6f, + 0x68, 0x76, 0x7e, 0x75, 0x6a, 0x62, 0x68, 0x6d, 0x66, 0x5d, 0x50, 0x50, 0x61, 0x6a, 0x6c, 0x62, + 0x5b, 0x5a, 0x64, 0x79, 0x7b, 0x74, 0x7d, 0x7b, 0x74, 0x80, 0x86, 0x85, 0x83, 0x85, 0x8d, 0x86, + 0x86, 0x8c, 0x9d, 0x9f, 0x9b, 0x9f, 0x8e, 0x83, 0x88, 0x89, 0x81, 0x76, 0x80, 0x87, 0x84, 0x82, + 0x8d, 0x9a, 0x9a, 0x8e, 0x8d, 0x9b, 0x9c, 0xa3, 0xa5, 0x93, 0x8b, 0x85, 0x92, 0xa1, 0xaa, 0xa3, + 0x9c, 0x98, 0x8a, 0x8a, 0x8d, 0x89, 0x8c, 0x93, 0x86, 0x69, 0x62, 0x7e, 0x8d, 0x8b, 0x8c, 0x91, + 0x91, 0x8c, 0x89, 0x85, 0x82, 0x84, 0x8e, 0x88, 0x74, 0x73, 0x76, 0x6a, 0x73, 0x8e, 0x95, 0x93, + 0x8f, 0x89, 0x89, 0x83, 0x80, 0x8c, 0x86, 0x7b, 0x71, 0x65, 0x57, 0x4a, 0x4e, 0x5d, 0x72, 0x74, + 0x64, 0x53, 0x4c, 0x4a, 0x56, 0x69, 0x6c, 0x69, 0x68, 0x5f, 0x57, 0x5b, 0x6e, 0x84, 0x86, 0x83, + 0x89, 0x8a, 0x79, 0x6e, 0x6e, 0x6a, 0x6b, 0x6c, 0x70, 0x72, 0x6a, 0x6b, 0x81, 0xac, 0xb8, 0xa4, + 0x9d, 0x93, 0x89, 0x82, 0x72, 0x6f, 0x7c, 0x85, 0x86, 0x82, 0x75, 0x72, 0x6c, 0x6c, 0x86, 0x90, + 0x87, 0x75, 0x65, 0x61, 0x5d, 0x5e, 0x65, 0x69, 0x6b, 0x6a, 0x64, 0x56, 0x54, 0x68, 0x76, 0x75, + 0x7c, 0x8c, 0x90, 0x91, 0x93, 0x8f, 0x9f, 0xa9, 0xa2, 0xa1, 0xa0, 0x9e, 0x94, 0x9f, 0xab, 0xa8, + 0xa1, 0x94, 0x85, 0x78, 0x6f, 0x64, 0x6b, 0x77, 0x7d, 0x7e, 0x7a, 0x73, 0x62, 0x58, 0x5d, 0x65, + 0x6d, 0x70, 0x70, 0x72, 0x66, 0x5d, 0x6b, 0x78, 0x7b, 0x86, 0x91, 0x92, 0x92, 0x95, 0xa1, 0xb0, + 0xa6, 0x9d, 0x98, 0x93, 0x8e, 0x88, 0x8c, 0x93, 0x92, 0x8b, 0x82, 0x7c, 0x82, 0x8d, 0x94, 0x93, + 0x9a, 0x99, 0x93, 0x8f, 0x87, 0x84, 0x86, 0x8c, 0x8d, 0x8c, 0x89, 0x89, 0x84, 0x72, 0x61, 0x59, + 0x61, 0x69, 0x6e, 0x78, 0x7c, 0x7d, 0x86, 0x96, 0x9c, 0x90, 0x86, 0x7d, 0x7e, 0x85, 0x8c, 0x94, + 0x96, 0x92, 0x89, 0x83, 0x7b, 0x82, 0x91, 0x8f, 0x8c, 0x92, 0x8e, 0x8a, 0x7d, 0x74, 0x7a, 0x83, + 0x82, 0x7c, 0x73, 0x6e, 0x6d, 0x6d, 0x6b, 0x60, 0x53, 0x5d, 0x6a, 0x73, 0x7c, 0x88, 0x8d, 0x8f, + 0x98, 0x94, 0x8c, 0x8a, 0x8a, 0x8f, 0x8d, 0x8d, 0x92, 0x94, 0x8e, 0x81, 0x73, 0x6d, 0x73, 0x7b, + 0x78, 0x6f, 0x74, 0x72, 0x6f, 0x6e, 0x6e, 0x6b, 0x6e, 0x73, 0x70, 0x6e, 0x6f, 0x72, 0x77, 0x77, + 0x72, 0x69, 0x68, 0x75, 0x80, 0x87, 0x92, 0x98, 0x9b, 0xa3, 0x93, 0x81, 0x7b, 0x7e, 0x84, 0x76, + 0x6f, 0x6f, 0x70, 0x71, 0x6e, 0x62, 0x5f, 0x67, 0x64, 0x63, 0x66, 0x6c, 0x6a, 0x65, 0x6b, 0x73, + 0x78, 0x80, 0x82, 0x85, 0x86, 0x87, 0x8e, 0x89, 0x78, 0x69, 0x5c, 0x58, 0x68, 0x7a, 0x84, 0x89, + 0x8c, 0x96, 0x9e, 0x8f, 0x82, 0x7c, 0x84, 0x88, 0x85, 0x89, 0x8d, 0x8e, 0x92, 0x95, 0x93, 0x8f, + 0x8b, 0x7c, 0x6c, 0x6d, 0x73, 0x6c, 0x66, 0x62, 0x64, 0x67, 0x67, 0x65, 0x64, 0x62, 0x68, 0x75, + 0x7e, 0x7a, 0x72, 0x6d, 0x70, 0x7a, 0x8d, 0x9b, 0x9f, 0xa0, 0xa5, 0xa5, 0x9f, 0xa2, 0xa6, 0xa7, + 0xa6, 0xa3, 0xa4, 0xa7, 0xa6, 0xa1, 0x9f, 0x9b, 0x99, 0x96, 0x8b, 0x7e, 0x79, 0x79, 0x7d, 0x7b, + 0x74, 0x6d, 0x6a, 0x6a, 0x6a, 0x6a, 0x6e, 0x76, 0x7d, 0x83, 0x83, 0x7e, 0x78, 0x76, 0x79, 0x83, + 0x8c, 0x8f, 0x8a, 0x85, 0x80, 0x7c, 0x7e, 0x85, 0x87, 0x83, 0x80, 0x83, 0x89, 0x8d, 0x8c, 0x8d, + 0x8c, 0x8d, 0x91, 0x8e, 0x8a, 0x87, 0x87, 0x8c, 0x91, 0x91, 0x91, 0x90, 0x8a, 0x85, 0x81, 0x81, + 0x84, 0x82, 0x78, 0x6e, 0x65, 0x61, 0x63, 0x68, 0x6a, 0x6c, 0x6f, 0x72, 0x6b, 0x5f, 0x5c, 0x61, + 0x6a, 0x6d, 0x6a, 0x6a, 0x70, 0x75, 0x7a, 0x7d, 0x7e, 0x7d, 0x7c, 0x78, 0x75, 0x76, 0x7b, 0x81, + 0x7c, 0x77, 0x72, 0x6f, 0x73, 0x72, 0x6e, 0x6a, 0x6e, 0x79, 0x83, 0x81, 0x78, 0x73, 0x72, 0x74, + 0x79, 0x7e, 0x83, 0x83, 0x80, 0x80, 0x84, 0x8a, 0x91, 0x96, 0x98, 0x96, 0x93, 0x93, 0x94, 0x93, + 0x90, 0x8b, 0x84, 0x80, 0x7b, 0x79, 0x78, 0x7e, 0x84, 0x83, 0x7b, 0x77, 0x78, 0x7d, 0x83, 0x84, + 0x80, 0x82, 0x8c, 0x93, 0x9a, 0x9f, 0x9e, 0x9e, 0x9f, 0xa4, 0xab, 0xa9, 0xa3, 0x9a, 0x90, 0x87, + 0x85, 0x83, 0x7d, 0x77, 0x6f, 0x6c, 0x70, 0x72, 0x6f, 0x6b, 0x66, 0x64, 0x65, 0x63, 0x62, 0x66, + 0x70, 0x78, 0x76, 0x73, 0x77, 0x7d, 0x86, 0x8a, 0x85, 0x82, 0x85, 0x88, 0x89, 0x88, 0x84, 0x82, + 0x7c, 0x79, 0x79, 0x7e, 0x88, 0x8f, 0x8f, 0x88, 0x83, 0x84, 0x88, 0x8c, 0x8c, 0x87, 0x84, 0x84, + 0x86, 0x8d, 0x8d, 0x87, 0x7d, 0x76, 0x73, 0x71, 0x71, 0x74, 0x71, 0x6c, 0x65, 0x61, 0x61, 0x60, + 0x60, 0x5e, 0x5c, 0x60, 0x65, 0x67, 0x69, 0x6a, 0x6a, 0x6b, 0x6d, 0x6f, 0x78, 0x86, 0x8f, 0x92, + 0x91, 0x8e, 0x8d, 0x94, 0x9e, 0xa5, 0xa7, 0xa7, 0xa5, 0xa4, 0xa1, 0x9b, 0x92, 0x88, 0x7d, 0x74, + 0x6e, 0x70, 0x75, 0x71, 0x65, 0x5d, 0x5b, 0x5d, 0x5d, 0x5b, 0x57, 0x58, 0x5f, 0x66, 0x6a, 0x6c, + 0x70, 0x73, 0x73, 0x6f, 0x6d, 0x74, 0x7e, 0x82, 0x80, 0x7c, 0x7a, 0x7d, 0x84, 0x8d, 0x93, 0x95, + 0x97, 0x93, 0x8c, 0x8b, 0x8e, 0x94, 0x97, 0x96, 0x98, 0x98, 0x97, 0x97, 0x94, 0x8b, 0x82, 0x7e, + 0x7a, 0x77, 0x75, 0x72, 0x72, 0x6f, 0x70, 0x75, 0x76, 0x72, 0x6d, 0x6e, 0x6c, 0x6b, 0x6f, 0x73, + 0x75, 0x73, 0x6f, 0x6f, 0x71, 0x75, 0x7a, 0x81, 0x88, 0x8a, 0x8a, 0x8a, 0x8c, 0x92, 0x97, 0x95, + 0x93, 0x92, 0x8d, 0x8e, 0x8e, 0x93, 0x99, 0x9a, 0x9a, 0x9a, 0x9b, 0x96, 0x92, 0x94, 0x93, 0x93, + 0x92, 0x90, 0x92, 0x93, 0x93, 0x8f, 0x8f, 0x95, 0x9c, 0x9c, 0x96, 0x92, 0x94, 0x98, 0x90, 0x8a, + 0x8e, 0x92, 0x93, 0x91, 0x92, 0x95, 0x96, 0x93, 0x90, 0x90, 0x8c, 0x86, 0x84, 0x84, 0x86, 0x84, + 0x7c, 0x79, 0x74, 0x6c, 0x67, 0x68, 0x6e, 0x75, 0x78, 0x75, 0x70, 0x6d, 0x69, 0x64, 0x63, 0x66, + 0x68, 0x67, 0x67, 0x66, 0x6b, 0x6f, 0x71, 0x73, 0x74, 0x73, 0x75, 0x75, 0x72, 0x6f, 0x6a, 0x63, + 0x5d, 0x5d, 0x5f, 0x60, 0x62, 0x66, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x71, 0x71, 0x73, 0x78, 0x79, + 0x79, 0x7b, 0x76, 0x71, 0x72, 0x73, 0x77, 0x79, 0x79, 0x7c, 0x7e, 0x7c, 0x7c, 0x81, 0x83, 0x83, + 0x80, 0x81, 0x84, 0x8a, 0x8d, 0x8b, 0x86, 0x85, 0x87, 0x81, 0x79, 0x74, 0x73, 0x72, 0x6a, 0x65, + 0x65, 0x63, 0x64, 0x6b, 0x70, 0x71, 0x6d, 0x6d, 0x70, 0x74, 0x79, 0x7d, 0x80, 0x7d, 0x7e, 0x84, + 0x88, 0x89, 0x89, 0x85, 0x81, 0x85, 0x90, 0x99, 0x99, 0x97, 0x96, 0x97, 0x96, 0x93, 0x94, 0x96, + 0x94, 0x92, 0x95, 0x99, 0x98, 0x97, 0x94, 0x8e, 0x88, 0x87, 0x88, 0x84, 0x7a, 0x78, 0x78, 0x72, + 0x70, 0x74, 0x76, 0x73, 0x74, 0x78, 0x77, 0x73, 0x77, 0x7c, 0x7e, 0x7e, 0x80, 0x87, 0x91, 0x9b, + 0xa4, 0xa5, 0xa1, 0x99, 0x94, 0x93, 0x96, 0x98, 0x99, 0x97, 0x90, 0x84, 0x7e, 0x81, 0x84, 0x85, + 0x7d, 0x73, 0x6d, 0x72, 0x7b, 0x82, 0x83, 0x82, 0x81, 0x82, 0x81, 0x85, 0x8a, 0x8e, 0x8e, 0x8b, + 0x88, 0x83, 0x82, 0x81, 0x7c, 0x79, 0x76, 0x78, 0x7b, 0x78, 0x75, 0x74, 0x79, 0x80, 0x86, 0x8b, + 0x8b, 0x88, 0x85, 0x80, 0x7c, 0x82, 0x88, 0x8e, 0x8e, 0x86, 0x7d, 0x7a, 0x79, 0x7a, 0x7e, 0x7d, + 0x77, 0x70, 0x6d, 0x6e, 0x6f, 0x74, 0x78, 0x75, 0x6c, 0x68, 0x6e, 0x77, 0x7e, 0x7d, 0x78, 0x75, + 0x7b, 0x86, 0x88, 0x89, 0x8c, 0x89, 0x83, 0x7e, 0x80, 0x84, 0x84, 0x81, 0x81, 0x80, 0x7d, 0x81, + 0x84, 0x80, 0x7a, 0x73, 0x6c, 0x6b, 0x6d, 0x71, 0x78, 0x7c, 0x7c, 0x78, 0x71, 0x6b, 0x6e, 0x79, + 0x7b, 0x75, 0x74, 0x7b, 0x82, 0x84, 0x83, 0x81, 0x7e, 0x80, 0x87, 0x90, 0x94, 0x8b, 0x7e, 0x75, + 0x75, 0x7d, 0x83, 0x82, 0x7c, 0x72, 0x6a, 0x68, 0x69, 0x6d, 0x6c, 0x64, 0x5d, 0x5f, 0x64, 0x67, + 0x6d, 0x74, 0x78, 0x75, 0x6f, 0x6d, 0x6f, 0x76, 0x81, 0x88, 0x8c, 0x88, 0x82, 0x80, 0x86, 0x8e, + 0x93, 0x94, 0x96, 0x9d, 0xa1, 0x9f, 0x9a, 0x94, 0x8d, 0x8a, 0x8a, 0x8d, 0x94, 0x93, 0x86, 0x79, + 0x7a, 0x7e, 0x7d, 0x7a, 0x73, 0x69, 0x61, 0x63, 0x6e, 0x75, 0x77, 0x75, 0x76, 0x7c, 0x82, 0x85, + 0x8b, 0x92, 0x92, 0x8b, 0x82, 0x7a, 0x7a, 0x7e, 0x84, 0x89, 0x8e, 0x92, 0x91, 0x8c, 0x8d, 0x91, + 0x91, 0x8d, 0x8c, 0x8e, 0x90, 0x94, 0x9d, 0xa4, 0xa1, 0x99, 0x92, 0x90, 0x8f, 0x8a, 0x82, 0x78, + 0x73, 0x72, 0x74, 0x73, 0x6e, 0x67, 0x60, 0x5c, 0x5f, 0x63, 0x65, 0x65, 0x6a, 0x74, 0x7b, 0x7c, + 0x81, 0x87, 0x85, 0x7e, 0x7d, 0x84, 0x8c, 0x8f, 0x8d, 0x89, 0x8a, 0x8f, 0x8e, 0x8c, 0x8c, 0x89, + 0x83, 0x80, 0x7e, 0x7b, 0x78, 0x76, 0x74, 0x6e, 0x6a, 0x68, 0x68, 0x6f, 0x7a, 0x81, 0x7b, 0x71, + 0x66, 0x60, 0x5f, 0x67, 0x72, 0x73, 0x6c, 0x61, 0x5e, 0x64, 0x68, 0x6c, 0x74, 0x7e, 0x83, 0x7d, + 0x7c, 0x82, 0x82, 0x82, 0x87, 0x8c, 0x8e, 0x8f, 0x90, 0x90, 0x92, 0x96, 0x97, 0x93, 0x88, 0x7b, + 0x74, 0x76, 0x86, 0x94, 0x98, 0x96, 0x93, 0x91, 0x8e, 0x88, 0x89, 0x90, 0x96, 0x95, 0x8f, 0x87, + 0x7e, 0x78, 0x7a, 0x84, 0x8a, 0x89, 0x83, 0x81, 0x89, 0x90, 0x90, 0x91, 0x93, 0x93, 0x90, 0x8d, + 0x91, 0x9a, 0x9d, 0x98, 0x90, 0x8a, 0x88, 0x84, 0x7c, 0x7b, 0x80, 0x81, 0x80, 0x79, 0x70, 0x6c, + 0x6c, 0x70, 0x79, 0x7d, 0x7d, 0x7b, 0x7d, 0x83, 0x84, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x82, 0x85, + 0x84, 0x7e, 0x7a, 0x74, 0x6e, 0x6c, 0x6e, 0x73, 0x7d, 0x86, 0x84, 0x79, 0x74, 0x75, 0x75, 0x75, + 0x74, 0x70, 0x6a, 0x63, 0x65, 0x6c, 0x71, 0x73, 0x75, 0x79, 0x77, 0x70, 0x71, 0x7a, 0x7c, 0x7b, + 0x7a, 0x76, 0x72, 0x75, 0x7a, 0x81, 0x87, 0x8b, 0x89, 0x82, 0x7a, 0x7a, 0x7e, 0x82, 0x83, 0x86, + 0x84, 0x7c, 0x74, 0x72, 0x78, 0x7b, 0x7d, 0x7c, 0x76, 0x6b, 0x62, 0x62, 0x6a, 0x72, 0x78, 0x77, + 0x6f, 0x69, 0x6d, 0x6e, 0x71, 0x78, 0x81, 0x87, 0x83, 0x80, 0x82, 0x84, 0x84, 0x8b, 0x8d, 0x86, + 0x81, 0x80, 0x87, 0x93, 0x99, 0x9a, 0x9b, 0x97, 0x8f, 0x8d, 0x91, 0x99, 0x9e, 0x9f, 0x99, 0x8e, + 0x88, 0x86, 0x81, 0x7c, 0x80, 0x80, 0x7b, 0x73, 0x6c, 0x6b, 0x6c, 0x6e, 0x71, 0x74, 0x72, 0x6f, + 0x6f, 0x73, 0x79, 0x80, 0x85, 0x84, 0x82, 0x80, 0x82, 0x82, 0x81, 0x82, 0x7e, 0x78, 0x72, 0x70, + 0x70, 0x73, 0x78, 0x80, 0x81, 0x7a, 0x75, 0x75, 0x77, 0x75, 0x71, 0x6e, 0x6f, 0x73, 0x74, 0x77, + 0x7d, 0x84, 0x88, 0x87, 0x85, 0x80, 0x7d, 0x7d, 0x7a, 0x78, 0x79, 0x7b, 0x7d, 0x85, 0x8d, 0x92, + 0x95, 0x9b, 0x9d, 0x99, 0x96, 0x96, 0x9a, 0x9f, 0xa1, 0xa0, 0x9b, 0x95, 0x92, 0x95, 0x99, 0x97, + 0x95, 0x97, 0x92, 0x8c, 0x89, 0x8b, 0x8a, 0x88, 0x85, 0x83, 0x81, 0x7e, 0x83, 0x8a, 0x8e, 0x8f, + 0x8b, 0x7a, 0x6a, 0x62, 0x69, 0x77, 0x80, 0x83, 0x81, 0x7a, 0x79, 0x78, 0x80, 0x8e, 0x94, 0x91, + 0x90, 0x8c, 0x89, 0x87, 0x86, 0x87, 0x8b, 0x91, 0x92, 0x8d, 0x87, 0x82, 0x7e, 0x7d, 0x7b, 0x78, + 0x6f, 0x67, 0x68, 0x72, 0x7c, 0x7b, 0x78, 0x75, 0x70, 0x68, 0x5e, 0x5b, 0x60, 0x69, 0x70, 0x72, + 0x71, 0x6e, 0x6c, 0x6a, 0x6b, 0x71, 0x72, 0x6c, 0x61, 0x5d, 0x60, 0x64, 0x68, 0x6d, 0x6f, 0x6a, + 0x63, 0x63, 0x67, 0x66, 0x61, 0x5c, 0x5b, 0x5f, 0x64, 0x6b, 0x6f, 0x6c, 0x69, 0x68, 0x69, 0x6a, + 0x6e, 0x72, 0x75, 0x7b, 0x82, 0x83, 0x84, 0x89, 0x8e, 0x92, 0x95, 0x99, 0x9a, 0x94, 0x93, 0x95, + 0x97, 0x99, 0x95, 0x95, 0x93, 0x93, 0x98, 0x99, 0x99, 0x94, 0x92, 0x96, 0x97, 0x93, 0x8e, 0x8e, + 0x8c, 0x89, 0x88, 0x85, 0x7b, 0x6f, 0x6e, 0x78, 0x83, 0x8a, 0x8b, 0x82, 0x6f, 0x64, 0x61, 0x6a, + 0x70, 0x6f, 0x6f, 0x72, 0x7c, 0x83, 0x85, 0x87, 0x88, 0x85, 0x84, 0x86, 0x86, 0x85, 0x89, 0x8f, + 0x92, 0x8f, 0x87, 0x7d, 0x77, 0x76, 0x77, 0x77, 0x76, 0x6d, 0x62, 0x5d, 0x60, 0x68, 0x6e, 0x70, + 0x70, 0x6f, 0x6c, 0x6a, 0x65, 0x5f, 0x5c, 0x5f, 0x68, 0x74, 0x79, 0x77, 0x76, 0x7a, 0x7d, 0x7e, + 0x7e, 0x80, 0x81, 0x87, 0x93, 0xa0, 0xa7, 0xac, 0xac, 0xa9, 0xa8, 0xa8, 0xaa, 0xa8, 0xa2, 0x9c, + 0x9a, 0x9c, 0x9a, 0x97, 0x97, 0x97, 0x95, 0x94, 0x96, 0x93, 0x90, 0x8e, 0x90, 0x94, 0x94, 0x8e, + 0x88, 0x86, 0x86, 0x88, 0x86, 0x84, 0x88, 0x8b, 0x8d, 0x91, 0x96, 0x9b, 0x9a, 0x97, 0x92, 0x8e, + 0x8e, 0x8c, 0x8b, 0x8c, 0x8c, 0x8a, 0x87, 0x83, 0x7d, 0x7a, 0x79, 0x7c, 0x7e, 0x79, 0x75, 0x74, + 0x73, 0x73, 0x74, 0x77, 0x75, 0x6d, 0x66, 0x63, 0x62, 0x5f, 0x5a, 0x59, 0x59, 0x5c, 0x66, 0x70, + 0x71, 0x6d, 0x68, 0x65, 0x66, 0x6a, 0x6d, 0x6e, 0x74, 0x7c, 0x83, 0x86, 0x85, 0x83, 0x7e, 0x75, + 0x6e, 0x6c, 0x6d, 0x6f, 0x73, 0x76, 0x78, 0x7a, 0x78, 0x76, 0x73, 0x75, 0x7e, 0x86, 0x85, 0x7e, + 0x7a, 0x78, 0x78, 0x7a, 0x78, 0x74, 0x75, 0x7e, 0x87, 0x85, 0x7b, 0x74, 0x77, 0x7d, 0x85, 0x8c, + 0x8d, 0x89, 0x80, 0x7a, 0x7b, 0x7d, 0x80, 0x7b, 0x75, 0x72, 0x74, 0x77, 0x7b, 0x79, 0x73, 0x6d, + 0x6a, 0x6a, 0x6c, 0x6c, 0x6f, 0x76, 0x7d, 0x84, 0x85, 0x83, 0x84, 0x88, 0x8c, 0x8b, 0x88, 0x8a, + 0x8f, 0x92, 0x91, 0x8e, 0x8d, 0x8c, 0x8a, 0x8a, 0x8c, 0x86, 0x7d, 0x78, 0x76, 0x79, 0x7e, 0x82, + 0x80, 0x76, 0x6b, 0x68, 0x6a, 0x6b, 0x67, 0x62, 0x62, 0x6a, 0x73, 0x77, 0x7a, 0x81, 0x85, 0x82, + 0x7c, 0x7a, 0x7a, 0x80, 0x83, 0x82, 0x81, 0x87, 0x92, 0x9e, 0xa3, 0xa1, 0x9c, 0x9b, 0x9b, 0x9a, + 0x9a, 0x99, 0x95, 0x94, 0x95, 0x96, 0x93, 0x93, 0x93, 0x8a, 0x7d, 0x71, 0x71, 0x75, 0x77, 0x7a, + 0x7a, 0x79, 0x77, 0x77, 0x76, 0x78, 0x7d, 0x7e, 0x7d, 0x80, 0x83, 0x85, 0x87, 0x8c, 0x8b, 0x85, + 0x80, 0x83, 0x8a, 0x8d, 0x8c, 0x87, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x93, 0x8f, 0x8e, 0x93, 0x96, + 0x95, 0x8f, 0x85, 0x77, 0x72, 0x74, 0x75, 0x72, 0x6c, 0x64, 0x5b, 0x54, 0x51, 0x52, 0x59, 0x61, + 0x65, 0x6a, 0x6f, 0x73, 0x78, 0x7e, 0x85, 0x85, 0x84, 0x87, 0x8e, 0x95, 0x98, 0x95, 0x93, 0x8f, + 0x8a, 0x89, 0x88, 0x89, 0x8a, 0x84, 0x7c, 0x79, 0x7b, 0x82, 0x86, 0x80, 0x72, 0x6b, 0x6e, 0x70, + 0x73, 0x71, 0x6b, 0x67, 0x67, 0x69, 0x6b, 0x71, 0x74, 0x6e, 0x63, 0x5c, 0x61, 0x6d, 0x75, 0x7a, + 0x7e, 0x80, 0x85, 0x8e, 0x95, 0x97, 0x94, 0x8f, 0x8e, 0x94, 0x9b, 0x9c, 0x99, 0x96, 0x96, 0x96, + 0x94, 0x92, 0x91, 0x90, 0x8b, 0x82, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x80, 0x7d, 0x7c, 0x7e, 0x84, + 0x8b, 0x8c, 0x86, 0x7a, 0x74, 0x78, 0x81, 0x85, 0x83, 0x7a, 0x6e, 0x6a, 0x6f, 0x79, 0x86, 0x87, + 0x82, 0x82, 0x86, 0x8a, 0x8c, 0x89, 0x80, 0x7a, 0x78, 0x78, 0x7a, 0x7d, 0x82, 0x82, 0x80, 0x80, + 0x80, 0x7d, 0x79, 0x74, 0x71, 0x6d, 0x6b, 0x69, 0x66, 0x69, 0x6e, 0x70, 0x72, 0x77, 0x7d, 0x87, + 0x91, 0x94, 0x8d, 0x86, 0x84, 0x85, 0x8b, 0x8f, 0x8e, 0x86, 0x79, 0x78, 0x7e, 0x87, 0x8c, 0x88, + 0x84, 0x7e, 0x7c, 0x80, 0x84, 0x88, 0x85, 0x79, 0x74, 0x78, 0x7c, 0x7e, 0x7e, 0x7a, 0x75, 0x76, + 0x77, 0x79, 0x7a, 0x75, 0x70, 0x6c, 0x6c, 0x71, 0x77, 0x7b, 0x80, 0x81, 0x7e, 0x83, 0x89, 0x8d, + 0x8c, 0x87, 0x82, 0x7a, 0x74, 0x70, 0x6b, 0x6b, 0x70, 0x72, 0x6f, 0x6a, 0x67, 0x6f, 0x7e, 0x86, + 0x82, 0x79, 0x77, 0x7d, 0x86, 0x8d, 0x8b, 0x83, 0x7d, 0x7e, 0x89, 0x90, 0x8f, 0x86, 0x7a, 0x74, + 0x74, 0x79, 0x7e, 0x7c, 0x70, 0x68, 0x69, 0x74, 0x7b, 0x7c, 0x7b, 0x78, 0x77, 0x7c, 0x80, 0x80, + 0x7d, 0x7e, 0x83, 0x88, 0x8a, 0x87, 0x86, 0x85, 0x87, 0x85, 0x7d, 0x74, 0x6c, 0x6c, 0x71, 0x73, + 0x74, 0x72, 0x71, 0x74, 0x7b, 0x86, 0x88, 0x83, 0x80, 0x86, 0x91, 0x9d, 0xa4, 0x9e, 0x91, 0x8c, + 0x93, 0x9d, 0xa3, 0xa1, 0x99, 0x94, 0x90, 0x90, 0x93, 0x94, 0x94, 0x93, 0x8f, 0x8e, 0x92, 0x99, + 0x9b, 0x97, 0x8e, 0x8a, 0x88, 0x85, 0x84, 0x82, 0x7d, 0x7c, 0x7b, 0x77, 0x75, 0x77, 0x7c, 0x84, + 0x8c, 0x93, 0x98, 0x9d, 0xa2, 0xa8, 0xa2, 0x98, 0x93, 0x96, 0x9b, 0x9d, 0x99, 0x93, 0x89, 0x7e, + 0x73, 0x71, 0x77, 0x7a, 0x76, 0x71, 0x6e, 0x6e, 0x73, 0x73, 0x6e, 0x65, 0x5e, 0x60, 0x69, 0x74, + 0x78, 0x75, 0x72, 0x70, 0x74, 0x78, 0x78, 0x77, 0x73, 0x71, 0x6e, 0x6c, 0x70, 0x74, 0x72, 0x6e, + 0x6c, 0x6f, 0x75, 0x78, 0x7b, 0x81, 0x82, 0x80, 0x76, 0x6f, 0x70, 0x76, 0x7c, 0x7c, 0x79, 0x77, + 0x77, 0x78, 0x7d, 0x7e, 0x7a, 0x76, 0x75, 0x77, 0x75, 0x6d, 0x67, 0x65, 0x65, 0x67, 0x6c, 0x70, + 0x6f, 0x6c, 0x69, 0x69, 0x6e, 0x78, 0x80, 0x7b, 0x73, 0x72, 0x76, 0x79, 0x7c, 0x80, 0x84, 0x84, + 0x83, 0x81, 0x7e, 0x84, 0x8b, 0x8c, 0x86, 0x79, 0x6f, 0x6d, 0x70, 0x73, 0x72, 0x6c, 0x67, 0x69, + 0x6b, 0x6c, 0x6a, 0x69, 0x6a, 0x6a, 0x6d, 0x6e, 0x6d, 0x6b, 0x69, 0x6f, 0x7a, 0x82, 0x8a, 0x92, + 0x92, 0x8f, 0x94, 0x9a, 0x9a, 0x98, 0x92, 0x8a, 0x83, 0x7d, 0x78, 0x76, 0x76, 0x76, 0x78, 0x74, + 0x71, 0x77, 0x82, 0x88, 0x8d, 0x8e, 0x88, 0x84, 0x86, 0x8c, 0x93, 0x99, 0x9c, 0x98, 0x94, 0x92, + 0x93, 0x93, 0x92, 0x8f, 0x8c, 0x8e, 0x95, 0x98, 0x99, 0x93, 0x8d, 0x92, 0x9c, 0xa1, 0xa0, 0xa1, + 0xa1, 0x9e, 0x9b, 0x9b, 0x9f, 0xa1, 0x9e, 0x98, 0x94, 0x92, 0x95, 0x95, 0x8f, 0x8b, 0x84, 0x79, + 0x76, 0x77, 0x7b, 0x7d, 0x7e, 0x83, 0x84, 0x83, 0x7b, 0x74, 0x73, 0x78, 0x7b, 0x7c, 0x7e, 0x81, + 0x83, 0x83, 0x7d, 0x79, 0x7d, 0x82, 0x89, 0x92, 0x94, 0x8d, 0x80, 0x77, 0x7d, 0x86, 0x8d, 0x8f, + 0x8a, 0x86, 0x88, 0x8b, 0x8c, 0x8d, 0x88, 0x78, 0x6d, 0x69, 0x66, 0x63, 0x5f, 0x59, 0x53, 0x50, + 0x51, 0x51, 0x52, 0x54, 0x5e, 0x6f, 0x7e, 0x81, 0x7b, 0x75, 0x72, 0x77, 0x82, 0x8a, 0x8c, 0x8f, + 0x95, 0x94, 0x8b, 0x82, 0x80, 0x81, 0x83, 0x8a, 0x8c, 0x82, 0x74, 0x6d, 0x6e, 0x74, 0x77, 0x78, + 0x72, 0x6c, 0x6f, 0x76, 0x7d, 0x82, 0x7e, 0x76, 0x72, 0x73, 0x74, 0x78, 0x78, 0x76, 0x75, 0x74, + 0x72, 0x71, 0x73, 0x76, 0x78, 0x7d, 0x86, 0x86, 0x7c, 0x71, 0x6b, 0x67, 0x68, 0x6f, 0x73, 0x77, + 0x79, 0x79, 0x77, 0x73, 0x7b, 0x86, 0x8a, 0x90, 0x94, 0x95, 0x92, 0x8b, 0x87, 0x86, 0x81, 0x7a, + 0x75, 0x74, 0x75, 0x79, 0x7b, 0x80, 0x7e, 0x75, 0x69, 0x62, 0x61, 0x65, 0x68, 0x68, 0x6a, 0x6c, + 0x74, 0x84, 0x8c, 0x8a, 0x86, 0x88, 0x8d, 0x8f, 0x8e, 0x89, 0x81, 0x7a, 0x7a, 0x80, 0x8a, 0x91, + 0x93, 0x94, 0x90, 0x8b, 0x89, 0x87, 0x84, 0x83, 0x82, 0x7e, 0x82, 0x87, 0x8d, 0x97, 0xa0, 0xa2, + 0xa0, 0x9b, 0x95, 0x97, 0x9a, 0x9e, 0x9f, 0x98, 0x94, 0x91, 0x8c, 0x89, 0x81, 0x76, 0x6f, 0x6b, + 0x6a, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x63, 0x62, 0x58, 0x5a, 0x59, 0x59, 0x61, 0x6c, 0x71, 0x75, + 0x7a, 0x78, 0x71, 0x6b, 0x6c, 0x74, 0x7c, 0x82, 0x84, 0x85, 0x86, 0x88, 0x91, 0x9f, 0xa5, 0xa5, + 0xa7, 0xa8, 0xa7, 0xa7, 0xa7, 0xa3, 0x98, 0x8a, 0x82, 0x82, 0x89, 0x8f, 0x8e, 0x8b, 0x89, 0x83, + 0x78, 0x6e, 0x64, 0x68, 0x70, 0x7b, 0x83, 0x84, 0x84, 0x80, 0x79, 0x74, 0x78, 0x7d, 0x81, 0x87, + 0x89, 0x85, 0x7d, 0x74, 0x6c, 0x6c, 0x78, 0x80, 0x7a, 0x78, 0x7b, 0x80, 0x84, 0x89, 0x83, 0x74, + 0x68, 0x65, 0x6a, 0x73, 0x7d, 0x7e, 0x7c, 0x87, 0x8c, 0x8c, 0x86, 0x82, 0x7d, 0x7d, 0x87, 0x83, + 0x7d, 0x7b, 0x6e, 0x5a, 0x4f, 0x58, 0x63, 0x6e, 0x7e, 0x83, 0x87, 0x8b, 0x90, 0x99, 0xa2, 0xad, + 0xb5, 0xb3, 0xac, 0xa5, 0x9a, 0x8d, 0x97, 0xa6, 0xa7, 0x9e, 0x97, 0x96, 0x97, 0x96, 0x8f, 0x89, + 0x83, 0x77, 0x6f, 0x6f, 0x72, 0x76, 0x83, 0x7b, 0x77, 0x82, 0x81, 0x77, 0x6b, 0x62, 0x65, 0x6e, + 0x74, 0x73, 0x68, 0x5f, 0x61, 0x68, 0x7c, 0x8c, 0x92, 0x86, 0x85, 0x89, 0x88, 0x89, 0x8d, 0x8d, + 0x88, 0x81, 0x76, 0x73, 0x7b, 0x83, 0x81, 0x7b, 0x83, 0x87, 0x88, 0x86, 0x85, 0x87, 0x86, 0x7d, + 0x73, 0x6a, 0x6e, 0x80, 0x81, 0x7a, 0x86, 0x86, 0x84, 0x86, 0x85, 0x7d, 0x75, 0x70, 0x6c, 0x69, + 0x69, 0x70, 0x7a, 0x7a, 0x77, 0x78, 0x77, 0x77, 0x7b, 0x71, 0x66, 0x57, 0x55, 0x72, 0x81, 0x7e, + 0x7d, 0x80, 0x89, 0x8b, 0x73, 0x68, 0x6a, 0x67, 0x69, 0x6a, 0x65, 0x5b, 0x5c, 0x5e, 0x55, 0x4f, + 0x53, 0x5a, 0x62, 0x66, 0x69, 0x6a, 0x67, 0x6c, 0x78, 0x83, 0x94, 0x9a, 0x95, 0x8d, 0x86, 0x83, + 0x89, 0x99, 0xa2, 0x90, 0x7d, 0x83, 0x8b, 0x89, 0x7d, 0x71, 0x68, 0x5f, 0x5b, 0x5d, 0x65, 0x7b, + 0x89, 0x93, 0x94, 0x88, 0x80, 0x71, 0x67, 0x6c, 0x76, 0x7e, 0x82, 0x82, 0x80, 0x7a, 0x7e, 0x8a, + 0x99, 0xaa, 0xab, 0xa1, 0xa4, 0xa6, 0xa5, 0x9f, 0x9a, 0x96, 0x94, 0x8c, 0x86, 0x8b, 0x89, 0x8a, + 0x8b, 0x84, 0x77, 0x6e, 0x6d, 0x69, 0x76, 0x90, 0x92, 0x8b, 0x83, 0x8b, 0xa2, 0xa3, 0x9f, 0xa5, + 0xab, 0xa9, 0x91, 0x8b, 0x87, 0x7e, 0x74, 0x6f, 0x72, 0x79, 0x85, 0x94, 0xa1, 0xa6, 0xa6, 0xa9, + 0xa5, 0x9c, 0x99, 0x98, 0x94, 0x9d, 0xb6, 0xb1, 0x9f, 0x97, 0x91, 0x8e, 0x8b, 0x95, 0x9a, 0x92, + 0x83, 0x69, 0x57, 0x61, 0x75, 0x77, 0x6e, 0x65, 0x57, 0x54, 0x5f, 0x5c, 0x5d, 0x69, 0x62, 0x5b, + 0x65, 0x6a, 0x78, 0x8c, 0x92, 0x99, 0x8e, 0x83, 0x85, 0x8a, 0x91, 0x9a, 0xa5, 0xa4, 0x92, 0x86, + 0x82, 0x76, 0x78, 0x78, 0x70, 0x65, 0x64, 0x6c, 0x6d, 0x62, 0x5d, 0x6a, 0x6e, 0x77, 0x7b, 0x6d, + 0x60, 0x58, 0x56, 0x5e, 0x6e, 0x6b, 0x67, 0x6d, 0x6e, 0x72, 0x73, 0x80, 0x88, 0x74, 0x69, 0x7b, + 0x88, 0x92, 0x97, 0x90, 0x90, 0x8a, 0x7c, 0x6b, 0x64, 0x71, 0x77, 0x76, 0x6f, 0x63, 0x61, 0x62, + 0x6d, 0x7e, 0x83, 0x7b, 0x7b, 0x75, 0x82, 0x9a, 0x9e, 0x93, 0x92, 0x90, 0x76, 0x6d, 0x78, 0x70, + 0x66, 0x6b, 0x64, 0x5a, 0x5f, 0x65, 0x6a, 0x73, 0x7b, 0x87, 0x88, 0x78, 0x65, 0x52, 0x60, 0x7b, + 0x8d, 0xa3, 0x9d, 0x8b, 0x83, 0x82, 0x8c, 0x89, 0x83, 0x8a, 0x85, 0x73, 0x6a, 0x6a, 0x61, 0x77, + 0x8d, 0x83, 0x75, 0x6e, 0x69, 0x5d, 0x5c, 0x70, 0x7b, 0x76, 0x6c, 0x63, 0x5d, 0x67, 0x7d, 0x8e, + 0xa3, 0xa7, 0xa3, 0xa4, 0xa6, 0xa6, 0xad, 0xac, 0x9a, 0x8a, 0x7e, 0x6b, 0x53, 0x44, 0x4a, 0x57, + 0x5d, 0x69, 0x75, 0x7e, 0x80, 0x73, 0x65, 0x77, 0x8a, 0x84, 0x76, 0x78, 0x8c, 0x9a, 0xa2, 0xa7, + 0xae, 0xb9, 0xbd, 0xbe, 0xc6, 0xd1, 0xcb, 0xb6, 0xa5, 0xa2, 0xa7, 0xab, 0xaa, 0xaa, 0xa7, 0x98, + 0x8e, 0x92, 0x8f, 0x92, 0x8d, 0x83, 0x7b, 0x6f, 0x5d, 0x4f, 0x56, 0x6c, 0x7e, 0x82, 0x83, 0x82, + 0x8f, 0xaf, 0xba, 0xc4, 0xc8, 0xad, 0x87, 0x61, 0x47, 0x4a, 0x62, 0x66, 0x63, 0x71, 0x7a, 0x70, + 0x6c, 0x71, 0x76, 0x85, 0x95, 0x96, 0x84, 0x74, 0x6e, 0x6d, 0x73, 0x89, 0x9e, 0x9f, 0x8b, 0x7b, + 0x78, 0x83, 0x87, 0x85, 0x76, 0x63, 0x52, 0x4b, 0x3e, 0x40, 0x53, 0x5a, 0x61, 0x60, 0x56, 0x50, + 0x4e, 0x60, 0x74, 0x81, 0x82, 0x6d, 0x65, 0x66, 0x62, 0x65, 0x7d, 0x9f, 0xa6, 0xa8, 0xb4, 0xc0, + 0xc2, 0xc2, 0xaa, 0x8f, 0x8b, 0x86, 0x77, 0x6a, 0x65, 0x62, 0x62, 0x6b, 0x6e, 0x72, 0x76, 0x7a, + 0x75, 0x71, 0x7c, 0x75, 0x63, 0x5a, 0x5a, 0x5e, 0x63, 0x69, 0x7a, 0x78, 0x67, 0x74, 0x8a, 0x99, + 0x93, 0x91, 0x98, 0x9b, 0x99, 0x95, 0x8b, 0x8d, 0x8f, 0x83, 0x7c, 0x6f, 0x77, 0x8c, 0x93, 0x8c, + 0x83, 0x76, 0x61, 0x4c, 0x4e, 0x60, 0x7b, 0x97, 0xa1, 0x98, 0x91, 0x9e, 0xa9, 0xb5, 0xbf, 0xb2, + 0x8f, 0x73, 0x6c, 0x6f, 0x64, 0x5d, 0x69, 0x75, 0x7a, 0x77, 0x70, 0x76, 0x79, 0x81, 0x84, 0x82, + 0x81, 0x77, 0x87, 0x9a, 0xa0, 0xae, 0xc4, 0xc0, 0xa5, 0x90, 0x85, 0x82, 0x80, 0x89, 0x8d, 0x79, + 0x64, 0x52, 0x4f, 0x4e, 0x5b, 0x61, 0x59, 0x55, 0x4b, 0x3e, 0x45, 0x4f, 0x51, 0x52, 0x50, 0x46, + 0x42, 0x48, 0x52, 0x6d, 0x8e, 0xa3, 0xad, 0xa0, 0x95, 0x98, 0x98, 0x9e, 0x9c, 0x8c, 0x7c, 0x6f, + 0x68, 0x67, 0x63, 0x74, 0x7e, 0x7b, 0x78, 0x70, 0x66, 0x61, 0x5a, 0x50, 0x47, 0x41, 0x3b, 0x47, + 0x55, 0x64, 0x76, 0x94, 0xaa, 0xad, 0xa7, 0xa2, 0xa2, 0xaf, 0xc2, 0xc2, 0xb9, 0xb8, 0xb9, 0xbb, + 0xba, 0xb7, 0xb3, 0xb7, 0xaf, 0x96, 0x8a, 0x86, 0x88, 0x88, 0x7a, 0x71, 0x6c, 0x68, 0x75, 0x88, + 0x9b, 0xb0, 0xc0, 0xc4, 0xc1, 0xb0, 0xa8, 0x9f, 0x8f, 0x86, 0x71, 0x59, 0x51, 0x53, 0x56, 0x53, + 0x66, 0x7e, 0x87, 0x7a, 0x77, 0x84, 0x94, 0xa1, 0x9d, 0x90, 0x86, 0x71, 0x6e, 0x79, 0x86, 0x97, + 0xaa, 0xb1, 0xad, 0xa2, 0x9b, 0x9b, 0x8f, 0x90, 0x91, 0x73, 0x67, 0x60, 0x61, 0x66, 0x62, 0x68, + 0x72, 0x71, 0x5b, 0x4e, 0x55, 0x5b, 0x5b, 0x54, 0x4c, 0x3c, 0x2f, 0x32, 0x43, 0x5b, 0x79, 0x98, + 0xac, 0xb1, 0xa9, 0xb0, 0xb6, 0xac, 0xac, 0xaa, 0x98, 0x81, 0x81, 0x8c, 0x95, 0x99, 0x9e, 0xa9, + 0x9f, 0x84, 0x7a, 0x77, 0x7a, 0x7d, 0x7c, 0x70, 0x5d, 0x54, 0x57, 0x65, 0x7a, 0x94, 0xa3, 0xab, + 0xa8, 0xa9, 0xbb, 0xb7, 0xad, 0xa1, 0x8c, 0x7e, 0x75, 0x7c, 0x80, 0x81, 0x82, 0x88, 0x8d, 0x7d, + 0x69, 0x6a, 0x6c, 0x6c, 0x67, 0x61, 0x53, 0x4c, 0x54, 0x57, 0x5f, 0x76, 0x8a, 0x9c, 0xa9, 0xa1, + 0xa1, 0x9e, 0x85, 0x75, 0x61, 0x41, 0x38, 0x45, 0x4c, 0x4e, 0x57, 0x63, 0x69, 0x61, 0x4e, 0x47, + 0x53, 0x5e, 0x67, 0x64, 0x5a, 0x4c, 0x47, 0x4a, 0x4f, 0x5b, 0x6c, 0x78, 0x83, 0x83, 0x82, 0x88, + 0x85, 0x84, 0x87, 0x75, 0x52, 0x5a, 0x73, 0x7e, 0x85, 0x88, 0x90, 0x89, 0x70, 0x5a, 0x5e, 0x6d, + 0x76, 0x72, 0x66, 0x59, 0x50, 0x52, 0x58, 0x6a, 0x84, 0x9a, 0xb3, 0xbf, 0xbc, 0xc0, 0xbb, 0xb6, + 0xb3, 0xaa, 0x9b, 0x82, 0x7e, 0x92, 0x96, 0x92, 0x9c, 0xb0, 0xb2, 0x9b, 0x84, 0x86, 0x8e, 0x94, + 0x8b, 0x82, 0x81, 0x7c, 0x71, 0x71, 0x84, 0x8f, 0x98, 0xa2, 0x9f, 0xa0, 0xa0, 0x9f, 0xa0, 0xa0, + 0x9b, 0x8e, 0x81, 0x78, 0x8e, 0x99, 0x9c, 0xaa, 0xb5, 0xb3, 0xa0, 0x90, 0x8e, 0x8e, 0x88, 0x72, + 0x65, 0x5f, 0x61, 0x6a, 0x71, 0x7e, 0x89, 0x90, 0x96, 0x9e, 0xa0, 0x9b, 0x91, 0x82, 0x71, 0x65, + 0x58, 0x54, 0x56, 0x6a, 0x79, 0x81, 0x92, 0x97, 0x8d, 0x78, 0x6e, 0x6f, 0x76, 0x72, 0x6e, 0x75, + 0x78, 0x7c, 0x83, 0x80, 0x81, 0x89, 0x8d, 0x8d, 0x90, 0x90, 0x94, 0x97, 0x93, 0x89, 0x7d, 0x72, + 0x6d, 0x68, 0x79, 0x8a, 0x94, 0x9a, 0x91, 0x7a, 0x63, 0x60, 0x69, 0x6b, 0x61, 0x5c, 0x5a, 0x59, + 0x5d, 0x65, 0x71, 0x83, 0x97, 0x9e, 0xa3, 0xa7, 0xa3, 0xa2, 0x9a, 0x86, 0x76, 0x6a, 0x63, 0x61, + 0x6a, 0x77, 0x83, 0x88, 0x87, 0x81, 0x74, 0x6b, 0x6c, 0x6f, 0x6e, 0x67, 0x66, 0x63, 0x61, 0x61, + 0x65, 0x6a, 0x76, 0x85, 0x8d, 0x91, 0x91, 0x92, 0x93, 0x8c, 0x84, 0x81, 0x7c, 0x77, 0x71, 0x77, + 0x83, 0x91, 0x97, 0x94, 0x8b, 0x82, 0x7c, 0x82, 0x87, 0x86, 0x7d, 0x71, 0x6c, 0x6f, 0x79, 0x8c, + 0x9a, 0xa0, 0x9b, 0x8e, 0x82, 0x79, 0x76, 0x76, 0x6e, 0x5e, 0x55, 0x52, 0x53, 0x56, 0x60, 0x6c, + 0x75, 0x74, 0x6b, 0x66, 0x69, 0x70, 0x79, 0x7c, 0x79, 0x73, 0x6a, 0x67, 0x67, 0x6f, 0x7b, 0x85, + 0x88, 0x87, 0x85, 0x89, 0x8e, 0x91, 0x95, 0x96, 0x8f, 0x86, 0x81, 0x7e, 0x79, 0x7b, 0x82, 0x86, + 0x85, 0x77, 0x67, 0x5e, 0x5a, 0x5b, 0x5b, 0x5c, 0x59, 0x55, 0x57, 0x5e, 0x6e, 0x80, 0x8d, 0x94, + 0x93, 0x92, 0x97, 0x9f, 0xa7, 0xae, 0xad, 0xa6, 0xa5, 0xab, 0xaf, 0xb5, 0xbb, 0xbf, 0xba, 0xad, + 0xa1, 0x97, 0x8f, 0x8e, 0x8f, 0x8a, 0x81, 0x74, 0x6b, 0x64, 0x61, 0x65, 0x68, 0x61, 0x56, 0x4d, + 0x51, 0x56, 0x5b, 0x5f, 0x5c, 0x5a, 0x5c, 0x68, 0x77, 0x82, 0x93, 0xa3, 0xaa, 0xa7, 0x9b, 0x92, + 0x8a, 0x87, 0x89, 0x8b, 0x8b, 0x86, 0x80, 0x7d, 0x82, 0x8e, 0x9c, 0xa1, 0x9b, 0x8d, 0x7e, 0x7a, + 0x7c, 0x80, 0x7c, 0x70, 0x68, 0x62, 0x64, 0x66, 0x6f, 0x81, 0x89, 0x88, 0x81, 0x73, 0x6a, 0x6b, + 0x73, 0x7b, 0x80, 0x7e, 0x74, 0x6a, 0x69, 0x70, 0x80, 0x91, 0x96, 0x93, 0x8a, 0x85, 0x86, 0x91, + 0x9c, 0x99, 0x93, 0x91, 0x92, 0x96, 0x9c, 0xa5, 0xb0, 0xb5, 0xad, 0x9b, 0x84, 0x72, 0x66, 0x5f, + 0x60, 0x62, 0x5f, 0x57, 0x58, 0x5e, 0x66, 0x75, 0x82, 0x88, 0x84, 0x7d, 0x82, 0x8b, 0x94, 0x96, + 0x93, 0x8f, 0x8c, 0x8b, 0x8a, 0x89, 0x8d, 0x94, 0x9a, 0x97, 0x8d, 0x88, 0x87, 0x83, 0x82, 0x86, + 0x8a, 0x83, 0x79, 0x78, 0x7b, 0x88, 0x95, 0x98, 0x91, 0x87, 0x88, 0x92, 0x99, 0x9c, 0x94, 0x89, + 0x81, 0x7d, 0x81, 0x84, 0x8a, 0x94, 0x97, 0x90, 0x86, 0x7b, 0x79, 0x7a, 0x7b, 0x80, 0x80, 0x77, + 0x6c, 0x66, 0x64, 0x6e, 0x7d, 0x82, 0x78, 0x65, 0x56, 0x56, 0x5e, 0x63, 0x63, 0x5a, 0x4f, 0x48, + 0x49, 0x4f, 0x58, 0x6a, 0x82, 0x8f, 0x88, 0x77, 0x70, 0x6c, 0x6f, 0x77, 0x7e, 0x80, 0x73, 0x67, + 0x5e, 0x5c, 0x67, 0x76, 0x7d, 0x77, 0x69, 0x60, 0x64, 0x6d, 0x75, 0x7b, 0x79, 0x76, 0x75, 0x74, + 0x73, 0x74, 0x7b, 0x83, 0x80, 0x6c, 0x55, 0x4a, 0x45, 0x4c, 0x58, 0x65, 0x6c, 0x6c, 0x69, 0x66, + 0x69, 0x79, 0x89, 0x8f, 0x8d, 0x8d, 0x97, 0xa0, 0xa5, 0xa8, 0xa4, 0x9a, 0x95, 0x9a, 0xa0, 0x9f, + 0xa3, 0xab, 0xb3, 0xb1, 0xa7, 0x9b, 0x93, 0x8a, 0x87, 0x84, 0x7c, 0x70, 0x67, 0x62, 0x61, 0x65, + 0x6b, 0x6c, 0x62, 0x56, 0x54, 0x58, 0x5e, 0x64, 0x68, 0x6f, 0x78, 0x86, 0x97, 0xa0, 0xa9, 0xb6, + 0xbe, 0xbd, 0xad, 0x9c, 0x94, 0x97, 0xa0, 0xad, 0xb0, 0xa7, 0x9c, 0x94, 0x92, 0x99, 0xa5, 0xac, + 0xa4, 0x92, 0x82, 0x81, 0x83, 0x83, 0x82, 0x78, 0x6a, 0x63, 0x67, 0x6a, 0x6a, 0x75, 0x86, 0x8e, + 0x8a, 0x7c, 0x75, 0x76, 0x7a, 0x82, 0x88, 0x87, 0x7e, 0x79, 0x7c, 0x84, 0x90, 0x9e, 0xa4, 0xa0, + 0x99, 0x94, 0x8e, 0x87, 0x89, 0x92, 0x99, 0x97, 0x95, 0x97, 0x91, 0x8e, 0x96, 0x9e, 0x9d, 0x91, + 0x7e, 0x70, 0x64, 0x62, 0x6b, 0x71, 0x6c, 0x63, 0x61, 0x63, 0x67, 0x74, 0x80, 0x83, 0x7b, 0x75, + 0x72, 0x70, 0x70, 0x74, 0x74, 0x6e, 0x66, 0x66, 0x69, 0x69, 0x6f, 0x7e, 0x88, 0x87, 0x83, 0x82, + 0x7e, 0x78, 0x78, 0x79, 0x7a, 0x77, 0x7a, 0x81, 0x7d, 0x7e, 0x88, 0x8c, 0x87, 0x84, 0x88, 0x8e, + 0x92, 0x97, 0x97, 0x90, 0x89, 0x88, 0x8a, 0x83, 0x7c, 0x86, 0x94, 0x96, 0x8b, 0x7e, 0x79, 0x78, + 0x75, 0x75, 0x71, 0x68, 0x5c, 0x57, 0x5c, 0x61, 0x69, 0x70, 0x6d, 0x68, 0x66, 0x67, 0x64, 0x63, + 0x65, 0x5e, 0x4f, 0x45, 0x42, 0x47, 0x4f, 0x5a, 0x65, 0x6b, 0x66, 0x59, 0x54, 0x57, 0x63, 0x72, + 0x7c, 0x7d, 0x7a, 0x78, 0x7c, 0x88, 0x97, 0xa2, 0xa0, 0x9a, 0x98, 0x96, 0x94, 0x95, 0x9a, 0xa2, + 0xa5, 0x9d, 0x96, 0x96, 0x94, 0x96, 0x99, 0x98, 0x8e, 0x79, 0x63, 0x5e, 0x63, 0x6d, 0x76, 0x76, + 0x72, 0x6d, 0x6a, 0x66, 0x65, 0x6f, 0x80, 0x8c, 0x91, 0x92, 0x93, 0x91, 0x8d, 0x8b, 0x8a, 0x8b, + 0x8c, 0x88, 0x87, 0x86, 0x88, 0x90, 0x96, 0x94, 0x86, 0x7b, 0x7e, 0x84, 0x8d, 0x95, 0x98, 0x98, + 0x91, 0x8b, 0x86, 0x88, 0x94, 0x9a, 0x91, 0x7c, 0x6b, 0x64, 0x64, 0x6b, 0x70, 0x70, 0x6e, 0x6d, + 0x76, 0x85, 0x90, 0x98, 0x97, 0x8f, 0x84, 0x7c, 0x82, 0x8c, 0x92, 0x95, 0x94, 0x8f, 0x89, 0x89, + 0x91, 0x94, 0x97, 0x96, 0x8e, 0x87, 0x84, 0x88, 0x83, 0x74, 0x6d, 0x6a, 0x65, 0x60, 0x65, 0x6e, + 0x6f, 0x6d, 0x6e, 0x72, 0x78, 0x71, 0x63, 0x59, 0x5a, 0x62, 0x6b, 0x74, 0x75, 0x70, 0x6c, 0x71, + 0x7d, 0x8e, 0x99, 0x93, 0x80, 0x6e, 0x71, 0x7e, 0x8f, 0x9f, 0xa2, 0x96, 0x8a, 0x91, 0xa1, 0xb5, + 0xc6, 0xca, 0xbb, 0xa3, 0x84, 0x71, 0x73, 0x80, 0x87, 0x7b, 0x70, 0x6f, 0x74, 0x87, 0x96, 0xa0, + 0xa1, 0x9c, 0x95, 0x8e, 0x91, 0x98, 0x99, 0x94, 0x8e, 0x86, 0x7d, 0x7b, 0x83, 0x86, 0x82, 0x85, + 0x88, 0x87, 0x7e, 0x6a, 0x5a, 0x5a, 0x6b, 0x7e, 0x8e, 0x94, 0x8c, 0x81, 0x7c, 0x7e, 0x89, 0x94, + 0x95, 0x88, 0x72, 0x68, 0x69, 0x6f, 0x75, 0x71, 0x61, 0x4b, 0x47, 0x55, 0x6a, 0x83, 0x93, 0x94, + 0x89, 0x79, 0x6f, 0x71, 0x81, 0x90, 0x90, 0x84, 0x70, 0x62, 0x67, 0x71, 0x75, 0x75, 0x71, 0x6c, + 0x62, 0x64, 0x6f, 0x71, 0x6c, 0x62, 0x53, 0x4a, 0x54, 0x66, 0x72, 0x75, 0x7d, 0x89, 0x8b, 0x85, + 0x79, 0x6f, 0x6b, 0x70, 0x77, 0x7d, 0x7a, 0x6d, 0x65, 0x60, 0x60, 0x6b, 0x76, 0x7b, 0x76, 0x69, + 0x65, 0x6d, 0x79, 0x84, 0x88, 0x81, 0x73, 0x73, 0x82, 0x8d, 0x99, 0xa4, 0xa3, 0x8f, 0x73, 0x68, + 0x6b, 0x79, 0x89, 0x8a, 0x7b, 0x66, 0x5a, 0x5c, 0x67, 0x76, 0x85, 0x89, 0x88, 0x86, 0x8a, 0x96, + 0xa1, 0xa4, 0x9d, 0x95, 0x8c, 0x89, 0x93, 0x9c, 0xa0, 0x9f, 0x9d, 0x9b, 0x9a, 0x96, 0x92, 0x90, + 0x96, 0xa1, 0xa6, 0xa1, 0x93, 0x85, 0x79, 0x73, 0x78, 0x7e, 0x80, 0x75, 0x60, 0x54, 0x55, 0x5e, + 0x64, 0x63, 0x5a, 0x4e, 0x4a, 0x57, 0x69, 0x77, 0x7d, 0x80, 0x7c, 0x74, 0x77, 0x83, 0x95, 0xa9, + 0xb4, 0xad, 0x9a, 0x8d, 0x89, 0x8d, 0x97, 0x9c, 0x95, 0x89, 0x80, 0x77, 0x7e, 0x89, 0x87, 0x79, + 0x6b, 0x63, 0x64, 0x6f, 0x7a, 0x7c, 0x76, 0x75, 0x7a, 0x7a, 0x79, 0x7a, 0x76, 0x76, 0x7d, 0x86, + 0x87, 0x82, 0x7d, 0x7a, 0x7e, 0x8d, 0x9d, 0xa9, 0xab, 0xa1, 0x94, 0x91, 0x99, 0x9e, 0x9f, 0x9e, + 0x98, 0x93, 0x97, 0xa2, 0xaa, 0xb3, 0xb9, 0xb5, 0x9f, 0x8e, 0x8c, 0x92, 0x9b, 0x9d, 0x9a, 0x90, + 0x89, 0x87, 0x87, 0x8c, 0x8c, 0x80, 0x70, 0x6d, 0x6a, 0x6b, 0x74, 0x78, 0x6e, 0x63, 0x62, 0x6a, + 0x7a, 0x8d, 0x95, 0x8d, 0x83, 0x85, 0x8c, 0x94, 0x97, 0x94, 0x90, 0x8e, 0x93, 0x92, 0x8d, 0x89, + 0x7c, 0x6b, 0x67, 0x6b, 0x6b, 0x6e, 0x6d, 0x64, 0x5e, 0x5f, 0x5f, 0x5c, 0x5b, 0x5d, 0x5c, 0x5c, + 0x65, 0x6f, 0x74, 0x7a, 0x7d, 0x78, 0x70, 0x71, 0x74, 0x75, 0x71, 0x69, 0x59, 0x49, 0x49, 0x4f, + 0x58, 0x63, 0x64, 0x5b, 0x51, 0x51, 0x5c, 0x6c, 0x73, 0x66, 0x4c, 0x44, 0x52, 0x68, 0x7c, 0x89, + 0x8a, 0x81, 0x7b, 0x79, 0x7c, 0x87, 0x91, 0x8e, 0x85, 0x80, 0x7b, 0x7a, 0x81, 0x85, 0x81, 0x81, + 0x89, 0x8e, 0x92, 0x8f, 0x8b, 0x85, 0x7d, 0x7b, 0x7b, 0x7e, 0x84, 0x86, 0x88, 0x8d, 0x96, 0xa0, + 0xa8, 0xa5, 0x95, 0x7d, 0x75, 0x7a, 0x85, 0x94, 0x98, 0x8e, 0x7e, 0x76, 0x75, 0x7e, 0x8c, 0x92, + 0x86, 0x75, 0x6f, 0x6f, 0x71, 0x77, 0x79, 0x71, 0x6a, 0x6c, 0x73, 0x83, 0x8c, 0x8d, 0x86, 0x87, + 0x92, 0x9e, 0xab, 0xb4, 0xb5, 0xae, 0xa4, 0x99, 0x96, 0x98, 0x8e, 0x73, 0x5d, 0x56, 0x5b, 0x65, + 0x6c, 0x70, 0x6f, 0x65, 0x5e, 0x5d, 0x62, 0x6a, 0x6a, 0x5f, 0x5a, 0x5f, 0x69, 0x7b, 0x91, 0x9f, + 0x9f, 0x9c, 0x9e, 0xa4, 0xa9, 0xa3, 0x96, 0x8d, 0x89, 0x86, 0x84, 0x8d, 0x94, 0x90, 0x84, 0x7b, + 0x7e, 0x83, 0x86, 0x84, 0x74, 0x66, 0x68, 0x70, 0x80, 0x8e, 0x8f, 0x86, 0x7b, 0x79, 0x83, 0x93, + 0xa1, 0x9f, 0x8d, 0x7d, 0x74, 0x74, 0x83, 0x8e, 0x8d, 0x86, 0x83, 0x84, 0x86, 0x8a, 0x8b, 0x8a, + 0x86, 0x89, 0x8d, 0x92, 0x9c, 0xa3, 0xa6, 0xa5, 0xa7, 0xa8, 0xab, 0xae, 0xab, 0x9d, 0x94, 0x97, + 0x9c, 0xa0, 0xa4, 0xa2, 0x9b, 0x90, 0x87, 0x82, 0x83, 0x81, 0x6e, 0x51, 0x3e, 0x37, 0x3a, 0x4d, + 0x5d, 0x5c, 0x51, 0x4a, 0x4d, 0x5b, 0x6b, 0x73, 0x6f, 0x68, 0x6f, 0x7a, 0x87, 0x98, 0xa2, 0x9f, + 0x91, 0x87, 0x82, 0x84, 0x7d, 0x6d, 0x5c, 0x5b, 0x64, 0x69, 0x71, 0x74, 0x6f, 0x5e, 0x52, 0x53, + 0x5b, 0x60, 0x5d, 0x5a, 0x5a, 0x61, 0x69, 0x77, 0x8d, 0x9d, 0x9c, 0x8e, 0x89, 0x88, 0x89, 0x8b, + 0x8b, 0x87, 0x88, 0x8d, 0x90, 0x99, 0xa9, 0xad, 0x9f, 0x8b, 0x80, 0x74, 0x6f, 0x6f, 0x6a, 0x5f, + 0x54, 0x4f, 0x57, 0x6d, 0x79, 0x78, 0x6d, 0x6a, 0x71, 0x7e, 0x87, 0x83, 0x72, 0x61, 0x5c, 0x60, + 0x6f, 0x84, 0x8b, 0x84, 0x7b, 0x81, 0x8a, 0x8e, 0x8a, 0x7b, 0x64, 0x56, 0x54, 0x58, 0x60, 0x66, + 0x6f, 0x74, 0x78, 0x7c, 0x79, 0x7a, 0x7b, 0x73, 0x68, 0x64, 0x64, 0x68, 0x6f, 0x72, 0x6e, 0x64, + 0x62, 0x66, 0x72, 0x82, 0x81, 0x6e, 0x5f, 0x60, 0x69, 0x7c, 0x91, 0x98, 0x92, 0x89, 0x8b, 0x9a, + 0xb2, 0xbe, 0xb7, 0xaa, 0xa9, 0xb4, 0xc0, 0xd0, 0xdd, 0xda, 0xc8, 0xb7, 0xb0, 0xaf, 0xaf, 0xa8, + 0x9b, 0x92, 0x96, 0x9b, 0x9a, 0x9c, 0x97, 0x86, 0x6f, 0x65, 0x64, 0x67, 0x68, 0x5c, 0x50, 0x51, + 0x60, 0x71, 0x84, 0x95, 0x9f, 0x9a, 0x8f, 0x90, 0x9a, 0xa2, 0x9c, 0x8d, 0x80, 0x7c, 0x80, 0x88, + 0x9b, 0xab, 0xa7, 0x96, 0x89, 0x7e, 0x79, 0x76, 0x6f, 0x5f, 0x51, 0x4e, 0x51, 0x62, 0x75, 0x7a, + 0x72, 0x69, 0x6c, 0x76, 0x82, 0x7c, 0x6d, 0x5c, 0x55, 0x5a, 0x64, 0x73, 0x7e, 0x7e, 0x74, 0x71, + 0x78, 0x82, 0x88, 0x82, 0x73, 0x6b, 0x6f, 0x79, 0x8b, 0x9f, 0xab, 0xb2, 0xb5, 0xb8, 0xbc, 0xc1, + 0xc2, 0xbb, 0xaa, 0x9e, 0x9a, 0x9b, 0xa7, 0xb3, 0xaf, 0xa1, 0x93, 0x87, 0x83, 0x89, 0x89, 0x77, + 0x5e, 0x52, 0x54, 0x5f, 0x72, 0x7a, 0x71, 0x60, 0x55, 0x55, 0x62, 0x6e, 0x6a, 0x5c, 0x50, 0x53, + 0x5c, 0x6b, 0x79, 0x7e, 0x75, 0x67, 0x5f, 0x5e, 0x68, 0x71, 0x6a, 0x59, 0x52, 0x57, 0x61, 0x6f, + 0x7c, 0x7d, 0x73, 0x6e, 0x71, 0x79, 0x82, 0x7d, 0x6b, 0x5b, 0x5d, 0x6a, 0x7e, 0x95, 0x9e, 0x9b, + 0x90, 0x89, 0x87, 0x8a, 0x88, 0x7a, 0x6c, 0x63, 0x64, 0x69, 0x75, 0x83, 0x84, 0x77, 0x67, 0x5e, + 0x5d, 0x69, 0x72, 0x6c, 0x5d, 0x54, 0x58, 0x68, 0x83, 0x9b, 0xa6, 0x9d, 0x92, 0x8e, 0x96, 0xa1, + 0x9e, 0x8c, 0x78, 0x74, 0x7d, 0x98, 0xad, 0xb0, 0xa4, 0x97, 0x92, 0x90, 0x91, 0x90, 0x82, 0x6d, + 0x68, 0x6f, 0x75, 0x7e, 0x83, 0x7b, 0x72, 0x70, 0x73, 0x7b, 0x82, 0x7e, 0x76, 0x6c, 0x6c, 0x72, + 0x80, 0x97, 0xa6, 0xa7, 0xa1, 0x98, 0x90, 0x92, 0x99, 0x97, 0x87, 0x6f, 0x64, 0x66, 0x76, 0x8b, + 0x91, 0x84, 0x73, 0x6b, 0x6c, 0x7c, 0x90, 0x99, 0x92, 0x8a, 0x8a, 0x95, 0xa9, 0xb2, 0xa7, 0x93, + 0x87, 0x84, 0x88, 0x88, 0x79, 0x61, 0x4f, 0x4e, 0x5b, 0x6c, 0x77, 0x78, 0x72, 0x70, 0x70, 0x6b, + 0x6d, 0x75, 0x73, 0x65, 0x5f, 0x69, 0x78, 0x89, 0x91, 0x94, 0x95, 0x91, 0x8a, 0x85, 0x89, 0x89, + 0x80, 0x71, 0x69, 0x6d, 0x7a, 0x8c, 0x98, 0x9a, 0x8e, 0x82, 0x77, 0x7d, 0x8c, 0x88, 0x6e, 0x56, + 0x4d, 0x52, 0x67, 0x7d, 0x89, 0x86, 0x80, 0x7b, 0x84, 0x97, 0x9d, 0x8d, 0x72, 0x67, 0x6a, 0x76, + 0x87, 0x93, 0x97, 0x97, 0x95, 0x96, 0x9a, 0x9b, 0x8e, 0x79, 0x71, 0x79, 0x81, 0x87, 0x8f, 0x94, + 0x94, 0x92, 0x9a, 0xa4, 0xac, 0xae, 0xa8, 0x9e, 0x95, 0x8d, 0x8b, 0x95, 0xa0, 0xa3, 0x9a, 0x8d, + 0x80, 0x78, 0x7c, 0x7a, 0x65, 0x47, 0x33, 0x34, 0x48, 0x64, 0x75, 0x74, 0x67, 0x60, 0x65, 0x6f, + 0x76, 0x77, 0x6f, 0x62, 0x63, 0x70, 0x89, 0x98, 0x96, 0x89, 0x83, 0x85, 0x85, 0x89, 0x8b, 0x87, + 0x7e, 0x78, 0x79, 0x83, 0x93, 0x99, 0x98, 0x9a, 0x9d, 0x9a, 0x96, 0x92, 0x8d, 0x84, 0x76, 0x75, + 0x7e, 0x8b, 0x99, 0x9e, 0x99, 0x8d, 0x83, 0x7d, 0x81, 0x82, 0x74, 0x63, 0x58, 0x5a, 0x68, 0x7c, + 0x88, 0x86, 0x7c, 0x76, 0x73, 0x79, 0x8b, 0x8f, 0x80, 0x68, 0x58, 0x57, 0x62, 0x75, 0x82, 0x81, + 0x78, 0x76, 0x77, 0x7e, 0x87, 0x82, 0x72, 0x62, 0x60, 0x6b, 0x7c, 0x8d, 0x93, 0x8e, 0x87, 0x82, + 0x7d, 0x7c, 0x76, 0x68, 0x59, 0x53, 0x52, 0x53, 0x58, 0x5f, 0x65, 0x67, 0x6a, 0x71, 0x78, 0x7d, + 0x7c, 0x6f, 0x60, 0x5e, 0x65, 0x75, 0x8a, 0x94, 0x95, 0x8c, 0x84, 0x84, 0x87, 0x89, 0x82, 0x6f, + 0x61, 0x5d, 0x65, 0x7b, 0x8e, 0x8d, 0x7e, 0x75, 0x74, 0x7d, 0x8b, 0x8f, 0x85, 0x74, 0x72, 0x7a, + 0x84, 0x8c, 0x91, 0x93, 0x91, 0x8f, 0x8f, 0x94, 0x93, 0x8a, 0x7c, 0x6c, 0x6b, 0x70, 0x7a, 0x86, + 0x87, 0x83, 0x79, 0x74, 0x72, 0x75, 0x7c, 0x7d, 0x75, 0x6d, 0x6c, 0x6f, 0x7c, 0x87, 0x88, 0x83, + 0x83, 0x8b, 0x94, 0x9d, 0x9a, 0x90, 0x84, 0x85, 0x90, 0xa0, 0xb0, 0xb9, 0xb8, 0xaf, 0xab, 0xab, + 0xb0, 0xb3, 0xa6, 0x8c, 0x79, 0x79, 0x84, 0x9b, 0xae, 0xb1, 0xa5, 0x9c, 0x9d, 0x9f, 0xa2, 0xa2, + 0x91, 0x75, 0x61, 0x59, 0x63, 0x72, 0x78, 0x78, 0x71, 0x6b, 0x6b, 0x68, 0x63, 0x5b, 0x50, 0x4c, + 0x52, 0x59, 0x65, 0x74, 0x7d, 0x85, 0x8f, 0x9e, 0xa9, 0xad, 0xb0, 0xaf, 0xa2, 0x98, 0x97, 0x9b, + 0xab, 0xb3, 0xae, 0xa2, 0x95, 0x8e, 0x8e, 0x90, 0x8b, 0x78, 0x5c, 0x4d, 0x4d, 0x5e, 0x74, 0x7c, + 0x74, 0x67, 0x62, 0x64, 0x6e, 0x78, 0x76, 0x6a, 0x61, 0x61, 0x68, 0x75, 0x7e, 0x82, 0x7c, 0x7a, + 0x88, 0x97, 0xa2, 0xa5, 0xa1, 0x97, 0x8d, 0x8d, 0x92, 0x95, 0x8f, 0x87, 0x7e, 0x79, 0x7b, 0x80, + 0x83, 0x80, 0x72, 0x64, 0x5f, 0x5f, 0x65, 0x6e, 0x6e, 0x67, 0x60, 0x5c, 0x5d, 0x64, 0x68, 0x66, + 0x5f, 0x53, 0x49, 0x45, 0x4c, 0x5a, 0x65, 0x65, 0x62, 0x67, 0x72, 0x79, 0x71, 0x5f, 0x4b, 0x43, + 0x48, 0x5e, 0x7a, 0x87, 0x85, 0x7b, 0x7e, 0x8b, 0x9b, 0xa2, 0x95, 0x7b, 0x6c, 0x6e, 0x7c, 0x92, + 0x9e, 0x9e, 0x94, 0x88, 0x85, 0x83, 0x7e, 0x77, 0x6a, 0x5a, 0x53, 0x4e, 0x4b, 0x59, 0x6a, 0x74, + 0x7d, 0x87, 0x8d, 0x8b, 0x87, 0x83, 0x7e, 0x7c, 0x80, 0x84, 0x8d, 0x9d, 0xa3, 0x9c, 0x90, 0x8d, + 0x93, 0x9c, 0x9f, 0x94, 0x80, 0x71, 0x74, 0x80, 0x91, 0x9e, 0x9c, 0x92, 0x92, 0x9c, 0xae, 0xbd, + 0xbe, 0xb3, 0xa0, 0x94, 0x92, 0x98, 0xa3, 0xa4, 0x9e, 0x97, 0x98, 0x9e, 0xa3, 0xa4, 0x9b, 0x8a, + 0x7a, 0x78, 0x76, 0x78, 0x7d, 0x7d, 0x74, 0x70, 0x74, 0x7d, 0x8c, 0x8f, 0x84, 0x72, 0x66, 0x66, + 0x6b, 0x75, 0x7e, 0x7d, 0x7a, 0x7b, 0x7e, 0x85, 0x8e, 0x93, 0x8c, 0x7e, 0x75, 0x71, 0x74, 0x80, + 0x80, 0x76, 0x6c, 0x68, 0x69, 0x6b, 0x66, 0x57, 0x43, 0x3a, 0x3d, 0x43, 0x52, 0x5a, 0x5a, 0x57, + 0x57, 0x5e, 0x70, 0x84, 0x85, 0x72, 0x62, 0x68, 0x78, 0x8b, 0x9d, 0xa4, 0x9d, 0x92, 0x8f, 0x8f, + 0x93, 0x9e, 0xa1, 0x91, 0x81, 0x7b, 0x77, 0x7a, 0x89, 0x95, 0x99, 0x9c, 0xa1, 0xa6, 0xb0, 0xb0, + 0xa6, 0x96, 0x8d, 0x8a, 0x8a, 0x93, 0x9f, 0xa1, 0x98, 0x94, 0x94, 0x95, 0x94, 0x84, 0x69, 0x54, + 0x55, 0x58, 0x5a, 0x63, 0x67, 0x5c, 0x50, 0x57, 0x69, 0x80, 0x8f, 0x8b, 0x75, 0x64, 0x5e, 0x5d, + 0x69, 0x7a, 0x81, 0x80, 0x82, 0x8d, 0x9e, 0xad, 0xb0, 0xa6, 0x99, 0x92, 0x8d, 0x8f, 0x9b, 0xa3, + 0x9c, 0x8d, 0x85, 0x81, 0x7e, 0x82, 0x7e, 0x71, 0x60, 0x5b, 0x5e, 0x64, 0x67, 0x66, 0x66, 0x6a, + 0x72, 0x7b, 0x88, 0x8c, 0x88, 0x7b, 0x6c, 0x61, 0x67, 0x7b, 0x86, 0x87, 0x81, 0x7e, 0x84, 0x8d, + 0x96, 0x92, 0x82, 0x73, 0x76, 0x83, 0x8e, 0x98, 0x9f, 0xa1, 0xa0, 0x9d, 0x9e, 0xa8, 0xac, 0xa1, + 0x8c, 0x7d, 0x7c, 0x7d, 0x80, 0x80, 0x7b, 0x77, 0x72, 0x6f, 0x76, 0x82, 0x7b, 0x68, 0x57, 0x50, + 0x4d, 0x4d, 0x5f, 0x70, 0x78, 0x75, 0x72, 0x74, 0x85, 0x92, 0x8f, 0x88, 0x7e, 0x79, 0x78, 0x7e, + 0x86, 0x89, 0x87, 0x80, 0x7d, 0x7c, 0x80, 0x78, 0x6c, 0x62, 0x5e, 0x60, 0x60, 0x68, 0x72, 0x72, + 0x6a, 0x6c, 0x76, 0x86, 0x90, 0x88, 0x78, 0x6b, 0x67, 0x63, 0x6b, 0x78, 0x82, 0x81, 0x7b, 0x84, + 0x94, 0xa0, 0xa8, 0xa4, 0x96, 0x8b, 0x89, 0x8b, 0x8d, 0x88, 0x83, 0x7b, 0x6f, 0x6c, 0x67, 0x63, + 0x60, 0x59, 0x51, 0x4a, 0x47, 0x47, 0x47, 0x44, 0x42, 0x48, 0x55, 0x68, 0x7d, 0x93, 0xa1, 0x9f, + 0x95, 0x93, 0x94, 0x91, 0x8c, 0x83, 0x72, 0x6d, 0x71, 0x77, 0x86, 0x8f, 0x83, 0x6a, 0x61, 0x6b, + 0x76, 0x81, 0x83, 0x81, 0x80, 0x82, 0x85, 0x8d, 0x9d, 0xaa, 0xab, 0xa6, 0xa6, 0xac, 0xac, 0xa6, + 0xae, 0xb0, 0xac, 0xb1, 0xc4, 0xdb, 0xe3, 0xd3, 0xb9, 0xa2, 0x97, 0x92, 0x94, 0x9b, 0x98, 0x92, + 0x8c, 0x94, 0xa6, 0xb5, 0xb1, 0x9b, 0x83, 0x7b, 0x84, 0x92, 0xa3, 0xa9, 0xa4, 0x9e, 0x9c, 0x9d, + 0xa3, 0x9d, 0x89, 0x6e, 0x58, 0x55, 0x55, 0x51, 0x4b, 0x3f, 0x37, 0x3b, 0x4b, 0x5f, 0x6b, 0x6a, + 0x60, 0x48, 0x4c, 0x60, 0x6a, 0x6d, 0x70, 0x75, 0x7a, 0x86, 0x91, 0x95, 0xa2, 0xa4, 0x9a, 0x9a, + 0xa8, 0xa9, 0x9f, 0x98, 0x97, 0x98, 0x9a, 0x9e, 0x96, 0x89, 0x87, 0x84, 0x7d, 0x76, 0x6a, 0x5a, + 0x52, 0x51, 0x51, 0x53, 0x4f, 0x4b, 0x51, 0x63, 0x72, 0x77, 0x7b, 0x75, 0x6d, 0x6c, 0x5f, 0x60, + 0x65, 0x57, 0x4b, 0x45, 0x4f, 0x5e, 0x72, 0x79, 0x69, 0x63, 0x66, 0x6d, 0x7c, 0x87, 0x8a, 0x84, + 0x80, 0x8a, 0x97, 0xa3, 0xa3, 0x8f, 0x7a, 0x78, 0x7a, 0x85, 0x8a, 0x83, 0x81, 0x73, 0x68, 0x78, + 0x84, 0x83, 0x78, 0x63, 0x54, 0x55, 0x5e, 0x6b, 0x6a, 0x5d, 0x58, 0x58, 0x5b, 0x6f, 0x86, 0x80, + 0x6f, 0x73, 0x79, 0x87, 0x9d, 0xa8, 0xa7, 0xac, 0xa7, 0xa3, 0xaf, 0xbc, 0xb8, 0x9a, 0x8a, 0x85, + 0x8f, 0x95, 0x8b, 0x78, 0x6a, 0x5e, 0x59, 0x62, 0x6f, 0x76, 0x70, 0x68, 0x6a, 0x77, 0x7c, 0x68, + 0x4f, 0x51, 0x58, 0x5b, 0x69, 0x77, 0x7d, 0x83, 0x83, 0x72, 0x7c, 0x8c, 0x77, 0x6d, 0x77, 0x7c, + 0x81, 0x83, 0x81, 0x7d, 0x85, 0x90, 0x92, 0x89, 0x82, 0x81, 0x77, 0x80, 0x90, 0x9d, 0x97, 0x8a, + 0x93, 0xa5, 0xb2, 0xbf, 0xce, 0xc3, 0xab, 0x9a, 0x8f, 0x8c, 0x89, 0x80, 0x7c, 0x86, 0x8e, 0x99, + 0x93, 0x87, 0x81, 0x74, 0x77, 0x85, 0x86, 0x86, 0x87, 0x7d, 0x76, 0x7c, 0x85, 0x8e, 0x93, 0x8c, + 0x79, 0x6f, 0x77, 0x81, 0x91, 0x9f, 0x99, 0x86, 0x7e, 0x7d, 0x8b, 0xaf, 0xbb, 0xa8, 0x98, 0x8e, + 0x8d, 0x99, 0x9d, 0x98, 0x99, 0x99, 0x90, 0x8d, 0x8b, 0x93, 0x9b, 0x87, 0x76, 0x77, 0x90, 0x9a, + 0x85, 0x73, 0x70, 0x73, 0x82, 0x97, 0xa4, 0x88, 0x66, 0x52, 0x48, 0x56, 0x60, 0x52, 0x3b, 0x3a, + 0x45, 0x56, 0x69, 0x71, 0x77, 0x6f, 0x5e, 0x6c, 0x82, 0x78, 0x5a, 0x4f, 0x5b, 0x6f, 0x88, 0x95, + 0x8f, 0x91, 0xa5, 0xa7, 0x9d, 0x9f, 0x91, 0x78, 0x7d, 0x78, 0x77, 0x85, 0x74, 0x5e, 0x5e, 0x6b, + 0x6d, 0x65, 0x5c, 0x56, 0x51, 0x4f, 0x61, 0x77, 0x79, 0x6f, 0x67, 0x60, 0x64, 0x6f, 0x7b, 0x85, + 0x83, 0x73, 0x64, 0x54, 0x58, 0x5d, 0x62, 0x72, 0x6e, 0x6b, 0x73, 0x7c, 0x81, 0x7e, 0x8e, 0x9f, + 0xaa, 0xb9, 0xd0, 0xc8, 0xaf, 0xa4, 0x9e, 0xa3, 0xb2, 0xb9, 0xb2, 0x9e, 0x9a, 0x98, 0xa0, 0xa3, + 0x93, 0x78, 0x6b, 0x67, 0x62, 0x61, 0x6b, 0x71, 0x68, 0x6a, 0x66, 0x63, 0x67, 0x65, 0x5d, 0x59, + 0x5e, 0x65, 0x74, 0x7b, 0x7b, 0x86, 0x8c, 0x94, 0xa5, 0xa7, 0x94, 0x81, 0x81, 0x77, 0x75, 0x88, + 0x9f, 0x94, 0x83, 0x80, 0x87, 0x8d, 0x8d, 0x81, 0x76, 0x6b, 0x6d, 0x7b, 0x8c, 0x8e, 0x81, 0x86, + 0x8a, 0x77, 0x6e, 0x69, 0x53, 0x3c, 0x3f, 0x48, 0x5c, 0x75, 0x72, 0x69, 0x6a, 0x88, 0x9e, 0xa1, + 0x8d, 0x73, 0x60, 0x57, 0x56, 0x60, 0x5f, 0x5e, 0x59, 0x6e, 0x80, 0x84, 0x8b, 0x8b, 0x78, 0x6b, + 0x66, 0x71, 0x85, 0x84, 0x7b, 0x82, 0x8d, 0x93, 0x9e, 0xa1, 0x9e, 0x90, 0x85, 0x83, 0x71, 0x6b, + 0x6d, 0x69, 0x6e, 0x78, 0x72, 0x76, 0x87, 0x8c, 0x85, 0x88, 0x87, 0x87, 0x8f, 0x8f, 0x97, 0xa1, + 0xa2, 0xa0, 0xa7, 0xa4, 0x99, 0x90, 0x88, 0x88, 0x88, 0x9e, 0xae, 0xb0, 0xaf, 0xa8, 0xa1, 0x9c, + 0x97, 0x9a, 0x9c, 0x9a, 0x84, 0x7d, 0x95, 0x9d, 0x8e, 0x85, 0x89, 0x91, 0x9d, 0xa7, 0xad, 0xa6, + 0x98, 0x8e, 0x8b, 0x88, 0x85, 0x7d, 0x72, 0x6c, 0x7b, 0x92, 0xa0, 0x92, 0x70, 0x59, 0x50, 0x58, + 0x60, 0x59, 0x51, 0x43, 0x46, 0x5e, 0x72, 0x6c, 0x57, 0x5f, 0x73, 0x86, 0x96, 0x9a, 0x91, 0x89, + 0x84, 0x7a, 0x76, 0x81, 0x94, 0x90, 0x79, 0x7e, 0xa3, 0xbe, 0xb6, 0x9d, 0x89, 0x7e, 0x84, 0x87, + 0x79, 0x65, 0x4f, 0x4f, 0x56, 0x58, 0x5d, 0x6a, 0x72, 0x6f, 0x7d, 0x8e, 0x8c, 0x89, 0x81, 0x71, + 0x68, 0x5e, 0x5c, 0x71, 0x74, 0x6a, 0x6e, 0x7a, 0x85, 0x7a, 0x7a, 0x7a, 0x73, 0x77, 0x80, 0x7b, + 0x76, 0x7a, 0x86, 0x93, 0x95, 0x99, 0xb1, 0xb8, 0xad, 0x9d, 0x90, 0x8e, 0x96, 0x9a, 0x96, 0x92, + 0x93, 0x8b, 0x80, 0x83, 0x7b, 0x7c, 0x82, 0x85, 0x81, 0x84, 0x87, 0x95, 0x92, 0x81, 0x6d, 0x58, + 0x5d, 0x6a, 0x5d, 0x4a, 0x47, 0x50, 0x61, 0x6d, 0x74, 0x7c, 0x79, 0x83, 0x90, 0x96, 0x8d, 0x79, + 0x68, 0x5d, 0x57, 0x52, 0x63, 0x73, 0x60, 0x56, 0x5b, 0x5f, 0x60, 0x5c, 0x48, 0x30, 0x2b, 0x39, + 0x57, 0x56, 0x4a, 0x4d, 0x5a, 0x53, 0x4b, 0x4b, 0x47, 0x3f, 0x34, 0x3d, 0x54, 0x5e, 0x59, 0x54, + 0x50, 0x4d, 0x5e, 0x70, 0x73, 0x69, 0x57, 0x55, 0x64, 0x74, 0x7c, 0x72, 0x6a, 0x6b, 0x83, 0x95, + 0x9f, 0xad, 0xb0, 0xaa, 0xad, 0xbd, 0xca, 0xd4, 0xe3, 0xe5, 0xec, 0xec, 0xea, 0xf4, 0xee, 0xd5, + 0xbc, 0xac, 0xac, 0xb6, 0xb3, 0xb1, 0xae, 0xb6, 0xb9, 0xb5, 0xaf, 0xb5, 0xb4, 0x9f, 0x9f, 0xaa, + 0xb9, 0xbf, 0xaf, 0xa0, 0x98, 0x87, 0x85, 0x8f, 0x98, 0x94, 0x8a, 0x8c, 0xae, 0xbd, 0xc0, 0xb4, + 0xa0, 0xa1, 0x8c, 0x72, 0x81, 0x95, 0xa0, 0x88, 0x71, 0x77, 0x95, 0x92, 0x72, 0x75, 0x84, 0x8e, + 0x95, 0x88, 0x68, 0x4a, 0x4e, 0x51, 0x57, 0x6f, 0x82, 0x81, 0x76, 0x72, 0x76, 0x7b, 0x61, 0x3c, + 0x36, 0x41, 0x46, 0x50, 0x63, 0x66, 0x5b, 0x50, 0x59, 0x64, 0x5f, 0x53, 0x57, 0x62, 0x70, 0x73, + 0x72, 0x72, 0x6d, 0x6b, 0x71, 0x81, 0x95, 0xa7, 0xa9, 0x9d, 0x90, 0x92, 0x97, 0x9a, 0x96, 0x8d, + 0x86, 0x84, 0x82, 0x80, 0x7b, 0x73, 0x5e, 0x50, 0x50, 0x5d, 0x7e, 0x9a, 0x9e, 0x9a, 0x8f, 0x85, + 0x88, 0x8c, 0x7c, 0x64, 0x58, 0x60, 0x71, 0x80, 0x71, 0x5c, 0x54, 0x54, 0x50, 0x5c, 0x76, 0x80, + 0x82, 0x83, 0x82, 0x7e, 0x8b, 0x99, 0xa7, 0xaf, 0xaf, 0xac, 0xa8, 0xa0, 0x97, 0x89, 0x7d, 0x77, + 0x7c, 0x7e, 0x73, 0x67, 0x6c, 0x68, 0x5e, 0x5b, 0x5b, 0x52, 0x3c, 0x2f, 0x35, 0x4c, 0x57, 0x53, + 0x4d, 0x3e, 0x31, 0x30, 0x34, 0x34, 0x38, 0x3b, 0x4b, 0x63, 0x7a, 0x84, 0x7d, 0x7b, 0x97, 0xab, + 0xa4, 0x96, 0x84, 0x72, 0x6a, 0x71, 0x86, 0x9d, 0xa3, 0x98, 0x8f, 0x8c, 0x88, 0x93, 0x9d, 0x95, + 0x86, 0x83, 0x84, 0x84, 0x81, 0x78, 0x76, 0x74, 0x78, 0x7a, 0x78, 0x75, 0x69, 0x62, 0x64, 0x5e, + 0x6c, 0x82, 0x87, 0x82, 0x7a, 0x7a, 0x85, 0x8f, 0x9a, 0xa2, 0xa4, 0xa3, 0x9f, 0xa4, 0xb0, 0xbd, + 0xbd, 0xbb, 0xbb, 0xbc, 0xc1, 0xcb, 0xcb, 0xc4, 0xc1, 0xc1, 0xcc, 0xce, 0xc4, 0xaf, 0xa0, 0xa3, + 0xa9, 0xa9, 0x98, 0x84, 0x6f, 0x67, 0x6b, 0x77, 0x81, 0x80, 0x7c, 0x82, 0x83, 0x86, 0x8f, 0x88, + 0x7a, 0x77, 0x7d, 0x85, 0x8d, 0x8c, 0x85, 0x81, 0x87, 0x94, 0x9b, 0x94, 0x80, 0x69, 0x68, 0x74, + 0x82, 0x8e, 0x8f, 0x84, 0x79, 0x79, 0x83, 0x8f, 0x8c, 0x77, 0x63, 0x55, 0x4d, 0x52, 0x62, 0x6f, + 0x71, 0x70, 0x75, 0x76, 0x74, 0x6a, 0x5b, 0x50, 0x4e, 0x4c, 0x51, 0x5a, 0x5c, 0x5b, 0x62, 0x6b, + 0x74, 0x7d, 0x82, 0x73, 0x5c, 0x56, 0x5e, 0x6e, 0x7b, 0x85, 0x89, 0x8e, 0x96, 0x9d, 0xa7, 0xaa, + 0x9e, 0x8b, 0x7b, 0x70, 0x6d, 0x72, 0x7c, 0x87, 0x90, 0x90, 0x92, 0x96, 0x92, 0x83, 0x77, 0x7c, + 0x84, 0x8e, 0x90, 0x89, 0x80, 0x7d, 0x7a, 0x7d, 0x85, 0x80, 0x71, 0x69, 0x68, 0x73, 0x8a, 0x94, + 0x8c, 0x7e, 0x7e, 0x81, 0x82, 0x7a, 0x69, 0x53, 0x46, 0x4b, 0x57, 0x62, 0x61, 0x55, 0x4c, 0x50, + 0x5c, 0x6d, 0x73, 0x69, 0x58, 0x55, 0x61, 0x7d, 0x9b, 0xb0, 0xbb, 0xc4, 0xce, 0xd4, 0xd8, 0xce, + 0xb8, 0xa1, 0x98, 0x96, 0x98, 0x9b, 0x93, 0x84, 0x7c, 0x7a, 0x7e, 0x88, 0x84, 0x71, 0x5f, 0x59, + 0x5c, 0x66, 0x73, 0x75, 0x69, 0x5f, 0x5a, 0x5c, 0x68, 0x70, 0x70, 0x71, 0x79, 0x7e, 0x84, 0x88, + 0x89, 0x8f, 0x97, 0x96, 0x91, 0x88, 0x7d, 0x71, 0x6e, 0x72, 0x7c, 0x8b, 0x91, 0x90, 0x8a, 0x8c, + 0x89, 0x86, 0x88, 0x81, 0x73, 0x68, 0x5e, 0x5e, 0x67, 0x6d, 0x6d, 0x69, 0x62, 0x57, 0x55, 0x5b, + 0x5a, 0x4f, 0x4d, 0x54, 0x60, 0x6c, 0x6d, 0x66, 0x65, 0x6e, 0x7c, 0x93, 0xa2, 0x9a, 0x84, 0x72, + 0x6a, 0x73, 0x81, 0x84, 0x7e, 0x7a, 0x82, 0x93, 0xa5, 0xaf, 0xaa, 0x98, 0x90, 0x93, 0xa2, 0xaa, + 0xa3, 0x97, 0x95, 0x95, 0x96, 0x95, 0x87, 0x6c, 0x54, 0x4d, 0x56, 0x69, 0x73, 0x6c, 0x62, 0x68, + 0x77, 0x86, 0x96, 0x9f, 0x98, 0x8f, 0x86, 0x82, 0x8c, 0x93, 0x8e, 0x87, 0x8c, 0x93, 0x98, 0x97, + 0x8a, 0x77, 0x6c, 0x6c, 0x76, 0x87, 0x90, 0x90, 0x94, 0x9a, 0x9d, 0xa4, 0xa6, 0x98, 0x82, 0x78, + 0x77, 0x7b, 0x87, 0x8e, 0x8e, 0x8b, 0x8c, 0x8f, 0x92, 0x90, 0x8b, 0x88, 0x8e, 0x95, 0x9e, 0xa2, + 0xa1, 0x9c, 0x9b, 0xa1, 0xa7, 0xac, 0xaa, 0x9b, 0x84, 0x73, 0x70, 0x75, 0x7a, 0x80, 0x84, 0x83, + 0x7c, 0x79, 0x80, 0x7e, 0x74, 0x6a, 0x65, 0x61, 0x63, 0x6b, 0x70, 0x6f, 0x73, 0x78, 0x7a, 0x7b, + 0x79, 0x6d, 0x62, 0x60, 0x6c, 0x87, 0x9a, 0x98, 0x87, 0x7a, 0x74, 0x7b, 0x8b, 0x91, 0x89, 0x7a, + 0x75, 0x7c, 0x8f, 0x9f, 0xa9, 0xa9, 0xa3, 0x99, 0x95, 0x93, 0x85, 0x6c, 0x5d, 0x5c, 0x67, 0x72, + 0x6e, 0x61, 0x57, 0x58, 0x63, 0x74, 0x7c, 0x75, 0x64, 0x5f, 0x6a, 0x83, 0x9c, 0xa8, 0xa5, 0xa0, + 0x9c, 0x99, 0x9d, 0x9f, 0x92, 0x7b, 0x6f, 0x6f, 0x78, 0x81, 0x80, 0x7d, 0x88, 0x8e, 0x8a, 0x85, + 0x7b, 0x6f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x57, 0x47, 0x42, 0x44, 0x45, 0x45, 0x44, 0x40, 0x39, + 0x35, 0x3c, 0x4b, 0x51, 0x4d, 0x4e, 0x5a, 0x66, 0x6e, 0x71, 0x6d, 0x66, 0x60, 0x5e, 0x61, 0x6f, + 0x7d, 0x85, 0x86, 0x86, 0x81, 0x81, 0x7d, 0x72, 0x63, 0x5d, 0x59, 0x5b, 0x69, 0x73, 0x71, 0x6b, + 0x6f, 0x74, 0x73, 0x6f, 0x69, 0x5e, 0x5b, 0x5b, 0x63, 0x75, 0x80, 0x82, 0x81, 0x82, 0x88, 0x96, + 0x9e, 0x95, 0x81, 0x73, 0x6b, 0x74, 0x8a, 0x9c, 0xa6, 0xb0, 0xb9, 0xc8, 0xd6, 0xdc, 0xd9, 0xd0, + 0xc7, 0xc5, 0xce, 0xd5, 0xd4, 0xc9, 0xbf, 0xbb, 0xbd, 0xbe, 0xb7, 0xa2, 0x8f, 0x88, 0x89, 0x93, + 0x99, 0x93, 0x8c, 0x8a, 0x8e, 0x9b, 0xa9, 0xa5, 0x93, 0x8a, 0x89, 0x8d, 0x9a, 0xa8, 0xa9, 0xa3, + 0xa0, 0xa0, 0xa4, 0xa5, 0x9b, 0x8e, 0x8c, 0x93, 0x9a, 0x9d, 0x96, 0x91, 0x91, 0x91, 0x90, 0x8c, + 0x84, 0x76, 0x62, 0x56, 0x51, 0x52, 0x54, 0x53, 0x50, 0x48, 0x42, 0x43, 0x4d, 0x54, 0x4a, 0x3d, + 0x39, 0x3d, 0x46, 0x52, 0x61, 0x6d, 0x7a, 0x80, 0x7d, 0x81, 0x8a, 0x8c, 0x88, 0x8a, 0x8f, 0x97, + 0x99, 0x91, 0x8a, 0x86, 0x82, 0x82, 0x8a, 0x8b, 0x84, 0x7c, 0x7b, 0x7d, 0x82, 0x85, 0x81, 0x76, + 0x71, 0x6d, 0x72, 0x80, 0x84, 0x79, 0x6d, 0x67, 0x68, 0x73, 0x75, 0x6e, 0x67, 0x63, 0x61, 0x5e, + 0x60, 0x5f, 0x51, 0x45, 0x43, 0x4e, 0x61, 0x6a, 0x72, 0x75, 0x77, 0x79, 0x86, 0x90, 0x8c, 0x85, + 0x81, 0x86, 0x94, 0xa2, 0xa8, 0xa2, 0x9d, 0x9e, 0xa4, 0xb4, 0xbe, 0xb5, 0xa1, 0x94, 0x91, 0x9f, + 0xa7, 0x98, 0x8a, 0x86, 0x80, 0x79, 0x7e, 0x81, 0x75, 0x65, 0x5b, 0x5b, 0x64, 0x67, 0x68, 0x69, + 0x77, 0x88, 0x91, 0x93, 0x90, 0x83, 0x71, 0x68, 0x62, 0x5f, 0x57, 0x4e, 0x4c, 0x51, 0x55, 0x53, + 0x4f, 0x4b, 0x42, 0x37, 0x38, 0x46, 0x59, 0x68, 0x72, 0x7b, 0x85, 0x86, 0x82, 0x86, 0x8f, 0x98, + 0x97, 0x91, 0x8e, 0x8d, 0x8c, 0x8d, 0x93, 0x9c, 0x9e, 0x9b, 0x92, 0x8a, 0x83, 0x7c, 0x7b, 0x7b, + 0x7d, 0x7e, 0x7c, 0x80, 0x86, 0x8a, 0x8a, 0x8a, 0x8a, 0x88, 0x7a, 0x6f, 0x75, 0x89, 0x99, 0xa5, + 0xaf, 0xb1, 0xaa, 0x9f, 0x98, 0x99, 0x97, 0x8d, 0x81, 0x7d, 0x83, 0x8a, 0x8a, 0x89, 0x8e, 0x96, + 0x9d, 0xac, 0xbb, 0xba, 0xad, 0xa1, 0xa0, 0xa6, 0xa3, 0x94, 0x84, 0x7a, 0x77, 0x80, 0x89, 0x81, + 0x70, 0x67, 0x63, 0x67, 0x6c, 0x66, 0x5b, 0x57, 0x5d, 0x64, 0x6b, 0x68, 0x5f, 0x58, 0x54, 0x55, + 0x5c, 0x5b, 0x53, 0x55, 0x64, 0x76, 0x8b, 0x93, 0x96, 0xa1, 0xac, 0xb4, 0xba, 0xb3, 0xa2, 0x9b, + 0x9f, 0xa0, 0xa3, 0xa0, 0x8e, 0x7c, 0x72, 0x71, 0x74, 0x6c, 0x5b, 0x4d, 0x46, 0x49, 0x50, 0x52, + 0x4e, 0x53, 0x62, 0x74, 0x84, 0x84, 0x78, 0x75, 0x80, 0x85, 0x88, 0x87, 0x80, 0x78, 0x74, 0x74, + 0x77, 0x79, 0x73, 0x6c, 0x6c, 0x69, 0x71, 0x83, 0x8a, 0x8a, 0x92, 0x9c, 0xa2, 0x9d, 0x91, 0x8a, + 0x94, 0xa2, 0xab, 0xb6, 0xb3, 0xa0, 0x93, 0x91, 0x95, 0x9d, 0x9d, 0x92, 0x88, 0x81, 0x7d, 0x7e, + 0x79, 0x73, 0x71, 0x6e, 0x6a, 0x71, 0x79, 0x78, 0x75, 0x75, 0x79, 0x86, 0x8d, 0x89, 0x84, 0x84, + 0x86, 0x91, 0x94, 0x89, 0x82, 0x7d, 0x78, 0x87, 0x99, 0xa1, 0xa1, 0x9f, 0x98, 0x97, 0x96, 0x8f, + 0x88, 0x87, 0x8c, 0x9a, 0xa3, 0xa0, 0x97, 0x95, 0x9b, 0xa2, 0xa4, 0x94, 0x7e, 0x73, 0x6c, 0x6c, + 0x70, 0x6a, 0x60, 0x60, 0x67, 0x78, 0x8a, 0x8b, 0x83, 0x7e, 0x79, 0x7a, 0x7d, 0x7a, 0x6e, 0x60, + 0x55, 0x56, 0x5b, 0x51, 0x3f, 0x35, 0x36, 0x40, 0x4f, 0x59, 0x5e, 0x68, 0x74, 0x7d, 0x85, 0x85, + 0x7e, 0x7b, 0x7d, 0x85, 0x8f, 0x90, 0x87, 0x80, 0x79, 0x70, 0x6b, 0x62, 0x55, 0x4e, 0x50, 0x55, + 0x5d, 0x5f, 0x57, 0x4e, 0x53, 0x5e, 0x6b, 0x70, 0x67, 0x5a, 0x5d, 0x63, 0x69, 0x6c, 0x63, 0x57, + 0x51, 0x50, 0x5e, 0x72, 0x83, 0x8b, 0x8b, 0x88, 0x8b, 0x93, 0x96, 0x91, 0x87, 0x7e, 0x83, 0x8c, + 0x89, 0x7c, 0x7b, 0x85, 0x96, 0xa5, 0xa6, 0xa2, 0xa8, 0xaa, 0xab, 0xab, 0xa3, 0x99, 0x97, 0x9d, + 0xa6, 0xb2, 0xb7, 0xb4, 0xb0, 0xac, 0xa8, 0xa5, 0x9b, 0x82, 0x71, 0x6c, 0x76, 0x8c, 0x93, 0x83, + 0x72, 0x76, 0x82, 0x8c, 0x8b, 0x7a, 0x6c, 0x6c, 0x7a, 0x92, 0xa5, 0xa3, 0x9a, 0x94, 0x92, 0xa0, + 0xb3, 0xb7, 0xaf, 0xac, 0xb0, 0xb5, 0xb0, 0xa2, 0x9b, 0x9a, 0x91, 0x8d, 0x8c, 0x7e, 0x70, 0x6e, + 0x71, 0x76, 0x75, 0x68, 0x5c, 0x60, 0x68, 0x71, 0x79, 0x71, 0x63, 0x65, 0x70, 0x80, 0x8b, 0x86, + 0x76, 0x71, 0x70, 0x70, 0x6f, 0x61, 0x4f, 0x4b, 0x53, 0x69, 0x85, 0x91, 0x89, 0x7c, 0x7b, 0x83, + 0x8d, 0x8e, 0x81, 0x77, 0x7c, 0x8b, 0x9d, 0xa6, 0x9e, 0x94, 0x8f, 0x8c, 0x89, 0x84, 0x7e, 0x83, + 0x8d, 0x94, 0x97, 0x97, 0x8c, 0x7c, 0x75, 0x73, 0x7b, 0x7e, 0x70, 0x60, 0x63, 0x70, 0x7a, 0x75, + 0x66, 0x5d, 0x65, 0x72, 0x7e, 0x84, 0x79, 0x69, 0x6b, 0x7a, 0x93, 0xa4, 0xa6, 0xa2, 0xa1, 0xa2, + 0xa7, 0xa3, 0x90, 0x78, 0x72, 0x7b, 0x8b, 0x9c, 0xa1, 0x96, 0x8c, 0x8a, 0x8e, 0x8f, 0x88, 0x76, + 0x6c, 0x6b, 0x6e, 0x73, 0x73, 0x6e, 0x6d, 0x70, 0x77, 0x7a, 0x75, 0x6e, 0x70, 0x79, 0x84, 0x82, + 0x6a, 0x4d, 0x3d, 0x3a, 0x3c, 0x40, 0x3f, 0x32, 0x28, 0x2f, 0x43, 0x52, 0x51, 0x4a, 0x44, 0x45, + 0x4f, 0x63, 0x6b, 0x61, 0x61, 0x72, 0x86, 0x8e, 0x84, 0x74, 0x6e, 0x6d, 0x6d, 0x75, 0x79, 0x72, + 0x6c, 0x6c, 0x6f, 0x77, 0x84, 0x83, 0x6f, 0x66, 0x6f, 0x7b, 0x76, 0x65, 0x5c, 0x62, 0x72, 0x82, + 0x85, 0x7b, 0x73, 0x77, 0x80, 0x8c, 0x93, 0x8b, 0x82, 0x8c, 0xa1, 0xba, 0xc0, 0xb1, 0xa0, 0x9a, + 0x9b, 0xa5, 0xb1, 0xb4, 0xaf, 0xaf, 0xb5, 0xc1, 0xc3, 0xb8, 0xac, 0xab, 0xb2, 0xbd, 0xc5, 0xbd, + 0xab, 0xa1, 0xa0, 0xa6, 0xb0, 0xaa, 0x96, 0x8c, 0x87, 0x8c, 0x95, 0x8c, 0x76, 0x71, 0x79, 0x84, + 0x87, 0x80, 0x78, 0x73, 0x6f, 0x72, 0x79, 0x77, 0x6d, 0x6a, 0x6f, 0x74, 0x7e, 0x86, 0x81, 0x78, + 0x7c, 0x8d, 0xa4, 0xa8, 0x97, 0x92, 0x9f, 0xa9, 0xaf, 0xa9, 0x91, 0x7b, 0x71, 0x6e, 0x6c, 0x68, + 0x66, 0x69, 0x69, 0x68, 0x70, 0x73, 0x65, 0x57, 0x55, 0x5d, 0x69, 0x6b, 0x65, 0x60, 0x65, 0x70, + 0x80, 0x84, 0x73, 0x5a, 0x4f, 0x4d, 0x51, 0x58, 0x52, 0x4b, 0x54, 0x5e, 0x69, 0x72, 0x7b, 0x84, + 0x86, 0x85, 0x8a, 0x8d, 0x86, 0x7e, 0x84, 0x8a, 0x8e, 0x89, 0x7c, 0x73, 0x71, 0x77, 0x86, 0x94, + 0x96, 0x8e, 0x8a, 0x89, 0x8f, 0x9a, 0x96, 0x85, 0x75, 0x75, 0x82, 0x85, 0x78, 0x70, 0x79, 0x89, + 0x95, 0x99, 0x96, 0x8b, 0x7e, 0x7a, 0x81, 0x86, 0x82, 0x80, 0x8a, 0x97, 0xa4, 0xb4, 0xc0, 0xbf, + 0xb7, 0xae, 0xa6, 0xa8, 0xa8, 0x9f, 0x97, 0x9a, 0x9d, 0x9b, 0x92, 0x87, 0x89, 0x92, 0x97, 0x98, + 0x8c, 0x73, 0x62, 0x5d, 0x5e, 0x5e, 0x58, 0x50, 0x4b, 0x4b, 0x4a, 0x52, 0x5d, 0x63, 0x67, 0x6d, + 0x6e, 0x6a, 0x65, 0x5b, 0x4b, 0x44, 0x43, 0x46, 0x45, 0x3d, 0x3d, 0x48, 0x4e, 0x51, 0x55, 0x54, + 0x4c, 0x4c, 0x52, 0x5a, 0x5b, 0x56, 0x5a, 0x68, 0x74, 0x77, 0x76, 0x73, 0x6f, 0x6f, 0x6e, 0x6c, + 0x69, 0x63, 0x54, 0x4a, 0x4a, 0x53, 0x5e, 0x66, 0x6a, 0x78, 0x8a, 0x99, 0xa0, 0x9d, 0x96, 0x97, + 0x9d, 0xa4, 0xa3, 0x9a, 0x92, 0x98, 0xa0, 0xa8, 0xb4, 0xba, 0xb9, 0xbb, 0xb9, 0xb6, 0xb7, 0xb6, + 0xb0, 0xaf, 0xb3, 0xba, 0xbd, 0xb7, 0xaf, 0xb2, 0xbd, 0xbd, 0xb3, 0xa5, 0x9b, 0x9a, 0x9f, 0xa4, + 0xa9, 0xa0, 0x8f, 0x89, 0x93, 0xa0, 0xa9, 0xaa, 0xa4, 0x9e, 0x9c, 0x98, 0x8f, 0x82, 0x74, 0x6d, + 0x6e, 0x73, 0x77, 0x6c, 0x58, 0x55, 0x66, 0x74, 0x7b, 0x77, 0x6d, 0x6c, 0x75, 0x79, 0x7a, 0x78, + 0x71, 0x64, 0x61, 0x6e, 0x82, 0x89, 0x7e, 0x73, 0x74, 0x70, 0x63, 0x52, 0x3f, 0x35, 0x3c, 0x4b, + 0x5c, 0x63, 0x57, 0x4c, 0x54, 0x62, 0x6f, 0x71, 0x6b, 0x60, 0x54, 0x50, 0x52, 0x53, 0x51, 0x55, + 0x64, 0x74, 0x84, 0x8d, 0x8e, 0x87, 0x86, 0x86, 0x82, 0x7a, 0x6a, 0x5e, 0x61, 0x6d, 0x83, 0x98, + 0x9f, 0x9f, 0xa6, 0xb3, 0xc0, 0xc4, 0xbc, 0xb5, 0xba, 0xc2, 0xc1, 0xb6, 0xa4, 0x92, 0x8d, 0x94, + 0x9f, 0xaa, 0xaa, 0xa2, 0x9c, 0x9b, 0x99, 0x99, 0x98, 0x90, 0x83, 0x76, 0x74, 0x7d, 0x7d, 0x76, + 0x79, 0x8d, 0xa0, 0xa7, 0xa1, 0x96, 0x8f, 0x90, 0x8e, 0x87, 0x77, 0x65, 0x5e, 0x61, 0x6d, 0x82, + 0x9a, 0xa7, 0xa8, 0xa8, 0xa4, 0xa1, 0x99, 0x88, 0x75, 0x6f, 0x6c, 0x6f, 0x6c, 0x60, 0x55, 0x5c, + 0x6d, 0x83, 0x8a, 0x7c, 0x6d, 0x6b, 0x6b, 0x70, 0x75, 0x71, 0x69, 0x66, 0x63, 0x67, 0x71, 0x79, + 0x7e, 0x88, 0x8e, 0x8e, 0x88, 0x7b, 0x6d, 0x65, 0x5d, 0x59, 0x57, 0x49, 0x39, 0x38, 0x41, 0x51, + 0x61, 0x62, 0x5b, 0x58, 0x59, 0x5e, 0x5e, 0x51, 0x42, 0x3f, 0x44, 0x49, 0x49, 0x4d, 0x55, 0x60, + 0x71, 0x85, 0x90, 0x8f, 0x85, 0x7e, 0x79, 0x7b, 0x8c, 0x99, 0x98, 0x94, 0x93, 0x96, 0xa0, 0xa1, + 0x9a, 0x98, 0x9a, 0x9c, 0x9c, 0x93, 0x85, 0x78, 0x75, 0x79, 0x80, 0x7c, 0x75, 0x77, 0x85, 0x92, + 0x9c, 0x9d, 0x95, 0x87, 0x7e, 0x7a, 0x7e, 0x83, 0x7b, 0x75, 0x80, 0x8e, 0x97, 0x96, 0x8c, 0x82, + 0x87, 0x97, 0xac, 0xb7, 0xac, 0x9e, 0x97, 0x8f, 0x8e, 0x91, 0x93, 0x8c, 0x80, 0x72, 0x6d, 0x66, + 0x5c, 0x5a, 0x64, 0x69, 0x67, 0x61, 0x58, 0x51, 0x51, 0x5a, 0x6b, 0x75, 0x6d, 0x66, 0x6a, 0x74, + 0x84, 0x91, 0x8f, 0x85, 0x7d, 0x78, 0x7b, 0x82, 0x82, 0x85, 0x99, 0xb0, 0xbf, 0xbd, 0xac, 0x99, + 0x8e, 0x8d, 0x92, 0x96, 0x8f, 0x85, 0x83, 0x82, 0x86, 0x93, 0x99, 0x91, 0x83, 0x75, 0x6c, 0x68, + 0x63, 0x5f, 0x64, 0x6f, 0x7a, 0x80, 0x7e, 0x7a, 0x73, 0x74, 0x7b, 0x85, 0x85, 0x77, 0x70, 0x78, + 0x83, 0x94, 0x9f, 0xa4, 0xad, 0xb8, 0xc0, 0xc6, 0xc3, 0xb2, 0xac, 0xb8, 0xc1, 0xc3, 0xb7, 0xa3, + 0x8c, 0x82, 0x85, 0x91, 0x96, 0x92, 0x90, 0x92, 0x98, 0xa3, 0xac, 0xad, 0xa2, 0x96, 0x8e, 0x85, + 0x7e, 0x73, 0x67, 0x6c, 0x79, 0x87, 0x8d, 0x87, 0x75, 0x6c, 0x6c, 0x79, 0x88, 0x88, 0x7b, 0x76, + 0x78, 0x7c, 0x80, 0x7b, 0x78, 0x7b, 0x80, 0x83, 0x7e, 0x6e, 0x5b, 0x58, 0x5f, 0x62, 0x5e, 0x4e, + 0x3a, 0x34, 0x40, 0x58, 0x71, 0x79, 0x74, 0x76, 0x7e, 0x84, 0x8a, 0x8c, 0x85, 0x7a, 0x6e, 0x65, + 0x64, 0x5d, 0x54, 0x5e, 0x74, 0x84, 0x8b, 0x83, 0x70, 0x5c, 0x51, 0x4f, 0x51, 0x4d, 0x40, 0x3a, + 0x44, 0x52, 0x5c, 0x5c, 0x59, 0x59, 0x5f, 0x63, 0x65, 0x66, 0x5f, 0x5b, 0x66, 0x71, 0x75, 0x71, + 0x67, 0x64, 0x69, 0x6d, 0x74, 0x78, 0x73, 0x6b, 0x6a, 0x69, 0x6c, 0x6a, 0x60, 0x54, 0x4f, 0x53, + 0x5e, 0x68, 0x68, 0x65, 0x6f, 0x7b, 0x87, 0x8c, 0x88, 0x7d, 0x75, 0x6e, 0x72, 0x7d, 0x82, 0x84, + 0x93, 0xa0, 0xa3, 0xa0, 0x99, 0x96, 0x9b, 0x9d, 0xa1, 0xa4, 0x9e, 0x92, 0x93, 0xa1, 0xb3, 0xc1, + 0xc1, 0xb7, 0xad, 0xa9, 0xad, 0xb4, 0xb8, 0xb6, 0xb7, 0xbd, 0xc4, 0xc7, 0xb9, 0xa4, 0x98, 0x95, + 0x93, 0x94, 0x8f, 0x83, 0x7a, 0x7c, 0x85, 0x8e, 0x89, 0x78, 0x6a, 0x66, 0x6c, 0x7e, 0x8f, 0x95, + 0x97, 0x9f, 0xa0, 0x9b, 0x92, 0x8b, 0x87, 0x8a, 0x8e, 0x98, 0x9c, 0x94, 0x8f, 0x9f, 0xb3, 0xbb, + 0xb4, 0xa4, 0x93, 0x8a, 0x82, 0x83, 0x80, 0x70, 0x66, 0x6b, 0x76, 0x80, 0x81, 0x78, 0x6c, 0x64, + 0x60, 0x62, 0x62, 0x5b, 0x53, 0x57, 0x61, 0x6e, 0x75, 0x6e, 0x63, 0x62, 0x69, 0x74, 0x7e, 0x80, + 0x7b, 0x80, 0x86, 0x87, 0x80, 0x6e, 0x65, 0x6a, 0x6f, 0x78, 0x82, 0x81, 0x77, 0x77, 0x7b, 0x80, + 0x7e, 0x72, 0x64, 0x62, 0x65, 0x6b, 0x79, 0x81, 0x7d, 0x82, 0x90, 0xa1, 0xaa, 0xa4, 0x96, 0x8e, + 0x8c, 0x90, 0x94, 0x8f, 0x83, 0x7d, 0x83, 0x8c, 0x93, 0x8f, 0x85, 0x80, 0x7c, 0x77, 0x79, 0x7a, + 0x74, 0x76, 0x85, 0x90, 0x99, 0x95, 0x8a, 0x83, 0x84, 0x88, 0x92, 0x91, 0x85, 0x7c, 0x80, 0x86, + 0x89, 0x7a, 0x63, 0x57, 0x57, 0x59, 0x61, 0x68, 0x68, 0x68, 0x6f, 0x78, 0x81, 0x7c, 0x6b, 0x56, + 0x4d, 0x4a, 0x50, 0x57, 0x53, 0x4a, 0x4d, 0x59, 0x69, 0x6f, 0x69, 0x60, 0x5c, 0x5d, 0x65, 0x6a, + 0x61, 0x54, 0x56, 0x61, 0x6b, 0x67, 0x5b, 0x54, 0x57, 0x5b, 0x60, 0x69, 0x6a, 0x64, 0x6a, 0x78, + 0x88, 0x91, 0x8d, 0x82, 0x7e, 0x81, 0x87, 0x93, 0x97, 0x94, 0x94, 0x9c, 0xa9, 0xaf, 0xa1, 0x88, + 0x7a, 0x79, 0x83, 0x91, 0x98, 0x9c, 0xa9, 0xb8, 0xc3, 0xc6, 0xb8, 0xa3, 0x98, 0x94, 0x97, 0x9f, + 0xa0, 0x9a, 0x98, 0x9f, 0xaa, 0xb5, 0xb2, 0xa3, 0x98, 0x92, 0x91, 0x9c, 0xa0, 0x92, 0x89, 0x90, + 0x9b, 0xa5, 0x9e, 0x8d, 0x84, 0x85, 0x87, 0x88, 0x8a, 0x84, 0x7e, 0x84, 0x8a, 0x91, 0x91, 0x85, + 0x74, 0x6d, 0x6b, 0x73, 0x7a, 0x77, 0x72, 0x74, 0x7a, 0x8d, 0x93, 0x88, 0x72, 0x66, 0x64, 0x6c, + 0x74, 0x6f, 0x69, 0x6f, 0x78, 0x7e, 0x7a, 0x67, 0x54, 0x4c, 0x46, 0x47, 0x4d, 0x49, 0x3e, 0x3c, + 0x44, 0x53, 0x5f, 0x5d, 0x50, 0x49, 0x46, 0x4d, 0x5d, 0x65, 0x61, 0x67, 0x74, 0x83, 0x8f, 0x8c, + 0x7e, 0x7a, 0x7d, 0x82, 0x8a, 0x8a, 0x82, 0x81, 0x86, 0x8d, 0x91, 0x86, 0x75, 0x69, 0x63, 0x69, + 0x78, 0x82, 0x86, 0x8a, 0x90, 0x9a, 0xa1, 0x9d, 0x91, 0x86, 0x89, 0x8e, 0x96, 0x9a, 0x92, 0x8d, + 0x97, 0xa5, 0xb2, 0xb3, 0xa6, 0x9a, 0x98, 0x98, 0x9c, 0xa1, 0x9f, 0x9e, 0xa6, 0xab, 0xb4, 0xb4, + 0xa3, 0x94, 0x92, 0x91, 0x94, 0x98, 0x92, 0x88, 0x88, 0x8e, 0x98, 0x97, 0x86, 0x71, 0x69, 0x6c, + 0x78, 0x83, 0x83, 0x81, 0x88, 0x8e, 0x96, 0x98, 0x90, 0x88, 0x83, 0x80, 0x86, 0x8f, 0x8e, 0x85, + 0x85, 0x8b, 0x93, 0x96, 0x8c, 0x79, 0x6d, 0x69, 0x6f, 0x7a, 0x7e, 0x7d, 0x86, 0x90, 0x9a, 0xa2, + 0x96, 0x80, 0x78, 0x7a, 0x7d, 0x80, 0x7b, 0x6f, 0x6c, 0x70, 0x77, 0x84, 0x83, 0x71, 0x63, 0x5c, + 0x5e, 0x6a, 0x70, 0x6e, 0x70, 0x74, 0x76, 0x78, 0x70, 0x5e, 0x4e, 0x47, 0x48, 0x4f, 0x52, 0x4a, + 0x47, 0x51, 0x62, 0x74, 0x76, 0x6c, 0x62, 0x5e, 0x5d, 0x65, 0x70, 0x70, 0x72, 0x7d, 0x81, 0x7d, + 0x74, 0x68, 0x5f, 0x5f, 0x65, 0x6f, 0x77, 0x73, 0x6e, 0x76, 0x86, 0x97, 0xa0, 0x98, 0x8a, 0x83, + 0x80, 0x85, 0x85, 0x7b, 0x73, 0x78, 0x7d, 0x83, 0x86, 0x7d, 0x72, 0x6e, 0x6f, 0x71, 0x72, 0x6d, + 0x6a, 0x6d, 0x71, 0x7a, 0x83, 0x7a, 0x6a, 0x59, 0x4b, 0x4a, 0x50, 0x54, 0x57, 0x69, 0x81, 0x90, + 0x96, 0x91, 0x87, 0x89, 0x92, 0x9a, 0xa4, 0xa4, 0x95, 0x8d, 0x8c, 0x89, 0x88, 0x82, 0x75, 0x6d, + 0x67, 0x6a, 0x79, 0x84, 0x82, 0x80, 0x83, 0x8a, 0x91, 0x8d, 0x82, 0x78, 0x74, 0x76, 0x7b, 0x7d, + 0x76, 0x79, 0x87, 0x97, 0xaa, 0xb3, 0xad, 0xa8, 0xa3, 0xa0, 0xa2, 0xa2, 0x9e, 0xa2, 0xad, 0xb2, + 0xb4, 0xae, 0x9d, 0x89, 0x81, 0x77, 0x83, 0x91, 0x8f, 0x8c, 0x90, 0x94, 0x98, 0x96, 0x8e, 0x7b, + 0x6d, 0x6c, 0x75, 0x80, 0x79, 0x6c, 0x77, 0x86, 0x8e, 0x8f, 0x84, 0x7b, 0x7c, 0x78, 0x7d, 0x8a, + 0x8b, 0x8e, 0x96, 0x9e, 0xa9, 0xb0, 0xa7, 0x90, 0x8a, 0x8a, 0x8c, 0x97, 0x90, 0x84, 0x93, 0x9e, + 0xa5, 0xac, 0xa8, 0x9e, 0x99, 0x9c, 0xa5, 0xa7, 0x9c, 0x88, 0x85, 0x8e, 0x99, 0x98, 0x8a, 0x74, + 0x68, 0x61, 0x65, 0x6c, 0x6e, 0x72, 0x79, 0x86, 0x97, 0xa9, 0xad, 0x9d, 0x92, 0x91, 0x8f, 0x93, + 0x8d, 0x80, 0x7e, 0x83, 0x8f, 0x8f, 0x7c, 0x6b, 0x60, 0x5f, 0x5f, 0x5f, 0x55, 0x49, 0x4d, 0x55, + 0x59, 0x5d, 0x53, 0x46, 0x3e, 0x3d, 0x49, 0x52, 0x4f, 0x42, 0x3c, 0x4a, 0x51, 0x57, 0x5f, 0x59, + 0x54, 0x57, 0x5e, 0x6c, 0x6b, 0x5d, 0x59, 0x66, 0x75, 0x73, 0x64, 0x5b, 0x58, 0x56, 0x4c, 0x3c, + 0x37, 0x39, 0x39, 0x44, 0x4c, 0x4d, 0x4c, 0x41, 0x31, 0x1d, 0xe, 0x14, 0x1f, 0x24, 0x31, 0x4a, + 0x5e, 0x6a, 0x77, 0x82, 0x7e, 0x7b, 0x88, 0x95, 0xa0, 0xae, 0xaa, 0xaa, 0xb9, 0xca, 0xd5, 0xc8, + 0xb0, 0xac, 0xa8, 0xb0, 0xc3, 0xbe, 0xaa, 0x9f, 0xa3, 0xba, 0xd2, 0xda, 0xcf, 0xbb, 0xb1, 0xb5, + 0xbc, 0xaf, 0x8d, 0x81, 0x95, 0xae, 0xc6, 0xc1, 0xa4, 0xa3, 0xa7, 0xa7, 0xb3, 0xa9, 0x9a, 0x9e, + 0xaa, 0xbd, 0xcb, 0xca, 0xb3, 0xaf, 0xbb, 0xb9, 0xac, 0x96, 0x81, 0x81, 0x9b, 0xb3, 0xb7, 0xa0, + 0x7d, 0x6b, 0x69, 0x6c, 0x69, 0x58, 0x46, 0x45, 0x55, 0x65, 0x59, 0x45, 0x3d, 0x46, 0x53, 0x51, + 0x44, 0x3f, 0x3e, 0x42, 0x4f, 0x50, 0x4d, 0x4c, 0x44, 0x45, 0x4e, 0x44, 0x41, 0x50, 0x55, 0x6c, + 0x89, 0x86, 0x86, 0x90, 0x99, 0xb2, 0xbf, 0xb8, 0xb2, 0xb1, 0xab, 0xa5, 0xad, 0xbb, 0xc9, 0xd1, + 0xd3, 0xd4, 0xc9, 0xb5, 0xa6, 0x9d, 0x9f, 0x91, 0x80, 0x81, 0x84, 0x89, 0x92, 0x88, 0x7a, 0x7a, + 0x7e, 0x87, 0x80, 0x66, 0x59, 0x60, 0x7c, 0x8d, 0x7e, 0x6c, 0x66, 0x67, 0x6d, 0x80, 0x8a, 0x7e, + 0x7a, 0x7b, 0x88, 0x8c, 0x7e, 0x73, 0x74, 0x78, 0x73, 0x77, 0x68, 0x57, 0x62, 0x6e, 0x7c, 0x85, + 0x73, 0x60, 0x63, 0x69, 0x83, 0x8f, 0x80, 0x6f, 0x6c, 0x8b, 0xa3, 0xad, 0xa9, 0x99, 0x9b, 0xb0, + 0xa9, 0x93, 0x7b, 0x69, 0x6b, 0x78, 0x7e, 0x72, 0x64, 0x58, 0x49, 0x4c, 0x4c, 0x3b, 0x38, 0x3c, + 0x34, 0x3f, 0x4b, 0x45, 0x48, 0x52, 0x68, 0x85, 0x79, 0x6e, 0x7c, 0x81, 0x94, 0x9d, 0x98, 0xa0, + 0x95, 0x8f, 0x8d, 0x81, 0x70, 0x63, 0x53, 0x54, 0x5f, 0x68, 0x77, 0x86, 0x88, 0x8e, 0x80, 0x70, + 0x68, 0x62, 0x6a, 0x6d, 0x72, 0x67, 0x61, 0x82, 0x96, 0xa6, 0xad, 0x99, 0x87, 0x84, 0x92, 0xa0, + 0x9c, 0x9a, 0xa7, 0xb3, 0xc6, 0xc3, 0xa7, 0xa7, 0xa5, 0x97, 0x9a, 0xa1, 0x8e, 0x7e, 0x87, 0xa1, + 0xb9, 0xba, 0xa8, 0x94, 0x85, 0x7d, 0x83, 0x82, 0x81, 0x84, 0x94, 0xa6, 0x9c, 0x82, 0x61, 0x59, + 0x69, 0x7d, 0x82, 0x72, 0x58, 0x5d, 0x66, 0x76, 0x8b, 0x7b, 0x6a, 0x5a, 0x53, 0x5e, 0x5a, 0x4d, + 0x52, 0x5f, 0x71, 0x83, 0x83, 0x77, 0x6c, 0x72, 0x7a, 0x70, 0x67, 0x66, 0x62, 0x5d, 0x64, 0x6e, + 0x6f, 0x67, 0x58, 0x5c, 0x64, 0x57, 0x49, 0x51, 0x67, 0x82, 0x88, 0x81, 0x7b, 0x6a, 0x6a, 0x6d, + 0x77, 0x74, 0x63, 0x72, 0x80, 0x88, 0x7d, 0x6c, 0x7a, 0x8f, 0x97, 0x9e, 0x93, 0x79, 0x6f, 0x72, + 0x81, 0x79, 0x6c, 0x6f, 0x87, 0x90, 0x8d, 0x8b, 0x84, 0x74, 0x6e, 0x79, 0x68, 0x58, 0x61, 0x68, + 0x7b, 0x97, 0xab, 0xaa, 0x9d, 0xa2, 0xa4, 0x9e, 0xa0, 0x96, 0x8a, 0xa2, 0xb6, 0xbb, 0xad, 0x98, + 0x94, 0x9e, 0xa8, 0xaa, 0x95, 0x8d, 0x82, 0x87, 0x99, 0x97, 0x85, 0x80, 0x9c, 0xb6, 0xb2, 0x9b, + 0x8e, 0x9a, 0xaf, 0xb2, 0xc6, 0xc6, 0xa2, 0x85, 0x8e, 0x9e, 0xa4, 0x9c, 0x7e, 0x7a, 0x88, 0x94, + 0xa2, 0xa4, 0xa5, 0xb3, 0xa4, 0xa2, 0x9d, 0x76, 0x73, 0x75, 0x77, 0x71, 0x6a, 0x62, 0x58, 0x66, + 0x8f, 0x90, 0x94, 0x85, 0x75, 0x81, 0x84, 0x8c, 0x83, 0x8b, 0x98, 0x9a, 0x92, 0x83, 0x73, 0x70, + 0x86, 0x90, 0x8f, 0x7e, 0x77, 0x75, 0x6c, 0x75, 0x73, 0x64, 0x58, 0x59, 0x5f, 0x58, 0x54, 0x53, + 0x5b, 0x61, 0x61, 0x5a, 0x45, 0x37, 0x16, 0x13, 0x3b, 0x4d, 0x49, 0x42, 0x43, 0x59, 0x76, 0x78, + 0x63, 0x57, 0x50, 0x57, 0x61, 0x61, 0x69, 0x86, 0x9f, 0xa5, 0xab, 0xa4, 0x94, 0x7d, 0x7b, 0x97, + 0xa2, 0x81, 0x6d, 0x59, 0x57, 0x5d, 0x5b, 0x54, 0x44, 0x38, 0x5d, 0x76, 0x76, 0x73, 0x7a, 0x87, + 0x93, 0x8b, 0x92, 0x95, 0x7b, 0x69, 0x7e, 0x70, 0x67, 0x66, 0x74, 0x76, 0x76, 0x84, 0x7c, 0x7b, + 0x89, 0x78, 0x7a, 0x86, 0x76, 0x83, 0x9d, 0xb1, 0xb0, 0x98, 0x7b, 0x82, 0x9e, 0xad, 0xa3, 0x83, + 0x66, 0x65, 0x6f, 0x64, 0x62, 0x63, 0x6b, 0x6b, 0x82, 0x88, 0x79, 0x7d, 0x76, 0x81, 0x94, 0x95, + 0x7e, 0x72, 0x69, 0x84, 0xa5, 0x95, 0x6c, 0x65, 0x6f, 0x73, 0x71, 0x7c, 0x7d, 0x7c, 0x80, 0x91, + 0xae, 0x9b, 0x8b, 0x9d, 0xb5, 0xd9, 0xd1, 0xb7, 0xa9, 0x9a, 0x97, 0x99, 0xb1, 0xbd, 0xab, 0x9f, + 0x87, 0x7b, 0x66, 0x4f, 0x45, 0x57, 0x6f, 0x75, 0x89, 0x87, 0x97, 0xb0, 0xb0, 0xa9, 0x9c, 0x92, + 0x9e, 0xa2, 0xa3, 0xa2, 0xac, 0xbb, 0xaa, 0xab, 0xab, 0xa3, 0xad, 0xa2, 0xa8, 0xbe, 0xc1, 0xa6, + 0x9b, 0xad, 0xb0, 0xb0, 0x9b, 0x7e, 0x84, 0x82, 0x91, 0x8c, 0x91, 0x97, 0x86, 0x77, 0x68, 0x5c, + 0x59, 0x46, 0x38, 0x51, 0x5a, 0x64, 0x56, 0x57, 0x69, 0x76, 0x70, 0x60, 0x3f, 0x49, 0x68, 0x7d, + 0xa1, 0x88, 0x7b, 0x7e, 0x73, 0x89, 0x84, 0x69, 0x6f, 0x68, 0x83, 0x8b, 0x6f, 0x66, 0x73, 0x88, + 0x88, 0x87, 0x6c, 0x54, 0x53, 0x59, 0x73, 0x74, 0x69, 0x75, 0x75, 0x6c, 0x75, 0x69, 0x4f, 0x2a, + 0x2a, 0x3f, 0x4f, 0x64, 0x62, 0x4b, 0x6b, 0x9c, 0xa1, 0x6e, 0x59, 0x4e, 0x50, 0x53, 0x6b, 0x85, + 0x80, 0x7a, 0x79, 0x86, 0x8c, 0x87, 0x69, 0x64, 0x85, 0x80, 0x67, 0x4d, 0x4e, 0x63, 0x6d, 0x71, + 0x69, 0x3c, 0x36, 0x4f, 0x71, 0x8f, 0x86, 0x95, 0x92, 0x81, 0x9b, 0xa7, 0x8a, 0x71, 0x82, 0x97, + 0x96, 0xac, 0x93, 0x99, 0xa6, 0xb0, 0xa7, 0x85, 0x82, 0x8a, 0x80, 0x88, 0x95, 0x94, 0x97, 0x99, + 0xa0, 0xa6, 0x96, 0x8e, 0x8f, 0xa2, 0xbf, 0xb6, 0x97, 0x8e, 0x7c, 0x90, 0xaf, 0xbe, 0xba, 0xa5, + 0xa9, 0xbb, 0xab, 0x9c, 0x86, 0x84, 0x9e, 0xa5, 0xa7, 0x95, 0x83, 0x8a, 0x96, 0x90, 0x96, 0x98, + 0x71, 0x69, 0x89, 0x8b, 0x69, 0x44, 0x42, 0x41, 0x3e, 0x54, 0x57, 0x44, 0x3c, 0x52, 0x6a, 0x83, + 0x7a, 0x70, 0x7d, 0x8e, 0xaa, 0xb1, 0x8c, 0x87, 0x97, 0x92, 0xad, 0xa5, 0x88, 0x60, 0x6d, 0x82, + 0x7c, 0x8f, 0x74, 0x6d, 0x82, 0x83, 0x73, 0x62, 0x3d, 0x47, 0x52, 0x5f, 0x76, 0x77, 0x62, 0x56, + 0x60, 0x7d, 0x8b, 0x6f, 0x66, 0x5a, 0x77, 0x8d, 0x6c, 0x65, 0x7b, 0x7a, 0x84, 0x85, 0x78, 0x8d, + 0x98, 0xb1, 0xc4, 0xb8, 0x9d, 0x94, 0x9a, 0xa7, 0xb3, 0x98, 0x78, 0x74, 0x73, 0x6e, 0x68, 0x68, + 0x63, 0x4f, 0x56, 0x5b, 0x5f, 0x63, 0x5d, 0x58, 0x7e, 0x9a, 0x8a, 0x77, 0x6a, 0x6c, 0x6a, 0x72, + 0x6c, 0x6a, 0x6d, 0x74, 0x8d, 0x8e, 0x6e, 0x8f, 0x90, 0x80, 0xa3, 0xa3, 0x8b, 0x89, 0x9d, 0x9f, + 0xa7, 0x9b, 0x92, 0x93, 0x95, 0x9f, 0xa5, 0x9e, 0x71, 0x6d, 0x6c, 0x70, 0x78, 0x8e, 0x8b, 0x8a, + 0x97, 0x7d, 0x6c, 0x68, 0x70, 0x82, 0x93, 0x96, 0x92, 0x88, 0x8f, 0x87, 0x7b, 0x91, 0x8d, 0x92, + 0xa8, 0xaf, 0xc5, 0xb3, 0x94, 0x8d, 0x80, 0x68, 0x5f, 0x54, 0x46, 0x4e, 0x67, 0x86, 0x94, 0xa7, + 0x99, 0x99, 0xba, 0xbb, 0xbc, 0xa8, 0x7b, 0x77, 0x9d, 0x97, 0x94, 0xa0, 0x82, 0x55, 0x5c, 0x61, + 0x51, 0x60, 0x61, 0x65, 0x83, 0x86, 0x75, 0x79, 0x72, 0x6b, 0x99, 0xa1, 0x7a, 0x83, 0x8f, 0x7c, + 0x98, 0xa2, 0x98, 0x9a, 0x95, 0x82, 0x94, 0x7a, 0x5d, 0x60, 0x84, 0x9d, 0xae, 0x9e, 0x83, 0x7c, + 0x91, 0xad, 0xa3, 0x90, 0x81, 0x7b, 0x8f, 0x83, 0x74, 0x84, 0x6b, 0x58, 0x5a, 0x48, 0x2f, 0x2b, + 0x38, 0x3b, 0x46, 0x45, 0x34, 0x22, 0x37, 0x3b, 0x4a, 0x52, 0x4b, 0x62, 0x8a, 0xa0, 0xa0, 0x9a, + 0x7d, 0x76, 0x84, 0x7b, 0x6b, 0x56, 0x46, 0x4d, 0x64, 0x63, 0x70, 0x88, 0x86, 0x82, 0x83, 0x84, + 0x87, 0x76, 0x61, 0x6c, 0x72, 0x62, 0x52, 0x5c, 0x5c, 0x5d, 0x74, 0x6e, 0x50, 0x55, 0x71, 0x83, + 0x86, 0x88, 0x83, 0x70, 0x71, 0x84, 0x86, 0x71, 0x77, 0x8a, 0x9a, 0xb0, 0xaf, 0xa2, 0x8e, 0x98, + 0x96, 0x8c, 0x7e, 0x67, 0x70, 0x8b, 0x9f, 0xb9, 0xaa, 0x98, 0xa1, 0x80, 0x81, 0x93, 0x7e, 0x6d, + 0x76, 0x97, 0xab, 0xa9, 0xa8, 0xad, 0x99, 0x92, 0x9d, 0x9e, 0x75, 0x64, 0x8d, 0xa2, 0x9a, 0xa0, + 0xab, 0x9e, 0x8a, 0x96, 0x9f, 0x96, 0x88, 0x8b, 0xb7, 0xd4, 0xc2, 0xc1, 0xb5, 0xa9, 0xae, 0x9e, + 0x84, 0x7c, 0x74, 0x87, 0xa2, 0x9f, 0x9c, 0x94, 0x95, 0x99, 0xab, 0xb0, 0xac, 0x93, 0x88, 0xa0, + 0x87, 0x85, 0x75, 0x67, 0x62, 0x6a, 0x7c, 0x92, 0x7d, 0x60, 0x6a, 0x76, 0x7b, 0x7a, 0x6c, 0x6a, + 0x6b, 0x6d, 0x5e, 0x4b, 0x57, 0x65, 0x76, 0x90, 0x9e, 0x8d, 0x88, 0x75, 0x84, 0x85, 0x4d, 0x34, + 0x46, 0x7a, 0x8b, 0x85, 0x79, 0x89, 0x8b, 0x77, 0xa7, 0x9a, 0x90, 0x84, 0x81, 0x93, 0x90, 0x8b, + 0x6f, 0x74, 0x72, 0x65, 0x6f, 0x5d, 0x3b, 0x32, 0x2c, 0x44, 0x68, 0x44, 0x29, 0x2f, 0x21, 0x39, + 0x51, 0x3d, 0x41, 0x64, 0x8b, 0xa2, 0x9c, 0x8a, 0x84, 0x7a, 0x8e, 0x94, 0x77, 0x53, 0x6c, 0x97, + 0xa3, 0xa4, 0xae, 0x97, 0x87, 0x90, 0x94, 0x82, 0x61, 0x5e, 0x6c, 0x6e, 0x4c, 0x49, 0x55, 0x4e, + 0x52, 0x6e, 0x81, 0x6e, 0x69, 0x6b, 0x76, 0x8b, 0x8e, 0x7a, 0x76, 0x6b, 0x67, 0x6e, 0x71, 0x6e, + 0x5d, 0x7b, 0xa3, 0xa2, 0x9a, 0x98, 0x9a, 0x86, 0x7a, 0x7a, 0x5a, 0x58, 0x70, 0x7b, 0x94, 0x90, + 0x8d, 0x89, 0x8f, 0x8c, 0x75, 0x57, 0x4a, 0x5e, 0x71, 0x8a, 0x8f, 0x91, 0x96, 0x90, 0x90, 0x8c, + 0x94, 0x72, 0x55, 0x62, 0x68, 0x70, 0x6f, 0x73, 0x86, 0x8e, 0x99, 0xa4, 0xa4, 0xa2, 0xb1, 0xcd, + 0xdf, 0xe2, 0xd6, 0xc4, 0xab, 0xa5, 0xa3, 0x95, 0x77, 0x8c, 0x87, 0x9b, 0xc4, 0xb0, 0xb1, 0xcb, + 0xcd, 0xb5, 0x8e, 0x87, 0x82, 0x7a, 0x7e, 0x81, 0x8c, 0x93, 0x8d, 0x81, 0xac, 0xd6, 0xb7, 0x93, + 0x82, 0x81, 0x87, 0x6c, 0x58, 0x6c, 0x7a, 0x7e, 0x8b, 0x90, 0x7d, 0x71, 0x74, 0x81, 0x8d, 0x8e, + 0x73, 0x74, 0x87, 0x84, 0x82, 0x7e, 0x68, 0x63, 0x78, 0x97, 0x98, 0x6e, 0x5a, 0x81, 0x91, 0x75, + 0x74, 0x7a, 0x65, 0x48, 0x4d, 0x69, 0x7d, 0x7b, 0x6e, 0x5f, 0x6e, 0x75, 0x57, 0x3e, 0x3a, 0x3c, + 0x3b, 0x46, 0x4d, 0x55, 0x58, 0x55, 0x5c, 0x53, 0x4b, 0x55, 0x71, 0x86, 0x8e, 0x98, 0x80, 0x73, + 0x6c, 0x66, 0x55, 0x60, 0x6f, 0x77, 0xa1, 0xc9, 0xbb, 0xb1, 0xad, 0xb2, 0x8f, 0x6c, 0x58, 0x54, + 0x52, 0x54, 0x46, 0x3e, 0x4c, 0x49, 0x5e, 0x74, 0x8f, 0x9e, 0x91, 0x8b, 0x8e, 0x92, 0x9f, 0x9a, + 0x71, 0x5f, 0x68, 0x6c, 0x7b, 0x6a, 0x5f, 0x7d, 0x9f, 0xb2, 0xb6, 0x9e, 0x83, 0x98, 0x9d, 0x97, + 0x8a, 0x7a, 0x6f, 0x6f, 0x8c, 0xb2, 0xa3, 0x8b, 0x8b, 0x8e, 0x91, 0x91, 0x7a, 0x62, 0x56, 0x61, + 0x72, 0x88, 0x82, 0x7a, 0x86, 0x9c, 0xa6, 0x97, 0x74, 0x60, 0x5d, 0x60, 0x6a, 0x79, 0x64, 0x4c, + 0x70, 0xa8, 0xbf, 0xac, 0xaa, 0xba, 0xd1, 0xf2, 0xd3, 0xa7, 0xa3, 0x86, 0x66, 0x6f, 0x79, 0x70, + 0x61, 0x6b, 0x88, 0x9c, 0x88, 0x8a, 0xa2, 0x97, 0x9d, 0x82, 0x60, 0x5f, 0x5c, 0x68, 0x7d, 0x9b, + 0x9e, 0x8d, 0xaf, 0xc8, 0xc1, 0xb8, 0x81, 0x78, 0x81, 0x75, 0x74, 0x6d, 0x66, 0x75, 0x7b, 0x81, + 0x7d, 0x75, 0x5d, 0x7d, 0xaf, 0xb6, 0xa6, 0x95, 0x8c, 0x71, 0x6f, 0x5a, 0x43, 0x41, 0x39, 0x58, + 0x7b, 0x8b, 0xae, 0xb9, 0xba, 0xc6, 0xbc, 0x84, 0x6c, 0x78, 0x87, 0x91, 0x88, 0x8e, 0x7b, 0x61, + 0x69, 0x79, 0x69, 0x3a, 0x1e, 0x2d, 0x31, 0x3d, 0x4d, 0x37, 0x40, 0x49, 0x3a, 0x4d, 0x5f, 0x57, + 0x69, 0x90, 0x8b, 0x83, 0x7c, 0x73, 0x6e, 0x4e, 0x5c, 0x6c, 0x55, 0x6a, 0x92, 0x9a, 0x9e, 0xae, + 0xb9, 0xb2, 0xb2, 0xa0, 0x81, 0x65, 0x5a, 0x59, 0x3e, 0x26, 0x46, 0x5c, 0x52, 0x7b, 0xa4, 0xb4, + 0xba, 0xa7, 0x9e, 0x9b, 0x79, 0x83, 0x8e, 0x7c, 0x76, 0x59, 0x69, 0x73, 0x6e, 0x8f, 0x98, 0x8e, + 0x88, 0x8b, 0x9c, 0x8e, 0x9c, 0xa4, 0x84, 0x7c, 0x66, 0x6d, 0x67, 0x5c, 0x74, 0x7d, 0x9c, 0xbc, + 0xc5, 0xb2, 0x8c, 0x78, 0x77, 0x7a, 0x82, 0x84, 0x84, 0x93, 0x96, 0x99, 0x9d, 0x94, 0x85, 0x71, + 0x59, 0x69, 0x72, 0x5f, 0x73, 0x74, 0x70, 0x6b, 0x78, 0x7a, 0x7c, 0xaf, 0xdc, 0xe4, 0xea, 0xf4, + 0xfe, 0xc0, 0xa9, 0xa7, 0x83, 0x6d, 0x6c, 0x86, 0x96, 0x96, 0xa3, 0xa4, 0xb0, 0xb2, 0xa1, 0x86, + 0x6a, 0x4a, 0x3d, 0x3c, 0x45, 0x4e, 0x5c, 0x74, 0x93, 0x98, 0x99, 0xa9, 0x96, 0x7a, 0x90, 0x9c, + 0x80, 0x6f, 0x67, 0x64, 0x75, 0x77, 0x78, 0x74, 0x70, 0x92, 0xac, 0x97, 0x7e, 0x6f, 0x88, 0x86, + 0x85, 0x78, 0x6e, 0x5a, 0x4d, 0x48, 0x53, 0x6f, 0x7e, 0x95, 0xbe, 0xd1, 0xdb, 0xdb, 0xa4, 0x81, + 0x6f, 0x5e, 0x6a, 0x71, 0x57, 0x60, 0x7b, 0x78, 0x79, 0x7c, 0x48, 0x33, 0x27, 0x25, 0x28, 0x2e, + 0x3b, 0x43, 0x47, 0x3f, 0x48, 0x51, 0x48, 0x49, 0x50, 0x4a, 0x3b, 0x5a, 0x65, 0x60, 0x5f, 0x59, + 0x64, 0x76, 0x7a, 0x77, 0x93, 0x98, 0x9f, 0xb0, 0xd6, 0xdb, 0xb4, 0x8e, 0x66, 0x58, 0x5a, 0x5c, + 0x55, 0x54, 0x52, 0x56, 0x6a, 0x82, 0x8e, 0x87, 0x7a, 0x8f, 0x91, 0x7d, 0x89, 0x9a, 0x9c, 0x8a, + 0x94, 0x91, 0x9a, 0xa2, 0x9e, 0xb3, 0xc8, 0xce, 0x98, 0x72, 0x9a, 0x9f, 0x84, 0x78, 0x72, 0x69, + 0x5c, 0x63, 0x87, 0x96, 0x99, 0xa9, 0xbb, 0xaf, 0xb9, 0xaf, 0x7e, 0x84, 0x7a, 0x6e, 0x87, 0x80, + 0x7d, 0x74, 0x80, 0x76, 0x66, 0x69, 0x4d, 0x49, 0x42, 0x51, 0x7a, 0x92, 0x9c, 0x91, 0x8e, 0x8d, + 0x71, 0x71, 0xaa, 0xbc, 0xb3, 0xbb, 0xbd, 0xd2, 0xdc, 0xbe, 0x9c, 0x9b, 0x93, 0x8c, 0x84, 0x76, + 0x90, 0xa6, 0xaa, 0xc1, 0xc6, 0x9d, 0xa2, 0x8c, 0x64, 0x6c, 0x55, 0x57, 0x6a, 0x67, 0x7a, 0x92, + 0x9c, 0x84, 0x67, 0x66, 0x68, 0x5c, 0x6e, 0x5d, 0x6d, 0x89, 0x76, 0x82, 0x8a, 0x7b, 0x79, 0x8a, + 0x90, 0x95, 0x87, 0x7a, 0x79, 0x7c, 0x81, 0x6b, 0x66, 0x68, 0x63, 0x57, 0x45, 0x48, 0x52, 0x63, + 0x87, 0x9f, 0xc2, 0xd1, 0xc7, 0xc8, 0xb2, 0x9d, 0x8e, 0x80, 0x80, 0x95, 0xa2, 0x91, 0x7c, 0x80, + 0x83, 0x75, 0x47, 0x28, 0x31, 0x3b, 0x4f, 0x4d, 0x45, 0x46, 0x41, 0x3d, 0x42, 0x6c, 0x73, 0x5b, + 0x4f, 0x3b, 0x42, 0x4f, 0x65, 0x76, 0x7b, 0x75, 0x84, 0x78, 0x83, 0x7e, 0x79, 0x9b, 0xbc, 0xcf, + 0xcc, 0xa6, 0x89, 0x7b, 0x5c, 0x5c, 0x4d, 0x3b, 0x3f, 0x3e, 0x3e, 0x3d, 0x4a, 0x6d, 0x67, 0x5c, + 0x58, 0x52, 0x76, 0x7b, 0x70, 0x6e, 0x6d, 0x74, 0x79, 0x79, 0x91, 0xae, 0xb7, 0xa0, 0x8e, 0x81, + 0x71, 0x63, 0x6d, 0x85, 0x94, 0xa2, 0x95, 0x72, 0x85, 0x9a, 0xa6, 0x9f, 0xa2, 0xaf, 0xb6, 0xa0, + 0x6c, 0x8b, 0x89, 0x75, 0x6d, 0x6b, 0x91, 0x96, 0x7d, 0x7c, 0x8f, 0xac, 0xa8, 0x85, 0x81, 0x7e, + 0x8a, 0xa5, 0x9b, 0x9c, 0x8c, 0x51, 0x60, 0x94, 0x8b, 0x99, 0x8f, 0x82, 0x97, 0x9d, 0xcb, 0xd7, + 0xd2, 0xc8, 0xae, 0xb1, 0xb2, 0xba, 0xc6, 0xb3, 0xaa, 0xab, 0xc2, 0xd5, 0xbf, 0x9b, 0x7a, 0x75, + 0x73, 0x61, 0x63, 0x6f, 0x73, 0x82, 0x90, 0x95, 0x8a, 0x82, 0x77, 0x6d, 0x60, 0x61, 0x69, 0x6b, + 0x69, 0x7e, 0x8c, 0x89, 0x86, 0x77, 0x7a, 0x7b, 0x88, 0x7c, 0x78, 0x6b, 0x4c, 0x55, 0x5b, 0x6b, + 0x7d, 0x68, 0x56, 0x51, 0x51, 0x5c, 0x6b, 0x83, 0x98, 0xaf, 0xc0, 0xa7, 0x93, 0x88, 0x7d, 0x8d, + 0x87, 0x79, 0x7d, 0x70, 0x5d, 0x74, 0x85, 0x72, 0x82, 0x65, 0x41, 0x36, 0x44, 0x67, 0x66, 0x62, + 0x59, 0x52, 0x45, 0x4b, 0x5d, 0x52, 0x48, 0x38, 0x32, 0x2a, 0x2a, 0x3c, 0x52, 0x5d, 0x64, 0x7e, + 0x89, 0x7e, 0x83, 0x92, 0xac, 0xbc, 0xda, 0xe1, 0xc4, 0xa0, 0x98, 0x95, 0x91, 0x6e, 0x4c, 0x4b, + 0x40, 0x4c, 0x62, 0x5e, 0x68, 0x56, 0x51, 0x5a, 0x63, 0x77, 0x80, 0x83, 0x8f, 0x93, 0x9f, 0xa2, + 0xa2, 0xb7, 0xbf, 0xc7, 0xc3, 0x9c, 0x97, 0x81, 0x6c, 0x85, 0x8e, 0x94, 0x8e, 0x82, 0x73, 0x56, + 0x68, 0x7a, 0x72, 0x8f, 0x99, 0x96, 0xa8, 0x93, 0x8b, 0x8c, 0x7d, 0x71, 0x7a, 0x7a, 0x78, 0x76, + 0x8c, 0x8b, 0x78, 0x7e, 0x85, 0x9d, 0x94, 0x7b, 0x84, 0x7b, 0x60, 0x6a, 0x75, 0x6f, 0x78, 0x85, + 0x7c, 0x87, 0x8f, 0x90, 0x9b, 0x99, 0x87, 0x8b, 0xa4, 0xa5, 0xa8, 0xc3, 0xc1, 0x98, 0x8c, 0x87, + 0x97, 0xb0, 0xaf, 0xba, 0xae, 0x95, 0x93, 0xb0, 0xb0, 0x9d, 0x92, 0x80, 0x86, 0x8b, 0x76, 0x61, + 0x63, 0x5d, 0x61, 0x75, 0x79, 0x76, 0x6f, 0x76, 0x78, 0x6c, 0x79, 0x82, 0x8b, 0x88, 0x8a, 0x93, + 0xaa, 0xa3, 0x89, 0x78, 0x5a, 0x59, 0x79, 0x75, 0x63, 0x5c, 0x5b, 0x48, 0x4e, 0x7c, 0x9f, 0x95, + 0x8c, 0x8f, 0x7b, 0x69, 0x81, 0x8b, 0x8c, 0x80, 0x86, 0x91, 0x91, 0x99, 0x91, 0x81, 0x6d, 0x5f, + 0x5e, 0x58, 0x5b, 0x4b, 0x50, 0x65, 0x5f, 0x49, 0x31, 0x40, 0x50, 0x5f, 0x58, 0x4f, 0x5e, 0x66, + 0x71, 0x81, 0x6d, 0x6f, 0x90, 0x96, 0x7a, 0x74, 0x79, 0x7d, 0x77, 0x85, 0x9b, 0x98, 0xb0, 0xb4, + 0x97, 0xa1, 0x9e, 0x76, 0x5f, 0x51, 0x53, 0x45, 0x52, 0x68, 0x57, 0x3f, 0x4c, 0x55, 0x65, 0x6e, + 0x6e, 0x5f, 0x68, 0x83, 0x89, 0x9f, 0xa5, 0x9a, 0xa1, 0x94, 0x88, 0x84, 0x85, 0x94, 0x97, 0x71, + 0x66, 0x78, 0x8e, 0x91, 0x88, 0x7b, 0x76, 0x6f, 0x79, 0x8e, 0x91, 0xa0, 0xa9, 0xa4, 0xa7, 0x8d, + 0x76, 0x6c, 0x77, 0x68, 0x56, 0x68, 0x7e, 0x8a, 0x88, 0x8d, 0xa9, 0xa7, 0xa5, 0xb0, 0xb8, 0xa7, + 0x9e, 0x99, 0x93, 0x93, 0x77, 0x70, 0x85, 0x9f, 0xa3, 0x97, 0x99, 0xab, 0x97, 0x80, 0x7b, 0x8d, + 0xa6, 0xb3, 0x9b, 0x8f, 0x9c, 0xa6, 0x9a, 0x98, 0xa4, 0xa9, 0xac, 0xaa, 0xb3, 0xac, 0xa8, 0xa1, + 0x94, 0x79, 0x61, 0x59, 0x5c, 0x4f, 0x52, 0x5f, 0x5a, 0x66, 0x72, 0x6f, 0x7c, 0x86, 0x97, 0xa3, + 0x94, 0x80, 0x8d, 0x93, 0xa6, 0xa2, 0x83, 0x75, 0x76, 0x6b, 0x68, 0x63, 0x55, 0x44, 0x50, 0x65, + 0x6c, 0x6c, 0x6d, 0x71, 0x62, 0x59, 0x71, 0x86, 0x77, 0x72, 0x69, 0x56, 0x5e, 0x52, 0x5a, 0x5f, + 0x56, 0x71, 0x78, 0x6d, 0x6d, 0x44, 0x50, 0x63, 0x68, 0x65, 0x5c, 0x71, 0x6a, 0x57, 0x4f, 0x51, + 0x55, 0x42, 0x48, 0x4f, 0x63, 0x75, 0x89, 0x95, 0x81, 0x72, 0x6c, 0x52, 0x5f, 0x7b, 0x70, 0x73, + 0x88, 0x93, 0xab, 0xc0, 0xc3, 0xcf, 0xdc, 0xdf, 0xc8, 0x88, 0x81, 0x9b, 0x90, 0x8b, 0x84, 0x74, + 0x5b, 0x46, 0x36, 0x34, 0x54, 0x57, 0x42, 0x50, 0x6c, 0x87, 0x9e, 0xa3, 0xa6, 0x97, 0x9f, 0xc1, + 0xce, 0xbb, 0xb5, 0xa8, 0x8f, 0xa1, 0xb1, 0x99, 0x8c, 0x81, 0x90, 0x93, 0x87, 0x91, 0x86, 0x81, + 0x7e, 0x72, 0x78, 0x96, 0x94, 0x8e, 0x93, 0x7a, 0x74, 0x83, 0x87, 0x8b, 0x80, 0x77, 0x92, 0xa1, + 0x91, 0x78, 0x62, 0x77, 0x82, 0x7d, 0x7e, 0x7c, 0x7c, 0x7e, 0x77, 0x5e, 0x79, 0x88, 0x83, 0x85, + 0x8b, 0x8b, 0x81, 0x76, 0x79, 0x90, 0x94, 0x90, 0x95, 0x88, 0x86, 0x78, 0x69, 0x7e, 0x8a, 0x90, + 0x94, 0xa3, 0xb7, 0xb5, 0xac, 0xb3, 0xa8, 0x9a, 0x9d, 0x9c, 0x86, 0x78, 0x65, 0x61, 0x68, 0x5c, + 0x4f, 0x60, 0x76, 0x72, 0x60, 0x54, 0x6e, 0x6e, 0x6b, 0x7d, 0x89, 0x84, 0x83, 0x9c, 0xa3, 0x91, + 0xa2, 0xa3, 0x97, 0x93, 0x95, 0x74, 0x80, 0x97, 0x95, 0x78, 0x66, 0x65, 0x5a, 0x54, 0x6a, 0x73, + 0x72, 0x67, 0x66, 0x76, 0x78, 0x7e, 0x96, 0x7c, 0x6c, 0x75, 0x6f, 0x75, 0x76, 0x6f, 0x6c, 0x6d, + 0x7c, 0x78, 0x67, 0x5c, 0x5a, 0x3d, 0x41, 0x5b, 0x54, 0x54, 0x62, 0x71, 0x6e, 0x6d, 0x65, 0x72, + 0x6d, 0x5b, 0x67, 0x55, 0x63, 0x74, 0x67, 0x70, 0x6c, 0x6e, 0x7b, 0x9c, 0x99, 0x96, 0x82, 0x86, + 0x9b, 0x81, 0x73, 0x7a, 0x7b, 0x65, 0x59, 0x49, 0x4f, 0x5e, 0x57, 0x59, 0x56, 0x6c, 0x75, 0x6c, + 0x7c, 0x89, 0x7b, 0x60, 0x6d, 0x82, 0x86, 0x94, 0x98, 0x93, 0x9f, 0x9d, 0x99, 0xa4, 0xaf, 0xae, + 0xa0, 0x99, 0xa3, 0xa5, 0x9c, 0x9c, 0x9c, 0x8a, 0x79, 0x9b, 0x9c, 0x89, 0x93, 0xa1, 0x7b, 0x76, + 0x8f, 0x9f, 0x9e, 0x9e, 0x94, 0x78, 0x8f, 0xa4, 0xa5, 0x96, 0x9d, 0xb0, 0xae, 0xad, 0xac, 0x8e, + 0x78, 0x8d, 0x8f, 0x94, 0x92, 0x8f, 0x94, 0x8e, 0x8e, 0xa4, 0xa6, 0x86, 0x8d, 0x9d, 0x92, 0x87, + 0x73, 0x70, 0x82, 0x85, 0x89, 0x99, 0x9b, 0xa1, 0x9d, 0x97, 0xaa, 0x9f, 0x84, 0x88, 0x84, 0x84, + 0x8a, 0x7e, 0x6b, 0x69, 0x5c, 0x5f, 0x74, 0x65, 0x5c, 0x5f, 0x66, 0x91, 0x7e, 0x66, 0x6b, 0x73, + 0x74, 0x5c, 0x5c, 0x82, 0x7a, 0x63, 0x6a, 0x65, 0x6b, 0x72, 0x63, 0x6e, 0x7c, 0x70, 0x5e, 0x6a, + 0x76, 0x70, 0x67, 0x76, 0x7a, 0x72, 0x71, 0x6a, 0x5e, 0x5a, 0x69, 0x81, 0x6c, 0x57, 0x67, 0x62, + 0x62, 0x52, 0x64, 0x7a, 0x71, 0x75, 0x71, 0x68, 0x6c, 0x72, 0x56, 0x55, 0x74, 0x7d, 0x72, 0x78, + 0x76, 0x80, 0x72, 0x62, 0x67, 0x5a, 0x56, 0x6a, 0x6b, 0x76, 0x7b, 0x65, 0x6e, 0x84, 0x8d, 0x8c, + 0x8d, 0x9d, 0x9b, 0x8e, 0xbc, 0xce, 0xbc, 0xb1, 0xac, 0x9c, 0x8a, 0x7d, 0x79, 0x7e, 0x75, 0x76, + 0x78, 0x6f, 0x6c, 0x72, 0x77, 0x81, 0x88, 0x80, 0x76, 0x72, 0x68, 0x62, 0x8a, 0x96, 0x98, 0xb1, + 0x9a, 0x8a, 0x8d, 0x95, 0xa2, 0x8e, 0x8d, 0x8e, 0x7d, 0x79, 0x76, 0x91, 0x91, 0x77, 0x8f, 0x98, + 0x7b, 0x64, 0x66, 0x74, 0x79, 0x8b, 0x8b, 0x9d, 0xa2, 0x97, 0x8a, 0x83, 0x7b, 0x6c, 0x70, 0x7a, + 0x7b, 0x85, 0x81, 0x8c, 0x93, 0x88, 0x85, 0x80, 0x83, 0x8a, 0x86, 0x8e, 0x8e, 0xa7, 0xae, 0x7e, + 0x86, 0x88, 0x78, 0x72, 0x6a, 0x6f, 0x72, 0x6d, 0x6e, 0x7c, 0x8f, 0x7b, 0x85, 0x8c, 0x81, 0x8e, + 0x93, 0xa0, 0xb3, 0xa7, 0x98, 0xb6, 0xa6, 0x9a, 0x96, 0x78, 0x6e, 0x6d, 0x70, 0x78, 0x6c, 0x67, + 0x79, 0x89, 0x8a, 0x81, 0x6e, 0x65, 0x75, 0x86, 0x75, 0x73, 0x87, 0x8b, 0x78, 0x6b, 0x7c, 0x8a, + 0x8f, 0x97, 0x7d, 0x83, 0x6b, 0x55, 0x5b, 0x67, 0x74, 0x73, 0x81, 0x77, 0x87, 0x79, 0x7a, 0x8b, + 0x70, 0x75, 0x7c, 0x74, 0x72, 0x78, 0x80, 0x88, 0x69, 0x6f, 0x83, 0x6d, 0x61, 0x60, 0x4b, 0x4f, + 0x6d, 0x6a, 0x73, 0x6a, 0x5f, 0x73, 0x70, 0x72, 0x6a, 0x67, 0x57, 0x59, 0x5a, 0x5f, 0x7c, 0x8d, + 0x71, 0x6e, 0x6b, 0x66, 0x74, 0x76, 0x87, 0x7e, 0x77, 0xa0, 0x96, 0x79, 0x85, 0xa4, 0xa4, 0x92, + 0x9d, 0xa1, 0x84, 0x7e, 0x77, 0x78, 0x64, 0x64, 0x77, 0x7e, 0x80, 0x75, 0x5c, 0x62, 0x7a, 0x6c, + 0x55, 0x62, 0x67, 0x69, 0x6d, 0x84, 0x95, 0x8e, 0x80, 0x70, 0x5d, 0x7d, 0x9a, 0x9d, 0x91, 0x94, + 0xae, 0x8d, 0x80, 0xa0, 0xa4, 0x92, 0x90, 0x8c, 0x81, 0x8e, 0xa1, 0xa5, 0xa5, 0xa6, 0x9f, 0x9b, + 0x95, 0x9a, 0xa1, 0x82, 0x7d, 0x95, 0x95, 0xaf, 0xa6, 0x93, 0x89, 0x9e, 0xaa, 0xa1, 0x99, 0x97, + 0x8b, 0x96, 0xa9, 0xb0, 0xa2, 0x8c, 0x92, 0x87, 0x87, 0x8e, 0x95, 0x7e, 0x6a, 0x5f, 0x62, 0x6c, + 0x7d, 0x90, 0x90, 0x8c, 0x83, 0x75, 0x70, 0x87, 0x8f, 0x97, 0x91, 0x9a, 0xa7, 0x93, 0x8e, 0x9c, + 0x89, 0x7d, 0x6e, 0x63, 0x75, 0x7b, 0x89, 0x71, 0x66, 0x80, 0x62, 0x4e, 0x5f, 0x5b, 0x49, 0x4e, + 0x5c, 0x62, 0x5d, 0x62, 0x6f, 0x73, 0x5e, 0x5c, 0x69, 0x73, 0x6b, 0x51, 0x42, 0x43, 0x4d, 0x66, + 0x7b, 0x71, 0x5b, 0x5b, 0x6b, 0x78, 0x7d, 0x74, 0x64, 0x70, 0x7d, 0x88, 0x85, 0x82, 0x71, 0x68, + 0x6d, 0x5e, 0x6f, 0x77, 0x59, 0x4f, 0x64, 0x73, 0x73, 0x6a, 0x76, 0x88, 0x80, 0x78, 0x7a, 0x90, + 0xa8, 0x9c, 0x8c, 0x7c, 0x85, 0x97, 0xa3, 0x97, 0x92, 0x8d, 0x6c, 0x63, 0x75, 0x8e, 0x96, 0x8c, + 0x81, 0x8e, 0x9d, 0x9c, 0x7a, 0x8b, 0xa9, 0x97, 0x81, 0x8b, 0x83, 0x74, 0x68, 0x7c, 0x86, 0x8a, + 0x8c, 0x88, 0x9c, 0x94, 0x8d, 0x8f, 0x7d, 0x7e, 0x84, 0x89, 0x84, 0x8b, 0x89, 0x8e, 0xa3, 0xa2, + 0x92, 0x85, 0x7b, 0x87, 0x9b, 0x97, 0x7d, 0x6e, 0x72, 0x73, 0x6d, 0x87, 0x87, 0x79, 0x62, 0x67, + 0x6d, 0x74, 0x84, 0x74, 0x72, 0x6a, 0x6f, 0x80, 0x79, 0x88, 0x8c, 0x8b, 0x83, 0x86, 0x84, 0x9f, + 0xaa, 0x95, 0x8e, 0x8c, 0x91, 0x98, 0x94, 0x93, 0x9a, 0x8a, 0x99, 0x9c, 0x8f, 0x95, 0x7a, 0x6a, + 0x7a, 0x7b, 0x73, 0x6d, 0x65, 0x71, 0x7b, 0x76, 0x8a, 0x97, 0x87, 0x9a, 0xa0, 0x90, 0x96, 0x95, + 0x96, 0x92, 0x9a, 0x91, 0x94, 0x87, 0x7b, 0x8a, 0x89, 0x82, 0x6c, 0x6a, 0x7c, 0x7b, 0x77, 0x63, + 0x51, 0x7b, 0x85, 0x77, 0x80, 0x87, 0x87, 0x62, 0x66, 0x76, 0x7a, 0x84, 0x71, 0x68, 0x6f, 0x79, + 0x6c, 0x65, 0x72, 0x7e, 0x6e, 0x5f, 0x75, 0x8e, 0x94, 0x93, 0x91, 0x7d, 0x6e, 0x6b, 0x7d, 0x6e, + 0x6f, 0x69, 0x5f, 0x74, 0x7a, 0x70, 0x68, 0x70, 0x6c, 0x5d, 0x64, 0x68, 0x58, 0x53, 0x58, 0x69, + 0x76, 0x7d, 0x84, 0x86, 0x8b, 0x89, 0x8d, 0x8f, 0x7e, 0x74, 0x72, 0x74, 0x70, 0x6c, 0x5f, 0x65, + 0x71, 0x6e, 0x73, 0x6f, 0x6b, 0x7a, 0x89, 0x8f, 0x86, 0x74, 0x80, 0x85, 0x83, 0x91, 0x87, 0x6e, + 0x6c, 0x6f, 0x67, 0x65, 0x71, 0x66, 0x6c, 0x7c, 0x78, 0x7c, 0x69, 0x6c, 0x76, 0x6d, 0x7b, 0x86, + 0x95, 0xa4, 0xa3, 0x9d, 0x9e, 0x87, 0x93, 0xa0, 0x83, 0x7b, 0x80, 0x7b, 0x83, 0x8b, 0x8d, 0x8a, + 0x88, 0x8e, 0x8a, 0x88, 0x9c, 0x9b, 0x89, 0x8a, 0x92, 0xaa, 0xad, 0xa9, 0xa0, 0xa2, 0xa5, 0xaf, + 0xaa, 0x9a, 0xaa, 0xae, 0x90, 0x8b, 0x90, 0x99, 0x7e, 0x84, 0x95, 0x8f, 0x8d, 0x83, 0x9b, 0x97, + 0x94, 0x8c, 0x82, 0x93, 0x94, 0x8e, 0x84, 0x88, 0x71, 0x6b, 0x6b, 0x61, 0x5d, 0x67, 0x7b, 0x73, + 0x79, 0x82, 0x84, 0x8a, 0x8b, 0x8b, 0x91, 0x91, 0x92, 0xa2, 0x8f, 0x8e, 0x93, 0x86, 0x83, 0x6d, + 0x6f, 0x7c, 0x65, 0x56, 0x58, 0x69, 0x63, 0x4d, 0x5d, 0x68, 0x71, 0x6a, 0x65, 0x6e, 0x71, 0x6b, + 0x67, 0x70, 0x7b, 0x87, 0x76, 0x66, 0x67, 0x67, 0x6e, 0x6a, 0x67, 0x71, 0x87, 0x6f, 0x6c, 0x78, + 0x77, 0x7e, 0x75, 0x71, 0x6b, 0x68, 0x6e, 0x67, 0x61, 0x5f, 0x68, 0x5e, 0x66, 0x69, 0x6f, 0x78, + 0x70, 0x6b, 0x61, 0x5a, 0x60, 0x5b, 0x48, 0x6c, 0x85, 0x81, 0x8a, 0x8b, 0x90, 0x92, 0x8c, 0x8e, + 0x94, 0x8a, 0x95, 0x90, 0x8d, 0x9f, 0x8c, 0x90, 0xa0, 0x97, 0x91, 0x8c, 0x89, 0x88, 0x8b, 0x92, + 0x9d, 0xa4, 0xa4, 0x8c, 0x8a, 0x8f, 0x8e, 0x80, 0x75, 0x82, 0x84, 0x7b, 0x7b, 0x7e, 0x82, 0x7e, + 0x83, 0x78, 0x6e, 0x76, 0x6b, 0x6e, 0x79, 0x92, 0x9e, 0x9c, 0x96, 0x9f, 0xa6, 0x9e, 0x9f, 0x91, + 0x94, 0x92, 0x8d, 0x81, 0x76, 0x82, 0x8d, 0x86, 0x80, 0x83, 0x87, 0x7c, 0x6c, 0x75, 0x84, 0x7a, + 0x71, 0x70, 0x7b, 0x77, 0x75, 0x6e, 0x6c, 0x76, 0x70, 0x71, 0x75, 0x85, 0x8a, 0x77, 0x85, 0x83, + 0x6f, 0x73, 0x81, 0x87, 0x77, 0x82, 0x8e, 0x87, 0x8c, 0x8b, 0x8b, 0x8e, 0x86, 0x83, 0x7e, 0x7a, + 0x76, 0x60, 0x65, 0x80, 0x96, 0x87, 0x7e, 0x84, 0x80, 0x85, 0x8d, 0x8d, 0x95, 0x94, 0x8e, 0x81, + 0x89, 0x8d, 0x8b, 0x8b, 0x94, 0x9c, 0x8b, 0x8a, 0x95, 0x8a, 0x85, 0x92, 0x93, 0x83, 0x7d, 0x87, + 0x7b, 0x75, 0x7c, 0x86, 0x87, 0x74, 0x7b, 0x6f, 0x77, 0x81, 0x70, 0x76, 0x80, 0x78, 0x69, 0x59, + 0x60, 0x67, 0x71, 0x7a, 0x83, 0x86, 0x78, 0x7b, 0x79, 0x70, 0x76, 0x71, 0x6a, 0x5f, 0x5c, 0x58, + 0x54, 0x62, 0x5c, 0x5e, 0x7b, 0x79, 0x7d, 0x6c, 0x69, 0x7b, 0x74, 0x6c, 0x70, 0x7b, 0x76, 0x78, + 0x86, 0x94, 0x95, 0x7e, 0x78, 0x7e, 0x86, 0x78, 0x73, 0x7b, 0x81, 0x75, 0x6c, 0x61, 0x77, 0x7e, + 0x69, 0x7e, 0x86, 0x73, 0x71, 0x72, 0x7e, 0x8f, 0x9c, 0x88, 0x81, 0x84, 0x7b, 0x72, 0x78, 0x83, + 0x77, 0x7b, 0x74, 0x72, 0x7e, 0x78, 0x77, 0x79, 0x77, 0x82, 0x8b, 0x7c, 0x83, 0x92, 0x99, 0x93, + 0x9a, 0x96, 0x96, 0x91, 0x90, 0x8b, 0x85, 0x92, 0x8f, 0x77, 0x71, 0x74, 0x6c, 0x6e, 0x80, 0x8d, + 0x8f, 0x8e, 0x97, 0x91, 0x9a, 0xa1, 0xa4, 0x98, 0x9d, 0x97, 0x88, 0x8d, 0x84, 0x84, 0x8b, 0x8d, + 0xa4, 0xa4, 0x96, 0x94, 0x92, 0x89, 0x86, 0x92, 0x95, 0x92, 0x95, 0x97, 0x98, 0x9a, 0x9d, 0x95, + 0x91, 0x89, 0x8e, 0x8e, 0x87, 0x80, 0x7d, 0x73, 0x79, 0x79, 0x73, 0x70, 0x7d, 0x77, 0x75, 0x84, + 0x84, 0x83, 0x7e, 0x89, 0x9d, 0x94, 0x8b, 0x87, 0x7d, 0x7a, 0x87, 0x83, 0x7e, 0x77, 0x82, 0x70, + 0x6b, 0x6b, 0x67, 0x59, 0x60, 0x5b, 0x6a, 0x73, 0x62, 0x55, 0x5e, 0x6c, 0x6a, 0x5b, 0x5c, 0x6a, + 0x63, 0x5e, 0x5c, 0x5f, 0x5c, 0x59, 0x5a, 0x4e, 0x58, 0x5e, 0x70, 0x6f, 0x7e, 0x81, 0x6d, 0x77, + 0x80, 0x77, 0x77, 0x75, 0x68, 0x6a, 0x6b, 0x6a, 0x73, 0x65, 0x68, 0x70, 0x71, 0x73, 0x77, 0x66, + 0x64, 0x68, 0x70, 0x79, 0x80, 0x83, 0x8b, 0x91, 0x95, 0x9d, 0x99, 0x95, 0x97, 0xa4, 0xa9, 0xa4, + 0xa2, 0xa6, 0xa1, 0xa1, 0xa4, 0x96, 0x9c, 0x8b, 0x87, 0x9a, 0x95, 0x8d, 0x8a, 0x8b, 0x91, 0x91, + 0x94, 0x88, 0x7e, 0x7a, 0x72, 0x78, 0x80, 0x7a, 0x82, 0x8d, 0x88, 0x83, 0x86, 0x77, 0x7d, 0x77, + 0x6e, 0x84, 0x82, 0x8e, 0x8c, 0x83, 0x8e, 0x8a, 0x8c, 0x8a, 0x7b, 0x7c, 0x7e, 0x7d, 0x78, 0x71, + 0x7b, 0x70, 0x79, 0x71, 0x67, 0x68, 0x79, 0x7b, 0x65, 0x6a, 0x84, 0x7c, 0x75, 0x6a, 0x7b, 0x7a, + 0x6e, 0x7d, 0x7d, 0x86, 0x80, 0x8a, 0x8f, 0x96, 0x9d, 0x98, 0x8e, 0x99, 0x9e, 0x82, 0x92, 0x91, + 0x95, 0x8e, 0x8b, 0x8b, 0x83, 0x90, 0x8b, 0x87, 0x82, 0x85, 0x85, 0x7d, 0x78, 0x7b, 0x76, 0x68, + 0x7a, 0x7d, 0x68, 0x6b, 0x6f, 0x68, 0x68, 0x78, 0x78, 0x79, 0x83, 0x83, 0x86, 0x83, 0x81, 0x7e, + 0x83, 0x82, 0x8c, 0x89, 0x8a, 0x88, 0x8f, 0x84, 0x87, 0x89, 0x79, 0x6f, 0x71, 0x88, 0x8a, 0x80, + 0x81, 0x7b, 0x7b, 0x7c, 0x92, 0x8f, 0x7a, 0x8f, 0x95, 0x88, 0x8e, 0x82, 0x84, 0x77, 0x6d, 0x7e, + 0x72, 0x77, 0x80, 0x74, 0x76, 0x81, 0x83, 0x75, 0x6f, 0x76, 0x6b, 0x66, 0x75, 0x79, 0x7c, 0x78, + 0x74, 0x79, 0x79, 0x73, 0x79, 0x7a, 0x77, 0x7b, 0x72, 0x68, 0x73, 0x73, 0x74, 0x74, 0x6e, 0x6e, + 0x6b, 0x78, 0x76, 0x7d, 0x85, 0x7d, 0x7c, 0x7b, 0x79, 0x75, 0x6e, 0x72, 0x6b, 0x60, 0x62, 0x68, + 0x6a, 0x6a, 0x74, 0x78, 0x83, 0x81, 0x7b, 0x7c, 0x76, 0x77, 0x71, 0x71, 0x80, 0x89, 0x84, 0x7b, + 0x83, 0x85, 0x81, 0x89, 0x7a, 0x7c, 0x7d, 0x79, 0x7b, 0x84, 0x8b, 0x8d, 0x8a, 0x87, 0x90, 0x8e, + 0x85, 0x90, 0x9b, 0x99, 0x8d, 0x8e, 0x90, 0x8c, 0x89, 0x8e, 0x8f, 0x93, 0x87, 0x84, 0x82, 0x7a, + 0x85, 0x8b, 0x8f, 0x9a, 0x8f, 0x78, 0x7a, 0x88, 0x8f, 0x82, 0x9a, 0xa2, 0x92, 0x9d, 0x9b, 0x8d, + 0x85, 0x89, 0x90, 0x95, 0x94, 0x8e, 0x84, 0x83, 0x82, 0x80, 0x8e, 0x8b, 0x85, 0x89, 0x7e, 0x93, + 0x91, 0x85, 0x92, 0x80, 0x72, 0x81, 0x75, 0x73, 0x6a, 0x6b, 0x76, 0x6c, 0x7c, 0x7a, 0x75, 0x83, + 0x7e, 0x7b, 0x77, 0x82, 0x80, 0x6f, 0x6c, 0x7d, 0x87, 0x74, 0x70, 0x6f, 0x6b, 0x66, 0x65, 0x5d, + 0x64, 0x67, 0x68, 0x66, 0x73, 0x77, 0x6d, 0x64, 0x6d, 0x78, 0x77, 0x75, 0x71, 0x7e, 0x89, 0x8d, + 0x83, 0x89, 0x7a, 0x79, 0x8c, 0x81, 0x87, 0x81, 0x7a, 0x81, 0x7a, 0x7a, 0x80, 0x83, 0x77, 0x6e, + 0x6c, 0x6b, 0x66, 0x5f, 0x6d, 0x7b, 0x87, 0x82, 0x7e, 0x85, 0x7b, 0x77, 0x80, 0x89, 0x88, 0x87, + 0x7a, 0x77, 0x73, 0x83, 0x75, 0x6f, 0x7e, 0x7d, 0x86, 0x80, 0x8b, 0x90, 0x92, 0x9b, 0x9b, 0xa4, + 0x9b, 0x90, 0x8b, 0x81, 0x7b, 0x79, 0x80, 0x87, 0x81, 0x75, 0x7c, 0x89, 0x79, 0x76, 0x84, 0x77, + 0x6a, 0x78, 0x7d, 0x7c, 0x85, 0x95, 0x8a, 0x83, 0x92, 0x8b, 0x7d, 0x77, 0x86, 0x97, 0x8b, 0x89, + 0x90, 0x89, 0x89, 0x92, 0x86, 0x8b, 0x8f, 0x89, 0x94, 0x94, 0x92, 0x94, 0x93, 0x8b, 0x88, 0x86, + 0x8f, 0x7c, 0x68, 0x68, 0x70, 0x71, 0x66, 0x5c, 0x61, 0x68, 0x60, 0x64, 0x7c, 0x77, 0x69, 0x6c, + 0x6d, 0x6f, 0x72, 0x73, 0x72, 0x75, 0x7b, 0x73, 0x72, 0x82, 0x82, 0x85, 0x8d, 0x8b, 0x81, 0x82, + 0x7e, 0x7d, 0x89, 0x83, 0x94, 0x94, 0x84, 0x84, 0x89, 0x89, 0x83, 0x8a, 0x81, 0x71, 0x82, 0x84, + 0x73, 0x79, 0x7a, 0x77, 0x77, 0x81, 0x8f, 0x8b, 0x8e, 0x88, 0x8d, 0x8d, 0x90, 0x8c, 0x84, 0x8b, + 0x97, 0x84, 0x7a, 0x8a, 0x7d, 0x75, 0x7e, 0x8b, 0x90, 0x91, 0x91, 0x8c, 0x84, 0x86, 0x8d, 0x79, + 0x7a, 0x7a, 0x73, 0x7b, 0x7c, 0x82, 0x80, 0x79, 0x8c, 0x8b, 0x74, 0x76, 0x76, 0x6d, 0x76, 0x74, + 0x77, 0x72, 0x71, 0x7c, 0x73, 0x74, 0x7a, 0x6d, 0x6f, 0x78, 0x7d, 0x79, 0x6e, 0x76, 0x87, 0x80, + 0x79, 0x75, 0x7b, 0x77, 0x6e, 0x75, 0x80, 0x85, 0x81, 0x78, 0x78, 0x71, 0x72, 0x67, 0x70, 0x72, + 0x74, 0x7e, 0x7c, 0x7a, 0x7b, 0x7e, 0x85, 0x7a, 0x7c, 0x80, 0x80, 0x71, 0x6c, 0x6c, 0x66, 0x75, + 0x86, 0x87, 0x7b, 0x76, 0x7c, 0x6d, 0x77, 0x87, 0x83, 0x70, 0x6f, 0x7c, 0x6e, 0x73, 0x7e, 0x6d, + 0x68, 0x82, 0x84, 0x83, 0x89, 0x90, 0x90, 0x89, 0x93, 0x89, 0x82, 0x82, 0x86, 0x83, 0x81, 0x87, + 0x8e, 0x85, 0x8c, 0x9d, 0x93, 0x8b, 0x99, 0x90, 0x8c, 0x8f, 0x80, 0x76, 0x7d, 0x74, 0x7c, 0x7c, + 0x82, 0x8a, 0x75, 0x78, 0x96, 0x9b, 0x92, 0x9d, 0x90, 0x96, 0x9d, 0x9b, 0x9a, 0x95, 0x9a, 0x93, + 0x8e, 0x9e, 0x9e, 0x93, 0x89, 0x87, 0x8f, 0x89, 0x85, 0x8b, 0x98, 0x88, 0x87, 0x89, 0x84, 0x89, + 0x83, 0x7c, 0x7d, 0x7a, 0x79, 0x6c, 0x6d, 0x75, 0x72, 0x77, 0x7d, 0x7d, 0x87, 0x7d, 0x87, 0x8d, + 0x84, 0x8b, 0x81, 0x7e, 0x88, 0x87, 0x77, 0x7a, 0x7a, 0x76, 0x73, 0x67, 0x6f, 0x5f, 0x55, 0x7c, + 0x84, 0x71, 0x71, 0x7a, 0x70, 0x60, 0x5f, 0x67, 0x62, 0x5c, 0x5e, 0x60, 0x5a, 0x68, 0x69, 0x60, + 0x74, 0x76, 0x6a, 0x75, 0x7a, 0x75, 0x71, 0x68, 0x71, 0x77, 0x77, 0x73, 0x6c, 0x63, 0x68, 0x80, + 0x7c, 0x7c, 0x83, 0x7b, 0x78, 0x71, 0x74, 0x7c, 0x86, 0x86, 0x7d, 0x82, 0x82, 0x8e, 0x85, 0x80, + 0x9a, 0x99, 0x8f, 0x8b, 0x8e, 0x98, 0x9b, 0xa5, 0x9f, 0x9a, 0xa1, 0xa0, 0x97, 0x9c, 0xa3, 0xa3, + 0x9a, 0x90, 0x88, 0x8a, 0x80, 0x77, 0x80, 0x7c, 0x84, 0x8e, 0x85, 0x71, 0x7b, 0x80, 0x71, 0x73, + 0x76, 0x72, 0x75, 0x65, 0x5f, 0x6c, 0x73, 0x77, 0x6d, 0x6a, 0x77, 0x7d, 0x86, 0x88, 0x86, 0x80, + 0x80, 0x86, 0x81, 0x7e, 0x82, 0x84, 0x76, 0x7e, 0x8d, 0x86, 0x7d, 0x7e, 0x8a, 0x7d, 0x76, 0x75, + 0x69, 0x67, 0x6b, 0x66, 0x6c, 0x64, 0x69, 0x6e, 0x6a, 0x71, 0x7c, 0x76, 0x79, 0x85, 0x86, 0x8b, + 0x8a, 0x87, 0x83, 0x7a, 0x8c, 0x8d, 0x7c, 0x7e, 0x84, 0x7c, 0x93, 0x80, 0x86, 0x8f, 0x88, 0x8e, + 0x87, 0x93, 0x99, 0x8b, 0x8c, 0x8c, 0x8a, 0x81, 0x83, 0x7a, 0x81, 0x86, 0x7d, 0x76, 0x76, 0x7e, + 0x83, 0x82, 0x84, 0x87, 0x83, 0x8c, 0x87, 0x85, 0x90, 0x8d, 0x95, 0x91, 0x8a, 0x82, 0x84, 0x7b, + 0x7e, 0x81, 0x83, 0x7b, 0x82, 0x89, 0x8c, 0x93, 0x95, 0x9a, 0x91, 0x91, 0x94, 0x89, 0x83, 0x7e, + 0x78, 0x77, 0x85, 0x85, 0x7d, 0x81, 0x8d, 0x85, 0x83, 0x86, 0x81, 0x7a, 0x6e, 0x78, 0x7b, 0x7a, + 0x80, 0x7c, 0x6e, 0x77, 0x76, 0x6e, 0x70, 0x72, 0x77, 0x6c, 0x6d, 0x72, 0x6f, 0x66, 0x6b, 0x6b, + 0x68, 0x6e, 0x77, 0x6b, 0x65, 0x6f, 0x76, 0x7a, 0x77, 0x72, 0x6b, 0x77, 0x84, 0x73, 0x69, 0x7b, + 0x76, 0x71, 0x72, 0x73, 0x7b, 0x85, 0x7c, 0x80, 0x8b, 0x8a, 0x7c, 0x74, 0x7b, 0x86, 0x82, 0x78, + 0x72, 0x7e, 0x78, 0x72, 0x76, 0x6f, 0x73, 0x70, 0x6c, 0x75, 0x76, 0x75, 0x7b, 0x77, 0x78, 0x87, + 0x86, 0x8d, 0x8c, 0x91, 0x94, 0x94, 0x9b, 0x8d, 0x84, 0x8a, 0x8b, 0x7d, 0x83, 0x8d, 0x82, 0x82, + 0x89, 0x8e, 0x95, 0x8f, 0x8f, 0x92, 0x8a, 0x80, 0x78, 0x7c, 0x81, 0x89, 0x80, 0x83, 0x88, 0x81, + 0x75, 0x81, 0x8a, 0x8a, 0x8e, 0x8b, 0x99, 0x8e, 0x89, 0x8e, 0x7d, 0x7e, 0x80, 0x84, 0x83, 0x8a, + 0x89, 0x83, 0x84, 0x87, 0x89, 0x7c, 0x85, 0x87, 0x83, 0x77, 0x83, 0x80, 0x78, 0x7c, 0x7d, 0x80, + 0x80, 0x79, 0x7a, 0x7e, 0x84, 0x73, 0x6d, 0x88, 0x92, 0x89, 0x83, 0x7c, 0x8c, 0x8b, 0x84, 0x90, + 0x90, 0x85, 0x7a, 0x73, 0x73, 0x6b, 0x6d, 0x6b, 0x61, 0x6d, 0x6c, 0x6e, 0x78, 0x78, 0x76, 0x77, + 0x84, 0x89, 0x7e, 0x79, 0x84, 0x7c, 0x77, 0x7d, 0x7a, 0x73, 0x79, 0x7d, 0x7d, 0x87, 0x88, 0x85, + 0x76, 0x7d, 0x86, 0x70, 0x6f, 0x75, 0x80, 0x87, 0x7d, 0x77, 0x83, 0x74, 0x79, 0x79, 0x66, 0x68, + 0x71, 0x6c, 0x5e, 0x64, 0x63, 0x59, 0x56, 0x67, 0x6c, 0x70, 0x79, 0x82, 0x87, 0x90, 0x9a, 0x94, + 0x93, 0x9d, 0x9d, 0x93, 0x8d, 0x97, 0x9c, 0x93, 0x9a, 0xa6, 0x98, 0x98, 0x93, 0x8c, 0x8d, 0x94, + 0x94, 0x85, 0x88, 0x8e, 0x8a, 0x8e, 0x8e, 0x7d, 0x8d, 0x8e, 0x8c, 0x92, 0x7e, 0x7e, 0x7b, 0x78, + 0x7a, 0x7b, 0x72, 0x71, 0x72, 0x70, 0x77, 0x7c, 0x8a, 0x7e, 0x7c, 0x8c, 0x8c, 0x88, 0x89, 0x76, + 0x6e, 0x81, 0x7d, 0x83, 0x84, 0x7d, 0x75, 0x7c, 0x7e, 0x7d, 0x7a, 0x72, 0x67, 0x6a, 0x67, 0x5f, + 0x68, 0x64, 0x69, 0x70, 0x79, 0x6c, 0x6a, 0x72, 0x67, 0x70, 0x77, 0x81, 0x78, 0x72, 0x7d, 0x7d, + 0x69, 0x69, 0x7e, 0x74, 0x73, 0x80, 0x8e, 0x92, 0x8d, 0x8a, 0x8c, 0x91, 0x97, 0x90, 0x7d, 0x8c, + 0x83, 0x87, 0x8e, 0x89, 0x8a, 0x83, 0x7b, 0x83, 0x7e, 0x7e, 0x77, 0x6e, 0x75, 0x74, 0x78, 0x83, + 0x85, 0x8c, 0x8a, 0x84, 0x97, 0xa0, 0x92, 0x8b, 0x95, 0x8f, 0x8a, 0x96, 0x95, 0x8d, 0x85, 0x83, + 0x8c, 0x90, 0x8c, 0x7b, 0x86, 0x8f, 0x88, 0x81, 0x88, 0x90, 0x8a, 0x82, 0x84, 0x86, 0x81, 0x7d, + 0x79, 0x79, 0x82, 0x84, 0x86, 0x79, 0x7e, 0x78, 0x6f, 0x6e, 0x6e, 0x6f, 0x6b, 0x6c, 0x6f, 0x6a, + 0x6d, 0x6f, 0x6f, 0x71, 0x6f, 0x79, 0x7b, 0x6d, 0x72, 0x7b, 0x73, 0x69, 0x62, 0x68, 0x65, 0x62, + 0x6e, 0x74, 0x7b, 0x84, 0x7c, 0x85, 0x86, 0x87, 0x89, 0x83, 0x87, 0x88, 0x77, 0x7d, 0x8f, 0x84, + 0x79, 0x84, 0x8d, 0x86, 0x87, 0x82, 0x84, 0x89, 0x8a, 0x8a, 0x90, 0x84, 0x89, 0x88, 0x73, 0x7b, + 0x7d, 0x78, 0x78, 0x7b, 0x77, 0x7c, 0x7a, 0x73, 0x6b, 0x76, 0x73, 0x67, 0x73, 0x71, 0x6a, 0x80, + 0x89, 0x7e, 0x7e, 0x8c, 0x80, 0x7b, 0x7d, 0x81, 0x7d, 0x79, 0x80, 0x80, 0x8e, 0x8d, 0x88, 0x93, + 0x92, 0x90, 0x90, 0x8a, 0x80, 0x87, 0x80, 0x7c, 0x84, 0x87, 0x8d, 0x83, 0x77, 0x82, 0x89, 0x8e, + 0x86, 0x7e, 0x8f, 0x98, 0x8d, 0x84, 0x8b, 0x8f, 0x82, 0x75, 0x80, 0x8c, 0x88, 0x91, 0x9a, 0x99, + 0x9a, 0x98, 0x8e, 0x94, 0x94, 0x87, 0x86, 0x81, 0x7b, 0x81, 0x85, 0x80, 0x8b, 0x8b, 0x7a, 0x81, + 0x82, 0x79, 0x78, 0x77, 0x79, 0x78, 0x7c, 0x82, 0x7e, 0x83, 0x73, 0x7c, 0x7d, 0x79, 0x7b, 0x6d, + 0x73, 0x73, 0x6a, 0x73, 0x6a, 0x63, 0x67, 0x62, 0x6c, 0x6f, 0x68, 0x6e, 0x81, 0x79, 0x7b, 0x7b, + 0x76, 0x7c, 0x7a, 0x78, 0x77, 0x76, 0x70, 0x75, 0x83, 0x7e, 0x76, 0x87, 0x83, 0x72, 0x77, 0x79, + 0x74, 0x73, 0x71, 0x78, 0x79, 0x86, 0x85, 0x82, 0x7e, 0x70, 0x73, 0x7b, 0x76, 0x77, 0x7d, 0x74, + 0x78, 0x75, 0x6c, 0x70, 0x71, 0x6b, 0x6d, 0x7a, 0x78, 0x8c, 0x98, 0x92, 0x90, 0x9c, 0x9f, 0xa0, + 0x92, 0x9b, 0x98, 0x7b, 0x84, 0x8e, 0x8f, 0x85, 0x86, 0x88, 0x8b, 0x90, 0x82, 0x7a, 0x7d, 0x81, + 0x7d, 0x84, 0x81, 0x8b, 0x8e, 0x82, 0x85, 0x89, 0x87, 0x7c, 0x7c, 0x7a, 0x7a, 0x81, 0x83, 0x7d, + 0x76, 0x7c, 0x78, 0x6e, 0x75, 0x84, 0x81, 0x81, 0x80, 0x8c, 0x81, 0x78, 0x7e, 0x85, 0x86, 0x8a, + 0x7e, 0x6e, 0x7c, 0x7c, 0x71, 0x79, 0x7d, 0x7e, 0x76, 0x68, 0x69, 0x78, 0x6f, 0x67, 0x6e, 0x6c, + 0x6c, 0x77, 0x73, 0x6f, 0x78, 0x7a, 0x81, 0x7d, 0x85, 0x88, 0x79, 0x7b, 0x81, 0x79, 0x81, 0x7d, + 0x7a, 0x7e, 0x7d, 0x90, 0x91, 0x82, 0x80, 0x85, 0x88, 0x84, 0x87, 0x93, 0x9a, 0x92, 0x8c, 0x85, + 0x8f, 0x96, 0x7a, 0x7e, 0x89, 0x81, 0x88, 0x80, 0x7a, 0x84, 0x73, 0x75, 0x88, 0x84, 0x7b, 0x80, + 0x87, 0x8d, 0x8d, 0x88, 0x8c, 0x91, 0x89, 0x8b, 0x8f, 0x8f, 0x8c, 0x7a, 0x76, 0x7a, 0x7a, 0x82, + 0x79, 0x80, 0x86, 0x81, 0x83, 0x82, 0x88, 0x88, 0x84, 0x81, 0x8b, 0x87, 0x81, 0x85, 0x90, 0x96, + 0x8d, 0x99, 0x95, 0x85, 0x86, 0x7e, 0x82, 0x80, 0x73, 0x87, 0x89, 0x80, 0x7d, 0x7d, 0x78, 0x74, + 0x6f, 0x70, 0x7e, 0x7a, 0x74, 0x75, 0x77, 0x71, 0x6c, 0x6c, 0x6d, 0x68, 0x62, 0x69, 0x63, 0x67, + 0x71, 0x6f, 0x74, 0x68, 0x66, 0x6a, 0x66, 0x65, 0x6d, 0x72, 0x70, 0x7e, 0x81, 0x7c, 0x89, 0x8b, + 0x81, 0x84, 0x80, 0x76, 0x7e, 0x75, 0x6a, 0x7d, 0x80, 0x79, 0x78, 0x78, 0x83, 0x86, 0x7e, 0x82, + 0x89, 0x83, 0x82, 0x86, 0x8d, 0x8a, 0x90, 0x94, 0x83, 0x7c, 0x7e, 0x80, 0x81, 0x7d, 0x7d, 0x7e, + 0x85, 0x80, 0x7e, 0x8c, 0x86, 0x87, 0x89, 0x86, 0x81, 0x7e, 0x83, 0x89, 0x8d, 0x8f, 0x8d, 0x8d, + 0x87, 0x7d, 0x83, 0x82, 0x78, 0x78, 0x7c, 0x84, 0x79, 0x79, 0x7e, 0x79, 0x77, 0x76, 0x76, 0x7e, + 0x7e, 0x7a, 0x83, 0x88, 0x7a, 0x79, 0x81, 0x7b, 0x88, 0x87, 0x7c, 0x86, 0x8b, 0x8a, 0x8e, 0x8e, + 0x8a, 0x8d, 0x8e, 0x88, 0x92, 0x96, 0x89, 0x89, 0x94, 0x91, 0x8e, 0x8b, 0x85, 0x88, 0x8a, 0x80, + 0x77, 0x7e, 0x80, 0x75, 0x75, 0x76, 0x7a, 0x75, 0x70, 0x77, 0x85, 0x82, 0x76, 0x81, 0x84, 0x75, + 0x72, 0x73, 0x73, 0x6d, 0x6f, 0x67, 0x6f, 0x81, 0x7d, 0x79, 0x7e, 0x7c, 0x7c, 0x77, 0x70, 0x7d, + 0x77, 0x76, 0x75, 0x81, 0x81, 0x7a, 0x78, 0x78, 0x82, 0x86, 0x79, 0x74, 0x7b, 0x75, 0x73, 0x6d, + 0x7d, 0x77, 0x6b, 0x6a, 0x6f, 0x74, 0x6f, 0x6f, 0x79, 0x6d, 0x6e, 0x85, 0x81, 0x76, 0x7c, 0x7c, + 0x7b, 0x77, 0x78, 0x80, 0x82, 0x7a, 0x80, 0x90, 0x91, 0x8e, 0x87, 0x88, 0x91, 0x8f, 0x8b, 0x8d, + 0x8e, 0x8e, 0x89, 0x90, 0x94, 0x8a, 0x8b, 0x8d, 0x8e, 0x8c, 0x87, 0x82, 0x7d, 0x80, 0x88, 0x87, + 0x88, 0x8c, 0x8b, 0x84, 0x86, 0x92, 0x8f, 0x83, 0x87, 0x8d, 0x8b, 0x88, 0x93, 0x8d, 0x84, 0x7c, + 0x7b, 0x86, 0x86, 0x7e, 0x7d, 0x83, 0x8d, 0x79, 0x7a, 0x88, 0x7c, 0x72, 0x6b, 0x7d, 0x85, 0x73, + 0x6f, 0x72, 0x7a, 0x75, 0x76, 0x7c, 0x82, 0x77, 0x6c, 0x6c, 0x71, 0x73, 0x6c, 0x65, 0x69, 0x74, + 0x75, 0x6b, 0x68, 0x6e, 0x68, 0x6c, 0x6b, 0x75, 0x7a, 0x72, 0x70, 0x72, 0x82, 0x7b, 0x77, 0x7c, + 0x78, 0x79, 0x81, 0x80, 0x7a, 0x78, 0x7e, 0x8d, 0x86, 0x83, 0x85, 0x89, 0x85, 0x7d, 0x8e, 0x8d, + 0x90, 0x87, 0x82, 0x8f, 0x91, 0x81, 0x7c, 0x82, 0x7d, 0x83, 0x86, 0x82, 0x86, 0x88, 0x85, 0x98, + 0x9e, 0x97, 0x99, 0x97, 0x9a, 0x93, 0x96, 0x98, 0x90, 0x8b, 0x88, 0x82, 0x8b, 0x8c, 0x79, 0x7b, + 0x7e, 0x83, 0x81, 0x73, 0x7a, 0x80, 0x73, 0x70, 0x79, 0x7e, 0x7b, 0x6a, 0x71, 0x70, 0x76, 0x7b, + 0x6c, 0x7a, 0x79, 0x71, 0x70, 0x78, 0x7c, 0x71, 0x76, 0x73, 0x7b, 0x79, 0x74, 0x7b, 0x77, 0x77, + 0x77, 0x79, 0x7c, 0x7d, 0x7b, 0x75, 0x86, 0x8c, 0x79, 0x7a, 0x8e, 0x84, 0x76, 0x79, 0x7c, 0x76, + 0x77, 0x75, 0x78, 0x80, 0x78, 0x70, 0x6e, 0x79, 0x7a, 0x71, 0x70, 0x76, 0x7c, 0x7a, 0x79, 0x7a, + 0x79, 0x75, 0x83, 0x7e, 0x76, 0x7c, 0x77, 0x77, 0x7d, 0x7e, 0x85, 0x86, 0x82, 0x7c, 0x7c, 0x7c, + 0x81, 0x81, 0x7d, 0x78, 0x7b, 0x82, 0x7a, 0x7c, 0x85, 0x80, 0x80, 0x7d, 0x80, 0x7e, 0x81, 0x83, + 0x76, 0x7e, 0x88, 0x88, 0x8b, 0x87, 0x93, 0x8e, 0x90, 0x8f, 0x8e, 0x8a, 0x8e, 0x90, 0x8c, 0x89, + 0x8a, 0x89, 0x85, 0x8e, 0x91, 0x88, 0x81, 0x84, 0x7e, 0x7b, 0x83, 0x87, 0x84, 0x7b, 0x83, 0x86, + 0x82, 0x87, 0x7d, 0x79, 0x7d, 0x8f, 0x8c, 0x7d, 0x85, 0x89, 0x84, 0x89, 0x92, 0x8b, 0x87, 0x95, + 0x91, 0x8c, 0x8d, 0x89, 0x87, 0x80, 0x7a, 0x81, 0x81, 0x79, 0x7b, 0x71, 0x73, 0x76, 0x76, 0x70, + 0x72, 0x80, 0x81, 0x83, 0x88, 0x8b, 0x83, 0x7a, 0x80, 0x82, 0x79, 0x77, 0x76, 0x77, 0x6f, 0x73, + 0x7e, 0x76, 0x70, 0x70, 0x71, 0x71, 0x73, 0x70, 0x6e, 0x74, 0x74, 0x77, 0x74, 0x79, 0x75, 0x65, + 0x6e, 0x76, 0x71, 0x74, 0x74, 0x76, 0x7a, 0x7e, 0x7b, 0x78, 0x77, 0x7c, 0x7c, 0x7b, 0x83, 0x82, + 0x7b, 0x75, 0x74, 0x81, 0x7b, 0x6f, 0x79, 0x74, 0x76, 0x81, 0x7a, 0x78, 0x87, 0x82, 0x79, 0x86, + 0x7e, 0x80, 0x85, 0x88, 0x7d, 0x7e, 0x86, 0x83, 0x86, 0x83, 0x85, 0x96, 0x98, 0x93, 0x95, 0x8c, + 0x94, 0x97, 0x85, 0x80, 0x8c, 0x8e, 0x77, 0x80, 0x8d, 0x86, 0x85, 0x7b, 0x76, 0x81, 0x84, 0x82, + 0x84, 0x81, 0x85, 0x8c, 0x89, 0x82, 0x7e, 0x7e, 0x74, 0x7d, 0x88, 0x81, 0x82, 0x84, 0x7e, 0x7e, + 0x87, 0x81, 0x7a, 0x7c, 0x77, 0x80, 0x85, 0x7e, 0x84, 0x81, 0x80, 0x85, 0x77, 0x73, 0x79, 0x76, + 0x6f, 0x6e, 0x79, 0x7e, 0x6e, 0x6e, 0x78, 0x77, 0x74, 0x6f, 0x76, 0x7a, 0x79, 0x77, 0x6e, 0x6c, + 0x71, 0x73, 0x72, 0x77, 0x84, 0x7b, 0x6f, 0x80, 0x7d, 0x80, 0x82, 0x80, 0x80, 0x82, 0x85, 0x7c, + 0x80, 0x7e, 0x80, 0x7e, 0x81, 0x81, 0x7a, 0x7e, 0x80, 0x88, 0x83, 0x87, 0x93, 0x93, 0x83, 0x82, + 0x7d, 0x7a, 0x81, 0x83, 0x7d, 0x82, 0x8a, 0x83, 0x83, 0x85, 0x86, 0x88, 0x92, 0x8d, 0x8d, 0x8f, + 0x93, 0x91, 0x8d, 0x92, 0x91, 0x95, 0x91, 0x88, 0x8c, 0x91, 0x8f, 0x8c, 0x88, 0x84, 0x86, 0x81, + 0x76, 0x7b, 0x81, 0x84, 0x7e, 0x7c, 0x80, 0x83, 0x75, 0x73, 0x7a, 0x85, 0x7b, 0x77, 0x83, 0x83, + 0x84, 0x85, 0x84, 0x82, 0x83, 0x85, 0x85, 0x8a, 0x83, 0x7e, 0x7a, 0x77, 0x79, 0x76, 0x70, 0x6f, + 0x6b, 0x67, 0x69, 0x6e, 0x71, 0x73, 0x71, 0x69, 0x73, 0x71, 0x6b, 0x6b, 0x6e, 0x6f, 0x6b, 0x74, + 0x78, 0x70, 0x6f, 0x76, 0x7d, 0x7a, 0x73, 0x74, 0x7c, 0x7c, 0x75, 0x76, 0x7d, 0x80, 0x79, 0x75, + 0x7c, 0x7d, 0x79, 0x78, 0x7d, 0x82, 0x82, 0x88, 0x86, 0x86, 0x8d, 0x90, 0x80, 0x87, 0x8a, 0x83, + 0x7b, 0x85, 0x90, 0x81, 0x7e, 0x85, 0x8e, 0x8b, 0x81, 0x80, 0x7c, 0x85, 0x7d, 0x7b, 0x8b, 0x8b, + 0x84, 0x81, 0x84, 0x8e, 0x8a, 0x85, 0x82, 0x83, 0x86, 0x85, 0x81, 0x82, 0x87, 0x87, 0x84, 0x88, + 0x88, 0x8c, 0x85, 0x7c, 0x85, 0x83, 0x7d, 0x86, 0x8a, 0x7e, 0x73, 0x78, 0x80, 0x79, 0x76, 0x76, + 0x7c, 0x7c, 0x83, 0x7d, 0x82, 0x82, 0x79, 0x83, 0x7e, 0x80, 0x85, 0x7e, 0x85, 0x88, 0x84, 0x8a, + 0x8e, 0x8b, 0x7e, 0x7c, 0x87, 0x7b, 0x78, 0x79, 0x80, 0x83, 0x7b, 0x80, 0x7d, 0x85, 0x88, 0x83, + 0x83, 0x7e, 0x85, 0x8a, 0x81, 0x86, 0x88, 0x80, 0x7d, 0x89, 0x87, 0x76, 0x81, 0x7c, 0x74, 0x7d, + 0x84, 0x7c, 0x7a, 0x7a, 0x72, 0x75, 0x7e, 0x78, 0x6f, 0x72, 0x7b, 0x7a, 0x73, 0x7a, 0x79, 0x78, + 0x71, 0x73, 0x78, 0x69, 0x6a, 0x75, 0x75, 0x6f, 0x72, 0x77, 0x72, 0x7c, 0x7e, 0x7d, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x85, 0x7c, 0x79, 0x7e, 0x80, 0x89, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7a, 0x82, + 0x85, 0x7c, 0x79, 0x7c, 0x81, 0x81, 0x79, 0x84, 0x8e, 0x88, 0x86, 0x87, 0x95, 0x96, 0x85, 0x82, + 0x8f, 0x83, 0x81, 0x83, 0x7e, 0x85, 0x81, 0x7a, 0x79, 0x80, 0x8e, 0x8a, 0x7e, 0x88, 0x91, 0x91, + 0x8b, 0x87, 0x84, 0x86, 0x8d, 0x85, 0x87, 0x8a, 0x8a, 0x86, 0x82, 0x8b, 0x87, 0x85, 0x88, 0x7d, + 0x7d, 0x82, 0x78, 0x7e, 0x86, 0x84, 0x84, 0x83, 0x7e, 0x80, 0x7c, 0x71, 0x6f, 0x73, 0x6a, 0x6e, + 0x73, 0x75, 0x73, 0x77, 0x6d, 0x74, 0x7b, 0x75, 0x78, 0x76, 0x79, 0x7b, 0x7e, 0x84, 0x81, 0x87, + 0x7d, 0x76, 0x7d, 0x74, 0x70, 0x70, 0x6d, 0x70, 0x75, 0x7a, 0x7b, 0x77, 0x73, 0x6d, 0x74, 0x6f, + 0x72, 0x7a, 0x75, 0x7b, 0x83, 0x83, 0x84, 0x89, 0x88, 0x7d, 0x80, 0x87, 0x83, 0x7b, 0x7d, 0x7b, + 0x82, 0x89, 0x86, 0x8e, 0x8d, 0x83, 0x81, 0x8c, 0x93, 0x8f, 0x8a, 0x8c, 0x99, 0x9e, 0x94, 0x8e, + 0x99, 0x97, 0x94, 0x93, 0x8e, 0x8e, 0x8e, 0x88, 0x87, 0x83, 0x87, 0x85, 0x7b, 0x73, 0x74, 0x80, + 0x7c, 0x75, 0x7a, 0x81, 0x83, 0x84, 0x87, 0x79, 0x83, 0x85, 0x84, 0x7d, 0x7d, 0x89, 0x84, 0x7c, + 0x7c, 0x80, 0x7b, 0x77, 0x7d, 0x82, 0x7b, 0x76, 0x78, 0x73, 0x7e, 0x82, 0x7d, 0x7c, 0x7a, 0x83, + 0x84, 0x7c, 0x73, 0x6a, 0x6f, 0x74, 0x70, 0x69, 0x6d, 0x73, 0x6c, 0x66, 0x73, 0x77, 0x6f, 0x70, + 0x70, 0x76, 0x7e, 0x77, 0x74, 0x72, 0x7a, 0x78, 0x71, 0x77, 0x77, 0x76, 0x79, 0x7d, 0x7a, 0x83, + 0x7e, 0x71, 0x75, 0x7b, 0x82, 0x7a, 0x7a, 0x78, 0x7b, 0x7d, 0x77, 0x7a, 0x7e, 0x78, 0x80, 0x83, + 0x84, 0x85, 0x8b, 0x8b, 0x84, 0x88, 0x8f, 0x8c, 0x86, 0x82, 0x7e, 0x89, 0x91, 0x8d, 0x8b, 0x88, + 0x84, 0x87, 0x83, 0x7c, 0x86, 0x85, 0x81, 0x8b, 0x8b, 0x8a, 0x8c, 0x90, 0x8c, 0x88, 0x84, 0x89, + 0x88, 0x7d, 0x86, 0x8c, 0x83, 0x82, 0x85, 0x83, 0x80, 0x81, 0x82, 0x7d, 0x87, 0x8a, 0x87, 0x88, + 0x8d, 0x86, 0x83, 0x88, 0x82, 0x7e, 0x82, 0x82, 0x81, 0x85, 0x81, 0x87, 0x90, 0x8e, 0x88, 0x84, + 0x84, 0x84, 0x7e, 0x7b, 0x7b, 0x81, 0x6f, 0x77, 0x84, 0x80, 0x81, 0x73, 0x70, 0x7b, 0x7a, 0x79, + 0x7c, 0x78, 0x7a, 0x78, 0x82, 0x84, 0x77, 0x75, 0x73, 0x79, 0x74, 0x79, 0x7b, 0x78, 0x78, 0x7a, + 0x83, 0x7e, 0x74, 0x71, 0x78, 0x73, 0x75, 0x75, 0x78, 0x7c, 0x79, 0x79, 0x78, 0x79, 0x75, 0x70, + 0x6f, 0x74, 0x73, 0x7e, 0x7b, 0x79, 0x86, 0x87, 0x7e, 0x79, 0x84, 0x7e, 0x7b, 0x82, 0x80, 0x78, + 0x81, 0x7b, 0x75, 0x74, 0x76, 0x7b, 0x7d, 0x80, 0x7a, 0x80, 0x85, 0x87, 0x87, 0x8e, 0x8c, 0x81, + 0x86, 0x8a, 0x8a, 0x89, 0x87, 0x8b, 0x8f, 0x8f, 0x8b, 0x8b, 0x88, 0x86, 0x87, 0x85, 0x81, 0x7e, + 0x7c, 0x86, 0x88, 0x85, 0x7c, 0x7e, 0x81, 0x7b, 0x7b, 0x7b, 0x7b, 0x84, 0x86, 0x85, 0x85, 0x85, + 0x81, 0x80, 0x80, 0x81, 0x80, 0x79, 0x78, 0x82, 0x86, 0x82, 0x87, 0x88, 0x7e, 0x81, 0x86, 0x87, + 0x84, 0x7a, 0x7c, 0x8a, 0x88, 0x84, 0x7e, 0x79, 0x78, 0x77, 0x71, 0x72, 0x6c, 0x6f, 0x6c, 0x6c, + 0x70, 0x73, 0x74, 0x73, 0x74, 0x78, 0x79, 0x75, 0x7b, 0x7d, 0x77, 0x81, 0x86, 0x81, 0x7d, 0x80, + 0x7d, 0x76, 0x74, 0x79, 0x78, 0x78, 0x72, 0x6d, 0x79, 0x76, 0x73, 0x78, 0x75, 0x76, 0x78, 0x73, + 0x78, 0x80, 0x83, 0x7b, 0x7b, 0x88, 0x84, 0x86, 0x82, 0x82, 0x7c, 0x82, 0x88, 0x84, 0x8e, 0x8b, + 0x8c, 0x8f, 0x8c, 0x89, 0x8f, 0x8d, 0x8c, 0x95, 0x95, 0x98, 0x93, 0x8e, 0x8f, 0x93, 0x93, 0x94, + 0x8f, 0x8b, 0x92, 0x8d, 0x83, 0x8a, 0x92, 0x8b, 0x84, 0x81, 0x7a, 0x85, 0x83, 0x7e, 0x85, 0x88, + 0x85, 0x82, 0x7e, 0x83, 0x7d, 0x7e, 0x81, 0x7b, 0x81, 0x7b, 0x7e, 0x88, 0x86, 0x80, 0x7e, 0x89, + 0x79, 0x70, 0x77, 0x78, 0x79, 0x78, 0x73, 0x7a, 0x79, 0x74, 0x7a, 0x76, 0x78, 0x7c, 0x77, 0x6f, + 0x70, 0x72, 0x6a, 0x66, 0x66, 0x68, 0x67, 0x64, 0x68, 0x69, 0x6b, 0x6e, 0x69, 0x74, 0x7b, 0x78, + 0x77, 0x79, 0x77, 0x7b, 0x7e, 0x78, 0x7b, 0x80, 0x7b, 0x7e, 0x80, 0x76, 0x79, 0x7d, 0x6b, 0x71, + 0x78, 0x77, 0x79, 0x7a, 0x7d, 0x89, 0x88, 0x82, 0x85, 0x8e, 0x8b, 0x80, 0x84, 0x8a, 0x88, 0x8b, + 0x88, 0x83, 0x8f, 0x8f, 0x81, 0x82, 0x87, 0x83, 0x89, 0x8e, 0x8e, 0x95, 0x8e, 0x8c, 0x8b, 0x82, + 0x85, 0x83, 0x81, 0x89, 0x86, 0x81, 0x86, 0x90, 0x8c, 0x87, 0x8b, 0x8c, 0x82, 0x7e, 0x7d, 0x7d, + 0x7e, 0x86, 0x83, 0x89, 0x84, 0x7c, 0x7e, 0x7d, 0x7d, 0x7c, 0x7e, 0x7c, 0x7c, 0x78, 0x78, 0x7e, + 0x82, 0x76, 0x73, 0x82, 0x83, 0x76, 0x6d, 0x79, 0x7a, 0x7c, 0x7b, 0x7d, 0x85, 0x87, 0x7b, 0x7b, + 0x85, 0x85, 0x84, 0x7c, 0x80, 0x88, 0x85, 0x81, 0x82, 0x7b, 0x7b, 0x7c, 0x7a, 0x82, 0x7d, 0x82, + 0x80, 0x80, 0x7e, 0x83, 0x89, 0x84, 0x7e, 0x83, 0x85, 0x7e, 0x81, 0x7d, 0x81, 0x82, 0x82, 0x81, + 0x7a, 0x7c, 0x7d, 0x74, 0x74, 0x80, 0x79, 0x7d, 0x79, 0x77, 0x7c, 0x76, 0x75, 0x77, 0x7c, 0x78, + 0x7d, 0x75, 0x72, 0x7a, 0x82, 0x82, 0x80, 0x77, 0x72, 0x7b, 0x7b, 0x7b, 0x76, 0x79, 0x7c, 0x77, + 0x79, 0x84, 0x79, 0x76, 0x7b, 0x77, 0x85, 0x83, 0x79, 0x7c, 0x78, 0x7b, 0x80, 0x7e, 0x81, 0x83, + 0x82, 0x7d, 0x7e, 0x86, 0x83, 0x89, 0x87, 0x84, 0x8b, 0x83, 0x87, 0x8f, 0x8b, 0x85, 0x86, 0x8c, + 0x88, 0x8a, 0x82, 0x79, 0x84, 0x88, 0x80, 0x84, 0x84, 0x84, 0x81, 0x80, 0x89, 0x81, 0x86, 0x81, + 0x77, 0x88, 0x89, 0x8a, 0x87, 0x7a, 0x88, 0x8e, 0x88, 0x84, 0x7d, 0x80, 0x81, 0x80, 0x81, 0x84, + 0x85, 0x7a, 0x79, 0x7e, 0x7d, 0x77, 0x75, 0x72, 0x73, 0x79, 0x76, 0x75, 0x6d, 0x76, 0x7a, 0x7a, + 0x77, 0x75, 0x7a, 0x7c, 0x71, 0x71, 0x74, 0x76, 0x7c, 0x73, 0x73, 0x79, 0x79, 0x74, 0x6e, 0x77, + 0x75, 0x6f, 0x75, 0x75, 0x82, 0x85, 0x7c, 0x78, 0x75, 0x7b, 0x83, 0x79, 0x7a, 0x7c, 0x7c, 0x7d, + 0x79, 0x7e, 0x86, 0x79, 0x79, 0x7d, 0x7b, 0x7b, 0x78, 0x7c, 0x7b, 0x85, 0x93, 0x8b, 0x8b, 0x90, + 0x8b, 0x90, 0x90, 0x8a, 0x8d, 0x91, 0x96, 0x95, 0x8f, 0x9a, 0x95, 0x90, 0x95, 0x95, 0x90, 0x8a, + 0x8d, 0x93, 0x90, 0x8e, 0x94, 0x92, 0x8d, 0x91, 0x90, 0x87, 0x80, 0x7d, 0x82, 0x82, 0x84, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x77, 0x75, 0x7d, 0x78, 0x74, 0x80, 0x7d, 0x82, 0x81, 0x7b, 0x7d, 0x78, + 0x79, 0x72, 0x6d, 0x74, 0x71, 0x6e, 0x6e, 0x75, 0x74, 0x70, 0x72, 0x77, 0x73, 0x70, 0x74, 0x74, + 0x72, 0x69, 0x72, 0x72, 0x6e, 0x75, 0x72, 0x74, 0x77, 0x71, 0x77, 0x72, 0x72, 0x79, 0x72, 0x7b, + 0x83, 0x7a, 0x77, 0x75, 0x77, 0x7c, 0x7d, 0x80, 0x77, 0x77, 0x78, 0x79, 0x7c, 0x77, 0x7c, 0x7e, + 0x79, 0x7a, 0x80, 0x80, 0x7b, 0x7b, 0x7e, 0x79, 0x80, 0x83, 0x7d, 0x7d, 0x80, 0x82, 0x83, 0x80, + 0x83, 0x81, 0x83, 0x82, 0x82, 0x8d, 0x91, 0x8e, 0x8b, 0x83, 0x88, 0x8a, 0x83, 0x89, 0x84, 0x80, + 0x84, 0x82, 0x82, 0x87, 0x8e, 0x89, 0x87, 0x92, 0x92, 0x8d, 0x8b, 0x83, 0x87, 0x8d, 0x8e, 0x8b, + 0x86, 0x88, 0x87, 0x82, 0x88, 0x83, 0x80, 0x80, 0x83, 0x83, 0x82, 0x8a, 0x8d, 0x83, 0x81, 0x87, + 0x89, 0x85, 0x78, 0x79, 0x84, 0x80, 0x7e, 0x84, 0x84, 0x7a, 0x78, 0x7a, 0x77, 0x76, 0x7b, 0x74, + 0x71, 0x77, 0x7c, 0x7d, 0x77, 0x79, 0x75, 0x73, 0x74, 0x74, 0x71, 0x72, 0x76, 0x7c, 0x7d, 0x7d, + 0x7e, 0x7c, 0x78, 0x7c, 0x75, 0x71, 0x7c, 0x7c, 0x79, 0x7b, 0x7c, 0x88, 0x87, 0x83, 0x83, 0x89, + 0x85, 0x81, 0x80, 0x81, 0x85, 0x84, 0x7d, 0x79, 0x80, 0x80, 0x7a, 0x74, 0x6e, 0x7b, 0x78, 0x78, + 0x7d, 0x80, 0x7e, 0x7e, 0x84, 0x84, 0x7d, 0x88, 0x8b, 0x7c, 0x84, 0x86, 0x86, 0x8a, 0x88, 0x84, + 0x89, 0x85, 0x7e, 0x81, 0x7e, 0x81, 0x80, 0x7c, 0x7e, 0x83, 0x85, 0x80, 0x7d, 0x7b, 0x7b, 0x7d, + 0x79, 0x79, 0x80, 0x77, 0x7d, 0x83, 0x81, 0x86, 0x82, 0x7e, 0x7a, 0x7d, 0x82, 0x7d, 0x78, 0x78, + 0x7b, 0x82, 0x85, 0x7c, 0x75, 0x7b, 0x7c, 0x76, 0x7c, 0x86, 0x88, 0x84, 0x80, 0x88, 0x87, 0x81, + 0x7d, 0x7a, 0x7d, 0x81, 0x76, 0x72, 0x7c, 0x7e, 0x7b, 0x81, 0x82, 0x84, 0x8e, 0x85, 0x81, 0x81, + 0x7d, 0x7b, 0x7d, 0x80, 0x7c, 0x7b, 0x79, 0x7b, 0x7d, 0x7a, 0x76, 0x78, 0x77, 0x75, 0x77, 0x7d, + 0x7d, 0x73, 0x75, 0x83, 0x82, 0x7c, 0x7c, 0x81, 0x84, 0x7a, 0x7c, 0x7d, 0x77, 0x78, 0x7a, 0x80, + 0x7c, 0x7b, 0x7a, 0x74, 0x73, 0x7b, 0x73, 0x71, 0x7d, 0x7d, 0x7e, 0x7a, 0x81, 0x85, 0x82, 0x82, + 0x7e, 0x81, 0x7d, 0x7d, 0x83, 0x7c, 0x81, 0x81, 0x81, 0x86, 0x87, 0x83, 0x7b, 0x7b, 0x82, 0x85, + 0x8a, 0x8e, 0x88, 0x86, 0x8c, 0x95, 0x95, 0x92, 0x8e, 0x8a, 0x84, 0x85, 0x8c, 0x8a, 0x87, 0x86, + 0x8a, 0x8f, 0x8c, 0x88, 0x83, 0x86, 0x8e, 0x8d, 0x8a, 0x89, 0x8c, 0x87, 0x85, 0x88, 0x83, 0x8a, + 0x84, 0x79, 0x7d, 0x81, 0x81, 0x83, 0x87, 0x89, 0x88, 0x89, 0x83, 0x80, 0x7e, 0x82, 0x7c, 0x78, + 0x7c, 0x83, 0x80, 0x7c, 0x79, 0x79, 0x78, 0x79, 0x76, 0x6a, 0x66, 0x6c, 0x6b, 0x6e, 0x6a, 0x6a, + 0x70, 0x6a, 0x65, 0x69, 0x70, 0x69, 0x60, 0x66, 0x6a, 0x77, 0x78, 0x6c, 0x6f, 0x73, 0x75, 0x72, + 0x6f, 0x72, 0x74, 0x76, 0x79, 0x79, 0x78, 0x76, 0x7b, 0x7e, 0x7c, 0x80, 0x81, 0x7b, 0x77, 0x7d, + 0x7b, 0x7d, 0x80, 0x88, 0x8a, 0x85, 0x82, 0x7e, 0x82, 0x81, 0x85, 0x87, 0x86, 0x8b, 0x92, 0x8d, + 0x90, 0x94, 0x91, 0x94, 0x91, 0x8b, 0x8b, 0x90, 0x8c, 0x85, 0x8c, 0x91, 0x8e, 0x87, 0x8b, 0x91, + 0x88, 0x85, 0x88, 0x85, 0x89, 0x8b, 0x84, 0x88, 0x83, 0x82, 0x87, 0x86, 0x7e, 0x83, 0x80, 0x7d, + 0x83, 0x89, 0x8a, 0x88, 0x7e, 0x7b, 0x7d, 0x7e, 0x7e, 0x7d, 0x7a, 0x7a, 0x7a, 0x74, 0x78, 0x7c, + 0x7b, 0x80, 0x7d, 0x80, 0x7e, 0x7b, 0x7c, 0x7a, 0x75, 0x78, 0x6c, 0x70, 0x78, 0x71, 0x6d, 0x78, + 0x7a, 0x79, 0x78, 0x74, 0x79, 0x82, 0x7c, 0x81, 0x81, 0x85, 0x83, 0x85, 0x84, 0x80, 0x85, 0x85, + 0x80, 0x86, 0x80, 0x7c, 0x83, 0x84, 0x81, 0x82, 0x85, 0x80, 0x7e, 0x81, 0x7d, 0x82, 0x8c, 0x86, + 0x80, 0x83, 0x82, 0x7c, 0x74, 0x77, 0x70, 0x6d, 0x76, 0x75, 0x76, 0x7c, 0x83, 0x82, 0x83, 0x86, + 0x81, 0x85, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x7c, 0x80, 0x82, 0x7d, + 0x76, 0x75, 0x75, 0x76, 0x79, 0x73, 0x75, 0x75, 0x74, 0x79, 0x79, 0x77, 0x7c, 0x7e, 0x80, 0x82, + 0x88, 0x85, 0x8a, 0x88, 0x82, 0x7e, 0x82, 0x80, 0x7b, 0x7d, 0x81, 0x80, 0x83, 0x85, 0x83, 0x84, + 0x80, 0x7b, 0x82, 0x88, 0x85, 0x83, 0x82, 0x82, 0x82, 0x89, 0x8a, 0x8c, 0x89, 0x81, 0x7c, 0x84, + 0x83, 0x82, 0x82, 0x7d, 0x7e, 0x84, 0x85, 0x87, 0x81, 0x7c, 0x86, 0x85, 0x85, 0x81, 0x7a, 0x78, + 0x7e, 0x7c, 0x75, 0x77, 0x78, 0x74, 0x77, 0x77, 0x7b, 0x7c, 0x75, 0x76, 0x75, 0x7a, 0x7e, 0x72, + 0x77, 0x76, 0x75, 0x79, 0x79, 0x77, 0x79, 0x81, 0x84, 0x81, 0x7d, 0x84, 0x82, 0x78, 0x74, 0x79, + 0x7c, 0x79, 0x70, 0x78, 0x82, 0x7a, 0x79, 0x7d, 0x86, 0x85, 0x82, 0x85, 0x88, 0x8b, 0x86, 0x82, + 0x84, 0x7e, 0x7c, 0x86, 0x81, 0x82, 0x87, 0x81, 0x83, 0x8c, 0x87, 0x87, 0x8b, 0x88, 0x8a, 0x91, + 0x93, 0x92, 0x8f, 0x90, 0x92, 0x90, 0x92, 0x8d, 0x8c, 0x8c, 0x87, 0x87, 0x84, 0x88, 0x85, 0x7d, + 0x82, 0x86, 0x85, 0x7a, 0x77, 0x81, 0x84, 0x84, 0x7c, 0x7e, 0x85, 0x7c, 0x76, 0x80, 0x86, 0x80, + 0x80, 0x81, 0x84, 0x85, 0x7e, 0x7d, 0x80, 0x7c, 0x78, 0x77, 0x7c, 0x78, 0x78, 0x78, 0x79, 0x76, + 0x6e, 0x73, 0x76, 0x72, 0x74, 0x7a, 0x79, 0x73, 0x74, 0x76, 0x75, 0x76, 0x75, 0x72, 0x72, 0x74, + 0x73, 0x74, 0x77, 0x79, 0x76, 0x75, 0x75, 0x77, 0x7b, 0x71, 0x71, 0x76, 0x77, 0x79, 0x7a, 0x76, + 0x77, 0x77, 0x75, 0x76, 0x7a, 0x74, 0x6f, 0x79, 0x7e, 0x79, 0x79, 0x7a, 0x76, 0x76, 0x77, 0x78, + 0x7d, 0x78, 0x7a, 0x81, 0x82, 0x84, 0x86, 0x85, 0x88, 0x8e, 0x8c, 0x82, 0x85, 0x8a, 0x87, 0x82, + 0x7d, 0x84, 0x88, 0x89, 0x86, 0x88, 0x90, 0x89, 0x86, 0x87, 0x84, 0x88, 0x8b, 0x87, 0x86, 0x8e, + 0x8f, 0x85, 0x87, 0x88, 0x8a, 0x8b, 0x8b, 0x87, 0x88, 0x8c, 0x8d, 0x89, 0x8a, 0x8d, 0x8a, 0x84, + 0x87, 0x8e, 0x8c, 0x89, 0x87, 0x84, 0x86, 0x89, 0x83, 0x7c, 0x7b, 0x80, 0x7d, 0x79, 0x7b, 0x7c, + 0x7d, 0x81, 0x7b, 0x7d, 0x84, 0x81, 0x79, 0x7b, 0x7b, 0x7b, 0x7a, 0x76, 0x7a, 0x77, 0x70, 0x75, + 0x76, 0x79, 0x7b, 0x7c, 0x78, 0x7b, 0x82, 0x7a, 0x7a, 0x77, 0x75, 0x75, 0x77, 0x78, 0x77, 0x7c, + 0x7c, 0x73, 0x78, 0x7c, 0x7a, 0x7d, 0x79, 0x75, 0x7d, 0x83, 0x80, 0x7c, 0x7a, 0x79, 0x77, 0x7a, + 0x7c, 0x7e, 0x7d, 0x7e, 0x80, 0x7a, 0x81, 0x84, 0x7c, 0x7b, 0x85, 0x86, 0x85, 0x80, 0x82, 0x86, + 0x84, 0x83, 0x85, 0x8e, 0x87, 0x81, 0x83, 0x87, 0x8d, 0x85, 0x81, 0x84, 0x86, 0x86, 0x86, 0x84, + 0x84, 0x80, 0x82, 0x87, 0x83, 0x83, 0x7e, 0x7a, 0x79, 0x7e, 0x86, 0x80, 0x7a, 0x80, 0x82, 0x81, + 0x81, 0x79, 0x7c, 0x78, 0x78, 0x80, 0x80, 0x80, 0x82, 0x7c, 0x7c, 0x77, 0x7c, 0x80, 0x77, 0x76, + 0x7d, 0x83, 0x81, 0x7c, 0x7d, 0x82, 0x7d, 0x79, 0x7c, 0x80, 0x82, 0x7b, 0x80, 0x7e, 0x7a, 0x79, + 0x77, 0x7c, 0x78, 0x77, 0x7d, 0x7d, 0x7d, 0x7c, 0x80, 0x7e, 0x7a, 0x83, 0x80, 0x74, 0x77, 0x7d, + 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7b, 0x79, 0x7b, 0x7c, 0x84, 0x87, 0x89, 0x83, + 0x83, 0x8e, 0x8b, 0x87, 0x8a, 0x81, 0x85, 0x8a, 0x7e, 0x7c, 0x7b, 0x7a, 0x75, 0x74, 0x7c, 0x7d, + 0x7b, 0x76, 0x77, 0x7b, 0x7c, 0x7d, 0x79, 0x7b, 0x7a, 0x80, 0x85, 0x81, 0x83, 0x88, 0x7e, 0x79, + 0x82, 0x83, 0x83, 0x82, 0x80, 0x80, 0x82, 0x80, 0x84, 0x80, 0x84, 0x86, 0x80, 0x81, 0x85, 0x84, + 0x83, 0x83, 0x87, 0x89, 0x87, 0x87, 0x82, 0x80, 0x84, 0x89, 0x87, 0x85, 0x86, 0x81, 0x81, 0x85, + 0x83, 0x87, 0x86, 0x85, 0x86, 0x8a, 0x88, 0x84, 0x87, 0x84, 0x82, 0x87, 0x84, 0x85, 0x84, 0x81, + 0x88, 0x8b, 0x86, 0x81, 0x83, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x83, 0x80, 0x7b, 0x82, 0x7c, + 0x73, 0x75, 0x78, 0x74, 0x74, 0x76, 0x74, 0x71, 0x6f, 0x70, 0x6f, 0x68, 0x6d, 0x71, 0x69, 0x67, + 0x69, 0x6c, 0x6c, 0x69, 0x6d, 0x70, 0x73, 0x74, 0x73, 0x79, 0x78, 0x7a, 0x79, 0x78, 0x77, 0x76, + 0x7a, 0x73, 0x79, 0x7d, 0x76, 0x7c, 0x7c, 0x7a, 0x7e, 0x7b, 0x74, 0x7d, 0x83, 0x82, 0x85, 0x86, + 0x84, 0x85, 0x84, 0x89, 0x8b, 0x88, 0x8a, 0x8b, 0x8a, 0x89, 0x8c, 0x8f, 0x85, 0x88, 0x94, 0x91, + 0x8e, 0x8d, 0x8a, 0x8f, 0x90, 0x8c, 0x90, 0x93, 0x8a, 0x87, 0x86, 0x88, 0x8a, 0x87, 0x87, 0x86, + 0x81, 0x82, 0x82, 0x82, 0x81, 0x85, 0x86, 0x81, 0x82, 0x83, 0x7d, 0x80, 0x85, 0x85, 0x81, 0x80, + 0x86, 0x85, 0x88, 0x81, 0x7d, 0x87, 0x83, 0x7c, 0x7e, 0x7d, 0x7d, 0x7c, 0x77, 0x7a, 0x7c, 0x79, + 0x76, 0x73, 0x77, 0x7c, 0x80, 0x7a, 0x73, 0x78, 0x7c, 0x79, 0x73, 0x73, 0x76, 0x76, 0x72, 0x72, + 0x7b, 0x7e, 0x7b, 0x75, 0x7a, 0x80, 0x7c, 0x7c, 0x78, 0x7c, 0x82, 0x80, 0x80, 0x81, 0x80, 0x85, + 0x8b, 0x7c, 0x7d, 0x86, 0x7e, 0x79, 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7b, 0x81, 0x81, 0x7c, 0x7b, + 0x7b, 0x81, 0x83, 0x7c, 0x79, 0x7e, 0x85, 0x7b, 0x79, 0x86, 0x81, 0x7c, 0x7d, 0x7b, 0x84, 0x87, + 0x85, 0x88, 0x87, 0x89, 0x86, 0x7e, 0x7c, 0x81, 0x83, 0x7d, 0x7d, 0x84, 0x83, 0x85, 0x88, 0x7e, + 0x7b, 0x81, 0x7d, 0x76, 0x75, 0x78, 0x74, 0x71, 0x7c, 0x79, 0x75, 0x78, 0x75, 0x76, 0x76, 0x7a, + 0x80, 0x74, 0x78, 0x84, 0x80, 0x7d, 0x80, 0x83, 0x83, 0x80, 0x81, 0x86, 0x7a, 0x83, 0x88, 0x87, + 0x86, 0x81, 0x83, 0x83, 0x82, 0x84, 0x88, 0x87, 0x83, 0x81, 0x80, 0x84, 0x87, 0x82, 0x7c, 0x81, + 0x81, 0x81, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x7e, 0x84, 0x85, 0x80, 0x7a, 0x7a, 0x84, 0x81, 0x78, + 0x7a, 0x7c, 0x7a, 0x78, 0x7b, 0x7d, 0x7b, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x7c, 0x7d, 0x7d, + 0x7e, 0x83, 0x79, 0x76, 0x81, 0x86, 0x81, 0x80, 0x83, 0x84, 0x84, 0x7e, 0x80, 0x82, 0x7b, 0x7b, + 0x7b, 0x7b, 0x7d, 0x7d, 0x7a, 0x7a, 0x7b, 0x85, 0x85, 0x7d, 0x82, 0x83, 0x83, 0x88, 0x7e, 0x81, + 0x82, 0x80, 0x7b, 0x7d, 0x83, 0x82, 0x82, 0x82, 0x83, 0x85, 0x89, 0x88, 0x85, 0x85, 0x8a, 0x8b, + 0x86, 0x84, 0x81, 0x86, 0x83, 0x7d, 0x86, 0x86, 0x81, 0x81, 0x7c, 0x80, 0x7c, 0x7b, 0x83, 0x82, + 0x81, 0x83, 0x8a, 0x88, 0x82, 0x83, 0x86, 0x83, 0x82, 0x86, 0x84, 0x80, 0x7d, 0x80, 0x7c, 0x7d, + 0x81, 0x7a, 0x78, 0x7a, 0x79, 0x7e, 0x81, 0x7d, 0x85, 0x84, 0x7d, 0x7b, 0x78, 0x78, 0x70, 0x76, + 0x79, 0x77, 0x7a, 0x7c, 0x7d, 0x7a, 0x7b, 0x7d, 0x78, 0x74, 0x75, 0x74, 0x74, 0x71, 0x77, 0x75, + 0x71, 0x73, 0x76, 0x79, 0x76, 0x72, 0x77, 0x78, 0x7a, 0x79, 0x75, 0x73, 0x73, 0x72, 0x72, 0x75, + 0x71, 0x72, 0x75, 0x76, 0x77, 0x7d, 0x7c, 0x7c, 0x7b, 0x80, 0x80, 0x82, 0x7e, 0x7c, 0x7e, 0x83, + 0x88, 0x86, 0x85, 0x87, 0x8a, 0x89, 0x87, 0x84, 0x84, 0x84, 0x82, 0x7d, 0x86, 0x89, 0x87, 0x85, + 0x89, 0x8d, 0x8c, 0x88, 0x8a, 0x85, 0x85, 0x85, 0x88, 0x87, 0x83, 0x89, 0x8a, 0x86, 0x87, 0x90, + 0x8c, 0x88, 0x8c, 0x8b, 0x8d, 0x8e, 0x8c, 0x8b, 0x8d, 0x8b, 0x87, 0x84, 0x82, 0x84, 0x81, 0x7e, + 0x83, 0x84, 0x83, 0x7d, 0x7d, 0x83, 0x7b, 0x7a, 0x7e, 0x7a, 0x7c, 0x80, 0x80, 0x7d, 0x80, 0x80, + 0x7c, 0x7d, 0x85, 0x84, 0x7a, 0x76, 0x7a, 0x73, 0x6e, 0x73, 0x72, 0x6f, 0x6b, 0x71, 0x77, 0x72, + 0x6f, 0x76, 0x74, 0x75, 0x77, 0x72, 0x76, 0x77, 0x76, 0x7a, 0x7c, 0x7a, 0x78, 0x78, 0x7c, 0x7c, + 0x77, 0x7a, 0x7b, 0x76, 0x77, 0x7d, 0x7d, 0x7b, 0x7a, 0x7d, 0x80, 0x7d, 0x84, 0x82, 0x81, 0x83, + 0x87, 0x87, 0x82, 0x85, 0x88, 0x84, 0x83, 0x88, 0x83, 0x86, 0x89, 0x8a, 0x8c, 0x8a, 0x91, 0x91, + 0x8a, 0x8e, 0x8e, 0x8c, 0x88, 0x8a, 0x89, 0x82, 0x84, 0x86, 0x82, 0x85, 0x86, 0x87, 0x81, 0x80, + 0x81, 0x80, 0x7a, 0x7a, 0x7b, 0x74, 0x77, 0x7b, 0x7b, 0x76, 0x78, 0x7b, 0x7b, 0x7b, 0x7e, 0x7d, + 0x7d, 0x7e, 0x7c, 0x7a, 0x77, 0x79, 0x74, 0x74, 0x79, 0x79, 0x78, 0x79, 0x7c, 0x7e, 0x78, 0x7d, + 0x80, 0x75, 0x72, 0x79, 0x78, 0x78, 0x79, 0x7b, 0x83, 0x80, 0x7e, 0x83, 0x7c, 0x7b, 0x7a, 0x7c, + 0x7d, 0x79, 0x7a, 0x82, 0x84, 0x7e, 0x7e, 0x86, 0x83, 0x80, 0x82, 0x81, 0x85, 0x83, 0x80, 0x82, + 0x84, 0x87, 0x85, 0x7b, 0x81, 0x83, 0x84, 0x83, 0x7e, 0x81, 0x86, 0x86, 0x7c, 0x7c, 0x81, 0x85, + 0x80, 0x7b, 0x80, 0x7e, 0x80, 0x7c, 0x7e, 0x85, 0x82, 0x85, 0x84, 0x81, 0x7e, 0x7d, 0x82, 0x7b, + 0x79, 0x84, 0x82, 0x7b, 0x7a, 0x83, 0x87, 0x80, 0x7c, 0x82, 0x81, 0x7b, 0x7e, 0x7b, 0x75, 0x77, + 0x76, 0x7a, 0x7d, 0x78, 0x80, 0x7b, 0x77, 0x7b, 0x80, 0x80, 0x7c, 0x7e, 0x82, 0x7e, 0x7d, 0x7a, + 0x7b, 0x80, 0x81, 0x86, 0x87, 0x83, 0x84, 0x87, 0x8b, 0x89, 0x81, 0x82, 0x83, 0x81, 0x7d, 0x82, + 0x85, 0x80, 0x80, 0x85, 0x87, 0x85, 0x82, 0x82, 0x86, 0x82, 0x84, 0x86, 0x81, 0x81, 0x84, 0x88, + 0x89, 0x84, 0x87, 0x8a, 0x83, 0x8a, 0x8a, 0x84, 0x85, 0x7c, 0x80, 0x83, 0x7d, 0x7e, 0x82, 0x7d, + 0x7c, 0x80, 0x80, 0x7a, 0x74, 0x78, 0x7a, 0x73, 0x71, 0x70, 0x70, 0x73, 0x6c, 0x6f, 0x71, 0x6f, + 0x6c, 0x6c, 0x72, 0x70, 0x72, 0x77, 0x75, 0x73, 0x77, 0x74, 0x74, 0x74, 0x73, 0x72, 0x74, 0x78, + 0x82, 0x83, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, 0x80, 0x7e, 0x7c, 0x7b, 0x7c, 0x7e, 0x83, 0x83, 0x83, + 0x87, 0x87, 0x86, 0x84, 0x89, 0x88, 0x80, 0x85, 0x89, 0x8f, 0x8d, 0x8b, 0x92, 0x92, 0x8e, 0x8e, + 0x90, 0x8e, 0x8a, 0x8c, 0x88, 0x87, 0x8f, 0x8b, 0x82, 0x82, 0x85, 0x83, 0x81, 0x81, 0x84, 0x82, + 0x83, 0x87, 0x86, 0x83, 0x85, 0x81, 0x80, 0x7d, 0x82, 0x86, 0x7e, 0x7e, 0x89, 0x88, 0x87, 0x85, + 0x82, 0x81, 0x7e, 0x7e, 0x78, 0x75, 0x77, 0x7a, 0x79, 0x7b, 0x7b, 0x7a, 0x78, 0x75, 0x79, 0x78, + 0x79, 0x78, 0x73, 0x74, 0x77, 0x75, 0x77, 0x79, 0x77, 0x73, 0x72, 0x79, 0x7c, 0x79, 0x79, 0x7a, + 0x7e, 0x7b, 0x7c, 0x83, 0x80, 0x7d, 0x79, 0x7c, 0x82, 0x78, 0x7b, 0x78, 0x7a, 0x85, 0x7e, 0x7c, + 0x7e, 0x7a, 0x7a, 0x7b, 0x79, 0x79, 0x7a, 0x78, 0x78, 0x80, 0x84, 0x82, 0x7d, 0x7d, 0x7d, 0x7b, + 0x82, 0x7e, 0x7c, 0x81, 0x81, 0x85, 0x8b, 0x85, 0x83, 0x86, 0x87, 0x83, 0x83, 0x86, 0x86, 0x83, + 0x7e, 0x87, 0x8b, 0x89, 0x88, 0x8a, 0x8b, 0x84, 0x85, 0x85, 0x86, 0x84, 0x82, 0x81, 0x82, 0x83, + 0x7d, 0x7b, 0x7d, 0x7b, 0x7c, 0x7a, 0x7e, 0x81, 0x7c, 0x7b, 0x7b, 0x81, 0x86, 0x81, 0x7e, 0x7c, + 0x7c, 0x7c, 0x75, 0x73, 0x76, 0x75, 0x79, 0x7c, 0x83, 0x81, 0x7b, 0x7e, 0x81, 0x7e, 0x7a, 0x7c, + 0x7c, 0x7a, 0x80, 0x85, 0x84, 0x7c, 0x7b, 0x81, 0x82, 0x7e, 0x81, 0x7e, 0x7a, 0x7c, 0x82, 0x7e, + 0x7e, 0x82, 0x80, 0x7b, 0x81, 0x7e, 0x7a, 0x7b, 0x79, 0x79, 0x7b, 0x7b, 0x7d, 0x7d, 0x79, 0x79, + 0x7a, 0x7a, 0x7c, 0x7a, 0x7d, 0x80, 0x81, 0x81, 0x85, 0x84, 0x80, 0x84, 0x81, 0x7e, 0x82, 0x80, + 0x82, 0x80, 0x83, 0x84, 0x81, 0x86, 0x88, 0x84, 0x80, 0x81, 0x80, 0x7a, 0x79, 0x7c, 0x7e, 0x7a, + 0x7c, 0x7d, 0x7d, 0x80, 0x85, 0x84, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x85, 0x86, 0x85, 0x84, 0x86, + 0x88, 0x7e, 0x85, 0x87, 0x81, 0x86, 0x86, 0x84, 0x84, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7b, + 0x7b, 0x82, 0x7d, 0x7c, 0x82, 0x81, 0x82, 0x7c, 0x80, 0x7e, 0x78, 0x7c, 0x80, 0x78, 0x7d, 0x82, + 0x7e, 0x82, 0x86, 0x7e, 0x7d, 0x80, 0x7b, 0x7d, 0x7b, 0x81, 0x7e, 0x7b, 0x7e, 0x85, 0x8a, 0x85, + 0x84, 0x85, 0x81, 0x83, 0x83, 0x7d, 0x7b, 0x7c, 0x7b, 0x7a, 0x7a, 0x80, 0x7d, 0x78, 0x7a, 0x7b, + 0x7c, 0x7c, 0x7a, 0x7b, 0x7b, 0x76, 0x7b, 0x7b, 0x78, 0x77, 0x78, 0x79, 0x82, 0x80, 0x7b, 0x83, + 0x86, 0x82, 0x82, 0x84, 0x81, 0x7d, 0x7c, 0x75, 0x74, 0x78, 0x79, 0x76, 0x75, 0x7a, 0x7b, 0x7a, + 0x7a, 0x7b, 0x7d, 0x7a, 0x76, 0x78, 0x79, 0x77, 0x79, 0x82, 0x81, 0x7c, 0x80, 0x83, 0x82, 0x83, + 0x82, 0x85, 0x83, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x81, 0x80, 0x7e, 0x7d, 0x7e, 0x83, 0x84, 0x82, + 0x83, 0x82, 0x83, 0x84, 0x85, 0x82, 0x80, 0x84, 0x86, 0x85, 0x89, 0x85, 0x84, 0x86, 0x87, 0x8b, + 0x8c, 0x88, 0x84, 0x87, 0x8b, 0x86, 0x84, 0x87, 0x87, 0x86, 0x84, 0x86, 0x87, 0x81, 0x81, 0x88, + 0x83, 0x82, 0x80, 0x82, 0x7e, 0x7b, 0x81, 0x7e, 0x7e, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x79, + 0x7d, 0x7c, 0x74, 0x77, 0x77, 0x76, 0x77, 0x76, 0x78, 0x76, 0x73, 0x75, 0x75, 0x76, 0x77, 0x74, + 0x70, 0x73, 0x75, 0x70, 0x72, 0x75, 0x76, 0x75, 0x75, 0x79, 0x7b, 0x7a, 0x79, 0x81, 0x82, 0x7d, + 0x80, 0x80, 0x79, 0x79, 0x7b, 0x7a, 0x7d, 0x7b, 0x7e, 0x7c, 0x7d, 0x81, 0x7e, 0x80, 0x80, 0x82, + 0x85, 0x85, 0x86, 0x88, 0x87, 0x88, 0x89, 0x87, 0x88, 0x86, 0x87, 0x8b, 0x8e, 0x8c, 0x89, 0x8e, + 0x8d, 0x89, 0x8b, 0x8b, 0x8d, 0x8a, 0x84, 0x8d, 0x8b, 0x83, 0x86, 0x85, 0x86, 0x84, 0x82, 0x84, + 0x81, 0x7d, 0x7b, 0x7b, 0x81, 0x82, 0x7b, 0x79, 0x7a, 0x7d, 0x7b, 0x7d, 0x7a, 0x76, 0x78, 0x76, + 0x79, 0x78, 0x7c, 0x79, 0x76, 0x7c, 0x7a, 0x78, 0x7a, 0x7b, 0x78, 0x78, 0x77, 0x78, 0x79, 0x78, + 0x77, 0x7b, 0x7b, 0x79, 0x7b, 0x7c, 0x7b, 0x79, 0x7b, 0x7d, 0x80, 0x81, 0x7d, 0x7c, 0x7c, 0x7b, + 0x78, 0x78, 0x78, 0x7a, 0x7a, 0x78, 0x7b, 0x7e, 0x7e, 0x82, 0x81, 0x7e, 0x82, 0x81, 0x83, 0x85, + 0x84, 0x80, 0x81, 0x88, 0x82, 0x85, 0x85, 0x84, 0x86, 0x85, 0x85, 0x86, 0x83, 0x82, 0x82, 0x82, + 0x82, 0x80, 0x81, 0x82, 0x7e, 0x83, 0x83, 0x81, 0x84, 0x85, 0x82, 0x7e, 0x7b, 0x7a, 0x79, 0x7e, + 0x80, 0x7e, 0x7d, 0x7d, 0x82, 0x81, 0x81, 0x7e, 0x7e, 0x81, 0x7c, 0x7d, 0x84, 0x84, 0x7e, 0x79, + 0x7e, 0x83, 0x80, 0x7c, 0x7a, 0x83, 0x82, 0x7b, 0x82, 0x81, 0x7b, 0x7c, 0x7e, 0x81, 0x81, 0x7c, + 0x80, 0x81, 0x7d, 0x7d, 0x7d, 0x83, 0x81, 0x80, 0x81, 0x7e, 0x82, 0x82, 0x80, 0x83, 0x87, 0x82, + 0x7e, 0x83, 0x88, 0x80, 0x7e, 0x81, 0x84, 0x84, 0x80, 0x84, 0x85, 0x81, 0x83, 0x82, 0x83, 0x88, + 0x87, 0x84, 0x89, 0x8c, 0x86, 0x83, 0x88, 0x89, 0x84, 0x81, 0x80, 0x84, 0x82, 0x7e, 0x7b, 0x7b, + 0x7a, 0x78, 0x76, 0x78, 0x77, 0x79, 0x77, 0x75, 0x78, 0x77, 0x76, 0x76, 0x74, 0x79, 0x77, 0x75, + 0x79, 0x78, 0x75, 0x79, 0x78, 0x76, 0x75, 0x77, 0x74, 0x73, 0x76, 0x77, 0x77, 0x75, 0x76, 0x77, + 0x7a, 0x7c, 0x78, 0x7c, 0x82, 0x82, 0x7c, 0x7d, 0x83, 0x85, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x83, + 0x84, 0x87, 0x85, 0x84, 0x85, 0x87, 0x88, 0x89, 0x88, 0x88, 0x8c, 0x8c, 0x88, 0x89, 0x8a, 0x88, + 0x8a, 0x89, 0x85, 0x84, 0x87, 0x86, 0x85, 0x88, 0x84, 0x82, 0x83, 0x82, 0x81, 0x83, 0x84, 0x86, + 0x80, 0x81, 0x88, 0x84, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7a, 0x79, 0x7b, 0x7c, 0x7d, 0x7b, + 0x7a, 0x7c, 0x79, 0x77, 0x77, 0x78, 0x75, 0x73, 0x78, 0x79, 0x7b, 0x7c, 0x7a, 0x7e, 0x7c, 0x7e, + 0x84, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7b, 0x78, 0x7a, 0x7c, 0x77, 0x78, 0x7d, 0x80, 0x78, 0x77, + 0x7c, 0x81, 0x81, 0x7e, 0x7c, 0x7a, 0x83, 0x7e, 0x7a, 0x7d, 0x7a, 0x7c, 0x7c, 0x7a, 0x82, 0x80, + 0x7c, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x82, 0x83, 0x80, 0x7d, 0x82, 0x7d, 0x7e, 0x86, 0x87, + 0x81, 0x81, 0x84, 0x81, 0x83, 0x86, 0x82, 0x84, 0x85, 0x7e, 0x84, 0x88, 0x86, 0x89, 0x84, 0x84, + 0x89, 0x87, 0x87, 0x87, 0x85, 0x83, 0x82, 0x83, 0x85, 0x85, 0x80, 0x83, 0x83, 0x80, 0x83, 0x84, + 0x7e, 0x7b, 0x7a, 0x7e, 0x7c, 0x7d, 0x7d, 0x7b, 0x7b, 0x7e, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x80, + 0x81, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7c, 0x7b, 0x79, 0x80, 0x80, 0x79, + 0x7a, 0x7b, 0x7b, 0x79, 0x73, 0x77, 0x7d, 0x79, 0x79, 0x7e, 0x80, 0x7b, 0x7e, 0x7d, 0x7e, 0x7e, + 0x7b, 0x7d, 0x77, 0x78, 0x7e, 0x78, 0x79, 0x79, 0x78, 0x7b, 0x79, 0x7c, 0x7d, 0x7a, 0x7a, 0x7a, + 0x7d, 0x7e, 0x7d, 0x80, 0x80, 0x7e, 0x80, 0x85, 0x81, 0x7c, 0x7e, 0x81, 0x80, 0x80, 0x80, 0x7e, + 0x81, 0x80, 0x80, 0x85, 0x86, 0x85, 0x83, 0x84, 0x8a, 0x85, 0x82, 0x83, 0x83, 0x82, 0x81, 0x80, + 0x81, 0x7e, 0x81, 0x84, 0x81, 0x83, 0x86, 0x84, 0x87, 0x8a, 0x88, 0x84, 0x85, 0x83, 0x86, 0x83, + 0x83, 0x84, 0x82, 0x82, 0x7d, 0x85, 0x88, 0x81, 0x82, 0x81, 0x81, 0x82, 0x7d, 0x7c, 0x7e, 0x7e, + 0x78, 0x78, 0x80, 0x7d, 0x7a, 0x7b, 0x80, 0x7c, 0x79, 0x7d, 0x83, 0x7e, 0x7b, 0x7d, 0x82, 0x81, + 0x7c, 0x7e, 0x7c, 0x7e, 0x80, 0x7e, 0x7e, 0x81, 0x82, 0x79, 0x7b, 0x7d, 0x7d, 0x7d, 0x7a, 0x7b, + 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x80, 0x83, 0x80, 0x7b, 0x81, 0x81, 0x7e, 0x81, 0x82, + 0x83, 0x81, 0x7e, 0x81, 0x88, 0x83, 0x7d, 0x81, 0x82, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x82, + 0x83, 0x81, 0x80, 0x7c, 0x7c, 0x7e, 0x7c, 0x77, 0x78, 0x7c, 0x7a, 0x79, 0x7d, 0x7c, 0x7b, 0x77, + 0x75, 0x7e, 0x7c, 0x7a, 0x7c, 0x7a, 0x7b, 0x7b, 0x78, 0x77, 0x78, 0x79, 0x7a, 0x76, 0x7d, 0x7d, + 0x7b, 0x7d, 0x7d, 0x81, 0x80, 0x7e, 0x82, 0x80, 0x80, 0x82, 0x85, 0x84, 0x85, 0x84, 0x81, 0x82, + 0x83, 0x84, 0x86, 0x85, 0x83, 0x83, 0x85, 0x87, 0x86, 0x83, 0x87, 0x89, 0x84, 0x82, 0x86, 0x87, + 0x82, 0x7c, 0x80, 0x85, 0x84, 0x80, 0x80, 0x82, 0x83, 0x84, 0x86, 0x86, 0x87, 0x8a, 0x87, 0x82, + 0x85, 0x86, 0x7e, 0x7d, 0x83, 0x82, 0x7c, 0x7c, 0x80, 0x7e, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x7c, + 0x7d, 0x7d, 0x79, 0x77, 0x77, 0x7a, 0x79, 0x75, 0x75, 0x77, 0x75, 0x72, 0x74, 0x77, 0x77, 0x76, + 0x77, 0x79, 0x78, 0x76, 0x78, 0x79, 0x77, 0x76, 0x78, 0x7a, 0x7b, 0x7c, 0x7a, 0x78, 0x7e, 0x7d, + 0x77, 0x79, 0x7c, 0x7a, 0x76, 0x7a, 0x7d, 0x82, 0x82, 0x7d, 0x81, 0x86, 0x88, 0x83, 0x82, 0x83, + 0x85, 0x84, 0x84, 0x87, 0x8a, 0x87, 0x87, 0x8e, 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8a, + 0x8b, 0x89, 0x88, 0x8a, 0x8a, 0x8a, 0x8c, 0x8d, 0x8b, 0x85, 0x85, 0x86, 0x85, 0x82, 0x81, 0x86, + 0x85, 0x7e, 0x7b, 0x81, 0x84, 0x7c, 0x7d, 0x7c, 0x7a, 0x80, 0x7a, 0x74, 0x77, 0x7b, 0x7d, 0x75, + 0x75, 0x79, 0x76, 0x72, 0x73, 0x76, 0x75, 0x78, 0x76, 0x74, 0x75, 0x78, 0x75, 0x70, 0x6f, 0x71, + 0x73, 0x72, 0x6f, 0x72, 0x76, 0x79, 0x7b, 0x78, 0x79, 0x7c, 0x7e, 0x7b, 0x76, 0x7a, 0x7d, 0x7a, + 0x78, 0x7a, 0x7e, 0x7b, 0x7b, 0x7a, 0x7b, 0x85, 0x83, 0x7d, 0x81, 0x83, 0x85, 0x85, 0x87, 0x8b, + 0x89, 0x89, 0x88, 0x88, 0x89, 0x8a, 0x8b, 0x86, 0x84, 0x86, 0x88, 0x85, 0x83, 0x86, 0x81, 0x81, + 0x86, 0x83, 0x81, 0x85, 0x86, 0x85, 0x80, 0x81, 0x82, 0x7e, 0x7e, 0x7b, 0x7d, 0x7e, 0x7c, 0x7c, + 0x83, 0x84, 0x81, 0x80, 0x80, 0x81, 0x81, 0x7d, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x81, 0x7b, 0x7d, + 0x7e, 0x7c, 0x81, 0x81, 0x80, 0x7a, 0x7d, 0x80, 0x7d, 0x7c, 0x7b, 0x7c, 0x78, 0x78, 0x7a, 0x7b, + 0x79, 0x7c, 0x7c, 0x7a, 0x7c, 0x7e, 0x7d, 0x7c, 0x7e, 0x7e, 0x81, 0x7e, 0x80, 0x81, 0x82, 0x84, + 0x83, 0x81, 0x85, 0x88, 0x85, 0x83, 0x84, 0x82, 0x83, 0x81, 0x82, 0x86, 0x85, 0x82, 0x84, 0x82, + 0x81, 0x82, 0x82, 0x80, 0x7e, 0x83, 0x80, 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7c, 0x7c, 0x80, 0x7e, 0x7c, 0x7c, 0x80, 0x7c, 0x7a, 0x7c, 0x80, 0x81, 0x7d, 0x7d, + 0x81, 0x7c, 0x7b, 0x7c, 0x78, 0x78, 0x79, 0x75, 0x76, 0x76, 0x74, 0x75, 0x77, 0x78, 0x78, 0x7a, + 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x77, 0x76, 0x77, 0x76, 0x7a, 0x7b, 0x7e, 0x81, 0x85, 0x83, 0x86, + 0x83, 0x84, 0x87, 0x85, 0x85, 0x85, 0x86, 0x84, 0x84, 0x82, 0x83, 0x85, 0x83, 0x83, 0x86, 0x86, + 0x83, 0x84, 0x84, 0x84, 0x84, 0x83, 0x81, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x84, 0x85, 0x85, + 0x88, 0x85, 0x81, 0x82, 0x83, 0x81, 0x7d, 0x83, 0x84, 0x81, 0x80, 0x7e, 0x80, 0x7d, 0x7b, 0x7d, + 0x7b, 0x79, 0x7b, 0x79, 0x7a, 0x79, 0x79, 0x78, 0x7b, 0x80, 0x7d, 0x79, 0x7c, 0x7b, 0x7a, 0x7c, + 0x7b, 0x7d, 0x7b, 0x7a, 0x79, 0x7a, 0x7d, 0x7b, 0x7b, 0x7b, 0x7e, 0x81, 0x7d, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7d, 0x7b, 0x7e, 0x81, 0x7d, 0x7e, 0x84, 0x83, 0x80, 0x7e, 0x82, 0x81, 0x7e, + 0x7d, 0x7e, 0x81, 0x82, 0x7d, 0x7a, 0x82, 0x85, 0x80, 0x7e, 0x83, 0x82, 0x82, 0x7e, 0x80, 0x80, + 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x83, 0x83, 0x85, 0x86, 0x83, 0x83, 0x84, 0x86, + 0x85, 0x83, 0x82, 0x82, 0x84, 0x82, 0x81, 0x81, 0x84, 0x83, 0x7e, 0x80, 0x80, 0x81, 0x83, 0x7c, + 0x7c, 0x82, 0x80, 0x80, 0x83, 0x81, 0x7e, 0x81, 0x83, 0x81, 0x7d, 0x7d, 0x84, 0x81, 0x7d, 0x82, + 0x82, 0x82, 0x81, 0x83, 0x83, 0x80, 0x80, 0x7c, 0x7a, 0x7d, 0x7b, 0x76, 0x76, 0x7b, 0x7c, 0x76, + 0x77, 0x79, 0x78, 0x7a, 0x79, 0x7a, 0x7b, 0x77, 0x75, 0x75, 0x79, 0x79, 0x75, 0x76, 0x79, 0x79, + 0x79, 0x77, 0x77, 0x7a, 0x7c, 0x7a, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7b, + 0x7e, 0x81, 0x7e, 0x7b, 0x7e, 0x82, 0x83, 0x84, 0x7e, 0x7e, 0x81, 0x82, 0x83, 0x82, 0x81, 0x80, + 0x81, 0x82, 0x81, 0x83, 0x83, 0x81, 0x7d, 0x81, 0x84, 0x82, 0x83, 0x86, 0x84, 0x84, 0x84, 0x83, + 0x86, 0x85, 0x84, 0x82, 0x85, 0x88, 0x86, 0x84, 0x87, 0x88, 0x87, 0x87, 0x88, 0x88, 0x88, 0x84, + 0x83, 0x86, 0x86, 0x80, 0x80, 0x81, 0x7e, 0x7c, 0x7b, 0x7e, 0x7a, 0x79, 0x7c, 0x79, 0x7c, 0x7d, + 0x7b, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x80, 0x80, 0x7e, 0x82, 0x7d, 0x7b, 0x80, 0x7d, 0x80, 0x80, + 0x7c, 0x7d, 0x81, 0x7e, 0x7a, 0x7b, 0x7d, 0x7b, 0x79, 0x7a, 0x7e, 0x7a, 0x76, 0x74, 0x79, 0x7e, + 0x7b, 0x78, 0x79, 0x7e, 0x7e, 0x7a, 0x7a, 0x7c, 0x7d, 0x7c, 0x7c, 0x7e, 0x7d, 0x80, 0x83, 0x84, + 0x80, 0x83, 0x84, 0x84, 0x81, 0x80, 0x82, 0x83, 0x83, 0x82, 0x81, 0x83, 0x82, 0x80, 0x80, 0x82, + 0x83, 0x80, 0x7d, 0x7d, 0x84, 0x88, 0x82, 0x80, 0x82, 0x80, 0x81, 0x82, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7d, 0x80, 0x7e, 0x77, 0x7a, 0x7e, 0x7d, 0x79, 0x79, 0x7b, 0x7b, 0x7b, 0x81, 0x7c, 0x79, + 0x7b, 0x7c, 0x7a, 0x7c, 0x80, 0x7c, 0x79, 0x79, 0x7b, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7b, 0x79, 0x7b, 0x7b, 0x7c, 0x81, 0x84, 0x85, 0x80, 0x7e, 0x84, 0x87, 0x88, 0x83, 0x82, 0x83, + 0x83, 0x83, 0x84, 0x84, 0x84, 0x86, 0x83, 0x85, 0x84, 0x84, 0x84, 0x85, 0x86, 0x87, 0x86, 0x84, + 0x83, 0x83, 0x83, 0x82, 0x83, 0x7e, 0x80, 0x81, 0x7c, 0x7c, 0x7c, 0x7b, 0x7d, 0x7c, 0x7b, 0x7b, + 0x7a, 0x7c, 0x79, 0x7b, 0x7e, 0x79, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x77, 0x76, 0x77, 0x78, + 0x76, 0x76, 0x7a, 0x7b, 0x7b, 0x80, 0x7d, 0x7b, 0x79, 0x7a, 0x7b, 0x7c, 0x79, 0x79, 0x7c, 0x7d, + 0x7d, 0x7e, 0x81, 0x80, 0x7c, 0x7e, 0x83, 0x82, 0x81, 0x81, 0x81, 0x84, 0x80, 0x81, 0x85, 0x85, + 0x84, 0x83, 0x85, 0x87, 0x86, 0x87, 0x89, 0x85, 0x8b, 0x8b, 0x85, 0x85, 0x85, 0x83, 0x80, 0x83, + 0x87, 0x84, 0x81, 0x84, 0x86, 0x84, 0x83, 0x85, 0x86, 0x81, 0x82, 0x86, 0x83, 0x83, 0x85, 0x86, + 0x86, 0x84, 0x83, 0x81, 0x7e, 0x7e, 0x80, 0x7b, 0x79, 0x7c, 0x79, 0x79, 0x7c, 0x7b, 0x7a, 0x79, + 0x7c, 0x7c, 0x7a, 0x78, 0x79, 0x78, 0x79, 0x7c, 0x7b, 0x78, 0x76, 0x77, 0x79, 0x77, 0x79, 0x78, + 0x74, 0x79, 0x79, 0x77, 0x77, 0x77, 0x76, 0x74, 0x77, 0x7a, 0x79, 0x76, 0x77, 0x7a, 0x79, 0x7a, + 0x7c, 0x7e, 0x7d, 0x7d, 0x80, 0x7d, 0x7c, 0x80, 0x80, 0x7c, 0x7e, 0x84, 0x86, 0x83, 0x83, 0x84, + 0x83, 0x85, 0x86, 0x84, 0x84, 0x84, 0x83, 0x83, 0x81, 0x84, 0x86, 0x83, 0x81, 0x83, 0x83, 0x80, + 0x7e, 0x81, 0x81, 0x81, 0x82, 0x83, 0x84, 0x82, 0x80, 0x81, 0x82, 0x83, 0x8a, 0x87, 0x80, 0x81, + 0x85, 0x88, 0x82, 0x82, 0x82, 0x7e, 0x81, 0x80, 0x82, 0x83, 0x82, 0x7e, 0x7e, 0x80, 0x81, 0x7d, + 0x7b, 0x7c, 0x7d, 0x7e, 0x7b, 0x78, 0x7a, 0x7d, 0x7e, 0x80, 0x7d, 0x80, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x82, 0x84, 0x7b, 0x79, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7d, 0x82, 0x81, 0x80, 0x80, 0x81, 0x82, 0x7e, 0x80, 0x80, 0x81, 0x83, 0x82, 0x82, + 0x82, 0x81, 0x7d, 0x7e, 0x7c, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x7d, 0x7e, 0x7e, 0x7b, 0x7a, 0x81, + 0x80, 0x7c, 0x7a, 0x7d, 0x80, 0x7e, 0x7d, 0x80, 0x82, 0x81, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, + 0x7c, 0x80, 0x7d, 0x78, 0x7a, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x79, 0x78, 0x7d, 0x7c, 0x7b, 0x7c, + 0x7b, 0x7c, 0x7c, 0x7c, 0x80, 0x7e, 0x7d, 0x80, 0x82, 0x81, 0x83, 0x83, 0x80, 0x82, 0x83, 0x82, + 0x80, 0x83, 0x85, 0x83, 0x81, 0x86, 0x85, 0x83, 0x82, 0x7e, 0x7e, 0x80, 0x7e, 0x81, 0x7e, 0x7c, + 0x80, 0x80, 0x83, 0x83, 0x82, 0x81, 0x81, 0x83, 0x84, 0x83, 0x81, 0x83, 0x83, 0x83, 0x85, 0x82, + 0x7e, 0x7e, 0x80, 0x7e, 0x82, 0x81, 0x7c, 0x7e, 0x81, 0x7d, 0x80, 0x82, 0x82, 0x80, 0x81, 0x80, + 0x7d, 0x7c, 0x7b, 0x7e, 0x7e, 0x7e, 0x7e, 0x7b, 0x80, 0x7e, 0x7a, 0x7b, 0x7c, 0x7d, 0x7d, 0x7b, + 0x7c, 0x7c, 0x7a, 0x7e, 0x7d, 0x7c, 0x7d, 0x79, 0x7b, 0x80, 0x7e, 0x7c, 0x7d, 0x7c, 0x80, 0x7d, + 0x7b, 0x7d, 0x80, 0x7c, 0x7e, 0x83, 0x80, 0x81, 0x82, 0x82, 0x84, 0x84, 0x82, 0x82, 0x82, 0x81, + 0x84, 0x82, 0x7e, 0x80, 0x80, 0x82, 0x80, 0x7c, 0x7a, 0x7b, 0x7d, 0x80, 0x7d, 0x7d, 0x82, 0x82, + 0x7d, 0x80, 0x81, 0x81, 0x81, 0x80, 0x84, 0x85, 0x83, 0x84, 0x84, 0x82, 0x87, 0x89, 0x83, 0x82, + 0x86, 0x84, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x7e, 0x80, 0x84, + 0x83, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7d, 0x81, 0x83, 0x80, 0x7d, 0x81, 0x83, 0x80, 0x80, 0x7d, + 0x80, 0x81, 0x7e, 0x80, 0x81, 0x7d, 0x7b, 0x7e, 0x7d, 0x7c, 0x7a, 0x7a, 0x78, 0x7a, 0x7b, 0x78, + 0x75, 0x72, 0x74, 0x75, 0x77, 0x7a, 0x7a, 0x78, 0x79, 0x7d, 0x7d, 0x7a, 0x7a, 0x7c, 0x7b, 0x7b, + 0x7a, 0x7a, 0x78, 0x77, 0x79, 0x78, 0x7a, 0x7a, 0x77, 0x7b, 0x7b, 0x78, 0x7b, 0x7c, 0x7a, 0x7a, + 0x7b, 0x7d, 0x7d, 0x7b, 0x7c, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84, 0x81, 0x83, 0x85, 0x84, + 0x84, 0x82, 0x83, 0x86, 0x87, 0x84, 0x83, 0x87, 0x88, 0x88, 0x89, 0x8a, 0x88, 0x88, 0x89, 0x86, + 0x85, 0x88, 0x84, 0x83, 0x89, 0x89, 0x88, 0x86, 0x84, 0x86, 0x85, 0x83, 0x82, 0x83, 0x80, 0x80, + 0x82, 0x82, 0x82, 0x83, 0x82, 0x7e, 0x82, 0x83, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7b, + 0x7c, 0x7d, 0x7d, 0x7a, 0x7b, 0x81, 0x80, 0x7a, 0x7b, 0x7c, 0x7a, 0x7b, 0x7a, 0x78, 0x7b, 0x7b, + 0x78, 0x7b, 0x7b, 0x79, 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x7a, 0x7b, 0x7b, 0x7a, 0x7c, 0x7c, 0x78, + 0x79, 0x7b, 0x7c, 0x80, 0x80, 0x7c, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x83, 0x83, 0x80, 0x82, 0x82, 0x81, 0x84, 0x85, 0x81, 0x83, 0x81, 0x81, 0x84, + 0x84, 0x82, 0x84, 0x85, 0x84, 0x83, 0x83, 0x83, 0x83, 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x7d, + 0x7d, 0x7e, 0x7c, 0x7a, 0x7c, 0x81, 0x7e, 0x7b, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x78, 0x78, 0x7a, 0x7a, 0x79, 0x79, 0x7c, 0x7e, + 0x7c, 0x7d, 0x7e, 0x7b, 0x7a, 0x7d, 0x82, 0x7d, 0x7e, 0x82, 0x82, 0x80, 0x7e, 0x83, 0x83, 0x84, + 0x87, 0x88, 0x85, 0x82, 0x83, 0x83, 0x83, 0x81, 0x81, 0x82, 0x82, 0x81, 0x83, 0x82, 0x84, 0x84, + 0x82, 0x82, 0x84, 0x83, 0x7d, 0x80, 0x82, 0x81, 0x82, 0x80, 0x7d, 0x81, 0x81, 0x82, 0x82, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7b, 0x7b, 0x7b, 0x79, + 0x7b, 0x7b, 0x79, 0x7a, 0x79, 0x7a, 0x7e, 0x7c, 0x7b, 0x7d, 0x7d, 0x7a, 0x7b, 0x7d, 0x7b, 0x7b, + 0x79, 0x7a, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x82, 0x85, 0x84, 0x83, 0x82, 0x84, 0x85, 0x85, + 0x84, 0x85, 0x86, 0x85, 0x84, 0x88, 0x86, 0x86, 0x87, 0x87, 0x88, 0x8b, 0x8b, 0x86, 0x85, 0x87, + 0x84, 0x84, 0x86, 0x81, 0x82, 0x81, 0x81, 0x81, 0x7e, 0x80, 0x82, 0x82, 0x7e, 0x83, 0x83, 0x81, + 0x82, 0x81, 0x80, 0x81, 0x83, 0x80, 0x7c, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7a, 0x79, 0x78, 0x7b, + 0x7b, 0x79, 0x78, 0x7a, 0x76, 0x78, 0x7a, 0x76, 0x76, 0x76, 0x76, 0x75, 0x77, 0x79, 0x78, 0x77, + 0x7a, 0x7a, 0x79, 0x7a, 0x7c, 0x7b, 0x79, 0x7d, 0x80, 0x7c, 0x79, 0x7e, 0x80, 0x7b, 0x7c, 0x7c, + 0x7d, 0x7d, 0x7b, 0x7d, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7e, 0x7e, 0x7c, 0x7c, 0x7e, 0x80, 0x80, + 0x80, 0x81, 0x83, 0x82, 0x81, 0x83, 0x84, 0x85, 0x84, 0x82, 0x82, 0x85, 0x86, 0x85, 0x87, 0x84, + 0x83, 0x85, 0x85, 0x7e, 0x7e, 0x83, 0x83, 0x83, 0x82, 0x83, 0x86, 0x85, 0x84, 0x85, 0x85, 0x85, + 0x82, 0x82, 0x84, 0x83, 0x84, 0x82, 0x82, 0x84, 0x84, 0x83, 0x82, 0x80, 0x81, 0x85, 0x82, 0x80, + 0x81, 0x82, 0x82, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7b, 0x7d, 0x82, + 0x7e, 0x7b, 0x7e, 0x81, 0x80, 0x7d, 0x7b, 0x7d, 0x7c, 0x7e, 0x7e, 0x7b, 0x7b, 0x7b, 0x7d, 0x7b, + 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, 0x7b, 0x7d, 0x7c, 0x7b, 0x7e, 0x7d, + 0x80, 0x81, 0x80, 0x82, 0x81, 0x7b, 0x7e, 0x81, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 0x7b, 0x7e, 0x7e, + 0x7d, 0x7b, 0x7c, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, + 0x7e, 0x80, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x81, 0x80, 0x7d, + 0x81, 0x80, 0x7e, 0x81, 0x82, 0x80, 0x82, 0x84, 0x82, 0x84, 0x84, 0x82, 0x83, 0x82, 0x80, 0x82, + 0x83, 0x81, 0x7e, 0x7d, 0x7e, 0x82, 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x82, 0x81, 0x7d, + 0x7c, 0x7d, 0x80, 0x82, 0x81, 0x7d, 0x7e, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x81, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x81, 0x7c, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7b, 0x7c, 0x80, 0x7e, 0x7e, 0x81, 0x82, 0x81, 0x83, 0x84, 0x82, + 0x80, 0x82, 0x83, 0x83, 0x83, 0x81, 0x80, 0x83, 0x82, 0x82, 0x81, 0x7d, 0x80, 0x81, 0x7e, 0x7e, + 0x7d, 0x7e, 0x7e, 0x81, 0x82, 0x82, 0x85, 0x81, 0x7e, 0x82, 0x83, 0x82, 0x80, 0x82, 0x83, 0x81, + 0x82, 0x81, 0x81, 0x83, 0x80, 0x81, 0x83, 0x80, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x80, 0x82, + 0x7e, 0x80, 0x82, 0x81, 0x7e, 0x81, 0x83, 0x84, 0x82, 0x82, 0x84, 0x83, 0x7e, 0x7d, 0x81, 0x81, + 0x80, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7c, 0x7c, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, + 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x82, 0x83, 0x80, 0x7e, 0x81, 0x83, 0x81, 0x7d, 0x80, + 0x7d, 0x7c, 0x7c, 0x7b, 0x7d, 0x7c, 0x79, 0x78, 0x78, 0x78, 0x79, 0x78, 0x7a, 0x7a, 0x79, 0x7a, + 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x79, 0x7b, 0x7e, 0x7b, 0x79, + 0x7b, 0x7c, 0x7d, 0x7b, 0x78, 0x7b, 0x7c, 0x78, 0x78, 0x7a, 0x78, 0x78, 0x7a, 0x7c, 0x7b, 0x7b, + 0x7c, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x84, 0x83, 0x85, 0x88, 0x86, 0x86, 0x88, 0x89, + 0x84, 0x84, 0x88, 0x87, 0x85, 0x85, 0x85, 0x84, 0x84, 0x85, 0x85, 0x85, 0x84, 0x83, 0x85, 0x87, + 0x87, 0x84, 0x84, 0x87, 0x88, 0x88, 0x86, 0x87, 0x88, 0x87, 0x85, 0x87, 0x87, 0x85, 0x83, 0x82, + 0x83, 0x86, 0x84, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x83, 0x81, 0x7d, 0x80, 0x80, 0x7c, 0x7d, + 0x7e, 0x7a, 0x79, 0x7b, 0x7d, 0x7c, 0x7a, 0x78, 0x78, 0x79, 0x7b, 0x78, 0x75, 0x75, 0x77, 0x78, + 0x76, 0x78, 0x79, 0x76, 0x76, 0x77, 0x7a, 0x7b, 0x78, 0x78, 0x7b, 0x7d, 0x7e, 0x80, 0x7d, 0x7b, + 0x7c, 0x7b, 0x7c, 0x7e, 0x7a, 0x7b, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x80, 0x7e, + 0x80, 0x81, 0x7d, 0x80, 0x82, 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x81, 0x81, 0x81, 0x82, 0x84, + 0x85, 0x84, 0x86, 0x88, 0x86, 0x82, 0x83, 0x85, 0x84, 0x82, 0x7d, 0x7d, 0x82, 0x81, 0x7c, 0x7c, + 0x80, 0x82, 0x80, 0x80, 0x80, 0x82, 0x80, 0x7d, 0x81, 0x82, 0x80, 0x80, 0x7d, 0x7c, 0x80, 0x80, + 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x7e, 0x7c, 0x79, 0x7b, 0x7c, 0x7d, 0x7a, + 0x7d, 0x80, 0x7d, 0x7c, 0x7c, 0x7e, 0x7d, 0x7b, 0x7c, 0x7d, 0x81, 0x7e, 0x7b, 0x7d, 0x7e, 0x80, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x81, 0x82, 0x83, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x80, 0x81, 0x82, + 0x82, 0x82, 0x81, 0x82, 0x84, 0x81, 0x80, 0x81, 0x81, 0x7e, 0x7d, 0x81, 0x80, 0x7e, 0x81, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7e, 0x7e, 0x7d, 0x80, 0x7d, 0x7c, 0x7c, + 0x7d, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x7e, 0x80, 0x83, 0x82, 0x82, 0x84, 0x82, + 0x81, 0x82, 0x83, 0x84, 0x82, 0x82, 0x83, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x84, 0x84, + 0x82, 0x81, 0x81, 0x85, 0x83, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x81, 0x81, 0x82, 0x80, 0x7c, 0x7d, + 0x7e, 0x7b, 0x7b, 0x7c, 0x7a, 0x7b, 0x7a, 0x7c, 0x7b, 0x78, 0x7a, 0x7b, 0x79, 0x7a, 0x79, 0x78, + 0x79, 0x78, 0x79, 0x78, 0x78, 0x77, 0x76, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x7a, 0x78, 0x7a, + 0x7b, 0x7b, 0x7b, 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x80, 0x7e, 0x81, 0x82, 0x7d, 0x80, + 0x82, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x82, 0x82, 0x7e, 0x81, 0x83, 0x82, 0x82, + 0x82, 0x83, 0x85, 0x81, 0x82, 0x83, 0x85, 0x85, 0x82, 0x84, 0x85, 0x84, 0x86, 0x83, 0x83, 0x87, + 0x83, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x84, 0x84, 0x85, 0x86, 0x81, 0x81, 0x85, 0x83, 0x7e, + 0x80, 0x82, 0x81, 0x81, 0x82, 0x83, 0x82, 0x83, 0x85, 0x83, 0x82, 0x84, 0x86, 0x82, 0x81, 0x82, + 0x83, 0x83, 0x83, 0x81, 0x80, 0x80, 0x82, 0x81, 0x7c, 0x7e, 0x81, 0x7d, 0x7c, 0x7e, 0x7e, 0x7a, + 0x79, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7a, 0x7d, 0x7d, 0x78, 0x7a, 0x7c, 0x7a, + 0x79, 0x78, 0x7b, 0x7e, 0x7d, 0x7d, 0x7e, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x79, 0x7a, 0x7b, + 0x7a, 0x79, 0x7b, 0x7c, 0x7d, 0x7c, 0x7d, 0x80, 0x7c, 0x7a, 0x7a, 0x7d, 0x7d, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7d, 0x80, 0x7e, 0x7e, 0x7e, 0x7c, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x7d, 0x80, + 0x82, 0x7e, 0x7c, 0x81, 0x83, 0x80, 0x7d, 0x81, 0x81, 0x82, 0x84, 0x81, 0x7e, 0x81, 0x80, 0x80, + 0x80, 0x81, 0x83, 0x81, 0x83, 0x83, 0x82, 0x83, 0x81, 0x80, 0x80, 0x82, 0x84, 0x82, 0x81, 0x82, + 0x82, 0x85, 0x83, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x7e, 0x7d, 0x80, 0x83, 0x81, + 0x7c, 0x7c, 0x80, 0x80, 0x7d, 0x7b, 0x7e, 0x80, 0x7e, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7d, + 0x7e, 0x7e, 0x7a, 0x7b, 0x7e, 0x7d, 0x7a, 0x7b, 0x7d, 0x7c, 0x7a, 0x78, 0x79, 0x7b, 0x7b, 0x7c, + 0x7c, 0x7d, 0x7c, 0x7d, 0x7b, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x83, 0x84, 0x84, 0x83, 0x82, + 0x84, 0x85, 0x82, 0x81, 0x83, 0x85, 0x84, 0x81, 0x83, 0x84, 0x81, 0x7e, 0x82, 0x85, 0x83, 0x82, + 0x83, 0x83, 0x86, 0x86, 0x83, 0x83, 0x84, 0x82, 0x7e, 0x82, 0x82, 0x81, 0x7e, 0x81, 0x83, 0x83, + 0x81, 0x7e, 0x7d, 0x80, 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x7d, 0x7e, 0x81, 0x80, + 0x7d, 0x80, 0x7d, 0x7d, 0x7d, 0x7b, 0x7d, 0x80, 0x7c, 0x7b, 0x7c, 0x7e, 0x7c, 0x7a, 0x7c, 0x80, + 0x7e, 0x79, 0x7b, 0x80, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7d, 0x7b, 0x7d, + 0x81, 0x80, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7c, 0x7d, 0x80, 0x7b, 0x79, 0x79, + 0x7a, 0x7a, 0x79, 0x79, 0x7b, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7e, 0x7e, 0x7b, + 0x7c, 0x7e, 0x7e, 0x7d, 0x7e, 0x82, 0x82, 0x7e, 0x7d, 0x7d, 0x80, 0x7d, 0x7a, 0x7c, 0x7c, 0x79, + 0x7b, 0x7c, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 0x81, + 0x7e, 0x81, 0x81, 0x82, 0x81, 0x80, 0x84, 0x83, 0x83, 0x84, 0x85, 0x86, 0x85, 0x86, 0x85, 0x85, + 0x87, 0x88, 0x88, 0x8a, 0x8b, 0x88, 0x86, 0x87, 0x89, 0x85, 0x84, 0x86, 0x84, 0x82, 0x83, 0x84, + 0x84, 0x83, 0x84, 0x85, 0x85, 0x85, 0x84, 0x83, 0x85, 0x87, 0x84, 0x84, 0x85, 0x85, 0x85, 0x83, + 0x80, 0x81, 0x81, 0x7e, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7e, 0x7e, 0x7e, 0x7c, 0x7b, 0x7b, 0x7a, + 0x7b, 0x7b, 0x79, 0x79, 0x7a, 0x79, 0x79, 0x7b, 0x77, 0x75, 0x77, 0x74, 0x73, 0x76, 0x76, 0x78, + 0x76, 0x75, 0x79, 0x79, 0x77, 0x77, 0x7a, 0x7a, 0x79, 0x7b, 0x7d, 0x7c, 0x7a, 0x7c, 0x7c, 0x7b, + 0x7e, 0x7d, 0x7a, 0x7a, 0x7d, 0x7e, 0x7b, 0x7c, 0x7e, 0x7a, 0x7a, 0x7e, 0x81, 0x7d, 0x7d, 0x81, + 0x82, 0x83, 0x83, 0x83, 0x83, 0x85, 0x84, 0x83, 0x83, 0x84, 0x81, 0x82, 0x86, 0x87, 0x82, 0x83, + 0x83, 0x83, 0x84, 0x83, 0x83, 0x83, 0x81, 0x82, 0x83, 0x82, 0x81, 0x82, 0x83, 0x82, 0x83, 0x86, + 0x83, 0x81, 0x82, 0x81, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7e, 0x7c, 0x7e, 0x80, 0x80, 0x7d, + 0x7d, 0x82, 0x82, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x79, 0x7a, 0x7c, + 0x7b, 0x7a, 0x7a, 0x7d, 0x80, 0x7b, 0x7a, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x7e, 0x7e, 0x81, 0x7e, 0x7b, 0x7d, 0x7c, 0x7c, 0x7e, 0x82, 0x82, 0x82, 0x83, 0x82, 0x83, + 0x83, 0x83, 0x81, 0x7d, 0x80, 0x82, 0x81, 0x80, 0x82, 0x84, 0x82, 0x80, 0x82, 0x84, 0x84, 0x81, + 0x82, 0x83, 0x83, 0x80, 0x80, 0x82, 0x83, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x83, 0x85, 0x84, + 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7c, 0x80, + 0x80, 0x7c, 0x7d, 0x80, 0x7d, 0x7d, 0x82, 0x83, 0x7d, 0x7d, 0x81, 0x83, 0x7e, 0x7e, 0x81, 0x7e, + 0x7c, 0x7c, 0x7e, 0x7d, 0x7d, 0x7e, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83, 0x80, 0x7e, + 0x80, 0x80, 0x7c, 0x7c, 0x82, 0x81, 0x7e, 0x81, 0x81, 0x7e, 0x7e, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, + 0x79, 0x7a, 0x7a, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x79, 0x79, 0x7d, 0x7d, 0x7a, 0x78, + 0x79, 0x7a, 0x78, 0x77, 0x79, 0x79, 0x7b, 0x79, 0x7a, 0x7c, 0x7d, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x81, 0x82, 0x81, 0x80, 0x82, 0x82, 0x84, 0x85, 0x83, 0x84, 0x86, 0x85, 0x85, 0x86, + 0x86, 0x84, 0x85, 0x85, 0x85, 0x85, 0x82, 0x84, 0x86, 0x82, 0x84, 0x84, 0x81, 0x82, 0x84, 0x81, + 0x83, 0x85, 0x83, 0x82, 0x83, 0x84, 0x83, 0x81, 0x7e, 0x7e, 0x81, 0x7c, 0x7d, 0x82, 0x7d, 0x7e, + 0x83, 0x83, 0x80, 0x81, 0x82, 0x82, 0x81, 0x84, 0x83, 0x83, 0x84, 0x83, 0x82, 0x81, 0x84, 0x82, + 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x80, 0x80, 0x7d, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7c, 0x78, 0x79, 0x7a, 0x7a, 0x7a, 0x78, 0x79, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x7a, + 0x78, 0x7a, 0x7b, 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7c, 0x7b, 0x7b, 0x7c, 0x7b, 0x7d, 0x7b, 0x7a, 0x7c, 0x7a, 0x7b, 0x80, 0x7e, 0x7d, 0x7e, + 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x7e, + 0x80, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x81, 0x84, 0x85, 0x85, + 0x85, 0x83, 0x83, 0x86, 0x85, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x83, 0x84, 0x83, 0x83, 0x83, + 0x85, 0x84, 0x83, 0x82, 0x81, 0x82, 0x80, 0x80, 0x82, 0x7e, 0x7d, 0x80, 0x7c, 0x7c, 0x7c, 0x7b, + 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x7d, 0x7c, 0x7e, 0x7b, 0x7a, 0x7d, 0x7c, 0x7b, 0x7a, + 0x7b, 0x7c, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x78, 0x7a, 0x7d, 0x7d, 0x7b, 0x7b, 0x7c, 0x7b, 0x7c, + 0x7d, 0x7d, 0x80, 0x7c, 0x7d, 0x81, 0x82, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x80, 0x81, + 0x83, 0x83, 0x83, 0x85, 0x84, 0x81, 0x84, 0x85, 0x84, 0x83, 0x85, 0x86, 0x85, 0x84, 0x86, 0x86, + 0x84, 0x83, 0x84, 0x86, 0x83, 0x82, 0x84, 0x84, 0x80, 0x81, 0x82, 0x82, 0x80, 0x7e, 0x82, 0x83, + 0x80, 0x80, 0x81, 0x82, 0x80, 0x80, 0x81, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x81, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, 0x7d, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7a, + 0x79, 0x79, 0x79, 0x7a, 0x7a, 0x7b, 0x7a, 0x79, 0x79, 0x7a, 0x78, 0x78, 0x7a, 0x7a, 0x7a, 0x7c, + 0x7e, 0x7d, 0x7e, 0x81, 0x80, 0x7e, 0x80, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x80, 0x80, 0x7d, + 0x7c, 0x7e, 0x80, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x7e, 0x7c, 0x80, 0x82, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x7e, 0x80, 0x80, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x83, 0x84, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, + 0x83, 0x85, 0x85, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x84, 0x84, 0x84, 0x82, 0x83, 0x85, 0x85, + 0x83, 0x83, 0x83, 0x84, 0x83, 0x82, 0x84, 0x83, 0x82, 0x82, 0x83, 0x83, 0x80, 0x81, 0x81, 0x7d, + 0x7e, 0x80, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7a, 0x7b, 0x7d, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, + 0x7b, 0x7a, 0x79, 0x7a, 0x7a, 0x77, 0x77, 0x79, 0x7a, 0x78, 0x78, 0x79, 0x78, 0x78, 0x76, 0x77, + 0x77, 0x78, 0x79, 0x79, 0x7a, 0x7c, 0x7b, 0x7d, 0x80, 0x7e, 0x7c, 0x7e, 0x7c, 0x79, 0x7b, 0x7e, + 0x7d, 0x7b, 0x7d, 0x7e, 0x7d, 0x7a, 0x7a, 0x7e, 0x7e, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x81, + 0x81, 0x83, 0x83, 0x82, 0x85, 0x85, 0x84, 0x84, 0x84, 0x85, 0x86, 0x84, 0x84, 0x84, 0x82, 0x83, + 0x82, 0x80, 0x82, 0x84, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x82, 0x82, 0x81, 0x81, 0x82, 0x80, 0x7d, 0x80, 0x81, 0x80, 0x80, 0x82, 0x81, 0x81, 0x81, + 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7b, 0x7d, + 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x80, 0x80, + 0x7d, 0x7c, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7b, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x83, 0x82, 0x82, 0x84, + 0x84, 0x83, 0x85, 0x83, 0x82, 0x82, 0x81, 0x83, 0x82, 0x84, 0x82, 0x81, 0x83, 0x82, 0x80, 0x81, + 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x7d, 0x7b, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x81, + 0x81, 0x7e, 0x7e, 0x81, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x81, 0x81, 0x7e, 0x80, 0x81, 0x7e, 0x7e, + 0x81, 0x81, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, + 0x7b, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7a, 0x7b, 0x7d, 0x7e, 0x7d, + 0x7c, 0x7e, 0x7e, 0x7c, 0x7c, 0x7a, 0x7a, 0x7c, 0x7b, 0x7b, 0x7e, 0x7e, 0x7b, 0x7a, 0x7a, 0x7b, + 0x7b, 0x7a, 0x78, 0x7a, 0x7c, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7c, + 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84, + 0x85, 0x84, 0x84, 0x83, 0x84, 0x87, 0x85, 0x84, 0x86, 0x87, 0x86, 0x85, 0x85, 0x86, 0x84, 0x82, + 0x83, 0x83, 0x83, 0x83, 0x85, 0x85, 0x85, 0x85, 0x83, 0x82, 0x82, 0x83, 0x80, 0x80, 0x82, 0x80, + 0x7d, 0x81, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x82, 0x80, + 0x80, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x81, 0x81, 0x7d, 0x80, 0x82, 0x7d, 0x7c, 0x7e, 0x7d, + 0x7b, 0x7d, 0x7e, 0x7c, 0x7b, 0x7d, 0x7d, 0x7d, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x7b, 0x7a, 0x7d, + 0x7e, 0x7b, 0x79, 0x7c, 0x7e, 0x7c, 0x7a, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7b, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x7e, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7b, 0x7b, 0x79, 0x7b, + 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x81, 0x80, 0x82, 0x80, 0x7e, 0x81, 0x81, 0x80, 0x80, 0x81, + 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x83, 0x84, 0x83, 0x82, 0x83, 0x84, 0x86, 0x86, 0x84, + 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x80, 0x82, 0x81, 0x80, 0x82, 0x82, 0x80, 0x80, 0x81, 0x82, + 0x82, 0x7e, 0x7e, 0x81, 0x80, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, + 0x7e, 0x80, 0x80, 0x7e, 0x7c, 0x7d, 0x7e, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x7e, 0x7e, + 0x7c, 0x7b, 0x7a, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x7d, 0x7b, + 0x7b, 0x7e, 0x7e, 0x7c, 0x7e, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x83, 0x84, + 0x83, 0x80, 0x80, 0x82, 0x82, 0x80, 0x81, 0x84, 0x83, 0x82, 0x83, 0x83, 0x82, 0x84, 0x84, 0x83, + 0x83, 0x84, 0x84, 0x81, 0x80, 0x81, 0x83, 0x83, 0x81, 0x81, 0x82, 0x82, 0x83, 0x82, 0x80, 0x82, + 0x83, 0x81, 0x7e, 0x81, 0x82, 0x81, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x7c, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, + 0x79, 0x79, 0x79, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x80, 0x7e, 0x80, 0x7e, 0x7d, + 0x7c, 0x7c, 0x7e, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7e, + 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7d, 0x7e, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x83, 0x81, 0x81, 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x83, 0x83, 0x83, 0x82, 0x82, + 0x84, 0x84, 0x82, 0x83, 0x84, 0x83, 0x82, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x83, 0x81, + 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x83, 0x82, 0x7e, 0x81, 0x80, 0x80, 0x82, 0x83, 0x83, 0x82, + 0x82, 0x83, 0x84, 0x82, 0x83, 0x82, 0x81, 0x81, 0x81, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, + 0x7d, 0x7b, 0x7b, 0x7c, 0x7d, 0x7b, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, + 0x7a, 0x79, 0x78, 0x7a, 0x79, 0x78, 0x7a, 0x7a, 0x78, 0x78, 0x79, 0x7a, 0x7b, 0x7a, 0x7a, 0x7a, + 0x7b, 0x7c, 0x7b, 0x7a, 0x7d, 0x7d, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x80, 0x80, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x82, 0x83, 0x82, 0x81, + 0x82, 0x83, 0x82, 0x82, 0x83, 0x84, 0x84, 0x82, 0x84, 0x85, 0x84, 0x84, 0x86, 0x84, 0x84, 0x86, + 0x84, 0x83, 0x85, 0x83, 0x82, 0x83, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, + 0x81, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7e, 0x80, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x82, 0x81, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x80, + 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x82, 0x80, 0x80, 0x82, 0x83, 0x82, 0x81, 0x80, 0x81, + 0x81, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7d, 0x80, 0x80, 0x7d, 0x7e, + 0x80, 0x7e, 0x7e, 0x80, 0x82, 0x82, 0x81, 0x82, 0x83, 0x81, 0x81, 0x82, 0x83, 0x82, 0x82, 0x81, + 0x81, 0x81, 0x7e, 0x7e, 0x81, 0x82, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x81, 0x80, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7d, 0x7e, 0x80, 0x80, 0x7d, 0x7e, 0x80, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7b, 0x7b, 0x7d, + 0x7c, 0x7a, 0x7b, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x81, 0x82, 0x81, 0x82, 0x84, 0x84, 0x84, 0x82, 0x81, 0x82, 0x82, 0x82, 0x83, 0x82, 0x83, + 0x85, 0x85, 0x84, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x81, 0x83, 0x85, 0x85, 0x84, + 0x84, 0x85, 0x85, 0x84, 0x82, 0x82, 0x84, 0x83, 0x81, 0x80, 0x83, 0x81, 0x80, 0x81, 0x81, 0x82, + 0x82, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7c, 0x7e, 0x80, 0x7d, 0x7e, 0x81, 0x80, 0x7c, 0x7c, + 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, + 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x79, 0x79, 0x7c, 0x7c, 0x7b, 0x7c, 0x7e, 0x7d, 0x7c, 0x7d, + 0x7e, 0x7d, 0x7c, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x7d, 0x7c, 0x80, 0x7e, 0x7c, 0x7e, 0x80, 0x7c, + 0x7b, 0x7d, 0x7d, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x82, 0x81, 0x80, 0x81, 0x80, 0x80, 0x7e, + 0x7e, 0x80, 0x81, 0x81, 0x7d, 0x7e, 0x81, 0x81, 0x81, 0x80, 0x81, 0x82, 0x82, 0x80, 0x80, 0x83, + 0x83, 0x82, 0x82, 0x84, 0x86, 0x85, 0x83, 0x84, 0x86, 0x85, 0x84, 0x84, 0x84, 0x85, 0x83, 0x82, + 0x83, 0x84, 0x83, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x80, 0x81, 0x82, 0x80, 0x7e, 0x80, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7c, 0x7d, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, + 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x82, 0x81, 0x81, 0x82, + 0x82, 0x82, 0x83, 0x82, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x82, 0x81, 0x80, 0x82, 0x81, + 0x81, 0x83, 0x83, 0x81, 0x82, 0x83, 0x82, 0x82, 0x82, 0x84, 0x83, 0x82, 0x84, 0x85, 0x83, 0x81, + 0x80, 0x82, 0x80, 0x80, 0x83, 0x81, 0x81, 0x80, 0x7d, 0x80, 0x81, 0x7e, 0x7c, 0x7d, 0x7d, 0x7c, + 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, + 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, + 0x7c, 0x7a, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x81, 0x80, 0x7e, 0x81, + 0x83, 0x81, 0x81, 0x83, 0x83, 0x83, 0x81, 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x82, 0x82, 0x80, 0x81, 0x84, 0x83, 0x81, 0x82, 0x83, 0x83, 0x80, 0x81, 0x83, 0x82, 0x81, + 0x81, 0x82, 0x83, 0x83, 0x82, 0x82, 0x82, 0x83, 0x82, 0x81, 0x82, 0x80, 0x80, 0x82, 0x82, 0x83, + 0x83, 0x81, 0x80, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, + 0x81, 0x81, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x7a, + 0x7b, 0x7a, 0x7a, 0x7b, 0x7c, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, 0x79, 0x79, + 0x7a, 0x7b, 0x7b, 0x79, 0x7b, 0x7d, 0x7b, 0x7a, 0x7c, 0x7c, 0x7b, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x81, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, + 0x7e, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x82, 0x83, + 0x84, 0x83, 0x82, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x81, + 0x82, 0x83, 0x84, 0x84, 0x82, 0x82, 0x82, 0x81, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, + 0x82, 0x81, 0x81, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x81, + 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x81, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x7d, 0x7e, 0x7e, 0x7c, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, + 0x80, 0x80, 0x81, 0x80, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7c, + 0x7d, 0x7d, 0x7c, 0x7d, 0x80, 0x7e, 0x7c, 0x7d, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7a, + 0x7a, 0x7a, 0x7a, 0x7b, 0x7a, 0x79, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x80, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x82, 0x81, 0x80, 0x81, 0x83, 0x84, 0x83, 0x81, 0x82, 0x82, 0x82, 0x84, 0x84, 0x83, + 0x83, 0x84, 0x83, 0x84, 0x85, 0x85, 0x84, 0x84, 0x85, 0x84, 0x84, 0x85, 0x84, 0x83, 0x84, 0x85, + 0x85, 0x84, 0x84, 0x85, 0x85, 0x82, 0x80, 0x82, 0x82, 0x80, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x7e, 0x7c, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x79, 0x7c, 0x7c, 0x7c, 0x7b, + 0x7b, 0x7c, 0x7b, 0x7a, 0x7b, 0x7c, 0x7b, 0x7a, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7b, 0x7c, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x81, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x81, 0x83, 0x82, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, + 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x83, 0x84, 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, + 0x84, 0x83, 0x83, 0x83, 0x81, 0x82, 0x83, 0x81, 0x81, 0x82, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x80, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, + 0x80, 0x81, 0x7d, 0x7d, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x82, 0x81, 0x81, + 0x80, 0x80, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x81, 0x80, 0x82, 0x81, 0x80, 0x81, 0x80, + 0x80, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7b, 0x7a, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, + 0x81, 0x82, 0x81, 0x81, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x82, 0x81, 0x80, 0x7e, 0x80, + 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x83, 0x82, 0x82, 0x83, 0x83, + 0x82, 0x82, 0x83, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x80, 0x82, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x82, 0x81, 0x82, 0x82, 0x81, 0x7e, 0x80, 0x81, 0x80, 0x7d, + 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, + 0x7a, 0x79, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x82, 0x83, 0x81, 0x82, 0x83, + 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x84, 0x84, 0x82, 0x81, 0x81, 0x82, 0x83, 0x83, 0x82, + 0x83, 0x84, 0x84, 0x83, 0x83, 0x84, 0x82, 0x81, 0x83, 0x84, 0x84, 0x82, 0x81, 0x83, 0x83, 0x82, + 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x82, 0x82, 0x83, 0x82, 0x7e, 0x7e, + 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, + 0x7b, 0x7c, 0x7d, 0x80, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7d, + 0x7d, 0x7e, 0x80, 0x81, 0x80, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x80, 0x7e, 0x81, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x80, 0x80, 0x7d, 0x7e, + 0x81, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x82, 0x81, 0x81, 0x82, + 0x80, 0x7e, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x80, 0x7e, 0x81, 0x82, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x82, 0x83, 0x83, 0x82, 0x83, + 0x82, 0x82, 0x84, 0x84, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x85, 0x84, 0x84, 0x84, 0x84, 0x83, + 0x84, 0x84, 0x82, 0x82, 0x83, 0x81, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7c, 0x7d, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, + 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, + 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, + 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x83, 0x82, 0x83, 0x83, 0x82, 0x81, 0x83, 0x82, + 0x82, 0x82, 0x82, 0x80, 0x80, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7d, 0x7c, 0x7e, 0x7e, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x83, + 0x84, 0x83, 0x82, 0x83, 0x82, 0x81, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, 0x82, 0x82, + 0x83, 0x83, 0x82, 0x83, 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x82, 0x82, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7b, 0x7c, 0x7b, 0x7a, 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, + 0x7b, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7b, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x83, 0x82, 0x81, 0x81, + 0x83, 0x83, 0x84, 0x83, 0x82, 0x83, 0x83, 0x82, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x82, 0x83, 0x84, 0x84, 0x83, 0x82, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x81, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x83, + 0x82, 0x81, 0x81, 0x81, 0x82, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, + 0x7b, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, + 0x84, 0x84, 0x83, 0x83, 0x82, 0x82, 0x84, 0x84, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, + 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x81, 0x82, 0x82, 0x81, 0x81, + 0x82, 0x82, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, 0x82, + 0x82, 0x82, 0x83, 0x83, 0x82, 0x80, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, + 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, + 0x82, 0x81, 0x82, 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x83, 0x83, 0x82, + 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x7e, + 0x80, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, + 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, + 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x82, 0x82, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, + 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x83, 0x84, + 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x81, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, + 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, + 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, 0x83, 0x82, + 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7d, + 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x81, 0x80, + 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, + 0x81, 0x81, 0x81, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x83, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x83, 0x82, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x80, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7c, 0x7c, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, + 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x82, + 0x81, 0x81, 0x81, 0x80, 0x7e, 0x80, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x80, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, + 0x80, 0x81, 0x82, 0x81, 0x82, 0x82, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x81, 0x80, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x81, + 0x80, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x82, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, + 0x82, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, + 0x82, 0x82, 0x81, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, + 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, + 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x82, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x82, 0x82, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7b, + 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, + 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x82, 0x82, 0x81, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, + 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, + 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x82, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x80, + 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, + 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, + 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, + 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x7f, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, + 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x80, 0x81, 0x80, 0x80, 0x81, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x7e, 0x7f, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, + 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, + 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, 0x80, 0x80, 0x81, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, + 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, + 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x7e, 0x80, 0x80, + 0x7e, 0x7e, 0x7f, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x7e, 0x7e, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +}; + diff --git a/components/driver/test/dac_dma_test/test_esp32.c b/components/driver/test/dac_dma_test/test_esp32.c new file mode 100644 index 000000000..5d4f96205 --- /dev/null +++ b/components/driver/test/dac_dma_test/test_esp32.c @@ -0,0 +1,176 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + Tests for the dac device driver + Hardware connection: + - ESP32: GPIO25 <---> GPIO26 + - ESP32S2: GPIO17 <---> GPIO18 +*/ +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" +#include "test_dac_audio_file.h" +#include "driver/i2s.h" + +#if !DISABLED_FOR_TARGETS(ESP8266, ESP32S2) // This testcase for ESP32 + +/* + * DAC DMA config. + */ + +//enable record sound and save in flash +#define RECORD_IN_FLASH_EN (1) +//enable replay recorded sound in flash +#define REPLAY_FROM_FLASH_EN (1) + +//i2s number +#define EXAMPLE_I2S_NUM (0) +//i2s sample rate +#define EXAMPLE_I2S_SAMPLE_RATE (16000) +//i2s data bits +#define EXAMPLE_I2S_SAMPLE_BITS (16) +//enable display buffer for debug +#define EXAMPLE_I2S_BUF_DEBUG (0) +//I2S read buffer length +#define EXAMPLE_I2S_READ_LEN (16 * 1024) +//I2S data format +#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT) +//I2S channel number +#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1)) + +//flash record size, for recording 5 seconds' data +#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5) +#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE) +//sector size of flash +#define FLASH_SECTOR_SIZE (0x1000) +//flash read / write address +#define FLASH_ADDR (0x200000) + +/** + * @brief I2S ADC/DAC mode init. + */ +static void example_i2s_init(void) +{ + int i2s_num = EXAMPLE_I2S_NUM; + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN, + .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, + .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, + .communication_format = I2S_COMM_FORMAT_PCM, + .channel_format = EXAMPLE_I2S_FORMAT, + .intr_alloc_flags = 0, + .dma_buf_count = 2, + .dma_buf_len = 1024, + .use_apll = 1, + }; + //install and start i2s driver + TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); + //init DAC pad + TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN) ); +} + +static void example_i2s_deinit(void) +{ + TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); +} + +/** + * @brief Set i2s clock for example audio file + */ +static void example_set_file_play_mode(void) +{ + TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1) ); +} + +/** + * @brief Scale data to 16bit/32bit for I2S DMA output. + * DAC can only output 8bit data value. + * I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data. + */ +static int example_i2s_dac_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len) +{ + uint32_t j = 0; +#if (EXAMPLE_I2S_SAMPLE_BITS == 16) + for (int i = 0; i < len; i++) { + d_buff[j++] = 0; + d_buff[j++] = s_buff[i]; + } + return (len * 2); +#else + for (int i = 0; i < len; i++) { + d_buff[j++] = 0; + d_buff[j++] = 0; + d_buff[j++] = 0; + d_buff[j++] = s_buff[i]; + } + return (len * 4); +#endif +} +/** + * @brief debug buffer data + */ +static void example_disp_buf(uint8_t *buf, int length) +{ + printf("======\n"); + for (int i = 0; i < length; i++) { + printf("%02x ", buf[i]); + if ((i + 1) % 8 == 0) { + printf("\n"); + } + } + printf("======\n"); +} + +/** + * @brief Reset i2s clock and mode + */ +static void example_reset_play_mode(void) +{ + TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM) ); +} + +TEST_CASE("DAC DMA output", "[dac]") +{ + example_i2s_init(); + + size_t bytes_written; + int i2s_read_len = EXAMPLE_I2S_READ_LEN; + uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char)); + printf("Playing file example: \n"); + int offset = 0; + int tot_size = sizeof(audio_table); + example_set_file_play_mode(); + while (offset < tot_size) { + int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset); + int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len); + i2s_write(EXAMPLE_I2S_NUM, i2s_write_buff, i2s_wr_len, &bytes_written, portMAX_DELAY); + offset += play_len; + example_disp_buf((uint8_t *) i2s_write_buff, 32); + } + vTaskDelay(100 / portTICK_PERIOD_MS); + example_reset_play_mode(); + free(i2s_write_buff); + + example_i2s_deinit(); +} + +#endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32S2) diff --git a/components/driver/test/esp32/test_touch_sensor.c b/components/driver/test/esp32/test_touch_sensor.c deleted file mode 100644 index c713d1d7b..000000000 --- a/components/driver/test/esp32/test_touch_sensor.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - Tests for the touch sensor device driver -*/ -#include "esp_system.h" -#include "driver/touch_pad.h" -#include "unity.h" -#include "esp_system.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "test_utils.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/rtc_cntl_struct.h" -#include "soc/sens_reg.h" -#include "soc/sens_struct.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/rtc_cntl_struct.h" -#include "soc/rtc_io_reg.h" -#include "soc/rtc_io_struct.h" - -static const char *TAG = "test_touch"; - -#define TOUCH_READ_INVALID_VAL (0) -#define TOUCHPAD_FILTER_TOUCH_PERIOD (10) - -#define TOUCH_REG_BASE_TEST() ({ \ - TEST_ASSERT_EQUAL_UINT32(RTC_CNTL_BROWN_OUT_REG, &RTCCNTL.brown_out.val); \ - TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ - TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ -}) - -#define TOUCH_READ_ERROR (50) -#define TEST_TOUCH_COUNT_NUM (10) -#define TEST_TOUCH_CHANNEL (9) -static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { - TOUCH_PAD_NUM0, - // TOUCH_PAD_NUM1 is GPIO0, for download. - TOUCH_PAD_NUM2, - TOUCH_PAD_NUM3, - TOUCH_PAD_NUM4, - TOUCH_PAD_NUM5, - TOUCH_PAD_NUM6, - TOUCH_PAD_NUM7, - TOUCH_PAD_NUM8, - TOUCH_PAD_NUM9, -}; - -static void printf_touch_hw_read(const char *str) -{ - uint16_t touch_value; - printf("[%s] ", str); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - while (!touch_pad_meas_is_done()) ; - touch_pad_read_raw_data(touch_list[i], &touch_value); - printf("[%d]%d ", touch_list[i], touch_value); - } - printf("\r\n"); -} - -/* - * Change the slope to get larger value from touch sensor. - */ -static void test_push_fake(touch_pad_t pad_num) -{ - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_2, TOUCH_PAD_TIE_OPT_DEFAULT); -} - -/* - * Change the slope to get larger value from touch sensor. - */ -static void test_release_fake(touch_pad_t pad_num) -{ - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); -} - -static esp_err_t test_touch_sw_read(void) -{ - ESP_LOGI(TAG, "%s", __func__); - uint16_t touch_value; - - TEST_ESP_OK( touch_pad_init() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); - } - - // Start task to read values sensed by pads - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) ); - printf("T%d:[%4d] ", touch_list[i], touch_value); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); - } - printf("\n"); - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -static esp_err_t test_touch_timer_read(void) -{ - ESP_LOGI(TAG, "%s", __func__); - uint16_t touch_value[TEST_TOUCH_CHANNEL], touch_temp[TEST_TOUCH_CHANNEL]; - int t_cnt = TEST_TOUCH_COUNT_NUM; - - TEST_ESP_OK( touch_pad_init() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); - } - // Start task to read values sensed by pads - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value[i]) ); - printf("T%d:[%4d] ", touch_list[i], touch_value[i]); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); - } - while (t_cnt--) { - // Start task to read values sensed by pads - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_temp[i]) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - } - vTaskDelay(50 / portTICK_PERIOD_MS); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -static esp_err_t test_touch_filtered_read(void) -{ - ESP_LOGI(TAG, "%s", __func__); - uint16_t touch_value, touch_temp; - int t_cnt = TEST_TOUCH_COUNT_NUM; - - TEST_ESP_OK( touch_pad_init() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); - } - // Initialize and start a software filter to detect slight change of capacitance. - touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD); - vTaskDelay(10 / portTICK_PERIOD_MS); - - while (t_cnt--) { - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); - TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_temp) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); - printf("T%d:[%4d] ", touch_list[i], touch_value); - } - vTaskDelay(50 / portTICK_PERIOD_MS); - } - printf("\n"); - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -// test the basic configuration function with right parameters and error parameters -TEST_CASE("Touch Sensor all channel read test", "[touch]") -{ - TOUCH_REG_BASE_TEST(); - TEST_ESP_OK( test_touch_sw_read() ); - TEST_ESP_OK( test_touch_timer_read() ); - TEST_ESP_OK( test_touch_filtered_read() ); -} - -static int test_touch_parameter(touch_pad_t pad_num, int meas_time, int slp_time, int vol_h, int vol_l, int vol_a, int slope) -{ - ESP_LOGI(TAG, "%s", __func__); - uint16_t touch_value; - TEST_ESP_OK( touch_pad_init() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_config(pad_num, TOUCH_READ_INVALID_VAL) ); - - touch_pad_set_meas_time(slp_time, meas_time); - touch_pad_set_voltage(vol_h, vol_l, vol_a); - touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT); - - // Initialize and start a software filter to detect slight change of capacitance. - touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD); - vTaskDelay(500 / portTICK_PERIOD_MS); - - // Start task to read values sensed by pads - TEST_ESP_OK( touch_pad_read(pad_num, &touch_value) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); - printf("T%d:[%4d] ", pad_num, touch_value); - TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); - printf("T%d:[%4d] ", pad_num, touch_value); - TEST_ESP_OK( touch_pad_read_filtered(pad_num, &touch_value) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); - printf("T%d:[%4d] \n", pad_num, touch_value); - - TEST_ESP_OK( touch_pad_deinit() ); - - return touch_value; -} - -TEST_CASE("Touch Sensor parameters test", "[touch]") -{ - int touch_val[5] = {0}; - - ESP_LOGI(TAG, "Charge / incharge voltage level test"); - touch_val[0] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V, - TOUCH_PAD_SLOPE_DEFAULT); - touch_val[1] = test_touch_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V, - TOUCH_PAD_SLOPE_DEFAULT); - touch_val[2] = test_touch_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5, - TOUCH_PAD_SLOPE_DEFAULT); - - TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]); - TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]); - - ESP_LOGI(TAG, "Measure time / sleep time test"); - touch_val[0] = test_touch_parameter(touch_list[0], 0xff, 0xa, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT); - touch_val[1] = test_touch_parameter(touch_list[0], 0x1ff, 0xf, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT); - touch_val[2] = test_touch_parameter(touch_list[0], 0x2fff, 0x1f, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT); - - TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]); - TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]); - - ESP_LOGI(TAG, "Charge / incharge slope level test"); - touch_val[0] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 1); - touch_val[1] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3); - touch_val[2] = test_touch_parameter(touch_list[1], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7); - - TEST_ASSERT_GREATER_OR_EQUAL(touch_val[0], touch_val[1]); - TEST_ASSERT_GREATER_OR_EQUAL(touch_val[1], touch_val[2]); -} - -static bool s_pad_activated[TOUCH_PAD_MAX]; - -static void test_touch_intr_cb(void *arg) -{ - uint32_t pad_intr = touch_pad_get_status(); - ets_printf("T%x ", pad_intr); - //clear interrupt - touch_pad_clear_status(); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if ((pad_intr >> touch_list[i]) & 0x1) { - s_pad_activated[touch_list[i]] = true; - } - } -} - -static esp_err_t test_touch_interrupt(void) -{ - ESP_LOGI(TAG, "%s", __func__); - uint16_t touch_value; - - TEST_ESP_OK( touch_pad_init() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i], TOUCH_READ_INVALID_VAL) ); - } - // Initialize and start a software filter to detect slight change of capacitance. - touch_pad_filter_start(TOUCHPAD_FILTER_TOUCH_PERIOD); - vTaskDelay(10 / portTICK_PERIOD_MS); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - //read filtered value - TEST_ESP_OK( touch_pad_read_filtered(touch_list[i], &touch_value) ); - ESP_LOGI(TAG, "test init: touch pad [%d] val is %d", touch_list[i], touch_value); - //set interrupt threshold. - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * 2 / 3) ); - } - - // Register touch interrupt ISR - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL) ); - TEST_ESP_OK( touch_pad_clear_status() ); - TEST_ESP_OK( touch_pad_intr_enable() ); - - int test_cnt = TEST_TOUCH_COUNT_NUM; - while (test_cnt--) { - ESP_LOGI(TAG, "touch push"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - test_push_fake(touch_list[i]); - } - vTaskDelay(100 / portTICK_PERIOD_MS); - printf_touch_hw_read("push"); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if (s_pad_activated[touch_list[i]] == false) { - ESP_LOGE(TAG, "touch%d not active", touch_list[i]); - TEST_FAIL(); - } - } - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - s_pad_activated[touch_list[i]] = 0; - } - - ESP_LOGI(TAG, "touch release"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - test_release_fake(touch_list[i]); - } - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor interrupt test", "[touch]") -{ - TEST_ESP_OK( test_touch_interrupt() ); -} \ No newline at end of file diff --git a/components/driver/test/esp32s2/test_touch_sensor.c b/components/driver/test/esp32s2/test_touch_sensor.c deleted file mode 100644 index 49a622f02..000000000 --- a/components/driver/test/esp32s2/test_touch_sensor.c +++ /dev/null @@ -1,2200 +0,0 @@ -/* - Tests for the touch sensor device driver -*/ -#include -#include "esp_system.h" -#include "driver/touch_pad.h" -#include "unity.h" -#include "esp_system.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "freertos/queue.h" -// #include "esp_event.h" -// #include "esp_wifi.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "test_utils.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/rtc_cntl_struct.h" -#include "soc/sens_reg.h" -#include "soc/sens_struct.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/rtc_cntl_struct.h" -#include "soc/rtc_io_reg.h" -#include "soc/rtc_io_struct.h" -#include "soc/apb_ctrl_reg.h" -#include "driver/rtc_io.h" - -static const char *TAG = "test_touch"; - -#define PLATFORM_SELECT (1) //0: pxp; 1: chip -#if (PLATFORM_SELECT == 0) //PXP platform -#define SET_BREAK_POINT(flag) REG_WRITE(APB_CTRL_DATE_REG, flag) -//PXP clk is slower. -#define SYS_DELAY_TIME_MOM (1/40) -#define RTC_SLOW_CLK_FLAG 1 // Slow clock is 32KHz. -void test_pxp_deinit_io(void) -{ - for (int i = 0; i < 22; i++) { - rtc_gpio_init(i); - } -} -#else -//PXP clk is slower. -#define SET_BREAK_POINT(flag) -#define SYS_DELAY_TIME_MOM (1) -#define RTC_SLOW_CLK_FLAG 0 // Slow clock is 32KHz. -void test_pxp_deinit_io(void) -{ - ; -} -#endif - -#define TOUCH_READ_INVALID_VAL (SOC_TOUCH_PAD_THRESHOLD_MAX) -#define TOUCH_READ_ERROR (100) -#define TOUCH_INTR_THRESHOLD (0.1) -#define TOUCH_EXCEED_TIME_MS (1000) - -#define TOUCH_REG_BASE_TEST() ({ \ - TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_CNTL_DATE), RTCCNTL.date.date); \ - TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ - TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ -}) - -#define TEST_TOUCH_COUNT_NUM (10) -#define TEST_TOUCH_CHANNEL (14) -static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { - // TOUCH_PAD_NUM0, is GPIO0, for download. - TOUCH_PAD_NUM1, - TOUCH_PAD_NUM2, - TOUCH_PAD_NUM3, - TOUCH_PAD_NUM4, - TOUCH_PAD_NUM5, - TOUCH_PAD_NUM6, - TOUCH_PAD_NUM7, - TOUCH_PAD_NUM8, - TOUCH_PAD_NUM9, - TOUCH_PAD_NUM10, - TOUCH_PAD_NUM11, - TOUCH_PAD_NUM12, - TOUCH_PAD_NUM13, - TOUCH_PAD_NUM14 -}; -// static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { -// // TOUCH_PAD_NUM0, is GPIO0, for download. -// TOUCH_PAD_NUM2, -// TOUCH_PAD_NUM4, -// TOUCH_PAD_NUM6, -// TOUCH_PAD_NUM10, -// TOUCH_PAD_NUM11, -// TOUCH_PAD_NUM12, -// TOUCH_PAD_NUM13, -// }; -#define TOUCH_WATERPROOF_RING_PAD TOUCH_PAD_NUM1 -static touch_pad_t proximity_pad[3] = { - TOUCH_PAD_NUM2, - TOUCH_PAD_NUM3, - TOUCH_PAD_NUM4, -}; - -static QueueHandle_t que_touch = NULL; -typedef struct touch_msg { - touch_pad_intr_mask_t intr_mask; - uint32_t pad_num; - uint32_t pad_status; - uint32_t pad_val; - uint32_t slp_proxi_cnt; - uint32_t slp_proxi_base; -} touch_event_t; - -static uint32_t s_touch_timeout_mask = 0; - -static void printf_touch_hw_read(const char *str) -{ - uint32_t touch_value; - printf("[%s] ", str); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - touch_pad_read_raw_data(touch_list[i], &touch_value); - printf("[%d]%d ", touch_list[i], touch_value); - } - printf("\r\n"); -} - -static void printf_touch_baseline_read(const char *str) -{ - uint32_t touch_value; - printf("[%s] ", str); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - printf("[%d]%d ", touch_list[i], touch_value); - } - printf("\r\n"); -} - -static void printf_touch_smooth_read(const char *str) -{ - uint32_t touch_value; - printf("[%s] ", str); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - touch_pad_filter_read_smooth(touch_list[i], &touch_value); - printf("[%d]%d ", touch_list[i], touch_value); - } - printf("\r\n"); -} - - -static void test_timeout_trigger_fake(touch_pad_t pad_num) -{ - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_0, TOUCH_PAD_TIE_OPT_DEFAULT); -} - -static void test_timeout_normal(touch_pad_t pad_num) -{ - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); -} - -/* - * Change the slope to get larger value from touch sensor. - */ -static void test_push_fake(touch_pad_t pad_num) -{ - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_3, TOUCH_PAD_TIE_OPT_DEFAULT); -} - -/* - * Change the slope to get larger value from touch sensor. - */ -static void test_release_fake(touch_pad_t pad_num) -{ - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); -} - -static void test_touch_push_all(void) -{ - ESP_LOGI(TAG, "touch push"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - test_push_fake(touch_list[i]); - } -} - -static void test_touch_release_all(void) -{ - ESP_LOGI(TAG, "touch release"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - test_release_fake(touch_list[i]); - } -} - -/* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ -static void test_touch_baseline_not_update(void) -{ - uint32_t touch_val[TEST_TOUCH_CHANNEL] = {0}; - uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_val[i]) ); - } - for (int i = 0; i < 10; i++) { - vTaskDelay(20 / portTICK_PERIOD_MS); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_temp[i]) ); - TEST_ASSERT_EQUAL(touch_temp[i], touch_val[i]); - } - } -} - -/* - * Test the stable and change of touch sensor reading in SW mode. - */ -esp_err_t test_touch_sw_read(void) -{ - uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; - uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; - uint32_t touch_push[TEST_TOUCH_CHANNEL] = {0}; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - while (test_cnt--) { - test_touch_release_all(); - - /* Read the touch sensor raw data in SW mode. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_sw_start() ); - while (!touch_pad_meas_is_done()) ; - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); - printf("T%d:[%4d] ", touch_list[i], touch_value[i]); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); - } - printf("\n"); - /* Check the stable of reading. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if (touch_temp[i]) { - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - } - touch_temp[i] = touch_value[i]; - } - - test_touch_push_all(); - - /* Read the touch sensor raw data in SW mode. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_sw_start() ); - while (!touch_pad_meas_is_done()) ; - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_push[i]) ); - printf("T%d:[%4d] ", touch_list[i], touch_push[i]); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_push[i]); - } - printf("\n"); - /* Check the change of reading. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ASSERT_GREATER_THAN(touch_value[i], touch_push[i]); - } - } - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -/* - * Test the stable and change of touch sensor reading in timer mode. - * TEST POINT: - * 1. Timer mode for FSM. - * 2. Touch channel slope setting. - * 3. Touch reading stable. - */ -esp_err_t test_touch_timer_read(void) -{ - uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; - uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; - uint32_t touch_push[TEST_TOUCH_CHANNEL] = {0}; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - TEST_ESP_OK( touch_pad_init() ); - /* Set different slope for channels to test slope function. */ - printf("Set slope for channel: "); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - TEST_ESP_OK( touch_pad_set_cnt_mode(touch_list[i], i % 7 ? i % 7 : 1, TOUCH_PAD_TIE_OPT_DEFAULT) ); - printf("[ch%d-%d] ", touch_list[i], i % 7 ? i % 7 : 1); - } - printf("\n"); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - /* Wait touch sensor stable */ - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - while (test_cnt--) { - test_touch_release_all(); - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - // Start task to read values sensed by pads - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); - printf("T%d:[%4d] ", touch_list[i], touch_value[i]); - } - printf("\n"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if (touch_temp[i]) { - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - } - touch_temp[i] = touch_value[i]; - } - - test_touch_push_all(); - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - /* Read the touch sensor raw data in FSM mode. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_push[i]) ); - printf("T%d:[%4d] ", touch_list[i], touch_push[i]); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_push[i]); - } - printf("\n"); - /* Check the change of reading. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ASSERT_GREATER_THAN(touch_value[i], touch_push[i]); - } - } - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -/* - * Test the filter mode. - * TEST POINT: - * 1. Timer mode for FSM. - * 2. Touch reading stable. - * 3. Touch reading init value. - * 4. Touch reading filtered value equal to raw data. - */ -esp_err_t test_touch_filtered_read(void) -{ - uint32_t touch_value[TEST_TOUCH_CHANNEL] = {0}; - uint32_t touch_temp[TEST_TOUCH_CHANNEL] = {0}; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - /* Wait touch pad init done. */ - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - /* Test the stable for init value of touch reading. - * Ideal: baseline == raw data == smooth data. - */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value[i]) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value[i]); - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_temp[i]) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &touch_temp[i]) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_temp[i]); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - } - printf("touch filter init value:\n"); - printf_touch_hw_read("raw "); - printf_touch_baseline_read("base "); - printf_touch_smooth_read("smooth"); - printf("\n"); - - int test_cnt = TEST_TOUCH_COUNT_NUM; - while (test_cnt--) { - /* Touch reading filtered value equal to raw data. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value[i]) ); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_temp[i]) ); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &touch_temp[i]) ); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - } - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if (touch_temp[i]) { - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp[i], touch_value[i]); - } - touch_temp[i] = touch_value[i]; - } - vTaskDelay(20 / portTICK_PERIOD_MS); - } - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor reading test (SW, Timer, filter)", "[touch]") -{ - TOUCH_REG_BASE_TEST(); - TEST_ESP_OK( test_touch_sw_read() ); - TEST_ESP_OK( test_touch_timer_read() ); - TEST_ESP_OK( test_touch_filtered_read() ); -} - -/* - * Test the base patameter mode. - * TEST POINT: - * 1. measure time and sleep time setting. - * 2. Charge / incharge voltage threshold setting. - * 3. Touch slope setting. - * 4. Touch reading filtered value equal to raw data. - */ -int test_touch_base_parameter(touch_pad_t pad_num, int meas_time, int slp_time, - int vol_h, int vol_l, int vol_a, int slope, bool is_conn_gnd) -{ - uint32_t touch_value = 0; - uint32_t touch_temp = 0, touch_filter; - uint64_t val_sum = 0; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - TEST_ESP_OK( touch_pad_init() ); - /* Note: init all channel, but test one channel. */ - // TEST_ESP_OK( touch_pad_config(pad_num) ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - - TEST_ESP_OK( touch_pad_set_cnt_mode(pad_num, slope, TOUCH_PAD_TIE_OPT_DEFAULT) ); - TEST_ESP_OK( touch_pad_set_meas_time(slp_time, meas_time) ); - TEST_ESP_OK( touch_pad_set_voltage(vol_h, vol_l, vol_a) ); - TEST_ESP_OK( touch_pad_set_inactive_connect(is_conn_gnd) ); - ESP_LOGI(TAG, "meas_time[%d]_slp_time[%d]_vol_h[%d]_vol_l[%d]_vol_a[%d]_slope[%d]_is_conn_gnd[%d]", - meas_time, slp_time, vol_h, vol_l, vol_a, slope, is_conn_gnd); - - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - /* Some parameters will delay the init time. so wait longger time */ - vTaskDelay(100 / portTICK_PERIOD_MS); - - while (test_cnt--) { - /* Correctness of reading. Ideal: baseline == raw data == smooth data. */ - TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_baseline(pad_num, &touch_filter) ); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_filter, touch_value); - TEST_ESP_OK( touch_pad_filter_read_smooth(pad_num, &touch_filter) ); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_filter, touch_value); - - /* Stable of reading */ - TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); - TEST_ESP_OK( touch_pad_read_raw_data(pad_num, &touch_value) ); - TEST_ASSERT_NOT_EQUAL(TOUCH_READ_INVALID_VAL, touch_value); - if (touch_temp) { - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); - } - touch_temp = touch_value; - - printf("T%d:[%4d] ", pad_num, touch_value); - val_sum += touch_value; // For check. - vTaskDelay(20 / portTICK_PERIOD_MS); - } - printf("\n"); - - TEST_ESP_OK( touch_pad_deinit() ); - return (uint32_t)(val_sum / TEST_TOUCH_COUNT_NUM); -} - -TEST_CASE("Touch Sensor base parameters test (meas_time, voltage, slope, inv_conn)", "[touch]") -{ - int touch_val[5] = {0}; - - ESP_LOGI(TAG, "Charge / incharge voltage level test"); - touch_val[0] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V8, TOUCH_HVOLT_ATTEN_1V5, - TOUCH_PAD_SLOPE_DEFAULT, true); - touch_val[1] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_HVOLT_2V5, TOUCH_LVOLT_0V6, TOUCH_HVOLT_ATTEN_1V, - TOUCH_PAD_SLOPE_DEFAULT, true); - touch_val[2] = test_touch_base_parameter(touch_list[2], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V, - TOUCH_PAD_SLOPE_DEFAULT, true); - - TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); - TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); - - ESP_LOGI(TAG, "Measure time / sleep time test"); - touch_val[0] = test_touch_base_parameter(touch_list[1], 0xff, 0x1ff, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); - touch_val[1] = test_touch_base_parameter(touch_list[1], 0xfff, 0xff, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); - touch_val[2] = test_touch_base_parameter(touch_list[1], 0x1fff, 0xf, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, true); - - TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); - TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); - - ESP_LOGI(TAG, "Charge / incharge slope level test"); - touch_val[0] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 7, true); - touch_val[1] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 5, true); - touch_val[2] = test_touch_base_parameter(touch_list[0], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, 3, true); - - TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); - TEST_ASSERT_GREATER_THAN(touch_val[1], touch_val[2]); - - /* The GND option causes larger parasitic capacitance and larger reading */ - ESP_LOGI(TAG, "Inactive connect test"); - touch_val[0] = test_touch_base_parameter(touch_list[3], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, - false); - touch_val[1] = test_touch_base_parameter(touch_list[3], TOUCH_PAD_MEASURE_CYCLE_DEFAULT, TOUCH_PAD_SLEEP_CYCLE_DEFAULT, - TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD, TOUCH_PAD_SLOPE_DEFAULT, - true); - TEST_ASSERT_GREATER_THAN(touch_val[0], touch_val[1]); -} - -/* - * Check active interrupt of touch channels. - */ -static esp_err_t test_touch_check_ch_touched(uint32_t test_ch_num, uint32_t exceed_time_ms) -{ - touch_event_t evt = {0}; - int ret = ESP_FAIL; - printf("Active: "); - while (1) { - if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { - printf("0x%x, ", evt.pad_status); - if (test_ch_num == __builtin_popcount(evt.pad_status)) { - ret = ESP_OK; - break; - } - } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { - continue; - } else { // If the interrupt type error, test error. - ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); - break; - } - } else { - ESP_LOGI(TAG, "Touch intr exceed time"); - break; - } - } - printf("\n"); - return (esp_err_t)ret; -} - -/* - * Check inactive interrupt of touch channels. - */ -static esp_err_t test_touch_check_ch_released(uint32_t test_ch_num, uint32_t exceed_time_ms) -{ - touch_event_t evt = {0}; - int ret = ESP_FAIL; - printf("Inactive: "); - while (1) { - if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) { - printf("0x%x, ", evt.pad_status); - if ((TEST_TOUCH_CHANNEL - test_ch_num) == __builtin_popcount(evt.pad_status)) { - ret = ESP_OK; - break; - } - } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { - continue; - } else { // If the interrupt type error, test error. - ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); - break; - } - } else { - ESP_LOGI(TAG, "Touch intr exceed time"); - break; - } - } - printf("\n"); - return (esp_err_t)ret; -} - -static esp_err_t test_touch_check_ch_touched_with_proximity(uint32_t test_ch_num, uint32_t exceed_time_ms) -{ - touch_pad_proximity_t proximity; - uint16_t ch_mask = 0; - touch_event_t evt = {0}; - int ret = ESP_FAIL; - - TEST_ESP_OK( touch_pad_proximity_get_config(&proximity) ); - printf("Active: "); - while (1) { - if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_ACTIVE) { - printf("0x%x, ", evt.pad_status); - if (test_ch_num == __builtin_popcount(evt.pad_status)) { - ret = ESP_OK; - break; - } - } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_SCAN_DONE)) { - touch_pad_get_channel_mask(&ch_mask); - for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { - if (BIT(i) & ch_mask) { - if (evt.pad_num == i) { - if (proximity.meas_num == evt.slp_proxi_cnt) { - ets_printf("priximity base(%d) cnt(%d)\n", evt.slp_proxi_base, evt.slp_proxi_cnt); - } - } - } - } - continue; - } else { // If the interrupt type error, test error. - ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); - continue;; - } - } else { - ESP_LOGI(TAG, "Touch intr exceed time"); - break; - } - } - printf("\n"); - return (esp_err_t)ret; -} - -static esp_err_t test_touch_check_ch_released_with_proximity(uint32_t test_ch_num, uint32_t exceed_time_ms) -{ - touch_pad_proximity_t proximity; - uint16_t ch_mask = 0; - touch_event_t evt = {0}; - int ret = ESP_FAIL; - - touch_pad_proximity_get_config(&proximity); - printf("Inactive: "); - while (1) { - if (pdTRUE == xQueueReceive(que_touch, &evt, exceed_time_ms / portTICK_PERIOD_MS)) { - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_INACTIVE) { - printf("0x%x, ", evt.pad_status); - if ((TEST_TOUCH_CHANNEL - test_ch_num) == __builtin_popcount(evt.pad_status)) { - ret = ESP_OK; - break; - } - } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_SCAN_DONE)) { - touch_pad_get_channel_mask(&ch_mask); - for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { - if (BIT(i) & ch_mask) { - if (evt.pad_num == i) { - if (proximity.meas_num == evt.slp_proxi_cnt) { - ets_printf("priximity base(%d) cnt(%d)\n", evt.slp_proxi_base, evt.slp_proxi_cnt); - } - } - } - } - continue; - } else { // If the interrupt type error, test error. - ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); - continue;; - } - } else { - ESP_LOGI(TAG, "Touch intr exceed time"); - break; - } - } - printf("\n"); - return (esp_err_t)ret; -} - -/* - * Check scan done interrupt of touch channels. - */ -static esp_err_t test_touch_check_ch_intr_scan_done(void) -{ - touch_event_t evt = {0}; - uint16_t ch_mask = 0; - int ret = ESP_FAIL; - /* Check the scan done interrupt. */ - while (1) { - if (pdTRUE == xQueueReceive(que_touch, &evt, 1000 / portTICK_PERIOD_MS)) { - /* Scan done interrupt have bug that be trigger by last two channel. */ - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) { - touch_pad_get_channel_mask(&ch_mask); - for (int i = TOUCH_PAD_MAX - 1; i >= 0; i--) { - if (BIT(i) & ch_mask) { - if (evt.pad_num == i) { - ESP_LOGI(TAG, "touch _SCAN_DONE INTR be triggered"); - ret = ESP_OK; - } - goto NEXT_TEST; - } - } - } else if (evt.intr_mask & (TOUCH_PAD_INTR_MASK_DONE | TOUCH_PAD_INTR_MASK_SCAN_DONE)) { - continue; - } else { // If the interrupt type error, test error. - ESP_LOGI(TAG, "Touch[%d] intr error, status %d, evt_msk0x%x", evt.pad_num, evt.pad_status, evt.intr_mask); - break; - } - } else { - ESP_LOGI(TAG, "Touch intr exceed time"); - break; - } - } -NEXT_TEST: - printf("\n"); - return (esp_err_t)ret; -} - -/* - * Check timeout interrupt of touch channels. - */ -static esp_err_t test_touch_check_ch_intr_timeout(touch_pad_t pad_num) -{ - int ret = ESP_FAIL; - touch_event_t evt = {0}; - - while (1) { - if (pdTRUE == xQueueReceive(que_touch, &evt, 1000 / portTICK_PERIOD_MS)) { - /* Scan done interrupt have bug that be trigger by last two channel. */ - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { - if (pad_num == evt.pad_num) { - ESP_LOGI(TAG, "touch TIMEOUT be triggered"); - s_touch_timeout_mask = 0; - ret = ESP_OK; - break; - } else { - ets_printf("-timeout %x T[%d] status %d, evt_msk %x -\n", - s_touch_timeout_mask, evt.pad_num, evt.pad_status, evt.intr_mask); - } - } else { - continue; - } - } else { - ESP_LOGI(TAG, "Touch intr exceed time"); - break; - } - } - printf("\n"); - return (esp_err_t)ret; -} - -static void test_touch_intr_cb(void *arg) -{ - uint32_t cnt, touch_value; - int task_awoken = pdFALSE; - touch_event_t evt; - evt.intr_mask = touch_pad_read_intr_status_mask(); - evt.pad_status = touch_pad_get_status(); - evt.pad_num = touch_pad_get_current_meas_channel(); - - if (!evt.intr_mask) { - ets_printf("."); - return; - } - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_SCAN_DONE) { - touch_pad_filter_read_baseline(evt.pad_num, &evt.pad_val); - touch_pad_sleep_channel_read_baseline(&touch_value); - touch_pad_sleep_channel_read_proximity_cnt(&cnt); - evt.slp_proxi_cnt = cnt; - evt.slp_proxi_base = touch_value; - // ets_printf("[intr] base(%d) cnt(%d)\n", touch_value, cnt); - } - if (evt.intr_mask & TOUCH_PAD_INTR_MASK_TIMEOUT) { - s_touch_timeout_mask |= (BIT(evt.pad_num)); - ets_printf("-%dtout-", SENS.sar_touch_status0.touch_scan_curr); - } - - xQueueSendFromISR(que_touch, &evt, &task_awoken); - if (task_awoken == pdTRUE) { - portYIELD_FROM_ISR(); - } -} - -/* - * Test the touch active/inactive interrupt. - * TEST POINT: - * 1. Touch interrupt. - * 2. Raw data noise. - * 3. smooth data and baseline data. - */ -esp_err_t test_touch_interrupt(void) -{ - uint32_t touch_value, smooth; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - // Initialize and start a software filter to detect slight change of capacitance. - vTaskDelay(50 / portTICK_PERIOD_MS); - - /* Set threshold of touch sensor */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - while (test_cnt--) { - test_touch_push_all(); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - - /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ - test_touch_baseline_not_update(); - - test_touch_release_all(); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -/* - * Test the touch active/inactive, scan_done interrupt. - * TEST POINT: - * 1. Touch interrupt. - * 2. Raw data noise. - * 3. smooth data and baseline data. - */ -esp_err_t test_touch_scan_done_interrupt(void) -{ - ESP_LOGI(TAG, " >> %s << \n", __func__); - uint32_t touch_value, smooth; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_SCAN_DONE | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - /* Check the scan done interrupt */ - TEST_ESP_OK( test_touch_check_ch_intr_scan_done() ); - - vTaskDelay(50 / portTICK_PERIOD_MS); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - while (test_cnt--) { - test_touch_push_all(); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - - /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ - test_touch_baseline_not_update(); - - test_touch_release_all(); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -/* - * Test the touch active/inactive, timeout interrupt. - * TEST POINT: - * 1. Touch interrupt. - * 2. Raw data noise. - * 3. smooth data and baseline data. - */ -esp_err_t test_touch_timeout_interrupt(void) -{ - ESP_LOGI(TAG, " >> %s << \n", __func__); - uint32_t touch_value, smooth; - - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_TIMEOUT | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - // Initialize and start a software filter to detect slight change of capacitance. - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - /* Set timeout parameter */ - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[0], &touch_value) ); - TEST_ESP_OK( touch_pad_timeout_disable() ); - TEST_ESP_OK( touch_pad_timeout_set_threshold(touch_value * 10) ); - TEST_ESP_OK( touch_pad_timeout_enable() ); - - // Only fake push one touch pad. - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - test_timeout_trigger_fake(touch_list[0]); - TEST_ESP_OK( test_touch_check_ch_intr_timeout(touch_list[0]) ); - test_timeout_normal(touch_list[0]); - - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - printf_touch_hw_read("raw "); - printf_touch_baseline_read("base "); - printf_touch_smooth_read("smooth"); - - int test_cnt = TEST_TOUCH_COUNT_NUM; - while (test_cnt--) { - test_touch_push_all(); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - - /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ - test_touch_baseline_not_update(); - - test_touch_release_all(); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor interrupt test (active, inactive, scan_done, timeout)", "[touch]") -{ - TEST_ESP_OK( test_touch_interrupt() ); - TEST_ESP_OK( test_touch_scan_done_interrupt() ); - TEST_ESP_OK( test_touch_timeout_interrupt() ); -} - -static void test_touch_measure_step(uint32_t step) -{ - /* Fake the process of debounce. */ - // printf("measure cnt %d: [ ", step); - for (int i = 0; i < step; i++) { - for (int j = 0; j < TEST_TOUCH_CHANNEL; j++) { - TEST_ESP_OK( touch_pad_sw_start() ); - while (!touch_pad_meas_is_done()) ; - } - // printf("."); - } - // printf(" ]\n"); -} - -/* - * Test the touch active/inactive, scan_done interrupt. - * TEST POINT: - * 1. Touch interrupt. - * 2. Raw data noise. - * 3. smooth data and baseline data. - */ -esp_err_t test_touch_filter_parameter_debounce(int deb_cnt) -{ - uint32_t touch_value; - int test_cnt = 2; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_128, // Test jitter and filter 1/4. - .debounce_cnt = ((deb_cnt < 0) ? 1 : deb_cnt) , // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_OFF, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - /* Run to wait the data become stable. */ - test_touch_measure_step(20); // 2 scan loop - - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ - touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - while (test_cnt--) { - test_touch_push_all(); - /* Fake the process of push debounce. */ - test_touch_measure_step(deb_cnt); // measure n times. touch state not changed. - TEST_ESP_ERR( ESP_FAIL, test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - test_touch_measure_step(1); // measure n+1 times. touch state changed. - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - - test_touch_release_all(); - /* Fake the process of release debounce. */ - test_touch_measure_step(deb_cnt); // measure n times. touch state not changed. - TEST_ESP_ERR( ESP_FAIL, test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - test_touch_measure_step(1); // measure n+1 times. touch state changed. - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -esp_err_t test_touch_filter_parameter_neg_reset(int reset_cnt) -{ - uint32_t touch_value, base_value; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - reset_cnt = ((reset_cnt < 0) ? 10 : reset_cnt); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = reset_cnt, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_OFF, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - /* Run to wait the data become stable. */ - test_touch_measure_step(20); // 2 scan loop - - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ - touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - /* 1. Fake init status is touched. */ - test_touch_push_all(); - TEST_ESP_OK( touch_pad_filter_reset_baseline(TOUCH_PAD_MAX) ); - /* Run to wait the data become stable. */ - test_touch_measure_step(20); // 2 scan loop - printf_touch_hw_read("[raw ] reset:"); - printf_touch_baseline_read("[base] reset:"); - - /* 2. Fake the touch status is released. */ - test_touch_release_all(); - /* 3. Fake measure `reset_cnt + 1` times to reset the baseline. */ - test_touch_measure_step(reset_cnt); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); - if ((base_value - touch_value) < (base_value * TOUCH_INTR_THRESHOLD)) { - ESP_LOGE(TAG, "neg reset cnt err"); - TEST_FAIL(); - } - } - printf_touch_hw_read("[raw ] neg_cnt:"); - printf_touch_baseline_read("[base] neg_cnt:"); - - test_touch_measure_step(1); - /* ESP32S2 neg reset baseline to raw data */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_read_raw_data(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); - TEST_ASSERT_EQUAL_UINT32(base_value, touch_value); - } - printf_touch_hw_read("[raw ] neg_cnt+1:"); - printf_touch_baseline_read("[base] neg_cnt+1:"); - - int test_cnt = 2; - while (test_cnt--) { - test_touch_push_all(); - /* Fake the process of push debounce. */ - test_touch_measure_step(filter_info.debounce_cnt + 1); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - - test_touch_release_all(); - /* Fake the process of release debounce. */ - test_touch_measure_step(filter_info.debounce_cnt + 1); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -esp_err_t test_touch_filter_parameter_jitter(int jitter_step) -{ - uint32_t touch_value, base_value = 0; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - jitter_step = ((jitter_step < 0) ? 4 : jitter_step); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_JITTER, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = jitter_step, // use for jitter mode. - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - /* Run to wait the data become stable. */ - test_touch_measure_step(20); // 2 scan loop - - /* Check the jitter step. */ - printf_touch_baseline_read("[smooth] t1:"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - test_touch_measure_step(1); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - test_push_fake(touch_list[i]); - test_touch_measure_step(1); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); - TEST_ASSERT_EQUAL_UINT32(jitter_step, (base_value - touch_value)); - } - printf_touch_baseline_read("[smooth] t2:"); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - test_touch_measure_step(1); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - test_release_fake(touch_list[i]); - test_touch_measure_step(1); - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &base_value) ); - TEST_ASSERT_EQUAL_UINT32(jitter_step, (touch_value - base_value)); - } - printf_touch_baseline_read("[smooth] t3:"); - - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - //read baseline value - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - //set interrupt threshold. - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, thresh %d", \ - touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - int test_cnt = 2; - while (test_cnt--) { - test_touch_push_all(); - /* Fake the process of push debounce. */ - test_touch_measure_step(filter_info.debounce_cnt + 1); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_smooth_read("push"); - - test_touch_release_all(); - /* Fake the process of release debounce. */ - test_touch_measure_step(filter_info.debounce_cnt + 1); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_smooth_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor filter paramter test (debounce, neg_reset, jitter)", "[touch]") -{ - ESP_LOGI(TAG, "*********** touch filter debounce test ********************"); - TEST_ESP_OK( test_touch_filter_parameter_debounce(0) ); - TEST_ESP_OK( test_touch_filter_parameter_debounce(3) ); - TEST_ESP_OK( test_touch_filter_parameter_debounce(7) ); - - ESP_LOGI(TAG, "*********** touch filter neg threshold reset limit test ********************"); - TEST_ESP_OK( test_touch_filter_parameter_neg_reset(1) ); - TEST_ESP_OK( test_touch_filter_parameter_neg_reset(5) ); - TEST_ESP_OK( test_touch_filter_parameter_neg_reset(15) ); - - ESP_LOGI(TAG, "*********** touch filter jitter test ********************"); - TEST_ESP_OK( test_touch_filter_parameter_jitter(1) ); - TEST_ESP_OK( test_touch_filter_parameter_jitter(5) ); - TEST_ESP_OK( test_touch_filter_parameter_jitter(15) ); -} - -esp_err_t test_touch_denoise(uint32_t out_val[], uint32_t *denoise_val, touch_pad_denoise_grade_t grade, touch_pad_denoise_cap_t cap) -{ - uint32_t touch_value; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - ESP_LOGI(TAG, "Denoise level (%d), cap level (%d) \n", grade, cap); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = (grade < 0) ? TOUCH_PAD_DENOISE_BIT4 : grade, - .cap_level = (cap < 0) ? TOUCH_PAD_DENOISE_CAP_L4 : cap, - }; - TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); - TEST_ESP_OK( touch_pad_denoise_enable() ); - ESP_LOGI(TAG, "Denoise function init"); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - /* Run to wait the data become stable. */ - test_touch_measure_step(20); // 2 scan loop - - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - if (out_val) { - /* Output value for check. */ - out_val[i] = touch_value; - } - } - printf_touch_baseline_read("Denoise"); - if (denoise_val) { - touch_pad_denoise_read_data(denoise_val); - } - - int test_cnt = 1; - while (test_cnt--) { - test_touch_push_all(); - /* Fake the process of push debounce. */ - test_touch_measure_step(filter_info.debounce_cnt + 1); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - - test_touch_release_all(); - /* Fake the process of release debounce. */ - test_touch_measure_step(filter_info.debounce_cnt + 1); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor denoise test (cap, level)", "[touch]") -{ - uint32_t val_1[TEST_TOUCH_CHANNEL]; - uint32_t val_2[TEST_TOUCH_CHANNEL]; - uint32_t val_3[TEST_TOUCH_CHANNEL]; - uint32_t denoise_val[TOUCH_PAD_DENOISE_CAP_MAX]; - - ESP_LOGI(TAG, "*********** touch filter denoise level test ********************"); - TEST_ESP_OK( test_touch_denoise(val_1, NULL, TOUCH_PAD_DENOISE_BIT4, TOUCH_PAD_DENOISE_CAP_L0) ); - TEST_ESP_OK( test_touch_denoise(val_2, NULL, TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L0) ); - TEST_ESP_OK( test_touch_denoise(val_3, NULL, TOUCH_PAD_DENOISE_BIT12, TOUCH_PAD_DENOISE_CAP_L0) ); - - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ASSERT_GREATER_OR_EQUAL(val_3[i], val_2[i]); - TEST_ASSERT_GREATER_OR_EQUAL(val_2[i], val_1[i]); - } - - ESP_LOGI(TAG, "*********** touch filter denoise cap level test ********************"); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[0], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L0) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[1], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L1) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[2], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L2) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[3], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L3) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[4], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L4) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[5], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L5) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[6], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L6) ); - TEST_ESP_OK( test_touch_denoise(NULL, &denoise_val[7], TOUCH_PAD_DENOISE_BIT8, TOUCH_PAD_DENOISE_CAP_L7) ); - - printf("denoise read: "); - for (int i = 0; i < TOUCH_PAD_DENOISE_CAP_MAX - 1; i++) { - TEST_ASSERT_GREATER_OR_EQUAL(denoise_val[i], denoise_val[i + 1]); - printf("%d ", denoise_val[i]); - } - printf("\n"); -} - -esp_err_t test_touch_waterproof(void) -{ - uint32_t touch_value; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); - TEST_ESP_OK( touch_pad_denoise_enable() ); - ESP_LOGI(TAG, "Denoise function init"); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - /* Waterproof function */ - touch_pad_waterproof_t waterproof = { - .guard_ring_pad = TOUCH_WATERPROOF_RING_PAD, // If no ring pad, set 0; - /* It depends on the number of the parasitic capacitance of the shield pad. */ - .shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf - }; - TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); - TEST_ESP_OK( touch_pad_waterproof_enable() ); - ESP_LOGI(TAG, "touch pad waterproof init"); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - vTaskDelay(50 / portTICK_PERIOD_MS); - - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - } - - while (test_cnt--) { - test_touch_push_all(); - vTaskDelay(20 / portTICK_PERIOD_MS); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL - 1, TOUCH_EXCEED_TIME_MS) ); // take off shield pad - printf_touch_hw_read("push"); - - test_touch_release_all(); - vTaskDelay(20 / portTICK_PERIOD_MS); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor waterproof guard test", "[touch]") -{ - ESP_LOGI(TAG, "*********** touch filter waterproof guard test ********************"); - TEST_ESP_OK( test_touch_waterproof() ); -} - -esp_err_t test_touch_proximity(int meas_num) -{ - ESP_LOGI(TAG, " >> %s << \n", __func__); - - uint32_t touch_value; - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); - TEST_ESP_OK( touch_pad_denoise_enable() ); - ESP_LOGI(TAG, "Denoise function init"); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - /* Waterproof function */ - touch_pad_waterproof_t waterproof = { - .guard_ring_pad = TOUCH_WATERPROOF_RING_PAD,// If no ring pad, set 0; - /* It depends on the number of the parasitic capacitance of the shield pad. */ - .shield_driver = TOUCH_PAD_SHIELD_DRV_L0, //40pf - }; - TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); - TEST_ESP_OK( touch_pad_waterproof_enable() ); - ESP_LOGI(TAG, "touch pad waterproof init"); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - vTaskDelay(50 / portTICK_PERIOD_MS); - - touch_pad_proximity_t proximity = { - .select_pad[0] = proximity_pad[0], - .select_pad[1] = proximity_pad[1], - .select_pad[2] = proximity_pad[2], - .meas_num = meas_num < 0 ? 16 : meas_num, - }; - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - if (touch_list[i] == proximity.select_pad[0] || - touch_list[i] == proximity.select_pad[1] || - touch_list[i] == proximity.select_pad[2]) { - /* The threshold of proximity pad is the sum of touch reading `meas_num` times */ - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], - proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)) ); - ESP_LOGI(TAG, "proximity pad [%d] base %d, thresh %d", touch_list[i], touch_value, - (uint32_t)(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); - } else { - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "touch pad [%d] base %d, thresh %d", \ - touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - } - /* Should stop the measure, then change the config. */ - while (!touch_pad_meas_is_done()); - TEST_ESP_OK( touch_pad_fsm_stop() ); - /* Proximity function */ - TEST_ESP_OK( touch_pad_proximity_set_config(&proximity) ); - ESP_LOGI(TAG, "touch pad proximity init"); - TEST_ESP_OK( touch_pad_fsm_start() ); - - vTaskDelay(20 / portTICK_PERIOD_MS); - int test_cnt = TEST_TOUCH_COUNT_NUM; - while (test_cnt--) { - test_touch_push_all(); - vTaskDelay(20 / portTICK_PERIOD_MS); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL - 1, TOUCH_EXCEED_TIME_MS) ); // take off shield pad - printf_touch_hw_read("push"); - - test_touch_release_all(); - vTaskDelay(20 / portTICK_PERIOD_MS); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ESP_OK; -} - -TEST_CASE("Touch Sensor proximity test", "[touch]") -{ - ESP_LOGI(TAG, "*********** touch proximity test ********************"); - - TEST_ESP_OK( test_touch_proximity(5) ); - TEST_ESP_OK( test_touch_proximity(1) ); -} - -esp_err_t test_touch_sleep_reading_stable(touch_pad_t sleep_pad) -{ - uint32_t touch_temp = 0; - uint32_t touch_value, smooth, ret_val; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - // /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); - TEST_ESP_OK( touch_pad_denoise_enable() ); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_OFF, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - touch_pad_sleep_channel_t slp_config = { - .touch_num = sleep_pad, - .en_proximity = false, - }; - TEST_ESP_OK( touch_pad_sleep_channel_set_config(&slp_config) ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - // Initialize and start a software filter to detect slight change of capacitance. - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - /* Set threshold of touch sensor */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - /* Sleep channel setting */ - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); - TEST_ESP_OK( touch_pad_sleep_set_threshold(touch_value * TOUCH_INTR_THRESHOLD) ); - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - while (test_cnt--) { - /* Touch reading filtered value equal to raw data. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_sleep_channel_read_data(&touch_value) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_temp) ); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&touch_temp) ); - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); - } - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if (touch_temp) { - TEST_ASSERT_UINT32_WITHIN(TOUCH_READ_ERROR, touch_temp, touch_value); - } - touch_temp = touch_value; - } - vTaskDelay(20 / portTICK_PERIOD_MS); - } - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&ret_val) ); - - TEST_ESP_OK( touch_pad_deinit() ); - - return ret_val; -} - - -TEST_CASE("Touch Sensor sleep pad reading stable test", "[touch]") -{ - ESP_LOGI(TAG, "*********** touch sleep pad low power (wakeup) test ********************"); - test_touch_sleep_reading_stable(touch_list[0]); -} - -/* - * Test the touch sleep pad interrupt in normal mode. - * TEST POINT: - * 1. Touch sleep pad interrupt. - * 2. sleep pad reading. - * 3. sleep pad enable proximity. - */ -uint32_t test_touch_sleep_pad_proximity(touch_pad_t sleep_pad, bool is_proximity, uint32_t meas_num) -{ - uint32_t touch_value, smooth, ret_val, dbc; - uint32_t measure_out; - uint32_t proximity_cnt; - uint32_t touch_thres; - int test_cnt = TEST_TOUCH_COUNT_NUM; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); - TEST_ESP_OK( touch_pad_denoise_enable() ); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_OFF, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Sleep channel setting */ - touch_pad_sleep_channel_t slp_config = { - .touch_num = sleep_pad, - .en_proximity = is_proximity, - }; - TEST_ESP_OK( touch_pad_sleep_channel_set_config(&slp_config) ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_SCAN_DONE | TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - // Initialize and start a software filter to detect slight change of capacitance. - vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - if (is_proximity) { - touch_pad_proximity_t proximity = { - .select_pad[0] = sleep_pad, - .select_pad[1] = 0, - .select_pad[2] = 0, - .meas_num = meas_num == 0 ? 16 : meas_num, - }; - /* Set the threshold. */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - if (touch_list[i] == sleep_pad) { - touch_pad_sleep_channel_read_smooth(&touch_value); - touch_pad_sleep_set_threshold(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)); - ESP_LOGI(TAG, "Sleep pad [%d] base %d, thresh %d", touch_list[i], touch_value, - (uint32_t)(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); - } else if (touch_list[i] == proximity.select_pad[0] || - touch_list[i] == proximity.select_pad[1] || - touch_list[i] == proximity.select_pad[2]) { - // TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - touch_pad_sleep_channel_read_smooth(&touch_value); - /* The threshold of proximity pad is the sum of touch reading `meas_num` times */ - touch_pad_sleep_set_threshold( proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD)); - ESP_LOGI(TAG, "proximity pad [%d] base %d, thresh %d", touch_list[i], touch_value, - (uint32_t)(proximity.meas_num * touch_value * (1 + TOUCH_INTR_THRESHOLD))); - } else { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "touch pad [%d] base %d, thresh %d", \ - touch_list[i], touch_value, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - } - /* Should stop the measure, then change the config. */ - while (!touch_pad_meas_is_done()); - TEST_ESP_OK( touch_pad_fsm_stop() ); - /* Proximity function */ - TEST_ESP_OK( touch_pad_proximity_set_config(&proximity) ); - ESP_LOGI(TAG, "touch pad proximity init"); - TEST_ESP_OK( touch_pad_fsm_start() ); - vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - } else { - /* Set threshold of touch sensor */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - /* Sleep channel setting */ - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&touch_value) ); - TEST_ESP_OK( touch_pad_sleep_set_threshold(touch_value * TOUCH_INTR_THRESHOLD) ); - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - } - - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&ret_val) ); - - while (test_cnt--) { - test_touch_push_all(); - TEST_ESP_OK( test_touch_check_ch_touched_with_proximity(TEST_TOUCH_CHANNEL, 5000) ); - printf_touch_hw_read("push"); - if (is_proximity) { - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); - TEST_ESP_OK( touch_pad_proximity_data_get(sleep_pad, &measure_out) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_proximity_cnt(&proximity_cnt) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_debounce(&dbc) ); - TEST_ESP_OK( touch_pad_sleep_get_threshold(&touch_thres) ); - printf("touch slp smooth %d, base %d, proxi %d cnt %d dbc %d thres%d status 0x%x\n", - smooth, touch_value, measure_out, proximity_cnt, dbc, - touch_thres, touch_pad_get_status()); - } - test_touch_release_all(); - TEST_ESP_OK( test_touch_check_ch_released_with_proximity(TEST_TOUCH_CHANNEL, 5000) ); - printf_touch_hw_read("release"); - if (is_proximity) { - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); - TEST_ESP_OK( touch_pad_proximity_data_get(sleep_pad, &measure_out) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_proximity_cnt(&proximity_cnt) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_debounce(&dbc) ); - printf("touch slp smooth %d, base %d, proxi %d cnt %d dbc %d status 0x%x\n", - smooth, touch_value, measure_out, proximity_cnt, dbc, touch_pad_get_status()); - } - } - - TEST_ESP_OK( touch_pad_deinit() ); - - return ret_val; -} - -TEST_CASE("Touch Sensor sleep pad and proximity interrupt test", "[touch]") -{ - ESP_LOGI(TAG, "*********** touch sleep pad interrupt test ********************"); - test_touch_sleep_pad_proximity(touch_list[0], false, 0); - test_touch_sleep_pad_proximity(touch_list[0], false, 0); - test_touch_sleep_pad_proximity(touch_list[0], false, 0); - - ESP_LOGI(TAG, "*********** touch sleep pad interrupt (proximity) test ********************"); - test_touch_sleep_pad_proximity(touch_list[0], true, 1); - test_touch_sleep_pad_proximity(touch_list[0], true, 3); - test_touch_sleep_pad_proximity(touch_list[0], true, 5); -} - -/* - * Test the touch sleep pad interrupt in normal mode. - * TEST POINT: - * 1. Touch sleep pad interrupt. - * 2. sleep pad reading. - * 3. denoise, waterproof - */ -esp_err_t test_touch_sleep_pad_interrupt_wakeup_deep_sleep(touch_pad_t sleep_pad) -{ - uint32_t touch_value, smooth, raw; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - TEST_ESP_OK( touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL) ); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - // /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - TEST_ESP_OK( touch_pad_denoise_set_config(&denoise) ); - TEST_ESP_OK( touch_pad_denoise_disable() ); - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 3, // 0% - .noise_thr = 0, // 50% - .noise_neg_thr = 0, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_OFF, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Sleep channel setting */ - touch_pad_sleep_channel_t slp_config = { - .touch_num = sleep_pad, - .en_proximity = false, - }; - TEST_ESP_OK( touch_pad_sleep_channel_set_config(&slp_config) ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - - // Initialize and start a software filter to detect slight change of capacitance. - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - /* Set threshold of touch sensor */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_INTR_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_INTR_THRESHOLD)); - } - - /* Sleep channel setting */ - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); - TEST_ESP_OK( touch_pad_sleep_set_threshold(touch_value * TOUCH_INTR_THRESHOLD) ); - - vTaskDelay(50 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - test_touch_push_all(); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_data(&raw) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); - printf("touch slp raw %d, smooth %d, base %d, status 0x%x\n", raw, smooth, touch_value, touch_pad_get_status()); - - test_touch_release_all(); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - TEST_ESP_OK( touch_pad_sleep_channel_read_smooth(&smooth) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_data(&raw) ); - TEST_ESP_OK( touch_pad_sleep_channel_read_baseline(&touch_value) ); - printf("touch slp raw %d, smooth %d, base %d, status 0x%x\n", raw, smooth, touch_value, touch_pad_get_status()); - - return ESP_OK; -} - -#include -#include "esp_sleep.h" - -static RTC_DATA_ATTR struct timeval sleep_enter_time; - -static void test_deep_sleep_init(void) -{ - struct timeval now; - gettimeofday(&now, NULL); - int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; - printf("RTC_CNTL_SLP_WAKEUP_CAUSE_REG %x\n", REG_READ(RTC_CNTL_SLP_WAKEUP_CAUSE_REG)); - switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_EXT1: { - uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); - if (wakeup_pin_mask != 0) { - int pin = __builtin_ffsll(wakeup_pin_mask) - 1; - printf("Wake up from GPIO %d\n", pin); - } else { - printf("Wake up from GPIO\n"); - } - break; - } - case ESP_SLEEP_WAKEUP_TIMER: { - printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms); - break; - } - case ESP_SLEEP_WAKEUP_TOUCHPAD: { - printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status()); - break; - } - case ESP_SLEEP_WAKEUP_UNDEFINED: - default: { - printf("Not a deep sleep reset\n"); - ESP_LOGI(TAG, "*********** touch sleep pad wakeup test ********************"); - /* Sleep pad should be init once. */ - test_touch_sleep_pad_interrupt_wakeup_deep_sleep(touch_list[0]); - } - } - - vTaskDelay(100 * SYS_DELAY_TIME_MOM / portTICK_PERIOD_MS); - - // const int wakeup_time_sec = 10; - // printf("Enabling timer wakeup, %ds\n", wakeup_time_sec); - // esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000); - - // const int ext_wakeup_pin_1 = 2; - // const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; - // const int ext_wakeup_pin_2 = 4; - // const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2; - - // printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2); - // esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH); - - printf("Enabling touch pad wakeup\n"); - esp_sleep_enable_touchpad_wakeup(); - // esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - - printf("Entering deep sleep\n"); - gettimeofday(&sleep_enter_time, NULL); -} - -// TEST_CASE("Touch Sensor sleep pad wakeup deep sleep test", "[touch]") -void test_touch_sleep_wakeup(void) -{ - test_deep_sleep_init(); - - /* Change the work duty of touch sensor to reduce current. */ - touch_pad_set_meas_time(100, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); - - /* Close PD current in deep sleep. */ - RTCCNTL.bias_conf.pd_cur_deep_slp = 1; - RTCCNTL.bias_conf.pd_cur_monitor = 1; - RTCCNTL.bias_conf.bias_sleep_deep_slp = 1; - RTCCNTL.bias_conf.bias_sleep_monitor = 1; - - esp_deep_sleep_start(); -} - -#include "touch_scope.h" -/* - * 0: 10 channels raw/smooth/baseline data debug. - * 1: 5 channges smooth + baseline data debug. - * 2: 1 channels filter data. - */ -#define SCOPE_DEBUG_TYPE 2 -#define TOUCH_THRESHOLD 0.5 -#define TOUCH_SHELD_PAD (1) -#define SCOPE_DEBUG_CHANNEL_MAX (10) -#define SCOPE_DEBUG_ENABLE (0) -#define SCOPE_UART_BUADRATE (256000) -#define SCOPE_DEBUG_FREQ_MS (50) - -void test_touch_slope_debug(int pad_num) -{ - touch_event_t evt; - uint32_t touch_value, smooth; - - ESP_LOGI(TAG, " >> %s << \n", __func__); - if (que_touch == NULL) { - que_touch = xQueueCreate(TEST_TOUCH_CHANNEL, sizeof(touch_event_t)); - /* Should register once. */ - touch_pad_isr_register(test_touch_intr_cb, NULL, TOUCH_PAD_INTR_MASK_ALL); - } else { - xQueueReset(que_touch); - } - TEST_ESP_OK( touch_pad_init() ); - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_config(touch_list[i]) ); - } - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_32, // Test jitter and filter 1/4. - .debounce_cnt = 1, // 1 time count. - .hysteresis_thr = 2, // 6.25% - .noise_thr = 3, // 50% - .noise_neg_thr = 3, // 50% - .neg_noise_limit = 10, // 10 time count. - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - TEST_ESP_OK( touch_pad_filter_set_config(&filter_info) ); - TEST_ESP_OK( touch_pad_filter_enable() ); - /* Register touch interrupt ISR, enable intr type. */ - TEST_ESP_OK( touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE) ); - TEST_ESP_OK( touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER) ); - TEST_ESP_OK( touch_pad_fsm_start() ); - /* Waterproof function */ - touch_pad_waterproof_t waterproof = { - .guard_ring_pad = 0, // If no ring pad, set 0; - /* It depends on the number of the parasitic capacitance of the shield pad. */ - .shield_driver = TOUCH_PAD_SHIELD_DRV_L2, //40pf - }; - TEST_ESP_OK( touch_pad_waterproof_set_config(&waterproof) ); - TEST_ESP_OK( touch_pad_waterproof_enable() ); - ESP_LOGI(TAG, "touch pad waterproof init"); - - // Initialize and start a software filter to detect slight change of capacitance. - vTaskDelay(50 / portTICK_PERIOD_MS); - - /* Set threshold of touch sensor */ - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - TEST_ESP_OK( touch_pad_filter_read_baseline(touch_list[i], &touch_value) ); - TEST_ESP_OK( touch_pad_filter_read_smooth(touch_list[i], &smooth) ); - TEST_ESP_OK( touch_pad_set_thresh(touch_list[i], touch_value * TOUCH_THRESHOLD) ); - ESP_LOGI(TAG, "test init: touch pad [%d] base %d, smooth %d, thresh %d", \ - touch_list[i], touch_value, smooth, (uint32_t)(touch_value * TOUCH_THRESHOLD)); - } - - float scope_temp[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. - uint32_t scope_data[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. - test_tp_scope_debug_init(0, -1, -1, SCOPE_UART_BUADRATE); - -#if SCOPE_DEBUG_TYPE == 0 - while (1) { - for (int i = 0; i < TEST_TOUCH_CHANNEL; i++) { - touch_pad_read_raw_data(touch_list[i], &scope_data[i]); - // touch_pad_filter_read_smooth(touch_list[i], &scope_data[i]); - // touch_pad_filter_read_baseline(touch_list[i], &scope_data[i]); - scope_temp[i] = scope_data[i]; - } - test_tp_print_to_scope(scope_temp, TEST_TOUCH_CHANNEL); - vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); - } -#elif SCOPE_DEBUG_TYPE == 1 - while (1) { - int cnt = 0; - for (int i = 0; i < 5; i++) { - touch_pad_read_raw_data(touch_list[i], &scope_data[i]); - scope_temp[i] = scope_data[i]; - } - for (int i = 0; i < 5; i++) { - touch_pad_filter_read_smooth(touch_list[i], &scope_data[i]); - scope_temp[i + SCOPE_DEBUG_CHANNEL_MAX / 2] = scope_data[i]; - } - test_tp_print_to_scope(scope_temp, SCOPE_DEBUG_CHANNEL_MAX); - vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); - } -#elif SCOPE_DEBUG_TYPE == 2 - uint32_t status; - touch_pad_filter_read_baseline(pad_num, &status); - while (1) { - xQueueReceive(que_touch, &evt, SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); - //read filtered value - touch_pad_read_raw_data(pad_num, &scope_data[0]); - touch_pad_filter_read_baseline(pad_num, &scope_data[1]); - touch_pad_get_thresh(pad_num, &scope_data[2]); - touch_pad_filter_read_smooth(pad_num, &scope_data[8]); - // raw data - scope_temp[0] = scope_data[0]; - // baseline - scope_temp[1] = scope_data[1]; - // smooth data - scope_temp[8] = scope_data[8]; - // noise neg thr - scope_temp[2] = scope_temp[1] - scope_data[2] * 0.5; - // noise thr - scope_temp[3] = scope_temp[1] + scope_data[2] * 0.5; - // touch thr - scope_temp[4] = scope_temp[1] + scope_data[2]; - // hysteresis_thr thr - scope_temp[5] = scope_temp[4] - scope_data[2] * 0.0625; - // hysteresis_thr thr - scope_temp[6] = scope_temp[4] + scope_data[2] * 0.0625; - // touch status - if (touch_pad_get_status() & BIT(pad_num)) { - scope_temp[7] = status + 100; - } else { - scope_temp[7] = status - 100; //0:release; 1:push; - } - test_tp_print_to_scope(scope_temp, 9); - } -#elif SCOPE_DEBUG_TYPE == 3 - while (1) { - test_touch_push_all(); - TEST_ESP_OK( test_touch_check_ch_touched(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("push"); - - /* Test: if the raw data exceed noise threshold, the baseline should not be updated. */ - test_touch_baseline_not_update(); - - test_touch_release_all(); - TEST_ESP_OK( test_touch_check_ch_released(TEST_TOUCH_CHANNEL, TOUCH_EXCEED_TIME_MS) ); - printf_touch_hw_read("release"); - } -#endif - TEST_ESP_OK( touch_pad_deinit() ); -} \ No newline at end of file diff --git a/components/driver/test/esp32s2/touch_scope.c b/components/driver/test/esp32s2/touch_scope.c deleted file mode 100644 index cc9a4d375..000000000 --- a/components/driver/test/esp32s2/touch_scope.c +++ /dev/null @@ -1,186 +0,0 @@ -#include "esp_err.h" -#include "driver/uart.h" -#include "esp32s2/rom/uart.h" - -#define ROM_UART_DRIVER_ENABLE 0 - -#if ROM_UART_DRIVER_ENABLE -static uint8_t scope_uart_num = 0; -static int8_t uart_used = 0; -#else -static uint8_t scope_uart_num = 255; -static int8_t uart_used = -1; -#endif -static int scope_tx_io_num = 0; -static int scope_rx_io_num = 0; -static int scope_debug_baud_rate = 256000; -static unsigned char datascope_output_buffer[42] = {0}; // Data buff. - -/** - * @brief Translate a float data to four unsigned char data for uart TX. - * @param target target float data address. - * @param buf save translated data. - * @param offset the start position in buf. - * @return - * - void - */ -static void Float2Byte(float *target, unsigned char *buf, unsigned char offset) -{ - unsigned char *point; - point = (unsigned char*)target; //Get the address of float. - buf[offset] = point[0]; - buf[offset+1] = point[1]; - buf[offset+2] = point[2]; - buf[offset+3] = point[3]; -} - -/** - * @brief Add data to channal buff. - * @param Data target data. - * @param Channel target channel (1 - 10). - * @return - * - void - */ -static void datascope_get_channel_data(float data, unsigned char channel) -{ - if ( (channel > 10) || (channel == 0) ) { - return; - } else { - switch (channel) { - case 1: Float2Byte(&data,datascope_output_buffer,1); break; - case 2: Float2Byte(&data,datascope_output_buffer,5); break; - case 3: Float2Byte(&data,datascope_output_buffer,9); break; - case 4: Float2Byte(&data,datascope_output_buffer,13); break; - case 5: Float2Byte(&data,datascope_output_buffer,17); break; - case 6: Float2Byte(&data,datascope_output_buffer,21); break; - case 7: Float2Byte(&data,datascope_output_buffer,25); break; - case 8: Float2Byte(&data,datascope_output_buffer,29); break; - case 9: Float2Byte(&data,datascope_output_buffer,33); break; - case 10: Float2Byte(&data,datascope_output_buffer,37); break; - } - } -} - -/** - * @brief Transform float data to DataScopeV1.0 data format. - * @param channel_num the number of channel that wait to be translated. - * @return - * - The number of the UART TX data. - */ -static unsigned char datascope_data_generate(unsigned char channel_num) -{ - if ( (channel_num > 10) || (channel_num == 0) ) { - return 0; - } else { - datascope_output_buffer[0] = '$'; //frame header - switch(channel_num) { - case 1: datascope_output_buffer[5] = 5; return 6; break; - case 2: datascope_output_buffer[9] = 9; return 10; break; - case 3: datascope_output_buffer[13] = 13; return 14; break; - case 4: datascope_output_buffer[17] = 17; return 18; break; - case 5: datascope_output_buffer[21] = 21; return 22; break; - case 6: datascope_output_buffer[25] = 25; return 26; break; - case 7: datascope_output_buffer[29] = 29; return 30; break; - case 8: datascope_output_buffer[33] = 33; return 34; break; - case 9: datascope_output_buffer[37] = 37; return 38; break; - case 10: datascope_output_buffer[41] = 41; return 42; break; - } - } - return 0; -} - -/** - * @brief Send touch sensor data to HMI in PC via UART. - * @param uart_num Choose uart port (0, 1, 2). - * @param data The addr of the touch sensor data. - * @param channel_num The number of channel that wait to be translated. - * @return - * - ESP_FAIL Error - * - The number of the UART TX data. - */ -int test_tp_print_to_scope(float *data, unsigned char channel_num) -{ - uint8_t uart_num = scope_uart_num; - - if (uart_num >= UART_NUM_MAX) { - return ESP_FAIL; - } - if ( (channel_num > 10) || (channel_num == 0) || (NULL == data) ) { - return ESP_FAIL; - } - for(uint8_t i = 0 ; i < channel_num; i++) { - datascope_get_channel_data(data[i] , i+1); // write data x into channel 1~10. - } - unsigned char out_len = datascope_data_generate(channel_num); // Generate n number data. - unsigned char *out_data = datascope_output_buffer; - // Init uart. - if(uart_num != uart_used) { - return 0; - } else { -#if ROM_UART_DRIVER_ENABLE - uart_tx_wait_idle(uart_num); // Default print uart mumber is 0. - for(int i=0; i= UART_NUM_MAX) { - return ESP_FAIL; - } - scope_uart_num = uart_num; - scope_tx_io_num = tx_io_num; - scope_rx_io_num = rx_io_num; - scope_debug_baud_rate = baud_rate; - uart_config_t uart_config = { - .baud_rate = scope_debug_baud_rate, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - }; - uart_param_config(uart_num, &uart_config); - // Set UART pins using UART0 default pins i.e. no changes - uart_set_pin(uart_num, scope_tx_io_num, scope_rx_io_num, - UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - uart_driver_install(uart_num, 1024, 2048, 0, NULL, 0); - uart_used = uart_num; -#endif - return ESP_OK; -} diff --git a/components/driver/test/esp32s2/touch_scope.h b/components/driver/test/esp32s2/touch_scope.h deleted file mode 100644 index 936d6ada2..000000000 --- a/components/driver/test/esp32s2/touch_scope.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -int test_tp_print_to_scope(float *data, unsigned char channel_num); -esp_err_t test_tp_scope_debug_init(uint8_t uart_num, int tx_io_num, int rx_io_num, int baud_rate); \ No newline at end of file diff --git a/components/driver/test/test_adc2.c b/components/driver/test/test_adc2_with_wifi.c similarity index 65% rename from components/driver/test/test_adc2.c rename to components/driver/test/test_adc2_with_wifi.c index e7194b9f2..080d05eef 100644 --- a/components/driver/test/test_adc2.c +++ b/components/driver/test/test_adc2_with_wifi.c @@ -12,10 +12,23 @@ #include "nvs_flash.h" #include "test_utils.h" -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) - static const char* TAG = "test_adc2"; +#ifdef CONFIG_IDF_TARGET_ESP32 + #define ADC_TEST_WIDTH ADC_WIDTH_BIT_12 + #define ADC_TEST_RESOLUTION (4096) + #define ADC_TEST_DAC_RANGE (256) + #define ADC_TEST_CH1 ADC2_CHANNEL_8 + #define ADC_TEST_CH2 ADC2_CHANNEL_9 + #define ADC_TEST_ERROR (600) +#elif defined CONFIG_IDF_TARGET_ESP32S2 + #define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width + #define ADC_TEST_RESOLUTION (8192) + #define ADC_TEST_DAC_RANGE (210) + #define ADC_TEST_CH1 ADC2_CHANNEL_6 + #define ADC_TEST_CH2 ADC2_CHANNEL_7 + #define ADC_TEST_ERROR (1500) +#endif #define DEFAULT_SSID "TEST_SSID" #define DEFAULT_PWD "TEST_PASS" @@ -84,9 +97,8 @@ TEST_CASE("adc2 work with wifi","[adc]") TEST_ESP_OK( dac_output_enable( DAC_CHANNEL_2 )); TEST_ESP_OK( dac_output_voltage( DAC_CHANNEL_1, 30 )); TEST_ESP_OK( dac_output_voltage( DAC_CHANNEL_2, 60 )); - TEST_ESP_OK( adc2_config_channel_atten( ADC2_CHANNEL_8, ADC_ATTEN_0db )); - TEST_ESP_OK( adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_0db )); - + TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CH1, ADC_ATTEN_0db )); + TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CH2, ADC_ATTEN_0db )); //init wifi printf("nvs init\n"); esp_err_t r = nvs_flash_init(); @@ -112,23 +124,26 @@ TEST_CASE("adc2 work with wifi","[adc]") TEST_ESP_OK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); //test read value - TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw )); - target_value = 30*4096*3/256; //3 = 3.3/1.1 + TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw )); + target_value = 30*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE; //3 = 3.3/1.1 printf("dac set: %d, adc read: %d (target_value: %d)\n", 30, read_raw, target_value ); - TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); - TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw )); - target_value = 60*4096*3/256; + TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw ); + TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw )); + target_value = 60*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE; printf("dac set: %d, adc read: %d (target_value: %d)\n", 60, read_raw, target_value ); - TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); + TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw ); //now start wifi printf("wifi start...\n"); TEST_ESP_OK(esp_wifi_start()); - //test reading during wifi on - TEST_ASSERT_EQUAL( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw ), ESP_ERR_TIMEOUT ); - TEST_ASSERT_EQUAL( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw ), ESP_ERR_TIMEOUT ); - +#ifdef CONFIG_IDF_TARGET_ESP32 + TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw ), ESP_ERR_TIMEOUT ); + TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw ), ESP_ERR_TIMEOUT ); +#elif defined CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw ), ESP_OK ); + TEST_ASSERT_EQUAL( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw ), ESP_OK ); +#endif //wifi stop again printf("wifi stop...\n"); TEST_ESP_OK( esp_wifi_stop() ); @@ -137,18 +152,16 @@ TEST_CASE("adc2 work with wifi","[adc]") nvs_flash_deinit(); //test read value - TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw )); - target_value = 30*4096*3/256; //3 = 3.3/1.1 + TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH1, ADC_TEST_WIDTH, &read_raw )); + target_value = 30*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE; //3 = 3.3/1.1 printf("dac set: %d, adc read: %d (target_value: %d)\n", 30, read_raw, target_value ); - TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); - TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw )); - target_value = 60*4096*3/256; + TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw ); + TEST_ESP_OK( adc2_get_raw( ADC_TEST_CH2, ADC_TEST_WIDTH, &read_raw )); + target_value = 60*ADC_TEST_RESOLUTION*3/ADC_TEST_DAC_RANGE; printf("dac set: %d, adc read: %d (target_value: %d)\n", 60, read_raw, target_value ); - TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); + TEST_ASSERT_INT_WITHIN( ADC_TEST_ERROR, target_value, read_raw ); printf("test passed...\n"); TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop."); } - -#endif diff --git a/components/driver/test/test_adc_common.c b/components/driver/test/test_adc_common.c new file mode 100644 index 000000000..29122b15b --- /dev/null +++ b/components/driver/test/test_adc_common.c @@ -0,0 +1,266 @@ +/* + Tests for the adc device driver +*/ +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" +#include "soc/adc_periph.h" + +static const char *TAG = "test_adc"; + +#ifdef CONFIG_IDF_TARGET_ESP32 +#define ADC1_TEST_WIDTH ADC_WIDTH_BIT_12 +#define ADC2_TEST_WIDTH ADC_WIDTH_BIT_12 +#elif defined CONFIG_IDF_TARGET_ESP32S2 +#define ADC1_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width +#define ADC2_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width +#endif + +#define ADC1_TEST_ATTEN ADC_ATTEN_DB_11 +#define ADC2_TEST_ATTEN ADC_ATTEN_DB_11 + +#define ADC1_TEST_CHANNEL_NUM 8 +#define ADC2_TEST_CHANNEL_NUM 6 + +static const int adc1_ch[ADC1_TEST_CHANNEL_NUM] = { + ADC1_CHANNEL_0, + ADC1_CHANNEL_1, + ADC1_CHANNEL_2, + ADC1_CHANNEL_3, + ADC1_CHANNEL_4, + ADC1_CHANNEL_5, + ADC1_CHANNEL_6, + ADC1_CHANNEL_7, +}; + +static const int adc2_ch[ADC2_TEST_CHANNEL_NUM] = { + ADC2_CHANNEL_0, + ADC2_CHANNEL_1, + ADC2_CHANNEL_2, + ADC2_CHANNEL_3, + ADC2_CHANNEL_4, + ADC2_CHANNEL_5, +}; + +#define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel]) + +static void adc_fake_tie_middle(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit & ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + } + if (adc_unit & ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + } + TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_PULLDOWN)); +} + +static void adc_fake_tie_high(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit & ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + } + if (adc_unit & ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + } + TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_ONLY)); +} + +static void adc_fake_tie_low(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit & ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + } + if (adc_unit & ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + } + TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLDOWN_ONLY)); +} + +static void adc_io_normal(adc_unit_t adc_unit, adc_channel_t channel) +{ + gpio_num_t gpio_num = 0; + if (adc_unit & ADC_UNIT_1) { + gpio_num = ADC_GET_IO_NUM(0, channel); + } + if (adc_unit & ADC_UNIT_2) { + gpio_num = ADC_GET_IO_NUM(1, channel); + } + TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); + TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); + TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); +} + +TEST_CASE("ADC1 rtc read", "[adc1]") +{ + int adc1_val[ADC1_TEST_CHANNEL_NUM] = {0}; + + /* adc1 Configure */ + adc1_config_width(ADC1_TEST_WIDTH); + ESP_LOGI(TAG, "ADC1 [CH - GPIO]:"); + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc1_config_channel_atten(adc1_ch[i], ADC1_TEST_ATTEN) ); + ESP_LOGI(TAG, "[CH%d - IO%d]:", adc1_ch[i], ADC_GET_IO_NUM(0, adc1_ch[i])); + } + printf("ADC tie normal read: "); + vTaskDelay(10 / portTICK_RATE_MS); + + /* adc Read */ + printf("ADC1: "); + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]); + printf("CH%d-%d ", adc1_ch[i], adc1_val[i]); + } + printf("\n"); + + /* tie high */ + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_high(ADC_UNIT_1, adc1_ch[i]); + } + printf("ADC tie high read: "); + vTaskDelay(50 / portTICK_RATE_MS); + /* adc Read */ + printf("ADC1: "); + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]); + printf("CH%d-%d ", adc1_ch[i], adc1_val[i]); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_EQUAL( adc1_val[i], 0x1fff ); +#endif + } + printf("\n"); + + /* tie low */ + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_low(ADC_UNIT_1, adc1_ch[i]); + } + printf("ADC tie low read: "); + vTaskDelay(50 / portTICK_RATE_MS); + /* adc Read */ + printf("ADC1: "); + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]); + printf("CH%d-%d ", adc1_ch[i], adc1_val[i]); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_INT_WITHIN( 100, 0, adc1_val[i] ); +#endif + } + printf("\n"); + + /* tie midedle */ + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_middle(ADC_UNIT_1, adc1_ch[i]); + } + printf("ADC tie mid read: "); + vTaskDelay(50 / portTICK_RATE_MS); + /* adc Read */ + printf("ADC1: "); + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]); + printf("CH%d-%d ", adc1_ch[i], adc1_val[i]); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_NOT_EQUAL( adc1_val[i], 0 ); +#endif + } + printf("\n"); + + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc_io_normal(ADC_UNIT_1, adc1_ch[i]); + } +} + +TEST_CASE("ADC2 rtc read", "[adc2]") +{ + int adc2_val[ADC2_TEST_CHANNEL_NUM] = {0}; + + /* adc2 Configure */ + ESP_LOGI(TAG, "ADC2 [CH - GPIO]:"); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc2_config_channel_atten(adc2_ch[i], ADC2_TEST_ATTEN) ); + ESP_LOGI(TAG, "[CH%d - IO%d]:", adc2_ch[i], ADC_GET_IO_NUM(1, adc2_ch[i])); + } + printf("ADC float read: "); + vTaskDelay(10 / portTICK_RATE_MS); + + /* adc Read */ + printf("ADC2: "); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) ); + printf("CH%d-%d ", adc2_ch[i], adc2_val[i]); + } + printf("\n"); + + /* tie high */ + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_high(ADC_UNIT_2, adc2_ch[i]); + } + printf("ADC tie high read: "); + vTaskDelay(10 / portTICK_RATE_MS); + /* adc Read */ + printf("ADC2: "); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) ); + printf("CH%d-%d ", adc2_ch[i], adc2_val[i]); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_EQUAL( adc2_val[i], 0x1fff ); +#endif + } + printf("\n"); + + /* tie low */ + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_low(ADC_UNIT_2, adc2_ch[i]); + } + printf("ADC tie low read: "); + vTaskDelay(10 / portTICK_RATE_MS); + /* adc Read */ + printf("ADC2: "); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) ); + printf("CH%d-%d ", adc2_ch[i], adc2_val[i]); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_INT_WITHIN( 100, 0, adc2_val[i] ); +#endif + } + printf("\n"); + + /* tie midedle */ + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_middle(ADC_UNIT_2, adc2_ch[i]); + } + printf("ADC tie middle read: "); + vTaskDelay(10 / portTICK_RATE_MS); + /* adc Read */ + printf("ADC2: "); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]) ); + printf("CH%d-%d ", adc2_ch[i], adc2_val[i]); +#ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_NOT_EQUAL( 0, adc2_val[i] ); + TEST_ASSERT_NOT_EQUAL( 0x1fff, adc2_val[i] ); +#endif + } + printf("\n"); + + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc_io_normal(ADC_UNIT_1, adc1_ch[i]); + } +} diff --git a/components/driver/test/test_dac.c b/components/driver/test/test_dac.c new file mode 100644 index 000000000..171572872 --- /dev/null +++ b/components/driver/test/test_dac.c @@ -0,0 +1,120 @@ +/* + Tests for the dac device driver +*/ +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "test_utils.h" +#include "driver/i2s.h" + +static const char *TAG = "test_dac"; + +#ifdef CONFIG_IDF_TARGET_ESP32 +#define ADC_TEST_WIDTH ADC_WIDTH_BIT_12 +#elif defined CONFIG_IDF_TARGET_ESP32S2 +#define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width +#endif +#define ADC_TEST_ATTEN ADC_ATTEN_DB_11 + +#if CONFIG_IDF_TARGET_ESP32 +#define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_8 // GPIO25 +#define DAC_TEST_CHANNEL_NUM DAC_CHANNEL_1 // GPIO25 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_6 // GPIO17 +#define DAC_TEST_CHANNEL_NUM DAC_CHANNEL_1 // GPIO17 +#endif + +#define DAC_OUT_MAX (200) +#define DAC_OUT_TIMES (10) +#define DAC_OUT_STEP (DAC_OUT_MAX / DAC_OUT_TIMES) + +#define DAC_TEST_TIMES (100) + +TEST_CASE("DAC output (RTC) check by adc", "[dac]") +{ + gpio_num_t adc_gpio_num, dac_gpio_num; + + TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) ); + TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) ); + + printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num, + DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num ); + + TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) ); + + //be sure to do the init before using adc2. + printf("adc2_init...\n"); + TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN ) ); + + vTaskDelay(2 * portTICK_RATE_MS); + + printf("start conversion.\n"); + int output_data = 0; + int read_raw = 0, read_old = 0; + for (int i = 0; i < DAC_OUT_TIMES; i++) { + TEST_ESP_OK( dac_output_voltage( DAC_TEST_CHANNEL_NUM, output_data ) ); + output_data += DAC_OUT_STEP; + vTaskDelay(2 * portTICK_RATE_MS); + TEST_ESP_OK( adc2_get_raw( ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw) ); + ESP_LOGI(TAG, "DAC%d - ADC%d", output_data, read_raw); + if (read_old != 0) { + TEST_ASSERT_GREATER_THAN(read_old, read_raw); + } + read_old = read_raw; + } + TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) ); +} + +TEST_CASE("DAC cw generator output (RTC) check by adc", "[dac]") +{ + gpio_num_t adc_gpio_num, dac_gpio_num; + + TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) ); + TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) ); + + printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num, + DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num ); + + dac_cw_config_t cw = { + .en_ch = DAC_TEST_CHANNEL_NUM, + .scale = DAC_CW_SCALE_2, + .phase = DAC_CW_PHASE_0, + .freq = 1000, +#if CONFIG_IDF_TARGET_ESP32 + .offset = 64, +#elif CONFIG_IDF_TARGET_ESP32S2 + .offset = 16, +#endif + }; + TEST_ESP_OK( dac_cw_generator_config(&cw) ); + TEST_ESP_OK( dac_cw_generator_enable() ); + TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) ); + + //be sure to do the init before using adc2. + printf("adc2_init...\n"); + TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN ) ); + + vTaskDelay(2 * portTICK_RATE_MS); + + printf("start conversion.\n"); + int read_raw[3] = {0}; + for (int i = 0; i < DAC_TEST_TIMES; i++) { + vTaskDelay(10 * portTICK_RATE_MS); + TEST_ESP_OK( adc2_get_raw( ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw[0]) ); + ESP_LOGI(TAG, "ADC: %d", read_raw[0]); + if (read_raw[0] == read_raw[1]) { + TEST_ASSERT_NOT_EQUAL(read_raw[1], read_raw[2]); + } + read_raw[2] = read_raw[1]; + read_raw[1] = read_raw[0]; + } + + TEST_ESP_OK( dac_cw_generator_disable() ); + TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) ); +} diff --git a/components/driver/test/test_i2s.c b/components/driver/test/test_i2s.c index 639213c0a..d3b1b076e 100644 --- a/components/driver/test/test_i2s.c +++ b/components/driver/test/test_i2s.c @@ -205,7 +205,7 @@ TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]") #if !DISABLED_FOR_TARGETS(ESP32S2) /* ESP32S2 has only single I2S port and hence following test cases are not applicable */ -TEST_CASE("I2S adc test", "[i2s]") +TEST_CASE("I2S adc test", "[i2s][ignore]") { // init I2S ADC i2s_config_t i2s_config = { diff --git a/components/soc/include/hal/adc_hal.h b/components/soc/include/hal/adc_hal.h index a8597a5ea..a243ad1ae 100644 --- a/components/soc/include/hal/adc_hal.h +++ b/components/soc/include/hal/adc_hal.h @@ -3,18 +3,6 @@ #include "hal/adc_types.h" #include "hal/adc_ll.h" -typedef struct { - bool conv_limit_en; - uint32_t conv_limit_num; - uint32_t clk_div; - uint32_t adc1_pattern_len; - uint32_t adc2_pattern_len; - adc_ll_pattern_table_t *adc1_pattern; - adc_ll_pattern_table_t *adc2_pattern; - adc_ll_convert_mode_t conv_mode; - adc_ll_dig_output_format_t format; -} adc_hal_dig_config_t; - /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ @@ -23,6 +11,11 @@ typedef struct { */ void adc_hal_init(void); +/** + * ADC module deinitialization. + */ +void adc_hal_deinit(void); + /** * Set adc sample cycle for digital controller. * @@ -30,7 +23,7 @@ void adc_hal_init(void); * @param sample_cycle Cycles between DIG ADC controller start ADC sensor and beginning to receive data from sensor. * Range: 2 ~ 0xFF. */ -#define adc_hal_dig_set_sample_cycle(sample_cycle) adc_ll_dig_set_sample_cycle(sample_cycle) +#define adc_hal_digi_set_sample_cycle(sample_cycle) adc_ll_digi_set_sample_cycle(sample_cycle) /** * Set ADC module power management. @@ -52,14 +45,14 @@ void adc_hal_init(void); * * @prarm div Division factor. */ -#define adc_hal_set_clk_div(div) adc_ll_set_clk_div(div) +#define adc_hal_digi_set_clk_div(div) adc_ll_digi_set_clk_div(div) /** - * ADC module output data invert or not. + * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`. * - * @prarm adc_n ADC unit. + * @prarm div Division factor. */ -void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en); +#define adc_hal_set_sar_clk_div(adc_n, div) adc_ll_set_sar_clk_div(adc_n, div) /** * Set ADC module controller. @@ -108,6 +101,15 @@ void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en); */ #define adc_hal_set_atten(adc_n, channel, atten) adc_ll_set_atten(adc_n, channel, atten) +/** + * Get the attenuation of a particular channel on ADCn. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. + */ +#define adc_hal_get_atten(adc_n, channel) adc_ll_get_atten(adc_n, channel) + /** * Close ADC AMP module if don't use it for power save. */ @@ -137,6 +139,21 @@ void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en); RTC controller setting ---------------------------------------------------------------*/ +/** + * Get the converted value for each ADCn for RTC controller. + * + * @note It may be block to wait conversion finish. + * + * @prarm adc_n ADC unit. + * @param channel adc channel number. + * @param value Pointer for touch value. + * + * @return + * - 0: The value is valid. + * - ~0: The value is invalid. + */ +int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value); + /** * Set adc output data format for RTC controller. * @@ -146,62 +163,19 @@ void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en); #define adc_hal_rtc_set_output_format(adc_n, bits) adc_ll_rtc_set_output_format(adc_n, bits) /** - * Get the converted value for each ADCn for RTC controller. + * ADC module output data invert or not. * - * @note It may be block to wait conversion finish. * @prarm adc_n ADC unit. - * @return - * - Converted value. */ -int adc_hal_convert(adc_ll_num_t adc_n, int channel); +#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en) /*--------------------------------------------------------------- Digital controller setting ---------------------------------------------------------------*/ + /** - * Setting the digital controller. + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. * - * @prarm adc_hal_dig_config_t cfg Pointer to digital controller paramter. + * @param adc_n ADC unit. */ -void adc_hal_dig_controller_config(const adc_hal_dig_config_t *cfg); - -/** - * Set I2S DMA data source for digital controller. - * - * @param src i2s data source. - */ -#define adc_hal_dig_set_data_source(src) adc_ll_dig_set_data_source(src) - -/*--------------------------------------------------------------- - Hall sensor setting ----------------------------------------------------------------*/ - -/** - * Enable hall sensor. - */ -#define adc_hal_hall_enable() adc_ll_hall_enable() - -/** - * Disable hall sensor. - */ -#define adc_hal_hall_disable() adc_ll_hall_disable() - -/** - * Start hall convert and return the hall value. - * - * @return Hall value. - */ -int adc_hal_hall_convert(void); - -/** - * @brief Output ADC2 reference voltage to gpio - * - * This function utilizes the testing mux exclusive to ADC2 to route the - * reference voltage one of ADC2's channels. - * - * @param[in] io GPIO number - * @return - * - true: v_ref successfully routed to selected gpio - * - false: Unsupported gpio - */ -#define adc_hal_vref_output(io) adc_ll_vref_output(io) \ No newline at end of file +#define adc_hal_digi_clear_pattern_table(adc_n) adc_ll_digi_clear_pattern_table(adc_n) diff --git a/components/soc/include/hal/adc_types.h b/components/soc/include/hal/adc_types.h index d651f00b4..160b01e89 100644 --- a/components/soc/include/hal/adc_types.h +++ b/components/soc/include/hal/adc_types.h @@ -1,5 +1,27 @@ #pragma once +#include "soc/adc_caps.h" +#include "sdkconfig.h" +#include + +/** + * @brief ADC units selected handle. + * + * @note For ADC digital controller(DMA mode), ESP32 don't support `ADC_UNIT_2`, `ADC_UNIT_BOTH`, `ADC_UNIT_ALTER`. + */ +typedef enum { + ADC_UNIT_1 = 1, /*!< SAR ADC 1. */ + ADC_UNIT_2 = 2, /*!< SAR ADC 2. */ + ADC_UNIT_BOTH = 3, /*!< SAR ADC 1 and 2. */ + ADC_UNIT_ALTER = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */ + ADC_UNIT_MAX, +} adc_unit_t; + +/** + * @brief ADC channels handle. See ``adc1_channel_t``, ``adc2_channel_t``. + * + * @note For ESP32 ADC1, don't support `ADC_CHANNEL_8`, `ADC_CHANNEL_9`. See ``adc1_channel_t``. + */ typedef enum { ADC_CHANNEL_0 = 0, /*!< ADC channel */ ADC_CHANNEL_1, /*!< ADC channel */ @@ -14,6 +36,9 @@ typedef enum { ADC_CHANNEL_MAX, } adc_channel_t; +/** + * @brief ADC attenuation parameter. Different parameters determine the range of the ADC. See ``adc1_config_channel_atten``. + */ typedef enum { ADC_ATTEN_DB_0 = 0, /*! ADC_CHANNEL_MAX), The data is invalid. */ + } type1; /*! ADC_CHANNEL_MAX), The data is invalid. */ + uint16_t unit: 1; /*! threshold, Generates monitor interrupt. + * MONITOR_LOW: If ADC_OUT < threshold, Generates monitor interrupt. + */ +typedef enum { + ADC_DIGI_MONITOR_HIGH = 0, /*! threshold, Generates monitor interrupt. */ + ADC_DIGI_MONITOR_LOW, /*!clk_div); + /* Single channel mode or multi channel mode. */ + adc_ll_digi_set_convert_mode(cfg->conv_mode); + if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) { + adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG); + if (cfg->adc1_pattern_len) { + adc_ll_digi_clear_pattern_table(ADC_NUM_1); + adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len); + for (int i = 0; i < cfg->adc1_pattern_len; i++) { + adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]); + } + } + } + if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) { + adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG); + if (cfg->adc2_pattern_len) { + adc_ll_digi_clear_pattern_table(ADC_NUM_2); + adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len); + for (int i = 0; i < cfg->adc2_pattern_len; i++) { + adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]); + } + } + } + adc_ll_digi_set_output_format(cfg->format); + if (cfg->conv_limit_en) { + adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num); + adc_ll_digi_convert_limit_enable(); + } else { + adc_ll_digi_convert_limit_disable(); + } + adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_ADC); +} + +int adc_hal_hall_convert(void) +{ + int Sens_Vp0; + int Sens_Vn0; + int Sens_Vp1; + int Sens_Vn1; + int hall_value; + // convert for 4 times with different phase and outputs + adc_ll_hall_phase_disable(); // hall phase + adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0, &Sens_Vp0 ); + adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3, &Sens_Vn0 ); + adc_ll_hall_phase_enable(); + adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0, &Sens_Vp1 ); + adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3, &Sens_Vn1 ); + hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0); + return hall_value; +} \ No newline at end of file diff --git a/components/soc/src/esp32/include/hal/adc_hal.h b/components/soc/src/esp32/include/hal/adc_hal.h new file mode 100644 index 000000000..f13fa295b --- /dev/null +++ b/components/soc/src/esp32/include/hal/adc_hal.h @@ -0,0 +1,118 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +// The HAL layer for ADC (esp32 specific part) + +#pragma once + +#include "hal/adc_ll.h" +#include "hal/adc_types.h" + +#include_next "hal/adc_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + bool conv_limit_en; /*!> offset)); // clear old data + tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data + SYSCON.saradc_sar1_patt_tab[index] = tab; // Write back } else { // adc_n == ADC_NUM_2 - SYSCON.saradc_sar2_patt_tab[patt_tab_idx] &= ~patt_mask; - SYSCON.saradc_sar2_patt_tab[patt_tab_idx] |= pattern.val << patt_shift; + tab = SYSCON.saradc_sar2_patt_tab[index]; // Read old register value + tab &= (~(0xFF000000 >> offset)); // clear old data + tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data + SYSCON.saradc_sar2_patt_tab[index] = tab; // Write back + } +} + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_clear_pattern_table(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + SYSCON.saradc_ctrl.sar1_patt_p_clear = 1; + SYSCON.saradc_ctrl.sar1_patt_p_clear = 0; + } else { // adc_n == ADC_NUM_2 + SYSCON.saradc_ctrl.sar2_patt_p_clear = 1; + SYSCON.saradc_ctrl.sar2_patt_p_clear = 0; } } @@ -223,7 +271,7 @@ static inline void adc_ll_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern * Set adc cct for PWDET controller. * * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. - * @prarm cct Range: 0 ~ 7. + * @param cct Range: 0 ~ 7. */ static inline void adc_ll_pwdet_set_cct(uint32_t cct) { @@ -249,8 +297,8 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /** * Set adc output data format for RTC controller. * - * @prarm adc_n ADC unit. - * @prarm bits Output data bits width option. + * @param adc_n ADC unit. + * @param bits Output data bits width option, see ``adc_bits_width_t``. */ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits) { @@ -266,9 +314,9 @@ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_wid /** * Enable adc channel to start convert. * - * @note Only one channel can be selected for once measurement. + * @note Only one channel can be selected in once measurement. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel) @@ -280,12 +328,29 @@ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel) } } +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n, int channel) +{ + if (adc_n == ADC_NUM_1) { + SENS.sar_meas_start1.sar1_en_pad = 0; //only one channel is selected. + } else { // adc_n == ADC_NUM_2 + SENS.sar_meas_start2.sar2_en_pad = 0; //only one channel is selected. + } +} + /** * Start conversion once by software for RTC controller. * * @note It may be block to wait conversion idle for ADC1. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel) @@ -303,7 +368,7 @@ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel) /** * Check the conversion done flag for each ADCn for RTC controller. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @return * -true : The conversion process is finish. * -false : The conversion process is not finish. @@ -322,7 +387,7 @@ static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n) /** * Get the converted value for each ADCn for RTC controller. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @return * - Converted value. */ @@ -337,13 +402,41 @@ static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n) return ret_val; } +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en) +{ + if (adc_n == ADC_NUM_1) { + SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_NUM_2 + SENS.sar_read_ctrl2.sar2_data_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Analyze whether the obtained raw data is correct. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 0: The data is correct to use. + */ +static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t adc_n, uint16_t raw_data) +{ + /* ADC1 don't need check data */ + return ADC_RTC_DATA_OK; +} + /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ /** * Set ADC module power management. * - * @prarm manage Set ADC power status. + * @param manage Set ADC power status. */ static inline void adc_ll_set_power_manage(adc_ll_power_t manage) { @@ -380,14 +473,17 @@ static inline adc_ll_power_t adc_ll_get_power_manage(void) } /** - * ADC module clock division factor setting. ADC clock devided from APB clock. + * ADC SAR clock division factor setting. ADC SAR clock divided from `RTC_FAST_CLK`. * - * @prarm div Division factor. + * @param div Division factor. */ -static inline void adc_ll_set_clk_div(uint32_t div) +static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div) { - /* ADC clock devided from APB clk, e.g. 80 / 2 = 40Mhz, */ - SYSCON.saradc_ctrl.sar_clk_div = div; + if (adc_n == ADC_NUM_1) { + SENS.sar_read_ctrl.sar1_clk_div = div; + } else { // adc_n == ADC_NUM_2 + SENS.sar_read_ctrl2.sar2_clk_div = div; + } } /** @@ -400,7 +496,7 @@ static inline void adc_ll_set_clk_div(uint32_t div) * * When VDD_A is 3.3V: * - * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V + * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below) @@ -412,16 +508,16 @@ static inline void adc_ll_set_clk_div(uint32_t div) * * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: * - * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV + * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV * * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. * - * @prarm adc_n ADC unit. - * @prarm channel ADCn channel number. - * @prarm atten The attenuation option. + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @param atten The attenuation option. */ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten) { @@ -433,30 +529,18 @@ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, a } /** - * ADC module RTC output data invert or not. + * Get the attenuation of a particular channel on ADCn. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. */ -static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en) +static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel) { if (adc_n == ADC_NUM_1) { - SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert - } else { // adc_n == ADC_NUM_2 - SENS.sar_read_ctrl2.sar2_data_inv = inv_en; // Enable / Disable ADC data invert - } -} - -/** - * ADC module Digital output data invert or not. - * - * @prarm adc_n ADC unit. - */ -static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en) -{ - if (adc_n == ADC_NUM_1) { - SYSCON.saradc_ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert - } else { // adc_n == ADC_NUM_2 - SYSCON.saradc_ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert + return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3); + } else { + return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3); } } @@ -467,10 +551,10 @@ static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en) * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep; * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2. * - * @prarm adc_n ADC unit. - * @prarm ctrl ADC controller. + * @param adc_n ADC unit. + * @param ctrl ADC controller. */ -static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl) +static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_hal_controller_t ctrl) { if (adc_n == ADC_NUM_1) { switch ( ctrl ) { diff --git a/components/soc/src/esp32/include/hal/dac_ll.h b/components/soc/src/esp32/include/hal/dac_ll.h index 15606357c..93fc72c6b 100644 --- a/components/soc/src/esp32/include/hal/dac_ll.h +++ b/components/soc/src/esp32/include/hal/dac_ll.h @@ -178,6 +178,7 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset) static inline void dac_ll_dma_enable(void) { SENS.sar_dac_ctrl1.dac_dig_force = 1; + SENS.sar_dac_ctrl1.dac_clk_inv = 1; } /** @@ -186,6 +187,7 @@ static inline void dac_ll_dma_enable(void) static inline void dac_ll_dma_disable(void) { SENS.sar_dac_ctrl1.dac_dig_force = 0; + SENS.sar_dac_ctrl1.dac_clk_inv = 0; } diff --git a/components/soc/src/esp32/touch_sensor_hal.c b/components/soc/src/esp32/touch_sensor_hal.c index da8454052..49ecdcff7 100644 --- a/components/soc/src/esp32/touch_sensor_hal.c +++ b/components/soc/src/esp32/touch_sensor_hal.c @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// The HAL layer for SPI (common part) +// The HAL layer for Touch sensor (common part) #include "hal/touch_sensor_hal.h" #include "hal/touch_sensor_types.h" diff --git a/components/soc/src/esp32s2/CMakeLists.txt b/components/soc/src/esp32s2/CMakeLists.txt index 0321c6ec0..95b644c68 100644 --- a/components/soc/src/esp32s2/CMakeLists.txt +++ b/components/soc/src/esp32s2/CMakeLists.txt @@ -1,4 +1,5 @@ -set(srcs "brownout_hal.c" +set(srcs "adc_hal.c" + "brownout_hal.c" "rtc_clk.c" "rtc_clk_init.c" "rtc_init.c" diff --git a/components/soc/src/esp32s2/adc_hal.c b/components/soc/src/esp32s2/adc_hal.c new file mode 100644 index 000000000..f6b93b8bd --- /dev/null +++ b/components/soc/src/esp32s2/adc_hal.c @@ -0,0 +1,252 @@ +// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The HAL layer for ADC (esp32s2 specific part) + +#include "hal/adc_hal.h" +#include "hal/adc_types.h" +#include "esp_log.h" +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + +void adc_hal_digi_init(void) +{ + adc_hal_init(); + adc_ll_digi_set_clk_div(SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT); + adc_ll_digi_output_invert(ADC_NUM_1, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_1)); + adc_ll_digi_output_invert(ADC_NUM_2, SOC_ADC_DIGI_DATA_INVERT_DEFAULT(ADC_NUM_2)); + +} + +void adc_hal_digi_deinit(void) +{ + adc_ll_digi_trigger_disable(); // boss + adc_ll_digi_dma_disable(); + adc_ll_digi_clear_pattern_table(ADC_NUM_1); + adc_ll_digi_clear_pattern_table(ADC_NUM_2); + adc_ll_digi_filter_reset(ADC_NUM_1); + adc_ll_digi_filter_reset(ADC_NUM_2); + adc_ll_digi_reset(); + adc_ll_digi_controller_clk_disable(); + adc_hal_deinit(); +} + +static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten) +{ + uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false); + adc_hal_set_calibration_param(adc_n, cal_val); +} + +void adc_hal_digi_controller_config(const adc_digi_config_t *cfg) +{ + /* If enable digtal controller, adc xpd should always on. */ + adc_ll_set_power_manage(ADC_POWER_SW_ON); + /* Single channel mode or multi channel mode. */ + adc_ll_digi_set_convert_mode(cfg->conv_mode); + if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) { + if (cfg->adc1_pattern_len) { + adc_ll_digi_clear_pattern_table(ADC_NUM_1); + adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len); + for (int i = 0; i < cfg->adc1_pattern_len; i++) { + adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]); + adc_set_init_code(ADC_NUM_1, cfg->adc1_pattern[i].channel, cfg->adc1_pattern[i].atten); + } + } + } + if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) { + if (cfg->adc2_pattern_len) { + adc_ll_digi_clear_pattern_table(ADC_NUM_2); + adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len); + for (int i = 0; i < cfg->adc2_pattern_len; i++) { + adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]); + adc_set_init_code(ADC_NUM_2, cfg->adc2_pattern[i].channel, cfg->adc2_pattern[i].atten); + } + } + } + if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) { + adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG); + } + if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) { + adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG); + } + adc_ll_digi_set_output_format(cfg->format); + if (cfg->conv_limit_en) { + adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num); + adc_ll_digi_convert_limit_enable(); + } else { + adc_ll_digi_convert_limit_disable(); + } + + adc_ll_digi_set_trigger_interval(cfg->interval); + adc_hal_digi_clk_config(&cfg->dig_clk); + adc_ll_digi_dma_set_eof_num(cfg->dma_eof_num); +} + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Enable clock and select clock source for ADC digital controller. + * Expression: controller_clk = APLL/APB * (div_num + div_b / div_a). + * + * @param clk Refer to `adc_digi_clk_t`. + */ +void adc_hal_digi_clk_config(const adc_digi_clk_t *clk) +{ + adc_ll_digi_controller_clk_div(clk->div_num, clk->div_b, clk->div_a); + adc_ll_digi_controller_clk_enable(clk->use_apll); +} + +/** + * Enable digital controller to trigger the measurement. + */ +void adc_hal_digi_enable(void) +{ + adc_ll_digi_dma_enable(); + adc_ll_digi_trigger_enable(); +} + +/** + * Disable digital controller to trigger the measurement. + */ +void adc_hal_digi_disable(void) +{ + adc_ll_digi_trigger_disable(); + adc_ll_digi_dma_disable(); +} + +/** + * Config monitor of adc digital controller. + * + * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + * @param config Refer to `adc_digi_monitor_t`. + */ +void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config) +{ + adc_ll_digi_monitor_set_mode(adc_n, config->mode); + adc_ll_digi_monitor_set_thres(adc_n, config->threshold); +} + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ + +/** + * Config ADC2 module arbiter. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. + * + * @note Only ADC2 support arbiter. + * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. + * @note Default priority: Wi-Fi > RTC > Digital; + * + * @param config Refer to `adc_arbiter_t`. + */ +void adc_hal_arbiter_config(adc_arbiter_t *config) +{ + adc_ll_set_arbiter_work_mode(config->mode); + adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri); +} + +/*--------------------------------------------------------------- + ADC calibration setting +---------------------------------------------------------------*/ + +static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} }; + +static uint32_t adc_hal_read_self_cal(adc_ll_num_t adc_n, int channel) +{ + adc_ll_rtc_start_convert(adc_n, channel); + while (adc_ll_rtc_convert_is_done(adc_n) != true); + return (uint32_t)adc_ll_rtc_get_convert_value(adc_n); +} + +uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal) +{ + if (!force_cal) { + if (s_adc_cali_param[adc_n][atten]) { + return (uint32_t)s_adc_cali_param[adc_n][atten]; + } + } + + uint32_t code_list[ADC_HAL_CAL_TIMES] = {0}; + uint32_t code_sum = 0; + uint32_t code_h = 0; + uint32_t code_l = 0; + uint32_t chk_code = 0; + uint32_t dout = 0; + + adc_hal_set_power_manage(ADC_POWER_SW_ON); + if (adc_n == ADC_NUM_2) { + adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); + adc_hal_arbiter_config(&config); + } + adc_hal_set_controller(adc_n, ADC_CTRL_RTC); //Set controller + + // adc_hal_arbiter_config(adc_arbiter_t *config) + adc_ll_calibration_prepare(adc_n, channel, internal_gnd); + + /* Enable/disable internal connect GND (for calibration). */ + if (internal_gnd) { + adc_ll_rtc_disable_channel(adc_n, channel); + adc_ll_set_atten(adc_n, 0, atten); // Note: when disable all channel, HW auto select channel0 atten param. + } else { + adc_ll_rtc_enable_channel(adc_n, channel); + adc_ll_set_atten(adc_n, channel, atten); + } + + for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) { + code_h = ADC_HAL_CAL_OFFSET_RANGE; + code_l = 0; + chk_code = (code_h + code_l) / 2; + adc_ll_set_calibration_param(adc_n, chk_code); + dout = adc_hal_read_self_cal(adc_n, channel); + while (code_h - code_l > 1) { + if (dout == 0) { + code_h = chk_code; + } else { + code_l = chk_code; + } + chk_code = (code_h + code_l) / 2; + adc_ll_set_calibration_param(adc_n, chk_code); + dout = adc_hal_read_self_cal(adc_n, channel); + if ((code_h - code_l == 1)) { + chk_code += 1; + adc_ll_set_calibration_param(adc_n, chk_code); + dout = adc_hal_read_self_cal(adc_n, channel); + } + } + code_list[rpt] = chk_code; + code_sum += chk_code; + } + code_l = code_list[0]; + code_h = code_list[0]; + for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) { + if (code_l > code_list[i]) { + code_l = code_list[i]; + } + if (code_h < code_list[i]) { + code_h = code_list[i]; + } + } + chk_code = code_h + code_l; + dout = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4) + ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1; + + adc_ll_set_calibration_param(adc_n, dout); + adc_ll_calibration_finish(adc_n); + s_adc_cali_param[adc_n][atten] = (uint16_t)dout; + return dout; +} \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/adc_hal.h b/components/soc/src/esp32s2/include/hal/adc_hal.h new file mode 100644 index 000000000..e05c936be --- /dev/null +++ b/components/soc/src/esp32s2/include/hal/adc_hal.h @@ -0,0 +1,262 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in soc/include/hal/readme.md + ******************************************************************************/ + +// The HAL layer for ADC (esp32s2 specific part) + +#pragma once + +#include "hal/adc_ll.h" +#include "hal/adc_types.h" + +#include_next "hal/adc_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ +/** + * Digital controller initialization. + */ +void adc_hal_digi_init(void); + +/** + * Digital controller deinitialization. + */ +void adc_hal_digi_deinit(void); + +/** + * Setting the digital controller. + * + * @param cfg Pointer to digital controller paramter. + */ +void adc_hal_digi_controller_config(const adc_digi_config_t *cfg); + +/** + * ADC Digital controller output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +#define adc_hal_digi_output_invert(adc_n, inv_en) adc_ll_digi_output_invert(adc_n, inv_en) + +/** + * Sets the number of interval clock cycles for the digital controller to trigger the measurement. + * + * @note The trigger interval should not be less than the sampling time of the SAR ADC. + * @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095. + */ +#define adc_hal_digi_set_trigger_interval(cycle) adc_ll_digi_set_trigger_interval(cycle) + +/** + * Enable digital controller to trigger the measurement. + */ +void adc_hal_digi_enable(void); + +/** + * Disable digital controller to trigger the measurement. + */ +void adc_hal_digi_disable(void); + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Enable clock and select clock source for ADC digital controller. + * Expression: controller_clk = APLL/APB * (div_num + div_b / div_a). + * + * @param clk Refer to `adc_digi_clk_t`. + */ +void adc_hal_digi_clk_config(const adc_digi_clk_t *clk); + +/** + * Reset adc digital controller filter. + * + * @param adc_n ADC unit. + */ +#define adc_hal_digi_filter_reset(adc_n) adc_ll_digi_filter_reset(adc_n) + +/** + * Set adc digital controller filter factor. + * + * @param adc_n ADC unit. + * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64). + */ +#define adc_hal_digi_filter_set_factor(adc_n, factor) adc_ll_digi_filter_set_factor(adc_n, factor) + +/** + * Get adc digital controller filter factor. + * + * @param adc_n ADC unit. + * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64). + */ +#define adc_hal_digi_filter_get_factor(adc_n, factor) adc_ll_digi_filter_get_factor(adc_n, factor) + +/** + * Enable/disable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @note The filter will filter all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + */ +#define adc_hal_digi_filter_enable(adc_n, enable) adc_ll_digi_filter_enable(adc_n, enable) + +/** + * Get the filtered data of adc digital controller filter. + * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API. + * + * @note The filter will filter all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + * @return Filtered data. + */ +#define adc_hal_digi_filter_read_data(adc_n) adc_ll_digi_filter_read_data(adc_n) + +/** + * Config monitor of adc digital controller. + * + * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + * @param config Refer to `adc_digi_monitor_t`. + */ +void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config); + +/** + * Enable/disable monitor of adc digital controller. + * + * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + */ +#define adc_hal_digi_monitor_enable(adc_n, enable) adc_ll_digi_monitor_enable(adc_n, enable) + +/** + * Enable interrupt of adc digital controller by bitmask. + * + * @param adc_n ADC unit. + * @param intr Interrupt bitmask. + */ +#define adc_hal_digi_intr_enable(adc_n, intr) adc_ll_digi_intr_enable(adc_n, intr) + +/** + * Disable interrupt of adc digital controller by bitmask. + * + * @param adc_n ADC unit. + * @param intr Interrupt bitmask. + */ +#define adc_hal_digi_intr_disable(adc_n, intr) adc_ll_digi_intr_disable(adc_n, intr) + +/** + * Clear interrupt of adc digital controller by bitmask. + * + * @param adc_n ADC unit. + * @param intr Interrupt bitmask. + */ +#define adc_hal_digi_intr_clear(adc_n, intr) adc_ll_digi_intr_clear(adc_n, intr) + +/** + * Get interrupt status mask of adc digital controller. + * + * @param adc_n ADC unit. + * @return + * - intr Interrupt bitmask. + */ +#define adc_hal_digi_get_intr_status(adc_n) adc_ll_digi_get_intr_status(adc_n) + + +/** + * Set DMA eof num of adc digital controller. + * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. + * + * @param num eof num of DMA. + */ +#define adc_hal_digi_dma_set_eof_num(num) adc_ll_digi_dma_set_eof_num(num) + +/** + * Enable output data to DMA from adc digital controller. + */ +#define adc_hal_digi_dma_enable() adc_ll_digi_dma_enable() + +/** + * Disable output data to DMA from adc digital controller. + */ +#define adc_hal_digi_dma_disable() adc_ll_digi_dma_disable() + +/** + * Reset adc digital controller. + */ +#define adc_hal_digi_reset() adc_ll_digi_reset() + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ +/** + * Reset RTC controller FSM. + */ +#define adc_hal_rtc_reset() adc_ll_rtc_reset() + +/*--------------------------------------------------------------- + Common setting +---------------------------------------------------------------*/ + +/** + * Config ADC2 module arbiter. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. + * + * @note Only ADC2 support arbiter. + * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. + * @note Default priority: Wi-Fi > RTC > Digital; + * + * @param config Refer to `adc_arbiter_t`. + */ +void adc_hal_arbiter_config(adc_arbiter_t *config); + +/*--------------------------------------------------------------- + ADC calibration setting +---------------------------------------------------------------*/ + +/** + * Calibrate the ADC according to the parameters. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param channel adc channel number. + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + * @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time. + * false: Use the result of the last calibration. + * + * @return + * - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set. + */ +uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal); + +/** + * Set the calibration result (initial data) to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + */ +#define adc_hal_set_calibration_param(adc_n, param) adc_ll_set_calibration_param(adc_n, param); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/adc_ll.h b/components/soc/src/esp32s2/include/hal/adc_ll.h index 1f09cbdfc..8ecdcd4eb 100644 --- a/components/soc/src/esp32s2/include/hal/adc_ll.h +++ b/components/soc/src/esp32s2/include/hal/adc_ll.h @@ -3,53 +3,20 @@ #include "soc/adc_periph.h" #include "hal/adc_types.h" #include "soc/apb_saradc_struct.h" +#include "soc/apb_saradc_reg.h" +#include "soc/rtc_cntl_struct.h" #include #ifdef __cplusplus extern "C" { #endif -typedef enum { - ADC_DIG_FORMAT_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data. - Note: In single convert mode. */ - ADC_DIG_FORMAT_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data. - Note: In multi convert mode. */ - ADC_DIG_FORMAT_MAX, -} adc_ll_dig_output_format_t; - -typedef enum { - ADC_CONV_SINGLE_UNIT_1 = 1, /*!< SAR ADC 1*/ - ADC_CONV_SINGLE_UNIT_2 = 2, /*!< SAR ADC 2, not supported yet*/ - ADC_CONV_BOTH_UNIT = 3, /*!< SAR ADC 1 and 2, not supported yet */ - ADC_CONV_ALTER_UNIT = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */ - ADC_CONV_UNIT_MAX, -} adc_ll_convert_mode_t; - typedef enum { ADC_NUM_1 = 0, /*!< SAR ADC 1 */ ADC_NUM_2 = 1, /*!< SAR ADC 2 */ ADC_NUM_MAX, } adc_ll_num_t; -typedef struct { - union { - struct { - uint8_t atten: 2; /*!< ADC sampling voltage attenuation configuration. - 0: input voltage * 1; - 1: input voltage * 1/1.34; - 2: input voltage * 1/2; - 3: input voltage * 1/3.6. */ - uint8_t bit_width: 2; /*!< ADC resolution. - 0: 9 bit; - 1: 10 bit; - 2: 11 bit; - 3: 12 bit. */ - uint8_t channel: 4; /*!< ADC channel index. */ - }; - uint8_t val; - }; -} adc_ll_pattern_table_t; - typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ @@ -58,16 +25,55 @@ typedef enum { } adc_ll_power_t; typedef enum { - ADC_HALL_CTRL_ULP = 0x0,/*!< Hall sensor controled by ULP */ - ADC_HALL_CTRL_RTC = 0x1 /*!< Hall sensor controled by RTC */ -} adc_ll_hall_controller_t ; + ADC_RTC_DATA_OK = 0, + ADC_RTC_CTRL_UNSELECTED = 1, + ADC_RTC_CTRL_BREAK = 2, + ADC_RTC_DATA_FAIL = -1, +} adc_ll_rtc_raw_data_t; +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +/** + * @brief Analyze whether the obtained raw data is correct. + * ADC2 use arbiter by default. The arbitration result can be judged by the flag bit in the original data. + * + */ +typedef struct { + union { + struct { + uint16_t data: 13; /*! 0), The data is invalid. */ + }; + uint16_t val; + }; +} adc_rtc_output_data_t; + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + +/** + * @brief ADC controller type selection. + * + * @note For ADC2, use the force option with care. The system power consumption detection will use ADC2. + * If it is forced to switch to another controller, it may cause the system to obtain incorrect values. + * @note Normally, there is no need to switch the controller manually. + */ typedef enum { - ADC_CTRL_RTC = 0, - ADC_CTRL_ULP = 1, - ADC_CTRL_DIG = 2, - ADC2_CTRL_PWDET = 3, -} adc_ll_controller_t ; + ADC_CTRL_RTC = 0, /*!> offset)); // clear old data + tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data + APB_SARADC.sar1_patt_tab[index] = tab; // Write back + } else { // adc_n == ADC_NUM_2 + tab = APB_SARADC.sar2_patt_tab[index]; // Read old register value + tab &= (~(0xFF000000 >> offset)); // clear old data + tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data + APB_SARADC.sar2_patt_tab[index] = tab; // Write back + } +} + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_clear_pattern_table(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.ctrl.sar1_patt_p_clear = 1; + APB_SARADC.ctrl.sar1_patt_p_clear = 0; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.ctrl.sar2_patt_p_clear = 1; + APB_SARADC.ctrl.sar2_patt_p_clear = 0; + } +} + +/** + * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize. + * + * @note Only ADC2 have arbiter function. + * @param cycle range: 0 ~ 4. + */ +static inline void adc_ll_digi_set_arbiter_stable_cycle(uint32_t cycle) +{ + APB_SARADC.ctrl.wait_arb_cycle = cycle; +} + +/** + * ADC Digital controller output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_NUM_2 + APB_SARADC.ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Sets the number of interval clock cycles for the digital controller to trigger the measurement. + * + * @note The trigger interval should not be less than the sampling time of the SAR ADC. + * @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095. + */ +static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) +{ + APB_SARADC.ctrl2.timer_target = cycle; +} + +/** + * Enable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_enable(void) +{ + APB_SARADC.ctrl2.timer_sel = 1; + APB_SARADC.ctrl2.timer_en = 1; +} + +/** + * Disable digital controller timer to trigger the measurement. + */ +static inline void adc_ll_digi_trigger_disable(void) +{ + APB_SARADC.ctrl2.timer_en = 0; + APB_SARADC.ctrl2.timer_sel = 0; +} + +/** + * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. + * Expression: controller_clk = APLL/APB * (div_num + div_b / div_a). + * + * @param div_num Division factor. Range: 1 ~ 255. + * @param div_b Division factor. Range: 1 ~ 63. + * @param div_a Division factor. Range: 1 ~ 63. + */ +static inline void adc_ll_digi_controller_clk_div(uint32_t div_num, uint32_t div_b, uint32_t div_a) +{ + APB_SARADC.apb_adc_clkm_conf.clkm_div_num = div_num; + APB_SARADC.apb_adc_clkm_conf.clkm_div_b = div_b; + APB_SARADC.apb_adc_clkm_conf.clkm_div_a = div_a; +} + +/** + * Enable clock and select clock source for ADC digital controller. + * + * @param use_apll true: use APLL clock; false: use APB clock. + */ +static inline void adc_ll_digi_controller_clk_enable(bool use_apll) +{ + if (use_apll) { + APB_SARADC.apb_adc_clkm_conf.clk_sel = 1; // APLL clock + } else { + APB_SARADC.apb_adc_clkm_conf.clk_sel = 2; // APB clock + } + APB_SARADC.ctrl.sar_clk_gated = 1; +} + +/** + * Disable clock for ADC digital controller. + */ +static inline void adc_ll_digi_controller_clk_disable(void) +{ + APB_SARADC.ctrl.sar_clk_gated = 0; + APB_SARADC.apb_adc_clkm_conf.clk_sel = 0; +} + +/** + * Reset adc digital controller filter. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_reset(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.filter_ctrl.adc1_filter_reset = 1; + APB_SARADC.filter_ctrl.adc1_filter_reset = 0; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.filter_ctrl.adc2_filter_reset = 1; + APB_SARADC.filter_ctrl.adc2_filter_reset = 0; + } +} + +/** + * Set adc digital controller filter factor. + * + * @param adc_n ADC unit. + * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64). + */ +static inline void adc_ll_digi_filter_set_factor(adc_ll_num_t adc_n, adc_digi_filter_mode_t factor) +{ + int mode = 0; + switch (factor) { + case ADC_DIGI_FILTER_IIR_2: mode = 2; break; + case ADC_DIGI_FILTER_IIR_4: mode = 4; break; + case ADC_DIGI_FILTER_IIR_8: mode = 8; break; + case ADC_DIGI_FILTER_IIR_16: mode = 16; break; + case ADC_DIGI_FILTER_IIR_64: mode = 64; break; + default: mode = 8; break; + } + if (adc_n == ADC_NUM_1) { + APB_SARADC.filter_ctrl.adc1_filter_factor = mode; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.filter_ctrl.adc2_filter_factor = mode; + } +} + +/** + * Get adc digital controller filter factor. + * + * @param adc_n ADC unit. + * @param factor Expression: filter_data = (k-1)/k * last_data + new_data / k. Set values: (2, 4, 8, 16, 64). + */ +static inline void adc_ll_digi_filter_get_factor(adc_ll_num_t adc_n, adc_digi_filter_mode_t *factor) +{ + int mode = 0; + if (adc_n == ADC_NUM_1) { + mode = APB_SARADC.filter_ctrl.adc1_filter_factor; + } else { // adc_n == ADC_NUM_2 + mode = APB_SARADC.filter_ctrl.adc2_filter_factor; + } + switch (mode) { + case 2: *factor = ADC_DIGI_FILTER_IIR_2; break; + case 4: *factor = ADC_DIGI_FILTER_IIR_4; break; + case 8: *factor = ADC_DIGI_FILTER_IIR_8; break; + case 16: *factor = ADC_DIGI_FILTER_IIR_16; break; + case 64: *factor = ADC_DIGI_FILTER_IIR_64; break; + default: *factor = ADC_DIGI_FILTER_IIR_MAX; break; + } +} + +/** + * Enable/disable adc digital controller filter. + * Filtering the ADC data to obtain smooth data at higher sampling rates. + * + * @note The filter will filter all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_filter_enable(adc_ll_num_t adc_n, bool enable) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.filter_ctrl.adc1_filter_en = enable; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.filter_ctrl.adc2_filter_en = enable; + } +} + +/** + * Get the filtered data of adc digital controller filter. + * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API. + * + * @note The filter will filter all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + * @return Filtered data. + */ +static inline uint32_t adc_ll_digi_filter_read_data(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + return APB_SARADC.filter_status.adc1_filter_data; + } else { // adc_n == ADC_NUM_2 + return APB_SARADC.filter_status.adc2_filter_data; + } +} + +/** + * Set monitor mode of adc digital controller. + * + * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + * @param is_larger true: If ADC_OUT > threshold, Generates monitor interrupt. + * false: If ADC_OUT < threshold, Generates monitor interrupt. + */ +static inline void adc_ll_digi_monitor_set_mode(adc_ll_num_t adc_n, bool is_larger) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.thres_ctrl.adc1_thres_mode = is_larger; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.thres_ctrl.adc2_thres_mode = is_larger; + } +} + +/** + * Set monitor threshold of adc digital controller. + * + * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + * @param threshold Monitor threshold. + */ +static inline void adc_ll_digi_monitor_set_thres(adc_ll_num_t adc_n, uint32_t threshold) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.thres_ctrl.adc1_thres = threshold; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.thres_ctrl.adc2_thres = threshold; + } +} + +/** + * Enable/disable monitor of adc digital controller. + * + * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. + * @param adc_n ADC unit. + */ +static inline void adc_ll_digi_monitor_enable(adc_ll_num_t adc_n, bool enable) +{ + if (adc_n == ADC_NUM_1) { + APB_SARADC.thres_ctrl.adc1_thres_en = enable; + } else { // adc_n == ADC_NUM_2 + APB_SARADC.thres_ctrl.adc2_thres_en = enable; + } +} + +/** + * Enable interrupt of adc digital controller by bitmask. + * + * @param adc_n ADC unit. + * @param intr Interrupt bitmask. + */ +static inline void adc_ll_digi_intr_enable(adc_ll_num_t adc_n, adc_digi_intr_t intr) +{ + if (adc_n == ADC_NUM_1) { + if (intr & ADC_DIGI_INTR_MASK_MONITOR) { + APB_SARADC.int_ena.adc1_thres = 1; + } + if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { + APB_SARADC.int_ena.adc1_done = 1; + } + } else { // adc_n == ADC_NUM_2 + if (intr & ADC_DIGI_INTR_MASK_MONITOR) { + APB_SARADC.int_ena.adc2_thres = 1; + } + if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { + APB_SARADC.int_ena.adc2_done = 1; + } + } +} + +/** + * Disable interrupt of adc digital controller by bitmask. + * + * @param adc_n ADC unit. + * @param intr Interrupt bitmask. + */ +static inline void adc_ll_digi_intr_disable(adc_ll_num_t adc_n, adc_digi_intr_t intr) +{ + if (adc_n == ADC_NUM_1) { + if (intr & ADC_DIGI_INTR_MASK_MONITOR) { + APB_SARADC.int_ena.adc1_thres = 0; + } + if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { + APB_SARADC.int_ena.adc1_done = 0; + } + } else { // adc_n == ADC_NUM_2 + if (intr & ADC_DIGI_INTR_MASK_MONITOR) { + APB_SARADC.int_ena.adc2_thres = 0; + } + if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { + APB_SARADC.int_ena.adc2_done = 0; + } + } +} + +/** + * Clear interrupt of adc digital controller by bitmask. + * + * @param adc_n ADC unit. + * @param intr Interrupt bitmask. + */ +static inline void adc_ll_digi_intr_clear(adc_ll_num_t adc_n, adc_digi_intr_t intr) +{ + if (adc_n == ADC_NUM_1) { + if (intr & ADC_DIGI_INTR_MASK_MONITOR) { + APB_SARADC.int_clr.adc1_thres = 1; + } + if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { + APB_SARADC.int_clr.adc1_done = 1; + } + } else { // adc_n == ADC_NUM_2 + if (intr & ADC_DIGI_INTR_MASK_MONITOR) { + APB_SARADC.int_clr.adc2_thres = 1; + } + if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { + APB_SARADC.int_clr.adc2_done = 1; + } + } +} + +/** + * Get interrupt status mask of adc digital controller. + * + * @param adc_n ADC unit. + * @return + * - intr Interrupt bitmask. + */ +static inline uint32_t adc_ll_digi_get_intr_status(adc_ll_num_t adc_n) +{ + uint32_t int_st = APB_SARADC.int_st.val; + uint32_t ret_msk = 0; if (adc_n == ADC_NUM_1) { - APB_SARADC.sar1_patt_tab[patt_tab_idx] &= ~patt_mask; - APB_SARADC.sar1_patt_tab[patt_tab_idx] |= pattern.val << patt_shift; - } - else { // adc_n == ADC_NUM_2 - APB_SARADC.sar2_patt_tab[patt_tab_idx] &= ~patt_mask; - APB_SARADC.sar2_patt_tab[patt_tab_idx] |= pattern.val << patt_shift; + if (int_st & APB_SARADC_ADC1_DONE_INT_ST_M) { + ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE; + } + if (int_st & APB_SARADC_ADC1_THRES_INT_ST) { + ret_msk |= ADC_DIGI_INTR_MASK_MONITOR; + } + } else { // adc_n == ADC_NUM_2 + if (int_st & APB_SARADC_ADC2_DONE_INT_ST_M) { + ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE; + } + if (int_st & APB_SARADC_ADC2_THRES_INT_ST_M) { + ret_msk |= ADC_DIGI_INTR_MASK_MONITOR; + } } + + return ret_msk; +} + +/** + * Set DMA eof num of adc digital controller. + * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. + * + * @param num eof num of DMA. + */ +static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) +{ + APB_SARADC.dma_conf.apb_adc_eof_num = num; +} + +/** + * Enable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_enable(void) +{ + APB_SARADC.dma_conf.apb_adc_trans = 1; +} + +/** + * Disable output data to DMA from adc digital controller. + */ +static inline void adc_ll_digi_dma_disable(void) +{ + APB_SARADC.dma_conf.apb_adc_trans = 0; +} + +/** + * Reset adc digital controller. + */ +static inline void adc_ll_digi_reset(void) +{ + APB_SARADC.dma_conf.apb_adc_reset_fsm = 1; + APB_SARADC.dma_conf.apb_adc_reset_fsm = 0; } /*--------------------------------------------------------------- @@ -225,7 +631,7 @@ static inline void adc_ll_set_pattern_table(adc_ll_num_t adc_n, uint32_t pattern * Set adc cct for PWDET controller. * * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. - * @prarm cct Range: 0 ~ 7. + * @param cct Range: 0 ~ 7. */ static inline void adc_ll_pwdet_set_cct(uint32_t cct) { @@ -251,18 +657,13 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) /** * Set adc output data format for RTC controller. * + * @note ESP32S2 RTC controller only support 13bit. * @prarm adc_n ADC unit. * @prarm bits Output data bits width option. */ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_width_t bits) { - if (adc_n == ADC_NUM_1) { - // SENS.sar_meas1_ctrl1.sar1_bit_width = bits; - // SENS.sar_reader1_ctrl.sar1_sample_bit = bits; - } else { // adc_n == ADC_NUM_2 - // SENS.sar_meas2_ctrl1.sar2_bit_width = bits; - // SENS.sar_reader2_ctrl.sar2_sample_bit = bits; - } + return; } /** @@ -270,7 +671,7 @@ static inline void adc_ll_rtc_set_output_format(adc_ll_num_t adc_n, adc_bits_wid * * @note Only one channel can be selected for once measurement. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel) @@ -282,12 +683,29 @@ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel) } } +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n, int channel) +{ + if (adc_n == ADC_NUM_1) { + SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected. + } else { // adc_n == ADC_NUM_2 + SENS.sar_meas2_ctrl2.sar2_en_pad = 0; //only one channel is selected. + } +} + /** * Start conversion once by software for RTC controller. * * @note It may be block to wait conversion idle for ADC1. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel) @@ -305,7 +723,7 @@ static inline void adc_ll_rtc_start_convert(adc_ll_num_t adc_n, int channel) /** * Check the conversion done flag for each ADCn for RTC controller. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @return * -true : The conversion process is finish. * -false : The conversion process is not finish. @@ -324,7 +742,7 @@ static inline bool adc_ll_rtc_convert_is_done(adc_ll_num_t adc_n) /** * Get the converted value for each ADCn for RTC controller. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. * @return * - Converted value. */ @@ -339,24 +757,124 @@ static inline int adc_ll_rtc_get_convert_value(adc_ll_num_t adc_n) return ret_val; } +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en) +{ + if (adc_n == ADC_NUM_1) { + SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert + } else { // adc_n == ADC_NUM_2 + SENS.sar_reader2_ctrl.sar2_data_inv = inv_en; // Enable / Disable ADC data invert + } +} + +/** + * Enable ADCn conversion complete interrupt for RTC controller. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_rtc_intr_enable(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + SENS.sar_reader1_ctrl.sar1_int_en = 1; + RTCCNTL.int_ena.rtc_saradc1 = 1; + } else { // adc_n == ADC_NUM_2 + SENS.sar_reader2_ctrl.sar2_int_en = 1; + RTCCNTL.int_ena.rtc_saradc2 = 1; + } +} + +/** + * Disable ADCn conversion complete interrupt for RTC controller. + * + * @param adc_n ADC unit. + */ +static inline void adc_ll_rtc_intr_disable(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + SENS.sar_reader1_ctrl.sar1_int_en = 0; + RTCCNTL.int_ena.rtc_saradc1 = 0; + } else { // adc_n == ADC_NUM_2 + SENS.sar_reader2_ctrl.sar2_int_en = 0; + RTCCNTL.int_ena.rtc_saradc2 = 0; + } +} + +/** + * Reset RTC controller FSM. + */ +static inline void adc_ll_rtc_reset(void) +{ + SENS.sar_meas1_ctrl1.rtc_saradc_reset = 1; + SENS.sar_meas1_ctrl1.rtc_saradc_reset = 0; +} + +/** + * Sets the number of cycles required for the conversion to complete and wait for the arbiter to stabilize. + * + * @note Only ADC2 have arbiter function. + * @param cycle range: [0,4]. + */ +static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) +{ + SENS.sar_reader2_ctrl.sar2_wait_arb_cycle = cycle; +} + +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 0: The data is correct to use. + * - 1: The data is invalid. The current controller is not enabled by the arbiter. + * - 2: The data is invalid. The current controller process was interrupted by a higher priority controller. + * - -1: The data is error. + */ +static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_ll_num_t adc_n, uint16_t raw_data) +{ + /* ADC1 don't need check data */ + if (adc_n == ADC_NUM_1) { + return ADC_RTC_DATA_OK; + } + adc_rtc_output_data_t *temp = (adc_rtc_output_data_t *)&raw_data; + if (temp->flag == 0) { + return ADC_RTC_DATA_OK; + } else if (temp->flag == 1) { + return ADC_RTC_CTRL_UNSELECTED; + } else if (temp->flag == 2) { + return ADC_RTC_CTRL_BREAK; + } else { + return ADC_RTC_DATA_FAIL; + } +} + /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ /** * Set ADC module power management. * - * @prarm manage Set ADC power status. + * @param manage Set ADC power status. */ static inline void adc_ll_set_power_manage(adc_ll_power_t manage) { /* Bit1 0:Fsm 1: SW mode Bit0 0:SW mode power down 1: SW mode power on */ if (manage == ADC_POWER_SW_ON) { + SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1; SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PU; } else if (manage == ADC_POWER_BY_FSM) { + SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 1; SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_FSM; } else if (manage == ADC_POWER_SW_OFF) { SENS.sar_power_xpd_sar.force_xpd_sar = SENS_FORCE_XPD_SAR_PD; + SENS.sar_meas1_ctrl1.rtc_saradc_clkgate_en = 0; } } @@ -382,14 +900,17 @@ static inline adc_ll_power_t adc_ll_get_power_manage(void) } /** - * ADC module clock division factor setting. ADC clock devided from APB clock. + * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`. * - * @prarm div Division factor. + * @param div Division factor. */ -static inline void adc_ll_set_clk_div(uint32_t div) +static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div) { - /* ADC clock devided from APB clk, e.g. 80 / 2 = 40Mhz, */ - APB_SARADC.ctrl.sar_clk_div = div; + if (adc_n == ADC_NUM_1) { + SENS.sar_reader1_ctrl.sar1_clk_div = div; + } else { // adc_n == ADC_NUM_2 + SENS.sar_reader2_ctrl.sar2_clk_div = div; + } } /** @@ -421,9 +942,9 @@ static inline void adc_ll_set_clk_div(uint32_t div) * * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. * - * @prarm adc_n ADC unit. - * @prarm channel ADCn channel number. - * @prarm atten The attenuation option. + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @param atten The attenuation option. */ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten) { @@ -435,30 +956,18 @@ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, a } /** - * ADC module RTC output data invert or not. + * Get the attenuation of a particular channel on ADCn. * - * @prarm adc_n ADC unit. + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. */ -static inline void adc_ll_rtc_output_invert(adc_ll_num_t adc_n, bool inv_en) +static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel) { if (adc_n == ADC_NUM_1) { - SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert - } else { // adc_n == ADC_NUM_2 - SENS.sar_reader2_ctrl.sar2_data_inv = inv_en; // Enable / Disable ADC data invert - } -} - -/** - * ADC module Digital output data invert or not. - * - * @prarm adc_n ADC unit. - */ -static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en) -{ - if (adc_n == ADC_NUM_1) { - APB_SARADC.ctrl2.sar1_inv = inv_en; // Enable / Disable ADC data invert - } else { // adc_n == ADC_NUM_2 - APB_SARADC.ctrl2.sar2_inv = inv_en; // Enable / Disable ADC data invert + return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3); + } else { + return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3); } } @@ -469,10 +978,10 @@ static inline void adc_ll_dig_output_invert(adc_ll_num_t adc_n, bool inv_en) * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep; * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2. * - * @prarm adc_n ADC unit. - * @prarm ctrl ADC controller. + * @param adc_n ADC unit. + * @param ctrl ADC controller. */ -static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl) +static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_controller_t ctrl) { if (adc_n == ADC_NUM_1) { switch ( ctrl ) { @@ -480,22 +989,16 @@ static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; - SENS.sar_hall_ctrl.xpd_hall_force = 1; // 1: SW control HALL power; 0: ULP FSM control HALL power. - SENS.sar_hall_ctrl.hall_phase_force = 1; // 1: SW control HALL phase; 0: ULP FSM control HALL phase. break; case ADC_CTRL_ULP: SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. SENS.sar_meas1_ctrl2.meas1_start_force = 0; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. SENS.sar_meas1_ctrl2.sar1_en_pad_force = 0; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; - SENS.sar_hall_ctrl.xpd_hall_force = 0; // 1: SW control HALL power; 0: ULP FSM control HALL power. - SENS.sar_hall_ctrl.hall_phase_force = 0; // 1: SW control HALL phase; 0: ULP FSM control HALL phase. break; case ADC_CTRL_DIG: SENS.sar_meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control. SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; - SENS.sar_hall_ctrl.xpd_hall_force = 1; // 1: SW control HALL power; 0: ULP FSM control HALL power. - SENS.sar_hall_ctrl.hall_phase_force = 1; // 1: SW control HALL phase; 0: ULP FSM control HALL phase. break; default: break; @@ -525,87 +1028,225 @@ static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t } /** - * Close ADC AMP module if don't use it for power save. - */ -static inline void adc_ll_amp_disable(void) -{ - //channel is set in the convert function - SENS.sar_meas1_ctrl1.force_xpd_amp = SENS_FORCE_XPD_AMP_PD; - //disable FSM, it's only used by the LNA. - SENS.sar_amp_ctrl3.amp_rst_fb_fsm = 0; - SENS.sar_amp_ctrl3.amp_short_ref_fsm = 0; - SENS.sar_amp_ctrl3.amp_short_ref_gnd_fsm = 0; - SENS.sar_amp_ctrl1.sar_amp_wait1 = 1; - SENS.sar_amp_ctrl1.sar_amp_wait2 = 1; - SENS.sar_amp_ctrl2.sar_amp_wait3 = 1; -} - -/*--------------------------------------------------------------- - Hall sensor setting ----------------------------------------------------------------*/ - -/** - * Enable hall sensor. - */ -static inline void adc_ll_hall_enable(void) -{ - SENS.sar_hall_ctrl.xpd_hall = 1; -} - -/** - * Disable hall sensor. - */ -static inline void adc_ll_hall_disable(void) -{ - SENS.sar_hall_ctrl.xpd_hall = 0; -} - -/** - * Reverse phase of hall sensor. - */ -static inline void adc_ll_hall_phase_enable(void) -{ - SENS.sar_hall_ctrl.hall_phase = 1; -} - -/** - * Don't reverse phase of hall sensor. - */ -static inline void adc_ll_hall_phase_disable(void) -{ - SENS.sar_hall_ctrl.hall_phase = 0; -} - -/** - * Set hall sensor controller. + * Set ADC2 module arbiter work mode. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data. * - * @param hall_ctrl Hall controller. + * @note Only ADC2 support arbiter. + * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. + * + * @param mode Refer to `adc_arbiter_mode_t`. */ -static inline void adc_ll_set_hall_controller(adc_ll_hall_controller_t hall_ctrl) +static inline void adc_ll_set_arbiter_work_mode(adc_arbiter_mode_t mode) { - SENS.sar_hall_ctrl.xpd_hall_force = hall_ctrl; // 1: SW control HALL power; 0: ULP FSM control HALL power. - SENS.sar_hall_ctrl.hall_phase_force = hall_ctrl; // 1: SW control HALL phase; 0: ULP FSM control HALL phase. + SENS.sar_meas2_mux.sar2_rtc_force = 0; // Enable arbiter in wakeup mode + if (mode == ADC_ARB_MODE_FIX) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 1; + } else if (mode == ADC_ARB_MODE_LOOP) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_fix_priority = 0; + } else { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_grant_force = 1; // Shield arbiter. + } } /** - * Output ADC2 reference voltage to gpio 25 or 26 or 27 + * Set ADC2 module controller priority in arbiter. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC data, and the validity of the data can be judged by the flag bit in the data. * - * This function utilizes the testing mux exclusive to ADC 2 to route the - * reference voltage one of ADC2's channels. Supported gpios are gpios - * 25, 26, and 27. This refernce voltage can be manually read from the pin - * and used in the esp_adc_cal component. + * @note Only ADC2 support arbiter. + * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. + * @note Default priority: Wi-Fi(2) > RTC(1) > Digital(0); * - * @param[in] io GPIO number (gpios 25,26,27 supported) - * - * @return - * - true: v_ref successfully routed to selected gpio - * - false: Unsupported gpio + * @param pri_rtc RTC controller priority. Range: 0 ~ 2. + * @param pri_dig Digital controller priority. Range: 0 ~ 2. + * @param pri_pwdet Wi-Fi controller priority. Range: 0 ~ 2. */ -static inline bool adc_ll_vref_output(int io) +static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig, uint8_t pri_pwdet) { - return false; + if (pri_rtc != pri_dig && pri_rtc != pri_pwdet && pri_dig != pri_pwdet) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_priority = pri_rtc; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_priority = pri_dig; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_priority = pri_pwdet; + } + /* Should select highest priority controller. */ + if (pri_rtc > pri_dig) { + if (pri_rtc > pri_pwdet) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 1; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0; + } else { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1; + } + } else { + if (pri_dig > pri_pwdet) { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 1; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 0; + } else { + APB_SARADC.apb_adc_arb_ctrl.adc_arb_apb_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_rtc_force = 0; + APB_SARADC.apb_adc_arb_ctrl.adc_arb_wifi_force = 1; + } + } } +/** + * Force switch ADC2 to RTC controller in sleep mode. Shield arbiter. + * In sleep mode, the arbiter is in power-down mode. + * Need to switch the controller to RTC to shield the control of the arbiter. + * After waking up, it needs to switch to arbiter control. + * + * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller. + * @note Only support ADC2. + */ +static inline void adc_ll_enable_sleep_controller(void) +{ + SENS.sar_meas2_mux.sar2_rtc_force = 1; +} + +/** + * Force switch ADC2 to arbiter in wakeup mode. + * In sleep mode, the arbiter is in power-down mode. + * Need to switch the controller to RTC to shield the control of the arbiter. + * After waking up, it needs to switch to arbiter control. + * + * @note The hardware will do this automatically. In normal use, there is no need to call this interface to manually switch the controller. + * @note Only support ADC2. + */ +static inline void adc_ll_disable_sleep_controller(void) +{ + SENS.sar_meas2_mux.sar2_rtc_force = 0; +} + +/* ADC calibration code. */ +#include "soc/rtc_cntl_reg.h" +#include "i2c_rtc_clk.h" + +#define I2C_ADC 0X69 +#define I2C_ADC_HOSTID 0 + +#define ANA_CONFIG2_REG 0x6000E048 +#define ANA_CONFIG2_M (BIT(18)) + +#define SAR1_ENCAL_GND_ADDR 0x7 +#define SAR1_ENCAL_GND_ADDR_MSB 5 +#define SAR1_ENCAL_GND_ADDR_LSB 5 + +#define SAR2_ENCAL_GND_ADDR 0x7 +#define SAR2_ENCAL_GND_ADDR_MSB 7 +#define SAR2_ENCAL_GND_ADDR_LSB 7 + +#define SAR1_INITIAL_CODE_HIGH_ADDR 0x1 +#define SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3 +#define SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0 + +#define SAR1_INITIAL_CODE_LOW_ADDR 0x0 +#define SAR1_INITIAL_CODE_LOW_ADDR_MSB 0x7 +#define SAR1_INITIAL_CODE_LOW_ADDR_LSB 0x0 + +#define SAR2_INITIAL_CODE_HIGH_ADDR 0x4 +#define SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3 +#define SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0 + +#define SAR2_INITIAL_CODE_LOW_ADDR 0x3 +#define SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7 +#define SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0 + +#define SAR1_DREF_ADDR 0x2 +#define SAR1_DREF_ADDR_MSB 0x6 +#define SAR1_DREF_ADDR_LSB 0x4 + +#define SAR2_DREF_ADDR 0x5 +#define SAR2_DREF_ADDR_MSB 0x6 +#define SAR2_DREF_ADDR_LSB 0x4 + +#define ADC_HAL_CAL_OFFSET_RANGE (4096) +#define ADC_HAL_CAL_TIMES (10) + +/** + * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param channel adc channel number. + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + */ +static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd) +{ + /* Enable i2s_write_reg function. */ + void phy_get_romfunc_addr(void); + phy_get_romfunc_addr(); + CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); + SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18)); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16)); + + /* Enable/disable internal connect GND (for calibration). */ + if (adc_n == ADC_NUM_1) { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR1_DREF_ADDR, 4); + if (internal_gnd) { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR1_ENCAL_GND_ADDR, 1); + } else { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0); + } + } else { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR2_DREF_ADDR, 4); + if (internal_gnd) { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR2_ENCAL_GND_ADDR, 1); + } else { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0); + } + } +} + +/** + * Resume register status after calibration. + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n) +{ + if (adc_n == ADC_NUM_1) { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0); + } else { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0); + } +} + +/** + * Set the calibration result to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t param) +{ + uint8_t msb = param >> 8; + uint8_t lsb = param & 0xFF; + /* Enable i2s_write_reg function. */ + void phy_get_romfunc_addr(void); + phy_get_romfunc_addr(); + SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18)); + SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16)); + + if (adc_n == ADC_NUM_1) { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR1_INITIAL_CODE_HIGH_ADDR, msb); + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR1_INITIAL_CODE_LOW_ADDR, lsb); + } else { + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR2_INITIAL_CODE_HIGH_ADDR, msb); + I2C_WRITEREG_MASK_RTC(I2C_ADC, SAR2_INITIAL_CODE_LOW_ADDR, lsb); + } +} +/* Temp code end. */ #ifdef __cplusplus } diff --git a/components/soc/src/esp32s2/include/hal/dac_ll.h b/components/soc/src/esp32s2/include/hal/dac_ll.h index d99471810..c4da302f2 100644 --- a/components/soc/src/esp32s2/include/hal/dac_ll.h +++ b/components/soc/src/esp32s2/include/hal/dac_ll.h @@ -28,6 +28,10 @@ extern "C" { #endif +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ + /** * Power on dac module and start output voltage. * @@ -36,6 +40,7 @@ extern "C" { */ static inline void dac_ll_power_on(dac_channel_t channel) { + SENS.sar_dac_ctrl1.dac_clkgate_en = 1; RTCIO.pad_dac[channel].dac_xpd_force = 1; RTCIO.pad_dac[channel].xpd_dac = 1; } @@ -49,6 +54,9 @@ static inline void dac_ll_power_down(dac_channel_t channel) { RTCIO.pad_dac[channel].dac_xpd_force = 0; RTCIO.pad_dac[channel].xpd_dac = 0; + if (RTCIO.pad_dac[0].xpd_dac == 0 && RTCIO.pad_dac[1].xpd_dac == 0) { + SENS.sar_dac_ctrl1.dac_clkgate_en = 0; + } } /** @@ -69,6 +77,15 @@ static inline void dac_ll_update_output_value(dac_channel_t channel, uint8_t val } } +/** + * Reset dac by software. + */ +static inline void dac_ll_rtc_reset(void) +{ + SENS.sar_dac_ctrl1.dac_reset = 1; + SENS.sar_dac_ctrl1.dac_reset = 0; +} + /************************************/ /* DAC cosine wave generator API's */ /************************************/ @@ -168,6 +185,10 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset) } } +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ + /************************************/ /* DAC DMA API's */ /************************************/ @@ -178,6 +199,7 @@ static inline void dac_ll_cw_set_dc_offset(dac_channel_t channel, int8_t offset) static inline void dac_ll_dma_enable(void) { SENS.sar_dac_ctrl1.dac_dig_force = 1; + SENS.sar_dac_ctrl1.dac_clk_inv = 1; } /** @@ -186,6 +208,7 @@ static inline void dac_ll_dma_enable(void) static inline void dac_ll_dma_disable(void) { SENS.sar_dac_ctrl1.dac_dig_force = 0; + SENS.sar_dac_ctrl1.dac_clk_inv = 0; } #ifdef __cplusplus diff --git a/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h b/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h index 9074d6b4b..5aab11106 100644 --- a/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h +++ b/components/soc/src/esp32s2/include/hal/touch_sensor_hal.h @@ -623,12 +623,6 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable); */ #define touch_hal_sleep_read_baseline(baseline) touch_ll_sleep_read_baseline(baseline) -#define touch_hal_sleep_read_smooth(smooth_data) touch_ll_sleep_read_smooth(smooth_data) - -#define touch_hal_sleep_read_data(raw_data) touch_ll_sleep_read_data(raw_data) - -#define touch_hal_sleep_reset_baseline() touch_ll_sleep_reset_baseline() - /** * Read smooth data of touch sensor for sleep pad. */ diff --git a/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h b/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h index d4bfece45..992066c5a 100644 --- a/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h +++ b/components/soc/src/esp32s2/include/hal/touch_sensor_ll.h @@ -231,26 +231,6 @@ static inline void touch_ll_get_fsm_mode(touch_fsm_mode_t *mode) *mode = (touch_fsm_mode_t)RTCCNTL.touch_ctrl2.touch_start_force; } -static inline void touch_ll_clk_enable(void) -{ - RTCCNTL.touch_ctrl2.touch_clkgate_en = 1; //enable touch clock for FSM. or force enable. -} - -static inline void touch_ll_clk_disable(void) -{ - RTCCNTL.touch_ctrl2.touch_clkgate_en = 0; //enable touch clock for FSM. or force enable. -} - -/** - * Touch timer trigger measurement and always wait measurement done. - * Force done for touch timer ensures that the timer always can get the measurement done signal. - */ -static inline void touch_ll_timer_force_done(void) -{ - RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_FORCE_DONE; - RTCCNTL.touch_ctrl2.touch_timer_force_done = TOUCH_LL_TIMER_DONE; -} - /** * Enable/disable clock gate of touch sensor. * diff --git a/components/soc/src/hal/adc_hal.c b/components/soc/src/hal/adc_hal.c index 562e3b788..509ba8e86 100644 --- a/components/soc/src/hal/adc_hal.c +++ b/components/soc/src/hal/adc_hal.c @@ -17,72 +17,22 @@ void adc_hal_init(void) { // Set internal FSM wait time, fixed value. - adc_ll_dig_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT, - SOC_ADC_FSM_STANDBY_WAIT_DEFAULT); - adc_ll_dig_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT); - adc_hal_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT); - adc_hal_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT); + adc_ll_digi_set_fsm_time(SOC_ADC_FSM_RSTB_WAIT_DEFAULT, SOC_ADC_FSM_START_WAIT_DEFAULT, + SOC_ADC_FSM_STANDBY_WAIT_DEFAULT); + adc_ll_digi_set_sample_cycle(ADC_FSM_SAMPLE_CYCLE_DEFAULT); + adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT); } -void adc_hal_dig_controller_config(const adc_hal_dig_config_t *cfg) +void adc_hal_deinit(void) { - /* If enable digtal controller, adc xpd should always on. */ - adc_ll_set_power_manage(ADC_POWER_SW_ON); - adc_ll_set_clk_div(cfg->clk_div); - /* Single channel mode or multi channel mode. */ - adc_ll_dig_set_convert_mode(cfg->conv_mode); - if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) { - adc_ll_set_controller(ADC_NUM_1, ADC_CTRL_DIG); - adc_ll_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len); - for (int i = 0; i < cfg->adc1_pattern_len; i++) { - adc_ll_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]); - } - } - if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) { - adc_ll_set_controller(ADC_NUM_2, ADC_CTRL_DIG); - adc_ll_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len); - for (int i = 0; i < cfg->adc2_pattern_len; i++) { - adc_ll_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]); - } - } - adc_ll_dig_set_output_format(cfg->format); - if (cfg->conv_limit_en) { - adc_ll_dig_set_convert_limit_num(cfg->conv_limit_num); - adc_ll_dig_convert_limit_enable(); - } else { - adc_ll_dig_convert_limit_disable(); - } - adc_ll_dig_set_data_source(ADC_I2S_DATA_SRC_ADC); + adc_ll_set_power_manage(ADC_POWER_SW_OFF); } -int adc_hal_convert(adc_ll_num_t adc_n, int channel) +int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value) { adc_ll_rtc_enable_channel(adc_n, channel); adc_ll_rtc_start_convert(adc_n, channel); while (adc_ll_rtc_convert_is_done(adc_n) != true); - return adc_ll_rtc_get_convert_value(adc_n); + *value = adc_ll_rtc_get_convert_value(adc_n); + return (int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*value)); } - -int adc_hal_hall_convert(void) -{ - int Sens_Vp0; - int Sens_Vn0; - int Sens_Vp1; - int Sens_Vn1; - int hall_value; - // convert for 4 times with different phase and outputs - adc_ll_hall_phase_disable(); // hall phase - Sens_Vp0 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0 ); - Sens_Vn0 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3 ); - adc_ll_hall_phase_enable(); - Sens_Vp1 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_0 ); - Sens_Vn1 = adc_hal_convert( ADC_NUM_1, ADC_CHANNEL_3 ); - hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0); - return hall_value; -} - -void adc_hal_output_invert(adc_ll_num_t adc_n, bool inv_en) -{ - adc_ll_rtc_output_invert(adc_n, inv_en); - adc_ll_dig_output_invert(adc_n, inv_en); -} \ No newline at end of file diff --git a/docs/Doxyfile b/docs/Doxyfile index 84269c282..66907b703 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -86,7 +86,6 @@ INPUT = \ ## ## Peripherals - API Reference ## - $(IDF_PATH)/components/driver/include/driver/adc.h \ $(IDF_PATH)/components/driver/include/driver/can.h \ $(IDF_PATH)/components/soc/include/hal/can_types.h \ $(IDF_PATH)/components/driver/include/driver/dac.h \ @@ -103,10 +102,12 @@ INPUT = \ $(IDF_PATH)/components/driver/include/driver/spi_common.h \ $(IDF_PATH)/components/driver/include/driver/spi_master.h \ $(IDF_PATH)/components/driver/include/driver/spi_slave.h \ - $(IDF_PATH)/components/driver/$(IDF_TARGET)/include/touch_sensor.h \ - $(IDF_PATH)/components/driver/esp32s2/include/temp_sensor.h \ + $(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/adc.h \ + $(IDF_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \ + $(IDF_PATH)/components/driver/esp32s2/include/driver/temp_sensor.h \ $(IDF_PATH)/components/driver/include/driver/timer.h \ $(IDF_PATH)/components/driver/include/driver/touch_sensor_common.h \ + $(IDF_PATH)/components/driver/include/driver/adc_common.h \ $(IDF_PATH)/components/driver/include/driver/uart.h \ $(IDF_PATH)/components/esp_adc_cal/include/esp_adc_cal.h \ $(IDF_PATH)/components/soc/include/hal/rmt_types.h \ diff --git a/examples/peripherals/adc/main/adc1_example_main.c b/examples/peripherals/adc/main/adc1_example_main.c index 1cae709d1..85baf3a50 100644 --- a/examples/peripherals/adc/main/adc1_example_main.c +++ b/examples/peripherals/adc/main/adc1_example_main.c @@ -22,8 +22,10 @@ #if CONFIG_IDF_TARGET_ESP32 static esp_adc_cal_characteristics_t *adc_chars; static const adc_channel_t channel = ADC_CHANNEL_6; //GPIO34 if ADC1, GPIO14 if ADC2 +static const adc_bits_width_t width = ADC_WIDTH_BIT_12; #elif CONFIG_IDF_TARGET_ESP32S2 static const adc_channel_t channel = ADC_CHANNEL_6; // GPIO7 if ADC1, GPIO17 if ADC2 +static const adc_bits_width_t width = ADC_WIDTH_BIT_13; #endif static const adc_atten_t atten = ADC_ATTEN_DB_0; static const adc_unit_t unit = ADC_UNIT_1; @@ -67,7 +69,7 @@ void app_main(void) //Configure ADC if (unit == ADC_UNIT_1) { - adc1_config_width(ADC_WIDTH_BIT_12); + adc1_config_width(width); adc1_config_channel_atten(channel, atten); } else { adc2_config_channel_atten((adc2_channel_t)channel, atten); @@ -76,7 +78,7 @@ void app_main(void) #if CONFIG_IDF_TARGET_ESP32 //Characterize ADC adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); - esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); + esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars); print_char_val_type(val_type); #endif @@ -89,7 +91,7 @@ void app_main(void) adc_reading += adc1_get_raw((adc1_channel_t)channel); } else { int raw; - adc2_get_raw((adc2_channel_t)channel, ADC_WIDTH_BIT_12, &raw); + adc2_get_raw((adc2_channel_t)channel, width, &raw); adc_reading += raw; } } diff --git a/examples/peripherals/adc2/main/adc2_example_main.c b/examples/peripherals/adc2/main/adc2_example_main.c index 87c5a4315..ec35cce86 100644 --- a/examples/peripherals/adc2/main/adc2_example_main.c +++ b/examples/peripherals/adc2/main/adc2_example_main.c @@ -19,6 +19,12 @@ #define DAC_EXAMPLE_CHANNEL CONFIG_EXAMPLE_DAC_CHANNEL #define ADC2_EXAMPLE_CHANNEL CONFIG_EXAMPLE_ADC2_CHANNEL +#if CONFIG_IDF_TARGET_ESP32 +static const adc_bits_width_t width = ADC_WIDTH_BIT_12; +#elif CONFIG_IDF_TARGET_ESP32S2 +static const adc_bits_width_t width = ADC_WIDTH_BIT_13; +#endif + void app_main(void) { uint8_t output_data=0; @@ -46,7 +52,7 @@ void app_main(void) printf("start conversion.\n"); while(1) { dac_output_voltage( DAC_EXAMPLE_CHANNEL, output_data++ ); - r = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, ADC_WIDTH_12Bit, &read_raw); + r = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, width, &read_raw); if ( r == ESP_OK ) { printf("%d: %d\n", output_data, read_raw ); } else if ( r == ESP_ERR_INVALID_STATE ) { diff --git a/examples/peripherals/i2s_adc_dac/main/app_main.c b/examples/peripherals/i2s_adc_dac/main/app_main.c index c97fe96aa..bd2a72888 100644 --- a/examples/peripherals/i2s_adc_dac/main/app_main.c +++ b/examples/peripherals/i2s_adc_dac/main/app_main.c @@ -11,6 +11,8 @@ #include "audio_example_file.h" #include "esp_adc_cal.h" +#if CONFIG_IDF_TARGET_ESP32 + static const char* TAG = "ad/da"; #define V_REF 1100 #define ADC1_TEST_CHANNEL (ADC1_CHANNEL_7) @@ -288,5 +290,4 @@ esp_err_t app_main(void) xTaskCreate(adc_read_task, "ADC read task", 2048, NULL, 5, NULL); return ESP_OK; } - - +#endif diff --git a/examples/peripherals/temp_sensor_esp32s2/main/temp_sensor_main.c b/examples/peripherals/temp_sensor_esp32s2/main/temp_sensor_main.c index dd35d2f1f..3cf1697d3 100644 --- a/examples/peripherals/temp_sensor_esp32s2/main/temp_sensor_main.c +++ b/examples/peripherals/temp_sensor_esp32s2/main/temp_sensor_main.c @@ -15,7 +15,7 @@ /* Note: ESP32 don't support temperature sensor */ #if CONFIG_IDF_TARGET_ESP32S2 -#include "temp_sensor.h" +#include "driver/temp_sensor.h" static const char *TAG = "TempSensor"; diff --git a/examples/system/app_trace_to_host/main/app_trace_to_host_example_main.c b/examples/system/app_trace_to_host/main/app_trace_to_host_example_main.c index f2b382df9..36ac767e9 100644 --- a/examples/system/app_trace_to_host/main/app_trace_to_host_example_main.c +++ b/examples/system/app_trace_to_host/main/app_trace_to_host_example_main.c @@ -88,7 +88,11 @@ static int adc1_sample_and_show(int sampling_period) void app_main(void) { ESP_LOGI(TAG, "Enabling ADC1 on channel 6 / GPIO34."); +#if CONFIG_IDF_TARGET_ESP32 adc1_config_width(ADC_WIDTH_BIT_12); +#elif CONFIG_IDF_TARGET_ESP32S2 + adc1_config_width(ADC_WIDTH_BIT_13); +#endif adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_DB_11); ESP_LOGI(TAG, "Enabling CW generator on DAC channel 1 / GPIO25."); diff --git a/examples/system/ulp_adc/main/ulp_adc_example_main.c b/examples/system/ulp_adc/main/ulp_adc_example_main.c index fdd314ef5..9e38e9ff7 100644 --- a/examples/system/ulp_adc/main/ulp_adc_example_main.c +++ b/examples/system/ulp_adc/main/ulp_adc_example_main.c @@ -64,7 +64,11 @@ static void init_ulp_program(void) /* Note: when changing channel here, also change 'adc_channel' constant in adc.S */ adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11); +#if CONFIG_IDF_TARGET_ESP32 adc1_config_width(ADC_WIDTH_BIT_12); +#elif CONFIG_IDF_TARGET_ESP32S2 + adc1_config_width(ADC_WIDTH_BIT_13); +#endif adc1_ulp_enable(); /* Set low and high thresholds, approx. 1.35V - 1.75V*/ diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index 5fb900716..62f3b03b5 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -336,7 +336,7 @@ example_test_012: UT_001: extends: .unit_test_template - parallel: 36 + parallel: 37 tags: - ESP32_IDF - UT_T1_1