From 626afe5484dfcae2ef6bcc1630ba4da4cc07e0bb Mon Sep 17 00:00:00 2001 From: cody <648753004@qq.com> Date: Fri, 22 Aug 2025 17:54:41 +0800 Subject: [PATCH] update --- .../Commands/LinkCoursesToCalendar.php | 302 ----------------- app/Console/Commands/UpdateCourseUrls.php | 316 ++++++++++++++---- .../Controllers/Admin/OtherController.php | 2 +- 课程台账.xlsx | Bin 14754 -> 15669 bytes 4 files changed, 246 insertions(+), 374 deletions(-) delete mode 100644 app/Console/Commands/LinkCoursesToCalendar.php diff --git a/app/Console/Commands/LinkCoursesToCalendar.php b/app/Console/Commands/LinkCoursesToCalendar.php deleted file mode 100644 index e661984..0000000 --- a/app/Console/Commands/LinkCoursesToCalendar.php +++ /dev/null @@ -1,302 +0,0 @@ -info("开始将课程关联到calendars日历表..."); - $this->info("总共需要处理 " . count($this->courseList) . " 个课程"); - - $linkedCount = 0; - $notFoundCourses = []; - $alreadyLinkedCourses = []; - - DB::beginTransaction(); - - try { - foreach ($this->courseList as $courseName) { - $this->info("正在处理课程: {$courseName}"); - - // 查找匹配的课程 - $course = $this->findCourse($courseName); - - if (!$course) { - $this->warn("✗ 未找到匹配的课程: {$courseName}"); - $notFoundCourses[] = $courseName; - continue; - } - - $this->info("✓ 找到匹配课程: {$course->name} (ID: {$course->id})"); - - // 检查是否已经存在日历记录 - $existingCalendar = Calendar::where('course_id', $course->id) - ->where('type', 1) // 类型1为课程 - ->first(); - - if ($existingCalendar) { - $this->warn("⚠ 课程已存在日历记录: {$course->name}"); - $alreadyLinkedCourses[] = $course->name; - continue; - } - - // 创建日历记录 - $calendarData = $this->createCalendarData($course); - $calendar = Calendar::create($calendarData); - - $this->info("✓ 成功创建日历记录 (ID: {$calendar->id}) 关联课程: {$course->name}"); - $linkedCount++; - } - - DB::commit(); - - $this->info("\n" . str_repeat('=', 60)); - $this->info("处理完成!"); - $this->info("成功关联课程数量: {$linkedCount}"); - $this->info("已存在日历记录: " . count($alreadyLinkedCourses)); - $this->info("未找到匹配课程: " . count($notFoundCourses)); - - // 显示未找到的课程 - if (!empty($notFoundCourses)) { - $this->warn("\n未找到匹配的课程列表:"); - foreach ($notFoundCourses as $course) { - $this->warn(" - {$course}"); - } - } - - // 显示已存在日历记录的课程 - if (!empty($alreadyLinkedCourses)) { - $this->warn("\n已存在日历记录的课程列表:"); - foreach ($alreadyLinkedCourses as $course) { - $this->warn(" - {$course}"); - } - } - - } catch (\Exception $e) { - DB::rollback(); - $this->error("处理过程中发生错误: " . $e->getMessage()); - $this->error("已回滚所有更改"); - return; - } - - $this->info("\n所有操作已完成!"); - } - - /** - * 查找匹配的课程 - */ - private function findCourse($courseName) - { - // 1. 精确匹配 - $course = Course::where('name', $courseName) - ->whereNull('deleted_at') - ->first(); - - if ($course) { - return $course; - } - - // 2. 模糊匹配 - $course = Course::where('name', 'like', "%{$courseName}%") - ->whereNull('deleted_at') - ->first(); - - if ($course) { - $this->info("通过模糊匹配找到课程: '{$course->name}'"); - return $course; - } - - // 3. 相似度匹配 - $courses = Course::whereNull('deleted_at') - ->whereNotNull('name') - ->where('name', '!=', '') - ->get(); - - $bestMatch = null; - $highestSimilarity = 0; - - foreach ($courses as $course) { - $similarity = $this->calculateSimilarity($courseName, $course->name); - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $bestMatch = $course; - } - } - - if ($bestMatch && $highestSimilarity > 0.3) { // 设置最低相似度阈值 - $this->info("通过相似度匹配找到课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}'"); - return $bestMatch; - } - - return null; - } - - /** - * 创建日历数据 - */ - private function createCalendarData($course) - { - return [ - 'type' => 1, // 类型1为课程 - 'course_id' => $course->id, - 'date' => $course->start_date ?? now()->format('Y-m-d'), - 'title' => $course->name, - 'content' => $course->content ?? '', - 'start_time' => $course->start_date ? $course->start_date . ' 09:00:00' : null, - 'end_time' => $course->end_date ? $course->end_date . ' 17:00:00' : null, - 'url' => $course->url ?? '', - 'created_at' => now(), - 'updated_at' => now(), - ]; - } - - /** - * 计算字符串相似度 - */ - private function calculateSimilarity($str1, $str2) - { - // 移除空格并转换为小写 - $str1 = strtolower(preg_replace('/\s+/', '', $str1)); - $str2 = strtolower(preg_replace('/\s+/', '', $str2)); - - if ($str1 === $str2) { - return 1.0; - } - - if (empty($str1) || empty($str2)) { - return 0.0; - } - - // 使用Levenshtein距离计算相似度 - $maxLen = max(strlen($str1), strlen($str2)); - if ($maxLen == 0) { - return 1.0; - } - - $distance = levenshtein($str1, $str2); - $similarity = 1 - ($distance / $maxLen); - - // 如果其中一个字符串包含另一个,提高相似度 - if (strpos($str1, $str2) !== false || strpos($str2, $str1) !== false) { - $containsSimilarity = min(strlen($str1), strlen($str2)) / $maxLen; - $similarity = max($similarity, $containsSimilarity); - } - - return max(0, $similarity); - } -} diff --git a/app/Console/Commands/UpdateCourseUrls.php b/app/Console/Commands/UpdateCourseUrls.php index 1c276a7..80363c8 100644 --- a/app/Console/Commands/UpdateCourseUrls.php +++ b/app/Console/Commands/UpdateCourseUrls.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use App\Models\Calendar; use App\Models\Course; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; @@ -22,7 +23,7 @@ class UpdateCourseUrls extends Command * * @var string */ - protected $description = '从Excel文件读取课程信息,匹配phome_ecms_news表的titleurl并更新courses表的url字段'; + protected $description = '从Excel文件读取课程信息,匹配courses表,获取新闻链接,并创建calendar记录'; /** * Create a new command instance. @@ -58,7 +59,9 @@ class UpdateCourseUrls extends Command $this->info("Excel文件包含 {$sheetCount} 个工作表"); - $totalUpdated = 0; + $totalCreated = 0; + $failedCourses = []; + $failedNews = []; // 处理每个工作表 for ($sheetIndex = 0; $sheetIndex < $sheetCount; $sheetIndex++) { @@ -67,11 +70,29 @@ class UpdateCourseUrls extends Command $this->info("正在处理工作表: {$sheetName}"); - $updated = $this->processWorksheet($worksheet, $sheetName); - $totalUpdated += $updated; + list($created, $sheetFailedCourses, $sheetFailedNews) = $this->processWorksheet($worksheet, $sheetName); + $totalCreated += $created; + $failedCourses = array_merge($failedCourses, $sheetFailedCourses); + $failedNews = array_merge($failedNews, $sheetFailedNews); } - $this->info("处理完成,总共更新了 {$totalUpdated} 条记录"); + $this->info("处理完成,总共创建了 {$totalCreated} 条日历记录"); + + // 显示匹配失败的课程 + if (!empty($failedCourses)) { + $this->warn("匹配失败的课程:"); + foreach (array_unique($failedCourses) as $failedCourse) { + $this->warn(" - {$failedCourse}"); + } + } + + // 显示匹配失败的新闻 + if (!empty($failedNews)) { + $this->warn("匹配失败的新闻:"); + foreach (array_unique($failedNews) as $failedNewsItem) { + $this->warn(" - {$failedNewsItem}"); + } + } } catch (\Exception $e) { $this->error("处理Excel文件时发生错误: " . $e->getMessage()); @@ -98,70 +119,150 @@ class UpdateCourseUrls extends Command $headers[$col] = trim($cellValue); } - $this->info("表头: " . implode(', ', $headers)); - - // 找到"课程"和"跳转链接"列的位置 + // 找到"课程"、"开始时间"、"结束时间"、"跳转链接"列的位置 $courseColumn = null; + $startTimeColumn = null; + $endTimeColumn = null; $linkColumn = null; foreach ($headers as $colIndex => $header) { if (strpos($header, '课程') !== false) { $courseColumn = $colIndex; } + if (strpos($header, '开始时间') !== false) { + $startTimeColumn = $colIndex; + } + if (strpos($header, '结束时间') !== false) { + $endTimeColumn = $colIndex; + } if (strpos($header, '跳转链接') !== false) { $linkColumn = $colIndex; } } - if (!$courseColumn || !$linkColumn) { - $this->warn("工作表 {$sheetName} 中未找到'课程'或'跳转链接'列"); - return 0; + if (!$courseColumn || !$startTimeColumn || !$endTimeColumn || !$linkColumn) { + $this->warn("工作表 {$sheetName} 中未找到必要的列(课程、开始时间、结束时间、跳转链接)"); + return [0, [], []]; } - $this->info("找到课程列: {$courseColumn},跳转链接列: {$linkColumn}"); - - $updated = 0; + $this->info("找到课程列: {$courseColumn},开始时间列: {$startTimeColumn},结束时间列: {$endTimeColumn},跳转链接列: {$linkColumn}"); + $created = 0; $failedCourses = []; + $failedNews = []; // 处理数据行 for ($row = 2; $row <= $highestRow; $row++) { $courseName = trim($worksheet->getCellByColumnAndRow($courseColumn, $row)->getCalculatedValue()); + + // 获取开始时间和结束时间的原始值,避免格式化问题 + $startTimeCell = $worksheet->getCellByColumnAndRow($startTimeColumn, $row); + $endTimeCell = $worksheet->getCellByColumnAndRow($endTimeColumn, $row); + + // 优先使用原始值,如果没有则使用计算值 + $startTime = $startTimeCell->getValue(); + if ($startTime === null) { + $startTime = trim($startTimeCell->getCalculatedValue()); + } + + $endTime = $endTimeCell->getValue(); + if ($endTime === null) { + $endTime = trim($endTimeCell->getCalculatedValue()); + } + $jumpLink = trim($worksheet->getCellByColumnAndRow($linkColumn, $row)->getCalculatedValue()); - if (empty($courseName) || empty($jumpLink)) { + if (empty($courseName) || empty($startTime) || empty($endTime)) { continue; } - $this->info("处理行 {$row}: 课程='{$courseName}', 跳转链接='{$jumpLink}'"); - - // 从phome_ecms_news表获取titleurl - list($title, $titleUrl) = $this->getTitleUrlFromNews($jumpLink); + $this->info("处理行 {$row}: 课程='{$courseName}', 开始时间='{$startTime}' (类型: " . gettype($startTime) . "), 结束时间='{$endTime}' (类型: " . gettype($endTime) . "), 跳转链接='{$jumpLink}'"); - if ($titleUrl) { - // 更新courses表 - $updateCount = $this->updateCourseUrl($courseName, $titleUrl, $title); - $updated += $updateCount; + // 1. 匹配courses表 + $courseId = $this->matchCourse($courseName); + if (!$courseId) { + $this->warn("✗ 未找到匹配的课程: '{$courseName}'"); + $failedCourses[] = $courseName; + continue; + } - if ($updateCount > 0) { - $this->info("✓ 成功更新课程 '{$courseName}' 的URL为: {$titleUrl}"); - } else { - $this->warn("✗ 未找到匹配的课程: '{$courseName}'"); - $failedCourses[] = $courseName; + // 2. 匹配phome_ecms_news表获取url和title + $url = null; + $title = null; + if (!empty($jumpLink)) { + list($title, $url) = $this->getTitleUrlFromNews($jumpLink); + if (!$url) { + $this->warn("✗ 未找到匹配的新闻标题: '{$jumpLink}'"); + $failedNews[] = $jumpLink; } + } + + // 3. 更新courses表的url字段 + if ($url && $title) { + $this->updateCourseUrl($courseId, $url, $title); + } + + // 4. 创建calendar记录 + $calendarCreated = $this->createCalendarRecord($courseId, $courseName, $startTime, $endTime, $url, $title, $courseName); + if ($calendarCreated) { + $created++; + $this->info("✓ 成功创建日历记录: '{$courseName}'"); } else { - $this->warn("✗ 未找到匹配的新闻标题: '{$jumpLink}'"); + $this->warn("✗ 创建日历记录失败: '{$courseName}'"); } } - // 显示匹配失败的课程 - if (!empty($failedCourses)) { - $this->warn("工作表 {$sheetName} 中匹配失败的课程:"); - foreach ($failedCourses as $failedCourse) { - $this->warn(" - {$failedCourse}"); + return [$created, $failedCourses, $failedNews]; + } + + /** + * 匹配courses表 + */ + private function matchCourse($courseName) + { + try { + // 直接匹配 + $course = Course::where('name', $courseName)->first(); + + if ($course) { + $this->info("通过直接匹配找到课程: '{$course->name}' (ID: {$course->id})"); + return $course->id; + } + + // 模糊匹配 + $course = Course::where('name', 'like', "%{$courseName}%") + ->whereNull('deleted_at') + ->first(); + + if ($course) { + $this->info("通过模糊匹配找到课程: '{$course->name}' (ID: {$course->id})"); + return $course->id; + } + + // 使用相似度匹配 + $courses = Course::whereNotNull('name')->where('name', '!=', '')->get(); + + $bestMatch = null; + $highestSimilarity = 0; + + foreach ($courses as $course) { + $similarity = $this->calculateSimilarity($courseName, $course->name); + if ($similarity > $highestSimilarity) { + $highestSimilarity = $similarity; + $bestMatch = $course; + } + } + + // 取相似度最高的作为结果,不设置阈值限制 + if ($bestMatch && $highestSimilarity > 0.3) { + $this->info("通过相似度匹配找到课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}' (ID: {$bestMatch->id})"); + return $bestMatch->id; } + + } catch (\Exception $e) { + $this->error("查询courses表时发生错误: " . $e->getMessage()); } - return $updated; + return null; } /** @@ -208,8 +309,9 @@ class UpdateCourseUrls extends Command } } - if ($bestMatch && $highestSimilarity > 0) { - $this->info("通过相似度匹配找到 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->title}' -> '{$bestMatch->titleurl}'"); + // 取相似度最高的作为结果,不设置阈值限制 + if ($bestMatch && $highestSimilarity > 0.3) { + $this->info("通过相似度匹配找到新闻 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->title}' -> '{$bestMatch->titleurl}'"); return [$bestMatch->title, $bestMatch->titleurl]; } @@ -223,58 +325,130 @@ class UpdateCourseUrls extends Command /** * 更新courses表的url字段 */ - private function updateCourseUrl($courseName, $titleUrl, $title) + private function updateCourseUrl($courseId, $titleUrl, $title) { try { - // 直接匹配 - $updateCount = Course::where('name', $courseName) - ->whereNull('deleted_at') - ->update(['url' => $titleUrl, 'url_title' => $title]); + $course = Course::find($courseId); + if ($course) { + $course->url = $titleUrl; + $course->url_title = $title; + $course->save(); + $this->info("✓ 成功更新课程URL: '{$course->name}' -> '{$titleUrl}'"); + return true; + } + } catch (\Exception $e) { + $this->error("更新courses表时发生错误: " . $e->getMessage()); + } + + return false; + } + + /** + * 创建calendar记录 + */ + private function createCalendarRecord($courseId, $courseName, $startTime, $endTime, $url = null, $title = null, $calendarTitle = null) + { + try { + // 转换时间格式 + $startDateTime = $this->parseDateTime($startTime); + $endDateTime = $this->parseDateTime($endTime); - if ($updateCount > 0) { - return $updateCount; + if (!$startDateTime || !$endDateTime) { + $this->warn("时间格式解析失败: 开始时间='{$startTime}', 结束时间='{$endTime}'"); + return false; } - // 模糊匹配 - $updateCount = Course::where('name', 'like', "%{$courseName}%") - ->whereNull('deleted_at') - ->update(['url' => $titleUrl, 'url_title' => $title]); + // 检查是否已存在相同的日历记录 + $existingCalendar = Calendar::where('course_id', $courseId) + ->where('start_time', $startDateTime) + ->where('end_time', $endDateTime) + ->first(); - if ($updateCount > 0) { - $this->info("通过模糊匹配更新了课程"); - return $updateCount; + if ($existingCalendar) { + $this->info("日历记录已存在,跳过创建: '{$courseName}'"); + return true; } - // 使用相似度匹配 - $courses = Course::whereNull('deleted_at') - ->whereNotNull('name') - ->where('name', '!=', '') - ->get(); + // 创建新的日历记录 + $calendar = new Calendar(); + $calendar->type = 1; // 课程类型 + $calendar->course_id = $courseId; + $calendar->title = $calendarTitle ?: $courseName; // 使用Excel中的课程名字作为title + $calendar->start_time = $startDateTime; + $calendar->end_time = $endDateTime; + $calendar->date = $startDateTime->format('Y-m-d'); + $calendar->url = $url; + $calendar->is_publish = 1; // 默认发布 + $calendar->save(); - $bestMatch = null; - $highestSimilarity = 0; + return true; - foreach ($courses as $course) { - $similarity = $this->calculateSimilarity($courseName, $course->name); - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $bestMatch = $course; + } catch (\Exception $e) { + $this->error("创建calendar记录时发生错误: " . $e->getMessage()); + } + + return false; + } + + /** + * 解析日期时间格式 + */ + private function parseDateTime($dateTimeString) + { + try { + // 处理Excel数字格式的日期时间 + if (is_numeric($dateTimeString)) { + $excelDate = (float) $dateTimeString; + + // Excel日期从1900年1月1日开始计算天数 + // 需要减去2是因为Excel错误地认为1900年是闰年 + $unixTimestamp = ($excelDate - 25569) * 86400; + + $dateTime = new \DateTime(); + $dateTime->setTimestamp($unixTimestamp); + + $this->info("Excel数字日期转换: {$dateTimeString} -> " . $dateTime->format('Y-m-d H:i:s')); + return $dateTime; + } + + // 尝试多种日期时间格式 + $formats = [ + 'Y-m-d H:i:s', + 'Y-m-d H:i', + 'Y/m/d H:i:s', + 'Y/m/d H:i', + 'Y-m-d', + 'Y/m/d', + 'd/m/Y H:i:s', + 'd/m/Y H:i', + 'd-m-Y H:i:s', + 'd-m-Y H:i' + ]; + + foreach ($formats as $format) { + $dateTime = \DateTime::createFromFormat($format, $dateTimeString); + if ($dateTime !== false) { + // 如果只有日期没有时间,设置默认时间 + if (strpos($format, 'H:i') === false) { + $dateTime->setTime(9, 0, 0); // 默认上午9点 + } + return $dateTime; } } - if ($bestMatch && $highestSimilarity > 0) { - $bestMatch->url = $titleUrl; - $bestMatch->url_title = $title; - $bestMatch->save(); - $this->info("通过相似度匹配更新了课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}'"); - return 1; + // 尝试使用strtotime + $timestamp = strtotime($dateTimeString); + if ($timestamp !== false) { + $dateTime = new \DateTime(); + $dateTime->setTimestamp($timestamp); + return $dateTime; } } catch (\Exception $e) { - $this->error("更新courses表时发生错误: " . $e->getMessage()); + $this->error("解析日期时间时发生错误: " . $e->getMessage()); } - return 0; + return null; } /** diff --git a/app/Http/Controllers/Admin/OtherController.php b/app/Http/Controllers/Admin/OtherController.php index 035a7fd..f133af0 100755 --- a/app/Http/Controllers/Admin/OtherController.php +++ b/app/Http/Controllers/Admin/OtherController.php @@ -163,7 +163,7 @@ class OtherController extends CommonController // 培养人数 $courseTypeSignsPass = $courseSignByType->count(); // 去重培养人数 - $courseTypeSignsPassUnique = User::whereIn('id', $courseSignByType->pluck('user_id'))->groupBy('mobile')->count(); + $courseTypeSignsPassUnique = User::whereIn('id', $courseSignByType->pluck('user_id'))->distinct('mobile')->count(); foreach ($courses2 as $course) { $courseTypesSum[] = [ 'course_type' => $courseType->name, diff --git a/课程台账.xlsx b/课程台账.xlsx index 3bc5dde1b46d29ae16a036196038ad8770a720db..4a2659a7261919437197f93c010761754a27b238 100644 GIT binary patch delta 11321 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 delta 10394 zcmZ8{WmFwOwPx8Gt^Jb=g zboJVM*X~-?-D}mUbDI3VyVvDG1Lg1u?qs2%pv+;Qps=8zpe&s&)ZCn1+}SOh-K^Mr z93A3Q)K$YcFh_nVzn~YL&%%T_qSZ-Ha0@JT#2S85x zv&}HOf+<|7ErLS25REuAv0zJj7o`2{4p~KOqw@P!tCz4-=ucmZbVIE|^&$}Sf2l}& z$RdkUK~#+rq53!%DJAs61}F!`^icG(#Sn+5Ss0liEl#BkXJFQca>3%nlI&2U6?h|n zoxnS0k0Zsm5$#t6w3eM<#~3A-ab6C{;rBCc0CVKR(&TD&$5joC>k0v#?MCD!m(s3w zHZ9Q`nQQOdyEOc^AdTNukB9N@bEI2XOq6uAYPzUis=9O`9^GCbM{70(sw&3SpG%6J z3RKN(76!e^C<1X#Ka=;E9TGJ~SU6Cy5OD)7Y$i1FmK9I90TL9H2NP%*jvSb)Z{)ly zfE^%a`W{wr-^4mb;fiVVV~?^G_AYp6^K_$OSO?p}VZw&_a$sTBNd&FsfGusgL3^=);v2ECkZF)o^sZDsdWmm0=V&t$S&jYKZ+~4k8pMKJb zwoL_YoO-_|)@_8SK{WGDZiTw@*mkF|^k~tTGC<8O6dB#Z0biayL2GA* z1h0pm4(>dSUi3xRtc+U4gI{b`jM>L#3cDYlYQ26rJ$aopYQ%LSbbD>^W4uHfWIyde zZ)x)71l|8!^Xf4n@B;2z-t?#qz8)egnTOvT6s#$#O`RXiH3vG1-gTYcy>B=^-+TTb z&RFUsTz)^S0Xlm-pLZ2D5DJ%jQM?9uI{@v)AYC1{Mq1sgC6JEEvtM&&2inGQ=u_US z(3VC%$?vPefip34^f$;SX+9!`dfRDd@65(}@t?ItjMy%I2?KGKGDlw%qsJ@AS1Nxd zO}KW(Chwy7>n&oWqIP(Ej+i&fvUU}tq01UdMAIjVI9R%Q@i?oY@tz0#(%cQq52(sT zJ!xRwPR+f7YtQlhxwlG{lpXhA8UJ-Aam+!KjC9?OljUDZ=#Sx_32_#( zNv@KJ9l;$cYF*ci!8BLRPCxk)~MeaI^IEyRQ@TRbL|9`#32_Mzqj>2`t!_7|Pa2A$)` zeF->8Q-rW$O>Rfsx<;lbE?4Z$t}FTnm>($75d~y^vX= zBmF(7xf>uri`Hu|-&C#<9CnttZ|b^9shIq0&~_eC1K>u;MN6o`aF7qN%z7#UcpwxW z^;H$o^G>p=`=MxBLr)`6;1;hIGDh0gk0_-g|4yg(bZ61@W+{&>i(G#>RstbMcnsM< zTmOdhm?@P-vUNzb?ddBMOTV05mQ+j^pD$5xHU*B$X_zPh5FpU%D;`Yp^Pj#j5fZaH zN1mnan?`N>L?!1CDhovY&>Iwp#!)?{*i}0UB1-SteR{S9YTE25q=5F&{Xd~rD!%v{ zZBR4U$u)jV;c_EH<=Lj>z~?UF&Q7)zL_D`_L#XK6>VG9MiY1L;aLr6!|AB!VQ8Xqf z@DbQ?z@fF}Gn=V^%R^|Dliq)m$q@MyOz%X<#`dC=c*jpWWYiXOgLHn8}@EYsBK z%VGzZ>thcfpyac8$FLat_)C^C-Xv?+@tq#pZ-PciWA{lg&q&h_n)(s! z1FeG8%}=ecSnSBQq{Jl-9?fZq`zbq@u2~>rHqD(`6g}x+r^6&=Zu`6u7t6>|>=~CKz6#HCIjxt!fQE+5EcmON=`b=l2v-&8R zGt0@aIZ%;O&-M5_iJeeFLgkz}M(2T`X4k7E${`l{{J4Il9%j@DDM++PBUu=W$QKd@ zTS9Dx(k&6zm3P!C^ma-wTaHnNq~>H8TGM|-zQHflDhvk8#7jb}$8gE&2r6|~^md}@ zOrjV*k~l7ONlu-CSvf((4K$l_66=4ezpGpo>f2f@w}Ea`PWBH1DhmRljP=mm6;s+N zrZvPS$#*%&1uV0_qN2Jhg3yb|PPy2NWZ@>sgkiiy8Vv>hWCSYq{6BWW-Els%r$b`TXMt^TH`7^hWtZy zq=HdoM1Ln(ez|V8W%jQ5l}T!f7_lnO?9OVr$HR;mgkbm8) zcNo+n_gaGw;UV0I=eorR$^eh2;7;nbYQ?~_y|{rt++z7ds}D;C=^7~YNfdEROSbgN z*oE*C5!44Wuu~3NaKaUoz|exz}*vD{kNoxPhYx+xq^B ziLJFUPa_*W|!j2nyQ$g;ebVt?nY za^Fmni}iRK|IcKpJhVt?+mqkNqT=zeBV(i6dFD^GZ~)3xZTGSxzZ-#QcSK{!$;Lzw z`$o_&qxa56h*XZftM@*+bLGdioZ@XDD-av$>Vn^H|Y$3XmBbaYH_q zGy)RV@^4riG$<%n&?x~ukh1ZRzHT4zr@8#J_rq*&2V2TnxO6<)V2VAX42q?M{BO+w zdFtCODQqkGBFE@d%dw(}q7RMlgIVr2*84rP=hFqFm-~}yZYUol0AT;Kwu8&ubFi>? z&(i_u8_auV0N=Hb-|^;ZDZg_(Jbh{Rx3}%f#l-vJ?&rH1{x=SMU}jcs=9Ae@=~4NZ zzr}ktnCSWV%^B$KZEejL+@#5UKTJL~E&A#f5b*o?6G)Zb+DSz$7u?Sd%n7=)G{=7r zxZ8c0T(AM*h)n{r!QjBFg$J7!rwt+?*QJjg%f;)>jAp~?{WbeAjF_s(+w%;_1S4;~ zNBH{TZR6*2Q86QMqg7bc|NX2rpkH(8 z;`7j*i}?c&@WPupn}bDjr{Q4x+wgA1RHKTVXpI?}wM-INy>c?_wJb-`eU4i|frmV+ zD!RxdYZd(+-e^IZCEEMO39WXc4&w)9g%wkEdB6182Vo7r4W_P_jX_W;u->bA>XoC& z6zI^aFI5wT$VgB!5JCvA}ci+sG^^ca8PYJ(W$FZ?4CEf+@{yyUM{c_d#x3_W~a^N~`1K%+Tr9=4l>g>Jyt==$1{2 zQ(AI6hkXao&(AD)aiNl`35#R1m*L%lm8kFGV(F?)b(~wE#jx)c{ar{JWm?BqnW7V%K6j|n>zYG_-<9Q$f1zwtK9sUltt`H`>vHa|54Tz zI9HaIOeKm5m>m#>!>dfyU1$ok@BO-ISZo<{T9~(nM-N6RYSR?9uAbPg@m8efL^Obo zsQ!@Ik4<(!tGg;usn8QNXout-Ht)1)o11MD%fTS^#|zYsGT(VA`6~c?O1d!s9apur z+wNR|AWi}9qQ>tp@;0PNuclMczo@AOvS)~4v1}8rFd!96aZq@h09g=L_@;)lI+h3C zu7*riZSaJaWk;*NR?Cfx0t&I0_+&g@GnkBN$j;4~O|EMIBoxug0X<47h%iS=G z?PxF+!kP{-=5$K*u)hTguMu2zlU+*>pAfb+?Zih9)!C+@J)_~G6sqAsuxzk^;=eWE zUOdK%QyG5L@Ds?+Qiv_M;%Os0Z*AxcK$XGV$jbz`uXT?G8?kS8`f3hEliSBS8}zYq z(~QxC6PMg&Lu)xqt2-jj1d=^GL#Pc()s{wCboX048pkKf>MW|A^>R@a*hi2iLo}@O zPN5VZk&ahwT0}dhw!}wV)BA~l6Lc7*95cui4BCsfh2x9EOy71tC)WmD^cOGd=oKC+ zcKJ$NDieH0{g#_1IVxBg6|5YiZE@LK#iCgTyJ^*kFZ*-Q;Rd;J6FJ)aPh#UUHgV={ zL{#lzE{`Ad$s+(NI>mk+{7MYQDNgmcbD9^3`^iE&2@h3k-(fnRkL+gv)F5068<02+ z>*p7+6XCEGq(U=|jNe2ZuRA6!g9uKfO9OMzHLc`plx&Y7ja)WEDvvflh@mA?sE|s+ zY9`N?U0CedLL*h$V$_l(LT9)=V?N6SBy!0Ua5MONHZ}KGnn?{3&)iROtw8`oDLX~} zxBc6nu-{gqENI&N6Ft*`)!#lr!gMHO~b4^HsWdvM;xs*aX)ndpp3ovC`O=ef|QZX!&ez=8LVj*kHSEzU5@-(Kz| zYvM?=bG_%@9yZN44QfnYp|V{yPN(mDHbr{uw{q?`)p+YVG7M`#jMg6nGS|!oq!nJ( z(ego^q&(@BanP`RO6{l3o*wPjor+9H#fcObf*6R2l7yX6>WINP(>e2^S#Yw%5A2i@ z$6qpny0Z4B<(twf+lJH^>`G<3j+a$AiLdzx?T#(j=eP&mH|8E|hC7dEoCRP-khZYLevo0C#Bgm{$l2 z|MDCGrEl-CPl}vhgNOYc3MEY@6Tv`(=Q}^|3zKpKr=@3UPr+_)Q&8WoHXdQ?jZRpo zV;+U+U@)wDSG+Z0Ryg2>C>E8kWmlmogqTvPI)#xGBRS>)=STi8;y+dPiiCKIp?Iu5 zbS8;Lj}zL*K#Jp6g8EGeK$Tozon&=FpC1ULk1Z1`CKWMOx3aFrXG>=Y2M!7O?(0%JJFcjrcWBndBf0zOlC?y;0xNZk zByK1mY{sHnp{a2)MMob@MXMnKsEfRC+nknOd%m&&*7^3-TOW5-H6b#d5h&M4l-v6j zs^v>hC_Sa1)f#SLdMKD>awpJ21F#8TLUoL}sRuxG~+~ z4Pag%{D90IWt}APoM%GW7Sy$AA;UpZ>vv2SU1B;i*Q8ixHN_ax2YjxU`KG8?F>FHd>#eoibI%@%3 zB=_DY)(cgIQe0UPTIyL6DIw*h3Q_Cw2xC3Jn`ex>=`*Lg2jdEm zJ!Vy3#}euD+>Yfy`)aWF10RVyYn^3WPLg#mg(1TS)`9b~5o<;_+{2=rQS@gL#4fTH zWV8zWJ_^ZLS(|vftM94~)^QoxOKUWC?LwB4IhMvQ2F0Q**;wH2yUOOH3 zsd2|O=_v=#$_Uk@JeipECE-(!Il-RE2MQD%%&+ z*+Us<5go6bSjf^eS>Kqb@!&lw{g_%!xyuUB(M1Pr*Naa{obFb)F9Lc-It)+JjyE@Q zU)43mzN*Xj+F*^!-c33z3K~E$ec-=U!|3V0{9MG<4SV^WghH;~Dk*RZ6ibT&Bq?Ni z=30OG`AcC>enR7w^sd9vu&7tca?+-w!g_jPy*r#rs8Fev+;9_gIq>$PwB=9d_>D^0 zsn`Fz2sE=6zuL~3LTX>m$WQrLf5JFnON{nBnB473&$r(Gx9{@C`kw7uvpqgTN8%{L zDzBo>nl}_^vf$S<-vO6}!kN}E#tzaA9~pQ{G`>b{PX+IfqPq{4H*Y}be}~t&f3pK0 zpdwXv#Cg8R;( z%B8OXU++I0oRfaD^l6&lK0%Qig1b*%s85Cm;HO?TC5p0rx5m&@z)_K>7kD^iX7J$k zdv|KZyLyz5vYCKty;866a&z%~xP(p$(Ly)GCG&nyIsgkb!ZA z)s+cH-3h7Xbx{kV_yt{zq-ZUrNuHUk!X*pM`nhzM@$`xq&g7f|&bchDq>mV_h|3b! z=y44Mkjd-!Nt=-nN=IX z8kDXzE*;(cNdZQx5^B?+R_e1Fw|O|O_&?rW@84rA+}5k}564-6(K3CL_!r9=BCBz+ zheOiwh-c*+N2=za?d7|)Tpvjc1K6wG%2DshAg38BW~I()H9Gb*S-`|@cw_cDNMMUEk)ZnZ{1Ie| z^3ag4i^I;}=p$IE>+so(){BnQmzzK^wpfjNu3C4ml{}h%VgJUZi6m-Mj=QnYOqnFr zuJNoodMq=_M}IB z@>%9CVJ%v%e3yzr*HR5*;4D1)p!WXSGnaDvb4+b7(Ar@pj@xV93ncLAUgp&DZKmgO z=GyXlXS+AK#vsqRV?ak`fQZApFePgBon$5==Y2V+|#q3`6LZn z`hDE3i;LsbEZSw2(BqneD05SFxX^8dEN-&*Y&C(5)XbRf%j|}aJMhrYdIVYZ$QyvFU#$OydxLOFc=WOa9%;~c-SC7JaSso3eN%%n}N&SJtl zmVx$Pv>$g%7_&? zq2u00Bez9Rc4+zVKrS9cd`3>exBcrbfdx(L*k7dm6#t%QP5t_S&Xu=diM41 zHR6@0nexmCJ#JDP&3qSWyOmo+Z5mM4rucy&LcpPk`p#K_hG1 zg3*r#IkSNnEY7yQD;f_0x3+MB`BZT{YH5{}<88(FBG+>2t~n`*z20OUk&Ua)4I=D^ zC-8j7OA`mK&k&@Z=17r~+0cYQvimlsxHVsGC559zcKLL>-d}E( zjw`dkzg^RbzpTHrU_BI3{QlS)WR4(yfTLwgs8PIi#C&Ibeb%$9d@*OLq((b!f1)-d zplfaMgsF^*ow%am?z2Qdp^p7BuF+DeOlh#%TgqhB9JnimgZt_;wzce=LVsL`UTp1@ z(n9C|g{|wl-Zi@a)4e)||lKZ%;c(NRc8EZDWk=A0t`9oGA+Y?>2h@BH$z z^$g$rM!`|91>N_kw@;~c{fM!?)fz5Pv95EI?gDZf>T?u!Kq#g%TLzks@XLsmAP^L8 z;?1$j z5IdyU{mT__O{i2MW}gtD>Sj9)TF$CggFT!#yz>0o@pp_(IaY~*+@{flYfV1Sb660# zk2kd+<9U)=%%Mj-w#t?Q+VAV*%tdmM{Z)O_7ood17gIDd!PP66j#zw9$Aw)o-qt`+ zXmv!!>A_{%*;3hRZ z{fEasrU=c;ywoO_iinoBs_+UWD;b4YX6ER3@8Ph7eIg%r+-hdqqp)t)0yj?L!nitP zVs0d?)KVm@x_C|Pn8Y@Z=HRbG54goOw^xixlr>qy90bkQ!~=~9Y8InJdae6z1Lm$M z+}QBI6-?fy@7eIt`IMqc3z+j#PG}hr7zQQD@JSgQrcTSUPF;rn^ihHNBygF=MZHjQ z=I>lhyW%`^eHXcyMa{p6YB6s}5*&9bS9<23)J8sxdQ){ROJYG6QZz>|uAh1@hjB-L z7?e5?YM9GXlok+(+Vd5-91#`9hZZ%gvQdDk#Vg{9a*&}#>}IpUYH&ZAHL~`A9%~!9 zWOC!4%UIKN_)>~}O>7Ze$?igZx6EHTmFEMho_ z0=aY1$8SE}cF|jHj$Ej(bHpIH{L6sT!yWxwqX?Q$&6=wI@@6!~tPYTYFM6xM=E&HG zaY!C=2feD!Vb+i@VFsPf9Q1d=Wq*w4+IEF^x0f+XyevUj-JNn~YbX3%KK{ae-=p5! zKi;NvsE)YekX8jje)K49g&k%t-*6_ng-BhxWx7W%l_;_#R>x%ZU^x^5N%6w3V?G<) zFvBVWyo6l@k}^Skd>Zk8#G*HW_%%LgQ<$N(YQ^vck6?ojQ$)7Eb-> ze;x$olPePxbp$#`_uk?6eC-Z)XoCF-X1|#>zg?2N?`%eXt+BUFqfeyx1_($T+s*xP z+KcZupBp@t!VTx`BntGixq4$)5qnaWM#u`LqVYD77RHbg{P^xC;QP`5jDqS*AMYEX z0l68!Y!iLRdSk^8^>a!^_;#x}uSB>J#PBYVQsSEW@SvNLQZ_Q1@5-ANF+)8y`|`Ye zv|+PgA`-Qiug+FXbze@q&hhxt0NQ0&JtymVIP3z^iVy=e`~u9W8Qq^|dcd1+9N1A2 zp{Y{t=WI_W4xJ<9Rwyo4L(WMoy7(e0SY8fm?DCs2DezaUypK|ukJLMAjA$3< z>u%Us?k^Rm4RFwljMBueBpyPHcu)jB8a$CwdB2dz>&WR*{JZqd1(<0FzD=2`{CKZ# zp%s9Er2Qd!>|n&zmmIAE6Rng#=;76@a=5Nz-CK zI_t1fdj`|dE=~E~BERr@d7jVxhUv$6;|O_#gP(_7z(WdPpI$UlSSnG?F3F!4nbpXg zIe+PhPfprV>sqyHd;m9IDmQrDXm0zo5f(!ShF*sX;AaLB@`k!TgI@Y2=2WyqLxFip zQ_yi*CR%FFZ=uiLGKbqy6_v-Sf8-4h#*HiR0@2->MZp*m z_ZxkTDvUKac3NB4M_wI1)rbV%tQ8eeVgSPCs%&#^*MEsxTWC3@&x5B&c7WbUuTnm= z9kQp@hd8!_)AEQnRF>!j`C6S!*t^`SU^N8yFQYhMp^!1D)FLlpRtX695R_w?-BU(6BA`0Ys*6yfo$JG_&L z0a+M}wMg5wajF`XI4Gpx4h_W`hS2h-N!vW;&!2R}U#Aevz#`X__;}NB)>J37Cw=|Q znLTEw1oP?Zy|L~I437s+UR-UKlDCyRhk)BV?ar@uXg3|O9z$Y4Q5A}r@&TU;o7<@$ zIEL{(4rzziRx_c`3zaL)9fw5#)SdqMjMEdRV7(@Vo2*ow-TA6f7jluX+Ygt6AN>b9 z^i2UUJrZ@C&1PwrrM!XOrJGui{p=EZD@SMV+D@a494kGi6MtSQK98m+wm7=7WPfx+ zbd1th*Z{F(2x1M;!tBTtjwon*&O-kY_F)cw;<@J8%aAltZy^Se%>l<$ahJ+X|ET-) zQ3B#Q4EsP9sYU|eQKfO2%)0V1Ow%Dpf%2?@%M+m z!hypm0D+4))4$|V{T=VzpH?Sfoma=aJ6)BKHFsBCBm4*H==Uem0?Ty?DS8*|}I8GyHy@GffzzKv%)(vsNNmKD)&^ZJu;q zHL#U}L1X@4ZbIzON1NQ08`0fiQ?_5yxxiwtU8%EdFWix&xhCAv5y4jJ_G|?8@yRhg zUP{Kl>6cjYZH!7#A^e>r<66XdZ*7r}*$x`cA>NZ-WVsJ30+#qQ|F&G_AP`Dr$j2|bcO)v%iKh=96H6bl%cu=vBIHD=sePCleIZzli={gNCB~driOvWeC%g{{I2n z{|IPkK|h5BVMNhExBy-lD|C<|fR6OvSpd!7+ClrjPsaGC{oDS_Z-ELF2M~r10gVEv gNdKqa4GN0zzf}J%tA+!O!x4ihL@*J;dH*s03+~(O(*OVf