添加原像心率 1817/1 1817/head 1825/target/1 sdk602patch1126
authorpenglei <1624952103@qq.com>
Mon, 9 Jun 2025 07:51:57 +0000 (15:51 +0800)
committerpenglei <1624952103@qq.com>
Mon, 9 Jun 2025 07:51:57 +0000 (15:51 +0800)
57 files changed:
code/sdk/build/config/target_config/brandy/config.py
code/sdk/drivers/boards/brandy_evb/board_config/board_w9.h
code/sdk/drivers/drivers/driver/touch/cst86xx_touch/cst86xx_touch1.c
code/sdk/zhihui/UI/producttest/include/testPresenter.h
code/sdk/zhihui/UI/producttest/src/testhrsenson.cpp
code/sdk/zhihui/drivers/bp/bn02/bn02.c
code/sdk/zhihui/drivers/mag/service/mag_service.c
code/sdk/zhihui/drivers/ppg/CMakeLists.txt
code/sdk/zhihui/drivers/ppg/gh3x2x/inc/gh3x2x_hal.h
code/sdk/zhihui/drivers/ppg/gh3x2x/src/gh3x2x_hal.c
code/sdk/zhihui/drivers/ppg/hx3695/CMakeLists.txt
code/sdk/zhihui/drivers/ppg/hx3695/hx3695.c
code/sdk/zhihui/drivers/ppg/hx3695/hx3695.h
code/sdk/zhihui/drivers/ppg/hx3695/hx3695_check_touch.c
code/sdk/zhihui/drivers/ppg/hx3695/hx3695_hal.c
code/sdk/zhihui/drivers/ppg/hx3695/hx3695_hrs_custom.c
code/sdk/zhihui/drivers/ppg/pah8009/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/Interrupt_function.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/pxi_interp.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/pxi_interp.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/libv307009_4.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pah8009_testpattern_HRD.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pxialg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pxivar.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/test_library_HRD.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/libv703_0_1.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/pah8009_testpattern_SPO2.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/pxialg_spo2.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/test_library_SPO2.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_stress/V6033/pxialg_hrv.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/factory/pah8009_factory_reg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/factory/pah800x_factory_test.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/factory/pah800x_factory_test.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_8009_reg_arr_default_20220623.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x_config.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_unit.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/ppgBleService/CMakeLists.txt
code/sdk/zhihui/drivers/ppg/service/CMakeLists.txt
code/sdk/zhihui/drivers/ppg/service/ppg_at_cmd.c [moved from code/sdk/zhihui/drivers/ppg/service/ppg_at_cmd.cpp with 97% similarity]
code/sdk/zhihui/drivers/ppg/service/ppg_at_cmd.h
code/sdk/zhihui/drivers/ppg/service/ppg_hal.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/service/ppg_hal.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/service/ppg_service.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/service/ppg_service.cpp [deleted file]
code/sdk/zhihui/drivers/ppg/service/ppg_service.h
code/sdk/zhihui/drivers/ppg/vc9202/src/vc9202_hal.c
code/sdk/zhihui/drivers/ppg/vc921x/src/vc921x_hal.c
code/sdk/zhihui/drivers/rotary_encoder/mixo/mixo_ots_driver.c
code/sdk/zhihui/services/factorytest_service/factorytest_protocol.c
code/sdk/zhihui/utils/custom_utils.c
code/sdk/zhihui/utils/custom_utils_at_cmd.c

index 1312d53..8bc109d 100644 (file)
@@ -569,6 +569,7 @@ target = {
                     'CYWEE_SPORT',
                     'CYWEE_MAC_ACTIVE',
                     'SUPPORT_CAT1_SERVICE',
+                    'SUPPORT_CYWEE_SERVICE',
                     'SUPPORT_TCPIP',                                   
                     'SUPPORT_HID_SERVICE',
                     'SUPPORT_BAIDU_MAP',
@@ -591,7 +592,7 @@ target = {
                     'NANDFLASH_F35UQA',
                     'BLE_INSTRUCT',
                     'FACTORYTEST_SERVICE',
-                    'PPG_GH3X2X',
+                    #'PPG_GH3X2X',
                     'GYRO_SH5001',
                     'ROTARYENCODER_MIXO',
                     ],
@@ -628,7 +629,8 @@ target = {
                         "cywee",
                         "ppg_sensor_gh3x2x",
                         "bp_sensor",
-                        'gyro',
+                        "gyro",
+                        "ppg_sensor_pah8009",
                            ],
                'image_analysis': False,
                'fs_image_path':'fd230',
index d43bff4..4939b1c 100644 (file)
@@ -15,7 +15,7 @@
 extern void bp_int_callback(pin_t pin, uintptr_t param);
 #endif
 
-#ifdef PPG_GH3X2X
+#ifdef SUPPORT_PPG_SERVICE
 extern void ppg_int_callback(pin_t pin, uintptr_t param);
 #endif
 
@@ -24,9 +24,12 @@ extern void gyro_int_callback(pin_t pin, uintptr_t param);
 #endif
 
 #ifdef ROTARYENCODER_MIXO
-extern void mixo_int_callback(pin_t pin, uintptr_t param);
+// extern void mixo_int_callback(pin_t pin, uintptr_t param);
 #endif
 
+#ifdef SUPPORT_CYWEE_SERVICE
+extern void cywee_int_callback(pin_t pin, uintptr_t param);
+#endif
 
 /**
  * @addtogroup connectivity_config_boards
@@ -225,7 +228,7 @@ const hal_pio_config_t g_pio_function_config[PIN_MAX_NUMBER] = {
     { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_DISABLE  },   // S_AGPIO_R3     NC   
     { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_DISABLE  },    // S_AGPIO_R4     tp reset
     { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE  },   // S_AGPIO_R5     touch int
-    { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE },    // S_AGPIO_R6     PRG_INT 心率中断
+    { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE },    // S_AGPIO_R6     PRG_INT 心率中断
     { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE },   // S_AGPIO_R7     GYRO_INT2
 #ifdef ENABLE_GYRO
     { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE },   // S_AGPIO_R8     GYRO_INT1
@@ -316,11 +319,11 @@ const hal_gpio_config_t g_gpio_function_config[PIN_MAX_NUMBER] = {
 //默认开启 EXT LDO V3.0 V1.8
     {   S_AGPIO_L18, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL },
 
-#ifdef ENABLE_CYWEE
+#ifdef SUPPORT_CYWEE_SERVICE
     /**G sensor G_INT1 S_AGPIO_L11 G_INT2 S_AGPIO_L19   采用timer 时这些中断要屏蔽*/
-    // {   S_AGPIO_L11, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_RISING_EDGE, cywee_int_callback },
+    {   S_AGPIO_L11, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_RISING_EDGE, cywee_int_callback },
     //{   S_AGPIO_L19, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_DEDGE, cywee_int_callback },
-#endif   
+#endif    
     /**S_AGPIO_R1 GPO alipay默认resetpin*/
     {   S_AGPIO_R1, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL },
 #ifdef SUPPORT_CAT1_SERVICE
@@ -338,8 +341,12 @@ const hal_gpio_config_t g_gpio_function_config[PIN_MAX_NUMBER] = {
 #ifdef ENABLE_BN02
      {   S_AGPIO_R3, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_RISING_EDGE, bp_int_callback },
 #endif
+#ifdef SUPPORT_PPG_SERVICE
 #ifdef PPG_GH3X2X
-    // {   S_AGPIO_R6, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_RISING_EDGE,  ppg_int_callback},
+    {   S_AGPIO_R6, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_RISING_EDGE,  ppg_int_callback},
+#elif defined PPG_PAH8009
+    {   S_AGPIO_R6, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_FALLING_EDGE,  ppg_int_callback},
+#endif
 #endif
 #ifdef ROTARYENCODER_MIXO
     // {   S_AGPIO_L0, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_DEDGE,  mixo_int_callback},
index c394421..e1aaa3e 100644 (file)
@@ -172,7 +172,7 @@ static ext_errno cst86xx_suspend(void)
         return EXT_ERR_SUCCESS;\r
     }\r
 \r
-    cst86xx_reset();//唤醒IC\r
+    // cst86xx_reset();//唤醒IC\r
 \r
     /* Send Sleep Cmd */\r
     reg_write = CST86XX_SLEEP_CMD;\r
index 15eeac5..694f380 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com\r
  * @Date: 2024-08-23 10:50:37\r
  * @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-05-13 18:35:42\r
+ * @LastEditTime: 2025-06-06 16:20:02\r
  * @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/producttest/include/testPresenter.h\r
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
  */\r
index 6bde9cd..69b8824 100644 (file)
@@ -4,12 +4,6 @@
 #include "producttest/include/testhrsenson.h" 
 #include "AlarmClockModel.h"
 #include "cmsis_os2.h"
-#ifdef SUPPORT_CAT1_SERVICE
-#include "cat1_server.h"
-#include "cat1_ctl.h"
-#include "cat1_server_hal.h"
-#endif
-#include "ppg_service.h"
 #include "producttest/include/testView.h"
 #ifdef __cplusplus
 #if __cplusplus
@@ -19,9 +13,12 @@ extern "C"
 #endif
     #include "pm_veto.h"
     #include "pm.h"
-#ifdef PPG_VC9202
-    #include "vc9202_user.h"
+
+#ifdef SUPPORT_PPG_SERVICE
+#include "ppg_service.h"
+#include "ppg_hal.h"
 #endif
+
 #ifdef __cplusplus
 #if __cplusplus
 }
@@ -100,50 +97,25 @@ namespace OHOS
     static bool button_falg=true;
     void testhrsenson1View:: setgrayvalue(int g,int r,int ir)
     {
-#ifdef PPG_HX3695
-        if(label_hrsenson_value_vison!=NULL)
-        {
-
-            char buf[124]={0};
-            sprintf(buf,"gray:\n green:%d\nred:%d\nir:%d",g,r,ir);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s",buf);
-            label_hrsenson_value_vison->SetText(buf);
-            RootView::GetInstance()->Invalidate();
-            int8_t md = PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST;
-            send_ppg_cmd_msg(md);
-            button_falg=true;
-        }
-#endif
     }
     void testhrsenson1View:: setlightvalue(int g,int r,int ir)
     {
         char buf[124]={0};
- 
         if(label_hrsenson_value_vison!=nullptr)
         {
-#ifdef PPG_HX3695    
-            sprintf(buf,"leaklight:\ngreen:%d\nred:%d\nir:%d",g,r,ir);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s",buf);
-            label_hrsenson_value_vison->SetText(buf);
-            RootView::GetInstance()->Invalidate();
-            int8_t md = PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST;
-            send_ppg_cmd_msg(md);
-            button_falg=true;
-#elif defined PPG_VC9202
-            //漏光测试
-            // send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST);
-            LOS_Msleep(500);
-            uint32_t led_cur = 0;
-            uint32_t apre_val = 0;
-            uint32_t aps_val = 9;
-            vc9202_get_leaklight_data(&led_cur,&apre_val,&aps_val);
+#ifdef SUPPORT_PPG_SERVICE       
+            LOS_Msleep(1000);
+            uint32_t ch0 = 0;
+            uint32_t ch1 = 0;
+            uint32_t ch2 = 0;
+            ppg_get_leaklight_data(&ch0,&ch1,&ch2);
             send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);
-            sprintf(buf,"leaklight:\ngreen:%d\nred:%d\nir:%d",led_cur,apre_val,aps_val);
+            sprintf(buf,"leaklight:\ngreen:%d\nred:%d\nir:%d",ch0,ch1,ch2);
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s",buf);
             label_hrsenson_value_vison->SetText(buf);
             RootView::GetInstance()->Invalidate();
             button_falg=true;
-#endif 
+#endif
         }    
     }
 
@@ -197,9 +169,7 @@ namespace OHOS
             int8_t md = PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST;
             send_ppg_cmd_msg(md);
              button_falg=false;
-#ifdef PPG_VC9202
             testhrsenson1View::setlightvalue(0,0,0);
-#endif
         }  
 
     }
index 7d2de8c..6f0edaf 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com\r
  * @Date: 2025-01-16 12:35:15\r
  * @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-05-24 14:43:40\r
+ * @LastEditTime: 2025-06-04 15:00:26\r
  * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/bn02/bn02.c\r
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
  */\r
 \r
 #define POWER_EN      S_AGPIO_R0\r
 \r
+#define BN02_FILE "user/userdata/bn02.bin"\r
+\r
+static int DATA_HANDLE = 1 << 24;\r
+\r
+static FILE *fp = NULL;\r
+\r
+static int data_cnt = 0;\r
+static int data[16 * 5 * 60] = {0};\r
+\r
+// int data = ((rxByte[i] & 0xff) << 16)\r
+//         + ((rxByte[i + 1] & 0xff) << 8)\r
+//         + (rxByte[i + 2] & 0xff);\r
+// if (data >= DATA_HANDLE / 2) {\r
+//     data -= DATA_HANDLE;\r
+// }\r
+// 其中:DATA_HANDLE = 2^24\r
+\r
+\r
 bool Bn02_write_reg(uint8_t data)\r
 {\r
        uint8_t cnt = pm_veto_get_id_cnt(PM_ID_BP);\r
@@ -127,10 +145,33 @@ void bn02_int_handle(void)
        memset(bn02_buf,0,sizeof(bn02_buf));\r
        Bn02_reads(bn02_buf,48);\r
 \r
-    if(bn02_get_ble_status())\r
-    {\r
-        bn02_replymsg(bn02_buf,sizeof(bn02_buf),1);\r
-    }\r
+       for(i = 0;i<48;i+=3)\r
+       {\r
+\r
+               data[data_cnt] = ((bn02_buf[i] & 0xff) << 16)\r
+        + ((bn02_buf[i + 1] & 0xff) << 8)\r
+        + (bn02_buf[i + 2] & 0xff);\r
+\r
+               if (data[data_cnt] >= DATA_HANDLE / 2)\r
+                       data[data_cnt] -= DATA_HANDLE;\r
+\r
+               data_cnt++;\r
+\r
+               printf("0x%x 0x%x 0x%x 0x%x\n",i,bn02_buf[i],bn02_buf[i+1],bn02_buf[i+2],data[data_cnt]);\r
+       }\r
+    // if(bn02_get_ble_status())\r
+    // {\r
+    //     bn02_replymsg(bn02_buf,sizeof(bn02_buf),1);\r
+    // }\r
+\r
+       // if(fp && data_cnt <= 48 * 300)\r
+       // {\r
+       //      data_cnt += 48;\r
+       //      if(fwrite(bn02_buf,1,48,fp) != 48)\r
+       //              printf("bn02 fwrite failed\n");\r
+       //      else\r
+       //              printf("bn02 fwrite succed data_cnt:%d\n",data_cnt);\r
+       // }\r
 \r
     // for(i = 0;i<48;i++)\r
        // {\r
@@ -143,6 +184,9 @@ void bn02_start(void)
        Bn02_Power_Ctrl(1);\r
        bn02_int_init();\r
        Bn02_write_reg(BN02_START_CMD);\r
+\r
+       data_cnt = 0;\r
+       // fp = fopen(BN02_FILE, "wb");\r
 }\r
 \r
 void bn02_stop(void)\r
@@ -150,4 +194,10 @@ void bn02_stop(void)
        bn02_int_deinit();\r
        Bn02_write_reg(BN02_STOP_CMD);\r
        Bn02_Power_Ctrl(0);\r
+\r
+       // if(fp)\r
+       // {\r
+       //      fclose(fp);\r
+       //      fp = NULL;\r
+       // }\r
 }\r
index b2561f2..ce74914 100644 (file)
@@ -1,47 +1,4 @@
-/**
- * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
- *
- * Description: Test adc source \n
- * Author: @CompanyNameTag \n
- * History: \n
- * 2022-08-16, Create file. \n
- */
-
-#include "adc.h"
-#define TEST_PARAM_ARGC_1 1
-#define TEST_PARAM_ARGC_2 2
-#define TEST_PARAM_ARGC_3 3
-#define TEST_PARAM_ARGC_4 4
-#define TEST_PARAM_ARGC_5 5
-#define TEST_PARAM_ARGC_6 6
-#define TEST_PARAM_ARGC_7 7
-#define TEST_PARAM_4_BYTES 4
-#define TEST_PARAM_8_BYTES 8
-typedef enum {
-    SUITE_OK = 0,
-    SUITE_UNKNOWN_FUNCTION = -1,
-    SUITE_ERROR_TIMED_OUT = -2,
-    SUITE_ERROR_BAD_PARAMS = -3,
-    SUITE_ERROR_PIN_ALLOCATION = -4,
-    SUITE_ERROR_PIN_DEALLOCATION = -5,
-    SUITE_ERROR_UNEXPECTED_INTERRUPT = -6,
-    SUITE_ALLOC_FAILED = -7,
-    SUITE_CONFIG_FAILED = -8,
-    SUITE_TEST_FAILED = -254,
-} magservice_error_e;
-
-#if defined(CONFIG_ADC_SUPPORT_AFE)
-
-#error CONFIG_ADC_SUPPORT_AFE
-
-#include "hal_adc_v152.h"
-#include "hal_adc_v152_regs_op.h"
-#else
-#include "hal_adc_v151.h"
-#include "hal_adc_v151_regs_op.h"
-#endif
 
-#include "adc_porting.h"
 #include "pinctrl.h"
 #include "debug_print.h"
 #include "soc_osal.h"
index 88975a2..360e652 100644 (file)
@@ -3,4 +3,5 @@ add_subdirectory_if_exist(hx3695)
 add_subdirectory_if_exist(ppgBleService)
 add_subdirectory_if_exist(vc9202)
 add_subdirectory_if_exist(vc921x)
-add_subdirectory_if_exist(gh3x2x)
\ No newline at end of file
+add_subdirectory_if_exist(gh3x2x)
+add_subdirectory_if_exist(pah8009)
\ No newline at end of file
index fce1cdf..f9485fc 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-06-07 11:18:26
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-01-13 14:09:50
+ * @LastEditTime: 2025-06-06 11:23:50
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.h
  * @Description: 
  * 
@@ -18,7 +18,7 @@ extern "C" {
 
 #include "stdint.h"
 
-typedef uint32_t PPG_CMD_TYPE_T ;
+// typedef uint32_t PPG_CMD_TYPE_T ;
 
 void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable);
 
index 2a84d34..385077b 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-13 15:08:38
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-05-13 16:48:04
+ * @LastEditTime: 2025-05-28 14:13:17
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
  * @Description: 
  * 
@@ -82,7 +82,7 @@ void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable)
     if (enable == 1)
     {
         // ppg_service_running_stat = true;
-        uapi_pm_control(PM_APP_WAKE_NEEDED);
+        // uapi_pm_control(PM_APP_WAKE_NEEDED);
         tyhx_poweron();
         // GH3X2X_AFE_StartFunction(mode);
         GH3X2X_AFE_Init();
@@ -90,7 +90,7 @@ void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable)
 
     } else {
         
-        uapi_pm_control(PM_APP_WAKE_NONEED);
+        // uapi_pm_control(PM_APP_WAKE_NONEED);
         GH3X2X_AFE_StopSampling();
         tyhx_poweroff();
     } 
index c55141c..c11b318 100644 (file)
@@ -12,7 +12,7 @@ set(SOURCES ${SOURCES}
     ${CMAKE_CURRENT_SOURCE_DIR}/hx3695_hrs_agc.c
     ${CMAKE_CURRENT_SOURCE_DIR}/hx3695_hrv_agc.c
     ${CMAKE_CURRENT_SOURCE_DIR}/hx3695_spo2_agc.c
-    ${CMAKE_CURRENT_SOURCE_DIR}/hx3695_hal.c
+    #${CMAKE_CURRENT_SOURCE_DIR}/hx3695_hal.c
     ${CMAKE_CURRENT_SOURCE_DIR}/hx3695_hrs_custom.c
 )
 set(PUBLIC_HEADER
index a847f5a..0045e14 100644 (file)
 // #include "lv_dev.h"\r
 // #include "app_task.h"\r
 \r
+#ifdef SUPPORT_CYWEE_SERVICE\r
 #include "cywee_hal.h"\r
 #include "cywee_service.h"\r
 #include "custom_utils.h"\r
 #include "custom_runtime.h"\r
+#endif\r
+\r
+#include "ppg_hal.h"\r
+\r
 \r
 FT_CUSTOM_RESULTS_t hrsresult ={0};\r
 \r
@@ -43,7 +48,9 @@ int16_t gsen_fifo_x[64]={0};
 int16_t gsen_fifo_y[64]={0};\r
 int16_t gsen_fifo_z[64]={0};\r
 \r
+#ifdef SUPPORT_CYWEE_SERVICE\r
 gsenson_t gsensordata[32];\r
+#endif\r
 \r
 static uint8_t msg_count = 0;\r
 \r
@@ -125,9 +132,10 @@ uint8_t alg_ram[11 * 1024] __attribute__((aligned(4)));
 //uint8_t alg_ram[10] = {0};\r
 ppg_sensor_data_t ppg_s_data;\r
 \r
-static int cywee_hrs_data = 0;\r
+static uint8_t hrs_result = 0;\r
 static int history_wear_status = -1;\r
-static int cywee_wear_status = 0;\r
+static uint8_t wear_status = 0;\r
+static uint8_t spo2_result = 0;\r
 \r
 static uint8_t hx3695_chip_id = 0;\r
 \r
@@ -364,7 +372,7 @@ void hx3695_gpioint_cfg(bool en)
 }\r
 #endif\r
 \r
-bool hx3695_chip_check(void)\r
+uint8_t hx3695_chip_check(void)\r
 {\r
     uint8_t i = 0;\r
     uint8_t chip_id = 0;\r
@@ -380,13 +388,13 @@ bool hx3695_chip_check(void)
             //printf("hx3695_chip_check ok  chip_id: 0x%x \r\n",chip_id);\r
                        //Efuse_Mode_Check();\r
             hx3695_chip_id = chip_id;\r
-            return true;\r
+            // return hx3695_chip_id;\r
         }\r
     }\r
 \r
-    printf(" hx3695_chip_check fail!  chip_id: 0x%x \r\n", chip_id);\r
+    printf(" hx3695 chip_id: 0x%x \r\n", chip_id);\r
 \r
-    return false;\r
+    return chip_id;\r
 }\r
 \r
 void hx3695_get_id(uint8_t *ppg_id)\r
@@ -2237,7 +2245,7 @@ void hx3695_check_touch_init(void) //
 // 初始化调用入口函数\r
 bool hx3695_init(WORK_MODE_T mode)\r
 {\r
-  hx3695_msg_callback_t func;\r
+  // hx3695_msg_callback_t func;\r
 \r
 \r
        //TYHX_LOG("this chip hx3695_init  mode: %d !! \r\n", mode);\r
@@ -2328,11 +2336,11 @@ bool hx3695_init(WORK_MODE_T mode)
         //TYHX_LOG(" hx3695_init mode : LEAK_LIGHT_MODE \n");\r
         hx3695_factroy_test(LEAK_LIGHT_TEST);\r
 \r
-        func =  hx3695_get_send_msg_callback_func();\r
-        if(func != NULL)\r
-        {\r
-          func(HX3695_MSG_TYPE_LEAKLIGHT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-        }\r
+        // func =  hx3695_get_send_msg_callback_func();\r
+        // if(func != NULL)\r
+        // {\r
+        //   func(HX3695_MSG_TYPE_LEAKLIGHT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+        // }\r
         break;\r
 \r
     case FT_GRAY_CARD_MODE:\r
@@ -2344,11 +2352,11 @@ bool hx3695_init(WORK_MODE_T mode)
         //TYHX_LOG(" hx3695_init mode : GRAY_CARD_MODE \n");\r
         hx3695_factroy_test(GRAY_CARD_TEST);\r
 \r
-        func =  hx3695_get_send_msg_callback_func();\r
-        if(func != NULL)\r
-        {\r
-          func(HX3695_MSG_TYPE_GRAYCARD_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-        }\r
+        // func =  hx3695_get_send_msg_callback_func();\r
+        // if(func != NULL)\r
+        // {\r
+        //   func(HX3695_MSG_TYPE_GRAYCARD_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+        // }\r
         break;\r
 \r
     case FT_INT_TEST_MODE:\r
@@ -2717,7 +2725,18 @@ static void get_avg_hrs(int32_t hrs)
 \r
 uint8_t hx3695_get_hrs(void)\r
 {\r
-    return cywee_hrs_data;\r
+    return hrs_result;\r
+}\r
+\r
+uint8_t hx3695_get_spo2(void)\r
+{\r
+    return spo2_result;\r
+}\r
+\r
+\r
+uint8_t hx3695_get_wear_status(void)\r
+{\r
+    return wear_status;\r
 }\r
 \r
 void hx3695_set_hrs_ble_swtich(uint8_t cmd)\r
@@ -2734,33 +2753,35 @@ uint8_t hx3695_get_hrs_ble_swtich(void)
 \r
 void hx3695_wearstatus_update(void)\r
 {\r
-    if(history_wear_status != cywee_wear_status)\r
+    if(history_wear_status != wear_status)\r
     {\r
-        history_wear_status = cywee_wear_status;\r
-        do_cywee_service_check_msg(CYWEE_SERVICE_CMD_WEAR_STATUS_CHANGE,&cywee_wear_status);\r
+        history_wear_status = wear_status;\r
+#ifdef SUPPORT_CYWEE_SERVICE\r
+        do_cywee_service_check_msg(CYWEE_SERVICE_CMD_WEAR_STATUS_CHANGE,&wear_status);\r
+#endif\r
     }\r
 }\r
   //脱腕上报未佩戴信息\r
 void hx3695_unwearstatus_update(void)\r
 {\r
-  hx3695_msg_callback_t func =  hx3695_get_send_msg_callback_func();\r
-  if(func != NULL && !uapi_dev_runtime_get_train_status())\r
-  {\r
-    hrsresult.lastesthrs = 0;\r
-    hrsresult.wearstatus = 0;\r
-    //为了主界面脱腕灵敏;需要增加未佩戴\r
-    func(HX3695_MSG_TYPE_HRS_UPDATE, &hrsresult, sizeof(FT_CUSTOM_RESULTS_t));\r
-    func(HX3695_MSG_TYPE_WEARSTAT_UPDATE, &hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-    func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-    func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-  }\r
+  // hx3695_msg_callback_t func =  hx3695_get_send_msg_callback_func();\r
+  // if(func != NULL && !uapi_dev_runtime_get_train_status())\r
+  // {\r
+  //   hrsresult.lastesthrs = 0;\r
+  //   hrsresult.wearstatus = 0;\r
+  //   //为了主界面脱腕灵敏;需要增加未佩戴\r
+  //   func(HX3695_MSG_TYPE_HRS_UPDATE, &hrsresult, sizeof(FT_CUSTOM_RESULTS_t));\r
+  //   func(HX3695_MSG_TYPE_WEARSTAT_UPDATE, &hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+  //   func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+  //   func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+  // }\r
 \r
   if(uapi_dev_runtime_get_train_status())\r
   {\r
-      cywee_wear_status = 0;\r
+      wear_status = 0;\r
       hx3695_wearstatus_update();\r
-      cywee_hrs_data = 0;\r
-      // do_cywee_service_check_msg(CYWEE_SERVICE_CMD_HRS_CHANGE,&cywee_data);\r
+      hrs_result = 0;\r
+\r
   }\r
 }                              \r
 \r
@@ -2847,9 +2868,10 @@ void hx3695_hrs_ppg_Int_handle(void)
     // {\r
     //     return;\r
     // }\r
+  #ifdef SUPPORT_CYWEE_SERVICE\r
     memset(gsensordata,0.0f,sizeof(gsenson_t) * *count);\r
 \r
-    gsensor_get_n_data(*count,gsensordata);  \r
+    cywee_get_gsensor_data(*count,gsensordata);  \r
 \r
     for(ii=0; ii<*count; ii++)\r
     {\r
@@ -2881,7 +2903,7 @@ void hx3695_hrs_ppg_Int_handle(void)
           gsen_fifo_z_send[ii] = gsensordata[ii].z * 4096 / 10;\r
       }\r
 \r
-    // gsensor_get_n_data(8,gsensordata);  \r
+    // cywee_get_gsensor_data(8,gsensordata);  \r
     // for(ii=0; ii<*count; ii++)\r
     // {\r
     //   if(gsensordata[ii].x == 0.0f && gsensordata[ii].y == 0.0f && gsensordata[ii].z == 0.0f)\r
@@ -2918,6 +2940,7 @@ void hx3695_hrs_ppg_Int_handle(void)
       //PRINT("hxdata:%d/%d %d %d %.3f %.3f %.3f %d\r\n" ,1+ii,*count,PPG_buf[ii],ir_buf[0],gsensordata[ii].x,gsensordata[ii].y,gsensordata[ii].z,ppg_s_data.green_cur);\r
 \r
     }\r
+#endif\r
     hrs_wear_status = hx3695_hrs_get_wear_status();\r
     //PRINT("hrs_wear_status:    %d !!\r\n", hrs_wear_status);\r
 \r
@@ -2962,45 +2985,39 @@ void hx3695_hrs_ppg_Int_handle(void)
 \r
     if(hrsresult.wearstatus == MSG_HRS_WEAR)\r
     {\r
-        if(hrsresult.hr_living == MSG_LIVING_TRUE)\r
-        {\r
-            cywee_wear_status = 1;\r
-            if(hrsresult.lastesthrs > 30 && hrsresult.lastesthrs < 220)\r
-                           get_avg_hrs(hrsresult.lastesthrs);\r
-        }\r
-        else\r
-        {\r
-            cywee_wear_status = 0;\r
-        }\r
+        wear_status = 1;\r
+        if(hrsresult.lastesthrs > 30 && hrsresult.lastesthrs < 220)\r
+          get_avg_hrs(hrsresult.lastesthrs);\r
     }\r
-    else\r
+    else if(hrsresult.wearstatus == MSG_HRS_NO_WEAR || hrsresult.hr_living == MSG_LIVING_FAIL)\r
     {\r
         hrsresult.wearstatus = MSG_HRS_NO_WEAR;\r
         hrsresult.lastesthrs = 0;\r
-        cywee_wear_status = 0;\r
+        wear_status = 0;\r
     }\r
 \r
     \r
-    hx3695_msg_callback_t func =  hx3695_get_send_msg_callback_func();\r
-    if(func != NULL)\r
-    {\r
-      if(his_wear == hrsresult.wearstatus)\r
-      {\r
-          wear_cnt++;\r
-          if(wear_cnt >= 2 && !his_wear) //未佩戴超过2次 上报未佩戴信息\r
-          {\r
-              func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-              wear_cnt = 0;\r
-          }\r
-      }\r
-      else\r
-      {\r
-          his_wear = hrsresult.wearstatus;\r
-          wear_cnt = 0;\r
-      }\r
-    }\r
+    // hx3695_msg_callback_t func =  hx3695_get_send_msg_callback_func();\r
+    \r
+    // if(func != NULL)\r
+    // {\r
+    //   if(his_wear == hrsresult.wearstatus)\r
+    //   {\r
+    //       wear_cnt++;\r
+    //       if(wear_cnt >= 2 && !his_wear) //未佩戴超过2次 上报未佩戴信息\r
+    //       {\r
+    //           func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+    //           wear_cnt = 0;\r
+    //       }\r
+    //   }\r
+    //   else\r
+    //   {\r
+    //       his_wear = hrsresult.wearstatus;\r
+    //       wear_cnt = 0;\r
+    //   }\r
+    // }\r
     //PRINT("hrsresult.wearstatus : %d , his_wear : %d , wear_cnt : %d \n",hrsresult.wearstatus,his_wear,wear_cnt);\r
-    // PRINT("hrsresult.wearstatus : %d , cywee_wear_status : %d , hr_living : %d \n",hrsresult.wearstatus,cywee_wear_status,hrsresult.hr_living);\r
+    // PRINT("hrsresult.wearstatus : %d , wear_status : %d , hr_living : %d \n",hrsresult.wearstatus,wear_status,hrsresult.hr_living);\r
     // if(hrs_wear_status == MSG_HRS_WEAR && hrsresult.hr_living == MSG_LIVING_TRUE)\r
     // {\r
     //     if(hrsresult.lastesthrs > 30 && hrsresult.lastesthrs < 220)\r
@@ -3014,24 +3031,27 @@ void hx3695_hrs_ppg_Int_handle(void)
     //     hrsresult.lastesthrs = 0;\r
     // }\r
 \r
+    // PRINT("hrs : %d , wear_status : %d \n",hrsresult.lastesthrs,hrsresult.wearstatus);\r
+    hrs_result = hrsresult.lastesthrs;\r
+\r
     msg_count++;\r
     if(msg_count >= 3)\r
     {\r
           msg_count = 0;\r
-          if(func != NULL)\r
-          {\r
-            //PRINT("hrsresult.lastesthrs : %d \n",hrsresult.lastesthrs);\r
-            func(HX3695_MSG_TYPE_HRS_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-            if(uapi_get_cywee_static_state())\r
-            {\r
-                func(HX3695_MSG_TYPE_STATIC_HRS_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-            }\r
-          }\r
+          // if(func != NULL)\r
+          // {\r
+          //   //PRINT("hrsresult.lastesthrs : %d \n",hrsresult.lastesthrs);\r
+          //   func(HX3695_MSG_TYPE_HRS_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+          //   if(uapi_get_cywee_static_state())\r
+          //   {\r
+          //       func(HX3695_MSG_TYPE_STATIC_HRS_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+          //   }\r
+          // }\r
 \r
           if(uapi_dev_runtime_get_train_status())\r
           {\r
               hx3695_wearstatus_update();\r
-              cywee_hrs_data = hrsresult.lastesthrs;\r
+              // hrs_result = hrsresult.lastesthrs;\r
               // do_cywee_service_check_msg(CYWEE_SERVICE_CMD_HRS_CHANGE,&cywee_data);\r
           }\r
     }\r
@@ -3155,7 +3175,7 @@ void hx3695_hrs_ppg_Int_handle(void)
             encoded_hrm[15] = ppg_s_data.green_cur;//绿灯电流\r
             encoded_hrm[16] = ppg_s_data.ir_cur;//红外电流\r
 \r
-#ifdef SUPPORT_BLE_SERVICE\r
+#ifdef SUPPORT_PPG_BLE_SERVICE\r
             if(cm_custom_ble_service_on_flag())\r
               ble_ppgtest_server_send_input_report(encoded_hrm,PPG_DATA_LEN_MAX);\r
 #endif\r
@@ -3414,7 +3434,7 @@ void hx3695_spo2_ppg_Int_handle(void)
     {\r
         return;\r
     }\r
-    //gsensor_get_n_data(8,gsensordata);\r
+    //cywee_get_gsensor_data(8,gsensordata);\r
     for(ii=0; ii<*count; ii++)\r
     {\r
 \r
@@ -3502,7 +3522,7 @@ void hx3695_spo2_ppg_Int_handle(void)
     DEBUG_PRINTF("block_cnt: %d, data_cnt:%d, hr_result:%d,ir_quality:%d,motion:%d,poor_signal:%d,reliable_score_result:%d,screen_up:%d,spo2_result:%d\r\n",spo2_alg_results.block_cnt,spo2_alg_results.data_cnt,spo2_alg_results.hr_result,spo2_alg_results.ir_quality,spo2_alg_results.motion,spo2_alg_results.poor_signal,spo2_alg_results.reliable_score_result,spo2_alg_results.screen_up,spo2_alg_results.spo2_result);\r
     \r
     hrsresult.lastestspo2 = spo2_alg_results.spo2_result;\r
-\r
+    spo2_result = hrsresult.lastestspo2;\r
 //     if(hrsresult.lastestspo2)\r
        {\r
                // store_latest_spo2(hrsresult.lastestspo2);\r
@@ -3511,13 +3531,13 @@ void hx3695_spo2_ppg_Int_handle(void)
 //             hr_sensor_notify_factory_test();\r
        }\r
            \r
-    hx3695_msg_callback_t func =  hx3695_get_send_msg_callback_func();\r
-    if(func != NULL)\r
-    {\r
-      hrsresult.wearstatus = spo2_wear_status;\r
-      func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-      func(HX3695_MSG_TYPE_SPO2_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
-    }\r
+    // hx3695_msg_callback_t func =  hx3695_get_send_msg_callback_func();\r
+    // if(func != NULL)\r
+    // {\r
+    //   hrsresult.wearstatus = spo2_wear_status;\r
+    //   func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+    //   func(HX3695_MSG_TYPE_SPO2_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
+    // }\r
 \r
 \r
 \r
@@ -3601,7 +3621,7 @@ if(hrs_ble_falg)
             \r
             encoded_hrm[15] = cal.R_LED;\r
             encoded_hrm[16] = cal.IR_LED1;\r
-#ifdef SUPPORT_BLE_SERVICE\r
+#ifdef SUPPORT_PPG_BLE_SERVICE\r
             if(cm_custom_ble_service_on_flag())\r
               ble_ppgtest_server_send_input_report(encoded_hrm,PPG_DATA_LEN_MAX);\r
 #endif \r
@@ -3794,7 +3814,7 @@ void hx3695_wear_ppg_Int_handle(void)
     hx3695_wear_msg_code_t hx3695_wear_status;\r
        \r
     hx3695_check_touch_read(&ppg_s_data);\r
-    cywee_wear_status = hx3695_check_touch_send_data(ir_buf,*count);\r
+    wear_status = hx3695_check_touch_send_data(ir_buf,*count);\r
     hx3695_wearstatus_update();\r
        extern uint8_t notouch_cnt;\r
        extern uint8_t touch_cnt;\r
@@ -3819,4 +3839,60 @@ void hx3695_lab_test_Int_handle(void)
 }\r
 #endif\r
 \r
+void hx3695_control(char *mode,uint8_t enable)\r
+{\r
+    WORK_MODE_T md = NULL_MODE;\r
+    if (strcmp(mode, "hrs") == 0) {\r
+        md = HRS_MODE;\r
+    } else if (strcmp(mode, "hrv") == 0) {\r
+        md = HRV_MODE;\r
+    } else if (strcmp(mode, "spo2") == 0) {\r
+        md = SPO2_MODE;\r
+    } else if (strcmp(mode, "leaklight") == 0) {\r
+        md = FT_LEAK_LIGHT_MODE;\r
+    } else if (strcmp(mode, "graycard") == 0) {\r
+        md = FT_GRAY_CARD_MODE;\r
+    } else if (strcmp(mode, "ledoff") == 0) {\r
+        md = FT_LED_OFF_MODE;\r
+    } else if (strcmp(mode, "wear") == 0) {\r
+        md = WEAR_MODE;\r
+    } else if (strcmp(mode, "single") == 0) {\r
+        md = FT_SINGLE_CHECK_MODE;\r
+    } \r
+\r
+\r
+    if (enable == 1 || md == FT_LED_OFF_MODE) {\r
+        hx3695_init(md);\r
+    } else {\r
+       if(md == HRS_MODE|| md == FT_LEAK_LIGHT_MODE || md == FT_GRAY_CARD_MODE || md == WEAR_MODE || md == FT_SINGLE_CHECK_MODE)\r
+        {\r
+#ifdef HRS_ALG_LIB   \r
+            hx3695_hrs_disable();\r
+            // PRINT("uapi_dev_runtime_get_sleep_monitoring_status : %d \n",uapi_dev_runtime_get_sleep_monitoring_status());\r
+            // PRINT("uapi_dev_runtime_get_hrs_passivity_flag : %d \n",uapi_dev_runtime_get_hrs_passivity_flag());\r
+            if(uapi_dev_runtime_get_sleep_monitoring_status() && uapi_dev_runtime_get_hrs_passivity_flag())//处于睡眠监测 且在心率周期检测期间 上报活体佩戴 \r
+            {\r
+                hx3695_wearstatus_update();   \r
+                uapi_dev_runtime_set_hrs_passivity(0);//清除被动检测runtime     \r
+            }\r
+#endif\r
+        }else  if(md == HRV_MODE)\r
+        {\r
+#ifdef HRV_ALG_LIB\r
+            hx3695_hrv_disable();\r
+#endif\r
+        }else  if(md == SPO2_MODE)\r
+        {\r
+#ifdef SPO2_ALG_LIB\r
+            hx3695_spo2_disable();\r
+#endif\r
+        }\r
+       else{\r
+#ifdef HRS_ALG_LIB   \r
+            hx3695_hrs_disable();\r
+#endif\r
+        }\r
+    }\r
+}\r
+\r
 #endif  //CHIP_HX3695
\ No newline at end of file
index 0e78bf5..32b00e0 100644 (file)
@@ -245,7 +245,7 @@ void hx3695_delay_ms(uint32_t ms);
 bool hx3695_write_reg(uint8_t addr, uint8_t data); \r
 uint8_t hx3695_read_reg(uint8_t addr); \r
 bool hx3695_brust_read_reg(uint8_t addr , uint8_t *buf, uint16_t length);\r
-bool hx3695_chip_check(void);\r
+uint8_t hx3695_chip_check(void);\r
 void hx3695_get_id(uint8_t *ppg_id);\r
 uint8_t hx3695_read_fifo_size(void);\r
 uint16_t hx3695_read_fifo_data(int32_t *s_buf, uint8_t size, uint8_t phase_num);\r
@@ -302,6 +302,9 @@ void hx3695_unwearstatus_update(void);
 void hx3695_set_hrs_ble_swtich(uint8_t cmd);\r
 uint8_t hx3695_get_hrs_ble_swtich(void);\r
 uint8_t hx3695_get_hrs(void);\r
-#include "hx3695_hal.h"\r
+uint8_t hx3695_get_spo2(void);\r
+uint8_t hx3695_get_wear_status(void);\r
+\r
+void hx3695_control(char *mode,uint8_t enable);\r
 \r
 #endif\r
index 09e9a46..dd10f20 100644 (file)
@@ -9,7 +9,9 @@
 #include "hx3695.h"\r
 #include "hx3695_check_touch.h"\r
 #include "hx3695_hrs_agc.h"\r
+#ifdef SUPPORT_CYWEE_SERVICE\r
 #include "cywee_hal.h"\r
+#endif\r
 \r
 hx3695_wear_msg_code_t hx3695_wear_status = MSG_NO_WEAR;\r
 hx3695_wear_msg_code_t hx3695_wear_status_pre = MSG_NO_WEAR;\r
index 4bad413..038259e 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-13 15:08:38
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2024-11-19 19:40:35
+ * @LastEditTime: 2025-05-15 17:02:49
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
  * @Description: 
  * 
@@ -65,7 +65,7 @@ void ppg_send_cmd_to_driver(char* mode, uint8_t enable)
    
     if (enable == 1 || md == FT_LED_OFF_MODE) {
         // ppg_service_running_stat = true;
-        uapi_pm_control(PM_APP_WAKE_NEEDED);
+        // uapi_pm_control(PM_APP_WAKE_NEEDED);
         tyhx_poweron();
         //custom_i2c_reset();
         hx3695_init(md);
@@ -100,7 +100,7 @@ void ppg_send_cmd_to_driver(char* mode, uint8_t enable)
             hx3695_hrs_disable();
 #endif
         }
-        uapi_pm_control(PM_APP_WAKE_NONEED);
+        // uapi_pm_control(PM_APP_WAKE_NONEED);
         tyhx_poweroff();
     } 
 }
\ No newline at end of file
index c78766d..2347c70 100644 (file)
@@ -35,9 +35,9 @@ void tyhx_delay_ms(uint32_t ms)
     LOS_Mdelay(ms);
 }
 
-
-
+#ifdef SUPPORT_PPG_SERVICE
 #include "ppg_service.h"
+#endif
 #include "cmsis_os2.h"
 #define BUTTON_APP_TIMER_INTERVAL 20
 osTimerId_t g_timer40_timer = NULL;
@@ -47,19 +47,25 @@ static uint8_t g_hx3695_timer_installed = 0;
 
 static void timer40_func(void)
 {
+#ifdef SUPPORT_PPG_SERVICE
     send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_PPG_40TIMER_CALLBACK);
+#endif
     // agc_timeout_handler(NULL);
 }
 
 static void timer320_func(void)
 {
+#ifdef SUPPORT_PPG_SERVICE
     send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_PPG_320TIMER_CALLBACK);
+#endif
     // heart_rate_meas_timeout_handler(NULL);
 }
 
 static void timer5000_func(void)
 {
+#ifdef SUPPORT_PPG_SERVICE
     send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_5000TIMER_CALLBACK);
+#endif
     // heart_rate_meas_timeout_handler(NULL);
 }
 bool tyhx_timer_init(void)
@@ -116,34 +122,5 @@ bool tyhx_timer_stop(uint32_t ms)
     return 1;
 }
 
-// S_AGPIO_L26 心率复位 PPG reset
-#define GPIO_PIN_PRG_RESET S_AGPIO_L26
-// S_AGPIO_R0 PRG_LED_POWER ON  心率等电源控制脚
-#define GPIO_PIN_PRG_LED_ON S_AGPIO_R0
-
-uint32_t tyhx_poweron(void)
-{
-    uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
-    uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_HIGH);
-   
-    uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
-    uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_HIGH);
-    tyhx_delay_ms(100);
-    return 0;
-}
-uint32_t tyhx_poweroff(void)
-{
-    uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
-    uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_LOW);
-   
-    uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
-    uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
-    uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_LOW);
-    tyhx_delay_ms(50);
-    return 0;
-}
 
 
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/CMakeLists.txt b/code/sdk/zhihui/drivers/ppg/pah8009/CMakeLists.txt
new file mode 100644 (file)
index 0000000..31c7b91
--- /dev/null
@@ -0,0 +1,52 @@
+#===============================================================================
+# @brief    cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "ppg_sensor_pah8009")
+
+set(SOURCES ${SOURCES}
+    ${CMAKE_CURRENT_SOURCE_DIR}/sensor/pah_800x.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/sensor/pah800x_bsp.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/sensor/pah800x_main.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/factory/pah800x_factory_test.c
+)
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/sensor
+    ${CMAKE_CURRENT_SOURCE_DIR}/factory
+    ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/pah_spo2/V703
+    ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/pah_stress/V6033
+    ${CMAKE_CURRENT_SOURCE_DIR}/algorithm/pah_hr/V303009
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+    PPG_PAH8009
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+find_library(LIB_PATH_SPO2 algorithm/pah_spo2/V703/libv703_0_1.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_HR algorithm/pah_hr/V303009/libv307009_4.a ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive ${LIB_PATH_HR} ${LIB_PATH_SPO2} PRIVATE -Wl,--whole-archive)
+
+build_component()
+
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/Interrupt_function.c b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/Interrupt_function.c
new file mode 100644 (file)
index 0000000..6c91bba
--- /dev/null
@@ -0,0 +1,12 @@
+#include "pxi_interp.h"\r
+\r
+\r
+void  PXI_MEMS_interp(int16_t *src_data, size_t src_data_count, int16_t *dst_data, size_t dst_data_count)\r
+{\r
+         pxi_interp_ex1(src_data,  src_data_count ,dst_data,dst_data_count ,3);\r
+               pxi_interp_ex1(&src_data[1],  src_data_count ,&dst_data[1],dst_data_count ,3);\r
+               pxi_interp_ex1(&src_data[2],  src_data_count ,&dst_data[2],dst_data_count ,3);\r
+}\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/pxi_interp.c b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/pxi_interp.c
new file mode 100644 (file)
index 0000000..36ed8cd
--- /dev/null
@@ -0,0 +1,42 @@
+#include "pxi_interp.h"\r
+\r
+\r
+/*****\r
+* @brief Example of Platform. In this function we initialize powerkey and register callback.\r
+* @param None.\r
+* @return None.\r
+*\r
+*****/\r
+\r
+void pxi_interp_ex1(int16_t *src_data, size_t src_data_count, int16_t *dst_data, size_t dst_data_count, size_t offset)\r
+{\r
+    float pre_time_acc = 0.0f;\r
+    float time_acc = 0.0f;\r
+    float d_time = (float)dst_data_count / src_data_count;\r
+    size_t idx_ptr = 0;\r
+\r
+    for (size_t i = 0; i < dst_data_count; ++i)\r
+    {\r
+        while (time_acc < (float)i)\r
+        {\r
+            pre_time_acc = time_acc;\r
+            time_acc = time_acc + d_time;\r
+            idx_ptr++;\r
+        }\r
+\r
+        if (idx_ptr == 0)\r
+        {\r
+            dst_data[i * offset] = src_data[idx_ptr * offset];\r
+        }\r
+        else if (idx_ptr == dst_data_count)\r
+        {\r
+            dst_data[i * offset] = src_data[(idx_ptr - 1) * offset];\r
+        }\r
+        else\r
+        {\r
+            float time_ratio = ((float)i - pre_time_acc) / (time_acc - pre_time_acc);\r
+            dst_data[i * offset] = (int16_t)((float)src_data[(idx_ptr - 1) * offset] * (1.0f - time_ratio) + (float)src_data[idx_ptr * offset] * time_ratio + 0.5f);\r
+        }\r
+    }\r
+}\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/pxi_interp.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/MEMS_INT/pxi_interp.h
new file mode 100644 (file)
index 0000000..15c4149
--- /dev/null
@@ -0,0 +1,7 @@
+//#pragma once\r
+\r
+#include <stdint.h>\r
+#include <stddef.h>\r
+\r
+void pxi_interp_ex1(int16_t *src_data, size_t src_data_count, int16_t *dst_data, size_t dst_data_count, size_t offset);\r
+void  PXI_MEMS_interp(int16_t *src_data, size_t src_data_count, int16_t *dst_data, size_t dst_data_count);\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/libv307009_4.a b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/libv307009_4.a
new file mode 100644 (file)
index 0000000..d0d7a95
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/libv307009_4.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pah8009_testpattern_HRD.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pah8009_testpattern_HRD.h
new file mode 100644 (file)
index 0000000..44b62ae
--- /dev/null
@@ -0,0 +1,23944 @@
+#ifndef _PAH8009_TESTPATTERN_\r
+#define _PAH8009_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 3\r
+#define NF_PPG_PER_CHANNEL 3\r
+static const int32_t PAH8009_rawdata_HRD[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{0, 123629, 5910},\r
+{0, 118569, 5918},\r
+{0, 113318, 5916},\r
+{0, 106371, 5944},\r
+{0, 105522, 5928},\r
+{0, 96770, 5938},\r
+{0, 91486, 5928},\r
+{0, 86122, 5918},\r
+{0, 81476, 5906},\r
+{0, 80788, 5908},\r
+{0, 80266, 5904},\r
+{0, 79770, 5909},\r
+{0, 79298, 5908},\r
+{0, 78950, 5892},\r
+{0, 78704, 5900},\r
+{0, 78700, 5897},\r
+{0, 78620, 5897},\r
+{0, 78202, 5900},\r
+{0, 77595, 5903},\r
+{0, 77266, 5899},\r
+{0, 77183, 5888},\r
+{0, 77194, 5893},\r
+{0, 77168, 5884},\r
+{0, 76801, 5883},\r
+{0, 76396, 5875},\r
+{0, 75904, 5877},\r
+{0, 75403, 5886},\r
+{0, 74506, 5860},\r
+{0, 72984, 5866},\r
+{0, 71718, 5857},\r
+{0, 70789, 5854},\r
+{0, 70106, 5851},\r
+{0, 69559, 5845},\r
+{0, 69000, 5840},\r
+{0, 68416, 5827},\r
+{0, 67926, 5840},\r
+{0, 67615, 5840},\r
+{0, 67369, 5826},\r
+{0, 66701, 5816},\r
+{0, 65556, 5820},\r
+{0, 64648, 5827},\r
+{0, 63936, 5806},\r
+{0, 63453, 5806},\r
+{0, 63170, 5815},\r
+{0, 62967, 5818},\r
+{0, 62761, 5801},\r
+{0, 62594, 5806},\r
+{0, 62541, 5807},\r
+{0, 62525, 5799},\r
+{0, 62088, 5792},\r
+{0, 61096, 5784},\r
+{0, 60432, 5782},\r
+{0, 60066, 5777},\r
+{0, 59871, 5789},\r
+{0, 59953, 5791},\r
+{0, 60000, 5791},\r
+{0, 60065, 5788},\r
+{0, 60235, 5786},\r
+{0, 60431, 5797},\r
+{0, 60713, 5797},\r
+{0, 60770, 5797},\r
+{0, 60015, 5801},\r
+{0, 59364, 5796},\r
+{0, 59129, 5776},\r
+{0, 59016, 5790},\r
+{0, 59049, 5791},\r
+{0, 59116, 5783},\r
+{0, 59132, 5786},\r
+{0, 59220, 5786},\r
+{0, 59394, 5795},\r
+{0, 59670, 5788},\r
+{0, 59727, 5788},\r
+{0, 59063, 5796},\r
+{0, 58552, 5788},\r
+{0, 58411, 5771},\r
+{0, 58361, 5771},\r
+{0, 58441, 5776},\r
+{0, 58643, 5771},\r
+{0, 58852, 5785},\r
+{0, 59047, 5777},\r
+{0, 59266, 5774},\r
+{0, 59575, 5779},\r
+{0, 59891, 5786},\r
+{0, 59477, 5801},\r
+{0, 58938, 5776},\r
+{0, 58697, 5772},\r
+{0, 58468, 5779},\r
+{0, 58370, 5771},\r
+{0, 58427, 5764},\r
+{0, 58382, 5775},\r
+{0, 58432, 5772},\r
+{0, 58479, 5781},\r
+{0, 58621, 5769},\r
+{0, 58790, 5773},\r
+{0, 58663, 5771},\r
+{0, 58086, 5758},\r
+{0, 57739, 5760},\r
+{0, 57461, 5759},\r
+{0, 57334, 5755},\r
+{0, 57343, 5751},\r
+{0, 57375, 5758},\r
+{0, 57431, 5746},\r
+{0, 57478, 5755},\r
+{0, 57565, 5755},\r
+{0, 57716, 5756},\r
+{0, 57982, 5749},\r
+{0, 57981, 5750},\r
+{0, 57916, 5757},\r
+{0, 57709, 5734},\r
+{0, 57546, 5743},\r
+{0, 57514, 5749},\r
+{0, 57607, 5742},\r
+{0, 57762, 5745},\r
+{0, 57895, 5749},\r
+{0, 58073, 5756},\r
+{0, 58254, 5751},\r
+{0, 58467, 5754},\r
+{0, 58649, 5742},\r
+{0, 58465, 5755},\r
+{0, 58106, 5747},\r
+{0, 57839, 5753},\r
+{0, 57640, 5741},\r
+{0, 57646, 5744},\r
+{0, 57765, 5744},\r
+{0, 57903, 5733},\r
+{0, 58067, 5750},\r
+{0, 58267, 5750},\r
+{0, 58492, 5758},\r
+{0, 58740, 5746},\r
+{0, 58888, 5746},\r
+{0, 58582, 5749},\r
+{0, 58189, 5741},\r
+{0, 58011, 5749},\r
+{0, 58024, 5743},\r
+{0, 58121, 5752},\r
+{0, 58343, 5745},\r
+{0, 58442, 5751},\r
+{0, 58542, 5750},\r
+{0, 58672, 5766},\r
+{0, 58794, 5753},\r
+{0, 58959, 5753},\r
+{0, 58984, 5760},\r
+{0, 58907, 5758},\r
+{0, 58684, 5751},\r
+{0, 58478, 5740},\r
+{0, 58365, 5746},\r
+{0, 58427, 5745},\r
+{0, 58506, 5751},\r
+{0, 58578, 5744},\r
+{0, 58631, 5751},\r
+{0, 58713, 5762},\r
+{0, 58823, 5748},\r
+{0, 58954, 5749},\r
+{0, 59096, 5754},\r
+{0, 58921, 5745},\r
+{0, 58644, 5748},\r
+{0, 58535, 5737},\r
+{0, 58464, 5744},\r
+{0, 58465, 5742},\r
+{0, 58579, 5748},\r
+{0, 58640, 5750},\r
+{0, 58767, 5753},\r
+{0, 58864, 5743},\r
+{0, 59022, 5758},\r
+{0, 59158, 5755},\r
+{0, 59290, 5754},\r
+{0, 59226, 5755},\r
+{0, 58941, 5751},\r
+{0, 58717, 5758},\r
+{0, 58687, 5748},\r
+{0, 58599, 5748},\r
+{0, 58670, 5744},\r
+{0, 58694, 5744},\r
+{0, 58653, 5730},\r
+{0, 58575, 5736},\r
+{0, 58443, 5738},\r
+{0, 58226, 5737},\r
+{0, 57957, 5731},\r
+{0, 57664, 5744},\r
+{0, 57410, 5727},\r
+{0, 57131, 5731},\r
+{0, 57002, 5729},\r
+{0, 56949, 5726},\r
+{0, 56996, 5734},\r
+{0, 57041, 5736},\r
+{0, 57073, 5740},\r
+{0, 57122, 5733},\r
+{0, 57229, 5737},\r
+{0, 57328, 5738},\r
+{0, 57443, 5738},\r
+{0, 57591, 5734},\r
+{0, 57670, 5737},\r
+{0, 57489, 5742},\r
+{0, 57335, 5727},\r
+{0, 57307, 5729},\r
+{0, 57370, 5730},\r
+{0, 57454, 5725},\r
+{0, 57553, 5731},\r
+{0, 57636, 5726},\r
+{0, 57694, 5731},\r
+{0, 57782, 5723},\r
+{0, 57860, 5731},\r
+{0, 57953, 5737},\r
+{0, 57978, 5735},\r
+{0, 57758, 5737},\r
+{0, 57593, 5730},\r
+{0, 57484, 5734},\r
+{0, 57454, 5735},\r
+{0, 57447, 5717},\r
+{0, 57429, 5728},\r
+{0, 57402, 5740},\r
+{0, 57444, 5734},\r
+{0, 57493, 5727},\r
+{0, 57583, 5723},\r
+{0, 57683, 5725},\r
+{0, 57812, 5729},\r
+{0, 57658, 5716},\r
+{0, 57615, 5722},\r
+{0, 57641, 5721},\r
+{0, 57787, 5715},\r
+{0, 57986, 5733},\r
+{0, 58116, 5725},\r
+{0, 58211, 5727},\r
+{0, 58335, 5724},\r
+{0, 58464, 5724},\r
+{0, 58575, 5719},\r
+{0, 58657, 5734},\r
+{0, 58753, 5740},\r
+{0, 58533, 5730},\r
+{0, 58259, 5721},\r
+{0, 58161, 5726},\r
+{0, 58156, 5737},\r
+{0, 58106, 5727},\r
+{0, 58076, 5737},\r
+{0, 58128, 5731},\r
+{0, 58129, 5735},\r
+{0, 58213, 5727},\r
+{0, 58282, 5733},\r
+{0, 58282, 5728},\r
+{0, 58252, 5728},\r
+{0, 57998, 5721},\r
+{0, 57697, 5706},\r
+{0, 57559, 5719},\r
+{0, 57528, 5713},\r
+{0, 57520, 5723},\r
+{0, 57651, 5727},\r
+{0, 57819, 5719},\r
+{0, 58009, 5717},\r
+{0, 58287, 5733},\r
+{0, 58597, 5741},\r
+{0, 58811, 5732},\r
+{0, 59046, 5744},\r
+{0, 59025, 5726},\r
+{0, 58912, 5734},\r
+{0, 58919, 5738},\r
+{0, 59012, 5732},\r
+{0, 59143, 5748},\r
+{0, 59188, 5745},\r
+{0, 59227, 5749},\r
+{0, 59316, 5743},\r
+{0, 59358, 5740},\r
+{0, 59496, 5750},\r
+{0, 59627, 5751},\r
+{0, 59740, 5746},\r
+{0, 59647, 5735},\r
+{0, 59492, 5738},\r
+{0, 59361, 5725},\r
+{0, 59307, 5727},\r
+{0, 59357, 5728},\r
+{0, 59335, 5731},\r
+{0, 59163, 5729},\r
+{0, 58947, 5736},\r
+{0, 58960, 5747},\r
+{0, 59110, 5739},\r
+{0, 59246, 5744},\r
+{0, 59243, 5742},\r
+{0, 58958, 5732},\r
+{0, 58742, 5735},\r
+{0, 58692, 5725},\r
+{0, 58708, 5746},\r
+{0, 58787, 5744},\r
+{0, 59036, 5750},\r
+{0, 59671, 5735},\r
+{0, 60295, 5756},\r
+{0, 60927, 5763},\r
+{0, 61483, 5775},\r
+{0, 62005, 5778},\r
+{0, 62364, 5775},\r
+{0, 62685, 5780},\r
+{0, 63073, 5793},\r
+{0, 63430, 5798},\r
+{0, 63809, 5806},\r
+{0, 64149, 5810},\r
+{0, 64475, 5804},\r
+{0, 64774, 5810},\r
+{0, 65019, 5809},\r
+{0, 65321, 5807},\r
+{0, 65612, 5812},\r
+{0, 65791, 5818},\r
+{0, 65710, 5815},\r
+{0, 65624, 5802},\r
+{0, 65575, 5809},\r
+{0, 65443, 5800},\r
+{0, 65313, 5812},\r
+{0, 65198, 5812},\r
+{0, 65152, 5796},\r
+{0, 65148, 5795},\r
+{0, 65237, 5799},\r
+{0, 65317, 5799},\r
+{0, 65423, 5803},\r
+{0, 65467, 5800},\r
+{0, 65256, 5792},\r
+{0, 65124, 5790},\r
+{0, 65061, 5803},\r
+{0, 65012, 5796},\r
+{0, 64980, 5796},\r
+{0, 64932, 5792},\r
+{0, 64922, 5795},\r
+{0, 64895, 5803},\r
+{0, 64900, 5798},\r
+{0, 64872, 5798},\r
+{0, 64872, 5793},\r
+{0, 64747, 5789},\r
+{0, 64413, 5798},\r
+{0, 64165, 5794},\r
+{0, 63986, 5790},\r
+{0, 63882, 5781},\r
+{0, 63760, 5789},\r
+{0, 63792, 5780},\r
+{0, 63732, 5794},\r
+{0, 63781, 5788},\r
+{0, 63736, 5803},\r
+{0, 63854, 5791},\r
+{0, 63865, 5789},\r
+{0, 63866, 5799},\r
+{0, 63594, 5778},\r
+{0, 63433, 5777},\r
+{0, 63378, 5791},\r
+{0, 63409, 5779},\r
+{0, 63463, 5764},\r
+{0, 63486, 5775},\r
+{0, 63487, 5787},\r
+{0, 63572, 5778},\r
+{0, 63735, 5783},\r
+{0, 63803, 5773},\r
+{0, 63922, 5785},\r
+{0, 64029, 5783},\r
+{0, 63849, 5789},\r
+{0, 63604, 5785},\r
+{0, 63504, 5782},\r
+{0, 63472, 5774},\r
+{0, 63538, 5777},\r
+{0, 63570, 5775},\r
+{0, 63577, 5784},\r
+{0, 63590, 5776},\r
+{0, 63669, 5778},\r
+{0, 63772, 5782},\r
+{0, 63856, 5779},\r
+{0, 63959, 5779},\r
+{0, 63837, 5784},\r
+{0, 63557, 5776},\r
+{0, 63414, 5778},\r
+{0, 63370, 5781},\r
+{0, 63343, 5787},\r
+{0, 63346, 5781},\r
+{0, 63259, 5773},\r
+{0, 63253, 5771},\r
+{0, 63201, 5782},\r
+{0, 63234, 5782},\r
+{0, 63266, 5773},\r
+{0, 63307, 5774},\r
+{0, 63246, 5774},\r
+{0, 62919, 5769},\r
+{0, 62727, 5774},\r
+{0, 62685, 5779},\r
+{0, 62739, 5766},\r
+{0, 62789, 5759},\r
+{0, 62847, 5762},\r
+{0, 63030, 5765},\r
+{0, 63262, 5770},\r
+{0, 63561, 5784},\r
+{0, 63943, 5792},\r
+{0, 64274, 5795},\r
+{0, 64520, 5789},\r
+{0, 64439, 5796},\r
+{0, 64276, 5802},\r
+{0, 64338, 5792},\r
+{0, 64500, 5801},\r
+{0, 64753, 5805},\r
+{0, 65005, 5806},\r
+{0, 65246, 5809},\r
+{0, 65430, 5798},\r
+{0, 65691, 5809},\r
+{0, 65870, 5815},\r
+{0, 66098, 5807},\r
+{0, 66239, 5814},\r
+{0, 65989, 5813},\r
+{0, 65656, 5812},\r
+{0, 65523, 5810},\r
+{0, 65470, 5802},\r
+{0, 65429, 5798},\r
+{0, 65380, 5802},\r
+{0, 65218, 5793},\r
+{0, 65087, 5787},\r
+{0, 64942, 5787},\r
+{0, 64877, 5793},\r
+{0, 64720, 5796},\r
+{0, 64662, 5780},\r
+{0, 64332, 5772},\r
+{0, 63902, 5763},\r
+{0, 63639, 5763},\r
+{0, 63495, 5766},\r
+{0, 63367, 5760},\r
+{0, 63324, 5764},\r
+{0, 63315, 5772},\r
+{0, 63263, 5764},\r
+{0, 63258, 5755},\r
+{0, 63344, 5763},\r
+{0, 63369, 5758},\r
+{0, 63416, 5762},\r
+{0, 63060, 5755},\r
+{0, 62872, 5763},\r
+{0, 62919, 5769},\r
+{0, 63045, 5764},\r
+{0, 63173, 5786},\r
+{0, 63278, 5775},\r
+{0, 63357, 5774},\r
+{0, 63445, 5773},\r
+{0, 63543, 5781},\r
+{0, 63648, 5780},\r
+{0, 63715, 5782},\r
+{0, 63488, 5777},\r
+{0, 62867, 5780},\r
+{0, 62518, 5783},\r
+{0, 62258, 5773},\r
+{0, 62083, 5771},\r
+{0, 61984, 5770},\r
+{0, 61896, 5759},\r
+{0, 61733, 5761},\r
+{0, 61567, 5759},\r
+{0, 61535, 5768},\r
+{0, 61595, 5758},\r
+{0, 61726, 5775},\r
+{0, 61675, 5762},\r
+{0, 61330, 5759},\r
+{0, 61190, 5756},\r
+{0, 61269, 5765},\r
+{0, 61508, 5774},\r
+{0, 61756, 5778},\r
+{0, 62028, 5785},\r
+{0, 62209, 5787},\r
+{0, 62461, 5787},\r
+{0, 62716, 5793},\r
+{0, 63008, 5787},\r
+{0, 63274, 5792},\r
+{0, 63253, 5789},\r
+{0, 62966, 5791},\r
+{0, 62966, 5788},\r
+{0, 62994, 5784},\r
+{0, 63066, 5796},\r
+{0, 63155, 5789},\r
+{0, 63205, 5792},\r
+{0, 63262, 5789},\r
+{0, 63272, 5793},\r
+{0, 63273, 5791},\r
+{0, 63206, 5779},\r
+{0, 63087, 5779},\r
+{0, 62588, 5777},\r
+{0, 62075, 5771},\r
+{0, 61794, 5769},\r
+{0, 61577, 5768},\r
+{0, 61466, 5766},\r
+{0, 61429, 5764},\r
+{0, 61455, 5758},\r
+{0, 61475, 5757},\r
+{0, 61626, 5755},\r
+{0, 61776, 5768},\r
+{0, 61934, 5752},\r
+{0, 61846, 5756},\r
+{0, 61389, 5753},\r
+{0, 61208, 5746},\r
+{0, 61084, 5748},\r
+{0, 61091, 5751},\r
+{0, 61154, 5746},\r
+{0, 61209, 5748},\r
+{0, 61262, 5759},\r
+{0, 61363, 5743},\r
+{0, 61588, 5752},\r
+{0, 61931, 5766},\r
+{0, 62269, 5764},\r
+{0, 62412, 5769},\r
+{0, 62312, 5770},\r
+{0, 62235, 5771},\r
+{0, 62334, 5778},\r
+{0, 62378, 5772},\r
+{0, 62394, 5772},\r
+{0, 62360, 5760},\r
+{0, 62291, 5763},\r
+{0, 62295, 5761},\r
+{0, 62378, 5751},\r
+{0, 62481, 5762},\r
+{0, 62624, 5774},\r
+{0, 62644, 5772},\r
+{0, 62389, 5770},\r
+{0, 62120, 5764},\r
+{0, 61878, 5753},\r
+{0, 61725, 5762},\r
+{0, 61746, 5757},\r
+{0, 61881, 5766},\r
+{0, 62153, 5760},\r
+{0, 62325, 5761},\r
+{0, 62548, 5761},\r
+{0, 62669, 5754},\r
+{0, 62879, 5764},\r
+{0, 62629, 5756},\r
+{0, 62332, 5769},\r
+{0, 62140, 5761},\r
+{0, 62120, 5757},\r
+{0, 62169, 5762},\r
+{0, 62272, 5766},\r
+{0, 62331, 5762},\r
+{0, 62382, 5769},\r
+{0, 62445, 5763},\r
+{0, 62407, 5762},\r
+{0, 62353, 5774},\r
+{0, 62361, 5773},\r
+{0, 62135, 5773},\r
+{0, 61827, 5766},\r
+{0, 61601, 5750},\r
+{0, 61589, 5761},\r
+{0, 61690, 5749},\r
+{0, 61801, 5744},\r
+{0, 61820, 5740},\r
+{0, 61842, 5747},\r
+{0, 61860, 5766},\r
+{0, 62029, 5760},\r
+{0, 62251, 5762},\r
+{0, 62550, 5769},\r
+{0, 62878, 5776},\r
+{0, 62925, 5768},\r
+{0, 62918, 5763},\r
+{0, 63128, 5777},\r
+{0, 63394, 5775},\r
+{0, 63669, 5780},\r
+{0, 63835, 5778},\r
+{0, 64013, 5789},\r
+{0, 64079, 5779},\r
+{0, 64186, 5784},\r
+{0, 64308, 5778},\r
+{0, 64334, 5784},\r
+{0, 64282, 5794},\r
+{0, 63926, 5776},\r
+{0, 63585, 5769},\r
+{0, 63334, 5760},\r
+{0, 63121, 5765},\r
+{0, 63129, 5768},\r
+{0, 63284, 5767},\r
+{0, 63503, 5765},\r
+{0, 63541, 5765},\r
+{0, 63550, 5769},\r
+{0, 63622, 5780},\r
+{0, 63724, 5771},\r
+{0, 63704, 5767},\r
+{0, 63429, 5774},\r
+{0, 63210, 5761},\r
+{0, 63150, 5774},\r
+{0, 63176, 5783},\r
+{0, 63244, 5765},\r
+{0, 63444, 5773},\r
+{0, 63690, 5795},\r
+{0, 63968, 5803},\r
+{0, 64241, 5807},\r
+{0, 64575, 5809},\r
+{0, 65009, 5814},\r
+{0, 65276, 5815},\r
+{0, 65257, 5803},\r
+{0, 65316, 5824},\r
+{0, 65368, 5818},\r
+{0, 65327, 5811},\r
+{0, 65260, 5814},\r
+{0, 65179, 5804},\r
+{0, 65040, 5801},\r
+{0, 64913, 5807},\r
+{0, 64802, 5797},\r
+{0, 64718, 5799},\r
+{0, 64611, 5797},\r
+{0, 64415, 5800},\r
+{0, 64046, 5793},\r
+{0, 63772, 5780},\r
+{0, 63499, 5775},\r
+{0, 63292, 5772},\r
+{0, 63055, 5758},\r
+{0, 62893, 5769},\r
+{0, 62851, 5762},\r
+{0, 62815, 5777},\r
+{0, 62848, 5775},\r
+{0, 62991, 5762},\r
+{0, 63131, 5772},\r
+{0, 62987, 5772},\r
+{0, 62700, 5771},\r
+{0, 62261, 5772},\r
+{0, 61915, 5753},\r
+{0, 61787, 5761},\r
+{0, 61831, 5763},\r
+{0, 61778, 5762},\r
+{0, 61723, 5754},\r
+{0, 61759, 5757},\r
+{0, 61860, 5750},\r
+{0, 61924, 5764},\r
+{0, 61758, 5756},\r
+{0, 61283, 5755},\r
+{0, 60873, 5753},\r
+{0, 60417, 5741},\r
+{0, 60167, 5751},\r
+{0, 59971, 5744},\r
+{0, 59851, 5749},\r
+{0, 59669, 5757},\r
+{0, 59506, 5756},\r
+{0, 59345, 5757},\r
+{0, 59243, 5752},\r
+{0, 59105, 5761},\r
+{0, 58659, 5769},\r
+{0, 57940, 5761},\r
+{0, 57566, 5749},\r
+{0, 57450, 5748},\r
+{0, 57445, 5745},\r
+{0, 57486, 5738},\r
+{0, 57651, 5744},\r
+{0, 57905, 5750},\r
+{0, 58216, 5751},\r
+{0, 58463, 5750},\r
+{0, 58707, 5755},\r
+{0, 58813, 5761},\r
+{0, 58531, 5752},\r
+{0, 58351, 5752},\r
+{0, 58368, 5753},\r
+{0, 58483, 5749},\r
+{0, 58537, 5752},\r
+{0, 58424, 5758},\r
+{0, 58200, 5751},\r
+{0, 58067, 5754},\r
+{0, 58120, 5753},\r
+{0, 58109, 5758},\r
+{0, 58206, 5758},\r
+{0, 58438, 5759},\r
+{0, 58333, 5757},\r
+{0, 58264, 5761},\r
+{0, 58408, 5762},\r
+{0, 58653, 5771},\r
+{0, 58882, 5773},\r
+{0, 59063, 5785},\r
+{0, 59244, 5778},\r
+{0, 59428, 5782},\r
+{0, 59686, 5780},\r
+{0, 59884, 5786},\r
+{0, 60120, 5780},\r
+{0, 59927, 5770},\r
+{0, 59720, 5783},\r
+{0, 59758, 5768},\r
+{0, 59921, 5776},\r
+{0, 60162, 5772},\r
+{0, 60400, 5777},\r
+{0, 60629, 5786},\r
+{0, 60963, 5788},\r
+{0, 61245, 5785},\r
+{0, 61478, 5798},\r
+{0, 61742, 5795},\r
+{0, 61906, 5801},\r
+{0, 61764, 5779},\r
+{0, 61563, 5771},\r
+{0, 61160, 5783},\r
+{0, 60853, 5774},\r
+{0, 60623, 5767},\r
+{0, 60401, 5764},\r
+{0, 60175, 5760},\r
+{0, 60017, 5747},\r
+{0, 59984, 5741},\r
+{0, 60044, 5749},\r
+{0, 60098, 5757},\r
+{0, 60058, 5750},\r
+{0, 59791, 5745},\r
+{0, 59593, 5738},\r
+{0, 59563, 5749},\r
+{0, 59562, 5745},\r
+{0, 59708, 5750},\r
+{0, 59850, 5761},\r
+{0, 60212, 5763},\r
+{0, 60788, 5772},\r
+{0, 61619, 5794},\r
+{0, 62580, 5807},\r
+{0, 63490, 5819},\r
+{0, 64080, 5810},\r
+{0, 64358, 5800},\r
+{0, 64702, 5810},\r
+{0, 65016, 5820},\r
+{0, 65346, 5815},\r
+{0, 65728, 5818},\r
+{0, 66106, 5825},\r
+{0, 66387, 5819},\r
+{0, 66487, 5803},\r
+{0, 66536, 5816},\r
+{0, 66665, 5812},\r
+{0, 66835, 5817},\r
+{0, 66918, 5815},\r
+{0, 66891, 5813},\r
+{0, 67104, 5823},\r
+{0, 67512, 5839},\r
+{0, 68016, 5847},\r
+{0, 68617, 5847},\r
+{0, 69134, 5837},\r
+{0, 69657, 5851},\r
+{0, 70277, 5850},\r
+{0, 70854, 5863},\r
+{0, 71531, 5868},\r
+{0, 72171, 5862},\r
+{0, 72584, 5858},\r
+{0, 72533, 5855},\r
+{0, 72529, 5860},\r
+{0, 72557, 5862},\r
+{0, 72559, 5848},\r
+{0, 72536, 5844},\r
+{0, 72540, 5857},\r
+{0, 72433, 5841},\r
+{0, 72360, 5839},\r
+{0, 72366, 5852},\r
+{0, 72429, 5853},\r
+{0, 72535, 5851},\r
+{0, 72559, 5844},\r
+{0, 72224, 5850},\r
+{0, 71803, 5831},\r
+{0, 71524, 5836},\r
+{0, 71237, 5830},\r
+{0, 70999, 5843},\r
+{0, 70703, 5831},\r
+{0, 70440, 5836},\r
+{0, 70200, 5825},\r
+{0, 70089, 5816},\r
+{0, 70102, 5825},\r
+{0, 70163, 5826},\r
+{0, 70264, 5824},\r
+{0, 69955, 5808},\r
+{0, 69458, 5817},\r
+{0, 69074, 5824},\r
+{0, 68792, 5815},\r
+{0, 68544, 5812},\r
+{0, 68363, 5816},\r
+{0, 68082, 5811},\r
+{0, 67793, 5806},\r
+{0, 67555, 5821},\r
+{0, 67313, 5802},\r
+{0, 67154, 5801},\r
+{0, 67135, 5806},\r
+{0, 66807, 5797},\r
+{0, 66342, 5796},\r
+{0, 65999, 5786},\r
+{0, 65750, 5789},\r
+{0, 65594, 5800},\r
+{0, 65564, 5798},\r
+{0, 65579, 5805},\r
+{0, 65708, 5793},\r
+{0, 65976, 5812},\r
+{0, 66309, 5818},\r
+{0, 66750, 5820},\r
+{0, 67196, 5828},\r
+{0, 67576, 5835},\r
+{0, 67401, 5824},\r
+{0, 67390, 5817},\r
+{0, 67687, 5828},\r
+{0, 68049, 5825},\r
+{0, 68289, 5837},\r
+{0, 68354, 5834},\r
+{0, 68266, 5829},\r
+{0, 68110, 5824},\r
+{0, 68086, 5824},\r
+{0, 68194, 5830},\r
+{0, 68355, 5820},\r
+{0, 68271, 5830},\r
+{0, 67668, 5818},\r
+{0, 67010, 5799},\r
+{0, 66590, 5790},\r
+{0, 66325, 5801},\r
+{0, 66197, 5803},\r
+{0, 66116, 5811},\r
+{0, 66067, 5796},\r
+{0, 66104, 5801},\r
+{0, 66128, 5794},\r
+{0, 66202, 5801},\r
+{0, 66259, 5798},\r
+{0, 66405, 5796},\r
+{0, 66178, 5803},\r
+{0, 65969, 5809},\r
+{0, 65970, 5826},\r
+{0, 66127, 5832},\r
+{0, 66350, 5823},\r
+{0, 66644, 5831},\r
+{0, 66948, 5833},\r
+{0, 67228, 5830},\r
+{0, 67423, 5831},\r
+{0, 67608, 5829},\r
+{0, 67628, 5835},\r
+{0, 67624, 5834},\r
+{0, 67072, 5819},\r
+{0, 66363, 5809},\r
+{0, 65909, 5814},\r
+{0, 65618, 5802},\r
+{0, 65434, 5811},\r
+{0, 65385, 5802},\r
+{0, 65371, 5799},\r
+{0, 65307, 5803},\r
+{0, 65389, 5807},\r
+{0, 65475, 5803},\r
+{0, 65600, 5797},\r
+{0, 65817, 5791},\r
+{0, 65903, 5795},\r
+{0, 65955, 5785},\r
+{0, 66018, 5803},\r
+{0, 66068, 5803},\r
+{0, 66256, 5823},\r
+{0, 66470, 5814},\r
+{0, 66754, 5827},\r
+{0, 66957, 5815},\r
+{0, 67166, 5819},\r
+{0, 67434, 5823},\r
+{0, 67766, 5814},\r
+{0, 67944, 5823},\r
+{0, 67453, 5815},\r
+{0, 66912, 5822},\r
+{0, 66562, 5816},\r
+{0, 66312, 5808},\r
+{0, 66113, 5809},\r
+{0, 66043, 5800},\r
+{0, 66037, 5791},\r
+{0, 66111, 5790},\r
+{0, 66138, 5798},\r
+{0, 66118, 5794},\r
+{0, 66166, 5803},\r
+{0, 65942, 5807},\r
+{0, 65162, 5806},\r
+{0, 64551, 5788},\r
+{0, 64171, 5790},\r
+{0, 64015, 5781},\r
+{0, 63944, 5776},\r
+{0, 63951, 5782},\r
+{0, 63982, 5786},\r
+{0, 64003, 5775},\r
+{0, 64111, 5764},\r
+{0, 64352, 5773},\r
+{0, 64586, 5778},\r
+{0, 64494, 5786},\r
+{0, 63841, 5793},\r
+{0, 63485, 5772},\r
+{0, 63356, 5772},\r
+{0, 63387, 5781},\r
+{0, 63461, 5781},\r
+{0, 63500, 5785},\r
+{0, 63508, 5800},\r
+{0, 63672, 5794},\r
+{0, 63958, 5790},\r
+{0, 64148, 5802},\r
+{0, 64287, 5803},\r
+{0, 64042, 5794},\r
+{0, 63661, 5795},\r
+{0, 63571, 5774},\r
+{0, 63626, 5783},\r
+{0, 63707, 5791},\r
+{0, 63814, 5801},\r
+{0, 63880, 5785},\r
+{0, 63927, 5803},\r
+{0, 64073, 5797},\r
+{0, 64378, 5796},\r
+{0, 64669, 5804},\r
+{0, 64946, 5804},\r
+{0, 64931, 5813},\r
+{0, 64756, 5802},\r
+{0, 64879, 5801},\r
+{0, 65114, 5806},\r
+{0, 65326, 5811},\r
+{0, 65482, 5805},\r
+{0, 65343, 5802},\r
+{0, 65069, 5793},\r
+{0, 64859, 5782},\r
+{0, 64643, 5790},\r
+{0, 64495, 5801},\r
+{0, 64215, 5786},\r
+{0, 63659, 5771},\r
+{0, 63267, 5771},\r
+{0, 63058, 5777},\r
+{0, 63026, 5772},\r
+{0, 63035, 5765},\r
+{0, 63062, 5765},\r
+{0, 62976, 5773},\r
+{0, 63006, 5776},\r
+{0, 63091, 5769},\r
+{0, 63301, 5774},\r
+{0, 63552, 5779},\r
+{0, 63545, 5769},\r
+{0, 63334, 5769},\r
+{0, 63208, 5782},\r
+{0, 63195, 5785},\r
+{0, 63141, 5778},\r
+{0, 63223, 5777},\r
+{0, 63365, 5770},\r
+{0, 63532, 5776},\r
+{0, 63595, 5770},\r
+{0, 63604, 5771},\r
+{0, 63612, 5767},\r
+{0, 63617, 5763},\r
+{0, 63330, 5759},\r
+{0, 63173, 5761},\r
+{0, 63254, 5759},\r
+{0, 63392, 5767},\r
+{0, 63557, 5776},\r
+{0, 63637, 5778},\r
+{0, 63674, 5785},\r
+{0, 63563, 5781},\r
+{0, 63390, 5773},\r
+{0, 63113, 5785},\r
+{0, 62949, 5781},\r
+{0, 62921, 5764},\r
+{0, 62731, 5772},\r
+{0, 62536, 5787},\r
+{0, 62566, 5779},\r
+{0, 62709, 5770},\r
+{0, 62973, 5761},\r
+{0, 62930, 5760},\r
+{0, 62722, 5768},\r
+{0, 62678, 5783},\r
+{0, 62750, 5773},\r
+{0, 62701, 5787},\r
+{0, 62641, 5766},\r
+{0, 62456, 5768},\r
+{0, 62061, 5769},\r
+{0, 61566, 5766},\r
+{0, 61094, 5759},\r
+{0, 60794, 5753},\r
+{0, 60716, 5763},\r
+{0, 60749, 5765},\r
+{0, 60691, 5766},\r
+{0, 60600, 5764},\r
+{0, 60608, 5762},\r
+{0, 60806, 5777},\r
+{0, 60900, 5761},\r
+{0, 60554, 5757},\r
+{0, 60184, 5767},\r
+{0, 60018, 5775},\r
+{0, 60038, 5756},\r
+{0, 60070, 5762},\r
+{0, 60201, 5765},\r
+{0, 60224, 5762},\r
+{0, 60226, 5762},\r
+{0, 60238, 5760},\r
+{0, 60294, 5759},\r
+{0, 60325, 5760},\r
+{0, 59975, 5763},\r
+{0, 59527, 5752},\r
+{0, 59243, 5747},\r
+{0, 59081, 5761},\r
+{0, 58982, 5754},\r
+{0, 59055, 5752},\r
+{0, 59020, 5769},\r
+{0, 58892, 5757},\r
+{0, 58811, 5770},\r
+{0, 58830, 5755},\r
+{0, 59012, 5760},\r
+{0, 58978, 5756},\r
+{0, 58707, 5739},\r
+{0, 58480, 5747},\r
+{0, 58500, 5750},\r
+{0, 58540, 5749},\r
+{0, 58683, 5751},\r
+{0, 58817, 5755},\r
+{0, 58919, 5747},\r
+{0, 59049, 5758},\r
+{0, 59185, 5754},\r
+{0, 59365, 5753},\r
+{0, 59505, 5756},\r
+{0, 59120, 5746},\r
+{0, 58775, 5738},\r
+{0, 58560, 5743},\r
+{0, 58458, 5742},\r
+{0, 58326, 5742},\r
+{0, 58099, 5744},\r
+{0, 57782, 5750},\r
+{0, 57663, 5747},\r
+{0, 57583, 5751},\r
+{0, 57501, 5759},\r
+{0, 57472, 5747},\r
+{0, 57352, 5762},\r
+{0, 57101, 5763},\r
+{0, 57000, 5754},\r
+{0, 57037, 5744},\r
+{0, 57180, 5745},\r
+{0, 57364, 5750},\r
+{0, 57533, 5755},\r
+{0, 57798, 5751},\r
+{0, 58047, 5752},\r
+{0, 58303, 5758},\r
+{0, 58605, 5755},\r
+{0, 58525, 5741},\r
+{0, 58442, 5743},\r
+{0, 58462, 5742},\r
+{0, 58490, 5739},\r
+{0, 58560, 5748},\r
+{0, 58525, 5749},\r
+{0, 58540, 5750},\r
+{0, 58503, 5746},\r
+{0, 58493, 5761},\r
+{0, 58545, 5739},\r
+{0, 58611, 5745},\r
+{0, 58398, 5744},\r
+{0, 58150, 5735},\r
+{0, 57974, 5747},\r
+{0, 57910, 5753},\r
+{0, 57873, 5755},\r
+{0, 57974, 5747},\r
+{0, 58039, 5739},\r
+{0, 58109, 5743},\r
+{0, 58262, 5747},\r
+{0, 58475, 5745},\r
+{0, 58743, 5746},\r
+{0, 58708, 5744},\r
+{0, 58682, 5740},\r
+{0, 58788, 5742},\r
+{0, 58870, 5735},\r
+{0, 59011, 5753},\r
+{0, 59102, 5744},\r
+{0, 59174, 5757},\r
+{0, 59160, 5765},\r
+{0, 59160, 5750},\r
+{0, 59133, 5736},\r
+{0, 59067, 5755},\r
+{0, 58809, 5752},\r
+{0, 58558, 5738},\r
+{0, 58407, 5739},\r
+{0, 58292, 5748},\r
+{0, 58251, 5740},\r
+{0, 58202, 5753},\r
+{0, 58198, 5752},\r
+{0, 58281, 5752},\r
+{0, 58366, 5745},\r
+{0, 58480, 5749},\r
+{0, 58661, 5750},\r
+{0, 58558, 5754},\r
+{0, 58560, 5735},\r
+{0, 58650, 5732},\r
+{0, 58802, 5744},\r
+{0, 59016, 5745},\r
+{0, 59198, 5744},\r
+{0, 59345, 5745},\r
+{0, 59413, 5746},\r
+{0, 59437, 5751},\r
+{0, 59463, 5743},\r
+{0, 59468, 5751},\r
+{0, 59121, 5749},\r
+{0, 58823, 5741},\r
+{0, 58629, 5749},\r
+{0, 58602, 5750},\r
+{0, 58552, 5750},\r
+{0, 58340, 5761},\r
+{0, 58175, 5760},\r
+{0, 58375, 5764},\r
+{0, 58742, 5756},\r
+{0, 59153, 5754},\r
+{0, 59574, 5776},\r
+{0, 59689, 5764},\r
+{0, 59730, 5765},\r
+{0, 59944, 5768},\r
+{0, 60291, 5767},\r
+{0, 60651, 5779},\r
+{0, 60970, 5778},\r
+{0, 61158, 5785},\r
+{0, 61301, 5789},\r
+{0, 61367, 5782},\r
+{0, 61452, 5783},\r
+{0, 61498, 5778},\r
+{0, 61177, 5765},\r
+{0, 60974, 5768},\r
+{0, 60937, 5779},\r
+{0, 60978, 5776},\r
+{0, 61039, 5773},\r
+{0, 61187, 5773},\r
+{0, 61391, 5770},\r
+{0, 61560, 5781},\r
+{0, 61708, 5771},\r
+{0, 61897, 5788},\r
+{0, 62062, 5781},\r
+{0, 61847, 5776},\r
+{0, 61679, 5774},\r
+{0, 61729, 5767},\r
+{0, 61817, 5762},\r
+{0, 62033, 5774},\r
+{0, 62435, 5781},\r
+{0, 62691, 5789},\r
+{0, 62874, 5778},\r
+{0, 62944, 5777},\r
+{0, 62923, 5779},\r
+{0, 62701, 5777},\r
+{0, 62265, 5769},\r
+{0, 61947, 5761},\r
+{0, 61728, 5770},\r
+{0, 61531, 5762},\r
+{0, 61388, 5766},\r
+{0, 61354, 5762},\r
+{0, 61261, 5760},\r
+{0, 61357, 5755},\r
+{0, 61658, 5767},\r
+{0, 61964, 5754},\r
+{0, 61978, 5752},\r
+{0, 61821, 5752},\r
+{0, 62047, 5752},\r
+{0, 62480, 5765},\r
+{0, 63117, 5784},\r
+{0, 63920, 5797},\r
+{0, 64722, 5820},\r
+{0, 65481, 5820},\r
+{0, 66153, 5840},\r
+{0, 66805, 5832},\r
+{0, 67430, 5830},\r
+{0, 67616, 5827},\r
+{0, 67176, 5799},\r
+{0, 66784, 5793},\r
+{0, 66504, 5784},\r
+{0, 66281, 5794},\r
+{0, 66279, 5800},\r
+{0, 66315, 5789},\r
+{0, 66427, 5794},\r
+{0, 66577, 5804},\r
+{0, 66901, 5812},\r
+{0, 67291, 5803},\r
+{0, 67197, 5807},\r
+{0, 66853, 5810},\r
+{0, 66640, 5799},\r
+{0, 66557, 5807},\r
+{0, 66489, 5808},\r
+{0, 66766, 5793},\r
+{0, 67121, 5817},\r
+{0, 67509, 5830},\r
+{0, 67877, 5826},\r
+{0, 68346, 5854},\r
+{0, 68755, 5840},\r
+{0, 68684, 5826},\r
+{0, 68376, 5810},\r
+{0, 68194, 5825},\r
+{0, 68102, 5820},\r
+{0, 68062, 5832},\r
+{0, 68109, 5815},\r
+{0, 68151, 5820},\r
+{0, 68191, 5810},\r
+{0, 68216, 5814},\r
+{0, 68286, 5829},\r
+{0, 68272, 5818},\r
+{0, 67857, 5811},\r
+{0, 67430, 5811},\r
+{0, 67198, 5808},\r
+{0, 67092, 5813},\r
+{0, 67054, 5812},\r
+{0, 67066, 5813},\r
+{0, 67162, 5817},\r
+{0, 67365, 5803},\r
+{0, 67515, 5823},\r
+{0, 67768, 5809},\r
+{0, 67856, 5817},\r
+{0, 67338, 5802},\r
+{0, 66942, 5818},\r
+{0, 66703, 5805},\r
+{0, 66609, 5818},\r
+{0, 66564, 5809},\r
+{0, 66526, 5814},\r
+{0, 66527, 5801},\r
+{0, 66432, 5804},\r
+{0, 66472, 5800},\r
+{0, 66588, 5799},\r
+{0, 66481, 5805},\r
+{0, 66056, 5796},\r
+{0, 65725, 5797},\r
+{0, 65665, 5795},\r
+{0, 65769, 5788},\r
+{0, 66041, 5791},\r
+{0, 66367, 5804},\r
+{0, 66625, 5811},\r
+{0, 66977, 5813},\r
+{0, 67326, 5818},\r
+{0, 67674, 5827},\r
+{0, 67523, 5818},\r
+{0, 67166, 5816},\r
+{0, 67022, 5814},\r
+{0, 67012, 5822},\r
+{0, 67069, 5810},\r
+{0, 67155, 5814},\r
+{0, 67175, 5823},\r
+{0, 67157, 5822},\r
+{0, 67220, 5814},\r
+{0, 67291, 5816},\r
+{0, 67360, 5808},\r
+{0, 66878, 5802},\r
+{0, 66324, 5808},\r
+{0, 65974, 5804},\r
+{0, 65771, 5792},\r
+{0, 65684, 5800},\r
+{0, 65698, 5797},\r
+{0, 65929, 5791},\r
+{0, 66161, 5804},\r
+{0, 66476, 5800},\r
+{0, 66790, 5811},\r
+{0, 66773, 5811},\r
+{0, 66449, 5805},\r
+{0, 66313, 5807},\r
+{0, 66311, 5804},\r
+{0, 66367, 5808},\r
+{0, 66407, 5801},\r
+{0, 66416, 5802},\r
+{0, 66329, 5807},\r
+{0, 66250, 5804},\r
+{0, 66168, 5804},\r
+{0, 65886, 5804},\r
+{0, 65142, 5794},\r
+{0, 64512, 5789},\r
+{0, 64154, 5792},\r
+{0, 63912, 5786},\r
+{0, 63745, 5783},\r
+{0, 63634, 5792},\r
+{0, 63618, 5781},\r
+{0, 63589, 5780},\r
+{0, 63621, 5784},\r
+{0, 63667, 5788},\r
+{0, 63723, 5775},\r
+{0, 63663, 5783},\r
+{0, 63543, 5781},\r
+{0, 63339, 5782},\r
+{0, 63415, 5785},\r
+{0, 63624, 5789},\r
+{0, 63856, 5790},\r
+{0, 64020, 5794},\r
+{0, 64166, 5786},\r
+{0, 64343, 5784},\r
+{0, 64011, 5788},\r
+{0, 63315, 5786},\r
+{0, 62970, 5781},\r
+{0, 62792, 5780},\r
+{0, 62726, 5779},\r
+{0, 62643, 5787},\r
+{0, 62619, 5769},\r
+{0, 62679, 5784},\r
+{0, 62745, 5781},\r
+{0, 62700, 5791},\r
+{0, 62715, 5785},\r
+{0, 62752, 5778},\r
+{0, 62799, 5784},\r
+{0, 62886, 5779},\r
+{0, 63014, 5777},\r
+{0, 63144, 5783},\r
+{0, 63154, 5773},\r
+{0, 63229, 5780},\r
+{0, 63342, 5798},\r
+{0, 63509, 5792},\r
+{0, 63717, 5777},\r
+{0, 63398, 5785},\r
+{0, 63108, 5783},\r
+{0, 63116, 5775},\r
+{0, 63216, 5775},\r
+{0, 63266, 5778},\r
+{0, 63243, 5771},\r
+{0, 63181, 5772},\r
+{0, 63147, 5782},\r
+{0, 63098, 5775},\r
+{0, 63081, 5767},\r
+{0, 62881, 5777},\r
+{0, 62521, 5773},\r
+{0, 62174, 5766},\r
+{0, 61926, 5762},\r
+{0, 62018, 5769},\r
+{0, 62183, 5772},\r
+{0, 62361, 5782},\r
+{0, 62569, 5774},\r
+{0, 62877, 5796},\r
+{0, 63329, 5813},\r
+{0, 63713, 5811},\r
+{0, 63611, 5812},\r
+{0, 63706, 5814},\r
+{0, 63983, 5806},\r
+{0, 64201, 5814},\r
+{0, 64393, 5814},\r
+{0, 64477, 5801},\r
+{0, 64463, 5795},\r
+{0, 64578, 5821},\r
+{0, 64567, 5806},\r
+{0, 64551, 5809},\r
+{0, 63995, 5803},\r
+{0, 63444, 5792},\r
+{0, 63179, 5788},\r
+{0, 63083, 5786},\r
+{0, 62980, 5785},\r
+{0, 63076, 5790},\r
+{0, 63157, 5795},\r
+{0, 63215, 5796},\r
+{0, 63245, 5782},\r
+{0, 63377, 5789},\r
+{0, 63108, 5779},\r
+{0, 62438, 5768},\r
+{0, 62142, 5767},\r
+{0, 62083, 5768},\r
+{0, 62217, 5782},\r
+{0, 62529, 5786},\r
+{0, 62895, 5785},\r
+{0, 63360, 5783},\r
+{0, 63766, 5790},\r
+{0, 63999, 5791},\r
+{0, 63939, 5785},\r
+{0, 63510, 5796},\r
+{0, 63254, 5793},\r
+{0, 63078, 5789},\r
+{0, 62948, 5798},\r
+{0, 62889, 5789},\r
+{0, 62802, 5789},\r
+{0, 62642, 5783},\r
+{0, 62496, 5771},\r
+{0, 62349, 5788},\r
+{0, 62173, 5776},\r
+{0, 61617, 5770},\r
+{0, 61141, 5772},\r
+{0, 60906, 5762},\r
+{0, 60834, 5761},\r
+{0, 60871, 5751},\r
+{0, 60932, 5757},\r
+{0, 61100, 5759},\r
+{0, 61308, 5760},\r
+{0, 61524, 5780},\r
+{0, 61754, 5773},\r
+{0, 61506, 5766},\r
+{0, 61086, 5773},\r
+{0, 61049, 5770},\r
+{0, 61115, 5770},\r
+{0, 61247, 5781},\r
+{0, 61427, 5769},\r
+{0, 61613, 5773},\r
+{0, 61668, 5765},\r
+{0, 61806, 5766},\r
+{0, 62008, 5774},\r
+{0, 61886, 5763},\r
+{0, 61188, 5751},\r
+{0, 60639, 5748},\r
+{0, 60412, 5752},\r
+{0, 60316, 5757},\r
+{0, 60310, 5761},\r
+{0, 60356, 5763},\r
+{0, 60405, 5761},\r
+{0, 60464, 5760},\r
+{0, 60630, 5762},\r
+{0, 60863, 5763},\r
+{0, 60954, 5765},\r
+{0, 60572, 5751},\r
+{0, 60416, 5757},\r
+{0, 60448, 5754},\r
+{0, 60505, 5759},\r
+{0, 60713, 5773},\r
+{0, 60769, 5766},\r
+{0, 60714, 5757},\r
+{0, 60657, 5755},\r
+{0, 60591, 5760},\r
+{0, 60567, 5755},\r
+{0, 60112, 5743},\r
+{0, 59439, 5753},\r
+{0, 59128, 5731},\r
+{0, 59000, 5746},\r
+{0, 59138, 5739},\r
+{0, 59421, 5744},\r
+{0, 59689, 5752},\r
+{0, 60117, 5751},\r
+{0, 60761, 5757},\r
+{0, 61771, 5789},\r
+{0, 62517, 5791},\r
+{0, 62664, 5798},\r
+{0, 62968, 5801},\r
+{0, 63303, 5791},\r
+{0, 63803, 5800},\r
+{0, 64494, 5805},\r
+{0, 65280, 5821},\r
+{0, 66256, 5819},\r
+{0, 67130, 5848},\r
+{0, 67923, 5853},\r
+{0, 68576, 5847},\r
+{0, 68487, 5828},\r
+{0, 67761, 5822},\r
+{0, 67183, 5810},\r
+{0, 66736, 5800},\r
+{0, 66396, 5800},\r
+{0, 66196, 5800},\r
+{0, 66150, 5812},\r
+{0, 66140, 5808},\r
+{0, 66223, 5807},\r
+{0, 66268, 5807},\r
+{0, 66370, 5801},\r
+{0, 65916, 5803},\r
+{0, 65289, 5797},\r
+{0, 64821, 5792},\r
+{0, 64674, 5784},\r
+{0, 64593, 5783},\r
+{0, 64812, 5790},\r
+{0, 65189, 5802},\r
+{0, 65670, 5820},\r
+{0, 66247, 5823},\r
+{0, 66900, 5832},\r
+{0, 67635, 5835},\r
+{0, 67749, 5830},\r
+{0, 67574, 5832},\r
+{0, 67596, 5835},\r
+{0, 67845, 5853},\r
+{0, 68130, 5834},\r
+{0, 68102, 5839},\r
+{0, 67864, 5832},\r
+{0, 67565, 5817},\r
+{0, 67381, 5813},\r
+{0, 67659, 5813},\r
+{0, 67756, 5819},\r
+{0, 67225, 5809},\r
+{0, 66788, 5813},\r
+{0, 66727, 5810},\r
+{0, 66886, 5812},\r
+{0, 67216, 5828},\r
+{0, 67493, 5832},\r
+{0, 67616, 5831},\r
+{0, 67729, 5828},\r
+{0, 67878, 5821},\r
+{0, 68146, 5828},\r
+{0, 68091, 5833},\r
+{0, 67867, 5838},\r
+{0, 68003, 5833},\r
+{0, 68079, 5834},\r
+{0, 67937, 5828},\r
+{0, 67850, 5834},\r
+{0, 67800, 5833},\r
+{0, 67676, 5819},\r
+{0, 67331, 5828},\r
+{0, 66976, 5818},\r
+{0, 66549, 5813},\r
+{0, 65528, 5792},\r
+{0, 64550, 5784},\r
+{0, 63974, 5792},\r
+{0, 63567, 5775},\r
+{0, 63210, 5783},\r
+{0, 63037, 5785},\r
+{0, 63024, 5771},\r
+{0, 62869, 5789},\r
+{0, 62621, 5779},\r
+{0, 62435, 5776},\r
+{0, 62339, 5775},\r
+{0, 61775, 5769},\r
+{0, 61353, 5765},\r
+{0, 61326, 5760},\r
+{0, 61299, 5772},\r
+{0, 61406, 5767},\r
+{0, 61483, 5767},\r
+{0, 61587, 5776},\r
+{0, 61659, 5764},\r
+{0, 61663, 5775},\r
+{0, 61582, 5779},\r
+{0, 61102, 5767},\r
+{0, 60299, 5770},\r
+{0, 59889, 5750},\r
+{0, 59580, 5755},\r
+{0, 59491, 5756},\r
+{0, 59531, 5760},\r
+{0, 59514, 5756},\r
+{0, 59516, 5766},\r
+{0, 59580, 5769},\r
+{0, 59621, 5763},\r
+{0, 59592, 5770},\r
+{0, 59062, 5761},\r
+{0, 58561, 5749},\r
+{0, 58431, 5756},\r
+{0, 58411, 5751},\r
+{0, 58573, 5750},\r
+{0, 58764, 5749},\r
+{0, 58822, 5753},\r
+{0, 58958, 5756},\r
+{0, 58950, 5749},\r
+{0, 58893, 5751},\r
+{0, 58397, 5752},\r
+{0, 57606, 5737},\r
+{0, 57424, 5743},\r
+{0, 57486, 5744},\r
+{0, 57633, 5747},\r
+{0, 57848, 5741},\r
+{0, 58040, 5749},\r
+{0, 58217, 5757},\r
+{0, 58392, 5764},\r
+{0, 58635, 5751},\r
+{0, 58852, 5764},\r
+{0, 58597, 5767},\r
+{0, 58185, 5757},\r
+{0, 58137, 5756},\r
+{0, 58330, 5762},\r
+{0, 58589, 5770},\r
+{0, 58916, 5764},\r
+{0, 59214, 5765},\r
+{0, 59515, 5769},\r
+{0, 59834, 5779},\r
+{0, 60227, 5769},\r
+{0, 60469, 5777},\r
+{0, 59967, 5764},\r
+{0, 59520, 5759},\r
+{0, 59356, 5752},\r
+{0, 59217, 5761},\r
+{0, 59071, 5750},\r
+{0, 59034, 5751},\r
+{0, 59003, 5744},\r
+{0, 58991, 5752},\r
+{0, 58937, 5750},\r
+{0, 58924, 5748},\r
+{0, 58454, 5738},\r
+{0, 58087, 5738},\r
+{0, 58107, 5734},\r
+{0, 58230, 5745},\r
+{0, 58340, 5740},\r
+{0, 58388, 5737},\r
+{0, 58381, 5745},\r
+{0, 58354, 5728},\r
+{0, 58366, 5737},\r
+{0, 58590, 5741},\r
+{0, 58713, 5734},\r
+{0, 58377, 5737},\r
+{0, 58177, 5748},\r
+{0, 58197, 5749},\r
+{0, 58062, 5748},\r
+{0, 57978, 5741},\r
+{0, 57882, 5752},\r
+{0, 57678, 5731},\r
+{0, 57587, 5724},\r
+{0, 57539, 5726},\r
+{0, 57666, 5733},\r
+{0, 57404, 5729},\r
+{0, 56725, 5725},\r
+{0, 56332, 5715},\r
+{0, 56194, 5713},\r
+{0, 56214, 5723},\r
+{0, 56322, 5732},\r
+{0, 56364, 5712},\r
+{0, 56641, 5722},\r
+{0, 57064, 5729},\r
+{0, 57575, 5739},\r
+{0, 57817, 5747},\r
+{0, 57687, 5748},\r
+{0, 57893, 5775},\r
+{0, 58419, 5768},\r
+{0, 58955, 5779},\r
+{0, 59378, 5779},\r
+{0, 59833, 5787},\r
+{0, 60090, 5779},\r
+{0, 60183, 5782},\r
+{0, 60170, 5779},\r
+{0, 60060, 5773},\r
+{0, 59675, 5754},\r
+{0, 59371, 5761},\r
+{0, 59183, 5759},\r
+{0, 59076, 5766},\r
+{0, 59091, 5759},\r
+{0, 59158, 5763},\r
+{0, 59216, 5767},\r
+{0, 59323, 5768},\r
+{0, 59399, 5748},\r
+{0, 59512, 5755},\r
+{0, 59429, 5746},\r
+{0, 59066, 5752},\r
+{0, 58959, 5743},\r
+{0, 59186, 5754},\r
+{0, 59638, 5765},\r
+{0, 60181, 5784},\r
+{0, 60936, 5800},\r
+{0, 61657, 5809},\r
+{0, 62331, 5817},\r
+{0, 62850, 5829},\r
+{0, 63079, 5819},\r
+{0, 62691, 5803},\r
+{0, 62403, 5797},\r
+{0, 62247, 5786},\r
+{0, 62108, 5783},\r
+{0, 61555, 5762},\r
+{0, 61147, 5759},\r
+{0, 61019, 5762},\r
+{0, 61070, 5766},\r
+{0, 61315, 5766},\r
+{0, 61772, 5788},\r
+{0, 61988, 5776},\r
+{0, 62173, 5791},\r
+{0, 62663, 5803},\r
+{0, 63542, 5812},\r
+{0, 64690, 5832},\r
+{0, 66229, 5843},\r
+{0, 67894, 5855},\r
+{0, 69538, 5866},\r
+{0, 71053, 5877},\r
+{0, 72442, 5889},\r
+{0, 73620, 5884},\r
+{0, 74230, 5880},\r
+{0, 74560, 5873},\r
+{0, 74737, 5875},\r
+{0, 74832, 5874},\r
+{0, 74956, 5873},\r
+{0, 74951, 5864},\r
+{0, 74822, 5857},\r
+{0, 74693, 5866},\r
+{0, 74461, 5861},\r
+{0, 74480, 5857},\r
+{0, 74253, 5856},\r
+{0, 74028, 5859},\r
+{0, 74087, 5863},\r
+{0, 74329, 5869},\r
+{0, 74604, 5869},\r
+{0, 74985, 5872},\r
+{0, 75312, 5874},\r
+{0, 75745, 5877},\r
+{0, 76194, 5893},\r
+{0, 76682, 5889},\r
+{0, 76737, 5877},\r
+{0, 76508, 5883},\r
+{0, 76662, 5895},\r
+{0, 76768, 5873},\r
+{0, 76785, 5878},\r
+{0, 76680, 5875},\r
+{0, 76524, 5863},\r
+{0, 76236, 5869},\r
+{0, 75933, 5864},\r
+{0, 75706, 5864},\r
+{0, 75246, 5848},\r
+{0, 74109, 5834},\r
+{0, 73140, 5829},\r
+{0, 72645, 5818},\r
+{0, 72371, 5817},\r
+{0, 72475, 5824},\r
+{0, 72654, 5823},\r
+{0, 72765, 5830},\r
+{0, 72691, 5835},\r
+{0, 72530, 5832},\r
+{0, 72256, 5837},\r
+{0, 71277, 5825},\r
+{0, 70128, 5815},\r
+{0, 69529, 5806},\r
+{0, 69262, 5810},\r
+{0, 69252, 5816},\r
+{0, 69429, 5813},\r
+{0, 69521, 5814},\r
+{0, 69398, 5808},\r
+{0, 69071, 5809},\r
+{0, 68771, 5810},\r
+{0, 68021, 5803},\r
+{0, 66642, 5792},\r
+{0, 65608, 5774},\r
+{0, 65018, 5777},\r
+{0, 64687, 5772},\r
+{0, 64674, 5762},\r
+{0, 65014, 5768},\r
+{0, 65759, 5787},\r
+{0, 66432, 5799},\r
+{0, 66646, 5787},\r
+{0, 67223, 5804},\r
+{0, 67929, 5815},\r
+{0, 68566, 5820},\r
+{0, 69257, 5830},\r
+{0, 69328, 5843},\r
+{0, 68808, 5829},\r
+{0, 68356, 5832},\r
+{0, 67702, 5829},\r
+{0, 67236, 5818},\r
+{0, 67059, 5822},\r
+{0, 67074, 5812},\r
+{0, 66592, 5811},\r
+{0, 66123, 5826},\r
+{0, 65668, 5814},\r
+{0, 65264, 5805},\r
+{0, 64861, 5811},\r
+{0, 64532, 5808},\r
+{0, 64333, 5818},\r
+{0, 64260, 5824},\r
+{0, 64172, 5831},\r
+{0, 64121, 5830},\r
+{0, 63886, 5824},\r
+{0, 63395, 5839},\r
+{0, 63283, 5831},\r
+{0, 63627, 5836},\r
+{0, 64740, 5851},\r
+{0, 66508, 5878},\r
+{0, 68738, 5908},\r
+{0, 70560, 5895},\r
+{0, 71276, 5922},\r
+{0, 72054, 5922},\r
+{0, 72124, 5912},\r
+{0, 71485, 5917},\r
+{0, 71691, 5902},\r
+{0, 70895, 5857},\r
+{0, 70368, 5851},\r
+{0, 70082, 5845},\r
+{0, 69925, 5843},\r
+{0, 69905, 5847},\r
+{0, 69942, 5852},\r
+{0, 70040, 5841},\r
+{0, 69994, 5837},\r
+{0, 69472, 5839},\r
+{0, 69057, 5846},\r
+{0, 68970, 5842},\r
+{0, 69231, 5851},\r
+{0, 69660, 5851},\r
+{0, 70155, 5869},\r
+{0, 70734, 5875},\r
+{0, 71378, 5881},\r
+{0, 72055, 5891},\r
+{0, 72588, 5879},\r
+{0, 72942, 5898},\r
+{0, 72781, 5882},\r
+{0, 73013, 5897},\r
+{0, 73351, 5887},\r
+{0, 73884, 5902},\r
+{0, 74289, 5901},\r
+{0, 74571, 5887},\r
+{0, 74683, 5891},\r
+{0, 74872, 5906},\r
+{0, 75047, 5900},\r
+{0, 74844, 5905},\r
+{0, 74167, 5891},\r
+{0, 73993, 5890},\r
+{0, 74094, 5896},\r
+{0, 74312, 5888},\r
+{0, 74558, 5894},\r
+{0, 74754, 5885},\r
+{0, 74920, 5899},\r
+{0, 75189, 5895},\r
+{0, 75489, 5888},\r
+{0, 75178, 5893},\r
+{0, 74596, 5882},\r
+{0, 74433, 5879},\r
+{0, 74408, 5886},\r
+{0, 74345, 5884},\r
+{0, 74341, 5877},\r
+{0, 74239, 5877},\r
+{0, 74135, 5869},\r
+{0, 74031, 5869},\r
+{0, 73905, 5879},\r
+{0, 73164, 5860},\r
+{0, 72268, 5851},\r
+{0, 71838, 5867},\r
+{0, 71706, 5854},\r
+{0, 71727, 5861},\r
+{0, 71907, 5857},\r
+{0, 72125, 5872},\r
+{0, 72408, 5868},\r
+{0, 72895, 5877},\r
+{0, 73338, 5881},\r
+{0, 73321, 5878},\r
+{0, 72919, 5878},\r
+{0, 72972, 5873},\r
+{0, 73083, 5870},\r
+{0, 73309, 5878},\r
+{0, 73530, 5869},\r
+{0, 73618, 5872},\r
+{0, 73596, 5885},\r
+{0, 73587, 5864},\r
+{0, 73547, 5868},\r
+{0, 73019, 5858},\r
+{0, 72151, 5853},\r
+{0, 71781, 5846},\r
+{0, 71687, 5852},\r
+{0, 71796, 5853},\r
+{0, 71949, 5857},\r
+{0, 72062, 5857},\r
+{0, 72167, 5856},\r
+{0, 72338, 5863},\r
+{0, 72655, 5873},\r
+{0, 72417, 5856},\r
+{0, 71948, 5861},\r
+{0, 71695, 5852},\r
+{0, 71640, 5850},\r
+{0, 71668, 5853},\r
+{0, 71761, 5849},\r
+{0, 71731, 5851},\r
+{0, 71692, 5849},\r
+{0, 71601, 5835},\r
+{0, 71472, 5843},\r
+{0, 70814, 5831},\r
+{0, 69756, 5818},\r
+{0, 69035, 5816},\r
+{0, 68569, 5805},\r
+{0, 68414, 5808},\r
+{0, 68345, 5801},\r
+{0, 68178, 5804},\r
+{0, 67999, 5794},\r
+{0, 67861, 5810},\r
+{0, 67663, 5807},\r
+{0, 66724, 5808},\r
+{0, 65861, 5795},\r
+{0, 65417, 5801},\r
+{0, 65260, 5785},\r
+{0, 65332, 5793},\r
+{0, 65283, 5795},\r
+{0, 64988, 5792},\r
+{0, 64675, 5786},\r
+{0, 64347, 5788},\r
+{0, 63951, 5783},\r
+{0, 62852, 5765},\r
+{0, 61867, 5770},\r
+{0, 61368, 5769},\r
+{0, 61239, 5778},\r
+{0, 61486, 5767},\r
+{0, 61988, 5774},\r
+{0, 62632, 5799},\r
+{0, 63408, 5796},\r
+{0, 64151, 5805},\r
+{0, 64517, 5813},\r
+{0, 63974, 5807},\r
+{0, 63699, 5805},\r
+{0, 63722, 5807},\r
+{0, 63989, 5806},\r
+{0, 64370, 5819},\r
+{0, 64688, 5805},\r
+{0, 64879, 5813},\r
+{0, 65024, 5816},\r
+{0, 65176, 5815},\r
+{0, 65004, 5808},\r
+{0, 64410, 5809},\r
+{0, 64106, 5817},\r
+{0, 63971, 5800},\r
+{0, 63992, 5799},\r
+{0, 64194, 5820},\r
+{0, 64332, 5812},\r
+{0, 64431, 5805},\r
+{0, 64604, 5800},\r
+{0, 64817, 5813},\r
+{0, 64292, 5806},\r
+{0, 63632, 5795},\r
+{0, 63383, 5804},\r
+{0, 63220, 5796},\r
+{0, 63175, 5793},\r
+{0, 63247, 5796},\r
+{0, 63233, 5804},\r
+{0, 63277, 5804},\r
+{0, 63287, 5797},\r
+{0, 63344, 5799},\r
+{0, 62868, 5787},\r
+{0, 62286, 5785},\r
+{0, 62076, 5784},\r
+{0, 62090, 5775},\r
+{0, 62301, 5781},\r
+{0, 62520, 5784},\r
+{0, 62761, 5789},\r
+{0, 62998, 5788},\r
+{0, 63236, 5788},\r
+{0, 63448, 5790},\r
+{0, 62970, 5788},\r
+{0, 62468, 5779},\r
+{0, 62254, 5775},\r
+{0, 62212, 5777},\r
+{0, 62281, 5775},\r
+{0, 62401, 5772},\r
+{0, 62447, 5780},\r
+{0, 62508, 5773},\r
+{0, 62578, 5768},\r
+{0, 62634, 5771},\r
+{0, 62224, 5761},\r
+{0, 61786, 5764},\r
+{0, 61571, 5758},\r
+{0, 61532, 5764},\r
+{0, 61525, 5764},\r
+{0, 61630, 5759},\r
+{0, 61746, 5766},\r
+{0, 61978, 5764},\r
+{0, 62241, 5771},\r
+{0, 62393, 5766},\r
+{0, 62041, 5760},\r
+{0, 61717, 5759},\r
+{0, 61744, 5750},\r
+{0, 61798, 5768},\r
+{0, 61958, 5764},\r
+{0, 62164, 5765},\r
+{0, 62281, 5764},\r
+{0, 62350, 5759},\r
+{0, 62417, 5768},\r
+{0, 62321, 5760},\r
+{0, 61874, 5756},\r
+{0, 61570, 5763},\r
+{0, 61516, 5769},\r
+{0, 61562, 5749},\r
+{0, 61738, 5742},\r
+{0, 61918, 5758},\r
+{0, 62105, 5751},\r
+{0, 62273, 5760},\r
+{0, 62529, 5749},\r
+{0, 62418, 5747},\r
+{0, 62035, 5750},\r
+{0, 61840, 5746},\r
+{0, 61803, 5759},\r
+{0, 61857, 5757},\r
+{0, 62023, 5745},\r
+{0, 62152, 5746},\r
+{0, 62293, 5747},\r
+{0, 62456, 5754},\r
+{0, 62602, 5756},\r
+{0, 62479, 5760},\r
+{0, 62059, 5758},\r
+{0, 61748, 5763},\r
+{0, 61755, 5754},\r
+{0, 62085, 5762},\r
+{0, 62519, 5778},\r
+{0, 63003, 5785},\r
+{0, 63486, 5788},\r
+{0, 63995, 5786},\r
+{0, 64508, 5784},\r
+{0, 64561, 5794},\r
+{0, 64397, 5786},\r
+{0, 64457, 5788},\r
+{0, 64575, 5796},\r
+{0, 64673, 5792},\r
+{0, 64803, 5785},\r
+{0, 64980, 5778},\r
+{0, 65071, 5783},\r
+{0, 65174, 5780},\r
+{0, 65294, 5781},\r
+{0, 65023, 5777},\r
+{0, 64700, 5781},\r
+{0, 64722, 5794},\r
+{0, 64954, 5779},\r
+{0, 65308, 5796},\r
+{0, 65654, 5803},\r
+{0, 66008, 5808},\r
+{0, 66386, 5811},\r
+{0, 66740, 5810},\r
+{0, 67062, 5798},\r
+{0, 66763, 5791},\r
+{0, 66183, 5779},\r
+{0, 65919, 5783},\r
+{0, 65646, 5777},\r
+{0, 65664, 5776},\r
+{0, 65711, 5785},\r
+{0, 65683, 5773},\r
+{0, 65671, 5785},\r
+{0, 65738, 5774},\r
+{0, 65819, 5787},\r
+{0, 65451, 5779},\r
+{0, 65118, 5771},\r
+{0, 65027, 5774},\r
+{0, 65271, 5782},\r
+{0, 65605, 5789},\r
+{0, 65948, 5793},\r
+{0, 66186, 5783},\r
+{0, 66328, 5788},\r
+{0, 66427, 5789},\r
+{0, 66466, 5792},\r
+{0, 65897, 5776},\r
+{0, 65270, 5771},\r
+{0, 64912, 5764},\r
+{0, 64731, 5766},\r
+{0, 64702, 5767},\r
+{0, 64758, 5761},\r
+{0, 64787, 5759},\r
+{0, 64938, 5753},\r
+{0, 65112, 5759},\r
+{0, 65230, 5762},\r
+{0, 65048, 5765},\r
+{0, 64882, 5767},\r
+{0, 64873, 5778},\r
+{0, 65103, 5769},\r
+{0, 65276, 5784},\r
+{0, 65464, 5784},\r
+{0, 65575, 5772},\r
+{0, 65649, 5774},\r
+{0, 65761, 5780},\r
+{0, 65777, 5775},\r
+{0, 65414, 5770},\r
+{0, 65099, 5769},\r
+{0, 65000, 5764},\r
+{0, 65025, 5770},\r
+{0, 65040, 5759},\r
+{0, 65073, 5765},\r
+{0, 65220, 5765},\r
+{0, 65406, 5760},\r
+{0, 65631, 5766},\r
+{0, 65865, 5770},\r
+{0, 65764, 5769},\r
+{0, 65743, 5777},\r
+{0, 65831, 5778},\r
+{0, 65952, 5775},\r
+{0, 66226, 5781},\r
+{0, 66401, 5784},\r
+{0, 66447, 5791},\r
+{0, 66398, 5780},\r
+{0, 66371, 5779},\r
+{0, 66423, 5780},\r
+{0, 66029, 5771},\r
+{0, 65662, 5765},\r
+{0, 65568, 5775},\r
+{0, 65594, 5771},\r
+{0, 65686, 5774},\r
+{0, 65890, 5776},\r
+{0, 66024, 5787},\r
+{0, 66182, 5775},\r
+{0, 66399, 5779},\r
+{0, 66569, 5771},\r
+{0, 66266, 5783},\r
+{0, 66114, 5786},\r
+{0, 66074, 5772},\r
+{0, 66060, 5784},\r
+{0, 66115, 5785},\r
+{0, 66105, 5783},\r
+{0, 66012, 5780},\r
+{0, 65946, 5782},\r
+{0, 65920, 5778},\r
+{0, 65734, 5790},\r
+{0, 65300, 5771},\r
+{0, 65110, 5768},\r
+{0, 65090, 5767},\r
+{0, 65144, 5777},\r
+{0, 65246, 5773},\r
+{0, 65414, 5770},\r
+{0, 65557, 5781},\r
+{0, 65740, 5768},\r
+{0, 65934, 5782},\r
+{0, 65981, 5768},\r
+{0, 65614, 5770},\r
+{0, 65409, 5768},\r
+{0, 65337, 5783},\r
+{0, 65317, 5779},\r
+{0, 65347, 5775},\r
+{0, 65401, 5779},\r
+{0, 65399, 5776},\r
+{0, 65420, 5777},\r
+{0, 65465, 5782},\r
+{0, 65206, 5776},\r
+{0, 64708, 5765},\r
+{0, 64445, 5773},\r
+{0, 64390, 5759},\r
+{0, 64474, 5761},\r
+{0, 64616, 5760},\r
+{0, 64708, 5766},\r
+{0, 64787, 5768},\r
+{0, 64904, 5764},\r
+{0, 65010, 5760},\r
+{0, 64665, 5743},\r
+{0, 64290, 5753},\r
+{0, 64118, 5758},\r
+{0, 64036, 5746},\r
+{0, 64071, 5753},\r
+{0, 64079, 5771},\r
+{0, 64008, 5758},\r
+{0, 63954, 5757},\r
+{0, 63947, 5762},\r
+{0, 63745, 5769},\r
+{0, 63147, 5749},\r
+{0, 62753, 5751},\r
+{0, 62511, 5745},\r
+{0, 62522, 5743},\r
+{0, 62658, 5738},\r
+{0, 62850, 5751},\r
+{0, 63096, 5758},\r
+{0, 63219, 5764},\r
+{0, 63397, 5760},\r
+{0, 63139, 5750},\r
+{0, 62637, 5742},\r
+{0, 62332, 5758},\r
+{0, 62161, 5737},\r
+{0, 62134, 5744},\r
+{0, 62162, 5727},\r
+{0, 62146, 5740},\r
+{0, 62211, 5742},\r
+{0, 62268, 5741},\r
+{0, 62296, 5735},\r
+{0, 61821, 5727},\r
+{0, 61329, 5731},\r
+{0, 61131, 5733},\r
+{0, 61167, 5723},\r
+{0, 61340, 5729},\r
+{0, 61444, 5732},\r
+{0, 61536, 5734},\r
+{0, 61631, 5747},\r
+{0, 61716, 5743},\r
+{0, 61505, 5735},\r
+{0, 60787, 5722},\r
+{0, 60345, 5731},\r
+{0, 60181, 5741},\r
+{0, 60248, 5729},\r
+{0, 60367, 5737},\r
+{0, 60461, 5731},\r
+{0, 60632, 5730},\r
+{0, 60762, 5744},\r
+{0, 60915, 5718},\r
+{0, 60493, 5732},\r
+{0, 60104, 5731},\r
+{0, 59990, 5723},\r
+{0, 60105, 5727},\r
+{0, 60318, 5729},\r
+{0, 60557, 5738},\r
+{0, 60774, 5735},\r
+{0, 60965, 5726},\r
+{0, 61098, 5739},\r
+{0, 60909, 5738},\r
+{0, 60327, 5738},\r
+{0, 59928, 5732},\r
+{0, 59877, 5738},\r
+{0, 59907, 5723},\r
+{0, 60155, 5737},\r
+{0, 60278, 5744},\r
+{0, 60408, 5733},\r
+{0, 60642, 5738},\r
+{0, 60747, 5738},\r
+{0, 60382, 5735},\r
+{0, 60107, 5730},\r
+{0, 60189, 5733},\r
+{0, 60398, 5731},\r
+{0, 60675, 5735},\r
+{0, 60925, 5743},\r
+{0, 61206, 5762},\r
+{0, 61511, 5754},\r
+{0, 61864, 5773},\r
+{0, 61935, 5746},\r
+{0, 61608, 5752},\r
+{0, 61605, 5754},\r
+{0, 61722, 5757},\r
+{0, 61819, 5756},\r
+{0, 61935, 5754},\r
+{0, 62005, 5755},\r
+{0, 62119, 5737},\r
+{0, 62356, 5755},\r
+{0, 62664, 5758},\r
+{0, 62743, 5758},\r
+{0, 62874, 5759},\r
+{0, 63192, 5772},\r
+{0, 63557, 5776},\r
+{0, 63993, 5791},\r
+{0, 64457, 5788},\r
+{0, 64667, 5808},\r
+{0, 64672, 5779},\r
+{0, 64583, 5778},\r
+{0, 64148, 5768},\r
+{0, 63687, 5762},\r
+{0, 63436, 5761},\r
+{0, 63363, 5751},\r
+{0, 63396, 5768},\r
+{0, 63591, 5753},\r
+{0, 63767, 5756},\r
+{0, 63919, 5763},\r
+{0, 64148, 5773},\r
+{0, 64423, 5776},\r
+{0, 64354, 5782},\r
+{0, 64326, 5774},\r
+{0, 64347, 5775},\r
+{0, 64417, 5781},\r
+{0, 64483, 5770},\r
+{0, 64511, 5768},\r
+{0, 64398, 5758},\r
+{0, 64234, 5750},\r
+{0, 64125, 5749},\r
+{0, 63702, 5748},\r
+{0, 63276, 5737},\r
+{0, 63115, 5742},\r
+{0, 63116, 5736},\r
+{0, 63333, 5760},\r
+{0, 63639, 5754},\r
+{0, 63971, 5768},\r
+{0, 64317, 5771},\r
+{0, 64662, 5779},\r
+{0, 64835, 5766},\r
+{0, 64640, 5774},\r
+{0, 64461, 5762},\r
+{0, 64329, 5772},\r
+{0, 64323, 5765},\r
+{0, 64358, 5771},\r
+{0, 64365, 5752},\r
+{0, 64315, 5762},\r
+{0, 64374, 5760},\r
+{0, 64409, 5775},\r
+{0, 64065, 5755},\r
+{0, 63710, 5764},\r
+{0, 63622, 5751},\r
+{0, 63622, 5763},\r
+{0, 63793, 5758},\r
+{0, 64031, 5763},\r
+{0, 64245, 5764},\r
+{0, 64488, 5756},\r
+{0, 64749, 5766},\r
+{0, 64617, 5757},\r
+{0, 64352, 5759},\r
+{0, 64136, 5758},\r
+{0, 64014, 5749},\r
+{0, 64040, 5754},\r
+{0, 64046, 5756},\r
+{0, 64095, 5763},\r
+{0, 64098, 5755},\r
+{0, 64138, 5759},\r
+{0, 63955, 5753},\r
+{0, 63361, 5760},\r
+{0, 63008, 5748},\r
+{0, 62864, 5747},\r
+{0, 62913, 5756},\r
+{0, 63108, 5748},\r
+{0, 63239, 5748},\r
+{0, 63376, 5747},\r
+{0, 63590, 5752},\r
+{0, 63659, 5756},\r
+{0, 63189, 5736},\r
+{0, 62855, 5750},\r
+{0, 62591, 5741},\r
+{0, 62464, 5747},\r
+{0, 62395, 5736},\r
+{0, 62361, 5739},\r
+{0, 62420, 5746},\r
+{0, 62539, 5740},\r
+{0, 62640, 5733},\r
+{0, 62287, 5744},\r
+{0, 61802, 5721},\r
+{0, 61712, 5732},\r
+{0, 61717, 5734},\r
+{0, 61936, 5731},\r
+{0, 62140, 5733},\r
+{0, 62389, 5746},\r
+{0, 62592, 5751},\r
+{0, 62793, 5754},\r
+{0, 62674, 5743},\r
+{0, 62331, 5746},\r
+{0, 62134, 5745},\r
+{0, 62047, 5740},\r
+{0, 62065, 5749},\r
+{0, 62175, 5738},\r
+{0, 62296, 5762},\r
+{0, 62479, 5745},\r
+{0, 62641, 5745},\r
+{0, 62776, 5754},\r
+{0, 62507, 5738},\r
+{0, 62360, 5742},\r
+{0, 62422, 5746},\r
+{0, 62578, 5742},\r
+{0, 62801, 5740},\r
+{0, 62981, 5744},\r
+{0, 63075, 5748},\r
+{0, 63254, 5757},\r
+{0, 63363, 5748},\r
+{0, 63030, 5745},\r
+{0, 62689, 5741},\r
+{0, 62470, 5740},\r
+{0, 62370, 5744},\r
+{0, 62403, 5750},\r
+{0, 62483, 5742},\r
+{0, 62575, 5738},\r
+{0, 62695, 5745},\r
+{0, 63069, 5756},\r
+{0, 63296, 5751},\r
+{0, 63314, 5749},\r
+{0, 63217, 5758},\r
+{0, 63309, 5760},\r
+{0, 63452, 5758},\r
+{0, 63635, 5744},\r
+{0, 63826, 5756},\r
+{0, 63935, 5759},\r
+{0, 63999, 5757},\r
+{0, 63655, 5750},\r
+{0, 63351, 5755},\r
+{0, 63208, 5745},\r
+{0, 63206, 5748},\r
+{0, 63277, 5749},\r
+{0, 63469, 5753},\r
+{0, 63729, 5755},\r
+{0, 63966, 5764},\r
+{0, 64137, 5752},\r
+{0, 64112, 5757},\r
+{0, 63987, 5759},\r
+{0, 63732, 5781},\r
+{0, 63601, 5766},\r
+{0, 63678, 5769},\r
+{0, 63797, 5772},\r
+{0, 63884, 5769},\r
+{0, 63884, 5768},\r
+{0, 63918, 5761},\r
+{0, 63836, 5765},\r
+{0, 63581, 5762},\r
+{0, 63400, 5760},\r
+{0, 63287, 5760},\r
+{0, 63299, 5762},\r
+{0, 63377, 5759},\r
+{0, 63602, 5756},\r
+{0, 63770, 5753},\r
+{0, 64167, 5770},\r
+{0, 64532, 5774},\r
+{0, 64516, 5779},\r
+{0, 64481, 5769},\r
+{0, 64437, 5773},\r
+{0, 64521, 5778},\r
+{0, 64509, 5767},\r
+{0, 64520, 5778},\r
+{0, 64447, 5777},\r
+{0, 64397, 5770},\r
+{0, 64370, 5765},\r
+{0, 64160, 5768},\r
+{0, 63821, 5759},\r
+{0, 63573, 5761},\r
+{0, 63482, 5763},\r
+{0, 63505, 5757},\r
+{0, 63565, 5761},\r
+{0, 63695, 5755},\r
+{0, 63855, 5770},\r
+{0, 63950, 5762},\r
+{0, 63716, 5763},\r
+{0, 63219, 5762},\r
+{0, 62846, 5748},\r
+{0, 62658, 5752},\r
+{0, 62592, 5761},\r
+{0, 62540, 5735},\r
+{0, 62563, 5750},\r
+{0, 62569, 5757},\r
+{0, 62628, 5747},\r
+{0, 62420, 5743},\r
+{0, 61910, 5741},\r
+{0, 61690, 5742},\r
+{0, 61672, 5757},\r
+{0, 61870, 5747},\r
+{0, 62132, 5740},\r
+{0, 62472, 5755},\r
+{0, 62911, 5765},\r
+{0, 63297, 5773},\r
+{0, 63437, 5765},\r
+{0, 63107, 5773},\r
+{0, 63006, 5772},\r
+{0, 62997, 5769},\r
+{0, 62962, 5762},\r
+{0, 63064, 5765},\r
+{0, 63159, 5763},\r
+{0, 63242, 5770},\r
+{0, 63358, 5761},\r
+{0, 63449, 5761},\r
+{0, 63321, 5766},\r
+{0, 63150, 5761},\r
+{0, 63133, 5762},\r
+{0, 63367, 5782},\r
+{0, 63649, 5759},\r
+{0, 64041, 5781},\r
+{0, 64376, 5779},\r
+{0, 64717, 5792},\r
+{0, 65015, 5789},\r
+{0, 64825, 5787},\r
+{0, 64526, 5781},\r
+{0, 64226, 5784},\r
+{0, 64006, 5777},\r
+{0, 63941, 5784},\r
+{0, 64014, 5776},\r
+{0, 64072, 5789},\r
+{0, 64077, 5770},\r
+{0, 64241, 5770},\r
+{0, 64040, 5772},\r
+{0, 63628, 5763},\r
+{0, 63414, 5762},\r
+{0, 63471, 5768},\r
+{0, 63684, 5773},\r
+{0, 63888, 5776},\r
+{0, 64024, 5770},\r
+{0, 64124, 5775},\r
+{0, 64260, 5777},\r
+{0, 64026, 5763},\r
+{0, 63414, 5776},\r
+{0, 62978, 5760},\r
+{0, 62713, 5760},\r
+{0, 62586, 5756},\r
+{0, 62588, 5743},\r
+{0, 62620, 5759},\r
+{0, 62765, 5748},\r
+{0, 62946, 5760},\r
+{0, 62902, 5754},\r
+{0, 62456, 5748},\r
+{0, 62211, 5749},\r
+{0, 62172, 5759},\r
+{0, 62189, 5746},\r
+{0, 62341, 5764},\r
+{0, 62470, 5762},\r
+{0, 62529, 5759},\r
+{0, 62579, 5764},\r
+{0, 62535, 5747},\r
+{0, 61983, 5739},\r
+{0, 61407, 5751},\r
+{0, 61151, 5747},\r
+{0, 61085, 5743},\r
+{0, 61183, 5736},\r
+{0, 61289, 5736},\r
+{0, 61472, 5737},\r
+{0, 61717, 5748},\r
+{0, 61983, 5754},\r
+{0, 61816, 5744},\r
+{0, 61361, 5754},\r
+{0, 61275, 5736},\r
+{0, 61235, 5741},\r
+{0, 61351, 5747},\r
+{0, 61462, 5755},\r
+{0, 61521, 5754},\r
+{0, 61551, 5747},\r
+{0, 61576, 5754},\r
+{0, 61585, 5764},\r
+{0, 61220, 5745},\r
+{0, 60991, 5743},\r
+{0, 61000, 5747},\r
+{0, 61196, 5740},\r
+{0, 61561, 5753},\r
+{0, 61866, 5754},\r
+{0, 62172, 5747},\r
+{0, 62484, 5759},\r
+{0, 62803, 5768},\r
+{0, 62628, 5752},\r
+{0, 62286, 5766},\r
+{0, 62272, 5762},\r
+{0, 62382, 5767},\r
+{0, 62551, 5763},\r
+{0, 62704, 5758},\r
+{0, 62756, 5755},\r
+{0, 62805, 5769},\r
+{0, 62874, 5762},\r
+{0, 62686, 5758},\r
+{0, 62017, 5756},\r
+{0, 61656, 5755},\r
+{0, 61481, 5747},\r
+{0, 61410, 5752},\r
+{0, 61404, 5751},\r
+{0, 61426, 5754},\r
+{0, 61636, 5756},\r
+{0, 61908, 5752},\r
+{0, 62211, 5760},\r
+{0, 62010, 5755},\r
+{0, 61685, 5756},\r
+{0, 61541, 5749},\r
+{0, 61511, 5746},\r
+{0, 61593, 5757},\r
+{0, 61610, 5760},\r
+{0, 61607, 5762},\r
+{0, 61511, 5753},\r
+{0, 61551, 5748},\r
+{0, 61497, 5747},\r
+{0, 61484, 5748},\r
+{0, 61526, 5750},\r
+{0, 61645, 5739},\r
+{0, 61786, 5751},\r
+{0, 62042, 5756},\r
+{0, 62390, 5757},\r
+{0, 62832, 5771},\r
+{0, 63289, 5769},\r
+{0, 63709, 5784},\r
+{0, 63647, 5782},\r
+{0, 63323, 5767},\r
+{0, 63181, 5771},\r
+{0, 63174, 5771},\r
+{0, 63162, 5763},\r
+{0, 63154, 5768},\r
+{0, 63011, 5762},\r
+{0, 63026, 5759},\r
+{0, 63142, 5753},\r
+{0, 62934, 5757},\r
+{0, 62515, 5760},\r
+{0, 62312, 5757},\r
+{0, 62297, 5754},\r
+{0, 62433, 5751},\r
+{0, 62682, 5754},\r
+{0, 62858, 5770},\r
+{0, 63028, 5755},\r
+{0, 63303, 5764},\r
+{0, 63398, 5755},\r
+{0, 62993, 5757},\r
+{0, 62608, 5753},\r
+{0, 62458, 5751},\r
+{0, 62346, 5743},\r
+{0, 62280, 5754},\r
+{0, 62242, 5763},\r
+{0, 62303, 5758},\r
+{0, 62358, 5765},\r
+{0, 62472, 5752},\r
+{0, 62424, 5752},\r
+{0, 62311, 5755},\r
+{0, 62270, 5752},\r
+{0, 62418, 5742},\r
+{0, 62654, 5760},\r
+{0, 62962, 5759},\r
+{0, 63310, 5777},\r
+{0, 63590, 5766},\r
+{0, 63899, 5772},\r
+{0, 64095, 5770},\r
+{0, 63684, 5757},\r
+{0, 63343, 5759},\r
+{0, 63230, 5759},\r
+{0, 63190, 5761},\r
+{0, 63277, 5762},\r
+{0, 63404, 5762},\r
+{0, 63526, 5775},\r
+{0, 63639, 5768},\r
+{0, 63752, 5771},\r
+{0, 63594, 5767},\r
+{0, 63147, 5760},\r
+{0, 62958, 5761},\r
+{0, 63029, 5754},\r
+{0, 63132, 5751},\r
+{0, 63350, 5763},\r
+{0, 63580, 5762},\r
+{0, 63728, 5762},\r
+{0, 63925, 5768},\r
+{0, 63941, 5769},\r
+{0, 63374, 5768},\r
+{0, 63028, 5750},\r
+{0, 62776, 5750},\r
+{0, 62640, 5756},\r
+{0, 62609, 5752},\r
+{0, 62681, 5755},\r
+{0, 62738, 5758},\r
+{0, 62820, 5763},\r
+{0, 62920, 5766},\r
+{0, 62639, 5759},\r
+{0, 62154, 5747},\r
+{0, 61864, 5743},\r
+{0, 61888, 5754},\r
+{0, 61960, 5753},\r
+{0, 62239, 5756},\r
+{0, 62466, 5758},\r
+{0, 62673, 5744},\r
+{0, 62900, 5764},\r
+{0, 62949, 5756},\r
+{0, 62397, 5750},\r
+{0, 61978, 5739},\r
+{0, 61755, 5753},\r
+{0, 61742, 5750},\r
+{0, 61845, 5753},\r
+{0, 62054, 5757},\r
+{0, 62186, 5766},\r
+{0, 62475, 5747},\r
+{0, 62930, 5770},\r
+{0, 63060, 5779},\r
+{0, 63022, 5779},\r
+{0, 63195, 5789},\r
+{0, 63697, 5783},\r
+{0, 64224, 5793},\r
+{0, 64910, 5810},\r
+{0, 65466, 5818},\r
+{0, 65995, 5809},\r
+{0, 66372, 5816},\r
+{0, 66701, 5813},\r
+{0, 66300, 5808},\r
+{0, 65946, 5809},\r
+{0, 65914, 5801},\r
+{0, 66021, 5804},\r
+{0, 66248, 5800},\r
+{0, 66482, 5807},\r
+{0, 66756, 5813},\r
+{0, 67131, 5814},\r
+{0, 67588, 5818},\r
+{0, 67899, 5825},\r
+{0, 67683, 5829},\r
+{0, 67813, 5826},\r
+{0, 68164, 5831},\r
+{0, 68446, 5820},\r
+{0, 68572, 5827},\r
+{0, 68717, 5829},\r
+{0, 68651, 5818},\r
+{0, 68414, 5813},\r
+{0, 67988, 5809},\r
+{0, 66941, 5788},\r
+{0, 65900, 5771},\r
+{0, 65298, 5767},\r
+{0, 64972, 5767},\r
+{0, 64967, 5779},\r
+{0, 65180, 5779},\r
+{0, 65468, 5791},\r
+{0, 65798, 5789},\r
+{0, 66108, 5798},\r
+{0, 66179, 5801},\r
+{0, 65593, 5790},\r
+{0, 65138, 5785},\r
+{0, 64874, 5788},\r
+{0, 64714, 5776},\r
+{0, 64530, 5775},\r
+{0, 64268, 5760},\r
+{0, 63955, 5763},\r
+{0, 63708, 5756},\r
+{0, 63417, 5753},\r
+{0, 62657, 5751},\r
+{0, 61682, 5742},\r
+{0, 61233, 5736},\r
+{0, 61069, 5742},\r
+{0, 61310, 5746},\r
+{0, 61715, 5746},\r
+{0, 62000, 5746},\r
+{0, 62230, 5752},\r
+{0, 62449, 5757},\r
+{0, 62507, 5774},\r
+{0, 61654, 5746},\r
+{0, 60821, 5744},\r
+{0, 60387, 5737},\r
+{0, 59880, 5735},\r
+{0, 59496, 5728},\r
+{0, 59358, 5732},\r
+{0, 59354, 5723},\r
+{0, 59329, 5742},\r
+{0, 59331, 5737},\r
+{0, 59350, 5734},\r
+{0, 58819, 5728},\r
+{0, 58525, 5740},\r
+{0, 58515, 5728},\r
+{0, 58705, 5738},\r
+{0, 59026, 5744},\r
+{0, 59270, 5742},\r
+{0, 59452, 5751},\r
+{0, 59545, 5756},\r
+{0, 59445, 5766},\r
+{0, 58818, 5743},\r
+{0, 58052, 5742},\r
+{0, 57569, 5734},\r
+{0, 57291, 5741},\r
+{0, 57174, 5719},\r
+{0, 57123, 5728},\r
+{0, 57029, 5735},\r
+{0, 57037, 5725},\r
+{0, 57128, 5732},\r
+{0, 57275, 5739},\r
+{0, 57110, 5733},\r
+{0, 56866, 5719},\r
+{0, 56784, 5736},\r
+{0, 56829, 5726},\r
+{0, 56994, 5735},\r
+{0, 57163, 5734},\r
+{0, 57203, 5731},\r
+{0, 57254, 5731},\r
+{0, 57384, 5735},\r
+{0, 57097, 5737},\r
+{0, 56576, 5730},\r
+{0, 56363, 5713},\r
+{0, 56377, 5712},\r
+{0, 56788, 5709},\r
+{0, 57322, 5724},\r
+{0, 57840, 5728},\r
+{0, 58287, 5746},\r
+{0, 58599, 5765},\r
+{0, 58873, 5755},\r
+{0, 58992, 5759},\r
+{0, 59133, 5769},\r
+{0, 59547, 5776},\r
+{0, 59909, 5776},\r
+{0, 60181, 5785},\r
+{0, 60555, 5793},\r
+{0, 61020, 5794},\r
+{0, 61340, 5797},\r
+{0, 61674, 5807},\r
+{0, 62036, 5793},\r
+{0, 61854, 5794},\r
+{0, 61705, 5814},\r
+{0, 61585, 5800},\r
+{0, 61722, 5805},\r
+{0, 62005, 5809},\r
+{0, 62302, 5810},\r
+{0, 62595, 5805},\r
+{0, 62918, 5820},\r
+{0, 63313, 5820},\r
+{0, 63635, 5831},\r
+{0, 63577, 5836},\r
+{0, 63674, 5823},\r
+{0, 64003, 5819},\r
+{0, 64328, 5816},\r
+{0, 64621, 5828},\r
+{0, 64843, 5829},\r
+{0, 64937, 5817},\r
+{0, 65114, 5801},\r
+{0, 65204, 5813},\r
+{0, 64832, 5809},\r
+{0, 64433, 5810},\r
+{0, 64394, 5802},\r
+{0, 64461, 5801},\r
+{0, 64496, 5809},\r
+{0, 64595, 5796},\r
+{0, 64774, 5791},\r
+{0, 65024, 5797},\r
+{0, 65207, 5801},\r
+{0, 65222, 5796},\r
+{0, 64850, 5784},\r
+{0, 64501, 5796},\r
+{0, 64304, 5796},\r
+{0, 64228, 5791},\r
+{0, 64207, 5780},\r
+{0, 64083, 5781},\r
+{0, 63955, 5779},\r
+{0, 63836, 5782},\r
+{0, 63848, 5786},\r
+{0, 63637, 5773},\r
+{0, 63210, 5761},\r
+{0, 62985, 5764},\r
+{0, 63039, 5767},\r
+{0, 63197, 5760},\r
+{0, 63341, 5778},\r
+{0, 63544, 5769},\r
+{0, 63739, 5767},\r
+{0, 63995, 5772},\r
+{0, 64323, 5767},\r
+{0, 64049, 5771},\r
+{0, 63642, 5765},\r
+{0, 63411, 5776},\r
+{0, 63356, 5765},\r
+{0, 63354, 5760},\r
+{0, 63317, 5751},\r
+{0, 63314, 5766},\r
+{0, 63295, 5763},\r
+{0, 63400, 5766},\r
+{0, 63437, 5758},\r
+{0, 63369, 5753},\r
+{0, 63327, 5767},\r
+{0, 63399, 5759},\r
+{0, 63467, 5750},\r
+{0, 63522, 5749},\r
+{0, 63643, 5760},\r
+{0, 63746, 5760},\r
+{0, 63901, 5755},\r
+{0, 63995, 5758},\r
+{0, 63701, 5752},\r
+{0, 63011, 5745},\r
+{0, 62404, 5752},\r
+{0, 62038, 5750},\r
+{0, 61801, 5749},\r
+{0, 61751, 5745},\r
+{0, 61743, 5751},\r
+{0, 61793, 5749},\r
+{0, 61898, 5745},\r
+{0, 62023, 5747},\r
+{0, 61989, 5745},\r
+{0, 61826, 5761},\r
+{0, 61562, 5750},\r
+{0, 61468, 5744},\r
+{0, 61576, 5749},\r
+{0, 61709, 5746},\r
+{0, 61772, 5750},\r
+{0, 61894, 5748},\r
+{0, 62009, 5755},\r
+{0, 61689, 5750},\r
+{0, 60954, 5751},\r
+{0, 60651, 5746},\r
+{0, 60585, 5749},\r
+{0, 60813, 5753},\r
+{0, 61144, 5773},\r
+{0, 61595, 5769},\r
+{0, 62118, 5771},\r
+{0, 62545, 5772},\r
+{0, 63013, 5782},\r
+{0, 62921, 5776},\r
+{0, 62850, 5789},\r
+{0, 63039, 5782},\r
+{0, 63403, 5789},\r
+{0, 63687, 5795},\r
+{0, 64014, 5791},\r
+{0, 64196, 5800},\r
+{0, 64372, 5798},\r
+{0, 64558, 5792},\r
+{0, 64607, 5795},\r
+{0, 64151, 5787},\r
+{0, 63895, 5787},\r
+{0, 63954, 5799},\r
+{0, 64189, 5779},\r
+{0, 64587, 5797},\r
+{0, 64970, 5815},\r
+{0, 65360, 5812},\r
+{0, 65723, 5796},\r
+{0, 66100, 5807},\r
+{0, 65975, 5796},\r
+{0, 65534, 5808},\r
+{0, 65351, 5795},\r
+{0, 65235, 5793},\r
+{0, 65136, 5783},\r
+{0, 64956, 5786},\r
+{0, 64777, 5778},\r
+{0, 64592, 5776},\r
+{0, 64480, 5778},\r
+{0, 64341, 5773},\r
+{0, 63685, 5778},\r
+{0, 63290, 5765},\r
+{0, 63096, 5767},\r
+{0, 63082, 5765},\r
+{0, 63151, 5769},\r
+{0, 63320, 5775},\r
+{0, 63511, 5790},\r
+{0, 63711, 5780},\r
+{0, 63809, 5779},\r
+{0, 63518, 5773},\r
+{0, 63015, 5767},\r
+{0, 62667, 5757},\r
+{0, 62371, 5760},\r
+{0, 62291, 5769},\r
+{0, 62318, 5751},\r
+{0, 62416, 5759},\r
+{0, 62491, 5772},\r
+{0, 62615, 5768},\r
+{0, 62820, 5780},\r
+{0, 62766, 5766},\r
+{0, 62747, 5767},\r
+{0, 63006, 5772},\r
+{0, 63298, 5786},\r
+{0, 63805, 5800},\r
+{0, 64308, 5792},\r
+{0, 64580, 5798},\r
+{0, 64543, 5797},\r
+{0, 64519, 5794},\r
+{0, 64231, 5788},\r
+{0, 63415, 5779},\r
+{0, 62813, 5780},\r
+{0, 62529, 5770},\r
+{0, 62474, 5761},\r
+{0, 62398, 5768},\r
+{0, 62397, 5763},\r
+{0, 62343, 5759},\r
+{0, 62261, 5762},\r
+{0, 62380, 5747},\r
+{0, 62215, 5753},\r
+{0, 61797, 5751},\r
+{0, 61596, 5748},\r
+{0, 61604, 5756},\r
+{0, 61836, 5762},\r
+{0, 62020, 5772},\r
+{0, 62051, 5761},\r
+{0, 62117, 5753},\r
+{0, 62315, 5767},\r
+{0, 62360, 5753},\r
+{0, 61815, 5764},\r
+{0, 61413, 5765},\r
+{0, 61228, 5760},\r
+{0, 61243, 5763},\r
+{0, 61355, 5763},\r
+{0, 61465, 5763},\r
+{0, 61588, 5761},\r
+{0, 61827, 5756},\r
+{0, 62006, 5774},\r
+{0, 61740, 5766},\r
+{0, 61107, 5748},\r
+{0, 60842, 5763},\r
+{0, 60838, 5763},\r
+{0, 60879, 5764},\r
+{0, 60958, 5768},\r
+{0, 61025, 5765},\r
+{0, 61060, 5758},\r
+{0, 61128, 5766},\r
+{0, 61120, 5766},\r
+{0, 60481, 5756},\r
+{0, 59914, 5755},\r
+{0, 59784, 5756},\r
+{0, 59777, 5762},\r
+{0, 59909, 5754},\r
+{0, 60083, 5757},\r
+{0, 60273, 5750},\r
+{0, 60514, 5752},\r
+{0, 60767, 5765},\r
+{0, 60808, 5754},\r
+{0, 60216, 5760},\r
+{0, 59910, 5738},\r
+{0, 59901, 5752},\r
+{0, 60023, 5769},\r
+{0, 60248, 5747},\r
+{0, 60533, 5744},\r
+{0, 60757, 5758},\r
+{0, 60971, 5770},\r
+{0, 61228, 5762},\r
+{0, 61118, 5753},\r
+{0, 60529, 5747},\r
+{0, 60192, 5745},\r
+{0, 60154, 5760},\r
+{0, 60270, 5749},\r
+{0, 60504, 5748},\r
+{0, 60755, 5762},\r
+{0, 60987, 5762},\r
+{0, 61232, 5763},\r
+{0, 61545, 5772},\r
+{0, 61119, 5764},\r
+{0, 60678, 5754},\r
+{0, 60493, 5762},\r
+{0, 60521, 5758},\r
+{0, 60591, 5754},\r
+{0, 60694, 5764},\r
+{0, 60803, 5757},\r
+{0, 60882, 5765},\r
+{0, 61101, 5764},\r
+{0, 61053, 5762},\r
+{0, 60476, 5753},\r
+{0, 60163, 5745},\r
+{0, 60176, 5754},\r
+{0, 60286, 5753},\r
+{0, 60471, 5761},\r
+{0, 60597, 5762},\r
+{0, 60765, 5750},\r
+{0, 60997, 5761},\r
+{0, 61186, 5760},\r
+{0, 61057, 5762},\r
+{0, 60504, 5741},\r
+{0, 60319, 5755},\r
+{0, 60354, 5755},\r
+{0, 60391, 5750},\r
+{0, 60439, 5751},\r
+{0, 60638, 5759},\r
+{0, 60767, 5754},\r
+{0, 60935, 5758},\r
+{0, 61126, 5760},\r
+{0, 60949, 5745},\r
+{0, 60527, 5750},\r
+{0, 60443, 5760},\r
+{0, 60562, 5750},\r
+{0, 60801, 5748},\r
+{0, 61128, 5754},\r
+{0, 61414, 5750},\r
+{0, 61637, 5757},\r
+{0, 61799, 5764},\r
+{0, 61925, 5765},\r
+{0, 61318, 5750},\r
+{0, 60805, 5743},\r
+{0, 60637, 5753},\r
+{0, 60530, 5749},\r
+{0, 60663, 5751},\r
+{0, 60765, 5756},\r
+{0, 60836, 5761},\r
+{0, 61034, 5764},\r
+{0, 61247, 5756},\r
+{0, 61305, 5746},\r
+{0, 60906, 5748},\r
+{0, 60653, 5750},\r
+{0, 60763, 5755},\r
+{0, 60995, 5751},\r
+{0, 61257, 5750},\r
+{0, 61507, 5756},\r
+{0, 61611, 5763},\r
+{0, 61801, 5767},\r
+{0, 62006, 5761},\r
+{0, 61518, 5762},\r
+{0, 60908, 5756},\r
+{0, 60678, 5741},\r
+{0, 60636, 5741},\r
+{0, 60638, 5755},\r
+{0, 60782, 5742},\r
+{0, 60932, 5749},\r
+{0, 61152, 5753},\r
+{0, 61356, 5757},\r
+{0, 61590, 5752},\r
+{0, 61185, 5753},\r
+{0, 60885, 5744},\r
+{0, 60924, 5749},\r
+{0, 61051, 5745},\r
+{0, 61224, 5755},\r
+{0, 61432, 5758},\r
+{0, 61663, 5753},\r
+{0, 61788, 5757},\r
+{0, 61848, 5763},\r
+{0, 61655, 5762},\r
+{0, 61100, 5749},\r
+{0, 60799, 5753},\r
+{0, 60930, 5756},\r
+{0, 61177, 5769},\r
+{0, 61555, 5760},\r
+{0, 61857, 5761},\r
+{0, 62092, 5772},\r
+{0, 62220, 5776},\r
+{0, 62445, 5767},\r
+{0, 62334, 5773},\r
+{0, 61905, 5771},\r
+{0, 61789, 5772},\r
+{0, 61878, 5775},\r
+{0, 62054, 5771},\r
+{0, 62205, 5772},\r
+{0, 62328, 5766},\r
+{0, 62407, 5769},\r
+{0, 62495, 5765},\r
+{0, 62495, 5759},\r
+{0, 62005, 5761},\r
+{0, 61616, 5767},\r
+{0, 61503, 5766},\r
+{0, 61602, 5758},\r
+{0, 61782, 5765},\r
+{0, 61961, 5753},\r
+{0, 62120, 5769},\r
+{0, 62290, 5768},\r
+{0, 62478, 5762},\r
+{0, 62490, 5762},\r
+{0, 61913, 5760},\r
+{0, 61594, 5758},\r
+{0, 61515, 5765},\r
+{0, 61640, 5761},\r
+{0, 61692, 5759},\r
+{0, 61827, 5755},\r
+{0, 61797, 5751},\r
+{0, 61813, 5742},\r
+{0, 62036, 5745},\r
+{0, 61561, 5728},\r
+{0, 61086, 5738},\r
+{0, 60923, 5739},\r
+{0, 60929, 5749},\r
+{0, 61136, 5744},\r
+{0, 61373, 5761},\r
+{0, 61605, 5756},\r
+{0, 61880, 5768},\r
+{0, 62064, 5774},\r
+{0, 62169, 5777},\r
+{0, 61895, 5761},\r
+{0, 62248, 5790},\r
+{0, 62649, 5785},\r
+{0, 63056, 5790},\r
+{0, 63459, 5794},\r
+{0, 63755, 5790},\r
+{0, 63968, 5803},\r
+{0, 63975, 5787},\r
+{0, 64034, 5803},\r
+{0, 63465, 5792},\r
+{0, 62798, 5789},\r
+{0, 62708, 5780},\r
+{0, 62791, 5788},\r
+{0, 62952, 5778},\r
+{0, 63170, 5772},\r
+{0, 63326, 5790},\r
+{0, 63500, 5789},\r
+{0, 63731, 5793},\r
+{0, 63953, 5791},\r
+{0, 63556, 5791},\r
+{0, 63278, 5797},\r
+{0, 63188, 5799},\r
+{0, 63161, 5783},\r
+{0, 63197, 5793},\r
+{0, 63261, 5793},\r
+{0, 63118, 5795},\r
+{0, 63035, 5797},\r
+{0, 62978, 5804},\r
+{0, 62831, 5781},\r
+{0, 62288, 5783},\r
+{0, 61923, 5779},\r
+{0, 61893, 5786},\r
+{0, 62082, 5781},\r
+{0, 62299, 5780},\r
+{0, 62488, 5772},\r
+{0, 62663, 5784},\r
+{0, 62891, 5785},\r
+{0, 63095, 5783},\r
+{0, 62599, 5780},\r
+{0, 62140, 5774},\r
+{0, 61934, 5768},\r
+{0, 61857, 5781},\r
+{0, 61991, 5782},\r
+{0, 62116, 5770},\r
+{0, 62133, 5780},\r
+{0, 62187, 5793},\r
+{0, 62388, 5779},\r
+{0, 62226, 5771},\r
+{0, 61572, 5774},\r
+{0, 61252, 5767},\r
+{0, 61281, 5764},\r
+{0, 61458, 5774},\r
+{0, 61656, 5776},\r
+{0, 61844, 5780},\r
+{0, 62050, 5790},\r
+{0, 62420, 5782},\r
+{0, 62644, 5777},\r
+{0, 62145, 5781},\r
+{0, 61751, 5780},\r
+{0, 61625, 5777},\r
+{0, 61618, 5789},\r
+{0, 61696, 5782},\r
+{0, 61788, 5782},\r
+{0, 61874, 5777},\r
+{0, 62052, 5785},\r
+{0, 62266, 5778},\r
+{0, 62277, 5786},\r
+{0, 61693, 5772},\r
+{0, 61435, 5778},\r
+{0, 61478, 5774},\r
+{0, 61711, 5764},\r
+{0, 61963, 5774},\r
+{0, 62215, 5776},\r
+{0, 62488, 5775},\r
+{0, 62743, 5788},\r
+{0, 63075, 5777},\r
+{0, 62594, 5783},\r
+{0, 62240, 5774},\r
+{0, 62145, 5775},\r
+{0, 62187, 5777},\r
+{0, 62278, 5776},\r
+{0, 62370, 5787},\r
+{0, 62541, 5776},\r
+{0, 62705, 5782},\r
+{0, 62874, 5783},\r
+{0, 62884, 5776},\r
+{0, 62389, 5773},\r
+{0, 62256, 5777},\r
+{0, 62397, 5768},\r
+{0, 62622, 5762},\r
+{0, 62894, 5773},\r
+{0, 63120, 5786},\r
+{0, 63277, 5773},\r
+{0, 63460, 5786},\r
+{0, 63655, 5783},\r
+{0, 63108, 5776},\r
+{0, 62718, 5775},\r
+{0, 62604, 5767},\r
+{0, 62563, 5769},\r
+{0, 62588, 5765},\r
+{0, 62552, 5769},\r
+{0, 62597, 5777},\r
+{0, 62628, 5780},\r
+{0, 62750, 5772},\r
+{0, 62529, 5768},\r
+{0, 61909, 5758},\r
+{0, 61576, 5762},\r
+{0, 61491, 5766},\r
+{0, 61657, 5759},\r
+{0, 61816, 5770},\r
+{0, 61928, 5765},\r
+{0, 62069, 5770},\r
+{0, 62260, 5770},\r
+{0, 62413, 5767},\r
+{0, 61801, 5770},\r
+{0, 61443, 5760},\r
+{0, 61378, 5762},\r
+{0, 61482, 5765},\r
+{0, 61646, 5765},\r
+{0, 61804, 5770},\r
+{0, 61832, 5771},\r
+{0, 61897, 5765},\r
+{0, 62009, 5767},\r
+{0, 61689, 5760},\r
+{0, 61014, 5750},\r
+{0, 60775, 5767},\r
+{0, 60705, 5755},\r
+{0, 60819, 5763},\r
+{0, 61163, 5762},\r
+{0, 61478, 5768},\r
+{0, 61753, 5764},\r
+{0, 62056, 5767},\r
+{0, 62274, 5765},\r
+{0, 61735, 5768},\r
+{0, 61425, 5760},\r
+{0, 61502, 5765},\r
+{0, 61651, 5762},\r
+{0, 61912, 5769},\r
+{0, 62253, 5775},\r
+{0, 62469, 5770},\r
+{0, 62734, 5774},\r
+{0, 62879, 5780},\r
+{0, 62580, 5783},\r
+{0, 61939, 5776},\r
+{0, 61669, 5771},\r
+{0, 61602, 5767},\r
+{0, 61671, 5786},\r
+{0, 61839, 5781},\r
+{0, 61977, 5771},\r
+{0, 62185, 5776},\r
+{0, 62400, 5783},\r
+{0, 62562, 5778},\r
+{0, 61962, 5760},\r
+{0, 61616, 5757},\r
+{0, 61672, 5776},\r
+{0, 61838, 5778},\r
+{0, 62090, 5758},\r
+{0, 62358, 5772},\r
+{0, 62582, 5779},\r
+{0, 62693, 5792},\r
+{0, 62966, 5791},\r
+{0, 62697, 5791},\r
+{0, 62455, 5783},\r
+{0, 62467, 5769},\r
+{0, 62605, 5783},\r
+{0, 62840, 5782},\r
+{0, 63168, 5786},\r
+{0, 63532, 5784},\r
+{0, 63896, 5794},\r
+{0, 64291, 5805},\r
+{0, 64758, 5804},\r
+{0, 64611, 5794},\r
+{0, 64211, 5797},\r
+{0, 64158, 5792},\r
+{0, 64267, 5801},\r
+{0, 64491, 5802},\r
+{0, 64811, 5805},\r
+{0, 65062, 5815},\r
+{0, 65306, 5812},\r
+{0, 65441, 5804},\r
+{0, 65284, 5799},\r
+{0, 64434, 5774},\r
+{0, 63854, 5784},\r
+{0, 63529, 5769},\r
+{0, 63279, 5760},\r
+{0, 63190, 5774},\r
+{0, 63219, 5760},\r
+{0, 63263, 5769},\r
+{0, 63351, 5765},\r
+{0, 63564, 5787},\r
+{0, 63277, 5774},\r
+{0, 62796, 5769},\r
+{0, 62506, 5764},\r
+{0, 62471, 5767},\r
+{0, 62562, 5770},\r
+{0, 62702, 5773},\r
+{0, 62732, 5769},\r
+{0, 62756, 5769},\r
+{0, 62713, 5764},\r
+{0, 62552, 5751},\r
+{0, 61826, 5756},\r
+{0, 61372, 5737},\r
+{0, 61237, 5751},\r
+{0, 61209, 5748},\r
+{0, 61388, 5754},\r
+{0, 61627, 5755},\r
+{0, 61730, 5766},\r
+{0, 61872, 5759},\r
+{0, 62014, 5754},\r
+{0, 61843, 5745},\r
+{0, 61188, 5759},\r
+{0, 60888, 5747},\r
+{0, 60594, 5760},\r
+{0, 60498, 5748},\r
+{0, 60528, 5757},\r
+{0, 60562, 5760},\r
+{0, 60561, 5753},\r
+{0, 60578, 5761},\r
+{0, 60557, 5750},\r
+{0, 59837, 5740},\r
+{0, 59182, 5725},\r
+{0, 58867, 5734},\r
+{0, 58708, 5732},\r
+{0, 58715, 5737},\r
+{0, 59117, 5744},\r
+{0, 59494, 5750},\r
+{0, 59745, 5759},\r
+{0, 60013, 5751},\r
+{0, 60076, 5742},\r
+{0, 59533, 5746},\r
+{0, 59173, 5744},\r
+{0, 59078, 5750},\r
+{0, 59113, 5750},\r
+{0, 59176, 5736},\r
+{0, 59239, 5744},\r
+{0, 59261, 5742},\r
+{0, 59241, 5745},\r
+{0, 59107, 5738},\r
+{0, 58684, 5723},\r
+{0, 58056, 5724},\r
+{0, 58010, 5735},\r
+{0, 58179, 5725},\r
+{0, 58548, 5737},\r
+{0, 59193, 5734},\r
+{0, 60022, 5738},\r
+{0, 61146, 5744},\r
+{0, 62468, 5761},\r
+{0, 63258, 5771},\r
+{0, 63210, 5769},\r
+{0, 63247, 5785},\r
+{0, 63493, 5783},\r
+{0, 63955, 5803},\r
+{0, 64734, 5807},\r
+{0, 65604, 5823},\r
+{0, 66555, 5835},\r
+{0, 67298, 5832},\r
+{0, 68032, 5844},\r
+{0, 68529, 5855},\r
+{0, 68500, 5848},\r
+{0, 68548, 5838},\r
+{0, 68630, 5840},\r
+{0, 68718, 5842},\r
+{0, 68746, 5839},\r
+{0, 68648, 5832},\r
+{0, 68411, 5830},\r
+{0, 68303, 5823},\r
+{0, 68230, 5824},\r
+{0, 67843, 5833},\r
+{0, 67282, 5807},\r
+{0, 67002, 5809},\r
+{0, 66832, 5822},\r
+{0, 66800, 5821},\r
+{0, 66781, 5823},\r
+{0, 66724, 5813},\r
+{0, 66764, 5822},\r
+{0, 66858, 5811},\r
+{0, 67014, 5811},\r
+{0, 66649, 5821},\r
+{0, 66162, 5810},\r
+{0, 65993, 5806},\r
+{0, 65948, 5800},\r
+{0, 66044, 5805},\r
+{0, 66143, 5811},\r
+{0, 66272, 5808},\r
+{0, 66337, 5807},\r
+{0, 66426, 5796},\r
+{0, 66364, 5809},\r
+{0, 65737, 5791},\r
+{0, 65333, 5797},\r
+{0, 65088, 5803},\r
+{0, 65079, 5785},\r
+{0, 65175, 5788},\r
+{0, 65235, 5798},\r
+{0, 65320, 5797},\r
+{0, 65371, 5797},\r
+{0, 65491, 5798},\r
+{0, 65058, 5780},\r
+{0, 64592, 5780},\r
+{0, 64366, 5793},\r
+{0, 64345, 5779},\r
+{0, 64479, 5778},\r
+{0, 64627, 5785},\r
+{0, 64727, 5778},\r
+{0, 64825, 5788},\r
+{0, 64874, 5782},\r
+{0, 64721, 5783},\r
+{0, 63950, 5786},\r
+{0, 63438, 5779},\r
+{0, 63242, 5777},\r
+{0, 63245, 5777},\r
+{0, 63368, 5781},\r
+{0, 63546, 5783},\r
+{0, 63663, 5789},\r
+{0, 63828, 5786},\r
+{0, 63995, 5789},\r
+{0, 63575, 5788},\r
+{0, 62933, 5784},\r
+{0, 62672, 5774},\r
+{0, 62758, 5769},\r
+{0, 62906, 5767},\r
+{0, 63141, 5777},\r
+{0, 63371, 5775},\r
+{0, 63553, 5780},\r
+{0, 63762, 5789},\r
+{0, 63802, 5792},\r
+{0, 62974, 5774},\r
+{0, 62377, 5777},\r
+{0, 62180, 5768},\r
+{0, 62152, 5770},\r
+{0, 62287, 5782},\r
+{0, 62424, 5782},\r
+{0, 62565, 5777},\r
+{0, 62763, 5785},\r
+{0, 62931, 5785},\r
+{0, 62525, 5779},\r
+{0, 61871, 5769},\r
+{0, 61663, 5767},\r
+{0, 61701, 5765},\r
+{0, 61877, 5774},\r
+{0, 62115, 5768},\r
+{0, 62270, 5775},\r
+{0, 62541, 5777},\r
+{0, 62833, 5772},\r
+{0, 62867, 5769},\r
+{0, 62178, 5770},\r
+{0, 61743, 5766},\r
+{0, 61632, 5765},\r
+{0, 61631, 5767},\r
+{0, 61840, 5772},\r
+{0, 61915, 5773},\r
+{0, 62116, 5774},\r
+{0, 62273, 5785},\r
+{0, 62462, 5782},\r
+{0, 62189, 5763},\r
+{0, 61577, 5771},\r
+{0, 61343, 5765},\r
+{0, 61373, 5776},\r
+{0, 61595, 5779},\r
+{0, 61835, 5772},\r
+{0, 62136, 5770},\r
+{0, 62389, 5774},\r
+{0, 62707, 5767},\r
+{0, 62890, 5778},\r
+{0, 62388, 5772},\r
+{0, 62031, 5768},\r
+{0, 61919, 5766},\r
+{0, 62038, 5766},\r
+{0, 62217, 5767},\r
+{0, 62342, 5770},\r
+{0, 62421, 5779},\r
+{0, 62534, 5775},\r
+{0, 62860, 5787},\r
+{0, 62865, 5785},\r
+{0, 62653, 5787},\r
+{0, 62773, 5770},\r
+{0, 63067, 5791},\r
+{0, 63408, 5789},\r
+{0, 63896, 5794},\r
+{0, 64195, 5796},\r
+{0, 64389, 5795},\r
+{0, 64516, 5796},\r
+{0, 64547, 5792},\r
+{0, 63648, 5790},\r
+{0, 62962, 5769},\r
+{0, 62591, 5780},\r
+{0, 62426, 5771},\r
+{0, 62464, 5774},\r
+{0, 62530, 5775},\r
+{0, 62655, 5774},\r
+{0, 62848, 5764},\r
+{0, 63071, 5762},\r
+{0, 62915, 5775},\r
+{0, 62279, 5765},\r
+{0, 62044, 5761},\r
+{0, 62044, 5760},\r
+{0, 62180, 5768},\r
+{0, 62331, 5767},\r
+{0, 62405, 5779},\r
+{0, 62539, 5781},\r
+{0, 62760, 5778},\r
+{0, 62957, 5778},\r
+{0, 62434, 5768},\r
+{0, 61954, 5766},\r
+{0, 61722, 5762},\r
+{0, 61691, 5765},\r
+{0, 61757, 5767},\r
+{0, 61894, 5758},\r
+{0, 62029, 5770},\r
+{0, 62164, 5769},\r
+{0, 62290, 5776},\r
+{0, 62143, 5773},\r
+{0, 61442, 5766},\r
+{0, 61082, 5754},\r
+{0, 61039, 5755},\r
+{0, 61151, 5761},\r
+{0, 61337, 5762},\r
+{0, 61538, 5760},\r
+{0, 61818, 5772},\r
+{0, 62053, 5768},\r
+{0, 62239, 5763},\r
+{0, 61566, 5760},\r
+{0, 60885, 5753},\r
+{0, 60757, 5757},\r
+{0, 60844, 5753},\r
+{0, 61042, 5757},\r
+{0, 61332, 5756},\r
+{0, 61622, 5756},\r
+{0, 61812, 5770},\r
+{0, 61931, 5763},\r
+{0, 61776, 5761},\r
+{0, 61115, 5756},\r
+{0, 60638, 5749},\r
+{0, 60487, 5749},\r
+{0, 60707, 5761},\r
+{0, 60958, 5741},\r
+{0, 61158, 5756},\r
+{0, 61232, 5749},\r
+{0, 61287, 5747},\r
+{0, 61422, 5757},\r
+{0, 60814, 5744},\r
+{0, 60165, 5735},\r
+{0, 59844, 5727},\r
+{0, 59797, 5725},\r
+{0, 59908, 5732},\r
+{0, 59991, 5739},\r
+{0, 59970, 5736},\r
+{0, 60230, 5727},\r
+{0, 60650, 5722},\r
+{0, 60913, 5729},\r
+{0, 60711, 5720},\r
+{0, 60289, 5718},\r
+{0, 59960, 5734},\r
+{0, 59757, 5715},\r
+{0, 59668, 5722},\r
+{0, 59582, 5723},\r
+{0, 59557, 5726},\r
+{0, 59620, 5734},\r
+{0, 59743, 5732},\r
+{0, 59203, 5731},\r
+{0, 58719, 5717},\r
+{0, 58536, 5716},\r
+{0, 58412, 5724},\r
+{0, 58451, 5723},\r
+{0, 58468, 5720},\r
+{0, 58452, 5733},\r
+{0, 58319, 5726},\r
+{0, 58223, 5732},\r
+{0, 58068, 5725},\r
+{0, 57694, 5717},\r
+{0, 57391, 5719},\r
+{0, 57123, 5707},\r
+{0, 57030, 5715},\r
+{0, 56991, 5721},\r
+{0, 57046, 5732},\r
+{0, 57170, 5730},\r
+{0, 57315, 5726},\r
+{0, 57433, 5728},\r
+{0, 57085, 5717},\r
+{0, 56826, 5730},\r
+{0, 56789, 5732},\r
+{0, 56786, 5714},\r
+{0, 56961, 5734},\r
+{0, 57075, 5743},\r
+{0, 57095, 5732},\r
+{0, 57127, 5726},\r
+{0, 57015, 5728},\r
+{0, 56576, 5730},\r
+{0, 55986, 5730},\r
+{0, 55667, 5724},\r
+{0, 55510, 5734},\r
+{0, 55469, 5732},\r
+{0, 55538, 5731},\r
+{0, 55559, 5733},\r
+{0, 55658, 5733},\r
+{0, 55836, 5742},\r
+{0, 56030, 5735},\r
+{0, 55839, 5739},\r
+{0, 55578, 5724},\r
+{0, 55592, 5732},\r
+{0, 55720, 5734},\r
+{0, 55944, 5735},\r
+{0, 56176, 5745},\r
+{0, 56352, 5748},\r
+{0, 56539, 5737},\r
+{0, 56714, 5750},\r
+{0, 56522, 5728},\r
+{0, 56097, 5738},\r
+{0, 55919, 5735},\r
+{0, 55870, 5735},\r
+{0, 55922, 5740},\r
+{0, 56056, 5751},\r
+{0, 56190, 5758},\r
+{0, 56245, 5751},\r
+{0, 56441, 5750},\r
+{0, 56457, 5745},\r
+{0, 56152, 5742},\r
+{0, 55996, 5746},\r
+{0, 56028, 5738},\r
+{0, 56175, 5745},\r
+{0, 56364, 5746},\r
+{0, 56600, 5746},\r
+{0, 56790, 5741},\r
+{0, 57027, 5749},\r
+{0, 57145, 5758},\r
+{0, 56925, 5744},\r
+{0, 56706, 5738},\r
+{0, 56700, 5745},\r
+{0, 56700, 5735},\r
+{0, 56770, 5746},\r
+{0, 56851, 5742},\r
+{0, 56970, 5743},\r
+{0, 57079, 5742},\r
+{0, 57204, 5748},\r
+{0, 57197, 5756},\r
+{0, 56916, 5738},\r
+{0, 56684, 5732},\r
+{0, 56706, 5730},\r
+{0, 56826, 5735},\r
+{0, 57092, 5732},\r
+{0, 57270, 5748},\r
+{0, 57462, 5739},\r
+{0, 57681, 5743},\r
+{0, 57812, 5743},\r
+{0, 57435, 5732},\r
+{0, 57147, 5740},\r
+{0, 57097, 5731},\r
+{0, 57157, 5734},\r
+{0, 57390, 5735},\r
+{0, 57618, 5750},\r
+{0, 57691, 5749},\r
+{0, 57788, 5748},\r
+{0, 57849, 5754},\r
+{0, 57736, 5756},\r
+{0, 57358, 5752},\r
+{0, 57049, 5732},\r
+{0, 56992, 5749},\r
+{0, 57064, 5739},\r
+{0, 57221, 5745},\r
+{0, 57493, 5737},\r
+{0, 57816, 5739},\r
+{0, 57955, 5753},\r
+{0, 57976, 5752},\r
+{0, 57485, 5749},\r
+{0, 57193, 5732},\r
+{0, 57121, 5742},\r
+{0, 56931, 5745},\r
+{0, 56800, 5743},\r
+{0, 56758, 5740},\r
+{0, 56842, 5736},\r
+{0, 56831, 5736},\r
+{0, 56778, 5749},\r
+{0, 56617, 5737},\r
+{0, 56046, 5736},\r
+{0, 55890, 5734},\r
+{0, 56052, 5730},\r
+{0, 56415, 5740},\r
+{0, 56673, 5735},\r
+{0, 56920, 5747},\r
+{0, 57196, 5743},\r
+{0, 57563, 5739},\r
+{0, 57915, 5749},\r
+{0, 57932, 5749},\r
+{0, 57920, 5732},\r
+{0, 57985, 5747},\r
+{0, 58101, 5759},\r
+{0, 58398, 5756},\r
+{0, 58657, 5749},\r
+{0, 59000, 5760},\r
+{0, 59327, 5760},\r
+{0, 59683, 5764},\r
+{0, 59682, 5757},\r
+{0, 59383, 5768},\r
+{0, 59284, 5749},\r
+{0, 59326, 5754},\r
+{0, 59510, 5762},\r
+{0, 59662, 5765},\r
+{0, 59903, 5764},\r
+{0, 60130, 5764},\r
+{0, 60352, 5753},\r
+{0, 60435, 5782},\r
+{0, 60048, 5753},\r
+{0, 59756, 5758},\r
+{0, 59621, 5756},\r
+{0, 59580, 5752},\r
+{0, 59641, 5761},\r
+{0, 59830, 5760},\r
+{0, 59982, 5766},\r
+{0, 60149, 5766},\r
+{0, 60287, 5766},\r
+{0, 60185, 5761},\r
+{0, 59823, 5761},\r
+{0, 59783, 5752},\r
+{0, 59734, 5753},\r
+{0, 59608, 5752},\r
+{0, 59343, 5744},\r
+{0, 59035, 5766},\r
+{0, 58994, 5754},\r
+{0, 59095, 5757},\r
+{0, 58951, 5751},\r
+{0, 58311, 5753},\r
+{0, 57810, 5751},\r
+{0, 57513, 5739},\r
+{0, 57431, 5744},\r
+{0, 57433, 5757},\r
+{0, 57538, 5760},\r
+{0, 57600, 5756},\r
+{0, 57706, 5760},\r
+{0, 57906, 5766},\r
+{0, 57933, 5761},\r
+{0, 57692, 5753},\r
+{0, 57595, 5759},\r
+{0, 57634, 5749},\r
+{0, 57804, 5753},\r
+{0, 57975, 5766},\r
+{0, 58127, 5756},\r
+{0, 58261, 5764},\r
+{0, 58500, 5764},\r
+{0, 58681, 5764},\r
+{0, 58418, 5741},\r
+{0, 58108, 5760},\r
+{0, 57945, 5755},\r
+{0, 57934, 5753},\r
+{0, 58145, 5755},\r
+{0, 58416, 5773},\r
+{0, 58614, 5759},\r
+{0, 58815, 5765},\r
+{0, 58994, 5764},\r
+{0, 58933, 5762},\r
+{0, 58552, 5761},\r
+{0, 58483, 5755},\r
+{0, 58520, 5769},\r
+{0, 58665, 5753},\r
+{0, 58897, 5752},\r
+{0, 59088, 5760},\r
+{0, 59329, 5766},\r
+{0, 59615, 5761},\r
+{0, 59787, 5763},\r
+{0, 59506, 5768},\r
+{0, 59280, 5761},\r
+{0, 59177, 5762},\r
+{0, 59261, 5756},\r
+{0, 59249, 5760},\r
+{0, 59316, 5765},\r
+{0, 59307, 5767},\r
+{0, 59357, 5772},\r
+{0, 59403, 5771},\r
+{0, 59406, 5764},\r
+{0, 59254, 5754},\r
+{0, 59190, 5761},\r
+{0, 59291, 5763},\r
+{0, 59545, 5762},\r
+{0, 59840, 5762},\r
+{0, 60165, 5765},\r
+{0, 60390, 5763},\r
+{0, 60620, 5769},\r
+{0, 60771, 5775},\r
+{0, 60512, 5761},\r
+{0, 60360, 5761},\r
+{0, 60213, 5770},\r
+{0, 60156, 5766},\r
+{0, 60120, 5765},\r
+{0, 60130, 5784},\r
+{0, 60283, 5778},\r
+{0, 60401, 5769},\r
+{0, 60492, 5776},\r
+{0, 60330, 5764},\r
+{0, 60068, 5763},\r
+{0, 59978, 5767},\r
+{0, 59953, 5759},\r
+{0, 60063, 5773},\r
+{0, 60169, 5752},\r
+{0, 60333, 5762},\r
+{0, 60513, 5755},\r
+{0, 60772, 5757},\r
+{0, 60695, 5764},\r
+{0, 60163, 5752},\r
+{0, 59778, 5756},\r
+{0, 59684, 5753},\r
+{0, 59685, 5753},\r
+{0, 59651, 5761},\r
+{0, 59614, 5756},\r
+{0, 59552, 5757},\r
+{0, 59510, 5753},\r
+{0, 59595, 5755},\r
+{0, 59255, 5753},\r
+{0, 58770, 5759},\r
+{0, 58577, 5757},\r
+{0, 58560, 5755},\r
+{0, 58583, 5753},\r
+{0, 58583, 5752},\r
+{0, 58582, 5750},\r
+{0, 58583, 5757},\r
+{0, 58737, 5757},\r
+{0, 58552, 5744},\r
+{0, 58014, 5751},\r
+{0, 57624, 5744},\r
+{0, 57584, 5737},\r
+{0, 57686, 5745},\r
+{0, 57722, 5751},\r
+{0, 57675, 5747},\r
+{0, 57624, 5748},\r
+{0, 57671, 5756},\r
+{0, 57748, 5740},\r
+{0, 57307, 5740},\r
+{0, 56921, 5737},\r
+{0, 56786, 5749},\r
+{0, 56851, 5745},\r
+{0, 57043, 5747},\r
+{0, 57191, 5747},\r
+{0, 57347, 5734},\r
+{0, 57539, 5741},\r
+{0, 57752, 5738},\r
+{0, 57509, 5721},\r
+{0, 57133, 5731},\r
+{0, 56986, 5728},\r
+{0, 56996, 5738},\r
+{0, 57230, 5743},\r
+{0, 57410, 5739},\r
+{0, 57515, 5739},\r
+{0, 57627, 5743},\r
+{0, 57699, 5740},\r
+{0, 57510, 5735},\r
+{0, 57097, 5742},\r
+{0, 56980, 5734},\r
+{0, 56984, 5725},\r
+{0, 57093, 5748},\r
+{0, 57203, 5733},\r
+{0, 57436, 5742},\r
+{0, 57640, 5750},\r
+{0, 57861, 5746},\r
+{0, 57906, 5730},\r
+{0, 57431, 5722},\r
+{0, 57308, 5725},\r
+{0, 57289, 5729},\r
+{0, 57486, 5730},\r
+{0, 57666, 5740},\r
+{0, 57832, 5742},\r
+{0, 58065, 5735},\r
+{0, 58216, 5731},\r
+{0, 58216, 5734},\r
+{0, 57671, 5735},\r
+{0, 57250, 5733},\r
+{0, 57038, 5727},\r
+{0, 57094, 5731},\r
+{0, 57244, 5733},\r
+{0, 57376, 5728},\r
+{0, 57454, 5735},\r
+{0, 57602, 5727},\r
+{0, 57737, 5719},\r
+{0, 57455, 5718},\r
+{0, 57109, 5721},\r
+{0, 57022, 5720},\r
+{0, 57099, 5732},\r
+{0, 57309, 5724},\r
+{0, 57564, 5732},\r
+{0, 57830, 5735},\r
+{0, 57975, 5728},\r
+{0, 58161, 5740},\r
+{0, 58118, 5737},\r
+{0, 57710, 5719},\r
+{0, 57527, 5728},\r
+{0, 57501, 5724},\r
+{0, 57592, 5722},\r
+{0, 57661, 5727},\r
+{0, 57671, 5732},\r
+{0, 57641, 5741},\r
+{0, 57605, 5734},\r
+{0, 57559, 5734},\r
+{0, 57396, 5723},\r
+{0, 57569, 5738},\r
+{0, 58093, 5756},\r
+{0, 58718, 5779},\r
+{0, 59324, 5776},\r
+{0, 59817, 5780},\r
+{0, 60291, 5792},\r
+{0, 60676, 5785},\r
+{0, 60910, 5786},\r
+{0, 60723, 5785},\r
+{0, 60731, 5783},\r
+{0, 60825, 5783},\r
+{0, 60989, 5788},\r
+{0, 61151, 5780},\r
+{0, 61360, 5794},\r
+{0, 61532, 5795},\r
+{0, 61786, 5794},\r
+{0, 61971, 5790},\r
+{0, 61843, 5791},\r
+{0, 61696, 5798},\r
+{0, 61734, 5793},\r
+{0, 61824, 5790},\r
+{0, 61995, 5783},\r
+{0, 62082, 5795},\r
+{0, 62183, 5798},\r
+{0, 62341, 5794},\r
+{0, 62467, 5798},\r
+{0, 62186, 5797},\r
+{0, 61929, 5794},\r
+{0, 61792, 5793},\r
+{0, 61775, 5788},\r
+{0, 61872, 5790},\r
+{0, 61929, 5782},\r
+{0, 61920, 5787},\r
+{0, 61914, 5790},\r
+{0, 61872, 5778},\r
+{0, 61670, 5778},\r
+{0, 61182, 5774},\r
+{0, 60971, 5761},\r
+{0, 60887, 5776},\r
+{0, 60914, 5772},\r
+{0, 61053, 5777},\r
+{0, 61298, 5777},\r
+{0, 61471, 5766},\r
+{0, 61733, 5766},\r
+{0, 61731, 5761},\r
+{0, 61416, 5763},\r
+{0, 61276, 5766},\r
+{0, 60872, 5759},\r
+{0, 60318, 5765},\r
+{0, 59821, 5768},\r
+{0, 59663, 5762},\r
+{0, 59724, 5768},\r
+{0, 59571, 5774},\r
+{0, 59225, 5767},\r
+{0, 58531, 5752},\r
+{0, 58153, 5761},\r
+{0, 58064, 5755},\r
+{0, 58052, 5752},\r
+{0, 58131, 5769},\r
+{0, 58161, 5762},\r
+{0, 58336, 5765},\r
+{0, 58513, 5767},\r
+{0, 58586, 5757},\r
+{0, 58015, 5762},\r
+{0, 57681, 5744},\r
+{0, 57555, 5753},\r
+{0, 57602, 5755},\r
+{0, 57802, 5748},\r
+{0, 57908, 5763},\r
+{0, 58042, 5768},\r
+{0, 58226, 5754},\r
+{0, 58298, 5745},\r
+{0, 57702, 5743},\r
+{0, 57215, 5751},\r
+{0, 57052, 5760},\r
+{0, 56961, 5749},\r
+{0, 57115, 5746},\r
+{0, 57342, 5768},\r
+{0, 57435, 5762},\r
+{0, 57506, 5762},\r
+{0, 57588, 5764},\r
+{0, 57205, 5760},\r
+{0, 56804, 5761},\r
+{0, 56664, 5745},\r
+{0, 56707, 5753},\r
+{0, 56811, 5762},\r
+{0, 56943, 5762},\r
+{0, 57149, 5754},\r
+{0, 57383, 5758},\r
+{0, 57559, 5767},\r
+{0, 57256, 5752},\r
+{0, 56872, 5742},\r
+{0, 56762, 5746},\r
+{0, 56790, 5745},\r
+{0, 56834, 5749},\r
+{0, 57029, 5737},\r
+{0, 57260, 5736},\r
+{0, 57682, 5739},\r
+{0, 58314, 5754},\r
+{0, 58656, 5770},\r
+{0, 58643, 5764},\r
+{0, 58539, 5761},\r
+{0, 58542, 5768},\r
+{0, 58596, 5765},\r
+{0, 58691, 5765},\r
+{0, 58731, 5774},\r
+{0, 58934, 5772},\r
+{0, 59123, 5761},\r
+{0, 59054, 5768},\r
+{0, 58660, 5759},\r
+{0, 58449, 5757},\r
+{0, 58359, 5759},\r
+{0, 58418, 5751},\r
+{0, 58399, 5759},\r
+{0, 58423, 5759},\r
+{0, 58394, 5764},\r
+{0, 58424, 5756},\r
+{0, 58387, 5754},\r
+{0, 58087, 5749},\r
+{0, 57859, 5749},\r
+{0, 57822, 5747},\r
+{0, 57919, 5751},\r
+{0, 58108, 5753},\r
+{0, 58344, 5748},\r
+{0, 58588, 5747},\r
+{0, 58813, 5756},\r
+{0, 58906, 5751},\r
+{0, 58689, 5746},\r
+{0, 58544, 5744},\r
+{0, 58565, 5745},\r
+{0, 58666, 5745},\r
+{0, 58771, 5744},\r
+{0, 58778, 5738},\r
+{0, 58750, 5758},\r
+{0, 58706, 5738},\r
+{0, 58619, 5747},\r
+{0, 58347, 5752},\r
+{0, 58253, 5750},\r
+{0, 58209, 5737},\r
+{0, 58327, 5749},\r
+{0, 58465, 5747},\r
+{0, 58677, 5773},\r
+{0, 58822, 5754},\r
+{0, 58988, 5770},\r
+{0, 59120, 5763},\r
+{0, 58836, 5753},\r
+{0, 58669, 5756},\r
+{0, 58673, 5750},\r
+{0, 58754, 5765},\r
+{0, 58889, 5752},\r
+{0, 59021, 5757},\r
+{0, 59062, 5777},\r
+{0, 59104, 5766},\r
+{0, 59146, 5760},\r
+{0, 58839, 5765},\r
+{0, 58500, 5767},\r
+{0, 58373, 5749},\r
+{0, 58279, 5756},\r
+{0, 58422, 5762},\r
+{0, 58559, 5765},\r
+{0, 58758, 5764},\r
+{0, 58937, 5768},\r
+{0, 59153, 5770},\r
+{0, 58995, 5766},\r
+{0, 58621, 5757},\r
+{0, 58507, 5756},\r
+{0, 58526, 5759},\r
+{0, 58618, 5752},\r
+{0, 58798, 5757},\r
+{0, 58994, 5757},\r
+{0, 59106, 5759},\r
+{0, 59158, 5761},\r
+{0, 58934, 5764},\r
+{0, 58364, 5763},\r
+{0, 58120, 5759},\r
+{0, 58090, 5757},\r
+{0, 58150, 5760},\r
+{0, 58238, 5758},\r
+{0, 58464, 5767},\r
+{0, 58693, 5760},\r
+{0, 58911, 5771},\r
+{0, 59013, 5762},\r
+{0, 58653, 5762},\r
+{0, 58510, 5743},\r
+{0, 58587, 5754},\r
+{0, 58661, 5758},\r
+{0, 58808, 5754},\r
+{0, 58986, 5763},\r
+{0, 59128, 5760},\r
+{0, 59136, 5765},\r
+{0, 59133, 5764},\r
+{0, 58746, 5762},\r
+{0, 58407, 5751},\r
+{0, 58295, 5754},\r
+{0, 58307, 5751},\r
+{0, 58368, 5763},\r
+{0, 58517, 5758},\r
+{0, 58731, 5752},\r
+{0, 58854, 5756},\r
+{0, 59067, 5765},\r
+{0, 58864, 5749},\r
+{0, 58655, 5752},\r
+{0, 58601, 5741},\r
+{0, 58679, 5745},\r
+{0, 58786, 5756},\r
+{0, 58916, 5763},\r
+{0, 58981, 5758},\r
+{0, 58914, 5763},\r
+{0, 58891, 5759},\r
+{0, 58888, 5764},\r
+{0, 58676, 5747},\r
+{0, 58834, 5759},\r
+{0, 59073, 5776},\r
+{0, 59332, 5767},\r
+{0, 59562, 5773},\r
+{0, 59824, 5773},\r
+{0, 60261, 5768},\r
+{0, 60683, 5770},\r
+{0, 61001, 5771},\r
+};\r
+static const int16_t PAH8009_mems_HRD[][3*NF_PPG_PER_CHANNEL] = \r
+{\r
+{6305, -1007, 8865},\r
+{5777, -95, 9889},\r
+{6385, 1137, 8897},\r
+{4401, 833, 5425},\r
+{4465, -1647, 3153},\r
+{19985, 3937, 1713},\r
+{-2447, -3775, 8273},\r
+{5009, 4017, 12657},\r
+{6769, 1329, 6033},\r
+{5025, -1567, 6145},\r
+{6225, 1025, 5889},\r
+{5681, -351, 5057},\r
+{5905, 113, 5745},\r
+{5793, -31, 6369},\r
+{5297, 193, 5857},\r
+{5121, 657, 6321},\r
+{5121, 1041, 5937},\r
+{5873, 17, 6753},\r
+{6577, -1583, 6065},\r
+{5825, -63, 6385},\r
+{5601, 33, 4961},\r
+{6097, -303, 4785},\r
+{6001, 433, 5697},\r
+{6001, 929, 5553},\r
+{6145, 561, 5201},\r
+{6353, 1009, 5009},\r
+{6481, 1697, 5153},\r
+{6049, 1633, 5441},\r
+{6033, 1361, 5697},\r
+{6113, 1313, 5681},\r
+{6161, 1697, 5409},\r
+{6145, 1345, 5537},\r
+{6081, 1889, 5505},\r
+{5985, 1425, 5409},\r
+{5985, 1809, 5505},\r
+{5953, 1729, 5553},\r
+{5953, 1569, 5681},\r
+{5889, 1649, 5489},\r
+{6065, 1409, 5713},\r
+{6017, 1761, 5457},\r
+{6001, 1953, 5521},\r
+{5985, 2065, 5617},\r
+{5777, 1793, 5633},\r
+{5633, 1601, 5745},\r
+{5809, 1601, 5857},\r
+{5809, 1633, 5665},\r
+{5713, 1761, 5633},\r
+{5841, 1697, 5777},\r
+{5745, 1713, 5617},\r
+{5825, 1713, 5793},\r
+{5905, 1633, 5713},\r
+{5841, 1601, 5681},\r
+{5921, 1761, 5649},\r
+{5889, 1649, 5553},\r
+{5985, 1649, 5569},\r
+{5825, 1857, 5937},\r
+{5809, 1585, 5601},\r
+{6017, 1569, 5441},\r
+{5601, 1377, 5697},\r
+{5841, 1265, 5825},\r
+{6049, 1857, 6145},\r
+{5889, 1585, 4977},\r
+{6609, 1185, 5521},\r
+{6161, 1697, 5441},\r
+{6065, 1633, 5489},\r
+{6193, 1633, 5505},\r
+{6225, 1569, 5441},\r
+{6129, 1521, 5329},\r
+{6129, 1569, 5409},\r
+{6081, 1473, 5345},\r
+{5857, 1377, 5537},\r
+{5905, 1153, 5665},\r
+{6113, 1217, 5441},\r
+{6209, 1441, 5409},\r
+{6145, 1121, 5505},\r
+{6097, 1121, 5585},\r
+{6177, 1089, 5473},\r
+{6193, 1281, 5345},\r
+{6225, 1265, 5457},\r
+{5985, 1249, 5361},\r
+{6209, 1425, 5761},\r
+{6049, 1057, 5585},\r
+{5969, 1009, 5793},\r
+{6017, 1153, 5649},\r
+{6065, 1377, 5569},\r
+{6001, 1345, 5617},\r
+{6033, 1345, 5457},\r
+{6241, 1473, 5457},\r
+{6097, 1425, 5473},\r
+{6161, 1521, 5441},\r
+{6129, 1569, 5441},\r
+{6097, 1537, 5441},\r
+{6065, 1505, 5425},\r
+{6177, 1681, 5441},\r
+{6113, 1745, 5505},\r
+{6337, 1505, 5233},\r
+{6129, 1649, 5393},\r
+{6225, 1617, 5361},\r
+{6177, 1553, 5329},\r
+{6305, 1569, 5201},\r
+{6209, 1633, 5265},\r
+{6401, 1745, 5233},\r
+{6225, 1569, 5281},\r
+{6385, 1585, 5217},\r
+{6321, 1665, 5217},\r
+{6289, 1521, 5121},\r
+{6321, 1761, 5249},\r
+{6289, 1569, 5201},\r
+{6273, 1601, 5217},\r
+{6273, 1649, 5233},\r
+{6321, 1649, 5313},\r
+{6321, 1601, 5249},\r
+{6321, 1569, 5249},\r
+{6273, 1569, 5297},\r
+{6161, 1441, 5249},\r
+{6257, 1537, 5329},\r
+{6225, 1425, 5313},\r
+{6289, 1697, 5425},\r
+{6257, 1281, 5153},\r
+{6305, 1281, 5249},\r
+{6337, 1393, 5393},\r
+{6321, 1201, 5313},\r
+{6369, 1425, 5361},\r
+{6257, 1537, 5201},\r
+{6385, 1473, 5137},\r
+{6433, 1569, 5137},\r
+{6369, 1745, 4977},\r
+{6417, 1585, 5153},\r
+{6289, 1585, 5105},\r
+{6289, 1585, 5185},\r
+{6321, 1649, 5185},\r
+{6241, 1569, 5329},\r
+{6337, 1713, 5313},\r
+{6209, 1537, 5281},\r
+{6369, 1569, 5265},\r
+{6049, 1713, 5265},\r
+{6241, 1649, 5489},\r
+{6353, 1409, 5169},\r
+{6177, 1409, 5041},\r
+{6369, 1505, 5377},\r
+{6273, 1521, 5393},\r
+{6289, 1553, 5329},\r
+{6289, 1633, 5185},\r
+{6273, 1617, 5217},\r
+{6257, 1761, 5089},\r
+{6337, 1777, 5201},\r
+{6209, 1617, 5297},\r
+{6257, 1729, 5185},\r
+{6401, 1841, 5121},\r
+{6353, 1745, 5169},\r
+{6273, 1601, 5137},\r
+{6369, 1793, 5153},\r
+{6337, 1713, 5153},\r
+{6369, 1713, 5201},\r
+{6385, 1665, 5217},\r
+{6241, 2017, 5025},\r
+{6369, 1761, 5025},\r
+{6337, 1697, 5105},\r
+{6369, 1761, 5137},\r
+{6401, 1809, 5057},\r
+{6353, 1793, 5089},\r
+{6417, 1841, 5073},\r
+{6385, 1873, 5041},\r
+{6385, 1809, 5073},\r
+{6417, 1905, 5089},\r
+{6353, 1841, 5057},\r
+{6353, 1873, 5073},\r
+{6337, 1873, 5073},\r
+{6353, 1889, 5025},\r
+{6385, 1857, 5153},\r
+{6305, 1873, 5121},\r
+{6337, 1857, 5089},\r
+{6289, 1889, 4961},\r
+{6241, 1825, 4769},\r
+{6225, 1841, 4737},\r
+{6305, 1921, 4977},\r
+{6353, 2177, 4561},\r
+{6161, 1697, 4225},\r
+{6401, 3089, 6225},\r
+{6321, 2769, 5537},\r
+{6177, 2449, 5153},\r
+{6177, 2545, 5057},\r
+{6145, 2545, 5153},\r
+{6177, 2561, 5025},\r
+{6161, 2561, 5073},\r
+{6145, 2513, 5057},\r
+{6161, 2385, 5025},\r
+{6161, 2657, 5121},\r
+{6161, 2753, 4897},\r
+{6145, 2689, 4913},\r
+{6145, 2753, 4977},\r
+{6145, 2801, 5009},\r
+{6161, 2673, 5073},\r
+{6129, 2657, 5025},\r
+{6145, 2705, 5041},\r
+{6145, 2625, 5041},\r
+{6129, 2577, 5089},\r
+{6113, 2625, 5073},\r
+{6081, 2641, 5041},\r
+{6081, 2593, 5105},\r
+{6161, 2689, 5233},\r
+{6033, 2449, 5121},\r
+{6081, 2497, 5137},\r
+{6097, 2577, 5233},\r
+{6097, 2465, 5169},\r
+{6113, 2481, 5153},\r
+{6097, 2561, 5121},\r
+{6081, 2513, 5105},\r
+{6113, 2561, 5153},\r
+{6129, 2545, 5105},\r
+{6129, 2529, 5089},\r
+{6097, 2497, 5169},\r
+{6113, 2513, 5185},\r
+{6097, 2401, 5169},\r
+{6193, 2529, 5217},\r
+{6161, 2801, 5153},\r
+{6113, 2737, 5009},\r
+{6129, 2577, 4961},\r
+{6081, 2561, 5217},\r
+{6049, 2449, 5057},\r
+{6049, 2321, 5169},\r
+{6097, 2497, 5249},\r
+{6065, 2449, 5313},\r
+{6017, 2513, 5185},\r
+{6049, 2529, 5201},\r
+{6097, 2481, 5201},\r
+{6065, 2369, 5297},\r
+{6001, 2401, 5233},\r
+{6017, 2417, 5313},\r
+{6033, 2385, 5281},\r
+{5985, 2337, 5217},\r
+{5969, 2385, 5329},\r
+{6049, 2337, 5457},\r
+{6081, 2577, 5329},\r
+{5969, 2481, 5249},\r
+{5953, 2257, 5409},\r
+{5953, 2353, 5521},\r
+{5873, 2289, 5393},\r
+{5473, 3185, 5297},\r
+{6081, 2817, 3889},\r
+{6161, 3313, 5569},\r
+{5745, 2769, 5249},\r
+{6449, 2849, 4913},\r
+{5857, 2593, 5009},\r
+{5953, 2481, 5233},\r
+{6273, 2369, 4817},\r
+{6353, 2609, 4929},\r
+{6209, 2385, 4849},\r
+{6337, 2177, 5073},\r
+{6225, 2129, 5041},\r
+{6353, 2033, 5057},\r
+{6321, 2193, 4945},\r
+{6417, 2017, 5057},\r
+{6321, 2001, 4993},\r
+{6417, 2017, 4833},\r
+{6385, 1969, 4961},\r
+{6353, 1953, 4961},\r
+{6321, 2049, 5025},\r
+{6401, 2209, 4945},\r
+{6449, 2049, 5041},\r
+{6465, 2161, 4961},\r
+{6337, 2113, 5009},\r
+{6417, 2225, 4897},\r
+{6481, 2305, 4961},\r
+{6465, 2049, 4673},\r
+{6225, 2897, 5377},\r
+{6193, 2657, 5537},\r
+{6449, 2385, 4673},\r
+{6353, 2273, 4753},\r
+{6273, 2369, 4529},\r
+{6369, 3169, 6049},\r
+{6337, 2753, 5361},\r
+{6113, 2417, 5009},\r
+{6273, 2257, 5009},\r
+{6225, 2433, 4897},\r
+{6225, 2129, 5153},\r
+{6257, 2641, 5137},\r
+{6001, 2353, 5281},\r
+{6193, 2241, 4849},\r
+{6305, 2481, 5617},\r
+{6529, 2817, 5809},\r
+{6337, 3473, 5441},\r
+{6129, 1345, 3569},\r
+{6049, 1585, 3985},\r
+{6241, 1633, 4177},\r
+{6225, 2081, 5009},\r
+{6273, 1985, 4977},\r
+{6145, 1969, 5265},\r
+{6289, 1713, 4577},\r
+{6401, 1649, 4769},\r
+{6273, 1505, 4993},\r
+{6305, 1553, 5521},\r
+{6145, 1617, 5393},\r
+{6193, 1505, 5185},\r
+{6305, 1761, 5313},\r
+{6081, 1569, 5425},\r
+{6177, 1537, 5297},\r
+{6209, 1473, 5441},\r
+{6257, 1569, 5441},\r
+{6177, 1409, 5297},\r
+{6241, 1473, 5185},\r
+{6177, 1601, 4913},\r
+{6177, 1553, 5137},\r
+{6257, 1361, 5633},\r
+{6193, 1729, 5617},\r
+{6193, 1425, 5409},\r
+{6241, 1569, 5329},\r
+{6193, 1665, 5217},\r
+{6289, 1489, 5201},\r
+{6257, 1521, 5297},\r
+{6225, 1553, 5297},\r
+{6113, 1713, 5249},\r
+{6209, 1713, 5281},\r
+{6225, 1697, 5329},\r
+{6209, 1745, 5217},\r
+{6241, 1697, 5233},\r
+{6193, 1697, 5233},\r
+{6193, 1809, 5297},\r
+{6273, 1825, 5217},\r
+{6241, 1841, 5233},\r
+{6241, 1697, 5265},\r
+{6225, 1905, 5233},\r
+{6209, 1793, 5265},\r
+{6193, 1873, 5233},\r
+{6257, 1873, 5265},\r
+{6209, 1825, 5249},\r
+{6257, 1809, 5233},\r
+{6209, 1793, 5185},\r
+{6241, 1825, 5217},\r
+{6193, 1857, 5297},\r
+{6225, 1729, 5329},\r
+{6097, 1633, 5361},\r
+{6161, 1841, 5377},\r
+{6129, 1841, 5377},\r
+{6129, 1841, 5345},\r
+{6113, 1713, 5393},\r
+{6129, 1681, 5393},\r
+{6113, 1697, 5425},\r
+{6129, 1649, 5409},\r
+{6081, 1601, 5457},\r
+{6113, 1713, 5425},\r
+{6097, 1713, 5505},\r
+{6113, 1601, 5441},\r
+{6081, 1649, 5409},\r
+{6081, 1617, 5521},\r
+{6017, 1649, 5473},\r
+{6065, 1601, 5441},\r
+{6081, 1585, 5441},\r
+{6113, 1713, 5473},\r
+{6097, 1793, 5441},\r
+{6081, 1713, 5425},\r
+{6081, 1745, 5457},\r
+{6097, 1665, 5441},\r
+{6113, 1697, 5441},\r
+{6097, 1729, 5425},\r
+{6081, 1713, 5441},\r
+{6097, 1697, 5425},\r
+{6113, 1697, 5425},\r
+{6113, 1745, 5409},\r
+{6081, 1745, 5473},\r
+{6049, 1713, 5377},\r
+{6097, 1681, 5409},\r
+{6081, 1873, 5409},\r
+{6097, 1809, 5377},\r
+{6145, 1777, 5489},\r
+{6193, 1761, 5281},\r
+{6113, 1489, 5281},\r
+{6209, 1521, 5393},\r
+{6129, 1793, 5265},\r
+{6145, 1937, 5377},\r
+{6225, 1905, 5361},\r
+{6145, 1713, 5473},\r
+{6145, 1473, 5489},\r
+{5873, 1793, 5473},\r
+{5985, 1729, 5553},\r
+{6017, 1473, 5457},\r
+{6033, 1697, 5665},\r
+{6033, 1873, 5953},\r
+{6065, 1713, 5425},\r
+{5985, 1425, 5489},\r
+{5889, 1329, 5537},\r
+{5953, 1233, 5489},\r
+{6033, 1233, 5601},\r
+{5729, 849, 5761},\r
+{5681, 705, 5969},\r
+{5761, 833, 6161},\r
+{5729, 689, 6017},\r
+{5841, 705, 5953},\r
+{5713, 305, 5953},\r
+{5537, 481, 6001},\r
+{5665, 545, 6145},\r
+{5601, 465, 6081},\r
+{5601, 417, 6049},\r
+{5681, 449, 6081},\r
+{5633, 305, 6209},\r
+{5617, 529, 6049},\r
+{5633, 513, 6001},\r
+{5745, 481, 5969},\r
+{5697, 561, 5937},\r
+{5745, 641, 5985},\r
+{5921, 929, 5793},\r
+{5857, 737, 5681},\r
+{5985, 913, 5681},\r
+{6001, 961, 5633},\r
+{6097, 1473, 5393},\r
+{6033, 1217, 5489},\r
+{6145, 1233, 5649},\r
+{6289, 1457, 5361},\r
+{6273, 1441, 5249},\r
+{6273, 1265, 5265},\r
+{6145, 1665, 5377},\r
+{6241, 1633, 5409},\r
+{6161, 1617, 5377},\r
+{6177, 1729, 5297},\r
+{6177, 1665, 5409},\r
+{6129, 1553, 5361},\r
+{6161, 1569, 5345},\r
+{6193, 1745, 5377},\r
+{6273, 1361, 5393},\r
+{6177, 1505, 5489},\r
+{5905, 1073, 5553},\r
+{5953, 1441, 5681},\r
+{5873, 1249, 5777},\r
+{5745, 1233, 5777},\r
+{5921, 849, 5921},\r
+{5825, 913, 5873},\r
+{5777, 801, 5873},\r
+{5745, 1185, 5841},\r
+{5793, 1089, 5873},\r
+{5761, 945, 5921},\r
+{5793, 1041, 5841},\r
+{5889, 1281, 5681},\r
+{5793, 1153, 5777},\r
+{5649, 1425, 5713},\r
+{5809, 1553, 5809},\r
+{5441, 1745, 5841},\r
+{5537, 1841, 5729},\r
+{6945, 641, 5521},\r
+{6097, 2113, 4945},\r
+{5953, 2705, 5329},\r
+{6193, 2449, 5585},\r
+{5841, 1953, 5249},\r
+{6321, 1793, 5329},\r
+{6369, 1633, 5425},\r
+{6177, 1745, 5185},\r
+{6305, 1457, 4833},\r
+{6353, 769, 5201},\r
+{6529, 817, 5265},\r
+{6305, 641, 5473},\r
+{6289, 497, 5313},\r
+{6241, 337, 5361},\r
+{6321, 145, 5409},\r
+{6257, -63, 5441},\r
+{6177, 273, 5489},\r
+{6129, 193, 5585},\r
+{6241, -79, 5633},\r
+{6017, 65, 5665},\r
+{6257, 49, 5617},\r
+{5985, -255, 5873},\r
+{6049, -111, 5537},\r
+{6273, -15, 5585},\r
+{6113, 17, 5585},\r
+{6033, -255, 5649},\r
+{6017, 17, 5569},\r
+{6225, -287, 5553},\r
+{6321, -127, 5489},\r
+{6081, 97, 5601},\r
+{6193, 209, 5201},\r
+{6385, 241, 5217},\r
+{6273, 321, 5233},\r
+{6769, 449, 5697},\r
+{6433, 257, 5249},\r
+{6545, 689, 5089},\r
+{6305, 1313, 5281},\r
+{6177, 721, 5505},\r
+{6193, 1825, 5649},\r
+{6129, 961, 4705},\r
+{6641, 1121, 4961},\r
+{6513, 801, 4945},\r
+{6673, 641, 5345},\r
+{6241, -159, 5185},\r
+{6353, 657, 4977},\r
+{6305, 1377, 5361},\r
+{6433, 561, 5265},\r
+{6129, 1745, 5265},\r
+{6561, 465, 5329},\r
+{6417, 1089, 5505},\r
+{6193, 785, 5745},\r
+{6065, 1233, 5729},\r
+{5793, 1777, 5521},\r
+{6001, 993, 5937},\r
+{5905, 769, 5697},\r
+{6033, 1105, 5489},\r
+{6049, 1377, 5537},\r
+{5873, 1153, 5649},\r
+{5937, 1281, 5665},\r
+{6097, 2001, 5409},\r
+{6081, 2065, 5217},\r
+{6177, 1953, 5217},\r
+{6129, 2081, 5297},\r
+{6385, 1873, 5313},\r
+{5745, 1761, 5457},\r
+{6081, 2385, 5361},\r
+{6273, 1537, 5041},\r
+{6433, 1857, 4737},\r
+{6529, 1905, 4881},\r
+{6801, 1857, 4929},\r
+{6401, 1649, 5201},\r
+{6017, 1713, 4865},\r
+{6497, 1793, 5217},\r
+{5985, 1377, 4977},\r
+{6177, 1521, 5425},\r
+{6161, 1697, 5457},\r
+{5985, 1169, 5345},\r
+{6033, 1713, 5473},\r
+{6193, 1473, 5649},\r
+{5873, 1761, 5873},\r
+{6289, 1761, 5665},\r
+{5873, 1505, 5649},\r
+{5985, 1441, 5473},\r
+{6081, 1057, 5713},\r
+{6097, 1057, 5585},\r
+{6049, 1057, 5553},\r
+{5873, 1377, 5505},\r
+{6049, 1313, 5521},\r
+{6161, 1521, 5489},\r
+{6097, 1841, 5617},\r
+{6273, 2209, 5329},\r
+{6273, 2081, 5233},\r
+{6161, 1537, 5473},\r
+{6049, 2225, 4817},\r
+{6385, 2753, 4721},\r
+{6513, 2593, 4465},\r
+{6641, 2545, 4625},\r
+{6561, 2337, 4785},\r
+{6449, 2209, 4705},\r
+{6113, 1633, 4993},\r
+{6257, 2273, 5057},\r
+{6193, 1953, 5153},\r
+{6081, 1969, 5393},\r
+{5969, 1729, 5601},\r
+{5905, 1489, 5617},\r
+{6001, 1681, 5569},\r
+{5953, 1233, 5457},\r
+{5905, 1601, 5649},\r
+{6049, 1473, 5889},\r
+{5825, 1025, 6001},\r
+{6033, 1185, 5649},\r
+{6113, 1409, 5361},\r
+{6145, 1329, 5505},\r
+{6097, 1569, 5377},\r
+{6257, 1489, 5361},\r
+{6353, 1777, 5121},\r
+{6385, 2225, 4881},\r
+{6305, 2769, 5041},\r
+{6001, 2145, 4785},\r
+{6513, 1713, 5281},\r
+{6481, 641, 4769},\r
+{6657, 1297, 5137},\r
+{6609, 1425, 5025},\r
+{6529, 1185, 5201},\r
+{6369, 1233, 5057},\r
+{6465, 1441, 5041},\r
+{6401, 1473, 5137},\r
+{6417, 1473, 5025},\r
+{6337, 1633, 5073},\r
+{6305, 1521, 5313},\r
+{6273, 1313, 5425},\r
+{6129, 1089, 5601},\r
+{6273, 1185, 5329},\r
+{6225, 481, 5185},\r
+{6033, 193, 5153},\r
+{6161, 929, 5377},\r
+{6145, 385, 5553},\r
+{6065, -95, 5953},\r
+{5809, 33, 5969},\r
+{5857, 81, 5617},\r
+{6097, -15, 5601},\r
+{6001, 113, 5569},\r
+{6193, 465, 5633},\r
+{6065, 337, 5633},\r
+{6161, 513, 5649},\r
+{6257, 145, 5393},\r
+{6145, 497, 5505},\r
+{6305, 817, 5233},\r
+{6449, 769, 5281},\r
+{6385, 801, 5537},\r
+{6241, 1057, 5313},\r
+{6273, 977, 5121},\r
+{6529, 1137, 4897},\r
+{6609, 1329, 4849},\r
+{6801, 1649, 4897},\r
+{6561, 1713, 4961},\r
+{6545, 1537, 4817},\r
+{6545, 1457, 5153},\r
+{6401, 1553, 5057},\r
+{6513, 1169, 5137},\r
+{6513, 833, 5217},\r
+{6529, 1393, 4913},\r
+{6049, 1697, 5041},\r
+{5969, 2929, 5729},\r
+{6049, 2481, 6001},\r
+{5985, 2289, 5521},\r
+{5937, 1553, 5681},\r
+{5985, 1937, 5649},\r
+{6081, 1953, 5521},\r
+{6065, 1857, 5441},\r
+{5953, 1457, 5489},\r
+{5937, 1393, 5521},\r
+{5937, 1841, 5489},\r
+{6081, 1953, 5377},\r
+{5969, 1809, 5265},\r
+{6129, 2289, 5217},\r
+{6097, 1953, 5377},\r
+{6081, 2433, 5185},\r
+{6097, 2689, 5025},\r
+{6065, 2977, 5025},\r
+{6161, 2625, 5041},\r
+{6177, 2689, 5041},\r
+{6193, 2785, 5025},\r
+{5985, 2913, 4001},\r
+{7281, 2417, 4865},\r
+{6481, 3697, 5569},\r
+{6161, 2993, 4289},\r
+{6289, 2465, 4769},\r
+{6001, 3041, 5105},\r
+{6017, 2369, 5649},\r
+{6033, 2753, 5297},\r
+{5921, 2321, 5393},\r
+{5857, 2033, 5345},\r
+{5809, 1905, 5377},\r
+{5841, 1953, 5489},\r
+{5889, 2225, 5729},\r
+{5825, 1985, 5729},\r
+{6033, 1793, 5633},\r
+{6049, 1553, 5521},\r
+{5521, 1505, 5313},\r
+{6545, 705, 5585},\r
+{5553, 1905, 5713},\r
+{6049, 1633, 5633},\r
+{6369, 1073, 5121},\r
+{6193, 1313, 4961},\r
+{6273, 1873, 5201},\r
+{6481, 1681, 5841},\r
+{6113, 945, 5729},\r
+{6369, 1217, 4833},\r
+{6049, 1409, 5553},\r
+{6017, 1, 5745},\r
+{6209, 257, 5457},\r
+{6049, 929, 5681},\r
+{6001, 465, 5777},\r
+{5937, 257, 5921},\r
+{6001, 433, 5793},\r
+{6033, 433, 5601},\r
+{5937, 481, 5473},\r
+{6017, 529, 5585},\r
+{6049, 305, 5777},\r
+{6081, 97, 5649},\r
+{6065, 209, 5729},\r
+{5937, -15, 5649},\r
+{5857, 145, 5921},\r
+{5905, -143, 6065},\r
+{5681, -79, 6161},\r
+{5921, -239, 5649},\r
+{5761, -111, 5665},\r
+{5889, 113, 5697},\r
+{5841, -31, 5713},\r
+{5761, -399, 5809},\r
+{5489, -911, 5633},\r
+{5521, -767, 5585},\r
+{6433, 449, 5729},\r
+{6145, 33, 5793},\r
+{6385, 273, 5505},\r
+{6401, 961, 5057},\r
+{6385, 1505, 5185},\r
+{6273, 1377, 5409},\r
+{5985, 1841, 5201},\r
+{5857, 1825, 5489},\r
+{5889, 2209, 5777},\r
+{6177, 1601, 5473},\r
+{6113, 1969, 5601},\r
+{6033, 1953, 5473},\r
+{6193, 1857, 5601},\r
+{6225, 1697, 5617},\r
+{5985, 2353, 5601},\r
+{6481, 2161, 6273},\r
+{5713, 1585, 4849},\r
+{5921, 1377, 4849},\r
+{5825, 1009, 6209},\r
+{5089, 529, 5537},\r
+{5409, 129, 6113},\r
+{5761, 177, 5697},\r
+{6193, 289, 5249},\r
+{6193, 449, 5665},\r
+{6049, 657, 5425},\r
+{5905, 1329, 5153},\r
+{6145, 1409, 5265},\r
+{5329, 1137, 5857},\r
+{6001, 817, 5793},\r
+{6097, 769, 5697},\r
+{6513, 1393, 5297},\r
+{6433, 1729, 5265},\r
+{6321, 1537, 5169},\r
+{6305, 1329, 5249},\r
+{6097, 1185, 5265},\r
+{6161, 833, 5537},\r
+{5825, 641, 5537},\r
+{5889, 513, 5809},\r
+{6049, 401, 5969},\r
+{5697, 177, 6049},\r
+{5681, -63, 6081},\r
+{5601, -191, 6113},\r
+{5505, -863, 6289},\r
+{5329, -559, 6161},\r
+{5489, -911, 6001},\r
+{5441, -735, 6209},\r
+{5521, -959, 6225},\r
+{5841, -303, 5745},\r
+{5825, -367, 5921},\r
+{5825, -159, 5761},\r
+{6001, -47, 5681},\r
+{5969, 49, 5697},\r
+{6257, 529, 5345},\r
+{6241, 449, 5601},\r
+{5969, 769, 5617},\r
+{6145, 497, 5649},\r
+{5953, 513, 5537},\r
+{6097, 625, 5521},\r
+{6145, 993, 5313},\r
+{5857, 289, 5745},\r
+{6001, 737, 5697},\r
+{6065, 353, 5825},\r
+{5873, 641, 5905},\r
+{6193, 1137, 5569},\r
+{6145, 929, 5633},\r
+{6129, 1153, 5505},\r
+{6081, 913, 5921},\r
+{5873, 833, 5777},\r
+{5937, 193, 5809},\r
+{5953, 689, 5921},\r
+{5857, 145, 5809},\r
+{5873, 289, 5665},\r
+{5889, 241, 5633},\r
+{5937, 433, 5793},\r
+{6001, 225, 5841},\r
+{5921, 417, 5697},\r
+{6033, 1041, 5633},\r
+{6049, 1057, 5409},\r
+{5809, 1233, 5841},\r
+{5985, 1441, 5633},\r
+{6001, 1313, 5697},\r
+{6049, 1137, 5777},\r
+{6385, 1473, 5537},\r
+{6465, 1697, 4977},\r
+{6465, 1505, 4865},\r
+{6513, 1649, 5073},\r
+{6209, 1633, 4945},\r
+{6705, 1601, 5073},\r
+{6369, 1633, 5137},\r
+{6625, 1393, 5345},\r
+{6113, 1633, 4993},\r
+{6193, 1217, 5105},\r
+{6097, 1297, 5649},\r
+{5905, 1057, 5841},\r
+{5649, 897, 5937},\r
+{5553, 417, 6209},\r
+{5729, 945, 5825},\r
+{5921, 721, 5553},\r
+{5761, 593, 5297},\r
+{5345, 721, 5905},\r
+{5665, 641, 6113},\r
+{5697, 625, 5953},\r
+{5937, 705, 6209},\r
+{5745, 1121, 6177},\r
+{5953, 1105, 5329},\r
+{5889, 1393, 5233},\r
+{5745, 1217, 5937},\r
+{5857, 1441, 6033},\r
+{5889, 1585, 6065},\r
+{6833, 1921, 4721},\r
+{6801, 1969, 4417},\r
+{6737, 1905, 4561},\r
+{6657, 1921, 4785},\r
+{6305, 1953, 5089},\r
+{6065, 1937, 5281},\r
+{6177, 1985, 5377},\r
+{5985, 1905, 5553},\r
+{6049, 1601, 5713},\r
+{6001, 1313, 5713},\r
+{5793, 689, 5697},\r
+{5601, 561, 5937},\r
+{5505, 657, 6225},\r
+{5457, 433, 6449},\r
+{5521, 609, 6305},\r
+{5457, 353, 6193},\r
+{5361, -79, 6385},\r
+{5553, -223, 6017},\r
+{5521, -143, 6049},\r
+{5489, -15, 5905},\r
+{5505, 401, 6193},\r
+{5809, 689, 5793},\r
+{5857, 273, 5681},\r
+{5697, 817, 5841},\r
+{6177, 1137, 5441},\r
+{6065, 1089, 5633},\r
+{5969, 1313, 5745},\r
+{6161, 1697, 5521},\r
+{6241, 1761, 5329},\r
+{6385, 1729, 5233},\r
+{6353, 1617, 5137},\r
+{6289, 1441, 5281},\r
+{6145, 1601, 5425},\r
+{6177, 1553, 5425},\r
+{6065, 1393, 5553},\r
+{6161, 1873, 5393},\r
+{5889, 705, 5649},\r
+{5953, 881, 5777},\r
+{5745, 609, 5873},\r
+{5681, 1089, 6033},\r
+{5697, 721, 6033},\r
+{5505, 433, 6273},\r
+{5649, 769, 6033},\r
+{5809, 385, 5969},\r
+{5809, 305, 5665},\r
+{6049, 209, 5553},\r
+{5697, 337, 5985},\r
+{5809, 577, 5953},\r
+{5745, 721, 5921},\r
+{5697, 689, 5873},\r
+{5713, 961, 5665},\r
+{6049, 1105, 5649},\r
+{6145, 881, 5713},\r
+{6289, 961, 4961},\r
+{6465, 1425, 4689},\r
+{6625, 1969, 4817},\r
+{6241, 1425, 5265},\r
+{6257, 1425, 5313},\r
+{6001, 1793, 5377},\r
+{6113, 1697, 5585},\r
+{6097, 1905, 5393},\r
+{6145, 1249, 5537},\r
+{6177, 1601, 5489},\r
+{6049, 1073, 5553},\r
+{5889, 1521, 5681},\r
+{5857, 1169, 5873},\r
+{6001, 897, 5601},\r
+{6129, 1041, 5505},\r
+{6193, 881, 5377},\r
+{6289, 353, 5313},\r
+{5393, 1281, 6017},\r
+{5377, 1793, 5345},\r
+{5585, 1601, 6433},\r
+{6385, -463, 5361},\r
+{6449, 705, 5153},\r
+{6449, 577, 5425},\r
+{5969, 1329, 5505},\r
+{6529, -351, 5473},\r
+{6625, -79, 4689},\r
+{6657, 65, 4737},\r
+{6257, 721, 5249},\r
+{6129, 577, 5473},\r
+{6353, 161, 5441},\r
+{6465, 289, 5217},\r
+{6481, 465, 5105},\r
+{6465, 993, 4913},\r
+{6625, 673, 4865},\r
+{6465, 97, 5217},\r
+{6529, -463, 5601},\r
+{6513, 465, 5297},\r
+{6689, 17, 4721},\r
+{6401, -95, 4993},\r
+{6241, -319, 5729},\r
+{6193, -543, 5457},\r
+{6177, -495, 5361},\r
+{6273, -543, 5441},\r
+{6097, -879, 5201},\r
+{5393, -1551, 5457},\r
+{6113, -1183, 5361},\r
+{6225, -847, 5889},\r
+{6033, -879, 5809},\r
+{6289, -783, 5457},\r
+{6529, -239, 4865},\r
+{6545, 145, 5137},\r
+{6113, 593, 5249},\r
+{6609, 737, 5665},\r
+{5953, 209, 5569},\r
+{6241, 833, 5553},\r
+{6241, 769, 5489},\r
+{6353, 497, 5201},\r
+{5905, 1617, 4849},\r
+{6801, 865, 5553},\r
+{6145, -399, 5569},\r
+{6193, 545, 5649},\r
+{6113, 177, 5377},\r
+{6369, 481, 5409},\r
+{6241, 113, 5393},\r
+{5921, 161, 5633},\r
+{5729, 289, 6033},\r
+{5873, 449, 5969},\r
+{6001, 433, 6001},\r
+{5873, 417, 5761},\r
+{5985, -143, 5617},\r
+{6145, 209, 5489},\r
+{6097, 593, 5633},\r
+{5953, 577, 5713},\r
+{6017, 497, 5665},\r
+{6145, 769, 5665},\r
+{6289, 737, 5553},\r
+{6289, 785, 5409},\r
+{6337, 561, 5313},\r
+{6321, 881, 5121},\r
+{6337, 1457, 4561},\r
+{6273, 1313, 5057},\r
+{6321, 657, 4961},\r
+{6657, 1457, 4737},\r
+{6497, 1041, 4721},\r
+{6049, 1569, 6017},\r
+{5937, 945, 6017},\r
+{6161, 1441, 5601},\r
+{5985, 753, 5457},\r
+{6017, 737, 5537},\r
+{5905, 1137, 5745},\r
+{5761, -143, 4977},\r
+{5809, -127, 4097},\r
+{6145, 81, 5649},\r
+{5825, -191, 7201},\r
+{6017, -127, 6049},\r
+{6161, -383, 5633},\r
+{6337, 353, 5425},\r
+{6161, 225, 5665},\r
+{5937, 353, 5521},\r
+{6257, 465, 5137},\r
+{6417, 1041, 4785},\r
+{5873, 1937, 6305},\r
+{5905, 1297, 6593},\r
+{5713, 961, 6065},\r
+{5889, 1521, 5345},\r
+{5889, 2193, 5409},\r
+{5777, 1489, 6193},\r
+{6033, 1473, 5777},\r
+{5857, 1409, 5473},\r
+{6081, 1361, 5217},\r
+{6225, 1569, 4913},\r
+{5905, 1681, 5841},\r
+{5825, 1729, 5985},\r
+{5889, 1617, 5841},\r
+{6033, 1697, 5329},\r
+{6209, 977, 5425},\r
+{5857, 1521, 5921},\r
+{5841, 1761, 5697},\r
+{6097, 1665, 5553},\r
+{6097, 1457, 5473},\r
+{6033, 1393, 5473},\r
+{5937, 1857, 5649},\r
+{5905, 2001, 5649},\r
+{5809, 1873, 5633},\r
+{5825, 2017, 5761},\r
+{5985, 2081, 5713},\r
+{6049, 1825, 5185},\r
+{5953, 2145, 5217},\r
+{5937, 2305, 5489},\r
+{6033, 2433, 5873},\r
+{6177, 2161, 5441},\r
+{6001, 2113, 5073},\r
+{6177, 1889, 5185},\r
+{6097, 2017, 5441},\r
+{6033, 2033, 5537},\r
+{6033, 1633, 5553},\r
+{5921, 1521, 5761},\r
+{5889, 1633, 5729},\r
+{5873, 1825, 5553},\r
+{5937, 1601, 5361},\r
+{5937, 1745, 5569},\r
+{5937, 1601, 5761},\r
+{5809, 1329, 5649},\r
+{6049, 1313, 5441},\r
+{6001, 1569, 5441},\r
+{5969, 1329, 5633},\r
+{5921, 1521, 5697},\r
+{5873, 1841, 5489},\r
+{5665, 2161, 5233},\r
+{6177, 2193, 5217},\r
+{6113, 2321, 5521},\r
+{5985, 1857, 5393},\r
+{5841, 2753, 5217},\r
+{6097, 2513, 5441},\r
+{6049, 2497, 5297},\r
+{6081, 2129, 5153},\r
+{6065, 2433, 5201},\r
+{6129, 2449, 5297},\r
+{6033, 2113, 5361},\r
+{6049, 2209, 5249},\r
+{5953, 1921, 5425},\r
+{5889, 1921, 5633},\r
+{5745, 1617, 5745},\r
+{5649, 1889, 5889},\r
+{5649, 1809, 5777},\r
+{5729, 1217, 5857},\r
+{5633, 1521, 5953},\r
+{5585, 1489, 5969},\r
+{5713, 1425, 5793},\r
+{5697, 1393, 5729},\r
+{5889, 1905, 5713},\r
+{5809, 1969, 5665},\r
+{5777, 2065, 5569},\r
+{6033, 2081, 5169},\r
+{5905, 3217, 5393},\r
+{5681, 2865, 5457},\r
+{6033, 2977, 5345},\r
+{6033, 2881, 4865},\r
+{6017, 3121, 5041},\r
+{5921, 3089, 5121},\r
+{6017, 2689, 5217},\r
+{6113, 2673, 5201},\r
+{5937, 2913, 4961},\r
+{6001, 2449, 5185},\r
+{5921, 2401, 5377},\r
+{5953, 2353, 5409},\r
+{5777, 2577, 5521},\r
+{5585, 2129, 5873},\r
+{5553, 2081, 5889},\r
+{5601, 2177, 5729},\r
+{5729, 1825, 5697},\r
+{5745, 1569, 5713},\r
+{5761, 1345, 5889},\r
+{5617, 1953, 5777},\r
+{5649, 2065, 5729},\r
+{5713, 2065, 5649},\r
+{5633, 2209, 5537},\r
+{5745, 1921, 5857},\r
+{5809, 2849, 5745},\r
+{5793, 2577, 5521},\r
+{6017, 2689, 5041},\r
+{6049, 2929, 5025},\r
+{6001, 2369, 5409},\r
+{6065, 2593, 5025},\r
+{6065, 2289, 5345},\r
+{6033, 2705, 5185},\r
+{5953, 2673, 5249},\r
+{5889, 2289, 5393},\r
+{5921, 2417, 5521},\r
+{5809, 2193, 5665},\r
+{5889, 2161, 5521},\r
+{5889, 2145, 5441},\r
+{5969, 1873, 5505},\r
+{5969, 1713, 5537},\r
+{5649, 1713, 5777},\r
+{5713, 1521, 5793},\r
+{5793, 1489, 5857},\r
+{5729, 1345, 5841},\r
+{5841, 1681, 5857},\r
+{5777, 2097, 5617},\r
+{5729, 2193, 5537},\r
+{5905, 2353, 5777},\r
+{5697, 2273, 5697},\r
+{5745, 2321, 5569},\r
+{6129, 2945, 4241},\r
+{6033, 3089, 4129},\r
+{6657, 1537, 5345},\r
+{6529, 2641, 5969},\r
+{5809, 3153, 5137},\r
+{6145, 2337, 5281},\r
+{6385, 1553, 5025},\r
+{6305, 1041, 5121},\r
+{6177, 545, 5521},\r
+{5873, 609, 5777},\r
+{5697, 657, 6145},\r
+{5553, 273, 5713},\r
+{5217, -447, 6545},\r
+{5393, 273, 6129},\r
+{5873, 257, 5713},\r
+{5985, 385, 5905},\r
+{5841, 369, 5953},\r
+{5889, 529, 5905},\r
+{5681, 385, 5985},\r
+{5921, 913, 5793},\r
+{6033, 961, 5937},\r
+{5969, 801, 5649},\r
+{6001, 1297, 5873},\r
+{6017, 1409, 5937},\r
+{6001, 1121, 5809},\r
+{5953, 817, 5697},\r
+{6289, 1057, 5217},\r
+{6017, 1409, 5329},\r
+{6385, 929, 5297},\r
+{6049, -895, 5729},\r
+{5953, -479, 5569},\r
+{6529, 273, 5713},\r
+{6273, 17, 5185},\r
+{5889, -63, 4353},\r
+{5713, -207, 5537},\r
+{6257, 17, 5009},\r
+{5505, -527, 7665},\r
+{5073, -911, 6673},\r
+{5777, -303, 5825},\r
+{6065, 17, 5569},\r
+{5905, 401, 6081},\r
+{6193, 1281, 5761},\r
+{6049, 321, 5233},\r
+{5953, 1505, 5569},\r
+{5745, 1345, 5537},\r
+{6193, 769, 5937},\r
+{6193, 1233, 5569},\r
+{6129, 1457, 5457},\r
+{6337, 1681, 5457},\r
+{5777, 529, 5009},\r
+{5825, 2161, 5953},\r
+{5841, 2865, 6417},\r
+{6609, 2657, 5665},\r
+{6017, 2913, 4353},\r
+{6081, 3281, 4401},\r
+{5873, 3713, 5025},\r
+{5969, 1105, 5905},\r
+{5345, 1089, 6721},\r
+{5137, 977, 6129},\r
+{5441, 961, 6433},\r
+{5649, 257, 5585},\r
+{5905, -111, 5489},\r
+{6001, 1969, 6001},\r
+{5873, 1633, 5681},\r
+{6145, 1377, 5121},\r
+{6513, 1841, 4337},\r
+{6305, 3121, 5169},\r
+{6465, 2529, 4977},\r
+{6465, 2625, 4801},\r
+{6769, 2305, 4593},\r
+{6657, 1521, 4945},\r
+{6241, 1601, 4817},\r
+{6065, 1073, 5665},\r
+{5937, 1265, 5617},\r
+{6033, 1169, 5729},\r
+{5969, 1185, 5777},\r
+{5841, 929, 6049},\r
+{5585, 1169, 6177},\r
+{5809, 801, 5985},\r
+{5585, 337, 5953},\r
+{5441, -495, 6193},\r
+{5233, -223, 6209},\r
+{5329, -463, 6321},\r
+{5297, -351, 6113},\r
+{5569, -367, 6049},\r
+{5697, 113, 6097},\r
+{5889, 273, 5857},\r
+{6097, 849, 5569},\r
+{6097, 673, 5649},\r
+{6097, 1377, 5473},\r
+{6113, 993, 5521},\r
+{6065, 753, 5633},\r
+{5921, 993, 5841},\r
+{5825, 1137, 5921},\r
+{6129, 945, 5617},\r
+{6161, 1233, 5425},\r
+{6001, 1233, 5553},\r
+{5873, 881, 5841},\r
+{5825, 1297, 5825},\r
+{5649, 1329, 5985},\r
+{5649, 1761, 5937},\r
+{5569, 1233, 6049},\r
+{5489, 689, 6081},\r
+{5761, 945, 6017},\r
+{5793, 753, 5809},\r
+{5649, 561, 5857},\r
+{5761, 513, 5937},\r
+{5665, 817, 5953},\r
+{5889, 929, 5937},\r
+{5841, 1217, 5681},\r
+{5761, 977, 5761},\r
+{5745, 1393, 5809},\r
+{5825, 1217, 5809},\r
+{6097, 2081, 5521},\r
+{6097, 1681, 5457},\r
+{6001, 1585, 5537},\r
+{6177, 1793, 5345},\r
+{6241, 1841, 5297},\r
+{6257, 1601, 5329},\r
+{6289, 1345, 5409},\r
+{6017, 1121, 5505},\r
+{5873, 1009, 5633},\r
+{5857, 1025, 5665},\r
+{5489, 753, 6305},\r
+{5521, 273, 6113},\r
+{5633, 673, 6113},\r
+{5681, 769, 5985},\r
+{5729, 465, 6017},\r
+{5873, 545, 5857},\r
+{5777, 257, 5889},\r
+{5889, 833, 5857},\r
+{6065, 449, 5921},\r
+{5761, 577, 5953},\r
+{5809, 1105, 5729},\r
+{5633, 1393, 5937},\r
+{5889, 1601, 5649},\r
+{5953, 1649, 5441},\r
+{5985, 705, 5585},\r
+{5873, 1009, 5457},\r
+{6401, 1713, 5281},\r
+{6225, 2081, 5361},\r
+{6177, 2337, 5409},\r
+{6065, 2001, 5521},\r
+{6033, 1985, 5457},\r
+{5937, 1457, 5585},\r
+{5841, 1201, 5665},\r
+{5649, 1521, 5745},\r
+{5665, 1393, 5937},\r
+{5745, 1633, 5905},\r
+{5761, 865, 5761},\r
+{5953, 721, 5729},\r
+{5681, 545, 5857},\r
+{5521, 721, 6129},\r
+{5569, 529, 6225},\r
+{5617, 817, 5953},\r
+{5649, 1233, 5985},\r
+{5473, 945, 5905},\r
+{5825, 945, 5777},\r
+{5969, 1569, 5745},\r
+{6161, 2353, 5185},\r
+{6161, 2721, 4977},\r
+{6321, 2577, 5057},\r
+{6033, 2433, 5249},\r
+{6225, 2865, 4929},\r
+{6225, 2465, 5105},\r
+{6289, 2273, 5185},\r
+{6081, 2417, 5265},\r
+{6209, 2257, 5121},\r
+{6129, 2225, 5233},\r
+{5921, 1521, 5697},\r
+{5921, 1681, 5761},\r
+{5889, 1505, 5553},\r
+{5681, 1329, 6049},\r
+{5745, 1281, 6017},\r
+{5793, 1425, 5745},\r
+{5761, 1201, 5761},\r
+{5809, 961, 5825},\r
+{5905, 721, 5793},\r
+{5857, 1009, 5665},\r
+{5841, 593, 5889},\r
+{5889, 1681, 5809},\r
+{5921, 1377, 5665},\r
+{6033, 1441, 5361},\r
+{6017, 1601, 5425},\r
+{5825, 2225, 5633},\r
+{6241, 2321, 4865},\r
+{6465, 2273, 4929},\r
+{6257, 2529, 5057},\r
+{6193, 2673, 5009},\r
+{6225, 2625, 4833},\r
+{6289, 2129, 5217},\r
+{6097, 2209, 5297},\r
+{6113, 2065, 5345},\r
+{5905, 2353, 5393},\r
+{5969, 2177, 5505},\r
+{5857, 1697, 5633},\r
+{5697, 1729, 5809},\r
+{5633, 1793, 5841},\r
+{5601, 1569, 5953},\r
+{5665, 1681, 5969},\r
+{5681, 961, 6113},\r
+{5665, 1105, 6001},\r
+{5953, 1377, 5601},\r
+{5921, 577, 5825},\r
+{5713, 865, 5921},\r
+{6017, 1393, 5585},\r
+{6033, 1473, 5457},\r
+{6065, 1409, 5345},\r
+{6225, 1425, 5297},\r
+{6241, 1873, 5201},\r
+{6321, 1841, 5105},\r
+{5921, 2257, 4737},\r
+{5761, 2705, 5601},\r
+{5969, 2497, 5169},\r
+{6177, 2081, 5217},\r
+{6193, 2129, 5265},\r
+{6033, 2417, 5489},\r
+{5969, 1937, 5425},\r
+{6225, 1697, 5457},\r
+{6609, 977, 5185},\r
+{6305, -415, 5361},\r
+{6417, 913, 5313},\r
+{6209, -31, 5393},\r
+{6193, -511, 5569},\r
+{6337, -511, 5249},\r
+{6289, -207, 5073},\r
+{5729, -927, 6177},\r
+{5729, -991, 5985},\r
+{6017, -687, 5681},\r
+{6145, -367, 5377},\r
+{6273, -207, 5409},\r
+{6033, -575, 5633},\r
+{6193, -543, 5553},\r
+{6305, -271, 5521},\r
+{6273, -255, 5441},\r
+{6353, -335, 5681},\r
+{6321, 497, 5089},\r
+{6193, 705, 5425},\r
+{6369, 209, 5553},\r
+{6417, 337, 5265},\r
+{6577, 225, 5201},\r
+{6497, 1, 4689},\r
+{6497, -95, 5649},\r
+{6465, -735, 5345},\r
+{6849, 273, 5105},\r
+{6657, 97, 5153},\r
+{6385, 433, 5057},\r
+{6161, -63, 5681},\r
+{5393, 209, 4881},\r
+{5313, -591, 6641},\r
+{3681, -639, 5713},\r
+{5585, -2383, 7441},\r
+{5409, -447, 6241},\r
+{5313, -927, 6321},\r
+{5265, -399, 6369},\r
+{5601, -367, 6177},\r
+{5729, -287, 6113},\r
+{5809, -223, 5825},\r
+{5937, 561, 5457},\r
+{5793, 561, 5521},\r
+{6257, -383, 6001},\r
+{5793, 865, 5825},\r
+{6113, 881, 5857},\r
+{5969, 1265, 5377},\r
+{6017, 593, 5809},\r
+{5969, 593, 5745},\r
+{6049, 641, 5889},\r
+{5921, 1089, 5473},\r
+{5809, 609, 5569},\r
+{5745, 353, 5585},\r
+{5745, 369, 6257},\r
+{5713, -95, 6225},\r
+{5857, 385, 6129},\r
+{5281, 673, 5793},\r
+{5633, -559, 6401},\r
+{4961, -511, 6097},\r
+{5073, -783, 6145},\r
+{5185, -415, 6913},\r
+{4961, 241, 6401},\r
+{5281, 913, 6273},\r
+{5761, 657, 5569},\r
+{6081, 401, 5201},\r
+{5777, 2481, 5729},\r
+{6385, 753, 5537},\r
+{6145, 1569, 5265},\r
+{6465, 2049, 4929},\r
+{6161, 2017, 5169},\r
+{6417, 1953, 4961},\r
+{6241, 1553, 5297},\r
+{6097, 1617, 5617},\r
+{5937, 1953, 5345},\r
+{6193, 1649, 5425},\r
+{6177, 929, 5169},\r
+{6017, 945, 5441},\r
+{5985, 977, 5809},\r
+{5505, 609, 6385},\r
+{5265, 545, 6497},\r
+{5185, 385, 6753},\r
+{5665, 737, 5985},\r
+{5633, 225, 5617},\r
+{5761, 625, 5665},\r
+{5889, 1297, 5873},\r
+{6001, 1665, 5697},\r
+{6113, 1249, 5409},\r
+{6129, 1825, 4961},\r
+{6353, 2305, 5025},\r
+{6401, 2593, 5025},\r
+{6305, 2673, 4881},\r
+{6081, 2929, 4865},\r
+{6209, 2385, 5297},\r
+{6193, 2881, 5633},\r
+{6465, 2769, 6145},\r
+{5969, 4161, 6209},\r
+{6961, 1489, 2113},\r
+{6289, 2673, 5569},\r
+{6177, 1729, 5345},\r
+{6049, 1729, 5393},\r
+{6145, 1761, 5585},\r
+{6081, 785, 5649},\r
+{6113, 577, 5889},\r
+{5761, 177, 5617},\r
+{5329, 65, 5681},\r
+{5297, 1, 6305},\r
+{5825, -831, 5505},\r
+{6049, -623, 5201},\r
+{5649, 113, 5761},\r
+{5553, 321, 5713},\r
+{5665, 449, 6065},\r
+{5857, 1073, 6081},\r
+{6641, 673, 4961},\r
+{6545, 1073, 5345},\r
+{6177, 977, 5393},\r
+{6129, 1297, 5457},\r
+{6129, 817, 5649},\r
+{6081, 961, 5409},\r
+{5921, 1137, 5745},\r
+{5793, 993, 5921},\r
+{5873, 1073, 6001},\r
+{5873, 801, 5969},\r
+{6145, 1169, 5569},\r
+{6225, 1313, 5409},\r
+{6257, 897, 5457},\r
+{5617, -687, 5841},\r
+{5425, -191, 6225},\r
+{5489, -287, 6353},\r
+{5393, -703, 6241},\r
+{5569, -191, 5953},\r
+{5841, -751, 5617},\r
+{5185, -2287, 5969},\r
+{1905, -2751, 6785},\r
+{2049, -1903, 6993},\r
+{3505, -639, 7633},\r
+{4641, -1295, 7649},\r
+{4049, -2447, 7313},\r
+{4337, -1791, 7617},\r
+{6001, -319, 5953},\r
+{5857, -47, 5873},\r
+{5393, -863, 5153},\r
+{6001, -223, 5121},\r
+{5905, 577, 6161},\r
+{5825, -463, 5713},\r
+{5809, -15, 5633},\r
+{5761, -591, 5537},\r
+{5633, -207, 5841},\r
+{5649, -367, 6177},\r
+{6065, 225, 5569},\r
+{6113, 17, 5393},\r
+{6145, -287, 5473},\r
+{5713, 929, 5697},\r
+{4785, -319, 5921},\r
+{4465, -1951, 6753},\r
+{4705, -3103, 6465},\r
+{4465, -655, 7633},\r
+{4449, -927, 7297},\r
+{5009, -751, 6833},\r
+{5249, -1103, 5777},\r
+{5473, -1679, 5633},\r
+{5825, -543, 5953},\r
+{5777, 289, 6097},\r
+{5649, 625, 6129},\r
+{5985, 257, 5697},\r
+{6161, 385, 5313},\r
+{6161, 865, 5537},\r
+{6065, 1505, 5825},\r
+{6321, 257, 6177},\r
+{6209, 529, 5137},\r
+{6273, 513, 5009},\r
+{5969, 401, 5921},\r
+{5713, -95, 6321},\r
+{6801, 1729, 4705},\r
+{6241, 529, 5185},\r
+{6209, 257, 5729},\r
+{6145, 609, 5489},\r
+{6049, -335, 6113},\r
+{5921, -735, 5745},\r
+{6081, 657, 5921},\r
+{6321, -15, 5505},\r
+{6241, -735, 5105},\r
+{6097, 385, 5489},\r
+{6145, 1025, 5553},\r
+{6049, 1681, 5537},\r
+{5937, 353, 5729},\r
+{5745, 1585, 5841},\r
+{5841, 1825, 5857},\r
+{6017, 1409, 5553},\r
+{6769, 1313, 5329},\r
+{6097, 1889, 5633},\r
+{6225, 2129, 5313},\r
+{6177, 1361, 5233},\r
+{5777, 2433, 5313},\r
+{6129, 1729, 5857},\r
+{5825, 881, 5713},\r
+{5713, 625, 5713},\r
+{5601, 1265, 5889},\r
+{5665, 1105, 6145},\r
+{5585, 1009, 5985},\r
+{5681, 689, 6001},\r
+{5649, 1233, 6065},\r
+{5585, 273, 5905},\r
+{5425, 209, 5585},\r
+{6129, 225, 5537},\r
+{6513, 2369, 5921},\r
+{6737, 1025, 5681},\r
+{6065, 753, 5073},\r
+{6289, 1089, 4865},\r
+{6241, 1649, 5409},\r
+{6305, 641, 5377},\r
+{6209, 769, 5249},\r
+{6257, 1681, 5521},\r
+{6353, 1425, 5345},\r
+{6321, 1137, 5089},\r
+{6289, 881, 5105},\r
+{6737, 769, 5265},\r
+{6449, 1025, 5153},\r
+{6289, 401, 5153},\r
+{6449, 385, 5361},\r
+{6497, 481, 5217},\r
+{6577, 353, 5105},\r
+{6385, 257, 5361},\r
+{6289, 273, 5361},\r
+{6257, -143, 5441},\r
+{5825, -159, 6385},\r
+{4881, -303, 5505},\r
+{5425, -751, 7169},\r
+{5681, 273, 6961},\r
+{5585, 1, 5921},\r
+{6017, 65, 6017},\r
+{6145, 337, 5457},\r
+{6305, 1137, 5025},\r
+{6545, 1441, 4641},\r
+{5457, 305, 5025},\r
+{6209, -671, 6689},\r
+{6161, 849, 5825},\r
+{6081, 625, 5169},\r
+{5985, 65, 5457},\r
+{5569, 529, 6017},\r
+{5265, 321, 5953},\r
+{5441, 577, 6433},\r
+{5857, 289, 6017},\r
+{5697, 145, 5873},\r
+{5745, 1105, 5313},\r
+{6097, 1153, 5489},\r
+{5601, 481, 5921},\r
+{5409, 49, 6193},\r
+{4769, 241, 5921},\r
+{4273, 177, 6833},\r
+{5377, -47, 7265},\r
+{5521, -15, 6481},\r
+{5729, -703, 5889},\r
+{5905, -31, 5761},\r
+{5889, 577, 5585},\r
+{5905, 1297, 5137},\r
+{5777, 1537, 6305},\r
+{5441, 449, 6625},\r
+{5473, -319, 6465},\r
+{6193, 369, 5617},\r
+{6273, 881, 5393},\r
+{6321, 849, 5249},\r
+{6065, 737, 5329},\r
+{6177, 1025, 5649},\r
+{6113, 1617, 5617},\r
+{6065, 1217, 5329},\r
+{5489, -175, 6049},\r
+{5329, -303, 6193},\r
+{5521, -207, 6033},\r
+{5249, 161, 6161},\r
+{5169, -31, 6449},\r
+{4737, -207, 6241},\r
+{3729, -1407, 7473},\r
+{4369, -2463, 7729},\r
+{4305, -1775, 7345},\r
+{4353, -927, 6881},\r
+{4737, -1407, 6753},\r
+{4993, -863, 6001},\r
+{5409, -687, 5761},\r
+{6081, -367, 5905},\r
+{5585, 321, 5857},\r
+{5681, -671, 6225},\r
+{5569, 209, 5937},\r
+{5457, 49, 6321},\r
+{5281, -415, 6497},\r
+{5297, -255, 6545},\r
+{5425, -271, 6209},\r
+{5857, 417, 6225},\r
+{5809, 593, 5937},\r
+{5841, 497, 5697},\r
+{5809, 497, 5457},\r
+{5953, 481, 5601},\r
+{3889, 801, 5921},\r
+{5169, -1583, 6929},\r
+{3889, -1455, 7249},\r
+{3985, -1807, 7249},\r
+{3009, -2479, 7825},\r
+{2897, -1279, 8353},\r
+{2881, -1055, 7969},\r
+{3105, -1487, 7441},\r
+{3217, -1679, 7345},\r
+{3745, -1407, 7761},\r
+{6561, -1135, 2257},\r
+{6993, -3679, 1905},\r
+{5217, -1023, 6945},\r
+{5137, 305, 7137},\r
+{5857, -783, 5553},\r
+{5649, -1103, 6305},\r
+{5633, 337, 6561},\r
+{5745, -1407, 5617},\r
+{5873, -367, 5569},\r
+{6369, -831, 4913},\r
+{5521, -2015, 5217},\r
+{4833, -2847, 5409},\r
+{4097, -2559, 6817},\r
+{3985, -2479, 7025},\r
+{3185, -2911, 6673},\r
+{2817, -2991, 6817},\r
+{1153, -3359, 8033},\r
+{993, -2863, 8273},\r
+{1441, -3311, 7473},\r
+{1425, -3263, 7617},\r
+{2129, -2959, 7409},\r
+{3361, -2879, 6721},\r
+{3825, -2575, 6641},\r
+{4513, -2463, 5921},\r
+{4689, -1967, 6321},\r
+{4737, -2111, 6209},\r
+{5345, -239, 6385},\r
+{5633, -239, 5665},\r
+{4737, -1215, 5361},\r
+{4657, -911, 6305},\r
+{3633, -1695, 7025},\r
+{4625, -1263, 7345},\r
+{4593, -1823, 6865},\r
+{4689, -1711, 6001},\r
+{4641, -2159, 5793},\r
+{4465, -2095, 5953},\r
+{3905, -2191, 6785},\r
+{3841, -1519, 6817},\r
+{3457, -2031, 6833},\r
+{2833, -2735, 7345},\r
+{2641, -1535, 8193},\r
+{3057, -1583, 7873},\r
+{3249, -1871, 7537},\r
+{3345, -1487, 7473},\r
+{4321, -735, 6945},\r
+{4417, -1471, 6609},\r
+{4401, -2175, 6273},\r
+{5793, -1391, 5489},\r
+{5457, -975, 6033},\r
+{5537, -767, 6417},\r
+{5857, -591, 5985},\r
+{5729, -383, 6033},\r
+{5553, -799, 5921},\r
+{5553, -15, 6273},\r
+{5505, 369, 5761},\r
+{6033, -143, 5345},\r
+{5985, -879, 4481},\r
+{5857, -367, 5585},\r
+{5905, -399, 5985},\r
+{5873, 1, 5857},\r
+{5953, -223, 5985},\r
+{5825, 657, 5857},\r
+{5665, -207, 6193},\r
+{5361, -399, 6209},\r
+{5345, -623, 6257},\r
+{5121, -1263, 6273},\r
+{5553, -991, 6129},\r
+{5985, -767, 5601},\r
+{5841, -175, 5889},\r
+{6177, 449, 5729},\r
+{6433, 97, 5121},\r
+{6337, 481, 5409},\r
+{6641, 1649, 5057},\r
+{6481, 337, 5265},\r
+{6289, 817, 5297},\r
+{6673, 369, 4881},\r
+{6561, 513, 4961},\r
+{7025, 1121, 4209},\r
+{6129, -3407, 3809},\r
+{6641, -767, 8721},\r
+{5169, -1807, 7265},\r
+{2689, -2703, 6801},\r
+{1649, -735, 8769},\r
+{2625, -3599, 4865},\r
+{4945, -5679, 4913},\r
+{5457, -3967, 5233},\r
+{5489, -6543, 3473},\r
+{3105, -5199, 4049},\r
+{3169, -6127, 5345},\r
+{3521, -5727, 4833},\r
+{3841, -5087, 5105},\r
+{3889, -5663, 5169},\r
+{3793, -5695, 5089},\r
+{4161, -4959, 4625},\r
+{3825, -4015, 4609},\r
+{4529, -4527, 5665},\r
+{4769, -4879, 6209},\r
+{4529, -4191, 4817},\r
+{4545, -4095, 5409},\r
+{4657, -4111, 5233},\r
+{4849, -4255, 5601},\r
+{4913, -4431, 5585},\r
+{4833, -4287, 5345},\r
+{4897, -4879, 5793},\r
+{4673, -3903, 5649},\r
+{5521, -4511, 5537},\r
+{5201, -4943, 5217},\r
+{5601, -5439, 5953},\r
+{2977, -3487, 3777},\r
+{2609, -3775, 4929},\r
+{641, -1983, 6865},\r
+{-207, -3631, 3857},\r
+{-719, -543, 481},\r
+{13217, -4719, 12625},\r
+{4305, 1057, 11297},\r
+{6593, -655, 4145},\r
+{7249, 1937, 5025},\r
+{6513, 737, 4961},\r
+{6305, 1521, 4417},\r
+{6193, 689, 5585},\r
+{6289, 1057, 5121},\r
+{6193, 1489, 5393},\r
+{6273, 2081, 4977},\r
+{6257, 1265, 4849},\r
+{6433, 1201, 5041},\r
+{6529, 945, 5201},\r
+{6673, 1505, 4897},\r
+{6801, 881, 5233},\r
+{6753, 1121, 5073},\r
+{6561, 529, 4897},\r
+{6161, 145, 5441},\r
+{6209, 65, 5473},\r
+{6257, -175, 5313},\r
+{6225, -31, 5313},\r
+{6241, -623, 5569},\r
+{6353, -399, 5505},\r
+{6481, -703, 5169},\r
+{6545, -111, 4945},\r
+{6529, 353, 5057},\r
+{6401, 17, 5409},\r
+{6609, 353, 5169},\r
+{6545, 273, 5041},\r
+{6593, 593, 4945},\r
+{6641, 993, 4817},\r
+{6689, 481, 5073},\r
+{6689, 721, 5041},\r
+{6737, 625, 4929},\r
+{6545, 673, 4865},\r
+{6801, 625, 4849},\r
+{6833, 529, 4673},\r
+{6545, 241, 5073},\r
+{6481, 161, 5217},\r
+{6449, 65, 5313},\r
+{6369, 209, 5185},\r
+{6481, 209, 5153},\r
+{6497, 81, 5297},\r
+{6641, 321, 5201},\r
+{6689, 513, 4897},\r
+{6657, 753, 4881},\r
+{6737, 753, 5009},\r
+{6753, 849, 4977},\r
+{6513, 1025, 5025},\r
+{6449, 1281, 5185},\r
+{6385, 1137, 5249},\r
+{6465, 1441, 5025},\r
+{6385, 1265, 5009},\r
+{6625, 625, 5201},\r
+{6801, 929, 5009},\r
+{6625, 1009, 5057},\r
+{6593, 577, 4929},\r
+{6369, 369, 5425},\r
+{6273, -15, 5569},\r
+{6241, -111, 5441},\r
+{6305, 225, 5217},\r
+{6305, 81, 5249},\r
+{6193, -255, 5473},\r
+{6513, -399, 5265},\r
+{6145, -351, 5345},\r
+{6353, 225, 5409},\r
+{6417, 257, 5281},\r
+{6561, 241, 5169},\r
+{6369, 353, 5185},\r
+{6433, 481, 5345},\r
+{6513, 801, 5009},\r
+{6513, 721, 5105},\r
+{6449, 641, 5201},\r
+{6513, 801, 5025},\r
+{6673, 1041, 4865},\r
+{6737, 225, 5089},\r
+{6497, 33, 5089},\r
+{6497, 417, 5281},\r
+{6337, 113, 5249},\r
+{6385, -15, 5329},\r
+{6353, 33, 5105},\r
+{6321, -191, 5281},\r
+{6225, -511, 5537},\r
+{6401, -287, 5281},\r
+{5953, 177, 5425},\r
+{7201, 273, 4849},\r
+{6305, -447, 5473},\r
+{6545, 817, 5553},\r
+{6113, 1009, 5297},\r
+{6705, 833, 5329},\r
+{6561, 1761, 4881},\r
+{6657, 1793, 4913},\r
+{6417, 1281, 4993},\r
+{6641, 1281, 4945},\r
+{6929, 1409, 4785},\r
+{6817, 1457, 4673},\r
+{6561, 1649, 4577},\r
+{6465, 865, 5473},\r
+{6161, 1329, 5425},\r
+{6081, 1153, 5793},\r
+{6241, 833, 6241},\r
+{5697, 1329, 6065},\r
+{5745, 2593, 5169},\r
+{6353, 1969, 4721},\r
+{6289, 1409, 4929},\r
+{5969, 1841, 4817},\r
+{6385, 2433, 4913},\r
+{6305, 1857, 5505},\r
+{6305, 1793, 5217},\r
+{6401, 2257, 4705},\r
+{6449, 2321, 5089},\r
+{6321, 2273, 5249},\r
+{6561, 2209, 5249},\r
+{6401, 2161, 5729},\r
+{6161, 1601, 4945},\r
+{6273, 1921, 4641},\r
+{6257, 1585, 4241},\r
+{6097, 1409, 5217},\r
+{5953, 1425, 4993},\r
+{5905, 1505, 5889},\r
+{5905, 1697, 6305},\r
+{5745, 1761, 5745},\r
+{6273, 1329, 5297},\r
+{6529, 945, 5105},\r
+{5985, 1921, 5313},\r
+{6049, 2065, 5553},\r
+{6001, 1697, 5905},\r
+{6033, 1457, 5569},\r
+{6193, 1697, 5377},\r
+{6305, 2001, 5137},\r
+{6065, 1617, 5617},\r
+{6113, 1921, 5441},\r
+{6225, 1665, 5361},\r
+{6177, 1649, 5281},\r
+{6001, 1841, 5409},\r
+{6225, 1905, 5409},\r
+{6257, 1521, 5553},\r
+{6257, 1121, 5249},\r
+{6193, 1041, 5441},\r
+{6065, 1649, 5585},\r
+{6065, 1777, 5313},\r
+{6225, 1441, 5217},\r
+{6257, 1489, 5329},\r
+{6225, 1489, 5361},\r
+{6081, 2209, 5265},\r
+{6161, 2033, 5265},\r
+{6385, 2017, 5265},\r
+{6385, 1937, 4977},\r
+{6497, 2305, 4929},\r
+{6305, 1921, 5249},\r
+{6273, 1953, 5137},\r
+{6305, 1857, 5185},\r
+{6241, 1985, 5073},\r
+{6273, 1857, 5217},\r
+{6161, 1521, 5361},\r
+{5921, 1857, 5617},\r
+{6001, 1809, 5553},\r
+{6065, 1457, 5361},\r
+{6145, 1681, 5281},\r
+{5969, 1185, 5553},\r
+{5985, 1297, 5825},\r
+{6049, 1633, 5457},\r
+{6225, 1681, 5169},\r
+{6097, 1521, 5313},\r
+{5937, 1985, 5377},\r
+{5985, 2081, 5777},\r
+{6065, 1841, 5457},\r
+{6161, 2193, 5249},\r
+{6209, 2321, 5137},\r
+{6257, 2337, 5009},\r
+{6129, 2033, 5249},\r
+{6337, 2433, 5313},\r
+{6289, 2577, 5249},\r
+{6289, 2033, 5073},\r
+{6257, 1649, 5089},\r
+{5921, 2385, 5457},\r
+{5793, 1633, 5953},\r
+{6129, 1393, 5393},\r
+{6273, 1585, 5425},\r
+{5873, 1969, 5617},\r
+{6017, 1569, 5489},\r
+{6161, 1825, 5441},\r
+{6033, 1537, 5585},\r
+{5969, 1857, 5441},\r
+{5761, 2177, 5617},\r
+{6033, 2113, 5521},\r
+{5985, 2017, 5281},\r
+{6193, 2257, 5185},\r
+{6225, 2401, 5217},\r
+{6065, 2033, 5457},\r
+{6129, 2001, 5441},\r
+{6305, 2497, 5121},\r
+{6241, 2305, 5057},\r
+{6209, 1441, 5153},\r
+{5905, 1889, 5505},\r
+{5729, 1697, 5889},\r
+{6065, 1585, 5505},\r
+{5905, 1617, 5633},\r
+{5937, 1937, 5617},\r
+{5905, 1889, 5569},\r
+{6129, 1569, 5505},\r
+{6193, 1361, 5345},\r
+{6193, 1873, 5249},\r
+{6145, 2129, 5137},\r
+{6337, 2129, 5249},\r
+{6065, 1761, 5633},\r
+{6081, 2081, 5265},\r
+{5921, 2113, 5441},\r
+{5793, 2305, 5585},\r
+{6081, 2113, 5265},\r
+{6369, 2673, 6081},\r
+{6081, 2449, 4961},\r
+{6129, 1313, 5297},\r
+{5761, 1441, 5665},\r
+{6465, 1265, 5681},\r
+{6001, 625, 5377},\r
+{6097, 1089, 5537},\r
+{6065, 945, 5441},\r
+{6289, 129, 5361},\r
+{6481, 257, 5553},\r
+{6273, 577, 5217},\r
+{6289, 1505, 5281},\r
+{6273, 801, 5489},\r
+{6049, 977, 5553},\r
+{6161, 1297, 5409},\r
+{6449, 1553, 5201},\r
+{6353, 1393, 5425},\r
+{6433, 1521, 5313},\r
+{6385, 849, 5137},\r
+{6641, 1537, 4961},\r
+{6481, 993, 5073},\r
+{6289, 1009, 5249},\r
+{6097, 945, 5521},\r
+{6273, 545, 5329},\r
+{6033, 641, 5393},\r
+{6001, 801, 5697},\r
+{5809, 449, 6017},\r
+{6385, 465, 4849},\r
+{6513, 1041, 4737},\r
+{6625, 2129, 4785},\r
+{6721, 1473, 4881},\r
+{6625, 1265, 4833},\r
+{6545, 1873, 4753},\r
+{6801, 2145, 4593},\r
+{6625, 1697, 4929},\r
+{6449, 1489, 4801},\r
+{6481, 1393, 5329},\r
+{6673, 1265, 4961},\r
+{6641, 993, 4961},\r
+{6417, 1505, 4993},\r
+{6081, 785, 5393},\r
+{6017, 977, 5617},\r
+{6033, 769, 5633},\r
+{6401, 1057, 5409},\r
+{6257, 705, 5489},\r
+{6369, 689, 5361},\r
+{6385, 993, 5201},\r
+{6353, 1825, 4817},\r
+{6385, 1921, 4945},\r
+{6433, 1585, 5201},\r
+{6449, 1809, 4721},\r
+{6705, 2065, 4641},\r
+{6593, 2289, 4881},\r
+{6385, 1985, 4833},\r
+{6369, 1777, 5057},\r
+{6449, 1489, 5185},\r
+{6337, 1889, 5089},\r
+{6321, 1281, 5521},\r
+{5713, 1345, 5745},\r
+{6225, 1105, 5649},\r
+{6097, 1361, 5281},\r
+{6001, 1441, 5601},\r
+{5985, 2081, 5537},\r
+{6129, 1505, 5377},\r
+{5905, 1937, 5201},\r
+{5873, 993, 5633},\r
+{5905, 2161, 5457},\r
+{6417, 2305, 5169},\r
+{6529, 2177, 4465},\r
+{6641, 2641, 4161},\r
+{6353, 2673, 4897},\r
+{6305, 2849, 4929},\r
+{6401, 2593, 4929},\r
+{6353, 2193, 5153},\r
+{6513, 1521, 5489},\r
+{6353, 2049, 5313},\r
+{6129, 2161, 4833},\r
+{6001, 1425, 5201},\r
+{6273, 1201, 5185},\r
+{6289, 1361, 5345},\r
+{5873, 1233, 5681},\r
+{5889, 1153, 5873},\r
+{5857, 1361, 5665},\r
+{6881, 1873, 4801},\r
+{6593, 1825, 4993},\r
+{6273, 1585, 5105},\r
+{6497, 1713, 5137},\r
+{6273, 2161, 4945},\r
+{6513, 2001, 4961},\r
+{6369, 2049, 5057},\r
+{6257, 1985, 5153},\r
+{6289, 2017, 5137},\r
+{6417, 2177, 4993},\r
+{6369, 1489, 5153},\r
+{6257, 1457, 5265},\r
+{6193, 1681, 5233},\r
+{6145, 1649, 5457},\r
+{6001, 1585, 5393},\r
+{6129, 993, 5457},\r
+{6017, 1601, 5329},\r
+{5953, 1889, 5489},\r
+{6305, 1201, 5377},\r
+{6561, 1153, 5105},\r
+{6481, 1921, 4993},\r
+{6017, 2081, 5345},\r
+{6001, 1521, 5937},\r
+{5649, 2017, 6561},\r
+{5633, 2145, 5969},\r
+{6129, 2401, 4961},\r
+{6561, 1745, 4721},\r
+{5985, 1825, 5681},\r
+{6113, 2289, 5521},\r
+{6385, 1873, 5361},\r
+{6177, 1809, 5249},\r
+{6081, 1889, 5281},\r
+{6081, 1617, 5345},\r
+{6129, 1377, 5569},\r
+{6129, 1217, 5441},\r
+{5985, 1265, 5489},\r
+{6065, 1793, 5489},\r
+{6273, 1329, 5409},\r
+{6465, 1521, 5249},\r
+{6337, 1601, 5169},\r
+{6225, 1745, 5121},\r
+{6177, 1665, 5553},\r
+{5889, 2065, 5569},\r
+{6081, 1921, 5409},\r
+{6193, 2241, 5025},\r
+{6241, 2097, 5185},\r
+{5937, 2257, 5361},\r
+{6369, 1601, 5409},\r
+{6129, 2017, 5041},\r
+{6417, 1329, 5169},\r
+{5969, 1233, 5393},\r
+{5985, 1617, 6049},\r
+{6273, 1345, 5265},\r
+{6369, 1137, 5105},\r
+{5969, 1553, 5489},\r
+{6257, 1265, 5553},\r
+{5985, 1249, 5905},\r
+{6065, 1697, 5185},\r
+{6305, 2033, 4897},\r
+{6481, 1825, 5121},\r
+{6321, 1697, 5377},\r
+{6353, 1713, 5041},\r
+{6065, 2593, 5137},\r
+{6241, 1985, 5425},\r
+{6481, 2529, 4721},\r
+{6577, 1937, 4881},\r
+{6465, 1569, 5153},\r
+{6273, 1729, 5329},\r
+{6081, 2033, 5281},\r
+{6305, 1681, 5281},\r
+{6161, 1377, 5073},\r
+{5937, 1585, 5169},\r
+{5825, 2369, 6225},\r
+{6225, 1473, 5169},\r
+{6433, 1889, 4833},\r
+{6353, 1745, 4849},\r
+{6321, 2321, 4737},\r
+{6129, 2449, 5153},\r
+{6257, 2177, 4929},\r
+{6241, 2417, 4769},\r
+{6273, 2417, 5249},\r
+{6305, 2257, 5313},\r
+{6353, 1921, 5009},\r
+{6225, 2241, 5137},\r
+{6145, 1969, 5265},\r
+{6161, 2129, 5105},\r
+{6369, 2001, 5137},\r
+{6337, 1681, 5009},\r
+{6145, 1905, 5169},\r
+{6177, 2209, 5249},\r
+{6129, 1697, 5489},\r
+{6241, 1921, 5009},\r
+{6545, 1793, 4769},\r
+{6321, 2241, 5313},\r
+{6161, 2081, 5505},\r
+{6209, 2241, 5153},\r
+{6289, 2209, 4865},\r
+{6209, 2545, 5041},\r
+{6289, 2113, 5329},\r
+{6257, 2305, 5185},\r
+{6465, 2225, 5041},\r
+{6273, 1873, 5137},\r
+{6145, 1681, 5185},\r
+{6081, 1937, 5537},\r
+{6113, 1697, 5377},\r
+{6097, 1521, 5249},\r
+{6097, 1713, 5345},\r
+{5953, 1889, 5537},\r
+{6337, 1489, 5329},\r
+{6049, 1601, 5457},\r
+{6289, 1761, 5265},\r
+{6193, 2081, 5089},\r
+{6289, 2177, 5041},\r
+{6177, 2001, 5121},\r
+{6289, 1953, 5057},\r
+{6257, 2241, 5073},\r
+{6225, 2225, 5137},\r
+{6161, 2129, 5233},\r
+{6353, 1857, 4993},\r
+{6257, 1745, 5057},\r
+{6705, 1265, 6097},\r
+{5425, 2721, 5409},\r
+{6577, 1441, 4993},\r
+{6033, 1745, 5329},\r
+{6129, 1905, 5585},\r
+{5969, 1473, 5649},\r
+{6177, 1473, 5633},\r
+{6241, 865, 5201},\r
+{6321, 1121, 5153},\r
+{6609, 1345, 4865},\r
+{6353, 1057, 5297},\r
+{6305, 785, 5457},\r
+{6401, 1169, 5281},\r
+{6465, 1281, 4961},\r
+{6529, 1169, 4737},\r
+{6769, 1729, 4593},\r
+{7169, 1121, 4865},\r
+{6721, 1217, 4737},\r
+{6737, 897, 4865},\r
+{6497, 417, 5233},\r
+{6529, 609, 5025},\r
+{6625, 289, 5009},\r
+{6513, 369, 4977},\r
+{6129, 209, 5217},\r
+{6273, 177, 5377},\r
+{6481, 49, 5185},\r
+{6401, 353, 4993},\r
+{6833, 1057, 4833},\r
+{6593, 1953, 4625},\r
+{6289, 801, 4849},\r
+{6737, 897, 5473},\r
+{6257, 1665, 4833},\r
+{6577, 1921, 4881},\r
+{6465, 913, 5457},\r
+{6737, 689, 5121},\r
+{6513, 897, 4945},\r
+{6305, 1489, 5121},\r
+{6241, 1393, 5585},\r
+{6241, 513, 5569},\r
+{6241, 801, 5377},\r
+{6241, 1393, 5553},\r
+{6097, 977, 5553},\r
+{6177, 449, 5585},\r
+{6385, 1089, 5329},\r
+{6449, 1793, 4705},\r
+{6369, 2257, 4945},\r
+{6849, 1457, 5489},\r
+{6465, 1697, 4689},\r
+{6801, 2001, 4769},\r
+{6529, 2113, 4849},\r
+{6593, 1713, 4913},\r
+{6385, 1265, 5105},\r
+{6481, 1329, 5585},\r
+{5905, 1409, 5361},\r
+{6321, 1633, 5313},\r
+{6209, 689, 5473},\r
+{6113, 401, 5713},\r
+{6049, 1265, 5473},\r
+{5969, 1409, 5553},\r
+{6033, 1601, 5633},\r
+{6289, 1409, 5105},\r
+{6417, 1569, 4865},\r
+{6385, 1793, 5073},\r
+{6225, 2177, 5185},\r
+{6257, 1665, 5281},\r
+{6529, 1921, 4801},\r
+{6369, 2241, 5009},\r
+{6449, 1953, 5249},\r
+{6321, 2273, 5009},\r
+{6305, 2257, 4945},\r
+{6321, 1585, 5201},\r
+{6273, 1393, 5153},\r
+{6097, 1649, 5361},\r
+{6049, 1793, 5489},\r
+{6161, 1057, 5489},\r
+{6033, 1057, 5569},\r
+{5905, 1313, 5745},\r
+{6145, 1281, 5553},\r
+{6257, 1073, 5329},\r
+{6257, 2017, 5169},\r
+{6081, 2097, 5393},\r
+{6129, 1665, 5729},\r
+{6145, 1665, 5537},\r
+{6241, 2177, 5009},\r
+{6305, 2129, 5025},\r
+{6097, 2273, 5281},\r
+{6129, 2609, 5249},\r
+{6513, 1521, 5137},\r
+{6433, 1937, 4881},\r
+{6305, 1297, 5169},\r
+{6097, 1473, 5329},\r
+{5985, 1473, 5809},\r
+{6113, 1553, 5185},\r
+{6257, 1265, 5041},\r
+{6033, 1713, 5345},\r
+{6065, 1569, 5553},\r
+{6433, 1345, 5217},\r
+{6209, 2161, 4993},\r
+{6257, 2657, 4945},\r
+{6129, 2609, 5153},\r
+{5969, 2625, 5329},\r
+{6033, 2529, 4961},\r
+{6081, 3169, 4945},\r
+{6369, 2657, 4961},\r
+{6465, 2497, 4833},\r
+{6289, 1665, 5153},\r
+{6081, 1473, 5329},\r
+{5905, 2081, 5425},\r
+{5857, 1889, 5729},\r
+{6033, 1825, 5537},\r
+{6161, 1729, 5233},\r
+{6065, 1745, 5617},\r
+{6049, 1553, 5809},\r
+{6273, 2017, 5009},\r
+{6401, 1585, 5041},\r
+{6129, 1969, 5105},\r
+{6081, 2161, 5729},\r
+{6209, 2385, 5185},\r
+{6353, 1857, 4993},\r
+{6241, 2225, 4881},\r
+{6065, 2033, 5425},\r
+{6097, 2401, 5489},\r
+{6193, 1937, 5265},\r
+{6193, 1185, 5281},\r
+{5953, 2017, 5233},\r
+{6065, 1633, 5537},\r
+{6065, 1873, 5473},\r
+{6081, 1569, 5473},\r
+{6177, 1649, 5473},\r
+{6177, 1569, 5457},\r
+{6209, 1265, 5457},\r
+{6225, 1201, 5345},\r
+{6193, 1921, 5041},\r
+{6273, 2161, 5601},\r
+{6353, 1857, 5297},\r
+{6433, 1425, 4993},\r
+{6321, 1873, 4849},\r
+{6161, 2657, 5201},\r
+{6273, 2033, 5505},\r
+{6241, 1825, 5569},\r
+{6193, 913, 5025},\r
+{6097, 673, 4977},\r
+{6545, 1761, 5729},\r
+{6065, -111, 5601},\r
+{5969, 881, 5473},\r
+{6161, 1409, 5121},\r
+{5889, 737, 5585},\r
+{6097, 1713, 5057},\r
+{6561, 1377, 4449},\r
+{6673, 1697, 5313},\r
+{6433, 2689, 5345},\r
+{6401, 2049, 4737},\r
+{6081, 1777, 5153},\r
+{5969, 1793, 5969},\r
+{6081, 1553, 5745},\r
+{6081, 2049, 5201},\r
+{6257, 1313, 5201},\r
+{6433, 1297, 4801},\r
+{6337, 1009, 5249},\r
+{6081, 1121, 5601},\r
+{5713, 289, 6017},\r
+{5793, 417, 6113},\r
+{5729, 737, 6209},\r
+{6385, 913, 5345},\r
+{6049, 1121, 5457},\r
+{6177, 1553, 5153},\r
+{6321, 1713, 5217},\r
+{6113, 1921, 5665},\r
+{6177, 1489, 5185},\r
+{6225, 1825, 4993},\r
+{6241, 2097, 5265},\r
+{6369, 2241, 5201},\r
+{6369, 2289, 5009},\r
+{6385, 1761, 5409},\r
+{6289, 2049, 4977},\r
+{6129, 1553, 4657},\r
+{5905, 609, 5697},\r
+{5713, 785, 5905},\r
+{6193, 1073, 5553},\r
+{5761, 1233, 5873},\r
+{6129, 737, 5697},\r
+{6321, 1297, 5089},\r
+{6561, 1297, 4865},\r
+{6337, 1825, 5649},\r
+{6161, 1793, 5489},\r
+{6177, 1585, 5217},\r
+{6113, 1729, 5217},\r
+{6353, 2465, 5041},\r
+{6353, 2513, 4929},\r
+{6193, 1729, 5345},\r
+{6161, 1633, 5217},\r
+{6097, 1473, 5345},\r
+{6081, 2129, 5377},\r
+{6145, 2001, 5281},\r
+{5825, 1473, 5457},\r
+{6241, 1393, 5265},\r
+{6241, 1937, 5073},\r
+{6225, 1425, 5585},\r
+{6273, 1873, 5281},\r
+{6369, 1761, 5025},\r
+{6289, 1793, 5281},\r
+{5937, 1809, 5537},\r
+{5905, 2433, 5617},\r
+{6209, 2001, 5297},\r
+{6097, 1953, 5425},\r
+{6017, 2305, 5441},\r
+{6257, 2385, 5297},\r
+{5921, 1713, 5505},\r
+{6081, 1937, 5505},\r
+{6001, 2193, 5457},\r
+{5745, 2177, 5777},\r
+{5505, 993, 5393},\r
+{5089, 2737, 6161},\r
+{6737, 1953, 5041},\r
+{6753, 465, 5457},\r
+{6209, 961, 4657},\r
+{6849, 1057, 4817},\r
+{6641, 2289, 4801},\r
+{6593, 1617, 4785},\r
+{6401, 673, 5585},\r
+{6641, 1841, 4769},\r
+{6593, 1585, 4625},\r
+{6625, 1249, 4929},\r
+{6561, 1329, 5169},\r
+{6609, 1233, 4609},\r
+{6609, 1393, 4785},\r
+{6657, 833, 4913},\r
+{6241, 721, 5505},\r
+{6561, 593, 5473},\r
+{6561, 625, 4961},\r
+{6241, 897, 5313},\r
+{6481, 513, 5537},\r
+{6353, 369, 5313},\r
+{6257, 497, 5153},\r
+{6529, 1297, 4849},\r
+{6673, 1153, 5041},\r
+{6465, 801, 5393},\r
+{6609, 1057, 4961},\r
+{6641, 1473, 4977},\r
+{6241, 2113, 4657},\r
+{6257, 1873, 4977},\r
+{6689, 1121, 5185},\r
+{6673, 1249, 4769},\r
+{6641, 1393, 4849},\r
+{6497, 849, 5137},\r
+{6401, 977, 5505},\r
+{6289, 1249, 5457},\r
+{6305, 1185, 5249},\r
+{6081, 1633, 5457},\r
+{6161, 1361, 5569},\r
+{6353, 1633, 5009},\r
+{6545, 1601, 4961},\r
+{6337, 2081, 4865},\r
+{6401, 1601, 5169},\r
+{6385, 1569, 5185},\r
+{6577, 2737, 4769},\r
+{6321, 2001, 5009},\r
+{6321, 2529, 4897},\r
+{6337, 2161, 5121},\r
+{6305, 1937, 5233},\r
+{6193, 1409, 5393},\r
+{5665, 1777, 5585},\r
+{5889, 1457, 5857},\r
+{6097, 1505, 5489},\r
+{6065, 1585, 5425},\r
+{5953, 1697, 5473},\r
+{5921, 1361, 5777},\r
+{6049, 1569, 5377},\r
+{6369, 2049, 4929},\r
+{6561, 1985, 4977},\r
+{6001, 2481, 5185},\r
+{6145, 2065, 5217},\r
+{6273, 2161, 4881},\r
+{6177, 2305, 5137},\r
+{6177, 2465, 5409},\r
+{6193, 2433, 5345},\r
+{6337, 1985, 5057},\r
+{6065, 1745, 5265},\r
+{5873, 1665, 5649},\r
+{5649, 2049, 5905},\r
+{6209, 1761, 5233},\r
+{6145, 1297, 5249},\r
+{5921, 1601, 5617},\r
+{6081, 1873, 5729},\r
+{6257, 1825, 5137},\r
+{6385, 1857, 4801},\r
+{6033, 2545, 5537},\r
+{6257, 2465, 5377},\r
+{6289, 2033, 5137},\r
+{6465, 1905, 4833},\r
+{6593, 2353, 4737},\r
+{6289, 2289, 4961},\r
+{6353, 2273, 4785},\r
+{6417, 1537, 5137},\r
+{6257, 1617, 5137},\r
+{6209, 1345, 5393},\r
+{6001, 1697, 5249},\r
+{6241, 1505, 5377},\r
+{6001, 1281, 5425},\r
+{6017, 1137, 5537},\r
+{5793, 1377, 5921},\r
+{5777, 1185, 6001},\r
+{6257, 1409, 5169},\r
+{6273, 1793, 5201},\r
+{5889, 1873, 5521},\r
+{5809, 2161, 5425},\r
+{5921, 2065, 5409},\r
+{6097, 1841, 4993},\r
+{6305, 1761, 5473},\r
+{6209, 1857, 5649},\r
+{6449, 1393, 5217},\r
+{6209, 1121, 5361},\r
+{6273, 1041, 5361},\r
+{6065, 1633, 5345},\r
+{6321, 1297, 5777},\r
+{6353, 705, 5521},\r
+{6081, 865, 5297},\r
+{6017, 1009, 5649},\r
+{6081, 1025, 5569},\r
+{6289, 545, 5537},\r
+{6209, 1105, 5153},\r
+{6449, 1217, 5233},\r
+{6273, 1521, 5233},\r
+{6465, 1105, 5233},\r
+{6497, 1137, 4945},\r
+{6401, 1457, 5041},\r
+{6529, 1713, 5329},\r
+{6353, 1137, 5409},\r
+{6561, 1553, 5041},\r
+{6481, 1377, 5009},\r
+{6481, 1297, 5073},\r
+{6449, 721, 5345},\r
+{6305, 881, 5393},\r
+{6065, 369, 5649},\r
+{5761, 529, 5825},\r
+{5777, 721, 6129},\r
+{5585, 1217, 6081},\r
+{6449, 961, 5361},\r
+{6337, 993, 5137},\r
+{6305, 1329, 5201},\r
+{6209, 2113, 5057},\r
+{6353, 1793, 5361},\r
+{6721, 1297, 5393},\r
+{6497, 1841, 4817},\r
+{6177, 2193, 5073},\r
+{6225, 2017, 5377},\r
+{6145, 2049, 5473},\r
+{6497, 1505, 5105},\r
+{6001, 2225, 4817},\r
+{6273, 1649, 5217},\r
+{5969, 1921, 5569},\r
+{6161, 1521, 5457},\r
+{6193, 1249, 5393},\r
+{6033, 1169, 5649},\r
+{5921, 1537, 5665},\r
+{6129, 1409, 5585},\r
+{6113, 1633, 5297},\r
+{6273, 1457, 5121},\r
+{6289, 2049, 5281},\r
+{6145, 1969, 5569},\r
+{6161, 1761, 5249},\r
+{6273, 1761, 5009},\r
+{6465, 2273, 5025},\r
+{6433, 2081, 4961},\r
+{6449, 1793, 5153},\r
+{6449, 1905, 5201},\r
+{6481, 1905, 5009},\r
+{6385, 1761, 4817},\r
+{6401, 1473, 4977},\r
+{6081, 1713, 5217},\r
+{6113, 1505, 5217},\r
+{6145, 1489, 5201},\r
+{6129, 1457, 5425},\r
+{6113, 1761, 5585},\r
+{6321, 1521, 5169},\r
+{6561, 1537, 5025},\r
+{6417, 1777, 4945},\r
+{6193, 2289, 5153},\r
+{6273, 1761, 5345},\r
+{6001, 2017, 5185},\r
+{6465, 2305, 4977},\r
+{6321, 2401, 4865},\r
+{6433, 1777, 5185},\r
+{6353, 1633, 5281},\r
+{6497, 2289, 5425},\r
+{6337, 1473, 5217},\r
+{6337, 1649, 5041},\r
+{6161, 2097, 5441},\r
+{6017, 1905, 5425},\r
+{6209, 1569, 5249},\r
+{6193, 1425, 5217},\r
+{5937, 1713, 5313},\r
+{5889, 1953, 5777},\r
+{6113, 1457, 5985},\r
+{6433, 1697, 5137},\r
+{6337, 2241, 5137},\r
+{6097, 2289, 5089},\r
+{6161, 1633, 5521},\r
+{6257, 1889, 5185},\r
+{6353, 2161, 4929},\r
+{6305, 1969, 5249},\r
+{6305, 2033, 5281},\r
+{6353, 2225, 5137},\r
+{6401, 1841, 5041},\r
+{6401, 1569, 5169},\r
+{6097, 1889, 5377},\r
+{6001, 1697, 5361},\r
+{6033, 1713, 5217},\r
+{6113, 1425, 5505},\r
+{6017, 1649, 5649},\r
+{6177, 1441, 5409},\r
+{6481, 1425, 5153},\r
+{6385, 1761, 4961},\r
+{6081, 1953, 5217},\r
+{5777, 2097, 5553},\r
+{6609, 961, 5761},\r
+{6353, 2017, 4769},\r
+{6449, 2225, 5057},\r
+{6385, 1505, 5537},\r
+{6081, 1969, 5281},\r
+{6161, 497, 5553},\r
+{6449, 1121, 5329},\r
+{6177, 897, 5313},\r
+{6129, 753, 4929},\r
+{6273, -79, 5425},\r
+{6129, 305, 5505},\r
+{6033, -127, 5633},\r
+{6049, -223, 5777},\r
+{6289, 273, 5617},\r
+{6305, 113, 5377},\r
+{6433, 657, 5121},\r
+{6353, 209, 5361},\r
+{6209, 65, 5793},\r
+{6241, 593, 5345},\r
+{6561, 753, 5153},\r
+{6433, 673, 5233},\r
+{6705, 737, 5329},\r
+{6465, -335, 5345},\r
+{6161, 257, 4945},\r
+{6369, 145, 5073},\r
+{6225, 337, 5793},\r
+{5969, -463, 5697},\r
+{6065, 49, 5505},\r
+{6657, -847, 6177},\r
+{5777, 497, 5233},\r
+{6401, 545, 5649},\r
+{6449, 1057, 5137},\r
+{6561, 993, 5073},\r
+{6481, 1537, 4817},\r
+{6881, 1137, 4993},\r
+{6321, 1537, 5121},\r
+{6433, 1729, 4929},\r
+{6561, 1297, 5457},\r
+{6449, 1217, 5265},\r
+{6177, 1921, 5121},\r
+{6305, 1633, 5201},\r
+{6017, 1217, 5185},\r
+{6353, 785, 5441},\r
+{6321, 737, 5489},\r
+{6129, 977, 5201},\r
+{6193, 1329, 5137},\r
+{6257, 801, 5825},\r
+{6177, 1169, 5377},\r
+{6801, 1361, 4753},\r
+{6769, 1777, 4657},\r
+{6257, 2305, 4625},\r
+{6417, 1889, 4545},\r
+{6641, 1937, 4865},\r
+{6545, 2193, 5105},\r
+{6433, 2065, 5185},\r
+{6769, 1937, 5105},\r
+{6577, 1761, 5393},\r
+{6241, 2337, 5105},\r
+{6257, 1825, 5201},\r
+{6017, 1681, 5153},\r
+{5921, 1009, 5425},\r
+{5985, 1121, 5457},\r
+{5825, 1185, 5489},\r
+{6113, 1105, 5777},\r
+{6193, 1457, 5537},\r
+{6337, 1697, 4625},\r
+{6321, 1985, 4721},\r
+{6657, 2465, 5585},\r
+{6433, 2241, 4833},\r
+{6561, 2577, 4401},\r
+{6481, 2577, 4545},\r
+{6289, 2673, 4897},\r
+{6401, 2193, 5169},\r
+{6385, 2257, 5169},\r
+{6145, 2241, 4881},\r
+{5905, 1889, 5409},\r
+{5905, 1329, 5601},\r
+{6257, 1537, 5345},\r
+{6081, 1281, 5217},\r
+{6065, 1361, 5265},\r
+{5841, 1345, 5489},\r
+{5681, 1409, 5761},\r
+{6353, 1601, 5121},\r
+{6449, 1761, 5265},\r
+{6353, 1985, 5233},\r
+{6273, 2129, 5297},\r
+{6273, 1985, 5233},\r
+{6161, 1969, 4961},\r
+{6129, 2209, 5201},\r
+{6129, 2161, 5249},\r
+{6097, 2241, 5233},\r
+{6129, 2465, 5217},\r
+{6193, 1905, 5361},\r
+{6097, 1697, 5249},\r
+{6017, 1585, 5521},\r
+{5697, 1697, 5761},\r
+{5729, 1793, 5969},\r
+{5761, 1729, 5521},\r
+{5857, 1521, 6097},\r
+{5873, 2017, 6033},\r
+{5985, 1809, 5537},\r
+{6081, 1985, 5313},\r
+{6049, 2241, 5617},\r
+{5937, 3393, 6065},\r
+{6241, 3681, 4721},\r
+{6481, 3569, 4673},\r
+{6577, 3521, 4433},\r
+{6145, 2881, 3889},\r
+{6257, 2817, 5201},\r
+{6337, 2769, 5777},\r
+{6289, 2577, 5777},\r
+{6177, 1985, 5793},\r
+{5969, 2529, 4321},\r
+{5921, 1649, 4865},\r
+{6033, 1825, 5089},\r
+{6033, 1537, 5681},\r
+{6161, 929, 5841},\r
+{6001, 1041, 4945},\r
+{6385, 1201, 5153},\r
+{5889, 1441, 5393},\r
+{6113, 1633, 5297},\r
+{6129, 1457, 5313},\r
+{6001, 2145, 5537},\r
+{6161, 1809, 6065},\r
+{6161, 1745, 5105},\r
+{6481, 1969, 5073},\r
+{6481, 2113, 5073},\r
+{6209, 1953, 5393},\r
+{6113, 1889, 5601},\r
+{6273, 2033, 5073},\r
+{6177, 1681, 5201},\r
+{6033, 1649, 5489},\r
+{6001, 2145, 5297},\r
+{5809, 1505, 5329},\r
+{5713, 1249, 5873},\r
+{5921, 1249, 5905},\r
+{5745, 1057, 6049},\r
+{5873, 1377, 5729},\r
+{6289, 1089, 5265},\r
+{5953, 1713, 5377},\r
+{5793, 1425, 5953},\r
+{5985, 1169, 5681},\r
+{6049, 1185, 5489},\r
+{6305, 1713, 4945},\r
+{6225, 1905, 5681},\r
+{6161, 1457, 5665},\r
+{6177, 1233, 5409},\r
+{6369, 1153, 5169},\r
+{6097, 1345, 5345},\r
+{6017, 1073, 5921},\r
+{5841, 1201, 5729},\r
+{6081, 1105, 5377},\r
+{5969, 1217, 5729},\r
+{5809, 1185, 5921},\r
+{5857, 929, 5697},\r
+{6065, 2097, 5249},\r
+{6033, 2033, 5281},\r
+{6001, 2449, 5441},\r
+{6193, 1681, 5441},\r
+{6177, 1937, 5201},\r
+{6049, 1969, 5393},\r
+{6033, 1713, 5729},\r
+{6001, 2209, 5361},\r
+{6161, 1649, 5345},\r
+{6097, 1361, 5505},\r
+{5729, 1361, 5745},\r
+{5793, 1857, 5777},\r
+{6033, 1217, 5745},\r
+{5889, 1233, 5553},\r
+{5969, 1169, 5553},\r
+{6017, 1185, 5617},\r
+{5985, 1265, 5681},\r
+{6001, 1233, 5569},\r
+{6033, 1137, 5473},\r
+{5985, 2033, 5313},\r
+{5969, 1537, 5569},\r
+{6145, 1473, 5233},\r
+{6209, 1713, 5201},\r
+{6033, 1985, 5537},\r
+{6097, 1777, 5649},\r
+{6209, 1489, 5457},\r
+{6033, 1217, 5489},\r
+{6065, 1569, 5505},\r
+{6081, 1713, 5457},\r
+{6209, 1425, 5441},\r
+{6209, 945, 5393},\r
+{6145, 1169, 5489},\r
+{5937, 1569, 5569},\r
+{6145, 1441, 5569},\r
+{6225, 1569, 5265},\r
+{6353, 1441, 5025},\r
+{6209, 1937, 5521},\r
+{6177, 1873, 5569},\r
+{6145, 1953, 5137},\r
+{6337, 2145, 4897},\r
+{6337, 2081, 5137},\r
+{6225, 1857, 5345},\r
+{6321, 2017, 5281},\r
+{6209, 1633, 5249},\r
+{6113, 1745, 5377},\r
+{6177, 1809, 5297},\r
+{5905, 1169, 5617},\r
+{5825, 1505, 5665},\r
+{6001, 1601, 5617},\r
+{6033, 1969, 5505},\r
+{6113, 1153, 5585},\r
+{6257, 1793, 5041},\r
+{6225, 1617, 5137},\r
+{5937, 2689, 5121},\r
+{5521, 1345, 6049},\r
+{6609, 1329, 5889},\r
+{6577, 1729, 5457},\r
+{5617, 2225, 5537},\r
+{6753, 1521, 5489},\r
+{6433, 1073, 5569},\r
+{6497, 1617, 4961},\r
+{6097, 1329, 4785},\r
+{6049, 481, 5857},\r
+{6017, -79, 5521},\r
+{6161, 689, 5313},\r
+{6401, 81, 5393},\r
+{6241, 65, 5617},\r
+{6417, 353, 5441},\r
+{6321, 305, 5169},\r
+{6433, 577, 5057},\r
+{6241, 593, 5361},\r
+{6225, 465, 5569},\r
+{6241, 497, 5377},\r
+{6129, 497, 5553},\r
+{6177, 241, 5617},\r
+{6353, 1185, 5489},\r
+{6545, 209, 5537},\r
+{6289, -255, 5313},\r
+{6241, -191, 5409},\r
+{5889, -79, 6145},\r
+{6385, -143, 5441},\r
+{6273, 161, 5441},\r
+{6209, 257, 5393},\r
+{5873, -271, 6049},\r
+{6353, -367, 5585},\r
+{6385, 33, 5633},\r
+{6513, 1329, 4961},\r
+{6465, 1105, 4993},\r
+{6545, 993, 5105},\r
+{6369, 737, 5233},\r
+{6513, 1889, 5233},\r
+{6209, 1505, 5297},\r
+{6529, 817, 5377},\r
+{6625, 1009, 5441},\r
+{6433, 1105, 4881},\r
+{6273, 1569, 4689},\r
+{6817, 1761, 5137},\r
+{5905, 849, 5489},\r
+{6241, 1505, 5233},\r
+{6081, 1921, 5345},\r
+{6257, 1089, 5857},\r
+{5969, 401, 5617},\r
+{5921, 1249, 5361},\r
+{6209, 2145, 5041},\r
+{6337, 1825, 5521},\r
+{6177, 1489, 5665},\r
+{6113, 1425, 5313},\r
+{6289, 2289, 4817},\r
+{6177, 1233, 5521},\r
+{6081, 1921, 5425},\r
+{6417, 913, 5665},\r
+{6145, 1073, 5345},\r
+{6049, 1313, 5329},\r
+{5697, 1089, 6209},\r
+{5777, 1073, 5969},\r
+{5825, 849, 5697},\r
+{5985, 1345, 5649},\r
+{5729, 1505, 5729},\r
+{5905, 1185, 5841},\r
+{5937, 1185, 5585},\r
+{5809, 1297, 5505},\r
+{5681, 1761, 5745},\r
+{5969, 1569, 5777},\r
+{5937, 1393, 5649},\r
+{6225, 1729, 5281},\r
+{6241, 1697, 5281},\r
+{5953, 1505, 5633},\r
+{6049, 1905, 5585},\r
+{6273, 1409, 5345},\r
+{6257, 1073, 5473},\r
+{5905, 609, 5505},\r
+{5729, 497, 5665},\r
+{5665, 561, 6145},\r
+{5713, 257, 5793},\r
+{5409, 113, 6145},\r
+{5345, 913, 6401},\r
+{5825, 753, 5921},\r
+{6225, 961, 5585},\r
+{6241, 481, 5361},\r
+{5569, 593, 6065},\r
+{6049, 225, 6273},\r
+{5713, 673, 6321},\r
+{5825, 721, 5793},\r
+{5969, 977, 5441},\r
+{5889, 881, 5841},\r
+{5857, 849, 6017},\r
+{5985, 497, 5809},\r
+{5729, 865, 5873},\r
+{5841, 1089, 5745},\r
+{5649, 657, 6241},\r
+{5617, 401, 6081},\r
+{5569, 497, 6033},\r
+{5617, 481, 5905},\r
+{5537, 513, 6337},\r
+{5745, 449, 5969},\r
+{5873, 641, 5713},\r
+{6001, 785, 5473},\r
+{6001, 1265, 5601},\r
+{5969, 1041, 5809},\r
+{5969, 753, 5601},\r
+{5921, 1297, 5505},\r
+{5841, 1441, 5713},\r
+{5937, 1409, 5905},\r
+{5873, 1297, 5857},\r
+{6065, 1361, 5537},\r
+{6081, 1041, 5473},\r
+{5777, 1121, 5825},\r
+{5809, 865, 6161},\r
+{5681, 865, 5953},\r
+{5761, 529, 5873},\r
+{5681, 1041, 6337},\r
+{5665, 705, 6241},\r
+{5745, 657, 5969},\r
+{6001, 929, 5457},\r
+{6001, 1153, 5457},\r
+{6033, 1521, 5569},\r
+{5985, 817, 5713},\r
+{6017, 1329, 5377},\r
+{6161, 1809, 5361},\r
+{6049, 1633, 5569},\r
+{6001, 1345, 5601},\r
+{5953, 1313, 5633},\r
+{6049, 1473, 5569},\r
+{6001, 1105, 5569},\r
+{5617, 833, 5793},\r
+{5889, 961, 5905},\r
+{5953, 881, 5633},\r
+{5889, 673, 5617},\r
+{5793, 753, 5809},\r
+{5809, 1073, 5969},\r
+{6177, 1137, 5425},\r
+{6209, 1009, 5361},\r
+{6049, 1025, 5473},\r
+{6081, 1297, 5617},\r
+{5889, 977, 5809},\r
+{6033, 1281, 5505},\r
+{5953, 1505, 5489},\r
+{6097, 1793, 5793},\r
+{6001, 1457, 5825},\r
+{6049, 1521, 5537},\r
+{5985, 1281, 5473},\r
+{5745, 1009, 5841},\r
+{5521, 945, 6417},\r
+{6049, 1441, 5633},\r
+{5921, 1185, 5425},\r
+{5809, 1265, 5633},\r
+{5633, 1329, 6337},\r
+{5697, 1265, 5985},\r
+{6097, 1105, 5537},\r
+{6081, 1441, 5233},\r
+{5921, 2161, 5425},\r
+{6049, 1537, 5857},\r
+{6033, 1521, 5601},\r
+{6113, 1537, 5217},\r
+{6097, 1985, 5233},\r
+{6049, 1809, 5585},\r
+{6257, 1425, 5425},\r
+{6033, 1377, 5377},\r
+{6225, 1553, 5297},\r
+{5921, 1057, 5649},\r
+{5681, 1393, 6097},\r
+{5825, 913, 5713},\r
+{5985, 1025, 5489},\r
+{5761, 625, 5889},\r
+{5617, 849, 6305},\r
+{5857, 593, 6161},\r
+{5937, 977, 5457},\r
+{5985, 1489, 5393},\r
+{6065, 1425, 5553},\r
+{5937, 1217, 5985},\r
+{5969, 977, 5665},\r
+{6081, 1665, 5329},\r
+{6113, 1537, 5489},\r
+{5841, 1537, 5921},\r
+{6129, 1537, 5617},\r
+{5985, 657, 5681},\r
+{5825, 657, 5745},\r
+{5665, 1089, 5857},\r
+{5889, 1137, 6001},\r
+{5713, 657, 6033},\r
+{5793, 929, 5809},\r
+{5681, 769, 5921},\r
+{5697, 1025, 6273},\r
+{5809, 1601, 5665},\r
+{6129, 913, 5457},\r
+{5921, 657, 5489},\r
+{5713, 1921, 5585},\r
+{5825, 1489, 5889},\r
+{5825, 1249, 5585},\r
+{5841, 1361, 5521},\r
+{5921, 1521, 5921},\r
+{5825, 1905, 5825},\r
+{5953, 769, 5713},\r
+{6049, 1217, 5489},\r
+{5857, 881, 5553},\r
+{5921, 1393, 5713},\r
+{5793, 1153, 6049},\r
+{5905, 881, 5601},\r
+{5825, 737, 5761},\r
+{5681, 1105, 6065},\r
+{5649, 833, 6273},\r
+{5729, 961, 6033},\r
+{5953, 753, 5521},\r
+{5985, 1057, 5553},\r
+{5729, 2177, 5569},\r
+{6305, 433, 6561},\r
+{6273, 1345, 5137},\r
+{6257, 1361, 5345},\r
+{5905, 1249, 5505},\r
+{6209, 1009, 5393},\r
+{6033, 1361, 5265},\r
+{6401, 369, 5697},\r
+{6769, 1217, 4529},\r
+{6801, 1089, 4561},\r
+{6433, 865, 4481},\r
+{6449, 369, 5265},\r
+{6257, 81, 5457},\r
+{6321, 497, 5377},\r
+{6305, 81, 5521},\r
+{6545, 177, 5153},\r
+{6577, 97, 5025},\r
+{6609, 513, 4817},\r
+{6721, 865, 4929},\r
+{6609, 705, 5121},\r
+{6353, 241, 5345},\r
+{6241, 465, 5345},\r
+{6369, 1217, 5249},\r
+{6321, 945, 5265},\r
+{6593, 497, 5281},\r
+{6529, 737, 5089},\r
+{6897, 369, 5201},\r
+{6417, 1121, 4561},\r
+{6833, 161, 4833},\r
+{6337, -79, 5425},\r
+{6545, 49, 5137},\r
+{6369, 305, 5137},\r
+{6369, 1, 5681},\r
+{5857, 897, 5345},\r
+{6225, 657, 5809},\r
+{6385, 1041, 5233},\r
+{6689, 1137, 5281},\r
+{6497, 1569, 4881},\r
+{6337, 2225, 4497},\r
+{6081, 1377, 5089},\r
+{6609, 1633, 4721},\r
+{6465, 2017, 4641},\r
+{6593, 2065, 5073},\r
+{6481, 1313, 5217},\r
+{6465, 1265, 5585},\r
+{6465, 1505, 5313},\r
+{6353, 1905, 5489},\r
+{6385, 1729, 5777},\r
+{6257, 2145, 5921},\r
+{5409, 1489, 4737},\r
+{5121, -463, 6465},\r
+{5505, 801, 6209},\r
+{5265, 1137, 6385},\r
+{5729, 577, 5969},\r
+{5873, 321, 5777},\r
+{5761, 1553, 5569},\r
+{5857, 1697, 5793},\r
+{5889, 1073, 6385},\r
+{5841, 1409, 5969},\r
+{6049, 1249, 5441},\r
+{6209, 929, 5201},\r
+{6017, 545, 5729},\r
+{6001, 1441, 5937},\r
+{6209, 1073, 5681},\r
+{6161, 1153, 5585},\r
+{5889, 881, 5489},\r
+{5729, 833, 5825},\r
+{5777, 673, 6193},\r
+{5585, 817, 5953},\r
+{5425, 369, 6193},\r
+{5585, 481, 6193},\r
+{5793, 737, 5969},\r
+{6209, 1105, 5345},\r
+{6209, 1185, 5249},\r
+{6113, 1745, 5457},\r
+{5873, 1889, 5889},\r
+{5825, 1313, 5985},\r
+{5777, 1329, 5729},\r
+{5841, 1425, 5617},\r
+{5777, 2225, 5713},\r
+{5905, 2385, 5793},\r
+{5937, 1345, 5777},\r
+{5729, 1409, 5681},\r
+{5745, 1233, 5761},\r
+{5537, 1441, 5921},\r
+{5473, 1537, 6017},\r
+{5553, 929, 5921},\r
+{5585, 849, 6017},\r
+{5585, 1057, 6017},\r
+{5473, 673, 6401},\r
+{5537, 881, 5985},\r
+{6145, 1121, 5569},\r
+{5953, 1793, 5521},\r
+{6001, 1537, 5809},\r
+{5889, 1457, 5777},\r
+{6017, 1377, 5617},\r
+{5905, 1905, 5489},\r
+{5953, 1793, 5601},\r
+{6049, 1489, 5569},\r
+{5969, 1569, 5809},\r
+{5905, 1137, 5633},\r
+{5713, 1313, 5809},\r
+{5569, 1649, 6081},\r
+{5793, 929, 5985},\r
+{5681, 769, 5857},\r
+{5681, 961, 5793},\r
+{5729, 1345, 6001},\r
+{5617, 561, 6225},\r
+{5601, 849, 6049},\r
+{5921, 1233, 5569},\r
+{5857, 1649, 5569},\r
+{6017, 1713, 5601},\r
+{5889, 769, 5889},\r
+{5777, 1121, 5729},\r
+{5937, 1761, 5553},\r
+{5889, 1473, 5633},\r
+{5857, 1361, 5985},\r
+{6033, 1617, 5713},\r
+{6257, 1601, 5521},\r
+{6225, 1185, 5249},\r
+{6161, 1105, 5153},\r
+{6017, 849, 5297},\r
+{5633, 1169, 5937},\r
+{6113, 1393, 5473},\r
+{6257, 401, 5441},\r
+{5937, 657, 5697},\r
+{5985, 993, 5777},\r
+{5969, 1441, 5601},\r
+{6241, 1073, 5473},\r
+{5857, 1729, 5489},\r
+{6017, 1633, 5649},\r
+{6065, 1681, 5681},\r
+{6113, 1457, 5281},\r
+{6193, 1745, 5153},\r
+{6209, 1825, 5409},\r
+{6113, 1729, 5585},\r
+{5937, 1697, 5665},\r
+{6033, 1105, 5841},\r
+{6033, 2001, 5537},\r
+{6145, 1665, 5249},\r
+{6209, 865, 5297},\r
+{6017, 1377, 5601},\r
+{5793, 769, 5889},\r
+{5697, 1025, 5889},\r
+{5601, 897, 6081},\r
+{5617, 1249, 6049},\r
+{6097, 833, 5697},\r
+{6193, 1105, 5409},\r
+{6001, 1313, 5553},\r
+{6033, 1617, 5521},\r
+{5985, 1745, 5617},\r
+{6001, 1409, 5761},\r
+{6033, 1537, 5441},\r
+{6129, 1729, 5313},\r
+{6017, 1665, 5313},\r
+{5905, 1617, 5953},\r
+{5825, 1457, 5937},\r
+{6097, 1585, 5553},\r
+{5969, 1153, 5665},\r
+{5857, 1441, 5633},\r
+{5889, 1169, 5761},\r
+{5889, 1217, 5873},\r
+{5889, 881, 5793},\r
+{5633, 1089, 5985},\r
+{5649, 961, 6033},\r
+{5617, 993, 6049},\r
+{5681, 849, 6065},\r
+{5745, 1057, 5937},\r
+{5921, 1185, 5745},\r
+{5825, 945, 5729},\r
+{5841, 1249, 5665},\r
+{5889, 1441, 5681},\r
+{5905, 1329, 5809},\r
+{5857, 1249, 5697},\r
+{5937, 1489, 5665},\r
+{5809, 1681, 5937},\r
+{5889, 1873, 5665},\r
+{5921, 1505, 5697},\r
+{6065, 1489, 5361},\r
+{6049, 1265, 5409},\r
+{6017, 1489, 5489},\r
+{5937, 1201, 5617},\r
+{5745, 1265, 5937},\r
+{5777, 1281, 5873},\r
+{5937, 1265, 5649},\r
+{5745, 945, 5969},\r
+{5777, 929, 5905},\r
+{5761, 945, 5905},\r
+{5777, 961, 5793},\r
+{5921, 561, 5777},\r
+{5857, 865, 5761},\r
+{5969, 1201, 5569},\r
+{5681, 1633, 5777},\r
+{5681, 1089, 6129},\r
+{5537, 1377, 6001},\r
+{5825, 1617, 5777},\r
+{5697, 1601, 5841},\r
+{5745, 1441, 5953},\r
+{5729, 1313, 5985},\r
+{5921, 1377, 5681},\r
+{5841, 1521, 5729},\r
+{5793, 929, 5969},\r
+{5585, 1601, 5937},\r
+{5761, 1281, 5921},\r
+{5697, 945, 5873},\r
+{5697, 881, 5921},\r
+{5713, 1073, 5841},\r
+{5585, 993, 5841},\r
+{5489, 961, 5985},\r
+{5889, 785, 6321},\r
+{5745, 1057, 6145},\r
+{6529, 1441, 5249},\r
+{6321, 561, 4401},\r
+{6497, 913, 5089},\r
+{6161, 513, 5553},\r
+{6449, 353, 5233},\r
+{6401, 417, 5121},\r
+{6273, 561, 5217},\r
+{6577, 273, 5249},\r
+{6465, -335, 5025},\r
+{6417, 97, 5041},\r
+{6497, -319, 5185},\r
+{6209, -559, 5345},\r
+{6001, -719, 5697},\r
+{5937, -1039, 6241},\r
+{5905, -895, 5745},\r
+{5985, -687, 5425},\r
+{5985, -1103, 5601},\r
+{6193, -911, 5393},\r
+{6257, -943, 5313},\r
+{6433, -351, 5233},\r
+{6129, 65, 4865},\r
+{6369, 49, 5937},\r
+{6305, -543, 5537},\r
+{6577, -383, 5345},\r
+{6785, 737, 5185},\r
+{6673, 289, 4593},\r
+{5969, 1313, 4817},\r
+{7969, 145, 4897},\r
+{6497, 1393, 5057},\r
+{6593, -591, 5169},\r
+{5921, -159, 5201},\r
+{6113, -367, 5761},\r
+{6129, 33, 5649},\r
+{6577, -447, 5361},\r
+{6177, 769, 5073},\r
+{6241, 209, 5761},\r
+{6209, -79, 6321},\r
+{6305, 209, 5713},\r
+{6577, 881, 4945},\r
+{6497, 1489, 4785},\r
+{6321, 657, 5313},\r
+{6241, 625, 5601},\r
+{6529, 929, 5377},\r
+{6449, 1489, 4977},\r
+{6193, 1585, 4961},\r
+{6273, 625, 5825},\r
+{6257, 1457, 5345},\r
+{6529, 785, 5249},\r
+{6289, 913, 4929},\r
+{6081, 385, 4897},\r
+{5809, -223, 6113},\r
+{5889, -271, 6049},\r
+{5761, -463, 5905},\r
+{5905, 33, 5793},\r
+{5921, 17, 5729},\r
+{5873, -111, 6049},\r
+{6081, -175, 5777},\r
+{6065, 65, 5697},\r
+{6193, 769, 5169},\r
+{6305, 865, 5121},\r
+{6337, 337, 5505},\r
+{6177, 417, 5697},\r
+{6241, 881, 5297},\r
+{6065, 1009, 5297},\r
+{6017, 545, 5745},\r
+{6193, 257, 5649},\r
+{6433, 641, 5361},\r
+{6401, 705, 5265},\r
+{6161, -399, 5473},\r
+{6033, 289, 5745},\r
+{6113, 257, 5553},\r
+{6161, -175, 5601},\r
+{6193, -335, 5569},\r
+{6113, 81, 5361},\r
+{6113, 465, 5393},\r
+{6001, 641, 5313},\r
+{6161, 2049, 6881},\r
+{6257, 1105, 5473},\r
+{6129, 1761, 5313},\r
+{6353, 2529, 5249},\r
+{6353, 2737, 5377},\r
+{6545, 2257, 4897},\r
+{6497, 2497, 5281},\r
+{6353, 2977, 4929},\r
+{6353, 2129, 3681},\r
+{6449, 2593, 4081},\r
+{6001, 1505, 5937},\r
+{6353, 1425, 5169},\r
+{6049, 1665, 5457},\r
+{5953, 1409, 5489},\r
+{6017, 977, 5617},\r
+{5617, 753, 5793},\r
+{5761, 897, 5713},\r
+{5825, 577, 5841},\r
+{5937, 753, 5649},\r
+{5793, 353, 5425},\r
+{6001, 225, 6049},\r
+{6353, 417, 5169},\r
+{6353, 577, 5521},\r
+{5921, 913, 5377},\r
+{6017, 1153, 5025},\r
+{6193, 1537, 6129},\r
+{5937, 1393, 5921},\r
+{5969, 1265, 5553},\r
+{6081, 1505, 5505},\r
+{6097, 1729, 5329},\r
+{6129, 1921, 5729},\r
+{5937, 1617, 5521},\r
+{6113, 1665, 5297},\r
+{6241, 1505, 5297},\r
+{6273, 1857, 5249},\r
+{5921, 1185, 5729},\r
+{5889, 1073, 5905},\r
+{6145, 1025, 5569},\r
+{6049, 961, 5457},\r
+{5889, 1089, 5665},\r
+{5745, 1057, 5921},\r
+{5889, 289, 5969},\r
+{6049, 929, 5585},\r
+{6129, 1105, 5425},\r
+{6049, 977, 5569},\r
+{5873, 1361, 5697},\r
+{6161, 1393, 5569},\r
+{6033, 1457, 5473},\r
+{6241, 1649, 5233},\r
+{6209, 2001, 5185},\r
+{6161, 1681, 5345},\r
+{6097, 1697, 5473},\r
+{6161, 1777, 5297},\r
+{6273, 1681, 5297},\r
+{6225, 1793, 5313},\r
+{6017, 1553, 5441},\r
+{5921, 1201, 5745},\r
+{5889, 1425, 5697},\r
+{6033, 1073, 5633},\r
+{5905, 1089, 5489},\r
+{5921, 897, 5681},\r
+{5745, 977, 6049},\r
+{5937, 1265, 5681},\r
+{6097, 865, 5473},\r
+{6081, 1217, 5441},\r
+{5873, 1281, 5713},\r
+{5889, 1697, 5729},\r
+{6129, 1585, 5553},\r
+{6097, 1489, 5425},\r
+{6097, 1457, 5409},\r
+{6049, 1633, 5473},\r
+{6033, 1697, 5569},\r
+{6129, 1505, 5441},\r
+{6129, 1537, 5473},\r
+{6177, 1761, 5345},\r
+{6193, 1585, 5361},\r
+{6145, 1393, 5441},\r
+{5841, 1473, 5697},\r
+{6065, 1233, 5585},\r
+{6129, 1073, 5425},\r
+{6001, 1073, 5553},\r
+{5969, 1185, 5649},\r
+{6049, 1089, 5697},\r
+{6129, 817, 5569},\r
+{6033, 1201, 5409},\r
+{6049, 993, 5553},\r
+{5969, 1361, 5553},\r
+{6017, 1313, 5633},\r
+{6225, 1409, 5313},\r
+{6209, 1217, 5297},\r
+{6193, 1457, 5329},\r
+{6193, 1633, 5345},\r
+{6033, 1505, 5665},\r
+{6129, 1537, 5441},\r
+{6145, 1553, 5409},\r
+{6161, 1473, 5457},\r
+{6161, 1281, 5553},\r
+{5969, 1361, 5617},\r
+{5985, 1281, 5617},\r
+{6033, 1249, 5553},\r
+{6001, 1041, 5585},\r
+{5969, 1137, 5681},\r
+{5889, 1089, 5825},\r
+{5921, 1185, 5761},\r
+{6113, 993, 5649},\r
+{6129, 1153, 5441},\r
+{6049, 1121, 5601},\r
+{6017, 1137, 5601},\r
+{6081, 1265, 5457},\r
+{6081, 1265, 5521},\r
+{6081, 1233, 5601},\r
+{5937, 1425, 5633},\r
+{6049, 1361, 5601},\r
+{6017, 1345, 5665},\r
+{5969, 1265, 5665},\r
+{6113, 1697, 5473},\r
+{6177, 1617, 5425},\r
+{6129, 1025, 5521},\r
+{5921, 1121, 5713},\r
+{5841, 1089, 5825},\r
+{6033, 1185, 5649},\r
+{5985, 1105, 5601},\r
+{5905, 1089, 5729},\r
+{5857, 737, 5873},\r
+{5857, 897, 5921},\r
+{5809, 849, 5809},\r
+{6129, 1073, 5505},\r
+{6001, 673, 5569},\r
+{6113, 1073, 5569},\r
+{6097, 1281, 5569},\r
+{6097, 1441, 5457},\r
+{6113, 1233, 5329},\r
+{5409, 1953, 5489},\r
+{6065, 1281, 5969},\r
+{5905, 1969, 5569},\r
+{6449, 1313, 4977},\r
+{6529, 1329, 4401},\r
+{6657, 945, 5041},\r
+{6273, 1121, 5473},\r
+{6369, 417, 5169},\r
+{6321, 385, 5345},\r
+{6289, 705, 5185},\r
+{6433, 417, 5329},\r
+{6161, 225, 5505},\r
+{6257, 417, 5121},\r
+{6657, 177, 4881},\r
+{6337, 241, 5393},\r
+{6369, 657, 5457},\r
+{6609, 849, 5089},\r
+{6577, 433, 5169},\r
+{6465, 913, 5169},\r
+{6641, 865, 4849},\r
+{6545, 1201, 4897},\r
+{6401, 945, 5265},\r
+{6449, 801, 5233},\r
+{6689, 929, 5025},\r
+{6625, 1041, 4945},\r
+{6577, 897, 4929},\r
+{6385, 417, 5201},\r
+{6289, 289, 5601},\r
+{6145, 241, 5521},\r
+{6193, 609, 5361},\r
+{6209, 353, 5537},\r
+{6385, 401, 5585},\r
+{6673, 609, 5265},\r
+{6273, 465, 5217},\r
+{6545, 513, 5105},\r
+{6369, 1185, 4977},\r
+{6465, 913, 5121},\r
+{6433, 753, 5249},\r
+{6305, 1137, 5265},\r
+{6321, 1313, 5249},\r
+{6289, 1313, 5441},\r
+{6321, 1057, 5393},\r
+{6257, 993, 5345},\r
+{6321, 1217, 5169},\r
+{6401, 817, 5201},\r
+{6465, 577, 5313},\r
+{6257, 481, 5537},\r
+{6401, 769, 5441},\r
+{6305, 513, 5249},\r
+{6001, 929, 5441},\r
+{5969, 849, 5825},\r
+{5953, 785, 6177},\r
+{6097, 609, 5777},\r
+{6097, 1281, 5425},\r
+{6081, 1489, 5617},\r
+{6145, 1345, 5553},\r
+{6289, 1185, 5073},\r
+{6225, 1313, 5169},\r
+{6433, 1409, 4961},\r
+{6113, 1521, 5537},\r
+{6225, 1265, 5681},\r
+{6161, 705, 5665},\r
+{6353, 1041, 5585},\r
+{5953, 1377, 5521},\r
+{6097, 1265, 5473},\r
+{6081, 1265, 5489},\r
+{5681, 881, 6193},\r
+{5857, 1521, 5953},\r
+{6209, 1457, 4977},\r
+{5969, 1537, 5617},\r
+{5889, 1313, 5793},\r
+{6049, 1553, 5937},\r
+{6065, 1425, 5745},\r
+{6001, 1681, 5521},\r
+{5537, 1937, 5777},\r
+{5889, 1937, 6273},\r
+{6289, 1329, 5489},\r
+{6257, 1201, 5057},\r
+{6241, 1425, 4721},\r
+{6209, 1937, 4929},\r
+{6049, 913, 5601},\r
+{5969, 1201, 5905},\r
+{6097, 1313, 5681},\r
+{6097, 1201, 5681},\r
+{5937, 1169, 5825},\r
+{5857, 1281, 5857},\r
+{6097, 1073, 5601},\r
+{6001, 1009, 5521},\r
+{5985, 1137, 5713},\r
+{6033, 1137, 5601},\r
+{5857, 1217, 5665},\r
+{5905, 1009, 5889},\r
+{5969, 1265, 5745},\r
+{5985, 1313, 5553},\r
+{6209, 1649, 5313},\r
+{6049, 1377, 5633},\r
+{6305, 1505, 5313},\r
+{6385, 1457, 5105},\r
+{6289, 1601, 5089},\r
+{6353, 1729, 5265},\r
+{6225, 1713, 5457},\r
+{6289, 1505, 5425},\r
+{6289, 1617, 5313},\r
+{6273, 1665, 5233},\r
+{6081, 1409, 5441},\r
+{6145, 1553, 5361},\r
+{5985, 977, 5665},\r
+{5953, 1169, 5809},\r
+{5825, 865, 5889},\r
+{5905, 1073, 5921},\r
+{5809, 945, 5921},\r
+{5777, 673, 5857},\r
+{5873, 897, 5745},\r
+{5921, 545, 5745},\r
+{5953, 865, 5761},\r
+{5985, 1041, 5713},\r
+{5921, 1025, 5873},\r
+{5969, 1025, 5745},\r
+{5969, 849, 5633},\r
+{5953, 1105, 5569},\r
+{5969, 1457, 5665},\r
+{5985, 1393, 5633},\r
+{6033, 1137, 5713},\r
+{6097, 961, 5697},\r
+{6209, 1025, 5329},\r
+{6113, 641, 5553},\r
+{6049, 1089, 5649},\r
+{6001, 753, 5729},\r
+{5953, 817, 5729},\r
+{5969, 721, 5777},\r
+{5825, 1073, 5809},\r
+{5841, 897, 5905},\r
+{5873, 1009, 5809},\r
+{6001, 801, 5713},\r
+{5937, 865, 5713},\r
+{5969, 1185, 5633},\r
+{5921, 1281, 5665},\r
+{5969, 1521, 5601},\r
+{6033, 1457, 5681},\r
+{6001, 1473, 5537},\r
+{6033, 1569, 5441},\r
+{5969, 1617, 5537},\r
+{5969, 1809, 5681},\r
+{6017, 1585, 5665},\r
+{6177, 1729, 5409},\r
+{6145, 1649, 5281},\r
+{6017, 1841, 5473},\r
+{5857, 1585, 5569},\r
+{5761, 1297, 5809},\r
+{5905, 1585, 5761},\r
+{5969, 1201, 5729},\r
+{5825, 1409, 5601},\r
+{5681, 1313, 5953},\r
+{5729, 1473, 6097},\r
+{5857, 1025, 5969},\r
+{5953, 1185, 5585},\r
+{5969, 1377, 5537},\r
+{5985, 1633, 5633},\r
+{5921, 1457, 5745},\r
+{5889, 1601, 5729},\r
+{5873, 1409, 5617},\r
+{5905, 1777, 5649},\r
+{5777, 1969, 5681},\r
+{5905, 1889, 5649},\r
+{6017, 1873, 5553},\r
+{5985, 1761, 5617},\r
+{6033, 1553, 5537},\r
+{5937, 1521, 5569},\r
+{5841, 1313, 5681},\r
+{5841, 1585, 5729},\r
+{5921, 1265, 5761},\r
+{5937, 1569, 5329},\r
+{5953, 1025, 5809},\r
+{5873, 1553, 5905},\r
+{5921, 945, 5953},\r
+{5841, 1249, 5713},\r
+{5729, 1889, 5521},\r
+{5857, 2337, 5569},\r
+{6193, 2129, 5393},\r
+{5825, 2497, 5473},\r
+{6113, 1985, 5361},\r
+{5921, 2097, 5473},\r
+{5953, 2209, 5537},\r
+{6193, 1953, 5361},\r
+{6065, 2113, 5377},\r
+{6001, 1953, 5441},\r
+{5905, 1857, 5553},\r
+{5793, 1873, 5665},\r
+{5761, 1345, 5729},\r
+{5777, 865, 5473},\r
+{5729, 1073, 5649},\r
+{5553, 1569, 6065},\r
+{5665, 1169, 6177},\r
+{5873, 1473, 5425},\r
+{5985, 1729, 5169},\r
+{6033, 1809, 5281},\r
+{5617, 1745, 6097},\r
+{5793, 1841, 5441},\r
+{5777, 2081, 5185},\r
+{5793, 1905, 5809},\r
+{5457, 1841, 5905},\r
+{5617, 1569, 6129},\r
+{5809, 1633, 5921},\r
+{5889, 1889, 5729},\r
+{5873, 1553, 5537},\r
+{5793, 1217, 5457},\r
+{5713, 1265, 6241},\r
+{5777, 1201, 5857},\r
+{5745, 1153, 5761},\r
+{5841, 1041, 5873},\r
+{6049, 1025, 5665},\r
+{6257, 945, 5665},\r
+{6065, 849, 5281},\r
+{6321, 1089, 5185},\r
+{6369, 1505, 5169},\r
+{6401, 977, 5425},\r
+{6097, 913, 5681},\r
+{6289, 1105, 5345},\r
+{6449, 1441, 5201},\r
+{6305, 1137, 5121},\r
+{6465, 1329, 5073},\r
+{6369, 897, 5393},\r
+{6497, 1073, 5249},\r
+{6433, 1121, 4929},\r
+{6241, 1121, 5281},\r
+{6193, 641, 5569},\r
+{6177, 433, 5553},\r
+{6113, 513, 5393},\r
+{6161, 705, 5457},\r
+{6273, 289, 5649},\r
+{6193, 337, 5665},\r
+{6401, 577, 5329},\r
+{6561, 385, 5217},\r
+{6305, 1121, 4929},\r
+{6065, 2193, 5425},\r
+{6769, -47, 5345},\r
+{6449, 1889, 5041},\r
+{6417, 1409, 5345},\r
+{6177, 1521, 5281},\r
+{6001, 1873, 5393},\r
+{6417, 1249, 5057},\r
+{6225, 945, 4929},\r
+{6241, 1041, 4945},\r
+{5969, 1601, 5329},\r
+{5665, 1889, 6081},\r
+{5649, 2417, 6609},\r
+{5745, 1361, 5585},\r
+{5985, 1441, 5473},\r
+{5953, 2289, 5537},\r
+{5985, 1393, 5377},\r
+{5921, 2081, 5441},\r
+{5905, 2241, 5601},\r
+{5985, 1921, 5489},\r
+{6097, 1969, 5249},\r
+{6081, 2161, 5169},\r
+{6097, 2065, 5329},\r
+{6097, 2241, 5585},\r
+{6097, 2241, 5393},\r
+{6065, 1809, 5409},\r
+{5969, 1633, 5377},\r
+{5937, 1745, 5537},\r
+{5953, 1985, 5601},\r
+{5921, 1793, 5553},\r
+{5889, 1729, 5569},\r
+{5793, 1809, 5937},\r
+{5841, 1793, 5873},\r
+{6129, 1665, 5505},\r
+{6241, 1361, 5361},\r
+{6049, 2081, 5105},\r
+{5937, 2273, 5249},\r
+{6033, 2161, 5633},\r
+{5921, 2017, 5905},\r
+{5889, 2033, 5713},\r
+{6001, 2097, 5217},\r
+{5825, 2337, 5553},\r
+{5953, 2129, 5633},\r
+{6017, 2065, 5409},\r
+{6017, 1777, 5457},\r
+{6065, 2273, 5297},\r
+{5889, 1873, 5537},\r
+{5809, 1825, 5713},\r
+{5745, 1425, 5841},\r
+{5777, 1777, 5745},\r
+{5889, 1265, 5585},\r
+{5809, 1681, 5777},\r
+{5873, 1553, 5777},\r
+{6033, 1505, 5665},\r
+{6065, 1393, 5489},\r
+{5953, 2017, 5329},\r
+{6129, 1553, 5553},\r
+{6065, 1185, 5521},\r
+{6049, 1297, 5489},\r
+{6017, 1585, 5377},\r
+{6033, 1889, 5329},\r
+{5953, 1921, 5537},\r
+{6113, 1681, 5473},\r
+{6177, 1825, 5297},\r
+{6113, 1697, 5329},\r
+{5985, 1505, 5425},\r
+{5937, 1457, 5649},\r
+{5857, 1425, 5921},\r
+{5825, 1185, 5681},\r
+{5809, 1377, 5745},\r
+{5713, 1393, 5873},\r
+{5745, 1217, 6049},\r
+{5825, 1281, 5777},\r
+{5937, 1169, 5649},\r
+{5905, 1185, 5585},\r
+{5873, 1345, 5665},\r
+{5857, 1377, 5713},\r
+{5873, 1633, 5873},\r
+{5889, 1473, 5745},\r
+{5841, 1249, 5601},\r
+{5873, 1729, 5617},\r
+{5793, 1761, 5633},\r
+{5777, 1441, 5969},\r
+{5873, 1681, 5713},\r
+{5985, 1665, 5505},\r
+{5969, 1601, 5617},\r
+{5873, 1537, 5617},\r
+{5857, 1297, 5841},\r
+{5761, 1313, 5969},\r
+{6017, 1377, 5409},\r
+{5953, 1265, 5473},\r
+{5889, 1329, 5537},\r
+{5873, 1265, 5809},\r
+{5953, 1169, 5697},\r
+{6049, 1249, 5489},\r
+{6113, 1361, 5441},\r
+{6065, 1601, 5441},\r
+{5873, 1585, 5553},\r
+{5809, 1617, 5761},\r
+{5841, 1857, 5665},\r
+{5873, 1793, 5489},\r
+{5969, 1809, 5505},\r
+{5857, 1873, 5633},\r
+{5969, 2225, 5409},\r
+{6017, 1617, 5537},\r
+{6049, 1697, 5521},\r
+{5953, 1505, 5553},\r
+{5905, 1761, 5489},\r
+{6001, 1601, 5825},\r
+{5905, 1393, 5553},\r
+{5921, 1441, 5505},\r
+{5777, 1265, 5633},\r
+{5681, 1681, 5889},\r
+{5985, 1521, 5617},\r
+{6065, 1169, 5441},\r
+{5969, 1425, 5473},\r
+{5841, 1521, 5649},\r
+{5777, 1857, 5809},\r
+{5793, 1745, 5953},\r
+{5825, 1745, 5553},\r
+{5841, 1841, 5553},\r
+{5889, 2017, 5569},\r
+{5793, 1873, 5681},\r
+{5937, 1889, 5729},\r
+{5921, 1985, 5505},\r
+{6017, 1921, 5441},\r
+{5905, 1649, 5681},\r
+{5905, 1585, 5697},\r
+{5937, 1761, 5569},\r
+{6097, 1409, 5265},\r
+{6017, 1377, 5441},\r
+{5905, 1377, 5649},\r
+{5793, 1665, 5921},\r
+{6001, 1521, 5649},\r
+{6065, 1473, 5361},\r
+{6033, 1313, 5521},\r
+{5873, 1777, 5697},\r
+{5841, 1649, 5857},\r
+{5761, 1569, 6001},\r
+{5841, 1793, 5409},\r
+{5777, 1729, 5537},\r
+{5809, 1713, 5713},\r
+{5713, 1905, 5777},\r
+{5761, 1681, 5969},\r
+{5889, 1937, 5569},\r
+{5857, 1713, 5553},\r
+{5777, 1521, 5761},\r
+{5745, 1457, 5857},\r
+{5745, 1777, 5745},\r
+{5825, 1393, 5777},\r
+{5825, 1377, 5777},\r
+{5825, 1345, 5761},\r
+{5745, 1681, 5841},\r
+{5697, 1361, 5841},\r
+{5761, 1377, 5905},\r
+{5937, 1409, 5633},\r
+{5873, 1617, 5601},\r
+{5745, 1857, 5521},\r
+{5793, 1793, 5601},\r
+{5793, 1969, 5889},\r
+{5857, 2049, 5489},\r
+{5889, 2161, 5377},\r
+{5873, 2385, 5409},\r
+{5873, 2193, 5585},\r
+{5793, 2001, 5681},\r
+{5985, 2401, 5297},\r
+{6001, 2289, 5377},\r
+{5873, 2289, 5409},\r
+{5857, 1729, 5617},\r
+{5825, 2017, 5601},\r
+{5889, 1761, 5569},\r
+{5841, 1713, 5521},\r
+{5793, 1601, 5601},\r
+{5825, 1873, 5793},\r
+{5841, 1521, 5857},\r
+{5921, 1441, 5633},\r
+{5905, 1793, 5601},\r
+{5809, 1745, 5713},\r
+{5809, 1793, 5713},\r
+{5905, 1761, 5745},\r
+{5921, 1745, 5473},\r
+{5713, 1745, 5425},\r
+{5793, 2129, 5585},\r
+{6689, 897, 6161},\r
+{6065, 2913, 5681},\r
+{6097, 1521, 5537},\r
+{6097, 1761, 5457},\r
+{6273, 1153, 5441},\r
+{6273, 1521, 5361},\r
+{6257, 1889, 5137},\r
+{6033, 1329, 5009},\r
+{6033, 209, 5729},\r
+{6113, 177, 5713},\r
+{5953, 609, 5761},\r
+{6129, 481, 5713},\r
+{5937, 481, 5665},\r
+{6129, 449, 5409},\r
+{6177, 369, 5457},\r
+{6177, 609, 5489},\r
+{6225, 305, 5569},\r
+{6097, 401, 5537},\r
+{6145, 305, 5649},\r
+{6081, 625, 5457},\r
+{6113, 705, 5457},\r
+{6081, 561, 5473},\r
+{6273, 609, 5633},\r
+{6433, 481, 5281},\r
+{6385, 529, 5217},\r
+{5873, 593, 5569},\r
+{6657, -1983, 5969},\r
+{5873, 1185, 5345},\r
+{6289, -607, 5681},\r
+{5489, 1441, 5313},\r
+{6033, -63, 5921},\r
+{6081, 1009, 5745},\r
+{5889, 1041, 6129},\r
+{6241, 817, 5345},\r
+{6145, 689, 5313},\r
+{6209, 1121, 5377},\r
+{6321, 1121, 5665},\r
+{6321, 1505, 5297},\r
+{6321, 1537, 5185},\r
+{6161, 2001, 4721},\r
+{6513, 2097, 5041},\r
+{6513, 1777, 5313},\r
+{6289, 1793, 5361},\r
+{5921, 2241, 4977},\r
+{6369, 2865, 4865},\r
+{5953, 3041, 5185},\r
+{6273, 3457, 4753},\r
+{6097, 3841, 4641},\r
+{6241, 3521, 4577},\r
+{6145, 2705, 4753},\r
+{6113, 2305, 4481},\r
+{5729, 2353, 4609},\r
+{5777, 3169, 7057},\r
+{6065, 2049, 4977},\r
+{6049, 1953, 5073},\r
+{5857, 2673, 5393},\r
+{5873, 2625, 5633},\r
+{5953, 2289, 5633},\r
+{5761, 2657, 5377},\r
+{5841, 2577, 5217},\r
+{5841, 2529, 5377},\r
+{5857, 2433, 5585},\r
+{5857, 2849, 5585},\r
+{5937, 2385, 5329},\r
+{5905, 2449, 5201},\r
+{6001, 2337, 5329},\r
+{5841, 2273, 5473},\r
+{5793, 2273, 5505},\r
+{5761, 2209, 5649},\r
+{5809, 2209, 5633},\r
+{5745, 2033, 5649},\r
+{5745, 2177, 5745},\r
+{5633, 2177, 5793},\r
+{5921, 2049, 5569},\r
+{5937, 1681, 5489},\r
+{5873, 1905, 5553},\r
+{5761, 2401, 5553},\r
+{5697, 2545, 5633},\r
+{5697, 2481, 5665},\r
+{5809, 2305, 5697},\r
+{5873, 2417, 5313},\r
+{5809, 2593, 5377},\r
+{5745, 2449, 5553},\r
+{5793, 2465, 5713},\r
+{5905, 2689, 5313},\r
+{5969, 2065, 5457},\r
+{5841, 2081, 5489},\r
+{5761, 1921, 5569},\r
+{5713, 2289, 5569},\r
+{5665, 2401, 5825},\r
+{5745, 1857, 5585},\r
+{5857, 1713, 5521},\r
+{5761, 1969, 5601},\r
+{5857, 2065, 5761},\r
+{5761, 1969, 5713},\r
+{6033, 1361, 5521},\r
+{5873, 2209, 5505},\r
+{5761, 2289, 5345},\r
+{5713, 2497, 5249},\r
+{5905, 2801, 5649},\r
+{6001, 2529, 5057},\r
+{6001, 2625, 5041},\r
+{6033, 2817, 5185},\r
+{5873, 2913, 5297},\r
+{5857, 2561, 5505},\r
+{5825, 2337, 5585},\r
+{5857, 2065, 5361},\r
+{5905, 2193, 5377},\r
+{5873, 1985, 5665},\r
+{5793, 1969, 5585},\r
+{5905, 1889, 5617},\r
+{5729, 1905, 5745},\r
+{5857, 1633, 5697},\r
+{5777, 1889, 5681},\r
+{5969, 2129, 5441},\r
+{6113, 1617, 5617},\r
+{6065, 1649, 5569},\r
+{5809, 2161, 5377},\r
+{5889, 2369, 5441},\r
+{5905, 1825, 5745},\r
+{6001, 2529, 5377},\r
+{6033, 2321, 5089},\r
+{6065, 2129, 5313},\r
+{5985, 2209, 5441},\r
+{6001, 2273, 5553},\r
+{6033, 1889, 5601},\r
+{5937, 1617, 5361},\r
+{5905, 1841, 5409},\r
+{5953, 1777, 5601},\r
+{6001, 1793, 5761},\r
+{5873, 1457, 5633},\r
+{5857, 1857, 5457},\r
+{5905, 1393, 5761},\r
+{5889, 1345, 5697},\r
+{5985, 1313, 5489},\r
+{6017, 1521, 5409},\r
+{5889, 2577, 5217},\r
+{5937, 2673, 5457},\r
+{5921, 2913, 5393},\r
+{5889, 2737, 5265},\r
+{6001, 2433, 5025},\r
+{6017, 2625, 5121},\r
+{5953, 2721, 5265},\r
+{6033, 2881, 5297},\r
+{6049, 2593, 5217},\r
+{6065, 2529, 5217},\r
+{5985, 2513, 5121},\r
+{5825, 2593, 5489},\r
+{5889, 2289, 5633},\r
+{5873, 2081, 5505},\r
+{5761, 1985, 5553},\r
+{5841, 2129, 5553},\r
+{5857, 2209, 5729},\r
+{5969, 1953, 5281},\r
+{5953, 2129, 5265},\r
+{5985, 2177, 5441},\r
+{5937, 2497, 5473},\r
+{6017, 2337, 5265},\r
+{6001, 2289, 5137},\r
+{5889, 2625, 5281},\r
+{5889, 2561, 5441},\r
+{5921, 2369, 5585},\r
+{6177, 2465, 5201},\r
+{5953, 2497, 5249},\r
+{5953, 2273, 5345},\r
+{6001, 2193, 5393},\r
+{5793, 2113, 5521},\r
+{5873, 1921, 5697},\r
+{5777, 1729, 5697},\r
+{5793, 2113, 5745},\r
+{5921, 1777, 5841},\r
+{5873, 2033, 5665},\r
+{5985, 1793, 5521},\r
+{5953, 1745, 5553},\r
+{5889, 2273, 5377},\r
+{5889, 2465, 5457},\r
+{6049, 2225, 5521},\r
+{5889, 2033, 5473},\r
+{5873, 2273, 5393},\r
+{5857, 2577, 5585},\r
+{5953, 2433, 5697},\r
+{6017, 2417, 5425},\r
+{6033, 2289, 5169},\r
+{5921, 2065, 5329},\r
+{5889, 1953, 5729},\r
+{5857, 2113, 5617},\r
+{6033, 1793, 5345},\r
+{5921, 2097, 5201},\r
+{5873, 1681, 5729},\r
+{5825, 2113, 5697},\r
+{5953, 1921, 5489},\r
+{5985, 1761, 5425},\r
+{6081, 1665, 5393},\r
+{6001, 2289, 5569},\r
+{6049, 2401, 5537},\r
+{6017, 2273, 5457},\r
+{5921, 1809, 5297},\r
+{5937, 2225, 5329},\r
+{5985, 2433, 5585},\r
+{5953, 2049, 5425},\r
+{6033, 2193, 5297},\r
+{5969, 2113, 5393},\r
+{5857, 1809, 5505},\r
+{5921, 1969, 5537},\r
+{5937, 2353, 5265},\r
+{5985, 2033, 5393},\r
+{5841, 2257, 5409},\r
+{5777, 2049, 5649},\r
+{5809, 1873, 5857},\r
+{5921, 1793, 5393},\r
+{5713, 2785, 5745},\r
+{6017, 1777, 5649},\r
+{5857, 2785, 5313},\r
+{6065, 2049, 5937},\r
+{6033, 2113, 5281},\r
+{6001, 1985, 5153},\r
+{5905, 2417, 5505},\r
+{5713, 2305, 5713},\r
+{5905, 2641, 5921},\r
+{6497, 1777, 4417},\r
+{6497, 673, 4625},\r
+{6721, 1057, 4785},\r
+};\r
+static const uint32_t duration_HRD[] = \r
+{\r
+41,\r
+39,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+40,\r
+40,\r
+80,\r
+40,\r
+40,\r
+};\r
+static const uint32_t frame_HRD[] =\r
+{      \r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+151,\r
+152,\r
+153,\r
+154,\r
+155,\r
+156,\r
+157,\r
+158,\r
+159,\r
+160,\r
+161,\r
+162,\r
+163,\r
+164,\r
+165,\r
+166,\r
+167,\r
+168,\r
+169,\r
+170,\r
+171,\r
+172,\r
+173,\r
+174,\r
+175,\r
+176,\r
+177,\r
+178,\r
+179,\r
+180,\r
+181,\r
+182,\r
+183,\r
+184,\r
+185,\r
+186,\r
+187,\r
+188,\r
+189,\r
+190,\r
+191,\r
+192,\r
+193,\r
+194,\r
+195,\r
+196,\r
+197,\r
+198,\r
+199,\r
+200,\r
+201,\r
+202,\r
+203,\r
+204,\r
+205,\r
+206,\r
+207,\r
+208,\r
+209,\r
+210,\r
+211,\r
+212,\r
+213,\r
+214,\r
+215,\r
+216,\r
+217,\r
+218,\r
+219,\r
+220,\r
+221,\r
+222,\r
+223,\r
+224,\r
+225,\r
+226,\r
+227,\r
+228,\r
+229,\r
+230,\r
+231,\r
+232,\r
+233,\r
+234,\r
+235,\r
+236,\r
+237,\r
+238,\r
+239,\r
+240,\r
+241,\r
+242,\r
+243,\r
+244,\r
+245,\r
+246,\r
+247,\r
+248,\r
+249,\r
+250,\r
+251,\r
+252,\r
+253,\r
+254,\r
+255,\r
+0,\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,\r
+62,\r
+63,\r
+64,\r
+65,\r
+66,\r
+67,\r
+68,\r
+69,\r
+70,\r
+71,\r
+72,\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+106,\r
+107,\r
+108,\r
+109,\r
+110,\r
+111,\r
+112,\r
+113,\r
+114,\r
+115,\r
+116,\r
+117,\r
+118,\r
+119,\r
+120,\r
+121,\r
+122,\r
+123,\r
+124,\r
+125,\r
+126,\r
+127,\r
+128,\r
+129,\r
+130,\r
+131,\r
+132,\r
+133,\r
+134,\r
+135,\r
+136,\r
+137,\r
+138,\r
+139,\r
+140,\r
+141,\r
+142,\r
+143,\r
+144,\r
+145,\r
+146,\r
+147,\r
+148,\r
+149,\r
+150,\r
+};\r
+\r
+static const uint8_t touch_HRD[] = \r
+{\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+1,\r
+};\r
+\r
+static const int32_t Expo_time[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{0, 256, 40},\r
+{0, 240, 40},\r
+{0, 224, 40},\r
+{0, 208, 40},\r
+{0, 208, 40},\r
+{0, 192, 40},\r
+{0, 184, 40},\r
+{0, 176, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+{0, 168, 40},\r
+};\r
+\r
+\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pxialg.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pxialg.h
new file mode 100644 (file)
index 0000000..ac2b98c
--- /dev/null
@@ -0,0 +1,698 @@
+#ifndef PXIALG_H__\r
+#define PXIALG_H__\r
+#include "stdint.h"\r
+#include "pxivar.h"\r
+\r
+#define FW                             1\r
+\r
+#define FW_DEBUG  0\r
+#if ( FW == 0 )\r
+#undef FW_DEBUG\r
+#define FW_DEBUG  0\r
+#endif\r
+\r
+//#define STRIIV\r
+\r
+#if FW == 1\r
+#define PXIALG_API\r
+#else\r
+#ifdef PXIALG_EXPORTS\r
+#define PXIALG_API             __declspec(dllexport)\r
+#else\r
+#define PXIALG_API             __declspec(dllimport)\r
+#endif\r
+#endif\r
+/*\r
+typedef struct {\r
+       uint8_t                                         frame_count;\r
+       uint32_t                                        time;\r
+       uint8_t                                         touch_flag;\r
+       uint32_t                                        nf_ppg_channel;\r
+       uint32_t                                        nf_ppg_per_channel;\r
+       int32_t                                         *ppg_data;\r
+       uint32_t                                        nf_mems;\r
+       int16_t                                         *mems_data;\r
+} pah8series_data_t;\r
+\r
+typedef enum {\r
+       FLAG_DATA_READY                         = 0,\r
+       FLAG_DATA_NOT_READY,\r
+       FLAG_DATA_LOSS,\r
+       FLAG_NO_TOUCH,\r
+       FLAG_DATA_ERROR,\r
+       FLAG_POOR_SIGNAL,\r
+       FLAG_FIFO_ERROR,\r
+       FLAG_TIMMING_ERROR,\r
+       FLAG_MEMS_ERROR,\r
+       FLAG_HR_UPDATE                          = 16,\r
+       FLAG_SG_UPDATE,\r
+} PXI_STATUS_FLAG;\r
+\r
+typedef enum {\r
+       _quick_report_rms_gs_th         = 0,\r
+       _hr_speed_mode,\r
+       _support_cal_motion_idx_enhancement_enh,\r
+       _rsv1,\r
+       _set_switch_mems_fft_max_energy_th,\r
+       _set_switch_mems_large_energy_num_th,\r
+       _set_switch_mn_fft_energy_lo_thr,\r
+       _set_switch_mn_fft_energy_hi_thr,\r
+\r
+       _ppg_large_energy_num_th,\r
+       _max_hr_idx_th,\r
+       _min_hr_idx_th,\r
+       _ppg_fft_total_peak_num_th,\r
+       _mems_large_energy_num_th,\r
+       _mems_fft_max_energy_th,\r
+       _support_signal_grade_motion_detection_enh,\r
+       _support_signal_grade_check_signal_lelvel_enh,\r
+       _support_signal_grade_large_energy_num_enh,\r
+       _rsv2,\r
+       _rsv3,\r
+       _set_reg_shake_count_th0,\r
+} PXI_PARAM_SET;\r
+\r
+typedef enum {\r
+       _rms_gs                                         = 0,\r
+       _signal_level,\r
+       _cal_motion_idx,\r
+       _is_prediction_hr,\r
+       _get_switch_mems_fft_max_energy_th,\r
+       _get_switch_mems_large_energy_num_th,\r
+       _get_switch_mn_fft_energy_lo_thr,\r
+       _get_switch_mn_fft_energy_hi_thr,\r
+\r
+       _hr_sample_count,\r
+       _ppg_large_energy_num,\r
+       _signal_grade_motion_frm,\r
+       _ppg_fft_max_energy_idx,\r
+       _ppg_fft_total_peak_num,\r
+       _mems_large_energy_num,\r
+       _mems_fft_max_energy,\r
+       _grade,\r
+       _signal_grade_hr_to_low_frm,\r
+       _flag_signal_grade_ready_go,\r
+       _motion_flag,\r
+       _get_reg_shake_count_th0,\r
+} PXI_PARAM_GET;\r
+\r
+typedef enum {\r
+       MemsLargeEnergyNumTh            = 0,\r
+       MemsFftMaxEnergyTh,\r
+       QuickReportRmsGsTh,\r
+       SupportSigGradeMotionDetection,\r
+       PpgLargeEnergyNumTh,\r
+       SupportSigGradeLargeEnergyNumEnh,\r
+       SupportSigGradeLargeEnergyNumTh,\r
+       SigGradeThr,\r
+       SupportSigGradeCheckSigLevel,\r
+       FlagCheckNotStableFirstHR,\r
+       MaxHrDefinition,\r
+       MinHrDefinition,\r
+} PXI_PARAM2;\r
+*/\r
+\r
+#if FW == 1\r
+/**\r
+ * @brief When HRD and MEMS data are ready, call this function to do the algorithm processing\r
+ *\r
+ * @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+ * @param[in] MEMS_Data  Pointer to the buffer where MEMS data (3*sizeof(float) Bytes) is stored.\r
+ *\r
+ * @return Return one of the PXI_STATUS_FLAG types.\r
+ */\r
+PXIALG_API int32_t PxiAlg_ProcessByTime(unsigned char *HRD_Data, float *MEMS_Data, float time);\r
+PXIALG_API int32_t PxiAlg_Process(unsigned char *HRD_Data, float *MEMS_Data);\r
+\r
+/**\r
+ * @brief Call this function to get Heart Rate\r
+ *\r
+ * @param[out] hr   Pointer to a float variable where heart rate is stored\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_HrGet(float *hr);\r
+\r
+\r
+PXIALG_API void PxiAlg_FlagInitialSignalNoiseGet(uint8_t *flag);\r
+/**\r
+ * @brief Call this function to feed Algorithm raw data(19 Bytes), and get Signal Grade and Heart Rate\r
+ *\r
+ * @param[in] pixart_19_byte_data   Pointer to a arrag where raw data is stored\r
+ *     Format: 13 bytes PPG + G-sensor X_L[13] + X_H[14] + Y_L[15] + Y_H[16] + Z_L[17] + Z_H[18]\r
+ * @param[out] grade   Pointer to a float variable where signal grade is stored.\r
+ * @param[out] heart_rate   Pointer to a float variable where heart rate is stored\r
+ *\r
+ * @return status bit field, combinatoin of the list below\r
+ * 1 << FLAG_DATA_READY,\r
+ * 1 << FLAG_DATA_NOT_READY,\r
+ * 1 << FLAG_DATA_LOSS,\r
+ * 1 << FLAG_NO_TOUCH,\r
+ * 1 << FLAG_DATA_ERROR,\r
+ * 1 << FLAG_POOR_SIGNAL,\r
+ * 1 << FLAG_FIFO_ERROR,\r
+ * 1 << FLAG_TIMMING_ERROR,\r
+ * 1 << FLAG_MEMS_ERROR,\r
+ * 1 << FLAG_HR_UPDATE,\r
+ * 1 << FLAG_SG_UPDATE,\r
+ */\r
+PXIALG_API uint32_t PxiAlg_HRM(uint8_t *pixart_19_byte_data, float *grade, float * heart_rate);\r
+#else\r
+/**\r
+ * @brief When HRD, MEMS, and ECG data are ready, call this function to do the algorithm processing\r
+ *\r
+ * @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+ * @param[in] MEMS_Data  Pointer to the buffer where MEMS data (12 Bytes) is stored.\r
+ * @param[in] ECG_Data   Pointer to the buffer where ECG data (4 Bytes) is stored.\r
+ *\r
+ * @return Return one of the PXI_STATUS_FLAG types.\r
+ */\r
+PXIALG_API int32_t PxiAlg_Process(unsigned char *HRD_Data, float *MEMS_Data, float ECG_Data);\r
+\r
+/**\r
+ * @brief When HRD, MEMS, ECG data, and time interval are ready, call this function to do the algorithm processing\r
+ *\r
+ * @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+ * @param[in] MEMS_Data  Pointer to the buffer where MEMS data (12 Bytes) is stored.\r
+ * @param[in] ECG_Data   Pointer to the buffer where ECG data (4 Bytes) is stored.\r
+ * @param[in] time              Time interval.\r
+ *\r
+ * @return Return one of the PXI_STATUS_FLAG types.\r
+ */\r
+PXIALG_API int32_t PxiAlg_ProcessByTime(unsigned char *HRD_Data, float *MEMS_Data, float ECG_Data, float time);\r
+\r
+/**\r
+ * @brief Call this function to get Heart Rate\r
+ *\r
+ * @param[out] hr   Pointer to a float variable where heart rate is stored\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_HrGet(float *hr);\r
+\r
+PXIALG_API void PxiAlg_FlagInitialSignalNoiseGet(uint8_t *flag);\r
+\r
+/**\r
+ * @brief Call this            function to get output\r
+ *\r
+ * @param[out] output  Pointer to a SHr_motion_plot variable where output information is stored\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API int32_t PxiAlg_OutputGet(void *output);\r
+\r
+/**\r
+ * @brief Call this            function to get a specific parameter\r
+ *\r
+ * @param[out] param   Pointer to the start address of the variable of parameter list\r
+ * @param[in]  offset  Offset of the parameter variable\r
+ * @param[in]  size            Type size of the parameter\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_ParamGet(uint8_t *param, int32_t offset, int32_t size);\r
+\r
+/**\r
+ * @brief Call this            function to set a specific parameter\r
+ *\r
+ * @param[in] offset   Offset of the parameter variable\r
+ * @param[in] size             Type size of the parameter\r
+ * @param[in] param            Pointer to the start address of the variable of parameter list\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_ParamSet(int32_t offset, int32_t size, uint8_t *param);\r
+#endif\r
+\r
+/**\r
+* @brief When HRD, MEMS, and Expo data are ready, call this function to do the algorithm processing\r
+*\r
+* @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+* @param[in] MEMS_Data  Pointer to the buffer where MEMS data (12 Bytes) is stored.\r
+* @param[in] expo       Exposure Time.\r
+*\r
+* @return Return one of the PXI_STATUS_FLAG types.\r
+*/\r
+PXIALG_API int32_t PxiAlg_Process_Expo(unsigned char *HRD_Data, float *MEMS_Data, int expo);\r
+\r
+/**\r
+ * @brief Call this function to determine the version of the algorithm\r
+ *\r
+ *\r
+ * @return Version of the algorithm\r
+ */\r
+PXIALG_API int32_t PxiAlg_Version(void);\r
+\r
+/**\r
+ * @brief Call this funtion to get Ready_Flag\r
+ *\r
+ * @return Return Ready_Flag\r
+ */\r
+PXIALG_API unsigned char PxiAlg_GetReadyFlag(void);\r
+\r
+/**\r
+ * @brief Call this funtion to get Motion_Flag\r
+ *\r
+ * @return Return Motion_Flag\r
+ */\r
+PXIALG_API unsigned char PxiAlg_GetMotionFlag(void);\r
+\r
+\r
+/**\r
+* @brief Call this function to get force flag\r
+*\r
+* @return force_flag\r
+*/\r
+PXIALG_API unsigned char PxiAlg_GetForceFlag(void);\r
+\r
+/**\r
+ * @brief Call this funtion to get Timeout_Flag\r
+ *\r
+ * @return Return Timeout_Flag\r
+ */\r
+PXIALG_API unsigned char PxiAlg_GetTimeoutFlag(void);\r
+\r
+/**\r
+ * @brief Call this function to set PPG buffer pointer and size\r
+ *\r
+ * @param[in] ppg_buffer   Pointer to a float buffer where the PPG data would be stored\r
+ * @param[in] size   PPG buffer size\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_SetPPGBuffer(float *ppg_buffer, int32_t size);\r
+\r
+/**\r
+ * @brief Call this function to set algorithm parameters\r
+ *\r
+ * @param[in] hr_param   Pointer to a "HR_Param" sturcture where the parameters are stored.\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_SetParam(void *hr_param);\r
+\r
+/**\r
+ * @brief Call this function to set data\r
+ *\r
+ * @param[in] data   Pointer to an algorithm-dependent data\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_SetData(void *data);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the Output Data Rate of PPG Sensor\r
+ *\r
+ * @param[in] odr                      The Output Data Rate of PPG Sensor. Only 10,20,40,160 and 200 ODR are supported.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetODR(int32_t odr);\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the Timeout Length of PPG Sensor\r
+ *\r
+ * @param[in] t                        The Timeout Length of PPG Sensor. Unit: second.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetTimeoutLength(int32_t t);\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the Quality Threshold of PPG Sensor\r
+ *\r
+ * @param[in] th                       The Quality Threshold of PPG Sensor. Range: 0.0 ~ 1.0\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetQualityThreshold(float th);\r
+\r
+/**\r
+* @brief Call this function to notify algorithm the HR smooth weight of PPG Sensor\r
+*\r
+* @param[in] w                 The weight. Range: 0.0 ~ 1.0\r
+*\r
+* @return 1 for success. 0 for failure.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_SetHRSmoothWeight(float w);\r
+\r
+/**\r
+* @brief Call this function to notify algorithm the length of process window of PPG Sensor\r
+*\r
+* @param[in] t                 The normal time window.\r
+* @param[in] t_fast            The fast time window.\r
+*\r
+* @return 1 for success. 0 for failure.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_SetProcWindow(float t, float t_fast);\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the number of PPG sample to skip\r
+ *\r
+ * @param[in] num                      The number\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetSkipSampleNum(int num);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the MEMS Scale of Motion Sensor\r
+ *\r
+ * @param[in] scale                    The MEMS Scale of Motion Sensor. 0: +-2G, 1: +-4G, 2: +-8G, and 3: +-16G\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetMemsScale(int scale);\r
+PXIALG_API uint8_t PxiAlg_SetMemsScaleBase(int scale, int th);\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time length to force hr to update\r
+ *\r
+ * @param[in] t                        The time length\r
+ * @param[in] ub               The upper bound\r
+ * @param[in] lb               The lower bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceOutput(int t, int ub, int lb);\r
+\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm force hr to output\r
+ *\r
+ * @param[in] t                        The time length\r
+ * @param[in] ub               The upper bound\r
+ * @param[in] lb               The lower bound\r
+ * @param[in] link_flag        To link with normal output\r
+ * @param[in] w                    Smoothing weight between force and normal\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceOutputLink(int t, int ub, int lb, int link_flag, float w);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm normal hr to output\r
+ *\r
+ * @param[in] ub                   The upper bound\r
+ * @param[in] lb                   The lower bound\r
+ * @param[in] static_flag      First normal output at static\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetNormalOutput(int ub, int lb, int static_flag);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time to force hr to output\r
+ *\r
+ * @param[in] t                        The duration\r
+ * @param[in] bpm              The amplitude\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceRipple(int t, int bpm);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time to force hr to output\r
+ *\r
+ * @param[in] ch               The ppg channel selection\r
+ * @param[in] flag             The resample flag\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetPackage(int ch, int flag);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time length to force hr to update\r
+ *\r
+ * @param[in] t                        The time length\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceUpdateTimeLength(int t);\r
+/**\r
+ * @brief Call this function to notify algorithm the time to force hr to output\r
+ *\r
+ * @param[in] t                        The time length\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceOutputTime(int t);\r
+/**\r
+ * @brief Call this function to notify algorithm the bound of hr\r
+ *\r
+ * @param[in] ub                       The upper bound\r
+ * @param[in] lb                       The lower bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetFullHRBound(int ub, int lb);\r
+/**\r
+ * @brief Call this function to notify algorithm the bound of first hr\r
+ *\r
+ * @param[in] ub                       The upper bound\r
+ * @param[in] lb                       The lower bound\r
+ * @param[in] t                        The time length to keep this bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetFirstHRBound(int ub, int lb, int t);\r
+\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the MEMS Energy Threshold of Motion Sensor\r
+ *\r
+ * @param[in] lower                    The MEMS energy lower threshold\r
+ * @param[in] upper                    The MEMS energy upper threshold\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetMemsEnergyThrd(int lower, int upper);\r
+\r
+/**\r
+ * @brief Call this function to set PPG Signal Grade Threshold\r
+ *\r
+ * @param[in] threshold                The PPG Signal Grade Threshold. Its value ranges from 0 to 100.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetSigGradeThrd(float thrd);\r
+\r
+/**\r
+ * @brief Call this function to set parameters of PPG Signal Grade\r
+ *\r
+ * @param[in] frm_thrd         The PPG Signal Grade Frame Threshold.\r
+ * @param[in] rep_count                The PPG Signal Grade Repetitive Counter.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetSigGradeParam(int16_t frm_thrd, int16_t rep_count);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable fast output mode\r
+ *\r
+ * @param[in] en               The flag of fast output mode.\r
+ */\r
+\r
+PXIALG_API void PxiAlg_EnableFastOutput(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable motion mode\r
+ *\r
+ * @param[in] en               The flag of motion mode.\r
+ */\r
+PXIALG_API void PxiAlg_EnableMotionMode(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable auto mode\r
+ *\r
+ * @param[in] en               The flag of auto mode.\r
+ */\r
+PXIALG_API void PxiAlg_EnableAutoMode(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable tracking mode after fast output\r
+ *\r
+ * @param[in] en               The flag of tracking mode.\r
+ */\r
+PXIALG_API void PxiAlg_EnableTrackingAfterFastOut(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable mems0 signal grade mode\r
+ *\r
+ * @param[in] en               1 : enable. 0 : disable.\r
+ */\r
+PXIALG_API void PxiAlg_EnableMEMS0SigGrade(uint8_t en);\r
+\r
+//PXIALG_API void PxiAlg_EnableMEMS0SigGrade(uint8_t en, uint8_t idx);\r
+//// idx = 0: PxiAlg_EnableFastOutput(uint8_t en);\r
+//// idx = 1: PxiAlg_EnableMotionMode(uint8_t en);\r
+//// idx = 2: PxiAlg_EnableAutoMode(uint8_t en);\r
+//// idx = 3: PxiAlg_EnableTrackingAfterFastOut(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to get PPG Signal Grade\r
+ *\r
+ * @param[out] grade   Pointer to a float variable where signal grade is stored.\r
+ *\r
+ * @return  Return 1 when Signal Grade is ready. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_GetSigGrade(float *grade);\r
+\r
+/**\r
+ * @brief Call this function to get the alarm flag of fast output\r
+ *\r
+ * @param[out] flag            The alarm flag of fast output\r
+ *\r
+ * @return  Return 1 when the flag is set. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_GetFastOutAlarmFlag(void);\r
+\r
+/**\r
+ * @brief Call this function to get the alarm flag of signal bad\r
+ *\r
+ * @param[out] flag            The alarm flag of fast output\r
+ *\r
+ * @return  Return 1 when the flag is set. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_GetSignalBadAlarm(void);\r
+\r
+/**\r
+ * @brief Call this function to open algorithm\r
+ */\r
+#if FW == 1\r
+PXIALG_API uint8_t PxiAlg_Open_Mem(void *mem);\r
+#else\r
+PXIALG_API void PxiAlg_Open(void);\r
+#endif\r
+\r
+/**\r
+ * @brief Call this function to close algorithm\r
+ */\r
+PXIALG_API void PxiAlg_Close(void);\r
+\r
+/**\r
+ * @brief Call this function to initialize 200Hz low-pass filter\r
+ */\r
+PXIALG_API void PxiAlg_LPF200Hz_Init(void);\r
+\r
+/**\r
+ * @brief Call this function to process 200Hz low-pass filter\r
+ */\r
+PXIALG_API float PxiAlg_LPF200Hz_Process(float data);\r
+\r
+/**\r
+ * @brief Call this function to get PPG Signal Level\r
+ *\r
+ * @param[out] grade   Pointer to a float variable where signal level is stored.\r
+ *\r
+ * @return  Return 1 when Signal Level is ready. Otherwise, return 0.\r
+ */\r
+#ifndef REDUCE_MORE_CODE_SIZE\r
+PXIALG_API uint8_t PxiAlg_Get_Signal_Level(float *level);\r
+#endif\r
+/**\r
+ * @brief Call this function to enable/disable Check_Not_Stable_First_HR\r
+ *\r
+ * @param[in] 1 : enable, 0: disable\r
+ */\r
+PXIALG_API void PxiAlg_Check_Not_Stable_First_HR(uint8_t check); \r
+\r
+/**\r
+ * @brief Call this function to set Signal_Grade_Large_Energy_Num_Th_Lo\r
+ *\r
+ * @param[in] Threshold.\r
+ *\r
+ */\r
+PXIALG_API void PxiAlg_Set_Signal_Grade_Large_Energy_Num_Th_Lo(uint8_t th) ;\r
+\r
+/**\r
+ * @brief Call this function to Set SportMode\r
+ *\r
+ * @@param[in] en      0: disable 1: enable\r
+ *\r
+ * @return  Return 1 when Set Signal Grade Large Energy Num Threshold is ready. Otherwise, return 0.\r
+ */\r
+PXIALG_API void PxiAlg_SetSportMode(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to Set Signal Grade Large Energy Num Threshold\r
+ *\r
+ * @@param[in] th      => threshold\r
+ *\r
+ * @return  Return 1 when Set Signal Grade Large Energy Num Threshold is ready. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_Set_Signal_Grade_Large_Energy_Num_Th(uint8_t th);\r
+\r
+\r
+/**\r
+ * @brief Call this function to Set Algorithm Parameters\r
+ *\r
+ * @@param[in] index - index of parameters, param - parameter value\r
+ *\r
+ * @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_Set_Parameter(uint32_t index, float param);\r
+\r
+/**\r
+ * @brief Call this function to Get Algorithm Parameters\r
+ *\r
+ * @@param[in] index - index of parameters, *param - pointer to parameter value\r
+ *\r
+ * @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_Get_Parameter(uint32_t index, float *param);\r
+\r
+/**\r
+* @brief Call this function to Set Algorithm Parameters (2nd Version)\r
+*\r
+* @@param[in] index - index of parameters, param - parameter value\r
+*\r
+* @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_Set_Parameter2(uint32_t index, float param);\r
+\r
+/**\r
+* @brief Call this function to Get Algorithm Parameters (2nd Version)\r
+*\r
+* @@param[in] index - index of parameters, *param - pointer to parameter value\r
+*\r
+* @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_Get_Parameter2(uint32_t index, float *param);\r
+\r
+\r
+\r
+PXIALG_API uint8_t PxiAlg_Set_Cal_Flag_HR_Trust_Energy_Ratio(float fValue);\r
+PXIALG_API uint8_t PxiAlg_Set_Cal_Flag_HR_Trust_Large_Energy_Num_Th(uint16_t fValue);\r
+PXIALG_API uint8_t PxiAlg_Get_Cal_Flag_HR_Trust_Energy_Ratio(float *fValue);\r
+PXIALG_API uint8_t PxiAlg_Get_Cal_Flag_HR_Trust_Large_Energy_Num_Th(uint16_t *fValue);\r
+\r
+PXIALG_API uint8_t PxiAlg_Get_Flag_HR_Trust(uint8_t *flag);\r
+\r
+#if (ANDROID_JNI==1)\r
+PXIALG_API uint8_t PxiAlg_Get_ParameterName(uint32_t index, const char **param);\r
+#endif\r
+\r
+PXIALG_API uint8_t PxiAlg_DecodeProcess(uint32_t data, int touch_flag, float time_in);\r
+PXIALG_API uint8_t  PxiAlg_Entrance_0(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t  PxiAlg_Entrance(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t  PxiAlg_EntranceD(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint32_t PxiAlg_Query_Mem_Size();\r
+PXIALG_API uint8_t PxiAlg_GetHrUpdateFlag();\r
+\r
+PXIALG_API void PxiAlg_SetData_Seg(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t PxiAlg_Process_Seg(uint8_t *is_finished);\r
+PXIALG_API uint8_t PxiAlg_ProcessD_Seg(uint8_t *is_finished);\r
+#endif /* PXIALG_H__ */\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pxivar.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/pxivar.h
new file mode 100644 (file)
index 0000000..0f1dd76
--- /dev/null
@@ -0,0 +1,96 @@
+#ifndef PXIVAR_H__\r
+#define PXIVAR_H__\r
+\r
+#include "stdint.h"\r
+\r
+#ifndef pah8series_data_t\r
+typedef struct {\r
+       uint8_t                                         frame_count;\r
+       uint32_t                                        time;\r
+       uint8_t                                         touch_flag;\r
+       uint32_t                                        nf_ppg_channel;\r
+       uint32_t                                        nf_ppg_per_channel;\r
+       int32_t                                         *ppg_data;\r
+       uint32_t                                        nf_mems;\r
+       int16_t                                         *mems_data;\r
+} pah8series_data_t;\r
+#endif\r
+\r
+typedef enum {\r
+       FLAG_DATA_READY                         = 0,\r
+       FLAG_DATA_NOT_READY,\r
+       FLAG_DATA_LOSS,\r
+       FLAG_NO_TOUCH,\r
+       FLAG_DATA_ERROR,\r
+       FLAG_POOR_SIGNAL,\r
+       FLAG_FIFO_ERROR,\r
+       FLAG_TIMMING_ERROR,\r
+       FLAG_MEMS_ERROR,\r
+       FLAG_HR_UPDATE                          = 16,\r
+       FLAG_SG_UPDATE,\r
+} PXI_STATUS_FLAG;\r
+\r
+typedef enum {\r
+       _quick_report_rms_gs_th         = 0,\r
+       _hr_speed_mode,\r
+       _support_cal_motion_idx_enhancement_enh,\r
+       _rsv1,\r
+       _set_switch_mems_fft_max_energy_th,\r
+       _set_switch_mems_large_energy_num_th,\r
+       _set_switch_mn_fft_energy_lo_thr,\r
+       _set_switch_mn_fft_energy_hi_thr,\r
+\r
+       _ppg_large_energy_num_th,\r
+       _max_hr_idx_th,\r
+       _min_hr_idx_th,\r
+       _ppg_fft_total_peak_num_th,\r
+       _mems_large_energy_num_th,\r
+       _mems_fft_max_energy_th,\r
+       _support_signal_grade_motion_detection_enh,\r
+       _support_signal_grade_check_signal_lelvel_enh,\r
+       _support_signal_grade_large_energy_num_enh,\r
+       _rsv2,\r
+       _rsv3,\r
+       _set_reg_shake_count_th0,\r
+} PXI_PARAM_SET;\r
+\r
+typedef enum {\r
+       _rms_gs                                         = 0,\r
+       _signal_level,\r
+       _cal_motion_idx,\r
+       _is_prediction_hr,\r
+       _get_switch_mems_fft_max_energy_th,\r
+       _get_switch_mems_large_energy_num_th,\r
+       _get_switch_mn_fft_energy_lo_thr,\r
+       _get_switch_mn_fft_energy_hi_thr,\r
+\r
+       _hr_sample_count,\r
+       _ppg_large_energy_num,\r
+       _signal_grade_motion_frm,\r
+       _ppg_fft_max_energy_idx,\r
+       _ppg_fft_total_peak_num,\r
+       _mems_large_energy_num,\r
+       _mems_fft_max_energy,\r
+       _grade,\r
+       _signal_grade_hr_to_low_frm,\r
+       _flag_signal_grade_ready_go,\r
+       _motion_flag,\r
+       _get_reg_shake_count_th0,\r
+} PXI_PARAM_GET;\r
+\r
+typedef enum {\r
+       MemsLargeEnergyNumTh            = 0,\r
+       MemsFftMaxEnergyTh,\r
+       QuickReportRmsGsTh,\r
+       SupportSigGradeMotionDetection,\r
+       PpgLargeEnergyNumTh,\r
+       SupportSigGradeLargeEnergyNumEnh,\r
+       SupportSigGradeLargeEnergyNumTh,\r
+       SigGradeThr,\r
+       SupportSigGradeCheckSigLevel,\r
+       FlagCheckNotStableFirstHR,\r
+       MaxHrDefinition,\r
+       MinHrDefinition,\r
+} PXI_PARAM2;\r
+\r
+#endif /* PXIVAR_H__ */\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/test_library_HRD.c b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_hr/V303009/test_library_HRD.c
new file mode 100644 (file)
index 0000000..7085701
--- /dev/null
@@ -0,0 +1,112 @@
+\r
+#include "pah8009_testpattern_HRD.h"\r
+// platform\r
+#include <stdlib.h>\r
+#include "pah800x_main.h"\r
+#include "pah800x_bsp.h"\r
+#include <math.h>  \r
+//#include "nrf_delay.h"\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+\r
+\r
+\r
+void test_library_HRD(void)\r
+{\r
+       int i               = 0;\r
+  void *hr_pBuffer = NULL;\r
+       static ppg_mems_data_t ppg_mems_data_alg;\r
+\r
+       sRaw_Data_13Bytes hr_data;\r
+                \r
+       \r
+       // static  Hr-V301009\r
+               \r
+               PxiAlg_Close();\r
+               int32_t version = PxiAlg_Version();\r
+               DEBUG_PRINT("HR_Version = %d \r\n", version);\r
+       \r
+\r
+               uint32_t Query_Mem_Size = PxiAlg_Query_Mem_Size();\r
+               DEBUG_PRINT("HR_Mem_Size = %d \r\n", Query_Mem_Size);\r
+               \r
+               hr_pBuffer = malloc(Query_Mem_Size);\r
+               \r
+   \r
+               if(!PxiAlg_Open_Mem(hr_pBuffer))\r
+                               DEBUG_PRINT("PxiAlg_Open_Mem fail \n");\r
+       \r
+                       \r
+               PxiAlg_SetQualityThreshold(0.35f); \r
+               PxiAlg_SetHRSmoothWeight(0.9f); \r
+               PxiAlg_SetProcWindow(5.0f, 5.0f); \r
+         PxiAlg_SetTimeoutLength(30.0f);\r
+               PxiAlg_SetMemsScale(1);               //MEMS 2/4/8/16G : 0/1/2/3\r
+               PxiAlg_SetSkipSampleNum(10); \r
+               PxiAlg_SetMemsScaleBase(1, 0);  //MEMS 2/4/8/16G : 0/1/2/3\r
+               PxiAlg_SetForceOutputLink(0, 150, 40, 1, 0.9f); \r
+               PxiAlg_SetNormalOutput(200, 40, 0); \r
+               PxiAlg_SetForceRipple(3, 1); \r
+    //PxiAlg_SetForceOutput(30, 120, 45);\r
+               //PxiAlg_SetForceOutputTime(10);\r
+               PxiAlg_SetPackage(0, 1);\r
+       \r
+       \r
+         \r
+//-----------------------------------------------//\r
+          \r
+               LOG_PRINT("ARRAY_SIZE = %d\n",array_szie(PAH8009_rawdata_HRD));\r
+//******************************************************************            \r
+          \r
+               float   hr         = 0.0f;\r
+               float   hr_grader  = 0.0f;\r
+         \r
+//*******************************************************************           \r
+                \r
+          //nrf_delay_ms(50);\r
+                \r
+\r
+               for( i = 0 ; i <array_szie(PAH8009_rawdata_HRD) ; i ++)\r
+               {\r
+                         \r
+                                               memset(&hr_data, 0, sizeof(hr_data));\r
+                       hr_data.loss        = 1;\r
+                       hr_data.rawData     = (uint32_t)PAH8009_rawdata_HRD[i][1] ;\r
+                                   //LOG_PRINT("rawData = %d \n ", hr_data.rawData);\r
+                       hr_data.non_zero1   = 1;\r
+                       hr_data.non_zero2   = 2;\r
+                       hr_data.non_zero3   = 3;\r
+                       hr_data.frame_count = frame_HRD[i];\r
+                                               //LOG_PRINT("frame_count = %d  ", hr_data.frame_count);\r
+                       hr_data.time        = duration_HRD[i];  \r
+                                               //LOG_PRINT("time = %d  ", hr_data.time);\r
+                       hr_data.rsv         = 0;\r
+                       hr_data.touch       = touch_HRD[i] > 0 ? 0x80 : 0x00;\r
+                                               //LOG_PRINT("touch = %d  ", hr_data.touch);\r
+                       hr_data.rsv2        = 0;\r
+\r
+                                               int exposure_time      = Expo_time[i][1];\r
+            //LOG_PRINT("exposure_time = %d  \n",exposure_time);\r
+\r
+                                               ppg_mems_data_alg.MEMS_Data[0]=PAH8009_mems_HRD[i][0];\r
+                                               ppg_mems_data_alg.MEMS_Data[1]=PAH8009_mems_HRD[i][1]; \r
+                                               ppg_mems_data_alg.MEMS_Data[2]=PAH8009_mems_HRD[i][2]; \r
+                                               \r
+                                               int32_t ret = PxiAlg_Process_Expo((uint8_t*)&hr_data, ppg_mems_data_alg.MEMS_Data, exposure_time);\r
+\r
+            //LOG_PRINT("ret_HR %d  \n",ret);\r
+\r
+                                               if(PxiAlg_GetHrUpdateFlag())\r
+                                               {\r
+                                                       PxiAlg_HrGet(&hr);\r
+                                                       PxiAlg_GetSigGrade(&hr_grader);\r
+                                               }\r
+\r
+                                               LOG_PRINT("ret  %d  , hr  %f ,  hr_grade  %f  \n", ret,  hr, hr_grader);\r
+                        \r
+               }\r
+        \r
+    PxiAlg_Close();\r
+\r
+    return;\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/libv703_0_1.a b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/libv703_0_1.a
new file mode 100644 (file)
index 0000000..0cb0d3b
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/libv703_0_1.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/pah8009_testpattern_SPO2.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/pah8009_testpattern_SPO2.h
new file mode 100644 (file)
index 0000000..d8d9d49
--- /dev/null
@@ -0,0 +1,257 @@
+#ifndef _PAH8009_TESTPATTERN_\r
+#define _PAH8009_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 2\r
+#define NF_PPG_PER_CHANNEL 81\r
+static const int32_t PAH8009_rawdata_SPO2[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{1,44,1413227,1375343,1847643,1787527,1849059,1795619,1850643,1799035,1853773,1804053,1855985,1807487,1857211,1810045,1858155,1811489,1857549,1810013,1856203,1807653,1855885,1807985,1856225,1808433,1856443,1808915,1856873,1809501,1856415,1809469,1856153,1808027,1854979,1805393,1853881,1804191,1853475,1803313,1853703,1803495,1853817,1804027,1852163,1801415},\r
+{1,50,1849833,1797659,1848117,1794425,1846501,1792429,1846933,1794465,1848347,1797081,1847485,1795507,1845053,1791709,1845377,1792531,1845089,1792009,1844055,1790507,1844639,1792275,1845127,1792257,1844247,1791883,1845803,1795625,1848153,1799679,1848469,1799821,1847757,1799101,1847791,1798791,1847717,1799383,1847285,1799295,1846165,1798421,1846711,1799119,1846979,1800181,1847917,1802373,1850389,1806013},\r
+{1,54,1851247,1807949,1852643,1810447,1854655,1814097,1856243,1816695,1856223,1816223,1855313,1814589,1854833,1813203,1854871,1813909,1855589,1815461,1855909,1816625,1856441,1816653,1856433,1816745,1856403,1816085,1854765,1813617,1853649,1811729,1853635,1812979,1854253,1814335,1854801,1814861,1855735,1817119,1856677,1818893,1856001,1817823,1855067,1815591,1854373,1814907,1853907,1813719,1852421,1811229,1851319,1809519,1850537,1808687},\r
+{1,54,1850007,1808285,1850491,1808867,1851353,1810153,1850677,1808535,1849503,1806183,1847779,1803439,1845305,1798249,1842229,1794125,1841311,1792951,1840299,1790817,1839801,1790775,1839609,1791541,1840653,1792959,1840111,1792037,1838781,1789819,1838071,1788025,1837549,1786829,1837177,1786199,1834709,1782813,1835469,1783903,1837155,1788265,1838507,1791097,1839841,1792945,1841147,1795599,1842109,1797251,1842343,1798043,1843101,1799101},\r
+{1,52,1843105,1799891,1843259,1800647,1843283,1801331,1842971,1800695,1843171,1800911,1843061,1801429,1843091,1801291,1843385,1801803,1843243,1802025,1843955,1803115,1845053,1804645,1844847,1804419,1844275,1802959,1844563,1803241,1844051,1802191,1844389,1802653,1844789,1803795,1845123,1804267,1845465,1804429,1845769,1804835,1845421,1804775,1844911,1804409,1844629,1804201,1844617,1804613,1845049,1804889,1845049,1805099},\r
+{1,54,1845203,1805421,1844861,1805319,1845265,1805971,1845519,1806249,1845809,1806711,1845999,1807367,1846361,1807837,1846561,1808147,1847089,1809035,1847853,1810107,1848437,1811271,1848687,1811447,1848663,1811475,1848819,1811293,1848815,1811405,1847765,1810337,1847277,1809779,1847415,1809381,1846875,1808739,1846289,1808049,1846243,1807663,1846263,1807911,1845817,1807357,1845631,1807343,1845983,1807737,1846023,1807371,1845827,1807367},\r
+{1,52,1846061,1807943,1845723,1807769,1845883,1807671,1845831,1807777,1845765,1807449,1845733,1807487,1845631,1807823,1845133,1806927,1844505,1806271,1844083,1805967,1843839,1805569,1843705,1805473,1844097,1806027,1844243,1806141,1844395,1806617,1844113,1806423,1844341,1806709,1844363,1807205,1844527,1807439,1844603,1807187,1844567,1807015,1844563,1806931,1844247,1806691,1844457,1806229,1844533,1806451,1844537,1806307},\r
+{1,52,1844555,1806299,1843955,1806475,1843797,1805597,1843233,1805593,1843451,1805647,1843265,1805505,1843037,1805499,1843121,1805159,1843229,1805383,1843029,1804627,1843313,1805051,1843019,1805145,1843261,1804877,1842989,1804949,1842807,1804521,1843091,1805135,1843381,1805241,1843323,1805171,1843523,1805439,1843737,1805711,1843861,1806105,1843411,1806039,1842957,1805241,1842411,1804437,1842521,1804595,1842225,1804201},\r
+{1,54,1842265,1804225,1842225,1804141,1842091,1803731,1842001,1803837,1842331,1804307,1842349,1804483,1842811,1805057,1842709,1804691,1842997,1805397,1843061,1805025,1843003,1805237,1843179,1805291,1843309,1804907,1843287,1805309,1843237,1805263,1843353,1805513,1843121,1805413,1842015,1803891,1841531,1803513,1841903,1804169,1841713,1803343,1841855,1803643,1841597,1803495,1841721,1803983,1841979,1804191,1841961,1804663,1842237,1805463},\r
+{1,52,1842841,1805611,1843219,1805829,1843215,1806035,1843643,1806543,1843665,1807081,1844097,1807349,1844393,1807677,1844555,1808157,1844457,1808143,1845213,1809151,1844893,1808913,1844453,1808725,1844261,1808397,1844083,1808377,1844029,1807939,1843945,1807671,1843379,1807363,1843327,1806831,1843163,1806443,1842717,1806451,1842935,1806207,1842847,1806623,1843341,1806843,1843117,1806631,1842887,1806461,1843239,1806761},\r
+{1,52,1843491,1806813,1843455,1807039,1843207,1806913,1843179,1806881,1843535,1806961,1842847,1806401,1842167,1805047,1842027,1804743,1841633,1804475,1841295,1803827,1841263,1803435,1840961,1803563,1840957,1803337,1841055,1803563,1840755,1803551,1841335,1804649,1842085,1805085,1842247,1805269,1842033,1805263,1842063,1805325,1842263,1805527,1842563,1805681,1843101,1806203,1843291,1806545,1844207,1808087,1844433,1808143},\r
+{1,54,1844493,1808715,1843847,1808245,1844033,1809131,1844385,1809343,1844457,1808979,1844433,1808869,1844073,1808139,1843385,1807065,1843145,1806497,1843803,1807307,1843051,1806933,1844003,1809509,1845831,1812717,1847551,1816579,1851097,1823331,1860321,1839875,1866743,1849125,1865911,1843927,1860507,1835367,1859875,1834775,1858871,1833191,1857559,1830255,1854361,1824619,1852367,1821855,1851795,1820705,1850731,1818609,1850629,1818733},\r
+{1,52,1852007,1822665,1852347,1822961,1851195,1820025,1850279,1817891,1848753,1815595,1847853,1814407,1847935,1814333,1848401,1816057,1848725,1816107,1848753,1815591,1848549,1815471,1848717,1815887,1849229,1816815,1848961,1816479,1848807,1815707,1847681,1814379,1846801,1812689,1846111,1810819,1843763,1806849,1840543,1801615,1839751,1801757,1840755,1802973,1841277,1804533,1840179,1802529,1840005,1801457,1840333,1802113},\r
+{1,52,1839583,1800437,1838631,1799091,1838427,1799267,1839369,1800713,1839779,1801687,1840619,1804035,1841259,1804479,1841405,1804525,1841135,1804127,1841249,1804447,1840529,1804373,1840391,1804179,1839897,1803301,1839635,1802829,1839387,1802491,1839369,1802159,1839377,1802149,1839271,1801763,1839453,1802063,1839409,1802091,1839343,1802141,1839449,1802299,1839911,1802955,1840165,1803041,1840579,1803235,1840957,1803901},\r
+{1,54,1840957,1804053,1841015,1804355,1841415,1804557,1841627,1805273,1841847,1805861,1841179,1805361,1841343,1805159,1841357,1805579,1841353,1805249,1841153,1805343,1841231,1805547,1841491,1805587,1841633,1806263,1841685,1806429,1841651,1806705,1842211,1807541,1842779,1807939,1843069,1808897,1843483,1809417,1843837,1809717,1844225,1810343,1844371,1811299,1844701,1811483,1845013,1811833,1845563,1812531,1845239,1812135,1844749,1811935},\r
+{1,52,1844875,1812555,1844835,1812143,1844691,1811903,1844741,1811959,1844491,1811669,1844505,1811673,1844443,1811543,1844435,1811445,1844101,1811371,1844163,1811027,1844233,1811177,1843949,1811133,1844233,1811133,1844221,1811021,1844069,1810507,1844051,1810775,1844061,1810745,1844051,1810749,1843349,1810309,1842981,1809331,1842705,1809183,1842441,1808973,1842451,1808739,1842345,1808835,1842219,1808761,1842411,1808559},\r
+{1,54,1842157,1808645,1842139,1808919,1842389,1808895,1842463,1808749,1842335,1808767,1842407,1808839,1842527,1808295,1842543,1808405,1842563,1808735,1842229,1808049,1842567,1808585,1842535,1808383,1842411,1808495,1841747,1807763,1841427,1807067,1841277,1807089,1841295,1807213,1840813,1806619,1840951,1806783,1841151,1807095,1841019,1806927,1841053,1807181,1840885,1807043,1841227,1806959,1841073,1807035,1841063,1807181,1841215,1807417},\r
+{1,52,1841459,1807145,1841449,1807199,1841393,1807067,1841415,1806979,1841509,1807187,1841507,1807269,1841729,1807481,1840863,1806965,1840663,1806083,1840347,1805851,1840275,1805935,1840177,1805587,1839961,1805841,1840045,1805471,1839875,1805569,1840161,1805727,1840281,1805785,1840409,1805607,1840463,1806087,1840779,1806397,1840677,1806737,1841009,1806767,1841183,1807029,1841241,1807131,1841197,1807195,1841343,1807293},\r
+{1,52,1841673,1807403,1841477,1807223,1841063,1806543,1840397,1806369,1840027,1805805,1839885,1805675,1839769,1805283,1839823,1804973,1839867,1805033,1839169,1804963,1839217,1805009,1839599,1804875,1839439,1805443,1839685,1805367,1839583,1804599,1839377,1804201,1839027,1803559,1838803,1803089,1838555,1802459,1837971,1801073,1837439,1800159,1837599,1801079,1837897,1801331,1836701,1799857,1836455,1800321,1837069,1801853},\r
+{1,54,1837643,1802797,1837269,1801951,1836379,1801137,1836025,1799811,1835379,1799317,1835171,1798263,1834655,1798043,1834249,1797073,1833925,1796527,1833769,1796001,1833431,1795583,1833475,1795783,1833499,1795867,1832885,1794835,1832697,1794735,1832605,1794313,1832151,1793511,1832045,1793463,1831047,1792143,1830137,1791131,1829695,1790225,1829007,1789429,1829437,1789379,1828881,1789107,1828783,1789009,1829103,1789001,1828851,1789125},\r
+{1,52,1829207,1789139,1829051,1789453,1829331,1789623,1829469,1789449,1829407,1788433,1828309,1786533,1827885,1785401,1826885,1783253,1826359,1782583,1826343,1783151,1825813,1781565,1824831,1780531,1824051,1779917,1823559,1779967,1823461,1779837,1824221,1781705,1824447,1781357,1823893,1781117,1823901,1780941,1823883,1781123,1824131,1780957,1823839,1781045,1823811,1780333,1823719,1780059,1823785,1780587,1824243,1781293},\r
+{1,52,1824133,1781279,1824061,1781059,1823835,1780387,1823857,1779837,1823781,1780479,1823985,1780725,1823713,1780581,1822647,1779399,1822121,1779229,1822219,1779113,1821779,1778493,1822043,1779141,1822127,1779127,1822081,1779237,1822189,1779195,1822481,1779691,1822655,1779935,1823117,1780235,1823349,1780897,1823763,1780883,1823977,1781445,1823793,1780467,1823777,1780327,1823715,1780481,1823367,1779621,1823461,1779755},\r
+{1,52,1823465,1779557,1823283,1779347,1822891,1778737,1822153,1778157,1821487,1777481,1821353,1777227,1821121,1777199,1820645,1776801,1820579,1775975,1820005,1775847,1820139,1775845,1819555,1774539,1818991,1774099,1819245,1774247,1818719,1773383,1818675,1773563,1818791,1774507,1819827,1776039,1819635,1775619,1819863,1775813,1819399,1774935,1819159,1774599,1818537,1773767,1818973,1773683,1817563,1772195,1816719,1771193},\r
+{1,54,1816439,1770893,1816497,1770653,1816021,1770379,1815945,1769969,1816019,1769913,1815701,1769797,1815695,1769489,1815829,1769099,1814869,1769189,1815429,1769169,1815005,1768841,1815127,1768777,1814807,1768449,1815069,1768503,1814833,1768411,1814667,1768117,1814673,1767747,1814187,1767043,1814171,1766827,1813321,1765607,1812461,1764623,1811547,1763381,1811347,1762825,1811605,1763061,1811461,1763159,1811267,1763141,1811417,1763043},\r
+{1,52,1811207,1763505,1811399,1763381,1811279,1762695,1811127,1762769,1810949,1762285,1810439,1761947,1810625,1762151,1810679,1761753,1810119,1760941,1810021,1760303,1809585,1760031,1809807,1759923,1809531,1760353,1810315,1761195,1809123,1759887,1809127,1759245,1808331,1757739,1807961,1757407,1807691,1756865,1807641,1756431,1806881,1754813,1805857,1753145,1805035,1752749,1805217,1752675,1804987,1752327,1804667,1752295},\r
+{1,52,1804585,1751465,1803327,1749265,1803413,1749487,1803309,1749749,1803243,1749473,1803393,1750037,1803025,1749159,1802261,1747897,1801561,1747231,1800863,1746159,1799649,1745263,1799405,1744755,1798743,1743721,1798005,1742265,1798061,1742259,1797767,1741831,1796901,1740061,1796891,1740181,1796599,1739815,1798083,1743175,1799139,1743641,1798311,1742347,1797813,1740889,1797559,1740953,1799387,1743481,1798947,1742593},\r
+{1,54,1799303,1742917,1799445,1742663,1799517,1743083,1799889,1743079,1799733,1743379,1799933,1743517,1799961,1743591,1800597,1744391,1801647,1745711,1802941,1747685,1803389,1748443,1804265,1749357,1804725,1750605,1805401,1751169,1806089,1752397,1806809,1754191,1807241,1754333,1807415,1755207,1808975,1757327,1809331,1757363,1809041,1757489,1809379,1758127,1809705,1759277,1809865,1759227,1808869,1757333,1808459,1757331,1808091,1756473},\r
+{1,52,1807045,1755147,1807231,1755243,1806873,1755451,1806761,1754827,1806757,1754295,1806217,1753817,1806027,1753769,1806401,1754069,1806711,1754661,1806859,1755233,1806933,1755225,1807365,1755345,1807071,1755757,1807251,1755761,1807623,1756141,1807495,1756057,1807387,1755677,1807371,1755835,1807757,1756141,1807543,1755461,1806361,1754421,1805533,1753405,1805511,1753201,1805605,1753187,1805401,1752729,1805263,1752781},\r
+{1,52,1805613,1752315,1805137,1752665,1805399,1752813,1805449,1753159,1805729,1753197,1806223,1753723,1806507,1754129,1806973,1754699,1807193,1755253,1807833,1755965,1808139,1756455,1808989,1757391,1809501,1758191,1809683,1758837,1810497,1759453,1810839,1760163,1810781,1760455,1810839,1760599,1811329,1761517,1812057,1762755,1811983,1762155,1812405,1762877,1812733,1763441,1813155,1764143,1812799,1763593,1812693,1763099},\r
+{1,54,1812481,1762807,1812405,1762063,1812249,1761607,1812057,1761435,1812155,1761647,1811813,1761203,1811925,1761757,1811969,1761647,1811403,1761043,1811723,1761365,1810887,1760215,1810353,1759897,1809919,1759359,1809891,1759121,1809359,1758787,1809403,1758791,1808939,1757795,1808829,1757503,1808451,1756935,1808371,1756989,1808229,1756681,1807947,1755785,1807993,1756061,1807975,1755867,1807775,1755789,1807797,1755511,1807659,1754985},\r
+{1,52,1807571,1755303,1808317,1755933,1807913,1755669,1807827,1755669,1807589,1755723,1807089,1755683,1807089,1755355,1806965,1755235,1806689,1754925,1806067,1754607,1806019,1754393,1805933,1754103,1805657,1753807,1805565,1753949,1805707,1753847,1805747,1754023,1805729,1753903,1805827,1754413,1805801,1754563,1805921,1754255,1805897,1754011,1805921,1754429,1805871,1754121,1805919,1754323,1805671,1754277,1805263,1754413},\r
+{1,52,1805209,1754227,1805897,1755557,1806035,1755549,1806173,1755697,1806917,1756611,1806969,1757139,1806929,1757599,1807535,1758705,1807847,1759115,1807765,1758737,1807761,1759143,1808165,1759313,1807975,1758823,1807067,1757647,1807303,1758459,1807947,1759133,1807415,1758703,1807023,1758117,1805867,1757439,1805501,1756357,1805079,1756339,1804715,1755955,1804569,1756201,1804279,1755947,1804421,1756037,1804527,1756601},\r
+{1,52,1804421,1756603,1804003,1756661,1804229,1756589,1804137,1756763,1804239,1756745,1804127,1756897,1803851,1756615,1803973,1756601,1804061,1756971,1803985,1757065,1803905,1757175,1803039,1756335,1802317,1755469,1802149,1755613,1801841,1755233,1801673,1754699,1801405,1755127,1801317,1755405,1801865,1755553,1801775,1755783,1802007,1756199,1802047,1756413,1802665,1757401,1802757,1758035,1802861,1758265,1803333,1758617},\r
+{1,54,1803509,1759013,1803501,1758825,1803795,1759225,1803461,1759059,1802741,1758075,1801625,1757051,1801379,1756855,1801095,1756713,1801011,1756625,1800729,1756575,1800587,1757069,1800615,1757869,1800587,1757725,1801113,1758269,1801113,1758713,1800655,1757585,1799911,1756633,1799735,1756663,1800747,1757825,1800325,1756675,1799329,1755123,1799205,1755179,1799257,1755341,1798751,1755963,1798707,1756185,1798551,1755997,1797879,1755225},\r
+{1,52,1797367,1754219,1796909,1753631,1796335,1752809,1796371,1753193,1796439,1752919,1795339,1751653,1795025,1751049,1794957,1751515,1795433,1752569,1795659,1753511,1795905,1753413,1796083,1754171,1795839,1753729,1795621,1753535,1795993,1754393,1795527,1754129,1795243,1754023,1794505,1753095,1794037,1752227,1793841,1752365,1794041,1752597,1794273,1753441,1794505,1753691,1794229,1753579,1794331,1753715,1794029,1753835},\r
+{1,52,1794295,1753793,1793707,1753123,1793787,1753483,1793619,1753311,1793601,1753293,1793553,1753311,1794067,1753995,1794167,1754753,1794223,1754135,1794091,1754389,1793681,1753663,1792693,1752901,1792507,1753105,1792355,1753073,1792199,1753371,1792045,1752957,1792649,1753473,1792303,1753857,1792405,1753733,1792671,1753691,1792351,1753631,1793255,1754989,1794139,1756167,1794665,1757393,1795615,1759015,1797051,1760923},\r
+{1,54,1797991,1762359,1798559,1763421,1799031,1764405,1799703,1764909,1799057,1764355,1798547,1763805,1798737,1763389,1798591,1763057,1798417,1762189,1797965,1761883,1797911,1762243,1798551,1762849,1797751,1761471,1797311,1760659,1797417,1760673,1797075,1760535,1797289,1760857,1797417,1760483,1797421,1760539,1797065,1760297,1797083,1760017,1796897,1760843,1797111,1760641,1796375,1759817,1796065,1759407,1795299,1758599,1794891,1757997},\r
+{1,52,1795229,1758153,1794979,1758241,1794927,1758215,1794753,1758163,1794531,1757951,1794695,1758301,1794971,1758681,1794939,1758113,1794869,1757941,1794863,1758579,1794913,1758357,1795135,1758257,1795121,1758229,1795145,1758331,1795241,1758783,1795439,1758945,1795717,1758843,1795145,1758755,1794829,1758243,1794325,1757997,1794269,1757651,1793837,1757147,1793867,1756763,1793707,1756767,1793947,1756901,1793907,1757069},\r
+{1,52,1793863,1757511,1794237,1757447,1794113,1757077,1794527,1757489,1794525,1757479,1794553,1757143,1794273,1757065,1794167,1756233,1794219,1755963,1793971,1756111,1794189,1755799,1794015,1755489,1793939,1755603,1793237,1755003,1793173,1755039,1793027,1755271,1793255,1755335,1793263,1755113,1793111,1755211,1793295,1754985,1792939,1754713,1793013,1754815,1793161,1754861,1793095,1754365,1792969,1754167,1793191,1754639},\r
+{1,54,1793451,1754383,1793197,1754107,1793031,1753455,1793121,1753197,1792693,1752887,1792279,1751911,1792253,1752093,1792703,1752489,1792099,1752093,1791591,1751783,1791697,1752701,1792059,1752601,1792155,1752739,1792431,1752761,1792067,1752901,1792537,1753275,1792721,1753297,1792775,1753497,1793449,1753821,1793771,1754181,1794665,1754975,1795037,1755147,1795439,1756265,1796243,1757069,1796545,1757719,1797129,1757675,1797421,1757989},\r
+{1,52,1797827,1758691,1797973,1759365,1797889,1759835,1797707,1759929,1798089,1760553,1797719,1759745,1797963,1760145,1798387,1760733,1797475,1759877,1797719,1760201,1797945,1760113,1797449,1759531,1797545,1758953,1797247,1759083,1797243,1759055,1797479,1758935,1797465,1759611,1797809,1759615,1797825,1760007,1798013,1760127,1798061,1760455,1798125,1760327,1798311,1760599,1798243,1760345,1797265,1759101,1797247,1759037},\r
+{1,58,1797381,1759389,1797111,1758861,1797007,1758981,1796897,1758719,1796803,1758561,1796629,1758353,1796679,1758385,1796871,1758779,1796733,1758215,1796683,1758241,1796821,1758251,1796949,1758399,1797217,1757969,1797221,1758569,1797319,1758283,1797675,1758897,1797475,1758991,1797933,1759147,1797947,1759319,1797337,1758603,1797155,1758227,1797247,1758575,1797071,1758301,1796851,1758195,1797163,1758279,1796999,1758539,1797443,1758195,1797407,1758985,1797523,1759019},\r
+{1,54,1797665,1758957,1798177,1759151,1798279,1759715,1798257,1759849,1798347,1759957,1798085,1759513,1798725,1760179,1798381,1759415,1798631,1758657,1798133,1757821,1797741,1757073,1797115,1756099,1796243,1756261,1796673,1756537,1796193,1756149,1795713,1755589,1796811,1757377,1797029,1757761,1796433,1757651,1796611,1758049,1796941,1758911,1797003,1759107,1797399,1759213,1797483,1759619,1797973,1760635,1798445,1760547,1798707,1761071},\r
+{1,52,1799277,1761591,1799209,1762007,1799747,1762487,1800085,1763007,1800473,1763689,1800161,1763315,1799281,1762309,1799427,1762225,1799285,1762189,1798857,1761577,1798671,1760497,1798751,1760641,1798501,1760441,1798503,1759999,1798485,1759943,1798421,1760427,1798507,1759929,1798729,1760695,1798759,1760803,1799001,1760787,1798863,1760853,1799271,1761001,1799417,1761055,1799539,1761569,1799453,1761439,1799939,1761785},\r
+{1,52,1799521,1761459,1799089,1760973,1799063,1760833,1799165,1761269,1799197,1761375,1799115,1761385,1799119,1761357,1799431,1762063,1799201,1761749,1799539,1762119,1799779,1762307,1800183,1762571,1799943,1762585,1800245,1762687,1800507,1762937,1800815,1762705,1800153,1761703,1799965,1761459,1799775,1761463,1800245,1761255,1799463,1760381,1798795,1759877,1798223,1759481,1798399,1759619,1797981,1758723,1797529,1758127},\r
+{1,54,1797773,1758939,1797609,1759523,1797559,1758847,1797547,1759313,1797853,1759703,1797737,1759285,1797625,1759403,1797621,1759287,1797315,1758769,1797235,1758349,1797071,1758349,1797053,1757913,1797129,1758529,1797079,1758487,1796995,1757601,1796661,1758003,1795985,1757139,1795833,1756439,1795385,1756513,1795277,1756237,1794699,1755395,1794647,1754749,1794263,1754773,1794245,1754819,1794165,1754841,1794481,1755679,1794903,1755807},\r
+{1,52,1794625,1755947,1795273,1756347,1795101,1756915,1795403,1756917,1795127,1756865,1795403,1757271,1795659,1757553,1795611,1757319,1795523,1757197,1794793,1756527,1794047,1755617,1793775,1755553,1793823,1755307,1793357,1755129,1793289,1754855,1793255,1754727,1793405,1755159,1793295,1755351,1793335,1755091,1793449,1755155,1793713,1755899,1794673,1757867,1795135,1757937,1795539,1758279,1795975,1759213,1796069,1759687},\r
+{1,52,1796651,1759951,1796531,1759435,1796831,1759809,1796203,1759315,1796145,1759375,1795647,1758913,1796029,1759623,1796669,1760941,1796847,1761305,1796799,1761905,1797447,1762993,1797381,1763315,1797489,1763569,1798253,1764323,1798027,1764683,1798155,1764631,1798285,1765205,1798461,1764483,1798137,1764147,1798227,1764217,1798097,1763989,1799093,1766027,1799693,1766979,1799867,1767313,1799303,1765971,1798503,1765287},\r
+{1,54,1798307,1764545,1797951,1762859,1796985,1760899,1796723,1759923,1795953,1758823,1795443,1758565,1795571,1757899,1795531,1758375,1795553,1758657,1795931,1758991,1795749,1759015,1795917,1759203,1796105,1759485,1796149,1759805,1796439,1760077,1796647,1760847,1795843,1760169,1795723,1759507,1795759,1759849,1795887,1759327,1795799,1759411,1795665,1759475,1795647,1759827,1795957,1759475,1795777,1759623,1796025,1759873,1796037,1759975},\r
+{1,52,1796411,1760465,1796949,1761305,1797151,1761693,1797209,1761859,1797519,1762475,1798107,1763275,1798577,1764179,1798555,1763559,1797825,1762927,1797563,1762803,1797861,1763227,1797271,1762681,1797409,1762409,1797541,1762711,1797527,1762651,1797239,1762659,1797439,1762603,1797333,1762863,1797541,1762637,1797289,1762525,1797537,1762531,1797351,1762169,1797573,1761901,1797083,1761043,1797367,1761623,1797621,1761873},\r
+{1,52,1797069,1761279,1796973,1761463,1796817,1761251,1796341,1760013,1796203,1760165,1796109,1760417,1796381,1760849,1796693,1761665,1796749,1762427,1797123,1762151,1797207,1762723,1797189,1762507,1797507,1762963,1797247,1762963,1797439,1762715,1797345,1762151,1797163,1762137,1797283,1762127,1797269,1761891,1797275,1762087,1797221,1762317,1797551,1762243,1797199,1762437,1796967,1762469,1796577,1761907,1796891,1762031},\r
+{1,52,1796879,1762087,1796475,1761633,1796335,1761369,1796221,1761323,1796229,1760927,1796153,1761189,1796033,1761195,1796261,1761369,1796469,1761509,1796653,1761787,1796653,1762295,1796705,1762353,1797003,1762373,1797435,1762933,1796999,1762913,1797213,1762739,1797319,1762451,1797275,1762415,1797029,1762161,1796643,1761667,1796665,1761683,1796581,1761725,1796493,1761791,1796331,1761933,1796933,1762189,1796705,1761861},\r
+{1,54,1796393,1761875,1796577,1762031,1796785,1762059,1796927,1762581,1797395,1762817,1797349,1763037,1797311,1762709,1797705,1763311,1797773,1763181,1798243,1763395,1798337,1764331,1798319,1764243,1798777,1764225,1798547,1764299,1797991,1764139,1797627,1763685,1797763,1763559,1797817,1763385,1797261,1763007,1797181,1762803,1797279,1762903,1797123,1762785,1796995,1762405,1796875,1761985,1796715,1762127,1796755,1762299,1796795,1762247},\r
+{1,52,1796705,1761915,1796639,1761781,1796781,1762017,1796567,1761625,1796635,1761759,1796767,1761637,1796937,1761569,1796915,1761163,1796447,1761505,1795793,1760875,1795665,1760205,1795341,1759965,1795361,1759703,1795201,1759231,1795069,1759093,1794975,1758815,1794749,1758741,1794819,1758807,1794557,1758145,1794405,1758375,1794743,1758325,1794645,1757997,1794807,1758123,1794579,1758205,1794727,1758081,1794757,1757881},\r
+{1,52,1794385,1757605,1794561,1757691,1794659,1757157,1794645,1757035,1794735,1757133,1794549,1757525,1794019,1756869,1793285,1755965,1793183,1756265,1793175,1756043,1792965,1755397,1793139,1755405,1792573,1755299,1792889,1755007,1792437,1754819,1792645,1754827,1792471,1754855,1792623,1754449,1792529,1754653,1792695,1754523,1792885,1754707,1792867,1754815,1792827,1754847,1793089,1755175,1793173,1754949,1793333,1755165},\r
+{1,54,1793223,1754919,1793253,1755275,1793161,1754949,1793089,1754847,1792231,1754005,1792143,1753613,1791987,1753709,1791881,1753131,1791841,1753123,1791729,1753063,1791609,1753251,1791681,1752855,1791387,1752771,1791439,1752961,1791569,1752805,1791639,1752447,1791547,1752809,1792019,1752869,1791845,1753193,1792187,1753505,1792449,1753787,1792877,1754295,1792853,1754417,1793015,1754361,1793085,1754431,1793117,1754845,1793055,1754759},\r
+{1,52,1792707,1754499,1792507,1754283,1792915,1754739,1792681,1754707,1792783,1754495,1792445,1754611,1792783,1754883,1792657,1754647,1792635,1754231,1792965,1754795,1793209,1755035,1793481,1755817,1793771,1756199,1794081,1756745,1794263,1756981,1794367,1757439,1795033,1757721,1795113,1758629,1795901,1759047,1795817,1759439,1796159,1760469,1797013,1761309,1797127,1761781,1796853,1762017,1796891,1761851,1796785,1762085},\r
+{1,52,1796719,1761901,1797007,1762303,1797167,1762295,1796429,1761611,1796465,1761439,1796491,1761473,1796509,1761593,1796275,1761301,1796283,1761033,1796399,1761139,1795989,1760871,1796039,1760751,1796101,1761115,1796265,1761037,1796175,1761319,1796453,1761213,1796417,1761319,1796083,1761287,1795105,1759139,1794157,1757065,1793851,1756269,1793677,1756107,1793037,1754947,1792279,1754457,1792489,1755755,1792743,1756163},\r
+{1,54,1792657,1756201,1792783,1756523,1793001,1757021,1793215,1757845,1793271,1757961,1792601,1756879,1793499,1758159,1793027,1757799,1792929,1757563,1793259,1758237,1793343,1758329,1793467,1758671,1793659,1758523,1793223,1758423,1792769,1757645,1792245,1757271,1792151,1757807,1791901,1757467,1791333,1756099,1791435,1756375,1791097,1755941,1790999,1755859,1790493,1755525,1790839,1755977,1790609,1755849,1791075,1756593,1791239,1756499},    \r
+};\r
+static const int16_t PAH8009_mems_SPO2[][3*NF_PPG_PER_CHANNEL] = \r
+{\r
+{80, 155,370,2007,136,383,2012,170,393,2021,170,381,2016,150,376,2012,155,376,2010,163,383,2016,163,377,2015,156,367,2029,153,373,2014,161,402,1999,168,390,2012,151,385,2015,159,386,2015,167,390,2013,162,394,2014,161,391,2014,163,395,2014,166,394,2010,158,398,2010,159,396,2007,164,396,2007,162,397,2010,157,397,2008,160,403,2009,162,402,2008,162,400,2009,162,395,2009,161,396,2009,161,397,2013,161,394,2014,162,388,2011,159,386,2011,160,392,2012,159,391,2016,161,385,2015,162,386,2012,158,389,2016,161,392,2014,161,391,2011,159,394,2015,163,394,2011,161,393,2011,160,399,2010,162,402,2010,163,412,2014,159,428,1982,162,439,1993,173,352,2029,139,371,2020,162,419,2015,188,416,2011,164,412,2012,152,401,2004,165,402,1999,164,420,2002,157,443,1997,165,430,2007,166,388,2023,154,366,2016,156,396,2002,171,407,2010,162,408,2015,158,391,2010,161,386,2008,163,388,2012,163,363,2044,159,345,2022,151,404,2012,164,426,1988,169,409,2005,156,392,2018,158,382,2016,161,387,2013,157,408,2002,157,413,2008,162,400,2016,158,393,2012,158,392,2009,161,392,2010},\r
+{52, 162,411,2012,164,406,2008,164,407,2005,161,413,2006,165,412,2005,164,417,2005,169,407,2000,165,403,2010,160,409,2011,166,409,2008,161,412,2010,159,421,2016,165,417,2012,162,409,2008,166,391,2001,163,400,2005,164,411,2004,159,426,2013,160,420,2017,167,408,2004,170,402,2000,163,406,2003,161,410,2010,165,415,2010,161,415,2013,162,409,2010,165,395,2003,163,392,2003,168,398,2004,154,409,2017,157,409,2017,166,402,2016,161,400,2013,160,387,2006,157,391,2010,161,396,2012,164,395,2011,159,392,2012,159,392,2009,159,396,2013,160,399,2012,158,392,2009,159,391,2010,163,386,2007,161,384,2006,155,393,2014,165,387,2014,158,384,2015,162,342,2044,152,371,2009,164,419,1993,168,420,2003},\r
+{53, 158,390,2012,150,377,2025,160,377,2018,166,391,2011,164,403,2010,157,403,2009,157,398,2009,156,406,2013,161,402,2008,156,393,2012,152,393,2011,161,393,2012,164,393,2011,157,387,2010,160,397,2012,167,394,2010,151,396,2014,159,394,2013,161,395,2017,163,395,2011,159,390,2010,159,394,2013,164,393,2009,158,392,2013,159,393,2006,157,398,2012,163,404,2014,165,396,2013,165,388,2007,167,396,2004,161,400,2011,161,405,2015,167,399,2000,152,402,2041,180,407,2000,145,369,2002,159,417,2022,181,384,2001,143,413,2025,169,393,2004,159,412,2020,167,399,2006,160,399,2009,165,396,2003,161,410,2010,169,413,2006,168,412,2008,158,418,1996,163,441,1985,179,390,2022,155,380,2030,163,399,2005,175,415,2011},\r
+{52, 169,408,2005,161,400,2006,162,403,2009,171,408,2008,165,413,2009,166,417,2015,169,418,2012,172,406,2005,160,429,1989,167,441,1995,177,411,2006,158,409,2022,158,408,2010,173,400,2006,174,388,2003,161,392,2019,164,408,2011,166,419,2012,167,411,1997,161,417,2006,166,420,2009,163,395,2011,156,399,2000,165,410,2006,170,424,2015,166,420,2016,167,418,2011,167,417,2010,168,415,2006,163,423,1996,164,446,1991,175,396,2016,162,398,2019,161,429,2006,164,459,1984,170,422,2004,165,370,2017,157,368,2018,164,398,2000,167,404,2007,167,406,2008,159,402,2014,152,397,2013,159,388,2022,159,372,2026,151,408,2003,165,411,2000,159,399,2012,154,386,2010,153,393,2017,158,378,2014,157,383,2018},\r
+{52, 155,398,2007,160,397,2012,152,392,2014,159,379,2016,155,393,2018,153,407,2007,161,402,2010,153,391,2014,150,388,2011,154,391,2012,159,391,2010,154,394,2013,157,393,2011,154,390,2013,155,390,2013,155,391,2014,153,393,2015,156,381,2014,163,367,2031,147,382,2011,153,421,2002,169,415,2006,149,400,2016,154,399,2015,159,395,2008,152,392,2008,149,399,2009,161,404,2012,162,402,2012,158,395,2008,155,398,2008,157,403,2012,158,405,2011,156,401,2011,158,405,2009,158,401,2012,158,402,2011,159,399,2008,156,401,2011,158,402,2009,154,403,2009,155,402,2011,158,400,2010,158,402,2009,160,400,2010,154,399,2011,153,399,2009,156,400,2011,157,402,2013,153,399,2012,155,399,2011,158,399,2012},\r
+{53, 157,401,2011,157,398,2012,155,398,2011,154,396,2009,154,402,2011,159,400,2012,156,399,2012,159,398,2011,157,394,2008,155,399,2012,158,399,2011,155,398,2014,156,397,2011,156,398,2014,157,394,2009,155,395,2011,156,395,2012,156,393,2008,155,395,2014,157,398,2012,155,396,2013,154,397,2012,159,399,2014,158,392,2009,154,394,2011,157,395,2010,156,397,2015,158,400,2013,157,398,2012,156,397,2011,158,397,2009,160,395,2010,156,399,2011,158,402,2011,158,404,2012,157,401,2011,156,402,2012,157,404,2008,159,404,2010,158,403,2011,157,402,2012,157,404,2009,158,406,2010,160,405,2012,156,403,2011,156,401,2010,159,403,2008,159,404,2010,159,408,2010,158,408,2012,159,405,2010,157,397,2006,160,406,2012},\r
+{52, 160,407,2009,154,407,2013,160,403,2009,160,402,2008,159,405,2012,157,403,2010,156,404,2010,158,405,2010,157,407,2011,159,405,2009,158,402,2010,159,405,2010,160,406,2009,158,406,2012,156,408,2011,157,405,2008,159,405,2010,162,406,2007,156,404,2009,157,405,2008,159,405,2010,160,408,2010,157,405,2010,156,405,2008,161,402,2007,156,407,2014,159,405,2006,154,405,2013,158,410,2012,159,403,2009,156,405,2009,161,403,2006,157,405,2011,154,407,2012,157,404,2011,155,404,2013,158,402,2008,158,402,2013,157,403,2011,158,402,2009,157,402,2010,157,405,2011,157,406,2009,155,406,2011,156,406,2009,155,405,2011,159,404,2008,157,404,2007,157,407,2011,159,406,2008,156,407,2012,161,405,2007},\r
+{52, 157,406,2009,156,406,2011,159,408,2011,160,407,2007,158,408,2009,160,404,2011,158,405,2008,157,404,2008,158,407,2014,157,405,2011,156,408,2010,157,405,2007,158,407,2011,159,407,2009,156,405,2010,154,404,2007,158,407,2008,158,408,2009,158,405,2009,157,405,2007,158,405,2010,158,407,2007,159,407,2010,158,405,2009,155,406,2007,158,406,2008,157,409,2011,160,407,2006,156,406,2009,160,404,2005,154,405,2011,160,411,2012,157,407,2010,155,406,2011,158,402,2010,156,404,2006,161,408,2012,159,407,2006,154,406,2011,158,407,2011,159,405,2011,158,405,2010,156,404,2008,156,406,2010,157,408,2010,160,405,2009,153,403,2007,157,405,2008,157,408,2008,159,410,2011,159,405,2007,156,406,2007},\r
+{53, 157,405,2014,159,407,2006,156,411,2013,160,405,2004,159,407,2009,160,405,2006,153,406,2012,158,405,2005,156,409,2013,158,406,2007,157,404,2010,158,405,2009,159,408,2011,158,404,2010,156,402,2009,158,404,2010,158,406,2009,157,407,2012,157,405,2012,159,403,2008,159,404,2010,158,404,2010,157,407,2008,157,406,2012,157,405,2009,158,403,2009,157,407,2010,159,406,2011,159,406,2011,158,403,2008,157,406,2013,157,407,2011,155,409,2012,158,406,2008,156,406,2011,162,404,2006,159,403,2008,158,407,2010,158,408,2013,159,405,2011,155,408,2012,158,407,2010,157,407,2007,157,408,2010,158,405,2010,157,405,2008,159,407,2011,159,407,2012,156,405,2010,156,405,2008,157,406,2011,157,404,2009,156,405,2012},\r
+{52, 159,405,2010,159,400,2010,158,399,2009,155,404,2011,156,406,2013,155,405,2009,155,402,2012,160,401,2012,156,398,2009,158,402,2011,160,403,2009,157,403,2009,154,398,2013,154,405,2011,157,402,2009,155,402,2014,159,400,2010,155,397,2010,158,401,2011,158,404,2013,155,405,2012,156,400,2009,153,400,2011,158,399,2008,159,401,2012,155,400,2010,156,399,2008,159,404,2010,156,402,2012,153,399,2010,154,400,2010,158,402,2010,158,403,2011,160,401,2009,156,402,2014,157,404,2007,152,401,2012,157,403,2008,159,402,2011,158,405,2009,158,401,2010,158,403,2010,155,401,2008,156,404,2012,156,407,2012,156,405,2011,156,402,2010,158,402,2011,159,403,2009,155,400,2011,154,404,2012,159,405,2010},\r
+{52, 157,404,2012,157,404,2010,156,401,2009,155,402,2011,157,406,2012,161,403,2012,156,402,2012,156,402,2009,158,405,2013,157,404,2011,155,405,2012,157,403,2008,157,404,2011,159,404,2009,157,403,2008,157,405,2008,157,406,2012,156,405,2010,155,404,2009,156,403,2009,158,407,2008,157,406,2010,157,409,2010,158,403,2010,157,403,2008,157,403,2009,157,407,2012,160,402,2009,158,402,2010,158,400,2009,155,403,2008,156,405,2012,158,406,2011,159,403,2010,156,399,2012,157,400,2013,158,404,2007,156,403,2013,158,405,2011,155,399,2008,157,403,2013,160,403,2008,159,401,2014,160,403,2011,157,401,2011,161,405,2011,155,394,2007,151,401,2009,160,404,2010,158,404,2014,159,397,2008,158,400,2008},\r
+{53, 157,404,2011,157,401,2012,158,396,2010,156,397,2009,155,401,2010,158,404,2012,160,400,2012,158,397,2008,158,400,2010,156,404,2013,160,405,2009,156,401,2009,156,404,2011,158,401,2006,157,404,2007,161,405,2009,160,403,2008,159,408,2013,167,414,2010,168,405,2007,155,396,2006,154,394,2007,161,400,2008,163,399,2008,162,390,2008,155,392,2014,147,396,2024,159,365,2019,177,274,2086,159,354,2003,160,433,1978,145,472,1978,124,461,2001,145,446,2029,156,437,1987,152,444,1982,164,351,2016,134,333,2034,144,399,2014,177,420,2013,152,416,2013,143,414,2012,156,426,2011,159,453,1983,159,411,2010,146,366,2029,143,385,2013,162,417,2007,160,417,2005,151,410,1998,149,413,2024,171,416,2002,149,391,1996},\r
+{52, 147,423,2013,163,416,2007,143,434,2023,154,418,2010,152,423,2013,157,415,2004,157,415,1997,147,449,1979,160,416,2015,154,384,2029,144,410,2005,157,416,2006,157,414,2004,150,412,2007,157,416,2005,154,420,2007,152,421,2012,157,417,2010,156,413,2007,156,415,2007,156,413,2007,155,417,2010,156,409,2004,150,412,2010,154,417,2006,152,414,2012,154,417,2010,157,409,2006,156,411,2008,153,414,2011,154,418,2011,156,417,2009,156,420,2009,160,421,2007,148,433,2012,150,456,1968,156,466,1996,161,381,2024,147,358,2034,147,396,1999,165,401,2002,165,429,2017,167,409,2010,147,409,2014,158,413,2006,159,423,2016,160,415,2016,159,407,2010,161,402,2000,157,410,2007,162,420,2010,162,425,2008},\r
+{52, 162,427,2011,164,419,2006,153,423,1989,158,425,1990,170,379,2026,150,415,2006,165,422,2011,162,414,2010,156,409,2007,162,404,2006,162,412,2009,158,410,2011,155,409,2012,158,408,2011,162,405,2011,156,399,2007,155,401,2010,159,401,2009,160,402,2007,156,402,2012,157,402,2011,157,402,2011,159,405,2011,159,402,2011,158,404,2010,159,400,2010,157,404,2009,158,399,2009,159,403,2011,159,399,2007,154,404,2012,158,407,2011,160,405,2009,158,402,2010,157,404,2012,159,402,2008,162,406,2010,159,405,2010,158,405,2009,157,405,2011,157,404,2010,157,403,2012,160,404,2010,158,405,2011,157,407,2009,158,404,2012,158,404,2010,156,402,2009,156,406,2008,157,404,2010,160,403,2009,159,401,2009},\r
+{52, 158,403,2010,155,405,2012,159,400,2008,157,404,2012,157,402,2010,152,401,2012,158,403,2009,158,402,2011,156,403,2011,159,402,2011,157,402,2011,155,399,2009,156,401,2010,153,402,2012,155,403,2011,157,403,2009,155,401,2011,157,402,2010,156,398,2010,155,402,2011,156,403,2010,154,404,2014,155,400,2008,155,403,2011,157,401,2010,157,401,2012,156,398,2013,156,396,2009,155,400,2010,156,405,2011,151,401,2013,156,395,2010,158,393,2010,150,403,2021,161,399,2005,154,386,2008,153,410,2015,152,392,2012,153,395,2015,161,396,2011,156,394,2011,152,392,2011,154,399,2010,152,398,2011,152,396,2015,153,395,2015,153,395,2011,158,398,2012,158,396,2011,155,396,2016,155,395,2011,152,393,2010},\r
+{52, 151,397,2010,154,400,2013,155,398,2016,158,396,2012,157,393,2011,153,395,2014,155,399,2011,152,399,2009,151,396,2011,152,395,2013,156,395,2010,156,395,2011,156,396,2010,154,397,2013,155,396,2012,154,399,2012,153,398,2011,150,395,2013,155,396,2010,156,398,2012,157,398,2012,155,397,2014,154,397,2013,154,396,2013,152,397,2011,155,400,2013,154,401,2011,156,398,2014,157,395,2009,153,396,2011,154,399,2011,154,400,2009,154,397,2011,155,397,2010,153,396,2012,155,400,2013,157,400,2011,154,400,2013,156,395,2012,155,397,2011,155,397,2010,152,400,2013,154,402,2013,154,398,2012,155,398,2012,152,398,2012,153,401,2012,155,400,2011,154,398,2011,152,399,2012,154,399,2013,154,399,2012},\r
+{53, 154,399,2014,153,397,2011,155,398,2012,154,399,2013,156,399,2012,154,400,2012,154,399,2010,155,396,2012,155,398,2011,155,397,2009,155,399,2011,153,400,2012,154,401,2013,155,398,2010,153,398,2010,155,399,2011,155,400,2013,154,399,2012,155,399,2008,153,398,2010,156,401,2010,156,402,2010,154,398,2012,155,400,2011,157,400,2012,153,401,2014,156,400,2011,154,398,2012,157,399,2012,154,398,2011,153,398,2012,155,401,2011,153,402,2011,154,400,2015,155,396,2012,153,397,2009,155,399,2012,155,399,2011,154,398,2010,156,398,2010,154,397,2010,155,400,2014,157,401,2013,154,397,2010,153,398,2014,157,397,2012,153,397,2011,153,397,2012,155,400,2011,156,398,2012,155,395,2009,155,397,2012,155,401,2011},\r
+{52, 154,398,2011,154,398,2011,155,396,2011,154,397,2013,157,396,2011,156,400,2012,156,399,2012,154,397,2012,155,398,2012,155,398,2012,157,399,2011,154,398,2009,157,397,2010,156,399,2013,157,398,2011,152,400,2012,154,400,2011,157,398,2010,155,398,2011,155,399,2010,156,399,2012,158,401,2014,156,401,2011,152,398,2012,151,397,2013,156,398,2011,156,398,2011,153,398,2011,154,398,2012,154,399,2010,158,400,2015,156,397,2011,154,397,2012,153,399,2013,153,399,2015,157,398,2009,154,396,2013,154,397,2015,155,398,2013,154,397,2010,154,396,2012,156,398,2011,155,396,2010,155,395,2012,155,396,2012,157,395,2011,154,398,2014,153,395,2010,152,395,2012,154,398,2012,155,397,2012,155,396,2013},\r
+{52, 153,395,2012,155,395,2010,154,398,2014,159,399,2013,154,398,2012,154,397,2012,153,396,2010,156,396,2011,158,397,2013,157,398,2013,154,398,2012,153,399,2012,154,400,2013,154,397,2010,152,396,2015,154,399,2011,157,398,2013,158,400,2012,154,398,2013,152,397,2009,154,399,2013,153,400,2012,154,398,2014,153,397,2012,156,398,2013,156,398,2013,157,399,2012,154,400,2013,152,401,2016,156,403,2010,153,398,2012,154,397,2012,155,397,2009,155,402,2011,156,403,2011,154,398,2009,154,402,2009,157,406,2011,158,411,2014,157,404,2010,155,402,2007,157,400,2007,157,402,2010,158,403,2010,154,409,2015,159,407,2011,157,403,2012,156,397,2009,154,395,2008,158,395,2010,154,392,2005,152,399,2012},\r
+{53, 156,400,2012,153,398,2014,151,394,2011,149,391,2011,150,395,2013,156,396,2014,155,393,2012,154,389,2010,155,393,2014,157,395,2015,154,394,2011,151,395,2014,153,397,2012,154,394,2013,154,396,2014,152,395,2014,157,398,2013,157,397,2012,154,395,2012,152,400,2015,155,394,2011,155,392,2012,154,389,2010,152,396,2013,157,397,2013,153,395,2016,154,395,2013,157,390,2008,153,391,2014,155,393,2010,151,396,2016,157,397,2015,156,391,2015,152,391,2011,153,392,2014,157,393,2013,154,393,2014,155,393,2015,155,390,2010,156,392,2013,158,395,2014,156,392,2014,155,392,2012,154,393,2011,157,395,2012,156,395,2013,157,395,2012,155,390,2011,154,394,2012,159,393,2009,155,395,2015,155,393,2014,153,391,2014},\r
+{52, 155,394,2011,156,394,2011,155,393,2014,156,394,2010,151,395,2013,156,398,2013,156,393,2010,155,394,2012,156,397,2012,156,403,2015,157,397,2012,152,394,2011,156,395,2009,161,406,2010,165,409,2013,156,412,2012,155,402,2008,157,397,2004,156,407,2007,161,416,2012,155,414,2012,153,406,2007,156,402,2006,159,409,2008,163,406,2006,159,402,2010,158,407,2010,159,411,2015,158,404,2011,156,393,2011,153,396,2009,158,401,2011,162,409,2013,155,402,2013,151,398,2012,156,394,2009,157,395,2010,156,397,2013,157,397,2012,158,401,2012,159,398,2010,155,396,2013,157,396,2010,158,393,2012,157,402,2012,156,399,2010,154,401,2011,153,397,2009,157,396,2010,158,393,2009,155,399,2011,155,402,2015},\r
+{52, 158,404,2015,155,396,2014,154,395,2012,154,396,2013,158,403,2012,159,401,2011,156,398,2010,155,396,2011,155,393,2009,158,398,2010,156,400,2012,155,402,2013,156,397,2012,156,397,2015,156,396,2012,155,395,2010,158,396,2006,149,396,2017,166,397,2005,146,394,2013,166,403,2013,154,382,2013,156,396,2010,162,395,2011,156,402,2014,156,393,2014,154,391,2012,156,392,2012,160,396,2013,156,394,2014,158,390,2010,153,392,2013,155,394,2010,156,393,2013,155,392,2012,154,392,2011,156,396,2013,157,394,2011,157,392,2016,156,391,2010,152,393,2012,156,398,2012,159,401,2010,156,393,2012,157,394,2012,156,395,2011,157,401,2012,158,402,2012,156,402,2014,157,396,2008,156,396,2010,158,401,2010},\r
+{52, 159,404,2013,158,402,2011,158,399,2010,157,399,2010,159,401,2013,155,403,2014,155,401,2011,156,401,2009,160,401,2010,160,399,2010,156,397,2011,156,398,2009,157,401,2013,158,402,2014,155,399,2009,157,397,2010,160,401,2010,160,400,2012,156,400,2011,159,396,2011,156,399,2008,157,408,2013,158,406,2015,154,397,2011,156,390,2006,158,395,2007,160,403,2011,157,406,2015,157,401,2015,155,393,2008,155,392,2008,158,398,2011,158,396,2014,156,393,2012,154,395,2012,156,399,2015,154,396,2018,152,385,2019,150,382,2008,160,408,2004,165,408,2013,152,394,2013,150,395,2009,160,401,2011,156,404,2013,154,398,2013,157,395,2009,159,402,2012,156,402,2014,156,402,2011,159,398,2009,155,398,2012},\r
+{53, 155,400,2008,154,404,2014,158,404,2009,156,399,2012,157,400,2010,156,403,2009,155,402,2013,156,401,2014,158,397,2008,158,401,2012,156,404,2013,156,401,2007,157,399,2009,155,401,2010,157,401,2013,156,401,2012,155,399,2010,156,402,2009,159,403,2013,155,401,2012,157,398,2009,153,401,2010,155,400,2012,155,403,2016,156,397,2008,153,398,2008,157,399,2013,157,399,2013,157,403,2014,160,399,2010,156,399,2012,157,401,2013,155,400,2014,157,403,2013,158,399,2008,157,400,2009,156,402,2013,157,401,2013,156,404,2013,157,397,2007,157,402,2012,160,405,2011,159,405,2011,156,400,2011,158,399,2010,158,398,2007,156,401,2011,154,401,2012,157,402,2011,158,402,2013,159,392,2021,153,407,2010,161,394,2000},\r
+{52, 150,402,2014,161,398,2010,159,401,2013,158,402,2015,156,398,2015,158,396,2010,156,395,2011,157,400,2011,158,403,2014,156,400,2011,155,399,2011,155,396,2009,155,397,2010,156,399,2010,157,404,2014,157,404,2014,156,400,2011,155,402,2006,157,403,2011,157,402,2009,154,398,2005,155,399,2016,163,410,2011,155,397,2004,155,403,2013,158,394,2011,156,402,2013,164,405,2012,158,405,2016,149,396,2010,151,397,2010,160,400,2009,158,402,2009,151,398,2007,151,400,2009,158,403,2008,159,405,2012,158,402,2009,158,404,2008,160,409,2009,155,409,2011,152,408,2012,161,404,2005,166,401,2005,161,411,2009,163,408,2007,165,411,2008,160,407,2010,158,410,2011,157,404,2008,156,404,2011,160,405,2007},\r
+{52, 160,408,2012,160,414,2012,159,408,2010,158,403,2008,161,399,2001,159,402,2006,162,409,2009,156,410,2015,154,406,2011,166,399,2007,156,402,2011,159,404,2010,161,410,2011,156,404,2014,155,399,2009,161,397,2005,155,400,2009,157,404,2013,160,407,2011,160,403,2008,162,402,2010,154,400,2010,154,403,2011,161,403,2007,161,405,2010,157,407,2013,156,399,2006,160,401,2009,165,396,2005,154,409,2013,162,413,2013,160,408,2013,153,398,2008,158,396,2004,163,407,2010,167,412,2015,161,395,2009,152,390,2006,158,398,2009,165,416,2019,159,411,2018,149,397,2011,156,392,2006,163,401,2011,160,404,2013,157,392,2007,157,390,2004,158,393,2007,159,409,2015,167,420,2020,161,398,2010,151,392,2010},\r
+{53, 164,398,2005,161,405,2015,159,403,2012,157,397,2008,157,403,2009,161,405,2012,161,406,2015,159,401,2008,156,402,2008,161,406,2010,160,407,2009,158,408,2012,160,402,2008,159,407,2007,158,404,2007,161,407,2010,156,403,2009,156,409,2012,171,404,2009,154,411,2016,154,402,2007,160,405,2009,163,405,2009,159,403,2011,159,401,2009,160,408,2012,160,403,2008,155,403,2010,161,398,2008,159,400,2010,158,412,2013,164,412,2015,161,404,2011,161,394,2006,160,390,2004,157,399,2010,163,410,2016,161,409,2020,159,400,2012,159,393,2009,157,392,2009,162,394,2010,162,398,2011,160,394,2012,156,399,2018,161,403,2015,161,399,2014,154,397,2015,156,390,2012,165,386,2004,161,398,2013,157,404,2016,161,402,2013},\r
+{52, 157,394,2012,157,394,2008,165,393,2008,165,396,2010,160,403,2013,158,403,2014,158,403,2015,160,398,2011,158,394,2008,160,401,2013,164,400,2009,162,399,2011,157,397,2010,161,399,2009,160,405,2013,158,398,2009,156,401,2012,164,401,2009,164,401,2014,159,397,2011,158,397,2011,160,393,2010,159,396,2011,160,397,2012,158,395,2015,161,394,2011,161,393,2011,159,392,2012,158,391,2011,157,395,2015,161,398,2013,156,394,2013,158,396,2013,158,390,2010,159,394,2013,161,392,2010,155,395,2012,161,397,2012,160,398,2014,154,396,2013,153,392,2010,162,399,2012,166,396,2009,157,395,2014,159,394,2009,161,395,2010,159,404,2015,159,401,2014,157,394,2013,160,395,2010,162,397,2012,163,399,2012},\r
+{52, 158,396,2012,155,397,2012,159,395,2011,161,395,2013,161,396,2013,158,397,2014,157,398,2014,160,394,2013,160,393,2010,159,397,2013,157,394,2013,156,394,2014,159,393,2010,160,394,2011,158,393,2012,156,392,2011,155,394,2015,158,394,2011,156,393,2014,158,395,2013,159,392,2012,157,390,2011,157,394,2012,157,394,2013,157,393,2013,155,393,2012,156,395,2012,156,390,2012,159,390,2011,161,392,2012,161,393,2013,156,392,2010,155,391,2014,156,388,2013,154,388,2012,159,390,2012,158,394,2014,157,390,2013,157,393,2015,160,391,2013,157,392,2010,157,391,2012,157,393,2014,153,388,2012,157,390,2012,164,391,2013,161,397,2013,158,394,2014,155,394,2013,157,390,2012,161,392,2014,157,395,2013},\r
+{53, 157,397,2013,162,396,2010,163,396,2013,161,390,2006,159,394,2012,158,397,2011,155,400,2012,156,397,2011,164,398,2013,163,392,2009,157,390,2013,158,388,2009,160,400,2012,160,404,2015,153,398,2017,149,388,2010,158,391,2010,173,395,2009,168,395,2014,152,391,2015,148,392,2012,160,393,2011,159,397,2012,154,393,2013,155,394,2011,165,393,2009,165,393,2011,156,392,2013,156,393,2009,155,397,2015,162,399,2012,159,395,2014,159,391,2010,160,394,2010,162,398,2010,160,401,2013,157,392,2009,154,395,2013,160,399,2012,162,399,2012,160,399,2011,158,398,2013,160,394,2012,159,394,2010,156,399,2012,156,400,2012,160,396,2011,156,396,2009,157,398,2010,162,401,2017,165,398,2008,156,396,2013,159,398,2010},\r
+{52, 155,394,2014,156,398,2012,159,397,2012,159,402,2013,161,397,2014,160,394,2011,161,394,2010,157,394,2013,156,398,2014,156,397,2013,159,394,2010,159,394,2013,159,392,2012,158,393,2013,160,391,2015,157,393,2012,159,396,2011,158,393,2013,157,392,2013,159,390,2011,160,392,2010,157,395,2011,156,395,2012,158,393,2014,157,393,2014,161,388,2012,160,392,2012,157,393,2010,152,394,2013,155,391,2013,158,390,2014,158,392,2016,157,390,2014,158,387,2010,159,392,2012,161,393,2013,155,389,2013,155,390,2013,157,390,2012,158,391,2016,160,388,2013,153,387,2014,155,390,2013,157,388,2014,157,394,2015,159,391,2012,156,387,2013,161,389,2014,162,392,2015,159,391,2011,153,394,2011,153,392,2016},\r
+{52, 155,388,2014,160,384,2011,159,391,2013,162,389,2012,157,394,2018,157,388,2014,152,385,2009,159,384,2011,156,389,2016,155,388,2014,158,391,2015,163,385,2015,163,385,2010,159,382,2011,158,391,2015,156,391,2017,156,393,2018,161,390,2015,159,386,2014,157,384,2013,162,383,2011,162,388,2013,161,391,2013,158,391,2014,155,397,2015,158,395,2013,159,388,2011,159,383,2008,162,386,2011,161,387,2011,156,394,2015,155,395,2011,155,396,2016,159,391,2013,158,389,2012,160,387,2013,161,393,2014,161,390,2013,158,393,2014,159,388,2011,156,387,2012,156,393,2014,158,390,2014,159,388,2013,160,387,2011,160,390,2014,160,388,2014,158,388,2012,156,390,2014,158,392,2016,157,389,2014,158,386,2013},\r
+{53, 160,388,2012,161,388,2013,155,389,2015,155,387,2012,156,387,2011,156,389,2012,157,390,2016,157,385,2013,157,385,2013,163,387,2011,159,390,2016,158,389,2014,156,387,2013,158,387,2010,156,388,2016,158,387,2012,158,385,2015,161,386,2010,157,390,2015,158,387,2009,155,386,2014,159,391,2014,158,389,2013,157,387,2015,157,384,2014,157,385,2013,158,387,2014,157,388,2014,156,389,2014,159,386,2011,159,387,2012,159,389,2012,155,384,2013,154,390,2015,162,385,2008,152,386,2021,163,390,2011,154,385,2015,158,385,2013,157,387,2013,159,388,2017,158,383,2012,154,384,2015,158,384,2012,156,385,2014,159,386,2014,158,385,2017,158,386,2011,156,388,2013,159,392,2014,156,386,2014,158,387,2012,159,386,2009},\r
+{52, 158,390,2015,157,390,2015,155,387,2012,158,390,2013,161,388,2014,158,390,2016,161,391,2014,163,391,2011,161,389,2010,154,388,2011,153,389,2012,161,392,2015,163,389,2010,158,393,2016,160,389,2009,155,391,2013,160,389,2010,159,390,2013,156,383,2011,156,388,2015,160,385,2012,160,389,2017,163,380,2017,155,367,2027,151,390,2009,168,407,2001,161,395,2012,151,393,2016,160,395,2015,162,394,2014,157,391,2011,159,392,2009,163,390,2008,159,387,2011,158,392,2012,164,398,2012,161,406,2016,161,404,2019,160,396,2012,158,395,2007,157,387,2005,157,398,2010,165,402,2013,163,408,2013,156,395,2009,156,397,2009,159,397,2011,158,399,2013,161,401,2014,165,400,2010,159,398,2014,157,396,2010},\r
+{52, 154,398,2013,165,403,2010,166,402,2009,155,401,2014,159,403,2009,163,397,2008,163,399,2006,160,404,2011,156,409,2013,161,413,2015,165,401,2004,154,401,2011,165,409,2009,165,408,2012,155,400,2008,163,397,2003,162,406,2012,159,402,2009,154,399,2011,160,402,2008,162,403,2016,164,399,2013,161,395,2008,162,397,2011,162,407,2015,164,397,2011,156,390,2011,160,389,2008,160,396,2010,163,401,2013,163,400,2015,161,393,2010,161,390,2011,157,395,2013,158,399,2016,163,400,2016,162,393,2010,160,393,2011,163,392,2009,159,395,2012,160,396,2009,159,397,2011,160,395,2013,161,398,2013,159,393,2011,154,394,2012,160,397,2011,162,397,2011,157,394,2015,158,393,2011,159,394,2012,160,402,2011},\r
+{53, 159,397,2010,159,397,2013,161,396,2009,155,390,2010,162,397,2012,163,396,2011,157,393,2014,162,395,2011,158,395,2014,162,394,2013,158,394,2013,160,392,2008,160,390,2008,157,393,2012,159,393,2012,160,397,2014,161,398,2014,157,391,2011,157,388,2011,158,390,2012,159,396,2014,161,397,2015,161,391,2014,159,384,2010,157,391,2007,157,397,2015,162,395,2014,158,393,2013,154,390,2010,157,390,2013,161,388,2010,159,385,2013,159,390,2012,158,388,2012,158,388,2015,159,379,2022,154,382,2017,156,407,2000,170,400,2012,156,396,2018,159,390,2012,160,390,2011,156,390,2010,158,392,2011,161,390,2013,156,393,2016,157,387,2012,156,385,2011,158,388,2015,162,375,2024,153,378,2013,157,403,2002,163,402,2007},\r
+{52, 152,389,2014,153,386,2011,159,389,2015,162,384,2011,156,385,2019,158,386,2019,160,399,2014,162,391,2014,152,385,2012,156,390,2012,161,393,2014,160,393,2013,162,391,2010,160,396,2012,165,396,2010,158,401,2014,159,397,2009,160,388,2007,161,399,2012,165,393,2006,160,399,2014,159,403,2016,159,408,2014,168,405,2012,163,402,2013,157,395,2008,160,396,2005,161,404,2007,158,404,2008,158,408,2013,162,401,2008,155,404,2013,169,403,2005,165,406,2013,157,403,2013,158,399,2009,162,408,2013,164,406,2011,159,399,2009,157,399,2011,163,400,2006,159,405,2011,159,407,2012,157,404,2010,161,404,2011,163,402,2014,163,398,2008,160,399,2008,163,407,2010,159,409,2012,155,406,2010,152,396,2008},\r
+{52, 162,404,2010,171,404,2010,163,403,2011,157,402,2007,155,406,2010,156,406,2016,161,401,2007,161,402,2010,162,403,2012,162,403,2009,162,402,2005,158,401,2009,157,404,2009,159,404,2009,159,404,2014,168,404,2012,163,399,2008,159,398,2009,158,399,2009,160,404,2011,159,403,2011,158,408,2012,162,407,2012,162,403,2012,159,397,2008,160,401,2010,164,403,2010,161,401,2010,159,400,2011,158,403,2008,157,403,2011,161,404,2012,160,401,2011,161,400,2010,163,401,2011,162,403,2013,158,398,2007,157,402,2011,163,400,2010,160,398,2011,159,399,2011,165,403,2012,161,402,2010,155,400,2012,159,396,2009,160,400,2011,162,400,2012,159,401,2013,162,400,2009,160,399,2010,161,397,2013,162,399,2012},\r
+{53, 159,399,2010,160,402,2016,158,399,2010,161,396,2010,164,399,2010,159,398,2011,157,393,2012,162,397,2012,164,399,2010,158,402,2014,158,399,2012,161,397,2012,159,401,2012,167,399,2007,158,402,2015,157,401,2011,157,398,2009,162,401,2007,160,405,2012,162,402,2010,159,403,2013,161,402,2011,162,403,2010,161,398,2009,158,405,2011,160,406,2014,164,405,2007,158,396,2012,160,399,2009,161,400,2013,162,404,2011,160,401,2013,160,401,2009,154,400,2019,162,401,2012,160,393,2008,160,401,2009,161,399,2010,156,399,2010,160,401,2015,161,397,2010,158,398,2010,160,398,2010,162,398,2011,161,399,2010,159,400,2011,160,400,2012,158,400,2010,158,398,2013,158,397,2009,163,397,2010,163,401,2011,162,400,2010},\r
+{52, 157,400,2013,165,405,2014,162,402,2008,156,401,2012,164,400,2009,160,397,2009,158,401,2010,160,405,2011,158,406,2014,162,407,2013,164,399,2006,161,394,2006,160,396,2006,163,408,2013,159,406,2013,156,404,2012,161,401,2009,165,400,2012,161,393,2009,158,396,2010,162,400,2015,161,397,2012,155,398,2013,161,401,2012,160,396,2010,157,392,2012,160,395,2009,159,399,2012,159,399,2015,164,396,2013,160,397,2012,157,398,2011,159,400,2013,165,398,2008,159,393,2007,156,400,2012,160,402,2011,161,400,2012,163,397,2011,163,402,2008,161,403,2012,162,402,2013,159,400,2010,159,397,2007,161,398,2010,163,403,2014,163,403,2008,165,404,2012,168,406,2012,163,402,2010,157,401,2011,160,404,2011},\r
+{52, 161,403,2005,161,404,2012,167,403,2010,166,402,2009,161,402,2009,159,404,2010,163,398,2009,158,396,2010,156,408,2016,172,407,2012,169,406,2014,157,394,2011,160,392,2005,158,391,2008,157,401,2013,164,404,2014,165,402,2013,161,395,2009,160,394,2007,163,396,2009,160,402,2016,161,401,2011,160,402,2013,162,400,2012,161,397,2011,161,398,2009,165,400,2009,162,401,2012,164,403,2008,160,402,2010,160,401,2011,161,396,2008,163,398,2007,161,403,2015,166,400,2013,162,398,2011,160,398,2014,159,398,2012,161,394,2012,165,397,2011,162,398,2013,161,397,2013,160,396,2011,160,394,2009,163,395,2012,164,396,2014,162,398,2013,159,397,2012,161,398,2013,163,392,2010,160,392,2009,160,396,2011},\r
+{58, 165,399,2011,162,398,2012,162,398,2014,157,393,2012,158,396,2009,161,397,2011,162,395,2012,166,396,2011,161,395,2008,161,399,2014,164,396,2007,158,395,2012,158,397,2014,160,392,2010,161,396,2009,163,397,2014,162,398,2014,163,393,2010,161,394,2013,160,396,2010,160,395,2012,161,396,2011,164,394,2010,162,394,2017,161,398,2010,163,388,2009,163,405,2013,161,391,2011,157,396,2017,163,387,2006,161,399,2017,166,394,2009,158,394,2014,160,394,2011,159,393,2012,159,392,2012,161,396,2012,161,400,2013,164,395,2013,162,392,2012,160,388,2009,159,394,2012,161,397,2014,160,396,2013,159,395,2015,160,393,2012,160,392,2013,163,392,2011,161,393,2014,159,394,2013,159,397,2013,161,394,2014,162,393,2012,160,391,2010,160,395,2012,164,393,2010,160,391,2012,157,400,2018},\r
+{52, 164,389,2004,153,390,2017,165,391,2009,159,392,2012,164,396,2012,159,395,2017,165,392,2007,162,393,2009,160,398,2017,165,394,2010,160,390,2009,162,398,2012,161,399,2014,159,399,2011,161,400,2014,166,402,2010,163,401,2009,158,405,2011,162,403,2013,163,402,2007,161,410,2010,161,412,2010,162,406,2010,163,393,1999,162,407,2010,166,417,2011,159,406,2010,157,406,2010,167,410,2011,160,397,2009,158,390,2006,164,397,2005,164,407,2017,167,408,2016,162,395,2011,159,396,2006,160,395,2013,163,396,2014,161,391,2012,162,392,2009,163,393,2013,164,392,2011,162,393,2014,163,392,2011,157,389,2013,159,389,2013,161,387,2010,163,390,2011,162,394,2015,163,391,2014,163,387,2009,159,387,2013},\r
+{52, 158,392,2014,161,391,2013,159,390,2013,160,390,2010,161,387,2010,162,390,2010,158,391,2012,159,390,2010,156,388,2012,160,387,2012,160,393,2016,161,397,2016,161,387,2015,163,382,2006,160,386,2010,161,391,2014,162,394,2017,165,391,2014,162,392,2013,162,391,2011,160,394,2013,163,388,2009,161,389,2011,160,393,2011,160,397,2014,162,396,2010,159,396,2013,161,393,2010,163,395,2014,166,395,2007,157,393,2014,163,399,2014,163,395,2011,158,393,2010,162,396,2014,161,393,2012,162,395,2013,163,393,2010,161,396,2011,163,394,2011,159,395,2014,161,393,2013,161,392,2010,164,395,2012,163,397,2016,163,393,2012,159,395,2012,165,397,2012,165,396,2010,161,394,2010,160,396,2012,164,399,2015},\r
+{53, 164,395,2013,162,398,2011,161,396,2011,164,394,2012,165,396,2010,161,392,2008,162,396,2014,167,394,2012,163,397,2012,161,394,2013,163,398,2015,166,391,2010,161,391,2012,161,394,2010,162,398,2013,164,394,2011,163,394,2014,162,394,2014,160,392,2011,161,392,2012,165,393,2012,163,395,2013,164,397,2014,164,393,2011,161,392,2013,164,394,2012,162,397,2014,163,397,2013,163,395,2014,167,395,2010,165,400,2010,163,401,2013,162,401,2015,164,397,2009,161,400,2010,162,400,2013,169,400,2009,164,397,2009,161,402,2008,168,404,2010,166,406,2014,161,401,2011,161,401,2008,166,401,2008,168,404,2015,165,399,2009,159,403,2010,163,409,2008,165,408,2013,159,400,2010,161,394,2005,164,399,2007,164,406,2014},\r
+{52, 170,404,2011,162,405,2010,160,403,2013,160,404,2013,166,397,2011,165,396,2008,162,397,2008,160,404,2012,165,404,2014,164,398,2011,160,396,2009,162,398,2011,164,400,2013,165,402,2010,167,402,2011,158,403,2010,160,398,2007,165,400,2009,165,397,2009,163,403,2012,163,405,2015,161,400,2010,165,396,2008,166,401,2010,162,404,2015,168,408,2013,162,406,2014,162,394,2007,160,393,2009,164,399,2007,161,405,2014,162,408,2013,164,400,2009,161,398,2010,167,399,2009,163,402,2012,162,402,2014,165,403,2009,164,404,2011,162,404,2010,162,399,2010,164,400,2009,163,400,2007,163,404,2011,166,404,2011,163,405,2010,163,401,2008,163,400,2011,164,400,2010,162,400,2009,160,403,2012,161,404,2011},\r
+{52, 164,398,2008,161,397,2007,162,396,2009,165,399,2010,165,399,2012,159,396,2013,161,396,2009,162,399,2012,161,398,2011,161,395,2012,161,394,2013,164,395,2012,163,394,2011,161,399,2017,161,396,2012,159,396,2013,160,393,2012,164,396,2013,163,394,2010,162,397,2014,162,396,2012,166,395,2013,164,391,2011,158,394,2012,164,393,2014,163,393,2013,159,392,2010,163,396,2010,162,395,2017,164,392,2010,161,391,2012,160,390,2014,161,393,2010,162,394,2015,162,395,2014,164,392,2009,162,393,2015,162,394,2016,162,395,2010,162,396,2017,163,391,2013,161,385,2011,162,385,2007,159,391,2011,164,404,2018,165,398,2018,158,386,2012,156,385,2004,157,391,2013,161,394,2018,171,395,2010,159,386,2011},\r
+{53, 161,394,2011,164,394,2013,163,394,2015,164,389,2008,157,397,2011,166,392,2008,164,395,2015,166,391,2006,161,393,2012,166,400,2015,162,398,2012,165,394,2011,164,392,2011,166,392,2007,165,393,2012,167,397,2016,166,392,2014,163,391,2009,164,389,2013,163,391,2013,160,385,2012,164,389,2015,168,387,2012,163,386,2015,163,389,2016,164,385,2013,163,383,2014,163,381,2012,160,388,2017,164,386,2014,164,383,2018,164,379,2011,164,379,2012,161,388,2019,161,384,2014,160,384,2016,167,382,2012,164,380,2014,165,383,2016,162,382,2011,161,385,2018,169,379,2012,162,371,2008,158,378,2015,164,376,2017,166,360,2057,156,354,2005,162,425,1995,183,403,2007,150,390,2018,159,384,2015,172,392,2015,163,389,2012},\r
+{52, 160,390,2015,168,398,2016,172,398,2013,164,396,2011,162,395,2011,163,401,2009,166,406,2012,167,417,1996,169,412,2005,171,375,2020,158,393,2016,172,404,2010,165,403,2009,157,399,2010,163,400,2008,165,401,2011,165,401,2013,172,396,2011,169,402,2010,166,401,2013,164,400,2010,162,397,2010,163,399,2012,165,398,2012,167,400,2013,167,395,2010,167,397,2011,167,394,2010,163,393,2012,165,395,2014,167,398,2014,165,396,2014,163,395,2015,169,393,2012,167,392,2011,165,391,2012,164,394,2011,164,396,2013,166,398,2011,166,393,2011,163,395,2012,166,394,2011,166,396,2011,168,399,2015,167,398,2011,165,395,2010,164,395,2010,164,396,2010,165,396,2013,166,396,2013,167,394,2010,164,397,2014},\r
+{52, 166,392,2010,165,393,2010,165,395,2009,165,392,2010,163,393,2013,167,395,2012,167,391,2014,165,394,2013,167,387,2007,164,394,2017,169,389,2009,163,388,2015,164,389,2011,163,392,2016,166,393,2014,165,392,2014,166,392,2012,164,388,2013,165,389,2010,166,389,2013,166,391,2015,164,389,2010,165,392,2012,166,393,2013,165,392,2010,164,392,2013,166,391,2009,167,390,2010,163,392,2010,164,393,2015,165,395,2012,167,392,2010,166,393,2014,164,396,2014,166,391,2009,166,391,2011,164,391,2011,164,394,2013,165,394,2015,168,392,2008,165,389,2010,166,393,2010,167,395,2012,165,395,2015,167,394,2009,164,395,2012,164,397,2014,166,397,2011,166,391,2006,163,392,2007,165,398,2007,165,403,2014},\r
+{52, 165,401,2012,166,400,2009,164,396,2012,165,396,2009,166,394,2010,165,403,2013,168,402,2012,168,401,2013,165,394,2009,161,394,2008,162,399,2009,167,403,2013,168,400,2010,165,394,2009,162,396,2013,167,398,2012,165,391,2012,164,397,2010,163,397,2012,165,401,2011,161,391,2012,162,398,2013,167,396,2013,165,392,2011,163,388,2004,160,394,2013,163,398,2014,164,394,2013,164,391,2014,169,394,2008,164,395,2012,165,398,2015,166,395,2012,164,393,2009,164,390,2010,165,398,2012,166,400,2014,167,394,2011,165,391,2012,167,392,2008,163,395,2016,165,394,2011,165,397,2014,164,393,2011,162,393,2014,166,391,2010,163,395,2013,166,396,2011,166,393,2013,164,390,2012,160,390,2012,164,392,2011},\r
+{53, 166,393,2012,161,393,2014,163,395,2013,165,391,2011,162,390,2011,162,392,2011,162,393,2010,164,393,2014,163,396,2012,163,392,2011,163,392,2011,163,395,2011,165,393,2012,165,395,2012,160,394,2014,163,393,2010,164,390,2011,164,391,2011,163,393,2015,161,393,2012,164,389,2012,163,391,2012,163,390,2013,162,391,2013,162,388,2013,164,391,2012,164,390,2011,161,393,2013,163,390,2013,163,387,2014,165,390,2013,165,390,2013,163,391,2012,161,393,2015,161,390,2013,165,388,2012,164,391,2016,165,390,2009,159,393,2014,167,392,2012,164,390,2010,160,389,2012,163,392,2013,164,393,2013,166,390,2015,166,389,2011,162,389,2011,161,389,2013,164,390,2011,162,389,2013,162,390,2014,162,387,2013,164,388,2013},\r
+{52, 164,387,2016,161,389,2013,162,390,2012,165,391,2014,162,388,2011,161,388,2013,165,391,2014,165,385,2013,162,389,2012,164,392,2013,161,395,2014,167,392,2013,162,388,2012,159,387,2010,165,392,2013,167,395,2014,165,393,2016,165,389,2011,162,388,2011,164,390,2014,164,393,2011,167,394,2015,167,393,2014,164,388,2010,163,390,2012,165,392,2013,165,390,2014,160,390,2015,164,392,2013,167,394,2010,167,390,2011,163,388,2015,163,391,2012,164,392,2014,164,392,2014,166,393,2015,164,391,2015,163,390,2012,167,390,2014,162,392,2013,162,393,2014,164,392,2013,167,393,2012,163,390,2013,164,390,2010,164,392,2012,166,391,2014,164,391,2014,163,390,2013,165,389,2013,162,390,2014,164,391,2011},\r
+{52, 163,391,2014,165,392,2013,168,389,2012,164,390,2012,163,389,2014,164,391,2012,162,391,2013,164,391,2014,164,388,2013,166,388,2013,163,388,2014,161,389,2012,161,388,2012,163,391,2014,165,392,2015,163,389,2014,166,386,2012,166,389,2010,163,393,2013,164,393,2014,164,390,2012,163,389,2012,162,389,2011,164,391,2012,165,390,2014,166,391,2014,164,392,2011,163,392,2014,164,391,2010,161,390,2013,165,391,2011,167,391,2013,165,388,2011,163,389,2012,165,390,2010,164,391,2014,163,395,2014,163,390,2012,166,388,2013,165,391,2010,163,391,2014,165,391,2013,163,391,2012,164,392,2013,164,392,2013,163,391,2013,164,390,2013,163,390,2013,164,388,2016,162,388,2011,163,391,2015,162,392,2014},\r
+{53, 162,390,2013,165,389,2011,164,391,2012,163,392,2013,162,392,2012,162,391,2013,163,393,2013,165,390,2013,164,390,2012,162,391,2012,163,389,2011,164,390,2012,162,393,2015,163,394,2015,163,392,2015,166,386,2011,166,388,2013,161,389,2012,161,390,2013,164,394,2015,164,393,2015,163,387,2013,163,387,2011,163,390,2012,166,390,2012,164,388,2014,161,389,2013,162,391,2012,165,392,2016,165,392,2014,160,388,2014,163,388,2013,167,391,2014,163,390,2012,163,391,2012,162,392,2011,160,392,2014,164,390,2014,164,389,2014,163,389,2011,163,390,2014,165,391,2014,162,390,2011,160,390,2014,161,391,2014,163,386,2014,164,386,2014,164,389,2013,165,390,2014,163,390,2013,162,390,2015,162,390,2011,163,390,2017},\r
+{52, 164,389,2012,165,388,2012,165,391,2012,162,390,2013,164,390,2015,161,388,2012,160,392,2014,163,393,2013,166,388,2011,161,388,2011,163,387,2013,165,391,2015,163,392,2011,162,391,2014,160,390,2010,162,390,2011,164,393,2013,163,389,2014,163,389,2012,164,390,2012,166,392,2013,162,388,2014,160,389,2015,161,391,2015,164,390,2013,165,387,2011,162,389,2012,164,391,2013,167,389,2014,162,389,2011,162,390,2012,161,390,2013,163,391,2013,165,388,2013,165,390,2012,165,389,2012,162,390,2012,161,387,2012,162,392,2012,164,390,2013,160,388,2013,163,389,2011,168,390,2013,164,391,2014,162,389,2015,163,390,2012,161,389,2013,161,390,2014,164,388,2014,163,385,2012,165,391,2016,165,389,2013},\r
+{52, 162,391,2014,162,391,2013,162,388,2014,162,387,2013,164,388,2010,165,389,2012,165,391,2012,162,389,2012,161,389,2014,162,391,2013,162,390,2014,166,388,2014,163,387,2013,162,389,2013,164,391,2015,162,389,2013,162,389,2011,162,386,2011,160,389,2011,162,389,2013,167,396,2012,162,392,2016,163,392,2015,162,389,2014,164,391,2013,165,388,2013,161,390,2013,161,390,2012,163,395,2014,166,390,2013,165,389,2012,161,390,2010,162,392,2014,164,387,2013,161,390,2013,165,390,2013,163,392,2013,164,392,2013,166,392,2010,163,386,2012,161,388,2012,161,385,2011,160,392,2011,165,389,2011,162,388,2015,163,384,2013,164,385,2015,165,386,2012,165,386,2011,159,387,2015,161,387,2013,160,387,2013},\r
+{53, 165,384,2013,164,386,2014,163,381,2013,163,384,2012,165,387,2014,161,393,2017,163,391,2016,162,389,2013,165,386,2011,166,386,2010,162,387,2011,164,390,2012,164,392,2016,161,389,2013,164,391,2014,166,392,2011,163,388,2012,162,388,2013,164,390,2011,163,389,2013,164,392,2012,162,392,2014,162,392,2013,164,387,2010,162,389,2013,165,391,2014,166,391,2012,163,392,2012,160,388,2013,160,388,2009,165,389,2013,166,389,2015,165,390,2012,163,388,2016,162,390,2013,162,392,2015,162,399,2017,162,398,2014,164,395,2012,164,393,2007,165,399,2012,167,398,2008,163,398,2007,158,399,2010,164,412,2010,167,409,2010,158,398,2009,161,395,2004,167,396,2006,166,403,2008,164,404,2014,162,406,2017,166,397,2007},\r
+{53, 167,395,2010,167,393,2010,161,389,2012,162,393,2013,166,393,2016,165,388,2013,162,386,2014,165,395,2014,166,394,2017,164,387,2014,165,379,2012,163,381,2007,160,388,2013,164,394,2018,164,388,2016,163,383,2013,165,380,2013,164,383,2010,164,388,2012,160,390,2014,161,386,2012,160,384,2012,159,386,2013,164,382,2014,164,384,2015,164,383,2015,162,385,2015,163,386,2015,161,382,2012,160,382,2016,160,381,2009,160,381,2013,163,384,2017,167,386,2017,167,386,2016,160,385,2019,159,376,2012,159,378,2011,162,384,2013,164,387,2014,162,382,2016,163,381,2015,165,383,2013,164,383,2016,162,379,2013,158,385,2014,159,385,2014,163,384,2016,165,379,2014,162,378,2013,164,383,2014,163,384,2015,158,383,2017},    \r
+};\r
+static const uint32_t duration_SPO2[] = \r
+{\r
+1013,\r
+1048,\r
+1062,\r
+1059,\r
+1037,\r
+1062,\r
+1065,\r
+1038,\r
+1058,\r
+1060,\r
+1040,\r
+1058,\r
+1060,\r
+1039,\r
+1060,\r
+1060,\r
+1036,\r
+1061,\r
+1061,\r
+1040,\r
+1059,\r
+1062,\r
+1035,\r
+1060,\r
+1062,\r
+1034,\r
+1062,\r
+1059,\r
+1060,\r
+1038,\r
+1060,\r
+1061,\r
+1036,\r
+1060,\r
+1061,\r
+1037,\r
+1062,\r
+1063,\r
+1037,\r
+1059,\r
+1060,\r
+1145,\r
+1059,\r
+1063,\r
+1036,\r
+1062,\r
+1062,\r
+1037,\r
+1059,\r
+1061,\r
+1035,\r
+1060,\r
+1061,\r
+1048,\r
+1047,\r
+1064,\r
+1048,\r
+1049,\r
+1063,    \r
+};\r
+\r
+static const uint8_t frame_SPO2[] = \r
+{\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,    \r
+};\r
+       \r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/pxialg_spo2.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/pxialg_spo2.h
new file mode 100644 (file)
index 0000000..fdda926
--- /dev/null
@@ -0,0 +1,152 @@
+#ifndef __PXIALG_SPO2_H__\r
+#define __PXIALG_SPO2_H__\r
+\r
+\r
+#include <stdint.h>\r
+\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+#pragma pack(1)\r
+typedef struct SpO2_mems {\r
+       int16_t data[3];\r
+} SpO2_mems_t;\r
+\r
+typedef struct SpO2_info {\r
+       float IR_DC;\r
+       float R_DC;\r
+       float G_DC;\r
+       float IR_AC;\r
+       float R_AC;\r
+       float G_AC;\r
+       float R_IR_Ratio;\r
+       float R_G_Ratio;\r
+       float G_IR_Ratio;\r
+       float Noise;\r
+       float SpO2_ref;\r
+       float PI;\r
+       float PVI;\r
+       float RMS;\r
+       float MEMS;\r
+       float Output[5];\r
+       float xyz_mean[3];\r
+} SpO2_info_t;\r
+#pragma pack()\r
+\r
+typedef enum {\r
+       SPO2_MSG_SUCCESS = 0,\r
+       SPO2_MSG_ALG_NOT_OPEN,\r
+       SPO2_MSG_ALG_REOPEN,\r
+       SPO2_MSG_ALG_NOT_SUPPORT,\r
+    SPO2_MSG_INVALID_ARGUMENT,\r
+       SPO2_MSG_MOVING_SPO2_READY = 0x100,\r
+       SPO2_MSG_MOVING_SPO2_NOT_READY,\r
+       SPO2_MSG_MOVING_SPO2_STOP,\r
+}spo2_msg_code_t;\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+\r
+PXIALG_API uint32_t SpO2_OpenSize(void);\r
+PXIALG_API int SpO2_Open(void *mem);\r
+PXIALG_API int SpO2_Close(void);\r
+PXIALG_API int SpO2_GetSpO2(float *spo2);\r
+PXIALG_API int SpO2_GetReadyFlag(uint8_t *ready_flag);\r
+PXIALG_API int SpO2_GetPeriodicity(float *periodicity);\r
+PXIALG_API int SpO2_Version(void);\r
+PXIALG_API int SpO2_Process(int touch_flag, int total_channel, int *input, int samples_per_ch, float time_in);\r
+PXIALG_API int SpO2_ProcessD(int touch_flag, int total_channel, int *input, int samples_per_ch, float time_in);\r
+PXIALG_API int SpO2_GetFilteredData(int touch_flag, int total_channel, int expo_R,  int expo_IR, int DAC_R, int DAC_IR, float **filter_R, float **filter_IR, int *FilteredDataLength);\r
+\r
+//parameters\r
+PXIALG_API int SpO2_SetIIRFilterRatio(float IIRFilterRatio);   //0 ~ 0.5. bigger value more smooth.\r
+PXIALG_API int SpO2_SetMotionDetectionLevel(float level);\r
+PXIALG_API int SpO2_SetInputModelScale(float scale);\r
+PXIALG_API int SpO2_SetInputCorrelationTh(float th);\r
+PXIALG_API int SpO2_SetInputRatioLow(float ratio);\r
+PXIALG_API int SpO2_SetInputCoefLow0(float coef);\r
+PXIALG_API int SpO2_SetInputCoefLow1(float coef);\r
+PXIALG_API int SpO2_SetInputCoefLow2(float coef);\r
+PXIALG_API int SpO2_SetInputCoefLow3(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid0(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid1(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid2(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid3(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh0(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh1(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh2(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh3(float coef);\r
+PXIALG_API int SpO2_SetInputRatioHighBound(float bound);\r
+PXIALG_API int SpO2_SetInputRatioLowBound(float bound);\r
+PXIALG_API int SpO2_SetInputFlagCheckHr(int value);\r
+PXIALG_API int SpO2_SetOutputHighBound(float value);\r
+PXIALG_API int SpO2_SetOutputLowBound(float value);\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Constrain(int value);\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Th(float value);\r
+\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Check_Sec(int value);\r
+\r
+PXIALG_API int SpO2_Set_Motion_Rms_Th(float value);\r
+PXIALG_API int SpO2_Set_Motion_Rms_Th2(float value);\r
+\r
+PXIALG_API int SpO2_Set_Correlation_Th2_Count(int value);\r
+PXIALG_API int SpO2_Set_Input_Correlation_Th2(float value);\r
+\r
+PXIALG_API int SpO2_Set_Flag_Hold_Breathe_Mode(char value);\r
+\r
+PXIALG_API int SpO2_Set_Keep_Init_SpO2_Bound(float value);\r
+PXIALG_API int SpO2_Set_Keep_Init_SpO2_Count_Th(int value);\r
+PXIALG_API int SpO2_Set_SpO2_Bias_Value(float value);\r
+PXIALG_API int SpO2_Set_SpO2_Outlier_Smooth_Coef(float value);\r
+PXIALG_API int SpO2_Set_SpO2_Decrease_Coef(float value);\r
+\r
+PXIALG_API int SpO2_Set_Motion_MEMS_Th(float value);\r
+\r
+PXIALG_API int SpO2_Set_T1(float value);\r
+PXIALG_API int SpO2_Set_T2(float value);\r
+PXIALG_API int SpO2_Set_T3(float value);\r
+PXIALG_API int SpO2_Set_T4(float value);\r
+PXIALG_API int SpO2_Set_T5(float value);\r
+PXIALG_API int SpO2_Set_Spo2_Force_Output_Second(int value);\r
+\r
+PXIALG_API int Spo2_Set_SpO2_First_Smooth_Th(float value);\r
+PXIALG_API int Spo2_Set_SpO2_First_Smooth_Sec(int value);\r
+PXIALG_API int Spo2_Set_SpO2_Correlation_Smooth_Th(float value);\r
+\r
+//set HR\r
+PXIALG_API int SpO2_SetHrValue(int value);\r
+\r
+//get SPO2_Info\r
+PXIALG_API int SpO2_GetInfo(SpO2_info_t *info);\r
+\r
+PXIALG_API int SpO2_SetMems(SpO2_mems_t *mems, int samples);\r
+\r
+PXIALG_API int SpO2_Set_Update_Sec(int spo2_update_sec);\r
+\r
+PXIALG_API int SpO2_SetMemsRmsThr(float mems_rms_thr);\r
+PXIALG_API int SpO2_CalAvgSpO2(float mySpO2, float trust_flag, float mems_rms, float *result); //called every one second\r
+PXIALG_API int SpO2_SetSkipDataLen(int len);\r
+PXIALG_API int SpO2_SetChMapping(int8_t *alg_ch, int8_t ch_nr);\r
+\r
+PXIALG_API int Spo2_Set_Force_Output_Value(float value);\r
+PXIALG_API int Spo2_Set_Force_Output_Value2(float value);\r
+\r
+PXIALG_API int SpO2_Set_Signal_Periodicity_Th(float value);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/test_library_SPO2.c b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_spo2/V703/test_library_SPO2.c
new file mode 100644 (file)
index 0000000..2f76e52
--- /dev/null
@@ -0,0 +1,432 @@
+// algorithm\r
+#include "pxialg_spo2.h"\r
+// HR algorithm\r
+#include "pxialg.h"\r
+// testpattern\r
+#include "pah8009_testpattern_SPO2.h"\r
+// platform\r
+#include <stdlib.h>\r
+\r
+#include "pah800x_main.h"\r
+//#include "system_clock.h"\r
+//#include "i2c.h"\r
+//#include "gpio_ctrl.h"\r
+//#include "pah_comm.h"\r
+#include <math.h>  \r
+#include "nrf_delay.h"\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+#define SAMPLES_PER_CHANNEL 25\r
+#define TOTAL_CHANNEL 3\r
+\r
+//#define Open_Rest_Flow\r
+\r
+static SpO2_mems_t  mems_data_raw[150];        //add item\r
+\r
+typedef struct\r
+{\r
+    void *pBuffer;\r
+    void *hr_pBuffer;\r
+} pxialg_spo2_state;\r
+\r
+//#define parameter_printf(...) NRF_LOG_RAW_INFO(__VA_ARGS__)\r
+\r
+extern void spo2_log_printf(char s, float f);\r
+//static void spo2_log_printf(char s, float f)\r
+//{\r
+//    parameter_printf("%s= "LOG_FLOAT_MARKER"   \n",s, LOG_FLOAT(f));\r
+\r
+//}\r
+\r
+\r
+\r
+\r
+static void bubblesort(float *input,int count) \r
+{\r
+    int i,j;\r
+    float sort_temp;\r
+    for(i=0;i<count - 1;i++)\r
+    {\r
+        for(j=0;j<count-i - 1;j++) \r
+        {\r
+            if(input[j+1]<input[j])\r
+            {\r
+                sort_temp=input[j+1];\r
+                input[j+1]=input[j];\r
+                input[j]=sort_temp;\r
+            }\r
+        }\r
+    }\r
+}\r
+    \r
+    \r
+    \r
+    \r
+    \r
+\r
+    \r
+void test_library_SPO2(void)\r
+{\r
+    int i               = 0;\r
+    int j               = 0;\r
+    int32_t version     = 0;\r
+    uint8_t ReadyFlag   = 0;\r
+    int     buffer_size = 0;\r
+    void *pBuffer       = NULL;\r
+    \r
+    \r
+    \r
+    \r
+    \r
+    // add for new flow\r
+    float            spo2_array[31]={0.0f};   \r
+    int              count         =0;\r
+\r
+    //int     time_s,time_e,time_c;\r
+    int8_t alg_ch[2]    = {0, 1};\r
+    static pxialg_spo2_state    _spo2_state;\r
+    pah8series_data_t   pxialg_data;\r
+        \r
+    version     = SpO2_Version();\r
+    LOG_PRINT("SPO2_version =%d \n",version);\r
+    buffer_size = SpO2_OpenSize();\r
+    LOG_PRINT("SPO2_size = %d  \n", buffer_size);\r
+    pBuffer = malloc(buffer_size);\r
+\r
+    \r
+    nrf_delay_ms(50);\r
+    if (!pBuffer)\r
+    {\r
+        LOG_PRINT("Out of memory. \n");\r
+        return;\r
+    }\r
+    nrf_delay_ms(50);\r
+    if (SpO2_Open(pBuffer) != SPO2_MSG_SUCCESS)\r
+    {\r
+        LOG_PRINT("SpO2_Open() failed. \n");\r
+        free(pBuffer);\r
+        return;\r
+    }\r
+    \r
+       //log_printf("pBuffer =%x \n",pBuffer);\r
+    SpO2_SetChMapping(alg_ch, 2);\r
+    SpO2_SetInputRatioHighBound(94.0f);\r
+    SpO2_SetInputRatioLowBound(87.0f);\r
+    SpO2_SetInputModelScale(0.50f);\r
+    \r
+    SpO2_SetInputCoefHigh0(-36877.85546875f);\r
+    SpO2_SetInputCoefHigh1(1135.91394042969f);\r
+    SpO2_SetInputCoefHigh2(-11.6429319381714f);\r
+    SpO2_SetInputCoefHigh3(0.0398150011897087f);\r
+    \r
+    SpO2_SetInputCoefMid0(-1430.70520019531f);\r
+    SpO2_SetInputCoefMid1(50.1599006652832f);\r
+    SpO2_SetInputCoefMid2(-0.567422986030579f);\r
+    SpO2_SetInputCoefMid3(0.00219199992716312f);\r
+    \r
+    SpO2_SetInputCoefLow0(-8.19796657562256f);\r
+    SpO2_SetInputCoefLow1(1.74200701713562f);\r
+    SpO2_SetInputCoefLow2(-0.0173850003629923f);\r
+    SpO2_SetInputCoefLow3(0.000105999999505002f);\r
+    \r
+    SpO2_SetIIRFilterRatio(0.5f);\r
+    SpO2_SetInputCorrelationTh(0.850000078678131f);\r
+    SpO2_SetInputRatioLow(0.05f);        \r
+    \r
+    SpO2_SetInputFlagCheckHr(1);\r
+    SpO2_SetMotionDetectionLevel(2.0f);\r
+    SpO2_Set_Update_Sec(1);\r
+    \r
+    SpO2_Set_Init_Low_SpO2_Constrain(0.0);\r
+    SpO2_SetOutputHighBound(100.0f);\r
+    SpO2_SetOutputLowBound(60.0f);\r
+    SpO2_Set_Keep_Init_SpO2_Bound(95.0f);    \r
+    SpO2_Set_Keep_Init_SpO2_Count_Th(18.0f);\r
+    SpO2_Set_SpO2_Bias_Value(0.5f);\r
+    SpO2_Set_SpO2_Outlier_Smooth_Coef(5.5f);\r
+    SpO2_Set_SpO2_Decrease_Coef(0.5f);\r
+    SpO2_SetSkipDataLen(25);\r
+             \r
+    SpO2_Set_Flag_Hold_Breathe_Mode(0);\r
+    SpO2_Set_Input_Correlation_Th2(0.85000f);\r
+    SpO2_Set_Correlation_Th2_Count(30.0f);\r
+    SpO2_Set_Init_Low_SpO2_Th(94.5f);\r
+    SpO2_Set_Motion_Rms_Th(3000.0f);\r
+    SpO2_Set_Motion_Rms_Th2(1500.0f);\r
+    SpO2_Set_Motion_MEMS_Th(0.0f);     \r
+    SpO2_Set_T1(0.85f);\r
+    SpO2_Set_Spo2_Force_Output_Second(30.0f);\r
+    \r
+    Spo2_Set_Force_Output_Value(97.50f);  // Good Signal Force SpO2\r
+    Spo2_Set_Force_Output_Value2(95.00f); // Bad  Signal Force SpO2\r
+    \r
+    SpO2_Set_Init_Low_SpO2_Check_Sec(20);\r
+    Spo2_Set_SpO2_First_Smooth_Th(95.0f);\r
+    Spo2_Set_SpO2_First_Smooth_Sec(15);\r
+    Spo2_Set_SpO2_Correlation_Smooth_Th(0.85f);\r
+    SpO2_Set_Signal_Periodicity_Th(0.50f);\r
+             \r
+    \r
+   /// static  Hr\r
+    version = PxiAlg_Version();\r
+    LOG_PRINT("HR_Version = %d \r\n", version);        \r
+    \r
+    uint32_t Query_Mem_Size = PxiAlg_Query_Mem_Size();\r
+    LOG_PRINT("HR_Mem_Size = %d \r\n", Query_Mem_Size);\r
+    \r
+    _spo2_state.hr_pBuffer = malloc(Query_Mem_Size);\r
+    \r
+    PxiAlg_Open_Mem(_spo2_state.hr_pBuffer);\r
+    \r
+////                \r
+    PxiAlg_SetQualityThreshold(0.35f); \r
+    PxiAlg_SetHRSmoothWeight(0.9f); \r
+    PxiAlg_SetProcWindow(5.0f, 5.0f); \r
+    PxiAlg_SetTimeoutLength(30.0f);\r
+    PxiAlg_SetMemsScale(0);              //MEMS 2/4/8/16G : 0/1/2/3\r
+    PxiAlg_SetSkipSampleNum(10); \r
+    PxiAlg_SetMemsScaleBase(1, 0);    //MEMS 2/4/8/16G : 0/1/2/3\r
+    PxiAlg_SetForceOutputLink(15, 90, 60, 1, 0.9f); \r
+    PxiAlg_SetNormalOutput(200, 40, 1); \r
+    PxiAlg_SetForceRipple(3, 1); \r
+\r
+    PxiAlg_SetPackage(0, 1);\r
+         \r
+\r
+//-----------------------------------------------//\r
+\r
+       int32_t  alg_count=0;\r
+\r
+       LOG_PRINT("ARRAY_SIZE = %d\n",array_szie(PAH8009_rawdata_SPO2));\r
+//******************************************************************         \r
+    \r
+      \r
+    float   mySpO2          = 0      ;\r
+    float   MEMS_RMS        = 0.0f   ;\r
+    float   myHR            = 0.0f   ;\r
+    int     ret_value  = 0   ;\r
+    float   hr_grader       = 0.0f   ;\r
+    uint8_t ready_flag = 0   ;\r
+    float   correlation     = 0.0f   ;\r
+    float   trust_flag      = 0.0f   ;\r
+    uint8_t no_value_reason = 0      ;\r
+    int     time_accu       = 0      ;\r
+    float   SignalPeriodicity=0.0f   ;\r
+//*******************************************************************         \r
+         \r
+    nrf_delay_ms(10);\r
+         \r
+\r
+    for( i = 0 ; i <array_szie(PAH8009_rawdata_SPO2) ; i ++)\r
+    {\r
+    \r
+        uint32_t  touch_flag         = PAH8009_rawdata_SPO2[i][0];               \r
+        uint32_t  time               = duration_SPO2[i];              \r
+        int       ppg_count_per_ch   = PAH8009_rawdata_SPO2[i][1];    \r
+        int       frame_number       = frame_SPO2[i]; \r
+        int       mems_number        =    PAH8009_mems_SPO2[i][0];         \r
+        int32_t   RAW_DATA [75]       = {0}; \r
+              \r
+        \r
+        //log_printf("RAW_DATA =\n");\r
+        for (j=0;j<ppg_count_per_ch; j++)\r
+        {\r
+            RAW_DATA[j] = PAH8009_rawdata_SPO2[i][j+2] ;\r
+            //log_printf("%d , ", RAW_DATA[j]);\r
+            \r
+        }\r
+         \r
+        \r
+         for( j = 0 ; j <(PAH8009_mems_SPO2[i][0]) ; j ++)\r
+        {            \r
+            mems_data_raw[j].data[0]=PAH8009_mems_SPO2[i][3*j+1];\r
+            mems_data_raw[j].data[1]=PAH8009_mems_SPO2[i][3*j+2];\r
+            mems_data_raw[j].data[2]=PAH8009_mems_SPO2[i][3*j+3];   \r
+        \r
+        }\r
+         \r
+                \r
+\r
+        nrf_delay_ms(10);\r
+        pxialg_data.touch_flag         = touch_flag;\r
+        pxialg_data.time               = time;\r
+        pxialg_data.ppg_data           = (int32_t*)RAW_DATA;\r
+        pxialg_data.nf_ppg_channel     = NF_PPG_CHANNEL;\r
+        pxialg_data.nf_ppg_per_channel = ppg_count_per_ch/NF_PPG_CHANNEL;\r
+        pxialg_data.frame_count        = frame_number;\r
+        pxialg_data.nf_mems            = mems_number;\r
+        pxialg_data.mems_data          = (int16_t*)mems_data_raw;\r
+                 \r
+                 \r
+        \r
+        ret_value = PxiAlg_Entrance(&pxialg_data); \r
+        \r
+        \r
+        alg_count  = alg_count + PAH8009_rawdata_SPO2[i][1]/NF_PPG_CHANNEL ;\r
+        nrf_delay_ms(10);\r
+        \r
+        //if( ret_value == FLAG_DATA_READY) \r
+        if(PxiAlg_GetHrUpdateFlag())\r
+        {\r
+            PxiAlg_HrGet(&myHR);\r
+            ready_flag = PxiAlg_GetReadyFlag();\r
+            PxiAlg_GetSigGrade(&hr_grader);\r
+        \r
+        }\r
+        //ready_flag = PxiAlg_GetReadyFlag();\r
+        //PxiAlg_GetSigGrade(&hr_grader);\r
+                 \r
+                 \r
+        nrf_delay_ms(50);\r
+        SpO2_SetHrValue(myHR);\r
+        SpO2_SetMems(mems_data_raw, pxialg_data.nf_mems);\r
+//        uint32_t time_s = get_tick_count();\r
+        ret_value = SpO2_Process(1, NF_PPG_CHANNEL, pxialg_data.ppg_data, pxialg_data.nf_ppg_per_channel,pxialg_data.time );\r
+        \r
+      //  uint32_t time_e = pah_get_tick_count();\r
+//        uint32_t time_diff=time_e-time_s;\r
+//        log_printf("process-time = %d \n",time_diff);\r
+        \r
+        \r
+        SpO2_GetSpO2(&mySpO2);\r
+        SpO2_GetReadyFlag(&ReadyFlag);\r
+        SpO2_info_t    _spo2_detect_item;\r
+        SpO2_GetInfo(&_spo2_detect_item);\r
+        correlation=_spo2_detect_item.Noise;\r
+        trust_flag =_spo2_detect_item.Output[3];\r
+        no_value_reason=_spo2_detect_item.Output[4];\r
+        SpO2_GetPeriodicity(&SignalPeriodicity);\r
+        MEMS_RMS  =_spo2_detect_item.RMS;\r
+         \r
+                                  \r
+                 \r
+        #if defined(Optimize_SPO2_flow)     \r
+            time_accu=time_accu+time;\r
+        #endif\r
+        nrf_delay_ms(10);\r
+        if( ret_value == 0  && (alg_count>=25) )\r
+        {        \r
+            alg_count = alg_count -25;\r
+            if (ReadyFlag > 0)\r
+            {\r
+                LOG_PRINT("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",grade = "LOG_FLOAT_MARKER" ",LOG_FLOAT(hr_grader));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(mySpO2));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(correlation));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(trust_flag));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(", SignalPeriodicity = "LOG_FLOAT_MARKER" ",LOG_FLOAT(SignalPeriodicity));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",MEMS_RMS    = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(MEMS_RMS));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",reason = %d \n",no_value_reason);\r
+            }\r
+                else\r
+            {\r
+                LOG_PRINT("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",grade = "LOG_FLOAT_MARKER" ",LOG_FLOAT(hr_grader));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(mySpO2));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(correlation));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(trust_flag));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(", SignalPeriodicity = "LOG_FLOAT_MARKER" ",LOG_FLOAT(SignalPeriodicity));\r
+                //nrf_delay_ms(10);\r
+                LOG_PRINT(",MEMS_RMS    = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(MEMS_RMS));\r
+                 //nrf_delay_ms(10);\r
+                LOG_PRINT(",reason = %d \n",no_value_reason);\r
+\r
+            }\r
+                     \r
+//                float  new_spo2=mySpO2;\r
+            \r
+                \r
+       #if defined(Optimize_SPO2_flow)     \r
+            //time_accu=time_accu+time;\r
+            LOG_PRINT("time_accu = %d\n",time_accu);\r
+            if(time_accu>=31000)\r
+            {\r
+                spo2_array[count]=mySpO2;\r
+                count=count+1;\r
+                \r
+                LOG_PRINT("Over_30_sec_Stop_measurement\n");\r
+                LOG_PRINT("This_meausrement_suggest_spo2_value is");\r
+                \r
+                bubblesort(spo2_array,count);\r
+                \r
+                if(count % 2 == 0)\r
+                {\r
+                    //LOG_PRINT(" "LOG_FLOAT_MARKER" \n", LOG_FLOAT(spo2_array[count/2]));\r
+                    LOG_PRINT(" "LOG_FLOAT_MARKER" \n",LOG_FLOAT((spo2_array[(int)(count/2)] + spo2_array[(int)(count/2) - 1]) / 2.0f));  \r
+                }\r
+                else\r
+                {\r
+                    LOG_PRINT(" "LOG_FLOAT_MARKER"\n", LOG_FLOAT(spo2_array[(int)(count/2)]*1.0f));\r
+                }\r
+                count=0;\r
+                nrf_delay_ms(50);\r
+              //add sensor stop here              \r
+                SpO2_Close();\r
+                PxiAlg_Close();\r
+                free(pBuffer);\r
+                free(_spo2_state.hr_pBuffer);\r
+                //NRF_LOG_FLUSH();\r
+                return;                \r
+\r
+            }\r
+            else\r
+            {\r
+                if(mySpO2>0)\r
+                {\r
+                    spo2_array[count]=mySpO2;\r
+                    count=count+1;                    \r
+                }\r
+                                    \r
+            }\r
+            #endif  \r
+        }\r
+        else\r
+        {\r
+        \r
+            switch (ret_value)\r
+            {\r
+                case SPO2_MSG_ALG_NOT_OPEN:\r
+                     LOG_PRINT("Algorithm is not initialized. \n");\r
+                break;\r
+                                \r
+                case SPO2_MSG_ALG_REOPEN:\r
+                     LOG_PRINT("Algorithm is re initialized. \n");\r
+                break;\r
+                                \r
+                case SPO2_MSG_ALG_NOT_SUPPORT:\r
+                     LOG_PRINT("Algorithm is not support. \n");\r
+                break;\r
+                case SPO2_MSG_SUCCESS:\r
+                     //LOG_PRINT("Algorithm is SUCCESS. \n");\r
+                break;                \r
+                default:\r
+                     LOG_PRINT("Algorithm unhandle error = %d \n", ret_value);\r
+                break;\r
+            }\r
+        }\r
+\r
+                \r
+        \r
+        nrf_delay_ms(40); \r
+    }\r
+    \r
+    LOG_PRINT("Out of memory. \n");\r
+    nrf_delay_ms(10);\r
+    SpO2_Close();\r
+    PxiAlg_Close();\r
+    free(pBuffer);\r
+    free(_spo2_state.hr_pBuffer);\r
+    return;\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_stress/V6033/pxialg_hrv.h b/code/sdk/zhihui/drivers/ppg/pah8009/algorithm/pah_stress/V6033/pxialg_hrv.h
new file mode 100644 (file)
index 0000000..0e2a007
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef _PXIALG_HRV_\r
+#define _PXIALG_HRV_\r
+#include "stdint.h"\r
+\r
+typedef struct\r
+{\r
+    void            *pBuffer;\r
+    float           collect_duration;\r
+    uint8_t         has_got_sdnn;\r
+} hrv_state_s;\r
+\r
+\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+       PXIALG_API int HRVReset(void);\r
+       PXIALG_API int HRVGetMemorySize(int enable_lhr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int HRVOpen(void *p_buffer);\r
+       PXIALG_API int HRVProcess(int data_ready, float data);\r
+       PXIALG_API int HRVProcessD(int data_ready, uint32_t data);\r
+       PXIALG_API int HRVClose(void);\r
+\r
+       PXIALG_API int HRVGetVersion(void);\r
+       PXIALG_API float HRVGetSDNN(void);\r
+       PXIALG_API int HRVGetSDNNLevel(int m_iAge, float dSDNN);\r
+       PXIALG_API float HRVGetLHRatio(float *nlf, float *nhf);\r
+       PXIALG_API float HRVGetRMSSD(void);\r
+       PXIALG_API int HRVGetSleepQuality(int age);\r
+       PXIALG_API int HRVGetOnlineRRIReportFlag(void);\r
+       PXIALG_API float HRVGetOnlineRRI(void);\r
+       PXIALG_API int HRVGetRawRRINum(void);\r
+       PXIALG_API float * HRVGetRawRRIBuf(void);\r
+       PXIALG_API float HRVGetNoiseRate(void);\r
+       PXIALG_API float HRVGetRRIStability(void);\r
+       PXIALG_API float HRVGetRRIQuality(void);\r
+       PXIALG_API int HRVGetReadyFlag(void);\r
+       PXIALG_API int HRVGetMotionFlag(void);\r
+       PXIALG_API int HRVGetAnomalyFlag(void);\r
+       PXIALG_API int HRVGetHRAvg(void);\r
+\r
+       PXIALG_API void HRVSetSkipCounterTh(int SkipCounterTh);\r
+       PXIALG_API void HRVSetFreqOffset(float FreqOffset);\r
+       PXIALG_API void HRVSetDiffTime(float DiffTime, int SampleNum);\r
+       PXIALG_API void HRVSetPeakProcessReadyCounterTh(int PeakProcessReady3Counter_Th0,\r
+                                                                                       int PeakProcessReady3Counter_Th1,\r
+                                                                                       int PeakProcessReady3Counter_Th2,\r
+                                                                                       int PeakProcessReady3Counter_Th3,\r
+                                                                                       int m_PeakProcessReady3Counter_HeartRate_Th1,\r
+                                                                                       int m_PeakProcessReady3Counter_HeartRate_Th2,\r
+                                                                                       int m_PeakProcessReady3Counter_HeartRate_Th3);\r
+\r
+       PXIALG_API float HRVGetStress(int grade);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _PXIALG_HRV_ */\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/factory/pah8009_factory_reg.h b/code/sdk/zhihui/drivers/ppg/pah8009/factory/pah8009_factory_reg.h
new file mode 100644 (file)
index 0000000..af20cbf
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef __pah8009_factory_reg_h__\r
+#define __pah8009_factory_reg_h__\r
+\r
+// pah\r
+#include "pah800x_factory_test.h"\r
+\r
+\r
+static const uint8_t PAH_800x_REG_DEVICE_INIT_FACTORY[][2] = {\r
+//  { 0xEE,0x07 }, //SW RESET\r
+    { 0xE8,0x00 },//Close suspend\r
+    { 0xD1,0xD0 },//{R_GPIO_0_IEB, R_GPIO_1_IEB, R_GPIO_0_OEB, R_GPIO_1_OEB, R_GPIO_0_PULLL_EnH, R_GPIO_1_PULLL_EnH, R_GPIO_0_PULLH_EnH, R_GPIO_1_PULLH_EnH};\r
+    { 0xD2,0x00 },//R_GPIO_0_Open_Drain_EnH(0xD2[5]), 1(0x20):GPIO default open-drain mode, 0(0x00):GPIO debug mode\r
+    { 0xD3,0x20 },//GPIO debug select\r
+//     { 0xD6,0x30 },//{Dummy, R_I2C_SLEW, R_I2C_DRV[1:0], Dummy[3:0]}\r
+//     { 0xD5,0x44 },//IO-level(I2C), 44:3.3V, 00:1.8V\r
+//     { 0xB2,0x25 },\r
+       { 0x55,0x24 },//Soft Reset:04 Hard Reset:24\r
+       { 0x52,0x12 },//VDDAY=1.63V\r
+//     { 0xA6,0xF7 },//Cmd_vdday_pwrsv_sel_EnH=0\r
+       { 0xAE,0x3F },//R_LPO_Cali_mode=1\r
+};\r
+\r
+static const uint8_t PAH_800x_REG_BRIGHTNESS_TEST_FACTORY[][2] = {\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x08,0x00 },//A period\r
+    { 0x09,0x08 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x08 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x08 },//C period\r
+    { 0x0E,0x01 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x01 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x77 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x52 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x44 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x44 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x00 },//RDB_expo_A[7:0]\r
+    { 0x18,0x01 },//RDB_expo_A[15:8]\r
+    { 0x19,0x00 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x01 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x00 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x01 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x2F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x4F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x2A },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0xEB,0x80 },//update_flag\r
+//  { 0x20,0xF7 },//Clear INT\r
+};\r
+\r
+static const uint8_t PAH_800x_REG_LEAK_LIGHT_TEST_FACTORY[][2] = {\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x08,0x00 },//A period\r
+    { 0x09,0x08 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x08 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x08 },//C period\r
+    { 0x0E,0x01 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x01 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x77 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x12 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x0A },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x8A },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x00 },//RDB_expo_A[7:0]\r
+    { 0x18,0x02 },//RDB_expo_A[15:8]\r
+    { 0x19,0x00 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x02 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x2F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x4F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x2A },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0xEB,0x80 },//update_flag\r
+//  { 0x20,0xF7 },//Clear INT\r
+};\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+void factory_test_mode(factory_test_type test_type, bool expo_adjust_en, uint16_t expo_a, uint16_t expo_b, uint16_t expo_c);\r
+\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/factory/pah800x_factory_test.c b/code/sdk/zhihui/drivers/ppg/pah8009/factory/pah800x_factory_test.c
new file mode 100644 (file)
index 0000000..d4cd39c
--- /dev/null
@@ -0,0 +1,556 @@
+// pah\r
+#include "pah800x_factory_test.h"\r
+#include "pah8009_factory_reg.h"\r
+\r
+static uint16_t factory_test_ch[3] = {0};\r
+\r
+//============================================================================\r
+// Static Global Variable\r
+//============================================================================\r
+static pah_800x_test_t _factory_state;\r
+static pah_verify_config_t     g_config_table[test_type_num] =\r
+{\r
+       //factory_tesst_num=0\r
+       {\r
+               .ch_spec[0] =\r
+               {\r
+                       .verify_enabled = BRIGHTNESS_GLODEN_CHA_ENABLE,\r
+                       .min_enabled = BRIGHTNESS_GLODEN_CHA_MIN_ENABLE, .max_enabled = BRIGHTNESS_GLODEN_CHA_MAX_ENABLE,\r
+                       .min = BRIGHTNESS_GLODEN_CHA_MIN, .max = BRIGHTNESS_GLODEN_CHA_MAX\r
+               },\r
+               .ch_spec[1] =\r
+               {\r
+                       .verify_enabled = BRIGHTNESS_GLODEN_CHB_ENABLE,\r
+                       .min_enabled = BRIGHTNESS_GLODEN_CHB_MIN_ENABLE, .max_enabled = BRIGHTNESS_GLODEN_CHB_MAX_ENABLE,\r
+                       .min = BRIGHTNESS_GLODEN_CHB_MIN, .max = BRIGHTNESS_GLODEN_CHB_MAX\r
+               },\r
+               .ch_spec[2] =\r
+               {\r
+                       .verify_enabled = BRIGHTNESS_GLODEN_CHC_ENABLE,\r
+                       .min_enabled = BRIGHTNESS_GLODEN_CHC_MIN_ENABLE, .max_enabled = BRIGHTNESS_GLODEN_CHC_MAX_ENABLE,\r
+                       .min = BRIGHTNESS_GLODEN_CHC_MIN, .max = BRIGHTNESS_GLODEN_CHC_MAX\r
+               },\r
+               .test_regs =\r
+               {\r
+                       .init_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_DEVICE_INIT_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_DEVICE_INIT_FACTORY)\r
+                       },\r
+                       .test_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_BRIGHTNESS_TEST_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_BRIGHTNESS_TEST_FACTORY)\r
+                       }\r
+               }\r
+       },\r
+\r
+       //factory_tesst_num=1\r
+       {\r
+               .ch_spec[0] =\r
+               {\r
+                       .verify_enabled = BRIGHTNESS_TARGET_CHA_ENABLE,\r
+                       .min_enabled = BRIGHTNESS_TARGET_CHA_MIN_ENABLE, .max_enabled = BRIGHTNESS_TARGET_CHA_MAX_ENABLE,\r
+                       .min = BRIGHTNESS_TARGET_CHA_MIN, .max = BRIGHTNESS_TARGET_CHA_MAX\r
+               },\r
+               .ch_spec[1] =\r
+               {\r
+                       .verify_enabled = BRIGHTNESS_TARGET_CHB_ENABLE,\r
+                       .min_enabled = BRIGHTNESS_TARGET_CHB_MIN_ENABLE, .max_enabled = BRIGHTNESS_TARGET_CHB_MAX_ENABLE,\r
+                       .min = BRIGHTNESS_TARGET_CHB_MIN, .max = BRIGHTNESS_TARGET_CHB_MAX\r
+               },\r
+               .ch_spec[2] =\r
+               {\r
+                       .verify_enabled = BRIGHTNESS_TARGET_CHC_ENABLE,\r
+                       .min_enabled = BRIGHTNESS_TARGET_CHC_MIN_ENABLE, .max_enabled = BRIGHTNESS_TARGET_CHC_MAX_ENABLE,\r
+                       .min = BRIGHTNESS_TARGET_CHC_MIN, .max = BRIGHTNESS_TARGET_CHC_MAX\r
+               },\r
+               .test_regs =\r
+               {\r
+                       .init_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_DEVICE_INIT_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_DEVICE_INIT_FACTORY)\r
+                       },\r
+                       .test_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_BRIGHTNESS_TEST_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_BRIGHTNESS_TEST_FACTORY)\r
+                       }\r
+               }\r
+       },\r
+\r
+       //factory_tesst_num=2\r
+       {\r
+               .ch_spec[0] =\r
+               {\r
+                       .verify_enabled = LEAK_LIGHT_TARGET_CHA_ENABLE,\r
+                       .min_enabled = LEAK_LIGHT_TARGET_CHA_MIN_ENABLE, .max_enabled = LEAK_LIGHT_TARGET_CHA_MAX_ENABLE,\r
+                       .min = LEAK_LIGHT_TARGET_CHA_MIN, .max = LEAK_LIGHT_TARGET_CHA_MAX\r
+               },\r
+               .ch_spec[1] =\r
+               {\r
+                       .verify_enabled = LEAK_LIGHT_TARGET_CHB_ENABLE,\r
+                       .min_enabled = LEAK_LIGHT_TARGET_CHB_MIN_ENABLE, .max_enabled = LEAK_LIGHT_TARGET_CHB_MAX_ENABLE,\r
+                       .min = LEAK_LIGHT_TARGET_CHB_MIN, .max = LEAK_LIGHT_TARGET_CHB_MAX\r
+               },\r
+               .ch_spec[2] =\r
+               {\r
+                       .verify_enabled = LEAK_LIGHT_TARGET_CHC_ENABLE,\r
+                       .min_enabled = LEAK_LIGHT_TARGET_CHC_MIN_ENABLE, .max_enabled = LEAK_LIGHT_TARGET_CHC_MAX_ENABLE,\r
+                       .min = LEAK_LIGHT_TARGET_CHC_MIN, .max = LEAK_LIGHT_TARGET_CHC_MAX\r
+               },\r
+               .test_regs =\r
+               {\r
+                       .init_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_DEVICE_INIT_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_DEVICE_INIT_FACTORY)\r
+                       },\r
+                       .test_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_LEAK_LIGHT_TEST_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_LEAK_LIGHT_TEST_FACTORY)\r
+                       }\r
+               }\r
+       },\r
+\r
+       //factory_tesst_num=3\r
+       {\r
+               .test_regs =\r
+               {\r
+                       .init_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_DEVICE_INIT_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_DEVICE_INIT_FACTORY)\r
+                       },\r
+                       .test_reg_arr =\r
+                       {\r
+                               .reg_arr = (pah_reg*)PAH_800x_REG_LEAK_LIGHT_TEST_FACTORY,\r
+                               .reg_arr_len = PAH_ARRAY_SIZE(PAH_800x_REG_LEAK_LIGHT_TEST_FACTORY)\r
+                       }\r
+               }\r
+       }\r
+\r
+};\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static void pah_sensor_factory_mode_init(factory_test_type test_type, bool expo_adjust_en, uint16_t expo_a, uint16_t expo_b, uint16_t expo_c);\r
+static void pah_sensor_factory_mode_start(void);\r
+static void pah_sensor_factory_mode_stop(void);\r
+static void pah_sensor_factory_mode_task(void);\r
+static void pah_sensor_factory_mode_verify_result(void);\r
+\r
+static pah_ret _pah_800x_hal_comm_write(uint8_t addr, const uint8_t *data, size_t write_size);\r
+static pah_ret _pah_800x_hal_comm_read(uint8_t addr, uint8_t *data, size_t read_size);\r
+static pah_ret _comm_write(uint8_t addr, uint8_t data);\r
+\r
+static pah_ret _pah_800x_hal_write_reg_arr(const pah_reg_arr *reg_arr);\r
+static pah_ret _pah_800x_hal_write_reg_array(const uint8_t reg_array[][2], size_t length);\r
+static pah_ret _pah_800x_hal_write_suspend_state(bool suspend);\r
+static pah_ret _pah_800x_hal_write_interrupt_clear(void);\r
+static pah_ret _pah_800x_hal_write_ch_exposure(uint16_t expo_a, uint16_t expo_b, uint16_t expo_c, uint8_t ch_num);\r
+static pah_ret _pah_800x_hal_tg_toggle(bool enable);\r
+static pah_ret _pah_800x_hal_update_flag(void);\r
+\r
+static pah_ret _pah_800x_hal_read_product_id(uint16_t *product_id);\r
+static pah_ret _pah_800x_hal_read_ppg_interrupt(uint8_t *ppg_interrupt);\r
+static pah_ret _pah_800x_hal_read_ppg_overflow(uint8_t *ppg_overflow, uint8_t *overflow_num);\r
+static pah_ret _pah_800x_hal_read_ppg_adc(uint16_t *ppg_adc, uint8_t ch_num);\r
+static pah_ret _pah_800x_hal_check_enable_channel(pah_800x_test_t *factory_state, const pah_reg_arr *reg_arr);\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+void factory_test_mode(factory_test_type test_type, bool expo_adjust_en, uint16_t expo_a, uint16_t expo_b, uint16_t expo_c)\r
+{\r
+       LOG_PRINT("test_type=%d\n{\n factory_test_brightness_golden_sample=0\n "        \\r
+                         "factory_test_brightness_target_sample=1\n factory_test_leak_light_target_sample=2\n "        \\r
+                         "factory_test_power_noise=3\n factory_test_INT_high=4\n factory_test_INT_low=5\n}\n", test_type);\r
+\r
+       pah_sensor_factory_mode_init(test_type, expo_adjust_en, expo_a, expo_b, expo_c);\r
+\r
+       pah_sensor_factory_mode_start();\r
+\r
+    pah_delay_ms(25);\r
+\r
+    if (test_type < factory_test_power_noise)\r
+    {\r
+       pah_sensor_factory_mode_task();\r
+       pah_sensor_factory_mode_verify_result();\r
+        pah_sensor_factory_mode_stop();\r
+    }\r
+    else\r
+    {\r
+       return;\r
+    }\r
+\r
+    pah_delay_ms(500);\r
+\r
+    return;\r
+\r
+}\r
+\r
+\r
+//============================================================================\r
+// Private function \r
+//============================================================================\r
+static void pah_sensor_factory_mode_init(factory_test_type test_type, bool expo_adjust_en, uint16_t expo_a, uint16_t expo_b, uint16_t expo_c)\r
+{\r
+       DEBUG_PRINT("%s(%d)\n", __func__, test_type);\r
+\r
+    memset(&_factory_state, 0, sizeof(_factory_state));\r
+\r
+    uint16_t product_id = 0;\r
+    _pah_800x_hal_read_product_id(&product_id);\r
+    DEBUG_PRINT("product_id = 0x%04X\n", product_id);\r
+    if (product_id != PAH_800x_PRODUCT_ID)\r
+    {\r
+       DEBUG_PRINT("Failed to verify product_id\n");\r
+    }\r
+/**/\r
+       for (int ch_index=0; ch_index<3; ch_index++)\r
+       {\r
+               _factory_state.verify_config.ch_spec[ch_index] = g_config_table[test_type].ch_spec[ch_index];\r
+       }\r
+\r
+       _factory_state.verify_config.test_regs = g_config_table[test_type].test_regs;\r
+    _pah_800x_hal_write_reg_arr(&_factory_state.verify_config.test_regs.init_reg_arr);\r
+    _pah_800x_hal_write_reg_arr(&_factory_state.verify_config.test_regs.test_reg_arr);\r
+       _pah_800x_hal_check_enable_channel(&_factory_state, &_factory_state.verify_config.test_regs.test_reg_arr);\r
+/**/\r
+       if (expo_adjust_en) \r
+       {\r
+        for(uint8_t ch_num=0; ch_num<PAH_800x_MAX_CH_NUM; ch_num++)\r
+               {\r
+               _pah_800x_hal_write_ch_exposure(expo_a, expo_b, expo_c, ch_num);\r
+               }\r
+        _pah_800x_hal_update_flag();\r
+       }\r
+\r
+       _pah_800x_hal_write_interrupt_clear();\r
+\r
+//     PAH_REG_ARR_SETUP(_factory_state.verify_config.test_regs.init_reg_arr, PAH_800x_REG_DEVICE_INIT_FACTORY);\r
+//     _pah_800x_hal_write_reg_arr(&_factory_state.verify_config.test_regs.init_reg_arr);\r
+}\r
+\r
+static void pah_sensor_factory_mode_start(void)\r
+{\r
+       DEBUG_PRINT("%s\n", __func__);\r
+\r
+    _pah_800x_hal_write_suspend_state(false);\r
+    _pah_800x_hal_tg_toggle(true);\r
+\r
+}\r
+\r
+static void pah_sensor_factory_mode_stop(void)\r
+{\r
+       DEBUG_PRINT("%s\n", __func__);\r
+\r
+    _pah_800x_hal_tg_toggle(false);\r
+    _pah_800x_hal_write_suspend_state(true);\r
+\r
+}\r
+\r
+static void pah_sensor_factory_mode_task(void)\r
+{\r
+       DEBUG_PRINT("%s\n", __func__);\r
+\r
+    uint8_t ppg_interrupt = 0;\r
+    bool has_ppg_interrupt = false;\r
+    uint8_t ppg_overflow = 0;\r
+    uint8_t overflow_num = 0;\r
+\r
+    _pah_800x_hal_read_ppg_interrupt(&ppg_interrupt);\r
+    _pah_800x_hal_read_ppg_overflow(&ppg_overflow, &overflow_num);\r
+\r
+    has_ppg_interrupt = (ppg_interrupt > 0);\r
+    if (has_ppg_interrupt > 0)\r
+    {\r
+        for (uint8_t ch_num=0; ch_num < PAH_800x_MAX_CH_NUM; ch_num++)\r
+        {\r
+            if (_factory_state.test_ch_enabled[ch_num])\r
+            {\r
+               _pah_800x_hal_read_ppg_adc(&_factory_state.test_result.adc[ch_num], ch_num);\r
+            }\r
+        }\r
+    }\r
+\r
+    //clear_interrupt(state, has_ppg_interrupt, state->ppg_result.has_overflow);\r
+\r
+}\r
+\r
+static void pah_sensor_factory_mode_verify_result(void)\r
+{\r
+       DEBUG_PRINT("%s\n", __func__);\r
+       LOG_PRINT("=============== Verify_Result ===============\n"     \\r
+                         "{\n result=1 : pass\n result=0 : fail\n}\n");\r
+\r
+       for (int i=0; i<PAH_800x_MAX_CH_NUM; ++i)\r
+       {\r
+               if (_factory_state.verify_config.ch_spec[i].verify_enabled\r
+                       && _factory_state.verify_config.ch_spec[i].min_enabled\r
+                       && _factory_state.verify_config.ch_spec[i].max_enabled)\r
+               {\r
+                       if (_factory_state.test_result.adc[i] < _factory_state.verify_config.ch_spec[i].min\r
+                               || _factory_state.test_result.adc[i] > _factory_state.verify_config.ch_spec[i].max)\r
+                       {\r
+                               _factory_state.verify_result.ch_result[i].is_passed = false;\r
+                       }\r
+                       else\r
+                       {\r
+                               _factory_state.verify_result.ch_result[i].is_passed = true;\r
+                       }\r
+                       printf("ch[%d] : (min, value, max)=(%d, %d, %d), result=%d \n",\\r
+                                               i, _factory_state.verify_config.ch_spec[i].min, \\r
+                                               _factory_state.test_result.adc[i], \\r
+                                               _factory_state.verify_config.ch_spec[i].max, \\r
+                                               _factory_state.verify_result.ch_result[i].is_passed);\r
+               }\r
+               else if (_factory_state.verify_config.ch_spec[i].verify_enabled\r
+                                && _factory_state.verify_config.ch_spec[i].min_enabled)\r
+               {\r
+                       if (_factory_state.test_result.adc[i] < _factory_state.verify_config.ch_spec[i].min)\r
+                       {\r
+                               _factory_state.verify_result.ch_result[i].is_passed = false;\r
+                       }\r
+                       else\r
+                       {\r
+                               _factory_state.verify_result.ch_result[i].is_passed = true;\r
+                       }\r
+                       printf("ch[%d] : (min, value)=(%d, %d), result=%d \n",\\r
+                                               i, _factory_state.verify_config.ch_spec[i].min, \\r
+                                               _factory_state.test_result.adc[i], \\r
+                                               _factory_state.verify_result.ch_result[i].is_passed);\r
+               }\r
+               else if (_factory_state.verify_config.ch_spec[i].verify_enabled\r
+                               && _factory_state.verify_config.ch_spec[i].max_enabled)\r
+               {\r
+                       if (_factory_state.test_result.adc[i] > _factory_state.verify_config.ch_spec[i].max)\r
+                       {\r
+                               _factory_state.verify_result.ch_result[i].is_passed = false;\r
+                       }\r
+                       else\r
+                       {\r
+                               _factory_state.verify_result.ch_result[i].is_passed = true;\r
+                       }\r
+\r
+                       factory_test_ch[i] = _factory_state.test_result.adc[i];\r
+\r
+                       printf("ch[%d] : (value, max)=(%d, %d), result=%d \n",\\r
+                                               i, _factory_state.test_result.adc[i], \\r
+                                               _factory_state.verify_config.ch_spec[i].max, \\r
+                                               _factory_state.verify_result.ch_result[i].is_passed);\r
+               }\r
+       }\r
+}\r
+\r
+\r
+//============================================================================\r
+// Private function (HAL)\r
+//============================================================================\r
+static pah_ret _pah_800x_hal_comm_write(uint8_t addr, const uint8_t *data, size_t write_size)\r
+{\r
+    //return plat->comm.write(&plat->comm, addr, data, write_size);\r
+    //return plat->comm.write(addr, data, write_size);\r
+    return pah_comm_i2c_write(addr, data, write_size);\r
+}\r
+\r
+static pah_ret _pah_800x_hal_comm_read(uint8_t addr, uint8_t *data, size_t read_size)\r
+{\r
+\r
+    //return plat->comm.read(&plat->comm, addr, data, read_size);\r
+    return pah_comm_i2c_read(addr, data, read_size);\r
+}\r
+\r
+static pah_ret _comm_write(uint8_t addr, uint8_t data)\r
+{\r
+    //return pah_800x_hal_comm_write( addr, &data, 1);\r
+    return _pah_800x_hal_comm_write(addr, &data, 1);\r
+}\r
+#define _comm_read(addr, data)                     _pah_800x_hal_comm_read(addr, data, 1)\r
+#define _comm_burst_read(addr, data, read_size)    _pah_800x_hal_comm_read(addr, data, read_size)\r
+\r
+\r
+static pah_ret _pah_800x_hal_write_reg_arr(const pah_reg_arr *reg_arr)\r
+{\r
+    return _pah_800x_hal_write_reg_array(reg_arr->reg_arr, reg_arr->reg_arr_len);\r
+}\r
+\r
+static pah_ret _pah_800x_hal_write_reg_array(const uint8_t reg_array[][2], size_t length)\r
+{\r
+    size_t i = 0;\r
+    uint8_t reg_value = 0;\r
+    for (i = 0; i < length; ++i)\r
+    {\r
+        //for trim bit\r
+        if(reg_array[i][0] == 0x14)\r
+        {\r
+            _comm_read(0x14, &reg_value);\r
+            reg_value = (reg_value & 0x1F) | (reg_array[i][1] & 0xE0);\r
+            _comm_write(reg_array[i][0], reg_value);\r
+        }\r
+        else\r
+               _comm_write(reg_array[i][0], reg_array[i][1]);\r
+    }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_write_suspend_state(bool suspend)\r
+{\r
+    uint8_t data = 0;\r
+    DEBUG_PRINT("%s(%d)\n", __func__, suspend);\r
+    if (suspend)\r
+    {\r
+        _comm_read(PAH_800x_ADDR_E8, &data);\r
+        PAH_SET_BIT(data, PAH_800x_ADDR_E8_CMD_SUSPEND_MODE_BIT);\r
+        _comm_write(PAH_800x_ADDR_E8, data);\r
+    }\r
+    else\r
+    {\r
+        _comm_read(PAH_800x_ADDR_E8, &data);\r
+        PAH_CLEAR_BIT(data, PAH_800x_ADDR_E8_CMD_SUSPEND_MODE_BIT);\r
+        _comm_write(PAH_800x_ADDR_E8, data);\r
+\r
+    }\r
+    DEBUG_PRINT("%s(%d) end\n", __func__, suspend);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_write_interrupt_clear(void)\r
+{\r
+    uint8_t data = 0;\r
+    // DR interrupt\r
+    _comm_read(PAH_800x_ADDR_20, &data);\r
+    //PAH_CLEAR_BIT(data, PAH_800x_ADDR_20_BIT_DR_FLAG);\r
+    _comm_write(PAH_800x_ADDR_20, (data|0x04));        //SD-revise-20191205\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_write_ch_exposure(uint16_t expo_a, uint16_t expo_b, uint16_t expo_c, uint8_t ch_num)\r
+{\r
+    //uint8_t data = 0;\r
+    DEBUG_PRINT("%s(%d, %d, %d, %d)\n", __func__, expo_a, expo_b, expo_c, ch_num);\r
+\r
+    uint8_t a_exposure_low = PAH_UINT16_LOW(expo_a);\r
+    uint8_t a_exposure_high = PAH_UINT16_HIGH(expo_a);\r
+    uint8_t b_exposure_low = PAH_UINT16_LOW(expo_b);\r
+    uint8_t b_exposure_high = PAH_UINT16_HIGH(expo_b);\r
+    uint8_t c_exposure_low = PAH_UINT16_LOW(expo_c);\r
+    uint8_t c_exposure_high = PAH_UINT16_HIGH(expo_c);\r
+\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+    {\r
+        _comm_write(PAH_800x_ADDR_17, a_exposure_low);\r
+        _comm_write(PAH_800x_ADDR_18, a_exposure_high);\r
+    }\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+    {\r
+        _comm_write(PAH_800x_ADDR_19, b_exposure_low);\r
+        _comm_write(PAH_800x_ADDR_1A, b_exposure_high);\r
+    }\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+    {\r
+        _comm_write(PAH_800x_ADDR_1B, c_exposure_low);\r
+        _comm_write(PAH_800x_ADDR_1C, c_exposure_high);\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_tg_toggle(bool enable)\r
+{\r
+    uint8_t data = 0;\r
+    DEBUG_PRINT("%s(%d)\n", __func__, enable);\r
+    _comm_read( PAH_800x_ADDR_07_TG, &data);\r
+    if(enable)\r
+        PAH_SET_BIT(data, PAH_800x_ADDR_07_TG_BIT_EN);\r
+    else\r
+        PAH_CLEAR_BIT(data, PAH_800x_ADDR_07_TG_BIT_EN);\r
+    _comm_write(PAH_800x_ADDR_07_TG, data);\r
+\r
+       return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_update_flag(void)\r
+{\r
+     _comm_write(PAH_800x_ADDR_EB, PAH_800x_ADDR_E8_UPDATE_FLAG);\r
+\r
+     return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_read_product_id(uint16_t *product_id)\r
+{\r
+    return _comm_burst_read(PAH_800x_ADDR_00_PRODUCT_ID, (uint8_t *)product_id,2);\r
+}\r
+\r
+static pah_ret _pah_800x_hal_read_ppg_interrupt(uint8_t *ppg_interrupt)\r
+{\r
+    uint8_t data = 0;\r
+    _comm_read(PAH_800x_ADDR_20, &data);\r
+    if (ppg_interrupt)\r
+        *ppg_interrupt = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_DR_FLAG);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_read_ppg_overflow(uint8_t *ppg_overflow, uint8_t *overflow_num)\r
+{\r
+    uint8_t data = 0;\r
+    _comm_read( PAH_800x_ADDR_20, &data);\r
+    if (ppg_overflow)\r
+    {\r
+        *ppg_overflow = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_OVERFLOW_FLAG);\r
+        *overflow_num = (data&0x70)>>4;\r
+    }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_read_ppg_adc(uint16_t *ppg_adc, uint8_t ch_num)\r
+{\r
+    uint16_t data = 0;\r
+\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+        _comm_burst_read(PAH_800x_ADDR_2E, (uint8_t*)&data, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+        _comm_burst_read(PAH_800x_ADDR_39, (uint8_t*)&data, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+        _comm_burst_read(PAH_800x_ADDR_44, (uint8_t*)&data, 2);\r
+\r
+    //*ppg_adc = data >> 2;\r
+    *ppg_adc = data >> 2;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret _pah_800x_hal_check_enable_channel(pah_800x_test_t *factory_state, const pah_reg_arr *reg_arr)\r
+{\r
+    for(int i=0;i<reg_arr->reg_arr_len;i++)\r
+    {\r
+        if(reg_arr->reg_arr[i][0] == PAH_800x_ADDR_11_EnCh)\r
+        {\r
+            uint8_t data = reg_arr->reg_arr[i][1];\r
+            factory_state->test_ch_enabled[0] = PAH_CHECK_BIT(data, 0); // CH A\r
+            factory_state->test_ch_enabled[1] = PAH_CHECK_BIT(data, 1); // CH B\r
+            factory_state->test_ch_enabled[2] = PAH_CHECK_BIT(data, 2); // CH C\r
+        }\r
+    }\r
+\r
+               return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+void pah8009_get_leaklight_data(uint16_t *ch0,uint16_t *ch1,uint16_t *ch2)\r
+{\r
+       *ch0 = factory_test_ch[0];\r
+       *ch1 = factory_test_ch[1];\r
+       *ch2 = factory_test_ch[2];\r
+\r
+       factory_test_ch[0] = 0;\r
+       factory_test_ch[1] = 0;\r
+       factory_test_ch[2] = 0;\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/factory/pah800x_factory_test.h b/code/sdk/zhihui/drivers/ppg/pah8009/factory/pah800x_factory_test.h
new file mode 100644 (file)
index 0000000..7519958
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef __pah800x_factory_test_h__\r
+#define __pah800x_factory_test_h__\r
+\r
+// pah\r
+//#include "pah_800x.h"\r
+#include "pah_unit.h"\r
+#include "pah_800x_config.h"\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+\r
+/*---------Brightness Test Golden Option---------*/\r
+#define BRIGHTNESS_GLODEN_CHA_ENABLE           true\r
+#define BRIGHTNESS_GLODEN_CHA_MIN_ENABLE       true\r
+#define BRIGHTNESS_GLODEN_CHA_MAX_ENABLE       true\r
+#define BRIGHTNESS_GLODEN_CHA_MIN                      7600\r
+#define BRIGHTNESS_GLODEN_CHA_MAX                      8400\r
+#define BRIGHTNESS_GLODEN_CHB_ENABLE           true\r
+#define BRIGHTNESS_GLODEN_CHB_MIN_ENABLE       true\r
+#define BRIGHTNESS_GLODEN_CHB_MAX_ENABLE       true\r
+#define BRIGHTNESS_GLODEN_CHB_MIN                      7600\r
+#define BRIGHTNESS_GLODEN_CHB_MAX                      8400\r
+#define BRIGHTNESS_GLODEN_CHC_ENABLE           true\r
+#define BRIGHTNESS_GLODEN_CHC_MIN_ENABLE       true\r
+#define BRIGHTNESS_GLODEN_CHC_MAX_ENABLE       true\r
+#define BRIGHTNESS_GLODEN_CHC_MIN                      7600\r
+#define BRIGHTNESS_GLODEN_CHC_MAX                      8400\r
+\r
+/*---------Brightness Test Target Option---------*/\r
+#define BRIGHTNESS_TARGET_CHA_ENABLE           true\r
+#define BRIGHTNESS_TARGET_CHA_MIN_ENABLE       true\r
+#define BRIGHTNESS_TARGET_CHA_MAX_ENABLE       true\r
+#define BRIGHTNESS_TARGET_CHA_MIN                      2400\r
+#define BRIGHTNESS_TARGET_CHA_MAX                      15200\r
+#define BRIGHTNESS_TARGET_CHB_ENABLE           true\r
+#define BRIGHTNESS_TARGET_CHB_MIN_ENABLE       true\r
+#define BRIGHTNESS_TARGET_CHB_MAX_ENABLE       true\r
+#define BRIGHTNESS_TARGET_CHB_MIN                      2400\r
+#define BRIGHTNESS_TARGET_CHB_MAX                      15200\r
+#define BRIGHTNESS_TARGET_CHC_ENABLE           true\r
+#define BRIGHTNESS_TARGET_CHC_MIN_ENABLE       true\r
+#define BRIGHTNESS_TARGET_CHC_MAX_ENABLE       true\r
+#define BRIGHTNESS_TARGET_CHC_MIN                      4000\r
+#define BRIGHTNESS_TARGET_CHC_MAX                      12000\r
+\r
+/*---------Brightness Test Target Option---------*/\r
+#define LEAK_LIGHT_TARGET_CHA_ENABLE           true\r
+#define LEAK_LIGHT_TARGET_CHA_MIN_ENABLE       false\r
+#define LEAK_LIGHT_TARGET_CHA_MAX_ENABLE       true\r
+#define LEAK_LIGHT_TARGET_CHA_MIN                      0\r
+#define LEAK_LIGHT_TARGET_CHA_MAX                      160\r
+#define LEAK_LIGHT_TARGET_CHB_ENABLE           true\r
+#define LEAK_LIGHT_TARGET_CHB_MIN_ENABLE       false\r
+#define LEAK_LIGHT_TARGET_CHB_MAX_ENABLE       true\r
+#define LEAK_LIGHT_TARGET_CHB_MIN                      0\r
+#define LEAK_LIGHT_TARGET_CHB_MAX                      160\r
+#define LEAK_LIGHT_TARGET_CHC_ENABLE           true\r
+#define LEAK_LIGHT_TARGET_CHC_MIN_ENABLE       false\r
+#define LEAK_LIGHT_TARGET_CHC_MAX_ENABLE       true\r
+#define LEAK_LIGHT_TARGET_CHC_MIN                      0\r
+#define LEAK_LIGHT_TARGET_CHC_MAX                      160\r
+\r
+\r
+//============================================================================\r
+// Type Definition\r
+//============================================================================\r
+typedef enum\r
+{\r
+       factory_test_brightness_golden_sample,\r
+       factory_test_brightness_target_sample,\r
+       factory_test_leak_light_target_sample,\r
+       factory_test_power_noise,\r
+       factory_test_INT_high,\r
+       factory_test_INT_low,\r
+       test_type_num,\r
+\r
+} factory_test_type;\r
+\r
+typedef struct\r
+{\r
+       bool            verify_enabled;\r
+\r
+       bool            min_enabled;\r
+       bool            max_enabled;\r
+\r
+       uint16_t    min;\r
+    uint16_t    max;\r
+\r
+} pah_ch_verify_spec_t;\r
+\r
+typedef struct\r
+{\r
+    pah_reg_arr     init_reg_arr;\r
+    pah_reg_arr                test_reg_arr;\r
+\r
+} pah_verify_reg_t;\r
+\r
+typedef struct\r
+{\r
+       pah_ch_verify_spec_t    ch_spec[PAH_800x_MAX_CH_NUM];\r
+\r
+       pah_verify_reg_t                test_regs;\r
+\r
+} pah_verify_config_t;\r
+\r
+typedef struct\r
+{\r
+    bool        has_data;\r
+\r
+    // Avaiable only if has_data is true\r
+    bool        has_overflow;\r
+\r
+    uint8_t     overflow_num;\r
+\r
+    // Avaiable only if has_data is true\r
+    uint16_t    exposure_time[PAH_800x_MAX_CH_NUM];\r
+    uint16_t    adc[PAH_800x_MAX_CH_NUM];\r
+\r
+} pah_test_result_t;\r
+\r
+typedef struct\r
+{\r
+    uint16_t   adc;\r
+\r
+    bool               is_passed;\r
+\r
+} pah_ch_verify_result_t;\r
+\r
+typedef struct\r
+{\r
+    pah_ch_verify_result_t             ch_result[PAH_800x_MAX_CH_NUM];\r
+\r
+} pah_verify_result_t;\r
+\r
+typedef struct\r
+{\r
+    // Config\r
+    //pah_plat            plat;\r
+       pah_verify_config_t             verify_config;\r
+\r
+    bool                                       test_ch_enabled[PAH_800x_MAX_CH_NUM];\r
+\r
+    // PPG state\r
+    pah_test_result_t          test_result;\r
+\r
+    // verify\r
+    pah_verify_result_t                verify_result;\r
+\r
+} pah_800x_test_t;\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+void factory_test_mode(factory_test_type test_type, bool expo_adjust_en, uint16_t expo_a, uint16_t expo_b, uint16_t expo_c);\r
+void pah8009_get_leaklight_data(uint16_t *ch0,uint16_t *ch1,uint16_t *ch2);\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.c b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.c
new file mode 100644 (file)
index 0000000..a208d81
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-05-27 11:09:04\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-06-04 15:38:48\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.c\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+// pah\r
+#include "pah800x_bsp.h"\r
+#include "custom_utils.h"\r
+#include "systick.h"\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+#define PAH800xx_I2C_SLAVE_ID 0x40\r
+#define I2C_PPG_PORT_ID 1\r
+#define PAH800xx_I2C_BUS I2C_BUS_2\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+void pah_delay_ms(uint32_t ms)\r
+{\r
+    // pxi_nrf_delay_ms(ms);\r
+    LOS_Mdelay(ms);\r
+}\r
+\r
+uint64_t pah_get_tick_count(void)\r
+{\r
+    // return pxi_nrf_get_tick_count();\r
+    uint64_t cnt = uapi_systick_get_ms();\r
+    // printf("cnt : %llu\n",cnt);\r
+    return cnt;\r
+}\r
+\r
+pah_ret pah_comm_i2c_write(uint8_t addr, const uint8_t *data, size_t write_size)\r
+{\r
+    //DEBUG_PRINT("W A:0x%02x,D:0x%02x\n",addr,*data);\r
+    // pxi_nrf_i2c_write(addr, data, write_size);\r
+    custom_i2c_write_reg(PAH800xx_I2C_SLAVE_ID, addr, 1, data, write_size, PAH800xx_I2C_BUS);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_comm_i2c_read(uint8_t addr, uint8_t *data, size_t read_size)\r
+{\r
+    // pxi_nrf_i2c_read(addr, data, read_size);\r
+    custom_i2c_read_regs(PAH800xx_I2C_SLAVE_ID, addr, 1 , data, read_size, PAH800xx_I2C_BUS);\r
+    //DEBUG_PRINT("R A:0x%02x,D:0x%02x\n",addr,*data);\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+void pah_print(\r
+    int32_t                         fileline,\r
+    const char                      *funcname,\r
+    const char                      *filename,\r
+    const char                      *format, ...)\r
+{\r
+    UNUSED_VAR(fileline);\r
+    UNUSED_VAR(funcname);\r
+    UNUSED_VAR(filename);\r
+\r
+    char dest[256];\r
+    va_list argptr;\r
+    int char_num = 0;\r
+\r
+    if (!format)\r
+        return;\r
+\r
+    va_start(argptr, format);\r
+    char_num = vsprintf(dest, format, argptr);\r
+    va_end(argptr);\r
+\r
+    //uart_printf("%s", dest);\r
+\r
+    //dest[char_num] = '\n';\r
+    // pxi_nrf_uart_transmit((uint8_t*)dest, (uint16_t)(char_num + 1));\r
+}\r
+\r
+void ReadGSensor(float *x, float *y, float *z)\r
+{\r
+    \r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.h b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.h
new file mode 100644 (file)
index 0000000..cae483f
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-05-27 11:09:04\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-05-27 11:32:50\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#ifndef __pah_800x_bsp_h__\r
+#define __pah_800x_bsp_h__\r
+\r
+// c\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+// pah\r
+#include "pah_unit.h"\r
+#include "pah_800x_config.h"\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+#ifdef __cplusplus\r
+extern  "C" {\r
+#endif \r
+\r
+void pah_delay_ms(uint32_t ms);\r
+uint64_t pah_get_tick_count(void);\r
+pah_ret pah_comm_i2c_write(uint8_t addr, const uint8_t *data, size_t write_size);\r
+pah_ret pah_comm_i2c_read(uint8_t addr, uint8_t *data, size_t read_size);\r
+void pah_print(\r
+    int32_t                         fileline,\r
+    const char                      *funcname,\r
+    const char                      *filename,\r
+    const char                      *format, ...);\r
+\r
+void ReadGSensor(float *x, float *y, float *z);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.c b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.c
new file mode 100644 (file)
index 0000000..59697f0
--- /dev/null
@@ -0,0 +1,1628 @@
+// pah\r
+#include "pah800x_main.h"\r
+//#include "pah_8009_reg_arr_default.h"\r
+#include "pxialg_spo2.h"\r
+#include "pxialg_hrv.h"\r
+#include "pxivar.h"\r
+#include "pah_8009_reg_arr_default_20220623.h"\r
+#include "pah800x_factory_test.h"\r
+#include "cmsis_os2.h"\r
+\r
+#ifdef SUPPORT_PPG_SERVICE\r
+#include "ppg_service.h"\r
+#endif\r
+//============================================================================\r
+// Static Global Variable\r
+//============================================================================\r
+static main_state _main;\r
+static ppg_mems_data_t ppg_mems_data_buf[FIFO_SIZE] ;\r
+static int _read_index = 0 ;\r
+static int _write_index = 0 ;\r
+    \r
+// hr algotirhm\r
+static float hr = 0.0f;\r
+static float hr_grader =0.0f;\r
+static ppg_mems_data_t ppg_mems_data_alg;\r
+\r
+// spo2 algorithm\r
+void *pBuffer                 = NULL;\r
+void *hr_pBuffer              = NULL;    \r
+static float myHR             = 0.0f;\r
+static float mySpO2           = 0.0f;\r
+static float correlation      = 0.0f;\r
+static float trust_flag       = 0.0f;\r
+static float MEMS_RMS         = 0.0f;\r
+uint8_t      mySPO2_ReadyFlag = 0   ;\r
+static uint8_t no_value_reason = 0      ;\r
+static float   SignalPeriodicity=0.0f   ;\r
+\r
+static int     time_accu       = 0      ;\r
+static int              count         =0;\r
+static float            spo2_array[31]={0.0f};   \r
+\r
+static  uint32_t   data_buf_count_spo2_alg=0;\r
+\r
+static  SpO2_info_t    _spo2_detect_item;\r
+pah8series_data_t      pxialg_data_spo2;\r
+static  SpO2_mems_t    mems_data_raw[150];  \r
+#ifdef PPG_MEMS_Synchronize \r
+//int16_t mems_int_data_in[90] ={0};\r
+int16_t mems_int_data_out[90]={0};\r
+int time_temp=0;  \r
+static uint8_t ppg_data_num=0;\r
+uint8_t mems_data_polling_ready = 0 ;  \r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+// Stress Algorithm \r
+static hrv_state_s _hrv_state;\r
+void *stress_pBuffer              = NULL;    \r
+#define HRV_ENABLE_LHR                1\r
+#define HRV_SAMPLING_RATE                20\r
+#define HRV_COLLECTION_SECONDS          180   \r
+static     uint32_t  duration_total  = 0;\r
+uint8_t SDNN_ReadyFlag               = 0;\r
+uint8_t Get_Stress                   = 0;\r
+static  float Stress                 = 0.0f;\r
+static  uint8_t HRAvg                = 0;\r
+static  float SQ_Stress              = 0.0f;\r
+static  uint8_t AnomalyFlag          = 0;\r
+uint8_t Stress_ReadyFlag             = 0;\r
+uint8_t Weak_Flag                    = 0;\r
+\r
+static uint32_t factory_data = 0;\r
+static uint8_t work_mode = 0;\r
+\r
+\r
+static osTimerId_t g_pah8009_timer = NULL;\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static bool sensor_basic_verification(void);    \r
+static void process(uint64_t timestamp);\r
+static void ppg_sensor_enable(void);\r
+static void ppg_sensor_disable(void);\r
+static void touch_sensor_enable(void);\r
+static void touch_sensor_disable(void);\r
+\r
+static void report_touch_data(uint64_t timestamp, const int8_t *touch_flag);\r
+static void report_ppg_data(const ppg_mems_data_t *ppg_mems_data_alg);\r
+static void report_hr_data(const ppg_mems_data_t *ppg_mems_data_alg, int32_t ret, float hr, float hr_grader);\r
+static void report_spo2_data(const ppg_mems_data_t *ppg_mems_data_alg, int32_t ret, float myHR, float mySpO2,  float correlation, float trust_flag, float MEMS_RMS, int data_buf_count_spo2_alg, uint8_t no_value_reason,  float   SignalPeriodicity,  int     time_accu );\r
+static void report_stress_data(const ppg_mems_data_t *ppg_mems_data_alg, uint8_t Stress_ReadyFlag, uint32_t measuretime, float collect_time);\r
+\r
+static void error_handle(void);\r
+\r
+\r
+static void bubblesort(float *input,int count) \r
+{\r
+    int i,j;\r
+    float sort_temp;\r
+    for(i=0;i<count - 1;i++)\r
+    {\r
+        for(j=0;j<count-i - 1;j++) \r
+        {\r
+            if(input[j+1]<input[j])\r
+            {\r
+                sort_temp=input[j+1];\r
+                input[j+1]=input[j];\r
+                input[j]=sort_temp;\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+void spo2_log_printf(char s, float f)\r
+{\r
+       LOG_PRINT("%s= "LOG_FLOAT_MARKER"   \n",s, LOG_FLOAT(f));\r
+\r
+}\r
+\r
+/*****************************\r
+FW FIFO Function\r
+*****************************/\r
+bool isFIFOEmpty(void)\r
+{\r
+    return (_write_index == _read_index) ;\r
+}\r
+\r
+bool pah_push(ppg_mems_data_t *data) //Push return data must be true. If return false, please increase FIFO size.  \r
+{\r
+    int tmp = _write_index ;\r
+    tmp++;\r
+    if(tmp >= FIFO_SIZE)\r
+        tmp = 0 ;\r
+    if(tmp == _read_index)\r
+        return false;\r
+    ppg_mems_data_buf[tmp] = *data ;\r
+    _write_index = tmp ;\r
+    return true;\r
+}\r
+\r
+bool pah_pop(ppg_mems_data_t *data)\r
+{\r
+    int tmp ;\r
+    if(isFIFOEmpty())\r
+        return false;\r
+    tmp = _read_index + 1;\r
+    if(tmp >= FIFO_SIZE)\r
+        tmp = 0 ;    \r
+    _read_index = tmp ;\r
+    *data = ppg_mems_data_buf[_read_index] ;\r
+    \r
+    return true;\r
+}\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+void pah_sensor_init(reg_config_type type)\r
+{\r
+    memset(&_main, 0, sizeof(_main));\r
+\r
+    pah_800x_reg_setting  reg_setting;\r
+    memset(&reg_setting, 0, sizeof(reg_setting));\r
+    \r
+    if (!sensor_basic_verification())\r
+    {\r
+        // error_handle();\r
+        LOG_PRINT("sensor_basic_verification failed\n");\r
+        return;\r
+    }\r
+\r
+\r
+    // pah_800x\r
+    pah_800x_config     pah_800x_config;\r
+    pah_800x_get_default_config(&pah_800x_config);\r
+    LOG_PRINT("PPG_SETTING_VESION = %d \n" ,PPG_SETTING_VERSION);\r
+    \r
+#if (ENABLE_AE==0)\r
+    pah_800x_config.enable_ppg_convergence[0] = false;\r
+    pah_800x_config.enable_ppg_convergence[1] = false;\r
+    pah_800x_config.enable_ppg_convergence[2] = false;\r
+#endif\r
+\r
+#if (ENABLE_AE_RECONVERGENCE==0)\r
+    pah_800x_config.enable_ppg_reconvergence_if_out_of_bounds[0] = false;\r
+    pah_800x_config.enable_ppg_reconvergence_if_out_of_bounds[1] = false;\r
+    pah_800x_config.enable_ppg_reconvergence_if_out_of_bounds[2] = false;\r
+#endif\r
+\r
+    if (type == pc_4mm_2g_ir_hrd)\r
+    {\r
+#if (PC_4MM_2G_IR_HRD==1)\r
+        PAH_REG_ARR_SETUP(reg_setting.startup_init, PAH8009_REG_DEVICE_INIT);\r
+        PAH_REG_ARR_SETUP(reg_setting.ppg_enable, PAH8009_REG_PC_4MM_2G_IR_PPG);\r
+        PAH_REG_ARR_SETUP(reg_setting.touch_enable, PAH8009_REG_PC_4MM_2G_IR_TOUCH);\r
+#endif\r
+    }\r
+    else if (type == diw_4mm_g_ir_hrd)\r
+    {\r
+#if (DIW_4MM_G_IR_HRD==1)\r
+        PAH_REG_ARR_SETUP(reg_setting.startup_init, PAH8009_REG_DEVICE_INIT);\r
+        PAH_REG_ARR_SETUP(reg_setting.ppg_enable, PAH8009_REG_DIW_4MM_G_IR_PPG);\r
+        PAH_REG_ARR_SETUP(reg_setting.touch_enable, PAH8009_REG_DIW_4MM_G_IR_TOUCH);\r
+#endif\r
+    }\r
+    else if (type == diw_4mm_ir_r_ir_spo2)\r
+    {\r
+#if (DIW_4MM_IR_R_IR_SPO2==1)\r
+        for(int ch=0;ch<PAH_800x_MAX_CH_NUM;ch++)\r
+        {\r
+            pah_800x_config.ppg_convergence[ch].t_weight_normal_mode = 4;\r
+            pah_800x_config.ppg_convergence[ch].t_weight_fast_mode = 8;\r
+            pah_800x_config.ppg_convergence[ch].t_max = 150;\r
+        }\r
+        PAH_REG_ARR_SETUP(reg_setting.startup_init, PAH8009_REG_DEVICE_INIT);\r
+        PAH_REG_ARR_SETUP(reg_setting.ppg_enable, PAH8009_REG_DIW_4MM_IR_R_IR_PPG);\r
+        PAH_REG_ARR_SETUP(reg_setting.touch_enable, PAH8009_REG_DIW_4MM_IR_R_IR_TOUCH);\r
+#endif\r
+    }\r
+    else if (type == pc_22mm_2g_ir_hrd)\r
+    {\r
+#if (PC_22MM_2G_IR_HRD==1)\r
+        for(int ch=0;ch<PAH_800x_MAX_CH_NUM;ch++)\r
+        {\r
+            pah_800x_config.ppg_convergence[ch].t_max = 1280;\r
+            pah_800x_config.ppg_convergence[ch].raw_outer_high_bound = 14848;\r
+            pah_800x_config.ppg_convergence[ch].raw_inner_high_target = 13824;\r
+            pah_800x_config.ppg_convergence[ch].raw_inner_low_target = 10752;\r
+            pah_800x_config.ppg_convergence[ch].raw_outer_low_bound = 9728;\r
+\r
+        }\r
+        PAH_REG_ARR_SETUP(reg_setting.startup_init, PAH800x_REG_DEVICE_INIT);\r
+        PAH_REG_ARR_SETUP(reg_setting.ppg_enable, PAH800x_REG_PC_22MM_2G_IR_PPG);\r
+        PAH_REG_ARR_SETUP(reg_setting.touch_enable, PAH800x_REG_PC_22MM_2G_IR_TOUCH);\r
+#endif\r
+    }\r
+    else if (type == di_18mm_g_g_hrd)\r
+    {\r
+#if (DI_18MM_G_G_HRD==1)\r
+        for(int ch=0;ch<PAH_800x_MAX_CH_NUM;ch++)\r
+        {\r
+            pah_800x_config.ppg_convergence[ch].t_weight_normal_mode = 15;\r
+            pah_800x_config.ppg_convergence[ch].t_weight_fast_mode = 25;\r
+            pah_800x_config.ppg_convergence[ch].t_max = 2048;\r
+        }\r
+        PAH_REG_ARR_SETUP(reg_setting.startup_init, PAH8001_REG_DEVICE_INIT);\r
+        PAH_REG_ARR_SETUP(reg_setting.ppg_enable, PAH8001_REG_DI_18MM_G_G_PPG);\r
+        PAH_REG_ARR_SETUP(reg_setting.touch_enable, PAH8001_REG_DI_18MM_G_G_TOUCH);\r
+#endif\r
+    }\r
+\r
+    _main.pah_800x.is_powered= false ;\r
+    pah_800x_init(&_main.pah_800x,  &pah_800x_config);\r
+    pah_800x_device_init(&_main.pah_800x, &reg_setting);\r
+\r
+}\r
+\r
+void touch_only_sensor_start(void)\r
+{\r
+    pah_800x_power_toggle(&_main.pah_800x, true);\r
+    _main.is_Auto_mode = 0;\r
+    touch_sensor_enable();\r
+    _main.debug_print_header = true;\r
+\r
+}\r
+\r
+void ppg_only_sensor_start(void)\r
+{\r
+    pah_800x_power_toggle(&_main.pah_800x, true);\r
+    \r
+    ppg_sensor_enable();\r
+   \r
+    //_main.ppg_only_is_enabled = 1 ;\r
+    _main.is_Auto_mode = 0;\r
+    _main.debug_print_header = true;\r
+    \r
+}\r
+\r
+void auto_mode_sensor_start(void)\r
+{\r
+    pah_800x_power_toggle(&_main.pah_800x, true);\r
+    \r
+    touch_sensor_enable();\r
+    _main.is_Auto_mode = 1;\r
+    _main.debug_print_header = true;\r
+    \r
+}\r
+\r
+void pah_sensor_stop(void)\r
+{\r
+    if (_main.ppg_is_enabled)\r
+    {\r
+        ppg_sensor_disable();\r
+    }\r
+    if (_main.touch_is_enabled)\r
+    {\r
+        touch_sensor_disable();\r
+    }\r
+    pah_800x_deinit(&_main.pah_800x);      \r
+      \r
+}\r
+\r
+void ppg_interrupt_handle(void)\r
+{\r
+    _main.has_interrupt = true;\r
+    _main.interrupt_timestamp = pah_get_tick_count();\r
+}\r
+\r
+void ppg_sensor_task_interrupt(void)\r
+{\r
+    if (_main.has_interrupt)\r
+    {\r
+        //LOG_PRINT("ppg_sensor_task_interrupt111111\n");\r
+        _main.has_interrupt = false;\r
+        _main.interrupt_timestamp = pah_get_tick_count();\r
+        process(_main.interrupt_timestamp);\r
+    }\r
+\r
+} \r
+\r
+void ppg_sensor_task_polling(void)\r
+{\r
+    _main.interrupt_timestamp = pah_get_tick_count();\r
+    process(_main.interrupt_timestamp);\r
+} \r
+\r
+uint8_t Check_alg_enable(void)\r
+{\r
+    return _main.alg_is_enabled;\r
+}\r
+\r
+void Clear_alg_enable(void)\r
+{\r
+    _main.alg_is_enabled = MSG_ALG_NOCHANGE;\r
+}\r
+\r
+\r
+// HR\r
+void hr_algorithm_enable(void)\r
+{\r
+    if (_main.hr_is_enabled)\r
+        return;\r
+\r
+    // static  Hr-V301009\r
+        \r
+    PxiAlg_Close();\r
+    int version = PxiAlg_Version();\r
+    DEBUG_PRINT("HR_Version = %d \r\n", version);\r
+   \r
+\r
+    uint32_t Query_Mem_Size = PxiAlg_Query_Mem_Size();\r
+    DEBUG_PRINT("HR_Mem_Size = %d \r\n", Query_Mem_Size);\r
+    \r
+    hr_pBuffer = malloc(Query_Mem_Size);\r
+           \r
+   \r
+    if(!PxiAlg_Open_Mem(hr_pBuffer))\r
+        DEBUG_PRINT("PxiAlg_Open_Mem fail \n");\r
+                \r
+            \r
+    PxiAlg_SetQualityThreshold(0.35f); \r
+    PxiAlg_SetHRSmoothWeight(0.9f); \r
+    PxiAlg_SetProcWindow(5.0f, 5.0f); \r
+    PxiAlg_SetTimeoutLength(30.0f);\r
+    PxiAlg_SetMemsScale(3);              //MEMS 2/4/8/16G : 0/1/2/3\r
+    PxiAlg_SetSkipSampleNum(10); \r
+    PxiAlg_SetMemsScaleBase(3, 0);    //MEMS 2/4/8/16G : 0/1/2/3\r
+    PxiAlg_SetForceOutputLink(10, 150, 40, 1, 0.9f); \r
+    PxiAlg_SetNormalOutput(200, 40, 0); \r
+    PxiAlg_SetForceRipple(3, 1); \r
+    //PxiAlg_SetForceOutput(30, 120, 45);\r
+    //PxiAlg_SetForceOutputTime(10);\r
+    PxiAlg_SetPackage(0, 1);\r
+\r
+    _main.hr_is_enabled = true;\r
+}\r
+\r
+void hr_algorithm_disable(void)\r
+{\r
+    if (!_main.hr_is_enabled)\r
+        return;\r
+\r
+    PxiAlg_Close();\r
+    free(hr_pBuffer);\r
+    hr = 0.0f;\r
+    hr_grader =0.0f;\r
+    _main.hr_is_enabled = false;\r
+}\r
+\r
+void hr_alg_task(void)\r
+{\r
+    if(Check_alg_enable())\r
+    {\r
+        if(Check_alg_enable()==MSG_ALG_ENABLE)\r
+        {\r
+            hr_algorithm_enable();\r
+        }else if(Check_alg_enable()==MSG_ALG_DISABLE)\r
+        {\r
+            hr_algorithm_disable();\r
+        }\r
+        Clear_alg_enable();\r
+    }\r
+\r
+    if(!isFIFOEmpty())\r
+    {\r
+        if(pah_pop(&ppg_mems_data_alg))    //Get data from FIFO\r
+        {\r
+            if(_main.hr_is_enabled)\r
+            {\r
+                // 13Bytes format to hr lib;\r
+                sRaw_Data_13Bytes hr_data;\r
+\r
+                memset(&hr_data, 0, sizeof(hr_data));\r
+                hr_data.loss = (uint8_t)ppg_mems_data_alg.ppg_data.overflow_num + 1;\r
+                hr_data.rawData = ppg_mems_data_alg.ppg_data.data[1];\r
+                hr_data.non_zero1 = 1;\r
+                hr_data.non_zero2 = 2;\r
+                hr_data.non_zero3 = 3;\r
+                hr_data.frame_count = ppg_mems_data_alg.ppg_frame_count;\r
+                hr_data.time = ppg_mems_data_alg.duration;\r
+                hr_data.rsv = 0;\r
+                hr_data.touch = (ppg_mems_data_alg.touch_flag > 0 ? 0x80 : 0x00);\r
+                hr_data.rsv2 = 0;\r
+  \r
+  \r
+                int32_t ret = PxiAlg_Process_Expo((uint8_t*)&hr_data, ppg_mems_data_alg.MEMS_Data, ppg_mems_data_alg.ppg_data.exposure_time[1]);\r
+  \r
+\r
+                if(PxiAlg_GetHrUpdateFlag())\r
+                {\r
+                    PxiAlg_HrGet(&hr);\r
+                    PxiAlg_GetSigGrade(&hr_grader);\r
+                }\r
+                if(ppg_mems_data_alg.touch_flag==0)\r
+                {\r
+                    hr = 0 ;\r
+                    hr_grader = 0;\r
+                }\r
+\r
+                // if(hr > 0)\r
+                    printf("hr:%f\n",hr);\r
+\r
+                report_hr_data(&ppg_mems_data_alg, ret, hr, hr_grader);\r
+\r
+    \r
+            }\r
+            else\r
+            {\r
+                report_ppg_data(&ppg_mems_data_alg);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+// HRD- ALG-  Task2\r
+void hr_alg_task2(uint8_t ppg_num)\r
+{\r
+#ifdef PPG_MEMS_Synchronize\r
+    if(Check_alg_enable())\r
+    {\r
+        if(Check_alg_enable()==MSG_ALG_ENABLE)\r
+        {\r
+            hr_algorithm_enable();\r
+        }else if(Check_alg_enable()==MSG_ALG_DISABLE)\r
+        {\r
+            hr_algorithm_disable();\r
+        }\r
+        Clear_alg_enable();\r
+    }\r
+  \r
+    if(!isFIFOEmpty())\r
+    {\r
+        for (int i=0; i<ppg_num; i++)\r
+        {\r
+              \r
+            if(pah_pop(&ppg_mems_data_alg))  //Get data from FIFO\r
+            {\r
+                if(_main.hr_is_enabled)\r
+                {\r
+                    ppg_mems_data_alg.MEMS_Data[0]=mems_int_data_out[3*i];\r
+                    ppg_mems_data_alg.MEMS_Data[1]=mems_int_data_out[3*i+1];\r
+                    ppg_mems_data_alg.MEMS_Data[2]=mems_int_data_out[3*i+2];\r
+            \r
+                    // 13Bytes format to hr lib;\r
+                    sRaw_Data_13Bytes hr_data;\r
+      \r
+                    memset(&hr_data, 0, sizeof(hr_data));\r
+                    hr_data.loss = (uint8_t)ppg_mems_data_alg.ppg_data.overflow_num + 1;\r
+                    hr_data.rawData = ppg_mems_data_alg.ppg_data.data[1];\r
+                    hr_data.non_zero1 = 1;\r
+                    hr_data.non_zero2 = 2;\r
+                    hr_data.non_zero3 = 3;\r
+                    hr_data.frame_count = ppg_mems_data_alg.ppg_frame_count;\r
+                    hr_data.time = ppg_mems_data_alg.duration;\r
+                    hr_data.rsv = 0;\r
+                    hr_data.touch = (ppg_mems_data_alg.touch_flag > 0 ? 0x80 : 0x00);\r
+                    hr_data.rsv2 = 0;\r
+      \r
+                    int32_t ret = PxiAlg_Process_Expo((uint8_t*)&hr_data, ppg_mems_data_alg.MEMS_Data, ppg_mems_data_alg.ppg_data.exposure_time[1]);\r
+  \r
+\r
+                    if(PxiAlg_GetHrUpdateFlag())\r
+                    {\r
+                        PxiAlg_HrGet(&hr);\r
+                        PxiAlg_GetSigGrade(&hr_grader);\r
+                    }\r
+               \r
+                    report_hr_data(&ppg_mems_data_alg, ret, hr, hr_grader);\r
+      \r
+                }\r
+                else\r
+                {\r
+                    report_ppg_data(&ppg_mems_data_alg);\r
+                }\r
+            }\r
+        }\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+\r
+// SPO2\r
+void spo2_algorithm_enable(void)\r
+{\r
+    if (_main.spo2_is_enabled)\r
+    {\r
+        return;\r
+    }\r
+\r
+\r
+    int version = SpO2_Version();\r
+    DEBUG_PRINT("PxiAlg_Version() = %d\n", version);\r
+        \r
+    uint32_t buffer_size = SpO2_OpenSize();\r
+    DEBUG_PRINT("SpO2_Open buffer_size = %d \n", buffer_size);\r
+\r
+    pBuffer = malloc(buffer_size);\r
+        \r
+    if (SpO2_Open(pBuffer) != SPO2_MSG_SUCCESS)\r
+    {\r
+        DEBUG_PRINT("SpO2_Open() failed. \n");\r
+        free(pBuffer);\r
+        return;\r
+    }\r
+    int8_t alg_ch[2]    = {0, 1};      \r
+\r
+    SpO2_SetChMapping(alg_ch, 2);\r
+    SpO2_SetInputRatioHighBound(94.0f);\r
+    SpO2_SetInputRatioLowBound(87.0f);\r
+    SpO2_SetInputModelScale(0.50f);\r
+\r
+    SpO2_SetInputCoefHigh0(-36877.85546875f);\r
+    SpO2_SetInputCoefHigh1(1135.91394042969f);\r
+    SpO2_SetInputCoefHigh2(-11.6429319381714f);\r
+    SpO2_SetInputCoefHigh3(0.0398150011897087f);\r
+\r
+    SpO2_SetInputCoefMid0(-1430.70520019531f);\r
+    SpO2_SetInputCoefMid1(50.1599006652832f);\r
+    SpO2_SetInputCoefMid2(-0.567422986030579f);\r
+    SpO2_SetInputCoefMid3(0.00219199992716312f);\r
+\r
+    SpO2_SetInputCoefLow0(-8.19796657562256f);\r
+    SpO2_SetInputCoefLow1(1.74200701713562f);\r
+    SpO2_SetInputCoefLow2(-0.0173850003629923f);\r
+    SpO2_SetInputCoefLow3(0.000105999999505002f);\r
+\r
+    SpO2_SetIIRFilterRatio(0.5f);\r
+    SpO2_SetInputCorrelationTh(0.850000078678131f);\r
+    SpO2_SetInputRatioLow(0.05f);        \r
+\r
+    SpO2_SetInputFlagCheckHr(1);\r
+    SpO2_SetMotionDetectionLevel(2.0f);\r
+    SpO2_Set_Update_Sec(1);\r
+\r
+    SpO2_Set_Init_Low_SpO2_Constrain(0.0);  \r
+    SpO2_SetOutputHighBound(100.0f);\r
+    SpO2_SetOutputLowBound(60.0f);\r
+    SpO2_Set_Keep_Init_SpO2_Bound(95.0f);    \r
+    SpO2_Set_Keep_Init_SpO2_Count_Th(18.0f);\r
+    SpO2_Set_SpO2_Bias_Value(0.5f);           \r
+    SpO2_Set_SpO2_Outlier_Smooth_Coef(5.5f);  \r
+    SpO2_Set_SpO2_Decrease_Coef(0.5f);        \r
+    SpO2_SetSkipDataLen(25);\r
+\r
+    SpO2_Set_Flag_Hold_Breathe_Mode(0);\r
+    SpO2_Set_Input_Correlation_Th2(0.85000f);\r
+    SpO2_Set_Correlation_Th2_Count(30.0f);\r
+    SpO2_Set_Init_Low_SpO2_Th(94.5f);\r
+    SpO2_Set_Motion_Rms_Th(3000.0f);\r
+    SpO2_Set_Motion_Rms_Th2(1500.0f);\r
+    SpO2_Set_Motion_MEMS_Th(0.0f); \r
+    SpO2_Set_T1(0.85f);\r
+    SpO2_Set_Spo2_Force_Output_Second(15.0f);\r
+\r
+    Spo2_Set_Force_Output_Value(97.50f);  // Good Signal Force SpO2\r
+    Spo2_Set_Force_Output_Value2(95.00f); // Bad  Signal Force SpO2\r
+\r
+    SpO2_Set_Init_Low_SpO2_Check_Sec(20);\r
+    Spo2_Set_SpO2_First_Smooth_Th(95.0f);\r
+    Spo2_Set_SpO2_First_Smooth_Sec(15);\r
+    Spo2_Set_SpO2_Correlation_Smooth_Th(0.85f);\r
+    SpO2_Set_Signal_Periodicity_Th(0.50f);\r
+       \r
+    // static  Hr-V301009\r
+    PxiAlg_Close();\r
+    version = PxiAlg_Version();\r
+    DEBUG_PRINT("HR_Version = %d \r\n", version);\r
+        \r
+    \r
+    uint32_t Query_Mem_Size = PxiAlg_Query_Mem_Size();\r
+    DEBUG_PRINT("HR_Mem_Size = %d \r\n", Query_Mem_Size);\r
+    \r
+    hr_pBuffer = malloc(Query_Mem_Size);\r
+        \r
+    \r
+    if(!PxiAlg_Open_Mem(hr_pBuffer))\r
+          DEBUG_PRINT("PxiAlg_Open_Mem fail \n");\r
+             \r
+            \r
+    PxiAlg_SetQualityThreshold(0.35f); \r
+    PxiAlg_SetHRSmoothWeight(0.9f); \r
+    PxiAlg_SetProcWindow(5.0f, 5.0f); \r
+    PxiAlg_SetTimeoutLength(30.0f);\r
+    PxiAlg_SetMemsScale(1);       //MEMS 2/4/8/16G : 0/1/2/3\r
+    PxiAlg_SetSkipSampleNum(10); \r
+    PxiAlg_SetMemsScaleBase(1, 0); //MEMS 2/4/8/16G : 0/1/2/3\r
+    PxiAlg_SetForceOutputLink(15, 90, 60, 1, 0.9f); \r
+    PxiAlg_SetNormalOutput(200, 40, 1); \r
+    PxiAlg_SetForceRipple(3, 1); \r
+    PxiAlg_SetPackage(0, 1);\r
+    \r
+    myHR                   = 0.0f;\r
+    mySpO2                 = 0.0f;\r
+    correlation            = 0.0f;\r
+    trust_flag             = 0.0f;\r
+    MEMS_RMS               = 0.0f;\r
+    mySPO2_ReadyFlag       = 0;\r
+    hr_grader              = 0.0f;\r
+    data_buf_count_spo2_alg=0;\r
+    no_value_reason = 0      ;\r
+    SignalPeriodicity=0.0f   ;\r
+    time_accu       = 0      ;\r
+    count           = 0 ;\r
+    memset(spo2_array, 0, sizeof(*spo2_array));\r
+    _main.spo2_is_enabled = true;\r
+}\r
+\r
+void spo2_algorithm_disable(void)\r
+{\r
+    if (!_main.spo2_is_enabled)\r
+        return;\r
+    PxiAlg_Close();\r
+    SpO2_Close();\r
+    free(pBuffer);\r
+    free(hr_pBuffer);\r
+    myHR                   = 0.0f;\r
+    mySpO2                 = 0.0f;\r
+    correlation            = 0.0f;\r
+    trust_flag             = 0.0f;\r
+    MEMS_RMS               = 0.0f;\r
+    mySPO2_ReadyFlag       = 0;\r
+    hr_grader              = 0.0f;\r
+    data_buf_count_spo2_alg=0;\r
+    \r
+    no_value_reason = 0      ;\r
+    SignalPeriodicity=0.0f   ;\r
+    time_accu       = 0      ;\r
+    \r
+    \r
+    _main.spo2_is_enabled = false;\r
+}\r
+\r
+void spo2_alg_task(void)\r
+{\r
+    if(Check_alg_enable())\r
+    {\r
+        if(Check_alg_enable()==MSG_ALG_ENABLE)\r
+        {\r
+            spo2_algorithm_enable();\r
+        }else if(Check_alg_enable()==MSG_ALG_DISABLE)\r
+        {\r
+            spo2_algorithm_disable();\r
+        }\r
+        Clear_alg_enable();\r
+    }\r
+\r
+    if(!isFIFOEmpty())\r
+    {\r
+        if(pah_pop(&ppg_mems_data_alg))    //Get data from FIFO\r
+        {\r
+            if(_main.spo2_is_enabled)\r
+            {\r
+                // 13Bytes format to hr lib;\r
+                    \r
+                int32_t  RAW_DATA[2]  ;\r
+                sRaw_Data_13Bytes hr_data;\r
+                 \r
+                memset(&hr_data, 0, sizeof(hr_data));\r
+                hr_data.loss = (uint8_t)ppg_mems_data_alg.ppg_data.overflow_num + 1;\r
+                hr_data.rawData = ppg_mems_data_alg.ppg_data.data[0];\r
+                hr_data.non_zero1 = 1;\r
+                hr_data.non_zero2 = 2;\r
+                hr_data.non_zero3 = 3;\r
+                hr_data.frame_count = ppg_mems_data_alg.ppg_frame_count;\r
+                hr_data.time = ppg_mems_data_alg.duration;\r
+                hr_data.rsv = 0;\r
+                hr_data.touch = (ppg_mems_data_alg.touch_flag > 0 ? 0x80 : 0x00);\r
+                hr_data.rsv2 = 0;\r
+           \r
+           \r
+                int32_t ret = PxiAlg_Process_Expo((uint8_t*)&hr_data, ppg_mems_data_alg.MEMS_Data, ppg_mems_data_alg.ppg_data.exposure_time[0]);\r
+               \r
+\r
+                \r
+\r
+                if(PxiAlg_GetHrUpdateFlag())\r
+                {\r
+                    PxiAlg_HrGet(&myHR);\r
+                    PxiAlg_GetSigGrade(&hr_grader);\r
+                }\r
+\r
+\r
+                int32_t spo2_raw_1=ppg_mems_data_alg.ppg_data.data[0];\r
+                int32_t spo2_raw_2=ppg_mems_data_alg.ppg_data.data[1];\r
+                \r
+                RAW_DATA[0]=spo2_raw_1;\r
+                RAW_DATA[1]=spo2_raw_2;\r
+\r
+                mems_data_raw[0].data[0]=ppg_mems_data_alg.MEMS_Data[0];\r
+                mems_data_raw[0].data[1]=ppg_mems_data_alg.MEMS_Data[1] ;\r
+                mems_data_raw[0].data[2]=ppg_mems_data_alg.MEMS_Data[2];            \r
+\r
+                // SPO2 fill data on pah8series structure\r
+                pxialg_data_spo2.touch_flag         =  ppg_mems_data_alg.touch_flag ;\r
+                pxialg_data_spo2.time               =  ppg_mems_data_alg.duration ;;\r
+                pxialg_data_spo2.ppg_data           =  (int32_t*)RAW_DATA;\r
+                pxialg_data_spo2.nf_ppg_channel     =  2;\r
+                pxialg_data_spo2.nf_ppg_per_channel =  1;\r
+                pxialg_data_spo2.frame_count        =  ppg_mems_data_alg.ppg_frame_count ;\r
+                pxialg_data_spo2.nf_mems            =  1;\r
+                pxialg_data_spo2.mems_data          = (int16_t*)mems_data_raw;\r
+\r
+\r
+\r
+                // DEBUG_PRINT("data_buf_count_spo2_alg = %d \r\n", data_buf_count_spo2_alg);\r
+\r
+\r
+                SpO2_SetHrValue(myHR);\r
+                SpO2_SetMems(mems_data_raw, 1);\r
+                //int  ret_value = SpO2_Process(ppg_mems_data_alg.touch_flag , 2, pxialg_data_spo2.ppg_data, 1);\r
+                int  ret_value = SpO2_Process(ppg_mems_data_alg.touch_flag , 2, pxialg_data_spo2.ppg_data, 1,pxialg_data_spo2.time );\r
+             \r
+                SpO2_GetSpO2(&mySpO2);\r
+                \r
+                // if(mySpO2 > 0)\r
+                    printf("SpO2 : %f\n",mySpO2);\r
+\r
+                SpO2_GetReadyFlag(&mySPO2_ReadyFlag);\r
+                SpO2_GetInfo(&_spo2_detect_item);\r
+                correlation =_spo2_detect_item.Noise;\r
+                trust_flag =_spo2_detect_item.Output[3];\r
+                no_value_reason=_spo2_detect_item.Output[4];\r
+                SpO2_GetPeriodicity(&SignalPeriodicity);\r
+                MEMS_RMS  =_spo2_detect_item.RMS;\r
+                \r
+\r
+                data_buf_count_spo2_alg++;\r
+                \r
+            #if defined(Optimize_SPO2_flow) \r
+                time_accu=time_accu+pxialg_data_spo2.time;\r
+            #endif\r
+                        \r
+                if( (ret_value == 0  ) && (data_buf_count_spo2_alg>=25) )\r
+                {   \r
+                       \r
+                #if defined(Optimize_SPO2_flow)\r
+                    //time_accu=time_accu+pxialg_data->time;\r
+                    DEBUG_PRINT("SPO2 Test Time = %d ,count =%d\n",time_accu,count);\r
+                    if(time_accu>=60000)\r
+                    {\r
+                        spo2_array[count]=mySpO2;\r
+                        count=count+1;\r
+                        \r
+                        LOG_PRINT("Over_30_sec_Stop_measurement\n");\r
+                        LOG_PRINT("This_meausrement_suggest_spo2_value is");\r
+                        \r
+                        bubblesort(spo2_array,count);\r
+                        \r
+                        if(count % 2 == 0)\r
+                        {\r
+                              //log_printf(" "LOG_FLOAT_MARKER" \n", LOG_FLOAT(spo2_array[count/2]));\r
+                              LOG_PRINT(" "LOG_FLOAT_MARKER" \n",LOG_FLOAT((spo2_array[(int)(count/2)] + spo2_array[(int)(count/2) - 1]) / 2.0f)); \r
+                        }\r
+                        else\r
+                        {\r
+                              LOG_PRINT(" "LOG_FLOAT_MARKER" \n", LOG_FLOAT(spo2_array[(int)(count/2)]*1.0f));\r
+                        }\r
+                        \r
+                        //log_pah8series_no_touch();\r
+                        spo2_algorithm_disable();\r
+                        pah_sensor_stop();\r
+                        count=0;\r
+                        //add sensor stop here              \r
+                    }\r
+                    else\r
+                    {\r
+                        if(mySpO2>0)\r
+                        {\r
+                           spo2_array[count]=mySpO2;\r
+                           count=count+1;                    \r
+                        }            \r
+                    }\r
+                #endif\r
+                    //report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg, Opt_SpO2, drop_flag, ascend_flag,  mems_fla);\r
+                    report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg, no_value_reason, SignalPeriodicity, time_accu);\r
+                    data_buf_count_spo2_alg = data_buf_count_spo2_alg -25;\r
+                }\r
+                else\r
+                {\r
+                    //report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg,  Opt_SpO2, drop_flag, ascend_flag,  mems_flag);\r
+                    report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg, no_value_reason, SignalPeriodicity, time_accu);\r
+\r
+                    switch (ret_value)\r
+                    {\r
+                        case SPO2_MSG_ALG_NOT_OPEN:\r
+                            DEBUG_PRINT("Algorithm is not initialized. \n");\r
+                        break;\r
+                     \r
+                        case SPO2_MSG_ALG_REOPEN:\r
+                            DEBUG_PRINT("Algorithm is re initialized. \n");\r
+                        break;\r
+                     \r
+                        case SPO2_MSG_ALG_NOT_SUPPORT:\r
+                            DEBUG_PRINT("Algorithm is not support. \n");\r
+                        break;\r
+                    \r
+                        default:\r
+                            // DEBUG_PRINT("Algorithm unhandle error = %d \n", ret_value);\r
+                        break;\r
+                    }\r
+                    //return 1 ;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                report_ppg_data(&ppg_mems_data_alg);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+\r
+// SPO2- ALG-  Task2\r
+void spo2_alg_task2(uint8_t ppg_num)\r
+{\r
+#ifdef PPG_MEMS_Synchronize\r
+    if(Check_alg_enable())\r
+    {\r
+        if(Check_alg_enable()==MSG_ALG_ENABLE)\r
+        {\r
+            spo2_algorithm_enable();\r
+        }else if(Check_alg_enable()==MSG_ALG_DISABLE)\r
+        {\r
+            spo2_algorithm_disable();\r
+        }\r
+        Clear_alg_enable();\r
+    }\r
+  \r
+    if(!isFIFOEmpty())\r
+    {\r
+        for (int k=0; k<ppg_num; k++)\r
+        {\r
+            if(pah_pop(&ppg_mems_data_alg))  //Get data from FIFO\r
+            {\r
+                if(_main.spo2_is_enabled)\r
+                {\r
+                    // 13Bytes format to hr lib;\r
+              \r
+\r
+                    ppg_mems_data_alg.MEMS_Data[0]=mems_int_data_out[3*k];\r
+                    ppg_mems_data_alg.MEMS_Data[1]=mems_int_data_out[3*k+1];\r
+                    ppg_mems_data_alg.MEMS_Data[2]=mems_int_data_out[3*k+2];\r
+          \r
+                    int32_t  RAW_DATA[2]={0}  ;\r
+                    sRaw_Data_13Bytes hr_data;\r
+                 \r
+                    memset(&hr_data, 0, sizeof(hr_data));\r
+                    hr_data.loss = (uint8_t)ppg_mems_data_alg.ppg_data.overflow_num + 1;\r
+                    hr_data.rawData = ppg_mems_data_alg.ppg_data.data[0];\r
+                    hr_data.non_zero1 = 1;\r
+                    hr_data.non_zero2 = 2;\r
+                    hr_data.non_zero3 = 3;\r
+                    hr_data.frame_count = ppg_mems_data_alg.ppg_frame_count;\r
+                    hr_data.time = ppg_mems_data_alg.duration;\r
+                    hr_data.rsv = 0;\r
+                    hr_data.touch = (ppg_mems_data_alg.touch_flag > 0 ? 0x80 : 0x00);\r
+                    hr_data.rsv2 = 0;\r
+          \r
+               \r
+                    int32_t ret = PxiAlg_Process_Expo((uint8_t*)&hr_data, ppg_mems_data_alg.MEMS_Data, ppg_mems_data_alg.ppg_data.exposure_time[0]);\r
+               \r
+\r
+                \r
+\r
+                if(PxiAlg_GetHrUpdateFlag())\r
+                {\r
+                    PxiAlg_HrGet(&myHR);\r
+                    PxiAlg_GetSigGrade(&hr_grader);\r
+                }\r
+          \r
+\r
+                    int32_t spo2_raw_1=ppg_mems_data_alg.ppg_data.data[0];\r
+                    int32_t spo2_raw_2=ppg_mems_data_alg.ppg_data.data[1];\r
+                \r
+                    RAW_DATA[0]=spo2_raw_1;\r
+                    RAW_DATA[1]=spo2_raw_2;\r
+          \r
+                    mems_data_raw[0].data[0]=ppg_mems_data_alg.MEMS_Data[0];\r
+                    mems_data_raw[0].data[1]=ppg_mems_data_alg.MEMS_Data[1] ;\r
+                    mems_data_raw[0].data[2]=ppg_mems_data_alg.MEMS_Data[2];            \r
+          \r
+                    // SPO2 fill data on pah8series structure\r
+                    pxialg_data_spo2.touch_flag         =  ppg_mems_data_alg.touch_flag ;\r
+                    pxialg_data_spo2.time               =  ppg_mems_data_alg.duration ;;\r
+                    pxialg_data_spo2.ppg_data           =  (int32_t*)RAW_DATA;\r
+                    pxialg_data_spo2.nf_ppg_channel     =  2;\r
+                    pxialg_data_spo2.nf_ppg_per_channel =  1;\r
+                    pxialg_data_spo2.frame_count        =  ppg_mems_data_alg.ppg_frame_count ;\r
+                    pxialg_data_spo2.nf_mems            =  1;\r
+                    pxialg_data_spo2.mems_data          = (int16_t*)mems_data_raw;\r
+           \r
+\r
+\r
+                    //DEBUG_PRINT("data_buf_count_spo2_alg = %d \r\n", data_buf_count_spo2_alg);\r
+                    \r
+\r
+                    SpO2_SetHrValue(myHR);\r
+                    SpO2_SetMems(mems_data_raw, 1);\r
+                    //int  ret_value = SpO2_Process(ppg_mems_data_alg.touch_flag , 2, pxialg_data_spo2.ppg_data, 1);\r
+                    int  ret_value = SpO2_Process(ppg_mems_data_alg.touch_flag , 2, pxialg_data_spo2.ppg_data, 1,pxialg_data_spo2.time );\r
+                   \r
+                    SpO2_GetSpO2(&mySpO2);\r
+                    SpO2_GetReadyFlag(&mySPO2_ReadyFlag);\r
+                    SpO2_GetInfo(&_spo2_detect_item);\r
+                    correlation =_spo2_detect_item.Noise;\r
+                    trust_flag  =_spo2_detect_item.Output[3];\r
+                    no_value_reason=_spo2_detect_item.Output[4];\r
+                    SpO2_GetPeriodicity(&SignalPeriodicity);\r
+                    MEMS_RMS    =_spo2_detect_item.RMS;\r
+          \r
+\r
+                    data_buf_count_spo2_alg++;\r
+                \r
+                #if defined(Optimize_SPO2_flow) \r
+                    time_accu=time_accu+pxialg_data_spo2.time;\r
+                #endif\r
+                    \r
+                    if( (ret_value == 0  ) && (data_buf_count_spo2_alg>=25) )\r
+                    {   \r
+                \r
+                        #if defined(Optimize_SPO2_flow)\r
+                        //time_accu=time_accu+pxialg_data->time;\r
+                        DEBUG_PRINT("SPO2 Test Time = %d ,count =%d\n",time_accu,count);\r
+                        if(time_accu>=31000)\r
+                        {\r
+                            spo2_array[count]=mySpO2;\r
+                            count=count+1;\r
+                                    \r
+                            LOG_PRINT("Over_30_sec_Stop_measurement\n");\r
+                            LOG_PRINT("This_meausrement_suggest_spo2_value is");\r
+                        \r
+                            bubblesort(spo2_array,count);\r
+                            \r
+                            if(count % 2 == 0)\r
+                            {\r
+                                //log_printf(" "LOG_FLOAT_MARKER" \n", LOG_FLOAT(spo2_array[count/2]));\r
+                                LOG_PRINT(" "LOG_FLOAT_MARKER" \n",LOG_FLOAT((spo2_array[(int)(count/2)] + spo2_array[(int)(count/2) - 1]) / 2.0f)); \r
+                            }\r
+                            else\r
+                            {\r
+                                LOG_PRINT(" "LOG_FLOAT_MARKER" \n", LOG_FLOAT(spo2_array[(int)(count/2)]*1.0f));\r
+                            }\r
+                            \r
+                            //log_pah8series_no_touch();\r
+                            spo2_algorithm_disable();\r
+                            pah_sensor_stop();\r
+                            count=0;\r
+                            //add sensor stop here              \r
+                        }\r
+                        else\r
+                        {        \r
+                            if(mySpO2>0)\r
+                            {\r
+                               spo2_array[count]=mySpO2;\r
+                               count=count+1;                    \r
+                            }\r
+                        }\r
+                        #endif\r
+                        //report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg, Opt_SpO2, drop_flag, ascend_flag,  mems_fla);\r
+                        report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg, no_value_reason, SignalPeriodicity, time_accu);\r
+                        data_buf_count_spo2_alg = data_buf_count_spo2_alg -25;\r
+                    }\r
+                    else\r
+                    {\r
+                        //report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg,  Opt_SpO2, drop_flag, ascend_flag,  mems_flag);\r
+                        report_spo2_data(&ppg_mems_data_alg, ret, mySpO2, myHR, correlation, trust_flag, MEMS_RMS,data_buf_count_spo2_alg, no_value_reason, SignalPeriodicity, time_accu);\r
+                  \r
+                        switch (ret_value)\r
+                        {\r
+                            case SPO2_MSG_ALG_NOT_OPEN:\r
+                                  DEBUG_PRINT("Algorithm is not initialized. \n");\r
+                            break;\r
+                           \r
+                            case SPO2_MSG_ALG_REOPEN:\r
+                                  DEBUG_PRINT("Algorithm is re initialized. \n");\r
+                            break;\r
+                           \r
+                            case SPO2_MSG_ALG_NOT_SUPPORT:\r
+                                  DEBUG_PRINT("Algorithm is not support. \n");\r
+                            break;\r
+                          \r
+                            default:\r
+                                DEBUG_PRINT("Algorithm unhandle error = %d \n", ret_value);\r
+                            break;\r
+                        }\r
+                        //return 1 ;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    report_ppg_data(&ppg_mems_data_alg);\r
+                }\r
+            }\r
+        }\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+\r
+// Stress\r
+void stress_algorithm_enable(void)\r
+{\r
+    int buffer_size = 0;\r
+    if (_main.stress_is_enable)\r
+    {\r
+    return;\r
+    }\r
+\r
+    LOG_PRINT("HRVGetVersion() = %d \n", HRVGetVersion());\r
+    buffer_size = HRVGetMemorySize(HRV_ENABLE_LHR, HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+    LOG_PRINT("HRVGetMemorySize(), open_size = %d \n", buffer_size);\r
+\r
+    if (!buffer_size)\r
+    {\r
+        LOG_PRINT("HRVGetMemorySize(), failed to get memory size \n");\r
+        return ;\r
+    }\r
+\r
+    stress_pBuffer = (uint8_t*)malloc(buffer_size);\r
+    if (!stress_pBuffer)\r
+    {\r
+        LOG_PRINT("Out of memory \n");\r
+        return ;\r
+    }\r
+\r
+    if (!HRVOpen(stress_pBuffer))\r
+    {\r
+        LOG_PRINT("HRVOpen() failed. \n");\r
+        return ;\r
+    }\r
+    duration_total=0;\r
+    _hrv_state.collect_duration = 0;\r
+ \r
+    _main.stress_is_enable = true;\r
+}\r
+\r
+void stress_algorithm_disable(void)\r
+{\r
+    if (!_main.stress_is_enable)\r
+        return;\r
+    HRVClose();\r
+    free(stress_pBuffer);\r
+    \r
+    duration_total            = 0;\r
+    SDNN_ReadyFlag            = 0;\r
+    Get_Stress                = 0;\r
+    Stress                    = 0.0f;\r
+    HRAvg                     = 0;\r
+    SQ_Stress                 = 0.0f;\r
+    AnomalyFlag               = 0;\r
+    Stress_ReadyFlag          = 0;\r
+    Weak_Flag                 = 0;                \r
+    _main.stress_is_enable    = false;\r
+}\r
+\r
+void stress_alg_task(int grade)\r
+{\r
+    if(Check_alg_enable())\r
+    {\r
+        if(Check_alg_enable()==MSG_ALG_ENABLE)\r
+        {\r
+            stress_algorithm_enable();\r
+        }else if(Check_alg_enable()==MSG_ALG_DISABLE)\r
+        {\r
+            stress_algorithm_disable();\r
+        }\r
+        Clear_alg_enable();\r
+    }\r
+\r
+    if(!isFIFOEmpty())\r
+    {\r
+        if(pah_pop(&ppg_mems_data_alg))    //Get data from FIFO\r
+        {\r
+            if(_main.stress_is_enable)\r
+            {\r
+                uint32_t raw_data = ppg_mems_data_alg.ppg_data.data[1];\r
+                uint8_t frame_count = ppg_mems_data_alg.ppg_frame_count;\r
+                uint8_t timeInterval = ppg_mems_data_alg.duration;\r
+                uint8_t touch_flag = ppg_mems_data_alg.touch_flag;\r
+\r
+                // If using Interrupt mode call this API\r
+                HRVSetDiffTime(timeInterval,1);\r
+  \r
+                HRVProcess(touch_flag, raw_data);\r
+\r
+                duration_total+=timeInterval;\r
+              \r
+              \r
+                if(Stress_ReadyFlag==0)\r
+                {\r
+                    Stress_ReadyFlag=HRVGetReadyFlag();\r
+                }\r
+            \r
+                if((duration_total>25000)&& Stress_ReadyFlag==0)\r
+                {\r
+                    LOG_PRINT("PPG Raw data is too Weak\r\n");\r
+                    LOG_PRINT("TEST Stop\r\n");\r
+                    stress_algorithm_disable();\r
+                    Weak_Flag=1;\r
+                    return  ;\r
+                }    \r
+                \r
+                if(Stress_ReadyFlag  == 1 || HRVGetReadyFlag())\r
+                {\r
+                    Stress_ReadyFlag=1;\r
+                    _hrv_state.collect_duration += timeInterval;\r
+  \r
+                    if(_hrv_state.collect_duration > (HRV_COLLECTION_SECONDS * 1000))\r
+                    {\r
+                        //int grade=100;\r
+                        HRAvg = HRVGetHRAvg();  \r
+                        Stress= HRVGetStress(grade);                                        \r
+                        SQ_Stress=HRVGetRRIQuality();                                        \r
+                        AnomalyFlag= HRVGetAnomalyFlag();\r
+                        LOG_PRINT("HRAvg = %d  Stress = %f  HRV_Quality = %f  AnomalyFlag= %d \n", HRAvg ,Stress,SQ_Stress,AnomalyFlag);\r
+\r
+                        if(SQ_Stress>0.4f)\r
+                        {\r
+                            LOG_PRINT("HRV_Quality Good\n");\r
+                        }\r
+                        else\r
+                        {\r
+                            LOG_PRINT("HRV_Quality Weak\n");\r
+                        }\r
+                        \r
+                        \r
+                        if(Stress >=80 &&  Stress<=100)\r
+                        {\r
+                            LOG_PRINT("Stress_Level High\n");\r
+                        }\r
+                        else if(Stress >=60 &&  Stress<80)\r
+                        {\r
+                            LOG_PRINT("Stress_Level Medium\n");\r
+                        }\r
+                        else if(Stress >=30 &&  Stress<60)\r
+                        {\r
+                            LOG_PRINT("Stress_Level Normal\n");\r
+                        }\r
+                        else\r
+                        {\r
+                            LOG_PRINT("Stress_Level Relaxed\n");\r
+                        }                                    \r
+        \r
+                        stress_algorithm_disable();\r
+                        _hrv_state.has_got_sdnn = 1;\r
+                        Get_Stress=1;\r
+                        return ;\r
+                    }\r
+                }    \r
+                report_stress_data(&ppg_mems_data_alg,Stress_ReadyFlag, duration_total, _hrv_state.collect_duration );\r
+            }\r
+            else\r
+            {\r
+                report_ppg_data(&ppg_mems_data_alg);\r
+                LOG_PRINT("Stress_Level Normal\n");\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static bool sensor_basic_verification(void)\r
+{\r
+    uint16_t product_id = 0;\r
+    pah_800x_get_product_id(&product_id);\r
+    if (product_id != PAH_800x_PRODUCT_ID)\r
+    {\r
+        pah_800x_power_toggle(&_main.pah_800x, true);\r
+        pah_800x_get_product_id( &product_id);\r
+    }\r
+\r
+    DEBUG_PRINT("product_id = 0x%04X\n", product_id);\r
+    if (product_id != PAH_800x_PRODUCT_ID)\r
+    {\r
+        DEBUG_PRINT("Failed to verify product_id\n");\r
+        return false;\r
+    }\r
+    \r
+    return true;\r
+}\r
+\r
+static void process(uint64_t timestamp)\r
+{\r
+    float mems_data[3] = { 0.0f, 0.0f, 0.0f };\r
+\r
+    // Task\r
+    pah_ret ret = pah_800x_task(&_main.pah_800x);\r
+    if (PAH_FAILED(ret))\r
+    {\r
+        DEBUG_PRINT("pah_800x_task() failed, ret = %d\n", ret);\r
+        return;\r
+    }\r
+\r
+    int8_t touch_flag = -1;\r
+    pah_800x_get_touch_flag(&_main.pah_800x, &touch_flag);\r
+\r
+    // PRINT("touch_flag : %d\n",touch_flag);\r
+\r
+    if (_main.ppg_is_enabled)\r
+    {\r
+        pah_800x_ppg_data ppg_data;\r
+        pah_800x_ppg_get_data(&_main.pah_800x, &ppg_data);\r
+\r
+        if (ppg_data.has_data)\r
+        {\r
+            // LOG_PRINT("ppg data %d %d %d %d %d %d %d %d\n",ppg_data.has_data,ppg_data.overflow_num,ppg_data.data[0],ppg_data.data[1],ppg_data.data[2],\r
+            // ppg_data.exposure_time[0],ppg_data.exposure_time[1],ppg_data.exposure_time[2]);\r
+            // LOG_PRINT("ppg data %d %d %d %d %d %d\n",ppg_data.frame_period[0],ppg_data.frame_period[1],ppg_data.frame_period[2]\r
+            // ,ppg_data.adc[0],ppg_data.adc[1],ppg_data.adc[2]);\r
+\r
+            // PRINT("ppg data : %d %d %d\n",ppg_data.data[0],ppg_data.data[1],ppg_data.data[2]);\r
+\r
+            factory_data = ppg_data.data[0];\r
+\r
+            uint64_t duration = timestamp - _main.ppg_prev_report_timestamp;\r
+\r
+            if (!_main.ppg_has_prev_report_timestamp)\r
+            {\r
+                _main.ppg_has_prev_report_timestamp = true;\r
+                duration = 50;\r
+            }\r
+            _main.ppg_prev_report_timestamp = timestamp;\r
+\r
+            if (duration > UINT8_MAX)\r
+            {\r
+                // DEBUG_PRINT("duration > UINT8_MAX !!!:%llu\n",duration);\r
+                PRINT("duration > UINT8_MAX !!!:%llu\n",duration);\r
+                return;\r
+            }\r
+            \r
+            ppg_mems_data_t ppg_mems_data;\r
+\r
+            /***********************G sensor explanation start***********************************/\r
+            //If no G sensor, please set ppg_mems_data.MEMS_Data[3] = {0};\r
+            //Please set G sensor default range = ±2G.\r
+            //If G sensor output data format is not 16bit, please change to 16bit format.\r
+            //For example: G sensor is 12bit\r
+            //ReadGSensor(&mems_data[0],&mems_data[1],&mems_data[2])\r
+            //MEMS_SensorX() absolute data must be largest when let hand down at static state.\r
+            //MEMS_SensorZ() absolute data must be largest when let hand horizontal on the table at static state.\r
+            /***********************G sensor explanation end***********************************/\r
+\r
+            ppg_mems_data.MEMS_Data[0] = mems_data[0];//ReadGSensorX();\r
+            ppg_mems_data.MEMS_Data[1] = mems_data[1];//ReadGSensorY();\r
+            ppg_mems_data.MEMS_Data[2] = mems_data[2];//ReadGSensorZ();\r
+            ppg_mems_data.duration = duration;\r
+            \r
+            ppg_mems_data.ppg_data = ppg_data ;\r
+            ppg_mems_data.touch_flag = touch_flag ;\r
+            ppg_mems_data.ppg_frame_count = _main.ppg_frame_count;    //SD-revise-20200320\r
+                                        \r
+            pah_push(&ppg_mems_data);\r
+\r
+#ifdef PPG_MEMS_Synchronize          \r
+            time_temp+=duration;\r
+            mems_data_polling_ready=0;\r
+            if(time_temp>=Time_Interval)\r
+            {\r
+              mems_data_polling_ready=1;\r
+              time_temp =0;\r
+            }\r
+            ppg_data_num++;\r
+#endif            \r
+            ++_main.ppg_frame_count;\r
+            \r
+            //report_ppg_data(&ppg_mems_data);\r
+\r
+        }\r
+    }\r
+    \r
+    if (_main.is_Auto_mode || _main.touch_is_enabled)//SD-reivse-20191205\r
+    {\r
+        if ( _main.touch_last_is_touched != touch_flag)\r
+        {\r
+            _main.touch_last_is_touched = touch_flag;   \r
+                \r
+            report_touch_data(timestamp, &touch_flag);\r
+                \r
+            bool is_touched = (touch_flag >= 1);\r
+\r
+            if (_main.is_Auto_mode && is_touched)//SD-revise-20191205\r
+            {             \r
+                //touch_sensor_disable(); \r
+                ppg_sensor_enable();\r
+                _main.alg_is_enabled = MSG_ALG_ENABLE;\r
+            }\r
+            else if (_main.is_Auto_mode && !is_touched)\r
+            {\r
+                ppg_sensor_disable();  \r
+                pah_800x_update_touch_setting(&_main.pah_800x);\r
+                //touch_sensor_enable();\r
+                _main.alg_is_enabled = MSG_ALG_DISABLE;  \r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+static void ppg_sensor_enable(void)\r
+{\r
+    if (_main.ppg_is_enabled)\r
+        return;\r
+    \r
+    pah_800x_ppg_toggle(&_main.pah_800x, true);\r
+\r
+    _main.debug_print_header = true;\r
+    _main.ppg_has_prev_report_timestamp = false;\r
+    _main.ppg_prev_report_timestamp = pah_get_tick_count();\r
+    _main.ppg_frame_count = 0;\r
+    \r
+    _main.ppg_is_enabled = true;\r
+    \r
+    _read_index = 0 ;\r
+    _write_index = 0 ;\r
+#ifdef PPG_MEMS_Synchronize\r
+    ppg_data_num = 0 ;\r
+#endif    \r
+    //LOG_PRINT("ppg_sensor_enable\n");\r
+}\r
+\r
+static void ppg_sensor_disable(void)\r
+{\r
+    if (!_main.ppg_is_enabled)\r
+        return;\r
+    \r
+    pah_800x_ppg_toggle(&_main.pah_800x, false);\r
+\r
+    _main.ppg_is_enabled = false;\r
+}\r
+\r
+static void touch_sensor_enable(void)\r
+{\r
+    if (_main.touch_is_enabled)\r
+        return;\r
+    \r
+    pah_800x_touch_toggle(&_main.pah_800x, true);\r
+\r
+    _main.touch_last_is_touched = 0;//default no touch => touch mode\r
+    \r
+    _main.touch_is_enabled = true;\r
+}\r
+\r
+static void touch_sensor_disable(void)\r
+{\r
+    if (!_main.touch_is_enabled)\r
+        return;\r
+    \r
+    pah_800x_touch_toggle(&_main.pah_800x, false);\r
+\r
+    _main.touch_is_enabled = false;\r
+}\r
+\r
+static void report_touch_data(uint64_t timestamp, const int8_t *touch_flag)\r
+{\r
+    LOG_PRINT("TOUCH: time = { %llu }, touch_flag = { %d } \n", timestamp, *touch_flag );\r
+}\r
+\r
+static void report_ppg_data(const ppg_mems_data_t *ppg_mems_data_alg)\r
+{\r
+    if (_main.debug_print_header == true)\r
+    {\r
+        LOG_PRINT("Frame, Time, Touch_Flag, Data_Ready, Overflow_Flag, Overflow_Num, ppg0, ppg1, ppg2, Expo_A, Expo_B, Expo_C, MEMS_X, MEMS_Y, MEMS_Z\n");\r
+        _main.debug_print_header = false;\r
+    }\r
+\r
+    LOG_PRINT("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",\r
+                ppg_mems_data_alg->ppg_frame_count, ppg_mems_data_alg->duration, ppg_mems_data_alg->touch_flag,\r
+                ppg_mems_data_alg->ppg_data.has_data, ppg_mems_data_alg->ppg_data.has_overflow, ppg_mems_data_alg->ppg_data.overflow_num,\r
+                ppg_mems_data_alg->ppg_data.data[0], ppg_mems_data_alg->ppg_data.data[1], ppg_mems_data_alg->ppg_data.data[2],\r
+                ppg_mems_data_alg->ppg_data.exposure_time[0], ppg_mems_data_alg->ppg_data.exposure_time[1], ppg_mems_data_alg->ppg_data.exposure_time[2],\r
+                (int)(ppg_mems_data_alg->MEMS_Data[0]), (int)(ppg_mems_data_alg->MEMS_Data[1]), (int)(ppg_mems_data_alg->MEMS_Data[2]));\r
+}\r
+\r
+static void report_hr_data(const ppg_mems_data_t *ppg_mems_data_alg, int32_t ret, float hr, float hr_grader)\r
+{\r
+    if (_main.debug_print_header == true)\r
+    {\r
+        LOG_PRINT("Frame, Time, Touch_Flag, Data_Ready, Overflow_Flag, Overflow_Num, PPG0, PPG1, PPG2, Expo_A, Expo_B, Expo_C, MEMS_X, MEMS_Y, MEMS_Z, ret, hr, hr_grade\n");\r
+\r
+        _main.debug_print_header = false;\r
+    }\r
+  \r
+    LOG_PRINT("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %f, %f\n",\r
+                ppg_mems_data_alg->ppg_frame_count, ppg_mems_data_alg->duration, ppg_mems_data_alg->touch_flag,\r
+                ppg_mems_data_alg->ppg_data.has_data, ppg_mems_data_alg->ppg_data.has_overflow, ppg_mems_data_alg->ppg_data.overflow_num,\r
+                ppg_mems_data_alg->ppg_data.data[0], ppg_mems_data_alg->ppg_data.data[1], ppg_mems_data_alg->ppg_data.data[2],\r
+                ppg_mems_data_alg->ppg_data.exposure_time[0], ppg_mems_data_alg->ppg_data.exposure_time[1], ppg_mems_data_alg->ppg_data.exposure_time[2],\r
+                (int)(ppg_mems_data_alg->MEMS_Data[0]), (int)(ppg_mems_data_alg->MEMS_Data[1]), (int)(ppg_mems_data_alg->MEMS_Data[2]), ret, hr,  hr_grader);\r
+\r
+}\r
+\r
+//static void report_spo2_data(const ppg_mems_data_t *ppg_mems_data_alg, int32_t ret, float mySpO2,  float myHR, float correlation, float trust_flag, float MEMS_RMS, int data_buf_count_spo2_alg, , float Opt_SpO2,  int drop_flag,  int ascend_flag,  int mems_flag)\r
+static void report_spo2_data(const ppg_mems_data_t *ppg_mems_data_alg, int32_t ret, float myHR, float mySpO2,  float correlation, float trust_flag, float MEMS_RMS, int data_buf_count_spo2_alg, uint8_t no_value_reason,  float   SignalPeriodicity,  int     time_accu )\r
+{\r
+    if (_main.debug_print_header == true)\r
+    {\r
+        \r
+         LOG_PRINT("Frame, Time, Touch_Flag, Data_Ready, Overflow_Flag, Overflow_Num, PPG0, PPG1, PPG2, Expo_A, Expo_B, Expo_C, MEMS_X, MEMS_Y, MEMS_Z, ret, spo2, myHR, hr_grader, correlation, MEMS_RMS, trust, no_value_reason, SignalPeriodicity, time_accu \n");       \r
+        _main.debug_print_header = false;\r
+    }\r
+\r
+  if(data_buf_count_spo2_alg>=25)\r
+    {\r
+                LOG_PRINT("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %f, %f, %f, %f, %f, %f, %d, %f, %d\n",\r
+                ppg_mems_data_alg->ppg_frame_count, ppg_mems_data_alg->duration, ppg_mems_data_alg->touch_flag,\r
+                ppg_mems_data_alg->ppg_data.has_data, ppg_mems_data_alg->ppg_data.has_overflow, ppg_mems_data_alg->ppg_data.overflow_num,\r
+                ppg_mems_data_alg->ppg_data.data[0], ppg_mems_data_alg->ppg_data.data[1], ppg_mems_data_alg->ppg_data.data[2],\r
+                ppg_mems_data_alg->ppg_data.exposure_time[0], ppg_mems_data_alg->ppg_data.exposure_time[1], ppg_mems_data_alg->ppg_data.exposure_time[2],\r
+                (int)(ppg_mems_data_alg->MEMS_Data[0]), (int)(ppg_mems_data_alg->MEMS_Data[1]), (int)(ppg_mems_data_alg->MEMS_Data[2]), ret, mySpO2,myHR,hr_grader,correlation, MEMS_RMS,trust_flag,no_value_reason,SignalPeriodicity, time_accu);\r
+    }\r
+    else\r
+    {\r
+                LOG_PRINT("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",\r
+                ppg_mems_data_alg->ppg_frame_count, ppg_mems_data_alg->duration, ppg_mems_data_alg->touch_flag,\r
+                ppg_mems_data_alg->ppg_data.has_data, ppg_mems_data_alg->ppg_data.has_overflow, ppg_mems_data_alg->ppg_data.overflow_num,\r
+                ppg_mems_data_alg->ppg_data.data[0], ppg_mems_data_alg->ppg_data.data[1], ppg_mems_data_alg->ppg_data.data[2],\r
+                ppg_mems_data_alg->ppg_data.exposure_time[0], ppg_mems_data_alg->ppg_data.exposure_time[1], ppg_mems_data_alg->ppg_data.exposure_time[2],\r
+                (int)(ppg_mems_data_alg->MEMS_Data[0]), (int)(ppg_mems_data_alg->MEMS_Data[1]), (int)(ppg_mems_data_alg->MEMS_Data[2]), ret);\r
+\r
+        \r
+    }\r
+}\r
+\r
+\r
+static void report_stress_data(const ppg_mems_data_t *ppg_mems_data_alg, uint8_t Stress_ReadyFlag, uint32_t measuretime, float collect_time)\r
+{\r
+    if (_main.debug_print_header == true)\r
+    {\r
+        LOG_PRINT("Frame, Time, Touch_Flag, Data_Ready, Overflow_Flag, Overflow_Num, PPG0, PPG1, PPG2, Expo_A, Expo_B, Expo_C, MEMS_X, MEMS_Y, MEMS_Z, Stress_Ready, measure_time, collect_time\n");\r
+\r
+        _main.debug_print_header = false;\r
+    }\r
+  \r
+    LOG_PRINT("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %f\n",\r
+                ppg_mems_data_alg->ppg_frame_count, ppg_mems_data_alg->duration, ppg_mems_data_alg->touch_flag,\r
+                ppg_mems_data_alg->ppg_data.has_data, ppg_mems_data_alg->ppg_data.has_overflow, ppg_mems_data_alg->ppg_data.overflow_num,\r
+                ppg_mems_data_alg->ppg_data.data[0], ppg_mems_data_alg->ppg_data.data[1], ppg_mems_data_alg->ppg_data.data[2],\r
+                ppg_mems_data_alg->ppg_data.exposure_time[0], ppg_mems_data_alg->ppg_data.exposure_time[1], ppg_mems_data_alg->ppg_data.exposure_time[2],\r
+                (int)(ppg_mems_data_alg->MEMS_Data[0]), (int)(ppg_mems_data_alg->MEMS_Data[1]), (int)(ppg_mems_data_alg->MEMS_Data[2]), Stress_ReadyFlag,duration_total, _hrv_state.collect_duration  );\r
+\r
+}\r
+#ifdef PPG_MEMS_Synchronize \r
+uint8_t  get_ppg_data_num(void)\r
+{\r
+    return ppg_data_num;\r
+}\r
+void  clear_ppg_data_num(void)\r
+{\r
+    ppg_data_num = 0;\r
+}\r
+\r
+void mems_interpolation(int16_t *mems_int_data_in,uint8_t mems_num,uint8_t ppg_num)\r
+{\r
+  \r
+    // Customer Define MEMS-input X, Y, Z\r
+    // Put data in mems_int_data_in ,and mems_count\r
+    // Then call the PXI_MEMS_interp to do interpolation \r
+    \r
+    PXI_MEMS_interp(mems_int_data_in, mems_num, mems_int_data_out, ppg_num);\r
+  \r
+}\r
+#endif\r
+\r
+static void error_handle(void)\r
+{\r
+    while (true)\r
+    {\r
+    }\r
+}\r
+\r
+uint16_t pah8009_get_chip_id(void)\r
+{\r
+    uint16_t product_id = 0;\r
+    pah_800x_get_product_id(&product_id);\r
+    return product_id;\r
+}\r
+\r
+uint32_t pah8009_get_factory_data(void)\r
+{\r
+    uint32_t data = factory_data;\r
+    factory_data = 0;\r
+    return data;\r
+}\r
+\r
+void pah8009_int_handler(void)\r
+{\r
+    ppg_interrupt_handle();\r
+    ppg_sensor_task_interrupt();\r
+    \r
+    if(work_mode == 1)\r
+    {\r
+        // PRINT("hr_alg_task \n");\r
+        hr_alg_task();\r
+    }    \r
+    else if(work_mode == 2)\r
+    {\r
+        // PRINT("spo2_alg_task \n");\r
+        spo2_alg_task();\r
+    }\r
+\r
+}\r
+\r
+void pah8009_timer_handler(void)\r
+{\r
+    ppg_sensor_task_polling();\r
+    \r
+    if(work_mode == 1)\r
+    {\r
+        // PRINT("hr_alg_task \n");\r
+        hr_alg_task();\r
+    }    \r
+    else if(work_mode == 2)\r
+    {\r
+        // PRINT("spo2_alg_task \n");\r
+        spo2_alg_task();\r
+    }\r
+\r
+}\r
+\r
+static void pah8009_timer_callback(void)\r
+{\r
+#ifdef SUPPORT_PPG_SERVICE\r
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_PPG_HRS_TIMER_CALLBACK);\r
+#endif\r
+}\r
+\r
+static void pah8009_timer_init(void)\r
+{\r
+    if(g_pah8009_timer == NULL)\r
+        g_pah8009_timer = osTimerNew((osTimerFunc_t)pah8009_timer_callback, osTimerPeriodic, NULL, NULL);\r
+}\r
+\r
+\r
+void pah8009_control(char *mode,uint8_t enable)\r
+{\r
+    // printf("mode : %s ,enable : %d\n",mode,enable);\r
+    if(!enable)\r
+    {\r
+#ifdef POLLING_MODE\r
+        if(g_pah8009_timer != NULL)\r
+            osTimerStop(g_pah8009_timer);\r
+#endif\r
+        pah_sensor_stop();\r
+    }\r
+    else\r
+    {\r
+#ifdef POLLING_MODE\r
+        pah8009_timer_init();\r
+#endif\r
+        if (strcmp(mode, "hrs") == 0) {\r
+            pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            auto_mode_sensor_start();\r
+            work_mode = 1;\r
+            // touch_only_sensor_start();\r
+            // ppg_only_sensor_start();\r
+        } else if (strcmp(mode, "hrv") == 0) {\r
+            // md = HRV_MODE;\r
+        } else if (strcmp(mode, "spo2") == 0) {\r
+            // md = SPO2_MODE;\r
+            pah_sensor_init(diw_4mm_ir_r_ir_spo2);\r
+            auto_mode_sensor_start();\r
+            work_mode = 2;\r
+        } else if (strcmp(mode, "leaklight") == 0) {\r
+            // md = FT_LEAK_LIGHT_MODE;\r
+            factory_test_mode(factory_test_leak_light_target_sample, 0, 0, 0, 0);\r
+        } else if (strcmp(mode, "wear") == 0) {\r
+            pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            touch_only_sensor_start();\r
+        }\r
+#ifdef POLLING_MODE\r
+        if(g_pah8009_timer != NULL)\r
+            osTimerStart(g_pah8009_timer,40);\r
+#endif\r
+    }\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.h b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.h
new file mode 100644 (file)
index 0000000..2e51b95
--- /dev/null
@@ -0,0 +1,192 @@
+#ifndef __pah_800x_main_h__\r
+#define __pah_800x_main_h__\r
+\r
+// pah\r
+#include "pah_800x.h"\r
+#include "pah_unit.h"\r
+#include "pah_800x_config.h"\r
+\r
+\r
+\r
+//static hr algotirhm\r
+// #include "pxialg.h"\r
+\r
+// spo2 algorithm\r
+// #include "pxialg_spo2.h"\r
+\r
+// Stress algorithm\r
+// #include "pxialg_hrv.h"\r
+#ifdef PPG_MEMS_Synchronize\r
+//MEMS-INT\r
+#include "pxi_interp.h"\r
+#endif\r
+//============================================================================\r
+// Functions\r
+//============================================================================\r
+#ifdef __cplusplus\r
+extern  "C" {\r
+#endif \r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+#ifdef PPG_MEMS_Synchronize\r
+#define FIFO_SIZE 50  //FIFO Size is dependent on the CPU performance\r
+#else\r
+#define FIFO_SIZE 8  //FIFO Size is dependent on the CPU performance\r
+#endif\r
+\r
+//============================================================================\r
+// Type Definition\r
+//============================================================================\r
+#pragma pack(1)\r
+typedef struct raw_data_13bytes_t\r
+{\r
+    uint8_t loss;\r
+    uint32_t rawData;\r
+    uint8_t non_zero1;\r
+    uint8_t non_zero2;\r
+    uint8_t non_zero3;\r
+    uint8_t frame_count;\r
+    uint8_t time;\r
+    uint8_t rsv;\r
+    uint8_t touch;\r
+    uint8_t rsv2;\r
+} sRaw_Data_13Bytes;\r
+\r
+typedef enum {\r
+    MSG_ALG_NOCHANGE = 0,\r
+    MSG_ALG_ENABLE,\r
+    MSG_ALG_DISABLE,\r
+} alg_msg_code_t;\r
+#pragma pack()\r
+\r
+typedef enum\r
+{\r
+    pc_4mm_2g_ir_hrd,           // PC 4.25mm for HRD          wear\r
+    diw_4mm_g_ir_hrd,           // DI+WALL 4.25mm for HRD     hrs\r
+    diw_4mm_ir_r_ir_spo2,       // DI+WALL 4.25mm for SPO2    spo2\r
+    pc_22mm_2g_ir_hrd,          // PC 2.2mm for HRD\r
+    di_18mm_g_g_hrd,            // DI 1.8mm for HRD\r
+\r
+} reg_config_type;\r
+\r
+typedef struct {\r
+    \r
+    volatile bool       has_interrupt;\r
+    volatile uint64_t   interrupt_timestamp;\r
+    \r
+    // pah\r
+    pah_800x            pah_800x;\r
+    \r
+    bool                is_Auto_mode;\r
+    // ppg\r
+    bool                ppg_is_enabled;\r
+    //bool                ppg_only_is_enabled;\r
+    bool                ppg_has_prev_report_timestamp;\r
+    uint64_t            ppg_prev_report_timestamp;\r
+    uint8_t             ppg_frame_count;\r
+\r
+    // touch\r
+    bool                touch_is_enabled;\r
+    //bool                touch_only_is_enabled;\r
+    int                 touch_last_is_touched;\r
+    \r
+    // alg\r
+    uint8_t             alg_is_enabled;\r
+    bool                hr_is_enabled;\r
+    bool                spo2_is_enabled;\r
+    bool                stress_is_enable;\r
+    // debug\r
+    bool                debug_print_header;\r
+    uint8_t             debug_frame_count;\r
+    \r
+} main_state;\r
+\r
+typedef struct {    \r
+    float                 MEMS_Data[3] ;\r
+    pah_800x_ppg_data     ppg_data;\r
+    uint8_t               touch_flag;\r
+    uint8_t               duration;\r
+    uint8_t               ppg_frame_count;\r
+    //pah_800x_touch_data touch_data;\r
+} ppg_mems_data_t;\r
+\r
+\r
+\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+void pah_sensor_init(reg_config_type type);\r
+void touch_only_sensor_start(void);\r
+void ppg_only_sensor_start(void);\r
+void auto_mode_sensor_start(void);\r
+void pah_sensor_stop(void);\r
+void ppg_interrupt_handle(void);\r
+void ppg_sensor_task_interrupt(void);\r
+void ppg_sensor_task_polling(void);\r
+\r
+\r
+bool isFIFOEmpty(void);\r
+bool pah_push(ppg_mems_data_t *data);\r
+bool pah_pop(ppg_mems_data_t *data);\r
+\r
+\r
+uint8_t Check_alg_enable(void);\r
+void Clear_alg_enable(void);\r
+\r
+//HRD\r
+void hr_algorithm_enable(void);\r
+void hr_algorithm_disable(void);\r
+void hr_alg_task(void);\r
+void hr_alg_task2(uint8_t ppg_num);\r
+\r
+//SPO2\r
+void spo2_algorithm_enable(void);\r
+void spo2_algorithm_disable(void);\r
+void spo2_alg_task(void);\r
+void spo2_alg_task2(uint8_t ppg_num);\r
+\r
+//Stress\r
+void stress_algorithm_enable(void);\r
+void stress_algorithm_disable(void);\r
+//void stress_alg_task(void);\r
+void stress_alg_task(int grade);\r
+\r
+uint16_t pah8009_get_chip_id(void);\r
+void pah8009_control(char *mode,uint8_t enable);\r
+uint32_t pah8009_get_factory_data(void);\r
+void pah8009_int_handler(void);\r
+\r
+/**\r
+ * @brief Macro to be used in a formatted string to a pass float number to the log.\r
+ *\r
+ * Macro should be used in formatted string instead of the %f specifier together with\r
+ * @ref LOG_FLOAT macro.\r
+ * Example: LOG_INFO("My float number" LOG_FLOAT_MARKER "\r\n", LOG_FLOAT(f)))\r
+ */\r
+#define LOG_FLOAT_MARKER "%c%d.%05d"\r
+\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+#define LOG_FLOAT(val) ((val >= 0.0f)?32:45),(int32_t)((val >= 0.0f)?val:val*-1) , (int32_t)(((val > 0) ? (val) - (int32_t)(val): (int32_t)(val) - (val))*100000)                       \r
+\r
+\r
+\r
+#ifdef PPG_MEMS_Synchronize\r
+//MEMS  Interpolation\r
+//void mems_interpolation(uint8_t ppg_num);\r
+void mems_interpolation(int16_t *mems_int_data_in,uint8_t mems_count,uint8_t ppg_num);\r
+uint8_t  get_ppg_data_num(void);\r
+void  clear_ppg_data_num(void);\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_8009_reg_arr_default_20220623.h b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_8009_reg_arr_default_20220623.h
new file mode 100644 (file)
index 0000000..abf28f2
--- /dev/null
@@ -0,0 +1,484 @@
+#ifndef __pah_8009_reg_arr_default_h__\r
+#define __pah_8009_reg_arr_default_h__\r
+\r
+// c\r
+#include <stdint.h>\r
+\r
+//pah\r
+#include "pah_800x_config.h"\r
+\r
+\r
+static const uint8_t PAH8009_REG_DEVICE_INIT[][2] = {\r
+//  { 0xEE,0x07 }, //SW RESET\r
+    { 0xD1,0xD0 },//{R_GPIO_0_IEB, R_GPIO_1_IEB, R_GPIO_0_OEB, R_GPIO_1_OEB, R_GPIO_0_PULLL_EnH, R_GPIO_1_PULLL_EnH, R_GPIO_0_PULLH_EnH, R_GPIO_1_PULLH_EnH};\r
+       { 0xD2,0x00+R_GPIO_SLEW+R_GPIO_0_OD_EnH },//R_GPIO_0_Open_Drain_EnH(0xD2[5]), 1(0x20):GPIO default open-drain mode, 0(0x00):GPIO debug mode\r
+    { 0xD3,0x20 },//GPIO debug select\r
+    { 0xD6,0x00+R_I2C_SLEW },//{Dummy, R_I2C_SLEW, Dummy[5:0]}\r
+#if (INT_OD_EXTERNAL_PULLH)\r
+    { 0xD1,0xD0 },//{R_GPIO_0_IEB, R_GPIO_1_IEB, R_GPIO_0_OEB, R_GPIO_1_OEB, R_GPIO_0_PULLL_EnH, R_GPIO_1_PULLL_EnH, R_GPIO_0_PULLH_EnH, R_GPIO_1_PULLH_EnH};\r
+       { 0xD2,0x20+R_GPIO_SLEW },//R_GPIO_0_Open_Drain_EnH(0xD2[5]), 1(0x20):GPIO default open-drain mode, 0(0x00):GPIO debug mode\r
+    { 0xD3,0x00 },//GPIO debug select\r
+    { 0xD6,0x00+R_I2C_SLEW },//{Dummy, R_I2C_SLEW, Dummy[5:0]}\r
+#endif\r
+#if (INT_OD_INTERNAL_PULLH)\r
+    { 0xD1,0xD2 },//{R_GPIO_0_IEB, R_GPIO_1_IEB, R_GPIO_0_OEB, R_GPIO_1_OEB, R_GPIO_0_PULLL_EnH, R_GPIO_1_PULLL_EnH, R_GPIO_0_PULLH_EnH, R_GPIO_1_PULLH_EnH};\r
+       { 0xD2,0x20+R_GPIO_SLEW },//R_GPIO_0_Open_Drain_EnH(0xD2[5]), 1(0x20):GPIO default open-drain mode, 0(0x00):GPIO debug mode\r
+    { 0xD3,0x00 },//GPIO debug select\r
+    { 0xD6,0x00+R_I2C_SLEW },//{Dummy, R_I2C_SLEW, Dummy[5:0]}\r
+#endif\r
+#if (INT_PUP_WITHOUT_PULLH)\r
+    { 0xD1,0xD0 },//{R_GPIO_0_IEB, R_GPIO_1_IEB, R_GPIO_0_OEB, R_GPIO_1_OEB, R_GPIO_0_PULLL_EnH, R_GPIO_1_PULLL_EnH, R_GPIO_0_PULLH_EnH, R_GPIO_1_PULLH_EnH};\r
+       { 0xD2,0x00+R_GPIO_SLEW },//R_GPIO_0_Open_Drain_EnH(0xD2[5]), 1(0x20):GPIO default open-drain mode, 0(0x00):GPIO debug mode\r
+    { 0xD3,0x00 },//GPIO debug select\r
+       { 0xD6,0x00+R_I2C_SLEW },//{Dummy, R_I2C_SLEW, Dummy[5:0]}\r
+#endif\r
+//    { 0xD6,0x30 },//{Dummy, R_I2C_SLEW, R_I2C_DRV[1:0], Dummy[3:0]}\r
+//    { 0xD5,0x44 },//IO-level(I2C), 44:3.3V, 00:1.8V\r
+//    { 0xB2,0x25 },\r
+    { 0x55,0x24 },//Soft Reset:04 Hard Reset:24\r
+    { 0x52,0x12 },//VDDAY=1.63V\r
+//    { 0xA6,0xF7 },//Cmd_vdday_pwrsv_sel_EnH=0\r
+    { 0xAE,0x3F },//R_LPO_Cali_mode=1\r
+    { 0x20,0x05 },//Clear INT\r
+};\r
+#ifndef LED_SUPPLIER_NEW\r
+#ifdef DI_WALL_4mm\r
+#define PPG_SETTING_VERSION 0x01\r
+#endif\r
+#if (DIW_4MM_G_IR_HRD==1)\r
+static const uint8_t PAH8009_REG_DIW_4MM_G_IR_PPG[][2] = {\r
+    //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x08,0xE8 },//A period\r
+    { 0x09,0x03 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x08 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x0E,0x04 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x08 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x76 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x12 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x04 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x92 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x58 },//RDB_expo_A[7:0]\r
+    { 0x18,0x02 },//RDB_expo_A[15:8]\r
+    { 0x19,0x00 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x01 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x1F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x2F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+static const uint8_t PAH8009_REG_DIW_4MM_G_IR_TOUCH[][2] = {\r
+  //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x44 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x16,0x92 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0x04 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+#endif\r
+#if (DIW_4MM_IR_R_IR_SPO2==1)\r
+static const uint8_t PAH8009_REG_DIW_4MM_IR_R_IR_PPG[][2] = {\r
+  //{ 0xEE,0x07 },\r
+    { 0x03,0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x05 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x08,0x00 },//A period\r
+    { 0x09,0x01 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x01 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x0E,0x40 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x40 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x77 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x52 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x44 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x84 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x40 },//RDB_expo_A[7:0]\r
+    { 0x18,0x00 },//RDB_expo_A[15:8]\r
+    { 0x19,0x40 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x00 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x1F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x4F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+\r
+static const uint8_t PAH8009_REG_DIW_4MM_IR_R_IR_TOUCH[][2] = {\r
+  //{ 0xEE,0x07 },\r
+    { 0x03,0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x05 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x44 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x16,0x92 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0x04 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+#endif\r
+\r
+#if (PC_4MM_2G_IR_HRD==1)\r
+#ifdef PC_4mm\r
+#define PPG_SETTING_VERSION 0x11\r
+#endif\r
+static const uint8_t PAH8009_REG_PC_4MM_2G_IR_PPG[][2] = {\r
+    //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x08,0xE8 },//A period\r
+    { 0x09,0x03 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x08 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x0E,0x04 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x08 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x76 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x12 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x44 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0xC4 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x58 },//RDB_expo_A[7:0]\r
+    { 0x18,0x02 },//RDB_expo_A[15:8]\r
+    { 0x19,0x00 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x01 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x28 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x1F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x6F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH  \r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+static const uint8_t PAH8009_REG_PC_4MM_2G_IR_TOUCH[][2] = {\r
+    //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x44 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x16,0xD2 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x1B,0x28 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0x04 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH  \r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+#endif\r
+\r
+\r
+#else\r
+#ifdef DI_WALL_4mm\r
+#define PPG_SETTING_VERSION 0x21\r
+#endif\r
+#if (DIW_4MM_G_IR_HRD==1)\r
+static const uint8_t PAH8009_REG_DIW_4MM_G_IR_PPG[][2] = {\r
+       //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x08,0xE8 },//A period\r
+    { 0x09,0x03 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x08 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x0E,0x04 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x08 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x76 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x12 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x04 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x12 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x58 },//RDB_expo_A[7:0]\r
+    { 0x18,0x02 },//RDB_expo_A[15:8]\r
+    { 0x19,0x00 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x01 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x1F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x2F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+static const uint8_t PAH8009_REG_DIW_4MM_G_IR_TOUCH[][2] = {\r
+  //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x44 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x16,0x12 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0x04 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+#endif\r
+\r
+#if (DIW_4MM_IR_R_IR_SPO2==1)\r
+static const uint8_t PAH8009_REG_DIW_4MM_IR_R_IR_PPG[][2] = {\r
+  //{ 0xEE,0x07 },\r
+    { 0x03,0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x05 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x08,0x00 },//A period\r
+    { 0x09,0x01 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x01 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x0E,0x40 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x40 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x77 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x12 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x04 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x04 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x40 },//RDB_expo_A[7:0]\r
+    { 0x18,0x00 },//RDB_expo_A[15:8]\r
+    { 0x19,0x40 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x00 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x1F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x4F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+static const uint8_t PAH8009_REG_DIW_4MM_IR_R_IR_TOUCH[][2] = {\r
+  //{ 0xEE,0x07 },\r
+    { 0x03,0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x05 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x44 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x16,0x12 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x1B,0x20 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0x04 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH\r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+#endif\r
+\r
+//China LED\r
+\r
+#if (PC_4MM_2G_IR_HRD==1)\r
+#ifdef PC_4mm\r
+#define PPG_SETTING_VERSION 0x31\r
+#endif\r
+static const uint8_t PAH8009_REG_PC_4MM_2G_IR_PPG[][2] = {\r
+    //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x08,0xE8 },//A period\r
+    { 0x09,0x03 },//A period\r
+    { 0x0A,0x00 },//B period\r
+    { 0x0B,0x08 },//B period\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x0E,0x04 },//RDB_FrameNum_A[6:0]\r
+    { 0x0F,0x08 },//RDB_FrameNum_B[6:0]\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x76 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x14,0x12 },//{RDB_ChA_congain_sel[1:0], Dummy[0], R_LEDDAC_code0[4:0]}\r
+    { 0x15,0x44 },//{RDB_ChB_congain_sel[1:0], Dummy[0], R_LEDDAC_code1[4:0]}\r
+    { 0x16,0x04 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x17,0x58 },//RDB_expo_A[7:0]\r
+    { 0x18,0x02 },//RDB_expo_A[15:8]\r
+    { 0x19,0x00 },//RDB_expo_B[7:0]\r
+    { 0x1A,0x01 },//RDB_expo_B[15:8]\r
+    { 0x1B,0x28 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1D,0x1F },//{R_ChA_LED_EnH[2:0], R_ChA_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1E,0x6F },//{R_ChB_LED_EnH[2:0], R_ChB_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0xF7 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH  \r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+\r
+static const uint8_t PAH8009_REG_PC_4MM_2G_IR_TOUCH[][2] = {\r
+    //{ 0xEE,0x07 },\r
+    { 0x03,0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04,0x06 },//Golden report period[15:8]\r
+    { 0x05,0x00 },//Golden report period[19:16]\r
+    { 0x12,0x01 },//ChC_report_divider[7:0]\r
+    { 0x13,0x00 },//ChC_report_divider[9:8]\r
+    { 0x0C,0x00 },//C period\r
+    { 0x0D,0x01 },//C period\r
+    { 0x10,0x01 },//RDB_FrameNum_C[6:0]\r
+    { 0x11,0x44 },//{R_OnOff_mode_C_EnH, R_OnOff_mode_B_EnH, R_OnOff_mode_A_EnH, R_ChC_EnH, R_ChB_EnH, R_ChA_EnH}\r
+    { 0x16,0x12 },//{RDB_ChC_congain_sel[1:0], Dummy[0], R_LEDDAC_code2[4:0]}\r
+    { 0x1B,0x28 },//RDB_expo_C[7:0]\r
+    { 0x1C,0x00 },//RDB_expo_C[15:8]\r
+    { 0x1F,0x1F },//{R_ChC_LED_EnH[2:0], R_ChC_Pixel_EnH[3:0]}, [3]:pixel3, [2]:pixel2, [1]:pixel1, [0]:pixel0, enable high\r
+    { 0x22,0x04 },//RDB_Int_En[7:0], [2]:touch flag [1]:overflow [0]:data ready\r
+    { 0x26,0x20 },//{R_ADCdata_C_Sel[1:0], R_ADCdata_B_Sel[1:0], R_ADCdata_A_Sel[1:0]}, 0:on, 1:off(需開On-Off), 2:on-off(需開On-Off)\r
+    { 0x49,0x11 },//RDB_Touch_EnH  \r
+    { 0x4A,0x00 },//R_TouchDetection_Th_Hi[7:0]\r
+    { 0x4B,0x07 },//R_TouchDetection_Th_Hi[13:8]\r
+    { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0]\r
+    { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+    { 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
+    { 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0xEB,0x80 },//update_flag\r
+};\r
+#endif\r
+\r
+#endif\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x.c b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x.c
new file mode 100644 (file)
index 0000000..da77ddb
--- /dev/null
@@ -0,0 +1,833 @@
+// pah\r
+#include "pah_800x.h"\r
+\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static bool sensor_has_enabled(pah_800x *state);\r
+\r
+static pah_ret ppg_convergence_toggle(pah_800x *state, bool enable, uint8_t ch_num);\r
+\r
+static pah_ret ppg_reset_exposure(pah_800x *state, uint8_t ch_num);\r
+\r
+//static pah_ret touch_process(pah_800x *state, uint8_t *touch_flag);\r
+static pah_ret ppg_process(pah_800x *state, pah_800x_ppg_data *ppg_result);\r
+static pah_ret clear_interrupt(pah_800x *state, bool has_ppg_interrupt, bool has_overflow);\r
+\r
+static pah_ret ppg_converging(pah_800x *state, uint32_t ppg_value, uint8_t ch_num);\r
+static uint16_t select_new_ppg_exposure(pah_800x *state, uint16_t old_ppg_exposure, uint16_t ppg_value, uint8_t ch_num);\r
+\r
+static bool is_touched(pah_800x *state);\r
+static bool is_not_touched(pah_800x *state);\r
+\r
+static bool ppg_value_is_out_of_outer_bounds(pah_800x *state, uint32_t ppg_data, uint8_t ch_num);\r
+static bool ppg_value_is_out_of_inner_bounds(pah_800x *state, uint16_t ppg_data, uint8_t ch_num);\r
+\r
+static pah_ret pah_800x_sw_reset(pah_800x *state);\r
+/////////////////////////////////////////////////////////////////////////////////////////////\r
+\r
+//// comm\r
+\r
+static pah_ret pah_800x_hal_comm_write(uint8_t addr, const uint8_t *data, size_t write_size);\r
+static pah_ret pah_800x_hal_comm_read(uint8_t addr, uint8_t *data, size_t read_size);\r
+\r
+    \r
+//// write\r
+static pah_ret pah_800x_hal_write_reg_arr(const pah_reg_arr *reg_arr);\r
+static pah_ret pah_800x_hal_write_reg_array(const uint8_t reg_array[][2], size_t length);\r
+static pah_ret pah_800x_hal_write_suspend_state(bool suspend);\r
+static pah_ret pah_800x_hal_write_interrupt_clear(void);\r
+static pah_ret pah_800x_hal_write_interrupt_clear_v2(bool int_status_DR_FLAG_b);\r
+static pah_ret pah_800x_hal_write_ppg_overflow_clear(void);\r
+static pah_ret pah_800x_hal_write_exposure(uint16_t exposure, uint8_t ch_num);\r
+static pah_ret pah_800x_hal_tg_toggle(bool enable);\r
+static pah_ret pah_800x_hal_update_flag(void);\r
+static pah_ret pah_800x_hal_write_sw_reset(void);\r
+static pah_ret pah_800x_hal_reset_gpio_state(void);\r
+//// read\r
+static pah_ret pah_800x_hal_read_product_id(uint16_t *product_id);\r
+static pah_ret pah_800x_hal_read_ppg_interrupt(uint8_t *ppg_interrupt);\r
+static pah_ret pah_800x_hal_read_ppg_sync(uint32_t *ppg_data, uint8_t ch_num);\r
+static pah_ret pah_800x_hal_read_ppg_overflow(uint8_t *ppg_overflow, uint8_t *overflow_num);\r
+static pah_ret pah_800x_hal_read_ppg_exposure(uint16_t *als_exposure, uint8_t ch_num);\r
+static pah_ret pah_800x_hal_touch_get_touch_flag(int8_t *touch_flag);\r
+static pah_ret pah_800x_hal_touch_get_touch_info(int8_t *touch_flag,uint16_t *touch_value);\r
+\r
+\r
+static pah_ret pah_800x_hal_check_enable_channel(pah_800x *state, const pah_reg_arr *reg_arr);\r
+static pah_ret comm_write(uint8_t addr, uint8_t data);\r
+static pah_ret pah_800x_hal_read_ppg_adc(uint16_t *ppg_adc, uint8_t ch_num);\r
+static pah_ret pah_800x_hal_read_ppg_frame_period(uint16_t *ppg_frame_period, uint8_t ch_num);\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+uint16_t pah_800x_get_i2c_default_slave_addr(void)\r
+{\r
+    return PAH_800x_DEFAULT_I2C_SLAVE_ID_1;\r
+}\r
+\r
+void pah_800x_get_default_config(pah_800x_config *config)\r
+{\r
+    memset(config, 0, sizeof(*config));    \r
+\r
+    config->enable_ppg_convergence[0] = PAH_800x_DEFAULT_ENABLE_PPG_CONVERGENCE;\r
+    config->enable_ppg_convergence[1] = PAH_800x_DEFAULT_ENABLE_PPG_CONVERGENCE;\r
+    config->enable_ppg_convergence[2] = false;\r
+\r
+    config->enable_ppg_reconvergence_if_out_of_bounds[0] = PAH_800x_DEFAULT_ENABLE_PPG_RECONVERGENCE_IF_OUT_OF_BOUNDS;\r
+    config->enable_ppg_reconvergence_if_out_of_bounds[1] = PAH_800x_DEFAULT_ENABLE_PPG_RECONVERGENCE_IF_OUT_OF_BOUNDS;\r
+    config->enable_ppg_reconvergence_if_out_of_bounds[2] = false;\r
+    \r
+    for(int ch=0;ch<PAH_800x_MAX_CH_NUM;ch++)\r
+    {\r
+        config->ppg_convergence[ch].t_weight_normal_mode = PAH_800x_DEFAULT_PPG_CONVERGENCE_T_WEIGHT_NORMAL_MODE;\r
+        config->ppg_convergence[ch].t_weight_fast_mode = PAH_800x_DEFAULT_PPG_CONVERGENCE_T_WEIGHT_FAST_MODE;\r
+        config->ppg_convergence[ch].t_min = PAH_800x_DEFAULT_PPG_CONVERGENCE_T_MIN;\r
+        config->ppg_convergence[ch].t_max = PAH_800x_DEFAULT_PPG_CONVERGENCE_T_MAX;\r
+        config->ppg_convergence[ch].raw_outer_high_bound = PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_OUTER_HIGH_BOUND;\r
+        config->ppg_convergence[ch].raw_inner_high_target = PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_INNER_HIGH_TARGET;\r
+        config->ppg_convergence[ch].raw_inner_low_target = PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_INNER_LOW_TARGET;\r
+        config->ppg_convergence[ch].raw_outer_low_bound = PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_OUTER_LOW_BOUND;\r
+        config->ppg_convergence[ch].convergence_count = PAH_800x_DEFAULT_PPG_CONVERGENCE_COUNT;\r
+        config->ppg_initial_exposure[ch] = PAH_800x_DEFAULT_PPG_INITIAL_EXPOSURE;\r
+    }   \r
+\r
+}\r
+\r
+pah_ret pah_800x_get_product_id(uint16_t *product_id)\r
+{\r
+    return pah_800x_hal_read_product_id(product_id);\r
+}\r
+\r
+pah_ret pah_800x_init(pah_800x *state, const pah_800x_config *config)\r
+{\r
+    memset(state, 0, sizeof(*state));\r
+    \r
+   // state->plat     = *plat;\r
+    state->config   = *config;\r
+    for(int ch=0;ch<PAH_800x_MAX_CH_NUM;ch++)\r
+    {\r
+        DEBUG_PRINT("enable_ppg_convergence_ch[%d] = %d\n", ch, config->enable_ppg_convergence[ch]);\r
+        if (config->enable_ppg_convergence[ch])\r
+        {\r
+            DEBUG_PRINT("(t_weight_normal_mode, t_weight_fast_mode) = (%d, %d)\n",\r
+                        config->ppg_convergence[ch].t_weight_normal_mode,\r
+                        config->ppg_convergence[ch].t_weight_fast_mode);\r
+            DEBUG_PRINT("(t_min, t_max) = (%d, %d)\n",\r
+                        config->ppg_convergence[ch].t_min,\r
+                        config->ppg_convergence[ch].t_max);\r
+            DEBUG_PRINT("(raw_outer_high_bound, raw_inner_high_target) = (%d, %d)\n",\r
+                        config->ppg_convergence[ch].raw_outer_high_bound,\r
+                        config->ppg_convergence[ch].raw_inner_high_target);\r
+            DEBUG_PRINT("(raw_inner_low_target, raw_outer_low_bound) = (%d, %d)\n",\r
+                        config->ppg_convergence[ch].raw_inner_low_target,\r
+                        config->ppg_convergence[ch].raw_outer_low_bound);\r
+        }\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_deinit(pah_800x *state)\r
+{\r
+    pah_800x_ppg_toggle(state, false);\r
+    pah_800x_touch_toggle(state, false);\r
+    pah_800x_power_toggle(state, false);\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_device_init(pah_800x *state, const pah_800x_reg_setting *reg_setting)\r
+{\r
+    DEBUG_PRINT("%s\n", __func__);\r
+\r
+    //uint16_t *product_id;\r
+    uint16_t product_id;\r
+    state->reg_setting = *reg_setting;\r
+\r
+    pah_800x_hal_write_suspend_state(false);\r
+    pah_800x_hal_write_sw_reset();\r
+    pah_delay_ms(2);\r
+    pah_800x_power_toggle(state, true);\r
+    \r
+    // read id, delay for reg bank reset\r
+    //pah_800x_hal_read_product_id(product_id);\r
+    pah_800x_hal_read_product_id(&product_id);\r
+    pah_800x_hal_write_reg_arr(&state->reg_setting.startup_init);\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_power_toggle(pah_800x *state, bool enable)\r
+{\r
+    DEBUG_PRINT("%s(%d, %d)\n", __func__, state->is_powered, enable);\r
+\r
+    \r
+    if (enable)\r
+    {\r
+        if (state->is_powered == enable)\r
+        {\r
+            return PAH_RET_SUCCESS;\r
+        }\r
+        pah_800x_hal_write_suspend_state(false);\r
+    }\r
+    else\r
+    {\r
+        state->ppg_state.is_enabled = false;\r
+        state->touch_state.is_enabled = false;\r
+        \r
+        pah_800x_hal_write_suspend_state(false);\r
+        //pah_800x_hal_write_sw_reset();\r
+        pah_delay_ms(2);\r
+        pah_800x_hal_write_suspend_state(true);\r
+        pah_800x_hal_reset_gpio_state();\r
+    }\r
+\r
+    state->is_powered = enable;\r
+    state->touch_state.touch_flag = TOUCH_TRALSE_VALUE;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_verify_product_id(pah_800x *state, uint16_t *product_id)\r
+{\r
+    return pah_800x_hal_read_product_id(product_id);\r
+}\r
+\r
+pah_ret pah_800x_ppg_toggle(pah_800x *state, bool enable)\r
+{\r
+    DEBUG_PRINT("%s(%d, %d)\n", __func__, state->ppg_state.is_enabled, enable);\r
+    if (state->ppg_state.is_enabled == enable)\r
+        return PAH_RET_SUCCESS;\r
+    //pah_800x_hal_write_als_toggle( enable);\r
+    if (enable)\r
+    {\r
+        //load ppg setting\r
+        //comm_write(0xEB,0x80);\r
+//        for(uint8_t ch_num=0;ch_num < PAH_800x_MAX_CH_NUM;ch_num++)\r
+//        {\r
+//            ppg_reset_exposure(state,ch_num);\r
+//            pah_800x_hal_update_flag();\r
+//        }\r
+       \r
+        pah_800x_hal_write_reg_arr(&state->reg_setting.ppg_enable);\r
+\r
+        pah_800x_hal_check_enable_channel(state, &state->reg_setting.ppg_enable);\r
+        //DEBUG_PRINT("ch enable %d %d %d \n",state->ppg_state.ppg_ch_enabled[0],state->ppg_state.ppg_ch_enabled[1],state->ppg_state.ppg_ch_enabled[2]);\r
+        pah_800x_hal_update_flag();              \r
+\r
+        pah_800x_hal_write_interrupt_clear();\r
+        if(!state->touch_state.is_enabled)\r
+            pah_800x_hal_tg_toggle(true);\r
+    }\r
+    else\r
+    {\r
+        if(!state->touch_state.is_enabled)\r
+            pah_800x_hal_tg_toggle(false);\r
+    }\r
+    \r
+    \r
+    for(uint8_t ch_num=0;ch_num < PAH_800x_MAX_CH_NUM;ch_num++)\r
+    {\r
+        state->ppg_state.is_converging[ch_num] = enable;\r
+        state->ppg_state.cur_converging_count[ch_num] = 0;\r
+    }\r
+    \r
+    state->ppg_state.is_enabled = enable;\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_ppg_get_data(pah_800x *state, pah_800x_ppg_data *ppg_data)\r
+{\r
+    *ppg_data = state->ppg_result;\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_update_touch_setting(pah_800x *state)\r
+{\r
+    pah_800x_hal_write_reg_arr(&state->reg_setting.touch_enable);\r
+    pah_800x_hal_update_flag();\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_touch_toggle(pah_800x *state, bool enable)\r
+{\r
+    DEBUG_PRINT("%s(%d, %d)\n", __func__, state->touch_state.is_enabled, enable);\r
+    if (state->touch_state.is_enabled == enable)\r
+        return PAH_RET_SUCCESS;\r
+\r
+    if (enable)\r
+    {\r
+        //load touch setting\r
+        pah_800x_hal_write_reg_arr(&state->reg_setting.touch_enable);\r
+        pah_800x_hal_update_flag();\r
+        pah_800x_hal_tg_toggle(true);\r
+    }\r
+    else\r
+        pah_800x_hal_tg_toggle(false);\r
+    state->touch_state.is_enabled = enable;\r
+        \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_800x_get_touch_flag(pah_800x *state, int8_t *touch_flag)\r
+{\r
+    *touch_flag = state->touch_flag;\r
+    return PAH_RET_SUCCESS;\r
+}\r
+pah_ret pah_800x_get_touch_value(pah_800x *state, uint16_t *touch_value)\r
+{\r
+    *touch_value = state->touch_value;\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+pah_ret pah_800x_task(pah_800x *state)\r
+{\r
+    uint8_t ppg_interrupt = 0;\r
+    bool has_ppg_interrupt = false;\r
+    memset(&state->ppg_result, 0, sizeof(state->ppg_result));\r
+    state->touch_flag = -1;\r
+    //memset(&state->touch_result, 0, sizeof(state->touch_result));\r
+    \r
+    //touch_process(state, &state->touch_flag);\r
+    pah_800x_hal_touch_get_touch_flag( &state->touch_flag);\r
+    //pah_800x_hal_touch_get_touch_info( &state->touch_flag,&state->touch_value);\r
+\r
+    pah_800x_hal_read_ppg_interrupt(&ppg_interrupt);\r
+    \r
+    has_ppg_interrupt = (ppg_interrupt > 0);\r
+    //DEBUG_PRINT("%s(%d)(%d)\n", __func__, ppg_interrupt,state->touch_flag);\r
+    if (has_ppg_interrupt > 0)\r
+    {\r
+        ppg_process(state, &state->ppg_result);\r
+    }\r
+\r
+    clear_interrupt(state, has_ppg_interrupt, state->ppg_result.has_overflow);\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static bool sensor_has_enabled(pah_800x *state)\r
+{\r
+    return state->ppg_state.is_enabled\r
+        || state->touch_state.is_enabled;\r
+}\r
+\r
+static pah_ret ppg_convergence_toggle(pah_800x *state, bool enable, uint8_t ch_num)\r
+{\r
+    //DEBUG_PRINT("%s(%d, %d, %d)\n", __func__, state->config.enable_ppg_convergence[ch_num], enable, ch_num);\r
+\r
+    if (ch_num >= PAH_800x_MAX_CH_NUM)\r
+        return PAH_RET_INVALID_ARGUMENT;\r
+\r
+    if (!state->config.enable_ppg_convergence[ch_num])\r
+        return PAH_RET_SUCCESS;\r
+   \r
+    if (enable && state->ppg_state.cur_converging_count[ch_num] < state->config.ppg_convergence[ch_num].convergence_count)\r
+    {\r
+        state->ppg_state.cur_converging_count[ch_num]++;\r
+        return PAH_RET_SUCCESS;\r
+    }\r
+    else\r
+       {\r
+         state->ppg_state.cur_converging_count[ch_num] = 0;\r
+       }\r
+    state->ppg_state.is_converging[ch_num] = enable;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret ppg_reset_exposure(pah_800x *state, uint8_t ch_num)\r
+{\r
+    //DEBUG_PRINT("%s(%d)\n", __func__, state->config.ppg_initial_exposure[ch_num]);\r
+    if (!state->config.enable_ppg_convergence[ch_num])\r
+        return PAH_RET_SUCCESS;\r
+\r
+    return pah_800x_hal_write_exposure( state->config.ppg_initial_exposure[ch_num],ch_num);\r
+}\r
+/*static pah_ret touch_process(pah_800x *state, uint8_t *touch_flag)\r
+{\r
+\r
+    pah_800x_touch_get_touch_flag( touch_flag);\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}*/\r
+\r
+\r
+static pah_ret ppg_process(pah_800x *state, pah_800x_ppg_data *ppg_result)\r
+{\r
+    uint32_t ppg_value[PAH_800x_MAX_CH_NUM] = {0};\r
+    uint8_t ppg_overflow = 0;\r
+    uint8_t overflow_num = 0;\r
+    uint16_t ppg_exposure = 0;\r
+    uint16_t ppg_adc = 0;\r
+    uint16_t ppg_frame_period = 0;\r
+    if (!state->ppg_state.is_enabled)\r
+        return PAH_RET_SUCCESS;\r
+\r
+    for(uint8_t ch_num=0; ch_num < PAH_800x_MAX_CH_NUM; ch_num++)\r
+    {\r
+        if(state->ppg_state.ppg_ch_enabled[ch_num])\r
+        {\r
+            pah_800x_hal_read_ppg_sync(&ppg_value[ch_num], ch_num);\r
+            pah_800x_hal_read_ppg_exposure(&ppg_exposure, ch_num);\r
+            pah_800x_hal_read_ppg_frame_period(&ppg_frame_period,ch_num);\r
+            pah_800x_hal_read_ppg_adc(&ppg_adc,ch_num);\r
+            ppg_converging(state, ppg_adc, ch_num);//SD-revise-20191205\r
+            \r
+            ppg_result->data[ch_num] = ppg_value[ch_num];\r
+            ppg_result->exposure_time[ch_num] = ppg_exposure;\r
+            ppg_result->frame_period[ch_num] = ppg_frame_period;\r
+            ppg_result->adc[ch_num] = ppg_adc;\r
+        }        \r
+    }    \r
+    pah_800x_hal_read_ppg_overflow(&ppg_overflow,&overflow_num);\r
+    ppg_result->has_data = true;   \r
+    ppg_result->has_overflow = (ppg_overflow > 0);   \r
+    ppg_result->overflow_num = overflow_num;\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret clear_interrupt(pah_800x *state, bool has_ppg_interrupt, bool has_overflow)\r
+{\r
+\r
+    //pah_800x_hal_write_interrupt_clear();            \r
+    pah_800x_hal_write_interrupt_clear_v2(has_ppg_interrupt); \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret ppg_converging(pah_800x *state, uint32_t ppg_adc, uint8_t ch_num)\r
+{\r
+    if (ch_num >= PAH_800x_MAX_CH_NUM)\r
+        return PAH_RET_INVALID_ARGUMENT;\r
+\r
+    if (!state->config.enable_ppg_convergence[ch_num])\r
+        return PAH_RET_SUCCESS;\r
+\r
+    if (state->config.enable_ppg_reconvergence_if_out_of_bounds[ch_num]\r
+        && !state->ppg_state.is_converging[ch_num]\r
+        && is_touched(state)\r
+        && ppg_value_is_out_of_outer_bounds(state, ppg_adc, ch_num))\r
+    {\r
+        ppg_convergence_toggle(state, true, ch_num);\r
+    }\r
+    else\r
+    {\r
+       state->ppg_state.cur_converging_count[ch_num] = 0;\r
+    }\r
+\r
+    if (!state->ppg_state.is_converging[ch_num])\r
+        return PAH_RET_SUCCESS;\r
+   \r
+    if (ppg_value_is_out_of_inner_bounds(state, ppg_adc, ch_num))\r
+    {\r
+        uint16_t ppg_exposure = 0;\r
+        uint16_t new_ppg_exposure = 0;\r
+\r
+        pah_800x_hal_read_ppg_exposure(&ppg_exposure, ch_num);\r
+        //DEBUG_PRINT("ppg converging[%d] exposure time %d ppg_value %d \n",ch_num, ppg_exposure,ppg_value);\r
+        new_ppg_exposure = select_new_ppg_exposure(state, ppg_exposure, ppg_adc, ch_num);\r
+        if(new_ppg_exposure==ppg_exposure)\r
+        {\r
+            return PAH_RET_SUCCESS;\r
+        }\r
+\r
+        if (new_ppg_exposure > state->config.ppg_convergence[ch_num].t_max)\r
+        {\r
+            new_ppg_exposure = state->config.ppg_convergence[ch_num].t_max;\r
+            ppg_convergence_toggle(state, false, ch_num);\r
+            \r
+            DEBUG_PRINT("ppg converging complete: (exposure, t_max) = (%d)\n", new_ppg_exposure, state->config.ppg_convergence[ch_num].t_max);\r
+        }\r
+        else if (new_ppg_exposure < state->config.ppg_convergence[ch_num].t_min)\r
+        {\r
+            new_ppg_exposure = state->config.ppg_convergence[ch_num].t_min;\r
+            ppg_convergence_toggle(state, false, ch_num);\r
+            \r
+            DEBUG_PRINT("ppg converging complete: (exposure, t_min) = (%d)\n", new_ppg_exposure, state->config.ppg_convergence[ch_num].t_min);\r
+        }\r
+\r
+        pah_800x_hal_write_exposure(new_ppg_exposure, ch_num);\r
+        pah_800x_hal_update_flag();      \r
+        \r
+    }\r
+    else\r
+    {\r
+        ppg_convergence_toggle(state, false, ch_num);\r
+        \r
+        DEBUG_PRINT("ppg converging complete: (low_target, als_lux_sync, high_target) = (%d, %d, %d)\n",\r
+                    state->config.ppg_convergence[ch_num].raw_inner_low_target, ppg_adc,\r
+                    state->config.ppg_convergence[ch_num].raw_inner_high_target);\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static uint16_t select_new_ppg_exposure(pah_800x *state, uint16_t old_ppg_exposure, uint16_t ppg_value, uint8_t ch_num)\r
+{\r
+    int32_t new_ppg_exposure = (int32_t)old_ppg_exposure;\r
+\r
+    if (ppg_value < state->config.ppg_convergence[ch_num].raw_outer_low_bound)\r
+        new_ppg_exposure += state->config.ppg_convergence[ch_num].t_weight_fast_mode;\r
+    else if (ppg_value < state->config.ppg_convergence[ch_num].raw_inner_low_target)\r
+        new_ppg_exposure += state->config.ppg_convergence[ch_num].t_weight_normal_mode;\r
+    else if (ppg_value > state->config.ppg_convergence[ch_num].raw_outer_high_bound)\r
+    {\r
+        if(new_ppg_exposure==state->config.ppg_convergence[ch_num].t_min)\r
+        {\r
+            return new_ppg_exposure;\r
+        }            \r
+        new_ppg_exposure -= state->config.ppg_convergence[ch_num].t_weight_fast_mode;\r
+    \r
+    }else if (ppg_value > state->config.ppg_convergence[ch_num].raw_inner_high_target)\r
+        new_ppg_exposure -= state->config.ppg_convergence[ch_num].t_weight_normal_mode;\r
+\r
+    return new_ppg_exposure;\r
+}\r
+\r
+static bool is_touched(pah_800x *state)\r
+{\r
+    return  state->touch_flag == 1;\r
+}\r
+\r
+static bool is_not_touched(pah_800x *state)\r
+{\r
+    return state->touch_flag == 0;\r
+}\r
+\r
+static bool ppg_value_is_out_of_outer_bounds(pah_800x *state, uint32_t ppg_data, uint8_t ch_num)\r
+{\r
+    return (ppg_data < state->config.ppg_convergence[ch_num].raw_outer_low_bound)\r
+        || (ppg_data > state->config.ppg_convergence[ch_num].raw_outer_high_bound);\r
+}\r
+\r
+static bool ppg_value_is_out_of_inner_bounds(pah_800x *state, uint16_t ppg_data, uint8_t ch_num)\r
+{\r
+    return (ppg_data < state->config.ppg_convergence[ch_num].raw_inner_low_target)\r
+        || (ppg_data > state->config.ppg_convergence[ch_num].raw_inner_high_target);\r
+}\r
+\r
+static pah_ret pah_800x_sw_reset(pah_800x *state)\r
+{\r
+    //set sw reset should not in suspend mode\r
+    if (state->is_powered == false)\r
+        return PAH_RET_FAILED;\r
+\r
+    return pah_800x_hal_write_sw_reset();\r
+}\r
+////////////////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+//===========================================================================\r
+// Private function\r
+//===========================================================================\r
+static pah_ret pah_800x_hal_comm_write(uint8_t addr, const uint8_t *data, size_t write_size)\r
+{\r
+    //return plat->comm.write(&plat->comm, addr, data, write_size);\r
+    //return plat->comm.write(addr, data, write_size);\r
+    return pah_comm_i2c_write(addr, data, write_size);\r
+}\r
+\r
+static pah_ret pah_800x_hal_comm_read(uint8_t addr, uint8_t *data, size_t read_size)\r
+{\r
+\r
+    //return plat->comm.read(&plat->comm, addr, data, read_size);\r
+    return pah_comm_i2c_read(addr, data, read_size);\r
+}\r
+\r
+static pah_ret comm_write(uint8_t addr, uint8_t data)\r
+{\r
+    //return pah_800x_hal_comm_write( addr, &data, 1);\r
+    return pah_800x_hal_comm_write(addr, &data, 1);\r
+}\r
+#define comm_read(addr, data)                     pah_800x_hal_comm_read(addr, data, 1)\r
+#define comm_burst_read(addr, data, read_size)    pah_800x_hal_comm_read(addr, data, read_size)\r
+\r
+\r
+//===========================================================================\r
+// Private function (HAL)\r
+//===========================================================================\r
+static pah_ret pah_800x_hal_write_reg_arr(const pah_reg_arr *reg_arr)\r
+{\r
+    return pah_800x_hal_write_reg_array(reg_arr->reg_arr, reg_arr->reg_arr_len);\r
+}\r
+\r
+static pah_ret pah_800x_hal_write_reg_array(const uint8_t reg_array[][2], size_t length)\r
+{\r
+    size_t i = 0;\r
+    uint8_t reg_value = 0;\r
+    for (i = 0; i < length; ++i)\r
+    {\r
+        //for trim bit\r
+        if (reg_array[i][0] == 0x14)\r
+        {\r
+            comm_read(0x14, &reg_value);\r
+            reg_value = (reg_value & 0x1F) | (reg_array[i][1] & 0xE0);\r
+            comm_write(reg_array[i][0], reg_value);\r
+        }\r
+        else\r
+            comm_write(reg_array[i][0], reg_array[i][1]);\r
+    }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_write_suspend_state(bool suspend)\r
+{\r
+    uint8_t data = 0;\r
+    DEBUG_PRINT("%s(%d)\n", __func__, suspend);\r
+    if (suspend)\r
+    {\r
+        pah_800x_hal_write_interrupt_clear();\r
+        comm_read(PAH_800x_ADDR_E8, &data);\r
+        PAH_SET_BIT(data, PAH_800x_ADDR_E8_CMD_SUSPEND_MODE_BIT);\r
+        comm_write(PAH_800x_ADDR_E8, data);\r
+    }\r
+    else\r
+    {\r
+        comm_read(PAH_800x_ADDR_E8, &data);\r
+        PAH_CLEAR_BIT(data, PAH_800x_ADDR_E8_CMD_SUSPEND_MODE_BIT);\r
+        comm_write(PAH_800x_ADDR_E8, data);\r
+\r
+    }\r
+    DEBUG_PRINT("%s(%d) end\n", __func__, suspend);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_write_interrupt_clear(void)\r
+{\r
+    uint8_t data = 0;\r
+    // DR interrupt\r
+    comm_read(PAH_800x_ADDR_20, &data);\r
+    //PAH_CLEAR_BIT(data, PAH_800x_ADDR_20_BIT_DR_FLAG);\r
+    comm_write(PAH_800x_ADDR_20, (data|0x04));    //SD-revise-20191205\r
+    return PAH_RET_SUCCESS;\r
+}\r
+static pah_ret pah_800x_hal_write_interrupt_clear_v2(bool int_status_DR_FLAG_b)\r
+{\r
+    uint8_t data = 0;\r
+    bool int_status_DR_FLAG = 0;\r
+    // DR interrupt\r
+    comm_read(PAH_800x_ADDR_20, &data);\r
+    int_status_DR_FLAG = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_DR_FLAG) ;\r
+    \r
+    if(int_status_DR_FLAG_b==int_status_DR_FLAG)\r
+    {\r
+        comm_write(PAH_800x_ADDR_20, (data|0x04));     //SD-revise-20191205\r
+    }else if((int_status_DR_FLAG_b)==0 &&(int_status_DR_FLAG==1))\r
+    {\r
+        comm_write(PAH_800x_ADDR_20, ((data|0x04)&0xFE));      //SD-revise-20191205\r
+    }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+static pah_ret pah_800x_hal_write_ppg_overflow_clear(void)\r
+{\r
+    uint8_t data = 0;\r
+    // Clear ppg_overflow flag\r
+    comm_read(PAH_800x_ADDR_20, &data);\r
+    PAH_SET_BIT(data, PAH_800x_ADDR_20_BIT_OVERFLOW_FLAG);\r
+    comm_write( PAH_800x_ADDR_20, data);\r
+    // Recover\r
+    PAH_CLEAR_BIT(data, PAH_800x_ADDR_20_BIT_OVERFLOW_FLAG);\r
+    comm_write(PAH_800x_ADDR_20, data);\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_write_exposure(uint16_t exposure, uint8_t ch_num)\r
+{\r
+    //uint8_t data = 0;\r
+    uint8_t exposure_low = PAH_UINT16_LOW(exposure);\r
+    uint8_t exposure_high = PAH_UINT16_HIGH(exposure);\r
+\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+    {\r
+        comm_write(PAH_800x_ADDR_17, exposure_low);\r
+        comm_write(PAH_800x_ADDR_18, exposure_high);\r
+    }\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+    {\r
+        comm_write(PAH_800x_ADDR_19, exposure_low);\r
+        comm_write(PAH_800x_ADDR_1A, exposure_high);\r
+    }\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+    {\r
+        comm_write(PAH_800x_ADDR_1B, exposure_low);\r
+        comm_write(PAH_800x_ADDR_1C, exposure_high);\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_read_product_id(uint16_t *product_id)\r
+{\r
+    return comm_burst_read(PAH_800x_ADDR_00_PRODUCT_ID, (uint8_t *)product_id,2);\r
+}\r
+\r
+static pah_ret pah_800x_hal_read_ppg_interrupt(uint8_t *ppg_interrupt)\r
+{\r
+    uint8_t data = 0;\r
+    comm_read(PAH_800x_ADDR_20, &data);\r
+    if (ppg_interrupt)\r
+        *ppg_interrupt = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_DR_FLAG);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_read_ppg_sync(uint32_t *ppg_data, uint8_t ch_num)\r
+{\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+         comm_burst_read(PAH_800x_ADDR_27_RAWDATA_A_SYNC, (uint8_t*)ppg_data, 3);\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+         comm_burst_read(PAH_800x_ADDR_32_RAWDATA_B_SYNC, (uint8_t*)ppg_data, 3);\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+         comm_burst_read(PAH_800x_ADDR_3D_RAWDATA_C_SYNC, (uint8_t*)ppg_data, 3);\r
+    return PAH_RET_SUCCESS; \r
+}\r
+\r
+static pah_ret pah_800x_hal_read_ppg_overflow(uint8_t *ppg_overflow, uint8_t *overflow_num)\r
+{\r
+    uint8_t data = 0;\r
+    comm_read( PAH_800x_ADDR_20, &data);\r
+    if (ppg_overflow)\r
+    {\r
+        *ppg_overflow = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_OVERFLOW_FLAG);\r
+        *overflow_num = (data&0x70)>>4;\r
+    }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_read_ppg_exposure(uint16_t *ppg_exposure, uint8_t ch_num)\r
+{\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+        comm_burst_read(PAH_800x_ADDR_2A, (uint8_t*)ppg_exposure, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+        comm_burst_read(PAH_800x_ADDR_35, (uint8_t*)ppg_exposure, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+        comm_burst_read(PAH_800x_ADDR_40, (uint8_t*)ppg_exposure, 2);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_read_ppg_frame_period( uint16_t *ppg_frame_period, uint8_t ch_num)\r
+{\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+        comm_burst_read(PAH_800x_ADDR_2C, (uint8_t*)ppg_frame_period, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+        comm_burst_read(PAH_800x_ADDR_37, (uint8_t*)ppg_frame_period, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+        comm_burst_read(PAH_800x_ADDR_42, (uint8_t*)ppg_frame_period, 2);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_read_ppg_adc(uint16_t *ppg_adc, uint8_t ch_num)\r
+{\r
+    uint16_t data = 0;\r
+\r
+    if(ch_num == PAH_800x_CH_NUM_A)\r
+        comm_burst_read(PAH_800x_ADDR_2E, (uint8_t*)&data, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_B)\r
+        comm_burst_read(PAH_800x_ADDR_39, (uint8_t*)&data, 2);\r
+    else if(ch_num == PAH_800x_CH_NUM_C)\r
+        comm_burst_read(PAH_800x_ADDR_44, (uint8_t*)&data, 2);\r
+    \r
+    //*ppg_adc = data >> 2;\r
+    *ppg_adc = data >> 2;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_touch_get_touch_flag(int8_t *touch_flag)\r
+{\r
+    uint8_t     data = 0;\r
+    uint16_t    data1 = 0;\r
+//    comm_read(PAH_800x_ADDR_20, &data);\r
+    comm_burst_read(PAH_800x_ADDR_44, (uint8_t*)&data1, 2);\r
+    comm_read(PAH_800x_ADDR_20, &data);\r
+    // printf("data : %d, data1 : %d\n",data,data1);\r
+     if (touch_flag)\r
+        *touch_flag = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_TOUCH_FLAG);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+static pah_ret pah_800x_hal_touch_get_touch_info(int8_t *touch_flag,uint16_t *touch_value)\r
+{\r
+    uint8_t    data = 0;\r
+    uint16_t   data1 = 0;\r
+//    comm_read(PAH_800x_ADDR_20, &data);\r
+    comm_burst_read(PAH_800x_ADDR_44, (uint8_t*)&data1, 2);\r
+    *touch_value =data1>>2;\r
+    comm_read(PAH_800x_ADDR_20, &data);\r
+     if (touch_flag)\r
+        *touch_flag = PAH_CHECK_BIT(data, PAH_800x_ADDR_20_BIT_TOUCH_FLAG);\r
+\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_tg_toggle(bool enable)\r
+{\r
+    uint8_t data = 0;\r
+    comm_read( PAH_800x_ADDR_07_TG, &data);\r
+    if(enable)\r
+        PAH_SET_BIT(data, PAH_800x_ADDR_07_TG_BIT_EN);\r
+    else\r
+        PAH_CLEAR_BIT(data, PAH_800x_ADDR_07_TG_BIT_EN);\r
+    comm_write(PAH_800x_ADDR_07_TG, data);\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_update_flag(void)\r
+{   \r
+     comm_write(PAH_800x_ADDR_EB, PAH_800x_ADDR_E8_UPDATE_FLAG);\r
+\r
+     return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_write_sw_reset(void)\r
+{\r
+    comm_write(PAH_800x_ADDR_EE, PAH_800x_ADDR_EE_SW_RESET);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret pah_800x_hal_check_enable_channel(pah_800x *state, const pah_reg_arr *reg_arr)\r
+{\r
+    for(int i=0;i<reg_arr->reg_arr_len;i++)\r
+    {\r
+        if(reg_arr->reg_arr[i][0] == PAH_800x_ADDR_11_EnCh)\r
+        {\r
+            uint8_t data = reg_arr->reg_arr[i][1];\r
+            state->ppg_state.ppg_ch_enabled[0] = PAH_CHECK_BIT(data, 0); // CH A\r
+            state->ppg_state.ppg_ch_enabled[1] = PAH_CHECK_BIT(data, 1); // CH B\r
+            state->ppg_state.ppg_ch_enabled[2] = PAH_CHECK_BIT(data, 2); // CH C\r
+        }\r
+    }\r
+        \r
+        return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+static pah_ret pah_800x_hal_reset_gpio_state(void)\r
+{\r
+    uint8_t data = 0;\r
+\r
+    comm_read(PAH_800x_ADDR_D2, &data);\r
+    PAH_SET_BIT(data, PAH_800x_ADDR_D2_OD_EnH);\r
+    comm_write(PAH_800x_ADDR_D2, data);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x.h b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x.h
new file mode 100644 (file)
index 0000000..2500dc6
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef __pah_800x_h__\r
+#define __pah_800x_h__\r
+\r
+// pah\r
+#include "pah_unit.h"\r
+#include "pah_800x_config.h"\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+#define TOUCH_TRALSE_VALUE      (-1)\r
+\r
+\r
+//============================================================================\r
+// Type Definition\r
+//============================================================================\r
+typedef struct\r
+{\r
+    uint16_t    t_weight_normal_mode;\r
+    uint16_t    t_weight_fast_mode;\r
+    uint16_t    t_min;\r
+    uint16_t    t_max;\r
+\r
+    uint16_t    raw_outer_high_bound;\r
+    uint16_t    raw_inner_high_target;\r
+    uint16_t    raw_inner_low_target;\r
+    uint16_t    raw_outer_low_bound;\r
+\r
+    uint16_t    convergence_count;\r
+} pah_800x_ppg_convergence;\r
+\r
+typedef struct\r
+{\r
+    uint16_t                    ppg_initial_exposure[PAH_800x_MAX_CH_NUM];\r
+\r
+    bool                        enable_ppg_convergence[PAH_800x_MAX_CH_NUM];\r
+    pah_800x_ppg_convergence    ppg_convergence[PAH_800x_MAX_CH_NUM];\r
+    bool                        enable_ppg_reconvergence_if_out_of_bounds[PAH_800x_MAX_CH_NUM];\r
+\r
+} pah_800x_config;\r
+\r
+typedef struct\r
+{\r
+    bool        is_enabled;\r
+\r
+    bool        is_converging[PAH_800x_MAX_CH_NUM];\r
+    \r
+    bool        ppg_ch_enabled[PAH_800x_MAX_CH_NUM];\r
+    uint16_t    cur_converging_count[PAH_800x_MAX_CH_NUM];\r
+} pah_800x_ppg_state;\r
+\r
+typedef struct\r
+{\r
+    bool        has_data;\r
+    uint32_t    data[PAH_800x_MAX_CH_NUM];\r
+\r
+\r
+    // Avaiable only if has_data is true\r
+    bool        has_overflow;\r
+\r
+    uint8_t     overflow_num;\r
+\r
+    // Avaiable only if has_data is true\r
+    uint16_t    exposure_time[PAH_800x_MAX_CH_NUM];\r
+    uint16_t    adc[PAH_800x_MAX_CH_NUM];\r
+    uint16_t    frame_period[PAH_800x_MAX_CH_NUM];\r
+\r
+} pah_800x_ppg_data;\r
+\r
+typedef struct\r
+{\r
+    bool        is_enabled;  \r
+    \r
+    int8_t        touch_flag;\r
+\r
+} pah_800x_touch_state;\r
+\r
+typedef struct\r
+{\r
+    pah_reg_arr     startup_init;\r
+    pah_reg_arr     ppg_enable;\r
+    pah_reg_arr     touch_enable;\r
+    \r
+} pah_800x_reg_setting;\r
+\r
+typedef struct\r
+{\r
+    // Config\r
+    //pah_plat            plat;\r
+    pah_800x_config         config;\r
+\r
+    // Power state\r
+    bool                    is_powered;\r
+\r
+    // PPG state\r
+    pah_800x_ppg_state      ppg_state;\r
+    pah_800x_ppg_data       ppg_result;\r
+\r
+    // TOUCH state\r
+    pah_800x_touch_state    touch_state;\r
+    int8_t                  touch_flag;\r
+    uint16_t                           touch_value;\r
+    // Other\r
+    pah_800x_reg_setting    reg_setting;\r
+\r
+} pah_800x;\r
+\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+#ifdef __cplusplus\r
+extern  "C" {\r
+#endif \r
+\r
+\r
+// Info\r
+uint16_t    pah_800x_get_i2c_default_slave_addr(void);\r
+void        pah_800x_get_default_config(pah_800x_config *config);\r
+pah_ret     pah_800x_get_product_id( uint16_t *product_id);    \r
+\r
+// Init\r
+pah_ret     pah_800x_init(pah_800x *state, const pah_800x_config *config);\r
+pah_ret     pah_800x_deinit(pah_800x *state);\r
+\r
+// Device init\r
+pah_ret     pah_800x_device_init(pah_800x *state, const pah_800x_reg_setting *reg_setting);\r
+\r
+// Config\r
+//pah_ret     pah_800x_set_ppg_convergence(pah_800x *state,uint8_t ch_num, const pah_800x_ppg_convergence *ppg_convergence);\r
+\r
+// Power\r
+pah_ret     pah_800x_power_toggle(pah_800x *state, bool enable);\r
+\r
+// Basic verification\r
+pah_ret     pah_800x_verify_product_id(pah_800x *state, uint16_t *product_id);\r
+\r
+// PPG\r
+pah_ret     pah_800x_ppg_toggle(pah_800x *state, bool enable);\r
+pah_ret     pah_800x_ppg_get_data(pah_800x *state, pah_800x_ppg_data *ppg_data);\r
+\r
+// TOUCH\r
+pah_ret     pah_800x_touch_toggle(pah_800x *state, bool enable);\r
+pah_ret     pah_800x_get_touch_flag(pah_800x *state, int8_t *touch_flag);\r
+pah_ret     pah_800x_get_touch_value(pah_800x *state, uint16_t *touch_value);\r
+pah_ret     pah_800x_update_touch_setting(pah_800x *state);\r
+\r
+// Task\r
+pah_ret     pah_800x_task(pah_800x *state);\r
+\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x_config.h b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_800x_config.h
new file mode 100644 (file)
index 0000000..0e3d853
--- /dev/null
@@ -0,0 +1,163 @@
+#ifndef __pah_800x_config_h__\r
+#define __pah_800x_config_h__\r
+\r
+// pah\r
+#include "pah800x_bsp.h"\r
+#include "debug_print.h"\r
+\r
+/*\r
+ * Select LED Supplier\r
+ * If Use new Supplier LED , Need to define LED_SUPPLIER_NEW\r
+*/\r
+//#define LED_SUPPLIER_NEW\r
+\r
+\r
+/*\r
+ * Select Cover Type\r
+*/\r
+#define  DI_WALL_4mm\r
+//#define  PC_4mm\r
+\r
+/*\r
+ * Select HW and ALG configuration\r
+ * PC_4MM_2G_IR_HRD : Printing Cover with 4mm 2 Green and 1 IR LED for HRD algorithm use (PAH8009ES)\r
+ * DIW_4MM_G_IR_HRD : DI+Wall Cover with 4mm 1 Green and 1 IR LED for HRD algorithm use (PAH8009ES)\r
+ * DIW_4MM_IR_R_IR_SPO2 : DI+Wall Cover with 4mm 1 IR LED and 1 RED for SpO2 algorithm use (PAH8009ES)\r
+ * This definition will enable the PPG register setting corresponding to different HW and ALG configuration\r
+ */\r
+\r
+#define PC_4MM_2G_IR_HRD    1\r
+#define DIW_4MM_G_IR_HRD          1\r
+#define DIW_4MM_IR_R_IR_SPO2    1\r
+\r
+//#endif\r
+\r
+//============================================================================\r
+// Debug Option\r
+//============================================================================\r
+#define ENABLE_AE 1\r
+#define ENABLE_AE_RECONVERGENCE 1\r
+\r
+\r
+// #define PAH_800x_ENABLE_DEBUG_PRINT\r
+// #define PAH_800x_ENABLE_LOG_PRINT\r
+\r
+#ifdef PAH_800x_ENABLE_LOG_PRINT\r
+#define LOG_PRINT(fmt, ...)                    \\r
+    do {                                      \\r
+        PRINT(fmt" ", ##__VA_ARGS__);     \\r
+    } while (0)\r
+#else\r
+#define LOG_PRINT(...) do {} while (0)\r
+#endif\r
+#ifdef PAH_800x_ENABLE_DEBUG_PRINT\r
+#define DEBUG_PRINT(fmt, ...)                    \\r
+    do {                                      \\r
+        PRINT(fmt" ", ##__VA_ARGS__);     \\r
+    } while (0) \r
+#else\r
+#define DEBUG_PRINT(...) do {} while (0)\r
+#endif\r
+\r
+/*\r
+ * Select Interrupt or Polling Mode\r
+ * This definition will enable the corresponding demo functionin main.c\r
+ * If select INT mode, then slect following INT configuration type\r
+ */\r
+#define INTERRUPT_MODE      1\r
+#define POLLING_MODE        0\r
+#define Test_pattern_mode   0\r
+\r
+/*\r
+ * Select INT HW configuration type\r
+ * INT_OD_EXTERNAL_PULLH : INT open-drain type with external pull-high resistor\r
+ * INT_OD_INTERNAL_PULLH : INT open-drain type with internal pull-high resistor\r
+ * INT_PUP_WITHOUT_PULLH : INT push-pull type without any pull-high resistor\r
+ * If user select POLLING_MODE, all define need to set 0\r
+ * This definition will enable the GPIO register setting corresponding to different INT HW configuration\r
+ */\r
+#define INT_OD_EXTERNAL_PULLH   1\r
+#define INT_OD_INTERNAL_PULLH   0\r
+#define INT_PUP_WITHOUT_PULLH   0\r
+\r
+\r
+/*\r
+* Configure VBUS Type\r
+ * Define VBUS_18V=1, compatible with VBUS=1.8V or 3.3V (default)\r
+ * Define VBUS_18V=0, only support VBUS=3.3V\r
+ * If user want to define VBUS_18V=0, or VBUS not 1.8V/3.3V, please contact with PixArt for evaluation\r
+ */\r
+#define VBUS_18V    1\r
+#if (VBUS_18V)\r
+    #define R_GPIO_0_OD_EnH        (0x20)\r
+    #define R_GPIO_SLEW            (0x01)\r
+    #define R_I2C_SLEW             (0x40)\r
+    #define R_SCL_Sel            (0x00)\r
+    #define R_SDA_Sel            (0x00)\r
+#else\r
+    #define R_GPIO_0_OD_EnH        (0x20)\r
+    #define R_GPIO_SLEW             0\r
+    #define R_I2C_SLEW              0\r
+    #define R_SCL_Sel            (0x40)\r
+    #define R_SDA_Sel            (0x04)\r
+#endif\r
+\r
+#define Time_Interval             400\r
+/*\r
+If Customer platform use G-Sensor with FIFO,they can refer this flow to run pxi alg to get alg output\r
+*/\r
+//#define PPG_MEMS_Synchronize\r
+#define Optimize_SPO2_flow\r
+\r
+//****** Demo 800X mode Select ******//\r
+//============HRD-INT================//\r
+//#define touch_only_hrd_en\r
+//#define ppg_only_hrd_en\r
+#define auto_hrd_en\r
+\r
+//============HRD-Polling================//\r
+//#define touch_only_polling_hrd_en\r
+//#define ppg_only_polling_hrd_en\r
+//#define auto_polling_hrd_en\r
+\r
+\r
+//============SPO2-INT================//\r
+//#define touch_only_spo2_en\r
+//#define ppg_only_spo2_en\r
+//#define auto_spo2_en\r
+\r
+//============SPO2-Polling================//\r
+//#define touch_only_polling_spo2_en\r
+//#define ppg_only_polling_spo2_en\r
+//#define auto_polling_spo2_en\r
+\r
+\r
+//============Stress-INT================//\r
+//#define touch_only_stress_en\r
+//#define ppg_only_stress_en\r
+//#define auto_stress_en\r
+\r
+//============Stress-Polling================//\r
+//#define touch_only_polling_stress_en\r
+//#define ppg_only_polling_stress_en\r
+//#define auto_polling_stress_en\r
+\r
+//=========== Test_pattern======== //\r
+//#define hrd_testpattern_en\r
+//#define spo2_testpattern_en\r
+\r
+//=========== Factory _Test=========//\r
+//#define factory_test_en\r
+\r
+\r
+//============HRD-INT====PC Cover============//\r
+//#define touch_only_hrd_en_pc\r
+//#define ppg_only_hrd_en_pc\r
+//#define auto_hrd_en_pc\r
+\r
+//============HRD-Polling======PC Cover==========//\r
+//#define touch_only_polling_hrd_en_pc\r
+//#define ppg_only_polling_hrd_en_pc\r
+//#define auto_polling_hrd_en_pc\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_unit.h b/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah_unit.h
new file mode 100644 (file)
index 0000000..64a1a7e
--- /dev/null
@@ -0,0 +1,340 @@
+#ifndef __pah_unit_h__\r
+#define __pah_unit_h__\r
+\r
+// c\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stddef.h>\r
+#include <string.h>\r
+#include <stdarg.h>\r
+#include <stdlib.h>\r
+\r
+\r
+//============================================================================\r
+// Default\r
+//============================================================================\r
+#define PAH_800x_DEFAULT_PPG_INITIAL_EXPOSURE       (400)\r
+\r
+#define PAH_800x_DEFAULT_ENABLE_PPG_CONVERGENCE     true\r
+\r
+\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_COUNT                                 (0)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_T_WEIGHT_NORMAL_MODE   (8)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_T_WEIGHT_FAST_MODE     (16)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_T_MIN                  (10)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_T_MAX                  (1792)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_OUTER_HIGH_BOUND   (12288)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_INNER_HIGH_TARGET  (10240)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_INNER_LOW_TARGET   (8192)\r
+#define PAH_800x_DEFAULT_PPG_CONVERGENCE_RAW_OUTER_LOW_BOUND    (6144)\r
+\r
+#define PAH_800x_DEFAULT_ENABLE_PPG_RECONVERGENCE_IF_OUT_OF_BOUNDS  true\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+\r
+// I2C 7-bit ID\r
+#define PAH_800x_DEFAULT_I2C_SLAVE_ID_1  (0x40)\r
+#define PAH_800x_DEFAULT_I2C_SLAVE_ID_2  (0x10)\r
+\r
+#define  PAH_800x_PRODUCT_ID        (0x8008)\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r
+/**\r
+ * @file pah_ret.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+typedef enum {\r
+\r
+    PAH_RET_SUCCESS = 0,            // Success\r
+    \r
+    PAH_RET_PENDING,\r
+\r
+    PAH_RET_FAILED,                 // Unknown error, generally there exists bug in this driver\r
+\r
+    PAH_RET_PLAT_FAILED,            // Platform API failed\r
+    PAH_RET_VERIFY_FAILED,          // Verify device failed\r
+\r
+    PAH_RET_NOT_IMPLEMENTED,        // This API is not supported or is not implemented\r
+\r
+    PAH_RET_INVALID_ARGUMENT,       // Invalid argument to API\r
+    PAH_RET_INVALID_OPERATION,      // This operation is not available at this time\r
+\r
+    PAH_RET_FIFO_CKS_FAILED,        // Failed to compare check sum with fifo data\r
+    PAH_RET_FIFO_OVERFLOW,          // Fifo in device is overflow\r
+\r
+    PAH_RET_ASYNC_PENDING,\r
+\r
+} pah_ret;\r
+\r
+typedef enum {\r
+    PAH_800x_CH_NUM_A = 0,\r
+    PAH_800x_CH_NUM_B,\r
+    PAH_800x_CH_NUM_C,\r
+    PAH_800x_MAX_CH_NUM,\r
+} pah_800x_ch_num;\r
+\r
+#define PAH_SUCCEEDED(ret)              (ret == PAH_RET_SUCCESS)\r
+#define PAH_FAILED(ret)                 (!PAH_SUCCEEDED(ret))\r
+\r
+\r
+#define PAH_CHECK_RET(ret) \\r
+    if (PAH_FAILED(ret)) { \\r
+        return ret; \\r
+    }\r
+\r
+#define PAH_CHECK_NULL(p) \\r
+    if (!p) { \\r
+        return PAH_RET_INVALID_ARGUMENT; \\r
+    }\r
+\r
+\r
+\r
+/**\r
+ * @file pah_plat.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+\r
+//============================================================================\r
+// Macro\r
+//============================================================================\r
+#ifndef __FILENAME__\r
+#   define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)\r
+#endif\r
+\r
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+/**\r
+ * @file pah_util.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+\r
+\r
+#define PAH_ARRAY_SIZE(arr)         (sizeof(arr) / sizeof(arr[0]))\r
+\r
+#define PAH_SET_BIT(var,pos)        do { ((var) |= (1 << (pos))); } while(0)\r
+#define PAH_CLEAR_BIT(var,pos)      do { ((var) &= ~(1 << (pos))); } while(0)\r
+#define PAH_CHECK_BIT(var,pos)      (((var) >> (pos)) & 1)\r
+\r
+//\r
+// PAH_SET_BITSLICE\r
+//\r
+// ex1:\r
+//      // var    = 0x00 : 00000000\r
+//      // pos    = 2    :      ^\r
+//      // mask   = 0x3C : 00111100\r
+//      // value  = 0x0D :   1101\r
+//      // ret    = 0x34 : 00110100\r
+//      uint8_t data = 0x00;\r
+//      uint8_t ret = PAH_SET_BITSLICE(data, 2, 0x3C, 0x0D);\r
+//\r
+// ex2:\r
+//      // var    = 0x6D : 01101101\r
+//      // pos    = 6    :  ^\r
+//      // mask   = 0xC0 : 11000000\r
+//      // value  = 0x02 : 10\r
+//      // ret    = 0xAD : 10101101\r
+//      uint8_t data = 0x6D;\r
+//      uint8_t ret = PAH_SET_BITSLICE(data, 6, 0xC0, 0x02);\r
+//\r
+#define PAH_SET_BITSLICE(var, pos, mask, value) \\r
+    ((var & ~mask) | ((value << pos) & mask))\r
+\r
+//\r
+// PAH_GET_BITSLICE\r
+//\r
+// ex1:\r
+//      // var    = 0x5D : 01011101\r
+//      // pos    = 2    :      ^\r
+//      // mask   = 0x3C : 00111100\r
+//      // ret    = 0x07 :   0111\r
+//      uint8_t ret = PAH_GET_BITSLICE(0x5D, 2, 0x3C);\r
+//\r
+// ex2:\r
+//      // var    = 0xA6 : 10100110\r
+//      // pos    = 5    :   ^\r
+//      // mask   = 0xE0 : 11100000\r
+//      // ret    = 0x05 : 101\r
+//      uint8_t ret = PAH_GET_BITSLICE(0xA6, 5, 0xE0);\r
+//\r
+#define PAH_GET_BITSLICE(var, pos, mask) \\r
+    ((var & mask) >> pos)\r
+\r
+#define PAH_UINT64_HIGH(var)        ((uint32_t)(var >> 32))\r
+#define PAH_UINT64_LOW(var)         ((uint32_t)(var & UINT32_MAX))\r
+\r
+#define PAH_UINT16_HIGH(var)        ((uint8_t)(var >> 8))\r
+#define PAH_UINT16_LOW(var)         ((uint8_t)(var & UINT8_MAX))\r
+\r
+#define PAH_UNUSED_VAR(var)         (void)(var)\r
+#define UNUSED_VAR(var)         (void)(var)\r
+  \r
+#ifndef __FILENAME__\r
+#   define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)\r
+#endif\r
+\r
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r
+/**\r
+ * @file pah_reg.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+typedef const uint8_t (pah_reg)[2];\r
+\r
+\r
+typedef struct {\r
+\r
+    pah_reg     *reg_arr;\r
+    uint32_t     reg_arr_len;\r
+    \r
+} pah_reg_arr;\r
+\r
+\r
+#define PAH_REG_ARR_SETUP(pah_reg_arr, reg_array) \\r
+    do { \\r
+        pah_reg_arr.reg_arr     = (pah_reg*)reg_array; \\r
+        pah_reg_arr.reg_arr_len = PAH_ARRAY_SIZE(reg_array); \\r
+    } while(0)\r
+\r
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r
+//============================================================================\r
+// Register address\r
+//============================================================================\r
+\r
+/*#define PAH_800x_ADDR_00_PRODUCT_ID                     (0x00)\r
+#define PAH_800x_ADDR_03                              (0x03)\r
+#define PAH_800x_ADDR_03_BIT_R_PS_EN                    (0)\r
+#define PAH_800x_ADDR_03_BIT_R_ALS_EN                   (1)\r
+#define PAH_800x_ADDR_03_BIT_SW_SUSPEND                 (5)\r
+\r
+#define PAH_800x_ADDR_04                                (0x04)\r
+#define PAH_800x_ADDR_04_BIT_ALS_OVERFLOW_ECO           (7)\r
+\r
+#define PAH_800x_ADDR_09                                (0x09)\r
+#define PAH_800x_ADDR_09_BIT_ALS_INTERRUPT              (2)\r
+#define PAH_800x_ADDR_09_BIT_PS_INTERRUPT               (5)\r
+#define PAH_800x_ADDR_09_BIT_PS_APPROACH                (6)\r
+\r
+#define PAH_800x_ADDR_10_PS_ONOFF_SYNC                  (0x10)\r
+\r
+#define PAH_800x_ADDR_11                                (0x11)\r
+#define PAH_800x_ADDR_11_BIT_R_LED_CONTROL_OUT_EN       (4)\r
+#define PAH_800x_ADDR_11_BIT_R_PS_INTERRUPT_EN          (7)\r
+\r
+#define PAH_800x_ADDR_0E_ALS_LUX_SYNC                   (0x0E)\r
+\r
+#define PAH_800x_ADDR_34                                (0x34)\r
+#define PAH_800x_ADDR_34_BIT_R_EXPOSURE_ALS_F0          (0)\r
+\r
+#define PAH_800x_ADDR_35                                (0x35)\r
+#define PAH_800x_ADDR_35_BIT_R_EXPOSURE_ALS_F0          (0)\r
+\r
+#define PAH_800x_ADDR_38                                (0x38)\r
+#define PAH_800x_ADDR_38_BIT_0_LOCK_EXPOTIME            (0)\r
+#define PAH_800x_ADDR_38_BIT_1_CLEAR_ALS_OVERFLOW_ECO   (1)\r
+\r
+#define PAH_800x_ADDR_EC                                (0xEC)\r
+#define PAH_800x_ADDR_EC_BIT_7_R_CLK_MANUAL             (7)*/\r
+\r
+#define PAH_800x_ADDR_00_PRODUCT_ID                     (0x00)\r
+\r
+#define PAH_800x_ADDR_07_TG                             (0X07)\r
+#define PAH_800x_ADDR_07_TG_BIT_EN                      (0)\r
+\r
+#define PAH_800x_ADDR_20                                (0x20)\r
+#define PAH_800x_ADDR_20_BIT_DR_FLAG                    (0)\r
+#define PAH_800x_ADDR_20_BIT_OVERFLOW_FLAG              (1)\r
+#define PAH_800x_ADDR_20_BIT_TOUCH_FLAG                 (2)\r
+\r
+//expo A Sync\r
+#define PAH_800x_ADDR_2A                                (0x2A)\r
+#define PAH_800x_ADDR_2B                                (0x2B)\r
+\r
+#define PAH_800x_ADDR_35                                (0x35)\r
+#define PAH_800x_ADDR_36                                (0x36)\r
+\r
+#define PAH_800x_ADDR_40                                (0x40)\r
+#define PAH_800x_ADDR_41                                (0x41)\r
+\r
+#define PAH_800x_ADDR_11_EnCh                           (0x11)\r
+\r
+//expo A write\r
+#define PAH_800x_ADDR_17                                (0x17)\r
+#define PAH_800x_ADDR_18                                (0x18)\r
+\r
+#define PAH_800x_ADDR_19                                (0x19)\r
+#define PAH_800x_ADDR_1A                                (0x1A)\r
+\r
+#define PAH_800x_ADDR_1B                                (0x1B)\r
+#define PAH_800x_ADDR_1C                                (0x1C)\r
+\r
+//frame period\r
+\r
+#define PAH_800x_ADDR_2C                                (0x2C)\r
+#define PAH_800x_ADDR_2D                                (0x2D)\r
+\r
+#define PAH_800x_ADDR_37                                (0x37)\r
+#define PAH_800x_ADDR_38                                (0x38)\r
+\r
+#define PAH_800x_ADDR_42                                (0x42)\r
+#define PAH_800x_ADDR_43                                (0x43)\r
+\r
+//adc\r
+\r
+#define PAH_800x_ADDR_2E                                (0x2E)\r
+#define PAH_800x_ADDR_2F                                (0x2F)\r
+\r
+#define PAH_800x_ADDR_39                                (0x39)\r
+#define PAH_800x_ADDR_3A                                (0x3A)\r
+\r
+#define PAH_800x_ADDR_44                                (0x44)\r
+#define PAH_800x_ADDR_45                                (0x45)\r
+\r
+#define PAH_800x_ADDR_27_RAWDATA_A_SYNC                 (0x27)\r
+#define PAH_800x_ADDR_32_RAWDATA_B_SYNC                 (0x32)\r
+#define PAH_800x_ADDR_3D_RAWDATA_C_SYNC                 (0x3D)\r
+\r
+#define PAH_800x_ADDR_E8                                (0xE8)\r
+#define PAH_800x_ADDR_E8_CMD_SUSPEND_MODE_BIT           (0)\r
+\r
+#define PAH_800x_ADDR_EB                                (0xEB)\r
+#define PAH_800x_ADDR_E8_UPDATE_FLAG                    (0x80)\r
+\r
+#define PAH_800x_ADDR_EE                                (0xEE)\r
+#define PAH_800x_ADDR_EE_SW_RESET                       (0x1F)//(0x07)\r
+#define PAH_800x_ADDR_D2                                (0xD2)\r
+#define PAH_800x_ADDR_D2_OD_EnH                        (5)\r
+\r
+#endif  // header guard\r
index 8315e76..3fa48fd 100644 (file)
@@ -9,14 +9,12 @@ set(PUBLIC_HEADER
 ${CMAKE_CURRENT_SOURCE_DIR}
 )
 set(PRIVATE_HEADER
-    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
-    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits
-    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/heartrate/include
 )
 
 set(SOURCES
-${CMAKE_CURRENT_SOURCE_DIR}/ppg_at_cmd.cpp
-${CMAKE_CURRENT_SOURCE_DIR}/ppg_service.cpp
+${CMAKE_CURRENT_SOURCE_DIR}/ppg_at_cmd.c
+${CMAKE_CURRENT_SOURCE_DIR}/ppg_service.c
+${CMAKE_CURRENT_SOURCE_DIR}/ppg_hal.c
 
 )
 
@@ -24,20 +22,8 @@ set(COMPONENT_PUBLIC_CCFLAGS
 )
 
 set(COMPONENT_CCFLAGS
-    -std=c++11
-    -Wno-error
-    -Wno-unused-parameter
-    -fno-exceptions
-    -fno-unwind-tables
-    -fno-asynchronous-unwind-tables
-    -Wno-undef
-    -Wno-bitwise-op-parentheses
-    -Wno-shift-op-parentheses
-    -nostdlibinc
-    -nostdinc
-    -nostdlib
-    -Wno-c++11-narrowing
-    -Wno-error=unused-function
+-Wno-incompatible-function-pointer-types
+-Wno-unused-function
 )
 
 set(WHOLE_LINK
@@ -86,8 +86,11 @@ static uint32_t ppg_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
         md = PPG_SERVICE_CMD_TYPE_FPC_TEST;
     } else if (strcmp(mode, "factory") == 0) {
         md = PPG_SERVICE_CMD_TYPE_FACTORY_TEST;
+    } else if (strcmp(mode, "wear") == 0) {
+        md = PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_TEST;
     }
 
+
     if(enabled == 0 )
     {   
         if (md == PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST)
index a2906e2..876828d 100644 (file)
@@ -6,8 +6,8 @@
  * History: \n
  * 2022-07-20, Create file. \n
  */
-#ifndef HX3695_AT_PROCESS_H
-#define HX3695_AT_PROCESS_H
+#ifndef PPG_AT_PROCESS_H
+#define PPG_AT_PROCESS_H
 
 #include <stdint.h>
 #include <stdio.h>
diff --git a/code/sdk/zhihui/drivers/ppg/service/ppg_hal.c b/code/sdk/zhihui/drivers/ppg/service/ppg_hal.c
new file mode 100644 (file)
index 0000000..0d76760
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-03-13 15:08:38
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-06-04 09:50:09
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
+ * @Description: 
+ * 
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. 
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ppg_hal.h"
+#include "pinctrl_porting.h"
+#include "hal_gpio.h"
+#include "pm_control.h"
+
+
+#include "custom_utils.h"
+
+
+#ifdef PPG_HX3695
+#include "tyhx_hrs_custom.h"
+#include "hx3695.h"
+#endif
+
+#ifdef PPG_PAH8009
+#include "pah800x_main.h"
+#endif
+
+#ifdef SUPPORT_CYWEE_SERVICE
+#include "cywee_service.h"
+#endif
+
+
+// S_AGPIO_L26 心率复位 PPG reset
+#define GPIO_PIN_PRG_RESET S_AGPIO_L26
+// S_AGPIO_R0 PRG_LED_POWER ON  心率等电源控制脚
+#define GPIO_PIN_PRG_LED_ON S_AGPIO_R0
+
+void ppg_power_on(void)
+{
+    // printf("ppg_power_on\n");
+    uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_HIGH);
+   
+    uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_HIGH);
+    LOS_Mdelay(50);
+}
+
+void ppg_power_off(void)
+{
+    // printf("ppg_power_off\n");
+    uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_LOW);
+   
+    uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
+    uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_LOW);
+    LOS_Mdelay(50);
+}
+
+uint8_t ppg_get_hrs(void)
+{
+    uint8_t hrs = 0;
+#ifdef PPG_HX3695
+    hrs = hx3695_get_hrs();
+    // printf("ppg_get_hrs : %d\n",hrs);
+#endif
+    return hrs;
+}
+
+uint8_t ppg_get_spo2(void)
+{
+    uint8_t spo2 = 0;
+#ifdef PPG_HX3695
+    spo2 = hx3695_get_spo2();
+#endif
+    return spo2;
+}
+
+uint8_t ppg_get_wear_status(void)
+{
+    uint8_t wear_status = 0;
+#ifdef PPG_HX3695
+    wear_status = hx3695_get_wear_status();
+#endif
+    return wear_status;
+}
+
+uint16_t ppg_get_chip_id(void)
+{
+    uint16_t chip_id = 0;
+#ifdef PPG_HX3695
+    chip_id = hx3695_chip_check();
+#elif defined PPG_PAH8009
+    chip_id = pah8009_get_chip_id();
+#endif
+    return chip_id;
+}
+
+void ppg_timer_handler(uint8_t mode)
+{
+    // printf("ppg_agc_timer_handler\n");
+#ifdef PPG_HX3695
+    if(mode == AGC_TIMER_MODE)
+        agc_timeout_handler(NULL);
+    else if(mode == HRS_TIMER_MODE)
+        heart_rate_meas_timeout_handler(NULL);
+    else if(mode == WEAR_TIMER_MODE)
+        wear_mode_timeout_handler(NULL);
+#elif defined PPG_PAH8009
+    pah8009_timer_handler();
+#endif
+}
+
+
+void ppg_int_handler(void)
+{
+#ifdef PPG_PAH8009
+    pah8009_int_handler();
+#endif
+}
+
+void ppg_send_cmd_to_driver(char* mode, uint8_t enable)
+{
+    // printf("ppg_send_cmd_to_driver \n");
+    if(enable)
+        ppg_power_on();
+#ifdef PPG_HX3695
+    hx3695_control(mode,enable);
+#elif defined PPG_PAH8009
+    pah8009_control(mode,enable);
+#endif
+    if(!enable)
+        ppg_power_off();
+}
+
+void ppg_get_leaklight_data(uint32_t *ch0,uint32_t *ch1,uint32_t *ch2)
+{
+#ifdef PPG_HX3695
+    FT_RESULTS_t ft_result = hx3695_factroy_test(LEAK_LIGHT_TEST);
+    *ch0 = ft_result.gr_data_final;
+    *ch1 = ft_result.red_data_final;
+    *ch2 = ft_result.ir_data_final;
+#elif defined PPG_VC9202
+    vc9202_get_leaklight_data(ch0,ch1,ch2);
+#elif defined PPG_PAH8009
+    pah8009_get_leaklight_data(ch0,ch1,ch2);
+#endif
+}
+
+uint32_t ppg_get_factory_data(void)
+{
+    uint32_t data = 0;
+#ifdef PPG_PAH8009  
+    data =  pah8009_get_factory_data();
+#endif
+    return data;
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/service/ppg_hal.h b/code/sdk/zhihui/drivers/ppg/service/ppg_hal.h
new file mode 100644 (file)
index 0000000..35f5431
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-06-07 11:18:26
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-30 15:49:50
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.h
+ * @Description: 
+ * 
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved. 
+ */
+#ifndef PPG_HAL_H__
+#define PPG_HAL_H__
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "tyhx_hrs_custom.h"
+
+#define AGC_TIMER_MODE 0
+#define HRS_TIMER_MODE 1
+#define WEAR_TIMER_MODE 2
+
+#ifdef PPG_HX3695
+#define PPG_CHIP_ID 0x65
+#elif defined PPG_PAH8009
+#define PPG_CHIP_ID 0x8008
+#else
+#define PPG_CHIP_ID 0
+#endif
+
+typedef uint32_t PPG_CMD_TYPE_T ;
+
+void ppg_send_cmd_to_driver(char* mode, uint8_t enable);
+void ppg_timer_handler(uint8_t mode);
+uint16_t ppg_get_chip_id(void);
+uint8_t ppg_get_hrs(void);
+uint8_t ppg_get_spo2(void);
+uint8_t ppg_get_wear_status(void);
+void ppg_wear_status_update(uint8_t status);
+void ppg_power_on(void);
+void ppg_power_off(void);
+void ppg_int_handler(void);
+void ppg_get_leaklight_data(uint32_t *ch0,uint32_t *ch1,uint32_t *ch2);
+uint32_t ppg_get_factory_data(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/service/ppg_service.c b/code/sdk/zhihui/drivers/ppg/service/ppg_service.c
new file mode 100644 (file)
index 0000000..3fa8f5b
--- /dev/null
@@ -0,0 +1,343 @@
+
+#include "pinctrl.h"
+#include "debug_print.h"
+#include "soc_osal.h"
+#include "tcxo.h"
+#include "irmalloc.h"
+#include "errcode.h"
+#include "common_def.h"
+#include "chip_core_irq.h"
+#include "chip_io.h"
+#include "gpio.h"
+#include "pm_veto.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+#include "cmsis_os2.h"
+#include "ppg_service.h"
+#include "los_printf.h"
+#include "thread_init.h"
+#include "custom_utils.h"
+#include "custom_save_runtime.h"
+#include "ppg_hal.h"
+
+#ifdef PPG_HX3695
+#include "hx3695.h"
+#endif
+
+#if defined(PPG_VC9202)
+#include "vc9202_hal.h"
+#include "vc9202_user.h"
+#elif  defined(PPG_VC921X)
+#include "vc921x_hal.h"
+#include "vc921x_user_app.h"
+#elif  defined(PPG_GH3X2X)
+#include "gh3x2x_hal.h"
+#include "gh3x2x_afe_drv.h"
+#else
+#endif
+
+static bool g_ppg_service_initialled = false;
+
+uint8_t card_databuf[64] = {0};
+uint8_t light_databuf[64] = {0};
+
+osTimerId_t g_ppg_service_timer = NULL;
+
+
+/***
+ * 其他cmd在Header里定义,对外开放
+*/
+
+
+#define PPG_SERVICE_MSG_COUNT       16
+#define PPG_SERVICE_TASK_SIZE       0x1000
+#define PPG_SERVICE_TASK_PRIO       5
+
+#define MAG_CHECK_MS 20
+static unsigned long g_app_queue= 0xFFFFFFFF;
+
+static bool ppg_service_running_stat = false;
+static bool ppg_sensor_exist = false;
+
+static uint8_t wear_mode_state = 0;
+static uint8_t keep_in_wear_det_mod = 1; //持续坚持 佩戴检测模式
+
+
+void set_keep_in_wear_det_mode(uint8_t mod)
+{
+    keep_in_wear_det_mod = mod;
+}
+
+
+void uapi_ppg_service_deinit(void)
+{
+    ppg_service_running_stat = false;
+}
+
+uint32_t ppg_suspend(void)
+{
+    return custom_i2c_suspend();
+}
+uint32_t ppg_resume(void)
+{
+    return custom_i2c_resume();
+}
+
+
+errcode_t send_ppg_cmd_msg(int cmd)
+{
+    errcode_t ret;
+    if (ppg_sensor_exist == false)
+        return OSAL_FAILURE;
+
+    // printf("send_ppg_cmd_msg cmd : 0x%x\n",cmd);
+    
+    PPG_CMD_TYPE_T mail = 0;
+    mail = cmd;
+    ret = osal_msg_queue_write_copy(g_app_queue, (void *)&mail,
+                                    sizeof(PPG_CMD_TYPE_T), 0);
+    if (ret != OSAL_SUCCESS) {
+        PRINT("Error ppg Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret);
+    }
+    return ret;
+}
+
+static void ppg_service_check_task(void  *arg)
+{
+    unused(arg);
+    int32_t ret;
+    uint32_t mail;
+    uint32_t msgsize = (uint32_t)sizeof(PPG_CMD_TYPE_T);
+
+    while (1) {
+        ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize,
+                                       OSAL_MSGQ_WAIT_FOREVER);
+        if (ret != OSAL_SUCCESS) {
+            continue;
+        }
+        if((wear_mode_state == 1) && (mail > 0x10) && mail != PPG_SERVICE_CMD_TYPE_STOP_WEAR_MODE_TEST)
+        {
+#ifdef PPG_HX3695
+            // uapi_save_runtime_log(RUNTIME_LOG_WEAR_MIN_STOP);
+            wear_mode_state = 0;
+
+            ppg_send_cmd_to_driver("wear",0);
+            ppg_service_running_stat = false;
+#endif
+        }
+        char* cmd = "hrs";
+        int enable = 1;
+        if (mail == PPG_SERVICE_CMD_TYPE_DO_PPG_HRS_TIMER_CALLBACK){
+// #ifdef PPG_HX3695
+//         heart_rate_meas_timeout_handler(NULL);
+// #endif
+            // ppg_hrs_timer_handler();
+            ppg_timer_handler(HRS_TIMER_MODE);
+            continue;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_PPG_AGC_TIMER_CALLBACK){
+// #ifdef PPG_HX3695
+//             agc_timeout_handler(NULL);
+// #endif
+            ppg_timer_handler(AGC_TIMER_MODE);
+            continue;
+        }else if(mail == PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_TIMER_CALLBACK){
+// #ifdef PPG_HX3695
+//             wear_mode_timeout_handler(NULL);
+// #endif
+            // ppg_wear_timer_handler();
+            ppg_timer_handler(WEAR_TIMER_MODE);
+            continue;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_PPG_TEST){
+            //do_cywee_service_check_msg(CYWEE_SERVICE_CMD_OPEN_GET_ACC,NULL);
+            // uapi_save_runtime_log(RUNTIME_LOG_HEART_DRIVER_MEASURE);
+            cmd = "hrs";
+            enable = 1;
+            // uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);
+            // if (cnt == 0) 
+            // {
+            //     uapi_pm_add_sleep_veto(PM_ID_HEART);
+            // }
+
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_HRV_TEST){
+            cmd = "hrv";
+            enable = 1;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST){
+            cmd = "spo2";
+            enable = 1;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST){
+            cmd = "leaklight";
+            enable = 1;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_GRAYCARD_TEST){
+            cmd = "graycard";
+            enable = 1;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_TEST){
+            if (keep_in_wear_det_mod == 0) continue;;
+            // uapi_save_runtime_log(RUNTIME_LOG_WEAR_MIN_START);
+            cmd = "wear";
+            enable = 1;
+            wear_mode_state = 1;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_LED_OFF_MODE_TEST){
+            cmd = "ledoff";
+            enable = 0;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST){
+            cmd = "single";
+            enable = 1;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_STOP_WEAR_MODE_TEST){
+            if (keep_in_wear_det_mod == 0) continue;
+            cmd = "wear";
+            enable = 0;
+            wear_mode_state = 0;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST){
+            // uapi_save_runtime_log(RUNTIME_LOG_HEART_DRIVER_MEASURE_END);
+            cmd = "hrs";
+            enable = 0;
+            // uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);
+            // if (cnt == 1) 
+            // {
+            //     uapi_pm_remove_sleep_veto(PM_ID_HEART);
+            // }
+        }else if (mail == PPG_SERVICE_CMD_TYPE_STOP_SPO2_TEST){
+   
+            cmd = "spo2";
+            enable = 0;
+        }
+        else if (mail == PPG_SERVICE_CMD_TYPE_OPEN_HRS_BLE)
+        {
+#ifdef PPG_HX3695
+            // hx3695_set_hrs_ble_swtich(1);
+#endif
+            continue ;
+        }
+        else if (mail == PPG_SERVICE_CMD_TYPE_CLOSE_HRS_BLE)
+        {
+#ifdef PPG_HX3695
+            // hx3695_set_hrs_ble_swtich(0);
+#endif
+            continue ;
+        }else if (mail == PPG_SERVICE_CMD_TYPE_INT_HANDLER){
+// #ifdef PPG_VC9202
+//             vc9202_usr_interrupt_handler(SPORT_TYPE_NORMAL,0);
+// #elif defined PPG_VC921X
+//             cmd = "int";
+//             enable = 1;
+//             ppg_send_cmd_to_vc921x_driver(cmd,enable);
+// #elif defined PPG_GH3X2X
+//             hal_gh3x2x_afe_int_handler_call_back();
+//             GH3X2X_AFE_ChipPro();
+// #elif defined PPG_PAH8009
+//             hal_gh3x2x_afe_int_handler_call_back();
+//             GH3X2X_AFE_ChipPro();
+// #endif
+            ppg_int_handler();
+            continue;
+        }
+        else if (mail == PPG_SERVICE_CMD_TYPE_FPC_TEST){
+#ifdef PPG_VC9202
+            cmd = "fpc";
+            enable = 1;
+#endif
+        }
+        else if (mail == PPG_SERVICE_CMD_TYPE_FACTORY_TEST){
+#ifdef PPG_VC9202
+            cmd = "factory";
+            enable = 1;
+#endif
+        }
+        if (ppg_service_running_stat == true && enable ==1 )
+        {
+            PRINT_ERR("ppg service already started! \r\n");
+            continue ;
+        }else if ( ppg_service_running_stat == false && enable == 0 )
+        {
+            PRINT_ERR("ppg service already stopped! \r\n");
+            continue ;
+        }
+
+    ppg_send_cmd_to_driver(cmd,enable);
+
+    if(enable == 1)
+        ppg_service_running_stat = true;
+    else
+        ppg_service_running_stat = false;
+
+#ifdef PPG_HX3695
+    if((strcmp(cmd, "wear") != 0) && (enable == 0))
+    {
+        if (keep_in_wear_det_mod == 1)
+        {
+            uapi_save_runtime_log(RUNTIME_LOG_WEAR_MIN_START);
+            ppg_send_cmd_to_driver("wear",1);
+            wear_mode_state = 1;
+            ppg_service_running_stat = true;
+        }
+    }
+#endif
+
+    }
+
+}
+void create_ppg_queue(void)
+{
+    if (osal_msg_queue_create("ppg_service_queue", PPG_SERVICE_MSG_COUNT, &g_app_queue,
+                              0, sizeof(PPG_CMD_TYPE_T)) != ERRCODE_SUCC) {
+        PRINT_ERR("[ppg][service] app create mail fail\n");
+    }
+}
+errcode_t uapi_ppg_service_init(void)
+{
+    PRINT("uapi_ppg_service_init !\r\n");
+
+    ppg_power_on();
+
+    if (ppg_get_chip_id() != PPG_CHIP_ID)
+    {
+        //TODO 没找到3695,退出线程
+        PRINT("ppg not exist!\r\n");
+        ppg_power_off();
+        return ERRCODE_FAIL;
+    }
+
+    ppg_power_off();
+
+    ppg_sensor_exist = true;
+
+    app_task_definition_t taskcfg={0};
+    taskcfg.create_queue_handle = create_ppg_queue;
+    taskcfg.attr.name="ppg_service";
+    taskcfg.attr.priority = osPriorityBelowNormal4;
+    taskcfg.attr.stack_size = PPG_SERVICE_TASK_SIZE;
+    taskcfg.func = ppg_service_check_task;
+    taskcfg.use_mem = USE_EXTEND_MEM;
+    
+    errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+    if(ret != ERRCODE_SUCC)
+    {
+        PRINT("create ppg_service failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+
+
+    // g_ppg_service_timer = osTimerNew((osTimerFunc_t)ppg_int_callback, osTimerPeriodic, NULL, NULL);
+
+    return ERRCODE_SUCC;
+}
+
+void ppg_int_callback(pin_t pin, uintptr_t param)
+{
+    uapi_gpio_clear_interrupt(pin);
+    // uint32_t tm;
+    // uapi_get_timestampe_ms(&tm);
+    // PRINT("ppg_int_callback %d 0x%X   tm : %d \n",pin,param,tm);
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_INT_HANDLER);
+}
+// void ppg_service_service_resume(void)
+// {
+//     DEBUG_PRINTF("ppg_service_service resume!\r\n");
+//     ppg_service_check_timer_callback(0);
+// }
+// void ppg_service_service_suspend(void)
+// {
+//     DEBUG_PRINTF("ppg_service_service suspend!\r\n");
+// }
+
diff --git a/code/sdk/zhihui/drivers/ppg/service/ppg_service.cpp b/code/sdk/zhihui/drivers/ppg/service/ppg_service.cpp
deleted file mode 100644 (file)
index 72492c7..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/**
- * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
- *
- * Description: Test  source \n
- * Author: @CompanyNameTag \n
- * History: \n
- * 2022-08-16, Create file. \n
- */
-
-#include "wearable_log.h"
-#include "securec.h"
-#include "broadcast_service.h"
-#include "broadcast_feature.h"
-#include "service_id_define.h"
-#include "samgr_lite.h"
-#include "thread_adapter.h"
-#include "graphic_service.h"
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
-#include "pinctrl.h"
-#include "debug_print.h"
-#include "soc_osal.h"
-#include "tcxo.h"
-#include "irmalloc.h"
-#include "errcode.h"
-#include "common_def.h"
-
-#include "chip_core_irq.h"
-#include "chip_io.h"
-#include "gpio.h"
-#include "pm_veto.h"
-
-#include "rtc.h"
-#include "timer.h"
-#include "systick.h"
-#include "cmsis_os2.h"
-#include "ppg_service.h"
-#include "los_printf.h"
-
-#include "thread_init.h"
-#include "custom_utils.h"
-#include "custom_save_runtime.h"
-
-#if defined(PPG_VC9202)
-#include "vc9202_hal.h"
-#include "vc9202_user.h"
-#elif  defined(PPG_VC921X)
-#include "vc921x_hal.h"
-#include "vc921x_user_app.h"
-#elif  defined(PPG_GH3X2X)
-#include "gh3x2x_hal.h"
-#include "gh3x2x_afe_drv.h"
-#else
-#include "hx3695_hal.h"
-#include "hx3695.h"
-#endif
-
-static bool g_ppg_service_initialled = false;
-
-uint8_t card_databuf[64] = {0};
-uint8_t light_databuf[64] = {0};
-
-osTimerId_t g_ppg_service_timer = NULL;
-
-
-/***
- * 其他cmd在Header里定义,对外开放
-*/
-
-
-#define PPG_SERVICE_MSG_COUNT       16
-#define PPG_SERVICE_TASK_SIZE       0x1000
-#define PPG_SERVICE_TASK_PRIO       5
-
-#define MAG_CHECK_MS 20
-static unsigned long g_app_queue= 0xFFFFFFFF;
-
-static bool ppg_service_running_stat = false;
-static bool ppg_sensor_exist = false;
-
-static uint8_t wear_mode_state = 0;
-static uint8_t keep_in_wear_det_mod = 1; //持续坚持 佩戴检测模式
-
-
-void set_keep_in_wear_det_mode(uint8_t mod)
-{
-    keep_in_wear_det_mod = mod;
-}
-
-#ifdef PPG_HX3695
-//漏光测试
-errcode_t update_leaklight_event_notify(uint8_t *data)
-{
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "send lightdata to ui %s",data);
-    CustomEventPublish(TOPIC_EVENT_LEAKLIGHT_UPDATA,(uint8_t*)data,strlen((char*)data));
-    return 0;
-}
-errcode_t update_leaklight_event_sendmsg_toUI(uint8_t *data)
-{
-    /**通过UI事件发送Notify*/
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_leaklight_event_notify, data));
-    return ERRCODE_SUCC;
-}
-
-
-//灰卡测试
-errcode_t update_graycard_event_notify(uint8_t *data)
-{
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "send carddata to ui %s",data);
-    CustomEventPublish(TOPIC_EVENT_GRAYCARD_UPDATA,(uint8_t*)data,strlen((char*)data));
-    return 0;
-}
-errcode_t update_graycard_event_sendmsg_toUI(uint8_t *data)
-{
-    /**通过UI事件发送Notify*/
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_graycard_event_notify, data));
-    return ERRCODE_SUCC;
-}
-
-
-//血氧
-errcode_t update_spo2_event_notify(uint8_t spo2)
-{
-    CustomEventPublish(TOPIC_EVENT_SPO2_UPDATE,(uint8_t*)&spo2,sizeof(spo2));
-    return 0;
-}
-errcode_t update_spo2_event_sendmsg_toUI(uint8_t spo2)
-{
-    /**通过UI事件发送Notify*/
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_spo2_event_notify, spo2));
-    return ERRCODE_SUCC;
-}
-
-//心率
-errcode_t update_hrs_event_notify(uint8_t hrs)
-{
-    CustomEventPublish(TOPIC_EVENT_HEARTRATE_UPDATA,(uint8_t*)&hrs,sizeof(hrs));
-    return 0;
-}
-errcode_t update_hrs_event_sendmsg_toUI(uint8_t hrs)
-{
-    /**通过UI事件发送Notify*/
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_hrs_event_notify, hrs));
-    return ERRCODE_SUCC;
-}
-
-
-//穿戴状态
-errcode_t update_wearstatus_event_notify(int32_t wearstatus)
-{
-    CustomEventPublish(TOPIC_EVENT_WEARSTATE_UPDATE,(uint8_t*)&wearstatus,sizeof(wearstatus));
-    return 0;
-}
-errcode_t update_wearstatus_event_sendmsg_toUI(int32_t wearstatus)
-{
-    /**通过UI事件发送Notify*/
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_wearstatus_event_notify, wearstatus));
-    return ERRCODE_SUCC;
-}
-
-//静息心率
-errcode_t update_static_hrs_event_notify(int32_t hrs)
-{
-    CustomEventPublish(TOPIC_EVENT_STATIC_HEARTRATE_UPDATA,(uint8_t*)&hrs,sizeof(hrs));
-    return 0;
-}
-errcode_t update_static_hrs_event_sendmsg_toUI(int32_t hrs)
-{
-    /**通过UI事件发送Notify*/
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_static_hrs_event_notify, hrs));
-    return ERRCODE_SUCC;
-}
-
-#include "hx3695_hal.h"
-#include "hx3695.h"
-void hx3695_msg_callback(uint8_t msg_type, uint8_t *msg_data, int32_t msg_datalen)
-{
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "hx3695_msg_callback");
-    FT_CUSTOM_RESULTS_t sensor_data; // 使用更通用的名称 sensor_data
-#if 1
-    if (msg_datalen < sizeof(FT_CUSTOM_RESULTS_t)) {
-        // 数据长度不足以填充整个结构体
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Invalid data length for SPO2 update");
-        //return;
-    }
-#endif
-    memcpy(&sensor_data, msg_data, sizeof(FT_CUSTOM_RESULTS_t));
-    switch(msg_type)
-    {
-        case HX3695_MSG_TYPE_HRS_UPDATE:
-           //每秒心率
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_HRS_UPDATE = %d", sensor_data.lastesthrs);
-            update_hrs_event_sendmsg_toUI(sensor_data.lastesthrs);
-            break;
-        case HX3695_MSG_TYPE_HRV_UPDATE:
-            break;
-        case HX3695_MSG_TYPE_SPO2_UPDATE:
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_SPO2_UPDATE = %d", sensor_data.lastestspo2);
-            update_spo2_event_sendmsg_toUI(sensor_data.lastestspo2);
-            break;
-        case HX3695_MSG_TYPE_LEAKLIGHT_UPDATE:
-            memset_s(light_databuf,64,0,64);
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "LEAKLIGHT_UPDATE");
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_leak_green_UPDATE = %d", sensor_data.leak_green);
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_leak_red_UPDATE = %d", sensor_data.leak_red);
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_leak_ir_UPDATE = %d", sensor_data.leak_ir);
-            sprintf((char *)light_databuf,"%d,%d,%d",sensor_data.leak_green,sensor_data.leak_red,sensor_data.leak_ir);
-            update_leaklight_event_sendmsg_toUI(light_databuf);
-            break;
-        case HX3695_MSG_TYPE_GRAYCARD_UPDATE:
-            memset_s(card_databuf,64,0,64);
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GRAYCARD_UPDATE");
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_card_green_UPDATE = %d", sensor_data.card_green);
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_card_red_UPDATE = %d", sensor_data.card_red);
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_card_ir_UPDATE = %d", sensor_data.card_ir);
-            sprintf((char *)card_databuf,"%d,%d,%d",sensor_data.card_green,sensor_data.card_red,sensor_data.card_ir);
-            update_graycard_event_sendmsg_toUI(card_databuf);
-            break;
-        case HX3695_MSG_TYPE_WEARSTAT_UPDATE:
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_WEARSTATUS_UPDATE = %d", sensor_data.wearstatus);
-            update_wearstatus_event_sendmsg_toUI(sensor_data.wearstatus);
-            break;
-        case HX3695_MSG_TYPE_STATIC_HRS_UPDATE:
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_STATIC_HRS_UPDATE = %d", sensor_data.lastesthrs);
-            update_static_hrs_event_sendmsg_toUI(sensor_data.lastesthrs);
-            break;
-        default:
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Unknown sensor message type");
-            break;
-    }
-}
-
-#endif
-
-void uapi_ppg_service_deinit(void)
-{
-    ppg_service_running_stat = false;
-}
-
-uint32_t ppg_suspend(void)
-{
-    return custom_i2c_suspend();
-}
-uint32_t ppg_resume(void)
-{
-    return custom_i2c_resume();
-}
-
-
-errcode_t send_ppg_cmd_msg(int cmd)
-{
-    errcode_t ret;
-    if (ppg_sensor_exist == false)
-        return OSAL_FAILURE;
-
-    PPG_CMD_TYPE_T mail = 0;
-    mail = cmd;
-    ret = osal_msg_queue_write_copy(g_app_queue, (void *)&mail,
-                                    sizeof(PPG_CMD_TYPE_T), 0);
-    if (ret != OSAL_SUCCESS) {
-        PRINT_ERR("Error ppg Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret);
-    }
-    return ret;
-}
-
-static void ppg_service_check_task(void  *arg)
-{
-    unused(arg);
-    int32_t ret;
-    uint32_t mail;
-    uint32_t msgsize = (uint32_t)sizeof(PPG_CMD_TYPE_T);
-
-    while (1) {
-        ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize,
-                                       OSAL_MSGQ_WAIT_FOREVER);
-        if (ret != OSAL_SUCCESS) {
-            continue;
-        }
-        if((wear_mode_state == 1) && (mail > 0x10) && mail != PPG_SERVICE_CMD_TYPE_STOP_WEAR_MODE_TEST)
-        {
-            uapi_save_runtime_log(RUNTIME_LOG_WEAR_MIN_STOP);
-            wear_mode_state = 0;
-#ifdef PPG_HX3695
-            ppg_send_cmd_to_driver("wear",0);
-#endif
-            ppg_service_running_stat = false;
-        }
-        char* cmd = "hrs";
-        int enable = 1;
-        if (mail == PPG_SERVICE_CMD_TYPE_DO_PPG_320TIMER_CALLBACK){
-#ifdef PPG_HX3695
-            heart_rate_meas_timeout_handler(NULL);
-#endif
-            continue;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_PPG_40TIMER_CALLBACK){
-#ifdef PPG_HX3695
-            agc_timeout_handler(NULL);
-#endif
-            continue;
-        }else if(mail == PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_5000TIMER_CALLBACK){
-#ifdef PPG_HX3695
-            wear_mode_timeout_handler(NULL);
-#endif
-            continue;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_PPG_TEST){
-            //do_cywee_service_check_msg(CYWEE_SERVICE_CMD_OPEN_GET_ACC,NULL);
-            uapi_save_runtime_log(RUNTIME_LOG_HEART_DRIVER_MEASURE);
-            cmd = "hrs";
-            enable = 1;
-            // uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);
-            // if (cnt == 0) 
-            // {
-            //     uapi_pm_add_sleep_veto(PM_ID_HEART);
-            // }
-
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_HRV_TEST){
-            cmd = "hrv";
-            enable = 1;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST){
-            cmd = "spo2";
-            enable = 1;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST){
-            cmd = "leaklight";
-            enable = 1;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_GRAYCARD_TEST){
-            cmd = "graycard";
-            enable = 1;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_TEST){
-            if (keep_in_wear_det_mod == 0) continue;;
-            uapi_save_runtime_log(RUNTIME_LOG_WEAR_MIN_START);
-            cmd = "wear";
-            enable = 1;
-            wear_mode_state = 1;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_LED_OFF_MODE_TEST){
-            cmd = "ledoff";
-            enable = 0;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST){
-            cmd = "single";
-            enable = 1;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_STOP_WEAR_MODE_TEST){
-            if (keep_in_wear_det_mod == 0) continue;
-            cmd = "wear";
-            enable = 0;
-            wear_mode_state = 0;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST){
-            uapi_save_runtime_log(RUNTIME_LOG_HEART_DRIVER_MEASURE_END);
-            cmd = "hrs";
-            enable = 0;
-            // uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);
-            // if (cnt == 1) 
-            // {
-            //     uapi_pm_remove_sleep_veto(PM_ID_HEART);
-            // }
-        }else if (mail == PPG_SERVICE_CMD_TYPE_STOP_SPO2_TEST){
-   
-            cmd = "spo2";
-            enable = 0;
-        }
-        else if (mail == PPG_SERVICE_CMD_TYPE_OPEN_HRS_BLE)
-        {
-#ifdef PPG_HX3695
-            hx3695_set_hrs_ble_swtich(1);
-#endif
-            continue ;
-        }
-        else if (mail == PPG_SERVICE_CMD_TYPE_CLOSE_HRS_BLE)
-        {
-#ifdef PPG_HX3695
-            hx3695_set_hrs_ble_swtich(0);
-#endif
-            continue ;
-        }else if (mail == PPG_SERVICE_CMD_TYPE_INT_HANDLER){
-#ifdef PPG_VC9202
-            vc9202_usr_interrupt_handler(SPORT_TYPE_NORMAL,0);
-#elif defined PPG_VC921X
-            cmd = "int";
-            enable = 1;
-            ppg_send_cmd_to_vc921x_driver(cmd,enable);
-#elif defined PPG_GH3X2X
-            hal_gh3x2x_afe_int_handler_call_back();
-            GH3X2X_AFE_ChipPro();
-#endif
-            continue;
-        }
-        else if (mail == PPG_SERVICE_CMD_TYPE_FPC_TEST){
-#ifdef PPG_VC9202
-            cmd = "fpc";
-            enable = 1;
-#endif
-        }
-        else if (mail == PPG_SERVICE_CMD_TYPE_FACTORY_TEST){
-#ifdef PPG_VC9202
-            cmd = "factory";
-            enable = 1;
-#endif
-        }
-        if (ppg_service_running_stat == true && enable ==1 )
-        {
-            PRINT_ERR("ppg service already started! \r\n");
-            continue ;
-        }else if ( ppg_service_running_stat == false && enable == 0 )
-        {
-            PRINT_ERR("ppg service already stopped! \r\n");
-            continue ;
-        }
-
-#ifdef PPG_VC9202
-       ppg_send_cmd_to_vc9202_driver(cmd,enable);
-#elif defined(PPG_VC921X)
-    ppg_send_cmd_to_vc921x_driver(cmd,enable);
-#elif defined(PPG_GH3X2X)
-    ppg_send_cmd_to_gh3x2x_driver(cmd,enable);
-#endif
-
-    if(enable == 1)
-        ppg_service_running_stat = true;
-    else
-        ppg_service_running_stat = false;
-
-    if((strcmp(cmd, "wear") != 0) && (enable == 0))
-    {
-        if (keep_in_wear_det_mod == 1)
-        {
-            uapi_save_runtime_log(RUNTIME_LOG_WEAR_MIN_START);
-#ifdef PPG_HX3695
-            ppg_send_cmd_to_driver("wear",1);
-#endif
-            wear_mode_state = 1;
-            ppg_service_running_stat = true;
-        }
-    }
-
-    }
-
-}
-void create_ppg_queue(void)
-{
-    if (osal_msg_queue_create("ppg_service_queue", PPG_SERVICE_MSG_COUNT, &g_app_queue,
-                              0, sizeof(PPG_CMD_TYPE_T)) != ERRCODE_SUCC) {
-        PRINT_ERR("[ppg][service] app create mail fail\n");
-    }
-}
-errcode_t uapi_ppg_service_init(void)
-{
-   
-
-    PRINT("uapi_ppg_service_init !\r\n");
-
-    tyhx_poweron();
-
-#ifdef PPG_HX3695
-
-    if ( hx3695_chip_check() == false)
-    {
-        //TODO 没找到3695,退出线程
-        PRINT("3695 not exist!\r\n");
-        tyhx_poweroff();
-        return ERRCODE_FAIL;
-    }
-    hx3695_register_msg_callback(hx3695_msg_callback);//注册驱动回调
-    // //ppg_send_cmd_to_driver("wear",0);
-#elif defined(PPG_VC9202)
-    if ( vc9202_drv_get_chip_id() != 0x21)
-    {
-        //TODO 没找到3695,退出线程
-        PRINT("PPG_VC9202 not exist!\r\n");
-        tyhx_poweroff();
-        return ERRCODE_FAIL;
-    }
-#elif defined(PPG_GH3X2X)
-    if (GH3X2X_AFE_CheckChipId() != 0)
-    {
-        //TODO 没找到3695,退出线程
-        PRINT("PPG_GH3X2X not exist!\r\n");
-        tyhx_poweroff();
-        return ERRCODE_FAIL;
-    }
-#endif
-
-    tyhx_poweroff();
-
-    ppg_sensor_exist = true;
-
-    app_task_definition_t taskcfg={0};
-    taskcfg.create_queue_handle = create_ppg_queue;
-    taskcfg.attr.name="ppg_service";
-    taskcfg.attr.priority = osPriorityBelowNormal4;
-    taskcfg.attr.stack_size = PPG_SERVICE_TASK_SIZE;
-    taskcfg.func = ppg_service_check_task;
-    taskcfg.use_mem = USE_EXTEND_MEM;
-    
-    errcode_t ret=uapi_create_osThread_custom(&taskcfg);
-    if(ret != ERRCODE_SUCC)
-    {
-        PRINT("create ppg_service failed %d!\r\n",ret);
-        return ERRCODE_FAIL;
-    }
-
-
-    // g_ppg_service_timer = osTimerNew((osTimerFunc_t)ppg_int_callback, osTimerPeriodic, NULL, NULL);
-
-    return ERRCODE_SUCC;
-}
-
-void ppg_int_callback(pin_t pin, uintptr_t param)
-{
-    uapi_gpio_clear_interrupt(pin);
-    uint32_t tm;
-    uapi_get_timestampe_ms(&tm);
-    // PRINT("ppg_int_callback %d 0x%X   tm : %d \n",pin,param,tm);
-    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_INT_HANDLER);
-}
-// void ppg_service_service_resume(void)
-// {
-//     DEBUG_PRINTF("ppg_service_service resume!\r\n");
-//     ppg_service_check_timer_callback(0);
-// }
-// void ppg_service_service_suspend(void)
-// {
-//     DEBUG_PRINTF("ppg_service_service suspend!\r\n");
-// }
-
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
index 012a1d8..a7aa9ab 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-27 09:07:00
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-01-06 16:57:23
+ * @LastEditTime: 2025-05-30 14:44:51
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/service/ppg_service.h
  * @Description: 
  * 
@@ -30,9 +30,10 @@ extern "C" {
 #include "errcode.h"
 #include "platform_core.h"
 
-#define PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_5000TIMER_CALLBACK 0x09
-#define PPG_SERVICE_CMD_TYPE_DO_PPG_40TIMER_CALLBACK 0x0A
-#define PPG_SERVICE_CMD_TYPE_DO_PPG_320TIMER_CALLBACK 0x10
+#define PPG_SERVICE_CMD_TYPE_INT_HANDLER 0x08
+#define PPG_SERVICE_CMD_TYPE_DO_WEAR_MODE_TIMER_CALLBACK 0x09
+#define PPG_SERVICE_CMD_TYPE_DO_PPG_AGC_TIMER_CALLBACK 0x0A
+#define PPG_SERVICE_CMD_TYPE_DO_PPG_HRS_TIMER_CALLBACK 0x10
 #define PPG_SERVICE_CMD_TYPE_DO_PPG_TEST 0x11
 #define PPG_SERVICE_CMD_TYPE_DO_HRV_TEST 0x12
 #define PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST 0x13
@@ -46,7 +47,6 @@ extern "C" {
 #define PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST 0x23
 #define PPG_SERVICE_CMD_TYPE_OPEN_HRS_BLE 0x24
 #define PPG_SERVICE_CMD_TYPE_CLOSE_HRS_BLE 0x25
-#define PPG_SERVICE_CMD_TYPE_INT_HANDLER 0x26
 #define PPG_SERVICE_CMD_TYPE_FPC_TEST 0x27
 #define PPG_SERVICE_CMD_TYPE_FACTORY_TEST 0x28
 
index 5e2d234..815e806 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-13 15:08:38
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2024-12-24 10:25:14
+ * @LastEditTime: 2025-05-15 17:15:13
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
  * @Description: 
  * 
 #endif
 
 #ifdef PPG_HX3695
-#include "tyhx_hrs_custom.h"
-#include "hx3695.h"
-#include "hx3695_hal.h"
-#include "hx3695.h"
 
 
 hx3695_msg_callback_t g_send_msg_toUI = NULL;
@@ -156,7 +152,7 @@ void ppg_send_cmd_to_vc9202_driver(char* mode, uint8_t enable)
 #endif
     {
         // ppg_service_running_stat = true;
-        uapi_pm_control(PM_APP_WAKE_NEEDED);
+        // uapi_pm_control(PM_APP_WAKE_NEEDED);
         tyhx_poweron();
 #ifdef PPG_HX3695
         hx3695_init(md);
@@ -205,7 +201,7 @@ void ppg_send_cmd_to_vc9202_driver(char* mode, uint8_t enable)
 #endif
 
 
-        uapi_pm_control(PM_APP_WAKE_NONEED);
+        // uapi_pm_control(PM_APP_WAKE_NONEED);
         tyhx_poweroff();
     } 
 }
\ No newline at end of file
index 477d9ee..648fb7e 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-13 15:08:38
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2024-12-16 16:40:25
+ * @LastEditTime: 2025-05-15 11:56:40
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
  * @Description: 
  * 
@@ -51,7 +51,7 @@ void ppg_send_cmd_to_vc921x_driver(char* mode, uint8_t enable)
     if (enable == 1)
     {
         // ppg_service_running_stat = true;
-        uapi_pm_control(PM_APP_WAKE_NEEDED);
+        // uapi_pm_control(PM_APP_WAKE_NEEDED);
         tyhx_poweron();
 
         vc921x_device = get_vc921x_device();
@@ -68,7 +68,7 @@ void ppg_send_cmd_to_vc921x_driver(char* mode, uint8_t enable)
 
     } else {
         
-        uapi_pm_control(PM_APP_WAKE_NONEED);
+        // uapi_pm_control(PM_APP_WAKE_NONEED);
         vc921x_device->ops->stop_work();
         tyhx_poweroff();
     } 
index 16fc440..be7f699 100644 (file)
@@ -32,9 +32,9 @@ static void put_crown_result(int16_t x)
     {   
         return;
     }
-    if(abs(x)>=8 )
+    if(abs(x)>=16 )
     {
-        ots_result += x/8; //大于4的值除以4, 代表角度, 单位0.5°
+        ots_result += x/16; //大于4的值除以4, 代表角度, 单位0.5°
     }
     else
     {
index 6f714c6..b88bff8 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com\r
  * @Date: 2024-06-17 14:31:08\r
  * @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-05-12 18:56:38\r
+ * @LastEditTime: 2025-06-06 16:19:51\r
  * @FilePath: /FD230/code/sdk/application/wearable/service/factorytest_service/factorytest_protocol.c\r
  * @Description: \r
  * \r
 #include "app_at_process.h"\r
 #include "cywee_hal.h"\r
 \r
+#ifdef SUPPORT_PPG_SERVICE\r
 #include "ppg_service.h"\r
+#endif\r
+\r
 #include "button_porting.h"\r
 #ifdef SUPPORT_CAT1_SERVICE\r
 #include "cat1_ctl.h"\r
@@ -407,20 +410,23 @@ void aging_task(void)
                 return;\r
             }\r
             uapi_get_timestampe_ss(&current_time);\r
-            send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST);\r
+\r
+            uint32_t green = 0;\r
+            uint32_t red = 0;\r
+            uint32_t ir = 0;\r
+\r
+#ifdef SUPPORT_PPG_SERVICE\r
+            send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST);\r
             LOS_Msleep(1000);\r
-            #ifdef PPG_HX3695\r
-            FT_RESULTS_t ft_result = hx3695_factroy_test(SINGLE_CHECK_TEST);\r
-            #endif\r
+            ppg_get_leaklight_data(&green,&red,&ir);\r
             send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
-            #ifdef PPG_HX3695\r
-            PRINT("ft_result.gr_data_final : %d , ft_result.red_data_final : %d , ft_result.ir_data_final : %d\r\n",ft_result.gr_data_final,ft_result.red_data_final,ft_result.ir_data_final);\r
-            if(!(ft_result.gr_data_final && ft_result.red_data_final && ft_result.ir_data_final))\r
+#endif\r
+            PRINT("green : %d , red : %d , ft_result.ir_data_final : %d\r\n",green,red,ir);\r
+            if(!green && !red && !ir)\r
             {\r
                 aging_t.ppg_error++;\r
                 aging_t.fail_num++;\r
             }\r
-            #endif\r
             PRINT("current_time -  enter_time[%d]\n",current_time -  enter_time);\r
         }while(current_time - enter_time <= 2 * 60);\r
 \r
@@ -1459,7 +1465,9 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
             {\r
                 //获取 ppg_id\r
                 uint8_t ppg_id;\r
-                uapi_ppg_get_id(&ppg_id);\r
+#ifdef SUPPORT_PPG_SERVICE\r
+                ppg_get_chip_id(&ppg_id);\r
+#endif\r
                 PRINT("0x%x\n",ppg_id);\r
                 factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
                         BLE_TEST_CMD_SOFT_TEST_SUB_MODE_HRS,\r
@@ -1467,48 +1475,22 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
                         &ppg_id,\r
                         1);\r
 \r
-            } else if(testitem == 0x02)\r
-            {\r
-                //关闭所有LED\r
-                uint8_t send_data = 0x00;\r
-                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LED_OFF_MODE_TEST);\r
-                factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
-                        BLE_TEST_CMD_SOFT_TEST_SUB_MODE_HRS,\r
-                        0x02,\r
-                        &send_data,\r
-                        1);\r
-            } else if(testitem == 0x03)\r
+            }else if(testitem == 0x03)\r
             {\r
                 //打开心率检测\r
-#ifdef PPG_HX3695\r
-                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST);\r
-#elif defined PPG_VC9202\r
+                uint8_t databuf[4] = {0};\r
+#ifdef SUPPORT_PPG_SERVICE\r
                 send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_PPG_TEST);\r
-#endif\r
                 LOS_Msleep(1000);\r
-                uint8_t databuf[4] = {0};\r
-#ifdef PPG_HX3695\r
-                FT_RESULTS_t ft_result = hx3695_factroy_test(SINGLE_CHECK_TEST);\r
-                databuf[0] = (uint8_t)((ft_result.gr_data_final & 0xFF000000) >> 24);\r
-                databuf[1] = (uint8_t)((ft_result.gr_data_final & 0x00FF0000) >> 16);\r
-                databuf[2] = (uint8_t)((ft_result.gr_data_final & 0x0000FF00) >> 8);\r
-                databuf[3] = (uint8_t)((ft_result.gr_data_final & 0x000000FF) >> 0);\r
-#elif defined PPG_VC9202\r
-                uint32_t ppg_data = vc9202_get_hr_ppg_data();\r
-                if(!ppg_data)\r
-                {\r
-                    LOS_Msleep(1000);\r
-                    ppg_data = vc9202_get_hr_ppg_data();\r
-                }\r
 \r
-                PRINT("ppg_data : %d \n",ppg_data);\r
-                databuf[0] = (uint8_t)((ppg_data & 0xFF000000) >> 24);\r
-                databuf[1] = (uint8_t)((ppg_data & 0x00FF0000) >> 16);\r
-                databuf[2] = (uint8_t)((ppg_data & 0x0000FF00) >> 8);\r
-                databuf[3] = (uint8_t)((ppg_data & 0x000000FF) >> 0);\r
-#endif\r
+                uint32_t data = ppg_get_factory_data();\r
+                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
 \r
-            send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+                databuf[0] = (uint8_t)((data & 0xFF000000) >> 24);\r
+                databuf[1] = (uint8_t)((data & 0x00FF0000) >> 16);\r
+                databuf[2] = (uint8_t)((data & 0x0000FF00) >> 8);\r
+                databuf[3] = (uint8_t)((data & 0x000000FF) >> 0);\r
+#endif\r
 \r
             PRINT("%2X %2X %2X %2X \r\n",databuf[0],databuf[1],databuf[2],databuf[3]);\r
 \r
@@ -1521,44 +1503,21 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
             } else if(testitem == 0x04)\r
             {\r
                 //打开血氧检测\r
-#ifdef PPG_HX3695\r
-                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST);\r
-#elif defined PPG_VC9202\r
+                uint8_t databuf[4] = {0};\r
+#ifdef SUPPORT_PPG_SERVICE\r
                 send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST);\r
-#endif\r
                 LOS_Msleep(1000);\r
-                uint8_t databuf[8] = {0};\r
-#ifdef PPG_HX3695\r
-                FT_RESULTS_t ft_result = hx3695_factroy_test(SINGLE_CHECK_TEST);\r
-                databuf[0] = (uint8_t)((ft_result.red_data_final & 0xFF000000) >> 24);\r
-                databuf[1] = (uint8_t)((ft_result.red_data_final & 0x00FF0000) >> 16);\r
-                databuf[2] = (uint8_t)((ft_result.red_data_final & 0x0000FF00) >> 8);\r
-                databuf[3] = (uint8_t)((ft_result.red_data_final & 0x000000FF) >> 0);\r
-#elif defined PPG_VC9202\r
-                uint32_t red_data = 0;\r
-                uint32_t ir_data = 0;\r
-                vc9202_get_spo2_ppg_data(&ir_data,&red_data);\r
-                PRINT("ir_data : %d ,red_data : %d \n",ir_data,red_data);\r
 \r
-                if(!ir_data && !red_data)\r
-                {\r
-                    LOS_Msleep(1000);\r
-                    vc9202_get_spo2_ppg_data(&ir_data,&red_data);\r
-                }\r
-                \r
-                databuf[0] = (uint8_t)((ir_data & 0xFF000000) >> 24);\r
-                databuf[1] = (uint8_t)((ir_data & 0x00FF0000) >> 16);\r
-                databuf[2] = (uint8_t)((ir_data & 0x0000FF00) >> 8);\r
-                databuf[3] = (uint8_t)((ir_data & 0x000000FF) >> 0);\r
-\r
-                databuf[4] = (uint8_t)((red_data & 0xFF000000) >> 24);\r
-                databuf[5] = (uint8_t)((red_data & 0x00FF0000) >> 16);\r
-                databuf[6] = (uint8_t)((red_data & 0x0000FF00) >> 8);\r
-                databuf[7] = (uint8_t)((red_data & 0x000000FF) >> 0);\r
+                uint32_t data = ppg_get_factory_data();\r
+                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_SPO2_TEST);\r
+\r
+                databuf[0] = (uint8_t)((data & 0xFF000000) >> 24);\r
+                databuf[1] = (uint8_t)((data & 0x00FF0000) >> 16);\r
+                databuf[2] = (uint8_t)((data & 0x0000FF00) >> 8);\r
+                databuf[3] = (uint8_t)((data & 0x000000FF) >> 0);\r
 #endif\r
-                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
-                PRINT("%2X %2X %2X %2X \r\n",databuf[0],databuf[1],databuf[2],databuf[3]);\r
-                PRINT("%2X %2X %2X %2X \r\n",databuf[4],databuf[5],databuf[6],databuf[7]);\r
+\r
+            PRINT("%2X %2X %2X %2X \r\n",databuf[0],databuf[1],databuf[2],databuf[3]);\r
 \r
                 factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
                                     BLE_TEST_CMD_SOFT_TEST_SUB_MODE_HRS,\r
@@ -1568,6 +1527,7 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
 \r
             } else if(testitem == 0x05)\r
             {\r
+#ifdef SUPPORT_PPG_SERVICE\r
                 //灰卡测试\r
                 send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_GRAYCARD_TEST);\r
                 LOS_Msleep(1000);\r
@@ -1617,6 +1577,7 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
                                     8);\r
 #endif\r
                 send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+#endif\r
                 // PRINT("%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\r\n",\r
                 // databuf[0],databuf[1],databuf[2],databuf[3],\r
                 // databuf[4],databuf[5],databuf[6],databuf[7],\r
@@ -1627,55 +1588,33 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
             } else if(testitem == 0x06)\r
             {\r
                 //漏光测试\r
-                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST);\r
-                LOS_Msleep(1000);\r
                 uint8_t databuf[12] = {0};\r
-#ifdef PPG_HX3695\r
-                FT_RESULTS_t ft_result = hx3695_factroy_test(LEAK_LIGHT_TEST);\r
-\r
-                databuf[0] = (uint8_t)((ft_result.gr_data_final & 0xFF000000) >> 24);\r
-                databuf[1] = (uint8_t)((ft_result.gr_data_final & 0x00FF0000) >> 16);\r
-                databuf[2] = (uint8_t)((ft_result.gr_data_final & 0x0000FF00) >> 8);\r
-                databuf[3] = (uint8_t)((ft_result.gr_data_final & 0x000000FF) >> 0);\r
-\r
-                databuf[4] = (uint8_t)((ft_result.red_data_final & 0xFF000000) >> 24);\r
-                databuf[5] = (uint8_t)((ft_result.red_data_final & 0x00FF0000) >> 16);\r
-                databuf[6] = (uint8_t)((ft_result.red_data_final & 0x0000FF00) >> 8);\r
-                databuf[7] = (uint8_t)((ft_result.red_data_final & 0x000000FF) >> 0);\r
 \r
-                databuf[8] = (uint8_t)((ft_result.ir_data_final & 0xFF000000) >> 24);\r
-                databuf[9] = (uint8_t)((ft_result.ir_data_final & 0x00FF0000) >> 16);\r
-                databuf[10] = (uint8_t)((ft_result.ir_data_final & 0x0000FF00) >> 8);\r
-                databuf[11] = (uint8_t)((ft_result.ir_data_final & 0x000000FF) >> 0);\r
-#elif defined PPG_VC9202\r
-                uint32_t led_cur = 0;\r
-                uint32_t apre_val = 0;\r
-                uint32_t aps_val = 9;\r
-                vc9202_get_leaklight_data(&led_cur,&apre_val,&aps_val);\r
-                PRINT("led_cur : %d ,apre_val : %d ,aps_val : %d \n",led_cur,apre_val,aps_val);\r
+                uint32_t green = 0;\r
+                uint32_t red = 0;\r
+                uint32_t ir = 0;\r
 \r
-                if(!led_cur && !apre_val && !aps_val)\r
-                {\r
-                    LOS_Msleep(1000);\r
-                    vc9202_get_leaklight_data(&led_cur,&apre_val,&aps_val);\r
-                }\r
+#ifdef SUPPORT_PPG_SERVICE\r
+                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST);\r
+                LOS_Msleep(1000);\r
+                ppg_get_leaklight_data(&green,&red,&ir);\r
+                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+#endif\r
+                databuf[0] = (uint8_t)((green & 0xFF000000) >> 24);\r
+                databuf[1] = (uint8_t)((green & 0x00FF0000) >> 16);\r
+                databuf[2] = (uint8_t)((green & 0x0000FF00) >> 8);\r
+                databuf[3] = (uint8_t)((green & 0x000000FF) >> 0);\r
 \r
-                databuf[0] = (uint8_t)((led_cur & 0xFF000000) >> 24);\r
-                databuf[1] = (uint8_t)((led_cur & 0x00FF0000) >> 16);\r
-                databuf[2] = (uint8_t)((led_cur & 0x0000FF00) >> 8);\r
-                databuf[3] = (uint8_t)((led_cur & 0x000000FF) >> 0);\r
+                databuf[4] = (uint8_t)((red & 0xFF000000) >> 24);\r
+                databuf[5] = (uint8_t)((red & 0x00FF0000) >> 16);\r
+                databuf[6] = (uint8_t)((red & 0x0000FF00) >> 8);\r
+                databuf[7] = (uint8_t)((red & 0x000000FF) >> 0);\r
 \r
-                databuf[4] = (uint8_t)((apre_val & 0xFF000000) >> 24);\r
-                databuf[5] = (uint8_t)((apre_val & 0x00FF0000) >> 16);\r
-                databuf[6] = (uint8_t)((apre_val & 0x0000FF00) >> 8);\r
-                databuf[7] = (uint8_t)((apre_val & 0x000000FF) >> 0);\r
+                databuf[8] = (uint8_t)((ir & 0xFF000000) >> 24);\r
+                databuf[9] = (uint8_t)((ir & 0x00FF0000) >> 16);\r
+                databuf[10] = (uint8_t)((ir & 0x0000FF00) >> 8);\r
+                databuf[11] = (uint8_t)((ir & 0x000000FF) >> 0);\r
 \r
-                databuf[8] = (uint8_t)((aps_val & 0xFF000000) >> 24);\r
-                databuf[9] = (uint8_t)((aps_val & 0x00FF0000) >> 16);\r
-                databuf[10] = (uint8_t)((aps_val & 0x0000FF00) >> 8);\r
-                databuf[11] = (uint8_t)((aps_val & 0x000000FF) >> 0);\r
-#endif\r
-                send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
 \r
                 // PRINT("%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\r\n",\r
                 // databuf[0],databuf[1],databuf[2],databuf[3],\r
index 12d076e..2fe7483 100644 (file)
@@ -1490,7 +1490,7 @@ void power_on_cat1(void)
 
 void power_off_cat1(void)
 {
-    #ifdef FD230
+    #if defined(FD230) && !defined(BOARD_W9)
     uapi_cat1_reset(1);
     uapi_cat1_power_on(0); 
     #else
index 97b4f1f..74809c6 100644 (file)
@@ -559,6 +559,7 @@ static uint32_t custom_get_cywee_id(uint8_t *para, uint32_t paraLen, char *strCo
     UNUSED(strCommonCmd);
     uint8_t id;
     uapi_cywee_get_id(&id);
+    wstp_print("cywee_id[%x]\n",id);
  
     return ERRCODE_SUCC;
 }