From ee91bf76d2d483228c1c77c2d7fdfbac246f2550 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Wed, 14 Jan 2026 09:56:04 +0800 Subject: [PATCH] 'commit' --- Apps/TeLaiDian/Config/Setting.py | 4 +- Apps/TeLaiDian/Crawler.py | 103 ++++++++++++++---- Apps/TeLaiDian/Kit.py | 58 ++++++++++ Apps/TeLaiDian/ReadImageKit.py | 36 ++++-- Apps/TeLaiDian/Service.py | 56 ++++++++-- Apps/TeLaiDian/Template/jgxx.jpg | Bin 6811 -> 13051 bytes .../__pycache__/Setting.cpython-310.pyc | Bin 514 -> 559 bytes .../__pycache__/Crawler.cpython-310.pyc | Bin 5515 -> 7087 bytes .../TelaiDian/__pycache__/Kit.cpython-310.pyc | Bin 6754 -> 8187 bytes .../__pycache__/ReadImageKit.cpython-310.pyc | Bin 5327 -> 6083 bytes .../__pycache__/Service.cpython-310.pyc | Bin 2963 -> 3597 bytes Model/StationStatus.py | 38 +++---- .../__pycache__/StationStatus.cpython-310.pyc | Bin 2648 -> 2774 bytes Tools/Sql/doris_ddl.sql | 5 +- 14 files changed, 233 insertions(+), 67 deletions(-) diff --git a/Apps/TeLaiDian/Config/Setting.py b/Apps/TeLaiDian/Config/Setting.py index 2611a60..7f5772c 100644 --- a/Apps/TeLaiDian/Config/Setting.py +++ b/Apps/TeLaiDian/Config/Setting.py @@ -10,8 +10,8 @@ DEBUG_BOX_COLOR = (0, 255, 0) DEBUG_BOX_THICKNESS = 3 # 等待时间配置 (秒) -WAIT_DETAIL_PAGE_LOAD = 2.0 -WAIT_BACK_TO_LIST = 1.0 +WAIT_DETAIL_PAGE_LOAD = 3.5 +WAIT_BACK_TO_LIST = 1.5 WAIT_AFTER_SCROLL = 2.5 # 坐标计算与安全防护 diff --git a/Apps/TeLaiDian/Crawler.py b/Apps/TeLaiDian/Crawler.py index 30ce41b..d0fe76e 100644 --- a/Apps/TeLaiDian/Crawler.py +++ b/Apps/TeLaiDian/Crawler.py @@ -1,10 +1,14 @@ # coding=utf-8 import asyncio -import logging +import asyncio import os import sys import time -from Apps.TeLaiDian.Kit import take_screenshot, get_image_content_md5, clean_station_name, setup_logger +import cv2 +from Apps.TeLaiDian.Kit import ( + take_screenshot, get_image_content_md5, clean_station_name, + setup_logger, detect_price_click_point_cv, read_image, save_image +) from Apps.TeLaiDian.ReadImageKit import ReadImageKit from Apps.TeLaiDian.Service import TeLaiDianService from Apps.TeLaiDian.Config.Setting import ( @@ -120,37 +124,92 @@ class TeLaiDianCrawler(BaseCrawler): d.swipe_ext("up", scale=DETAIL_SCROLL_DISTANCE_RATIO) await asyncio.sleep(1.5) - # 3. 点击“价格信息”按钮 (jgxx.jpg) - template_path = os.path.join(project_root, "Apps", "TeLaiDian", "Template", "jgxx.jpg") - logger.info(f"尝试点击价格详情按钮: {template_path}") + # 3. 点击“价格信息”区域 (识别橘红色价格 P0) + price_button_screen = take_screenshot(d, f"tld_before_price_click_{int(time.time())}.jpg") + logger.info("正在通过 CV 寻找橘红色价格区域 (P0)...") + + click_point = detect_price_click_point_cv(price_button_screen) + + # 调试:生成点击点标注图 + if click_point: + debug_flag_path = price_button_screen.replace(".jpg", "_click_debug.jpg") + img_debug = read_image(price_button_screen) + if img_debug is not None: + cv2.circle(img_debug, (click_point[0], click_point[1]), 20, (0, 0, 255), -1) # 红色大圆点 + cv2.line(img_debug, (click_point[0]-40, click_point[1]), (click_point[0]+40, click_point[1]), (255, 255, 255), 3) + cv2.line(img_debug, (click_point[0], click_point[1]-40), (click_point[0], click_point[1]+40), (255, 255, 255), 3) + save_image(debug_flag_path, img_debug) + logger.info(f"点击点调试图已保存: {debug_flag_path}") try: - # 使用 uiautomator2 的图像识别点击 - match = d.image.match(template_path) - if match: - logger.info(f"找到价格按钮,坐标: {match['point']}") - d.image.click(template_path) + if click_point: + logger.info(f"CV 成功定位价格区域,点击坐标: {click_point}") + d.click(click_point[0], click_point[1]) await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD) else: - logger.warning("未找到价格按钮模板,尝试备选方案:直接点击屏幕下方区域") - # 备选方案:如果模板匹配失败,尝试点击屏幕中下方 - w, h = d.window_size() - d.click(w // 2, int(h * 0.8)) + logger.warning("CV 未能定位价格区域,尝试模板匹配兜底...") + template_path = os.path.join(project_root, "Apps", "TeLaiDian", "Template", "jgxx.jpg") + match = d.image.match(template_path) + if match: + d.image.click(template_path) + else: + logger.warning("模板匹配也失败,执行坐标兜底...") + w, h = d.window_size() + d.click(w // 2, int(h * 0.45)) # 滑动后价格通常在屏幕中上部 await asyncio.sleep(WAIT_DETAIL_PAGE_LOAD) except Exception as e: - logger.error(f"点击价格按钮失败: {e}") + logger.error(f"点击价格区域失败: {e}") + finally: + if os.path.exists(price_button_screen): os.remove(price_button_screen) - # 4. 截图并分析价格表 - price_screen_path = take_screenshot(d, f"tld_detail_price_{int(time.time())}.jpg") - prices = await self.read_image_kit.analyze_detail_price(price_screen_path) + # 4. 循环滑动抓取完整分时电价 + all_prices = [] + last_price_md5 = None + price_page_count = 0 + max_price_pages = 3 # 分时电价通常不会超过3页 + + logger.info("开始循环滑动抓取完整分时电价...") + while price_page_count < max_price_pages: + price_screen_path = take_screenshot(d, f"tld_detail_price_{int(time.time())}.jpg") + + # 校验页面是否发生滚动变化 + curr_md5 = get_image_content_md5(price_screen_path, top_ratio=0.2, bottom_ratio=0.2) + if curr_md5 == last_price_md5: + logger.info("价格页面内容无变化,判定已触底") + if os.path.exists(price_screen_path): os.remove(price_screen_path) + break + last_price_md5 = curr_md5 + + logger.info(f"正在分析价格详情页第 {price_page_count + 1} 页: {price_screen_path}") + page_prices = await self.read_image_kit.analyze_detail_price(price_screen_path) + + if page_prices: + # 简单去重:根据时段合并 + for p in page_prices: + if p not in all_prices: + all_prices.append(p) + + # 向上滑动一点点,继续抓取 + d.swipe_ext("up", scale=0.6) + await asyncio.sleep(1.5) + price_page_count += 1 + + # 清理临时截图 + if os.path.exists(price_screen_path): os.remove(price_screen_path) + # 5. 保存数据 - if prices: + if all_prices: station_name_clean = clean_station_name(station_name) - logger.info(f"场站 {station_name_clean} 提取到 {len(prices)} 条价格信息,准备保存...") - await self.service.save_station_data(station_name_clean, address, prices) + # 对价格按时间排序 + try: + all_prices.sort(key=lambda x: x.get('start', '00:00')) + except: + pass + logger.info(f"✅ 场站 {station_name_clean} 共提取到 {len(all_prices)} 条价格信息,准备保存...") + await self.service.save_station_data(station_name_clean, address, all_prices) else: - logger.warning(f"未能从 {price_screen_path} 提取到价格信息") + logger.warning(f"❌ 未能提取到任何价格信息,请检查页面识别逻辑") # 清理临时截图 for p in [first_screen_path, price_screen_path]: diff --git a/Apps/TeLaiDian/Kit.py b/Apps/TeLaiDian/Kit.py index 38a3c3d..6377f22 100644 --- a/Apps/TeLaiDian/Kit.py +++ b/Apps/TeLaiDian/Kit.py @@ -93,6 +93,64 @@ def save_image(path, img): logger.error(f"Error saving image {path}: {e}") return False +def detect_price_click_point_cv(image_path): + """ + 使用 HSV 颜色过滤定位详情页的橘红色价格区域,返回最左侧区域的中心点击点 + """ + img = read_image(image_path) + if img is None: + return None + + h, w = img.shape[:2] + # 1. 转换为 HSV 空间 + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + + # 2. 橘红色的 HSV 范围 (适配特来电价格颜色) + lower_orange = np.array([0, 150, 150]) + upper_orange = np.array([20, 255, 255]) + mask = cv2.inRange(hsv, lower_orange, upper_orange) + + # 3. 对掩码进行膨胀,连接数字 + kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 20)) + dilated = cv2.dilate(mask, kernel) + + # 4. 寻找轮廓 + contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + + detected_areas = [] + for cnt in contours: + x, y, cw, ch = cv2.boundingRect(cnt) + # 1. 过滤掉宽度过大(可能是横幅广告)或过小(可能是杂点)的区域 + # 2. 价格区域 P0 通常在屏幕的中部,且宽度约为屏幕的一半 + if 200 < y < h * 0.8 and 100 < cw < w * 0.6 and ch > 30: + detected_areas.append([x, y, x + cw, y + ch]) + + if not detected_areas: + # 备选:如果 HSV 失败,尝试通过轮廓大小寻找 + # 1.1556 这种大数字通常会有很明显的轮廓 + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) + kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10)) + closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) + contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + for cnt in contours: + x, y, cw, ch = cv2.boundingRect(cnt) + if 200 < y < h * 0.6 and 150 < cw < 300 and 50 < ch < 150: + detected_areas.append([x, y, x + cw, y + ch]) + + if not detected_areas: + return None + + # 5. 按 X 轴排序,取最左边的区域 (即用户确认的 P0) + # 但要排除掉可能在最左侧的导航栏返回按钮等小元素,所以前面加了宽度限制 + detected_areas.sort(key=lambda b: b[0]) + target = detected_areas[0] + + center_x = (target[0] + target[2]) // 2 + center_y = (target[1] + target[3]) // 2 + + return [center_x, center_y] + def detect_cards_cv(image_path, top_ratio=0.40, bottom_ratio=0.12): """ 使用计算机图形学 (OpenCV) 检测列表中的场站卡片。 diff --git a/Apps/TeLaiDian/ReadImageKit.py b/Apps/TeLaiDian/ReadImageKit.py index f4c86e5..6370dd5 100644 --- a/Apps/TeLaiDian/ReadImageKit.py +++ b/Apps/TeLaiDian/ReadImageKit.py @@ -22,27 +22,43 @@ class ReadImageKit: async def analyze_detail_price(self, image_path): """ - 分析详情页截图,提取电价信息 + 分析详情页截图,提取电价信息,包括优惠价、PLUS价和挂牌价 """ prompt = """ - 分析这张充电站详情页截图,提取**电价时段表**。 - 请仔细寻找包含“时段”、“电价”、“服务费”或“总价”的表格或列表。 + 分析这张充电站价格详情页截图,提取**分时电价表**。 + 对于每个时段,请识别并提取以下所有价格信息(如果存在): + 1. 优惠价 (通常是红色或加粗的大字,作为默认 price) + 2. PLUS会员价 (标有 "PLUS" 标签的价格) + 3. 挂牌价 (标有 "挂牌价" 标签的价格) + 4. 电费 (Base electricity price) + 5. 服务费 (Service fee) 请提取每个时段的: - 1. 开始时间 (HH:MM) - 2. 结束时间 (HH:MM) - 3. 总电价 (元/度,包含电费和服务费) + - start: 开始时间 (HH:MM) + - end: 结束时间 (HH:MM) + - price: 优惠价 (元/度) + - plus_price: PLUS会员价 (元/度) + - market_price: 挂牌价 (元/度) + - elec_price: 电费 (元/度) + - service_price: 服务费 (元/度) 输出格式为 JSON 数组: [ { - "start": "00:00", - "end": "08:00", - "price": 1.23 + "start": "16:00", + "end": "21:00", + "price": 1.3435, + "plus_price": 1.3035, + "market_price": 1.4435, + "elec_price": 0.9435, + "service_price": 0.4000 }, ... ] - 如果无法识别任何价格信息,请返回空数组 []。 + 注意: + - 如果某个字段缺失,请设为 null。 + - 确保 price 包含电费和服务费的总和。 + - 如果无法识别任何价格信息,请返回空数组 []。 """ try: res_text = await self.vlm.analyze_image(image_path, prompt) diff --git a/Apps/TeLaiDian/Service.py b/Apps/TeLaiDian/Service.py index 1c39e53..54fd1b1 100644 --- a/Apps/TeLaiDian/Service.py +++ b/Apps/TeLaiDian/Service.py @@ -52,18 +52,38 @@ class TeLaiDianService: now = datetime.now() # 将价格转换为 24 小时的 schedule 格式 (0-23) - hourly_schedule = [0.0] * 24 + # 每个小时存储一个包含多重价格的字典,以记录优惠价、PLUS价和挂牌价 + hourly_schedule = [None] * 24 for p in prices: try: - start_hour = int(p['start'].split(':')[0]) - end_hour = int(p['end'].split(':')[0]) - price = float(p['price']) + start_parts = p['start'].split(':') + end_parts = p['end'].split(':') + start_hour = int(start_parts[0]) + end_hour = int(end_parts[0]) - # 处理跨天的情况(如 23:00 - 01:00) + # 处理 00:00 作为结束时间的情况 (表示 24:00) + if end_hour == 0 and (int(end_parts[1]) == 0 if len(end_parts) > 1 else True): + if start_hour != 0: + end_hour = 24 + + # 提取各项价格 + price_data = { + "price": float(p.get('price')) if p.get('price') is not None else 0.0, + "plus_price": float(p.get('plus_price')) if p.get('plus_price') is not None else None, + "market_price": float(p.get('market_price')) if p.get('market_price') is not None else None, + "elec_price": float(p.get('elec_price')) if p.get('elec_price') is not None else None, + "service_price": float(p.get('service_price')) if p.get('service_price') is not None else None + } + + # 填充对应的小时槽位 curr = start_hour - while curr != end_hour: - hourly_schedule[curr] = price - curr = (curr + 1) % 24 + # 如果是跨天的,比如 23:00 - 01:00 + if end_hour < start_hour: + end_hour += 24 + + while curr < end_hour: + hourly_schedule[curr % 24] = price_data + curr += 1 except Exception as e: logger.error(f"解析价格时段失败: {p}, error: {e}") @@ -80,7 +100,7 @@ class TeLaiDianService: valid_start_time=now ) - # 2. 保存价格 + # 2. 保存价格计划 schedule_id = self.generate_id() await self.station_price_schedule_model.save( session=session, @@ -89,6 +109,24 @@ class TeLaiDianService: schedule_json=hourly_schedule, valid_start_time=now ) + + # 3. 保存当前状态快照 (包含当前小时的价格) + current_hour = now.hour + current_price_info = hourly_schedule[current_hour] or {} + + status_id = self.generate_id() + await self.station_status_model.save( + session=session, + id=status_id, + station_hash=station_hash, + total_piles=None, # 特来电暂时没抓取总桩数 + free_piles=None, + piles_detail_json=None, + current_price=current_price_info.get('price'), + pro_price=current_price_info.get('plus_price'), + market_price=current_price_info.get('market_price'), + valid_start_time=now + ) await session.commit() logger.info(f"成功保存场站数据: {station_name}") diff --git a/Apps/TeLaiDian/Template/jgxx.jpg b/Apps/TeLaiDian/Template/jgxx.jpg index 14832c0642ed1614364f9aa75781a1241dc03374..04b9789d80ef8bfeac98a6418e0aa5c606f84da3 100644 GIT binary patch literal 13051 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 EKTlu`2mk;8 diff --git a/Apps/TelaiDian/Config/__pycache__/Setting.cpython-310.pyc b/Apps/TelaiDian/Config/__pycache__/Setting.cpython-310.pyc index a88fd32e75a8004eca6440c0a60c9384f6b195cf..ce7032e8abe9b15aaf8eb54dc2bc46dc79f86309 100644 GIT binary patch delta 196 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 diff --git a/Apps/TelaiDian/__pycache__/Kit.cpython-310.pyc b/Apps/TelaiDian/__pycache__/Kit.cpython-310.pyc index e7627b992eeee2dc4510aeb4b3ffffcb6726c37a..9d6e5450b8699a1e649d0a386bf3712059fbfd62 100644 GIT binary patch delta 2544 zcmai$Yit}>6@cf?%4phLlc|ZpU-S>-9cn zxjXB|(M-3(u2Q5{V5T526}7FZv=UH(6%~@UsrUn`s*0azg!oZxC;JOk=?^4?;G9|8 zX(A-Xns3iJ_i^r-d(OT7K&pp|)VDyC5cSi* z0;hy&@1m8xKStxA#OQ9CqG@Q3(;nJEJ3&f-l%ZW9CFvg8O?QEmqGW>0_5J1#(Ew4L zKL-YT6={kYm8oJ`SA30P)$Di0dhw#}3fk-uW$lo3hLC>eVz8(GL0FO^6)SpGGpMfk zO#=t9hrrApMhpOQB8#E?C4ejF7fg1{`8YVx90FYb;3#B=3!ELXLdUuD{dN?3$X0ZP zoD*%?j@fZLLH$-t{x&0CS> zm?c~I#xorJCNf+>Tp>7t6{&v)F57X&VTno55>}FiVSymeq-cclD}Fl#_I6Owt)S8t z*k(E)Fu_hkYuExpV9n1(=0!E|f1>&bqViVGZhBE&rm)bhsQyA@5bd@-ZY8$t>r}pF zzdgX_Z4q9E2>a;Qi9uhj!V30?lK6uvOyLSDRH~UUaob79^zIx+(zrAto(q{AO>l?pbT7U258*jg{ zIsZay%aTe#>C+bGL{1ogIZLibQa+yuNg zv92tRk}Rk>eiYW$gfRiIzC~Oz=}B#1Pu2_gA-p$n0*SkLnChmknfV$kYIs1wCI=&1vsY zV%{zs1(%92U7uAVW#d_$#t8C#2nrucxDgX~e~V&uS4b_S-$Ov3$bFK%>4!n|TTiS$R* z9^*LYuaW%{dmOZ3cG?L=@6sCB^7*6y^_yrrk2s8Y8j(jlgE)(L0-+)%5#L5UiBJ$v zAc2K5;huUtpR0=sor$n zPn;mf95K0%{LQ&Lc|TcLdpa4xyS$Wo_^vxHZ6E8z`SHMEJ%|GcxVck%$-kXXQ#tbD z+OBj-fYFySKT5b#T{lPcS-tFvr$>j!T<37tJ>PPpOs^QT`YE+aVa4nc&Vi0xADkpm z6v1JGRa6sl-HlF|P%M?Lu5JY8yVV#{Dcx>ye%aMaT<62CL-)E8GYm6Ni%bbX#iQT` zrnj6OLqEZ(Z3nF4?9cA!W#T-N9VV;JVz#4M$Mu*1NaW#Mn#rhtAF&6Z_^ORcZO%K4 zyscnA0IMtI^HsH?=kx7Bf~q1)gj6IB$q4=et`$O-IB+Qv;(|DEKnO;hI3W4P9jfx4-3p0a?Z@AF@Ax)tn?-i{ifGqD%tS@aYZE} z?|r7??(VGWUe<4r`K!=Gqh3vO69gXtC_QSoJi+z^ul1Ln&jL53Or=DKUVH&d7ZKOw zx9M@REPqMY$ZGf2v8I;qJ%dDV7_imsUw_U^CtIA0bO_y#QBsUSms*3LL4zScl_;{= zR|8-nF9SY>C(;1AJei+1pf0|{_Uk<=SMoEnYgl#`aSk!))!h|KVJqayTv}gS->|Q( zY|O4~EZ*Vgp+-J2m*ku|CCNxhZkyMWi74bk{**6$pbXD^#5TWxeisq_cU(d> zi+B}aCAPS;Z>2@pwp*U>2`jT13K9CxS1B-H(Y8wMFdnd$O1Z5tV${;zFc4vfM~c{1 z(sekEEYtS_8>PHGHd=sf34|hhitH=ReGi^(MLZ=x9;=ai^82y7B3w9U@)jOXRdI9E!a(*40P#n7Z$5nyMP$% zFR1D;Z^DmCwL>^Uku@B4M7tvfqZ0D%!W(b^J};aiU&wC?uaO7czX};buF9v!=Vt!r zl;jg=jfaDm5T_B#@?LR@d?!CDR>{Neg$$#QasYjKB|;*%V?NxzHs7!{JJu&{T!3OSL(NpAXz1is>WXd)d%P|QNM*L4Zf)S;EQ^M z!AXEh1|7e>&tJy?9#;MdMs?c`9G}@XUzB^3e8Bq1Sg*dU)LLCYsIE$XTjf2~wO zo{>tb7K1`mXcW}aj+kiT)}=|~j(KlNOk|_DGV#7ne<5`ir*G~%_jh{le69XmyScxl zq-X;?zt_(9+^T%N`FpOWi~PuKG_Oit>b=2+U&)e>T?@#O_sg!U&1cTGz=@7|nRiI> zc;Q@x5|5)fpBVCx7Hljak*2&IPU^nN#@{LT--0bRIa5=!>>5h(X>d^v-(|rOIrIWp zZ0;?jj0NAvf;XxAC0%^SMn>t#13B_c4h=Jpi}^ijX!+wLyBb`T-1PYnd+evPKI)%Y zl{~A`L@Icl5y_G>Q8?1CxF%>Q#C$;|{50ly!`u((?SS%TT$#8|r>5!bIHZ<8_~lS| zCE|XfyqDcz?5;l3^_QX+&sdh%aRTpTM1oYI%x zxK>NU&ocuJ*c@V8g4uk=33HPcFAKf5UATztNr#j^NS}qvl}Iv^5@n%@st$2x1-52N zlwgB8T{(4)WG%lcr@oGC)$VpSm>VnyQvZ8$wsq-lbXHVnY%pbIWi}D#nX^YrHvlY? z@lcwjOJ;;$U1kF~&NQ1$CUQty?_~2c?D|ON#2b*h4(!P&EEJ41ER-UJ>D24QTFouN zc%wdt&6c@^2Bb{R$sZr7BZXk)>F7&URKDfOse;jFt_WCE-vYHv1G%7GDv1`Q`-#q5 z3OY5Kz4H$@{>(YL13oMQ;;@^8j>CQql^hNLRBHwP`4J2pj2vn?m^fI-mtuqF-2AWN zzxmq3+;W8c*>c>e=f^@0+2Zfv7kdGsg}Beri-mSOj^=h_yHLY#)}`N+PTyMCIoQ_G z(SI3>>ndq29<=qg30QR4>|!ffEZwd>%41o`w^F_4(pXubxRJjfpO=@50SE$br)5r-*vNN>nbBtQYi2VZE(ItkZDE>xkwv2O9TPHQ8Aj%&# z%zfO@2;@S{fODVC>3!O@@Wqy$K#^x1(?IGQb^|Q|a-Yv?0b25G!5*Oa(~jwEKn~Ep z$)ap#oQ8S|PxmxDUEV#pj!m4&NN;jEo1BEPo&r!W#C!#fr>)KUPj@YQzo%!i0jI>| zIQA4J0|P4q10@}}i(#HrO3h1AvQkhou$cUWU6IMic=9q1qsj4{dwHX{Qgc$1;|q#1 zlT)KMYjPzsGKy^O<$lLxF98g;A~_Ht4NCwS%9)$H#oXKVJNlEz?sl{k6iQ+EH$&D{cEiTO|DUO=FR#bw`7G#$3nbXouX>8 zh5e_T$hJ)czwaNe`}bORokYTUHkPj7Ms{DC9&^><&?jrO1{B&j6wT~2`SUZbyhC2h zD_+=-h?g6i-Yw#9cyZE^Xq{7!9r8tFGrOd0F3*7z2z=38^Fu%Bk`Movo(CS!eplXj zWr?dtW7K{S#ops0a$P`>ufv0$$=*{}YHd($_k`iA>Zf zPIa&B^j3+2eFSw%^wSar`v_Vq(JxCB z?D2>%ERp)xYHBevwON&!+lYP(yOUo+P%(JGzQ-(9VK$NH(W?k%9WcAV;_t4Z8*K$8 z`t9E^N*#>$8i_G6NrP#35NR^!4*Eu!VvMe#>xf9H^O19-UCg_9w2K(ps!psadJDie z(ONlw)lX{-P3$R3>%effYOKcUOaZ;lFq4={TKifNgCU1tHUMo1W&@ZN;LPo-ha7dQ znKr@OTto+W(DYH-VxuB(4gy;uaE>X^4;ZXf9F3Ua5X21ahNSI%^Dt>`GB+!o?~q6e zQqWkQ;h}Z5+|U7z-`<5T@NpeJ=uw-@!(O005^oPN-a(y(Y+iePboBwhF1Z>fJ(~Q5 zFXXZp5{kk1fQxr?bwK^Tw*k8N<>nw5#$Dmet(_j-_L9;vy};|2x(#>bCd3tHN2Mnr znu-gu%(WFRo<}JAL|e)3YD?J3e$h^kPI31OT$~2s+Hrr=Bg4S!ZpBeZ&w;OF(*KaE zNtE=0?!XVc*frOw2a5{5A*L?zlAa%k46fZDQtE|e#jY`+QBffkRpE2ll78a3&OCjZ z*C2t&m439d15t_} zu1B4A@i?8~%(DU(J&eUp=_>cscx-UHJKJ@R2X0jyOm_gM6T1eSO{to~pFPxTfoqCP zUD8W>xx#mtV^4I6BhflEqw5pMG;1ap)~peHNw+z(ibT9#*MJ2QIBB2!>jA!KJbC^L zC|3GdQ50-SIyMy@OW1*7!8j@FSiwum5-vvNZ^h7orArppvpr+=*^1$SRe_jC18^7; zw*IVJ%YW3DvmcDBt1aHD1upn&S{%u7uASiGH7*|gHIz^Nnt2}2XQBD)6BjscJeKr+ H_2qv63c;Iv delta 1028 zcmZuw-A)rh7@gUj{oif3XrUMs)Ef#`P#_UhE{rDCL=uA$!HcGL7P<&qnB7_>Q!#R< zAu*XdiAnncCi)8An-GI0`vl@6c;(DO(I_*SGqZEfneY2HGuwTvCslJC6Y%zBZ_&5x zkEuw43v5fe3thG=wR5pjulsnMq_~8*N04E!=vpHo#2~XAcDr4ANWxTKmPA{VH{xJ(ao#I-SClo&~ zFHC3I17$cZB3pcX<|BLs*;}Qsd9SH$T#jU_Vblv+2rF%f)n2d#n|iXV{j+OC3fJn1 z!lZiBq82rt$fQV3s#5D3pcXcI0G7K!hYP3Xz z!P6Ceo)2D42B#_HWk{k7?9PIGh86W2!%O^MCv9KcfLIBmGKqe{DFVf(>;*Vh)`(y6 z_94@Z!oW;ki?z@TL%$Zpl8HKi@^p2#LfYmV;U&mi-{&8LX}N?2b7-9iy=P)FX}%*+QgNYOAY$6eB-a ztmWNvUn^3Ih=QQln^1}s>OsL$sFs*%HT_9+GPM}q7&YgL zb`BP-*d7!-c+TG_hTpcO%vK+vp$G!NY-O;N!tJYh!8a6@bE`~HkONcofZQxBL zloFnNj1RTE8Ua&yR2P|M9`J_6ZOF7SH9)K4O)`ckI)g+OvKx+y^CwX4ppJOz)+9zE zz^EBfle-YK@lDh?ORYVdjjI!Ul{>hHC(xwIB7)mN&Dh~(yo|tS-@tFpr9}?>IZxyj zW<;nkD+&sIQRD&m)TXGdi72t1#O_G!RAP5R$euJqP9WrNo3K@GY~&!^#G=HFITK10 zQ$n>BO@!*|PIC2ijN&+cFmFW!l&>W)<_HUS=lV#!RD8t=E_z z2e|T$6%~^>mX0^#2hK7vWaSb2hU>HX^7QTxKC&x#P5!p~A`|N*{nx%j{^*uTOuRGG z@~9ITzV2gRjyomimuZoox~pTk;0)*l=eFeor$CHz^0{*iAC{k-F3r$wiYd-NEJj7QM@XmA|m(;rC4JpYTCG4X17+u8&l1} zlY-7gM6l6+!K)X=yLeFP#eczr3Zhout`)pEkNLj$=G*sX=Iy*|e5eO;x$H3-N1xBM zuZQ=8FB^9s*f%AUGqIYRI@?K)t9Z6GlhVq5)m-efl&QnPU4E9bHpYnqny+XkAAqr2 zfF;Qmm@1}h83s&Kqf$1u+ZcRFA39Eg$#*!nl@Yh$zXom_`Z$mc8uimUK!Xm?pdW)4=Uk?$M zb*)Df=#a3Y>x5O^NJ)~eWPM8y=YBEw*I}q0bn7X{FfH}Dx|7<=H4F!!M^by%!4V0P zOY5$sLpo$JKjeL2nVn@(wsoCa0P0a1V!aQvTZ7^rsHe2hpoInwp_t?G3#_4?a~%sg zH_**FL_g;#jZ9$V|+Sf4tMmMlHye|rc_`g;AEzMgcB7K%-1 zqmKo2v4|f1r1E3$p9Cs88JJtvMtE-q)@fsl!S?y4nrlawr`yq`cx!h&iYJnVnJW`B zacALbv~S{H*?bhAVBWm3?@{Kkx$QhOlZCzDnTv(<=5^s*uSyR@4P{WvAk3gnuu{0( zN}Fk_R_spPl*x*Hi8!4cS5B@btt4s3k*Z_~r40U8NoDU+l{3g*CH zC+3-Z!8D3fy$2-mB^O)}mJ0#YKyYDkdklPvMmR-|0C$Oh5oO16;E(yF(pTV-RY5FK z1pJpPvN~kKp~&HU)v@?bNAMqx&A&Si|0cYwx@U9X5UdKvGoOo%k=oa8?F3z#?v>F( ZvLk6;YfTEX+1m-*%qj0MjG8Cjp5NGl