From 42484848771296364649e32d2bf8809dba893f56 Mon Sep 17 00:00:00 2001 From: Naz <2022755409@student.uitm.edu.my> Date: Thu, 24 Apr 2025 11:45:08 +0800 Subject: [PATCH] - --- .../Controllers/HodDashboardController.cs | 4 +- .../Controllers/HouDashboardController.cs | 26 +++ .../Controllers/OvertimeController.cs | 2 +- .../Services/OvertimePdfService.cs | 84 ++++---- .../Views/HouDashboard/HouApproval.cshtml | 5 + .../Views/HouDashboard/OtReview.cshtml | 169 +++++++++++++++ .../Views/Overtime/OtRecords.cshtml | 194 ++++-------------- .../Views/Overtime/OtRegister.cshtml | 2 +- .../Views/Overtime/OtStatus.cshtml | 119 ----------- Controllers/API/OvertimeAPI.cs | 149 ++++---------- Views/Shared/_Layout.cshtml | 14 ++ ...T_0c935b6f-beb7-459d-ae67-807251e104a3.pdf | Bin 282290 -> 0 bytes .../OT_15_2025_4_638809276784755591.pdf | Bin 71450 -> 0 bytes .../OT_15_2025_4_638809289066407421.pdf | Bin 71450 -> 0 bytes .../OT_15_2025_4_638809289682209687.pdf | Bin 72070 -> 0 bytes .../OT_15_2025_4_638809323916424471.pdf | Bin 71450 -> 0 bytes .../OT_15_2025_4_638809389078270198.pdf | Bin 71450 -> 0 bytes .../OT_15_2025_4_638809392040377761.pdf | Bin 71450 -> 0 bytes .../OT_1_2025_4_638809164154988965.pdf | Bin 71450 -> 0 bytes .../OT_1_2025_4_638809168067665769.pdf | Bin 71450 -> 0 bytes ...T_1c49d312-a22e-4ac2-9c45-d3d57a917eed.pdf | Bin 75325 -> 0 bytes ...T_1f536404-6970-4ef7-bd5f-560807b76a05.pdf | Bin 282290 -> 0 bytes ...T_525ffef0-da41-463a-bd4b-05556272c6cc.pdf | Bin 75325 -> 0 bytes ...T_56a769f2-e911-48bd-8872-a4f749d82fa1.pdf | Bin 282290 -> 0 bytes ...T_f46b391b-dc33-49cc-bac3-642c469c66c5.pdf | Bin 282290 -> 0 bytes 25 files changed, 353 insertions(+), 415 deletions(-) create mode 100644 Areas/OTcalculate/Controllers/HouDashboardController.cs create mode 100644 Areas/OTcalculate/Views/HouDashboard/HouApproval.cshtml create mode 100644 Areas/OTcalculate/Views/HouDashboard/OtReview.cshtml delete mode 100644 wwwroot/Media/Overtime/OT_0c935b6f-beb7-459d-ae67-807251e104a3.pdf delete mode 100644 wwwroot/Media/Overtime/OT_15_2025_4_638809276784755591.pdf delete mode 100644 wwwroot/Media/Overtime/OT_15_2025_4_638809289066407421.pdf delete mode 100644 wwwroot/Media/Overtime/OT_15_2025_4_638809289682209687.pdf delete mode 100644 wwwroot/Media/Overtime/OT_15_2025_4_638809323916424471.pdf delete mode 100644 wwwroot/Media/Overtime/OT_15_2025_4_638809389078270198.pdf delete mode 100644 wwwroot/Media/Overtime/OT_15_2025_4_638809392040377761.pdf delete mode 100644 wwwroot/Media/Overtime/OT_1_2025_4_638809164154988965.pdf delete mode 100644 wwwroot/Media/Overtime/OT_1_2025_4_638809168067665769.pdf delete mode 100644 wwwroot/Media/Overtime/OT_1c49d312-a22e-4ac2-9c45-d3d57a917eed.pdf delete mode 100644 wwwroot/Media/Overtime/OT_1f536404-6970-4ef7-bd5f-560807b76a05.pdf delete mode 100644 wwwroot/Media/Overtime/OT_525ffef0-da41-463a-bd4b-05556272c6cc.pdf delete mode 100644 wwwroot/Media/Overtime/OT_56a769f2-e911-48bd-8872-a4f749d82fa1.pdf delete mode 100644 wwwroot/Media/Overtime/OT_f46b391b-dc33-49cc-bac3-642c469c66c5.pdf diff --git a/Areas/OTcalculate/Controllers/HodDashboardController.cs b/Areas/OTcalculate/Controllers/HodDashboardController.cs index 0f1f920..ff10d85 100644 --- a/Areas/OTcalculate/Controllers/HodDashboardController.cs +++ b/Areas/OTcalculate/Controllers/HodDashboardController.cs @@ -12,9 +12,9 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers { [Area("OTcalculate")] [Authorize] - public class HodDashboardController : Controller + public class HouDashboardController : Controller { - public IActionResult HodApproval() + public IActionResult HouApproval() { return View(); } diff --git a/Areas/OTcalculate/Controllers/HouDashboardController.cs b/Areas/OTcalculate/Controllers/HouDashboardController.cs new file mode 100644 index 0000000..0f1f920 --- /dev/null +++ b/Areas/OTcalculate/Controllers/HouDashboardController.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using PSTW_CentralSystem.Areas.OTcalculate.Models; +using PSTW_CentralSystem.DBContext; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers +{ + [Area("OTcalculate")] + [Authorize] + public class HodDashboardController : Controller + { + public IActionResult HodApproval() + { + return View(); + } + public IActionResult OtReview() + { + return View(); + } + } +} diff --git a/Areas/OTcalculate/Controllers/OvertimeController.cs b/Areas/OTcalculate/Controllers/OvertimeController.cs index c5596ae..1b3b5d4 100644 --- a/Areas/OTcalculate/Controllers/OvertimeController.cs +++ b/Areas/OTcalculate/Controllers/OvertimeController.cs @@ -20,7 +20,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers return View(); } - public IActionResult OtSTatus() + public IActionResult OtStatus() { return View(); } diff --git a/Areas/OTcalculate/Services/OvertimePdfService.cs b/Areas/OTcalculate/Services/OvertimePdfService.cs index 173b241..6f54e82 100644 --- a/Areas/OTcalculate/Services/OvertimePdfService.cs +++ b/Areas/OTcalculate/Services/OvertimePdfService.cs @@ -62,6 +62,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services { table.ColumnsDefinition(columns => { + columns.RelativeColumn(0.7f); // Days columns.RelativeColumn(1.1f); // Date columns.RelativeColumn(0.8f); // Office From columns.RelativeColumn(0.8f); // Office To @@ -74,13 +75,13 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services columns.RelativeColumn(); // Net OT if (departmentId == 2) columns.RelativeColumn(); // Station - columns.RelativeColumn(0.9f); // Day Type columns.RelativeColumn(2.7f); // Description }); table.Header(header => { // Row 1 — grouped headers + header.Cell().RowSpan(2).Background("#e0f7da").Border(0.25f).Padding(5).Text("Days").FontSize(9).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#d0ead2").Border(0.25f).Padding(5).Text("Date").FontSize(9).Bold().AlignCenter(); header.Cell().ColumnSpan(3).Background("#dceefb").Border(0.25f).Padding(5).Text("Office Hours\n(8:30 - 17:30)").FontSize(9).Bold().AlignCenter(); @@ -93,17 +94,17 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services if (departmentId == 2) header.Cell().RowSpan(2).Background("#d0f0ef").Border(0.25f).Padding(5).Text("Station").FontSize(9).Bold().AlignCenter(); - header.Cell().RowSpan(2).Background("#e0f7da").Border(0.25f).Padding(5).Text("Days").FontSize(9).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#e3f2fd").Border(0.25f).Padding(5).Text("Description").FontSize(9).Bold().AlignCenter(); + // Row 2 — subheaders only for grouped columns header.Cell().Background("#dceefb").Border(0.25f).Padding(5).Text("From").FontSize(9).Bold().AlignCenter(); header.Cell().Background("#dceefb").Border(0.25f).Padding(5).Text("To").FontSize(9).Bold().AlignCenter(); - header.Cell().Background("#dceefb").Border(0.25f).Padding(5).Text("Break").FontSize(9).Bold().AlignCenter(); + header.Cell().Background("#dceefb").Border(0.25f).Padding(5).Text("Break (min)").FontSize(9).Bold().AlignCenter(); header.Cell().Background("#edf2f7").Border(0.25f).Padding(5).Text("From").FontSize(9).Bold().AlignCenter(); header.Cell().Background("#edf2f7").Border(0.25f).Padding(5).Text("To").FontSize(9).Bold().AlignCenter(); - header.Cell().Background("#edf2f7").Border(0.25f).Padding(5).Text("Break").FontSize(9).Bold().AlignCenter(); + header.Cell().Background("#edf2f7").Border(0.25f).Padding(5).Text("Break (min)").FontSize(9).Bold().AlignCenter(); }); @@ -128,44 +129,55 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services } else { - foreach (var r in records) + var groupedRecords = records.GroupBy(r => r.OtDate.Date); + + foreach (var group in groupedRecords) { - var totalOT = CalculateTotalOT(r); - var totalBreak = (r.OfficeBreak ?? 0) + (r.AfterBreak ?? 0); - var netOT = totalOT - TimeSpan.FromMinutes(totalBreak); + bool isFirstRow = true; - totalOTSum += totalOT.TotalHours; - totalBreakSum += totalBreak; - totalNetOt += netOT; - - string rowBg = alternate ? "#f9f9f9" : "#ffffff"; - alternate = !alternate; - - void AddCell(string value, bool alignLeft = false) + foreach (var r in group) { - var text = table.Cell().Background(rowBg).Border(0.25f).Padding(5).Text(value).FontSize(9); - if (alignLeft) - text.AlignLeft(); - else - text.AlignCenter(); - } + var totalOT = CalculateTotalOT(r); + var totalBreak = (r.OfficeBreak ?? 0) + (r.AfterBreak ?? 0); + var netOT = totalOT - TimeSpan.FromMinutes(totalBreak); - AddCell(r.OtDate.ToString("dd/MM/yyyy")); - AddCell(FormatTime(r.OfficeFrom)); - AddCell(FormatTime(r.OfficeTo)); - AddCell($"{r.OfficeBreak ?? 0} min"); - AddCell(FormatTime(r.AfterFrom)); - AddCell(FormatTime(r.AfterTo)); - AddCell($"{r.AfterBreak ?? 0} min"); - AddCell($"{(int)totalOT.TotalHours} hr {totalOT.Minutes} min"); - AddCell($"{totalBreak}"); - AddCell($"{netOT.Hours} hr {netOT.Minutes} min"); - if (departmentId == 2) - AddCell(r.Stations?.StationName ?? "N/A"); - AddCell(r.OtDays); - table.Cell().Background(rowBg).Border(0.25f).Padding(5).Text(r.OtDescription ?? "-").FontSize(9).WrapAnywhere().LineHeight(1.2f); + totalOTSum += totalOT.TotalHours; + totalBreakSum += totalBreak; + totalNetOt += netOT; + + string rowBg = alternate ? "#f9f9f9" : "#ffffff"; + alternate = !alternate; + + void AddCell(string value, bool alignLeft = false) + { + var text = table.Cell().Background(rowBg).Border(0.25f).Padding(5).Text(value).FontSize(9); + if (alignLeft) + text.AlignLeft(); + else + text.AlignCenter(); + } + + AddCell(isFirstRow ? $"{r.OtDate:ddd}" : ""); + AddCell(isFirstRow ? r.OtDate.ToString("dd/MM/yyyy") : ""); + + AddCell(FormatTime(r.OfficeFrom)); + AddCell(FormatTime(r.OfficeTo)); + AddCell($"{r.OfficeBreak ?? 0}"); + AddCell(FormatTime(r.AfterFrom)); + AddCell(FormatTime(r.AfterTo)); + AddCell($"{r.AfterBreak ?? 0}"); + AddCell($"{(int)totalOT.TotalHours} hr {totalOT.Minutes} min"); + AddCell($"{totalBreak}"); + AddCell($"{netOT.Hours} hr {netOT.Minutes} min"); + if (departmentId == 2) + AddCell(r.Stations?.StationName ?? "N/A"); + table.Cell().Background(rowBg).Border(0.25f).Padding(5).Text(r.OtDescription ?? "-").FontSize(9).WrapAnywhere().LineHeight(1.2f); + + isFirstRow = false; + } } + var totalOTTimeSpan = TimeSpan.FromHours(totalOTSum); var totalBreakTimeSpan = TimeSpan.FromMinutes(totalBreakSum); diff --git a/Areas/OTcalculate/Views/HouDashboard/HouApproval.cshtml b/Areas/OTcalculate/Views/HouDashboard/HouApproval.cshtml new file mode 100644 index 0000000..0cc15d5 --- /dev/null +++ b/Areas/OTcalculate/Views/HouDashboard/HouApproval.cshtml @@ -0,0 +1,5 @@ +@{ + ViewData["Title"] = "Overtime Approval"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + diff --git a/Areas/OTcalculate/Views/HouDashboard/OtReview.cshtml b/Areas/OTcalculate/Views/HouDashboard/OtReview.cshtml new file mode 100644 index 0000000..6693b41 --- /dev/null +++ b/Areas/OTcalculate/Views/HouDashboard/OtReview.cshtml @@ -0,0 +1,169 @@ +@{ + ViewData["Title"] = "Overtime Review"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} + +
| {{ formatDate(record.otDate) }} | +{{ formatTime(record.officeFrom) }} | +{{ formatTime(record.officeTo) }} | +{{ record.officeBreak }} min | +{{ formatTime(record.afterFrom) }} | +{{ formatTime(record.afterTo) }} | +{{ record.afterBreak }} min | +{{ formatHourMinute(calcTotalTime(record)) }} | +{{ calcBreakTotal(record) }} | +{{ formatHourMinute(calcNetHours(record)) }} | +{{ record.stationName || 'N/A' }} | +{{ record.otDays}} | +
+
+ {{ record.otDescription }}
+
+ |
+ + + + + + + - + | ++ + + | +
| No overtime records found for this user and period. | +||||||||||||||
| TOTAL | ++ | {{ formatHourMinute(totalHours) }} | +{{ formatHourMinute(totalBreak) }} | +{{ formatHourMinute(totalNetTime) }} | ++ | + | ||||||||
| Date | Office Hour (8:30 - 17:30) |
After Office Hour (17:30 - 8:30) |
Total OT Hours | -Break Hours (min) | +Break (min) | Net OT Hours | Station | -Days | +Days | Description | -Action | +Action | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| From | @@ -128,24 +119,23 @@{{ calcBreakTotal(record) }} | {{ formatHourMinute(calcNetHours(record)) }} | {{ record.stationName || 'N/A' }} | -{{ record.otDays}} | +{{ record.otDays }} |
{{ record.otDescription }}
|
- - | |||||||||
| No records found for selected month and year. | +No records found. | |||||||||||||||
| TOTAL | @@ -161,49 +151,22 @@||||||||||||||||
| Month | -Year | -Submitted On | -HOD Status | -HR Status | -Details | -
|---|---|---|---|---|---|
| {{ getMonthName(status.month) }} | -{{ status.year }} | -{{ formatDate(status.submitDate) }} | -{{ status.hodStatus }} | -{{ status.hrStatus }} | -
- |
-
HOD Updates:
-HR Updates:
-1o>{6KD`;|6sTP3`nB z#jaglRJYiH`s6m~)5Eu@WV$vFib=YP zf~18dn2}3$U&j>_y)0y3&0?>xaT8X$RrgAaU4sA9D4QS(=5@mc&yz&=-@uOua!ShG46S z&!RnM9Q&{w5uJ`M9ZG?&K#wWVcRBK%dUi=|zg-B_P`@K_)s(!BkGh%nCA; 1fMtHz{Rc#FlEjgwls7RJxTDIXR|Jx+|cpM5JDb;pxc)-hw% zwA0E&)deY{%qDPeY;)4SKFA~IwXc#D6ob3q)iA`UNG=O1;SKS!6re6nj`EKCZ03q- zVuoq5Vzb2OrWH~`h~H&X!Lb6J|E~5P=~8s%ky^lkdICbSBH5liZY_(p|6#R{P^#Rm zGJivXUP;}wbm<3xeq`_1&-XP^r-JVx<*cMYJL#$}@uyZ`4w(s6Y+2L?sW@vcpRIwc z?=dzNOAldK)mni4rsYsNWLizvV}l-7rEezld3k;fw@D-0f;c)J&q!xqf^@DD@{*e0 zFZNFFZ?UQcSRQ{gH*YMePdR?2-_@A!aG!`T;~VZazQbZ9$rTV5(k{tl&>sXNhj5$| z&i#0*CMJ$TquNhO&Jo8=7nI!pBa=xY61Ff_HiucMK=D@yCR5z@BtENhMpDNd^Uota zt?46%uF4`(78d;vW;PvX!=@=Z-DQ q=*e z6}%C3v+!a3?)Hpy@Tb~7kNjNc)~Tx)L)|($HQh8!YG k`i4=Wt8d2 z#ni|>5&?RYC`DL)Bqrorp|Z&|8` a$}iW+77 z=u2D7jS!0^DC6wUdNy&Rv{W_t^cy=%U%nV`KDB4#RpY=^J5_#TYVuU8)ONgd&C4&k zRiDE`T7c&(S_RrrvU?aPtzNwa5IlF?ZbnC%V#sLCrtC3R5w`f~&hKLF7HXu-#Q2k{ zyrbC`GkvINWoYwkxIz*n7xpTN&KB>_#973-$w|S;lE)fP!C**Y)=&Ofk*SWgp%WsU zCt;50vv;O2!GD!EzKiGfB(pGYY5Ki_kycZ^MmHt@iM1Zw)GGXF#DOE(EDmjj2%B-z zc5S`s_4{V{YSXE!>A2qUOtf}2z4av!OvXpw2=vFCPKgU4?Pdz_+Y`4<0CZALueT<* z_8ZEnne3n};*VBRc~2f}m7}`RaMCqFq)XCDk4)OCS!E}}v-?i-%FwM^Vmt<674@5& zang5rIp6=9nGu>uD0(!$OKf_17;t3zSe~qI{unOJM-x%_P^ErXb=$}_SCO-Qmy-V; z=6Q&;IcNzm%J%=^fI_Pc8~4zZlXGMean895stBu!%ZUsbi{Tch4^Ta1>&F6~O%r zL8V@aS(Om2*P>i~fMl}U=*x_?k$K%M|7&BnbyI%U>6*h4!f=OiN`nM3>G8Xxo~g@D ze=yu8c#tQ8Q}r<(r0vRzu9$VmF&>m^4a)$2PPOOfeJ6#dt)p8Gy58WK*m6>{N{z zrIU^2Z2kPCjB%+Z^5?qcj*~6;bQ>ydP}Yx#QzeNpgM2{42#f@eIkJ5@uO0ou$K(b{ z30n#)na3H`BI~dVPhUT8=|@&_lhEs?H_om#jF1r{GDcvcLU+1H1@FVat6le_){-%3 z3tZhm_MNBt*$2w_hVa>gTP2Z50tw!#TA)4jnHp;ogXFWqV%zQ`olXS$Jz+D+;=WF8 zp@Dm+pa{u3S&4zvqx9sCR9#)Ejnv*wmFmdOhSgcg 6+VYFXn;bfh% z!cD}*=?(d7i&KsX`Mt3ZJ206q(zN;EIO%)6%A@lSq^X1(Kc^TIa-=MML6}xK-@x_U zOh1gXQktR5nBE7J2TtE_EU$AhcT;`SG bcud-1OKc++I}$j(XjxiEFe6Q9_uKoyb?9sKI{6+lDJ_!N|OQ`S(HDiHEn DGB9t2Rv>wbvGz1?^l7< L%yIgXy$)m0}5$SM$nlv6HUuq6^_A;2m7TOr?z2zCWm8X}wq@ z6PHX~EGBAG*ZcMS^T(mTb}ninKmd!I_Ho(Wc$WZBMTH*!|0GaYeg~BP2PyS0M(QtS z>M!a`_;1wLU$_>q_7C&L$^Ab ^@6Z +fm~u8+ULvp<(%W&PclgNyASq!|bI zZ@BFr!NsiqTl*}|e~a zvTr{cI2Fj{b`~LCZ9vxBGZG|A+GDx|be^1?TTGiSASN z#9mb?&7NR{zv@Mn{BH{Y_|=-X>X)|~esm^MYYooO%|&+K=iNY(VMs)OB;-?vC;Feh z9ZJvE7u$DRhwResh9OHAO5)Naic;kxOWEBByO2}~DWe{ihB}dpFs8E?D9xf+?v#xT z;487sMSMiTP?ds3u|&DWAyA5-X8I92%oZIsc0}5TER`1#S;iK{$XW~$#dswOi|Ym3 z%$HEbD6W+A)S>L1$4BDOze3*}#Qy4x7W`w3Gs?Sy(r0blQ)F_W*?qsqlaHM*#C5zN zXrF=cy3Wq!)fd$7z7^#^-!c9M2mT8a{Y@_#xd3T3U}XIN&8+=*E9-wrto>Qd%Kt{J z{h2avg{?}lt%urAs|9%o$6=a53N5U^knG{S|9 z4zS1&j6&hO17gTR;iyt!b5=rh#11GFcKOuW$~F?oXzF>UrV5o<1Fm@dLw4zI#4EKY zKb0~QIIA)`W-}Qzb*NnR*Y^_k$*A1)jJ5l(bwJQ5rq$B37u~%PS@sRy(jLwBHq03r zVZm}^K}e_AxW6%Ynr&}@w4H+7-r206JY7A;@WY1&fM7s3&Cg}MT-E15za(MRH6Zr{^=H*z;Z7#xfCUDCygd)!9P~3)GU-Ex5BaY$MGwZvU$240L-#QA_!{kW z@dpWl;gc%f%m(yb=IOY-3xe%%`xOU3hipIEAHWDTftT`evv|E+eA=e+djddJ#$A?) zzQh2Yhoy;|37DZMw}whwYj%jhLNWaKaB{Hip2m~kA+hB_ZypcJ3hJ*bP#`72iE^@W zva?yEt3VHOz`kHYkS7U)!VoWAd_do#cge*Tg?D!hbLxfxg#c@q^!BT1>< Hl?dXTickdU7ns)(Tw}UKuy=S69 zFL*Q%Cn2_LF-P7 rOWWZu?Bf}m znw}x>S0Uc2Uu1YDIlk%$t%OZBSk+x=^{3sRw4(+g$3o+{TJ+;qiXd%a50V$N1ZeW5 zOIupc<)c)kP3H|1lmSSdM|_EIv*zxVH=vbi6k(VP5$O+xlH=;ARje@{!7RntmZ#it z0F4~+ uZFBZ#+#@S-Q$c*)Q%36u?Rd)93GeXVAM{NVHbjhwY+1@W7oPu z*WKW*&z?V=%6}zZCL+ehZp-B}-!MR6g)dOSyHe1Nq%oji@}WsxC1*5evt@#z1el|) zG)`Es<09-)z=H=j^5hr>>HWCYqb!SIyUZgOQ&+}4(xM+bJv6_7C+rVcCGFMjc|lv% zn?Wn%5~aDVaQP6yJmaxxb+mX5h!>O6$0(YsVQZP?jsoY-<)z5N5|Gi~#$Ka2j0uE3 zq)W##85# yH&it3kKA4hZvA20TP7h5wQ$`>V&oIT?_*r$&4T;FZXMzYJ-gJ5(07c ziC=&dcPRVjey27J=LBfTlnFR{_Esl^6^(!bL*aRWQrILXwfG9_iC_#u u*R42>r9M08x%hG0o`Tme%N@YV#o1{<7!`qm@*G-e;^SeOfug@BXG*n`T~9q z>8mud23wqnU3#B;iOhtHRY&n@f46HYaSnM7X%1x$nf|ZS -2JOUJ(<@hPvm0Xj3?J4tR=T2SK`|<;p67Ajbh)%DbG`$ ztTP!O%G-iD1!Z+C ;}-2}7=DPVR0A-7BHx3lNHa+b5j@e=SHkG7 zke&5DhM}QSPD%qXG-Q?l9Ax}H7D-&Kl04T4@~U}q{%A}^Y`-~omGfdfna<27dmP{Q zkFFfIl(C*{w`NDSw%H(P)RDO6JPzxkQO!4RUz@rMPbY7=!OKr4Uo*V8_mjPFQ>afJ z4>hRg9*} EEE;0;oeBL2;sNrWnAeK=E+C?kdXa*o zB?N+GZh=z7os>s`FKQXQ(7A|oLl&(m`#q)#dyqQX5Z`gkfGU_Jpa8oMow9M3-cPGi zoNT#4E&Z+lli}BfoYwoNF(b@bjR4%aUyM}{4H%DvWXoFh+~FXosl5 $#~5=*az}5Go49O}4>CuRRLNUdGcs`LTjDONw=r_;|6+_Z#DtDZekm %w9yIG`@i!cHV3a%;7239fhdnj>zV9Re3?Lpo9W3H59bXQPItYmbm9_pkV0~|V z2}ir5UD<^TTB#@8TOetnl_kEMzN#>Y(t~cs9F7Zb!2hIFbqTv#kYsNhCcOGy9Z%kj zt`$dvH2Z$P+dU(Ta%Z(`A0#GrqNDmIrNj8{i2FsC_HioF@K9!^z2o5S@b0kM+hH2| zw*D#Q3(IN>4ZvK3aTHf$p{EWind4if|B4kc)w^Ir;{Jm(j}xb*sl9xg>`sS0D7I>v zp+q4s?Wj+R;quIo%Zi(rMnINFel3cJokXCLI^S!bn(#*hcW&%_c*CM&RG8k{*c_Ck zky;eNf^t6cdV3_+>CWT$5bVCSu(PUmGQ w%t|C>Khd3rek{-Y{Wvy_ zk$!T-Ir1UCF+L*fj3Mr4E`JvXu2Mc?8f3E=_T^HmVp`U#ta6&bNjpTkT9mx0Cq>~f zyfpR1fj^2kYGi-v&MjLftuv)_U)U%q;&7%rW~A6h@`WN6OGTzbXOuHU4}uRrCY0<| zyI4BmE@|KmDcg*k?lV#MgQwUbc^4@YPU%~6i6~nVzo>ggtlp R^8fo}TP(a1qs?@fVz zTMzcxEGS)iXOtAxSvoVVmj!4^$CiMq{8FiSx T zl=V_drTiC*tdw_d;W%h6+hpaAzSycKc RE*&3saH7p#dZ4b&4-ft?#+hc z2v#V5zw+sZj;WX )h3-&vI zn0B%w^TrQ*B%Es7a?*t@yvlg 5OP&Fl!ORd&UrHasyRT{dv1BOj6@UDlCSRF-4p zb+e>p>Y~xTUMoK(t?Xvs$AyyM+h5j;b12T7naec?u%gO0JZRRZ7k+Eq@muW+NKslG zY;7ehk_a1(19!{DOqwd96b`S_6SP*sv5|FQnJ)UIA^($$4@=Rc)u(!3QmY1O)c*!o zR#h0Eq8>Zu{#WvFf-0uTbHW@$qL>IDG;Z%zW`17MEemC^Jz`PnSSVB0i6u8@Au|a+ z5pE PYt%g-%vQBd z(|@#p;6xdDkrOx5A@c5X&(b*S)zL1trtU1aJlx3P9jWby)8LF!uSW5*;s@3jhh1(z znhluBEtSza`B~e(E`+WUB9MdkA6?fsepm~LXbfo=Bt zd4^f=2OLr4-`Z@Z+5szfvE^;Hf!jW|{K>CWS75slmdus_V{Vj9Y Rb+UsU4= ~>;^3J!|Q*{OeNwJgwM+1n@QC7oqX{UvtAT3I6W9Vf&-{j zk)|u`g_*wXX?Yl1yGEFso`rXanpcgh*m0(K*)(Qd1IS-e+>eg}``h&~W0qET%_v&h zi#)!K@4F>M5;!kB^Z9dRKi!dP$DOXZTYcRNKZ-|H2=b`NOqPctg<%0mp3mIe=3p#3 pl>eI;VpKe?2&Yc+okFPO^K4tg&$*AcaceCReh~1L10Pna|J-&u~ z%9AJ!=MS=k>PtQ5fG DJAHt@$fzzN zH3=@Bmg(Jkl&GjvhX;0wJWJ5Rfor5Ffh2hwgg3q*ipas-TB`_3_*l;c-*qCCwRX#| z&~YQ_eEP`?cTWn(3ll5^1|h3SC_gzuSs05@+3GonxMOtQ#MLNNGG4n=b7ZtHs_A$+ zKD(c-Ue@aR``0BwRg?gp-#BccxgJGwyk3ui7M;_s928=vA9rf{KfCJcP2#33DQi;A z9x? ovQF=4EXaZaF-KczC}BlAF20lNHO(7V2OYANP@_p zhw%5iy953UPTry{L2lU+(|xoXZ;6}N4k>(yeA*1Xs~t=;e?xo{Oe_ogI-OgVo7?mG z*OjVTTUI(7MCjI>X_Xxd-2`s$8d+7~6OVS7ro-I0-IoJHbLs_@*6zm{lIB{6HDfgQ zOgt;AoVOpt>oHs~MlF{`_LPLnrv$6i0(W;>ixQkey(Qhw=Qk1iO_jEJ6`yLOWGJPV zwKqltk_(nJsigDe(-+XdlqC8g0BqwpStkMHmXt*M%B_xGztB%(psM_is+>NmRZ-In zhkyo42h{$Qzy(uvJi3Xn$&jbz8BijbTXdayYD3M_gB{|L_vs21*#F7KxyF~=Vc*x5 zVB>V35)BcdrnAB@XOpvr99>hxvT}8xv2US&yD!Lje$~**z@PKw@J%G;-9Tk%nrg6< z&UpWBv9espbnkqb2rMus6jd$v*zyAj`|&TaT=aG^Fj=$NV1A1L>gXFwG7WZQpFu;V za5@UYrZiDYwK2X=M>l2zI{NCuxCEUmcbvA*2Z*;LwSC|@8rM69?$HiC^JjFHgaXai z%Mu4eF}@9eHI9sn %l>P9A-w>Mv}&pFI}rzhiSMqY7BR~q-w+WC$Uy|>_fM+opa zr6EbbR!34C=tp=aZe3f#M)C+7P=e)k-U+;EE5zQ1rV*~^rirtsXDf-ql4w?tWckmq z%_hqrSr?B+LXCbZ6$)eaNwA#Vo<3lUHY%A<<7C*3D_*3LKRuAiSWpvAx0*y8wWWA$ zQ&vf+Z>p&pyxNg$l|%1 k_Vh1E>u1p6P836{VQ{?2!hv*C@=NNr+ozGi)%5e*ass;b`4oYJElg> z@UbAs$9NcMN9;(ooE;ag;+QBi87fOMGl|+ho5mtC8w?hdtF`U>Ecyn1H3swyca+7K z(X0w}HFb16*;WMq*&w7 )WzBMH?t>qmyVwPd!=_qYk4H?Pko|a1()tN}jLv$asG_@-%i+X-)IJZ4l&tA_H z @RMP-qH;!m2hxaQ!xATQIMp%%m~rjHiV)a &`&`_N8k0pfXXd^641Ki*$Ywh;regvhbbojMTszgL#dtY?p(Z!^O#m z1T^&tJC7!h^AW{^o$S3m{*Lt(+3xq3mv>)URF80tY(Ta~PPAxt_WSNN7QnZ->U3<9 zN$&-x1~6FE2?Jv 3cHi0Xw8x@cL`y(NYSf*kJjNivr^oFP6`OPLI(N `2mymuHI+7PA`=&9UIyvu2T}6?T@d<@W{>_ z_LUN@Q@X;`l1u;{l*etjZZ% ~JiNnw-v{QNe znq}@LyFS(Kp+&(aPWG-P8N$Za@p0#jCT~xtwI{FllV1nhLyJidJQaK0@%rsY`4?u3 zn|ki!dvSXgqJYMl_o <~N+rDzX;lqjP z6}pHt042^VEyF7g%~@iN90}Ht-4!Wp_uV^-ys$5MDlMb02|37gv9D=8GirIyldUR; z=(& abII zrL!#(^vCLkOGhW|l`7Q`3MIZN_7T+#Rfgq} u*5z+AU}! z>k;4$aab`d#!>z?3G$FW|Fs!>GhEIbjUnU<|L3ITwTWJPAvsI+Z}f43E|6MJ4~E|w zJ1g32`MryCdsUaUHV>^;XhpoVwDPU9T>V3w6Sp*J-CW$b8iGZx0fw&Wa*uR)Tvck# zkZaM=Sy7!s3!RxI{I2+*7T_Ft=t-YKG`&uye2ZJiPMgv;XvQ#$xX0Ifx6ijq;Iv2R zCj2qac^Y^0a%j0~TDVMTV~0N^y RKEPP67zg0@ zqHeDovNe46)R;=BF
3jJ$$K0?BuD!o| z2LisgZJ3&~1ZPD!=11B_tPrVbt@h>A*uR8c9{b!3Egs@2fxLoxbKPGyH8>x>6@44^ z8O42Iw)E==^BRs}xi#E+?CYuc0(H8Dqk}%FBlw}8?H7_5^5n&S^v1ggQ*MA>4|QkH zdEp^aXOBI}q99juO$@!t-+zEJMWDAf&; w%vfrQ(Mdv%E4`-j~6=F$Ju;8_2|T=} o z30VEVv}*aS_x=yM{r_dw!VVPn|0&x8mE*r;``=RVUpEC5<$#7Qe^k4_t9XAifBw6w z`0w2Uis3*x`rl;x|F(Dk)FS_X>h>H!D{n3?pc)QT$hm$Sulyy>vwsAZ{pHp2mmL2` zX$LlA25ROU9DkH_;1L|0zk!E8>N_Vpu=X$Y{g0yl59=1@|5i}{eat`bhyR!S$;QI@ zcfXE*S+@kGjF8qLNKvB-OOr^_KNZa2gPizl(GIdsd|gqGw4`<29N51%8}#i9Z>x;D zOYCfy;{0V<6XnFL;7;Z5#%v)XDw>q+OV*KKYz<3yRHtc%WNiBsW`a|60uIIR)jYK( zCP#1r>*WlW$qBx;7H+1X;oN+OC(fMh6u+ WiWMLK4^=UoT7bitv0 zBY*K>(hhNXII|ULhbkODlT7FA*~;>AS}KD%LEZkm%Hv)2<0-;j_HDkckIIoQ=>FCI zsD-7XJkSjCU_hNb2RtiwBI7zdF%VWNH8yi9P4p8Tm?0KQiR7i}yr?I9AitO=V&YbF z)4e^3%j^01fJ)=CDDBq_`?K5{k4i7EK!)=P|H~E~o$t6+oEJa4vrf{tJbgiO@3W%+ zb8Y_3LFMl=`JZ$0KlJhcb_)M*1@b?}NB=I6|DFPWUs``NnfWh)oQ;*`f3kF80b(IQ zPatBTagnK^EgUdqnGdXsjzrR(`fc)hp`B}Uo3^sGN7Z6g71n7xeKUnjG{sW#X}_9R z#BzMck7Rn@+HLyO{t@gDZhwC%?jia TRpN1xZ)KD(Z)H`~oycS3^^M}UxiD+CN2<#ato)PNO3 zgY>0SRMZ@PIXkTBKtj#|wQw0Y`jL(YXuSs$Vh0HjY2VsrO18TJ@5KU%=WuxyC_3#e zQvkck0MT1#?Q&gYst0&uegpru+RoACp4kW$3lB0_RlsF~vbfQWsBsOMyK`zwc4;WH zZwm}80|h}?X^QG+vu9(120FdGthk->UWoTUVk I0tVumOU1|%&$SfGVg!L!}Ld0$Cx2O0UZnRjIMXCZ+RNm1G?15|&= z&X}znbp%;dC;H;Jp-5&U3vX1Xp|Z8(HoR~O)o&3N;;SuVEkcZ3p78N3NsTIcbnan| zb)=W{GDGT4h#!%b5Yv!G{2){Y$m@8zz8=W_^60(Tk`nw_=Oh$Ch?8ofPH}SNxJ`o0 z;%RbVm5mcIU^E>`vJJN_{Lx~JLlOrg2KCiVuERRs=(3Q#gWI+cAk69yk==u4Ge-)E znjlL#L-SgBFf~b06Dv-Zg`C&TB17S$ nbJszK5PPS!VwMZwwS6Q27r+m0FS>gwdEto zu*ASIiI6yBM+;^~t=wve(n&8ir2|3rkX%c^HHR^tFN~w3`^NkMUYns2x~(>qxEm=u z?nX17$5 -Vk5?I~;fk``088`n!N07|^9} zy`kEl91{-Fa(~)*!hqTJnwd>IsA$QVg+%5)u*+^aZ@KrM$D{4|UV(VTdS~;w;IsuW zhry1Jd=%6DDoRc}5>FB(zxR?Vrvv#F4%wunK~`h@Ml15eIZ~(1D=RYh158?e>cEQF z(}=VaS8IrOsCVkNUr*xt#tzI(i(CvNlGz9_0}o2-C#F6uW&?r@seD*s_g`tM=~DNj zW$ZyH`jSPEiJJjs>>0MuDweP-za)!H1=0ojYmtm$3c!tlwkHb)5NJOmPO ?N~; FV)tUZ<)O|p(6KR; zG&dk| X zf>~UlKNl!;hWXSgIy4`e`@~AN8bQK1??~=Cq{tEu(`>7)6ozpiPV~b=5T|Lp1@~E* zvpQ>~1=ns{nz7DtEL(Pk*G$fAR%+$@3Gp`78GhQ&s1BKKmFrlg43OcOm6;9L98!{# z05a2@RE$lvB#k`36~@;{UwMUt{h#z$_x`;Q{?KV&N|a{ T?hPd0b0~*_CW!0B?-U>@5i$^B}UMJ?b^|a$KhI3nO6^`w!hk$ugeifGNkc9tt z0D%vf*{n!$NQ CIOe!nyrFp&dllo? z2I#);X2!Gmy+!MdUfr-gX^*hJ;+MQ9=@oW+pp?}6y|wugPN6wJyaYP81Oosn?@HlF z$CFIA8%IqMEicjlk@v8-uXgkLSt~?(?~z?lQ-b;3rQPM-c?y>u^-mQ~qn `^=SrNOsX+(puQ0)!aRqWa7HA)rMWc~^T#`6?r+yTO#3vGuM(Vx%#LXIskAS&) zBVjMHXA%1m5h5BKZODJjvB&KL;zUHTq1;Z#SPSN&@SvGZaH#E1sIVCEJzH$ -pKJt}(&?MaV6?>*yfrgHU` z?Mddz{ub*aC!i!}HqA_L5m4|hDwr{sm_0Rl+`Xv3IC)@xYhSDLity_7^zl_)D(Y}! z5l{qB0O$ZxQ?lkarW6i{rrtkwe*(l^8^L&e0>}xL QE`7MsY)gww z$GVukO0#9bq?#kGfIPuE$|+INj;)Zr@@K!#mH>7O6wM+r &*r4|~%tw0i$nhn|XeWW(2?(uEwciZ}YFn;hfLH|NMBd&87B%)uLTmb~tu z L$bg?i>JxI_>&h@XcZ^>)C7dwzdCl+E{duL>u8nSE{J$QRj7TrgYL;~m zbaziW1DF$@@h5$f0e~35dnDjJah6{${Wj+EIOkjT@#MwozEu4iUiPzb_A|t6*Bivk z(`<{1Ac6%94Q@5gK{$={dBL~pllh(bW2gq68Z}J3)qMO;Gob?iFHU59g?4vO-nd4% zJo5uopQb+kL|KrORDo&^ 9Pc^Mkdp FP;Nr{`hJQ1Ip{Yzrp2(9Bvr*I7 zXgn~8jDu&~%VH0f$E80wIV!yvhgm^Sr}K7>{{UN#%frFKT ugT56^DNB&ZdUmVA3OruMod(-*n+MROUU0G+3BOW=ZCfx%m4Uap_3}(!Z=OjBs z>LGC?IdBhB#|-q-*r)PPn#(POa{&hNB 1HR-%r z7z&)jl9yUd6bqa`-!j5wLS!BpMY&j62ui_hq7C5ml3Og!gQv@#Dz>plEa# h(fTkjFQfy~DV2BQCJeeZT{QhkZP7W2bT_hoKAbYB?XDf56aCmEV zs<3~nW2$h>$lhY6XX|CEFm3=cPYNw!R76^o46jcMQsD&F`crl)jCBx+McQ}4f*7$p zDRij5bkuZm`nw=XnurLI1h9yC;K_^t7RpAB#OyTnE#&N$29A~%Gs9bTQ-xszd9gEt zB|_YV@K%}u(k10_pNc2BGXzM2n j#o xF3Li>FfK4n_f$U!)wFEZ_qYO-&q~YDoI#CyOGXs&J9%MN z&;`m3pEx%P=%5Mn!gIe6 V%*HopUVQt8&h%S~Ot<0*plHRLDH@OgL6_QWAc7(cs zJ*$R?g@Y#~o!{a~oZnC;z;x_Lt77PrhS`b_eDE_j^IT=6GT%8$i`ffUv6&=qbDgy~ z0&G0GG#qBjZIH^O1Es3G=KW?cBV@%T-IyyGGDpr7CZi`zoR1F6oh>kf8j63pjNlg& zkW_vAqN=ovtr5+s8!V2-OQuDRy};Ajf(=qqG}=={Ybz~kD}C$eXfZ<##bXxB!@o`^ z;yAMFce$S%GZM9w!r3@-EHm58lze22g*Mor*uM1OBYRaDQRX-X?;#}_K=<*Z!q;&T zbJ2 *u@iW(Seev+zM(#l)bGS@O`(L;gq!IIrMEF*_G&j3SP%>(jp z+}I1rA@X0p^@mSM^*TR^P{B@Wj##vPHMGSjFbtcI45p|yW2bjSD9}WQx3 $VO-~pb40NCml*ou=GH~HtVMH{dP4OnE2gCGOXiklqDmL6@Ou`*_%VH7(3 zt)CfK6&Jg}O18&vB5aKm+*rle$c(+v ||D zI(C6mq%A`in1?IdsBoKaK=MAY0g|l{?c{61*)ENETMV#~Yo3HGX_i|y&)0NEQM8v= z=;D-2W^E+I%M1GKfqL>DV4Om*@ecN*lhy<5rhi*mhFvE)ejXO&_iQ+Km=p-5Hlqiu zOa8Ae0NM`XPT&ixFo?j3^=0@M*8>9A FI!YTcL31e)X031@QiP(87-I_Oh){{gSY)Pax>_vT!NS%FQ5uZYnah#6$G<6&2fY zBE$oBOvd0}$7_*)8+u&dG^^!( *%gya0$7tZdlSLS@sfnA+v=J6Cd)uF3KEx0`IWw*9popD8S74cavq+sS zuP_vkGBCqX{}{}xL~jTFOceEzs21kLz3V#11NP;!lpoyBPri{H?@98r>dcO I~mG#VK0yo@k?`&T5b@;m`A89`ZY~pZUhyA`^Ng>6HL47faecq4% zyu?4A-rui!jru?r?`M+w+BuywYul%UE@IL>fO=horZ^p{MlY(~01if>O1w=>O0i{k zM=b{G0z*n(K#lO-B;Gi7H%|{cDi|9+*idAn*R7quy;8Jln29sv!`BHnWo;En-6geY z@wu6Jx7x01QHCbv#+EtFMR}DVRfcHAt@>wNAGeM3bV2qx{;m$b?tIF8=`-llx{?k~ z9aW4=_2 8dXKRxBLYvc&M@pF>FE!{n>nj3s$d@0 z0?_=Q401cvK8q~STYp!z^hKypOVC$5b#Hx{- i zCkz8g^s@`5M!ba!j5VBrZqZ#r%$PU&iXy(0NkA?fn5Y%@iP*|fs_Yk9CAnm%!b3}P zn*I3Lq_;-Py9b8}PL`*`95&4xqb(((maLv4l$Et{SD^ioxfLOe+{>^EX_jA)? S^v=|&oqF_XnUpxso3WQ^4+&97zh}Z>@_~0Ue7+$u7+{%94Gnz>kQ#12g zM6+1<1fbznsb$HnD@ys3lclX3`0OViWrjK8wz?|S+oeNw&u01yOmT^1@`=}92f88A z_|GZ#%@~Z4?(yMgyxFa$N9G$q$JG!zuj6Yp@ch)D>>bvVzpfGbhKw5V)ZM=D+#(F! zix#2fR=&@ed%Qa