From 3791d1bf876d62998c8fb024f8657c7aa595e7a1 Mon Sep 17 00:00:00 2001 From: "antony.wang" Date: Thu, 26 Oct 2023 15:19:18 +0800 Subject: [PATCH 01/12] =?UTF-8?q?1.=20=E4=B8=BA=E9=81=BF=E5=85=8Dcardv?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E5=81=B6=E5=8F=91=E4=B8=8D=E8=83=BD=E8=B5=B7?= =?UTF-8?q?=E6=9D=A5=EF=BC=8C=E4=BF=AE=E6=94=B9message=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E5=92=8Ccardv=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E9=87=8D=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../source/sf_app/code/source/commMng/sf_message_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/application/source/sf_app/code/source/commMng/sf_message_queue.c b/code/application/source/sf_app/code/source/commMng/sf_message_queue.c index 7f1347b5c..d11b23178 100644 --- a/code/application/source/sf_app/code/source/commMng/sf_message_queue.c +++ b/code/application/source/sf_app/code/source/commMng/sf_message_queue.c @@ -110,7 +110,7 @@ SINT32 sf_com_message_send_to_app(SF_MESSAGE_BUF_S *pMessageBuf) SINT32 sf_com_message_cardv_init(void) { - return message_queue_create((char*)"/tmp/cardv_message",&cardv_msgQueueId); + return message_queue_create((char*)"/tmp/cdv_message",&cardv_msgQueueId); } SINT32 sf_com_message_recv_from_cardv(SF_MESSAGE_BUF_S *pMessageBuf) { From 89892c20122c0424112aff4911b7513077375128 Mon Sep 17 00:00:00 2001 From: payton Date: Tue, 31 Oct 2023 16:10:00 +0800 Subject: [PATCH 02/12] =?UTF-8?q?1.sd=E5=8D=A1=E5=92=8CUI=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=9A=84=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UIFlowMovie/UIFlowMovieEventCallback.c | 91 +++++++++----- .../UIFlowPhoto/UIFlowPhotoEventCallback.c | 117 +++++++++++------- 2 files changed, 132 insertions(+), 76 deletions(-) diff --git a/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowMovie/UIFlowMovieEventCallback.c b/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowMovie/UIFlowMovieEventCallback.c index 9a428d7a7..6f97d7386 100755 --- a/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowMovie/UIFlowMovieEventCallback.c +++ b/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowMovie/UIFlowMovieEventCallback.c @@ -285,45 +285,70 @@ static void update_camera_message(void) // if((puiPara->CamMode == SF_CAM_MODE_PHOTO) || (puiPara->CamMode == SF_CAM_MODE_PHOTO_VIDEO)) switch (puiPara->ImgSize) { - case PHOTO_SIZE_16M: - lv_label_set_text(label_5_scr_uiflowmovie, "16M"); - break; - case PHOTO_SIZE_12M: - lv_label_set_text(label_5_scr_uiflowmovie, "12M"); - break; - case PHOTO_SIZE_8M: - lv_label_set_text(label_5_scr_uiflowmovie, "8M"); - break; - - default: - break; + case PHOTO_SIZE_40M: + lv_label_set_text(label_5_scr_uiflowmovie, "40M"); + break; + case PHOTO_SIZE_32M: + lv_label_set_text(label_5_scr_uiflowmovie, "32M"); + break; + case PHOTO_SIZE_24M: + lv_label_set_text(label_5_scr_uiflowmovie, "24M"); + break; + case PHOTO_SIZE_16M: + lv_label_set_text(label_5_scr_uiflowmovie, "16M"); + break; + case PHOTO_SIZE_12M: + lv_label_set_text(label_5_scr_uiflowmovie, "12M"); + break; + case PHOTO_SIZE_8M: + lv_label_set_text(label_5_scr_uiflowmovie, "8M"); + break; + case PHOTO_SIZE_5M: + lv_label_set_text(label_5_scr_uiflowmovie, "5M"); + break; + default: + break; } switch (puiPara->Multishot) { - case 1: - lv_label_set_text(label_4_scr_uiflowmovie, "1P"); - break; - case 2: - lv_label_set_text(label_4_scr_uiflowmovie, "2P"); - break; - case 3: - lv_label_set_text(label_4_scr_uiflowmovie, "3P"); - break; - - default: - break; + case CONTINUE_SHOT_OFF: + lv_label_set_text(label_4_scr_uiflowmovie, "1P"); + break; + case CONTINUE_SHOT_BURST_2: + lv_label_set_text(label_4_scr_uiflowmovie, "2P"); + break; + case CONTINUE_SHOT_BURST_3: + lv_label_set_text(label_4_scr_uiflowmovie, "3P"); + break; + case CONTINUE_SHOT_BURST_4: + lv_label_set_text(label_4_scr_uiflowmovie, "4P"); + break; + case CONTINUE_SHOT_BURST_5: + lv_label_set_text(label_4_scr_uiflowmovie, "5P"); + break; + default: + break; } UINT32 freePicNum = 0; // PhotoExe_GetTotalPicNum(); - if (UIStorageCheck(STORAGE_CHECK_ERROR, NULL) == TRUE) - { - lv_label_set_text(label_6_scr_uiflowmovie, "NO SD CARD"); - } - else - { - UIStorageCheck(STORAGE_CHECK_FULL, &freePicNum); - lv_label_set_text(label_6_scr_uiflowmovie, Get_FreePicNumString(freePicNum)); - } + UINT32 cardStatus = System_GetState(SYS_STATE_CARD); + + if (cardStatus != CARD_REMOVED) + { + if (UIStorageCheck(STORAGE_CHECK_ERROR, NULL) == TRUE) + { + lv_label_set_text(label_6_scr_uiflowmovie, "SD CARD ERROR"); + } + else + { + UIStorageCheck(STORAGE_CHECK_FULL, &freePicNum); + lv_label_set_text(label_6_scr_uiflowmovie, Get_FreePicNumString(freePicNum)); + } + } + else + { + lv_label_set_text(label_6_scr_uiflowmovie, "NO SD CARD"); + } } static void update_rec_time(void) diff --git a/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowPhoto/UIFlowPhotoEventCallback.c b/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowPhoto/UIFlowPhotoEventCallback.c index 1033383fd..54114d1ea 100755 --- a/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowPhoto/UIFlowPhotoEventCallback.c +++ b/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/UIFlowLVGL/UIFlowPhoto/UIFlowPhotoEventCallback.c @@ -142,14 +142,19 @@ static void update_quality(void) static void update_free_pic_number(void) { - if(g_PhotoBgInitFileSys == TRUE){ -#if (FS_FUNC == ENABLE) - UIStorageCheck(STORAGE_CHECK_FULL, &g_uiFreePicNum); -#endif - lv_label_set_text(label_free_pic_scr_uiflowphoto, Get_FreePicNumString(g_uiFreePicNum)); - }else{ - lv_label_set_text_fmt(label_free_pic_scr_uiflowphoto, "Check free space ..."); - } + UINT32 cardStatus = System_GetState(SYS_STATE_CARD); + + if (cardStatus != CARD_REMOVED) + { + if(g_PhotoBgInitFileSys == TRUE){ + #if (FS_FUNC == ENABLE) + UIStorageCheck(STORAGE_CHECK_FULL, &g_uiFreePicNum); + #endif + lv_label_set_text(label_free_pic_scr_uiflowphoto, Get_FreePicNumString(g_uiFreePicNum)); + }else{ + lv_label_set_text_fmt(label_free_pic_scr_uiflowphoto, "Check free space ..."); + } + } } static void update_card(void) @@ -406,45 +411,71 @@ static void update_camera_message(void) { UIMenuStoreInfo *puiPara = sf_ui_para_get(); // if((puiPara->CamMode == SF_CAM_MODE_PHOTO) || (puiPara->CamMode == SF_CAM_MODE_PHOTO_VIDEO)) - switch (puiPara->ImgSize) - { - case PHOTO_SIZE_16M: - lv_label_set_text(label_5_scr_uiflowphoto, "16M"); - break; - case PHOTO_SIZE_12M: - lv_label_set_text(label_5_scr_uiflowphoto, "12M"); - break; - case PHOTO_SIZE_8M: - lv_label_set_text(label_5_scr_uiflowphoto, "8M"); - break; - - default: - break; + + switch (puiPara->ImgSize) + { + case PHOTO_SIZE_40M: + lv_label_set_text(label_4_scr_uiflowphoto, "40M"); + break; + case PHOTO_SIZE_32M: + lv_label_set_text(label_4_scr_uiflowphoto, "32M"); + break; + case PHOTO_SIZE_24M: + lv_label_set_text(label_4_scr_uiflowphoto, "24M"); + break; + case PHOTO_SIZE_16M: + lv_label_set_text(label_4_scr_uiflowphoto, "16M"); + break; + case PHOTO_SIZE_12M: + lv_label_set_text(label_4_scr_uiflowphoto, "12M"); + break; + case PHOTO_SIZE_8M: + lv_label_set_text(label_4_scr_uiflowphoto, "8M"); + break; + case PHOTO_SIZE_5M: + lv_label_set_text(label_4_scr_uiflowphoto, "5M"); + break; + default: + break; } switch (puiPara->Multishot) { - case 1: - lv_label_set_text(label_4_scr_uiflowphoto, "1P"); - break; - case 2: - lv_label_set_text(label_4_scr_uiflowphoto, "2P"); - break; - case 3: - lv_label_set_text(label_4_scr_uiflowphoto, "3P"); - break; - - default: - break; - } - if (UIStorageCheck(STORAGE_CHECK_ERROR, NULL) == TRUE) - { - lv_label_set_text(label_6_scr_uiflowphoto, "NO SD CARD"); - } - else - { - UIStorageCheck(STORAGE_CHECK_FULL, &g_uiFreePicNum); - lv_label_set_text(label_6_scr_uiflowphoto, Get_FreePicNumString(g_uiFreePicNum)); + case CONTINUE_SHOT_OFF: + lv_label_set_text(label_4_scr_uiflowphoto, "1P"); + break; + case CONTINUE_SHOT_BURST_2: + lv_label_set_text(label_4_scr_uiflowphoto, "2P"); + break; + case CONTINUE_SHOT_BURST_3: + lv_label_set_text(label_4_scr_uiflowphoto, "3P"); + break; + case CONTINUE_SHOT_BURST_4: + lv_label_set_text(label_4_scr_uiflowphoto, "4P"); + break; + case CONTINUE_SHOT_BURST_5: + lv_label_set_text(label_4_scr_uiflowphoto, "5P"); + break; + default: + break; } + UINT32 cardStatus = System_GetState(SYS_STATE_CARD); + + if (cardStatus != CARD_REMOVED) + { + if (UIStorageCheck(STORAGE_CHECK_ERROR, NULL) == TRUE) + { + lv_label_set_text(label_6_scr_uiflowphoto, "SD CARD ERROR"); + } + else + { + UIStorageCheck(STORAGE_CHECK_FULL, &g_uiFreePicNum); + lv_label_set_text(label_6_scr_uiflowphoto, Get_FreePicNumString(g_uiFreePicNum)); + } + } + else + { + lv_label_set_text(label_6_scr_uiflowphoto, "NO SD CARD"); + } } static void update_wifi(void) From f6886c08783b7ae35363036da0cb41f3af0121e9 Mon Sep 17 00:00:00 2001 From: payton Date: Tue, 31 Oct 2023 17:49:23 +0800 Subject: [PATCH 03/12] =?UTF-8?q?1.=E5=85=B3=E6=9C=BA=E7=94=BB=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UIWnd/LVGL_SPORTCAM/Resource/Goodbye.c | 1448 +++++++++++------ 1 file changed, 928 insertions(+), 520 deletions(-) diff --git a/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/Resource/Goodbye.c b/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/Resource/Goodbye.c index 072bfa51b..0a0e5cd8b 100755 --- a/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/Resource/Goodbye.c +++ b/code/application/source/cardv/SrcCode/UIWnd/LVGL_SPORTCAM/Resource/Goodbye.c @@ -3,525 +3,933 @@ #include "kwrap/type.h" const UINT8 g_ucBGGoodbye[] = { -0xFF, 0xD8, 0xFF, 0xFE, 0x00, 0x0F, 0x4C, 0x61, 0x76, 0x63, 0x35, 0x38, 0x2E, 0x36, 0x2E, 0x31, -0x30, 0x33, 0x00, 0xFF, 0xDB, 0x00, 0x43, 0x00, 0x08, 0x06, 0x06, 0x07, 0x06, 0x07, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0A, 0x0A, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x0A, 0x0A, -0x0A, 0x0A, 0x0A, 0x0A, 0x0C, 0x0C, 0x0C, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0C, 0x0C, -0x0C, 0x0C, 0x0D, 0x0E, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x12, 0x12, -0x11, 0x11, 0x15, 0x15, 0x15, 0x19, 0x19, 0x1F, 0xFF, 0xC4, 0x00, 0xB8, 0x00, 0x00, 0x02, 0x03, -0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x04, -0x00, 0x01, 0x05, 0x06, 0x07, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x05, 0x10, 0x00, 0x02, -0x01, 0x03, 0x02, 0x03, 0x04, 0x06, 0x07, 0x04, 0x0A, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, -0x02, 0x04, 0x03, 0x11, 0x12, 0x21, 0x05, 0x31, 0x41, 0x61, 0x71, 0x51, 0x13, 0x81, 0x22, 0x32, -0xA1, 0x91, 0x06, 0x23, 0x72, 0x52, 0x62, 0x14, 0x42, 0xF0, 0x82, 0x33, 0x92, 0xB1, 0xA2, 0xB2, -0x53, 0xD2, 0xF1, 0x43, 0x15, 0xD1, 0xE1, 0xC2, 0x73, 0x34, 0xF2, 0xC1, 0x24, 0x83, 0x11, 0x00, -0x00, 0x05, 0x03, 0x01, 0x04, 0x06, 0x06, 0x08, 0x03, 0x08, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, -0x03, 0xC4, 0x01, 0x83, 0x43, 0x42, 0x02, 0x11, 0x12, 0x04, 0xB1, 0x21, 0x82, 0xD1, 0x13, 0x33, -0x31, 0x32, 0x22, 0xA1, 0x71, 0x41, 0x91, 0x23, 0x51, 0x81, 0x14, 0xE1, 0xB2, 0xC1, 0x53, 0xC3, -0x44, 0x54, 0x61, 0xF0, 0x64, 0x72, 0x52, 0x73, 0x74, 0x34, 0x63, 0x62, 0x84, 0xD2, 0xC2, 0x94, -0xB4, 0xA2, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40, 0x03, 0x01, 0x22, 0x00, 0x02, -0x11, 0x00, 0x03, 0x11, 0x00, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, -0x00, 0x3F, 0x00, 0xF3, 0xAA, 0x3D, 0xC6, 0xA8, 0x05, 0x51, 0x19, 0x47, 0x27, 0xE0, 0x17, 0x64, -0x69, 0x87, 0xCF, 0xEE, 0xCE, 0xDA, 0x60, 0xCE, 0xFF, 0x00, 0xA7, 0xF8, 0x77, 0x5F, 0xCD, 0xC0, -0xD4, 0x4D, 0xD0, 0x15, 0x40, 0xB2, 0x8E, 0x13, 0x05, 0xD9, 0x1A, 0x61, 0x4B, 0x62, 0xB4, 0xC3, -0xD2, 0xCA, 0x97, 0x0D, 0xD7, 0xEE, 0xF8, 0xB8, 0x8F, 0xA7, 0x76, 0x6E, 0x91, 0xF0, 0x6E, 0x90, -0x5D, 0x91, 0xA6, 0x11, 0xB3, 0x6C, 0x9C, 0xBE, 0x5A, 0x33, 0x39, 0x4C, 0xDF, 0x5B, 0xEE, 0x8E, -0x13, 0x49, 0xB1, 0x86, 0x58, 0xFA, 0x72, 0x1A, 0x36, 0xF0, 0x88, 0x5D, 0x91, 0xA6, 0x1D, 0x0B, -0xD8, 0xCB, 0x02, 0x1D, 0xDF, 0x2D, 0x5B, 0x12, 0x9B, 0xE2, 0xFB, 0xA7, 0xDD, 0xF1, 0x70, 0x2D, -0x1B, 0x0A, 0x96, 0x42, 0xCF, 0x9E, 0x3E, 0x26, 0x28, 0xE0, 0x85, 0xD9, 0x1A, 0x51, 0x96, 0xCB, -0x17, 0x62, 0x99, 0xBC, 0x1B, 0xB2, 0xE3, 0xBA, 0xE9, 0xC4, 0x26, 0x82, 0xE8, 0x61, 0x94, 0x4D, -0xD2, 0x0B, 0xB2, 0x34, 0xA2, 0x10, 0xFA, 0x3E, 0x0E, 0xFE, 0x1A, 0x61, 0xEB, 0xC7, 0x75, 0xD3, -0xD6, 0x23, 0xE8, 0x33, 0x49, 0x23, 0x49, 0x9A, 0x41, 0x76, 0x46, 0x94, 0x4C, 0x6C, 0xF0, 0xA7, -0xE1, 0xEC, 0xDD, 0x44, 0x6D, 0x08, 0xC7, 0x12, 0x43, 0xB6, 0x2B, 0x80, 0x2E, 0xC8, 0xD2, 0x8D, -0x96, 0xF8, 0x3B, 0x61, 0xAE, 0xB4, 0xD3, 0xFD, 0xC2, 0x3E, 0x91, 0x5C, 0x49, 0x0E, 0x38, 0x15, -0xA2, 0x97, 0x64, 0x69, 0x84, 0xC5, 0xB0, 0xF4, 0x36, 0x5F, 0x2B, 0x3C, 0x7F, 0xF4, 0xDF, 0x96, -0x9E, 0xB0, 0x07, 0x11, 0x5C, 0x42, 0xB4, 0x66, 0x06, 0x16, 0x46, 0x94, 0x4C, 0x2C, 0x8F, 0x8E, -0xEC, 0x00, 0xE2, 0x2B, 0x41, 0xF0, 0x2B, 0x88, 0x2E, 0xC8, 0xD3, 0x01, 0x5E, 0x18, 0x47, 0xC3, -0x77, 0x11, 0xDC, 0x45, 0x71, 0xC0, 0x77, 0x11, 0x1A, 0x05, 0xD9, 0x1A, 0x60, 0x2B, 0x27, 0xC1, -0xF0, 0xD3, 0xFF, 0x00, 0x04, 0xCD, 0xC0, 0x05, 0xA1, 0x5A, 0x0C, 0xE2, 0x23, 0x40, 0xBB, 0x23, -0x4C, 0x35, 0x83, 0x95, 0x9E, 0xC7, 0x8E, 0x2F, 0xF2, 0xF9, 0x78, 0xE2, 0xDF, 0xF1, 0x79, 0x37, -0xFF, 0x00, 0xCE, 0x9F, 0x58, 0x1F, 0x22, 0x9A, 0xD1, 0x41, 0x76, 0x46, 0x98, 0x0B, 0xCF, 0x1C, -0x36, 0x18, 0xBD, 0x69, 0xFA, 0x4F, 0xCB, 0x96, 0x9B, 0xB3, 0x7A, 0xF1, 0x76, 0xF8, 0x0C, 0x29, -0x4A, 0x0B, 0xB2, 0x34, 0xA2, 0x13, 0x93, 0xE3, 0xD9, 0xBB, 0x7B, 0xFB, 0x3D, 0x5F, 0x5F, 0x1D, -0x7E, 0xCA, 0xDA, 0xFC, 0x05, 0x29, 0x4A, 0x0B, 0xB2, 0x34, 0xA1, 0x83, 0x95, 0x9E, 0xC6, 0x5E, -0x5E, 0xEF, 0x96, 0x9E, 0xF7, 0xFB, 0x2E, 0x9F, 0x0F, 0x45, 0xBE, 0xB1, 0x4A, 0x52, 0x82, 0xEC, -0x8D, 0x28, 0x17, 0x9E, 0x2C, 0xC5, 0xB6, 0x1A, 0xB3, 0x3F, 0x64, 0xFA, 0xFD, 0x2D, 0xAE, 0xEA, -0xCD, 0xF1, 0x67, 0xD0, 0x52, 0x94, 0xA0, 0xBB, 0x23, 0x4A, 0x30, 0x46, 0x6F, 0x8F, 0x67, 0xA6, -0x8D, 0xDD, 0x37, 0xC5, 0xB7, 0x46, 0xFB, 0x85, 0x29, 0x4A, 0x0B, 0xB2, 0x34, 0xA3, 0x78, 0x39, -0x59, 0x6C, 0x65, 0xCF, 0x1D, 0x7B, 0x37, 0xD3, 0xCC, 0xDC, 0xFE, 0xC9, 0xA7, 0x3F, 0x83, 0x7C, -0x5C, 0x52, 0x94, 0xA0, 0xBB, 0x23, 0x4A, 0x18, 0x67, 0x8B, 0x76, 0x78, 0x96, 0xCF, 0xA7, 0xCB, -0xF7, 0xF3, 0xD1, 0xBE, 0xCB, 0xFF, 0x00, 0xC5, 0xF9, 0x8E, 0xFA, 0x8F, 0x21, 0xD4, 0x06, 0x82, -0xD8, 0x2A, 0x8E, 0x4B, 0x85, 0x91, 0xA6, 0x1C, 0x4A, 0xA7, 0x12, 0x30, 0x25, 0x01, 0x2E, 0xAE, -0x4B, 0xE2, 0x4A, 0x50, 0x01, 0x75, 0x66, 0x63, 0x0B, 0x23, 0x4C, 0x29, 0x54, 0xE2, 0x46, 0x01, -0xA4, 0x6C, 0x0D, 0xA4, 0xDD, 0x20, 0xBB, 0x3A, 0x09, 0x80, 0xBA, 0x71, 0x24, 0x16, 0xDC, 0x35, -0x30, 0xD3, 0x5A, 0x50, 0x4B, 0x50, 0xC2, 0xC8, 0x2B, 0xBE, 0xB3, 0xEE, 0x18, 0x59, 0x1A, 0x61, -0xA2, 0x69, 0xC5, 0xC7, 0x72, 0x01, 0xD2, 0x32, 0x88, 0xE9, 0x1B, 0x82, 0x17, 0x64, 0x69, 0x44, -0x2A, 0x9C, 0x48, 0xC2, 0xE9, 0xC1, 0xB8, 0xFD, 0x64, 0x74, 0x8B, 0x8C, 0x10, 0xBB, 0x23, 0x4A, -0x29, 0x74, 0xE3, 0x48, 0x17, 0x06, 0x63, 0x71, 0xDA, 0xC1, 0x89, 0x02, 0xE9, 0xC6, 0x94, 0x0B, -0xB2, 0x34, 0xA1, 0x74, 0x08, 0xE0, 0x1B, 0x02, 0xCB, 0x62, 0x97, 0x64, 0x69, 0x80, 0xBB, 0x23, -0x4A, 0x00, 0xE3, 0x80, 0x72, 0x41, 0x9E, 0x77, 0x17, 0x03, 0x0B, 0x23, 0x4A, 0x29, 0x76, 0x46, -0x98, 0x01, 0xC4, 0x57, 0x1C, 0x87, 0xD3, 0x93, 0x34, 0x10, 0xBB, 0x23, 0x4A, 0x35, 0x8D, 0x91, -0xF1, 0xDD, 0xC4, 0x77, 0x11, 0x5A, 0xFD, 0x64, 0x90, 0xE2, 0x0E, 0x51, 0x29, 0x76, 0x46, 0x94, -0x42, 0x7C, 0x30, 0x8F, 0x86, 0xEC, 0x00, 0xE2, 0x24, 0xA2, 0x19, 0x88, 0xFA, 0x82, 0xEC, 0x8D, -0x28, 0x98, 0xF8, 0xE1, 0x1F, 0x1D, 0xD8, 0x05, 0xA1, 0x5A, 0x08, 0xC4, 0x65, 0x2E, 0xC8, 0xD3, -0x0C, 0x97, 0x4E, 0x34, 0x80, 0x4D, 0x60, 0x57, 0xCC, 0x23, 0x11, 0x82, 0xEC, 0x8D, 0x30, 0x17, -0x4E, 0x34, 0x81, 0x30, 0x51, 0x9F, 0x51, 0x70, 0x42, 0xEC, 0x8D, 0x28, 0xD9, 0x7E, 0x05, 0xC5, -0xF8, 0xB7, 0x41, 0x4A, 0x52, 0x82, 0xEC, 0x8D, 0x28, 0xC1, 0x7E, 0x05, 0x42, 0x90, 0x52, 0x94, -0xA0, 0xBB, 0x23, 0x4A, 0x21, 0x54, 0xE2, 0x46, 0x29, 0x4A, 0x50, 0x5D, 0x91, 0xA5, 0x02, 0xA9, -0xC4, 0x8C, 0x52, 0x94, 0xA0, 0xBB, 0x23, 0x4A, 0x05, 0x53, 0x89, 0x18, 0xA5, 0x29, 0x41, 0x76, -0x46, 0x94, 0x0A, 0xA7, 0x12, 0x31, 0xE9, 0xA0, 0xB6, 0x44, 0x88, 0x47, 0x20, 0xA0, 0x89, 0x56, -0xE2, 0x6B, 0x06, 0xF2, 0x46, 0x98, 0x0B, 0x6E, 0xEE, 0x24, 0x83, 0x34, 0xEC, 0x42, 0x7B, 0xB7, -0xDA, 0xCE, 0x95, 0xC5, 0x88, 0x49, 0xF6, 0x1C, 0xF1, 0x83, 0x79, 0x23, 0x4C, 0x05, 0xB7, 0x77, -0x12, 0x41, 0x98, 0x1A, 0x31, 0xCB, 0x2E, 0x03, 0x5A, 0x8E, 0xE8, 0x61, 0x64, 0x69, 0xC6, 0x8B, -0xA7, 0x1A, 0x40, 0xD2, 0xF5, 0x21, 0xDE, 0x47, 0xC1, 0x22, 0xFE, 0x33, 0x8F, 0x40, 0x24, 0x89, -0x85, 0x91, 0xA6, 0x10, 0xAA, 0x71, 0x71, 0xDC, 0xC2, 0xAD, 0x86, 0xC0, 0xD8, 0x37, 0x04, 0x2E, -0xC8, 0xD2, 0x8A, 0x55, 0x3F, 0x61, 0x5C, 0x37, 0x21, 0x98, 0x2B, 0x34, 0x49, 0x10, 0xBA, 0x71, -0xA5, 0x02, 0xE9, 0xC4, 0x90, 0x2F, 0x36, 0x11, 0x44, 0xC8, 0xC4, 0x22, 0x45, 0x2A, 0xC8, 0xD2, -0x81, 0x54, 0xE3, 0x4A, 0x11, 0xA0, 0x52, 0x41, 0x9F, 0x51, 0x34, 0x97, 0x0B, 0x23, 0x4A, 0x29, -0x76, 0x46, 0x94, 0x0B, 0x06, 0x69, 0xC8, 0x5D, 0x3E, 0x05, 0xD2, 0x42, 0xE9, 0xC6, 0x94, 0x42, -0xEC, 0x8D, 0x30, 0x16, 0x9C, 0x08, 0xD6, 0x03, 0x34, 0x0E, 0x7B, 0x02, 0xE9, 0xC6, 0x94, 0x74, -0x2E, 0xCE, 0x87, 0xEC, 0x00, 0xCB, 0x60, 0x32, 0x0B, 0x30, 0x2C, 0x17, 0x64, 0x69, 0x47, 0x32, -0xEC, 0xE8, 0x25, 0x03, 0x60, 0xE4, 0x11, 0xF5, 0x15, 0xAE, 0x65, 0x2E, 0xC8, 0xD2, 0x8D, 0xB7, -0x3D, 0x88, 0xF8, 0xEE, 0xE0, 0x4C, 0x57, 0xB8, 0x57, 0x13, 0x34, 0x82, 0xEC, 0x8D, 0x28, 0xE6, -0x5D, 0x91, 0xA5, 0x01, 0x68, 0x56, 0xB9, 0x87, 0x71, 0x15, 0xA0, 0x5D, 0x91, 0xA5, 0x02, 0xE9, -0xC4, 0x90, 0x01, 0xC4, 0x56, 0x19, 0xC4, 0x46, 0x81, 0x76, 0x46, 0x94, 0x6C, 0x9B, 0x23, 0xE3, -0xBA, 0x01, 0x3D, 0xB7, 0x28, 0xCD, 0x0A, 0xD2, 0x40, 0xBB, 0x23, 0x4A, 0x31, 0x83, 0x77, 0x71, -0x24, 0x14, 0xA5, 0x29, 0x0B, 0xB2, 0x34, 0xC2, 0x15, 0x4E, 0x24, 0x62, 0x94, 0xA5, 0x05, 0xD9, -0x1A, 0x50, 0x2A, 0x9C, 0x48, 0xC5, 0x29, 0x4A, 0x0B, 0xB2, 0x34, 0xA2, 0x95, 0x4E, 0x24, 0x62, -0x94, 0xA5, 0x05, 0xD9, 0x1A, 0x50, 0x2A, 0x9C, 0x48, 0xC7, 0xAB, 0x87, 0x42, 0x5D, 0x95, 0xBA, -0x23, 0x45, 0x72, 0x26, 0x58, 0x5B, 0xA3, 0x78, 0x59, 0xD0, 0x4E, 0x05, 0x53, 0x8D, 0x20, 0xDA, -0x88, 0xE2, 0xD3, 0x20, 0x28, 0x9D, 0x3A, 0xD8, 0xE2, 0xD2, 0xEF, 0x20, 0x24, 0x30, 0xB3, 0xA0, -0x9C, 0x52, 0xDB, 0xBB, 0x8D, 0x28, 0x5C, 0x07, 0xB1, 0x1E, 0x6F, 0xC1, 0x64, 0x4D, 0x21, 0xA2, -0xB4, 0xDB, 0x97, 0xA1, 0x0C, 0x2C, 0x8D, 0x38, 0x17, 0x4E, 0x34, 0xA2, 0x3C, 0xB7, 0x65, 0xD2, -0x3E, 0x91, 0xB0, 0x63, 0x0B, 0x23, 0x4A, 0x26, 0x0D, 0xDD, 0xC6, 0x90, 0x0B, 0x06, 0x84, 0xC7, -0xEB, 0x25, 0x68, 0x85, 0xD3, 0x8D, 0x20, 0x13, 0x4E, 0x2E, 0x3B, 0x90, 0x13, 0x4C, 0x50, 0x8D, -0x15, 0x44, 0x17, 0x4E, 0x34, 0x80, 0x55, 0x38, 0x92, 0x0C, 0x8C, 0x47, 0xC0, 0xD1, 0x89, 0xAD, -0x14, 0xAB, 0x23, 0x4A, 0x29, 0x4F, 0xDD, 0xC6, 0x90, 0x09, 0xC4, 0x5C, 0x06, 0xC0, 0xB8, 0xFD, -0x64, 0x61, 0x4E, 0x3E, 0x3B, 0xA8, 0xA5, 0xF2, 0xD8, 0x8D, 0x2B, 0x01, 0x60, 0xBA, 0x72, 0x11, -0x47, 0x53, 0xC1, 0xB3, 0xC4, 0x56, 0xC4, 0x2E, 0x9C, 0x69, 0x03, 0x0B, 0x23, 0x4C, 0x23, 0xCD, -0xE1, 0x11, 0xA6, 0xC3, 0x4F, 0x70, 0x12, 0x65, 0x2E, 0x9C, 0x69, 0x46, 0xCA, 0xB3, 0xA1, 0xC3, -0x77, 0x02, 0x90, 0x36, 0x3B, 0xEA, 0x60, 0x2E, 0x9C, 0x69, 0x46, 0x19, 0xBD, 0x2C, 0x3D, 0xB8, -0x71, 0xDD, 0x40, 0xDA, 0x15, 0xA0, 0xBA, 0x58, 0xBA, 0x0A, 0x5D, 0x91, 0xA5, 0x14, 0xB7, 0xDA, -0x6C, 0x23, 0xE1, 0xBB, 0xB8, 0x10, 0xAF, 0xA8, 0x57, 0x01, 0x7C, 0xB6, 0x42, 0xEC, 0x8D, 0x28, -0xCE, 0x16, 0x46, 0x98, 0x05, 0xED, 0xE0, 0x2B, 0x61, 0x5D, 0xB1, 0x7C, 0xB2, 0x97, 0x64, 0x69, -0x44, 0x2A, 0x9C, 0x69, 0x00, 0x9F, 0x51, 0x5B, 0x41, 0x5C, 0x01, 0xB8, 0x02, 0xEC, 0x8D, 0x28, -0xD1, 0x3E, 0x25, 0xC4, 0x94, 0x0D, 0x8A, 0x3B, 0x8E, 0x05, 0x60, 0xBB, 0x23, 0x4A, 0x26, 0x3E, -0x62, 0xE1, 0x4A, 0x13, 0x96, 0xC5, 0x2B, 0x31, 0xF3, 0x21, 0x76, 0x46, 0x94, 0x64, 0xBA, 0x71, -0x23, 0x1A, 0x52, 0x94, 0x17, 0x64, 0x69, 0x40, 0xAA, 0x71, 0x23, 0x14, 0xA5, 0x28, 0x2E, 0xC8, -0xD2, 0x8A, 0x55, 0x38, 0x91, 0x8A, 0x52, 0x94, 0x17, 0x64, 0x69, 0x40, 0xAA, 0x71, 0x23, 0x1E, -0xBE, 0x0B, 0x18, 0x26, 0x58, 0xE6, 0x88, 0xD1, 0x5C, 0x89, 0x54, 0xEB, 0x74, 0x68, 0xBB, 0x23, -0x4C, 0x04, 0x78, 0x17, 0x17, 0x0D, 0xD0, 0x1F, 0x88, 0x47, 0xE8, 0xE1, 0xDE, 0x73, 0xF4, 0x9D, -0x5A, 0xE8, 0xFD, 0x0D, 0xB3, 0x9C, 0x97, 0xEB, 0x25, 0x2E, 0xC8, 0xD3, 0x0D, 0x17, 0x64, 0x69, -0x42, 0xA4, 0x15, 0xAC, 0x5B, 0x8F, 0x7B, 0x66, 0x28, 0x84, 0x9A, 0xF5, 0x63, 0xE9, 0x7E, 0xF1, -0x85, 0x91, 0xA6, 0x10, 0xBB, 0x23, 0x4A, 0x01, 0xA4, 0xDD, 0x23, 0xE0, 0xDC, 0x1C, 0x8B, 0xA7, -0x1A, 0x41, 0x4B, 0x6F, 0x24, 0x69, 0x40, 0xF0, 0xCC, 0x6B, 0xF5, 0x90, 0x98, 0x15, 0xA2, 0x97, -0x4E, 0x24, 0x83, 0x25, 0xB6, 0x9D, 0x9C, 0x5C, 0x77, 0x40, 0x36, 0x6A, 0x46, 0xF3, 0x1E, 0x28, -0x15, 0x4E, 0x34, 0x80, 0x55, 0x38, 0x91, 0x8A, 0xA2, 0x5C, 0x64, 0x74, 0x8B, 0x83, 0x58, 0x53, -0x8D, 0x28, 0x17, 0x4E, 0x34, 0x80, 0x6D, 0x0A, 0xD7, 0x4E, 0x61, 0x9A, 0x36, 0xC5, 0xAD, 0x4D, -0xC9, 0xF4, 0xF7, 0xB3, 0x25, 0x59, 0x1A, 0x41, 0xA2, 0x9F, 0x5D, 0x88, 0xD2, 0xB8, 0x5D, 0x1E, -0x5C, 0x7B, 0x79, 0x91, 0x2E, 0x32, 0x5D, 0xF9, 0x6E, 0x73, 0xAE, 0xCF, 0x9A, 0x5E, 0x96, 0x0B, -0xA7, 0x1A, 0x41, 0xA2, 0xFC, 0x30, 0x8F, 0x86, 0xEC, 0x03, 0x39, 0x74, 0xF7, 0x82, 0xC6, 0x42, -0xA8, 0x39, 0xB0, 0x8A, 0xD2, 0x88, 0x2E, 0x9C, 0x69, 0x04, 0x2F, 0x96, 0xC7, 0x41, 0x38, 0x8E, -0xAD, 0x78, 0xFC, 0x0D, 0xD1, 0xE1, 0xB1, 0x23, 0x46, 0x46, 0x56, 0xCA, 0x5D, 0x38, 0xD2, 0x8A, -0xD6, 0x47, 0xC7, 0x77, 0x11, 0xBC, 0xB2, 0xF9, 0x58, 0x25, 0x69, 0x42, 0x35, 0x80, 0x5D, 0x38, -0xD2, 0x8C, 0x15, 0x64, 0x7C, 0x37, 0x46, 0x11, 0xDD, 0xB1, 0x1C, 0x11, 0x25, 0x82, 0x97, 0x52, -0x17, 0x4E, 0x34, 0x82, 0xE3, 0x64, 0x69, 0x80, 0x1C, 0x01, 0xB8, 0x92, 0x18, 0x26, 0xB9, 0x94, -0xBA, 0x71, 0xA5, 0x19, 0x2E, 0xC8, 0xD2, 0x80, 0x35, 0x80, 0x6E, 0x21, 0xE4, 0x81, 0x34, 0x5C, -0x29, 0xC6, 0x94, 0x52, 0x9F, 0xBB, 0x8F, 0x86, 0xEA, 0x01, 0x25, 0x80, 0x72, 0x8F, 0x30, 0xF2, -0x88, 0x36, 0x88, 0x5D, 0x91, 0xA5, 0x0C, 0x69, 0xC7, 0xC7, 0x74, 0x01, 0x68, 0x47, 0x90, 0xAD, -0x73, 0x11, 0x82, 0xEC, 0x8D, 0x28, 0xC9, 0x74, 0xE2, 0x46, 0x14, 0xA5, 0x28, 0x2E, 0xC8, 0xD2, -0x81, 0x54, 0xE2, 0x46, 0x29, 0x4A, 0x52, 0x97, 0x64, 0x69, 0x45, 0x2A, 0x9C, 0x48, 0xC5, 0x29, -0x4A, 0x0B, 0xB2, 0x34, 0xA0, 0x55, 0x38, 0x91, 0x8F, 0x68, 0xBF, 0x5B, 0x92, 0x2C, 0xF3, 0x40, -0x97, 0x40, 0xD6, 0xC8, 0x5B, 0xF7, 0x71, 0xA4, 0x10, 0x9A, 0x71, 0x70, 0xDC, 0xC4, 0xFA, 0xB5, -0xAA, 0x9A, 0xDF, 0x7B, 0x47, 0x39, 0x23, 0xA9, 0x3F, 0x5E, 0x91, 0x76, 0x33, 0x9C, 0xA2, 0x52, -0xEC, 0x8D, 0x28, 0xD9, 0x54, 0xE3, 0x4A, 0x31, 0x44, 0x79, 0xAD, 0xA1, 0xDC, 0x5C, 0x0D, 0x25, -0xB4, 0x3B, 0xBF, 0xEC, 0x5C, 0x6C, 0x8F, 0x8E, 0xEC, 0x2E, 0x16, 0x46, 0x94, 0x0B, 0x4E, 0x0D, -0xC7, 0xEB, 0x23, 0x99, 0x83, 0x91, 0x7E, 0x25, 0xC4, 0x8C, 0x42, 0xEC, 0x8D, 0x28, 0x46, 0xBB, -0xC1, 0xCC, 0x2C, 0x96, 0x01, 0xBE, 0x65, 0x2A, 0x9C, 0x48, 0xC3, 0x06, 0xF2, 0x46, 0x94, 0x0D, -0x73, 0x0F, 0x14, 0x0A, 0x2B, 0x72, 0x4C, 0x22, 0x68, 0xA6, 0xEE, 0xE3, 0x48, 0x32, 0x5F, 0x2E, -0xCE, 0x2E, 0x3B, 0xA0, 0xBA, 0x4C, 0xD2, 0x17, 0x1F, 0xAC, 0x98, 0xD0, 0xC2, 0x9C, 0x69, 0x40, -0xBE, 0x7D, 0x9C, 0x49, 0x00, 0x5A, 0xDF, 0x1D, 0xA4, 0x99, 0x47, 0xC9, 0xB6, 0xA3, 0xD7, 0x19, -0x7D, 0xE6, 0x53, 0xDB, 0xD7, 0x75, 0x67, 0x92, 0xDD, 0x9B, 0x57, 0x22, 0x15, 0x4E, 0x24, 0x82, -0x95, 0x4E, 0x34, 0xA3, 0x9B, 0x51, 0x2C, 0x11, 0x15, 0xB7, 0x37, 0xFC, 0xC9, 0x32, 0x8B, 0x9C, -0x87, 0xD2, 0xA0, 0xBB, 0x41, 0x74, 0xE3, 0x48, 0x35, 0x87, 0x3D, 0x8F, 0xA7, 0xE5, 0xA6, 0xD4, -0x07, 0x4A, 0x8A, 0xC2, 0xF8, 0x95, 0x43, 0x21, 0x54, 0x32, 0x13, 0x46, 0xC0, 0xBA, 0x71, 0xA4, -0x14, 0xBE, 0x7B, 0x1F, 0x4F, 0xCB, 0xE1, 0xBB, 0x00, 0xA8, 0x18, 0xE2, 0x15, 0xAC, 0x0A, 0xD0, -0x2E, 0x9C, 0x69, 0x00, 0xBB, 0x3A, 0x1F, 0xB0, 0x02, 0xD7, 0x31, 0x5A, 0xE6, 0x15, 0xC4, 0x46, -0xB9, 0x82, 0xE9, 0xC4, 0x90, 0x67, 0x16, 0xD1, 0xF0, 0xF6, 0x97, 0xC7, 0x75, 0xEA, 0x01, 0x92, -0x07, 0x28, 0x92, 0x1A, 0xE6, 0x09, 0xA0, 0x55, 0x38, 0x92, 0x08, 0x5D, 0x91, 0xF0, 0xDD, 0x7A, -0xC0, 0x1C, 0x41, 0xB4, 0x1E, 0x51, 0x06, 0xD1, 0x4B, 0xB2, 0x34, 0xA2, 0x61, 0x64, 0x69, 0x80, -0x24, 0x81, 0x49, 0x60, 0x91, 0x24, 0x0A, 0x51, 0x05, 0xD3, 0x8D, 0x28, 0x17, 0x64, 0x69, 0x40, -0x1A, 0x05, 0x24, 0x48, 0x60, 0xA4, 0x88, 0x5D, 0x38, 0xD2, 0x8B, 0x85, 0x38, 0xF8, 0xEE, 0xA0, -0x0D, 0x03, 0x68, 0x3B, 0x40, 0xA4, 0x8A, 0x5D, 0x38, 0xD2, 0x8C, 0x97, 0x4E, 0x24, 0x60, 0x6F, -0xA9, 0x83, 0x31, 0x79, 0x6C, 0x0B, 0xB2, 0x34, 0xA0, 0x55, 0x38, 0x91, 0x8A, 0x52, 0x94, 0x17, -0x64, 0x69, 0x40, 0xAA, 0x71, 0x23, 0x14, 0xA5, 0x28, 0x2E, 0xC8, 0xD2, 0x8A, 0x55, 0x38, 0x91, -0x8F, 0x71, 0x15, 0xC8, 0x35, 0xB0, 0x6B, 0x97, 0xA0, 0x2C, 0x08, 0x55, 0x38, 0x92, 0x0C, 0x95, -0x4E, 0x24, 0x43, 0xA3, 0x67, 0xD7, 0xA7, 0xB9, 0x1E, 0xCC, 0x90, 0x5C, 0x70, 0xD9, 0x3A, 0x8B, -0x77, 0xA7, 0xED, 0x26, 0x88, 0xD7, 0x21, 0xA6, 0x4C, 0xD1, 0x54, 0xE3, 0x4A, 0x36, 0x4B, 0xF7, -0x71, 0x24, 0x03, 0xC0, 0xED, 0x7D, 0x1C, 0x5F, 0x6B, 0x46, 0x24, 0x32, 0x59, 0xB5, 0x2E, 0xC7, -0x92, 0xB7, 0x8E, 0x11, 0xF1, 0xDD, 0x46, 0xB0, 0xB2, 0x34, 0xC1, 0x0C, 0x63, 0x25, 0xB2, 0x2B, -0x47, 0x22, 0xA9, 0xC4, 0x8C, 0x0B, 0xB2, 0x34, 0xA0, 0x33, 0x07, 0xD4, 0x2C, 0xF9, 0x01, 0xB5, -0xEB, 0x37, 0xDC, 0x0B, 0xA7, 0x12, 0x30, 0x2E, 0xC8, 0xD3, 0x01, 0xDA, 0xDE, 0x4C, 0x9D, 0x05, -0xFC, 0x88, 0x16, 0x9E, 0x2E, 0xFA, 0x4E, 0xE7, 0x0A, 0xA0, 0xBD, 0xC4, 0xAA, 0x6D, 0x53, 0x59, -0xC6, 0xB9, 0xB7, 0xBB, 0xF6, 0x63, 0x15, 0xBC, 0xA5, 0x3E, 0xC4, 0x8D, 0x93, 0x4E, 0x24, 0x82, -0x60, 0xDE, 0x48, 0xD2, 0x88, 0xF8, 0x15, 0xC7, 0x99, 0xE9, 0x6E, 0xBF, 0x97, 0x78, 0x6C, 0x9D, -0x95, 0x62, 0xFF, 0x00, 0x14, 0x9C, 0x76, 0xB9, 0x79, 0xDF, 0x95, 0x9B, 0x5A, 0xBA, 0xF9, 0x7E, -0x5B, 0xCB, 0x5D, 0xB8, 0x6B, 0xEF, 0x01, 0xBF, 0x4F, 0xC1, 0x2B, 0xA9, 0xAF, 0x5D, 0xA5, 0xBB, -0x3E, 0x1D, 0x7E, 0xDD, 0xB7, 0x37, 0x4F, 0x53, 0x3D, 0x76, 0xAE, 0xA5, 0xF9, 0x6C, 0xDD, 0x4D, -0xCB, 0x57, 0x62, 0x79, 0xFB, 0x9D, 0x4C, 0x96, 0xFD, 0xDC, 0x48, 0xC6, 0x70, 0xA7, 0x1A, 0x41, -0xC8, 0xA3, 0x86, 0x2D, 0xDC, 0x9F, 0x6E, 0x11, 0x0A, 0xA7, 0xD6, 0x67, 0x77, 0x85, 0xF0, 0xFB, -0xD5, 0xF1, 0xB1, 0x4F, 0x6B, 0x0A, 0x57, 0x75, 0x37, 0x27, 0xEC, 0xC2, 0x2B, 0x9C, 0xA5, 0xD8, -0x92, 0xD8, 0x35, 0xE9, 0xFC, 0xB7, 0x43, 0x71, 0xD9, 0x8D, 0x1D, 0xFE, 0x2B, 0x25, 0xB4, 0xEF, -0xCE, 0xA2, 0x56, 0x2D, 0xB9, 0x2E, 0x7E, 0x54, 0x6D, 0xED, 0xA7, 0xB5, 0xFC, 0x58, 0x2D, 0xFB, -0xB8, 0x92, 0x0D, 0x92, 0xDE, 0x48, 0xF8, 0x6E, 0xC3, 0xCB, 0x42, 0xDA, 0x8A, 0xD4, 0xFF, 0x00, -0xC4, 0x55, 0x1D, 0x52, 0x6C, 0xF4, 0xF5, 0x3C, 0x2B, 0x87, 0xF1, 0x3A, 0x5B, 0xD7, 0xF8, 0x4C, -0xAE, 0xDB, 0xBB, 0x4D, 0x0F, 0x32, 0xFD, 0x05, 0xE7, 0xAE, 0x5E, 0x5F, 0x59, 0xD8, 0x9A, 0x6F, -0x52, 0x5D, 0x54, 0x9B, 0xFD, 0x9E, 0xBC, 0xAE, 0x17, 0xC3, 0x2F, 0x71, 0x3A, 0x9B, 0x74, 0xF6, -0x70, 0xA5, 0x2C, 0xB7, 0x39, 0x7B, 0x30, 0x82, 0xDE, 0x53, 0x93, 0xF0, 0x4B, 0x64, 0x0A, 0x7E, -0xEE, 0x24, 0x63, 0x38, 0x72, 0xD8, 0x8D, 0x28, 0x81, 0xA7, 0x62, 0xB4, 0x7A, 0x5B, 0xB7, 0x7E, -0x5A, 0xE1, 0xF2, 0x76, 0x61, 0x47, 0x51, 0xC5, 0x1A, 0xDA, 0x75, 0x13, 0xA8, 0x95, 0x88, 0x4A, -0x5D, 0x5D, 0xA8, 0xDB, 0xDB, 0x4F, 0x83, 0x7E, 0x86, 0xC4, 0xBD, 0xC2, 0xB8, 0x7F, 0x13, 0xA4, -0xBD, 0x57, 0xC2, 0x5D, 0xDB, 0x77, 0x29, 0xE3, 0xAE, 0xA2, 0x82, 0xF3, 0x53, 0x9C, 0x6D, 0xF5, -0xB9, 0x62, 0x69, 0xB7, 0x28, 0xAD, 0xF3, 0x9C, 0xBF, 0xAB, 0xC9, 0x8A, 0x7E, 0xEE, 0x24, 0x63, -0x45, 0x3E, 0xBB, 0x11, 0xA6, 0x1E, 0x6D, 0xA0, 0x6D, 0x1E, 0x83, 0xE5, 0xDA, 0x0A, 0x3A, 0xEB, -0xF5, 0x7F, 0x8C, 0x85, 0xC9, 0xDA, 0xA7, 0xA1, 0xBD, 0x53, 0xA6, 0xDC, 0xDC, 0x1B, 0x76, 0xDC, -0x36, 0x4D, 0x7D, 0xD6, 0xC7, 0x53, 0xF9, 0x4E, 0xFB, 0xD3, 0x3A, 0x7E, 0x2B, 0x49, 0x9D, 0xBC, -0xC8, 0xDD, 0x85, 0xE4, 0xBB, 0x5A, 0x93, 0x94, 0xBF, 0x85, 0x30, 0x55, 0x38, 0x91, 0x8B, 0x87, -0x3D, 0x87, 0xFF, 0x00, 0x4D, 0x30, 0xF3, 0x4C, 0x49, 0x23, 0xB1, 0xC6, 0xB8, 0x2C, 0xB8, 0x54, -0xED, 0x4A, 0x37, 0x63, 0x53, 0x4D, 0x53, 0x1F, 0x32, 0x9E, 0xA6, 0x0B, 0x0A, 0xEC, 0x3A, 0xA6, -0xBA, 0x4D, 0x65, 0x6A, 0x5D, 0xA7, 0x4B, 0xF0, 0x9C, 0x06, 0x87, 0x85, 0xF0, 0xBA, 0x8A, 0xDA, -0x5A, 0xCB, 0xD7, 0x6B, 0x6D, 0xDD, 0x94, 0xA5, 0x62, 0xA3, 0x46, 0x9F, 0x2A, 0xE2, 0x8F, 0xB3, -0x29, 0x28, 0xF2, 0x92, 0xF8, 0x02, 0xA9, 0xC4, 0x8C, 0x4C, 0x39, 0xEC, 0x74, 0x13, 0x8F, 0x24, -0xD7, 0x30, 0x6D, 0x1D, 0xEF, 0x98, 0x38, 0x55, 0x3F, 0x0F, 0x95, 0x25, 0xEA, 0x4B, 0x97, 0x2E, -0xD2, 0x56, 0xD8, 0xF3, 0xAC, 0x79, 0xA9, 0x79, 0x90, 0x5B, 0x6A, 0xB7, 0x73, 0x1E, 0xAB, 0x71, -0x6E, 0x3B, 0x9B, 0x5F, 0xC2, 0xA9, 0xAF, 0x70, 0x8A, 0x6E, 0x29, 0x41, 0x19, 0xC6, 0x30, 0x7F, -0x87, 0xAF, 0xB2, 0xE6, 0xEE, 0x3B, 0x37, 0xFF, 0x00, 0x2D, 0xD4, 0xE5, 0xFE, 0x5D, 0xD7, 0xFC, -0x2E, 0x51, 0x29, 0x54, 0xE2, 0x48, 0x21, 0x4D, 0xE4, 0x8F, 0x8E, 0xE8, 0xC3, 0xCE, 0x34, 0x0A, -0x48, 0xF4, 0x95, 0x1C, 0x2A, 0x97, 0x87, 0xF0, 0x3B, 0x75, 0x55, 0x71, 0x9B, 0xAE, 0xAF, 0x9E, -0xAA, 0x4B, 0x5A, 0xE5, 0x05, 0x6A, 0x9A, 0x3E, 0xD5, 0xFB, 0x90, 0xFC, 0xDA, 0xD6, 0xD6, 0xD4, -0xBE, 0xD4, 0x5F, 0x88, 0x7A, 0x3A, 0x2E, 0x05, 0x4D, 0xC0, 0x6C, 0xF1, 0x1E, 0x23, 0x4B, 0x57, -0x53, 0x72, 0xF5, 0x65, 0xDA, 0x7F, 0xA0, 0xA8, 0x76, 0xD2, 0x56, 0xE2, 0xE4, 0x9B, 0x4E, 0x4A, -0x3D, 0x0A, 0x5D, 0x38, 0x92, 0x0C, 0x97, 0x64, 0x69, 0x7A, 0xC7, 0x90, 0x92, 0x07, 0x24, 0x7A, -0x0E, 0x29, 0x51, 0xF2, 0xED, 0xDA, 0x67, 0x1A, 0x0A, 0x0A, 0xEA, 0x7A, 0x8D, 0x51, 0xD3, 0x72, -0xF5, 0x54, 0x6E, 0x5B, 0x51, 0xCF, 0xAE, 0xB4, 0xA9, 0x3D, 0xE5, 0x13, 0x82, 0xC1, 0x74, 0xE2, -0x48, 0x05, 0xD9, 0x1A, 0x51, 0x1E, 0x48, 0x46, 0x83, 0x49, 0x03, 0x64, 0x2E, 0x9C, 0x69, 0x00, -0xBA, 0x71, 0xA4, 0x11, 0xE4, 0xB9, 0x89, 0x24, 0x1A, 0x48, 0x13, 0x45, 0x2E, 0x9C, 0x69, 0x04, -0x2E, 0x9C, 0x48, 0xC0, 0x58, 0x8C, 0x2C, 0xBA, 0x83, 0x68, 0x17, 0x4E, 0x34, 0xA0, 0x55, 0x38, -0x91, 0x8C, 0x29, 0x8F, 0x99, 0xA0, 0xBA, 0x71, 0xA5, 0x02, 0xA9, 0xC4, 0x8C, 0x52, 0x94, 0xA6, -0x70, 0xA7, 0x12, 0x41, 0x4A, 0xA7, 0x12, 0x31, 0xEE, 0x97, 0x24, 0x12, 0x3D, 0x04, 0x8F, 0x41, -0xC1, 0x54, 0xE2, 0x48, 0x21, 0x74, 0xE2, 0xE3, 0xB9, 0x89, 0xD4, 0xD2, 0xD2, 0xE2, 0xFB, 0x42, -0x55, 0x43, 0x17, 0x1B, 0x5C, 0xB3, 0x95, 0xE9, 0x23, 0x58, 0x97, 0x22, 0x75, 0xD5, 0xAE, 0xDC, -0x5F, 0x66, 0x19, 0xA2, 0xA9, 0xC6, 0x94, 0x0A, 0xA7, 0x12, 0x31, 0x0D, 0x23, 0x6C, 0xAF, 0x5E, -0x50, 0xFB, 0x49, 0xA5, 0xDE, 0x68, 0xAF, 0xD4, 0x9C, 0x67, 0xDA, 0x8D, 0x37, 0x8E, 0x11, 0xF1, -0xDD, 0x46, 0xCA, 0x7D, 0x76, 0x23, 0x4A, 0x11, 0x2E, 0x7F, 0x03, 0x5F, 0x21, 0xEF, 0x47, 0x45, -0xD7, 0x8E, 0x52, 0x59, 0x5D, 0xCC, 0x57, 0xF1, 0x39, 0x15, 0x4E, 0x24, 0x62, 0xE1, 0x64, 0x69, -0x84, 0x6B, 0xDB, 0x20, 0x54, 0xDB, 0xDC, 0xC0, 0x5A, 0x8E, 0x4C, 0x05, 0x23, 0xFA, 0x6F, 0x48, -0x2A, 0x9C, 0x48, 0xC4, 0x2E, 0xC8, 0xD3, 0x00, 0xFB, 0x35, 0x0D, 0x76, 0x9E, 0xD7, 0xE5, 0x5D, -0x4E, 0xDF, 0x16, 0x56, 0xBF, 0x7E, 0xF8, 0x75, 0xDF, 0x2F, 0x1C, 0xFB, 0x71, 0xDB, 0xEC, 0xFA, -0x4F, 0x17, 0x5F, 0x1F, 0x2A, 0xA6, 0x2F, 0xC5, 0x9D, 0xCE, 0x0F, 0x5D, 0x7A, 0x86, 0xF5, 0xAA, -0x8B, 0x12, 0x4A, 0x70, 0xF1, 0xDE, 0x32, 0x5C, 0x9C, 0x1A, 0xEA, 0xA4, 0x8D, 0x13, 0x4E, 0x24, -0x80, 0x5D, 0x91, 0xA5, 0x17, 0x1B, 0x6D, 0xE1, 0xB1, 0xDC, 0xA7, 0xE0, 0x1C, 0x3E, 0xBE, 0xE4, -0x2C, 0x59, 0xE3, 0x16, 0xE7, 0x7A, 0xE7, 0x2B, 0x6A, 0x92, 0xF6, 0x73, 0x15, 0x96, 0xB2, 0xEE, -0x28, 0xFA, 0xB8, 0x7E, 0xB0, 0x4B, 0x9F, 0xE8, 0x1C, 0x45, 0xF9, 0xCE, 0xE5, 0x47, 0x0D, 0xBB, -0x2D, 0xEE, 0x5B, 0x8D, 0xAF, 0x3A, 0xCE, 0xAE, 0xAE, 0xDA, 0x82, 0x6D, 0x2C, 0xF4, 0x58, 0xEE, -0x12, 0xE7, 0x11, 0xE1, 0xFC, 0x1E, 0xC5, 0xD5, 0xC3, 0x5D, 0xEA, 0x8A, 0xAB, 0x90, 0x76, 0xDD, -0x65, 0xE8, 0x68, 0x56, 0xE1, 0x2F, 0x69, 0xDA, 0x83, 0x4A, 0x59, 0x7E, 0x2D, 0x73, 0xEA, 0x42, -0x9B, 0xBB, 0x89, 0x18, 0xB8, 0x36, 0xBB, 0x1D, 0x04, 0xDD, 0x42, 0x5F, 0x09, 0xB4, 0xED, 0x53, -0x71, 0x3B, 0x76, 0x65, 0xAA, 0xE4, 0x78, 0x75, 0xD8, 0xDB, 0x92, 0x58, 0x72, 0x8C, 0x5B, 0x52, -0x6B, 0xEB, 0x7A, 0xBE, 0x93, 0xC9, 0xA8, 0xA8, 0xA7, 0x2E, 0x89, 0x67, 0xFD, 0x8E, 0xE5, 0x3D, -0x6D, 0xDE, 0x1F, 0xF8, 0x5A, 0x9B, 0x0F, 0x12, 0x84, 0x16, 0xCF, 0xD9, 0x94, 0x5A, 0xC3, 0x8C, -0xD7, 0x54, 0xD7, 0x26, 0x3D, 0x64, 0x7E, 0x5F, 0xAD, 0x8F, 0x98, 0xEF, 0xD4, 0x70, 0xC9, 0x5D, -0x79, 0x95, 0xA5, 0x61, 0xDF, 0x82, 0x97, 0x5F, 0x2D, 0xC1, 0x26, 0x97, 0x8A, 0x78, 0xEE, 0x05, -0x37, 0x77, 0x12, 0x31, 0x71, 0x6D, 0x36, 0x23, 0xE3, 0xBB, 0x88, 0x9F, 0x26, 0x2B, 0x92, 0xE3, -0x76, 0x66, 0xBD, 0x9D, 0x37, 0xBC, 0xC6, 0xF9, 0x79, 0x5E, 0x53, 0xCE, 0x7B, 0x35, 0x69, 0xF7, -0x12, 0x38, 0x0A, 0xFA, 0x0E, 0x3B, 0xE4, 0x7E, 0xF7, 0xF0, 0x33, 0xF2, 0xF1, 0xCF, 0xCB, 0xD5, -0x2D, 0x78, 0xFD, 0x9D, 0x26, 0x4F, 0x88, 0x50, 0x70, 0xEA, 0x4B, 0x94, 0xBC, 0x2A, 0x37, 0x9C, -0xAF, 0xC7, 0x45, 0xEA, 0xDB, 0xE9, 0x2B, 0x92, 0x87, 0x5B, 0x76, 0x62, 0xBD, 0x88, 0x3E, 0xBB, -0x27, 0xD9, 0xF9, 0x97, 0x37, 0x87, 0xD7, 0x5E, 0xE1, 0x95, 0x36, 0xEA, 0x6C, 0x69, 0xD5, 0x0C, -0xE6, 0x32, 0xF6, 0x67, 0x17, 0xB4, 0xAD, 0xCD, 0x78, 0x35, 0xC8, 0x14, 0xDD, 0xDC, 0x48, 0xC7, -0x32, 0xE9, 0xC6, 0x94, 0x73, 0xDA, 0xFF, 0x00, 0x83, 0xBB, 0xF2, 0x6A, 0x92, 0xE3, 0x76, 0x71, -0xEC, 0x2B, 0x57, 0xFC, 0xEF, 0xB3, 0xE5, 0xF9, 0x4F, 0x3A, 0xBE, 0xEE, 0xBD, 0x1E, 0xE0, 0xB7, -0x6D, 0xFC, 0xB9, 0x5F, 0x27, 0x79, 0x5F, 0xA9, 0xE1, 0x92, 0x96, 0xF3, 0xB1, 0xE4, 0x3A, 0x8B, -0x6A, 0x5D, 0x7C, 0xA9, 0x46, 0x2D, 0xA5, 0xD8, 0xF1, 0xF5, 0x41, 0x54, 0x71, 0x3A, 0x0A, 0x0A, -0x4B, 0xB4, 0x9C, 0x26, 0x17, 0xB5, 0x54, 0x47, 0x4D, 0x45, 0x6D, 0xF4, 0x95, 0xC9, 0xDB, 0xEB, -0x6A, 0xDC, 0x57, 0xB1, 0x09, 0x75, 0xD9, 0x4B, 0xFA, 0xC8, 0x53, 0x77, 0x71, 0x23, 0x14, 0xBB, -0x23, 0x4A, 0x17, 0xE5, 0x8C, 0x79, 0x9C, 0x63, 0x4F, 0xB3, 0xFE, 0x91, 0x59, 0x8E, 0xEC, 0xC3, -0x1E, 0xE3, 0xCE, 0xBE, 0x9D, 0xC7, 0x6F, 0x80, 0x57, 0xD2, 0x50, 0x5E, 0xAA, 0xFC, 0x57, 0x9B, -0xE5, 0x54, 0x51, 0x5E, 0xA6, 0xCD, 0x98, 0xA9, 0x49, 0x3B, 0x8E, 0x1B, 0xA4, 0xDC, 0x63, 0xEC, -0xA6, 0x12, 0x30, 0xF9, 0x56, 0x1E, 0xB4, 0xAE, 0xF1, 0x8B, 0xC9, 0x7F, 0x97, 0xE5, 0xD9, 0xB7, -0xAB, 0xB2, 0x52, 0xF5, 0x7F, 0x9A, 0x21, 0x54, 0xE2, 0x46, 0x29, 0x6F, 0xE4, 0xD7, 0xFE, 0xB4, -0xA3, 0x2A, 0x32, 0xFE, 0x52, 0xA3, 0xF3, 0x33, 0xA9, 0x71, 0x4B, 0xAA, 0xC6, 0x7F, 0xB2, 0xF2, -0xE7, 0xAF, 0x4F, 0x66, 0xBC, 0xFE, 0xD1, 0x36, 0xF5, 0x47, 0x09, 0xA7, 0xE0, 0x9F, 0x2F, 0xFF, -0x00, 0xA8, 0x51, 0x5E, 0xAC, 0xFA, 0x1A, 0x9D, 0x1A, 0x2F, 0xCA, 0xD4, 0x62, 0xBC, 0xD8, 0xEB, -0x53, 0x51, 0x92, 0xD7, 0xAB, 0x6F, 0x81, 0xC6, 0xE3, 0x5C, 0x59, 0xF1, 0x49, 0x59, 0x85, 0xBB, -0x51, 0xA5, 0xA4, 0xA6, 0x86, 0x8A, 0x7A, 0x78, 0xEE, 0xA1, 0x1E, 0xAD, 0xBE, 0xB3, 0x78, 0xF5, -0x9F, 0xF8, 0x93, 0x7F, 0x1B, 0xC0, 0xAB, 0x78, 0x6F, 0x0C, 0xA6, 0xAD, 0xBB, 0xC4, 0x2D, 0x5C, -0xA2, 0xB7, 0x76, 0x0F, 0xF0, 0xF6, 0xAD, 0x4A, 0x2F, 0xCD, 0xB8, 0xA5, 0xCE, 0x79, 0xFB, 0x2B, -0xA0, 0x2A, 0x9C, 0x48, 0xC5, 0x2E, 0xC8, 0xD3, 0x0B, 0xF3, 0x54, 0x6D, 0xF1, 0x3A, 0x4A, 0x4E, -0x2F, 0x47, 0x37, 0xF8, 0x38, 0xE2, 0x89, 0x52, 0xBB, 0x6A, 0xDB, 0xA3, 0x94, 0x21, 0x95, 0x08, -0xE3, 0x69, 0xA9, 0x6E, 0xF3, 0xD3, 0xD5, 0xF4, 0x44, 0xF9, 0x3E, 0xA7, 0x4F, 0x14, 0x8D, 0x15, -0xC8, 0xC6, 0xED, 0x2F, 0x10, 0x8C, 0xA9, 0xEA, 0x2C, 0xCF, 0xD8, 0x9A, 0xD3, 0x27, 0x19, 0xF7, -0xA6, 0xB1, 0x17, 0xF7, 0x99, 0x9C, 0x5F, 0x8A, 0xD1, 0xCE, 0x8A, 0xCF, 0x0C, 0xE1, 0xB6, 0xAF, -0x5B, 0xA3, 0xB5, 0x75, 0xDF, 0x9D, 0xCB, 0xED, 0x3B, 0xD7, 0xAF, 0x35, 0x8D, 0x53, 0x4B, 0x68, -0xA8, 0xAE, 0x4B, 0x6C, 0xF8, 0x6C, 0x41, 0xE0, 0x95, 0xB6, 0xB8, 0x6F, 0x14, 0xA3, 0xAB, 0xBF, -0xAB, 0xCA, 0xB3, 0x77, 0x54, 0xB4, 0x2D, 0x52, 0xC3, 0x8C, 0xA3, 0xB2, 0xEB, 0xCC, 0xA5, 0x53, -0x89, 0x18, 0x61, 0x64, 0x69, 0x82, 0xFC, 0xC7, 0xC4, 0x2E, 0xF1, 0x2E, 0x29, 0x55, 0x76, 0xE2, -0x51, 0x50, 0xB9, 0x3B, 0x16, 0xAD, 0xAF, 0x66, 0xD5, 0x9B, 0x32, 0x94, 0x61, 0x08, 0x63, 0xC5, -0x2D, 0x5F, 0x59, 0xB3, 0xB3, 0x4D, 0x7F, 0x87, 0x53, 0xFC, 0xA7, 0x48, 0xEB, 0xE8, 0x67, 0x5D, -0x6D, 0xF1, 0x4A, 0x85, 0x08, 0x46, 0xA2, 0x74, 0xEE, 0x12, 0xF2, 0xDF, 0xAC, 0xDC, 0x73, 0x9F, -0x57, 0x31, 0xD2, 0x79, 0x9A, 0xC9, 0xC6, 0xF5, 0x45, 0xFB, 0xB1, 0xCE, 0x99, 0xDE, 0xBB, 0x35, -0x95, 0x87, 0x89, 0xDC, 0x6D, 0x6A, 0xF8, 0x9D, 0xBA, 0x4A, 0xFE, 0x07, 0x7B, 0x82, 0x59, 0xE1, -0xBC, 0x46, 0xE5, 0x7D, 0xA9, 0xD9, 0xAC, 0xBB, 0x50, 0xA5, 0x4B, 0x6A, 0xDC, 0xD3, 0x57, 0x22, -0xE2, 0x93, 0x73, 0xCF, 0x8F, 0x81, 0x4B, 0xA7, 0x12, 0x41, 0x0A, 0xD1, 0xFB, 0x36, 0xFF, 0x00, -0x4F, 0x8E, 0xEA, 0xDF, 0x90, 0xE5, 0xF1, 0x4A, 0xDE, 0x07, 0x51, 0x4E, 0xE1, 0x43, 0xC2, 0x6F, -0x51, 0x5E, 0xD7, 0x17, 0xE7, 0x4E, 0xBA, 0xED, 0xF5, 0xA5, 0x67, 0x31, 0xF2, 0xE5, 0x9F, 0x6B, -0xC7, 0xF2, 0x9C, 0x46, 0x8E, 0xEF, 0x13, 0xB5, 0xF2, 0xFC, 0x69, 0xF3, 0xC3, 0xEA, 0x38, 0x95, -0xCB, 0xFA, 0xE2, 0xB4, 0xD4, 0xD9, 0xB1, 0x1B, 0x5A, 0x3F, 0x33, 0xCC, 0x31, 0x2C, 0xF2, 0xD2, -0x70, 0xE4, 0x0B, 0xA7, 0x12, 0x41, 0x0B, 0x6E, 0xEE, 0x34, 0x80, 0x32, 0x40, 0x64, 0x1E, 0x48, -0x14, 0x8A, 0x5D, 0x38, 0x92, 0x08, 0x5D, 0x38, 0xD2, 0x81, 0x48, 0x0C, 0x83, 0xB0, 0x52, 0x4C, -0x15, 0x4E, 0x24, 0x82, 0x17, 0x4E, 0x24, 0x80, 0x32, 0x59, 0x04, 0xC3, 0xB0, 0x4F, 0xA8, 0x2E, -0x9C, 0x69, 0x00, 0xBA, 0x71, 0x23, 0x03, 0x65, 0x35, 0xF5, 0x30, 0xC9, 0x6F, 0xDD, 0xC4, 0x90, -0x0A, 0xA7, 0x12, 0x31, 0x4A, 0x52, 0x82, 0xA9, 0xC4, 0x90, 0x0A, 0xA7, 0x12, 0x31, 0xEE, 0x94, -0xB6, 0x43, 0x64, 0x02, 0x66, 0xEA, 0x21, 0x74, 0xE2, 0x46, 0x2E, 0x14, 0xE2, 0x48, 0x25, 0xD8, -0x9A, 0xC9, 0xD5, 0xB1, 0xEB, 0x41, 0xC7, 0xC5, 0x7B, 0xCE, 0x1C, 0x27, 0x86, 0x8E, 0xAD, 0x2D, -0xCE, 0x46, 0x89, 0xA7, 0x12, 0x41, 0x92, 0xE9, 0xC4, 0x8C, 0x6C, 0xE3, 0x86, 0x25, 0xC8, 0x6A, -0x89, 0x2A, 0xF4, 0x33, 0xBF, 0x60, 0x14, 0x6D, 0xBC, 0x4B, 0x8B, 0x8E, 0xEA, 0x29, 0x2F, 0xDD, -0xC5, 0xC3, 0x74, 0x01, 0x97, 0xD3, 0x52, 0xA9, 0xAD, 0xE5, 0x65, 0xE1, 0xF8, 0xE0, 0x48, 0xC9, -0x49, 0x26, 0x12, 0xDC, 0x95, 0x3D, 0x46, 0x25, 0xFB, 0xBB, 0xCB, 0x44, 0xBB, 0x33, 0xD4, 0x14, -0xA0, 0xE9, 0xAF, 0x4E, 0xCC, 0xBC, 0x73, 0x17, 0xE2, 0x8E, 0x65, 0x37, 0x77, 0x12, 0x31, 0xD0, -0xA7, 0xF2, 0x46, 0x98, 0x06, 0xA1, 0x6C, 0xC8, 0x36, 0x25, 0xA6, 0xFA, 0xEF, 0x3A, 0x37, 0x7D, -0x64, 0x72, 0x6E, 0xFD, 0x1D, 0xE8, 0xBE, 0xD2, 0x94, 0xDD, 0xDC, 0x49, 0x04, 0xC3, 0x96, 0xC4, -0x69, 0x44, 0xEE, 0x35, 0x67, 0xD4, 0x8D, 0xD5, 0xE0, 0x98, 0x4E, 0x1D, 0x73, 0x5D, 0xB5, 0x8F, -0x02, 0x65, 0xCB, 0x6A, 0xAA, 0x8B, 0xB9, 0x1C, 0x8E, 0x1F, 0x27, 0x6A, 0x6E, 0xDB, 0xE8, 0xF0, -0x52, 0xA9, 0xC4, 0x90, 0x0B, 0xE7, 0xB1, 0x1A, 0x51, 0xDF, 0x82, 0xD8, 0x1D, 0xF5, 0xEA, 0x3E, -0xE0, 0x96, 0xF9, 0x1B, 0x71, 0x66, 0x2C, 0x85, 0xD3, 0x8D, 0x20, 0xD9, 0x56, 0x74, 0x38, 0x10, -0x25, 0x43, 0xE9, 0x28, 0xEC, 0x4B, 0x9E, 0xD8, 0x7E, 0x83, 0x9B, 0x59, 0xEB, 0x5F, 0xB7, 0x0F, -0xB3, 0x1C, 0xBE, 0xF6, 0x4F, 0xE1, 0x72, 0xF3, 0x29, 0x27, 0x0E, 0xB6, 0xAE, 0x35, 0xE8, 0x64, -0x1B, 0xAB, 0x35, 0xB7, 0xBE, 0xEA, 0x8A, 0xF7, 0x02, 0xE9, 0xC6, 0x90, 0x1B, 0x4F, 0x43, 0xA1, -0xC7, 0x77, 0x1B, 0xA7, 0x61, 0x25, 0x10, 0xC2, 0x34, 0x0B, 0xA7, 0x1A, 0x41, 0xCF, 0x06, 0xF2, -0x46, 0x94, 0x09, 0xAE, 0x62, 0x35, 0xCC, 0x2B, 0x58, 0xC8, 0x8C, 0x17, 0x4E, 0x34, 0x82, 0x17, -0x64, 0x69, 0x40, 0x5A, 0x11, 0xF7, 0x86, 0x92, 0x06, 0xC8, 0x5D, 0x38, 0xD2, 0x01, 0x76, 0x46, -0x94, 0x0D, 0x83, 0x90, 0x47, 0xE2, 0x2C, 0x81, 0x74, 0xE2, 0x48, 0x29, 0x76, 0x46, 0x94, 0x09, -0x83, 0x90, 0x56, 0x84, 0x60, 0xAA, 0x71, 0x23, 0x14, 0xB7, 0xD7, 0x62, 0x34, 0xA0, 0x2C, 0x49, -0x20, 0xAD, 0x60, 0x1B, 0x05, 0x53, 0x89, 0x18, 0x61, 0x64, 0x69, 0xBD, 0xFF, 0x00, 0x58, 0x0C, -0xB6, 0x05, 0x20, 0xF2, 0x05, 0x20, 0x55, 0x38, 0x91, 0x81, 0x4F, 0xDD, 0xEB, 0xCF, 0xBB, 0xE7, -0xEF, 0xFE, 0x14, 0x01, 0xF5, 0x06, 0xC2, 0xC8, 0x1C, 0xBA, 0x82, 0xA9, 0xC4, 0x8C, 0x0B, 0xC3, -0x5E, 0xCF, 0x4E, 0x7D, 0xDF, 0xB7, 0xF8, 0x4E, 0xA7, 0x70, 0x06, 0x0E, 0x48, 0x34, 0x81, 0xB3, -0x45, 0x72, 0xEC, 0xE2, 0x4A, 0x32, 0x5B, 0x77, 0x71, 0x24, 0x00, 0x60, 0xE4, 0x82, 0xCB, 0xA8, -0x39, 0x19, 0x2F, 0x9F, 0x67, 0x1A, 0x31, 0x0B, 0xA7, 0x12, 0x30, 0x26, 0x27, 0x21, 0xD8, 0xBD, -0x48, 0x5D, 0x38, 0xD2, 0x01, 0x54, 0xE2, 0x46, 0x29, 0x4A, 0x50, 0x5D, 0x91, 0xA5, 0x02, 0xA9, -0xC4, 0x8C, 0x7B, 0x29, 0x66, 0x12, 0x71, 0x7D, 0x1E, 0x0C, 0xC9, 0x22, 0xBE, 0xDE, 0x99, 0xEA, -0x5E, 0x92, 0x16, 0xB2, 0x95, 0x4A, 0x24, 0x43, 0xA9, 0x65, 0x65, 0xE8, 0x47, 0xEA, 0xFB, 0x37, -0x53, 0x83, 0xA6, 0x4E, 0xA3, 0xBD, 0x87, 0x83, 0x98, 0xA4, 0x1A, 0xD5, 0xCD, 0x2C, 0xD1, 0x14, -0xE2, 0xE1, 0xB9, 0x89, 0x81, 0x59, 0x7A, 0x11, 0xFA, 0xBE, 0xCD, 0xFF, 0x00, 0xB5, 0xC7, 0xA7, -0xB6, 0xFC, 0xC8, 0x63, 0xE0, 0x06, 0x71, 0xD2, 0xC0, 0xD1, 0xDF, 0xCE, 0x37, 0x27, 0x5C, 0x82, -0x92, 0xD5, 0xD8, 0x74, 0x6B, 0x23, 0xE3, 0xBA, 0x8C, 0xE1, 0x86, 0x9D, 0x9F, 0x3F, 0xD3, 0xE3, -0xBA, 0x75, 0x7A, 0xC4, 0x1B, 0xF6, 0xBC, 0xEB, 0x6D, 0x76, 0x65, 0x3E, 0xD0, 0x6F, 0x35, 0xD4, -0xBA, 0x97, 0xFE, 0xCD, 0x2E, 0xD2, 0x5D, 0x65, 0x0F, 0x12, 0x56, 0x30, 0xC8, 0x97, 0xBC, 0xCA, -0x3B, 0xD1, 0xAB, 0xB2, 0xB3, 0x8D, 0xA7, 0x1F, 0xB5, 0x1E, 0xA8, 0xE4, 0x55, 0x38, 0x92, 0x08, -0x4B, 0xF7, 0x71, 0x70, 0xDD, 0x3A, 0xC4, 0x78, 0x4D, 0x4E, 0x29, 0xF6, 0x10, 0x2B, 0xED, 0x65, -0x36, 0xBB, 0xCE, 0xA5, 0x6D, 0xA8, 0x5A, 0x70, 0xAA, 0xB1, 0xEB, 0x52, 0xD4, 0x6F, 0xFF, 0x00, -0x8A, 0x7D, 0x54, 0x88, 0xF7, 0x23, 0xE6, 0x47, 0x1D, 0x85, 0x2E, 0x9C, 0x69, 0x07, 0x42, 0xFD, -0x2D, 0x88, 0xD3, 0x38, 0x93, 0xC0, 0xEF, 0x2B, 0xD6, 0xB4, 0x3D, 0xF6, 0xC6, 0x08, 0xB5, 0xD4, -0xCE, 0x9A, 0xA3, 0x5A, 0xE4, 0xDE, 0xE4, 0x7E, 0x1F, 0x75, 0xD1, 0xD4, 0xE9, 0xE8, 0xD9, 0xE9, -0x2B, 0x69, 0x95, 0x55, 0x95, 0x35, 0xE1, 0xBE, 0x3C, 0x41, 0x74, 0xE3, 0x48, 0x29, 0x78, 0xE9, -0xB1, 0xD0, 0x4F, 0xD4, 0x21, 0x52, 0xDC, 0xD5, 0x15, 0xEF, 0x25, 0xF3, 0x47, 0x2A, 0x9F, 0x36, -0xA6, 0xE0, 0xF6, 0xE8, 0x74, 0xE0, 0xF2, 0x88, 0x5D, 0x38, 0xD2, 0x06, 0x3C, 0xB6, 0x3A, 0x1F, -0xB0, 0x33, 0x86, 0xCF, 0xCA, 0xAD, 0xB9, 0x65, 0xF2, 0xBD, 0x0C, 0xAF, 0xAC, 0x81, 0xB5, 0xFF, -0x00, 0xEC, 0xAB, 0xFF, 0x00, 0xC8, 0x97, 0xB9, 0x09, 0x59, 0xAA, 0xCB, 0xB7, 0x51, 0x0C, 0xE6, -0xCC, 0x94, 0xBB, 0xD7, 0x54, 0x1A, 0x72, 0x8C, 0xEA, 0xEA, 0x27, 0x06, 0x9C, 0x6E, 0xAB, 0x37, -0x62, 0xD7, 0x84, 0xE1, 0xFE, 0xE9, 0x82, 0xE9, 0xC6, 0x90, 0x63, 0x17, 0xF2, 0x47, 0xC7, 0x75, -0x18, 0xD6, 0x05, 0x08, 0xC4, 0x05, 0xD3, 0x8D, 0x20, 0x17, 0x64, 0x69, 0x80, 0xDF, 0x51, 0x1F, -0x50, 0xAC, 0x1B, 0x40, 0xBA, 0x71, 0xA4, 0x13, 0x0B, 0x23, 0x4C, 0x04, 0xD7, 0x30, 0x6D, 0x06, -0x60, 0xDF, 0x32, 0x17, 0x4E, 0x34, 0xA0, 0x5D, 0x91, 0xA5, 0x01, 0x92, 0x15, 0x85, 0x60, 0x81, -0x74, 0xE2, 0x48, 0x26, 0x16, 0x46, 0x94, 0x0E, 0x40, 0xE4, 0x19, 0x82, 0x60, 0xBA, 0x71, 0x23, -0x0C, 0x29, 0xC6, 0x94, 0x0E, 0x40, 0xDF, 0x50, 0xAD, 0x03, 0x60, 0xAA, 0x71, 0x23, 0x02, 0x9D, -0xDB, 0x62, 0x34, 0xA0, 0x52, 0x05, 0x30, 0xF3, 0xD8, 0x14, 0x81, 0x54, 0xE2, 0x46, 0x34, 0x5B, -0xE2, 0xFD, 0x9E, 0xAD, 0xA7, 0x77, 0xE5, 0xE4, 0xDF, 0xC2, 0xFB, 0xBF, 0xB7, 0x20, 0x06, 0x0A, -0x41, 0xA4, 0x0E, 0x45, 0x26, 0x9C, 0x5C, 0x37, 0x40, 0x2F, 0x06, 0x7E, 0xCF, 0x4C, 0xBF, 0x4F, -0xC7, 0x97, 0xF2, 0xBF, 0x7B, 0x80, 0x48, 0x1B, 0x09, 0x20, 0x6C, 0x60, 0xFD, 0xDC, 0x5C, 0x77, -0x40, 0xC1, 0xB3, 0x6E, 0xCF, 0x56, 0x7A, 0x7F, 0xD7, 0xF9, 0x5F, 0x7F, 0xB7, 0x80, 0x0C, 0x81, -0xB0, 0xD3, 0x04, 0xCC, 0x97, 0x4E, 0x3E, 0x1B, 0xA0, 0x85, 0x53, 0xF4, 0x5E, 0x97, 0xF5, 0xFE, -0x53, 0xEE, 0x01, 0x7B, 0x08, 0xF6, 0x08, 0xD6, 0x32, 0x23, 0x29, 0x76, 0x46, 0x94, 0x0A, 0xD8, -0xF9, 0x7C, 0xDE, 0x97, 0xBB, 0xFD, 0xA7, 0xF6, 0xFA, 0xC6, 0x14, 0xA5, 0x21, 0x74, 0xE2, 0x48, -0x29, 0x58, 0x37, 0xCB, 0xF4, 0xB1, 0xA4, 0x93, 0xAB, 0xD6, 0xC3, 0xE8, 0x95, 0xB6, 0xD4, 0xBF, -0x99, 0xC3, 0xBB, 0x1D, 0x12, 0x7D, 0x0F, 0x4B, 0x76, 0x0A, 0x69, 0x35, 0x86, 0x9A, 0xCA, 0x7E, -0x27, 0x1E, 0xB2, 0xC1, 0x4A, 0x6E, 0xEE, 0x24, 0x63, 0x58, 0x19, 0x93, 0xEC, 0x73, 0xFD, 0x34, -0xDD, 0x6E, 0x20, 0xA9, 0x05, 0x84, 0xB2, 0x44, 0xC6, 0x97, 0x86, 0x1E, 0xDC, 0x8D, 0x12, 0xFD, -0xDC, 0x48, 0xC4, 0xC1, 0xDD, 0xF6, 0x39, 0xFE, 0x9A, 0x51, 0xD2, 0xA5, 0xBD, 0xA1, 0x9D, 0xFA, -0x5B, 0xCA, 0x69, 0x1E, 0x62, 0xD9, 0x3E, 0x96, 0xA1, 0xC1, 0xAE, 0x66, 0xED, 0x2A, 0x2F, 0xC5, -0xBA, 0x88, 0x5D, 0x91, 0xA5, 0x1D, 0xBB, 0x90, 0xEA, 0x81, 0xB8, 0xA6, 0xB7, 0xF8, 0x04, 0xB1, -0x7A, 0x37, 0x62, 0x97, 0xBF, 0xC0, 0xB2, 0xB7, 0x86, 0x73, 0x2E, 0x9C, 0x49, 0x00, 0xBC, 0x7C, -0x91, 0xA5, 0xEA, 0x1C, 0xE8, 0x38, 0xF0, 0xF9, 0xCE, 0xDD, 0xD8, 0xBB, 0x94, 0x55, 0x1B, 0x5C, -0x87, 0xF6, 0x6E, 0x5F, 0x9E, 0x24, 0x7A, 0x9A, 0x59, 0xD0, 0xDC, 0x8C, 0x25, 0x2F, 0x32, 0xCD, -0xC5, 0x9B, 0x17, 0x97, 0x29, 0xC7, 0xC2, 0x4F, 0xED, 0xC4, 0xEB, 0x4A, 0xDC, 0x67, 0x17, 0x19, -0x24, 0xD3, 0xD9, 0xA2, 0x2C, 0x34, 0xD2, 0xC2, 0x54, 0xB5, 0x51, 0x77, 0xA8, 0xAE, 0x3C, 0xA7, -0xF9, 0xAC, 0x4B, 0xED, 0xC1, 0x94, 0xBA, 0x71, 0x24, 0x1B, 0x29, 0xB4, 0xD8, 0xE8, 0x70, 0xDD, -0xC7, 0x26, 0xA2, 0xCE, 0xBF, 0x5A, 0x3C, 0xD6, 0xE7, 0x6F, 0x82, 0xD6, 0xAB, 0xB0, 0xF2, 0x6E, -0x3E, 0x98, 0x79, 0xFE, 0x64, 0x1A, 0xCA, 0x1B, 0x94, 0x2E, 0x2F, 0x57, 0x9D, 0x62, 0xE6, 0xF6, -0xAA, 0x23, 0xBC, 0x64, 0xBC, 0x27, 0xE0, 0xC8, 0xD1, 0xCD, 0xA9, 0xAB, 0x90, 0xE7, 0xCD, 0xAF, -0x12, 0x17, 0x4E, 0x34, 0x83, 0xA6, 0x0F, 0xE5, 0xE8, 0xFE, 0xC8, 0xEC, 0x57, 0xD0, 0xB8, 0x4D, -0xC9, 0x77, 0x81, 0xB3, 0x3D, 0x92, 0x67, 0x56, 0x86, 0xA2, 0xDF, 0x12, 0xB2, 0xAD, 0xC9, 0xA5, -0x71, 0x2F, 0x57, 0xB7, 0xEE, 0x7F, 0x74, 0x87, 0x51, 0x4B, 0x2B, 0x53, 0x7B, 0x63, 0xC4, 0x17, -0x4E, 0x34, 0x83, 0x1F, 0xE4, 0xF6, 0xE1, 0xC7, 0x77, 0x0B, 0x24, 0xA7, 0x16, 0x9F, 0x54, 0x41, -0xA2, 0xCD, 0xAB, 0xF2, 0xB1, 0x2F, 0xC9, 0x0F, 0x51, 0xBE, 0xB0, 0xD7, 0x95, 0xFC, 0x39, 0x71, -0x25, 0xC2, 0x58, 0x32, 0x76, 0xD7, 0x9B, 0x0B, 0xAB, 0x9C, 0x5B, 0x4F, 0xBA, 0x5B, 0x30, 0x5D, -0x38, 0xD2, 0x0E, 0x18, 0x59, 0x1A, 0x40, 0x56, 0x0D, 0xA0, 0xAC, 0x1B, 0x5C, 0xC1, 0x74, 0xE3, -0x4A, 0x29, 0x74, 0xE3, 0x48, 0x11, 0x89, 0x2E, 0xA3, 0xB1, 0x1E, 0xE0, 0xBB, 0x23, 0x4A, 0x05, -0xD3, 0x8D, 0x28, 0x1B, 0x06, 0xF9, 0x84, 0x7D, 0x44, 0x97, 0x52, 0x17, 0x64, 0x69, 0x45, 0x2E, -0xC8, 0xD2, 0x81, 0x30, 0x6F, 0xC4, 0x2B, 0x06, 0xCA, 0x5D, 0x38, 0xD2, 0x08, 0x5D, 0x91, 0xA5, -0x08, 0xC1, 0x30, 0xAC, 0x14, 0x88, 0x55, 0x38, 0x91, 0x8A, 0x5D, 0x91, 0xA5, 0x08, 0xC4, 0x51, -0xCC, 0xBD, 0xE3, 0x4B, 0x60, 0xB6, 0xE1, 0xB3, 0x60, 0xAA, 0x71, 0x23, 0x10, 0xBB, 0x23, 0x4A, -0x22, 0x5E, 0xE6, 0x05, 0x87, 0xBB, 0xBB, 0x60, 0x18, 0x2B, 0x9F, 0x67, 0x12, 0x31, 0x0B, 0xB2, -0x34, 0xA0, 0x2C, 0x1B, 0x5C, 0xC2, 0xBD, 0x81, 0x4C, 0xD1, 0x7C, 0xBB, 0x38, 0x92, 0x0A, 0x5D, -0x38, 0xD2, 0x00, 0xCC, 0x13, 0x0D, 0x20, 0x4F, 0xA9, 0x92, 0xA9, 0xC5, 0xC3, 0x74, 0x02, 0x9D, -0xDB, 0xB3, 0xD1, 0xFF, 0x00, 0x4D, 0x20, 0x14, 0x81, 0x30, 0xD2, 0x04, 0xC8, 0x5D, 0x91, 0xA5, -0x14, 0xB3, 0x32, 0xF9, 0x7A, 0xBF, 0xE9, 0xA4, 0xEB, 0x7F, 0x88, 0x14, 0x81, 0x3E, 0xA1, 0x64, -0x0D, 0xF5, 0x05, 0xD3, 0x89, 0x20, 0xA5, 0x9B, 0x9F, 0xCB, 0xE6, 0xD4, 0xBD, 0xCD, 0xFD, 0xD3, -0xAD, 0xC6, 0x14, 0xA5, 0x29, 0x4D, 0xAF, 0x67, 0x12, 0x30, 0x2C, 0xCC, 0xFE, 0x5F, 0x36, 0xA5, -0xEE, 0x6F, 0xEE, 0x9D, 0x6E, 0x3E, 0x87, 0x47, 0x7F, 0x4A, 0xD1, 0x2F, 0x67, 0xA7, 0x60, 0x7A, -0x8B, 0x0A, 0x71, 0xF4, 0x73, 0xF1, 0x39, 0x96, 0xA4, 0x74, 0xE9, 0xEF, 0x26, 0x94, 0x65, 0xFE, -0x00, 0xAA, 0x71, 0x23, 0x02, 0xDB, 0xC9, 0x1A, 0x51, 0xC1, 0xAB, 0xA7, 0x70, 0x79, 0x48, 0x15, -0xAD, 0xF1, 0xEF, 0x3D, 0x05, 0x5D, 0x2A, 0x9A, 0x6D, 0x63, 0xC7, 0x63, 0x83, 0x76, 0xD4, 0xAC, -0x4F, 0x3D, 0x33, 0xBA, 0x29, 0x54, 0xE2, 0x46, 0x29, 0x6D, 0xE4, 0x8D, 0x28, 0x95, 0x6D, 0x07, -0x51, 0xCE, 0x1F, 0x20, 0x36, 0x5A, 0x9A, 0x4D, 0x7A, 0x51, 0x32, 0xDC, 0x4E, 0x98, 0x79, 0x4B, -0x85, 0x20, 0xD1, 0x78, 0xF9, 0x3A, 0x09, 0xFA, 0x81, 0x29, 0xEF, 0xBB, 0x6C, 0xEB, 0xD9, 0xBF, -0x1B, 0xA9, 0x26, 0x72, 0x1D, 0x9C, 0xAC, 0xA1, 0xAD, 0xCE, 0x56, 0xDF, 0x54, 0x73, 0x2F, 0xC0, -0xB8, 0x92, 0x0D, 0xE1, 0x8E, 0x9B, 0x3D, 0x0F, 0xD9, 0xEA, 0x1D, 0x97, 0x1C, 0x09, 0x28, 0xA9, -0x2C, 0x35, 0x90, 0x56, 0x2A, 0x94, 0x92, 0x52, 0x24, 0x3C, 0x3E, 0x45, 0x2A, 0x9C, 0x49, 0x05, -0xC7, 0x4F, 0x47, 0xA3, 0xFB, 0x22, 0x3D, 0xA9, 0x4E, 0x89, 0x4A, 0x1A, 0x15, 0x45, 0x2C, 0xFD, -0xBB, 0x12, 0xDF, 0x1D, 0xB0, 0xF0, 0x90, 0x2B, 0xFC, 0x29, 0x4E, 0x0E, 0xA2, 0x82, 0x4E, 0xF5, -0x95, 0xBC, 0xED, 0x3F, 0xDE, 0xDA, 0xEC, 0x92, 0xEB, 0x1F, 0xBC, 0x4B, 0x62, 0x45, 0x4A, 0xD5, -0xCF, 0x36, 0xCC, 0xA5, 0x6A, 0xE2, 0xDF, 0x31, 0x78, 0xCF, 0xD6, 0x05, 0xD3, 0x8D, 0x20, 0xC6, -0x2F, 0xAE, 0xCF, 0x41, 0x38, 0xE4, 0xDA, 0x9C, 0xEC, 0xCF, 0x54, 0x5E, 0x99, 0x27, 0xBF, 0x4F, -0x89, 0xE8, 0xE9, 0x2B, 0x6C, 0x71, 0x48, 0x2B, 0x77, 0x9A, 0x85, 0xF4, 0xB0, 0xA4, 0xDE, 0x14, -0xFB, 0x25, 0xF7, 0xBE, 0xF0, 0x09, 0xFE, 0x0E, 0xBF, 0x6A, 0xA8, 0x2A, 0x6B, 0xDD, 0x2F, 0xDB, -0x5F, 0x46, 0xFE, 0xBC, 0x23, 0xCB, 0xEB, 0x47, 0xF8, 0x48, 0x95, 0x3C, 0x22, 0xA6, 0x95, 0x2B, -0x91, 0xFA, 0x4B, 0x7F, 0x96, 0xE5, 0xB7, 0xAA, 0x2F, 0xB9, 0xC7, 0xFF, 0x00, 0x91, 0x0B, 0xA7, -0x1A, 0x41, 0x82, 0xDD, 0xFD, 0x08, 0xD3, 0x09, 0x35, 0x54, 0x53, 0xB3, 0x26, 0x9C, 0x5A, 0x6B, -0xA1, 0x1B, 0x78, 0xF3, 0x24, 0xD2, 0x71, 0x89, 0x42, 0x2A, 0xCD, 0x64, 0x1D, 0xEB, 0x7C, 0x93, -0xE5, 0x72, 0x1D, 0xCF, 0xAA, 0xFB, 0xB2, 0x25, 0xBA, 0x2B, 0x35, 0x71, 0xD7, 0x49, 0x72, 0x37, -0x96, 0x32, 0xE0, 0xB6, 0xB9, 0x1F, 0xAD, 0x0F, 0x6B, 0xFE, 0xA0, 0xBA, 0x71, 0xA4, 0x0C, 0x19, -0x9F, 0x62, 0x34, 0xC3, 0x98, 0x2B, 0xE4, 0x16, 0xE5, 0x89, 0xDB, 0x78, 0x6B, 0x1E, 0x29, 0xAC, -0x02, 0x69, 0xA0, 0x5D, 0x91, 0xA5, 0x19, 0xC3, 0x1D, 0x3B, 0x38, 0xD2, 0xF5, 0x05, 0x7D, 0x44, -0x7D, 0x46, 0x62, 0xBE, 0xA0, 0xBB, 0x23, 0x4A, 0x21, 0x74, 0xE3, 0x48, 0x06, 0xFA, 0x83, 0x97, -0x50, 0x8F, 0xA8, 0x39, 0x02, 0xEC, 0x8D, 0x28, 0x15, 0x4E, 0x24, 0x80, 0x6C, 0x1B, 0xEA, 0x11, -0x83, 0x7D, 0x48, 0x5D, 0x38, 0xD2, 0x01, 0x74, 0xE3, 0x4A, 0x11, 0x83, 0x61, 0x18, 0x9A, 0x5C, -0x9A, 0x05, 0x53, 0x89, 0x18, 0x17, 0x4E, 0x34, 0xA1, 0x61, 0x0D, 0x4C, 0x3C, 0xB1, 0x18, 0xBE, -0xEC, 0x8F, 0x6E, 0xDE, 0x94, 0x0A, 0xA6, 0x58, 0x88, 0x2E, 0x9C, 0x48, 0xC0, 0xBA, 0x71, 0xA5, -0x10, 0x27, 0xD4, 0x0B, 0x0A, 0xFA, 0x82, 0x65, 0x22, 0x9C, 0x5C, 0x37, 0x40, 0x2E, 0x9C, 0x69, -0x00, 0xE4, 0x06, 0x61, 0x64, 0x0A, 0x63, 0x07, 0xD7, 0xB3, 0x8B, 0x8E, 0xE6, 0x21, 0x74, 0xE2, -0x48, 0x05, 0x20, 0x4C, 0x2C, 0x81, 0x33, 0x25, 0xD3, 0x8D, 0x20, 0x17, 0x4E, 0x24, 0x80, 0x72, -0x04, 0xC2, 0xCB, 0xA8, 0x29, 0x02, 0xA9, 0xC4, 0x90, 0x0A, 0xA7, 0x12, 0x30, 0x39, 0x03, 0x61, -0x25, 0xC8, 0x18, 0x2E, 0x9C, 0x48, 0xC0, 0xAA, 0x71, 0x23, 0x0A, 0x52, 0x94, 0xD1, 0x34, 0xE2, -0x46, 0x05, 0x53, 0x89, 0x18, 0xF6, 0x11, 0x9E, 0x30, 0x49, 0xB5, 0x7F, 0x0C, 0x82, 0xA5, 0xFC, -0x87, 0x4C, 0x85, 0x53, 0x89, 0x18, 0xF4, 0x96, 0x5B, 0x7A, 0x1D, 0x04, 0xFD, 0x43, 0xB7, 0x66, -0xA6, 0x32, 0x5A, 0x58, 0x95, 0x54, 0x91, 0xBC, 0xB5, 0x47, 0x0F, 0xB1, 0x1C, 0xB8, 0x5C, 0x68, -0x97, 0x66, 0xAE, 0x50, 0xC6, 0xE0, 0xAA, 0x71, 0x23, 0x1A, 0xC3, 0x16, 0x6D, 0x9E, 0x87, 0xEC, -0xF5, 0x0E, 0x7C, 0xAD, 0xDC, 0xA5, 0x9E, 0x57, 0x2C, 0xF2, 0x3A, 0x34, 0xB7, 0xA3, 0x75, 0x2F, -0x1F, 0x06, 0x1A, 0x4E, 0xCD, 0x4A, 0xDF, 0x11, 0x7E, 0x3E, 0x27, 0x3E, 0xED, 0x2D, 0xCB, 0x12, -0xD5, 0x0E, 0x5C, 0xCE, 0x84, 0xF9, 0x0A, 0x85, 0x20, 0x36, 0x4D, 0xE8, 0xF4, 0x7F, 0x67, 0xAC, -0x76, 0xAD, 0xC4, 0x23, 0xA7, 0x52, 0xE4, 0x73, 0xA8, 0xEB, 0x96, 0xD1, 0x9F, 0x77, 0x71, 0xD8, -0xB5, 0x28, 0xCD, 0x66, 0x2D, 0x3C, 0x98, 0x2B, 0xC0, 0xB8, 0x91, 0x8C, 0xE3, 0x96, 0xBB, 0x3D, -0x0F, 0xD8, 0xEB, 0x10, 0xDD, 0xA9, 0x41, 0x85, 0xB7, 0x7A, 0x50, 0xC7, 0x32, 0x6E, 0x95, 0x20, -0x72, 0xB0, 0x81, 0x54, 0xE2, 0x48, 0x39, 0xE3, 0x96, 0xBB, 0x1D, 0x04, 0xFD, 0x62, 0xC6, 0xE2, -0x92, 0xF0, 0x37, 0x3E, 0x00, 0x7C, 0xA6, 0x86, 0xDD, 0x14, 0xBA, 0x71, 0x24, 0x19, 0x2E, 0xC8, -0xD3, 0x07, 0xE6, 0x12, 0xC5, 0xFB, 0xD4, 0xAD, 0xBB, 0x37, 0x25, 0x0C, 0xF3, 0x8F, 0x38, 0x4B, -0xB2, 0x50, 0x97, 0xAA, 0xC0, 0xEA, 0x37, 0x39, 0x21, 0x74, 0xE3, 0x48, 0x05, 0xD9, 0x1A, 0x51, -0x31, 0xD4, 0x51, 0xD4, 0xED, 0x53, 0x4F, 0xE5, 0x4B, 0xFB, 0x4A, 0x7E, 0x5D, 0xEE, 0xDC, 0xBD, -0x5F, 0xE1, 0x94, 0x44, 0x5C, 0x2A, 0xD5, 0xD7, 0xAA, 0x92, 0xAE, 0xD4, 0xA5, 0xCD, 0x27, 0x2F, -0x2A, 0xE2, 0xFD, 0x99, 0x68, 0xFE, 0x8C, 0x88, 0xA6, 0x30, 0x5D, 0x38, 0xD2, 0x01, 0x76, 0x46, -0x98, 0x4F, 0x9D, 0xAE, 0x2F, 0x61, 0x62, 0xED, 0xB7, 0x7E, 0x2B, 0xFB, 0x48, 0xEB, 0xDB, 0xEB, -0xFB, 0x5F, 0xD2, 0x23, 0x3B, 0xB6, 0xDF, 0xEF, 0x69, 0xAE, 0xDA, 0x7D, 0x5D, 0xB7, 0x95, 0xF0, -0x97, 0xF7, 0x81, 0xDA, 0xAA, 0xA8, 0xB3, 0xFB, 0xBB, 0xD7, 0x61, 0xF5, 0x66, 0xD2, 0xF8, 0x06, -0xFF, 0x00, 0x58, 0xAE, 0xEB, 0x7B, 0x57, 0xD6, 0x8C, 0x25, 0xFD, 0x68, 0x82, 0xEC, 0x8D, 0x28, -0xD6, 0x16, 0x46, 0x98, 0x27, 0x97, 0x47, 0x3E, 0x57, 0xDC, 0x3B, 0x2E, 0x5B, 0x9C, 0x7D, 0xF1, -0xD6, 0x67, 0xE0, 0x23, 0x3F, 0x62, 0xA2, 0x9E, 0x5D, 0xD3, 0xC3, 0xFE, 0x90, 0xEF, 0x8B, 0x54, -0x3E, 0x6A, 0xCB, 0xFF, 0x00, 0xF8, 0xC3, 0xFB, 0xA0, 0xE5, 0xC5, 0xAA, 0x7A, 0x79, 0x6B, 0xBA, -0xD4, 0x17, 0xFD, 0x41, 0x76, 0x46, 0x94, 0x67, 0x0D, 0x3D, 0x08, 0xD3, 0x0C, 0x7C, 0x26, 0xFF, -0x00, 0x4D, 0x2F, 0xBA, 0x49, 0x82, 0x97, 0x0A, 0xBE, 0xB3, 0x94, 0xBF, 0x88, 0xCB, 0x9C, 0x46, -0xAA, 0x5F, 0xE6, 0xCB, 0xD1, 0x88, 0xFF, 0x00, 0x54, 0x8B, 0x72, 0xF5, 0xC9, 0xE7, 0x54, 0xA5, -0x2E, 0xF7, 0x26, 0x30, 0xB2, 0x34, 0xC2, 0x60, 0xCF, 0xE8, 0x46, 0x97, 0xA8, 0x5B, 0xB4, 0xF1, -0xB5, 0x9D, 0x57, 0x21, 0xDD, 0x17, 0xA8, 0x8D, 0x3D, 0x3D, 0x06, 0x69, 0x9B, 0x1B, 0x60, 0xBA, -0x71, 0xA4, 0x10, 0xBA, 0x71, 0x24, 0xEA, 0x01, 0xD2, 0xE4, 0x1A, 0xDD, 0x9E, 0x41, 0xED, 0xD8, -0xEC, 0xF4, 0xB1, 0xE5, 0x15, 0x14, 0xC8, 0x55, 0x38, 0x91, 0x81, 0x54, 0xE2, 0x46, 0x03, 0x3F, -0x55, 0x78, 0x6C, 0x72, 0xEA, 0x27, 0xA9, 0xBF, 0x82, 0x25, 0xD5, 0x5E, 0xFC, 0xAB, 0xD2, 0x73, -0xA4, 0xF2, 0x0B, 0xA7, 0x12, 0x30, 0x2A, 0x9C, 0x48, 0x82, 0x48, 0x1B, 0xEA, 0x11, 0xF2, 0x06, -0xCD, 0x13, 0xE0, 0x5C, 0x49, 0x40, 0xA6, 0xEE, 0xE2, 0x46, 0x05, 0x20, 0x53, 0x0B, 0x2E, 0xA0, -0xA4, 0x60, 0xBB, 0x23, 0xE1, 0xB9, 0x81, 0x4D, 0xDD, 0xC4, 0x8C, 0x09, 0x82, 0x61, 0x64, 0x09, -0xF5, 0x05, 0x53, 0x89, 0x20, 0x14, 0xDD, 0xDC, 0x48, 0xC0, 0xE4, 0x0A, 0x41, 0x9F, 0x50, 0x32, -0x05, 0x53, 0x89, 0x18, 0xA5, 0x62, 0xFF, 0x00, 0x2E, 0x24, 0x60, 0x72, 0xFF, 0x00, 0xE8, 0x18, -0xF2, 0x11, 0x94, 0xAA, 0x71, 0x23, 0x02, 0xB0, 0x7F, 0x97, 0x12, 0x30, 0xA5, 0x29, 0x41, 0x54, -0xE2, 0x46, 0x34, 0x51, 0x7D, 0xDC, 0x49, 0x3A, 0x87, 0xA5, 0x52, 0xE4, 0x3A, 0x90, 0x0C, 0x9A, -0xA4, 0x6F, 0x77, 0x6C, 0x5F, 0x61, 0xF2, 0xE7, 0xDD, 0xF8, 0x7F, 0x87, 0x74, 0xFC, 0xD8, 0x6F, -0x03, 0x1D, 0xF6, 0x23, 0xF5, 0xFD, 0x9B, 0xAC, 0x49, 0x8C, 0x82, 0xC6, 0x44, 0x64, 0xC2, 0xC6, -0x45, 0x2F, 0xB1, 0xD3, 0x0D, 0x36, 0x9B, 0xBA, 0x4B, 0xF7, 0x37, 0xC4, 0x4C, 0x32, 0x77, 0xD8, -0x8D, 0x37, 0x58, 0x95, 0x19, 0x72, 0x0D, 0x1B, 0xCD, 0x6C, 0xF7, 0x5E, 0x0C, 0x8B, 0x19, 0x06, -0x8B, 0x2E, 0x05, 0xEC, 0xF6, 0x6D, 0xCA, 0x97, 0x87, 0xF4, 0xFB, 0x1B, 0x09, 0x83, 0xF9, 0x23, -0x4C, 0x36, 0x76, 0xAD, 0xDC, 0xDE, 0x3E, 0xAB, 0xF7, 0x0F, 0x66, 0xA6, 0xED, 0x33, 0xDF, 0x38, -0xF7, 0x15, 0x45, 0x33, 0x74, 0xBF, 0xF8, 0x2E, 0x0C, 0x5B, 0x60, 0x43, 0xBE, 0xBC, 0xF1, 0x29, -0xFD, 0x7B, 0xA7, 0xDC, 0x18, 0x3F, 0x92, 0x34, 0xC3, 0xAF, 0x4F, 0x5F, 0x6E, 0xEA, 0x59, 0xD9, -0xFB, 0x89, 0xF1, 0x6A, 0x4B, 0x66, 0x9F, 0x71, 0xE6, 0x3C, 0xB6, 0xB9, 0x65, 0x7A, 0x49, 0x16, -0x6A, 0x6E, 0xDA, 0xC6, 0xED, 0x98, 0x6C, 0x5B, 0x0E, 0xCF, 0x4F, 0x07, 0xEC, 0xB4, 0xF6, 0x6B, -0xBA, 0x30, 0xC9, 0x76, 0x46, 0x98, 0x7A, 0x07, 0x14, 0xC4, 0x76, 0x7B, 0x88, 0x76, 0x78, 0x8A, -0x96, 0x35, 0x13, 0x21, 0x51, 0x6E, 0x7F, 0x9B, 0x1D, 0xE5, 0xC7, 0x16, 0xD9, 0x2B, 0x26, 0xFF, -0x00, 0xA9, 0x9F, 0xDA, 0xEF, 0xBA, 0xFE, 0x4C, 0x05, 0xD9, 0x1A, 0x50, 0x37, 0x64, 0x47, 0x06, -0x89, 0x99, 0x4F, 0xC1, 0xFA, 0x72, 0x63, 0x82, 0x63, 0x0C, 0x59, 0x98, 0xBD, 0x7C, 0xCF, 0xD9, -0x3F, 0xFF, 0x00, 0x99, 0x9F, 0x83, 0x01, 0x76, 0x46, 0x94, 0x43, 0x62, 0xB2, 0x5B, 0xB6, 0x85, -0x76, 0x4A, 0x53, 0x60, 0xCC, 0x5E, 0x4E, 0xDC, 0xF2, 0xEC, 0xDF, 0xE3, 0xF6, 0x76, 0xFC, 0x98, -0x0B, 0xB2, 0x34, 0xA2, 0x23, 0x5C, 0xC5, 0x7B, 0x12, 0x9D, 0x89, 0x78, 0x19, 0xF8, 0x69, 0xBE, -0x84, 0xC7, 0x63, 0xD0, 0xD9, 0x6F, 0xD3, 0x4D, 0xF9, 0x68, 0x05, 0xD9, 0x1A, 0x61, 0x11, 0x88, -0xE3, 0xCC, 0x9D, 0xF8, 0x49, 0xF8, 0x7B, 0xCD, 0x54, 0x32, 0x7C, 0xDF, 0xBC, 0xC1, 0x76, 0x46, -0x98, 0x4C, 0x2C, 0x8D, 0x30, 0xE6, 0xB8, 0x97, 0xCB, 0x6C, 0xEB, 0x46, 0x82, 0x3D, 0x58, 0xFE, -0x45, 0x9B, 0x7C, 0xF1, 0xDE, 0xD9, 0x70, 0xB2, 0x34, 0xC1, 0x83, 0xF9, 0x23, 0x4C, 0x39, 0x50, -0xA6, 0x94, 0xB9, 0x44, 0x93, 0x1A, 0x55, 0x1F, 0x68, 0x91, 0x72, 0xA6, 0xD4, 0x32, 0x96, 0x3D, -0x04, 0x1B, 0xD5, 0x9E, 0x1B, 0x02, 0x70, 0x7C, 0xF6, 0x34, 0xFF, 0x00, 0xAD, 0x2B, 0xFE, 0x42, -0x17, 0x64, 0x69, 0x83, 0xDC, 0x9C, 0x61, 0xE1, 0xDC, 0x8E, 0x75, 0x45, 0x4E, 0x32, 0x97, 0x3E, -0xCE, 0x80, 0xEF, 0x54, 0xB7, 0xCB, 0x6E, 0xD2, 0x24, 0xA5, 0x93, 0x78, 0x39, 0x38, 0x6C, 0x33, -0x62, 0xF9, 0x3F, 0xCB, 0xF4, 0x9D, 0xF4, 0xD7, 0xFE, 0x2B, 0x6B, 0xEB, 0xC5, 0xFE, 0xA1, 0x70, -0xB2, 0x34, 0xC1, 0x27, 0x2D, 0x4D, 0x83, 0x63, 0x36, 0x0D, 0x8C, 0x7B, 0x2C, 0xBB, 0x37, 0x6D, -0x71, 0x7F, 0x97, 0xE8, 0xEB, 0xAB, 0x7F, 0x0B, 0xC1, 0x99, 0x9B, 0xEB, 0x10, 0xBB, 0x23, 0x4B, -0xD4, 0x16, 0x40, 0xD8, 0xEF, 0x98, 0x39, 0x10, 0x8C, 0x76, 0x9B, 0x06, 0xF0, 0xD3, 0xB3, 0xF7, -0x7D, 0x1F, 0x65, 0x70, 0x2E, 0x9C, 0x49, 0x3A, 0x80, 0xE4, 0x0A, 0x41, 0x18, 0x29, 0x02, 0xDC, -0xAC, 0x5F, 0x0C, 0x5B, 0x1D, 0x5B, 0xE5, 0xFB, 0xFF, 0x00, 0xDA, 0xE9, 0xEA, 0x76, 0xF8, 0x0A, -0x53, 0xE9, 0xD9, 0xC4, 0x8F, 0xA8, 0x0E, 0x40, 0x9F, 0x50, 0x92, 0xEA, 0x0D, 0x8C, 0x71, 0xC7, -0x26, 0xC1, 0xF0, 0xD6, 0x9F, 0xA1, 0xFE, 0x5F, 0xF8, 0xBC, 0x19, 0x80, 0xAC, 0xFB, 0xBE, 0x5F, -0xA4, 0x8C, 0x0E, 0x40, 0xD8, 0x49, 0x73, 0x04, 0xCC, 0x11, 0x83, 0xE7, 0xB1, 0xA6, 0x8D, 0xA7, -0x67, 0xEA, 0x6D, 0xD1, 0xC5, 0x2B, 0x3E, 0xEF, 0x97, 0xE9, 0x23, 0x03, 0x90, 0x36, 0x3C, 0xBA, -0x88, 0xFA, 0x9B, 0xC1, 0xCA, 0x6D, 0x86, 0x6C, 0x76, 0x99, 0xBB, 0x36, 0x67, 0x77, 0xD3, 0xF9, -0x4D, 0x1D, 0x9B, 0xEB, 0x67, 0xF6, 0xB7, 0xF5, 0x02, 0xF3, 0xEE, 0xF9, 0x7E, 0x92, 0x4E, 0xB1, -0x85, 0x29, 0x4A, 0x5E, 0x38, 0x67, 0xD9, 0xE5, 0x83, 0x3B, 0x77, 0x7C, 0xB5, 0xE7, 0xA3, 0xFD, -0x95, 0xFD, 0x58, 0xB7, 0x31, 0x4A, 0x33, 0xBB, 0xE5, 0xFA, 0x49, 0x3A, 0xC7, 0x6F, 0x50, 0xEA, -0x40, 0x46, 0x4C, 0x9B, 0xAF, 0x86, 0x11, 0xFE, 0x1D, 0xD4, 0x42, 0xEC, 0x8D, 0x30, 0x91, 0x17, -0xC8, 0x34, 0x5E, 0x08, 0xD1, 0x0D, 0x17, 0x93, 0x99, 0x76, 0x7B, 0x4A, 0x48, 0x05, 0xD9, 0x1A, -0x61, 0x26, 0x2C, 0x3C, 0x5E, 0x48, 0xB0, 0x0F, 0x13, 0xA9, 0x5D, 0xD9, 0x51, 0x7E, 0x2D, 0xD0, -0x52, 0xEC, 0x8D, 0x30, 0x91, 0x16, 0x1A, 0x2C, 0x8D, 0x16, 0x19, 0x33, 0x58, 0xEC, 0x76, 0x64, -0x6A, 0xD6, 0x17, 0xF8, 0xB7, 0x5F, 0xCF, 0x40, 0x2E, 0xC8, 0xD3, 0x03, 0xAC, 0x0D, 0xA1, 0x30, -0x71, 0x61, 0x53, 0xEF, 0x32, 0xFC, 0xD8, 0xA7, 0x6F, 0x07, 0xEC, 0xF4, 0x6F, 0xA3, 0x5C, 0xB7, -0x5D, 0x18, 0x42, 0xEC, 0x8D, 0x30, 0xDF, 0x24, 0x68, 0xC6, 0x51, 0xE4, 0xDF, 0xC4, 0x68, 0xB0, -0x89, 0x8D, 0xDB, 0xC7, 0x0C, 0x5F, 0xC3, 0x4C, 0x39, 0x7B, 0x1B, 0x75, 0xD1, 0xFE, 0xA7, 0x02, -0xEC, 0x8D, 0x28, 0xB1, 0xB9, 0x38, 0xF5, 0x7F, 0x10, 0xD1, 0xAA, 0x9C, 0x7A, 0xE4, 0x06, 0x4D, -0xD8, 0xCE, 0xD3, 0xE4, 0xF8, 0xFF, 0x00, 0x88, 0xB4, 0xA0, 0x5D, 0x91, 0xA5, 0x12, 0x95, 0x63, -0xEB, 0x86, 0x3A, 0xAC, 0x5D, 0x57, 0xBC, 0x82, 0x53, 0xA1, 0x7B, 0x2C, 0x59, 0x5A, 0xB7, 0xB8, -0xAE, 0x24, 0x7F, 0x6F, 0xA8, 0x0B, 0xB2, 0x34, 0xA3, 0xA1, 0xF8, 0xD8, 0x78, 0x3F, 0x89, 0xBF, -0x8E, 0xB6, 0xBA, 0x48, 0xE6, 0xB6, 0x2B, 0x93, 0x31, 0x8E, 0xC3, 0xEC, 0x6C, 0xB7, 0xF9, 0x13, -0x7E, 0x5A, 0x09, 0x85, 0x91, 0xA6, 0x1D, 0x47, 0xC4, 0x60, 0xBF, 0x2B, 0xF4, 0xB0, 0x72, 0xE2, -0x7E, 0x11, 0x5D, 0xFC, 0xCE, 0x6B, 0x97, 0x31, 0x25, 0x23, 0x38, 0xB7, 0x92, 0x34, 0xC0, 0x5D, -0x91, 0xA5, 0x13, 0xA7, 0xC4, 0x6E, 0x3E, 0xB8, 0xEE, 0x22, 0xDC, 0xAA, 0x94, 0xB3, 0x99, 0x37, -0xE9, 0x00, 0xE4, 0x0D, 0xBD, 0x8A, 0x5D, 0x9E, 0xCC, 0x13, 0x88, 0x5D, 0x91, 0xA5, 0x0D, 0x3B, -0xCC, 0x0C, 0xE6, 0xDF, 0x36, 0x6B, 0x60, 0xA4, 0xCD, 0x6E, 0xDE, 0x18, 0xFB, 0x4A, 0xE1, 0xBB, -0x81, 0x76, 0x46, 0x94, 0x2C, 0xBA, 0x83, 0x93, 0xE6, 0x33, 0x60, 0xDB, 0xC9, 0xC8, 0xAA, 0x7F, -0x47, 0xCA, 0xE7, 0xFF, 0x00, 0xD4, 0x02, 0xEC, 0x8D, 0x28, 0x56, 0x26, 0x79, 0x8E, 0xFA, 0x82, -0x6F, 0x99, 0xD4, 0x92, 0x8B, 0xC9, 0xB0, 0xD9, 0x31, 0xE9, 0xDB, 0xFD, 0x37, 0x6F, 0xC9, 0x9B, -0xE3, 0xFD, 0x00, 0xBB, 0x23, 0x4A, 0x15, 0x89, 0x2F, 0x40, 0xCC, 0x1C, 0x8D, 0x10, 0xDA, 0x62, -0xDE, 0xD2, 0xBF, 0x0E, 0xEC, 0x05, 0xD9, 0x1A, 0x50, 0x8F, 0xA8, 0x29, 0x75, 0xFF, 0x00, 0x71, -0xE4, 0xC1, 0xC8, 0xF3, 0x93, 0xE2, 0x5C, 0x48, 0xC4, 0x2E, 0x9C, 0x69, 0x00, 0xD8, 0x8C, 0x66, -0x23, 0x3A, 0x6E, 0x9D, 0xE1, 0x7A, 0x78, 0x6C, 0x63, 0xAF, 0xB7, 0x67, 0x76, 0xD3, 0xD4, 0x05, -0xD3, 0x8D, 0x20, 0x13, 0x11, 0x8C, 0xC4, 0x7D, 0x4B, 0xBB, 0x69, 0xB2, 0xDA, 0x7D, 0x24, 0xFC, -0x34, 0xDD, 0x75, 0x02, 0xE9, 0xC4, 0x8C, 0x0D, 0x88, 0xC6, 0x62, 0x1C, 0x8A, 0xA5, 0x12, 0x30, -0x2A, 0x9C, 0x48, 0xC5, 0x29, 0x4A, 0x75, 0xDD, 0x3C, 0xD8, 0x7F, 0x87, 0x1F, 0xC1, 0xBA, 0x81, -0x54, 0xE2, 0x46, 0x3F, 0xFF, 0xD9 +0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x01, 0x00, 0x48, +0x00, 0x48, 0x00, 0x00, 0xFF, 0xE1, 0x07, 0x0C, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4D, 0x4D, +0x00, 0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, +0x00, 0x01, 0x00, 0x00, 0x01, 0x1A, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, +0x01, 0x1B, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x6A, 0x01, 0x28, 0x00, 0x03, +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x31, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1C, +0x00, 0x00, 0x00, 0x72, 0x01, 0x32, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x8E, +0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0xD0, +0x00, 0x0A, 0xFC, 0x80, 0x00, 0x00, 0x27, 0x10, 0x00, 0x0A, 0xFC, 0x80, 0x00, 0x00, 0x27, 0x10, +0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x20, +0x43, 0x53, 0x34, 0x20, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x00, 0x32, 0x30, 0x32, 0x31, +0x3A, 0x31, 0x31, 0x3A, 0x30, 0x34, 0x20, 0x31, 0x30, 0x3A, 0x31, 0x37, 0x3A, 0x31, 0x32, 0x00, +0x00, 0x00, 0x00, 0x03, 0xA0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, +0xA0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x40, 0xA0, 0x03, 0x00, 0x04, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, +0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01, 0x1A, 0x00, 0x05, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x1E, 0x01, 0x1B, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x01, 0x26, 0x01, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, +0x02, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2E, 0x02, 0x02, 0x00, 0x04, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x05, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xD8, 0xFF, 0xE0, +0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, +0xFF, 0xED, 0x00, 0x0C, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x5F, 0x43, 0x4D, 0x00, 0x01, 0xFF, 0xEE, +0x00, 0x0E, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x00, 0x64, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xDB, +0x00, 0x84, 0x00, 0x0C, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0C, 0x09, 0x09, 0x0C, 0x11, 0x0B, 0x0A, +0x0B, 0x11, 0x15, 0x0F, 0x0C, 0x0C, 0x0F, 0x15, 0x18, 0x13, 0x13, 0x15, 0x13, 0x13, 0x18, 0x11, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x01, 0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E, 0x0E, 0x10, 0x14, 0x0E, +0x0E, 0x0E, 0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, +0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x78, 0x00, 0xA0, 0x03, 0x01, 0x22, +0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0A, 0xFF, 0xC4, 0x01, +0x3F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x03, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x00, +0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x01, 0x04, 0x01, +0x03, 0x02, 0x04, 0x02, 0x05, 0x07, 0x06, 0x08, 0x05, 0x03, 0x0C, 0x33, 0x01, 0x00, 0x02, 0x11, +0x03, 0x04, 0x21, 0x12, 0x31, 0x05, 0x41, 0x51, 0x61, 0x13, 0x22, 0x71, 0x81, 0x32, 0x06, 0x14, +0x91, 0xA1, 0xB1, 0x42, 0x23, 0x24, 0x15, 0x52, 0xC1, 0x62, 0x33, 0x34, 0x72, 0x82, 0xD1, 0x43, +0x07, 0x25, 0x92, 0x53, 0xF0, 0xE1, 0xF1, 0x63, 0x73, 0x35, 0x16, 0xA2, 0xB2, 0x83, 0x26, 0x44, +0x93, 0x54, 0x64, 0x45, 0xC2, 0xA3, 0x74, 0x36, 0x17, 0xD2, 0x55, 0xE2, 0x65, 0xF2, 0xB3, 0x84, +0xC3, 0xD3, 0x75, 0xE3, 0xF3, 0x46, 0x27, 0x94, 0xA4, 0x85, 0xB4, 0x95, 0xC4, 0xD4, 0xE4, 0xF4, +0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, +0xF6, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, 0x11, 0x00, +0x02, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x06, 0x05, 0x35, 0x01, +0x00, 0x02, 0x11, 0x03, 0x21, 0x31, 0x12, 0x04, 0x41, 0x51, 0x61, 0x71, 0x22, 0x13, 0x05, 0x32, +0x81, 0x91, 0x14, 0xA1, 0xB1, 0x42, 0x23, 0xC1, 0x52, 0xD1, 0xF0, 0x33, 0x24, 0x62, 0xE1, 0x72, +0x82, 0x92, 0x43, 0x53, 0x15, 0x63, 0x73, 0x34, 0xF1, 0x25, 0x06, 0x16, 0xA2, 0xB2, 0x83, 0x07, +0x26, 0x35, 0xC2, 0xD2, 0x44, 0x93, 0x54, 0xA3, 0x17, 0x64, 0x45, 0x55, 0x36, 0x74, 0x65, 0xE2, +0xF2, 0xB3, 0x84, 0xC3, 0xD3, 0x75, 0xE3, 0xF3, 0x46, 0x94, 0xA4, 0x85, 0xB4, 0x95, 0xC4, 0xD4, +0xE4, 0xF4, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, +0xD6, 0xE6, 0xF6, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xFF, 0xDA, +0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, 0xF3, 0x44, 0x92, 0x5D, +0x3F, 0x4A, 0xE9, 0x9D, 0x12, 0xEC, 0x4E, 0x95, 0xEB, 0xB7, 0x14, 0x65, 0x67, 0x32, 0xFD, 0xE7, +0x26, 0xCB, 0xC0, 0x73, 0xEB, 0xBC, 0xD7, 0x5B, 0x1B, 0xF6, 0x5C, 0x8A, 0x19, 0x8F, 0x6B, 0xB1, +0xFD, 0x95, 0xFA, 0xDF, 0xA2, 0xB7, 0xFE, 0x31, 0x33, 0x2E, 0x51, 0x8C, 0x02, 0x41, 0x36, 0x6B, +0xD3, 0xAF, 0xE8, 0xCA, 0x7F, 0xF7, 0x28, 0x26, 0x9E, 0x61, 0x25, 0xD7, 0x55, 0xD1, 0xFA, 0x1D, +0x9B, 0x1F, 0x46, 0x18, 0x73, 0x6C, 0x39, 0x04, 0xD5, 0x79, 0xBD, 0xF6, 0x56, 0xD6, 0x64, 0x59, +0x4D, 0x0C, 0xB6, 0xBC, 0x5C, 0x9A, 0x7D, 0x1B, 0x1B, 0x4B, 0x76, 0x7B, 0xFE, 0x9A, 0xA1, 0x4F, +0x4A, 0xE9, 0x7D, 0x41, 0x8F, 0xA9, 0x86, 0xBE, 0x9B, 0x95, 0x83, 0x98, 0x59, 0x9D, 0xBA, 0xC2, +0x5B, 0xF6, 0x4B, 0x1F, 0xB3, 0xED, 0x2C, 0x6E, 0x45, 0x96, 0x3B, 0x7E, 0x0B, 0xBF, 0x42, 0xF6, +0xFF, 0x00, 0xC2, 0x56, 0xFB, 0x94, 0x63, 0x9A, 0x81, 0xBD, 0x24, 0x28, 0xD1, 0xB1, 0xB7, 0xE8, +0xF7, 0x47, 0x10, 0x70, 0x12, 0x5D, 0x46, 0x26, 0x0F, 0x41, 0xCE, 0x61, 0xCA, 0xC4, 0xC3, 0x61, +0xAE, 0xCC, 0x9C, 0x86, 0x55, 0x4B, 0xDF, 0x7B, 0xDC, 0xDA, 0x6B, 0x6E, 0x2F, 0xA0, 0xE7, 0xB2, +0x9C, 0x8A, 0xAD, 0xF5, 0x1C, 0xEB, 0x2D, 0x7B, 0x9F, 0xBB, 0x67, 0xE9, 0x3D, 0x3F, 0xF4, 0x68, +0x74, 0x74, 0x7E, 0x96, 0xDC, 0x9C, 0xEC, 0x8C, 0xF6, 0x55, 0x4E, 0x33, 0x6D, 0x18, 0xB8, 0x78, +0xA6, 0xE7, 0x52, 0x3D, 0x42, 0xD6, 0x5B, 0x7E, 0x4E, 0xFB, 0xEE, 0x7D, 0xEC, 0x66, 0x3E, 0x37, +0xE9, 0x9A, 0xCB, 0xAC, 0x7F, 0xA9, 0x93, 0x75, 0x54, 0x7F, 0xC1, 0xA5, 0xF7, 0xA8, 0x6B, 0x71, +0x90, 0x23, 0xA1, 0x02, 0xF7, 0xE1, 0xE1, 0xF9, 0x95, 0xC4, 0x1E, 0x6D, 0x25, 0xBF, 0x97, 0xF5, +0x7A, 0x8A, 0xA8, 0xCD, 0xA3, 0x10, 0x8C, 0xCC, 0xA6, 0x65, 0x53, 0xF6, 0x1B, 0x19, 0x60, 0x25, +0xF8, 0x96, 0x57, 0x75, 0xDE, 0xA0, 0x60, 0x73, 0x6B, 0x7F, 0xF3, 0x6C, 0xF5, 0x1F, 0xB7, 0xD9, +0x62, 0xC5, 0xCA, 0xC4, 0xC9, 0xC4, 0xB7, 0xD1, 0xCA, 0xAC, 0xD5, 0x6C, 0x07, 0x6C, 0x74, 0x4C, +0x1F, 0xA2, 0xEF, 0x6C, 0xA9, 0x21, 0x96, 0x13, 0xF9, 0x4F, 0xD0, 0xEF, 0x5F, 0x35, 0xD2, 0x41, +0x05, 0x12, 0x49, 0x24, 0xA4, 0x4A, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, +0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xFF, 0x00, 0xFF, 0xD0, 0xF3, +0x45, 0x7B, 0x17, 0xAD, 0xF5, 0x2C, 0x4C, 0x71, 0x8D, 0x8F, 0x65, 0x6D, 0xA4, 0x4C, 0x35, 0xD4, +0x53, 0x61, 0xD4, 0xEE, 0x32, 0xFB, 0xA9, 0xB2, 0xC7, 0x7F, 0x9C, 0xA8, 0xA4, 0x84, 0xA3, 0x19, +0x0A, 0x90, 0x12, 0x1F, 0xD6, 0x16, 0xAA, 0x7A, 0xBF, 0xAB, 0x9F, 0x59, 0xF0, 0x77, 0xDF, 0x57, +0xD6, 0x06, 0xE3, 0xB9, 0x85, 0xA1, 0xD8, 0xF9, 0x07, 0x16, 0xB3, 0x0E, 0x1E, 0xD7, 0xD2, 0xE6, +0xE3, 0x51, 0xBB, 0x6D, 0x8D, 0x3B, 0xD8, 0xED, 0x9F, 0xE0, 0xD5, 0xCB, 0xBA, 0xD7, 0x44, 0x75, +0xCE, 0x75, 0x1D, 0x57, 0x15, 0xB8, 0xFB, 0xCB, 0x99, 0x53, 0xF0, 0x1C, 0x5C, 0xD6, 0x92, 0xD7, +0x35, 0x8C, 0xB4, 0x61, 0x7B, 0x3D, 0x26, 0xB7, 0x67, 0xD0, 0xB3, 0xD4, 0xDE, 0xB8, 0x84, 0x95, +0x79, 0x72, 0x78, 0xCC, 0x8C, 0x81, 0x31, 0xBF, 0xD1, 0x8F, 0x07, 0x07, 0xD2, 0x32, 0x84, 0x96, +0xF0, 0x0B, 0xB7, 0xB5, 0x77, 0x59, 0xE9, 0x07, 0x4F, 0xDA, 0xF8, 0x6F, 0xE6, 0x1D, 0x67, 0x4F, +0x71, 0x77, 0x04, 0x35, 0xCF, 0x8C, 0x3D, 0xAF, 0xDB, 0xBB, 0x77, 0xA5, 0xFA, 0x3F, 0xF8, 0xDF, +0xF4, 0x87, 0xE9, 0xDD, 0x7B, 0xEA, 0xF5, 0x16, 0x58, 0xEC, 0xFE, 0xA3, 0x89, 0x92, 0xD7, 0x06, +0xB6, 0xA6, 0xD7, 0xD3, 0xDD, 0x5E, 0xC8, 0x27, 0x7B, 0x8C, 0x62, 0xEE, 0x7E, 0xFF, 0x00, 0xFA, +0x0B, 0x83, 0x49, 0x03, 0xC8, 0xE3, 0x22, 0xB8, 0xA5, 0xAF, 0x61, 0x8C, 0x7F, 0xEA, 0x35, 0x70, +0x0E, 0xEE, 0xDF, 0x53, 0xFA, 0xD1, 0x95, 0x76, 0x7D, 0xEE, 0xC0, 0x6D, 0x34, 0x61, 0x6F, 0x23, +0x1E, 0xAF, 0xB3, 0x50, 0x7D, 0x83, 0x40, 0xF7, 0x7A, 0x94, 0x39, 0xFB, 0xED, 0xDB, 0xEA, 0xBD, +0x64, 0xE5, 0x65, 0xDF, 0x99, 0x77, 0xAF, 0x79, 0x69, 0xB0, 0x80, 0xD9, 0x63, 0x19, 0x58, 0x81, +0xC7, 0xB2, 0x86, 0x55, 0x5F, 0xFD, 0x14, 0x24, 0x94, 0xF0, 0xC5, 0x08, 0x01, 0xC3, 0x10, 0x28, +0x55, 0xD7, 0xAB, 0xFC, 0x64, 0x80, 0x02, 0x92, 0x49, 0x25, 0x22, 0x54, 0x92, 0x49, 0x24, 0xA5, +0x24, 0x92, 0x49, 0x29, 0x49, 0x24, 0x92, 0x4A, 0x52, 0x49, 0x24, 0x92, 0x94, 0x92, 0x49, 0x24, +0xA7, 0xFF, 0xD1, 0xF3, 0x44, 0x92, 0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, +0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, +0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, +0xD2, 0xF3, 0x44, 0x92, 0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, +0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, +0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD3, 0xF3, +0x44, 0x92, 0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, +0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, +0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD4, 0xF3, 0x44, 0x92, +0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, +0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, +0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD5, 0xF3, 0x44, 0x92, 0x49, 0x15, +0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, +0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, +0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD6, 0xF3, 0x44, 0x95, 0x54, 0x91, 0x53, 0x69, +0x25, 0x55, 0x24, 0x94, 0xDA, 0x49, 0x55, 0x49, 0x25, 0x36, 0x92, 0x55, 0x52, 0x49, 0x4D, 0xA4, +0x95, 0x54, 0x92, 0x53, 0x69, 0x25, 0x55, 0x24, 0x94, 0xDA, 0x49, 0x55, 0x49, 0x25, 0x36, 0x92, +0x55, 0x52, 0x49, 0x4D, 0xA4, 0x95, 0x54, 0x92, 0x53, 0x69, 0x25, 0x55, 0x24, 0x94, 0xFF, 0x00, +0xFF, 0xD9, 0xFF, 0xED, 0x0B, 0xB2, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x20, +0x33, 0x2E, 0x30, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, +0x1C, 0x02, 0x00, 0x00, 0x02, 0xB8, 0xCB, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x25, 0x00, 0x00, +0x00, 0x00, 0x00, 0x10, 0x79, 0x78, 0xE6, 0xAC, 0xD2, 0x94, 0x0B, 0x77, 0xE3, 0x9D, 0xDD, 0x2B, +0x62, 0xE4, 0x9B, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x03, 0xED, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, +0x38, 0x42, 0x49, 0x4D, 0x04, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x0D, +0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1E, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x19, +0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1E, 0x38, 0x42, 0x49, 0x4D, 0x03, 0xF3, +0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, +0x38, 0x42, 0x49, 0x4D, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x42, 0x49, 0x4D, 0x03, 0xF5, 0x00, 0x00, 0x00, 0x00, +0x00, 0x48, 0x00, 0x2F, 0x66, 0x66, 0x00, 0x01, 0x00, 0x6C, 0x66, 0x66, 0x00, 0x06, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x2F, 0x66, 0x66, 0x00, 0x01, 0x00, 0xA1, 0x99, 0x9A, 0x00, 0x06, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5A, 0x00, 0x00, +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x35, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2D, +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x42, 0x49, 0x4D, 0x03, 0xF8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xE8, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x03, 0xE8, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, +0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, +0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4B, 0x00, 0x00, +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, +0x01, 0x40, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x34, 0x00, 0x5F, 0x00, 0x77, 0x00, 0x6F, 0x00, 0x72, +0x00, 0x6B, 0x00, 0x5F, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, +0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x6E, 0x75, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x62, +0x6F, 0x75, 0x6E, 0x64, 0x73, 0x4F, 0x62, 0x6A, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x52, 0x63, 0x74, 0x31, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x54, +0x6F, 0x70, 0x20, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, +0x65, 0x66, 0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, +0x74, 0x6F, 0x6D, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x52, +0x67, 0x68, 0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x06, 0x73, +0x6C, 0x69, 0x63, 0x65, 0x73, 0x56, 0x6C, 0x4C, 0x73, 0x00, 0x00, 0x00, 0x01, 0x4F, 0x62, 0x6A, +0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x73, 0x6C, 0x69, 0x63, 0x65, +0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x73, 0x6C, 0x69, 0x63, 0x65, 0x49, 0x44, 0x6C, +0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x67, 0x72, 0x6F, 0x75, 0x70, +0x49, 0x44, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x6F, 0x72, +0x69, 0x67, 0x69, 0x6E, 0x65, 0x6E, 0x75, 0x6D, 0x00, 0x00, 0x00, 0x0C, 0x45, 0x53, 0x6C, 0x69, +0x63, 0x65, 0x4F, 0x72, 0x69, 0x67, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x0D, 0x61, 0x75, 0x74, 0x6F, +0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x54, 0x79, 0x70, +0x65, 0x65, 0x6E, 0x75, 0x6D, 0x00, 0x00, 0x00, 0x0A, 0x45, 0x53, 0x6C, 0x69, 0x63, 0x65, 0x54, +0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6D, 0x67, 0x20, 0x00, 0x00, 0x00, 0x06, 0x62, +0x6F, 0x75, 0x6E, 0x64, 0x73, 0x4F, 0x62, 0x6A, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x52, 0x63, 0x74, 0x31, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x54, +0x6F, 0x70, 0x20, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, +0x65, 0x66, 0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, +0x74, 0x6F, 0x6D, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x52, +0x67, 0x68, 0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x03, 0x75, +0x72, 0x6C, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x6E, 0x75, 0x6C, 0x6C, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x4D, 0x73, 0x67, 0x65, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x06, 0x61, 0x6C, 0x74, 0x54, 0x61, 0x67, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x63, 0x65, 0x6C, 0x6C, 0x54, 0x65, 0x78, 0x74, +0x49, 0x73, 0x48, 0x54, 0x4D, 0x4C, 0x62, 0x6F, 0x6F, 0x6C, 0x01, 0x00, 0x00, 0x00, 0x08, 0x63, +0x65, 0x6C, 0x6C, 0x54, 0x65, 0x78, 0x74, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, +0x00, 0x00, 0x00, 0x00, 0x09, 0x68, 0x6F, 0x72, 0x7A, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x65, 0x6E, +0x75, 0x6D, 0x00, 0x00, 0x00, 0x0F, 0x45, 0x53, 0x6C, 0x69, 0x63, 0x65, 0x48, 0x6F, 0x72, 0x7A, +0x41, 0x6C, 0x69, 0x67, 0x6E, 0x00, 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, +0x00, 0x00, 0x00, 0x09, 0x76, 0x65, 0x72, 0x74, 0x41, 0x6C, 0x69, 0x67, 0x6E, 0x65, 0x6E, 0x75, +0x6D, 0x00, 0x00, 0x00, 0x0F, 0x45, 0x53, 0x6C, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x74, 0x41, +0x6C, 0x69, 0x67, 0x6E, 0x00, 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, +0x00, 0x00, 0x0B, 0x62, 0x67, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x54, 0x79, 0x70, 0x65, 0x65, 0x6E, +0x75, 0x6D, 0x00, 0x00, 0x00, 0x11, 0x45, 0x53, 0x6C, 0x69, 0x63, 0x65, 0x42, 0x47, 0x43, 0x6F, +0x6C, 0x6F, 0x72, 0x54, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x6E, 0x65, 0x00, +0x00, 0x00, 0x09, 0x74, 0x6F, 0x70, 0x4F, 0x75, 0x74, 0x73, 0x65, 0x74, 0x6C, 0x6F, 0x6E, 0x67, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x6C, 0x65, 0x66, 0x74, 0x4F, 0x75, 0x74, 0x73, +0x65, 0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x62, 0x6F, +0x74, 0x74, 0x6F, 0x6D, 0x4F, 0x75, 0x74, 0x73, 0x65, 0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x72, 0x69, 0x67, 0x68, 0x74, 0x4F, 0x75, 0x74, 0x73, 0x65, +0x74, 0x6C, 0x6F, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x28, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, +0x00, 0x03, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x05, 0xF2, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, +0xE1, 0x00, 0x00, 0x00, 0x05, 0xD6, 0x00, 0x18, 0x00, 0x01, 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, +0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xED, +0x00, 0x0C, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x5F, 0x43, 0x4D, 0x00, 0x01, 0xFF, 0xEE, 0x00, 0x0E, +0x41, 0x64, 0x6F, 0x62, 0x65, 0x00, 0x64, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xDB, 0x00, 0x84, +0x00, 0x0C, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0C, 0x09, 0x09, 0x0C, 0x11, 0x0B, 0x0A, 0x0B, 0x11, +0x15, 0x0F, 0x0C, 0x0C, 0x0F, 0x15, 0x18, 0x13, 0x13, 0x15, 0x13, 0x13, 0x18, 0x11, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x01, 0x0D, 0x0B, 0x0B, 0x0D, 0x0E, 0x0D, 0x10, 0x0E, 0x0E, 0x10, 0x14, 0x0E, 0x0E, 0x0E, +0x14, 0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0x78, 0x00, 0xA0, 0x03, 0x01, 0x22, 0x00, 0x02, +0x11, 0x01, 0x03, 0x11, 0x01, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0A, 0xFF, 0xC4, 0x01, 0x3F, 0x00, +0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x00, 0x01, 0x05, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, +0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x01, 0x04, 0x01, 0x03, 0x02, +0x04, 0x02, 0x05, 0x07, 0x06, 0x08, 0x05, 0x03, 0x0C, 0x33, 0x01, 0x00, 0x02, 0x11, 0x03, 0x04, +0x21, 0x12, 0x31, 0x05, 0x41, 0x51, 0x61, 0x13, 0x22, 0x71, 0x81, 0x32, 0x06, 0x14, 0x91, 0xA1, +0xB1, 0x42, 0x23, 0x24, 0x15, 0x52, 0xC1, 0x62, 0x33, 0x34, 0x72, 0x82, 0xD1, 0x43, 0x07, 0x25, +0x92, 0x53, 0xF0, 0xE1, 0xF1, 0x63, 0x73, 0x35, 0x16, 0xA2, 0xB2, 0x83, 0x26, 0x44, 0x93, 0x54, +0x64, 0x45, 0xC2, 0xA3, 0x74, 0x36, 0x17, 0xD2, 0x55, 0xE2, 0x65, 0xF2, 0xB3, 0x84, 0xC3, 0xD3, +0x75, 0xE3, 0xF3, 0x46, 0x27, 0x94, 0xA4, 0x85, 0xB4, 0x95, 0xC4, 0xD4, 0xE4, 0xF4, 0xA5, 0xB5, +0xC5, 0xD5, 0xE5, 0xF5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, 0x37, +0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, 0x11, 0x00, 0x02, 0x02, +0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x06, 0x05, 0x35, 0x01, 0x00, 0x02, +0x11, 0x03, 0x21, 0x31, 0x12, 0x04, 0x41, 0x51, 0x61, 0x71, 0x22, 0x13, 0x05, 0x32, 0x81, 0x91, +0x14, 0xA1, 0xB1, 0x42, 0x23, 0xC1, 0x52, 0xD1, 0xF0, 0x33, 0x24, 0x62, 0xE1, 0x72, 0x82, 0x92, +0x43, 0x53, 0x15, 0x63, 0x73, 0x34, 0xF1, 0x25, 0x06, 0x16, 0xA2, 0xB2, 0x83, 0x07, 0x26, 0x35, +0xC2, 0xD2, 0x44, 0x93, 0x54, 0xA3, 0x17, 0x64, 0x45, 0x55, 0x36, 0x74, 0x65, 0xE2, 0xF2, 0xB3, +0x84, 0xC3, 0xD3, 0x75, 0xE3, 0xF3, 0x46, 0x94, 0xA4, 0x85, 0xB4, 0x95, 0xC4, 0xD4, 0xE4, 0xF4, +0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, +0xF6, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xFF, 0xDA, 0x00, 0x0C, +0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, 0xF3, 0x44, 0x92, 0x5D, 0x3F, 0x4A, +0xE9, 0x9D, 0x12, 0xEC, 0x4E, 0x95, 0xEB, 0xB7, 0x14, 0x65, 0x67, 0x32, 0xFD, 0xE7, 0x26, 0xCB, +0xC0, 0x73, 0xEB, 0xBC, 0xD7, 0x5B, 0x1B, 0xF6, 0x5C, 0x8A, 0x19, 0x8F, 0x6B, 0xB1, 0xFD, 0x95, +0xFA, 0xDF, 0xA2, 0xB7, 0xFE, 0x31, 0x33, 0x2E, 0x51, 0x8C, 0x02, 0x41, 0x36, 0x6B, 0xD3, 0xAF, +0xE8, 0xCA, 0x7F, 0xF7, 0x28, 0x26, 0x9E, 0x61, 0x25, 0xD7, 0x55, 0xD1, 0xFA, 0x1D, 0x9B, 0x1F, +0x46, 0x18, 0x73, 0x6C, 0x39, 0x04, 0xD5, 0x79, 0xBD, 0xF6, 0x56, 0xD6, 0x64, 0x59, 0x4D, 0x0C, +0xB6, 0xBC, 0x5C, 0x9A, 0x7D, 0x1B, 0x1B, 0x4B, 0x76, 0x7B, 0xFE, 0x9A, 0xA1, 0x4F, 0x4A, 0xE9, +0x7D, 0x41, 0x8F, 0xA9, 0x86, 0xBE, 0x9B, 0x95, 0x83, 0x98, 0x59, 0x9D, 0xBA, 0xC2, 0x5B, 0xF6, +0x4B, 0x1F, 0xB3, 0xED, 0x2C, 0x6E, 0x45, 0x96, 0x3B, 0x7E, 0x0B, 0xBF, 0x42, 0xF6, 0xFF, 0x00, +0xC2, 0x56, 0xFB, 0x94, 0x63, 0x9A, 0x81, 0xBD, 0x24, 0x28, 0xD1, 0xB1, 0xB7, 0xE8, 0xF7, 0x47, +0x10, 0x70, 0x12, 0x5D, 0x46, 0x26, 0x0F, 0x41, 0xCE, 0x61, 0xCA, 0xC4, 0xC3, 0x61, 0xAE, 0xCC, +0x9C, 0x86, 0x55, 0x4B, 0xDF, 0x7B, 0xDC, 0xDA, 0x6B, 0x6E, 0x2F, 0xA0, 0xE7, 0xB2, 0x9C, 0x8A, +0xAD, 0xF5, 0x1C, 0xEB, 0x2D, 0x7B, 0x9F, 0xBB, 0x67, 0xE9, 0x3D, 0x3F, 0xF4, 0x68, 0x74, 0x74, +0x7E, 0x96, 0xDC, 0x9C, 0xEC, 0x8C, 0xF6, 0x55, 0x4E, 0x33, 0x6D, 0x18, 0xB8, 0x78, 0xA6, 0xE7, +0x52, 0x3D, 0x42, 0xD6, 0x5B, 0x7E, 0x4E, 0xFB, 0xEE, 0x7D, 0xEC, 0x66, 0x3E, 0x37, 0xE9, 0x9A, +0xCB, 0xAC, 0x7F, 0xA9, 0x93, 0x75, 0x54, 0x7F, 0xC1, 0xA5, 0xF7, 0xA8, 0x6B, 0x71, 0x90, 0x23, +0xA1, 0x02, 0xF7, 0xE1, 0xE1, 0xF9, 0x95, 0xC4, 0x1E, 0x6D, 0x25, 0xBF, 0x97, 0xF5, 0x7A, 0x8A, +0xA8, 0xCD, 0xA3, 0x10, 0x8C, 0xCC, 0xA6, 0x65, 0x53, 0xF6, 0x1B, 0x19, 0x60, 0x25, 0xF8, 0x96, +0x57, 0x75, 0xDE, 0xA0, 0x60, 0x73, 0x6B, 0x7F, 0xF3, 0x6C, 0xF5, 0x1F, 0xB7, 0xD9, 0x62, 0xC5, +0xCA, 0xC4, 0xC9, 0xC4, 0xB7, 0xD1, 0xCA, 0xAC, 0xD5, 0x6C, 0x07, 0x6C, 0x74, 0x4C, 0x1F, 0xA2, +0xEF, 0x6C, 0xA9, 0x21, 0x96, 0x13, 0xF9, 0x4F, 0xD0, 0xEF, 0x5F, 0x35, 0xD2, 0x41, 0x05, 0x12, +0x49, 0x24, 0xA4, 0x4A, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, +0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xFF, 0x00, 0xFF, 0xD0, 0xF3, 0x45, 0x7B, +0x17, 0xAD, 0xF5, 0x2C, 0x4C, 0x71, 0x8D, 0x8F, 0x65, 0x6D, 0xA4, 0x4C, 0x35, 0xD4, 0x53, 0x61, +0xD4, 0xEE, 0x32, 0xFB, 0xA9, 0xB2, 0xC7, 0x7F, 0x9C, 0xA8, 0xA4, 0x84, 0xA3, 0x19, 0x0A, 0x90, +0x12, 0x1F, 0xD6, 0x16, 0xAA, 0x7A, 0xBF, 0xAB, 0x9F, 0x59, 0xF0, 0x77, 0xDF, 0x57, 0xD6, 0x06, +0xE3, 0xB9, 0x85, 0xA1, 0xD8, 0xF9, 0x07, 0x16, 0xB3, 0x0E, 0x1E, 0xD7, 0xD2, 0xE6, 0xE3, 0x51, +0xBB, 0x6D, 0x8D, 0x3B, 0xD8, 0xED, 0x9F, 0xE0, 0xD5, 0xCB, 0xBA, 0xD7, 0x44, 0x75, 0xCE, 0x75, +0x1D, 0x57, 0x15, 0xB8, 0xFB, 0xCB, 0x99, 0x53, 0xF0, 0x1C, 0x5C, 0xD6, 0x92, 0xD7, 0x35, 0x8C, +0xB4, 0x61, 0x7B, 0x3D, 0x26, 0xB7, 0x67, 0xD0, 0xB3, 0xD4, 0xDE, 0xB8, 0x84, 0x95, 0x79, 0x72, +0x78, 0xCC, 0x8C, 0x81, 0x31, 0xBF, 0xD1, 0x8F, 0x07, 0x07, 0xD2, 0x32, 0x84, 0x96, 0xF0, 0x0B, +0xB7, 0xB5, 0x77, 0x59, 0xE9, 0x07, 0x4F, 0xDA, 0xF8, 0x6F, 0xE6, 0x1D, 0x67, 0x4F, 0x71, 0x77, +0x04, 0x35, 0xCF, 0x8C, 0x3D, 0xAF, 0xDB, 0xBB, 0x77, 0xA5, 0xFA, 0x3F, 0xF8, 0xDF, 0xF4, 0x87, +0xE9, 0xDD, 0x7B, 0xEA, 0xF5, 0x16, 0x58, 0xEC, 0xFE, 0xA3, 0x89, 0x92, 0xD7, 0x06, 0xB6, 0xA6, +0xD7, 0xD3, 0xDD, 0x5E, 0xC8, 0x27, 0x7B, 0x8C, 0x62, 0xEE, 0x7E, 0xFF, 0x00, 0xFA, 0x0B, 0x83, +0x49, 0x03, 0xC8, 0xE3, 0x22, 0xB8, 0xA5, 0xAF, 0x61, 0x8C, 0x7F, 0xEA, 0x35, 0x70, 0x0E, 0xEE, +0xDF, 0x53, 0xFA, 0xD1, 0x95, 0x76, 0x7D, 0xEE, 0xC0, 0x6D, 0x34, 0x61, 0x6F, 0x23, 0x1E, 0xAF, +0xB3, 0x50, 0x7D, 0x83, 0x40, 0xF7, 0x7A, 0x94, 0x39, 0xFB, 0xED, 0xDB, 0xEA, 0xBD, 0x64, 0xE5, +0x65, 0xDF, 0x99, 0x77, 0xAF, 0x79, 0x69, 0xB0, 0x80, 0xD9, 0x63, 0x19, 0x58, 0x81, 0xC7, 0xB2, +0x86, 0x55, 0x5F, 0xFD, 0x14, 0x24, 0x94, 0xF0, 0xC5, 0x08, 0x01, 0xC3, 0x10, 0x28, 0x55, 0xD7, +0xAB, 0xFC, 0x64, 0x80, 0x02, 0x92, 0x49, 0x25, 0x22, 0x54, 0x92, 0x49, 0x24, 0xA5, 0x24, 0x92, +0x49, 0x29, 0x49, 0x24, 0x92, 0x4A, 0x52, 0x49, 0x24, 0x92, 0x94, 0x92, 0x49, 0x24, 0xA7, 0xFF, +0xD1, 0xF3, 0x44, 0x92, 0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, +0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, +0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD2, 0xF3, +0x44, 0x92, 0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, +0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, +0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD3, 0xF3, 0x44, 0x92, +0x49, 0x15, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, +0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, +0xA4, 0x92, 0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD4, 0xF3, 0x44, 0x92, 0x49, 0x15, +0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, +0x25, 0x29, 0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, +0x49, 0x25, 0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD5, 0xF3, 0x44, 0x92, 0x49, 0x15, 0x29, 0x24, +0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, 0x29, +0x24, 0x92, 0x49, 0x4A, 0x49, 0x24, 0x92, 0x52, 0x92, 0x49, 0x24, 0x94, 0xA4, 0x92, 0x49, 0x25, +0x29, 0x24, 0x92, 0x49, 0x4F, 0xFF, 0xD6, 0xF3, 0x44, 0x95, 0x54, 0x91, 0x53, 0x69, 0x25, 0x55, +0x24, 0x94, 0xDA, 0x49, 0x55, 0x49, 0x25, 0x36, 0x92, 0x55, 0x52, 0x49, 0x4D, 0xA4, 0x95, 0x54, +0x92, 0x53, 0x69, 0x25, 0x55, 0x24, 0x94, 0xDA, 0x49, 0x55, 0x49, 0x25, 0x36, 0x92, 0x55, 0x52, +0x49, 0x4D, 0xA4, 0x95, 0x54, 0x92, 0x53, 0x69, 0x25, 0x55, 0x24, 0x94, 0xFF, 0x00, 0xFF, 0xD9, +0x38, 0x42, 0x49, 0x4D, 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x01, +0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x62, 0x00, 0x65, 0x00, +0x20, 0x00, 0x50, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x68, 0x00, +0x6F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x13, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x62, 0x00, +0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x73, 0x00, +0x68, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x20, 0x00, 0x43, 0x00, 0x53, 0x00, 0x34, 0x00, 0x00, 0x00, +0x01, 0x00, 0x38, 0x42, 0x49, 0x4D, 0x04, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, +0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xE1, 0x13, 0x39, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, +0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x78, 0x61, +0x70, 0x2F, 0x31, 0x2E, 0x30, 0x2F, 0x00, 0x3C, 0x3F, 0x78, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, +0x20, 0x62, 0x65, 0x67, 0x69, 0x6E, 0x3D, 0x22, 0xEF, 0xBB, 0xBF, 0x22, 0x20, 0x69, 0x64, 0x3D, +0x22, 0x57, 0x35, 0x4D, 0x30, 0x4D, 0x70, 0x43, 0x65, 0x68, 0x69, 0x48, 0x7A, 0x72, 0x65, 0x53, +0x7A, 0x4E, 0x54, 0x63, 0x7A, 0x6B, 0x63, 0x39, 0x64, 0x22, 0x3F, 0x3E, 0x20, 0x3C, 0x78, 0x3A, +0x78, 0x6D, 0x70, 0x6D, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x78, 0x3D, +0x22, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x3A, 0x6E, 0x73, 0x3A, 0x6D, 0x65, 0x74, 0x61, 0x2F, 0x22, +0x20, 0x78, 0x3A, 0x78, 0x6D, 0x70, 0x74, 0x6B, 0x3D, 0x22, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, +0x58, 0x4D, 0x50, 0x20, 0x43, 0x6F, 0x72, 0x65, 0x20, 0x34, 0x2E, 0x32, 0x2E, 0x32, 0x2D, 0x63, +0x30, 0x36, 0x33, 0x20, 0x35, 0x33, 0x2E, 0x33, 0x35, 0x32, 0x36, 0x32, 0x34, 0x2C, 0x20, 0x32, +0x30, 0x30, 0x38, 0x2F, 0x30, 0x37, 0x2F, 0x33, 0x30, 0x2D, 0x31, 0x38, 0x3A, 0x31, 0x32, 0x3A, +0x31, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x3E, 0x20, 0x3C, 0x72, 0x64, +0x66, 0x3A, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x72, 0x64, 0x66, 0x3D, +0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x33, 0x2E, 0x6F, +0x72, 0x67, 0x2F, 0x31, 0x39, 0x39, 0x39, 0x2F, 0x30, 0x32, 0x2F, 0x32, 0x32, 0x2D, 0x72, 0x64, +0x66, 0x2D, 0x73, 0x79, 0x6E, 0x74, 0x61, 0x78, 0x2D, 0x6E, 0x73, 0x23, 0x22, 0x3E, 0x20, 0x3C, +0x72, 0x64, 0x66, 0x3A, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, +0x72, 0x64, 0x66, 0x3A, 0x61, 0x62, 0x6F, 0x75, 0x74, 0x3D, 0x22, 0x22, 0x20, 0x78, 0x6D, 0x6C, +0x6E, 0x73, 0x3A, 0x78, 0x6D, 0x70, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6E, +0x73, 0x2E, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x78, 0x61, 0x70, 0x2F, +0x31, 0x2E, 0x30, 0x2F, 0x22, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x64, 0x63, 0x3D, 0x22, +0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x70, 0x75, 0x72, 0x6C, 0x2E, 0x6F, 0x72, 0x67, 0x2F, +0x64, 0x63, 0x2F, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x2F, 0x31, 0x2E, 0x31, 0x2F, +0x22, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x70, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, +0x70, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, 0x6F, +0x62, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x70, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, +0x2F, 0x31, 0x2E, 0x30, 0x2F, 0x22, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x78, 0x6D, 0x70, +0x4D, 0x4D, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, +0x6F, 0x62, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x78, 0x61, 0x70, 0x2F, 0x31, 0x2E, 0x30, 0x2F, +0x6D, 0x6D, 0x2F, 0x22, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x73, 0x74, 0x45, 0x76, 0x74, +0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, 0x6F, 0x62, +0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x78, 0x61, 0x70, 0x2F, 0x31, 0x2E, 0x30, 0x2F, 0x73, 0x54, +0x79, 0x70, 0x65, 0x2F, 0x52, 0x65, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6E, +0x74, 0x23, 0x22, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x74, 0x69, 0x66, 0x66, 0x3D, 0x22, +0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x2E, +0x63, 0x6F, 0x6D, 0x2F, 0x74, 0x69, 0x66, 0x66, 0x2F, 0x31, 0x2E, 0x30, 0x2F, 0x22, 0x20, 0x78, +0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x65, 0x78, 0x69, 0x66, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, +0x2F, 0x2F, 0x6E, 0x73, 0x2E, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x65, +0x78, 0x69, 0x66, 0x2F, 0x31, 0x2E, 0x30, 0x2F, 0x22, 0x20, 0x78, 0x6D, 0x70, 0x3A, 0x43, 0x72, +0x65, 0x61, 0x74, 0x6F, 0x72, 0x54, 0x6F, 0x6F, 0x6C, 0x3D, 0x22, 0x41, 0x64, 0x6F, 0x62, 0x65, +0x20, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x20, 0x32, 0x31, 0x2E, 0x30, 0x20, +0x28, 0x4D, 0x61, 0x63, 0x69, 0x6E, 0x74, 0x6F, 0x73, 0x68, 0x29, 0x22, 0x20, 0x78, 0x6D, 0x70, +0x3A, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x3D, 0x22, 0x32, 0x30, 0x32, +0x31, 0x2D, 0x31, 0x31, 0x2D, 0x30, 0x34, 0x54, 0x31, 0x30, 0x3A, 0x30, 0x36, 0x3A, 0x33, 0x37, +0x2B, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x22, 0x20, 0x78, 0x6D, 0x70, 0x3A, 0x4D, 0x6F, 0x64, 0x69, +0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3D, 0x22, 0x32, 0x30, 0x32, 0x31, 0x2D, 0x31, 0x31, 0x2D, +0x30, 0x34, 0x54, 0x31, 0x30, 0x3A, 0x31, 0x37, 0x3A, 0x31, 0x32, 0x2B, 0x30, 0x38, 0x3A, 0x30, +0x30, 0x22, 0x20, 0x78, 0x6D, 0x70, 0x3A, 0x4D, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x44, +0x61, 0x74, 0x65, 0x3D, 0x22, 0x32, 0x30, 0x32, 0x31, 0x2D, 0x31, 0x31, 0x2D, 0x30, 0x34, 0x54, +0x31, 0x30, 0x3A, 0x31, 0x37, 0x3A, 0x31, 0x32, 0x2B, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x22, 0x20, +0x64, 0x63, 0x3A, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x3D, 0x22, 0x69, 0x6D, 0x61, 0x67, 0x65, +0x2F, 0x6A, 0x70, 0x65, 0x67, 0x22, 0x20, 0x70, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, +0x3A, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x4D, 0x6F, 0x64, 0x65, 0x3D, 0x22, 0x33, 0x22, 0x20, 0x70, +0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x3A, 0x49, 0x43, 0x43, 0x50, 0x72, 0x6F, 0x66, +0x69, 0x6C, 0x65, 0x3D, 0x22, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, +0x36, 0x36, 0x2D, 0x32, 0x2E, 0x31, 0x22, 0x20, 0x78, 0x6D, 0x70, 0x4D, 0x4D, 0x3A, 0x49, 0x6E, +0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3D, 0x22, 0x78, 0x6D, 0x70, 0x2E, 0x69, 0x69, +0x64, 0x3A, 0x38, 0x35, 0x36, 0x38, 0x33, 0x42, 0x37, 0x38, 0x39, 0x37, 0x33, 0x43, 0x45, 0x43, +0x31, 0x31, 0x42, 0x33, 0x37, 0x34, 0x44, 0x44, 0x30, 0x46, 0x33, 0x41, 0x32, 0x43, 0x42, 0x44, +0x37, 0x31, 0x22, 0x20, 0x78, 0x6D, 0x70, 0x4D, 0x4D, 0x3A, 0x44, 0x6F, 0x63, 0x75, 0x6D, 0x65, +0x6E, 0x74, 0x49, 0x44, 0x3D, 0x22, 0x61, 0x64, 0x6F, 0x62, 0x65, 0x3A, 0x64, 0x6F, 0x63, 0x69, +0x64, 0x3A, 0x70, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x3A, 0x31, 0x66, 0x66, 0x33, +0x64, 0x32, 0x63, 0x64, 0x2D, 0x39, 0x35, 0x34, 0x36, 0x2D, 0x34, 0x62, 0x34, 0x62, 0x2D, 0x38, +0x36, 0x36, 0x38, 0x2D, 0x36, 0x35, 0x30, 0x35, 0x66, 0x66, 0x37, 0x39, 0x37, 0x36, 0x36, 0x36, +0x22, 0x20, 0x78, 0x6D, 0x70, 0x4D, 0x4D, 0x3A, 0x4F, 0x72, 0x69, 0x67, 0x69, 0x6E, 0x61, 0x6C, +0x44, 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x49, 0x44, 0x3D, 0x22, 0x78, 0x6D, 0x70, 0x2E, +0x64, 0x69, 0x64, 0x3A, 0x61, 0x38, 0x32, 0x36, 0x66, 0x31, 0x36, 0x31, 0x2D, 0x32, 0x39, 0x30, +0x65, 0x2D, 0x34, 0x66, 0x32, 0x37, 0x2D, 0x62, 0x37, 0x61, 0x61, 0x2D, 0x30, 0x32, 0x65, 0x38, +0x35, 0x37, 0x36, 0x31, 0x65, 0x66, 0x66, 0x63, 0x22, 0x20, 0x74, 0x69, 0x66, 0x66, 0x3A, 0x4F, +0x72, 0x69, 0x65, 0x6E, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x74, +0x69, 0x66, 0x66, 0x3A, 0x58, 0x52, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x3D, +0x22, 0x37, 0x32, 0x30, 0x30, 0x30, 0x30, 0x2F, 0x31, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x74, +0x69, 0x66, 0x66, 0x3A, 0x59, 0x52, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x3D, +0x22, 0x37, 0x32, 0x30, 0x30, 0x30, 0x30, 0x2F, 0x31, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x74, +0x69, 0x66, 0x66, 0x3A, 0x52, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x69, 0x6F, 0x6E, 0x55, 0x6E, +0x69, 0x74, 0x3D, 0x22, 0x32, 0x22, 0x20, 0x74, 0x69, 0x66, 0x66, 0x3A, 0x4E, 0x61, 0x74, 0x69, +0x76, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x3D, 0x22, 0x32, 0x35, 0x36, 0x2C, 0x32, 0x35, +0x37, 0x2C, 0x32, 0x35, 0x38, 0x2C, 0x32, 0x35, 0x39, 0x2C, 0x32, 0x36, 0x32, 0x2C, 0x32, 0x37, +0x34, 0x2C, 0x32, 0x37, 0x37, 0x2C, 0x32, 0x38, 0x34, 0x2C, 0x35, 0x33, 0x30, 0x2C, 0x35, 0x33, +0x31, 0x2C, 0x32, 0x38, 0x32, 0x2C, 0x32, 0x38, 0x33, 0x2C, 0x32, 0x39, 0x36, 0x2C, 0x33, 0x30, +0x31, 0x2C, 0x33, 0x31, 0x38, 0x2C, 0x33, 0x31, 0x39, 0x2C, 0x35, 0x32, 0x39, 0x2C, 0x35, 0x33, +0x32, 0x2C, 0x33, 0x30, 0x36, 0x2C, 0x32, 0x37, 0x30, 0x2C, 0x32, 0x37, 0x31, 0x2C, 0x32, 0x37, +0x32, 0x2C, 0x33, 0x30, 0x35, 0x2C, 0x33, 0x31, 0x35, 0x2C, 0x33, 0x33, 0x34, 0x33, 0x32, 0x3B, +0x43, 0x46, 0x30, 0x32, 0x35, 0x30, 0x34, 0x39, 0x39, 0x34, 0x30, 0x37, 0x33, 0x42, 0x37, 0x32, +0x42, 0x44, 0x36, 0x36, 0x41, 0x35, 0x37, 0x38, 0x32, 0x34, 0x36, 0x39, 0x39, 0x44, 0x37, 0x42, +0x22, 0x20, 0x65, 0x78, 0x69, 0x66, 0x3A, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x53, 0x70, 0x61, 0x63, +0x65, 0x3D, 0x22, 0x31, 0x22, 0x20, 0x65, 0x78, 0x69, 0x66, 0x3A, 0x50, 0x69, 0x78, 0x65, 0x6C, +0x58, 0x44, 0x69, 0x6D, 0x65, 0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x33, 0x32, 0x30, 0x22, +0x20, 0x65, 0x78, 0x69, 0x66, 0x3A, 0x50, 0x69, 0x78, 0x65, 0x6C, 0x59, 0x44, 0x69, 0x6D, 0x65, +0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x32, 0x34, 0x30, 0x22, 0x20, 0x65, 0x78, 0x69, 0x66, +0x3A, 0x4E, 0x61, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x3D, 0x22, 0x33, +0x36, 0x38, 0x36, 0x34, 0x2C, 0x34, 0x30, 0x39, 0x36, 0x30, 0x2C, 0x34, 0x30, 0x39, 0x36, 0x31, +0x2C, 0x33, 0x37, 0x31, 0x32, 0x31, 0x2C, 0x33, 0x37, 0x31, 0x32, 0x32, 0x2C, 0x34, 0x30, 0x39, +0x36, 0x32, 0x2C, 0x34, 0x30, 0x39, 0x36, 0x33, 0x2C, 0x33, 0x37, 0x35, 0x31, 0x30, 0x2C, 0x34, +0x30, 0x39, 0x36, 0x34, 0x2C, 0x33, 0x36, 0x38, 0x36, 0x37, 0x2C, 0x33, 0x36, 0x38, 0x36, 0x38, +0x2C, 0x33, 0x33, 0x34, 0x33, 0x34, 0x2C, 0x33, 0x33, 0x34, 0x33, 0x37, 0x2C, 0x33, 0x34, 0x38, +0x35, 0x30, 0x2C, 0x33, 0x34, 0x38, 0x35, 0x32, 0x2C, 0x33, 0x34, 0x38, 0x35, 0x35, 0x2C, 0x33, +0x34, 0x38, 0x35, 0x36, 0x2C, 0x33, 0x37, 0x33, 0x37, 0x37, 0x2C, 0x33, 0x37, 0x33, 0x37, 0x38, +0x2C, 0x33, 0x37, 0x33, 0x37, 0x39, 0x2C, 0x33, 0x37, 0x33, 0x38, 0x30, 0x2C, 0x33, 0x37, 0x33, +0x38, 0x31, 0x2C, 0x33, 0x37, 0x33, 0x38, 0x32, 0x2C, 0x33, 0x37, 0x33, 0x38, 0x33, 0x2C, 0x33, +0x37, 0x33, 0x38, 0x34, 0x2C, 0x33, 0x37, 0x33, 0x38, 0x35, 0x2C, 0x33, 0x37, 0x33, 0x38, 0x36, +0x2C, 0x33, 0x37, 0x33, 0x39, 0x36, 0x2C, 0x34, 0x31, 0x34, 0x38, 0x33, 0x2C, 0x34, 0x31, 0x34, +0x38, 0x34, 0x2C, 0x34, 0x31, 0x34, 0x38, 0x36, 0x2C, 0x34, 0x31, 0x34, 0x38, 0x37, 0x2C, 0x34, +0x31, 0x34, 0x38, 0x38, 0x2C, 0x34, 0x31, 0x34, 0x39, 0x32, 0x2C, 0x34, 0x31, 0x34, 0x39, 0x33, +0x2C, 0x34, 0x31, 0x34, 0x39, 0x35, 0x2C, 0x34, 0x31, 0x37, 0x32, 0x38, 0x2C, 0x34, 0x31, 0x37, +0x32, 0x39, 0x2C, 0x34, 0x31, 0x37, 0x33, 0x30, 0x2C, 0x34, 0x31, 0x39, 0x38, 0x35, 0x2C, 0x34, +0x31, 0x39, 0x38, 0x36, 0x2C, 0x34, 0x31, 0x39, 0x38, 0x37, 0x2C, 0x34, 0x31, 0x39, 0x38, 0x38, +0x2C, 0x34, 0x31, 0x39, 0x38, 0x39, 0x2C, 0x34, 0x31, 0x39, 0x39, 0x30, 0x2C, 0x34, 0x31, 0x39, +0x39, 0x31, 0x2C, 0x34, 0x31, 0x39, 0x39, 0x32, 0x2C, 0x34, 0x31, 0x39, 0x39, 0x33, 0x2C, 0x34, +0x31, 0x39, 0x39, 0x34, 0x2C, 0x34, 0x31, 0x39, 0x39, 0x35, 0x2C, 0x34, 0x31, 0x39, 0x39, 0x36, +0x2C, 0x34, 0x32, 0x30, 0x31, 0x36, 0x2C, 0x30, 0x2C, 0x32, 0x2C, 0x34, 0x2C, 0x35, 0x2C, 0x36, +0x2C, 0x37, 0x2C, 0x38, 0x2C, 0x39, 0x2C, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x2C, 0x31, 0x32, 0x2C, +0x31, 0x33, 0x2C, 0x31, 0x34, 0x2C, 0x31, 0x35, 0x2C, 0x31, 0x36, 0x2C, 0x31, 0x37, 0x2C, 0x31, +0x38, 0x2C, 0x32, 0x30, 0x2C, 0x32, 0x32, 0x2C, 0x32, 0x33, 0x2C, 0x32, 0x34, 0x2C, 0x32, 0x35, +0x2C, 0x32, 0x36, 0x2C, 0x32, 0x37, 0x2C, 0x32, 0x38, 0x2C, 0x33, 0x30, 0x3B, 0x41, 0x44, 0x42, +0x43, 0x32, 0x42, 0x31, 0x36, 0x34, 0x44, 0x46, 0x41, 0x46, 0x34, 0x42, 0x31, 0x35, 0x34, 0x37, +0x36, 0x33, 0x36, 0x34, 0x39, 0x32, 0x43, 0x37, 0x32, 0x39, 0x34, 0x43, 0x36, 0x22, 0x3E, 0x20, +0x3C, 0x78, 0x6D, 0x70, 0x4D, 0x4D, 0x3A, 0x48, 0x69, 0x73, 0x74, 0x6F, 0x72, 0x79, 0x3E, 0x20, +0x3C, 0x72, 0x64, 0x66, 0x3A, 0x53, 0x65, 0x71, 0x3E, 0x20, 0x3C, 0x72, 0x64, 0x66, 0x3A, 0x6C, +0x69, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x22, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x69, +0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3D, 0x22, 0x78, 0x6D, 0x70, 0x2E, 0x69, +0x69, 0x64, 0x3A, 0x61, 0x38, 0x32, 0x36, 0x66, 0x31, 0x36, 0x31, 0x2D, 0x32, 0x39, 0x30, 0x65, +0x2D, 0x34, 0x66, 0x32, 0x37, 0x2D, 0x62, 0x37, 0x61, 0x61, 0x2D, 0x30, 0x32, 0x65, 0x38, 0x35, +0x37, 0x36, 0x31, 0x65, 0x66, 0x66, 0x63, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x77, +0x68, 0x65, 0x6E, 0x3D, 0x22, 0x32, 0x30, 0x32, 0x31, 0x2D, 0x31, 0x31, 0x2D, 0x30, 0x34, 0x54, +0x31, 0x30, 0x3A, 0x30, 0x36, 0x3A, 0x33, 0x37, 0x2B, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x22, 0x20, +0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x41, 0x67, +0x65, 0x6E, 0x74, 0x3D, 0x22, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x50, 0x68, 0x6F, 0x74, 0x6F, +0x73, 0x68, 0x6F, 0x70, 0x20, 0x32, 0x31, 0x2E, 0x30, 0x20, 0x28, 0x4D, 0x61, 0x63, 0x69, 0x6E, +0x74, 0x6F, 0x73, 0x68, 0x29, 0x22, 0x2F, 0x3E, 0x20, 0x3C, 0x72, 0x64, 0x66, 0x3A, 0x6C, 0x69, +0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x63, +0x6F, 0x6E, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, +0x70, 0x61, 0x72, 0x61, 0x6D, 0x65, 0x74, 0x65, 0x72, 0x73, 0x3D, 0x22, 0x66, 0x72, 0x6F, 0x6D, +0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x70, 0x6E, 0x67, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6D, +0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x65, 0x67, 0x22, 0x2F, 0x3E, 0x20, 0x3C, 0x72, 0x64, 0x66, +0x3A, 0x6C, 0x69, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, +0x3D, 0x22, 0x73, 0x61, 0x76, 0x65, 0x64, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x69, +0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3D, 0x22, 0x78, 0x6D, 0x70, 0x2E, 0x69, +0x69, 0x64, 0x3A, 0x33, 0x62, 0x39, 0x35, 0x31, 0x61, 0x30, 0x65, 0x2D, 0x65, 0x62, 0x62, 0x63, +0x2D, 0x34, 0x62, 0x39, 0x38, 0x2D, 0x62, 0x38, 0x35, 0x62, 0x2D, 0x63, 0x37, 0x61, 0x36, 0x34, +0x38, 0x62, 0x38, 0x65, 0x37, 0x32, 0x32, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x77, +0x68, 0x65, 0x6E, 0x3D, 0x22, 0x32, 0x30, 0x32, 0x31, 0x2D, 0x31, 0x31, 0x2D, 0x30, 0x34, 0x54, +0x31, 0x30, 0x3A, 0x30, 0x39, 0x3A, 0x35, 0x35, 0x2B, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x22, 0x20, +0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x41, 0x67, +0x65, 0x6E, 0x74, 0x3D, 0x22, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x50, 0x68, 0x6F, 0x74, 0x6F, +0x73, 0x68, 0x6F, 0x70, 0x20, 0x32, 0x31, 0x2E, 0x30, 0x20, 0x28, 0x4D, 0x61, 0x63, 0x69, 0x6E, +0x74, 0x6F, 0x73, 0x68, 0x29, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x63, 0x68, 0x61, +0x6E, 0x67, 0x65, 0x64, 0x3D, 0x22, 0x2F, 0x22, 0x2F, 0x3E, 0x20, 0x3C, 0x72, 0x64, 0x66, 0x3A, +0x6C, 0x69, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, +0x22, 0x73, 0x61, 0x76, 0x65, 0x64, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x69, 0x6E, +0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3D, 0x22, 0x78, 0x6D, 0x70, 0x2E, 0x69, 0x69, +0x64, 0x3A, 0x38, 0x34, 0x36, 0x38, 0x33, 0x42, 0x37, 0x38, 0x39, 0x37, 0x33, 0x43, 0x45, 0x43, +0x31, 0x31, 0x42, 0x33, 0x37, 0x34, 0x44, 0x44, 0x30, 0x46, 0x33, 0x41, 0x32, 0x43, 0x42, 0x44, +0x37, 0x31, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x77, 0x68, 0x65, 0x6E, 0x3D, 0x22, +0x32, 0x30, 0x32, 0x31, 0x2D, 0x31, 0x31, 0x2D, 0x30, 0x34, 0x54, 0x31, 0x30, 0x3A, 0x31, 0x37, +0x3A, 0x31, 0x32, 0x2B, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, +0x3A, 0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x41, 0x67, 0x65, 0x6E, 0x74, 0x3D, 0x22, +0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0x70, 0x20, +0x43, 0x53, 0x34, 0x20, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x22, 0x20, 0x73, 0x74, 0x45, +0x76, 0x74, 0x3A, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x64, 0x3D, 0x22, 0x2F, 0x22, 0x2F, 0x3E, +0x20, 0x3C, 0x72, 0x64, 0x66, 0x3A, 0x6C, 0x69, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x61, +0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x73, 0x61, 0x76, 0x65, 0x64, 0x22, 0x20, 0x73, 0x74, +0x45, 0x76, 0x74, 0x3A, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x49, 0x44, 0x3D, 0x22, +0x78, 0x6D, 0x70, 0x2E, 0x69, 0x69, 0x64, 0x3A, 0x38, 0x35, 0x36, 0x38, 0x33, 0x42, 0x37, 0x38, +0x39, 0x37, 0x33, 0x43, 0x45, 0x43, 0x31, 0x31, 0x42, 0x33, 0x37, 0x34, 0x44, 0x44, 0x30, 0x46, +0x33, 0x41, 0x32, 0x43, 0x42, 0x44, 0x37, 0x31, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, +0x77, 0x68, 0x65, 0x6E, 0x3D, 0x22, 0x32, 0x30, 0x32, 0x31, 0x2D, 0x31, 0x31, 0x2D, 0x30, 0x34, +0x54, 0x31, 0x30, 0x3A, 0x31, 0x37, 0x3A, 0x31, 0x32, 0x2B, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x22, +0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x73, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x41, +0x67, 0x65, 0x6E, 0x74, 0x3D, 0x22, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x50, 0x68, 0x6F, 0x74, +0x6F, 0x73, 0x68, 0x6F, 0x70, 0x20, 0x43, 0x53, 0x34, 0x20, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, +0x73, 0x22, 0x20, 0x73, 0x74, 0x45, 0x76, 0x74, 0x3A, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x64, +0x3D, 0x22, 0x2F, 0x22, 0x2F, 0x3E, 0x20, 0x3C, 0x2F, 0x72, 0x64, 0x66, 0x3A, 0x53, 0x65, 0x71, +0x3E, 0x20, 0x3C, 0x2F, 0x78, 0x6D, 0x70, 0x4D, 0x4D, 0x3A, 0x48, 0x69, 0x73, 0x74, 0x6F, 0x72, +0x79, 0x3E, 0x20, 0x3C, 0x2F, 0x72, 0x64, 0x66, 0x3A, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, +0x74, 0x69, 0x6F, 0x6E, 0x3E, 0x20, 0x3C, 0x2F, 0x72, 0x64, 0x66, 0x3A, 0x52, 0x44, 0x46, 0x3E, +0x20, 0x3C, 0x2F, 0x78, 0x3A, 0x78, 0x6D, 0x70, 0x6D, 0x65, 0x74, 0x61, 0x3E, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x3F, +0x78, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x20, 0x65, 0x6E, 0x64, 0x3D, 0x22, 0x77, 0x22, 0x3F, +0x3E, 0xFF, 0xE2, 0x0C, 0x58, 0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, +0x00, 0x01, 0x01, 0x00, 0x00, 0x0C, 0x48, 0x4C, 0x69, 0x6E, 0x6F, 0x02, 0x10, 0x00, 0x00, 0x6D, +0x6E, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5A, 0x20, 0x07, 0xCE, 0x00, 0x02, 0x00, +0x09, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, 0x4D, 0x53, 0x46, 0x54, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0xD6, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0xD3, 0x2D, 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x50, 0x00, +0x00, 0x00, 0x33, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x00, 0x6C, 0x77, +0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x14, 0x62, 0x6B, 0x70, 0x74, 0x00, +0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5A, 0x00, 0x00, 0x02, 0x18, 0x00, +0x00, 0x00, 0x14, 0x67, 0x58, 0x59, 0x5A, 0x00, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x00, 0x14, 0x62, +0x58, 0x59, 0x5A, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, 0x64, 0x6D, 0x6E, 0x64, 0x00, +0x00, 0x02, 0x54, 0x00, 0x00, 0x00, 0x70, 0x64, 0x6D, 0x64, 0x64, 0x00, 0x00, 0x02, 0xC4, 0x00, +0x00, 0x00, 0x88, 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x4C, 0x00, 0x00, 0x00, 0x86, 0x76, +0x69, 0x65, 0x77, 0x00, 0x00, 0x03, 0xD4, 0x00, 0x00, 0x00, 0x24, 0x6C, 0x75, 0x6D, 0x69, 0x00, +0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x14, 0x6D, 0x65, 0x61, 0x73, 0x00, 0x00, 0x04, 0x0C, 0x00, +0x00, 0x00, 0x24, 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x0C, 0x72, +0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3C, 0x00, 0x00, 0x08, 0x0C, 0x67, 0x54, 0x52, 0x43, 0x00, +0x00, 0x04, 0x3C, 0x00, 0x00, 0x08, 0x0C, 0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3C, 0x00, +0x00, 0x08, 0x0C, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6F, 0x70, 0x79, 0x72, +0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, +0x77, 0x6C, 0x65, 0x74, 0x74, 0x2D, 0x50, 0x61, 0x63, 0x6B, 0x61, 0x72, 0x64, 0x20, 0x43, 0x6F, +0x6D, 0x70, 0x61, 0x6E, 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x12, 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, +0x2D, 0x32, 0x2E, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, +0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2D, 0x32, 0x2E, +0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x58, 0x59, 0x5A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x51, 0x00, +0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xCC, 0x58, 0x59, 0x5A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5A, 0x20, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xA2, 0x00, 0x00, 0x38, 0xF5, 0x00, 0x00, 0x03, 0x90, 0x58, +0x59, 0x5A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, 0x00, 0x00, 0xB7, 0x85, 0x00, +0x00, 0x18, 0xDA, 0x58, 0x59, 0x5A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xA0, 0x00, +0x00, 0x0F, 0x84, 0x00, 0x00, 0xB6, 0xCF, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, +0x77, 0x2E, 0x69, 0x65, 0x63, 0x2E, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, +0x77, 0x77, 0x2E, 0x69, 0x65, 0x63, 0x2E, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x2E, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2D, 0x32, 0x2E, 0x31, +0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6F, 0x6C, +0x6F, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x2D, 0x20, 0x73, 0x52, 0x47, 0x42, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x49, 0x45, 0x43, 0x20, +0x36, 0x31, 0x39, 0x36, 0x36, 0x2D, 0x32, 0x2E, 0x31, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, +0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x63, 0x6F, 0x6C, 0x6F, 0x75, 0x72, 0x20, 0x73, 0x70, 0x61, +0x63, 0x65, 0x20, 0x2D, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, +0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x52, 0x65, 0x66, 0x65, 0x72, +0x65, 0x6E, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6E, 0x67, 0x20, 0x43, 0x6F, 0x6E, +0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, +0x36, 0x36, 0x2D, 0x32, 0x2E, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x2C, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, +0x69, 0x6E, 0x67, 0x20, 0x43, 0x6F, 0x6E, 0x64, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x69, 0x6E, +0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2D, 0x32, 0x2E, 0x31, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x65, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, +0x13, 0xA4, 0xFE, 0x00, 0x14, 0x5F, 0x2E, 0x00, 0x10, 0xCF, 0x14, 0x00, 0x03, 0xED, 0xCC, 0x00, +0x04, 0x13, 0x0B, 0x00, 0x03, 0x5C, 0x9E, 0x00, 0x00, 0x00, 0x01, 0x58, 0x59, 0x5A, 0x20, 0x00, +0x00, 0x00, 0x00, 0x00, 0x4C, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, 0x00, 0x57, 0x1F, 0xE7, 0x6D, +0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8F, 0x00, +0x00, 0x00, 0x02, 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x63, +0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, +0x0A, 0x00, 0x0F, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2D, 0x00, +0x32, 0x00, 0x37, 0x00, 0x3B, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4A, 0x00, 0x4F, 0x00, 0x54, 0x00, +0x59, 0x00, 0x5E, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6D, 0x00, 0x72, 0x00, 0x77, 0x00, 0x7C, 0x00, +0x81, 0x00, 0x86, 0x00, 0x8B, 0x00, 0x90, 0x00, 0x95, 0x00, 0x9A, 0x00, 0x9F, 0x00, 0xA4, 0x00, +0xA9, 0x00, 0xAE, 0x00, 0xB2, 0x00, 0xB7, 0x00, 0xBC, 0x00, 0xC1, 0x00, 0xC6, 0x00, 0xCB, 0x00, +0xD0, 0x00, 0xD5, 0x00, 0xDB, 0x00, 0xE0, 0x00, 0xE5, 0x00, 0xEB, 0x00, 0xF0, 0x00, 0xF6, 0x00, +0xFB, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0D, 0x01, 0x13, 0x01, 0x19, 0x01, 0x1F, 0x01, 0x25, 0x01, +0x2B, 0x01, 0x32, 0x01, 0x38, 0x01, 0x3E, 0x01, 0x45, 0x01, 0x4C, 0x01, 0x52, 0x01, 0x59, 0x01, +0x60, 0x01, 0x67, 0x01, 0x6E, 0x01, 0x75, 0x01, 0x7C, 0x01, 0x83, 0x01, 0x8B, 0x01, 0x92, 0x01, +0x9A, 0x01, 0xA1, 0x01, 0xA9, 0x01, 0xB1, 0x01, 0xB9, 0x01, 0xC1, 0x01, 0xC9, 0x01, 0xD1, 0x01, +0xD9, 0x01, 0xE1, 0x01, 0xE9, 0x01, 0xF2, 0x01, 0xFA, 0x02, 0x03, 0x02, 0x0C, 0x02, 0x14, 0x02, +0x1D, 0x02, 0x26, 0x02, 0x2F, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4B, 0x02, 0x54, 0x02, 0x5D, 0x02, +0x67, 0x02, 0x71, 0x02, 0x7A, 0x02, 0x84, 0x02, 0x8E, 0x02, 0x98, 0x02, 0xA2, 0x02, 0xAC, 0x02, +0xB6, 0x02, 0xC1, 0x02, 0xCB, 0x02, 0xD5, 0x02, 0xE0, 0x02, 0xEB, 0x02, 0xF5, 0x03, 0x00, 0x03, +0x0B, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2D, 0x03, 0x38, 0x03, 0x43, 0x03, 0x4F, 0x03, 0x5A, 0x03, +0x66, 0x03, 0x72, 0x03, 0x7E, 0x03, 0x8A, 0x03, 0x96, 0x03, 0xA2, 0x03, 0xAE, 0x03, 0xBA, 0x03, +0xC7, 0x03, 0xD3, 0x03, 0xE0, 0x03, 0xEC, 0x03, 0xF9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20, 0x04, +0x2D, 0x04, 0x3B, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, 0x04, 0x7E, 0x04, 0x8C, 0x04, +0x9A, 0x04, 0xA8, 0x04, 0xB6, 0x04, 0xC4, 0x04, 0xD3, 0x04, 0xE1, 0x04, 0xF0, 0x04, 0xFE, 0x05, +0x0D, 0x05, 0x1C, 0x05, 0x2B, 0x05, 0x3A, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77, 0x05, +0x86, 0x05, 0x96, 0x05, 0xA6, 0x05, 0xB5, 0x05, 0xC5, 0x05, 0xD5, 0x05, 0xE5, 0x05, 0xF6, 0x06, +0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, 0x06, 0x6A, 0x06, 0x7B, 0x06, +0x8C, 0x06, 0x9D, 0x06, 0xAF, 0x06, 0xC0, 0x06, 0xD1, 0x06, 0xE3, 0x06, 0xF5, 0x07, 0x07, 0x07, +0x19, 0x07, 0x2B, 0x07, 0x3D, 0x07, 0x4F, 0x07, 0x61, 0x07, 0x74, 0x07, 0x86, 0x07, 0x99, 0x07, +0xAC, 0x07, 0xBF, 0x07, 0xD2, 0x07, 0xE5, 0x07, 0xF8, 0x08, 0x0B, 0x08, 0x1F, 0x08, 0x32, 0x08, +0x46, 0x08, 0x5A, 0x08, 0x6E, 0x08, 0x82, 0x08, 0x96, 0x08, 0xAA, 0x08, 0xBE, 0x08, 0xD2, 0x08, +0xE7, 0x08, 0xFB, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3A, 0x09, 0x4F, 0x09, 0x64, 0x09, 0x79, 0x09, +0x8F, 0x09, 0xA4, 0x09, 0xBA, 0x09, 0xCF, 0x09, 0xE5, 0x09, 0xFB, 0x0A, 0x11, 0x0A, 0x27, 0x0A, +0x3D, 0x0A, 0x54, 0x0A, 0x6A, 0x0A, 0x81, 0x0A, 0x98, 0x0A, 0xAE, 0x0A, 0xC5, 0x0A, 0xDC, 0x0A, +0xF3, 0x0B, 0x0B, 0x0B, 0x22, 0x0B, 0x39, 0x0B, 0x51, 0x0B, 0x69, 0x0B, 0x80, 0x0B, 0x98, 0x0B, +0xB0, 0x0B, 0xC8, 0x0B, 0xE1, 0x0B, 0xF9, 0x0C, 0x12, 0x0C, 0x2A, 0x0C, 0x43, 0x0C, 0x5C, 0x0C, +0x75, 0x0C, 0x8E, 0x0C, 0xA7, 0x0C, 0xC0, 0x0C, 0xD9, 0x0C, 0xF3, 0x0D, 0x0D, 0x0D, 0x26, 0x0D, +0x40, 0x0D, 0x5A, 0x0D, 0x74, 0x0D, 0x8E, 0x0D, 0xA9, 0x0D, 0xC3, 0x0D, 0xDE, 0x0D, 0xF8, 0x0E, +0x13, 0x0E, 0x2E, 0x0E, 0x49, 0x0E, 0x64, 0x0E, 0x7F, 0x0E, 0x9B, 0x0E, 0xB6, 0x0E, 0xD2, 0x0E, +0xEE, 0x0F, 0x09, 0x0F, 0x25, 0x0F, 0x41, 0x0F, 0x5E, 0x0F, 0x7A, 0x0F, 0x96, 0x0F, 0xB3, 0x0F, +0xCF, 0x0F, 0xEC, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61, 0x10, 0x7E, 0x10, 0x9B, 0x10, +0xB9, 0x10, 0xD7, 0x10, 0xF5, 0x11, 0x13, 0x11, 0x31, 0x11, 0x4F, 0x11, 0x6D, 0x11, 0x8C, 0x11, +0xAA, 0x11, 0xC9, 0x11, 0xE8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84, 0x12, +0xA3, 0x12, 0xC3, 0x12, 0xE3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43, 0x13, 0x63, 0x13, 0x83, 0x13, +0xA4, 0x13, 0xC5, 0x13, 0xE5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, 0x14, 0x6A, 0x14, 0x8B, 0x14, +0xAD, 0x14, 0xCE, 0x14, 0xF0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9B, 0x15, +0xBD, 0x15, 0xE0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6C, 0x16, 0x8F, 0x16, 0xB2, 0x16, +0xD6, 0x16, 0xFA, 0x17, 0x1D, 0x17, 0x41, 0x17, 0x65, 0x17, 0x89, 0x17, 0xAE, 0x17, 0xD2, 0x17, +0xF7, 0x18, 0x1B, 0x18, 0x40, 0x18, 0x65, 0x18, 0x8A, 0x18, 0xAF, 0x18, 0xD5, 0x18, 0xFA, 0x19, +0x20, 0x19, 0x45, 0x19, 0x6B, 0x19, 0x91, 0x19, 0xB7, 0x19, 0xDD, 0x1A, 0x04, 0x1A, 0x2A, 0x1A, +0x51, 0x1A, 0x77, 0x1A, 0x9E, 0x1A, 0xC5, 0x1A, 0xEC, 0x1B, 0x14, 0x1B, 0x3B, 0x1B, 0x63, 0x1B, +0x8A, 0x1B, 0xB2, 0x1B, 0xDA, 0x1C, 0x02, 0x1C, 0x2A, 0x1C, 0x52, 0x1C, 0x7B, 0x1C, 0xA3, 0x1C, +0xCC, 0x1C, 0xF5, 0x1D, 0x1E, 0x1D, 0x47, 0x1D, 0x70, 0x1D, 0x99, 0x1D, 0xC3, 0x1D, 0xEC, 0x1E, +0x16, 0x1E, 0x40, 0x1E, 0x6A, 0x1E, 0x94, 0x1E, 0xBE, 0x1E, 0xE9, 0x1F, 0x13, 0x1F, 0x3E, 0x1F, +0x69, 0x1F, 0x94, 0x1F, 0xBF, 0x1F, 0xEA, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6C, 0x20, 0x98, 0x20, +0xC4, 0x20, 0xF0, 0x21, 0x1C, 0x21, 0x48, 0x21, 0x75, 0x21, 0xA1, 0x21, 0xCE, 0x21, 0xFB, 0x22, +0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xAF, 0x22, 0xDD, 0x23, 0x0A, 0x23, 0x38, 0x23, 0x66, 0x23, +0x94, 0x23, 0xC2, 0x23, 0xF0, 0x24, 0x1F, 0x24, 0x4D, 0x24, 0x7C, 0x24, 0xAB, 0x24, 0xDA, 0x25, +0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xC7, 0x25, 0xF7, 0x26, 0x27, 0x26, 0x57, 0x26, +0x87, 0x26, 0xB7, 0x26, 0xE8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7A, 0x27, 0xAB, 0x27, 0xDC, 0x28, +0x0D, 0x28, 0x3F, 0x28, 0x71, 0x28, 0xA2, 0x28, 0xD4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6B, 0x29, +0x9D, 0x29, 0xD0, 0x2A, 0x02, 0x2A, 0x35, 0x2A, 0x68, 0x2A, 0x9B, 0x2A, 0xCF, 0x2B, 0x02, 0x2B, +0x36, 0x2B, 0x69, 0x2B, 0x9D, 0x2B, 0xD1, 0x2C, 0x05, 0x2C, 0x39, 0x2C, 0x6E, 0x2C, 0xA2, 0x2C, +0xD7, 0x2D, 0x0C, 0x2D, 0x41, 0x2D, 0x76, 0x2D, 0xAB, 0x2D, 0xE1, 0x2E, 0x16, 0x2E, 0x4C, 0x2E, +0x82, 0x2E, 0xB7, 0x2E, 0xEE, 0x2F, 0x24, 0x2F, 0x5A, 0x2F, 0x91, 0x2F, 0xC7, 0x2F, 0xFE, 0x30, +0x35, 0x30, 0x6C, 0x30, 0xA4, 0x30, 0xDB, 0x31, 0x12, 0x31, 0x4A, 0x31, 0x82, 0x31, 0xBA, 0x31, +0xF2, 0x32, 0x2A, 0x32, 0x63, 0x32, 0x9B, 0x32, 0xD4, 0x33, 0x0D, 0x33, 0x46, 0x33, 0x7F, 0x33, +0xB8, 0x33, 0xF1, 0x34, 0x2B, 0x34, 0x65, 0x34, 0x9E, 0x34, 0xD8, 0x35, 0x13, 0x35, 0x4D, 0x35, +0x87, 0x35, 0xC2, 0x35, 0xFD, 0x36, 0x37, 0x36, 0x72, 0x36, 0xAE, 0x36, 0xE9, 0x37, 0x24, 0x37, +0x60, 0x37, 0x9C, 0x37, 0xD7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8C, 0x38, 0xC8, 0x39, 0x05, 0x39, +0x42, 0x39, 0x7F, 0x39, 0xBC, 0x39, 0xF9, 0x3A, 0x36, 0x3A, 0x74, 0x3A, 0xB2, 0x3A, 0xEF, 0x3B, +0x2D, 0x3B, 0x6B, 0x3B, 0xAA, 0x3B, 0xE8, 0x3C, 0x27, 0x3C, 0x65, 0x3C, 0xA4, 0x3C, 0xE3, 0x3D, +0x22, 0x3D, 0x61, 0x3D, 0xA1, 0x3D, 0xE0, 0x3E, 0x20, 0x3E, 0x60, 0x3E, 0xA0, 0x3E, 0xE0, 0x3F, +0x21, 0x3F, 0x61, 0x3F, 0xA2, 0x3F, 0xE2, 0x40, 0x23, 0x40, 0x64, 0x40, 0xA6, 0x40, 0xE7, 0x41, +0x29, 0x41, 0x6A, 0x41, 0xAC, 0x41, 0xEE, 0x42, 0x30, 0x42, 0x72, 0x42, 0xB5, 0x42, 0xF7, 0x43, +0x3A, 0x43, 0x7D, 0x43, 0xC0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8A, 0x44, 0xCE, 0x45, 0x12, 0x45, +0x55, 0x45, 0x9A, 0x45, 0xDE, 0x46, 0x22, 0x46, 0x67, 0x46, 0xAB, 0x46, 0xF0, 0x47, 0x35, 0x47, +0x7B, 0x47, 0xC0, 0x48, 0x05, 0x48, 0x4B, 0x48, 0x91, 0x48, 0xD7, 0x49, 0x1D, 0x49, 0x63, 0x49, +0xA9, 0x49, 0xF0, 0x4A, 0x37, 0x4A, 0x7D, 0x4A, 0xC4, 0x4B, 0x0C, 0x4B, 0x53, 0x4B, 0x9A, 0x4B, +0xE2, 0x4C, 0x2A, 0x4C, 0x72, 0x4C, 0xBA, 0x4D, 0x02, 0x4D, 0x4A, 0x4D, 0x93, 0x4D, 0xDC, 0x4E, +0x25, 0x4E, 0x6E, 0x4E, 0xB7, 0x4F, 0x00, 0x4F, 0x49, 0x4F, 0x93, 0x4F, 0xDD, 0x50, 0x27, 0x50, +0x71, 0x50, 0xBB, 0x51, 0x06, 0x51, 0x50, 0x51, 0x9B, 0x51, 0xE6, 0x52, 0x31, 0x52, 0x7C, 0x52, +0xC7, 0x53, 0x13, 0x53, 0x5F, 0x53, 0xAA, 0x53, 0xF6, 0x54, 0x42, 0x54, 0x8F, 0x54, 0xDB, 0x55, +0x28, 0x55, 0x75, 0x55, 0xC2, 0x56, 0x0F, 0x56, 0x5C, 0x56, 0xA9, 0x56, 0xF7, 0x57, 0x44, 0x57, +0x92, 0x57, 0xE0, 0x58, 0x2F, 0x58, 0x7D, 0x58, 0xCB, 0x59, 0x1A, 0x59, 0x69, 0x59, 0xB8, 0x5A, +0x07, 0x5A, 0x56, 0x5A, 0xA6, 0x5A, 0xF5, 0x5B, 0x45, 0x5B, 0x95, 0x5B, 0xE5, 0x5C, 0x35, 0x5C, +0x86, 0x5C, 0xD6, 0x5D, 0x27, 0x5D, 0x78, 0x5D, 0xC9, 0x5E, 0x1A, 0x5E, 0x6C, 0x5E, 0xBD, 0x5F, +0x0F, 0x5F, 0x61, 0x5F, 0xB3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xAA, 0x60, 0xFC, 0x61, 0x4F, 0x61, +0xA2, 0x61, 0xF5, 0x62, 0x49, 0x62, 0x9C, 0x62, 0xF0, 0x63, 0x43, 0x63, 0x97, 0x63, 0xEB, 0x64, +0x40, 0x64, 0x94, 0x64, 0xE9, 0x65, 0x3D, 0x65, 0x92, 0x65, 0xE7, 0x66, 0x3D, 0x66, 0x92, 0x66, +0xE8, 0x67, 0x3D, 0x67, 0x93, 0x67, 0xE9, 0x68, 0x3F, 0x68, 0x96, 0x68, 0xEC, 0x69, 0x43, 0x69, +0x9A, 0x69, 0xF1, 0x6A, 0x48, 0x6A, 0x9F, 0x6A, 0xF7, 0x6B, 0x4F, 0x6B, 0xA7, 0x6B, 0xFF, 0x6C, +0x57, 0x6C, 0xAF, 0x6D, 0x08, 0x6D, 0x60, 0x6D, 0xB9, 0x6E, 0x12, 0x6E, 0x6B, 0x6E, 0xC4, 0x6F, +0x1E, 0x6F, 0x78, 0x6F, 0xD1, 0x70, 0x2B, 0x70, 0x86, 0x70, 0xE0, 0x71, 0x3A, 0x71, 0x95, 0x71, +0xF0, 0x72, 0x4B, 0x72, 0xA6, 0x73, 0x01, 0x73, 0x5D, 0x73, 0xB8, 0x74, 0x14, 0x74, 0x70, 0x74, +0xCC, 0x75, 0x28, 0x75, 0x85, 0x75, 0xE1, 0x76, 0x3E, 0x76, 0x9B, 0x76, 0xF8, 0x77, 0x56, 0x77, +0xB3, 0x78, 0x11, 0x78, 0x6E, 0x78, 0xCC, 0x79, 0x2A, 0x79, 0x89, 0x79, 0xE7, 0x7A, 0x46, 0x7A, +0xA5, 0x7B, 0x04, 0x7B, 0x63, 0x7B, 0xC2, 0x7C, 0x21, 0x7C, 0x81, 0x7C, 0xE1, 0x7D, 0x41, 0x7D, +0xA1, 0x7E, 0x01, 0x7E, 0x62, 0x7E, 0xC2, 0x7F, 0x23, 0x7F, 0x84, 0x7F, 0xE5, 0x80, 0x47, 0x80, +0xA8, 0x81, 0x0A, 0x81, 0x6B, 0x81, 0xCD, 0x82, 0x30, 0x82, 0x92, 0x82, 0xF4, 0x83, 0x57, 0x83, +0xBA, 0x84, 0x1D, 0x84, 0x80, 0x84, 0xE3, 0x85, 0x47, 0x85, 0xAB, 0x86, 0x0E, 0x86, 0x72, 0x86, +0xD7, 0x87, 0x3B, 0x87, 0x9F, 0x88, 0x04, 0x88, 0x69, 0x88, 0xCE, 0x89, 0x33, 0x89, 0x99, 0x89, +0xFE, 0x8A, 0x64, 0x8A, 0xCA, 0x8B, 0x30, 0x8B, 0x96, 0x8B, 0xFC, 0x8C, 0x63, 0x8C, 0xCA, 0x8D, +0x31, 0x8D, 0x98, 0x8D, 0xFF, 0x8E, 0x66, 0x8E, 0xCE, 0x8F, 0x36, 0x8F, 0x9E, 0x90, 0x06, 0x90, +0x6E, 0x90, 0xD6, 0x91, 0x3F, 0x91, 0xA8, 0x92, 0x11, 0x92, 0x7A, 0x92, 0xE3, 0x93, 0x4D, 0x93, +0xB6, 0x94, 0x20, 0x94, 0x8A, 0x94, 0xF4, 0x95, 0x5F, 0x95, 0xC9, 0x96, 0x34, 0x96, 0x9F, 0x97, +0x0A, 0x97, 0x75, 0x97, 0xE0, 0x98, 0x4C, 0x98, 0xB8, 0x99, 0x24, 0x99, 0x90, 0x99, 0xFC, 0x9A, +0x68, 0x9A, 0xD5, 0x9B, 0x42, 0x9B, 0xAF, 0x9C, 0x1C, 0x9C, 0x89, 0x9C, 0xF7, 0x9D, 0x64, 0x9D, +0xD2, 0x9E, 0x40, 0x9E, 0xAE, 0x9F, 0x1D, 0x9F, 0x8B, 0x9F, 0xFA, 0xA0, 0x69, 0xA0, 0xD8, 0xA1, +0x47, 0xA1, 0xB6, 0xA2, 0x26, 0xA2, 0x96, 0xA3, 0x06, 0xA3, 0x76, 0xA3, 0xE6, 0xA4, 0x56, 0xA4, +0xC7, 0xA5, 0x38, 0xA5, 0xA9, 0xA6, 0x1A, 0xA6, 0x8B, 0xA6, 0xFD, 0xA7, 0x6E, 0xA7, 0xE0, 0xA8, +0x52, 0xA8, 0xC4, 0xA9, 0x37, 0xA9, 0xA9, 0xAA, 0x1C, 0xAA, 0x8F, 0xAB, 0x02, 0xAB, 0x75, 0xAB, +0xE9, 0xAC, 0x5C, 0xAC, 0xD0, 0xAD, 0x44, 0xAD, 0xB8, 0xAE, 0x2D, 0xAE, 0xA1, 0xAF, 0x16, 0xAF, +0x8B, 0xB0, 0x00, 0xB0, 0x75, 0xB0, 0xEA, 0xB1, 0x60, 0xB1, 0xD6, 0xB2, 0x4B, 0xB2, 0xC2, 0xB3, +0x38, 0xB3, 0xAE, 0xB4, 0x25, 0xB4, 0x9C, 0xB5, 0x13, 0xB5, 0x8A, 0xB6, 0x01, 0xB6, 0x79, 0xB6, +0xF0, 0xB7, 0x68, 0xB7, 0xE0, 0xB8, 0x59, 0xB8, 0xD1, 0xB9, 0x4A, 0xB9, 0xC2, 0xBA, 0x3B, 0xBA, +0xB5, 0xBB, 0x2E, 0xBB, 0xA7, 0xBC, 0x21, 0xBC, 0x9B, 0xBD, 0x15, 0xBD, 0x8F, 0xBE, 0x0A, 0xBE, +0x84, 0xBE, 0xFF, 0xBF, 0x7A, 0xBF, 0xF5, 0xC0, 0x70, 0xC0, 0xEC, 0xC1, 0x67, 0xC1, 0xE3, 0xC2, +0x5F, 0xC2, 0xDB, 0xC3, 0x58, 0xC3, 0xD4, 0xC4, 0x51, 0xC4, 0xCE, 0xC5, 0x4B, 0xC5, 0xC8, 0xC6, +0x46, 0xC6, 0xC3, 0xC7, 0x41, 0xC7, 0xBF, 0xC8, 0x3D, 0xC8, 0xBC, 0xC9, 0x3A, 0xC9, 0xB9, 0xCA, +0x38, 0xCA, 0xB7, 0xCB, 0x36, 0xCB, 0xB6, 0xCC, 0x35, 0xCC, 0xB5, 0xCD, 0x35, 0xCD, 0xB5, 0xCE, +0x36, 0xCE, 0xB6, 0xCF, 0x37, 0xCF, 0xB8, 0xD0, 0x39, 0xD0, 0xBA, 0xD1, 0x3C, 0xD1, 0xBE, 0xD2, +0x3F, 0xD2, 0xC1, 0xD3, 0x44, 0xD3, 0xC6, 0xD4, 0x49, 0xD4, 0xCB, 0xD5, 0x4E, 0xD5, 0xD1, 0xD6, +0x55, 0xD6, 0xD8, 0xD7, 0x5C, 0xD7, 0xE0, 0xD8, 0x64, 0xD8, 0xE8, 0xD9, 0x6C, 0xD9, 0xF1, 0xDA, +0x76, 0xDA, 0xFB, 0xDB, 0x80, 0xDC, 0x05, 0xDC, 0x8A, 0xDD, 0x10, 0xDD, 0x96, 0xDE, 0x1C, 0xDE, +0xA2, 0xDF, 0x29, 0xDF, 0xAF, 0xE0, 0x36, 0xE0, 0xBD, 0xE1, 0x44, 0xE1, 0xCC, 0xE2, 0x53, 0xE2, +0xDB, 0xE3, 0x63, 0xE3, 0xEB, 0xE4, 0x73, 0xE4, 0xFC, 0xE5, 0x84, 0xE6, 0x0D, 0xE6, 0x96, 0xE7, +0x1F, 0xE7, 0xA9, 0xE8, 0x32, 0xE8, 0xBC, 0xE9, 0x46, 0xE9, 0xD0, 0xEA, 0x5B, 0xEA, 0xE5, 0xEB, +0x70, 0xEB, 0xFB, 0xEC, 0x86, 0xED, 0x11, 0xED, 0x9C, 0xEE, 0x28, 0xEE, 0xB4, 0xEF, 0x40, 0xEF, +0xCC, 0xF0, 0x58, 0xF0, 0xE5, 0xF1, 0x72, 0xF1, 0xFF, 0xF2, 0x8C, 0xF3, 0x19, 0xF3, 0xA7, 0xF4, +0x34, 0xF4, 0xC2, 0xF5, 0x50, 0xF5, 0xDE, 0xF6, 0x6D, 0xF6, 0xFB, 0xF7, 0x8A, 0xF8, 0x19, 0xF8, +0xA8, 0xF9, 0x38, 0xF9, 0xC7, 0xFA, 0x57, 0xFA, 0xE7, 0xFB, 0x77, 0xFC, 0x07, 0xFC, 0x98, 0xFD, +0x29, 0xFD, 0xBA, 0xFE, 0x4B, 0xFE, 0xDC, 0xFF, 0x6D, 0xFF, 0xFF, 0xFF, 0xEE, 0x00, 0x0E, 0x41, +0x64, 0x6F, 0x62, 0x65, 0x00, 0x64, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xDB, 0x00, 0x84, 0x00, +0x20, 0x21, 0x21, 0x33, 0x24, 0x33, 0x51, 0x30, 0x30, 0x51, 0x42, 0x2F, 0x2F, 0x2F, 0x42, 0x27, +0x1C, 0x1C, 0x1C, 0x1C, 0x27, 0x22, 0x17, 0x17, 0x17, 0x17, 0x17, 0x22, 0x11, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x01, 0x22, 0x33, 0x33, 0x34, 0x26, 0x34, 0x22, 0x18, 0x18, 0x22, 0x14, 0x0E, 0x0E, 0x0E, 0x14, +0x14, 0x0E, 0x0E, 0x0E, 0x0E, 0x14, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x11, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x11, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, +0x0C, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, +0x01, 0x03, 0x11, 0x01, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF, 0xC4, 0x01, 0x1B, 0x00, 0x00, +0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, +0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x02, 0x01, 0x03, 0x02, 0x03, +0x04, 0x07, 0x06, 0x03, 0x03, 0x06, 0x02, 0x01, 0x35, 0x01, 0x00, 0x02, 0x11, 0x03, 0x21, 0x12, +0x31, 0x04, 0x41, 0x51, 0x22, 0x13, 0x61, 0x71, 0x32, 0x81, 0x91, 0xB1, 0x42, 0xA1, 0x05, 0xD1, +0xC1, 0x14, 0xF0, 0x52, 0x23, 0x72, 0x33, 0x62, 0xE1, 0x82, 0xF1, 0x43, 0x34, 0x92, 0xA2, 0xB2, +0x15, 0xD2, 0x53, 0x24, 0x73, 0xC2, 0x63, 0x06, 0x83, 0x93, 0xE2, 0xF2, 0xA3, 0x44, 0x54, 0x64, +0x25, 0x35, 0x45, 0x16, 0x26, 0x74, 0x36, 0x55, 0x65, 0xB3, 0x84, 0xC3, 0xD3, 0x75, 0xE3, 0xF3, +0x46, 0x94, 0xA4, 0x85, 0xB4, 0x95, 0xC4, 0xD4, 0xE4, 0xF4, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, +0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, 0x11, 0x00, 0x02, 0x02, 0x00, +0x05, 0x01, 0x06, 0x06, 0x01, 0x03, 0x01, 0x03, 0x05, 0x03, 0x06, 0x2F, 0x00, 0x01, 0x11, 0x02, +0x21, 0x03, 0x31, 0x41, 0x12, 0x51, 0x61, 0x71, 0x81, 0x91, 0x22, 0x13, 0x32, 0xF0, 0xA1, 0xB1, +0x04, 0xC1, 0xD1, 0xE1, 0xF1, 0x42, 0x52, 0x23, 0x62, 0x72, 0x14, 0x92, 0x33, 0x82, 0x43, 0x24, +0xA2, 0xB2, 0x34, 0x53, 0x44, 0x63, 0x73, 0xC2, 0xD2, 0x83, 0x93, 0xA3, 0x54, 0xE2, 0xF2, 0x05, +0x15, 0x25, 0x06, 0x16, 0x26, 0x35, 0x64, 0x45, 0x55, 0x36, 0x74, 0x65, 0xB3, 0x84, 0xC3, 0xD3, +0x75, 0xE3, 0xF3, 0x46, 0x94, 0xA4, 0x85, 0xB4, 0x95, 0xC4, 0xD4, 0xE4, 0xF4, 0xA5, 0xB5, 0xC5, +0xD5, 0xE5, 0xF5, 0x56, 0x66, 0x76, 0x86, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, +0x03, 0x11, 0x00, 0x3F, 0x00, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, +0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, +0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD0, 0xF0, +0xD5, 0x55, 0x03, 0xA3, 0x06, 0x0F, 0x58, 0x48, 0xDD, 0x6C, 0x1E, 0x1B, 0xBF, 0x8F, 0xFC, 0x7F, +0xF9, 0x4D, 0xD2, 0x3D, 0x36, 0x39, 0x57, 0xF3, 0x05, 0x9F, 0xB3, 0xB7, 0xFF, 0x00, 0x8B, 0x37, +0xD1, 0x10, 0x04, 0xEC, 0xF6, 0xFF, 0x00, 0xE0, 0xCE, 0xBD, 0x36, 0x78, 0x4F, 0xCB, 0x21, 0x18, +0xCF, 0xEC, 0x4F, 0x6F, 0xEF, 0xFC, 0xD7, 0x93, 0x76, 0x9B, 0x7F, 0xE5, 0x64, 0x39, 0xCF, 0x46, +0x44, 0xA4, 0x2F, 0xE0, 0x1B, 0xF8, 0xF8, 0xD4, 0x74, 0xD0, 0xFF, 0x00, 0xBC, 0x8F, 0xEF, 0xFF, +0x00, 0x99, 0x1E, 0x98, 0x4C, 0xEE, 0xC9, 0xBC, 0x8B, 0xDB, 0xF6, 0x7E, 0x0F, 0xB7, 0xFD, 0x96, +0x80, 0x34, 0x34, 0xC0, 0xCE, 0x4F, 0xE7, 0xFE, 0x00, 0x71, 0xC3, 0xA6, 0x19, 0x24, 0x63, 0x19, +0x03, 0x5E, 0xCF, 0x8F, 0xFE, 0x7B, 0xCD, 0xB0, 0xEE, 0xDB, 0xF6, 0xAF, 0x6B, 0xB4, 0xA4, 0x71, +0x65, 0xDC, 0x36, 0xDD, 0xEE, 0xFE, 0x57, 0xF6, 0xFF, 0x00, 0xF1, 0x4F, 0x79, 0x38, 0xC4, 0xC6, +0x7E, 0xC4, 0x7F, 0xC9, 0xC9, 0xFB, 0xFF, 0x00, 0x25, 0xD4, 0xB5, 0xFF, 0x00, 0x96, 0x73, 0xA7, +0xA3, 0xFF, 0x00, 0x35, 0x07, 0x29, 0xE8, 0xEA, 0x63, 0x1E, 0xEF, 0x31, 0x1B, 0xBE, 0x1F, 0x83, +0xFE, 0x7B, 0x23, 0xA6, 0x87, 0x7C, 0x91, 0x89, 0xD7, 0xCB, 0xFB, 0xE4, 0x6F, 0xA7, 0xCB, 0xBF, +0x3E, 0xF9, 0x77, 0xDC, 0xEF, 0x1B, 0x3C, 0x0C, 0x3C, 0xCF, 0xFB, 0x9F, 0xDC, 0xF8, 0xA6, 0xE5, +0xBB, 0x20, 0x79, 0xF9, 0x71, 0xC7, 0x1D, 0x6D, 0x90, 0x9F, 0xF4, 0x3B, 0x43, 0xA4, 0x32, 0x86, +0xF2, 0x68, 0xCB, 0xFB, 0x70, 0xDB, 0xF1, 0xFF, 0x00, 0xCF, 0x74, 0x9E, 0x2D, 0xF9, 0x00, 0x96, +0xC8, 0x83, 0xF1, 0x7A, 0x3F, 0x06, 0xD8, 0x7F, 0xEF, 0xC7, 0x6C, 0x99, 0xF1, 0xEF, 0x00, 0x93, +0x11, 0x8F, 0xFB, 0x7E, 0x9F, 0xEF, 0xFF, 0x00, 0x98, 0x9B, 0x2F, 0x0E, 0x20, 0xF3, 0xBD, 0x32, +0x27, 0xB0, 0xE8, 0x6F, 0x6A, 0x73, 0x62, 0xF4, 0xA5, 0xB6, 0xED, 0xEE, 0xCF, 0xB2, 0x66, 0x39, +0x62, 0x47, 0x23, 0x7B, 0x3D, 0x46, 0x23, 0x9B, 0x21, 0x31, 0x31, 0xAF, 0x2F, 0xC5, 0x36, 0xAB, +0x69, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x9A, 0x03, 0xCE, 0x57, 0x7C, 0x9D, 0x3C, 0xB1, 0x8B, 0x26, +0x27, 0xFA, 0x25, 0xB9, 0xC1, 0xE8, 0x9C, 0x94, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, +0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, +0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD1, 0xF0, 0xD5, 0x55, 0x03, 0x5C, +0x59, 0x06, 0x3B, 0xB8, 0xC6, 0x77, 0xFC, 0x6E, 0xFF, 0x00, 0xB5, 0x43, 0xFE, 0xEE, 0x0F, 0x1A, +0xB1, 0xA4, 0xC1, 0xDD, 0x1E, 0xA7, 0x19, 0x20, 0x1C, 0x70, 0x01, 0xF4, 0xFD, 0x0C, 0x7F, 0xC3, +0x1F, 0xF9, 0x31, 0x7E, 0x79, 0xEF, 0xC5, 0xD7, 0x1C, 0x71, 0x11, 0x23, 0x75, 0x7D, 0xAD, 0xDB, +0x7F, 0xF7, 0xDB, 0xCA, 0xD5, 0x7F, 0xF6, 0x7F, 0xF8, 0x44, 0x68, 0xEA, 0xC9, 0xB2, 0x12, 0x20, +0xC2, 0x1B, 0x44, 0x7D, 0x4D, 0xDF, 0xE1, 0xFF, 0x00, 0xCD, 0x7F, 0xF7, 0x8E, 0x43, 0x26, 0x39, +0x00, 0x44, 0x21, 0xC6, 0xE9, 0xEE, 0xDB, 0x0F, 0xB5, 0xE8, 0xFA, 0x78, 0xBC, 0x9F, 0xCC, 0x60, +0xF5, 0xE0, 0xF3, 0x0F, 0xF9, 0xFF, 0x00, 0xFC, 0x41, 0x1F, 0xB6, 0xC4, 0x9B, 0xF4, 0xC5, 0xFC, +0x5F, 0x17, 0xFF, 0x00, 0x10, 0x67, 0x1B, 0x7F, 0xA7, 0xFF, 0x00, 0x4E, 0x7F, 0xEA, 0xE4, 0x36, +0xDD, 0x01, 0xF1, 0x42, 0x03, 0x53, 0x0E, 0xDF, 0xEE, 0xFF, 0x00, 0xBF, 0xFE, 0xED, 0x4C, 0xF1, +0x8B, 0x3B, 0x21, 0x5E, 0x6D, 0x9F, 0x0E, 0xF9, 0x6C, 0xFF, 0x00, 0xCA, 0x3F, 0xF9, 0x51, 0xCB, +0xF6, 0xE8, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x95, 0xFF, 0x00, 0xC4, 0x11, 0xFB, 0x6C, 0x6E, 0xFD, +0x31, 0x7F, 0xD5, 0xFF, 0x00, 0xD8, 0xEA, 0x1F, 0xFA, 0x6D, 0xFF, 0x00, 0xA5, 0x7F, 0xF5, 0x70, +0x54, 0xB3, 0xE2, 0x1F, 0x62, 0x3F, 0x0E, 0xEE, 0x3E, 0xDF, 0xFD, 0xCF, 0xC0, 0xF7, 0x0C, 0x38, +0xC8, 0xBD, 0xB1, 0xFF, 0x00, 0x92, 0x1F, 0x3F, 0xF6, 0xD8, 0xFF, 0x00, 0xDD, 0x8F, 0xF9, 0x5F, +0xFC, 0x41, 0xBF, 0xFA, 0xC7, 0xFC, 0x1F, 0xF3, 0xFF, 0x00, 0xF8, 0x83, 0x1D, 0x6D, 0xFE, 0x35, +0xB7, 0xFE, 0x94, 0x05, 0xF5, 0x33, 0xC7, 0x86, 0x80, 0x84, 0x64, 0x4F, 0xF8, 0x5E, 0x5F, 0xDA, +0xA1, 0xFF, 0x00, 0x77, 0x07, 0x9F, 0x2E, 0x43, 0x96, 0x46, 0x47, 0xBB, 0x9B, 0xD5, 0x57, 0x0F, +0x51, 0x60, 0xE8, 0xCB, 0x9A, 0x33, 0x14, 0x21, 0x18, 0x1F, 0xE2, 0x83, 0xCE, 0xAA, 0xE9, 0x28, +0x28, 0xAA, 0xAB, 0x40, 0xAA, 0xAA, 0x02, 0xAA, 0xA8, 0x0A, 0xAA, 0xA0, 0x2A, 0xAA, 0x80, 0xAA, +0xAA, 0x02, 0xAA, 0xA8, 0x0A, 0xAA, 0xA0, 0x2A, 0xAA, 0x80, 0xAA, 0xAA, 0x02, 0xAA, 0xA8, 0x0A, +0xAA, 0xA0, 0x7F, 0xFF, 0xD2, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, +0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, +0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD3, 0xF0, +0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, +0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, +0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD4, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, +0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, +0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, +0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0xFF, 0xD5, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, +0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, +0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, +0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD6, 0xF0, 0xD5, 0x55, +0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, +0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, +0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, +0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD7, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, +0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, +0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, +0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, +0xD0, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, +0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, +0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, +0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD1, 0xF0, 0xD5, 0x55, 0x01, 0x55, +0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, +0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, +0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, +0x15, 0x55, 0x40, 0xFF, 0xD2, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, +0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, +0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD3, 0xF0, +0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, +0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, +0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD4, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, +0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, +0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, +0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, +0x40, 0xFF, 0xD5, 0xF0, 0xD5, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, +0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, +0x55, 0x50, 0x15, 0x55, 0x40, 0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, +0x55, 0x55, 0x01, 0x55, 0x54, 0x05, 0x55, 0x50, 0x15, 0x55, 0x40, 0xFF, 0xD9 }; -#endif +#endif \ No newline at end of file From baefeb41c0f1732ae4ab636e19a9bab87ce1d87c Mon Sep 17 00:00:00 2001 From: payton Date: Tue, 31 Oct 2023 17:56:27 +0800 Subject: [PATCH 04/12] =?UTF-8?q?1.Linux=E4=B8=8B=E6=B0=B4=E5=8D=B0?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cardv/SrcCode/PrjCfg_HUNTING_S550.h | 1 + .../cardv/SrcCode/UIApp/Photo/UIAppPhoto.h | 34 +- .../SrcCode/UIApp/Photo/UIAppPhoto_Exe.c | 530 ++++++++++++++---- .../cardv/SrcCode/UIApp/Photo/UIDateImprint.c | 2 +- 4 files changed, 432 insertions(+), 135 deletions(-) diff --git a/code/application/source/cardv/SrcCode/PrjCfg_HUNTING_S550.h b/code/application/source/cardv/SrcCode/PrjCfg_HUNTING_S550.h index bd02a19ee..2618bdd26 100755 --- a/code/application/source/cardv/SrcCode/PrjCfg_HUNTING_S550.h +++ b/code/application/source/cardv/SrcCode/PrjCfg_HUNTING_S550.h @@ -918,6 +918,7 @@ #define HUNTING_CAMERA_4G ENABLE//DISABLE #define PHOTO_PREVIEW_SLICE_ENC_FUNC ENABLE #define PHOTO_PREVIEW_SLICE_ENC_VER2_FUNC ENABLE +#define PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP ENABLE #define DZOOM_FUNC ENABLE #define HUNTING_MCU_I2C DISABLE #define HUNTING_MCU_UART ENABLE diff --git a/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto.h b/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto.h index 0717d5ef0..765bf8335 100755 --- a/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto.h +++ b/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto.h @@ -73,12 +73,29 @@ #else #if PHOTO_PREVIEW_SLICE_ENC_FUNC #define PHOTO_MAX_CAP_SIZE UIAPP_PHOTO_SIZE_40M /* Max slice encode size */ - #define PHOTO_SLICE_ENC_MIN_CAP_SIZE UIAPP_PHOTO_SIZE_2M /* UI Menu only display options which size is larger than PHOTO_SLICE_ENC_MIN_CAP_SIZE */ + #define PHOTO_MIN_CAP_SIZE UIAPP_PHOTO_SIZE_2M /* UI Menu only display options which size is larger than PHOTO_SLICE_ENC_MIN_CAP_SIZE */ #else #define PHOTO_MAX_CAP_SIZE UIAPP_PHOTO_SIZE_12M #endif #endif +#if PHOTO_PREVIEW_SLICE_ENC_FUNC == ENABLE +#define CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_WIDTH 1920 +#define CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_HEIGHT 1080 +#define CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_SIZE VDO_YUV_BUFSIZE(CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_WIDTH, CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_HEIGHT, HD_VIDEO_PXLFMT_YUV420) +#define CFG_JPG_PREVIEW_SLICE_ENC_BS_BUF_RATIO JPG_COMERESSED_RATIO_8 /* (yuv size / ratio) + header = bs buf size */ +#define CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_PRIMARY 90 +#define CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_THUMBNAIL 70 +#define CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL 70 +#define CFG_JPG_PREVIEW_SLICE_ENC_QUALITY_STEP 10 + +#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL 1 /* rate control */ +#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL_UBOUND (SCREENNAIL_TARGETBYTERATE + (SCREENNAIL_TARGETBYTERATE * 20 / 100)) +#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL_LBOUND (SCREENNAIL_TARGETBYTERATE - (SCREENNAIL_TARGETBYTERATE * 20 / 100)) +#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL_QUALITY_STEP 2 + +#endif + #define JPG_COMERESSED_RATIO_5 (5) #define JPG_COMERESSED_RATIO_6 (6) #define JPG_COMERESSED_RATIO_7 (7) @@ -105,22 +122,7 @@ #define PRIMARY_TARGETBYTERATE_LBOUND(TBR) (TBR - (TBR * 15 / 100)) #define JPG_FILE_BUFFER_SIZE(primary, screenail, thumbnail, exif) (primary + screenail + thumbnail + exif*6) -#if PHOTO_PREVIEW_SLICE_ENC_FUNC == ENABLE -#define CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_WIDTH 1920 -#define CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_HEIGHT 1080 -#define CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_SIZE VDO_YUV_BUFSIZE(CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_WIDTH, CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_HEIGHT, HD_VIDEO_PXLFMT_YUV420) -#define CFG_JPG_PREVIEW_SLICE_ENC_BS_BUF_RATIO 8 /* (yuv size / ratio) + header = bs buf size */ -#define CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_PRIMARY 90 -#define CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_THUMBNAIL 70 -#define CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL 70 -#define CFG_JPG_PREVIEW_SLICE_ENC_QUALITY_STEP 3 -#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL 1 /* rate control */ -#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL_UBOUND (SCREENNAIL_TARGETBYTERATE + (SCREENNAIL_TARGETBYTERATE * 20 / 100)) -#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL_LBOUND (SCREENNAIL_TARGETBYTERATE - (SCREENNAIL_TARGETBYTERATE * 20 / 100)) -#define CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL_QUALITY_STEP 2 - -#endif extern UINT32 gPhotoFrameBuf; diff --git a/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto_Exe.c b/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto_Exe.c index d7df8b1a3..0470dc728 100755 --- a/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto_Exe.c +++ b/code/application/source/cardv/SrcCode/UIApp/Photo/UIAppPhoto_Exe.c @@ -35,6 +35,11 @@ #if HUNTING_CAMERA_MCU == ENABLE #include #endif + +#if (USE_DCF == ENABLE) +#include "DCF.h" +#endif + #define THIS_DBGLVL 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER #if 1//_TODO @@ -133,7 +138,8 @@ PHOTO_STRM_CBR_INFO g_tStrmCbrInfo[SENSOR_MAX_NUM] = { #define PHOTO_SLICE_ENC_DBG_PERF 0 #define PHOTO_SLICE_ENC_DBG_DUMP 0 #define PHOTO_SLICE_ENC_DBG_PRIMARY_YUV 0 -#define PHOTO_SLICE_ENC_DBG_SLICE_YUV 0 +#define PHOTO_SLICE_ENC_DBG_SRC_SLICE_YUV 0 +#define PHOTO_SLICE_ENC_DBG_DST_SLICE_YUV 0 #define PHOTO_SLICE_ENC_DBG_PRIMARY_JPG 0 #define PHOTO_SLICE_ENC_DBG_SCREENNAIL_JPG 0 @@ -219,7 +225,7 @@ static PhotoExe_SliceEncode_Info* PhotoExe_Preview_SliceEncode_Get_Info(const PH static INT32 PhotoExe_Preview_SliceEncode_Open(void); static INT32 PhotoExe_Preview_SliceEncode_Close(void); static INT32 PhotoExe_Preview_SliceEncode_Get_Dst_Slice_Info(PhotoExe_SliceSize_Info *info, UINT32 cap_size_w, UINT32 cap_size_h, UINT32 slice_num); -static INT32 PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(PhotoExe_SliceSize_Info *info); +static INT32 PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(PhotoExe_SliceSize_Info *info, const HD_VIDEO_FRAME src_frame); static INT32 PhotoExe_Preview_SliceEncode_Get_Max_Dst_Slice_Info(PhotoExe_SliceSize_Info *info); static UINT32 PhotoExe_Preview_SliceEncode_Get_Max_Dst_Slice_Buffer_Size(HD_VIDEO_PXLFMT pxl_fmt); static HD_DIM PhotoExe_Preview_SliceEncode_Get_Encode_Max_Size(void); @@ -695,12 +701,12 @@ UINT32 PhotoExe_GetFreePicNum(void) #endif uiFreeSpace = FileSys_GetDiskInfo(FST_INFO_FREE_SPACE); - DBG_IND("[cap]Free Space = %d KB\r\n", uiFreeSpace / 1024); + //DBG_IND("[cap]Free Space = %d KB\r\n", uiFreeSpace / 1024); size = UI_GetData(FL_PHOTO_SIZE); CaptureSize = PhotoExe_GetExpectSize_RhoBRCrtl(size, TRUE); - DBG_IND("[cap]CaptureSize = %d K \r\n", CaptureSize / 1024); + //DBG_IND("[cap]CaptureSize = %d K \r\n", CaptureSize / 1024); if (uiFreeSpace < reserveSize) { freeImgNum = 0; @@ -708,7 +714,7 @@ UINT32 PhotoExe_GetFreePicNum(void) freeImgNum = (uiFreeSpace - reserveSize) / CaptureSize; } - DBG_IND("[cap]Free ImgNum = %d\r\n", freeImgNum); + //DBG_IND("[cap]Free ImgNum = %d\r\n", freeImgNum); uiMaxImageSize = CaptureSize + reserveSize; //uiMaxImageSize = CaptureSize ; @@ -717,7 +723,7 @@ UINT32 PhotoExe_GetFreePicNum(void) localInfo->uiMaxImageSize = uiMaxImageSize; //NA51055-1333 localInfo->uiMaxImageSize = ALIGN_CEIL_4(localInfo->uiMaxImageSize); - DBG_IND("[cap]uiMaxImageSize = %ld KB\r\n", uiMaxImageSize / 1024); + //DBG_IND("[cap]uiMaxImageSize = %ld KB\r\n", uiMaxImageSize / 1024); //#NT#store in info localInfo->FreePicNum = freeImgNum; @@ -737,16 +743,16 @@ UINT32 PhotoExe_GetTotalPicNum(void) UINT32 size; uiSpace = FileSys_GetDiskInfo(FST_INFO_DISK_SIZE); - DBG_IND("[cap]Free Space = %d KB\r\n", uiSpace / 1024); + //DBG_IND("[cap]Free Space = %d KB\r\n", uiSpace / 1024); size = UI_GetData(FL_PHOTO_SIZE); CaptureSize = PhotoExe_GetExpectSize_RhoBRCrtl(size, TRUE); - DBG_IND("[cap]CaptureSize = %d K \r\n", CaptureSize / 1024); + //DBG_IND("[cap]CaptureSize = %d K \r\n", CaptureSize / 1024); totalImgNum = (uiSpace - reserveSize) / CaptureSize; - DBG_IND("[cap]Free ImgNum = %d\r\n", totalImgNum); + //DBG_IND("[cap]Free ImgNum = %d\r\n", totalImgNum); return totalImgNum; } @@ -4258,6 +4264,10 @@ static INT32 PhotoExe_Preview_SliceEncode_Open(void) in = HD_VIDEOENC_IN(0, first_out_port); out = HD_VIDEOENC_OUT(0, first_out_port); ret = hd_videoenc_open(in, out, &venc_path_id); + if (ret != HD_OK ){ + DBG_ERR("hd_videoenc_open(%lx, %lx) failed(%d)!\r\n", in, out, ret); + goto EXIT; + } if (ret != HD_OK ){ DBG_ERR("hd_videoenc_open(%lx, %lx) failed(%d)!\r\n", in, out, ret); @@ -4349,7 +4359,7 @@ EXIT: static INT32 PhotoExe_Preview_SliceEncode_Close(void) { - HD_RESULT ret; + HD_RESULT ret = HD_OK; HD_PATH_ID path_id = 0; for(int i=0 ; iheight = video_frame.dim.h; if(src_info->slice_num > 1){ - src_info->slice_height = ALIGN_CEIL((src_info->width * dst_info->slice_height) / dst_info->width, 2); + src_info->slice_height = ALIGN_CEIL((src_info->height) / src_info->slice_num, 2); src_info->last_slice_height = ALIGN_CEIL(src_info->height - src_info->slice_height * (src_info->slice_num - 1), 2); } else{ @@ -4393,6 +4403,14 @@ static void PhotoExe_Preview_SliceEncode_Get_Src_Slice_Info( src_info->last_slice_height = src_info->slice_height; } + if(src_info->slice_height * (src_info->slice_num - 1) >= src_info->height){ + DBG_ERR("aligned total slice height(%lu * %lu + %lu = %lu) exceed photo height(%lu)!\n", + src_info->slice_height, + src_info->slice_num - 1, + src_info->last_slice_height, + src_info->height); + } + PHOTO_SLICE_ENC_DUMP("Src Slice Info: size = {%lu,%lu} slice num = {%lu} slice height = {%lu} last slice height = {%lu}\r\n", src_info->width, src_info->height, src_info->slice_num, src_info->slice_height, src_info->last_slice_height); } @@ -4409,11 +4427,17 @@ static INT32 PhotoExe_Preview_SliceEncode_Get_Dst_Slice_Info(PhotoExe_SliceSize_ info->width = cap_size_w; info->height = cap_size_h; info->slice_num = slice_num; + + if(info->height == 1080 && slice_num == 1){ + info->slice_height = info->height; + } + else{ info->slice_height = ALIGN_CEIL_16(info->height / info->slice_num); + } if(info->slice_height * (info->slice_num - 1) > info->height){ - DBG_ERR("calculate last slice height error! \n"); + DBG_ERR("calculate last slice height error! (slice height = %lu , slice num = %lu , photo height = %lu)\n", info->slice_height, info->slice_num, info->height); return E_SYS; } @@ -4425,23 +4449,52 @@ static INT32 PhotoExe_Preview_SliceEncode_Get_Dst_Slice_Info(PhotoExe_SliceSize_ return E_OK; } -static INT32 PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(PhotoExe_SliceSize_Info *info) +static INT32 PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(PhotoExe_SliceSize_Info *info, const HD_VIDEO_FRAME src_frame) { UINT32 cap_size_w = GetPhotoSizeWidth(SysGetFlag(FL_PHOTO_SIZE)); UINT32 cap_size_h = GetPhotoSizeHeight(SysGetFlag(FL_PHOTO_SIZE)); + UINT32 max_slice_num; UINT32 slice_num; unsigned int cap_size = cap_size_w * cap_size_h; unsigned int buf_size = CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_WIDTH * CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_HEIGHT; if(buf_size > cap_size){ + max_slice_num = 1; slice_num = 1; } else{ PHOTO_SLICE_ENC_DUMP("cap_size = %lu buf_size = %lu\n", cap_size, buf_size); UINT32 lines = (buf_size / cap_size_w); - slice_num = cap_size_h / lines + (cap_size_h % lines ? 1 : 0); + max_slice_num = cap_size_h / lines + (cap_size_h % lines ? 1 : 0); + + UINT32 tmp_src_h = src_frame.dim.h / 2; + UINT32 tmp_dst_h = cap_size_h / 16; + UINT32 found_common_factor = 0; + UINT32 i; + + for (i = 1; i <= (tmp_src_h > tmp_dst_h ? tmp_dst_h : tmp_src_h) ; ++i) + { + if (tmp_src_h % i == 0 && tmp_dst_h % i == 0) + { + PHOTO_SLICE_ENC_DUMP("common factor = %d\n", i); + + if(max_slice_num < i){ + found_common_factor = i; + break; + } + } + } + + if(found_common_factor){ + slice_num = found_common_factor; + PHOTO_SLICE_ENC_DUMP("use common factor %d\n ", slice_num); + } + else{ + slice_num = max_slice_num; + PHOTO_SLICE_ENC_DUMP("use max slice num %d\n ", slice_num); + } } return PhotoExe_Preview_SliceEncode_Get_Dst_Slice_Info(info, cap_size_w, cap_size_h, slice_num); @@ -4451,31 +4504,83 @@ static UINT32 PhotoExe_Preview_SliceEncode_Get_Max_Dst_Slice_Buffer_Size(HD_VIDE { HD_DIM dim = PhotoExe_Preview_SliceEncode_Get_Encode_Max_Size(); UINT32 reserved_buffer = 0; - UINT32 max_buffer_size = VDO_YUV_BUFSIZE(dim.w, dim.h, pxl_fmt) + reserved_buffer; + UINT32 max_buffer_size = VDO_YUV_BUFSIZE(ALIGN_CEIL(dim.w, 16), ALIGN_CEIL(dim.h, 16), pxl_fmt) + reserved_buffer; return max_buffer_size; } static INT32 PhotoExe_Preview_SliceEncode_Get_Max_Dst_Slice_Info(PhotoExe_SliceSize_Info *info) { - UINT32 cap_size_w = GetPhotoSizeWidth(PHOTO_MAX_CAP_SIZE); - UINT32 cap_size_h = GetPhotoSizeHeight(PHOTO_MAX_CAP_SIZE); + static PhotoExe_SliceSize_Info max_slice_info = {0}; + UINT32 max_slice_num; UINT32 slice_num; - - unsigned int cap_size = cap_size_w * cap_size_h; + INT32 ret = E_OK; + UIAPP_PHOTO_SENSOR_INFO *sensor_info = UIAppPhoto_get_SensorInfo(0); unsigned int buf_size = CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_WIDTH * CFG_JPG_PREVIEW_SLICE_ENC_PRIMARY_BUF_HEIGHT; - if(buf_size > cap_size){ + /* search max slice (slice height * slice width) */ + if(!max_slice_info.slice_height || !max_slice_info.width){ + + UINT8 cap_idx = 0; + + for(cap_idx = PHOTO_MAX_CAP_SIZE ; cap_idx <= PHOTO_MIN_CAP_SIZE ; cap_idx++) + { + HD_DIM tmp_cap_size = {0}; + PhotoExe_SliceSize_Info tmp_slice_info = {0}; + + tmp_cap_size = (HD_DIM){GetPhotoSizeWidth(cap_idx), GetPhotoSizeHeight(cap_idx)}; + + if(buf_size > (tmp_cap_size.w * tmp_cap_size.h)){ + max_slice_num = 1; slice_num = 1; } else{ - PHOTO_SLICE_ENC_DUMP("cap_size = %lu buf_size = %lu\n", cap_size, buf_size); + PHOTO_SLICE_ENC_DUMP("cap_size = %lu buf_size = %lu\n", tmp_cap_size.w * tmp_cap_size.h, buf_size); - UINT32 lines = (buf_size / cap_size_w); - slice_num = cap_size_h / lines + (cap_size_h % lines ? 1 : 0); + UINT32 lines = (buf_size / tmp_cap_size.w); + max_slice_num = tmp_cap_size.h / lines + (tmp_cap_size.h % lines ? 1 : 0); + + UINT32 tmp_src_h = sensor_info->sSize.h / 2; + UINT32 tmp_dst_h = tmp_cap_size.h / 16; + UINT32 found_common_factor = 0; + UINT32 i; + + for (i = 1; i <= (tmp_src_h > tmp_dst_h ? tmp_dst_h : tmp_src_h) ; ++i) + { + if (tmp_src_h % i == 0 && tmp_dst_h % i == 0) + { + PHOTO_SLICE_ENC_DUMP("common factor = %d\n", i); + + if(max_slice_num < i){ + found_common_factor = i; + break; + } + } + } + + if(found_common_factor){ + slice_num = found_common_factor; + PHOTO_SLICE_ENC_DUMP("use common factor %d\n ", slice_num); + } + else{ + slice_num = max_slice_num; + PHOTO_SLICE_ENC_DUMP("use max slice num %d\n ", slice_num); + } + } + + ret = PhotoExe_Preview_SliceEncode_Get_Dst_Slice_Info(&tmp_slice_info, tmp_cap_size.w, tmp_cap_size.h, slice_num); + + if((tmp_slice_info.slice_height * tmp_slice_info.width) > (max_slice_info.slice_height * max_slice_info.width)){ + max_slice_info = tmp_slice_info; + } + } + + PHOTO_SLICE_ENC_DUMP("max dst slice = {%lu, %lu}, cap idx = %lu\n", max_slice_info.width, max_slice_info.slice_height, cap_idx); } - return PhotoExe_Preview_SliceEncode_Get_Dst_Slice_Info(info, cap_size_w, cap_size_h, slice_num); + *info = max_slice_info; + + return ret; } static HD_DIM PhotoExe_Preview_SliceEncode_Get_Encode_Max_Size() @@ -4492,7 +4597,7 @@ static HD_DIM PhotoExe_Preview_SliceEncode_Get_Encode_Max_Size() static UINT32 PhotoExe_Preview_SliceEncode_Get_Encode_Max_Bitrate(HD_VIDEO_PXLFMT vproc_out_pxlfmt) { - const UINT32 ratio = JPG_COMERESSED_RATIO_5; + const UINT32 ratio = CFG_JPG_PREVIEW_SLICE_ENC_BS_BUF_RATIO; UINT32 bitrate; HD_DIM dim = PhotoExe_Preview_SliceEncode_Get_Encode_Max_Size(); @@ -4798,7 +4903,9 @@ static INT32 PhotoExe_Preview_SliceEncode_Init_VF_GFX_Slice( addr_dst[0], addr_dst[1] ); - if(slice_idx == (dst_slice_info.slice_num - 1)){ + if(slice_idx == (dst_slice_info.slice_num - 1) && + dst_scale_slice_height < dst_slice_info.last_slice_height + ){ HD_GFX_DRAW_RECT draw_rect = {0}; @@ -4816,6 +4923,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Init_VF_GFX_Slice( hd_gfx_draw_rect(&draw_rect); } + return E_OK; } @@ -4849,8 +4957,52 @@ static INT32 PhotoExe_Preview_SliceEncode_Dump_Frame(const HD_VIDEO_FRAME video_ #endif -#if PHOTO_SLICE_ENC_DBG_SLICE_YUV -static INT32 PhotoExe_Preview_SliceEncode_Dump_Slice( +#if PHOTO_SLICE_ENC_DBG_SRC_SLICE_YUV +static INT32 PhotoExe_Preview_SliceEncode_Dump_Src_Slice( + const HD_VIDEO_FRAME* video_frame, + const PhotoExe_SliceSize_Info src_slice_info, + const UINT8 slice_idx, + const UINT32 pa_y, + const UINT32 pa_uv +) +{ + char fileName[128] = {0}; + UINT32 src_slice_height = (slice_idx == (src_slice_info.slice_num - 1)) ? src_slice_info.last_slice_height : src_slice_info.slice_height; + UINT32 va; + UINT32 size; + FST_FILE fp = NULL; + + size = VDO_YUV_BUFSIZE(src_slice_info.width, src_slice_height, video_frame->pxlfmt); + + va = (UINT32)hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, pa_y, size); + if (va == 0) { + DBG_ERR("hd_common_mem_mmap error!r\n"); + return E_SYS; + } + + sprintf(fileName, "A:\\src_slice%u_%lux%lu_fmt%lx.dat", slice_idx, src_slice_info.width, src_slice_height, video_frame->pxlfmt); + + fp = FileSys_OpenFile(fileName, FST_CREATE_ALWAYS | FST_OPEN_WRITE); + + size = src_slice_info.width * src_slice_height; + FileSys_WriteFile(fp, (UINT8*)va, &size, 0, NULL); + + size = (src_slice_info.width * src_slice_height) / 2; + FileSys_WriteFile(fp, (UINT8*)va + (pa_uv - pa_y), &size, 0, NULL); + + FileSys_FlushFile(fp); + FileSys_CloseFile(fp); + + hd_common_mem_munmap((void*) va, size); + + return E_OK; +} + +#endif + +#if PHOTO_SLICE_ENC_DBG_DST_SLICE_YUV + +static INT32 PhotoExe_Preview_SliceEncode_Dump_Dst_Slice( const HD_VIDEO_FRAME* video_frame, const PhotoExe_SliceSize_Info dst_slice_info, const UINT8 slice_idx, @@ -4870,7 +5022,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Dump_Slice( return E_SYS; } - sprintf(fileName, "A:\\slice%u_%lux%lu_fmt%lx.dat", slice_idx, dst_slice_info.width, dst_slice_height, video_frame->pxlfmt); + sprintf(fileName, "A:\\dst_slice%u_%lux%lu_fmt%lx.dat", slice_idx, dst_slice_info.width, dst_slice_height, video_frame->pxlfmt); fp = FileSys_OpenFile(fileName, FST_CREATE_ALWAYS | FST_OPEN_WRITE); FileSys_WriteFile(fp, (UINT8*)va, &size, 0, NULL); @@ -4881,6 +5033,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Dump_Slice( return E_OK; } + #endif @@ -5129,7 +5282,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Scale_Screennail( } #if CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL -static INT32 PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(HD_VIDEO_FRAME* video_frame_in) +static INT32 PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(HD_VIDEO_FRAME* video_frame_in, UINT8* screennail_quality) { static UINT32 quality = CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL; INT8 direction = 0; @@ -5211,6 +5364,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(HD_VIDEO_FRAME* v } while(1); + ret = E_OK; EXIT: return ret; @@ -5281,7 +5435,7 @@ EXIT: DBG_ERR("hd_videoenc_stop failed(%d)\r\n", ret); } - return (ret == HD_OK) ? E_OK : E_SYS; + return (ret == HD_OK) ? E_OK : ret; } @@ -5314,11 +5468,78 @@ static INT32 PhotoExe_Preview_SliceEncode_DateStamp( return E_OK; } +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == ENABLE +static INT32 PhotoExe_Preview_SliceEncode_Src_DateStamp( + const HD_VIDEO_FRAME* video_frame, + const PhotoExe_SliceSize_Info* src_slice_info, + const PhotoExe_SliceSize_Info* dst_slice_info) +{ + + HD_VIDEO_FRAME video_frame_src_stamp = *video_frame; + UINT32 dst_last_slice_scale_height = (src_slice_info->last_slice_height * dst_slice_info->slice_height) / src_slice_info->slice_height; + + if(dst_last_slice_scale_height > dst_slice_info->last_slice_height) + { + video_frame_src_stamp.dim.h = video_frame_src_stamp.dim.h - ((src_slice_info->last_slice_height * (dst_last_slice_scale_height - dst_slice_info->last_slice_height)) / dst_last_slice_scale_height); + video_frame_src_stamp.ph[0] = video_frame_src_stamp.dim.h; + video_frame_src_stamp.ph[1] = video_frame_src_stamp.dim.h; + } + + return PhotoExe_Preview_SliceEncode_DateStamp(&video_frame_src_stamp, CAP_DS_EVENT_PRI); +} +#endif + +static INT32 PhotoExe_Preview_SliceEncode_QView(HD_VIDEO_FRAME* video_frame) +{ + HD_PATH_ID vout_path = 0; + IMG_CAP_YCC_IMG_INFO QvImgInfo = {0}; + IMG_CAP_QV_DATA QVInfor = {0}; + UINT8 retry_timeout = 10 , cnt = 0; + HD_RESULT ret; + + QvImgInfo.ch[IMG_CAP_YUV_Y].width = video_frame->pw[IMG_CAP_YUV_Y]; + QvImgInfo.ch[IMG_CAP_YUV_Y].height = video_frame->ph[IMG_CAP_YUV_Y]; + QvImgInfo.ch[IMG_CAP_YUV_Y].line_ofs = video_frame->loff[IMG_CAP_YUV_Y]; + QvImgInfo.ch[IMG_CAP_YUV_U].width = video_frame->pw[IMG_CAP_YUV_U]; + QvImgInfo.ch[IMG_CAP_YUV_U].height = video_frame->ph[IMG_CAP_YUV_U]; + QvImgInfo.ch[IMG_CAP_YUV_U].line_ofs = video_frame->loff[IMG_CAP_YUV_U]; + QvImgInfo.ch[IMG_CAP_YUV_V].width = video_frame->pw[IMG_CAP_YUV_V]; + QvImgInfo.ch[IMG_CAP_YUV_V].height = video_frame->ph[IMG_CAP_YUV_V]; + QvImgInfo.pixel_addr[0] = video_frame->phy_addr[0]; + QvImgInfo.pixel_addr[1] = video_frame->phy_addr[1]; + QvImgInfo.pixel_addr[2] = video_frame->phy_addr[2]; + QVInfor.ImgInfo = QvImgInfo; + + if(PhotoCapMsgCb){ + PhotoCapMsgCb(IMG_CAP_CBMSG_QUICKVIEW, &QVInfor); + } + + vout_path = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); + + do{ + if ((ret = hd_videoout_push_in_buf(vout_path, video_frame, NULL, -1)) != HD_OK) { + DBG_WRN("QV push_in error(%d), retrying ...\n", ret); + vos_util_delay_ms(1); + continue; + } + + break; + } while(cnt++ < retry_timeout); + + if(ret != HD_OK){ + DBG_ERR("QV push_in error(%d)\n", ret); + return E_SYS; + } + + return E_OK; +} + static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( const HD_VIDEO_FRAME* video_frame, const PhotoExe_SliceSize_Info src_slice_info, const PhotoExe_SliceSize_Info dst_slice_info, - UINT32* enc_bs_accum_size + UINT32* enc_bs_accum_size, + UINT8* primary_quality ) { PhotoExe_SliceEncode_Info* slice_enc_info = PhotoExe_Preview_SliceEncode_Get_Info(PHOTO_ENC_JPG_PRIMARY); @@ -5330,9 +5551,11 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( UINT32 enc_jpg_va = 0; UINT32 enc_bs_buf_ptr = 0; BOOL restart = FALSE; - const UINT8 slice_idx_of_date_stamp = dst_slice_info.slice_num - 1; - HD_VIDEOENC_BS bs_data_pull; + HD_VIDEOENC_BS bs_data_pull; +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == DISABLE + const UINT8 slice_idx_of_date_stamp = dst_slice_info.slice_num - 1; +#endif do { restart = FALSE; @@ -5366,6 +5589,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( slice_idx); if((ret = vf_gfx_scale(&vf_gfx_scale_param, 1)) != HD_OK){ + DBG_ERR("vf_gfx_scale failed!\n"); goto EXIT; } @@ -5374,6 +5598,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( } /* attach the date stamp to a slice */ +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == DISABLE if(slice_idx == slice_idx_of_date_stamp){ SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_PRI_STAMP_S); @@ -5392,6 +5617,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_PRI_STAMP_E); } +#endif vf_gfx_scale_param.dst_img.count = 0; vf_gfx_scale_param.dst_img.timestamp = hd_gettime_us(); @@ -5405,11 +5631,21 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( vf_gfx_scale_param.dst_img.reserved[2] = 0; } - /* src img */ +#if PHOTO_SLICE_ENC_DBG_SRC_SLICE_YUV -#if PHOTO_SLICE_ENC_DBG_SLICE_YUV + PhotoExe_Preview_SliceEncode_Dump_Src_Slice( + video_frame, + src_slice_info, + slice_idx, + vf_gfx_scale_param.src_img.phy_addr[0], + vf_gfx_scale_param.src_img.phy_addr[1] + ); - PhotoExe_Preview_SliceEncode_Dump_Slice( +#endif + +#if PHOTO_SLICE_ENC_DBG_DST_SLICE_YUV + + PhotoExe_Preview_SliceEncode_Dump_Dst_Slice( video_frame, dst_slice_info, slice_idx, @@ -5498,6 +5734,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( /* check restart */ if(restart == FALSE){ + CHKPNT; ret = HD_ERR_SYS; goto EXIT; } @@ -5509,6 +5746,7 @@ static INT32 PhotoExe_Preview_SliceEncode_Encode_Primary( goto EXIT; } + *primary_quality = quality_new; if((ret = PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_enc_info->enc_path_id, quality_new) != HD_OK)) goto EXIT; @@ -5629,7 +5867,11 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par HD_VIDEOPROC_OUT vproc_out = {0}; HD_VIDEO_PXLFMT vproc_out_pxlfmt = 0; PhotoExe_MEM_Info exif_mem_info = {0}; + BOOL last_shot = TRUE; UINT32 enc_accum_size = 0; + static UINT8 primary_quality = CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_PRIMARY; + static UINT8 screennail_quality = CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL; + #if HUNTING_CAMERA_MCU == ENABLE UIMenuStoreInfo *puiPara = sf_ui_para_get(); #endif @@ -5641,7 +5883,11 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par vid_in = (PHOTO_VID_IN) paramArray[0]; /* sensor id */ } - DBG_DUMP("slice encode vid_in = %lu\r\n", vid_in); + if(paramNum >= 2){ + last_shot = (BOOL) paramArray[1]; /* for cont shot */ + } + + DBG_DUMP("slice encode vid_in = %lu last_shot = %lu\r\n", vid_in, last_shot); /******************************************************************* * Get vproc info @@ -5659,13 +5905,6 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par vproc_out_pxlfmt = vproc_out.pxlfmt; - /******************************************************************* - * Calculate dst slice info - ******************************************************************/ - if(PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(&dst_slice_info) != E_OK){ - return NVTEVT_CONSUME; - } - /******************************************************************* * Pull out preview video frame, size should equal to sensor size ******************************************************************/ @@ -5675,11 +5914,17 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par goto EXIT; } -#if PHOTO_SLICE_ENC_DBG_PRIMARY_YUV +/******************************************************************* + * Calculate dst slice info + ******************************************************************/ + if(PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(&dst_slice_info, video_frame) != E_OK){ + return NVTEVT_CONSUME; + } - PhotoExe_Preview_SliceEncode_Dump_Frame(video_frame); - -#endif + /******************************************************************* + * Calculate src slice info + ******************************************************************/ + PhotoExe_Preview_SliceEncode_Get_Src_Slice_Info(&dst_slice_info, &src_slice_info, video_frame); /******************************************************************* * Init Date Buffer @@ -5688,10 +5933,20 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par Ux_SendEvent(&CustomPhotoObjCtrl, NVTEVT_EXE_INIT_DATE_BUF, 0); } +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == ENABLE /******************************************************************* - * Calculate src slice info + * Stamp on the src frame ******************************************************************/ - PhotoExe_Preview_SliceEncode_Get_Src_Slice_Info(&dst_slice_info, &src_slice_info, video_frame); + if(PhotoExe_Preview_SliceEncode_Src_DateStamp(&video_frame, &src_slice_info, &dst_slice_info) != E_OK){ + goto EXIT; + } +#endif + +#if PHOTO_SLICE_ENC_DBG_PRIMARY_YUV + + PhotoExe_Preview_SliceEncode_Dump_Frame(video_frame); + +#endif /******************************************************************* * Allocate slice buffer @@ -5746,12 +6001,23 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par /* screennail date stamp */ SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_THUMB_STAMP_S); +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == DISABLE if(PhotoExe_Preview_SliceEncode_DateStamp(&video_frame_out_screennail, CAP_DS_EVENT_SCR) != E_OK){ goto EXIT; } +#endif SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_THUMB_STAMP_E); + /******************************************************************* + * Quick View (screennail) + ******************************************************************/ + SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_QVIEW_S); + + PhotoExe_Preview_SliceEncode_QView(&video_frame_out_screennail); + + SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_QVIEW_E); + /******************************************************************* * Primary ******************************************************************/ @@ -5760,9 +6026,9 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par SLICE_ENC_VOS_TICK_TRIG(SLICE_ENC_VOS_TICK_PRI_ENC_S); PhotoExe_Preview_SliceEncode_Encode_Set_In(slice_encode_primary_info->enc_path_id, vproc_out_pxlfmt, (HD_DIM) {dst_slice_info.width, dst_slice_info.height}); - PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_primary_info->enc_path_id, CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_PRIMARY); + PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_primary_info->enc_path_id, primary_quality); - if(PhotoExe_Preview_SliceEncode_Encode_Primary(&video_frame, src_slice_info, dst_slice_info, &enc_accum_size) != E_OK){ + if(PhotoExe_Preview_SliceEncode_Encode_Primary(&video_frame, src_slice_info, dst_slice_info, &enc_accum_size, &primary_quality) != E_OK){ goto EXIT; } @@ -5794,11 +6060,12 @@ INT32 PhotoExe_Preview_SliceEncode(VControl *pCtrl, UINT32 paramNum, UINT32 *par #endif #if CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL - if(PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(&video_frame_out_screennail) != E_OK){ + if(PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(&video_frame_out_screennail, &screennail_quality) != E_OK){ goto EXIT; } #else PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_screennail_info->enc_path_id, CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL); + if(PhotoExe_Preview_SliceEncode_Encode_Screennail(&video_frame_out_screennail) != E_OK){ goto EXIT; } @@ -5936,7 +6203,7 @@ EXIT: } } - if(PhotoCapMsgCb){ + if(PhotoCapMsgCb && (last_shot == TRUE)){ PhotoCapMsgCb(IMG_CAP_CBMSG_RET_PRV, NULL); PhotoCapMsgCb(IMG_CAP_CBMSG_CAPEND, NULL); } @@ -6067,7 +6334,7 @@ INT32 PhotoExe_Preview_SliceEncode_CB1(void* user_data) PHOTO_VID_IN vid_in = PHOTO_VID_IN_1; HD_PATH_ID vproc_path_id; PhotoExe_Preview_SliceEncode_Queue12_Param* queue_ele_out = NULL; - VOS_TICK tick1; + VOS_TICK tick = 0; UINT32 err_cnt = 0, err_timeout = 30; if(!user_data){ @@ -6104,9 +6371,9 @@ INT32 PhotoExe_Preview_SliceEncode_CB1(void* user_data) } } - vos_perf_mark(&tick1); + vos_perf_mark(&tick); - DBG_DUMP("frame%lu : %lu ms\n", param->cnt, tick1 / 1000); + DBG_DUMP("pic%lu = %lu\n", param->cnt, tick); queue_ele_out = (PhotoExe_Preview_SliceEncode_Queue12_Param*) malloc(sizeof(PhotoExe_Preview_SliceEncode_Queue12_Param)); memset(queue_ele_out, 0, sizeof(PhotoExe_Preview_SliceEncode_Queue12_Param)); @@ -6123,7 +6390,7 @@ INT32 PhotoExe_Preview_SliceEncode_CB1(void* user_data) } while(1); - DBG_IND("task1 job finished\n"); + DBG_DUMP("task1 job finished\n"); exit: return ret; @@ -6148,7 +6415,8 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) HD_VIDEO_PXLFMT vproc_out_pxlfmt = 0; PhotoExe_MEM_Info exif_mem_info = {0}; UINT32 enc_accum_size = 0; - PHOTO_CAP_CBMSG_FP PhotoCapMsgCb = (PHOTO_CAP_CBMSG_FP)Photo_CaptureCB; + static UINT8 primary_quality = CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_PRIMARY; + static UINT8 screennail_quality = CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL; if(!user_data){ DBG_ERR("user_data can't be null!\n"); @@ -6159,8 +6427,6 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) param = (PhotoExe_Preview_SliceEncode_CB2_Param*) user_data; param->cnt = 0; - DBG_IND("enter cb2 loop\n"); - /******************************************************************* * Get vproc info ******************************************************************/ @@ -6177,13 +6443,6 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) vproc_out_pxlfmt = vproc_out.pxlfmt; - /******************************************************************* - * Calculate dst slice info - ******************************************************************/ - if(PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(&dst_slice_info) != E_OK){ - return NVTEVT_CONSUME; - } - /* pull out vprc frame is in the CB1 */ /******************************************************************* @@ -6198,6 +6457,7 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) ******************************************************************/ slice_encode_thumbnail_info->bs_buf_mem_info.blk_size = (CFG_THUMBNAIL_W * CFG_THUMBNAIL_H) / 2; if(PhotoExe_Preview_SliceEncode_Alloc_Buffer(&slice_encode_thumbnail_info->bs_buf_mem_info, "slice_enc_thumbnail") != E_OK){ + CHKPNT; goto EXIT; } @@ -6207,8 +6467,11 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) // } exif_mem_info.blk_size = CFG_JPG_HEADER_SIZE; - if(PhotoExe_Preview_SliceEncode_Alloc_Buffer(&exif_mem_info, "slice_enc_exif") != E_OK) + if(PhotoExe_Preview_SliceEncode_Alloc_Buffer(&exif_mem_info, "slice_enc_exif") != E_OK){ + CHKPNT; goto EXIT; + } + do{ @@ -6219,24 +6482,41 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) } if(queue_ele_in->comm.terminate){ - DBG_ERR("force terminate\n"); + DBG_ERR("abort CB2\n"); free(queue_ele_in); queue_ele_in = NULL; goto EXIT; } - DBG_IND("process frame %lu\n", param->cnt); + /******************************************************************* + * Calculate dst slice info + ******************************************************************/ + if(PhotoExe_Preview_SliceEncode_Get_Curr_Dst_Slice_Info(&dst_slice_info, queue_ele_in->frame) != E_OK){ + CHKPNT; + goto EXIT; + } /******************************************************************* * Calculate src slice info ******************************************************************/ PhotoExe_Preview_SliceEncode_Get_Src_Slice_Info(&dst_slice_info, &src_slice_info, queue_ele_in->frame); - slice_encode_primary_info->bs_buf_mem_info.blk_size = (VDO_YUV_BUFSIZE(dst_slice_info.width, dst_slice_info.height, queue_ele_in->frame.pxlfmt) / (CFG_JPG_PREVIEW_SLICE_ENC_BS_BUF_RATIO)) + CFG_JPG_HEADER_SIZE + PhotoExe_GetScreenNailSize() ; -// if(PhotoExe_Preview_SliceEncode_Alloc_Buffer(&slice_encode_primary_info->bs_buf_mem_info, "slice_enc_primary") != E_OK){ -// goto EXIT; -// } +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == ENABLE + /******************************************************************* + * Stamp on the src frame + ******************************************************************/ + if(PhotoExe_Preview_SliceEncode_Src_DateStamp(&queue_ele_in->frame, &src_slice_info, &dst_slice_info) != E_OK){ + goto EXIT; + } +#endif +#if PHOTO_SLICE_ENC_DBG_PRIMARY_YUV + + PhotoExe_Preview_SliceEncode_Dump_Frame(queue_ele_in->frame); + +#endif + + slice_encode_primary_info->bs_buf_mem_info.blk_size = (VDO_YUV_BUFSIZE(dst_slice_info.width, dst_slice_info.height, queue_ele_in->frame.pxlfmt) / (CFG_JPG_PREVIEW_SLICE_ENC_BS_BUF_RATIO)) + CFG_JPG_HEADER_SIZE + PhotoExe_GetScreenNailSize() ; if(PhotoExe_Preview_SliceEncode_Alloc_Buffer_Retry( &slice_encode_primary_info->bs_buf_mem_info, "slice_enc_primary", @@ -6247,10 +6527,6 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) } slice_encode_screennail_info->bs_buf_mem_info.blk_size = PhotoExe_GetScreenNailSize(); -// if(PhotoExe_Preview_SliceEncode_Alloc_Buffer(&slice_encode_screennail_info->bs_buf_mem_info, "slice_enc_screennail") != E_OK){ -// goto EXIT; -// } - if(PhotoExe_Preview_SliceEncode_Alloc_Buffer_Retry( &slice_encode_screennail_info->bs_buf_mem_info, "slice_enc_screennail", @@ -6274,25 +6550,27 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) goto EXIT; } +#if PHOTO_PREVIEW_SLICE_ENC_SRC_STAMP == DISABLE /* screennail date stamp */ if(PhotoExe_Preview_SliceEncode_DateStamp(&video_frame_out_screennail, CAP_DS_EVENT_SCR) != E_OK){ goto EXIT; } /* thumbnail date stamp */ - if(PhotoExe_Preview_SliceEncode_DateStamp(&video_frame_out_thumbnail, CAP_DS_EVENT_QV) != E_OK){ - goto EXIT; - } - + // if(PhotoExe_Preview_SliceEncode_DateStamp(&video_frame_out_thumbnail, CAP_DS_EVENT_QV) != E_OK){ + // goto EXIT; + // } +#endif /******************************************************************* * Primary ******************************************************************/ /* slice encode */ PhotoExe_Preview_SliceEncode_Encode_Set_In(slice_encode_primary_info->enc_path_id, vproc_out_pxlfmt, (HD_DIM) {dst_slice_info.width, dst_slice_info.height}); - PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_primary_info->enc_path_id, CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_PRIMARY); + PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_primary_info->enc_path_id, primary_quality); - if(PhotoExe_Preview_SliceEncode_Encode_Primary(&queue_ele_in->frame, src_slice_info, dst_slice_info, &enc_accum_size) != E_OK){ + if(PhotoExe_Preview_SliceEncode_Encode_Primary(&queue_ele_in->frame, src_slice_info, dst_slice_info, &enc_accum_size, &primary_quality) != E_OK){ + CHKPNT; goto EXIT; } @@ -6313,12 +6591,15 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) #if CFG_JPG_PREVIEW_SLICE_ENC_RC_SCREENNAIL - if(PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(&video_frame_out_screennail) != E_OK){ + if(PhotoExe_Preview_SliceEncode_Encode_Screennail_RC(&video_frame_out_screennail, &screennail_quality) != E_OK){ + CHKPNT; goto EXIT; } #else PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_screennail_info->enc_path_id, CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_SCREENNAIL); + if(PhotoExe_Preview_SliceEncode_Encode_Screennail(&video_frame_out_screennail) != E_OK){ + CHKPNT; goto EXIT; } #endif @@ -6328,17 +6609,13 @@ INT32 PhotoExe_Preview_SliceEncode_CB2(void* user_data) PhotoExe_Preview_SliceEncode_Encode_Set_Out(slice_encode_thumbnail_info->enc_path_id, CFG_JPG_PREVIEW_SLICE_ENC_INIT_QUALITY_THUMBNAIL); if(PhotoExe_Preview_SliceEncode_Encode_Thumbnail(&video_frame_out_thumbnail) != E_OK){ + CHKPNT; goto EXIT; } /******************************************************************* * Combine All Images ******************************************************************/ - -// exif_mem_info.blk_size = CFG_JPG_HEADER_SIZE; -// if(PhotoExe_Preview_SliceEncode_Alloc_Buffer(&exif_mem_info, "slice_enc_exif") != E_OK) -// goto EXIT; - MEM_RANGE exif_data = {.addr = exif_mem_info.va, .size = exif_mem_info.blk_size}; MEM_RANGE thumb_jpg = {.addr = slice_encode_thumbnail_info->bs_buf_mem_info.va, .size = slice_encode_thumbnail_info->bs_buf_mem_info.used_size}; MEM_RANGE pri_jpg = {.addr = slice_encode_primary_info->bs_buf_mem_info.va + CFG_JPG_HEADER_SIZE, .size = slice_encode_primary_info->bs_buf_mem_info.used_size}; @@ -6420,11 +6697,12 @@ EXIT: if(param->cnt < param->max_cnt){ queue_ele_out = (PhotoExe_Preview_SliceEncode_Queue23_Param*) malloc(sizeof(PhotoExe_Preview_SliceEncode_Queue23_Param)); + memset(queue_ele_out, 0, sizeof(PhotoExe_Preview_SliceEncode_Queue23_Param)); queue_ele_out->comm.terminate = 1; lfqueue_enq(param->queue23, (void*) queue_ele_out); } - DBG_IND("task2 job finished\n"); + DBG_DUMP("task2 job finished\n"); return ret; } @@ -6434,8 +6712,7 @@ INT32 PhotoExe_Preview_SliceEncode_CB3(void* user_data) INT32 ret = E_OK; PhotoExe_Preview_SliceEncode_CB3_Param* param = NULL; PhotoExe_Preview_SliceEncode_Queue23_Param* queue_ele_in = NULL; - PHOTO_CAP_CBMSG_FP PhotoCapMsgCb = (PHOTO_CAP_CBMSG_FP)Photo_CaptureCB; - + if(!user_data){ DBG_ERR("user_data can't be null!\n"); ret = E_SYS; @@ -6453,8 +6730,10 @@ INT32 PhotoExe_Preview_SliceEncode_CB3(void* user_data) continue; } + DBG_DUMP("CB3 deq cnt = %lu , termi = %lu\n", param->cnt, queue_ele_in->comm.terminate); + if(queue_ele_in->comm.terminate){ - DBG_ERR("force terminate\n"); + DBG_ERR("abort CB3\n"); free(queue_ele_in); queue_ele_in = NULL; goto EXIT; @@ -6551,13 +6830,7 @@ EXIT: PhotoCapMsgCb(IMG_CAP_CBMSG_CAPEND, NULL); } - PhotoExe_Preview_SliceEncode2_Close(); - - if(param->cnt < param->max_cnt){ - DBG_ERR("force terminate\n"); - } - - DBG_IND("task3 job finished\n"); + DBG_DUMP("task3 job finished\n"); return ret; } @@ -6614,23 +6887,45 @@ static VOID PhotoExe_Preview_SliceEncode2_Close(VOID) FLGPTN flag = 0; /* stop cmd */ - set_flg(task1_param.flag_id, FLG_PHOTO_SLICE_ENC_CMD_STOP); - set_flg(task2_param.flag_id, FLG_PHOTO_SLICE_ENC_CMD_STOP); - set_flg(task3_param.flag_id, FLG_PHOTO_SLICE_ENC_CMD_STOP); + if(task1_param.flag_id) + set_flg(task1_param.flag_id, FLG_PHOTO_SLICE_ENC_CMD_STOP); + + if(task2_param.flag_id) + set_flg(task2_param.flag_id, FLG_PHOTO_SLICE_ENC_CMD_STOP); + + if(task3_param.flag_id) + set_flg(task3_param.flag_id, FLG_PHOTO_SLICE_ENC_CMD_STOP); /* check stopped */ - wai_flg(&flag, task1_param.flag_id, FLG_PHOTO_SLICE_ENC_STA_STOPPED, TWF_ORW); - wai_flg(&flag, task2_param.flag_id, FLG_PHOTO_SLICE_ENC_STA_STOPPED, TWF_ORW); - wai_flg(&flag, task3_param.flag_id, FLG_PHOTO_SLICE_ENC_STA_STOPPED, TWF_ORW); + if(task1_param.flag_id) + wai_flg(&flag, task1_param.flag_id, FLG_PHOTO_SLICE_ENC_STA_STOPPED, TWF_ORW); + + if(task2_param.flag_id) + wai_flg(&flag, task2_param.flag_id, FLG_PHOTO_SLICE_ENC_STA_STOPPED, TWF_ORW); + + if(task3_param.flag_id) + wai_flg(&flag, task3_param.flag_id, FLG_PHOTO_SLICE_ENC_STA_STOPPED, TWF_ORW); DBG_DUMP("slice encode finished\n"); - lfqueue_destroy(&queue12); - lfqueue_destroy(&queue23); + if(queue12.head){ + lfqueue_destroy(&queue12); + memset(&queue12, 0, sizeof(queue12)); + } - PhotoExe_Preview_SliceEncode_Uninit_Flag(&task1_param.flag_id); - PhotoExe_Preview_SliceEncode_Uninit_Flag(&task2_param.flag_id); - PhotoExe_Preview_SliceEncode_Uninit_Flag(&task3_param.flag_id); + if(queue23.head){ + lfqueue_destroy(&queue23); + memset(&queue23, 0, sizeof(queue23)); + } + + if(task1_param.flag_id) + PhotoExe_Preview_SliceEncode_Uninit_Flag(&task1_param.flag_id); + + if(task2_param.flag_id) + PhotoExe_Preview_SliceEncode_Uninit_Flag(&task2_param.flag_id); + + if(task3_param.flag_id) + PhotoExe_Preview_SliceEncode_Uninit_Flag(&task3_param.flag_id); } INT32 PhotoExe_Preview_SliceEncode2(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) @@ -6641,6 +6936,9 @@ INT32 PhotoExe_Preview_SliceEncode2(VControl *pCtrl, UINT32 paramNum, UINT32 *pa INT32 ret = E_OK; FLGPTN flag = 0; + /* make sure last execution is finished */ + PhotoExe_Preview_SliceEncode2_Close(); + if(lfqueue_init(&queue12)){ DBG_ERR("init lfqueue12 failed\n"); goto EXIT; @@ -6698,10 +6996,8 @@ INT32 PhotoExe_Preview_SliceEncode2(VControl *pCtrl, UINT32 paramNum, UINT32 *pa cb1_param.max_cnt = max_cnt; cb1_param.cnt = 0; cb1_param.queue12 = &queue12; - cb1_param.period = 1000 / max_cnt; /* average ms in one second */ - DBG_IND("resume task1\n"); task1_param.run = 1; vos_task_resume(task1_param.task_id); @@ -6731,7 +7027,6 @@ INT32 PhotoExe_Preview_SliceEncode2(VControl *pCtrl, UINT32 paramNum, UINT32 *pa cb2_param.queue12 = &queue12; cb2_param.queue23 = &queue23; - DBG_IND("resume task2\n"); task2_param.run = 1; vos_task_resume(task2_param.task_id); @@ -6761,7 +7056,6 @@ INT32 PhotoExe_Preview_SliceEncode2(VControl *pCtrl, UINT32 paramNum, UINT32 *pa cb3_param.cnt = 0; cb3_param.queue23 = &queue23; - DBG_IND("resume task3\n"); task3_param.run = 1; vos_task_resume(task3_param.task_id); diff --git a/code/application/source/cardv/SrcCode/UIApp/Photo/UIDateImprint.c b/code/application/source/cardv/SrcCode/UIApp/Photo/UIDateImprint.c index 176567a13..6b11ba6c8 100755 --- a/code/application/source/cardv/SrcCode/UIApp/Photo/UIDateImprint.c +++ b/code/application/source/cardv/SrcCode/UIApp/Photo/UIDateImprint.c @@ -853,7 +853,7 @@ void UiDateImprint_ChkUpdateData(DATE_IMPRINT_INFO *pInfo) DBG_IND("event=%d, bScreenNailEn=%d, bGenEn=%d\r\n",pInfo->pCapInfo->event,bScreenNailEn,bGenEn); //if (pInfo->pCapInfo->event == CAP_DS_EVENT_QV || pInfo->pCapInfo->event == CAP_DS_EVENT_SCR) { - if (pInfo->pCapInfo->event == CAP_DS_EVENT_QV || bGenEn) { + if (pInfo->pCapInfo->event == CAP_DS_EVENT_PRI) { #if HUNTING_CAMERA_MCU == ENABLE pInfo->isStrDirty = UiDateImprint_UpdateDate(pInfo->StrBuf,sizeof(pInfo->StrBuf)); #else From d62d2d4525a9761b52fdee6d4cea3d2f15f908d2 Mon Sep 17 00:00:00 2001 From: payton Date: Thu, 2 Nov 2023 09:31:45 +0800 Subject: [PATCH 05/12] =?UTF-8?q?1.=E8=93=9D=E7=89=99=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code/source/sf_blue/src/hciconfig.c | 376 +- .../sf_app/code/source/sf_blue/src/hcitool.c | 3501 +++++++++++++++++ .../code/source/sf_blue/src/sf_blue_app.c | 81 +- .../code/source/sf_blue/src/sf_blue_app.h | 65 + .../code/source/sf_blue/src/sf_blue_hal.c | 81 +- .../code/source/sf_blue/src/sf_blue_hal.h | 1 + 6 files changed, 3928 insertions(+), 177 deletions(-) mode change 100755 => 100644 code/application/source/sf_app/code/source/sf_blue/src/hciconfig.c create mode 100644 code/application/source/sf_app/code/source/sf_blue/src/hcitool.c mode change 100755 => 100644 code/application/source/sf_app/code/source/sf_blue/src/sf_blue_app.c mode change 100755 => 100644 code/application/source/sf_app/code/source/sf_blue/src/sf_blue_app.h mode change 100755 => 100644 code/application/source/sf_app/code/source/sf_blue/src/sf_blue_hal.c mode change 100755 => 100644 code/application/source/sf_app/code/source/sf_blue/src/sf_blue_hal.h diff --git a/code/application/source/sf_app/code/source/sf_blue/src/hciconfig.c b/code/application/source/sf_app/code/source/sf_blue/src/hciconfig.c old mode 100755 new mode 100644 index 81ec406d8..977deaac9 --- a/code/application/source/sf_app/code/source/sf_blue/src/hciconfig.c +++ b/code/application/source/sf_app/code/source/sf_blue/src/hciconfig.c @@ -21,13 +21,59 @@ #include #include #include +#include #include "bluetooth.h" #include "hci.h" #include "hci_lib.h" +#include "src/util.h" -static struct hci_dev_info di; -static char g_sf_ble_ssid[14] = {0}; +static void cmd_lecc(int dev_id, char *addr) +{ + int err, dd; + bdaddr_t bdaddr; + uint16_t interval, latency, max_ce_length, max_interval, min_ce_length; + uint16_t min_interval, supervision_timeout, window, handle; + uint8_t initiator_filter, own_bdaddr_type, peer_bdaddr_type; + + own_bdaddr_type = LE_RANDOM_ADDRESS; + peer_bdaddr_type = LE_RANDOM_ADDRESS; + initiator_filter = 1; /* Use peer address */ + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + return ; + } + + memset(&bdaddr, 0, sizeof(bdaddr_t)); + if (addr) + str2ba(addr, &bdaddr); + + printf("Conn_Address: %02x %02x %02x %02x %02x %02x.\n", bdaddr.b[0], bdaddr.b[1], bdaddr.b[2], bdaddr.b[3], bdaddr.b[4], bdaddr.b[5]); + + interval = htobs(0x0004); + window = htobs(0x0004); + min_interval = htobs(0x000F); + max_interval = htobs(0x000F); + latency = htobs(0x0000); + supervision_timeout = htobs(0x0C80); + min_ce_length = htobs(0x0001); + max_ce_length = htobs(0x0001); + + err = hci_le_create_conn(dd, interval, window, initiator_filter, + peer_bdaddr_type, bdaddr, own_bdaddr_type, min_interval, + max_interval, latency, supervision_timeout, + min_ce_length, max_ce_length, &handle, 25000); + if (err < 0) { + perror("Could not create connection"); + return ; + } + + printf("Connection handle %d\n", handle); + + hci_close_dev(dd); +} static void cmd_up(int ctl, int hdev) { @@ -42,48 +88,19 @@ static void cmd_up(int ctl, int hdev) } } -static void cmd_piscan(int ctl, int hdev) +static void cmd_down(int ctl, int hdev) { - struct hci_dev_req dr; - - dr.dev_id = hdev; - dr.dev_opt = SCAN_DISABLED; - dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; - - if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) + /* Start HCI device */ + if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { - fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n", + if (errno == EALREADY) + return; + fprintf(stderr, "Can't init device hci%d: %s (%d)\n", hdev, strerror(errno), errno); return; } } -static void cmd_name(int ctl, int hdev, char *name) -{ - int dd; - - dd = hci_open_dev(hdev); - if (dd < 0) - { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - hdev, strerror(errno), errno); - return; - } - - char *opt = name; - if (hci_write_local_name(dd, opt, 2000) < 0) - { - fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", - hdev, strerror(errno), errno); - return; - } - printf("Name: '%s'\n", name); - hci_close_dev(dd); -} -static int sf_ba2str(const bdaddr_t *ba, char *str) -{ - return sprintf(str, "%2.2X%2.2X%2.2X",ba->b[2], ba->b[1], ba->b[0]); -} static void cmd_address(int ctl, int hdev, char *ssid) { int dd; @@ -96,115 +113,185 @@ static void cmd_address(int ctl, int hdev, char *ssid) return; } - hci_read_bd_addr(dd, &di.bdaddr, 1000); + bdaddr_t bdaddr = {0}; + if (hci_read_bd_addr(dd, &bdaddr, 0) < 0) + { + fprintf(stderr, "Get bd address on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + return; + } - sf_ba2str(&di.bdaddr, ssid); + if (NULL != ssid) + { + ssid[0] = bdaddr.b[5]; + ssid[1] = bdaddr.b[4]; + ssid[2] = bdaddr.b[3]; + ssid[3] = bdaddr.b[2]; + ssid[4] = bdaddr.b[1]; + ssid[5] = bdaddr.b[0]; - printf("BT Address: %s.\n", ssid); + printf("BT_Address: %02x,%02x,%02x,%02x,%02x,%02x.\n", ssid[0], ssid[1], ssid[2], ssid[3], ssid[4], ssid[5]); + } hci_close_dev(dd); } -static void cmd_le_adv(int ctl, int hdev) +static void set_random_address(int fd) { - struct hci_request rq; - le_set_advertise_enable_cp advertise_cp; - le_set_advertising_parameters_cp adv_params_cp; - uint8_t status; - int dd, ret; + le_set_random_address_cp cmd; - if (hdev < 0) - hdev = hci_get_route(NULL); + memset(&cmd, 0, sizeof(cmd)); - dd = hci_open_dev(hdev); - if (dd < 0) - { - perror("Could not open device"); - return; + int urandom_fd; + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) { + fprintf(stderr, "Failed to open /dev/urandom device\n"); + cmd.bdaddr.b[5] = 0xc0; + cmd.bdaddr.b[4] = 0x55; + cmd.bdaddr.b[3] = 0x44; + cmd.bdaddr.b[2] = 0x33; + cmd.bdaddr.b[1] = 0x22; + cmd.bdaddr.b[0] = 0x11; + + } else { + ssize_t len; + + len = read(urandom_fd, cmd.bdaddr.b, sizeof(cmd.bdaddr.b)); + if (len < 0 || len != sizeof(cmd.bdaddr.b)) { + fprintf(stderr, "Failed to read random data\n"); + return; + } + + cmd.bdaddr.b[5] &= 0x3f; + cmd.bdaddr.b[5] |= 0xc0; } - memset(&adv_params_cp, 0, sizeof(adv_params_cp)); - adv_params_cp.min_interval = htobs(0x0800); - adv_params_cp.max_interval = htobs(0x0800); - adv_params_cp.advtype = 0; //mt set - adv_params_cp.chan_map = 7; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_ADVERTISING_PARAMETERS; - rq.cparam = &adv_params_cp; - rq.clen = LE_SET_ADVERTISING_PARAMETERS_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - ret = hci_send_req(dd, &rq, 1000); - if (ret < 0) - goto done; - - memset(&advertise_cp, 0, sizeof(advertise_cp)); - advertise_cp.enable = 0x01; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; - rq.cparam = &advertise_cp; - rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - ret = hci_send_req(dd, &rq, 1000); - -done: - hci_close_dev(dd); - - if (ret < 0) - { - fprintf(stderr, "Can't set advertise mode on hci%d: %s (%d)\n", - hdev, strerror(errno), errno); - return; - } - - if (status) - { - fprintf(stderr, - "LE set advertise enable on hci%d returned status %d\n", - hdev, status); - return; - } + if (hci_send_cmd(fd, OGF_LE_CTL, OCF_LE_SET_RANDOM_ADDRESS, sizeof(cmd), + &cmd) < 0) + perror("Send msg for set random address error"); } -int hciconfig_open_piscan(void) +static void set_adv_parameters(int fd) { - int ctl = -1; - int hdev = 0; + le_set_advertising_parameters_cp cmd; - /* Open HCI socket */ - if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) + cmd.min_interval = cpu_to_le16(0x0001); + cmd.max_interval = cpu_to_le16(0x0001); + //cmd.min_interval = cpu_to_le16(0x0020); + //cmd.max_interval = cpu_to_le16(0x0020); + + /* 0x00: Connectable undirected advertising + * 0x03: Non connectable undirected advertising + * */ + cmd.advtype = 0x00; + /* 0: public address + * 1: random address */ + cmd.own_bdaddr_type = 0x00; + cmd.direct_bdaddr_type = 0x00; + memset(cmd.direct_bdaddr.b, 0, 6); + cmd.chan_map = 0x07; + cmd.filter = 0x00; + + if (hci_send_cmd(fd, OGF_LE_CTL, OCF_LE_SET_ADVERTISING_PARAMETERS, + sizeof(cmd), &cmd)) + perror("Send msg for set adv params error"); +} + +static void set_scan_enable(int fd, uint8_t enable, uint8_t filter_dup) +{ + le_set_scan_enable_cp scan_cp; + //uint8_t status; + + if (enable) + enable = 0x01; + + memset(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable; + scan_cp.filter_dup = filter_dup; + + if (hci_send_cmd(fd, OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE, sizeof(scan_cp), + &scan_cp) < 0) + perror("Send cmd for set scan enable error"); +} + +static void set_adv_enable(int fd, uint8_t enable) +{ + if (enable) + enable = 0x01; + + if (hci_send_cmd(fd, OGF_LE_CTL, OCF_LE_SET_ADVERTISE_ENABLE, 1, + &enable) < 0) + perror("Send cmd for set adv enable error"); +} + +static void set_adv_data(int fd, const char* name) +{ + le_set_advertising_data_cp cmd; + int i = 0; + int n; + //const char *name = "ADVTEST"; + + cmd.length = 0; + memset(cmd.data, 0, sizeof(cmd.data)); + /* set adv data */ + cmd.data[i] = 0x02; /* Field length */ + cmd.length += (1 + cmd.data[i++]); + cmd.data[i++] = 0x01; /* Flags */ + /* LE General Discoverable Mode, BR/EDR Not Supported */ + cmd.data[i++] = (0x02 | 0x04); + + cmd.data[i] = 0x03; + cmd.length += (1 + cmd.data[i++]); + cmd.data[i++] = 0x03; /* complete list of 15-bit service class uuids */ + cmd.data[i++] = 0xa0; + cmd.data[i++] = 0x0a; + + n = strlen(name); + cmd.data[i] = 1 + n; + cmd.length += (1 + cmd.data[i++]); + cmd.data[i++] = 0x09; /* complete local name */ + memcpy(&cmd.data[i], name, n); + i += n; + + printf("advertise_data, len=%d:\n", i); + for (int k = 0; k < i; k++) { - perror("Can't open HCI socket."); - return -1; + printf("%02x ", cmd.data); + } + printf("\n"); + + if (hci_send_cmd(fd, OGF_LE_CTL, OCF_LE_SET_ADVERTISING_DATA, + sizeof(cmd), &cmd)) + perror("Send cmd for set adv data error"); + +} + +int hciconfig_start_advertising(const char *ssid) +{ + int hci_fd; + + //printf("Start advertising\n"); + + hci_fd = hci_open_dev(0); + if (hci_fd < 0) + { + perror("Failed to open hci dev"); + return -1; } - cmd_up(ctl, hdev); - usleep(100*1000); - //cmd_name(ctl, hdev, g_sf_ble_ssid); - //usleep(100*1000); - cmd_piscan(ctl, hdev); - usleep(100*1000); + set_scan_enable(hci_fd, 0, 1); + set_adv_enable(hci_fd, 0); + set_adv_data(hci_fd, ssid); + set_random_address(hci_fd); + set_adv_parameters(hci_fd); + set_adv_enable(hci_fd, 1); - cmd_le_adv(ctl, hdev); - //usleep(500*1000); - //cmd_le_adv(ctl, hdev); - - close(ctl); - printf("blue scan.\n"); + hci_close_dev(hci_fd); return 0; } -int hciconfig_set_name(char *name) +int hciconfig_open_device(void) { - snprintf(g_sf_ble_ssid, sizeof(g_sf_ble_ssid), "%s",name); - printf("set bluename:%s\n",g_sf_ble_ssid); int ctl = -1; int hdev = 0; @@ -214,11 +301,32 @@ int hciconfig_set_name(char *name) perror("Can't open HCI socket."); return -1; } + cmd_up(ctl, hdev); - cmd_name(ctl, hdev, name); - usleep(100*1000); + close(ctl); - printf("set bluename.\n"); + printf("open hci0 device.\n"); + + return 0; +} + +int hciconfig_close_device(void) +{ + int ctl = -1; + int hdev = 0; + + /* Open HCI socket */ + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) + { + perror("Can't open HCI socket."); + return -1; + } + + cmd_down(ctl, hdev); + + close(ctl); + printf("close hci0 device.\n"); + return 0; } @@ -233,15 +341,19 @@ int hciconfig_get_address(char *ssid) perror("Can't open HCI socket."); return -1; } + cmd_up(ctl, hdev); - - if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) { - perror("Can't get device info"); - } - cmd_address(ctl, hdev, ssid); - usleep(100*1000); + close(ctl); printf("get blueaddress.\n"); return 0; } + +int hciconfig_conn_le(char *addr) +{ + cmd_lecc(0, addr); + + printf("connect le.\n"); + return 0; +} diff --git a/code/application/source/sf_app/code/source/sf_blue/src/hcitool.c b/code/application/source/sf_app/code/source/sf_blue/src/hcitool.c new file mode 100644 index 000000000..62f4c979c --- /dev/null +++ b/code/application/source/sf_app/code/source/sf_blue/src/hcitool.c @@ -0,0 +1,3501 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2010 Marcel Holtmann + * + * + */ + +#if 0 +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib/bluetooth.h" +#include "lib/hci.h" +#include "lib/hci_lib.h" + +#include "src/oui.h" + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* Unofficial value, might still change */ +#define LE_LINK 0x80 + +#define FLAGS_AD_TYPE 0x01 +#define FLAGS_LIMITED_MODE_BIT 0x01 +#define FLAGS_GENERAL_MODE_BIT 0x02 + +#define EIR_FLAGS 0x01 /* flags */ +#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define EIR_NAME_SHORT 0x08 /* shortened local name */ +#define EIR_NAME_COMPLETE 0x09 /* complete local name */ +#define EIR_TX_POWER 0x0A /* transmit power level */ +#define EIR_DEVICE_ID 0x10 /* device ID */ + +#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) + +static volatile int signal_received = 0; + +static void usage(void); + +static int str2buf(const char *str, uint8_t *buf, size_t blen) +{ + int i, dlen; + + if (str == NULL) + return -EINVAL; + + memset(buf, 0, blen); + + dlen = MIN((strlen(str) / 2), blen); + + for (i = 0; i < dlen; i++) + sscanf(str + (i * 2), "%02hhX", &buf[i]); + + return 0; +} + +static int dev_info(int s, int dev_id, long arg) +{ + struct hci_dev_info di = { .dev_id = dev_id }; + char addr[18]; + + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) + return 0; + + ba2str(&di.bdaddr, addr); + printf("\t%s\t%s\n", di.name, addr); + return 0; +} + +static void helper_arg(int min_num_arg, int max_num_arg, int *argc, + char ***argv, const char *usage) +{ + *argc -= optind; + /* too many arguments, but when "max_num_arg < min_num_arg" then no + limiting (prefer "max_num_arg=-1" to gen infinity) + */ + if ( (*argc > max_num_arg) && (max_num_arg >= min_num_arg ) ) { + fprintf(stderr, "%s: too many arguments (maximal: %i)\n", + *argv[0], max_num_arg); + printf("%s", usage); + exit(1); + } + + /* print usage */ + if (*argc < min_num_arg) { + fprintf(stderr, "%s: too few arguments (minimal: %i)\n", + *argv[0], min_num_arg); + printf("%s", usage); + exit(0); + } + + *argv += optind; +} + +static char *type2str(uint8_t type) +{ + switch (type) { + case SCO_LINK: + return "SCO"; + case ACL_LINK: + return "ACL"; + case ESCO_LINK: + return "eSCO"; + case LE_LINK: + return "LE"; + default: + return "Unknown"; + } +} + +static int conn_list(int s, int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int id = arg; + int i; + + if (id != -1 && dev_id != id) + return 0; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i = 0; i < cl->conn_num; i++, ci++) { + char addr[18]; + char *str; + ba2str(&ci->bdaddr, addr); + str = hci_lmtostr(ci->link_mode); + printf("\t%s %s %s handle %d state %d lm %s\n", + ci->out ? "<" : ">", type2str(ci->type), + addr, ci->handle, ci->state, str); + bt_free(str); + } + + free(cl); + return 0; +} + +static int find_conn(int s, int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i = 0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) { + free(cl); + return 1; + } + + free(cl); + return 0; +} + +static void hex_dump(char *pref, int width, unsigned char *buf, int len) +{ + register int i,n; + + for (i = 0, n = 1; i < len; i++, n++) { + if (n == 1) + printf("%s", pref); + printf("%2.2X ", buf[i]); + if (n == width) { + printf("\n"); + n = 0; + } + } + if (i && n!=1) + printf("\n"); +} + +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch (minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch (minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch (minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch (minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ { + static char cls_str[48]; cls_str[0] = 0; + + switch (minor & 48) { + case 16: + strncpy(cls_str, "Keyboard", sizeof(cls_str)); + break; + case 32: + strncpy(cls_str, "Pointing device", sizeof(cls_str)); + break; + case 48: + strncpy(cls_str, "Combo keyboard/pointing device", sizeof(cls_str)); + break; + } + if ((minor & 15) && (strlen(cls_str) > 0)) + strcat(cls_str, "/"); + + switch (minor & 15) { + case 0: + break; + case 1: + strncat(cls_str, "Joystick", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + case 2: + strncat(cls_str, "Gamepad", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + case 3: + strncat(cls_str, "Remote control", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + case 4: + strncat(cls_str, "Sensing device", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + case 5: + strncat(cls_str, "Digitizer tablet", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + case 6: + strncat(cls_str, "Card reader", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + default: + strncat(cls_str, "(reserved)", + sizeof(cls_str) - strlen(cls_str) - 1); + break; + } + if (strlen(cls_str) > 0) + return cls_str; + break; + } + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 7: /* wearable */ + switch (minor) { + case 1: + return "Wrist Watch"; + case 2: + return "Pager"; + case 3: + return "Jacket"; + case 4: + return "Helmet"; + case 5: + return "Glasses"; + } + break; + case 8: /* toy */ + switch (minor) { + case 1: + return "Robot"; + case 2: + return "Vehicle"; + case 3: + return "Doll / Action Figure"; + case 4: + return "Controller"; + case 5: + return "Game"; + } + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + +/* Display local devices */ + +static struct option dev_options[] = { + { "help", 0, 0, 'h' }, + {0, 0, 0, 0 } +}; + +static const char *dev_help = + "Usage:\n" + "\tdev\n"; + +static void cmd_dev(int dev_id, int argc, char **argv) +{ + int opt; + + for_each_opt(opt, dev_options, NULL) { + switch (opt) { + default: + printf("%s", dev_help); + return; + } + } + helper_arg(0, 0, &argc, &argv, dev_help); + + printf("Devices:\n"); + + hci_for_each_dev(HCI_UP, dev_info, 0); +} + +/* Inquiry */ + +static struct option inq_options[] = { + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } +}; + +static const char *inq_help = + "Usage:\n" + "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--iac=lap] specify the inquiry access code\n" + "\t [--flush] flush the inquiry cache\n"; + +static void cmd_inq(int dev_id, int argc, char **argv) +{ + inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + int num_rsp, length, flags; + char addr[18]; + int i, l, opt; + + length = 8; /* ~10 seconds */ + num_rsp = 0; + flags = 0; + + for_each_opt(opt, inq_options, NULL) { + switch (opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'i': + l = strtoul(optarg, 0, 16); + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf("%s", inq_help); + return; + } + } + helper_arg(0, 0, &argc, &argv, inq_help); + + printf("Inquiring ...\n"); + + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); + if (num_rsp < 0) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", + addr, btohs((info+i)->clock_offset), + (info+i)->dev_class[2], + (info+i)->dev_class[1], + (info+i)->dev_class[0]); + } + + bt_free(info); +} + +/* Device scanning */ + +static struct option scan_options[] = { + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, + { "flush", 0, 0, 'f' }, + { "class", 0, 0, 'C' }, + { "info", 0, 0, 'I' }, + { "oui", 0, 0, 'O' }, + { "all", 0, 0, 'A' }, + { "ext", 0, 0, 'A' }, + { 0, 0, 0, 0 } +}; + +static const char *scan_help = + "Usage:\n" + "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui] [--refresh]\n"; + +static void cmd_scan(int dev_id, int argc, char **argv) +{ + inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + int num_rsp, length, flags; + uint8_t cls[3], features[8]; + char addr[18], name[249], *comp; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int extcls = 0, extinf = 0, extoui = 0; + int i, n, l, opt, dd, cc; + + length = 8; /* ~10 seconds */ + num_rsp = 0; + flags = 0; + + for_each_opt(opt, scan_options, NULL) { + switch (opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'i': + l = strtoul(optarg, 0, 16); + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } else if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + case 'C': + extcls = 1; + break; + + case 'I': + extinf = 1; + break; + + case 'O': + extoui = 1; + break; + + case 'A': + extcls = 1; + extinf = 1; + extoui = 1; + break; + + default: + printf("%s", scan_help); + return; + } + } + helper_arg(0, 0, &argc, &argv, scan_help); + + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + perror("Device is not available"); + exit(1); + } + } + + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + + printf("Scanning ...\n"); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); + if (num_rsp < 0) { + perror("Inquiry failed"); + exit(1); + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + + if (extcls || extinf || extoui) + printf("\n"); + + for (i = 0; i < num_rsp; i++) { + uint16_t handle = 0; + + if (!extcls && !extinf && !extoui) { + ba2str(&(info+i)->bdaddr, addr); + + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + + for (n = 0; n < 248 && name[n]; n++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) + name[i] = '.'; + } + + name[248] = '\0'; + + printf("\t%s\t%s\n", addr, name); + continue; + } + + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + if (extoui) { + comp = batocomp(&(info+i)->bdaddr); + if (comp) { + char oui[9]; + ba2oui(&(info+i)->bdaddr, oui); + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + } + + cc = 0; + + if (extinf) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + handle = 0; + cc = 1; + } else { + handle = htobs(cr->conn_info->handle); + cc = 0; + } + free(cr); + } + + if (cc) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) { + handle = 0; + cc = 0; + } + } + } + + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) { + } else { + for (n = 0; n < 248 && name[n]; n++) { + if ((unsigned char) name[i] < 32 || name[i] == 127) + name[i] = '.'; + } + + name[248] = '\0'; + } + + if (strlen(name) > 0) + printf("Device name:\t%s\n", name); + + if (extcls) { + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(major_classes) / sizeof(char *)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + } + + if (extinf && handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + ver ? ver : "n/a", + version.lmp_ver, version.lmp_subver); + if (ver) + bt_free(ver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", tmp); + bt_free(tmp); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); + } + + bt_free(info); + + hci_close_dev(dd); +} + +/* Remote name */ + +static struct option name_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *name_help = + "Usage:\n" + "\tname \n"; + +static void cmd_name(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + char name[248]; + int opt, dd; + + for_each_opt(opt, name_options, NULL) { + switch (opt) { + default: + printf("%s", name_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, name_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("%s\n", name); + + hci_close_dev(dd); +} + +/* Info about remote device */ + +static struct option info_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *info_help = + "Usage:\n" + "\tinfo \n"; + +static void cmd_info(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + uint16_t handle; + uint8_t features[8], max_page = 0; + char name[249], *comp, *tmp; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int i, opt, dd, cc = 0; + + for_each_opt(opt, info_options, NULL) { + switch (opt) { + default: + printf("%s", info_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, info_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + + if (dev_id < 0) + dev_id = hci_get_route(&bdaddr); + + if (dev_id < 0) { + fprintf(stderr, "Device is not available or not connected.\n"); + exit(1); + } + + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + + printf("Requesting information ...\n"); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't get connection info"); + close(dd); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + if (hci_create_connection(dd, &bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + 0, 0x01, &handle, 25000) < 0) { + perror("Can't create connection"); + free(cr); + close(dd); + exit(1); + } + sleep(1); + cc = 1; + } else + handle = htobs(cr->conn_info->handle); + + free(cr); + + printf("\tBD Address: %s\n", argv[0]); + + comp = batocomp(&bdaddr); + if (comp) { + char oui[9]; + ba2oui(&bdaddr, oui); + printf("\tOUI Company: %s (%s)\n", comp, oui); + free(comp); + } + + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("\tDevice Name: %s\n", name); + + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); + printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" + "\tManufacturer: %s (%d)\n", + ver ? ver : "n/a", + version.lmp_ver, + version.lmp_subver, + bt_compidtostr(version.manufacturer), + version.manufacturer); + if (ver) + bt_free(ver); + } + + memset(features, 0, sizeof(features)); + hci_read_remote_features(dd, handle, features, 20000); + + if ((di.features[7] & LMP_EXT_FEAT) && (features[7] & LMP_EXT_FEAT)) + hci_read_remote_ext_features(dd, handle, 0, &max_page, + features, 20000); + + if (max_page < 1 && (features[6] & LMP_SIMPLE_PAIR)) + max_page = 1; + + printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + (max_page > 0) ? " page 0" : "", + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + + tmp = lmp_featurestostr(features, "\t\t", 63); + printf("%s\n", tmp); + bt_free(tmp); + + for (i = 1; i <= max_page; i++) { + if (hci_read_remote_ext_features(dd, handle, i, NULL, + features, 20000) < 0) + continue; + + printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i, + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + + hci_close_dev(dd); +} + +/* Start periodic inquiry */ + +static struct option spinq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *spinq_help = + "Usage:\n" + "\tspinq\n"; + +static void cmd_spinq(int dev_id, int argc, char **argv) +{ + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + struct hci_request rq; + periodic_inquiry_cp cp; + int opt, dd; + + for_each_opt(opt, spinq_options, NULL) { + switch (opt) { + default: + printf("%s", spinq_help); + return; + } + } + helper_arg(0, 0, &argc, &argv, spinq_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + memset(&cp, 0, sizeof(cp)); + memcpy(cp.lap, lap, 3); + cp.max_period = htobs(16); + cp.min_period = htobs(10); + cp.length = 8; + cp.num_rsp = 0; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_PERIODIC_INQUIRY; + rq.cparam = &cp; + rq.clen = PERIODIC_INQUIRY_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Periodic inquiry failed"); + exit(EXIT_FAILURE); + } + + hci_close_dev(dd); +} + +/* Exit periodic inquiry */ + +static struct option epinq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *epinq_help = + "Usage:\n" + "\tepinq\n"; + +static void cmd_epinq(int dev_id, int argc, char **argv) +{ + int opt, dd; + + for_each_opt(opt, epinq_options, NULL) { + switch (opt) { + default: + printf("%s", epinq_help); + return; + } + } + helper_arg(0, 0, &argc, &argv, epinq_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + if (hci_send_cmd(dd, OGF_LINK_CTL, + OCF_EXIT_PERIODIC_INQUIRY, 0, NULL) < 0) { + perror("Exit periodic inquiry failed"); + exit(EXIT_FAILURE); + } + + hci_close_dev(dd); +} + +/* Send arbitrary HCI commands */ + +static struct option cmd_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *cmd_help = + "Usage:\n" + "\tcmd [parameters]\n" + "Example:\n" + "\tcmd 0x03 0x0013 0x41 0x42 0x43 0x44\n"; + +static void cmd_cmd(int dev_id, int argc, char **argv) +{ + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; + struct hci_filter flt; + hci_event_hdr *hdr; + int i, opt, len, dd; + uint16_t ocf; + uint8_t ogf; + + for_each_opt(opt, cmd_options, NULL) { + switch (opt) { + default: + printf("%s", cmd_help); + return; + } + } + helper_arg(2, -1, &argc, &argv, cmd_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + errno = 0; + ogf = strtol(argv[0], NULL, 16); + ocf = strtol(argv[1], NULL, 16); + if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { + printf("%s", cmd_help); + return; + } + + for (i = 2, len = 0; i < argc && len < (int) sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(argv[i], NULL, 16); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + /* Setup filter */ + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_all_events(&flt); + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + perror("HCI filter setup failed"); + exit(EXIT_FAILURE); + } + + printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); fflush(stdout); + + if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { + perror("Send failed"); + exit(EXIT_FAILURE); + } + + len = read(dd, buf, sizeof(buf)); + if (len < 0) { + perror("Read failed"); + exit(EXIT_FAILURE); + } + + hdr = (void *)(buf + 1); + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + printf("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); fflush(stdout); + + hci_close_dev(dd); +} + +/* Display active connections */ + +static struct option con_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *con_help = + "Usage:\n" + "\tcon\n"; + +static void cmd_con(int dev_id, int argc, char **argv) +{ + int opt; + + for_each_opt(opt, con_options, NULL) { + switch (opt) { + default: + printf("%s", con_help); + return; + } + } + helper_arg(0, 0, &argc, &argv, con_help); + + printf("Connections:\n"); + + hci_for_each_dev(HCI_UP, conn_list, dev_id); +} + +/* Create connection */ + +static struct option cc_options[] = { + { "help", 0, 0, 'h' }, + { "role", 1, 0, 'r' }, + { "ptype", 1, 0, 'p' }, + { 0, 0, 0, 0 } +}; + +static const char *cc_help = + "Usage:\n" + "\tcc [--role=c|p] [--ptype=pkt_types] \n" + "Example:\n" + "\tcc --ptype=dm1,dh3,dh5 01:02:03:04:05:06\n" + "\tcc --role=c 01:02:03:04:05:06\n"; + +static void cmd_cc(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + uint16_t handle; + uint8_t role; + unsigned int ptype; + int dd, opt; + + role = 0x01; + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + for_each_opt(opt, cc_options, NULL) { + switch (opt) { + case 'p': + hci_strtoptype(optarg, &ptype); + break; + + case 'r': + role = optarg[0] == 'm' || optarg[0] == 'c' ? 0 : 1; + break; + + default: + printf("%s", cc_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, cc_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (hci_create_connection(dd, &bdaddr, htobs(ptype), + htobs(0x0000), role, &handle, 25000) < 0) + perror("Can't create connection"); + + hci_close_dev(dd); +} + +/* Close connection */ + +static struct option dc_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *dc_help = + "Usage:\n" + "\tdc [reason]\n"; + +static void cmd_dc(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t reason; + int opt, dd; + + for_each_opt(opt, dc_options, NULL) { + switch (opt) { + default: + printf("%s", dc_help); + return; + } + } + helper_arg(1, 2, &argc, &argv, dc_help); + + str2ba(argv[0], &bdaddr); + reason = (argc > 1) ? atoi(argv[1]) : HCI_OE_USER_ENDED_CONNECTION; + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_disconnect(dd, htobs(cr->conn_info->handle), + reason, 10000) < 0) + perror("Disconnect failed"); + + free(cr); + + hci_close_dev(dd); +} + +/* Role switch */ + +static struct option sr_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *sr_help = + "Usage:\n" + "\tsr \n"; + +static void cmd_sr(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + uint8_t role; + int opt, dd; + + for_each_opt(opt, sr_options, NULL) { + switch (opt) { + default: + printf("%s", sr_help); + return; + } + } + helper_arg(2, 2, &argc, &argv, sr_help); + + str2ba(argv[0], &bdaddr); + switch (argv[1][0]) { + case 'm': /* Deprecated. Kept for compatibility. */ + case 'c': + role = 0; + break; + case 's': /* Deprecated. Kept for compatibility. */ + case 'p': + role = 1; + break; + default: + role = atoi(argv[1]); + break; + } + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { + perror("Switch role request failed"); + exit(1); + } + + hci_close_dev(dd); +} + +/* Read RSSI */ + +static struct option rssi_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *rssi_help = + "Usage:\n" + "\trssi \n"; + +static void cmd_rssi(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int8_t rssi; + int opt, dd; + + for_each_opt(opt, rssi_options, NULL) { + switch (opt) { + default: + printf("%s", rssi_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, rssi_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { + perror("Read RSSI failed"); + exit(1); + } + + printf("RSSI return value: %d\n", rssi); + + free(cr); + + hci_close_dev(dd); +} + +/* Get link quality */ + +static struct option lq_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lq_help = + "Usage:\n" + "\tlq \n"; + +static void cmd_lq(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t lq; + int opt, dd; + + for_each_opt(opt, lq_options, NULL) { + switch (opt) { + default: + printf("%s", lq_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, lq_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_link_quality(dd, htobs(cr->conn_info->handle), &lq, 1000) < 0) { + perror("HCI read_link_quality request failed"); + exit(1); + } + + printf("Link quality: %d\n", lq); + + free(cr); + + hci_close_dev(dd); +} + +/* Get transmit power level */ + +static struct option tpl_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *tpl_help = + "Usage:\n" + "\ttpl [type]\n"; + +static void cmd_tpl(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t type; + int8_t level; + int opt, dd; + + for_each_opt(opt, tpl_options, NULL) { + switch (opt) { + default: + printf("%s", tpl_help); + return; + } + } + helper_arg(1, 2, &argc, &argv, tpl_help); + + str2ba(argv[0], &bdaddr); + type = (argc > 1) ? atoi(argv[1]) : 0; + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_transmit_power_level(dd, htobs(cr->conn_info->handle), type, &level, 1000) < 0) { + perror("HCI read transmit power level request failed"); + exit(1); + } + + printf("%s transmit power level: %d\n", + (type == 0) ? "Current" : "Maximum", level); + + free(cr); + + hci_close_dev(dd); +} + +/* Get AFH channel map */ + +static struct option afh_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *afh_help = + "Usage:\n" + "\tafh \n"; + +static void cmd_afh(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t handle; + uint8_t mode, map[10]; + int opt, dd; + + for_each_opt(opt, afh_options, NULL) { + switch (opt) { + default: + printf("%s", afh_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, afh_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + + if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) { + perror("HCI read AFH map request failed"); + exit(1); + } + + if (mode == 0x01) { + int i; + printf("AFH map: 0x"); + for (i = 0; i < 10; i++) + printf("%02x", map[i]); + printf("\n"); + } else + printf("AFH disabled\n"); + + free(cr); + + hci_close_dev(dd); +} + +/* Set connection packet type */ + +static struct option cpt_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *cpt_help = + "Usage:\n" + "\tcpt \n"; + +static void cmd_cpt(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_ptype_cp cp; + evt_conn_ptype_changed rp; + bdaddr_t bdaddr; + unsigned int ptype; + int dd, opt; + + for_each_opt(opt, cpt_options, NULL) { + switch (opt) { + default: + printf("%s", cpt_help); + return; + } + } + helper_arg(2, 2, &argc, &argv, cpt_help); + + str2ba(argv[0], &bdaddr); + hci_strtoptype(argv[1], &ptype); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = htobs(cr->conn_info->handle); + cp.pkt_type = ptype; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; + rq.cparam = &cp; + rq.clen = SET_CONN_PTYPE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; + rq.event = EVT_CONN_PTYPE_CHANGED; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Packet type change failed"); + exit(1); + } + + free(cr); + + hci_close_dev(dd); +} + +/* Get/Set link policy settings */ + +static struct option lp_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lp_help = + "Usage:\n" + "\tlp [link policy]\n"; + +static void cmd_lp(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t policy; + int opt, dd; + + for_each_opt(opt, lp_options, NULL) { + switch (opt) { + default: + printf("%s", lp_help); + return; + } + } + helper_arg(1, 2, &argc, &argv, lp_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + char *str; + if (hci_read_link_policy(dd, htobs(cr->conn_info->handle), + &policy, 1000) < 0) { + perror("HCI read_link_policy_settings request failed"); + exit(1); + } + + policy = btohs(policy); + str = hci_lptostr(policy); + if (str) { + printf("Link policy settings: %s\n", str); + bt_free(str); + } else { + fprintf(stderr, "Invalig settings\n"); + exit(1); + } + } else { + unsigned int val; + if (hci_strtolp(argv[1], &val) < 0) { + fprintf(stderr, "Invalig arguments\n"); + exit(1); + } + policy = val; + + if (hci_write_link_policy(dd, htobs(cr->conn_info->handle), + htobs(policy), 1000) < 0) { + perror("HCI write_link_policy_settings request failed"); + exit(1); + } + } + + free(cr); + + hci_close_dev(dd); +} + +/* Get/Set link supervision timeout */ + +static struct option lst_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lst_help = + "Usage:\n" + "\tlst [new value in slots]\n"; + +static void cmd_lst(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t timeout; + int opt, dd; + + for_each_opt(opt, lst_options, NULL) { + switch (opt) { + default: + printf("%s", lst_help); + return; + } + } + helper_arg(1, 2, &argc, &argv, lst_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), + &timeout, 1000) < 0) { + perror("HCI read_link_supervision_timeout request failed"); + exit(1); + } + + timeout = btohs(timeout); + + if (timeout) + printf("Link supervision timeout: %u slots (%.2f msec)\n", + timeout, (float) timeout * 0.625); + else + printf("Link supervision timeout never expires\n"); + } else { + timeout = strtol(argv[1], NULL, 10); + + if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), + htobs(timeout), 1000) < 0) { + perror("HCI write_link_supervision_timeout request failed"); + exit(1); + } + } + + free(cr); + + hci_close_dev(dd); +} + +/* Request authentication */ + +static struct option auth_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *auth_help = + "Usage:\n" + "\tauth \n"; + +static void cmd_auth(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, auth_options, NULL) { + switch (opt) { + default: + printf("%s", auth_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, auth_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) { + perror("HCI authentication request failed"); + exit(1); + } + + free(cr); + + hci_close_dev(dd); +} + +/* Activate encryption */ + +static struct option enc_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *enc_help = + "Usage:\n" + "\tenc [encrypt enable]\n"; + +static void cmd_enc(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t encrypt; + int opt, dd; + + for_each_opt(opt, enc_options, NULL) { + switch (opt) { + default: + printf("%s", enc_help); + return; + } + } + helper_arg(1, 2, &argc, &argv, enc_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + encrypt = (argc > 1) ? atoi(argv[1]) : 1; + + if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) { + perror("HCI set encryption request failed"); + exit(1); + } + + free(cr); + + hci_close_dev(dd); +} + +/* Change connection link key */ + +static struct option key_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *key_help = + "Usage:\n" + "\tkey \n"; + +static void cmd_key(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, key_options, NULL) { + switch (opt) { + default: + printf("%s", key_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, key_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) { + perror("Changing link key failed"); + exit(1); + } + + free(cr); + + hci_close_dev(dd); +} + +/* Read clock offset */ + +static struct option clkoff_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *clkoff_help = + "Usage:\n" + "\tclkoff \n"; + +static void cmd_clkoff(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t offset; + int opt, dd; + + for_each_opt(opt, clkoff_options, NULL) { + switch (opt) { + default: + printf("%s", clkoff_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, clkoff_help); + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) { + perror("Reading clock offset failed"); + exit(1); + } + + printf("Clock offset: 0x%4.4x\n", btohs(offset)); + + free(cr); + + hci_close_dev(dd); +} + +/* Read clock */ + +static struct option clock_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *clock_help = + "Usage:\n" + "\tclock [bdaddr] [which clock]\n"; + +static void cmd_clock(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t which; + uint32_t handle, clock; + uint16_t accuracy; + int opt, dd; + + for_each_opt(opt, clock_options, NULL) { + switch (opt) { + default: + printf("%s", clock_help); + return; + } + } + helper_arg(0, 2, &argc, &argv, clock_help); + + if (argc > 0) + str2ba(argv[0], &bdaddr); + else + bacpy(&bdaddr, BDADDR_ANY); + + if (dev_id < 0 && !bacmp(&bdaddr, BDADDR_ANY)) + dev_id = hci_get_route(NULL); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (bacmp(&bdaddr, BDADDR_ANY)) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + free(cr); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + which = (argc > 1) ? atoi(argv[1]) : 0x01; + + free(cr); + } else { + handle = 0x00; + which = 0x00; + } + + if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) { + perror("Reading clock failed"); + exit(1); + } + + accuracy = btohs(accuracy); + + printf("Clock: 0x%4.4x\n", btohl(clock)); + printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); + + hci_close_dev(dd); +} + +static int read_flags(uint8_t *flags, const uint8_t *data, size_t size) +{ + size_t offset; + + if (!flags || !data) + return -EINVAL; + + offset = 0; + while (offset < size) { + uint8_t len = data[offset]; + uint8_t type; + + /* Check if it is the end of the significant part */ + if (len == 0) + break; + + if (len + offset > size) + break; + + type = data[offset + 1]; + + if (type == FLAGS_AD_TYPE) { + *flags = data[offset + 2]; + return 0; + } + + offset += 1 + len; + } + + return -ENOENT; +} + +static int check_report_filter(uint8_t procedure, le_advertising_info *info) +{ + uint8_t flags; + + /* If no discovery procedure is set, all reports are treat as valid */ + if (procedure == 0) + return 1; + + /* Read flags AD type value from the advertising report if it exists */ + if (read_flags(&flags, info->data, info->length)) + return 0; + + switch (procedure) { + case 'l': /* Limited Discovery Procedure */ + if (flags & FLAGS_LIMITED_MODE_BIT) + return 1; + break; + case 'g': /* General Discovery Procedure */ + if (flags & (FLAGS_LIMITED_MODE_BIT | FLAGS_GENERAL_MODE_BIT)) + return 1; + break; + default: + fprintf(stderr, "Unknown discovery procedure\n"); + } + + return 0; +} + +static void sigint_handler(int sig) +{ + signal_received = sig; +} + +static void eir_parse_name(uint8_t *eir, size_t eir_len, + char *buf, size_t buf_len) +{ + size_t offset; + + offset = 0; + while (offset < eir_len) { + uint8_t field_len = eir[0]; + size_t name_len; + + /* Check for the end of EIR */ + if (field_len == 0) + break; + + if (offset + field_len > eir_len) + goto failed; + + switch (eir[1]) { + case EIR_NAME_SHORT: + case EIR_NAME_COMPLETE: + name_len = field_len - 1; + if (name_len > buf_len) + goto failed; + + memcpy(buf, &eir[2], name_len); + return; + } + + offset += field_len + 1; + eir += field_len + 1; + } + +failed: + snprintf(buf, buf_len, "(unknown)"); +} + +static int print_advertising_devices(int dd, uint8_t filter_type) +{ + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; + struct hci_filter nf, of; + struct sigaction sa; + socklen_t olen; + int len; + + olen = sizeof(of); + if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &olen) < 0) { + printf("Could not get socket options\n"); + return -1; + } + + hci_filter_clear(&nf); + hci_filter_set_ptype(HCI_EVENT_PKT, &nf); + hci_filter_set_event(EVT_LE_META_EVENT, &nf); + + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) { + printf("Could not set socket options\n"); + return -1; + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sigint_handler; + sigaction(SIGINT, &sa, NULL); + + while (1) { + evt_le_meta_event *meta; + le_advertising_info *info; + char addr[18]; + + while ((len = read(dd, buf, sizeof(buf))) < 0) { + if (errno == EINTR && signal_received == SIGINT) { + len = 0; + goto done; + } + + if (errno == EAGAIN || errno == EINTR) + continue; + goto done; + } + + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + meta = (void *) ptr; + + if (meta->subevent != 0x02) + goto done; + + /* Ignoring multiple reports */ + info = (le_advertising_info *) (meta->data + 1); + if (check_report_filter(filter_type, info)) { + char name[30]; + + memset(name, 0, sizeof(name)); + + ba2str(&info->bdaddr, addr); + eir_parse_name(info->data, info->length, + name, sizeof(name) - 1); + + printf("%s %s\n", addr, name); + } + } + +done: + setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); + + if (len < 0) + return -1; + + return 0; +} + +static struct option lescan_options[] = { + { "help", 0, 0, 'h' }, + { "static", 0, 0, 's' }, + { "privacy", 0, 0, 'p' }, + { "passive", 0, 0, 'P' }, + { "whitelist", 0, 0, 'w' }, /* Deprecated. Kept for compatibility. */ + { "acceptlist", 0, 0, 'a' }, + { "discovery", 1, 0, 'd' }, + { "duplicates", 0, 0, 'D' }, + { 0, 0, 0, 0 } +}; + +static const char *lescan_help = + "Usage:\n" + "\tlescan [--privacy] enable privacy\n" + "\tlescan [--passive] set scan type passive (default active)\n" + "\tlescan [--acceptlist] scan for address in the accept list only\n" + "\tlescan [--discovery=g|l] enable general or limited discovery" + "procedure\n" + "\tlescan [--duplicates] don't filter duplicates\n"; + +static void cmd_lescan(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + uint8_t own_type = LE_PUBLIC_ADDRESS; + uint8_t scan_type = 0x01; + uint8_t filter_type = 0; + uint8_t filter_policy = 0x00; + uint16_t interval = htobs(0x0010); + uint16_t window = htobs(0x0010); + uint8_t filter_dup = 0x01; + + for_each_opt(opt, lescan_options, NULL) { + switch (opt) { + case 's': + own_type = LE_RANDOM_ADDRESS; + break; + case 'p': + own_type = LE_RANDOM_ADDRESS; + break; + case 'P': + scan_type = 0x00; /* Passive */ + break; + case 'w': /* Deprecated. Kept for compatibility. */ + case 'a': + filter_policy = 0x01; /* Accept list */ + break; + case 'd': + filter_type = optarg[0]; + if (filter_type != 'g' && filter_type != 'l') { + fprintf(stderr, "Unknown discovery procedure\n"); + exit(1); + } + + interval = htobs(0x0012); + window = htobs(0x0012); + break; + case 'D': + filter_dup = 0x00; + break; + default: + printf("%s", lescan_help); + return; + } + } + helper_arg(0, 1, &argc, &argv, lescan_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_set_scan_parameters(dd, scan_type, interval, window, + own_type, filter_policy, 10000); + if (err < 0) { + perror("Set scan parameters failed"); + exit(1); + } + + err = hci_le_set_scan_enable(dd, 0x01, filter_dup, 10000); + if (err < 0) { + perror("Enable scan failed"); + exit(1); + } + + printf("LE Scan ...\n"); + + err = print_advertising_devices(dd, filter_type); + if (err < 0) { + perror("Could not receive advertising events"); + exit(1); + } + + err = hci_le_set_scan_enable(dd, 0x00, filter_dup, 10000); + if (err < 0) { + perror("Disable scan failed"); + exit(1); + } + + hci_close_dev(dd); +} + +static struct option leinfo_options[] = { + { "help", 0, 0, 'h' }, + { "static", 0, 0, 's' }, + { "random", 0, 0, 'r' }, + { 0, 0, 0, 0 } +}; + +static const char *leinfo_help = + "Usage:\n" + "\tleinfo [--static] [--random] \n"; + +static void cmd_leinfo(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + uint16_t handle; + uint8_t features[8]; + struct hci_version version; + uint16_t interval, latency, max_ce_length, max_interval, min_ce_length; + uint16_t min_interval, supervision_timeout, window; + uint8_t initiator_filter, own_bdaddr_type, peer_bdaddr_type; + int opt, err, dd; + + own_bdaddr_type = LE_PUBLIC_ADDRESS; + peer_bdaddr_type = LE_PUBLIC_ADDRESS; + + for_each_opt(opt, leinfo_options, NULL) { + switch (opt) { + case 's': + own_bdaddr_type = LE_RANDOM_ADDRESS; + break; + case 'r': + peer_bdaddr_type = LE_RANDOM_ADDRESS; + break; + default: + printf("%s", leinfo_help); + return; + } + } + helper_arg(1, 1, &argc, &argv, leinfo_help); + + str2ba(argv[0], &bdaddr); + + printf("Requesting information ...\n"); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + interval = htobs(0x0004); + window = htobs(0x0004); + initiator_filter = 0; + min_interval = htobs(0x000F); + max_interval = htobs(0x000F); + latency = htobs(0x0000); + supervision_timeout = htobs(0x0C80); + min_ce_length = htobs(0x0000); + max_ce_length = htobs(0x0000); + + err = hci_le_create_conn(dd, interval, window, initiator_filter, + peer_bdaddr_type, bdaddr, own_bdaddr_type, min_interval, + max_interval, latency, supervision_timeout, + min_ce_length, max_ce_length, &handle, 25000); + if (err < 0) { + perror("Could not create connection"); + exit(1); + } + + printf("\tHandle: %d (0x%04x)\n", handle, handle); + + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); + printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" + "\tManufacturer: %s (%d)\n", + ver ? ver : "n/a", + version.lmp_ver, + version.lmp_subver, + bt_compidtostr(version.manufacturer), + version.manufacturer); + if (ver) + bt_free(ver); + } + + memset(features, 0, sizeof(features)); + hci_le_read_remote_features(dd, handle, features, 20000); + + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + + hci_close_dev(dd); +} + +static struct option lecc_options[] = { + { "help", 0, 0, 'h' }, + { "static", 0, 0, 's' }, + { "random", 0, 0, 'r' }, + { "whitelist", 0, 0, 'w' }, /* Deprecated. Kept for compatibility. */ + { "acceptlist", 0, 0, 'a' }, + { 0, 0, 0, 0 } +}; + +static const char *lecc_help = + "Usage:\n" + "\tlecc [--static] [--random] \n" + "\tlecc --acceptlist\n"; + +static void cmd_lecc(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + bdaddr_t bdaddr; + uint16_t interval, latency, max_ce_length, max_interval, min_ce_length; + uint16_t min_interval, supervision_timeout, window, handle; + uint8_t initiator_filter, own_bdaddr_type, peer_bdaddr_type; + + own_bdaddr_type = LE_PUBLIC_ADDRESS; + peer_bdaddr_type = LE_PUBLIC_ADDRESS; + initiator_filter = 0; /* Use peer address */ + + for_each_opt(opt, lecc_options, NULL) { + switch (opt) { + case 's': + own_bdaddr_type = LE_RANDOM_ADDRESS; + break; + case 'r': + peer_bdaddr_type = LE_RANDOM_ADDRESS; + break; + case 'w': /* Deprecated. Kept for compatibility. */ + case 'a': + initiator_filter = 0x01; /* Use accept list */ + break; + default: + printf("%s", lecc_help); + return; + } + } + helper_arg(0, 1, &argc, &argv, lecc_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + memset(&bdaddr, 0, sizeof(bdaddr_t)); + if (argv[0]) + str2ba(argv[0], &bdaddr); + + interval = htobs(0x0004); + window = htobs(0x0004); + min_interval = htobs(0x000F); + max_interval = htobs(0x000F); + latency = htobs(0x0000); + supervision_timeout = htobs(0x0C80); + min_ce_length = htobs(0x0001); + max_ce_length = htobs(0x0001); + + err = hci_le_create_conn(dd, interval, window, initiator_filter, + peer_bdaddr_type, bdaddr, own_bdaddr_type, min_interval, + max_interval, latency, supervision_timeout, + min_ce_length, max_ce_length, &handle, 25000); + if (err < 0) { + perror("Could not create connection"); + exit(1); + } + + printf("Connection handle %d\n", handle); + + hci_close_dev(dd); +} + +static struct option lealadd_options[] = { + { "help", 0, 0, 'h' }, + { "random", 0, 0, 'r' }, + { 0, 0, 0, 0 } +}; + +static const char *lealadd_help = + "Usage:\n" + "\tlealadd [--random] \n"; + +static void cmd_lealadd(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + bdaddr_t bdaddr; + uint8_t bdaddr_type = LE_PUBLIC_ADDRESS; + + for_each_opt(opt, lealadd_options, NULL) { + switch (opt) { + case 'r': + bdaddr_type = LE_RANDOM_ADDRESS; + break; + default: + printf("%s", lealadd_help); + return; + } + } + + helper_arg(1, 1, &argc, &argv, lealadd_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + str2ba(argv[0], &bdaddr); + + err = hci_le_add_white_list(dd, &bdaddr, bdaddr_type, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't add to accept list: %s(%d)\n", + strerror(-err), -err); + exit(1); + } +} + +static struct option lealrm_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lealrm_help = + "Usage:\n" + "\tlealrm \n"; + +static void cmd_lealrm(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + bdaddr_t bdaddr; + + for_each_opt(opt, lealrm_options, NULL) { + switch (opt) { + default: + printf("%s", lealrm_help); + return; + } + } + + helper_arg(1, 1, &argc, &argv, lealrm_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + str2ba(argv[0], &bdaddr); + + err = hci_le_rm_white_list(dd, &bdaddr, LE_PUBLIC_ADDRESS, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = errno; + fprintf(stderr, "Can't remove from accept list: %s(%d)\n", + strerror(err), err); + exit(1); + } +} + +static struct option lealsz_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lealsz_help = + "Usage:\n" + "\tlealsz\n"; + +static void cmd_lealsz(int dev_id, int argc, char **argv) +{ + int err, dd, opt; + uint8_t size; + + for_each_opt(opt, lealsz_options, NULL) { + switch (opt) { + default: + printf("%s", lealsz_help); + return; + } + } + + helper_arg(0, 0, &argc, &argv, lealsz_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_read_white_list_size(dd, &size, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't read accept list size: %s(%d)\n", + strerror(-err), -err); + exit(1); + } + + printf("Accept list size: %d\n", size); +} + +static struct option lealclr_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lealclr_help = + "Usage:\n" + "\tlealclr\n"; + +static void cmd_lealclr(int dev_id, int argc, char **argv) +{ + int err, dd, opt; + + for_each_opt(opt, lealclr_options, NULL) { + switch (opt) { + default: + printf("%s", lealclr_help); + return; + } + } + + helper_arg(0, 0, &argc, &argv, lealclr_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_clear_white_list(dd, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't clear accept list: %s(%d)\n", + strerror(-err), -err); + exit(1); + } +} + +static struct option lerladd_options[] = { + { "help", 0, 0, 'h' }, + { "random", 0, 0, 'r' }, + { "local", 1, 0, 'l' }, + { "peer", 1, 0, 'p' }, + { 0, 0, 0, 0 } +}; + +static const char *lerladd_help = + "Usage:\n" + "\tlerladd [--local irk] [--peer irk] [--random] \n"; + +static void cmd_lerladd(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + bdaddr_t bdaddr; + uint8_t bdaddr_type = LE_PUBLIC_ADDRESS; + uint8_t local_irk[16], peer_irk[16]; + + memset(local_irk, 0, 16); + memset(peer_irk, 0, 16); + + for_each_opt(opt, lerladd_options, NULL) { + switch (opt) { + case 'r': + bdaddr_type = LE_RANDOM_ADDRESS; + break; + case 'l': + str2buf(optarg, local_irk, 16); + break; + case 'p': + str2buf(optarg, peer_irk, 16); + break; + default: + printf("%s", lerladd_help); + return; + } + } + + helper_arg(1, 1, &argc, &argv, lerladd_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + str2ba(argv[0], &bdaddr); + + err = hci_le_add_resolving_list(dd, &bdaddr, bdaddr_type, + peer_irk, local_irk, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't add to resolving list: %s(%d)\n", + strerror(-err), -err); + exit(1); + } +} + +static struct option lerlrm_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lerlrm_help = + "Usage:\n" + "\tlerlrm \n"; + +static void cmd_lerlrm(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + bdaddr_t bdaddr; + + for_each_opt(opt, lerlrm_options, NULL) { + switch (opt) { + default: + printf("%s", lerlrm_help); + return; + } + } + + helper_arg(1, 1, &argc, &argv, lerlrm_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + str2ba(argv[0], &bdaddr); + + err = hci_le_rm_resolving_list(dd, &bdaddr, LE_PUBLIC_ADDRESS, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = errno; + fprintf(stderr, "Can't remove from resolving list: %s(%d)\n", + strerror(err), err); + exit(1); + } +} + +static struct option lerlclr_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lerlclr_help = + "Usage:\n" + "\tlerlclr\n"; + +static void cmd_lerlclr(int dev_id, int argc, char **argv) +{ + int err, dd, opt; + + for_each_opt(opt, lerlclr_options, NULL) { + switch (opt) { + default: + printf("%s", lerlclr_help); + return; + } + } + + helper_arg(0, 0, &argc, &argv, lerlclr_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_clear_resolving_list(dd, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't clear resolving list: %s(%d)\n", + strerror(-err), -err); + exit(1); + } +} + +static struct option lerlsz_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lerlsz_help = + "Usage:\n" + "\tlerlsz\n"; + +static void cmd_lerlsz(int dev_id, int argc, char **argv) +{ + int err, dd, opt; + uint8_t size; + + for_each_opt(opt, lerlsz_options, NULL) { + switch (opt) { + default: + printf("%s", lerlsz_help); + return; + } + } + + helper_arg(0, 0, &argc, &argv, lerlsz_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_read_resolving_list_size(dd, &size, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't read resolving list size: %s(%d)\n", + strerror(-err), -err); + exit(1); + } + + printf("Resolving list size: %d\n", size); +} + +static struct option lerlon_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lerlon_help = + "Usage:\n" + "\tlerlon\n"; + +static void cmd_lerlon(int dev_id, int argc, char **argv) +{ + int err, dd, opt; + + for_each_opt(opt, lerlon_options, NULL) { + switch (opt) { + default: + printf("%s", lerlon_help); + return; + } + } + + helper_arg(0, 0, &argc, &argv, lerlon_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_set_address_resolution_enable(dd, 0x01, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't set address resolution enable: %s(%d)\n", + strerror(-err), -err); + exit(1); + } +} + +static struct option lerloff_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *lerloff_help = + "Usage:\n" + "\tlerloff\n"; + +static void cmd_lerloff(int dev_id, int argc, char **argv) +{ + int err, dd, opt; + + for_each_opt(opt, lerloff_options, NULL) { + switch (opt) { + default: + printf("%s", lerloff_help); + return; + } + } + + helper_arg(0, 0, &argc, &argv, lerloff_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + err = hci_le_set_address_resolution_enable(dd, 0x00, 1000); + hci_close_dev(dd); + + if (err < 0) { + err = -errno; + fprintf(stderr, "Can't set address resolution enable: %s(%d)\n", + strerror(-err), -err); + exit(1); + } +} + +static struct option ledc_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char *ledc_help = + "Usage:\n" + "\tledc [reason]\n"; + +static void cmd_ledc(int dev_id, int argc, char **argv) +{ + int err, opt, dd; + uint16_t handle; + uint8_t reason; + + for_each_opt(opt, ledc_options, NULL) { + switch (opt) { + default: + printf("%s", ledc_help); + return; + } + } + helper_arg(1, 2, &argc, &argv, ledc_help); + + if (dev_id < 0) + dev_id = hci_get_route(NULL); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Could not open device"); + exit(1); + } + + handle = atoi(argv[0]); + + reason = (argc > 1) ? atoi(argv[1]) : HCI_OE_USER_ENDED_CONNECTION; + + err = hci_disconnect(dd, handle, reason, 10000); + if (err < 0) { + perror("Could not disconnect"); + exit(1); + } + + hci_close_dev(dd); +} + +static struct option lecup_options[] = { + { "help", 0, 0, 'h' }, + { "handle", 1, 0, 'H' }, + { "min", 1, 0, 'm' }, + { "max", 1, 0, 'M' }, + { "latency", 1, 0, 'l' }, + { "timeout", 1, 0, 't' }, + { 0, 0, 0, 0 } +}; + +static const char *lecup_help = + "Usage:\n" + "\tlecup \n" + "\tOptions:\n" + "\t --handle=<0xXXXX> LE connection handle\n" + "\t --min= Range: 0x0006 to 0x0C80\n" + "\t --max= Range: 0x0006 to 0x0C80\n" + "\t --latency= Peripheral latency. Range: 0x0000 to 0x03E8\n" + "\t --timeout=