From 124a8c9bb853bfc7199012d8e486ec5ccd507f04 Mon Sep 17 00:00:00 2001 From: Paul Kraft Date: Wed, 26 Jul 2023 17:42:49 +0200 Subject: [PATCH] Add Checksum protocol and simplify CRC verification --- .../UserInterfaceState.xcuserstate | Bin 52460 -> 56209 bytes Sources/CRC+Verify.swift | 45 ++++++------------ Sources/CRC.swift | 2 +- Sources/CRC32.swift | 1 - Sources/Checksum.swift | 14 ++++++ Sources/Hex.swift | 26 ++++++++++ 6 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 Sources/Checksum.swift create mode 100644 Sources/Hex.swift diff --git a/.swiftpm/xcode/package.xcworkspace/xcuserdata/pauljohanneskraft.xcuserdatad/UserInterfaceState.xcuserstate b/.swiftpm/xcode/package.xcworkspace/xcuserdata/pauljohanneskraft.xcuserdatad/UserInterfaceState.xcuserstate index da5a1ea623a98101c7a4112609934a9ebb66a4b6..7344f4648d75b6858fbfacc98c3dc1dd277dc351 100644 GIT binary patch literal 56209 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�~aoirp@lKB8{Wgvd**HFS0>|TkQ$36?i*Eoug zz+mfmgAcZkwkMI?YYThV@qtC+`<%pGM=4~N_|)+o2k|q<=Z-HNUpfvrzH)r+IOzDs z@h!toF#IILPci&7!_P4MEW^(+{5-=iF#KYZj7$L}1(muwJUwWEvsPJnpq zK@^<;qUd7yec5`~kxsGW=1KINX9!9BIKQW^)+#+c17=!+78X zjK=}SDICVB41a9H2$7zRVi8W`ABI0MAOHeifMSf@)APgy97PC-d{!@l3HEshQCuwg zEEG#QieGT3%1so%Y>y(fSE7nlqTfQXhNJk^(Ms7TSSP~b)h2P7xLjNzt`tubSBa;K ztHm?KGZ_Z2=^KVYL4L>Z_Y6Y_96Yd}7zPjQmnM;gQ9Rcgpv5&D#b0d{{|pb%1f4+f zIG}hnM-lA#-)t1G=P2GF-pD@;|IY9q);GYYdJ65{-Y9P7ID#$tSG~A};lDeG<1M23 z%+En_JIC=K7;nWp_#pjndm2+$*uw4=@3&~&0W=bPltOliN5tnijE{id+f(2#DgNd{i9y|hLOm6 z@jFJMI*8*>;;)u=`~`3%(VVQ`0Y?(k9>>cIlSZdo&uw_bFlSEWq$Zh8!pZD%l=5~7 z$r%k~I%TKgRGperceD+1FN+gHCXH?74If1TLL}80iz{(g_itBTr5{vz)_#N9RyR`qev!Gt$3f zJUT}@N1Hr4M{ynpz_{zo;iEMf*bYd~EE}n@&hZw61suZUqZP7?Om)uV6i#zacNRK} zoHLv=owJ;?opYRX8A)X%jgfRlG8oBZWH2K`7|CJ;E@oJhbAFh@MNY4CG1}!U-GoSHPcPgpw=TkcxtdJD`eIGA~$ z9i3~qc7=C39TFR|OI+vN#JRlQd4uyt=S|L=og19>&IV_rb0Z^T7=c>GF;c+Dct$2L zGLex?@bPcr_be+T*TyAT@l{SNCoM7-cFj&ADgpp~5&ETY?GFarA$r+r%$Z7SiS&Xde zAcON<3ps=HIfJKj28%g^s}I9qgpgrF=yO$A5SDWY&*Tsma|l--5yBeRN)DmlRqHy{ z6>tSzAy=JinQOTV3=FU#&SKR&co7Hxv{Bsdy2C>8c8=ouqZG1B+~?ZG zQQYCW-}Qj&LDxgBhg~~ekGLLnJ;umYj9ksgHH=)#$aRcd&&Umoz=hnz$jwcz$E`8h z^|Te`c0JEg+yE$=V{$_{%1t((K=C-B$lv_xdW(^I8^y!F`ql2`k6oW~2tQ$@vEBu- zo{b%Z@PO-}1>x5m!cD-_e|Qs#1pdqk+|q#(e@RYG;NPx)T>nZ)!V;0FBuEZP zWMms7O^n>a$gPZQXXG|UZfE2UM($+ft|rN4DMLxMl%eF|1m0~c!+ULI_`nGQk3E4> z91tjhKDsANpaidkIdarS>My~<>UwDaBlp!y5bW8}F#@GDDbplS%HRav&v`n!mmv+8 zVDS&wgwjczzy~`}B1f781WLJ5o|G?*k;Y2nqylNYG(iF<_+dtNGV%x`k1_%(aTgLsx4pYI@n%cPYSfh#zHFLWRTD4i*tWg*Bof-iNX$OY0BoWV8Hh0;aR#nL6xrP5{6 z<{8QH_gUPfMHWFI51Gx7!_Z#GHmt#MeoCd}XsoWZy3arj-E!H-Tb zcpMmP;taz0^tR35ZNQ*(J4)prM&5yZE&K}%LOUgibe{w>ZuQa*M&7HJ9$@7C4sy6t zdJLeF9^t;p2jH7XySQ)i;bD9e&+PEHFFhkYZ-Mw62XQ~>LTMK_B0p?rMA{`@mEPeT z?w0mQd!^T;ebVdF8`7K7ThiN%fcfw#BVay!&d3*xe8~s|ZoXpVYeo(>N$-X^{Lr!o zrB67A-`E^}Z`*^voZ#>{aQFk~@JB|zwK@C+IHadbzwr-$>Xg9p0R9am>ULlMBO^}Y zzl{7)FJnf2>==o%Lv{gGvdBsN2}qPBPU6ppAu)nJ6BZ`BAiKF=Q zkx-O7%SnKu+(qsxcayuzJ>)pKryMUQ$S`g9J0pKE@+TvIG4eMf|1k0|qli(=C~1;= zSt!c=~Ec?7^HpTwvThEYBRV3bFpRQ_Sq z!IN0Q7ofP?relme4p5ZGGU}|C3mA2E5XDLIR8G}Fc?t~9RN_=k2db#tj;e@^XOl)} zgr`w<*mCE{^DQdp0hLrgN_o4)V!4`ASt6IpKDkUTmn-B-d5OGKu42@~DCF#lWHgG= zXhvfgjb*eGqn#P;(j?bd#-bds25Na3r?P9mZL;$=6yuUc-6p36`G>>-YhR z`1U|zJ6)Z;L2k4tY~U0o9<7v(;Wqgmj$xC0i+roRUA|4eUA{xUQ@%^So6%m3_GYvX zqrg``M*A~5fYE`B4q`O9NxnCX;REu6@y%l#(JL)y`77x_{ChjaOp z{ImRv{Hy$%{JZ>z{HOev{5PX8B*4W1S*I{MiqX-G!ab71XfC69P4d4MmkLz`{?MP| zD6U(g`k)J(o%haH+s>H73lZ(gnCY;wvJQcqI{-R1z2+SFgZ}LJK;^ zq|#RzU@AzZKUa|BVZc=e@d0~6JE9`Q-;+jLM4~WVN`^ATRFukK4&>ycl(tKpq(B15 zCgo&hq;iTfN*S$WD>+K8lBeV|I+f9Bj812?kkKMWXD~XG(OHbnW^_)IGB(WP1k0aM zrf?qT+B_}{`!lrU1dYdm#s!?lg^bR#Y4ie(%3`I2e;A$5=mP5-^kjl(uHD;9lqyc; zQbvpGm1;&8b&$$a75=Qf65yKB3z|}?sH{;gR4!t)lF>Rw;R#mA{|1Q>+vRGtvaJRu z_#hkVki#9ov$R4Q!_u}%RC88Z1pV3np4KNyHG-MSvJttJP0D7Ti;a}mbgXP3`Y(gwdK)rFwkqQjklQ_GoHVMZq%DM-f18C@F@qHH{N4! zd@KgYtF@bFhw?DW*a*$@fbyX7kl8rP7+ucjijB%n9_5%~?v})p}4_qw>7+qM2{i`n@MC?-f%@|FD#Fkdih$eOO*r zX72D|rj*Ls3V)5yAG9R+>~eelhvoMDKbEt*;|=9)cy+t-rt%h}XEJIuDDNomGRhb| zi#L78FW~>RNlnB)YGLH@W^g_+Hx7Gnjk0%4D{wwnzT}$f3r5eWR{*nfjl2bLXHJG> zZdTLtyT`t)Z^9{)<$L7^kC36OOLgqFmJ+4Z=ll4GiJA`!hYjBkZ&EC z9Vn@&3_&L6x`1y^bKzo7Olt{~AQ@(rl>qq=$?(c~c+GyuH`5|}hWSsiC$V%{sMI`X zNI+cTtxASOX0>%8Utom!v%(LW(ZqkQRgULIn>)!{QVj`6hYzwd0;|z#7r3F-7&TVy zq=MgmHKW%sdM%^ZZB)Ce-PG=C4@R$N6x7{~jNZhl;yG;FCciGK4Dpui+-?WFp_wNk zJ>0G-wLD8Ov}anoQsKPYu)DCXx*9U^g$ePM^Bmg28D>JgS?PoGGcqz3dk&Z{ZBYBF z0~^(TYJYVAqc=0UkF@ng5vk6V~|@NtB&KtL@DGdoDv}@iy^^aFqD?|8YWb5h)#KS zFGwxRdt^>8FQ*cI74-`FYiIWgCyb9o_`D6Ko`f;cS8AdQ2kmxAMFGD*WZ>I9T@*Dc zx_giQ1JXvEbaK+j?1J$VCQd4xHG6(>I48ZPyFC$+kmDeHRaSy)NPv(X0;Rhc7!4W( zvToBkg>@w*K3}P?bZ<5_(7j9fgAImc&fTn3)R~&JH$8fqJJAEg> zIfW-;3@0L=QNU&7Ktk5N`oKZSDXGPtPL|x3dYj4Zdgz{37Z@99V5r~4uPl8?x5kXj z!G>hWhSHcdbeN$U8sub;GSg;rf&3zx3m1FhCl}@x@$F+Ey#{CvI~hf*Lps}s%qW-< zgtzH8@7fcqpEA0Bl%X5ZTy{==w}#w2!)Hp_Xi3};m)co ztMmb@otpO+t*rI6?C~IvxM%W|snZUZy}V75?}n+#Ni>NigUMvb!!n)BB8$mVvVyE4=RjtT zYas8&Mo5P75P6yGCZCWm$#>*O@*CBt$8sDA4m*$~;eW&b@c7sk(+*O{s}mM9_XgOE z-bUCo5tTs`@?W;XoUG138Jj_2PF1I=X=1nbC#LK2osAvwz>>bdH9>iOyg>KgSzGl9yB#_PskkZ5I(@ucx8qxUg-Kcf#a`Y@x9 zF!~rjk9m+Mdp=r#7OIyS@LGLFcN~wmV~;u9EAG|xmc$2+cP0k)T1(JF{~Kva)SE0} zJCEnsDG+| zsedyHae?<3eV@?}Hmd(>NW<#CjDE=IM~v==Kln99gBk}9(j+x!C3i{95LyHevo+Vx zH-ptY0}`Pf?%>W=9lp{T1#RmIpO+?SGK$@>fd~D#!`Pf?(j9S=$)>jL}c0L^$NO?onBJ z^&D{1tIe|pPOIRev%xU%mcP73SwUBC$`^Q|TWI{mjp@IDh_kf&eeWM%`tF^9l22`4vv8QvFj?@KJ zbnDS5caLpdgNN+lK3B)jh9*F8hBhIY7yeuW=H4Z}}r$Q&`l95p?TJtI#U z_5V=*D=43RQiD8VPi|g*hs*Wf`x=xRt2bt9@}7e69T5n}Pt+Ub5tC*^Pn+ku2b{DH zOYB$p6Vy-$H593>`)be3S<^bu=TLTzUN7&NH-ABgMfQL0TPRlSZIBnWmgu2-N=khl zkZE;tGEFf5NPFO(yFAmdu3Yl%=GcRFN~m$iEsqybX{L@qY3Qd6B$I-Xial?0Rvb@R?E*;BDrrE92yo^JhQMkGri?FQ}Gpo@ljLW5}>dXJ!n0(LU$bLnOxW&oM)aFk3RB{X{7n95DX=V%aoWy7sQNV z#LV%AN-DTbQRG_@GD{bg!LQe~leCkyk=iNRC>RGvYuV^Bv_Q+#^5=MKN-7{~SyMj8 ztg^@#sGd{JE8!l%+!|FmU_!>KdX_fZnow+RDYNP}P1&H$;WGHN<57;9Y9laTD+M1# zTc9n}inT?WS6i&XwCo>@{>kWHjDmUf52ODw0d3KIFps`VtI#U7CE%k77~B%Dnh6t} zOmJ}@g}WGG7h*b?e3m;O*hTm~uJ92lxn$v8*FB4xSLP4+n(F~GlUE+LKCQC6RmOP1r9aa7#H?DC zHYh%A^`Q7w8G|zh#iwTs%UHeIZmeb63U0M6X9BI)Rx&~0RvVXM2DpRSK`zBUc(ryW zL`bwVnBb__3?_(1Li0E_6-?3=N$EpDX2#(37D4A}FuQCETEhg%$g``xSi7{P+RK$OLj(Cw&h#FPk9)7CXOCNn476tz>ggkF6I4zlJ+_F3~J zQPDB6Gs9CPFjAQFMOIieCgfl0s~J=2t17iZ>E`VNu42Gf0?v$e2b*_1=rNzADst*V zAwQJiqgczp7&KfS1amHeA@1p{b?FK-BPrntpA81x)4fMr&%?#^?GSxKTzpG7zq6K@ zw83ydq27HCjfM7(i--FACDr#goQA_vY=@ppvE{ku2Lk>8RFa$mCtnOEfpr`xGH}(J zT^sX?H>Reg$N%S1pd?$WDdH_>+6dt`J9MAfs^-2Ug#Qx|I0B51=&~4}yv>VoB z?L%*%x6u3OOLTynf#@&nz?vEOx5EB?@DMy4pMpn&Ntg%5;8J`sUJEAR%ZHd>;Z@nT z`GpU3z!QE-dxj(YG!x?LwP%?CSzV4&ihIH@f+zg)e|o|~{FDf+ABwy7Klg+;m^OLj znO*;CaLEml)MAq>>S1hheGg0)#vI}tH%3N9bKe*|PWWz<=NG0@&2EeLm&J#`&WP`8 z{_GoH;SI*u_~Wa6)r)MPBG#Q;lTMCmzudh;G`?sEMR z@K-knuk4fhM*9>FFoX$NOc;8r_Lugz_K)^2O4YGWbgB!wLlNSNiLCtjvx9nmc(D%?%ea zLsRj2zA`TqpUS7YgZxt427sVB23STAUuXbpID-BfGpGeC$pYbaZ(W}|Y(|;!7ITIv zswHM)o{AO5Oscg`(+)wJ^XsK;WyAH^rj~t}&ud;r0oZRV!11V9ILW)BvKl6YVcrs; zg6Jn$PT@;xB`xNV^5(&CX_4Vpn&>MF75S%EmRE$rovU}!VXa5K-kAv_>h-QnIElA+ z1nA!8b~Hy56I(q_9oV4v)Z>`|eFck_?WGiYk`AvHZq$3}y>$o)gK2vT6Gk=a{ZL=*1G-4%PGY zd~4_H`Z&EnACKJn1bw1DNuR7w(WmOu978}G<@rnM_!<;@jnBfCOXOV#_h0iJH64~q zz?kNhtvlaE%KcL-a*+TV&5L&x#3? zKq?a^&o1}Cc~*Lf4$eq-=&Y7_faUjv>8%Vj=sxaO9rYMnb~!y=U&Mr|{7F4w za!X9c-d}~+@%_^wH{8j7eIVI zFx^{I?wjZX2i?OLT5(@JzXqbsPy{wvWhX+^q`5jR_8A^#@80fVayunlajaJ7B|I4$}$`nCFX`t?j$$b@1h09xLS`i=Tc&c*r$CM;$`IU_j? zGMXjK=BkyeuQ{f6HOC)I=~`1GJZ{mfQJXckEpCer8AUhhTlH;vlYR?>v}!^r6MRf4 z+Xw@BDyjurU?e;b(=%)ln2QYIZU^n@TW*fw)4j`0n+KGA*S34ZPP`e+fsv-oPP4c_ z&}uyml#gw5h*>-LJ?wMcp+CR}jQg2TQ4ddzootR5U_J!>Rp9^vzhe97NA$<|(coV# zsn;R$vGi!e%Ts)Kd0Kyl2~|w+w;Eoa*Iz!IzK0Z9`fesv^H@rak=NV@Nu$qfJ6^o5 z!)yB54^QvFc<~++YWa9^s*%^ybxEU*56v1ZjkzBdX6PR?0hV+(k9eQy2Vn+L|6Kn< z|587of2DuTgb)+zm;j0iq8uxjuyV8hjsC6v9en@5qduoGVHFcVgTf!Tanr1gg%V+n zb=HKkJ<40##(~8GW+ZF`yKRBBjW=?7=D>Me;ZLZnDK#hMdO&a0Rh9BSn_5>@HJ$6} zUkH-=S&`ak-=Zp4JsnXsA(XEeGAf7FEuXF{i%-5Loe1Cg1q_^?;$ zv27LDX=-=~y94?RAj&0a2No_z*0rb8&RoBgZBcyC?~$ApWSa3Mr71;&I+nQ)2m3llDCV`87mMR*9yLew4}Ql|RKy}`PmHHXR9Gq()uFtmCh##vL^Z*e7rHcMgc^oah}>E*k} zzhH51k{ zVf$e*br-se++FmA98;^~nQ$Ew)|ov&=`cM%*FCSL=dWb~#1z9uo89y998aTrvAe_# zN`5^Pu42M9Ej=GLfUZ1J&xZ}5tN&*`AJ)t6mF{!kkudjZ?p5y7-K*VaxX*MOZstDA z4J5*NcLRfDi~>Y2Z)O6FboESVU_v7kHa5A>g%JrB+PK$PPjI_0fk(oGO`y(Ttql{l zgrDFRPGsM*AWI2?GS03G!DI`Jt=(Jhf$(l_5RHLVuBNHjwcYOJu)KvEiB{ae4apPg z-OxFk4eJSR_sw9;AMpup_h$E22oSlqFkx%Gdm9tBai^$jp06t8wZvN{O0$Zy>DcZz zU!ix^*SbwGuP9L&*wYdP^{ggTm7QX*;Xgq7+ z|8(K|2cAfm#FuKAYub6Nwo~UWUAys!Xp$L)8@QnlwEJLt6Pv~UDen?t$7*THYi;I!C~t}ElLm}( z9GsUtIBn>VR=VroEzU<8WVd)U(;z-1&@d+vT0x;n3wD^o6S>azZ;KD`> z^Lt_-yc>W|G77@--AYu3LMT2y8pWe=$cI+IYJleLFl+&y%@=E36U_2l?xV8&dsAu>L<{?BEg%%l>o|Qf%ZAf}@*6^XwEJJhhl85DI=OpLmr47#=GB^`jCvE;Je(f+p zH+XQ`>OEt|jw?7^pdY%b^$9eL8{Zu7e{JHVp_8ZdojMKL*6vX2G+UQ2JwXW3w>_dg zJ6+ly&1m81<%YZv^lMQ5P%AmqOZZAbT@ov`ZT0QvECOFBJt;j8uebU@Iv{;7{UZG) z{UQA;V_A?zc-v5(JPqFMvP7aV`AYd}`C9n~`DVF6-Xw2@ zmvC%{*Kgb{-z&c;e<}a1$V!4zq?9RV!-J|jls(E`nU5&2@|zQ{Ks-->)E^1a9pB0q}UANg(M50O7b{u=pvBx-2X@TmN#qNrI>i=uo{HBqagjHt7s&WTzRby3tMQI|zs8MQHL zd(?wbyQB6-?TdON>aD1EqTY-8AnK#2kE1?~`aJ5NXcSGNg=jI_6)i`r(R#EeIx;#s zIyO2pdV2J-=xd@Mj@}&nMa<7Jf5iM1^G_^|b;LSjrP$7~-C}#irpIQ*4vQTTJ1RCi zHa9juwkXycTM@e?wkozJwk~#g?8?|xv8!V*jJ-Ja(%8$pq;(nDWmK2!F1g)ycYD9v zhu!vf`y}q1xV3Sc{%#oZcrTihLScg5WkcVFE7aSz7561O{UZ`{7PH{#xkdnfL_ zxDVn!iu*Y3)1IVfLeKo3*ANkuZ+JczA=7ld{g|b@ps1G9e;29j`*kJUxxbNKQyiNKY7(FfL(y!o-Bh2~!iMCln>j zOqiW8H(`Fl%7kkY9!_{aktFs@oS3*Y@xsI{iFYL4op^8Jj>N|jpG$lp@ukF95_c!= zO?*A^&BV78KTkZ6_;up9iQgywnB+<7k(8L!E2&S?z@+4))TH#J(MkD9lar<;Eles& z@+FlgRVCFV)g}d!Skk3QjY*r5wj^y!x+Q6Q((OriCf%KMZ_zTATmVl zOq{eFNEwJIAfnuLmF>Lh+Lq0$Yj^E&t!sSm_4>TNKRtiM`*|KfE+7w343Gdy0CK=4 zKq+7wpcCK#I03x?FTe*F1pERx0XPj90gM9f1D*h$0-gij0Nw%K13m&L1Lpx30ha)O z0Ot zfwDmY&_<9RR0FC7Z3S6DHc%gEFK9n#2y_T^95f6%4;lsC1U&&g1HAyf2E7IS10DyS z0-g^hgDK!Fa5k6$W`c9Ud0;M>2j+td!9`#ZSPYhcOTZh!3a}Ea0+)fy!8))3Yy?+< zH-l@ywcwNB)8Mn<3*Zs(DEK<~7WfYM9{3^n3HTZKCHM{aAMi);zu<3yV*@7yP7a(F zI3sX&;M~9kfr|o{1}+a=85kNE9vB%I9oQIX3A6_84%`#8B4}+;SWrYzR8Vcu&Y;$y z_Mnd7F~Ku}X9dp*o*P^etPR!&R|HoEKMwvU_(Slg;D19{Aw?mg5OIhkWF+LTkb5By zLLRM6Si5d5el1}wajkppzO@I|9$b4kba`k7{KV|Z2g=I|%s@54Wae-8f=L5yHVxs3TFwqE1Bp z9=$d?J~|;95si$tM!TXt(cWlZ%Jy%h)%u?_%G_ z&5etU%ZgLRwZ$EYdkC2bSp!Le;2;DD2||YCKzNV>ND-tMB7u}ZHbNAT3P=^?XGkri z9?}SLL-s)qL5@I%c8eRi8!5iRBa5H=xyc2GRcf)((9=I2N7JdVM2YwI!0RA`pIs7I3HDU~6JYqIt zKH^8jV#IR9O2irj5D|kwA!rB&f`!OKfG9!85j6-Cq8`zRXhv*9>_D_2 z+7KOxU5HM^A;j&(@ri)Mb%`4in-lvJFC@N5{E+xL@oVCD31!gm53&w zhf)ux9!nigJ(+qX^;+u9)Z3|dQ}1KPVrOFKV&`KQVt>M}z^=vuu+i99EE|yLt>~ZWc_7wIH>{;x2>?Q1F z>?ro#y1DD(*3s8#)^)BMUiT0;5w{8#j0?p@;G%E|I1CPp!{gF%8MsUw6-UGIa0R#` zTrp09E5X&{+HkvYoj5zL2j|9laX#D;+;QAR+$ioE?k4Up+{7?85 z_|0Z+n{@f3U(o{rDKv+!&@7th1<@fG;p_!IcYY17jp)3Va! zY34L<+HYwG(hj8^Njsf3k~W%lE$wF7pJ{i}?xwv=dz1E0+Q+ni)4mcG6F`IzLMS1E z5KDj%U<5cJjX)$Y2^>N`flm+;iU|@z2|-V&BXkn%gl>~^j4il~r zt`Tk!ZV_%1?h@`39ugiCo)VrDUZzh^4^AhhOVhWe?@Pa({*Cw(F`kGfrV!T=@k9!d zMa(1S6Zu2|QAjK%s)!n*j#xpgB5o$yi2cN0h0Xgs1z!V%Am5SdDMI= zpQ@&oQ*~4W)kv+T)=*8W)S6Oee z{-sTzO{Ptw&7jSu1<>Zv7SLAHfV4nb2rY~jK})CQ(DG=An6MhiGSLcWDo3k7-Y7FKDl6?`R)rpJ`vS$7IjXUYNZ&dujHv z?3LN8vjN$l?4azB?9gm{c2Ra+c3<{L_GkJsI-Jg=m(mUNO8RDc4ZWG(Mz_$d^xgD5 zbUWQg_tW>%_tOv357YmoKc&B-zoGv_|4jeN7{eIHn8TRMSit}=K#U+p7$cGq!-!*~ zFftj13?W0zkTNzhHZfET4MWGMU{o<$85V|>v751n(Zz5wTnrDRpE1DjGcGaS- zu;#NCvX-!xv7%V9EC?%}mB315C9%*f3=7M`vC>!q)@D{O>n!U{?!w%J+?-rh?)F@3 zZfCAN*OBYZ{VjKY?ojTb+#|WiaxdhLzE`vQcad8^=y#6WJN;Ja#eLz^-I(W^ZBFu^ZWD_I7p)yPa)i53+w{|Hj_W9%3J6 zA7vkB53^6P|6reGKh2w#7n(=P+nCpqHUBiWP6SxR2l8fSExT)NATs$|OOX8Bb8@P4ce(nhO zWB#&yR6ZwPm*1Xm&+pFf&3EVjl7A@wNdB?>6ZyaApUNN2zn*_9|4#nB{0F>oyji?? zydQasc*}Szd8>H&){eBseCSfJ-?7I%>^ zgnxy9jsGYA4*wqi0smdW*n$NGiwc$&EH7A904M+#1Q&!BL=;39tSd+>NG~82kPD~< zv;ulTPC;%#UIDj2TVN?TQgFX;N?~XrxlmfzQ0OZ37w#?GUpQ1aTzJ0lV&O>PmBOoq z*9#vN{$2RI@Kxd4!hZw-g5`oW0-zvJ5Gn{4LyH>C>Rlp3a$xm2yO}P2<{5*7mY1iQIuT7 zFRCf(D;gXQn!a?CL!V|(v!mGmT!dt?-!u!HU!Y9IyqKTr#qMt-7M5{$WQJ^S96efxk#fTsx zf`}v{izuQj5nYrcVu{!yu81e%iz-CBMJGg$i>DVy7H1X9i_OK};@^r76dx)+Qhd62 zr1(nl)#B^LH;ex)ep>vZ_;vBS;t$22#0$i$#b9xec&#{693zH^;6c>xj#6OEI;$7lB;x4gM>=O5hePX|OuXw-sf_OxHMSN9!U3^P?Tl|;!p7^2o zvH0%|lQ#f2;5LXhG;Hv1xW3_&WT7NRf{-Lhk|ik;q9j|ABVkGMBwPtk!k5S-3Q4J? zOrn+OB^F7Kq)+0L3`%~J9FQE89G0AyT$J3F+?PC*JdwPRypp_?{3D$pog)QG1EnF- zFlnSTMhcO_qzGw}G+9cQGNrlFJSkVYURod(NQF|dR3a^r)=S;ei_&)`3ri3s+!B3> zwd6p_iIS5gf0Udp87;X}a=BRPRjm}os->{ zJ(4|L%4f>g%5m~cd6t|m&yn-w z#d3+fL@t+al9$TW^3C!s@;Z5=+$`TF_sI{*kIRSUr{w447vv-IEAj{O$MVIa%S|7ZW0m8T6P1&dQHXw34KxDrriFlC9(_*DDK@3T3IXO1VX8QZ^{JDt9PbmF>!2>RvoU6Qpc#1)fsBOTA&uGH>gY0awYNL9mx=n3STh+VOHnl_DqjstL)cxuK^#%2-vUz2(WsEXi*`BhaWp~TIYo=&^ z(9G1#)-2Mj(yY+{HDFDUCPV|(Bxn*fC=EuFs^Mv*8ihuwQEPM>gQikbt=Xp8soAaZ zXa+QX&0fur=8)#7=D21=^Oxqm=9A`&=6m_L@`>eB%6}-ISw5$HUU^`7NO@>^czI-b zOnF>6v>aBBC`Xo~%Gu@R<-5y|l|RyR>~;pVqJ4tKF|1 z(jL+t(Vo*@)LzzJ)!xwF(tiGLVKDtaG?=4Xpj)I{s#~U8s|){6rct_NU8*ikN7RvZ z6kWbfqT8fX=`=c>u3A^4GwB+1O*)_MseYb*r9MO-rjOLe=plNTK1IJypQb13$$F}u zrq9t!^hW(oy-V-c59x>Xr}UTf*Y&sckM*zh@AO{{lMGW00fr@pWd@KT+z@3z8rB)o z3`7IjKsDqVI0l}fz))lm8T5v22B*PiIAAzrcxm`pF|A@w#o~(96~GE|MNUO-MNLI> z#kPtg73V5ODn=`=SKO|+Tk)Xck#VjOWyBjPMw&6tC@_kQrN%O&)@U$R8mo<4jXRBY z<6h%_<3ZyQ<8kBf#?!{L#tX&~<0In}<1^z6<7?wP;|Jqs<5%PN%CVKxD_2)0R1z!s zmFmjM%Jxcs<$=nhm5(c5RDPsk0jt8QBCBGmAXTs`cvV)Fw5qo1 zVAb)eGgarRu2$Wyx?A<2>T%W6s*hFQtH)JOte#Rmt2&^1e)YoY#ntF)X?1&bM|E$t zui9U|w|al|(dy&XzgM5GK2tqXeXIJxmUmk|)Q+j0Sv$XWX>DL_Y%R1lp*FD=Rg0;` z)>3P;YjbLIYdN*N+Jag^ZC$Oe_Lga~X|`#RX_X0JiZ;PbX{JmQ)5JD$O!+2>NoJCp zlqR)FW2!R!Y}#U~Gi^8RFtwWYn2wuH%F(#GIM zN~5-MSL1=ktBnsDKQ{i`_^oMd(}bqUP1BlYG|g_B+XQR^Hw8C^Hbpc=H^nu@HzhPB zHYGJtnhKiKO?6GXn>S_PZ)|RAwm1LU{Acsi=6B5>nm;#xHIFe*HBUFsG6$IFn}0Nino;H)v%*|qHkvEV z)#lx1kGbDGX#Ul_&wRjq)%=(F+t#sLC$t2#ENMw@!MAK|xz_Tq&??c#Pxdr7;zUD>W~*R*Tf>)QL;|7gEwnPFLO zL0Ymc>n(*Ap+#(wT4a_=OOs`*WrwBJVzF2)-4>_iu;r}ff@Q=qYPoK?X?bFKW_f9O zWBJGOp<_bF1avIxNa{%Mpmi`hSRHvC`5mH;4IL#N@(yK(s-vT0xZ`i@ z3~Q7%!t|wOzBlw$HV%utV($_C!0%jA5E3u2(rS7tHxw?*a z-ROGN_0=)PG2SuBG1c*dW4QzDSnCLPL^)y|Xa~+gaF86C4u*r}U^}=Do}BJ z95zS4W3OYsHh8<=bYf2<6P=o6YgX> zIZmC^nw)O1n zY3ssns z?poynxWKLmSF|h674L$(5?xpq*~N0nT?W?{SDmZTWp-_MSzWtbdt7#x!{v1S?t0*! z;$Gt63JbQihH-PP_|cfGsGz16+j-RoH^dv}jr2x) z-gn7&$9LEF!1u`aZeZ%b^nqCe0R!^~77i>KST?Y7V9fw%AYmYJAZY+SfEmCJ;0DqL z(g!jIG6$#wB?FBEg9D=j{|>Gk#0>HVD+aBD-GjY@o4nFoz^auEV^e^%+^{@1=_5=N3f1E$rzs`^Mr~5PgRDZUg;TQNz{5Af1 ff0uu+|FZwjeRuvx^W(<-FJ}$^Kh^&)_uczHJt1;i literal 52460 zcmeFa2Y3`k`1rpwvv=E%3q2&H6H>S|Y7mfA2sMy|4&g`+a->|iyU@`cMMM$o*p&oO z2{sga?_CiPvG<0(U<2X*&hBjz2q53@1K;QW{2s(ha=X)Z<}>rY^UmzNbLwlnfnY|) zZVqvnBOK4!I6EhB@|1*y9)G~=tDBnO_E%JS;ah1!&{sbt!8d2Vry>~W$e~pm%AFm? zm5lZ*@l@u70=>nFoK#j4bO${;x;u<_a|)+&-MH>tIM&n7UgBQnUgzH6c5=J8ceuUW2i%9;r`%`USKQa!cii{f&)hHEe(n$MAMOBm z7;%V4HY6b#IZy}G33Wz&kPD@ubd-TIQ5Ncp`l0@402+*PP%g?tg=hpCi^iczXfm3D zrlT3C9L+{<daX20);9fWpr{GMSh5O=uxIaD%55f7k02ktMcs!nmtFRZ($JMw7*Wx8|HX;!x2_xM|cM?NlNgPQbsU(l&lLAsm zMv#%Dh>Rkm$rv)0OdwOpR8mf6lPcmR^NF7X$Qp79SxeTDOUY&Aa&iT^l3YcuCfAV- zq>?QA#_sIL?1M(sHlzcPV;dA*sel$OZujD=aTz(#3#e4br zd^KOg*Yb6|pI^c+<#nF&7x5SKYxqm}wfxomdj2l{ZvGyA8-Fi5HM_NHxz?Je6*+b-K~ z+uOE1w)bqG+P=1ZWBb|mi|tq2Kehw*PWI0BF7~eWZuai>aC;AXggw&U(;jP2vM1Zq z?HTq#_H6rLd#*jtKHWaUKGQzSUT&XlciZRKE9{kakKJppw=c9WvY%_$?W^q<*&FRm z_Ko&U_RaQN?YG%)w{NjG+qc^9wm)Eh%>KCjdHW0YH|%fPzqWs4|JJ_G{+<1M`w#XX z?LXOnw*O+^Z$D`NS0Dl}sDdUqgswt2AzjE2GKDOmuh38EFANX{3WJ1fVW^NV6bOaF z7-6hXCQK403+2LWVX?48SSlr^ECE;b^72#FkHDQPFj<8qwNcdRzTKGozR`^BuRg^_VR7Fj6 zh#f?y7$$ZUJBgje?qamqOH35g#B?!3%oMZ5!Qw=*L@X7{#7W|0af&!qoF+~eXNa@K zd19656@6m8xL8~wE)~xc&llH-mx`B(SBY1PcZ>Ik+r)dt`^4?y{o(`SgW^Nt!{Q_2 z6XNsYtKw_oZt-n#kNA%GvG|Gjk9a^lDE=!R5)Vt9gd{8xiI;4WBsrxpshiYYijiWa zI4MO+mHJEB(qL(rbheZyd z)<_$rP10uRR_QkBc4>>$ENzwUknWVWNe@X6OOHrTNl!~JORq?;O0P+~rMIOYq#vc9 zq@Sf7L^JWei=C(ASBO1Vn*%C&NxyjWf$FO`?c%Vk|YPrg9DSY9VzC0{MCmp90ba+ADK z-X`BG-zRUE@0TBtACVuIpOT-IUyxsx-kJ8Kh(@XDda@ zC}p%VMj5M2R;DO3l-WwXvOw`G0VOC;P#ToQ$`WO{qARPEiKJm7kQKm0y&9l|#y5l~a*w zQ|+p%YHFC;QSGKit1)V<>Qd9xbTvcGRI}8+>e*_cTBMFu$EoAh617yFtIkuaRIfT; ztyXK)TD49MstxKgb-B7iJx5)sUaVfGUanrD-mKoDZcrQ5CUv8_NxetirrxXGr*2mt zQ6E(wQy*8KRi9H|QeReIQFo|ssk_y;)%Vp8)GyR8)vq+H5slYunq3n#QIj-TQ#4i6 zG>6tf>!NklBD7vwqSjkW(vr0lt)JFk8=wu;&eDcx!?iKmSglN(uFcS9Yn57+=GAJo zI?b;IG+nzuyGXlOTc=&2U8P;EHEK=TMs1U}S=*-FtKFw<*Y4LI)gIHH)?U?K(_Yu! z(e`TZY9DK#XkTc*Yx}i7v_G}Kw7<1~v;z*C!|o6qqC<5=I^rG44woa%k>%*?80a|5 zakgW)Bgc{J$a9QvjCPE7OmUPuJPxm8zN60Ja|9fV9G5ySb6oDY!f~bJD#z81^^R*C z*E+6q+~nBgXm)IM+~?Ttc+By*%?`PJgy|I+Os4u4St98 zp-Bl9HSR#5i3{U8>R2aDTxYHeND{I@_mn$37v&dB_W7#=_3jE!zOSO8)>9WOcP8{N z>^G<&Gpo>*TTqbe>Q~S|-<6x6o8uZVAZI{s-;At`ti1kK&ONw9E^8|n!9{XCxhO80 zi{WCqI4+(`;Cksc-L4C|s7t!6E4r#{xFCM zB$|?;lnke&n35VwYV{?Q_$aB@tD(5LeviAl-si0g268Hb-i4sfRhBz@)b(5FUy@7W88sYp0BpP#sirYGp#cagy?3pTz3GJOI8GLaLGhZz0VKT*1@X5$=(|a}4JSxvb4x4wuX2ars<<-cj$Qch7169zOB9_Ono^wxMvmOu^Hw#}vYi6W2j&9iFYKgthJRSIoeT;r}YpUkSP z60VNRy4%@g0s=M@bJyY+i_tyvN+4@=fQ2lH@N6*s>^bvZIKAL6a zRdX0X* ze!YIL{*wNQzMmqQqG*cxQ#6VqH$@E;T|&_<6x~PBixho8(N7d(ilLcZ6z5YsmEt?zzEqtKtLc6B@h~)wy1OWqP6CUF%uIMw9dke}yZs$O{3@)(oWQP0UL( zuI%Kl;I8DZ;;x=%j!bnBX^Q!$Cr~!71YmB0+v}%{D;aN0>Dm_hdZU1m<<2FitbhPT zh*hJIeY4W)TduS%J=`$L-?lin7{!SycTPHW#c@|uyXSe@=e5bmE2i8z>y+ii`h@Y& zgN(o0=efnmGp^h@7;iOQjCzcN}(} zF*5B_?wo$gGHp|*gWA{Ti$;cNrwP_$b^q6l95YT!z4pyIPQAWmWSVt4>a`FC{r2^` z$H=f>xpUzuYsjO<+(E|~a@&{XeWNS`%AHeBSy@bykNxPM7}*Uvm1AxjhFfJ~+s^u> zk>}uYXYna}#4$yA1>;Hz+UBy)$YscBK{s>2anSwA$aGk_bI~b#w4+EmuJmq?((guL zhL=0%owCB1D1oMv=dP(}0FBD$KTb{jZDgK%D#ctIuu6jdhKgYOM?PfanqTgmbIKms z%5{v-SKUxw>Yj6q5d;w<-@?s~L4g-B5QFj(VU76p4DGC={)a)5q(@ z`UHKVUZR)kW%?w2ax;oWaa?Z{hkBtz#C|7pz4a;jOt1sY)Mx2)^?C5S3ckVgw1-*y zZ0>2!;L-xd)YzD+N4CFNCE`H1~MRg0=Y`n$; zQ~CC(z%;?v5G+^>Rspsm1!3abr&8hf)zla!i8SBbxiH^9R!V_3p=!K!P@ZEyQcgp# z%IAlS+TUig_d;JyrMGV0v1)6P-(5cjQV#57)*>_zWjCTh`c!>}`TZ=Ey$KCLL)k~4 zrcXCMGo0O>9gOK3%0~q-U1VmAB~2)wTQ7zt&}bwY#dU2&MS6K78m-S}HYKpe)CApT zD~&m_imX`U(L}Cm6Dmd%bhkdI36-Eyy+W_lJ=59K7u8jI7JCA-Dns_DF`l}4!78($ zQ&IK?eMXpCW|nIvnl)owNxl~hF}^yt9||{g){zhmRK3iK^~T21*+7&`usK- zmd%AaYo8TNQBe)5Eq8VrS2DIC$cDAnOg6$T$i_(K(_M*$Q>4QL@+gchSE zdaYik`}BH!f$rA>dQflB7dE41Ksx((F4DPl_cN4lDZPCxs&(%Fg0UajHG?~83U^?DpmTSrVUUa|7>~>)Gye6~--43ao(=HvW zw2z_}7>AFc$I%n$N%RzY8a;!aMbDw<^_BVs`YQcGeYJj(ezCqrzeHc#j9v_lzOSO! z3=ZD}4%Y#DZ1lZCzsBJ3+A|!U1`a=D9Dbx_(UxCD{8HxK*iM}2N+IA$OJL8}H+2qg4@gO>E(su~x zyN->R`yuA~c5y@Du?;(cK5WMV7O{k7tY8&u*nvCfH|RI&H|aO)x9A)6M!iYjsBdb< zVJ3aJi%B022l_UL=-V2i@18UCoqGCkZ=eq+>9>aH!>K?Y?t@)84X5k3>9^}!^k#jA zQ*rXn2&c_z-vM|K5QqorcQoQ`{mzpk5D&$}8AZkTY!LK!0Yx|$D7w2HMPa4Otc*rr z&?rDu<01fW+wr4V;fwKf2Hpfb5tranT!ts%$#@E$il^!K>D%@D^#}9^^@sF_^+)ta z^~aj=j1YLUL*P{cc#ns`dpZQ(3unMP4dD41cme$h3%rF4yhV61`{+;VPZ^&XPR;4J z+V)&b8Fae-Od~!|fA%DyTZJz&p<4~mJ;w-I1JFI+9y;{AmCpONB=TIJ%yiUAN_58kMWt|jCN*QZTk{_ zg+ceSzPAy-s=s@Z(7lOw0zr5O$lCWn*5X|tYu`VXtnKh}{MjK{>lCa!-^U-B{Cx=g zea!gV1##bRhpZL;3;Yw~?@Rm@{u+OSzs39Tcldk!1O8F}RR2u>T>nD zR^Qi*e-82YduY)63;6pk#NUshLGQOS{GEFKh#mMNg8qGoKOzHvMB&oeNB;qoZ1$Pq zj1RRe=}0;QeWa8AQzPl3|9o=vk#G`e40$91hP+>Z9})%p{MwG6FxyNkqj-{NAV+!u za=#xxiWR;O83@P`7fB=OB!gsk^Q7IqUEb|pBSeJH|uv+)DK zBUbxPBQqFy(<$N`$xMoDCyAb$RGR2j=&%vN&On;0S5PFhhY#OxWmZk1off&JIN11TCrQ8q<`DLRXyAruXzXc$FjH}fI;3*W_r zkq7$=MZ+x^^DG!go`Lby!^kre3=e}sP6$Sx*;!MJI@4#Td&^ zVJME{$MePf1b!l4!k6-8{3L!dMWZPiL(y1@#!&=X3G|5x6iuY8OO!VAQ_XRapUKbS z%TXM>n*}JAStw4S2(*z|I{YX<1LJ9c(Z^t{r)ZJ|V*p^}gJ>xGP&8Qwl@NXaik+>t zUdFFrC@!aHY9kK{*tC;G@jU(l6UCJb#p#Ty3mJ+t+M{?`N&N6k(Y zj8QrJ1o5pH*YHh@%4_-S`0M!__#63~_?!7#_zip`MRO>Eyeld4P&AjKc@$Mq1nJJF zsJfZo7^3nvQ*Gp7(>g^p7L|3D+88*)}RUh(a3=6xwX~DfXf0JpFCs2aJpqm9}n-Qz^)soo4KhbY+Ym z7j1R6C5%9yt=_i4=C=iGL0f}up>2^3hQkdMfrM_NXd^|NC;~IUtrXox(d`s%X|^pj zHqgY`&Iu8C9wV?B2!wwW-C+^9?F@mZfxyccfiNm;wFtcGgaqDTyNMBaBSm*M+HR)k zu9GCN$+nphxRDWfHyaUeMO!Gk=NKDloba-Pv0=w{hwW~Y!MhlP_rjhT+pYS!EY{Im z9;_Jm+n!@EdlA`St-A~a26g^1MLliws5ojcjQuG)_ zk2l+%4vm7(hZuaBG5CZv3O;2q`1~0LPXmMRFb4Nh^rXe$`zK`ZGus!8!Otmry3zI} zMbDfhgWuX<+f9>gA7k)Y#^4WZ6nyR&qhJ`HWg+#O?GF>e{S3kvm?-{%iQ?yu3*kY# zz##nBcF15L7KHDef$-ErXpaI2?a>tN3PEU(0|;@NJ%N367_4@iKV~?)h1jsC*!uv8 z_Ed`YG}>Jhy>oIP+B5C_7*oaezHFkh7nrgSU`)a4^wGNte>h-ec9wmZ0it~<1M&S6 zM6zP!+s6Zl_5ypMeT03ay~sYwKH5IUKGqI)n-3}ah$66{enQcw6n#b!bSJQ!LU;PA z*FaqzS=zvAwJtrjaLHomuKv1gwZM1_@b?77se8T>;N#IkAz{CGN z$FRR>hs`{&o6!C;5QyRUtK(XDtTAwh{e4E@TlSsyUH0Afx9xlE@7VX+-?hI-F`<~J z*haCPVu50jVu@mzVufP0+5SOj4E!WS;1@t3)IYZ!SAn;d4;BOQ=ECT-k z0_}ft>Fh&c7xEJ02iR(?lQQgw1ddU7nBuTT0a4uXs=wj1w7*DaVD;Ez~d==Li)-rQi|f3iE_2 z!7I!cswqyRu%!rRP@G9|7R7xj?niNdiU&|Uuvw@L!MH&13jq`-G%y$kSujFHL8at? z)dn_(pVB74yV=5e7vc#q|^~px94wfZ`y<4HPe=coD^m zo5c|!97mg~qd1=7$X-Z>mqICCVX2PiouTnG&^VLP2t&kDi$*ulD9#Zp*oWd}6fZY_ z!pIowoMyH5e6fa637XhBjbbgu@TT#}yo4_<5Q8R_0Y;_HxLU}lr0uB`KC&`fCZ1!$ zxPrlW{s|&kF;B{1>!1-FQE9sCULcR5ykNTEk_(kC$3{>RZzUD-03-GXLcNQ zJPaII(R#RBo8xfAE6u!DpUU$>j>^03sU23`tQTQ-(pK>r@mldZ@p|zF@ka3`@n-QB zaf8@M@x>Icq4*Mt*HXNW;!7z8o$PXoK_|PC;;Xibutkae6K_MhxP`sLE#ATU>(!Qa zeT}YDd?QFw=)3<9uEs~TKW)QX>6zp9r!DeU2CM%6aL|UxUOy8bqjW?z1j_2uh9cNTXt-5Zwsk6s@jqvD5GZZKqwh2dTi zv@0fI-ea8_mhO)m+luk2_yYs?Gx2lr3-L?wEAeab8}VClpZJ~lJ;fU+27H?+-bnE# ziZ@eyE5)}_d^^QkC~n>={umN7zk>SR+W_}Z5$GPtabl1oaHV4m>+#Sc;Z$VMqs%98q0483#*#a|yGl%zqXV0f@R4Bxoe zwV0i<9yV2uIJ(Yk;GM zhMFhZwhmomLO0Tk)Dn#|MqP8Qqf}k>kV;@^`XpZsoXs3a_l%n~wjjOKQwt{!!+AI9 zMr!H#aKPk3Pi4M4=x#lF)m2r!#8X`hhw!?q{Z$q7D&{X*P#>(GUsttgPF=cj$WB@v z9Hk70?WE^6cxx)ti~aCq;6nq_gF}jYWo4x2)Pp0A3gblNfSFgCyS_f%I8PZ)QigyF zJvF|1k3SuxU2v|?UmHjt>#i7IGKC3R<3gJ-W4v>WLbo0i8+zO-kGs<2|9|RP8v_3H z8td^HtS zZf{*+XoatqRXZH5RvAodxt?aUedy@xHp+}N)MWNyVD{qUG3yOfv_%!Zo*@({K11mL z38A?rp^yI8s9FTaw$FnDsN15-Mpf(j8D`HgdwNGzV_%_EAQgi_MJkj=NF${pX_Pct z8Y7LB#!2HTew^YbD1MT{j&S@m#m`XuEXB`J{5-`kG)ogqO;;*24b9S2HbHyQ(sN(7 z49#zxF{qq+gNihd>9AE4zhvpK)u6*-7nhFV$Tv9XXbBv21ZHMSJ@iXp5NVVG6u;6a zfmQ6)lhj_9NXwb_x|C_JuQBa)1=C(%KZf?&k+VI}lHK{zDr43qUBL9$H<|vrg6XfX zA6I|9M7oAyxK>&xT`FBBT`pZAT`659T`jGr_$`WeQoM`e-4wq~@g9obp?ELF?^66; zvvh3;!y9q4bTf*RHZTm|w=n!z|A68zn3dqmGaQ}<4&i{mM(J*fKd?Bwm(8W_leSCu z!8^J5LyA9wpK#{pj4(dN8D{bLsPs7F5#}YIG)geWe0q{RJ|jKPz$%uWW5$5b7+5bd zus&}GR!5G1MGNDt?TOOsl3_-ukltiSeszMFRvGt5pE4xhk@iaOO7BVUOCLxdN*_rd zOP^5u4aMJ5ypQ7VC0Oz|(x(q|zgze0)9H-O|mhUBjnl7H&3_HmFQ z`R^GdPXm&FF(m({_%{p5gAB=kr9;xcGDq?66z?~F{sByCDbB9Ws8EZ`b{TfRG|FHa z_^VNtDE|B8sFXF?X;3M5U{wACMkcudoU^wogk(a zBUVlTo3k7z$5X;lf}7-Cav~+*^~iq2^j=Oi6j6f8omtjQsm3=C9G?{QFUZU;?AOnuuyMj2cui6@R`n0MqHXn#4E5=o!&HrGKekPGDz@<_ReTZ;IH=fLADnKT%nQC+rWyu>V$jMdQFTtFgis>ylE=%%knRNd zHxYa=jVm$i4J?>>nlGf<=Gr88O@qgYC{c`KedSWQ47}2`L}`*IaqHV&Fhfm|r5n@#Ag?`YOOp6?koO1)&OEUpx>3?YubyF^vJL*P-0W29 zuGUvD0L}HzYw(+vA@HGP-6#QvR$vATOa%8=vnq}VWrDYYfp-oi-Sru70U(r;aI-bf zmsd_2S27MO+vMBjEtDis(u)!p276PIv{~LN-yz>A z-zDEoNirp=l=Pv*MM;`oT>_*+pM{@;Vv@kF7jlo3T<+`$*ZO81<6`E3qb`QEcz|*h zn;wmJ$`3+=J|sWP{7$jaB|hi*ejAn-zrBN!6tm$Tl^+8Hz>4WQUVuu$ZyFzGVwR?>&^M}~Xj(6Qv; z>j4tmD1Rt_Z1~JFzgzizX5^9_$|VzW$;i$els}+vUiKg(7jJ!)ug>EOm^pZ?cwhc6 z<9+i#jAzlhPlolRCiy%0drGn?8QdiQDE~wW$h0A>>QDXw{-;%H(Db_n&Qo2UX#wX? z^Wui(uRrx~8*u)S4>I-V042j3Ww-&m+h#(~90wMEv+7yz2|bpA6_x9{MIj2W*c7`W zD54@MvZ7FuLkURVJWBE@DWIf~k`a`Qq@-vI*IRL*IK`=iDIJwgN@uRO?xbWCsKR74 zC1WTVOUXD&#)DeyndS`?)OhDH4+Ss=oAzWd$$Kk2&}|LtJB-C!{?p8O%z!>^th=HX z+&g6Vv2-V;x6%hXw34JGD=7+$W)moxNJ$ALrJEF&lBT39(7($lnMBECN~SQXnCft( z3&&D#kkw@Ob~nI-7jyA&tXt#jnePFp&y04lLf#|cc1c5REiBiB2=UBgo*)Bd#;VKY z%zgz~Sy^+O`wRi83|5A1RL)X{C_^ckO35rrK=T04eTLjthAa6Xx0M_vR{?mYQ8=%U z%-AUMN}&Slan%$~?jvRF;h4BM^5Kriyx8yc`3)bFsV5GY3!`_5r``>s-sgv&c;e7z z9)>zMA;v26IA!87%8Z+pQl$(m4+NB~*?M&a7t;%KF*}v1TnA;EGM$NuN?6buAI2+l zEO+n-6W(SQ{`YR+MXA*9^98{Nyfa);J9UoinVga__^cuELvxBojUF?$Wb%|5v@sSBcR*Si7EX>7GFhiHjh?u;2% zl2^*E7lJ+vqlTp&wh7YR3Q|^77J&89mRmc!I))8zJRAJQc4m3!7DP1VQ>6kQL4{hR0%!HJJ;(0R=c&_EnQOYX}#m*oc5jL#uraGmIuls-H8-W zgeEcFP(qB-vRN(eKn!0f8%rlmgtj*R2BB;|E30(lQ6R?DX~sl{RY7aLH%*5r5lnxM zyb7Ub&I+;7G;<<+o$ZF9w+(HTCWlRPAo?+`b0YZo?ZG90W8ExnAXmhV;U;h;;BK^m zTMmvyFX67^Zs2a>ZsE3Y_izt!&vMUmFLEz)uX3+*ySY!fZ@6E$Lr6kS@Z1y0eDMj0$qi!Mc1Pn(amTBdH}tPen)?!1L$9L7|#Ef;N*V| zJ8?(c8F$6~@HkuyN3&1Hb8s~r^}P(Q#24Xf;neI+_yPPVegnUSzku_Lf5yMzzlcVh z=H^F?LYp8fLcc@5msA;rE0jtl zPnoNL;swKI1tpa*a#G@d+QJ|z$WCbM2j;BWY&iVdf6Cm#10VE-8i ziUomspExBJs3f?AiJ|`pSqeI|5i)+bXjYG*8!HP<#bui>bqUNAlE!t^NsDbg~~AFDu^ia z!Ww1RhL$huQ1;!<4qPc$4UTo0L)}_%tviXU1Q)wg!Nu-maIouv0dxeo&}FW3N9(=8 zp>DR`OOFR)C`|Hl-od;x|=CZYzG`!3ip^QwT!hV6Y-`~W$;;+>-HA~48O}Yo>?t7j9m(* zAZ;6RvfBze*&D1X0p+{K18I~ylUPj4m$n(B944wTi-fHjprIK~pctCqZOUT6(-Hxa zV7n@qwF&FIK@`5Bpg3$h0EcV!LC>hJ0|C?nsMou6Ik z>YJ6FTQFcyPF8+ja90_=Y*}X3po~5-87un4g#OIzm)U>C3RC(%qD%*=d+2DXn>r-{ z++{I6XljDnUr_~HPW+__L0|opgpjlGjvQLG!I+)EOceZMhXQ@<>?lgIqM8D=Q|B&S zyLAum5fRxlDmp4Q)|7zBy;Gn&o7HC2JdCR$bu0|3(Y#?+riV#H)@*)gGYD41=DpDE z%ZiHfVYn^|jD=kj<_PQc2f*uhpxy_&T$n_FKy|h5I*>CVm)b^FSzuerV_wpkY=ys# zUNzPoU}}_=^;jbo)7x5Ifwzhj$gQQ2rq3%-2*X=0K@mVOj_}lhw=vVZIQW$^AE^a^ zqI~nIM)>QE$AAYcs$2}c)C@PSp>~eP5BdfV0$a0hOpbz2xnMA-f5to{Sw68lyL4>ov^&)EeWWBcLb;sV?vaEv{d3vw|r zow*qBJU$UVX|2~mVzs5#e5PWUJHS=T3fId2uKu803?2e)d$bxAa%bO|txJt(fj9ZE zUBk{EI6MbDDS{$V0`m(`omu~7Wkva>yflPm+gnUYG2PKajSR{hkl8<@f2M0d_CTnX zfw}pvK?OOvuDtw=?7aT{`ary$?Kmzl;?-3rCDBI+o@DP1QD+rjessbcfwz z#ts}ezIX8is9UQ+&0@BV5gKr!jttSBo$w_1 zPaKY;@fhp|1!5_NedG8laJq35INWH&8}Vj*2YwNMfIq^Y;LnIex{?Tz2we4qb$asE%B`9{#E&tSr~p(epmJ@e^9cPl690^ zO37uLl)sd}m4B4KD7l=HD=4`V{$S78xzJk!mJCDk=PqHU5s*|+HfHW^NuOPYZdnEv z^X>EGs%Polv<{tP-y4h7HX4%(R*#(k<};D`0rA!V0Pc)+<${QFnVPT0f?J71X+Q(WU^61Cp%34kaxgc*hN-O2j#VYaX%6^40LbyK}TPpwgE z;1mRGFbC$z0kCs3Eq7MH@OoM73jof(x|!AzLJ`CX-0kdP*E)6y?-?84JH?ebVDPZv zc?CsdCzMW^F}rdnNIg|KgJe6YO`VmgEw<~Ops1X58mp$Wg7t`Ok|W9(g8`>)C(Q9rI{xa5mqPrw z$fnK_JHaS$((zVJZ-977VH@R$)<^UUuzT!H0(_z6qjhAmr-Q+tCzRpZqJwU-L(k~dOv6D6>m zdJDWEr6#K>YAU=6PQaYdNJ$gRp=(I)K=Dc{;I)IiDxWXF6q-mTTngNQC8fTiIuIuy zUM8@@7_++RM!A?VoLTTY8sADlUjj3sxs}44hUB_~6;({NDD^B38nH{~!nZwYKefL) zKpm(K0&$qF4n~FCT6L&8Y^uAi0=zLpS*99EmU{fPQ)^iwdG3H`8hZz%(kSIL$l5Sqhs%t99x~SaqAQ*o1AAI{K)`F&_ouH>qP7S!~MH@~ka4kGkGk2X(MMXeM2( zPB7QEkBogpRW_*;SsrW^`~;zjEdpnmSzto7`4P?x5sOO75Zr zmZ$HbWZP}(EcU9S>Q?8d6)299dts*-D9`s%@(?8t!*JKCOPje_zbu$=W(~?(vBIh>pSpl4Z}pUH zZ&bnXbw5+yST4qTOCTq}a@w)azl+@iisSQu3TJ;dq=43UMtu{1FogL)T9$ z3IrOM_x4^V3Iuincf*<&n+>Sr3IBs68Ga#!{Hmk6g zW0QKTdYgK?x`l$LA@U+6FH!RHCUvWNhw_&S9px2DUN`0+Z~ULlJnmN?WSl%e$*YYj zbi>z9IGY$BhU<=;A)Jzhye*2_Eh09dcWNKg%Jp`ul`&*2n!#RBV{>ZLO5Y{utM=3t zdObCj=E{!IePCAR_f)`~#_YjHkB4#0V-6L$4Z)xf;xH-JDi{NX;f^r+_;XS~B zmlm>wZqUh2X5T!Pp$N=c#)?r>R7{J72;#@ZZ_sTJsaGPHVM4n*%vGjdQ892oDZVjT z7j&CBupM2Na+9-*ySTTxcer=Ck3a?7$9)g0PzR9> zX~sH~xeAqt`lDN8l91$PO0n51t*v+Jhw3Lx>-fpcs@5n$4vCD5fMfiWI;wWl%{ zHjPxncpp7wV#^(-hq8|C_tmx-m#jj4t^Uqs-JyP?eyi?Nzf-?ge^7r^e^P%|e^Gx` zf1~6>N%5rD2i!jjITF~X_*L(6`{%_^M>cMbRa93$89`@u|Jb-2%a_8 zz1Uj|Hu=hsrKl6AG@(aolUtXg;v0eC(K?1|X^dxXu+%rvJFhAjYFy2!bp+zHFiO5_ z)H+e}J*)397|mMh(HQ0pY_)F6uqF*gaY}xm1X|wGYqUr$2DW}`J+&w;nt~5F0vpqQ z-l)ZLy|s8seqm>=J87u&Ooc}@pC^9!I1~2ky?>9ivO9F+gAavo!14&gf^YeYJEi3bkP4= zdelVNRs+JuV_t`twXh1;8k{NHph_9)1D8nQU zjIzculWkRzT2wc)5y2V8W^KGytWD4+Y9*BXOL>m+i1LK;Hdss6CTWx5L8tKL+O%n{ z1t>F$M#&*?G)Bo`$Q?G91(WK1HB0JzwO)74VD=q;8=`G6jDc*oiKlY#VxJ$T)`OFc z36eHbn*~!*Xxi3ky}1MxV%_U+(qMSfU1htAVes<0-wn0oH}-179&Kh#3~^LY z2lix$0+-CVW56KNlAM)G+lxmh=c~}eDK9$1b*|Il(0^ttQ0+We>4hH0=CBrQ7Qh>| z^R<<%362-w*e?cv;MZ1Z7iz1g)dTisqf%a>yj<=qPG{q2Aidt*P&40G<*uvq1gib+ zxxsWR^FaE925&`muGe3gZmiQSV%r2-PijbS*{r{q9WY@&#v1LC>F^L%muk{r8++Re zW~fWG%gmhz=9nGoC9V7&IT|-6mQ>`#|v_fUT z5bRlGC;}7Ri;T_-5~IhFcSBQj!&C#}>WG_0bf3S?<}HZd^@t!w>TG6VmGuGbAtrSm zqwu%guZ@I7DbPhhB>?4b zrg@E(F0*gybS5=Md+REVmA9VIS`9Uotj&tyO_PZpFwF&mpcWY$a$B5XYX?C`&f2K` zs~yq~Q$CII>6Fjd=s@h`Cdy|*Z5Z{@5efr#mr(YhIiu53c-RgOCi1{YlfMMaf!+%1 zicxD033gdIWXfmhGxj<(hr`jq;p93v!W1H8ardG62NO; z5Zn6JIs<6gdrA3Wlpg{%O1>}Uhg0x3+MV)4k5DumJsnY|qQPo(Fy;HT$bWr_Sw9IV zd!wV5BhdlO^r!ql%EKwPAz|i7F@@QHV+%q@x+w?;{kI_8C69oYGYYs%9ogJkCR5JR zIb&>f3~>xSwlrvR3}eISvECqqtMv_Yz<_HG=`M5atK8{oQD>Nu$|Teh4{61odG0_% zz+Adyd*@pPI|x@e`2}QT(i|_?Eh}N4en{JJ?0Ci&><6yd6(ExM1y5JGLieXLpJj$0JlTyb-M~S1mHic1Ywmap=P(GhE zJUMiXhM($~*4pr+DPPd8;b*gkcRS`dDkxt_`H_?#)!OiL&4wRwoQAJ98@}j&*YKgi z&#~A6+Z~%7OB_ob%N)xcD;(!I&UNSx>Nt<`V<|t5^5ZFAO!*0vpGf%<%9m2UjPjG3 z9VjPmH+b#qwI`|rbExj7T#J3A$ zF5Sa;8}y|44D9CAtn=Hx-d#hXSBzKYf$VKu@dA>~L?eYuq=kU5yHziBy z3-7CpR>mshl?h6TQl`vS<|rPe3btC;DfO_U_hr?tW~j5(T9sM1Z&#buJJh?>d(?Z? z?dk*SL+T^yV=7qa)MwP^)ECs3)K}Ek)Hl=}>P~gH3g#rOgBGTB(zH?hAeo{aH#ly0G&}Ba+|@zo(78j`4&6KS=&-EA>JAroxTM3n4nK7Gr^CSx zhu}qm3TM63?+iK@I^T1C?flmHo%4sV+_3Rs6T(Wu%EBHDdoJvSu$RJK>6p~9f5(9x zvpb&E@%oOpb==Z%YsWh~b?6k?DXLRUr?^gfr?s6f?R0skD?6*5!#hWG?%6rI^RmvX zJ73)SlFsWo|J3^iw?W!Je~tGdqb zy1VPAT|e*oW!JB}jp{bJ+thB;yUpzOOt&|?z13}3x3|0Z@1EN|zk6Z#k=^g^{#f@X zx&^BS7uJ91Ct-pKbNe~SDi^0&zSk$*=19eE(~-^jx~QBTs- z)-$eWPESwI3wv(u`Bu;UQJtguMioa*jhYcPD{6L>H_9Isj9M7AIBIFs@~Cs7)x{iP|3Zbkqw`FGal)^=8ytQM;nvj`||%>!_cjeu?@m>R_}K?TB_pcZ}{9 z9UdJK-7~sRbawQ(=;G*!(WTLoqNhYpi=GiZD|&YHoajZ-OQM%WuZTW3nns@=eL?hv z(HBLpiC!Ds9Q|_i4>28L`o>I+SrKz%%%d@TV?K@fBIc`@Z(@Fl`6uRJ%%NB=7RU0j z_E<5tOKkVp9Cf zzbbxp{KfIt#9tqOWBe`gjqw}fpNfAyerNpd_&xFO$A1|Aar~$8Kga);z$Mrcgaj$U zk>E_|n9w;PJ|QEaAYnv8QNrkiu?gc7CM1+3lqF0~n3_p-u6dmTYEF7E>9M3IlAcO>KIz4zmy=#idN1k2q_2{`N!p+E zPtw7pL&+rBmMkPo$=#ECB@a#>k~}PVcyexXesW>*$mCJUW0J=uS0sCq=OufStCMS! zeaQ=w1IZ1^i;|ZluTQ=|`Q79LDbXnfDc+RTDYvCOm-2ebj+C7#yHh?)`6}g`lzl1R zr~H`mbIPwNhf{GXpDLtEsY+^6YX8*1sY6nSrRJp;q>e}}N}ZBAJ+&&eHr1E9Aa!Bt z;?$+7%Tw2+UYmMn>fNc^QtwN>KlQ=Xhf^O-eLVHa)TdMTq`sT_e(Hy*AE$nn`bFwj zso$i2m-<8MPkq!rseQ)xS<4t#WO2-Q&97^`Pq!*ORWNUC+5*aJ}u?>-y5Q&-K0QC)e+;KU{yi z4y4Ix-O~D`rKe@3^-mj=c2?T3w4Aj3v=M2e(#q53q*bQPO{+?)PODAxr7cJcrY%fc zoOX5E_O!ie|D;Ey=ciYtUzmPt`m^b;rN5cJGktgZhv{FXf1CbY`j6>9r~jJ%dj`tj zGlUE|L(Axp(FgWB56c*yk(V(tV^qf2jPV(>GTa$;8G($3jKvu%GS1C7FJooKl^Gi{ z?$3BAu{P*9oV|$-Y%Z4Yb)9D-q5oE}S5krO`f-e!F(?Spd88SL2p#|8I zA*l!=8?ic_%F|w_>8aB?b;@?xKKZHBHoslh`}+R!y#I&$emtIgGY@1Q&ODZRBJ*@+ zXXg3Li~*8R%ccZXf)_Y5Dioa z;(-8=0JIb&2Pr{nkPc)3nLs~-R)IEvHiH}>H)t!U5!3`ojjnM!-hFrov{z(qS2}`LG4BOc)4;h0$S)VM}2v zU{aVIri7_sI+y{r61EEFf_Y#KuqIeDtOeEz3&A3=IIIoU4m%5bnmZ~tE4MJ$klUPl zAh#>`1AHKSFnkDn7<@c@8hko@COjQJ8$Jh~4Tr+va1?p!8LFL+ywsx zUIX6@uY>#GL3kJ*gSW%C!*{}W!H>f)z`Nm3;LqVN;jiFt;P2s|;C+Yzh!n(R#5BZo z#7smwA_FlG@jc=PL>2;!fFKGG3WO7}8*v@kA2}O|M=nPGf?SWZBR3*9Bex<0$PhAu zj3e8S?a1xO1IWY3W5^T8)5x>P$H+IxkI2ucey9{wDrzWdIBE(i4K)Wf50!&Lpin3b zihv@aC@2~VKrKg^P`{wes5PkdC_8E+Y75GVsz)`TwxNDS{f63&>Ok#79Y7sI9YGyO zoj{#JJ0dO!Lg`Uv_2`V{&s`cHHh`U$!ZGXRru?TE2wi@fg zHe*|`L2MYi4cmd;i`|bsh&_xwian3Lh`oZnhP{EkiT#L6#f`v?#*M{I#7)Lc#iijE z;C{p*aai0!91%yw<>Q#R0-Oj}fivUQ;MU{pxQ)0iI475{3~*62=h56DATS6Q&Vn5Yh=51Oy?EfFa-rcmjz)CQu3a1SX+?z#%9In+Q7z zR|p@7Gl+QNVqy)knHV9)iAmx%Vh8aE@fh(0@f7ha@lWD;Vi)l?@gDIZ@iFl!DU~#V zG?_G&G@bM;Q{ozzA8uxQdE)FR;`^P=dY&PC72!^m^VS>$Xo zl$=Y(k*VZ-GK0(_v&n^IF?k7jIk}u%L9Qg%lDCqZ$$oMxIZBR`ljLpWgXFX1zsMKK zSIF1NUF6&3yW}47XUaIr*OW<=sg&uIS(Mq7xs>^oA1GNABISz$PRXY*C@Ol5Tfkn*UcoMBSFkJDUn*qwDz=5amThI% zvNy65><;z;_96CB_DS|>b|?EB`zHGi`w9CQ`#t+Jrypk^CzUglGlDaUlg63P!EnCF z-W)QA#$j*@IE5S@2jG-)R2&UQ$I)|)oS!+XIA+dj&N_~jW9LLUCppgwM;3w#d4Mlq$hve;4lYw?BRe~aH0e=PnC^aF+fV}S|4H^3Ai4VVGU0=@;Z zfNTH?zyTD121O zHgFGk2s{G*1KtAfflnnrl_*M7CF&Ag$*q!Sf`Nj;f+2$8f>DC8f(e3e1XBcQf|-JE z1qeZ&03*N&@B)&6ET9SK0;Yg1C=?V4sswd{-GXa^-qQ3^eChJiwWXobqorp{&y`*% zy;Ry&`mpp->66lDr7ucfmi7w!2?q)X3x^1Y3Fm%+@ZmzF5G}+Di9)iFDl8TXgiD1g zp-!k5nuIk%i*T)Qy|7*w6z&rq6dn;C7oHTJ5&kLsOL$56x9}ffm+-alt?<3@qp-KE zU)g}NL1lx>Qp<*wjVv2owxEnwR#~>CY**QhviG8CBBTfq8AYo_>qItDt;i*67PW|i zqKGIiY7@1K_K6OPj);znPKr*8x<#)=??sDOQVhVuRQuwuL=@<{ST@=WqV(j$2#`LBFz zc~*I0xwgEa{BZdL=^$yk6eA@|X;OxiB`uaNmM)Plldh1KOJ!2M)Fk~yYL>2%u9F6( zJEXg%zf1Q?4@-|p|B#-P{w=*BeJp(;eJOnyjFE$7O4 z@?~;gVRen`Dq;h!W$jZ@`3o2=qm6cm6cU9g{^ixb%8s_9j8tFTpzzSPRvDofS+Dtpz&Do2&OYHL+vRkSKz)mF8w>TcD) zRXtU&s@|yi>ZNL#x>BuDYt$z7FKV-Tje4EhsZOeot1qd$)VJ05)DP58)X&v#)V-Pk znsJ&m&3sL^2CBhms2ZjQ&@9)KYbrDfO_fHYF>BUqT$(10PZQ9DG;Nw~nqM`$Ga+%}NxMqx)W)<2wHLKFwD+~owJ){rb^UZH zx{eM=&&Y-jC*6OUfTHPky7F|fUS9e}_ zO?OZCuzEsuT6JbMv>H=QuBKJ%s#jH8s<%~lRPU>PRQ+G|hw5H^KYfZmRXSN}l&NdHv-Lf@l*t$(ZkU>IQ- zWf*H1ZxN=y{NMCV0~nLVtsD?*EYa5!8Xr^v@vZ0o65Gv=CJu~N!xbYPTOwV@3#H6L$*%a zdD}(X727r24cjf-9s3~rEIY=|u`jjT?H+rJJ!p^ESH`XR<+iQ1hIkDyZmiKl2>gLsLsB5V6 z)dlK8b@94n-S)a)>(146)jg?uRrjXuech+JK1Zr!sAGgLRvU{3)hCAJz;hyV;yGd?}JKxQ8v)zU6Qn%2pahu(1-0R(T_eS?- zx7Y1=x4Ogbm^Q|qVK&#IqYKezt7 zdPcprerx^y`g@+io^hV3p6Q-hp4pzco-9wc2kL=)P#(00>ydcO9c6xSu zIy{#eiH)Mhibh3aRin01-)L-fH~Jd)Hy&y{+Eme`ZL&12ZL&7iHf?I!(zL7TVAG+d zqfKX3-8g?;!6O@7LZ*-l^W1-gNJ5?;J1MEAm!&*LtnqTJI)ro!8~{ zcpJUV-WG4r8}Y`y$Gj)Jr@fut^WF>I%igQr>)xB*JKp==Ztvsf;mtFe=Qq=v4b8R9 zf#y@q&ze8_#`xy>@_bYu-N*8Ad__LKPv+D348E1VRX&Svv#;LQ;Pd+YzKAdGYx8aM z?eHD)b^31mp7>t*`}x1Tn)Q$HkM>XWPxepsPxsICgZ)TIvOHs>DE%Fw1i>}4c zva)4cOGnGqmadjhfgyq6fsuhRfwaKPKzbk}kQqP)FacbE5XcV{2Lu6OKpc<;oPk8( zaNu&_QQ%|i=+RUIpdRkjs!>zH_-r(Ti*xm0N)1g2rG;jOz75R@ zeHQ|UAR%ZdH-reGLO@6tY6$HN9S$7}od}%{b%xG`?uDL(dP1*5Z$lr#Uxi18$Arg+ zCx+9)GsEfOjPTrWRu~>8h3R2dm=i7vmxe{*#o?vliaMkI=)vfb=<(=@ z=;>%@^nCO}^m6n?v?uyH`ZoF@+8gbQrN&0Z#>OVZzKKna&53;%`#$z#EH_4skz>>t zJ;seKjxCKXkCn%CF@4Mw`#H8Q=8Xkn9kFw=ha_{;dK_?!5731LE%_$i@Cs1lllF0neXHPMvtB?5_1BAQ4f+7mkxza{o0 zIuqv;7ZR5eR}$9}*ArcdTZy}g`-z8b1KVb`5!;rx+1qxsU1|F-IX;<{geOr+OcIx* zCOJuNl9wz_mLyA)<;jYqB3YHxCaaUKWFQ$y#*=Ny9m$=^UCBMk6Uj@-Ysu@$o5_30 k2g&Z_: Error, CustomStringConvertible { + // MARK: Stored Properties + public let actualValue: Value public let expectedValue: Value - public init(actual: Value, expected: Value) { - self.actualValue = actual - self.expectedValue = expected - } + // MARK: Computed Properties public var description: String { "\(String(describing: Self.self))(expected: 0x\(expectedValue.hex), actual: 0x\(actualValue.hex))" } + // MARK: Initialization + + internal init(actual: Value, expected: Value) { + self.actualValue = actual + self.expectedValue = expected + } + } -extension CRC { +extension Checksum { - public func verify>(_ expectedValue: Value, for bytes: S) throws { - let actualValue = calculate(for: bytes) - guard expectedValue == actualValue else { - throw VerificationError( - actual: actualValue, - expected: expectedValue - ) + public func verify>(_ expectedValue: Value, for data: S) throws { + let actualValue = calculate(for: data) + guard actualValue == expectedValue else { + throw VerificationError(actual: actualValue, expected: expectedValue) } } @@ -50,21 +53,3 @@ extension CRCCalculator { } } - -extension FixedWidthInteger { - - internal var hex: String { - withUnsafeBytes(of: bigEndian) { $0.hex } - } - -} - -extension Sequence { - - internal var hex: String { - self - .map { String(format: "%02hhX", $0) } - .joined() - } - -} diff --git a/Sources/CRC.swift b/Sources/CRC.swift index 59aa997..a4d8295 100644 --- a/Sources/CRC.swift +++ b/Sources/CRC.swift @@ -6,7 +6,7 @@ import Foundation -public struct CRC { +public struct CRC: Checksum { // MARK: Stored Properties diff --git a/Sources/CRC32.swift b/Sources/CRC32.swift index 5f29080..627ef7e 100644 --- a/Sources/CRC32.swift +++ b/Sources/CRC32.swift @@ -17,7 +17,6 @@ extension CRC32 { public static let posix = Self(polynomial: 0x04C11DB7, xorOut: 0xFFFFFFFF) public static let sata = Self(polynomial: 0x04C11DB7, initialValue: 0x52325032) public static let xfer = Self(polynomial: 0x000000AF) - public static let c = Self(polynomial: 0x1EDC6F41, initialValue: 0xFFFFFFFF, reflected: true, xorOut: 0xFFFFFFFF) public static let d = Self(polynomial: 0xA833982B, initialValue: 0xFFFFFFFF, reflected: true, xorOut: 0xFFFFFFFF) public static let q = Self(polynomial: 0x814141AB) diff --git a/Sources/Checksum.swift b/Sources/Checksum.swift new file mode 100644 index 0000000..1f86abd --- /dev/null +++ b/Sources/Checksum.swift @@ -0,0 +1,14 @@ +// +// File.swift +// +// +// Created by Paul Kraft on 26.07.23. +// + +import Foundation + +public protocol Checksum { + associatedtype Value: FixedWidthInteger + + func calculate>(for data: S) -> Value +} diff --git a/Sources/Hex.swift b/Sources/Hex.swift new file mode 100644 index 0000000..2c4f040 --- /dev/null +++ b/Sources/Hex.swift @@ -0,0 +1,26 @@ +// +// File.swift +// +// +// Created by Paul Kraft on 26.07.23. +// + +import Foundation + +extension FixedWidthInteger { + + internal var hex: String { + withUnsafeBytes(of: bigEndian) { $0.hex } + } + +} + +extension Sequence { + + internal var hex: String { + self + .map { String(format: "%02hhX", $0) } + .joined() + } + +}