From 5ccf3fe1501be4b8d8d4587dfcc0afb0fdfdf8f7 Mon Sep 17 00:00:00 2001 From: Antony Liu Date: Fri, 15 Mar 2024 09:19:51 +0800 Subject: [PATCH 1/5] poi: Bug 60452: WorkdayCalculator calculateWorkdays does return wrong value for same day input --- main/SS/Formula/Atp/WorkdayCalculator.cs | 20 +++---- .../SS/Formula/Atp/TestWorkdayCalculator.cs | 60 +++++++++++++++++++ 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/main/SS/Formula/Atp/WorkdayCalculator.cs b/main/SS/Formula/Atp/WorkdayCalculator.cs index b900fac31..ccad037ad 100644 --- a/main/SS/Formula/Atp/WorkdayCalculator.cs +++ b/main/SS/Formula/Atp/WorkdayCalculator.cs @@ -187,7 +187,7 @@ public int PastDaysOfWeek(double start, double end, DayOfWeek dayOfWeek) pastDaysOfWeek++; } } - return start < end ? pastDaysOfWeek : -pastDaysOfWeek; + return start <= end ? pastDaysOfWeek : -pastDaysOfWeek; } /** @@ -199,22 +199,22 @@ public int PastDaysOfWeek(double start, double end, DayOfWeek dayOfWeek) * @return number of holidays that occur in workdays, between start and end dates. */ - private int CalculateNonWeekendHolidays(double start, double end, double[] holidays) + protected internal int CalculateNonWeekendHolidays(double start, double end, double[] holidays) { int nonWeekendHolidays = 0; double startDay = start < end ? start : end; double endDay = end > start ? end : start; - for (int i = 0; i < holidays.Length; i++) + foreach (double holiday in holidays) { - if (IsInARange(startDay, endDay, holidays[i])) + if (IsInARange(startDay, endDay, holiday)) { - if (!IsWeekend(holidays[i])) + if (!IsWeekend(holiday)) { nonWeekendHolidays++; } } } - return start < end ? nonWeekendHolidays : -nonWeekendHolidays; + return start <= end ? nonWeekendHolidays : -nonWeekendHolidays; } /** @@ -236,9 +236,9 @@ private bool IsWeekend(double aDate) private bool IsHoliday(double aDate, double[] holidays) { - for (int i = 0; i < holidays.Length; i++) + foreach (double holiday in holidays) { - if (Math.Round(holidays[i]) == Math.Round(aDate)) + if (Math.Round(holiday) == Math.Round(aDate)) { return true; } @@ -251,8 +251,8 @@ private bool IsHoliday(double aDate, double[] holidays) * @param holidays an array of holidays. * @return 1 is not a workday, 0 otherwise. */ - - private int IsNonWorkday(double aDate, double[] holidays) + [Obsolete("will be removed, not used in POI itself")] + protected internal int IsNonWorkday(double aDate, double[] holidays) { return IsWeekend(aDate) || IsHoliday(aDate, holidays) ? 1 : 0; } diff --git a/testcases/main/SS/Formula/Atp/TestWorkdayCalculator.cs b/testcases/main/SS/Formula/Atp/TestWorkdayCalculator.cs index 8f0f069f6..ff74d8753 100644 --- a/testcases/main/SS/Formula/Atp/TestWorkdayCalculator.cs +++ b/testcases/main/SS/Formula/Atp/TestWorkdayCalculator.cs @@ -16,6 +16,7 @@ limitations under the License. ==================================================================== */ using System; +using System.Diagnostics.CodeAnalysis; using NPOI.SS.Formula.Atp; using NPOI.SS.UserModel; using NUnit.Framework; @@ -66,6 +67,27 @@ public void TestCalculateWorkdaysShouldIgnoreWeekendHolidays() Assert.AreEqual(4, WorkdayCalculator.instance.CalculateWorkdays(A_FRIDAY, A_WEDNESDAY, new double[] { A_SATURDAY, A_SUNDAY })); } + [Test] + public void TestCalculateWorkdaysOnSameDayShouldReturn1ForWeekdays() + { + double A_MONDAY = DateUtil.GetExcelDate(new DateTime(2017, 1, 2)); + Assert.AreEqual(1, WorkdayCalculator.instance.CalculateWorkdays(A_MONDAY, A_MONDAY, new double[0])); + } + + [Test] + public void TestCalculateWorkdaysOnSameDayShouldReturn0ForHolidays() + { + double A_MONDAY = DateUtil.GetExcelDate(new DateTime(2017, 1, 2)); + Assert.AreEqual(0, WorkdayCalculator.instance.CalculateWorkdays(A_MONDAY, A_MONDAY, new double[] { A_MONDAY })); + } + + [Test] + public void TestCalculateWorkdaysOnSameDayShouldReturn0ForWeekends() + { + double A_SUNDAY = DateUtil.GetExcelDate(new DateTime(2017, 1, 1)); + Assert.AreEqual(0, WorkdayCalculator.instance.CalculateWorkdays(A_SUNDAY, A_SUNDAY, new double[0])); + } + [Test] public void TestCalculateWorkdaysNumberOfDays() { @@ -110,6 +132,44 @@ public void TestPastDaysOfWeekShouldReturn1EndingAtASaturday() double A_SATURDAY = DateUtil.GetExcelDate(new DateTime(2011, December, 10)); Assert.AreEqual(1, WorkdayCalculator.instance.PastDaysOfWeek(A_THURSDAY, A_SATURDAY, DayOfWeek.Saturday)); } + + [Test] + public void TestCalculateNonWeekendHolidays() + { + double start = DateUtil.GetExcelDate(new DateTime(2016, 12, 24)); + double end = DateUtil.GetExcelDate(new DateTime(2016, 12, 31)); + double holiday1 = DateUtil.GetExcelDate(new DateTime(2016, 12, 25)); + double holiday2 = DateUtil.GetExcelDate(new DateTime(2016, 12, 26)); + int count = WorkdayCalculator.instance.CalculateNonWeekendHolidays(start, end, new double[] { holiday1, holiday2 }); + Assert.AreEqual(1, count, + "Expected 1 non-weekend-holiday for " + start + " to " + end + " and " + holiday1 + " and " + holiday2); + } + + [Test] + public void TestCalculateNonWeekendHolidaysOneDay() + { + double start = DateUtil.GetExcelDate(new DateTime(2016, 12, 26)); + double end = DateUtil.GetExcelDate(new DateTime(2016, 12, 26)); + double holiday1 = DateUtil.GetExcelDate(new DateTime(2016, 12, 25)); + double holiday2 = DateUtil.GetExcelDate(new DateTime(2016, 12, 26)); + int count = WorkdayCalculator.instance.CalculateNonWeekendHolidays(start, end, new double[] { holiday1, holiday2 }); + Assert.AreEqual(1, count, + "Expected 1 non-weekend-holiday for " + start + " to " + end + " and " + holiday1 + " and " + holiday2); + } + + [Test] + public void TestIsNonWorkday() + { + double weekend = DateUtil.GetExcelDate(new DateTime(2016, 12, 25)); + double holiday = DateUtil.GetExcelDate(new DateTime(2016, 12, 26)); + double workday = DateUtil.GetExcelDate(new DateTime(2016, 12, 27)); +#pragma warning disable CS0618 // 类型或成员已过时 + Assert.AreEqual(1, WorkdayCalculator.instance.IsNonWorkday(weekend, new double[] { holiday })); + Assert.AreEqual(1, WorkdayCalculator.instance.IsNonWorkday(holiday, new double[] { holiday })); + Assert.AreEqual(0, WorkdayCalculator.instance.IsNonWorkday(workday, new double[] { holiday })); +#pragma warning restore CS0618 // 类型或成员已过时 + + } } } \ No newline at end of file From a496566ac38954b0884926ab45d4617435084a18 Mon Sep 17 00:00:00 2001 From: Antony Liu Date: Fri, 15 Mar 2024 09:26:38 +0800 Subject: [PATCH 2/5] poi: Bug 60512: Add missing XSSFRelation.CUSTOM_PROPERTY --- ooxml/XSSF/UserModel/XSSFRelation.cs | 7 +++++ testcases/ooxml/XSSF/TestXSSFCloneSheet.cs | 32 +++++++++++++++++++++ testcases/test-data/spreadsheet/60512.xlsm | Bin 0 -> 66151 bytes 3 files changed, 39 insertions(+) create mode 100644 testcases/test-data/spreadsheet/60512.xlsm diff --git a/ooxml/XSSF/UserModel/XSSFRelation.cs b/ooxml/XSSF/UserModel/XSSFRelation.cs index 960d2f959..c61b3ac69 100644 --- a/ooxml/XSSF/UserModel/XSSFRelation.cs +++ b/ooxml/XSSF/UserModel/XSSFRelation.cs @@ -315,6 +315,13 @@ public class XSSFRelation : POIXMLRelation null ); + public static XSSFRelation CUSTOM_PROPERTIES = new XSSFRelation( + "application/vnd.openxmlformats-officedocument.spreadsheetml.customProperty", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customProperty", + "/xl/customProperty#.bin", + null + ); + public static String NS_SPREADSHEETML = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; public static String NS_DRAWINGML = "http://schemas.openxmlformats.org/drawingml/2006/main"; public static String NS_CHART = "http://schemas.openxmlformats.org/drawingml/2006/chart"; diff --git a/testcases/ooxml/XSSF/TestXSSFCloneSheet.cs b/testcases/ooxml/XSSF/TestXSSFCloneSheet.cs index aad263620..3bc014638 100644 --- a/testcases/ooxml/XSSF/TestXSSFCloneSheet.cs +++ b/testcases/ooxml/XSSF/TestXSSFCloneSheet.cs @@ -18,7 +18,10 @@ limitations under the License. namespace TestCases.XSSF { using System; + using System.IO; using NPOI.SS.UserModel; + using NPOI.Util; + using NPOI.XSSF; using NPOI.XSSF.UserModel; using NUnit.Framework; using TestCases.HSSF; @@ -59,6 +62,35 @@ public void TestCloneSheetIntStringInvalidName() { } Assert.AreEqual(1, wb.NumberOfSheets); } + + [Test] + public void Test60512() + { + XSSFWorkbook wb = XSSFTestDataSamples.OpenSampleWorkbook("60512.xlsm"); + + Assert.AreEqual(1, wb.NumberOfSheets); + ISheet sheet = wb.CloneSheet(0); + Assert.IsNotNull(sheet); + Assert.AreEqual(2, wb.NumberOfSheets); + + + IWorkbook wbBack = XSSFTestDataSamples.WriteOutAndReadBack(wb); + Assert.IsNotNull(wbBack); + wbBack.Close(); + FileInfo fi = TempFile.CreateTempFile("60512", ".xlsx"); + //Stream str = new FileStream("/tmp/60512.xlsx", FileMode.Create, FileAccess.Write); + Stream str = new FileStream(fi.FullName, FileMode.Create, FileAccess.Write); + try + { + wb.Write(str); + } + finally + { + str.Close(); + } + + wb.Close(); + } } } \ No newline at end of file diff --git a/testcases/test-data/spreadsheet/60512.xlsm b/testcases/test-data/spreadsheet/60512.xlsm new file mode 100644 index 0000000000000000000000000000000000000000..7c38c6d279a37a14007d2ba6b395594c893c4b89 GIT binary patch literal 66151 zcmeFXb9-f9vo0LlM#r{obH%o8yVJ34+err<+qP}HW1sw~iAb!ilSWRZE#yMD$X3vScv`eWyr$jg9T??!MuD z3P!e%%CI9a;}U3f^8K!Kb)Fsw1MRZb%vO3A@|aS)7KDbNXLf8%f(E5?CTFj0WQ3J9rn1ri(6kc4D7ipWr`6Ft5ko`Y2;8{~3USeU^Lp^50xj)+*iF7?Wp zzy3%SDxBxxA4HK2duoFPn26x8Qy~qfNPGC7w~n3ne!AI^qh?yPhBUn@*~ZD}%&*=Q zDG(L_i)M9?kn%{;t<93_JfC&aP*pUBRcL-*9lcLr3tC^p16vuM zgE2nBr@|F9P3C{`vw1QuzPngGNLN5NLq3 z@%rrJ@w9;U*42@v3c(K}2D$z=N})OyBkyG^kLp}C#5^Nnb4#>goR}Ym>YH0O`W{6| znMTWRW%ZGfIBiMqBu1=w@@TNP7f!|TjEZB17PE=iWu_ZRhkPO3_zHBqi@jD*klv6L z{I9$(_06mRdk=;qU!zpHD8U?5o^iKB5i{8G>GiS<;c=-z^t-Hih^)fSm`;Vgo{$$ns$OgZa(wjo*0F6!&=Nv!n`% z3NamAlDD_%w2kEY0>4NVhN6m5O zh(|yJy!-k-Lk-82&}!Mm3I*Trjf9wE&)cOJVvfd@Bv&3HpeoPROB}8nibR=@b6akD zSh#x^{y5M?QPlxHR-nQ+UnucsDZh|k%%HtM_^h;{o4?fLp+ghc=Ij+8U8!HwV&+|N zpn40k{g*Zkh{%pRXEy#|`246=F zGU<}GDR*K_X**g3@EvSY_83Eaag;d*1z>^@xb-I@xRIgBVhAyX+%RFwmso!7d)>do z{!gx0tvsyq{&oX51P~C~zg^*MVd!LPqU_>iX=m>IPmKGhtlOb7A^A$|5s1_D;;xb= z!3fnaq7)-h{i!se>X7T0udZzDT-l0yw0_3)i&`z(Gb;7H-|(4AA3v}u#aT&kojb8) z#(_g6q?09czsz074pYq(%xhxrte!6UDb=?a=Yx`v> z)o{F~5uB6TB&TZ)P2(Hnbcs&rcU1f=tcSM$xmQl5V%bjxvA94Kt*V#l%9C_#Ind zGCZm{jMAEHy)lIH^Un~M#%ziUrbwqSk3S|+?{C`Tz|^v}CrB~VtX9kmA~Un3gc^cw z$w(CUpVGa;?NbF9Xnq=T{280>KEs74dtYA>?-~R7=ipyse19YU{Pb^U#R4_89FBwC zHbgBjUd}A6xFb|SiAru&p+s4h<~TmEq|}#rkKf=DX7vy9ao+jbQC^uZ941OV(4aHBxIF2P@<> zj9r%D`cK+6`<(Ix#T=W70wo_c#$*(ZFirUj%5kLCWizNz#d32Tri8A!krtZ_^b!e( zdwE$$R+zcjKZH}w8k5(nhFDccx-$YXzMlDl=N0WBRM9$UlHoDY#ok+E^UJ`s*Egrl zp9KGt0Y(eqJ8r%eH~x;;|1iKmiPPD_)YRoaP4KVIe;J@Eq4%FcCgfj*4388KY0%7^ zF4CMG)DURUf^A`=l!>?Cc8*TS3G0AqGiUeTmxknrBWs*RNR&`Cx`j57;Mr34fvvvv ztJ5QVw8+S6TxC&M7G|4_^U4R<7`ZVLd|@+H%6K|B;+I~mM^L#K*D)-aIkJqbqy(?T z?Co~^$%=|AxDPYI27?M)>t9WmbY+`aGRI%5<>vvz!v~0{;#~86e-8M^O~6mfBJ|+za~hh3!@dOqfvS91FQ##^Fts&h_*eTcD_v;H+pn{ubtA606S~;j zQZ(U0x<;(jWmW@l2kb)eEz?splnVssq#@dV<{)sF7DGjefBJlF?~}MbtObVUix86@I<8mh)_8>t@Dt2)T6nvMe8}M9 zC%_CFPk6|#ZDmPbuPwb@>kej8lOhY%@~33BTn0;%WhO`58)A)*^Aa&l09wLo1JsdK zhCm2_H^WqyDi+Pi`dA+oqDTn6y_xg*g+u^z>tkV0SRF&sXTZ7PzsLbu=nyTXW25IqabHOuF&-i=u~zy{lpfNEN?jE7J0>cm-E|BHR*OS?wJ>h@=lj|Z}J z?QFTyS!vTcQTP%5rPLeTMKfRT$zI&JL5`H0hbgz_b(b3mliNu$pD*c3P4`;}G-e$6 z)S0#X4?k(XP+87(x?p=CpTdkjOvkuDvaxsJGdaDdAC8)I)AGOX9{oS$E3FUt34FNyo1(=h~}F7GF^ zxBUckbmqJCF@bx1soQ>!$IAqT0y%zne{V4lJv0ZtUi&G!-`_pCkeDrqW+NGL-ybhV zBY*RMe6$af-Prz;5POaj7cI~}fWo_ha$yN^B%>g4>_YEHQZ@%i_~izDngfHkQ_W>& z+JfL1?XE6(O9`r%yXkI%7i3go0ey^XcmVXoX^uxP4euawN3G$(85!twWTZBLXW*kT z)E;R(+}NoJqRIj*J^Z*C$7yuM@`L6_TpDH3@pDof%H@^f*@|oIYk&;D;t9SOo~#Uj zxrl@!4kOad63j0>^%Sng&8EQ})0LBE-YfJ+o1`Svgme%A%2C=acMjE$oG;x~Gqkg&!W6;^mk-6LLa3{8QP!<9r+BnhJ>)5kLD|d?N?1FagWxSTLWMe~ zesD|qA;}1PETqH1{m>z-)eHnvCs0I35Y7_Z*1Kbk7c40P4M(Bh?XU=uv9#vB{~XI< z$9?@_L=!q-6&rhb(}q74gUf|YqG~Yp2fNS}uv0a$^t(t@sCn5?ZC*G#U3)UjETW*F zPF*u|C2PF*pw)^oO&gUP7wiK`qZNACZxUyUCoR6Nsr^Cm2xC7u(j^}5Hm!(%&Wqu# z%q%Nua4dmX3lSIY^}-`!5oSXx;{w-#Co(bO;*4g+bjur+!4$dU21S7;gG$ISCGc;VO<5z19^b^@LGW+NiK`|reVNs=OdQZw4sV8+T}8FZ zkSIip2r2pS@GQw8K#^<|G+$bv6JCliNh*a6QgvOxy*Iz5fZbelWyn$YDhnE5N!HvR z+31RWO2V*$_DNWcSRDO(Ke$zda+#7H_6?~6{C=Ht+1j!kVjQ!cMx+`+m=80_2xp~e zXBTLaYqwBIw!$4%6XKt!QMW5zy;r0qbrY&a7`_WAi(OMVfYWfx9mpbrXiZc29E2^cS&ZkuCzm$K}-$lq(?BBbtti zZc`0doo<;*)hES;mj$#i*BQl*5E+W-f@XTzKPf=v+f_(uLBL&^ytiIkLPUdX9-!S# zmYck6Sv&9KUisKC2P)a&vBLw*zH|mU_%tpm+&VRLE<444Ct$RNXaH}^ zXuDb3)zum@IKSDLcY7koarzCmkjNb3gYF4dzRGUWKX&pt7KjA=*CKY_g2^EaK^1*R z+3_VYC3!dlhDH(A4CaceEa#V`wCUEX7+U5hUve0mQZ8se`Ah5WjwVcx5B9`xcp7Vs zt$CW}7Isz>sbEABF9?l)7F|KcKgwA*p2cp&vt8K!pAMcZ^NDU zt3ho6t!=kg_0E|6YRuU=eSvMa&lgT_fm6=)0bPboLM`v+Y!3VNm+?}8&)t1?PuPy% z3^}QsjDud@>z+~xlc9F*?H;$n?%wFO9c=HW=!5y0J?qb{?VAHR?Hl!xeR(`54?~+X z56gJ`{herSaEEb zd74ErxUcaNaB15!GCh#Q!w%UztbcoaJnps{ie0?D{=C1!o7j3wGUNAG8D{jK_fPx&N<1A8X_3*_2bP>Q2085(%XjC zykDQ8QysC&V688y5qT23U08yOnrpD|4JG(0M+sgcdZ4dG$q2>--VO&qBU)TSdt*=2 zxeXGiI>#PFUId746g24dw=G6jz6uZ9>$aeBC3>LCs<_I6GRJ7tx{tRRvR+KEB{ItF zEokPn<}%|L(0W8BLuJiEXPL<;a3gcK1Fdk#^vjrfj=H^jZ(_-ODCwW(=y$Wt3odsa z7^#Gt*CH2;9)m+&ZvzcZbpw|vdkL!c`Zd*|WsrAa!ko;JpsDwn$zi_uk)laOKgG$$ zVAm0xz+Zi*^rmKoU*(h(X0f@j2!SuJh0sDLdh3S+ zxenJN`8YB7+OT_nlppNjZ7@IoJgKKt6w?Y$@EAyFFZJ8IN;^=V-#6%r^LFn6Zi{pE ze7G6@-pbnI0NYfTzsBg^`J(Fq(sI|{y_X&4olNA`C)X{^Q+{Cl-SgJ?Bo!MAY#AfN zt=Q12Ygpryn=Q+@iWP??Lz?C`R@>A*Yv^N6x?{uAxR_RVW*kn5OIwE=eo#2W=JdV+ zW7!{2KVYsc+*z4<>cV{*OOZJ0;;~79fKJ5{`ZMj_gTopyrPN9kME8*|7H*guC-dIr zzDOWfx}SM!!HN^>Rk$U18=mFJhOFK9{r8YTW+cLKG*oXmXIjq2_atLy!a2X#4+)Iu%foiwcI8G( z@9~j8-04){$*g-zZDBUm1On4u9pW^l3?EvSkzjyT-iTC(GHN-P-}ZS#d%3=^SRR#N zClMdVn2+`-wpgBu2|dUMrLi*GzA;O7Kn(4BFt_$E(wv#W#w+VnDD+Pn%Y$#1St-cV z549m0eScwMN^xS+t_B~BFaN^1lh-ajCuJmISMCP6h;zD{!gdyS!=6j3JBn#`MZiKq z)6|sF6i)dw6OglNe2+Y-oG+m!V_UMzCu3`Xu8s5mRnRaa zY>m^JSUerM>qR=T1{dIgZ1mv}5XK1krL>#mG`%EQrPn@zq4kdAW5#(FJ-j~()Kmaz zxxFA7NahBBS%9l47w8h+G^kQkB04s$iA^JJzNk*GP)M|MZJF?bPApGNQZxYGQX|WR zfsPVKC_d!x)uh#>GX%hnEw)qiSQ${pp_g&!dIR|!S}2&}ssXWuQZ5b2lxc+iDUW#y z4)d51nzzP2XmDkWbcKSU#i&igf;M3Cvd7Bc^;bB_F0Kkpk?viRt&6JFOQ-O6K#1d) z{-ZhwU2ylyqmzLjl^CE<-Zg+>H9l5zlqM6j(@WMwziHrxs;qieqm7cjv}YtE{~JG& zk{NzW0!otRbc)Mn(NpLq`O@yoI{CUVc6f%gt7b-o)qw!Sn=+8kvtO@oQf^g-AMq!s zv=V(lKei*Xw>Wt_l-^im57g!)xyRcueU|qvt#25WF7by8gv^+`JC(`Hr}K`$ZxKYq z7Zi!`X34qGsuen|8y`4=y$;d3FM_lfK8*%{>kiINyffG0;SKX?c+V!Th4^k z6Qs$+q6#9G>4TDN8aVsZYZdgka|924Oo~>Yk+)wp zn1halHV1+M$M+{+4Vtb_Ue6F(<5CoXLHDkLZ^RSjs+T<4WvdNP>%z{;VN8Iu%&t4!iGk& zQ7a{;3Adw>W06`qF-tMAx@rQpkDZp5DiYfOk zpz#aoSIDrH(+6c!Mkp;w7fxH5Tnv_)s?A(n`AVG?yI5sYpxs^_Vl)47OsKH{zy#hV zRPl}MmlzSeCM7RxfX^S|ENUOjM*Y#+-dP$|U)p_@b4~zXP+HJ%tCM+XD)U+$!=VGf z8|qLiRaO)S@rtHgQWOI>#j3Je7y*UN2+EWO1Di~QaVW0Fs-IRX6#`@+RarzK;n7k< zq3_g^aA5_LCyCDAK6?d2L*3U3N;=*RMcV*ySgxtCcWSA@>FW|y8Wvj$m9@$$rE-$L zsP-p~G6~{SK~OrfPe@AdM6cnB{@e~yTE}EDok(hlx@8<(!u4xrxmRTmV7Ogc~42AwiOWsbLUdF~Jl8(nqrb4)maW((o150UAm42w$xu)5DY1RQ1?X zLxd0xRZI=b93rI|fm{9qR~0f+qw>mO;{;6$k5kd99l{%9qnE=b56l`NQ`~Rnom;}3 zq9;@#IsWkyl4H;5<%?Q)1-&RS)4r4qeU4a(U5af4eW zJfabj_$lKutM6i9la1YNXc+B<^_7VEkBF6;dC)4q(<+?xDKe4zzIre|dLivx2{nMi zpT0d#FPbfS9sJoRXKOR*bQ4J_Bfn~&R@X-ct6K`k1$+f;?40mGGX18!KnDGVmW_)^;CJyryK%MIOb<{p zmn)bMQArbP6`ZG!~>{B!1H)}AOf^jHI_B01DaqEsO z9?r@riP}0CbsFR}2eBOko9(R2VBa3C&a}n%pa14%7Rc#3oURFm3RY)h|UO=r& z_0z2O58{FopM+WwylTLv%K9To4pGJOt|n@a%Ltn*kCZoGGkcJE31vR(V8;%8GrgNU z7Ghe6)8h$IpsTvtWnk}GtA@$ErPYU~FgJnwkj@?@43ue4YR@!Hm{kwx#&};$vC>PNf|k zo_aLJTy(gK7CPi11~+fDq=0OQEzoUQ9WY*`coHYGjA)9Z=Fg)3?^=9}@)b+DNWj`* zU_TVl#0$JkZB1k|n^+=+`D-|3Xh<;45i^4o8nu#uMQ1#*NucGWYaTi3&g>jZ0L=Jz@bjQLDKUA(IvU!6upAYP2hc z(^b@fj8kbXFN>$rmy$`;4;y}W;j&lHjQTc(8vgu48MWPAhuCHi88J&%Gut&KEY=PG zk9inTvQ5nw8xh`Kaux0!<&YJG6Fl~kOR&*A76MHI6a6q4Lj_4Cf~wh!35$RFtSx-r zWLe~v6e{T%`@75g;v6;4MYT5v{H9bndckTBVx!fiG!k&{B$)yO-z2f~I-}BMjJK#0 zE*GuSwAhGHmg!7OCAR$;_3PyduQtqeaeg^}bz4l3t+Kb#q&10A42++Ds(i(-V#|XU zwg~rZ%X=zvYf(gt0eb7%4GoDuDba;>T&yX}J^AdC(xpM$NbDIJ^V->3Oq@Cb7CeoA zfkUT+w0nbO7Xr3?BEy>I0*R}q@io)%(Tu;(iK5KM=qqe{JEaaFO_zs2RHCBWZc02~ zw7j)IJ!9SLR6mW;bF^-~Y3T3p;3L_8i>EB5WSA@uGKaV5Lx@fGA;Z0sty5aG8CDdk zMmBl5qlrLjRN7d}ZQ_|`_N2SA25&(;JrvENdr#U|Y>nTaZx}_>5rpTjp(Yd-STy$O ziU>6p#L8i;9AqDd`WOVK`|9RV0_jNy$bB*Bq9v71X`-pjz-h7;B4C<4_~x9#bF~@) zQg<;WLD#gmrxigbv_#j;m=#hIt%3AzlqRV&u9k_dx)!0TiXehSz+I|rRW5)8m|>)C zSrkW@b>;;%>b${bX@y4zEk>9A*s2(Hju)~-Cy1<8Ra{g#UTTBZ%^Yajj}rczce8)_ zEDlp*FJj-~Y&aoi7~*hASI0lsi=w=2@nmxTC3YyKbUa^%KD*g&XdLJ2ZkExcA{iBF zUtUX#xury;m}ImEqD`Gmi8-gl^jyHW6rON=TS3y0sOCcHRhJ4`bz{pZat6sNO2?pF zZ&&$yX$v+%Z#^x41^$>jTE?|lc>b6Db^8yC*E8}sEfXW~!U~~HDsY`(+xzt7k8`Zb zU?kNDE!WCyO{;*nq9YMkBb@qQdaEV{9fFx6<68?bCCX`KeOjh)++2Os1Xh~WwONvG z7pAHal%gX>tx?fIo$PY%^yX>`oEg7Bn7~^nS0kZd-$@#+m&N$z@nR%(muu;4hdRG7 zM_7MZ7=u<-PRM~0*(4s!Ij&OAS|Ng+|Ii1SXI`ndkD9zW)9S!pX?thqIxP-jQmNJQ z`&+#=n>%%z)|=Ic#2I)VWFX+LLQ@)IyY~Og=m6hZ(iG)+eA~Tg z$2>7MzYN*3Jr3PUb|7DAgyJcizP)!pmd>-KZA^{-Rlp&%ieVO8+R$ERGg@ktcZf{R6*0$DXpH#6OnYeVfR2cl;7(0N~dy7w9xh*bmI_It7>!tR*!&BzEH7(v6Au5$Sk|ZhgnUpb+HS3 z6ag(B=c-{QY$d;l!p$S9Xnv5hB;hd+@4aDFP2@7Xqd_BbkD3U^tL{$Q4$hn6;9`L+ zy3TcGjvLFR?JUmMs}3Mu1~)hBX93wuy8PS3BQ|o|XLBsL2(a8qVS27JOov{I)Q>;a zSdeeUK`KAp6IXuvdfg`yau7UYvsx8(>p72%ep4>8XQ z${)h@@MG|2K(o(7h3R*A?A}Kj=kG5^(@nx^XJ*t9*1XYD5oaIE?9g{m)TjvYykFq6 zk>I|7w56y)cFWn}KmQ2}&~5Qk+AtP{X$~*k)}=huaGLrR*Y$Khf4t(HPC{Wsr~(8Q zr*9aAf*Pr$r>>#Ig@|#NWY^(_W116@gT8{7{QNcg;sR?ZL zV$C*FN~^E#8Jb{4?|A&H)QuiVEoEzL6MWS8b9g<*=fmCp^jf&Aq+U_~eY=n}d#{N^ z|7%a6o76!R5(?;%VV(42d3Es9_PASMYg3lMFAIK4-pf7lso&cE-jBP@+d}|nYnzXE zqNG#k`tv8DI963Nf!6qXBQ=hh#d%aEGx5IH#Vms)rOl`QDYUtiP$?U#8RKm5iBdLS`^kv8e9@4D*6 z_&@%+ll4CwXcBtBnBl5m ztxY;tnjwB*VGb9}HXwa+k2)LFz<5knmg_A2pE+k^RWfe#3F*4TLq_=Zf0b0zUB{_E zUUR=bKRxb`k6sQ9-|lZY%T!`x+2xshAuNeSZ90@W}?Xq_S?4Vl~9fZoRDSSiLUWuQPrDAAEjZ+Zi+q(cp>ZpN&ni zd<$G_93t-SUu|o=c31A1(-s%|g`1DV4tJ)@YrOn^y!?nwWT-ECuLrh2n-ny6dV?Rji?+f5^rr8q48mkL2!CKO~gno98u>`7H8V*4u~q>r9|JKFMP* z(bKG#r4pKTHxmth$1lC)4Abl_Ruw*~eFyXCHMU)}r>oG zvuyXwzDC2XsmDt@!TpG1IKm%K{-bZvh>yY3I;yPhyj&k{`{zms+avD-ER$Ggcln{! zh5cD72>4g|@Z!q;0>eaio_R;>_o&kuCWZmX(E3>ro;O>B3B;{pESvmDOgnDkH^f6pNBMPDnJ;91(ZtY)%awKX5u4_qJcScW| zSq!GeMSuRoi4JyCaz_os+?#j zP?%&Ia<@V8-Ek@9=fk}`t=?5Rs2d$}vn2!K!`+N2K90o*`-K9i>v|MPG;95$%F?s3 zrUmh@axgQTFkAOrYcNz9_Pq!g%~{w2CQ=#bDkq&Kt^+NMw)mcEu&F7h5l;k5uCV1m zM!iFC1qH?Vf!rv*2vjeHChFy02@+TBSWHn=A>4UWtMF~pwUjXH_QcRO&$86eSDgB4 zR`Lv_M@@LEE(lba0UX)88Ct|iXs6e3@eRpBWZeA}l@XUL)tGVaP@QpM4wRPUo>ff* zu4y7V$lF)wEZ$}Lg^a%xJmE(B!Pp?g>!O&RWrak;v+be>Ehe#q%CWxi8dJsvH#quW zRpG@p2!t5&uV39xcp%U(NSVL~|C1<2XX%M6b+R{@aEQ-yKc} z9Yvzbn*fWbuK(k&hS%cXa4WKpR;vr+JZ=+=l;5oWqF_~3O(53ME3!ahd(p*f;zcuY2U#O!owp7Y3skFp-W@HuGnZFN1e350J{|(Lm z0ct@X4uNiKBE=6{&)c7bDwvrW%5i;J4e+)fTTBO6{aQG-33bjrKT>WH07 z1K3|xjeLL9imPI7PZ3onw-$R%y4AGCX+(dw^43KKK#xxPC1{fyVsi3~6CHCE9TMiK zSNcwG)X1vCKGs<&dV{f#!jh=XSOKf~#G zYK3F6odrbw_9CIP-M}q88AzT1U4FU{+F{5vdO;;`hp$#pbib(tdhyT0w7ev0*{~uT z0(D~^G6bjQV`Xt+`FWFG8;;bOrl)Jgb?V7!H_16s=4c7U=Dja&p)-5-Ahs3?>z~DI!0ES$zQ>krJyd^zzKEh5F1h9(`VtQBVBSaCv?9q_NTO$u3!W@zXb%LhUqBp{#|47yC37Wu_bXutr@BS+)cSO|qEz#L-_>WvCKA(smae+ag6A(PY*tj)E2( znC%Nj`E@`$m?EQKd*R|{?jz*vqPGgMk|BW3rINznFMci>QCuzRGU|`;#q*g`Jyg3T z^YG}ZP23ltT@*rLL7*{>qlX*UBT#DGvztPvP@S`ivN)pn{kW)Of0C4%cCvSg6#;UP z`Y)8T{0VQL`iMr(=y(F<@IEN(FG4haRzqkv7At85t?@H7VmU!q!ftGIv&>+R?%|1W z&ZfTK8U)657Iomraf1qvV5VF9iEN@~VhYv9HJPM_IwDX{!Svz46Z=+rnv{{aJJ1!N zFV*FY!7(eC3~SFBVbvG7^m6&2^~nH*@B?F{YO+P@0KQj8h2JpFcI6$oe1B&=@vU0p z2m}}Mv)esZPzBLi2?U`WLBm3n+}ZU|ee0^{;(MqT3wzt$UV&rYVHZV`$Q>g-s190H z;spZZ_L{9jWwf78QP6gj*=!h~+nd!Eya6cwW5Yayl@IZ@)V!T;Ef_^H5c zJ`80~6vUV`xbYg^(%P&$64EybHpP-A0Uth>bcUh(TvMtMEZzgzke} z1xv@n)Lcrz01inM6JyWJa@vK_@2fVej>QrhCfTj>3N~VTN97Q3tD7rCLS>Zr%o1Q^ zDa&cFTH%SjtfnLNxyUBwz|O)yeyM|zHEjfFYW|W5FseL_@YDn>f9H21<6Qtk>m<>M zVZHA3)Sbe3@H>8qT+t?e2!8$?+|RT7+ZzCHGIQl?R`n@{$fLz|0Fibzr{EY&MG;*i zs=-t;QdfQa{i1U*Lh?X4t9v&6U981dP>bv05{NSmuZT_ zp}Tb^;ZJ*Q*)JYZm9AER=oXRW)l39ea<<+*B2k-3L4894Fsi3^PPu?L9<$==78Ng5 zrT%u?MwKG!;&@eNZ3}Y&6>733hj9V(;PLk-HUXkJuC1W780sa@3E^XC`gL-qSxcfp zg>LQ9G>GKC!zF#wI`yPn`bEiDn?piG;5+o1OI)cqeG!=LN`6ecduklFb~wp{MfVBS zW1y8{blTtEPyX8%NPiR>x`CpGdI^n~QFbp`EP=DI`OuX1`4nj} zU^i}x9G&KY7-4ZxHx?H@reh=eecdEFT{+w`kr>Bt?N69^8aquve92_Eg}ec0-XezB zo@gaqq(zWrgSda9f2|fK%@;yEkA$f1 zQgMZQ>D@2|U%^bNu_mf-yZ4q4|I$oJkhH=04<6&y1;5x9VB8`%($9C&^2&lj z#PE&sKgdGmM{(Om*bQMesZ6E(pBq0KURUk|xG1iB(7ew|rcf?K4BT6l0FKV=QaDcQ z4#LD)(wX(&cQ&Nts6RKd>Q!t6gkWvjoQp3LIgAtkOeW|ot!0gDI&-T{FJxe4V9*w{ zEZrO*1w0Ht!e4NCx(93ZGi=N!P}ZoPM@#EevsGB4gb6v1Qm>#-j|q$M!T+?Y(V#@| z&jWkB1QaJnYNOh7mm!TURtUFS6HAaDcuq!-6J0}oYZlVjAD?z6S)rB3#^7A2RU}tU z!-)lBWmrgm_MT#j6AzWa%xg%U9H>Qq011H0(3{z4X#73$(TGH3$G8xO2}iP9X6st6 z;y7m>$QdFG6=eT6w(RmB2N>!eDIB6Yd!}rV!1yvBw51{ZwBT^9$K8GOeXls+XOg;D zdz=$4z@+Y4y=lz7_D@rACt-URa*||?StLoZjp-Nl!ABLUn@y*oI;=IsS)?iZdm+I( z6%?$ISqgT_BB+_V3h|`Z#Ik27OHSrfcr1FD4SY70fK@oi>?LFx5k19=wl*k40!5OQ zQM_g~JDjp4`goEY45P)p&bc=24v<~3sSL4yW}Edy7Q@X!e;|%Hv($`WqtD+Z#e9K2 z8z60vp`Wu$|BcHw@A6!p**#z%7vTe!`pPi03Ixqrh)MsqKeRcCd_J4SHq3|Iilq8T0$zsanVm+kP+ zUxZMZiRLu8*ySPY+K7IP`-W59&w-52BXMJ5%BEani9(zrwvERc2uY_3vGB41Xc@=A z(57x)kMB2(4;O-hWwCuFlmWp@Z*JI`Xx!Cl;N;6>19CsQ?}n_ z_I6EClhUUZi?S{=R-De?79=BY8(YYo7*Z_gq>ZI?0F`VycQwR(kf5TfB}E&|`na4^ z|H;QPDrZ;YQFzcC@o`1Tu`{PO(etXR1&XDF#`=ad^{5ZMj!G`{ARf81 zCZ(H?q*#Faz1nSnTzp%EL8wj&pm8Vey#~;XznI_N^T)H zV#u)|lir8^Ta6P9VV3bw6f%*aC4%KX?z8Dp@Zz;D$W?ZTalaSNP4^M*kr3}qgCm~h zAsj~_FKTY@%+>kBasV1494ADYZ?!7ovI*ht&l{!gkpXA~R-Tur;)Md5Laju?&NFOc z5~))C;PVCrz8!Df%=uj+pAF(da@oD=suwkZ8kjnP~y7abz;ZPcU1(a?SFyv`)#4>FG zm2gZ-i}POm85S}f7DjmiSE7~KzCMseKU^u|N}(5e=ndg@E9j5g`+dNppz1Rr3M!*y zE=wJh`lCTjNR|>v!_S~fnMZBpGqoDU2A> z6iCtxh+{A@X!B^(7S0TVz_ew<47qcHlg59MG2I48r9Ys_KHlo0>f8C2A@7nas3`Lc zYWRhx`2h~}7-y|ae(1rHM{^gL6bA4vf`u}*l#qIj(A~Nc4{PFcPm5gq)f5s)E4#1F zg(7FptSZiNQQjSdC&y8;N@HnNsM254k%LUE#prYJY+EKGW{9fgZ5XFEl8=Q+4vDW# zsW=q`J)M1(U_3=dWr(sEEso6kHo-tD_Z#+f=n9WAm^=ML zsb}Ozd5s8M@joBMh9(5t*fgd6Bm954;=O+bW%RBvsOZ;*)e8pX(@4=s&Q-8@!F}fu%ip4cuYx+9B9&l1TU4c zm3RyO02!GU@rX`4qB{BDPM`v^6v#OBXZWz(Q_ex7P)`wws!?kMmT$#)06i84%I!+( zcbj|uhEenRY43KxLQV= zzNuqSr@1@ztn`0p?Uqg5zkU8fooig+Zd@JgcTlyR6;nLtEnRU-!I7INkQ4}6hxz}4 z@6WY-Cw@O-ElQ`K@FHQjbWlp><8E6-@AcVu9)ajn2@6ep^kTbqv2E_rENF{$;J(8% z>+g3pz4zHpHu915#m-tuNf&cj8?B`)$h&e0Z9);9wkA!2ZDmhg@y1UkE_-8@S(a=K zv3LGl#_{Qk0hQqu5Qfunr*+m-o8F=tuUcd$q{-^4#XSL{=r#z3{L#r^SNq3HD5xZB zY5{Vhz{j#5I=LnD+rC-m16*_YgA~)TgU)JT{m9F`i(T9^R209Lfbn+o-iZDTV2RfL zoKe6$c?Sd)BipvOPtkZLvjnI5W-TL_FCzPRsRW!PEQf4CfM$ynXpyw1kn`|l!$97! zCdUQgzOFzH2$gFfZ7`cFx2{me+x>LQ3H^u7v6HKgA+Upx9^f45>6+jFXz(4M{dUmu zJP9Bwjt=Ml%kI9eU}`*BT6uVar?i<7Cf)5Y1&A{WM3ILv2*j}-7pE-=!t3wrvRGo% zaLapx-aSU6og|a=(T?~^Ji0E&#jr|yPp}kU^%QTw2~feyOn2209lR1D_Ojfro#6;h zb{wg+CXQl)tt)iVQ~=SGq~?j0S$KrPLxOEfC^aD#`yCE+>?pag5?!4^I>26ats_zx zR6T=itm-?Dn16vL{UQ6k8w&3AL!Gkt3VTxc0@v_RyLa#nXqn8I=}{IARy%*B)tZ=; z8CEf0nI5^KrA9lR`Kbkr+@V<5d?4T|tpY~uQ4h6uZXao10pr*hSVwaxtW~iOKIuZV zO&A$d9(nL*i7@8GQn|v|8B0b!Ok$f?*$>FHvmTO%Os`SetTQ2gJ=EJ|%`g~U^rXBh zetN}q5*Gk%7JkG+7di3oX(Bip*N*=9L*!>G{RWgp+6wdb5f0Cqr0HQDTr50ft6ACS z;u3N<{$=g{#psp|SqvVAygSf50vFZ#TwIrInsU?Whs*F@=HS|5y_ToKzu-bk(d$72 z8fz746U`utoqk=z>hEhN6w_VfaUJLaToXERYXNcbyr1XbX8a9mznjYZ7F3rA1muFj=NcFO#`L zzfc*rkQF&vxdT9PC)Pff;!;rOx3RHaVy8Vzr}lU9L;hgUXOCnJ3ZI;stz>vXyUu{p z6f_bb1=CC|j`KD=j_A|C$PiY}vyfIOAe#cAq|p>JLCujh1@a=oR|WO3QDlZz_71SU z@r-?c6)@t05tGMtU=(?UV_rUsxTt!fA+Ul#D$6I*6EB|${}5eG30Yy{eJ~Zsd)(HL zda|KxxJyKpTlvCxl>stLQD+-&_EjN^%c}^^r#2OqjWn$3lly*qclpvORy|wVV5I$z(;b->mc+zJ3WW6J63~U5g^}$qm z<B2IZ~QSs#C zUlE*S54ZmSY8*SA$_Fb=RZInGl!zr7Q`3YP;TN|+>Z@HQXl3b0p3GBR&jMEy|I_40 z2$HcWj1YA>ly^?|1_>AzFVo+~wHqiY$;5{hG<2B@(+whL;cHa>b0m9I(#v(_~ zfK6@|gR$dDk-XcANzf?=Wd6x5q2cKC zNqG~jCP*9Z;^%v+34!$w<$o*>#%iJ1O_f)Bb#h`J;ER*dysPP=wqer$eTfQ!!E^^l z{jQFJao>kcCql1EU6R*`6`9&%mS5mSVqleL&^;tNXsF1;WT-{0wfoE--Y939XXs-=*2WJW} zV-%i@XlO+up26`#A8noXb$q?{G29&nhc!ury9HYc_<&GJ^IYI73=@f2W{(dTdKi?_ zea1xv9)UjP2%Jh)8zB>#CQ48Ob@>YRrs#o`*YHQBfZAsSPRTP&oLHMGy9~gX3EzxH zsfw%D_V>^CAtF|q0_qr&BHH&6G#iVwL1R*Wi8eUX!WLVPg&nwGCL z*7+k3%Lh&RZ}cCLPq;hVG`Jn9{l=CXdhMvp!c^NawDw!kUnO44hK-F*-Uh*g5n zR)pi{YI3Gqp-?jx5h7!(%;#GzRDRndAddWcB;jbIn7Ll6CWfz!(XP1sAu~LcQ79y4 zkYG49LEh%*EMnT0+XgFiSQ&$#*X1l6dThaqNlXffZ8seTm%RC}IWB*pziKySy$*@{ z2F!z4*g1wBvr&2(0kbj4GPN8DW3hXlLTmM3|LtG=(Br?SetM7UrAyyOEh4cI{a)^X zYt%zgpz1DAcmT}R5O^5aZ(ysz&N?jCi0J&)BfgEj( z+EKKQ=vo5xXM95#lRL|+2}I(Nssx&-hl{Ihf;oidLwFThCCqHmeG1BdaOWDG;?A63 zbE;8twwD{JRL4)}l}afa%&efw;Ws&Eky)t8#F-a~p$NtlQa$$Y8HZ=18x!JP0(=RC z{1Q|^L#sxK1!G2$1tmre!cTJ(R>%e zwd{xDs>9iYQ_eGpYUM4SIAu)2TVza-9;swaG7m0!5YvypbhBEd~8J3|OD0OlARpM-{D#bSyrY(--2+mQ0^T(4ekulbw7G{J~JRTJ3%3GTfi5T4=|L+t9rB ztF0eV&ar)D+3DUi5q<#w&PpBA>A$9L%9A5^CbcIHA?uTNA`HjMK!XQtaY%-(WfPKOXN4a(s_ z)j^non%h|na{7FwMXrirc(Q!5eT?|WNk!dgJ1k-nQ8;22@m_kg@4OcQ;JGk1q1Vt( zcaf%`R`ymcOEm9bLk{80^KH7S35T*1ZD`qMG=Bf26ApzcjI6=nR>;mi$xnfOMW~LM z>RMxR{`hu7tDzQj=OA7lhb6i1)KY%krh9_mRXfJLB4z)E)u%)H|mbCE;`ZB^VKb|v)?D$IGL!DIrrIgEL4;%o-g-$%mj)b~L z$_EV399HpE|0GR23Nnx%zTbp(0Yx%6Cg_R*E=+LlTZ{(v6qQQ*IrLi4y*1x z!3?BHFVb0U&fL}?UX8!5@v(Zu>-Fla56G9yP_~x^C5I+2pD<$=%1A89|Lh9%GKJ z9J`EqTca}=F8$yTB9Vx;Z^VLfgapXOIqm(b6bQtzaLjVAYwAnPLI47ZDyvMy#ey8D1l}9OHd^hQV|{w9fF@_ zClw`3M713b2V3pddO(V=i;cc00fZ7#Q5LZv17C!Vvf^Gz=4$ zNl?YAL@8iirK@VuN?29s$7Dam+D%x2ig*?V+--zm(!;y?JxvoC`2HDPABWVO#kC-IQPQP<0z>x^7P7CszzhlBvVzvPJA@CbVgSKrth= zEFb%;Zg-R-SJ638=!Q6>q=!jYQYg>{Tz-qHyj9imoE*36eXuuuRZmmmF8F_Hy8tAki5ZAOoPq0A~$!b8{}%f^^Ld`h5pG$a#LQkKMDyRixFEbVQ?gNZ+Cc;Zpt$Fj=mU#G4Z zJU-_}GRZs9_4DB}njZyW3p{oLI9&}1(Me8C47}4d60&YK2D+WjR&L2A`-MK*VBYDB zx2AHm_yWdd!xH$W)ixsX-o-bJ7-g8C3&2}ie9kUM zgTV?*9fW9dhlZioXXx#Sdmvg<7Et;t2&cfwpQGBR_74i^j0JBbF^HVkuO7BL?$LcK zk|%97*qQMQ3Kg;HC=mNUoBa~EmV#BZj?9BTv8pGA*F>EoM*o;H_*V@V=HVG_4o!X& zMBYTy?rX7~;(+B?jK9*}{ng_BF`@dXIrkDMDtHNzd1L6gVK~TvT^kfH!O-jMUg39k z2c=f{kiQQC@l`^Ivyr@mrP2rBc-|eErf_$!R7Ab|!zf>f@p)W-ZN`oA5-v9x`e-cn zrj0AW3+TKsc6Uymr|p7}&|mI>$fcYL@^;{vH#^+fnK=AG?PMF*+6zu-s&} zIbsJ}vI*f+@CjWvh2uym4K zx@yyHbJ~K&Z1^8Ez>u$`dyl9>I`i+fzVR@GICoG|h}E!nld1f+tymZC(FqYXN0s{r zEAJ{4ETQc$Y5xk&|FR^KTovh>7Q{_vRiYt_U8AwhzE?Aej_45?dV@@;&G=*62({^_ zY(u*4(I<{7crk?j*p1xuR(%7ftpl^|FHRSoTb&x$Y|~g|-80gb*y^Q9Z84N_sAF=l~CBZ28`0`rQsf1IT*L@!-|K~U`)z_0Ubw#kt_AU441?;LBQTn zfIwqfE;6KC$@9&Z^X(i|FdY52=O|rGRP)_ zlzraMjECMF1k+N69rnzvp{?udh1wmC89k2bse^-wxzDFq%HZ-#UTM$^JKEtrWN#{I zX-vPqbl5kEIlY=&Ocz@Jw#;8ag;MqtG3Y~j^!=s`7d#*%RHQ{{KM`(3MQESJ=xhuP zsLFk?Ya_DBL|H4auXD1={aN3z4egoKW9_>PZ2v9|Q?7{)orCIr&pzuP>M0bJ4MLHd zhLGRRV{entQagn(U-UD(C&A5Jp(md$-Yy#l&=~<3Dn9FBK*1l?krW2~z)V;^7O}qW z&sGR`n&mUM20kBOPbZ!%R=%TZLLKgI2s2|x%&& zE^0W3Z9i-~d^UMMUfg+J>pi&MVp*azdcc=<`F-Cx_D4>38e%(kVq*FDJ3rhz-`@}J z&J7+`=9aEsZChU7?ERdd?(avQ3Av%X?uz2UtY6Tjp%7CTeL5%LezUDt;cD- z4$4sCsb%lr_r9|IonpHwarO|7?whb_II zVCrg$KZM+$R_`BP7y!P{mj6BY8|J^pPay^pia~7B_#p=Sul~PmRyHQa76uF!HU?%U zO!NwJ;^99P9tP*XG4PTSB1%8k`kzV%^}`qjWP5{O@pA!oQW6&es+q<+`)Pog3Caro zbc%)jFaZB)6B$V;$pQg+QUC$@2Ll1U{oL|D1p;zm1OhtO|KSNt0|LUd&uUlX`FQ~8 zEGa7rxe0=V%*5*PAtC*9i^5q{!&%wR)YIKO7AR;?5NMEgn0)Q~i`_sZKj_JHHf{sK>+37#ZL@Tz2Lx@})ThszTu}ak^%)<> zEH`J_%|gq)nV(XizPouoZ{wS@6xr_2);P7m~s*W4cUj z_Zu}{L3g)r)dDv)1q2;N;@s-m#s)L1u^RfxOg4wvkQt4dcXL&3ZFOa(Bv(hVm76?^ zO<7U>*rHWEmLRl0K02ZI-FlPN$lDe|(!rfw&*u|ABu3!vbRrTa=JT95p^n>@OGBr* ztu4XDrf2WqZkrQEnHA$-;j?_=1Ik?b_N%9j$jArSNVG&cu zPBUH4+g7y#-gasFE?ScizbaOw{dYw)s&rZ?*m$W(?iXGB-cW0AuB=$n+v!qtGXkJ- zIYSMAwcRUr7TGxUt?g>9Y;Bz->8LU3wMVghzaDaX9_OXydH*dI#`3-04j}S#dh@&< zCaOdn)Q=D(UWo3+ixYSpr<>*YeR(j!VniP85TL@{&gKgncG`8`g|g6=l~+}L5;Zao+eOL?V3rR^ z>kIIG3D(ppTS9Le7+g}B%WPRi{`XSP@z78lD{*nU&YZ%D0gCs-|fxDt` z;%E_oPAKTqZuFX|832ato1KjV#{&Z7R0!$)&YuJ}A|j{w_-cF#`ekfCNE-^5@Ww zPELwSOP!tnYDKTc2i?8AzB1L()U*oCX5MKmDQyTw(_(7J=wa!2cIgfWe;)92>IB?9 zKVrYjnj#*f9&EKb6k^?I*>xRt!qG!eRQZhiLRE2_gJsjANKOBFqci3G1x#3m3}FO` zw%0g4C`PZ>ench8v5apshLU1h4YXaU%(x6AoS}( zi}l*RElk-n3hMjQ)qB2CU?0Y5#xjajfL%<9XH!v+Ir;hIaol}0cmKxAvWg*(av(8xk$rl#hprY0sQXR2!}XJ9~|B&J16qpZG?#LBMb>dgA@ z$@TG{i@vQtXc6?v)6-i6b97Bn8o@5Sl*!%;C583#TDR>Mjq23C!ubC|4<@IUYED#ei1F2`i)yY^=wt;$Zag55QUH9N4baixK;e< z2|oSKd5o%i5OgXFsT=2hBM#nQ6*WuPdndGr%S-FoxRm&G2<9p?OEptXS2c)Ip?Gjm z0UKKC$pOFOxnICi_0&BDLh8y|CG_-V74)UDnwpNDo|gK%d#aV{B_$MB{B#JEjdPidLGnq|b_@dsgJ8rVww(tJ^``7C@)G5p~ zM%{7|7BeW{JZQ(6=D^j3mv7NUio7&_WgQ0E_X6_@n&4R341Pk};@V(pw|?ht zqaLexEut1$urN-LjeUE+e^5*J`*nXLztXidOJ)(DyK;{QrxJm;(qY$6s8Ow4MbG!O zc!16Vs&K6!2e?nii@&72NF+Hk6JFG*fyJqT96?bdO*~yRm+lTO+{xIu#MD@#bWj3F z$~BaPGBJf!f%-v#GBPq!NeLxU8D)h<9ym)DD(m)Ga#*VRzqxjzVf;*m5qQ2l8T5<3Os zZJ+U-4?n!#0mn?m%i)mY$pKCF9+T6OqTXpB8k^ZB;HLI$* zAV2}+@~cNggVI*}KP%O7A?HBt)u4YV zBEI2~MM2OsoJy_z{Q3}R`v*oW^UCBhWI^GN#S2j8p_JQJ;syJbLm#hRbF2s0=-3b2`r78ov9lHA)*Gyd5RL5 z1CKA)SPb?kQBn4h@bp2}91bOJgAn<>k0&kkix!eCo5;!A=OZG{+uuT$mzQhkRgk*Y zf=LJ2YHtZp4H;K-y{fxf26Db7gz@=6Kxec(mMs!UDrRx}>tw34vngM|y8=Lrji?r) z9$rI62r{vea93l5y8 zH`vhWFA;G5HZ`qzS)-mK@mE?yRLT;iVodMr4bvHc zF+MTcphDsBkSbE8nEa?WQ1I#Tu|O-&sa?6SvtAUO`}1F|9~~fuMI^_nP0P~vxnn0B zA`FqR*$(LF#c4YfD-BEqF?xZEpZ@qxr2v5fI5GECH7RXmZ!PJ%yXgZB?bF+=VPfQ{ z2?32_5*kE_G3SAa_zv3B-okB`nTiU!`gF}KH@WXq=Oy^|v^6R&J1qPyG@@TfR8i5_ zqI{amEsTiA7Q#fayWtliVNx&TE)cdoT9T}LXtIa#(V?-3nCQ#ZMrNEnMmCyaLP7#q zB_NhRG6C3me;?)GATc3PLA^0RRMdmqV6tYK9!VE;Ln1o<0|HWT*@-hV zAR=u=XA4~x^CBS^qu21b5S`ggN2h2MBIRGVoiGieA0H_Ij12@LjXn)bK~m7~cDbIO zhL#(?7N3%pk&={=5tR_16CX&8LqLF!j*jYdY;9-=BQS3vJwIk68ivw zDg>RHiXeCh+bbfFq%;cd?th|+K&Pkcz26oaQxFl6qMfur#>t8)s^^S*9X+Xf0|SHD6T%EgrlQ0PTTQd1Z4XshXz z3DTamP<3fahX1E(Qmh#O4UO>&8wC6HcS4v{JUTXd_tXd_6%_$I=p8UEStP4$Ao#l2 z>0KQFO5cHko}QS6R7e16J39FL&@8-eOcf? zH@?VBwrWI&CxflMjBP+NRoZQiRcT23sv@a)BBhjkeabI+00n)eKB*M{{YVPLJB8qRw_+BW~vOcg4mgKvV z@R@VtuE1|h!XD!jDS!dBJzwi@YdLtrPtB)!bE`otTE+d?s`}s}z>2c0B5y(fC=4CV ziuww)1T|tEav358wAD)F_&u%W8wpuyu^9iLq$Cl8DpRv!(Of=!Z!$EQ!NDw9A=g79 zZYlD$Il%}B3@Y#bq5a2D`BoQO4ZG3p$sZ^smBKKc#+jZMk|?Z#1~QW-09k|`NO9_1 zj~;?TF|73ulvWi4qi`G{41&41D;3|UKbW!8?_Z_f*uZnI?9fP*K1hHq^S`|U0k2>5 z^kAsx`~B_h<2_$DQ-G+_@4LxyRXy4-X9tULF@Zi$DJ4)DBtpSTs93m-1|u&|9I~0B zsm<31BpQ7Z@pxo3Z`M-@a}D>$wMOVOi}Voi@%xDJV~TnE(M`b-vaBawBO$SY64}hO zm{|U=wABc!H3L~uKl3+()3?FR-SIcM)VjQewrb29@QU7n8~p1t(o0IwIPP|M{XnVR zf=V1-@1yDdc8N57V8-)IyY4^3gM{BN;)ty+17P`dv_g&X_7L|%)${@Y`*Y`tQ9$CA zO|;vN*Nus~?%Mi1RQ(s?qVrqGCjJRprHO+?3rx7pmzF88qc&9=F0fOf)MquCl8l^A7_^XoQ@zjZKJe=Dpo zDGiWT*if)LOJ~yzVM1!Cz}T~C#NyT`;#KPVVGWIX8$MaUHM4LfsND7={pjKOooZiS zA2Th_2&|1aNK+5tPJCNWff9`a6b%t84lXSYZbfbP@%oe&dvZ!eljRXYu8mfU?VP1b zps;=(2q_T?GIsOS3S=0^TZz=4+vN?r0moa*k*x5$4JRag7It=mE2Uy3b=76o7FOxd zvSdk(O+X859Dd-35bVH!(M;LaS^@L3ZWkpw4YJc;wPuzui(gFPPunA=5HL-`67bM6 z#?Wb#LazSFyI7KW?igm@#(c=w77KANjE{)e81A22J{9n&w@~xDlN6*(^7|Tjz_K6< zL5YEbbR+}g6HT+N%_aL!+&6GgkK%b6bZBQ_VvKNO*SG%!`vwK7t7x--TT#>?yo_9T zK_a|Cii%{(NlGRbg)XrO?t)&;gC-(Ptl)kJ^Gy7Wjg2*11;~ez0uet_!Q?Ozuj}Iz zVG2ORBY5$kC$k=;?~084U5<4pDr(DdJ4}|BubaiRcIKYT2@s;h43{U$2EPJ-|G10w zqa6rbIz_=4NMp=Q7ZFNrWv<5Shk%;>InfcX2ppD2;5)mh@lg5$axW?Qv)O$#U0ljh z9z>KxVIB1K-Cka<`hhIUYSV8I6C+b;L$wA6hppF|A5QC0@9x4qB0zZ3f_c_AxT}-~ zpknR!fSa|lbq$5!UjD7U%4OBp` zN0LdwApse1HzkpW8YEMQZs}CNKi&A+9m83#guY2xX*Q!^pkU*7JGBr>{W^QDRI3e) z&oi>!?ELJ_7hnyqn#8Lv0ZV1)gWfMd(Mkv`$cZAkc?F{*^!spN(gcPwv+2$D6M~3# zXC%^OyDKaN8^5C|!dN`C#M$5yH_V@&$QD;11tjMw{p^y~@5mt&Lmbq(NKA}lExdRt zPLw9Y#%`SMwXe-Vkci`Ty~@`gO=>a{FeTwtq1QFnZ|$C}K-FR(!2Z2(#7;Fu!HIz? zL9FFvvtnX71v{CxZAbNY2e`PEZLlqXsF>9zGmhx7DOv^^(HSTxnC;^Ow-0v>OGnLm zsp!P<3UyC#s2dZ=LKt{>^aC`mVCib*94K|By8O`P9J+wD=N_*gH#Sh%mcc~&Z60yL zr~iypUBs|j!>afkbucnbt>QR?22%hQ^{nT5n~3yU{7si%|JTHsL4Ppxy)_=Eeea%? z_#<@C-0IdA{8YqJLSn=cVzB}4vU0DGQ0OleH7U8Z3%ierd-RF(3z~Al;@<1qjTT5^ zr3z)E9And>>Ww-o#uxL=HIYR?MFoywei!fIGYkS#JM}Ql>XCt+M#rPn+~u;C9r~1Z z3G;&fa@8M4ep)mpSmq^6Z`??_acauJBQU_+onU0bIeXx4t*_@i&JBX#-6Ig}94Qtx zZGC($zX1yn>~HkMz0({w1-(_NvriEF7)R*eG|l3G0fX;NC<-EUW`YqzBcnv6az2Oq z!7~;`&O&{}UJyG9Nf)$nDK?Yh^Y!(6I}Tr`4g8jif7!(-&JmJLT-dIT&)Z$pCIl75 za+RA6TW&YLet4-^xgwnznOdIh9pv!=M`!RPoy$zvd#dU>CW!cu%-zr1UdAeQMgo5g zXyVOhS62ZkBEV<8Z=n*uJUQ_a9V=-rxJCnL8o6H^EAmloj9Q(-^xqT&lFskel!9f7 zX4i@ZS2ZJmupq;K|EPAa!H46m`E~XSe+EZjVTD8TX{KiD{M1y%B8KfLg@tk1t&u?c z*v_JO!gy%@j5zC~)6vo0M=2r^Qmn5s2CxBw(viq@W^rnr{#b|#2{rf$>IsWUfjbq{WM2hFVJYIX4UbjU{YzkfiLLF4CqQC5>a1mX(!l*+>cakQ9j`7 zPe_nv+vlw&FE{r=Dr@N^Sw`R)fu!9Y5>6rQBz!zQyY<5kD@qf*jm+jZ0&ZVwa&n#O z$;`A=Y;{$xnaX(WNNe7Az z^BFr8Wo6O@RaSSSHL5;3k>#jQs-sSCPZ0KAbO!JS3gXgnYz!!50!ZH09*xIQ5OX*M zg0%A)Nf1IGu6O=m&w#KX)UyH7hvg9@^4ANpo?Bx{8K>Z|utJ?}_k-vkwqz^gv-#qF z8qp-6dS;_xxUh2fqh$56R7h#*uS2R6?12rh`@=Eho#t8AG5bCnAm~5FgQSf34-YWP z%JYSVMzO(Jw_8ni1H)4r-rhlhpvp=pj_BzcIj2R3b1zq04^~$wl?S$zZs|AbZI zIVGn}^Vxd$dg;o>)Rt=RrHkQTRr10#PBSOus<%>8Y8#K1+8Xr8#u`lZ)|H)t1ZR{V z0-1uU37oZxqIs7ui$weWvmFm*(Q5t$5T^e)WjD9nc4S#XgaUL!_9ac3`8HiHmILzB zS zvU4{J8BEu~DZBQ(WrS_$H+Zg+jjqFlr}t`BPv7d&blvgD(HPmu-DUcaAX_JWk0;eA zwXvx_HC*ESVOl;Ej~5CP0YpcW=7msFGoG&Q`6EUBFhm*jf}4?dQ?17_|JVophaCvujT{nxzBA@naCd|Z_RJ8e~!N`x*kUxd8BF7Rk*G?`s>W7&+U!M_JFx$s9MfZQ426p^|#{Q4QQvhmaCZF z6DD+I!d!fFLakKw9G1P}tgguKLMen=q#Y-N8<$URHV}-2P=l?u5LQ89oGIgP^Jf;htAA+bFhK70j*57mh#pX0K@1HSjdpy!|3q~MKF(ci!n8g;yR67^OqDX zCAEOT4S4KeG5`TZKiGF}pW->DEP4^Fe!uAv=)NSNph=s!x;>vp+NQ(8KjKJq=pLBR-V8Q&Wa8wmzgBx0c;p9HNyB{8TZ zM4BTddn=Ol`xGlAqg~bcVt|L(NK1>H3Rr7pxcfx})j0?@b>9@tNi9*6WcCmMNst#6 z`t|jG(-<%44lbch0sNh!WosbEII|ifM&8VQXZ6v&(QGpiU+4SjNsT;ZSV;K$??@~m z<_7XhJVyO%U@mJCJh?;UCyO={>&qN4-jYa=2g5WLE5D%8Bx;SbTyIA9d!54;fN<03*7{JJqo`+s+L`5edxNIBvlgqP3<{&8uA&cE`; z1n>r*vo)GLlaql=D4ygMh;g-y1a-vUwzyw$w1cdpjDcy(8CP)mLz@#4+MQ{>% zTmTUeDrcm`iTqfl7$ypA4Cqs8r7e+V1h?Z@Gg!h^+22^#Tgn>7xil9^1nw+s17M5t z0HC9zqf8FFk|>(9pIx)qA2fm{GJ%F(6nUClAq-U#&0pmw-3$+5T)0_0mG&9-Gd=VE zbI&)gUm)X~F&by>i}GOiZ+qi#5V$Cs0ueH8MWl~VTGV!M*O#Uj)Hq;#7|w>TNa%3N z@H5h3A6B)8bh~@*+>rQ8Dx1L<&c}b`l#;#AycwCw){#-1rIWW+L_G>SyQnfu;Dapc zD8OwbP#S?~!5{%5C)8NbxbzwqaTt8W?0Qg0v#}bVoUYIZ;Vv^wK5x!7fjhkqYtoHw zH@bID`~c9o&}|XmFA;v8z_`Hk&iFdy)yUUCndGWDslyjpjSr1Zzm~QXijLJTL7+Tqh!MP%X_r4}e{>^L*4nOv z1Fef?C-Cs5n5f}9fSfl(n20Tmxk)uFtcW+eXLf;OKOr?Iiuy(MkLf)rGfXSptKm_K zowYKJ+yi>>EvXAPx-%|H037jt35cK|V0sl5c~fB!yInUYBXeTZQj1&8n#4{!g_EE|NEWycZ$2!t z3A_<3s^$I|;tM%3qKLxsk{f;OyiW740g_@jHf8bprtDpW&Vx!Xc;E&G#E}k%+UUz1 z6Ht=I$&rEf?=hbC3NlQuDfw!J8n-xPc&A+*t%+$vW9GST826}G6{S^{iNU2V4Gxi0 zW8)aV;YvEM4VQ*2y0Haj;<1S9)9cim5=qwvknM>KA4+kn`9lV$ z<^)_Dm!o6t7DahyR&JzXGMHl#v*p7yuwoE41?vK+{M13GrfH}VD?+urWp#zs%6D-R z3GVWTS%DQi2DPMKv(J_*|ce#VCANFoTcB z7ZlH%$lb3TYlu$4&_$vrm$%B>fH;Y_c&bmR?fpec>4tqwp~k$}{nCUfiq+t;hpN5+ z#4dJ$ z7AHw=<1;bb8(bTUx0pm=Z<;5lN%D_}M0>U*MrAXS#qfb?|oIp4;1b&#W8F!$MxrMjQZnjIUxG7Cj8@*0Uo<2 z>oCf4&A*SDQ{=nuE%bZ;(s=Z>R-^YAHzIicV!^Z@J-fvZo@l`cY;(oX%Xv-YeedU7-HA2~X9^G;56FWg^>wuohA7+r#B;q6+3{678&#BFnor z;?*>e>U^4`(VMsoOE_(}{ecerH5j{$BukZVYGT7OS=fEbyK(i=x9{QV@nvA_sJ3S_ zskU6Ly+CEUc`}>&I0Ia)jC-Z(eyGIoV|+~(zxfZBjwJ5>Z4s9mKAIECcRy4 zZfzKEb;D8DHizWrgsDrIFUk=-KEB$q;b%2H#LlI@EFkQc4L^Cq={h2}ZI~B!Kp@3q{6bX(R;VBAC$gz(%5H# z!4HFlb!+>OVo6^A)|UFBJAU}ejjw9n^^bxm9iiwq0(qe~Ytl&YYgf9(F@nksehZsf z%f-Zml3r}>k^JKibO9qUNMomEyO{Xbvqy7di5hH$A_~m-s`UoMpXQgHABm1o(gU;? z=ponxHMYLhs#u3D^G(2!^QkZRCEHt=LAm1f=(*p~!ofHnMCIRB2)5=YDD zE^Tgl{45}Ja`=cluM$D{(e%eFpcgW8Ap}$B`+(QA*=8;AF8)RA4t+KeIUO{$I5m3s zpq{D0DK-1#rauekQhSH;3(~QNm<*rAU)i~%hFLGSrg@_8aiBx^mc4k#>zks7w^h*- z)PMOA;syQluJjxCI|Grv;o5z*yaPezV`3I5?03n2PpdS_*Rd$#V}*=*qPTs_0fV2; z9vMmGC9C1pqneXn2N6%OeRo7{KW?ckgv1C%ZmO=79$nKRF0Z= zQp@FrofVXUNM`SIP$p!Sd_Zio)0-)jQJd^_!>v#!eCOAiD_iODz$6ib+cC3~xOiPP zv)}JONfG_jCy!d&*h*v}ZJZwlcjjnsi_McQ^SC9z*ykE%w!;woVzuSLB8K+*a`Tuj z`p7hJaA-Z|!CTnfyrrFo)KI*ai_e^b5j#&tp+#ujHK4Fc!JUY!O&Q5-BX>jzE>ZbSXqg&`Z`DpMkxcfPa>V~VQ6W1rbj(PgbP~0 z%%uQ!KYR6ODr!!B0{{%=-N@w};rCq#Zw@b52c@oVf;#v{Z>~Y@tjo!R?}1$li`C^G3VTqj2UzWIosQ z7%P-3eTk1ugFY*)mglxP#W%JbgP)!O%ErxI(Sf5ORDfPqkiq!!?F7trD zKV$TO)qqV0Np?u_jR={H!q^8l>5Yniwnz@fph@4Os7sa&$7z}O=&R29n5ujekW{R0 zkB3mVDdIs%^ghEPPz+MpI{z4ux?QUf$iah$qp?)N!2lypOiD4$ulWk zevmYfV6G&z`CDHr!L**Ffp>rm52JfRwuIo^gOogluBW(YHK=Hw|T0;?2M)nBcWtUS-M}x)?h29sM&0L8?D>w zg83qVYVmu0<88)>d51s3urEgFKr{y;VI1QX`hnIBzEnnkZYo_GpAWB|yqSp)hzrXf z0tmSTe)P7F&k65c1(Psl_myNW9$I*x7(nx>sQ4jaP#hMMaJzT-a$FmZh(5PKsv&nj zw;+R87Tr3AtmV&n-y<|xm%Yq%AfYLrX%FMD6(30Ie02B)gro}>gNIHx(9}vohu$Da z;|V0Lv?$vx%S4X`oDV|Z8`%tiJ<E)n%w|LRK1n*&Srq~8z% zS2sGMyi03GmR$pm^j~d4lCZC0LJM*N{ADu*p|JKI`|EYg_MPX2Fg?>}sHoK%M^L#N z=1K4O%fU_P)yG|K4=(9JY%an9{}&(D2b#Fm%k0Se|HIQcMRyW4Yd^Ma+qP}nPA0Z9 zv2ELSX5#!~+qNdQ^W{D7`OZzR)qSzovv=1;*RP+d(ui*AHU*t%TaBsM;NxgefE__B zt7-AUbNKo6b&*RTiGF#F+8C^#*_u$Vxun&!@PDvb{IX~;miedpM<~iIU@8!8;;IF& zoh?s}JBvbefTa5vDCWqk-9sJN=(Gd__+_SZDFhFmr%0Z|LZ+}+6N|OUZ56Bbk$S_H zMebP4DQSZ~!ifIYbc6L879+(LV9v%=73QhStxv21T;2vttq+W++K;Ky+(o>!4BAeX zPA7FrxrwxyyTDa7^sWk5zl{n&zecZT&360e&#xYr+kKS;ibIw5%? zql-tc$@6qy)kc@9FL{~MpM5l4ez*;uLZ51u#+im5S~$}!7ZA&J(T z$QNBS9`q`0^1zI6?9{%fQFGvQoe2$y&s<&kG)JSVq)a(%sp*#K&sw7Uf3=pN%6eAw zNiHD~rJZPOm1EV0M6FwtARDxax11+q%rj9glSG5Q!ZaGO&8>=s*p}1KId;UGu+Qi? z&M$GY_v(x~x(4gV<>=X6C$s`_WM`IJKR`wIx}+$D5(sNb2P|09w4 zR#WUBHH6~Fxc#XCU&I~Fl%to5Sxr;Pd@dTNZO}2u!MC=EJGyJF zr#I2&x3Ra>jczD~%8qO(wTl0KfeuzVkPxOWjOblf9#HYYYgUo0-BCz636@{`czZ5e# zFof71n#M~zJlR%g^VMUOhb=VgZW=^UE7t1HT5OZY7A=6KF(7v; zr~@cvOm^x%4hLQ+k~duD^`iMN2x}xTyUg*2YSnZ`yD7P$F?La$q(--c)i|U>+fY9h zZ^9G2Jl(iMTu#?<7jw6DIow#w58z|o$LA#UMPA%4)MLvL{2T|Hdg z>@vOE`Y;cz*}71VS#6&_-a?Wd)~6t3Oq@{$7x8<@- z-kIk|Wm#RyzW*#c&i;)rYJVQb9-#M|@2-b99dqpdlY)J8D9N3F^pb=<7M&~I-Y!do z-mi8fCiLR3!HHAt&idvrn}x|-s?WFC>A>2^;SFr|IdKN&h{LL}U{KzVx$~8mC!$ z3^Z%fMSIBtvA|QL367d5aJ`-YMdDWha;*Yfyx?@ZIc>EXGnU4~T;y7WT=7|n5_Gwj zo#dAtNt1w@G$ZKNyH>Dh&Czs}n(T?}gXrMuXj7y(sPbzxbqWK*uyGXNdL&W&Tvp~P z+6nnZC8XO*P&jotM8L$0ghY)(hih@{bL?Fm(-LUJqXsx$;nCo?^YjHP|C(y@%3sc6wNUU&nk#hI6tPPCX<=`KWnTgF zu}>5Q{b@W&1M6*ngEdthvK^DD80u>9i&z|{o!3x&*1A2ZE*YU^ej9f3;z3)~VO|WL`R2hYIJ2*pZRUc_oIONNRz|r*X-SCu4tPtw zPb7v>REpv<(9Du(uLGGcZV6NxLdumx{yZRr8F>3ZJ^+l482Vf~9JKj}V;ih;oz1w# zV6TJAUCAFGUYgAh1Ny?}d>M+CD#RPI1icbnvqOddj@i6eBh;*IbbB|ci zsVqN}(*V8_Ffnk3ICAgRpfB!#NtQFhh2|hM)XS|mUJDw6whe1eE2HyLzm~o><)$9o ze|9pF%qTc3NfAHsaKv}>X9E4Y@(^5US$Lb^1ak~t;dw$Sudt-?aZB1o5wcb14o1>{P~pi<77Q8MeHu>y3#Zd%i4OH4k5$aZqC@ zcyu1J|8$L#bLOW@7+4=AY+aD?UQ__iegxtP+mKtTN(eV~1C ztSe^W*0?BKkG~W!u7Ra7m?avNrJbcjo|h>JyVc41A%T>65ce7DL3XkQN46lZM}Omc z{o7rA?nZZVGNt+p#Q}T$L6)h6A%nadYcIo)^Tm4AlpyAs)F)jyyBcy?D&M4(Cj@6b zlTk{9UDDhAs1ZF8>v3JH_w5-u>eZeFussx=W*De++^bE(R%xLgV<6u-{&E)<7(k}A zKdim7L<|ulo>s|`ePNcSK+~n&1XuKVGQBSpMCKt2c7q!9JrXjFu9u)0$3ap&pJ3Pi z6v!i23&Xo9X-Q6-CpY2Y=-v`W`X(V+ve>q{n;?18y_1^fw(}1`w3AQ++AF9;%bF z9A0C?qCrc;Ak5s>5ce4IK&+mzFEEXBURltLd7v-wrkbT?yIyhxf;~v9f1|bMw&s06 zz2+v{ij5x5C)8j1Nw*h&AY}!Qy3t`+3;-qPA2m?hndKfz#zi3G6-uL%O^sF2V}P?f z@#xm9+b##7QdiIUpasY)FdiO$fNYVL-fh3|}9ASQAQ59AcYtzgH*OxVSKvtQ#&;wX7^|GTciSNU4 zY_R4ngJ{0cQh(!lPkX58l3yL68XX=F5?u~}IA8_n6UIqQTS6;eG3euOAWb1TEV836 zWZLPLml>)mDzZUm5FE!}|3_aGSav+IiC@%t{TRYmI?Y@G&7uZx186VjOk4iD77}R-r(Ylf3H)~vg?hQp{np(uvdc!N7+x@~ zxYpc=GE_u7S5bTzANhk`r;@xxh}KjQqqPxy;&~Y`cS4X)IglU%wI{PWj1oC};?4vE z`v|}`+k6qZ?$bSU#WGuV5h;ld!PK$z=^ZNgXB;UB1kF?lO0fLv9q>t==76o&ZE*acr^2zg04P+{lGjg2w zsj;`)?&<{@FnO2Uk%3q=QY-cqo1fF2z`vn<{o( zIyFjUK#%UJ@Lp`r*pdk1O6n@UcYzuau2~z=Vi)Q|0Zizszcm8pPf@~~Ft~RCsL$yc zn75g5Jb^dMZ1I7kx-7odlSeEItPTZy(Igdp&~Z2KgV65=IR2M81O&`F62 z0{`h*@ubtX$$KM#_I+`99^Atzm!9LIYwAE~7WsbF7X3fr+TpJP-3t)dO1vprMKr9n1K-8LF+(toIPj`hz2;LotbhJ}-ZA0|&0 zeJt@BAIhYADdEDQ;nNoW=Y#h@%GYmOk03wRjIfQP_}*;)kNlmfTSCFPlxtl&=e=Lk z26}zqV|6v#WYT{nG7&hw+|IKw(iZ}5G*p-*ChGgC4>uh4JAyzfNCPMBQHE=&zCj>J zGlE)^IG^6(k~$P%(QPwOeIr~ zP!bw~bu_1OsZ#rBpcgo76Z(RP5Oz>)Rd51>u+{%6+0Ia96k5)3Lq=mhp09c`wq`QG zHaSZvLJZC_XF&gngBassM+$19wc<5`>r~e(RFIm^u}*)0cB#P$4?U|an9lq~8Y4w{ z3<&oYA{jzt4S=xmgibi^u$(nd@_`Wlmh0Se6OIH<^;qp)B!}tVdgP?98v#fg#FJ~& z&8>md15nTykXQC7T)`v+oqWjma9~%Ved#fEpuNfAxnR#zBkWS-^_IeS-^hHu$DXOf zU>1qT0!yM0ff+Yw)KYvfSWm5t>Ap`yd+5n}^3|btyIDDS`eyK$^Fmn?q**u%;40@Phch3Fkm^c`A@9@&^o^ zURx1I#KLf?Uz8`bt`p&n&Jbr12T!qI1 zKOB_yoAt{h+0PYMTwM#+h8Tlf*>Q?#2{u($4T{1QU44AqNYR$rR<~8&uDQQImQVMNpabeU(q6sGyd&^}R3xx{W>~o;tX?bqRpv z+;@I~=oeepf>smV`J`2Pp@EdW;nJQX>tYt@4u3|l0&<4>VI^fP5!iytR6qYP8Y|Vs zw-dd@A}B~ky##*=^50iQ6NEtDbu%{pXJ)OBG*-GA^QVnW!J%aeZ_=$Vu(q*g>G}4J zNa!5S5lXTe=BZHFerg8=72mVIq>zt<&UPAwnKwbo-HA=>+Jq_SdyW1R44uJwSuLLM($k2y zJYQ&C1R{9}39J?0`MM^As2!~Bx|ug12(bpx+JiaHmvR{!g-w~Mhc+nwqL}|11hSs5 zOs;Chl8G)?KH$9NcPD8e#GwdRr1q8o8E0w$%<0_?ITDiP}rU zs^fHD#K^E6;@!wsawbY<0N9sRiqX7K1)vVa8c9{Azw#yBgy?$-U2L_R0+fApAM~2y zaz$npKawRyhz<(H@%KDY%*+xd4sW42_vAV>h0Z#BTb+Bbd@JrcsMQh}YR!daX@XXl zp#*VqO_F2Qhbr>3f%jxj@P|2r6%Ya>`p4Nn7Am1ZN5MzfDE0%~C5pbYFWxKuP^sJxN(uAt@#VZX>$0vAZPuCpl29`hvrK z)>k_4tj;)4TOCWlRvU{DMggX|NEC<0R5gp50gORNu(QCJ+80n-z5w8mmfu_l%3Z`w zgCcF)Vc!f@P6(pWiNjSs2wD?(cd=TxDQf9!vTw256|(ws$j%{?fQBN2%Q>>cH@|<% z0CJ+n<$q&qeo_EHwua%Ub+kC5*0$N zTeFWH;ei?oa#7^)YVUrBr$2KJ#}{=2`}v_t$`bU=r9$>iCm|hnl4WoO@d@d}jRQpd zz?MjMsuh`Dv00=@t`jGnlaj$xpAj%wc4fb8%v5-OtGfk7lEUJ&9BMX#8^|y@HDvU1 zi}n|N(AXE9Yu>W>34|_kA*3yxtk?8A?V9U~Qw@QkN>-d+Gx#C`D`puvqfutC@j?&& zQX05cTe^v+Cie@9M2UL}{YZ8CC`1shNn>*2sXAl?Xf=;gRzHf!r;X0SL@!P;1vZma zC-!jNmFfbng*02EW}|L>BrA67j}o-h42Ox6Tap9@%-rsF>#mYntD~^U((!gDzPGUs zqv^W2=AjqVEi;6;Xns0*C&|`~%pkYw><)Bzx76bY*5|^ZhOhkl2`vfbS`wXF5#_=O z9s9?(k!je!k)oc(1{xV86n%B<18VaZ&DN%s#U`<+~wVr zCC@xJS6Q#X?BrQ0cw(^Cq+WCCFs;#8WSE1&BB%x*I&OY?=NE-&HUu^?KSbTgS+crOR%d)xAS@phIdC`9i;7b+VV5PP{IAo*t%vKO3B9@q7-LHF zhkU~~_!=O>KeaFiv7grf@V#@jykN=yH1LCb`z?;X4q7`b_vy@swytwoh?o33zB_)| z-#y>QIv?E~40WXOE6_T+Ij?fSHyXhfUByl78AU2&UIb{r$crZilWKl?^mVAIzTWWk znBr6VF>YBM_!S4>mC@Q49t!bmHREIS6r2XJW1Mh8+R!bmfY^9y7ufSi7NsS(=#T3f z>xVtL`tZ%zC#7`N9|Nkngg^fSyF>=IHwRqAUpiS4Sp083hQex8X!m6x`DzvhZ-|2v z@R*iRAYorzR6CdP8j%R6A_N6Y<5D3jf~|@0NTDbRd2f4jSl{KYm4w67AJc_Jn6LX; zJ~rR0JdJ0SlQ7*~ev>2UNnNFzq3b6|?%&_a(#85^!VyK2%_SVIdz>7a?lO*AFl`NW z^^TnBc4m6aEt6Q|MPzK=Lon-rc80`G1X|B8D-{d382H`HI(Plm5_Y-4T1T=JxoOyy z@{(UofPH421;;Re!wm(0k!eVDS*cT~_gP*2%yA8`#&!I-HWm$m&kYH|S=|Le*tBmo zE>>D7Omit{2#V0b9;n^NE2xhh;%_tOvRs~J*-+k=p;M7-E(y}^~IhiCFVB0IvcT5!CfHZ>{+p>Sm#=q@2m$#VVG)QO|YtD;Cicq z#gm#$3lNia0?euFIo?IVLXlY@l3k)97Bz(YrF#ewBO@zQcxgtEB9keYl2S@0!9=ex zC)3jiJkSb*q+&*)1xMLv6cjQO`{(HjNsc*Knf^-}n-sh7P~@ss9SfS@NE;1PjHuC@ z=oh$@L{rGnc7T~f_Iz5Li6OgIjMBbnOCp64Fhxqp-7<7p%mijpV-PF}}MX^_QoQepu1~%~i^vt;9229S~Qn@7L3Q ziKLl>1=5tzK4sS3JIA+yTVDcO&AAP5=o2S2@@@Ahf0w^0x{y>yDOR4x?Jr{TjT!ZVz719&aDVM*KgyUW{)R6vaL2acSv}8P5VXwT`wqbDX(j20UwI49U?D z^vlvsI`@s`YxraG{G9K*C?WybL@;5pG;BAoC&GXK<79Yb)Z_$YNnWpc2m~IS^s_ny zC+7}7u5mtR8+GP2=F9BZNp%t4WMlH{?G5*VZeSHaga02Q+ce60U4H!BJ;Rap-gbz1 zSN9frLE`&lTmvKi&JjoY|By^5%N004%=69evQC6)TM-~~5%p3K_3+aZ>~$yjm)f_0 z7YcjPjVCU+hXENs&31=beJ?z8&IJ!;^m712^y>6cY;q`O#~*>$)7m05Fgco)6h5ZA zWkBP#5AFW`w!9;5C&i(-km(G|>ywUq zy{+5+b&H~W;T(E`dZ%nuA6D%01HFVN>|s?(%+iw_{^R+{*Y}6j0jhpq10`0DK!ps) z6r>o#V%>Dd)We#|-;5?!dCe8A^o#QLnksR)e=MzxN>}M zM2z6GDZ#H3`44lrnvmZIbt|^ku(d(reZj04`(1ghigiIZ-Gr09!|vSOJsBJ@rsc&y=WSNLo3`iMkG!+SCIP zb;d356B%+fk){Ze9Af2|3m&$Eb5M%Die&1fYV>``z0$qezkf>D5M4Ga(CRap2Qxg{ zDXI-e7b+EJbCSnqwgYq=;3BW}1$@4+|Mb2@**JR$Z*~Gw3Zxs&Gkxru|2D4gs6bgM zdnk!i9-N8rjhM%XxDAB;93*}-HYHBjSDjnyrx?c{0PE=ovZ-eBb#DZnhdyuNaZl&x z5v?4;)uDLoo=V<0IMM(T(Gr*t!iKe+yI!y+ z>o;RN(Fke!U^UgOEOsk!3(R+C1F>+74f6irkrAul7hj{As7|K3f&Z-xmfiagnv`@G zbG@X|&V#RuW@U`s&l#CO7%97squ?L{BT-;^W=bQQ6a!0lJyMn_CoF6W`a9g#!a0Z` zyrwBGAC@x)+-OAm+7F60tYvd?OF0KzmpkkEhZ~YVf|Xtru>q{{TP&m>Ky{1}Bqss` zpxFfBQNp?*@ZNtUo}|WNLA6VO92&Upn2;rS1k9dq&#ifUoS!cpuK|%6EGG|Gpf=l8g=pP&tk)}h<%O%)vX#Sau zK2rxqy7JQ7HN%JorrRYJHW<-GTizcgPO(n#%5AQV24nI;_X92Gy% z3}Gxt=cLp&PK3}9TTS?eT8k*MQ0r9KC1!85PKsh!jjoy=F(iXiM=EqpfElB! zNe6_8Q~8Af!6IgnhEZ*>>Q-d0v7Yn(jKc_R7qXO|45f7bx9Ztjobm(9PQ_;+#5f92 zmulC_B)XBnkY4h)+A5WgNG#=Afku*AjY?7n;LjwU^JS{X0;<3+4A&ntidveU#N)|Gl7tqEFKf>tTUyscqWV@T4Qkce zxQe1{yVzq*u(*q>Lva~Sm4;E(ULnr8*&tyST}E5Ap{bnLEg@u$GFflVDe?@3&alg6_k_NJ}raEd*lbPzIb6$qxW zmKdCe)gTE?>yBr!1eypCLL_b9wZ3}hQ$oR|&)YnP zsRsIR^!{|S6376WwN;iOXkf06F9H6uNfVQVFB&)bqL^R7ttGZ=zmKk#J*jFH84;JY z&|kK#(i9Bj+-@xRE=G@vs(Z!qheh$zZ6=2}-Cf&-WR zf>5_=DNfR2z)M4Ptk|{4Vy|T*X4eT%2+D;yN8JgE*+RHp4GB8>lm2p=$T#^xOQ90fF;8wfSt94Sp>P^& zwvk}^#Uv4uES+QIw2BE0>wz7b2Q;UpjB07hn8}rjty*{WIqzJfK8V#qFBMRZOQ$3* zd|^Fr4941t{7i;|c*gJ{Lra{UofEE@HYS`vA=wf!E_{%pS4>@EHnXV6uw_YOC;Vag z7NxPUt+;Af6kWE}aLtMw(xjkzIHuP^jeoRqiEZdA7f%6oj_8a{wM6Xb?}-F$Inw{&EI$?K@f>DN`4mvxXY=>eLA7#$I*RI&;*L)glPdK;g2!&} zjG+0gRo^2WOW&raO$fK`YSd0Kskc>3qp&^ECfR-(&_?*ts2qh=T6GK(9ZwhszL`Fp zJddvI+T@N#&SfK=rBzzWEO zay<=bJgVAiV-~==uTvh4hyo6!tg#BPb3--R=vlLj&KON**N2He*2`yLqJq9gYcj`P z>X#61%{V_pN4dC zO%k*w{SUhON2*d5r>UN+&XPC;t3#q<>zCg2qpN)sTRyl2CiKC_0CBu+Z1i)1NeLDo=$qk$6m0mVmL1daon=#U~ne@aF zf%+2RhTr`|;4l5XoaZkj!H;DM&{l2+V`6E9r)e4{mws_YOT$|YVFZ^plD+M@T}jaO zQztHJu{kF2epgfKqtve2)rV@#_5UMMO5q^q#F*4zy+H0qUm2rC(t{Uy^QO~2xEFbH zk63S1Mi!5HJ3H}2oXmr4M5RXLS4jG4FP!f(%|rev#+%|g!^6zJ3%BqPiDz5EB8r;9 zx<1<0#l1|+-Oov7FbsEiSJ70ZX7I2Bmb}PO4Hjo2HUFrgM?brS)TULL-1czMnmJeC z0H@MUAHAcUq#7-`)=klnp&GQQC#{{NmUxkC1u`f^b^{M>w>it_iZo<(p=20m8eC$* z%@1+F8!iP4%We>B5im{@u`~6Fc=0o>F1SN!6gNY7oH!K?K;sfOkejgG@ibOsv)85B z-!5E5pDs@wP2COwmWG(6^urvXhSlDL8q18I))lz&N74WJ1ka^o<1A8h2kW212vf{Wcf6@4=liO)U8oK41%!jeR>Tt>P zi{~~cO`NSUfOIL)(d0)wGi;7_dl@8~xf)@ECXH#0;*;aA3rmjJAN>0_YO60y(i{M`IYWsk$;9C zDzL}?vAHtY0&GbnC<04SKkL--h3T4d=)aX?7zv7*^iHlVj(M2);`@OjYHUbxX+%th zQ}v;WU)h@Ng(+U6JS#MKn8#t(&sIxl#3w8aG3WgV5S=*L9|xNPm|F41MeZ77r&Yq@ z>g4Gdw|2{{h7p|8McM1+8ay{R_40WA6oHr}@Gn$LlYpeN?7r*_ghAo*xQVcz)#}v- zZq#zvqQP)2IwPnlBPr81Z)-Xsa4Diid)WrS1t9p?!qbbQ@+mP1>s7JXQ61q?A4a4X4vnlU=qF>W2zUW5{Q5C|l@U_m5Ho=D|2Df3wRCBR5d8ZvJpB^rjoSYB zmq3uLp1S#o_V)k0UV#_pHWgzcN{Yfc-kE7BO-PHXqus4Au!WLdQ4DZJ5x3@0?P~l9 z7YJlYqU)fMP-HsLK1)K*A?pN1pKMNMeO*Zf+v}kjwkd-TtIoI%L28#-a#XeTy>Y_` zXm!z|$&V{@1*XpWABY6xTVRTWk)1@@uGPm-M;urtWS!j~MQ5Gl@CE{hzrh>#>YXk* z@*50P?-xyo)d+;RxI^dA0AP&a#Ik?;g&arz3>ACtL;D*@q&9Dht z6Q3U z;d!0V{l!6M39$HaXaS%w8@LgG~vaup*NDDGXIV;eh9ZWO3pwezb(=XIFKA^zFM{6UCVn#nMKJ(Dio`w8ezt{ z-+A8jZkCENi;UXB2jS1q@?H9u*D<47)%z|cR9G6xLj+LWqMxHCbOE0flEq)$poD-1 z-hLAW%k?EXW2?G-bol;^(Kquf(-3aaiWsV0e?*A^#*&_kJkpPfqqZVlk38q#G*S~l zFpT@Sq2h!7ya^BoH!OO(bz~!n$8R~XELh?)_9qM-c^N|NH~l7i$cvqPKdi?~t$sq- z&rI+M=a%5X8V%b+`Rqrk;}L{x#l) zz)z`J9g^kvlM?Z6PqXEbHB%jZc0?u`2}@(ZP?h`Al+V%p?(K8+4uss=e;nQM!S4U& zWmiK_Y93%?UP?`;8Xie;b`$DWt+9nLI*IoDV(1Z6FinzgO%k_hr(*H-L6z^h`3Mly z(yhM!8{;suf9mcr>5yayvb^XkwVmki<-vI{Ix4&w1Pb>B1J4(u8jx?0+HWwh$a)zZ zzJ5kw4X#x%M@)*+<8VW*w$0N%0S*NmpK5#ifiX;tUsYu3M+?+?uHjb}sfJJFix$5_ z`5S_`ZNnjSzmKX_#Amf_JIaLAz{nnb`i9&c4!ERtG(&ekaW_JBjt@FR{Bi)vCwQ@N z-^qBK^~mHtv(394Kuzffa?FZp`P8{4CUkBw0mK7FFWSt>9zE9@iBvO{RpBcZd$+$X z7JD6sTI>AOwk+12$;F`@D{m-Ib}ub-{m$3(l}3X1l0Dtmw`{vkd(l z93Wb@csINGq}UEglMZ_yEHSDolF=`<3woHVnk?}Po)-Gk9_nvTm^&n^zaJ=?RM^s5 zQUze&aRnEITITx-jwFpWr81Z1nED+rV?i;QUJaf^RO&eTN4`8gd{(z6pK{F>pk8J5 zYNX#u?2=fTur^GM%0<7=e)1|ci;089E$Kc|!qeDYW;M>{IYwq4wwT}HIR+Dj&Me`I zDKX|v)cpxgtaD-?{>u@iNlBlHgp$`e^eON5+sDo7%9Q+T_d(ktoPs0^)vSU(N2$%AN#q)BI&GVClLl}Wx9 z!Q>Fd9u$p}bM~O@u?3SyK(FC>3yKOcs9oH=y$GjG{8f;>R>ioc$q>+>h3$r_nDZPy z2zly284^@)0DRy_IXuxU1wU0ED@29PNF^DgRq=rl(0jO0oS7h4mt$!+$-B29i>Ohk z^J(7TJyg`RM>r<&hT^|nTk~%>Ap(K{6jObgt<^tcjBPP|-k2*gkQcObUB5t92tv^_ z1m!MI2K9`uxZ7O+sHc!shwAA)`B*E7_~g50>lT8+!abH!LI0DYl8JyZmvz2NruR*k z(0L`E2L-;OX`*ycNpmG&>>V~!YOst3ROo)uJ`1==qx&Igx{nB|ieEGf4)}lf=Sm#H zX#{Il_hW-W%cD2GCt(!Igm!9CG~1p$TScx))3N<6Hj5;xdrACWmI*wFidz@FJ~&)B zNyU-NDYL(-L(L;&SUFl?G^`fU%BI?%L;Fh^*`Ui6>691=P}S-;?A!cvsn6-RkgvhAyA0P%gI-eDA)cZAG3KX(OrEagE-DuJ!Y1Wx zly7UXhcqN1oq@9_nq=Y{7GD%PfXII*SvNv(i8>Vq8UXY&vBUm=1Yq=7)zmUI;Z@7r z!(0Ih0>nW!??n-9QeYjslAHOuGBdCi)J+aeMu5LUARn(%ISiuh(@<$E5z}K!lMo}! zWA|B+BwdWWYg+}W%lgYkRT>1eJ>cS5ZN!Xb4Q3q(jc0>as5Lgcm`|1De0hJ*A7VGW z43#yQ0d4MmFo&qG2bnjLF|aL}<^m64Qp~`=oHYDd`9*s*7t$g1tk${EMz7qIjS5Ed?paX*FFRvH~AU5Ee*5J;(m3`RD>J+O;WK7<_DQC6kX)k)}>n5x~Dno*2 z*tj4@g1{mU@t&YOx^td2G&*w#P}rm)XA%F%C00|~A}RhIMqHj%))$obTon};>3b{w zg0Q+_S+uUiB)U=D_epH{^|f>dg_;*#AlFA!fgkCbknjt8k#ZXf45^h((WoaT7Cr zsCaLv7+i+$vmcmRXB&}SUlLic(`zhNME2cS@cxRtCh>uuxE zOk4xu1#&62kZT{xXU-B%d|i^>h59p4vZJv<&ds{}BuRJY&?FdmnhhxCL!y#0gD-cv zfV@f@9QuuUf5_9Grb2^{xIca5(r38^Xr!2d4cTfhEkiSnfvb(FQF(5t_%h_tG93u=TlnC3yL@!mod zU{2qr^kjlYDRoQOls3IB2T)B6Ro6TdGY&B`f`>wZr@t5UVmxT3TX&arp-H0?u{YZN zs~3YI3X!XJoO+{e1gU`?Zc&hHv{}=&&QnX&w|1wULdCyQzsEySjTuC%a^U<48{pvs z^0L2ZS?uIxQXm0#K|!(>FvuV&B@N)75gG25u~lN>L85T_XG&fCRrj2jHoB*C(`>OB zmj&f$CD<&g-s5s!EQ`R3tgE{!A4_IE(k8%A_hFgT3MIhXd1mmZaHK;)fm5uiIaZLf zzb%t%9QFg3DKY_kvv^WO3;{fZOC6IbcyDWlZxKabmC6lTHB;v!3pKu&F4fe`Llp9- zQ=387ViQ_OtHm<$2>Fjn1LsA|g&{WGRrAZ6A`;(knCg^sfKrXQ3l1JcH&5JS4bxj{ zXGgW&`DJaVD#7as zSs*smT!*@l>ol~rb8Mk{cNR}YsyyXop7waaB_1i4x9&{c>Tvsg#wqZw#q@@ICSlvKK(JLDgFz_76aLC6JyZN|zEW zyWGieo_@)2XocRf%QE0ECLX_*bO9&B+|1F6&HE3dUBrDgMTiSqP71# zOAY~1LEUKkl9>c1N3UB8p*#k1F<*r-wK1&JzqIeI7}k_Q-zc^CGtW1-XTUx~%r5?O zLTX?34AGLHF_NEI4Y`q(ug?SPwZehc_bc5M5NH)L zy^9wb1px>SplDg3RBAAcSzY`tDK*L=3P@tN9hoI+$_zRyHG#_9T=F`p5bl1z{T$m| zoZNvJrgP#h8-819vpR)piwZz$4K+8Xxnj#VVkejrbhK}$~ zykp@{A2^3Gxiyk6!nvwHJt(Mcdy)ASj~8CDFFLi>%=_IGooS@P6)|5qXRIY(B(JY{ zqFY0iU=CzB3JN4+{Yx_<(X#eSm9ef!)iKLk@BL#H`ceNRug|$R=E~+a-;h(ux`ABU zW*9fn;a|Kx^yl>OeX&KKR5!oapO>XWNiHPl)zrp4;PR`6-Cc|%%a)6`eK#~{j zjyOSya+Gv=i9raHGKjC@i$+ivwTN<%alWFOE{eLGOOMh$Chb7u>vh zKUB~?IG6*RDv@Q**)lKV7~>cr9~w*zK{R;GnWb>R+fm_8jf=u%sZ~(DrOKeFyKoD_ zRc{j{!4N2X(FZ;7y+ep+NwGqOg`iM+V4gr`utjV1t7jwFu~br1mJvi{N<}3{G*=u? z0p`T1C&G|{p@%^vpw9z3SCHviDyT71SK(8}gRx5h7fZJUrhPjEQhPmwJl6DJ&0}XG zEMbTtAkrZ*JW8y_$$4RH=2YbJlyM0xgVHlY@-zfqCDLo0Z=QqIul5hDlte}v z;-me$gR`q?&97(Co+!&1#Adcw%4)LglNrUIdIRtUgg65#yaP+Vt#9!6dmAuCN1Awi z(Jv~CU>hqmh1WA9ma(hj>XQYoe5L~9IMb)u=*%qvDiw>B2#cb!*zc}4PdC5zI%%%J z&yNIuWxractYo_G?5QIqZ2Z|gL-f}qk2QFXWjH65MYc9CA+I~fsepb>OSp=`)GA~< zcER!Rk>e94ouT}uqk$O*#dt3N~K zz(aS=N?Y{e!|M~@NsEWD zkE4flAw_4go|cMTM46?Cr^DXwwKNLZrq37)A4>11Sz>!M3C9F2e!fMfX)*X=X1vio ze)zQcO#>m#8pH!ZDp7*d>Y3wHEt~Xx*$!L1 zcM4rY5S!eAlc>PzDV>gd(r1xoI8dcTtlE3wHZwvsj4WT~HTzGVEG`PQ1-M*ivuWd{ zrUb?BSO?m#AJ8%4vWVMPm|QHzb>%GQPY_uVlmwk@p6wF9%6&sr^1`f6d?>A)b?Tb1 zQkwtrdA2^oFW|?#Y6(q=M$`8P(u%<&36Ss59OMg?>+s`-Q5W9Gvs=SIN3CRo%6h1} zG`*)*aD0GN2op2zTYp{4W9;Pp9bK%w`>(H#raEhvZ`U9B_7`-qRtz-& z-eO?;6)1|e!+Smi27WSel6@98OK^2#rAdA|gFXVjAKP7?M~5#vE5B7{OSO2cfK~MK zF}I8ibRBbHILwKqQWiCKNi~kAAs(ii*OOoZ`HOk`O-|G8aR1M`vMWsZ&l{qtLhCK6 z^5{czUi~Xg2!=8wAsv|G<_b>WRjanunBS2MXdO_~spkYRdl!)UQakIw>xKh4o?Rib z@hb`6jKY#|HpIGQ8?5d=swxZBebl307*ZGXzex)d5~1ebB~7wz*%rd5C#{6D19za6x>mE(9CrcBBtCiGFv5G;Y0GHC4ZUfPFx9NfAJzhw(DG!mL zd&o!74W}?*=!$X=61XxtyUjPUN}7LoDtxz@j^%AZ0g1x`)r=h)=y{Vcb=CjSSbsfA z*#V7uS{yEdD{r6VF^KM=b%X4V(tNyeb(MN)UBWb~C%0Hh#oQBC?hhCDJ zBV2pr>gw%u%S{jb?MQ(Ch!~nBrG;vhOwim$;0JwtZ5vQUGN<$*cZBnNO8h9oFeI$< z-6_O_LfU_A1nQF66s*P;QG@Q=&ATD=w#~6eB_5|t(xUcRFZdc;S|YW=S|lwAsV?np zm=90BPUNn`=p^5n*t=5OjN{E*UF`3%8bCB!LTN?OjpYv!!)Ygw>1=;+v<-*=Zrezt z)b`Fg?R-MGB=8)E52ouvv|KL?A2~90MJFxIzZ$mb`j8AUr6qV0MmWTviv(l+3JN&p zc6^oIdkEv6(D@ioBiX6Xn_neu6(bK*i8it5`^Joa9P?usB6E1CO>-}Y;XNjT>lN(H ze0e?`d;013$_?}O0{gQR)>;|kbNprD)oMUb|IECmCG;UyE=LtXidJ9Y%|`7TyizgW zLCs*K0TWo&hBN)s`QlawinOF;0LWMx9EtLypOB&(w|_;z+(0Y0XbVV1F^v>5-Lex- zt_Qnx-eT1tGXDrqxNS_cTrf7frp(PR!3VTmu@VJ>)8Y?|AZ)%z67Fff{Ky(SrfrcBM(e4!n2YFD>J{r0!@BGR~)H(21xg80Q}yM*?U zyvPQyQgKs+&ZEdd;$pls8BW3Xa%CXdq|(EKa$d$px8y;QUxaklOhl1)Ln*L0CJ8=M z=L%xv*zT|)Zyg|G1BU6;9G&1eK_lm2ivVsQXi&m-MC)NWfhWa69QCEiWVP5IGTM~2 zanXlzcJq9Z`o+putG^(+wrTX0&6+-e;3ExT7|$FO?u1NLJe_$uGRSY15ZzeHjMGz4 zRMAV5EQ^qPsD8Sm?-Ri?$aYIzXpilOJmh)gD3+Ab3-Msa%P&m^Vbv6P$vQbg9Ue;p zGqMC+~jmN0mI#XbRKu**` ztYj?CzKO5y9bm2M^ZAzBR9pH(sOYkCetZm;fMAh6v>@m4}t_3y$SR zRwnJRO*Sm4uuVjnlmmm!$&$&i7tEVL%9@!W*TM#98Vyvx!BWIVD>v#8WAkj#CN?9K zpcaN&UM&S414#|q5>~<>`Q+iA_v`b~4Yh!Aa5yz8Uc85~L<}B~AGAi9l3HGDuy;~4 zi43wva*<^7%IP{f4g|G4@zo7m8Sm8_)m&xk8F<#(JC40~3l(HB4=kI5kCxSVKJbS7 z7NHXQ6pSMwZNdfBhI}iBfeb?>kct>#Jf|AKei(!QnE|FX~uw} z^6zL|uL<|}3Bie|8UTTgxXl0Zpe`A1bfTt3pRs8eGM*~BN1Vjz<`&n_UC(cJi=Mo= zyot8x(_PL+deh^$tV(<{%<`Hs^mED|FZQFY`$l0eV@ub2m1gja`Kq=oxmb_04i$Fq zFH2}h7VBJcLqz0d)+1I@U{|7!URw+2I@VP~AWGl8X|oP)^agx0P~tu?QWKMi^a?=a zKoy!M;a)PuqoJw+*HFLnDCCRKb6xJEn8b3`P;tNAK0nnRUx~+yL;G?L6A6NBne3R4 zj0ToTG$5YeBCz0}PS{bI4Z>A z0A>u$9Ab)_ktj1FEyRXR&TK1=CT0$g;65H}ZH}Mu%5)*V6i}%dYfCzJm4_nUi~J|E~^0r z2|pM%zHQBv%@8Brn=&)nk`#QKbKO)F=Fpu#X`XE!@=oKZ!i!A3bFV^~@gpXbJH{t2KO@?X+PuCDG9A8R>@$$*dVqOR7*{-`m7f zoCWa26QHPYRqIlg5lDjF=PlwT?rM< zRKQPCo!8-T7C@p}J1(2w@%)RIn6B)~6ETl8F^B0Af`G=qSq^;tuH3zx{D}nxw^KHL zgNJHh4OO_rDPPNvTp+-$K7HvE^#^!wndu~$cA07WcNXLntvSjtkN=!iSz|fjcXuup=~O7Q=rmelWfli z62Ph;RHv8Y&#vzqM46{mShV}X6XQH4cZ_zC`~^}O*@MmJN~+{=e*7{Ub}GYJ#r7)5 z?j%F?(Li}EquWKb|9mf-He=CezeLg;(5?t{an*hUpo_<()(}4^goJeFSV%JPr zhOlV~DQuAeg43d(4Quz3N1U=9wOOoW18-*JnL_9~Cg(IM2VG9}749qiW96sJ-OgkZ z&b^Z0L`5OsRAzj4D_r< zVotHclHmU^4N;&^4D1&0?bP{2@9ypM^4#^aeda;YykPQzRWltJNOAS7g#s#W@Zaww zfKm}J4n$En%;J&Tpyi{2D|OjZP^TnEEwS4esv^oKsTT+6WL~3Emu))F0P8XbdDWYf`D^mIiklx+IZ@_F6z* zz(>FQz4%wIp0XNw0SQ+?XOYQBxzoX-Ra0aQA;yT?NE#zr5=3}RAsIv^D|Pj0PyOws zM@Cfv?na}R;+7BvXAkk$1j^ilurByrEvI}2apKYM@3_HVfrQ28tUn@oW#G-dD+pjp zo=yWi)?j)4Bc@oS^{Z5>DHzP-?7ap|hGagqK2FHat7Y7b|KS@>b}(h^VK3?2HpSdb zDmEl+)Os|uZmxd%XJGi>3zm%&tP8l~V`+xkRblG)oFjpW#S7yy6`9eIbVVwGa_}d% zA4%U6JBlU#xMR788tPBD;0~l9Nb~$vn!==(Y;FClKVA<^D8H%u;`>H7M-X6+rh$36 zsv^_Oi=a?T{v7ltpzvx#BW2GI+l!1JIEf`lxj~*b2T|fmzfeQka>J3t0_6`xb}gHS zrt0gq*tu++w|Tai#g?k-uAEC|msB=GY!*g=`&1l;hi{=Bl!!WOR_l+l-L1MP43wosqUC8vTA&E`#prb!w+t%$>aD? z3V|RBkJK_l)*d7yF?CY~$2V6OES+2QUS<@lwh1GR9zBt%h)d0xW_Ui_QN1I_i<{Fl zz*`@>0v=w|`)9lS7QZmdCmc~s#oH1ppPUo~8NR97H;6Tf=E~vc{-~`ovDwTc);M0@ z7~^|KZ@(uX;zs%u)+Cy``m)ZIF(UK1Qu-9{gSYrs_E)!&fM=HnW-3Ah&3+1edtaxA zOIP%&qDsh&XTQ0UMP%)TRy&jxjZz2b0dOzEX6_d&v3 z*dhAjO3Aqh6iKJ{J&zARjxYE7_jlI)Ub~`JRvCNwaz`G5t!StGroLVon{#4isOHzM zkXhrz$m{AE)Yy>5+6xLkOHy|$Cg_(TVu*Vr7P~jL;|csAC-sF1dr#pTnQ_N~$TCY> zLtr{yx1B$TWomV%3U8gsoiqiy>lQXo^O{UgI3@Ko?lu#SmuC(q?V|qOSs=Ce(tE&~ zHwpKhnU+iC5T5~mkyHQ9kL&9e`?0XC;FJeS|{H`Iw^!UTwUFV zrl~Uw4vI*du`9VkspsDD@7EA7-&|6Kz1&ANrXm>aCk~FmJ~A78SX!i#YkZP%{?dtDGPPUO9&JR~)x+TRh;^fkbg$1cwx{XpHJxSdk+;*1r~jsFbjMXsw3YZa(o<-77(x8EU|Z&ev?e?>j4p)YRfjnlq)CNtiPs9jVOk@&=@5FE zW^YjkvW0#IW-pa6hc6f@2sb+$=_%0WA3hbYfTcOfXBry0!tm6y^QiENoPa8nu0pf` z*%WQFk;)`)I|0mjl&9H>vO<-1Kk_0ak8^MG_cuQCEixFgEt~5~4wneoWsN3v)8~ z&t=2*^)*ii$=d4z@>wwf@R-4Rwm2$0QIFdOrG&>sUnQWKshNVN*=6F1N^Su`d_o{U zk%13bTCb#;lD!4+YdeB?5Z6PKIqKnGR*qity563iE@LXjg$#HgvQ~`@DL9|r)0Qp5 zQcZsr@lY&m|G~>n2wX=_*caj*Ew<j#Y&yvlf@0vFnL&DSTgY21Cyqb9Rt4E4G<(1ViIi@r|ux zJk?QMC_(@gaX~lAU2KZ|eXNPfFa=BCL@RJdG)v28a%%mn=NoGR`fWum{4z{j>x>Jz z!*8vUmU_a-Zw>l76d%CyN520Ap(dN4YqWK1j>Ie}vm%7@3zn(%0teGudWL@mdBGnP zR|HJnDRf>ou-g){2kTcpPE5RCCyl1tNFUCWP;F9JqbN~oe;RMASznhGLy31Go zJRFK#uf-DxS|^Laq&`m3j{vGUe3t(Md{B0~gQ^i(mAE?T^v}kR5~@NB1SDzT274jLm~vs=LyR~BECtSvtixt{-mu^9 z2wR%~=Z)mgF()jJKex$viAQwXhLJKvU+Gzn6&ay};4G$D2csK|FGQGq={fS@@Y`ck znet)u^&CXaj+!u)6k>2kN)OaCrUDqpVIXh7A-N3D2k;p*dAsCj0L5p{;N5Mng@X z(KY3!(HCPY%6xG0#n|VUuI*VoY|4~%PU@4T98wW;vw-?!tpi(RMs4#WCT;&8KavMx zNDFz|JP4zW2DoA)gfz_XP~l!+ZBRrQkdmkcFVRR$r43X->ia0}9OV&&?pcSW4+!@) zpeUp@whKg4;H>I*kvC_ycFmf=6W=?aceIGh7rWt9PqJcXM zMO#b`;rW5^Hrqpd?PmLgousU2e2jv5aT;#SsY)U&5MD5yWug;jao@~jeeFU1JTbiW zV5!VE?&WX5l$92;d|7$1Sv*drr6w>Dv>sAwK983{C!D9Al=S?Iax7D`)5{t0@1cGe z5>vQsGG2Tc`cWE(Y5PNpIb*Z9GWbsFo;t>?+J|jgr>n|}!QryXkeQHh@JN%tZdUyZ zGmV;}rM)hjAerX?Ma{M`uBY2v`A9Iaq`rr)l|^-$6+gkk!`2;!;)7K42sMnwB!`ew zHmv+4hhMWUr*~P8@&p(;t)v1zN#l9lZN`xiCKP7>_*_yHY{do42cC>{v=2H)inqq^ zBN%S%s{T z=x^J-zJ*AXFGeod&bU8dAKBTPn&)8eEl6M=I)Bx8eKHBkr%6YAXpxJF@QCQfNmd;JtYYp+!pL z7UxFuliKbFMDe<+Y;=QCPutoGtm-nQdSp;H5#p=eXAgjJ{;}*hQZ7RU#@tEfkC40p zeMRN28RNN`{AoI{Z%D@UTATD>G}OPGUcFVq{?9Ue27~Mdc}uKq!4pGA$5DTW6-oq z%JeIxj%(tGbNY|@lD-A1bsXYgDIRJC6`;_N0_&_e(bvAqe$LtRLK4?4n#b|#Uo+3d zgZO4OKoyXewXxx;^cDo}-NeCW^ysnRt!wYs3_0dv>HQ-Pxyq5*V=xP0Bn%FD1D;P& z8|fum)8tI7oFDTrb%^i zm|Zp)&{?3*VXopdF12prH_;8$DB~B6uyz3a`x>>dwe+TwR3Zkx8Ag(BS1aKYoZ!}K zy;z}2DR&G@@X_R4YA}Q-FY4tE?^J@puDT4241nO3hfh4F;%V zpjNLxZ(S^tS5}r0fTmolFZ8ZX$j&q< zjFU-=ITsUj3d;==@6${+IWo6N!eF8!s%c>35n+RfmA8_*HZ-d0yItHL)-k5ExJu$(T1vPp~> zmC2t(SWCa+oE%eWHs-jNSnhuT5ozUi^TPK@4LF)GcO5ivM_Txbl+&sbB&K>vbnw;g zhb7`N>S%#`ar5AU)ueoFN5UFX^KtM*Z)kG2h>tYAHK`XwEN8dIrwVvA30svBG(LU& zEPR6>S-lUVmpiw|VJ4!E-v=SZtwKM;a9XqR)H>=fskg4DwyHL-qm=vXe~1!`-m+;~ zCr!3Sqm-w+Ec`4J{bgq7Ve$5{et|b&T@%DqZ`tF`L`>-md(eJLYCCxFWcD{fq@6Zv zO-=tRxxA#hyPB~j0A^XeKRjpoCA1GFLjk-&KJBQe_nc@WH z`qR}AHq;e8P3*gQJGy$jzTzvS*R0w_yO3;>AuFDCv}KXc5B58ylnrlbwzh%Rj4A>l5C`(6eyZoy2+(a~}G_^z(>F zrs37hQNmMA{;>6fa=Y6PPu-__~H8kq_cF}{lgZp za5_+V_l~1dJ)0!M+sWsT&~KiSreYPcmN{q@gTrEc7lNnpnG?u=?@ICsFWt1bRfK^@ zKW=J5Nl_-^tqznt0Cd7M$u@)7o@%+sBU1XQCSIh7<>TIZ$>;Ma;PXA%hmH}8M3Lj| ziG^J;#iE*>k;D9Tav@a43iFk1TK8p0!$XWJEf=mn&svww4;cnlq&+Rji&5#ZUxZbN zEKq#uE{lZ|ltGBLe(*LoLe^7@X-5FOsbTI(1d@C9FJK z<84+L?VUI2%~EaxmvEc-x|AUo)}-66A!GW%9HEvulP)CaQ&sxA^0iOOPuJ`0zwhfz zW1jjOC%@~Y$4Fg>Uf$5$qx+^%7Y=J@;sGI?iio+r7_RZ{4HLNQ*MDyuMr9{$D)9~g zfFc9{D1lda*fKggTiLssIjfktx?0&=xcq+3%wTL~f2wX{i?@j0!-3ABgQDYxidJ64 z)eK5JQjb3hZ70>#$$GLmeKzA^(ZWG8ZvEk|#(m;+W1i2Lw;WGfIZ;T&V@&Ous+gTj z&J*0StP)U<ZkHmDVM(c5jWH)lUaE6+s0+aYuu!h?Zx3Y?@~tE?{G z2|ktX{5kgU>LqG7jq)>`;_2)6&4If602P#C&{QR44=k#%%-D z1dJ?IuyKa5VbaVqpU9r3P&h=qE4-7dCIm4jRRgQL^Ck}OYkAc7UGN-LgJl5tjSxQv%b7_woPDga-% zxeVojY;h>O-VMDq4+_)h{b)W&sb_c!Mlu=4U?OCeqRwctr_^X@Ue&-@c5#UL8n&&6 z9jfFGa6M>@5h*cXZ<>pWzysY=bBt_*Y6~BdouVpFR$!KmO7o|-Dj36xm`_IqkzB#R zwkY3IQI#DZY*bT=vh)Tnz{v)SOAU$2s$s)owO}D z8!9eBvVWeP+2o~hu#Y|Cq$51?(0WFedJ{z+)|^%ynO?T$!^0)}J2fj|CG&X;vw{RT zsoi>Zv##}%W0?ga(gJ z`D#UoM}IYqoHnHPf(LsTxc2l`utgoX@1RLnFWT#Hi!JU~@0+hEKiz-2-){ayYrO8R zX2is-?x=TU7yLQBHr;7}cs6;1x3xFTMBhW>1@&<9H#yn;31!`J33! zrI6Z)QDImWMu=3*+fxDOo+3X7+G9broadXd5=0BMwm^woO^u7tUR$^GDQ;eQe6sUe zqz?IK>+hF@8;V~zO~#XvE1lD6pJXhzMBcD`YJDz8S|P7;xOzSd+I{{)xs25rXRwWs zC0}&#b>pkWW6m+QS7$-tD_9V0?zPxAi!;^q^Xb)F>9>&zmx$ZNbw7hF$9FP<)Q$Xz zvmTt-zMg~0)A-$tUt6r#7J3;7bU7;#*thZpns<^C0?ry<4><{LCj8o(2N&Dz_WQQh zd7e6RU%bDp-FD(0rl?AM&B#8cr`zl;wwpQmqUR^qvA zS4rsQ<>RvD-v6jvSP%c`BBS8$ei8R-dA74qB2tsY*j3-9k;~|=MwQ#Dkx(N>*ua@(fvBqf z;#jwx>SjZj>2;S@sv&9Dh>M7JT3-IRd^h`5K;7?VB}2n+qs5DAcyo(Ym#wy-+DKz~ zR-gB2Sn%Vyr@h2yx6h#%?lby2r_^-CwSD862x)K6lMceeduQn)L}5Y*0eGO?;LcEc zNMpqDfB)eAO>|rEALn9ML2j=B;5Sqt000313gpjCJPn-9Y+e4`%9G*ODNzA92vr^c zchTUkftK!+8T#S1 zXj5>Y>MVU#g>6oiohmxki%#Lp6PooME2O`2p$S)6{q_5sM;Dg-n z#m+F8CJ2$&HZ`eq2fU|}+r~KJs35xxJz6s=Hefq!Zb$t#VgD&2`|OR6i2-a;SL7UUIguc@Kl;DEGdhpyqGh*&o#aNVIATvNpwEDe3+w{kYdjbq zO!V+m3oTm%zbD5e2hPG=>P+(LHtoFg$B~X7UpK*BW5uh7TFm3i!NqgO8&4&{x2@h+ z{TTVf+gHzS{?jL|+d@G#1AE^G$8IeLPQUIdgP(=OgRg9r`ZI^Ef}`I)9~5s@D-a?& zy!hVd`XP*NKJqM{lbYCKt{l#Y!kFIe_?vxRTD*E50o{P>?av*qC_GkN?i2hRv^@_!K}X0@v;8BkSmcppoaB#wN6r_~Phzf+oG-EoBs>eG${(5daB|>s z6~Z*6^j09o>BsSeCeO)7KCqlJO}mYpZvxZBPF6|u;JX@ z+FR)(D4~(`h8M30^mx#yNpNw5$p{LTAqNY0#vPZFMan{sBEMc3w%KItjTdy zig($BQrCVB!6;yD3oU^cmGBxo^bV8yA3fs86v*hmvb=B~GK=jmL4^A*_*15gLCq)N ztGSmk*zi;IO1_(44eSC(!J5yL+`eI}023{Z3#A-n)vfqgk;5EKPO(cWM)uxSaMe-a z8?lgUsHF!B-(Yd8KQRpoGpHDfsK#vQ$1dx{|M|)|Uh)8Z{!`-)z1~VVvh(=EYu$J_ zolS}ekMRX5Ws#hN1MBV*gbzzA2tXr=3HeWD)aP(hU`|-8GR|4Bblwbfl#!<_i@3 zm?$aV!WgvbM3QMVIQ5y6mMEyGp!6^N%LO9VqA^>b65pJq4x-aUiUy4$>4-ZXlXmd& zpHP&|<7KM($NRt6A|==h6@bmUZeufxA$LGsW}Boznz6DV$dTpKZrY`W#rJtbs|qfo zrWG%-03YbA!g=T}h^qa5g?l6oTAUpg@q9lo!`mjxAjy-QlFkjQew@l{Z8t+QjUf|K z{5{ZLnf`Ta1%)ToDPect!{4rOv>;!jXYPyQzc8FL!ofG;we?`{j%Oe>4XU zVZh>@s3$YXgcWiQ@g_3vlj%FfExf+-?%EuzKXO-3@~d4x8@1Fyi=V@qeY40V3-_Uq z^H-6phy2ujOf1?a8by?0D!?!srnO4mvNiIIq9MLomUMNVkVKuOzP`bJ6|pR?2S*3U zH}I9dq-63c>ba%%P(#~Q3~OuBb47h!8x@tqIP)Of34vosN1Ra=-JrrOo=6?T6*y5> zVP_7a%tYN zxn49ChH6u|#`--ygKY}D(Ds4l#@{?;rL>;z)NAK0gk^8HBr)X#k2guPB$|_biV3$6THWt?Cg0}-n)SaY2eR6Px>4XaC%^;izjh4& zqjUaWZ5ysDKWRP4gw%!kh-iEsxu@7JU56LGFH}<;q94*F54S|4DNP;x{1MIT#3~*8 zVE)v1aLU(FN`(w;Q5sa_$|?QGbo=DGkG(D#AKpGT7?NtB#>dAhvfNXxM}&O9`rlRU6O0@vjV zRGngG=-(GkOA7zS<=HfE0H%y#Lv6EDYbM|whP`%}+k5jaR;nrH-mlK*AB_aqE-Ua#s-Q5*~5+cJs04cXr?VsEtQ{EXo@)O+iPtKjrMPQ zAi|z0W_z8vh}vK(PA-hb#7D)#-fXlzH?NCZudtvrBg2rY=3$OguR7=FDGf~SJmw4` zauFcr?S#$?`wOQaa$AfGQ$onGC$(3>19KrR;VKaAs%2%BUE7X?3gfg`dZ}A*Q@bm{ z`Q`h0&|{n>HDA_N;F{r~3!nGDF|Y&D!AnDw@FtGWnmF8@1?Uu=+E;L+iP+ji>EN{` z1-~~(-XrclBzqWQc}irZ5G!BzoP$mKKBhL@2lH&?05h$rh1U1&g>;J;bEn{f(7VHJ zdS39w2GqeSeQ50LJ#EeY(Kf9W&Tv-Ujo4V`*LD{a4cf8CXkN)b^N`Pj%ojaVrOP*WyEM@XJlc< z%%CVQ@w*0J9DSygf%Z%WcFDhsq2%=kz<(O)ug&v2N})eo$hHjtka7d|n;5I!!1i); zadoiMw6py)EB_tfcWV7ld!QWuA;$j+(f&K=-#LOmApw9KU^n_xs()e(e#iPf)BF>y z=;{vv{~_=E9pm>L^G}Ske`EYLjD6tcL2bD1H}c stC`)O5zX%?f1l+4io*2x7a{&V Date: Fri, 15 Mar 2024 09:50:08 +0800 Subject: [PATCH 3/5] Bug 60369: Adjust pattern to better handle non-ASCII characters in Month-names which can appear since Java 8 --- main/HSSF/Record/FormulaRecord.cs | 25 ++-- main/SS/UserModel/ExcelStyleDateFormatter.cs | 36 ++--- .../UserModel/TestExcelStyleDateFormatter.cs | 139 ++++++++++++++++++ 3 files changed, 169 insertions(+), 31 deletions(-) create mode 100644 testcases/main/SS/UserModel/TestExcelStyleDateFormatter.cs diff --git a/main/HSSF/Record/FormulaRecord.cs b/main/HSSF/Record/FormulaRecord.cs index e3eea4103..e1331fcd9 100644 --- a/main/HSSF/Record/FormulaRecord.cs +++ b/main/HSSF/Record/FormulaRecord.cs @@ -159,10 +159,7 @@ private static SpecialCachedValue Create(int code, int data) } public override String ToString() { - StringBuilder sb = new StringBuilder(64); - sb.Append(GetType().Name); - sb.Append('[').Append(FormatValue).Append(']'); - return sb.ToString(); + return GetType().Name + '[' + FormatValue + ']'; } public NPOI.SS.UserModel.CellType GetValueType() { @@ -248,25 +245,25 @@ public FormulaRecord() * @param in the RecordInputstream to Read the record from */ - public FormulaRecord(RecordInputStream in1):base(in1) + public FormulaRecord(RecordInputStream ris):base(ris) { - long valueLongBits = in1.ReadLong(); - field_5_options = in1.ReadShort(); + long valueLongBits = ris.ReadLong(); + field_5_options = ris.ReadShort(); specialCachedValue = SpecialCachedValue.Create(valueLongBits); if (specialCachedValue == null) { field_4_value = BitConverter.Int64BitsToDouble(valueLongBits); } - field_6_zero = in1.ReadInt(); - int field_7_expression_len = in1.ReadShort(); + field_6_zero = ris.ReadInt(); + int field_7_expression_len = ris.ReadShort(); - field_8_parsed_expr = NPOI.SS.Formula.Formula.Read(field_7_expression_len, in1,in1.Available()); + field_8_parsed_expr = NPOI.SS.Formula.Formula.Read(field_7_expression_len, ris, ris.Available()); } /** - * @return true if this {@link FormulaRecord} is followed by a - * {@link StringRecord} representing the cached text result of the formula - * evaluation. - */ + * @return true if this {@link FormulaRecord} is followed by a + * {@link StringRecord} representing the cached text result of the formula + * evaluation. + */ public bool HasCachedResultString { get diff --git a/main/SS/UserModel/ExcelStyleDateFormatter.cs b/main/SS/UserModel/ExcelStyleDateFormatter.cs index 6aa042936..0da43fb23 100644 --- a/main/SS/UserModel/ExcelStyleDateFormatter.cs +++ b/main/SS/UserModel/ExcelStyleDateFormatter.cs @@ -59,7 +59,7 @@ static ExcelStyleDateFormatter() //DataFormatter.SetExcelStyleRoundingMode(format4digits); } - private double dateToBeFormatted = 0.0; + private double dateToBeFormatted; public ExcelStyleDateFormatter() : base() @@ -73,16 +73,18 @@ public ExcelStyleDateFormatter(String pattern) } - //public ExcelStyleDateFormatter(String pattern, - // DateFormatSymbols formatSymbols) - //{ - // super(processFormatPattern(pattern), formatSymbols); - //} + public ExcelStyleDateFormatter(String pattern, + DateTimeFormatInfo formatSymbols) + : base(ProcessFormatPattern(pattern), formatSymbols) + { + + } - //public ExcelStyleDateFormatter(String pattern, Locale locale) - //{ - // super(processFormatPattern(pattern), locale); - //} + public ExcelStyleDateFormatter(String pattern, CultureInfo locale) + : base(ProcessFormatPattern(pattern), locale) + { + + } private static string DateTimeMatchEvaluator(Match match) { return match.Groups[1].Value; @@ -94,12 +96,12 @@ private static string DateTimeMatchEvaluator(Match match) private static String ProcessFormatPattern(String f) { String t = f.Replace("MMMMM", MMMMM_START_SYMBOL + "MMM" + MMMMM_TRUNCATE_SYMBOL); - t = Regex.Replace(t, "\\[H\\]", (H_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); - t = Regex.Replace(t, "\\[HH\\]", (HH_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); - t = Regex.Replace(t, "\\[m\\]", (M_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); - t = Regex.Replace(t, "\\[mm\\]", (MM_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); - t = Regex.Replace(t, "\\[s\\]", (S_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); - t = Regex.Replace(t, "\\[ss\\]", (SS_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); + t = Regex.Replace(t, "\\[H]", (H_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); + t = Regex.Replace(t, "\\[HH]", (HH_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); + t = Regex.Replace(t, "\\[m]", (M_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); + t = Regex.Replace(t, "\\[mm]", (MM_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); + t = Regex.Replace(t, "\\[s]", (S_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); + t = Regex.Replace(t, "\\[ss]", (SS_BRACKET_SYMBOL).ToString(), RegexOptions.IgnoreCase); t = t.Replace("s.000", "s.fff"); t = t.Replace("s.00", "s." + LL_BRACKET_SYMBOL); t = t.Replace("s.0", "s." + L_BRACKET_SYMBOL); @@ -142,7 +144,7 @@ public StringBuilder Format(DateTime date, StringBuilder paramStringBuilder, Cul // Now handle our special cases if (s.IndexOf(MMMMM_START_SYMBOL) != -1) { - Regex reg = new Regex(MMMMM_START_SYMBOL + "(\\w)\\w+" + MMMMM_TRUNCATE_SYMBOL, RegexOptions.IgnoreCase); + Regex reg = new Regex(MMMMM_START_SYMBOL + "(\\p{L}|\\p{P}|\\p{N})[\\p{L}|\\p{P}|\\p{N}]+" + MMMMM_TRUNCATE_SYMBOL, RegexOptions.IgnoreCase); Match m = reg.Match(s); if (m.Success) { diff --git a/testcases/main/SS/UserModel/TestExcelStyleDateFormatter.cs b/testcases/main/SS/UserModel/TestExcelStyleDateFormatter.cs new file mode 100644 index 000000000..63ac7eb87 --- /dev/null +++ b/testcases/main/SS/UserModel/TestExcelStyleDateFormatter.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestCases.SS.UserModel +{ + using NPOI.Util; + using NPOI.SS.UserModel; + using NUnit.Framework; + using System.Globalization; + using NPOI.SS.Util; + + [TestFixture] + public class TestExcelStyleDateFormatter + { + private static String EXCEL_DATE_FORMAT = "MMMMM"; + private static CultureInfo ROOT = CultureInfo.GetCultureInfo("en-US"); + /// + /// [Bug 60369] Month format 'MMMMM' issue with TEXT-formula and Java 8 + /// + [Test] + public void Test60369() + { + + // Setting up the locale to be tested together with a list of asserted unicode-formatted results and Put them in a map. + //Locale germanLocale = Locale.GERMAN; + CultureInfo germanLocale = CultureInfo.GetCultureInfo("de-DE"); + + //Locale russianLocale = new Locale("ru", "RU"); + CultureInfo russianLocale = CultureInfo.GetCultureInfo("ru-RU"); + + //Locale austrianLocale = new Locale("de", "AT"); + CultureInfo austrianLocale = CultureInfo.GetCultureInfo("de-AT"); + + //Locale englishLocale = Locale.UK; + CultureInfo englishLocale = CultureInfo.GetCultureInfo("en-GB"); + + //Locale frenchLocale = Locale.FRENCH; + CultureInfo frenchLocale = CultureInfo.GetCultureInfo("fr-FR"); + + //Locale chineseLocale = Locale.CHINESE; + CultureInfo chineseLocale = CultureInfo.GetCultureInfo("zh-Hans"); + + //Locale turkishLocale = new Locale("tr", "TR"); + CultureInfo turkishLocale = CultureInfo.GetCultureInfo("tr-TR"); + + //Locale hungarianLocale = new Locale("hu", "HU"); + CultureInfo hungarianLocale = CultureInfo.GetCultureInfo("hu-HU"); + + //Locale indianLocale = new Locale("en", "IN"); + CultureInfo indianLocale = CultureInfo.GetCultureInfo("en-IN"); + + //Locale indonesianLocale = new Locale("in", "ID"); + CultureInfo indonesianLocale = CultureInfo.GetCultureInfo("id-ID"); + + Dictionary testMap = new() + { + { chineseLocale, "123456789111"}, // "\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341\u5341\u5341"="一二三四五六七八九十十十" ,"123456789111" + { germanLocale, "JFMAMJJASOND" }, + { russianLocale, "\u044f\u0444\u043c\u0430\u043c\u0438\u0438\u0430\u0441\u043e\u043d\u0434" }, + { austrianLocale, "JFMAMJJASOND" }, + { englishLocale, "JFMAMJJASOND" }, + { frenchLocale, "jfmamjjasond" }, + { turkishLocale, "\u004f\u015e\u004d\u004e\u004d\u0048\u0054\u0041\u0045\u0045\u004b\u0041" }, + { hungarianLocale, "\u006a\u0066\u006d\u00e1\u006d\u006a\u006a\u0061\u0073\u006f\u006e\u0064" }, + { indianLocale, "JFMAMJJASOND" }, + { indonesianLocale, "JFMAMJJASOND" } + }; + String[] dates = { + "1980-01-12", "1995-02-11", "2045-03-10", "2016-04-09", "2017-05-08", + "1945-06-07", "1998-07-06", "2099-08-05", "1988-09-04", "2023-10-03", "1978-11-02", "1890-12-01" + }; + // We have to Set up dates as well. + List testDates = new(); + Array.ForEach(dates, (s) => testDates.Add(DateTime.Parse(s))); + + + // Let's iterate over the test Setup. + foreach (CultureInfo locale in testMap.Keys) + { + //System.err.Println("Locale: " + locale); + ExcelStyleDateFormatter formatter = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT, locale.DateTimeFormat); + for (int i = 0; i < 12; i++) + { + // Call the method to be tested! + String result = + formatter.Format(testDates[i], + new StringBuilder(), + locale).ToString(); + //new FieldPosition(java.text.DateFormat.MONTH_FIELD)).ToString(); + //System.err.Println(result + " - " + GetUnicode(result[0])); + Assert.AreEqual(GetUnicode(testMap[locale][i]), GetUnicode(result[0]), + "current culture:"+ locale.ToString() + ", date="+ testDates[i]); + } + } + } + + private String GetUnicode(char c) + { + return "\\u" + HexDump.ToHex(c | 0x10000).Substring(1); + } + + [Test] + public void TestConstruct() + { + Assert.IsNotNull(new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT, LocaleUtil.GetUserLocale())); + Assert.IsNotNull(new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT)); + } + + [Test] + public void TestWithLocale() + { + + CultureInfo before = LocaleUtil.GetUserLocale(); + try + { + LocaleUtil.SetUserLocale(CultureInfo.GetCultureInfo("de-DE")); + String dateStr = new ExcelStyleDateFormatter(EXCEL_DATE_FORMAT).Format( + new SimpleDateFormat("yyyy-MM-dd", ROOT).Parse("2016-03-26"), + CultureInfo.GetCultureInfo("de-DE")); + Assert.AreEqual("M", dateStr); + } + finally + { + LocaleUtil.SetUserLocale(before); + } + } + + [Test] + public void TestWithPattern() + { + String dateStr = new ExcelStyleDateFormatter("yyyy|" + EXCEL_DATE_FORMAT + "|").Format( + new SimpleDateFormat("yyyy-MM-dd", ROOT).Parse("2016-03-26"), ROOT); + Assert.AreEqual("2016|M|", dateStr); + } + } +} \ No newline at end of file From 7dd3dfd19fa37741793fe08b6f8baf7ce7964ecd Mon Sep 17 00:00:00 2001 From: Antony Liu Date: Fri, 15 Mar 2024 10:06:54 +0800 Subject: [PATCH 4/5] poi: Bug 60219: FormulaParser can't parse external references when sheet name is quoted --- main/POIFS/FileSystem/POIFSFileSystem.cs | 21 +++++-- main/SS/Formula/FormulaParser.cs | 43 +++++++------- .../main/HSSF/Model/TestFormulaParser.cs | 7 +-- testcases/main/HSSF/UserModel/TestBugs.cs | 56 ++++++++++--------- .../ooxml/SS/Formula/TestFormulaParser.cs | 1 - 5 files changed, 74 insertions(+), 54 deletions(-) diff --git a/main/POIFS/FileSystem/POIFSFileSystem.cs b/main/POIFS/FileSystem/POIFSFileSystem.cs index 32e251c2e..9068e027e 100644 --- a/main/POIFS/FileSystem/POIFSFileSystem.cs +++ b/main/POIFS/FileSystem/POIFSFileSystem.cs @@ -164,11 +164,22 @@ public static POIFSFileSystem Create(FileInfo file) // TODO Make this nicer! // Create a new empty POIFS in the file POIFSFileSystem tmp = new POIFSFileSystem(); - FileStream fout = file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite); - tmp.WriteFileSystem(fout); - fout.Close(); - tmp.Close(); - + try + { + FileStream fout = file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite); + try + { + tmp.WriteFileSystem(fout); + } + finally + { + fout.Close(); + } + } + finally + { + tmp.Close(); + } // Open it up again backed by the file return new POIFSFileSystem(file, false); } diff --git a/main/SS/Formula/FormulaParser.cs b/main/SS/Formula/FormulaParser.cs index 5b786c8c8..c8cc16dd4 100644 --- a/main/SS/Formula/FormulaParser.cs +++ b/main/SS/Formula/FormulaParser.cs @@ -81,7 +81,7 @@ public class FormulaParser * Tracks whether the run of whitespace preceeding "look" could be an * intersection operator. See GetChar. */ - private bool _inIntersection = false; + private bool _inIntersection; private IFormulaParsingWorkbook _book; private static SpreadsheetVersion _ssVersion; @@ -759,7 +759,7 @@ private ParseNode ParseStructuredReference(String tableName) GetChar(); } // parse column quantifier - String startColumnName = null; + String startColumnName; String endColumnName = null; int nColQuantifiers = 0; savePtr1 = _pointer; @@ -1386,13 +1386,22 @@ public bool IsCompatibleForArea(SimpleRangePart part2) public override String ToString() { - StringBuilder sb = new StringBuilder(64); - sb.Append(this.GetType().Name).Append(" ["); - sb.Append(_rep); - sb.Append("]"); - return sb.ToString(); + return this.GetType().Name + " [" + _rep + "]"; } } + + private String GetBookName() + { + StringBuilder sb = new StringBuilder(); + GetChar(); + while (look != ']') + { + sb.Append(look); + GetChar(); + } + GetChar(); + return sb.ToString(); + } /** * Note - caller should reset {@link #_pointer} upon null result * @return The sheet name as an identifier null if '!' is not found in the right place @@ -1403,15 +1412,7 @@ private SheetIdentifier ParseSheetName() String bookName; if (look == '[') { - StringBuilder sb = new StringBuilder(); - GetChar(); - while (look != ']') - { - sb.Append(look); - GetChar(); - } - GetChar(); - bookName = sb.ToString(); + bookName = GetBookName(); } else { @@ -1420,9 +1421,13 @@ private SheetIdentifier ParseSheetName() if (look == '\'') { - StringBuilder sb = new StringBuilder(); - Match('\''); + if (look == '[') + { + bookName = GetBookName(); + } + + StringBuilder sb = new StringBuilder(); bool done = look == '\''; while (!done) { @@ -1655,7 +1660,7 @@ private void AddName(String functionName) * Generates the variable Function ptg for the formula. * * For IF Formulas, Additional PTGs are Added To the Tokens - * @param name a {@link NamePtg} or {@link NameXPtg} or null + * @param name a {@link NamePtg} or {@link NameXPtg} or null * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this Function */ private ParseNode GetFunction(String name, Ptg namePtg, ParseNode[] args) diff --git a/testcases/main/HSSF/Model/TestFormulaParser.cs b/testcases/main/HSSF/Model/TestFormulaParser.cs index e7baadb60..6f73fb084 100644 --- a/testcases/main/HSSF/Model/TestFormulaParser.cs +++ b/testcases/main/HSSF/Model/TestFormulaParser.cs @@ -1483,8 +1483,7 @@ public void TestBackSlashInNames() } /** - * TODO - delete equiv Test: - * {@link BaseTestBugzillaIssues#test42448()} + * See the related/similar test: {@link BaseTestBugzillaIssues#test42448()} */ [Test] public void TestParseAbnormalSheetNamesAndRanges_bug42448() @@ -1537,11 +1536,11 @@ public void TestRangeFuncOperand_bug46951() [Test] public void TestUnionOfFullCollFullRowRef() { + ParseFormula("3:4"); Ptg[] ptgs; - ptgs = ParseFormula("3:4"); ptgs = ParseFormula("$Z:$AC"); ConfirmTokenClasses(ptgs, typeof(AreaPtg)); - ptgs = ParseFormula("B:B"); + ParseFormula("B:B"); ptgs = ParseFormula("$11:$13"); ConfirmTokenClasses(ptgs, typeof(AreaPtg)); diff --git a/testcases/main/HSSF/UserModel/TestBugs.cs b/testcases/main/HSSF/UserModel/TestBugs.cs index 7e07fe21b..60d7ab955 100644 --- a/testcases/main/HSSF/UserModel/TestBugs.cs +++ b/testcases/main/HSSF/UserModel/TestBugs.cs @@ -2274,16 +2274,16 @@ public void Test45777() } } /** - * Problems with formula references to - * sheets via URLs - */ + * Problems with formula references to + * sheets via URLs + */ [Test] - public void Test45970() + public void Bug45970() { - HSSFWorkbook wb = OpenSample("FormulaRefs.xls"); - Assert.AreEqual(3, wb.NumberOfSheets); + HSSFWorkbook wb1 = OpenSample("FormulaRefs.xls"); + Assert.AreEqual(3, wb1.NumberOfSheets); - ISheet s = wb.GetSheetAt(0); + ISheet s = wb1.GetSheetAt(0); IRow row; row = s.GetRow(0); @@ -2310,10 +2310,20 @@ public void Test45970() Assert.AreEqual("'[$http://gagravarr.org/FormulaRefs.xls]Sheet1'!B1", row.GetCell(1).CellFormula); Assert.AreEqual(112.0, row.GetCell(1).NumericCellValue); + // Link our new workbook + IWorkbook externalWb1 = new HSSFWorkbook(); + externalWb1.CreateSheet("Sheet1"); + wb1.LinkExternalWorkbook("$http://gagravarr.org/FormulaRefs2.xls", externalWb1); + // Change 4 row.GetCell(1).CellFormula = ("'[$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2"); row.GetCell(1).SetCellValue(123.0); + // Link our new workbook + IWorkbook externalWb2 = new HSSFWorkbook(); + externalWb2.CreateSheet("Sheet1"); + wb1.LinkExternalWorkbook("$http://example.com/FormulaRefs.xls", externalWb2); + // Add 5 row = s.CreateRow(5); row.CreateCell(1, CellType.Formula); @@ -2322,8 +2332,9 @@ public void Test45970() // Re-test - wb = WriteOutAndReadBack(wb); - s = wb.GetSheetAt(0); + HSSFWorkbook wb2 = WriteOutAndReadBack(wb1); + wb1.Close(); + s = wb2.GetSheetAt(0); row = s.GetRow(0); Assert.AreEqual(CellType.Numeric, row.GetCell(1).CellType); @@ -2344,25 +2355,20 @@ public void Test45970() Assert.AreEqual("[Formulas2.xls]Sheet1!B2", row.GetCell(1).CellFormula); Assert.AreEqual(112.0, row.GetCell(1).NumericCellValue); -#if !HIDE_UNREACHABLE_CODE - // TODO - Fix these so they work... - if (1 == 2) - { - row = s.GetRow(4); - Assert.AreEqual(CellType.Formula, row.GetCell(1).CellType); - Assert.AreEqual("'[\u0005$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2", row.GetCell(1).CellFormula); - Assert.AreEqual(123.0, row.GetCell(1).NumericCellValue); + row = s.GetRow(4); + Assert.AreEqual(CellType.Formula, row.GetCell(1).CellType); + Assert.AreEqual("'[$http://gagravarr.org/FormulaRefs2.xls]Sheet1'!B2", row.GetCell(1).CellFormula); + Assert.AreEqual(123.0, row.GetCell(1).NumericCellValue); - row = s.GetRow(5); - Assert.AreEqual(CellType.Formula, row.GetCell(1).CellType); - Assert.AreEqual("'[\u0005$http://example.com/FormulaRefs.xls]Sheet1'!B1", row.GetCell(1).CellFormula); - Assert.AreEqual(234.0, row.GetCell(1).NumericCellValue); - } -#endif + row = s.GetRow(5); + Assert.AreEqual(CellType.Formula, row.GetCell(1).CellType); + Assert.AreEqual("'[$http://example.com/FormulaRefs.xls]Sheet1'!B1", row.GetCell(1).CellFormula); + Assert.AreEqual(234.0, row.GetCell(1).NumericCellValue); + + wb2.Close(); } [Test] - public void Test47251() - { + public void Test47251() { // Firstly, try with one that triggers on InterfaceHdrRecord OpenSample("47251.xls"); diff --git a/testcases/ooxml/SS/Formula/TestFormulaParser.cs b/testcases/ooxml/SS/Formula/TestFormulaParser.cs index d4b548774..7cfd8a746 100644 --- a/testcases/ooxml/SS/Formula/TestFormulaParser.cs +++ b/testcases/ooxml/SS/Formula/TestFormulaParser.cs @@ -233,7 +233,6 @@ public void TestParseExternalReferencesWithUnquotedSheetName() } // bug 60219: FormulaParser can't parse external references when sheet name is quoted - [Ignore("bug 60219: FormulaParser can't parse external references when sheet name is quoted")] [Test] public void TestParseExternalReferencesWithQuotedSheetName() { From 8cf75f8278c6538887acf07252f652a625b90d7a Mon Sep 17 00:00:00 2001 From: Antony Liu Date: Sun, 8 Sep 2024 08:22:50 +0800 Subject: [PATCH 5/5] Use StringBuilder in ToString methods as before --- main/HSSF/Record/FormulaRecord.cs | 5 ++++- main/SS/Formula/FormulaParser.cs | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/main/HSSF/Record/FormulaRecord.cs b/main/HSSF/Record/FormulaRecord.cs index e1331fcd9..ba74708ef 100644 --- a/main/HSSF/Record/FormulaRecord.cs +++ b/main/HSSF/Record/FormulaRecord.cs @@ -159,7 +159,10 @@ private static SpecialCachedValue Create(int code, int data) } public override String ToString() { - return GetType().Name + '[' + FormatValue + ']'; + StringBuilder sb = new StringBuilder(64); + sb.Append(GetType().Name); + sb.Append('[').Append(FormatValue).Append(']'); + return sb.ToString(); } public NPOI.SS.UserModel.CellType GetValueType() { diff --git a/main/SS/Formula/FormulaParser.cs b/main/SS/Formula/FormulaParser.cs index c8cc16dd4..2467d4969 100644 --- a/main/SS/Formula/FormulaParser.cs +++ b/main/SS/Formula/FormulaParser.cs @@ -1386,7 +1386,11 @@ public bool IsCompatibleForArea(SimpleRangePart part2) public override String ToString() { - return this.GetType().Name + " [" + _rep + "]"; + StringBuilder sb = new StringBuilder(64); + sb.Append(this.GetType().Name).Append(" ["); + sb.Append(_rep); + sb.Append("]"); + return sb.ToString(); } }