1、添加py文件到sdk
authorp15692025051 <846603105@qq.com>
Mon, 8 May 2023 07:46:09 +0000 (15:46 +0800)
committerp15692025051 <846603105@qq.com>
Mon, 8 May 2023 07:46:09 +0000 (15:46 +0800)
2、增加体温功能
3、优化gps定位逻辑

13 files changed:
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/EventMesh.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/appFactoryMode.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/btn_device_ec800m.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/capacitive_hynitron_cst816d_update.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/code.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/common.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/constants.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/initTP.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/lcd.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/location.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/mgr.py
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/protocol.py [new file with mode: 0644]
2.sdk/Helios_SDK/services/microPython/ports/quectel/core/ui.py

diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/EventMesh.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/EventMesh.py
new file mode 100644 (file)
index 0000000..1b32fbd
--- /dev/null
@@ -0,0 +1,74 @@
+import _thread
+import usys
+
+
+class EventStore(object):
+    def __init__(self):
+        self.map = dict()
+        self.log = None
+        self.__filters = []
+
+    def add_filter(self, flt):
+        self.__filters.append(flt)
+
+    def append(self, event, cb):
+        self.map[event] = cb
+
+    def fire_async(self, event, msg):
+        if event in self.map:
+            _thread.start_new_thread(self.map[event], (event, msg))
+            if self.log:
+                self.log.info("ASYNC executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, None))
+
+    def fire_sync(self, event, msg):
+        res = None
+        try:
+            if event in self.map:
+                res = self.map[event](event, msg)
+        except Exception as e:
+            usys.print_exception(e)
+            if self.log:
+                self.log.info("ERROR executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, res))
+        if event not in self.__filters:
+            if self.log:
+                self.log.info("SYNC executed (event) -> {} (params) -> {} (result) -> {}".format(event, msg, res))
+        return res
+
+
+event_store = EventStore()
+
+
+def subscribe(event, cb):
+    """
+    subscribe event and cb
+    """
+    return event_store.append(event, cb)
+
+
+def publish(event, msg=None):
+    """
+    publish event and msg
+    """
+    return publish_sync(event, msg)
+
+
+def publish_async(event, msg=None):
+    """
+    异步发送
+    """
+    return event_store.fire_async(event, msg)
+
+
+def publish_sync(event, msg=None):
+    """
+    同步发送
+    """
+    return event_store.fire_sync(event, msg)
+
+
+def set_log(log_adapter):
+    event_store.log = log_adapter
+
+
+def add_filter(flt):
+    event_store.add_filter(flt)
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/appFactoryMode.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/appFactoryMode.py
new file mode 100644 (file)
index 0000000..078e0d7
--- /dev/null
@@ -0,0 +1,159 @@
+import osTimer
+import lvgl as lv
+import EventMesh
+import osTimer
+import constants
+import ujson
+import ql_fs
+import audio
+from machine import Pin
+from ui import style_screen,style_font_youyuan_20,ContStyle,style_btn,style_img,Screen,style_contact_btn
+import audio
+factorymode_cont_y = 0
+factorymode_screen = lv.obj()
+factorymode_screen.center()
+factorymode_screen.set_size(240, 320)
+factorymode_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+factorymode_title = lv.label(factorymode_screen)
+factorymode_title.set_pos(0, 10)
+factorymode_title.set_size(240, 40)
+factorymode_title.set_text("-工厂模式-")
+factorymode_title.set_long_mode(lv.label.LONG.WRAP)
+factorymode_title.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
+factorymode_title.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+factorymode_cont = lv.obj(factorymode_screen)
+factorymode_cont.set_pos(0, 50)
+factorymode_cont.set_size(240, 270)
+factorymode_cont_style = ContStyle()
+factorymode_cont.add_style(
+    factorymode_cont_style.style_cont(0, lv.color_make(0x00, 0x00, 0x00), lv.color_make(0x00, 0x00, 0x00), 255),
+    lv.PART.MAIN | lv.STATE.DEFAULT)
+
+factorymode_location = lv.btn(factorymode_cont)
+factorymode_location.set_pos(0, factorymode_cont_y)
+factorymode_location.set_size(240, 60)
+factorymode_location_label = lv.label(factorymode_location)
+factorymode_location_label.set_text("定位测试")
+factorymode_location.set_style_pad_all(0, lv.STATE.DEFAULT)
+factorymode_location_label.align(lv.ALIGN.LEFT_MID, 70, 0)
+factorymode_location_label.set_style_text_color(lv.color_make(0xff, 0xff, 0xff), lv.STATE.DEFAULT)
+factorymode_location_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+factorymode_location.add_style(style_btn, lv.PART.MAIN | lv.STATE.DEFAULT)
+factorymode_cont_y+=60
+
+class FactoryModeScreen(Screen):
+    NAME = "factorymode"
+    def __init__(self):
+        super().__init__()
+        self.meta = factorymode_screen
+        factorymode_location.add_event_cb(lambda e: self.load_screen(e, {"screen": "FactoryModeLocation"}), lv.EVENT.CLICKED, None)
+    
+
+    def done_return(self):
+        EventMesh.publish("load_screen", {"screen": "main_menu"})
+
+    def btn1_release(self):
+        EventMesh.publish("load_screen", {"screen": "main_menu"})
+        
+    def btn8_press(self):
+        EventMesh.publish("load_screen", {"screen": "main_menu"})
+
+
+FactoryModeLocation_screen = lv.obj()
+FactoryModeLocation_screen.center()
+FactoryModeLocation_screen.set_size(240, 320)
+FactoryModeLocation_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+FactoryModeLocation_WIFI_label = lv.label(FactoryModeLocation_screen)
+FactoryModeLocation_WIFI_label.set_text("WIFI:\n")
+FactoryModeLocation_WIFI_label.set_size(240, 80)
+FactoryModeLocation_WIFI_label.set_pos(0, 0)
+FactoryModeLocation_WIFI_label.set_style_text_color(lv.color_make(0xff, 0xff, 0xff), lv.STATE.DEFAULT)
+FactoryModeLocation_WIFI_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+FactoryModeLocation_CALL_label = lv.label(FactoryModeLocation_screen)
+FactoryModeLocation_CALL_label.set_text("CALL:\n")
+FactoryModeLocation_CALL_label.set_size(240, 40)
+FactoryModeLocation_CALL_label.set_pos(0, 80)
+FactoryModeLocation_CALL_label.set_style_text_color(lv.color_make(0xff, 0xff, 0xff), lv.STATE.DEFAULT)
+FactoryModeLocation_CALL_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+FactoryModeLocation_GNSS_label = lv.label(FactoryModeLocation_screen)
+FactoryModeLocation_GNSS_label.set_text("GNSS:\n")
+FactoryModeLocation_GNSS_label.set_size(240, 200)
+FactoryModeLocation_GNSS_label.set_pos(0, 120)
+FactoryModeLocation_GNSS_label.set_style_text_color(lv.color_make(0xff, 0xff, 0xff), lv.STATE.DEFAULT)
+FactoryModeLocation_GNSS_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+class FactoryModeLocationScreen(Screen):
+    NAME = "FactoryModeLocation"
+    def __init__(self):
+        super().__init__()
+        self.meta = FactoryModeLocation_screen
+
+    def post_processor_after_initialization(self):
+        EventMesh.subscribe("PUSH_LOCATION_DATA",self.GET_LOCATION_DATA)
+        EventMesh.publish(constants.EVENT.START_LOCATION, 1) #测试模式
+        FactoryModeLocation_GNSS_label.set_text("GNSS:\n") 
+        FactoryModeLocation_WIFI_label.set_text("WIFI:\n")
+        FactoryModeLocation_CALL_label.set_text("CALL:")
+    def GET_LOCATION_DATA(self, event, msg):
+        #print("GPS:{}".format(msg[0]))
+        print("WIFI:{}".format(msg[1]))
+        print("CALL:{}".format(msg[2]))
+        EventMesh.publish("system_sleep_rest")#防止黑屏
+        if msg[1] != [] : #WIFI
+            WIFI_len = len(msg[1][1])
+            WIFI_DATA = "WIFI:\n"
+            if WIFI_len > 3:
+                WIFI_len = 3
+            for i in range(WIFI_len) :
+                WIFI_DATA += "{}\n".format(msg[1][1][i])
+            FactoryModeLocation_WIFI_label.set_text(WIFI_DATA)
+        
+        if len(msg[0]) > 1 : #GPS
+            GNSS_DATA = "GNSS:\n"
+
+            gsv_data = msg[0][1].split("GSV")
+            if len(gsv_data) < 2 :
+                return
+            gsv_data = gsv_data[1:]
+            
+            GSV_dict= {}
+            for i in range(len(gsv_data)) :
+                gsv_data[i] = gsv_data[i].split("\r\n")[0]
+                gsv_tmp = gsv_data[i].split(",")
+                if len(gsv_tmp) < 7 :
+                    break
+                gsv_tmp = gsv_tmp[4:]
+                #print("gsv_tmp:{}".format(gsv_tmp))
+                for i in range(len(gsv_tmp)) :
+                    if i % 4 == 0:
+                        GSV_dict[gsv_tmp[i]] = gsv_tmp[i+3]
+                        #print("GSV_dict:{}:[{}]".format(gsv_tmp[i],gsv_tmp[i+3]))
+                    if len(gsv_tmp)-i < 4:
+                        break 
+            count = 0
+            for key in GSV_dict :
+                GNSS_DATA+="        {}:[{}]\n".format(key,GSV_dict[key])
+                count+=1
+                if count > 9:
+                    break
+            print("GxGSV:{}".format(GNSS_DATA))
+            FactoryModeLocation_GNSS_label.set_text(GNSS_DATA)  
+        if msg[2] != [] :#基站
+            if len(msg[2]) > 2 :
+                FactoryModeLocation_CALL_label.set_text("CALL:{}".format(msg[2][0]))      
+    def Close(self):
+        EventMesh.publish(constants.EVENT.CLOSE_LOCATION) 
+
+    def done_return(self):
+        EventMesh.publish("load_screen", {"screen": "factorymode"})
+
+    def btn1_release(self):
+        EventMesh.publish("load_screen", {"screen": "factorymode"})
+        
+    def btn8_press(self):
+        EventMesh.publish("load_screen", {"screen": "main_menu"})
\ No newline at end of file
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/btn_device_ec800m.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/btn_device_ec800m.py
new file mode 100644 (file)
index 0000000..310e0be
--- /dev/null
@@ -0,0 +1,80 @@
+from common import Abstract
+import machine
+import osTimer
+from misc import PowerKey
+import EventMesh
+from machine import Pin
+
+
+class BtnDevice(Abstract):
+
+    def __init__(self, tp=None):
+        self.pk = PowerKey()
+        self.__pwk_timer = osTimer()
+
+        self.keypad = machine.KeyPad(4, 1)
+        self.__PowerDownTimeOut = 2000
+        self.__tp = tp
+
+    def post_processor_after_instantiation(self):
+        self.keypad.init()
+        self.keypad.set_callback(self.key_callback)
+        self.pk.powerKeyEventRegister(self.pwk_callback)
+        if self.__tp:
+            self.__tp.set_callback(self.__ui_callback)
+
+    def __ui_callback(self, para):
+        print("para = {}".format(para))
+        if para == 0:
+            EventMesh.publish("done_left_to_right")
+            print("<-")
+        elif para == 1:
+            EventMesh.publish("done_right_to_left")
+            print("->")
+        elif para == 2:
+            EventMesh.publish("done_bottom_to_top")
+            print("^")
+        elif para == 3:
+            EventMesh.publish("done_top_to_bottom")
+            print("V")
+        elif para == 4:
+            EventMesh.publish("done_return")
+            print("return")
+        elif para == 5:
+            EventMesh.publish("done_click")
+            print("CLICK")
+        elif (para == 6):
+            EventMesh.publish("done_error")
+            print("error")
+
+    def key_callback(self, l_list):
+        print("key_callback:",str(l_list))
+        if l_list[0] == 1:
+            # 马达震动预留
+            pass
+        if (l_list[1] == 3) and (l_list[2] == 0):
+            if l_list[0] == 1:
+                EventMesh.publish("btn1_press")
+            else:
+                pass
+                # EventMesh.publish("btn1_press")
+
+
+
+
+    def pwk_callback(self, status):
+        print('==pwr:', status)
+        if status == 1:
+            
+            self.__pwk_timer.start(self.__PowerDownTimeOut, 0, self.__pwk_long_press_cb)
+        elif status == 0:
+            self.__pwk_timer.stop()
+            # print("btn_back:{}".format(mdls.screen_size_style[mdls.models][1]))
+            EventMesh.publish("btn8_press")
+
+    def __pwk_long_press_cb(self, *args):
+        '''KEY2:联动屏幕右下角或返回键长按关机'''
+        EventMesh.publish("btn8_long_press")
+
+    def start(self):
+        self.post_processor_after_instantiation()
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/capacitive_hynitron_cst816d_update.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/capacitive_hynitron_cst816d_update.py
new file mode 100644 (file)
index 0000000..b99420f
--- /dev/null
@@ -0,0 +1,977 @@
+"""
+*Name        : capacitive_hynitron_cst816d_update.h
+*Author      : gary
+*Version     : V1.0
+*Copyright   : Hynitron
+*ProjectName : CSW_2211527_CST816D_COB_ZT_YAT_K5_G1_JL_55028.hex       Modify at 2022-11-21 17:57:42
+"""
+
+app_bin_816d = [
+0x00, 0x00, 0x00, 0x3c, 0x78, 0xa8,
+0x02, 0x1f, 0xc9, 0x7f, 0x00, 0x22, 0x02, 0x34, 0x9c, 0x22, 0x00, 0x00, 0x02, 0x33, 0xd2, 0x02, 
+0x33, 0x5f, 0x85, 0x5b, 0x82, 0x85, 0x5a, 0x83, 0x75, 0xf0, 0x05, 0xe5, 0x21, 0x02, 0x0c, 0xa0, 
+0x00, 0x02, 0x28, 0xf5, 0x8f, 0x22, 0xe5, 0x09, 0x24, 0x05, 0x12, 0x12, 0x63, 0xe0, 0x70, 0x03, 
+0x02, 0x07, 0x77, 0x12, 0x12, 0x89, 0x74, 0x20, 0x93, 0xff, 0xe5, 0x09, 0x24, 0x09, 0x12, 0x12, 
+0x63, 0xe0, 0xc3, 0x9f, 0x50, 0x58, 0xe5, 0x09, 0x24, 0x07, 0x12, 0x12, 0x63, 0xe0, 0x54, 0xfe, 
+0xf0, 0xe5, 0x09, 0x24, 0x11, 0x12, 0x12, 0x63, 0xe4, 0xf0, 0xa3, 0xf0, 0xe5, 0x09, 0x24, 0x13, 
+0x12, 0x12, 0x63, 0xe4, 0xf0, 0x12, 0x12, 0x6e, 0x12, 0x13, 0x2c, 0x24, 0x1b, 0x12, 0x12, 0x63, 
+0x12, 0x12, 0x6b, 0x12, 0x13, 0x2a, 0x24, 0x1d, 0x12, 0x12, 0x29, 0x12, 0x12, 0x6b, 0x12, 0x13, 
+0x2c, 0x24, 0x15, 0x12, 0x12, 0x63, 0x12, 0x12, 0x6b, 0x12, 0x13, 0x2a, 0x24, 0x17, 0x12, 0x12, 
+0x63, 0x12, 0x14, 0x46, 0x24, 0x05, 0x12, 0x12, 0x63, 0xe4, 0xf0, 0x02, 0x01, 0xe1, 0xe5, 0x09, 
+0x24, 0x07, 0x12, 0x12, 0x63, 0xe0, 0x30, 0xe0, 0x03, 0x02, 0x01, 0x3f, 0xe5, 0x09, 0x24, 0x1b, 
+0x12, 0x12, 0x63, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x12, 0x70, 0x12, 0x13, 0xe9, 0xf5, 0x28, 
+0xec, 0x9e, 0xf5, 0x27, 0xe5, 0x09, 0x24, 0x1d, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 
+0x12, 0x12, 0x70, 0x12, 0x13, 0xe7, 0xf5, 0x2a, 0xec, 0x9e, 0xf5, 0x29, 0x12, 0x12, 0x89, 0x74, 
+0x19, 0x93, 0xff, 0xe4, 0x8f, 0x36, 0xf5, 0x35, 0xf5, 0x34, 0xf5, 0x33, 0x12, 0x13, 0x62, 0x90, 
+0x02, 0xb8, 0xe0, 0x24, 0x01, 0xff, 0xe4, 0x33, 0xfe, 0x12, 0x13, 0xc6, 0x8f, 0x36, 0x8e, 0x35, 
+0x8d, 0x34, 0x8c, 0x33, 0xaf, 0x2a, 0xae, 0x29, 0x12, 0x2b, 0x6f, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 
+0x28, 0xae, 0x27, 0x12, 0x2b, 0x6f, 0xd0, 0xe0, 0x2f, 0xff, 0xd0, 0xe0, 0x3e, 0xfe, 0x12, 0x13, 
+0x5d, 0xc3, 0x12, 0x0c, 0x2e, 0x50, 0x0d, 0xe5, 0x09, 0x24, 0x07, 0x12, 0x12, 0x63, 0xe0, 0x44, 
+0x01, 0xf0, 0x80, 0x37, 0xe4, 0xf5, 0x27, 0xf5, 0x28, 0xf5, 0x29, 0xf5, 0x2a, 0x80, 0x2c, 0xe5, 
+0x09, 0x24, 0x21, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x12, 0x70, 0x12, 0x13, 
+0xe9, 0xf5, 0x28, 0xec, 0x9e, 0xf5, 0x27, 0x12, 0x12, 0x5f, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 
+0x12, 0x70, 0x12, 0x13, 0xe7, 0xf5, 0x2a, 0xec, 0x9e, 0xf5, 0x29, 0xe5, 0x09, 0x24, 0x11, 0x12, 
+0x12, 0x63, 0x12, 0x13, 0x56, 0xe5, 0x28, 0x9f, 0xfd, 0xe5, 0x27, 0x9e, 0xfc, 0xef, 0x78, 0x02, 
+0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x2d, 0xff, 0xec, 0x3e, 0xfe, 0xef, 0x78, 0x02, 0x12, 
+0x14, 0x01, 0xd8, 0xfb, 0xf5, 0x28, 0x8e, 0x27, 0xe5, 0x09, 0x24, 0x13, 0x12, 0x12, 0x63, 0x12, 
+0x13, 0x56, 0xe5, 0x2a, 0x9f, 0xfd, 0xe5, 0x29, 0x9e, 0xfc, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 
+0x33, 0xce, 0xd8, 0xf9, 0x2d, 0xff, 0xec, 0x3e, 0xfe, 0xef, 0x78, 0x02, 0x12, 0x14, 0x01, 0xd8, 
+0xfb, 0xf5, 0x2a, 0x8e, 0x29, 0xe5, 0x09, 0x24, 0x11, 0x12, 0x12, 0x63, 0xe5, 0x27, 0xf0, 0xa3, 
+0xe5, 0x28, 0xf0, 0xe5, 0x09, 0x24, 0x13, 0x12, 0x12, 0x63, 0xe5, 0x29, 0xf0, 0xa3, 0xe5, 0x2a, 
+0xf0, 0x12, 0x12, 0x89, 0x74, 0x20, 0x93, 0xff, 0xe5, 0x09, 0x24, 0x09, 0x12, 0x12, 0x63, 0xe0, 
+0xc3, 0x9f, 0x50, 0x03, 0x02, 0x07, 0x35, 0xe5, 0x09, 0x24, 0x21, 0x12, 0x12, 0x63, 0xe0, 0xfe, 
+0xa3, 0xe0, 0x25, 0x28, 0xff, 0xe5, 0x27, 0x3e, 0xfe, 0x12, 0x13, 0x7c, 0x12, 0x12, 0x70, 0x12, 
+0x14, 0x08, 0x12, 0x14, 0x01, 0xd8, 0xfb, 0xf5, 0x24, 0x8e, 0x23, 0x12, 0x12, 0x5f, 0xe0, 0xfe, 
+0xa3, 0xe0, 0x25, 0x2a, 0xff, 0xe5, 0x29, 0x3e, 0xfe, 0x12, 0x13, 0x7c, 0x12, 0x12, 0x70, 0xa3, 
+0xa3, 0x12, 0x14, 0x08, 0x12, 0x14, 0x01, 0xd8, 0xfb, 0xf5, 0x26, 0x8e, 0x25, 0xc3, 0xe5, 0x24, 
+0x94, 0x01, 0xe5, 0x23, 0x64, 0x80, 0x94, 0x80, 0x50, 0x08, 0x75, 0x23, 0x00, 0x75, 0x24, 0x01, 
+0x80, 0x1d, 0x12, 0x12, 0x89, 0x74, 0x01, 0x93, 0xfe, 0x74, 0x02, 0x93, 0xff, 0xd3, 0x95, 0x24, 
+0xee, 0x95, 0x23, 0x50, 0x0a, 0xef, 0x24, 0xff, 0xf5, 0x24, 0xee, 0x34, 0xff, 0xf5, 0x23, 0xc3, 
+0xe5, 0x26, 0x94, 0x01, 0xe5, 0x25, 0x64, 0x80, 0x94, 0x80, 0x50, 0x08, 0x75, 0x25, 0x00, 0x75, 
+0x26, 0x01, 0x80, 0x1d, 0x12, 0x12, 0x89, 0x74, 0x03, 0x93, 0xfe, 0x74, 0x04, 0x93, 0xff, 0xd3, 
+0x95, 0x26, 0xee, 0x95, 0x25, 0x50, 0x0a, 0xef, 0x24, 0xff, 0xf5, 0x26, 0xee, 0x34, 0xff, 0xf5, 
+0x25, 0x12, 0x12, 0x89, 0x74, 0x20, 0x93, 0x24, 0x0a, 0xff, 0xe4, 0x33, 0xfe, 0xe5, 0x09, 0x24, 
+0x09, 0x12, 0x12, 0x63, 0xe0, 0xc3, 0x9f, 0xee, 0x64, 0x80, 0xf8, 0x74, 0x80, 0x98, 0x50, 0x5d, 
+0xe5, 0x09, 0x24, 0x11, 0x12, 0x12, 0x63, 0x12, 0x07, 0xc9, 0x12, 0x12, 0x89, 0x74, 0x20, 0x93, 
+0xfd, 0xe5, 0x09, 0x24, 0x09, 0x12, 0x12, 0x63, 0xe0, 0xc3, 0x9d, 0xfd, 0xe4, 0x94, 0x00, 0xfc, 
+0x12, 0x13, 0xd7, 0x12, 0x14, 0x15, 0xe5, 0x09, 0x24, 0x13, 0x12, 0x12, 0x63, 0x12, 0x07, 0xc9, 
+0x12, 0x12, 0x89, 0x74, 0x20, 0x93, 0xfd, 0xe5, 0x09, 0x24, 0x09, 0x12, 0x12, 0x63, 0xe0, 0xc3, 
+0x9d, 0xfd, 0xe4, 0x94, 0x00, 0xfc, 0x12, 0x12, 0xf4, 0xf5, 0x83, 0x12, 0x14, 0x15, 0x75, 0x3b, 
+0x00, 0x75, 0x3c, 0x5a, 0x75, 0x3d, 0x00, 0x75, 0x3e, 0x5a, 0x02, 0x05, 0x45, 0xe5, 0x09, 0x24, 
+0x11, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x2b, 0x6f, 0x8e, 0x46, 0x8f, 0x47, 
+0xe5, 0x09, 0x24, 0x13, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x2b, 0x6f, 0x8e, 
+0x48, 0x8f, 0x49, 0xd3, 0xe5, 0x47, 0x94, 0xff, 0xe5, 0x46, 0x94, 0x00, 0x40, 0x06, 0x75, 0x46, 
+0x00, 0x75, 0x47, 0xff, 0xd3, 0xe5, 0x49, 0x94, 0xff, 0xe5, 0x48, 0x94, 0x00, 0x40, 0x06, 0x75, 
+0x48, 0x00, 0x75, 0x49, 0xff, 0x85, 0x46, 0x3f, 0x85, 0x47, 0x40, 0x85, 0x48, 0x41, 0x85, 0x49, 
+0x42, 0x75, 0x45, 0x09, 0x12, 0x12, 0xa5, 0xe0, 0x25, 0x40, 0xf5, 0x40, 0xe4, 0x35, 0x3f, 0xf5, 
+0x3f, 0x12, 0x12, 0xf4, 0x12, 0x12, 0xb2, 0xe0, 0x25, 0x42, 0xf5, 0x42, 0xe4, 0x35, 0x41, 0xf5, 
+0x41, 0xe5, 0x22, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xbe, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0x12, 0x12, 
+0xb2, 0xe0, 0xff, 0x12, 0x12, 0xa5, 0xef, 0xf0, 0xe5, 0x22, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xd2, 
+0xf5, 0x82, 0xe4, 0x34, 0x02, 0x12, 0x12, 0xb2, 0xe0, 0xff, 0x12, 0x12, 0xf4, 0x12, 0x12, 0xb2, 
+0xef, 0xf0, 0x15, 0x45, 0xe5, 0x45, 0x70, 0xac, 0x12, 0x13, 0xd7, 0xe5, 0x47, 0xf0, 0x12, 0x12, 
+0xf4, 0xf5, 0x83, 0xe5, 0x49, 0xf0, 0xd3, 0xe5, 0x40, 0x95, 0x42, 0xe5, 0x3f, 0x95, 0x41, 0x40, 
+0x26, 0x75, 0x4a, 0x00, 0x75, 0x4b, 0x00, 0x75, 0x4c, 0x41, 0x75, 0x4d, 0x00, 0x75, 0x4e, 0x00, 
+0x75, 0x4f, 0x3f, 0x75, 0x50, 0x00, 0x75, 0x51, 0x00, 0x75, 0x52, 0x3b, 0x75, 0x53, 0x00, 0x75, 
+0x54, 0x00, 0x75, 0x55, 0x3d, 0x80, 0x24, 0x75, 0x4a, 0x00, 0x75, 0x4b, 0x00, 0x75, 0x4c, 0x3f, 
+0x75, 0x4d, 0x00, 0x75, 0x4e, 0x00, 0x75, 0x4f, 0x41, 0x75, 0x50, 0x00, 0x75, 0x51, 0x00, 0x75, 
+0x52, 0x3d, 0x75, 0x53, 0x00, 0x75, 0x54, 0x00, 0x75, 0x55, 0x3b, 0x12, 0x14, 0x64, 0x45, 0xf0, 
+0x70, 0x06, 0x75, 0xf0, 0x01, 0x12, 0x0a, 0xc5, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f, 0x12, 0x0a, 
+0x15, 0xae, 0xf0, 0x78, 0x03, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x12, 0x14, 0x64, 
+0xfd, 0xac, 0xf0, 0x12, 0x09, 0x74, 0x8e, 0x43, 0x8f, 0x44, 0xe5, 0x09, 0x24, 0x0b, 0x12, 0x12, 
+0x63, 0x12, 0x13, 0x77, 0xe5, 0x44, 0x2f, 0xff, 0xe5, 0x43, 0x3e, 0xfe, 0xef, 0x78, 0x02, 0xce, 
+0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x44, 0x8e, 0x43, 0xc3, 0x94, 0x28, 0xe5, 0x43, 0x94, 
+0x00, 0x50, 0x08, 0x75, 0x43, 0x00, 0x75, 0x44, 0x28, 0x80, 0x11, 0xd3, 0xe5, 0x44, 0x94, 0x46, 
+0xe5, 0x43, 0x94, 0x00, 0x40, 0x06, 0x75, 0x43, 0x00, 0x75, 0x44, 0x46, 0xae, 0x43, 0xaf, 0x44, 
+0x7c, 0x00, 0x7d, 0x0a, 0x12, 0x09, 0x62, 0xef, 0x24, 0xca, 0xff, 0xee, 0x34, 0xfe, 0xab, 0x53, 
+0xaa, 0x54, 0xa9, 0x55, 0x8f, 0xf0, 0x12, 0x0a, 0xc5, 0xe5, 0x44, 0x25, 0xe0, 0xff, 0xe5, 0x43, 
+0x33, 0xfe, 0xc3, 0x74, 0xaa, 0x9f, 0xff, 0xe4, 0x9e, 0xab, 0x50, 0xaa, 0x51, 0xa9, 0x52, 0x8f, 
+0xf0, 0x12, 0x0a, 0xc5, 0xe5, 0x09, 0x24, 0x0b, 0x12, 0x12, 0x63, 0xe5, 0x43, 0xf0, 0xa3, 0xe5, 
+0x44, 0xf0, 0xe5, 0x09, 0x24, 0x0d, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7d, 0x03, 
+0x12, 0x09, 0x62, 0xe5, 0x3c, 0x2f, 0xff, 0xe5, 0x3b, 0x3e, 0xfe, 0xef, 0x78, 0x02, 0xce, 0xc3, 
+0x13, 0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x3c, 0x8e, 0x3b, 0xe5, 0x09, 0x24, 0x0f, 0x12, 0x12, 0x63, 
+0x12, 0x13, 0x77, 0xe5, 0x3e, 0x2f, 0xff, 0xe5, 0x3d, 0x3e, 0xfe, 0xef, 0x78, 0x02, 0xce, 0xc3, 
+0x13, 0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x3e, 0x8e, 0x3d, 0xe5, 0x09, 0x24, 0x0d, 0x12, 0x12, 0x63, 
+0xe5, 0x3b, 0xf0, 0xa3, 0xe5, 0x3c, 0xf0, 0xe5, 0x09, 0x24, 0x0f, 0x12, 0x12, 0x63, 0xe5, 0x3d, 
+0xf0, 0xa3, 0xe5, 0x3e, 0xf0, 0x12, 0x12, 0x5f, 0x12, 0x07, 0xd2, 0x7c, 0x00, 0x7d, 0x02, 0x12, 
+0x09, 0xc9, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x09, 0x24, 0x21, 0x12, 0x12, 0x63, 0x12, 0x07, 0xe2, 
+0xd0, 0xe0, 0x2f, 0xff, 0xd0, 0xe0, 0x3e, 0xfe, 0x33, 0x95, 0xe0, 0x8f, 0x36, 0x8e, 0x35, 0xf5, 
+0x34, 0xf5, 0x33, 0xad, 0x34, 0xac, 0x33, 0x12, 0x12, 0x78, 0x12, 0x14, 0x2f, 0xe5, 0x36, 0x2f, 
+0xf5, 0x36, 0xe5, 0x35, 0x3e, 0xf5, 0x35, 0xe5, 0x34, 0x3d, 0xf5, 0x34, 0xe5, 0x33, 0x3c, 0xf5, 
+0x33, 0xae, 0x3b, 0xaf, 0x3c, 0xe4, 0xfc, 0xfd, 0x12, 0x13, 0x62, 0xd3, 0x12, 0x0c, 0x2e, 0x40, 
+0x0b, 0xe4, 0x85, 0x3c, 0x36, 0x85, 0x3b, 0x35, 0xf5, 0x34, 0xf5, 0x33, 0xc3, 0xe5, 0x3c, 0x95, 
+0x36, 0xfb, 0xe5, 0x3b, 0x95, 0x35, 0xfa, 0xe4, 0x95, 0x34, 0xf9, 0xe4, 0x95, 0x33, 0xf8, 0xe5, 
+0x09, 0x24, 0x21, 0x12, 0x12, 0x63, 0x12, 0x13, 0xc1, 0x8f, 0x2e, 0x8e, 0x2d, 0x8d, 0x2c, 0x8c, 
+0x2b, 0xae, 0x23, 0xaf, 0x24, 0xee, 0x12, 0x13, 0x5d, 0x12, 0x0b, 0x11, 0xef, 0x25, 0x2e, 0xff, 
+0xee, 0x35, 0x2d, 0xfe, 0xed, 0x35, 0x2c, 0xfd, 0xec, 0x35, 0x2b, 0xfc, 0x12, 0x13, 0x6e, 0xe5, 
+0x3b, 0xc3, 0x13, 0xfe, 0xe5, 0x3c, 0x12, 0x13, 0x34, 0xc0, 0x06, 0xc0, 0x07, 0xae, 0x3b, 0xaf, 
+0x3c, 0xab, 0x07, 0xaa, 0x06, 0xe4, 0xf9, 0xf8, 0xd0, 0x07, 0xd0, 0x06, 0x12, 0x0b, 0x9c, 0x8f, 
+0x2e, 0x8e, 0x2d, 0x8d, 0x2c, 0x8c, 0x2b, 0xe5, 0x09, 0x24, 0x21, 0x12, 0x12, 0x63, 0x12, 0x07, 
+0xe2, 0x7c, 0x00, 0x7d, 0x02, 0x12, 0x09, 0xc9, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x12, 0x5f, 0x12, 
+0x07, 0xd2, 0xd0, 0xe0, 0x2f, 0xff, 0xd0, 0xe0, 0x3e, 0xfe, 0x33, 0x95, 0xe0, 0x8f, 0x3a, 0x8e, 
+0x39, 0xf5, 0x38, 0xf5, 0x37, 0xad, 0x38, 0xac, 0x37, 0x12, 0x12, 0x78, 0x12, 0x14, 0x2f, 0xe5, 
+0x3a, 0x2f, 0xf5, 0x3a, 0xe5, 0x39, 0x3e, 0xf5, 0x39, 0xe5, 0x38, 0x3d, 0xf5, 0x38, 0xe5, 0x37, 
+0x3c, 0xf5, 0x37, 0xae, 0x3d, 0xaf, 0x3e, 0xe4, 0xfc, 0xfd, 0xab, 0x3a, 0xaa, 0x39, 0xa9, 0x38, 
+0xa8, 0x37, 0xd3, 0x12, 0x0c, 0x2e, 0x40, 0x0b, 0xe4, 0x85, 0x3e, 0x3a, 0x85, 0x3d, 0x39, 0xf5, 
+0x38, 0xf5, 0x37, 0xc3, 0xe5, 0x3e, 0x95, 0x3a, 0xfb, 0xe5, 0x3d, 0x95, 0x39, 0xfa, 0xe4, 0x95, 
+0x38, 0xf9, 0xe4, 0x95, 0x37, 0xf8, 0x12, 0x12, 0x5f, 0x12, 0x13, 0xc1, 0x8f, 0x32, 0x8e, 0x31, 
+0x8d, 0x30, 0x8c, 0x2f, 0xae, 0x25, 0xaf, 0x26, 0xee, 0x33, 0x95, 0xe0, 0xfd, 0xfc, 0xab, 0x3a, 
+0xaa, 0x39, 0xa9, 0x38, 0xa8, 0x37, 0x12, 0x0b, 0x11, 0xef, 0x25, 0x32, 0xff, 0xee, 0x35, 0x31, 
+0xfe, 0xed, 0x35, 0x30, 0xfd, 0xec, 0x35, 0x2f, 0xfc, 0x12, 0x13, 0x6e, 0xe5, 0x3d, 0xc3, 0x13, 
+0xfe, 0xe5, 0x3e, 0x12, 0x13, 0x34, 0xc0, 0x06, 0xc0, 0x07, 0xae, 0x3d, 0xaf, 0x3e, 0xab, 0x07, 
+0xaa, 0x06, 0xe4, 0xf9, 0xf8, 0xd0, 0x07, 0xd0, 0x06, 0x12, 0x0b, 0x9c, 0x8f, 0x32, 0x8e, 0x31, 
+0x8d, 0x30, 0x8c, 0x2f, 0xe5, 0x09, 0x24, 0x07, 0x12, 0x12, 0x63, 0xe0, 0x30, 0xe0, 0x11, 0x12, 
+0x12, 0x70, 0xe5, 0x2d, 0xf0, 0xa3, 0xe5, 0x2e, 0x12, 0x12, 0x6f, 0xa3, 0xa3, 0xee, 0x80, 0x21, 
+0xe5, 0x09, 0x24, 0x1b, 0x12, 0x12, 0x63, 0xe0, 0xff, 0xa3, 0xe0, 0x12, 0x12, 0x70, 0xcf, 0x12, 
+0x14, 0x47, 0x24, 0x1d, 0x12, 0x12, 0x63, 0xe0, 0xff, 0xa3, 0xe0, 0x12, 0x12, 0x70, 0xa3, 0xa3, 
+0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x09, 0x24, 0x21, 0x12, 0x12, 0x63, 0x12, 0x13, 0x2c, 0x24, 
+0x15, 0x12, 0x12, 0x63, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x12, 0x5f, 0x12, 0x13, 0x2c, 0x24, 
+0x17, 0x12, 0x12, 0x29, 0x12, 0x14, 0x46, 0x24, 0x09, 0x12, 0x12, 0x63, 0xe0, 0xc3, 0x94, 0x14, 
+0x50, 0x0a, 0xe5, 0x09, 0x24, 0x09, 0x12, 0x12, 0x63, 0xe0, 0x04, 0xf0, 0xe5, 0x09, 0x24, 0x0a, 
+0x12, 0x12, 0x63, 0x74, 0x01, 0xf0, 0x22, 0xe5, 0x09, 0x24, 0x0a, 0x12, 0x12, 0x63, 0xe0, 0xd3, 
+0x94, 0x00, 0x40, 0x0a, 0xe5, 0x09, 0x24, 0x0a, 0x12, 0x12, 0x63, 0xe0, 0x14, 0xf0, 0xe5, 0x09, 
+0x24, 0x0a, 0x12, 0x12, 0x63, 0xe0, 0x70, 0x30, 0xe5, 0x09, 0x24, 0x09, 0x12, 0x12, 0x63, 0xe4, 
+0xf0, 0xe5, 0x09, 0x24, 0x0d, 0x12, 0x12, 0x63, 0xe4, 0xf0, 0xa3, 0x74, 0x5a, 0xf0, 0xe5, 0x09, 
+0x24, 0x0f, 0x12, 0x12, 0x63, 0xe4, 0xf0, 0xa3, 0x74, 0x5a, 0xf0, 0xe5, 0x09, 0x24, 0x0b, 0x12, 
+0x12, 0x63, 0xe4, 0xf0, 0xa3, 0x74, 0x28, 0xf0, 0x22, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x2b, 
+0x6f, 0x22, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0x95, 0x26, 0xff, 0xee, 0x95, 0x25, 0xfe, 0x12, 0x2b, 
+0x6f, 0x22, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0x95, 0x24, 0xff, 0xee, 0x95, 0x23, 0xfe, 0x12, 0x2b, 
+0x6f, 0x22, 0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 
+0x80, 0x3e, 0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 
+0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 
+0x8c, 0x83, 0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 
+0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 
+0x80, 0x4c, 0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 
+0x80, 0x10, 0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 
+0x80, 0x33, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 
+0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 
+0xe7, 0x80, 0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 
+0xa9, 0xf0, 0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 
+0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 
+0xea, 0xde, 0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 
+0x80, 0xcc, 0x88, 0xf0, 0xef, 0x60, 0x01, 0x0e, 0x4e, 0x60, 0xc3, 0x88, 0xf0, 0xed, 0x24, 0x02, 
+0xb4, 0x04, 0x00, 0x50, 0xb9, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xaf, 0x23, 
+0x23, 0x45, 0x82, 0x23, 0x90, 0x08, 0x42, 0x73, 0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 
+0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02, 0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 
+0x22, 0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 
+0x50, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 
+0x22, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22, 0xbb, 0x01, 
+0x06, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0x22, 0x50, 0x02, 0xf7, 0x22, 0xbb, 0xfe, 0x01, 0xf3, 0x22, 
+0xf8, 0xbb, 0x01, 0x0d, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe8, 0xf0, 
+0x22, 0x50, 0x06, 0xe9, 0x25, 0x82, 0xc8, 0xf6, 0x22, 0xbb, 0xfe, 0x05, 0xe9, 0x25, 0x82, 0xc8, 
+0xf2, 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0, 0xa4, 0x28, 0xce, 0x8d, 0xf0, 
+0xa4, 0x2e, 0xfe, 0x22, 0xbc, 0x00, 0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 
+0xf0, 0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xec, 0x33, 
+0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05, 0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 
+0xce, 0xfd, 0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe, 0xad, 0xf0, 0x75, 
+0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd, 0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 
+0x22, 0xc3, 0x98, 0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xc2, 0xd5, 0xec, 0x30, 0xe7, 0x09, 0xb2, 
+0xd5, 0xe4, 0xc3, 0x9d, 0xfd, 0xe4, 0x9c, 0xfc, 0xee, 0x30, 0xe7, 0x15, 0xb2, 0xd5, 0xe4, 0xc3, 
+0x9f, 0xff, 0xe4, 0x9e, 0xfe, 0x12, 0x09, 0x74, 0xc3, 0xe4, 0x9d, 0xfd, 0xe4, 0x9c, 0xfc, 0x80, 
+0x03, 0x12, 0x09, 0x74, 0x30, 0xd5, 0x07, 0xc3, 0xe4, 0x9f, 0xff, 0xe4, 0x9e, 0xfe, 0x22, 0xc5, 
+0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 
+0x83, 0xe0, 0x38, 0xf0, 0x22, 0xbb, 0x01, 0x0a, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xf5, 0xf0, 0xa3, 
+0xe0, 0x22, 0x50, 0x06, 0x87, 0xf0, 0x09, 0xe7, 0x19, 0x22, 0xbb, 0xfe, 0x07, 0xe3, 0xf5, 0xf0, 
+0x09, 0xe3, 0x19, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xf5, 0xf0, 0x74, 0x01, 0x93, 0x22, 
+0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0, 
+0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe, 
+0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83, 
+0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22, 0xbb, 0x01, 0x0d, 0xc5, 0x82, 0x29, 0xc5, 0x82, 
+0xc5, 0x83, 0x3a, 0xc5, 0x83, 0x02, 0x09, 0xff, 0x50, 0x11, 0xc5, 0x82, 0x29, 0xf8, 0x08, 0xe5, 
+0xf0, 0x26, 0xf6, 0x18, 0xf5, 0xf0, 0xe5, 0x82, 0x36, 0xf6, 0x22, 0xbb, 0xfe, 0x11, 0xc5, 0x82, 
+0x29, 0xf8, 0x08, 0xe2, 0x25, 0xf0, 0xf5, 0xf0, 0xf2, 0x18, 0xe2, 0x35, 0x82, 0xf2, 0x22, 0xf8, 
+0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x2a, 0xf5, 0x83, 0x74, 0x01, 0x93, 0x25, 0xf0, 0xf5, 
+0xf0, 0xe4, 0x93, 0x38, 0x22, 0xbb, 0x01, 0x0a, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0xe5, 0xf0, 0xa3, 
+0xf0, 0x22, 0x50, 0x06, 0xf7, 0x09, 0xa7, 0xf0, 0x19, 0x22, 0xbb, 0xfe, 0x06, 0xf3, 0xe5, 0xf0, 
+0x09, 0xf3, 0x19, 0x22, 0xf8, 0xbb, 0x01, 0x11, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 
+0xf5, 0x83, 0xe8, 0xf0, 0xe5, 0xf0, 0xa3, 0xf0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xc8, 0xf6, 
+0x08, 0xa6, 0xf0, 0x22, 0xbb, 0xfe, 0x09, 0xe9, 0x25, 0x82, 0xc8, 0xf2, 0xe5, 0xf0, 0x08, 0xf2, 
+0x22, 0xe8, 0x8f, 0xf0, 0xa4, 0xcc, 0x8b, 0xf0, 0xa4, 0x2c, 0xfc, 0xe9, 0x8e, 0xf0, 0xa4, 0x2c, 
+0xfc, 0x8a, 0xf0, 0xed, 0xa4, 0x2c, 0xfc, 0xea, 0x8e, 0xf0, 0xa4, 0xcd, 0xa8, 0xf0, 0x8b, 0xf0, 
+0xa4, 0x2d, 0xcc, 0x38, 0x25, 0xf0, 0xfd, 0xe9, 0x8f, 0xf0, 0xa4, 0x2c, 0xcd, 0x35, 0xf0, 0xfc, 
+0xeb, 0x8e, 0xf0, 0xa4, 0xfe, 0xa9, 0xf0, 0xeb, 0x8f, 0xf0, 0xa4, 0xcf, 0xc5, 0xf0, 0x2e, 0xcd, 
+0x39, 0xfe, 0xe4, 0x3c, 0xfc, 0xea, 0xa4, 0x2d, 0xce, 0x35, 0xf0, 0xfd, 0xe4, 0x3c, 0xfc, 0x22, 
+0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc, 
+0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40, 
+0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6, 
+0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9, 
+0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb, 
+0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb, 
+0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9, 
+0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 
+0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a, 
+0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f, 
+0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07, 
+0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8, 
+0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22, 0xeb, 0x9f, 
+0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0, 0x22, 0xe8, 
+0x60, 0x0f, 0xef, 0xc3, 0x33, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xd8, 
+0xf1, 0x22, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x22, 0xe4, 0x93, 
+0xfc, 0x74, 0x01, 0x93, 0xfd, 0x74, 0x02, 0x93, 0xfe, 0x74, 0x03, 0x93, 0xff, 0x22, 0xe6, 0xfb, 
+0x08, 0xe6, 0xf9, 0x08, 0xe6, 0xfa, 0x08, 0xe6, 0xcb, 0xf8, 0x22, 0xec, 0xf6, 0x08, 0xed, 0xf6, 
+0x08, 0xee, 0xf6, 0x08, 0xef, 0xf6, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xe4, 0x93, 0xf6, 0x08, 0x74, 
+0x01, 0x93, 0xf6, 0x08, 0x74, 0x02, 0x93, 0xf6, 0x08, 0x74, 0x03, 0x93, 0xf6, 0x74, 0x04, 0x73, 
+0xa4, 0x25, 0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xec, 0x8e, 0xf0, 0xa4, 
+0xcc, 0xc5, 0xf0, 0xcc, 0xcd, 0xf8, 0xef, 0xa4, 0xce, 0xc5, 0xf0, 0x2d, 0xfd, 0xe4, 0x3c, 0xfc, 
+0xe8, 0xa4, 0x2e, 0xc8, 0xc5, 0xf0, 0x3d, 0xfd, 0xe4, 0x3c, 0xfc, 0xef, 0xa4, 0xff, 0xe5, 0xf0, 
+0x28, 0xfe, 0xe4, 0x3d, 0xfd, 0xe4, 0x3c, 0xfc, 0x22, 0xef, 0x4e, 0x60, 0x12, 0xef, 0x60, 0x01, 
+0x0e, 0xed, 0xbb, 0x01, 0x0b, 0x89, 0x82, 0x8a, 0x83, 0xf0, 0xa3, 0xdf, 0xfc, 0xde, 0xfa, 0x22, 
+0x89, 0xf0, 0x50, 0x07, 0xf7, 0x09, 0xdf, 0xfc, 0xa9, 0xf0, 0x22, 0xbb, 0xfe, 0xfc, 0xf3, 0x09, 
+0xdf, 0xfc, 0xa9, 0xf0, 0x22, 0xe4, 0xf5, 0x23, 0xe5, 0x1e, 0x60, 0x07, 0xe5, 0x1f, 0x70, 0x03, 
+0x02, 0x0f, 0x70, 0xe5, 0x1f, 0x60, 0x07, 0xe5, 0x1e, 0x70, 0x03, 0x02, 0x0f, 0x70, 0xe5, 0x1e, 
+0x70, 0x03, 0x02, 0x0e, 0xd8, 0xe5, 0x1f, 0x70, 0x03, 0x02, 0x0e, 0xd8, 0xe5, 0x20, 0xd3, 0x94, 
+0x01, 0x40, 0x0a, 0x78, 0xa2, 0xe6, 0x94, 0x64, 0x50, 0x0c, 0x06, 0x80, 0x09, 0x78, 0xa1, 0xe6, 
+0xc3, 0x94, 0x64, 0x50, 0x01, 0x06, 0x78, 0x9e, 0xe6, 0x65, 0x20, 0x60, 0x12, 0xe4, 0x78, 0x9c, 
+0xf6, 0x78, 0x92, 0x12, 0x27, 0x98, 0x78, 0x90, 0xf6, 0x08, 0xf6, 0x78, 0x9e, 0xa6, 0x20, 0x78, 
+0x90, 0xe6, 0xff, 0x60, 0x13, 0xe5, 0x1e, 0x12, 0x0f, 0x82, 0x50, 0x0c, 0x78, 0x90, 0xe6, 0xff, 
+0xc3, 0xe5, 0x1e, 0x78, 0x93, 0x12, 0x27, 0xb4, 0x78, 0x90, 0xa6, 0x1e, 0x08, 0xe6, 0xff, 0x60, 
+0x13, 0xe5, 0x1f, 0x12, 0x0f, 0x82, 0x50, 0x0c, 0x78, 0x91, 0xe6, 0xff, 0xc3, 0xe5, 0x1f, 0x78, 
+0x95, 0x12, 0x27, 0xb4, 0x78, 0x91, 0xa6, 0x1f, 0x78, 0x96, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x12, 
+0x2b, 0x6f, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x0f, 0x77, 0xd0, 0x05, 0xd0, 0x04, 0x12, 0x27, 0xd7, 
+0x40, 0x04, 0x78, 0x92, 0x80, 0x02, 0x78, 0x96, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x78, 0x96, 0xa6, 
+0x06, 0x08, 0xa6, 0x07, 0x08, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x12, 0x2b, 0x6f, 0xc0, 0x06, 0xc0, 
+0x07, 0x12, 0x0f, 0xa4, 0xd0, 0x05, 0xd0, 0x04, 0x12, 0x27, 0xd7, 0x40, 0x04, 0x78, 0x94, 0x80, 
+0x02, 0x78, 0x98, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x78, 0x98, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0xe4, 
+0x78, 0x9d, 0xf6, 0x78, 0xa3, 0xe6, 0x54, 0x3c, 0x60, 0x79, 0x12, 0x0f, 0x77, 0x12, 0x27, 0xee, 
+0x50, 0x08, 0x12, 0x0f, 0xa4, 0x12, 0x27, 0xee, 0x40, 0x69, 0x78, 0x90, 0xe6, 0x78, 0x94, 0x60, 
+0x0f, 0x12, 0x27, 0xcb, 0x78, 0x92, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x12, 0x09, 0xc9, 0x80, 0x03, 
+0x12, 0x27, 0xcb, 0x8e, 0x24, 0x8f, 0x25, 0xaf, 0x25, 0xae, 0x24, 0x12, 0x2b, 0x6f, 0xd3, 0xef, 
+0x95, 0x21, 0x74, 0x80, 0xf8, 0x6e, 0x98, 0x40, 0x1c, 0x78, 0xa3, 0xe6, 0x54, 0x0c, 0x60, 0x33, 
+0x78, 0x95, 0x12, 0x27, 0xe3, 0x7f, 0x02, 0x40, 0x02, 0x7f, 0x01, 0x12, 0x27, 0xa0, 0x30, 0xe1, 
+0x02, 0x7f, 0x0c, 0x80, 0x1a, 0x78, 0xa3, 0xe6, 0x54, 0x30, 0x60, 0x17, 0x78, 0x93, 0x12, 0x27, 
+0xe3, 0x7f, 0x03, 0x40, 0x02, 0x7f, 0x04, 0x12, 0x27, 0xa0, 0x30, 0xe2, 0x02, 0x7f, 0x30, 0x78, 
+0xa3, 0xa6, 0x07, 0x78, 0xa3, 0xe6, 0x30, 0xe1, 0x52, 0x90, 0x01, 0x9b, 0xe0, 0x60, 0x4c, 0x78, 
+0x92, 0x12, 0x0f, 0xaf, 0x50, 0x45, 0x78, 0x94, 0x12, 0x0f, 0xaf, 0x50, 0x3e, 0xe5, 0x20, 0x64, 
+0x01, 0x70, 0x18, 0x12, 0x27, 0xc2, 0x9f, 0x40, 0x12, 0x75, 0x23, 0x0c, 0x90, 0x01, 0xaa, 0xe0, 
+0x7f, 0x02, 0x30, 0xe0, 0x02, 0x7f, 0x00, 0x78, 0xa3, 0xa6, 0x07, 0xe5, 0x20, 0xd3, 0x94, 0x01, 
+0x40, 0x19, 0x12, 0x27, 0xc2, 0xd3, 0x9f, 0x40, 0x12, 0x75, 0x23, 0x1c, 0x90, 0x01, 0xaa, 0xe0, 
+0x7f, 0x02, 0x30, 0xe0, 0x02, 0x7f, 0x00, 0x78, 0xa3, 0xa6, 0x07, 0x78, 0x9c, 0xe6, 0x60, 0x03, 
+0x02, 0x0f, 0x70, 0x76, 0x01, 0x02, 0x0f, 0x70, 0x78, 0x9c, 0xe6, 0xff, 0x60, 0x4c, 0x78, 0xa3, 
+0xe6, 0x30, 0xe0, 0x22, 0xef, 0xd3, 0x94, 0x01, 0x40, 0x1c, 0x12, 0x27, 0xc2, 0x9f, 0x50, 0x16, 
+0x79, 0xa1, 0xe7, 0x78, 0xa2, 0x96, 0x40, 0x08, 0xe4, 0x78, 0xa0, 0xf6, 0x18, 0x06, 0x80, 0x06, 
+0xe4, 0x78, 0x9f, 0xf6, 0x08, 0x06, 0xe4, 0x78, 0x90, 0x12, 0x27, 0x98, 0x08, 0x12, 0x27, 0x98, 
+0x08, 0xf6, 0x08, 0xf6, 0x78, 0x9c, 0xf6, 0x78, 0xa1, 0xf6, 0x08, 0xf6, 0x78, 0x9e, 0xf6, 0x18, 
+0x76, 0x01, 0x78, 0xa3, 0xe6, 0x44, 0x3e, 0xf6, 0x80, 0x46, 0x90, 0x01, 0x9c, 0xe0, 0x7f, 0x01, 
+0x30, 0xe0, 0x02, 0x7f, 0x14, 0x78, 0x9d, 0xe6, 0xfe, 0xd3, 0x9f, 0x40, 0x33, 0xee, 0x94, 0x1e, 
+0x50, 0x2e, 0x78, 0xa3, 0xe6, 0x30, 0xe0, 0x1e, 0x78, 0x9f, 0xe6, 0xff, 0xb4, 0x01, 0x05, 0x75, 
+0x23, 0x05, 0x80, 0x12, 0xef, 0xb4, 0x02, 0x05, 0x75, 0x23, 0x0b, 0x80, 0x09, 0x78, 0xa0, 0xe6, 
+0xb4, 0x01, 0x03, 0x75, 0x23, 0x15, 0x78, 0xa3, 0x76, 0xff, 0xe4, 0x78, 0x9f, 0xf6, 0x08, 0xf6, 
+0x78, 0xa4, 0xa6, 0x23, 0xaf, 0x23, 0x22, 0x78, 0x92, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x12, 0x2b, 
+0x6f, 0x22, 0xc3, 0x9f, 0xff, 0xe4, 0x94, 0x00, 0xfe, 0x12, 0x2b, 0x6f, 0xac, 0x06, 0xad, 0x07, 
+0xe5, 0x22, 0x75, 0xf0, 0x04, 0xa4, 0xff, 0xc3, 0xed, 0x9f, 0xe5, 0xf0, 0x64, 0x80, 0xf8, 0xec, 
+0x64, 0x80, 0x98, 0x22, 0x78, 0x94, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x12, 0x2b, 0x6f, 0x22, 0xe6, 
+0xfe, 0x08, 0xe6, 0xff, 0x12, 0x2b, 0x6f, 0xc3, 0xef, 0x95, 0x22, 0x74, 0x80, 0xf8, 0x6e, 0x98, 
+0x22, 0xef, 0x12, 0x12, 0xc2, 0xe0, 0xf5, 0x2f, 0x12, 0x12, 0x89, 0xe4, 0x93, 0xfd, 0x7c, 0x00, 
+0x74, 0x03, 0x93, 0xfe, 0x74, 0x04, 0x93, 0xff, 0x12, 0x09, 0x74, 0x8e, 0x30, 0x8f, 0x31, 0xe5, 
+0x2f, 0x70, 0x58, 0x75, 0x22, 0x01, 0x12, 0x13, 0x04, 0xe4, 0xf5, 0x27, 0xf5, 0x28, 0x78, 0x02, 
+0xe2, 0xfe, 0x08, 0xe2, 0xff, 0x78, 0x01, 0x12, 0x13, 0x49, 0x78, 0x06, 0xe2, 0xfe, 0x08, 0xe2, 
+0xff, 0x78, 0x05, 0x12, 0x13, 0xcd, 0x74, 0x09, 0x93, 0xfc, 0x74, 0x0a, 0x93, 0xfd, 0xc3, 0xec, 
+0x94, 0x00, 0x50, 0x05, 0x12, 0x14, 0x3a, 0x80, 0x04, 0xae, 0x25, 0xaf, 0x26, 0x12, 0x12, 0xd0, 
+0x40, 0x06, 0xae, 0x29, 0xaf, 0x2a, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x01, 0x8e, 0x25, 0x8f, 0x26, 
+0x78, 0x0a, 0xe2, 0xfe, 0x08, 0xe2, 0xff, 0x78, 0x09, 0x80, 0x62, 0x78, 0xaa, 0xe6, 0x14, 0x65, 
+0x2f, 0x70, 0x6a, 0xf5, 0x22, 0x12, 0x13, 0x04, 0x12, 0x12, 0x89, 0x74, 0x03, 0x93, 0xf5, 0x27, 
+0x74, 0x04, 0x93, 0xf5, 0x28, 0x12, 0x12, 0x90, 0x12, 0x13, 0x46, 0x12, 0x12, 0x9e, 0x24, 0xfe, 
+0x12, 0x12, 0x98, 0x24, 0xfd, 0x12, 0x13, 0xcc, 0x74, 0x0b, 0x93, 0xfc, 0x74, 0x0c, 0x93, 0xfd, 
+0xc3, 0xec, 0x94, 0x00, 0x50, 0x05, 0x12, 0x14, 0x3a, 0x80, 0x04, 0xae, 0x25, 0xaf, 0x26, 0x12, 
+0x12, 0xd0, 0x40, 0x06, 0xae, 0x29, 0xaf, 0x2a, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x01, 0x8e, 0x25, 
+0x8f, 0x26, 0x12, 0x12, 0x9e, 0x24, 0xfa, 0x12, 0x12, 0x98, 0x24, 0xf9, 0xf8, 0x12, 0x13, 0x15, 
+0xfe, 0xe4, 0x8f, 0x2e, 0x8e, 0x2d, 0xf5, 0x2c, 0xf5, 0x2b, 0x02, 0x11, 0x5d, 0x12, 0x13, 0x9e, 
+0xac, 0x06, 0xad, 0x07, 0xe5, 0x30, 0xc3, 0x13, 0xfe, 0xe5, 0x31, 0x13, 0x2d, 0xf5, 0x28, 0xec, 
+0x3e, 0xf5, 0x27, 0x12, 0x12, 0x9e, 0x24, 0xfe, 0x12, 0x12, 0x98, 0x24, 0xfd, 0x12, 0x13, 0x48, 
+0x12, 0x12, 0x9e, 0x24, 0x06, 0x12, 0x12, 0x98, 0x24, 0x05, 0x12, 0x13, 0xcc, 0xd3, 0xe5, 0x24, 
+0x95, 0x26, 0xe5, 0x23, 0x95, 0x25, 0x40, 0x38, 0xe5, 0x2f, 0xb4, 0x01, 0x25, 0xe5, 0x31, 0xae, 
+0x30, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x7c, 0x00, 0x7d, 0x05, 0x12, 
+0x09, 0x74, 0xaa, 0x06, 0xab, 0x07, 0x12, 0x13, 0x9e, 0xef, 0x2b, 0xf5, 0x28, 0xee, 0x3a, 0x12, 
+0x13, 0x02, 0xe4, 0xf5, 0x22, 0x12, 0x14, 0x59, 0x85, 0x23, 0x25, 0x85, 0x24, 0x26, 0x80, 0x37, 
+0x78, 0xaa, 0xe6, 0x24, 0xfe, 0xb5, 0x2f, 0x1b, 0x12, 0x13, 0x9e, 0xaa, 0x06, 0xab, 0x07, 0xae, 
+0x30, 0xaf, 0x31, 0x7c, 0x00, 0x7d, 0x05, 0x12, 0x09, 0x74, 0xeb, 0x2f, 0xf5, 0x28, 0xea, 0x3e, 
+0x12, 0x13, 0x02, 0x75, 0x22, 0x01, 0xe4, 0x85, 0x24, 0x2e, 0x85, 0x23, 0x2d, 0xf5, 0x2c, 0xf5, 
+0x2b, 0x85, 0x25, 0x25, 0x85, 0x26, 0x26, 0x12, 0x12, 0x90, 0x12, 0x13, 0x46, 0xae, 0x23, 0xaf, 
+0x24, 0xe4, 0xfc, 0xfd, 0xab, 0x2e, 0xaa, 0x2d, 0xa9, 0x2c, 0xa8, 0x2b, 0xc3, 0x12, 0x0c, 0x2e, 
+0x50, 0x29, 0xae, 0x25, 0xaf, 0x26, 0xe4, 0xfc, 0xfd, 0xa8, 0x2b, 0xc3, 0x12, 0x0c, 0x2e, 0x50, 
+0x1a, 0xae, 0x2d, 0xaf, 0x2e, 0xc3, 0xe5, 0x24, 0x9f, 0xf5, 0x24, 0xe5, 0x23, 0x9e, 0xf5, 0x23, 
+0xc3, 0xe5, 0x26, 0x9f, 0xf5, 0x26, 0xe5, 0x25, 0x9e, 0xf5, 0x25, 0xe4, 0x12, 0x14, 0x59, 0x7f, 
+0x80, 0xfe, 0xfd, 0xfc, 0xab, 0x2e, 0xaa, 0x2d, 0xa9, 0x2c, 0xa8, 0x2b, 0x12, 0x13, 0x6b, 0xae, 
+0x30, 0xaf, 0x31, 0x12, 0x13, 0xc6, 0xc0, 0x06, 0xc0, 0x07, 0xe5, 0x24, 0x25, 0x26, 0xff, 0xe5, 
+0x23, 0x35, 0x25, 0xab, 0x07, 0xfa, 0xe4, 0xf9, 0xf8, 0xd0, 0x07, 0xd0, 0x06, 0x12, 0x0b, 0x9c, 
+0xef, 0x24, 0x40, 0xff, 0xe4, 0x3e, 0xfe, 0xe4, 0x3d, 0xfd, 0xe4, 0x3c, 0xfc, 0xe4, 0x7b, 0x80, 
+0xfa, 0xf9, 0xf8, 0x12, 0x0b, 0x9c, 0x8f, 0x2e, 0x8e, 0x2d, 0x8d, 0x2c, 0x8c, 0x2b, 0xe5, 0x22, 
+0x60, 0x1b, 0xe4, 0xfc, 0xfd, 0xe5, 0x2e, 0x25, 0x28, 0xf5, 0x2e, 0xe5, 0x2d, 0x35, 0x27, 0xf5, 
+0x2d, 0xed, 0x35, 0x2c, 0xf5, 0x2c, 0xec, 0x35, 0x2b, 0xf5, 0x2b, 0x80, 0x17, 0xc3, 0xe5, 0x28, 
+0x95, 0x2e, 0xf5, 0x2e, 0xe5, 0x27, 0x95, 0x2d, 0xf5, 0x2d, 0xe4, 0x95, 0x2c, 0xf5, 0x2c, 0xe4, 
+0x95, 0x2b, 0xf5, 0x2b, 0xae, 0x2d, 0xaf, 0x2e, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x08, 0xf5, 0x83, 
+0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x09, 0x82, 0x85, 0x08, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 
+0xff, 0xe5, 0x09, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x35, 0x08, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 
+0xf0, 0x85, 0x09, 0x82, 0x85, 0x08, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe5, 
+0x09, 0x24, 0x23, 0xf5, 0x82, 0xe4, 0x35, 0x08, 0xf5, 0x83, 0x22, 0xee, 0xf0, 0xef, 0xa3, 0xf0, 
+0x85, 0x09, 0x82, 0x85, 0x08, 0x83, 0xa3, 0x22, 0xe4, 0x7b, 0x0a, 0xfa, 0xf9, 0xf8, 0x12, 0x0b, 
+0x9c, 0xa8, 0x04, 0xa9, 0x05, 0xaa, 0x06, 0xab, 0x07, 0x85, 0x0b, 0x82, 0x85, 0x0a, 0x83, 0x22, 
+0xe5, 0x2f, 0x25, 0xe0, 0x25, 0xe0, 0x24, 0x02, 0xf8, 0xe2, 0xfe, 0x08, 0xe2, 0xff, 0xe5, 0x2f, 
+0x25, 0xe0, 0x25, 0xe0, 0x22, 0xe5, 0x22, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xbf, 0xf5, 0x82, 0xe4, 
+0x34, 0x02, 0xf5, 0x83, 0xe5, 0x82, 0x25, 0x45, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x22, 
+0xe5, 0x21, 0x75, 0xf0, 0x27, 0xa4, 0x24, 0x69, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0x22, 
+0x8e, 0x29, 0x8f, 0x2a, 0x12, 0x09, 0x62, 0x7c, 0x00, 0x7d, 0x32, 0x12, 0x09, 0x74, 0xef, 0x25, 
+0x26, 0xf5, 0x2a, 0xee, 0x35, 0x25, 0xf5, 0x29, 0xd3, 0xe5, 0x2a, 0x94, 0x00, 0xe5, 0x29, 0x64, 
+0x80, 0x94, 0x80, 0x22, 0xe5, 0x22, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xd3, 0xf5, 0x82, 0xe4, 0x34, 
+0x02, 0x22, 0xf5, 0x27, 0xe5, 0x31, 0x25, 0x31, 0xf5, 0x31, 0xe5, 0x30, 0x33, 0xf5, 0x30, 0x22, 
+0x25, 0xe0, 0x24, 0x01, 0xf8, 0xe2, 0x2f, 0xff, 0x18, 0xe2, 0x3e, 0x22, 0x74, 0x01, 0x93, 0xfe, 
+0x74, 0x02, 0x93, 0xff, 0xe4, 0xfc, 0xfd, 0x02, 0x0c, 0x6e, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 
+0xff, 0xe5, 0x09, 0x22, 0x13, 0xff, 0xe4, 0xfc, 0xfd, 0xeb, 0x2f, 0xff, 0xea, 0x3e, 0xfe, 0xed, 
+0x39, 0xfd, 0xec, 0x38, 0xfc, 0x22, 0x24, 0x01, 0xf8, 0xe2, 0x2f, 0xf5, 0x24, 0x18, 0xe2, 0x3e, 
+0xf5, 0x23, 0x22, 0x90, 0x02, 0x8c, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x22, 0x33, 0x95, 0xe0, 
+0xfd, 0xfc, 0xab, 0x36, 0xaa, 0x35, 0xa9, 0x34, 0xa8, 0x33, 0x22, 0x12, 0x0b, 0x11, 0xa8, 0x04, 
+0xa9, 0x05, 0xaa, 0x06, 0xab, 0x07, 0x22, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7c, 0x00, 0x7d, 0x03, 
+0x02, 0x09, 0x62, 0x93, 0xff, 0xe4, 0xfc, 0xfd, 0x12, 0x0c, 0x6e, 0x12, 0x0b, 0x11, 0xe4, 0x7b, 
+0x02, 0xfa, 0xf9, 0xf8, 0x22, 0x7b, 0x01, 0x7e, 0x00, 0x7f, 0x07, 0x02, 0x08, 0xc2, 0xaf, 0x2f, 
+0x7e, 0x00, 0xac, 0x30, 0xad, 0x31, 0x02, 0x09, 0x62, 0x3e, 0xf5, 0x25, 0xd3, 0xe5, 0x24, 0x95, 
+0x26, 0xe5, 0x23, 0x95, 0x25, 0x22, 0x7e, 0x00, 0x7f, 0x06, 0x7d, 0x00, 0x7b, 0x01, 0x02, 0x0c, 
+0xd9, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x02, 0x0b, 0x11, 0xf8, 0xe2, 0x2f, 0xf5, 
+0x26, 0x18, 0xe2, 0x3e, 0xf5, 0x25, 0x22, 0xe5, 0x22, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xbf, 0xf5, 
+0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0x22, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xc3, 0x9f, 0x22, 
+0x78, 0x6e, 0xfe, 0xe4, 0xfc, 0xfd, 0x02, 0x0c, 0x7b, 0xf0, 0xe5, 0x21, 0x75, 0xf0, 0x27, 0xa4, 
+0x22, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, 0x2f, 0xff, 0xee, 0x3c, 
+0xfe, 0xef, 0x78, 0x02, 0x22, 0xe5, 0x82, 0x2d, 0xf5, 0x82, 0xe5, 0x83, 0x3c, 0xf5, 0x83, 0xef, 
+0xf0, 0x22, 0x78, 0x72, 0x12, 0x0c, 0x52, 0x78, 0x6e, 0x12, 0x0c, 0x6e, 0xeb, 0x2f, 0x22, 0x74, 
+0x1a, 0x93, 0xff, 0xe4, 0xfc, 0xfd, 0xfe, 0x02, 0x0b, 0x11, 0xc3, 0xe5, 0x24, 0x95, 0x26, 0xff, 
+0xe5, 0x23, 0x95, 0x25, 0xfe, 0x22, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x09, 0x22, 0x74, 0x24, 
+0x25, 0x23, 0xf8, 0xa6, 0x06, 0x78, 0x74, 0xe6, 0x22, 0x85, 0x26, 0x2e, 0x85, 0x25, 0x2d, 0xf5, 
+0x2c, 0xf5, 0x2b, 0x22, 0xab, 0x4a, 0xaa, 0x4b, 0xa9, 0x4c, 0x02, 0x0a, 0x15, 0xf8, 0xe2, 0xfe, 
+0x08, 0xe2, 0xff, 0x22, 0x90, 0x02, 0x6e, 0xe0, 0x60, 0x0e, 0x90, 0x02, 0x95, 0xe0, 0x7f, 0x01, 
+0x60, 0x02, 0x7f, 0x02, 0x8f, 0x27, 0x80, 0x0c, 0x90, 0x02, 0x95, 0xe0, 0x7f, 0x00, 0x60, 0x02, 
+0x7f, 0x01, 0x8f, 0x27, 0x90, 0x02, 0x8e, 0xe0, 0xff, 0x60, 0x0e, 0x90, 0x02, 0xb5, 0xe0, 0x7e, 
+0x01, 0x60, 0x02, 0x7e, 0x02, 0x8e, 0x28, 0x80, 0x0c, 0x90, 0x02, 0xb5, 0xe0, 0x7e, 0x00, 0x60, 
+0x02, 0x7e, 0x01, 0x8e, 0x28, 0xe4, 0xf5, 0x22, 0xe5, 0x27, 0x64, 0x01, 0x70, 0x54, 0xe5, 0x28, 
+0x70, 0x03, 0x02, 0x15, 0xe2, 0xe5, 0x28, 0xb4, 0x01, 0x12, 0xef, 0x60, 0x03, 0x02, 0x15, 0xe2, 
+0x90, 0x02, 0xb5, 0xe0, 0x70, 0x03, 0x02, 0x15, 0xe2, 0x02, 0x15, 0xdf, 0xe5, 0x28, 0x64, 0x02, 
+0x60, 0x03, 0x02, 0x15, 0xe2, 0x12, 0x16, 0x77, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x16, 0x10, 0xd0, 
+0xe0, 0x2f, 0xf5, 0x24, 0xd0, 0xe0, 0x12, 0x16, 0x29, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x16, 0x45, 
+0xd0, 0xe0, 0x2f, 0xf5, 0x26, 0xd0, 0xe0, 0x12, 0x13, 0xa9, 0x50, 0x03, 0x02, 0x15, 0xe2, 0x02, 
+0x15, 0xdf, 0xe5, 0x27, 0x64, 0x02, 0x60, 0x03, 0x02, 0x15, 0xe2, 0xe5, 0x28, 0x70, 0x03, 0x02, 
+0x15, 0xe2, 0xe5, 0x28, 0x64, 0x01, 0x70, 0x73, 0x90, 0x02, 0x8e, 0xe0, 0x60, 0x2c, 0x12, 0x16, 
+0x77, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x16, 0x10, 0xd0, 0xe0, 0x2f, 0xf5, 0x24, 0xd0, 0xe0, 0x3e, 
+0xf5, 0x23, 0x90, 0x02, 0x8a, 0x12, 0x16, 0x90, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x13, 0x53, 0x90, 
+0x02, 0x94, 0xe0, 0x9f, 0xff, 0x90, 0x02, 0x93, 0x80, 0x2a, 0x90, 0x02, 0xb1, 0x12, 0x16, 0x90, 
+0xc0, 0x06, 0xc0, 0x07, 0x12, 0x16, 0x5e, 0xd0, 0xe0, 0x2f, 0xf5, 0x24, 0xd0, 0xe0, 0x12, 0x16, 
+0x29, 0xc0, 0x06, 0xc0, 0x07, 0x90, 0x02, 0xb3, 0x12, 0x13, 0x56, 0x90, 0x02, 0x6d, 0xe0, 0x9f, 
+0xff, 0x90, 0x02, 0x6c, 0xe0, 0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0xd0, 0xe0, 0x2f, 0xf5, 0x26, 0xd0, 
+0xe0, 0x3e, 0xf5, 0x25, 0x12, 0x13, 0xac, 0x40, 0x49, 0x80, 0x44, 0xe5, 0x28, 0x64, 0x02, 0x70, 
+0x41, 0x12, 0x16, 0x5e, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x13, 0x53, 0x90, 0x02, 0x6d, 0xe0, 0x90, 
+0x02, 0x6c, 0x12, 0x16, 0xa6, 0xd0, 0xe0, 0x2f, 0xf5, 0x24, 0xd0, 0xe0, 0x3e, 0xf5, 0x23, 0x12, 
+0x13, 0x53, 0x90, 0x02, 0x94, 0xe0, 0x90, 0x02, 0x93, 0x12, 0x16, 0xa6, 0xc0, 0x06, 0xc0, 0x07, 
+0x12, 0x16, 0x45, 0xd0, 0xe0, 0x2f, 0xf5, 0x26, 0xd0, 0xe0, 0x12, 0x13, 0xa9, 0x40, 0x03, 0x75, 
+0x22, 0x01, 0xe5, 0x22, 0x60, 0x29, 0x78, 0x6e, 0x7c, 0x00, 0x7d, 0x00, 0x7a, 0x02, 0x79, 0x69, 
+0x12, 0x13, 0x95, 0x78, 0x69, 0x7c, 0x02, 0x7d, 0x01, 0x7a, 0x02, 0x79, 0x90, 0x12, 0x13, 0x95, 
+0x78, 0x90, 0x7c, 0x02, 0x7d, 0x01, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x6e, 0x12, 0x13, 0x97, 0x22, 
+0x90, 0x02, 0x8c, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x90, 0x02, 0x6d, 0xe0, 0x9f, 0xff, 0x90, 
+0x02, 0x6c, 0xe0, 0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0x22, 0x3e, 0xf5, 0x23, 0x90, 0x02, 0xb1, 0xe0, 
+0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x90, 0x02, 0x6b, 0xe0, 0x9f, 0xff, 0x90, 0x02, 0x6a, 0xe0, 0x9e, 
+0xfe, 0x12, 0x2b, 0x6f, 0x22, 0x90, 0x02, 0xb3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x90, 0x02, 
+0x6d, 0xe0, 0x9f, 0xff, 0x90, 0x02, 0x6c, 0xe0, 0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0x22, 0x90, 0x02, 
+0xb3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x90, 0x02, 0x94, 0xe0, 0x9f, 0xff, 0x90, 0x02, 0x93, 
+0xe0, 0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0x22, 0x90, 0x02, 0x8a, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 
+0x90, 0x02, 0x6b, 0xe0, 0x9f, 0xff, 0x90, 0x02, 0x6a, 0xe0, 0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0x22, 
+0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x90, 0x02, 0x92, 0xe0, 0x9f, 0xff, 0x90, 0x02, 0x91, 0xe0, 
+0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0x22, 0x9f, 0xff, 0xe0, 0x9e, 0xfe, 0x12, 0x2b, 0x6f, 0x22, 0x15, 
+0x0f, 0x15, 0x0f, 0x12, 0x25, 0x8a, 0x78, 0x8c, 0xe6, 0xa8, 0x0f, 0xf6, 0x78, 0x8a, 0xe6, 0x60, 
+0x33, 0xa8, 0x0f, 0x08, 0xe4, 0xf6, 0xa8, 0x0f, 0x08, 0xe6, 0xff, 0xc3, 0x78, 0x8f, 0x96, 0x50, 
+0x58, 0x12, 0x24, 0x95, 0xa8, 0x0f, 0xe6, 0xfd, 0x12, 0x27, 0xf8, 0xa8, 0x0f, 0x08, 0x12, 0x24, 
+0x93, 0xa8, 0x0f, 0xe6, 0x7d, 0x01, 0xb4, 0x08, 0x02, 0x7d, 0x00, 0x12, 0x29, 0xd6, 0xa8, 0x0f, 
+0x08, 0x06, 0x80, 0xd2, 0x78, 0x7d, 0x12, 0x24, 0x93, 0xa8, 0x0f, 0xe6, 0xfd, 0x12, 0x27, 0xf8, 
+0x78, 0x7d, 0x12, 0x24, 0x93, 0xa8, 0x0f, 0xe6, 0x7d, 0x01, 0xb4, 0x08, 0x02, 0x7d, 0x00, 0x12, 
+0x29, 0xd6, 0x12, 0x24, 0x91, 0xa8, 0x0f, 0xe6, 0xfd, 0x12, 0x24, 0x8e, 0xa8, 0x0f, 0xe6, 0x7d, 
+0x01, 0xb4, 0x08, 0x02, 0x7d, 0x00, 0x12, 0x29, 0xd6, 0x90, 0xff, 0x52, 0xe0, 0xfe, 0xa3, 0xe0, 
+0xff, 0x78, 0x7d, 0xe6, 0xfd, 0x12, 0x24, 0xe0, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0xff, 0x5a, 
+0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x18, 0xe6, 0x12, 0x24, 0xe0, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x74, 
+0x55, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x79, 0x08, 0xe6, 0xff, 0x24, 
+0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0x74, 0x01, 0xf0, 0xef, 0x12, 0x24, 0xb8, 0xe0, 
+0xfe, 0xa3, 0xe0, 0xff, 0xe6, 0x12, 0x24, 0xe0, 0x12, 0x25, 0x74, 0x12, 0x2b, 0x6f, 0x90, 0x02, 
+0x51, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x78, 0x7c, 0xe6, 0xff, 0x12, 0x24, 0xb8, 0xe0, 0xfc, 0xa3, 
+0xe0, 0xfd, 0xef, 0x12, 0x24, 0xe0, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0x9d, 0xff, 0xee, 0x9c, 0xfe, 
+0x12, 0x2b, 0x6f, 0x90, 0x02, 0x53, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x24, 0xee, 0x74, 0x07, 
+0x93, 0xfe, 0x74, 0x08, 0x93, 0xff, 0xc3, 0x90, 0x02, 0x52, 0xe0, 0x9f, 0x90, 0x02, 0x51, 0xe0, 
+0x9e, 0x50, 0x61, 0xc3, 0x90, 0x02, 0x54, 0xe0, 0x9f, 0x90, 0x02, 0x53, 0xe0, 0x9e, 0x50, 0x54, 
+0x12, 0x25, 0x7f, 0x80, 0x4f, 0x12, 0x25, 0x7f, 0x12, 0x24, 0xee, 0x78, 0x7d, 0x12, 0x24, 0xae, 
+0x12, 0x24, 0xd6, 0x12, 0x25, 0x1d, 0x40, 0x16, 0xe6, 0x12, 0x24, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 
+0x90, 0x02, 0x51, 0x12, 0x25, 0x0e, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x24, 
+0xee, 0x78, 0x7c, 0x12, 0x24, 0xae, 0x12, 0x24, 0xd6, 0x12, 0x25, 0x1d, 0x40, 0x16, 0xe6, 0x12, 
+0x24, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x02, 0x53, 0x12, 0x25, 0x0e, 0xd0, 0x82, 0xd0, 0x83, 
+0xf0, 0xa3, 0xef, 0xf0, 0x78, 0x8d, 0xe6, 0x70, 0x0a, 0x90, 0xff, 0x50, 0xf0, 0x90, 0xff, 0x58, 
+0xf0, 0x80, 0x03, 0x12, 0x28, 0xa7, 0x05, 0x0f, 0x05, 0x0f, 0x22, 0x8b, 0x1e, 0x8a, 0x1f, 0x89, 
+0x20, 0x7e, 0x00, 0x7f, 0x0c, 0x7d, 0x00, 0x12, 0x0c, 0xd9, 0x7a, 0x02, 0x79, 0x6a, 0x12, 0x13, 
+0xb6, 0x7a, 0x02, 0x79, 0x91, 0x12, 0x13, 0xb6, 0x78, 0xae, 0xe6, 0x14, 0x60, 0x34, 0x04, 0x60, 
+0x03, 0x02, 0x19, 0xb1, 0xe4, 0x78, 0xad, 0xf6, 0xff, 0x12, 0x2b, 0x57, 0x12, 0x1d, 0xe7, 0x78, 
+0x30, 0xe2, 0x30, 0xe2, 0x09, 0x78, 0x89, 0xe6, 0x30, 0xe4, 0x03, 0x02, 0x19, 0xb5, 0x7e, 0x00, 
+0x7f, 0x4e, 0x7d, 0x00, 0x7b, 0x01, 0x7a, 0x02, 0x79, 0x69, 0x12, 0x0c, 0xd9, 0x78, 0xae, 0x76, 
+0x01, 0x22, 0x12, 0x1d, 0xe7, 0x78, 0x30, 0xe2, 0x30, 0xe2, 0x09, 0x78, 0x89, 0xe6, 0x30, 0xe4, 
+0x03, 0x02, 0x19, 0xb1, 0x78, 0x89, 0xe6, 0x20, 0xe3, 0x03, 0x02, 0x19, 0x4e, 0x12, 0x22, 0x5f, 
+0x78, 0xab, 0xe6, 0xff, 0x12, 0x27, 0x22, 0x78, 0xab, 0xa6, 0x07, 0x08, 0xe6, 0xff, 0x12, 0x27, 
+0x22, 0x78, 0xac, 0xa6, 0x07, 0x75, 0x25, 0xfe, 0x75, 0x26, 0x00, 0x75, 0x27, 0x00, 0x7b, 0x00, 
+0x7a, 0x00, 0x79, 0xab, 0x12, 0x33, 0xea, 0xe4, 0xf5, 0x21, 0x74, 0xab, 0x25, 0x21, 0xf8, 0xe6, 
+0xff, 0x12, 0x12, 0xc0, 0xef, 0xf0, 0x12, 0x12, 0xc0, 0xe0, 0xf4, 0x60, 0x49, 0xaf, 0x21, 0x12, 
+0x1c, 0x8e, 0x12, 0x13, 0xfa, 0x24, 0x6a, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 
+0xa3, 0xef, 0xf0, 0xaf, 0x21, 0x12, 0x0f, 0xc1, 0x12, 0x13, 0xfa, 0x24, 0x6c, 0xf5, 0x82, 0xe4, 
+0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0x12, 0x13, 0xf9, 0x24, 0x6e, 0xf5, 0x82, 0xe4, 
+0x34, 0x02, 0xf5, 0x83, 0x74, 0x01, 0x12, 0x13, 0xf9, 0x24, 0x6a, 0xf9, 0x74, 0x02, 0x35, 0xf0, 
+0xfa, 0x7b, 0x01, 0x12, 0x00, 0x09, 0x05, 0x21, 0xe5, 0x21, 0xc3, 0x94, 0x02, 0x40, 0x9b, 0x12, 
+0x14, 0x74, 0x78, 0x89, 0xe6, 0x30, 0xe5, 0x15, 0x78, 0xad, 0x76, 0x01, 0x80, 0x0f, 0x90, 0x02, 
+0xb7, 0x74, 0xff, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x02, 0xbd, 0xf0, 0xa3, 0xf0, 0x75, 0x08, 0x02, 
+0x75, 0x09, 0x69, 0xe4, 0xf5, 0x21, 0xe5, 0x21, 0xc3, 0x94, 0x02, 0x50, 0x17, 0xaf, 0x21, 0x12, 
+0x00, 0x24, 0x12, 0x1f, 0x3e, 0x05, 0x21, 0x74, 0x27, 0x25, 0x09, 0xf5, 0x09, 0xe4, 0x35, 0x08, 
+0xf5, 0x08, 0x80, 0xe2, 0xa8, 0x20, 0xac, 0x1f, 0xad, 0x1e, 0x7b, 0x01, 0x7a, 0x02, 0x79, 0x6a, 
+0x7e, 0x00, 0x7f, 0x06, 0x12, 0x08, 0xc2, 0xe5, 0x20, 0x24, 0x06, 0xf9, 0xe4, 0x35, 0x1f, 0xa8, 
+0x01, 0xfc, 0xad, 0x1e, 0x7b, 0x01, 0x7a, 0x02, 0x79, 0x91, 0x7e, 0x00, 0x7f, 0x06, 0x02, 0x08, 
+0xc2, 0xe4, 0x78, 0xae, 0xf6, 0x22, 0x8b, 0x1e, 0x8a, 0x1f, 0x89, 0x20, 0x43, 0xad, 0x04, 0x90, 
+0xff, 0x40, 0xe0, 0x20, 0xe0, 0xf9, 0x43, 0x95, 0x80, 0x90, 0xff, 0x41, 0x74, 0x37, 0xf0, 0x90, 
+0xff, 0x49, 0x74, 0x0d, 0xf0, 0xe4, 0xf5, 0x27, 0xf5, 0x27, 0x12, 0x2a, 0x55, 0xe5, 0x27, 0xc3, 
+0x9f, 0x50, 0x22, 0xe9, 0x24, 0x0c, 0xf9, 0xe4, 0x3a, 0x12, 0x2a, 0x46, 0xe4, 0xfd, 0x12, 0x2a, 
+0x0a, 0x12, 0x2a, 0x3c, 0x7d, 0x08, 0x12, 0x28, 0x53, 0x12, 0x2a, 0x3c, 0xe4, 0xfd, 0x12, 0x29, 
+0xd6, 0x05, 0x27, 0x80, 0xd5, 0xe4, 0x90, 0xff, 0x4a, 0xf0, 0x90, 0xff, 0x50, 0x74, 0x0f, 0xf0, 
+0xe4, 0x90, 0xff, 0x58, 0xf0, 0x90, 0xff, 0x40, 0x74, 0x08, 0xf0, 0x90, 0xff, 0x43, 0x74, 0x9f, 
+0xf0, 0xab, 0x1e, 0xaa, 0x1f, 0xa9, 0x20, 0x12, 0x08, 0xe8, 0x90, 0xff, 0x48, 0xf0, 0x90, 0x00, 
+0x01, 0x12, 0x09, 0x01, 0x90, 0xff, 0x42, 0xf0, 0x90, 0x00, 0x02, 0x12, 0x09, 0x01, 0x90, 0xff, 
+0x55, 0xf0, 0xe4, 0x90, 0xff, 0x5d, 0xf0, 0x90, 0x00, 0x03, 0x12, 0x09, 0x01, 0x90, 0xff, 0x54, 
+0xf0, 0xe4, 0x90, 0xff, 0x5c, 0xf0, 0xf5, 0x27, 0x12, 0x2a, 0x55, 0xe5, 0x27, 0xc3, 0x9f, 0x50, 
+0x5b, 0xe4, 0xf5, 0x28, 0x75, 0x29, 0x64, 0x90, 0xff, 0x50, 0xe0, 0x20, 0xe7, 0x03, 0x43, 0x28, 
+0x01, 0xe5, 0x28, 0x64, 0x01, 0x60, 0x03, 0xd5, 0x29, 0xed, 0x12, 0x2a, 0x63, 0x12, 0x2a, 0x3c, 
+0x7d, 0x06, 0x12, 0x28, 0x53, 0x90, 0xff, 0x40, 0x74, 0x29, 0xf0, 0x90, 0xff, 0x40, 0xe0, 0x20, 
+0xe0, 0xf9, 0x12, 0x2a, 0x3c, 0x7d, 0x08, 0x12, 0x28, 0x53, 0x90, 0xff, 0x52, 0xe0, 0xfe, 0xa3, 
+0xe0, 0xff, 0xab, 0x21, 0xe5, 0x23, 0xf9, 0x24, 0x02, 0xf5, 0x23, 0xe5, 0x22, 0xfa, 0x34, 0x00, 
+0xf5, 0x22, 0xee, 0x8f, 0xf0, 0x12, 0x0a, 0xc5, 0x05, 0x27, 0x80, 0x9c, 0xe4, 0xf5, 0x27, 0x75, 
+0x28, 0x01, 0x12, 0x2a, 0x3c, 0x7d, 0x07, 0x12, 0x28, 0x53, 0xe5, 0x28, 0x24, 0x02, 0x90, 0xff, 
+0x55, 0xf0, 0xe4, 0xf5, 0x29, 0xf5, 0x2a, 0x05, 0x2a, 0xe5, 0x2a, 0x70, 0x02, 0x05, 0x29, 0xb4, 
+0x20, 0xf5, 0xe5, 0x29, 0xb4, 0x03, 0xf0, 0x90, 0xff, 0x50, 0xe0, 0x30, 0xe7, 0x0c, 0x12, 0x2a, 
+0x63, 0x05, 0x28, 0xe5, 0x28, 0xc3, 0x94, 0x64, 0x40, 0xd0, 0xab, 0x24, 0xaa, 0x25, 0xa9, 0x26, 
+0x85, 0x27, 0x82, 0x75, 0x83, 0x00, 0xe5, 0x28, 0x12, 0x09, 0x40, 0x12, 0x2a, 0x3c, 0x7d, 0x08, 
+0x12, 0x28, 0x53, 0x12, 0x2a, 0x63, 0x12, 0x2a, 0x55, 0x05, 0x27, 0xe5, 0x27, 0xc3, 0x9f, 0x40, 
+0x9e, 0xe4, 0x90, 0xff, 0x50, 0xf0, 0xff, 0x22, 0x8b, 0x1f, 0x8a, 0x20, 0x89, 0x21, 0x43, 0xad, 
+0x04, 0x43, 0x95, 0x80, 0x90, 0xff, 0x41, 0x74, 0x80, 0xf0, 0x90, 0xff, 0x49, 0x74, 0x0d, 0xf0, 
+0xe4, 0x90, 0xff, 0x4a, 0xf0, 0x90, 0xff, 0x42, 0x04, 0xf0, 0x90, 0xff, 0x55, 0x74, 0x7d, 0xf0, 
+0x90, 0xff, 0x5d, 0xf0, 0xe4, 0x12, 0x2a, 0x8a, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x26, 0xf5, 0x27, 
+0xf5, 0x28, 0xf5, 0x29, 0xf5, 0x25, 0xe4, 0x90, 0xff, 0x50, 0x12, 0x2a, 0x7a, 0xf4, 0x60, 0x0d, 
+0xe4, 0xfd, 0x12, 0x29, 0xd6, 0x12, 0x2a, 0x7f, 0x7d, 0x08, 0x12, 0x28, 0x53, 0x12, 0x2a, 0x6c, 
+0xf4, 0x60, 0x0d, 0xe4, 0xfd, 0x12, 0x29, 0xd6, 0x12, 0x2a, 0x6c, 0x7d, 0x08, 0x12, 0x28, 0x53, 
+0xe4, 0xff, 0x00, 0x0f, 0xbf, 0xc8, 0xfb, 0x90, 0xff, 0x50, 0x74, 0x03, 0x12, 0x2a, 0x7a, 0xf4, 
+0x60, 0x0d, 0xe4, 0xfd, 0x12, 0x2a, 0x0a, 0x12, 0x2a, 0x7f, 0x7d, 0x07, 0x12, 0x28, 0x53, 0x12, 
+0x2a, 0x6c, 0xf4, 0x60, 0x0d, 0x7d, 0x01, 0x12, 0x2a, 0x0a, 0x12, 0x2a, 0x6c, 0x7d, 0x07, 0x12, 
+0x28, 0x53, 0x90, 0xff, 0x43, 0x74, 0x9f, 0xf0, 0x90, 0xff, 0x50, 0x74, 0x07, 0xf0, 0x90, 0xff, 
+0x58, 0xf0, 0x90, 0xff, 0x40, 0x74, 0x09, 0xf0, 0x75, 0x8a, 0xa0, 0xe4, 0x90, 0x00, 0x3a, 0xf0, 
+0x90, 0xff, 0x43, 0xe0, 0x30, 0xe4, 0xf9, 0x90, 0xff, 0x43, 0x74, 0x9f, 0xf0, 0x90, 0xff, 0x52, 
+0xe0, 0xfe, 0xa3, 0xe0, 0x25, 0x27, 0xf5, 0x27, 0xee, 0x35, 0x26, 0xf5, 0x26, 0x90, 0xff, 0x5a, 
+0xe0, 0xfe, 0xa3, 0xe0, 0x25, 0x29, 0xf5, 0x29, 0xee, 0x35, 0x28, 0xf5, 0x28, 0x05, 0x25, 0xe5, 
+0x25, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x02, 0x1b, 0x66, 0xe5, 0x27, 0xae, 0x26, 0x78, 0x02, 0xce, 
+0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xab, 0x22, 0xaa, 0x23, 0xa9, 0x24, 0xee, 0x8f, 0xf0, 
+0x12, 0x0a, 0xc5, 0xe5, 0x29, 0xae, 0x28, 0x78, 0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 
+0xff, 0xab, 0x22, 0xaa, 0x23, 0xa9, 0x24, 0x90, 0x00, 0x02, 0xee, 0x8f, 0xf0, 0x12, 0x0a, 0xe4, 
+0x53, 0x95, 0x7f, 0xe4, 0x90, 0xff, 0x41, 0xf0, 0x90, 0xff, 0x49, 0xf0, 0x90, 0xff, 0x4a, 0xf0, 
+0x90, 0xff, 0x50, 0xf0, 0x90, 0xff, 0x58, 0xf0, 0x90, 0xff, 0x42, 0xf0, 0x90, 0xff, 0x55, 0xf0, 
+0x90, 0xff, 0x5d, 0xf0, 0x12, 0x2a, 0x8a, 0x12, 0x2a, 0x7e, 0xf4, 0x60, 0x05, 0xe4, 0xfd, 0x12, 
+0x28, 0x53, 0x12, 0x2a, 0x6c, 0xf4, 0x60, 0x05, 0xe4, 0xfd, 0x12, 0x28, 0x53, 0x22, 0xef, 0x12, 
+0x12, 0xc2, 0xe0, 0xff, 0x70, 0x04, 0xf5, 0x22, 0x80, 0x18, 0x78, 0xaa, 0xe6, 0xfe, 0x14, 0xb5, 
+0x07, 0x09, 0xee, 0x25, 0xe0, 0x24, 0xfa, 0xf5, 0x22, 0x80, 0x07, 0xef, 0x25, 0xe0, 0x24, 0xfe, 
+0xf5, 0x22, 0xe5, 0x22, 0x25, 0xe0, 0x24, 0x04, 0x12, 0x14, 0x6d, 0xe5, 0x22, 0x12, 0x13, 0x10, 
+0xfe, 0xe5, 0x22, 0x25, 0xe0, 0x24, 0x09, 0x12, 0x13, 0x14, 0xfe, 0x90, 0x02, 0xbd, 0xe0, 0xfa, 
+0xa3, 0xe0, 0xfb, 0xc3, 0xef, 0x9b, 0xff, 0xee, 0x9a, 0x12, 0x13, 0xf0, 0xe5, 0x22, 0x25, 0xe0, 
+0x24, 0x06, 0x12, 0x14, 0x6d, 0xe5, 0x22, 0x25, 0xe0, 0x24, 0x03, 0x12, 0x13, 0x14, 0xfe, 0xe5, 
+0x22, 0x25, 0xe0, 0x24, 0x0b, 0x12, 0x13, 0x14, 0xcf, 0xc3, 0x9b, 0xcf, 0x9a, 0x78, 0x72, 0x12, 
+0x13, 0xf2, 0x12, 0x12, 0x89, 0x74, 0x07, 0x93, 0xfe, 0x74, 0x08, 0x78, 0x72, 0x12, 0x13, 0x83, 
+0x12, 0x0b, 0x11, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x12, 0x89, 0x78, 0x72, 
+0x12, 0x13, 0x1c, 0x12, 0x0b, 0x11, 0xd0, 0x03, 0xd0, 0x02, 0xd0, 0x01, 0xd0, 0x00, 0xef, 0x2b, 
+0xff, 0xee, 0x3a, 0x12, 0x13, 0x3e, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x12, 
+0x89, 0x74, 0x05, 0x93, 0xfe, 0x74, 0x06, 0x78, 0x6e, 0x12, 0x13, 0x83, 0x12, 0x13, 0x6b, 0xd0, 
+0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xc3, 0xef, 0x9b, 0xff, 0xee, 0x9a, 0xfe, 0xed, 0x99, 
+0xfd, 0xec, 0x98, 0xfc, 0x78, 0x76, 0x12, 0x0c, 0x7b, 0x78, 0x76, 0x12, 0x0c, 0x52, 0xec, 0x33, 
+0x50, 0x0b, 0x78, 0x6e, 0x12, 0x0c, 0x87, 0x00, 0x00, 0x00, 0x01, 0x80, 0x64, 0x12, 0x14, 0x22, 
+0xff, 0xea, 0x3e, 0xfe, 0xe9, 0x3d, 0xfd, 0xe8, 0x3c, 0xfc, 0x12, 0x13, 0x8e, 0x12, 0x0b, 0x9c, 
+0x78, 0x76, 0x12, 0x0c, 0x6e, 0xef, 0x2b, 0xff, 0xee, 0x3a, 0x12, 0x13, 0x3e, 0xc0, 0x04, 0xc0, 
+0x05, 0xc0, 0x06, 0xc0, 0x07, 0x12, 0x14, 0x22, 0xfb, 0xea, 0x3e, 0xfa, 0xe9, 0x3d, 0xf9, 0xe8, 
+0x3c, 0xf8, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0x12, 0x0b, 0x9c, 0x78, 0x6e, 0x12, 
+0x0c, 0x7b, 0x12, 0x12, 0x89, 0x78, 0x6e, 0x12, 0x13, 0x1c, 0xd3, 0x12, 0x0c, 0x2e, 0x40, 0x11, 
+0x12, 0x12, 0x89, 0x74, 0x02, 0x93, 0x24, 0xff, 0xff, 0x74, 0x01, 0x93, 0x34, 0xff, 0x12, 0x13, 
+0xf0, 0x78, 0x6e, 0x12, 0x0c, 0x52, 0x22, 0xe4, 0x78, 0x89, 0xf6, 0x18, 0xe6, 0x14, 0x70, 0x03, 
+0x02, 0x1e, 0xac, 0x14, 0x70, 0x03, 0x02, 0x1f, 0x15, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1f, 0x39, 
+0xe4, 0x78, 0x8e, 0xf6, 0x78, 0x89, 0xf6, 0xfe, 0x7f, 0x8c, 0xfd, 0x12, 0x24, 0xf5, 0x7f, 0x1c, 
+0x7a, 0x00, 0x79, 0x00, 0x12, 0x25, 0x4b, 0x7f, 0x0e, 0x7a, 0x00, 0x79, 0x20, 0x12, 0x25, 0x4b, 
+0x12, 0x24, 0xee, 0x74, 0x02, 0x93, 0x78, 0x8f, 0xf6, 0x78, 0x84, 0xe6, 0x30, 0xe0, 0x08, 0x75, 
+0x23, 0x05, 0x75, 0x24, 0x01, 0x80, 0x06, 0x75, 0x23, 0x08, 0xe4, 0xf5, 0x24, 0xe4, 0xf5, 0x22, 
+0xe5, 0x22, 0xc3, 0x78, 0x8f, 0x96, 0x50, 0x60, 0xe5, 0x59, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 
+0x58, 0xf5, 0x83, 0xe5, 0x82, 0x25, 0x22, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe4, 0x93, 
+0xf5, 0x25, 0xe5, 0x22, 0x24, 0x0a, 0xff, 0xe4, 0x33, 0xfe, 0xe5, 0x59, 0x2f, 0xf5, 0x82, 0xe5, 
+0x58, 0x3e, 0xf5, 0x83, 0xe4, 0x93, 0xf5, 0x26, 0xe4, 0xfd, 0xaf, 0x25, 0x12, 0x2a, 0x0a, 0x7d, 
+0x01, 0xaf, 0x26, 0x12, 0x2a, 0x0a, 0xad, 0x24, 0xaf, 0x25, 0x12, 0x29, 0xd6, 0xad, 0x24, 0xaf, 
+0x26, 0x12, 0x29, 0xd6, 0xad, 0x23, 0xaf, 0x25, 0x12, 0x28, 0x53, 0xad, 0x23, 0xaf, 0x26, 0x12, 
+0x28, 0x53, 0x05, 0x22, 0x05, 0x22, 0x80, 0x98, 0x78, 0x88, 0x76, 0x01, 0x12, 0x24, 0xee, 0x74, 
+0x08, 0x93, 0x25, 0xe0, 0xf5, 0x25, 0x74, 0x07, 0x93, 0x33, 0xf5, 0x24, 0x75, 0x23, 0x04, 0x12, 
+0x2a, 0xbe, 0x7f, 0xff, 0x12, 0x26, 0x5a, 0x12, 0x2a, 0xbe, 0xe4, 0xf5, 0x22, 0xe5, 0x22, 0xc3, 
+0x78, 0x8f, 0x96, 0x50, 0x36, 0xe5, 0x22, 0x12, 0x24, 0xb8, 0xe0, 0xfe, 0xa3, 0xe0, 0x78, 0x02, 
+0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe5, 0x22, 0x12, 0x24, 0xc8, 0xee, 0x8f, 0xf0, 
+0x12, 0x09, 0xff, 0xe5, 0x22, 0x12, 0x24, 0xc8, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe5, 0x22, 0x12, 
+0x25, 0x54, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x05, 0x22, 0x80, 0xc2, 0x15, 0x23, 0xe5, 0x23, 0x70, 
+0xb1, 0x78, 0x88, 0x76, 0x02, 0x12, 0x2a, 0xbe, 0x7f, 0xff, 0x12, 0x26, 0x5a, 0x78, 0x8f, 0xe6, 
+0xfd, 0xe4, 0xff, 0x12, 0x21, 0x29, 0x78, 0x89, 0xe6, 0x30, 0xe1, 0x04, 0x78, 0x8e, 0x76, 0x50, 
+0x78, 0x8f, 0xe6, 0xfd, 0xe4, 0xff, 0x02, 0x1f, 0xf2, 0xe4, 0x78, 0x88, 0xf6, 0x22, 0xe5, 0x09, 
+0x24, 0x05, 0x12, 0x12, 0x63, 0xe0, 0x60, 0x12, 0xe5, 0x09, 0x24, 0x25, 0x12, 0x12, 0x63, 0xe0, 
+0x7e, 0x01, 0x60, 0x02, 0x7e, 0x03, 0xaf, 0x06, 0x80, 0x1e, 0xe5, 0x09, 0x24, 0x25, 0x12, 0x12, 
+0x63, 0xe0, 0x60, 0x12, 0xe5, 0x09, 0x24, 0x0a, 0x12, 0x12, 0x63, 0xe0, 0x7e, 0x02, 0x60, 0x02, 
+0x7e, 0x03, 0xaf, 0x06, 0x80, 0x02, 0xe4, 0xff, 0xe5, 0x09, 0x24, 0x06, 0x12, 0x12, 0x63, 0xef, 
+0xf0, 0xe5, 0x09, 0x24, 0x05, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xe5, 0x09, 0x24, 0x25, 0x12, 0x12, 
+0x63, 0xee, 0x12, 0x12, 0x6f, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xe5, 0x09, 0x24, 0x21, 0x12, 0x12, 
+0x63, 0xec, 0xf0, 0xed, 0x12, 0x12, 0x6e, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x12, 0x12, 
+0x5f, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xe5, 0x09, 0x24, 0x06, 0x12, 0x12, 0x63, 0xe0, 0xfe, 0xe5, 
+0x09, 0x24, 0x26, 0x12, 0x12, 0x63, 0xee, 0xf0, 0x22, 0x78, 0xff, 0xe4, 0xf6, 0xd8, 0xfd, 0x90, 
+0x00, 0x00, 0x7f, 0x00, 0x7e, 0x03, 0xe4, 0xf0, 0xa3, 0xdf, 0xfc, 0xde, 0xfa, 0x75, 0x81, 0xb0, 
+0x75, 0xa0, 0x00, 0x02, 0x2c, 0xb9, 0x12, 0x2b, 0x22, 0x22, 0x90, 0x00, 0x04, 0x02, 0x09, 0x01, 
+0x01, 0x06, 0x8f, 0x27, 0x8d, 0x28, 0x78, 0x8e, 0xe6, 0x60, 0x01, 0x16, 0x12, 0x24, 0xc6, 0xe0, 
+0xfe, 0xa3, 0xe0, 0xff, 0xe5, 0x27, 0x12, 0x24, 0xb8, 0xe0, 0xfc, 0xa3, 0xe0, 0xc3, 0x9f, 0xf5, 
+0x2a, 0xec, 0x9e, 0xf5, 0x29, 0x12, 0x25, 0x27, 0xe0, 0xf5, 0x2b, 0x78, 0x8e, 0xe6, 0x60, 0x09, 
+0xd3, 0x12, 0x25, 0x62, 0x40, 0x03, 0x02, 0x20, 0xe2, 0xaf, 0x2a, 0xae, 0x29, 0x12, 0x2b, 0x6f, 
+0x12, 0x24, 0xee, 0xc3, 0x74, 0x08, 0x93, 0x9f, 0x74, 0x07, 0x93, 0x9e, 0x50, 0x0d, 0x12, 0x25, 
+0x62, 0x40, 0x04, 0x05, 0x2b, 0x80, 0x57, 0x15, 0x2b, 0x80, 0x53, 0x12, 0x24, 0xfe, 0xe0, 0xff, 
+0x33, 0x95, 0xe0, 0xfe, 0xef, 0x25, 0x2a, 0xf5, 0x2a, 0xee, 0x35, 0x29, 0xf5, 0x29, 0xd3, 0xe5, 
+0x2a, 0x94, 0x78, 0x12, 0x25, 0x66, 0x40, 0x09, 0x12, 0x24, 0xc6, 0xe4, 0x75, 0xf0, 0x01, 0x80, 
+0x1a, 0xe5, 0x2a, 0x24, 0x78, 0xe4, 0x35, 0x29, 0xc3, 0x64, 0x80, 0x94, 0x80, 0xe5, 0x27, 0x75, 
+0xf0, 0x0a, 0x50, 0x11, 0x12, 0x24, 0xcb, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x09, 0xff, 0x12, 0x24, 
+0xfe, 0xe4, 0xf0, 0x80, 0x06, 0x12, 0x25, 0x03, 0xe5, 0x2a, 0xf0, 0xe4, 0xf5, 0x2b, 0x12, 0x24, 
+0xee, 0x74, 0x04, 0x93, 0xff, 0xd3, 0x64, 0x80, 0xf8, 0xe5, 0x2b, 0x64, 0x80, 0x98, 0x50, 0x17, 
+0xef, 0x33, 0x95, 0xe0, 0xfe, 0xad, 0x2b, 0xed, 0x33, 0x95, 0xe0, 0xfc, 0xed, 0x2f, 0xec, 0x3e, 
+0xc3, 0x64, 0x80, 0x94, 0x80, 0x50, 0x15, 0xe4, 0xf5, 0x2b, 0xe5, 0x27, 0x12, 0x24, 0xb8, 0xe0, 
+0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x24, 0xc6, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x12, 0x25, 0x27, 0xe5, 
+0x2b, 0xf0, 0x78, 0x8e, 0xe6, 0x70, 0x36, 0x12, 0x24, 0xc6, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe5, 
+0x27, 0x12, 0x25, 0x54, 0x12, 0x25, 0x74, 0x12, 0x2b, 0x6f, 0xaa, 0x06, 0xab, 0x07, 0x12, 0x24, 
+0xee, 0x74, 0x07, 0x93, 0xfe, 0x74, 0x08, 0x93, 0xff, 0x7c, 0x00, 0x7d, 0x03, 0x12, 0x09, 0x62, 
+0xd3, 0xeb, 0x9f, 0xea, 0x9e, 0x40, 0x06, 0x78, 0x89, 0xe6, 0x44, 0x10, 0xf6, 0x05, 0x27, 0x15, 
+0x28, 0xe5, 0x28, 0x60, 0x03, 0x02, 0x1f, 0xfc, 0x22, 0xab, 0x07, 0xaa, 0x05, 0xe4, 0x90, 0x01, 
+0xb0, 0xf0, 0xeb, 0x12, 0x24, 0xb8, 0xe0, 0xf5, 0x29, 0xa3, 0xe0, 0xf5, 0x2a, 0x78, 0x8f, 0xe6, 
+0xff, 0xeb, 0xc3, 0x9f, 0x40, 0x04, 0x78, 0x86, 0x80, 0x02, 0x78, 0x7e, 0xe6, 0x75, 0x27, 0x00, 
+0xf5, 0x28, 0xae, 0x27, 0xaf, 0x28, 0x7c, 0x00, 0x7d, 0xfc, 0x12, 0x09, 0x62, 0xd3, 0xe5, 0x2a, 
+0x9f, 0xe5, 0x29, 0x9e, 0x40, 0x0e, 0x78, 0x89, 0xe6, 0x44, 0x20, 0xf6, 0x74, 0x20, 0x2b, 0xf8, 
+0xe2, 0x44, 0x10, 0xf2, 0x12, 0x24, 0xee, 0x74, 0x08, 0x93, 0x25, 0xe0, 0xf5, 0x2a, 0x74, 0x07, 
+0x93, 0x33, 0xf5, 0x29, 0x74, 0x20, 0x2b, 0xf8, 0xe2, 0xf9, 0x30, 0xe0, 0x19, 0xe5, 0x2a, 0xae, 
+0x29, 0x78, 0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xc3, 0xe5, 0x2a, 0x9f, 0xf5, 
+0x2a, 0xe5, 0x29, 0x9e, 0xf5, 0x29, 0xe5, 0x29, 0xc3, 0x13, 0xfe, 0xe5, 0x2a, 0x13, 0xff, 0xeb, 
+0x12, 0x24, 0xc8, 0xe0, 0xfc, 0xa3, 0xe0, 0x2f, 0xff, 0xec, 0x3e, 0xfe, 0xeb, 0x12, 0x24, 0xb8, 
+0xe0, 0xfc, 0xa3, 0xe0, 0xd3, 0x9f, 0xec, 0x9e, 0x40, 0x51, 0x74, 0x20, 0x2b, 0xf8, 0xe9, 0x44, 
+0x02, 0xf2, 0xeb, 0x12, 0x24, 0xc8, 0xe0, 0xfe, 0xa3, 0xe0, 0x25, 0x2a, 0xff, 0xe5, 0x29, 0x3e, 
+0xfe, 0xeb, 0x12, 0x24, 0xb8, 0xe0, 0xfc, 0xa3, 0xe0, 0xd3, 0x9f, 0xec, 0x9e, 0x40, 0x22, 0x78, 
+0x89, 0xe6, 0x44, 0x02, 0xf6, 0x44, 0x08, 0xf6, 0x74, 0x20, 0x2b, 0xf8, 0xe2, 0x44, 0x01, 0xf2, 
+0x78, 0x8f, 0xe6, 0xff, 0xeb, 0xc3, 0x9f, 0x50, 0x1a, 0x90, 0x01, 0xb0, 0xe0, 0x04, 0xf0, 0x80, 
+0x12, 0x74, 0x20, 0x2b, 0xf8, 0xe2, 0x54, 0xfe, 0xf2, 0x80, 0x08, 0x74, 0x20, 0x2b, 0xf8, 0xe9, 
+0x54, 0xfd, 0xf2, 0xeb, 0x12, 0x24, 0xc8, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xeb, 0x12, 0x24, 0xb8, 
+0x12, 0x25, 0x1d, 0xeb, 0x40, 0x17, 0x12, 0x24, 0xc8, 0xe0, 0xfe, 0xa3, 0xe0, 0x12, 0x25, 0x15, 
+0xf8, 0xeb, 0x25, 0xe0, 0x24, 0x00, 0xc8, 0xf2, 0x08, 0xef, 0xf2, 0x80, 0x09, 0x25, 0xe0, 0x24, 
+0x00, 0xf8, 0xe4, 0xf2, 0x08, 0xf2, 0x0b, 0x1a, 0xea, 0x60, 0x03, 0x02, 0x21, 0x32, 0x22, 0xe4, 
+0x78, 0x74, 0xf6, 0x08, 0xf6, 0x78, 0x6e, 0xf6, 0x08, 0xf6, 0x08, 0xf6, 0x08, 0xf6, 0x08, 0xf6, 
+0x08, 0xf6, 0xf5, 0x22, 0xff, 0xf5, 0x23, 0x7e, 0xff, 0xe5, 0x22, 0xc3, 0x78, 0xaa, 0x96, 0x40, 
+0x03, 0x02, 0x23, 0x11, 0xe5, 0x22, 0x25, 0xe0, 0x25, 0xe0, 0x24, 0x02, 0xf8, 0xe2, 0xfc, 0x08, 
+0xe2, 0xfd, 0xe5, 0x22, 0x25, 0xe0, 0x25, 0xe0, 0x24, 0x01, 0xf8, 0xe2, 0x2d, 0xf5, 0x28, 0x18, 
+0xe2, 0x3c, 0xf5, 0x27, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x78, 0x74, 0xe6, 0xfc, 0x08, 0xe6, 
+0xfd, 0x74, 0x08, 0x93, 0x2d, 0xfb, 0x74, 0x07, 0x93, 0x3c, 0xfa, 0xd3, 0xe5, 0x28, 0x9b, 0xe5, 
+0x27, 0x9a, 0x40, 0x05, 0x7f, 0x01, 0x18, 0x80, 0x3c, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x74, 
+0x08, 0x93, 0x25, 0x28, 0xfb, 0x74, 0x07, 0x93, 0x35, 0x27, 0xfa, 0xd3, 0xed, 0x9b, 0xec, 0x9a, 
+0x40, 0x2a, 0xef, 0x60, 0x1e, 0xe4, 0xff, 0x12, 0x14, 0x4e, 0xfc, 0x08, 0xe6, 0xfd, 0xe5, 0x23, 
+0x25, 0xe0, 0x24, 0x6e, 0xf8, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0x05, 0x23, 0xe5, 0x23, 0xc3, 0x94, 
+0x03, 0x50, 0x0e, 0x78, 0x74, 0xa6, 0x27, 0x08, 0xa6, 0x28, 0xae, 0x22, 0x05, 0x22, 0x02, 0x22, 
+0x79, 0xef, 0x60, 0x1c, 0xe5, 0x23, 0xc3, 0x94, 0x02, 0x50, 0x15, 0x12, 0x14, 0x4e, 0xfe, 0x08, 
+0xe6, 0xff, 0xe5, 0x23, 0x25, 0xe0, 0x24, 0x6e, 0xf8, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x05, 0x23, 
+0x7b, 0x00, 0x7a, 0x00, 0x79, 0x6e, 0x75, 0x2d, 0xff, 0x12, 0x23, 0x6d, 0xb4, 0xff, 0x04, 0x7f, 
+0xff, 0x80, 0x07, 0x74, 0x24, 0x25, 0x22, 0xf8, 0xe6, 0xff, 0x78, 0xab, 0xa6, 0x07, 0x7b, 0x00, 
+0x7a, 0x00, 0x79, 0x6e, 0x85, 0x22, 0x2d, 0x12, 0x23, 0x6d, 0xb4, 0xff, 0x04, 0x7f, 0xff, 0x80, 
+0x07, 0x74, 0x24, 0x25, 0x22, 0xf8, 0xe6, 0xff, 0x78, 0xac, 0xa6, 0x07, 0x22, 0xad, 0x23, 0x12, 
+0x29, 0x30, 0x8f, 0x22, 0xe5, 0x22, 0x22, 0x8b, 0x1e, 0x8a, 0x1f, 0x89, 0x20, 0xe4, 0xf5, 0x21, 
+0xf5, 0x22, 0xf5, 0x23, 0x85, 0x5b, 0x82, 0x85, 0x5a, 0x83, 0xe4, 0x93, 0xff, 0xe5, 0x21, 0xc3, 
+0x9f, 0x40, 0x03, 0x02, 0x24, 0x58, 0x12, 0x00, 0x18, 0x74, 0x01, 0x93, 0xf5, 0x24, 0x12, 0x00, 
+0x12, 0x74, 0x02, 0x93, 0xf5, 0x25, 0x12, 0x00, 0x12, 0x74, 0x04, 0x93, 0xfc, 0x74, 0x05, 0x93, 
+0xfd, 0xe5, 0x24, 0x25, 0xe0, 0x24, 0x00, 0xf8, 0xe2, 0xfe, 0x08, 0xe2, 0xff, 0xd3, 0x9d, 0xee, 
+0x9c, 0x40, 0x6f, 0x7c, 0x00, 0x7d, 0x05, 0x12, 0x09, 0x62, 0xe5, 0x25, 0x25, 0xe0, 0x24, 0x01, 
+0xf8, 0xe2, 0x24, 0x01, 0xfd, 0x18, 0xe2, 0x34, 0x00, 0xfc, 0x12, 0x09, 0x74, 0x8e, 0x26, 0x8f, 
+0x27, 0x12, 0x00, 0x12, 0x74, 0x03, 0x93, 0x30, 0xe7, 0x2b, 0x54, 0x7f, 0xc3, 0x95, 0x27, 0xff, 
+0xe4, 0x95, 0x26, 0xfe, 0x12, 0x2b, 0x6f, 0xc3, 0x74, 0x03, 0x9f, 0xee, 0x64, 0x80, 0xf8, 0x74, 
+0x80, 0x98, 0x40, 0x2e, 0xaf, 0x21, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 
+0xfc, 0x42, 0x22, 0x80, 0x1d, 0x12, 0x00, 0x12, 0x74, 0x03, 0x93, 0xc3, 0x95, 0x27, 0xe4, 0x95, 
+0x26, 0x50, 0x0f, 0xaf, 0x21, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 
+0x42, 0x22, 0x12, 0x00, 0x12, 0x74, 0x01, 0x93, 0x24, 0x20, 0xf8, 0xe2, 0xc3, 0x13, 0x20, 0xe0, 
+0x0f, 0x12, 0x00, 0x12, 0x74, 0x02, 0x93, 0x24, 0x20, 0xf8, 0xe2, 0xc3, 0x13, 0x30, 0xe0, 0x03, 
+0x75, 0x23, 0x01, 0x05, 0x21, 0x02, 0x23, 0x84, 0x90, 0x00, 0x36, 0xe0, 0x65, 0x22, 0x60, 0x0a, 
+0xe5, 0x22, 0xf0, 0xe4, 0x90, 0x00, 0x35, 0xf0, 0x80, 0x14, 0x90, 0x00, 0x35, 0xe0, 0x04, 0xf0, 
+0xc3, 0x94, 0x03, 0x40, 0x09, 0xe0, 0x14, 0xf0, 0x90, 0x00, 0x37, 0xe5, 0x22, 0xf0, 0x90, 0x00, 
+0x37, 0xe0, 0xab, 0x1e, 0xaa, 0x1f, 0xa9, 0x20, 0x12, 0x09, 0x2e, 0xaf, 0x23, 0x22, 0x12, 0x27, 
+0xf8, 0x78, 0x7c, 0xe6, 0xff, 0xe5, 0x59, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x58, 0xf5, 0x83, 
+0xe5, 0x82, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe4, 0x93, 0xff, 0x22, 0x74, 0x07, 
+0x93, 0xfe, 0x74, 0x08, 0x93, 0xff, 0xe6, 0xfd, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb1, 0xf5, 0x82, 
+0xe4, 0x34, 0x01, 0xf5, 0x83, 0x22, 0xe5, 0x27, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb3, 0xf5, 0x82, 
+0xe4, 0x34, 0x01, 0xf5, 0x83, 0x22, 0xe0, 0xfa, 0xa3, 0xe0, 0x2f, 0xff, 0xea, 0x3e, 0xfe, 0xed, 
+0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb7, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0x22, 0x85, 0x59, 
+0x82, 0x85, 0x58, 0x83, 0x22, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0xb1, 0x02, 0x0c, 0xd9, 0xe5, 0x27, 
+0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0x22, 0xe0, 0xc3, 
+0x13, 0xfe, 0xa3, 0xe0, 0x13, 0xff, 0xc3, 0xed, 0x9f, 0xff, 0xec, 0x9e, 0x22, 0xe0, 0xfc, 0xa3, 
+0xe0, 0xfd, 0xd3, 0x9f, 0xec, 0x9e, 0x22, 0xe5, 0x27, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb6, 0xf5, 
+0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0x22, 0xe6, 0x90, 0xff, 0x55, 0xf0, 0x90, 0xff, 0x5d, 0xf0, 
+0x22, 0x43, 0xad, 0x04, 0x90, 0xff, 0x40, 0x74, 0x29, 0xf0, 0x22, 0x7e, 0x00, 0x7d, 0x00, 0x7b, 
+0xfe, 0x02, 0x0c, 0xd9, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb9, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 
+0x83, 0x22, 0xe5, 0x2a, 0x94, 0x00, 0xe5, 0x29, 0x64, 0x80, 0x94, 0x80, 0x22, 0x85, 0x1f, 0x82, 
+0x85, 0x1e, 0x83, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, 0xc3, 0x9f, 0xff, 0xec, 0x9e, 0xfe, 0x22, 0x78, 
+0x7d, 0x06, 0x06, 0x18, 0x06, 0x06, 0x78, 0x8d, 0x16, 0x22, 0x90, 0xff, 0x43, 0x74, 0x9f, 0xf0, 
+0x22, 0x8e, 0x1e, 0x8f, 0x1f, 0xe4, 0x78, 0x88, 0xf6, 0x78, 0x8b, 0xf6, 0x85, 0x1e, 0x58, 0x85, 
+0x1f, 0x59, 0xe5, 0x1f, 0x24, 0x31, 0xff, 0xe4, 0x35, 0x1e, 0xfa, 0xa9, 0x07, 0x7b, 0xff, 0x78, 
+0x7e, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x0a, 0x12, 0x08, 0xc2, 0x7e, 0x00, 0x7f, 0xa0, 
+0x7d, 0x00, 0x12, 0x24, 0xf5, 0x12, 0x25, 0x6d, 0x74, 0x31, 0x93, 0x78, 0x7e, 0xf6, 0x12, 0x25, 
+0x6d, 0x74, 0x39, 0x93, 0x78, 0x86, 0xf6, 0x12, 0x24, 0xee, 0x74, 0x05, 0x93, 0xff, 0x7e, 0x00, 
+0x7c, 0x10, 0x7d, 0x00, 0x12, 0x0c, 0xac, 0xe4, 0x7b, 0xc8, 0xfa, 0xf9, 0xf8, 0x12, 0x0b, 0x9c, 
+0x78, 0x7a, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0xe4, 0x78, 0x8d, 0xf6, 0x43, 0x95, 0x80, 0x90, 0xff, 
+0x41, 0x74, 0x77, 0xf0, 0x90, 0xff, 0x49, 0x74, 0x0d, 0xf0, 0x12, 0x25, 0x6d, 0xe4, 0x93, 0xf5, 
+0x20, 0xf4, 0x60, 0x0c, 0xe4, 0xfd, 0xaf, 0x20, 0x12, 0x29, 0xd6, 0xe4, 0xfd, 0x12, 0x26, 0x46, 
+0x12, 0x25, 0x6d, 0x74, 0x01, 0x93, 0xf5, 0x20, 0xf4, 0x60, 0x0c, 0xe4, 0xfd, 0xaf, 0x20, 0x12, 
+0x29, 0xd6, 0x7d, 0x01, 0x12, 0x26, 0x46, 0x78, 0x84, 0xe6, 0x7f, 0x08, 0x30, 0xe0, 0x02, 0x7f, 
+0x05, 0x78, 0x8c, 0xa6, 0x07, 0x22, 0xaf, 0x20, 0x12, 0x2a, 0x0a, 0x7d, 0x08, 0xaf, 0x20, 0x12, 
+0x28, 0x53, 0x7d, 0x07, 0xaf, 0x20, 0x12, 0x28, 0x53, 0x22, 0x90, 0xff, 0x4a, 0x74, 0x71, 0xf0, 
+0x90, 0xff, 0x50, 0x74, 0x0f, 0xf0, 0x90, 0xff, 0x58, 0xf0, 0xe4, 0x90, 0xff, 0x40, 0xf0, 0x12, 
+0x25, 0x8a, 0x78, 0x81, 0xe6, 0x90, 0xff, 0x54, 0xf0, 0x90, 0xff, 0x5c, 0xf0, 0x78, 0x7f, 0xe6, 
+0x90, 0xff, 0x42, 0xf0, 0x78, 0x83, 0x12, 0x25, 0x37, 0x90, 0xff, 0x48, 0x74, 0x02, 0xf0, 0x12, 
+0x25, 0x41, 0x90, 0xff, 0x43, 0xe0, 0x20, 0xe4, 0x08, 0x75, 0x91, 0xc1, 0xe4, 0xf5, 0x91, 0x80, 
+0xf1, 0x12, 0x25, 0x8a, 0xe4, 0x78, 0x8a, 0xf6, 0x78, 0x7d, 0xbf, 0xff, 0x1b, 0xf6, 0x18, 0x76, 
+0x01, 0x78, 0x8f, 0xe6, 0xc3, 0x13, 0x78, 0x8d, 0xf6, 0x78, 0x7f, 0xe6, 0x90, 0xff, 0x42, 0xf0, 
+0x08, 0x12, 0x25, 0x37, 0x78, 0x7e, 0x80, 0x1b, 0xa6, 0x07, 0xef, 0x04, 0x18, 0xf6, 0x78, 0x8d, 
+0x76, 0x01, 0x78, 0x8a, 0x76, 0x01, 0x78, 0x85, 0xe6, 0x90, 0xff, 0x42, 0xf0, 0x78, 0x87, 0x12, 
+0x25, 0x37, 0x18, 0xe6, 0x90, 0xff, 0x48, 0xf0, 0x7e, 0x00, 0x7f, 0x14, 0x7d, 0x00, 0x7b, 0x01, 
+0x7a, 0x02, 0x79, 0x55, 0x12, 0x0c, 0xd9, 0x12, 0x28, 0xa7, 0x78, 0x82, 0xe6, 0x30, 0xe7, 0x1b, 
+0x12, 0x25, 0x41, 0x90, 0xff, 0x43, 0xe0, 0x20, 0xe4, 0x08, 0x75, 0x91, 0xc1, 0xe4, 0xf5, 0x91, 
+0x80, 0xf1, 0x12, 0x16, 0xaf, 0x78, 0x8d, 0xe6, 0x70, 0xe9, 0x22, 0x53, 0xad, 0xfb, 0x12, 0x25, 
+0x44, 0x22, 0xab, 0x07, 0xbb, 0xff, 0x03, 0x7f, 0xff, 0x22, 0xeb, 0x70, 0x0c, 0x12, 0x12, 0x89, 
+0x74, 0x11, 0x93, 0xf5, 0x22, 0x74, 0x12, 0x80, 0x1d, 0x78, 0xaa, 0xe6, 0x14, 0xb5, 0x03, 0x0c, 
+0x12, 0x12, 0x89, 0x74, 0x13, 0x93, 0xf5, 0x22, 0x74, 0x14, 0x80, 0x0a, 0x12, 0x12, 0x89, 0x74, 
+0x0f, 0x93, 0xf5, 0x22, 0x74, 0x10, 0x93, 0xf5, 0x23, 0x90, 0x02, 0x8f, 0xe0, 0x70, 0x06, 0x90, 
+0x02, 0xb6, 0xe0, 0x60, 0x14, 0xe5, 0x23, 0x25, 0xe0, 0xff, 0xe5, 0x22, 0x33, 0xfe, 0x7c, 0x00, 
+0x7d, 0x03, 0x12, 0x09, 0x74, 0x8e, 0x22, 0x8f, 0x23, 0xeb, 0x25, 0xe0, 0x25, 0xe0, 0x24, 0x02, 
+0x12, 0x14, 0x6d, 0xeb, 0x25, 0xe0, 0x12, 0x13, 0x10, 0xfe, 0xc3, 0xef, 0x95, 0x23, 0xee, 0x95, 
+0x22, 0xaf, 0x03, 0x50, 0x02, 0x7f, 0xff, 0x22, 0xf6, 0x08, 0xf6, 0x08, 0xf6, 0x08, 0xf6, 0x22, 
+0x8f, 0x23, 0xe4, 0x78, 0x94, 0xf6, 0x08, 0xf6, 0x78, 0x92, 0xf6, 0x08, 0xf6, 0x90, 0x01, 0x9c, 
+0xe0, 0x7f, 0x00, 0x22, 0x9f, 0xff, 0xe4, 0x94, 0x00, 0xfe, 0xef, 0x26, 0xf6, 0x18, 0xee, 0x36, 
+0xf6, 0x22, 0x90, 0x01, 0x9b, 0xe0, 0xff, 0x78, 0x9c, 0xe6, 0x22, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 
+0x7c, 0x00, 0x7d, 0x0a, 0x02, 0x09, 0x62, 0xd3, 0xef, 0x9d, 0xec, 0x64, 0x80, 0xf8, 0xee, 0x64, 
+0x80, 0x98, 0x22, 0xd3, 0xe6, 0x94, 0x00, 0x18, 0xe6, 0x64, 0x80, 0x94, 0x80, 0x22, 0xd3, 0xef, 
+0x95, 0x22, 0x74, 0x80, 0xf8, 0x6e, 0x98, 0x22, 0xef, 0x54, 0x07, 0x90, 0x2c, 0xa9, 0x93, 0xfe, 
+0xf4, 0xfc, 0xef, 0x54, 0xf0, 0xff, 0xc2, 0xaf, 0x75, 0xa0, 0xff, 0x64, 0x10, 0x70, 0x16, 0xbd, 
+0x08, 0x02, 0x7d, 0x02, 0x78, 0x12, 0xed, 0x30, 0xe2, 0x05, 0xe2, 0x4e, 0xf2, 0x80, 0x03, 0xe2, 
+0x5c, 0xf2, 0x18, 0x80, 0x08, 0xef, 0x13, 0x13, 0x54, 0x3f, 0x24, 0x11, 0xf8, 0xed, 0x24, 0xfb, 
+0x60, 0x0b, 0x14, 0x60, 0x11, 0x24, 0xfe, 0x70, 0x14, 0xe2, 0x5c, 0x80, 0x0b, 0xe2, 0x5c, 0xf2, 
+0x18, 0xe2, 0x4e, 0xf2, 0x80, 0x07, 0xe2, 0x4e, 0xf2, 0x18, 0xe2, 0x5c, 0xf2, 0xe4, 0xf5, 0xa0, 
+0xd2, 0xaf, 0x22, 0xef, 0x54, 0x07, 0x90, 0x2c, 0xb1, 0x93, 0xfe, 0xf4, 0xfc, 0xef, 0x54, 0xf0, 
+0xff, 0xc2, 0xaf, 0x75, 0xa0, 0xff, 0x64, 0x10, 0x70, 0x16, 0xbd, 0x08, 0x02, 0x7d, 0x02, 0x78, 
+0x12, 0xed, 0x30, 0xe2, 0x05, 0xe2, 0x4e, 0xf2, 0x80, 0x03, 0xe2, 0x5c, 0xf2, 0x18, 0x80, 0x08, 
+0xef, 0x13, 0x13, 0x54, 0x3f, 0x24, 0x11, 0xf8, 0xed, 0x30, 0xe1, 0x05, 0xe2, 0x4e, 0xf2, 0x80, 
+0x03, 0xe2, 0x5c, 0xf2, 0x18, 0xed, 0x30, 0xe0, 0x05, 0xe2, 0x4e, 0xf2, 0x80, 0x03, 0xe2, 0x5c, 
+0xf2, 0xe4, 0xf5, 0xa0, 0xd2, 0xaf, 0x22, 0x15, 0x0f, 0xa8, 0x0f, 0x76, 0x64, 0x90, 0xff, 0x58, 
+0xe0, 0xff, 0x90, 0xff, 0x50, 0xe0, 0x4f, 0x30, 0xe7, 0x06, 0xa8, 0x0f, 0x16, 0xe6, 0x70, 0xed, 
+0x78, 0x8a, 0xe6, 0x60, 0x1b, 0xa8, 0x0f, 0xe4, 0xf6, 0xa8, 0x0f, 0xe6, 0xff, 0xc3, 0x78, 0x8f, 
+0x96, 0x50, 0x1c, 0x12, 0x24, 0x95, 0x7d, 0x06, 0x12, 0x28, 0x53, 0xa8, 0x0f, 0x06, 0x80, 0xe9, 
+0x78, 0x7d, 0x12, 0x24, 0x93, 0x7d, 0x06, 0x12, 0x24, 0x8e, 0x7d, 0x06, 0x12, 0x27, 0xf8, 0x12, 
+0x25, 0x44, 0x05, 0x0f, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 
+0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 
+0xc0, 0x07, 0x12, 0x16, 0xaf, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 
+0x02, 0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 
+0x8d, 0x2c, 0xe4, 0xff, 0xf5, 0x2e, 0xf5, 0x2f, 0x7e, 0xff, 0xef, 0xc3, 0x95, 0x2c, 0x50, 0x28, 
+0xef, 0x65, 0x2d, 0x60, 0x19, 0x12, 0x0a, 0x15, 0xfd, 0xac, 0xf0, 0xd3, 0x95, 0x2f, 0xec, 0x95, 
+0x2e, 0x40, 0x0b, 0xed, 0x24, 0x20, 0xf5, 0x2f, 0xe4, 0x3c, 0xf5, 0x2e, 0xae, 0x07, 0x0f, 0x74, 
+0x02, 0x29, 0xf9, 0xe4, 0x3a, 0xfa, 0x80, 0xd2, 0xaf, 0x06, 0x22, 0xe4, 0x90, 0x00, 0x3a, 0xf0, 
+0xef, 0x70, 0x11, 0x75, 0x88, 0x08, 0xf5, 0x8d, 0xf5, 0x8c, 0xf5, 0x8f, 0xf5, 0x8e, 0xf5, 0x88, 
+0x43, 0xac, 0x02, 0x22, 0x75, 0x88, 0x08, 0xe4, 0xf5, 0x8d, 0xf5, 0x8c, 0xef, 0x75, 0xf0, 0x20, 
+0xa4, 0xff, 0xe5, 0xf0, 0x44, 0x80, 0xf5, 0x8f, 0x8f, 0x8e, 0x75, 0x88, 0xa0, 0x53, 0xac, 0xfd, 
+0x22, 0xe4, 0x78, 0xae, 0xf6, 0x8f, 0x82, 0x8e, 0x83, 0x74, 0x64, 0x93, 0x78, 0xaa, 0xf6, 0xef, 
+0x24, 0x64, 0xf5, 0x0b, 0xe4, 0x3e, 0xf5, 0x0a, 0x78, 0x30, 0xe2, 0x54, 0xfe, 0xf2, 0x54, 0xfd, 
+0xf2, 0x54, 0xfb, 0xf2, 0xe4, 0x90, 0x02, 0x72, 0xf0, 0x90, 0x02, 0x99, 0xf0, 0x90, 0x02, 0x73, 
+0xf0, 0x90, 0x02, 0x9a, 0xf0, 0x22, 0x12, 0x2b, 0x4a, 0xfb, 0xef, 0xf4, 0x60, 0x2b, 0xc2, 0xaf, 
+0x75, 0xa0, 0xff, 0xbb, 0x01, 0x04, 0x7e, 0x18, 0x80, 0x08, 0xeb, 0x25, 0xe0, 0x25, 0xe0, 0x24, 
+0x12, 0xfe, 0xed, 0xa8, 0x06, 0x60, 0x05, 0xe2, 0x4c, 0xf2, 0x80, 0x08, 0xe2, 0xff, 0xec, 0xf4, 
+0xfd, 0xef, 0x5d, 0xf2, 0xe4, 0xf5, 0xa0, 0xd2, 0xaf, 0x22, 0x12, 0x2b, 0x4a, 0xfe, 0xef, 0xf4, 
+0x60, 0x29, 0x90, 0xff, 0x13, 0xee, 0xd3, 0x94, 0x03, 0x40, 0x11, 0xaf, 0x06, 0xef, 0x75, 0xf0, 
+0x04, 0xa4, 0x25, 0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0xed, 0x60, 0x04, 0xe0, 
+0x4c, 0xf0, 0x22, 0xe0, 0xff, 0xec, 0xf4, 0xfe, 0xef, 0x5e, 0xf0, 0x22, 0xab, 0x1e, 0xe5, 0x20, 
+0x24, 0x0c, 0xf9, 0xe4, 0x35, 0x1f, 0xfa, 0x7e, 0x00, 0xe9, 0x25, 0x27, 0xf9, 0xee, 0x3a, 0xfa, 
+0x12, 0x08, 0xe8, 0xff, 0x22, 0xab, 0x1e, 0xaa, 0x1f, 0xa9, 0x20, 0x90, 0x00, 0x0b, 0x12, 0x09, 
+0x01, 0xff, 0x22, 0x75, 0x8a, 0xa0, 0xe4, 0x90, 0x00, 0x3a, 0xf0, 0x22, 0xab, 0x1f, 0xaa, 0x20, 
+0xa9, 0x21, 0x90, 0x00, 0x01, 0x12, 0x09, 0x01, 0xff, 0x22, 0xf0, 0x90, 0xff, 0x58, 0xf0, 0xab, 
+0x1f, 0xaa, 0x20, 0xa9, 0x21, 0x12, 0x08, 0xe8, 0xff, 0x22, 0x90, 0xff, 0x54, 0xf0, 0x90, 0xff, 
+0x5c, 0xf0, 0x90, 0xff, 0x48, 0x22, 0x75, 0x9b, 0x5a, 0x75, 0x9a, 0xa5, 0x75, 0x99, 0xf0, 0x75, 
+0x98, 0x0f, 0x75, 0xac, 0xff, 0x75, 0xad, 0xff, 0x90, 0xff, 0x88, 0x74, 0x40, 0xf0, 0x74, 0xc0, 
+0xf0, 0x90, 0xff, 0x01, 0x74, 0x0f, 0xf0, 0x43, 0x95, 0x60, 0xe4, 0xf5, 0x96, 0x22, 0x78, 0x8d, 
+0xe6, 0x70, 0xfb, 0xff, 0xef, 0x12, 0x24, 0xe0, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x12, 0x24, 
+0xb8, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0x0f, 0xbf, 0x10, 0xea, 0x22, 0xef, 0x14, 0x60, 0x0a, 0x04, 
+0x70, 0x0e, 0x78, 0x30, 0xed, 0xf2, 0x7f, 0x00, 0x22, 0x78, 0xae, 0xa6, 0x05, 0x7f, 0x00, 0x22, 
+0x7f, 0x01, 0x22, 0xef, 0x24, 0x3b, 0xf5, 0x5b, 0xe4, 0x3e, 0xf5, 0x5a, 0x7e, 0x00, 0x7f, 0x03, 
+0x7d, 0x00, 0x7b, 0x01, 0x7a, 0x00, 0x79, 0x35, 0x02, 0x0c, 0xd9, 0x78, 0x9c, 0xe6, 0x60, 0x06, 
+0xc3, 0x94, 0xff, 0x50, 0x01, 0x06, 0x78, 0x9d, 0xe6, 0x60, 0x06, 0xc3, 0x94, 0xff, 0x50, 0x01, 
+0x06, 0x22, 0xef, 0x75, 0xf0, 0x0a, 0xa4, 0x24, 0xb1, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 
+0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x22, 0x7e, 0x00, 0x7f, 0x15, 0x7d, 0x00, 0x7b, 0x00, 0x7a, 0x00, 
+0x79, 0x90, 0x12, 0x0c, 0xd9, 0x78, 0xa3, 0x76, 0xff, 0x22, 0xef, 0x54, 0x07, 0x90, 0x2c, 0xb1, 
+0x93, 0xfc, 0xef, 0xc4, 0x54, 0x0f, 0x22, 0x78, 0x88, 0xa6, 0x07, 0xef, 0x70, 0x04, 0x78, 0x8b, 
+0xa6, 0x07, 0x22, 0xef, 0x25, 0xe0, 0x24, 0x00, 0xf8, 0xe2, 0xfe, 0x08, 0xe2, 0xff, 0x22, 0xee, 
+0x30, 0xe7, 0x07, 0xc3, 0xe4, 0x9f, 0xff, 0xe4, 0x9e, 0xfe, 0x22, 0x11, 0x16, 0x0e, 0x01, 0x0f, 
+0x78, 0x0f, 0x00, 0x64, 0x10, 0x41, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x46, 0x45, 0x44, 0x43, 
+0x17, 0x54, 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, 0x40, 0x40, 0x28, 0x00, 
+0x80, 0x64, 0x00, 0x40, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0xf0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc8, 
+0x00, 0xc8, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 
+0x00, 0x00, 0x00, 0x00, 0x11, 0x16, 0x0c, 0x02, 0x0f, 0x78, 0x14, 0x00, 0x3c, 0x41, 0x44, 0x51, 
+0x45, 0x52, 0x46, 0x53, 0x56, 0x54, 0x55, 0x43, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x2f, 0x28, 0x00, 0x80, 0x78, 0x00, 0x40, 0x0e, 0x14, 0x01, 
+0x0a, 0x08, 0x07, 0x00, 0x82, 0x1f, 0x1e, 0x32, 0x01, 0x2c, 0x1b, 0x1a, 0x32, 0x01, 0x2c, 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, 0x05, 0x00, 0xef, 0x01, 0x3f, 0x00, 0x28, 0x00, 
+0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xf0, 0x01, 0x00, 0x00, 
+0x00, 0x04, 0x01, 0x00, 0x01, 0x01, 0x05, 0x02, 0x02, 0x30, 0x03, 0x07, 0x28, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x18, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 
+0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xc2, 0xaf, 0x51, 0x96, 0xe5, 0x9b, 0xb4, 
+0x5a, 0x16, 0xe5, 0x9a, 0xb4, 0xa5, 0x11, 0xe5, 0x99, 0xb4, 0xf0, 0x0c, 0xe5, 0x98, 0xb4, 0x0f, 
+0x07, 0x90, 0xff, 0x85, 0xe0, 0x44, 0x20, 0xf0, 0x75, 0x8a, 0x0a, 0xd2, 0xaf, 0x7f, 0x0c, 0x31, 
+0x6b, 0x12, 0x33, 0xd9, 0x91, 0xea, 0xf1, 0x7e, 0x80, 0xfa, 0x75, 0x8f, 0x81, 0x75, 0x8e, 0x80, 
+0x75, 0x8a, 0xa0, 0x75, 0x8a, 0x0a, 0x90, 0x00, 0x38, 0xe0, 0x70, 0x02, 0xa1, 0xae, 0x14, 0x70, 
+0x02, 0xa1, 0xd6, 0x24, 0xfc, 0x70, 0x02, 0xc1, 0xb0, 0x04, 0x60, 0x02, 0xe1, 0x02, 0xe4, 0xf5, 
+0x1d, 0xf5, 0x1c, 0xf5, 0x1b, 0xf5, 0x1a, 0x75, 0x0d, 0x2b, 0x75, 0x0e, 0x7b, 0x12, 0x35, 0x0c, 
+0xe4, 0xfd, 0xff, 0x51, 0xdb, 0xf1, 0x87, 0x12, 0x18, 0x3b, 0xe4, 0xf5, 0x19, 0xf1, 0x67, 0x74, 
+0x02, 0x93, 0xff, 0xe5, 0x19, 0xc3, 0x9f, 0x50, 0x33, 0xaf, 0x19, 0x12, 0x1f, 0xe6, 0xd3, 0xef, 
+0x94, 0xb0, 0xee, 0x94, 0x36, 0x40, 0x21, 0xe4, 0x7f, 0x01, 0xfe, 0xfd, 0xfc, 0xa9, 0x19, 0xa8, 
+0x01, 0x12, 0x0c, 0x3f, 0xe5, 0x1d, 0x4f, 0xf5, 0x1d, 0xe5, 0x1c, 0x4e, 0xf5, 0x1c, 0xe5, 0x1b, 
+0x4d, 0xf5, 0x1b, 0xe5, 0x1a, 0x4c, 0xf5, 0x1a, 0x05, 0x19, 0x80, 0xc1, 0x75, 0x0c, 0x04, 0xe5, 
+0x0c, 0x70, 0x02, 0xe1, 0x02, 0xff, 0x12, 0x34, 0xef, 0x8e, 0x0d, 0x8f, 0x0e, 0xef, 0x4e, 0x60, 
+0x05, 0xe4, 0x90, 0x00, 0x38, 0xf0, 0x90, 0x01, 0x5a, 0xe5, 0x0c, 0xf1, 0x66, 0x74, 0x85, 0x93, 
+0x90, 0x01, 0xa5, 0xf1, 0x66, 0x74, 0x86, 0x93, 0x90, 0x01, 0xa6, 0xf1, 0x66, 0x74, 0x87, 0x93, 
+0x90, 0x01, 0xa7, 0xf1, 0x66, 0x74, 0x88, 0x93, 0x90, 0x01, 0xa8, 0xf0, 0xe1, 0x02, 0xe4, 0x78, 
+0xa5, 0xf6, 0xf1, 0x8e, 0xef, 0x64, 0x01, 0x60, 0xf9, 0x12, 0x35, 0x0c, 0xaf, 0x0e, 0xae, 0x0d, 
+0x51, 0xf3, 0xe4, 0xfd, 0xff, 0x51, 0xdb, 0x71, 0x36, 0xe4, 0x78, 0xa8, 0xf6, 0x08, 0xf6, 0x90, 
+0x00, 0x38, 0x04, 0xf0, 0xe1, 0x02, 0xe4, 0x78, 0x60, 0xf6, 0x08, 0xf6, 0x90, 0x01, 0xaf, 0xe0, 
+0xb4, 0x01, 0x08, 0x90, 0x00, 0x38, 0x74, 0x05, 0xf0, 0xe1, 0x02, 0x78, 0xa5, 0x76, 0x01, 0xf1, 
+0x87, 0x12, 0x18, 0x3b, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x61, 0x12, 0x23, 0x77, 0x78, 0x60, 0xa6, 
+0x07, 0x78, 0x66, 0xe6, 0x60, 0x07, 0x78, 0x6c, 0xe6, 0x60, 0x02, 0xc1, 0x9f, 0x78, 0x61, 0xe6, 
+0x30, 0xe0, 0x0f, 0x08, 0x76, 0x00, 0x08, 0x76, 0x64, 0x08, 0x76, 0x01, 0x08, 0x76, 0x90, 0x08, 
+0x76, 0x01, 0x78, 0x66, 0xe6, 0x60, 0x11, 0x78, 0x63, 0xe6, 0x78, 0x5c, 0xf6, 0x78, 0x65, 0xe6, 
+0x78, 0x5d, 0xf6, 0x08, 0x76, 0x01, 0x80, 0x08, 0xe4, 0x78, 0x5c, 0xf6, 0x08, 0xf6, 0x08, 0xf6, 
+0x78, 0x1e, 0x7c, 0x00, 0x7d, 0x00, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x5c, 0x7e, 0x00, 0x7f, 0x03, 
+0x12, 0x08, 0xc2, 0x90, 0x01, 0x9f, 0xe0, 0xf5, 0x21, 0x75, 0x22, 0x0f, 0x12, 0x0d, 0x05, 0x78, 
+0x5f, 0xa6, 0x07, 0x78, 0x66, 0xe6, 0x60, 0x3d, 0x90, 0x01, 0xab, 0xe0, 0xff, 0x60, 0x15, 0x78, 
+0x5f, 0xe6, 0x70, 0x10, 0x12, 0x34, 0xfd, 0x70, 0x01, 0x06, 0x86, 0x04, 0xd3, 0x9f, 0xec, 0x9e, 
+0x40, 0x23, 0x80, 0x1b, 0x90, 0x01, 0xac, 0xe0, 0xff, 0x60, 0x1a, 0x78, 0x5f, 0xe6, 0xb4, 0x0c, 
+0x14, 0x12, 0x34, 0xfd, 0x70, 0x01, 0x06, 0x86, 0x04, 0xd3, 0x9f, 0xec, 0x9e, 0x40, 0x06, 0xe4, 
+0x90, 0x00, 0x38, 0xf0, 0x22, 0xf1, 0x87, 0x78, 0x61, 0xe6, 0xfd, 0x12, 0x30, 0xac, 0x80, 0x52, 
+0xf1, 0x67, 0x74, 0x02, 0x93, 0xff, 0x90, 0x01, 0x7b, 0xf0, 0x7e, 0x00, 0xe5, 0x0e, 0x24, 0x09, 
+0xfd, 0xe4, 0x35, 0x0d, 0xfa, 0xa9, 0x05, 0x7b, 0xff, 0x78, 0x7c, 0x7c, 0x01, 0x7d, 0x01, 0x12, 
+0x08, 0xc2, 0x90, 0x01, 0xaf, 0xe0, 0xb4, 0x01, 0x29, 0x75, 0x21, 0x01, 0x75, 0x22, 0x00, 0x75, 
+0x23, 0xf0, 0x75, 0x24, 0x01, 0x75, 0x25, 0x01, 0x75, 0x26, 0x30, 0x7b, 0x01, 0x7a, 0x01, 0x79, 
+0x70, 0x12, 0x19, 0xb6, 0xe4, 0x90, 0x01, 0xaf, 0xf0, 0x75, 0x8a, 0xa0, 0x90, 0x00, 0x3a, 0xf0, 
+0x80, 0xd0, 0x90, 0x01, 0x95, 0xe0, 0x64, 0x03, 0x70, 0x20, 0x7f, 0x01, 0x12, 0x32, 0xe8, 0x7f, 
+0x3c, 0x31, 0x6b, 0x75, 0x8d, 0x83, 0x75, 0x8c, 0xe8, 0xf1, 0x7e, 0x75, 0x8a, 0xa0, 0xf0, 0x75, 
+0x91, 0xc3, 0xf5, 0x91, 0xf1, 0xee, 0xf1, 0xee, 0x80, 0xef, 0xe4, 0x75, 0x1c, 0x88, 0x75, 0x1b, 
+0x13, 0xf5, 0x1a, 0xf5, 0x19, 0x78, 0xa5, 0xe6, 0x60, 0x2b, 0xaf, 0x1c, 0xae, 0x1b, 0xad, 0x1a, 
+0xac, 0x19, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0x1d, 0xf1, 0x7e, 0x75, 0x91, 0xc1, 0xf5, 0x91, 0xef, 
+0x24, 0xff, 0xf5, 0x1c, 0xee, 0x34, 0xff, 0xf5, 0x1b, 0xed, 0x34, 0xff, 0xf5, 0x1a, 0xec, 0x34, 
+0xff, 0xf5, 0x19, 0x80, 0xd0, 0x22, 0xf0, 0x85, 0x0e, 0x82, 0x85, 0x0d, 0x83, 0x22, 0x75, 0xf0, 
+0x20, 0xa4, 0x24, 0x08, 0xff, 0xe4, 0x35, 0xf0, 0x44, 0x80, 0xf5, 0x8f, 0x8f, 0x8e, 0x75, 0x8a, 
+0xa0, 0xe4, 0x90, 0x00, 0x3a, 0xf0, 0x22, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x62, 0x22, 0xe4, 0xf5, 
+0x1e, 0xaa, 0x0d, 0xa9, 0x0e, 0x7b, 0xff, 0x75, 0x22, 0x01, 0x75, 0x23, 0x00, 0x75, 0x24, 0x31, 
+0x12, 0x1b, 0x28, 0xf1, 0x67, 0xe4, 0x93, 0xf4, 0x60, 0x0f, 0x90, 0x00, 0x31, 0x12, 0x35, 0x1a, 
+0x40, 0x04, 0xf1, 0xe6, 0x40, 0x03, 0x75, 0x1e, 0x01, 0xf1, 0x67, 0x74, 0x01, 0x93, 0xf4, 0x60, 
+0x0f, 0x90, 0x00, 0x33, 0x12, 0x35, 0x1a, 0x40, 0x04, 0xf1, 0xe6, 0x40, 0x03, 0x75, 0x1e, 0x01, 
+0x78, 0x60, 0x7c, 0x01, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x00, 0x79, 0x31, 0x7e, 0x00, 0x7f, 0x04, 
+0x12, 0x08, 0xc2, 0xaf, 0x1e, 0x22, 0xd3, 0xef, 0x94, 0xb8, 0xee, 0x94, 0x0b, 0x22, 0x75, 0x8a, 
+0xa0, 0xf0, 0x75, 0x8a, 0xa0, 0xf0, 0x22, 0x7c, 0x00, 0x7d, 0xb0, 0x7f, 0x15, 0x12, 0x33, 0x18, 
+0x90, 0xff, 0x10, 0xe0, 0x44, 0x18, 0xf0, 0x7e, 0x01, 0x7f, 0x00, 0x7d, 0x00, 0x7b, 0x01, 0x7a, 
+0x00, 0x79, 0xb0, 0x12, 0x0c, 0xd9, 0x51, 0xd5, 0x7d, 0x03, 0x7f, 0x12, 0x12, 0x28, 0x53, 0x90, 
+0xff, 0x1b, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0xff, 0x14, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x57, 
+0x74, 0xb6, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0x04, 0xf0, 0xe4, 0x90, 0x01, 0x9c, 0xf0, 0xa3, 0x04, 
+0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x06, 0xf0, 0x90, 0x01, 0xa4, 0x74, 0x04, 0xf0, 0x90, 0x01, 0xa9, 
+0x74, 0x02, 0xf0, 0xa3, 0x74, 0x60, 0xf0, 0xa3, 0x74, 0x2d, 0xf0, 0xa3, 0x74, 0x32, 0xf0, 0xa3, 
+0x74, 0x01, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x9b, 0x74, 0x64, 0xf0, 0x90, 0x01, 0x9a, 0x74, 0x03, 
+0xf0, 0xe4, 0x78, 0xb0, 0xf6, 0x11, 0x81, 0x78, 0xaf, 0x76, 0x01, 0xe4, 0x90, 0x00, 0xaf, 0xf0, 
+0x22, 0x90, 0x01, 0xad, 0xe0, 0xff, 0x30, 0xe0, 0x05, 0x43, 0x90, 0x10, 0x80, 0x03, 0x53, 0x90, 
+0xef, 0xef, 0x90, 0xff, 0x10, 0x30, 0xe1, 0x06, 0xe0, 0x54, 0xe7, 0xf0, 0x80, 0x04, 0xe0, 0x44, 
+0x18, 0xf0, 0x90, 0x01, 0xad, 0xe0, 0x30, 0xe2, 0x02, 0x51, 0xdd, 0x22, 0x8b, 0x1e, 0x8a, 0x1f, 
+0x89, 0x20, 0x8d, 0x21, 0x90, 0x01, 0xaa, 0xe0, 0xf5, 0x22, 0xe4, 0xf5, 0x23, 0x85, 0x21, 0x21, 
+0x51, 0xd5, 0x12, 0x1f, 0xea, 0xff, 0x7e, 0x00, 0x60, 0x02, 0x7e, 0x01, 0x90, 0x00, 0xb2, 0xee, 
+0xf0, 0x75, 0x24, 0x01, 0x75, 0x25, 0x00, 0x75, 0x26, 0xb3, 0xef, 0x60, 0x10, 0x51, 0x44, 0xab, 
+0x24, 0xaa, 0x25, 0xa9, 0x26, 0x74, 0x10, 0x75, 0xf0, 0x00, 0x12, 0x0a, 0xc5, 0x7e, 0x00, 0x7f, 
+0x17, 0x7d, 0xff, 0x7b, 0x01, 0x7a, 0x00, 0x79, 0xb9, 0x12, 0x0c, 0xd9, 0x90, 0x00, 0xb2, 0xe0, 
+0xff, 0x78, 0xb0, 0xe6, 0xfe, 0x6f, 0x60, 0x24, 0xa3, 0xe0, 0x54, 0x3f, 0xf0, 0xee, 0x60, 0x06, 
+0xe0, 0x44, 0x40, 0xf0, 0x80, 0x0a, 0x90, 0x00, 0xb3, 0xe0, 0xf0, 0xe4, 0x90, 0x00, 0xb1, 0xf0, 
+0x90, 0x00, 0xb2, 0xe0, 0x78, 0xb0, 0xf6, 0x75, 0x23, 0x01, 0x80, 0x0d, 0xee, 0x60, 0x0a, 0x90, 
+0x00, 0xb3, 0xe0, 0x54, 0x3f, 0xf0, 0x44, 0x80, 0xf0, 0xe5, 0x22, 0x20, 0xe7, 0x1c, 0x30, 0xe6, 
+0x07, 0x51, 0x3d, 0x12, 0x1f, 0xea, 0x70, 0x12, 0xe5, 0x22, 0x30, 0xe5, 0x04, 0xe5, 0x23, 0x70, 
+0x09, 0xe5, 0x22, 0x30, 0xe4, 0x0b, 0xe5, 0x21, 0x60, 0x07, 0x90, 0x01, 0x9d, 0xe0, 0xff, 0x51, 
+0x97, 0x90, 0x01, 0xad, 0xe0, 0x78, 0xaf, 0x66, 0x60, 0x07, 0x11, 0x81, 0x90, 0x01, 0xad, 0xe0, 
+0xf6, 0x90, 0x00, 0xaf, 0xe0, 0x70, 0x02, 0x41, 0x3c, 0xe5, 0x21, 0x60, 0x13, 0x51, 0x3d, 0xe4, 
+0xf5, 0xf0, 0x12, 0x0a, 0xc5, 0x51, 0x3d, 0x90, 0x00, 0x02, 0xe4, 0xf5, 0xf0, 0x12, 0x0a, 0xe4, 
+0x75, 0x2b, 0x30, 0xaf, 0x2b, 0x05, 0x2b, 0x74, 0xb0, 0x2f, 0x51, 0x8f, 0x74, 0x30, 0xf0, 0x51, 
+0x8b, 0xe5, 0x21, 0xf0, 0x05, 0x2b, 0x51, 0x3d, 0x12, 0x1f, 0xea, 0x7f, 0x00, 0x60, 0x02, 0x7f, 
+0x01, 0x51, 0x8b, 0xef, 0xf0, 0x90, 0x00, 0x0a, 0x12, 0x09, 0x01, 0x60, 0x05, 0x51, 0x8b, 0xe0, 
+0x04, 0xf0, 0x75, 0x24, 0x01, 0x75, 0x25, 0x00, 0x75, 0x26, 0xe3, 0x51, 0x44, 0x51, 0x3d, 0x90, 
+0x00, 0x06, 0x51, 0x6f, 0x51, 0x3d, 0x90, 0x00, 0x08, 0x51, 0x6f, 0x90, 0x00, 0xf0, 0x74, 0x40, 
+0xf0, 0x90, 0x01, 0x10, 0x74, 0x60, 0xf0, 0x90, 0x01, 0x30, 0x74, 0x80, 0xf0, 0x75, 0x24, 0x01, 
+0x75, 0x25, 0x00, 0x75, 0x26, 0xf1, 0x75, 0x27, 0x01, 0x75, 0x28, 0x01, 0x75, 0x29, 0x11, 0x75, 
+0x2b, 0x81, 0xe4, 0xf5, 0x2a, 0xaf, 0x2a, 0x12, 0x1f, 0xe6, 0x51, 0x75, 0xaf, 0x2a, 0x12, 0x2b, 
+0x63, 0xab, 0x27, 0xe5, 0x29, 0xf9, 0x24, 0x02, 0xf5, 0x29, 0xe5, 0x28, 0xfa, 0x34, 0x00, 0xf5, 
+0x28, 0x51, 0x85, 0xaf, 0x2a, 0x12, 0x00, 0x03, 0xae, 0x2b, 0x05, 0x2b, 0x74, 0xb0, 0x2e, 0x51, 
+0x8f, 0xef, 0xf0, 0x05, 0x2a, 0xe5, 0x2a, 0xc3, 0x94, 0x10, 0x40, 0xc9, 0x22, 0xab, 0x1e, 0xaa, 
+0x1f, 0xa9, 0x20, 0x22, 0xab, 0x1e, 0xaa, 0x1f, 0xa9, 0x20, 0x12, 0x0a, 0x15, 0xff, 0xae, 0xf0, 
+0xab, 0x24, 0xe5, 0x26, 0xf9, 0x24, 0x02, 0xf5, 0x26, 0xe5, 0x25, 0xfa, 0x34, 0x00, 0xf5, 0x25, 
+0xee, 0x8f, 0xf0, 0x12, 0x0a, 0xc5, 0xab, 0x1e, 0xaa, 0x1f, 0xa9, 0x20, 0x90, 0x00, 0x02, 0x12, 
+0x0a, 0x40, 0xff, 0xae, 0xf0, 0xab, 0x24, 0xe5, 0x26, 0xf9, 0x24, 0x02, 0xf5, 0x26, 0xe5, 0x25, 
+0xfa, 0x34, 0x00, 0xf5, 0x25, 0xee, 0x8f, 0xf0, 0x02, 0x0a, 0xc5, 0x74, 0xb0, 0x25, 0x2b, 0xf5, 
+0x82, 0xe4, 0x34, 0x00, 0xf5, 0x83, 0x22, 0xac, 0x07, 0x90, 0x01, 0xad, 0xe0, 0xfd, 0x30, 0xe2, 
+0x0a, 0x90, 0xff, 0x19, 0xe0, 0x54, 0xfb, 0xf0, 0x43, 0xac, 0x08, 0x90, 0xff, 0x18, 0xe0, 0x54, 
+0xfb, 0xf0, 0xec, 0x12, 0x2f, 0x6e, 0x75, 0x8a, 0x0a, 0x75, 0x91, 0xc1, 0xf5, 0x91, 0x51, 0xd5, 
+0x90, 0x01, 0x9e, 0xe0, 0x12, 0x2f, 0x6e, 0x75, 0x8a, 0x0a, 0x78, 0xa5, 0x76, 0x01, 0xed, 0x30, 
+0xe2, 0x02, 0x51, 0xdd, 0x22, 0x90, 0xff, 0x18, 0xe0, 0x44, 0x04, 0xf0, 0x22, 0x90, 0xff, 0x19, 
+0xe0, 0x44, 0x04, 0xf0, 0x53, 0xac, 0xf7, 0x22, 0xef, 0x60, 0x0e, 0x43, 0xac, 0x10, 0x71, 0x05, 
+0x44, 0x18, 0xf0, 0xe4, 0xf5, 0xa6, 0xf5, 0xa2, 0x22, 0x11, 0x81, 0x75, 0xa6, 0x68, 0x75, 0xa2, 
+0xc1, 0x53, 0xac, 0xef, 0x22, 0x90, 0xff, 0x12, 0xe0, 0x54, 0xe7, 0xf0, 0x90, 0xff, 0x11, 0xe0, 
+0x44, 0x18, 0xf0, 0x90, 0xff, 0x10, 0xe0, 0x22, 0xab, 0x07, 0x8c, 0x56, 0x8d, 0x57, 0x71, 0x05, 
+0x54, 0xe7, 0xf0, 0x90, 0xff, 0x14, 0xe0, 0x44, 0x18, 0xf0, 0x90, 0xff, 0x1b, 0xe0, 0x44, 0x18, 
+0xf0, 0xe4, 0x90, 0x00, 0x39, 0xf0, 0x53, 0xac, 0xef, 0xf5, 0xa3, 0xeb, 0x44, 0x80, 0xf5, 0xa1, 
+0x75, 0xa6, 0x68, 0x75, 0xa2, 0xc1, 0x71, 0x53, 0xf5, 0xd5, 0x8f, 0xd4, 0x75, 0xd2, 0xff, 0x75, 
+0xd1, 0x5a, 0x22, 0xe0, 0x25, 0x57, 0xff, 0xe4, 0x35, 0x56, 0xf5, 0xd7, 0x8f, 0xd6, 0x22, 0xc0, 
+0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x85, 0xa3, 0x18, 0xaf, 0xa6, 0x75, 
+0xa3, 0x08, 0xef, 0x30, 0xe4, 0x0b, 0x90, 0x00, 0x39, 0x71, 0x53, 0x75, 0xd2, 0xff, 0x75, 0xd1, 
+0x5a, 0xe5, 0x18, 0x30, 0xe3, 0x16, 0xe5, 0xa6, 0x20, 0xe0, 0x0c, 0x75, 0xd2, 0x01, 0x75, 0xd5, 
+0x00, 0x75, 0xd4, 0x39, 0x75, 0xd1, 0x55, 0x75, 0xa3, 0x00, 0x80, 0x2d, 0xe5, 0x18, 0x30, 0xe0, 
+0x28, 0x90, 0x00, 0x39, 0xe0, 0xff, 0x25, 0x57, 0xfd, 0xe4, 0x35, 0x56, 0xf5, 0xd5, 0x8d, 0xd4, 
+0x75, 0xd2, 0xff, 0xef, 0xc3, 0x94, 0xc0, 0x40, 0x10, 0x75, 0xd1, 0x55, 0x90, 0x00, 0x39, 0xe0, 
+0xb4, 0xfe, 0x06, 0x90, 0x00, 0xaf, 0x74, 0x01, 0xf0, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 
+0xe0, 0x32, 0x75, 0x91, 0xcc, 0x75, 0x91, 0x00, 0x32, 0x12, 0x2f, 0xf7, 0x78, 0xa6, 0x76, 0x00, 
+0x08, 0x76, 0x28, 0x90, 0x00, 0x38, 0x74, 0x04, 0xf0, 0x22, 0x8b, 0x22, 0x8a, 0x23, 0x89, 0x24, 
+0x90, 0x01, 0x9a, 0xe0, 0x30, 0xe1, 0x76, 0xe4, 0xf5, 0x28, 0xf5, 0x29, 0x12, 0x2f, 0x67, 0x74, 
+0x02, 0x93, 0xff, 0xe5, 0x29, 0xc3, 0x9f, 0x50, 0x36, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x75, 
+0xf0, 0x02, 0xe5, 0x29, 0xa4, 0xf5, 0x82, 0x85, 0xf0, 0x83, 0x12, 0x0a, 0x40, 0xfb, 0xaa, 0xf0, 
+0x12, 0x2f, 0x67, 0x74, 0x07, 0x93, 0xfe, 0x74, 0x08, 0x93, 0xff, 0x7c, 0x00, 0x7d, 0x03, 0x12, 
+0x09, 0x62, 0xd3, 0xeb, 0x9f, 0xea, 0x9e, 0x40, 0x02, 0x05, 0x28, 0x05, 0x29, 0x80, 0xbd, 0x12, 
+0x2f, 0x67, 0x74, 0x02, 0x93, 0x75, 0xf0, 0x04, 0xa4, 0xff, 0xae, 0xf0, 0x7c, 0x00, 0x7d, 0x05, 
+0x12, 0x09, 0x74, 0xe5, 0x28, 0xc3, 0x9f, 0x40, 0x14, 0x91, 0x95, 0x74, 0xff, 0x12, 0x09, 0x2e, 
+0x91, 0x95, 0x90, 0x00, 0x01, 0x12, 0x09, 0x40, 0xe4, 0x90, 0x00, 0x38, 0xf0, 0x91, 0x95, 0x12, 
+0x08, 0xe8, 0xb4, 0x04, 0x1f, 0xab, 0x25, 0xaa, 0x26, 0xa9, 0x27, 0x90, 0x00, 0x10, 0x12, 0x0a, 
+0x40, 0xff, 0xae, 0xf0, 0x7c, 0x00, 0x7d, 0x06, 0x12, 0x09, 0x74, 0x90, 0x00, 0x10, 0xee, 0x8f, 
+0xf0, 0x12, 0x0a, 0x78, 0x22, 0xab, 0x22, 0xaa, 0x23, 0xa9, 0x24, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 
+0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x02, 0xc0, 
+0x03, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0x75, 0x89, 0x80, 0x90, 0x00, 0x3a, 0xe0, 
+0xc3, 0x94, 0x0a, 0x50, 0x06, 0xe0, 0x04, 0xf0, 0x75, 0x8a, 0x0a, 0x78, 0xa5, 0xe6, 0x60, 0x01, 
+0x16, 0x12, 0x2b, 0x0b, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04, 0xd0, 0x03, 0xd0, 0x02, 
+0xd0, 0x01, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xef, 
+0x24, 0xfc, 0x70, 0x05, 0x7e, 0x2c, 0x7f, 0x04, 0x22, 0xe4, 0xfe, 0xff, 0x22, 0xef, 0x75, 0xf0, 
+0x64, 0xa4, 0xff, 0xae, 0xf0, 0x78, 0xa8, 0x08, 0x06, 0xe6, 0x18, 0x22, 0xaf, 0x0e, 0xae, 0x0d, 
+0x12, 0x25, 0x91, 0xaf, 0x0e, 0xae, 0x0d, 0x02, 0x29, 0xa1, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 
+0x94, 0x78, 0xee, 0x94, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xb6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa8, 
+0x43, 0x53, 0x57, 0x5f, 0x32, 0x32, 0x31, 0x31, 0x35, 0x32, 0x37, 0x5f, 0x43, 0x53, 0x54, 0x38, 
+0x31, 0x36, 0x44, 0x5f, 0x43, 0x4f, 0x42, 0x5f, 0x5a, 0x54, 0x5f, 0x59, 0x41, 0x54, 0x5f, 0x4b, 
+0x35, 0x5f, 0x47, 0x31, 0x5f, 0x4a, 0x4c, 0x5f, 0x35, 0x35, 0x30, 0x32, 0x38, 0x2e, 0x68, 0x65, 
+0x78, 
+]
+
+#endif /*CAPACITIVE_HYNITRON_CST816D_UPDATE_H__*/
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/code.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/code.py
new file mode 100644 (file)
index 0000000..6b81d64
--- /dev/null
@@ -0,0 +1,296 @@
+from machine import LCD, Pin
+import lvgl as lv
+from tp import cst816
+
+test = (
+
+    0, 0, 0x11,
+    2, 0, 120,
+
+    0, 1, 0x36,
+    1, 1, 0x00,
+
+    0, 1, 0x35,
+    1, 1, 0x01,
+
+    0, 1, 0x3a,
+    1, 1, 0x05,
+
+    0, 5, 0xB2,
+    1, 1, 0x0c,
+    1, 1, 0x0c,
+    1, 1, 0x00,
+    1, 1, 0x33,
+    1, 1, 0x33,
+
+    0, 1, 0xB7,
+    1, 1, 0x77,
+
+    0, 1, 0xBB,
+    1, 1, 0x2c,
+
+    0, 1, 0xC0,
+    1, 1, 0x2C,
+
+    0, 1, 0xC2,
+    1, 1, 0x01,
+
+    0, 1, 0xC3,
+    1, 1, 0x21,
+
+    0, 1, 0xC4,
+    1, 1, 0x20,
+
+    0, 1, 0xC6,
+    1, 1, 0x10,
+
+    0, 2, 0xD0,
+    1, 1, 0xA4,
+    1, 1, 0xA1,
+
+    0, 14, 0xE0,
+    1, 1, 0xd0,
+    1, 1, 0x03,
+    1, 1, 0x08,
+    1, 1, 0x0e,
+    1, 1, 0x12,
+    1, 1, 0x2d,
+    1, 1, 0x42,
+    1, 1, 0x45,
+    1, 1, 0x53,
+    1, 1, 0x29,
+    1, 1, 0x16,
+    1, 1, 0x15,
+    1, 1, 0x22,
+    1, 1, 0x24,
+
+    0, 14, 0xE1,
+    1, 1, 0xd0,
+    1, 1, 0x03,
+    1, 1, 0x08,
+    1, 1, 0x0e,
+    1, 1, 0x13,
+    1, 1, 0x2c,
+    1, 1, 0x42,
+    1, 1, 0x54,
+    1, 1, 0x50,
+    1, 1, 0x2c,
+    1, 1, 0x16,
+    1, 1, 0x16,
+    1, 1, 0x20,
+    1, 1, 0x27,
+    # 0, 0, 0x11,
+    0, 0, 0x21,
+    0, 0, 0x29,
+    # 0, 1, 0xe7,
+    # 1, 1, 0x11,
+)
+
+XSTART_H = 0xf0
+XSTART_L = 0xf1
+YSTART_H = 0xf2
+YSTART_L = 0xf3
+XEND_H = 0xE0
+XEND_L = 0xE1
+YEND_H = 0xE2
+YEND_L = 0xE3
+
+XSTART = 0xD0
+XEND = 0xD1
+YSTART = 0xD2
+YEND = 0xD3
+
+lcd = LCD()
+
+test1 = bytearray(test)
+
+test2 = (
+    0, 4, 0x2a,
+    1, 1, XSTART_H,
+    1, 1, XSTART_L,
+    1, 1, XEND_H,
+    1, 1, XEND_L,
+    0, 4, 0x2b,
+    1, 1, YSTART_H,
+    1, 1, YSTART_L,
+    1, 1, YEND_H,
+    1, 1, YEND_L,
+    0, 0, 0x2c,
+)
+test_invalid = bytearray(test2)
+
+test3 = (
+    0, 0, 0x28,
+    2, 0, 120,
+    0, 0, 0x10,
+)
+test_displayoff = bytearray(test3)
+
+test4 = (
+    0, 0, 0x11,
+    2, 0, 120,
+    0, 0, 0x29,
+)
+test_displayon = bytearray(test4)
+
+gpio4 = Pin(Pin.GPIO18, Pin.OUT, Pin.PULL_PU, 0)
+gpio4.write(1)
+lcd.lcd_init(test1, 240, 320, 52000, 1, 4, 0, test_invalid, test_displayon, test_displayoff, None, TESel=True, TEPin=7)
+lcd.lcd_clear(0xf800)
+gpio5 = Pin(Pin.GPIO17, Pin.OUT, Pin.PULL_PU, 0)
+gpio5.write(1)
+
+LCD_SIZE_W = 240
+LCD_SIZE_H = 320
+
+# 初始化lvgl
+lv.init()
+
+# Register SDL display driver.
+disp_buf1 = lv.disp_draw_buf_t()
+buf1_1 = bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+buf1_2 = bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+disp_buf1.init(buf1_1, buf1_2, len(buf1_1))
+disp_drv = lv.disp_drv_t()
+disp_drv.init()
+disp_drv.draw_buf = disp_buf1
+disp_drv.flush_cb = lcd.lcd_write
+disp_drv.hor_res = LCD_SIZE_W
+disp_drv.ver_res = LCD_SIZE_H
+disp_drv.register()
+
+# CST816初始化
+tp_cst816 = cst816(i2c_no = 2,irq=33,reset=32)
+tp_cst816.activate()
+tp_cst816.init()
+print("cst816 init...")
+# LVGL触摸注册
+indev_drv = lv.indev_drv_t()
+indev_drv.init()
+indev_drv.type = lv.INDEV_TYPE.POINTER
+indev_drv.read_cb = tp_cst816.read
+indev_drv.register()
+gpio6 = Pin(Pin.GPIO33, Pin.OUT, Pin.PULL_PU, 0)
+gpio6.write(0)
+
+
+# 启动lvgv线程
+lv.tick_inc(5)
+lv.task_handler()
+print("lvgl init complete")
+
+# 界面风格1
+style_bar = lv.style_t()
+style_bar.init()
+style_bar.set_border_width(0)
+style_bar.set_radius(0)
+style_bar.set_pad_top(0)
+style_bar.set_pad_bottom(0)
+style_bar.set_pad_left(0)
+style_bar.set_pad_right(0)
+
+screen = lv.obj()
+
+# Code 39字符集和对应的二进制码
+code_39_dict = {'0': '0001101000', '1': '1001000010', '2': '0011000010', '3': '1011000000', '4': '0001100010',
+                '5': '1001100000', '6': '0011100000', '7': '0001001010', '8': '1001001000', '9': '0011001000',
+                'A': '1000010010', 'B': '0010010010', 'C': '1010010000', 'D': '0000110010', 'E': '1000110000',
+                'F': '0010110000', 'G': '0000011010', 'H': '1000011000', 'I': '0010011000', 'J': '0000111000',
+                'K': '1000000110', 'L': '0010000110', 'M': '1010000100', 'N': '0000100110', 'O': '1000100100',
+                'P': '0010100100', 'Q': '0000001110', 'R': '1000001100', 'S': '0010001100', 'T': '0000101100',
+                'U': '1100000010', 'V': '0110000010', 'W': '1110000000', 'X': '0100100010', 'Y': '1100100000',
+                'Z': '0110100000', '-': '0100001010', '.': '1100001000', ' ': '0110001000', '*': '0100101000',  
+                '$': '0101010000', '/': '0101000100', '+': '0100010100', '%': '0001010100'}
+
+# Code 39条形码的起始和结束符
+code_39_start = '0100101000'
+code_39_end = '010010100'   #结束符结尾'0'去掉
+
+# Code 39条形码的宽度系数
+code_39_narrow = 1
+code_39_wide = 3
+
+
+def code_39_encode(data):
+    """将数据编码为Code 39条形码对应的二进制码"""
+    result = ''
+    for char in data:
+        try:
+            result += code_39_dict[char]
+        except Exception as e:
+            print("your data contains illegal code!")
+            return None
+    return result
+
+
+def code_39_generate_binary(data):
+    """生成Code 39条形码对应的二进制码"""
+    encoded_data = code_39_encode(data)
+    if encoded_data:
+        # 添加起始和结束符
+        encoded_data = code_39_start + encoded_data + code_39_end
+        return encoded_data
+    else:
+        return None
+
+
+def code_39_generate_barcode(screen, data, width=180, height=80):
+    """生成Code 39条形码"""
+    left_curr_line = 0
+
+    # 删除上次的container
+    old_container = screen.get_child(-1)
+    if old_container:
+        old_container.delete()
+
+    # 生成二进制码
+    binary_data = code_39_generate_binary(data)
+    if not binary_data:
+        return
+    print("binary_data is ",binary_data)
+
+    # 在LVGL中创建一个容器对象
+    container = lv.obj(screen)
+    # container.set_size(width, height)
+    container.add_style(style_bar,lv.PART.MAIN | lv.STATE.DEFAULT)
+    container.center()
+
+    # 计算每个条的宽度
+    bar_width = width // (len(binary_data))
+
+    # 按照二进制码中的1和0,分别创建LVGL矩形对象
+    for i in range(len(binary_data)):
+        if i % 2 == 0:
+            # 创建一个黑色矩形
+            bar = lv.obj(container)
+            bar.add_style(style_bar, lv.PART.MAIN | lv.STATE.DEFAULT)
+            if binary_data[i] == '1':
+                real_width = bar_width * code_39_wide
+                bar.set_size(real_width, height)
+            else:
+                real_width = bar_width * code_39_narrow
+                bar.set_size(real_width, height)
+            bar.align(lv.ALIGN.TOP_LEFT, left_curr_line, 0)
+            bar.set_style_bg_color(lv.color_make(0x00, 0x00, 0x00), lv.PART.MAIN | lv.STATE.DEFAULT)
+            left_curr_line += real_width
+        else:
+            # 创建一个白色矩形
+            bar = lv.obj(container)
+            bar.add_style(style_bar, lv.PART.MAIN | lv.STATE.DEFAULT)
+            if binary_data[i] == '1':
+                real_width = bar_width * code_39_wide
+                bar.set_size(real_width, height)
+            else:
+                real_width = bar_width * code_39_narrow
+                bar.set_size(real_width, height)
+            bar.align(lv.ALIGN.TOP_LEFT, left_curr_line, 0)
+            bar.set_style_bg_color(lv.color_make(0xFF, 0xFF, 0xFF), lv.PART.MAIN | lv.STATE.DEFAULT)
+            left_curr_line += real_width
+
+    container.set_size(left_curr_line, height)
+
+
+if __name__ == "__main__":
+    code_39_generate_barcode(screen,"A123 321")
+    lv.scr_load(screen)
+
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/common.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/common.py
new file mode 100644 (file)
index 0000000..04489e7
--- /dev/null
@@ -0,0 +1,145 @@
+import _thread
+import utime
+from event_message import Event, EventManager
+
+
+class Lock(object):
+
+    def __init__(self):
+        self.lock = _thread.allocate_lock()
+
+    def __enter__(self, *args, **kwargs):
+        self.lock.acquire()
+
+    def __exit__(self, *args, **kwargs):
+        self.lock.release()
+
+
+class LOG_LV(object):
+    """日志等级"""
+    DEBUG = "DEBUG"
+    INFO = "INFO"
+    WARNING = "WARNING"
+    ERROR = "ERROR"
+    CRITICAL = "CRITICAL"
+
+
+class Abstract(object):
+    def post_processor_after_instantiation(self, *args, **kwargs):
+        """实例化后调用"""
+        pass
+
+    def post_processor_before_initialization(self, *args, **kwargs):
+        """初始化之前调用"""
+        pass
+
+    def initialization(self, *args, **kwargs):
+        """初始化load"""
+        pass
+
+    def post_processor_after_initialization(self, *args, **kwargs):
+        """初始化之后调用"""
+        pass
+
+
+class AbstractOutput(object):
+    def open(self):
+        pass
+
+    def output(self, message, **kwargs):
+        pass
+
+    def close(self):
+        pass
+
+
+class PrintLogOutput(AbstractOutput):
+    def output(self, message, **kwargs):
+        fmt = "{} [ {} ] {} {}"
+        print(fmt.format(*message))
+
+
+class LogService(Abstract):
+    """
+        default log is async queue
+        you can set
+    """
+    INSTANCE = None
+    REPORTER = PrintLogOutput()
+    LEVEL = LOG_LV.DEBUG
+    MODE = 1
+    LEVEL_MAP = {
+        LOG_LV.DEBUG: 0,
+        LOG_LV.INFO: 1,
+        LOG_LV.WARNING: 2,
+        LOG_LV.ERROR: 3,
+        LOG_LV.CRITICAL: 4
+    }
+
+    def __init__(self):
+        self.__event = Event(__name__)
+        self.__em = EventManager()
+        self.__em.register_event(self.__event)
+
+    @classmethod
+    def create(cls):
+        if not cls.INSTANCE:
+            cls.INSTANCE = LogService()
+            cls.INSTANCE.start()
+        return cls.INSTANCE
+
+    def log_send(self, tag, level, msg, mode):
+        if self.MODE:
+            mode = self.MODE
+        if self.LEVEL_MAP[level] >= self.LEVEL_MAP.get(self.LEVEL, 0):
+            output_format = "{ascdate} {asctime}"
+            rt = utime.localtime()
+            d_f = "{0:02}"
+            send_msg = (output_format.format(
+                ascdate=str(rt[0]) + "-" + d_f.format(rt[1]) + "-" + d_f.format(rt[2])
+                , asctime=d_f.format(rt[3]) + ":" + d_f.format(rt[4]) + ":" + d_f.format(rt[5])
+            ), tag, level, msg)
+            # self.REPORTER.output(send_msg)
+            print("{} [ {} ] {} {}".format(*send_msg))
+            # self.__event.post(send_msg)
+
+    def output(self, *args, **kwargs):
+        emo = kwargs.get("event_message")
+        self.REPORTER.output(emo.msg)
+
+    def start(self):
+        self.__event.add_handler(self.output)
+        self.__em.start()
+
+
+class LogAdapter(object):
+    """
+        log adapter mode
+        mode used : adapter proxy single LogService
+    """
+
+    def __init__(self, tag, enable=1):
+        self.log_service = LogService.create()
+        self.tag = tag
+        self.enable = enable
+        self.mode = 1
+
+    def critical(self, msg):
+        if self.enable:
+            self.log_service.log_send(self.tag, LOG_LV.CRITICAL, msg, self.mode)
+
+    def debug(self, msg):
+        if self.enable:
+            self.log_service.log_send(self.tag, LOG_LV.DEBUG, msg, self.mode)
+
+    def info(self, msg):
+        if self.enable:
+            self.log_service.log_send(self.tag, LOG_LV.INFO, msg, self.mode)
+
+    def warning(self, msg):
+        if self.enable:
+            self.log_service.log_send(self.tag, LOG_LV.WARNING, msg, self.mode)
+
+    def error(self, msg):
+        if self.enable:
+            self.log_service.log_send(self.tag, LOG_LV.ERROR, msg, self.mode)
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/constants.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/constants.py
new file mode 100644 (file)
index 0000000..23eb744
--- /dev/null
@@ -0,0 +1,106 @@
+class PROTOCOL:
+    LK_SEND = "LK_SEND"
+    LK_RECV = "LK_RECV"
+
+    PING_SEND = "PING_SEND"
+    PING_RECV = "PING_RECV"
+
+    KA_SEND = "KA_SEND"
+    KA_RECV = "KA_RECV"
+
+    UD_SEND = "UD_SEND"
+    UD_RECV = "UD_RECV"
+
+    CR_SEND = "CR_SEND"
+    CR_RECV = "CR_RECV"
+
+    FIND_SEND = "FIND_SEND"
+    FIND_RECV = "FIND_RECV"
+
+    POWEROFF_SEND = "POWEROFF_SEND"
+    POWEROFF_RECV = "POWEROFF_RECV"
+
+    PHL_SEND = "PHL_SEND"
+    PHL_RECV = "PHL_RECV"
+
+    TK_SEND = "TK_SEND"
+    TK_RECV = "TK_RECV"
+
+    MESSAGE_SEND = "MESSAGE_SEND"
+    MESSAGE_RECV = "MESSAGE_RECV"
+
+    WT_SEND = "WT_SEND"
+    WT_RECV = "WT_RECV"
+
+    REMIND_SEND = "REMIND_SEND"
+    REMIND_RECV = "REMIND_RECV"
+
+    HRTSTART_SEND = "hrtstart_SEND"
+    HRTSTART_RECV = "hrtstart_RECV"
+
+    HEART_SEND = "heart_SEND"
+    HEART_RECV = "heart_RECV"
+    
+    OXYGEN_SEND = "oxygen_SEND"
+    OXYGEN_RECV = "oxygen_RECV"
+
+    OXSTART_SEND = "oxstart_SEND"
+    OXSTART_RECV = "oxstart_RECV"
+
+    TEMP_SEND = "temp_SEND"
+    TEMP_RECV = "temp_RECV"
+
+    DLT_SEND = "DLT_SEND"
+    DLT_RECV = "DLT_RECV"
+
+    UPLOAD_SEND = "UPLOAD_SEND"
+    UPLOAD_RECV = "UPLOAD_RECV"
+
+    CENTER_SEND = "CENTER_SEND"
+    CENTER_RECV = "CENTER_RECV"
+
+    MONITOR_SEND = "MONITOR_SEND"
+    MONITOR_RECV = "MONITOR_RECV"
+
+    SOS_SEND = "SOS_SEND"
+    SOS_RECV = "SOS_RECV"
+
+class EVENT:
+    CHANNEL_SOCKET_SEND = "CHANNEL_SOCKET_SEND"
+    START_LOCATION = "START_LOCATION" 
+    READ_LOCATION = "READ_LOCATION"  
+    CLOSE_LOCATION = "CLOSE_LOCATION"
+    GPSOPEN = "GPSOPEN"
+    GPSCLOSE = "GPSCLOSE"
+    GPSINFO = "GPSINFO"
+    WIFISCANOPEN = "WIFISCANOPEN"
+    WIFIINFO = "WIFIINFO"
+
+    GET_KEY = "GET_KEY"
+    SET_KEY = "SET_KEY"
+    GET_IMEI = "GET_IMEI"
+    GET_CID = "GET_CID"
+    SET_CID = "SET_CID"
+    GET_IMSI = "GET_IMSI"
+    GET_PASSWORD = "GET_PASSWORD"
+    SET_PASSWORD = "SET_PASSWORD"
+    GET_BATTERY = "GET_BATTERY"
+    PERSISTENT_CONFIG_GET = "PERSISTENT_CONFIG_GET"
+    PERSISTENT_CONFIG_STORE = "PERSISTENT_CONFIG_STORE"
+    SET_PING = "SET_PING"
+    GET_PING = "GET_PING"
+    SET_CONNECT = "SET_CONNECT"
+    GET_CONNECT = "GET_CONNECT"
+    GET_STEP = "GET_STEP"
+    PUSH_STEP = "PUSH_STEP"
+    SYSTEM_SLEEP = "SYSTEM_SLEEP"
+    SYSTEM_UP = "SYSTEM_UP"
+    START_HEART = "START_HEART" 
+    GET_HEART = "GET_HEART"
+    STOP_HEART = "STOP_HEART"
+    START_TEMP = "START_TEMP"
+    STOP_TEMP = "STOP_TEMP"
+    GET_TEMP = "GET_TEMP"
+    START_BLOOD_OXYGEN = "STARTT_BLOOD_OXYGEN" 
+    GET_BLOOD_OXYGEN = "GET_BLOOD_OXYGEN"
+    STOP_BLOOD_OXYGEN = "STOP_BLOOD_OXYGEN"
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/initTP.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/initTP.py
new file mode 100644 (file)
index 0000000..534ca06
--- /dev/null
@@ -0,0 +1,197 @@
+import log
+from machine import I2C
+import utime
+from machine import Pin
+import uos
+
+# from ext import capacitive_hynitron_cst816d_update_new
+import capacitive_hynitron_cst816d_update
+
+TP_HYN_I2C_UPDATE_WRITE_ADDR = (0x6A<<1)  
+TP_HYN_I2C_UPDATE_READ_ADDR =  ((0x6A<<1)|1)
+PER_LEN = 512
+x = 0
+y = 0
+#---------------------------------------------------------------------
+# cst816d_read_checksum
+#---------------------------------------------------------------------
+def cst816d_read_checksum():
+
+    if -1 == cst816d_enter_bootmode():
+        return -1
+
+    i2c_obj = I2C(I2C.I2C2, I2C.FAST_MODE)
+    cmd = [0]
+
+    if -1 == i2c_obj.write(TP_HYN_I2C_UPDATE_WRITE_ADDR>>1, bytearray([0xa0,0x03]), 2, bytearray(cmd), 1):
+        return -1
+    utime.sleep_ms(500)#这里延时太短会读错checksum
+
+    r_data = bytearray(2)
+    if -1 == i2c_obj.read(TP_HYN_I2C_UPDATE_READ_ADDR>>1, bytearray([0xa0,0x08]), 2, r_data, 2, 0):
+        return -1
+    check_sum = (r_data[1] << 8) | r_data[0]
+    print("check_sum的值为:",check_sum)
+    return check_sum    
+#---------------------------------------------------------------------
+# GPIO_ResetTP
+#---------------------------------------------------------------------
+def GPIO_ResetTP():
+
+    print("GPIO_ResetTP")
+    
+    gpio_power = Pin(Pin.GPIO18, Pin.OUT, Pin.PULL_PU, 0)
+    gpio_power.write(1)
+
+    gpio_reset = Pin(Pin.GPIO32, Pin.OUT, Pin.PULL_PU, 0)
+    gpio_reset.write(0)
+    utime.sleep_ms(10)
+    gpio_reset.write(1)
+    utime.sleep_ms(10)
+
+#---------------------------------------------------------------------
+# cst816d_update
+#---------------------------------------------------------------------
+def cst816d_update(startAddr, length, data):
+    print("cst816d_update")
+    if -1 == cst816d_enter_bootmode():
+        return -1
+
+    sum_len = 0
+    cmd = [0,0]
+    global x
+    while 1:
+        x += 1
+        if sum_len >= length:
+            print("sum_len >= length,退出循环")
+            return
+        a = startAddr&0xFF
+        cmd[0]=a
+        b = startAddr>>8
+        cmd[1]=b
+        i2c_obj = I2C(I2C.I2C2, I2C.FAST_MODE)
+
+        ret = i2c_obj.write(TP_HYN_I2C_UPDATE_WRITE_ADDR>>1, bytearray([0xa0,0x14]), 2, bytearray(cmd), 2)
+        utime.sleep_ms(100)
+
+        ret = i2c_obj.write(TP_HYN_I2C_UPDATE_WRITE_ADDR>>1, bytearray([0xa0,0x18]), 2, bytearray(data), PER_LEN)
+
+        utime.sleep_ms(100)
+
+        cmd[0] = 0xEE
+        ret = i2c_obj.write(TP_HYN_I2C_UPDATE_WRITE_ADDR>>1, bytearray([0xa0,0x04]), 2, bytearray(cmd), 1)
+
+        utime.sleep_ms(100)
+
+        retrycnt = 51
+        for i in range (retrycnt):
+            r_data = bytearray(1)
+            ret = i2c_obj.read(TP_HYN_I2C_UPDATE_READ_ADDR>>1, bytearray([0xa0,0x05]), 2, r_data, 1, 0)
+            utime.sleep_ms(50)
+
+            if r_data[0] == 0x55:
+                print("r_data[0] = 0x55,break")
+                break
+        
+        startAddr = startAddr + PER_LEN
+        del data[0:PER_LEN]
+        sum_len = sum_len + PER_LEN 
+
+#---------------------------------------------------------------------
+# cst816d_enter_bootmode
+#---------------------------------------------------------------------
+def cst816d_enter_bootmode():
+
+    GPIO_ResetTP()
+    i2c_obj = I2C(I2C.I2C2, I2C.FAST_MODE)
+
+    cmd = [0xAB]
+    #进入boot模式
+    retrycnt = 10
+    global y
+    for i in range (retrycnt):
+        y += 1
+        if 0 == i2c_obj.write(TP_HYN_I2C_UPDATE_WRITE_ADDR>>1, bytearray([0xa0,0x01]), 2, bytearray(cmd), 1):
+            utime.sleep_ms(100)
+        else:
+            print("boot模式写命令失败")
+
+        r_data = bytearray(1)
+        if -1 == i2c_obj.read(TP_HYN_I2C_UPDATE_READ_ADDR>>1, bytearray([0xa0,0x03]), 2, r_data, 1, 0):
+            utime.sleep_ms(100)
+        else:
+            if 0xc1 == r_data[0]:
+                utime.sleep_ms(100)
+                return 0
+            else:
+                print("boot模式进入失败")
+    
+    return -1
+#---------------------------------------------------------------------
+# ctp_hynitron_update
+#---------------------------------------------------------------------
+def ctp_hynitron_update():
+
+    # 初始化固件数组和数组长度
+    p_app_bin = []
+    app_bin_len = 0
+
+    #进入boot模式
+    # if -1 == cst816d_enter_bootmode():
+    #     return 
+
+    #  获取固件数组
+    # p_app_bin = capacitive_hynitron_cst816d_update_new.app_bin_816d
+    p_app_bin = capacitive_hynitron_cst816d_update.app_bin_816d
+
+    #  获取固件数组的长度
+    app_bin_len = len(p_app_bin)
+
+    if app_bin_len > 10:
+        startAddr = p_app_bin[1]
+        length = p_app_bin[3]
+        checksum = p_app_bin[5] #a8  78
+
+        startAddr <<= 8; startAddr |= p_app_bin[0]
+        length <<= 8; length |= p_app_bin[2]
+        checksum <<= 8; checksum |= p_app_bin[4] 
+
+        print("startAddr:%x"%startAddr)
+        print("length:%x"%length) 
+        print("checksum:%x"%checksum)   
+
+
+        #检查checksum
+        sum_now = cst816d_read_checksum()
+        if sum_now == -1:
+           print("初始化失败") 
+        elif sum_now != checksum:
+            print("固件包checksum不相同!")
+
+            del p_app_bin[0:6]
+            cst816d_update(startAddr, length, p_app_bin)
+
+            #升级后再次确认checksum
+            if checksum == cst816d_read_checksum():
+                print("固件升级成功!")
+
+        elif  checksum == sum_now:
+            print("固件包checksum相同,退出")
+
+
+#---------------------------------------------------------------------
+# HYN_Initial
+#---------------------------------------------------------------------
+def HYN_Initial():
+
+    #GPIO_ResetTP()
+
+    ctp_hynitron_update() 
+
+    GPIO_ResetTP()
+
+
+
+
+
+
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/lcd.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/lcd.py
new file mode 100644 (file)
index 0000000..9afabe1
--- /dev/null
@@ -0,0 +1,236 @@
+import lvgl as lv
+from machine import LCD, Pin
+from tp import cst816
+import _thread
+import utime
+import EventMesh
+from misc import PWM
+
+    
+init_data = (
+
+    0, 0, 0x11,
+    2, 0, 120, 
+
+    0, 1, 0x36,
+    1, 1, 0x00,
+
+    0, 1, 0x35,
+    1, 1, 0x00,
+
+    0, 1, 0x3a,
+    1, 1, 0x05,
+
+    0, 5, 0xB2,
+    1, 1, 0x0c,
+    1, 1, 0x0c,
+    1, 1, 0x00,
+    1, 1, 0x33,
+    1, 1, 0x33,
+
+    0, 1, 0xB7,
+    1, 1, 0x77,
+
+    0, 1, 0xBB,
+    1, 1, 0x2c,
+    
+    0, 1, 0xC0,
+    1, 1, 0x2C,
+
+    0, 1, 0xC2,
+    1, 1, 0x01,
+    
+    0, 1, 0xC3,
+    1, 1, 0x21,
+
+    0, 1, 0xC4,
+    1, 1, 0x20,
+
+    0, 1, 0xC6,
+    1, 1, 0x10,
+
+    0, 2, 0xD0,
+    1, 1, 0xA4,
+    1, 1, 0xA1,
+
+    0, 14, 0xE0,
+    1, 1, 0xd0,
+    1, 1, 0x03,
+    1, 1, 0x08,            
+    1, 1, 0x0e,
+    1, 1, 0x12,
+    1, 1, 0x2d,
+    1, 1, 0x42,
+    1, 1, 0x45,
+    1, 1, 0x53,
+    1, 1, 0x29,
+    1, 1, 0x16,
+    1, 1, 0x15,
+    1, 1, 0x22,
+    1, 1, 0x24,
+
+    0, 14, 0xE1,
+    1, 1, 0xd0,
+    1, 1, 0x03,
+    1, 1, 0x08,
+    1, 1, 0x0e,
+    1, 1, 0x13,
+    1, 1, 0x2c,
+    1, 1, 0x42,
+    1, 1, 0x54,
+    1, 1, 0x50,
+    1, 1, 0x2c,
+    1, 1, 0x16,
+    1, 1, 0x16,
+    1, 1, 0x20,
+    1, 1, 0x27,
+    #0, 0, 0x11,
+    0, 0, 0x21,
+    0, 0, 0x29,
+    #0, 1, 0xe7,
+    #1, 1, 0x11,
+)
+
+XSTART_H = 0xf0
+XSTART_L = 0xf1
+YSTART_H = 0xf2
+YSTART_L = 0xf3
+XEND_H = 0xE0
+XEND_L = 0xE1
+YEND_H = 0xE2
+YEND_L = 0xE3
+
+XSTART = 0xD0
+XEND = 0xD1
+YSTART = 0xD2
+YEND = 0xD3
+
+lcd = LCD()
+
+init_buf = bytearray(init_data)
+
+init_data2 = (
+    0, 4, 0x2a,
+    1, 1, XSTART_H,
+    1, 1, XSTART_L,
+    1, 1, XEND_H,
+    1, 1, XEND_L,
+    0, 4, 0x2b,
+    1, 1, YSTART_H,
+    1, 1, YSTART_L,
+    1, 1, YEND_H,
+    1, 1, YEND_L,
+    0, 0, 0x2c,
+)
+invalid = bytearray(init_data2)
+
+init_data3 = (
+    0, 0, 0x28,
+    2, 0, 120,
+    0, 0, 0x10,
+)
+displayoff = bytearray(init_data3)
+
+init_data4 = (
+    0, 0, 0x11,
+    2, 0, 20,
+    0, 0, 0x29,
+)
+displayon = bytearray(init_data4)
+# CST816初始化
+import initTP
+initTP.HYN_Initial()
+tp_cst816 = cst816(i2c_no = 2,irq=33, reset=32)
+tp_cst816.activate()
+tp_cst816.init()
+
+print("cst816 init...")
+from btn_device_ec800m import BtnDevice
+btn_device = BtnDevice(tp_cst816)
+btn_device.start()
+
+lcd_ctrl = Pin(Pin.GPIO18, Pin.OUT, Pin.PULL_DISABLE, 1)
+lcd.lcd_init(init_buf, 240, 320, 52000, 1, 4, 0, invalid, displayon, displayoff, None,TESel = True,TEPin = 17)
+# gpio_backlight = Pin(Pin.GPIO37, Pin.OUT, Pin.PULL_DISABLE, 0)
+# gpio_backlight.write(1)
+PWM_backlight = PWM(PWM.PWM1, PWM.ABOVE_MS, 0, 1)
+PWM_backlight.open()
+
+LCD_SIZE_W = 240
+LCD_SIZE_H = 320
+# pwm.close()
+# 初始化lvgl
+lv.init()
+
+# Register SDL display driver.
+disp_buf1 = lv.disp_draw_buf_t()
+buf1_1 = bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+#buf1_2= bytearray(LCD_SIZE_W * LCD_SIZE_H * 2)
+
+disp_buf1.init(buf1_1, None, len(buf1_1))
+disp_drv = lv.disp_drv_t()
+disp_drv.init()
+disp_drv.draw_buf = disp_buf1
+disp_drv.flush_cb = lcd.lcd_write
+disp_drv.hor_res = LCD_SIZE_W
+disp_drv.ver_res = LCD_SIZE_H
+disp_drv.register()
+
+
+# LVGL触摸注册
+indev_drv = lv.indev_drv_t()
+indev_drv.init()
+indev_drv.type = lv.INDEV_TYPE.POINTER
+indev_drv.read_cb = tp_cst816.read
+indev_drv.long_press_time = 300
+indev_drv.register()
+gpio4 = Pin(Pin.GPIO33, Pin.OUT, Pin.PULL_PU, 0)
+
+# def indev_task():
+#     while 1:
+#         pos_s = tp_cst816.read_xy()
+#         # import _thread
+#         # x = _thread.get_heap_size()
+#         # print('heap:',x)
+#         if pos_s:
+#             if 100 == pos_s[0] and 400 == pos_s[1]:
+#                 EventMesh.publish("done_return")
+#                 print("return")
+#                 utime.sleep_ms(200)
+#         else:
+#             utime.sleep_ms(200)
+
+# _thread.start_new_thread(indev_task,())
+
+# 启动lvgv线程
+lv.tick_inc(5)
+lv.task_handler()
+style_screen = lv.style_t()
+style_screen.init()
+style_screen.set_radius(0)
+style_screen.set_bg_color(lv.color_make(0x00, 0x00, 0x00))
+style_screen.set_bg_opa(255)
+style_screen.set_border_width(0)
+style_screen.set_pad_left(0)
+style_screen.set_pad_right(0)
+style_screen.set_pad_top(0)
+style_screen.set_pad_bottom(0)
+#开机画面
+style_font_youyuan_40 = lv.style_t()
+style_font_youyuan_40.init()
+style_font_youyuan_40.set_text_color(lv.color_make(0xff, 0xff, 0xff))
+style_font_youyuan_40.set_text_font_v2("font_40.bin",40,0)
+
+power_on_screen = lv.obj()
+power_on_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+power_on_label = lv.label(power_on_screen)
+power_on_label.set_text("WELCOME")
+power_on_label.align(lv.ALIGN.CENTER, 0, 0)
+power_on_label.add_style(style_font_youyuan_40, lv.PART.MAIN | lv.STATE.DEFAULT)
+print("power_on_screen init...")
+lv.scr_load(power_on_screen)
+utime.sleep_ms(1000)
+print("power_on_screen end...")
+PWM_backlight = PWM(PWM.PWM1, PWM.ABOVE_MS, 1, 1)
+PWM_backlight.open()
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/location.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/location.py
new file mode 100644 (file)
index 0000000..b546faf
--- /dev/null
@@ -0,0 +1,1024 @@
+# Copyright (c) Quectel Wireless Solution, Co., Ltd.All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import ure
+import net
+import math
+import utime
+import osTimer
+import _thread
+import wifiScan
+import cellLocator
+
+from queue import Queue
+from machine import UART, Pin
+
+try:
+    from wifilocator import wifilocator
+except:
+    wifilocator = None
+
+from log import getLogger
+
+try:
+    import quecgnss
+except ImportError:
+    quecgnss = None
+
+log = getLogger(__name__)
+
+_gps_read_lock = _thread.allocate_lock()
+_gps_data_set_lock = _thread.allocate_lock()
+
+EE = 0.00669342162296594323
+EARTH_RADIUS = 6378.137  # Approximate Earth Radius(km)
+M_PI = math.pi
+
+
+class _loc_method(object):
+    gps = 0x1
+    cell = 0x2
+    wifi = 0x4
+
+
+class _gps_mode(object):
+    none = 0x0
+    internal = 0x1
+    external = 0x2
+
+
+def transformLat(x, y):
+    ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(math.fabs(x))
+    ret += (20.0 * math.sin(6.0 * x * M_PI) + 20.0 * math.sin(2.0 * x * M_PI)) * 2.0 / 3.0
+    ret += (20.0 * math.sin(y * M_PI) + 40.0 * math.sin(y / 3.0 * M_PI)) * 2.0 / 3.0
+    ret += (160.0 * math.sin(y / 12.0 * M_PI) + 320 * math.sin(y * M_PI / 30.0)) * 2.0 / 3.0
+    return ret
+
+
+def transformLon(x, y):
+    ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(math.fabs(x))
+    ret += (20.0 * math.sin(6.0 * x * M_PI) + 20.0 * math.sin(2.0 * x * M_PI)) * 2.0 / 3.0
+    ret += (20.0 * math.sin(x * M_PI) + 40.0 * math.sin(x / 3.0 * M_PI)) * 2.0 / 3.0
+    ret += (150.0 * math.sin(x / 12.0 * M_PI) + 300.0 * math.sin(x / 30.0 * M_PI)) * 2.0 / 3.0
+    return ret
+
+
+def WGS84ToGCJ02(lon, lat):
+    dLat = transformLat(lon - 105.0, lat - 35.0)
+    dLon = transformLon(lon - 105.0, lat - 35.0)
+    radLat = lat / 180.0 * M_PI
+    magic = math.sin(radLat)
+    magic = 1 - magic * magic * EE
+    sqrtMagic = math.sqrt(magic)
+
+    dLat = (dLat * 180.0) / ((EARTH_RADIUS * 1000 * (1 - EE)) / (magic * sqrtMagic) * M_PI)
+    dLon = (dLon * 180.0) / (EARTH_RADIUS * 1000 / sqrtMagic * math.cos(radLat) * M_PI)
+    lon02 = lon + dLon
+    lat02 = lat + dLat
+
+    return lon02, lat02
+
+
+class GPSMatch(object):
+    """This class is match gps NEMA 0183"""
+
+    def GxRMC(self, gps_data):
+        """Match Recommended Minimum Specific GPS/TRANSIT Data(RMC)
+
+        Args:
+            gps_data(str): GPS NMEA string.
+
+        Returns:
+            str: RMC NMEA string.
+        """
+        if gps_data:
+            rmc_re = ure.search(
+                r"\$G[NP]RMC,\d*\.*\d*,*[AV],*\d*\.*\d*,*[NS],*\d*\.*\d*,*[EW],*\d*\.*\d*,*\d*\.*\d*,*\d*,*\d*\.*\d*,*[EW]*,*[ADEN]*,*[SCUV]*\**(\d|\w)*",
+                gps_data)
+            if rmc_re:
+                return rmc_re.group(0)
+        return ""
+
+    def GxGGA(self, gps_data):
+        """Match Global Positioning System Fix Data(GGA)
+
+        Args:
+            gps_data(str): GPS NMEA string.
+
+        Returns:
+            str: GGA NMEA string.
+        """
+        if gps_data:
+            gga_re = ure.search(
+                r"\$G[BLPN]GGA,\d*\.*\d*,*\d*\.*\d*,*[NS],*\d*\.*\d*,*[EW],*[0126],*\d*,*\d*\.*\d*,*-*\d*\.*\d*,*M,*-*\d*\.*\d*,*M,*\d*,*\**(\d|\w)*",
+                gps_data)
+            if gga_re:
+                return gga_re.group(0)
+        return ""
+
+    def GxVTG(self, gps_data):
+        """Match Track Made Good and Ground Speed(VTG)
+
+        Args:
+            gps_data(str): GPS NMEA string.
+
+        Returns:
+            str: VTG NMEA string.
+        """
+        if gps_data:
+            vtg_re = ure.search(r"\$G[NP]VTG,\d*\.*\d*,*T,*\d*\.*\d*,*M,*\d*\.*\d*,*N,*\d*\.*\d*,*K,*[ADEN]*\*(\d|\w)*",
+                                gps_data)
+            if vtg_re:
+                return vtg_re.group(0)
+        return ""
+
+    def GxGSV(self, gps_data):
+        """Mactch GPS Satellites in View(GSV)
+
+        Args:
+            gps_data(str): GPS NMEA string.
+
+        Returns:
+            str: GSV NMEA string.
+        """
+        if gps_data:
+            gsv_re = ure.search(
+                r"\$G[NP]GSV,\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*\**(\d|\w)*",
+                gps_data)
+            if gsv_re:
+                return gsv_re.group(0)
+        return ""
+
+    def GxGLL(self, gps_data):
+        """Geographic Position
+
+        Args:
+            gps_data(str): GPS NMEA string.
+
+        Returns:
+            str: GLL NMEA string.
+        """
+        if gps_data:
+            gll_re = ure.search(r"\$G[NP]GLL,\d*\.*\d*,*[NS]*,*\d*\.*\d*,*[EW]*,*\d*\.*\d*,*[AV]*,*[ADEN]*\**(\d|\w)*",
+                                gps_data)
+            if gll_re:
+                return gll_re.group(0)
+
+    def GxGSA(self, gps_data):
+        """GNSS DOP and Active Satellites
+
+        Args:
+            gps_data(str): GPS NMEA string.
+
+        Returns:
+            str: GSA NMEA string.
+        """
+        if gps_data:
+            gsa_re = ure.search(
+                r"\$G[NP]GSA,[MA]*,*[123]*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*,*\d*\.*\d*,*\d*\.*\d*,*\d*\.*\d*,*(\d|\w)*\**(\d|\w)*",
+                gps_data)
+            if gsa_re:
+                return gsa_re.group(0)
+
+
+class GPSParse(object):
+    """Parse details from gps data"""
+
+    def GxGGA_satellite_num(self, gga_data):
+        """Parse satellite num from GGA"""
+        if gga_data:
+            satellite_num_re = ure.search(r",[EW],[0126],\d+,", gga_data)
+            if satellite_num_re:
+                return satellite_num_re.group(0).split(",")[-2]
+        return ""
+
+    def GxGGA_latitude(self, gga_data):
+        """Parse latitude from GGA"""
+        if gga_data:
+            latitude_re = ure.search(r",[0-9]+\.[0-9]+,[NS],", gga_data)
+            if latitude_re:
+                latitude = latitude_re.group(0)[1:-3]
+                return str(float(latitude[:2]) + float(latitude[2:]) / 60)
+        return ""
+
+    def GxGGA_longitude(self, gga_data):
+        """Parse longitude from GGA"""
+        if gga_data:
+            longitude_re = ure.search(r",[0-9]+\.[0-9]+,[EW],", gga_data)
+            if longitude_re:
+                longitude = longitude_re.group(0)[1:-3]
+                return str(float(longitude[:3]) + float(longitude[3:]) / 60)
+        return ""
+
+    def GxGGA_altitude(self, gga_data):
+        """Parse altitude from GGA"""
+        if gga_data:
+            altitude_re = ure.search(r",-*[0-9]+\.[0-9]+,M,", gga_data)
+            if altitude_re:
+                return altitude_re.group(0)[1:-3]
+        return ""
+
+    def GxVTG_speed(self, vtg_data):
+        """Parse speed from VTG"""
+        if vtg_data:
+            speed_re = ure.search(r",N,\d+\.\d+,K,", vtg_data)
+            if speed_re:
+                return speed_re.group(0)[3:-3]
+        return ""
+
+    def GxGSV_satellite_num(self, gsv_data):
+        """Parse satellite num from GSV"""
+        if gsv_data:
+            satellite_num_re = ure.search(r"\$G[NP]GSV,\d+,\d+,\d+,", gsv_data)
+            if satellite_num_re:
+                return satellite_num_re.group(0).split(",")[-2]
+        return ""
+
+    def GxRMC_loc_status(self, rmc_data):
+        if rmc_data:
+            loc_status_re = ure.search(r"\$G[NP]RMC,\d*\.*\d*,[AV],", rmc_data)
+            if loc_status_re:
+                loc_status = loc_status_re.group(0).split(",")[-2]
+                return True if loc_status == "A" else False
+        return False
+
+    def __nmea_parse(self, nmea):
+        return tuple(nmea[1:].split("*")[0].split(",")) if nmea else ()
+
+    def GxRMC(self, rmc_data):
+        return self.__nmea_parse(rmc_data)
+
+    def GxGGA(self, gga_data):
+        return self.__nmea_parse(gga_data)
+
+    def GxGSV(self, gsv_data):
+        return self.__nmea_parse(gsv_data)
+
+    def GxGSA(self, gsa_data):
+        return self.__nmea_parse(gsa_data)
+
+    def GxVTG(self, vtg_data):
+        return self.__nmea_parse(vtg_data)
+
+    def GxGLL(self, gll_data):
+        return self.__nmea_parse(gll_data)
+
+
+class GPS(object):
+    """This class if for reading gps data.
+
+    Now support external gps and internal gps.
+
+    Sleep power consumption:
+        power off < backup < standby
+    """
+
+    __RMC = 0
+    __GGA = 1
+    __GSV = 2
+    __GSA = 3
+    __VTG = 4
+    __GLL = 5
+    __NMEA = 0b010111
+
+    def __init__(self, UARTn, buadrate, databits, parity, stopbits, flowctl, PowerPin, StandbyPin, BackupPin, gps_mode):
+        """Init GPS module
+
+        [description]
+
+        Args:
+            UARTn(int): UART No.
+            buadrate(int): baud rate
+            databits(int): data bits (5 ~ 8)
+            parity(int): parity (0 – NONE,1 – EVEN,2 - ODD)
+            stopbits(int): stop bit
+            flowctl(int): hardware control flow (0 – FC_NONE, 1 – FC_HW)
+            PowerPin(int): Power GIPO Pin
+            StandbyPin(int): Standby GPIO Pin
+            BackupPin(int): Back GPIO Pin
+            gps_mode(int): GPS mode
+                0 - None
+                1 - internal GPS
+                2 - external GPS
+        """
+        self.__UARTn = UARTn
+        self.__buadrate = buadrate
+        self.__databits = databits
+        self.__parity = parity
+        self.__stopbits = stopbits
+        self.__flowctl = flowctl
+        self.__PowerPin = PowerPin
+        self.__StandbyPin = StandbyPin
+        self.__BackupPin = BackupPin
+        self.__gps_mode = gps_mode
+
+        self.__external_obj = None
+        self.__internal_obj = quecgnss
+        self.__gps_match = GPSMatch()
+        self.__gps_parse = GPSParse()
+        self.__gps_power_gpio = None
+        self.__gps_standby_gpio = None
+        self.__gps_backup_gpio = None
+
+        self.__external_retrieve_queue = None
+        self.__queue_size = 2
+        self.__first_break = 0
+        self.__break = 0
+        self.__gps_data = ""
+        self.__rmc_data = ""
+        self.__gga_data = ""
+        self.__vtg_data = ""
+        self.__gsv_data = ""
+        self.__gps_timer = osTimer()
+        self.__gps_data_check_timer = osTimer()
+
+        if self.__gps_mode & _gps_mode.external:
+            self.__external_init()
+        elif self.__gps_mode & _gps_mode.internal:
+            self.__internal_init()
+        #print("GPS:__init__%d",self.__gps_mode)
+    def __gps_power_control(self, GPIOn, onoff, method):
+        if method == "power_switch":
+            if self.__gps_power_gpio is None:
+                self.__gps_power_gpio = Pin(GPIOn, Pin.OUT, Pin.PULL_DISABLE, onoff)
+            gpio_obj = self.__gps_power_gpio
+        elif method == "standby":
+            if self.__gps_standby_gpio is None:
+                self.__gps_standby_gpio = Pin(GPIOn, Pin.OUT, Pin.PULL_DISABLE, onoff)
+            gpio_obj = self.__gps_standby_gpio
+        elif method == "backup":
+            if self.__gps_backup_gpio is None:
+                self.__gps_backup_gpio = Pin(GPIOn, Pin.OUT, Pin.PULL_DISABLE, onoff)
+            gpio_obj = self.__gps_backup_gpio
+        else:
+            raise TypeError("Param method %s is not compare." % method)
+
+        if gpio_obj.read() != onoff:
+            gpio_obj.write(onoff)
+            if gpio_obj.read() != onoff:
+                return False
+        return True
+
+    def __reverse_gps_data(self, this_gps_data):
+        """Reverse GPS data for regular match get the latest data"""
+        log.debug("this_gps_data: \n%s" % this_gps_data)
+        delimiter = "\r\n"
+        if this_gps_data:
+            _gps_data = self.__get_gps_data()
+            if _gps_data:
+                _gps_data = delimiter.join(_gps_data.split(delimiter)[::-1])
+            _gps_data += this_gps_data.strip().replace("\r", "").replace("\n", "").replace("$", delimiter + "$")
+            _gps_data = delimiter.join(_gps_data.split(delimiter)[::-1])
+            self.__set_gps_data(_gps_data)
+
+    def __read_latitude(self, gps_data):
+        """Read latitude from gps data"""
+        return self.__gps_parse.GxGGA_latitude(self.__gps_match.GxGGA(gps_data))
+
+    def __read_longitude(self, gps_data):
+        """Read longitude from gps data"""
+        return self.__gps_parse.GxGGA_longitude(self.__gps_match.GxGGA(gps_data))
+
+    def __read_altitude(self, gps_data):
+        """Read altitude from gps data"""
+        return self.__gps_parse.GxGGA_altitude(self.__gps_match.GxGGA(gps_data))
+
+    def __set_gps_data(self, gps_data):
+        self.__gps_data = gps_data
+
+    def __get_gps_data(self):
+        return self.__gps_data
+
+    def __gps_timer_callback(self, args):
+        """GPS read timer callback
+        When over time to get uart data, break queue wait
+        """
+        self.__break = 1
+        if self.__external_retrieve_queue is not None:
+            self.__external_retrieve_queue.put(False)
+
+    def __gps_data_check_callback(self, args):
+        """GPS read old data clean timer callback
+        When GPS read over time, clean old gps data, wait to read new gps data.
+        """
+        clean = False
+        if "" in (self.__rmc_data, self.__gga_data, self.__gsv_data):
+            clean = True
+        else:
+            if self.__nmea_statement_exist(self.__GSA) and not self.__gsa_data:
+                clean = True
+            elif self.__nmea_statement_exist(self.__VTG) and not self.__vtg_data:
+                clean = True
+            elif self.__nmea_statement_exist(self.__GLL) and not self.__gll_data:
+                clean = True
+
+        if clean:
+            self.__gps_nmea_data_clean()
+
+    def __external_init(self):
+        """External GPS init"""
+        self.__external_retrieve_queue = Queue(maxsize=self.__queue_size)
+
+    def __external_open(self):
+        """External GPS start, UART init"""
+        self.power_switch(1)
+        self.__external_obj = UART(
+            self.__UARTn,
+            self.__buadrate,
+            self.__databits,
+            self.__parity,
+            self.__stopbits,
+            self.__flowctl
+        )
+        self.__external_obj.set_callback(self.__external_retrieve_cb)
+
+    def __external_close(self):
+        """External GPS close, UART close, NOT GPS stop"""
+        self.__external_obj.close()
+
+    def __external_retrieve_cb(self, args):
+        """
+        GPS data retrieve callback from UART
+        When data comes, send a message to queue of data length
+        """
+        # log.debug("GPS __external_retrieve_cb args: %s" % str(args))
+        if self.__external_retrieve_queue.size() >= self.__queue_size:
+            self.__external_retrieve_queue.get()
+        self.__external_retrieve_queue.put(True)
+
+    def __internal_init(self):
+        """Internal GPS init"""
+        if self.__internal_obj:
+            if self.__internal_obj.init() != 0:
+                self.__internal_open()
+                log.error("GNSS INIT Failed.")
+            else:
+                log.debug("GNSS INIT Success.")
+        else:
+            log.error("Module quecgnss Import Error.")
+
+    def __internal_open(self):
+        """Internal GPS enable"""
+        if self.__internal_obj.get_state() == 0:
+            return True if self.__internal_obj.gnssEnable(1) == 0 else False
+        else:
+            return True
+
+    def __internal_close(self):
+        """Internal GPS close"""
+        return True if self.__internal_obj.gnssEnable(0) == 0 else False
+
+    def __nmea_statement_exist(self, nmea_item):
+        return (self.__NMEA & (0b1 << nmea_item)) >> nmea_item
+
+    def __gps_nmea_data_clean(self):
+        self.__set_gps_data("")
+        self.__rmc_data = ""
+        self.__gga_data = ""
+        self.__gsv_data = ""
+        self.__gsa_data = ""
+        self.__vtg_data = ""
+        self.__gll_data = ""
+
+    def __check_gps_valid(self, gps_data):
+        self.__reverse_gps_data(gps_data)
+
+        if not self.__rmc_data:
+            self.__rmc_data = self.__gps_match.GxRMC(self.__get_gps_data())
+        loc_status = self.__gps_parse.GxRMC_loc_status(self.__rmc_data)
+
+        if self.__rmc_data and loc_status:
+            if self.__nmea_statement_exist(self.__GGA) and not self.__gga_data:
+                self.__gga_data = self.__gps_match.GxGGA(self.__get_gps_data())
+            if self.__nmea_statement_exist(self.__GSV) and not self.__gsv_data:
+                self.__gsv_data = self.__gps_match.GxGSV(self.__get_gps_data())
+            if self.__nmea_statement_exist(self.__GSA) and not self.__gsa_data:
+                self.__gsa_data = self.__gps_match.GxGSA(self.__get_gps_data())
+            if self.__nmea_statement_exist(self.__VTG) and not self.__vtg_data:
+                self.__vtg_data = self.__gps_match.GxVTG(self.__get_gps_data())
+            if self.__nmea_statement_exist(self.__GLL) and not self.__gll_data:
+                self.__gll_data = self.__gps_match.GxGLL(self.__get_gps_data())
+
+            if self.__nmea_statement_exist(self.__GGA) and not self.__gga_data:
+                return False
+            if self.__nmea_statement_exist(self.__GSV) and not self.__gsv_data:
+                return False
+            if self.__nmea_statement_exist(self.__GSA) and not self.__gsa_data:
+                return False
+            if self.__nmea_statement_exist(self.__VTG) and not self.__vtg_data:
+                return False
+            if self.__nmea_statement_exist(self.__GLL) and not self.__gll_data:
+                return False
+            return True
+
+        return False
+
+    def __external_read(self):
+        """Read external GPS data
+
+        Return:
+            $GPTXT,01,01,02,ANTSTATUS=OPEN*2B
+            $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07
+            $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22
+            $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56
+            $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02
+            $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03
+            $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54
+            $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58
+            $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B
+            $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71
+            $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71
+            $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70
+            $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78
+            $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72
+            $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E
+        """
+        self.__external_open()
+        log.debug("__external_read start")
+
+        while self.__break == 0:
+            self.__gps_timer.start(50, 0, self.__gps_timer_callback)
+            signal = self.__external_retrieve_queue.get()
+            log.debug("[first] signal: %s" % signal)
+            if signal:
+                to_read = self.__external_obj.any()
+                log.debug("[first] to_read: %s" % to_read)
+                if to_read > 0:
+                    self.__set_gps_data(self.__external_obj.read(to_read).decode())
+            self.__gps_timer.stop()
+        self.__break = 0
+
+        self.__gps_nmea_data_clean()
+        self.__gps_data_check_timer.start(2000, 1, self.__gps_data_check_callback)
+        cycle = 0
+        while self.__break == 0:
+            self.__gps_timer.start(1500, 0, self.__gps_timer_callback)
+            signal = self.__external_retrieve_queue.get()
+            log.debug("[second] signal: %s" % signal)
+            if signal:
+                to_read = self.__external_obj.any()
+                log.debug("[second] to_read: %s" % to_read)
+                if to_read > 0:
+                    if self.__check_gps_valid(self.__external_obj.read(to_read).decode()):
+                        self.__break = 1
+
+            self.__gps_timer.stop()
+            cycle += 1
+            if cycle >= self.__retry:
+                self.__break = 1
+            if self.__break != 1:
+                utime.sleep(1)
+        self.__gps_data_check_timer.stop()
+        self.__break = 0
+
+        # To check GPS data is usable or not.
+        self.__gps_data_check_callback(None)
+        self.__external_close()
+        log.debug("__external_read data: %s" % self.__get_gps_data())
+        return self.__get_gps_data()
+
+    def __internal_read(self):
+        import EventMesh
+        log.debug("__internal_read start.")
+        """Read internal GPS data
+
+        Return:
+            $GPTXT,01,01,02,ANTSTATUS=OPEN*2B
+            $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07
+            $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22
+            $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56
+            $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02
+            $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03
+            $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54
+            $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58
+            $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B
+            $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71
+            $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71
+            $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70
+            $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78
+            $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72
+            $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E
+        """
+
+        #self.__gps_nmea_data_clean()
+
+        cycle = 0
+        #while self.__break == 0:
+        gnss_data = quecgnss.read(1024*3)
+        #print("__internal_read")
+        #print(gnss_data)
+        if gnss_data and gnss_data[1]:
+            this_gps_data = gnss_data[1].decode() if len(gnss_data) > 1 and gnss_data[1] else ""
+            _gps_valid = self.__check_gps_valid(this_gps_data)
+            log.debug("_gps_valid: %s" % _gps_valid)
+            
+            #print("_gps_valid:",_gps_valid)
+            #print(str(_gps_valid),self.__get_gps_data())
+            if _gps_valid == True :
+                #EventMesh.publish("time", [self.__get_gps_data(),"0",str(_gps_valid),"0"])
+                return self.__get_gps_data()
+            else :
+                EventMesh.publish("time", [self.__get_gps_data(),"0",str(_gps_valid),"0"])
+                return ""
+        
+    def read(self, retry=30):
+        """For user to read gps data
+
+        Return: (res_code, gps_data)
+            res_code:
+                -  0: Success
+                - -1: Failed
+            gps_data:
+                $GPTXT,01,01,02,ANTSTATUS=OPEN*2B
+                $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07
+                $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22
+                $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56
+                $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02
+                $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03
+                $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54
+                $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58
+                $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B
+                $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71
+                $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71
+                $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70
+                $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78
+                $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72
+                $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E
+        """
+        self.__retry = retry
+        gps_data = ""
+        if self.__gps_mode & _gps_mode.external:
+            gps_data = self.__external_read()
+        elif self.__gps_mode & _gps_mode.internal:
+            gps_data = self.__internal_read()
+
+        res = 0 if gps_data else -1
+        return (res, gps_data)
+
+    def read_coordinates(self, gps_data):
+        """Read positioning coordinates.
+
+        Params:
+            gps_data: read gps data.
+            map_coordinate_system: `WGS84` or GCJ02
+
+        Return:
+            (longitude, latitude, altitude)
+        """
+        latitude = self.__read_latitude(gps_data)
+        latitude = float(latitude) if latitude else latitude
+        longitude = self.__read_longitude(gps_data)
+        longitude = float(longitude) if longitude else longitude
+        altitude = self.__read_altitude(gps_data)
+        altitude = float(altitude) if altitude else altitude
+        return (longitude, latitude, altitude)
+
+    def power_switch(self, onoff):
+        """GPS module power switch
+
+        Params:
+            onoff: 0 -- off, 1 -- on
+        """
+        if self.__gps_mode & _gps_mode.external:
+            if self.__PowerPin is not None:
+                return self.__gps_power_control(self.__PowerPin, onoff, "power_switch")
+            else:
+                return False
+        elif self.__gps_mode & _gps_mode.internal:
+            # TODO: Interal GNSS power down will not be used this api.
+            if onoff == 0:
+                return self.__internal_close()
+            else:
+                return self.__internal_open()
+
+    def backup(self, onoff):
+        """GPS module low enery mode backup
+
+        Params:
+            onoff: 0 -- off, 1 -- on
+        """
+        if self.__BackupPin is not None:
+            return self.__gps_power_control(self.__BackupPin, onoff, "backup")
+        else:
+            return False
+
+    def standby(self, onoff):
+        """GPS module low enery mode standby
+
+        Params:
+            onoff: 0 -- off, 1 -- on
+        """
+        if self.__StandbyPin is not None:
+            return self.__gps_power_control(self.__StandbyPin, onoff, "standby")
+        else:
+            return False
+
+    def set_nmea_statement(self, nmea_statement):
+        """Set NMEA statement to check gps info valid
+
+        RMC, GGA, GSV must be required.
+
+        Args:
+            nmea_statement(int):
+                RMC - 0b1 << 0 (bit0), 0 - off, 1 - on
+                GGA - 0b1 << 1 (bit1), 0 - off, 1 - on
+                GSV - 0b1 << 2 (bit2), 0 - off, 1 - on
+                GSA - 0b1 << 3 (bit3), 0 - off, 1 - on
+                VTG - 0b1 << 4 (bit4), 0 - off, 1 - on
+                GLL - 0b1 << 5 (bit5), 0 - off, 1 - on
+
+        Returns:
+            bool: True - success, False - falied.
+        """
+        if nmea_statement >= 0b111:
+            self.__NMEA = nmea_statement
+            return True
+        return False
+
+
+class CellLocator(object):
+    """This class is for reading cell location data"""
+
+    def __init__(self, serverAddr, port, token, timeout, profileIdx):
+        self.__serverAddr = serverAddr
+        self.__port = port
+        self.__token = token
+        self.__timeout = timeout
+        self.__profileIdx = profileIdx
+
+    def read(self):
+        read_loc_res = self.__read_loc()
+        read_cell_res = self.__read_cell()
+        res = 0 if read_loc_res[0] == 0 or read_cell_res[0] == 0 else -1
+        return (res, read_loc_res[1], read_cell_res[1])
+
+    def __read_loc(self):
+        """Read cell location data.
+
+        Return: (res_code, loc_data)
+            res_code:
+                -  0: Success
+                - -1: Initialization failed
+                - -2: The server address is too long (more than 255 bytes)
+                - -3: Wrong key length, must be 16 bytes
+                - -4: The timeout period is out of range, the supported range is (1 ~ 300) s
+                - -5: The specified PDP network is not connected, please confirm whether the PDP is correct
+                - -6: Error getting coordinates
+            loc_data:
+                (117.1138, 31.82279, 550)
+        """
+        res = -1
+        loc_data = cellLocator.getLocation(
+            self.__serverAddr,
+            self.__port,
+            self.__token,
+            self.__timeout,
+            self.__profileIdx
+        )
+        if isinstance(loc_data, tuple) and len(loc_data) == 3:
+            res = 0
+        else:
+            res = loc_data
+            loc_data = ()
+
+        return (res, loc_data)
+
+    def __read_cell(self):
+        res = -1
+        near_cell = []
+        server_cell = []
+
+        near_cells = net.getCi()
+        if near_cells != -1 and isinstance(near_cells, list):
+            near_cell = list(map(str, near_cells))
+
+        server_cells = net.getCellInfo()
+        if server_cells != -1 and isinstance(server_cells, tuple):
+            server_cell = server_cells
+
+        res = 0 if near_cell or server_cell else -1
+        return (res, {"near_cell": near_cell, "server_cell": server_cell})
+
+
+class WiFiLocator(object):
+    """This class is for reading wifi location data"""
+
+    def __init__(self, token):
+        self.__wifilocator_obj = wifilocator(token)
+
+    def read(self):
+        read_loc_res = self.__read_loc()
+        read_mac_res = self.__read_mac()
+        res = 0 if read_loc_res[0] == 0 or read_mac_res[0] == 0 else -1
+        return (res, read_loc_res[1], read_mac_res[1])
+
+    def __read_loc(self):
+        """Read wifi location data.
+
+        Return: (res_code, loc_data)
+            res_code:
+                -  0: Success
+                - -1: The current network is abnormal, please confirm whether the dial-up is normal
+                - -2: Wrong key length, must be 16 bytes
+                - -3: Error getting coordinates
+            loc_data:
+                (117.1138, 31.82279, 550)
+        """
+        res = -1
+        loc_data = self.__wifilocator_obj.getwifilocator()
+        if isinstance(loc_data, tuple) and len(loc_data) == 3:
+            res = 0
+        else:
+            res = loc_data
+            loc_data = ()
+
+        return (res, loc_data)
+
+    def __read_mac(self):
+        res = -1
+        macs = []
+        if wifiScan.support():
+            if wifiScan.control(1) == 0:
+                if wifiScan.getState():
+                    wifisacn_start = wifiScan.start()
+                    if wifisacn_start != -1 and wifisacn_start[0] > 0:
+                        macs = [i[0] for i in wifisacn_start[1]]
+                        res = 0
+            wifiScan.control(0)
+        return (res, macs)
+
+
+class Location(object):
+    """This class is for reading location data from gps, cell, wifi"""
+    gps = None
+    cellLoc = None
+    wifiLoc = None
+
+    def __init__(self, loc_method, locator_init_params):
+        """Init Location module
+
+        1. If loc_method include gps then init gps module;
+        2. If loc_method inculde cell then init cell module;
+        3. If loc_method Include wifi then init wifi module;
+
+        Args:
+            loc_method(int):
+                1 - gps
+                2 - cell
+                3 - cell & gps
+                4 - wifi
+                5 - wifi & gps
+                6 - wifi & cell
+                7 - wifi & cell & gps
+            locator_init_params(dict):
+                gps_cfg(dict):GPS module init args
+                cell_cfg(dict):CELL module init args
+                wifi_cfg(dict):WIFI module init args
+        """
+        self.__loc_method = loc_method
+        self.__locator_init_params = locator_init_params
+        self.__locater_init()
+
+    def __locater_init(self):
+        """Init gps, cell, wifi by loc_method"""
+
+        if self.__loc_method & _loc_method.gps:
+            if self.gps is None:
+                _gps_cfg = self.__locator_init_params.get("gps_cfg", {})
+                if _gps_cfg:
+                    self.gps = GPS(**_gps_cfg)
+                    if _gps_cfg.get("nmea_cfg") is not None:
+                        self.gps.set_nmea_statement(_gps_cfg.get("nmea_cfg"))
+                else:
+                    raise ValueError("Invalid gps init parameters.")
+        else:
+            self.gps = None
+
+        if self.__loc_method & _loc_method.cell:
+            if self.cellLoc is None:
+                _cell_cfg = self.__locator_init_params.get("cell_cfg")
+                if _cell_cfg:
+                    self.cellLoc = CellLocator(**_cell_cfg)
+                else:
+                    raise ValueError("Invalid cell-locator init parameters.")
+        else:
+            self.cellLoc = None
+
+        if self.__loc_method & _loc_method.wifi:
+            if self.wifiLoc is None:
+                _wifi_cfg = self.__locator_init_params.get("wifi_cfg")
+                if _wifi_cfg:
+                    self.wifiLoc = WiFiLocator(**_wifi_cfg)
+                else:
+                    raise ValueError("Invalid wifi-locator init parameters.")
+        else:
+            self.wifiLoc = None
+
+    def __read_gps(self, retry):
+        """Read loction data from gps module
+
+        Return:
+            $GPTXT,01,01,02,ANTSTATUS=OPEN*2B
+            $GNRMC,073144.000,A,3149.330773,N,11706.946971,E,0.00,337.47,150422,,,D,V*07
+            $GNVTG,337.47,T,,M,0.00,N,0.00,K,D*22
+            $GNGGA,073144.000,3149.330773,N,11706.946971,E,2,19,0.66,85.161,M,-0.335,M,,*56
+            $GNGSA,A,3,01,195,06,03,21,194,19,17,30,14,,,0.94,0.66,0.66,1*02
+            $GNGSA,A,3,13,26,07,10,24,25,08,03,22,,,,0.94,0.66,0.66,4*03
+            $GPGSV,3,1,12,14,84,210,31,195,67,057,46,17,52,328,28,50,51,161,33,1*54
+            $GPGSV,3,2,12,194,49,157,33,03,48,090,37,19,36,305,32,06,34,242,32,1*58
+            $GPGSV,3,3,12,01,32,041,35,30,17,204,22,21,07,051,13,07,03,183,,1*6B
+            $BDGSV,5,1,18,07,86,063,30,10,75,322,30,08,60,211,34,03,52,192,33,1*71
+            $BDGSV,5,2,18,24,44,276,33,13,43,215,33,01,43,135,30,26,40,208,37,1*71
+            $BDGSV,5,3,18,02,38,230,,04,32,119,,22,26,135,30,19,25,076,,1*70
+            $BDGSV,5,4,18,05,17,251,,25,06,322,27,09,02,211,22,21,02,179,,1*78
+            $BDGSV,5,5,18,29,02,075,,20,01,035,,1*72
+            $GNGLL,3149.330773,N,11706.946971,E,073144.000,A,D*4E
+        """
+        if self.gps:
+            return self.gps.read(retry)[1]
+        return ""
+
+    def __read_cell(self):
+        """Read loction data from cell module
+
+        Return:
+            (117.1138, 31.82279, 550) or ()
+        """
+        if self.cellLoc:
+            cell_loc_data = self.cellLoc.read()
+            return (cell_loc_data[1], cell_loc_data[2])
+        return ()
+
+    def __read_wifi(self):
+        """Read loction data from wifi module
+
+        Return:
+            (117.1138, 31.82279, 550) or ()
+        """
+        if self.wifiLoc:
+            wifi_loc_data = self.wifiLoc.read()
+            return (wifi_loc_data[1], wifi_loc_data[2])
+        return ()
+
+    def read(self, retry=30):
+        """Read location data
+
+        args:
+            retry(int): gps read uart data retry count.
+
+        Returns:
+            dict:
+                key:
+                    1 - GPS data
+                    2 - CELL data
+                    4 - WIFI data
+            .e.g:
+            {
+                1: "$GPGGA,XXX",
+                2: (0.00, 0.00, 0.00),
+                4: (0.00, 0.00, 0.00),
+            }
+        """
+        loc_data = {}
+
+        if self.__loc_method & _loc_method.gps:
+            loc_data[_loc_method.gps] = self.__read_gps(retry)
+
+        if self.__loc_method & _loc_method.cell:
+            loc_data[_loc_method.cell] = self.__read_cell()
+
+        if self.__loc_method & _loc_method.wifi:
+            loc_data[_loc_method.wifi] = self.__read_wifi()
+
+        return loc_data
+
+    def wgs84togcj02(self, Longitude, Latitude):
+        return WGS84ToGCJ02(Longitude, Latitude)
+
+
+if __name__ == '__main__':
+    _gps_cfg = {
+        "UARTn": UART.UART1,
+        "buadrate": 115200,
+        "databits": 8,
+        "parity": 0,
+        "stopbits": 1,
+        "flowctl": 0,
+        "PowerPin": Pin.GPIO2,
+        "StandbyPin": Pin.GPIO3,
+        "BackupPin": None,
+        "gps_mode": 0x01,
+    }
+    gps = GPS(**_gps_cfg)
+    print("read {}".format(gps.read(300)))
index a074d6d..2c45ef8 100644 (file)
@@ -26,7 +26,7 @@ import wifiScan
 import math
 import voiceCall
 from misc import PWM
-
+from machine import I2C
 class PhoneVolumeLevelManager(Abstract):
     def __init__(self):
         self.level = 0
@@ -537,7 +537,9 @@ class DeviceInfoManager(Abstract):
             print('GNSS init ok.')
         else:
             print('GNSS init failed.')
-        
+        self.i2c0 = I2C(I2C.I2C0, I2C.STANDARD_MODE)
+        self.stop_temp( None, None)
+
     def post_processor_after_instantiation(self):
         print("post_processor_after_instantiation:1")
         """订阅此类所有的事件到 EventMesh中"""
@@ -574,7 +576,9 @@ class DeviceInfoManager(Abstract):
         EventMesh.subscribe(constants.EVENT.STOP_HEART, self.stop_heart)
         EventMesh.subscribe(constants.EVENT.GET_BLOOD_OXYGEN, self.get_blood_oxygen)
         EventMesh.subscribe(constants.EVENT.GET_HEART, self.get_heart)
-
+        EventMesh.subscribe(constants.EVENT.START_TEMP, self.start_temp)
+        EventMesh.subscribe(constants.EVENT.STOP_TEMP, self.stop_temp)
+        EventMesh.subscribe(constants.EVENT.GET_TEMP, self.get_temp)
         print("post_processor_after_instantiation:2")
         self.timer_push_schedule.start(10000, 1, self.publish_event)
         # self.battery_push_schedule.start(3000, 1, self.__check_battery)
@@ -592,8 +596,6 @@ class DeviceInfoManager(Abstract):
         :param kwargs:
         :return:
         """
-
-
         self.timer_push = self.timer_push+1
 
         #if self.timer_push > 10 :
@@ -1132,7 +1134,6 @@ class DeviceInfoManager(Abstract):
         self.PING = msg
     def get_ping(self, topic, msg):
         return self.PING
-
     def set_connect(self, topic, msg):
         #print("set_connect:{}".format(msg))
         self.connect = msg
@@ -1142,26 +1143,45 @@ class DeviceInfoManager(Abstract):
     def start_blood_oxygen(self, topic, msg):
         print("start_blood_oxygen!!!")
         self.hsensor.open_blood_oxygen()
-
     def start_heart(self, topic, msg):
         print("start_heart!!!")
         self.hsensor.open_heart()
-
     def stop_blood_oxygen(self, topic, msg):
         print("stop_blood_oxygen!!!")
         self.hsensor.close()
-
     def stop_heart(self, topic, msg):
         print("stop_heart!!!")
         self.hsensor.close()
-
     def get_blood_oxygen(self, topic, msg):
         data = self.hsensor.get_all_data()
         return data[1]
-
     def get_heart(self, topic, msg):
         data = self.hsensor.get_all_data()
         return data[0]
+    def start_temp(self, topic, msg):
+        WHO_AM_I = bytearray([0x01, 0])
+        I2C_SLAVE_ADDR = 0x49
+        r_data = bytearray(2)
+        data = bytearray([0x61A0, 0])   # 唤醒
+        return self.i2c0.write(I2C_SLAVE_ADDR, WHO_AM_I, 1, data, 2)
+    def stop_temp(self, topic, msg):
+        WHO_AM_I = bytearray([0x01, 0])
+        I2C_SLAVE_ADDR = 0x49
+        r_data = bytearray(2)
+        data = bytearray([0x60A0, 0])   #休眠
+        return self.i2c0.write(I2C_SLAVE_ADDR, WHO_AM_I, 1, data, 2)
+        
+    def get_temp(self, topic, msg):
+        WHO_AM_I = bytearray([0x00, 0])
+        I2C_SLAVE_ADDR = 0x49
+        r_data = bytearray(2)
+        self.i2c0.read(I2C_SLAVE_ADDR, WHO_AM_I, 1, r_data, 2, 0)
+        print("temp_data:{}".format(r_data))
+        temp_s = ((r_data[0]<<8) | (r_data[1]))>>4
+        print("temp_s:{}".format(temp_s))
+        temp_data = temp_s * 0.0625
+        print("temp_data:{}".format(temp_data))
+        return temp_data
 
  
             
@@ -1415,7 +1435,9 @@ class LocationManager(Abstract):
         data = ""
         self.location_timer_count = self.location_timer_count +1
         self.location_check_data_timer_count = self.location_check_data_timer_count+1
-        if self.location_check_data_timer_count > 5 :#5秒查一次
+        match_gga_data = []
+        match_gsv_data = []
+        if self.location_check_data_timer_count > 2 :#5秒查一次
             self.location_check_data_timer_count = 0
             #print(self.location_timer_count)
             #检查wifi数据
@@ -1427,10 +1449,12 @@ class LocationManager(Abstract):
                 data = quecgnss.read(4096)
                 #print(data[1].decode())
                 if data[0] > 0 : #有数据
+                    match_gga_data = self.match.GxGGA(data[1]).split(",")
+                    match_gsv_data = self.match.GxGSV(data[1]).split(",")
                     if self.gps.__check_gps_valid(data[1].decode()): #数据齐全
                         match_gmc_data = self.match.GxRMC(data[1]).split(",")
                         match_vtg_data = self.match.GxVTG(data[1]).split(",")
-                        match_gga_data = self.match.GxGGA(data[1]).split(",")
+                        
                         data = self.gps.read_coordinates(data[1])
                         latitude_tmp = str(data[1]).split(".")
                         if len(latitude_tmp) >= 2 and len(latitude_tmp[1])>=5:
@@ -1459,14 +1483,19 @@ class LocationManager(Abstract):
                         break
         if self.location_type == 1: #测试模式
               EventMesh.publish("PUSH_LOCATION_DATA", [data,self.wifi_data,self.cell_data]) 
-        elif self.location_type == 0: #正常模式     
-            if self.gps_data  != [] or self.location_timer_count > 60: #or( self.wifi_data != [] and self.cell_data != []): 
+        elif self.location_type == 0: #正常模式 
+            #print("(match_gsv_data):{}".format((match_gsv_data)))    
+            if self.gps_data  != [] or self.location_timer_count > 40 : #有gps数据或者超时
                 #print("publish:READ_LOCATION")
                 EventMesh.publish(constants.EVENT.READ_LOCATION, [self.gps_data,self.wifi_data,self.cell_data])
                 EventMesh.publish(constants.EVENT.CLOSE_LOCATION)#关闭定位
-            # if self.location_timer_count > 60 : #1分钟定位超时,超时发送数据,停止定时器及关闭定位
-            #     EventMesh.publish(constants.EVENT.CLOSE_LOCATION)#关闭定位
-            #     EventMesh.publish(constants.EVENT.READ_LOCATION, [self.gps_data,self.wifi_data,self.cell_data])#发送数据
+            if len(match_gsv_data) >= 3:
+                #print("match_gsv_data[3]:{}".format(match_gsv_data[3]))  
+                if (int(match_gsv_data[3]) < 3 and self.wifi_data != [] and self.cell_data != [] and self.location_timer_count > 10): #超过10秒且卫星个数少于3
+                    #print("publish:READ_LOCATION")
+                    EventMesh.publish(constants.EVENT.READ_LOCATION, [self.gps_data,self.wifi_data,self.cell_data])
+                    EventMesh.publish(constants.EVENT.CLOSE_LOCATION)#关闭定位    
+
         
         
             
diff --git a/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/protocol.py b/2.sdk/Helios_SDK/services/microPython/ports/quectel/core/protocol.py
new file mode 100644 (file)
index 0000000..0d1f090
--- /dev/null
@@ -0,0 +1,952 @@
+import ujson
+import utime
+import EventMesh
+import constants
+from common import Abstract
+import uhashlib
+import ubinascii
+from misc import Power
+import audio
+from machine import Pin
+import ujson
+import ql_fs
+def unicode_to_utf8(src):
+    ref = 0xe08080
+    result = ref
+    
+    #取最后六位
+    a = src & 0x3f
+    
+    #将最后六位放在ref最后六位的空位置
+    result = result | a
+    src = src >> 6
+    
+    #取接下来的六位
+    a = src & 0x3f
+    
+    #放在ref对应的六个位置
+    result = result | (a << 8)
+
+    #保留最后四位
+    src = src >> 6
+
+    #放在ref对应的四个位置    
+    result = result | (src << 16)
+    return result
+
+def UnicodeHexStr_To_Utf8Str(str):
+    odata = 0
+
+    result = bytes() 
+    su =str.upper()
+
+    i = 0
+    for c in su:
+        tmp=ord(c)
+        if tmp <= ord('9') :
+            odata = odata << 4
+            odata += tmp - ord('0')
+
+        elif ord('A') <= tmp <= ord('F'):
+            odata = odata << 4
+            odata += tmp - ord('A') + 10
+        if(i%4==3): #每2字节获取一个int,拿到转换后的unicode int
+            #print(odata.to_bytes(2, 'big'))
+            #result.append(odata)
+            if odata > 255:
+                tmp = unicode_to_utf8(odata)#拿到转换后的utf8 int
+                tmp2 = tmp.to_bytes(3, 'big') #转bytes
+            else :
+                tmp2 = odata.to_bytes(1, 'big') 
+            #print("tmp2:{}".format(tmp2))
+            result = result + tmp2
+            odata = 0 
+        i+=1
+    return result.decode('utf-8') #返回utf8的str
+
+class ProtoCol(Abstract):
+    TYPE = ""
+    HEADER = "#@{}@#;"
+    SEPARATOR = ";"
+    END = ";" + chr(0x01)
+
+    def __init__(self):
+        self.content = None
+        self.check_sum = None
+        self.location_old_data = None
+        self.password = EventMesh.publish(constants.EVENT.GET_PASSWORD)
+        self.imei = EventMesh.publish(constants.EVENT.GET_IMEI)
+        self.cid = EventMesh.publish(constants.EVENT.GET_CID)
+        self.imsi = EventMesh.publish(constants.EVENT.GET_IMSI)
+        self.key = EventMesh.publish(constants.EVENT.GET_KEY)
+        self.HEADER = self.HEADER.format(self.TYPE)
+
+    def initialization(self, *args, **kwargs):
+        EventMesh.subscribe(self.TYPE + "_SEND", self.handler)
+        EventMesh.subscribe(self.TYPE + "_RECV", self.handler)
+
+    def handler(self, event, msg):
+        self.password = EventMesh.publish(constants.EVENT.GET_PASSWORD)
+        self.imei = EventMesh.publish(constants.EVENT.GET_IMEI)#"867387060319166"#EventMesh.publish(constants.EVENT.GET_IMEI)#"867387060319166" #EventMesh.publish(constants.EVENT.GET_IMEI)#"867387060319166"#EventMesh.publish(constants.EVENT.GET_IMEI) #"867387060319166"#EventMesh.publish(constants.EVENT.GET_IMEI) #"867387060319166"#"867387060319188"#"867387060319177"#"867387060319166"#"860132060004322"#"867387060319166"#"860132060004322"#EventMesh.publish(constants.EVENT.GET_IMEI)
+        self.cid = EventMesh.publish(constants.EVENT.GET_CID)
+        self.imsi = EventMesh.publish(constants.EVENT.GET_IMSI)
+        self.key = EventMesh.publish(constants.EVENT.GET_KEY)
+        if event.endswith("_SEND"):
+            self.send(event, msg)
+        else:
+            self.recv(event, msg)
+
+    def send(self, event, msg):
+        pass
+
+    def recv(self, event, msg):
+        pass
+
+    @staticmethod
+    def get_date():
+        return "{:04d}-{:02d}-{:02d}".format(*utime.localtime()[0:3])
+
+    @staticmethod
+    def get_time():
+        return "{:02d}:{:02d}:{:02d}".format(*utime.localtime()[3:6])
+
+    def calc_crc(self):
+        data = self.content
+        if not isinstance(data, bytes):
+            data = data.encode()
+        count = 0
+        for x in data:
+            count += x
+        self.check_sum = 100 - count % 100
+
+    def pack(self):
+        self.calc_crc()
+        return self.HEADER.encode() + self.content.encode() + self.SEPARATOR.encode() + int(self.check_sum).to_bytes(1,'little') + self.END.encode()
+    
+    def pack_MD5_head(self,data):                                                                                                                 
+        key = "bZld0ALsZTt15tKEZhOlLPgbsO75BLTP"
+        
+        MD5_head = ""
+        hash_obj = uhashlib.md5(data+key)
+        res = hash_obj.digest()
+
+        # 转成十六进制表示
+        MD5_head = ubinascii.hexlify(res)
+        MD5_head = MD5_head.decode('ascii')
+        #print("pack_MD5_head:")
+        #print(res)
+        #print(MD5_head)
+        return MD5_head
+
+class LK_ProtoCol(ProtoCol):
+    """链路保持"""
+    TYPE = "LK"
+
+    def send(self, event, msg):
+        #[SZKW*334588000000156*0002*LK]
+        #print('self.imei:%s'%(self.imei))
+        send_data = "SZKW*%s*0002*LK"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        # print("LK_ProtoCol:send:%s"%(data))
+
+        
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: LK成功
+        @param msg: 接收到的下行数据
+        """
+        print("LK_ProtoCol:recv:%s"%(msg))
+        EventMesh.publish(constants.PROTOCOL.PING_SEND)
+        EventMesh.publish(constants.PROTOCOL.KA_SEND)
+        EventMesh.publish(constants.EVENT.START_LOCATION) #开始定位
+
+class PING_ProtoCol(ProtoCol):
+    """获取绑定状态"""
+    TYPE = "PING"
+
+    def send(self, event, msg):
+        #[SZKWT*YYYYYYYYYYYYYYY*LEN*PING]
+        send_data = "SZKW*%s*0004*PING"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        #print("PING_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: PING
+        @param msg: 接收到的下行数据
+        """
+        #print("PING_ProtoCol:recv:%s"%(msg))   
+        data_tmp =  msg.decode('ascii')   
+        data_tmp = data_tmp.split(']')[0] #去掉]    
+        EventMesh.publish(constants.EVENT.SET_PING, data_tmp.split(',')[1])
+
+class KA_ProtoCol(ProtoCol):
+    """心跳"""
+    TYPE = "KA"
+
+    def send(self, event, msg):
+        #"{:04d}-{:02d}-{:02d}".format(*utime.localtime()[0:3])
+        #[XT*YYYYYYYYYYYYYYY*LEN*KA,日期,步数,翻滚次数,电量百分数,车载里程数(km)] 实例:[XT*334588000000156*0014*KA,120414,50,100,100,100.12]
+        date = "{:04d}{:02d}{:02d}".format(*utime.localtime()[0:3])
+        date = date[2:]
+        #print("date:",date)
+        #步数
+        old_step = 0
+        step = 0
+        step = EventMesh.publish("get_old_step_value")
+        if step != 0:
+            read_data = EventMesh.publish("get_storage_data")
+            b = str("old_step_new") in read_data.keys()
+            if b == True:
+                old_step = read_data["old_step_new"]
+            else:
+                old_step = 0
+            if old_step !=  step:
+                # print("old_step:send:%d %d"%(old_step,step))
+                read_data["old_step"] = step
+                read_data["old_step_new"] = step+10
+                EventMesh.publish("set_storage_data", read_data)
+                with open("/ext/static/storage_file/config.json","w",encoding="utf-8") as fd:
+                    ujson.dump(read_data,fd)
+
+        old_step = step
+        # step = EventMesh.publish(constants.EVENT.GET_STEP)[0]
+        # 电池电量百分比 
+        bat_tmp = EventMesh.publish("screen_get_battery")
+        battery_caption =  bat_tmp[1]
+        send_data = "KA,%s,%d,%d,%d"%(date,step,0,battery_caption)
+        send_len = len(send_data)
+
+        send_data = "SZKW*%s*%04X*%s"%(self.imei,send_len,send_data)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        #print("KA_ProtoCol:send:%s"%(data))
+
+        
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: PING
+        @param msg: 接收到的下行数据
+        """
+        #print("KA_ProtoCol:recv:%s"%(msg))   
+        
+class UD_ProtoCol(ProtoCol):
+    """位置信息"""
+    TYPE = "UD"
+    def send(self, event, msg):
+        #"{:04d}-{:02d}-{:02d}".format(*utime.localtime()[0:3])
+        #[6f62cfc40fc50173f9a7b21e87be3424IS*861217001020120*00f6*UD,220726,211210,A,22.649529,N,114.119165,E,0.28,137.4,100.0,8,24,63,119,0,00000000,2,1,460,11,30472,125667122,24,30472,218944048,19,4,
+        # wifi0,34:93:44:01:28:b9,-74,wifi1,34:20:03:96:35:ad,-78,wifi2,ea:b5:7b:e8:56:54,-80,wifi3,c4:49:bb:d4:d9:78,-88]
+        date = "{:04d}{:02d}{:02d},{:02d}{:02d}{:02d}".format(*utime.localtime()[0:6])
+        date = date[2:]
+        GPS_type = "V"
+        latitude = "0.000000,N"
+        longitude = "0.000000,E"
+        speed = "0.00"
+        direction = "0.0"
+        high = "100.0"
+        number = "0"
+        if msg[0] != [] :#有GPS数据
+            GPS_type = "A"
+            # 纬度
+            latitude = msg[0]["latitude"]
+            # 经度
+            longitude = msg[0]["longitude"]
+            # 速度
+            speed = msg[0]["speed"]
+            # 方向
+            direction = "0"
+            if msg[0]["direction"] :
+                direction = msg[0]["direction"]
+            # 高度
+            high = msg[0]["high"]
+            high_tmp = high.split(".")
+            if len(high_tmp) >= 2 :
+                high = "%s"%(high_tmp[0])
+            # 讯号质量:搜索到的卫星数目
+            number = msg[0]["number"]
+        #gsm 信号强度
+        gsm_sig =  str((100//31)*EventMesh.publish("screen_get_sig"))
+        # 电池电量百分比 
+        bat_tmp = EventMesh.publish("screen_get_battery")
+        battery_caption =  str(bat_tmp[1])
+        #步数
+        old_step = 0
+        step = 0
+        step = EventMesh.publish("get_old_step_value")
+        if step != 0:
+            read_data = EventMesh.publish("get_storage_data")
+            b = str("old_step_new") in read_data.keys()
+            if b == True:
+                old_step = read_data["old_step_new"]
+            else:
+                old_step = 0
+            if old_step !=  step:
+                read_data["old_step"] = step
+                read_data["old_step_new"] = step
+                EventMesh.publish("set_storage_data", read_data)
+                with open("/ext/static/storage_file/config.json","w",encoding="utf-8") as fd:
+                    ujson.dump(read_data,fd)
+        old_step = step
+        # step = str(EventMesh.publish(constants.EVENT.GET_STEP)[0])
+        #翻转次数
+        turn_count = "0"
+        #终端状态
+        state = "00000000"
+        #基站数据
+        CELL_num = len(msg[2])
+        CELL_data = "1," #时延
+        if msg[2] != []:
+            for CELL in msg[2] :
+                if CELL[0] == 0 :
+                    CELL_data += "%X,"%(int(CELL[2])) #MCC
+                    CELL_data += str(CELL[3]) +","#MNC
+                    CELL_data += str(CELL[5]) +","#tac,区域码
+                    CELL_data += str(CELL[1]) +","#基站编号 CID
+                    CELL_data += str(int(CELL[7]+140)) +","#信号强度 rssi
+                else :
+                    CELL_data += str(CELL[5]) +","#tac,区域码
+                    CELL_data += str(CELL[1]) +","#基站编号 CID
+                    CELL_data += str(int(CELL[7]+140)) +","#信号强度 rssi
+            CELL_data = CELL_data[:(len(CELL_data)-1)]
+        #WIFI数据
+        WIFI_num = 0 
+        WIFI_data = ""
+        if msg[1] :
+            WIFI_num = msg[1][0]
+            i = 0
+            for MAC in msg[1][1] :
+                WIFI_data += "wifi%d,%s,%d,"%(i,str(MAC[0]),MAC[1])
+                i += 1
+            WIFI_data = WIFI_data[:(len(WIFI_data)-1)]
+        WIFI_data = WIFI_data.lower()
+        #send_data = "UD ,%s ,%s     ,%s       ,%s       ,%s   ,%s       ,%s  ,%s    ,%s     ,%s             ,%s  ,%s        ,%s   ,%d     ,%s       ,%d      ,%s"\
+        #              %(date,GPS_type,latitude,longitude,speed,direction,high,number,gsm_sig,battery_caption,step,turn_count,state,CELL_num,CELL_data,WIFI_num,WIFI_data)
+        send_data = "UD,%s,%s,%s"%(date,GPS_type,latitude)
+        send_data += ",%s,%s,%s"%(longitude,speed,direction)
+        send_data += ",%s,%s,%s"%(high,number,gsm_sig,)
+        send_data += ",%s,%s,%s"%(battery_caption,step,turn_count)
+        send_data += ",%s,%d,%s"%(state,CELL_num,CELL_data)
+        send_data += ",%d,%s"%(WIFI_num,WIFI_data)
+
+        send_len = len(send_data)
+        wt_data = "%s"%(send_data)
+        send_data = "SZKW*%s*%04X*%s"%(self.imei,send_len,send_data)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+
+
+    
+        #这个是发送WT位置数据到手机端
+        msg_tmp = wt_data.split('UD,')
+        msg_tmp = msg_tmp[1]
+        # print("WT_ProtoCol:msg_tmp:%s"%(msg_tmp))
+        send_data_1 = "SZKW*%s*%04x*WT"%(self.imei,len(msg_tmp))
+        MD5_SIGN_1 = self.pack_MD5_head(send_data_1)
+        data_1 = "[%s%s,%s]"%(str(MD5_SIGN_1),send_data_1,msg_tmp)
+        # print("WT_ProtoCol:send:%s"%(data_1))
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data_1)
+        # 通过socket发送到服务器端
+        
+
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: PING
+        @param msg: 接收到的下行数据
+        """
+        # print("UD_ProtoCol:recv:%s"%(msg))  
+
+class CR_ProtoCol(ProtoCol):
+    """立即定位"""
+    TYPE = "CR"
+
+    def send(self, event, msg):
+        #[SZKWT*YYYYYYYYYYYYYYY*LEN*PING]
+        send_data = "SZKW*%s*0002*CR"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        #print("CR_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: PING
+        @param msg: 接收到的下行数据
+        """
+        EventMesh.publish(constants.PROTOCOL.CR_SEND)
+        EventMesh.publish(constants.EVENT.START_LOCATION) #开始定位
+        #print("CR_ProtoCol:recv:%s"%(msg))   
+        
+class FIND_ProtoCol(ProtoCol):
+    """查找设备"""
+    TYPE = "FIND"
+
+    def send(self, event, msg):
+        #[SZKWT*YYYYYYYYYYYYYYY*LEN*PING]
+        send_data = "SZKW*%s*0004*FIND"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        #print("FIND_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: FIND,播放铃声
+        @param msg: 接收到的下行数据
+        """
+        EventMesh.publish(constants.PROTOCOL.FIND_SEND)
+        # a = audio.Audio(0)
+        # a.set_pa(Pin.GPIO29)
+        # a.setVolume(10)
+        # a.play(1, 1, 'E:/audio_audio_haixiu.mp3')  #文件名前面要加上路径
+        
+        EventMesh.publish("load_screen", {"screen": "FIND"})
+        #print("FIND_ProtoCol:recv:%s"%(msg)) 
+
+class POWEROFF_ProtoCol(ProtoCol):
+    """关机"""
+    TYPE = "POWEROFF"
+
+    def send(self, event, msg):
+        # [SZKW*867387060319491*0008*POWEROFF]
+        send_data = "SZKW*%s*0008*POWEROFF"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        #print("POWEROFF_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: POWEROFF关机
+        @param msg: 接收到的下行数据
+        """
+        EventMesh.publish(constants.PROTOCOL.POWEROFF_SEND)
+        #print("POWEROFF_ProtoCol:recv:%s"%(msg))
+        Power.powerDown()
+         
+class PHL_ProtoCol(ProtoCol):
+    """电话本同步"""
+    TYPE = "PHL"
+
+
+    def send(self, event, msg):
+        # [SZKW*867387060319491*0008*PHL]
+        send_data = "SZKW*%s*0003*PHL"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        #print("POWEROFF_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: 电话本同步
+        @param msg: 接收到的下行数据
+        """
+        msg = msg[1:-1]
+        # print("phonebook:msg:%s\r\n"%msg)
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split(',')
+        # print("phonebook:len:{}\r\n data:{}".format(len(msg_tmp),msg_tmp))
+
+        phonebook = {}
+        msg_tmp = msg_tmp[1:]
+        # print("msg_tmp1:{}".format(msg_tmp))
+        j = 0
+        i = 0
+        phonebook_oldtmp = {}
+        # 0 1 2 3
+        for phonebook_tmp in msg_tmp: 
+            j+=1
+            # print("phonebook_tmp:{}".format(phonebook_tmp))
+
+            if (j%2) == 0:
+                i+=1
+                phonebook_name = UnicodeHexStr_To_Utf8Str(phonebook_tmp)
+                phonebook_name = "{}:{}".format("%03d"%i,phonebook_name)                                      
+                phonebook[phonebook_name] = phonebook_oldtmp
+                
+            phonebook_oldtmp = phonebook_tmp
+            # print("phonebook_oldtmp!!!:{}".format(str(phonebook_oldtmp)))
+        # print("phonebook!!!:{}".format(str(phonebook)))
+        with open("/ext/static/storage_file/phonebook.json","w",encoding="utf-8") as fd:
+            ujson.dump(phonebook,fd)
+            print("创建电话簿")
+        
+        EventMesh.publish(constants.PROTOCOL.PHL_SEND)
+        EventMesh.publish("set_phonebook_list",[1,phonebook])
+        EventMesh.publish("contact_updata_list_show")
+
+         
+class WT_ProtoCol(ProtoCol):
+    """天气数据"""
+    TYPE = "WT"
+
+
+    def send(self, event, msg):
+        # [SZKW*867387060319491*0008*WT]
+        send_data = "SZKW*%s*003*WT"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        # print("WT_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+
+        @param event: T天气温度数据下发
+        @param msg: 接收到的下行数据
+        """
+        # b'SZKW*860132060004322*0035*WT,23-04-06,14:41:06,b6e0d4c6,1,27,-1,40,6DF157335E02'
+        msg = msg[1:-1]
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split('WT,')
+        # print("phonebook:len:{}\r\n data:{}".format(len(msg_tmp),msg_tmp))
+        msg_tmp = msg_tmp[1]
+
+        # print("msg_tmp :%s"%(msg_tmp))
+
+        msg_date = msg_tmp.split(',')[0]
+
+        msg_time = msg_tmp.split(',')[1]
+        msg_weather_content = msg_tmp.split(',')[2]
+        msg_type = msg_tmp.split(',')[3]
+        msg_temp = msg_tmp.split(',')[4]
+        msg_min_temp = msg_tmp.split(',')[5]
+        msg_max_temp = msg_tmp.split(',')[6]
+        msg_city = msg_tmp.split(',')[7]
+
+        msg_city = UnicodeHexStr_To_Utf8Str(msg_city)
+        msg_weather_content = UnicodeHexStr_To_Utf8Str(msg_weather_content)
+        # print("msg_date:{} msg_time:{} msg_weather_content:{} msg_type:{} msg_temp:{} msg_min_temp:{} msg_max_temp:{} msg_city:{}".format(msg_date,msg_time,\
+        #     msg_weather_content,msg_type,msg_temp,msg_min_temp,msg_max_temp,msg_city))
+        print("WT_ProtoCol RECV msg:%s"%(msg))
+
+        EventMesh.publish("set_weather_data",[msg_date,msg_time,msg_weather_content,msg_type,msg_temp,msg_min_temp,msg_max_temp,msg_city,1])
+        EventMesh.publish("updata_weather_show")
+        EventMesh.publish(constants.PROTOCOL.WT_SEND)
+
+class REMIND_ProtoCol(ProtoCol):
+    """闹钟数据"""
+    TYPE = "REMIND"
+
+
+    def send(self, event, msg):
+        # [SZKW*867387060319491*0008*REMIND]
+        send_data = "SZKW*%s*006*REMIND"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        # print("REMIND_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND, data)
+
+    def recv(self, event, msg):
+        """
+        @param event: 闹钟数据下发
+        @param msg: 接收到的下行数据
+        """
+        # b'SZKW*860132060004322*0035*REMIND,23-04-06,14:41:06,b6e0d4c6,1,27,-1,40,6DF157335E02'
+        # print("REMIND_ProtoCol RECV msg:%s"%(msg))
+        self.alarm_list = []
+
+        msg = msg[1:-1]
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split('REMIND,')
+        msg_tmp = msg_tmp[1]
+        num = 0
+        j=0
+        for j in range(0,3):
+            self.alarm_day = []
+            self.alarm_week = []
+            self.alarm_total_data = []
+            self.alarm_total_data = msg_tmp.split(',')[j]
+
+            b = self.alarm_total_data.find('-')
+            if b != -1:
+                alarm_data = self.alarm_total_data.split('-')#-作为分隔符
+                alarm_switch = int(alarm_data[1])#开关
+                alarm_day_num = int(alarm_data[2])#天
+                alarm_time = alarm_data[0]#时间
+                alarm_time_tmp = alarm_time.split(':')#冒号分隔时间 时 分
+                alarm_time_hour = int(alarm_time_tmp[0])
+                alarm_time_min = int(alarm_time_tmp[1])
+                if alarm_day_num == 3:
+                    self.alarm_week = alarm_data[3]#星期
+
+                if alarm_day_num == 2:#每一天
+                    self.alarm_day = [1,2,3,4,5,6,0]
+                elif alarm_day_num == 3:#自定义
+                    for i in range(0,7):
+                        if self.alarm_week[i] != '0':
+                            self.alarm_day.append(i)
+                self.alarm_list.append({"idx": num, "hour": alarm_time_hour, "minute": alarm_time_min, "days": self.alarm_day, "enabled": alarm_switch,"repeart":alarm_day_num})
+                with open("/ext/static/storage_file/alarm_msg.json", 'w',encoding='utf-8') as fd:
+                    ujson.dump(self.alarm_list,fd) 
+                num+=1
+                if num >= 2:
+                    num = 2
+        EventMesh.publish("push_update_alarm_show")
+        EventMesh.publish(constants.PROTOCOL.REMIND_SEND)
+
+class HRSTART_ProtoCol(ProtoCol):
+    """心率频率数据"""
+    TYPE = "hrtstart"
+
+
+    def send(self, event, msg):
+        # [SZKW*867387060319491*0008*hrtstart]
+        send_data = "SZKW*%s*008*hrtstart"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        # print("HRSTART_ProtoCol:send:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event: 心率数据下发
+        @param msg: 接收到的下行数据
+        """
+        # b'SZKW*860132060004322*0035*REMIND,23-04-06,14:41:06,b6e0d4c6,1,27,-1,40,6DF157335E02'
+        # print("REMIND_ProtoCol RECV msg:%s"%(msg))
+        # HRSTART_ProtoCol RECV msg:b'SZKW*860132060004322*000D*hrtstart,7200' msg_:7200
+        msg = msg[1:-1]
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split(',')
+        msg_tmp = msg_tmp[1]
+        # print("HRSTART_ProtoCol RECV msg:{} msg_:{}".format(msg,msg_tmp))
+        hrTotal = int(msg_tmp)
+        if hrTotal == 1:#单次测量
+            get_hr_state = EventMesh.publish("get_hr_state")
+            get_spo2_state = EventMesh.publish("get_spo2_state")
+            if (get_spo2_state == 3) or (get_spo2_state == 0 and get_hr_state == 0):#只要两个不在测量 单次优先级最低
+                EventMesh.publish("set_hr_state",3)#3代表单次测量
+        elif hrTotal > 1:
+            if hrTotal <= 300:
+                hrTotal = 300
+            storage_tmp = EventMesh.publish("get_storage_data")
+            storage_tmp["measure_time"] = hrTotal
+            EventMesh.publish("set_storage_data", storage_tmp)
+            with open("/ext/static/storage_file/config.json","w",encoding="utf-8") as fd:
+                ujson.dump(storage_tmp,fd)
+                
+            EventMesh.publish("set_time_hr_spo2",hrTotal)
+       
+        EventMesh.publish(constants.PROTOCOL.HRTSTART_SEND)
+
+class HEART_ProtoCol(ProtoCol):
+    """心率数据"""
+    TYPE = "heart"
+
+
+    def send(self, event, msg):
+        # [SZKW*334588000000156*len*heart,x]
+        # print("HEART:send:{}".format(msg))
+        len_size = len(str(msg))+6
+        send_data = "SZKW*%s*%04X*heart"%(self.imei,len_size)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s,%d]"%(str(MD5_SIGN),send_data,msg)
+        # print("HEART_ProtoCol:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event: 心率数据下发
+        @param msg: 接收到的下行数据
+        """
+        # print("HRSTART_ProtoCol RECV msg:")
+        #EventMesh.publish(constants.PROTOCOL.HEART_SEND)
+class OXYGEN_ProtoCol(ProtoCol):
+    """上传血氧测试数据"""
+    TYPE = "oxygen"
+    def send(self, event, msg):
+        # [SZKW*334588000000156*len*heart,x]
+        # print("oxstart:send:{}".format(msg))
+        len_size = len(str(msg))+6
+        send_data = "SZKW*%s*%04X*oxygen"%(self.imei,len_size)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s,%d]"%(str(MD5_SIGN),send_data,msg)
+        # print("HEART_ProtoCol:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event: 心率数据下发
+        @param msg: 接收到的下行数据
+        """
+        # print("HRSTART_ProtoCol RECV msg:")
+        #EventMesh.publish(constants.PROTOCOL.OXYGEN_SEND)
+
+class OXYGEN_One_ProtoCol(ProtoCol):#单次测量
+    """上传单次测量测试数据"""
+    TYPE = "oxstart"
+
+# 终端发送[XT*YYYYYYYYYYYYYYY*LEN*oxygen,x]
+# x 表示血氧饱和度
+# 示例[XT*334588000000156*0009*oxygen,15]
+# 平台回复:handler -> b'[SZKW*860132060004322*0009*oxstart,1]'
+# [XT*334588000000156*0006*oxygen]
+    def send(self, event, msg):
+        # [SZKW*334588000000156*len*heart,x]
+        print("oxstart:")
+        send_data = "SZKW*%s*0007*oxstart"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        # print("HEART_ProtoCol:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event: 血氧单次测量下发
+        @param msg: 接收到的下行数据
+        """
+        print("oxstart:{}".format(msg))
+        msg = msg[1:-1]
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split(',')
+        msg_tmp = msg_tmp[1]
+        state = int(msg_tmp)
+        get_hr_state = EventMesh.publish("get_hr_state")
+        get_spo2_state = EventMesh.publish("get_spo2_state")
+        if state == 1:
+            if (get_hr_state == 3 ) or (get_spo2_state == 0 and get_hr_state == 0):#只要两个不在测量 单次优先级最低
+                EventMesh.publish("set_spo2_state",3)#3代表单次测量
+        EventMesh.publish(constants.PROTOCOL.OXSTART_SEND)
+
+class TEMP_ProtoCol(ProtoCol):
+    """上传体温测试数据"""
+    TYPE = "temp"
+    def send(self, event, msg):
+        # [SZKW*334588000000156*len*heart,x]
+        # print("temp:send:{}".format(msg))
+        len_size = len(str(msg))+5
+        #  实例:[XT*334588000000156*0009*temp,36.2]
+        # 代表终端的温度为:36.2
+        # 平台回复:
+        # [XT*334588000000156*0004*temp]
+        send_data = "SZKW*%s*%04X*temp"%(self.imei,len_size)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s,%d.%d]"%(str(MD5_SIGN),send_data,msg[0],msg[1])
+        # print("temp:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event: 心率数据下发
+        @param msg: 接收到的下行数据
+        """
+        # print("HRSTART_ProtoCol RECV msg:")
+        #EventMesh.publish(constants.PROTOCOL.TEMP_SEND)
+
+#解绑
+# [XT*334588000000156*0003*DLT]
+def reset_factory(msg):
+    if msg == 1:
+        Power.powerRestart()
+class DLT_ProtoCol(ProtoCol):
+    """解绑数据"""
+    TYPE = "DLT"
+    def send(self, event, msg):
+        # [XT*334588000000156*0004*temp]
+        send_data = "SZKW*%s*0003*DLT"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        print("temp:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event:
+        @param msg: 接收到的下行数据
+        """
+        # print("DLT_ProtoCol RECV msg:")
+        reset_factory(1)
+
+#定位频率
+class UPLOAD_ProtoCol(ProtoCol):
+    """定位频率数据"""
+    TYPE = "UPLOAD"
+    def send(self, event, msg):
+        # [XT*334588000000156*0004*temp]
+        send_data = "SZKW*%s*0006*UPLOAD"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event:
+        @param msg: 接收到的下行数据
+        """
+        # b'[SZKW*867387060319166*000A*UPLOAD,600]'
+        # print("DLT_ProtoCol RECV msg:".format(msg))
+        msg = msg[1:-1]
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split(',')
+        msg_tmp = msg_tmp[1]
+        upload_time = int(msg_tmp)
+        storage_tmp = EventMesh.publish("get_storage_data")
+        storage_tmp["upload_time"] = upload_time
+        EventMesh.publish("set_storage_data", storage_tmp)
+        EventMesh.publish("set_upload_data", upload_time)
+        with open("/ext/static/storage_file/config.json","w",encoding="utf-8") as fd:
+            ujson.dump(storage_tmp,fd)
+        EventMesh.publish(constants.PROTOCOL.UPLOAD_SEND)
+
+#设置快捷号码
+class CENTER_ProtoCol(ProtoCol):
+    """设置快捷号码"""
+    TYPE = "CENTER"
+    def send(self, event, msg):
+        # [XT*334588000000156*0004*temp]
+        send_data = "SZKW*%s*0006*CENTER"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        print("UPLOAD:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event:
+        @param msg: 接收到的下行数据
+        """
+        # b'[SZKW*867387060319166*000A*UPLOAD,600]'
+        # print("DLT_ProtoCol RECV msg:".format(msg))
+        msg = msg[1:-1]
+        msg_tmp = msg.decode('ascii')
+        msg_tmp = msg_tmp.split(',')
+        msg_tmp = msg_tmp[1]
+        print("CENTER_ProtoCol RECV msg:{} msg_:{}".format(msg,msg_tmp))
+        center_dial = str(msg_tmp)
+        storage_tmp = EventMesh.publish("get_storage_data")
+        storage_tmp["center_dial"] = center_dial
+        EventMesh.publish("set_storage_data", storage_tmp)
+        with open("/ext/static/storage_file/config.json","w",encoding="utf-8") as fd:
+            ujson.dump(storage_tmp,fd)
+        EventMesh.publish(constants.PROTOCOL.CENTER_SEND)  
+
+#呼叫快捷电话号码
+import voiceCall
+class MONITOR_ProtoCol(ProtoCol):
+    """呼叫快捷号码"""
+    TYPE = "MONITOR"
+    def send(self, event, msg):
+        # [XT*334588000000156*0004*MONITOR]
+        send_data = "SZKW*%s*0007*MONITOR"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        print("MONITOR:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event:
+        @param msg: 接收到的下行数据
+        """
+        # b'[SZKW*867387060319166*000A*MONITOR]'
+        self.read_data = {}
+        self.read_data = EventMesh.publish("get_storage_data")
+        if self.read_data != {}:
+            b = str("center_dial") in self.read_data.keys()
+            if b == True:
+                contact = self.read_data["center_dial"]
+                if len(contact) > 0:
+                    print("MONITOR RECV msg:{} {}".format(contact,type(contact)))
+                    EventMesh.publish("save_phonename", contact)  
+                    EventMesh.publish("save_phonenum", contact)  
+                    voiceCall.callStart(contact)
+        EventMesh.publish(constants.PROTOCOL.MONITOR_SEND)  
+  
+#SOS紧急电话
+class SOS_ProtoCol(ProtoCol):
+    """紧急呼叫"""
+    TYPE = "SOS"
+    def send(self, event, msg):
+        # [XT*334588000000156*0004*MONITOR]
+        send_data = "SZKW*%s*0003*SOS"%(self.imei)
+        MD5_SIGN = self.pack_MD5_head(send_data)
+        data = "[%s%s]"%(str(MD5_SIGN),send_data)
+        print("SOS:data:%s"%(data))
+        # 通过socket发送到服务器端
+        EventMesh.publish(constants.EVENT.CHANNEL_SOCKET_SEND,data)
+
+    def recv(self, event, msg):
+        """
+        @param event:
+        @param msg: 接收到的下行数据
+        """
+        # b'[SZKW*867387060319166*000A*SOS_SEND]'
+        self.read_data = {}
+        self.read_data = EventMesh.publish("get_storage_data")
+        if self.read_data != {}:
+            b = str("center_dial") in self.read_data.keys()
+            if b == True:
+                sos_dial = self.read_data["center_dial"]
+                if len(sos_dial) > 0:
+                    pass
+                    # print("SOS RECV msg:{} {}".format(sos_dial,type(sos_dial)))
+                    # EventMesh.publish("save_phonename", sos_dial)  
+                    # voiceCall.callStart(sos_dial)
+        EventMesh.publish(constants.PROTOCOL.SOS_SEND)  
+  
+
+class ProtoColResolver(object):
+    def __init__(self):
+        self.protocol_list = []
+
+    def add_support(self, prot):
+        self.protocol_list.append(prot)
+        prot.initialization()
+
+    def handler(self, data):
+        # 这里接收数据
+        
+        # print("handler -> {}".format(data))
+        # if data.startswith('Init;'):
+        #     data = data[5:]
+        #     EventMesh.publish(constants.EVENT.SET_KEY, {"value": ujson.loads(data)['KEY']})
+            
+        # elif data.startswith("Update;"):
+        #     data = data[7:]
+        #     EventMesh.publish(constants.PROTOCOL.H04_RECV, data)
+        print("handler:{}".format(type(data)))
+        data_tmp = data.decode('ascii')
+        data_tmp = data_tmp.split(']')[0] #去掉]
+        ProtoCol_type = data_tmp.split('*')[3] #拿到协议标识
+        ProtoCol_type = ProtoCol_type.split(',')[0]
+        ProtoCol_type = "%s_RECV"%(ProtoCol_type)
+        # print("ProtoColResolver:ProtoCol_type:%s\r\ndata:%s"%(ProtoCol_type,data))
+        EventMesh.publish(ProtoCol_type, data) #返回协议read
index acf2226..4401a71 100644 (file)
@@ -2256,7 +2256,7 @@ class TemperatureScreen(Screen):
     def __init__(self):
         super().__init__()
         self.meta = None
-
+        self.temp_timer = osTimer()
     def initialization(self):
         global temperature_screen,temperature_bg_img ,temperature_body_label ,temperature_degree_img ,temperature_value_label,\
             temperature_wrist_label,temperature_wrist_degree_img ,temperature_wrist_value_label  
@@ -2314,7 +2314,15 @@ class TemperatureScreen(Screen):
             temperature_wrist_value_label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
             temperature_wrist_value_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
             self.meta = temperature_screen
-
+        print("START_TEMP:{}".format(EventMesh.publish(constants.EVENT.START_TEMP)))
+        self.temp_timer.start(1*1000, 1, self.temp_timerout)
+    def temp_timerout(self,*args):
+        temp = EventMesh.publish(constants.EVENT.GET_TEMP) 
+        print("temp:{}".format(temp))   
+        temperature_value_label.set_text("{}".format(temp))
+    def Close(self):
+        print("STOP_TEMP:{}".format(EventMesh.publish(constants.EVENT.STOP_TEMP)))
+        self.temp_timer.stop()
     def done_return(self):
         EventMesh.publish("load_screen", {"screen": "main_menu"})