From bc327ae60b5c277ebaa91f40c55d94c5ba4ab9e2 Mon Sep 17 00:00:00 2001 From: guoyi Date: Wed, 11 Feb 2015 14:00:41 +0800 Subject: [PATCH] Drivers: input: add gt9xx/ for goodix touchscreen. --- drivers/input/touchscreen/Kconfig | 8 + drivers/input/touchscreen/Makefile | 3 +- drivers/input/touchscreen/gt9xx/Makefile | 7 + ...GT9271_1060_Config_20140821_1341110X42.cfg | 1 + ...WGJ10162_GT9271_Config_20140820_182456.cfg | 1 + ...187_GT9271_Config_20140623_104014_0X41.cfg | 1 + ...06B_GT9271_Config_20140625_085816_0X41.cfg | 1 + drivers/input/touchscreen/gt9xx/goodix_tool.c | 627 +++ drivers/input/touchscreen/gt9xx/gt9xx.c | 3101 ++++++++++++++ drivers/input/touchscreen/gt9xx/gt9xx.h | 413 ++ .../input/touchscreen/gt9xx/gt9xx_firmware.h | 2341 +++++++++++ .../input/touchscreen/gt9xx/gt9xx_update.c | 3614 +++++++++++++++++ 12 files changed, 10117 insertions(+), 1 deletion(-) create mode 100644 drivers/input/touchscreen/gt9xx/Makefile create mode 100644 drivers/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg create mode 100644 drivers/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg create mode 100644 drivers/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg create mode 100644 drivers/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg create mode 100644 drivers/input/touchscreen/gt9xx/goodix_tool.c create mode 100644 drivers/input/touchscreen/gt9xx/gt9xx.c create mode 100644 drivers/input/touchscreen/gt9xx/gt9xx.h create mode 100644 drivers/input/touchscreen/gt9xx/gt9xx_firmware.h create mode 100644 drivers/input/touchscreen/gt9xx/gt9xx_update.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index d9152962c98b..45787d918a33 100755 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -30,6 +30,14 @@ config TOUCHSCREEN_GT8XX code includes that in its table of IIC devices. If unsure, say N. +config TOUCHSCREEN_GT9XX + tristate "Goodix touch screen gt9xx support for rockchip based platform" + help + Say Y here if you have a touchscreen interface using the + two goodix gt9xx, and your board-specific initialization + code includes that in its table of IIC devices. + If unsure, say N. + config TOUCHSCREEN_CT36X_TS tristate "CT36X touchscreens support" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index aae524d315fa..b2ef928973cb 100755 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_TOUCHSCREEN_ZET62XX) += zet62xx/ obj-$(CONFIG_TOUCHSCREEN_GSLX680) += rockchip_gslX680_rk3128.o obj-$(CONFIG_TOUCHSCREEN_CT36X_TS) += ct36x/ obj-$(CONFIG_TOUCHSCREEN_GT8XX) += rk29_i2c_goodix.o +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/ obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o @@ -75,4 +76,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o -obj-$(CONFIG_TOUCHSCREEN_VTL_CT36X) += vtl_ts/ \ No newline at end of file +obj-$(CONFIG_TOUCHSCREEN_VTL_CT36X) += vtl_ts/ diff --git a/drivers/input/touchscreen/gt9xx/Makefile b/drivers/input/touchscreen/gt9xx/Makefile new file mode 100644 index 000000000000..ee8f9fef99a1 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/Makefile @@ -0,0 +1,7 @@ + +obj-y += goodix_gt9xx.o +#obj-y += vtl_ts_ct36x.o + +#goodix_gt9xx-y +=goodix_tool.o +goodix_gt9xx-y +=gt9xx.o +#goodix_gt9xx-y +=gt9xx_update.o diff --git a/drivers/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg b/drivers/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg new file mode 100644 index 000000000000..db5ed0f34b82 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg @@ -0,0 +1 @@ +0x42,0x80,0x07,0xB0,0x04,0x0A,0x35,0x00,0x02,0x0F,0x28,0x0F,0x5A,0x3C,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x19,0x1D,0x14,0x8F,0x2F,0xAA,0x37,0x39,0xD9,0x0B,0x00,0x00,0x00,0x83,0x02,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x46,0x94,0xC5,0x02,0x07,0x00,0x00,0x04,0x95,0x2C,0x00,0x8A,0x31,0x00,0x81,0x36,0x00,0x79,0x3C,0x00,0x72,0x42,0x00,0x72,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,0x19,0x18,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x01 \ No newline at end of file diff --git a/drivers/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg b/drivers/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg new file mode 100644 index 000000000000..96bf8cb7961c --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/WGJ10162_GT9271_Config_20140820_182456.cfg @@ -0,0 +1 @@ +0x41,0x80,0x07,0xB0,0x04,0x0A,0x31,0x00,0x01,0x08,0x28,0x0F,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x2F,0xAA,0x37,0x39,0xD3,0x07,0x00,0x00,0x00,0x02,0x02,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x4B,0x94,0x45,0x02,0x07,0x00,0x00,0x00,0xB5,0x25,0x00,0x9B,0x2C,0x00,0x88,0x33,0x00,0x78,0x3B,0x00,0x6A,0x45,0x00,0x6A,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,0x19,0x18,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x01 \ No newline at end of file diff --git a/drivers/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg b/drivers/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg new file mode 100644 index 000000000000..ffbfe3d547da --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/WGJ10187_GT9271_Config_20140623_104014_0X41.cfg @@ -0,0 +1 @@ +0x41,0xB0,0x04,0x80,0x07,0x0A,0xF5,0x00,0x01,0x08,0x28,0x0F,0x64,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x19,0x1E,0x14,0x8F,0x2F,0x99,0x41,0x43,0x15,0x0E,0x00,0x00,0x00,0x22,0x03,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x2D,0x62,0x94,0xC5,0x02,0x07,0x17,0x00,0x04,0x92,0x30,0x00,0x86,0x39,0x00,0x7F,0x42,0x00,0x79,0x4D,0x00,0x74,0x5A,0x00,0x74,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,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E,0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1C,0x1B,0x19,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x01 \ No newline at end of file diff --git a/drivers/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg b/drivers/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg new file mode 100644 index 000000000000..7ed0266acfaa --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg @@ -0,0 +1 @@ +0x41,0x80,0x07,0xB0,0x04,0x0A,0x05,0x00,0x01,0x08,0x28,0x0F,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x2F,0x99,0x2B,0x2D,0x31,0x0D,0x00,0x00,0x00,0x01,0x03,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x55,0x94,0xC5,0x02,0x07,0x00,0x00,0x00,0x8C,0x26,0x00,0x7B,0x2D,0x00,0x6C,0x36,0x00,0x61,0x41,0x00,0x58,0x4E,0x00,0x58,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,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x13,0x12,0x11,0x10,0x0F,0x0D,0x0C,0x0A,0x08,0x07,0x06,0x04,0x02,0x00,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB5,0x01 \ No newline at end of file diff --git a/drivers/input/touchscreen/gt9xx/goodix_tool.c b/drivers/input/touchscreen/gt9xx/goodix_tool.c new file mode 100644 index 000000000000..b2dffcb5e105 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/goodix_tool.c @@ -0,0 +1,627 @@ +/* drivers/input/touchscreen/goodix_tool.c + * + * 2010 - 2012 Goodix Technology. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Version:2.2 + * V1.0:2012/05/01,create file. + * V1.2:2012/06/08,modify some warning. + * V1.4:2012/08/28,modified to support GT9XX + * V1.6:new proc name + * V2.2: compatible with Linux 3.10, 2014/01/14 + */ + +#include "gt9xx.h" + +#define DATA_LENGTH_UINT 512 +#define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8*)) +static char procname[20] = {0}; + +#define UPDATE_FUNCTIONS + +#ifdef UPDATE_FUNCTIONS +extern s32 gup_enter_update_mode(struct i2c_client *client); +extern void gup_leave_update_mode(void); +extern s32 gup_update_proc(void *dir); +#endif + +extern void gtp_irq_disable(struct goodix_ts_data *); +extern void gtp_irq_enable(struct goodix_ts_data *); + +#pragma pack(1) +typedef struct{ + u8 wr; //write read flag£¬0:R 1:W 2:PID 3: + u8 flag; //0:no need flag/int 1: need flag 2:need int + u8 flag_addr[2]; //flag address + u8 flag_val; //flag val + u8 flag_relation; //flag_val:flag 0:not equal 1:equal 2:> 3:< + u16 circle; //polling cycle + u8 times; //plling times + u8 retry; //I2C retry times + u16 delay; //delay befor read or after write + u16 data_len; //data length + u8 addr_len; //address length + u8 addr[2]; //address + u8 res[3]; //reserved + u8* data; //data pointer +}st_cmd_head; +#pragma pack() +st_cmd_head cmd_head; + +static struct i2c_client *gt_client = NULL; + +static struct proc_dir_entry *goodix_proc_entry; + +static ssize_t goodix_tool_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t goodix_tool_write(struct file *, const char __user *, size_t, loff_t *); +static const struct file_operations tool_ops = { + .owner = THIS_MODULE, + .read = goodix_tool_read, + .write = goodix_tool_write, +}; + +//static s32 goodix_tool_write(struct file *filp, const char __user *buff, unsigned long len, void *data); +//static s32 goodix_tool_read( char *page, char **start, off_t off, int count, int *eof, void *data ); +static s32 (*tool_i2c_read)(u8 *, u16); +static s32 (*tool_i2c_write)(u8 *, u16); + +#if GTP_ESD_PROTECT +extern void gtp_esd_switch(struct i2c_client *, s32); +#endif +s32 DATA_LENGTH = 0; +s8 IC_TYPE[16] = "GT9XX"; + +static void tool_set_proc_name(char * procname) +{ + char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", + "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + char date[20] = {0}; + char month[4] = {0}; + int i = 0, n_month = 1, n_day = 0, n_year = 0; + + sprintf(date, "%s", __DATE__); + + //GTP_DEBUG("compile date: %s", date); + + sscanf(date, "%s %d %d", month, &n_day, &n_year); + + for (i = 0; i < 12; ++i) + { + if (!memcmp(months[i], month, 3)) + { + n_month = i+1; + break; + } + } + + sprintf(procname, "gmnode%04d%02d%02d", n_year, n_month, n_day); + //sprintf(procname, "goodix_tool"); + //GTP_DEBUG("procname = %s", procname); +} + + +static s32 tool_i2c_read_no_extra(u8* buf, u16 len) +{ + s32 ret = -1; + s32 i = 0; + struct i2c_msg msgs[2]; + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = gt_client->addr; + msgs[0].len = cmd_head.addr_len; + msgs[0].buf = &buf[0]; + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = gt_client->addr; + msgs[1].len = len; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + + for (i = 0; i < cmd_head.retry; i++) + { + ret=i2c_transfer(gt_client->adapter, msgs, 2); + if (ret > 0) + { + break; + } + } + return ret; +} + +static s32 tool_i2c_write_no_extra(u8* buf, u16 len) +{ + s32 ret = -1; + s32 i = 0; + struct i2c_msg msg; + + msg.flags = !I2C_M_RD; + msg.addr = gt_client->addr; + msg.len = len; + msg.buf = buf; + + for (i = 0; i < cmd_head.retry; i++) + { + ret=i2c_transfer(gt_client->adapter, &msg, 1); + if (ret > 0) + { + break; + } + } + return ret; +} + +static s32 tool_i2c_read_with_extra(u8* buf, u16 len) +{ + s32 ret = -1; + u8 pre[2] = {0x0f, 0xff}; + u8 end[2] = {0x80, 0x00}; + + tool_i2c_write_no_extra(pre, 2); + ret = tool_i2c_read_no_extra(buf, len); + tool_i2c_write_no_extra(end, 2); + + return ret; +} + +static s32 tool_i2c_write_with_extra(u8* buf, u16 len) +{ + s32 ret = -1; + u8 pre[2] = {0x0f, 0xff}; + u8 end[2] = {0x80, 0x00}; + + tool_i2c_write_no_extra(pre, 2); + ret = tool_i2c_write_no_extra(buf, len); + tool_i2c_write_no_extra(end, 2); + + return ret; +} + +static void register_i2c_func(void) +{ +// if (!strncmp(IC_TYPE, "GT818", 5) || !strncmp(IC_TYPE, "GT816", 5) +// || !strncmp(IC_TYPE, "GT811", 5) || !strncmp(IC_TYPE, "GT818F", 6) +// || !strncmp(IC_TYPE, "GT827", 5) || !strncmp(IC_TYPE,"GT828", 5) +// || !strncmp(IC_TYPE, "GT813", 5)) + if (strncmp(IC_TYPE, "GT8110", 6) && strncmp(IC_TYPE, "GT8105", 6) + && strncmp(IC_TYPE, "GT801", 5) && strncmp(IC_TYPE, "GT800", 5) + && strncmp(IC_TYPE, "GT801PLUS", 9) && strncmp(IC_TYPE, "GT811", 5) + && strncmp(IC_TYPE, "GTxxx", 5) && strncmp(IC_TYPE, "GT9XX", 5)) + { + tool_i2c_read = tool_i2c_read_with_extra; + tool_i2c_write = tool_i2c_write_with_extra; + GTP_DEBUG("I2C function: with pre and end cmd!"); + } + else + { + tool_i2c_read = tool_i2c_read_no_extra; + tool_i2c_write = tool_i2c_write_no_extra; + GTP_INFO("I2C function: without pre and end cmd!"); + } +} + +static void unregister_i2c_func(void) +{ + tool_i2c_read = NULL; + tool_i2c_write = NULL; + GTP_INFO("I2C function: unregister i2c transfer function!"); +} + +s32 init_wr_node(struct i2c_client *client) +{ + s32 i; + + gt_client = client; + memset(&cmd_head, 0, sizeof(cmd_head)); + cmd_head.data = NULL; + + i = 5; + while ((!cmd_head.data) && i) + { + cmd_head.data = kzalloc(i * DATA_LENGTH_UINT, GFP_KERNEL); + if (NULL != cmd_head.data) + { + break; + } + i--; + } + if (i) + { + DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH; + GTP_INFO("Applied memory size:%d.", DATA_LENGTH); + } + else + { + GTP_ERROR("Apply for memory failed."); + return FAIL; + } + + cmd_head.addr_len = 2; + cmd_head.retry = 5; + + register_i2c_func(); + + tool_set_proc_name(procname); + //goodix_proc_entry = create_proc_entry(procname, 0666, NULL); + goodix_proc_entry = proc_create(procname, 0666, NULL, &tool_ops); + if (goodix_proc_entry == NULL) + { + GTP_ERROR("Couldn't create proc entry!"); + return FAIL; + } + else + { + GTP_INFO("Create proc entry success!"); + //goodix_proc_entry->write_proc = goodix_tool_write; + //goodix_proc_entry->read_proc = goodix_tool_read; + } + + return SUCCESS; +} + +void uninit_wr_node(void) +{ + kfree(cmd_head.data); + cmd_head.data = NULL; + unregister_i2c_func(); + remove_proc_entry(procname, NULL); +} + +static u8 relation(u8 src, u8 dst, u8 rlt) +{ + u8 ret = 0; + + switch (rlt) + { + case 0: + ret = (src != dst) ? true : false; + break; + + case 1: + ret = (src == dst) ? true : false; + GTP_DEBUG("equal:src:0x%02x dst:0x%02x ret:%d.", src, dst, (s32)ret); + break; + + case 2: + ret = (src > dst) ? true : false; + break; + + case 3: + ret = (src < dst) ? true : false; + break; + + case 4: + ret = (src & dst) ? true : false; + break; + + case 5: + ret = (!(src | dst)) ? true : false; + break; + + default: + ret = false; + break; + } + + return ret; +} + +/******************************************************* +Function: + Comfirm function. +Input: + None. +Output: + Return write length. +********************************************************/ +static u8 comfirm(void) +{ + s32 i = 0; + u8 buf[32]; + +// memcpy(&buf[GTP_ADDR_LENGTH - cmd_head.addr_len], &cmd_head.flag_addr, cmd_head.addr_len); +// memcpy(buf, &cmd_head.flag_addr, cmd_head.addr_len);//Modified by Scott, 2012-02-17 + memcpy(buf, cmd_head.flag_addr, cmd_head.addr_len); + + for (i = 0; i < cmd_head.times; i++) + { + if (tool_i2c_read(buf, 1) <= 0) + { + GTP_ERROR("Read flag data failed!"); + return FAIL; + } + if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val, cmd_head.flag_relation)) + { + GTP_DEBUG("value at flag addr:0x%02x.", buf[GTP_ADDR_LENGTH]); + GTP_DEBUG("flag value:0x%02x.", cmd_head.flag_val); + break; + } + + msleep(cmd_head.circle); + } + + if (i >= cmd_head.times) + { + GTP_ERROR("Didn't get the flag to continue!"); + return FAIL; + } + + return SUCCESS; +} + +/******************************************************* +Function: + Goodix tool write function. +Input: + standard proc write function param. +Output: + Return write length. +********************************************************/ +//static s32 goodix_tool_write(struct file *filp, const char __user *buff, unsigned long len, void *data) +ssize_t goodix_tool_write(struct file *filp, const char __user *buff, size_t len, loff_t *off) +{ + s32 ret = 0; + + GTP_DEBUG_FUNC(); + GTP_DEBUG_ARRAY((u8*)buff, len); + + ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH); + if(ret) + { + GTP_ERROR("copy_from_user failed."); + return -EPERM; + } + + + GTP_DEBUG("[Operation]wr: %02X", cmd_head.wr); + GTP_DEBUG("[Flag]flag: %02X, addr: %02X%02X, value: %02X, relation: %02X", cmd_head.flag, cmd_head.flag_addr[0], + cmd_head.flag_addr[1], cmd_head.flag_val, cmd_head.flag_relation); + GTP_DEBUG("[Retry]circle: %d, times: %d, retry: %d, delay: %d", (s32)cmd_head.circle, (s32)cmd_head.times, + (s32)cmd_head.retry, (s32)cmd_head.delay); + GTP_DEBUG("[Data]data len: %d, addr len: %d, addr: %02X%02X, buffer len: %d, data[0]: %02X", (s32)cmd_head.data_len, + (s32)cmd_head.addr_len, cmd_head.addr[0], cmd_head.addr[1], (s32)len, buff[CMD_HEAD_LENGTH]); + + if (1 == cmd_head.wr) + { + ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + if(ret) + { + GTP_ERROR("copy_from_user failed."); + return -EPERM; + } + memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.addr, cmd_head.addr_len); + + GTP_DEBUG_ARRAY(cmd_head.data, cmd_head.data_len + cmd_head.addr_len); + GTP_DEBUG_ARRAY((u8*)&buff[CMD_HEAD_LENGTH], cmd_head.data_len); + + if (1 == cmd_head.flag) + { + if (FAIL == comfirm()) + { + GTP_ERROR("[WRITE]Comfirm fail!"); + return -EPERM; + } + } + else if (2 == cmd_head.flag) + { + //Need interrupt! + } + if (tool_i2c_write(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], + cmd_head.data_len + cmd_head.addr_len) <= 0) + { + GTP_ERROR("[WRITE]Write data failed!"); + return -EPERM; + } + + GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],cmd_head.data_len + cmd_head.addr_len); + if (cmd_head.delay) + { + msleep(cmd_head.delay); + } + } + else if (3 == cmd_head.wr) //Write ic type + { + ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + if(ret) + { + GTP_ERROR("copy_from_user failed."); + return -EPERM; + } + memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); + + register_i2c_func(); + } + else if (5 == cmd_head.wr) + { + //memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); + } + else if (7 == cmd_head.wr)//disable irq! + { + gtp_irq_disable(i2c_get_clientdata(gt_client)); + + #if GTP_ESD_PROTECT + gtp_esd_switch(gt_client, SWITCH_OFF); + #endif + } + else if (9 == cmd_head.wr) //enable irq! + { + gtp_irq_enable(i2c_get_clientdata(gt_client)); + + #if GTP_ESD_PROTECT + gtp_esd_switch(gt_client, SWITCH_ON); + #endif + } + else if(17 == cmd_head.wr) + { + struct goodix_ts_data *ts = i2c_get_clientdata(gt_client); + ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + if(ret) + { + GTP_DEBUG("copy_from_user failed."); + return -EPERM; + } + if(cmd_head.data[GTP_ADDR_LENGTH]) + { + GTP_INFO("gtp enter rawdiff."); + ts->gtp_rawdiff_mode = true; + } + else + { + ts->gtp_rawdiff_mode = false; + GTP_INFO("gtp leave rawdiff."); + } + } +#ifdef UPDATE_FUNCTIONS + else if (11 == cmd_head.wr)//Enter update mode! + { + if (FAIL == gup_enter_update_mode(gt_client)) + { + return -EPERM; + } + } + else if (13 == cmd_head.wr)//Leave update mode! + { + gup_leave_update_mode(); + } + else if (15 == cmd_head.wr) //Update firmware! + { + show_len = 0; + total_len = 0; + memset(cmd_head.data, 0, cmd_head.data_len + 1); + memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH], cmd_head.data_len); + + if (FAIL == gup_update_proc((void*)cmd_head.data)) + { + return -EPERM; + } + } + +#endif + + return len; +} + +/******************************************************* +Function: + Goodix tool read function. +Input: + standard proc read function param. +Output: + Return read length. +********************************************************/ +//static s32 goodix_tool_read( char *page, char **start, off_t off, int count, int *eof, void *data ) +ssize_t goodix_tool_read(struct file *file, char __user *page, size_t size, loff_t *ppos) +{ + s32 ret = 0; + + GTP_DEBUG_FUNC(); + + if (*ppos) // ADB call again + { + //GTP_DEBUG("[HEAD]wr: %d", cmd_head.wr); + //GTP_DEBUG("[PARAM]size: %d, *ppos: %d", size, (int)*ppos); + //GTP_DEBUG("[TOOL_READ]ADB call again, return it."); + return 0; + } + + if (cmd_head.wr % 2) + { + return -EPERM; + } + else if (!cmd_head.wr) + { + u16 len = 0; + s16 data_len = 0; + u16 loc = 0; + + if (1 == cmd_head.flag) + { + if (FAIL == comfirm()) + { + GTP_ERROR("[READ]Comfirm fail!"); + return -EPERM; + } + } + else if (2 == cmd_head.flag) + { + //Need interrupt! + } + + memcpy(cmd_head.data, cmd_head.addr, cmd_head.addr_len); + + GTP_DEBUG("[CMD HEAD DATA] ADDR:0x%02x%02x.", cmd_head.data[0], cmd_head.data[1]); + GTP_DEBUG("[CMD HEAD ADDR] ADDR:0x%02x%02x.", cmd_head.addr[0], cmd_head.addr[1]); + + if (cmd_head.delay) + { + msleep(cmd_head.delay); + } + + data_len = cmd_head.data_len; + + while(data_len > 0) + { + if (data_len > DATA_LENGTH) + { + len = DATA_LENGTH; + } + else + { + len = data_len; + } + data_len -= len; + + if (tool_i2c_read(cmd_head.data, len) <= 0) + { + GTP_ERROR("[READ]Read data failed!"); + return -EPERM; + } + + //memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], len); + ret = simple_read_from_buffer(&page[loc], size, ppos, &cmd_head.data[GTP_ADDR_LENGTH], len); + if (ret < 0) + { + return ret; + } + loc += len; + + GTP_DEBUG_ARRAY(&cmd_head.data[GTP_ADDR_LENGTH], len); + GTP_DEBUG_ARRAY(page, len); + } + return cmd_head.data_len; + } + else if (2 == cmd_head.wr) + { + ret = simple_read_from_buffer(page, size, ppos, IC_TYPE, sizeof(IC_TYPE)); + return ret; + } + else if (4 == cmd_head.wr) + { + u8 progress_buf[4]; + progress_buf[0] = show_len >> 8; + progress_buf[1] = show_len & 0xff; + progress_buf[2] = total_len >> 8; + progress_buf[3] = total_len & 0xff; + + ret = simple_read_from_buffer(page, size, ppos, progress_buf, 4); + return ret; + } + else if (6 == cmd_head.wr) + { + //Read error code! + } + else if (8 == cmd_head.wr) //Read driver version + { + ret = simple_read_from_buffer(page, size, ppos, GTP_DRIVER_VERSION, strlen(GTP_DRIVER_VERSION)); + return ret; + } + return -EPERM; +} diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c new file mode 100644 index 000000000000..6fa34ac6a65b --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/gt9xx.c @@ -0,0 +1,3101 @@ +/* drivers/input/touchscreen/gt9xx.c + * + * 2010 - 2013 Goodix Technology. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Version: 2.2 + * Authors: andrew@goodix.com, meta@goodix.com + * Release Date: 2014/01/14 + * Revision record: + * V1.0: + * first Release. By Andrew, 2012/08/31 + * V1.2: + * modify gtp_reset_guitar,slot report,tracking_id & 0x0F. By Andrew, 2012/10/15 + * V1.4: + * modify gt9xx_update.c. By Andrew, 2012/12/12 + * V1.6: + * 1. new heartbeat/esd_protect mechanism(add external watchdog) + * 2. doze mode, sliding wakeup + * 3. 3 more cfg_group(GT9 Sensor_ID: 0~5) + * 3. config length verification + * 4. names & comments + * By Meta, 2013/03/11 + * V1.8: + * 1. pen/stylus identification + * 2. read double check & fixed config support + * 3. new esd & slide wakeup optimization + * By Meta, 2013/06/08 + * V2.0: + * 1. compatible with GT9XXF + * 2. send config after resume + * By Meta, 2013/08/06 + * V2.2: + * 1. gt9xx_config for debug + * 2. gesture wakeup + * 3. pen separate input device, active-pen button support + * 4. coordinates & keys optimization + * By Meta, 2014/01/14 + */ + +#include +#include "gt9xx.h" + +#if GTP_ICS_SLOT_REPORT + #include +#endif + +static const char *goodix_ts_name = "goodix-ts"; +static struct workqueue_struct *goodix_wq; +struct i2c_client * i2c_connect_client = NULL; +u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH] + = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + +#if GTP_HAVE_TOUCH_KEY + static const u16 touch_key_array[] = GTP_KEY_TAB; + #define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0])) + +#if GTP_DEBUG_ON + static const int key_codes[] = {KEY_HOME, KEY_BACK, KEY_MENU, KEY_SEARCH}; + static const char *key_names[] = {"Key_Home", "Key_Back", "Key_Menu", "Key_Search"}; +#endif + +#endif + +static s8 gtp_i2c_test(struct i2c_client *client); +void gtp_reset_guitar(struct i2c_client *client, s32 ms); +s32 gtp_send_cfg(struct i2c_client *client); +void gtp_int_sync(s32 ms, struct goodix_ts_data *ts); + +static ssize_t gt91xx_config_read_proc(struct file *, char __user *, size_t, loff_t *); +static ssize_t gt91xx_config_write_proc(struct file *, const char __user *, size_t, loff_t *); + +static struct proc_dir_entry *gt91xx_config_proc = NULL; +static const struct file_operations config_proc_ops = { + .owner = THIS_MODULE, + .read = gt91xx_config_read_proc, + .write = gt91xx_config_write_proc, +}; + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void goodix_ts_early_suspend(struct early_suspend *h); +static void goodix_ts_late_resume(struct early_suspend *h); +#endif + +#if GTP_CREATE_WR_NODE +extern s32 init_wr_node(struct i2c_client*); +extern void uninit_wr_node(void); +#endif + +#if GTP_AUTO_UPDATE +extern u8 gup_init_update_proc(struct goodix_ts_data *); +#endif + +#if GTP_ESD_PROTECT +static struct delayed_work gtp_esd_check_work; +static struct workqueue_struct * gtp_esd_check_workqueue = NULL; +static void gtp_esd_check_func(struct work_struct *); +static s32 gtp_init_ext_watchdog(struct i2c_client *client); +void gtp_esd_switch(struct i2c_client *, s32); +#endif + +//*********** For GT9XXF Start **********// +#if GTP_COMPATIBLE_MODE +extern s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len); +extern s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len); +extern s32 gup_clk_calibration(void); +extern s32 gup_fw_download_proc(void *dir, u8 dwn_mode); +extern u8 gup_check_fs_mounted(char *path_name); + +void gtp_recovery_reset(struct i2c_client *client); +static s32 gtp_esd_recovery(struct i2c_client *client); +s32 gtp_fw_startup(struct i2c_client *client); +static s32 gtp_main_clk_proc(struct goodix_ts_data *ts); +static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode); + +#endif +//********** For GT9XXF End **********// + +#if GTP_GESTURE_WAKEUP +typedef enum +{ + DOZE_DISABLED = 0, + DOZE_ENABLED = 1, + DOZE_WAKEUP = 2, +}DOZE_T; +static DOZE_T doze_status = DOZE_DISABLED; +static s8 gtp_enter_doze(struct goodix_ts_data *ts); +#endif + +u8 grp_cfg_version = 0; + +/******************************************************* +Function: + Read data from the i2c slave device. +Input: + client: i2c device. + buf[0~1]: read start address. + buf[2~len-1]: read data buffer. + len: GTP_ADDR_LENGTH + read bytes count +Output: + numbers of i2c_msgs to transfer: + 2: succeed, otherwise: failed +*********************************************************/ +s32 gtp_i2c_read(struct i2c_client *client, u8 *buf, s32 len) +{ + struct i2c_msg msgs[2]; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + msgs[0].scl_rate=200 * 1000; + //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc. + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + msgs[1].scl_rate=200 * 1000; + //msgs[1].scl_rate = 300 * 1000; + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2)break; + retries++; + } + if((retries >= 5)) + { + #if GTP_COMPATIBLE_MODE + struct goodix_ts_data *ts = i2c_get_clientdata(client); + #endif + + #if GTP_GESTURE_WAKEUP + // reset chip would quit doze mode + if (DOZE_ENABLED == doze_status) + { + return ret; + } + #endif + GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + #if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + gtp_recovery_reset(client); + } + else + #endif + { + gtp_reset_guitar(client, 10); + } + } + return ret; +} + + + +/******************************************************* +Function: + Write data to the i2c slave device. +Input: + client: i2c device. + buf[0~1]: write start address. + buf[2~len-1]: data buffer + len: GTP_ADDR_LENGTH + write bytes count +Output: + numbers of i2c_msgs to transfer: + 1: succeed, otherwise: failed +*********************************************************/ +s32 gtp_i2c_write(struct i2c_client *client,u8 *buf,s32 len) +{ + struct i2c_msg msg; + s32 ret = -1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + msg.scl_rate=200 * 1000; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1)break; + retries++; + } + if((retries >= 5)) + { + #if GTP_COMPATIBLE_MODE + struct goodix_ts_data *ts = i2c_get_clientdata(client); + #endif + + #if GTP_GESTURE_WAKEUP + if (DOZE_ENABLED == doze_status) + { + return ret; + } + #endif + GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + #if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + gtp_recovery_reset(client); + } + else + #endif + { + gtp_reset_guitar(client, 10); + } + } + return ret; +} + + +/******************************************************* +Function: + i2c read twice, compare the results +Input: + client: i2c device + addr: operate address + rxbuf: read data to store, if compare successful + len: bytes to read +Output: + FAIL: read failed + SUCCESS: read successful +*********************************************************/ +s32 gtp_i2c_read_dbl_check(struct i2c_client *client, u16 addr, u8 *rxbuf, int len) +{ + u8 buf[16] = {0}; + u8 confirm_buf[16] = {0}; + u8 retry = 0; + + while (retry++ < 3) + { + memset(buf, 0xAA, 16); + buf[0] = (u8)(addr >> 8); + buf[1] = (u8)(addr & 0xFF); + gtp_i2c_read(client, buf, len + 2); + + memset(confirm_buf, 0xAB, 16); + confirm_buf[0] = (u8)(addr >> 8); + confirm_buf[1] = (u8)(addr & 0xFF); + gtp_i2c_read(client, confirm_buf, len + 2); + + if (!memcmp(buf, confirm_buf, len+2)) + { + memcpy(rxbuf, confirm_buf+2, len); + return SUCCESS; + } + } + GTP_ERROR("I2C read 0x%04X, %d bytes, double check failed!", addr, len); + return FAIL; +} + +/******************************************************* +Function: + Send config. +Input: + client: i2c device. +Output: + result of i2c write operation. + 1: succeed, otherwise: failed +*********************************************************/ + +s32 gtp_send_cfg(struct i2c_client *client) +{ + s32 ret = 2; + +#if GTP_DRIVER_SEND_CFG + s32 retry = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if (ts->fixed_cfg) + { + GTP_INFO("Ic fixed config, no config sent!"); + return 0; + } + else if (ts->pnl_init_error) + { + GTP_INFO("Error occured in init_panel, no config sent"); + return 0; + } + + GTP_INFO("Driver send config."); + for (retry = 0; retry < 5; retry++) + { + ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); + if (ret > 0) + { + break; + } + } +#endif + return ret; +} +/******************************************************* +Function: + Disable irq function +Input: + ts: goodix i2c_client private data +Output: + None. +*********************************************************/ +void gtp_irq_disable(struct goodix_ts_data *ts) +{ + unsigned long irqflags; + + GTP_DEBUG_FUNC(); + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (!ts->irq_is_disable) + { + ts->irq_is_disable = 1; + disable_irq_nosync(ts->client->irq); + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); +} + +/******************************************************* +Function: + Enable irq function +Input: + ts: goodix i2c_client private data +Output: + None. +*********************************************************/ +void gtp_irq_enable(struct goodix_ts_data *ts) +{ + unsigned long irqflags = 0; + + GTP_DEBUG_FUNC(); + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (ts->irq_is_disable) + { + enable_irq(ts->client->irq); + ts->irq_is_disable = 0; + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); +} + + +/******************************************************* +Function: + Report touch point event +Input: + ts: goodix i2c_client private data + id: trackId + x: input x coordinate + y: input y coordinate + w: input pressure +Output: + None. +*********************************************************/ +static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w) +{ + if(mGtpChange_X2Y){ + GTP_SWAP(x, y); + } + + if(mGtp_X_Reverse){ + x = ts->abs_x_max - x; + } + + if(mGtp_Y_Reverse){ + y = ts->abs_y_max - y; + } + +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); +#else + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + input_mt_sync(ts->input_dev); +#endif + + GTP_DEBUG("ID:%d, X:%d, Y:%d, W:%d", id, x, y, w); +} + +/******************************************************* +Function: + Report touch release event +Input: + ts: goodix i2c_client private data +Output: + None. +*********************************************************/ +static void gtp_touch_up(struct goodix_ts_data* ts, s32 id) +{ +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); + GTP_DEBUG("Touch id[%2d] release!", id); +#else + input_report_key(ts->input_dev, BTN_TOUCH, 0); +#endif +} + +#if GTP_WITH_PEN + +static void gtp_pen_init(struct goodix_ts_data *ts) +{ + s32 ret = 0; + + GTP_INFO("Request input device for pen/stylus."); + + ts->pen_dev = input_allocate_device(); + if (ts->pen_dev == NULL) + { + GTP_ERROR("Failed to allocate input device for pen/stylus."); + return; + } + + ts->pen_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; + +#if GTP_ICS_SLOT_REPORT + input_mt_init_slots(ts->pen_dev, 16); // +#else + ts->pen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); +#endif + + set_bit(BTN_TOOL_PEN, ts->pen_dev->keybit); + set_bit(INPUT_PROP_DIRECT, ts->pen_dev->propbit); + //set_bit(INPUT_PROP_POINTER, ts->pen_dev->propbit); + +#if GTP_PEN_HAVE_BUTTON + input_set_capability(ts->pen_dev, EV_KEY, BTN_STYLUS); + input_set_capability(ts->pen_dev, EV_KEY, BTN_STYLUS2); +#endif + + input_set_abs_params(ts->pen_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->pen_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); + + ts->pen_dev->name = "goodix-pen"; + ts->pen_dev->id.bustype = BUS_I2C; + + ret = input_register_device(ts->pen_dev); + if (ret) + { + GTP_ERROR("Register %s input device failed", ts->pen_dev->name); + return; + } +} + +static void gtp_pen_down(s32 x, s32 y, s32 w, s32 id) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + if(mGtpChange_X2Y){ + GTP_SWAP(x, y); + } + + input_report_key(ts->pen_dev, BTN_TOOL_PEN, 1); +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->pen_dev, id); + input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, id); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_Y, y); + input_report_abs(ts->pen_dev, ABS_MT_PRESSURE, w); + input_report_abs(ts->pen_dev, ABS_MT_TOUCH_MAJOR, w); +#else + input_report_key(ts->pen_dev, BTN_TOUCH, 1); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->pen_dev, ABS_MT_POSITION_Y, y); + input_report_abs(ts->pen_dev, ABS_MT_PRESSURE, w); + input_report_abs(ts->pen_dev, ABS_MT_TOUCH_MAJOR, w); + input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, id); + input_mt_sync(ts->pen_dev); +#endif + GTP_DEBUG("(%d)(%d, %d)[%d]", id, x, y, w); +} + +static void gtp_pen_up(s32 id) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + input_report_key(ts->pen_dev, BTN_TOOL_PEN, 0); + +#if GTP_ICS_SLOT_REPORT + input_mt_slot(ts->pen_dev, id); + input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, -1); +#else + + input_report_key(ts->pen_dev, BTN_TOUCH, 0); +#endif + +} +#endif + +/******************************************************* +Function: + Goodix touchscreen work function +Input: + work: work struct of goodix_workqueue +Output: + None. +*********************************************************/ +static void goodix_ts_work_func(struct work_struct *work) +{ + u8 end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; + u8 point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; + u8 touch_num = 0; + u8 finger = 0; + static u16 pre_touch = 0; + static u8 pre_key = 0; +#if GTP_WITH_PEN + u8 pen_active = 0; + static u8 pre_pen = 0; +#endif + u8 key_value = 0; + u8* coor_data = NULL; + s32 input_x = 0; + s32 input_y = 0; + s32 input_w = 0; + s32 id = 0; + s32 i = 0; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; + +#if GTP_COMPATIBLE_MODE + u8 rqst_buf[3] = {0x80, 0x43}; // for GT9XXF +#endif + +#if GTP_GESTURE_WAKEUP + u8 doze_buf[3] = {0x81, 0x4B}; +#endif + + GTP_DEBUG_FUNC(); + ts = container_of(work, struct goodix_ts_data, work); + if (ts->enter_update) + { + return; + } +#if GTP_GESTURE_WAKEUP + if (DOZE_ENABLED == doze_status) + { + ret = gtp_i2c_read(i2c_connect_client, doze_buf, 3); + GTP_DEBUG("0x814B = 0x%02X", doze_buf[2]); + if (ret > 0) + { + if ((doze_buf[2] == 'a') || (doze_buf[2] == 'b') || (doze_buf[2] == 'c') || + (doze_buf[2] == 'd') || (doze_buf[2] == 'e') || (doze_buf[2] == 'g') || + (doze_buf[2] == 'h') || (doze_buf[2] == 'm') || (doze_buf[2] == 'o') || + (doze_buf[2] == 'q') || (doze_buf[2] == 's') || (doze_buf[2] == 'v') || + (doze_buf[2] == 'w') || (doze_buf[2] == 'y') || (doze_buf[2] == 'z') || + (doze_buf[2] == 0x5E) /* ^ */ + ) + { + if (doze_buf[2] != 0x5E) + { + GTP_INFO("Wakeup by gesture(%c), light up the screen!", doze_buf[2]); + } + else + { + GTP_INFO("Wakeup by gesture(^), light up the screen!"); + } + doze_status = DOZE_WAKEUP; + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + } + else if ( (doze_buf[2] == 0xAA) || (doze_buf[2] == 0xBB) || + (doze_buf[2] == 0xAB) || (doze_buf[2] == 0xBA) ) + { + char *direction[4] = {"Right", "Down", "Up", "Left"}; + u8 type = ((doze_buf[2] & 0x0F) - 0x0A) + (((doze_buf[2] >> 4) & 0x0F) - 0x0A) * 2; + + GTP_INFO("%s slide to light up the screen!", direction[type]); + doze_status = DOZE_WAKEUP; + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + } + else if (0xCC == doze_buf[2]) + { + GTP_INFO("Double click to light up the screen!"); + doze_status = DOZE_WAKEUP; + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + } + else + { + // clear 0x814B + doze_buf[2] = 0x00; + gtp_i2c_write(i2c_connect_client, doze_buf, 3); + gtp_enter_doze(ts); + } + } + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + return; + } +#endif + + ret = gtp_i2c_read(ts->client, point_data, 12); + if (ret < 0) + { + GTP_ERROR("I2C transfer error. errno:%d\n ", ret); + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + return; + } + + finger = point_data[GTP_ADDR_LENGTH]; + +#if GTP_COMPATIBLE_MODE + // GT9XXF + if ((finger == 0x00) && (CHIP_TYPE_GT9F == ts->chip_type)) // request arrived + { + ret = gtp_i2c_read(ts->client, rqst_buf, 3); + if (ret < 0) + { + GTP_ERROR("Read request status error!"); + goto exit_work_func; + } + + switch (rqst_buf[2]) + { + case GTP_RQST_CONFIG: + GTP_INFO("Request for config."); + ret = gtp_send_cfg(ts->client); + if (ret < 0) + { + GTP_ERROR("Request for config unresponded!"); + } + else + { + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + GTP_INFO("Request for config responded!"); + } + break; + + case GTP_RQST_BAK_REF: + GTP_INFO("Request for backup reference."); + ts->rqst_processing = 1; + ret = gtp_bak_ref_proc(ts, GTP_BAK_REF_SEND); + if (SUCCESS == ret) + { + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + ts->rqst_processing = 0; + GTP_INFO("Request for backup reference responded!"); + } + else + { + GTP_ERROR("Requeset for backup reference unresponed!"); + } + break; + + case GTP_RQST_RESET: + GTP_INFO("Request for reset."); + gtp_recovery_reset(ts->client); + break; + + case GTP_RQST_MAIN_CLOCK: + GTP_INFO("Request for main clock."); + ts->rqst_processing = 1; + ret = gtp_main_clk_proc(ts); + if (FAIL == ret) + { + GTP_ERROR("Request for main clock unresponded!"); + } + else + { + GTP_INFO("Request for main clock responded!"); + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + ts->rqst_processing = 0; + ts->clk_chk_fs_times = 0; + } + break; + + default: + GTP_INFO("Undefined request: 0x%02X", rqst_buf[2]); + rqst_buf[2] = GTP_RQST_RESPONDED; + gtp_i2c_write(ts->client, rqst_buf, 3); + break; + } + } +#endif + if (finger == 0x00) + { + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + return; + } + + if((finger & 0x80) == 0) + { + goto exit_work_func; + } + + touch_num = finger & 0x0f; + if (touch_num > GTP_MAX_TOUCH) + { + goto exit_work_func; + } + + if (touch_num > 1) + { + u8 buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff}; + + ret = gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num - 1)); + memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); + } + +#if (GTP_HAVE_TOUCH_KEY || GTP_PEN_HAVE_BUTTON) + key_value = point_data[3 + 8 * touch_num]; + + if(key_value || pre_key) + { + #if GTP_PEN_HAVE_BUTTON + if (key_value == 0x40) + { + GTP_DEBUG("BTN_STYLUS & BTN_STYLUS2 Down."); + input_report_key(ts->pen_dev, BTN_STYLUS, 1); + input_report_key(ts->pen_dev, BTN_STYLUS2, 1); + pen_active = 1; + } + else if (key_value == 0x10) + { + GTP_DEBUG("BTN_STYLUS Down, BTN_STYLUS2 Up."); + input_report_key(ts->pen_dev, BTN_STYLUS, 1); + input_report_key(ts->pen_dev, BTN_STYLUS2, 0); + pen_active = 1; + } + else if (key_value == 0x20) + { + GTP_DEBUG("BTN_STYLUS Up, BTN_STYLUS2 Down."); + input_report_key(ts->pen_dev, BTN_STYLUS, 0); + input_report_key(ts->pen_dev, BTN_STYLUS2, 1); + pen_active = 1; + } + else + { + GTP_DEBUG("BTN_STYLUS & BTN_STYLUS2 Up."); + input_report_key(ts->pen_dev, BTN_STYLUS, 0); + input_report_key(ts->pen_dev, BTN_STYLUS2, 0); + if ( (pre_key == 0x40) || (pre_key == 0x20) || + (pre_key == 0x10) + ) + { + pen_active = 1; + } + } + if (pen_active) + { + touch_num = 0; // shield pen point + //pre_touch = 0; // clear last pen status + } + #endif + + #if GTP_HAVE_TOUCH_KEY + if (!pre_touch) + { + for (i = 0; i < GTP_MAX_KEY_NUM; i++) + { + #if GTP_DEBUG_ON + for (ret = 0; ret < 4; ++ret) + { + if (key_codes[ret] == touch_key_array[i]) + { + GTP_DEBUG("Key: %s %s", key_names[ret], (key_value & (0x01 << i)) ? "Down" : "Up"); + break; + } + } + #endif + input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<pen_dev); + } + else +#endif + { + input_sync(ts->input_dev); + } + +exit_work_func: + if(!ts->gtp_rawdiff_mode) + { + ret = gtp_i2c_write(ts->client, end_cmd, 3); + if (ret < 0) + { + GTP_INFO("I2C write end_cmd error!"); + } + } + if (ts->use_irq) + { + gtp_irq_enable(ts); + } +} + +/******************************************************* +Function: + Timer interrupt service routine for polling mode. +Input: + timer: timer struct pointer +Output: + Timer work mode. + HRTIMER_NORESTART: no restart mode +*********************************************************/ +static enum hrtimer_restart goodix_ts_timer_handler(struct hrtimer *timer) +{ + struct goodix_ts_data *ts = container_of(timer, struct goodix_ts_data, timer); + + GTP_DEBUG_FUNC(); + + queue_work(goodix_wq, &ts->work); + hrtimer_start(&ts->timer, ktime_set(0, (GTP_POLL_TIME+6)*1000000), HRTIMER_MODE_REL); + return HRTIMER_NORESTART; +} + +/******************************************************* +Function: + External interrupt service routine for interrupt mode. +Input: + irq: interrupt number. + dev_id: private data pointer +Output: + Handle Result. + IRQ_HANDLED: interrupt handled successfully +*********************************************************/ +static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) +{ + struct goodix_ts_data *ts = dev_id; + + GTP_DEBUG_FUNC(); + + gtp_irq_disable(ts); + + queue_work(goodix_wq, &ts->work); + + return IRQ_HANDLED; +} +/******************************************************* +Function: + Synchronization. +Input: + ms: synchronization time in millisecond. +Output: + None. +*******************************************************/ +void gtp_int_sync(s32 ms, struct goodix_ts_data *ts) +{ + GTP_GPIO_OUTPUT(ts->irq_pin, 0); + msleep(ms); + //GTP_GPIO_AS_INT(GTP_INT_PORT); + gpio_direction_input(ts->irq_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + //s3c_gpio_cfgpin(pin, GTP_INT_CFG); +} + + +/******************************************************* +Function: + Reset chip. +Input: + ms: reset time in millisecond +Output: + None. +*******************************************************/ +void gtp_reset_guitar(struct i2c_client *client, s32 ms) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + GTP_DEBUG_FUNC(); + GTP_INFO("Guitar reset"); + GTP_GPIO_OUTPUT(ts->rst_pin, 0); // begin select I2C slave addr + msleep(ms); // T2: > 10ms + // HIGH: 0x28/0x29, LOW: 0xBA/0xBB + GTP_GPIO_OUTPUT(ts->irq_pin, client->addr == 0x14); + + msleep(2); // T3: > 100us + GTP_GPIO_OUTPUT(ts->rst_pin, 1); + + msleep(6); // T4: > 5ms + + //GTP_GPIO_AS_INPUT(GTP_RST_PORT); // end select I2C slave addr + gpio_direction_input(ts->rst_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + return; + } +#endif + + gtp_int_sync(50, ts); +#if GTP_ESD_PROTECT + gtp_init_ext_watchdog(client); +#endif +} + +#if GTP_GESTURE_WAKEUP +/******************************************************* +Function: + Enter doze mode for sliding wakeup. +Input: + ts: goodix tp private data +Output: + 1: succeed, otherwise failed +*******************************************************/ +static s8 gtp_enter_doze(struct goodix_ts_data *ts) +{ + s8 ret = -1; + s8 retry = 0; + u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 8}; + + GTP_DEBUG_FUNC(); + + GTP_DEBUG("Entering gesture mode."); + while(retry++ < 5) + { + i2c_control_buf[0] = 0x80; + i2c_control_buf[1] = 0x46; + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret < 0) + { + GTP_DEBUG("failed to set doze flag into 0x8046, %d", retry); + continue; + } + i2c_control_buf[0] = 0x80; + i2c_control_buf[1] = 0x40; + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret > 0) + { + doze_status = DOZE_ENABLED; + GTP_INFO("Gesture mode enabled."); + return ret; + } + msleep(10); + } + GTP_ERROR("GTP send gesture cmd failed."); + return ret; +} +#else +/******************************************************* +Function: + Enter sleep mode. +Input: + ts: private data. +Output: + Executive outcomes. + 1: succeed, otherwise failed. +*******************************************************/ +static s8 gtp_enter_sleep(struct goodix_ts_data * ts) +{ + s8 ret = -1; + s8 retry = 0; + u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; + +#if GTP_COMPATIBLE_MODE + u8 status_buf[3] = {0x80, 0x44}; +#endif + + GTP_DEBUG_FUNC(); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + // GT9XXF: host interact with ic + ret = gtp_i2c_read(ts->client, status_buf, 3); + if (ret < 0) + { + GTP_ERROR("failed to get backup-reference status"); + } + + if (status_buf[2] & 0x80) + { + ret = gtp_bak_ref_proc(ts, GTP_BAK_REF_STORE); + if (FAIL == ret) + { + GTP_ERROR("failed to store bak_ref"); + } + } + } +#endif + + GTP_GPIO_OUTPUT(ts->irq_pin, 0); + msleep(5); + + while(retry++ < 5) + { + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret > 0) + { + GTP_INFO("GTP enter sleep!"); + + return ret; + } + msleep(10); + } + GTP_ERROR("GTP send sleep cmd failed."); + return ret; +} +#endif +/******************************************************* +Function: + Wakeup from sleep. +Input: + ts: private data. +Output: + Executive outcomes. + >0: succeed, otherwise: failed. +*******************************************************/ +static s8 gtp_wakeup_sleep(struct goodix_ts_data * ts) +{ + u8 retry = 0; + s8 ret = -1; + + GTP_DEBUG_FUNC(); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + u8 opr_buf[3] = {0x41, 0x80}; + + GTP_GPIO_OUTPUT(ts->irq_pin, 1); + msleep(5); + + for (retry = 0; retry < 10; ++retry) + { + // hold ss51 & dsp + opr_buf[2] = 0x0C; + ret = gtp_i2c_write(ts->client, opr_buf, 3); + if (FAIL == ret) + { + GTP_ERROR("failed to hold ss51 & dsp!"); + continue; + } + opr_buf[2] = 0x00; + ret = gtp_i2c_read(ts->client, opr_buf, 3); + if (FAIL == ret) + { + GTP_ERROR("failed to get ss51 & dsp status!"); + continue; + } + if (0x0C != opr_buf[2]) + { + GTP_DEBUG("ss51 & dsp not been hold, %d", retry+1); + continue; + } + GTP_DEBUG("ss51 & dsp confirmed hold"); + + ret = gtp_fw_startup(ts->client); + if (FAIL == ret) + { + GTP_ERROR("failed to startup GT9XXF, process recovery"); + gtp_esd_recovery(ts->client); + } + break; + } + if (retry >= 10) + { + GTP_ERROR("failed to wakeup, processing esd recovery"); + gtp_esd_recovery(ts->client); + } + else + { + GTP_INFO("GT9XXF gtp wakeup success"); + } + return ret; + } +#endif + +#if GTP_POWER_CTRL_SLEEP + while(retry++ < 5) + { + gtp_reset_guitar(ts->client, 20); + + GTP_INFO("GTP wakeup sleep."); + return 1; + } +#else + while(retry++ < 10) + { + #if GTP_GESTURE_WAKEUP + if (DOZE_WAKEUP != doze_status) + { + GTP_INFO("Powerkey wakeup."); + } + else + { + GTP_INFO("Gesture wakeup."); + } + doze_status = DOZE_DISABLED; + gtp_irq_disable(ts); + gtp_reset_guitar(ts->client, 10); + gtp_irq_enable(ts); + + #else + GTP_GPIO_OUTPUT(ts->irq_pin, 1); + msleep(5); + #endif + + ret = gtp_i2c_test(ts->client); + if (ret > 0) + { + GTP_INFO("GTP wakeup sleep."); + + #if (!GTP_GESTURE_WAKEUP) + { + gtp_int_sync(25, ts); + #if GTP_ESD_PROTECT + gtp_init_ext_watchdog(ts->client); + #endif + } + #endif + + return ret; + } + gtp_reset_guitar(ts->client, 20); + } +#endif + + GTP_ERROR("GTP wakeup sleep failed."); + return ret; +} +#if GTP_DRIVER_SEND_CFG +static s32 gtp_get_info(struct goodix_ts_data *ts) +{ + u8 opr_buf[6] = {0}; + s32 ret = 0; + + //ts->abs_x_max = GTP_MAX_WIDTH; + //ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; + + opr_buf[0] = (u8)((GTP_REG_CONFIG_DATA+1) >> 8); + opr_buf[1] = (u8)((GTP_REG_CONFIG_DATA+1) & 0xFF); + + ret = gtp_i2c_read(ts->client, opr_buf, 6); + if (ret < 0) + { + return FAIL; + } + + ts->abs_x_max = (opr_buf[3] << 8) + opr_buf[2]; + ts->abs_y_max = (opr_buf[5] << 8) + opr_buf[4]; + + opr_buf[0] = (u8)((GTP_REG_CONFIG_DATA+6) >> 8); + opr_buf[1] = (u8)((GTP_REG_CONFIG_DATA+6) & 0xFF); + + ret = gtp_i2c_read(ts->client, opr_buf, 3); + if (ret < 0) + { + return FAIL; + } + ts->int_trigger_type = opr_buf[2] & 0x03; + + GTP_INFO("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x", + ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + + return SUCCESS; +} +#endif + +/******************************************************* +Function: + Initialize gtp. +Input: + ts: goodix private data +Output: + Executive outcomes. + 0: succeed, otherwise: failed +*******************************************************/ +static s32 gtp_init_panel(struct goodix_ts_data *ts) +{ + s32 ret = -1; +#if GTP_DRIVER_SEND_CFG + s32 i = 0; + u8 check_sum = 0; + u8 opr_buf[16] = {0}; + u8 sensor_id = 0; + + u8 cfg_info_group2[] = CTP_CFG_GROUP2; + u8 cfg_info_group3[] = CTP_CFG_GROUP3; + u8 cfg_info_group4[] = CTP_CFG_GROUP4; + u8 cfg_info_group5[] = CTP_CFG_GROUP5; + u8 cfg_info_group6[] = CTP_CFG_GROUP6; + u8 *send_cfg_buf[] = {gtp_dat_10_1, cfg_info_group2, cfg_info_group3, + cfg_info_group4, cfg_info_group5, cfg_info_group6}; + u8 cfg_info_len[] = { CFG_GROUP_LEN(gtp_dat_10_1), + CFG_GROUP_LEN(cfg_info_group2), + CFG_GROUP_LEN(cfg_info_group3), + CFG_GROUP_LEN(cfg_info_group4), + CFG_GROUP_LEN(cfg_info_group5), + CFG_GROUP_LEN(cfg_info_group6)};; + + GTP_INFO(" <%s>_%d \n", __func__, __LINE__); + + if(m89or101){ + send_cfg_buf[0] = gtp_dat_8_9; + cfg_info_len[0] = CFG_GROUP_LEN(gtp_dat_8_9); + } + + GTP_DEBUG_FUNC(); + GTP_DEBUG("Config Groups\' Lengths: %d, %d, %d, %d, %d, %d", + cfg_info_len[0], cfg_info_len[1], cfg_info_len[2], cfg_info_len[3], + cfg_info_len[4], cfg_info_len[5]); + + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + ts->fw_error = 0; + } + else +#endif + { + ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1); + if (SUCCESS == ret) + { + if (opr_buf[0] != 0xBE) + { + ts->fw_error = 1; + GTP_ERROR("Firmware error, no config sent!"); + return -1; + } + } + } + + if ((!cfg_info_len[1]) && (!cfg_info_len[2]) && + (!cfg_info_len[3]) && (!cfg_info_len[4]) && + (!cfg_info_len[5])) + { + sensor_id = 0; + } + else + { + #if GTP_COMPATIBLE_MODE + msleep(50); + #endif + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1); + if (SUCCESS == ret) + { + if (sensor_id >= 0x06) + { + GTP_ERROR("Invalid sensor_id(0x%02X), No Config Sent!", sensor_id); + ts->pnl_init_error = 1; + return -1; + } + } + else + { + GTP_ERROR("Failed to get sensor_id, No config sent!"); + ts->pnl_init_error = 1; + return -1; + } + GTP_INFO("Sensor_ID: %d", sensor_id); + } + ts->gtp_cfg_len = cfg_info_len[sensor_id]; + GTP_INFO("CTP_CONFIG_GROUP%d used, config length: %d", sensor_id + 1, ts->gtp_cfg_len); + + if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH) + { + GTP_ERROR("Config Group%d is INVALID CONFIG GROUP(Len: %d)! NO Config Sent! You need to check you header file CFG_GROUP section!", sensor_id+1, ts->gtp_cfg_len); + ts->pnl_init_error = 1; + return -1; + } + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + ts->fixed_cfg = 0; + } + else +#endif + { + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0], 1); + + if (ret == SUCCESS) + { + GTP_DEBUG("CFG_GROUP%d Config Version: %d, 0x%02X; IC Config Version: %d, 0x%02X", sensor_id+1, + send_cfg_buf[sensor_id][0], send_cfg_buf[sensor_id][0], opr_buf[0], opr_buf[0]); + + if (opr_buf[0] < 90) + { + GTP_INFO(" <%s>_%d \n", __func__, __LINE__); + grp_cfg_version = send_cfg_buf[sensor_id][0]; // backup group config version + send_cfg_buf[sensor_id][0] = 0x00; + ts->fixed_cfg = 0; + } + else // treated as fixed config, not send config + { + GTP_INFO("Ic fixed config with config version(%d, 0x%02X)", opr_buf[0], opr_buf[0]); + ts->fixed_cfg = 1; + gtp_get_info(ts); + return 0; + } + } + else + { + GTP_ERROR("Failed to get ic config version!No config sent!"); + return -1; + } + } + + memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); + memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len); + +#if GTP_CUSTOM_CFG + config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; + config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); + config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; + config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); + + if (GTP_INT_TRIGGER == 0) //RISING + { + config[TRIGGER_LOC] &= 0xfe; + } + else if (GTP_INT_TRIGGER == 1) //FALLING + { + config[TRIGGER_LOC] |= 0x01; + } +#endif // GTP_CUSTOM_CFG + + check_sum = 0; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) + { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + +#else // driver not send config + + ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; + ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH); + if (ret < 0) + { + GTP_ERROR("Read Config Failed, Using Default Resolution & INT Trigger!"); + //ts->abs_x_max = GTP_MAX_WIDTH; + //ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; + } + +#endif // GTP_DRIVER_SEND_CFG + + if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) + { + ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC]; + ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2]; + ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; + GTP_INFO(" <%s>_%d <%d, %d>\n", __func__, __LINE__, ts->abs_x_max, ts->abs_y_max); + } + GTP_INFO(" <%s>_%d \n", __func__, __LINE__); +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + u8 sensor_num = 0; + u8 driver_num = 0; + u8 have_key = 0; + + have_key = (config[GTP_REG_HAVE_KEY - GTP_REG_CONFIG_DATA + 2] & 0x01); + + if (1 == ts->is_950) + { + driver_num = config[GTP_REG_MATRIX_DRVNUM - GTP_REG_CONFIG_DATA + 2]; + sensor_num = config[GTP_REG_MATRIX_SENNUM - GTP_REG_CONFIG_DATA + 2]; + if (have_key) + { + driver_num--; + } + ts->bak_ref_len = (driver_num * (sensor_num - 1) + 2) * 2 * 6; + } + else + { + driver_num = (config[CFG_LOC_DRVA_NUM] & 0x1F) + (config[CFG_LOC_DRVB_NUM]&0x1F); + if (have_key) + { + driver_num--; + } + sensor_num = (config[CFG_LOC_SENS_NUM] & 0x0F) + ((config[CFG_LOC_SENS_NUM] >> 4) & 0x0F); + ts->bak_ref_len = (driver_num * (sensor_num - 2) + 2) * 2; + } + + GTP_INFO("Drv * Sen: %d * %d(key: %d), X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", + driver_num, sensor_num, have_key, ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + return 0; + } + else +#endif + { + #if GTP_DRIVER_SEND_CFG + GTP_INFO(" <%s>_%d \n", __func__, __LINE__); + ret = gtp_send_cfg(ts->client); + if (ret < 0) + { + GTP_ERROR("Send config error."); + } + // set config version to CTP_CFG_GROUP, for resume to send config + config[GTP_ADDR_LENGTH] = grp_cfg_version; + check_sum = 0; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) + { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + #endif + GTP_INFO("X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + } + + msleep(10); + return 0; +} + + +static ssize_t gt91xx_config_read_proc(struct file *file, char __user *page, size_t size, loff_t *ppos) +{ + char *ptr = page; + char temp_data[GTP_CONFIG_MAX_LENGTH + 2] = {0x80, 0x47}; + int i; + + if (*ppos) + { + return 0; + } + ptr += sprintf(ptr, "==== GT9XX config init value====\n"); + + for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++) + { + ptr += sprintf(ptr, "0x%02X ", config[i + 2]); + + if (i % 8 == 7) + ptr += sprintf(ptr, "\n"); + } + + ptr += sprintf(ptr, "\n"); + + ptr += sprintf(ptr, "==== GT9XX config real value====\n"); + gtp_i2c_read(i2c_connect_client, temp_data, GTP_CONFIG_MAX_LENGTH + 2); + for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++) + { + ptr += sprintf(ptr, "0x%02X ", temp_data[i+2]); + + if (i % 8 == 7) + ptr += sprintf(ptr, "\n"); + } + *ppos += ptr - page; + return (ptr - page); +} + +static ssize_t gt91xx_config_write_proc(struct file *filp, const char __user *buffer, size_t count, loff_t *off) +{ + s32 ret = 0; + + GTP_DEBUG("write count %d\n", count); + + if (count > GTP_CONFIG_MAX_LENGTH) + { + GTP_ERROR("size not match [%d:%zu]\n", GTP_CONFIG_MAX_LENGTH, count); + return -EFAULT; + } + + if (copy_from_user(&config[2], buffer, count)) + { + GTP_ERROR("copy from user fail\n"); + return -EFAULT; + } + + ret = gtp_send_cfg(i2c_connect_client); + + if (ret < 0) + { + GTP_ERROR("send config failed."); + } + + return count; +} +/******************************************************* +Function: + Read chip version. +Input: + client: i2c device + version: buffer to keep ic firmware version +Output: + read operation return. + 2: succeed, otherwise: failed +*******************************************************/ +s32 gtp_read_version(struct i2c_client *client, u16* version) +{ + s32 ret = -1; + u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; + + GTP_DEBUG_FUNC(); + + ret = gtp_i2c_read(client, buf, sizeof(buf)); + if (ret < 0) + { + GTP_ERROR("GTP read version failed"); + return ret; + } + + if (version) + { + *version = (buf[7] << 8) | buf[6]; + } + if (buf[5] == 0x00) + { + GTP_INFO("IC Version: %c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[7], buf[6]); + } + else + { + GTP_INFO("IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); + } + return ret; +} + +/******************************************************* +Function: + I2c test Function. +Input: + client:i2c client. +Output: + Executive outcomes. + 2: succeed, otherwise failed. +*******************************************************/ +static s8 gtp_i2c_test(struct i2c_client *client) +{ + u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + u8 retry = 0; + s8 ret = -1; + + GTP_DEBUG_FUNC(); + + while(retry++ < 5) + { + ret = gtp_i2c_read(client, test, 3); + if (ret > 0) + { + return ret; + } + GTP_ERROR("GTP i2c test failed time %d.",retry); + msleep(10); + } + return ret; +} + +/******************************************************* +Function: + Request gpio(INT & RST) ports. +Input: + ts: private data. +Output: + Executive outcomes. + >= 0: succeed, < 0: failed +*******************************************************/ +static s8 gtp_request_io_port(struct goodix_ts_data *ts) +{ + s32 ret = 0; + + GTP_DEBUG_FUNC(); +/* + ret = GTP_GPIO_REQUEST(ts->tp_select_pin, "GTP_tp_select_PORT"); + if (ret < 0) + { + GTP_ERROR("1Failed to request GPIO:%d, ERRNO:%d",(s32)ts->tp_select_pin, ret); + return -ENODEV; + } + else + { + gpio_direction_input(ts->tp_select_pin); + } +*/ + ret = GTP_GPIO_REQUEST(ts->rst_pin, "GTP_RST_PORT"); + if (ret < 0) + { + GTP_ERROR("2Failed to request GPIO:%d, ERRNO:%d",(s32)ts->rst_pin, ret); + return -ENODEV; + } + + ret = GTP_GPIO_REQUEST(ts->irq_pin, "GTP_INT_IRQ"); + if (ret < 0) + { + GTP_ERROR("3Failed to request GPIO:%d, ERRNO:%d", (s32)ts->irq_pin, ret); + return -ENODEV; + } + else + { + //GTP_GPIO_AS_INT(GTP_INT_PORT); + gpio_direction_input(ts->irq_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + //s3c_gpio_cfgpin(pin, GTP_INT_CFG); + + //ts->client->irq = ts->irq_pin; + } + + //GTP_GPIO_AS_INPUT(ts->rst_pin); + gpio_direction_input(ts->rst_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + + gtp_reset_guitar(ts->client, 20); + + if(ret < 0) + { + GTP_GPIO_FREE(ts->rst_pin); + GTP_GPIO_FREE(ts->irq_pin); + } + + return ret; +} + +/******************************************************* +Function: + Request interrupt. +Input: + ts: private data. +Output: + Executive outcomes. + 0: succeed, -1: failed. +*******************************************************/ +static s8 gtp_request_irq(struct goodix_ts_data *ts) +{ + s32 ret = -1; + + GTP_DEBUG_FUNC(); + GTP_DEBUG("INT trigger type:%x", ts->int_trigger_type); + + ts->irq=gpio_to_irq(ts->irq_pin); //If not defined in client + if (ts->irq) + { + ts->client->irq = ts->irq; + ret = devm_request_threaded_irq(&(ts->client->dev), ts->irq, NULL, + goodix_ts_irq_handler, ts->irq_flags | IRQF_ONESHOT /*irq_table[ts->int_trigger_type]*/, + ts->client->name, ts); + if (ret != 0) { + GTP_ERROR("Cannot allocate ts INT!ERRNO:%d\n", ret); + goto test_pit; + } + //gtp_irq_disable(ts->irq); + GTP_INFO(" <%s>_%d ts->irq=%d ret = %d\n", __func__, __LINE__, ts->irq, ret); + }else{ + GTP_ERROR(" ts->irq error \n"); + ret = 1; + goto test_pit; + } +/* + ret = request_irq(ts->client->irq, + goodix_ts_irq_handler, + irq_table[ts->int_trigger_type], + ts->client->name, + ts); +*/ +test_pit: + if (ret) + { + GTP_ERROR("Request IRQ failed!ERRNO:%d.", ret); + //GTP_GPIO_AS_INPUT(GTP_INT_PORT); + gpio_direction_input(ts->irq_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + + GTP_GPIO_FREE(ts->irq_pin); + + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ts->timer.function = goodix_ts_timer_handler; + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + return -1; + } + else + { + GTP_INFO(" <%s>_%d ts->irq=%d ret = %d\n", __func__, __LINE__, ts->irq, ret); + gtp_irq_disable(ts); + ts->use_irq = 1; + return 0; + } +} + +/******************************************************* +Function: + Request input device Function. +Input: + ts:private data. +Output: + Executive outcomes. + 0: succeed, otherwise: failed. +*******************************************************/ +static s8 gtp_request_input_dev(struct goodix_ts_data *ts) +{ + s8 ret = -1; + s8 phys[32]; +#if GTP_HAVE_TOUCH_KEY + u8 index = 0; +#endif + + GTP_DEBUG_FUNC(); + + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) + { + GTP_ERROR("Failed to allocate input device."); + return -ENOMEM; + } + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; +#if GTP_ICS_SLOT_REPORT + input_mt_init_slots(ts->input_dev, 16); // in case of "out of memory" +#else + ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); +#endif + __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + +#if GTP_HAVE_TOUCH_KEY + for (index = 0; index < GTP_MAX_KEY_NUM; index++) + { + input_set_capability(ts->input_dev, EV_KEY, touch_key_array[index]); + } +#endif + +#if GTP_GESTURE_WAKEUP + input_set_capability(ts->input_dev, EV_KEY, KEY_POWER); +#endif + + if(mGtpChange_X2Y){ + GTP_SWAP(ts->abs_x_max, ts->abs_y_max); + } + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); + + sprintf(phys, "input/ts"); + ts->input_dev->name = goodix_ts_name; + ts->input_dev->phys = phys; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0xDEAD; + ts->input_dev->id.product = 0xBEEF; + ts->input_dev->id.version = 10427; + + ret = input_register_device(ts->input_dev); + if (ret) + { + GTP_ERROR("Register %s input device failed", ts->input_dev->name); + return -ENODEV; + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = goodix_ts_early_suspend; + ts->early_suspend.resume = goodix_ts_late_resume; + register_early_suspend(&ts->early_suspend); +#endif + +#if GTP_WITH_PEN + gtp_pen_init(ts); +#endif + + return 0; +} + +//************** For GT9XXF Start *************// +#if GTP_COMPATIBLE_MODE + +s32 gtp_fw_startup(struct i2c_client *client) +{ + u8 opr_buf[4]; + s32 ret = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + //init sw WDT + opr_buf[0] = 0xAA; + ret = i2c_write_bytes(client, 0x8041, opr_buf, 1); + if (ret < 0) + { + return FAIL; + } + + //release SS51 & DSP + opr_buf[0] = 0x00; + ret = i2c_write_bytes(client, 0x4180, opr_buf, 1); + if (ret < 0) + { + return FAIL; + } + //int sync + gtp_int_sync(25, ts); + + //check fw run status + ret = i2c_read_bytes(client, 0x8041, opr_buf, 1); + if (ret < 0) + { + return FAIL; + } + if(0xAA == opr_buf[0]) + { + GTP_ERROR("IC works abnormally,startup failed."); + return FAIL; + } + else + { + GTP_INFO("IC works normally, Startup success."); + opr_buf[0] = 0xAA; + i2c_write_bytes(client, 0x8041, opr_buf, 1); + return SUCCESS; + } +} + +static s32 gtp_esd_recovery(struct i2c_client *client) +{ + s32 retry = 0; + s32 ret = 0; + struct goodix_ts_data *ts; + + ts = i2c_get_clientdata(client); + + gtp_irq_disable(ts); + + GTP_INFO("GT9XXF esd recovery mode"); + for (retry = 0; retry < 5; retry++) + { + ret = gup_fw_download_proc(NULL, GTP_FL_ESD_RECOVERY); + if (FAIL == ret) + { + GTP_ERROR("esd recovery failed %d", retry+1); + continue; + } + ret = gtp_fw_startup(ts->client); + if (FAIL == ret) + { + GTP_ERROR("GT9XXF start up failed %d", retry+1); + continue; + } + break; + } + gtp_irq_enable(ts); + + if (retry >= 5) + { + GTP_ERROR("failed to esd recovery"); + return FAIL; + } + + GTP_INFO("Esd recovery successful"); + return SUCCESS; +} + +void gtp_recovery_reset(struct i2c_client *client) +{ +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_OFF); +#endif + GTP_DEBUG_FUNC(); + + gtp_esd_recovery(client); + +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_ON); +#endif +} + +static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode) +{ + s32 ret = 0; + s32 i = 0; + s32 j = 0; + u16 ref_sum = 0; + u16 learn_cnt = 0; + u16 chksum = 0; + s32 ref_seg_len = 0; + s32 ref_grps = 0; + struct file *ref_filp = NULL; + u8 *p_bak_ref; + + ret = gup_check_fs_mounted("/data"); + if (FAIL == ret) + { + ts->ref_chk_fs_times++; + GTP_DEBUG("Ref check /data times/MAX_TIMES: %d / %d", ts->ref_chk_fs_times, GTP_CHK_FS_MNT_MAX); + if (ts->ref_chk_fs_times < GTP_CHK_FS_MNT_MAX) + { + msleep(50); + GTP_INFO("/data not mounted."); + return FAIL; + } + GTP_INFO("check /data mount timeout..."); + } + else + { + GTP_INFO("/data mounted!!!(%d/%d)", ts->ref_chk_fs_times, GTP_CHK_FS_MNT_MAX); + } + + p_bak_ref = (u8 *)kzalloc(ts->bak_ref_len, GFP_KERNEL); + + if (NULL == p_bak_ref) + { + GTP_ERROR("Allocate memory for p_bak_ref failed!"); + return FAIL; + } + + if (ts->is_950) + { + ref_seg_len = ts->bak_ref_len / 6; + ref_grps = 6; + } + else + { + ref_seg_len = ts->bak_ref_len; + ref_grps = 1; + } + ref_filp = filp_open(GTP_BAK_REF_PATH, O_RDWR | O_CREAT, 0666); + if (IS_ERR(ref_filp)) + { + GTP_ERROR("Failed to open/create %s.", GTP_BAK_REF_PATH); + if (GTP_BAK_REF_SEND == mode) + { + goto bak_ref_default; + } + else + { + goto bak_ref_exit; + } + } + + switch (mode) + { + case GTP_BAK_REF_SEND: + GTP_INFO("Send backup-reference"); + ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); + ret = ref_filp->f_op->read(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); + if (ret < 0) + { + GTP_ERROR("failed to read bak_ref info from file, sending defualt bak_ref"); + goto bak_ref_default; + } + for (j = 0; j < ref_grps; ++j) + { + ref_sum = 0; + for (i = 0; i < (ref_seg_len); i += 2) + { + ref_sum += (p_bak_ref[i + j * ref_seg_len] << 8) + p_bak_ref[i+1 + j * ref_seg_len]; + } + learn_cnt = (p_bak_ref[j * ref_seg_len + ref_seg_len -4] << 8) + (p_bak_ref[j * ref_seg_len + ref_seg_len -3]); + chksum = (p_bak_ref[j * ref_seg_len + ref_seg_len -2] << 8) + (p_bak_ref[j * ref_seg_len + ref_seg_len -1]); + GTP_DEBUG("learn count = %d", learn_cnt); + GTP_DEBUG("chksum = %d", chksum); + GTP_DEBUG("ref_sum = 0x%04X", ref_sum & 0xFFFF); + // Sum(1~ref_seg_len) == 1 + if (1 != ref_sum) + { + GTP_INFO("wrong chksum for bak_ref, reset to 0x00 bak_ref"); + memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len); + p_bak_ref[ref_seg_len + j * ref_seg_len - 1] = 0x01; + } + else + { + if (j == (ref_grps - 1)) + { + GTP_INFO("backup-reference data in %s used", GTP_BAK_REF_PATH); + } + } + } + ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); + if (FAIL == ret) + { + GTP_ERROR("failed to send bak_ref because of iic comm error"); + goto bak_ref_exit; + } + break; + + case GTP_BAK_REF_STORE: + GTP_INFO("Store backup-reference"); + ret = i2c_read_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); + if (ret < 0) + { + GTP_ERROR("failed to read bak_ref info, sending default back-reference"); + goto bak_ref_default; + } + ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); + ref_filp->f_op->write(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); + break; + + default: + GTP_ERROR("invalid backup-reference request"); + break; + } + ret = SUCCESS; + goto bak_ref_exit; + +bak_ref_default: + + for (j = 0; j < ref_grps; ++j) + { + memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len); + p_bak_ref[j * ref_seg_len + ref_seg_len - 1] = 0x01; // checksum = 1 + } + ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); + if (!IS_ERR(ref_filp)) + { + GTP_INFO("write backup-reference data into %s", GTP_BAK_REF_PATH); + ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); + ref_filp->f_op->write(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); + } + if (ret == FAIL) + { + GTP_ERROR("failed to load the default backup reference"); + } + +bak_ref_exit: + + if (p_bak_ref) + { + kfree(p_bak_ref); + } + if (ref_filp && !IS_ERR(ref_filp)) + { + filp_close(ref_filp, NULL); + } + return ret; +} + + +static s32 gtp_verify_main_clk(u8 *p_main_clk) +{ + u8 chksum = 0; + u8 main_clock = p_main_clk[0]; + s32 i = 0; + + if (main_clock < 50 || main_clock > 120) + { + return FAIL; + } + + for (i = 0; i < 5; ++i) + { + if (main_clock != p_main_clk[i]) + { + return FAIL; + } + chksum += p_main_clk[i]; + } + chksum += p_main_clk[5]; + if ( (chksum) == 0) + { + return SUCCESS; + } + else + { + return FAIL; + } +} + +static s32 gtp_main_clk_proc(struct goodix_ts_data *ts) +{ + s32 ret = 0; + s32 i = 0; + s32 clk_chksum = 0; + struct file *clk_filp = NULL; + u8 p_main_clk[6] = {0}; + + ret = gup_check_fs_mounted("/data"); + if (FAIL == ret) + { + ts->clk_chk_fs_times++; + GTP_DEBUG("Clock check /data times/MAX_TIMES: %d / %d", ts->clk_chk_fs_times, GTP_CHK_FS_MNT_MAX); + if (ts->clk_chk_fs_times < GTP_CHK_FS_MNT_MAX) + { + msleep(50); + GTP_INFO("/data not mounted."); + return FAIL; + } + GTP_INFO("Check /data mount timeout!"); + } + else + { + GTP_INFO("/data mounted!!!(%d/%d)", ts->clk_chk_fs_times, GTP_CHK_FS_MNT_MAX); + } + + clk_filp = filp_open(GTP_MAIN_CLK_PATH, O_RDWR | O_CREAT, 0666); + if (IS_ERR(clk_filp)) + { + GTP_ERROR("%s is unavailable, calculate main clock", GTP_MAIN_CLK_PATH); + } + else + { + clk_filp->f_op->llseek(clk_filp, 0, SEEK_SET); + clk_filp->f_op->read(clk_filp, (char *)p_main_clk, 6, &clk_filp->f_pos); + + ret = gtp_verify_main_clk(p_main_clk); + if (FAIL == ret) + { + // recalculate main clock & rewrite main clock data to file + GTP_ERROR("main clock data in %s is wrong, recalculate main clock", GTP_MAIN_CLK_PATH); + } + else + { + GTP_INFO("main clock data in %s used, main clock freq: %d", GTP_MAIN_CLK_PATH, p_main_clk[0]); + filp_close(clk_filp, NULL); + goto update_main_clk; + } + } + +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + ret = gup_clk_calibration(); + gtp_esd_recovery(ts->client); + +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); +#endif + + GTP_INFO("calibrate main clock: %d", ret); + if (ret < 50 || ret > 120) + { + GTP_ERROR("wrong main clock: %d", ret); + goto exit_main_clk; + } + + // Sum{0x8020~0x8025} = 0 + for (i = 0; i < 5; ++i) + { + p_main_clk[i] = ret; + clk_chksum += p_main_clk[i]; + } + p_main_clk[5] = 0 - clk_chksum; + + if (!IS_ERR(clk_filp)) + { + GTP_DEBUG("write main clock data into %s", GTP_MAIN_CLK_PATH); + clk_filp->f_op->llseek(clk_filp, 0, SEEK_SET); + clk_filp->f_op->write(clk_filp, (char *)p_main_clk, 6, &clk_filp->f_pos); + filp_close(clk_filp, NULL); + } + +update_main_clk: + ret = i2c_write_bytes(ts->client, GTP_REG_MAIN_CLK, p_main_clk, 6); + if (FAIL == ret) + { + GTP_ERROR("update main clock failed!"); + return FAIL; + } + return SUCCESS; + +exit_main_clk: + if (!IS_ERR(clk_filp)) + { + filp_close(clk_filp, NULL); + } + return FAIL; +} + + +s32 gtp_gt9xxf_init(struct i2c_client *client) +{ + s32 ret = 0; + + ret = gup_fw_download_proc(NULL, GTP_FL_FW_BURN); + if (FAIL == ret) + { + return FAIL; + } + + ret = gtp_fw_startup(client); + if (FAIL == ret) + { + return FAIL; + } + return SUCCESS; +} + +void gtp_get_chip_type(struct goodix_ts_data *ts) +{ + u8 opr_buf[10] = {0x00}; + s32 ret = 0; + + msleep(10); + + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CHIP_TYPE, opr_buf, 10); + + if (FAIL == ret) + { + GTP_ERROR("Failed to get chip-type, set chip type default: GOODIX_GT9"); + ts->chip_type = CHIP_TYPE_GT9; + return; + } + + if (!memcmp(opr_buf, "GOODIX_GT9", 10)) + { + ts->chip_type = CHIP_TYPE_GT9; + } + else // GT9XXF + { + ts->chip_type = CHIP_TYPE_GT9F; + } + GTP_INFO("Chip Type: %s", (ts->chip_type == CHIP_TYPE_GT9) ? "GOODIX_GT9" : "GOODIX_GT9F"); +} + +#endif +//************* For GT9XXF End ************// + +/******************************************************* +Function: + I2c probe. +Input: + client: i2c device struct. + id: device id. +Output: + Executive outcomes. + 0: succeed. +*******************************************************/ +static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + s32 ret = -1; + struct goodix_ts_data *ts; + u16 version_info; + + struct device_node *np = client->dev.of_node; + enum of_gpio_flags rst_flags, pwr_flags; + u32 val; + printk("___%s() start____ \n", __func__); + + + GTP_DEBUG_FUNC(); + + //do NOT remove these logs + GTP_INFO("GTP Driver Version: %s", GTP_DRIVER_VERSION); + GTP_INFO("GTP Driver Built@%s, %s", __TIME__, __DATE__); + GTP_INFO("GTP I2C Address: 0x%02x", client->addr); + + i2c_connect_client = client; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + { + GTP_ERROR("I2C check functionality failed."); + return -ENODEV; + } + ts = kzalloc(sizeof(*ts), GFP_KERNEL); + if (ts == NULL) + { + GTP_ERROR("Alloc GFP_KERNEL memory failed."); + return -ENOMEM; + } + + memset(ts, 0, sizeof(*ts)); + + if (!np) { + dev_err(&client->dev, "no device tree\n"); + return -EINVAL; + } + if (of_property_read_u32(np, "tp-size", &val)) { + dev_err(&client->dev, "no max-x defined\n"); + return -EINVAL; + } + if(val == 89){ + m89or101 = TRUE; + mGtpChange_X2Y = TRUE; + mGtp_X_Reverse = FALSE; + mGtp_Y_Reverse = TRUE; + }else if(val == 101){ + m89or101 = FALSE; + mGtpChange_X2Y = TRUE; + mGtp_X_Reverse = TRUE; + mGtp_Y_Reverse = FALSE; + } + ts->irq_pin = of_get_named_gpio_flags(np, "touch-gpio", 0, (enum of_gpio_flags *)(&ts->irq_flags)); + ts->rst_pin = of_get_named_gpio_flags(np, "reset-gpio", 0, &rst_flags); + ts->pwr_pin = of_get_named_gpio_flags(np, "power-gpio", 0, &pwr_flags); + //ts->tp_select_pin = of_get_named_gpio_flags(np, "tp-select-gpio", 0, &tp_select_flags); + if (of_property_read_u32(np, "max-x", &val)) { + dev_err(&client->dev, "no max-x defined\n"); + return -EINVAL; + } + //ts->abs_x_max = val; + if (of_property_read_u32(np, "max-y", &val)) { + dev_err(&client->dev, "no max-y defined\n"); + return -EINVAL; + } + //ts->abs_y_max = val; + ts->pendown =PEN_RELEASE; + ts->client = client; + + + INIT_WORK(&ts->work, goodix_ts_work_func); + ts->client = client; + spin_lock_init(&ts->irq_lock); // 2.6.39 later + // ts->irq_lock = SPIN_LOCK_UNLOCKED; // 2.6.39 & before +#if GTP_ESD_PROTECT + ts->clk_tick_cnt = 2 * HZ; // HZ: clock ticks in 1 second generated by system + GTP_DEBUG("Clock ticks for an esd cycle: %d", ts->clk_tick_cnt); + spin_lock_init(&ts->esd_lock); + // ts->esd_lock = SPIN_LOCK_UNLOCKED; +#endif + i2c_set_clientdata(client, ts); + + ts->gtp_rawdiff_mode = 0; + + ret = gtp_request_io_port(ts); + if (ret < 0) + { + GTP_ERROR("GTP request IO port failed."); + //return ret; + goto probe_init_error_requireio; + } +/* + if(gpio_get_value(ts->tp_select_pin))//WGJ + { + printk("tp 11111111111111111111111111111 WGJ\n\n"); + mGtp_X_Reverse = FALSE; + mGtp_Y_Reverse = TRUE; + } + else//DPT + { + printk("tp 00000000000000000000000000000 DPT\n\n"); + mGtp_X_Reverse = TRUE;//FALSE; + mGtp_Y_Reverse = TRUE; + } + */ +#if GTP_COMPATIBLE_MODE + gtp_get_chip_type(ts); + + if (CHIP_TYPE_GT9F == ts->chip_type) + { + ret = gtp_gt9xxf_init(ts->client); + if (FAIL == ret) + { + GTP_INFO("Failed to init GT9XXF."); + } + } +#endif + + ret = gtp_i2c_test(client); + if (ret < 0) + { + printk("<%s>_%d I2C communication ERROR!\n", __func__, __LINE__); + goto probe_init_error; + } + + ret = gtp_read_version(client, &version_info); + if (ret < 0) + { + GTP_ERROR("Read version failed."); + } + + ret = gtp_init_panel(ts); + if (ret < 0) + { + GTP_ERROR("GTP init panel failed."); + //ts->abs_x_max = GTP_MAX_WIDTH; + //ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; + } + + // Create proc file system + gt91xx_config_proc = proc_create(GT91XX_CONFIG_PROC_FILE, 0666, NULL, &config_proc_ops); + if (gt91xx_config_proc == NULL) + { + GTP_ERROR("create_proc_entry %s failed\n", GT91XX_CONFIG_PROC_FILE); + } + else + { + GTP_INFO("create proc entry %s success", GT91XX_CONFIG_PROC_FILE); + } + +#if GTP_AUTO_UPDATE + ret = gup_init_update_proc(ts); + if (ret < 0) + { + GTP_ERROR("Create update thread error."); + } +#endif + + ret = gtp_request_input_dev(ts); + if (ret < 0) + { + GTP_ERROR("GTP request input dev failed"); + } + ret = gtp_request_irq(ts); + if (ret < 0) + { + GTP_INFO("GTP works in polling mode."); + } + else + { + GTP_INFO("GTP works in interrupt mode."); + } + + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + +#if GTP_CREATE_WR_NODE + init_wr_node(client); +#endif + +#if GTP_ESD_PROTECT + gtp_esd_switch(client, SWITCH_ON); +#endif + return 0; + +probe_init_error: + printk(" <%s>_%d prob error !!!!!!!!!!!!!!!\n", __func__, __LINE__); + GTP_GPIO_FREE(ts->rst_pin); + GTP_GPIO_FREE(ts->irq_pin); +probe_init_error_requireio: + kfree(ts); + return ret; +} + + +/******************************************************* +Function: + Goodix touchscreen driver release function. +Input: + client: i2c device struct. +Output: + Executive outcomes. 0---succeed. +*******************************************************/ +static int goodix_ts_remove(struct i2c_client *client) +{ + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + GTP_DEBUG_FUNC(); + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&ts->early_suspend); +#endif + +#if GTP_CREATE_WR_NODE + uninit_wr_node(); +#endif + +#if GTP_ESD_PROTECT + destroy_workqueue(gtp_esd_check_workqueue); +#endif + + if (ts) + { + if (ts->use_irq) + { + //GTP_GPIO_AS_INPUT(GTP_INT_PORT); + + gpio_direction_input(ts->irq_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + + GTP_GPIO_FREE(ts->irq_pin); + free_irq(client->irq, ts); + } + else + { + hrtimer_cancel(&ts->timer); + } + } + + GTP_INFO("GTP driver removing..."); + i2c_set_clientdata(client, NULL); + input_unregister_device(ts->input_dev); + kfree(ts); + + return 0; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +/******************************************************* +Function: + Early suspend function. +Input: + h: early_suspend struct. +Output: + None. +*******************************************************/ +static void goodix_ts_early_suspend(struct early_suspend *h) +{ + struct goodix_ts_data *ts; + s8 ret = -1; + ts = container_of(h, struct goodix_ts_data, early_suspend); + + GTP_DEBUG_FUNC(); + + GTP_INFO("System suspend."); + + ts->gtp_is_suspend = 1; +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + +#if GTP_GESTURE_WAKEUP + ret = gtp_enter_doze(ts); +#else + if (ts->use_irq) + { + gtp_irq_disable(ts); + } + else + { + hrtimer_cancel(&ts->timer); + } + ret = gtp_enter_sleep(ts); +#endif + if (ret < 0) + { + GTP_ERROR("GTP early suspend failed."); + } + // to avoid waking up while not sleeping + // delay 48 + 10ms to ensure reliability + msleep(58); +} + +/******************************************************* +Function: + Late resume function. +Input: + h: early_suspend struct. +Output: + None. +*******************************************************/ +static void goodix_ts_late_resume(struct early_suspend *h) +{ + struct goodix_ts_data *ts; + s8 ret = -1; + ts = container_of(h, struct goodix_ts_data, early_suspend); + + GTP_DEBUG_FUNC(); + + GTP_INFO("System resume."); + + ret = gtp_wakeup_sleep(ts); + +#if GTP_GESTURE_WAKEUP + doze_status = DOZE_DISABLED; +#endif + + if (ret < 0) + { + GTP_ERROR("GTP later resume failed."); + } +#if (GTP_COMPATIBLE_MODE) + if (CHIP_TYPE_GT9F == ts->chip_type) + { + // do nothing + } + else +#endif + { + gtp_send_cfg(ts->client); + } + + if (ts->use_irq) + { + gtp_irq_enable(ts); + } + else + { + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + } + + ts->gtp_is_suspend = 0; +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); +#endif +} +#endif + +#if GTP_ESD_PROTECT +s32 gtp_i2c_read_no_rst(struct i2c_client *client, u8 *buf, s32 len) +{ + struct i2c_msg msgs[2]; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc. + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + //msgs[1].scl_rate = 300 * 1000; + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2)break; + retries++; + } + if ((retries >= 5)) + { + GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d!", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + } + return ret; +} + +s32 gtp_i2c_write_no_rst(struct i2c_client *client,u8 *buf,s32 len) +{ + struct i2c_msg msg; + s32 ret = -1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1)break; + retries++; + } + if((retries >= 5)) + { + GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d!", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); + } + return ret; +} +/******************************************************* +Function: + switch on & off esd delayed work +Input: + client: i2c device + on: SWITCH_ON / SWITCH_OFF +Output: + void +*********************************************************/ +void gtp_esd_switch(struct i2c_client *client, s32 on) +{ + struct goodix_ts_data *ts; + + ts = i2c_get_clientdata(client); + spin_lock(&ts->esd_lock); + + if (SWITCH_ON == on) // switch on esd + { + if (!ts->esd_running) + { + ts->esd_running = 1; + spin_unlock(&ts->esd_lock); + GTP_INFO("Esd started"); + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt); + } + else + { + spin_unlock(&ts->esd_lock); + } + } + else // switch off esd + { + if (ts->esd_running) + { + ts->esd_running = 0; + spin_unlock(&ts->esd_lock); + GTP_INFO("Esd cancelled"); + cancel_delayed_work_sync(>p_esd_check_work); + } + else + { + spin_unlock(&ts->esd_lock); + } + } +} + +/******************************************************* +Function: + Initialize external watchdog for esd protect +Input: + client: i2c device. +Output: + result of i2c write operation. + 1: succeed, otherwise: failed +*********************************************************/ +static s32 gtp_init_ext_watchdog(struct i2c_client *client) +{ + u8 opr_buffer[3] = {0x80, 0x41, 0xAA}; + GTP_DEBUG("[Esd]Init external watchdog"); + return gtp_i2c_write_no_rst(client, opr_buffer, 3); +} + +/******************************************************* +Function: + Esd protect function. + External watchdog added by meta, 2013/03/07 +Input: + work: delayed work +Output: + None. +*******************************************************/ +static void gtp_esd_check_func(struct work_struct *work) +{ + s32 i; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; + u8 esd_buf[5] = {0x80, 0x40}; + + GTP_DEBUG_FUNC(); + + ts = i2c_get_clientdata(i2c_connect_client); + + if (ts->gtp_is_suspend) + { + GTP_INFO("Esd suspended!"); + return; + } + + for (i = 0; i < 3; i++) + { + ret = gtp_i2c_read_no_rst(ts->client, esd_buf, 4); + + GTP_DEBUG("[Esd]0x8040 = 0x%02X, 0x8041 = 0x%02X", esd_buf[2], esd_buf[3]); + if ((ret < 0)) + { + // IIC communication problem + continue; + } + else + { + if ((esd_buf[2] == 0xAA) || (esd_buf[3] != 0xAA)) + { + // IC works abnormally.. + u8 chk_buf[4] = {0x80, 0x40}; + + gtp_i2c_read_no_rst(ts->client, chk_buf, 4); + + GTP_DEBUG("[Check]0x8040 = 0x%02X, 0x8041 = 0x%02X", chk_buf[2], chk_buf[3]); + + if ((chk_buf[2] == 0xAA) || (chk_buf[3] != 0xAA)) + { + i = 3; + break; + } + else + { + continue; + } + } + else + { + // IC works normally, Write 0x8040 0xAA, feed the dog + esd_buf[2] = 0xAA; + gtp_i2c_write_no_rst(ts->client, esd_buf, 3); + break; + } + } + } + if (i >= 3) + { + #if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + if (ts->rqst_processing) + { + GTP_INFO("Request processing, no esd recovery"); + } + else + { + GTP_ERROR("IC working abnormally! Process esd recovery."); + esd_buf[0] = 0x42; + esd_buf[1] = 0x26; + esd_buf[2] = 0x01; + esd_buf[3] = 0x01; + esd_buf[4] = 0x01; + gtp_i2c_write_no_rst(ts->client, esd_buf, 5); + msleep(50); + gtp_esd_recovery(ts->client); + } + } + else + #endif + { + GTP_ERROR("IC working abnormally! Process reset guitar."); + esd_buf[0] = 0x42; + esd_buf[1] = 0x26; + esd_buf[2] = 0x01; + esd_buf[3] = 0x01; + esd_buf[4] = 0x01; + gtp_i2c_write_no_rst(ts->client, esd_buf, 5); + msleep(50); + gtp_reset_guitar(ts->client, 50); + msleep(50); + gtp_send_cfg(ts->client); + } + } + + if(!ts->gtp_is_suspend) + { + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt); + } + else + { + GTP_INFO("Esd suspended!"); + } + return; +} +#endif + +static const struct i2c_device_id goodix_ts_id[] = { + { GTP_I2C_NAME, 0 }, + { } +}; + +static struct of_device_id goodix_ts_dt_ids[] = { + { .compatible = "goodix,gt9xx" }, + { } +}; + +static struct i2c_driver goodix_ts_driver = { + .probe = goodix_ts_probe, + .remove = goodix_ts_remove, +//#ifndef CONFIG_HAS_EARLYSUSPEND +#ifdef CONFIG_HAS_EARLYSUSPEND + .suspend = goodix_ts_early_suspend, + .resume = goodix_ts_late_resume, +#endif + .id_table = goodix_ts_id, + .driver = { + .name = GTP_I2C_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(goodix_ts_dt_ids), + }, +}; + +/******************************************************* +Function: + Driver Install function. +Input: + None. +Output: + Executive Outcomes. 0---succeed. +********************************************************/ +static int goodix_ts_init(void) +{ + s32 ret; + + GTP_DEBUG_FUNC(); + GTP_INFO("GTP driver installing..."); + goodix_wq = create_singlethread_workqueue("goodix_wq"); + if (!goodix_wq) + { + GTP_ERROR("Creat workqueue failed."); + return -ENOMEM; + } +#if GTP_ESD_PROTECT + INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); + gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); +#endif + ret = i2c_add_driver(&goodix_ts_driver); + return ret; +} + +/******************************************************* +Function: + Driver uninstall function. +Input: + None. +Output: + Executive Outcomes. 0---succeed. +********************************************************/ +static void goodix_ts_exit(void) +{ + GTP_DEBUG_FUNC(); + GTP_INFO("GTP driver exited."); + i2c_del_driver(&goodix_ts_driver); + if (goodix_wq) + { + destroy_workqueue(goodix_wq); + } +} + +//late_initcall(goodix_ts_init); +module_init(goodix_ts_init); + +module_exit(goodix_ts_exit); + +MODULE_DESCRIPTION("GTP Series Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h new file mode 100644 index 000000000000..b3f4ac7e69b3 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/gt9xx.h @@ -0,0 +1,413 @@ +/* drivers/input/touchscreen/gt9xx.h + * + * 2010 - 2013 Goodix Technology. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef _GOODIX_GT9XX_H_ +#define _GOODIX_GT9XX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +//#include + +#define CONFIG_8_9 0 +#define DEBUG_SWITCH 0 + +//***************************PART1:ON/OFF define******************************* +#define GTP_CUSTOM_CFG 0 +#if CONFIG_8_9 +#define GTP_CHANGE_X2Y 1 +#define GTP_X_REVERSE_ENABLE 0 +#define GTP_Y_REVERSE_ENABLE 1 +#else +#define GTP_CHANGE_X2Y 1 +#define GTP_X_REVERSE_ENABLE 1 +#define GTP_Y_REVERSE_ENABLE 0 +#endif +#define GTP_DRIVER_SEND_CFG 1 +#define GTP_HAVE_TOUCH_KEY 0 +#define GTP_POWER_CTRL_SLEEP 0 +#define GTP_ICS_SLOT_REPORT 0 + +#define GTP_AUTO_UPDATE 0 // auto update fw by .bin file as default +#define GTP_HEADER_FW_UPDATE 0 // auto update fw by gtp_default_FW in gt9xx_firmware.h, function together with GTP_AUTO_UPDATE +#define GTP_AUTO_UPDATE_CFG 0 // auto update config by .cfg file, function together with GTP_AUTO_UPDATE + +#define GTP_COMPATIBLE_MODE 0 // compatible with GT9XXF + +#define GTP_CREATE_WR_NODE 0 +#define GTP_ESD_PROTECT 0 // esd protection with a cycle of 2 seconds + +#define GTP_WITH_PEN 0 +#define GTP_PEN_HAVE_BUTTON 0 // active pen has buttons, function together with GTP_WITH_PEN + +#define GTP_GESTURE_WAKEUP 0 // gesture wakeup + +#define GTP_DEBUG_ON 1 +#define GTP_DEBUG_ARRAY_ON 0 +#define GTP_DEBUG_FUNC_ON 0 + +#define PEN_DOWN 1 +#define PEN_RELEASE 0 +#define PEN_DOWN_UP 2 //fjp + +#if GTP_COMPATIBLE_MODE +typedef enum +{ + CHIP_TYPE_GT9 = 0, + CHIP_TYPE_GT9F = 1, +} CHIP_TYPE_T; +#endif + +struct goodix_ts_data { + spinlock_t irq_lock; + struct i2c_client *client; + struct input_dev *input_dev; + struct hrtimer timer; + struct work_struct work; + //struct early_suspend early_suspend; + s32 irq_is_disable; + s32 use_irq; + u16 abs_x_max; + u16 abs_y_max; + u8 max_touch_num; + u8 int_trigger_type; + u8 green_wake_mode; + u8 enter_update; + u8 gtp_is_suspend; + u8 gtp_rawdiff_mode; + u8 gtp_cfg_len; + u8 fixed_cfg; + u8 fw_error; + u8 pnl_init_error; + + //add by Daniel(yc) + int irq; + int irq_pin; + int pwr_pin; + int rst_pin; + int tp_select_pin; + int rst_val; + bool pendown; + unsigned long irq_flags; + +#if GTP_WITH_PEN + struct input_dev *pen_dev; +#endif + +#if GTP_ESD_PROTECT + spinlock_t esd_lock; + u8 esd_running; + s32 clk_tick_cnt; +#endif + +#if GTP_COMPATIBLE_MODE + u16 bak_ref_len; + s32 ref_chk_fs_times; + s32 clk_chk_fs_times; + CHIP_TYPE_T chip_type; + u8 rqst_processing; + u8 is_950; +#endif + +}; + +extern u16 show_len; +extern u16 total_len; + + +//*************************** PART2:TODO define ********************************** +// STEP_1(REQUIRED): Define Configuration Information Group(s) +// Sensor_ID Map: +/* sensor_opt1 sensor_opt2 Sensor_ID + GND GND 0 + VDDIO GND 1 + NC GND 2 + GND NC/300K 3 + VDDIO NC/300K 4 + NC NC/300K 5 +*/ +// TODO: define your own default or for Sensor_ID == 0 config here. +// The predefined one is just a sample config, which is not suitable for your tp in most cases. +/* +#define CTP_CFG_GROUP1 {\ + 0x46,0xE0,0x01,0x56,0x03,0x02,0xF1,0x01,0x02,0x44,\ + 0x00,0x04,0x46,0x32,0x03,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x11,0x04,0x26,0x01,0x74,0x77,0x05,0x00,0x88,\ + 0x64,0x0F,0xD0,0x07,0x05,0x07,0x00,0xDA,0x01,0x1D,\ + 0x00,0x01,0x08,0x08,0x33,0x33,0x5D,0xAA,0x00,0x00,\ + 0x00,0x32,0x96,0x54,0xC5,0x03,0x02,0x00,0x00,0x01,\ + 0xC8,0x38,0x00,0xA0,0x45,0x00,0x91,0x57,0x00,0x80,\ + 0x6C,0x00,0x61,0x87,0x00,0x61,0x10,0x0B,0x08,0x00,\ + 0x51,0x40,0x30,0xFF,0xFF,0x00,0x04,0x00,0x00,0x1E,\ + 0x0A,0x00,0x06,0x0B,0x09,0x0F,0x08,0x07,0x01,0x03,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x03,0x02,0x05,0x04,0x07,0x06,0x09,\ + 0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0xFF,0xFF,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,\ + 0x00,0x00,0x08,0x09,0x0A,0x0D,0x0E,0xFF,0xFF,0xFF,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0xFF,0x0B,0x0C,0xFF,0xFF,0xFF,0xFF,\ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\ + 0xFF,0xFF,0xFF,0xFF,0x6C,0xB2,0xB2,0x6C,0xFF,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,\ + 0x8C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ + 0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x01\ + } +*/ + +/* +//WGJ10187_GT9271_Config_20140623_104014_0X41.cfg +#define CTP_CFG_GROUP1 {\ + 0x41,0xB0,0x04,0x80,0x07,0x05,0xF5,0x00,0x01,0x08,0x28,0x0F,0x64,0x32,0x03, \ + 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x19,0x1E,0x14,0x8F,0x2F,0x99, \ + 0x41,0x43,0x15,0x0E,0x00,0x00,0x00,0x22,0x03,0x1D,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x06,0x00,0x2D,0x62,0x94,0xC5,0x02,0x07,0x17,0x00,0x04, \ + 0x92,0x30,0x00,0x86,0x39,0x00,0x7F,0x42,0x00,0x79,0x4D,0x00,0x74,0x5A,0x00, \ + 0x74,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,0x17,0x16,0x15,0x14,0x11,0x10,0x0F,0x0E, \ + 0x0D,0x0C,0x09,0x08,0x07,0x06,0x05,0x04,0x01,0x00,0xFF,0xFF,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x07,0x08,0x0A,0x0C, \ + 0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22, \ + 0x21,0x20,0x1F,0x1E,0x1C,0x1B,0x19,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x3D,0x01 \ + } +*/ + +//WGJ10187_GT9271_Config_20140623_104014_0X41.cfg +#define CTP_CFG_GROUP1 {\ + 0x41,0x80,0x07,0xB0,0x04,0x0A,0x05,0x00,0x01,0x08,0x28,0x0F,0x50,0x32,0x03, \ + 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8F,0x2F,0x99, \ + 0x2B,0x2D,0x31,0x0D,0x00,0x00,0x00,0x01,0x03,0x1D,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x55,0x94,0xC5,0x02,0x07,0x00,0x00,0x00, \ + 0x8C,0x26,0x00,0x7B,0x2D,0x00,0x6C,0x36,0x00,0x61,0x41,0x00,0x58,0x4E,0x00, \ + 0x58,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,0x01,0x04,0x05,0x06,0x07,0x08,0x09, \ + 0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0xFF,0xFF,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x13,0x12,0x11,0x10,0x0F,0x0D,0x0C, \ + 0x0A,0x08,0x07,0x06,0x04,0x02,0x00,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22, \ + 0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00, \ + 0x00,0x00,0x00,0x00,0xB5,0x01 \ + } + +// TODO: define your config for Sensor_ID == 1 here, if needed +#define CTP_CFG_GROUP2 {\ + } + +// TODO: define your config for Sensor_ID == 2 here, if needed +#define CTP_CFG_GROUP3 {\ + } + +// TODO: define your config for Sensor_ID == 3 here, if needed +#define CTP_CFG_GROUP4 {\ +} +// TODO: define your config for Sensor_ID == 4 here, if needed +#define CTP_CFG_GROUP5 {\ + } + +// TODO: define your config for Sensor_ID == 5 here, if needed +#define CTP_CFG_GROUP6 {\ + } + +// STEP_2(REQUIRED): Customize your I/O ports & I/O operations +/* +#define GTP_RST_PORT S5PV210_GPJ3(6) +#define GTP_INT_PORT S5PV210_GPH1(3) +#define GTP_INT_IRQ gpio_to_irq(GTP_INT_PORT) +#define GTP_INT_CFG S3C_GPIO_SFN(0xF) + +#define GTP_GPIO_AS_INPUT(pin) do{\ + gpio_direction_input(pin);\ + s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);\ + }while(0) +#define GTP_GPIO_AS_INT(pin) do{\ + GTP_GPIO_AS_INPUT(pin);\ + s3c_gpio_cfgpin(pin, GTP_INT_CFG);\ + }while(0) +*/ +#define GTP_GPIO_GET_VALUE(pin) gpio_get_value(pin) +#define GTP_GPIO_OUTPUT(pin,level) gpio_direction_output(pin,level) +#define GTP_GPIO_REQUEST(pin, label) gpio_request(pin, label) +#define GTP_GPIO_FREE(pin) gpio_free(pin) +#define GTP_IRQ_TAB {IRQ_TYPE_EDGE_RISING, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH} + +// STEP_3(optional): Specify your special config info if needed +#if GTP_CUSTOM_CFG + #define GTP_MAX_HEIGHT 800 + #define GTP_MAX_WIDTH 480 + #define GTP_INT_TRIGGER 0 // 0: Rising 1: Falling +#else + #define GTP_MAX_HEIGHT 4096 + #define GTP_MAX_WIDTH 4096 + #define GTP_INT_TRIGGER 1 +#endif +#define GTP_MAX_TOUCH 10 + +// STEP_4(optional): If keys are available and reported as keys, config your key info here +#if GTP_HAVE_TOUCH_KEY + #define GTP_KEY_TAB {KEY_MENU, KEY_HOME, KEY_BACK} +#endif + +//***************************PART3:OTHER define********************************* +#define GTP_DRIVER_VERSION "V2.2<2014/01/14>" +#define GTP_I2C_NAME "Goodix-TS" +#define GT91XX_CONFIG_PROC_FILE "gt9xx_config" +#define GTP_POLL_TIME 10 +#define GTP_ADDR_LENGTH 2 +#define GTP_CONFIG_MIN_LENGTH 186 +#define GTP_CONFIG_MAX_LENGTH 240 +#define FAIL 0 +#define SUCCESS 1 +#define SWITCH_OFF 0 +#define SWITCH_ON 1 + +//******************** For GT9XXF Start **********************// +#define GTP_REG_BAK_REF 0x99D0 +#define GTP_REG_MAIN_CLK 0x8020 +#define GTP_REG_CHIP_TYPE 0x8000 +#define GTP_REG_HAVE_KEY 0x804E +#define GTP_REG_MATRIX_DRVNUM 0x8069 +#define GTP_REG_MATRIX_SENNUM 0x806A + +#define GTP_FL_FW_BURN 0x00 +#define GTP_FL_ESD_RECOVERY 0x01 +#define GTP_FL_READ_REPAIR 0x02 + +#define GTP_BAK_REF_SEND 0 +#define GTP_BAK_REF_STORE 1 +#define CFG_LOC_DRVA_NUM 29 +#define CFG_LOC_DRVB_NUM 30 +#define CFG_LOC_SENS_NUM 31 + +#define GTP_CHK_FW_MAX 40 +#define GTP_CHK_FS_MNT_MAX 300 +#define GTP_BAK_REF_PATH "/data/gtp_ref.bin" +#define GTP_MAIN_CLK_PATH "/data/gtp_clk.bin" +#define GTP_RQST_CONFIG 0x01 +#define GTP_RQST_BAK_REF 0x02 +#define GTP_RQST_RESET 0x03 +#define GTP_RQST_MAIN_CLOCK 0x04 +#define GTP_RQST_RESPONDED 0x00 +#define GTP_RQST_IDLE 0xFF + +//******************** For GT9XXF End **********************// +// Registers define +#define GTP_READ_COOR_ADDR 0x814E +#define GTP_REG_SLEEP 0x8040 +#define GTP_REG_SENSOR_ID 0x814A +#define GTP_REG_CONFIG_DATA 0x8047 +#define GTP_REG_VERSION 0x8140 + +#define RESOLUTION_LOC 3 +#define TRIGGER_LOC 8 + +#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0])) + +// Log define +#define GTP_ERROR(fmt,arg...) printk("<<-GTP-ERROR->> "fmt"\n",##arg) +#if DEBUG_SWITCH +#define GTP_INFO(fmt,arg...) printk("<<-GTP-INFO->> "fmt"\n",##arg) +#define GTP_DEBUG(fmt,arg...) do{\ + if(GTP_DEBUG_ON)\ + printk("<<-GTP-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\ + }while(0) +#define GTP_DEBUG_ARRAY(array, num) do{\ + s32 i;\ + u8* a = array;\ + if(GTP_DEBUG_ARRAY_ON)\ + {\ + printk("<<-GTP-DEBUG-ARRAY->>\n");\ + for (i = 0; i < (num); i++)\ + {\ + printk("%02x ", (a)[i]);\ + if ((i + 1 ) %10 == 0)\ + {\ + printk("\n");\ + }\ + }\ + printk("\n");\ + }\ + }while(0) +#define GTP_DEBUG_FUNC() do{\ + if(GTP_DEBUG_FUNC_ON)\ + printk(" <<-GTP-FUNC->> Func:%s@Line:%d\n",__func__,__LINE__);\ + }while(0) + +#else +#define GTP_INFO(fmt,arg...) +#define GTP_DEBUG(fmt,arg...) +#define GTP_DEBUG_ARRAY(array, num) +#define GTP_DEBUG_FUNC() +#endif +#define GTP_SWAP(x, y) do{\ + typeof(x) z = x;\ + x = y;\ + y = z;\ + }while (0) + +//*****************************End of Part III******************************** +#define TRUE 1 +#define FALSE 0 + +bool m89or101 = TRUE; +bool mGtpChange_X2Y = TRUE; //GTP_CHANGE_X2Y 1 +bool mGtp_X_Reverse = FALSE; //GTP_X_REVERSE_ENABLE +bool mGtp_Y_Reverse = TRUE; //GTP_Y_REVERSE_ENABLE +/* +u8 gtp_dat[] = +{ + //TODO:Puts your update firmware data here! +#if CONFIG_8_9 +#include "WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg" //<1920, 1200> 8.9 +#else +#include "WGJ10187_GT9271_Config_20140623_104014_0X41.cfg" //<1200, 1920> 10.1 +#endif +}; +*/ +u8 gtp_dat_8_9[] = +{ + //TODO:Puts your update firmware data here! +//#include "WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg" //<1920, 1200> 8.9 +//#include "WGJ10162_GT9271_Config_20140820_182456.cfg" //<1920, 1200> 8.9 +#include "WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg" +}; + + +u8 gtp_dat_10_1[] = +{ + //TODO:Puts your update firmware data here! +#include "WGJ10187_GT9271_Config_20140623_104014_0X41.cfg" //<1200, 1920> 10.1 +}; + +#endif /* _GOODIX_GT9XX_H_ */ diff --git a/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h b/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h new file mode 100644 index 000000000000..b796661a3453 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/gt9xx_firmware.h @@ -0,0 +1,2341 @@ +/* Copyright Statement: +*This firmware are protected under relevant copyright laws,this information contained +*herein is confidential and proprietary to Goodix. +* +*GOODIX (C) 2013. All rights reserved. +* +*WARNING:The GTP_COMPATIBLE_MODE part of this file was generated by the specialized tools, +*please do not modify it manually! +* +*/ + + +#ifndef _GT9XX_FIRMWARE_H_ +#define _GT9XX_FIRMWARE_H_ + +#if GTP_HEADER_FW_UPDATE +unsigned char gtp_default_FW[] = +{ + //TODO:Puts your update firmware data here! +//#include "WGJ10187_GT9271_Config_20140623_104014_0X41.cfg" +//#include "WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg" +}; +#endif + +/* +*[HW INFO]00900600 +*[PID]910 +*[VID]1010 +*[GENERATED]2013/08/27 20:59:13 +*/ +#if GTP_COMPATIBLE_MODE +unsigned char gtp_default_FW_fl[] = { +/* 0x00,0x90,0x06,0x00,0x39,0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x80,0x00, + 0x55,0x40,0xf8,0x86,0x98,0x71,0x69,0xf0,0x0c,0xc1,0x78,0x1e,0xd2,0x48,0x88,0x58, + 0xa3,0x41,0xd2,0xeb,0xb2,0x63,0x32,0xe0,0x1d,0xc9,0xf8,0x75,0x15,0x6e,0x01,0x8d, + 0x05,0x02,0xf9,0x87,0x18,0x7a,0x12,0x6b,0x4d,0x21,0x17,0xd5,0x94,0x6d,0x09,0x0d, + 0x87,0x03,0x4f,0xc2,0x13,0x0b,0x09,0x7b,0x4d,0x4b,0xf9,0x74,0x99,0xe8,0x38,0xa8, + 0x3d,0xc9,0xa2,0x4d,0x13,0x74,0xab,0x47,0xe3,0xe5,0xee,0x49,0xdf,0xd2,0x00,0x54, + 0x8b,0xfb,0x48,0x94,0x1f,0x67,0x8b,0x8e,0xbe,0xe4,0xce,0x59,0x55,0x46,0xbe,0x86, + 0x40,0x06,0x98,0xb8,0x77,0xa0,0x85,0x9e,0x2b,0x05,0x99,0xfd,0xb1,0xd4,0xf6,0xb9, + 0x40,0x9c,0x50,0x1d,0x4e,0x1a,0x0d,0x82,0xe9,0x9a,0x5d,0x17,0xba,0x86,0x47,0xac, + 0x2c,0x48,0x26,0x6e,0x59,0x38,0x10,0xda,0x0f,0x4c,0x15,0xce,0xda,0x40,0x9a,0x3c, + 0x2f,0x49,0xd0,0x18,0xba,0x2f,0x20,0x3a,0x55,0x69,0xea,0x5c,0x4f,0x62,0x98,0xcc, + 0x0f,0x7a,0xfb,0x8f,0x99,0x52,0x17,0x7d,0x2f,0xb4,0x91,0xcf,0xde,0x32,0x48,0x6c, + 0xaf,0x48,0x83,0x51,0xdb,0x24,0x9b,0x29,0xd9,0x49,0xda,0xc2,0x2e,0x29,0xa5,0xcc, + 0x28,0x7a,0x6d,0x4e,0x1e,0xd7,0x04,0xc8,0xa1,0x4f,0x8a,0x74,0x39,0x55,0xf0,0xa7, + 0xb2,0x61,0xcf,0x1d,0x5d,0xa0,0x5c,0x41,0xa2,0xfc,0x2f,0x1e,0x1b,0x62,0x79,0xa2, + 0xb9,0xf5,0x44,0xc9,0xf3,0x59,0x55,0x44,0x82,0x7f,0xc5,0x40,0xdc,0x6d,0xac,0x19, + 0x8f,0x26,0xb6,0xb5,0xa4,0xe2,0x03,0xd6,0x83,0xde,0xfb,0x6d,0x93,0x1e,0x04,0x80, + 0x78,0xf8,0x88,0x83,0x91,0xba,0x2c,0xc0,0xd0,0x58,0x9c,0xb7,0x63,0x58,0xde,0xb0, + 0x26,0xe9,0x6a,0x64,0x85,0x3e,0xe5,0xc2,0xef,0x34,0x5c,0x69,0x02,0xaa,0x4f,0x28, + 0x82,0x11,0x7b,0x67,0x32,0x38,0x64,0xd3,0x6e,0x37,0x48,0x25,0xc7,0x77,0x02,0x1d, + 0x24,0xe6,0x65,0xb8,0xb7,0x22,0x64,0xc3,0x6f,0x36,0xa8,0x48,0xc1,0x06,0x22,0x10, + 0x21,0x5d,0x8e,0x84,0x36,0x1d,0x74,0xa0,0x61,0x4f,0xe4,0x60,0x50,0x10,0x34,0xe2, + 0xd7,0x1a,0x06,0x36,0xd3,0xca,0x5c,0xb0,0x79,0xf8,0x4f,0xe7,0x5d,0x84,0x7b,0xe9, + 0x6a,0xdc,0xfc,0xb6,0x82,0x92,0x8b,0x97,0x6d,0xd0,0xdd,0xf1,0x3a,0x35,0x16,0xd1, + 0xcb,0x3d,0x7e,0x37,0x5a,0x1d,0xca,0xc0,0x42,0xa8,0xe3,0x50,0x9b,0x54,0xc6,0x69, + 0x14,0xb3,0x86,0xca,0xc4,0x3e,0x3f,0xfb,0xec,0x44,0xdf,0x82,0x37,0xc3,0x79,0x69, + 0x44,0x1c,0x3a,0x8c,0x9a,0x7b,0x66,0x9f,0xf8,0xf5,0x43,0x0c,0x12,0xea,0x37,0x37, + 0xc3,0xd3,0x0f,0x21,0x59,0x35,0xbe,0xfa,0x64,0x06,0x68,0x29,0xc1,0x20,0x51,0xfc, + 0xcc,0xb0,0x14,0x4a,0x65,0x72,0xbf,0xf3,0x7c,0xf7,0x0c,0x86,0xea,0xee,0x38,0xf1, + 0xdb,0xcf,0x1f,0xcc,0x46,0x93,0x68,0xd4,0x44,0x83,0xa8,0x4d,0x93,0x3f,0x5b,0xab, + 0x13,0x73,0xdd,0xcf,0x30,0x0c,0xbc,0x70,0x8e,0xd4,0xd8,0xd5,0x33,0xcc,0x39,0xf1, + 0x62,0x34,0xd0,0xa3,0xcc,0x91,0xfb,0x96,0xd9,0xd5,0x81,0x4d,0x11,0x7d,0x29,0x1d, + 0xa8,0x57,0xf1,0xf4,0x34,0x99,0x7f,0x13,0x1e,0xd6,0xe1,0xc4,0xd8,0x3f,0x20,0x02, + 0x04,0xc0,0xff,0x26,0x67,0xa0,0x20,0x62,0xc4,0xc6,0x2f,0xd9,0xb5,0x1f,0x28,0x12, + 0x05,0xc1,0x68,0xdf,0xca,0x5c,0x3c,0xb5,0x64,0x56,0x82,0xc9,0xa2,0xa3,0x79,0xfa, + 0x84,0x82,0x7e,0x07,0xe3,0xae,0xac,0xd1,0x25,0x19,0x4a,0xa3,0xa1,0x01,0x29,0x8f, + 0x85,0x83,0x22,0x77,0xcd,0xa5,0x8d,0xcc,0x86,0x30,0xa7,0x31,0x34,0x5c,0xa5,0xb2, + 0x3d,0xb5,0x1f,0x2d,0x9b,0x52,0x50,0xd5,0x0e,0xd5,0xd0,0xb8,0xbf,0x95,0x10,0x39, + 0x6f,0x88,0xb6,0xb4,0x57,0x98,0xc2,0x8d,0xc8,0x68,0xbf,0x4f,0x51,0xc6,0xa1,0xe3, + 0x39,0x0b,0xe9,0x43,0x1e,0x58,0x7d,0xda,0xf5,0x1d,0xee,0x87,0xd4,0x6d,0x7f,0x31, + 0xe7,0x78,0xdb,0x67,0x54,0x08,0xee,0xec,0xa4,0xc3,0x7d,0x04,0xbb,0xe8,0x22,0x0a, + 0x0c,0xc8,0xae,0x79,0x7f,0x37,0x62,0x59,0x54,0x42,0x4d,0xd0,0x5a,0x01,0x2a,0x1a, + 0x0d,0xc9,0xe7,0x19,0x9d,0xe7,0x8e,0x5a,0x45,0x19,0x65,0x62,0x2e,0xee,0x23,0x96, + 0x8c,0x8a,0xdb,0xf2,0x90,0xe8,0xf4,0xd5,0x2d,0xac,0x02,0x0b,0xab,0x5f,0xb6,0xda, + 0x8d,0x8b,0x6b,0xfe,0xa1,0xad,0x94,0xeb,0x4c,0x6a,0xe4,0x0b,0x15,0x01,0x1c,0x4c, + 0xef,0x0f,0x42,0x3d,0xbd,0x2f,0x0b,0x1b,0x3a,0xda,0x32,0xce,0xec,0x67,0x14,0x77, + 0xc7,0xe7,0x95,0x4d,0x10,0xbc,0x2e,0xe8,0x4f,0x60,0xae,0xda,0x3c,0xef,0x93,0xcf, + 0xac,0x14,0x04,0xcb,0xbc,0x34,0x7b,0xb2,0x41,0x63,0xf7,0x8d,0x86,0xac,0x7a,0x28, + 0xbf,0xe1,0xd5,0x77,0x10,0x09,0x2b,0x0b,0x4f,0x49,0x6c,0x8c,0x5b,0x64,0x01,0x82, + 0x4f,0xb4,0xc4,0x84,0x6a,0x1d,0x90,0xec,0xbb,0xed,0x7a,0x5b,0x76,0x2b,0xac,0x92, + 0x94,0x1c,0x82,0x12,0x1e,0x43,0x94,0x9f,0x1e,0xc9,0xe5,0x57,0x90,0x0e,0xda,0x87, + 0xa4,0xf7,0x3d,0x65,0xb2,0x99,0xde,0xd4,0x64,0x05,0x85,0x23,0xd9,0xd7,0xc9,0xb4, + 0x16,0x1e,0x72,0x3a,0xb3,0x98,0xe2,0xb2,0xe3,0x9a,0x51,0xc4,0x9f,0x05,0xa4,0x63, + 0x00,0x1f,0x2c,0x86,0x32,0x9d,0x54,0x68,0x67,0x57,0xf2,0xde,0x5f,0x6e,0x36,0xe9, + 0x21,0x96,0xfb,0x25,0xb3,0x3e,0x26,0x64,0x75,0x18,0x10,0x85,0x0b,0x73,0xee,0xfe, + 0x4d,0xd2,0xdf,0x37,0x86,0x17,0x99,0x90,0x9a,0xcd,0xf3,0xcf,0xdf,0x65,0xc9,0x93, + 0xe3,0x33,0xd8,0x66,0xc7,0x18,0x67,0xf1,0x54,0x7a,0x02,0x84,0x83,0x7e,0xc2,0xad, + 0x2d,0xf8,0x4b,0x7f,0x8e,0x28,0x20,0xd8,0xee,0xdc,0xec,0xac,0xcf,0x51,0x2f,0x45, + 0xce,0x9d,0x56,0x6e,0x35,0xb6,0xb2,0x4a,0x92,0xd6,0xe7,0x47,0x1a,0xf8,0xdd,0x89, + 0xa4,0xd5,0x4f,0xa5,0x3e,0xb2,0x3b,0x49,0x6e,0xde,0xe5,0x25,0xfd,0x7a,0x3a,0xe9, + 0x23,0xfe,0x07,0xa1,0x3a,0xce,0x05,0x9c,0x4e,0xbe,0x85,0x3d,0x1f,0xe0,0xb6,0xf6, + 0xe6,0xff,0x42,0xac,0xd5,0x5d,0xe5,0x9a,0xee,0xca,0xd6,0x7c,0xfe,0xf4,0x10,0xdc, + 0x4c,0x98,0xd0,0xeb,0xdc,0xb4,0xcc,0xc6,0x7f,0x18,0xde,0xfb,0xb7,0x0c,0xf0,0x3b, + 0xac,0x6f,0xfd,0xd2,0x9f,0xb7,0x7f,0xfe,0xdd,0xb5,0xf1,0x1e,0xc6,0x01,0xbc,0x28, + 0x23,0x92,0x3e,0xad,0x54,0xce,0xe8,0x88,0xd3,0xb1,0xea,0x84,0x70,0x79,0x00,0x40, + 0x3f,0x8d,0xda,0x06,0xa3,0xb9,0xaa,0xdf,0xa9,0x71,0xa8,0x20,0xd5,0xb2,0x58,0xba, + 0xa0,0xfe,0x9a,0x15,0x17,0x22,0x08,0xbd,0x4a,0x5a,0xd9,0xd4,0x59,0xa3,0x7f,0x2c, + 0xda,0x40,0xe0,0x45,0xa2,0xdf,0xfd,0xbe,0xc3,0xc0,0xc8,0xcc,0x35,0xa0,0xe5,0x82, + 0xbd,0x0b,0x98,0xd5,0xdb,0x38,0x45,0x47,0xbd,0xbc,0xc0,0xdc,0x34,0x71,0xfa,0xbf, + 0x8d,0x82,0xd6,0x26,0xa9,0x99,0xe8,0x80,0x46,0x69,0x77,0xa5,0xbb,0x4e,0x11,0xbd, + 0x66,0x0c,0x08,0xf4,0x19,0xd8,0x85,0x06,0xbc,0xd8,0x5c,0x06,0xb8,0x4f,0x41,0x01, + 0xde,0xfb,0x6d,0xce,0x91,0x56,0x2c,0x13,0x31,0x5d,0x3d,0xf7,0x84,0x6e,0x4c,0xb9, + 0xa4,0xca,0xb1,0x4c,0x13,0x48,0xf5,0xee,0xc2,0x07,0x19,0xd5,0x92,0x25,0x00,0x17, + 0x34,0xbc,0x5f,0x7a,0x79,0x08,0x28,0x8d,0xbf,0x0a,0x18,0xcc,0x3e,0x6e,0x34,0x31, + 0x86,0x12,0x18,0x9e,0x99,0x22,0x4a,0x04,0x48,0x41,0x5e,0xb9,0x1a,0x9a,0x95,0x72, + 0xab,0xd7,0xdb,0x24,0xb8,0x98,0x43,0xc1,0x69,0x08,0xb3,0x74,0x79,0xb5,0xd0,0x8f, + 0x88,0x6b,0xb3,0x98,0x97,0xa1,0x21,0xd1,0xa2,0x84,0x5f,0xbb,0x97,0x96,0x20,0x4d, + 0x09,0x4c,0xc1,0x0f,0xd6,0x37,0x6e,0xed,0xbb,0xed,0x82,0x16,0xd5,0xc1,0x92,0xae, + 0x38,0xb6,0x4a,0x3f,0xa0,0x36,0x48,0x72,0x4d,0x4e,0xd2,0x6c,0xa7,0x27,0xc1,0x6d, + 0x6b,0x15,0x1e,0x3b,0xeb,0x25,0x6b,0x58,0x6b,0xf1,0x1b,0xe9,0xf8,0x9f,0xf1,0xa6, + 0x06,0x89,0x16,0xc9,0x7a,0xb0,0x4b,0x1b,0x34,0x0d,0xfb,0x6c,0xdd,0x6c,0x7a,0xa8, + 0xdd,0x19,0xdd,0x86,0xd7,0x31,0xd4,0x00,0x53,0x5d,0x1f,0x2e,0x71,0xd0,0x34,0x63, + 0x11,0x17,0xd7,0x26,0x06,0xc7,0x14,0xb4,0xbd,0x60,0xf6,0x36,0x93,0x6a,0x06,0x05, + 0x8a,0x62,0x40,0x04,0x83,0x26,0xea,0x66,0x2a,0x63,0xaf,0x5a,0xf6,0x59,0x7f,0x79, + 0x00,0x91,0xd0,0x47,0xc6,0x33,0x7d,0x03,0xd2,0x5e,0xa5,0x4a,0xd2,0xd3,0x34,0x39, + 0x46,0x61,0xf8,0x32,0x34,0x37,0x66,0x1f,0x51,0x9f,0xee,0x17,0x7d,0x36,0xd0,0x0f, + 0xc2,0x0e,0xf2,0x10,0xbe,0xc3,0xb9,0x00,0xe3,0x4a,0xe7,0x33,0x9a,0xff,0x0c,0xef, + 0xed,0x54,0x82,0xa7,0xf0,0xc9,0xed,0x0e,0x6f,0xab,0x85,0x4d,0xf4,0x75,0x12,0x27, + 0x90,0xbc,0x85,0xd1,0x1a,0xf8,0x43,0x13,0x71,0x5f,0x1d,0x55,0x8f,0x7f,0x7e,0x0c, + 0x0a,0x03,0x59,0x34,0x3e,0x1b,0xe9,0x98,0x3c,0x1a,0xcf,0x5d,0x3c,0x7c,0x1b,0xd8, + 0x2d,0xed,0x50,0xea,0xb6,0xbf,0x66,0x3c,0x10,0x34,0x64,0x54,0x52,0xb4,0x3f,0x76, + 0x27,0xbc,0x41,0xce,0xfe,0x21,0x47,0x44,0x01,0x6b,0x95,0xdf,0xcb,0xd1,0x1a,0x69, + 0xfd,0xba,0x8f,0xdd,0xb5,0xf9,0x1a,0xd8,0xb3,0x5d,0xe0,0x7a,0x10,0xd8,0xfc,0x0f, + 0xe8,0x95,0x06,0x6c,0x08,0x7e,0x81,0x6c,0x48,0xee,0xd4,0xd3,0x39,0x78,0xb1,0x5c, + 0x00,0x93,0x02,0x58,0x19,0xcc,0xb2,0x6a,0x3d,0x55,0xdc,0x03,0xa7,0xf7,0x4f,0xc4, + 0x4b,0xd1,0x97,0xb7,0x35,0x93,0x6f,0x79,0x01,0x74,0xd1,0x69,0xd8,0x6d,0x6f,0xdc, + 0x98,0xa4,0xc7,0xd9,0x12,0xf0,0xdb,0x8b,0x00,0x75,0x86,0x10,0xbd,0xb2,0x06,0x2b, + 0x38,0x0b,0x77,0x26,0xb5,0xd2,0x0e,0x0b,0x2f,0xcf,0x74,0xa0,0x02,0xe6,0x7c,0x17, + 0xa4,0x2e,0x44,0x84,0x19,0xa9,0x6e,0x41,0x27,0x48,0x43,0xd4,0xd0,0x93,0x66,0x32, + 0xe8,0xc0,0xf8,0x05,0xd0,0x6f,0xb1,0x11,0x49,0x64,0x91,0x76,0x75,0x68,0xbf,0x23, + 0xbe,0xc1,0x6b,0xff,0xa6,0x68,0x19,0xd9,0x2c,0xcc,0x11,0xbe,0x57,0x64,0x70,0x82, + 0x1e,0x79,0xb9,0xab,0xf3,0x5b,0x20,0x32,0xcb,0x32,0xfa,0x76,0xa9,0x10,0x3e,0xf2, + 0x1d,0xc6,0x68,0x15,0xdf,0x38,0x30,0x8d,0x41,0xc6,0xba,0x89,0xbe,0x8f,0xcd,0xd1, + 0x96,0x8e,0xda,0x00,0x48,0xae,0x73,0x88,0xc0,0xc5,0x39,0xe3,0xf4,0xec,0x09,0xe1, + 0xb4,0x8a,0xff,0x35,0xff,0xaa,0x28,0x34,0x19,0x47,0x55,0xe8,0xd4,0x07,0x72,0xe5, + 0xad,0x77,0x27,0x06,0x7b,0xbf,0x28,0x28,0xde,0xc2,0xeb,0x4c,0x7f,0x4a,0x62,0x1e, + 0x85,0x17,0xa4,0x7c,0x5c,0x89,0x63,0xdb,0x8b,0xc3,0x56,0x4d,0x00,0x1f,0x1d,0x26, + 0x03,0x7c,0x4b,0x82,0x1e,0xae,0xb6,0x58,0xf4,0xa6,0xea,0xd3,0x39,0x15,0x4b,0xa9, + 0xbe,0x86,0xd3,0x1d,0xdd,0x26,0xbf,0x1b,0xd3,0x59,0xe1,0x3d,0x6e,0x42,0x3b,0xb7, + 0xe9,0x41,0x9d,0x7e,0x86,0xee,0x8d,0x01,0xc3,0x4a,0x41,0xab,0x83,0x31,0xaa,0xfa, + 0x91,0x56,0xd1,0x2d,0x14,0xef,0xd6,0xe8,0x5f,0xc7,0x36,0x0d,0x50,0x83,0x3a,0xb4, + 0xfd,0xc9,0xb3,0x1a,0x98,0xad,0x72,0xab,0xd8,0x33,0x5c,0x6d,0xde,0x1a,0x5c,0xa6, + 0xda,0x14,0xbb,0x63,0x9e,0xef,0x39,0x10,0x13,0xc0,0x99,0x53,0xde,0x8f,0x35,0x06, + 0x06,0xeb,0x84,0x92,0xd5,0xab,0x46,0x4a,0xc5,0x2f,0xd3,0x56,0xf4,0xef,0x3d,0x16, + 0x5c,0xfc,0x96,0x7e,0x3a,0xfe,0xdb,0x41,0x51,0xca,0x3f,0xc9,0x15,0xb1,0x1b,0xaa, + 0x07,0x67,0x79,0x71,0xa4,0x7d,0x99,0x4b,0xdb,0x1f,0xab,0x17,0x66,0xfa,0x77,0x7a, + 0xcd,0x72,0xcd,0x95,0xe0,0xbe,0xe1,0xd5,0x16,0xc3,0x7d,0x17,0xc5,0xfb,0xe6,0x2a, + 0x55,0x59,0x24,0x66,0x35,0x36,0xb4,0x42,0x27,0x54,0xe2,0x84,0x1e,0xf9,0x68,0x46, + 0x03,0x8e,0x0b,0x16,0x33,0x98,0x34,0x62,0x8c,0xbf,0xb4,0xfe,0x71,0xf6,0x89,0x51, + 0xa6,0x9e,0x1a,0xb4,0xf5,0xda,0x0b,0x27,0xe0,0xd5,0x88,0x9c,0x7b,0xc0,0xcb,0xb5, + 0x28,0x11,0x17,0x53,0x95,0x05,0x91,0x61,0xd3,0xdf,0xb9,0x88,0x54,0x47,0xe6,0x2a, + 0x93,0x35,0x8c,0x5e,0x60,0xb9,0x8e,0x51,0xe1,0x55,0x34,0x68,0x66,0xe3,0xab,0xe9, + 0x1d,0x96,0xce,0x9c,0x1e,0xb4,0x45,0x52,0x1a,0x14,0xcc,0x56,0xdc,0xe2,0xb2,0x69, + 0xaa,0xb9,0x9f,0x8b,0x39,0x58,0x50,0x50,0x0d,0x4c,0x69,0x5b,0xbe,0xfc,0x0f,0x47, + 0x9e,0x40,0x50,0xd8,0xb3,0xba,0xc2,0x7c,0x14,0xad,0x62,0x49,0xce,0x30,0x66,0x8a, + 0x32,0xd1,0xde,0x5e,0xc1,0x11,0xf2,0x98,0x85,0xb6,0xd6,0x09,0x9f,0x63,0xd4,0x3a, + 0x23,0x86,0x68,0xe0,0x34,0x41,0x00,0x2a,0x5c,0xa6,0xee,0xda,0x4c,0xef,0x25,0x2d, + 0x9d,0xe5,0xab,0x88,0x60,0xb4,0xb7,0x4b,0xdc,0x5e,0xcb,0xcf,0xae,0xd3,0xc9,0x3d, + 0x9c,0xf5,0x54,0x80,0x3f,0xbf,0xc5,0x6b,0x87,0xd2,0x47,0xef,0x58,0xbe,0xa8,0x38, + 0xe1,0x1b,0xcd,0x44,0x92,0x24,0x5a,0xbd,0x4e,0x06,0xd6,0x03,0xf1,0x25,0xe0,0x0d, + 0x13,0x4e,0xa2,0x91,0x1f,0xab,0x20,0xe0,0x1d,0x5a,0x3e,0xc0,0x59,0x7a,0xa3,0xe7, + 0x05,0xb0,0xc9,0x67,0xd3,0x2e,0xd6,0xa3,0x40,0xda,0xaf,0xa3,0x88,0x79,0xa1,0x81, + 0x04,0xa3,0x0d,0xfd,0x15,0x6c,0x39,0xd7,0x64,0x2d,0x5a,0x53,0x2e,0x6a,0x02,0xa6, + 0x31,0xd6,0x98,0x5d,0xb3,0x46,0xa8,0xe2,0xc2,0x9e,0x2f,0x5a,0x3e,0x26,0x36,0x84, + 0x05,0xed,0x4a,0x36,0x9e,0x47,0x20,0xf2,0xc3,0xbf,0xdd,0x07,0x6b,0x6a,0xf9,0xa9, + 0x1a,0xc7,0x21,0xd5,0xb0,0xa4,0x69,0xe3,0x2c,0x0b,0xca,0x5e,0x50,0x65,0x5a,0x23, + 0x7c,0x45,0x0d,0xd3,0xd7,0x21,0x61,0xf3,0x2d,0x2a,0x89,0x6c,0x8b,0x61,0xaa,0x1c, + 0x8d,0x28,0xe2,0x0e,0x43,0x25,0x70,0x39,0x49,0x28,0x16,0xc4,0x94,0xa8,0xf5,0xf5, + 0x01,0x52,0x72,0x7a,0x94,0xaf,0x3a,0x65,0xe8,0xc3,0x8e,0x5a,0xae,0x72,0xf8,0xf4, + 0x9f,0xb1,0xc9,0x10,0xab,0x3e,0x49,0x38,0x6f,0x4c,0x83,0x34,0x80,0x71,0x79,0xf0, + 0x06,0x49,0x89,0xdd,0x95,0xa0,0x9c,0xd1,0xa6,0x04,0x8b,0x5b,0xad,0x24,0xdc,0xbc, + 0xe3,0xa6,0xe2,0xe8,0xbb,0x83,0x2a,0xea,0xca,0x45,0x82,0x71,0xb3,0x3d,0x6c,0xba, + 0x44,0xa2,0x5b,0xde,0x9b,0x76,0x22,0xfa,0xcb,0x64,0xe0,0x9e,0xdb,0x5d,0x65,0x9d, + 0x29,0x8b,0xd6,0x6a,0x3b,0x81,0x6b,0xeb,0x24,0xc3,0xab,0xef,0xf8,0xde,0x02,0x2a, + 0xc0,0xae,0xf3,0xb5,0x5b,0xe0,0x63,0xfb,0x25,0x60,0xfd,0x54,0xef,0x69,0x64,0x82, + 0x39,0x1d,0xa4,0x6d,0xfb,0xef,0xb0,0xd2,0xc3,0xdb,0xac,0x21,0x7e,0xfa,0x6c,0x92, + 0x34,0x1c,0x4a,0x7c,0x41,0xaa,0x26,0x00,0xcf,0xfe,0xda,0x25,0x42,0x50,0x65,0x82, + 0xed,0x1d,0x5a,0xcd,0xb6,0x11,0xfd,0x9d,0x0b,0x16,0x52,0x56,0x99,0x73,0x6d,0x92, + 0xb0,0x1c,0x7e,0x6c,0x46,0x48,0xb9,0x41,0x1e,0x5c,0x25,0x4a,0xc2,0x72,0x24,0xc2, + 0x63,0x19,0x23,0x84,0x7a,0x76,0x50,0x06,0x83,0x4f,0x92,0x96,0x5c,0xfc,0x86,0x3a, + 0xc2,0x2e,0x0c,0xb1,0x1e,0x3f,0x24,0x4d,0x83,0xaa,0x64,0xa6,0x5d,0x16,0x4f,0xc9, + 0x01,0xbb,0x9d,0x12,0x32,0xd6,0x95,0x07,0x1f,0xfd,0xf5,0x1a,0xc1,0xe4,0x94,0x36, + 0x12,0xb6,0x4d,0x13,0xc3,0x31,0xee,0x13,0xe5,0x8e,0x97,0xb7,0xae,0x88,0x66,0x8a, + 0x35,0x15,0x82,0x60,0xb8,0x03,0x4c,0xd8,0x14,0x47,0x2e,0x52,0xf7,0x8e,0xd5,0x98, + 0x56,0x92,0x9e,0x18,0x61,0xbd,0x1c,0x84,0x9e,0x5d,0x31,0xbe,0x79,0x8d,0x67,0x8a, + 0xb1,0x15,0x71,0x71,0xb8,0xc1,0x2d,0x4f,0xb4,0xd1,0x9f,0xbc,0x25,0xa7,0x50,0x99, + 0x96,0x3b,0xef,0x9f,0x9c,0x36,0xb2,0x51,0x61,0xd0,0x81,0xbf,0xed,0xd6,0x7e,0x41, + 0x85,0xb1,0xe6,0xa4,0x9b,0xe3,0x73,0x6a,0x6b,0xbb,0xe8,0x88,0x12,0x71,0x15,0x3f, + 0x9a,0xbc,0xb1,0xa2,0xd0,0xdc,0x56,0x57,0x8a,0x52,0xe4,0x59,0x8c,0xf1,0x09,0x23, + 0x4b,0x25,0xa7,0xcf,0xd7,0x33,0x0d,0xe8,0x49,0x58,0x58,0x12,0x5e,0x6e,0x77,0x50, + 0x04,0x19,0xf0,0x2e,0x8b,0x3e,0xf7,0xd7,0x69,0x5c,0x0b,0x2d,0x5a,0x87,0x60,0x38, + 0xe5,0x9b,0xa2,0xe0,0x96,0xa4,0x88,0xc2,0x40,0x40,0x8a,0xce,0x7c,0xaf,0x56,0x4b, + 0x36,0xb5,0x50,0x94,0x95,0x2b,0x87,0x75,0x87,0x31,0xe1,0x3d,0xb0,0x3e,0x85,0xe5, + 0x94,0xcd,0xed,0x65,0xa7,0x69,0xc9,0x51,0x3b,0x1d,0xe8,0x29,0xb3,0xc2,0xd1,0xfb, + 0xb2,0x4c,0x91,0xff,0xe2,0x6c,0x71,0x0e,0xa6,0xd7,0x55,0xa8,0xd4,0x43,0xaa,0xaa, + 0x71,0xcb,0x54,0x24,0x25,0x60,0x08,0x24,0xba,0x88,0xa0,0x7f,0x35,0xc4,0x56,0x9a, + 0x4e,0x6f,0x17,0x25,0x2f,0xc9,0x42,0x9a,0x55,0x8a,0xed,0x90,0x64,0x27,0x5b,0xe6, + 0x94,0xc9,0x1b,0xaf,0x56,0x6b,0xb3,0xe7,0xd5,0xda,0x89,0x8f,0x9c,0x4b,0x71,0x5e, + 0x08,0x2a,0x0e,0x17,0xd5,0x0a,0x20,0x63,0x60,0xdc,0xc7,0x5b,0x70,0xa5,0x7b,0x0a, + 0xab,0x93,0xc2,0x0c,0x13,0xa5,0xa1,0xae,0x6e,0xc9,0x1d,0x50,0x81,0xec,0x4a,0x18, + 0x1c,0x84,0xf3,0x09,0xba,0xb2,0x10,0x07,0xa6,0x8d,0x45,0xd6,0x0d,0x14,0x36,0xfb, + 0x80,0xc5,0xfa,0xee,0x7b,0x27,0x69,0xd4,0x6f,0x41,0xb1,0xc7,0x8a,0xa7,0x4b,0x18, + 0xc8,0x84,0x32,0xe7,0x73,0xf0,0x01,0x8b,0x2f,0x64,0x43,0xbd,0x5d,0x32,0x2b,0xd8, + 0x0e,0x21,0x73,0xd1,0x1f,0x5c,0xd3,0x8c,0xcc,0xc8,0x3c,0xc4,0x58,0xe4,0xec,0xa7, + 0x03,0xcf,0xd4,0x77,0x90,0x5b,0x68,0x6b,0x7c,0xbf,0x3a,0xa7,0x38,0xf6,0xad,0xd9, + 0x82,0x86,0xba,0x59,0x7b,0x51,0xb9,0x09,0x8d,0x3e,0xf3,0xeb,0xac,0x61,0x26,0x5c, + 0x87,0x9c,0xa3,0x4e,0x76,0xfe,0x83,0x1d,0x30,0xd4,0xf8,0x19,0x24,0xaa,0xfd,0x81, + 0x1f,0x08,0xee,0x1b,0x07,0xb1,0xb4,0x44,0x57,0x3b,0xaa,0x61,0xb6,0x80,0x74,0xbc, + 0xa7,0x95,0x6b,0x7e,0x1d,0xfe,0x44,0x5a,0x62,0x9e,0x39,0x5e,0x55,0xbc,0xe5,0x03, + 0x54,0xd0,0x5d,0xa0,0x15,0x38,0x8d,0xb3,0x25,0x58,0xbd,0xa2,0x9f,0x5b,0x22,0xf1, + 0xab,0xf1,0x19,0xf5,0xf6,0x43,0x5d,0xb1,0xe6,0xde,0x42,0x86,0x9c,0x71,0x44,0x8b, + 0x87,0x4b,0xf7,0xdf,0x30,0xbf,0xf0,0x00,0xe4,0xd0,0x8a,0xaa,0x49,0xd4,0x13,0xac, + 0x14,0x0d,0xd4,0x25,0x0f,0xd0,0xfc,0x34,0x2f,0xd3,0x26,0x1e,0xef,0x38,0x05,0xc1, + 0xb7,0x9b,0x0b,0x45,0x36,0x1f,0x2a,0x81,0xc4,0x1b,0x42,0x96,0xf0,0xaf,0x95,0xa8, + 0xb7,0xd8,0xd5,0x24,0x83,0x4c,0x5d,0x0a,0x46,0xb4,0x00,0x1f,0xa1,0xba,0x6c,0x37, + 0x22,0xde,0xff,0x85,0xdb,0xb5,0x7c,0x17,0x87,0xe2,0x90,0xdf,0xdf,0x7c,0x16,0x1f, + 0xab,0x4b,0x6d,0x78,0xbf,0xbd,0x40,0x73,0xe2,0x5f,0xaa,0xd8,0x8a,0x04,0xe1,0x09, + 0x2c,0x91,0x8d,0x5f,0xe0,0xa1,0x21,0xc9,0x84,0xd7,0xee,0xa9,0x1b,0xe1,0x17,0x1e, + 0xa3,0xf9,0x37,0xfd,0x93,0xfd,0x37,0xfb,0xe1,0x70,0x2c,0x4c,0xb6,0xe0,0x06,0xc8, + 0x33,0x91,0xfc,0x32,0x3e,0xfe,0x96,0xe3,0x4c,0xec,0xe6,0xf7,0x3a,0x53,0x56,0x21, + 0xda,0x86,0x01,0xad,0x53,0xf2,0x46,0x08,0x90,0xdb,0xfc,0x0d,0x6a,0x48,0x9c,0x49, + 0x2e,0xc6,0x7c,0x71,0xb8,0xbd,0xbe,0x69,0x6e,0x2f,0x7e,0x9d,0x05,0xfa,0x27,0x3d, + 0x56,0x8f,0xee,0xac,0x8f,0xf0,0x5f,0xc7,0x4e,0x26,0xe1,0xc0,0x96,0xbd,0x99,0x8c, + 0x82,0x03,0x6f,0xea,0x90,0xb8,0x70,0x96,0x15,0x4d,0x7f,0xcf,0xd0,0xfc,0xc8,0xf0, + 0x1e,0x02,0xa8,0x42,0x91,0xaf,0x45,0xad,0xee,0xcc,0x9c,0x28,0x04,0x68,0x85,0xf1, + 0x88,0x0d,0xa1,0xc3,0x10,0x7d,0xbd,0xc9,0x00,0x84,0xb0,0xc7,0x2d,0x6b,0x0c,0xe8, + 0x03,0x07,0xa9,0x7c,0x11,0x6c,0xe6,0xb5,0xea,0xa0,0x35,0x3f,0x72,0xde,0x7a,0x1e, + 0xf9,0x45,0xbf,0x2f,0xce,0x2b,0x81,0x93,0xce,0x49,0x6b,0xc1,0xa5,0xd9,0xf3,0x42, + 0x23,0x4b,0xb0,0xae,0xae,0xf1,0xc8,0xb0,0x5b,0x78,0xa3,0x1b,0x7d,0x1a,0x7e,0xab, + 0x69,0x09,0xf3,0x7d,0x4b,0x85,0x2f,0x83,0x6e,0x4b,0x05,0x9e,0x23,0x05,0x0a,0xaf, + 0x7b,0x08,0xb1,0x67,0x64,0x12,0x4f,0x77,0x70,0x83,0x99,0xa2,0xdf,0x51,0x59,0x6a, + 0xc9,0x6a,0xa2,0xa9,0x98,0x2a,0x28,0xc0,0x37,0x87,0x80,0x28,0xba,0xe8,0xcc,0xfe, + 0x3a,0xed,0xaa,0x92,0x99,0x3c,0xe0,0xd0,0x22,0x86,0x3a,0x53,0x39,0x29,0xc7,0xd9, + 0x84,0x11,0xa3,0x3b,0x18,0x77,0x4a,0xc1,0x2f,0x5a,0x93,0xed,0x62,0xc5,0xb1,0xde, + 0x4b,0x2b,0xab,0xd3,0x19,0x66,0x1a,0xcf,0xfa,0xf0,0xe9,0x2d,0xd9,0x61,0x1c,0xaa, + 0x1a,0xf1,0xba,0x23,0xc6,0x23,0x2a,0x60,0xaf,0x0d,0xda,0x7c,0xe7,0x5a,0x35,0x18, + 0x47,0x1b,0x59,0x07,0x21,0xf2,0x4c,0x7e,0xf8,0x00,0xe0,0x97,0xec,0x2c,0xd4,0xb6, + 0x73,0x6d,0xf1,0x12,0x53,0x21,0xa6,0x97,0xde,0x73,0x2e,0x70,0x49,0xc3,0x03,0x4d, + 0x40,0x00,0xf1,0xe5,0x68,0x72,0x25,0x9b,0xdb,0x02,0x82,0xf5,0x26,0x9e,0x24,0x79, + 0x81,0x9a,0xb9,0x5a,0xdd,0x34,0xfb,0x4e,0xe0,0x83,0xae,0x23,0x54,0x8d,0xb8,0xf2, + 0xde,0x9d,0x28,0xe6,0xbf,0x54,0xa2,0xb9,0xc2,0x34,0xe4,0xeb,0xa1,0x7e,0x82,0x69, + 0x90,0x5d,0x82,0x8e,0x34,0x66,0x34,0xa7,0x30,0x36,0xb2,0x47,0x10,0x67,0x47,0x8c, + 0x92,0x71,0x77,0x9d,0x6e,0x0c,0xf2,0x5f,0x61,0x10,0xaf,0x9d,0x24,0xc7,0xe8,0x5f, + 0xdd,0x99,0x64,0x4b,0xcb,0x62,0xe0,0x02,0x46,0x5e,0x2d,0x96,0xa3,0x0b,0x22,0x97, + 0xc2,0xa3,0xad,0x94,0x63,0x9a,0x75,0x06,0x73,0x90,0x63,0xc9,0x8c,0xa8,0xa6,0x3f, + 0xa4,0xa6,0xfe,0x4e,0x5b,0x72,0x50,0x8a,0x8a,0x12,0x45,0x14,0x51,0x74,0x32,0xa3, + 0x71,0x88,0x6d,0xab,0x2d,0xe8,0x25,0xd5,0x5d,0x88,0x09,0x0b,0x0a,0x14,0xfe,0xee, + 0xa5,0x9e,0xbd,0x62,0x80,0x37,0xaa,0xa1,0x8f,0x48,0xee,0x9e,0x0c,0xa7,0x08,0x7e, + 0xab,0x1d,0x2e,0x92,0xb5,0xa4,0xa2,0xb1,0xce,0x49,0x6d,0xbc,0x41,0x84,0x01,0x49, + 0xa4,0x91,0xb8,0x62,0x9c,0x0e,0xf8,0x47,0x68,0x41,0x07,0x17,0xf8,0x0a,0xd4,0xfb, + 0xea,0xeb,0x76,0xff,0x15,0x27,0xf0,0x57,0x69,0x50,0xb8,0x5f,0x39,0x84,0x66,0xcd, + 0x2c,0xac,0xf9,0x42,0xc1,0xa1,0x53,0x83,0x02,0x18,0xa9,0xb6,0x54,0xe0,0xe2,0xaa, + 0xf5,0xe2,0xb6,0x0a,0xda,0xe1,0x5f,0x1e,0x4f,0x40,0x30,0xe9,0xe5,0xe0,0x29,0x69, + 0x61,0xfe,0xa2,0x37,0xe6,0x90,0x7e,0x0f,0x03,0x51,0xfe,0x48,0x6b,0x7c,0x75,0x47, + 0x5c,0x5e,0x32,0xaf,0x62,0x60,0xf8,0x1b,0x0b,0xc3,0x3e,0x97,0x61,0x77,0x28,0x17, + 0x37,0x62,0x80,0x48,0x94,0xc3,0xca,0x64,0x5e,0x8c,0x07,0x03,0x78,0x48,0xd0,0x90, + 0x85,0x1a,0x93,0xf8,0xf4,0xc7,0x8f,0xb6,0x6e,0x28,0xba,0xd3,0xeb,0xc1,0x99,0xfc, + 0x21,0x73,0x84,0x01,0x00,0xc6,0xf4,0x65,0xc0,0x8c,0x11,0x02,0x56,0x52,0x11,0xc3, + 0xfb,0x98,0x1d,0x5d,0x5c,0xe7,0x60,0x2f,0x30,0x8c,0x3b,0x3c,0x51,0xb7,0x98,0x66, + 0x8b,0x92,0xd2,0x7f,0xc3,0x07,0xe0,0x11,0xca,0x95,0x0f,0x18,0x78,0x3b,0xd1,0x76, + 0x82,0x2b,0x93,0x72,0x7c,0xaa,0x06,0x90,0xeb,0xf8,0x2c,0x8c,0xce,0x86,0x1e,0x5e, + 0x4d,0x89,0x99,0xbc,0x77,0x35,0x0f,0x64,0x7f,0xa0,0xce,0xc2,0x2d,0x7b,0x52,0xf3, + 0x6a,0xb7,0xe8,0xa6,0x13,0xa7,0x9d,0x57,0x74,0xb0,0xd4,0xf7,0x18,0x47,0xb7,0xec, + 0xa9,0x23,0x8b,0x54,0xd5,0xcc,0x33,0x55,0xeb,0x89,0x16,0x4c,0x78,0xe2,0x52,0x0b, + 0xcd,0x8f,0x84,0x18,0x8c,0x35,0xd5,0xd4,0xcd,0x01,0x41,0x3a,0xf0,0xa8,0x5b,0x0e, + 0x6c,0x21,0x88,0xed,0x30,0xb6,0x8d,0x22,0x2b,0xda,0x33,0x58,0xf8,0x9d,0xd9,0xdb, + 0x2e,0x8d,0x85,0x18,0x4c,0x55,0x85,0x32,0x6a,0xdb,0x9e,0x39,0x49,0x8f,0x92,0x99, + 0xef,0xe0,0x5d,0x73,0xe1,0x71,0x76,0xeb,0xa7,0x88,0x17,0x05,0xc8,0xe4,0x11,0x24, + 0x2d,0x60,0xc5,0x04,0x31,0x31,0xde,0xd6,0xa4,0xa9,0xc7,0xf0,0xe4,0x1d,0x04,0xb0, + 0x6f,0x18,0x37,0xb1,0x47,0xcd,0x66,0x98,0x4a,0x63,0x75,0x15,0x40,0x71,0x2d,0xfd, + 0x44,0x02,0xc5,0x59,0xb1,0x03,0x42,0x99,0x26,0xc0,0x92,0x1d,0x3e,0xd3,0x32,0xe0, + 0x4c,0x9d,0x8a,0x80,0xa5,0x2c,0x15,0xa4,0xb4,0xb4,0x83,0x44,0x50,0x7d,0x14,0x7a, + 0x33,0xde,0x18,0xdc,0xfc,0xf5,0xd3,0x5c,0xe5,0x58,0xbd,0xc9,0x09,0x0e,0x7c,0xaf, + 0x03,0xf7,0x8b,0x80,0x65,0xbd,0x89,0xaa,0x47,0xb7,0x9e,0x4d,0x9f,0xfd,0xed,0xff, + 0x26,0xd1,0x84,0xcd,0x7c,0xd7,0x18,0xb5,0x71,0xb7,0x06,0x12,0x02,0x6e,0x4a,0x20, + 0x95,0xf1,0xde,0x9c,0x8d,0xa1,0xd1,0x00,0x86,0x45,0x75,0x9d,0xe8,0x4b,0x14,0x38, + 0xce,0xd1,0xc0,0x7d,0x37,0x8f,0x4e,0xca,0x94,0x81,0x99,0x1c,0x2b,0x5b,0x5d,0xeb, + 0x05,0x3a,0x45,0xe3,0x04,0xb6,0x0e,0x88,0x32,0xd9,0xce,0x69,0x05,0xeb,0x2b,0xd5, + 0x84,0xd7,0x1c,0xd7,0xcf,0x2a,0x05,0x88,0x07,0x46,0x85,0x39,0x16,0x4b,0xe4,0xa7, + 0x2a,0xb3,0x8d,0x51,0x89,0x66,0x0e,0x8d,0x8b,0xc8,0x62,0x54,0x89,0x4e,0x77,0x07, + 0x4e,0x66,0x0e,0x90,0xb1,0x34,0x1b,0xbc,0xf9,0xbd,0xc5,0xc0,0xa7,0x26,0xa8,0x0f, + 0xef,0xa6,0x9e,0x8d,0x23,0x8e,0xd8,0x45,0x6c,0xc0,0x8c,0x25,0xfd,0x5a,0xd7,0x3b, + 0xe5,0xeb,0x4b,0xb8,0x1a,0xab,0x07,0x9c,0x4a,0xcb,0x38,0x6c,0x5e,0xc6,0x20,0xcd, + 0x8f,0x8f,0x43,0x2c,0xfe,0x40,0x0d,0x84,0xba,0xd3,0x0b,0x9c,0xaf,0xa3,0x2e,0xa9, + 0xab,0xac,0x96,0x91,0x84,0xa6,0xdb,0x18,0x8f,0x6c,0x43,0x61,0x94,0xf2,0x1f,0xef, + 0x10,0xbe,0x4c,0x94,0x4d,0x13,0x45,0xb0,0x5e,0xd1,0xcd,0xa5,0x45,0xbf,0x11,0xdd, + 0x46,0xfb,0xae,0xa0,0xc3,0x40,0x54,0x53,0x87,0xd0,0x46,0x61,0xfa,0xf0,0x3d,0x9b, + 0x05,0x0f,0x27,0xa0,0xe4,0xa3,0xb2,0xa4,0x42,0x84,0x90,0x64,0x54,0x48,0x98,0x7a, + 0x20,0xf1,0xa7,0xec,0x11,0x63,0xac,0x63,0xcd,0xed,0x8e,0x56,0x7e,0x40,0x38,0x9b, + 0xc9,0x0d,0x36,0xb4,0x49,0x5f,0x2b,0xc4,0x21,0x24,0xea,0xa7,0xda,0x16,0x32,0x56, + 0x8f,0x9c,0x0a,0x39,0x49,0x00,0x61,0x62,0x4d,0x5f,0x7c,0x14,0x2f,0x42,0x4c,0xba, + 0xeb,0xa7,0xda,0x45,0x31,0x64,0xfc,0xff,0x41,0xd6,0x10,0xe1,0x84,0x91,0x76,0xe0, + 0xc1,0x05,0x8b,0x14,0x4f,0x3e,0x66,0xd4,0xce,0xb3,0xc3,0x0f,0xd3,0xd5,0x27,0x95, + 0x69,0xe5,0xdd,0xce,0x94,0xac,0x6f,0xb0,0x80,0xb9,0x87,0x5b,0xb0,0x24,0x37,0xe5, + 0x8a,0x98,0x90,0x33,0x6c,0x8a,0x11,0xf5,0xc5,0xcd,0xe7,0xd5,0x5c,0xc1,0x3d,0x8d, + 0xf3,0xd5,0xd2,0x85,0x0e,0x33,0x3c,0x2e,0xd9,0x47,0xaf,0x6d,0x5e,0x40,0xf5,0xd2, + 0xa2,0x48,0x0a,0xdc,0x1f,0x92,0x62,0x6b,0xc5,0x55,0x2a,0x7d,0xc8,0x2b,0xc7,0xf7, + 0x75,0x68,0x5c,0x7b,0x15,0xac,0xa7,0x7a,0x44,0xe6,0xc5,0x6c,0xff,0x42,0x32,0x79, + 0xd5,0xf6,0x09,0x99,0xda,0xf8,0x35,0x3f,0x58,0x0a,0xd1,0x3d,0x30,0xc1,0x44,0x75, + 0xe3,0xc6,0x92,0x8b,0xc4,0x24,0xd5,0x2f,0xa3,0xef,0x41,0x2c,0x1e,0x2e,0x18,0xa7, + 0xfc,0x4f,0xd6,0xb1,0xf2,0x2e,0x64,0xc8,0x89,0x4d,0x39,0x6d,0x27,0x4c,0x51,0xb6, + 0x75,0x83,0x47,0x3e,0xb8,0x61,0x35,0xbd,0x21,0x7d,0x1f,0x1e,0xdc,0x0c,0x01,0x49, + 0x62,0x2c,0x27,0xce,0xef,0x27,0x25,0xd1,0xe2,0x8c,0xc4,0x59,0xb8,0x4f,0xb0,0xe2, + 0xd7,0x75,0x84,0x00,0x68,0x5c,0xff,0x4e,0x44,0x64,0x5e,0x94,0x8f,0x8f,0xe8,0x6a, + 0x42,0x31,0x1d,0x8b,0x49,0x2a,0x19,0x6f,0x92,0x64,0x50,0x53,0x77,0xfb,0x3d,0x7e, + 0x84,0x9f,0xda,0x8d,0xb6,0xe2,0x6d,0x61,0xac,0xbd,0xaf,0x15,0x0f,0x30,0xe9,0x6a, + 0xc2,0x53,0x2b,0xf3,0x3e,0xb5,0x65,0x95,0x5f,0x8c,0xd1,0xf2,0x2f,0x79,0x0e,0x5d, + 0xdd,0x78,0x53,0x34,0x02,0x95,0x43,0x13,0x58,0xc9,0x46,0xe1,0x50,0x15,0x5f,0x54, + 0x60,0x15,0x7e,0x65,0x01,0x9a,0x06,0x0e,0x0b,0xf6,0x70,0x1c,0xd9,0x38,0x7b,0xf9, + 0x7c,0xb9,0x90,0x36,0x36,0xbd,0x75,0x41,0xaa,0xa7,0x56,0x96,0xce,0xc9,0x73,0x70, + 0x2c,0x91,0x69,0xb7,0x44,0x9a,0x23,0x40,0x80,0xa8,0xba,0x13,0xe1,0x3a,0xe2,0x76, + 0x4b,0x78,0x86,0x4c,0x20,0x23,0x6d,0x4f,0x70,0xa6,0x54,0xdf,0x3f,0xf9,0xf4,0x90, + 0xd0,0xd6,0xc6,0x03,0x38,0xf9,0x20,0x74,0xe6,0xdf,0x32,0x23,0x78,0x39,0xe3,0x76, + 0x8c,0x87,0x5d,0xeb,0x47,0x97,0x6c,0x82,0x4b,0x1b,0x6c,0x52,0x11,0x59,0x0e,0xe7, + 0x4e,0x0b,0xb1,0xa4,0x34,0x59,0x1f,0x79,0xed,0x72,0x93,0x47,0xff,0xf1,0x46,0x88, + 0x70,0xb1,0x12,0x0b,0xe4,0x34,0x00,0x58,0x81,0xdf,0xb4,0xec,0xdd,0x67,0x9e,0x43, + 0x28,0x9f,0x2d,0x9c,0x4d,0xe0,0x5e,0x38,0x6f,0x74,0x60,0x7c,0x59,0xbc,0x09,0x59, + 0x51,0xb3,0xcd,0xbe,0x94,0x50,0x69,0x48,0x65,0xd8,0xa7,0x8b,0xea,0x7d,0x8f,0x09, + 0xb2,0xbc,0x0b,0x23,0x46,0x53,0x3a,0x8a,0xcd,0x31,0x5f,0x3b,0x93,0x31,0x8c,0xa7, + 0xfb,0x5d,0xff,0x0e,0x12,0x70,0x02,0x13,0xc0,0x6f,0xf2,0xdd,0xbd,0xa3,0x57,0x68, + 0x2b,0x1e,0xa8,0xef,0x19,0xa5,0x9c,0xc1,0xc9,0x80,0x86,0xe7,0x35,0x3e,0xf5,0xfd, + 0x7d,0xe1,0x30,0x18,0xe4,0x39,0x91,0x50,0x67,0x61,0x1d,0xbc,0xd7,0x40,0x40,0xf0, + 0xa1,0x4e,0x2e,0xee,0xd9,0xe1,0x86,0x6f,0xe4,0x81,0xc6,0x44,0xf3,0x8f,0x8c,0xd0, + 0x06,0x8c,0xb9,0x35,0x78,0x2b,0x76,0x5f,0xaf,0x0e,0x88,0x59,0x3c,0x31,0x0a,0x53, + 0x04,0xc5,0x92,0x36,0x0f,0xe7,0x40,0x8d,0xb6,0x87,0x68,0x04,0xbc,0x94,0xe2,0x30, + 0xac,0xe8,0xb9,0x42,0x7f,0x65,0x0e,0x9b,0xc6,0x67,0xa3,0xe3,0xff,0x1c,0x65,0xa9, + 0x81,0x0d,0xa3,0x6a,0x7e,0xa4,0xb5,0x95,0x2e,0x84,0x06,0x9f,0xa0,0x2a,0x59,0x02, + 0xe9,0x37,0xe8,0xb2,0x44,0xea,0x8d,0x4a,0x44,0x18,0xd5,0x6e,0x58,0xc0,0x90,0xe5, + 0x29,0x84,0xf1,0x1e,0x66,0x09,0x1f,0x3c,0xd9,0xad,0xc4,0x8b,0xa8,0xed,0x22,0x7d, + 0x7b,0x9a,0x20,0x23,0x40,0x3b,0x0c,0x84,0xc4,0xba,0xc8,0x5c,0xb6,0x1b,0x50,0x3c, + 0x2c,0x34,0x04,0x70,0x40,0x70,0x43,0x1c,0x12,0x54,0xa9,0x2e,0xa1,0x46,0xe5,0x0b, + 0xfd,0x2c,0x0e,0xd1,0x1f,0x05,0x9e,0xf8,0x4e,0xc4,0x09,0x29,0x50,0x43,0xae,0xa9, + 0x7b,0x20,0xd4,0x3c,0x7e,0x8d,0x9d,0xba,0x53,0x8f,0xe2,0x6f,0x34,0x9c,0xf4,0x38, + 0xfe,0xe2,0xff,0xc8,0x98,0xc4,0x37,0xef,0x8d,0xe4,0xe0,0x87,0x4a,0xa3,0x78,0xde, + 0x81,0xed,0xf3,0x92,0x99,0x25,0x31,0x66,0x26,0x6c,0xff,0x82,0xdb,0xec,0x9b,0x74, + 0x00,0x0d,0xda,0xbf,0xdd,0x21,0x53,0x26,0x19,0xf1,0xb9,0x17,0x16,0x5f,0x98,0xec, + 0x86,0xf4,0xd2,0xaa,0xd4,0x1e,0x66,0x9a,0x19,0x7e,0x2b,0xc5,0x32,0x70,0x5d,0xa4, + 0x5d,0x9d,0x61,0x02,0xf7,0x41,0x96,0x13,0x38,0x71,0x67,0xe6,0x07,0x52,0x92,0x71, + 0x81,0x86,0x3a,0xe4,0xc9,0xdf,0x9d,0x43,0x01,0x00,0xb9,0x48,0x14,0xb1,0x36,0x31, + 0x40,0xf8,0x20,0xfa,0xdd,0xb7,0x16,0xe2,0x65,0x94,0x66,0x0e,0xd4,0x7f,0x39,0xa1, + 0x45,0x43,0xbc,0x52,0x74,0x27,0x71,0x43,0x05,0x7a,0xef,0x10,0x57,0xe4,0x5b,0x72, + 0x78,0x39,0x09,0x54,0xce,0xbe,0x69,0x68,0xe0,0x5c,0xf1,0x01,0xe6,0x7d,0x13,0x7b, + 0x8e,0x54,0xe5,0x4b,0x84,0xac,0xaf,0x0f,0xe7,0x7a,0x37,0x1f,0xa2,0xba,0x86,0x99, + 0xa0,0x97,0xc4,0x86,0x3d,0xf8,0x48,0xad,0xcd,0x77,0x7a,0x48,0x95,0xbb,0xee,0x1a, + 0xe9,0xdb,0xd0,0x2a,0xd6,0x5a,0xe7,0xba,0x96,0x42,0x78,0xcd,0x5b,0x97,0x4f,0x8c, + 0x2f,0xde,0xa3,0x45,0xdf,0x45,0xe3,0xd8,0xab,0xa5,0x5b,0x3d,0xfc,0xf2,0x6f,0x8d, + 0xab,0x99,0x91,0xa2,0x5f,0xab,0x3f,0x3f,0xb9,0x8a,0xdd,0xbe,0xfe,0xbb,0x60,0xf7, + 0x4d,0xdc,0x5e,0x31,0xd7,0xbf,0x20,0xdb,0x29,0x73,0x0d,0x1f,0xdd,0x5c,0x54,0x6b, + 0x4d,0x32,0xd0,0x7e,0x98,0x1d,0x00,0x52,0xef,0x8e,0xa7,0x2e,0xda,0x62,0x71,0x7a, + 0x45,0x3d,0x0b,0x50,0xbf,0xde,0x22,0x95,0x84,0x5d,0xc5,0xdf,0xb6,0x41,0x3d,0x5f, + 0xec,0xb5,0xa7,0x5b,0xb0,0x12,0xbf,0x3e,0x06,0xd2,0x13,0x64,0xfe,0x6f,0x59,0xb7, + 0xa5,0x6e,0x6b,0x44,0x1c,0x21,0xa8,0xde,0x50,0x0d,0xc9,0xd8,0xb5,0x9f,0x52,0x11, + 0x81,0xc3,0xab,0x62,0xdb,0x50,0x9e,0x77,0xa0,0xb7,0x58,0x88,0x4f,0x6b,0x63,0x00, + 0x83,0x43,0x17,0xd0,0x1d,0x39,0xee,0x5f,0xe2,0xaf,0xee,0xdd,0xd0,0x0c,0x32,0xe0, + 0x22,0xa3,0x73,0xf5,0x95,0x6d,0xe6,0x43,0x17,0x9c,0x9f,0xb1,0xab,0xbd,0xfa,0xa0, + 0x42,0x14,0x99,0xdd,0xb7,0xdb,0x28,0xe2,0x60,0x74,0x90,0xfc,0xd1,0x69,0x93,0x26, + 0x8e,0x47,0xea,0xa7,0x31,0x88,0xf0,0x60,0xa2,0x5e,0x65,0x29,0xac,0x38,0x9b,0x45, + 0xa6,0x1d,0xff,0x91,0x4e,0x29,0x69,0x89,0x4e,0x89,0xac,0xa7,0x73,0x79,0x9a,0xd8, + 0x80,0xc5,0x03,0x4a,0x30,0xa3,0x4f,0x97,0xe1,0xf7,0x52,0x8b,0x6a,0xdf,0x30,0x38, + 0x40,0xb7,0x13,0xac,0x2c,0x21,0xbe,0x57,0x82,0xb0,0xda,0x25,0x6b,0xfc,0x4f,0xf0, + 0xe7,0x44,0xfb,0x7a,0xea,0x39,0x5e,0xf8,0x09,0x9c,0xfc,0x11,0xbe,0x72,0xb8,0xce, + 0x52,0x02,0x43,0xb4,0x77,0x31,0x2d,0x75,0xce,0x99,0x29,0x4d,0x98,0x06,0x11,0x18, + 0xa8,0x5b,0x33,0xe6,0x14,0xd6,0x90,0x06,0x94,0x50,0xb8,0x4b,0xfa,0x2b,0x82,0xf1, + 0xdd,0x06,0xfc,0xae,0x3b,0x6c,0x46,0xea,0x68,0xbc,0xad,0x06,0x0b,0xf3,0x5c,0x75, + 0xac,0x40,0xdc,0xfc,0x59,0x89,0xb8,0x91,0x2f,0x22,0x1a,0xfc,0x76,0xcd,0x07,0xa1, + 0x3c,0x43,0xc5,0xed,0x73,0xe4,0x6b,0x2e,0xf9,0x2a,0xbb,0x6b,0x59,0x0a,0xe7,0xcb, + 0xc3,0x07,0x9b,0xbf,0x5b,0x34,0x02,0x4d,0x6e,0xb0,0x8f,0x6c,0xa7,0x6b,0x5d,0x36, + 0x87,0x0b,0x97,0x00,0x46,0x20,0xc7,0x92,0x53,0x3c,0x54,0x1d,0xcb,0x1e,0x8d,0xd0, + 0x61,0x5f,0xf9,0xf2,0xfb,0xa0,0xa4,0x77,0xa3,0x01,0x99,0x30,0x07,0x79,0xf7,0xe7, + 0x2f,0x94,0xcd,0x05,0x3d,0x29,0xad,0x90,0xdc,0x1d,0x55,0x19,0xa4,0x7a,0x1c,0xe3, + 0x06,0x10,0x75,0x1d,0x14,0xb5,0x15,0x30,0x00,0x1c,0xc4,0xaf,0x96,0xb5,0xd2,0x26, + 0xaf,0x2f,0x3b,0xb7,0x18,0x5a,0xea,0x08,0xa2,0x92,0xd5,0x86,0xf0,0xe1,0xae,0x23, + 0x57,0x13,0x98,0xa6,0xd8,0xc4,0x64,0x0e,0x9e,0x81,0x9a,0x96,0x8c,0x73,0xe7,0xb6, + 0x91,0x92,0x22,0x85,0xb6,0xc2,0xaa,0x63,0xc0,0x46,0x8f,0x07,0xf4,0x5c,0xbf,0xc7, + 0xa5,0x3d,0xf3,0xe8,0x3e,0x91,0x25,0xe3,0x08,0x86,0x2f,0x78,0x52,0xa8,0x17,0x14, + 0x1b,0xdf,0x86,0x6a,0x0b,0xac,0x46,0x89,0x38,0x1a,0xb6,0x94,0xf7,0x85,0x57,0x74, + 0xcc,0x10,0x34,0x7c,0x23,0x15,0x47,0xa3,0x0e,0xd9,0xe7,0xc0,0xeb,0x71,0xbf,0xb8, + 0x94,0x55,0x5d,0x11,0x8b,0xae,0xc7,0x74,0xeb,0xba,0xf1,0x95,0x9b,0x7e,0x0d,0xeb, + 0x9a,0xdc,0x0b,0x19,0xc3,0xd4,0xb7,0x09,0xcd,0x58,0x9a,0x39,0x8f,0x73,0x5e,0xdb, + 0x89,0x1f,0x96,0x0c,0x6f,0x7e,0x36,0x5e,0x38,0x1e,0x69,0xd0,0xf8,0xe9,0xc9,0x3a, + 0xc2,0x1e,0xe6,0xda,0x9a,0x22,0x9b,0x8b,0xc8,0x52,0xfa,0xbc,0x18,0x4e,0x27,0x7a, + 0x36,0x95,0x8b,0xe8,0x3b,0x5a,0x1b,0x89,0x68,0x99,0x89,0x0f,0xde,0x78,0x57,0xcc, + 0x08,0x19,0x7b,0xbf,0x00,0x5a,0x9f,0x90,0x56,0x59,0xa7,0xda,0x98,0x5c,0x7a,0x06, + 0xa3,0x92,0xc7,0xf9,0xe1,0x36,0x43,0xa6,0x3e,0xdd,0x58,0x0a,0x76,0xb1,0x08,0x9b, + 0xe4,0x9a,0xa8,0xd1,0xe8,0x17,0x39,0x4d,0xe2,0xc2,0xe0,0xb2,0x66,0x8b,0x99,0x32, + 0xb8,0xcd,0x5a,0x3c,0xe4,0x39,0x79,0xa7,0x31,0x8d,0x29,0xcf,0xe3,0x2f,0xdf,0xf5, + 0x97,0xcc,0xf3,0x15,0x26,0x7a,0x2d,0x3f,0xc3,0x80,0x01,0xd7,0x8d,0xf8,0x65,0xaa, + 0xde,0x4f,0xa7,0xa0,0xf7,0x0b,0x20,0x15,0x5e,0x4b,0x45,0x77,0x22,0xc9,0x99,0xb4, + 0x23,0x9e,0xaf,0x30,0xe8,0x08,0xdc,0x84,0xc0,0x45,0x98,0x4c,0x74,0xea,0xe5,0x67, + 0x67,0x9d,0xb5,0xb4,0xe2,0xbd,0x73,0x85,0x67,0xdd,0x67,0x8f,0x16,0x2b,0x99,0xab, + 0x69,0x3c,0x7a,0x10,0x49,0xad,0x20,0x47,0x62,0xdc,0xa0,0x61,0x32,0x82,0x02,0x8b, + 0x3f,0x4f,0xc3,0x4e,0x08,0xb3,0xfd,0xea,0x04,0x8a,0xee,0x58,0xa3,0x84,0x22,0x0b, + 0xf8,0x7f,0xeb,0x78,0x6f,0xad,0x63,0x7d,0x2e,0xb9,0x69,0xa2,0x5c,0xa9,0x9b,0xf5, + 0x03,0x7c,0xd6,0x69,0xe4,0xe5,0xe0,0x19,0x4c,0xcb,0x8d,0x72,0x02,0xa8,0xd3,0x19, + 0xcd,0x06,0xe9,0x58,0x7c,0x0d,0xc3,0x39,0xed,0x89,0x9b,0x87,0xee,0xfc,0x66,0xa7, + 0x06,0xd7,0xb8,0xca,0x15,0xcd,0x64,0x8c,0xaf,0xca,0x8a,0x86,0x4a,0xa1,0x6a,0xa7, + 0x2f,0xcf,0xea,0x5e,0x1f,0xc1,0x3f,0x9c,0x49,0xc6,0xc1,0x59,0xfc,0x88,0x43,0xa2, + 0x60,0x55,0x23,0xcf,0xe3,0xae,0x05,0x21,0x6d,0xd5,0x88,0x67,0x7b,0x51,0x6c,0x49, + 0x6e,0x94,0xd5,0x8b,0x55,0xac,0xb6,0x3c,0xf4,0xab,0xc4,0x9d,0x5d,0xec,0xdc,0x6a, + 0xc2,0xdd,0xfd,0x98,0xd1,0xdc,0x26,0xa6,0xcc,0x5b,0xed,0xbc,0x13,0x22,0xaa,0xe0, + 0x82,0x8a,0xcb,0x66,0xb5,0xae,0x90,0xc1,0x38,0x27,0x7c,0x0f,0xce,0xea,0xc9,0x11, + 0xb4,0x9a,0x61,0x7c,0x39,0x4f,0x6c,0x42,0x01,0x2d,0x95,0x2f,0xc7,0xe5,0x0a,0x67, + 0xad,0xd2,0x36,0x1d,0xb6,0x33,0xfd,0x0f,0xb3,0xd9,0x66,0xc1,0x0e,0x9f,0x96,0xd4, + 0x87,0x14,0xdc,0x28,0x9a,0xb9,0x86,0x6b,0x9b,0xdb,0x8c,0xc1,0x34,0xfb,0x54,0x15, + 0xe5,0xc5,0xd1,0x94,0x96,0x38,0x04,0x70,0xe7,0x91,0xa6,0x76,0xd4,0x90,0x1d,0x41, + 0x40,0x52,0x18,0xad,0x37,0xbb,0x4f,0x61,0x00,0xfc,0xcf,0xc0,0x55,0x93,0x65,0xda, + 0xc4,0xc7,0x32,0xd6,0x40,0x08,0x45,0x1b,0xbd,0x98,0x85,0x1f,0xf7,0x6c,0x36,0xba, + 0x20,0x9b,0xff,0x94,0x5b,0x7e,0x2d,0x42,0xb8,0x15,0x8c,0x35,0x7a,0x2b,0xd0,0x72, + 0x1a,0x54,0x3f,0xd9,0x0e,0x2d,0xd2,0x3e,0x1b,0xeb,0x6d,0xfe,0x4e,0x6d,0x32,0xe2, + 0xaa,0xe2,0xb7,0xbf,0xb8,0x96,0xf3,0x2e,0xaf,0x29,0xb6,0x6f,0xb0,0xb8,0x77,0xda, + 0x9e,0xf0,0x15,0x0c,0x81,0x74,0x77,0xb3,0xeb,0x68,0x65,0xb3,0xce,0x6f,0x1e,0x48, + 0xc4,0xe8,0x9d,0x3e,0x98,0x1d,0xce,0x0a,0x6a,0x5c,0xd6,0x17,0x76,0x87,0x3e,0xd2, + 0x4c,0xbd,0xbc,0x69,0xd4,0xd9,0x92,0x68,0x33,0xd5,0x86,0x02,0x7f,0x06,0x3d,0xd6, + 0x0d,0x98,0xb3,0x3c,0x3a,0x33,0x8f,0x03,0xb4,0x93,0x08,0x03,0x8b,0xc5,0x17,0x59, + 0x8d,0x4f,0xd7,0x34,0x0c,0xfd,0xfb,0x0b,0xb3,0x90,0xef,0xfb,0xa7,0x7b,0x5e,0xa5, + 0xe4,0xab,0xb1,0x28,0x00,0x24,0xcf,0xf2,0x37,0xb6,0x93,0x65,0x50,0xc4,0x9e,0x63, + 0x6d,0x6d,0x4c,0x4a,0x1f,0x3f,0x90,0xdc,0x41,0xcc,0x48,0x75,0x51,0xec,0x53,0x29, + 0x61,0xad,0x03,0x5b,0x34,0xcf,0xd1,0x44,0xa0,0x39,0x06,0x84,0x18,0x61,0x6f,0xc0, + 0x80,0x43,0xf0,0xea,0x1c,0xa5,0x66,0xcc,0xc3,0x98,0xe7,0x94,0x3a,0x20,0x80,0xf0, + 0x21,0xb1,0x3f,0xac,0x65,0xe9,0x0b,0x42,0x39,0x64,0xb0,0x46,0x91,0x69,0x89,0x95, + 0xea,0xcf,0x08,0xe4,0x9b,0x2d,0x05,0xa2,0x45,0xf5,0x74,0x0b,0x89,0x9a,0x91,0x7b, + 0xa8,0x44,0x6d,0xc0,0x69,0x48,0x8c,0x60,0xf5,0xb0,0xaa,0x42,0x73,0xd9,0x17,0xb3, + 0x87,0x82,0x49,0x44,0xeb,0x87,0x7b,0x99,0xb4,0x8a,0x62,0xef,0x24,0xca,0x0e,0x95, + 0xe1,0xc2,0x8a,0x4c,0x1c,0xd3,0x22,0xac,0x71,0x12,0xec,0x04,0xb1,0x79,0x9f,0xe9, + 0x7b,0xb8,0x1b,0xe3,0x45,0x94,0x0b,0x7f,0x83,0x83,0x1c,0xb8,0x77,0x9e,0x7c,0xf1, + 0x88,0x71,0x54,0x7f,0x6f,0x81,0x29,0xda,0xf8,0xe7,0x3f,0xbe,0x9f,0x60,0xbc,0xa9, + 0x7d,0x68,0x89,0xee,0xa9,0x86,0x53,0x25,0xcf,0xc8,0x9d,0x15,0x59,0x24,0xf1,0xaa, + 0x62,0x8f,0x54,0x0d,0xa2,0x37,0xad,0x93,0xc7,0xe1,0x9c,0x5c,0xad,0xd3,0x9e,0xab, + 0x25,0xad,0x96,0x2a,0xa4,0x76,0x23,0x09,0x1e,0x5b,0x1a,0x60,0x6f,0xe0,0x3d,0xf9, + 0x7f,0xad,0x18,0x3b,0x65,0x35,0xdc,0xf2,0xa9,0x4a,0xe9,0xdd,0x25,0xf1,0xdd,0x58, + 0x93,0x09,0xcb,0x60,0x70,0xbe,0x13,0x71,0x36,0x23,0xa5,0x50,0x30,0xfe,0x5f,0x80, + 0x5b,0x18,0xba,0xac,0x72,0x9f,0xef,0x87,0xc1,0xaf,0xf2,0x04,0xf2,0x97,0x0e,0x63, + 0x19,0x9c,0x66,0xe6,0xda,0x12,0x22,0x11,0x17,0xfe,0xd4,0x14,0x77,0xf2,0xc5,0x9d, + 0x94,0xef,0x14,0x94,0x80,0x36,0x03,0x05,0x0b,0xc3,0x6c,0xc7,0x3a,0x83,0x73,0xbd, + 0x69,0x22,0xf3,0x31,0x5a,0x02,0x88,0xf6,0x08,0x10,0x91,0x5d,0x86,0xbe,0xfb,0x45, + 0xdd,0x12,0x7b,0xe9,0xcd,0xe9,0x6c,0x1b,0x9f,0x16,0x14,0x54,0xee,0xc2,0xf8,0xaf, + 0x80,0x98,0xac,0x67,0xff,0x38,0xf9,0x6b,0x92,0xdc,0xa2,0xdd,0x75,0xf6,0xb3,0x3b, + 0x57,0x19,0x14,0x3b,0x53,0x89,0x81,0xf3,0xe4,0xd5,0xab,0xc9,0x47,0xe0,0x2d,0x66, + 0x14,0x18,0xb4,0xf2,0x12,0x08,0x7d,0x1b,0x56,0xde,0x93,0x71,0xdd,0x23,0x17,0xfb, + 0x18,0x76,0xf8,0xa4,0xd1,0x29,0xf1,0x5b,0x1c,0xf5,0x3a,0x29,0x83,0x14,0x30,0xb0, + 0x27,0xb6,0xcd,0x18,0x5b,0xd8,0x4e,0xcf,0x21,0xd4,0xe7,0xc0,0xeb,0x73,0x65,0x89, + 0xa9,0x2a,0x2b,0x1e,0xff,0x30,0x43,0x37,0x03,0xeb,0x28,0x36,0x9b,0x7e,0x1e,0x88, + 0x9d,0x1f,0x70,0xda,0x73,0x6a,0x61,0x80,0x02,0x8a,0xd8,0xce,0x85,0x74,0xf2,0x2a, + 0x0e,0x69,0x72,0x48,0x58,0x48,0x76,0x62,0x69,0x1d,0xee,0x16,0xd6,0x71,0x1c,0xe6, + 0x05,0x5f,0x8e,0x34,0x34,0x70,0x0c,0xa1,0x6d,0x3e,0xe5,0x72,0xcc,0x11,0x15,0xe7, + 0x84,0xeb,0x07,0xd0,0x09,0x34,0x97,0x4c,0x6e,0x1c,0xa8,0xaa,0x64,0x01,0xd7,0xea, + 0x8f,0x92,0x97,0xd0,0x39,0x98,0xff,0x97,0x48,0x3a,0xe1,0xd1,0x25,0xd2,0xe0,0x67, + 0xac,0x0b,0xb1,0xc1,0xca,0xaa,0xa6,0x12,0x4e,0x82,0x87,0xf2,0x52,0x63,0x88,0x60, + 0x67,0xb7,0x7c,0xd9,0xee,0x2a,0x3e,0x1a,0xc5,0xbc,0x9e,0x92,0x77,0x4c,0x79,0x32, + 0xe8,0x2d,0xb3,0xf7,0x96,0xe0,0xe5,0xf8,0x84,0xcd,0xb2,0x34,0xfe,0x13,0x57,0x14, + 0x24,0x88,0x2e,0x93,0xbb,0xdd,0x95,0x41,0x0f,0x12,0x2e,0x97,0x38,0x93,0x96,0xa9, + 0xa7,0xea,0x59,0xe3,0xfd,0xd5,0xb4,0x93,0x3f,0xc4,0xae,0x53,0x5e,0x49,0x52,0xb0, + 0x85,0x62,0xed,0xbe,0x18,0xe8,0xee,0x01,0x2b,0xa9,0x6e,0x31,0x8d,0xef,0x03,0x09, + 0x87,0xd7,0xb8,0xab,0x73,0xad,0x0f,0x1f,0x27,0x69,0xbf,0xf7,0x2d,0x4b,0x12,0x31, + 0x70,0xe2,0xb1,0x47,0x12,0x44,0x1f,0xa2,0xc4,0xae,0xb2,0x86,0x74,0xa7,0xa2,0x2b, + 0x90,0xca,0xb5,0xf5,0x7f,0x8a,0x4c,0x8e,0xad,0x6e,0x1e,0x5c,0x96,0xeb,0x19,0x23, + 0x0b,0xdb,0xd4,0x37,0x92,0x7f,0xad,0x29,0x6b,0xca,0x2d,0xcd,0x21,0x85,0x71,0xeb, + 0x74,0x5b,0x63,0xaa,0x03,0x1b,0x24,0xd8,0xe6,0x65,0xcd,0x8f,0x3d,0x4c,0xe7,0x9f, + 0xef,0xa3,0xa3,0x0a,0x69,0x9a,0x5b,0x8c,0x3e,0xc6,0xdb,0x88,0x62,0xe6,0x5a,0xb5, + 0x8c,0x6b,0xc2,0x76,0x3e,0x4f,0x4c,0x5f,0x0e,0x33,0xcc,0x5b,0xbe,0x6d,0x0a,0xed, + 0xb8,0x80,0xf9,0xa6,0x1f,0x16,0x32,0xc7,0x49,0xae,0xc2,0x84,0xf3,0xe0,0x9e,0x29, + 0xf2,0x71,0xb1,0x71,0xa2,0x5b,0xcc,0x2c,0x04,0x64,0x1b,0xeb,0xf0,0xba,0xb8,0x1c, + 0x81,0x50,0xed,0xdb,0xc7,0xc3,0xdb,0x19,0x3c,0xaa,0x84,0xfb,0xf1,0xab,0x5c,0x06, + 0x0a,0x5d,0xac,0x9b,0xdd,0xe1,0x0a,0x8f,0x46,0x3d,0x00,0xd5,0x56,0xff,0x9f,0x37, + 0x23,0xf8,0x40,0x08,0x36,0x11,0x42,0x8a,0x8c,0x00,0x84,0x25,0x57,0xf7,0x7e,0x1c, + 0x58,0x11,0xb7,0x83,0x43,0x4f,0x33,0xd1,0x0f,0xa3,0x19,0x25,0x1a,0x4d,0xc2,0xe0, + 0xe2,0xec,0x6d,0x32,0x4b,0x13,0x8e,0x8a,0x55,0x82,0x4b,0x4d,0x54,0x55,0x1a,0xea, + 0xcd,0x25,0x42,0x42,0x34,0x4d,0xc9,0x00,0x0d,0xdb,0xe1,0x78,0x75,0xd5,0xa6,0xa0, + 0xcc,0x4d,0x7c,0x54,0xdd,0x51,0xda,0x81,0x5b,0xda,0x1f,0xb6,0x61,0xb7,0x75,0x5f, + 0xa2,0xb2,0xe5,0xc7,0xb6,0xb6,0xf5,0x9c,0xe0,0xb5,0x59,0x88,0x28,0xab,0x13,0x8e, + 0xd8,0x86,0x2d,0x57,0xca,0xb7,0xc9,0x80,0x97,0xd8,0x29,0xf1,0xf1,0x74,0xff,0x8a, + 0xd4,0xc9,0xb3,0x9f,0x0c,0xbc,0x37,0xa8,0x28,0x04,0x21,0x6e,0x30,0x55,0xee,0xeb, + 0x75,0xdb,0xcc,0x9e,0x3c,0x59,0xfa,0x70,0xde,0x66,0xee,0x5c,0xff,0x1e,0xf8,0x59, + 0xdb,0x6c,0xc8,0xfc,0x84,0xd4,0x87,0xdc,0xe2,0x06,0x20,0x4d,0x50,0x57,0xfb,0xed, + 0xde,0x6d,0x98,0xb6,0xbb,0x38,0x01,0x83,0x19,0xaa,0xc2,0xdd,0xbd,0xf4,0xbd,0xfc, + 0x28,0xcf,0xe6,0xce,0x3e,0x11,0x48,0xdf,0x4d,0x9c,0xf9,0x06,0x09,0x31,0x16,0xde, + 0xcf,0x62,0x2e,0x7b,0xab,0xb0,0x0c,0x7e,0x41,0x99,0xb6,0xe3,0x79,0x7e,0x9c,0xb8, + 0xe5,0x35,0xa9,0x4b,0xdc,0x87,0xd0,0xc3,0xb2,0xf6,0x5b,0x6b,0x9c,0x24,0xdc,0x39, + 0x9c,0x11,0x14,0xf8,0x1e,0x40,0x47,0x05,0x43,0xd2,0xb1,0x7b,0xd1,0xab,0xc0,0xb0, + 0x59,0x04,0x19,0x88,0x23,0xf2,0x24,0xde,0xa9,0xc9,0xb0,0x21,0x3b,0xa8,0xbc,0xd7, + 0xe8,0x90,0x32,0xfb,0x6d,0x9e,0x2c,0x49,0x72,0xd3,0x67,0x12,0x1d,0x06,0x03,0x10, + 0xec,0x2b,0x39,0xfa,0xa3,0x16,0x0b,0x20,0xe1,0x02,0x95,0x56,0xb1,0xe0,0x6f,0x6d, + 0x68,0x72,0xb3,0xb0,0x62,0x38,0xa1,0xd1,0xd3,0x58,0x79,0x08,0x75,0x33,0x9b,0xa8, + 0x4c,0x49,0xd0,0xc4,0xb3,0xa6,0xe8,0x24,0x7a,0x40,0xc0,0x21,0xaf,0x6b,0xe4,0xcf, + 0x00,0xc4,0xd9,0xd0,0x33,0x27,0x62,0x8f,0xc3,0x27,0x18,0x54,0x51,0xee,0xbe,0xa9, + 0xee,0x4b,0xb9,0xb5,0x35,0x87,0x90,0x90,0xfa,0x66,0x8b,0x83,0xba,0x77,0x10,0x46, + 0x66,0x81,0xf1,0x45,0x30,0x92,0x67,0x58,0x80,0x48,0xdd,0x97,0xb8,0x68,0x64,0x71, + 0x09,0x2a,0xa6,0x7a,0xaf,0x85,0x02,0x4e,0xb7,0x0a,0x72,0x8c,0x6b,0xa8,0xf5,0x6b, + 0x35,0xaa,0x75,0x22,0xba,0x6b,0xa5,0xde,0x7a,0x68,0x22,0xcf,0x4c,0x72,0x3d,0x31, + 0xe0,0xd3,0x9d,0x03,0x3b,0xaf,0xd4,0x5b,0xfb,0x2a,0x2b,0xde,0xc1,0x7a,0x14,0x5e, + 0x87,0xa4,0x8c,0x5a,0xaa,0xeb,0xa3,0xc6,0xcf,0xf2,0x9a,0x5b,0x32,0x13,0x46,0x08, + 0x0e,0x4b,0x54,0x73,0x2a,0x6e,0x4a,0x71,0xab,0xe3,0x52,0x1f,0x36,0x2e,0x1a,0xd9, + 0x43,0x09,0xca,0xd8,0x3b,0x45,0x4c,0x4d,0x4d,0x4c,0xcb,0xf8,0x7b,0xcb,0xc2,0xe9, + 0x9e,0xae,0x59,0x3d,0x9c,0x2f,0x46,0x96,0xa9,0xc2,0xc3,0x49,0x25,0xc3,0x4a,0xf9, + 0x81,0xaf,0x74,0xbf,0xf8,0xa3,0x56,0x0b,0x68,0xc4,0x85,0x9f,0xdf,0xc2,0xe7,0x04, + 0x72,0xfa,0x84,0x00,0x68,0x5c,0x4d,0xb8,0xc5,0xef,0xb2,0xb0,0xf7,0x32,0x42,0x50, + 0x39,0xe4,0xb7,0x28,0xc2,0x6c,0x16,0xb2,0x9e,0x4a,0x22,0xf3,0x42,0x95,0x3b,0xb4, + 0x2d,0xb4,0x3a,0xb4,0xf9,0x8d,0xa5,0x30,0x01,0x31,0x7d,0xa1,0xcb,0xd6,0x9b,0x15, + 0x8b,0x80,0x9b,0xf7,0x79,0x9a,0x5e,0xd7,0x20,0x30,0x7f,0xf5,0x8c,0x3f,0x2c,0xc6, + 0xa1,0x70,0x6b,0x40,0x5f,0xea,0x94,0xc0,0x32,0x59,0xc2,0xcc,0xc1,0x69,0x9c,0xa2, + 0xc8,0xf4,0x5a,0x50,0x68,0xb9,0x9c,0xd0,0x1b,0x58,0x85,0x30,0xd6,0xaa,0x2d,0x23, + 0x21,0x1b,0xea,0xae,0x6b,0xc3,0x0d,0xe5,0x4b,0xa8,0xfd,0x87,0x57,0x89,0x17,0x83, + 0xcb,0xf6,0x0d,0xf5,0xe3,0x3a,0x20,0x03,0xc0,0x17,0x62,0xa9,0x0c,0x79,0x00,0xbd, + 0xa8,0x17,0xfe,0xbe,0xc7,0x54,0xc2,0x78,0xe9,0xa0,0x17,0x44,0xb0,0xb3,0xf5,0xbf, + 0x88,0xe6,0xe8,0x7e,0xce,0x22,0x26,0xe5,0x96,0x1c,0xc3,0xbf,0x94,0x62,0xef,0x3c, + 0x8c,0x17,0xb8,0x12,0x47,0xa7,0xe8,0xda,0xcd,0xfb,0x97,0x45,0x70,0xba,0x50,0x4b, + 0xda,0x3e,0x4c,0xfb,0x85,0x84,0x1e,0xcb,0xc7,0x84,0x3f,0x2b,0xf8,0xa1,0x86,0xe8, + 0x33,0x11,0x39,0x3c,0xfb,0x0d,0x6a,0x8c,0x09,0xd5,0xee,0x06,0x87,0x33,0x82,0x28, + 0x8c,0x5f,0xb6,0x2c,0x5a,0x0c,0x4b,0x10,0xeb,0x10,0xe0,0xd4,0xf6,0xfb,0xab,0x5b, + 0xaa,0x16,0x07,0xed,0xa3,0xc3,0x42,0x03,0x4f,0xf1,0xf7,0xe4,0xb2,0x6f,0x5f,0xc5, + 0x0a,0x14,0xb6,0xae,0x83,0x70,0xa0,0x92,0x66,0xa9,0x58,0xbd,0x35,0xdf,0x3f,0x7d, + 0x0a,0x2f,0x1b,0xe0,0x04,0x5d,0x27,0xca,0x0c,0x3d,0xb1,0x40,0xbf,0x78,0xe8,0xb7, + 0xd3,0xc3,0xf0,0x06,0x26,0xa0,0x2c,0x54,0xba,0x83,0x84,0xb2,0x68,0x44,0xba,0x87, + 0xaa,0x5f,0x59,0xef,0xc6,0xef,0xc9,0x21,0x82,0xd9,0x86,0x73,0xd2,0x98,0x6a,0xc6, + 0x6c,0x62,0x89,0x13,0xa6,0x82,0xfe,0x41,0xf6,0x63,0x87,0x47,0x5a,0x45,0xa0,0xa3, + 0x71,0x80,0xf5,0xc2,0x36,0x9c,0x6a,0x53,0x2a,0xdb,0x66,0xe4,0xf6,0x9e,0xa8,0x86, + 0x4d,0x9e,0x6a,0xd2,0x37,0x14,0x68,0x97,0xba,0xca,0xc6,0x5e,0x51,0xe4,0xe5,0xc7, + 0xad,0xed,0xdb,0xa5,0xa5,0xfd,0x4f,0x4a,0x61,0x84,0x31,0x47,0xbe,0x19,0xff,0x35, + 0xc7,0xc8,0xb3,0xa8,0x34,0x8a,0x7f,0x46,0x2e,0x26,0x8d,0xf3,0xf7,0xe2,0x3a,0x03, + 0x46,0x69,0x1a,0xfd,0x55,0xb3,0x8d,0xcc,0x7f,0xc9,0xac,0xee,0x58,0xc4,0x79,0x18, + 0xa2,0xcb,0x55,0x6c,0x7f,0x56,0x2d,0xd2,0x41,0x34,0xe6,0x8b,0x36,0x60,0x94,0x3e, + 0x8a,0xa9,0x03,0x79,0xfc,0x55,0x8b,0xd4,0xca,0x73,0x60,0x5d,0x23,0xa8,0xff,0x65, + 0x8b,0xe8,0x50,0x24,0xf4,0x30,0xc3,0xbf,0xbf,0x44,0xbb,0x99,0xc9,0xf0,0x42,0x43, + 0x3d,0x6d,0x0d,0x5f,0x2e,0x80,0x68,0x77,0x6d,0xda,0xa8,0x87,0x58,0xed,0xaa,0x32, + 0xc9,0xcf,0x6d,0x3e,0x13,0xc7,0xec,0x3d,0x85,0x75,0x5f,0x4f,0x6f,0xf2,0x59,0xad, + 0x09,0xce,0x5a,0x3c,0xa6,0x24,0x49,0x98,0xa2,0x63,0x64,0x0d,0x21,0x65,0xe4,0x2f, + 0x0c,0x81,0xfe,0xbd,0x42,0x92,0x73,0x7f,0x66,0xa2,0x44,0x99,0xbc,0x66,0xe4,0xe7, + 0xfb,0x34,0x9e,0x23,0xc7,0xf2,0x1e,0x07,0x27,0xdd,0xed,0xa5,0x13,0xf0,0x14,0xd0, + 0x86,0x9d,0x17,0x70,0x25,0x4c,0x38,0x8d,0x0c,0x93,0xb9,0x66,0x4e,0xe5,0x34,0xb6, + 0x80,0x9e,0xa2,0xc0,0x87,0xa2,0xba,0x50,0xf1,0xa9,0xec,0xad,0xb0,0xf1,0x89,0xd1, + 0x21,0x9f,0x55,0xe4,0xd4,0x34,0xa4,0x47,0xd6,0xb3,0x03,0x5f,0x61,0x35,0xe9,0x32, + 0x47,0x35,0xd8,0x19,0x30,0xb5,0x7c,0x27,0x8f,0xe5,0x62,0xa5,0x98,0xb5,0x79,0x56, + 0x07,0xfe,0x36,0x52,0x17,0x25,0x02,0xda,0x54,0xd1,0xc2,0x87,0xa3,0xfa,0xf3,0x29, + 0x03,0x39,0xf2,0xa5,0x55,0xbd,0x3f,0x01,0xc5,0x6e,0xac,0xe4,0x13,0x29,0x55,0x2c, + 0x4e,0xa6,0xd5,0x10,0x84,0x9c,0xc5,0x0c,0x0e,0xc6,0x3d,0xaa,0x0e,0xff,0x4e,0x7b, + 0xaf,0x9a,0xa2,0x9f,0x57,0x70,0x8e,0x55,0x5f,0x78,0xbe,0xf6,0x4f,0x19,0xaa,0xd9, + 0x5b,0x82,0xb4,0xef,0x54,0xb2,0x84,0x55,0x5e,0x0b,0x3e,0x3a,0x00,0x22,0x37,0x83, + 0xec,0xd4,0xa7,0x8d,0xe8,0x17,0x8f,0x50,0xdf,0xee,0xed,0xae,0x5b,0xb6,0xb9,0xfd, + 0x8c,0xdb,0xa9,0x6e,0xf8,0xdb,0x87,0x48,0xf8,0x99,0x9f,0xff,0xfb,0x02,0x3e,0x46, + 0x1d,0x18,0x04,0x8e,0x4f,0x31,0xda,0x75,0x6f,0x9c,0x72,0xd1,0x17,0xbd,0xd6,0xba, + 0x23,0x60,0xe0,0xbc,0x1c,0xe7,0x70,0x98,0x4c,0x7e,0xfc,0x81,0xa9,0x02,0xdf,0x2b, + 0xaa,0x8c,0x99,0xe7,0xb8,0xbf,0x4b,0x34,0xe8,0xdf,0x48,0xa8,0x28,0xf6,0x77,0xce, + 0x9c,0xbb,0x2f,0xff,0xbf,0xfd,0x25,0x1d,0xd7,0x9d,0x6f,0x02,0xff,0xbe,0x37,0x28, + 0xfc,0xe1,0xb0,0x66,0xeb,0x62,0x49,0x0d,0xab,0x04,0x64,0xd7,0xdc,0x21,0x19,0x94, + 0x6c,0xdf,0xf0,0x26,0x35,0x8c,0xbc,0x14,0x22,0xa5,0xa2,0x84,0xff,0xce,0xc1,0xd8, + 0x41,0xf7,0xdd,0x00,0x6d,0x8d,0x2b,0x91,0x6e,0xed,0x83,0xe9,0x3b,0x26,0x53,0x76, + 0xe9,0xe2,0x1a,0x25,0x95,0xdc,0x8c,0xc2,0x45,0xce,0x3d,0x11,0xba,0x52,0x20,0x42, + 0x79,0x09,0xc8,0x55,0xf3,0x6b,0xa8,0x1e,0x29,0x4b,0x5e,0xec,0xaa,0xb5,0xdc,0x58, + 0x05,0x2e,0x17,0x50,0x15,0x0e,0xaa,0xfd,0xe2,0xb4,0xf8,0xe1,0xea,0xc4,0x51,0x32, + 0x8e,0x44,0x01,0x34,0x71,0x67,0xd6,0x53,0x3d,0x40,0xe2,0x5c,0xa5,0x46,0xc6,0xd5, + 0xea,0x88,0xa3,0xa8,0x97,0x65,0xa6,0xf5,0xf2,0x47,0xe1,0x9e,0x1b,0x16,0x7c,0x0e, + 0xe9,0x8b,0x42,0x75,0xe7,0xd5,0x40,0x8f,0xa3,0x2c,0x6d,0xae,0xbe,0x5a,0x21,0x63, + 0xd8,0x75,0xb0,0xac,0xb7,0x86,0x28,0x08,0x82,0xe6,0xc5,0xbd,0x5f,0x71,0xe4,0xfa, + 0x04,0x4b,0x2f,0x29,0x73,0x6e,0x83,0xd8,0x6b,0x8a,0xab,0xd2,0xe7,0x5b,0xb4,0x56, + 0x34,0xa0,0x2f,0x39,0x72,0x6f,0xbb,0x4b,0xab,0xcc,0x9b,0x22,0xe9,0x6d,0x78,0xa0, + 0x10,0x43,0x9e,0xea,0x3e,0x37,0xe9,0x9b,0x26,0x57,0x44,0x7f,0x2a,0x7d,0x3c,0x12, + 0xa8,0x16,0xaa,0xeb,0x22,0x20,0xa5,0x0b,0x27,0x23,0x1a,0x29,0x49,0xf8,0x63,0x58, + 0x6b,0x08,0x1a,0x3b,0xbb,0x1e,0xc2,0x0f,0xa2,0x7f,0x6a,0xe9,0x9f,0x0a,0xde,0x3f, + 0x74,0x14,0xd9,0x51,0x38,0x2b,0xbc,0x39,0xff,0x54,0x4c,0x46,0xf9,0xe2,0x84,0x00, + 0x80,0x1d,0xfa,0x82,0xd1,0xb3,0x6a,0xa6,0x81,0xd3,0x73,0x64,0x74,0x84,0x1d,0x63, + 0xa5,0x9c,0x1c,0x64,0xa5,0xc0,0x62,0xb7,0x0a,0x5e,0xe4,0xa4,0x91,0x8e,0xfa,0x71, + 0x61,0xb3,0xf7,0x76,0x3c,0x3f,0xe3,0x52,0x6c,0x13,0x80,0xd6,0xc8,0xd9,0x5f,0x23, + 0x4a,0x77,0xf3,0x93,0x50,0xb0,0x9d,0xc2,0xd9,0x11,0x71,0xc6,0xcd,0x85,0x45,0x42, + 0xc4,0x46,0x86,0xa4,0x62,0xb5,0x44,0x93,0x6e,0x16,0xd4,0xe6,0x68,0x89,0xb3,0xaf, + 0xac,0x93,0x17,0xd6,0x6b,0xce,0xd3,0x72,0x89,0x49,0xcf,0x07,0xf7,0xd8,0x7d,0x86, + 0x68,0x07,0x45,0x25,0xe2,0xcd,0xc1,0xe9,0xe4,0x7d,0x8b,0xe2,0xf2,0xd7,0xcd,0x91, + 0xbb,0xea,0x04,0xd7,0xab,0xcc,0x65,0x11,0xf9,0x4c,0x79,0x44,0xcf,0x35,0x96,0xe7, + 0x43,0x17,0xf4,0x7f,0xb4,0x35,0x56,0x8a,0xc9,0xc7,0xa8,0x80,0xb2,0x77,0x9e,0x68, + 0xb9,0xe8,0xf0,0x9a,0xd8,0xba,0x08,0xda,0x4d,0xa6,0x24,0x43,0x4a,0xbd,0x87,0x0b, + 0x08,0x60,0x17,0x7d,0x24,0xcb,0xa3,0xcb,0x13,0xa7,0x9f,0xed,0xcb,0xfe,0x71,0x9f, + 0x48,0x98,0xfd,0x6e,0x35,0x36,0x46,0xbe,0x4c,0x83,0x25,0x22,0x0e,0x60,0x24,0x36, + 0x29,0x9c,0x14,0xce,0x72,0x91,0x16,0x8e,0x49,0xde,0x58,0xf0,0x79,0xac,0x2e,0x6e, + 0x3d,0xb0,0xae,0x6b,0x02,0x30,0xc8,0x7a,0x8d,0x6f,0xcd,0x8e,0x11,0x0c,0x7d,0x21, + 0xa8,0x51,0x8a,0x8a,0xb4,0xc1,0x97,0x80,0x57,0xaa,0x68,0xdc,0x8a,0xd1,0x5e,0x3b, + 0xc0,0x10,0x63,0x4f,0x88,0x35,0x67,0x88,0x87,0x56,0xa1,0xd0,0x62,0xf7,0x58,0x06, + 0x86,0x85,0x9a,0xb6,0xba,0x0f,0x4e,0x25,0xb1,0xcf,0x42,0xbe,0xf5,0x1f,0x10,0xec, + 0xa9,0x8c,0xd6,0xf4,0xf5,0x10,0x40,0x49,0x2e,0xce,0xb8,0x29,0x65,0xe7,0x76,0x87, + 0x86,0x87,0x05,0x23,0x64,0xad,0x85,0x5c,0x67,0x83,0x8b,0xdc,0xd2,0xfa,0xb9,0xe3, + 0xdb,0x22,0x56,0x64,0x36,0x30,0xb9,0xb1,0x65,0xb9,0x4b,0xba,0x74,0xa1,0x25,0x24, + 0x46,0xcb,0xe6,0x34,0x94,0x43,0x30,0x04,0x65,0xa4,0x0b,0x19,0x2e,0x4b,0x64,0x19, + 0xe6,0xca,0x29,0xa6,0x5c,0xf4,0x38,0x14,0x07,0x8a,0x5c,0xb1,0xbe,0x74,0x8d,0xdc, + 0x85,0xc6,0xfc,0xa5,0xa1,0x56,0xc9,0x73,0x61,0xdd,0x51,0x15,0xa4,0x49,0xa9,0x8b, + 0x4f,0x53,0x90,0x31,0xb4,0xe7,0xd5,0xe1,0x87,0xcf,0x9f,0x71,0x3e,0x96,0xb4,0xf9, + 0x88,0x05,0x59,0x2a,0x67,0x88,0xa2,0xdb,0xef,0x08,0xfe,0x27,0xfd,0x47,0xba,0x65, + 0x66,0x86,0x75,0x03,0x19,0x19,0x9a,0x48,0x2f,0x6e,0x2f,0xd6,0x53,0xa4,0x71,0x29, + 0x67,0xee,0x7e,0x0e,0xeb,0xaa,0x01,0x1b,0xb0,0x65,0x22,0x08,0x7d,0x45,0xab,0x99, + 0x2d,0xab,0x89,0xef,0x05,0x5a,0xab,0xcb,0x42,0xfa,0x44,0x4c,0xe5,0x87,0xf3,0x55, + 0x32,0x28,0xc6,0x51,0xe2,0x96,0x33,0x18,0xe9,0x61,0x94,0x69,0x5f,0x1c,0x14,0x72, + 0xee,0x72,0xb2,0x73,0x2c,0xe9,0x85,0xfe,0x48,0x56,0xe9,0xed,0xdb,0x42,0xf6,0x62, + 0x67,0xdf,0x23,0x1b,0x01,0xa3,0x62,0x83,0x0e,0x0f,0x4c,0x9c,0x5a,0x43,0x32,0xdb, + 0x2a,0x86,0x53,0xcf,0xbe,0xdf,0x1b,0x79,0xb4,0xc2,0xe8,0x0c,0xe3,0x69,0x56,0x71, + 0xa8,0xd1,0x34,0x02,0x23,0x5d,0xcc,0xaa,0xc1,0x28,0xa2,0xc0,0x8f,0x9c,0x71,0x74, + 0x52,0x91,0x17,0x04,0x35,0xf0,0x04,0x48,0xc9,0xdc,0x82,0x9e,0xf8,0x57,0x7a,0x83, + 0x93,0x64,0x09,0xf8,0x76,0xba,0xcd,0x87,0x0f,0xb6,0x0e,0x3c,0x1f,0x13,0xf2,0x8e, + 0x9a,0xb3,0x82,0xe8,0x6c,0x2f,0x42,0x37,0x9c,0x6f,0x2b,0x77,0x85,0xf5,0xe3,0xd0, + 0xcd,0x75,0xe6,0x36,0x47,0x45,0xf2,0x91,0x0a,0xdb,0xf0,0xad,0x83,0x7d,0x97,0xa3, + 0x4b,0x9c,0xd4,0x25,0x4f,0xd0,0x25,0x1e,0x82,0xdc,0x76,0x39,0xd6,0xcd,0x05,0x75, + 0xf4,0x9b,0x1a,0x43,0xf3,0xa3,0x4f,0x0b,0xe2,0x99,0xf1,0x87,0x5a,0xb4,0x2f,0x51, + 0x41,0xa5,0xd5,0x24,0xc3,0xf5,0x78,0x1b,0x73,0x9a,0x85,0xe4,0xcb,0xc6,0xa6,0x0a, + 0xdc,0x13,0x1d,0xd4,0x18,0x13,0xda,0xd5,0xae,0xd8,0xc0,0xe4,0xdd,0x78,0x8e,0xe8, + 0x4f,0xfe,0x63,0xba,0x5d,0x2a,0x60,0x58,0x69,0xdf,0x2e,0xcd,0x4d,0x08,0x8b,0xba, + 0xc0,0x35,0xdf,0x8b,0x3e,0xbf,0x8c,0x39,0xe8,0x9b,0xcf,0x3d,0xf4,0xf2,0x51,0x9c, + 0x89,0x10,0xd1,0x99,0x5c,0x38,0x0f,0x02,0xe9,0xd9,0x40,0x3b,0xfa,0x60,0x5e,0xbb, + 0x42,0x95,0x6c,0x7d,0x9f,0x13,0x89,0x02,0x6a,0x91,0xd0,0xd6,0x4a,0xc1,0x6a,0x3c, + 0xc6,0x7c,0xbe,0xac,0x84,0xe0,0x36,0x98,0x90,0xc6,0x68,0xed,0x0b,0xec,0x64,0x23, + 0xac,0x15,0x70,0xe8,0x1f,0x11,0xe0,0x0d,0x6c,0x19,0xaf,0xf3,0x36,0x4f,0x17,0xa9, + 0x9c,0xdf,0x2f,0x8b,0xd8,0xfd,0xff,0x9d,0x62,0x29,0xd9,0xc2,0xc7,0x5b,0x50,0x2c, + 0x80,0xd1,0xd6,0x28,0x16,0xaa,0xbc,0xa5,0xff,0x02,0xae,0xf4,0x9a,0x0a,0x51,0x1a, + 0xa4,0x7e,0x75,0x67,0x5a,0xa3,0x64,0xc0,0xdd,0x10,0x40,0x73,0xb8,0x2b,0x3c,0x21, + 0x21,0x60,0x60,0xc5,0x94,0x07,0x8b,0xf3,0xc6,0x8a,0x7d,0xb7,0x90,0x68,0x3e,0xb1, + 0x71,0xf2,0x97,0x20,0xb0,0x01,0x60,0x4e,0x66,0x1e,0xff,0xf4,0x2e,0x0d,0xd5,0x20, + 0x06,0x20,0x99,0x4f,0xb7,0xdb,0x6e,0x4d,0x2a,0x49,0x40,0x16,0xb9,0x85,0xe6,0x41, + 0x6f,0x21,0x80,0xa0,0x5b,0x94,0x98,0x51,0x1f,0xc3,0xd7,0xb4,0x30,0xee,0xef,0x50, + 0xb6,0x22,0xff,0x1c,0x1d,0xd0,0x47,0x03,0x29,0x97,0xef,0x50,0x5f,0xc0,0x79,0x75, + 0x5f,0x76,0xe5,0x88,0xdb,0xb6,0x5f,0xb1,0x8f,0x05,0x65,0x44,0xbf,0x25,0xb5,0x24, + 0xfc,0x39,0xbc,0xd8,0x6b,0x28,0x0a,0x2c,0x61,0x59,0xf0,0x3c,0x59,0xa8,0x1f,0x07, + 0x3d,0x34,0xdc,0x30,0x1f,0xa3,0x43,0xd5,0xae,0x52,0x82,0x5d,0xd4,0xc4,0xc3,0x7d, + 0x4b,0xde,0x95,0x20,0x63,0xb7,0x83,0x5b,0x23,0x7b,0xad,0xfd,0xb1,0x00,0x1b,0x7a, + 0x87,0x10,0xef,0xdd,0x9d,0x0e,0xd7,0xdf,0x22,0xaa,0xd1,0xae,0xd6,0xeb,0xaa,0x70, + 0x69,0x85,0xee,0x10,0x38,0xbd,0x46,0x65,0x88,0xec,0xc2,0xec,0xfb,0x65,0x32,0x9f, + 0xc9,0x0f,0x35,0x2f,0x67,0xa2,0x38,0x3a,0xba,0xcb,0x4c,0xf8,0x7b,0x4e,0xd4,0xa3, + 0x2f,0x84,0x03,0x3e,0xb8,0xa1,0x5b,0x70,0x47,0xf3,0x49,0x9d,0x84,0xcf,0x43,0x5d, + 0x22,0x0b,0x30,0xb5,0x17,0x62,0x5b,0xb9,0x97,0x03,0xe3,0x8f,0xf8,0x15,0xc4,0xd4, + 0xac,0xbf,0xe3,0x7f,0xd9,0x61,0x6c,0x8c,0x8b,0x21,0xcd,0x5c,0xb6,0x78,0xb8,0xe3, + 0x15,0x1e,0xe8,0x54,0x35,0x14,0x0d,0xf7,0xab,0x9b,0xc5,0xd2,0x8e,0x6a,0xa1,0xf2, + 0x98,0x1d,0xe7,0x85,0xb6,0xb8,0x2f,0x52,0xd0,0xff,0x15,0x93,0xf3,0x69,0xcd,0xc5, + 0x11,0xbe,0x70,0x11,0xf2,0xa4,0x15,0xb5,0x68,0x63,0x40,0xc3,0x91,0xa3,0x14,0x30, + 0x85,0xb5,0xd3,0x3f,0xce,0xe5,0x40,0xed,0xa0,0xd4,0x9c,0x55,0x8a,0x95,0x74,0x23, + 0x09,0x98,0x70,0xe5,0x4b,0x77,0x3e,0x21,0x92,0xd3,0x69,0x04,0xde,0xd4,0xd0,0x45, + 0x82,0x14,0x05,0x78,0x0e,0xbd,0x5d,0x61,0x6d,0xeb,0x62,0xcd,0xf4,0x85,0x33,0xe9, + 0x4a,0x34,0xdd,0x55,0x52,0x38,0x5d,0xb1,0xdd,0xfa,0x4b,0x71,0xd3,0x75,0x90,0x6a, + 0x84,0xb5,0xdc,0x8d,0x9b,0x9c,0xd6,0x78,0x9a,0x55,0xe8,0xaa,0x99,0xfb,0x78,0xeb, + 0x11,0x16,0x46,0x8f,0x55,0x53,0x44,0x90,0x01,0x28,0xe6,0x54,0x72,0x3b,0x16,0x6b, + 0xae,0xd2,0x96,0x4c,0x70,0x2b,0x0f,0xad,0x40,0x25,0xe5,0x5e,0x74,0x87,0xbb,0xea, + 0x9d,0x14,0xa9,0xa8,0xfa,0x94,0x61,0xbf,0x8a,0x9e,0xdf,0x80,0x9a,0x6f,0x04,0x37, + 0xc3,0x8d,0x9c,0x51,0x52,0x8d,0x06,0xb9,0x16,0x57,0xec,0x0e,0x86,0x6d,0x72,0x5c, + 0xc2,0x8c,0x31,0x3e,0x58,0x72,0x3c,0xb8,0x9a,0xdb,0x19,0xcd,0x4b,0x3f,0xeb,0x56, + 0xab,0x5e,0x07,0xed,0x90,0xb5,0x01,0xcd,0x65,0xe3,0x17,0x81,0x45,0xf5,0x4d,0x2a, + 0xd3,0xb2,0xd9,0xf0,0xbd,0x3e,0x5f,0xb9,0xd7,0xf2,0xcf,0x5c,0x5a,0x80,0x01,0x64, + 0xbb,0x35,0x5d,0x75,0x24,0xa9,0x0e,0x17,0xc9,0x66,0x4b,0x59,0x14,0x34,0x39,0x2c, + 0x69,0xc3,0x3d,0xe5,0x91,0x2a,0x3f,0xc2,0x66,0x60,0x62,0x50,0xae,0x8d,0xb2,0x39, + 0xfc,0x77,0xe5,0xf7,0xf8,0x03,0x7f,0x63,0xc0,0xee,0xc9,0x15,0x2b,0xf9,0xb3,0xc1, + 0x51,0x62,0x1b,0xa6,0xa1,0xe1,0xaf,0xc0,0x41,0x4e,0x06,0xac,0x34,0x65,0xd7,0x6f, + 0x00,0x5e,0x2b,0xa0,0x06,0xe9,0x63,0x60,0x5a,0xa8,0x8e,0x4e,0xbf,0xf5,0x68,0x78, + 0x3b,0x95,0x0f,0x84,0xb6,0x0a,0x1a,0x72,0x44,0x85,0x30,0x05,0x3b,0x4c,0x54,0xb3, + 0x8e,0x5d,0x2e,0xa1,0xb2,0xa0,0x4e,0xf1,0xe5,0x5b,0x5d,0xf4,0x8f,0xec,0x49,0x42, + 0x0a,0xe4,0x7a,0xa6,0xe7,0x87,0xd1,0x4b,0x2e,0xe4,0xe8,0x17,0xc6,0x6c,0x85,0x22, + 0xb9,0xca,0xe8,0x80,0x1f,0xe8,0x60,0xa1,0xa7,0xac,0xb2,0x6e,0x48,0xf3,0x14,0x2f, + 0xae,0xec,0xb2,0x9b,0xf4,0x63,0x3f,0x49,0x21,0x6d,0xe3,0x29,0x3e,0x6b,0xa9,0xff, + 0x67,0xee,0x97,0xe0,0x75,0x4b,0x0b,0xcb,0xc8,0xe6,0x7f,0xdf,0xd4,0xa5,0x15,0x33, + 0x2e,0xd6,0xd4,0x58,0x74,0xda,0xf1,0xd9,0x2d,0x6f,0x43,0x4c,0xde,0x85,0xc9,0xef, + 0xdb,0x92,0xdc,0x76,0x93,0x0a,0x68,0x6e,0x6d,0x8f,0x4e,0x5f,0x6e,0xae,0xd2,0x86, + 0xe4,0x7c,0x80,0x6f,0x6f,0xef,0x85,0x05,0xc2,0x4b,0x29,0x45,0x6f,0x18,0x1e,0xb4, + 0xbd,0xea,0xb7,0x8f,0xb4,0x25,0xc4,0x57,0xc8,0x77,0xe3,0xef,0x7f,0xe7,0x6a,0x3d, + 0xd0,0x20,0xfb,0xdf,0x3e,0x00,0x79,0x3b,0x81,0x8d,0x6d,0xfb,0xf7,0xc6,0x7e,0x8d, + 0x10,0x8f,0xec,0x6e,0x07,0x4d,0x62,0x8e,0x8f,0xb4,0xa2,0x8f,0x9f,0xb4,0x76,0x43, + 0x11,0x8e,0x1b,0xbb,0xc1,0xe0,0x86,0x4c,0x98,0xbd,0x18,0x32,0x77,0x98,0x9d,0xc4, + 0xaa,0x6d,0x5d,0xf5,0x5f,0xe8,0x0d,0x5c,0xd7,0x09,0x8f,0x17,0x16,0x5d,0x95,0xd4, + 0xab,0x62,0x6d,0xef,0x4c,0xf1,0xde,0x73,0xe1,0xf6,0xe7,0xa7,0x9d,0xc2,0x73,0x85, + 0xec,0xb7,0xa4,0xa4,0x74,0xbb,0x24,0xb3,0x1a,0xdf,0x8e,0x86,0x34,0x7f,0x36,0x00, + 0x4f,0x04,0x5b,0xea,0x31,0xec,0x1e,0xf0,0x96,0x53,0x43,0xbc,0x67,0xf1,0x6d,0xc7, + 0x0f,0x46,0xe3,0xff,0x36,0xaa,0x63,0xc7,0x69,0x6b,0xf1,0x1b,0xf6,0xea,0xad,0xf3, + 0xa5,0x9a,0x10,0x27,0xbf,0x6c,0x7d,0xb3,0xf7,0x7a,0xfb,0xb0,0xd9,0x2b,0xd9,0x0e, + 0x69,0xb7,0xe6,0x44,0x0f,0xa3,0xcb,0xd9,0x2b,0x5a,0xc8,0x87,0x4f,0x83,0xbf,0x70, + 0x88,0x26,0x53,0xed,0x3a,0x10,0x64,0x93,0x05,0xa8,0x39,0x7e,0x7b,0x59,0xfc,0x8b, + 0xcf,0xee,0x1f,0x6f,0xb8,0x9f,0x29,0x83,0xcd,0xf8,0x35,0xd9,0x71,0x7c,0x74,0x9b, + 0x44,0xa1,0xe3,0x7f,0xa9,0xd7,0x41,0xbd,0x8e,0x1e,0xae,0xae,0xc1,0x56,0x99,0x3a, + 0xed,0x3d,0xe6,0xe4,0x02,0xac,0x26,0xbb,0x12,0xd7,0x22,0xb0,0xed,0xc3,0x56,0x21, + 0x29,0xc7,0x45,0x7b,0xea,0xa3,0x41,0x68,0x6f,0x40,0xef,0xfc,0x93,0x5d,0x70,0x4f, + 0x8e,0x9c,0xc7,0xde,0x33,0xdd,0xf7,0x88,0x6e,0xb0,0x37,0xcf,0x61,0x5e,0xd1,0x5f, + 0x87,0x06,0x92,0x5b,0x9f,0xc1,0x1d,0xfa,0xee,0x8f,0x69,0x9c,0x3f,0xbe,0x60,0x44, + 0x71,0x8d,0x8a,0x00,0xb3,0x26,0x4a,0x21,0xe3,0x46,0x6f,0x24,0xaf,0x9f,0x70,0x92, + 0x04,0x6b,0x73,0xf6,0xb0,0xa9,0x67,0xd2,0xc3,0x42,0x67,0xcb,0x51,0x41,0x79,0x83, + 0x85,0x3b,0x09,0x1c,0x31,0xa8,0x1d,0x27,0x61,0xc8,0x6a,0xda,0xd8,0x62,0x31,0xc1, + 0x76,0x0c,0x09,0xf7,0xee,0xaa,0xac,0x53,0x80,0xc3,0x66,0xcb,0x2e,0x43,0x40,0xbf, + 0x02,0xfb,0x62,0x22,0x31,0x06,0x50,0x60,0x42,0x75,0xa8,0x94,0x19,0xc5,0x4c,0xaf, + 0xfc,0xfa,0x4c,0x50,0x30,0x70,0x06,0x59,0xcf,0x74,0xd8,0x0b,0xf0,0xc5,0xbe,0xbe, + 0x7d,0x26,0x98,0x6c,0x37,0x2d,0x4f,0x48,0xff,0x77,0x47,0x8f,0xd4,0x65,0xb6,0x50, + 0x7c,0x27,0x21,0xdd,0xa0,0x16,0x3f,0x58,0x7f,0x76,0xc8,0x64,0xe3,0x25,0x3a,0xd8, + 0xf3,0x07,0x42,0x71,0xda,0x2e,0x6a,0x4a,0x09,0x40,0x92,0xd3,0xa7,0x68,0x40,0xe3, + 0xaa,0x0f,0xa0,0x99,0x17,0xa3,0x62,0xba,0x4c,0xad,0x65,0x3c,0xa6,0x96,0x63,0x4d, + 0x00,0x07,0x0b,0x98,0x39,0xd5,0x6b,0x4b,0x8b,0x35,0x97,0x2d,0x27,0x95,0x5b,0x36, + 0x28,0x81,0x0f,0xbd,0x38,0x5b,0x41,0x38,0x6a,0x4d,0x9b,0xc2,0xd9,0x6b,0xbd,0x49, + 0x02,0x2c,0x7a,0xdc,0xbd,0x28,0x7c,0x41,0xe7,0x1d,0x82,0x2b,0xfb,0xf3,0xb5,0xa7, + 0x03,0x2d,0x4e,0xba,0x70,0x3c,0x14,0x78,0x4b,0x4d,0x4f,0x42,0x6f,0x2f,0x47,0xb6, + 0x75,0x2e,0xc5,0xa5,0xa2,0xa5,0x55,0x45,0xf6,0x1f,0x67,0x0f,0x21,0x9b,0xb4,0xa6, + 0x74,0xf0,0x4c,0x2f,0x70,0x1e,0x5d,0x79,0xcb,0x4f,0xc4,0x26,0x59,0x6b,0x7c,0x02, + 0x21,0x52,0xe4,0xc0,0x76,0x3d,0xef,0x42,0xc1,0xda,0x94,0xa4,0x8f,0x70,0x34,0x40, + 0xda,0x1e,0xec,0xd0,0x29,0x3c,0x9c,0xd2,0x22,0xee,0x9c,0xb4,0x8e,0x71,0x3d,0x51, + 0x1f,0x1d,0x7a,0x25,0x11,0x42,0x6a,0x43,0x62,0x1a,0x95,0x5a,0x0f,0x72,0xb9,0xf3, + 0xe2,0xe4,0xc7,0x6e,0x12,0x3e,0x65,0x33,0xe4,0x93,0x9d,0x4a,0x0e,0x73,0x44,0xc0, + 0x22,0x14,0x55,0xdb,0x0e,0x8f,0x1c,0xe0,0x55,0xc8,0x6b,0x7f,0x87,0xf2,0x4c,0xd1, + 0x23,0x15,0x9e,0x52,0xe7,0xa4,0x64,0x90,0x67,0x71,0x9d,0x70,0x51,0x19,0x41,0xc1, + 0xaa,0x16,0xc1,0xfa,0xde,0x74,0x65,0x63,0x6a,0x8e,0xd5,0xa5,0xb4,0x38,0x49,0xd0, + 0xa3,0x17,0x6a,0xec,0xd0,0x9d,0x5f,0x51,0xed,0xc7,0xe3,0xd9,0x50,0x12,0x7e,0xea, + 0x6b,0xe6,0x8c,0x8d,0x9b,0xc5,0x2e,0x78,0x93,0x57,0x69,0xac,0x87,0x87,0x36,0x48, + 0xde,0x16,0x0b,0x1e,0x3c,0x89,0x54,0x43,0xca,0x5f,0x9e,0x43,0x79,0x79,0x7f,0x0b, + 0xa9,0x58,0x2b,0x08,0x9a,0x37,0x77,0xed,0xfc,0x57,0x68,0x52,0xf8,0x7a,0xbb,0xfb, + 0xea,0x64,0xb7,0x4d,0x42,0x34,0x97,0xa5,0x48,0xd1,0x60,0x42,0xf9,0x84,0x42,0xc8, + 0x22,0x3c,0xd0,0xf9,0x89,0x71,0x36,0xea,0x67,0xd7,0xe8,0xc1,0xd9,0x3e,0xb1,0x27, + 0x2b,0xe2,0xc8,0xf5,0xc7,0x2c,0xb6,0x70,0xe3,0xdd,0xa6,0xdb,0x92,0xcc,0x47,0x36, + 0x55,0xe1,0x9f,0xc9,0x93,0x80,0xd7,0x0b,0x6f,0x3c,0x87,0x2e,0x13,0xef,0x4f,0x26, + 0x54,0x1f,0xc9,0xf5,0xd8,0x37,0xf7,0x71,0xd8,0x04,0xa7,0xec,0x97,0x56,0xd7,0xe0, + 0x86,0xc8,0xc0,0x42,0x1c,0xad,0x60,0x33,0xa5,0xcf,0xb0,0xd9,0xab,0x1f,0x9c,0xe2, + 0x09,0x8e,0xa2,0x17,0xb6,0x5c,0x58,0x92,0x1f,0xce,0x47,0x36,0x55,0x1e,0x39,0xf3, + 0x85,0x8d,0xeb,0xfc,0x37,0xaf,0x51,0x83,0xfe,0xcd,0xb1,0xd8,0x2b,0xe2,0x49,0x57, + 0x92,0x0e,0x83,0x92,0x9b,0xc1,0x59,0x93,0xd9,0xcc,0x46,0xc8,0x2a,0xe3,0x64,0xbd, + 0x0e,0x7b,0x9e,0x73,0x25,0xa0,0x36,0x62,0x46,0xc4,0x3e,0x04,0xad,0x88,0x97,0xad, + 0x0f,0x85,0x44,0xc9,0x16,0xe5,0x61,0x72,0x47,0x05,0xf8,0xb6,0x05,0xa7,0x65,0x42, + 0x8e,0xa6,0x59,0xb8,0x7f,0x47,0x62,0x63,0xc6,0xe6,0x4e,0xfc,0x23,0x60,0x69,0x53, + 0x87,0xa7,0xf5,0x34,0xf4,0x0d,0x1d,0x73,0xc7,0x95,0xa9,0xb4,0x76,0x78,0x5a,0x88, + 0x09,0x42,0xe8,0x0f,0x3e,0xa5,0x52,0x8a,0x20,0xc7,0xb2,0xd1,0x5c,0xe8,0x12,0xca, + 0x72,0x86,0x92,0xce,0xe6,0xa6,0x70,0xc1,0xee,0xcf,0x45,0xc1,0xa2,0x16,0x5b,0x89, + 0x89,0x8e,0x26,0x8d,0x99,0x0a,0x53,0x6a,0x79,0xc7,0xb3,0xd0,0xdc,0xea,0x9f,0x79, + 0xce,0x54,0x93,0x4f,0x95,0xa4,0x37,0x50,0x6c,0x41,0xbb,0x3f,0x22,0xeb,0x62,0x4b, + 0x0e,0x8c,0xf4,0x7b,0xad,0xe1,0x02,0x6a,0x4e,0x4e,0x46,0x0c,0xa5,0x19,0x6e,0x5a, + 0x0f,0xad,0xd0,0xa5,0xe3,0x4c,0x43,0x7a,0x0f,0x62,0xe5,0x25,0xdd,0xe9,0x67,0x4b, + 0x8e,0xae,0xbb,0x4b,0xb7,0x10,0x18,0x6b,0xce,0x54,0xe4,0x51,0xae,0xac,0x6b,0x5a, + 0x87,0x8f,0x2b,0xef,0x19,0x7b,0x78,0x7b,0x93,0xa4,0xb2,0x1d,0x24,0x83,0x5c,0xe0, + 0x67,0x2f,0x9c,0xd6,0x3c,0xbf,0x4b,0x40,0xe6,0x98,0xb4,0x59,0x8b,0xf0,0x16,0x70, + 0x89,0x9e,0xa8,0x96,0x3d,0x91,0x44,0xd0,0x24,0x91,0xbc,0xb6,0x75,0x0e,0x5d,0x01, + 0xa1,0x13,0x35,0x86,0xb4,0x92,0x31,0xc1,0xa7,0x0d,0x4a,0x58,0xf4,0x0d,0x4d,0xd3, + 0x09,0x13,0xad,0x97,0xb5,0x93,0x45,0x31,0xe0,0x73,0x42,0xb7,0xf5,0xf3,0x64,0x3d, + 0xd9,0x94,0x73,0x42,0x14,0x84,0xce,0x1d,0xe4,0x93,0x64,0x0e,0xb2,0xb6,0x6c,0xd2, + 0x27,0x6a,0xbc,0xd2,0xde,0xc4,0xfc,0xf0,0x7b,0xce,0xc2,0xdf,0x36,0xf1,0x65,0x3c, + 0xa6,0x69,0xdb,0xf2,0x15,0xf4,0x8e,0x81,0x9b,0xdf,0xa5,0xe7,0x0b,0xf9,0x92,0x2c, + 0x58,0x68,0x95,0xa4,0x83,0xf5,0xdf,0x95,0x18,0xd1,0x83,0xc2,0x0a,0xfe,0x5e,0x08, + 0x29,0xc1,0xa2,0x8e,0x3c,0xb8,0x0e,0x7a,0x9b,0xd7,0x49,0xae,0x83,0x07,0x8e,0xf8, + 0x6c,0xd9,0xae,0x61,0x3d,0x46,0x5e,0xfe,0x75,0xd4,0x41,0xbe,0x7d,0xf9,0x1d,0x69, + 0x2e,0xb2,0xa3,0x70,0x43,0xba,0x0f,0xfb,0xe8,0xd5,0xb7,0x50,0x03,0xfa,0x57,0x19, + 0xac,0xf8,0x50,0x60,0xbd,0xbb,0x75,0x45,0x4e,0xd6,0x40,0x40,0xfd,0xfb,0x66,0x35, + 0x2e,0x63,0xb6,0xcf,0xc3,0xb3,0x82,0x47,0xcf,0x25,0x72,0xab,0x12,0xfe,0x91,0xda, + 0x2f,0x62,0xf9,0x3c,0xd6,0x2c,0x96,0x72,0x5c,0x86,0xda,0xa2,0x96,0x1c,0x98,0xcb, + 0xae,0x61,0x27,0x6f,0xba,0x13,0x6f,0xfb,0x13,0xd1,0xa7,0x67,0xee,0xf8,0x6f,0x24, + 0xaf,0x9f,0x2f,0x7f,0xb7,0x42,0xc5,0x1b,0xa9,0xc4,0x87,0xfd,0xb7,0x72,0x60,0x03, + 0x55,0x0f,0x15,0x35,0x64,0x8f,0xcf,0xde,0x64,0x5b,0x0f,0x24,0x50,0x60,0x49,0x0d, + 0x32,0x5a,0xf6,0x2d,0xe0,0xa1,0xe0,0xb4,0x18,0x29,0x58,0xb4,0x2c,0x61,0x51,0x1c, + 0x8c,0x03,0x12,0x77,0xfa,0x93,0xf2,0x47,0xf3,0x27,0x91,0xa7,0x3e,0xdf,0xb3,0xf1, + 0xd9,0x18,0xf4,0x66,0xad,0x17,0xa0,0xd3,0x6d,0x3e,0x99,0x35,0xd1,0x65,0x0a,0x80, + 0x3a,0xa9,0xc0,0x84,0x16,0x09,0x1a,0x19,0xc0,0xe3,0xc3,0xa3,0x90,0xe5,0x03,0xbd, + 0xfc,0x88,0x52,0x6c,0x9c,0x88,0x62,0x8d,0xe2,0x9e,0xe6,0x4c,0xdc,0xe3,0x0d,0x21, + 0x9e,0xa9,0xf7,0x7a,0xaa,0x64,0xf7,0xe5,0xc0,0x2f,0xd9,0xf8,0x52,0x86,0x36,0xac, + 0x7c,0x45,0x5c,0xc7,0x30,0x8a,0xde,0x8a,0x30,0x05,0xb9,0x35,0x95,0xec,0xa0,0x6e, + 0x2b,0x18,0xfa,0x3e,0xec,0x27,0x6a,0xc0,0xac,0x05,0x64,0x5f,0x5e,0x6a,0x8e,0x9c, + 0x2a,0x15,0x31,0xad,0x65,0x86,0x28,0xc7,0x6d,0x52,0x9a,0x2f,0x56,0x13,0x5a,0x20, + 0x2d,0x03,0x95,0xad,0x73,0x29,0x11,0xd8,0x6b,0x5a,0x0c,0x2d,0xd8,0x6a,0x9b,0xf1, + 0x1f,0x46,0x1c,0x05,0x19,0xe5,0xa9,0x5f,0x36,0x30,0xa5,0xf0,0x56,0xcd,0x5e,0x3a, + 0xe3,0xc6,0x53,0xde,0x1a,0x26,0x18,0xb4,0xc7,0x0e,0x2a,0x5d,0x62,0x2e,0xe6,0xc7, + 0x08,0x9d,0x71,0xce,0x1b,0x25,0x04,0xa1,0xb4,0x0c,0xa2,0x8c,0x05,0xcc,0x01,0xb6, + 0x63,0x44,0xc2,0x32,0x58,0x21,0xd4,0x83,0xcb,0xce,0xc3,0xed,0x7b,0xec,0x6d,0x9d, + 0xd8,0x74,0x4b,0x9b,0x8d,0x82,0x9b,0xa9,0xb2,0x54,0x4d,0xf9,0xfb,0x4c,0x1f,0x0a, + 0x23,0x00,0xbc,0x7b,0xb3,0x3d,0x2e,0x5a,0x91,0x3c,0x59,0xa6,0xeb,0xd4,0x88,0x6d, + 0xde,0x50,0x2f,0xa9,0xed,0x32,0xdc,0xe9,0x5d,0x13,0x70,0x27,0x76,0x7b,0x5c,0xba, + 0x05,0x19,0x7e,0x01,0xec,0xfb,0x73,0x99,0xe3,0x82,0xd9,0x7d,0x19,0xe8,0x1d,0x34, + 0xf0,0x08,0xd4,0x0b,0x14,0xcc,0x12,0xec,0xe0,0x33,0x8e,0xc6,0xfe,0x7a,0x1c,0x44, + 0x7e,0xdd,0xa6,0xa4,0xdb,0x65,0x84,0x92,0x89,0xb5,0xee,0x17,0x1e,0xff,0xf7,0x60, + 0x2b,0xba,0xec,0x85,0xbe,0xc8,0x53,0xb0,0x67,0x78,0xcc,0x55,0xd2,0x7c,0x7f,0xfc, + 0x49,0xec,0xa7,0xcc,0xb3,0x76,0x6b,0xd4,0x6f,0xf0,0xf4,0xd4,0x9e,0x34,0x86,0x53, + 0x4d,0xaa,0xaf,0xf7,0x46,0xb1,0x75,0x01,0xbd,0xf6,0x9f,0x05,0x54,0xd6,0x32,0xee, + 0x6b,0xe8,0xdf,0xab,0x9f,0x28,0xc9,0x56,0x4c,0xc8,0x15,0x5f,0x67,0xd5,0x3c,0xfe, + 0x9e,0x09,0xf1,0xe3,0x3f,0x81,0x25,0x7f,0xb3,0x51,0xa4,0x53,0x02,0x86,0xf8,0x75, + 0xa8,0x01,0x3f,0x77,0xa8,0x77,0x37,0xd3,0x9b,0xea,0x5d,0x5f,0xb8,0x85,0xb7,0x76, + 0x52,0x87,0x03,0xe7,0x1a,0x5e,0x9c,0x3d,0xb0,0x2a,0x5f,0xdc,0x18,0xd6,0x86,0x18, + 0x09,0x07,0xc6,0x0c,0x6a,0x91,0xc0,0x6c,0x4a,0x7f,0x40,0x68,0x5a,0x7e,0x8e,0x08, + 0x38,0x1b,0x5f,0x4e,0x37,0x35,0x06,0xfc,0xc2,0xca,0x32,0xcd,0x17,0x3f,0x42,0x4d, + 0xa8,0x8c,0x52,0x5f,0x3b,0x93,0x6f,0x1a,0xd2,0xd1,0xef,0x0d,0xee,0xf5,0xb9,0xa2, + 0xad,0x95,0x4f,0xdf,0x99,0x51,0x05,0x89,0x83,0x6e,0xcf,0xbf,0x98,0x5f,0xdf,0xea, + 0xe4,0xcd,0x13,0x3b,0xe8,0xa3,0xcf,0x50,0xbf,0x82,0xfa,0xe6,0x74,0x44,0x84,0x8d, + 0x66,0x85,0x2c,0x92,0x17,0x33,0x80,0xcd,0x7a,0xe1,0x54,0xa5,0x52,0xeb,0x5a,0x0b, + 0x21,0x3d,0x9b,0xfd,0x6f,0xb9,0xf9,0xd0,0x18,0x53,0xfd,0xff,0x3d,0x78,0x50,0x69, + 0xe4,0x87,0x12,0x55,0x34,0x5e,0x66,0x2a,0xc3,0x89,0x79,0x0c,0x86,0x16,0x64,0x30, + 0xfd,0x7f,0xf1,0x96,0xb5,0x1b,0x72,0xe6,0x44,0xf4,0xaa,0x99,0xf5,0xe0,0x6e,0x9f, + 0x87,0x8b,0x50,0x66,0xb6,0x3a,0xe8,0xd2,0x59,0x95,0xa0,0xf2,0xe8,0x50,0x65,0xc7, + 0xaf,0x0b,0xf9,0xd2,0xa5,0xec,0xd6,0xba,0x8e,0x7c,0x37,0x0c,0x95,0x76,0x09,0xe4, + 0x3e,0xc5,0xd6,0x10,0x45,0xaf,0x20,0x8b,0x22,0xa9,0xec,0x48,0xbb,0xa5,0x43,0xca, + 0x00,0x73,0x8a,0x6c,0xe8,0x19,0x4c,0x71,0xb1,0x74,0x7f,0xaa,0x77,0x92,0x92,0xe5, + 0x80,0x34,0x07,0x50,0xe8,0xf5,0xd6,0xa8,0x41,0xc1,0x7a,0xf3,0x89,0x49,0xdc,0x2f, + 0xbf,0x3c,0x14,0x33,0x01,0x57,0x9f,0x50,0x06,0x5b,0x73,0xff,0x78,0x15,0xcc,0xeb, + 0x0d,0x94,0x91,0xf4,0x2e,0xa5,0xbf,0xc6,0x3a,0x8a,0xf0,0x3d,0x30,0x4b,0x28,0xaa, + 0x3d,0xbc,0xe1,0x31,0xdc,0x3e,0x10,0x63,0x4f,0x8c,0xfc,0xd0,0x5f,0xfc,0x9c,0x31, + 0x09,0x07,0xe8,0xa2,0x1f,0x56,0x21,0x58,0x78,0x3b,0x6c,0xfa,0x16,0x3a,0xa3,0xcb, + 0xdc,0x88,0x58,0xdd,0x9e,0xa4,0x4f,0x01,0xfd,0xda,0x76,0x54,0xe6,0x1b,0xa6,0x7c, + 0x89,0x05,0xa8,0x98,0x76,0xde,0x26,0x9d,0xc9,0xee,0xfd,0x4a,0x56,0x63,0x9d,0xd8, + 0x22,0x20,0x9b,0x64,0xc8,0xb3,0xf4,0xfb,0x39,0xd8,0xfa,0x36,0x8b,0x5d,0x66,0x70, + 0xb4,0x6c,0xba,0xf4,0x55,0xa5,0x7f,0xb0,0x9c,0x5c,0xbf,0xa5,0x36,0x8b,0x89,0xfd, + 0x65,0x8d,0x35,0xf8,0xdc,0xbf,0xb1,0x5e,0x13,0x93,0xff,0xe0,0x2a,0xf8,0x07,0x43, + 0xf9,0x8b,0xd3,0x91,0x54,0x30,0x43,0x8a,0x0e,0x02,0x87,0x58,0x8e,0xd3,0x3c,0x46, + 0x7a,0x5d,0xda,0xeb,0xe8,0x19,0x0d,0x84,0x8d,0xc5,0x8c,0xf7,0x1a,0x59,0xd7,0x62, + 0x2f,0x3a,0x2c,0xf7,0x46,0x40,0xbc,0xd2,0x08,0xd8,0x6c,0x07,0x22,0xf1,0x5f,0xfe, + 0x4d,0xbf,0x74,0x59,0xb7,0x86,0x2f,0xa4,0x8e,0xe7,0x63,0x55,0xaa,0x88,0x75,0x57, + 0x86,0x2f,0x78,0xe9,0x83,0xb3,0x00,0xc8,0xdf,0x22,0xa3,0xaa,0xf7,0xec,0x58,0xa7, + 0x1f,0x7d,0xd4,0x7d,0xb0,0xfa,0x48,0x97,0x87,0xdb,0x01,0x7a,0x7a,0xd1,0xbb,0x5a, + 0x65,0xdb,0x6e,0x1e,0x72,0xbf,0x59,0x7a,0x05,0x9b,0x91,0xad,0x72,0x83,0x9f,0x74, + 0x23,0x3c,0xed,0x6f,0x8f,0x90,0x04,0x93,0x1d,0xb4,0x8d,0xbe,0xaf,0xfe,0x20,0x5a, + 0xac,0xfb,0x59,0xf4,0xbb,0xb9,0x30,0x96,0x4c,0x74,0x81,0x72,0x72,0x5d,0xa6,0x1a, + 0x57,0x9a,0xe4,0xf5,0x02,0x29,0xe0,0x6e,0x07,0xc4,0x2a,0x1e,0x01,0xb3,0x72,0x9d, + 0x29,0x6d,0x49,0xe6,0x86,0x37,0xd2,0x89,0x53,0x5b,0xc4,0x16,0x3c,0xb2,0x11,0xdc, + 0xa8,0x14,0x76,0x4b,0xf3,0x60,0xd4,0xc7,0x32,0xaf,0xf6,0x1f,0x01,0xb1,0x16,0x1b, + 0xb7,0xdd,0xec,0x3f,0xa7,0x12,0x77,0x88,0xdb,0x59,0xa6,0xa3,0x58,0xbe,0xb8,0xff, + 0xf4,0x11,0xfe,0x03,0x34,0x8f,0x6e,0x27,0x64,0x93,0x93,0xa0,0x7e,0x86,0x9b,0xe3, + 0x85,0x8c,0xf6,0x13,0x35,0xaa,0xc8,0x17,0xe0,0xee,0xa0,0xc7,0x77,0x65,0x07,0x29, + 0xe3,0x0a,0x21,0x77,0xf2,0xa5,0x6f,0x26,0x61,0xed,0xa9,0xd6,0xfa,0x07,0x5b,0x12, + 0x6a,0x67,0x6b,0x24,0xfd,0x8c,0xcd,0xf6,0x0b,0xb2,0xcf,0xb1,0xff,0x85,0xa4,0x22, + 0xf5,0x61,0x57,0x37,0x30,0x87,0x28,0x64,0xa2,0xc5,0x7c,0x40,0xbb,0x85,0x48,0x2e, + 0x62,0x01,0xe8,0xd2,0x15,0xf6,0x20,0xc0,0xd9,0xb0,0xca,0xa6,0xb8,0x21,0x79,0xbe, + 0x0d,0x80,0x52,0xb6,0xe6,0x16,0x39,0x92,0x46,0xeb,0x8f,0x87,0xd6,0xe3,0x2b,0x53, + 0x82,0x65,0x19,0x37,0x60,0x42,0xf9,0x82,0xe5,0xb3,0xe7,0x97,0xb1,0x62,0x92,0xf8, + 0xd8,0xb9,0x22,0x7e,0x7a,0x4f,0x2c,0x14,0x29,0x4c,0xaa,0xd2,0xf4,0x65,0x78,0xeb, + 0x85,0x04,0x8e,0xf1,0x11,0x69,0x3a,0xb2,0x6d,0xe2,0x29,0x45,0xa5,0xb0,0x7d,0x0f, + 0x69,0x89,0xfd,0x0a,0xbc,0x91,0x6a,0x5a,0xee,0xc3,0x6e,0xa9,0xba,0x81,0xf4,0xe9, + 0x19,0xba,0x8c,0x0f,0x72,0x4f,0x63,0x29,0x29,0xb4,0x20,0x98,0x13,0x66,0x1b,0xa9, + 0xef,0xb3,0xfa,0xb7,0xeb,0x40,0x86,0x94,0x94,0xb7,0xac,0x6b,0x7e,0xb7,0xcb,0x27, + 0x63,0x8e,0x35,0x1b,0xf2,0xdc,0xc4,0x74,0xaa,0x72,0x49,0x83,0xae,0xce,0x83,0xf9, + 0x02,0x04,0x07,0xb3,0x63,0x4c,0x39,0x52,0xb2,0x0c,0xd3,0x1e,0xbc,0xcf,0x35,0xe9, + 0x7e,0xac,0x2c,0x2e,0xef,0xf9,0x65,0xad,0xab,0x90,0x8d,0x83,0x26,0xce,0x7a,0x87, + 0x81,0x51,0xfa,0x21,0xdb,0xb3,0x6a,0xa7,0x44,0xfd,0x33,0x00,0x76,0x13,0xac,0xe2, + 0x43,0x96,0xbe,0x87,0x92,0x92,0x0f,0x43,0xe5,0xdc,0x3c,0xd6,0xc6,0x14,0x5f,0x8a, + 0xd8,0xbd,0xba,0x96,0xf7,0x3d,0x83,0x90,0x41,0xd3,0x71,0xe7,0x7c,0x7e,0x73,0x96, + 0x00,0x52,0xf3,0x21,0xda,0x3c,0x4f,0x03,0x0a,0x37,0xa5,0x5a,0x9a,0x7c,0x44,0x44, + 0x76,0x45,0xbd,0xb7,0x10,0xbd,0xf4,0x93,0xc1,0xd7,0x86,0xe2,0xba,0x17,0x8c,0x60, + 0x41,0x6a,0x0c,0x68,0x15,0x38,0x27,0xd7,0xc2,0xea,0xe2,0xdc,0x75,0x77,0xe6,0x64, + 0x7e,0x95,0xe5,0x4f,0xb3,0xa4,0xb2,0x12,0x6e,0x5b,0x71,0x14,0x51,0x36,0xf6,0x61, + 0x47,0x48,0x36,0xf2,0x12,0x2c,0x03,0x13,0xe7,0x6a,0xed,0x97,0x04,0x12,0x5c,0x86, + 0x50,0xb7,0x06,0xf7,0x3e,0x5b,0x86,0xdb,0x04,0xf9,0x16,0xdf,0x0c,0xfd,0x70,0x9f, + 0x88,0x58,0x3a,0xfe,0xd2,0x3a,0xbe,0xca,0x0b,0xde,0xa0,0x5e,0x1b,0x5c,0xa7,0xfb, + 0xca,0x9d,0x73,0xef,0x53,0xcb,0x2f,0x99,0xfd,0xf5,0x85,0x7f,0x13,0x3e,0x71,0x9e, + 0x08,0x84,0x4f,0x2d,0xdb,0xc4,0x61,0xbe,0xcd,0x5d,0xe1,0xba,0x58,0xa4,0xe9,0xa7, + 0xf7,0xc3,0x46,0x92,0xb7,0x5e,0x64,0xd8,0xf9,0xf3,0xee,0xdd,0x5c,0xd3,0x1c,0xe2, + 0x05,0x5f,0x31,0x1b,0xd2,0x1e,0xb9,0x0b,0xe7,0x50,0xa0,0x5d,0x5f,0xdc,0x87,0x79, + 0x89,0xab,0x6c,0x48,0x29,0x01,0xf7,0x9a,0x49,0xdd,0x07,0x93,0x90,0x5d,0xd7,0xea, + 0x8f,0x53,0x28,0xae,0x99,0xe9,0xa6,0xde,0x4a,0x33,0xce,0x0e,0x7f,0xf2,0x5e,0x04, + 0xe5,0x03,0x98,0xf5,0x32,0xc5,0x83,0xc0,0x3f,0xe0,0xcf,0xdc,0x52,0x30,0xd7,0x60, + 0x2b,0x5e,0x05,0x69,0x88,0xfd,0x65,0x38,0x41,0x71,0x07,0x74,0xf4,0x34,0x53,0xf0, + 0x08,0xc3,0x99,0xf4,0xba,0xe3,0xec,0x22,0xf3,0x45,0x5c,0x59,0x55,0xef,0x17,0x3f, + 0x0a,0x75,0x12,0x59,0x74,0x9c,0x1b,0xcf,0x45,0x38,0x2e,0x08,0xf7,0x9f,0xb4,0xb1, + 0x28,0x24,0xa8,0x42,0x91,0x15,0x8f,0x09,0xcb,0x32,0xc8,0x99,0xa3,0x87,0xa8,0xf7, + 0xfc,0x8f,0x96,0xf7,0xe6,0x03,0xd8,0x61,0x61,0xa1,0x86,0x70,0x34,0x20,0xf2,0x62, + 0xfb,0xe8,0x4d,0x3c,0x5c,0x57,0x39,0x13,0x0e,0xa5,0x0a,0x97,0xe6,0x17,0x6a,0xd7, + 0xa9,0x4a,0x7a,0xa4,0xb5,0xbc,0x27,0x91,0xc3,0xfa,0x2a,0x84,0x5b,0xa6,0x99,0x7a, + 0x8c,0x97,0xdb,0x2a,0xf5,0x19,0xbc,0xd3,0xe1,0x8a,0x0d,0x61,0x5a,0x6b,0x70,0x15, + 0x75,0x26,0xb9,0xbb,0xea,0xe8,0x60,0x53,0x35,0x66,0xd2,0x5c,0xaa,0xab,0x79,0x09, + 0x1e,0xcb,0xb5,0x6d,0x63,0x07,0xac,0xf8,0x31,0x8b,0x6d,0xed,0x7d,0x15,0x8b,0x69, + 0xef,0x0c,0x84,0x60,0x44,0x26,0x9b,0x49,0xaf,0x4c,0xa7,0xb2,0x09,0xc8,0x39,0x69, + 0x71,0x02,0x39,0x38,0xe5,0x07,0xb2,0xea,0xee,0xc1,0xac,0x8c,0x5a,0x69,0x85,0x64, + 0x21,0x78,0x06,0x2d,0x35,0x5b,0x24,0x98,0x4b,0xf0,0xc4,0x9c,0x3d,0x1b,0xb8,0x6d, + 0x8a,0xe7,0x9b,0x4b,0x7e,0x51,0x88,0x4c,0x6f,0x31,0xe1,0xbd,0x35,0xaa,0x39,0x60, + 0xc8,0x14,0xd5,0xbd,0xfe,0xab,0x49,0x4b,0x0c,0x60,0x85,0x78,0xfb,0x4b,0x90,0xe0, + 0xdf,0xf5,0x1f,0x36,0xd0,0x6f,0x14,0xdb,0xc5,0x5a,0x00,0xc4,0x1c,0xb3,0xd3,0x7a, + 0x2e,0xd3,0x1c,0x12,0x18,0x4f,0x44,0x5a,0x71,0x90,0x47,0x4e,0x75,0x4a,0x1d,0x7d, + 0x08,0x9f,0x65,0x22,0x51,0x29,0xb2,0x21,0xc6,0xa0,0x4a,0xd4,0xde,0x21,0x6d,0x46, + 0x44,0x3c,0x97,0x64,0xc1,0x1e,0x2f,0xb2,0x1a,0x5e,0x3d,0x33,0xa1,0xa2,0x73,0x2a, + 0x59,0xd9,0xec,0xc2,0xb1,0x05,0x13,0x19,0xd3,0x42,0xa6,0xc4,0x9d,0x90,0x94,0xa1, + 0x5f,0xf9,0x13,0x3e,0x99,0xf8,0x28,0x89,0xb1,0x7a,0x01,0x1a,0x77,0x4e,0x1b,0xfa, + 0xc5,0x69,0xb5,0xfe,0xac,0x0b,0x5a,0xa4,0x38,0x79,0xcd,0xc3,0x1f,0x3c,0x0b,0x02, + 0xa6,0xb7,0x7a,0x28,0xa5,0xfa,0x2d,0x53,0x0a,0xa7,0x97,0xd3,0x0b,0xe6,0xb5,0x79, + 0x50,0x37,0x35,0xc9,0xf6,0x72,0xe2,0x54,0x48,0xde,0x1a,0xc1,0xa2,0x07,0x74,0x86, + 0x15,0x36,0x6e,0x3b,0xc6,0x62,0xba,0x45,0x49,0x76,0xd6,0xb9,0xde,0x9c,0x77,0x78, + 0x86,0xdb,0xaf,0x8b,0xb5,0x5b,0x17,0xf2,0x4d,0x50,0x0e,0x31,0x7f,0xbe,0x8f,0xe9, + 0xcf,0x1c,0xaf,0xec,0xdb,0xb1,0x9f,0xc9,0x8f,0x5c,0x00,0x5d,0xfb,0x98,0xf6,0xb8, + 0xc5,0x4d,0xb4,0xce,0xc9,0xd2,0xda,0x98,0xa4,0xff,0x2d,0xee,0x97,0x36,0x7c,0x24, + 0x94,0x39,0xaf,0xb8,0xe9,0xb5,0x2e,0x09,0x4d,0x70,0xa5,0xfe,0x7b,0x4d,0x19,0xf6, + 0x47,0x54,0xbe,0x7c,0x1b,0x48,0x09,0x4a,0x0f,0x78,0x0a,0x03,0xfe,0x41,0x78,0x39, + 0x4f,0x34,0xeb,0xfb,0x30,0xfe,0x2b,0xca,0x93,0x70,0x53,0x8c,0xdd,0x59,0x9b,0x73, + 0x79,0x89,0xbe,0xb5,0xda,0x03,0x80,0x5f,0x9a,0xcb,0x42,0x1b,0x3e,0xff,0x12,0x12, + 0x93,0x40,0xee,0xb4,0xfa,0xa2,0x38,0xba,0x65,0x4c,0x23,0x76,0xf0,0x9c,0x21,0xeb, + 0x69,0xf3,0xff,0xb4,0x79,0xa1,0x31,0xcb,0x35,0xcb,0xee,0xa1,0x84,0x1c,0xba,0xb0, + 0x7d,0x40,0xb7,0xb0,0xf1,0x3f,0xe0,0x16,0x60,0x3c,0xb1,0x57,0x25,0xe0,0xc8,0x2c, + 0x61,0x24,0x16,0xd3,0x30,0x29,0xa7,0x82,0xc0,0x0c,0xc8,0x71,0xd0,0x4c,0x70,0x00, + 0x07,0x0a,0xe2,0xd1,0x50,0xc5,0x20,0x12,0x02,0x65,0xa0,0x07,0x63,0xe2,0x39,0xc3, + 0x83,0x64,0x41,0x54,0xe2,0xdb,0x9d,0x03,0x83,0x06,0xae,0x07,0x93,0x26,0x71,0x01, + 0xc3,0x08,0x99,0x37,0x97,0x87,0x21,0xf3,0xc6,0x7e,0x26,0x70,0xac,0x98,0x59,0x08, + 0x0e,0xd8,0x7d,0x7e,0x72,0x6b,0xbe,0x0c,0x99,0xb5,0x25,0x9d,0x5e,0x4b,0xda,0x3c, + 0xa8,0x96,0x1d,0x62,0xd3,0xf8,0x43,0xf8,0xec,0xe6,0xf2,0x5e,0xae,0x2b,0x92,0x17, + 0xa2,0xfe,0x78,0x4a,0x65,0x8c,0x38,0x52,0xe9,0x9a,0x82,0xef,0x79,0x95,0xbf,0x7b, + 0x06,0x8d,0x83,0x99,0x70,0x88,0xc9,0x31,0x6c,0xe4,0x1c,0x49,0xfd,0x6d,0x22,0x08, + 0x0c,0x01,0xd5,0x9f,0x76,0x51,0x08,0x69,0xe9,0x4a,0x42,0x1f,0x62,0xcd,0x72,0x08, + 0x2b,0x02,0x80,0xa2,0xb8,0x2b,0x56,0xef,0x0b,0x42,0xc0,0xf8,0x26,0xeb,0x49,0x48, + 0x29,0x6b,0xa3,0x0c,0x21,0x23,0xdb,0x11,0x69,0x48,0xc2,0x92,0xfe,0x95,0x73,0x09, + 0x8a,0x00,0xc7,0xa6,0x3a,0xa5,0x3b,0x3d,0xf7,0xcd,0xbb,0x39,0x95,0x62,0x94,0xc7, + 0xc9,0x81,0x87,0xf7,0x5a,0xb1,0x29,0x70,0x3c,0xfb,0xf4,0xe5,0x89,0x7d,0x99,0x03, + 0x59,0xce,0xde,0x24,0xce,0x9e,0x64,0x10,0x8a,0x72,0x96,0xb0,0xd2,0x77,0x63,0xbd, + 0x5f,0xbf,0x7a,0x76,0x9e,0x9f,0x6d,0x81,0x00,0xf6,0xdf,0x5b,0x53,0x7f,0x9d,0xf3, + 0x4a,0x62,0x5d,0xd2,0x58,0x50,0x7d,0xb3,0xb8,0x5e,0x91,0x56,0x50,0xf9,0xb4,0xa2, + 0x61,0xe4,0xfa,0xfc,0xbf,0xb2,0x34,0xa1,0x95,0x59,0xea,0x99,0xd1,0x11,0x44,0x72, + 0xd2,0x1a,0xdd,0xd5,0xb3,0x55,0x50,0x0b,0xc2,0xdd,0xb9,0x09,0xf0,0xd8,0x4f,0xe1, + 0x01,0x10,0xc4,0x85,0xfa,0x9d,0x1f,0x1a,0x41,0x50,0xeb,0x05,0x51,0xad,0xf9,0xaa, + 0x00,0x11,0x93,0xfd,0x4c,0x9a,0xdd,0x13,0x88,0xb6,0x4e,0xc5,0xfb,0xc8,0xb2,0xea, + 0xc3,0x89,0xe0,0xb1,0xd1,0x7b,0xd2,0x2d,0x66,0xd2,0x6d,0x4e,0xd9,0xf2,0x76,0x9c, + 0xc9,0x98,0xa8,0xa0,0x1f,0x9d,0x25,0x89,0xc8,0xd8,0xe0,0xde,0x3a,0xa6,0x97,0xfa, + 0xc4,0xb1,0xe1,0xb1,0xbb,0xfa,0x13,0xd0,0xc9,0x78,0xe8,0x4f,0x7a,0x52,0xe5,0xbd, + 0x16,0xa6,0x18,0x38,0x34,0x96,0xd6,0x4a,0x6d,0xd6,0xe7,0xdf,0xba,0xc4,0x4e,0x5d, + 0xd7,0x13,0x53,0x8b,0xf8,0x2c,0xd7,0x6c,0x04,0xba,0xec,0x5d,0x02,0xe3,0x36,0x5a, + 0x2e,0x39,0xac,0xd4,0x3a,0x9d,0xcf,0x87,0xaa,0x3f,0x84,0xfd,0xa5,0xc2,0x27,0x8d, + 0xf5,0x93,0xcf,0x4d,0x53,0x8f,0x47,0x8b,0xee,0xfe,0x17,0x98,0xfb,0x12,0x77,0x89, + 0xa3,0x10,0x91,0xf4,0xb7,0x3b,0x15,0xec,0xcb,0x52,0xe5,0x63,0x08,0xd2,0x21,0x78, + 0x65,0x84,0xb2,0x4c,0xeb,0x2d,0xe6,0xa0,0xc4,0xba,0x38,0x31,0xb5,0xef,0x42,0x23, + 0x35,0x2e,0x96,0xb3,0xcb,0x0c,0x80,0xc1,0x23,0xd1,0xf2,0xcd,0xf6,0xe7,0x43,0x01, + 0xa0,0x09,0xf7,0xb7,0x63,0xcc,0x11,0x3b,0xf7,0x5a,0xd1,0x66,0x21,0xef,0x89,0x61, + 0xe7,0x75,0x79,0x89,0x94,0x63,0x81,0xc0,0xab,0xc5,0xb5,0xd1,0x74,0x69,0x00,0x02, + 0x00,0x89,0x1b,0xa4,0xff,0xf5,0x08,0x46,0xa7,0x6b,0x0f,0x34,0x15,0x14,0x62,0x42, + 0xa4,0x83,0x6d,0x25,0x67,0x23,0x6b,0x81,0x3f,0xc3,0x86,0x4f,0x47,0xa8,0x6b,0x47, + 0x25,0x8b,0x4d,0xd5,0x86,0xae,0xe0,0x90,0xfa,0x69,0x61,0x8f,0x17,0xab,0xe1,0x63, + 0xe4,0xa7,0xe8,0x17,0xdf,0x0c,0xf1,0x36,0x66,0x4d,0x87,0x4b,0x9f,0xec,0x5c,0x0d, + 0xad,0xc9,0xf8,0xdf,0x6c,0xb7,0x12,0xf2,0xed,0xf7,0xcd,0xcc,0xde,0xc0,0xd5,0x69, + 0x67,0xea,0x7e,0x8d,0x77,0x04,0x42,0x1a,0xad,0x6d,0xc2,0xbc,0x54,0x36,0x1d,0xbf, + 0xe4,0x87,0x99,0xe9,0x11,0x07,0x19,0xfb,0x90,0x61,0x49,0x4d,0x9f,0x55,0xd0,0x64, + 0xed,0x9a,0x7b,0x8c,0xff,0xa3,0x43,0x07,0x26,0x3a,0x83,0xef,0x26,0xe4,0x1a,0xc8, + 0x0f,0xe1,0xf3,0x4a,0x9e,0xde,0x89,0x88,0xcc,0xe4,0xcc,0x8e,0x7d,0xac,0x50,0xb8, + 0x8d,0x85,0xeb,0x1e,0x57,0x20,0x02,0xf8,0x46,0xf2,0xec,0x1c,0xa0,0x40,0x1b,0xc9, + 0x8f,0xeb,0xdd,0x63,0x13,0x28,0x8a,0x09,0x8d,0x71,0xf5,0x12,0x37,0x3f,0x9f,0xb9, + 0x0d,0x87,0x95,0x77,0x1f,0x5f,0x43,0x2b,0xcb,0xc0,0xec,0xfb,0xa9,0x4e,0xc1,0x72, + 0xa4,0x8f,0x70,0x15,0x48,0x1f,0x66,0x05,0x62,0xf3,0xcc,0x24,0x7d,0x4f,0xbc,0x63, + 0x86,0xd1,0x3f,0x65,0x13,0xdd,0xbb,0xc8,0x0d,0xdc,0x84,0x66,0x8e,0xfe,0x1e,0xf3, + 0x24,0x84,0x71,0xf4,0x92,0x14,0xf6,0x4b,0xdb,0xd6,0x8d,0x77,0x03,0xfd,0x1f,0xa3, + 0x22,0xd2,0x93,0x26,0x7f,0x42,0x2f,0x0b,0x0e,0x97,0xdd,0xf6,0x71,0xfe,0x04,0x86, + 0xa6,0x99,0x61,0xb4,0xdd,0x85,0xf4,0xf3,0x5a,0x7a,0x67,0xd7,0xd7,0x0b,0xe4,0x06, + 0x44,0xf5,0x13,0x27,0x0f,0x4a,0x01,0x90,0x24,0x6a,0xa6,0x30,0x0b,0x5a,0x6f,0xc1, + 0x05,0x90,0xc5,0xd3,0xdd,0xa7,0xe3,0x8c,0x64,0xfe,0xcb,0xde,0xd8,0x29,0x15,0x51, + 0xa2,0xcd,0xd3,0xff,0xd6,0xf7,0x05,0x91,0xa6,0xf7,0x5d,0x07,0x6d,0x24,0x78,0x33, + 0x2c,0x3c,0xd8,0x3f,0xd5,0x3b,0x0c,0x1a,0xc2,0x9a,0xbc,0xaa,0xdf,0xfe,0x95,0xd4, + 0x98,0xfa,0x1d,0x3a,0xc1,0xda,0x86,0x49,0x0f,0xc9,0xde,0xff,0xf9,0xf4,0xed,0x37, + 0x88,0xc6,0xc1,0xb3,0x57,0x39,0x63,0x37,0xdf,0xe1,0xbf,0x0a,0x1d,0xf5,0x49,0xf9, + 0x16,0x84,0x6f,0x3e,0x8d,0x6e,0x87,0x48,0x87,0xb7,0xf5,0x44,0x5e,0xfd,0x1e,0x48, + 0x2b,0x95,0xfe,0xde,0xd7,0xad,0x0e,0x68,0x67,0x63,0x88,0xe9,0x8f,0xf3,0x34,0x25, + 0x8c,0x9b,0x93,0xbc,0x7e,0xfd,0x46,0xaa,0x67,0xd2,0xde,0xae,0xde,0x75,0x3d,0x36, + 0x0d,0xfb,0xbf,0xda,0x3c,0x96,0x4f,0x3b,0x15,0xd1,0x43,0x94,0x5d,0xf8,0x3f,0xf4, + 0x0e,0x15,0x97,0xac,0x87,0x30,0x21,0xce,0xfb,0x9d,0xdf,0x1d,0xdb,0xff,0xa8,0x38, + 0x33,0x12,0x6c,0x84,0xec,0x00,0x12,0x46,0x3c,0x0f,0x37,0xbb,0xbb,0xd6,0xc8,0x76, + 0x20,0xeb,0x59,0x0b,0x2f,0x95,0x41,0x20,0xe4,0x2f,0x2a,0x2b,0xbd,0xce,0xb9,0xe1, + 0xa9,0x19,0x2d,0x47,0x13,0xf6,0x2b,0xc9,0xd2,0x0d,0xcf,0xbf,0xd4,0xb6,0x59,0x11, + 0xc2,0x02,0x29,0x0f,0x1d,0xae,0x7b,0x41,0xc0,0xd1,0xaf,0xc4,0x31,0x23,0xe7,0x6d, + 0xda,0x95,0x67,0x79,0xf3,0x8b,0x31,0x20,0x52,0xd0,0x43,0x63,0xf3,0xfb,0xdb,0xa3, + 0x7f,0xaa,0xae,0x85,0x12,0x65,0xbb,0x1b,0xe4,0x29,0x8c,0x0e,0x25,0xca,0x7b,0xb2, + 0xfa,0xa9,0x93,0x36,0xf0,0x4a,0x46,0x7a,0xb6,0x5d,0x65,0x07,0xae,0xc9,0x19,0xd5, + 0xda,0xce,0xd5,0xba,0x7a,0xed,0x66,0xe2,0xe1,0xea,0x89,0x9d,0xa4,0xaa,0x11,0xc9, + 0x8f,0x99,0xfc,0x9a,0xf3,0xce,0xaa,0x18,0x9a,0x07,0x3a,0xa6,0xcc,0xfc,0x0e,0xe4, + 0x81,0xf2,0xe8,0x02,0xcf,0xdd,0xe2,0xd0,0x49,0x04,0x1e,0xfa,0xcb,0x6a,0xc3,0x69, + 0x98,0x44,0xdd,0x9e,0x88,0x85,0x4a,0x27,0xab,0x6a,0x36,0x36,0xb3,0x1e,0x23,0xf5, + 0x6d,0x70,0x6c,0xee,0x43,0x80,0x19,0xdf,0xe9,0x9b,0x78,0xc6,0x11,0x9c,0x3c,0xec, + 0xff,0x8f,0xbd,0xb4,0x1a,0x57,0xc5,0x18,0xca,0x53,0x2d,0x97,0xd5,0xc1,0x62,0x65, + 0xe0,0x49,0x94,0xf1,0x1f,0xd8,0x12,0x70,0x9b,0xbc,0xa3,0x0d,0x79,0x7b,0xe5,0xba, + 0xa0,0x85,0x13,0xbc,0xac,0x2d,0x68,0x19,0x4a,0x58,0x87,0xf6,0xb9,0x6a,0x11,0x5a, + 0xfd,0xfa,0x5c,0x63,0xef,0x6d,0x7c,0xd9,0xf8,0xd9,0xd3,0x6d,0xe8,0xe5,0x1a,0xdc, + 0xb2,0x1a,0x66,0x97,0x0e,0xd6,0x44,0x39,0x6a,0xdd,0x14,0x55,0xa2,0x30,0xd3,0xa5, + 0x5a,0x20,0xee,0x90,0xcd,0x75,0x8c,0xd6,0x9a,0xaa,0xc2,0x87,0x75,0xda,0x91,0x21, + 0xca,0x60,0xbf,0x76,0x7a,0x99,0x4c,0xa1,0x47,0x49,0x36,0x93,0x2c,0x97,0xcd,0x3d, + 0xa1,0x08,0x3e,0x92,0x65,0xe5,0x19,0x35,0xc4,0xf2,0xaf,0xb1,0x74,0x65,0xab,0xd3, + 0x04,0x50,0xfa,0x64,0x53,0x30,0x2d,0x1b,0xb3,0x89,0x00,0x77,0x2f,0xd9,0x34,0xd4, + 0x96,0x57,0x9c,0x70,0xfb,0x16,0x5e,0x82,0xdc,0x51,0xe2,0x50,0x12,0x71,0x63,0x60, + 0x2e,0xbd,0xa4,0x85,0xf6,0x92,0x7e,0x9b,0xc0,0xbb,0x5e,0x95,0x72,0x69,0x0d,0xf3, + 0x02,0xc8,0x19,0x3d,0x98,0xfa,0x9d,0x36,0x1a,0xd1,0xbc,0xb5,0xef,0xd3,0xe7,0xee, + 0xd7,0x76,0x21,0x13,0x53,0x8e,0x2c,0x57,0xe8,0x79,0x37,0xb6,0xe4,0xcc,0x2e,0x72, + 0x40,0xf8,0x2d,0xaa,0xe5,0xdc,0xd9,0x3a,0xe9,0xf3,0xff,0x1c,0xaf,0xc6,0x39,0xa1, + 0x76,0x91,0x07,0x7c,0x6a,0x7a,0x4e,0x2d,0x4d,0x51,0xc9,0xa2,0xbe,0x34,0x6e,0xd9, + 0xe9,0x55,0xd1,0xae,0xbd,0x90,0x27,0x69,0xb5,0xf0,0xa1,0x00,0x91,0x8c,0xf2,0xaa, + 0xd5,0xb8,0x39,0x8b,0xd3,0x5f,0xa9,0x92,0x0b,0x58,0x06,0xb0,0xb2,0x1f,0xea,0x29, + 0x88,0x5d,0xd0,0x78,0xa9,0x37,0x83,0x07,0xeb,0x3d,0x8c,0x1a,0x92,0xfe,0x15,0xcf, + 0x62,0x7d,0x20,0x3d,0x3a,0x21,0x35,0xeb,0xeb,0xde,0x58,0x05,0x85,0xd3,0xf6,0x5d, + 0xa9,0x1a,0xd3,0xae,0xfc,0xbe,0xf2,0x82,0x76,0xf2,0x1f,0x58,0x59,0xd2,0x31,0x11, + 0x4b,0x88,0xc3,0x02,0xe8,0xe4,0xb7,0x50,0xbb,0x82,0x67,0x35,0xa2,0x33,0x00,0xea, + 0xc9,0xc3,0x0f,0x21,0x7e,0x04,0xd0,0xb7,0xc5,0x41,0xcb,0x8e,0x9d,0xb2,0x07,0xcb, + 0x8d,0x39,0x12,0x00,0x40,0x67,0xa9,0x52,0xc5,0xd2,0x97,0x9c,0xae,0x46,0xe6,0xeb, + 0xf2,0x46,0x29,0xe6,0x75,0xe3,0x03,0xdb,0x51,0x8c,0x5b,0x24,0xeb,0x05,0xc0,0xb1, + 0x28,0x70,0x2a,0x29,0x9b,0x09,0x4d,0x84,0x66,0xa7,0xd0,0xef,0xdb,0x69,0xd1,0x0d, + 0x01,0x7f,0xc8,0x96,0x33,0xc9,0x06,0x74,0xa6,0x46,0xf8,0x88,0xda,0x48,0x33,0x31, + 0x31,0x7a,0xb1,0x37,0x16,0x20,0x61,0x93,0x51,0xf7,0x16,0x98,0x37,0x60,0xbb,0x18, + 0x7a,0xbb,0xd3,0xc4,0xbd,0x08,0x8b,0x80,0x4b,0xca,0xad,0xe8,0x22,0x6e,0xfd,0x22, + 0x0a,0xdb,0x0a,0x84,0x88,0x3c,0x6b,0xd6,0xa9,0x37,0x88,0xdd,0x96,0x43,0xd5,0xdd, + 0xe4,0x71,0xee,0xd8,0x8f,0xaa,0x60,0x38,0xfe,0x60,0x09,0x39,0x89,0x3f,0xd8,0xe3, + 0xfb,0x47,0x06,0x14,0xf7,0xde,0xdf,0x58,0x91,0x3c,0xd1,0x2b,0x20,0xae,0xcc,0xeb, + 0x0d,0x94,0x48,0xe4,0x55,0xf8,0xb0,0xb1,0xce,0xab,0x1c,0xa0,0xb6,0x5d,0x5f,0x8d, + 0xcc,0xec,0xb6,0x3c,0xd4,0xaf,0x8d,0x96,0x4e,0x8e,0xd2,0x84,0xb7,0xef,0xaa,0x03, + 0x69,0x00,0xbe,0xcd,0x31,0x00,0x78,0x24,0xeb,0x20,0xfc,0x96,0x0a,0xa0,0x6b,0x46, + 0x6f,0xf1,0x9d,0xef,0x11,0x03,0x74,0x2c,0x33,0xd5,0xe9,0x6d,0x4c,0xe4,0x13,0x7c, + 0x2c,0xa7,0x3b,0x2f,0x1f,0xb0,0xbf,0x25,0xc1,0xd1,0xf9,0x99,0x50,0x42,0x63,0x80, + 0x6c,0xd2,0x96,0x82,0xb1,0xa6,0x4c,0xae,0x84,0x2f,0xca,0x1b,0x9d,0x23,0x75,0x16, + 0x80,0x9a,0xf2,0x99,0x7b,0xff,0xdb,0xc1,0xc6,0x58,0x82,0x0f,0x1f,0x46,0x7d,0xcf, + 0x24,0xc4,0x04,0x9d,0x28,0x06,0x6c,0xa3,0x41,0xbc,0xe3,0x19,0x1f,0x21,0xaf,0x7b, + 0xbb,0xde,0xcc,0x37,0x63,0x0c,0x1d,0x59,0x86,0xd7,0xc3,0x0e,0x1c,0x60,0x5c,0x38, + 0x8a,0x99,0x1b,0x39,0xd7,0x37,0x6f,0xce,0x60,0x6c,0x24,0x04,0xda,0x59,0x8f,0x89, + 0xda,0x29,0xd4,0x29,0xc2,0xd6,0xc5,0x82,0x33,0xdc,0xa2,0x14,0x73,0x70,0xc9,0x5c, + 0x59,0x0b,0x1a,0x39,0x4b,0x17,0xe6,0x8c,0x45,0x86,0x21,0x05,0x1f,0x3c,0x16,0x57, + 0xfe,0x54,0x16,0xa4,0xcb,0x46,0xfd,0xb2,0x8b,0xc2,0x4e,0x15,0x9f,0x06,0xd9,0x88, + 0x28,0x63,0x9c,0x7d,0xfa,0x17,0x57,0xea,0x24,0x23,0xe0,0x14,0x97,0x6b,0x89,0x78, + 0xcd,0x66,0xd0,0x0c,0xc1,0xfd,0x2e,0xa7,0x2d,0x54,0x89,0x07,0x8e,0xf7,0x36,0x63, + 0xbe,0xd7,0x41,0x7e,0x76,0xaa,0x33,0x2f,0xdd,0x73,0x00,0x12,0x08,0x29,0x76,0x9a, + 0x0a,0x80,0x1c,0x98,0x69,0x6d,0x66,0xbb,0x4a,0x9a,0xd7,0x39,0x01,0xba,0x5d,0x28, + 0x82,0x21,0x98,0xc8,0xd7,0x6d,0xe3,0xdc,0x16,0xcc,0x88,0xd3,0x8b,0x5f,0x50,0xe3, + 0x4e,0x99,0x15,0xf9,0x9e,0x42,0xcc,0xc7,0x7f,0x18,0xac,0x9f,0x37,0xbc,0x1f,0x0c, + 0x64,0x4f,0x34,0x3c,0x32,0xb3,0xc5,0xd7,0x5e,0x4f,0x64,0x1c,0x8a,0x5e,0x16,0xa1, + 0xce,0x9b,0xc9,0xe2,0x3b,0x1b,0x2f,0xdf,0x3b,0x0e,0x58,0xd2,0x7a,0x6e,0x59,0x9f, + 0xa5,0x0b,0xe3,0xc4,0x14,0xb4,0x06,0x18,0x46,0xf8,0xee,0x22,0xdd,0xdd,0xf7,0x98, + 0xa4,0xbe,0x9b,0x72,0xea,0x20,0x5e,0x0b,0x7d,0x03,0xe1,0x4c,0xc3,0x6b,0x52,0xe9, + 0x2c,0x4f,0x0f,0xc3,0x9a,0x39,0x36,0x43,0x3f,0x4b,0xf7,0x23,0xb3,0x66,0x96,0xf1, + 0xa7,0x05,0xb1,0x11,0x14,0x01,0x45,0x34,0xf2,0x35,0x5a,0xc5,0xed,0x52,0xcf,0xdf, + 0xfd,0xa9,0xf8,0x14,0x1a,0x2b,0x06,0x1d,0xa9,0xbd,0xe8,0xb4,0xed,0x6b,0x37,0x22, + 0xc1,0x05,0xc2,0x14,0xb0,0x23,0x60,0x20,0x63,0x4a,0xe0,0x24,0x57,0x6a,0xca,0xdf, + 0x75,0x47,0xa1,0xe5,0x2e,0x2b,0xc1,0xe3,0x42,0xce,0xe9,0x35,0xda,0x69,0x32,0x16, + 0x7e,0xb1,0x99,0x44,0x32,0xaf,0xc9,0x0e,0xcd,0x25,0x06,0x9b,0xd5,0x9e,0x22,0xcc, + 0xa9,0x82,0xdb,0x1b,0xfd,0x46,0xaa,0xd6,0xb5,0x26,0xeb,0x4a,0xa7,0xe3,0x38,0xe7, + 0xf0,0x4b,0xbe,0x22,0x39,0x0b,0x09,0x28,0xa2,0xf8,0xca,0xbd,0x11,0xe2,0x84,0xf8, + 0x2b,0x4a,0xe1,0x0c,0x9b,0x6a,0xf0,0xe9,0x84,0xe7,0x84,0xa9,0xdb,0x11,0x04,0x8a, + 0x28,0x94,0x0c,0x66,0x97,0x2d,0x3b,0x30,0x81,0xda,0xd3,0x10,0x59,0xab,0x79,0x38, + 0x8a,0x13,0xc3,0xae,0xb6,0xa7,0x18,0xd5,0xb5,0x20,0xb0,0xe8,0x71,0xba,0xda,0xa7, + 0xf0,0xa0,0x4f,0x3e,0x58,0x22,0xca,0xdd,0xbc,0xb0,0x8a,0x58,0xba,0x62,0xf8,0x39, + 0x0a,0x18,0x44,0xaf,0x18,0x2d,0x0a,0xd7,0x6f,0xb8,0x13,0x8c,0x42,0x68,0xc4,0xc2, + 0xe8,0x0b,0xb3,0xdf,0xb9,0x0d,0x49,0xab,0x34,0x92,0xbb,0x3d,0xca,0xef,0x17,0x68, + 0xfe,0x5d,0xe1,0x44,0x91,0xb8,0x1c,0xb0,0x81,0x42,0xce,0x89,0x4c,0x6f,0x8e,0xb0, + 0x51,0x71,0x31,0xd3,0xfb,0xd9,0x1a,0x58,0x99,0xfc,0x09,0x5e,0xd4,0x1d,0x5d,0x84, + 0x82,0x83,0x8d,0x67,0x8f,0x12,0xed,0x85,0x1d,0x59,0x2d,0x5a,0x93,0xe3,0xcd,0xe8, + 0x35,0xbe,0x85,0x91,0x19,0x8d,0x0a,0x57,0xd2,0xe6,0x7a,0x4b,0x55,0x9e,0x1d,0x6a, + 0xcb,0xcc,0xfc,0x14,0xff,0xbc,0xad,0x93,0x58,0x36,0x78,0x7a,0x71,0x64,0xb4,0xf4, + 0x54,0x23,0xb5,0x36,0xb1,0xd6,0x98,0x92,0x20,0xea,0xcc,0x74,0x86,0x7a,0xbd,0xc9, + 0x4b,0xee,0xc4,0x27,0x13,0xbc,0xa8,0xc5,0x60,0x5e,0x8f,0x82,0x8e,0x34,0x92,0x13, + 0x90,0xbb,0x19,0xb7,0xf0,0xc9,0x25,0x93,0xa0,0x28,0x62,0xc4,0x52,0xd6,0x93,0x3a, + 0xd7,0x08,0x3b,0xbd,0x99,0x07,0xae,0xd9,0x10,0x51,0x52,0x53,0x1b,0x72,0xbb,0x7e, + 0xa9,0x61,0x4d,0x6c,0x0d,0x08,0x1f,0x48,0x2d,0x16,0x21,0x5e,0x65,0x7d,0x3d,0x7a, + 0xd0,0x01,0x2b,0x1e,0xff,0x30,0x16,0xdb,0xfa,0x15,0x02,0x29,0xfb,0x0b,0x31,0xb4, + 0x4b,0xc4,0xf6,0xfb,0x46,0xb0,0x8f,0x51,0x19,0x16,0xf4,0x99,0x74,0xf6,0xfe,0xf8, + 0x2e,0xa3,0xbe,0x4e,0x3f,0x35,0x2e,0x6a,0x48,0x29,0xee,0x13,0x83,0xdd,0x35,0xfc, + 0xc2,0xd7,0xae,0x98,0x6c,0xbd,0x66,0x28,0xd4,0x52,0x05,0xec,0x18,0x69,0x06,0xaf, + 0xc8,0x1e,0xfd,0x2f,0x16,0x31,0x6f,0xb9,0xaa,0x51,0xef,0xdc,0x5b,0xc1,0x11,0x3b, + 0xaf,0x9a,0xb7,0xfa,0x1a,0xb7,0x3f,0x59,0xe9,0xd4,0xc8,0x79,0xdb,0xe5,0x94,0x60, + 0x89,0x76,0xc5,0xc6,0xb7,0xbb,0x0e,0x1a,0xc9,0x46,0xe9,0x2d,0xb1,0x91,0xd3,0x96, + 0x26,0x92,0x97,0xf4,0x95,0xc3,0x2f,0x52,0x0d,0xaf,0x2d,0x48,0xf6,0x91,0xde,0x79, + 0x4e,0x8d,0xb6,0x83,0x97,0xe3,0x33,0x63,0x0b,0x6f,0xa3,0xe7,0xd2,0xe8,0x70,0x34, + 0x20,0xc1,0xf0,0x2f,0x93,0xa9,0x5b,0x23,0xc4,0xf3,0x99,0xb9,0xe6,0x72,0x19,0x33, + 0x53,0x92,0xba,0xdf,0xb5,0xa2,0x22,0xfd,0xb1,0x85,0x88,0x14,0xa9,0xa6,0x00,0x6f, + 0xec,0xc1,0x13,0xb4,0xb6,0x2f,0x79,0x94,0x63,0xb9,0x78,0x97,0x5a,0xe3,0xf1,0xe6, + 0x71,0x0d,0x69,0x82,0x37,0x2c,0x4b,0x8b,0x78,0x89,0xad,0xd2,0x37,0x19,0x33,0xd8, + 0xf1,0x28,0x96,0xb5,0x15,0xef,0xc6,0x3c,0x52,0x1a,0x0f,0xb1,0x76,0x65,0x2d,0x4f, + 0xad,0x17,0x32,0x75,0xbf,0xb3,0x08,0xc2,0xbc,0x87,0x0a,0x69,0x52,0xee,0x11,0x84, + 0x0e,0x29,0xca,0x95,0x1e,0xa6,0xaa,0xd2,0xb5,0x84,0xbe,0x51,0xd0,0xf2,0x97,0x69, + 0x01,0x7c,0xb4,0x69,0x11,0xc8,0x32,0x58,0xb4,0x85,0xd6,0xef,0x7f,0x91,0xeb,0x62, + 0x19,0xc5,0xa1,0x1d,0x3e,0xad,0xc4,0xfc,0x0f,0x4b,0x9e,0xa9,0xde,0x59,0xc6,0x6e, + 0xe7,0x3d,0x28,0x3c,0xbd,0xaa,0xdb,0x4e,0xc3,0x61,0x8a,0x9e,0xf3,0x5d,0x14,0x5c, + 0xee,0x0e,0x62,0xab,0x7c,0xdc,0xe5,0xe8,0x4f,0x8c,0x01,0x8e,0xf2,0x1c,0x75,0x29, + 0xee,0x88,0x6b,0x83,0x3d,0xa8,0x2b,0xf9,0x86,0x63,0x33,0x4f,0xdc,0xe3,0x0e,0xa8, + 0x03,0xce,0x93,0xdd,0xbe,0x5e,0x45,0xd3,0x42,0xad,0x3b,0x5f,0xdd,0xe2,0xe2,0x73, + 0x5c,0x30,0xb7,0x02,0x37,0xcb,0x24,0xd5,0x68,0x9d,0x53,0x59,0x95,0x76,0xff,0x16, + 0x7c,0x24,0xe4,0xbb,0xb5,0x71,0x84,0x4d,0xea,0x57,0x10,0xd0,0xab,0x2c,0x7c,0x1c, + 0x01,0x99,0xb5,0x06,0xfc,0x39,0x37,0x45,0xd7,0x47,0xb5,0x59,0xc7,0x79,0x95,0xd4, + 0x67,0x11,0xf4,0x9c,0x50,0xc2,0xbd,0xf3,0xa5,0x2e,0xa7,0xb5,0x1e,0xfc,0xd7,0x20, + 0x02,0xda,0x64,0x24,0xb4,0xfc,0xf3,0x00,0xe4,0xd7,0xcc,0x1c,0x70,0xf5,0x35,0xdd, + 0xc0,0xd4,0x8c,0x92,0x0c,0xba,0x76,0xe7,0xc4,0xd3,0xf4,0xe6,0x48,0xd5,0x71,0x05, + 0xca,0x1b,0x3c,0x37,0xbe,0xb9,0xc4,0x81,0xa5,0xd9,0xb8,0x85,0x79,0x60,0xd6,0x35, + 0xb7,0x6a,0x8d,0x93,0xc8,0x3a,0x2d,0x62,0x84,0xf7,0xdd,0xf3,0xc8,0xf7,0x2e,0x3b, + 0xa9,0x1b,0xb4,0x4e,0x3a,0xb2,0x3c,0xa8,0xcb,0x99,0xf7,0xc8,0x1d,0xfc,0x70,0xa3, + 0x69,0x14,0xbc,0x9f,0xc6,0x34,0x40,0xef,0x5e,0x0b,0x62,0xd8,0x8a,0xe9,0x1d,0x6d, + 0x2c,0x6b,0x32,0xf1,0x1f,0x87,0x6e,0xa0,0x09,0x65,0xd1,0x4d,0xd8,0xe1,0x51,0xa3, + 0xce,0xc9,0x7b,0x65,0x54,0x71,0x87,0x41,0x14,0xb7,0x07,0x40,0x70,0x56,0x9e,0x22, + 0x88,0x41,0x9e,0x4c,0x3b,0x67,0x0e,0x68,0x4c,0xbe,0x4d,0x3e,0x76,0x85,0xfe,0xa8, + 0x47,0x96,0xce,0xbc,0x7c,0x43,0x2e,0xe2,0x0c,0xbd,0xb3,0x84,0xdc,0x0d,0x9f,0xc3, + 0x53,0xd1,0xe5,0x2d,0x3c,0xf6,0x2d,0xfe,0x4d,0xd8,0xef,0xfe,0xf8,0xff,0x11,0x3b, + 0xcc,0xbf,0x97,0x5d,0xd1,0xdc,0x07,0x79,0xea,0x25,0xf8,0x21,0x60,0xbe,0x3a,0xe8, + 0x52,0x4f,0xf3,0x42,0x16,0x1b,0xc9,0x96,0x7b,0xf2,0xe8,0xa6,0x51,0xe7,0xfe,0x7c, + 0xa0,0x6d,0x29,0x82,0x12,0x61,0x1f,0x89,0xa0,0xee,0x34,0xab,0xae,0xfc,0x51,0x18, + 0xd0,0x04,0xa0,0x72,0x1d,0x39,0xd1,0xa1,0x30,0x41,0xa9,0xdf,0x7c,0x6f,0x6b,0x80, + 0x80,0x63,0x9d,0xb7,0xb3,0x13,0x8e,0xd9,0x83,0x0e,0x7a,0xcb,0x2c,0x78,0x11,0x33, + 0x2c,0x85,0xb8,0x02,0x72,0x66,0xfc,0x13,0x28,0xe2,0xae,0xc5,0xb9,0x27,0x98,0xaa, + 0x68,0x0d,0xd8,0x61,0x1c,0x26,0x8a,0xb0,0x07,0xce,0x82,0x26,0x6b,0x27,0xc1,0xba, + 0x63,0xa5,0x12,0xe3,0x93,0x6c,0x87,0x12,0xa0,0xe0,0xaf,0xc0,0x33,0x59,0x49,0x42, + 0xf7,0x2f,0x5b,0x71,0xa0,0xf3,0xa6,0x82,0xa1,0xe8,0xc9,0x3c,0x72,0x6e,0x58,0x09, + 0xaf,0x0b,0xc6,0x88,0x18,0xea,0xed,0x5b,0x34,0x24,0x12,0x72,0xd5,0x0a,0x18,0xe3, + 0xf6,0x65,0xda,0x15,0xba,0x32,0x52,0x9d,0xb6,0x25,0x65,0xbe,0x58,0xee,0x45,0xd5, + 0x61,0xa3,0xda,0x9c,0x3d,0x2c,0xf4,0xe9,0xd5,0x08,0x38,0xa8,0x4b,0x55,0xcf,0x28, + 0x28,0xaa,0x49,0x7b,0x1b,0x28,0x79,0xa8,0xca,0x8b,0x20,0xdf,0x75,0x96,0xf7,0xe9, + 0xbe,0x0f,0x78,0xbd,0xb9,0x4c,0x04,0x56,0x28,0xb9,0x85,0xe8,0x7a,0xdb,0x8a,0x85, + 0x78,0xa0,0x26,0x33,0xc5,0xa6,0xf2,0x5d,0xce,0x7c,0x22,0x55,0x5d,0x6c,0xf4,0xec, + 0x7e,0x4d,0xf1,0x0a,0x94,0xd1,0x05,0x4d,0x4f,0x6f,0xeb,0x8d,0xb4,0xe5,0xd8,0xdd, + 0xfd,0x95,0xeb,0xb7,0xae,0x39,0xb3,0x49,0x49,0x4b,0x9b,0x1f,0xf8,0xbe,0x97,0x50, + 0x28,0xef,0x48,0xe6,0x71,0x10,0xb0,0xdf,0xc3,0xf0,0xaa,0x70,0x32,0xdf,0x47,0xa1, + 0x5d,0x53,0xb4,0xc4,0x33,0x3e,0x62,0x8d,0x52,0xd3,0xe2,0x89,0x98,0xbb,0xba,0x91, + 0x1f,0x99,0xfd,0x07,0xb9,0x56,0x82,0xa3,0x25,0xdf,0x06,0xd6,0xbb,0xf0,0x45,0x74, + 0x1c,0x1c,0xed,0xd5,0xbf,0x3e,0xa5,0x4e,0x08,0xa2,0xc3,0x57,0xf5,0xf6,0x3c,0x68, + 0xc9,0x27,0x83,0x40,0x44,0x80,0xd0,0x64,0x37,0x5e,0x6b,0x77,0x5c,0xa9,0x8c,0x6c, + 0xd1,0xee,0x77,0x14,0x3d,0x59,0x58,0x83,0x1e,0xd3,0x7f,0x50,0xaf,0x16,0x1e,0xfa, + 0xd9,0xce,0x9f,0xc7,0xb4,0x85,0xb9,0x92,0xc1,0xd0,0xb3,0x41,0xf1,0xb6,0x27,0x2d, + 0x7d,0x55,0xf3,0xa8,0x71,0x17,0x5d,0x31,0xe7,0x7e,0xf8,0xc8,0xeb,0x40,0x38,0xb5, + 0x40,0xb1,0x8c,0x88,0x9b,0x35,0xba,0x37,0x6b,0x88,0x03,0x57,0x91,0x77,0xd2,0xf7, + 0x8a,0xec,0x84,0xbc,0x9a,0x34,0x56,0x7d,0x82,0x3d,0xb8,0x68,0xda,0xfc,0x15,0x51, + 0xae,0x10,0x8d,0x9d,0x1b,0x37,0xd7,0x69,0xc6,0x18,0x46,0x57,0x11,0x8b,0x9c,0xa7, + 0xd1,0xae,0x85,0xdd,0x1a,0x3d,0xa0,0x5b,0xa1,0xaa,0xb9,0x5f,0xf8,0xd4,0x13,0xc8, + 0xfe,0x9f,0xce,0xd4,0x3c,0xef,0x9d,0x2e,0x42,0x47,0x51,0x5a,0x93,0x5f,0x9c,0xcb, + 0x41,0xfe,0xee,0xcc,0x08,0x49,0x07,0xbb,0xce,0x02,0x8e,0x0e,0x5a,0xb4,0xe0,0x78, + 0x62,0x9d,0x5b,0x49,0xcc,0x9a,0xf4,0x9f,0x15,0xe1,0xad,0x0d,0xf6,0xd3,0x8f,0x65, + 0x59,0xbe,0x15,0xdc,0x36,0x92,0x5e,0x9f,0x54,0xe9,0x33,0x8e,0xd1,0xf9,0x18,0x32, + 0x9e,0x2f,0x27,0xe4,0x93,0xa0,0x8f,0xa6,0x47,0xaa,0xc8,0xa4,0x55,0x07,0x56,0x15, + 0x03,0x83,0xec,0xf0,0x97,0xe9,0xec,0xcd,0xc8,0x47,0xc7,0xc9,0x53,0xa8,0x81,0x71, + 0xe6,0xd3,0x09,0x03,0x75,0xb9,0x11,0xaa,0xc2,0xc8,0xeb,0x26,0x77,0x6f,0xa7,0x0c, + 0xf1,0x57,0x63,0xe7,0x99,0xac,0xac,0xf3,0x87,0x3e,0xaf,0x71,0x93,0xa2,0x76,0xe3, + 0xed,0xa7,0xe8,0x42,0x96,0x67,0x7a,0x00,0x05,0x33,0xdf,0x0d,0x8f,0x11,0x38,0xd6, + 0x71,0xdf,0x8a,0x52,0x14,0xe6,0x64,0x0a,0x41,0x9f,0x54,0x09,0x9d,0xc6,0xda,0xf2, + 0xa4,0x29,0xb8,0x48,0x73,0xca,0x09,0x43,0x92,0x86,0xe2,0xe3,0x9d,0xd5,0x7f,0xf6, + 0x6c,0xe4,0x33,0x53,0x17,0x76,0x99,0xf7,0x8e,0xe7,0x42,0xe4,0xf5,0xed,0x35,0x11, + 0x7c,0x1c,0xc2,0x4a,0x0b,0xa7,0x28,0x2f,0xb3,0x1d,0x8c,0x5e,0x7f,0x88,0x14,0x27, + 0x80,0x2f,0x75,0xfc,0xb1,0x22,0xee,0x06,0xa6,0x8d,0x27,0x0d,0xd8,0xa9,0xb6,0x79, + 0x67,0x7b,0xc3,0x4b,0xbd,0x21,0x67,0x3a,0xe6,0x41,0x73,0x47,0x11,0xa8,0x35,0xdb, + 0xe7,0x26,0x54,0xfd,0x1f,0xe3,0x01,0x8b,0x2b,0x64,0x2b,0xbb,0xab,0x9e,0xd9,0xfb, + 0x28,0x23,0xbb,0x50,0xfb,0x53,0x2b,0x71,0xab,0xa0,0x70,0x70,0x7c,0x18,0x40,0x29, + 0x7b,0x29,0x57,0xc5,0x7c,0xa9,0x2a,0x4b,0x57,0xcc,0xc7,0x25,0xa3,0x5c,0xb3,0xda, + 0xf6,0x8a,0x4f,0xca,0x65,0xc2,0x11,0x6e,0xcd,0x5e,0xa7,0x64,0xaa,0x52,0xfc,0xb9, + 0x6f,0x2b,0x92,0x33,0x0d,0xa5,0xed,0x6f,0xef,0x0f,0x3b,0xae,0xe5,0x83,0x37,0xb8, + 0x18,0x8b,0x2c,0x85,0x95,0x38,0x14,0xc8,0x40,0xd1,0xb8,0xf9,0xc9,0x0c,0x8b,0xae, + 0xf1,0x20,0x8c,0xf4,0x74,0xb5,0x65,0x87,0xc0,0xd8,0xd6,0x5a,0xab,0xb3,0x21,0x07, + 0xa6,0xa2,0xa1,0x65,0x36,0xfa,0xb5,0xa7,0xcc,0x45,0x1e,0xc9,0x21,0x89,0x0a,0xab, + 0x75,0xe2,0xd5,0x7f,0xb3,0xfe,0xbd,0x92,0x17,0xd0,0x72,0x4f,0x9e,0xf0,0x5c,0x3d, + 0x93,0xd6,0x7b,0x54,0x3e,0xbc,0x2e,0xe0,0xd5,0x89,0xe4,0x95,0x54,0x72,0x33,0x8e, + 0xaa,0x38,0xf4,0xd2,0xb0,0xd4,0xbd,0x8d,0xea,0xb7,0x28,0x64,0x57,0x58,0xb6,0x48, + 0xd5,0x23,0xe3,0x2f,0x2a,0x7b,0x6f,0xe1,0x74,0xdc,0xf1,0x27,0xe9,0x5b,0x38,0x5c, + 0x18,0x3a,0x7d,0xc8,0x8b,0xf5,0x82,0x34,0x5a,0x21,0x2d,0x65,0xff,0xfd,0x20,0xb7, + 0xac,0x14,0xbc,0x8f,0x1f,0x8b,0xf6,0x2b,0xee,0x24,0x51,0x5f,0x56,0x76,0x7a,0x64, + 0x52,0x08,0x55,0xb9,0x9c,0x46,0xba,0x7d,0xed,0xf9,0x6a,0x6c,0xb5,0x08,0x1d,0x78, + 0x8e,0x35,0xc7,0xcf,0x3d,0xb7,0x4f,0xc9,0x0e,0xba,0xe9,0x0b,0x22,0x51,0x70,0x64, + 0x92,0xbb,0xcf,0xdf,0x53,0x36,0x93,0xfb,0xe9,0xfa,0xa8,0xcc,0x85,0xf2,0x37,0x44, + 0x99,0xde,0x2d,0xe5,0xbc,0x4a,0xcf,0x9a,0xee,0xca,0xba,0x1f,0xdd,0xbc,0x38,0x29, + 0x45,0x40,0x5a,0xbc,0xd4,0x0c,0x5e,0xef,0xed,0xd9,0xfa,0x7a,0x5f,0x5c,0x32,0xcb, + 0x53,0x3f,0x8d,0xad,0x55,0x2f,0x7f,0xfb,0x69,0xef,0xc9,0xd6,0x7c,0xfb,0x39,0x6b, + 0x44,0x1c,0xb5,0x20,0x54,0xbc,0x75,0x99,0xae,0xd7,0xe9,0x5e,0x00,0x52,0x50,0xbc, + 0xf7,0xab,0x10,0x76,0xfb,0x91,0xe8,0x23,0xf3,0x02,0xae,0x84,0xf7,0xcd,0xc8,0x30, + 0x7b,0x0c,0x70,0x1c,0xb6,0xfa,0x70,0xc3,0xcd,0x4c,0x0b,0x46,0x3b,0xd0,0x79,0x05, + 0x69,0x93,0xff,0x39,0xa3,0x0e,0x9b,0x3e,0xc6,0x8a,0x82,0x14,0xa4,0xcd,0x72,0x36, + 0x20,0xa2,0xec,0xe8,0x13,0x58,0x67,0x19,0x6d,0x4e,0xe7,0x0c,0x99,0x12,0x1a,0xf2, + 0x7a,0xab,0xf8,0xbe,0xbe,0x29,0x22,0x44,0xfb,0xef,0x6f,0x34,0x73,0x2b,0x36,0x57, + 0xa2,0x5a,0x73,0xb6,0xbf,0xd8,0x4f,0x83,0xc7,0xc8,0xb8,0xc2,0xc4,0x27,0xe1,0x33, + 0xe0,0x61,0xbe,0x61,0x79,0x42,0x29,0x75,0x22,0xc7,0xb1,0x67,0x44,0x6b,0x72,0x61, + 0x8f,0xf8,0xb1,0x71,0x78,0x43,0x0b,0xc2,0xe7,0x7a,0xd6,0xbc,0x51,0x63,0xd6,0xf3, + 0xe1,0x4b,0x8a,0xe2,0xe3,0x6a,0x6c,0x01,0x90,0x0c,0xb2,0x1f,0x2f,0x5e,0xed,0x62, + 0xdf,0x01,0xd5,0xde,0x2a,0xa5,0xae,0x5a,0xaa,0x42,0xc1,0x3c,0x5f,0x80,0x50,0xf3, + 0x07,0xb7,0x9e,0xc1,0xeb,0x1c,0x30,0x2e,0x69,0x15,0x4c,0xaf,0x20,0xc0,0x0c,0x0a, + 0xf1,0x18,0x33,0xee,0x98,0x3b,0x9b,0x57,0x2a,0x40,0x93,0x22,0xbb,0xbf,0x7f,0x8f, + 0xd4,0x04,0x6e,0x3f,0x9e,0x9a,0x44,0x0a,0x2a,0xdf,0x37,0x0e,0xd8,0xab,0xb1,0x22, + 0x84,0xdb,0xb4,0x5b,0xba,0x82,0xae,0x8b,0xc7,0x40,0xe0,0x83,0xa6,0xf6,0x46,0x27, + 0xea,0x6e,0xfd,0x4a,0x48,0x6f,0x2d,0x6f,0x2b,0xcd,0xb8,0xe9,0x83,0x54,0x03,0x45, + 0x32,0x8e,0x5e,0x7a,0x3a,0x80,0xa0,0x5e,0x6a,0xb0,0xdb,0x90,0xd3,0xee,0x00,0x62, + 0x04,0x9d,0x92,0xe6,0xcf,0x9d,0x4e,0x71,0x58,0x4f,0x29,0x44,0x5c,0xdb,0x3b,0x96, + 0xd2,0x53,0xb2,0xac,0x8e,0x6a,0x09,0x5a,0x98,0x1e,0x8c,0x90,0x42,0x91,0x78,0x05, + 0xe5,0xb9,0x92,0x01,0xc6,0x04,0xad,0x5a,0x83,0x26,0xed,0xa1,0x0d,0x30,0x87,0x97, + 0x5d,0x57,0x8d,0x6c,0x41,0xa8,0x47,0x2d,0xd9,0x11,0x36,0xf2,0xff,0xaf,0xe8,0x45, + 0xb1,0x8b,0x14,0xb6,0x01,0x31,0xf0,0xc4,0x28,0xb5,0xc4,0x41,0x32,0xf9,0x5c,0xa6, + 0x67,0xe9,0xac,0xd6,0x66,0x38,0x02,0x12,0x67,0xf8,0x92,0x87,0x38,0xd1,0xba,0x61, + 0xd2,0xe6,0x3d,0x41,0x91,0xb4,0x72,0xe7,0x32,0x32,0x8c,0x6a,0x55,0xd4,0x47,0x91, + 0x7e,0x13,0x09,0x53,0xd9,0x36,0xcb,0xf5,0xe1,0x52,0x17,0x17,0x13,0xf6,0x78,0xa4, + 0xf4,0x69,0xb3,0x08,0x02,0x38,0x9c,0x76,0x89,0x57,0x52,0x66,0xc3,0x47,0xb6,0x78, + 0x19,0xad,0xdc,0xe2,0x9a,0x5c,0xa5,0x5a,0xc5,0xa4,0x8e,0xba,0xd8,0xe6,0x5d,0x58, + 0x90,0x05,0xb9,0xa0,0xbe,0xe9,0x2a,0x2d,0xad,0x6f,0xcd,0x45,0x80,0x38,0xaf,0x83, + 0x25,0x16,0x30,0x7f,0x50,0xaa,0x67,0xd2,0xef,0x93,0xc5,0x8e,0x81,0xd4,0xc7,0x97, + 0x6b,0x9c,0x90,0xc8,0x93,0x82,0x6b,0xd9,0xcb,0xdd,0xc7,0x1f,0xfe,0xf7,0x04,0x67, + 0xf6,0xc1,0x97,0x47,0x9c,0x58,0x0c,0x5f,0x4f,0xd6,0x7e,0x0f,0x46,0x89,0xe8,0xcb, + 0xea,0xe2,0xa7,0xcf,0x28,0x33,0x9e,0x1a,0x6e,0xd3,0xe2,0x5c,0x59,0x8b,0xf2,0x87, + 0x56,0x03,0xf7,0x35,0x2d,0x70,0x9c,0xd5,0x00,0x1b,0xc4,0xd9,0x06,0xa7,0x95,0x3e, + 0xfc,0xa3,0x18,0xf5,0x1d,0xdb,0x3d,0xd3,0x28,0xa0,0x64,0x3d,0x72,0x74,0x08,0x1f, + 0xcd,0x10,0xc2,0xea,0xcb,0xe3,0x40,0x15,0xb8,0xce,0xf1,0xb2,0x23,0x94,0x12,0xa3, + 0x78,0x13,0xcb,0xeb,0x4a,0x59,0xf1,0x77,0x41,0x1f,0xe5,0x19,0x9b,0x17,0x78,0x3c, + 0xf9,0x36,0x66,0xef,0x7c,0x69,0x1f,0x1e,0x41,0x67,0x83,0xdc,0x66,0x16,0xe4,0xbc, + 0xf7,0xea,0xf3,0x62,0xb7,0x3b,0xe0,0x71,0x3a,0x80,0x14,0x8d,0xa7,0x67,0x84,0xcd, + 0x06,0x05,0xd3,0xea,0xe0,0xe4,0xc1,0x43,0xe6,0x44,0x49,0x8d,0x14,0x05,0x82,0x03, + 0x9e,0xdb,0x55,0x25,0xea,0x59,0x57,0x5f,0x4a,0x87,0xd1,0x89,0xd0,0x56,0x81,0x6b, + 0x07,0xc7,0x32,0x57,0xe8,0x37,0x6e,0x80,0x43,0x4a,0xe1,0x63,0x2e,0x68,0xf6,0x30, + 0x2a,0x7d,0xb0,0xf0,0xf7,0x39,0xa3,0x2d,0x4a,0x00,0xe0,0x10,0x72,0xaa,0x70,0xfc, + 0x65,0xf8,0x3f,0x59,0xd7,0x03,0x8e,0x49,0x75,0xc6,0x01,0xd8,0x4d,0x14,0x34,0x8f, + 0xc3,0xc0,0x99,0xfc,0xa0,0x07,0x1a,0x58,0xfc,0xc5,0x34,0x5b,0xef,0x5d,0xeb,0x3b, + 0x8f,0x00,0xe3,0xcf,0x74,0x7a,0x05,0x0e,0xee,0x46,0x43,0x1b,0x01,0x5a,0xca,0x72, + 0x6d,0xe0,0xbd,0x4e,0x21,0x73,0x20,0xdd,0xa5,0xa8,0xea,0x6a,0xd9,0x8f,0x52,0xa5, + 0x9e,0xf0,0x2a,0xde,0xef,0xe1,0x68,0x37,0xa4,0x89,0xf5,0x65,0xa6,0xe2,0x74,0xcf, + 0xae,0x65,0x3a,0xf1,0xa5,0x2b,0xe3,0x05,0xa6,0xc3,0xa9,0xe3,0xa2,0xac,0x42,0x53, + 0x0f,0xcf,0xb9,0x19,0xb1,0xe3,0x41,0xcb,0x21,0x60,0x7c,0xc0,0x9f,0xb1,0xdf,0xa5, + 0x85,0x1f,0xdb,0x7e,0x34,0xcb,0xc6,0xd1,0x54,0xdf,0x14,0xd4,0x16,0x97,0x74,0x96, + 0xad,0x8e,0x73,0xac,0x42,0x84,0x1c,0xae,0x63,0xe9,0x7c,0x97,0x5a,0xb3,0x7d,0x87, + 0x51,0x1d,0x32,0x76,0xc6,0x11,0x81,0xd0,0xdc,0xdd,0x95,0x83,0x1d,0x43,0x73,0xa6, + 0xa9,0xd1,0x6d,0xf2,0x1d,0xdf,0x76,0x88,0xd9,0x46,0xad,0x86,0xc6,0x13,0xdf,0x88, + 0x36,0x90,0x84,0xc4,0xf8,0xb9,0x4e,0x52,0x88,0x7b,0xac,0xf7,0x2a,0x03,0x17,0x2d, + 0x44,0xf9,0xd4,0x84,0x74,0x45,0xdd,0xf5,0xcb,0xb0,0xf7,0x16,0x3f,0x45,0xe5,0x84, + 0x88,0x88,0xaf,0xda,0xa6,0xf9,0xd1,0xc7,0x7a,0x92,0xf5,0xe6,0xa2,0x4b,0x7a,0x57, + 0x87,0x7c,0xb3,0x35,0xa3,0x32,0x45,0x0d,0x4b,0xda,0x8a,0xf7,0xff,0x67,0xac,0xcc, + 0x4f,0x67,0xff,0xc8,0x99,0x1e,0xa7,0x95,0x54,0x0d,0x1d,0xe9,0x72,0x24,0xb8,0x7a, + 0xce,0x12,0xf9,0xe4,0x3e,0x59,0x3b,0xd1,0x0c,0x29,0xe4,0xa9,0x05,0xbb,0x5f,0xac, + 0x0f,0x37,0xf7,0xfc,0xc0,0xf8,0x26,0x2f,0xf5,0x40,0x73,0x65,0x47,0xc5,0x8a,0xb2, + 0x1e,0x16,0x91,0xa2,0x1a,0xab,0x27,0xbf,0x65,0x73,0xaf,0xa4,0x5c,0x64,0xd9,0x28, + 0x8a,0x0d,0xbf,0x51,0x99,0xba,0xe6,0x1a,0x25,0x8d,0x36,0xf7,0xb5,0x92,0xec,0xe8, + 0x4f,0xf3,0xda,0x38,0x9a,0x42,0x30,0xd6,0xdc,0x90,0x9c,0xfe,0x7e,0x9d,0xf7,0xa0, + 0xc5,0x91,0xc7,0x55,0x1f,0xa5,0x0e,0x94,0x49,0x55,0x48,0x7d,0x01,0x23,0x11,0xdd, + 0x4e,0x1c,0xa5,0x3d,0x9c,0x3f,0x80,0xdf,0x43,0xba,0x20,0x00,0xdb,0xbe,0xa7,0x38, + 0xd8,0xb1,0xbf,0x5b,0xc5,0xbd,0x68,0xa4,0x4b,0x23,0xd8,0xbd,0x56,0xa8,0x44,0x9d, + 0xa0,0xae,0x46,0x90,0x3c,0xa0,0x31,0x46,0xb6,0xbc,0xa0,0xcb,0xdc,0xc7,0x5b,0x1d, + 0xfc,0x40,0x2a,0x2a,0x83,0x77,0x29,0xde,0x51,0x3f,0xa5,0x47,0x27,0x07,0x5d,0xe0, + 0xfd,0xf3,0x99,0x08,0x9d,0x61,0xb5,0xaf,0xc2,0xe3,0x8e,0x4b,0x1b,0xf2,0xca,0x63, + 0xf7,0x0b,0x68,0x49,0x97,0x24,0x28,0x1d,0x61,0x55,0xc0,0x91,0xb3,0x6b,0xef,0x78, + 0x60,0x4a,0x37,0xb6,0x91,0xa2,0x66,0x58,0x45,0x44,0x92,0x96,0x72,0x8f,0xf5,0x3e, + 0x21,0x47,0xa1,0xf7,0xa3,0xad,0x91,0x41,0x94,0xb9,0xcd,0x02,0x3b,0x77,0xde,0xd5, + 0xa3,0x05,0xd0,0x37,0x71,0xd8,0x3f,0xf5,0xe3,0x6d,0x6e,0x40,0xd5,0xbd,0x62,0xbe, + 0xcc,0x05,0x99,0x4c,0x6f,0x1d,0xb8,0x57,0x8d,0x1c,0xda,0x31,0x5e,0xa0,0x88,0x9a, + 0xe3,0x7d,0x3b,0xc9,0xf8,0x96,0x1e,0x11,0x4f,0x63,0x36,0x43,0x83,0xb4,0x41,0x78, + 0xf8,0x01,0x5c,0x25,0x24,0x30,0x43,0x38,0xbc,0x1a,0xa7,0xa9,0x9d,0xb5,0x33,0xea, + 0xf5,0x67,0x4b,0x74,0x8e,0x69,0xc8,0x5b,0x36,0x57,0xf8,0xfd,0xdd,0x6f,0x7a,0xbb, + 0x32,0x4e,0x43,0xc8,0x7c,0x69,0x92,0x48,0x22,0xb3,0xe7,0x23,0xa7,0x10,0xe7,0x2a, + 0xbc,0x50,0xb2,0x5e,0xe6,0x2b,0x2e,0xfc,0x6b,0x48,0xca,0xdd,0x38,0x92,0x88,0x62, + 0x17,0xf3,0xa3,0xff,0xab,0xd3,0x6d,0x41,0xcc,0x4f,0x89,0xf0,0xe6,0x2c,0xe7,0xca, + 0xb3,0x05,0xb9,0x35,0x3a,0x29,0x01,0x90,0xf7,0x0d,0xa3,0x8d,0x78,0xce,0xbd,0xc7, + 0xfa,0x18,0xdd,0x70,0xd7,0x72,0xcf,0xa3,0x1f,0x5c,0x45,0x5a,0x8d,0x01,0x55,0xbc, + 0x84,0xe0,0xaa,0x10,0x70,0x59,0x3a,0x65,0x60,0xf5,0xe2,0x14,0x77,0xb9,0x80,0xa1, + 0xe2,0x02,0x07,0xe8,0xb6,0x38,0xcc,0x97,0xdf,0x43,0xeb,0x04,0x05,0x21,0xf2,0xe3, + 0xd7,0xcc,0x4d,0xb0,0xbf,0x71,0x54,0xf0,0x9a,0x5f,0xa9,0xd7,0x02,0x16,0x64,0x0b, + 0xc3,0x4b,0x7c,0x83,0xf0,0x64,0x6c,0x30,0x99,0x5b,0x14,0xc4,0x1a,0x8b,0x04,0xa1, + 0x40,0x9b,0xae,0x50,0x10,0x9a,0x56,0xf4,0xc0,0xae,0xa8,0x70,0x53,0xb8,0xfc,0x86, + 0x68,0x27,0xcd,0x23,0xb4,0x1d,0x35,0xa0,0x1b,0x5b,0xeb,0xd0,0xf4,0x77,0xdc,0x55, + 0x83,0x15,0x0d,0x34,0x41,0x75,0x8d,0x75,0x9e,0xd1,0xd5,0xed,0x88,0x57,0x2d,0xf7, + 0xf9,0xc5,0x9c,0x1a,0x3e,0x71,0x4d,0xbf,0x6e,0xa2,0xae,0x57,0x7e,0x81,0xb7,0xdf, + 0xf3,0x13,0x4e,0xe4,0x2f,0x78,0xde,0xc4,0x77,0x1b,0x33,0xc3,0xe4,0xec,0x1f,0x8d, + 0xdb,0xe5,0xb9,0x09,0x93,0x2f,0x4c,0x09,0xb4,0x3a,0xdb,0xe3,0x0d,0x26,0xcb,0x71, + 0x69,0xd6,0x2c,0xa5,0x65,0x8a,0xd3,0xc5,0x96,0x1b,0x8c,0x86,0x81,0x8e,0x7e,0x39, + 0x89,0x5c,0xc6,0xd8,0x3c,0x2f,0x36,0xac,0x24,0x51,0x61,0xd9,0x7c,0xf5,0x5e,0xe9, + 0xd4,0xb6,0xb0,0xe9,0x58,0xb4,0x66,0x70,0xe9,0x75,0xfe,0xf5,0x18,0x8f,0x27,0xeb, + 0xa2,0x5c,0xc7,0xcf,0x13,0xb3,0xa8,0xae,0xe4,0x5d,0x90,0x05,0xcd,0xbe,0x37,0xdd, + 0x16,0x5d,0xd9,0xe8,0x08,0x72,0xe4,0x9b,0xa8,0xe0,0x4a,0x79,0xdb,0x5c,0x1e,0xa3, + 0x37,0x04,0xb2,0x95,0x96,0xa4,0x8d,0x68,0xa1,0x1f,0xbb,0x55,0x28,0x61,0xbb,0x61, + 0x71,0xed,0x6c,0x93,0x56,0x53,0xf8,0xf3,0x33,0x1c,0xee,0x0a,0x53,0x29,0xc3,0xed, + 0x65,0x2d,0x2a,0x65,0x6b,0xc0,0xdd,0xbc,0xc5,0x62,0xb3,0xd4,0x50,0x6f,0x4f,0x2e, + 0x86,0xda,0xb9,0x75,0xd7,0xe1,0x41,0x0c,0xe7,0x82,0xdc,0xb3,0x90,0xc6,0x74,0xb2, + 0xc5,0xd5,0xc4,0x0a,0xb5,0xa2,0x60,0xc3,0xe7,0x3b,0xe1,0x95,0x66,0x6e,0x97,0x3f, + 0x26,0xe7,0xec,0xb4,0x11,0xfc,0x01,0x0d,0xe0,0x84,0xe8,0xea,0xa8,0x48,0xa1,0x63, + 0x84,0x8b,0xc1,0x17,0x37,0x2e,0x2b,0x6c,0xae,0xd7,0x89,0x87,0xa4,0xa4,0x33,0xce, + 0xfb,0xc5,0x5d,0xd3,0xc0,0xa8,0xf8,0x32,0x86,0x86,0x6f,0x86,0x74,0x27,0x1c,0x33, + 0x64,0x59,0xa6,0xb8,0x2f,0xe3,0x22,0x2b,0x40,0x8a,0x72,0x7a,0xab,0x84,0xd1,0x3d, + 0xac,0x76,0xa2,0x1b,0x3d,0x59,0xe5,0x3b,0x4b,0x20,0x17,0x41,0xc0,0xb6,0xe3,0xca, + 0x94,0x87,0x19,0xc8,0x5e,0xaa,0x2b,0x23,0x49,0xea,0x54,0xd0,0x2d,0x3c,0x72,0x86, + 0x28,0x34,0x68,0xf7,0xa2,0x66,0xe1,0xbf,0xac,0x91,0x84,0x12,0x22,0x76,0x72,0xeb, + 0x6d,0x73,0x3d,0x4f,0x18,0xe5,0xad,0x6a,0x39,0x4c,0xc0,0x5e,0x95,0x43,0x7b,0xde, + 0x2f,0x8f,0xfa,0x5e,0x03,0xef,0x72,0xdd,0x2c,0xed,0x3a,0x5e,0xba,0xe7,0x1b,0xbb, + 0x29,0x2f,0xfd,0xcb,0xeb,0xdc,0xb3,0x17,0xbb,0xc8,0x53,0x1d,0xbc,0x69,0x53,0xcb, + 0x2c,0xdf,0xb3,0x13,0xac,0xbd,0x03,0xf9,0xc6,0x12,0xbf,0xfb,0xff,0xc5,0x07,0x60, + 0xc4,0x6f,0x87,0xba,0xec,0x41,0xf4,0xd7,0x03,0x92,0xe0,0x98,0x56,0xb2,0x77,0x92, + 0x23,0x21,0x57,0xb1,0x94,0x4e,0x8d,0x36,0x46,0xe6,0x5b,0xd8,0xa3,0xf9,0x96,0x61, + 0x5c,0xb1,0x65,0xd3,0x1c,0xbf,0xf4,0x7e,0xe2,0x2b,0x2a,0x66,0x79,0x8f,0x43,0xc9, + 0x58,0x0f,0x41,0x04,0xcd,0x6e,0xe6,0x85,0x9a,0xc2,0x7c,0x33,0xb0,0xd6,0x74,0x7b, + 0x87,0x0b,0x9a,0xee,0x75,0x44,0x0c,0x60,0x6f,0x69,0xca,0xd3,0xd5,0x7f,0x73,0x89, + 0xaa,0x68,0xd2,0xfe,0x74,0x45,0xa3,0x56,0x61,0x2c,0xc2,0xde,0xd0,0x55,0xd1,0xa1, + 0x5d,0xd4,0xfd,0xe7,0xfc,0xa7,0x4d,0xb3,0xe2,0xd9,0xef,0xd6,0x9a,0xe9,0x0f,0xfb, + 0x52,0x11,0xf5,0xc7,0x56,0x08,0x1f,0x77,0xcc,0x51,0x6b,0x84,0x9b,0x9b,0x20,0x2b, + 0x2a,0xb2,0xc0,0xb6,0x3d,0x68,0x6d,0x91,0x17,0x00,0x76,0xfa,0xc9,0x59,0xc2,0x05, + 0x2c,0x39,0x6e,0xca,0xca,0xd7,0xfe,0xdf,0xb2,0x42,0x6d,0xf9,0x73,0x26,0xf3,0xe9, + 0x53,0x07,0x80,0x89,0x6c,0xde,0x82,0x63,0x58,0x30,0xa0,0x50,0x15,0x6b,0xef,0x5a, + 0x83,0x06,0x10,0x04,0x48,0x2d,0x8d,0x42,0xdd,0x27,0x00,0x3a,0x02,0xb9,0x66,0x0a, + 0x14,0x17,0xfa,0x0c,0x5d,0x30,0x56,0x34,0xec,0xf4,0x94,0xf3,0x7d,0xbc,0xd6,0x0a, + 0x8c,0x62,0xe3,0xac,0x9c,0x36,0x06,0x78,0xef,0x55,0x19,0x03,0xbc,0xbf,0x7d,0xfa, + 0x9e,0x81,0xf1,0xfa,0xb8,0xbf,0x48,0x89,0xad,0x61,0xeb,0x23,0xda,0x25,0x36,0x1f, + 0x0a,0x1e,0x43,0xee,0xd3,0xfd,0x47,0xab,0xeb,0xd0,0x64,0xcd,0x88,0x09,0xdf,0xd2, + 0x06,0x28,0x16,0x80,0x30,0x22,0xef,0x07,0xe1,0xbc,0x2f,0x15,0xf1,0xe1,0xf0,0x18, + 0xfc,0x4e,0x80,0x05,0xed,0xc0,0xd8,0xe8,0x6f,0x4b,0xca,0x82,0xba,0x05,0x76,0xe9, + 0x62,0xdf,0xb9,0xc2,0x52,0x02,0xe9,0x29,0x3d,0x0d,0x7a,0xd6,0x54,0xef,0x69,0xa6, + 0x62,0x0e,0x49,0x21,0xc5,0xa8,0x9b,0xd9,0x19,0x88,0x09,0xc6,0x55,0xee,0xd3,0x7f, + 0x7a,0x46,0x55,0xa2,0xb7,0x4a,0xf0,0x13,0x7e,0x97,0x10,0xa5,0x23,0xe5,0x5e,0x6c, + 0x05,0x04,0x60,0xe4,0x20,0xb3,0xe6,0xf5,0xf4,0x20,0x8a,0xfe,0x55,0x9d,0x96,0x6e, + 0xe1,0x6b,0xa3,0x54,0x93,0x9c,0x2f,0x66,0x63,0x03,0x81,0x96,0x56,0xeb,0x09,0x23, + 0x20,0x8c,0x71,0xbd,0x37,0x68,0x61,0xf4,0x7c,0xfa,0x61,0xf1,0xd8,0x87,0xae,0x9a, + 0x0a,0x02,0x7a,0x3d,0x74,0x6a,0x90,0x6e,0x2a,0x09,0xc0,0x9b,0xb3,0x0c,0xbe,0x7a, + 0xba,0x6c,0x0a,0x0d,0xe5,0xc8,0xe2,0x09,0x25,0x0b,0x39,0xcf,0xdd,0xe4,0x57,0x6b, + 0xc8,0x05,0x93,0x8d,0x39,0xad,0x29,0xda,0xa4,0xc1,0x03,0x1c,0x79,0xeb,0x33,0xf2, + 0x25,0x06,0x4b,0x58,0xe0,0x8b,0x0b,0xb9,0x68,0x25,0xc9,0x8b,0x32,0x0f,0x85,0x79, + 0x7e,0x4e,0x02,0x15,0xd0,0xb1,0x44,0x0a,0xb5,0xd1,0xea,0x96,0xf6,0x61,0x32,0x67, + 0x73,0x4f,0x5a,0x37,0x15,0x4f,0xff,0x9a,0x4d,0x9d,0x92,0x74,0x5d,0x47,0x53,0xe8, + 0xe9,0xf1,0xbb,0x6a,0x63,0x21,0x93,0xd5,0xa2,0x13,0x7f,0xf2,0x2b,0xb8,0xd2,0xb6, + 0x62,0xbe,0x81,0xe0,0x24,0x74,0x43,0x02,0x9a,0x44,0x5d,0x03,0x78,0x0a,0x64,0x37, + 0xcb,0x50,0xfa,0x83,0x14,0x91,0x72,0xf9,0x63,0x63,0x04,0xbb,0x4c,0xc4,0x72,0xf2, + 0xd2,0x74,0x2c,0xe6,0x53,0xf6,0x0c,0x11,0xc0,0xf8,0xa2,0xed,0x33,0x8e,0x45,0xe4, + 0x22,0xf5,0xbd,0xb5,0x76,0x9d,0x4f,0x3c,0x9c,0x10,0x86,0xd7,0x1b,0xc3,0x35,0x6a, + 0x0d,0x1e,0xf3,0x92,0x95,0x3e,0x8b,0x51,0xdd,0x11,0xa3,0x8c,0x7c,0x85,0xd1,0x44, + 0x02,0x16,0x28,0x56,0x64,0x3c,0x0d,0xef,0x87,0x38,0x14,0x25,0x41,0x36,0xdf,0xf3, + 0x8e,0xb5,0x60,0xab,0xe9,0xca,0xde,0xf2,0x61,0x17,0x63,0x6f,0x86,0xd3,0x7d,0x51, + 0x01,0xb6,0xd5,0x83,0xd0,0x77,0x37,0xe4,0xe1,0x36,0x56,0x11,0x09,0x18,0x5a,0xf2, + 0x32,0x56,0x76,0x4f,0x44,0x2c,0x8e,0x94,0x6e,0xfa,0xa5,0xb5,0xeb,0x35,0xfd,0xaf, + 0x89,0xe7,0x79,0x64,0xe2,0x75,0x06,0x01,0xc9,0xc7,0xde,0x55,0x1b,0x8a,0x0b,0x1a, + 0xc7,0x56,0x1e,0x67,0xf8,0xb3,0x8f,0x88,0xe8,0x26,0xca,0xde,0x10,0x08,0x5e,0x99, + 0xae,0x18,0x7c,0xf2,0x35,0xec,0xa3,0xcb,0x13,0xf7,0x81,0x94,0xfe,0x7b,0xb4,0x7b, + 0x1e,0x7e,0x08,0x8d,0x1a,0x86,0x25,0x08,0xd1,0x04,0xc7,0xc4,0x10,0xca,0x18,0xe5, + 0xf4,0xb7,0x27,0xaa,0xb7,0x5e,0xc9,0x7a,0x62,0x56,0x9a,0x04,0x8f,0x88,0x70,0x38, + 0x62,0xe4,0x94,0xde,0x88,0xe4,0x9e,0x44,0xa3,0x1d,0xd8,0xa9,0x92,0x95,0x54,0x1b, + 0x2f,0xbf,0xb8,0x8a,0x47,0x88,0xd3,0x6d,0x9c,0x65,0xaf,0x69,0xae,0xab,0x17,0xd1, + 0xad,0x45,0xae,0x1d,0xff,0xb2,0x89,0xca,0xd8,0xea,0x73,0x6f,0xa7,0x77,0xd9,0x25, + 0xa5,0xff,0x36,0x75,0x78,0xcc,0x52,0x23,0x45,0xbb,0x20,0x55,0x25,0x51,0x5a,0x74, + 0xf2,0x91,0x8c,0x81,0x31,0x0c,0x0d,0x2d,0x75,0x83,0xeb,0xc5,0xd9,0xec,0x18,0x41, + 0x25,0x99,0xc3,0x1a,0x97,0xe2,0x86,0x16,0xc2,0x18,0xcf,0x21,0x3d,0x9b,0x91,0xec, + 0x64,0x1c,0xb2,0x2f,0x7e,0xe7,0x29,0x9a,0x64,0x6c,0x29,0xdf,0x41,0xae,0x7e,0x7a, + 0x27,0x44,0xe0,0x81,0xeb,0xd2,0xdf,0xe6,0x30,0x83,0x4f,0x84,0xbf,0xfc,0x30,0xd7, + 0x64,0xa5,0x89,0x96,0x0b,0xd8,0xc2,0x8d,0x49,0x7a,0x86,0x70,0xb6,0x66,0x5f,0x7f, + 0xef,0x17,0xbb,0x45,0x25,0x7f,0x79,0xd2,0xf5,0x12,0xe7,0x05,0xb6,0xec,0xb2,0x53, + 0x37,0xf6,0xfe,0x39,0xe5,0xcb,0xd5,0x9b,0x42,0x8a,0x98,0xf3,0xdc,0x7e,0x5d,0xc8, + 0xad,0x97,0x98,0xbf,0x21,0x07,0x27,0x0d,0xed,0x67,0x4d,0xc6,0xe0,0xa5,0xf9,0xe4, + 0xf4,0xba,0x92,0x2e,0xcb,0x06,0xac,0xbe,0x14,0xe5,0x81,0x4e,0xdd,0xf6,0x9e,0x36, + 0x73,0xd7,0x07,0x2b,0x29,0x0b,0xa2,0x10,0xfc,0x3f,0x24,0xc9,0xf8,0x5c,0x54,0x61, + 0xbf,0x14,0x0b,0x6d,0xff,0x6c,0x01,0xc4,0x30,0xa7,0x02,0x4f,0x5d,0xfd,0x63,0x48, + 0x46,0xe0,0xf8,0x4c,0xdc,0xa8,0x15,0x9a,0xce,0x8e,0xe0,0x8e,0xb5,0xa8,0x03,0xb1, + 0x09,0x8c,0x52,0xb1,0x2c,0x58,0xba,0xc6,0x97,0x8f,0x75,0x18,0x60,0xcd,0xb7,0x15, + 0xa0,0x52,0xab,0xcb,0xad,0xfa,0x24,0x15,0xcd,0xaf,0xc9,0xdf,0x4c,0xac,0x86,0xab, + 0x28,0x2e,0x53,0x72,0x38,0xe2,0x2c,0x99,0xcc,0xbd,0x22,0xcc,0xe4,0x92,0x9b,0x60, + 0x9b,0x96,0xee,0x9b,0x74,0xd5,0xd8,0xd9,0xfa,0x4d,0xb6,0x55,0x00,0x5d,0xb3,0x92, + 0x25,0x91,0xba,0xf4,0xca,0x1c,0xfb,0x8f,0x63,0xd0,0xf4,0xd7,0x16,0x03,0xd3,0x70, + 0xa2,0x90,0xdd,0xa3,0x5d,0xa8,0xd4,0xe3,0xea,0x59,0x26,0xe0,0x3e,0x4a,0x2d,0xe1, + 0x27,0x74,0x63,0x32,0x42,0x4e,0x69,0x43,0x1a,0xdc,0xab,0x8b,0xf3,0xf2,0x84,0x46, + 0x05,0x55,0xbd,0xf8,0x91,0xa4,0xcc,0x82,0x62,0xf9,0xd5,0xc2,0x9d,0x90,0xd4,0x2c, + 0x37,0xd8,0x62,0xc5,0x7a,0xad,0x24,0x1f,0x54,0xbf,0x83,0x72,0x24,0x3b,0x49,0x0c, + 0x95,0x1a,0x1d,0xe3,0x57,0x19,0x6b,0x0b,0xd1,0x1b,0xcd,0x1d,0x5a,0xfb,0x12,0x89, + 0x52,0x0b,0xbd,0xc2,0xf3,0x3c,0xc5,0x13,0x80,0xcc,0x6d,0xc5,0x00,0x56,0x5c,0x68, + 0xa3,0x83,0xb4,0xcc,0x18,0xc5,0x6c,0x4c,0x04,0x39,0xe2,0xcc,0x15,0x89,0x96,0x14, + 0x2c,0x09,0xd5,0xe1,0x45,0x06,0x7c,0x58,0x31,0xdd,0x09,0x87,0x7b,0xd8,0x0f,0xed, + 0x32,0x88,0xd8,0x2a,0x76,0xb7,0xf7,0x8b,0xee,0xd7,0xef,0x6e,0x04,0x2b,0x4f,0x2c, + 0x0a,0x96,0x95,0x27,0x4e,0xfa,0x13,0x4b,0x4a,0x7a,0xa3,0x7f,0xec,0x4e,0x59,0x53, + 0x0d,0xbc,0xee,0xff,0x2f,0x13,0x97,0x8c,0xd5,0x6d,0xe8,0x15,0x9f,0x9f,0x91,0xa0, + 0x01,0x42,0xd6,0xee,0x3d,0x12,0x6e,0x12,0xfb,0x90,0xc5,0x8e,0xff,0xe2,0x24,0xb0, + 0xc6,0x93,0xee,0xbc,0xaf,0x1f,0x4d,0x53,0xcc,0x33,0x8c,0x90,0x73,0x48,0x51,0xe3, + 0xd3,0x30,0x4f,0xad,0xdd,0xa9,0x82,0x13,0x1b,0x92,0xa5,0xfd,0x6d,0xbe,0x12,0xff, + 0xfb,0x8d,0x76,0xc2,0xb1,0x3b,0xa0,0x57,0x4e,0x9f,0xb6,0xc6,0xdc,0x21,0x1f,0xe3, + 0x85,0xdc,0x06,0x25,0xb0,0xa0,0x66,0x69,0xc3,0xa6,0x67,0xd8,0xf1,0x5a,0x53,0xfe, + 0x73,0xff,0xa4,0xe3,0xb4,0x8f,0x81,0xc9,0xff,0x8f,0x51,0x05,0xb1,0xd9,0x5a,0xe2, + 0x0d,0x0e,0xa4,0xe6,0x15,0xae,0xf1,0xd3,0xb6,0x43,0x5e,0xb1,0xf1,0x3a,0x9b,0xcb, + 0x7d,0x0f,0xfe,0x3c,0x6e,0x66,0x0a,0x29,0x3e,0x06,0x89,0xba,0x21,0xa3,0x48,0x22, + 0xf8,0x47,0x0c,0xd1,0x1d,0xaf,0x66,0x48,0xce,0x93,0x01,0xc2,0x68,0xb3,0x7f,0x90, + 0x3d,0x5d,0xce,0x79,0x33,0x19,0x1d,0xa9,0x63,0x99,0x8e,0x64,0xed,0x46,0x54,0x9d, + 0x62,0xf8,0x0e,0xa6,0xb5,0x4b,0x51,0x61,0x9f,0xb0,0x22,0x88,0x81,0x25,0x7d,0xad, + 0xc2,0x05,0xd0,0xbf,0xf3,0x4c,0xcd,0x35,0x33,0x48,0xa8,0xdf,0x34,0xc5,0x31,0xa8, + 0x2f,0xbd,0xb2,0x2c,0x4d,0x86,0x47,0xe9,0x4f,0x4b,0xd2,0x4d,0x3a,0x04,0x78,0x7b, + 0xf0,0xb5,0x13,0x8f,0x7e,0xb8,0xce,0xd7,0xff,0x9d,0x05,0x6a,0x12,0xd2,0xab,0xea, + 0x05,0x86,0x2b,0x6f,0xfb,0xec,0x28,0x4a,0x90,0x40,0x8d,0x08,0xdf,0x6a,0xfd,0x0f, + 0xc0,0xa6,0xff,0xdf,0x3c,0x83,0xd0,0x16,0x29,0xa8,0xd5,0x7e,0xdd,0x2f,0x9e,0xfa, + 0xaa,0x92,0x1d,0xaf,0x35,0x6f,0x62,0xfa,0xad,0xfd,0xea,0x1a,0x1b,0x22,0x0b,0x38, + 0x77,0x4c,0x13,0xc8,0x94,0xa4,0xc4,0xed,0xc1,0xf6,0x13,0x8d,0x98,0x75,0xff,0x3b, + 0x70,0x14,0xc4,0xb8,0x9d,0x97,0x23,0xd9,0x93,0x0d,0x63,0xcf,0x9b,0x8f,0x64,0xc4, + 0x5b,0x9b,0x92,0xbc,0xdb,0x74,0x49,0xbc,0x66,0x71,0x23,0x91,0x76,0xda,0xac,0xe2, + 0x82,0x17,0x28,0xb0,0x52,0xd5,0xdc,0x71,0xa1,0x13,0x0d,0xca,0xbb,0x40,0x85,0x63, + 0x22,0x5a,0xbf,0x35,0x56,0x9d,0xc5,0x25,0xc9,0x17,0xc0,0xe2,0x0d,0xd4,0xdd,0xd5, + 0x02,0x76,0x9a,0x66,0x35,0xbe,0x16,0x23,0xe7,0x49,0xd5,0xa1,0x25,0x42,0x59,0x44, + 0x0c,0xd3,0xcb,0x21,0x8f,0x9b,0x6a,0xd9,0xc5,0x52,0xe7,0x82,0x8d,0xf5,0x4b,0x20, + 0x5e,0xe4,0xb2,0xd3,0xca,0x94,0xdd,0x96,0x94,0x45,0x8c,0x83,0x69,0x6e,0x85,0x71, + 0xb4,0x1e,0x65,0x60,0x78,0x3b,0x05,0xfc,0x41,0x4d,0x2a,0x63,0xa8,0x8b,0x33,0xd7, + 0x42,0x94,0x6d,0x2e,0x42,0x94,0xe5,0x0e,0xe5,0xce,0x11,0x93,0xd0,0xf5,0x7e,0xaf, + 0x0c,0x91,0xd4,0x3a,0xd3,0x5c,0x8c,0x2c,0x1c,0x6d,0x31,0x80,0xe0,0x69,0x08,0x38, + 0x4a,0xab,0xf0,0x9a,0xd8,0xba,0x88,0xbb,0xe9,0x39,0xa0,0x94,0x9a,0x70,0x83,0x76, + 0x5c,0x19,0x17,0x7d,0xa1,0x8b,0xd7,0xd0,0xd5,0x18,0x92,0x06,0xa4,0xb4,0x9c,0x6a, + 0x2d,0x96,0x7d,0x6e,0x35,0x7a,0xdf,0x99,0x88,0xd6,0x0f,0x4d,0xa7,0xda,0x23,0x3b, + 0xa6,0x97,0x62,0x36,0x3c,0x84,0x61,0x6c,0x2c,0x2d,0x8f,0xd7,0xdf,0xfe,0x0c,0x26, + 0xd6,0x71,0x2d,0x9c,0x3d,0x39,0x5f,0x9e,0xe9,0x59,0x61,0xb6,0x6b,0x79,0x43,0x2b, + 0x43,0xb4,0xf3,0x33,0x03,0x50,0x0e,0xe5,0x4f,0xa1,0x28,0x1d,0xf2,0x62,0xac,0x19, + 0xb1,0xe2,0x4d,0xb6,0x34,0x99,0x0f,0xa6,0x48,0x3a,0x5f,0xba,0xd5,0x61,0x58,0x26, + 0xa1,0xec,0xde,0x01,0x30,0x0d,0x74,0xca,0x73,0x0d,0xf0,0x44,0x75,0x0a,0x92,0x22, + 0x06,0x2e,0x90,0x26,0xc5,0x0e,0x80,0xd2,0x09,0xda,0xc6,0x1a,0xbe,0xf0,0xe5,0xf8, + 0xb7,0xb6,0x32,0x36,0x35,0x03,0x69,0x3b,0xf7,0xf6,0xeb,0xd8,0x3f,0xd3,0x89,0x61, + 0xe7,0xb5,0x09,0x65,0xf7,0x04,0x9d,0xd5,0xd5,0x8c,0x83,0xdc,0xb6,0x6f,0xbb,0x34, + 0x8b,0xe6,0xd4,0xad,0x9b,0x02,0x29,0x56,0xe3,0x65,0x30,0xaa,0x6c,0x69,0x60,0x0e, + 0x64,0x8e,0xfb,0x42,0xea,0xc9,0x7a,0x7f,0xbb,0x54,0x69,0x4c,0x6f,0x10,0x8d,0xc7, + 0xe4,0x5c,0x31,0x87,0x9f,0xa5,0x62,0x90,0xbe,0xc5,0xa8,0x45,0x71,0x53,0xfe,0xa0, + 0x03,0x0a,0x8b,0x53,0x94,0x97,0x07,0x4b,0x1b,0x76,0xe8,0x49,0xbb,0xa5,0x5c,0x0d, + 0x28,0x03,0xdc,0x09,0x38,0x23,0x9a,0xb2,0xad,0xd3,0xa7,0xaa,0x7c,0xd0,0x8a,0x68, + 0x6f,0x6e,0x90,0xae,0xed,0x06,0x22,0x1e,0x7e,0xa4,0xaa,0x85,0xfc,0xe2,0xba,0x3a, + 0xf0,0x25,0x79,0x23,0x77,0xee,0xea,0xdd,0x25,0x72,0x8b,0x4f,0x86,0xa8,0x55,0x1c, + 0x2c,0xca,0x0f,0x3b,0xfe,0xe1,0x60,0xa4,0xfa,0x4c,0x7d,0x64,0x64,0x57,0x30,0xc1, + 0xe5,0xe8,0xf2,0x76,0x2a,0x51,0x52,0x6f,0x86,0x5d,0x79,0xb0,0x58,0x96,0x86,0xc8, + 0x0f,0x85,0xf8,0x35,0x90,0x0b,0x69,0x9c,0xcd,0xce,0x3a,0xd3,0xac,0x60,0x39,0x4a, + 0x2d,0x73,0x0f,0xdd,0x82,0xa4,0x64,0x83,0x84,0x63,0x26,0xeb,0xae,0x5c,0x2e,0x24, + 0x89,0x0c,0x3f,0x1f,0xeb,0xed,0x7e,0x99,0xfc,0x0d,0xa2,0x69,0x78,0xf4,0x76,0x34, + 0x00,0x2f,0xfa,0x64,0x68,0x34,0xcb,0x52,0xa5,0x21,0x22,0x22,0x54,0xd3,0x13,0xe2, + 0x29,0x3e,0xd4,0x8b,0xf5,0xf0,0x64,0xba,0x06,0xbf,0x44,0x32,0x55,0xf3,0x1f,0x33, + 0x82,0x0d,0xdd,0xf4,0xc0,0x19,0xf5,0x83,0xfd,0xdf,0x8b,0x8f,0x57,0x73,0x8d,0x89, + 0x29,0x6e,0xd3,0x90,0x14,0x6c,0xaa,0x37,0xc5,0xdf,0x85,0xa7,0x56,0x5e,0xa4,0x72, + 0x69,0xd6,0x30,0x86,0x22,0xc9,0xcb,0x00,0xca,0x79,0x8f,0x0e,0xb2,0xbb,0xad,0x92, + 0x7f,0x1e,0x51,0xeb,0xc8,0x9d,0x6b,0x10,0x61,0xec,0xaa,0x05,0xf3,0x7e,0xb1,0x75, + 0xa0,0x15,0x72,0x38,0x36,0x16,0x66,0x01,0x4a,0x7b,0x65,0x17,0xc6,0x57,0x31,0xee, + 0x4c,0xd3,0x10,0xf3,0x95,0x14,0x68,0x77,0x9a,0x8a,0xc8,0x46,0x95,0x58,0x5e,0x96, + 0x08,0x37,0x12,0xec,0xc3,0x15,0x0c,0x48,0x30,0x2f,0x20,0x2a,0x5c,0xab,0x50,0x9d, + 0x09,0xa8,0xf0,0x7c,0x39,0x14,0x33,0x3e,0x70,0x33,0x80,0x92,0xde,0x59,0x87,0xf9, + 0xce,0x5d,0xae,0xbe,0x1d,0xfb,0xb0,0xc4,0xea,0x08,0x89,0x86,0x5f,0x9f,0x56,0xfd, + 0x20,0x6d,0x21,0xad,0x56,0xff,0xff,0xc3,0x34,0xdd,0x29,0x9e,0x73,0xba,0x5c,0x7a, + 0xb4,0x33,0x3a,0x33,0x52,0x07,0x3e,0xee,0xeb,0x3d,0x52,0xca,0x50,0x23,0xe9,0x9b, + 0x2d,0xdc,0xb7,0x41,0x9a,0xb6,0xaa,0x7c,0x1f,0x20,0x80,0x4f,0x96,0x7e,0xc3,0x3b, + 0xa6,0x91,0xf2,0x4b,0x88,0xbe,0xe7,0xf0,0xc4,0xa3,0x5b,0x9c,0x94,0x08,0xc8,0xe3, + 0xd0,0xbf,0x7e,0xff,0x99,0x5d,0x61,0x5a,0xce,0x66,0x1c,0x0c,0x9d,0xbe,0xb7,0xd4, + 0x77,0x00,0xfe,0x03,0xb1,0x5f,0x2a,0xda,0xbb,0x3d,0x6f,0x5e,0x26,0xbf,0x5e,0x6e, + 0x6b,0x82,0x48,0xd5,0x5a,0xbc,0x60,0xce,0xb8,0x72,0x87,0x62,0x57,0x40,0xbe,0x30, + 0xea,0xad,0x2d,0x7f,0x0e,0xbd,0x86,0xde,0x75,0xe1,0x51,0x05,0x44,0x20,0x77,0xa1, + 0xa5,0xae,0xf1,0x0c,0xf2,0x43,0x66,0x4b,0xf3,0xdc,0x82,0xb1,0x89,0x0f,0x0a,0xbb, + 0xa1,0x02,0xd6,0xf0,0xed,0x89,0xf3,0xc5,0x9e,0xc7,0xf8,0x17,0xde,0xe2,0xb3,0xb2, + 0xa2,0x8f,0x2a,0x4b,0xdd,0xa8,0x62,0x41,0x25,0xea,0x1f,0x45,0x61,0x27,0x61,0x7d, + 0x23,0x8c,0xb9,0xf4,0xf8,0x89,0x72,0xd0,0x1a,0x85,0xd1,0xa5,0xc0,0xed,0x36,0xb3, + 0x22,0x88,0xb7,0xc6,0xf8,0xa1,0x08,0x02,0xa9,0xc4,0xc9,0xd4,0xb0,0x98,0x54,0x38, + 0xf7,0xa7,0x15,0xf3,0xf9,0xfb,0x82,0xd2,0x2b,0x59,0x3b,0x52,0xcd,0x14,0xf5,0xeb, + 0x6f,0x48,0x28,0x6a,0x9b,0xee,0xa8,0x80,0xa2,0x2d,0xad,0x8d,0xad,0xea,0xd5,0x7a, + 0xea,0x89,0x78,0x0f,0x51,0x31,0x04,0xda,0x4c,0xc1,0x2c,0x62,0x28,0xe9,0x51,0x31, + 0xe1,0xa8,0x04,0xff,0xe2,0x0b,0x23,0xc7,0x34,0x27,0x2c,0x8c,0xdf,0xdb,0x22,0x4a, + 0x76,0x03,0x42,0x5f,0x70,0xfa,0x29,0x9b,0x24,0x20,0xaa,0x9d,0xf9,0x2c,0x72,0xda, + 0x29,0x3d,0xad,0xad,0xc9,0x6d,0x12,0xe1,0xc6,0xc0,0x8d,0x8c,0xa4,0x62,0xd3,0xcd, + 0x81,0xac,0xe5,0xf9,0x44,0x81,0x6d,0xcc,0x08,0xce,0xed,0xc5,0xdc,0x6f,0x33,0xdb, + 0x6d,0x3d,0xb5,0x6b,0x70,0xca,0x3d,0xc9,0x34,0xc4,0x6f,0x9f,0xff,0xe4,0xf9,0x78, + 0x20,0xef,0x44,0xa4,0x6e,0x2b,0x6a,0xa6,0x03,0x65,0x7a,0x87,0xe7,0x55,0xa0,0xe3, + 0x4b,0x90,0x27,0x11,0xa2,0x0e,0x8c,0x4c,0xe1,0xaa,0x1b,0x90,0xf4,0x81,0xde,0x81, + 0xa4,0xa2,0x03,0xdb,0x3d,0x50,0x43,0x8d,0x0b,0x36,0x29,0x86,0x47,0x3c,0x09,0x62, + 0xcf,0x9e,0x72,0x65,0x59,0x42,0xbd,0x33,0x07,0xb7,0x0d,0xc7,0x0e,0x31,0x1d,0x59, + 0x87,0xcb,0xb6,0xcc,0xd6,0x93,0x5c,0xc8,0x8b,0xd7,0x73,0xe2,0xa6,0x10,0x6e,0x2b, + 0xca,0xdf,0xcd,0xe2,0xcb,0xce,0x88,0x63,0x0d,0x8a,0x18,0x24,0x7f,0x73,0x7b,0x15, + 0x76,0x19,0xf4,0x69,0x56,0xa3,0x33,0x49,0x1d,0xfb,0xed,0x0a,0xfc,0x14,0xee,0x33, + 0x63,0xba,0xcd,0x17,0x30,0x71,0x9d,0x39,0xe3,0xfa,0x55,0x38,0x50,0x0a,0x96,0xfb, + 0x6f,0x9a,0x46,0xad,0x7e,0x35,0x4c,0xaa,0xcb,0x43,0xca,0x7e,0x99,0x87,0x6e,0x2f, + 0xd0,0x5b,0xb5,0x20,0xce,0x7b,0x13,0x5a,0x12,0x79,0x85,0xc8,0x02,0x79,0xf8,0xfa, + 0x82,0x5b,0xdc,0x8d,0xc4,0xc5,0x35,0xdf,0x6a,0x9d,0x17,0x4c,0x5e,0x3a,0x4f,0xfc, + 0x2b,0xfc,0x9f,0x60,0xbf,0x82,0x20,0xfe,0x2b,0xbb,0xc4,0xdd,0x86,0x5b,0x3e,0xa8, + 0x22,0xac,0x71,0xe8,0x51,0x33,0x07,0xd5,0x95,0xf1,0x9c,0xf9,0xf8,0x7f,0x2e,0x6e, + 0x20,0x12,0xde,0x65,0x9a,0x22,0xe1,0x6b,0x0d,0x80,0x92,0x0c,0x77,0x72,0xf8,0xd2, + 0x09,0x9a,0x47,0xbe,0x88,0x7c,0x81,0x55,0x1d,0x32,0x94,0x0f,0x78,0x36,0x16,0x40, + 0x0e,0xe0,0x7b,0xbf,0x50,0x7b,0x39,0x48,0xea,0x0f,0xf8,0xfb,0x2b,0x1b,0x5e,0x04, + 0x67,0x45,0x60,0xc7,0x5f,0xad,0xd3,0x06,0x27,0xd1,0x1c,0x59,0x68,0x1f,0x10,0xe1, + 0x27,0xef,0x04,0x89,0x14,0x21,0x8a,0x8e,0xae,0xa5,0xd8,0x34,0x54,0xec,0x77,0xb3, + 0x6f,0xe6,0x5e,0xef,0x18,0x6f,0xa6,0xd0,0x40,0x49,0x0a,0x8b,0x23,0xa3,0x4f,0x2b, + 0xa1,0x08,0xae,0xac,0xd1,0xac,0x01,0x17,0x32,0xce,0xcb,0x3f,0xd5,0xe9,0xa0,0x83, + 0x14,0x89,0xbe,0x75,0x06,0x0b,0x72,0xf1,0x68,0x1b,0x37,0x5b,0x50,0xe5,0x08,0x50, + 0x7e,0x88,0xd6,0xfe,0xdd,0xd6,0x42,0xed,0xb8,0x4e,0x00,0xf2,0x77,0xe7,0x01,0xe3, + 0xda,0x89,0xd3,0x01,0x04,0xca,0xb1,0xab,0xc6,0xaa,0xa5,0x08,0x75,0x67,0x7b,0x57, + 0x05,0x84,0x97,0x4c,0x7e,0x44,0x7b,0xed,0x30,0xc4,0xa3,0x76,0x74,0xa5,0x33,0x3b, + 0x62,0x27,0x62,0xcf,0x09,0xa5,0x4d,0xd2,0x4c,0x8a,0x2e,0xac,0x17,0x0f,0xf8,0xe9, + 0x81,0x84,0x3a,0x51,0xe4,0xd5,0x46,0x58,0xb6,0x88,0x14,0x1d,0xc8,0xcc,0x83,0xfb, + 0x68,0x29,0xc3,0xb9,0xc4,0xa5,0x34,0x6c,0x4e,0x2d,0xa5,0x4d,0xf3,0xcf,0xd4,0x3f, + 0x64,0xe8,0x02,0x60,0x08,0xf6,0x61,0x13,0xa5,0xba,0x12,0x1c,0x04,0xce,0xa7,0xa8, + 0x8c,0x4b,0x80,0x4e,0xf5,0x38,0xcc,0xc2,0xaf,0x13,0xe2,0xc7,0xaf,0xe3,0x0a,0xec, + 0x1d,0x80,0x8b,0xfe,0xc9,0x12,0x44,0xca,0x85,0xde,0x21,0x7c,0x20,0x94,0x2f,0x29, + 0xce,0x81,0xbd,0x40,0x92,0xe0,0x8c,0x69,0xe0,0xa0,0x47,0x14,0x7d,0xaf,0x94,0xa9, + 0xae,0x1d,0xc2,0x30,0x0e,0x6a,0x45,0xde,0x05,0x2c,0xa0,0x7d,0xa4,0x76,0x1a,0xe0, + 0x97,0xf5,0x0e,0x98,0x56,0x44,0x7c,0x13,0xb8,0x94,0x34,0x17,0xaa,0xbe,0xd5,0xb5, + 0x84,0xee,0x64,0x12,0x15,0x10,0x47,0x36,0x6e,0x89,0x9c,0xe7,0xd4,0x79,0x1d,0x68, + 0x08,0x9f,0xf3,0xe9,0xb2,0xb3,0x96,0xa4,0x48,0xdf,0xf7,0x61,0xb0,0xf4,0xbd,0x11, + 0x4b,0x3e,0xf4,0x82,0x60,0xdf,0x06,0x51,0x39,0x97,0x3d,0x55,0x77,0xf7,0x04,0x74, + 0x2d,0x99,0xc5,0xc1,0xbb,0x32,0x4a,0x56,0x06,0x2b,0xcc,0x19,0xb7,0x96,0x14,0x56, + 0x2c,0x34,0xec,0x96,0x55,0x08,0x83,0x0c,0x43,0xbb,0x9c,0xb2,0x24,0xfa,0xc2,0x21, + 0x66,0x3b,0x85,0xb4,0x3a,0x30,0x8a,0x90,0x8c,0x55,0x31,0x62,0xb5,0xd6,0x55,0x29, + 0x0b,0x9a,0x8f,0x55,0x46,0x31,0x3d,0xcc,0xef,0xbb,0x42,0xa5,0xf9,0x7d,0x1e,0x70, + 0x80,0x95,0x62,0xd0,0x32,0xa6,0x95,0xad,0xc0,0xbd,0x25,0xcc,0x3d,0xd8,0x9a,0xf8, + 0xd2,0xd8,0x3b,0x1a,0x15,0x6b,0x64,0xf2,0x15,0x76,0x9e,0x3b,0xf8,0x7b,0x58,0xac, + 0x0d,0x45,0xda,0x70,0xdf,0x3d,0x0f,0x9a,0x4d,0x45,0xcf,0xcd,0xbd,0xba,0x11,0x2f, + 0x4d,0x64,0x97,0x67,0xbd,0x4a,0x9f,0xc9,0x8f,0x1c,0xdf,0xbd,0xb4,0xf6,0x19,0xed, + 0x8f,0x43,0xe6,0x8e,0x4e,0xfe,0x5e,0x28,0xba,0x7f,0x72,0xc9,0xdd,0x48,0xbe,0x8a, + 0x29,0x9f,0x5a,0xbc,0xd4,0xf9,0x59,0x52,0x86,0xae,0xb4,0xeb,0xfd,0xb5,0xd3,0xa9, + 0x51,0x98,0xf7,0x66,0x1f,0xa1,0xd0,0x5f,0x3e,0x3d,0x57,0xf5,0x72,0xf3,0xf3,0xdf, + 0x8c,0x0b,0xce,0xd8,0x30,0x39,0x21,0x19,0xeb,0x5a,0x67,0x1d,0xdb,0xff,0x2f,0x7f, + 0xd9,0x9c,0x08,0x06,0xb1,0xaa,0x06,0x15,0x46,0x41,0x27,0x08,0x74,0x94,0xf1,0xd7, + 0xf8,0x87,0xc2,0xea,0xb2,0x27,0xd8,0x10,0x5a,0x4c,0xa0,0x64,0x53,0x6e,0xba,0x5b, + 0x61,0x7d,0x5e,0xe7,0x3c,0x2f,0x51,0x43,0xe1,0x31,0x82,0xa7,0x50,0xca,0x09,0x6b, + 0x43,0x43,0x81,0x90,0x30,0xa9,0x01,0x25,0xc7,0x42,0xa3,0xb7,0x59,0xbb,0xc1,0xb3, + 0xe2,0x48,0x6b,0xc1,0x81,0x1b,0xa6,0xa0,0x52,0x06,0xd8,0x71,0x61,0x81,0xe3,0xb8, + 0x47,0x69,0x08,0xb5,0x1f,0x19,0xec,0x0b,0xe0,0xb5,0x20,0x69,0xad,0xb5,0x20,0x3a, + 0x57,0x9b,0xbe,0x1a,0x27,0xda,0x5e,0x63,0x33,0x49,0xee,0x83,0xc2,0x9b,0x9d,0x0f, + 0xad,0xdb,0x76,0x1e,0x95,0x26,0xe6,0x01,0x97,0x4c,0x2c,0x51,0x0f,0xa4,0x0a,0x81, + 0xe9,0xb9,0x75,0xee,0xb9,0xa2,0x5f,0x4a,0x0a,0x47,0xea,0xae,0xd8,0x00,0x6a,0xaf, + 0xe8,0x4b,0x77,0xfe,0xb8,0xa3,0xda,0x19,0x33,0x25,0xa3,0xc0,0x55,0x2b,0xfc,0x73, + 0xea,0xd5,0x6c,0xef,0x39,0xa0,0x2d,0xfd,0x8a,0x95,0xad,0x15,0x7b,0x91,0x41,0x27, + 0x8f,0xbb,0xf4,0xff,0x1b,0x03,0xf8,0xf9,0x81,0x09,0x06,0x66,0xdf,0x92,0x2b,0xa3, + 0xe1,0xb8,0x8e,0xc8,0x3a,0x8d,0xe3,0x4c,0x21,0xfd,0x8c,0xd9,0x52,0x6a,0xca,0x9e, + 0x99,0x0e,0x0e,0x02,0x15,0x33,0x04,0x45,0x95,0xe6,0x5d,0x83,0xb2,0xae,0xe0,0x53, + 0xe1,0x7a,0x9a,0x58,0x4f,0x42,0x77,0x98,0xbe,0x42,0xf3,0xa9,0x7b,0xe4,0xa8,0xa2, + 0x62,0xa8,0xb6,0xb2,0x6a,0x6d,0x0b,0xab,0x22,0x85,0x77,0xe2,0xd8,0xcf,0xc4,0x99, + 0xeb,0xed,0xbe,0x28,0xdb,0x54,0x94,0xcc,0xdf,0xf0,0xb4,0xe1,0xd1,0x79,0xf5,0x68, + 0x29,0xaa,0x8c,0x6d,0x3d,0x73,0x0c,0x24,0x76,0x1f,0x18,0x30,0x4c,0xcd,0x90,0x6e, + 0x55,0x41,0x45,0xd0,0x94,0xa9,0x83,0xa0,0xc3,0x13,0x10,0x58,0x41,0xa9,0x0d,0x13, + 0x4f,0x5e,0x8a,0x46,0x65,0x02,0xdf,0x59,0xe7,0x1e,0x9b,0x8c,0x71,0x6e,0x3f,0xe7, + 0x83,0xab,0x3c,0xcc,0x95,0x24,0xc3,0xdb,0x16,0xc1,0xe9,0x60,0x70,0x1d,0xb1,0x3c, + 0x23,0xa8,0xf2,0xac,0x4f,0x77,0x62,0x54,0x65,0x86,0x96,0x95,0xbb,0x0f,0x1c,0x4f, + 0x07,0xc9,0x3d,0xcd,0x15,0xc9,0x42,0x65,0xbd,0xcd,0xb5,0x52,0x0b,0x34,0xd8,0x2a, + 0x16,0x84,0xc2,0xe9,0x12,0x88,0x16,0xc0,0xc1,0xf8,0xa5,0x71,0xb0,0xec,0x3e,0x77, + 0x5f,0x18,0x21,0xa0,0x3e,0xf0,0x64,0xa9,0x2e,0x43,0xf6,0xae,0x75,0xf3,0x0e,0x1c, + 0x71,0xb7,0x8c,0x6f,0xbd,0xb4,0x1a,0x3c,0x4c,0xf8,0x90,0xde,0x3a,0x84,0xc7,0x59, + 0x06,0x81,0x3d,0x72,0x05,0xbb,0x87,0xcf,0x13,0xa1,0x68,0x4f,0x7a,0x7e,0xb0,0xb4, + 0x16,0xc6,0x5e,0x19,0xf4,0xfb,0xc0,0x73,0x9e,0x6b,0xe7,0x7a,0xdd,0x15,0x3d,0x4c, + 0x73,0x18,0x9d,0xcc,0xb7,0x27,0x06,0x96,0x00,0xad,0x16,0x3c,0x69,0xd1,0xb3,0x1f, + 0x2d,0xa5,0xee,0x2f,0x98,0x2f,0x97,0xc9,0x1f,0xf2,0x1e,0x2c,0x0c,0x7b,0x7f,0x27, + 0x06,0x13,0xf1,0xab,0x60,0xb5,0x29,0xd4,0xec,0x8d,0x05,0xfe,0x94,0x71,0xb9,0x99, + 0xe9,0xc2,0x77,0xad,0x3b,0x99,0xcc,0x87,0x81,0xee,0x29,0x8e,0xff,0x7d,0x4e,0x6d, + 0x78,0xff,0x04,0x64,0x57,0x5d,0x24,0x9b,0x04,0xcf,0xb5,0xdb,0xe5,0x3b,0xa8,0xeb, + 0x05,0xef,0x0f,0x3e,0x88,0x1c,0x3e,0xb6,0x6d,0xf9,0x78,0xd6,0xcb,0xa3,0x98,0xbf, + 0x33,0x19,0xd9,0x23,0x40,0x43,0xf1,0x02,0xdd,0xcb,0x35,0xa3,0xe9,0x5e,0x16,0x81, + 0x85,0x1e,0x04,0x59,0x64,0xff,0x7b,0xd1,0x2c,0x69,0xe5,0xa5,0x3c,0x72,0x6e,0xf0, + 0x25,0x44,0xf0,0x68,0x10,0xa5,0x62,0x9c,0xad,0x87,0xca,0x95,0x30,0xe0,0x48,0x42, + 0xb3,0x52,0x44,0xd3,0xc2,0xc7,0x2c,0x35,0x8d,0x6f,0xc0,0xa6,0x0b,0x1a,0x3b,0x19, + 0x31,0xf9,0xf7,0xaf,0xda,0x7a,0x4b,0x90,0xec,0x6b,0xf6,0xe5,0x56,0xac,0xdc,0xec, + 0x5a,0xfa,0x80,0xbc,0x6c,0x5b,0x31,0xdb,0x2e,0x16,0x55,0x04,0xb1,0x11,0x40,0x0b, + 0x0d,0xba,0x62,0x5a,0xf9,0x57,0x70,0xd4,0x4a,0xe9,0xc0,0x2a,0x58,0x84,0x78,0xe5, + 0x8f,0x6e,0x6a,0x4b,0x39,0xd4,0x3c,0xbe,0x65,0x63,0x84,0x07,0xd0,0x6f,0x19,0x32, + 0x73,0x17,0x06,0x09,0x08,0xce,0x7d,0x6c,0x1a,0xc0,0x23,0x5d,0x37,0x5b,0x97,0x9f, + 0xce,0x5e,0xb9,0x0f,0x76,0xef,0x39,0xd9,0x31,0x2a,0xf9,0xff,0x5a,0xed,0xcd,0x14, + 0xbb,0x50,0x5f,0x11,0x18,0x8d,0x60,0x7a,0xb1,0x41,0x8c,0xda,0xdc,0x0b,0xfa,0x28, + 0xf0,0x70,0xfe,0x6a,0x3b,0x20,0x72,0x7a,0x87,0x8e,0xdc,0xa6,0xfc,0xaf,0x0b,0x89, + 0x08,0x7b,0x67,0xb4,0x27,0xec,0x25,0x52,0x39,0x65,0xce,0xeb,0x9d,0xc7,0xab,0x02, + 0xe1,0x82,0xb2,0x6d,0x38,0xbf,0x77,0x54,0xed,0x9a,0xb1,0x87,0x5d,0x08,0xf5,0x7c, + 0xf9,0xed,0x01,0x80,0xa0,0xd4,0xf4,0xde,0xfc,0xd6,0xf4,0x99,0x7c,0x9c,0xc4,0xf0, + 0x44,0xb1,0x09,0x90,0xa1,0xd5,0x44,0x30,0x60,0xbb,0x1b,0x21,0x1e,0x57,0x8a,0xa7, + 0x26,0x75,0x9d,0x78,0x18,0xbf,0x3d,0x14,0x87,0xf2,0x9d,0x65,0x20,0x34,0x75,0x5a, + 0x4e,0x72,0x19,0xb0,0x68,0xbc,0x05,0x63,0x12,0xdc,0x3d,0x46,0x37,0xb3,0x1b,0x05, + 0x9b,0x22,0x9c,0x06,0x3c,0xa4,0x0a,0xdb,0x2e,0xf7,0x68,0x64,0xab,0xfb,0x76,0xd0, + 0xb5,0x9d,0xad,0xb0,0x04,0xa0,0x6c,0x7a,0x54,0x35,0x53,0x04,0x14,0x6b,0x3f,0xc1, + 0x15,0xcb,0x5d,0x2f,0x5a,0xf9,0x55,0xa0,0xc2,0x94,0xaf,0xe6,0x55,0xf0,0xae,0x95, + 0xc5,0xdb,0x15,0x3f,0x57,0x2a,0xd6,0xb4,0xe9,0x0b,0x85,0x75,0x2a,0x88,0x18,0xbf, + 0xa1,0x3e,0x12,0xf1,0x9f,0xcc,0x56,0xee,0x4d,0x55,0x8c,0x5d,0xaa,0x57,0xb8,0xab, + 0x8c,0x38,0x38,0x7c,0x91,0x14,0xb6,0x76,0xce,0xdf,0xc0,0x24,0x96,0x3c,0x28,0x4b, + 0xaf,0x37,0x07,0x81,0x30,0x17,0x4f,0x8c,0x4f,0xdc,0x50,0x5e,0x26,0xea,0x17,0x64, + 0xce,0xf6,0xbe,0x7d,0x49,0x8a,0xb7,0x6f,0x4e,0xdd,0xc1,0x88,0x96,0x5e,0xb6,0xc8, + 0x3c,0x61,0x1e,0xc6,0xbe,0xbe,0xb2,0x20,0xd5,0x83,0x49,0x0c,0xda,0x0d,0x15,0xfd, + 0x8e,0x22,0x02,0xa5,0xa1,0x36,0xbe,0xda,0x4b,0xc6,0x2a,0x2e,0xfe,0x45,0xa7,0x92, + 0xc0,0x93,0xbe,0xf8,0x1b,0xc1,0x29,0x09,0xea,0x43,0xcd,0x4a,0x3f,0x9d,0xc3,0xb4, + 0xa9,0x27,0xcf,0x35,0xce,0xa9,0xf9,0xa5,0x62,0xbd,0x00,0xd9,0xdd,0x72,0xd4,0x52, + 0x2e,0x8a,0xd0,0xfa,0x1c,0x8b,0x90,0xe7,0x64,0x2c,0xee,0x22,0xb1,0xe3,0xf1,0xf2, + 0x83,0xfd,0x48,0xe5,0xae,0x83,0x42,0xcf,0xaa,0x90,0x7c,0xca,0x32,0x41,0x39,0x5c, + 0x02,0xfe,0x7c,0x15,0xfb,0x5d,0x81,0xd0,0xb8,0x62,0x00,0xd6,0x5c,0xef,0x74,0x62, + 0x98,0x0c,0xd7,0xfa,0xc5,0x20,0x67,0x0c,0x43,0x84,0x7d,0x2b,0xed,0xcc,0x95,0x2f, + 0x6a,0x09,0xbe,0x42,0xf3,0xa7,0xd0,0xbc,0x44,0x5f,0x7c,0x26,0xd1,0xb0,0x36,0x56, + 0xe2,0x86,0x57,0xb4,0x73,0xd8,0x42,0x37,0x9d,0x4f,0xa6,0xe7,0x38,0xe3,0x57,0x23, + 0xe2,0x48,0xe1,0xb6,0x1e,0x2b,0x41,0x07,0x3d,0xeb,0x33,0x7a,0x1c,0xeb,0xbd,0xa2, + 0x0f,0x47,0x5a,0xab,0xcb,0x90,0xdf,0x8d,0x25,0xbc,0x59,0x2b,0x22,0xbb,0x62,0x57, + 0xbb,0xa5,0xfb,0xf7,0x73,0x57,0xb0,0x4a,0x23,0x47,0x81,0x5e,0xa3,0xc5,0xf0,0x6b, + 0x14,0x06,0xd4,0xf3,0x3b,0x2a,0x6c,0x37,0xe8,0xb8,0xa8,0xc3,0xa0,0x05,0x8a,0xeb, + 0x0a,0xf6,0xc0,0xfc,0x27,0x4a,0x94,0x1b,0x37,0x4c,0x8d,0xdc,0x7b,0x2a,0xbf,0x6a, + 0xd8,0x04,0xf2,0xe6,0x6d,0xf4,0x09,0xdb,0x22,0xda,0x7c,0x4e,0x7a,0xe2,0x02,0x2d, + 0xde,0xe4,0xc4,0x23,0x98,0x28,0x15,0xec,0x7b,0x2f,0x7d,0x17,0x87,0xb8,0x4c,0xb0, + 0x83,0xc0,0x08,0x23,0x96,0xab,0x4e,0x1e,0xb4,0xe0,0xbd,0x8d,0x89,0x2d,0xe4,0x01, + 0xaa,0xff,0xd5,0x2f,0xee,0x25,0x03,0x70,0xc0,0x55,0x30,0x72,0x04,0xc1,0x6b,0x51, + 0xb8,0x4b,0x1b,0x1d,0x99,0xd2,0x41,0x3e,0x15,0x45,0x70,0x13,0x0e,0x93,0x3c,0x7f, + 0xad,0xa6,0xf3,0x6c,0xd2,0x72,0x72,0x9c,0x63,0x90,0x93,0xa6,0xf3,0x31,0xcc,0xe9, + 0xf8,0x7f,0xc8,0x10,0x47,0x69,0x39,0x89,0x79,0x55,0x23,0xef,0x1a,0x7e,0xbe,0x1b, + 0xa3,0x30,0x56,0xfd,0x92,0xe2,0xb6,0x9d,0x3c,0xa3,0x38,0xde,0x6d,0xce,0xb2,0x03, + 0xb2,0xce,0x4d,0xe0,0xb0,0xce,0xa5,0xc2,0x99,0xcc,0x1d,0xce,0xf7,0x72,0x3e,0xa0, + 0x3c,0x9f,0xdc,0x60,0xbf,0xb2,0x44,0x41,0xc3,0x6d,0x63,0xc0,0xfd,0x76,0x90,0xb2, + 0xd4,0x28,0xcc,0xd6,0x73,0x88,0x5a,0x40,0x00,0xdb,0xb4,0xea,0xb5,0x81,0x0e,0xfc, + 0xa4,0x1c,0xc7,0x05,0xf2,0xad,0x0d,0xc4,0x5e,0xd5,0x62,0xe4,0x7f,0x7a,0x5f,0xd1, + 0x1c,0x9a,0xdf,0x2f,0x40,0xaa,0xc8,0x75,0xc3,0x55,0x3b,0x04,0x39,0x37,0x64,0x8c, + 0x29,0xb8,0x9c,0x8d,0x6d,0x31,0x28,0x94,0x97,0xc5,0x06,0x44,0x34,0xa4,0x9e,0x70, + 0xd7,0x54,0xc3,0x9b,0x3f,0x71,0xa9,0xb9,0xe4,0x55,0xf7,0x57,0x86,0x3b,0x17,0x04, + 0xac,0x74,0x81,0x70,0xb4,0x78,0xec,0x8d,0x67,0x58,0x3b,0x28,0x2d,0x18,0xf4,0x91, + 0x0c,0xe4,0x6d,0x19,0xc4,0x08,0x77,0xa7,0x1e,0xaf,0x8f,0x40,0x04,0x39,0x14,0x6c, + 0xb6,0x58,0x02,0x49,0x34,0xb6,0x6d,0x0a,0x6c,0x5d,0x88,0x7e,0x7e,0x80,0x08,0x91, + 0x73,0xed,0x08,0x26,0xb6,0xbb,0x66,0x17,0xe6,0xab,0xde,0xe3,0xa5,0xd6,0x39,0xce, + 0x5f,0x11,0x00,0x36,0x98,0x5d,0x86,0x8b,0x5d,0x3b,0xe8,0xb2,0x91,0xa8,0x6f,0x1f, + 0x8f,0x1c,0xc8,0x1d,0xb3,0xaf,0xe6,0x67,0xe8,0x6f,0xb8,0xf0,0x1a,0xd0,0x40,0x42, + 0xb9,0x0b,0x17,0xf9,0x97,0xae,0x60,0x3b,0x50,0xdb,0x90,0xcc,0x37,0xe4,0x57,0x90, + 0x04,0x7e,0x8f,0x60,0x34,0x99,0x06,0x0a,0x9b,0x6e,0xab,0x0f,0xbe,0xa5,0x25,0xe1, + 0xa6,0x7d,0x41,0x38,0xb0,0xb9,0x27,0x45,0x3b,0xae,0xd0,0xe7,0x86,0x4f,0x11,0x33, + 0x24,0xbc,0x45,0x85,0xd9,0xab,0x2a,0xda,0xcd,0xfe,0x83,0x86,0xe9,0x4c,0xda,0x05, + 0x35,0xa0,0x0c,0xd4,0x25,0xae,0xf6,0x9e,0xa0,0x3f,0x4d,0x39,0x82,0x21,0x10,0x60, + 0xfc,0x70,0x10,0xad,0x68,0x85,0xe8,0x39,0xba,0xf9,0xa6,0x44,0x53,0xa9,0x83,0xd3, + 0x4e,0x2f,0x60,0xaf,0xb2,0x5b,0xa5,0xe7,0xf7,0xa5,0x56,0x50,0x3d,0x43,0x73,0x40, + 0xee,0xbf,0x69,0x33,0xff,0x5c,0x23,0x8c,0x38,0x18,0x98,0x64,0xd6,0x73,0xfd,0x0a, + 0x28,0x93,0x22,0x9a,0x38,0x73,0x9e,0xb9,0x3c,0xc2,0x16,0x5c,0xd2,0x17,0x92,0xe1, + 0x8f,0x6e,0x31,0x2c,0x6a,0x8d,0xfa,0x52,0x4d,0xa5,0x1a,0x4c,0x3f,0xdf,0xd3,0x6d, + 0x7f,0x9a,0x87,0xf2,0x1d,0xe8,0x72,0x74,0x75,0x36,0xe9,0xaf,0xa4,0x45,0xd3,0x79, + 0x7a,0xee,0x74,0x5d,0x9b,0x83,0x84,0xa8,0xb1,0x16,0xc5,0x38,0x20,0xe4,0x5c,0x03, + 0x2f,0xdd,0xe0,0xca,0x05,0xc8,0x45,0x33,0xaf,0x53,0xd4,0x2f,0x86,0x47,0xca,0x28, + 0x65,0x65,0xb0,0xd2,0x6b,0xef,0x1c,0x23,0x4c,0xce,0xaa,0xe0,0xa4,0x16,0x5d,0x03, + 0xf6,0x21,0xc3,0xf0,0x7f,0x71,0x0d,0xdb,0x3f,0xa2,0x56,0x6a,0x59,0xf8,0x15,0x5c, + 0x2e,0xb0,0xe4,0x44,0x3e,0x10,0x21,0xe6,0xbf,0x8d,0xfb,0xbd,0x5c,0xa9,0x44,0x35, + 0x83,0x9d,0xf4,0xa7,0x36,0xb1,0xcb,0x53,0xdb,0xe3,0xa4,0x8c,0x72,0xf1,0xec,0xeb, + 0xfc,0xfd,0x2a,0x7e,0x06,0x7a,0xc1,0xa2,0x0e,0xae,0x10,0x33,0xa0,0x93,0x5e,0xa4, + 0x05,0x2d,0xb7,0x9e,0x96,0xc0,0x65,0x5d,0xe8,0x79,0xa3,0x4f,0xb8,0x2e,0x92,0x01, + 0xd5,0x4e,0xad,0x9f,0xd2,0x93,0xfd,0x42,0x5a,0x71,0xd4,0x5c,0x0a,0xb1,0x22,0xe3, + 0x51,0x53,0xdb,0xa6,0x3e,0x06,0xdf,0x8c,0xb3,0x28,0x97,0xb8,0xc3,0x28,0xd4,0xe2, + 0xd8,0xd3,0x69,0xa9,0xb8,0x23,0x53,0xea,0xe7,0x89,0x4e,0xe9,0x9b,0x5e,0xba,0x5a, + 0x95,0x04,0x5a,0x80,0x6c,0xbe,0xc8,0xbc,0x3f,0x4b,0x5a,0x88,0x2b,0x22,0xfa,0x57, + 0xf0,0xd5,0xa5,0xc3,0x37,0xa7,0xd2,0x88,0x3a,0x96,0xcb,0xf5,0x9c,0x72,0x44,0x8b, + 0x2f,0x68,0x0e,0xae,0x18,0xf6,0x68,0x45,0x3c,0xdb,0xa6,0xa0,0x81,0xf7,0x2a,0x5a, + 0x69,0x82,0xbc,0x65,0xb0,0xdb,0xff,0xa0,0x9a,0x6d,0x86,0x8e,0xed,0xbb,0x7e,0x67, + 0x49,0x1c,0xb7,0xab,0x55,0x13,0x4e,0x50,0x87,0xa5,0x88,0x9e,0x5d,0x5b,0xe3,0xfd, + 0x4f,0xbb,0xb9,0xfd,0xdd,0xdf,0xc0,0x4a,0x52,0xe8,0xaf,0x67,0xfb,0xf9,0x36,0xd3, + 0x44,0x47,0x59,0xb7,0x1f,0x3c,0x2f,0xce,0x0d,0xc4,0xf4,0xa8,0xec,0x58,0x2d,0xbc, + 0x4e,0xbd,0x41,0xa0,0xe2,0xfc,0x46,0x05,0x98,0x66,0xd9,0x0f,0xe3,0x3d,0x95,0x36, + 0x80,0x85,0x64,0x71,0xfe,0xb2,0x8f,0x69,0x6e,0xdf,0x27,0xf5,0x36,0x9d,0x7d,0x24, + 0x29,0x6e,0x03,0x5f,0x43,0x9f,0x7b,0x0b,0xcf,0x6e,0x17,0x75,0xdd,0x29,0x7f,0xfd, + 0x00,0x0e,0xe0,0x40,0x2d,0x2f,0xcd,0x46,0xb3,0x50,0x5a,0xdf,0x23,0x60,0x58,0x19, + 0x08,0x07,0x77,0x53,0xd3,0x11,0xab,0x50,0x47,0x8b,0x25,0x6b,0x57,0xd1,0x69,0x87, + 0x7c,0x43,0xe1,0x07,0x58,0x2f,0xa9,0xda,0x3c,0x6b,0x3a,0x4b,0x05,0x9e,0xfb,0x08, + 0x20,0xbc,0x81,0x01,0x6c,0x4d,0x39,0x2f,0xe0,0xb7,0xf7,0x6a,0x28,0x9f,0xbf,0x2e, + 0x74,0xdb,0x0c,0x22,0x33,0xa4,0xfc,0x44,0xc5,0x94,0x70,0x16,0x30,0x60,0xe4,0xcb, + 0xd6,0x0f,0x91,0x77,0xb6,0xa9,0x60,0x8f,0x59,0x28,0xc0,0x70,0xde,0x24,0x81,0x91, + 0x26,0xf9,0xfb,0xad,0x2a,0x69,0x0c,0x32,0x6f,0xe7,0xaf,0x62,0x73,0xbf,0x4b,0x2e, + 0x56,0x03,0x83,0x48,0x6c,0x3c,0x99,0xcd,0xab,0x4a,0x66,0x95,0x72,0xbc,0x1a,0xa4, + 0x3b,0x8a,0xe0,0xe6,0x19,0xe8,0x0e,0x0c,0xc7,0x4a,0x2d,0xeb,0x92,0x22,0xad,0xfa, + 0xe9,0xad,0x1d,0xfe,0x3d,0x65,0x72,0x47,0x29,0x09,0x0a,0x43,0xd4,0xcf,0xbb,0xf6, + 0x61,0xc0,0xe3,0x49,0xa5,0x27,0xa4,0x28,0x45,0x46,0x9b,0x28,0x04,0x20,0x73,0x34, + 0x62,0x9a,0xe5,0x77,0xbb,0xc6,0x65,0xae,0x28,0x98,0xd7,0xfd,0xdd,0x9f,0xc2,0x33, + 0xdf,0xf0,0xf7,0x2a,0x97,0xda,0x2c,0x15,0xe6,0x41,0xf2,0x91,0x78,0xd7,0x5c,0x95, + 0xe0,0x77,0x72,0xa3,0x28,0x18,0xd6,0x88,0xb4,0x42,0xd2,0x03,0x0e,0x64,0xf8,0x16, + 0x63,0x8d,0x8b,0x54,0xa9,0x7a,0x2d,0x89,0x48,0x4a,0xd1,0x97,0xdc,0x87,0x75,0xe8, + 0xe3,0x95,0x73,0x60,0x3c,0xa2,0x3b,0x7b,0x82,0x42,0x5b,0x3a,0xff,0x01,0x6e,0xaf, + 0x50,0x45,0xbe,0x0a,0x87,0xbd,0x26,0xa4,0xe5,0x46,0xea,0xa2,0x91,0xf3,0xaa,0x14, + 0x00,0x57,0xf5,0x96,0x3d,0x73,0x42,0xbf,0x65,0x1f,0x84,0xa5,0x8d,0x90,0x90,0x78, + 0x21,0x89,0xe0,0x6e,0x51,0x24,0xb4,0xbb,0x7c,0xe6,0x72,0x56,0x7c,0x7f,0x9d,0x13, + 0x21,0xab,0x0a,0xe1,0x93,0x9d,0x7c,0x11,0x37,0xec,0x5d,0xd9,0x4e,0xd3,0x40,0x22, + 0xa0,0x5c,0x6f,0x9b,0xcb,0xc8,0xed,0xbe,0xbf,0x29,0xf3,0x15,0xee,0x66,0xc4,0xb9, + 0x80,0x70,0x92,0xe7,0x3f,0x9e,0xea,0x03,0x8b,0xfe,0xa3,0xbe,0xce,0x69,0x5e,0xb3, + 0x01,0x10,0x66,0xf3,0x6e,0xd3,0xfa,0xff,0x06,0xa2,0x3d,0x6f,0xd0,0xa0,0x35,0x53, + 0xa6,0x7d,0xff,0xd4,0x36,0x21,0x6f,0xf5,0x66,0x41,0x6f,0x47,0xe3,0xb2,0x3e,0xda, + 0x6b,0x78,0x81,0xfe,0xb5,0xce,0xc9,0xa8,0xeb,0x56,0x00,0xae,0xd1,0x7e,0x4c,0x1a, + 0xc7,0x54,0xb4,0x07,0xc2,0xb4,0xa1,0xe3,0x90,0xd3,0xe6,0x54,0x46,0xb4,0xeb,0x1b, + 0xac,0x10,0x78,0xff,0x6e,0xe5,0xf7,0x96,0xcc,0xe6,0x65,0x25,0x9b,0x85,0x55,0x0c, + 0x0a,0x7e,0xec,0x67,0x9d,0x47,0x9b,0x48,0x4a,0x59,0x87,0xac,0x10,0xa1,0x7e,0x18, + 0xdd,0x13,0x67,0xd6,0xa6,0x88,0x70,0x51,0xba,0xf8,0xa0,0xc6,0x08,0xb9,0xe1,0xa6, + 0xf6,0x5f,0xaf,0x7c,0xed,0x82,0xda,0x3e,0xf9,0x5e,0x01,0xfc,0xf8,0x73,0x7f,0x19, + 0x51,0x11,0x99,0xc2,0xbe,0x70,0x84,0xf2,0x81,0x2a,0xe4,0xe5,0x1e,0xcb,0x57,0x0e, + 0x29,0x17,0x10,0xdd,0x38,0x31,0xbc,0x02,0x94,0x5f,0x3f,0xc2,0xdf,0x11,0xf9,0x9d, + 0x3b,0x0e,0x27,0xa0,0xdf,0x2d,0x4e,0xb4,0x2f,0x66,0xfc,0x02,0x23,0xe0,0xfc,0xef, + 0x84,0x5a,0x49,0xf8,0xf4,0x97,0x02,0xc1,0x93,0x6e,0x65,0x37,0x62,0xe4,0x07,0x2e, + 0xa2,0x2d,0x0d,0x88,0x2b,0x2f,0xb1,0xd2,0x06,0x42,0x6e,0x3a,0xaf,0xe2,0x8f,0x97, + 0xda,0xcf,0xd4,0x65,0x07,0xbc,0xde,0xc2,0x1f,0xd3,0xe4,0xde,0xd3,0xe1,0x1e,0x9a, + 0x02,0xfe,0xb9,0x7c,0xb1,0xe5,0x3a,0x1d,0xe5,0xaa,0x60,0xa1,0x54,0x11,0xd7,0xc2, + 0x26,0xb5,0x44,0x14,0x94,0x71,0x7c,0x35,0xc6,0xcb,0x5b,0xe0,0x8b,0x03,0xc2,0x1d, + 0x7f,0x5a,0x0d,0xc7,0x6a,0x86,0xe1,0xa4,0xc4,0x33,0xf5,0x20,0x57,0xe8,0x6b,0xb3, + 0xed,0x81,0x0b,0x48,0x59,0x2a,0xda,0xe5,0x1b,0x21,0xc3,0x84,0x1d,0x4c,0xf9,0x95, + 0x73,0x06,0x99,0xae,0xf1,0x4a,0x4c,0xb0,0x99,0x55,0x81,0x5c,0xb7,0x09,0x75,0x0f, + 0x0b,0xb0,0xe6,0x9a,0x41,0x60,0x99,0x0c,0x91,0x2c,0x67,0xa8,0x5e,0x0b,0x96,0x33, + 0x38,0xfb,0x53,0xdc,0x9a,0x83,0x98,0x74,0x35,0x36,0x8d,0x1a,0x51,0xf1,0x8e,0xe7, + 0x53,0x70,0x91,0x58,0x03,0xd4,0x65,0x08,0xc9,0x60,0xe1,0x58,0xb5,0x0a,0x6a,0xef, + 0xef,0x83,0x9c,0xdd,0x75,0x2a,0x48,0x99,0x84,0x67,0x90,0x6a,0xb5,0x29,0x52,0x8a, + 0xd0,0x82,0x0d,0xaf,0xc5,0xbd,0x5d,0xe5,0x24,0x7b,0xfb,0x8d,0xbf,0xa1,0xf3,0xc9, + 0x8b,0xe4,0x63,0xbc,0x48,0x01,0x11,0x6f,0x1e,0x18,0x8d,0x58,0xb5,0x4b,0x0b,0x1f, + 0xa0,0x04,0x95,0xc5,0x4a,0x32,0x7a,0x88,0x1d,0x13,0x9a,0x65,0x0f,0x5b,0x7e,0x0b, + 0x87,0xf5,0x1b,0xc9,0xa1,0x6d,0x06,0x5d,0xe6,0x98,0x18,0x23,0xd7,0xb1,0xda,0x71, + 0x46,0x13,0xf7,0x96,0x33,0x01,0x04,0x62,0xb8,0xae,0x19,0x07,0x8d,0x6b,0x7f,0x1b, + 0x07,0x94,0x0c,0xf4,0xf3,0x0d,0x15,0xc1,0x53,0xb7,0x12,0x02,0x2c,0x71,0x55,0x7b, + 0x9e,0xde,0xc3,0xe8,0x3a,0x15,0x84,0xe2,0x46,0x0c,0x0a,0x7a,0xf3,0xd8,0xb0,0x32, + 0x2e,0x9b,0x04,0xf9,0x12,0xb2,0x1c,0x20,0xe0,0x21,0xb4,0xd9,0x7e,0x98,0x30,0x89, + 0xda,0x1c,0x5d,0xb6,0x33,0xd9,0x25,0xe4,0xc2,0xdc,0x5b,0x61,0x96,0x5a,0xf5,0xdc, + 0x9a,0xd4,0xc5,0x77,0x17,0x3f,0xe5,0x43,0x8c,0xa5,0xdd,0x25,0x22,0x30,0x69,0x8f, + 0x86,0xd5,0x7d,0x2a,0xa7,0x45,0xfb,0x1b,0x8c,0x9a,0x9b,0x06,0x35,0xb7,0x5d,0x82, + 0x89,0x27,0xec,0xce,0x7c,0x4c,0x8b,0xf7,0x93,0xde,0x7b,0x2a,0x3f,0xbd,0xee,0x4e, + 0xad,0x4d,0x02,0x0d,0x32,0xb3,0x8a,0xc5,0xce,0x64,0x6a,0x51,0x53,0x5f,0x90,0x56, + 0x58,0x40,0xed,0x8d,0xac,0x47,0xbf,0xa9,0x19,0xd5,0x1b,0x2a,0x07,0x57,0xe4,0x84, + 0xf2,0x80,0x2f,0x80,0xb2,0x16,0xfb,0x3e,0xae,0x28,0x87,0x51,0x40,0x0a,0x58,0xe7, + 0x0f,0x3c,0xbc,0x66,0x42,0x13,0x7c,0xee,0xc9,0x9d,0x88,0x70,0x95,0x0a,0xca,0x9c, + 0x7b,0x10,0x90,0xd9,0x9e,0x62,0x01,0x1c,0x5c,0x86,0x9d,0xa0,0x8e,0x21,0xb8,0xcf, + 0xa8,0xa4,0x47,0xbd,0xdc,0xba,0x2e,0x1a,0x4b,0x54,0xa9,0x74,0xee,0x51,0x11,0xa6, + 0x44,0x94,0xb5,0x7f,0xc3,0x10,0xc5,0x1b,0xa7,0xc4,0x50,0x84,0x22,0x2b,0xb2,0x1f, + 0xec,0xaf,0xbf,0x81,0xeb,0xbd,0xcb,0x20,0x3f,0xd2,0x02,0x00,0xdf,0x62,0xa0,0x9a, + 0x95,0x95,0x18,0x4b,0xe8,0xdd,0xa9,0x56,0xa3,0x51,0xf0,0x2a,0x68,0x95,0x37,0xf0, + 0x60,0x42,0x99,0x00,0xef,0xdd,0xd1,0x38,0x00,0x59,0x26,0x24,0x5d,0x6e,0xac,0x0a, + 0xea,0x77,0x19,0xd2,0x93,0xd6,0x9d,0xf7,0xa3,0x02,0x00,0xb1,0xa8,0xfb,0x38,0x59, + 0xf8,0x54,0x3b,0x46,0x56,0xf8,0x68,0x8f,0xbf,0xe5,0x92,0x04,0x7a,0xe5,0x92,0x69, + 0x05,0x2f,0x67,0x70,0xc7,0xa6,0xe1,0x92,0xef,0x38,0x42,0xee,0xd3,0x17,0x3d,0x33, + 0x79,0x8d,0xfa,0x1b,0x4f,0x9b,0x69,0xe5,0xea,0xc2,0xd3,0x85,0xf2,0x24,0x9b,0x33, + 0x70,0xac,0x6e,0xe4,0x7a,0xed,0x21,0x81,0xf8,0xf6,0xc9,0x51,0xc1,0x25,0x82,0xce, + 0x9a,0x0b,0x86,0x4b,0x99,0x26,0x4b,0x06,0xed,0xc8,0x2d,0x4c,0xef,0xcc,0x62,0xda, + 0x8f,0xfc,0xac,0x1b,0xdf,0x8d,0x40,0xe9,0x71,0x56,0x3e,0x5e,0x7a,0x09,0xe0,0xf2, + 0xf7,0x0a,0x24,0x0b,0x4c,0x4e,0xeb,0x0d,0x29,0x75,0x0a,0x2b,0x10,0x53,0x9b,0x02, + 0xb1,0xf6,0x2b,0x8a,0x60,0xa7,0xa3,0x59,0xbd,0x09,0x77,0x3f,0xd1,0x07,0x3a,0x5d, + 0xea,0xd9,0xe5,0xae,0xfa,0x8d,0x92,0x48,0x60,0x41,0xcd,0x46,0xda,0x0e,0xe6,0xdd, + 0xde,0x6f,0x1e,0xa2,0xe6,0xac,0x23,0x06,0xec,0x0c,0x1e,0x57,0x5d,0xd7,0x3b,0xa1, + 0x86,0xd2,0xfb,0xb2,0x73,0x21,0xa8,0x99,0x81,0xbf,0x83,0x49,0xd8,0x2c,0x22,0xb2, + 0x74,0x84,0xda,0xae,0xf5,0xf2,0xf3,0x5d,0x4e,0xae,0x4d,0x7f,0xcb,0x2d,0x56,0x33, + 0x26,0x11,0xfb,0x79,0x30,0x3e,0xb4,0x9b,0xe4,0xcf,0xaf,0x63,0xba,0xfa,0x37,0x72, + 0x8d,0xac,0x4c,0xb4,0x23,0x2a,0x96,0x72,0x67,0xb9,0x56,0x56,0x91,0x2a,0x2c,0x05, + 0x88,0x96,0xed,0x03,0x4c,0x73,0xd5,0x68,0x84,0x10,0xdd,0x9c,0x01,0xd6,0x75,0x61, + 0x3d,0xe2,0x0b,0xcb,0x3c,0x51,0x9f,0xb8,0x5b,0xa3,0x9d,0x84,0xfa,0x8c,0x18,0xc5, + 0xf3,0xe9,0x28,0x44,0xce,0x14,0x6a,0x34,0x02,0x8b,0xe2,0xec,0x99,0xf1,0x8c,0xf1, + 0x75,0x18,0x2e,0xcb,0xfd,0x9e,0x24,0xc2,0x9c,0x4e,0x73,0x07,0xa3,0x81,0x6e,0x31, + 0x40,0xc7,0x69,0x87,0x31,0xe2,0xaa,0x92,0xa9,0xa2,0x7d,0x6f,0x2f,0xcb,0xb2,0x21, + 0x6f,0xc6,0xab,0xd1,0xd8,0xb1,0x77,0x82,0x40,0x18,0xfa,0x04,0x6f,0x65,0x7f,0xee, + 0xdf,0x93,0x2d,0x09,0xab,0x07,0xb8,0x8c,0x1f,0x58,0x2f,0x1d,0xdb,0xa7,0xf6,0xbc, + 0x0b,0xba,0x4e,0xbc,0xbd,0x34,0xa5,0x08,0x99,0x86,0xf8,0x78,0x7a,0xfb,0x49,0xb4, + 0x1b,0xc7,0x78,0x7d,0x8b,0xab,0x4d,0x58,0x94,0xa5,0x22,0x6c,0x45,0x14,0x5e,0xb9, + 0xcb,0xb8,0xf0,0x19,0x92,0x5b,0xb8,0xbf,0x02,0x3f,0xc5,0x95,0x85,0xd4,0x86,0xe8, + 0xf2,0x5e,0x46,0xbe,0xd1,0xf9,0x57,0x97,0xcd,0x1d,0x3e,0x66,0x58,0xaa,0x36,0xa2, + 0xc0,0x12,0x4f,0x2f,0xdb,0x71,0x64,0x40,0x80,0x39,0x29,0x3e,0xf8,0x3b,0x53,0xc8, + 0x15,0x4b,0xb9,0xfa,0xd1,0x9b,0xea,0xd0,0x01,0x1a,0xa8,0xd3,0x0c,0x8b,0x7d,0xf4, + 0x54,0xb2,0xae,0xc7,0x6b,0x8b,0xb3,0x86,0x21,0x1b,0x68,0xd9,0x98,0x64,0x7e,0xe0, + 0x40,0x05,0xea,0xe4,0x55,0xe0,0xba,0x3d,0x42,0x08,0x50,0x92,0x76,0x23,0x12,0xa2, + 0xe7,0xc3,0x28,0x08,0xf1,0x55,0xf8,0xfb,0x21,0xfc,0x9e,0x5f,0xd9,0x6a,0x33,0xc4, + 0x6f,0xc6,0xdf,0x94,0xff,0x24,0x6f,0x18,0x40,0x5d,0xb4,0x34,0xe1,0xa6,0x39,0x59, + 0x83,0xa2,0x1f,0xe6,0x7d,0xe3,0x2f,0x51,0xa5,0x50,0xbd,0xd5,0xd3,0xc8,0xba,0x7b, + 0x00,0xae,0xb2,0x70,0xfd,0x67,0xd8,0x56,0xc3,0x65,0xeb,0x12,0xd6,0x84,0x1f,0xc4, + 0xd4,0xc4,0x48,0xa6,0x9f,0x76,0xd2,0x94,0x74,0xc2,0xf8,0x52,0xd8,0xe7,0xb3,0x3c, + 0x25,0x36,0xbb,0x05,0xea,0x09,0xb1,0xdf,0x26,0xdd,0x31,0x87,0xa7,0x1d,0xc2,0x2c, + 0x52,0x0c,0x5e,0x51,0x60,0x0c,0x23,0x77,0x60,0xd7,0x4e,0x76,0x5a,0xeb,0xfb,0x70, + 0xaf,0xed,0xfc,0x3c,0x18,0xe4,0x4c,0x2c,0xad,0x4b,0x8e,0x08,0x3a,0x65,0x52,0x0e, + 0xed,0x08,0x8d,0xef,0x81,0xbb,0xfa,0x6e,0xce,0x8b,0x5a,0x01,0x79,0x55,0x1c,0xe9, + 0x71,0x21,0xc2,0x01,0x4c,0xde,0xc7,0xaf,0x81,0x0a,0x67,0xd0,0x5f,0xe4,0x3c,0xe8, + 0x09,0x06,0x43,0x95,0xbf,0x7d,0xb1,0xb0,0xcb,0x03,0x04,0x64,0x2d,0x81,0x54,0x76, + 0x08,0xad,0xea,0x4e,0xd6,0x66,0x28,0xa2,0xe9,0x41,0x9a,0x70,0x98,0x18,0x33,0x66, + 0x09,0x8c,0xb8,0x65,0x71,0x38,0xa1,0x0c,0x7c,0x19,0xa4,0xec,0x1f,0x42,0xa1,0x29, + 0x71,0x05,0xef,0x60,0xf4,0xfb,0x2a,0x64,0x29,0xd5,0x15,0x1d,0x35,0x48,0xcb,0x39, + 0x74,0xcd,0x39,0x5b,0xc0,0x34,0x81,0xff,0xb2,0xfc,0x49,0x8c,0x33,0x44,0xe4,0xdb, + 0x41,0x2f,0x0d,0xf9,0xa1,0xf2,0x0c,0xe5,0x6a,0x6f,0x14,0x56,0xcc,0x23,0x01,0xe9, + 0xbc,0xea,0xba,0x7e,0x79,0x6d,0x06,0x17,0x96,0x25,0x39,0xab,0x8b,0xf1,0x9e,0x33, + 0x68,0xcd,0xb5,0x46,0xb2,0xb3,0x81,0xc1,0x9c,0x6d,0xcb,0xa0,0x0d,0xfd,0x29,0xf8, + 0x24,0x9e,0x01,0x12,0x60,0xd1,0x9d,0xad,0x69,0xb6,0xb9,0xab,0x75,0x3e,0x1c,0x6e, + 0xd1,0xd5,0xc3,0x37,0xaa,0xa6,0xcf,0x71,0xea,0xdc,0x63,0x62,0x56,0xb0,0x54,0x3c, + 0x8b,0x98,0x93,0xe9,0xc9,0x60,0x1b,0x0d,0x92,0x53,0x6b,0x72,0x5f,0x37,0x5a,0x47, + 0x86,0x89,0x0d,0x4d,0x94,0x60,0xf0,0x8c,0x1d,0x2b,0xcd,0x19,0x95,0x53,0x90,0xac, + 0xcf,0x9a,0x1e,0xec,0x4d,0x22,0x7d,0x0d,0x67,0xe5,0x46,0x15,0x94,0x13,0x7c,0xc8, + 0x50,0xa7,0xcf,0x65,0xc3,0x33,0x82,0xc8,0xe1,0xba,0xb5,0xac,0xa5,0xb9,0x13,0xd0, + 0xde,0x22,0x89,0x1a,0x15,0x99,0x85,0x02,0xb4,0x24,0xa9,0x3a,0x76,0xb1,0x7d,0x88, + 0xda,0x86,0x01,0xb7,0xba,0xbb,0xec,0xab,0x94,0x25,0x8d,0x54,0x9f,0xb0,0x2b,0x59, + 0x0c,0xa4,0xd0,0xf1,0xbb,0x9a,0x10,0xfc,0xe3,0x44,0x87,0x40,0x70,0x99,0xa6,0xeb, + 0x19,0xc1,0x95,0x0c,0xbd,0xfa,0xcb,0xd7,0x85,0x98,0x61,0x6a,0x5e,0x48,0x7e,0xf0, + 0x29,0x9f,0xf6,0x5a,0x7d,0xb4,0xfd,0x3a,0x7f,0xa0,0x69,0x7a,0x57,0x2f,0x1f,0xec, + 0x13,0xdc,0x50,0xeb,0x43,0x3c,0x4d,0x57,0xe8,0x36,0xcf,0x11,0x9d,0x79,0x5f,0xb9, + 0x18,0xfa,0x29,0x4f,0x9e,0x4d,0xe8,0x04,0x0e,0x0c,0x44,0x1d,0xdb,0xff,0xad,0x7f, + 0x9d,0x42,0xce,0x2e,0x92,0x24,0x62,0x21,0x18,0xbb,0xf1,0x84,0x86,0xdf,0xa1,0x7e, + 0x6a,0x22,0x90,0x11,0x72,0xde,0x83,0x3b,0xc3,0x49,0x78,0x0b,0x75,0x0f,0x1b,0xc7, + 0x15,0xff,0x89,0x67,0xf1,0x77,0x31,0xdd,0xc4,0x00,0x4e,0x25,0x53,0x6c,0x09,0xe2, + 0xa3,0x00,0xf1,0x97,0x19,0x72,0xef,0xc1,0xc9,0x4c,0xd9,0x0a,0xd9,0x0f,0x80,0xb0, + 0x05,0xb5,0xfe,0xe0,0x14,0x25,0x30,0x3f,0xf5,0xf9,0xcb,0xec,0xf7,0xe2,0x33,0x17, + 0xdd,0x0f,0x7c,0x27,0x4c,0x2a,0xe5,0x92,0xc1,0xb9,0x18,0x95,0x8a,0x98,0x81,0x80, + 0x87,0x0b,0xb8,0x36,0xc5,0x29,0x29,0xe3,0x1f,0x79,0xd5,0x25,0xda,0x27,0xcb,0x0e, + 0x72,0xfb,0xf7,0xf1,0x95,0x06,0x20,0x02,0xd6,0x48,0xc3,0x74,0x86,0x6e,0x05,0x90, + 0x3b,0xa9,0xba,0xbe,0x10,0xaa,0x4b,0xac,0xa1,0x39,0xba,0xee,0xa1,0xe4,0x10,0xde, + 0xd0,0xf4,0xf2,0x98,0x3b,0x9c,0xdd,0x5a,0x0a,0x96,0xe4,0xaf,0x32,0xdf,0xbb,0x24, + 0x77,0x48,0xb9,0x8f,0x10,0x7b,0xeb,0x0d,0x4a,0x49,0xd9,0xcf,0x99,0x7a,0x24,0x77, + 0x06,0xbd,0xd3,0x18,0x9d,0x3b,0x63,0xbb,0xcc,0x81,0x9a,0x23,0x3d,0x9f,0xe9,0x33, + 0xdf,0xbc,0x1e,0xc8,0x18,0x29,0x32,0x28,0xf7,0xc7,0x52,0x2b,0x7e,0x2e,0xe5,0x7c, + 0x89,0xf1,0xf4,0x3d,0xb8,0xa6,0x25,0xfa,0x4a,0xb2,0x62,0x01,0x78,0x0d,0x63,0x87, + 0x57,0xd3,0xfd,0x2d,0x39,0x4b,0x57,0x8b,0xe8,0xb1,0x8f,0x18,0xe9,0x9e,0x31,0xa9, + 0x83,0x00,0x96,0x6c,0xbd,0x6d,0x63,0x59,0x6a,0x70,0x9a,0x1b,0xae,0x66,0xa0,0x82, + 0x74,0xbd,0xe4,0x86,0x56,0x3f,0x54,0xdd,0x2a,0xfa,0x9e,0xa0,0xd3,0x76,0xb3,0xa1, + 0x40,0xbe,0xac,0x7d,0x13,0x4a,0x1d,0x32,0x64,0xab,0xe4,0x36,0x53,0x83,0x1f,0x05, + 0xa3,0x12,0x31,0xfa,0x13,0x69,0x5b,0x70,0xc4,0x1c,0xc5,0x3c,0x93,0x52,0xad,0xe3, + 0xd7,0xbc,0x89,0x7d,0x83,0xa8,0x47,0xb4,0x42,0x11,0xa5,0xe5,0xf9,0x7c,0xbb,0xa2, + 0x02,0x19,0xbc,0x46,0xdc,0x9b,0x55,0x92,0xe0,0x70,0x88,0x01,0x74,0xae,0x1c,0x5d, + 0x17,0xb8,0xcc,0xd4,0x33,0xb8,0x5c,0x0d,0x6b,0x17,0x2c,0xe1,0x3b,0xfc,0x38,0x3c, + 0xa2,0x57,0x05,0x45,0xcf,0x36,0xc4,0x03,0xe6,0x46,0x1a,0x61,0xd1,0xe2,0x01,0x16, + 0x61,0x17,0xad,0x62,0x50,0x38,0x10,0xf6,0x63,0x69,0x4d,0xae,0x0e,0xcb,0xa2,0xea, + 0xd7,0x7b,0xa6,0x75,0x30,0xe3,0x46,0x77,0xcd,0x87,0xf6,0x0c,0x2e,0xf5,0x99,0x67, + 0xdc,0x9a,0x89,0x8e,0xb6,0x3b,0x05,0x83,0x5a,0xfb,0xc4,0xb9,0xda,0xf4,0x61,0xeb, + 0x5f,0x97,0x87,0x70,0xa8,0x7a,0x16,0xcf,0x17,0x18,0xef,0x2f,0xfd,0xb0,0xdf,0x86, + 0x2d,0xb4,0x38,0x9c,0x34,0x37,0xa7,0x3b,0xcb,0x6b,0x60,0x39,0xd2,0x98,0x4e,0xcc, + 0x60,0x36,0x56,0x8e,0x9b,0x30,0x0f,0xfa,0x8f,0xa3,0xfd,0x92,0xab,0x3e,0x70,0x1c, + 0xa6,0xeb,0x6e,0x9e,0xb8,0x96,0xcd,0x7c,0x60,0x2f,0x73,0xb2,0x8e,0x21,0x79,0x1d, + 0xe8,0xe1,0xbf,0x8f,0x36,0x32,0x6d,0x17,0x89,0x8e,0x48,0xaf,0x67,0x83,0x07,0xdd, + 0xe3,0x55,0xa7,0x55,0xbd,0x3f,0xe0,0x1b,0x88,0x15,0x1f,0x80,0x7a,0x13,0x28,0x07, + 0xb1,0x84,0xa0,0xfb,0x1c,0xe2,0x0a,0xc0,0xc6,0xc3,0x06,0xd7,0xbc,0xa4,0x07,0xe1, + 0x27,0x3c,0x38,0x94,0x95,0x22,0x40,0xb0,0x67,0x73,0xd9,0x38,0x85,0x95,0x23,0x78, + 0x5d,0xdf,0xec,0x00,0x14,0x3f,0xf6,0x41,0x87,0x7d,0xef,0x15,0x94,0xae,0x57,0xb2, + 0x71,0x80,0xf3,0x39,0x36,0x78,0x03,0xd1,0x47,0xc7,0x9e,0xc6,0x49,0x71,0x00,0x1d, + 0xb9,0x79,0xf0,0xe7,0xff,0x1e,0xaf,0x62,0x62,0xc2,0x70,0x21,0x72,0x8a,0x57,0xb0, + 0x85,0x79,0x37,0x14,0x11,0x8d,0x00,0xf6,0x65,0x70,0x9e,0x07,0x54,0x37,0x19,0xc1, + 0x5b,0xd9,0x99,0x63,0xe1,0x82,0x51,0x23,0xa5,0x39,0x61,0x14,0xb7,0x8a,0x14,0x3c, + 0x24,0x81,0x9e,0xbf,0x75,0x7a,0x21,0xfe,0x45,0xc3,0x39,0x0a,0xe6,0xe4,0x95,0xab, + 0x28,0x25,0x82,0xf3,0x3e,0x13,0x2d,0x48,0xce,0xcb,0x5a,0xa4,0x7e,0x3e,0x3a,0x7c, + 0x0b,0x83,0x34,0x5e,0x90,0x24,0x65,0xca,0x49,0xc6,0xd2,0xb8,0xa1,0xa8,0x39,0xeb, + 0xdc,0x91,0x27,0xf7,0x9c,0xe8,0xf6,0xc9,0x4e,0x82,0xcc,0xd2,0xdc,0xe4,0x2b,0x04, + 0x09,0x5f,0x4c,0xe0,0x7c,0x7d,0x5b,0x9f,0x8c,0x89,0xdb,0x9f,0x83,0xe6,0xcd,0xa0, + 0xe7,0xd4,0x1a,0x46,0xe3,0xe3,0x6c,0x08,0x6f,0x6e,0x73,0x7f,0x7c,0xce,0x30,0x5b, + 0xac,0x8e,0xf1,0xdc,0xf1,0xe2,0x60,0x7b,0x6e,0x6d,0xbe,0x6f,0x59,0xc6,0x1b,0xc9, + 0x8f,0xf3,0xba,0xf0,0x98,0x7d,0x13,0x68,0xfa,0xc3,0xf5,0x6d,0xce,0xed,0x94,0xa0, + 0x0d,0x87,0x50,0xbd,0x33,0x52,0xbb,0x16,0xf0,0xc5,0x20,0x7d,0xd3,0xad,0x80,0x72, + 0x20,0x9f,0xcc,0x77,0xf2,0xb0,0x4c,0x20,0x46,0x60,0x6b,0xf6,0xf6,0x57,0xec,0xf4, + 0x4c,0xe0,0x29,0xe4,0xde,0x37,0x44,0xb0,0x69,0x5a,0x53,0x4c,0x51,0x0a,0xb5,0x9c, + 0x98,0x89,0x82,0x10,0xdf,0x14,0x65,0xba,0xa4,0x5f,0x98,0xd5,0x57,0x97,0x35,0xa6, + 0x4c,0xe2,0x0e,0xa1,0x69,0x56,0x39,0x51,0xe3,0x39,0x42,0xc5,0x02,0x4c,0x5a,0x07, + 0xa9,0x12,0x24,0x42,0x1d,0x32,0xe7,0x66,0x6d,0x9c,0x4b,0x69,0x89,0x29,0xa0,0xa1, + 0x6c,0x17,0x94,0x54,0x3e,0xd1,0xeb,0x0d,0x33,0x02,0x9b,0x88,0xa5,0xfd,0x65,0x83, + 0xa2,0x34,0x85,0x87,0x18,0x3b,0x4f,0x01,0x85,0x26,0x14,0x19,0x7b,0x0b,0x92,0xa0, + 0xe4,0xfb,0xd5,0x87,0xbf,0xb8,0xfc,0x99,0x90,0x42,0x79,0x30,0x77,0xd7,0x7e,0x92, + 0x1f,0xea,0xf8,0xbd,0x30,0x13,0x47,0x28,0x69,0xbc,0xd6,0x18,0xb8,0xf5,0x1c,0x65, + 0xd9,0x96,0x0f,0x84,0xa1,0x0d,0x5e,0xb8,0x6c,0xd4,0xf6,0x26,0xff,0x3e,0x9f,0x7a, + 0x0f,0x69,0x95,0x8e,0x39,0xac,0x6d,0xbb,0x4f,0x9b,0xcc,0xd4,0x71,0x6c,0x0f,0x92, + 0x44,0xea,0xf1,0x90,0xaf,0xf5,0x45,0xdb,0xb9,0x99,0xfc,0xdd,0x84,0xf2,0x81,0x0a, + 0x2a,0x3c,0x8e,0x0c,0xbd,0xf8,0xa9,0x1e,0x51,0x1a,0x5a,0x2e,0xc7,0xbd,0x14,0xa8, + 0x8c,0x9b,0x86,0xbc,0x19,0xd3,0xfe,0x93,0x78,0x29,0xd2,0x7b,0xf6,0x9d,0x2d,0xef, + 0x2c,0x62,0x8f,0xc8,0x3d,0xb1,0xae,0xeb,0x0f,0x61,0xdb,0xfa,0x77,0xae,0xc0,0x34, + 0x52,0x90,0xb6,0x8c,0x1a,0x39,0xaf,0x7f,0x97,0x76,0xd3,0xe7,0x77,0xdd,0x00,0x43, + 0x04,0x24,0x20,0x77,0xb3,0xa3,0xd0,0x9c,0x88,0xc8,0x96,0x11,0xb9,0x81,0x08,0x54, + 0xef,0x9e,0xf0,0x33,0xec,0x2e,0x60,0x14,0xc3,0x65,0xa6,0x10,0x57,0xd9,0x5f,0x01, + 0x08,0x68,0xb7,0xf6,0x1c,0xff,0x19,0xc3,0x81,0x46,0x3d,0xb7,0x8c,0x6a,0x09,0x11, + 0x84,0xe4,0x19,0xe9,0x75,0xd8,0x92,0x53,0x80,0x47,0xae,0xdd,0x0f,0x2e,0xa8,0x7d, + 0xe9,0x40,0x95,0xe5,0x30,0xde,0x30,0x20,0xe0,0x99,0xc9,0xc2,0x1e,0xc9,0xec,0x32, + 0xf4,0x8e,0xc8,0xd6,0x1a,0x98,0xc8,0xf2,0x42,0xa2,0xc2,0x8b,0x55,0x5c,0x7b,0xf1, + 0x2c,0xa9,0x95,0xe5,0xb8,0x25,0x29,0x46,0x3f,0x49,0xcb,0x85,0x82,0xcd,0xa5,0x6c, + 0x68,0x43,0xf1,0x85,0x64,0x28,0x63,0x93,0x41,0x4f,0xaa,0xf1,0xf8,0x0c,0xfb,0x08, + 0x08,0x20,0x93,0xe1,0x74,0x83,0x6a,0xac,0x6b,0x54,0x6d,0xcc,0x4c,0x73,0xdc,0x18, + 0x0f,0x0a,0xb9,0xc9,0x1f,0x40,0xf6,0xaa,0x49,0x41,0xd8,0x7c,0x09,0x6d,0xf5,0xe2, + 0x88,0x26,0xd0,0x24,0x60,0x30,0x73,0x2a,0x9d,0x47,0x26,0x4b,0x55,0xec,0x3c,0x79, + 0xdb,0x10,0xbf,0x0e,0xf5,0xf3,0x1c,0xd1,0xdb,0x06,0x1d,0xd5,0x65,0x26,0x78,0xf8, + 0xa4,0xa3,0x76,0x2e,0x59,0xf3,0xa0,0x0a,0x09,0x93,0x12,0xb8,0x10,0x2d,0x48,0xa7, + 0x2f,0x4f,0xb2,0xde,0x12,0xf0,0x50,0x38,0xe8,0x4b,0x21,0xfe,0x5a,0x88,0xe7,0x2b, + 0x07,0xd8,0xbb,0x6a,0xf9,0xde,0x2b,0x0b,0x89,0xbe,0xb3,0x2d,0x36,0x63,0x02,0x13, + 0x6a,0xa0,0xf3,0x0d,0x9f,0x20,0x53,0xcb,0x3e,0x40,0xe3,0x3a,0x0d,0x03,0x54,0x31, + 0x04,0x45,0x3b,0xc3,0xe6,0x38,0x14,0x24,0x49,0x22,0x54,0xc9,0x14,0x3e,0x08,0xfb, + 0xa0,0x1c,0x1c,0x69,0x31,0x70,0x64,0x97,0x9c,0x5e,0xa4,0x4f,0x90,0x12,0x98,0xaa, + 0xd1,0x69,0x87,0xfa,0x66,0xcd,0x75,0x01,0xa6,0xdf,0x05,0x81,0x51,0xd3,0x57,0xb9, + 0xc9,0x09,0x61,0x15,0x4d,0x13,0x8d,0xc3,0x12,0xce,0xe6,0x72,0x0c,0xc5,0xc0,0xa0, + 0x3e,0x9f,0x6c,0xec,0x22,0x7b,0xa1,0x92,0xc1,0x52,0x38,0x64,0x8e,0x54,0x9f,0x2e, + 0xfe,0x9f,0xcd,0x32,0xb6,0x64,0xa7,0x12,0xc2,0xdf,0xe4,0x07,0x07,0xd1,0xc1,0xfc, + 0x5d,0x9b,0xc4,0x23,0xa2,0x79,0x5d,0x4f,0x43,0xdc,0x79,0x67,0xf3,0xb3,0x36,0x8e, + 0x20,0x19,0x94,0xcf,0xd4,0xf1,0xda,0x13,0x61,0x5f,0x32,0xc8,0x75,0x82,0x7b,0x78, + 0xcc,0xbb,0x2a,0xce,0xbb,0x3e,0xba,0x3b,0x31,0x52,0x2d,0x36,0x79,0x98,0x75,0x61, + 0x21,0x17,0xf6,0x1e,0x38,0x86,0xde,0x98,0x43,0x54,0xfd,0x42,0x5d,0x15,0xc9,0xc3, + 0x11,0x06,0x8f,0x52,0xdb,0xaa,0xd1,0x59,0xb6,0xcb,0x28,0x36,0x07,0xa7,0x37,0x72, + 0xde,0x1b,0xb7,0x2f,0xe9,0xbb,0xe0,0x4b,0xc8,0x6b,0xa0,0x22,0x06,0xe6,0xa6,0xf7, + 0x0e,0x10,0x56,0x8b,0xc7,0x8a,0x27,0x96,0xc9,0x39,0x65,0xd0,0x86,0x8d,0xea,0x9a, + 0xaf,0x11,0x62,0xac,0xbb,0xbb,0x52,0x9f,0xca,0xd5,0x61,0xc5,0x90,0x39,0x7f,0x8b, + 0x09,0x12,0x38,0xb3,0x68,0xe1,0xe8,0x0b,0xce,0x58,0x47,0x9f,0x09,0xcc,0x27,0x28, + 0x28,0x1d,0xef,0x1d,0xab,0x53,0x5b,0x1b,0x94,0xd6,0xe5,0x41,0x10,0x1b,0x81,0x64, + 0xfb,0x9b,0x86,0x2e,0x49,0xbb,0xdc,0xb0,0x25,0xca,0x1c,0xb9,0x55,0x80,0x90,0xd5, + 0xc7,0x03,0xa9,0x65,0x21,0xee,0x18,0x5c,0x41,0x18,0xe1,0x60,0xf0,0x61,0x07,0x65, + 0xf8,0xcd,0x7d,0x74,0xac,0xed,0x37,0xa7,0xef,0x44,0x71,0xc6,0xde,0xa3,0x21,0x92, + 0xfa,0xe3,0x39,0x50,0xae,0xe7,0xfc,0x41,0x36,0x7c,0x41,0xb3,0xf6,0x2e,0x7a,0xaa, + 0xce,0x4b,0x70,0xd7,0x01,0x0f,0xc4,0x1d,0xe5,0x85,0x17,0x26,0x5a,0x8a,0x92,0x14, + 0x4b,0xc9,0xda,0x66,0xd4,0x0a,0x6f,0x71,0x2c,0x14,0x80,0x52,0x51,0x14,0xc9,0x4f, + 0xb5,0xa2,0x99,0x43,0x7f,0xfc,0xb1,0xdf,0x7a,0x6d,0xd1,0x66,0x5b,0xec,0xa9,0xbb, + 0x17,0x48,0x49,0x24,0x34,0x24,0x51,0x8a,0xf7,0x5c,0xc4,0x8a,0xe7,0x3c,0xe2,0xc3, + 0x80,0x8e,0x1c,0xe6,0x94,0x6e,0xef,0xaa,0x7b,0x29,0xeb,0x78,0xf9,0x86,0x2e,0xf8, + 0x29,0x04,0x6a,0x43,0xe4,0xa1,0xd7,0xd7,0x35,0x92,0x65,0x3f,0x5b,0xa0,0x2f,0x0c, + 0x2d,0x02,0xe1,0x1c,0xf5,0xa5,0x4e,0xc1,0xca,0x1a,0xd1,0x27,0xdd,0x5a,0x72,0x08, + 0x2a,0xca,0x2f,0x20,0xf4,0xea,0xce,0xd2,0xdd,0xd0,0xa5,0xbb,0xd8,0x2d,0xca,0x52, + 0x8b,0x8c,0xd4,0xbd,0x92,0xa1,0xc0,0x79,0x01,0xc4,0x40,0xea,0x68,0x33,0x2a,0x65, + 0x07,0xe1,0x7a,0x2c,0x2c,0x19,0xe9,0x44,0x37,0x8d,0x3c,0x7b,0x59,0xff,0x8b,0x4f, + 0xaa,0xe0,0x18,0x68,0x3f,0x51,0x55,0xa3,0xc7,0x3b,0x33,0xab,0xde,0xed,0x43,0x99, + 0x72,0x05,0x11,0xb7,0x79,0xe0,0xb4,0x83,0x4d,0xc7,0xfb,0x7b,0xa6,0x5f,0xfb,0x9e, + 0x22,0x20,0x7b,0x87,0xb4,0xf0,0x1b,0xd8,0xbd,0x92,0x57,0x58,0x50,0x8c,0xb3,0x00, + 0x2d,0x9b,0x4c,0xa9,0x11,0x3c,0xbe,0xaa,0xe5,0xbc,0x7c,0x36,0x09,0x8c,0x07,0xa7, + 0x29,0x3f,0x7a,0x87,0x37,0xbc,0xaf,0xd3,0xd7,0x89,0x0a,0xe8,0xc7,0xd8,0xa9,0x17, + 0xd3,0xa8,0xd3,0xa2,0xd6,0xfc,0xad,0xc0,0xf2,0xbf,0xab,0xd5,0x9d,0xfe,0xa4,0x82, + 0x8b,0x9a,0xde,0x59,0xc9,0x39,0xb4,0x9f,0xa4,0xd2,0xcc,0xde,0x85,0x49,0xc8,0x10, + 0x84,0x9b,0x8c,0x76,0x25,0xb6,0x1c,0xb3,0xca,0xd8,0x53,0xd2,0x57,0x34,0x0d,0x01, + 0x22,0x98,0x06,0x39,0x92,0xf7,0x7d,0x36,0x47,0x29,0xad,0x04,0x2b,0x6b,0x55,0x77, + 0x25,0x9f,0x6b,0xdf,0xd4,0xa1,0x37,0x0d,0x44,0x96,0xbd,0x30,0xc4,0xd0,0x8e,0xba, + 0xa9,0xf9,0xb0,0xbb,0x3a,0xb9,0x54,0x36,0x6f,0xca,0xa4,0xa4,0x7a,0xfb,0xe7,0x1c, + 0x2b,0x92,0xaa,0xde,0x75,0x4c,0x60,0x58,0x69,0x64,0xde,0x0c,0x4e,0xf4,0xe7,0x37, + 0x81,0xd8,0xe7,0xed,0x33,0x3c,0x00,0x67,0xa4,0x80,0xa7,0x2b,0xfe,0x93,0xbd,0x1f, + 0xc3,0x3e,0x39,0x1b,0xa8,0xab,0x0d,0x8b,0x2e,0x74,0xbd,0x5d,0xd9,0x70,0x92,0xb8, + 0x8d,0x9a,0x9e,0xe9,0x5d,0xba,0xf8,0x3a,0x54,0xdf,0x4e,0x7c,0x0e,0xee,0x6a,0x38, + 0x8e,0x17,0x96,0xf9,0x5c,0xbf,0x72,0x3f,0x7e,0x45,0xda,0xbe,0x7b,0x93,0x6f,0x6d, + 0x0f,0x16,0x9f,0xeb,0xdd,0xa8,0x27,0x36,0xab,0x46,0x4f,0x9f,0x7e,0x78,0xe8,0x8b, + 0x0f,0x90,0x97,0xfb,0xb9,0x46,0x71,0x3e,0xe0,0x25,0x6f,0xb8,0xdb,0x91,0x40,0x3f, + 0x08,0x6c,0x7f,0xe6,0x34,0xdd,0x78,0xd1,0xc3,0x50,0x98,0xa0,0x52,0x99,0x30,0x01, + 0x5d,0xf6,0x37,0x8f,0xee,0x60,0x70,0xf2,0xe0,0x02,0x08,0xb6,0x3f,0xa0,0x29,0xc3, + 0x7d,0x01,0x6d,0x9e,0x91,0xa2,0xd1,0x34,0x77,0x4c,0x00,0x0b,0x64,0x37,0x09,0x10, + 0xd5,0x0d,0x25,0x6e,0x4f,0xdc,0x79,0x91,0xcd,0xce,0xc3,0x20,0x72,0x06,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0x6a,0x8e, + 0xf4,0x49,0x12,0x7e,0x2b,0xbd,0x6a,0x88,0xb7,0xf7,0xc8,0xd3,0xfb,0x29,0xf2,0x6a, + 0x3a,0xdf,0x3f,0xfa,0x9c,0xaa,0x1e,0xda,0x6d,0x4f,0x65,0x4e,0xfa,0x94,0x5a,0x93, + 0xeb,0xf5,0x7b,0x05,0x3f,0x31,0x73,0x89,0xc4,0xc1,0xf3,0x6d,0x76,0x67,0xf3,0xf1, + 0x2d,0x80,0x0b,0xfd,0xdb,0x65,0x17,0x47,0x68,0xc1,0xe3,0x19,0x5b,0x88,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0x24,0x95, + 0xad,0x9d,0x11,0x73,0x14,0xbd,0x11,0x1f,0x68,0x30,0x11,0x20,0x58,0xa4,0xf7,0xb4, + 0xae,0x13,0x4c,0x54,0x1c,0xe6,0xdc,0x10,0xce,0x58,0xa4,0xe4,0x31,0x7e,0xe2,0x7e, + 0x41,0xc4,0x7e,0xfb,0xd0,0xa3,0xd5,0x41,0x7e,0x13,0x05,0x27,0x70,0xfa,0xba,0x90, + 0x2c,0x1f,0xcd,0x62,0x95,0xbe,0x99,0x0e,0xed,0x33,0x0d,0x31,0x87,0x2b,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0x6e,0x88, + 0x43,0xfc,0xdf,0x0c,0x9f,0x3e,0x96,0x48,0xf6,0x1a,0x56,0xd9,0x79,0x39,0xee,0xa7, + 0x0d,0x57,0xcb,0x7a,0x1d,0xc4,0x1e,0x45,0x79,0xe2,0xb9,0x4a,0x5d,0x7f,0x03,0x89, + 0x2b,0x14,0xf1,0xc7,0x1b,0x21,0x88,0xa0,0xcc,0x81,0x28,0x9d,0xb4,0x61,0x4f,0xeb, + 0x42,0x92,0xa9,0x49,0x1a,0xbe,0x51,0x55,0x69,0x60,0x97,0xda,0x04,0x74,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xe4, + 0xe5,0x90,0xa1,0x82,0x62,0x6c,0x4f,0xc0,0xc6,0xe8,0xa2,0x54,0xf7,0x85,0x77,0xd0, + 0x36,0x0d,0x28,0x6a,0xe3,0xa7,0x40,0x16,0x43,0xc2,0x78,0x1a,0x9c,0xe0,0xd9,0x27, + 0xf7,0xb4,0x7e,0xf3,0xe3,0xe2,0x0e,0x41,0x85,0xe2,0xeb,0xd8,0x77,0xa3,0x91,0xfd, + 0x95,0xce,0xa1,0x5a,0xf6,0xc3,0xc5,0x53,0xc9,0x34,0x3e,0x32,0xd3,0x7a,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdf,0xf7, + 0xcf,0x53,0xda,0x8c,0x1d,0xf0,0xb6,0x2f,0x48,0x31,0x13,0x0a,0xd9,0x6b,0x86,0x64, + 0x6c,0x8d,0x51,0x60,0x7d,0xa9,0xaa,0xbe,0x6f,0xa6,0xe3,0x10,0xfa,0xa8,0xc4,0x0f, + 0xa1,0x74,0x99,0xed,0xb8,0x27,0x36,0xaf,0xef,0xbc,0x1f,0xdf,0xcc,0x1c,0x49,0x19, + 0x8c,0xcb,0x6b,0xdf,0xb0,0x7c,0x63,0x3e,0xc9,0x32,0xeb,0x32,0x95,0xa7,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0x7d,0x81, + 0xc3,0x96,0xb3,0x79,0xd5,0x13,0x64,0x4f,0x6c,0x90,0x24,0x24,0x75,0x0e,0x54,0x54, + 0x91,0xd0,0x8c,0x6b,0x24,0x0a,0x63,0xf0,0xd9,0xcb,0x43,0x49,0x8a,0x0e,0x2d,0x2c, + 0x07,0x12,0xdd,0x79,0x90,0x69,0x75,0x99,0x97,0xf6,0x8f,0x45,0xd0,0x0d,0x17,0x60, + 0xd8,0x3c,0xf8,0x6f,0xb5,0xf1,0x8c,0x66,0x9a,0xdf,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0x7e,0xcc, + 0x04,0xd4,0x38,0xce,0x18,0xfa,0xed,0xbd,0x68,0xb1,0x49,0x51,0x83,0x07,0x16,0xca, + 0xad,0x96,0x31,0x0f,0x76,0x13,0x5e,0xb8,0x6c,0xd4,0x41,0x41,0x82,0x06,0xb1,0x09, + 0x2c,0x12,0xef,0xcf,0xba,0xb8,0xd8,0x2f,0xdd,0xc5,0x48,0x50,0x03,0x05,0xbf,0xd9, + 0x0c,0x97,0xe1,0xbb,0xbb,0xb1,0x4d,0x95,0xe1,0x50,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0xff,0xff, + 0xff,0xff,0x7f,0xfb,0xef,0xdf,0xef,0xdf,0xbf,0xbf,0x6f,0xdb,0xaf,0x9f,0xf7,0xef, + 0xfe,0xfe,0x77,0xeb,0xee,0xde,0xe7,0xcf,0xbe,0xbe,0x67,0xcb,0xae,0x9e,0xfe,0xfe, + 0x7f,0xfd,0x7e,0xfa,0x6f,0xdd,0xee,0xde,0x3f,0xbd,0x6e,0xda,0x2f,0x9d,0xf6,0xee, + 0x7e,0xfc,0x76,0xea,0x6e,0xdc,0xe6,0xce,0x3e,0xbc,0x66,0xca,0x2e,0x9c,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0xfd,0xf7, + 0xf7,0xf7,0x7d,0xf3,0xe7,0xd7,0xed,0xd7,0xb7,0xb7,0x6d,0xd3,0xa7,0x97,0xf5,0xe7, + 0xf6,0xf6,0x75,0xe3,0xe6,0xd6,0xe5,0xc7,0xb6,0xb6,0x65,0xc3,0xa6,0x96,0xfc,0xf6, + 0x77,0xf5,0x7c,0xf2,0x67,0xd5,0xec,0xd6,0x37,0xb5,0x6c,0xd2,0x27,0x95,0xf4,0xe6, + 0x76,0xf4,0x74,0xe2,0x66,0xd4,0xe4,0xc6,0x36,0xb4,0x64,0xc2,0x26,0x94,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0xfb,0x7f, + 0xdf,0xef,0x7b,0x7b,0xcf,0xcf,0xeb,0x5f,0x9f,0xaf,0x6b,0x5b,0x8f,0x8f,0xf3,0x6f, + 0xde,0xee,0x73,0x6b,0xce,0xce,0xe3,0x4f,0x9e,0xae,0x63,0x4b,0x8e,0x8e,0xfa,0x7e, + 0x5f,0xed,0x7a,0x7a,0x4f,0xcd,0xea,0x5e,0x1f,0xad,0x6a,0x5a,0x0f,0x8d,0xf2,0x6e, + 0x5e,0xec,0x72,0x6a,0x4e,0xcc,0xe2,0x4e,0x1e,0xac,0x62,0x4a,0x0e,0x8c,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0xf9,0x77, + 0xd7,0xe7,0x79,0x73,0xc7,0xc7,0xe9,0x57,0x97,0xa7,0x69,0x53,0x87,0x87,0xf1,0x67, + 0xd6,0xe6,0x71,0x63,0xc6,0xc6,0xe1,0x47,0x96,0xa6,0x61,0x43,0x86,0x86,0xf8,0x76, + 0x57,0xe5,0x78,0x72,0x47,0xc5,0xe8,0x56,0x17,0xa5,0x68,0x52,0x07,0x85,0xf0,0x66, + 0x56,0xe4,0x70,0x62,0x46,0xc4,0xe0,0x46,0x16,0xa4,0x60,0x42,0x06,0x84,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xfd, + 0xfb,0x7f,0x5f,0xf9,0xeb,0x5f,0xcf,0xdd,0xbb,0x3f,0x4f,0xd9,0xab,0x1f,0xd7,0xed, + 0xfa,0x7e,0x57,0xe9,0xea,0x5e,0xc7,0xcd,0xba,0x3e,0x47,0xc9,0xaa,0x1e,0xde,0xfc, + 0x7b,0x7d,0x5e,0xf8,0x6b,0x5d,0xce,0xdc,0x3b,0x3d,0x4e,0xd8,0x2b,0x1d,0xd6,0xec, + 0x7a,0x7c,0x56,0xe8,0x6a,0x5c,0xc6,0xcc,0x3a,0x3c,0x46,0xc8,0x2a,0x1c,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdd,0xf5, + 0xf3,0x77,0x5d,0xf1,0xe3,0x57,0xcd,0xd5,0xb3,0x37,0x4d,0xd1,0xa3,0x17,0xd5,0xe5, + 0xf2,0x76,0x55,0xe1,0xe2,0x56,0xc5,0xc5,0xb2,0x36,0x45,0xc1,0xa2,0x16,0xdc,0xf4, + 0x73,0x75,0x5c,0xf0,0x63,0x55,0xcc,0xd4,0x33,0x35,0x4c,0xd0,0x23,0x15,0xd4,0xe4, + 0x72,0x74,0x54,0xe0,0x62,0x54,0xc4,0xc4,0x32,0x34,0x44,0xc0,0x22,0x14,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0xdb,0x7d, + 0xdb,0x6f,0x5b,0x79,0xcb,0x4f,0xcb,0x5d,0x9b,0x2f,0x4b,0x59,0x8b,0x0f,0xd3,0x6d, + 0xda,0x6e,0x53,0x69,0xca,0x4e,0xc3,0x4d,0x9a,0x2e,0x43,0x49,0x8a,0x0e,0xda,0x7c, + 0x5b,0x6d,0x5a,0x78,0x4b,0x4d,0xca,0x5c,0x1b,0x2d,0x4a,0x58,0x0b,0x0d,0xd2,0x6c, + 0x5a,0x6c,0x52,0x68,0x4a,0x4c,0xc2,0x4c,0x1a,0x2c,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0xd9,0x75, + 0xd3,0x67,0x59,0x71,0xc3,0x47,0xc9,0x55,0x93,0x27,0x49,0x51,0x83,0x07,0xd1,0x65, + 0xd2,0x66,0x51,0x61,0xc2,0x46,0xc1,0x45,0x92,0x26,0x41,0x41,0x82,0x06,0xd8,0x74, + 0x53,0x65,0x58,0x70,0x43,0x45,0xc8,0x54,0x13,0x25,0x48,0x50,0x03,0x05,0xd0,0x64, + 0x52,0x64,0x50,0x60,0x42,0x44,0xc0,0x44,0x12,0x24,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0xff,0xff, + 0xff,0xff,0x7f,0xfb,0xef,0xdf,0xef,0xdf,0xbf,0xbf,0x6f,0xdb,0xaf,0x9f,0xf7,0xef, + 0xfe,0xfe,0x77,0xeb,0xee,0xde,0xe7,0xcf,0xbe,0xbe,0x67,0xcb,0xae,0x9e,0xfe,0xfe, + 0x7f,0xfd,0x7e,0xfa,0x6f,0xdd,0xee,0xde,0x3f,0xbd,0x6e,0xda,0x2f,0x9d,0xf6,0xee, + 0x7e,0xfc,0x76,0xea,0x6e,0xdc,0xe6,0xce,0x3e,0xbc,0x66,0xca,0x2e,0x9c,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0xfd,0xf7, + 0xf7,0xf7,0x7d,0xf3,0xe7,0xd7,0xed,0xd7,0xb7,0xb7,0x6d,0xd3,0xa7,0x97,0xf5,0xe7, + 0xf6,0xf6,0x75,0xe3,0xe6,0xd6,0xe5,0xc7,0xb6,0xb6,0x65,0xc3,0xa6,0x96,0xfc,0xf6, + 0x77,0xf5,0x7c,0xf2,0x67,0xd5,0xec,0xd6,0x37,0xb5,0x6c,0xd2,0x27,0x95,0xf4,0xe6, + 0x76,0xf4,0x74,0xe2,0x66,0xd4,0xe4,0xc6,0x36,0xb4,0x64,0xc2,0x26,0x94,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0xfb,0x7f, + 0xdf,0xef,0x7b,0x7b,0xcf,0xcf,0xeb,0x5f,0x9f,0xaf,0x6b,0x5b,0x8f,0x8f,0xf3,0x6f, + 0xde,0xee,0x73,0x6b,0xce,0xce,0xe3,0x4f,0x9e,0xae,0x63,0x4b,0x8e,0x8e,0xfa,0x7e, + 0x5f,0xed,0x7a,0x7a,0x4f,0xcd,0xea,0x5e,0x1f,0xad,0x6a,0x5a,0x0f,0x8d,0xf2,0x6e, + 0x5e,0xec,0x72,0x6a,0x4e,0xcc,0xe2,0x4e,0x1e,0xac,0x62,0x4a,0x0e,0x8c,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0xf9,0x77, + 0xd7,0xe7,0x79,0x73,0xc7,0xc7,0xe9,0x57,0x97,0xa7,0x69,0x53,0x87,0x87,0xf1,0x67, + 0xd6,0xe6,0x71,0x63,0xc6,0xc6,0xe1,0x47,0x96,0xa6,0x61,0x43,0x86,0x86,0xf8,0x76, + 0x57,0xe5,0x78,0x72,0x47,0xc5,0xe8,0x56,0x17,0xa5,0x68,0x52,0x07,0x85,0xf0,0x66, + 0x56,0xe4,0x70,0x62,0x46,0xc4,0xe0,0x46,0x16,0xa4,0x60,0x42,0x06,0x84,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xfd, + 0xfb,0x7f,0x5f,0xf9,0xeb,0x5f,0xcf,0xdd,0xbb,0x3f,0x4f,0xd9,0xab,0x1f,0xd7,0xed, + 0xfa,0x7e,0x57,0xe9,0xea,0x5e,0xc7,0xcd,0xba,0x3e,0x47,0xc9,0xaa,0x1e,0xde,0xfc, + 0x7b,0x7d,0x5e,0xf8,0x6b,0x5d,0xce,0xdc,0x3b,0x3d,0x4e,0xd8,0x2b,0x1d,0xd6,0xec, + 0x7a,0x7c,0x56,0xe8,0x6a,0x5c,0xc6,0xcc,0x3a,0x3c,0x46,0xc8,0x2a,0x1c,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdd,0xf5, + 0xf3,0x77,0x5d,0xf1,0xe3,0x57,0xcd,0xd5,0xb3,0x37,0x4d,0xd1,0xa3,0x17,0xd5,0xe5, + 0xf2,0x76,0x55,0xe1,0xe2,0x56,0xc5,0xc5,0xb2,0x36,0x45,0xc1,0xa2,0x16,0xdc,0xf4, + 0x73,0x75,0x5c,0xf0,0x63,0x55,0xcc,0xd4,0x33,0x35,0x4c,0xd0,0x23,0x15,0xd4,0xe4, + 0x72,0x74,0x54,0xe0,0x62,0x54,0xc4,0xc4,0x32,0x34,0x44,0xc0,0x22,0x14,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0xdb,0x7d, + 0xdb,0x6f,0x5b,0x79,0xcb,0x4f,0xcb,0x5d,0x9b,0x2f,0x4b,0x59,0x8b,0x0f,0xd3,0x6d, + 0xda,0x6e,0x53,0x69,0xca,0x4e,0xc3,0x4d,0x9a,0x2e,0x43,0x49,0x8a,0x0e,0xda,0x7c, + 0x5b,0x6d,0x5a,0x78,0x4b,0x4d,0xca,0x5c,0x1b,0x2d,0x4a,0x58,0x0b,0x0d,0xd2,0x6c, + 0x5a,0x6c,0x52,0x68,0x4a,0x4c,0xc2,0x4c,0x1a,0x2c,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0xd9,0x75, + 0xd3,0x67,0x59,0x71,0xc3,0x47,0xc9,0x55,0x93,0x27,0x49,0x51,0x83,0x07,0xd1,0x65, + 0xd2,0x66,0x51,0x61,0xc2,0x46,0xc1,0x45,0x92,0x26,0x41,0x41,0x82,0x06,0xd8,0x74, + 0x53,0x65,0x58,0x70,0x43,0x45,0xc8,0x54,0x13,0x25,0x48,0x50,0x03,0x05,0xd0,0x64, + 0x52,0x64,0x50,0x60,0x42,0x44,0xc0,0x44,0x12,0x24,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x00,0x00,0xff,0xff, + 0xff,0xff,0x7f,0xfb,0xef,0xdf,0xef,0xdf,0xbf,0xbf,0x6f,0xdb,0xaf,0x9f,0xf7,0xef, + 0xfe,0xfe,0x77,0xeb,0xee,0xde,0xe7,0xcf,0xbe,0xbe,0x67,0xcb,0xae,0x9e,0xfe,0xfe, + 0x7f,0xfd,0x7e,0xfa,0x6f,0xdd,0xee,0xde,0x3f,0xbd,0x6e,0xda,0x2f,0x9d,0xf6,0xee, + 0x7e,0xfc,0x76,0xea,0x6e,0xdc,0xe6,0xce,0x3e,0xbc,0x66,0xca,0x2e,0x9c,0xbf,0xbf, + 0xfd,0xfb,0x3f,0xbb,0xed,0xdb,0xaf,0x9f,0xbd,0xbb,0x2f,0x9b,0xad,0x9b,0xb7,0xaf, + 0xfc,0xfa,0x37,0xab,0xec,0xda,0xa7,0x8f,0xbc,0xba,0x27,0x8b,0xac,0x9a,0xbe,0xbe, + 0x7d,0xf9,0x3e,0xba,0x6d,0xd9,0xae,0x9e,0x3d,0xb9,0x2e,0x9a,0x2d,0x99,0xb6,0xae, + 0x7c,0xf8,0x36,0xaa,0x6c,0xd8,0xa6,0x8e,0x3c,0xb8,0x26,0x8a,0x2c,0x98,0xfd,0xf7, + 0xf7,0xf7,0x7d,0xf3,0xe7,0xd7,0xed,0xd7,0xb7,0xb7,0x6d,0xd3,0xa7,0x97,0xf5,0xe7, + 0xf6,0xf6,0x75,0xe3,0xe6,0xd6,0xe5,0xc7,0xb6,0xb6,0x65,0xc3,0xa6,0x96,0xfc,0xf6, + 0x77,0xf5,0x7c,0xf2,0x67,0xd5,0xec,0xd6,0x37,0xb5,0x6c,0xd2,0x27,0x95,0xf4,0xe6, + 0x76,0xf4,0x74,0xe2,0x66,0xd4,0xe4,0xc6,0x36,0xb4,0x64,0xc2,0x26,0x94,0xbd,0xb7, + 0xf5,0xf3,0x3d,0xb3,0xe5,0xd3,0xad,0x97,0xb5,0xb3,0x2d,0x93,0xa5,0x93,0xb5,0xa7, + 0xf4,0xf2,0x35,0xa3,0xe4,0xd2,0xa5,0x87,0xb4,0xb2,0x25,0x83,0xa4,0x92,0xbc,0xb6, + 0x75,0xf1,0x3c,0xb2,0x65,0xd1,0xac,0x96,0x35,0xb1,0x2c,0x92,0x25,0x91,0xb4,0xa6, + 0x74,0xf0,0x34,0xa2,0x64,0xd0,0xa4,0x86,0x34,0xb0,0x24,0x82,0x24,0x90,0xfb,0x7f, + 0xdf,0xef,0x7b,0x7b,0xcf,0xcf,0xeb,0x5f,0x9f,0xaf,0x6b,0x5b,0x8f,0x8f,0xf3,0x6f, + 0xde,0xee,0x73,0x6b,0xce,0xce,0xe3,0x4f,0x9e,0xae,0x63,0x4b,0x8e,0x8e,0xfa,0x7e, + 0x5f,0xed,0x7a,0x7a,0x4f,0xcd,0xea,0x5e,0x1f,0xad,0x6a,0x5a,0x0f,0x8d,0xf2,0x6e, + 0x5e,0xec,0x72,0x6a,0x4e,0xcc,0xe2,0x4e,0x1e,0xac,0x62,0x4a,0x0e,0x8c,0xbb,0x3f, + 0xdd,0xeb,0x3b,0x3b,0xcd,0xcb,0xab,0x1f,0x9d,0xab,0x2b,0x1b,0x8d,0x8b,0xb3,0x2f, + 0xdc,0xea,0x33,0x2b,0xcc,0xca,0xa3,0x0f,0x9c,0xaa,0x23,0x0b,0x8c,0x8a,0xba,0x3e, + 0x5d,0xe9,0x3a,0x3a,0x4d,0xc9,0xaa,0x1e,0x1d,0xa9,0x2a,0x1a,0x0d,0x89,0xb2,0x2e, + 0x5c,0xe8,0x32,0x2a,0x4c,0xc8,0xa2,0x0e,0x1c,0xa8,0x22,0x0a,0x0c,0x88,0xf9,0x77, + 0xd7,0xe7,0x79,0x73,0xc7,0xc7,0xe9,0x57,0x97,0xa7,0x69,0x53,0x87,0x87,0xf1,0x67, + 0xd6,0xe6,0x71,0x63,0xc6,0xc6,0xe1,0x47,0x96,0xa6,0x61,0x43,0x86,0x86,0xf8,0x76, + 0x57,0xe5,0x78,0x72,0x47,0xc5,0xe8,0x56,0x17,0xa5,0x68,0x52,0x07,0x85,0xf0,0x66, + 0x56,0xe4,0x70,0x62,0x46,0xc4,0xe0,0x46,0x16,0xa4,0x60,0x42,0x06,0x84,0xb9,0x37, + 0xd5,0xe3,0x39,0x33,0xc5,0xc3,0xa9,0x17,0x95,0xa3,0x29,0x13,0x85,0x83,0xb1,0x27, + 0xd4,0xe2,0x31,0x23,0xc4,0xc2,0xa1,0x07,0x94,0xa2,0x21,0x03,0x84,0x82,0xb8,0x36, + 0x55,0xe1,0x38,0x32,0x45,0xc1,0xa8,0x16,0x15,0xa1,0x28,0x12,0x05,0x81,0xb0,0x26, + 0x54,0xe0,0x30,0x22,0x44,0xc0,0xa0,0x06,0x14,0xa0,0x20,0x02,0x04,0x80,0xdf,0xfd, + 0xfb,0x7f,0x5f,0xf9,0xeb,0x5f,0xcf,0xdd,0xbb,0x3f,0x4f,0xd9,0xab,0x1f,0xd7,0xed, + 0xfa,0x7e,0x57,0xe9,0xea,0x5e,0xc7,0xcd,0xba,0x3e,0x47,0xc9,0xaa,0x1e,0xde,0xfc, + 0x7b,0x7d,0x5e,0xf8,0x6b,0x5d,0xce,0xdc,0x3b,0x3d,0x4e,0xd8,0x2b,0x1d,0xd6,0xec, + 0x7a,0x7c,0x56,0xe8,0x6a,0x5c,0xc6,0xcc,0x3a,0x3c,0x46,0xc8,0x2a,0x1c,0x9f,0xbd, + 0xf9,0x7b,0x1f,0xb9,0xe9,0x5b,0x8f,0x9d,0xb9,0x3b,0x0f,0x99,0xa9,0x1b,0x97,0xad, + 0xf8,0x7a,0x17,0xa9,0xe8,0x5a,0x87,0x8d,0xb8,0x3a,0x07,0x89,0xa8,0x1a,0x9e,0xbc, + 0x79,0x79,0x1e,0xb8,0x69,0x59,0x8e,0x9c,0x39,0x39,0x0e,0x98,0x29,0x19,0x96,0xac, + 0x78,0x78,0x16,0xa8,0x68,0x58,0x86,0x8c,0x38,0x38,0x06,0x88,0x28,0x18,0xdd,0xf5, + 0xf3,0x77,0x5d,0xf1,0xe3,0x57,0xcd,0xd5,0xb3,0x37,0x4d,0xd1,0xa3,0x17,0xd5,0xe5, + 0xf2,0x76,0x55,0xe1,0xe2,0x56,0xc5,0xc5,0xb2,0x36,0x45,0xc1,0xa2,0x16,0xdc,0xf4, + 0x73,0x75,0x5c,0xf0,0x63,0x55,0xcc,0xd4,0x33,0x35,0x4c,0xd0,0x23,0x15,0xd4,0xe4, + 0x72,0x74,0x54,0xe0,0x62,0x54,0xc4,0xc4,0x32,0x34,0x44,0xc0,0x22,0x14,0x9d,0xb5, + 0xf1,0x73,0x1d,0xb1,0xe1,0x53,0x8d,0x95,0xb1,0x33,0x0d,0x91,0xa1,0x13,0x95,0xa5, + 0xf0,0x72,0x15,0xa1,0xe0,0x52,0x85,0x85,0xb0,0x32,0x05,0x81,0xa0,0x12,0x9c,0xb4, + 0x71,0x71,0x1c,0xb0,0x61,0x51,0x8c,0x94,0x31,0x31,0x0c,0x90,0x21,0x11,0x94,0xa4, + 0x70,0x70,0x14,0xa0,0x60,0x50,0x84,0x84,0x30,0x30,0x04,0x80,0x20,0x10,0xdb,0x7d, + 0xdb,0x6f,0x5b,0x79,0xcb,0x4f,0xcb,0x5d,0x9b,0x2f,0x4b,0x59,0x8b,0x0f,0xd3,0x6d, + 0xda,0x6e,0x53,0x69,0xca,0x4e,0xc3,0x4d,0x9a,0x2e,0x43,0x49,0x8a,0x0e,0xda,0x7c, + 0x5b,0x6d,0x5a,0x78,0x4b,0x4d,0xca,0x5c,0x1b,0x2d,0x4a,0x58,0x0b,0x0d,0xd2,0x6c, + 0x5a,0x6c,0x52,0x68,0x4a,0x4c,0xc2,0x4c,0x1a,0x2c,0x42,0x48,0x0a,0x0c,0x9b,0x3d, + 0xd9,0x6b,0x1b,0x39,0xc9,0x4b,0x8b,0x1d,0x99,0x2b,0x0b,0x19,0x89,0x0b,0x93,0x2d, + 0xd8,0x6a,0x13,0x29,0xc8,0x4a,0x83,0x0d,0x98,0x2a,0x03,0x09,0x88,0x0a,0x9a,0x3c, + 0x59,0x69,0x1a,0x38,0x49,0x49,0x8a,0x1c,0x19,0x29,0x0a,0x18,0x09,0x09,0x92,0x2c, + 0x58,0x68,0x12,0x28,0x48,0x48,0x82,0x0c,0x18,0x28,0x02,0x08,0x08,0x08,0xd9,0x75, + 0xd3,0x67,0x59,0x71,0xc3,0x47,0xc9,0x55,0x93,0x27,0x49,0x51,0x83,0x07,0xd1,0x65, + 0xd2,0x66,0x51,0x61,0xc2,0x46,0xc1,0x45,0x92,0x26,0x41,0x41,0x82,0x06,0xd8,0x74, + 0x53,0x65,0x58,0x70,0x43,0x45,0xc8,0x54,0x13,0x25,0x48,0x50,0x03,0x05,0xd0,0x64, + 0x52,0x64,0x50,0x60,0x42,0x44,0xc0,0x44,0x12,0x24,0x40,0x40,0x02,0x04,0x99,0x35, + 0xd1,0x63,0x19,0x31,0xc1,0x43,0x89,0x15,0x91,0x23,0x09,0x11,0x81,0x03,0x91,0x25, + 0xd0,0x62,0x11,0x21,0xc0,0x42,0x81,0x05,0x90,0x22,0x01,0x01,0x80,0x02,0x98,0x34, + 0x51,0x61,0x18,0x30,0x41,0x41,0x88,0x14,0x11,0x21,0x08,0x10,0x01,0x01,0x90,0x24, + 0x50,0x60,0x10,0x20,0x40,0x40,0x80,0x04,0x10,0x20,0x00,0x00,0x68,0xf7,0x80,0x0c, + 0xcc,0x40,0x3b,0xa1,0xe7,0xdd,0x4e,0xb6,0x98,0xeb,0xa8,0xdb,0xa5,0x03,0xbf,0x11, + 0x8c,0x0d,0x33,0xa5,0x1f,0x8e,0x7e,0xc1,0x83,0xc1,0xe6,0xa4,0xa4,0xc2,0x04,0x19, + 0x0f,0x00,0x97,0x95,0x7b,0xa0,0xf7,0x67,0x21,0xed,0x6a,0x5a,0xb8,0xe0,0x61,0x6e, + 0xc2,0x63,0x4d,0x17,0x9f,0x8e,0x67,0xaf,0x2a,0xb5,0x5d,0xc6,0xdf,0x67,0x1e,0x4f, + 0x46,0x4a,0x6c,0x06,0x91,0xd0,0x76,0x4c,0x0c,0xe9,0xe8,0x9b,0xa7,0x07,0x6e,0xef, + 0xfc,0xa1,0x17,0x54,0x93,0x65,0x6a,0x4e,0xe0,0xe4,0xa6,0xf9,0xa6,0xe6,0x20,0xe1, + 0x54,0xb9,0x81,0xe5,0x82,0xa6,0x43,0x90,0x61,0x06,0x2a,0x1a,0xb2,0x6a,0xba,0xaf, + 0x4b,0xb0,0x16,0x54,0x4f,0x45,0x1b,0x82,0x81,0x9a,0x7f,0x86,0xc5,0x63,0x1a,0x05, + 0x6b,0x68,0xd4,0x3d,0xb9,0xd7,0x4c,0xb3,0x58,0xe7,0x56,0x5f,0x32,0xc9,0xf1,0x47, + 0x4a,0x96,0x35,0x2d,0x5b,0x86,0x44,0x0f,0xc8,0xe6,0x4e,0xc2,0xa4,0xc8,0x94,0xf6, + 0x69,0xd9,0xbd,0xbd,0xb6,0xf5,0x70,0xd8,0x2c,0xfe,0xab,0xd2,0x31,0xe9,0xa4,0xdb, + 0x0a,0x4d,0xc9,0x63,0xf3,0x49,0x2d,0xc8,0x29,0x0b,0xd9,0xce,0x9b,0xb6,0x3d,0x5b, + 0xf8,0x93,0x92,0x40,0x5a,0xd7,0x04,0xed,0xa1,0x2e,0x91,0x53,0x58,0xb7,0x28,0x58, + 0x08,0x6d,0xce,0x43,0x59,0x86,0x3c,0x1a,0xbc,0xb0,0xda,0xf8,0x47,0xee,0x76,0xc1, + 0x33,0x60,0x43,0x4f,0x9e,0xd5,0xe4,0xe5,0x37,0x2d,0xd3,0x56,0xba,0xf5,0xcb,0x5d, + 0x16,0x5a,0x0b,0x59,0x72,0x6d,0x4d,0x1b,0x34,0x92,0x64,0x4c,0x7a,0x90,0x12,0x78, + 0x20,0x52,0x84,0xbf,0x58,0xab,0xcb,0xa1,0xbc,0x52,0x2b,0x01,0xba,0x7d,0x34,0x6f, + 0xd4,0x72,0x33,0x7c,0x35,0x5d,0x7a,0x39,0x62,0x31,0x63,0xca,0x5f,0xae,0x80,0x31, + 0x5d,0xb3,0x85,0x01,0xac,0xb1,0xc8,0xa5,0x5d,0x3c,0x6e,0xda,0x98,0x7f,0x22,0xee, + 0x78,0x8c,0x59,0xcb,0x9f,0xef,0x9d,0xb5,0x0e,0xfe,0x22,0x84,0xf7,0xdc,0x7a,0x55, + 0xad,0x92,0xa2,0xf9,0x33,0x54,0x0a,0x0f,0x70,0x06,0x6f,0x55,0x64,0xdb,0xdc,0xb0, + 0x21,0xb1,0x98,0x74,0x92,0x17,0xdc,0xf4,0x25,0xf8,0xe2,0x74,0xfe,0xd3,0x45,0x81, + 0xc0,0xbb,0x45,0xd4,0xd8,0x9b,0xd5,0xe5,0xca,0x64,0x14,0xe1,0xb2,0x7c,0x8d,0xd7, + 0x6b,0x35,0x93,0x44,0x21,0x9c,0x9b,0x36,0x21,0x57,0x8d,0xb5,0xff,0x37,0x56,0x80, + 0x64,0xa5,0xef,0x67,0x50,0xfa,0xc6,0x08,0xc9,0xf8,0x56,0xd2,0x12,0x5a,0xda,0x62, + 0xc0,0xa8,0xc8,0x6f,0x73,0x9d,0x9a,0xca,0x82,0x0b,0x58,0x82,0x33,0x8c,0x11,0xeb, + 0x53,0x87,0xf9,0x19,0x4d,0x99,0x49,0x25,0xe0,0x5e,0xe9,0x2c,0x30,0x2b,0x25,0x49, + 0x0a,0x93,0xdf,0x15,0x9b,0x4b,0xa2,0xc9,0xed,0x50,0x5d,0xa3,0x3f,0x8f,0xe2,0xbb, + 0xdf,0xb8,0x04,0x4e,0x51,0xde,0x5e,0xc9,0x83,0x1d,0xd0,0x40,0x93,0x5f,0xc4,0xda, + 0x73,0xb9,0x90,0x55,0x99,0x39,0xfe,0xeb,0x61,0x39,0x98,0x76,0x10,0xbf,0xf8,0x2b, + 0xac,0x6e,0xc3,0x3c,0xa8,0x28,0x4f,0x69,0x22,0x1c,0x87,0x8f,0xf0,0xd5,0x8f,0xdf, + 0x63,0x3d,0x48,0x2c,0xf1,0x29,0x61,0x87,0x23,0xa2,0xb7,0x0c,0xb5,0x5f,0x97,0x26, + 0x22,0xc0,0xde,0x83,0xfd,0x43,0x98,0xa8,0x94,0x54,0xe6,0xa3,0xbf,0x82,0x9f,0x13, + 0x88,0x8d,0x7a,0xb3,0xe2,0x5c,0xb8,0xf4,0xd7,0xc2,0x47,0x45,0x33,0x82,0x21,0x27, + 0x0b,0x80,0xb7,0x65,0x6b,0x0f,0x16,0x38,0xaf,0xb6,0x8f,0x92,0xbc,0xef,0x41,0xe2, + 0x8f,0x67,0xbf,0x87,0x7e,0x21,0xda,0xc8,0xe7,0xd3,0x42,0x48,0xbd,0x61,0x76,0x2c, + 0x89,0x02,0x0c,0xd5,0x18,0xae,0xa4,0x9c,0xbb,0x65,0x4b,0xc3,0xa1,0x19,0xe8,0x05, + 0x6c,0xfa,0xd6,0xf2,0x36,0x05,0x2e,0xf7,0xac,0xe7,0x43,0xc6,0x9b,0x4a,0x61,0x83, + 0x8a,0xc6,0x65,0x43,0xde,0xf5,0x33,0x90,0xc0,0x1b,0xe3,0x25,0x3d,0x94,0xed,0xa2, + 0x38,0x84,0xb7,0xcf,0x9f,0xa3,0x91,0x6e,0xe5,0x11,0x38,0x48,0x85,0x1a,0x7c,0x8e, + 0x8d,0x23,0x19,0xbf,0x12,0x07,0x30,0xd7,0x4c,0xcc,0xcc,0xbe,0xa9,0x4b,0x02,0x5c, + 0x51,0x7c,0xe8,0x9a,0x19,0x89,0x7f,0x9a,0x59,0x49,0xfe,0x2d,0x1f,0xab,0xe7,0x1c, + 0xe7,0x08,0x67,0xfc,0x96,0x0e,0xb3,0xd6,0xc4,0x3e,0x77,0xdc,0xd2,0x45,0xbd,0xe7, + 0x8d,0x3e,0x58,0x20,0xf1,0x70,0xe4,0x3f,0x4d,0x8b,0x13,0x22,0x21,0xb9,0xca,0xc0, + 0x65,0x18,0x66,0x3c,0xf5,0x3e,0x0d,0xca,0xfd,0x73,0x26,0xfd,0xff,0x33,0x34,0x55, + 0x4b,0xc3,0xf2,0x5b,0x1b,0xcd,0x89,0x04,0x87,0x7a,0x41,0xdb,0xa8,0x10,0x63,0xba, + 0x56,0xce,0xdd,0xcb,0xff,0xee,0x55,0xd4,0x33,0x6a,0x4c,0x5e,0x7f,0x11,0x0a,0xfb, + 0xd3,0x16,0xc2,0x2c,0x9d,0xc3,0x44,0x68,0x3d,0x52,0xed,0xf2,0x34,0x9d,0x25,0x71, + 0xee,0x3b,0xa5,0x77,0x3a,0x54,0x7f,0x53,0x2e,0x64,0x52,0xd4,0x9f,0x56,0x0b,0x63, + 0xc9,0x9d,0x79,0x67,0x3b,0x55,0xab,0x3a,0x47,0xa1,0x5f,0xa9,0xab,0x5e,0x42,0x8b, + 0xcf,0x57,0xfb,0x17,0x35,0xb6,0x6b,0x37,0x65,0x76,0xeb,0x35,0xf0,0x26,0x73,0xa0, + 0x25,0x38,0xf3,0x07,0x34,0x1e,0x6b,0xc0,0x8f,0x7b,0xda,0x46,0x27,0xb3,0xc0,0xb1, + 0xd3,0x9b,0xba,0x52,0x34,0x1f,0x0c,0x66,0x7a,0x1c,0xaa,0x6e,0xe4,0x5f,0x2a,0x47, + 0xce,0x97,0x8d,0x27,0x2d,0xb6,0xdc,0xe1,0x6d,0xb1,0xa2,0x67,0xe5,0x5e,0xd1,0xb0, + 0x5b,0x99,0x23,0xc6,0xdd,0xa4,0x55,0xfa,0x2e,0x94,0xb0,0x05,0x76,0x06,0x33,0x31, + 0xa3,0x12,0xbd,0xda,0x93,0x1a,0x43,0x8d,0x44,0xb2,0x3f,0x37,0x9c,0x15,0x14,0x9a, + 0xa9,0x8e,0xf0,0xdf,0x5e,0xb3,0x64,0x4a,0x3e,0x2d,0xc8,0x98,0x97,0x1d,0x70,0x95, + 0x7f,0xd7,0x99,0xa3,0xce,0xfb,0x45,0x3e,0x71,0x5a,0x8c,0xf8,0xef,0x56,0x04,0x91, + 0x74,0x2e,0xe4,0xb0,0xdc,0x65,0x25,0x55,0x14,0xd9,0xe9,0x9c,0xec,0x55,0x4e,0x3b, + 0x7b,0x24,0x2a,0x2f,0x40,0x1a,0x80,0x8a,0x4c,0x24,0x9c,0x4e,0x25,0xbb,0xd5,0x28, + 0x46,0xde,0xa6,0xff,0x1c,0x43,0x48,0x95,0xcd,0xae,0xf2,0x1f,0x6c,0xea,0x2a,0x29, + 0x25,0xc0,0xfc,0x26,0x3f,0xff,0x16,0x7c,0x93,0x9c,0x7b,0x62,0x83,0xff,0x19,0x4f, + 0x5b,0x3d,0xdd,0x6a,0x49,0x0b,0xf7,0xeb,0x2b,0xd0,0xa9,0x66,0xdd,0xfd,0x71,0xea, + 0x8c,0x0e,0x6a,0x6f,0x42,0x1e,0x93,0x7b,0x13,0xff,0x24,0xff,0x07,0x7e,0x5b,0x00, + 0x06,0x70,0x7f,0xa1,0xda,0x2d,0x75,0xce,0xd9,0xbd,0x55,0x57,0x7a,0x63,0xf7,0x6e, + 0x2f,0xde,0x77,0x6a,0x3f,0xfe,0x9a,0xdd,0x49,0x1a,0x47,0xb6,0xd1,0xe1,0x53,0x7e, + 0xe8,0x0f,0x7a,0x7a,0xf8,0x2f,0x3c,0xcc,0xc8,0x46,0xa9,0x31,0xa7,0x74,0xb6,0x21, + 0x00,0xac,0x36,0x24,0xd7,0x8c,0x7c,0xd8,0xc2,0x37,0x42,0xbf,0xae,0x61,0xc0,0x07, + 0x2c,0xd8,0x82,0xb7,0x50,0xaf,0x94,0x5a,0x2a,0xd9,0x11,0x7e,0x39,0x06,0x5a,0x02, + 0xe8,0xe7,0x0e,0x26,0x79,0xe7,0xdc,0x74,0x0f,0x04,0x18,0x68,0x38,0x57,0x95,0x1f, + 0x11,0x39,0xc0,0x74,0xdc,0x89,0xbd,0xf3,0xc2,0x4c,0xd5,0x67,0xe2,0xcd,0xf2,0xe1, + 0x5b,0xa8,0xb7,0xc1,0x5b,0x85,0x7f,0xf9,0x05,0xe3,0xea,0x84,0xc5,0x32,0xc7,0x76, + 0x6a,0xec,0x40,0x72,0x72,0x8a,0x55,0x26,0x1e,0x7c,0x31,0xbc,0x84,0xca,0x34,0x98, + 0x61,0xf8,0xcf,0xef,0x03,0xf4,0xd9,0x13,0x17,0x0b,0x5c,0x7e,0xd9,0xc2,0x7d,0x85, + 0x08,0x0b,0xfd,0x9c,0x65,0x8b,0xd4,0x06,0x92,0x1f,0xcd,0xb9,0x00,0xc1,0xf4,0x6b, + 0xa7,0xd4,0xdd,0x95,0x72,0x39,0x9e,0xb4,0x36,0x28,0xec,0x38,0xc7,0xc6,0x80,0x3b, + 0x2c,0x0f,0x62,0x5f,0x58,0x48,0x17,0xff,0x21,0xea,0x8c,0xe9,0x52,0x68,0x4b,0xb5, + 0x03,0x56,0xf2,0xaf,0x15,0x2e,0x7c,0xfc,0x9d,0xe9,0x84,0xf5,0xab,0xc6,0x7b,0x68, + 0xa8,0x9e,0xfb,0xbe,0x9c,0x4b,0x57,0x98,0x08,0x6e,0x12,0x9c,0xdc,0x9e,0x2e,0xb0, + 0x88,0x0b,0x28,0xa6,0xc9,0x6f,0x9f,0xe6,0xa0,0xf9,0x1a,0x2b,0xb0,0x0d,0x12,0xe2, + 0xdf,0xcd,0xc4,0xbb,0x38,0x5c,0x50,0xd3,0x6a,0x3e,0xac,0xb0,0x07,0x66,0xc9,0x63, + 0x3f,0xcc,0xab,0x15,0xcc,0xb0,0x3a,0x24,0xe5,0xf5,0x47,0x3e,0x0e,0x7b,0xd1,0x7f, + 0x5d,0xb3,0xad,0x47,0x6c,0x30,0x77,0xa1,0xe1,0xeb,0x4a,0x67,0x70,0xf2,0x5b,0x1d, + 0x4a,0x41,0xcd,0x66,0xab,0xbe,0x5b,0xb6,0x40,0x8c,0x3e,0x25,0x2d,0xd1,0x16,0x4b, + 0x95,0x28,0x06,0xc5,0x59,0xd6,0x0a,0xfa,0x62,0xf0,0x2f,0xc3,0xd3,0x8b,0x6c,0xc4, + 0x1c,0x35,0xec,0xc9,0x58,0xb7,0xde,0x36,0xf1,0x51,0xe9,0x7c,0x75,0x05,0xfa,0x8a, + 0x9d,0x36,0xa4,0x34,0xa0,0x31,0xc3,0xfa,0x89,0x22,0x60,0x71,0x46,0x94,0x94,0x5a, + 0x98,0x1d,0xac,0x24,0xf9,0x35,0x5a,0xb7,0x71,0xfc,0x96,0x0e,0x03,0x78,0x38,0x2c, + 0x0a,0x15,0xd4,0x07,0xd3,0x2a,0xa2,0xca,0x97,0x2d,0xa8,0x34,0x8c,0x0a,0xd3,0x99, + 0x1e,0x2f,0x8e,0x9e,0x3d,0xc2,0x5b,0x3c,0x75,0xc3,0x35,0x19,0xac,0x67,0x13,0x29, + 0xf8,0x0a,0xd7,0x85,0xf8,0xc1,0xd1,0x87,0xfa,0x6f,0xce,0xa9,0x75,0x19,0x52,0x59, + 0x29,0xcb,0x0f,0x82,0xaf,0xce,0x60,0x83,0x4a,0x19,0xe2,0x8d,0x78,0xd4,0xe3,0x51, + 0xbe,0xce,0x98,0x58,0x32,0x97,0x75,0xe8,0xa2,0xbd,0x16,0xf4,0x29,0xd8,0xff,0x44, + 0x93,0xef,0x9e,0xaf,0x39,0xbf,0xb6,0x72,0x08,0x7d,0x7a,0x82,0xd8,0x18,0x62,0x54, + 0x16,0xac,0x01,0x47,0xd1,0x2c,0x70,0x18,0x76,0xbe,0x16,0xeb,0x32,0x4c,0x8f,0xd4, + 0xb5,0xe0,0xd7,0x50,0xf9,0x36,0x49,0x64,0x00,0xad,0x60,0x1f,0x98,0x3f,0x17,0x32, + 0x77,0x80,0x9e,0x96,0x7f,0xaf,0x56,0x40,0xb3,0x3d,0xe4,0x86,0xf5,0x20,0x3e,0x70, + 0xfa,0x5c,0xbe,0x9b,0xfe,0xd3,0xec,0xcc,0xb8,0x60,0x98,0x26,0x22,0xf7,0xe1,0x0e, + 0xe6,0x7f,0x21,0x35,0x60,0xad,0x27,0x41,0x3b,0x1f,0x6a,0xad,0xab,0xe5,0xfd,0xed, + 0x78,0x02,0x12,0xa6,0x83,0x0c,0xfb,0xc0,0x83,0x1e,0x66,0x97,0x01,0x61,0xe3,0x31, + 0x3a,0x05,0x62,0x41,0x4c,0xe4,0x71,0x10,0xad,0x52,0x70,0x64,0x06,0x4f,0x0d,0xbc, + 0x9e,0x78,0x08,0x69,0x33,0xcb,0xbe,0x45,0x2c,0x60,0xcb,0x87,0x41,0xf9,0x29,0xbc, + 0x67,0x05,0xe7,0xb6,0x15,0xa8,0x57,0xf7,0x22,0x62,0x31,0x7a,0xbd,0xd4,0x44,0xbe, + 0x8f,0xf3,0xa9,0x68,0x9f,0xcb,0x59,0x00,0xaf,0x6c,0xa7,0xf2,0xd3,0x6a,0x0a,0xf9, + 0x12,0x55,0x63,0x9f,0x16,0xac,0x64,0xbb,0xa7,0x6a,0x15,0xbf,0x37,0x2a,0x9d,0x82, + 0xf0,0xea,0x2e,0x82,0x9e,0xa7,0x7f,0x44,0x27,0xdb,0x9a,0xeb,0xa7,0xa9,0x71,0x1c, + 0x67,0xd8,0x80,0x9e,0x9a,0xea,0x8c,0x1a,0xd6,0x65,0x94,0xde,0x92,0x66,0x4d,0x79, + 0x7a,0x76,0x4b,0x20,0xb9,0xc5,0x45,0xb3,0x05,0x9a,0x2e,0x4c,0xf7,0xe8,0x25,0x44, + 0x58,0xb8,0xca,0x8c,0xc2,0xae,0x0a,0x62,0xae,0x63,0x8c,0xef,0xb7,0xce,0x69,0xda, + 0xe6,0xfc,0xae,0xaf,0x5d,0xbb,0x38,0x09,0x45,0xcc,0xb2,0x6d,0x15,0xa9,0xa4,0x49, + 0xd0,0x8d,0xdd,0xee,0xbc,0xa3,0x41,0x18,0xcc,0xc5,0x5f,0xfc,0xd8,0xe4,0x79,0x9b, + 0x70,0x02,0xb5,0xce,0x1d,0x04,0x43,0x66,0x4a,0xd9,0xdd,0xef,0x53,0xe2,0x1a,0xaf, + 0x44,0x9a,0x32,0x7a,0x34,0x05,0x37,0x7a,0xac,0xa2,0x72,0xd8,0x16,0x44,0xd5,0xd9, + 0xd8,0xad,0x29,0x26,0xc8,0x10,0x87,0x50,0xc9,0x2c,0x82,0x17,0x57,0xfc,0xda,0xf1, + 0xc6,0xa4,0xb3,0x7f,0xb4,0xf0,0x95,0xb0,0xf2,0xb6,0xcb,0x33,0x74,0xc3,0xf0,0x92, + 0x39,0x21,0x95,0x64,0xe7,0x6e,0x45,0x43,0xed,0x72,0x3f,0x4b,0x67,0x08,0xb0,0x51, + 0x87,0x4b,0x76,0x56,0x17,0x97,0x4e,0x53,0x30,0x7b,0xe2,0x77,0x9d,0x56,0xd7,0x77, + 0xd0,0x68,0xee,0x36,0x76,0x1e,0x49,0x6f,0x61,0xa5,0xbe,0x06,0x73,0x54,0xda,0xf2, + 0x07,0x69,0xa7,0xa7,0xc4,0x37,0xb6,0xcc,0xbc,0x89,0xcf,0x56,0xb4,0x59,0x7b,0x42, + 0x4c,0x35,0x2d,0xcb,0xdc,0x85,0xb8,0x0c,0xc9,0x71,0xbc,0x04,0xe5,0x7a,0x87,0x16, + 0xb4,0x6a,0x72,0x7d,0x22,0x03,0xf1,0x59,0x32,0x55,0xce,0xac,0x3c,0x23,0x6e,0xe9, + 0x11,0x18,0x6f,0x5e,0x31,0xf9,0x8b,0x23,0xda,0xec,0xfc,0xa1,0x37,0x54,0x07,0x16, + 0x8e,0x0a,0xa5,0xf4,0x33,0x1c,0x61,0x37,0x07,0x08,0xd6,0x52,0xdf,0x2e,0x67,0x64, + 0x4c,0x18,0x29,0xab,0x47,0x3b,0xf8,0x3f,0xf1,0xa9,0xfc,0x81,0xe3,0xe0,0xdd,0x7b, + 0x6c,0x33,0xd5,0x3f,0x28,0xb7,0x4e,0x14,0x93,0x7d,0xa0,0x7b,0x95,0x1e,0x10,0xdd, + 0x8e,0x32,0x3c,0x2f,0x39,0x4d,0x85,0x85,0x07,0x7f,0x7e,0xcc,0x8b,0xf2,0x25,0xd8, + 0xe4,0xda,0xb9,0x4a,0xb6,0xba,0x4f,0x14,0x1b,0xbd,0xc9,0x6a,0x95,0xf1,0xaf,0xfc, + 0x0e,0x30,0xb1,0x56,0x4f,0x14,0x01,0x6a,0x1a,0x7c,0xe9,0x73,0x14,0xad,0xbb,0xb1, + 0x1a,0xaf,0x9a,0x00,0x31,0x40,0x06,0xb8,0xab,0xd2,0x38,0x3c,0xd2,0x56,0x3d,0x63, + 0x03,0x88,0xe0,0x92,0xed,0x60,0xdd,0x43,0x7d,0xe0,0x9a,0xf2,0x45,0x65,0x44,0x10, + 0x8a,0x06,0x01,0x0d,0x9e,0x2c,0xaa,0x90,0xde,0xed,0xd9,0x47,0xf2,0xaf,0x0b,0x71, + 0x8d,0x43,0xa1,0x77,0x10,0x2c,0x0a,0xc2,0xc7,0xce,0x19,0x73,0xc5,0x65,0x10,0x5f, + 0x6e,0x1f,0xfa,0xc3,0xbe,0x38,0x38,0x67,0xc1,0x4b,0x34,0x97,0xf1,0xef,0xd1,0xb8, + 0xbc,0x48,0xe6,0x53,0x86,0x2a,0xef,0x98,0xbc,0xc8,0x3f,0x87,0xf0,0x38,0x39,0x33, + 0x25,0x02,0xef,0x43,0x03,0x7a,0x39,0x03,0xe4,0x0a,0xd5,0xe2,0xf6,0x1b,0x37,0xf4, + 0x91,0x4a,0x7d,0x1f,0x5a,0x63,0xa3,0xbb,0x38,0xec,0x3a,0x31,0x70,0x5a,0x07,0x1d, + 0xf3,0xb5,0xaa,0x0b,0x99,0x6c,0x6c,0xa9,0xa1,0x6a,0xf7,0xec,0xf9,0xe2,0x39,0xe9, + 0x5f,0x18,0x8b,0x9e,0x18,0xd6,0x04,0x4b,0x6d,0x42,0x41,0x28,0x22,0x6f,0x5b,0x45, + 0xe3,0xb8,0xab,0xcf,0xf3,0x24,0xbf,0xba,0xce,0x40,0x44,0xcf,0xa7,0x6a,0x55,0x94, + 0x79,0xa0,0xb3,0x3d,0x38,0x4b,0xdd,0x2a,0x9b,0x0f,0xc0,0x3d,0x5b,0x23,0xbd,0xe8, + 0xe7,0x8c,0xeb,0x02,0xd3,0x48,0x62,0x37,0x21,0x78,0xb5,0x28,0xf9,0x71,0x91,0x58, + 0xdf,0x4c,0x74,0x5e,0xed,0x5a,0xda,0x74,0x8c,0x0d,0x36,0xfc,0xa7,0x4d,0x98,0x48, + 0x0a,0x4e,0x6a,0x92,0x23,0xf0,0x53,0x98,0x42,0xb1,0xb0,0x3c,0x79,0x2f,0xf4,0xf9, + 0x6e,0x8f,0xcf,0x49,0x03,0x6b,0x58,0x78,0x2a,0x29,0x77,0x3f,0x58,0xbb,0x41,0x1f, + 0x4b,0x42,0x3c,0x77,0x58,0x22,0xd5,0xa6,0xa8,0x62,0x84,0xc6,0xc3,0x15,0x34,0x6f, + 0xc8,0xd2,0x34,0x6b,0x3f,0x77,0xdc,0xbd,0x24,0xf1,0x65,0x93,0xd0,0x0e,0x6f,0xf2, + 0xce,0xb3,0x3d,0x76,0xc8,0x20,0xb1,0xdf,0x3c,0x5d,0xad,0x4e,0x5c,0x7f,0xd9,0x6f, + 0x5c,0xb2,0x8a,0xea,0x93,0xde,0xde,0xc2,0xb7,0x58,0x31,0x31,0xed,0x97,0x96,0x48, + 0x87,0xbb,0xe3,0x26,0xd2,0xe5,0x7d,0xe7,0x63,0xd4,0x5b,0x60,0x2a,0x66,0x32,0x60, + 0x33,0x58,0xb5,0xf3,0x92,0x24,0xd6,0x06,0xbc,0xd8,0x9d,0xcb,0x45,0x37,0x93,0x29, + 0x45,0x5b,0x3e,0xe1,0x7b,0x39,0x2f,0x35,0x62,0x76,0x62,0x4c,0xf4,0xc6,0x33,0x60, + 0x81,0x07,0xb5,0x86,0x10,0x28,0x7d,0xfc,0xeb,0x17,0xda,0x7d,0x0f,0xe4,0xc7,0x7b, + 0x3e,0xc5,0x02,0x4b,0xb8,0x18,0x96,0xb9,0x32,0xf7,0xce,0x0d,0x13,0x49,0x30,0xa5, + 0x41,0x1a,0xde,0xea,0x35,0x57,0x26,0x47,0x47,0xff,0x63,0xda,0x92,0x88,0x51,0x00, + 0x43,0x28,0x2b,0x0b,0xa8,0xc7,0xb7,0xba,0xb2,0x3e,0x93,0xaf,0x88,0x61,0x71,0x1d, + 0x29,0xea,0xaf,0x9c,0x34,0x7d,0x27,0x47,0x14,0xfa,0xde,0xdb,0x12,0x78,0x87,0xbb, + 0x0c,0x1f,0xf8,0xca,0x70,0x78,0x54,0xe0,0x68,0x5d,0xf6,0x65,0x86,0x0f,0xdd,0x78, + 0x7b,0x0d,0xf6,0x74,0x98,0x7c,0x32,0x8a,0x1c,0x7d,0x18,0xd3,0x2a,0xdd,0x7f,0xc1, + 0x62,0x1d,0x9f,0xc9,0xf0,0x5a,0x5f,0xeb,0x68,0xee,0x91,0x40,0x07,0x77,0x6f,0x59, + 0x63,0xee,0x3a,0xdc,0xaf,0x0b,0xbb,0x99,0x19,0x3a,0x54,0x8e,0xae,0x2a,0x63,0xe2, + 0xcc,0x52,0x20,0x0a,0x67,0xbb,0x16,0xaf,0xc8,0xcd,0xa0,0x44,0xe7,0x85,0x10,0xed, + 0x2b,0x27,0x2c,0x12,0x0d,0x4f,0xf9,0x34,0x8d,0xf3,0x41,0x11,0xf4,0x9e,0x81,0x10, + 0xde,0xe6,0xdb,0x61,0xd6,0xa9,0xce,0x04,0x65,0x66,0x89,0xcc,0x78,0xef,0x11,0xed, + 0x78,0x22,0xbb,0x26,0xb6,0xc3,0x9d,0x6c,0x66,0xa6,0x15,0xb3,0xc9,0x07,0xbf,0x43, + 0x86,0xc4,0x41,0x41,0xb7,0xe5,0xc4,0x88,0xa7,0xa2,0xa5,0x79,0x60,0x50,0x31,0xbc, + 0xa2,0x7a,0x1d,0xa8,0x13,0xc8,0x58,0x73,0xe0,0xd5,0xf3,0x76,0x3c,0x5d,0xbe,0x43, + 0x5a,0xa5,0xa9,0x43,0x7b,0xe7,0xc5,0x23,0xca,0x09,0x24,0x68,0xa4,0x4d,0x39,0x20, + 0xc7,0x5c,0x79,0x5c,0x13,0xf3,0x96,0x81,0x47,0xf6,0xf9,0x86,0x82,0x54,0x1a,0xf5, + 0xf9,0xeb,0x22,0x02,0x04,0x29,0x8d,0xc8,0xcc,0x2a,0xea,0x3e,0xb7,0xd9,0x54,0x82, + 0xf8,0x2a,0x2b,0xfb,0x2e,0xd6,0xff,0x3d,0xec,0x16,0x61,0x2a,0x26,0xef,0xd8,0x74, + 0xe4,0x18,0xc8,0x6f,0x90,0xea,0x15,0xb3,0x48,0x6e,0x93,0x76,0xa3,0xca,0xee,0xe8, + 0x93,0x20,0x13,0xec,0xad,0xb9,0x8f,0x59,0x32,0x6f,0xe0,0x3f,0x5f,0xa3,0x66,0x48, + 0x0a,0x57,0x46,0x3c,0x90,0xed,0x48,0xed,0xe2,0xd3,0x2d,0x90,0x29,0x1b,0x20,0xc7, + 0xe4,0x9e,0xdb,0xbc,0xc2,0x39,0x53,0x3d,0x61,0x41,0xe2,0x88,0xb6,0x9e,0x63,0x55, + 0xa8,0x73,0x5c,0x54,0x3d,0x2b,0x39,0x7e,0xae,0x5e,0x33,0x77,0x26,0x13,0x32,0xb0, + 0x2a,0x20,0x93,0x6d,0xaf,0x73,0x31,0x66,0x8e,0xce,0xe9,0x18,0x20,0x40,0x7a,0x1b, + 0xd4,0x3b,0x21,0x6e,0x87,0xfd,0x0c,0x5d,0x91,0xb3,0xf5,0xc0,0x9f,0x81,0x1f,0x63, + 0x77,0x5d,0x40,0x94,0x3d,0xdd,0x42,0x2a,0x90,0x72,0x82,0x8b,0x1d,0xf2,0xe6,0x47, + 0xcf,0xe0,0x5a,0x27,0x5d,0xd2,0xce,0xdc,0x8c,0x40,0xf4,0xc1,0x1f,0x63,0x0b,0x0f, + 0x21,0x37,0x4d,0x9e,0x48,0x39,0xf8,0x40,0xfb,0x58,0xc3,0x83,0x1c,0x82,0xf7,0x62, + 0x76,0x34,0x44,0xc8,0xba,0xb9,0x8b,0x32,0x18,0xd7,0xfb,0x06,0x72,0x54,0x6d,0xd0, + 0x2b,0x31,0x7c,0x16,0x73,0x51,0x87,0x80,0xe9,0xb0,0x79,0x7b,0x88,0xb7,0x43,0xfb, + 0x92,0x92,0x9b,0x25,0x1a,0xbb,0x4b,0xea,0xa5,0x24,0xfa,0x77,0x4d,0xb4,0xfa,0xef, + 0x6f,0xe6,0x95,0xde,0x5a,0x85,0x65,0xf2,0xb3,0x2b,0xfa,0x7f,0x77,0xba,0x61,0x8d, + 0x8d,0x67,0x65,0xc9,0x32,0x17,0xb6,0x9b,0x7a,0x77,0xa0,0x96,0x97,0x79,0x91,0xab, + 0x8c,0x66,0x96,0x3e,0xd0,0x39,0x40,0x33,0x25,0xfb,0xee,0xfe,0x3d,0x0c,0xf3,0x18, + 0x0d,0x45,0x33,0x0d,0x26,0xb0,0xf6,0xd9,0x86,0xe8,0x89,0x92,0x73,0x5c,0x94,0x3e, + 0x5a,0x66,0x47,0x87,0x3d,0xfb,0x1f,0x29,0xb5,0x66,0x28,0xbd,0xf9,0x0e,0xf7,0x0c, + 0x2e,0x9a,0x76,0x61,0xc9,0x5c,0x3c,0xa8,0x06,0xd1,0xc8,0xb3,0x9d,0x03,0x16,0x7a, + 0xd0,0x22,0x52,0x57,0x1b,0x89,0x44,0x7d,0xc3,0x82,0x09,0x00,0x9e,0xf2,0x6f,0xa5, + 0xcd,0xbe,0x5b,0x3c,0x1d,0x8e,0x6f,0xc1,0xef,0xc9,0x37,0xf6,0xec,0xf8,0x07,0x19, + 0x2c,0xdb,0x4f,0xd1,0x33,0x32,0x45,0x7c,0x43,0xc0,0x97,0x3d,0x79,0x0a,0x90,0x46, + 0xfc,0xab,0xc4,0x80,0x10,0xe1,0xeb,0x3b,0xbf,0xeb,0x26,0x46,0xa7,0x66,0xf4,0xe0, + 0x09,0x0e,0x48,0x10,0xe2,0x25,0x9c,0xc1,0xfe,0xc1,0x7b,0x73,0x8f,0x69,0x70,0x00, + 0x02,0x0a,0xa1,0x1d,0x6c,0x41,0xec,0x88,0xe2,0x9d,0x99,0x12,0x71,0x0e,0xe1,0x3b, + 0x06,0xf6,0x8f,0x2a,0xbf,0x61,0x47,0xde,0xc7,0xe8,0x1d,0xf2,0x51,0x43,0x40,0x40, + 0x02,0x04,0xc0,0x44,0x12,0x24,0x50,0x60,0x42,0x44,0xd0,0x64,0x52,0x64,0x48,0x50, + 0x03,0x05,0xc8,0x54,0x13,0x25,0x58,0x70,0x43,0x45,0xd8,0x74,0x53,0x65,0x41,0x41, + 0x82,0x06,0xc1,0x45,0x92,0x26,0x51,0x61,0xc2,0x46,0xd1,0x65,0xd2,0x66,0x49,0x51, + 0x83,0x07,0xc9,0x55,0x93,0x27,0x59,0x71,0xc3,0x47,0xd9,0x75,0xd3,0x67,0x62,0x4c, + 0x04,0x83,0x04,0x21,0x2b,0x27,0xef,0xb9,0x23,0x37,0x3e,0xec,0xfb,0x29,0x8a,0x7a, + 0x48,0x49,0xea,0x7c,0x53,0x24,0x44,0xd7,0x1b,0xe2,0x36,0x7e,0xda,0xc4,0x84,0xeb, + 0x0a,0x42,0xd9,0x08,0x3f,0x6b,0x90,0x89,0x7b,0xf5,0x7f,0xad,0x24,0x4a,0x73,0x7b, + 0xca,0xd4,0x27,0x8f,0x98,0x21,0xe6,0x3c,0xa2,0x34,0x8b,0xdd,0x91,0x6b,0x42,0x48, + 0x0a,0x0c,0xc2,0x4c,0x1a,0x2c,0x52,0x68,0x4a,0x4c,0xd2,0x6c,0x5a,0x6c,0x4a,0x58, + 0x0b,0x0d,0xca,0x5c,0x1b,0x2d,0x5a,0x78,0x4b,0x4d,0xda,0x7c,0x5b,0x6d,0x43,0x49, + 0x8a,0x0e,0xc3,0x4d,0x9a,0x2e,0x53,0x69,0xca,0x4e,0xd3,0x6d,0xda,0x6e,0x4b,0x59, + 0x8b,0x0f,0xcb,0x5d,0x9b,0x2f,0x5b,0x79,0xcb,0x4f,0xdb,0x7d,0xdb,0x6f,0xdf,0xf2, + 0x9f,0xaf,0x68,0x04,0xcc,0x10,0xb4,0xb3,0x63,0x34,0xf6,0x24,0x70,0x30,0x6d,0xe2, + 0xde,0xce,0xb4,0x67,0x33,0x95,0x3c,0xb1,0xec,0x17,0x26,0xb6,0xde,0x77,0xfa,0x7f, + 0xa6,0x62,0x29,0x07,0xb1,0x27,0x2d,0x41,0xec,0x3c,0xb5,0x4f,0xf6,0xe2,0xcd,0x89, + 0x59,0x9e,0xe2,0x14,0x79,0xed,0x9e,0x11,0xb5,0x63,0x95,0x6a,0x10,0x7c,0x44,0xc0, + 0x22,0x14,0xc4,0xc4,0x32,0x34,0x54,0xe0,0x62,0x54,0xd4,0xe4,0x72,0x74,0x4c,0xd0, + 0x23,0x15,0xcc,0xd4,0x33,0x35,0x5c,0xf0,0x63,0x55,0xdc,0xf4,0x73,0x75,0x45,0xc1, + 0xa2,0x16,0xc5,0xc5,0xb2,0x36,0x55,0xe1,0xe2,0x56,0xd5,0xe5,0xf2,0x76,0x4d,0xd1, + 0xa3,0x17,0xcd,0xd5,0xb3,0x37,0x5d,0xf1,0xe3,0x57,0xdd,0xf5,0xf3,0x77,0xf9,0x76, + 0x2e,0xa8,0x46,0x9f,0xe7,0x5a,0x30,0x69,0xec,0xfc,0x06,0xad,0x58,0x78,0xce,0x98, + 0x6d,0x58,0x3d,0x18,0xc1,0x1b,0x66,0x3c,0x31,0x25,0x9e,0xbc,0x79,0x79,0x32,0xfb, + 0x57,0xc5,0x67,0xb2,0x44,0x58,0x5f,0xae,0x8b,0x7a,0x97,0xad,0xf8,0x7a,0xe3,0x19, + 0x55,0x3b,0xbc,0x1d,0x9d,0x55,0xaf,0xa5,0x08,0x38,0x9f,0xbd,0xf9,0x7b,0x46,0xc8, + 0x2a,0x1c,0xc6,0xcc,0x3a,0x3c,0x56,0xe8,0x6a,0x5c,0xd6,0xec,0x7a,0x7c,0x4e,0xd8, + 0x2b,0x1d,0xce,0xdc,0x3b,0x3d,0x5e,0xf8,0x6b,0x5d,0xde,0xfc,0x7b,0x7d,0x47,0xc9, + 0xaa,0x1e,0xc7,0xcd,0xba,0x3e,0x57,0xe9,0xea,0x5e,0xd7,0xed,0xfa,0x7e,0x4f,0xd9, + 0xab,0x1f,0xcf,0xdd,0xbb,0x3f,0x5f,0xf9,0xeb,0x5f,0xdf,0xfd,0xfb,0x7f,0x58,0x80, + 0x01,0x60,0x5e,0x84,0xea,0x1f,0x60,0x82,0xf7,0x7f,0xee,0x31,0x5c,0xe0,0xa0,0x06, + 0xa4,0x09,0xd6,0x10,0xf4,0x22,0x50,0xf0,0xc3,0x34,0x28,0xf1,0x57,0x14,0x7b,0x1e, + 0x27,0x84,0x99,0xf9,0xf4,0xae,0x82,0xdd,0x38,0x3d,0xd9,0xe5,0x52,0x17,0xa9,0xf1, + 0x24,0x09,0xde,0xe4,0x19,0x5e,0xa9,0xf4,0xc7,0x36,0xbd,0x70,0x54,0xed,0x60,0x42, + 0x06,0x84,0xe0,0x46,0x16,0xa4,0x70,0x62,0x46,0xc4,0xf0,0x66,0x56,0xe4,0x68,0x52, + 0x07,0x85,0xe8,0x56,0x17,0xa5,0x78,0x72,0x47,0xc5,0xf8,0x76,0x57,0xe5,0x61,0x43, + 0x86,0x86,0xe1,0x47,0x96,0xa6,0x71,0x63,0xc6,0xc6,0xf1,0x67,0xd6,0xe6,0x69,0x53, + 0x87,0x87,0xe9,0x57,0x97,0xa7,0x79,0x73,0xc7,0xc7,0xf9,0x77,0xd7,0xe7,0xd9,0xe8, + 0x0a,0x38,0xda,0x70,0x5c,0x22,0x36,0x6d,0xcd,0xc6,0x0d,0x8e,0xfd,0x48,0xba,0x9e, + 0x55,0x81,0xd2,0x9c,0x3c,0xdb,0xfa,0x23,0x12,0x34,0x39,0xfc,0xde,0xaf,0xd0,0x6b, + 0xec,0x81,0x74,0x8d,0x62,0x15,0x90,0xeb,0x10,0xe0,0x34,0x90,0xdc,0xca,0xf4,0x17, + 0x8b,0x3b,0xf1,0x1e,0x3e,0xea,0x23,0xd5,0x05,0xe1,0x0c,0x1b,0xdb,0x5b,0x62,0x4a, + 0x0e,0x8c,0xe2,0x4e,0x1e,0xac,0x72,0x6a,0x4e,0xcc,0xf2,0x6e,0x5e,0xec,0x6a,0x5a, + 0x0f,0x8d,0xea,0x5e,0x1f,0xad,0x7a,0x7a,0x4f,0xcd,0xfa,0x7e,0x5f,0xed,0x63,0x4b, + 0x8e,0x8e,0xe3,0x4f,0x9e,0xae,0x73,0x6b,0xce,0xce,0xf3,0x6f,0xde,0xee,0x6b,0x5b, + 0x8f,0x8f,0xeb,0x5f,0x9f,0xaf,0x7b,0x7b,0xcf,0xcf,0xfb,0x7f,0xdf,0xef,0x88,0xc0, + 0xa7,0x44,0xe4,0xb9,0x3c,0xdc,0xcb,0x60,0xe7,0x96,0xb4,0xa6,0x74,0xf0,0xd1,0x3b, + 0x07,0x4e,0x43,0x66,0x6d,0xbe,0x2e,0x12,0x3d,0x83,0xbc,0xb6,0x75,0xf1,0xde,0x9c, + 0x5b,0x39,0x8d,0x45,0x36,0xba,0x82,0x87,0xc6,0xe2,0xb5,0xa7,0xf4,0xf2,0xa9,0x62, + 0x1a,0x13,0xcd,0xd7,0x4e,0xbe,0x0a,0x1b,0x19,0xb0,0xbd,0xb7,0xf5,0xf3,0x64,0xc2, + 0x26,0x94,0xe4,0xc6,0x36,0xb4,0x74,0xe2,0x66,0xd4,0xf4,0xe6,0x76,0xf4,0x6c,0xd2, + 0x27,0x95,0xec,0xd6,0x37,0xb5,0x7c,0xf2,0x67,0xd5,0xfc,0xf6,0x77,0xf5,0x65,0xc3, + 0xa6,0x96,0xe5,0xc7,0xb6,0xb6,0x75,0xe3,0xe6,0xd6,0xf5,0xe7,0xf6,0xf6,0x6d,0xd3, + 0xa7,0x97,0xed,0xd7,0xb7,0xb7,0x7d,0xf3,0xe7,0xd7,0xfd,0xf7,0xf7,0xf7,0x78,0x65, + 0x2a,0x33,0xd4,0x97,0x7c,0x43,0xf6,0xbb,0x12,0x75,0xb6,0xae,0x7c,0xf8,0x2d,0x3a, + 0x9e,0x26,0xae,0x5c,0xbe,0xff,0x66,0x32,0x84,0xca,0xbe,0xbe,0x7d,0xf9,0xda,0x1a, + 0xc7,0xe5,0xa3,0x8d,0xb8,0x41,0x26,0x3b,0x85,0xb9,0xb7,0xaf,0xfc,0xfa,0x71,0x74, + 0xbb,0x0f,0x18,0xbb,0x3f,0xb3,0x93,0x29,0xe9,0xd3,0xbf,0xbf,0xfd,0xfb,0x66,0xca, + 0x2e,0x9c,0xe6,0xce,0x3e,0xbc,0x76,0xea,0x6e,0xdc,0xf6,0xee,0x7e,0xfc,0x6e,0xda, + 0x2f,0x9d,0xee,0xde,0x3f,0xbd,0x7e,0xfa,0x6f,0xdd,0xfe,0xfe,0x7f,0xfd,0x67,0xcb, + 0xae,0x9e,0xe7,0xcf,0xbe,0xbe,0x77,0xeb,0xee,0xde,0xf7,0xef,0xfe,0xfe,0x6f,0xdb, + 0xaf,0x9f,0xef,0xdf,0xbf,0xbf,0x7f,0xfb,0xef,0xdf,0xff,0xff,0x88,0x9f,*/ +}; +#endif + +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/gt9xx/gt9xx_update.c b/drivers/input/touchscreen/gt9xx/gt9xx_update.c new file mode 100644 index 000000000000..72a64426c8fc --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/gt9xx_update.c @@ -0,0 +1,3614 @@ +/* drivers/input/touchscreen/gt9xx_update.c + * + * 2010 - 2012 Goodix Technology. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Latest Version: 2.2 + * Author: andrew@goodix.com + * Revision Record: + * V1.0: + * first release. By Andrew, 2012/08/31 + * V1.2: + * add force update,GT9110P pid map. By Andrew, 2012/10/15 + * V1.4: + * 1. add config auto update function; + * 2. modify enter_update_mode; + * 3. add update file cal checksum. + * By Andrew, 2012/12/12 + * V1.6: + * 1. replace guitar_client with i2c_connect_client; + * 2. support firmware header array update. + * By Meta, 2013/03/11 + * V2.2: + * 1. multi-system supported + * 2. flashless update no pid vid compare + * By Meta, 2014/01/14 + */ +#include +#include "gt9xx.h" + +#include +#include +#if ((GTP_AUTO_UPDATE && GTP_HEADER_FW_UPDATE) || GTP_COMPATIBLE_MODE) + #include "gt9xx_firmware.h" +#endif + +#define GUP_REG_HW_INFO 0x4220 +#define GUP_REG_FW_MSG 0x41E4 +#define GUP_REG_PID_VID 0x8140 + +#define GUP_SEARCH_FILE_TIMES 50 + +#define UPDATE_FILE_PATH_1 "/data/_goodix_update_.bin" +#define UPDATE_FILE_PATH_2 "/sdcard/_goodix_update_.bin" + +#define CONFIG_FILE_PATH_1 "/data/_goodix_config_.cfg" +#define CONFIG_FILE_PATH_2 "/sdcard/_goodix_config_.cfg" + +#define FW_HEAD_LENGTH 14 +#define FW_SECTION_LENGTH 0x2000 // 8K +#define FW_DSP_ISP_LENGTH 0x1000 // 4K +#define FW_DSP_LENGTH 0x1000 // 4K +#define FW_BOOT_LENGTH 0x800 // 2K +#define FW_SS51_LENGTH (4 * FW_SECTION_LENGTH) // 32K +#define FW_BOOT_ISP_LENGTH 0x800 // 2k +#define FW_GLINK_LENGTH 0x3000 // 12k +#define FW_GWAKE_LENGTH (4 * FW_SECTION_LENGTH) // 32k + +#define PACK_SIZE 256 +#define MAX_FRAME_CHECK_TIME 5 + + +#define _bRW_MISCTL__SRAM_BANK 0x4048 +#define _bRW_MISCTL__MEM_CD_EN 0x4049 +#define _bRW_MISCTL__CACHE_EN 0x404B +#define _bRW_MISCTL__TMR0_EN 0x40B0 +#define _rRW_MISCTL__SWRST_B0_ 0x4180 +#define _bWO_MISCTL__CPU_SWRST_PULSE 0x4184 +#define _rRW_MISCTL__BOOTCTL_B0_ 0x4190 +#define _rRW_MISCTL__BOOT_OPT_B0_ 0x4218 +#define _rRW_MISCTL__BOOT_CTL_ 0x5094 + +#define AUTO_SEARCH_BIN 0x01 +#define AUTO_SEARCH_CFG 0x02 +#define BIN_FILE_READY 0x80 +#define CFG_FILE_READY 0x08 +#define HEADER_FW_READY 0x00 + +#pragma pack(1) +typedef struct +{ + u8 hw_info[4]; //hardware info// + u8 pid[8]; //product id // + u16 vid; //version id // +}st_fw_head; +#pragma pack() + +typedef struct +{ + u8 force_update; + u8 fw_flag; + struct file *file; + struct file *cfg_file; + st_fw_head ic_fw_msg; + mm_segment_t old_fs; + u32 fw_total_len; + u32 fw_burned_len; +}st_update_msg; + +st_update_msg update_msg; +u16 show_len; +u16 total_len; +u8 got_file_flag = 0; +u8 searching_file = 0; + +extern u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH]; +extern void gtp_reset_guitar(struct i2c_client *client, s32 ms); +extern s32 gtp_send_cfg(struct i2c_client *client); +extern s32 gtp_read_version(struct i2c_client *, u16* ); +extern struct i2c_client * i2c_connect_client; +extern void gtp_irq_enable(struct goodix_ts_data *ts); +extern void gtp_irq_disable(struct goodix_ts_data *ts); +extern s32 gtp_i2c_read_dbl_check(struct i2c_client *, u16, u8 *, int); +static u8 gup_burn_fw_gwake_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u32 len, u8 bank_cmd ); + +#define _CLOSE_FILE(p_file) if (p_file && !IS_ERR(p_file)) \ + { \ + filp_close(p_file, NULL); \ + } + +#if GTP_ESD_PROTECT +extern void gtp_esd_switch(struct i2c_client *, s32); +#endif + +#if GTP_COMPATIBLE_MODE +s32 gup_fw_download_proc(void *dir, u8 dwn_mode); +#endif +/******************************************************* +Function: + Read data from the i2c slave device. +Input: + client: i2c device. + buf[0~1]: read start address. + buf[2~len-1]: read data buffer. + len: GTP_ADDR_LENGTH + read bytes count +Output: + numbers of i2c_msgs to transfer: + 2: succeed, otherwise: failed +*********************************************************/ +s32 gup_i2c_read(struct i2c_client *client, u8 *buf, s32 len) +{ + struct i2c_msg msgs[2]; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; + msgs[0].scl_rate=200 * 1000; + //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + msgs[1].scl_rate=200 * 1000; + //msgs[1].scl_rate = 300 * 1000; // for Rockchip, etc. + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2)break; + retries++; + } + + return ret; +} + +/******************************************************* +Function: + Write data to the i2c slave device. +Input: + client: i2c device. + buf[0~1]: write start address. + buf[2~len-1]: data buffer + len: GTP_ADDR_LENGTH + write bytes count +Output: + numbers of i2c_msgs to transfer: + 1: succeed, otherwise: failed +*********************************************************/ +s32 gup_i2c_write(struct i2c_client *client,u8 *buf,s32 len) +{ + struct i2c_msg msg; + s32 ret=-1; + s32 retries = 0; + + GTP_DEBUG_FUNC(); + + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + msg.scl_rate=200 * 1000; + //msg.scl_rate = 300 * 1000; // for Rockchip, etc + + while(retries < 5) + { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1)break; + retries++; + } + + return ret; +} + +static s32 gup_init_panel(struct goodix_ts_data *ts) +{ + s32 ret = 0; + s32 i = 0; + u8 check_sum = 0; + u8 opr_buf[16]; + u8 sensor_id = 0; + u16 version = 0; + + u8 cfg_info_group1[] = CTP_CFG_GROUP1; + u8 cfg_info_group2[] = CTP_CFG_GROUP2; + u8 cfg_info_group3[] = CTP_CFG_GROUP3; + u8 cfg_info_group4[] = CTP_CFG_GROUP4; + u8 cfg_info_group5[] = CTP_CFG_GROUP5; + u8 cfg_info_group6[] = CTP_CFG_GROUP6; + u8 *send_cfg_buf[] = {cfg_info_group1, cfg_info_group2, cfg_info_group3, + cfg_info_group4, cfg_info_group5, cfg_info_group6}; + u8 cfg_info_len[] = { CFG_GROUP_LEN(cfg_info_group1), + CFG_GROUP_LEN(cfg_info_group2), + CFG_GROUP_LEN(cfg_info_group3), + CFG_GROUP_LEN(cfg_info_group4), + CFG_GROUP_LEN(cfg_info_group5), + CFG_GROUP_LEN(cfg_info_group6)}; + + if ((!cfg_info_len[1]) && (!cfg_info_len[2]) && + (!cfg_info_len[3]) && (!cfg_info_len[4]) && + (!cfg_info_len[5])) + { + sensor_id = 0; + } + else + { + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1); + if (SUCCESS == ret) + { + if (sensor_id >= 0x06) + { + GTP_ERROR("Invalid sensor_id(0x%02X), No Config Sent!", sensor_id); + return -1; + } + } + else + { + GTP_ERROR("Failed to get sensor_id, No config sent!"); + return -1; + } + } + + GTP_DEBUG("Sensor_ID: %d", sensor_id); + + ts->gtp_cfg_len = cfg_info_len[sensor_id]; + + if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH) + { + GTP_ERROR("Sensor_ID(%d) matches with NULL or INVALID CONFIG GROUP! NO Config Sent! You need to check you header file CFG_GROUP section!", sensor_id); + return -1; + } + + ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0], 1); + + if (ret == SUCCESS) + { + GTP_DEBUG("CFG_GROUP%d Config Version: %d, IC Config Version: %d", sensor_id+1, + send_cfg_buf[sensor_id][0], opr_buf[0]); + + send_cfg_buf[sensor_id][0] = opr_buf[0]; + ts->fixed_cfg = 0; + } + else + { + GTP_ERROR("Failed to get ic config version!No config sent!"); + return -1; + } + + memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); + memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len); + + GTP_DEBUG("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x", + ts->abs_x_max, ts->abs_y_max, ts->int_trigger_type); + + config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; + config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); + config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; + config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); + + if (GTP_INT_TRIGGER == 0) //RISING + { + config[TRIGGER_LOC] &= 0xfe; + } + else if (GTP_INT_TRIGGER == 1) //FALLING + { + config[TRIGGER_LOC] |= 0x01; + } + + check_sum = 0; + for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) + { + check_sum += config[i]; + } + config[ts->gtp_cfg_len] = (~check_sum) + 1; + + GTP_DEBUG_FUNC(); + ret = gtp_send_cfg(ts->client); + if (ret < 0) + { + GTP_ERROR("Send config error."); + } + gtp_read_version(ts->client, &version); + msleep(10); + return 0; +} + + +static u8 gup_get_ic_msg(struct i2c_client *client, u16 addr, u8* msg, s32 len) +{ + s32 i = 0; + + msg[0] = (addr >> 8) & 0xff; + msg[1] = addr & 0xff; + + for (i = 0; i < 5; i++) + { + if (gup_i2c_read(client, msg, GTP_ADDR_LENGTH + len) > 0) + { + break; + } + } + + if (i >= 5) + { + GTP_ERROR("Read data from 0x%02x%02x failed!", msg[0], msg[1]); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_set_ic_msg(struct i2c_client *client, u16 addr, u8 val) +{ + s32 i = 0; + u8 msg[3]; + + msg[0] = (addr >> 8) & 0xff; + msg[1] = addr & 0xff; + msg[2] = val; + + for (i = 0; i < 5; i++) + { + if (gup_i2c_write(client, msg, GTP_ADDR_LENGTH + 1) > 0) + { + break; + } + } + + if (i >= 5) + { + GTP_ERROR("Set data to 0x%02x%02x failed!", msg[0], msg[1]); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_get_ic_fw_msg(struct i2c_client *client) +{ + s32 ret = -1; + u8 retry = 0; + u8 buf[16]; + u8 i; + + // step1:get hardware info + ret = gtp_i2c_read_dbl_check(client, GUP_REG_HW_INFO, &buf[GTP_ADDR_LENGTH], 4); + if (FAIL == ret) + { + GTP_ERROR("[get_ic_fw_msg]get hw_info failed,exit"); + return FAIL; + } + + // buf[2~5]: 00 06 90 00 + // hw_info: 00 90 06 00 + for(i=0; i<4; i++) + { + update_msg.ic_fw_msg.hw_info[i] = buf[GTP_ADDR_LENGTH + 3 - i]; + } + GTP_DEBUG("IC Hardware info:%02x%02x%02x%02x", update_msg.ic_fw_msg.hw_info[0], update_msg.ic_fw_msg.hw_info[1], + update_msg.ic_fw_msg.hw_info[2], update_msg.ic_fw_msg.hw_info[3]); + // step2:get firmware message + for(retry=0; retry<2; retry++) + { + ret = gup_get_ic_msg(client, GUP_REG_FW_MSG, buf, 1); + if(FAIL == ret) + { + GTP_ERROR("Read firmware message fail."); + return ret; + } + + update_msg.force_update = buf[GTP_ADDR_LENGTH]; + if((0xBE != update_msg.force_update)&&(!retry)) + { + GTP_INFO("The check sum in ic is error."); + GTP_INFO("The IC will be updated by force."); + continue; + } + break; + } + GTP_DEBUG("IC force update flag:0x%x", update_msg.force_update); + + // step3:get pid & vid + ret = gtp_i2c_read_dbl_check(client, GUP_REG_PID_VID, &buf[GTP_ADDR_LENGTH], 6); + if (FAIL == ret) + { + GTP_ERROR("[get_ic_fw_msg]get pid & vid failed,exit"); + return FAIL; + } + + memset(update_msg.ic_fw_msg.pid, 0, sizeof(update_msg.ic_fw_msg.pid)); + memcpy(update_msg.ic_fw_msg.pid, &buf[GTP_ADDR_LENGTH], 4); + GTP_DEBUG("IC Product id:%s", update_msg.ic_fw_msg.pid); + + //GT9XX PID MAPPING + /*|-----FLASH-----RAM-----| + |------918------918-----| + |------968------968-----| + |------913------913-----| + |------913P-----913P----| + |------927------927-----| + |------927P-----927P----| + |------9110-----9110----| + |------9110P----9111----|*/ + if(update_msg.ic_fw_msg.pid[0] != 0) + { + if(!memcmp(update_msg.ic_fw_msg.pid, "9111", 4)) + { + GTP_DEBUG("IC Mapping Product id:%s", update_msg.ic_fw_msg.pid); + memcpy(update_msg.ic_fw_msg.pid, "9110P", 5); + } + } + + update_msg.ic_fw_msg.vid = buf[GTP_ADDR_LENGTH+4] + (buf[GTP_ADDR_LENGTH+5]<<8); + GTP_DEBUG("IC version id:%04x", update_msg.ic_fw_msg.vid); + + return SUCCESS; +} + +s32 gup_enter_update_mode(struct i2c_client *client) +{ + s32 ret = -1; + s32 retry = 0; + u8 rd_buf[3]; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + //step1:RST output low last at least 2ms + GTP_GPIO_OUTPUT(ts->rst_pin, 0); + msleep(2); + + //step2:select I2C slave addr,INT:0--0xBA;1--0x28. + GTP_GPIO_OUTPUT(ts->irq_pin, (client->addr == 0x14)); + msleep(2); + + //step3:RST output high reset guitar + GTP_GPIO_OUTPUT(ts->rst_pin, 1); + + //20121211 modify start + msleep(5); + while(retry++ < 200) + { + //step4:Hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + + //step5:Confirm hold + ret = gup_get_ic_msg(client, _rRW_MISCTL__SWRST_B0_, rd_buf, 1); + if(ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + if(0x0C == rd_buf[GTP_ADDR_LENGTH]) + { + GTP_DEBUG("Hold ss51 & dsp confirm SUCCESS"); + break; + } + GTP_DEBUG("Hold ss51 & dsp confirm 0x4180 failed,value:%d", rd_buf[GTP_ADDR_LENGTH]); + } + if(retry >= 200) + { + GTP_ERROR("Enter update Hold ss51 failed."); + return FAIL; + } + + //step6:DSP_CK and DSP_ALU_CK PowerOn + ret = gup_set_ic_msg(client, 0x4010, 0x00); + + //20121211 modify end + return ret; +} + +void gup_leave_update_mode(struct goodix_ts_data *ts) +{ + //GTP_GPIO_AS_INT(GTP_INT_PORT); + gpio_direction_input(ts->irq_pin); + //s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); + //s3c_gpio_cfgpin(pin, GTP_INT_CFG); + + GTP_DEBUG("[leave_update_mode]reset chip."); + gtp_reset_guitar(i2c_connect_client, 20); +} + +// Get the correct nvram data +// The correct conditions: +// 1. the hardware info is the same +// 2. the product id is the same +// 3. the firmware version in update file is greater than the firmware version in ic +// or the check sum in ic is wrong +/* Update Conditions: + 1. Same hardware info + 2. Same PID + 3. File VID > IC VID + Force Update Conditions: + 1. Wrong ic firmware checksum + 2. INVALID IC PID or VID + 3. (IC PID == 91XX || File PID == 91XX) && (File VID > IC VID) +*/ + +static u8 gup_enter_update_judge(st_fw_head *fw_head) +{ + u16 u16_tmp; + s32 i = 0; + u32 fw_len = 0; + s32 pid_cmp_len = 0; + u16_tmp = fw_head->vid; + fw_head->vid = (u16)(u16_tmp>>8) + (u16)(u16_tmp<<8); + + GTP_INFO("FILE HARDWARE INFO:%02x%02x%02x%02x", fw_head->hw_info[0], fw_head->hw_info[1], fw_head->hw_info[2], fw_head->hw_info[3]); + GTP_INFO("FILE PID:%s", fw_head->pid); + GTP_INFO("FILE VID:%04x", fw_head->vid); + GTP_INFO("IC HARDWARE INFO:%02x%02x%02x%02x", update_msg.ic_fw_msg.hw_info[0], update_msg.ic_fw_msg.hw_info[1], + update_msg.ic_fw_msg.hw_info[2], update_msg.ic_fw_msg.hw_info[3]); + GTP_INFO("IC PID:%s", update_msg.ic_fw_msg.pid); + GTP_INFO("IC VID:%04x", update_msg.ic_fw_msg.vid); + + if (!memcmp(fw_head->pid, "9158", 4) && !memcmp(update_msg.ic_fw_msg.pid, "915S", 4)) + { + GTP_INFO("Update GT915S to GT9158 directly!"); + return SUCCESS; + } + //First two conditions + if (!memcmp(fw_head->hw_info, update_msg.ic_fw_msg.hw_info, sizeof(update_msg.ic_fw_msg.hw_info))) + { + fw_len = 42 * 1024; + } + else + { + fw_len = fw_head->hw_info[3]; + fw_len += (((u32)fw_head->hw_info[2]) << 8); + fw_len += (((u32)fw_head->hw_info[1]) << 16); + fw_len += (((u32)fw_head->hw_info[0]) << 24); + } + if (update_msg.fw_total_len != fw_len) + { + GTP_ERROR("Inconsistent firmware size, Update aborted! Default size: %d(%dK), actual size: %d(%dK)", fw_len, fw_len/1024, update_msg.fw_total_len, update_msg.fw_total_len/1024); + return FAIL; + } + GTP_INFO("Firmware length:%d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len/1024); + + if (update_msg.force_update != 0xBE) + { + GTP_INFO("FW chksum error,need enter update."); + return SUCCESS; + } + + // 20130523 start + if (strlen(update_msg.ic_fw_msg.pid) < 3) + { + GTP_INFO("Illegal IC pid, need enter update"); + return SUCCESS; + } + else + { + for (i = 0; i < 3; i++) + { + if ((update_msg.ic_fw_msg.pid[i] < 0x30) || (update_msg.ic_fw_msg.pid[i] > 0x39)) + { + GTP_INFO("Illegal IC pid, out of bound, need enter update"); + return SUCCESS; + } + } + } + // 20130523 end + + pid_cmp_len = strlen(fw_head->pid); + if (pid_cmp_len < strlen(update_msg.ic_fw_msg.pid)) + { + pid_cmp_len = strlen(update_msg.ic_fw_msg.pid); + } + + if ((!memcmp(fw_head->pid, update_msg.ic_fw_msg.pid, pid_cmp_len)) || + (!memcmp(update_msg.ic_fw_msg.pid, "91XX", 4))|| + (!memcmp(fw_head->pid, "91XX", 4))) + { + if(!memcmp(fw_head->pid, "91XX", 4)) + { + GTP_DEBUG("Force none same pid update mode."); + } + else + { + GTP_DEBUG("Get the same pid."); + } + + //The third condition + if (fw_head->vid > update_msg.ic_fw_msg.vid) + { + GTP_INFO("Need enter update."); + return SUCCESS; + } + GTP_ERROR("Don't meet the third condition."); + GTP_ERROR("File VID <= Ic VID, update aborted!"); + } + else + { + GTP_ERROR("File PID != Ic PID, update aborted!"); + } + + return FAIL; +} + + + +#if GTP_AUTO_UPDATE_CFG +static u8 ascii2hex(u8 a) +{ + s8 value = 0; + + if(a >= '0' && a <= '9') + { + value = a - '0'; + } + else if(a >= 'A' && a <= 'F') + { + value = a - 'A' + 0x0A; + } + else if(a >= 'a' && a <= 'f') + { + value = a - 'a' + 0x0A; + } + else + { + value = 0xff; + } + + return value; +} + +static s8 gup_update_config(struct i2c_client *client) +{ + s32 file_len = 0; + s32 ret = 0; + s32 i = 0; + s32 file_cfg_len = 0; + s32 chip_cfg_len = 0; + s32 count = 0; + u8 *buf; + u8 *pre_buf; + u8 *file_config; + //u8 checksum = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + + if(NULL == update_msg.cfg_file) + { + GTP_ERROR("[update_cfg]No need to upgrade config!"); + return FAIL; + } + file_len = update_msg.cfg_file->f_op->llseek(update_msg.cfg_file, 0, SEEK_END); + + chip_cfg_len = ts->gtp_cfg_len; + + GTP_DEBUG("[update_cfg]config file len:%d", file_len); + GTP_DEBUG("[update_cfg]need config len:%d", chip_cfg_len); + if((file_len+5) < chip_cfg_len*5) + { + GTP_ERROR("Config length error"); + return -1; + } + + buf = (u8*)kzalloc(file_len, GFP_KERNEL); + pre_buf = (u8*)kzalloc(file_len, GFP_KERNEL); + file_config = (u8*)kzalloc(chip_cfg_len + GTP_ADDR_LENGTH, GFP_KERNEL); + update_msg.cfg_file->f_op->llseek(update_msg.cfg_file, 0, SEEK_SET); + + GTP_DEBUG("[update_cfg]Read config from file."); + ret = update_msg.cfg_file->f_op->read(update_msg.cfg_file, (char*)pre_buf, file_len, &update_msg.cfg_file->f_pos); + if(ret<0) + { + GTP_ERROR("[update_cfg]Read config file failed."); + goto update_cfg_file_failed; + } + + GTP_DEBUG("[update_cfg]Delete illgal charactor."); + for(i=0,count=0; i> 8; + file_config[1] = GTP_REG_CONFIG_DATA & 0xff; + for(i=0,file_cfg_len=GTP_ADDR_LENGTH; i 0) + { + GTP_INFO("[update_cfg]Send config SUCCESS."); + break; + } + GTP_ERROR("[update_cfg]Send config i2c error."); + } + +update_cfg_file_failed: + kfree(pre_buf); + kfree(buf); + kfree(file_config); + return ret; +} + +#endif + +#if (GTP_AUTO_UPDATE && (!GTP_HEADER_FW_UPDATE || GTP_AUTO_UPDATE_CFG)) +static void gup_search_file(s32 search_type) +{ + s32 i = 0; + struct file *pfile = NULL; + + got_file_flag = 0x00; + + searching_file = 1; + for (i = 0; i < GUP_SEARCH_FILE_TIMES; ++i) + { + if (0 == searching_file) + { + GTP_INFO("Force exiting file searching"); + got_file_flag = 0x00; + return; + } + + if (search_type & AUTO_SEARCH_BIN) + { + GTP_DEBUG("Search for %s, %s for fw update.(%d/%d)", UPDATE_FILE_PATH_1, UPDATE_FILE_PATH_2, i+1, GUP_SEARCH_FILE_TIMES); + pfile = filp_open(UPDATE_FILE_PATH_1, O_RDONLY, 0); + if (IS_ERR(pfile)) + { + pfile = filp_open(UPDATE_FILE_PATH_2, O_RDONLY, 0); + if (!IS_ERR(pfile)) + { + GTP_INFO("Bin file: %s for fw update.", UPDATE_FILE_PATH_2); + got_file_flag |= BIN_FILE_READY; + update_msg.file = pfile; + } + } + else + { + GTP_INFO("Bin file: %s for fw update.", UPDATE_FILE_PATH_1); + got_file_flag |= BIN_FILE_READY; + update_msg.file = pfile; + } + if (got_file_flag & BIN_FILE_READY) + { + #if GTP_AUTO_UPDATE_CFG + if (search_type & AUTO_SEARCH_CFG) + { + i = GUP_SEARCH_FILE_TIMES; // Bin & Cfg File required to be in the same directory + } + else + #endif + { + searching_file = 0; + return; + } + } + } + + #if GTP_AUTO_UPDATE_CFG + if ( (search_type & AUTO_SEARCH_CFG) && !(got_file_flag & CFG_FILE_READY) ) + { + GTP_DEBUG("Search for %s, %s for config update.(%d/%d)", CONFIG_FILE_PATH_1, CONFIG_FILE_PATH_2, i+1, GUP_SEARCH_FILE_TIMES); + pfile = filp_open(CONFIG_FILE_PATH_1, O_RDONLY, 0); + if (IS_ERR(pfile)) + { + pfile = filp_open(CONFIG_FILE_PATH_2, O_RDONLY, 0); + if (!IS_ERR(pfile)) + { + GTP_INFO("Cfg file: %s for config update.", CONFIG_FILE_PATH_2); + got_file_flag |= CFG_FILE_READY; + update_msg.cfg_file = pfile; + } + } + else + { + GTP_INFO("Cfg file: %s for config update.", CONFIG_FILE_PATH_1); + got_file_flag |= CFG_FILE_READY; + update_msg.cfg_file = pfile; + } + if (got_file_flag & CFG_FILE_READY) + { + searching_file = 0; + return; + } + } + #endif + msleep(3000); + } + searching_file = 0; +} +#endif + + +static u8 gup_check_update_file(struct i2c_client *client, st_fw_head* fw_head, u8* path) +{ + s32 ret = 0; + s32 i = 0; + s32 fw_checksum = 0; + u8 buf[FW_HEAD_LENGTH]; + + got_file_flag = 0x00; + if (path) + { + GTP_DEBUG("Update File path:%s, %d", path, strlen(path)); + update_msg.file = filp_open(path, O_RDONLY, 0); + + if (IS_ERR(update_msg.file)) + { + GTP_ERROR("Open update file(%s) error!", path); + return FAIL; + } + got_file_flag = BIN_FILE_READY; + } + else + { +#if GTP_AUTO_UPDATE + #if GTP_HEADER_FW_UPDATE + GTP_INFO("Update by default firmware array"); + update_msg.fw_total_len = sizeof(gtp_default_FW) - FW_HEAD_LENGTH; + if (sizeof(gtp_default_FW) < (FW_HEAD_LENGTH+FW_SECTION_LENGTH*4+FW_DSP_ISP_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH)) + { + printk(" <<-GTP-ERROR->> haha INVALID gtp_default_FW, check your gt9xx_firmware.h file! sizeof(gtp_default_FW)=%d\n", sizeof(gtp_default_FW)); + return FAIL; + } + GTP_DEBUG("Firmware actual size: %d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len/1024); + memcpy(fw_head, >p_default_FW[0], FW_HEAD_LENGTH); + + //check firmware legality + fw_checksum = 0; + for(i=0; i< update_msg.fw_total_len; i+=2) + { + fw_checksum += (gtp_default_FW[FW_HEAD_LENGTH + i] << 8) + gtp_default_FW[FW_HEAD_LENGTH + i + 1]; + } + + GTP_DEBUG("firmware checksum:%x", fw_checksum&0xFFFF); + if (fw_checksum&0xFFFF) + { + GTP_ERROR("Illegal firmware file."); + return FAIL; + } + got_file_flag = HEADER_FW_READY; + return SUCCESS; + #else + + #if GTP_AUTO_UPDATE_CFG + gup_search_file(AUTO_SEARCH_BIN | AUTO_SEARCH_CFG); + if (got_file_flag & CFG_FILE_READY) + { + ret = gup_update_config(i2c_connect_client); + if(ret <= 0) + { + GTP_ERROR("Update config failed."); + } + _CLOSE_FILE(update_msg.cfg_file); + msleep(500); //waiting config to be stored in FLASH. + } + #else + gup_search_file(AUTO_SEARCH_BIN); + #endif + + if ( !(got_file_flag & BIN_FILE_READY) ) + { + GTP_ERROR("No bin file for fw update"); + return FAIL; + } + #endif + +#else + { + GTP_ERROR("NULL file for firmware update"); + return FAIL; + } +#endif + } + + update_msg.old_fs = get_fs(); + set_fs(KERNEL_DS); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + update_msg.fw_total_len = update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_END); + if (update_msg.fw_total_len < (FW_HEAD_LENGTH + FW_SECTION_LENGTH*4+FW_DSP_ISP_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH)) + { + GTP_ERROR("INVALID bin file(size: %d), update aborted.", update_msg.fw_total_len); + return FAIL; + } + + update_msg.fw_total_len -= FW_HEAD_LENGTH; + + GTP_DEBUG("Bin firmware actual size: %d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len/1024); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + ret = update_msg.file->f_op->read(update_msg.file, (char*)buf, FW_HEAD_LENGTH, &update_msg.file->f_pos); + if (ret < 0) + { + GTP_ERROR("Read firmware head in update file error."); + return FAIL; + } + + memcpy(fw_head, buf, FW_HEAD_LENGTH); + + //check firmware legality + fw_checksum = 0; + for(i=0; if_op->read(update_msg.file, (char*)buf, 2, &update_msg.file->f_pos); + if (ret < 0) + { + GTP_ERROR("Read firmware file error."); + return FAIL; + } + //GTP_DEBUG("BUF[0]:%x", buf[0]); + temp = (buf[0]<<8) + buf[1]; + fw_checksum += temp; + } + + GTP_DEBUG("firmware checksum:%x", fw_checksum&0xFFFF); + if(fw_checksum&0xFFFF) + { + GTP_ERROR("Illegal firmware file."); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_burn_proc(struct i2c_client *client, u8 *burn_buf, u16 start_addr, u16 total_length) +{ + s32 ret = 0; + u16 burn_addr = start_addr; + u16 frame_length = 0; + u16 burn_length = 0; + u8 wr_buf[PACK_SIZE + GTP_ADDR_LENGTH]; + u8 rd_buf[PACK_SIZE + GTP_ADDR_LENGTH]; + u8 retry = 0; + + GTP_DEBUG("Begin burn %dk data to addr 0x%x", (total_length/1024), start_addr); + while(burn_length < total_length) + { + GTP_DEBUG("B/T:%04d/%04d", burn_length, total_length); + frame_length = ((total_length - burn_length) > PACK_SIZE) ? PACK_SIZE : (total_length - burn_length); + wr_buf[0] = (u8)(burn_addr>>8); + rd_buf[0] = wr_buf[0]; + wr_buf[1] = (u8)burn_addr; + rd_buf[1] = wr_buf[1]; + memcpy(&wr_buf[GTP_ADDR_LENGTH], &burn_buf[burn_length], frame_length); + + for(retry = 0; retry < MAX_FRAME_CHECK_TIME; retry++) + { + ret = gup_i2c_write(client, wr_buf, GTP_ADDR_LENGTH + frame_length); + if(ret <= 0) + { + GTP_ERROR("Write frame data i2c error."); + continue; + } + ret = gup_i2c_read(client, rd_buf, GTP_ADDR_LENGTH + frame_length); + if(ret <= 0) + { + GTP_ERROR("Read back frame data i2c error."); + continue; + } + + if(memcmp(&wr_buf[GTP_ADDR_LENGTH], &rd_buf[GTP_ADDR_LENGTH], frame_length)) + { + GTP_ERROR("Check frame data fail,not equal."); + GTP_DEBUG("write array:"); + GTP_DEBUG_ARRAY(&wr_buf[GTP_ADDR_LENGTH], frame_length); + GTP_DEBUG("read array:"); + GTP_DEBUG_ARRAY(&rd_buf[GTP_ADDR_LENGTH], frame_length); + continue; + } + else + { + //GTP_DEBUG("Check frame data success."); + break; + } + } + if(retry >= MAX_FRAME_CHECK_TIME) + { + GTP_ERROR("Burn frame data time out,exit."); + return FAIL; + } + burn_length += frame_length; + burn_addr += frame_length; + } + return SUCCESS; +} + +static u8 gup_load_section_file(u8 *buf, u32 offset, u16 length, u8 set_or_end) +{ +#if (GTP_AUTO_UPDATE && GTP_HEADER_FW_UPDATE) + if (got_file_flag == HEADER_FW_READY) + { + if(SEEK_SET == set_or_end) + { + memcpy(buf, >p_default_FW[FW_HEAD_LENGTH + offset], length); + } + else //seek end + { + memcpy(buf, >p_default_FW[update_msg.fw_total_len + FW_HEAD_LENGTH - offset], length); + } + return SUCCESS; + } +#endif + { + s32 ret = 0; + + if ( (update_msg.file == NULL) || IS_ERR(update_msg.file)) + { + GTP_ERROR("cannot find update file,load section file fail."); + return FAIL; + } + + if(SEEK_SET == set_or_end) + { + update_msg.file->f_pos = FW_HEAD_LENGTH + offset; + } + else //seek end + { + update_msg.file->f_pos = update_msg.fw_total_len + FW_HEAD_LENGTH - offset; + } + + ret = update_msg.file->f_op->read(update_msg.file, (char *)buf, length, &update_msg.file->f_pos); + + if (ret < 0) + { + GTP_ERROR("Read update file fail."); + return FAIL; + } + + return SUCCESS; + } +} + +static u8 gup_recall_check(struct i2c_client *client, u8* chk_src, u16 start_rd_addr, u16 chk_length) +{ + u8 rd_buf[PACK_SIZE + GTP_ADDR_LENGTH]; + s32 ret = 0; + u16 recall_addr = start_rd_addr; + u16 recall_length = 0; + u16 frame_length = 0; + + while(recall_length < chk_length) + { + frame_length = ((chk_length - recall_length) > PACK_SIZE) ? PACK_SIZE : (chk_length - recall_length); + ret = gup_get_ic_msg(client, recall_addr, rd_buf, frame_length); + if(ret <= 0) + { + GTP_ERROR("recall i2c error,exit"); + return FAIL; + } + + if(memcmp(&rd_buf[GTP_ADDR_LENGTH], &chk_src[recall_length], frame_length)) + { + GTP_ERROR("Recall frame data fail,not equal."); + GTP_DEBUG("chk_src array:"); + GTP_DEBUG_ARRAY(&chk_src[recall_length], frame_length); + GTP_DEBUG("recall array:"); + GTP_DEBUG_ARRAY(&rd_buf[GTP_ADDR_LENGTH], frame_length); + return FAIL; + } + + recall_length += frame_length; + recall_addr += frame_length; + } + GTP_DEBUG("Recall check %dk firmware success.", (chk_length/1024)); + + return SUCCESS; +} + +static u8 gup_burn_fw_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u8 bank_cmd ) +{ + s32 ret = 0; + u8 rd_buf[5]; + + //step1:hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]hold ss51 & dsp fail."); + return FAIL; + } + + //step2:set scramble + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]set scramble fail."); + return FAIL; + } + + //step3:select bank + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, (bank_cmd >> 4)&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]select bank %d fail.", (bank_cmd >> 4)&0x0F); + return FAIL; + } + + //step4:enable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]enable accessing code fail."); + return FAIL; + } + + //step5:burn 8k fw section + ret = gup_burn_proc(client, fw_section, start_addr, FW_SECTION_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_section]burn fw_section fail."); + return FAIL; + } + + //step6:hold ss51 & release dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]hold ss51 & release dsp fail."); + return FAIL; + } + //must delay + msleep(1); + + //step7:send burn cmd to move data to flash from sram + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, bank_cmd&0x0f); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]send burn cmd fail."); + return FAIL; + } + GTP_DEBUG("[burn_fw_section]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]Get burn state fail"); + return FAIL; + } + msleep(10); + //GTP_DEBUG("[burn_fw_section]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step8:select bank + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, (bank_cmd >> 4)&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]select bank %d fail.", (bank_cmd >> 4)&0x0F); + return FAIL; + } + + //step9:enable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]enable accessing code fail."); + return FAIL; + } + + //step10:recall 8k fw section + ret = gup_recall_check(client, fw_section, start_addr, FW_SECTION_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_section]recall check %dk firmware fail.", FW_SECTION_LENGTH/1024); + return FAIL; + } + + //step11:disable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]disable accessing code fail."); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_burn_dsp_isp(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_dsp_isp = NULL; + u8 retry = 0; + + GTP_INFO("[burn_dsp_isp]Begin burn dsp isp---->>"); + + //step1:alloc memory + GTP_DEBUG("[burn_dsp_isp]step1:alloc memory"); + while(retry++ < 5) + { + fw_dsp_isp = (u8*)kzalloc(FW_DSP_ISP_LENGTH, GFP_KERNEL); + if(fw_dsp_isp == NULL) + { + continue; + } + else + { + GTP_INFO("[burn_dsp_isp]Alloc %dk byte memory success.", (FW_DSP_ISP_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_dsp_isp]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load dsp isp file data + GTP_DEBUG("[burn_dsp_isp]step2:load dsp isp file data"); + ret = gup_load_section_file(fw_dsp_isp, FW_DSP_ISP_LENGTH, FW_DSP_ISP_LENGTH, SEEK_END); + if(FAIL == ret) + { + GTP_ERROR("[burn_dsp_isp]load firmware dsp_isp fail."); + goto exit_burn_dsp_isp; + } + + //step3:disable wdt,clear cache enable + GTP_DEBUG("[burn_dsp_isp]step3:disable wdt,clear cache enable"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__TMR0_EN, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]disable wdt fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + ret = gup_set_ic_msg(client, _bRW_MISCTL__CACHE_EN, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]clear cache enable fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step4:hold ss51 & dsp + GTP_DEBUG("[burn_dsp_isp]step4:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step5:set boot from sram + GTP_DEBUG("[burn_dsp_isp]step5:set boot from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOTCTL_B0_, 0x02); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]set boot from sram fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step6:software reboot + GTP_DEBUG("[burn_dsp_isp]step6:software reboot"); + ret = gup_set_ic_msg(client, _bWO_MISCTL__CPU_SWRST_PULSE, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]software reboot fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step7:select bank2 + GTP_DEBUG("[burn_dsp_isp]step7:select bank2"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x02); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]select bank2 fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step8:enable accessing code + GTP_DEBUG("[burn_dsp_isp]step8:enable accessing code"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]enable accessing code fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + + //step9:burn 4k dsp_isp + GTP_DEBUG("[burn_dsp_isp]step9:burn 4k dsp_isp"); + ret = gup_burn_proc(client, fw_dsp_isp, 0xC000, FW_DSP_ISP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_dsp_isp]burn dsp_isp fail."); + goto exit_burn_dsp_isp; + } + + //step10:set scramble + GTP_DEBUG("[burn_dsp_isp]step10:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_dsp_isp]set scramble fail."); + ret = FAIL; + goto exit_burn_dsp_isp; + } + update_msg.fw_burned_len += FW_DSP_ISP_LENGTH; + GTP_DEBUG("[burn_dsp_isp]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_dsp_isp: + kfree(fw_dsp_isp); + return ret; +} + +static u8 gup_burn_fw_ss51(struct i2c_client *client) +{ + u8* fw_ss51 = NULL; + u8 retry = 0; + s32 ret = 0; + + GTP_INFO("[burn_fw_ss51]Begin burn ss51 firmware---->>"); + + //step1:alloc memory + GTP_DEBUG("[burn_fw_ss51]step1:alloc memory"); + while(retry++ < 5) + { + fw_ss51 = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_ss51 == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_ss51]Alloc %dk byte memory success.", (FW_SECTION_LENGTH / 1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_ss51]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load ss51 firmware section 1 file data +// GTP_DEBUG("[burn_fw_ss51]step2:load ss51 firmware section 1 file data"); +// ret = gup_load_section_file(fw_ss51, 0, FW_SECTION_LENGTH, SEEK_SET); +// if(FAIL == ret) +// { +// GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 1 fail."); +// goto exit_burn_fw_ss51; +// } + + GTP_INFO("[burn_fw_ss51]Reset first 8K of ss51 to 0xFF."); + GTP_DEBUG("[burn_fw_ss51]step2: reset bank0 0xC000~0xD000"); + memset(fw_ss51, 0xFF, FW_SECTION_LENGTH); + + //step3:clear control flag + GTP_DEBUG("[burn_fw_ss51]step3:clear control flag"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_ss51]clear control flag fail."); + ret = FAIL; + goto exit_burn_fw_ss51; + } + + //step4:burn ss51 firmware section 1 + GTP_DEBUG("[burn_fw_ss51]step4:burn ss51 firmware section 1"); + ret = gup_burn_fw_section(client, fw_ss51, 0xC000, 0x01); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 1 fail."); + goto exit_burn_fw_ss51; + } + + //step5:load ss51 firmware section 2 file data + GTP_DEBUG("[burn_fw_ss51]step5:load ss51 firmware section 2 file data"); + ret = gup_load_section_file(fw_ss51, FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 2 fail."); + goto exit_burn_fw_ss51; + } + + //step6:burn ss51 firmware section 2 + GTP_DEBUG("[burn_fw_ss51]step6:burn ss51 firmware section 2"); + ret = gup_burn_fw_section(client, fw_ss51, 0xE000, 0x02); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 2 fail."); + goto exit_burn_fw_ss51; + } + + //step7:load ss51 firmware section 3 file data + GTP_DEBUG("[burn_fw_ss51]step7:load ss51 firmware section 3 file data"); + ret = gup_load_section_file(fw_ss51, 2 * FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 3 fail."); + goto exit_burn_fw_ss51; + } + + //step8:burn ss51 firmware section 3 + GTP_DEBUG("[burn_fw_ss51]step8:burn ss51 firmware section 3"); + ret = gup_burn_fw_section(client, fw_ss51, 0xC000, 0x13); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 3 fail."); + goto exit_burn_fw_ss51; + } + + //step9:load ss51 firmware section 4 file data + GTP_DEBUG("[burn_fw_ss51]step9:load ss51 firmware section 4 file data"); + ret = gup_load_section_file(fw_ss51, 3 * FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]load ss51 firmware section 4 fail."); + goto exit_burn_fw_ss51; + } + + //step10:burn ss51 firmware section 4 + GTP_DEBUG("[burn_fw_ss51]step10:burn ss51 firmware section 4"); + ret = gup_burn_fw_section(client, fw_ss51, 0xE000, 0x14); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_ss51]burn ss51 firmware section 4 fail."); + goto exit_burn_fw_ss51; + } + + update_msg.fw_burned_len += (FW_SECTION_LENGTH*4); + GTP_DEBUG("[burn_fw_ss51]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_ss51: + kfree(fw_ss51); + return ret; +} + +static u8 gup_burn_fw_dsp(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_dsp = NULL; + u8 retry = 0; + u8 rd_buf[5]; + + GTP_INFO("[burn_fw_dsp]Begin burn dsp firmware---->>"); + //step1:alloc memory + GTP_DEBUG("[burn_fw_dsp]step1:alloc memory"); + while(retry++ < 5) + { + fw_dsp = (u8*)kzalloc(FW_DSP_LENGTH, GFP_KERNEL); + if(fw_dsp == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_dsp]Alloc %dk byte memory success.", (FW_SECTION_LENGTH / 1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_dsp]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware dsp + GTP_DEBUG("[burn_fw_dsp]step2:load firmware dsp"); + ret = gup_load_section_file(fw_dsp, 4 * FW_SECTION_LENGTH, FW_DSP_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_dsp]load firmware dsp fail."); + goto exit_burn_fw_dsp; + } + + //step3:select bank3 + GTP_DEBUG("[burn_fw_dsp]step3:select bank3"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x03); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]select bank3 fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + + //step4:hold ss51 & dsp + GTP_DEBUG("[burn_fw_dsp]step4:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + + //step5:set scramble + GTP_DEBUG("[burn_fw_dsp]step5:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]set scramble fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + + //step6:release ss51 & dsp + GTP_DEBUG("[burn_fw_dsp]step6:release ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); //20121211 + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]release ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_dsp; + } + //must delay + msleep(1); + + //step7:burn 4k dsp firmware + GTP_DEBUG("[burn_fw_dsp]step7:burn 4k dsp firmware"); + ret = gup_burn_proc(client, fw_dsp, 0x9000, FW_DSP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_dsp]burn fw_section fail."); + goto exit_burn_fw_dsp; + } + + //step8:send burn cmd to move data to flash from sram + GTP_DEBUG("[burn_fw_dsp]step8:send burn cmd to move data to flash from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x05); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]send burn cmd fail."); + goto exit_burn_fw_dsp; + } + GTP_DEBUG("[burn_fw_dsp]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_dsp]Get burn state fail"); + goto exit_burn_fw_dsp; + } + msleep(10); + //GTP_DEBUG("[burn_fw_dsp]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step9:recall check 4k dsp firmware + GTP_DEBUG("[burn_fw_dsp]step9:recall check 4k dsp firmware"); + ret = gup_recall_check(client, fw_dsp, 0x9000, FW_DSP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_dsp]recall check 4k dsp firmware fail."); + goto exit_burn_fw_dsp; + } + + update_msg.fw_burned_len += FW_DSP_LENGTH; + GTP_DEBUG("[burn_fw_dsp]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_dsp: + kfree(fw_dsp); + return ret; +} + +static u8 gup_burn_fw_boot(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_boot = NULL; + u8 retry = 0; + u8 rd_buf[5]; + + GTP_INFO("[burn_fw_boot]Begin burn bootloader firmware---->>"); + + //step1:Alloc memory + GTP_DEBUG("[burn_fw_boot]step1:Alloc memory"); + while(retry++ < 5) + { + fw_boot = (u8*)kzalloc(FW_BOOT_LENGTH, GFP_KERNEL); + if(fw_boot == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_boot]Alloc %dk byte memory success.", (FW_BOOT_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_boot]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware bootloader + GTP_DEBUG("[burn_fw_boot]step2:load firmware bootloader"); + ret = gup_load_section_file(fw_boot, (4 * FW_SECTION_LENGTH + FW_DSP_LENGTH), FW_BOOT_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot]load firmware bootcode fail."); + goto exit_burn_fw_boot; + } + + //step3:hold ss51 & dsp + GTP_DEBUG("[burn_fw_boot]step3:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + + //step4:set scramble + GTP_DEBUG("[burn_fw_boot]step4:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]set scramble fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + + //step5:hold ss51 & release dsp + GTP_DEBUG("[burn_fw_boot]step5:hold ss51 & release dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); //20121211 + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]release ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + //must delay + msleep(1); + + //step6:select bank3 + GTP_DEBUG("[burn_fw_boot]step6:select bank3"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x03); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]select bank3 fail."); + ret = FAIL; + goto exit_burn_fw_boot; + } + + //step6:burn 2k bootloader firmware + GTP_DEBUG("[burn_fw_boot]step6:burn 2k bootloader firmware"); + ret = gup_burn_proc(client, fw_boot, 0x9000, FW_BOOT_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot]burn fw_boot fail."); + goto exit_burn_fw_boot; + } + + //step7:send burn cmd to move data to flash from sram + GTP_DEBUG("[burn_fw_boot]step7:send burn cmd to move data to flash from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x06); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]send burn cmd fail."); + goto exit_burn_fw_boot; + } + GTP_DEBUG("[burn_fw_boot]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot]Get burn state fail"); + goto exit_burn_fw_boot; + } + msleep(10); + //GTP_DEBUG("[burn_fw_boot]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step8:recall check 2k bootloader firmware + GTP_DEBUG("[burn_fw_boot]step8:recall check 2k bootloader firmware"); + ret = gup_recall_check(client, fw_boot, 0x9000, FW_BOOT_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot]recall check 2k bootcode firmware fail."); + goto exit_burn_fw_boot; + } + + update_msg.fw_burned_len += FW_BOOT_LENGTH; + GTP_DEBUG("[burn_fw_boot]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_boot: + kfree(fw_boot); + return ret; +} +static u8 gup_burn_fw_boot_isp(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_boot_isp = NULL; + u8 retry = 0; + u8 rd_buf[5]; + + if(update_msg.fw_burned_len >= update_msg.fw_total_len) + { + GTP_DEBUG("No need to upgrade the boot_isp code!"); + return SUCCESS; + } + GTP_INFO("[burn_fw_boot_isp]Begin burn boot_isp firmware---->>"); + + //step1:Alloc memory + GTP_DEBUG("[burn_fw_boot_isp]step1:Alloc memory"); + while(retry++ < 5) + { + fw_boot_isp = (u8*)kzalloc(FW_BOOT_ISP_LENGTH, GFP_KERNEL); + if(fw_boot_isp == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_boot_isp]Alloc %dk byte memory success.", (FW_BOOT_ISP_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_boot_isp]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware bootloader + GTP_DEBUG("[burn_fw_boot_isp]step2:load firmware bootloader isp"); + //ret = gup_load_section_file(fw_boot_isp, (4*FW_SECTION_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH+FW_DSP_ISP_LENGTH), FW_BOOT_ISP_LENGTH, SEEK_SET); + ret = gup_load_section_file(fw_boot_isp, (update_msg.fw_burned_len - FW_DSP_ISP_LENGTH), FW_BOOT_ISP_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot_isp]load firmware boot_isp fail."); + goto exit_burn_fw_boot_isp; + } + + //step3:hold ss51 & dsp + GTP_DEBUG("[burn_fw_boot_isp]step3:hold ss51 & dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]hold ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + + //step4:set scramble + GTP_DEBUG("[burn_fw_boot_isp]step4:set scramble"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]set scramble fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + + + //step5:hold ss51 & release dsp + GTP_DEBUG("[burn_fw_boot_isp]step5:hold ss51 & release dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); //20121211 + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]release ss51 & dsp fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + //must delay + msleep(1); + + //step6:select bank3 + GTP_DEBUG("[burn_fw_boot_isp]step6:select bank3"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x03); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]select bank3 fail."); + ret = FAIL; + goto exit_burn_fw_boot_isp; + } + + //step7:burn 2k bootload_isp firmware + GTP_DEBUG("[burn_fw_boot_isp]step7:burn 2k bootloader firmware"); + ret = gup_burn_proc(client, fw_boot_isp, 0x9000, FW_BOOT_ISP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot_isp]burn fw_section fail."); + goto exit_burn_fw_boot_isp; + } + + //step7:send burn cmd to move data to flash from sram + GTP_DEBUG("[burn_fw_boot_isp]step8:send burn cmd to move data to flash from sram"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x07); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]send burn cmd fail."); + goto exit_burn_fw_boot_isp; + } + GTP_DEBUG("[burn_fw_boot_isp]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_boot_isp]Get burn state fail"); + goto exit_burn_fw_boot_isp; + } + msleep(10); + //GTP_DEBUG("[burn_fw_boot_isp]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step8:recall check 2k bootload_isp firmware + GTP_DEBUG("[burn_fw_boot_isp]step9:recall check 2k bootloader firmware"); + ret = gup_recall_check(client, fw_boot_isp, 0x9000, FW_BOOT_ISP_LENGTH); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_boot_isp]recall check 2k bootcode_isp firmware fail."); + goto exit_burn_fw_boot_isp; + } + + update_msg.fw_burned_len += FW_BOOT_ISP_LENGTH; + GTP_DEBUG("[burn_fw_boot_isp]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_boot_isp: + kfree(fw_boot_isp); + return ret; +} + +static u8 gup_burn_fw_link(struct i2c_client *client) +{ + s32 ret = 0; + u8* fw_link = NULL; + u8 retry = 0; + u32 offset; + + if(update_msg.fw_burned_len >= update_msg.fw_total_len) + { + GTP_DEBUG("No need to upgrade the link code!"); + return SUCCESS; + } + GTP_INFO("[burn_fw_link]Begin burn link firmware---->>"); + + //step1:Alloc memory + GTP_DEBUG("[burn_fw_link]step1:Alloc memory"); + while(retry++ < 5) + { + fw_link = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_link == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_link]Alloc %dk byte memory success.", (FW_SECTION_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_link]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load firmware link section 1 + GTP_DEBUG("[burn_fw_link]step2:load firmware link section 1"); + offset = update_msg.fw_burned_len - FW_DSP_ISP_LENGTH; + ret = gup_load_section_file(fw_link, offset, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_link]load firmware link section 1 fail."); + goto exit_burn_fw_link; + } + + //step3:burn link firmware section 1 + GTP_DEBUG("[burn_fw_link]step3:burn link firmware section 1"); + ret = gup_burn_fw_gwake_section(client, fw_link, 0x9000, FW_SECTION_LENGTH, 0x38); + + if (FAIL == ret) + { + GTP_ERROR("[burn_fw_link]burn link firmware section 1 fail."); + goto exit_burn_fw_link; + } + + //step4:load link firmware section 2 file data + GTP_DEBUG("[burn_fw_link]step4:load link firmware section 2 file data"); + offset += FW_SECTION_LENGTH; + ret = gup_load_section_file(fw_link, offset, FW_GLINK_LENGTH - FW_SECTION_LENGTH, SEEK_SET); + + if (FAIL == ret) + { + GTP_ERROR("[burn_fw_link]load link firmware section 2 fail."); + goto exit_burn_fw_link; + } + + //step5:burn link firmware section 2 + GTP_DEBUG("[burn_fw_link]step4:burn link firmware section 2"); + ret = gup_burn_fw_gwake_section(client, fw_link, 0x9000, FW_GLINK_LENGTH - FW_SECTION_LENGTH, 0x39); + + if (FAIL == ret) + { + GTP_ERROR("[burn_fw_link]burn link firmware section 2 fail."); + goto exit_burn_fw_link; + } + + update_msg.fw_burned_len += FW_GLINK_LENGTH; + GTP_DEBUG("[burn_fw_link]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_link: + kfree(fw_link); + return ret; +} + +static u8 gup_burn_fw_gwake_section(struct i2c_client *client, u8 *fw_section, u16 start_addr, u32 len, u8 bank_cmd ) +{ + s32 ret = 0; + u8 rd_buf[5]; + + //step1:hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]hold ss51 & dsp fail."); + return FAIL; + } + + //step2:set scramble + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]set scramble fail."); + return FAIL; + } + + //step3:hold ss51 & release dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x04); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]hold ss51 & release dsp fail."); + return FAIL; + } + //must delay + msleep(1); + + //step4:select bank + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, (bank_cmd >> 4)&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_section]select bank %d fail.", (bank_cmd >> 4)&0x0F); + return FAIL; + } + + //step5:burn fw section + ret = gup_burn_proc(client, fw_section, start_addr, len); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_app_section]burn fw_section fail."); + return FAIL; + } + + //step6:send burn cmd to move data to flash from sram + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, bank_cmd&0x0F); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]send burn cmd fail."); + return FAIL; + } + GTP_DEBUG("[burn_fw_section]Wait for the burn is complete......"); + do{ + ret = gup_get_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, rd_buf, 1); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_app_section]Get burn state fail"); + return FAIL; + } + msleep(10); + //GTP_DEBUG("[burn_fw_app_section]Get burn state:%d.", rd_buf[GTP_ADDR_LENGTH]); + }while(rd_buf[GTP_ADDR_LENGTH]); + + //step7:recall fw section + ret = gup_recall_check(client, fw_section, start_addr, len); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_app_section]recall check %dk firmware fail.", len/1024); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_burn_fw_gwake(struct i2c_client *client) +{ + u8* fw_gwake = NULL; + u8 retry = 0; + s32 ret = 0; + //u16 start_index = 4*FW_SECTION_LENGTH+FW_DSP_LENGTH+FW_BOOT_LENGTH + FW_DSP_ISP_LENGTH + FW_BOOT_ISP_LENGTH; // 32 + 4 + 2 + 4 = 42K + u16 start_index; + + if(update_msg.fw_burned_len >= update_msg.fw_total_len) + { + GTP_DEBUG("No need to upgrade the gwake code!"); + return SUCCESS; + } + start_index = update_msg.fw_burned_len - FW_DSP_ISP_LENGTH; + GTP_INFO("[burn_fw_gwake]Begin burn gwake firmware---->>"); + + //step1:alloc memory + GTP_DEBUG("[burn_fw_gwake]step1:alloc memory"); + while(retry++ < 5) + { + fw_gwake = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_gwake == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_gwake]Alloc %dk byte memory success.", (FW_SECTION_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_gwake]Alloc memory fail,exit."); + return FAIL; + } + + //step2:load app_code firmware section 1 file data + GTP_DEBUG("[burn_fw_gwake]step2:load app_code firmware section 1 file data"); + ret = gup_load_section_file(fw_gwake, start_index, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 1 fail."); + goto exit_burn_fw_gwake; + } + + //step3:burn app_code firmware section 1 + GTP_DEBUG("[burn_fw_gwake]step3:burn app_code firmware section 1"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3A); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 1 fail."); + goto exit_burn_fw_gwake; + } + + //step5:load app_code firmware section 2 file data + GTP_DEBUG("[burn_fw_gwake]step5:load app_code firmware section 2 file data"); + ret = gup_load_section_file(fw_gwake, start_index+FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 2 fail."); + goto exit_burn_fw_gwake; + } + + //step6:burn app_code firmware section 2 + GTP_DEBUG("[burn_fw_gwake]step6:burn app_code firmware section 2"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3B); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 2 fail."); + goto exit_burn_fw_gwake; + } + + //step7:load app_code firmware section 3 file data + GTP_DEBUG("[burn_fw_gwake]step7:load app_code firmware section 3 file data"); + ret = gup_load_section_file(fw_gwake, start_index+2*FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 3 fail."); + goto exit_burn_fw_gwake; + } + + //step8:burn app_code firmware section 3 + GTP_DEBUG("[burn_fw_gwake]step8:burn app_code firmware section 3"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3C); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 3 fail."); + goto exit_burn_fw_gwake; + } + + //step9:load app_code firmware section 4 file data + GTP_DEBUG("[burn_fw_gwake]step9:load app_code firmware section 4 file data"); + ret = gup_load_section_file(fw_gwake, start_index + 3*FW_SECTION_LENGTH, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]load app_code firmware section 4 fail."); + goto exit_burn_fw_gwake; + } + + //step10:burn app_code firmware section 4 + GTP_DEBUG("[burn_fw_gwake]step10:burn app_code firmware section 4"); + ret = gup_burn_fw_gwake_section(client, fw_gwake, 0x9000, FW_SECTION_LENGTH, 0x3D); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_gwake]burn app_code firmware section 4 fail."); + goto exit_burn_fw_gwake; + } + + update_msg.fw_burned_len += FW_GWAKE_LENGTH; + GTP_DEBUG("[burn_fw_gwake]Burned length:%d", update_msg.fw_burned_len); + ret = SUCCESS; + +exit_burn_fw_gwake: + kfree(fw_gwake); + return ret; +} + +static u8 gup_burn_fw_finish(struct i2c_client *client) +{ + u8* fw_ss51 = NULL; + u8 retry = 0; + s32 ret = 0; + + GTP_INFO("[burn_fw_finish]burn first 8K of ss51 and finish update."); + //step1:alloc memory + GTP_DEBUG("[burn_fw_finish]step1:alloc memory"); + while(retry++ < 5) + { + fw_ss51 = (u8*)kzalloc(FW_SECTION_LENGTH, GFP_KERNEL); + if(fw_ss51 == NULL) + { + continue; + } + else + { + GTP_DEBUG("[burn_fw_finish]Alloc %dk byte memory success.", (FW_SECTION_LENGTH/1024)); + break; + } + } + if(retry >= 5) + { + GTP_ERROR("[burn_fw_finish]Alloc memory fail,exit."); + return FAIL; + } + + GTP_DEBUG("[burn_fw_finish]step2: burn ss51 first 8K."); + ret = gup_load_section_file(fw_ss51, 0, FW_SECTION_LENGTH, SEEK_SET); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_finish]load ss51 firmware section 1 fail."); + goto exit_burn_fw_finish; + } + + GTP_DEBUG("[burn_fw_finish]step3:clear control flag"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x00); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]clear control flag fail."); + goto exit_burn_fw_finish; + } + + GTP_DEBUG("[burn_fw_finish]step4:burn ss51 firmware section 1"); + ret = gup_burn_fw_section(client, fw_ss51, 0xC000, 0x01); + if(FAIL == ret) + { + GTP_ERROR("[burn_fw_finish]burn ss51 firmware section 1 fail."); + goto exit_burn_fw_finish; + } + + //step11:enable download DSP code + GTP_DEBUG("[burn_fw_finish]step5:enable download DSP code "); + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x99); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]enable download DSP code fail."); + goto exit_burn_fw_finish; + } + + //step12:release ss51 & hold dsp + GTP_DEBUG("[burn_fw_finish]step6:release ss51 & hold dsp"); + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x08); + if(ret <= 0) + { + GTP_ERROR("[burn_fw_finish]release ss51 & hold dsp fail."); + goto exit_burn_fw_finish; + } + + if (fw_ss51) + { + kfree(fw_ss51); + } + return SUCCESS; + +exit_burn_fw_finish: + if (fw_ss51) + { + kfree(fw_ss51); + } + return FAIL; +} +s32 gup_update_proc(void *dir) +{ + s32 ret = 0; + s32 update_ret = FAIL; + u8 retry = 0; + st_fw_head fw_head; + struct goodix_ts_data *ts = NULL; + + GTP_DEBUG("[update_proc]Begin update ......"); + + ts = i2c_get_clientdata(i2c_connect_client); + +#if GTP_AUTO_UPDATE + if (searching_file) + { + u8 timeout = 0; + searching_file = 0; // exit .bin update file searching + GTP_INFO("Exiting searching .bin update file..."); + while ((show_len != 200) && (show_len != 100) && (timeout++ < 100)) // wait for auto update quitted completely + { + msleep(100); + } + } +#endif + + show_len = 1; + total_len = 100; + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + return gup_fw_download_proc(dir, GTP_FL_FW_BURN); + } +#endif + + update_msg.file = NULL; + ret = gup_check_update_file(i2c_connect_client, &fw_head, (u8*)dir); //20121211 + if(FAIL == ret) + { + GTP_ERROR("[update_proc]check update file fail."); + goto file_fail; + } + + ret = gup_get_ic_fw_msg(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]get ic message fail."); + goto file_fail; + } + + ret = gup_enter_update_judge(&fw_head); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]Check *.bin file fail."); + goto file_fail; + } + + ts->enter_update = 1; + gtp_irq_disable(ts); +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + ret = gup_enter_update_mode(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]enter update mode fail."); + goto update_fail; + } + + while(retry++ < 5) + { + show_len = 10; + total_len = 100; + update_msg.fw_burned_len = 0; + ret = gup_burn_dsp_isp(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn dsp isp fail."); + continue; + } + + show_len = 20; + ret = gup_burn_fw_ss51(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn ss51 firmware fail."); + continue; + } + + show_len = 30; + ret = gup_burn_fw_dsp(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn dsp firmware fail."); + continue; + } + + show_len = 40; + ret = gup_burn_fw_boot(i2c_connect_client); + if(FAIL == ret) + { + GTP_ERROR("[update_proc]burn bootloader firmware fail."); + continue; + } + show_len = 50; + + ret = gup_burn_fw_boot_isp(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn boot_isp firmware fail."); + continue; + } + + show_len = 60; + ret = gup_burn_fw_link(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn link firmware fail."); + continue; + } + + show_len = 70; + ret = gup_burn_fw_gwake(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn app_code firmware fail."); + continue; + } + show_len = 80; + + ret = gup_burn_fw_finish(i2c_connect_client); + if (FAIL == ret) + { + GTP_ERROR("[update_proc]burn finish fail."); + continue; + } + show_len = 90; + GTP_INFO("[update_proc]UPDATE SUCCESS."); + retry = 0; + break; + } + + if (retry >= 5) + { + GTP_ERROR("[update_proc]retry timeout,UPDATE FAIL."); + update_ret = FAIL; + } + else + { + update_ret = SUCCESS; + } + +update_fail: + GTP_DEBUG("[update_proc]leave update mode."); + gup_leave_update_mode(ts); + + msleep(100); + + if (SUCCESS == update_ret) + { + if (ts->fw_error) + { + GTP_INFO("firmware error auto update, resent config!"); + gup_init_panel(ts); + } + else + { + GTP_DEBUG("[update_proc]send config."); + ret = gtp_send_cfg(i2c_connect_client); + if (ret < 0) + { + GTP_ERROR("[update_proc]send config fail."); + } + else + { + msleep(100); + } + } + } + ts->enter_update = 0; + gtp_irq_enable(ts); + +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); +#endif + +file_fail: + if (update_msg.file && !IS_ERR(update_msg.file)) + { + if (update_msg.old_fs) + { + set_fs(update_msg.old_fs); + } + filp_close(update_msg.file, NULL); + } +#if (GTP_AUTO_UPDATE && GTP_AUTO_UPDATE_CFG && GTP_HEADER_FW_UPDATE) + if (NULL == dir) + { + gup_search_file(AUTO_SEARCH_CFG); + if (got_file_flag & CFG_FILE_READY) + { + ret = gup_update_config(i2c_connect_client); + if(ret <= 0) + { + GTP_ERROR("Update config failed."); + } + _CLOSE_FILE(update_msg.cfg_file); + msleep(500); //waiting config to be stored in FLASH. + } + } +#endif + + total_len = 100; + if (SUCCESS == update_ret) + { + show_len = 100; + return SUCCESS; + } + else + { + show_len = 200; + return FAIL; + } +} + +#if GTP_AUTO_UPDATE +u8 gup_init_update_proc(struct goodix_ts_data *ts) +{ + struct task_struct *thread = NULL; + + GTP_INFO("Ready to run update thread."); + +#if GTP_COMPATIBLE_MODE + if (CHIP_TYPE_GT9F == ts->chip_type) + { + thread = kthread_run(gup_update_proc, "update", "fl update"); + } + else +#endif + { + thread = kthread_run(gup_update_proc, (void*)NULL, "guitar_update"); + } + if (IS_ERR(thread)) + { + GTP_ERROR("Failed to create update thread.\n"); + return -1; + } + + return 0; +} +#endif + + +//************************** For GT9XXF Start ***********************// +#define FW_DOWNLOAD_LENGTH 0x4000 +#define FW_SS51_SECTION_LEN 0x2000 // 4 section, each 8k +#define FL_PACK_SIZE 1024 +#define GUP_FW_CHK_SIZE FL_PACK_SIZE //FL_PACK_SIZE + +#define FL_UPDATE_PATH "/data/_fl_update_.bin" +#define FL_UPDATE_PATH_SD "/sdcard/_fl_update_.bin" +//for clk cal +#define PULSE_LENGTH (200) +#define INIT_CLK_DAC (50) +#define MAX_CLK_DAC (120) +#define CLK_AVG_TIME (1) +#define MILLION 1000000 + +#define _wRW_MISCTL__RG_DMY 0x4282 +#define _bRW_MISCTL__RG_OSC_CALIB 0x4268 +#define _fRW_MISCTL__GIO0 0x41e9 +#define _fRW_MISCTL__GIO1 0x41ed +#define _fRW_MISCTL__GIO2 0x41f1 +#define _fRW_MISCTL__GIO3 0x41f5 +#define _fRW_MISCTL__GIO4 0x41f9 +#define _fRW_MISCTL__GIO5 0x41fd +#define _fRW_MISCTL__GIO6 0x4201 +#define _fRW_MISCTL__GIO7 0x4205 +#define _fRW_MISCTL__GIO8 0x4209 +#define _fRW_MISCTL__GIO9 0x420d +#define _fRW_MISCTL__MEA 0x41a0 +#define _bRW_MISCTL__MEA_MODE 0x41a1 +#define _wRW_MISCTL__MEA_MAX_NUM 0x41a4 +#define _dRO_MISCTL__MEA_VAL 0x41b0 +#define _bRW_MISCTL__MEA_SRCSEL 0x41a3 +#define _bRO_MISCTL__MEA_RDY 0x41a8 +#define _rRW_MISCTL__ANA_RXADC_B0_ 0x4250 +#define _bRW_MISCTL__RG_LDO_A18_PWD 0x426f +#define _bRW_MISCTL__RG_BG_PWD 0x426a +#define _bRW_MISCTL__RG_CLKGEN_PWD 0x4269 +#define _fRW_MISCTL__RG_RXADC_PWD 0x426a +#define _bRW_MISCTL__OSC_CK_SEL 0x4030 +#define _rRW_MISCTL_RG_DMY83 0x4283 +#define _rRW_MISCTL__GIO1CTL_B2_ 0x41ee +#define _rRW_MISCTL__GIO1CTL_B1_ 0x41ed + + +#if GTP_COMPATIBLE_MODE + +u8 i2c_opr_buf[GTP_ADDR_LENGTH + FL_PACK_SIZE] = {0}; +u8 chk_cmp_buf[FL_PACK_SIZE] = {0}; + +extern s32 gtp_fw_startup(struct i2c_client *client); +static u8 gup_download_fw_dsp(struct i2c_client *client, u8 dwn_mode); +static s32 gup_burn_fw_proc(struct i2c_client *client, u16 start_addr, s32 start_index, s32 burn_len); +static s32 gup_check_and_repair(struct i2c_client *client, u16 start_addr, s32 start_index, s32 chk_len); + + +u8 gup_check_fs_mounted(char *path_name) +{ + struct path root_path; + struct path path; + int err; + err = kern_path("/", LOOKUP_FOLLOW, &root_path); + + if (err) + { + GTP_DEBUG("\"/\" NOT Mounted: %d", err); + return FAIL; + } + err = kern_path(path_name, LOOKUP_FOLLOW, &path); + + if (err) + { + GTP_DEBUG("%s NOT Mounted: %d", path_name, err); + return FAIL; + } + +#if 1 + path_put(&path); + return SUCCESS; +#else + if (path.mnt->mnt_sb == root_path.mnt->mnt_sb) + { + //-- not mounted + path_put(&path); + return FAIL; + } + else + { + path_put(&path); + return SUCCESS; + } +#endif +} + +s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len) +{ + s32 ret = 0; + s32 write_bytes = 0; + s32 retry = 0; + u8 *tx_buf = buf; + + while (len > 0) + { + i2c_opr_buf[0] = (u8)(addr >> 8); + i2c_opr_buf[1] = (u8)(addr & 0xFF); + if (len > FL_PACK_SIZE) + { + write_bytes = FL_PACK_SIZE; + } + else + { + write_bytes = len; + } + memcpy(i2c_opr_buf + 2, tx_buf, write_bytes); + for (retry = 0; retry < 5; ++retry) + { + ret = gup_i2c_write(client, i2c_opr_buf, write_bytes + GTP_ADDR_LENGTH); + if (ret == 1) + { + break; + } + } + if (retry >= 5) + { + GTP_ERROR("retry timeout, I2C write 0x%04X %d bytes failed!", addr, write_bytes); + return -1; + } + addr += write_bytes; + len -= write_bytes; + tx_buf += write_bytes; + } + + return 1; +} + +s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len) +{ + s32 ret = 0; + s32 read_bytes = 0; + s32 retry = 0; + u8 *tx_buf = buf; + + while (len > 0) + { + i2c_opr_buf[0] = (u8)(addr >> 8); + i2c_opr_buf[1] = (u8)(addr & 0xFF); + if (len > FL_PACK_SIZE) + { + read_bytes = FL_PACK_SIZE; + } + else + { + read_bytes = len; + } + for (retry = 0; retry < 5; ++retry) + { + ret = gup_i2c_read(client, i2c_opr_buf, read_bytes + GTP_ADDR_LENGTH); + if (ret == 2) + { + break; + } + } + if (retry >= 5) + { + GTP_ERROR("retry timeout, I2C read 0x%04X %d bytes failed!", addr, read_bytes); + return -1; + } + memcpy(tx_buf, i2c_opr_buf + 2, read_bytes); + addr += read_bytes; + len -= read_bytes; + tx_buf += read_bytes; + } + return 2; +} + + + +// main clock calibration +// bit: 0~7, val: 0/1 +static void gup_bit_write(s32 addr, s32 bit, s32 val) +{ + u8 buf; + i2c_read_bytes(i2c_connect_client, addr, &buf, 1); + + buf = (buf & (~((u8)1 << bit))) | ((u8)val << bit); + + i2c_write_bytes(i2c_connect_client, addr, &buf, 1); +} + +static void gup_clk_count_init(s32 bCh, s32 bCNT) +{ + u8 buf; + + //_fRW_MISCTL__MEA_EN = 0; //Frequency measure enable + gup_bit_write(_fRW_MISCTL__MEA, 0, 0); + //_fRW_MISCTL__MEA_CLR = 1; //Frequency measure clear + gup_bit_write(_fRW_MISCTL__MEA, 1, 1); + //_bRW_MISCTL__MEA_MODE = 0; //Pulse mode + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__MEA_MODE, &buf, 1); + //_bRW_MISCTL__MEA_SRCSEL = 8 + bCh; //From GIO1 + buf = 8 + bCh; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__MEA_SRCSEL, &buf, 1); + //_wRW_MISCTL__MEA_MAX_NUM = bCNT; //Set the Measure Counts = 1 + buf = bCNT; + i2c_write_bytes(i2c_connect_client, _wRW_MISCTL__MEA_MAX_NUM, &buf, 1); + //_fRW_MISCTL__MEA_CLR = 0; //Frequency measure not clear + gup_bit_write(_fRW_MISCTL__MEA, 1, 0); + //_fRW_MISCTL__MEA_EN = 1; + gup_bit_write(_fRW_MISCTL__MEA, 0, 1); +} + +static u32 gup_clk_count_get(void) +{ + s32 ready = 0; + s32 temp; + s8 buf[4]; + + while ((ready == 0)) //Wait for measurement complete + { + i2c_read_bytes(i2c_connect_client, _bRO_MISCTL__MEA_RDY, buf, 1); + ready = buf[0]; + } + + msleep(50); + + //_fRW_MISCTL__MEA_EN = 0; + gup_bit_write(_fRW_MISCTL__MEA, 0, 0); + i2c_read_bytes(i2c_connect_client, _dRO_MISCTL__MEA_VAL, buf, 4); + GTP_DEBUG("Clk_count 0: %2X", buf[0]); + GTP_DEBUG("Clk_count 1: %2X", buf[1]); + GTP_DEBUG("Clk_count 2: %2X", buf[2]); + GTP_DEBUG("Clk_count 3: %2X", buf[3]); + + temp = (s32)buf[0] + ((s32)buf[1] << 8) + ((s32)buf[2] << 16) + ((s32)buf[3] << 24); + GTP_INFO("Clk_count : %d", temp); + return temp; +} +u8 gup_clk_dac_setting(int dac) +{ + s8 buf1, buf2; + + i2c_read_bytes(i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1); + i2c_read_bytes(i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1); + + buf1 = (buf1 & 0xFFCF) | ((dac & 0x03) << 4); + buf2 = (dac >> 2) & 0x3f; + + i2c_write_bytes(i2c_connect_client, _wRW_MISCTL__RG_DMY, &buf1, 1); + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_OSC_CALIB, &buf2, 1); + + return 0; +} + +static u8 gup_clk_calibration_pin_select(s32 bCh) +{ + s32 i2c_addr; + + switch (bCh) + { + case 0: + i2c_addr = _fRW_MISCTL__GIO0; + break; + + case 1: + i2c_addr = _fRW_MISCTL__GIO1; + break; + + case 2: + i2c_addr = _fRW_MISCTL__GIO2; + break; + + case 3: + i2c_addr = _fRW_MISCTL__GIO3; + break; + + case 4: + i2c_addr = _fRW_MISCTL__GIO4; + break; + + case 5: + i2c_addr = _fRW_MISCTL__GIO5; + break; + + case 6: + i2c_addr = _fRW_MISCTL__GIO6; + break; + + case 7: + i2c_addr = _fRW_MISCTL__GIO7; + break; + + case 8: + i2c_addr = _fRW_MISCTL__GIO8; + break; + + case 9: + i2c_addr = _fRW_MISCTL__GIO9; + break; + } + + gup_bit_write(i2c_addr, 1, 0); + + return 0; +} + +void gup_output_pulse(int t) +{ + unsigned long flags; + //s32 i; + + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); + msleep(10); + + local_irq_save(flags); + + GTP_GPIO_OUTPUT(GTP_INT_PORT, 1); + msleep(50); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); + msleep(t - 50); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 1); + + local_irq_restore(flags); + + msleep(20); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); +} + +static void gup_sys_clk_init(void) +{ + u8 buf; + + //_fRW_MISCTL__RG_RXADC_CKMUX = 0; + gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 5, 0); + //_bRW_MISCTL__RG_LDO_A18_PWD = 0; //DrvMISCTL_A18_PowerON + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_LDO_A18_PWD, &buf, 1); + //_bRW_MISCTL__RG_BG_PWD = 0; //DrvMISCTL_BG_PowerON + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_BG_PWD, &buf, 1); + //_bRW_MISCTL__RG_CLKGEN_PWD = 0; //DrvMISCTL_CLKGEN_PowerON + buf = 0; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__RG_CLKGEN_PWD, &buf, 1); + //_fRW_MISCTL__RG_RXADC_PWD = 0; //DrvMISCTL_RX_ADC_PowerON + gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 0, 0); + //_fRW_MISCTL__RG_RXADC_REF_PWD = 0; //DrvMISCTL_RX_ADCREF_PowerON + gup_bit_write(_rRW_MISCTL__ANA_RXADC_B0_, 1, 0); + //gup_clk_dac_setting(60); + //_bRW_MISCTL__OSC_CK_SEL = 1;; + buf = 1; + i2c_write_bytes(i2c_connect_client, _bRW_MISCTL__OSC_CK_SEL, &buf, 1); +} + +s32 gup_clk_calibration(void) +{ + u8 buf; + //u8 trigger; + s32 i; + struct timeval start, end; + s32 count; + s32 count_ref; + s32 sec; + s32 usec; + //unsigned long flags; + struct goodix_ts_data *ts; + + buf = 0x0C; // hold ss51 and dsp + i2c_write_bytes(i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1); + + //_fRW_MISCTL__CLK_BIAS = 0; //disable clock bias + gup_bit_write(_rRW_MISCTL_RG_DMY83, 7, 0); + + //_fRW_MISCTL__GIO1_PU = 0; //set TOUCH INT PIN MODE as input + gup_bit_write(_rRW_MISCTL__GIO1CTL_B2_, 0, 0); + + //_fRW_MISCTL__GIO1_OE = 0; //set TOUCH INT PIN MODE as input + gup_bit_write(_rRW_MISCTL__GIO1CTL_B1_, 1, 0); + + //buf = 0x00; + //i2c_write_bytes(i2c_connect_client, _rRW_MISCTL__SWRST_B0_, &buf, 1); + //msleep(1000); + + GTP_INFO("CLK calibration GO"); + gup_sys_clk_init(); + gup_clk_calibration_pin_select(1);//use GIO1 to do the calibration + + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); + + ts = i2c_get_clientdata(i2c_connect_client); + + for (i = INIT_CLK_DAC; i < MAX_CLK_DAC; i++) + { + GTP_INFO("CLK calibration DAC %d", i); + + if (ts->gtp_is_suspend) + { + i = 72; // 80; // if sleeping while calibrating main clock, set it default 72 + break; + } + + gup_clk_dac_setting(i); + gup_clk_count_init(1, CLK_AVG_TIME); + + #if 0 + gup_output_pulse(PULSE_LENGTH); + count = gup_clk_count_get(); + + if (count > PULSE_LENGTH * 60)//60= 60Mhz * 1us + { + break; + } + + #else + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); + + //local_irq_save(flags); + do_gettimeofday(&start); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 1); + //local_irq_restore(flags); + + msleep(1); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); + msleep(1); + + //local_irq_save(flags); + do_gettimeofday(&end); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 1); + //local_irq_restore(flags); + + count = gup_clk_count_get(); + msleep(20); + GTP_GPIO_OUTPUT(GTP_INT_PORT, 0); + + usec = end.tv_usec - start.tv_usec; + sec = end.tv_sec - start.tv_sec; + count_ref = 60 * (usec+ sec * MILLION);//60= 60Mhz * 1us + + GTP_DEBUG("== time %d, %d, %d", sec, usec, count_ref); + + if (count > count_ref) + { + GTP_DEBUG("== count_diff %d", count - count_ref); + break; + } + + #endif + } + + //clk_dac = i; + + gtp_reset_guitar(i2c_connect_client, 20); + +#if 0//for debug + //-- ouput clk to GPIO 4 + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x41FA, &buf, 1); + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x4104, &buf, 1); + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x4105, &buf, 1); + buf = 0x00; + i2c_write_bytes(i2c_connect_client, 0x4106, &buf, 1); + buf = 0x01; + i2c_write_bytes(i2c_connect_client, 0x4107, &buf, 1); + buf = 0x06; + i2c_write_bytes(i2c_connect_client, 0x41F8, &buf, 1); + buf = 0x02; + i2c_write_bytes(i2c_connect_client, 0x41F9, &buf, 1); +#endif + + GTP_GPIO_AS_INT(GTP_INT_PORT); + return i; +} + + + +s32 gup_hold_ss51_dsp(struct i2c_client *client) +{ + s32 ret = -1; + s32 retry = 0; + u8 rd_buf[3]; + + while(retry++ < 200) + { + // step4:Hold ss51 & dsp + ret = gup_set_ic_msg(client, _rRW_MISCTL__SWRST_B0_, 0x0C); + if(ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + + // step5:Confirm hold + ret = gup_get_ic_msg(client, _rRW_MISCTL__SWRST_B0_, rd_buf, 1); + if (ret <= 0) + { + GTP_DEBUG("Hold ss51 & dsp I2C error,retry:%d", retry); + continue; + } + if (0x0C == rd_buf[GTP_ADDR_LENGTH]) + { + GTP_DEBUG("[enter_update_mode]Hold ss51 & dsp confirm SUCCESS"); + break; + } + GTP_DEBUG("Hold ss51 & dsp confirm 0x4180 failed,value:%d", rd_buf[GTP_ADDR_LENGTH]); + } + if(retry >= 200) + { + GTP_ERROR("Enter update Hold ss51 failed."); + return FAIL; + } + //DSP_CK and DSP_ALU_CK PowerOn + ret = gup_set_ic_msg(client, 0x4010, 0x00); + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]DSP_CK and DSP_ALU_CK PowerOn fail."); + return FAIL; + } + + //disable wdt + ret = gup_set_ic_msg(client, _bRW_MISCTL__TMR0_EN, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]disable wdt fail."); + return FAIL; + } + + //clear cache enable + ret = gup_set_ic_msg(client, _bRW_MISCTL__CACHE_EN, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]clear cache enable fail."); + return FAIL; + } + + //set boot from sram + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOTCTL_B0_, 0x02); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]set boot from sram fail."); + return FAIL; + } + + //software reboot + ret = gup_set_ic_msg(client, _bWO_MISCTL__CPU_SWRST_PULSE, 0x01); + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]software reboot fail."); + return FAIL; + } + + return SUCCESS; +} + +s32 gup_enter_update_mode_fl(struct i2c_client *client) +{ + s32 ret = -1; + //s32 retry = 0; + //u8 rd_buf[3]; + + //step1:RST output low last at least 2ms + GTP_GPIO_OUTPUT(GTP_RST_PORT, 0); + msleep(2); + + //step2:select I2C slave addr,INT:0--0xBA;1--0x28. + GTP_GPIO_OUTPUT(GTP_INT_PORT, (client->addr == 0x14)); + msleep(2); + + //step3:RST output high reset guitar + GTP_GPIO_OUTPUT(GTP_RST_PORT, 1); + + msleep(5); + + //select addr & hold ss51_dsp + ret = gup_hold_ss51_dsp(client); + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]hold ss51 & dsp failed."); + return FAIL; + } + + //clear control flag + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_CTL_, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]clear control flag fail."); + return FAIL; + } + + //set scramble + ret = gup_set_ic_msg(client, _rRW_MISCTL__BOOT_OPT_B0_, 0x00); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]set scramble fail."); + return FAIL; + } + + //enable accessing code + ret = gup_set_ic_msg(client, _bRW_MISCTL__MEM_CD_EN, 0x01); + + if (ret <= 0) + { + GTP_ERROR("[enter_update_mode]enable accessing code fail."); + return FAIL; + } + + return SUCCESS; +} + +static u8 gup_download_fw_dsp(struct i2c_client *client, u8 dwn_mode) +{ + s32 ret = 0; + + //step1:select bank2 + GTP_DEBUG("[download_fw_dsp]step1:select bank2"); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, 0x02); + if (ret == FAIL) + { + GTP_ERROR("select bank 2 fail"); + return FAIL; + } + + if (GTP_FL_FW_BURN == dwn_mode) + { + GTP_INFO("[download_fw_dsp]Begin download dsp fw---->>"); + + if (ret <= 0) + { + GTP_ERROR("[download_fw_dsp]select bank2 fail."); + return FAIL; + } + GTP_DEBUG("burn fw dsp"); + ret = gup_burn_fw_proc(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); // write the second ban + if (FAIL == ret) + { + GTP_ERROR("[download_fw_dsp]download FW dsp fail."); + return FAIL; + } + GTP_INFO("check firmware dsp"); + ret = gup_check_and_repair(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + if (FAIL == ret) + { + GTP_ERROR("check fw dsp failed!"); + return FAIL; + } + } + else if (GTP_FL_ESD_RECOVERY == dwn_mode) + { + GTP_INFO("[download_fw_dsp]Begin esd check dsp fw---->>"); + //GTP_INFO("esd recovery: check fw dsp"); + //ret = gup_check_and_repair(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + + //if(FAIL == ret) + { + //GTP_ERROR("[download_fw_dsp]Checked FW dsp fail, redownload fw dsp"); + GTP_INFO("esd recovery redownload firmware dsp code"); + ret = gup_burn_fw_proc(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + if (FAIL == ret) + { + GTP_ERROR("redownload fw dsp failed!"); + return FAIL; + } + } + } + else + { + GTP_INFO("check firmware dsp"); + ret = gup_check_and_repair(client, 0xC000, 2 * FW_DOWNLOAD_LENGTH, FW_DSP_LENGTH); + if (FAIL == ret) + { + GTP_ERROR("check fw dsp failed!"); + return FAIL; + } + } + return SUCCESS; +} + +static s32 gup_burn_fw_proc(struct i2c_client *client, u16 start_addr, s32 start_index, s32 burn_len) +{ + s32 ret = 0; + + GTP_DEBUG("burn firmware: 0x%04X, %d bytes, start_index: 0x%04X", start_addr, burn_len, start_index); + + ret = i2c_write_bytes(client, start_addr, (u8*)>p_default_FW_fl[FW_HEAD_LENGTH + start_index], burn_len); + if (ret < 0) + { + GTP_ERROR("burn 0x%04X, %d bytes failed!", start_addr, burn_len); + return FAIL; + } + return SUCCESS; +} + +static s32 gup_check_and_repair(struct i2c_client *client, u16 start_addr, s32 start_index, s32 chk_len) +{ + s32 ret = 0; + s32 cmp_len = 0; + u16 cmp_addr = start_addr; + s32 i = 0; + s32 chked_times = 0; + u8 chk_fail = 0; + + GTP_DEBUG("check firmware: start 0x%04X, %d bytes", start_addr, chk_len); + while ((chk_len > 0) && (chked_times < GTP_CHK_FW_MAX)) + { + if (chk_len >= GUP_FW_CHK_SIZE) + { + cmp_len = GUP_FW_CHK_SIZE; + } + else + { + cmp_len = chk_len; + } + ret = i2c_read_bytes(client, cmp_addr, chk_cmp_buf, cmp_len); + if (ret < 0) + { + chk_fail = 1; + break; + } + for (i = 0; i < cmp_len; ++i) + { + if (chk_cmp_buf[i] != gtp_default_FW_fl[FW_HEAD_LENGTH + start_index +i]) + { + chk_fail = 1; + i2c_write_bytes(client, cmp_addr+i, >p_default_FW_fl[FW_HEAD_LENGTH + start_index + i], cmp_len-i); + GTP_ERROR("Check failed index: %d(%d != %d), redownload chuck", i, chk_cmp_buf[i], + gtp_default_FW_fl[FW_HEAD_LENGTH + start_index +i]); + break; + } + } + if (chk_fail == 1) + { + chk_fail = 0; + chked_times++; + } + else + { + cmp_addr += cmp_len; + start_index += cmp_len; + chk_len -= cmp_len; + } + } + if (chk_len > 0) + { + GTP_ERROR("cmp_addr: 0x%04X, start_index: 0x%02X, chk_len: 0x%04X", cmp_addr, + start_index, chk_len); + return FAIL; + } + return SUCCESS; +} + +static u8 gup_download_fw_ss51(struct i2c_client *client, u8 dwn_mode) +{ + s32 section = 0; + s32 ret = 0; + s32 start_index = 0; + u8 bank = 0; + u16 burn_addr = 0xC000; + + if (GTP_FL_FW_BURN == dwn_mode) + { + GTP_INFO("download firmware ss51"); + } + else + { + GTP_INFO("check firmware ss51"); + } + for (section = 1; section <= 4; section += 2) + { + switch (section) + { + case 1: + bank = 0x00; + burn_addr = (section - 1) * FW_SS51_SECTION_LEN + 0xC000; + break; + case 3: + bank = 0x01; + burn_addr = (section - 3) * FW_SS51_SECTION_LEN + 0xC000; + break; + } + start_index = (section - 1) * FW_SS51_SECTION_LEN; + + GTP_DEBUG("download firmware ss51: select bank%d", bank); + ret = gup_set_ic_msg(client, _bRW_MISCTL__SRAM_BANK, bank); + if (GTP_FL_FW_BURN == dwn_mode) + { + GTP_INFO("download firmware ss51 section%d & %d", section, section+1); + ret = gup_burn_fw_proc(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("download fw ss51 section%d & %d failed!", section, section+1); + return FAIL; + } + GTP_INFO("check firmware ss51 section%d & %d", section, section+1); + ret = gup_check_and_repair(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("check ss51 section%d & %d failed!", section, section+1); + return FAIL; + } + } + else if (GTP_FL_ESD_RECOVERY == dwn_mode)// esd recovery mode + { + // GTP_INFO("esd recovery check ss51 section%d & %d", section, section+1); + // ret = gup_check_and_repair(client, burn_addr, start_index, FW_SS51_SECTION_LEN); + // if (ret == FAIL) + { + // GTP_ERROR("check ss51 section%d failed, redownload section%d", section, section); + GTP_INFO("esd recovery redownload ss51 section%d & %d", section, section+1); + ret = gup_burn_fw_proc(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("download fw ss51 section%d failed!", section); + return FAIL; + } + } + } + else + { + GTP_INFO("check firmware ss51 section%d & %d", section, section+1); + ret = gup_check_and_repair(client, burn_addr, start_index, 2 * FW_SS51_SECTION_LEN); + if (ret == FAIL) + { + GTP_ERROR("check ss51 section%d & %d failed!", section, section+1); + return FAIL; + } + } + } + + return SUCCESS; +} + + +static s32 gup_prepare_fl_fw(char *path, st_fw_head *fw_head) +{ + s32 ret = 0; + s32 i = 0; + s32 timeout = 0; + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + if (!memcmp(path, "update", 6)) + { + GTP_INFO("Search for GT9XXF firmware file to update"); + + searching_file = 1; + for (i = 0; i < GUP_SEARCH_FILE_TIMES; ++i) + { + if (0 == searching_file) + { + GTP_INFO("Force terminate auto update for GT9XXF..."); + return FAIL; + } + GTP_DEBUG("Search for %s, %s for fw update.(%d/%d)", FL_UPDATE_PATH, FL_UPDATE_PATH_SD, i+1, GUP_SEARCH_FILE_TIMES); + update_msg.file = filp_open(FL_UPDATE_PATH, O_RDONLY, 0); + if (IS_ERR(update_msg.file)) + { + update_msg.file = filp_open(FL_UPDATE_PATH_SD, O_RDONLY, 0); + if (IS_ERR(update_msg.file)) + { + msleep(3000); + continue; + } + else + { + path = FL_UPDATE_PATH_SD; + break; + } + } + else + { + path = FL_UPDATE_PATH; + break; + } + } + searching_file = 0; + if (i == 50) + { + GTP_INFO("Search timeout, update aborted"); + return FAIL; + } + else + { + GTP_INFO("GT9XXF firmware file %s found!", path); + _CLOSE_FILE(update_msg.file); + } + while (ts->rqst_processing && (timeout++ < 5)) + { + GTP_DEBUG("request processing, waiting for accomplishment"); + msleep(1000); + } + } + GTP_INFO("Firmware update file path: %s", path); + + update_msg.file = filp_open(path, O_RDONLY, 0); + + if (IS_ERR(update_msg.file)) + { + GTP_ERROR("Open update file(%s) error!", path); + return FAIL; + } + + update_msg.old_fs = get_fs(); + set_fs(KERNEL_DS); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + update_msg.fw_total_len = update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_END); + + update_msg.force_update = 0xBE; // GT9XXF ignore the 0xBE + if (update_msg.fw_total_len != sizeof(gtp_default_FW_fl)) + { + GTP_ERROR("Inconsistent fw size. default size: %d(%dK), file size: %d(%dK)", sizeof(gtp_default_FW_fl), sizeof(gtp_default_FW_fl)/1024, update_msg.fw_total_len, update_msg.fw_total_len/1024); + set_fs(update_msg.old_fs); + _CLOSE_FILE(update_msg.file); + return FAIL; + } + + update_msg.fw_total_len -= FW_HEAD_LENGTH; + GTP_DEBUG("Fimrware size: %d(%dK)", update_msg.fw_total_len, update_msg.fw_total_len / 1024); + + update_msg.file->f_op->llseek(update_msg.file, 0, SEEK_SET); + ret = update_msg.file->f_op->read(update_msg.file, (char*)gtp_default_FW_fl, + update_msg.fw_total_len + FW_HEAD_LENGTH, + &update_msg.file->f_pos); + set_fs(update_msg.old_fs); + _CLOSE_FILE(update_msg.file); + + if (ret < 0) + { + GTP_ERROR("read %s failed, err-code: %d", path, ret); + return FAIL; + } + return SUCCESS; +} +static u8 gup_check_update_file_fl(struct i2c_client *client, st_fw_head* fw_head, char* path) +{ + s32 ret = 0; + s32 i = 0; + s32 fw_checksum = 0; + + if (NULL != path) + { + ret = gup_prepare_fl_fw(path, fw_head); + if (FAIL == ret) + { + return FAIL; + } + } + + memcpy(fw_head, gtp_default_FW_fl, FW_HEAD_LENGTH); + GTP_INFO("FILE HARDWARE INFO: %02x%02x%02x%02x", fw_head->hw_info[0], fw_head->hw_info[1], fw_head->hw_info[2], fw_head->hw_info[3]); + GTP_INFO("FILE PID: %s", fw_head->pid); + fw_head->vid = ((fw_head->vid & 0xFF00) >> 8) + ((fw_head->vid & 0x00FF) << 8); + GTP_INFO("FILE VID: %04x", fw_head->vid); + + //check firmware legality + fw_checksum = 0; + for(i = FW_HEAD_LENGTH; i < (FW_HEAD_LENGTH + update_msg.fw_total_len); i += 2) + { + fw_checksum += (gtp_default_FW_fl[i] << 8) + gtp_default_FW_fl[i+1]; + } + ret = SUCCESS; + + GTP_DEBUG("firmware checksum: %x", fw_checksum&0xFFFF); + if (fw_checksum & 0xFFFF) + { + GTP_ERROR("Illegal firmware file."); + ret = FAIL; + } + + return ret; +} + +s32 gup_fw_download_proc(void *dir, u8 dwn_mode) +{ + s32 ret = 0; + u8 retry = 0; + st_fw_head fw_head; + struct goodix_ts_data *ts; + + ts = i2c_get_clientdata(i2c_connect_client); + if (NULL == dir) + { + if(GTP_FL_FW_BURN == dwn_mode) // GT9XXF firmware burn mode + { + GTP_INFO("[fw_download_proc]Begin fw download ......"); + } + else if (GTP_FL_ESD_RECOVERY == dwn_mode) // GTP_FL_ESD_RECOVERY: GT9XXF esd recovery mode + { + GTP_INFO("[fw_download_proc]Begin fw esd recovery check ......"); + } + else + { + GTP_INFO("[fw_download_proc]Being fw repair check......"); + } + } + else + { + GTP_INFO("[fw_download_proc]Begin firmware update by bin file"); + } + + total_len = 100; + show_len = 0; + + ret = gup_check_update_file_fl(i2c_connect_client, &fw_head, (char *)dir); + show_len = 10; + + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]check update file fail."); + goto file_fail; + } + + if (!memcmp(fw_head.pid, "950", 3)) + { + ts->is_950 = 1; + GTP_DEBUG("GT9XXF Ic Type: gt950"); + } + else + { + ts->is_950 = 0; + } + + if (NULL != dir) + { + gtp_irq_disable(ts); +#if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_OFF); +#endif + } + + ret = gup_enter_update_mode_fl(i2c_connect_client); + show_len = 20; + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]enter update mode fail."); + goto download_fail; + } + + while (retry++ < 5) + { + ret = gup_download_fw_ss51(i2c_connect_client, dwn_mode); + show_len = 60; + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]burn ss51 firmware fail."); + continue; + } + + ret = gup_download_fw_dsp(i2c_connect_client, dwn_mode); + show_len = 80; + if (FAIL == ret) + { + GTP_ERROR("[fw_download_proc]burn dsp firmware fail."); + continue; + } + + GTP_INFO("[fw_download_proc]UPDATE SUCCESS."); + break; + } + + if (retry >= 5) + { + GTP_ERROR("[fw_download_proc]retry timeout,UPDATE FAIL."); + goto download_fail; + } + + if (NULL != dir) + { + gtp_irq_enable(ts); + gtp_fw_startup(ts->client); + #if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); + #endif + } + show_len = 100; + return SUCCESS; + +download_fail: + if (NULL != dir) + { + gtp_irq_enable(ts); + gtp_fw_startup(ts->client); + #if GTP_ESD_PROTECT + gtp_esd_switch(ts->client, SWITCH_ON); + #endif + } +file_fail: + show_len = 200; + + return FAIL; +} + +#endif + +//**************** For GT9XXF End ********************// -- 2.34.1