From eb485481b96ca8a2beb6e478b8adf1eb6906646a Mon Sep 17 00:00:00 2001 From: alain Date: Wed, 5 May 2021 23:43:21 +0200 Subject: [PATCH 1/3] initial release --- .gitignore | 9 + ATK_DUMP.png | Bin 0 -> 196323 bytes CreateAuthCommand.py | 418 +++++++ CreateCertificate.py | 238 ++++ CreateToken.py | 284 +++++ ETSI-SSP-AAA-FAKE-param.yaml | 70 ++ ETSI-SSP-AAA-TOKEN-param.yaml | 23 + ETSI-SSP-AAA-param.yaml | 77 ++ ETSI-SSP-AAS-TOKEN-param.yaml | 24 + ETSI-SSP-AAS-param.yaml | 77 ++ ETSI-SSP-AUTHENTICATE-param.yaml | 37 + ETSI-SSP-CI-param.yaml | 93 ++ GENKEY.bat | 44 + LICENSE | 21 + RFC3279.asn | 275 +++++ RFC5280.asn | 1030 +++++++++++++++++ Readme.md | 123 ++ SSPToken.asn | 77 ++ SSP_ASN.asn | 490 ++++++++ certificates/ETSI-SSP-AAA-CA.der | Bin 0 -> 649 bytes certificates/ETSI-SSP-AAA-CA.pem | 16 + certificates/ETSI-SSP-AAA-CI.der | Bin 0 -> 644 bytes certificates/ETSI-SSP-AAA-CI.pem | 16 + certificates/ETSI-SSP-AAA-EE.der | Bin 0 -> 656 bytes certificates/ETSI-SSP-AAA-EE.pem | 16 + certificates/ETSI-SSP-AAS-CA.der | Bin 0 -> 649 bytes certificates/ETSI-SSP-AAS-CA.pem | 16 + certificates/ETSI-SSP-AAS-CI.der | Bin 0 -> 643 bytes certificates/ETSI-SSP-AAS-CI.pem | 16 + certificates/ETSI-SSP-AAS-EE.der | Bin 0 -> 652 bytes certificates/ETSI-SSP-AAS-EE.pem | 16 + constante.py | 85 ++ credentials/AAS01.bin | 1 + credentials/CP_AAA.der | Bin 0 -> 1953 bytes credentials/CP_AAS.der | Bin 0 -> 1948 bytes credentials/GCM_AAA_AAS.der | 1 + credentials/Text_in.bin | 8 + .../aAAS-OP-AUTHENTICATE-Service-Command.der | Bin 0 -> 2257 bytes .../aAAS-OP-AUTHENTICATE-Service-Response.der | Bin 0 -> 300 bytes .../aAAS-OP-GET-CHALLENGE-Service-Command.der | Bin 0 -> 4 bytes ...aAAS-OP-GET-CHALLENGE-Service-Response.der | Bin 0 -> 1978 bytes private_keys/ATK-AAA-ECKA-private-key.der | Bin 0 -> 122 bytes private_keys/ATK-AAS-ECKA-private-key.der | Bin 0 -> 122 bytes .../ETSI-SSP-AAA-CA-FAKE-private-key.der | Bin 0 -> 171 bytes .../ETSI-SSP-AAA-CA-FAKE-private-key.pem | 6 + private_keys/ETSI-SSP-AAA-CA-private-key.der | Bin 0 -> 171 bytes private_keys/ETSI-SSP-AAA-CA-private-key.pem | 6 + private_keys/ETSI-SSP-AAA-CI-private-key.der | Bin 0 -> 171 bytes private_keys/ETSI-SSP-AAA-EE-private-key.der | Bin 0 -> 171 bytes private_keys/ETSI-SSP-AAA-EE-private-key.pem | 6 + .../ETSI-SSP-AAA-Token-private-key.der | Bin 0 -> 122 bytes private_keys/ETSI-SSP-AAS-CA-private-key.der | Bin 0 -> 171 bytes private_keys/ETSI-SSP-AAS-CA-private-key.pem | 6 + private_keys/ETSI-SSP-AAS-CI-private-key.der | Bin 0 -> 171 bytes private_keys/ETSI-SSP-AAS-EE-private-key.der | Bin 0 -> 171 bytes private_keys/ETSI-SSP-AAS-EE-private-key.pem | 6 + .../ETSI-SSP-AAS-Token-private-key.der | Bin 0 -> 122 bytes private_keys/ETSI-SSP-CI-private-key.pem | 6 + .../ETSI-SSP-AAA-CA-FAKE-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAA-CA-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAA-CA-public-key.pem | 5 + public_keys/ETSI-SSP-AAA-CI-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAA-CI-public-key.pem | 5 + .../ETSI-SSP-AAA-EE-FAKE-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAA-EE-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAA-EE-public-key.pem | 5 + public_keys/ETSI-SSP-AAS-CA-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAS-CA-public-key.pem | 5 + public_keys/ETSI-SSP-AAS-CI-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAS-CI-public-key.pem | 5 + public_keys/ETSI-SSP-AAS-EE-public-key.der | Bin 0 -> 124 bytes public_keys/ETSI-SSP-AAS-EE-public-key.pem | 5 + public_keys/ETSI-SSP-CI-public-key.pem | 5 + tokens/ATK-AAA-ECKA.der | Bin 0 -> 288 bytes tokens/ATK-AAS-ECKA.der | Bin 0 -> 288 bytes ui.py | 60 + viewcert.bat | 39 + 77 files changed, 3771 insertions(+) create mode 100644 .gitignore create mode 100644 ATK_DUMP.png create mode 100644 CreateAuthCommand.py create mode 100644 CreateCertificate.py create mode 100644 CreateToken.py create mode 100644 ETSI-SSP-AAA-FAKE-param.yaml create mode 100644 ETSI-SSP-AAA-TOKEN-param.yaml create mode 100644 ETSI-SSP-AAA-param.yaml create mode 100644 ETSI-SSP-AAS-TOKEN-param.yaml create mode 100644 ETSI-SSP-AAS-param.yaml create mode 100644 ETSI-SSP-AUTHENTICATE-param.yaml create mode 100644 ETSI-SSP-CI-param.yaml create mode 100644 GENKEY.bat create mode 100644 LICENSE create mode 100644 RFC3279.asn create mode 100644 RFC5280.asn create mode 100644 Readme.md create mode 100644 SSPToken.asn create mode 100644 SSP_ASN.asn create mode 100644 certificates/ETSI-SSP-AAA-CA.der create mode 100644 certificates/ETSI-SSP-AAA-CA.pem create mode 100644 certificates/ETSI-SSP-AAA-CI.der create mode 100644 certificates/ETSI-SSP-AAA-CI.pem create mode 100644 certificates/ETSI-SSP-AAA-EE.der create mode 100644 certificates/ETSI-SSP-AAA-EE.pem create mode 100644 certificates/ETSI-SSP-AAS-CA.der create mode 100644 certificates/ETSI-SSP-AAS-CA.pem create mode 100644 certificates/ETSI-SSP-AAS-CI.der create mode 100644 certificates/ETSI-SSP-AAS-CI.pem create mode 100644 certificates/ETSI-SSP-AAS-EE.der create mode 100644 certificates/ETSI-SSP-AAS-EE.pem create mode 100644 constante.py create mode 100644 credentials/AAS01.bin create mode 100644 credentials/CP_AAA.der create mode 100644 credentials/CP_AAS.der create mode 100644 credentials/GCM_AAA_AAS.der create mode 100644 credentials/Text_in.bin create mode 100644 credentials/aAAS-OP-AUTHENTICATE-Service-Command.der create mode 100644 credentials/aAAS-OP-AUTHENTICATE-Service-Response.der create mode 100644 credentials/aAAS-OP-GET-CHALLENGE-Service-Command.der create mode 100644 credentials/aAAS-OP-GET-CHALLENGE-Service-Response.der create mode 100644 private_keys/ATK-AAA-ECKA-private-key.der create mode 100644 private_keys/ATK-AAS-ECKA-private-key.der create mode 100644 private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der create mode 100644 private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.pem create mode 100644 private_keys/ETSI-SSP-AAA-CA-private-key.der create mode 100644 private_keys/ETSI-SSP-AAA-CA-private-key.pem create mode 100644 private_keys/ETSI-SSP-AAA-CI-private-key.der create mode 100644 private_keys/ETSI-SSP-AAA-EE-private-key.der create mode 100644 private_keys/ETSI-SSP-AAA-EE-private-key.pem create mode 100644 private_keys/ETSI-SSP-AAA-Token-private-key.der create mode 100644 private_keys/ETSI-SSP-AAS-CA-private-key.der create mode 100644 private_keys/ETSI-SSP-AAS-CA-private-key.pem create mode 100644 private_keys/ETSI-SSP-AAS-CI-private-key.der create mode 100644 private_keys/ETSI-SSP-AAS-EE-private-key.der create mode 100644 private_keys/ETSI-SSP-AAS-EE-private-key.pem create mode 100644 private_keys/ETSI-SSP-AAS-Token-private-key.der create mode 100644 private_keys/ETSI-SSP-CI-private-key.pem create mode 100644 public_keys/ETSI-SSP-AAA-CA-FAKE-public-key.der create mode 100644 public_keys/ETSI-SSP-AAA-CA-public-key.der create mode 100644 public_keys/ETSI-SSP-AAA-CA-public-key.pem create mode 100644 public_keys/ETSI-SSP-AAA-CI-public-key.der create mode 100644 public_keys/ETSI-SSP-AAA-CI-public-key.pem create mode 100644 public_keys/ETSI-SSP-AAA-EE-FAKE-public-key.der create mode 100644 public_keys/ETSI-SSP-AAA-EE-public-key.der create mode 100644 public_keys/ETSI-SSP-AAA-EE-public-key.pem create mode 100644 public_keys/ETSI-SSP-AAS-CA-public-key.der create mode 100644 public_keys/ETSI-SSP-AAS-CA-public-key.pem create mode 100644 public_keys/ETSI-SSP-AAS-CI-public-key.der create mode 100644 public_keys/ETSI-SSP-AAS-CI-public-key.pem create mode 100644 public_keys/ETSI-SSP-AAS-EE-public-key.der create mode 100644 public_keys/ETSI-SSP-AAS-EE-public-key.pem create mode 100644 public_keys/ETSI-SSP-CI-public-key.pem create mode 100644 tokens/ATK-AAA-ECKA.der create mode 100644 tokens/ATK-AAS-ECKA.der create mode 100644 ui.py create mode 100644 viewcert.bat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d85c24 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +__pycache__/ui.cpython-37.pyc +./tokens/*.der +./credentials/*.der +__pycache__/ui.cpython-39.pyc + +.vscode/launch.json +.vscode/settings.json + + diff --git a/ATK_DUMP.png b/ATK_DUMP.png new file mode 100644 index 0000000000000000000000000000000000000000..75e106d48a7a6ad858a1c9ee304d12460ecb2fd8 GIT binary patch literal 196323 zcmeFYWmFv7(=Ut#4Gb4$iBvEFu%$F|f5uE}zxCt6hnTu{>x3NW~b zeJdhCDsx`cnJF&Mayv-pme;RHE(X?BnA-u>CajT4*&5K9@r%AiO2yL_BbQ3_QWIuG z!cNstBnsK4Bk-DW0?7o(MX<5QCRn{XXPv!{?>dg|ZdWtIeMuvj7v=rTot*VgF0$e+{XQ{lB6Aw;Rtp@PE+_uD6t}JT=ukg3IQ5iFvJz zZ_90I_?JUu{?@Gm3U>D-Nwsth`C^Lrbv6v!ZPbY zG@D9<(diTUj1r1oB)M1o*&@}ccMeKaUQIUtsAgrcm3H z7QxTcoM{P$3d3z{X^q58;8Pz>m0yEqquJ$V!)`))R+!cINp5W#9a-NS#YJNeZd~YF z?hWj-a5fLxN{q*SNxd;VPY4)NEFgjlOEzhbzdm$vWS8pol&X?_pGBOV@DKX{!?dm40?apeN$cmvJ3nuo7~ht1D)uMPMFSn5gGJf%)TEM7PL%oF@W{ zU5oy{kslngTVI>*9DaQ7FsDYu^p5w0D8O{QQ1GEV$yUU4y*k3rHu##S>$>f zuE;RGiXO>|)5egcXbmk5&wc6Punf8ip%=PqML*7MaK@}pVm;e7CAz+14(vd z06UO%@J?V+>3WTHZwZJegL|^W+Nn4><2T_~_4U{z6c9)xr`>RYVLy@yw+=eLt$Ymm z&{;+U9Z4u_63ntB9kW;t^&JkLK@}x+0Uuc0wJ?0bGmoDGeZESm{r!XSEhc=R;2WqN zyT@{B??uWNMt=aC$DCE%uO=$lwnR{(=0%s%|2pY%*!?v*^wjFRpyN~`8-iITQnU*=QZDP(YH`*>5k za_oiocyXXESW^;kU=2&FlsVMb-yUcp9Y#mY^T=UC1b!WgGRBoJ$V$FzwWP&B8&g}STU+YdUXP(4cxaTv*3o?3w! zCWX`dZ3FbHEw~=9N0fH-AqTt0N4tjex|xQ_P^*7r8_~c!KfKjKZ;c~8h=MUD@1=Hg z$Je4I`JLLl?eVfje19O#XbLCfjH1M8$Zb*&@+M2v=*pG@u?7R2da57?8%J*OX(h-5g zHOlGeql924$2xt>ysVtT5sn*+1U{gnSr+}AbUkV|(2pNDc+8es`B7fiHYszxs6*8z zukj2#0DLmn>nNf*5`z!b_n;W`+rC3|hZ+L%{IKS^%LX0`S}%Xx%I~GdnBXI(cf=g@ z+JboLT56grtKgj?-cf6~RP`~E9JzzM0;+*Y3&PcKSTW~H5~BiFD0yxW%&?x5mkE5+ zP9UM&4eI^r-6cQsV{ zgh6pjB4&Yxs_o{>8Iq%$*@_b-9=i%UU*a%H>xEnXsJl*r`nI}PNtzm06W7Bdff zV9Dc~|9pOA1Y6}b?QmN{uTWBo5->(oNvj%>8_lKfKd*?^HS=WbDq^85gQ^&TXuZDB4gq^OkC>rj)iR`pCYcKXko0;Li zg?vwOf5o?<7xpu-;vCOOmT-3$Ml~H089Ai)yi%H3BzbS_f*pTh@waFAKUQC=UUoia ze|MXvXE5l|Z^Vlgsux+Y{!rFrDa`2I)(~mQkP?gD#r^;VADtNca)5o#noe&xc-Ej?YVbaPUuSz$B@&1T%{wk*+Gv?&z- zz4ma87$K`wy1d|FRTt1n()v`KvFeZ?g^PVtJLO zA2ytmI-bSbc$T20YrVWMq?p!>cTFm^V^z>X`?5e)J5zaaSKcF9mSTSv=;G)>FMxUY z?Fh4$KGS{suv#1S+&)dx=p{9P19_Z+e+ho9b$`qyE*j&VL;Wy9abeF94`nV-9s>4l z`!gODtn+S1D&y4ZoCR?UK4zJ}9!D1S#M}awujTp(58~x$%YTpu$!lLJ3#=b)y+Ert zZ~!f39~F{He|Fl$O^%gKt*^8#hB$2D)6G$2W#6i<2r|GXoN}PfydGU(f?@D#ocVC zxMSRvN}kh(N-njd9OuG9r!NrGMi0o@k4Y5$1YJA9;%9-nKcf*>Pm~a3MxqGJx;_b| z5p44isH|W$T^TqGX3#qI+>&SV{7p}q2GW($>dNng@<^)RWqay*sO$YA6BqUGsZ#iS z?`i*d**QyU{#r%Ql18~hZ)CgwMWR`z|8;f)n;wKhyz?feW<5O54 zgmDX5qJ3VfR7`eWj5@7S#;86BO6S+HPM$3Br`7#?Dj!WgE>eA@veAv%7r}>UPzpuXBl@MkSliST^LC5WMsIjOtbYwRs z5d^O_1`Q&2;*O$wY9IN28K;udwdAkpkT5u#3%BO z%+SL8+}p(T7=j2b{$3LiC~cuq18s-vwK7sII*!Ylv8L%Ew(Gobw1p_IOk*tboFxA=~8iVGyljUjvL92DJjJ((Z2A zVs8)W@K~b1Yy3i*()Y5xA-UcGCJ@`c`7~&?NtBI~^o@O4QNth?P2YZ{1}qz|&Fwe$ zUoXHb-Ec;Cw{xDgq1+U7tEs?vm@fBhsQ=v5Pu=%?Ukm*xS3lz|kx*s^fZd=SfwTeg zE<-YkUGOOJ?&zYCw});LN*COIYid&#eLf_R<8SWAjx6BC{%)1G2I_1{o5p1l&tQrk ztsZDN&1gdpnv^JM&oV7W(yBHMhS(Qhg!`|BKC#-`v@syT6rVQy8R?kvkCPJV?^*Fx zh_1KQ^pLClN?g;oIFk+bD=7o*@zk_^yFCld9IWm3?s0jc`y-OmdbJGBmdMBM1c3li z6v%|K=sPcAdY9&{4j3*63l}%cxxp>fGm(ws;iVs*JI4=!WcDR_*8T#Ahlh2cke@2; zX-S~w9NbD8N){sT;pqn=YnV_X>l+~EO)QSSL`>bJ_9bVwPkji!?AY5ODo@xr*W-bB zr(UK3_-X)d8GU)tsS%PsT~O!KWQ+zCt@=2{R_vJ=UYd-Ise}NfJ)Vb1MFCxuoCZrn zEiQ$U+%L=`l||g_oL2|e_URe0YC{wFW&L*ln1&;NeJH5<{)hJI$_FqRU<;1)<}sPG zan5e>yS5Y1SM$QzZJ{=asre`fhy!K@3mC5Unu?Sbx{q%xcWxgDz-r`{L;FMm^=>w@3uNk|k92{P|f>Qp8ydlM17NG&?*I0*$WZ1yF%ZjfGH?0PRPy{ z9xH^I8!x1Ww=(FjeQf=z;<4kwG$nDv$w&_pDf?B*n&3=tkUHvVQkUqEw=L@0#MttV z#4h)Dzg@5_WvV|>b3$k<`SWSHQiU~jbZ!jkdOKEHJuq$9VFp(XMtM71zJ4LC*aDn; zWq*7J7_ylP32*x_l0NdPx`68|skXv|%3N@d{oLN{*g(nRC+Oi%qxpF#r4if&B$8H|mZ~p&Em{DJXQrB5T zpTSXfD%5ffqUuihUVlN#{Q>NV=ZwXVWnsA>wfDt8N$+{-7g)ScnUU)%!r3u!F4(*2 zWQ|jUWnAgR)_5dGyYK6WOXX|9hCl}pw#7fW;-T1kf zcP7inZ`*{lgU@bfe^-2P3DNJxF zdOH|Vb#CX{g8|ZeZvhpbf8LO~c~M~cQluny)7L!?&?a!)1TjQ=NbCp-M_yhSzn{o@ z-6#aS)u&+a`ygf{OJP0StDp4D)9qWr%Rs{kknrL$M(cBm0yD>*qb>B1$baZ6YHRs& zMfzr-%?Q&2G4<}J`k2t6LM6!;D$%;q&o%m4Z0sq&Lz)YGU%#<$HzCFJwO%caDc8-h zxUVoSD^?yZ7-!8rQMM_W*OFeCSTn|NGeul5J{DYE!89ize zKXhBeIRrB`X9p}W%Ob(%tdE?hvo!rWp1X>_KdBeM_Qg9&5{IIrawYPv%mpf+o1r0} zrIKY;;GbkuK*4FL!kq@`&737xlj|#5!9}TihaWd9{s&afT!^y61$uF^tHmOUM|HIx zZ*2>I?_SP~>y7p1$Xb9$_ZJ!jP*cY9uF-A^Cf$#k&wUr@Inh$<^AocU9aJH!iU^!6 z@rDA=>*u0oiN@&M_Ws@@`Yj+clC(ma(9=o%10?ig`W1$;9m;Dv`)}-sdfB7g>R(#Z z4KjDW-GKbY_Wa9pw?q@G6VznV1WEaqtQM+6xPj%xM~)`Nk)$QL7die?UI50p3Ntm@ z;#iJ~2pJn8T%y^kmYO817!UWKYW3NBE2<`<2O=J751NeQy7ItxT31W6=Xh+iGFO-M zqLBl)+Xmausvvvo$nsS)|El4h3wG>f_VfzgcZ1;sk++3BzGn(J>%D^kle53)B=?Wr zz^GL!fe*6l<0zr6m$u%;2?eFKZw(Ta7l-XTaIgpsnaxK9$~B-ZU+V5GaAYKiN$iSD zR(Rf5pPDUu^Lkhy2{*ZZ`%>e!gxvl?sy|8SpmOenA;V;N^9^h9$y8R^gBN<7zkgc! z;S&Y)*xlSt(Nlo+%_DG^fV#6IVdrS2juc3_5s%Q8@oYfYc(PBPMSkdSB&`=B$mWZX zsv94}&4`#JH6o1I#tW=u@E~gl}%ZvL%2 zWaz{jKNsf5stdntUp@q_Hz!e#wO@)!^+c7n9kqC1q^W{q;0mzuReTI1CwlGbW;ClF znjiab^}&5cWFK9RTkHA)Y@CPFfA$8jiwS#uX#4Ur2bmB-4 z;ZxyLzX@?-Yb4q%KlZ4Z(TR@SVwZbP9{Pu48EGVVKi+>hw8xWPOPOgW1AQT@fg@*2 zF^>U6(C}t<^lh*&wq}eJ6=yr}HpDbl4pK9OyEiA`}DgIU5zl~1q}pPZhPaqDovw%3clBC$X}Ius7`niasa z#Oa+_qJ^LqW-g2{ut(Rv%En|T?#vmmaJ;d8TPkl-$Z_BcXkqKHl!h97^d(w#f5&5A zsB_T&T%nnNL+c~}pY73e{oq@NMfx?m=bZn&r-&%Wus{29{WByM#KcEXoe-t;X5Rf4 z@?%X-!r`|R4LfuDfefDpnV|6*LQ@FV_-qZs?tYAh33UqHpTA)d<(M8LPO5l|lz2H;;V?T2OV*g(noUz_m4a3a$hiAemjM+q#^T`^9ZE7g(BqSr~d zW!I{FigdbTl!}RuRxcPC0!2|q@hmV5)8OM3K3WK-MnF44Fo|y5BzxO3SD1`I;|M6;gIPxQz?GlY+1at2op>ZmdqlBy(suDCS+kx2j1U#?!_}+I zM`RH%iX5%EBvsA!EFoj$v7wEk9+M+|ji2YMe)+?}#M@gR)ISn!m8VOceXUJ(6vLFE z^qP8IF*HPbe5*G_i~c@p*!s2KE~8nedhdQ~`U0dFc@jT1QDMZ;pqrc1G67)6)^TC^ zxnN9hY;H=otD%FxNyDv=A((M8S^!2qj@&n z5dWm)MW1&3_%}r5x{$LR`+^56j^>CCg>|k@+h?sx)W#bo^}~xp(HVQRjiol>vR`;_ zI_NbJ&3-_nr<&eqpZ8$p%i8DleifPC#VRC}m5>$2-k3Hi%=%vnj2U^GoPX=D(+%qMT@3dc_4=f0@!1lk_C5`_%;siI zfh%#19-ASp?uO>|gEcztU4v?immns~NORXclKZ2yr z7d}C2oWT}m4l~`Z7E3F>H)5`LcsY`fG?@C@`M4vdq6T$f)pnkDhSqGG(^45dLD+>( z=P42(eBOl%)vM}}k&#FKW{vHmmDbSu)N=xK?&s7bwXC?^%)vU{^K9x}Jw!i313Jo? zBs(*(KZXYdUM`NYd$L`@(TO7-DXC(&?u%s_dq6OBB`;3)6ceq9?QHIL8^rzgl6mbfjrw zBX2B=(tO1I99m74n62?5z;T|*YeRg(Ng1f%S#8>g_ohKuw{Uv+4z^GJH$BQNM@1!{u^ zFHX4FQC=v0CeQ17jJRmcPv1XTg;`XUyh}+G%eMbt_}M{%yWz;p0t{aFAjs4#0en1u zjyto91xUhv@x~vH^4KolSz5>k(-j*&exTUt@L*w?i!%!4ib4KwBw;Z@^b;osJCGfE zgsxO?tC2p=$~A;43lOaKUPXzR-3>S&-5%xpni^Dv3c!y6cIdaW-HYZhda=kCHN+Mw zlu}cl>U?@?x5&1X#~*5MwzBF-$kK1W^ygYMv@fBiSiYPL{$F_LLCH5H_GZ(S4L_It zZin%+$}ctQI>dX+T6HqX1U(-9cv%eQ@-AS4V$-bh8LfshrCz3^4uPCCqtK*h2#iue z^rMnB6JTuZ?KqH(IXk(RG%JFMqaDfdPsb%9^gJcgiocI=P!QkVc%_Q(8h0Anj{prK9dP zIkhF-dyS_Gq^!D2vx}H8Cv8kf1v2xa2WQ6Wr+hn0f?w8{YKeZ^&|HxF)1=Z(7Hv^K zZ&cG=%9_^n@r->dfu@9-@5*Ou<(!DDWr=?qlQn`1MH^PZ?$(Dk{4ZT#(yhtLr%S-l zr@aQ;tCFU{tMu1)R&33)&GM<_rk8UKkng5vr12j5VkzR4JM{H-6qGhI`L4l!tw4|E zGD|X`j^}Km7eVf`f-0it;)LhqZDiRU*wU>|dU+TN9>C*g^hDl7G~cIFlgk0zgw{Fj z%Pf~Bl#B$M(eTtgKcJcp!k7-kJAa^va2TaT3FFaFf6NK5)ct$23nsfTI>UHCDr3rFqzg92XWDkg+m|0ABWY2_t{BZ;uRoWz>*w+Lq`HLjYh zqm88BjV~ANB#>kMAJr`M-{cI{q>z-Isd(XVL+8S;oMfo`WD)$DY3oFxV?T$&3HEcGPEk4q^6h^!# zd7i5?cC>oVF*PH~*j48>c0@s}G?6);IUHpxKx{F0+&h*&-C5}JoaeiJTixqWU{z7f z@Dc%aXxAF8Q3jsX{`=m8iv08{MHzEo-Z(nfK)|R=vxOXJW6vs-%aJttDh7v_p#*a`PD!f8tcVWPjxx08{} zNG%4tR7x+EEUk+A+H@l4HYC(aqZ~&2XLSFVdIyzYaWAj#JS!*-w5}$i%8% zhhQs*C1sqhu{FLGK<-|W;7yR)C*^Xtd5P;2cB8ubYq!ak))xUYKc;1OO)pNqgMUS_ zo0zJl)f>U`78bK5BS%#x*KB1ez5i7?oe3Z!Na>SCsu-bF(O0~-5*oidLosl=I)ADJ zk;LR%=w&RB7!=0dg@g_Z@tHZiP1r~Ym%ck>3{Fb~a$U4{- zaH^TrWbo4$Uj)>mTwtXm7FotZZ|J*K?{_h(wswKvJ{U}R|6cE{u=XYI-!=Li?0 zbFP%6`2)EUk9 zJwI+Qoh??% z_|)2%%<`AF6_T6(&fvM4h%7A(b1()?kpxV%Tfe|D3#KE(u>e-?>91cXU7GYrgZFMRV?)4D6#e&xqXHHZ{3>e@9J_Wkl9;} zap=X=fqj)aS~J+uA5R2VjLt9RmmF#|(rAkpH5T)u*G2@Xr>jvYil7z;*8; z1hBnoyT^Li&3&ODQjEsZmn|0{$U+w71uAs}Kb0|!XNoxKf*NFT-udu$tQA|}l$6u9 zH3n`|@og&Y<=td?n~1Kp5WE~ATN>*Z^mY08o{Z1j8Lst?1uYgeIG{k5Z`s=eO9u>H zkhVhWkAWi-X%@B)=%Nb%h^nFT<>*RGa)W1aZ>EQd)OW1S)t_xscyIX$b5rBS%V7|j zHqM1Y09{MIylYZy+O& zIv7JZ=KIH;eQUhNYZ6Iy9Bn@KqNlRVs6S@Jnt!1I*E$a>&8V%4f*_~e!RB&3LL6&0 z#j# z^_mKNWyh*aBz285$Ar$qIdRGhS!Fn@LK7GC+-Tud>;E}8e(2t+uu4@CN7wZ;P_!|0 zf&UZyDs}$}ehbKW^#VjE+O9pO45Sw-8Lar0@9p)mJ~GVJmQtW1q(T-lIa9XUm_ohg zGJOXxHQMlU_YoZPB8Gf$%O2f?RLLFHDflYD&oq^YB4$E;MxQ|t7sShNL(;)LaOq~CLmK}=_r?;fvZ00ci6frlOlR=!>|QN_Yr zHP`F!u^SWgIk!Z-($C}v5;)ee-_0r&aFTLI1Dm4aKi94Ld$A0Y3kZY{=o|Nh2FO>^ zLB9JzzemYZv5Lq5%){n8>=GZ$meS^c3qKtGr)rwsO0P?T^W71$5LVuL6kDu>riJ(K z$KKdXvGpFk_eA?)#AT)%%KH<9Y}t{WABPTH_|X!Eo0?OXRi486#ge;W@HYPlc0E%#r{l}nf5#qI<>q?ZNflno}sS29Edb2))$wgiULD$Sc5ZT^c3$AtfJ)ad^~VqH)FDDo`Do}C zt{$fg&%zwy?vLNm9yXr)Z`sT-YVUBA{E(m8>%7(;UhaMRG=FN(m^B#qw9Vj%XMYEZ7A0 zds=|B1zT!~$?~fH4)_TQpWKDfYR_4%veomL+YElak2G@@$&fZ;!@JE&l(JVPY`*tv zwl`IiY3&HB+h@Iy`Uli*mwT1P9p1k=7a^h!$B)u&`006N;FYgmm$av~_j?6Udp=C4 z${cAKG1caVb17{M9TQ079q)vHE~-sgnXVNZ$8prA{!ZJVnC{UZW%_EJCqSAM3t+1uVT?5zI!y+lnl^hu+%!<+BNFXiOF8 zeZ||3=lD!@8GU=%rh-e!!ydGB#6mq@_uPA4pgP>;fE=v*2_@%EAN%?Ix3Ouzs^mpp z#I4C7)2Hf+2S{2==Y^>QX`wNQAYLZh^+lS?*>ERM(k2%16|BP0nB_z^AuV8AsfHHQ zgZnuK-0i*9HaFk$FDx#GukwK$88dJDN{L5356e!e5UmS6gtq1dhW#fWCUWN++k+%Ol*L8Noh7XmmVUK9dv$X<@M%wM zK+3*-kD+7rX^5wpyW}ztJFG0*C_FpVXeWXDYzEAcpFD&(?`M)*f+f*yw$FdMbOixb znz>rR!%rntXk`Ul@~OfWwo=rsNkCUL}^V=q-c1Hl9>Aii2Uc0l3D%aS6Esv_^ zX-H-an&jE@hw#@QAJF)6AyTsoAAa1vhxj@Rv#XhWucihFh9p8-MY8|X=hpji+A9)0 z-rs}bZdUWv;s+@mBYK*-obz6WXG07#TI0o!=Bc_OBQyP#0cPpP_ij!8xl})ch&F)^ zMO@Q%p^x#mp;-c^a!818MQ~|!3@rkMdN4bh19nqrZAV}i#}-o}=&#>zhpaUC3ov#< z0CK8^jCDzNiC|bK za$?qd#Qy;U{ajj3g*!0w1!kWu0^j%{1n)#xkr;8v14AmELEb z8R3GCG49}a6RT`@NtP4&Ui5T=FAX2je)#FgUnkM&IC=2{1yjeHU^~_WKD{81X?Ah1 z1?c0}M{o@9JBZzl>YV<7oCs+P3F?WGyZJ+GZ=VWmt81Ifvl2%15(=(KuKBT$OQ9ZZNw2SNn$8U|M z`P{skdAHeORpAq%M9${JLvTOu$I2&^lb6jBiE=jl!^jd|BF2NJN$K|;;zL6^=zdU` zQu=8f3M05_n}FNtO(mjCGU)%Nc>8W2EPSR(|AR62q#K(9BeC`&$-9RxKJ9d&(|CRC zHGleq(A*FCsnmPWbcs)WQZg?gilKl_ut)f_bI-!#eoeF30e9)~e*T;C-0BH! z1}w+dR3Ci@8&ivTh}P-%biymgqlwSG6bYaEU2?r>%zqsMqV2tFGid|(`j<~j`&i`o zO^EG^*0bH6S{(EV>M{g#k_GkIU(s!}^%vy0 z;&8J6Z}nbaqkD))jkSx=`i3Zz-019_^|Ds)E$4(??$OYVe5#`xiw;caC#(6Kp_J#& z4C}Qg17yw*h`)hREW2O47kr5L*i+q|!7_7}aoru2rXT`r+T}d^jg&+oH3ApY?d4Gg zGvBt$3z&ILJ2QhIx*esJP|~j=on9ewQ1rs+6XI?H;%y!Bdc(CU8{1kafc*d0US{DI za#mR?Arf-A^XxdRwCCKcYrMQStzK;2#6^lzeQ9M=*M6YHZ zT#G+c|IWTC+c{nQ^DxVM9+<)F^PJY+(9_|}Q~?bNIJBvr=T0{8w4ZKP z?bj3pJNbTEsmaHy`!nO+5~LyYXE%bPh|$InBNIgen~mXu(lKa+U8zExU+6Nw#ph$< zP_Czz-rgpx`=+FB>3kh$2i}@u$fg3mr<)T+I_L;NEj4N79Jus%t+^^Rx)lv?<&K4! zeJx$D#@jpQs2!E!|3k|%VibvAkOk%RdCG~^12*YuYnIkrO11rl`}?FHo^59|Zv;Io(kSel)0@vlw_h= zV$E5|+`Qj$4XKm@g`+vNq#-x_N+3w#z<6ed=Sl*n9CE(l7Ir zq-@2TpmqDnlZK{tZG_Sc|CE9t|4+qS{N1{jLKfH00m)~_AA1C&lOjb{Neo)DYX!Ww z#iR86g?>tY6!qzo&msPD@72ghm^aI*E(}a)1`GN_xgwAje}i{3uSJj*HaFla8hF!Q zGi9UMZWr3M`ZNhg|FB%e74f~H@#9>Z7>cuk3!Hh(X}^p4v^RnC_?Rdm@r^t;AWo_v z{etsmUimmnBCvb^d(U|SrM1!Bj)zTGb&hEs*(Zs^^)y2~70@*Zh*L|CKiEpX? zoM2@lGV9l#M_mgu34W@W85b@Z1Ns~GezXFFAd2|Z;A1jg^7nACpL4e^--WusHH)nB zLbhp_=K$>npN3`XxwhWDM89IzmR{hE_^B*e#VT8T1t@-mJGKZJ? zHl?)F!Rix0$~)qSil>Qw8Lj7j8WYQ>M;!!J!hK_7wUMjcyV&QcK`B{zq#%1yijvmU z5_ZTR@X_D~8|KqEie{sEkCz`G}OOrmyUHIwtSnv zA*aiiK7C8Ceg3s1NrG?|y-#?^Gmn3`4MT|yFbvjN1 zQggBqTy+O=l7W}vp8*9G zCZhvz@%Q%2bDyCS1;DK2%%mS-NWLkI^R<=f=M4sJ@PQ(oc%kJXx8KEyg>iCy+h%+_ zT4dmxN<=OgF>-25$ZD7k8c7PPqfI+21_;x*5k2lH$H!rYH^B-YoOJ(7j!)lAObS8` zgS{3#YR_}rV}w<=X|wOabo4J5ipsxcff$S}!z?}842G`?dHt02Ak?h>l}TU_m+9&` z9B75p7lWkexP1%+;uW;AG~18K=|3A|Oq@H|mgW{4C}-Rp&N*n}Q+XF&{pC%BHGp8C z5!8ik^0m)R#B6S~>iovT+V;oRO3tsdBcPO$RvSwn9K%!3r0h^!%@1dRoAsA&->JaYJLrn(7z4gCCYT#JvU#(ex!Les|@5;w=Kp{gI=r#^S>MFu9){V0A=?= z$~B-pFIfthnh;@46WHbxF=^8^=bC5=_RbgjmR9~FTKog5)kPVIyj%Fcsqu6I0+iBf zGEXunEljok$x?~GdGS_0wxQCzO2`knYWB;2bU}avM+^KQYTuKX+cz@!JLNZtrK(hCn zbsdzF?l@$rzqW_G1F*}=|oUrxU+l&&YXEiY2~{;o8P zKFJ7FUi8bf#ggFa%9rQ$ZedK`zZng)w$n5>H-8i*7>U4Rm2zXtk7Gyu_XVFOv&UbY z;QSlZpT>WqDZu%?50iDu6>1*ftNrrjUh zwBv$ot(t7k@!ICT1>J(6pTAzM`_I)rgma+A=dl;5dgAVl?5k#8LZ>>Tj#q7B4TAoC zU3PKVE(a->yv%EOBu0^f^~kgVp3BPHLfQ)*so6Jnxwcsk+d8&eZ71bf8d24oB$Zk< z0PCs`3^N^%7{^I-YHpga7n>=s)o$0QmOC|pC!VSs+1S~BXr3l`NikbUh6@YriGuY+ z^W7CAhcA`5bE|o38aJ)o;j6+^Fofit&QACa5<9Qi1Q?|klrrDa39n`4|4Id>TGzw3 zFe!{Gz7}c%c+woYvs` zbj+Wx9JG5{D)FkBOk09W>#XeMX`5M3esp45#t<254055CXXiOofX`M@6FHIiN_-+~ zaH%jf|C@j~0}!AV-)*7}?gzmO_me|vks~^sPcI9==}-WO+A|$;+5_qoJ5>CkVO8dv zGBDz?aMx7}T>{xt+SvDL^2tii`?#X@gLtAH8m>OBUeD!JIb7S=IP~i+d~H6{7xsRD zVO=SXSXOc1_Ta<~-E+cH?%rm8Jw{}%X2X4lnVolDG?a#!QXhC`n3G>^)`IXITf1S` zDH$EQs1EFCWKhZDE2ti0G#a%K=oD0mQS%Dp?=>xxjk@~wkC*UgJ}-%iY83B)?NkB6_!$_2U91!%AX@2_a&rhD`X%fIFzdwy zj2#8r+aJufdhL-+`b?fJR(7`EzMqk_ydO6_BStb{GWQOJTj6?qcnb!+>V%5TG85B? z16Rh7kd!BPr(-*QQ}FmQ6Rp^;dDEdk0%FfB@Z`2Al+1+&z9;H7z#1|<88|q@u)YS| zl$8$I8}f2R=ii-R`1hhYzv{io4quFRIROY%gkA3m& zqf-(V4LeEaC(5Ct`;})0z5Sc4GjXY@GI=Z!&^$%K8z`&SQAFm-oWbC6hVQrGjn&Gi zNnU#;42Zue?&!mB_JYd>TGyB{9CNqXmxCu0h+)#&{J9Oha@Uf0x7CXVVaN7)_Ct+(3mxRE+GrU@C8 zxg1M-Lok2#71y5F<47`|{X`cyA}NNPM#yPDN)YgoY#sP_!nXQjEI^<%87XwrHUu|~ zu@*$y=Wg(qWZKqzUZi*NAEpK6HU5oj64bI^Knkykh>#6FsNPjuj%a~xpC;Ti zpXya+XB0H$76;a}Ju9k%9go+zTj-j^t9;Zzd0M{Nh~7of{y-sU-qcrtc*YCJ6cqG0 z!TQk2|B-*$Dj{Ar8xONW>7x>{DNy&Wv=iG`v-19RXbhK8C&u-19rWQHn02oDv8a%9hg}F z?y^($*httZm@pMXN1ouUar2c+(w-@tca`TDtFUiC9$$va&N&aLj{e`S^`?LX$A?YT zNO0}L7P-sY1Fm3&x4KE`eNjI1eG%IGXrM!-AzZhYm0$kc|MvGl%Fba&L+&zZ{fl(i zKz%0ynd@VxzU;C3K%X$dZ23KtHISVvl97Xs5wJ` zr->CkUi!K{q%C?#It#gKE5dp?I0YyP!6b^-7S^l2_jF@|%KnVtHRY@8ec) zOu4K&k@j3%5P*0qsu3m<5hpOe&p2g;@Fr zE3rRCT8%P67qan%5gm!k!b&=-X;6RA5ZH2&jazo$eal4-(CbVu@Y)@ni6k2_loQ!r z_A4@6HF$fn^+%lW-D}v()lU}B`ZkILWiq%z+PS*|Uc}%^+ zm^11%9brfEDbWBNFTr&IBz*PXulLO%7GpBL29`^@Jxgu_{%4-#>eT;j-$mDdu)g+B zI8!!$%yprHggS@tCK~X|YpPGQ2S*r`%%R4AJ(7NX{xgcBqJ_5rCq5WG7hWnQWQrqK zQzlC@wlaig?<;jd#`pV2Oemu=z{IY8+gnP(D7vI`xjvxjv$L)Pv!_rC@vE!++tQkf z{$q}`_5c@G6$xN8b^JsVY^h=5#y9bj4%XZc_4*iecBp4#Dbt$&=N5P2zq7u6N0CUx zD2t+B`h8Rv5&S-xU`2ds!f_al6Hqa)mI}FC@3~@7{UZwpTWV<``t9yKR2+~kyWc1s z#feTfu=drTtXVcTVK_$oTFzw2;77kC?>2`4~z3zuiVZ139G7x9@aW>54=c z=JM1_mu9l?(10r|o~Nw{5m_TzqD#{&X<_w2K$-piAUMn6&~Putb(*#a?Y#k(K~Rs6 zrOuY~zO_c!Kv@BOhb2X5X4-^#&3KgBkW0`w3`%mEn>yq$uh5a*iZG zfzp6OGW-&xTkrCa+Aig$xVkov7ki&^1!NUNOSfHTUWZj}%W}b9JSN|y45AR6T#SP#KI13SuU=VFZmXN`I6iw@^Y3mRl~gWHw*`7Joa zDX-}zw03m=tq(@Lv4lQs(M13*z7I>_F`B8}?uxHZY;QEUU3~eu0@XFh-F4_J!A9S6 z57_UbaC-~X@_3hHI}~8L-Vo?Jnl^md9D98O^aZ#|G`>G+(oeOEdQ8~)sGx!Ab)uQC zBavy)fpOT@7B$I>Nrv7aM0%1!DIK7gYX<^fmT%Hvqt@n|Cd1Xc&A#)%nJ9g>BNcMe zAAFiN+NL<7$)80sqMR-8J)R@-8$(~qLWe%r`lwaGf*@MuYd(bJ12Z|51g;OU6kYA9 zynO5jmK;Kj?cwx`-Zy8{K7N(_UP79OOHs<%tyn6?)_M0N{BZ4wMhg0}FVGBga1k&M zHt1dK<0qR~+J){F6OU6c|GkP)pH(PZj-{yigt?)^t(lzIqDc@EbXGgkE z8yg=oX%A}(l{H#pBnhd%3neu02anR2jjeLcm-nLFi-S?4oCp;H zK-4Xo8Lr@08*4Mc!h^BqDibo`cXB6ITvQFU=Fn5wqF+l(4n7NJx2U-Sg)y;7_Iq$) zTE(Ea6p1rad`6Dr;t&P1o(#$#ba%t@5e743Jg|!&55N&2^`RTK37z+K|1~&^!)R|1 zlw(pAiEl_|^v&JKEnRYyHYB1);Mh|xq3-_}b4s&+Q|(;wFo zEcd4aTIVgVIOr(cJOO+b#*TEMC(I$nm+5`Mejw3!jE{rjA@kK9ma0tjx!C`xDVsky zH&@J=!<&J84AsIFFqUU5O!#zr$skb$sXwO}nQ<2J=x5eg$%~{)lRZ=C6YvT2KQc@i z>$ina2Zlp>e)Jb>X-R1!O}D2l`RWCtetz-5#~gL*5b^L*k)#@oRq0Ngfa%}MD|lsg zA-J@NvM_616dh>eSf0sdS{3eTw?LNqZ$tN;T?$#~8wFUjE#OoYE(&kD;k}Q#C#F&_ zm!(b)%a0M{{+LeoKEx+D*A^+|9A@>IJC$O_{c* zQ(LZV$a#wO{NmY$dRCT5{J(cFx#yqj$(rY$6a9!6_rf>obuP5E340_qEB<6mlNK>U z_`mRzMI52e|GZW3c6$3ucPsqo;aOl_xovIhSJI#I1kfRcrviCT1y2&+NWP;#=qg%R zUlmpft&)AyxASQgD#^PPRj7v}1z+H=wv>$Le_)pziu`%?*?B~VlrkFj$fA`>G}#O3 z)t8_Tfyi;yKx}(>dzuZohIu+di1MHXbjHM>u9UKV3E#3H(r=y@`S5NI4YDS$mGpjes zuMyHSg#SXCcK#>#8%lq(&&|hpZrgy=LWYG4NUb(#`np{)5y%O#Rd_srf58*F;oq!x zEDZXC01EA9^NP%vk52Y~QIjanWGYw1XN~t^7M~|5iJwn#)vFumo9b1n{W$|&GIqQ@jP5E*fx19f63JH4hfNyph z!0oJE7k1=+2C2)}Tz#nJeez*&f5KU0!Z*#xTKwse>n}^d=5{#tq9?KFI*@)jJ*U34Tga5ho?nu5 z3Ig{ek)2BW;O>_0o|@pXy%c;}{ZO8_)Gb+T-;9pm- zhRz7=<&&|@tIV&P1dmjce=CI4Fm3`htXP^Jddj(3)iGI>tK2-}JtsAE{g+6>4YHO( zpB1oz(IY2xPf1)KAe2|HW%KI^-@_s`(g>#sE4)bzh|e0pk<4H zBaLISl_5SlL08~tP>`1*{L}oC0^S1^y)%fIk|N0k<|X^%yH|pzRch-^9tFe4*?!T+ ztM}Fs13O?fXfGAZR|qAKLXao!eBEYtmy)Yr@i~22YpvSHu8*hM4*Q_tX3wVXT3Q=U zpt2hzNSWBbRyRC0f$-b`p!_>yH8a^+1AN;gsWMNlgW)-k6{6H3QaKsWYEkj zINM9;H115>NhnCtFx(z~F3rp7ui>1cE&a@nig+yk$DXnbfUQU&OW-Ovsu_aAwSOt= z7#NSiWRpbd9E$t^QZ#N6946g0N{rh^Bu8ED2@!dRsDI=nOTUANNC@fSTyJ})N@1DW zk$+C6@;EMz$21Lo#`Kv%Si!0?`6sG)CrQJUc+Wx}n?hE4*sepLsxKRDitWH~GNn5l zb@MRiZLfMo(t3CQ(|0KEZLAf53-EkP4vF1Q#a?hi^32AW3whW=)m@EiMQnAEk^iS_tOGc(oPF6yt!qsgmx$P^z z`Lr+T-aG5&M3w)-!uF_1q1T)jnFu6&-N3S_J(2u$cic4NEW(gbD#sD)HFrnIi>u%` ziTT;jy57Qg-XNx|EnyIiKp8XKRrfu4E|HOc2e!a_qdwg(|KYUyZ3no0UjJ+Mou|e6 zYjO!oz|;AHH{iM-n-A7WBvC#tzy;~_) zr?c;@AIHKU!=O%Iu>1L&A`0bWlzKbeOoehjhf%xtOr+GPqfidZ&&hUm=^4mHJ8}Nr zqcHt(NFj3sr`ca^LmQ=>voo!*@@&R1I2XI5SJyGv@&46huXs;x}k*{~q?6LgzZ;TckbRqX3k zTyEFmbh9GSfh&2#9n;AJAU42 zE%F4Ez)4bqBDC*l78E4A94|~7r(!)d4uc*(RvC|Dey02y4U*bM4;s)MEk;8zDnWVS zU|s|NY1)8Vt1tbOH?=R>CD-^uz>OZ|JdCPnAFo`$l8OY@bM35zTSug>F2#6AKF8N& zfm-vIUinaz($$|Q7*8{OwO`>pyFYRKVwRqd#H^~BSb`srE2xA7AQ|*Lh4?0O#EOoc z7oDnSyW@Og&{CL!ec%?ON@=Pr2X~++dPx`i)s(R&BVTL7#!Ost9Ii>Lw&uhn$Eb9E zrn~EYCF1I@n>5)T`z0Ws*7&E_EAhMefjX1Hdp;f$N>YnAtT~5!HD_^(=W6@_{g*qJ zpS%m_El>I6FP@&)`VBemh<~JRp@s4A!j_ElDkfwH33f81)3L^_s_hdK`(ax4O$%bN z@wjJR`0sVwWZa5^zkT`j0wojV-GMhwjQ{u^8n4l(i_MtT?>P}RG5Z~O(UOnw#mbdS zv)Thv?(0emSCWNuL%Lc3pl)~isEQc)*uD6aUZ2S$7nT>*$QCgU(h{`%Hh%5mqct=l zdn!k``Ue3a4DmP)HH5%)$r*t9`Oy+>WL#I~@#4nfX7|)$*EtR`swu5dg3gj|2)6WJfe0A)IN%4dI{Q?-N(xK-!<=KZkA}Zxs^6Sp1*khZPR8p0HN{cd$eScnC-lN-VNWNH4+DGPvVh+)630WRsA+%>a*# zAwfpm29K*F2_LoEsn(_~ZsfkEIIMo>+cICHg*I$RNj=th`+8W4>1{Ec6n``Q_03>q z>d!L_f4xfvZnbUI&QlSIzH0lTRb-~Ch!G_6X425`Z`YZG_k>{0tgg`73uHxRA;aqi zX$_73L$8J2oKB|*cKxvFuLKh+DqMTl198f?N!}kjs@R2VVXSif{ggRVx)ZnK!YJ8A z5sPIr1anw=zQ~DnYA-J$X|Z9JgN2WfobVL_-R0!9iN}3y!)sO39x%k2_59E!xY=EB z+Fr*_#D0&i0+zVPEzbVef~c*Q*6MS4yNHx(cyo52KoIOT{S<|{UCIjgXunW3+sTy? z`90B71qp5|8iqub+g?oBEN4(zgFA=c2~rLA%>(tV#F+ zh6WaTHOt_qW9!`!^*=^YYn}7pKoClIiE%tk5fs*H#y`T;Wx;qKs*q3?1~ipJ@NbuN zO6|w=ksnbp$O-*&6e!X*h zb>sKQklt#$gM}QT0?CDngM6zGyi?ai{sH7J({vBF)rpCsbFVcIpgqt?=$^2_SJgf5 zV=KSFh<5d>B=B}8g!PBG60`Yff9-HHLhr(teR=DNL5W; z8KpJSig-a!R;n+Yg#3&jo_#;mq~5x}=|lhfLJg9S`w#kCmJXD$Uqlj)D9};+7bPEx!#U~eYrag+3QX%9BfP`i7f6Hkz+Sn zoo0iAz8$0N0p0QR@3X8}akf$f=Iw6td< z|BnlRCwSC-7aglDI_zrt23XcgwP-o-K6vOW$2N+)-#^47(-LJ@sp@SWUqHw0d!~Qf zv+3#%lqKML904DJHak2%LTSCJF)_(cZ9X~eikO@>a(iG5)AGu_mdfor5;RA!9FnSm zs?4V8ZH`GJroOZ#vPU#!cvoUNyLb@vSB; z@0Hc=BEuO7?Ld=1P&AW<8gStxB%sULY#d+urEXSgNwa2!w|PB9cC^?n9^!t+O&7p! zeu=dm=|@i1a%Vf=M=OU#3(~-1kn?wJ`l7jy=o=&Ski`t1*R16WrINJf=`4H@~hw)^{HQ5lgzw3C3#U=0D7Ge@!YKhtt^S*MDX z$e{4#YX?D-@VKW+sBT+{T6=YFU<=loxmvqrY{5S;pSPxTP*!pfJ-bQ?kEnLo4-(ni z{==$$ABfEXM@#&%O33LNOUroK5^lVw<6_>#i?kwHp&o4}S5p#g7YJ2$Ez;CI$=y@Z z#A%QP}o@KkKiz`7ZYL8D-n4ZkXISkPxjMFhFEf&?FW9H2RE56>PCGUt z7CrD+baa<b^Sdb*xRK(LDI`qX#U~_h1So zjwZpr*;fU1v<50%%L~_?izpF3?J(Cx;jGoTdGGS|d%-CEV)dz+Hv#ILSqV@%wEzT5 zzNrM0RDy$KP-{mf5@WF7^PB?#F<}SEFprz)(6dQr8Nyo7xNwW%$SejJlIon_FC=7n zTh_9)fn|<~;~34@uJH^P7v|7F=c6YOsOz8G9FEby+>bDu7Pv;oQ6;qdK zk)G$p8_*BOr0zB9O^$45Oy@bfw;o6zq9o?JG~#0q1_F~Yc~&32PY2o>S!nxv8yi0c zYVMwmM9q@r}N*m7gNj<#=0h;t?)tIIkVN zh%C@Xw9H7o^tR<@wt_28*ds0g&VYYXDt1z~(FMoUs03mA@-@~G-B>xTcFb$AeCE|_ z{E7sQHZS3EFB(ltJmGm}8TG6ZVV}(oZ34foeD`fuq;p6TDs!iXw5^Ui{%XL;tOm~8}E!$V2y{8Ie9=DH( z@lL=5V;$z#n3xLUK;y^;bS&s-;H6Fj9wfRNqFkqsp!Y1XV@L~qc^5!b_Vxko0 zBpceRmKG~uHxBb-SxBL2|GY=`7$}~;c7Gv}lf0$J+jv7d=bVm8Y~h;n6V%IDC@|=V z6_9W>#tjPRwn+kA>(~5LwjOGx&l>+#tC}mGCUTi^G4C@Q@evvr=kEwrgVREf1mqy> z9QH3hdg%O?B8les@KqhqUH&PSlDjZFozca+?l2bnWGeLCZdJ=)(;@$m-gM+QdHuUT zFej;VY(k?>%+ybAIsr5F#lKl4TsA2>C4b<`=HUJW)3Y5=uUj2UP@)&u=P6J7knlT!otMdUyFyLL5sMt{iLn`C)D9 zC~GoVtgm&%>`vFtB&9c^t)P6ncrA2T_duj?Gz2{uoe~hI1fGs6>k8|88KSEq=$iLE zQrA+|E91mDe=-}soa{uZLkwU73~c6OIqp=!5c2g)x`Zb%Vg<9*u8*p!fm}q@4hMxN zY0^9)w&}$i3JKMGPq_bJoPnx(3wzZ+AI6rJHNPB>y5Ht}h6RTc@h@mrn4`Vkj-)9& z=y5-KxQNJ3q9nO(F7sPFg(epKkIc@7+dfD*_u=@|*6URO-5x~8VO-U;<;3||R~*=c z_0H@GPTSz@SJ0r*pL7ntRDr!OLC-TplxImgq5;`$`}A~LIHzq7J@}&x_sm5&ZoHNw z?3iCqfeOj9%7JYA$nDo@0Pgv?;fg+bjKHNumgs*EW`e0;EWe%SW9=Jp6fG z$C4GR7MkzOSQhK;Sum^x)3J_AxL<=L&e&_nPivdKE-c`W^WT4P0p3u|H3pMyK{^Z? zy!^uanlND6H1o3d#Pg8TGXK}4RVQhjCny%|>04uEbSa|8iQGD6h8=FYFC8SP9LQ9a zZB)@;Gn2nB6Nxtpe;Hjyw$KS^De&p6^IW@QwF`q%AD9x}MPh=P1J@9P_O*%4luDhHxd zB*OZFwiZOz7S0V1GfwH@dug#*!J4l=d z)^6~R;+`u}RdDa@pw}>dJvxiU>nr}7;zXo4YD#*?aGxhb4vP{Ux=ok5dL_f#?{D~e z`e(fs#tdUdrTh7BtIf+0Poks%t8YZM`$bAq^8}Kag29UNQz`eIA3Q$uoPYYS&jpg+ z+dy10=?v%$eiBgfdn>~cl6P^Vj$X=RL^@QOl1EkY_T137>#}?EAbUy35feCI70J;` z;z9td!Y+$9{|rVTgBmR=LvhQQM&u>!1K!; zvVJ^*$m_im39r(JSXyBk)4Yx~8LRnv-OI%yg@Yp-rW*t1teRR*lDLnIl7p>wMQU#` zc&@;QxPKtZ){ijdlZ(nm=|C(G#HP0t#Wb)UUn&mX(|v0@$O_H%K#aN7lYaT2_C zGCOy3=Jp4BloXCVg576``vpK6_Dsv1zLTCXE!dxU&^}dRm$DJ_i<K) zal@U~^?q012Vz>hrBF<|qk%bNI6If)4k`4=nC&uY!7p+n;`!=4dNJ?qI9ySpZ_@A^ zdefVU7_Sdd^W$br*%V}KPd6-29&<;%EceZ_`ocjkpBl&dW(jo(if=kmC|K=l@F=9( z6jy^ftl{hur}JY{a8CDyCilEiw^T)27_Og>-GJiv?f)P%8Qf2$}@ zX8LOga`Z-}@iyRV>9TwrO#`+3w7nxXCZ(H#!)({@XaQm!;4(|3{FpRgh!OD!9CX z?`cQKZiu~ydp2n_!4rwFbSMy{j&WGAA?0&jhFEU=@7gVDTJnClhWro@+QTqNuEg3t$24f%!0ZOwv0 z8Sx6OCyy>OmI3uMomo?(1|lyoHlbmSn0PCO-YHRS0%^b3>TdMUdRJ#f(v?MT@2qJv@F>P9Xe2KfA5tGoc$MLgLkGnZ zUnrK}Z^Q^Bk8ruyNseCRt%Ex$_qwT`|&SR=tro@Q^*Mw&w~VI zpnd(9jb`W%=m9H)I62)&&_aM3N%wB-P`9$*+x-G6u5nu9tMNv?d z2xBTMwc7lAG~!$X{!t9>S*+T++(?J>eM;Tq;iG+&$=A!z*MmK45v}ccW{;1?KI(Be z_gqE*^r)8o#D3hRHJBJ;HXG6Ve)Q&Vkd>L+<(VF=mLC@#E#Ff(B{@d_!0C`|RB>i_P?bM`z&^?oY>f!MvL$~H4QsK{zZ`@^DqwZ~p` zf{NDS@+L=`&fv~%Vab*G-DQK|xGY{qiPSIP#aNYE5YYpV6rDP3CN@2BqBNMWz?sA^ z>MnvoIq~4AQ>BLqd47*Hvt2H#)@KJH^pR!XQ>%;U%EkUV3kA!w16skNKBmP<9!=KB z3iH`|sfL$N>xvXP^DjGcS}|S^&BPx(?7>|9&h&Ba?lrkN$vktWKqrJJv56{<=#$wFUwMe3T6FjL@n9ZpQ zvRYzEG&Zh;@`5r=;KKs8GIR_@QbN!#yi7SBCIUIEdE&pEG5sy4TdnkR%c2BK(qWo) zoLS}ZPr^YNp58eTRMJ^;BCf>Sm{?iMWhAEzWY zr&<3ne>dX|kP}eM@Enl^~C-(fR7fS8L!YH;qI()U$v-wwczznP! zVjGE2PqV*$vevS>>mDzF@NDTG+Xy{Xp-i3ZdKH zUeFbp|A*z}Fmd7Do$xQkB>d;w0>dwprLFlEmfX#@@?*#IVyy9 z+^T&vw$i1JyoeE9!y)HOJ14!|Mt&gg=I-n;qZAq6uyUmWAH+1}87b=gv=y|Q=*z1P zGK-vy5)?JzueN3$--n>iv4`~6?}(2jD?>A1TAtu0m1`VwK)K?s5dlXzJPvdF{oFHC zY0`hCHNt83pj_lO?i*4{2EOkkPblsU>!@;moje_6+&GN2j z#txl(uq{>7=`6e=HbSm+_-R$B(5tL$J;d0pbZT5TX^49*7dE(N=pg?4w zi$yh){ahY@y-9jXu@BRw^(E6Q!9hrfe^8zsmiiEmfs8zYPH3BFV5Ih{_Bfx0(JdvR z!f@D&aqI3rZFhMKxx~Y$J}Y!vzu{H#dTwlZ@}&xsjMpk&iTZEfzE%doYN9G0s>LM_ zJxWUl=4H3hGJ`Y!lUeJpyV3~#<}WY3meb1-Z!*dD=VzR}eNxS1&13-@-3xZ6xz8Rr zCH_wFQ+RJa%5NL&nl`80s0i3t{i3lq5{)`uXo)kk2frEXsG*A6255eh-EPfo)fAGT?k*M`f$e;ie~7O8J-GJ#X_V>|Zj$(Qh%w zfX#mk^;0TC(@UtEI{Ii7$$9xbKeAMovz zjhwAFxy4kzyGMAGVDEbUAHUjis&ofuY$nN~t^SYHC|luf&{FjKeNU{|{1hB%;0q!U zT(&S$KCG6mSgwdKM4jy&9N&-+;v$3T}``U zVzrj=Yhj2zLh0sHU)FEV`Zq5E=VO#THlSgM;batGPcYoj=rF1-iU_IyB|^17Yi{U{ z%@9-#Zu&so6|{ddCECFH_#xNUn(1wP+^x90#{C72pv+Yf$s_eH9mw(1Y4H2XwNkmd zyrR<}+_<5*9#|zO-4|UWy2r zE%qYbl+g5RVekv$F-!=Ugd1;$gpk>B{@ReOnuDhi+Z5=uqbF+kL2nRZf;<9_qYs6Q!@l$ zdaoy>;E~)Gpl3s{v0oVOVCj_!31}BBD}yfZGBSUwyevBn_?*xN{(^@rnpHblP$kLP`JLog5Y@(Ui{ z(iv>6Qs%%2Nz|=~+nJEPgbXXDQ7)#FHqnNh%X}T>@G~o-t`gdYz%*b)bjo}0$;)ms zOF_$ti&G!D(G{x&}DC9m#(i3|rwc_kxk-0M&CE^?{<>!!u;cos~Egi~WOC^YlVvd{>HReRdZr&y%vD)!XOnnT|A^iAl1o{?vsn<=6MVNc1!~CG9+jZ6# z2b!}S>_k0{e1{CSQ#HFNgMV21qFrPG?sjx_Xm!g$6&Zfo4B1}}Gmmc}wBwUuGYcpt zj%=-Pe&D+iH=~RF8+g-lao+|0jM_uESJR?FqO;v@hn;9iuoMbB=+~ngOS6n*gXVoK zB$4Q(V7g(A|DWiz_e;HX_z0>mhMuS-8+-F9id9GB=Ur8)Gy(ei2ir<>z z)D?n&+t6&qWzKd;&J2oN?lT1q5Co2ZY{WFB57_} zsK|N1AJq?Tz~_Wf2*m4bW|lEw&F`TV>!;#sU40#D%-@ z-{+t3*hA|2l!*I(<2p&0VhSoH+0DXDAy~Yzba!8s%=+7lul3D@^e40^@JdFvjsA}d zurzoh2Yt+pz2vo+6!Y(*LBFMEsuN+kozD6Y=u>#-V9F300TP0LtU|R%+*@yLdm4@x zky(J>jplW_)I|>=AEWw>rm$vVhQ5!VrcBz3+Ea$!cd-$}RzRx?*DH-^JdA>a$`?bH z$#+8VL+?A1*G;|ya~VGA_5yt&O_?K}S2yCJjPyS808m}JMV9YD%FtSJ#f@R-&6R?q z^XA|=PNv1!qs{^Q$IjBzOBR8dh?D+g0wlVo3#JzawL!!Uji`^P4>ri;VcX}}6I;R}0~ zM`KvhE7OhR(UAqfprS)H0HO2Vc(XJ1Vim>ym6>5|wNvtWm8#ZUNtrfYSP7JuZ4yUn z9#RPuHzxA?IEQ~dwz*t2y~~V~`CbAQ8%iVoWi*}5iKcD!()dZ;o*CbD=51HuWb&3~ zAX3cxCDWVcO12o(Uu1dP{=?oPee>gLNGY>RlidY)H>?Z)kZ{0HcD-Yn>BCZo9&@wx zmR{tW^h!79Wq07h&~^4Lve|cZE$>^r1kY+R@MW;OtNMVWr)xU z^$zAxRFQS5ID3ZvXBV-UZpUBRW11j^xA-097QwVNI>i>tO3E^ox@kNIhnHZcacgLZ z_Kerp;EXzo#%DWv3J(}f`@;g zXKlzFwJ(*Lk5n~CDFE_9{NksosuW~p<5(t&b8`wyGOxWjz2~3|qY%r65)Zs+hY{Fg zL@fuKUH<$emY|2FMo9jFXW>;)(wptD8{Ur%`W60C(ZX*E6)rnSp3&31{Tg!{9v&j` z{f+dwG@cR-R`Rnw|JZ>0AHOxZZt!Od3Iu{2nB3+~+$Z->^Ax!RE-Y^b)RXfZ7!4&D z|9j0+lCYmJW$Ovv03Rk@jiUQ(YRZ}3sk;7 zv(&`W)K>ZC9Y=sM2mpO{({@k@4Q6d->vLM2?iO_7Qgcumm^mUlE9do9lFQk$6TWaj zix@!Bko!AMQCk5!X8{2u|6YYKn^6;$yhSM8kCIQ;15uNF9Ad%DV0zK<>eG4KFzP)h zh>wP>n1mC30bu=iaWUPpGu1h)ERL#wJc}c}9eQlO$YEV|UiB;REVym<%>)ze=QP5O zI-TvZQ5U^TN~B&1j?Z`@&lwEYmT}fQzNYEt?B3&)1Ju%ey63yavR)971-;{gL@DfM zwYVRfy0$xkTl>#j?E}JD2_kNZyjaCg4MS3W{${wyn0OfwgpSf$1 z2bW^_s~G}K`htoUqsw-7**OIvx)`#|40fC1YehjfS-6ztthFDTgTIfk=u7PP-er9@ z>w^{Twx$3P)-f~He&{E~wmd%))+WW9lCDjZR^SKH*yB}Gmkl{{rd*BmRYl%(yMk|S zKlhygF){Mi%Lfcf^IWwF&q}L~x;Kqr89hJCg=|6&Q1FH)3TW6V?ww3jE?2e!m_m?; zaNwW*euw!aLJXPxGpB-Cv8|35bXS2^8tSPfXx1;l8oq`{8SBi&pq4v>%e=6_=q*f* zmJtZxgL390`wWQ(UHLV2t`Dy?{9K@T=&X7VA09QNpdn92Ok9=Y(5mlurl~|8q*u2r z)K68rA}d|7JhR-KLr&<*J3UlEsz@n}6jwIli8HZ)&FbOyA|}bI>+Oi4&+dKIF5kM^ za%mgYBey3KLDtq3gQ46#KmTZ??&9^oD&b~8D$6lQT)e;*gm6#prGBE8=$eb|gH{ro zU_>)E-}r7W%01au(%Q$qWnEQ_U7!>pQ8naljVQ5!x`cCz>#7Pm#zQ1SFDWT4)9gpd z?Ok?`X0XE(%hT&so&|xQbj2$7@X-n(jZ33Ci}X9R6x5A?qRPg= zK2^JOtPOW6(mG?UobP#My(+eY^)CL>=3ybU5qRd`>8G0Wx_3;%oHewxrV(YGx*bu` zi$tSIJxSFV8-64%O{v$ZNmK21pNw6u(2@PSoSYQrH#Y^H)@+*~uY2H#%B@W?MJtVc zn!lY=|K|YZIF#g2IvN_VQ;?7_n?T|3a9)KX4`o-`T8Q1qZmj(NtDVX-GpFpp;Epth z%+zEt_RO_)vNa^PsI$V-0~U~y7OiP7RgmMqWle3sKea&WehgTWAVx|(#ni$?eLvfr zGH#x7G3-jr*3h5oDGU^7F*W&j+1YST&v4-UXQf0z4Aj;rNE{Xt9~%B5C-wxYYI0`R zAb+1?V>=}!X76nYyd4`E9v&_yBLVqgztl@fHkd-=f&T8`;FF-hsYuW_*-GtXksji9 z`!GPt2qbR&bG3igp_wG-(?4ha-=a_Xq}Ua(3AFk2$)GM|kltg16G7X`vQsw-^>6s2 z;hpK1DjM+C)aiXD;Xi7tY0dLPeY=QA<|?Lh{C{k{W0WM(x-DAjGP~^RvTfV8ZQJa! zZQIpl+qP}nu9y4lbH}@HjF&$mGDk#4tjt*Y=A7SLhV!8Z+HB4KKq8jX(NCvr%H$_) z#5HSmy3oLqk4+sXLHf!6oj|p5#3Q`?pBw&XPaRU4>Z+xG{llsv?^pV33taUTq%2D2 z62{HIMeGhXOUNZJIAi{)COIl}tHv7zc^22=HUX=o&>x%VQ{D+VPwS~=Su39ZS zr8g)rN0)65lVtro`c?OT|4rxs>)XWt-u!>I8sI~ca3&j8W&aq$_89GeoKw&;Og(GS zuM(pF(?Mg078oiQgIBmM8O__?5-1NzGMkWEo?FqEt#mL(%3BsRkB1f>y23A78&4EP z{m)C9m%`G{F1PKfc?0NmHxOaDi4o?{3IpFJq)XEOb>sifTMbU^&)1~?e*gb(J1IB{ z&iB7n0I*93i6gjlId~3{sB%*=HfANrkGE~713$cT5F(sl``?<9ndOf0ZzGzm(?N}E zZsN=N$t$edO@tNE5&r+ZQaW5@=(a01@M79?i{V=R_LBxDuoik3p2NivBYs|!YR5E- zrd@(fdU(!zGilU?JW=`+5%YZX5^4Y;m#k7`mf9V-P>Nmp=)KKVTfj2J%9V4r3v%*D z;ADmaXfy(5I-C^HM!GIHL*8g`TU+vaG;7Mf(JI|r7&LFYSAOwWm}S>RBXAs?FC#YI z&zn-#=aW?yr_s<^=zWIiHOD={{|sdJZ@KuN7T9v!nMaY*aLhMWhuh6^4|g5WlRF7; z_u3oC+zs+3-Jd8|dX{N=BQ4!SWq`f9QMa?spqv60X6I&9$Fvv9EI{G!Hit%T!m}#Z7zEp*?Sea@$(GFCS<` zQd-pIn^9)k_de-QU@40;sZM$xEK?sD9FM&xt#lWynq;KhkIg*-p*-SQq>o+ijm89M@F!5<@2r zu4mkWtLx&Xk^1yUCg*ErfXS$DOIsAQ5ziF<#!O8_KQ|dvz%Im%P1`j+UHXe|@@HMBDxm%Z2_J%=Dg(%BJM_14kM8y5b9n@yG zxr3PL9(m;`M<+}bF3Ym=`F!f}yI%@)@Eyo<1k%!+Sz1+dM%x;4Q#9w7FGWcWFnO#F zc}w;Bm7@RJ9NM_u1Ca~`?~U#ElI+4I=!i~iTK~aV8w&|dE=c84fdG0Ww`10456_Ld zsg}G+lRj5*#BRp^(Nl~*iGabV*PVSCtZ~Yz#YK#{qghDeemqf8?WkbFhA-v+8ELeY z0vT4KCkz67RjZWqDVX#t%7@Cf%mc!W-&k{#$68d75f0i8dwp2MiBpzGk|mSQX_PlL z<-VFP9cj<&9JY@{%31?cVmteu!O5_CJuJXl_-tw@R14;n_1855+q7vy*%HU-m=r*0 zA&6{usxB!gMa$>q4Jz`7l><0KbEHVw!fQj3LcOlr>&h@x%JBxOSr%;<#*IAMq&;hO z?DwM8>_>E(CbX&{4HPG`)5-VfYv*8nBPgG*VdkE?GtGNLmUJa6MYd}v!1>bQqC#u@ zIQ#T^*x65dd_$8H;i<^!k(T^-f|JR$J~C-Z^0FS25WoV z|Jr>iLF7bHj|*|#`+*O92d196?_S{0*7Cj+ zMel?+ZG|^|k@&VD4XY4_9b_kVTH==8a)P6m{uP}6aPL>3e?}J{Osfrsu(JT zY!5kghI6R7_Ko3brTPcXpf(cgkxzG!yMQ!ImwmKY?DTl`1B%CEOl(J!aLaVN{*OKR zj`twZ7spJuk70GNa3ofL+6X-j>*DxG&vk$7boXwI;2^c#<6vF`obQeVZ!1-=kBwz{ zB9n{@1HL-=Ifeyqf-zVid`>&~;}c_!5bii5y6#+4uVVG9u40Xkr>l|9a!SKL9ZZne z-;3PeYjJd&>%4qaT~=fSybj(Yd}{K`kMMUd$LvsAc^iG^ej0+;&#$rDX7Is*))@r- z7aH?|O^iWpSZ!E>JYhdCre6yZgTt-*UA^ilY6)pEi1r(h!gOV&>%BAOa*j3>A){x%x+6y?Kc%1q2+-gW zTWNcnFIymnd4dS@meHFt7=uX;PxI}VqvF;OeuLEAV#IV4Fsuzok>&>BJU((k$(eon zkp|GCnqDgM^_7D*Y90oHNtu$4uLe77_185-bU|G|$>XFaCTGDbUIXU|ENb(JJK zreq5=Qizb6T0BgXTfxl^KHea5-T)Ea0$sJ`5dRYMwoU!dXpn>v$d?@Db5za!JoV4f zIu|J!#88)tj^_zC$F}8u^5+Wy!|#q*tN|(;)~-T*b)c7O=U_0l{kHQvw)1&R6|aNI z=U}z>?%6fQ?5%>tBSSz{u4*XvVa8)$W3J4?+AC@V&%8LlZxn6!JsB9>Yuf&N#iHes zL)PnKQ?sPAD@Es9k>cdEWrHK*-D`Q{qVA@}$$Q4|#SDX*?2G+l`!LOrxyBYByL%%l1tmgBQ`pX%?uS8mbQcH56s(}&@aS>ss5x>5Q}n#K;v z3QKfx(-z^2j3I9UccsryfPKEROak?Aa&7Fq&14 zUPNN>mxZ=sB*l^hf9UtH_aCWBF`#3eo~wbeVs2&*(v;&VFh$ z+4Rnak@1eFmO_^$RJXLOIP$>B38Ek0NOWL!ii+0o7_@@t4rZNW8Ot_Lg7 zB{N)&EPavE^_=`+{3N~6tvL8@=T7Mv6F1U=`JgtXlp4B0B^}1}JTZ~g38VLYmI24= z8T{s^`5xZ!5@CL}xM07(MZ%(#QXr(i+w17OAJ-Tj=<3|GJ*HY)HzFbCcK*=>oOK>^ z`yqx!Uy`#Rbo29$S}JzX>ia=E&~a00tAsZW+s5woj*|UM;DC~b&?N8Jp1H^E?V`Hu zO`XZ{=;s?82;*~T$;RigM~x(cS^VpEy(?V-%XQ)XZtFrPIx`eju11)8FztYlD2HBf zQ0T`$Byj3@jhaZ1uISw?}|Wtvilg6(PNJr z@D8(lk!Vj>2A0z=%_hp9(t5K3Fl|?Bc>Fm`{Y1P%TaZ}0LesmjJuHkr%%GA!G##my zgYzq943jjnZ^ zhw0!OT}Gh)^E*?~z{1qcy~8l*N&J(USxd0%#14sZu_oS*t|_jpdIQ`f?G(Cn=nYC{uE>r(`mLFo=5>-taK%xi^86(C_-l z9APH@_}|feK^~dFU7}F^U;%dk%W@+}+By@YfrS;Oj^|Ov6rb)&_pS#u8pdGJa053g z8@66YF%#>8KdTZq$rw2>tduw9V!2fBV`4yS$f~ABjGw=E{9F;uck7Vl96x2}Rw42j znVl{-c8)IGK%H;D^t4i$(<>T9GkRWAxwpZ0PYylI0w{Z66=yVLFOd26$#!_B=Q?OG znlu|VX@=WXV|>3WKfh*d32%7)r;e0&e4@yHMwGalA#QW`KYo@)*mF&oxkm#L_*Y_e z2PpqFLywpe!R3BQb>Df+6)icK`gdOVrwDF}yx2`M@>b{F$B4b&`>{)YEenp!(mS0x ziCL^uV158aBqw2Ewf*#c6`-fvVW^SEikt&J{;-Q5u#T;gC2Mpa5Fq#o!a8I0>}H(M z!0w)TW;f)sM_fU?_4|E-h~3bmPp?8Gv24!}y)aK>eE_j08-1@1;H&{7nwc|e$*9G= z%`(JnDL1CvWpS#;jKto2~_&eSrcwcJzQyi7nZOPs|BaVJ>D z3WSh7DDS?~gBtkjc<(F8Pymq9`o+<2If*^m1H4a8cTNjm&gptr>*05QKdACE;+5hayFsdUD;K&YJ|4z7f0bI_Ih;15stK?8k1 zH-*1u$yY*^dQp*Iux zK8NcZdRlh~@h8Mx>VQc#8nnVkiuM7(lV0%i>&E%(c|z5yg{l|ym$kJoy#njcm`rxY z!iufsupJz$>p>==z}cG7n$@CaWyAF^KoAJ%?8+5_!OQx4{ME+$k-u)`Q0n>9vElj- zhRJ}SK|5}?Bg>^($g1kRCfTM^gBgfRpp9Kb^?T~zcrxtXgk1vhF_&C+W^#c*3*@P0ASyf~C?Q8ugzNUD=F zS(UL$snfPun+OODUDIltPEKB%J-x7;rSeaM_<#tGwQP!ykL4P(76<3bHACDDF!DB) zYp$-1|KRn@GMnZO{V^-8`&MA8mdcQuV7MN&Qc)8~i$Tvp%Wb%F=zb4PiPbfnn}Wmn zkQ?zho5>yc8Mku&a=5Vm?om+^c*vjWy_mUMPB&u4Pe9iW78HOX%&+IC*iI3p zFwqK_W1+5B53GS5P2Hn;>M~*8awESeR$Q=A-Z#u5S6blb<=(XlYFO#bL zZqf;!!)dlsRvMJ`Q6amIX#V+3>;9==7}-u_hC1zF@UHTdEv^$jqk8VU50;=U){rdS ze#QEBLz!Pqa9#{Y^~xiK?%Aw3se!@?ZGtG2jat#lT9%{bR5?hHI?YZFi&E~Eta@>x zR=v(0zZS5LaTb=+X4}Ldkw_BawS=0w0!pmeP*v(&CVq9U49>cF5bgKwq2`GTJ#D}J z5k)6V|0io>o8P1=^jHD9L4qD2uBmlxk@jJmEDEc|la%qSKzBqmc>!GCNx1ty8wpfa zVM&i}xtD7V%5P&`loQJ@ePEWcCO%G#c;v_W&j+?jw4dEWS3!L z#C-Ad2o48P;Wgg+)&pP7zg&DyT86WMhdmSSGY-&1j}F(%g6$-d9_4!NF)6JhCwo9z za&vhjhV90{^;O2^jMq}Y7brr2aSw0=8*1XH#|ZRA#`!BM{G4- zRTCn)8ewPP&J0oF4sX2ZOH9OavCj4dS3=2ST5zUKC~^2-xpldhh|nbmrq`V&+)tsC zk`A@g(asstFDV)=pWp$!g<2J>gxe&dEna{v9X((F`6rJqyI|o{8Eytxf#hL)P5UfT zqa=7uJ59$_UUEbwt~88hqfWZSOKmyFisp%nU5#Wgm@R$6v{v2F{{|VieCy(x!UX>t z)LJ5&3jwGmsHB!|s)aKf8WBJ-hfrtpme=NGgfD97N?A(R)TK34xv5IV*CUD^O;%3F znA&rkYM$L?JAo6~@yJ@^N}64jyaze-&oy|*G-?I5p7nCBmn>~v-n-kkwNBKMn zgPQfS zMe&N6x}453%)(i~b~SYHi`?L&nMLwkql);(*J5K*9R&#e)YmSnJZhq^+m;qcdC_26 zt!LrpB>rQ0bQQw7s*Za1{A>_3i5b7hVQU25-Y4jqDUcnsVO;AsgW$DqyBALz5#A&* zq9DBI_EjG*Ed`|F3;etj@4^68RM*J(Zds^2v5Y`a(ub9ET#YSPKD9@ps??<;-_7GH zCd>?_O_&&D)U#33iK|YuC^!4G>%0-Z6kv4zjfDT4LtDSixmVCq8QC}2dl`ZmC zmZxZ>4HN46WZS{BC`cg1Z9JMGMzTOVBqwEPD2#SONYDF`!Q_qTQDwj4ECUH~OR^`@ zU<-`gi`^*6PNVAib9;7V-Z^w4MdafIOa)*w1>UlR%y6!Kjxl|Tt6e_NM3M_b?Q9haiXV3 z1`=&KKbwsOcn zry~+=;XbZ14KGWB2#mIz4NWZhzh+mACV(v(1Tq`?#=VHgW|sgY`j>T)McukZ$B%1xmH0B~j&^og`cF zGcw$owL?J4hEgAzJ2^aXVQi0)m)?Hqo{zWL7j@wMQ4!L=!oMK-Mcg5$gt*oP((^X1F+AmZznhMn7D z`<1j%??!|(5x(Et0Ysvy#1qX0R~A|5ZgYas`C9~%-CmpNcytJ@_uH4?rArr`wvYY< z%)U-AdfV98s~E|Lkxr3Ybd-mGrx>xnC^M3l3Bq-frO}+Gy0N(AUYktV38~isiCj^^ zz{2>&6?a@1!)%8GM^afoNXfb{F} zUK&X21~R}xKQZTg>q$Aal7duV@n+DqPePwFgVC>wOOxkjPiU4Vaa2(3{2{+d==UGcG;B@%Z@hch6qtXSSk&9{}% zvn>~9tW*18o$;?1GyhZ#_DyHaE?gM&eFAjF{mb|X60B4PVKm-=qw7asZBg$^UXMxk z5||*^PFXfg4P>6Mo>D_E)K#Wlx5z*CaFB5t(({)^!&PnR$BJmDK)eD$pim-z2Ax$f z>nv<20-*8grOTRs03eiMu<$jDm9`ZGQc0H02IFZyU94VQY?&E8J`Vk;NugYa*vGX=HZ?>P^%`|K?F!;J z9>^YT#jwPtXeFJ5TIF_-CPw5AXs8eYZ?$H~5P zl5XcdA*K_)kJk#slvh(*Yt{ml%_!jhh;u?4j7YlK3c_OH!>@0hhoGjpQ_gZa*hnoH zHJc3c2nTV0a>RzT?}?L_R)6nu8n$w&4%$mfQ?hZ=QoM2`NH1;$??VEf3?V12e_5aE z`SlqmYIKnBN5X6{%l0mAnevYStjlU=Ddp0L(u3jPkbiYnVEV&;D{hAzA^;j7dfIR< zXXY@Bk-}f_fdAX5xCUMI_NvZ{Bxo>(Tv_Ff+ZmF=utE`yF)j-E3y?J^vZ&28V@2yI z!im#Z9&v?fW)Irz6b1H+oT2t(8oVNbZ6wi26>P;n`kwnxJo1&KEw3!k@t0YEn%WBL zC-#_~% zMS58HL`1Jq9mNALn$*=cMW$SGbXWVvY-H%}wv5*^d$@eDs5jLKRfhO!G4uZ2&Ox)n zfBorzLa^;-;t-4j0i6#KD@pMFoML^RPf5_C!?AlwF6iwgawAXX+YC7GgI>;IogA&m zXtn<{vUl^9@UxYkZ^Sd*l!``v5=8*RC9748E`kK;SmoH1R({}2?ZD7q|YjSF{)euu(b^1f03 zxU<9pucG^pWPLxeGhaWH(*QIMqj20PGdZjb_x&i6 z5ucGAOpIssSgHIa|< zWGWFCHa7bxIyXDHhMatDyT8=$hv3*d2qC%8>ACR~v*Uw62HP|@Z+LZ8+K19N6KkNx zM>(|JL3B{t`bo

W2DdIde|04w+z(1wXAaA$Lj9OYP$GpM2TumHF`R-vdg)punr~ zC+SV%(Pz`D)Di#;O;N|ruxdlX*!1tM3qfd=V#?CIcPM6bBNFwp>VmgdS`2_e7eJ^f zOUIHxLUf4^(`A6>N$JR#?*xrdNL`tAPL0@R0yJtwTQdwNMa)ZVB&XW^VP~@mYaZa@ z>Cx*BNrjxc{g~m~D9^GLbl)SS_Cr#zyt3UCtrYjfl`(Y`exYQG{9tn+EibNlYOy;~ z)c=z1!ybP^O{2pyrNFqKb+r!!2*;G3MTW{G;WPvhOz0E4Xf7zX)agbL|N0W1rusp9 zXF~-QiKA)i)X;YJPO+{7)IW4nEULod>mTw~XpoUCx#H@Q32Kd)QyE;+q7Jz>WK6Tl zbrpXzeBhMnumtaqQ|-=eyezg^u%{(`qJ=i%AM$Cb0ylv>RTvt# zG*dWFXckniOml^oc^3wL!oy*YEpF@_E70+ltTO4#E$sZ#6&Yhuf=j%ji+bqlK4FiGfkKn1bnjR-GE0>Io$x82ny2q~Ap zxjRrXxJEiKfg9_yA4%e^O0Wwru@BZTXPs+7P^}VfG4sit7JT=e#XAjYC766u*8aBLTzD~~ zjP2|=s2|x$JLCS5G2u|4xn}KE9cm?991S7av#Z~i+NDOxkQLJ&tc#em)18n7Qvtod zb!3RGu)Wx^=8kc{mlq9`S(&XEbCy4=;kp*l_XK1+Ep(3Rsmc|rHOIT$63%H_kR)0e za}vrUBetE^N%wg@JIFNe6%7W$b$W}SWM<+|OJXfY=(b1Oh4z7NeWVlUlUF5_D_1zA zz~@SSfj`7Jn$eI~rL$_CY=(%8NILY1FznttOTlSs6JEDQoRH_ZHTPfNDj;PeZA0Fc z7^-g)-!}rfud9~VP(9chKi}9Q2dgbX0$*WzpDYM`py^KOky}r-a z)Ng+&P*}F4H>WGAi4!}6t&r;NkmqzXgo?f@+Z;@ z!u_C0R{KG)VK6;mc@Fg7cN+RSguPB?fw2{)i53fa2~m{Z`Ejz@50_o6DF=65d&ch` z+OEu^fOz(UFT2}wOmwBU*hUaYX_5^hW|Cw~gI71Z+vi=ylZYiG?iWfsUqpx@+UpLk zpYht?IvhvqlZd_!LACgPZZ84taE^jC7+oYjiMhf;L#lUv;r8UA zhD0M>A|@0=zJ{0wb28Sy{79FJ|CIFLIvI>G3`2$ev!j*`v z7WuLYz{~~Ju4$6tx!AT#gzlTpH(UOGyDYTs0!Xr=LPq0ZtE~AZ&k~tGsds6O=>uD$ zn**x(_5?ejrAs3^cR&8gDt-PMCPy->Lc-E+mNh)WZ zW?mpN%0seYih%OwfVajJ7N_s(4?XCAl!a$h)8s~KLn_(R=F`5TByGbIl>H0xmBr)1 zTdV(sSA4d$wVQ2|?&2fY-dq|?d8#HSvMyj->q60hln-? zrY;$!Bb7Q8MoJlNJs<5EfIaxR3ATx<-pbMRgzoScNM6ynvIwi$_nBwJ=J_yIxrr=TYiKG1Dr^FEozb}rQ zAAl6@%frf`lS^%)BFDjm`}xZ?=0@Y&XP9RSgJrkF7@%`F@4!E({5fKuvP#0T8K^se z)caURx_b%gRh}K-KcV2f63Tkd71$q%olBZAKILD-9eG{HEgFY?4>{v{A~mCPd+47j zaesV8nk-M=0YhFH+(BvQgva9%UZ^%9R?3Y7gd4{XoeqBlZ>a2yz8gNuHY>?d>P{#A$*VjK`YgB`RePz;?Yc{aw)8 zU&Rf+s8TAld+_cMgFSm6MLNIl1j+qhqBK0Pz>+VP+Zo|VZRhCl!VD7u?%}ydXZT?j zy=|vnVX=vgRN{u$m3g7oK=!C?)_SaF7LhHi?iXuV+w~OWT7m%K<`?sB>f5H%3QXnS1wQf!;%QzzS^B(0V_ zQekFZ0d~oh!$&IO^O91Y1qf*V@McfF=~)4%G$;eV9Z`ND)=cwB)I>U>M_hss6PQ*9 zc&=Y#!D|p zl3UXuz3k5Cy^M-x%94GkY$WlQ+0n*R(a8duGsjRSUN#yxaG0p@*|6tCOLD=i;kpyh zLKMIGWWd1LANq9uG>ie?<BHjD;rI$s*JNxPdw`haLjl&#(W7U|2QBu`Ran_+qxSNIWo$sd2ncvUsBR`Q zbPDOX(^br=s2H$jFq}fKNK&O%Tk-L#jvEt$SmBxJr#tB=pl(o!-Fg}d*R(=jR>^gh z_NE!<(Xr@Hx<@Ii-(JAC`<_f{CKi2$$(TB~FVQE~1*SI~Pv8l9J-O%{cVn5;XHhYzV&}~$Rmy{Y){Jv07@R+Jte1mN%A*D2f-(vhzp>?!alYEP#|kB zkUwv$e=MCP$6fLEVSesla5igz2w}S%BJxRcd=tm|2NAcrl=z`Ow6NKtN+%N1rdKG2 zF^mGUogZQMA73Fwz=F;ibDwxgy9G-M#%Ok`?o1>Ge_1efO@4?INYj0nqZR^0u4N^A z*MT_d5mH0akX|jQFT{%Ej8d+_LbOSg&LLRO&DX>KVVGPwwp0Y7H96@Ec0BywZ7ha) z5eM!stI;O1po;rtCJvFWtl6i}R_l}a*A*$G2PT>8o|f?_luw(NoOWw8%X`8&Z0-l9 z$af3}758P-Q^@25#aW-h6YVC7#lvkggG)LP7S_!LE5S^`ywM@-kF5UjAon{wpZ>|m+Bux3BmPhNB(NwOp+YW24lI#o2XOwH7@k~ORiBl@i{Uz!Z4=*J(Q3YX5C^>pyJo^rRg{$+}G2rq1uBEls zUU64PC^;vt#bxk599CAaV~Yq!$$)>blJEmZ@2i5t%vtD>qo#9yJ1R{mmOJt9lYEOB z)4d?xM9e_zqP?U;o-_!@s2(vgEG{r-$7RmSjR_4BS*rq8T}idQC4u69kuH5<=3p27 zANt`r8xHDE1F``gAT;V0+AVowZu_JG=eYm~KSXuI)!9y^?r78A2-FX9=9OwCp5@F{ zh}8|?@w!dTGNTPq-tSu>?~_RhU0$1$e4k&G$AuvUS<8GLStHZjeM|$T?01O+jo(Xq z(Psi}$4T-nUTmx2yPyaMm;KtOgpm{Fc4b8kMp+au>;h4W7+k+d<|TbCC1C{^Vr9Ui zz%klEx~&BAdapB3pO`T?Ij*wz?~@6vsXD#PC2V*)Fb#nq@aQhr<9BXy-*;_%@9WJk zD?b+N{<^QqtWGncK(Mmi_2y$q&cC#fBsX$9gRR8M?nQ8&HbJbZ@XHNnV#YRsis7uf z#`$clbg)Vhx210t5#q-u2O~hV?nVPkHkNokFJjCVg~!x(MdnNzHDjj;pMNElC0a%s zMntCh*tLmwtr(~MIqM!u6HqKDmp@@zY+4@-SVle0kAbLtd5i!ghkSr66@9zY$ zRwdfTBt3+ngi#$TE@V_vVHG^Zf>e5o=U_|rmhuoTlP@0Jm`~b~AStUS7NVuqGz~b^ z!c*8W+~aRZxV9yWPe;UaLvflq*FgdWRAycDJaG|`|G`q6;PJdXH^veiEr-aHhiU~A zC)bx%!X2R?Y9As*vr>&9!9XqAz}Of!nhh}EccVjZJ;5eTN#Ye^(*o6u20QtM(>OdP zQiS43kAShEqV`KKdUTa^fcYPK-if?Cqb z=35;^4c-5NmF-l7-c3ZwB$5PKgHwf3*Zv-yjbsSZB_klfTUMvFQeM$uEclI*1k?;n zW&liH-dkUaXOvDk){L75qA~3 z$1ful=sX5(Tb=Zbkvj7M1Afq%%WVaC)#E#f<-}?G@>Q;9@&V`wVNSl+b#dE=Ze*hG zdjh`dZDNzU&~o>*P|@*vMX!T{n;aQLDY25zj#yf1r%t2o^(^CzqU7FQk~4?fri@lX zi$7VRTV^vD;5K$}St@IcN~f)5U>Q-a(v!pPaOSZ@5=s5^8*l}sN)z#Dw21*2~9zQ3Sh~sr^!0hI{@dHT}mSLXeI=(EQP)Pmaw+ zoq077PImEKz!YaYrqL+zVu|BAC|!7?9*ivKFku(%GR0I%+J~9WMmwfNUN3C&O%)_I z>lE7@!@p=aE!1$+TXQ@T2djWx%R|C50~@=MX{unFy9McN?+7<#`s8);8w`<1qXx$s3G?ASK8&1c)!1hdc`bKNt_1qitl=bfL{HcrM4$c`O|O? zi~YEu_%8}WosLaMLrPCjaDiL^5X(>p9cx&V(q~g!i6h}Z``qCl&d3CCyZc+CPgi9FXU)@n z|H4oI0^cY4_uJY+t7wHH4 zk-)SLD7{jL{OSY+K&5-J!2LB)`j%R%r>~Fd(MLuLZwRrvDZT}w3o~I8D{Zt>&-0OT z7d0+3-_edm{4ugmj7vb-LTj(druXGNc35{qos7y`_@iBVDx%>Km(m_xH6|@|OMi~) zRZ&BTZvayuOd{jwzaq^V(1zFP$v{1|sAd#WDEX|J6U zT3V-=!NtB%kS@A94qL1_fE~H_3<(vjLW^>R``;utW3*4@-KErT$6a_}6r-|=3@3^= zU$7r{*I$=U4BkpWl#i&`-`3u`6jGW>f-BHozc*@mOlIM9>J59Edo2<;Y>dSz3ZbI) zyD&ztxZ+P{gE_+6FcM2(r&7Fe`dZTuGyTn+r2#)>oPij%rTFMnW&eqxl&f-&_1JMQ z8dQW6c6hDrIwa8!2I&DQDZ{aW^+N%}B|J%l#+jzFPoK7dLozw@_$7Og1>*Ws6Mfcp zi;(h?)F;YBmEL&7lOff>_3ENxMdJQyU1gZ@@IL}&z3nd3rL^dFV_?|lws2bF)cJol zs#4Iqknxi*h%O6W237j`$B!zghHJ>W+}{kHNO|I+b6HnFMJZa%k|Aw%NZfCn!TIt= z>l!3@uxaVU38@3KR&-iwyu7M0>()tv`6B@5mgxx!wor~Q2F!bHeZnk-N_U`-kC?xh zRY@DLhS>+a!y_ZDSmJR!K~-VTXcVDV&QbB5F73gT=EKgB<{4qF@3nMBJw3-RL;P*T zt{{c3f>w2C5u(MuRg;e990I!uUJe7zno+yG&T&@1oP5>awkdxg!D=D{mD)@$*4=;G z^8W`s4-xh{jeUFH0@Cq5q3aotI{7M}lDv#aKKVY*JVPJl0XRj=NF6o zQw>9Ya*DshwjzIewcD1P)6aQMmcreH)97>#0pLIk@~#=+ZzleUjKB68d7B{k=PLPq zfcf3C%{ZLy*|SHPwMHuSyyE$N4V_?2T8&*uP2Ln;4BgzK$L8)P;g9pZ!F9je z@9Esqg!0Nz+221U{-V1e3a&_p=%L2?ch%z^UBfbaWG0lBVQ9&CWyZ-7SDKdg@UywI z$GH;E2s8_{0LxQ9(U^(pHBve=E< zMo@wz_-Y#d-5;P&{|09MK$vg!_p$C@mar4I9I-$z^-9$+6x63=o|Ye(@pzVja6nna zu^moxdTQu=PGfmamUnwZV0W%`w8fYH7(41}$ueWs#2Q-Y>6X>?aPq$kUxO>8XPEBI z{AYiRl}A4>pQ^>sUgb;cfj|8%UF4`ZT$=g}Fb(FqU`;6vIlF!ag|>vhETGpgQ491( zoRa@7+_hT83gV#OkiKCzHL@%bsS3S7s_n81D`5ithr1bXo5KnCMpRmdP&j;g3^$&D zdwrs9LV;gG#O4a;sIhyPnt~r>b>{g1ewg?`^l#aU?2H%DzNl|Qcza`4qR^eD1i5?Sl?8FleR6>x2%#o zTYQ5v+>lP$%P$^h*GF0}xLRscFv9<&^%pyoRpoh#@xl(Wm3SkUkSRHW`=^uZW}<2l z0E<{ox*RhPrRQKZl*LN}R?AtqAx*mcxFgr~LfA?bj;`?Z!aZ)ZI2ew%L(&FCx7WTy ziWxrc#{MIE3NVs`L5Bo>Q zDLYxP_5@jrvSL11*zRS^UNi_3$R9Vp?3<480>NaO{Q=HJ6&(|PC9uJ+)fo<`k@PFO zW}v^4$!>HoN7Wr=DbGlPy|ODEJld^?B*bHtwL5_Wrp1+oFkbB}BIRb0Sp2i8toos@0w|RhZ>W#U( z!@#pDu2uvAiz-^qrRt>Qi>im%?QR!*-k^L_ek>_!687O~{iGNI5yIEo4%6qM-oyM` zqW8^RqBq?Gkyp&aRu5MU$;$ZM8kxBl>qfAnX7201PZO;YO1hA*HDvC@tDJjNypKpD zX6j~18@@iX4cWuiR}8r({8EGIA8MSBQ2f4~Z&W$AcZcpLSh8(T(u=MUbc*)cSB|Hv z8OH*j?_@JPJEP{|(6`|pzOgxv(BPcC@Mh~771;-T-{^loYkR+V@*G=8W}o47KcDA{ zDNJSX0eEM((8`6>+btve4~|W&nMe2J_w7-s`H$kj=S(%wkJiq9gWm$fkKk|z=jRl< z$Nl!Dotf>%lu751@D73I^CPz{?YWz+LL+0FMr2Jg+#4<8F8DyBJxx$~YF3@Y3&82ETxa^=fUf!H#g zwdF#sr-q!^3o|pG4&E)-?8>W_o#mNsu8os(2QIafwq+x)iVM~Df?A0uar=0 z;jTtYV$%w|**e$;W( z;+GB1%MV+HAQE=lBRp;uGz`Rm$`2YVJ=%j1J+~+Y!FF*`GCLo>7?wE7LA}Qlk$9^7 z(Nc@nmHT@P+l6nXdrIB~%=L)UqswtW)=Bs`D3nd1*18cSUEE{UykhBP2g!Csxei}x zNc=`6zNIisnJxR8v@tr8(Vcl~vg65S6&Ce#dDk>J0y1F*wN+;&+eJ1n=V8V28P8cS z!3O^`r3)YSljWXOw(9z|n+Bnl_4(yGv*T}6@q$C+k8Tat_vDgBL-s?8_cFkh=rxW! zg~vU2#q^ib5MBP$Fp2Gx>ul8r(^Q~d7V6;NF#Vd1%`HOCd+y&YwArFwW{V*dX&?J` zfJJy)7`e#9)*7;eS~*V2pb4p2gCWq`nUD2Z#wIw~eQL7tK3Jmgm*}fv-?PM1c+*z> z*xY(FVAL~kCU&qi&n~YH6Y^sW0u?5qMY0pte+J%kh-UPhvL7^QP9VM?m$iv)&~LuO z78j=55H`eo|6Op>cs3SF-=Z-8@XjkL5BT+FqXv_jKsDj(>@T|zHTiuTyZgYY-0|11 zOYwcX&VSCGAzjzs6-MvIGMAY>F}G{ z+Kf@aQl(|ev$8BbY2dZh=?S`fFWz(6d~%D^P%u}e9k`8u7+LGiTxm1zoGxZS&#KbW zu2_M$lL8Vj7%buTw?ckaCb-`5+<^UTgEO6hGGq;Wwrltsu9-6ILwfAECUVK)llqcm-lvgUdX- z;aVU$Yt;Hcua)@{oSbhE3rlW(zw(rJt6*h$^6XrIhKfAvLlNEZYxeXg|F2NEoK!Fq z_=$HgPqucK`R=*M%1hhx4J47P1bZs)nf*2j@2eL{SnX=?WSjfgfPvshj7Bwd=~E)S z?NqU!^z$L;IE`J#dO!(*R#sSqBQi*=HWe|lK$vDntjJY^|c zCrw>#Cm*T^9-F+RWX!%K<+*3{+LuKy4S1XznhcF_JIHOzoGMWf#}{axo?PaIV|N-%)A&d2F29W9Q@cc1*eQtJHMo=45rb@75DUiJ{c7raV5 zWQ7yqSEaa5E&5lwTr2N7XQ@z?0+!;U%jx8n{RP$(+{$KiotI$OV$V5D-5_o2_}fL- zX1ihD@)H(^Gw@!^zXb+Op4?(WUk9ocx-G}+hjZ;1sDo~Bdk!@xo}b6Z_3?>zI?b%` zpvwj%m zH0AxR-R6QqSF-38QG$%$@3byz0&Reh<|cd9K#_s%ueb_GhB2IkgQVav_l#2fojLfi zkV|7e@!8%IvGlF1u!uQWLzk7n( zQ34XWz^wV*v<%@(C218ZDQBQc(LaeCeFXAf`48yGg&LCQ^Tx^tY52Ux7PJ?%>Kvw* z#O4m1R*7V-M5;lEcSA$O)KUTs%y>teb!chc9@2}0%?w~F&uku+9>`Dlr|foZAy*|# z<;9TEq@)zVQIE#TMu!!oS~FzU^Dbulq@B?%GK)*>v9RYo*wyG|eALDklK96|YHhw< znOa?4kK3-KvZkRyNKJ>l`%5sbBbn&3d*Q}Kp@!@mlTVpneAF}Wq}BlutAp+ZH5YT9 z4`SGMr@7?a|5{c&*v>8q1W)LMeRh1x`Zv+d?Hfa?Ze25?tJQ6tx7)0IUFFGy7bT$r)lATOk943Wyq z;BdAe+x{^TpwR#Y4NtNkDHRs&mgwGQ_9tUfoRik?@0lW3Hs}Ws_)@^?>zv(kW)PCmI~Z;M!48!!HH?{ z07b+WDHn;+{l*!3XQCTdSr?m*)booJIbbH@HB=-3!3)|8KaJnZWUp#82Q>5(L zBK!5i1=nYT?ETiz-(f7=41vk{;M2OTqAj3lESd60KGb^MLG-~UmNh-7Fkx~tf=k;G zbxVJ%J5H{{kRt%kMx>6O7VW9F$Q=taqG#59uf1W@Y>L$U8e~7!O8xh8^xZj0jojR6 zw?GAXKb`aA4?$PlP@yyn5Mq_5e~;FzUyb2KiJ3mA83YmzRyd`qjP>HJR`+!}zC`Pm zXiJxy_)XcGKz@)24Kc54(N}2bXRX~+qmT5oHQHuJ0<{WPHEAj%rsJg}MdB|hjkjKF zEWYjyQnS#YLP>4eee|2Yg535Xe3*i8=w@~=^BHI{7S-4{eN+Tvn!K(yzn#?uuNREp zIFg6`>Wg&>x*cZz)yx&SLlq@k1NL3Cm2wPqcSxSC8Q@d6}^P?e-_PiAniexG5(MewozJ!|=?A?Cl@E^k`GOW(>zD*cL^ z1-Aa+71)%!Vmp$i1iz>qmP9P8*)L;Yw9#mupH5q#HqMtAt`ny)KVRJI?%$2c1${OJ zrcVupK1}*nf4N#{<1J12eP-YX)`4=_eMC&J&)%4fgYMzKQlwD-r_*!vn^F~NZ5L!8 z4+PmQoYdAQf`2iP%a5Tm}OytulDDXJs~}4tWwX%Yy;ZT zeG^vzw!e??2D@M6G@`v{JW9N5k}kfv8YJDL_x{z;6LK;=$Q8(L(VUFzbF27ogMMa?B*%w;%qnAtmz2@KH zSWrvfk4wEn+7=iW;H)f4ER0F42|ku2B6XEstXe1^G&C9=RX435*?aifRwr@rv~>*W z(s|@yPqujRarq?mqSOC$mh}*2`n9Sb0tjjw7E_LO(*|!liAa_f zvJ3BTWax5zXLI;6p1eMuPAlA&M$V>BPc7Q?pF->g<`|@k-)hE&W$=0hHXyKDDYCm< z*l;2Vp_Eu?OS~&pogMq(@m%a(-JlI3;;r&ohIHtR$!=koSANch^!|m(5y>fxoha8` z;IYnEG?+tQpz=U}X(GZG<Vrj~_mzF{0*uHIEp+?!lEo~` zPTxo7EibXJFrfq!LL{r9uHB8Ti?*%m;eJ4?H1dfWjD1Q(_vfHE4crw}C6QxA+CU)c-IlWUu_b=~RwI z11vzQvS3UEJE~2vW9c5>`HaWWaSuPS`|gr$lOKEik$IxCp!e``ngY5-_MKZHRtziG zCMQN&`FFKVLdmD)1`geo3}7>oE3+7W4hGD0W@Q zqW5qsoR;EJWI{ZLo2b^updTt>=N?ey6HyOeQDu%+oZkDrcyR6x!25Xvh1MHLRrXqS z=Ot#m`|;V`kv*5E>;L{JU@kqfPr4b~g1I9wv71=j$IV z@TgP?2?yYfT9thF1{=a)<8L=XS{J^aV}T8PVOqZHiO(Ns!OL=A?E6MWHv?tx3j|N$ zRTH0u$QoSU7R#q5N5nkWV~FrMMfbs(D=_6MUAq5c;D;V6@=ea(lc$74`%##e!|W>= zvJk)KAHM9EBmNJBwlyBHm_B#UBkYXX`mT45y)Swhe(6)*JMOm{Xt?TpBx0p^OLRt%U&H)|*11m2OeU6~pY~fpOc2yF zi}%Puc3LTNWh~fU6;n2B(^{&+2V8=VGE4Gmg!Vnc)Wy+e*@T)oR#1Q!s9VJ-?l|9Y zD;3TPGF}DgNxOY}$89U^w*?9a3I1i0?exA{1XVth{=!+IlxIas=~>^nPN z%gaYJ<&UVm^8?^kO}&Z%nC9o>g{(de9ibROWsOg%y?Z~nTu8qZ&Qr+^-%YunTD|tm zQo}Vz$0p^NtlRCkjm=vz&#_O>q|3tNU%MKxMrew6g9ZA zXk5_I5`deF2m?R6gcGQ?V2nF>cX*}ct54|5F-D}Ws=U=EtBw*UFX6=QzV+b37df}E zGi5nwQ?_LlbOoi4k|8(WZaRO- zx(59H!t`z5QGg)8XqCov%FMQ)0YKEHhmlGzxZPaIJ0qrEh#PXpm4=Rp2hY({?Avyy zJaLcNTx`1G3N*`PvBj!9@ei_W+|CM9M#aS3eR9y)QN5lJ+yN-wcLFl=Pv6KRDbe{R zm(k$DvyeN}zdaZ(Te+3LJawl8K?LN)(ky;IZ7S<2^D`Lhcqzt({|Q$3S4(D5PMwnJqNq z9`ZWh3i#4ZcrwF%Ko|Bo)tF~ghw#8H)nD!?bhkuZv0~Ryv9H^Nl_fsIQ>07>)mCIV@yD^hFiG#~6(>mB=4Chit!eSN)iM`g_H> z>^&|1uJ~31AKIY;F+mdlTI0KEZV%%A!z-{ddl|U{53(8zCeLZ4@5458)cPKIgQaUt z_)mQ5s9j8Y^%NqFexb&tBP%w#jE`m#J{WQQsCN1Jtiv?c~W8rt7ONuH9 z3V-r_2UrONHwDWwQy-YUhING}5#Zf;uEL1um=zSvNjFGJD;c-ydjBC#Joty1nUu-9 z(p_jR>-)vl;&onTy`t=6K}dGH*og~SjT%?G)o64SIzHR4pH4hY&D5cTvjX% ztNQ+#DU|I5u*Urx%{VL`4Y74&}!V5!gMK2&NC#__^S>2tlzZ(nIWD-qI#N}?r=wGb#OSCM)>fpDWuZ$v%E z!pMxZ`Ia_5g*)yJMEg4^`^SeAR-=lo`i_Q9yih9ol11Ocr9r)s1D#8j2{1;dfLAPP zZqI%R`Ok`V_`Xs4w+Z+mrkerhPW3%%l<-U!`T(Ezv&oI`+Qn1b+@8B7%m1vHT;wbi zHD^xP9e^nVo|3Ekp{QiOiwo5LAQ2ue<>+srg}bCky*UIqGKk;P9dP=I9wIE-k=WJe zDg+d{W|lP!Nhf1oywKU?oJznZvOW`)-w*Zq&;S5%Ubf~{{krK0?6gbdI5t2mL#Vw) zynW4%+I<=BOTR*$RlSv9e#A4-Pgy8pI}n42a(ySq*$!GtoTuE&I}CF!TE*XN(NRzV zWWPp7U@pTLSlK$yvx=iSN38ldS+Y_o;(=bR23VYoKh21YVnATPol^QWHfC3{UsL_E z*IIsO^Lg(NlG6GPEU1@8OM{*P&rus6M0_6BZXEilg>UW!o5s1Pr_cwuhaXazL&(ZM z3op-^G>EB5GUX4Z0_CphIF*(|h)ixgJ;y@-nA)|(XB66w3f>oMBFLFU%N}Rq@4y2- zhf&t-(>K%3IDCJ1#?QXP%$BVS&(g{xV4exM@8_m0OGswZ=+xI8AMVZvL2u?9^49}I z(cLoyy0C4&jNbK3HRIJ+wvCpi2+P;v(7NJeIww84{gTqO7;BS4BVdow^kuk|k1b<= z0uKjO9<#}mcBGFRE^*9LLYP5xU#k~$BiCR;WQQP9=ME)r+4I(PsS?rwq*eZN$(3^5 zG)2n~3mX~P;#M9j++#cfw=Z{IG`La9hfZBRZXD%?C-^0Kxna3y`1!>%B6Boosg;!P zm!>4ksDGtkK>IIEc0RvL$VDv2$&i_1Ee5=>Wjftns_qC#Pr)P0lB>w~=oNJ?$&DI% zOUqo(XAec4q+Zp~>KwT2%vk1MNZ}-WrDE+|5?`=4LRzfUO~l-6x&KoHjIM)M+8y!Qs8Pkl=X%6aHP*>CLyadmOq6~ zXL^r%qco=+?iTp`PP7=HsFlR!*_!hT&7wPAs{+;HUM1UITrLj6gnL0-^ohSnisj^lZr2q5~s+-@xE+tM3+zee0E`?R`sWTNV1Rie8D8A64}mUbrGc`b@wJ1%PG4W>&Gj`8qZk%Vvnuc>R3 zTmxPt`|D@tC8BLECJLziG~m^LYzW3*pJF!s0HYM_Q!9eK>-T`$53R46wtAooWEwBx z?{R*{RvDjyp0(BSAIAld2psco?gc!EHeh6379RuwHQc<3#fu_JT4Nr=CwOA*BV_rx&Llehpy)Pe8 zLxY=k+-$9y_~kaIsB8mivX{I9>mmMI0tq0B>A<2VY=jx2;MyS=iVZ z^RU_Cqv9dR+rGuJRY}^jIfDa+i7NG5=Y~uo&zmc_y|+73$C@|zAX6}Y6haa1>HR@H zNnM@JtZa#!|L&6xfU-K0@JjTz(w9DG14o&>Iz^2VLMHyR5xT(}A@koG;lK6L|Gg2g zIl+Fv6R&^1`O4*&POts8qTHt&!zxYP{`E8cudhA{IdA+WxIB$7xb3_JLhN5>WlkhSIF2IUPuO zD+Ku$*S@&tiBpmBEI;$1)Fz10LsfA7tS#26#u_`##F*M`W1U`+&pnFG=*3V^=D`Od zv>r#65hRa2Szr;6(J$Id7#avCOa()~MG51!8&jm_+LOCj)-C71ZgMmqd7p-B&r ztUZ&nSbuJe`Ilw6PX1#XE3=#sfzUDVgO~}!xV^t zJ!;R@M9V)8Slgi|o>jgmup+7OMO=Tq4A;yhC>8GYqkREu#5m*#ZkM+)SO)<|u}G zt;2l7Sw5Rt|2>9Zrg>vh)h7!zLiCG`J4z7QxMm>)zWsh_+FfT5<+gGYWx{?pKQ~M; zMi_i2Z&_%xo7)mx8+SDy#+zq2rI}(G2z2FQbiP!{r=N`L@}%5W#LhM)xu`-Y@`nSF z+iSc{t7k}GP`Nu_AGDva4o`~b*~v>Y>Mk;TU+!-=Ss@$@iDW%L z4Q**r^$z}--_HBhMsvYr8vCU|iyn^0m!@MX7yR=Mu*3U9?LTM-4(#p3m-~=~=!|N9H+~5D33&76pR03b2bwGY@F^iKRBE5_zxMPU1vB~>toYznXZz_zU z%2JylBE8$#F$z>wtesHnKIL>BdQt|)zbE4nN@)KQ`P!Ix8T;|uQCvu;aZI=tL- zC~uLG+N+?umQV2m%>C}u31hD?#d5n`EEPg>ZVp5lk0Bn*>I@-6iJuUjC+L+>5w#%1 zKe5;njZ#@_@z+mrD821qQiA3y=gn};-SZ(TJsa(HB^*3t-Z%q574!Kxf;~UMWE8L) z@UKZmcEL|Zg>+Nc^ZfTDXTblNWc5QJ!3^o|a8O39eq(Yqs;WyGvK)W!yTp$l*>6;t)rpqY+DKwxI!}GneA*I$G)R^zJ@I0+5X)7|Z5LnK z7eSq<{ZihY!ovb{holV_r4k23oXGBWui`>#xP~6C!Vnxf0v_umMJnPCy9^O4Cv}Zq zj{>*WXYB!UHV;UpS0Xgq8QyIuK!Oqqa6C_(1?QB(0OBgh71-EUbh!%TSjKCM#65KI^raiT&bv!`W>)X-!WKihw@(aa6S4DeK*DGq)}g{qQ?VGf4gk zw{-BSY6C9s^1K<0y?q@deoqzL%6`aJ&DpTCk<6QE?({)>Ps-VJAsz;AhVQ^?Xey20 zqA2@E6v=*z;@dUny;b`#>FUfCXrIyxvc0c*2@8AYuK7AwTr2Sq^-27W9S338&#b8ZxT~sgx^yJwB<$A<8cg5d&A$&c`y{<_WZ~(r=MV8q755 zcbR&i_KN`w#v_Ky5=%pJ;TBsv#Zh!9E6RU`hBX$S&f;OBiV8G`?-DjGC)CXxb@Amm zw7ur~{C$>u77&#ogG%UhNy$vWOeG~Kd3Nvmv{z!S1j)#}EQS&&RRGDBR&vqZSN2_+ z&#Tibe;U=lg{5HUoI7&YEe;ojbgGW+Eu?dcWMMfBt>Bz-gC-6OI!Qbq#Ck^5sUZhX zys}81>*g?+Oeej+{Zqc*hLKBSqtSe0F#PN&N^n`St8OR786P&ywM82IO$h*X(DW?? zG%v(6h?J-GtPJ4eckEwqAFS0XC&H-h%=`9>6M4oBEemU=+7SFR@Yzw_^Z}4PDYpX5=KYq@$DULDcw7C1gN@2u4JVv$E%xJTDLGWAp@R7tNd68rx8+ST}=&(P9$KgEhf1A?M6VaLnAQhbNqa+|&NadnLtW zeRBOIr5HAnm=4TCc}cFrK&-2;6Te(`4R%^7mo+`n>Ar>1IR`B#gkOGT@08+GjQRj+|Kjj|te zq&Hd;j{AGD>I}=a8_m7!9I)_<`Oe!;Kea^WHbi%?&O#avhF6Z7ww*w$H7lyrne1N@ zg2PCcRoVU^#E&6>XF>*Z+6g|s>k5O7#E`w}mQymx#NR26rdl)N`e=v}Ucw|8)@*uj z+)_cXdjWO|*ShaO^AI+pOwdu#go83d=~TWiM@W!vdKrDpv_@d%OQ%7!KrnHq*-^=x z(dTssNc=F}*%5Ip{`HRH-S4kb0=R}znz%8;!Gmbr*F+LF zvL#Fvj3ysJioxYNy&UG;FcM?CK`{+m80&s&gVnKH_>Pln4;k?n*5rj&S_uggqO_)k zOe4<8Npc!G?EO5vmWQcQv~sCGw=dvDddRfXvPkU3OBOtWI^=R+KbC6) z!cpj?j~%Yk{gV8Mtat<@ZiBF#X_q?@ zJ^DgC_=N^VYR`?Z@n72DxcILw$UptWuAy$igA(k;lVlcyiugfz^(&lM+s1ojvl#Su zS(GOv?2%LqXw5vqx7b2DHF5#J}TsHT} z%k`z$;~y2r12TI)aK^>xKH{;y|2U66_WUX*F%k1%jj9hlOo}Fti2@ye9G|u_cU<6> z#RRw6K=ELT5DBm>0YlbPk0aAg+#d%l?>v8{K8Z8P~xvf*%C zJ9Y~1U@YvZZ=X<;vab>`N9HVu=m!zX7G`jQ8ZOI2<^u0|DgQMwf5&a|CieUXOS+cA zbC}ABGcKMRHUoF2I=!MO#*d+rW0CM0HBl_<%AY}%Cj~a&6xSbU=~oh4b@PLk?>08u z!*xo4IuIDCt8$lrQ_^}@;=#|&e9t^pTk3Ty?5CO@w-C)6YcPM5^=aE^t`;KxkZ-Cl zgxz+2jpcBdlYWm(e}wL0Ie|IvL7&SZ_8ES$#6ni?96YtDw5&9lw=apU<^XB|_I22w z6uPMdj~nP|%&$837n%h=Jcg&@x7g#OdSeGWA;2j_wpjq#mQKHO-ainrFBM=ggsgOeP1Lqb~au-$*Nu3 z8%Cr*?sdh8xO8N2RrgoS*4!ETOH>~LZ0*Gh!5{uU$v?(X<}B#Y)&niU+^YqS!d;c5 z_)5~RwD}NG23IemZB2e9$m=6RS~kfuGZ?fN2%pt?k~{juZhsN{Lx&CP&m@U7_XB5e z%i27ZqQ!M3(!F?bVqTDB{_z~x3aEYtmidPpX~P0LU&Vdy4oF>oCA>kt=4xFEt8Y&j z08XK*aP!@Pl7^yj_dc$a-fR2UC_WgW@HRRcxtow{3GQwa`S*5g994C^x_U5%Z_N?l z22eEz#f4*hW@FK;R{|+uw9tp;MRI1*VjRDmI(#hq%n}*-sx%awFx>a?YxW*)d9XxD z-I`HHJ_#H>4{D5!9>1V z+EGFI3wGr2inQU+uaklyzm=k0eabUc`D~k}WDgn+wfU~AC9i^IHIK%Ed;KV~Wig~M zN4Bzfqk!Qp|8AYv-puvs4Y(KzUfOz_s%!nX2OWXUN~+2Y8cADewqIai!FnK;$UN%L z6BOml8XF=uX4!HAB2n-`H67$n>aE%3{+poq14$|HLp4`S9ixBBY;tk&{a;qcdP=Dh z3ac9WPP9`jClNCEd#hai}CeU6P^{qHp->4U(To;gz6em&EyUd*uE zki;x`*@97PN0as2tf#T{XDVZ~^xNSt7>R#6LOa|vIoj7-?#>hVU}mMFhHKl#zNaPpP? zYg=-51TQ{{S-G?%Hy*m7%9mjgKw)gzxM*gryL)%hRB%>!Sa2f8?`#}(`(yh*5XXl& z68@(Gk>p_e*M>|^!*yxDHq^3mwYH8Qg`Kys8=o#9)W=PcjkyKVwLl?QW7;h1evakO zqWlUl{|Qqpuv|7y_jYmRRZnFuEX^D*R&aawi%(=)-E|lobJ{IBELOQMI(tx`3|x0B ze?(kAjzcL zzc?ChuAL_y^}PB?j5;?R*}-j+{i6RLSSFN)4Ez{!*wsrbpBTLHCiKd7w4`ay;^$1J zPPg8kc-#40U}TIF&`2l!i+onSfV#RtQ*jvk7F&^p4rPu@0Pr+GRH_T!5*5p%6Vd3Z z9qb`Ffm0jn%N9X9gp|)Ne=Ne*W1`O)=B+MJGUkeEnNdN0ops{-!mDQGT6lhSa5yfS z{NQ?zhc~Y{Z5vaxp(S3DBb1wp;qAM3fJTJtwL`^KgWO!Sl`cz#FgP@ZwEaK+O*e={hWx4dX9hW-5#vGkWA#jezTf~O#hKH zq>dgS9feW$Q@^2-pLI=U8TqB`GxA_^ztu&dG8{+aUrniv;?CZ&Lg~LWBuOAFAJ_sU#e-=c!=0#4f*rjEs`UBn5*&W?&Mrj7a?oy04Q~-} zB@S7wtl7DU%&4O7GnCCs3(6!_&qsX1QNx!&^UgLz8wa}tG1N(1L{s+ z5L)8=Iz4&^_OFH`6^DFfwI$FZ*-WiN@{+5QaELH|tMzoVv-aQc9ZZAtZR$}L3sP*@ z%K2}I3%jWf9^M|RG|*XqW!-Hf)1FlAPGDcIFTFy7(WTD6xB8(jGxr&8$X zN+tF^_~_FPdP~F$KCnK? zBcdNC?qli)K?%}-k!JsD)~49N%p{x*L7{#cvP7VQ*E^~Te10v)d6lPM(GUIBLd_|N zwC&7N7NmFpI|(@KJHd%)!^#|YV$X${u#0=f#b=kd8u8nL`cliQ!VwG;c~;y)+}5Hk6byPZ78Rmyy!7Ho`QCsaFpND$BczYr&Uf zL;SLyPx)~`paM^MId;kD66msV(RUT^fMo+AtQncTE0Qv`()*sow|$X!*{bA`zLLmx z;7h=L8k?Gd^?@)sU$O%A&nCU$mtQui%dPtaQcpKGCbo_ehUx>G?-*|eBWA036d>Jl z8A0?RN8?&B<4X&+jV8>q&ewpsEx1b`+sO8*oh&0KZAK!bD~!N z8pmr+`lX@T*9`_1$+Uv<@HN9x^E=qezpf~7&}b!eqtwt>l~!=qBgTE zNS+5j{)mXq-;t8`=?>cE-Jsoe^YidFK0|&^Nn%MY@H)oE6Dj2Z@6%I^oSG_k;-1kT z&3<&O&IP4@d*@ki2dyr-p8G34Y9RWt(H(rlc(eI!ho2;s*J;-wp5&GVs=n1=s1j9h zEl)1brdbF}@+%@jS}QTY!kTXc1+6|K0?fa@`;}S@5(??|!O?B3r7b083+TTqh`BXF zy@)Zuzh?OzwaFB5t%!<4q-5~7={@}kY+#Td7OIu&4}G{AKCI2+wSI?AZcd3-R4@DA zYPD}~fv#Kwq^+li4?#~)?}uo?_T|HtoAKYErN~420@uA*PG>I)+O)Xp!4bZ_bC#A) zm+BFkSqGP3?LoL_?#Qo#yX=3cLS}xjKxT@{sFTWc>1an}TaGnGSep|{BkyIYeBOFO ziOM*-1PHON)bos#&}AvbG%EZvvO!WnC4KLytf#k{o)PL-&li{TrmHU6@L3Wg@g>hN zdR(f%)VsLp*TR0ER*x#pYP<|JQYtNyDq!yPEYzal$G93{Nq0DS?s-)9K)l5Nv}pV( zy=Sg8G2?=Z(sO`2W3GFs4KA+hxjIIBVt>^#e-X4TRMa?0Wd}S^J*Le%x7>c5uJrAk zUO1E&y;`SwaEGd}+oLIZ#rKYX#9~Ma7^Uxh72Yy#43xsKqj%oot@GyR&XtgJ9Ff3x zHbjmie|#p$zzzw;5a*lH6xliUk-mM<`5s;u5?gIBRmGr7aYg+Pu#`M+VO_sG@h&*q z&f5CImMJ#|`=5Ir94}JXJxBY8hzEWk{S0O~gjQcKO(rEO`>$<$2@R_{9HF+YdfZSHKnzC^rmkpHoC}=fs+$80^;SsJOcF#-tf89)~M-d|Hn<5#5 z%Osj{cP``PlFVE;fV!M7tYQg%M2n>sf#zvIf(0wG%}z@V*P8b1#lCT$NiS9JSQT6= zsCz7TOAj;!ZA6nTEi44(XUFEwQQ9F%tzEwNWZu$SskcadkBBXo)I4uI2zlNt4ZJbo z2gDw-?kV~0(9{e*q<^BLO9_xa`5P3F%fHm!?hlk(d-SqT#>1OT=N;@XT?5wq_^${_ zlsh1KYGE$B)#>+kyT-^yq3hs`{FZ<_dj)e=VZXoO_jQCe*FW#$o%G!>5X{3UtV??u z6<=;4_#7}9#7tf}LUFWS9hW=*_4T_ z!+e39SIxtp0lUz#OW+l5SlRdMQ8*l28Qhc{Xl|WHUK)md06V`R{$uKM#gx#MIi82) zYfZ$~6kk*7d%z0UG|!rh`4OvU(ON|-mhPzZNc8NChj%;+c0(FLX?2FpnkR!l5A`l1 zgN607jS5<~$H?&){gS-y2s!xVapmQ{Re^+etb{AxTH}FZ+;ACioYb$*_waY!0bkhZs(9J+4ZB+Vx3bPr!dm(j zhQo(*QG$UlCt||;PyMT{q+b~ei}Vj4yX3LAn4?UEGb0}X>sek#o!@J~)#e`08WIMD zzm=H{V(K@wSW?M#g_R&41wXfUxl7HJs$=S?ak28JA35zknG{EJCxV+dMGxI17?APt z_5x9>_YI~yp3GHD^$sV;8+_~6Z zP{l#5raI|u9&nz^M7a|N^X=1%CGL`hSGd8IjB_f}9kHhkNQ*%9t6-07M~_ty-+#pT zQ#$$68;If8^VKHr#hc`C&&?3;;(8>n>17%FCB`E9Qll%yj4hD%M^4#~!#!_Jb1T(pben6c_RrGmt@vvk zW048Tc;#eN$&`l@XdxT?;l*fs(IZ#AS%qjTa~6j$lX9jb8XY%PUV&PWcFB=nabFRk z3v6-B#G=k`k@!P4T%Ir1zO?ts&A?csUc;4nmwnEA*a}@U9`vYBc`O~D)s+0+cIteI z7E-urj~Mb$eiS{8#LMA|#=c7lBrnUg5}i)A_saQAHlnTUncdWhHEo*e+x$8h%(&3m z?k<_iyy5nM^6W(xBKt9I=Mw<(cws;{>iN-bf1?t|(xs0TO!{7F?nQrX40A}6{ub)# z)H*5w7K{-Fw%C^bXL$$@S9Xg0n>s`q_&@azegGuVQ&|3BPzw`*cSP@=-rW{bi(|6& zY$|u5Z2ox|->hmKQ4KqOzQwm65E5Ja4aNe7Umu=m-Xl9&+J=vM+-h6VXFl8rYe#CLNvS;l%Y5i+|CB*vB%@bS&!r@AmuO6bn%&hus*c)dR zb;^C-o;gwN5MMUxy5u+I&D4my30{wgCAbd6KgQQ*zKuOU)g@ zp~c!A?u-WwfiRTMVAJ-)d(n5YE8Bl5V)rCz$Z-42h^pHm=h6xdNkrP0+;*18>SQ6c z$om!hMw1{bl-Sc9-=6BGF4B^}aU5)*WPC%Qcg5nK66~fEOO${K1qX;IwD8)F59}cm zoX*=~P>SV>=hM+W4F4TnT)Oe7pSs>t`3Q8M(eVE^uzixp=%hax_0abto{h_2NRv*E zl1lz7kHj!v*694VhpnsqSC-2Xs_BUM-*pAU9h2rq)H>dGlH0t35S;NYYV}{`ML(A*K$vSI1?Eja8!Gf1O>?7;_(_ex4L* zJiw-6B(GvHp2Y2CLw_-yE;8IGSB$!p5N8z&Mm{-N`QJqiH#3iGzbQ!55529V0rv@p zl=Q;#Zj1a*D-u7N-+s-`$gWjxPzDU893#jNft4*{iKp=7O3;HDPX3L(8)v)e=dr3C zto^5RCKOge^3gNvvKV>8Z3Zc0-!WQoI+xXDaD)WxW4tW`$?%PEcb#zHzP850t8!x6 z%RdUSKj~Vx93Yx4f??jx64kfy-B;3((c?!->K#(9Bf#ioMp|xkK89)U z6tp5h=Sm6cK^>wU5=G;WCiXgbJdz$6IkY~SRV`7k9j&ML)**D8QgaS0P*4)fSE(ZT zaW8yRD6Kod{1tH}MFv+DCSlm@5a~l5S4vv~4SAm!E920^nw!3DPD@$9Yi2tL*%s7s z*8WP@ql`FKBQ8(JN%}Kfry^9GxSN@vV&_-lEb#m|jYl4{P`W`6pir6qaNGh&zmoJY zZ1r$iTkvg2&qzBlYo0Ij*kaRO>!)!zUMlDQl7cZPla)wj!mWWQOjEOyMI4?5AG+o* zm23zVi1L%Xa?ssbeEM#1FZYa*d*klz*%S0ATK7W47!^WWFaa)-(B}S%$1O;ia&-0? zR4-QL*mDDo9rfVeBy7f?L)I~E1S5T{UDf>l&X`cI@G_qw!gh{Asg6{7_&X*YMiY;8y+*e6KAZO zTt?p3bbh@J!yy~crCn+shwnQ8w+Z=_>Mq6rf`uAD#AxC`hyLJKXuABMtt@kLrmoyV zi30&SG%}#4m0*Yb3k&MNJlPzN8B3$;Y6av}&JF?n$?uesi^Z8k)tcV@hwPw31~eV3 z>GLIUTmFKpqe7bA!rWBO;cnKyGk<0U5}UeXRAAG>|6YY`Jc+dL%C4#7=8gBqGVA%r zZ@+AL(qV6RmWq7ul@B?RO!Vz#>Y8&PN^@hE9R-Hh;Ziu>s-1c$>r^L6dhk?klu_|w z*}AVS01UER?UtYi5LK#mX3%I7eAjMJI>Ws-ssT1X*<)&1w&&#)PBg>VCiS{*8~ zbKiJfaJ84PH8HkY7@gb6{ldEPj?BB)TAjH+E`rV#(rjJOHkfIDtoGO(R%DKz+`|kq zvPVBNWB)X<#Am85o@d8AhSstec$w1~i3M#h!)!Gi@&V1ORG!Ci(~e@hJGLKPG?P?7 zk>P#NWc+?mz6XxWORJL)%tYDS&Ee_xhD3m8h#FUVH6Q*5Z!~07;LkgBls`vIP~lL( zm@uy+xcpnGXWen0$$e4*Vdb^g;N|hyxQ8*lA0)-SQyUM}MuYfpk%k8`W>=C%Pe%76 zhtV$U-W9L7y%xe0^ZO}cO;J+fJR}o(t*<1-TLdi=hWzdi>xOJsyOpT!bMHsT4`Wm&<~gPKoey^0CI|K&Uu$`jLEBhqH$w8Jd~W%C1(Ak80JW z2C1(n<45e(??>g!o<+D55){e~z9F~t3@2V&*@)(IWg#V@(dc^wX9eje}k5gv2B>(D?8Y}sc=(KO}81)D-(Y^ zi4m|da8EDiswaNYp79>lzP!IVCwhR}%{K@3gr3mkv%4#IVqIf5)Nyn-MCTzCbyu~( z+}y{cSj2udH}?;ID~e4fCePBQ%IxgLxMMX=D?C>AA&Zmed11YMv5HODN%?-OWKEyBM^C=%wr|pS@+Ay|74zXaZ21)ug zj8x#Fo2jE9$#e6jE3k}slwcUIir-ga$WmowJne=r>5vt1GgnmF$M6!XHf_S0*oQ=L>FXX^{ga8?E&rmpIlqPg8Cui;k zM~NlwF0eQeG+zoNLAN3x1W7T-Mf4DN3WjA4M$`y`lPEMlyhg<3p~onB}k!etcc_d`}35b zfME}Tq+$r|W%`**o$p+fcDlCC_I2M!wdnJ|Tt$95!`DQ%R%ecSvPktd`Luzk(r$5> zKKC=<>}Sr9@bG@*fe04pt~J(?^pl_4_W|021>A6bo9*)y;tM`Jc5e?Ap5;t9_e|Vs z0p$q$1}*6hj1?Cvg5#{KXX9gv2&V(QsGr{a%xreRfpj&64$l{1rj#aSsi{53MA>S{ zEladY(kW^=9_XBOtT0MiX_?Sj|I$l-ioL7xfw@*i~wd8OE?v=w7{HM#@CCMT9$BO2%6x5;4lOT?lw3C2qegmKmr7JcXti$!99ck z!GgQHyX)YCyALqmWS@O*_C9~^cjw`m^@mxjS9f()y>C@lm62%7TSCn(`CFoxXTKS~ zw4OyZyKR5R_9Wsy@v(*2&c4jbE9NjR=p9OkH?i!2Mdvg7B*o947nE>fpD72ws`01I@>q^HgvqtMAKb<=Wkhb9(Jah1CdPE#GWOk3H z*nAt8ByNMbAq%%U0>nY6=vvMW7j4%Qlr>yl(z3^7fCI9G;s=!ehypw1mYptZgmvu& zcEx8Unx`8S$cag7nn~Fv=n~#d4{Za_$SstIIc8>8t8EKO@;D&$tr|W&Z)_RxgF-K* zLoVQd-Ot;FQBPp&w2_C(P<~-S;bn8~a9;D&Zk1H@vs*<6bNj3y8f10FiGwWTwegp4 zv0lwt18TEW3G{T3a935i$%{HA$Gd8F6_B9_>$6Si_eq3LFt~>HI8MQ|*S)4x8T{F` ziuMPVzH@yn;nAdkF{a@YB+O9IhcYh7&jB=e!o7;)cxat>hadC!UGy`C(=DT4d%sw; zp?b?RUWXvNW!XOVW&!Y-&@!s4dKm2a>^L~ieVpvuC1g0%^3t*U2@j>*)FO|Kvw~QY zapF_u7Lv)$Lk@zMOZX{Vv|Cl*wbd7%&wHgErRHs$76)u+xrOTGnR~q1_GfvZ-~k9o zIG8wIxy4aKqU;K}u~CHC}ez zuD$5*VFbVA=5q8N^0Nyhaah^RR@=b54t{z)yauL_M3VaDJhtHYC18}IeKKt=D(pX| z?d?MR8ok3TlnratJF682;p<3dgyFzq#oUU67L$-J&eJk;k5+{>OM&sDVPr#svWoGh zXL-qbZ|svR7Ud0iqok>CKor}Xfqq?O2{2VFRPOMhV!r&5_Z(g$Prl?C%d;|fT)jbR z!Lakx7GqnS!;N_DqtCCnfx4K!_i~t)bPt4ycbBFT_4rNXQoh_UyEs#nTAtFAD{#EQ zIF>;ft!N0D`PT!KgrdulpO9|HDm%M7`glrCD(EVAf%f=DOwm1hF5E1BhncRdU^U1aK?F;_Fgo&Zy08Pny5~PO^wG+(3W6a# z35P~LpU;N-IASTqAY`ENg~RPWInFELgO1ep5BqIj&ix+vWx&{P(6vMrB_)~LD`i~u zY;mG3D@VS@3KEWS31(E{P3vRH4bFr z9KH6W!1|_}>p7#lqkkA}S*)`XT3Jb{n3WYol$p)hE49LEkdli(RD&f=?HV<+v8#w# zqULhV19qSdgH6eiH*z4L;@6Z2*(Uh5?(*lezd^62*lJ5)x|;c<#4%{cle#RUClD3y zWElK3T_Df}cPPz8DMh+u{v(~HkaSS!)s2}2|C{}3+>%T7b|l63B61Y1YN|BBY5oS1 z7NA?}^CiH8H|TMPxaG0SCf6bugUp*WI;#gv^u78KVL9!(!eVlYWiNEwl`R_Z)!i^z zjW(n<*Dp~{l+>H}<>Sf9Zt(l%y5NUJC8OC9LvKj0rZ*abzUuN6tS(TO9J5yCeXRla zHqO`1(W_gt`+RGEAXr<2|`Db`9gp3ES6 zT`z@@+hl%MT)WG%`N*Me=j8!#N(*D`0^#+Y@;>tJ0g74XfB#)A~aa zBzc^BIg3m5ZI&-Cu{&)j-=RWTKEm2_4p^9}fVBvaC>b});0$uAm1T(s%U-vs;6;3- zh>uIksTFKnw%=0lA*fWXVHuMsR1hXO>_3IjB2_(3h#BxX78k`5Xv+SODtGt+W6uE z7NSw7E&D(RkDdMCKr)MQ-_y!ac$ymrqhhyFQF$>c_{Gky0&}p{qx9F;JdZz-~S#BsSz?b&tkwK6xiyA#3Ie_ye>qau2uQM%@t%oTb zTf`!oX@|2CS-AHpP^!|g@t{s2=!pUcX|@$BbZRQ2Yx;4m@IzsQsioaJEzkXUC##9O zuX_Yg5jJ{c4@gLz9OT*PxNWhhTaW0%1dMD=RA@K_Q?*xjZV~$`KX~}C*2KRqrh0S; z5nhSHY62Xg5_#Q0=%jvmA|_1MStp{YJ!SfaHJ0gvQf93ZWjZSecvg2F^wlQRZmgt<{reR0?N zB=`(Fn&>#Y3^|s7hnk%^?<_xu1U?J!-aOBtZTl6Fjtz)zt(hqTDv^GeQmnAN~ z18#mrw;dTW1Whe&s3*5zPP35?qjGy+Ri=E_Ygj)uOpJ&<(CG2XwCS!Pr|J=i_R*_+ zGeNL#-YbM2goPh`NbcRr&6#dO>iIY#F#R?H=T+;iN#u~xD5i^>=^+Y-L8BKNuzjN| zSUN2|yF1f)DZ{Q!ek)@J#Z{1w%;JOHx{)f`A&`sU?2B$zMh4D7m*_G_0LhC^*q{_b zcUkt6-X_WjwSxz|oSbDjOr)!?->3FT00$cIBks_m@*y5%L!IRJmEKa1BuI(CO(e`0yBV@#T5-feN94f>VUiX9n3B z%&6cFd1zclyMvo6gPW5^X7gLcppzT$WeT^z?T2I=>M zIgvb#y}kZR{E_8gioFA~=32V<4Xq`0-2Z6tOJ$#yABaMqIN3PHN0n`H!->k>-4cGG zTkfCF4Ki^dF2+d8Gp#Q{?i2vTx;%V227NfrE5(QLB5?Cr^h}25kv>}$AVS29C&(M| z;7s5z<3o9RQ8j7T-BssRi=%8BsfYd+V7!8dQjGI(n)%t2AeW81u2~1YxQ}{a`uQ`o3;MY1M{rt zr)JW3NL+xI+0>H3ylGiO)=6+@jF?k%XZd){*e5=*n z5wf;V5DlchT-}~VkBzR^fae!$@^i;@@`E(qN*hA%!{~j)U*IoKas1o{c#V?FhXu8^ zol!@(Vi{Vl-)8hk@Zhre-V9qS_Vp2`<~2+!aNzhEwf_XjaJr# z3GF@gWB(iKD8jdDKlzfxEszpINp*jo?{;THR>yPq)@$=QmJgIi5s0|mEc{uu!f`pB zh-T(%7uG~yBSolQk1@A!dFE$JjviC}m9A0xZ4skV2c<-`i>eb@Wwi0r6w3g_R2?CO z7&3IzA#>lIwjboh?YJeS(;FnnoeQj%nMcMBzbGK6NVs_qAJ@05^a5y73i#qIRWzR0 z${1Lc+MVgU7K3z{1}*uSzh0)KVxOLw0kU`ML~-D5=GB;{52m8vQ*?my>OM-D0kirS z2szw?y9_+Z@J>O>7Ys4@<|-$U_)b;xJY%t-4=Ds+_~H5JLmlGi7H;e&Cw|L%r^6jX zaHa)q8SVpl7+(F1U;diW<53{${R1kC#y;JQ3)xAIo>12NaY8E>jm|3a)vH0&S)y(bV-*W0!a!Vlt^aaxO(W+=~s(K?aUqwP-KGQ&dx z-Iz|0UuaeK3=VmCW27XRj=y9|O)PtYaY@9+{+kOxr%gsjem!XUahAXUVdvWRqU~i= z=IQf$4gnvX5P0@noS1i1C!}|aJrd`N#A@oGpvOGfogxgYXJX)IMw%UB{CC*{psSVo z*aK&7N!R7~wXDY|$^3gvVwSoixzm_#IFE7r;@~a_f3lBf(aCdpcuQr5h{Tt_C5s|A z*JA0?$}rhh6+^}+6Fn6YU!o|IZZZ_TNP&t;08a4kaiqiYA^vu$qn(|L#vxBp=)^K- z(xu`cHeG9!zrq(6ecpfgqh2f`aGw!0Q!a9b)O@YrK8@jwhf z3ARcMwt}y%7kmIWudy?*p9t_Dm!zL*(Em*#g~O>wE?^e8J?p+(sOg%h*UabA>~Uv0 zpB@ARcgFc#@^4k5`dVw(zu7N;PBpfX*WBp8_u0JYP17a0<+Hr>ZJ|@m^-vdt^n>|h z(xTfqqwG6xqGfiz=fXbmkj2PkZ%8G_nZ_OT`D;l@JzkGVOw%9i{!kehS?$X=9!1P` zt=4&|Zu4_|@%nYEa0H7Q5x*R}qVRDth$-C$jwHo=kGo!a()TE4s51|pZ8g{Zf^&Av zpr41d?6tY-MJTGIK*9i<#yAp6{NTc&5K)|99G#|v4WBLA$47)CRh%`@w6h*>BVRtH64!x( z@ipu3pbNF3BX^6+25rz2rmKV0kByxE$B~AI;`%pa*lSr=-_jh@!8?zA)s@vfqtjWp zBs=yFn}P8fFDx$E3X2PB_LibE`szC;A2X4NRpx9T9!FC45u%DR_`BoJ?OGr*9aYe; z1S#_tO!cMIZOkPvsSmN5mNNBaNaf>aj?$G{9eVcb+ojA7fp$g=_#gfg1eV$cA&RAN z56*~f+$I$YTyD7UrGZzQIg-N%=MNUTfi5=hv=)yyXlvsO&y2BayZIqkA6l3*(iVWG zaMsJmv>h65ymJ2u7`xIHlPXY4sN7)2obZOOg8S-6Q^G*-9!IMO9xRtC8!Q!a(bKcQ zT$=a2E5Z)mhM-cpW=V3NDn=*NAklZnNt*dr@U@rDf6E~S>D}EKHpIvq*n_#fXc-4t;whiSqZVTM&HegE2XK936bxM<0UfR_s z?AeI)_l(pqf+y>!v#R;fw#X=k>~vc$8d40XeIj2h-bM1uKI_YI1G#QQG;Vwfk2@*TgMdb>)zpDsq|r;rHWK z#I235NW=^BgqIzB!n&6LsP-z`4*OO>`=z0FSs@`nB`!aV?#Ll&_lV-{fn)&Q}?nZIDr0K*5CDk&P@dt*>^@HeRrdDEE|1z{Y`J%sK>5?lM65^cA3_)pSF@ zEVxhCzHyu2y(##u(Hq7@N4~k64da{_aa_>99Km zpFs zx4$2MOC0^_o1_LwU^ubgHohyW-@U>|_K7hEAd_=Jtid5CoTE7(e0CKY60%fg^w;&b zhrcv*(RxTd$ziqB{VP%c_jq;64wyZsbZr{?M$%QWS^nV`kweXPSvB<5xW(UdPWIs) zz|P**oApx(@b6*3FR_ZKubR*iRsf>IS((JwuczZYU0mJ;X*@mesZ>1Qh$>gqZ^s12 zevmHKxL&_o#f@BMB^S-?G-xEs&zl{l5#QjJIf;Pv>2`ds#efXt?kSVrHIv`!aksl- z!=X?2r=O--f1?rj#nYZ~l^)@X&;oiiMpyZ14vJYmOr6ZihPAJdNE#jleZb+=1i!ti zQPe22q3*QDw`jEmPV2Dc>fS0{8xy*{`l#x>uKi(n1S>E1DDuy3`~2_Zm6a!3iC(-w z9Gjo7|B;arddKj$UHa?7H9f59C-?V~|L0!K8Km?qNr%^@t{Ia! zbhSWC%0QJIN&BGD+F#JyixL}PN*fX<0@YGWY7oOJigGXw5#OE<;L`6 z!n*pUiHw71&26#guSs>xy6(#`itPNzC_=~VYC^efT<}OkkWlT5$>u)RljJ*H*&f^4 zpqYTkb1u!vXX;!p`~tzCKeKzbo9CN_@cs@>ahS1_?S8OR_#EEO%^lP($bIbzX8&Jx}HZ9z7alw$ONp zDg5%r7Iy!UI%iP#yQ2eMHaDe2`0S!$4GaEAgU3_vW8#)@debVA*H-;czTCt44*CGE zplOiv(a$`1Ob1hD=caapT!@HzN?oz?lG8k_r&{d!%acK4QuXJbGlDwInQY8@4o5wS z{!UipX@*QvH*QC?WF!;H^`I+e-E;P6Ef)D0b|i%f+8e>5O%M zMU~4&%NE`(=R_-2wnylVyWcVDRh8E-Jn1@pC`wy>yPX!IZJJ%3B_$1c_$38TN?MdU zoe}xXMRlFtI_7+ZX_}9AwpiFrrE!Dll?L-5(g9vs?>T*hTKLO)`tNw26IWXCPJN;c@Cs*HnC@#Qidt_; zN54YsLVHp*16Vz&@0*MGOi1qX%HMOXcHt?gvSn4ML<-^AV0r1ldwQAg@Ft`p*pE{R zz0<_=%<{=9+il_@QI+%pj;rXID?BrCM(rPrpRC_BdFzwxQ6dDq7A!?jEBow_4~h;v zX&MK8uhRLVYwEdg%;d~C_mAa~lOge@#>d3pIY9Wf8vZ6Zu@1<6Zog-m?y7?LLddzS zzE6q|&odv};j9CpeVhA+qIxdz)iz(LgRZqTo$yXKSS!-#aPt!7v^5Uh@P!S-OS~(t zHBVi!k@3$Bq;A`vaEk3tcaTP^Y7}pVY2YNjubvZ1qqC|3#qc&6$)SaB&+L*Kps-6= zZfwf45o;qwML#10Ip|=vb+PHquW>AK#O-%}jcVTlX~dlHNlC9W?!I%#9p(Q+OY46K z%IZU&MR!IdE-P-S@ASf@Z&?}{k)izIo)LP$LN)ls3+nZe1#Mk);bDVoTxFh-9XZ5q zgebY8!CGwPb(?Ol-r#!<=DnPG3e@5{=SYkz&Vo`AlhdZGp1Wt(Imo`){vs*6)Cd49 zdM?!2cN57n#9zJarW z?(|o1w>s*Q7jzQvHjIRB)W&$)+?RM9jA@b=$Jq7Do!@ztihhx%3k!}Vu1|X#nQfPh zKbP_SLls!Z2VD@5*f8|iAoiJbE9m?z^Yu?C$WK<)@TEG94b3tETjzAGb`o8WAGzo) z#tdzeJza0bMT&@D;3ArOrgbRWRCh1P{`gH`OIWhsu>QRb;0Nbh)0&s3V5vl{pqz?R zj>k#%$q7PgY+~yYU5M8-0ey6!ANULRV&=Fl;Q`-QiVt?n7=`EnQ1oow z^@Lj&rAS4lKToRQ`Pivw*z`BY$s;?koE}u4SiEe)nIEF|t71(P3Af9E5mPeb1{{f` zGH_@X1obAP$?UOY9_n9vEvd&d3^*3ptpOd_MhKdW3GZGe~O#r?I6At$#*) z?E<>|u6aaMB`Y%GGm1IUUnyCC-u5i?hi}%PtpC4xBBL z;$S(mMl%b%4>IUNrGJbxZdJJVdJ&(#7E{ zEA{En3?J^%#Van9*+m9;gS00Ox@;w~mT}%Vm!&)t<7xNSop^$&QMSb*sL2I)vK2>b z{GD-EKJb2%J@gc0DWb^#@y`DGevc)Vl4EgRC|iMV>h{?_4;xl1rqJLFEB?SFEH$~F5o!}7MQODzu9J*zcq7xBq4>vmH{nP zz$HG(+b^UJmemK#`WcVNa4}!wSQP@$Eg`Y6ch<8-4!%xII5Wps$)h?wBE%L0bJ^X+ zt9#YY9WTE*$%U8n$GabvIRWOYm9`5&%ekKacqrk}ZPQkYzYR|s|DADj@-w)P7e~ft zHHAkK?gGz#5O`I|A$~4Ku6MSCplPwT6@V-sauy9GKa3D=! ziEtx*QRbEn8XxiNRRZMO6(SN*b883e@sqndTFAu{R2sT{)Pds`GLyA~*RP72F*j~i z^nGvH&=Pshy%dZ*+*rV!Brar04K!WG%-bea>vvc9{A_gs4l9b+X#GZiVavh0$OL{q zwd9iC@o?)AtS7f=KjrE9-H;*z*(klbf_e|P54sVMB-<*;pB3j?uBg8$4?6psw}#7n zY+B3{Z!Y@n(#KZ{I$C?$EW&bu;rgTR1O*kxJqwZ-zV4zm{uQvEr*>vzCYwxEVw#Ot z5{RD0#G&s^;vrBr1CE-_YZk?k7R9AH67_K@t^Uj#`5=<-{43nacH0rnE`q;RDa!37 z8jZGI_h*Cdl&hr5^@Ucz>=WmAe?-KPu5gY1tL(3g5}k5gs;J}5cb;(;TV6}>)CSm6 zT;EYqagVohE(eIP6L!bh6cAHsNB=3%9rXGicMygffIPj0x^OKr2db6!f(>hl^4y~j z#!{tjX08R4iekhw4L=(_tmnPLS(j8sL&M<_bNl0@68S6(#((U;-5(!G5Zj>emfVy0 z8=^nmzaAg4_1iM*t+-y9c`tEZy<<)h#W!L(h zbz5lCArtfh;WFq+1keud6xRMoRXDEye7cn}r^@DJ^JgZctU+03=H_?T-@j8M2nq=$RdI8F z0Q^HhrKIv2`p-T7@e3&_L%L@-p+m;B{`rp#B>*-j8PP!L4!D=pJ=r)#@kck})w>l0 zf%7$?*(IJ3@vx`SB65?WGC>*`lP5%tZVhI8@vJ_NOg^`t9D)`HePhux@8H4RZqC*2 zmVLUP8?%tL6F+Hxe)x6{bSi*W`hGv=nV2A{Qi=qk7-E~ICg{Us z9nP6`irwQ0d$hw11lF;Oe~66ea4O=t)napIt0iFEc`>+E!j^yktNglLm+Y`LQ+1Z; zeT4Yr8vK+&Nw`;Ql6093t?Y>>4Sm{!)cWdDGeC7s|H3I&3aL)9(JXp?u6Z!j%r9+_ zb-Dl77zVij;Kyl#^bk&C87WcScq}@FNgDsTGf}o5zb;j8gP%e|nw`3d=o9KB4O7AW z-2FWSJGiTCBx&?24XED#NwoTpA!flvxkvV$5OZZ}#%y$rnH&`zhMk*3zeIOZ*qp?* zdIe9&Q@(eueLyFtIvI~9qJQp zQY0eN(z+~>>BNG=XsMHjK|RnN8l5LO0DaZ!nQeBnKlHe?r(&#K_Rs9!epG6Md)3Vb zKJb$RUc1+Bdx`*)aMoyzn~+Br?~X}DkzTT6&nz)mb^zevg8(-KePvVMn^f^GBrf3G z;uE)VLbtnTosW0eOpzT&GQ+Z_)J{b3*!tyF9P8kh$|G%muu#zP`cqOX#rGN&2(gv1 zRKxwcS$frR8A64O+9_CY+wyqG-#ZeBUOh8u=@pUsJ@gRGCl>RHhWKQ(vu^>wpGA9O-H z^KMiK0ljrfUIQj?QGbiFT)Gh+p!dL6_{`+lI3~U;Gu{Drv9r?kPR^7i2Y2VsJbRi5 zK0de`$KT@Pgiqe@i9e3PT6GoIx6=epfMW{7G=`OiV2@ccU*Z*G_O+)N?q+5b2==x! zhwarPQqF`i36W+Q;Ud+}nBv9FB*(!i$F+atB!uhUFp6dBetacf`Aqi65TjQ>0p}q= zd}aNL#o+$|vORa&7-&(Ea~iL6cc6Klnk6Q`PnBGBU0$l6x~Ac=MDAH0h;Cd6n3w4; zM9&0J{5T!>ar=wM{v@TRV9;i%^U-Q1z9>^2{L8mPXrO?t(f}lYd?5Az1k~bq*=dp% zo+1#ad`O|@w`3_WoRkHyHtUVFlI7_ulS)GV&I0@W?n8d?TnGozmu6P~2eRGILq=<+ z->bqGnzh1Il?F|RKMZP5J%<+BU{`X9#_!3-#b=O+(yJ9Ju6$GC>_1t|egk60^X;%d zDB_yxk7anw@`?@+bDFf{mA-oRJ9Cf&_xr}dJ8TMm|9oKNrQv7W_!M7$(b6onpa!%y z-Ix((1VYQ1rGiO=m%=txac?yvaWNxnC~4+W=28=#RPxwJXdHh9UV&*>-uPz^U1|K$ znaJ>vJe?NCItoXU?&s#IjQS6q$bv!$3^)3Cd9RL!hnms_N$E2`iFZd)Sh8`&Dj_GQ~&c^vW<&@W)&j&ck*%dT2x;levJZrKt$-hyiCIUISJEjv_+tT0@=$dPIG zYG(eOZlCu<1RK;i5X(dF(sX7 zsJZ7s<%+0u(jVUdub%+^l0g^eJ)_Q9nN}J(&GGW zU%*G5QZkc{mIqO$L?k=F;iKKHVbMW6(UUHI2!_0tRxRL|O1EsI%!q;Z#pU<`Hj;{F zV-E^6d1^MZ(sf1Azze1J!xM3|_RJwiJm2Ub{1g|9Ab`iX&yGq1FrwXh=7V#2+0D3EY%YMH&!V@4Z(XDwlx+^kvJ#} zHbBF+uMm+~((S160{ApFKIyeeOd%r2ToZuP37IF)L&-Q2rpk`{MLzNu4^{m5qXzo0 zCSx+WYyi#Y)QYfL)DC{v``unf9Z@J3uq2zf6@@D6MI4eDFyqNHmAp)SZ7W3oE*U!S zOs~es=K(l6OEQh%Kr2bEI2+m!m;@$=lKG&fDU)M0^XdB8e$!3BcKkW!E9Di5X0MnY zs_glG_1I9BMobx_4ZZt(oxEIDDROu)>pxK>N(`jdr;4>ydOqCjS!N2D5B0^qVH8du ziC*QTBYDZ!{&UQpa3=WtY+Q)_EDN@AZPwe~>2nTtyOFD9aY{05YB8m@u(^2PA_L{) z>1aemVI+lEGbl{$d4PNCUsJU{?~PyZKIiyatOMi`{{alxAFdjW>GN#b&b}oT$F3=9 zoNFmZ*r*fUS)YPZRFL{O=^gViGN*#{o>^>k=+y1Z2d{Fr^x>PJq`yOEm5? zI_(r66Gu-a?rjY}>o(o*7w{g4pT(+mVsWI2cw)^BmH*h)*jqRjs(%SjNWp;(`#=;6 zMPI%cI2$4$Mv(Y2$-wC1K)S77;hfc-POV=*5afU*jysymf$6mF1H@Kitj#Amf?7qm zl2(>*&_{>APad)y5$#Y#h#(eAi+w@2`I!-f9j*S}+a*jFFg6LGihQ z`Y!}EyLiL8?Qehf1Uh_ROnuYJl*xcrtTCy%Ya{x9a zuUk{&XPeI+%UHJ}Jzl{>n2h9L_DMhO!sDk;Zfw-brVClr*tp{tc*Lhoep*$Q9(%C9 zFuw3I2YiYinM8vbjX={W#RjzB&Bvd8{aa-?r5^xgjOM)PzJ;9 zHOMoaS6GEFM}6K6?{)8KY;O{l^ve2*N2gsKJu93Y5%%fQ7;Vqf9WZObA6;vF9O=(| zVB=ElA5rW)9~~=WK~p~By7`&aCr&+;3_lHjOt^nRf5SzF9gGORYVL5-ap_7oJUHb{#P7#a6};?`Tqi!C1unPjfh8U=_*E# z>~-I9gJ(b1B=w$&q}$cn6$nXK*64e~W4AV9ejEO2+>i%HpBT*^-L8xJ>SC~3s6jyB zygPaG&h`>jOl#Jj=T*lIM$$CT^lY;}9WiY!#oDH%BB`LGz0Fxq}p zhWyM_7MkrA>RW%`Dtc<-f@ z`l~B1;oUd8PBVleGD`+B_4KO zwjn)mx&|=1R=%7IR26A;bmBc5D$0BcAW`9;{{-oB#1DSRS)pli6nrZ@Dt-9CRvh*_ zp8D6P4>r2;AOm#D3~hle5LU2YkPP-o^LG%xx8%^}nBuQ`Z~B)0>5xLIqpXQK*W_l+ zepRyxFZaIlcJb%k;uZNB0SIXHaBoQ6%p;$EmnQ}OZ(m~;-}7VP3)8*oK|~9{ayG=3 z#v{{sTk(ZOPU7n^K;w~hv4RywC7e}V;eTn-y5L~}bIrPT`(3$y<87NF!m1O`1_fS- zfrBF`5#JFw>FEp-b+C>xp$ldZ*d$feUn~#T+7Iv7>S`DD^;~3g zcI4H&zd&S4Vs*6mSGl&3ZpNaP7H{3ly=jDScfo&2YyNF$vMfcAiMBQ>?R^!wTVUMm#^#vp)`p8)WYa$V?Km0h1^|3d zJL)|m2s=!X0O!Kbt8LRh?&4vwj~doh$t|IKS@I)YrWGWJ<6iH4Ma zzR!15s66!M2zJf_9gN$Br+!AV`$WUe7M^Omu1L>E3$ghMjGx{Ic=0}-X;)DO>6+JAlr``A{%(~0 zcRiK5H2GN7SKHAUIqa>WMEGd1JNDoJF9ZR)y_QE7uqK+OpnPZWIEsZ49fQL01Z8k~ z*l4-Kv|)QL@kph48GEnhuz?Pg6grdEmr|R!LSsLB+Qx=~oBtq|`u;h_^1myHNyrBq z-mntFPeSb=&y5}(7MS19|GY&ab6jw{lxGgEnc;AI)%Io&M9&J5^bMt`R#pHM=v^*c z#5Gd zx$b>QpX8swXD)ilSg86U!mT_mPRu?=iR?LovSe{vuUBd+qu_)^^L+>>ByJyczT{ZOWb`q6|ga6r|ov@r0&k$ z*!R{2KNtpK7Z~5`0u1Krenv!DAoez4rU$zQX3YwP{_r#bL0ai*KVu$R+17*JYs>3 z5O%CHJeOYG-2rXiZ}Jk5igF{17Awct*X7gcP=pEv3wY1>_k(%#9%NbbiumHK7m$;Mt!=Y;GWwXZjbf_aa{-0d$sjOL z|8d&VcZp4I_w9S?z&!zbUyUu8)R%vt#BQyYEE;xnlWBJRD(e$Imw~Q_5XM1DSjURLvkS^o)%HqKh3$SEm|c38H*k4@s#}8} zhw4!`j)S|oq#>5i`UzbWPdXCjj*g7D(MMlGKosRAS=c*~)Bgc>e7tWk^S`TdF7d=W zygzK&^BVSmBD8YDD+6j#JP#gr)XO%9dSiQg5k(VKo%Z@XFj=zam}W2Dy-Nrwg0W#N{k@spTxj`&h8b$h%Q&T!}S#lTXx|eNg=| z#XNjyo8IlpVa84KTVS&y;D>u`aol&Kugm{qU|4?yfwd&FPr=booP_Imol0uojOu=e zH;qEGp&I}XBjzyHTYEGO$>B%RRf_^dTp=_$wn~UiKt%igX;w##e~k-0mhI`y@(cet z*yZu9ok()a{VPf)t(~i(kDR}Qh8DmkV+g*ksQ z&gp$fjLaG-!j_uhh}yp;>eoxe);G+u96xo%F6qQ>&hu~X;N}J>46k2phP4oAy%4db zUtKV1cqe8bqteGt_;Nz*uGKK1nKQbVYqIM*6Qx=P(ic;={iG(ZkO@1Ht$85Rra6B7DL${y1v%Kw9bn{kzET)5prhsYf*z!ZZw0I=x7gY& zy{@HPgIvlEKo+7OzFcLu7P_6yHxIS!X^SRA3rC$T;Hf|H7F28oK?(@i2MhAd9p%h! zr$+_cxVtUbn?|D9Fkzn`x+)K}c-L=VH1glnQ);`-zH5S#_v#2GRTw3X9;RK@zSEG% zJ}f5c%buuF$Hx4(2G)|gyCh;(CgHW<(_gGlSZ;JyHfr%Wzmx6<_l=|~lUqmGwiINf z_A>YD?C?b>Dm3|I$C1_EORbB8*iZ&lmCEZA3oi+s_C_%o=k94?Zq)&K zU?991q@UQ2ZO-i-47K{apwyCtc%m(1+t8d#Cmy>N0K>xTLs9{jf9oxmxZ=CJJHP27 zRV3TPg=!S5A;Y5}zNqQHd@Qbm#}zVR*tgwGjmIx{3vT;c8~p16ACF+DIE&kCF|Q_Y z?QGYxR=!t@CGF9-jI4Zm{y$YIkLZ*-6^B~yWv@JEB(Uukq5=8MHrZs3?BQd#M~hWg z0p90`&a!3yW6}5Dwy_7OlxmB_hceKqmfhM>f{TOe0$if_#_>Pz5H6=R4a@M);Gs$K zMtd%VZL0sPdM2(5;2k6dtps-e#K+FE3rVQ8A1ABK$dyr>RL9d#M<@so%0QwmCB3D; z>=4sjtG%`vIY};B2-&6QV{38u&eHWNDLq#YkXR~<3T~|l8Xgz;3>sUOKc5%4-Kme&62ByBl{n~o$CDMO3-%nWJ=B*`#qUuBe6ydIsFnWr z%yTDv($Nv);K$mkwwNWX;*5*s`}d2$n>S`o{m+EL)jJym@d#BVGM$ z4eFy8NQl2Y$G$YHUcuXzy?=$?pjEf@db2P2wS6Q_9;4?5btKV??L5;sT#2Fd|K66m zGd|H>(DNJfGALuXY;3q60YG7*{{FjoBEE$Jg+-FFJIOQFONyJZ4-F;Q8a-kT4L#&uD77>vmhcT0Cx6LefkxWxF@F^Z zgLzKbs{aPUE_!YkdH$}6uPL~@v0Ud8H_FY_+;71g1Fl5i1EYP{c1#IrcJ$9_y=A2z z;hEe*QFg<^Iq-^?!8yno;CZ~XDm_?RWY53(Ho;`hXS3NZ5`8{TLD-|yP<6VOX>&ed z80mKRW-qId6x`zjBg?#53}S5Q=WbH-2{}EcypQ1nH9cr}FV4xIzd}Ly?Je(7ZjH;p z_aG=UmHoF4QCJwLS`Ze|26@7sYX8jIb82)u(#bN(61as(Sy3zyMxV{Y@x8s0&%&2Q z`yV2sr#;u#oOR3*ON2GB3;6joqs5zR%o>X>kIBWLPG_HEtW2LVp1bqBulgE4s+Tyy zoQKzuR`fA5-l7@TDFZ*}H9LRFv~)=_`lw?3P|VJK(z6##GP`L1H;*Tpi(*zIC!CBvlf7pS`I!b8l**gs7NTDR~pRc(_nl{4{W(64~Fd$ z$exYv(PtVR7rsk$yX3hvQLkU2pvK3+437!IfF0}iQ#qn9D4ob`%{!1+>)Zz z63E}yq}1?EEDsc1ixR7s3b@g!Sp70mRd|)RbdgG4@9duxUG*HXtz#u0N6CsD%0y4^ zb0NqY=RL7>R2yThVe)djci!D^doU@u21V|IKx4MjO@@_BZbGwQa9qW%qon3g7>3cJ>PPyFZrbLQp$WD43N@aMIQ+WkQCZlyA2eid!=y7^R4Qkf! z(zsk&^TGQK=+)JR|0-IpgGzL*_oG!-jGH>{M81l*Val;R>8?HG$#lTW`< zZrSAA0kv>91gn}+PH{fpoDon-+EGjHsOhu@xR07Ay+Fy0SB*EA8U7U-mwF^hinG3V zkFKid`~J)&tAtmVt?0-1shBmh$cbADP&EZUvW@oIz~#}J6NVxCxbl0;+@>XeyAuR1 zS4&D}W-^6L#Pcw&0om{|1=~@y7<490yEs{zqSP=ZcfZCTCja}Y>QG=kRQ|cN|^TYM}QcV_P$4Df-+yFTc zu>3pg)X3{qUW4`5@kQ9022lm`q*$cON?}Ju-}JjrUhD3V3w&;KIhp&xY~+!_dMWzC zVd5UjjQn+w`_}^|?+hG->H)Dmh{D+4I-Z=p)d_J@K-n5p2K<~5Xa#v$E8sf1tl2ln z=tzPbwGxy&@`e#f#T@ajoW?9i^G6c<(?sB8LVdSm2Hkdo#D-W?n~z(L)l`nQ47Uu$ zFuBN?M&@m6CS)v+hh1IMil=eGRMa`y$9vPw`$n~q{@64b_~F2&sSSKD+4;T~O0}iL zEyK?1aIwYcALx>Xx44d$3%xz^fnq~djl7FvAM#~PT{jyKG6hAcj0gTd00}|%zS~7} zeHYF3Z}RKK@ViR*alChwx0`#2PyOmyE-Qlb_pfv0+?ZwE3E^x#!7nejvG>qHs+VPQ znSFG=^BQko4vl#tPN>&OYrT`p&DA{qmAzOei=`y|wEXV$xMR*luWkSBVUBl>US>R$ zTwdEYzWBvmSTY>DiFCK{&d~-s1Jl@&Gj3}H<<#r^+n8+`@Au+3a~wxoCl7z|0F_g1 z%ZQWHCk6v(i`+c4)!FcKUcWHr!8;*(uAbw>)$?4~_C=oDWg%m`PQpv;Z~u)GW4C|5 z7sr{maI{tPh=(fz>?W4J1tR^ zi%oQRV&k70ND#XdBH-yIOj+g^J>bS081Z+&jS{mmVV_pqhvR%3UAM=yH4!D)W9O{* z78SMCSTcV37R6(~z-3pE6l-Zwi8@>9@Wnt=NX1qg#;mE|6LkAVOsf^c-R+~IaDs^6 z2qBk)?(!;1(pZMtIE9NJbl|y@;<&SfH=JfZ`M6ZM9)-HnM zeojHU?Pu}as#si^7twAmH(#bZMc;JdP6(f?17C=#v#JIX#6kg-s~1rmdMq2aP*F7g zTL!K)(d-<1ZJT`mohU({kKi3(qJZCYk8cY=U%s8sln?$jJV@h{NrS~&g6mQ@;VeDY z@-*)bdwWmMGdDrCJ{K1+*zrvF=FMoM=Kc^(9X`UY zRyvmNoN%C#5JJqSMRb`a=1-KiSCYX#QytHI?>ijaY(bj?QFk+MzW4)vQs2x=|M~B* z{OWo3r8@DC$)<`16aESW)(XAZH_L}zc(`91c_v_g= z^!ISK*E2t^=g@|!-ajT_+3%(6!aKb54?m&7b(9}G8zJ|{&!yguFtaSh9d*>5Im&NO zf0f;jOnsAKdhmJb9~}MI&~~3{`D3=pjJC%#zvI~Urrp*N(%W`ZysuxO?bu6v?;lQ} z9Qzx7vVCl3;5*l)70;{?YphhWSyNyPBl>v`*Ut@r~ioNTS;scjQ4)!%xY zh8uBmR$3^&p-dY1Q+}Tepyd=(y?;NuRu`ZlhX2|rjvj5H$9;|?4fpZ%L*)Z=U|*I7!^#RO%Ze~)lLwV} zlyLuTd_B<#`?P1}W)HprKySnt2@r?}aNmq!y)X5z!Shiv*rzd2TCsuh<$5&42z7UG zzQav4=A)y{iFxZponkYY@-#;G#U?H%1ERXZQp#3aDKhBLPLdh4AfirMuLb}Og=^QR z8TbsMc)~z7Mx%~EAVkdDgO5TcI}B>HT4GT*E?10_3AWeR zQYzM$W7caR7DDMbPlr27%-2Ed$7X8M+P>2>an|nyq6#fd9r%*LNnK$nmX#%xEY$*0 zZufL^v&W4m_0mRVnIxh?d^a7~9Uj61A(Yl;vd08rW8D|IkPP28ykK3_G zm{6b_{~TStD?Ms1_v1&B^oO5wOC6EFyyAUPPCS4s{E&Exfw;d+(GdJ6%=OdyeNba zGb58P-HSTkME<`)x zPMUsqj-ER?6mNNqr~hmp70c$fcQDuX5C^txz#E`3Z{)zE+th%Pr-`4a3&;OMA)aGl_rp6Wo@|kQt(-m= z0`ycr_9T1P6sXJ0)=;o!FHb&PNe&QcJ4NeM^G2n~Yd^^;yPvpW9ee-y8$7wqN`5+T zoM~GV3e61;;^bi2bC3gDEJM?N=C7#cz!!F^0o$9WdH?FfWBFswQye=V0z);AJXpD? zYdFnUTdlhevTsZIP_Pd`lV8lnhyIXlc>rEIyD}GQEdJCJ?5*0y!9xeAUXeev{qtAt z;<3-ElcUBjx6#?3u|;uTrqB9g> zS!0J-4jy-IGc7-S8c;mun2>FfZN`sW&{|^Sf6g1<81{`7|1E2w9>2|d!rtDdMAII zX1N7(4g{`WnR1Fo0DLZ#egHjXTeo8~8%C|eY^@H1$wIkh5e)Iylu)szP`%*~bkWg0 zyhlcFT*eUq&|;|=lR-JqjpJiANMu}7GaT##$T3j1#fCWth`DjPGMFnmqkXi9^_xm5 zG_R+2n@tV&0ciACsK>?|Py-BvadkKt&gF}txIDyw?B(mJ+f+In>;uTspw$^Mud+@$ zJ?nIjZ$gO0BXt{MQvd)U07*naRHnG_#DE+#>vwFTv|u>c2cXH-VKkRvor^h|2bAPF zSdY2VN>L6lpbi*FDc8zoo0-D08g_0f#hAQ~%hncAUXwiU5T)DY&R`=$IFf^3GzDv^ z-C4`}RYhqB`vw)RE2l6Ah$`5xrO2ojLWp@L!?Nx{ZKn^@2Jpy1zOW(HO|*rFzI=$6 z&b*5EwNo_zaSe58%>iY?GD(f9`4yz$^`EHUbI-T<&L7zp&onOcC9jHuUq8f~fBq`o zw|-0GSL=rB|IJzvHM_n5$6n>%&m5#?*CL*;{;sEGwQVEN0B5`Kz#L?mPGQMv)~zqc zyy;=KCF_FCNygGBxs>nPm-?v{_hI84twe}rEZ`g?lKiaPC8>Ls^o9bU2Xb>KIC=Kb z{%!+GJO|63hp9FOI627@{q{DT0IPOVyJ~#?UaqZ{9n0D|-RtGTM_#t=nEjSFt*N5i zo6nvHE2mX&ZN_c=xSjL;K;9O1Z%#4)Z&3|9D^BxvN1S&1HTJDbksX#$c>jO35JFG& z=XYXV(w=_9=i6dvYqlO^0g&myTXq4}5A90%RDS7digD6In8+Pqj_PZsCqdBFLHl(# z!ALTKm7~Q_RLa^lWfV@@pOK=bQdTzFd^4r%$|+km!J7wbjr0bI4$fPfqak~$09x2b z*VQYyyd!EV0ohA5=nB@dd81`~Hrhapz%3`r*!m(l8uZ3V>S{$o^a1H4yk=`g{t73W z8f}scvkB@=`8w*U@0iBtfVyrw95{PJ>h{RdQ?zCSRpV-Mg$XC8SIo_u=OF<@9a=gH z&3erJMP$3(Bm!RC16C}lMtNr$v295`+)Tf`5bgC4Q4+)^n`UoXLO2|5Vt{_t=9JU^ zEgCT=&Ra1+i>2I}_Vs)4rbi9v7)_Mu3kd1E=n6&gxr4B5lIzqgGsPw+Zg)2~dMYTK zbfgXt4krU0x#$-2=#wPv%Jr1rJk6Cr49}G-_=+ni#Et!`j|8AG+s02ncIy_NI6xsK z_odhZStS&kI&ixa1bP%=_hq7<+bs4`qmAm6KPNp!%d~WbqUuzuvu@)og&a8C$?QeT zMyiS@`Hs`c4$)euTCMP2X8`)TaosLY9#g}Flh?M|+_Z*wjW?6y+bksdJt!aF7+t$D zD;tegPtmHmsK*ElgmF7MaNO_{icNgtPL<6W3%Ia<)P=h*I^5Pg1Lo5Ev88P5VEsoO z)=$;3R-at9%cs_!%*sY@TFZtFj_oZGb+LcvQr+Ol*gk?)FTyK8?>l4PavbhJ`Fz z0R&t5@R-_`Lys+%dV=#$yS0ulm;f4Rvu8BN55x9d95TVtUmV4r(N7i=+H9d{K^ClG z-M+_$f_)1vTSMj(67sRGRfAML&F|AW_U96D(%jqwuNP(ANd`Z8q$ux_D9uDpM(6i>?1})r;I|O7EVqLwsqf}w1qGtE$%#^0x zTNc9YQ@dXai!FejlI806411I*XSpz!mY^kp``XCts0k#e$pt?>H|~aMF0@!}R&-fF zRH4J}!_#5M9RoB)*eX(t28_jqGJ>-w==>}+ChsEqL)^|pGv{a@&CXgp-5ud>x4M62 z87WkNb%SQiK9i$CvqUo{(=>{wqlx#L?Q{pDquUw^pxDoH`kZ6Z zb)E=!)7F?=c6|8#A&;H2&1oEq=1mmkV)EK5nmjTLB#8Q5w4J?3cgomH6xXF>U=JYb z;mXx+oUIo}J=SqKt%~Op%hxBbary~Pbs*{wtNTt?9{R;_nKR($$_Eo{|Fc&zHapYM z{v7t8Omq!AN4h=g5Mf=B1p`o0T%?{qdwWo3a6Fpmd^8(ww}%9vD=C}x^wj!Q7Ik1< zw3{25OhObwh#8O!zk7|li?&XH8rGFfGTK#Z!L|!H1$M;?8z#>ziQa7E=r3O2C!JvW z{I_^?>jIA)cG>w406t5VZ4r-Ro^uw;wgbO||8OXLXQyq-cce{Q!|pHHc=e};Y54F9 z*cN)5e_|;#pK1WWR#i6t*?o&qz>8Wv(1K~A`TJ+UwDmFeUU`L+H`;mo=L+j~?qkq@>|K}Q)EVjINEmsUfkX4zlu#`f-?P1P9Hf!Q}>A8 z{N4b4keNDu(>Bw#M(`&qpBJ0PbZjNOv>tnllXgEt@9giR?+&Bu$atD~`+YCuZRDX( zTNmj2r)e>?HRh-N-FIn^gMRY?YA34QnrXes-(*fPrUgv+_H~@+ia!RqX4Y@5qGYf` zXQ<{>2xn^trg613LO5D3qJ$W#|F)srj9!BpEc7cl?7{ItnA=xq{>VdY05r?WSbx8j zBE1Gk5DofpT)v3Xm#U>99PMg7l~FaPV7S&?-;&gcUD??~HJ>bnMzk8#<@ueoUUU$M zg>l)tux=|G_kK0|0ES1j8(I6AnxQ%>v6Pt&25fbE7`l3xU}XC!mTLA4jf)r_JwLr# zS7BUsC!nRswvqKKjc5{s+c8G?Mi<>{swf%Sj%KVSI@~wHBzo3v`@q^{qrJPeuoJ^2D^=dsQ}!J@7!6T|IOyScTd zk_iVUjuRRV78NItdwO#ry6YjrVIS@g7$%D$Ewf_LD|CevoW11}*9HPuZpET=;|eG6 zeRP^ekByBP%*L1#OV_f&;->jVn6T2q#bigTv8;lU8TJNf1|vy#!kL*WbB^}W+o5FZ z@(k(kPjkc{Oonjug_twl3zJoVK?lBm2nGG9slhr*OAB#+Ixg>0>Xk`<*C7Z*`z(5mO%SO|CL1=?B1GImy` z8o3b0)p{8QlC>4rmtxc;2wp$W`Ktk9eJ-57@=@8hqicXpl$kctnDh5w_Pwr@?RB>F ze-FJ5ItH&-Hmt>*mreLq2j|-q!Z8nB*F%)7(T{tNeLzFu{k3e$b#VG(H?doGx?&m% z@83TBSTKN(*-W*)6ul07;V98CFj-yOQ1V!ns~a(RaR%2oOKsGRD8@Qii*@2m%hbY( z9p_-Jy0P28-$hr?TB@eXI8TGFw3Nb+?fBwhTpzxNe`N(5*O}EpAaiM;n_IpFprdF- za=n;M6lA&a4fyf8!7{Dy7bKXRy=3BA)6*5C_qKZNn{Uj(8A4;GF#igHz63sx56qI| zCxloy67aj%L?g-3LI!dtjnCvVG+aNPBCq7-Z?os+u@6@9g};8DXFflT3&`oHe}O0V zypa02r(dN0so}X?yh@i^>&#@LXrb@!7Lk>~#P`Lw22jr#30{NhKvP!E_6^34Mo z4A|bql$JAUrp>A<)@5>lbanyNUwjJVdq;V@xrfeEuhV%d`P>o{l@A@@;i^>oN(4v4 zJG95avio7Sr4@vX5$lJsK}&zf3Euc!EB-jJ#LBLkTuznlo z$UtGF`y6lo+bNuPfSdw0)~=@K{T6!g)7Q^%z%SwF+&ic7lFPRaDhhQ(2VZaNMlhI#UX#|LHg#0EsZcK!iAY*6sNd9@81RgVbv!BEYq;Cq*GM-{H$te|kj2`lz-J6(MMYUfn-$oZvm zv=~ffY}zq)fiaw&PQn9_z05}KmeLVZ4`!n^6k*gdLBP*XAfzs@XtfRV$bPcHT5}Uz zyBOBiQaA3=Y_tVs)Z8DW;gXxg?OuG8CC|yp43Bs}p&)8!Sjdf<3>83ehOw59Tv=N5 zGo1M?^K_I}*J4|i+^KR5lvR|{-PA=Wew#oLN=Eeg7;RgyMb4@jv$C&g@BlN;*L(o$$1-e{KMLOOgt624n>50s1uOim?)<70I?)a;@a zlT4R4y1m&N4LZGj6uu;EGO% z1~N8H=A7)KAqUQ0fNac`xw%V8JykJ`pAs;{V7w2VJ~K1*j-pqymiif0kX5^K6PxW^V9( z^xRT^5XQ32L%}|P>}BO_Sm~zedWe|cOMs#gQ(}9#(xs+K=~mWId;f@ImBxr=LoNB5 zMw)MgiFRK{sVGc+EFaKdTw6oUVBJ=-F|1lgiK`h`B!!-@E=fvy(_D!y+2uJm23>FDk;6$L{})mZGRAoGtg3PDVsKhINRbP zG!P@`YNPRn7K6Ez@^ULhc~cxweI3-NKFCeZotzq4TgdXk<6xGB;$3c;ifmu4{zhm|N1xl-LKj* zHU+_q4FsuNi9$Q z?_Xozj&&*D=Rbd(Q#T=};vsgeo^9wVP9)&R*>RfVul^%HuXkoXxG<$lrqvlLDg|?dEVBa9UE*Z!Us{zcBvUHSg`V4g&%P35CU?uu} zxZ0a}uc48at8T(GnbK}DgSF1IMHG)5?6IO)%_5C^xOFT2j|f?p!_NaTY z(QFwJs54+GQoGthp6)3-l{KZMm~#NXf^(|5^mL_c+F3`{szP+xz(9hq&qYV`d(=0! z;JB5MoVU!%DrEVx;kBbHC>q;EKWwQ5b=Ae_{-`b4$vP-O*xSX$4ke>C@iM-T4g|1Y z>`I;&%CTi2Q)YG&L%~a(ZazmO~sgdyl3|E`sq1-kRa# z+wADkW&HALu=cBtrOU<#>h*ca1tx3Y4sqX9r^IFAsacI{O4R`2fFJJ!>qxh9^N3*I z&^w2-krPuD0-h(jQZ|nW_6^D(96jD2OwsqF#j<8>4c1hT&7NMTZoB@z!Bz}U@f>gu zAEyRu*=h3@$Ec?4Wj1Ptf_;OA_w#TlBaQwg^&ouDf2bXaL zGrzA5PL-)GDjt==X(?9!O89Q2Eai|=RH3Cqt?{Z|VWT|V>x1NUz#dlzXWvUPt$!?* zymtztv|UuE*^h%}Npfo6#01mjPr_(O?qAVp#>=S-A;fen&LN0m?r62x06SeMZm3El z=(oExMF-xPjJl}5i{@i5@%KM%py8+A#*_0iUi_mBXCv)-jyJx)Z+aOn7Zf}!R94Jg zV$8Oj9s_lsKZNPns~rAKBm4inZgGs58*5hIab}+RaXp7NO#gkB4K-Nw;JMmNmlw)* zJi~YX`VckqREld+>uur4TP=jh!LsKuYBL?pPxR6G&TG7VIRrTctlP7ny*B8qKT3n$ zPfzn(ynJ&f2Oq1Yc(Bvqj+4_TT8Us{=cBclrag=%j<@p^zkFYvGL$97Y}@}ByH+P} z7D55$Cv20BnYXpi)xz5+8t4qf)pfgT|8NFce;?!Sp#m)&|Gfe^l|1sfb<@mLv$FTu zXW2XQp+pS7$4TdzcR1A3~nDBkl>&eJcbxI&?WoRgVUm4eWG{;0fLioRXVxvKTV77}@^TXW z9-IybE_aaVKp5ZkHX3hPsrl4ejN^iuW3zEant19ocXGNrjcIg;*62~}ZZJ=M!5vjv zxZnz-W}0p!b@G*k>OEtw%i~dkem5?M1Lby%n5TnQXAw0cJ|G-P?ipDc3@g@h|JvmA za{!E(M$Fei>&Iql?pvT+#5;qvgw0L6_nqoQM(Xv2)hvrQ%bY7(3o2 zlgGE|2=}^h-nfO|f1B`#I7A|o5oTaG13t{{-WV($y-$VulS9Mu42-;z3J3etf?i@de7n-?3ZUqan77dKE`p^MyVc~y}Vp45F7qo z4b}q%2q-wiR?2nI7gkT=y1Ye@H3?|*3+C*&lv0j?(hb`w9f%R=cHrnz@bxE%^>t%E z=fQh_Et^sedMm78&qN2g!D(X0ans{X02+#l$4qOvqL{*ueE8xX(mH$$1h9YDp$?AA zD`jIv>S;1ZPkF0~MFRL-UD%x-q5~#?{)v z@|_h^Pd_{O*_oQ|S_mO#Xi?nKi+NN~G<*R$(P%yZB1Dpdq_k<&q|g?WQTOHN`QiVm zPBhi_;t84;aEP#}xJ>&xUf{&dg>Kmb>uurit0z(7IanSz$m4Sm#PELb zdNSB&Vb@o`#(^!xxJV{QzVRKo2bq z$@+ln_VOoB|H*Iw4Imm*GttaO7PQ-NMs3v$U1fBhIZ0n$Np4Zw?na^JCWoK zQ4wnS1V1gu8&KjoR6d-cAX2u50&_Xr4t#}us{rD(w>dJ9 zgLT$`>=|UlX)V>%ZW_)+iv~To>=$V~RnO@U?YJlCC5ZO4ar(Wpv|U&51VW>~;{-MM z40!-iLVXN(gc-}QnKXbp-QlpjMKq=7>}2N^QMO?_J3q4>TT!wTE99g#W#`mP40mW1 zF3Tev4v+e8=~A^rKjH0}auj=1X`!jZM+|j}x9W5=O(8k$Y$+AnYA8$gV+L-Hu0f>B zP43&v*0Q}~WFQ69X~Z^DmOQNnZgr=>>_s4~Br{eGg%rj{Z-ej>L$VJ)gj<=q>#eZd ziZKgfx12cB4lZP)GnKJ^`%ZRmw=pUM_Y*xB5w~t0qTAJwa#Xw_Z?bhmXfvkm* zoO%%8PBf$0k*eYPR+DBhX^dEG)zs~(qpH-P4syBUp`+C~CUY`#$G5Z%1aO>tkH+(M zTs=O5k#x@CvteeXS=~7TT^HyYk>!-=y+W%?{dMR}C8M%oQ=e-mmWXA3Yl~qzL%w>u zk^Eh$=Y(vGMm@vF{ut_vo*MEE_jt}jmImVr8`V2@Q@61+c|M5Y`KT3Vruxm?J!*Ea zrVwM^nDcUEDaL$&qJ0CZ+5DlF=2q8@IgndK*h5R1V*ezv;@nJuWHumese^}$-aC3yv`F5P2wqVUx=sd4> z26*3pg&(~?@u#=E@grK)PiODb2dOriFqHr|Q0v%z{t5O~j1OY^ZzY3^rh?2*Uz)a= zwlyD9aSq&w136fC9pu2)Vsgh0HS)UEnvBbg6l4Q|YqZ}`BQWhpe?t3&?HXC5ubL;H z-HUa~?~;#ojRmeN5LN??v)Y&Dw5>CjyS9S$w9|?M#SN9KGW+?FYbW`|5jEJi?hg*~ zux$}Vh$b6}JeBEmCTcWf1GAX~Nn2D-bx}EqXaLX0F1l{I2}Tn{{Vv+hhN!3=(@`CB z(t6oVbO1Cgit+OO>zvB zZrX{awSmjG5=7lMa90-2{t|VtLyH*h_Qr`jz2iQ-J}^%(EIfRpg|i>2!9GJ-swv*m zrN>;Tqbn4Kcx+TaVM$K1+FJ7Q@i%}P3Jp5&hansy$b9D?B@LyQj;J{~sW8f|WXLMm z#o5Nx*}VWEpPN|uB(?bfv{p)s90YC!P_Boj9?3sOwxN_wbsE~kw6AH-K@ohSMAGOkTI|f-=iq>tUVuf+kz+QE`+-gu?)){Z!52b~NmGkV7W0|GI(Zsp_7H^l7Wu_oSLN%dy{nGBPL=F(Uob80k79 z*k^g*AW!bHOg}(#Cqm@T6t4+*>4^grP;O0~J!n~7ss1D0gLl@2O7pP}4pleT@cN4B zAOHX$07*naRH+mJH1KonqaJnH7W3qtl<9oO8Jl@qEv3o1RdO~`n=04`IImt-U$V+F zFVio_BgunQ_SB=EVvz`u`5c&?h!N?JFwMc^I>`zrT;g#+ss z$9%&}2U90f){>b_K{5jl{N8C~Ht7cI<@Ku_0AocJdeSVvlC3pjUbCLSUdq zn2)Zm(cdJdxCsmZIc97%w$Z`9$(owXoQcPRYH%bgIrU*-F=j0gcH`>pBNSmyJ1F7{ zoaInbR4~|(jAYmNJiasozA@b0se7qM2K$U_YuH{syIk&}I%s32Su_}vTeUyLM7w2T zAd&LD^D5s!eilHOa5~qMF*m+czrR!hZj>}Oe93(!Xo1j8Co_sIWR+k_ZpKBC*%Nir zeqCLe8uMCgM$oQY&)}{WxON%WbZ?Xf0=RlYfEM$LDIz@sF{0rpu_*==%z7Uk73?#z zcI$R#`E$y+!lGoouDBc5$C&=CzXU_z&5!V8lIKEAfkDgoV zI?-FVu&LCT)+|G_6U5%G5JiKbs1Us-Tg_yRCCJw3DO^=WU5Y87^@BCK!nY@`!5jAA zi@>7HD2peUvs;FRkgq2X)LM%%1$O{2nlKxawMhHiDB;_L!a!EuaHegB#o~AATGg8= zOs<{et7FB-q(K3JCD||zjVw?`rCN(UycG$_vCJ- zQ;APGdx8dlbybw5bF&d`qxrP@&zkbGX)I|fHg-Q*$4~z6M!dgzfxlbxBF}w(QO$-w z_imox$1gSjQ1|qs)Xe1-hqi{@U$XJ)PhaKV|9$@)F6iE4dGJdd`dK5ddK=XY$}eZQ zHs*ZlZQ=FTPU5@+ImT@~erOlgC6l~)~OT~3v4;-E^}-*FaZ+E&f#byViG(;jc-^o5%7_2hcbar#0W$Yo1qGUv@$ z&B14@CvHrjg~KnOL>bDKoW>W4IA}ia2f$jjZj!)81ZVv(Ida}loE)tCp5n=kDYii- z+Zu6l^0gzh1mdv7%DzKSvT=r;m3<$zVF$?D$hzW*UpL)-XKb)d)2GAZONJ3LG6kWJ9*??#C#&HVv^R3r6(;8C!AIe!QS4)beKXJO zONzRV;{Y$$nGZ|YmQ-DDao<8vVd{8oZ zFe#?E)gXtil&SiMf4 ziODW!BZ}*iBRNo@khK+qH)mR`HY=`XC*imcM@Kg$n@ZBVb{GiLeW_KgX=$`lK3Pq! zsKUh$I`G^9vhcOA9 zc+4|oAh+MwgZmDURY=9|YAh*_V}rGk)d2$)BM`Mwe)k~5uCMal9RQ8|;4go` zo0q&p8F0~?&Aj@z-{YlAz=mgd=D{?BWc>_=|77zzHvyKK~rwIWYIZPTQ`>sRNE4J38mfx~KgA z?A?DB} z*Ih|hzKQqz>Rml;&q~toO-)Yqq&=p`U#Bt2Nlc{J8YD_Y8HEgrFvSr@1|h=$&3Zo|*lg_vam*&xXeXResht-=?%RJYjgdy6EcY_wP#2 z3%QH-0n>+n4BLqkY~AYaU$>-XZUKf?a^0s}V2-kn8SDBe92b6J%Y1-Pl$ zzneqnS_A9!ducs)h~2-hqzf?KvzFXpznzX_8@sn<;Pcns+sDp#WrXMTT4SA&$%++5 zz=yqf7jK=g)875K?H4O}>pu=-2coj>XT`j6J$vJGrIn`Y!~Et~`>E`JsCjEyw`hc~ z{H`jFoM`QRUTuFmiGBFFL!!O#{@Y?&e_=qB7O+Kb! zkJa%VJAKK%7&6y=nbo%&g1#O@QlWS)64OYX4dA8a(=v`#+iCOk1>)^$!*Q;f^3qd7 z_GM4sF0OXc@JT7B8rtymBnTON;-I#^El@FY)l1vOYK|Q# z<&0zGiV?4~x!;Ab?roo&L^R;J)3vM-Xj`8i}K zM-J(c75F!LWt89JqPhMQr5{;o@d2|^$<7#b$@8(aMdE4kKVw12WMGLH1z zY?7mby_P!ZoYIp0U=qnPcaMT_wUdU5KT=v@rNQayjdtF{Yg zadhv0e@Ec_U2>w1;RQxa&D%!9 zsZuH~dH@5785t8ygoe5u8B#o5+3iUEDcsJp2#kbs>P z7xLk%6BD|B#o(^vWL3XoVOnrwt2{&P#b#WCKTmi)fzOX0*9Jz$FeEeYwu!H?rO^?1 zUEN|NdDtH<#9>P6e*fwJUf)027oE(a+;nF9hdG~*_FBE_#nWo1`uHCyzt9O7NX#@3 z8A>@Z%|vVj&~}#cPg@2&NB+yToH!e(b{^A@DZF+Zp8*(19_0s1A|jJb6@E7*6C1zx z57fNyBley?z|WsNz|RNIvUm$W{rfGLhx-=y+EWz17VHiq1yB7WKPVhLFq;SKYunf! zY#C!dTfbjK&S?3*;%#g$+&0XeTY0H?3poR(nJN0GSK;q|$SX&j)P1m>Z69n8y6l!w zRz10#9DIH=+lq(Yv;E0J`XXM#v%h*ZRe@NVB2LR|0_@P%-^nI#B|@V`w}R8 zmOam}8{05@sb65j`kzqx&RAw1htoSLd@{)P4L%+oe~IEpbB4}$4V)kRn9VPi483E} zbG7EVJ-l#V@MmY>z8h$y<$^J--o(SNm9p2lmwiXRO2PW6u2yZuviEfkT?}?#74QCk z{W_N|d4#9$4c?v15M_Yg0X3qCnKArWJ+@B*$vyz*@!h<7eE8^sRnK*=F)*BAPZA?4 z2E(xLdb7zcyq}u?c$XTNjj}yEC<`)I)cnbTMS!yNNveJ}TOpsQAyiKJMMcTE;YW&$r zb{FO-E2kQQT=}`;qOrb#y87X_#*na(#kUXIA-83aTHiuLhnKc<<^1v7pk?O76Meaj z!6P9C5`~?3J)Qvg3qJ>aCH!Tefv^3O?I9sggF76(j47&!s7qsG&2PRPlyX96A zXEb2H;-R^*1?D6IE^PHJ-H9hZuKEhfhCLPrJwK!MX^b^-*WKnJL(l;vFJ3}wSvd_I zEm)71aMoZTG9oa9m;Wjd5sN7|m*LvEO_kW&l8LRa!|iG0LQ@ur!&NEw4Ba+{3v0>7 zc&c04x`*{l8}*`{AvKlc+BO_PlGA>73k?k|G@KiHU$2N*Ou2V6_)zPqh#I1$n&RTV z^VQ7M>Q0m~Y$wN&DnYMNOLZ~DLEdTts|&IplXFBmg15tt<>;VKI1#ZV-r}L9Em$_iPDOEb&>skNHXNh4?~Q8U z`84G==GHXRc%>6ZRe8`pg^`9>66R%)m6046Zo6AzRxau7C#n0)i>tvxS&+61v1v=j zG1|aru5lati!hNfua1_6&cKhg%LYBi6X}5*W`X{g9y&W2c--D{D~Zt!y`OQSXASyX z9D>g{eV@&s^P+{aLEo20s*;_2emY%^G+b&N{=5h_zR;Ql`@3#NBu z4o~0*1Br8hrusm#55VK#%*P}ANMz9QI%1E{2m^_Cv+o*?P)QOZx2Q|AOy zbJ+M753}LHb>vJ|MSu72-2ch@?0WA5Do>VUX$TVYB&~kxnaEk5PwuLvtXVzG zzL+#|6nt?D#&>q&oWix<6cP&9@KrN=e`%$3cL~<@MdKQ3ce*gG*u;uI{|9A_V9dIo zd+wO*w;&TMzO(|{-ZGjnl6~(zWR5h1=$vdGeB6ZX3JA=*b1EPqXJD=Q@g{-<`wEk%0+{SRk8ks=erf-vG zJ3hJA?@DW8!{5;GnSF?Ii@ZNr*6cwAmytEv0R^*YLG=|jOtZWMZq6X)|8eGvP zmfe>->HP&`vI=?NoRjyhE)4UQaewYO*BBK;!mabjT(pFotPG5^Mq6MCkDaL!ZQ`y~ zi8yMl)HSx^_VipNj>HfhOVZqQ($bTIUa*Ny%3{UmO*EXXp~2z8-BYF*X&^Q(nbgdM zLw`IIZ6a^E0qYqn_BIdxtAT!eraKp7zI7%p>yS&h0W;!AOpK%1)rq&~LN|VySz)Z%iEmRZ_P52Ek8g zN9nIhBE~t9*d2a6EthbS81m`@q71~&PG;^M>7>sYVF0O!c+4vbm{VI#?S)p{UT+{7 z6ctTeQaX3unM(Y0_+}WJLHeyW&Rp{2sH?@Dk`Z)>H1Eak;XI=fF^+O!&5)c(?AbQl zSKDwpAZ@gZuMu;ZmvR<|eQ1SWVv30*Un{L0p1wpB^qyxDZcQcQ4ij;c-hXUlj%q7` z>#j3N%?kb;5|K>S!bF;@Tkw1AR9j6H1R0)?h)4{EnZzb0V!Ay8(-;qwnG3Q>cLtIo zk+bHqaJ1^t>*W}opqX=XSe4Wkc)z*i!hNN$H(}2)l%6qqh9GiAEO8_4lUcViH^ohJ z>t}TO{CNA7-$xn@%#00o-U#3ME!vdF@)=f6TkW)Ub;lYNOMFTycV?!-xl)b=P551- zh-6Z4i^XAciu`bw9g4^e$MffMj?}b)ArbTPJW>b$Uc%Rj!+HYC z#ZF)*X`d@#;dJZ`DI)ki9{e++F@z#H zRJbJ~14KrLFWE;+HI)}SAz~(}iOK(>5fKrQ35Z*mPgbG< zuDYo^RZa8I(KSUxCd_;JB94xs**t%T1FN+W4?uJxw@$RztccurIvc34*zo`}=PkxO zm5fKp)ksC)erX@>om6g-bVdvC|XjZHkrWc)v$hgcTW1$KADLbCd zMl44g13gTAV|d(K_jcGcjoR3D8rw}{r?Jh(wrv~JG`4NqwvCC6cY4nMc~9p{CYdYq z+gN+;weE#`%S~2VziI-1`SiVWL!z%854ZUKi!j+z zx?L*Xc?$XOx6k}53XBd$OGECa7lxNVdDJ2pi*Cm3bkpoLf<1|Fv=#Di1{V zQs_*Ho$$-`LfICvIymO>jDhU%PWKlbDYA!1`E!YNJt0_p9qqzI^Jr?^^|(sDe_b=8 zADCvCI;4=qsNdG|HQZ>e<9YIqBw9MK9`L&Q48$+bo`Z2s2N<8d6ooiOz%!DLiXXmS zOSsdV(~yi37}wYn7%I$EEO}0kXTNg<*p8@A>v!WN{8#p)2s&UPQj84U>2X}m9<}5Xm>}kTT5g83cMr)I;eV-F=ZgN<^@l=kAfO`*mx5} zyD9xg>a(~YBkHZ7DjUqasDEy`$19bTco(x4n=-hJS zRyzf96aUvs_X`#U*-JhGMxyBbHq;ftJDo;STF5z8Gcz^z%y1dcr4ln(o}&|wUby}C zsS$zvo_}GfyBe!^t{W45y#dg^bxKsx4j+m44)X*Z3(HtYp-GuBb+u+0>Y?yS5X;HC z5%Mp-#@Nfrn5>x~7+KNHc^lfd?FjPDPgRT&tI#&sE%JhWuT zkeRDGIbaNEQ514GBjrnFV*f3%7{wRqY!NBRAGj_OPu0|Rls$Y_^9I`?L0J~ux z)T8V#0wU9poDov$fwJ|nkRdFw_RbKSImOk+DUSbZ%nOofkTPJ(GV85fP~O9CDZEjaVZ|yW-YU+v30+T&&3++~0gYAMRkF#q}g2 zy>J(lHQt(5oAr~=n??x;++Jg5Lws$IsI92z#0(QMR6z({=kZ&^klcUO+3&(N_(PR< z>VEz44&|96;mH!80f~C1rgcK29rKEfw`*B#!1cAks5Z+j7)gt9*YZhZqt=aEW}1PC z$H0x8kpQpYWb@+oA96yft5eU%0Jq(?#+ zf3R^PFE4_@RR;?QH2lo$42`s&{^6mJOS^BgTh@bbusK-?PG8pw8xBmnLZlzYZ)c3c?X*StF(QZLr5XNK0H(xt+IIs3GRP-`Q)w zX>pQuc!UkxPh3oFtcX38P7zoxH%$vufQk1G1acRT~Ho%4KKDX-;&Hlv)_nfO| zh<6>^88=tz`33tPQ56juErrUzIB~u-RZ(uSTdHzCs8fNNXSr3gFD;N*Jt}9tt;o0E zO41~4B0HCs|}o2+o@tY0-QtL5h!M=5ayl;trJ zT?rpHcV3`P8vS9ZiD*eCo6fg?44)L}`$(ghse$oPOVXI$Mzg(>{;aph_kouZ*NYJR zOZW5(!*(1I(GZmKR)sUAqWpN%p3W*ANpd95#i&P zp3GXi3NEs%-8mC~d2FlY`dLJ|G@(I3(Xc=1+D`JQrw@SN)dv8RI#TG;;&^wxX=yV2#4fSG#4-Gu~p2i-ete zwC=dGp2m2+QiW>|@xw43-=&e3M!2x&77Pg_m?ttNZVJc?~g2sf0Mo0fvBq{PzzrgEI}Ql zyik;RyJXqZ1zXW6^5`vh#+KWuwC+Av5a;TP(R|fE%frKMwh7RJ(RcN*KfgISaE3Im zSRKP5bMmlF<+<3a%cTNY-2eY&rzPKQ{fWbT#P&|Ix2l(!>cp0Fn2Mi`3W=AK7-jJJ zYT@#nJ77zj>^Xng;`*oZeBzh)N0^~3lylR+j@queFsM{e=L{?8>i^a`?8jdp3mH=0 z{=Ir%zBENqZBY=TOuO0fKaXT?A@1bQI=+2w3A1zvv4yqg{SAGu5i zPju!JveIlMNefY?etQMs%eXviy~_jPgW*V`QY074RNSh*Yf4=euhAEg?lU2<&Qkw> zro_nTAXsTub20kO*Rzj6&b1m>Qc$= zLRX5yTb!?C!Fu~`@2FS!*1Z?WYjht&G}2-7E>KP7mB`7{vd1yWyc+#NEu^qHMB)l{z!a7CU%Wn%2t$ zOobemZlcrIKKCkApwR&aU<=UE5PPFWq_GEur+dJiu6oUS{ea%0I!yEaAbX1avdVQr zNnf7R>Ov3TX$ZzRXAYv9Et*&A$$mv^3?&0*OYe?hc`0iQot*M`$M<*Z;Qe>LH22(UH#BFm@Ln+8uZ#fxTwN0$-BMXg0bmOFoO3e?usy24aBqTB*B z$9wkY30rtNK;EascRo@PyuNKLzO~q80AB+v8)!H42JAz!Hqm7$mBFs4R9&;C*(E7A zEXch}!L@h>>nR#+L2;q$rH6&|#Y&!J2Ll$Dw4xeCdHEOeu^w8Thp+BgIs-Q{&`v+D zx40D_37v-Al*b6jl-PTOthPQSrOb$>;&JS`tfUt{?eHOH+0Hn;cv9OF7^!We26#b+ zrFJCIZx|R1h{{B@YKiPGsOTy>EC01|VRUdC5!ihC8}2f?B(nVPP$x{!WY1v6eR>&y zp0vK~;`3{{cA$wb>Ed=->w~jwrL7rPer1u8m{%;w)Oy5qx-D8qwL5S7@`@BnHh69uG>vI*Qd9dYtB^> zNF|=16UW*B1Z~!u%g4m?YnfB&r;rSzGDP?Pn2kR1Y0dLP5f4EoqdJo7Uw=JP2A8b# z;6?rCK1wkvJ*-8jXC^?};D{?sU6s@&Ag$X#7}vk?3-3ZO z1~d0_M(i67j+BIYt=z-Z+mE2g%Gs=-_HyjC&MIbfB4DbN6512* z*ogEa1Hc>tC~Ld8(h6T@^!WJPediGgg!*C_CZygD_(a!VhBz-Y{&A9wtSh<;7g6^& z5+{yZY8Vl@&NXCDw{P`TpIyGBM#3z;YLm%$!(-_@(BP}beQR+%tkoM6GwAb{%-QzD zsT(M^p;KoYD-rsSIfgVram$%GEb3fFJ5kPUnE9y0UX5=H?At!qCv+rsw*1tWj*mh{ zb+e4MHM$%rYS&`mv#s6jJ>@?R>b>kf({v6?TQt(t`p3!O;IXQXKY*dQhLfkrH*a^I zgN5j=TV_jlIE=Z$Tf@WJBa4OHP5&&}oy@{()wal?NuarDP`K844_Ws{0m!Oea<<|C5P z3mJS=O3Pt^-LdVf5eP_9dmZsrdQDmyP9&-CkQUh zmVD&oUmw#jSrsCq--+#bM3m)u!;JR4Uhz2S;O~bF*WU_@6zrhyIU;Dy%_QmI|31?? z$MduS*z}e1QI}ZflQ{7)b2^P&kM&Ohbx45*)0&-?j!tO$YqAIkN3IG?Rp;KV0d2RO z_1^jgyU7~`yJHUXmdo8eCkrw0JW0p3$n~CiF_r?rm0`&~jY06v9ut5g1%bW+=22{p z!A`SvVDqs}Y1M~VxlT_VcDv2Uv)0$4R|_q!Rdf~w=dU(2yqrhNg0$=X``w$dR}Ye? z{9G2f3f;Dhle&!5tbvzvyGxu`6+n4}OB{l*-iPCZP}RV9LJ*0)cc!lE%@Ete<775VcphI_HR+=KA3 z?5wypiBv8Lt{j|-kSnsYWX}ECk zqyhrh2hyJ6S&8$4nEf}iFJWuMsTf(;`uunTx7KM6=q;hhW1i7>`u`xfs~Ws7}sJ_-gg2_CPaK0-$vcvH&xsl%|N8sS`@{F0zF}s3QQPuAgUIexArJue znZ3g&7?h>(;xr+<)I9ugk@MnZf^(8#N|Y_m!To;hhkDG`_03nN?MZ;bMDME(Rd-0B zR`75zmd$L4nd4^C3|jNL4Lh}9L~N}Q(v=F5Axa>UyDg&<9+AuDdKfQ(mgO2+p#S@= zGGvsip{m1$wM>A@VJMTv6aFrMd;2gBVwBRTM2B^b+;#7A89IIw(U*cu)@GG*&e z=!}W=&88CUJUF3yiRk(qRz2=w@Qa^7nu9)g^RmBo`25BpK0X`oDPOsyhRVj^&cZl| z{XZhMFR9-p9>hO8dbly!m`fkC&MhOYEeDEjUYRSNj<}GFS)`qpxbU-wJ&qz z4B?8QpYuz(PFjRzMz7O=|03k}lrK4!Dq*YqLb>(|4uHZ!VX}JsS&s=W@i_Fp9BR}E zzvuYX$m$o=g!6h7GgS1#8;Ikuvs9Bw;roS8ir5Im#Sb-gffDc9M+!QSpDuUea!I*& zyM;SG7v5uq)N3d~L>>|Q*JjVkcLT`{J*_EVqSdQfG+mx3%02KiZu3sv-b7zsFm*jr z5Jm(U#qv`lqxmDgRGzy;5wt0P*OI*&-|2qpnpnEq7RbOc9 z@m>{w>}z+(E|?qc(y`c~5Cu2*qC*QWU}r}P3vxysNoH|3JGTh$MGq8i_#sw?j?Q>) z+4;8*+$Act9k%S6Y&cIUarruF=)L?c2?B_<*lzXr=}8eb?a=CI7aj<`=(Q}R6%${A z7S=2JL{YKKuNVV&Eer|mkC^nqHv$Du7adcmMY-3rdI1}fB{@l9aj&h8OhUIV;+(5B zgr95_s@~aK9an>DbSC($lTljoBAmV5F*Qu*F;^3>XJ^4kW8yj0{8#=Xp8Y2*!A>;M zcV_Y2az-+d&>U;>_6GYY$Z|%xyS@Uo+A_ucUnj-Wd!WqC52HhAz`i0$p?zn-!(d>O zEMnLDMA*w_V>351HQ4(Ge!jpPq*YcP-(m@Eao}9G0riMds4|4}Tf*@j^&hWsDs=IT zqZ*Yq_VO_FR_xuYSQ4u5G4f7d`z9afOR@LC!y2lZY!=1-$wD%Kb*vs8Cp70^zqr|UX(1x6)4ElXzFyR-)hM!e9u<3BZ$-9ztj5MfBCB>^<0bH z=KCv=SA7BTV1^T7+Z{9FE#I3u{`GtP6Nsd?W1h1E|#vVfc`a>tE2 zZ*_r0Br)~x#?z$be}zTz@yK4Rz8{SMwqWngqUINms*??lj@Xma1lu2Fl*_dTUIRHX zbG|pto7%O%DR|Yn&~tk?MDyboo!}!+3ynV^pnBfw%^N}y#4x+PiDa$Cj-)l**;eKz z#Lf8L#F|}Vf10=4EYbPe$&zZ|dY9Z3Bu%3OtB8i!Q~T7?TI&r-25cSc%Gp!&nrE$5d}5yny)!6$ZaZE7yWM7GKl-TzItYiOj4%l5gHkJEPCa-xb(>t%s{^hRiGdQ3X5NLIQZnTQVdKw3!@9VVU>3UfIo{+R2G$)oh%V zNRD2&98<6M%Md0H8Ux5CY{)!{vJr-z`e~Lgx-ektQ1!disHi?T*|!NM*_oD^YhQ4=Z;dW2g?YStlDZ9ttC_#jYSq?9lK1?J zu#_G0_9DKLA#D^B{2*KYYt|2wWHTeSrTg+OROt3&XP0{^_eRL(Cf4Mtj$XtcXrx6?yJ!=p*50-yGOZY>x zH+wMg0@V`x96b3|M@;y&J|a>nTT%4y|IIyQP+AI>AC}&LPndtSfO6G#kd=9#znf$W zahsfVr8O#ebSvunf6i>TH1ErQzk%MB8~hv59K6}K-!e7r+`0VkT0Q&OX54+V#cBR=U$TgIs%z@k)wx-!nrqE7EpY=#+JA48g0=UVKfKR;jK@0L) z5`k-wKD3sc&~O7&84o`xXzSI-**I(*Z}SR>O@x@)-O<#<1(Gh8Df!)!>Px_~iwz!UfA+P;Ke(O% zJ|%1L3t7{uN@FN}DGTEbQ&eDPplp?AuI~S(Gxk4pMK8VR4^e7VCnkqAFgP4#!Bp8? zlr^}v)Mi}GIDtupUk}kQb_U&ovWlV*N1gxRI#HN=Df;*X{}GlDfUq!TxBe5> z8o`#kc0n5=_ne6Zhllv;Yg6EscbhbNMYxmf{aHz7qh@CzEI&PMoe76~RbUFVd80Y9 zz1&@xezAtG@v+^fQU7~C7k-HPmG5V%HH-8E zF;!1={mvg))v zFY9KHe$_W81u3&@^MC##esgLlKL#f*i@7DVWj`gSC9G8g7fsJV#Y7&p`?zG7*S|(6 zcqg^S$+OC5f1CNW^~}+*{)vg8y|Z%~l&e?JIt% zd;R5(PJ%9hL-eZyCyY$8{bt>dxWI*Uujg%wA{^I!V8=-RWA;0`+3Oyk#5{jbn%seF zZgfr5)i&2~`2Ce}qmBw~Vr$(qA#3>?il+nXg8UtzPLa+vzoZrzEdH8o8CkSweJL63ph$g|Yq-|Cl0QyJTH?2Ei^l17iJ2y*J3tAk^)#ckQ>5S0K&>!dGIFf3S-0PCfZdPH+?8+%gE4-Vtoa*P9v9uz;%T?Nw5Sib!m=i| z4Er?J7fJR0#f>2@OMnx_GkotxRlw@3%kLZ?P0!IwjqEhiN$_$)7QXSuJ-C|2(nwG?e0*e0auiYY}Up zb7!lVAi5-WSvJi!mtN1cQfIw(&hFF@kB+*Bo&PS%A|}yN{`qWYQ)zO+j`};IRab_@fznr|lnUu-j4Smd&R^ zO2S(k;xho(06fzPOG*ie`VRaUUr+Yxrs>a9{PmMMdPHXL4N!A7 zCw~fjiD>9h?VQhh?Wo_a%xg@c6~O-~m1z9A7TNsf>;+%84PESK+NXwUM^A80PI4=7 zz82Ncy~Q7hZ|xhz;SF+{JPgC@KPzl2yh|fW-P=a68Q(n+O(s|okS>o(z?v)3ri2#gA-po4t)?n9hsRjT>p z^fIng4Z^17z}=MB9iDZ!ryW7?K7SWvYPQ!2bJg7?@m0QVV@`hbJxrXZZEC5f4J{{C z4dZ6s>jXiS_q%PHCfX^D%uZ;>AnwBl?@Jr!YWk$pTVbA*?!+8NgU$HRBzH&w`E8`6dV z8`cG)m?2qM{N2!39Mj3K?9&xQ^Ek;c8b-P)3WD3;(Gijvqs0ujx=C?O(k|;4ei%uT z@t1A1;^QdY`V#byvd|*F#&qs@zBZb3PGz1luf|EtZwHc2g!OK0ZJr+e#OAx+F6NG8 zHJh9aRl!pQLDWG3@aNjo?9?I$c|T=TPaWzN?SHfRqG4^xm<^|_#f@K0=)hFGfO6?1 zF|L+GP0Y->CG#xLI~P*_*d9`nPg-qKvaIf|kF0PpJ@c0Il}2WNqW75@vQyXmd#Q~f9-onJ|gXu@5#ROqW588>+bM>=TxSdaa7VrqO5PO@+28mI_Hz=;=( zlR`7b_&1j-pyNEqL}_e;$YM~HEwm-itBKn$b+tib(oKDZGD6VO3#Dg~ z=W9r<;~b$}z9MvO80-HGD}&=R^hJ(2|?cD!eTJ$|{xroOOmtD8@V8nBX&u0)* zUYQTm#ml2EK`GD*NVdz@DR{qo_Xior6n}p4_k7OrveBv;bR0Gq(6{V|8lK60)lc4o3<)NP$LWVFwl4<6Ny(q*%A>$s6y<-IURu zzOKt;Ja6RRRKPtwy-TYiKb8;#IXhi-O%Y$I$WDOUTft9#WjKH!vnh=-P6?o%VN8i1 zXrAjj2W^5MYN55?I33s46W%;ClW*&@zZGeX0!EBqBstenGsNg|drnXPlA8~zUA5m? z>QV}ZkxgYg`auzP#)z`i)myrBH|{Slc@?InayPRU!yYU9O;hKcv-2XM1mDF6MW$*d zu`Es(B5t(4xmx%Y`{DyHu~BMLIiBeX7$xsa1Y8;`OzedaB?>Q1ggM1IP8-)3-}N7t z{?$zGo9bVIL4`=3Hch0H{&%u75KTLJn`Y!LWCClhv}@x`d3K z>P;X0Ixb~wEc6Z?yfh!{=CDLVS&r|P+LG6tvVHso|KKM{5`R|LmcOY2eo1u@7I9r( z8o%=5C357^xsu@+EFX@_N~M>)^e;;t^v4`B%%GEj#O9cY+FsuY$wC7>dO&zknyi^k z<5QHc7-SH*S*UJvbb}jAdAZksj65|QP>jNMaY2+=EzmV(8Hd9@A5pXg=3R-9I;nRy z@M|-PS*J|iOVBio!_cC!+ROelEoe7#`}!k|<2?1^3D(KwErbku zVuW7uQ8LS|?@|I$Cs_-gn~wO>*GOg<(KReQ< z_?7@JC`AmHysL}t5rt!{F`!O+Y-!&4WY%G?FGLyy$|@;X59Jgi7=X1l;I~c1BGuvX z?>Xt5-z0l<()#`xd&U^Yvk*TbZJ3nStR&gIlS2~0~g>8Ryt z1_>I+l?}I&ci<1Lji9%aoTXGA|e(Qu#jDSJ7x)Gwf`Sr(yzY4cY-duAsUi?j@Mb`^kCTtwl4@LN==x;(aE1 zvKZ+L7A@UIFjP zpCtGZ;Y~Qys-h%U)P~<&;7i&pHyJnYr{5=t%A2b^r#)L8A46F%Av^~_rJmAtinz2p zrynbjCIS^+E>jXkk_&*}nrE-a3EQ*ZW$YBYXP(}n5t#d9?)$jN#!&l~&XGw01l+Rrta+levvrM^+Gl+8 z#4j#uv@D8vJA+iuol{D`rFT=}Av#FUD}T5;O&&a!&?*98zoKvsNWFE-y?&e!v{y2_ zXFTg8FzaOK`L?S>f1dQAIGSK9!Smss3IsaT7>RNyZDfA*UvCeam!+!&eRgV>Kf9y_OPy1bk84gT%%1G<( zx44QiD}zH>(tjLZuBnL{!zbHWy&~{I3TDp$`hY3&(GuSt-8yc)%RyGEtZ;P17dM=W zS)a>r*=jwrl#?Uu(idRZbS-^$zba8=owOEY35M{N~ z>)@jwT^+#RoK8W6P_f1#X$?u;r6;xXOiXd9p+zbCV|@vjvbEry(FJoNdqwKYt(h#U zCt?~&<2HTv1}MQzzhc&F^koCT#Yp6R(JIe#lLHp6zsar}A0Mxcw&m!&7l4*tB_nU| z6R6neMp!Ku#{@YPAY+0zXL4-XwB2Q!kGzucqDO73UgMtmP-Xe{EiUC8IV zr%$0BjF8UW)DlNFSbwMZDXLa0pXU>(&)SR%(V_|wXKQbhxX{X(i^muXtH4#vYK=d+ z2_Y47x`lq@xhlRp^c*5RCi0LvcCK4N$N53s7~IrQ_@E9?Lj&;$uz068RDF4sjk+YV zbogA-C4hR~_L9x+*zleqpvrz|SbcCcz?2x=S_S8>I6lJ?HcQvEh_7o&nZB2_#?%ba z-d!7t55ti{R&M3EUs)~kGD~+(g?85KlaNrn;keOMs|);F)?TZFc41#uYH*P|r-HWL z22#FTbSk6r2xH^GmW@*WD}qWkyQb3grmEB~+FiIsV=*KVejsonpE<|(pyFQw8svjl74t%8{~AYzo4IbQN% zd;cKDTT~xNAK<>ho>o#+ONMZGV4UKPA*n72s+Sc%0MJyC-`|orWYj|;O9lyzhATXK zp)&f~yAaMw$Y`BH3F00#J+=w9+SLKu@*ig;EX2Du3V57o*n-@xEwanU1I^^}Dq8A4 zrQYQK=bjm=UjoxvW%r zs|!2E;{Z(@6_qDopO!n4EaAx+sbUAi5ns+|Ia;w^*IWKEw3;8^ms;Kn3&-6r@2yj9 zzmXCOeiLOP9)?0C4g=K&$`z(yv(k{8eShk?Nq^vNqZr~W;A|^6aL7#Gze{(UuuQLU zo4L!~cYm5&?M-K^XFU$MHg19_vzLG12a6wM^eCo zdMR|xeb(z~8{pOdpoV{fB>JcR9hQw-zg;*nkFE!K#+CzmL-dcPJATPGFCfy4>*0pB z;k{?PDP?BFG%rs^$H0AUfp+#yXl(4mX}z&gDRWs;4`B)lOxzLoQSarT%+wDCVTZ)^M!TX`pd zKPqXg*Xi}axX0_3_NNgW=MEo&AWFQ@{MuSVrn$+*6DyZ^8s0)i`mZR~NB1oCd_Fxs3Or&sb`dwEibiE#KO#)s_aE~^$E`NL zh(_POSGO~;#S|e%le5Vqv_p8cNvBjGg2j>=MSZ#hFZ?a0ZvN}J=eibY(X=T}qO=0V zP#Y@rM8ppo^pS-0?oUVNHg@;JcEr(_N{fcMgp+Yob^*MaxY9Z|;)BSq>2Z@`msenP z!I|3nf+!4GAlqD4Syl077ZKQM3SY#vY;Fnf0$~z6GVOPWe1q=5CeMYsmWdIhjv_vq z8A@6)8Hr_r)XAEF*h2Vo*E{;n3HwCKWt*cA<0#~)W@-x;uQ8nXC-@}Ns}>&o=RFd4 z4!@6)OtOWw>FGz!uzJqeih6X|Lh zmV{3V@mKOtKerW_DOzPdoEdZP@6!=RJhZUK@Nm_*YC~O`nTs74=QpumcuL@C{LqE0{%tHHzS)ETjIZOY}c99VxCV+0xn|!!@(f`E` zCHVan+UqGPbkYf*6I!sVY-t&K+eCOfdC`eq&M|;#L<(cSMh|o(b`NOy?|B~@PF+_5 ztahxt?v`f^AKgk^$q~2;dA;Ju*$d?xV%i*eU0xT2e4xY(|&Zd6TtxT-_OkBij?X(R8AOZ!^dWs_UTRzcykH;);TugX*2FQMr&zap6??3jGlbR z9^d7-Ch#t;o0S#-)^&1 znEq8|C9$;A6wgfuhtrxdoM%accfr$fqG&eVwuewe#HC*w?^grG!&N|5)aXmByRO&U z2V~w`PBzDz13~^SBkT`OG>#?-Awu&JpY9Ms+k2Qp7RCgO&l64yR%XUPNu;0s!(25S zD5`o=kG}Nwuk}~%jR|OuTXCu5aK7qop8rg&qMeZcu?KrM7Os0)jQeJ6N$vbZY3Jcb z(Q@9L*c_f|5FK3tr?G>T_KF9jGAkG>hdMx~c=Ey_xf)m9!(Z4aaZut~2Az_7QYy#N zibVT;a;ZoOjFK;*=3+=jF^4m3dwBtm;cCY<&KF|a=v4OvWQBWz0YIyiU|{5H+s>O# z#77mnYC3lmX;7}FVE*f;GddqrWR(X*f6)ptMTlJx6(j#GV-ITmRDrAWXDmb#wZeY{ zQNKP8o}cmAlm!!vd2DeR_88F9Dnu|wrH$nX8D$(nad&yGGD7KotH!0+v7aa^m=T%q z&SU*vX=A5_J->A5qqc;wUApD?m4YHHj*Ve}$s9609u*;`txmI4AW|J8^*Ga54 zzuirqDI5Qe0gHzb$+ALZwqw(nne(O@*mIq_lIHjZ)JY|_gW3sxx|k+hn;0RKF;RiU^?U2v)$u-{9^8`U-O5CQ5s)Qc5fz6peAiZM|aDBW{d5nelpquk|Mq zd9UNFK$mv!o&K(=!>XzC_e}?HE^*ZA(X{uSKN*gd--sP7c88|~3f;^AbK>FZtk8mF zOUzDfrq<*oQ(58bxTLT|XUTG$Q8#J89 zZZ3Sujei>%8-^o-yD^Li-`+@DFF%n0n{`B+(RqomI=<7i;1MXZz15Sy7ZE-UOYHSp z7Aq)8-(N;Dn-}_mQDJbT#kGwdaHn;=b*@WtPB_1jr;0a%_hoX9Urg4Szt?>&vY;}u zJ<#{S{rkLU>E}NJn}Qyj|B?miR4#X396g!zliz;)(y+B#(q` zhNchGAFI$K%@idrLFaT$6VPQh%EMhBK5XqOnNM+Aq}C9*hSTMB^U>QXGfBy#+~WBe za9Q*IfK~DSX6f}3>5x`(cezG!FXv&DFUgjMastpkkkg_U%B$MBgt%!SVMEO)C+ADO z($5wWjNxOiHryFnITzO$CA9GwseI-z>7mc7{QH$)~@YIMirD0ke^ zj`?P%3?9vsQKIQw!1T6ZI2uhv#F|{e-wsPVso@-Ptb06Wxn6;SWy<{Ha?4DLmW`{~ z&34Tu@}<$3#gZ1vgM}1k+i9#F%%pPG4S6R)bZgxSr%e!`)AYRsXYyeL_c8^;UoX>F z6>V}sLMs#Dz2REmLvXd;YI&8T@dL%TwWhghnf_a=C!Z;V)-LSvF!l-{+EFG$CZWt36p)OLqF z&P?7`a4j8#3M^!_;egs=e*PZv`5*Pwdm{H;&nV@c>)RGGzqOk)y8$PHZl{gPg)i}1 z(D$ptTzDKO7-selzD}@eK3_=o(FY|`v+YJ}eI-*Q!D}(k)5=vw9X-qjoV1I%#$)Z6 zR~DpZe)3r>s@t{S!nc%U83FQAcqRX&bxJE3gXsOt)P5e|GABP0oXar7B^HHE>L85 z+CH|(UB?!khw=~Z%ioXZ1a%Kj8o@4oJl60gVPH#qDYD4@Xj<%Oa(Aui?9+}9Xj1jM znV!{EYMzf2Gjvo&UNEO&)WOMZ$OAXmpTCLPV^{Y}O0hq4U>ZDZlr)_E9t5)#J{#Lk z?x=~3&W@Kg`jhp`PO}IS3AHU64zfz5&cRqo$|%^>*H1?eU|&efC%QH>+c0wJ?0M(g zvpb%u(nfn>Mt$0$zl2&0rsh{Iy-xMUW?+d{yZg|&)0B;|ExUif#6A37_r}szv}72h zTiLxC#|9G&97qdUv1iYcKrjDCH#B;Z_Q;NY7tiG{d~v$kaqF-iarV|6*Yio}K0-=z zeY0i%`cbb$V0+C%3Y@{dauJh|X0v8Y+bh5yZ22r#cE>hixiM8so#DM4e&@{f==oY8 zUS^9#V*V?|dgdeiFk@FcixW?~f30x*DObc6p471l1 zX)2&A0YnQ=3i}YMMi~}?umWD$@yIRn^oj5$mE&b)2W*!oj=iYL$D$yd3Q|m*f-2>- z9UP_q)80bqZmxK#8S#fJ9$(~V4fltm=laiH_qeusDLQTPAHIz%tPG}&H&n8!?eZFf zJ%jT-=qlgxavmJ9@%Piwej^hd9%ELCvF&Q7GQ86&*_&K{Hw3=F$a*z(;GQVvP>+*G zm?Zdw@bLzIYjTci7JRu%Y&-SbOKw#*&a8A70_tuAqNDqUDF6xlSxIV^fX)Rp57k5!YmSuG0LdACLtHg2LNL5VP-)l)IT3)E5 zM5;ipDZx}`zQ!QQD#>5!QO#i#;O8GTFG^teP-g{9t(_D*_PVbR9a%8a9Gsf6w=l5N zXyBqZKxxIO+4wJ{6}Bu65n?-x+!8e-4&+24%FTzuFBX=W=e?5`8Ym1ku5>P=4P)Fj z%>Tftypp-X#;;I~~1k`0YQ^7otH9&d*3Ayyq1Uw1g_$&GU8*?KwE@u|7o9WVG89 z<=5Td)V;NGvIdb`=kVd=qwt$dcq>Avf9hy5viMcm76ECEYG6^t%y1J{-XjHSPN@%o z7F&{DPn#6Ub+`xaAI*U|g}uM3wcqAIqI$1Jw6&z4pIccZNrY`Yac;c#gG&)Af`5SvUwI54V)1>N39uuIF8$Z+}x@ z<66YX`o2Zdbf_eg;mPL(kz1fPk$?d6xT?j9NgIz#b`CO``|Z50JEG(_V2bmgQOiG} zCROXd)Xc@BZT9Q2=wHsnAcBU>H16_s zX71c|=lyzrSWQcHbyXePXV*DS`Oz~N@o6@93t2eQbreu*bK2q#jrP9UI^}8Q6*qW- zIED(WE~BuA`45&Pp!S*A0rb=|HC&vv^dyV%>0@j`DiEY6t%;nEqmbDL-6#pE?b8o; zekqGQyy4H8DNGHH;j1GQpPFR~Ey05D`hx{95<^=%PC8rVG{c+nx%kO(FfydH7eMMX)cn{PMoSy^Pf* zOk3PTE7dGhCflY3+jh~k?BUbSp0}W^Wr$zD;ZJAt>k%g@#+J%>?%d>C{t1lwN`l(z zhu`ri_xf3X=sW3#z?wE^(^RKrvNW({}LcU(|+ zzBRA4b7>u$1o#A5H)$F}B1*s-`}mqMTrardYV$aY9-L>?a?T-(Ce29xb+ivQY>I9T z$q@>7ecjpBH~idV0VlDm$lf=G7Un%B-~yk~+TFikQSb^d<%_u8KYu;?p;AuaR&8Gn z>eL3BIq>wR9vmgac)$W4t*o36VYX!FSF57`GcwKEis861B zxnl-*E};^cl~$&rh8-jXiQ#@K1|Z-Tav&XDRw~ zGb3^rs6;06NB2}u8AE`)J~!UCCoC%bM6TvYz?GL(VnUgC=8lI?B9`kaV<+&-pif4l zkGjP7TuyTDV5_@Mk-cDjlZ;;u@Pj@Bz+1P4pudsQ>x(N{zZZWj*L!i}9ST=aX&X`7 zSZJyjIK3KZT_!m4kTbG2B>Y6fWhpQk9ReI|eq%>vo?R1kN-xA1GRwYqLhOIt*HP?> zjRb6$qRG@tA@`=+7k|jCyzCsW&_p?7xL7eQ*G!O}x|K12>Cns-D~AsJ$yZ`K>kS@7 z!KJo{=V-Pwpz?+d-3XsmI9L9hEd28OJ!Pr+g}XCvl=P*@QdG%#wNSv|Ak@x*29?{x zr~22pec!anh}g{^b8NV!VW?L20OfxVPc4{=tu6_jIatB5b=H4v z`f1nPdbJ~=gVn>7Y*`=2{y2PcR9IgSw`KGOwZkS#M)ujGK3Xo(-jaF%KNZSQvH0c? zQzxs`!PgI35JP@j873K*565LC2zbSkf)!) zaDlNJLCVDve-?>*)U=heGXHyOp3}R*&F0I;nesuKsIDH1a#O!=s^pjaLPFBm}ay zV{Oksnp_N+f&yMqQjWO?GQb1kYh>OMLu-i5C0wjZxmacw=p5>tMX#L9tC>^U~=XlB#B^VoK1&575 z0jEwhPx<5kmgaDhd`_%-E>mmfIm_Y`9MO+#UvXF_D^t~)R|~Yk0D0BUzdihO@r;GO z(|Xb%@bjgW{f59GJXp>Cc*o?_R8rH0A%Lf$nooeh%D3UZx{kDbn&`M!>tqIJ7oeoEa_KMfAgf3m&gYWkVPWGWFhh#6 zT5D|py$8jT&kO9Fnow#>fCsFz9ajc5b720X<8&>HWGG@mDWtz5s*xd|wk)3JbcZJc z)eJv-NXVe59c>3q!0f2w^tS(KoK}?Bs~YWMD4nB)W7$U9XYDMnQTN0eTE6(vStQ3P zGzO-&-MqUK))dG|=!GMmNY5>&9|pTu%ogF1t6PSwO2V1Z)uxNpQmjxCN7wCn!{}ZV zmxY0{svV;IXu^{c_w~;^z#^ov39~{v(i|0TpK0ZijS}Jt<$$Zn5|;=B3ec|%!Me$^ za@s7i2?|auGO|W8#6!hH9l+bG0>xYnTX?&VF41w=;v$o8@Un8(!`jAr@`T5*C z&)DX`iBJ<`XTngeG0*8`xw|3{gT-eFgD+n+3gk)Iji@Hga|{fFYxD}=0xe|Z5q@kb z^uZ~hl3VGr4xMm(2DgV_^-R)+QBcvv_Z1y^!Is=9vVg1wb4lFhjc)$NOFsDQ$0sDL zYj=2ZK_$}bq)hd^BQ{0~Z~iU@f!5IAbU4?{dkXmk@3=^wR7Rl^%M(HdAY(^+Ijk2#r^Om@YN2YS4R%k~NlJgTQ1KOrCKaD>H2ZrZeMbK~g!duy(88GG*PpDA z4~s|yeD-i*Ut-Zg`pO^4YL{0LnR=x7Par}S_4gY8{m;LDl6wDLslSK)XKZ{(#PY{? z`u9zL9_=&YK+qFKa+F{gSfZKs#Hq;TY7LpTF;^pyww*C zJjA8jE@uQaix-9ktK7?%jSFi#GUEeF--zpHd<3vh7#*I|z3z^Lo6B2CoKC6#>gcV3 zuB#)eG1@5RIS+i;smF6Geie-m<_qwNw_RwbHO^-D>ePGh4kW-maAyy+3I88Y=zNwY zjz5}k)hu7_Uxev41X4ynp3*O-Pio>NqIA z=bGSuruDcbQv2xzb^9l$QGJm7Htw>)It4Oph8_{>cG>?LLF9JP)>L9T9z@c?KHw z_Vd+77+)VXym8;Oblc=PYBu8yydN1nitB_Qdnc||8!s9AOuN>?o3Eif^tgUs^bzX* zUbq-mI=UavPA%d6lO#tUkoT6HIqF^X14Uw941rM%yx$CuGly|&<=c#{Mz<8_gogRO zKlHXtS_l7k|E(E@&e0sg0*lBrP9F;agRoUZz*$!JmgL^IW>mDO*V#zd3%m?{B407- z`5lJKTAy*~tkXFcCX~V+C#8oKJq1g6kk`c3vj8S_H$RjLdf=G+)s7F%H^ih3&aR>P zqmAj!Bu2t&*p;RGv2O@UP)~OJ?C-}fLYLdZbI^I<*SUki_>%uUl%p7srQ9!YC6Mgk z7f>7Oc7R%;a-Vd;%sA@+F4lL(z}~{fWzrK{D52M>U7jiM=w}^Pe{J;_%XvK7+3SV)KZGhRIMQE#E z&agFkQmHV#jkNXnpV|Jt_=B|4ok3fM10UXAE8CN%6d^1R1;e=|GxlWYL1xm=dw0^T zhpM~K#5i5Oy~BCPa2v_~ge`fFT_5t^bzY>XOuY=bBrpr(@1`4YLF3vc8Z9EwmJALJG5=Jl@U z6Wt@)H9|cY1LK~{(aWZ)KT%i_5o~Qz;kC2XtJ^!~jdtD;^Nf+<^BVUO#6#c?p26QY zGT8VUdZ4K<*Bk3nQupPR|ETMK72>%ljJLu3%AE}VQ=5SH%cqIA$TjqWFq9K6J9ovo z9L#qS6~9V(JDa+PpvHA4HlnxqTcHUGa8qzy!`g;u3@36QPA|BuI4a}L47B0XF-iI{ z^>@UkcY^q3C@cySyq?C;Guf5mz7(xYQQDua1l;yP-?m#Ajck~_U%%z*4fpsCEC4#k zw7V7&{)#;huvAUwmf|xhQ)`G}t^kiq;?^m=9Kfyqs`Xwe(kBvB=lqE0@_q8rB18+f zh|7n8Di%TW@6h<)U-PLumY%PF)$xqc<8>m_{`~ZCoD#GsPt!?8_Ac2&&AL|(g3u0U zx=H^WTe29KC$#)g81%4XFe)hLJ)gt`Kf}TM3zHEGk4gTVAjQcIJ>U0b47JEnMo+`0 z(w3PJo8a{7!_1e?cU{OF!c{5kh&O9pIX8I>H*CG%u1CG zx^e#7Gz7ikX0`SYUc3kZY|L;x-m+m|7iiG)p-d<9pfF9XYtfX0QXjY-O`FanJE&U? zf|#~ge2@;eDKcnW{|UR19(l&F-%R0Z26c8+*5@>M^VWd;(oAB~p92Ng+ztK$N8{hV z?sCF!Y)G!>`Z2>CAkbZC>fvNC8S%g3C-WD`h{~@Rr$H@Pa6Z00;xO4!?$zZY!vDqP z{U7^M;17{dE-~TR8vGFNdzOyI&s}}%2Dyd)W1QP(km@teaL<^4Oo~srQ&0-4pAV8Z z5!!D3bSLaJO&Xp?vd?(IOM{n5)-A2#Z-)}Y?-?P4QxPujtP!6uV!9-6tw5$(zIgAz zW;njiCP+hCF3-2?W^hfFxxNF!Cgj8^}t7ni+r*gCkWawH=4WZIAv$Q$J zOh};M{88vOwPWDpx|^jJCGJvp7FP3U#VfuR@pc_C&!$rV?k-Ow+FuV!AK$IyqQyB0 zVFo~AnEPXB{vv7vm)|3g$&Gow6hsqor+oj>#w=pY&wT(X#bx1P2C$Dzd#5E^Q1oRk z6db|=m5%zcYMvn!r%pum+(sj+Q|`wV4x>*PHHz{H;qoQq-hKOT5VTPfYf+e z?hP~FOmohAM7||A_ER0*na31Lw?f>Y$~{N-X{gm3<=KZc;s2GfKU>vA2XVIc)BI@2 zBi;;98C0N`zd2j6hslHu?WDe?!3ysAcqS&Uv;QCpS-)9g?0A3?ShRteUV52LP|(rA zbv*=!Ov2nY-k!g_7_*}G+rqUl`J6l4J{Mv0Xd=8_e62CDg%Vf+66wEdnuv`*j7=z8 z<%J5{6C+1?5RG=&ps!2f^3I_ZA!}#TT(eh(q9cPacBWXm??aT>1qj!^K*6gJDbLIo zdagR;Cm7lg<~OWt*i#u*M7~>Hl-k(jFh;Hmr{6_}x5BcZ60i@`1PkW;U!nc*`5W^e zslDZko#59)tK;H*neq9`;C%{gA=uagVpU$fG|J+?_1EIR1>F5SI(>}HtfFzUoRzEn z!65)a0e!skzwF>KoR@P9lt)2&UHjZ8dY0e)+8jpQec80qT|KpUV7}!|nIIGx0llhF zwW`7{GA2;(e899CJZBNhF03=d8_Gd4RN)$!2U*G^savw1TvAGLb?HiPK3J!=)(mQC z$`2WHG$_G8+!R;GvJiPk{4~y1S3oj5nW5xa_kFT|-}#VdFHH`C?P?mRT&*&Bh8VCaNp2C*Q7P`a1!$%P(r)NE< z3Y)p}5q-HuNf~cU`^=tMC-)%$uiNu8h&FLZdiN&?{O{ua{|`_; z-hces2k`xy{v*o?4`?AJHuZNlkHF8rU6#QT`9H%lElBqqIA``qeg+oMDrJFdNu|7&8&AX|95JQB78INKN%3;I`rfF9O#6U zLQo^2)U^Kg_bZDHxlxWF5yXEYB2`?bj9Ta{t#nb-b9Q=?KP}x0Z`;t1$Y1sQco#aVE zY#nWSID|a#bX=4jqxjq#w4{XVDCzck$DoJ})>xi!Mj?Xl1Wxt&Jp+>Oi|#in13RDC zI=xpJy`!^t(*LGtebOrhTbJ)nfa9)&)+E-Z$N_fXfw5iwb29rcxt_FauoZLmyQXv~ zE~Lq*KIyCZ(DWx>RJYNMO&d)wtV!R7Y~EJY<_5zl5s;41b#H8Bep&Tj(?@M+`La&axM?fA-#ejD zHM%j1V!q)X9z%l`$NDB2G7raD;N_fxD?6Ls7&c3kIr6X}&?W@@*%e^lOv&(~u+E^q}(VR+Hvd8Bv;|Z=Go%i z&ouO;>4?0H@c9#kM0a!Y%hXfHu;vegKVGMRNGFUt?=q&I(--_v%AAN4tnin`c<;(E zjJ&oGjp$Q1*Le?n?2gcZ^0Sl9B)@myCjo_9GF$^&+=bdF+m6LXUUn~i3s*yFBmbxy z&vA%G7&Tz0_Nfj6cUs|I6}Jx!UXYUjBilyK-Y$q+&n_@rak`#w33cy9mzoC9SGY)k z6F6KQK9*UB4m(mf3@=~?+qOB6pXvLNAXXpCUu>w=UN_g6hWDKKZi#Ci-lG+BDN&WZ z&&QvK&)x{#VuM$ktm4`qzc9S5|6a40wq5fmHJADBFo3jN>|OXSRV#qL^Y>5VS3H@t zd3zLs;_NZLM4??9^v{$@5hD3+MsD&D9irdh+HkWF`5w(!TYV(#}!$zT? zfDkbnTFGWv8YJ;dJ(2E0oA36`2_!z#SD+`QCaW!_Ml|3Yxp@VjkX<_S#)XUI@?YeRonqGP!H-8`=Kn+iJfITJ5xG!&G!Z20o8P3|BKHl~^ zU9-|-ofX^B;AP}%#H=f%zhHYe5s*pD3Q!(B3g1b1zK-HMBPDwAy~+k=0hjYO=&s5! zQU_33pYi3yP3EL?n53Ee?Jk>2*QLN*YN51v9lk(w0^Xx4%`?{UpuN)8+P%_k-fYz9 zfCHv&mL=Z7jk<-d?QWh4x22uGb1Jk~2|moi<;u$9O06J&dhx`Tii7 zy2?#}|C-CRRej6@%K}Dw!e*zL_HRqp2l(~wxsR63_Xt_ONID(ib#?r(&1>gm zoFZvVCGMqyWDuOHdm9;{Fa=$b?`C;3^Bu-_re}zRt*%*xv}~<=o`F0!9d*?-_cc-V=xYekaAF@@zY_og4QJpS%NODk7p#V&gT<<>q+$9 z9)m&8b8pKxr?9{Qw75La)bhY1gasl#CAbdICSTi#{+3!xsVZB(bnz=hD&hAb} z!R5phP)@~9C~B=v<#Y9cO~*PZQ*Z#wVMuB&Tj$e#b^k4vJV_8uBB%leV%`v&aQ@L{Y-5QU8d=(2O2(CG_=O z8UeC$r;p;$p<;iO9oT+ZZf+X02w(T-SQ*Y%kLE321U3QW4oy_F_}L??Bhyxq{|A(C zjg2hC!d|KVR$!5pi{Z-^6>VvQ`+M9p^|x#8pyRkem$_}E%NmG9oT>SAXvg~FB`gBo{ z9+?j%#a6MlqxWt6oMI&2B%Y!vit#->6#Xa+$)oJ$DuP^Tu=+;E0V3$a6EOe0D z?pp6mo3wknJ4w$$+HZHuLkk3zquD}OazWvbAqLc=DEI}2ZN=`tY`ok&^?MY2eshFC zT04KP_2j$rW=h{(#P0EbtOWc#%>kBQ|@6i=P?24!d8ze5%V`e@M)<(`cp=ZkZh z*>7?xee)_}75$8X5kOBC)C277jof&CHoili#i#}2M_sZqyjJ}#Q-DCq;ea=z zd>I#)c-)+Xz3Qj8dqOU#gkJ2_Z*3vhR+g@W{SncabbZ+x=sQ$ zmzu%WH?s^M&_nXX*@;p{_ikUD}?$lFi<>m zH#@CsHFI&3yKr;UFd+?Ykjwz0lacikb?P>hrLwX{(oQb?c-lGo+1MPkHSVi+xYap( zxf(%)^OC#sb0Y<%dI^ksvDb#j3m_EC8(6Q+-DO5y*unC94J}=4`|`j{R1q z?XN79g_yL?^ft0#=ae^YXP!C4p7@u8D{;}(<_rk?%Bo-kZet5>dlqKC5=Cv^VJjx{ zYBJ!aZrZgXWMa3QA~Vl69#iGJmIGo%+V-!h?05AYw^kjxNx}T=P5K+0Kg@d!W2s#K zLM8BB37czO0n*H+6`j0SCWX|7Ska>)Wl;&5uhl;!F8h}YU{fzWJvizSMUinkeCD7| zNd@t##baXLoH}04-LIpSR`>OhmKhV+w!}o2=ONqgTZKK{;94=V1}JJjJQ(IS?KiN8 zbyvJvh^>aQO|52qO7YUg~pm#a^)3W{%lo5^ZEMyhaP0D#cF>4^41QyZUm6+ znko=b)mv+GSTw*Y)L78lGuuZyWCZj|9)4K*(S4jA&K5GFIUdZ?{waRwC3WV5qlCw} z+V>e`5#ySx()UtTsBwubmqc5y${3q@9c|v)sPMw%E^EmpT1~pLH~fry?q_|=i@)%G z53O?-pnNJ2OVu2lm)U!6Xk79F7Y=2ND9r&Nt)=jO|Ja%T8Ldy$~CYel~`-YtEl zvCY-L0t*P>We(LCQnveq*7YLFyIWf-PM}4&(ce)5ySPCMysxLV&w*;8;;B>9V1L8u zxGM6SbV28Gae`3i#$Eb9bJU6|kkV5?3Np*pj-eEP#m)WX%UNSj^b-yKKC9$++3Lri zNw8w;YkD6AA8RKr(xH+OYW>=?H9z*{TNAVV_Q&bqU7(SkA&~*<&}0p~8^_ZPm-bi1 zHBT4hw0Ij3|IQ>Mtty9$0mQS-Y_vTZnVBqCQ$xeZFDzaRz>QmEyTWNM4++lAx%|FJaY&ulrG5z))0&YO6j`dVm28mUY+L`AVlNCZ7`%CK`hIg?sfJrjU)dk=TBIkrUg( zoQ5&BgCpqEkQgP->Yv!nhSO4E)@lI2uZ0)%TJ|7RS)wiRw{#(L7}eS-z+x<%&UzUD zUIsQRIJQRYA1+JWBhp=Flr6fesTVH@41Y(!{+cJI7XhFwt`o|flcDAJ6IBsW zGSgUZdiBarh;%O;)Y8MtXg*PB(R1nW7N?z0pCl*9i zX9cEoz|kfmNPe_O>el*P>x`H>-XY{B&HxzK7}8;`X%}WF7OC*@Eq`sHL@Bn7aqwE# z`7xw}U6f5oQSp}^FD_>J?3FK$l|Q@OOLc-S@lcx$+T#N+uv!}k#p+_VHIL$}@yN!Lz*k^=Aclw&XbpEwa?L6&^})DG{&W4;L>*1e*GIciv{9b#YW>hWUCtqAEWg@lvyFQlmr;ra zB|2}IHfCRSQ*ByB{PDi$S9=CW9<9lyar4yyQmX=*3THABzUX?qP|jh+>l0BLp3mYh zO?0#5a?>HsM0W@k3*63-6Zt^}fYJ(AhKx1x++1|HRn{=qSKe^NOH)i8N`f`eg=I*u zb**w9`|zF@qBZfmjZOoOB=qoLo6L$D-*I3nQT7)^9SwKHU5+{rBR?!s`}kF3Yp8{X z=$q|7YUxFVA}`;ch(cimw*G9#Yp%+u=z{wNup;i=xYfHzOO>8hCq$-|yf6xwHGC+| zESI3#?Y{Xa^gc^CXJR-2Q!rjg)%*jVMdh9dayzyxhoRdLz{$ zJmco&tU&yRCGehXXqZ6_#BWH@AdTDvt+Q-z0Hq@Zx8=KH)O~!F!cuSLxOSdKMeXC) zcE5%7&T>c5u^==d&LhrY*s6o|IK`&de*NR&ViFf(22}5?(s&NYtUd4D)3)N|liQ~T zAIF#!h!5rPs4~_h6h{{v&#QSmOSZKJ_f|FM_5QNPFcP&Kfd!TUbqT4 zRHL3CvKmm*H6($NqY*R2%ObW)26J;gIJkx6T<7&c*C{9&X9G`K)9J*_m!VZ~-N88n z6$jmPu}HVjv{Q!Pq0Jtg&VR`yXin3V?FsGkZ z8Wuo91-tnbDHeZ)f-;5nl90uAbIw1`>-kfl)9ZLqnzw1o$>!ca5;T;bTNNPu>Ey1)>jIi|xTl_6A?EPMHYQ_n@`j?UwDL#tG7P}y_ zD(@%fGe{tkl3iWyULBv=6T{EE9_kF~cz9`l>UE<|e~_bf{NlwBB7RRLs8hAFN+By_>&-g%` zDw7)b?H*FbDUtq1do<>w<&dwzB)vj628Wy$9^aw51gaIgab^I69_}h<0UFL}_wAJA z#A59G-NFc)JnLGjmnZU7u4J}lv(A#|gsdBGdoNY$2>k5F5|7S>2)JgSXwlK7 zXw{Wl)J^SFOLYi9E@{aX>1M4fSLvW70QbfLPwNwJAqyZwZsN=vaGN}{1fH>TX(?xE z0fnuZJ5kS-*Htl!<_F*+U`U}e1$>CpH~sJq&GWUXw=zo5_gwg;ZT#YcWPC-g*4VFe&d-gH}1suXTSH8`kst4Z-k(d?LHhl+A*UM*qs9=eBiny9@NfV_=w_A zw1DyylX;Pp*2F!g{Z=DStsB7y&y16^70IoB|F{M=+ilZlVv^H~L&kqroXCyrzt2v`A|&z-@E{7u;t1 z*KQl+g{hk#G}KUw!VU_K044&+zC2E>5KKFvtKPYo~P2Fz`o$-aMnX z=W$Wqu6gjitw{7XYD0BUZH(r$-?#9>s#~C5jbsw$d|bR2=-eWRVY^nma;d)1^B&LM z$lQ;9YJeYntovc5P$Q)T4k18;s&9WYbbhN_J-AABdlk@4YIJ+nCQv0)vNFcMU;#;V zYK}CQLcuXB0yCgq=#9@Qww*}2D?3n1_wCbiw^dNt)=?NL&=A zziZHD&5tYRjN`f)kljgs#l0;5@w=voofI@w>g@%P(ZRkEF%T3R4dqxi5WeU6QRRSP z%6TjpUcWlfRhT>#;ZlN7iIn4v{~V;=$dO=s-Of$M*uE&}-H;OEVDcsu7c7GO{+ZXd zcjBpD+_iZAP84}4mB{#n+iOyTdj1%Jtkq7Ia6nL_sF$FRTTzT{IWSH}xt?4bYgGMB zB+?s``9VfpuV?p;fG1e9Btv>eLoUT%vNf&J%AvKua|#NCxm1O>W_hk) zpiX|~(;CuXY9PFGcA-4@O`S5B-+?&hH+9fufDB2wD$X0l#v5a2V${k65mwpbNb_JP zJUw(s7#H!hW;Qk*TTO@o`hVd_41NDm;-mm*i0Ncz?M^gJS5&M}Kg4FeZ{HUYgQGpF zDo*1OnnIbA)TdNBN|Alwqfa>>hohdDoiqjYtQTrm&Q8%tu0_eerUWws%i=n2zj(tr z!G)c=jRRhRAJt_K;x0)|qQ2NZJy*&TSQwp*e|y78_IECkS2GZn-Ot>Q#fMZeqbzj{ zh}f#cubVl4Rgha)xqvF^^Ry?XE@FQAxISLDmMry>)NrH+Z{nB{WX8mQ`)%GQQNSFYW0ha&j=!q$wl$`FL*a2Jliwuz5OmC zyz>lh_q84Y2TMKbi6e)?@rfuErOle}?%$HHq#BDE&(HmIZ>96wE^KTlyF2LN4NC}Xb69F=_wI|#3CszZ^D$&11VKJhi5^-M2@ z!Ao>F}V1|6q94ls)r&T%KDacJzItYJDQjN;q)e zCv@yDH%H*94wX@fZwL1%n%pxR2QPi$rSQu~6nwh;aRXqzdZ=?U=9obw^C^f3<@^Md zRtc|XeoCf4nnYRqjNq!q!;}aZj$k^Pcp`TS8dFXr*y?&ENve2gBT5%}M1Wu_WEkq6 zfx#eoSCZ1wkHb4h!6gr4KgBo<~m_M#vTCgje$<4DUEpGU} zkUxWSkwa~j9-Qo0|FgF;Gv`4Ch09fq=*)?nuT_mK)`Gzwjwu3~o{!uW(ZI{EX3R)@h4 ztk1TTE9pbW;zcrB+>AR{yfUHeszLL2uiGsIT8Vs{Z2I&kmsON>Oe1wWfvGo~mX0eP zFZ9ex$EE}=lp9~I`I-pWE%|mPE&`Mj|6w~dEkS|_bys3yiT5d{-OC?wgx00E6Hsh+B$NfCudW_9!)&naSI~svs`IlNdgFvCJ8e>fWIk7Jyb zi!6`(_rrvQkL4M{?U6{MviU((-iKh8h4!Ukg6nH2A*3UA)=UG_S~5VzjwS=C9L3=Qi{-Hs4?&_i6;<(o z``L$1&`PfhA#OUsl5}O`l^OT>43^eJEGS)Ic63-lm) z_RTUrF|+Nv#bZEIE7J*{SEUc9xj3kJ)ScX3uC`QH zHtVo+kC96WFizR6eLLb&!6uv_V5=*}+?oG2TA65YRJK3ZnITR<&>zEi_%OP zF%=Y{@rrTAI{;b&C%BaR05;i_6zTU0W01smh@p+Dffdc(Jq29G;DyUts>#5X>4FSC zk9AKlf>*bkJ%wk)Ai&Gt+EOp6h_<+I)v(}N7WKH$IbsyBY`8rer20L-7L;u^x^+_h zgWkt~7?+GhwVpSKAaXzUw4KS`d#^Jf&AOGP{gFv&rU_+qmzU_Y-}BK)PTQ6mq|@z; zpwz9cD&rQL9+9%s=FAq^&g0O2CoBBzd!knbU#xu+*Ub|eD`%XA<<{*tMMfn}h#@HS zKQ^qKYA|DHW$&AC^*;RCdo!M!X2a8H^X)F*rD=wcCBM_6x8=pIp&&weesb3MA6lBV zJcJyKNoaLC7~7Z;%zxOEe_epK1^P78U#aL_#dUA4?;PS{5iHo)@Y@Rl1jD29PAn|I zG~nuby{ec$lIysd*W6w_3%vZ)dp>qa<2)A*alC1Jx!c%+hd)UM31ir8knpxcTLL35 z^vYlPvxUK+-}vL0?eWOVOzlol)9k1v@ouMUX4gD<^R`j_+M;H$1d-H)JDGglu`A)Z z+~to!EHws+V|KnJg)WvRliTQFV)^=GSSi@vaxbB9<9E>2%|^fMb!lv#cI{A%s~%n* z1Z>3FSHWnNk@3@I+W4@b5eDR0q+idN-hPL{A5C@J?YT3otGwaWOWtvzM43umS_na1!NS*MUQ!?`;)df|Ikg z)j`ZQ%KbY%Y*QT>uv_K?k73_B+9|}3SivO)>l{yJ$K{};C&SU1YfC-N7ZMLg z$*ng~EFKe-^XhU0rJo54zkZg6tRS1`c=_V!?U*6#JE-HmX3HU^VN(m!45LreM+qZ+ zTf+J3eAL&ew>2X!68%HJ0&=BCe*kw@+CbVYfaAb3>C+^+c*C0_i4D!cII%+AT`OW9 zS!LG)b7`u3_K8!1kGDcu@FCw;&fcjA6j;D5_#I^&G(<+Y`g^%wzCBAimxWR=GZXII zQn;CWaN~B(s18+AXSTB}IJvp5|M*@$dT;?g>uTbS8Qc?d_PnEVE}McPECWP5XeR=? zj0_ICO|F{wl zX+j7kN&~a&!==gSgA^rotg|lA;Y2eCXI_+jgkV%SD(Yv0tS}_%`9?&Hz4%}lVii<; zZ$z}@R?AYYt9eZxx`jDo{*c~kzyUrxeqv^F!gyv29Ee|eYd!LH z-6bPl2rpd?x=v(+X%0ELK*$E0j@y0}?eNjVVQNlUzg01^nF7tQ4(}>}n>UPznMT=! z#KCynzi_ciSHXK4hz!b?sN>E;J1w`mX72rJBpxbDLQ)YEB8O$A2C6bJ^-w8Fq!eh@ zwtikOpp6hFf``(9NgI|VHP0mFdX#@8&N+nrj^wfq?w>r5l5B<|C|;k=;JKrugN?X%sgQ+JQ@}kh$KNT zoyF}!p~rfSG~%=y+1dJu(c+HH9TST%6P@r`-q;O(F`lcb4$4KuYgn?L%x}edV3!9ty1=uVdV{C^C6l2Y;B8ZiM2r3&> zVwlJ?l_%c`U6$72^G(?O6;=N!wnl@2Mxg9B-Z&DXnn&e_mkM80t;203Uu15NZk5L~{Fz7`2upHU zmM+z!GasNqj!10LE@9jWwR2}OssaU;`wM=>nFp9MDpG=~nVs?YnGaxMrN&EBXODFzNte5Ra_A{OJ* z$c5y48`wPb@OQUg&VC3Z2%-f^o15@CoF?Rs?RLQI0V_I|);wCCbxvoXS?!t}ZzEM^ z1A~?d{R=ooitQqN^fIgcEPW#>GEQv1P9AN?6Lr)v4w@+3U$1dwV-XM$E4teEGRx)l5JgUizGQT9I0kr1V-4y z<#TP*P?sLCEW=zwATwSuN90v4^EiYGKn{o|Wuab17jz-w>kqx~K z6|o!5v>Hw^0j7!52EkcitmcH?hD*816k!B;+3bE6=5VkD;Mi*1YtJ-D*Qy%HmFL7h z>5f~}3Daj1&8!B!e}XA<5bvy(XpUXX!kz9y$d1<_sF5Lju-cTZ2ryNylJ7KQ@VLDB ziuZ+yGzW>)qqcCT7JP?x3hPd9c=m2GSC3zj1W>+~Z2j`V6tfc6Z~Tf7kAM)0ZV2wJ zypf+u=b?MXZ;a{scy+zUec=Mr>?ohitARp{-JObsIcMNbdt@v$8_%ITV|ELG3Zhz$mbViTu zFM0BE5T}l9NbF5^;%~p)HAeafYzaAAJ#n#7q%OXN3LCw4J`J8@ZE8Xh@2KSrgp`hj z+_X#qP->w({k_nPZjrUpM22xOkg<4Y)7hfE5+^1zA<;OEtSeMKlh=LmjmDgkyc079G^rFCMd?n<_yfiER`UD!bS3Pw+?gcK zBR|*AIlSWf`n96{Kd#;~EUvA~8btyGPk`VO+#$G2(BSUwu7yhh!JXjl?(Xgq+}+(> z3vQjayYJVh|JC!<*0tAMYfKqq4qb49bV`aRIP^c(BF=#Vx7^6ClBd6zBJj!9`819u zz>Bg+R4VN;#*0_g>5aIuuF68nA6zdZqcSehXB87~yoDm^plcO%I1LYKj22oml%_4Y=$$sxJ=Zrf2pLHH!t|M z&@N8$nvxP+wzeVnm}#S|nBPTx6zSp!&fsiZOJcXM?*>|OAUL%ni11#B- zLZS}js>=Cxf782=r*5^i6!|hdJgQj z>^ZAbClzmA^=@3FiE@FmO_rU@oUcT7O7AJPjDyB=$eh(c)xYl_uV#`9dn+B*+B~o1 zGgw~!9o)W#C|!%Jr>9cmn*(CmPsTM_u6avu8Hdy}kXaq0bw1ZdC|OoL?3N6DkXl%X zhCy9V7|cmftOm9Yau3H$J^Y4%rTdVt=M&mz=>Jm-kZrZb%Uj96*;3Ujq0t3Nuw_BJ zf7M1&E=(QRp(=d|j%3ngOPY-Z$-6e)89vJBomph>RXCRWn(7b_Lf{1cdBjd=iEcgN z@-Bo#rI}$-qPX;poQ}(fs+QN(4s3AU@h%%%6RAb8Pv(4hfiJCEvPbpU#CO^~X;gfi zrrw|eb0nF&U0Qy+=kn7B=Ij4%X4!LDu1;s%j$Di~a)eM2bK%>o%fc**(TgwV6}YbP;-3a=sNi23`Zz% zKW$p6wh|H_$}H1BRzUkY@a}$_Y^D0Ear#_wrIBTb>&i~N_~I^mWJPql8Rhv4psiYm zNx|`H5x>eA3O9ns`>+O_0p-W}Mu;m*kk@K;7PNFC=TN&a;Pm?u5*hAQFsUw_KtuD& z)#e-!sZB(|d{o#}=Qqmxn{iJ5Y?=fTr3fzr_^#Y5<;F#z zr&LC+XPuoQTB{r%UF2O~I1ei!Y4~uc^MoUA<^RXRMTbE(>e+YJA3Xww!0k)7*E&Ps zv)aJh%ptlK4q8^}FKoYn|HGOG9){eT?nGCtpK2^Mp{>p!TyB}Rl3sNP~t za$M5pez+}lb9{JmX$|_F604@0Yg_|svuB8HukT8;nk}(Bx-lNqja5BBZERd@Uff`C z3YA#d*UTLcPU~?Fo$clp|k~Is2hY22RD?Ewa`T|jei^J)$ojnqB z`MmXrdH2|bnJCgeoIh+qsqqzO?E-@KB@dq&=U-?`6XSzjYDtZLdj$)Q?PQG6j(yZN za@)CV&N%NC%B+K7Xy*wadC}4tei$UWdA*J{Sy?IcL;qu@yupm z@jK5)pD}O&oEJ;se3v9RIigAo`1zscqD`n@;47Eu|jri>YcgyR%d@s_6zyk3OMy}R%efYZG>k3W$jnFgR zy}uD?q@DN`LQT^BxVVe0bgB@uwqy7xE|4$Y0_K<+z3Ho_FtcX)Qrn5e#l%l67OB*I&qLZA4INfj(ySB zQwQ`1S@a^B&h`B((mUArDOuk(kR0G(M>h7 zgF36(Dep09Fl!95imy9NDD$n*flP^!Ipa48%lU`JpnE|WY1h4$BGPl)Fw0Z?NjSp8 zt4&q*ZXd_e$M%#R|8fDXqdV(Ruhu-l(y5eN9`LQh-;wYPdogpeo#DUaH5@!+eY4b? zRjv14KVGSxF9{Anj}wjuahTRe>du=KVJ^JA55JL|{0?kFBuy?iKQigF(hsgYFO}4^ zguQ8fqf{PEVml02L{aTB7q?c|!bx_mHqEjg&`-1ooODWa240)18MxB&@01A{mInOs z?ml6=+p6XRZ5UVe-kAm(h1-2>8JC~yS{|s_fi^^~alugh)C7N;Gl&SiVssJ)+F#$f zEG>f{;xZ%dmyHkBhYsGxjr+$9nf$XSM~38;e(y_?v#GI+=rMVo&X}HWrv$*33Y7QG z8TRc%&MVT>UUp`^!7+m-&pC7yaI8UvVS}yV$zA3}r>W?#Y=Q-1R_ekJphqL=bgyh` z;TP_?hWXLBw^NqinXWQzwv2KEshmnG!b)izR7{Z0hQxC3qOi_H8957UVvF*EmL-Ym z-nbeqIL4L9?d=_rD(RQdh8!_?()Nyn%Efs`8Y#&_sZ9QN&7uA>tq}ygamEFet(JdX zYSsN+L`iT`mVY8e7Yfx`lZWD1V9zp7zorSB4>OZ`ehA5}2Y>T&szH8bGx^0eeq+qc zff19IPrkOvq=HBFc7dKh2NY46hoO^=c5M;)=g%hY;h&@Js|hZyusA8O^-A1i8{TQL zKV4K|gG?YXJ8cU~6)i%Md}8@VxGeLY0R{e?To%9eIUu-^T+4D+0xL#-^NC}{<}4SI zONU?Am`&*wXYXjE+wi%Z`AVY8-E^c;H4AV(d6y~XbpXhzt!hV7kCN%wVm>M^|2Ve< zv1H8w_Dh=pOOMR~#?X}1W{C!8KZeoi0ph$ba~RCbQ0Xk|MAl2POxKf_J&f*Q6=!OPe??LUTErAzbAv}#02 z7Agr8(tKL{ILscvYqb;INE z%9M6D|Ks2BYACC!x{y*+!~2dUF-}?;Q2ZlVla>`&4Dfl}G8NgT3iL4Ob+&KS&E$h0k*i@zaN8*GNM)-W7_21IajTQ- zzPPF(K5{zrgG;cX_Q#c%4PrpW0X8Kb-xm|(Rp=m%6ga8>MP+n2jZ=mKQ;SpRS!%6{ zA~y-yrsdzb|7^O2y(Khh%mNGIlcG`w+w;TN!GAlr9Ka#`*=Qwg*R>r$Pv~73LSXt; z|G%{jm}HtXs;a*Tt$ECa26~xc;kU#KU7TZ{;Ry$Fdytpl-Hhm=M|(iRy+V*E-7Zfl zirzu<{L*9JEcp80Z}?C2eeEx1LPEm&FG)$Lm>j}?QTxG9-aJBg^#=D}QTqQ!sq7aa z+j6DFt2g3yNk6%GW*D|HpAx&T*-fq-cm4VQ4*TbqLs^>zrDv&tdUsvbv-|EpD7d*>JIe=Zm^LrbU(79ggL8-8Y(mDZ--FUTvrt}^=v zbRYrrG9~VSs*?LAh?&B{2AjGO%mPXOCZU>+$lzV!zzVKC(jHC z|9&1@Q4a5J#@orPEXAOV^SHkDJGoctEX8Wsp+PgBoUp>(b?~%*K%N-2fTw9c`@)hqyoO#`Vxs^xq z;~Eln=qDKL`=^lLY7><}XZudX|9gXR8G(E=dy--859h|shLlSiEl~`?L$4$YOl=M$ z?#oY3*25XrPs8@H7rMeX85-6djD*hEQ!JDPpSpo1v9$naZ41{ONM-O!bU9Apqr=@= zP*>gCiE_eUzLghlv-HZFt(d2iBKeI8^efhU!3o&N!#i1TUXtMsB!o1~iO zx8RR+WXTh{rFF~tv3hgTwIzDzctXBmKW4;txYe_QmbcH}l62f4GiEkc5}L{9SNmi4Nvq5DPAq4cvIKbf}>IFt8MWQ<3-Pzm{*Xd6=C@?Hbe^&c-Fn z52F=QuaLBqyl3uCSgUzR&7z`B$-It}+J|3~C_?8iEoh&yi-)Py9jy_8_(ZJlN zSZXIR8ntA~j_!Q1PW!j1d}>k%+N`KTKm7*r?WGw8_u|whJ9iWon`(`XW(n>~A-VTh z-X0xH>x97z32PaC>a2VQ=qMR1W8~q^z(dFkL5N$5SN+Oxb}jhNv@0=a@gsu>Mo+r5 zTJ$*1DF1%#`UgRfWuX$sF7e;@?f(J)v`+JKw)6tAGfh9`mUSvgI!^d~{Fg_57HYt8 zixrzM+-cHouidQvz*`FXRBT+%<7?<}0ND;?rHdinowu6!hS+Ay7f=Ugzz+f@2XL~z z%TdnR;$L$^D8$$J*QC~fGZqMlIG03EBDR*7#ams*n4SK>8Z5OU3uRv4M*YZ zG_?S?mHqMrc>)S-f_rsA|1*+W6X)nxc;Lua#5)I?J?@j`-6`~~`f!T8(Jz&tk$RsE zX?bFSCPcN(C7%tA2QOXM;KGm^9BWBMNLlHj%`K4znAQ8~ff|DfaJUCdx(qN5+|FN1 z@`t^uPjI}lhe6KhXby(*@wYw87*8IJ2IRW908ng_@Z!q{>oH<6Cr?WMJ(LbjLzTuNygC>peN!o0$juwcf^mReFS|n5mJWG3j(v=9>0nx*T^VSO3cueC!B{ zd$quRA0N&+TV{r|`NZJMR&|Gu@5 zm4b%Ga%6r!83Y(t@m2+gd`(#zz)71VSar@ zY~KKG=1NA()xm9B;Qa!@_Prx*CYVjeuNv|**ZW@=4@f2lqlU=^ZGRi(?@{G`8XD1g zbwR1oX8UDk;>no1M$xfHQ=;aZgOgpSH`-_uS>lqqxVW@bFxC63EYw;c26h zgbYAs{{eW`h8TMv=G13~xG#o14y+mby9@6QRh!(4n>DR?lZLf4#IWH8e0Y~AAa<0? z*<@CPh?f|jk6sq6N6x05j%}O2v$C@V3@__C$|>I$izy8|$G~8N<175rILWFRIY!ql z1Not)d5s^~C6@_|z8a1qVRqUT(DSMGHPgGj6@|w!HZ!@g?_nTZ%Qkzfkm3tQ$lRX~ zMYx?Ci|6~p)ERO4kqkEeEMuwvSbc<^$C1_IfS%I{tDTQ&F< zTkcWs`5`$<26r{TK$lflqZ~>@j4aBP3S+RYNaFu(KpYRR6uXD&pBi+tY>+&-HXWgU zW*jPM$To$Ym0RC5dHd4?Pv?1$8w_c9MBU>EP{kg2)j|vsRrf8c@=mmoo$1;Ci9Epy zYZ5-A8l!bNxhz<88SdmoTbf(e(VmI~nl4MKR*mhy(?PH3-%M1g0G>F$sdseYx(bLJ z?0hTal)V(_)s zzW~N8bIWV+5(^Zo8Hk%FVNccoJVyi`0ncIrC~!Y4%#zbC4iL55S0cGBSRN;SW*K}m zU}`cn%r2kypI>)2Q$<`|k(=ix#d%%Q7zXjbsi2#cX&q<%=swCmJ{zI}Wx_mNJ~|ma z??r3Zd-_CnrU{I&OW%n9{T{VI!Ea|%G;};p@j3ka$%ION5&5TPA3TH*S+bydC{px` zlXqK9dOdy6OcbDdd<%JhKX4wB%eSFX75;%<=DVl&m!3|mNaai-j~Raaj%&GJ;nyG2 zIkIXHGKLH-WkWu%0R$TyVA1#bDX#`}@y%g=k#Dlin*J{C%#W2}*B{<-pGO>yEOxAA zXhCsaoAxP~7V6GE3?uw)IUi%DxQq>kL@R^U_N*(PVrOGRwV3NjWX($ti-&%eJp(j( zJnTJAz12l99Li=Sq(TtDMCP8kzLBWi?@?t~Ep7$g#+y(E;cVu+$YhkKp@f!#K`W+u z;k}>ra7EX`RLUhoOeB1}o*`ffR2kTtW-MHpw+Qhy_<7UG6>7-x3vy81c#CE`$1AF@ z?0d1IpOBaQ67Vsp&(y_8?AC-b|E;i$bsn{S1X%ZxRfzjgj?2)iw-F#AtrJ=p{wS9veU|+|R{62GI8s&N&&jQ2 z-ry9~5sc)dSD-o3p~069%1?N|5VK4rSx&|s6?h2vva`?_b3txLtUB?28~(OF{lZkW zl4?a|Tbc8;)W!??Xz%Xy^l!JYs3((${Gvi z*$7q_D9d@O!wu6*BU5*)!*QkqW>#kqz4tvXXJWsYMW(**WACp5hYv<}p$%KD>F44b z)cL`X zAH+?`!0EklwbgE#Q~9?y5SO%#kg@-V0-ecJ)N#kCgN>dp!<(z7FHF{akH|_NWtyg0qhYd13J~i1Q z?Q~w`7oFmQ$`L@Nc20(;IQO1%l&VdBzTTRdwyBegvo{HH8gOv-POR58=Tb9{kw?P7 zS9U=)C3-APf~RFE#8KaZs6ktffT0){J(}ro3cbPUWj;%FdX9|q_56WPAy1Jz);5KF zT>kq%!Kuvj1UUiA{L|K~M_${t3BuOOdltMR&8b`^39aeS;}ZywP1bb!5B}ufx|GS4 zc$67(*NS_0AK!lPOxcm5TCAn^PU9uczG(1(!dbCn z{ohWnG~pHqDd|$$W!mXwP6^>!dCKXY)>i<3O6BM{L7#fy)@@<&*PVR!gT6PpOLE)v zfeGB1vb46sTX3*1tEVLvN5uqn1F4Dtlk!{56#k{6VBS;rwI7k~iEZRPg5pHC6z=T3(FLF6`X0$lPfB6M@9%3ZbV{k@vm}h;L`H{L}DCMT@63x@}!WT_vE-9R^es zo4&dvUDo~Y(2&*!rT(&6Ucm!v)%z`QR4e@X8Ne{t<+1VM5O8clZM!r)2pDMBdOoz? zV1FjUX${uPKHILTLMD0~S-1p97drETNw%H)$gSmhpIpx-$~0=v(*jBQe9uM? zRgdFH>7@P))-o#TGz!c;%F`)(6&KkzUPI*-GtSrbXlF_TMr)l3Z)619;BJ)VyK~oQ ze^F?`&bZN15_&E7@~V382%_wj1|_)eSH=Y2rwYY0I&_AcRBrE+Zdu0##=Z@qGVOhT zlLjTyn})z0?3D5~c9R{YfP@q$cn_wfVql-1))=q3X>+rbax{nH;KMAXl`OWd-TfIz zEP&-K`t9I5W`?bXCu8~z>?>ijzC+v=4$r1nh_!XQ-b_|ECtf`Dco(Mv*~H=HK7iwTj67;xtW?7aJ(J?`{#X zh_c+Ja!N_hpSXx$^6GZ;b|tGBX##r*0*(8{(W25e7$@xC+}H?E(1%8mye{RG_6BW; z;ZZ4(ey4(aCY(X*hf++Do^SV8EdT0BmH)<2kB?;)ufLgVpQ~Em@+A{Ff`SdpZDvTB+ULF+j*5{hA@R4i!B6NY<;?f$h6 zis9}eXe%{=FJex2XdWKv%{By1=zSvN`fehhF8pLQwbtoS?c2Q;0oUku)piaT@Q?X* zl2~l*sBmyE4&1HBPLTq$xr!W$KP>GdvYDw&zf=Po%;&(mRD zpzZ0r;z9eR6(^lefxjkO9(ibShTpvo7LvnqFotvXDx$Dou!DdGHUN zVWTeHyunpq&7Nh;(eScb?o9+Ny~V-w+Pk|@ecc1&!PIF%f99EP0cg6lsNh&?B1@cO zv!IKP`o6Ym+ol8J^jxW#oLO&c5FU|T5D}l(_BBEKL2XQQi)aNXwpk)ak;Y53OgaSJ z9yx!WWGwmv&RVI!aR>&S?=*9N?QY8!PyCQFf!8n(>qSKGq%T%h4amJ}MCUc~5nT8Z>VhNOnb0k&~Uhc0RSyxyU6)dAT8BVM1B8e{$`B zSw3DM%+U*I^-`nxppNz{JI32P&2H7+DxfPSSm@=?_2+17|GKJnsmQnMXgzwT_0Df}<9#7a z8i^8jjQ3Sk`*yD;+#rUPIB3f2%kFxb?2LvP#ZVDaAx0iya#{@oJZT^5FZrn5Q8-?1 zXN!IcRbAE+H)%kh(qC%{?w!{($uQV9SHr3`v*M=dR?+*pZoDf7GqRv8DGKImD zLp(a%7(9!0hc63IQ5AmI4O<{b1!p08Nq0xqZm77VAgz_^?ix9s{itNH7vbs0iLTC{SOJVbQ;7SGQVpl;#7>k(SHlBJtqC zZLUew(Y}QP8-TrAlTOI4=Ibd@Ka0wnie_=IG{2^0iuTrWF6>oOvdQK-wbLVr*OB-; z!`hV@G#SF11WB5a%IMgV`vU9;@ghr(8W4Xh!8x%vP~kvMm#L#$r|zn$w!T2B(7_)& zNUrisi4HY{Vj*@Z$)zKBRBER?g@{44YSlbInuC+U9*VoUgJ*r!A><;*cVwqn-K6i^ zV-i{fd2dYXvqDC%!#G@1E`A4uzMt_!6&|8&Pdcf zZYSBFukV2)VH8a4NBWyF$??X9%H6&Rg=0YGQgF5@f;2iRP~Cgq-~_VqeE-x61o~QG zHpcOIebOSlq+6AJptWp`WQjyY@B)8OoT`N~8hxhLShrR6^zI|2!`avTH=zLM3^eB5 z4)PaXis}NFuxxTNe{4n!#AbXrbGnB-PM(wV_&`Rh`OJoYr)EQ^3Xaw~`mHg{oYB8S zrno?c?s}=}*nazaTyk&*+cFl6-@6)i7!*qiQLrvzVA9u{+cyhz&$`Sc&E|in%q<>I;b_!fKFJno&(yFn)UsSZnt%Y z9clc9Kq#9v<7G9=aEgTtPKPH}8UYfsu6>N^Mx@I2MDl`z3db-Co<>mc>KzXRWH_hw z-!ut>29SHOyejDfYJ)677NBxa+5;_^Y)2knRgHzvuGNpSi58vp6Au=VCcs{%7;dH0 zj=ejndg#XB3NkyXqfCkbayiX&yBduH-^kiL+XY0{fuYaGRC-NfNWJ*c@;y_cH@=d5Phz0Y@JQ)weSS3>9T!+~WygGof&fw}wpMQG4+8XD#Jct$g% zjA7!Y!3QQ%6UQu*P(d^@@(`9qZYAnrCFhHfbWGY99`NLzq11VH8)~L z#(BMS{#TamIBr3oE{>@j(-9%yOFymQK5lH4s${#R-8}0yNW}o z0uTF1PVNwf>cFHd(rRsB#t9=PM<>YYwnjN6v+E&NE?fukmF@S9=&384u?v3U8e%FkeR z-{gmGEarY$p~>xlghcZwHtnIfnE$c{aBE_ui2Tj=l{NLG<^e@WgwEphQdDm7Y0=b? z>!f3NIhyVcj>WZNRcM@uamGJL1rMxN1_k!GaWY?B%ikBGue-D;hoL&ZzFlWkzUPSP zJAC>B$Z%$lCuk=N;*`PfU@~w5a{ZE1qg>nfDH19F+kJEyDLSU%G6ch2Mco$@BrVR8 zsQaBas@@rvb#`5R+d~nZPFcrcr(W|&RyHjG?l0J#Rwcm!63>h1w8WC$-M^jr0$N0j z*M=}5HVThNF*@7O1cx3PZn-RAwu*P-;v_X5&b6s-;U_vmUfFM)2?V+BWr)YGNiDtk zU!CONRt-~yUdBnX>G*1HYj^Aw!(33{UJrECIdkNGh4kAuq2-?xbNMefwKmhu%{f8P z%%Fpss45E)Wc41hHCs|D-hXQu2}Iu4GA|VY8@lLtum}!mOFkr@$8FC)k9*lOahhdMtyor^pEfeo187Dd?Q3HHpD#{!DRC3F1+Q!rx~S&rz@pj=kj{dHcuR=X)5mh# z$5G+rTlb@#mQZ5gA9|eS&*Iqr-|&z)nIee)Ci@|!n4-1jNVpuG$2(EBoVT#lwaIwe zHhDf6dw9&GUo_5U#BF%aq^z<_P%fvS%o6+2TO0+1>ZE_!_4V(8v`hRmjJTg{Wca2w8-piS1~} zgl8z__5tV7op(;kQ^|0(=6VtC)h69aVprX1NW@-8Qd>(DO+4ri=hv*b2SC!146bMB zR(tyAGf0t_7LN)n@znx}XlGrCvK@CzTIW!!bYiGFf{-8~$<2{b(I$KbfS8vyh;`u5 z=fZMO)eQG^G6$$#Qt5{!Vb{ehs;*^Dfl9?dqdbuX?cIFfz$@v@ulc#DEsHaoo^Y@w7#IB_lI2u*|XDj z|D1?$`_8P(&$&e4)-y3Yac~wwy-f1b%VpDX?=f2$mDNbP0r6mVYsyY&?CxS@7}b<#*+tmhs(tJoa=5=YSg18e{%tWcJOYaOFrGtyqn5; z?f9+H^FD}

=$)(g!z+c{_PM5fd;?+3*P3l&(~yu*W>fmWKUcFz9V+x`k5nRv2cg zIo_rT6Nhsew3LN$sCPC@SJfg7>9|L${BCr=$)1!lRif}akRQuMOW)(m!Gnq>|0N|i z)X8r}c0ThQ`6AdI5h&d=HHK|m>4ll^4=4qhqxq>yKXk2Z?L}|;E6>hqQsqqj2_tb$ zJo({llFpv;h|?Qw=~ktRI&??)eXnuOJ=lRIrsYwRtQMxigbO;JIBg!knCiUI0BoK^ z2ci*^nORyDWnW~|pr_=`*Lw>aJm#*aCz&LV#5g+eN~s86@nzJ*8k+3_LQt1DXZLzq z3&LXC2Z+ut&!vzs$zkh}l)uYoEV5HaJoa$uAEH&nz5&1 zkuqUWB#Tq#O5>Fq&eosR&(U5l}P#Wp*9o zuR9kGn+%w_{7 zK#_4;i@i0^5()JJ+lOvzXiO+^MK@3uaYH`f*XQJtN}C@J<)hQG$?crcR_Q9LE;3Yu z+?wHR&V?q9#7W3Q<`u0aSsyWR7oCyH7Fub($p5E|pt;w8R^ zTjVEcZE$86*vlApB}eR;wOmI%T{ZXc7CmBpk5TU+bFMgULHJ>>)$*WIGTDtIWYb%H zL-XFlxdCKMCL02$Buz;myQISc(CY$khEtgMH~IfO-b(C zWq@Yi^za}xH;+r&5ue95D^^~P&cyJc`HDGi7F=rWleRW;ll&{leM&jH0k7fwtOCPH z*Ujzys(chCjZ>7`)8NhB^DJODI;ud67YjAk72)COz1`*h{hk)M3A6`S#l8wDKVFf~ z9ZeN0#GtU(sUR$LqbrlzsRsG1sm{0kl=SZz8FKe^lQ|zpe6sa-)AMfem4p44s@Nr7 zXAse9YLF z=mGvufWpUMS*VGM%HGi}6|N;;t?C9%}MU93C43W{6Y2j~+;%%>xGIl;L0i%yOsAfd~uPwP2P z@qNxll2wt@){`tCo>U)Q$WY?I9+=+$&I+{*qiRV+lTv-B&z{;Ybcd_>>CNlOfAj%i zQHx0ipAxTvEoo6Aw% z{OrIbq&`Y!oj?;k6NcuI)&@UlyNfD#9l%7?aZg;n4Uj~x zmKSIQ6t$#Ub!%&iY19A}$5W4mz`WKNW46kaNMv)1AIXCPtbjj$vQ-5$POH?zm`aX~{y0rKtSH;i^m|sNt(;!df`Y|~e9W0QF)i4TaFSe@ z`4WdvYYFxbPPe!;Gk#*DY*}0NmW<>*`7w`5B1}(U6i+-|+pwE9UdY~Xl{hEUG%1|e z74l#Y9Ky$>;CV56H^nmsbULl7SEGJ!%Z?bgT4#Oy6#ByZM4etu<|3fhmY__1zJhB> zlx|#emY9+(zt~re(mvFUmX@_ znKYYSeYvK>nC@4;j?PaF14cF50r-uFp1H93JT~=3%aKA~mAjotvCtC^S)g?fI_yn6 zkVulwFXKn+TM2MCsaWE#WtbS6oH}fek0AU*Wkumbk4T0}?TD6|#K^d5tG|QoE0lb^ zU!tYtQY+hViz;Q$A1X*Q9vKeSy%b3*+B*4Up0TggSR>oCI z#=5Kuu_S>$$LCpd>c5LqeAvVup1xm#L^&4_iTgW@p3D0j7_Z#TA+s?6srPHLn|Jxo zL#ytOlOF+HZx)_|iQki(rneSi>HXZYsGgbSypTCPBW87^){{N^PB%BkHabRq^t?}8 z-S;zG{_^N;z1ji8Q^_mB8+ZdePo58Ne|8UFFxpAfw(mii9LDLHllct94+VR>y?7&0 zNch6*+3gv7Vk5ZTE(zai3po@=FQEI3rCl~{hnEaDT^zR9@%25>jNKsSPc~IJ5IqEC zT{V3agLSwE8hCGgfN>z6vAE6&*KM*$j-M*m*v_X|xUFGdA71U9GPn0u!B;|#`b+mG zHD){#xQ>b(YVSG2*fpp1+w8T7^9NT)TAx_rw_;AM(zW zZe(z%HjMfg5+~9|W^$6OtLaMl#&w_dC=Mmk zgO*gX^I=hzeK&SYe8}InYCDJKhM`kuE%Q;DtjpNtY`Z<33fwj%F$9WG$>=5))XOjA zE;iHyG1%QRL9qI;x7Y!&=dMx~Nl6NTm~#KzdZ^0@g6#cD zl!@{BtIcIKK!0$Z+n^FQ^*Fvpd+v&x zWn|>2MnkVqvo6m!PBzUk*|;`dQ#KPU^%5M!he+JZ!yJ7vOew-u)$=45efm-1IG6}3 zsdYVW&(vuCj^8XX&z>e#datMyOU#FkCz4kRevIgyQ`afy2WZ^3-%kwqd7XQYZfmK2(|Irr&N&oai{?xI zW#>pm6He3DJ<-?50z)~^usO3|E=mr6`G;e3mu9VqKciK)a5pNi*zm{@xl($|@-m&E znK$VVesNej=Uj&*Ati3-J7-<5mA?&)JSu`=D>B`cj`uibbv10^X>hpl zUD(q&v;8p+>>+SyaGb^w8ev@*y4j;;nfENxP8uTllj(&`(8m? z1$@7OMYf)YPjXOb(-48<%~ zS{~9m0L!X4X)}YaG~K*;wxQI4KT_U7qjC)i25tb4*HC>y0abAXDWMRO7TjO%V&NIV3_^*LZaaze^I(O1P8d^*k@a2%eNn`I?%%=Mp5vD()-Py2Fu^ zD!g^LoUJpo3p?cccPvdj?z&eeR*X<|;Lt3koqXqLl|Ey&ec^Qwlrfl&H=$p|FnC%E z=U9-_437RP&^XDRFyhccZe8-LQ~F?!-0s_SHBnU^URqw(@UK`CkoYM#lsO``=Tz80 zF@Zo);F?oo<1Q}3w)Ls;{YBVvQWgPdHAVA6^E2^FP9S88B|8y>L2syp zVk)bpqWO)~@_icPE$Bl_!@LyKpj1z{jbUJ*?mr)QQAJo+gwR4aIR6uX&^V= zCwJ8=dxbAB*fs7>PscQm{&D^4^-4o^{L{}$BNe%_Dd*Dia7G92w zd`hYNiEF$!4<;Ti3Z-obg2E`}lR2L|u9~#y{w@vziAmWAM?wv#n`5a9<-3@88y~a= zFnnqOM*a}H##*4;j!!o<47)N2mK)Q;!=kw;lc-}>@(V$N9MIqUH1T0PS|)&qNm761 ze`*0j(Fvj`K#ZBJZC0#x$jT>NpSZ+M%ORI{wx=6MNRm%*I7FXklMLBPAx&EP99qWAB_;z$Cg{Np zY*1W$EZ`P;`@gGB{nVQ2DS5^wnqtP-LqiCp05w@AFlQ4z-i>pI^X*s`w9HCjn1nW+ z{C{M9WmH^U(dudId$sR-L-3PXEr&~+EbfPSgY1Fa#6<5_VQIC1>;h;XMxeDC8@YSpiS{=Z4;^F z%ipv+kLoJ%zvML&aL*t!ndEaM*I5qQ z-JjO5wi!83O-l^4tpvihc=nf?wCwN47sE-2a`T=R$ePXB7r2^Z6~Ylp=LI=tid2f( zGv&82u$-38kN@PP*G)UgN7JbsclONBS*X9-I<^d`D2)H-8HGaHF6)|td4{p{zR7-!y(RvYvCuo39F7e)xZ~sBqs(5MzkON>GdwTr zI7eA=dzi#6(itjGt`^b#33Y}E+14tNl5Fpmkq#>zNh4Xnbd>VSs zGR-u%>;nvw(&_42_3DRoH>&KM?K_fQ6M@Ai=hG4 zKbR)t$ZoU_n>KON1npzR#I*5BP11UXtTb`>t)sEgfNd2gn)AG}a%0j=I0VD443GF+ zf1UY5sCj1W8Zv+op9Ox2$~2^6lcqUkZ_*cE0#fx8D&}NVIYFscpcD|(uwE=p5~XuT z%V-|c)nmNPnCplkO^JSKA}XQP&vRvH9CEQif|95}VOY=+Vbd49qyX`Oi3Y#g^0(T? zb2H!}psl+qm5%Ftfz#(5fl;;~$6Aj`r(Hje?TAvEl{W@>Hzo;NR`|+s zY2WnLbB88{w65lvXKtXL@xc$7)XflN0)2MlVb^IF5j@08?`!O8-#^dQ&0RNil_UD* zpqsFg1$-847%s)*C7(OXdkt9>qh~wHz{r7@F=qYrrl%$s$^kO0wcpTm3@%~Zm%q?> zREn?M*QDhJJ_tN5`@i!NawQ_j4thZ#1k-k^g~RgwG@J*+w7brVzPcVn0VV|6fC1RM zLUG%Zmpz*b0}R3j!@<4K5tp=A@Yc!Q%V8?|DgAq+7{8sa1X^C28QG*6Q&6}S$8xtQ zw#W=7#Iy9L1pjvNyM}z5ecPw++uyzAS0-UgO8~5jgf3IA{c$quFrxlBOyDOl5rsh&+ zZW@{~uZ1sN8O3w3!@a{mnuU?yIX}rM8$wU%m@$#*D3l2s&MD->4gBe>ENmD;r)0}` z^>~{>&k@Sc_$Z3{8GTd!fS59>Fh#zEhbJGkN;^DGEhocCZn)kHI#7>mx(?6k2HJul z5p(4VbiH%@X+ki;FXFTVz3E(e_H7z#trnq^YfTk5`Pj@tXUZ3E5Y<2Vj~pKjQp3zG z#G=}Oi!kPo)N)ROgPDrh;?RAWJK{+gNwo;v$$GiS{G~$SR;^h>9S(`kC1yHPf$>2o~?w56!r-;9KL)-vz7bJDU)AN zmm!(EaX%;PY>s!Zi;ZPT<7tA(HpR?BZfv8IrP?CUgH?uDA1o*CN_d@PJ65Kez%d^C#qJojeR%;>r zDaM2{S&$vma0ZH$Ya&1-&=A|jpRB1*6S+U+DIaP0hih~*D8sCqE25q2iRP})Alug% ziEjiuc~n3h-gbmF(&M?Wm=}{mtvM>TFQMx`Mk{S_gux#**SU&1->zf0%WwE`y=CTc zGm@A_0_LMVZ>ok3X*sU(wy_R&ngAL+p}@$5Y6hp#e3020l|*~``!iOiQ>W6`tDVy? zAHK?3n}y#-eGd;N`);15ShFd}OS@ETzSGP1b90e)2QehvQfoJ${|}JllUL8*w}9@WRgTCg3#A9tS(?h4 zUA{>x%upAr{SO0lC4S{JRvVxV&c1}$9yi%kLX%-4Z=IDPB#GBiq_h#&W$PZslbp&Y z5Bn$wU*nLo2Q@BG2G`*no}~)q;NVHYp>n&A3{MYII!cm&AOiW zm1yYaL907Cq@~ymnD2Oq1@0H*I~SAy13v@yd9BK>dYPurq(gS*v z&5TVa+1ej_^x3zbj_6;ETLQl-am3gdi3X(8cr@&cD(jB zKkYGR>+~V5`;F;8@rJ!ug*OYxNyF{go3(K61K6iVrimAKaN&}C`QT9&4K-PMZy*j_ z`w7bj?e2-qg3hR7;=bb|$QM#9?SA6&M&0E8gZLqTk0v8RC2{--bUj(6DqExoAl%hN z^_=G;oMkS`(UHeZ&Zunm?N*QEsFx|>( zf?@{bQTbcc1nryTp`S!r zN>F6@?q?qtjZd}PB3r@5DrpszH1mNPuyN#)C2A~wKW9;778(_Nc;-MoevUt$8IH)C zwE3g!Q~lR&VWnKS6nas=YW*ic6I0J30CpuDf=KrwO7eEp+gjnh{7ByRligW2j0(KPC<2;Nhp~vVoReo*TurlnLHj8T2sizL7X*W zhxQbZexJcKp)$7iy&j$wc_(@7(4)!XNyT(&O(F?v3MOo?7_LW`)M>~%@8jDZJc}@@ z9dit2s4-Y*Jw(3WzMj~z;hmWjCR4ATH#Mpq4f(ya}k-G)RVcHmV@yQd&I147|X%oXjc9?EP#QqkfSlNaE0>AQT}Y8&nSJp zeUv3*|5vUmgvaVe18ud)Mv{Isx8N%+#d=78%A!4&;FY7_bZnuYI>Oy&#DknZrK6U4 z>Tj&Q6AoG8@01b^Ss}kc_*3rL%B^eiEW4p}U-!&PcVO2C@0J@L6A$*6FDmerV4tZ{y0e9|Wv zEDV%Kl^~xl!>2Nr`ZBV=71L85dR>x zTKK(Jd+b%GLy?31z_r5xq7RlEz9*QB0z_o_v)0}a>!VA1_s%agegOijtoZS)erK>< zjdz#DUWr{j7%{s5=|VJL{_Rk82$;>)6ahn$y0b4LRiWIkcziOBEqOoMw5 zdIy4oKAzU8SKF#BtlYOfC`Tvn>-}vh;-kLkNGe!FRK9#<5xWmtkAID_Y@VI&SMY9PJRKenNPXMErPF?JZaWo?;D zuO?8h^9AcfO*ksXPhcXAXz~#hEqQgDx%J4L2#fE6qGmAMmo{7zvW`VZ^5f(xe@_2~ zb~Q@!O1J#rP^cLVE-LoaSZ1VsmIuNv^-Ak_hZ{Uz>JK$vs=l#3iEy;CjuuAL=>2E1 zoF(cw#cFZF@?w0vCbnxr!uR@N&=UW{{EE*hh`pE5FDHl%$J-b@ ze|06UQ<@Dx3j&x!bf>y&f(90N>{y5>PcQO!ZWY{jVE9;66VFO}GV7`*Dleko!HzVb zcLo=fk_2C3wm-St#Bg6I>7n!7h3xlriof`obdW-zfQLqTt#l?iFoWcYD+~JHCryl$ zOkcA6p0=OC{>2$G=BsI$@8)?!B~fK?gg8eXg=?FVukuVBw09Eh>6rOdq&WB1OwTa6 zS7#JWd%$J+2mfn@PQ&XV(G3f_?HYWqSpDHtyzp({@^CAgoQ}g}CJXxAtpYBBOvl5v zD7)}(vi5Mgxyr3JihRS%gaoaA3XH&u(Rl3lWur(L$K%Ybk>MoRjPZ7#3D+~ySaMXVO`vbxJ zM3TL6<(KD&aL#9khou(hb3`N@^LDr&1glJ3PDL&ag2tb;>8MUKMBvX-&RX~bEH4DU z-tQdqOV;a#%a?0Z6B4KDZ(iB@sz;mZJ=yE@10G*?#73^bw;^`Ql$&GP6iPBIGqF2G z`cH^tmO9-fjER&p(V|>TjuZP-+$&8b#0P~`TJ{o99HDh}uyCSmCBl1g<-wO;2pW4*L>ZnW!jhMI3r55|F`eSe7n`xs7ArqXf|0{eL#g^ z(i~hB^F91g$2sf$H>AlX9G$zyYfEby)E~w4}RCM9G&2 zTPThqO)3V+&}|$dP~2dDSm=@1x${NewB_|=!5b&I&x?pr7*N*vl9)mvCu8(`@O{jP3nq_EQT+teg6 zzbCiL1HUnp3HQUdy_1gX(M3opddZNXr$Z$FdNkWH^X-+Z+Rux5hjF7<=KYoxT)ghy zIpKCs<)trS_4XS1GX35dhS%#uDe&nV*1vXS0O8C)V}^JlWiR=gM_lZZdbjn%f5+G*>B;EReF4SC_eEfhv|1#Jh)QN}1$EoPTmaee{{z!uNnNJ%L}Qu_`7g)`TvI zDePJjMfr?Zq8u2z@cwF+Hv!_-ecIu_3rTw((b*usESK=ToS3Vmc@}*8B=qQhtFOW~ zvky|=!O1epzF|D}3UuZm$SpU#zECSV;|E)K>>snnn9frcYiSJTQkN%r29%aKQcaG` z9bxC%?V228B^(4)&5hUeYi^K3S_s5G5io4990zl5-p=febU~ECN4$5~y2Z)@ZbWG* zc)9r%ZGqjzfLj#FPc6Kb4leS3TI!@KIGn=9hNH-JuDV&`pfDZhSN-T&AEl`V-wD^<}M@v5J_DW*(c$JM5URXejdzz zzsiu{5DCx`4l^(?3jRgmIx@#WAgPTFAmpnHt-M>t}T<*(n&)G5>mW z1=J=LnGe;B&@=W=t%h@zHGszoT&-!ByS|)=V&oc$bjVZd75fYnAB|~ySXh0tAsT>d zxGfqMNi0>b9H{vlZp{s;<#0YD3PVZ8a-q3LU>sT&@|fzU*7=#0&z7*&-;tg)P#!|b zW;83!tOYs^MV_5nR+Y`0nA6I*_e=US5biT-|4^Galb^0+$vruu!adrP(1#6G)f~x} zX)a``F=IVGx_!nN_0%#WY*0x_G^hhRP=Asi4ARS#XP&U0_2Z(F3G)~glRdM_$5Wbh z=d-lH71Fbmajh9`>oz>HU%`L|8eeJhB>1%KM&}#vbdRo`8 z`fayj1>iU#^BQ?JKgMHL++UW2K_)3| z%x)f$_W#D%-y}&|mIiFdGf$J^oS7HvY?&N=tBBaVqmC?Uv9LXq<(KSz47a+z zYOp}+*L}T34*TWSKmifqt6Yc&Hbq6SCe*FD2Id-lDGb6n>LR4vv?=D1T80Ift`ex@ zr;hW3cD`$xjV!qCxP&GSuZ*kQUx`|gFtZd2nguKV9)5M5w?h1Su*4BVBt09WNO zP(4oKTo2f%eHdjk9cJp{&J|{!(C#dajfA2{wDB&n3Wd^b8>kPWmS>VNvoVeN&1%@K z2z7f$1DTKbok5>H@lDD^+7D1WV4nQ7H#B`0B&mysB5+s?fq4%l=!skFl*;Q#i73-s z;2;~Zn;WqlYu`hZ@<$1n$?6q?YJ`{I4>I~$9|?N*1LdCMNIvc{r$6pOsy19&pGUNN zV)sDm2X#YPuXS(oLKOR4vjd`gKT{O7A_{8dStew^2W?EwtinB`FY81(1rgMKXI$>v z-M(em<-b(2AbIjlg$R5K6Z5j2(x7XTyPj4s9@+53Hz_+G^R?;JH&wueRxnaLVX&&2 zXyEZ})%|=^{o>10yZiQu`o?Q+bWwhBtFfNY_qSlQq3%}B_?t{)v{fMjD4vXa8BI!RN}()nO*m^kT~5UoV>auy-L}os>nG&6 zc!U%a5|z_RKXoDs=MtT}B~*TjoZ*afSG#UG!z08L(VCS{@1@bug1CLIqXuN}kU5&@ zId$F;uFwjJvY&d!e`;8NS}H=?qEp{B{I)wyjDSW+I3!_NY*q+83u9`dlfWe~%On%) zGKlO9ks^A4OOhSwvmQICOsu@0S@|Zg$u-;ntph_z#aLw`@>_NqLWa|oa$7v$2E#-q zY-uP4w|)zqB&J|BjDsWb3V{P`e3x3581qQuUUEOWp{RpJs-M&7_pc?vPvMjA^NNHD zjWWl9=uBx_=DCZ}7Q(VIkR%ljYPCmx@S?uQ7Yv*(K}S@!9HM8~>w%YRUy52N)gVD!1prK#wl zqtn!S8HQo2b~J^PbZOx6NymCyXT~4IZ<oY;lls5Z*_K}brow) zJ!6nftNu3878E^fx#Luv(LMEe7iv}*J~Q%Jn$@vun4!}Jr_mF?>0HlS3?oM0t#yq6 zDUM-^y~~*gG75)=y#`@iRaT0Fl3MO{{y<2d({*hvsRqE5)vd=}C-tVUjp|{Ra(IQ< zy#@aF9Z0v7b!{%Vvh@TNND_#2IOjh|HcO+?S0m<*OW->6h)|wGUZ@rkE+lI68WDjRx?`~n>lhdDE%X* zSKOZ;Y;5Ite!mG3iIe3(r)15HmZ*P$`@=>D8Q-6^3nb40wPd6h%JX50t~rqbt+r%S zi09xc_{wP0c=gG!|Jt?-gU3;G`maNDZFFK9NkdTk$kDdx*-O~aS~B6^59CH>awFrU zAV}>)nb%8<`afbYcnOR>f~0){bTU2{kRd#0QyX7lJf8>sc7LCN1~t;)R0yqCBMJ?)8}e0v4t`?l|sATxknJv@Lop{NlyMVj(&w_#T0iAf z@c#%i{q*mM=1|3*`-WZsR;GTP)mVfuzhNVh*ZKt51=4Yd9gXYn(4nVre|Ao3)k8Sp z3PV!X?U4vMy6t!;gw=-sAj{QW28F)==j%|9rVTclqJ^ElOpxNFFjvr%%_4;#!H~T%sW5n$AZu$syWRMV9w8BqOzoSJ6s?u=pTK}w zDb%7FvP_1li-_c97|UlPzCNfp5;$& z2b%?YBV)DBy}is>+*`BQ776<{1V4nKDCySBF{1xVbEvQLxC-epnl*X8rt8;V7!S4- zr#tU^B1zvX=1gB8A&vpVYJZB~>j{Bx8C*Wy-O05q$J{CIyW7&dXuFe$oc?!10whVu z4EBl-|HFkD^8Hg4$IY-gP7P0BACy{EyvyqGQhR;W%ibTDvI$ZkiQj2#b2Y< zV|*;O9=g;g9G8;*wR6EO%?v3omEwy&+g{Q&_BZyIGob8E93&)m_Lo2mzZ*tZynxZ_ zoAvj3QIk^qHpMNbV+B`KG08g(w@KWJ6Yy;dq!&YP4zhn^dcP6^4n@8{30=1<*cbnR z{iwyWFeQE)!|_Ix0O1#_=;tfL)=oT>Hix9NiT~Fk;McjJfiuN#zf-!d7~jtQ-UPv; zH;UMAb8*d2sLZcD2~h67Yd>TRXti5^Rqdl3{SGMGR&uS*;K{By{Gw1_ZN(RcOq}C6 zE_{~s;@-g(}gDC)Pmdd}!Q^7@-n-wLLqYW3ub zVgz`fU<4ExsT5v-5U7!jJ<~S7m`jOEQKPS|l4DLlH5?M|9}G%jn_}^wZjX_?#aI*} z<-~&YI8K-FUE2$-f~(^Dv69w5F|R+i^#YdUaS}ibJtKG-=ViE+^Ro#B0D!hAtCK`q z-kTpP7m0dwe2IO|{&n*ZY7fsd5P^85$!*YSXy;bN^mJ27XrrYSl3p^;(_mmN!YBj530j6o?D2JX3K|Z?X>NVBvL%iPCPDYGVo6xJXuI=f$2Npj=ZG=IXyU zI5?G9isQqtb_kVhi3wsrWzs=R0{sP+5izabL$_|Fh8Mdc8>Kg|9dlW zoj~v}IzaCvApbe^4r$k2qDyH8o1d5a2Py!KuC;qFgX{HXoSNH*ZF7#4HK^#_jDdZ5|zS7eM2IjFB6 zk~a|_=9~(8#1RSS70&X#C*mvTo;|%1iK~2uR^O*mZ+UvdRa?8Dg&3R-XM~BlLZLon z3cXRC4gX!eLWPEUzJiB(?bFwyVU_g}sT-Whm&X*pMMAFIe4zSw(8vD*!M%{Bfc85`6aWqwW(p==$^+4G)&)xix2YC_(=a zAUyLc0*6njbdKD)V_g?I_xwIE1$lc@ioY1Z?Zo0^Hq zZX)--7PVjX8-V>iVx&9x#PR^~& zHm%;#2Ns)v`#HlBSPN)tWD{7GlvJS?f%@wV@QkcdDb30#{pwC%`m!RTBP1wM4wBT^ zQEK~|z%QpJH=o$l^mZ$EY)|EJ-k;y$>F|<0uK*nCa>4Kg7R89g-d`<*Asclb@I39@ zNNJn-I=^Rvj5enb_SFoofE{ zYv(v+{qHwgpyYg#nPBTuf3&vXUl!pcvA5$!Rh#lctAsRJb+j?iJ>t7%CtyET+rn+F z8z%}nXJ)V7RSby(MMGIVHKB)5o^xq=EQB=Y7j+~4EQ{eeU`!mW?e#Q)UvtoYae1u~^{{@g^7VA{5udttP*qj%$qPca=@3r-A+|J8>c=g= zs)#(V@XiEYkm~*~vBfkO(A;IaeMN=IMap=|?`el?3c?_n^&GHfY88sY6z9h_Tll4a z%J_dRh#|0@YO~q*)l-5Et$*ygnQ(WLld$j9`%;h1XRFX|`gM5LG3tTOI8I}HvCBfl zk@4T^-nF>r&x!d>?{}a59^ZoDUHu|2glxwz)%n>w?>`IG#|ojln!01)B?XyYklwF* zMn2=4b6;o09At0Qy&ONS_rk5lT<^>>8F}pSznuy)pr8G_;O!%8J%RBh^7@kXDS*34 z9NUx++U*PD0rs8(bIhrCS@tX3G{lmTILQD6XqwR)oH#eT)#n#B?NM%)`1hGV)K!Fr zhQ?19vR3N@y9%PyhS#Sg{=E|r(q=<@QE2wRFI_OI5ig|luU*;})QTlM=x{5=ceKA; zZ!iWPY2Tg&S1&>`tBCt_^S@=M8OC(=dli10GM?w(Eosj^^eIkD?Dc@_v+^$fqHWmx z>iGvcRvPVik2!eJ?wCJ>R!t@Li4j}9W?LKz&tpngXx#qXaGn3i_A-%=?TBqI^RF_k zFHowRdFOxX_@;xiEy#FT+G|mt(0cJ>g5Ue+V(1ZIKj`(9v|?6oc4E~F*n5JZ@AYJR z?+d=W&G_GwZ5kXKEBbGr6yBGQH1%#jRC5p%(e>NIOi;a@W#d2X^+RL}+o8TC&tDEr zR4YE5=$mOs>HT^5RxbeZ2}=PQWxl!$C|fnnD?T(<-z>?qd8qgS3;uF{je%HVH-g>I zL50ZoNNs!;LW}ZVlm8T1!s0Q$jHcSw?j~M%Pi%YJ$R39+Q$I!viJk*lpj2C*Fw^Nv zp0-`-z9a;fZ3o>huUJ}I5Bl~>a>JGUU)ZVLF#dz(7xezw1F08+UYAjng6Rnn`0?Tl zOO%wG+n!@*J!mU7m&x;;fz`VfCZe6xD;{J4=dkw~Baz}pIu} z9e1NWb=W#%Ilzzm_C=3TFRl~p-l7@#v70qB3uL3%M9b|Ntgo_unBI#MQ@@&`vo=Ur zgduw2rA^6_O`1Q`)U&*B!SMFKIt2K=_yT_U!5;|O;n~yEIo^g;tgDKxizVTzoUJN} z5uF0gbUJ1r2`JnLG4;XMNlS>}OVK3B@=4M4x=sE~z5EIx*Ck~P`PkI^{=8eBAb~B8 zWvinp#7s(XP|jvmb2NFI{qOOWhz`yP&+<|TGu(et=5W?w&f9!`!^9g7G#fZe==+`Q zE6w@N%j8DEmDx7PQb8}(7<6Qtf0eILOWCDew&uNH_wsiP%wgE|>ix_aU9qYzqbo-_ zz%KZw^&a5imvZ1Vo$B}fo@4Nj&Pa7RCI2AE>B168@4 zgkr;v+Gl?3XyS9d7#f9JL!V6W9&=*FCk$NCbxxAQfMQ!vz)uPmPh+9vsV#Q2I+Axd z4|QJ1i>O;C#qK*lwaGGklP`?c!d`7)vZL;xO@ZeXKEYO_h_j{pP5^e(_9}WngKNXA z(`*WNRYDzz;V_+P*^5DMFd0yPx)^c`c+wLad(h#^en`zdS@;D6#N0= z*zVf@`8V&cm%7&b36o3)P82bFtr82i<;E8i9=8DJF5>)shgTku(*mF)bZE#$d1aAE zDqX8Nfc+g+cgh%C|P;KIYQ_y)N1bUGvotj#(@AShvSh%o>U;dze?2)V>oC z(dqmEa{v3*r9b$NDlMXLFFaECsWx}~)tK$m$$Z;-aKFpex|DrN8r=Bnb&tIPK3X0Q z7?-_qo}HPJlj&`LIkkq+&4o6CJmNVyGz_%`2ASYUtJ8xN)QY=2AVIx7r~*UE^4Axh zkeKh#g7M(W97Rzx&IG@6oB+Ixr&Bu|I~eMH3)z_6#+wGAXM#!D;ouux{vL&*jhBJH zj|7C74$i-FUmTDHlz717TZDyXuf6TGZLXodE_hy6Gh>*i7u&MMFbj#3wob6~1l}XP zu^X2C^S?69MxExcCpzaXBf&L(w?x!h&%ejtPFc3_qX`5&v%12WBSNlp{`pzXHs3Q; zcuu+2`0y|XZ|_9ogJK(N?%(-mm_n@(^sG0mM1JNVIq%}JDsyuP=!*6oPj*EAQ*V$o zv5;?N^l`CYn9s={*d`z6mr*o%S6FH;uEU(lo}Q$8NSDlpa9`7Ip;y5CF-HKS;_zO>9t+;VQh*qQG_wupwoZV~v!*k5e zZN@BoSZL6#F5hISHBL**t7cXyTk%-Yovt-Oy9jXB8%M!$fB$qc!-~mg5Hi-AO?_W3 zoubeMC)(^&f4=zia5KD0;I$qnc~pL;OFJphy#_|Ud1sn@&`Du&Ag%;*v)u%T1lQ!p z=MNSUB!r_mH#i&$t)h6vKH;s9~Yt z@bc3Fgx8@rdF5vZxb~PZfL?S?*vO{~dkN(K{qgc{qD~)Y%5C2TsW#4O9nz=?tQPp| z)8P9n>bdH6vg+myvUD)oe=w4{Ipe1|c<}Ph(rUTK{-q$paM#b97hjrHz~tQl|D>jj zI}(fjP1il{asFNJ13Gj#PwM1BZCn>ju$T7JW+!A4>7x6|7x+spfC#Om17gA_BoInb5sQngNXwA&>M(oVQrXmi`}qMx0gA0~dN zYOSVct2bk<2J~TosVdnVK4b6|1xR4Zkx*eZ>aZk7S|M1)lP^YyqkR`K+8~znr?|cO z;h(Ua-S|`H#|p1k_RZ`0>pJLS1628|3$dKx08+D)pjNPuZE85PH+UDvCilOmxE2Y# zJ@^oSy_>Edekt_wW%7a9-sV8E zJ_KH3s&BmC-KzOX6FE~Y*0#(y^Mt&X<1)@u^W~GF+1ea;)nc0#Ydy>^UkdQUs$gW+ zg6UsQh&%$RELn(c`n70Bb$8n$&#UzKX9aDl`KE~L87?qBCjcc*woQVaa07r*?Rpt$zI8If=RyUN!q_1;jx1RcO zr-{ekIOgliwPIastFL$77UeyeCpX=0H(3b>9ld5a>|5|W>m~J~8B1BtO8bNkDe6NH zYu{3+Eyr$?KuA~Hc<^k0(ywL9~Y_Ux8(DUK|>A5rhV z@L}x-wRp+T`YeZ?sqw80RviA>6)DYR)^ifkb33BZhtIW^w=uVMFA{KeXnsy9ju|arK1XCDfg9rN3)l#=AD5FMjc$Ne0j| zBYQE!|1Kx z?zXe;cOFY4S4^LkHd{JYZlEchvPAbs#p9g*NjeCEc5BLDw~tVb{8O%|O#GAhz(b-s9u*>A-Js@BI2IMXBHEE(k8#p1Kr&NJY(o=8vG*cUKzvPA3MGr4_x z7HBDgjyi1zbsYA6prKtfY!$**4SzYdNMvC0b2^R&e* ze((wgfh|iuP+-s?n@qF?RJR2Pssq^a-$%QCwQfj*;l!lk^R$L%Y%j+qbb+GW(~<=f z_tg=R_#bqdr1*Wjm^3X8Z&;QE=f}>}sfaOsRj$(up*zbC7P{{kam`5Kc}_vtK0P1A zNt*I0O_H!h#?dQrtEywWFmCaSqCp>6;2xyy=H(a&0kip_9nAkQ(kyf&a+A|lfwygU ziL?|NZBDlYOXr{Fv~qSETytOz%R{$SI9JdQ-@d4o><{3ze*U30htI}-g?2lmZ9t9YIBR}`UWmBUGw6P+NIo#W9Oy&S zbcDUyQW{SV#&9buZJHY#k-!7D^3_Je4#g$a+A17^$c>14n=iV3$#X(>izk%=cC;7K{ zH?pfGkbNOtNKG-H7x`<%49NsBpgWnrr^RfiufAzdf3j)2Sykbc_{ibj z-IRK6LX{rtOHKoN?*tvEUoMu+nB|{@cB75RRXjM=)3!&ZXT}bQKEqd zyzR^;y0Qw!0+SO$)tzqf)E{~fgCSv8v(6XK55h9Ga%Js$@^=$-p40;fFEe7@%D_jP zzXQ``=!}k< zM(?VW6@gubakgNfqhC2p1lhu;TMI0Jli!0O6MsWhn^Z%IZqcRU%Ze4}OB?odU}1zLM!v$`dsFOg&gboay+k{N@S zW#3bv_nvFzqdoja0u%j;&>8h!ynnbO|3o~+&LNgQoBS|PG2cv@sO*2{;DyzgM6B3V z4Qq^SKEjxH>)|iD3_TvBRrX2%X)y&0khkP_tFv*ys#EYrufFgCh-HPTuUPT zt)YQgUe9qrh-oyRHv& zr3Bgz4uRoZ4`ByCrMRz+uvFb4^h%$=VE5tLPXy%nYAD#P7;8LC3h3RLURPoS@jal5 zT~NPnd!ru25!_9yo=E*7WZ-6{z;NLxuitm>k*a97UaZ56k5HoHb6UL8g;%V#J#j3S z4$lp7g&(IQ`x&3W!L^PlG1=x`Pi13?^|H3d#^`wX@?SHNwexg;)NZoNxZWN z<&1kvONVj4<8A)&X(^9H&@VHXCYg{pYt&F!GN{!(a%E=KnHW78>m%(tn@+WOGaAVc zk{V1CWd=UjCDf4t-aXqfS+iAg{wwPae^u=i(wc0cBWE6Zo?^pzm<;}S(+&-Re}*JgQC3R_~$-$=Qa9+*bdSRlKQ-yrJZ zkGeo4+pfB#T#)A7lm9l40`#*(*jrSDYL1HJg84mzP0Dy{wGO&){%Pk${}7>dn&r26KVT-Cf=PiF+8x&@3j)uy#duFQP zNf%;cC~fwBA#zqqkryBm4El2MiLzu5YN1wKl<<)+I!vtDU;pg(B3}MCz7ihJD&V7#yMWh~9^3 znQ$}2N2>ej$obtOCe^Mo?o{}zZqcJL;buDxd_w_X|5n7mzuw*D=gp_bBFY~mu5(dL zPhIAP!LVoup~(~m;#rdN&+%EMKglU8sqWmpjDOb$LI1QjdhdKb)kFktXsR9 z8g#bx&~I}s#89+eq?1yAEXiv(FrXn7NhOFcLHb-9SU^-?cj-_|Dri@b0ML#K1P?iL z29tfRO^8s~Ey~ysMqEM-is$hG*2CQdsAb7>7HV*)62X} z_0)|pA-qui-^CNJ(6IC@sn=y=KS|Kl%90SY_r-AQRr$qIVw@fO<*fb9l>R+6*2d`U z`^$Rb!K1)?u^fN)b>Pt`#f{Rh#5bJmy);4L*`5Sj>&~4^-mXtjpVs$Z5D%t?H1#|* z^oY4}KC`lgWrBg7Jf>wbQ1ka@U2hyn0te4m9Tz!ZO37127XSyP=oq~;+i6JRAyJP&>AyX*YhwSr@5^MaDTa?X?toER(gAS77$Ys4q z(n{iT)MW?9eNFSz#_!7mayH9KGV69X*Xul3UmMUL^8`D(zU?E?o_jJ-Y8yplAjE6_ z$g+T|zP(<_U|J5>EF07+{_ERQzeegZE21z)y581I7i(TA3c7WPvGU|Lf7m2G-{0E` zDJq-dAlOz6@?DMqZ3Z4(-aC?E$a{ha_m4SRQJ})>7*|<1*r!{_dvDsEL(Q4{^-_{^ z7i@ZJ>SJ`p!&tJ^W& z%x-J_@a>&+R>d%H=%DNrRH=*AdChZr9TN+PPPJEf1zffOvgnnTtO_|yk2l$A;sMcL zo&94SIxd2IWg;#TM;)_LyM90bfwP8i6wFYN+pl{yz6~B>W#h7H2<*_8y~(da^A8?S zR8z|o9v2y4$dfbw)BcAsLKxo3g(l*o)-}Ro(cTIrlMc+3iuV8F>n)?=+O~C32o^j6 z5?m631$X!0?(XjH9xMcRE!;J@yIbMzE`>W3aw}`E^Ul8Swf26|fPzsl=N!HF&jx@} z37@3~mSL-(ze+6q`j zl(JdpwRHb>F?%8;cwBO}WYI*d6uEpE5OZ(j64_9YZN?MVyvSE}MXLRh5aBYi()6RF zVNg-uR!IZ)yk9qjPS@nhl&1HG1+Hd$7_UsE@*Za6X!a=Xa3S##@-~s{M>u6u(x(U4 z&&9;Q<#|j^O#5wqwVmY4A>kSqi9bBaURY;6Yid>%Zlk-*rX4e?Suvg2kCsK#Ooj|) z37zDBW#H@zW3TF?$aXQw5*? zZD+J5uToj+WsAby*^f7bCn+F=!n*A&W+Kb_IgY9~U>}m8Psz;w5`ntHaow}wxUU#z zWez|SuHdP@UG%c|iBS$u*Cnu99$pp(J~?E*@KFF;-;0vX&e0P1T`?qSzFeu)TniGc zxq6G^-0vO6$QIWk-IAl4G?J0khKZ&i!oCO6(qo`b4AF}M9k*HW>Fi?cOYm+*SxpKQ zOxKBx4)tU&UK-m*m7)s`Z9_J}MjTH-`|W1tQKda#uu%KM867DcY)J>CU{sxyx#LpO@p% zNfxb~iDY6XOg2yfB}mYIXY%56*n$sE$FAX)y^g)k_l&-6AG`OX zNlI3NoSipmvS+08H5|GkO;j59UB?=!!Q$-DtM|K(qxW9b02c-r^E(!LsrZt0gM{;2 z8H9E_irbv)FVAWx&Tl-yuvl8jPE*m&V+anJAOjjC#c|)`M%p*Y3q$rhtE+=~Nt3OY z3$QG(!~W-4EQx|dq`{lRYjh~h?0T&3$aNw>oa1htmAgpq*z~Y8%i_DdopPQo`W6*^ zWoGi@Ynkj%i-A^e8!kZiHw0>)mz!_*!LcN|V(fQV7O$U1WidQfJ|GQn71%_86*C*e zoTn_#xx9Wd`_Q$q_ZG92D%jBor=@rMx%{fc?ufSeI>`4eoUVur;YD2RVq3#=Adduh zX(MK-SSgp-L#dpRx?{b}M%cJEp6|;pDR(~!7yh?H7iRm{ZyRqE`0FT^iE6|e<&cT` z3R2hvzqPsB?FN%~)rG#=uGBP`mAMW0nxXE)i2PgINW{Y+{TQ;+ls)kv3uICr!EbZg zoM&RVZ_(TU2uUSToqMlRz%0#y5eqKgD6TEH}1OnVPv##{PTi-eYqbD^1md6efMX`(MFeRKFY5h9Y(=uDRez%9=QHA1cYZMluO0*BgY`WXjRDIuit7T>IbW0 z3ukc>xt(I%+&35yo%eC><=pq1RVS8|G}&0N+P@n$rk3n7I@l8o&6qA#4&T$~o*zl! z8+q8Jq@_KmF%c1(&KwNAM#KDo z;itD>ZlY)D3xKJpv|QWyw2r^IclMk34Cf~%K}EPJHwIp70k7&w%3&VEQJMQinYo;m zm3#|O?Jz{Ey!0P4xMjr{-_cm8zrXtf!6*}MBQ^<7x>=Facx^P6<9<0VDHz$>3|z;d zp1UBJy>^BdvngMcxLj(!;b@`=7(y1{YLlY_i@q|5n6Y02ea8Q%(P7O z4mY+v5SqE4opx^zoQXwc?UR4pT#(=(RiLv?nV5P#O_LxRg0 zb9`<61IGPH&s2Yr{+wsgFy~Ydv@IKxx>1zmNLEw3NI{xYu_71V|Eqzg-%fV<@F_TR zCuz@(RWH5L*o)Mrb?~SSr*Fn7&I~*vpPbwyHUn#x8^+&3XX`Kjog105=1W4P%kPyY zXSM4(UZEgESxbw+fPv4{``oiqX8z*{4)+;_;42g$9sbi>#V6rHLaydRM@h%YXlF7C z>x{GOVTd>@oiU%fSe`#Y;V>n!4{7DYZ%EyP;v9_&sx(Rp0aVSS|!1ROAwv7+GDTpv~5>QxpaV}ByN-k)E# zzdiEmJ|8SRoJY@Itp^`G@)P@ntVbNQ_>8Hm{q(H;Xf;U6V*9QTkU=OJ7w`u`Yb;Eq zp$tI5RjzD9DcIgSGG#|p;E)bGwt05e4;W3VQ)FGnqZaF2{so`X?3|Rt+Ek?Ur8<)y z`!k_x=9fnTM2Yan=;-UiZa6W*zM}l4I!56Sdxh~cMb;0w7%jYn1S9O5xyr7R%H|De z5bWz#MYe<2qL%GhO;Am+?aw$nGZ5Q*{ zwu(IbroTM?sO#24r@*;}C%+<;PUf(UoLy;Qupx{1Yn$lWv_dRQGO)5CH7}Ib5#N>r z=W@{JOVZtY=M!FYnT%DK@&(0CJ>R6&rXKY|m3FuhS;(u`rw67~Nih_>eSDgjPt56l z#iV~JA~>mDjrT+l?6W#}?#Er671sg+wULqt+0rv)BHn@H!nB7S7~b`XP{cLiL$E^St=JF~dGYOau7{$-bg zrcvr#eHsTMWg*=`HgO5!jt@u#sGSyoL~5g_)4_rGlcN=UDMA)e;lY*pMnb;709Xut z2|og79{wTE_X!{C2WloY342Yu!8A+Zp~r7pO1De2J`%XIV2^a%0*voXLSS z^^}8eO_`;%S7)`G<0Lb0x&f}C!TX_TMr%kUIqkgFLXyTsAO6D3YU21xadUT+MLhdh z?Dcg9OGMZwFzQ7EO?Jehh`(BJ-)usx_HstUc5{g>BxM)fFIg#=6AXAB-jA06gJ^&7 zBMBa*B#z-Neb6|~kLKhY1|rGV2udXuM2g*wmXPMDiQ%6nViD&YWcdl-yYEpfH%yZU3K$w z&;m|_y4l2Zkvn;=CW;!nKl8UTtKO)h^&mX6m#4>mfBWk7ftSY2^$<428+%F`JQ6^y zYDQkE%p`k5?xE55=iz5Lc|;wD&8T;vae_apWSQ~V(~5q7aL>^_FGUCKqu?3$xx&_! zg-`dPPZoNmb&-4K=a#r|!z$jd%XiEd?U)!$S#&fcY*dQ$G`jOi4MLAzU4Pn#(e8xL zHtj8%d7eZ-lYOJ-?kEnLcMK9nh0Dk*RCb*|DlUf~Bzr$0qUc>&Xer07;-#1Xs2gof zM!B>=W;JhsiXSqw_I~`LX_>S@_RyNbESOhF@LtztC;VL#Cpd%K$ERwEtC9 z)sEO|MH@Ip@}q?5*zz67?V1;LEs!YM$9G|Zu{ZLM_hXKE9oz=Kn`Y&eqz)dEjkwj6 zrVVARr=kChhYKz6qT!=WBAS{Z-0Yn+pYJW3yuK{Bf~}Mx^0|pFtGmXbH_oV4erZ@M zIh{5sFnME3C|;+BtRg#t8S?VBkqNA2f}kjAPCl z*OUi2MBHID{)*(B@1Ed@wJ-EE*esT{Z)~e5ZEB-ZFx;CizOK9Pm6R4I8MR078QJjl zs0rYSWK#6wlb1X(`B_Z3Sgl4!nRb@pZvyZx3ftPdW5UR~b8~H7*Y!}|_wtdxpsVQX zM8Z9`psVW2Nwz|=iqkJSPYKW831oR&6kBlDOzrgo@!4l0Dv_Ku=#n8gBMFb~PQNUt zzEM*r>C4&PyPG`yE27%Crcc(toL#2}Q!-4<;HVbxC%5_sL$4MSK(Y8sPvUTFK}<-0 z;#E;Tg#fs>ej^X~JTS&xeVg=t0t;$k+S#qvzM-) zm~O2^I;B`Y_B>G-L&NA}nIsaA!U`(D1sSq({yu*+_s8HGe8SIR|IWffMYu_&-tRVRQ-J8?udD3~-}v5-JY zDy8}(w!ycExkQKf0mqxHNEvkY1qZj^B=2Ey-x8mtU0TLP)L$@27^pf+r$LIZnI}-t z7axCVk(I6IC#oHG5{qZyne&migRay|YTemFVf{Y51;CH9`I7_){Dz|L^8QvxKWt)z zrRAEdu$xv)*<2ArEGfMBmwX~IXe+zh+2ct;-+nE?p8NxHy7VGT7;Qddc03O-&gDzQ zM842%r|~msrLzqc{b)=X`6sE$54K%!3{WW=0 zeZYR?58?-~I*0L25*j#ST>q!Hj(ji@tHC20JO8aprh$okc)sE!lD z96j$~3A^7&cYP&Vmsv+&4vb&_#iK$dc%4f6?VQolNvFB--Qk&6iV?qis8WF2VO_N2 zMcJH{8gAX;%_c!K6CW;=Pr&|LTXd}6NUX4r%XX?cS;2P_lul$Oky7Tp-0+f=E6FWp z&Yu2sD9LMtoGU@83*3o6HF-fI zj;mx7y_iG$PX1X`{*5AJD2I{t_|&oVi_arBjYW{!+-&2Wq{%@c=HMr&Pp$mPj_sC` z??`!XB7zK*NN>3@LYc=8Tyt>iFq>Qhwh(t}oJF@T-Ef=87wQ`{U4P|s9gt;i_RnM- zUU$!%61|ji4pZq04SVW;epV`BbsUDyH4$#hu$xn&<#gC^-f33I`Wm^ZI4SC67BY7= zT;Pj4Q+C_R=u7?@?|9>8sn66^Y?iTqyhlYz+6f7m6p*Z*F@!UwxGDSi=n0a+se^k} zM|y{iunXWz$19nzClW7Zw%ESxxTP_ptM+yyf^4_&`@QZPeAwLhe?BTHZt8|*z$7T+ zF-Y33DqzDTA16VwyJxz)3MjJ;8yPzQkX8wg>Bv!Gpyf|!P7V}_!Kx8(GewGr*pgG% zdLpwMF@@Ok_r7wgcpMCD^BKJ4U^zCp85#m?V$V-*;UJ6EXa;SDL?g=de)YFf+18 z4Z>s>&dWcuX2ja3Tv)GetoArwGvox_??@%;H*UpZhaHE#p7b{b=;;_Tmnc)Y|8pSbZ$4y`g^$He$d|>WECVS+VLF6SWUZAA8#G$JV-PxF+`75 zBXEWT-w7fc+DZ4Z{tBmi^t6vKm=QR&erBzTuL@S2Z2F z0rf_l$7m04Fe+mc< zoV7BJW|V$=-Zz)#{7aP*Uw=g~bC~x)dHtU+iixA$vfumeetkwmh5<(xo($ipDr3sQqtyf3x; zTI93sd7WX9oi zEaKq}E0o;I@t8*k%;1XL37n0V{|ih1tlva`dU|?ouc^WCzr4I;t&k??Lvu+$oCE_x z-3#eg?(eQ{`2CWT#;g6R?ypYYZctu$fE%}jd2B~3Gk2Z2r}V%Ax^(TpEZ_9d*Bauq z%>DZFI%DT`8eewO641?5ALr}S+bcEDL^>~3d*P!jt55hrt+vCtUfY1%d3e>MV)Niz zN3>Cv-1iUOp`E^vo@)@g>0rWd$dCVzDFw37P=6}%&9+GJ-WEl*DWX2j8ID9?T|uUB zDBcwPiU{t28GmmXn%|RhVjP|lsJHH0`IYu^PE6s4&iH z>7)ZfwUVk@0O;G^x8E8TJ-(Epe)6^?^nL)7Y*EUW4tnOJjwbPBnn=Dxmz@PgV(Wzi zG}JUhTH3Jq(#SbT7rx9fE6{M`X6^{-pn{hz%5*AqhF`=&s7K6v$=dPlGj{WNp+L0G z&ta^s%nUF`ZVx8pWheP_=!h=2x@Zk4Gv_o4-yvtmWB@3tW%B7LAOpiUnI|r?nmp~~ z#3&cWeIDnxUX4|S$@4c%w1v+YTN5?C^hW&2KjKgd=4d4%yFFuGT4$;<)NXhTcPogO zoH;YK-RewNw;E>$l3O!im5>Cv@N+*b{X4_Q-IvnVYE367+0K~!fs?FPM{6*ukfv>g zAO{%uLXYZ2b&+t(73_cvK9l$fjYQ>Q{uip0x0s_6$dw2|pbhgWSJY80C-zwUNpj;5d{2nHB?VO@uOpy!$P9}9ltAf;2Pp=SvB#saU!%<&IgSK(6Z_ldeZd4w zziXW0(y*%RvVQg>waus-@G}Qp)v-4e7SKaAw^Nc_7PvD~Ohd?HF-OKjyw<^=W2DBp z-qE=?)^C37iuAYA{R#P%kV%aB9q()>WuKr()n-N8)po@<=FRg;iU5ye5TC!j>!JVx zIYS*5x0j(Q?O-oitx4IWbr~xtZ1lpQt6lH-;p_pJUm}PO^~W*1k|3p^*2$A&tp5wU zOK5~gQC`f*to6)-;&nfswAM`Xi1J}M1Q@!uC9p&Pha0n|8TCy~IvvoN)sjARY-xh9 zoHo`~72VoKLTbAS{FX}8gav9ikM#)W_4u%6KVi)TG^<4Ql*D}6n;%MecB(pC0|(hS zaS8BDotfBDhY~%AdjoaFQ)O*V70$WFFtZ$X+`Zl(ctQ6lJa*XrhmTau8dXw;>|8;X zz2ptJmL)3y&~-B9N>doE8%{Cfg5he0NYg){7(s7=8!lc;1Us7p?Me-yk}zf@_iyip zFv-wcD>-@Y<1Rk$;NcD0p)~JtKt7TK3yzV!%v)NKT1ID49o?HIBxwCdPm;0pe2HzW;C7W;4Q7JrtHS9HWNo4 zxmfpw<+6!g^obpr97v_H5a&W{l-bp*&!l}!QL%(wucr2T23oob7SB3vIZsMkL}KR4 zN*;s>S>5Ipt)|W9eEKJLjPi*~Pse$lTws7XU+A$c751H8@4YR${eqodZ#rGxUd;mejb#}1?_%{(Szv8W0|>S{r3 z1Cj@}Ue+u#mokKvji+s3ki<{+!0HxN155MV4n>(^S{iV3wlx3mA00-jj8$cQAw#{g z7`uWNxW^SMC9HEsmGisx<}7b~OcN091yWOf2iNJ2lLG=Ym1qY>p3kf*%b&cn)txdE zf0%XEbO#%`;z#PmV8@lYr7)s^aeIFlMS9EKwBF|uS2LDa^fiTm#^L_ry5gcI7ntu= zf5xO&Vz=OiOX8sO30nPT(f%2Y(7gqj0MzX7l1O494Z|abvK4OtIG+)l{A&r{9Z>Qg z5i{)1T+);LPhT*ib&!_gFuVZ=v`oZ$&Tzxq@CLaj%4pu+B z+TSt#)cUo=Xw45%;RXShe|zj`s)_$Y(*9@df1qkeZJhn(pC$0euy~T)WwK4?D;H?8St`VsKnoSG}fY1y>(p#J{Wk*N3LWkI?)9`UM(A-B*)a^_9USawBD0=2f~N z&Hv9j0Rl0EvC~Tbz4ZV75f3<|?|k2NOEMGpEiDD_1lCs$Q3P(*GY(Y3sXcRTIp7z8 z+k(`dCI4&f|NP@fK4682A5lTx{=enmN36X8&kgZ4LFd0CU1cv%y=!H_9#7r3|-+!z+W{MiKVG1LA+c|NnaLn@J+D&%b5;*Ux$Sn0=Ny z8k39O9$V|Iqh7q)lkMJ$%nlJ4c!tqms{{82LnG}=kFZR&mjv74<>A|&Fo*A7WZc&>wxgtL>8o$>XP>vpz`Pq&Sibcic#G(lu6sWhIIiZ|y zE^K=D+Hd83&nI)|m^Pu#^BL3ALwGCdwiV^Oj-!&=r`xW~qAQUati3*yGt6VHCmB*yl ztt4J{+=0urO5WZf;E}{AN-)Ha@wXc}IZS$kQAcCg03lT+?|&vq&KLKz1BmSVKigd@ zXLcP*#d=?6p=c>v{%b-1rVTvAK~&hT*Ig!z^1A&sZyh(+zfQOJPDeEjuV$$EXN%{C zXA*NVlj^5yVY#U`-hPBfzG#jf_EnB`BHdDmb_q3ov7r_XWJ{WMYk>qI^4qx~+7!fh z)xO!%o$&+wHHOP^g3$+o?)2@WlNXfn5KRhHfk|=WS@zjkE2Ev9-o^!(?&R%>E-zlN zN1^$A(e+?W{hT#NMs32_mW$&>?oLEQ+DlGpcI9#e@npg9%}nFNhYb6xv)0~l7r3yR z$d$$F*34G7qnVND?E`4oDzr(r?*2Y7qX+FwZEZ&;Z|hCMK?3QQG4%;#=g7W0Bs-h^ zsVdX+(4Pz1+K>I8MBCzFjb1!8dFk>iuMM7)PZ#NFhN5`x{@KW9b4M7_f4H|LV{_?L z6HalZ5reuiMCtcHqVJ>79nace-n94mj6RY*K}KMHuAV@{TfLcahJ6OI&1wgmZ*v&uLZr6t2UjZ z860SFW*DcBYni+T!%vr(IhY%~;ciF+2wXUmt2veUvu6vnsC9JpSqGp+Y-j{rzY4Zh zN}=d=v{ACxoL0x{px&kq?!h_MSBLA*P~m|RZep#B{RS|bIR`c$YdO}V_jxMcK?LT% zPgM(C#?^oehaOnQMoODLI<)v-2OPCDAlLp@9TZ{isQocbZUfJEqkl5kK>Hld7(hcS ztT&Ug#zx;2La7YAuKt2GDx1Tm6YvuCk4~MK;z!rHYTq>h;4bi44OH=|LsN8C?2Z5V z)5PmFLqLA?JEPtVeEj{@Xu5CkY~eDSydmIqqo(u0Hpk6Y@AHZKT&*0bJt_BD(Sriq zVg{$;wTyN3Oh?DNg55C9go_01`xV_)S(pm3Wd>Vmhsb}~c9zSRL+cN3b6;AjxNw%- zGI~o~d&UuP!3$0qgm;)auSc}vh>3dEKfGN0@yS$9Dn=P;JbHV(KG9pV?z%NcnxfSs z{AFG`I_N@f21_;){3@KbVX)06ZnjgS{Fo&l25^Mmm_n@7Acz$_eb(NM9M2dDH|E?P z19seAA*dAjT3D~h!|P)e2XWW!K-rC_DaLx#--|rizxXS)cQ9?LsA;!!LFMxL{Z8lP z@R6WioU90<+#_!5q*PQPdBZAEveqiXIj@V;YiJH8mq*sz>!><;Zj-*&mZy4w4g7VSb)cEGeB z$gx2%G&PkVexb+?vryv~{rDj>GnvE7gZwBEqRDA*dTP@qVsko-HGWih{fo@{?y#&4 zUvXi!uKx-q6)Qii`K9A-=${$Og8?HKZ2;m5zxE_*ubFNM@mbXK`80T&vSXE(HvNd6 znt8Q-?2$T3I!?eJXKG(@LpR)}ohpeZl+SFGONqOs%seQEqG^TtS+&>%Ef4Gdh}N1+|I7F{=T-eeRk z{c}pw3TF-I-!?6*(|aPSMg)|q_}5)4eum9Tp0@CBDhTar^p3-hK@jNM5}>Vuul1;| zW=~w=|I@lfgCE!k?0@I#k-h7IrQi6y5`;JOIB3BKRc0mpZDl0P< zcmRBd%N1WaxGL?sq751Bi!-qGg?FXCyv&u3{_Dqxc>nN;5S4c0D9_~btpH#V{pLeF z$d^^|%)2^s0io1hBi^ieQ+VBPAB}Eq38f$z`wO}=Gi`T(&nyj7V!ZXYq7j;?WFY^?_W>IyQ!}hVcFV#OaOfdm)G#FO zbE89-B}Qda^Zo99P3OHU_OD-vfmv<8eZKy_Hw$!kZ7`(Np@bl4fBlzj-xZhja~(pn z0>WQEHGk^QH@4yx>s0BqTu`#H+aDsLr$B%~X=4o9iuGg>;eVW+n2g>-)a-GJ2)aOX zojST;b}GSKxudXP?UN7?p$&ZvXWXIpdjQ$W-b8g5qK36fRV^9CXEH?~aG6(x$v7VL zK5QfcM1hsI&e8Qo(v7sN6F23rZmqk+#=!ym4W^d$dkG)D+@uS(v=BTL0i5rSJeV|q z;qnU^s;_i&%1hT!O>937vZEWg#X5%c|c z={eqiBst5Ran`#t@S2OdW2A0DVIp>Rnc>G3SuPajJ{n!y;@-<&IV1gkG--3UHM)6$ zs&lmWyoVc8mxA74SP=oD5Cb22&WPBLgpHf*H<4AosXg&PZLCy71?2a8Uy#g8vXcFH zAGN~i1`K;^2?V}!yIcFIJVA|RBnPkq#^gh6wWuH&mS)ki%^Xgp*yjY|_@#eVTSJ#6 zQ7u(Wm1Hz@{`xFsMgGTUiTD5VS;muL{9isw8|tDqj+1tj2>7tCIsbSMw}!pdkS5Wy z{~u>B$Jzzj?c`%+G_D+apc?9^3$8ve{G~vaKuLje&ah=cQYR8^{K>k|3D)jy)ERB` zbT;kIupVcsM5Si6FyG%70c$ksicM(JB_zIGH&?uvn)al*F{yNA&bT9A$jdC2$2Fs0 z9a9J1aY-fBUoqX5)|oRbkr?6k)WEYzs3Kuup{J_~Xo`*xng7i1H2?kz#a9fSPD!yd zZ+3ugs8ES-p6Zx%q31ONefuRCunvvhO)0)oF}q=EM!5o|*p(qxy;fRRDY@qzc>wdc zvOMfY42SN%nKvrSQ61@)SL$o0YNs{U3zZF#$-6=_0N>^kfPwcP@gSt>5+X(qV1l^ z?t3|%vvnix@+7QB ze__vjEw#S8)3c{tv1$7J5VGDw2v=fC9J!<#Zo@G3G#HuEV40K=@UPYKvwYZJt7Z1X z|5`0^{5NM5(SrJMq5Li9@b5L z_{kH_8kQqy^&+8_Npd}Au7Q|V_vQR{@Ru|zT4w^Q-nM$}q+1uV1iQxR4$1>kcheoI z3K5-8eCS>5$8m1gvnP2jZev@bHIBG|pAaAMbidUA2kx%iLhk zR~Qi{&R|a7v^A2vFnV5+P|pbxPOW#U?doRK^Tvt(C}=MHwlIPYaow=Ha+6r>Q@Eg#-$PtyBYFb&g#0tNZMhIP{OjaRrV-i`2dG}KHGjcL{%_)R@x8A z%9CjRJo8%MJ9w=d2huHxtXM3h)-M+}Aa4GAXEqr)e)a{2ws+Dwfr6+edqPAUIpvzN zRtvefOp)^qosn1_2LCHib)MB_vO%jc<+a(nEVZGEW#s;987dIhde8ewRpr)qnT8w^ zuq5-xO^PkuJe=3h7KO3K+9AjhU#L1m$saZ6g9+Q(^8eT&BmZhVYmUNIJ9;=}+aJ*g z^;W&Y0a6IwEMxfeZ7>3-jhWjMOqDpgsJ3}E%dj`S6B|45yVXh#a4FZDZ5%M>=Edw- z2_em?cy#UH=;Fj0tSfm{ zDa||l@j7)SANi;bMPy9h2ZpiGm|7kY@{m0i4Un6X9ws|k=Is>-5sJ2+wM0|#|8hO* zW!zON8Lem4#QwLR&fc+H1@iDji?gt8(Z?#HRqpN8h+a{B8vb5ZS~qZt5^V&C;&$~n zg6(mVKnpI`MvyN!gPBiMP=y}*`F$Pp{C+bHZc$sYjnG1Zi@EPP_};TGa(xD!!HTb58$&4GW;RwSEMI=X%z6*bg;b|-qQ zM6)QbvM}>!YP@S4D%tl_*K~{!BoUU5)BWx+md?zQR4S?i2^sy2eb>D(<*Mb$mr#n< zq`W((RB6eyt8P8OXg<=c4NlnQH#f(*(FMg-CB=0z{#0@c^SnxJUQ($5r_B9c7LjbM zuW>%Xt*HLj@j>K(uO+`<5I|G=JTdefN#9B}moWm5mgKq6C=&?xY+$o`2h_1fXwauM zbu#uYa8C(?%fslXMRH^sKex2?9Y?^3SQs&Cs13lg#`HjUD6+X~rbqQyN8cD9ktWX8 ze@H*O`)*0ipY5%OJkaK9@%e%$VX*>k)}>(g8IzG%AJzKT|GGTIjI2xZs!jcC)pCz) z_S(RzpH$`(Sc5Cv6|oe>;jj_v3^~NBZ83hDVyjy z+8D`q|7$`7%ewln(AJ&PpJ~X)2=X&wbiHXkswCPz&gWkARb9SQw9)ZB0(>TriVJH= z`??=IGI>rJ4|uoy3w>gbAv>>IyA4hca&w84N77M?LT)bd76POCfdIq0>f$k-K{rBy z{)UR-Q(Z)S?m(GA$t9vxu(*f|?NH&2K4*g2A9VFIdV*;cq57Wb)4O9A*#0HEvKJ3tF9KMB;RMYCNtn%l!)w$>1OA5J_y@Wn=Rt9Y>k8rUrUj0BY3IBCD3U{uJDxaZVC4 ze)BxuPqv|?@Snc|ip5V}F5geeedEP=KRsbJ!2Il4etzxUIdT8Uvyqi?baD_q{%JK4 z^ey=DP_y+(L<#lNQJp3|F8fP^EtKSFN5YPR2DEmsFcg-biI!&M(-gVg-SqknT)((Z z1(~alH$>BO5s2yjN~GLrBg)zFq@0j#;qp0N)y5;v&Txgz z9tG^+yIWv-eWf#nSk*G|OVL`K_cTv!ZmR7!97v6&EqD(^3FZBek^z4ePZ*QqKu-i! zfFsX??^DhhOdEyq6y;!4js3UD5Yj-C`V zWckrZgj?+0hIUXQyGopSa2q|Yys)6p`V%w_2fQx>N2#YD_uP3&%4E_h??lKkNz9fX zJ@QIM&gRcru=|k!-RQU9|8%f}nZGR|G;z-kYw_cgI4BOh9$ZT)1C=aUz%D?1SIYN$ zREtZ}Is-`-*pV9U_cqQXLRlc*YBP9EhbD!-;L3@`h8>I4g&|edJYII zDTOnlL3=!Q8>mAXQAbX=BRe*z+vZFF0r(~`dxj(VQN3K5pDR!GpgJ(sAE zJCvE?jXYY8Mw@h2h8e!+?_jKlY2bJgWCxjS8d3ume8%_%3n@}FzFa*SbIYc^*TIj# znJ#B%ZI|lFeaztu8ETL|F5@gKSpNvgQ=29s^rcSppdWA5+XvgVNq~($5wy95@mGP! zGK+nvUe9$O@LMuzk$rahUt(K2JdS+uzb4_|zHU!=Y|Q$v9`?w#oT z`o)#MPY*TBvelv8CL>2r2Q{${q=lqHXs3$+w*Qidk(Bn~2SM_LG3M9*F#zQpEN~cadCguk}$HR&` zBWGT6^r*NZTGK7oZ6wc`?R599WS}rj3LK6TZdIdr)PhcXJf3VJBbJL{I(W#7X7()| ze&jriZ@~YfJ#z%;a|&Dk_6LPe*kFQ=}-u+n>lgE5Su=Vd2$1cTDxX zLC*(`->+HAVMlfKn;G20-Y`iokt_-QR`!!|#L(|%KCESLx6XGjWub2(zk4LN{O-I+ z$8E&@V-ReP&U(ReLMu_7nbPHjnVpjBjUFYHeE4RcP>tBh)#6=|Nvr1@lNLHkdVe!a zQXv9g56iIK!)%qyA)Bh491vdnuv8x1aYxj4NconBC+XN6p;QBg@t1(7YYTgF2W$bG zS`wTuE6LODlKM2>Ipsjx3kyOmB%*m%t?E1Tuu$`M`Wq^7dRdlHg;^rpj1#)ceF^x; zO-Ov>v{U%RgAn{vMvH1gN9y*)BH>Ns@53Vo=43ik0j)%e?5?>^I+bKuoiTdP2nqN}*%Fzq;Z>VB#9|I7$Ev?RfgG4zT(!O*AoYQT%FQUwPH(AN_z# z9(LqEW)$rV5|6YPSA9-(3h%4H9fAb8OCLDyip?9IkhN4oXgp!>5Iw->&y4zger3_u zc1!l-P`@*;N^RWfmM(v|VbKa^>^A7BUK?29?mNS;n0qD%^(^Jk#zU+_Rh-K+Uq!K^r0Sk?eSmweI^?8zlt|sxSAUGH+4IKs3YE z7a3ps=N0AMmOS(2P&d5nltbvfVOUf0%SiA=&B+E~JwQkS)8~If8l*?tME-s#1@gFC2`#2!{#cu`1-Z-F@NKbZz|-cNsh6Qi=T1i8 zBa3A^^sUq&7trltxHH3PFY9FY5iyy@9Y9}u|C!l#sH%(#{jk?C?YAB#8Bf^}(z zMuXRAN&?#BL4XvY0n?*ODqqJDP?Y%|fFOM!zMhD-E9q!SJFVIL}4=9gdyl)D{&TkB`mlc7(A z8mLm$r}3}GfAQW8rayfp_j}UI(!d=J2UcNr2IR6Ne+^S_ab)wi8ylXBa(xo@vhe7g z$T2%Myo@r&WA3S5>kvEj0HWVN+N&2^*K z#BB{f`i_hzi{hlN{Q$ndCm;b-Ko)cS0^LV*&9l?%wDX;i(5H#M(cbXs!^A1Fo~>2f zu>3)aB9N^uI(;o4!Ks-!*dEEtilWeOgMr`4(2*%2{`0J?q&zPIAJJSaw6S>i(*lue zy^1J|?wf(G87#I3+GPMLtcZFUi&=o?2AR?@`Y9ukYYcZC2(-C`{JG@QA3n)MD^JEz2og zPLseFj=f%X-_XrvL&@*Q95+8AxeQtRd0DQU;Ui33cwCAVeY){LMw9WoG-6zw4)Z`P zICV5W8J*mh*c!lmF64*sJv=*G%4IH=Nrc0JloGuB&kNkbsJ3wG>CsoS>linWo|1Qb z{ZmzHM#}!&XmqX|pR>rgK)tW?5?o?|lv<^n(+T>1`5N@?cA;G0hS`f7cD!oa@A>xe zi34_R0y|OfNPdB*IX&}0gSV<^?H5?Ldxewb1h*~U^%x91ngYz;inU)_WkTc;ApMsY zcJ+otXEobqjl<;#mUVHV!&Fr2LmP2j5EnRN_Ic&NVpT=jz<_Z+aN@d05E)LuzAn^B z!6kqHSssdKu~irhlLm4>4ler4^&ZL>U*0UpnkM)CEPSS)J?89m7pA7<`-l@>b<8CL zm_H3Er7v@qd=WZEl-`9&Np&HIZbaLM3!wkg+;_D#wMN}WQIHmFC>@oy5h)Q7LW>F# zkRnZb?+|+E(vc!{BQ4ZO2PO0_y$XR)0-;Ioy%TEq;&;x?KEL3syS1M8Vy)*bbIvj5 z8iQMSeP~`2D*utENKm^#a_Q*G1scX*@PKGvvD5i-Ctt>;iB! zwK-8Ebt6zDL@$E9>c@ItNi#l20-*B;$*pzLAJvf(%81!Jv;+nf8*4^W1xISCX zL#d_ynr~o!_a7HV_Laj&X$(P_d;yE^4vC97PGXiyt_#5DbanKoz^K-Ne~?-;)Jg4;J9mV6 zCY{Gx-R@pL+OG|U0UC&wC4~}f`N2`xm7r-5=MG@KsEieVEm+!EgvhX`A;d_W3Sb9!}TdA+_@Suiqq`e1&b)EX5IvFI=k; zyi=uvq0EqgSx$oBwIdf7rjS2w1tR**n{?xTPSv1UR~V%*avphOftM^z!&hP9G*@bR z(_}RO!Qt(a`orqa>cXho<5pua3^^sv<$WwrI(*uc%6Zb*fIB)X2<1 z%6v&7LMRx4hbR%T&-1+e+JldLHm{-E(`D6&gLA3)v2Ji`>s!E);mhDepz~rw7N6!? zqsuqbr2G10rAUd8dU!%?{o`n(T6;?hqoU9_zlpfhmQtUmQB?z>7K*i{_#Z*?kwVn! zGTTrst;v=}TB)>kyr64mz^1XO74jbH%($hLobLTJa+wDC-S@NY^!kNjLD|gr{JVS8 zj&s19A|lu2Z2RDut))|t>tk*=mW56q&fjCf3^92l<#YoQod^Iw3n!=l@g$bPlexDL zqON3n4`F6>_sz$i#>{Na5U0o=v{j33Xm&~TUSoL?lUG@^i(8box+os{lCfH?x{Pef z4w5bGQ|h@h$-TCt(R^@0(m|bYC~WfQPIRik>z$y%IPD=?faKoAS3ffrMq%3aP#3;?LP|K+htnRW}ng4dzyC+G2*_Z`#3m>?#v-O8DjNt(I1RRINjhIgEid^_#kB z{fkbPefA=@syrbx?u7x4L^op4=|g+&9J1xor7kxXzhMALKMgUtEi>9^ttbSw@_vG8 zs+^hHXmZ$$7*T4s?UF+tIjvkzI+D?b^Uy$1BW2@Y8^0t42}ou4-JTpBHxu@sB^t*6 z8-C2*S)8I=&O<$ptVu)$2CvWwpu--m>QoAUKXGV{VE5O$pONQMG=+wSm-N^Fw%sY` zpq->+5cj}ND4E@BO;&E2MJ?`>B0sM(6jrAQ$n3&yD_gZSXkQI)M`=5nnJ3rvZ%+Ya zs5X<<1Rq(aDFi#%yC1Z*g?ax@348pC7;;{l$gS!`QV)wU-J(*LFzPjW6^hJky>a=E z)`yy0{B_?hS8mHL$LVal0VgjRGS3Oh$vl*t>uR&JSzEC>+)u+lqjLQ7ejLbNXCz4r zAUxyoxhz;%+O}}z_dG*nM8ot&m$*%`fngxG0f|9@6aAC5eNLpcAQH$LZCD2&5o<25 zj2Pn-n(usYYf#N3+)yKO>cz(6w=^?iaL8y1YcQhe;dxpVtvFqN5Wt)2S_efF*%hTt z2R3gheShWGIP>Nbl1%+&qh#+hj2tVvW8`>iyz~LwzIrn%VdW}T?_Z;WxGj5q4^(k? zskT1at;}-u&l6hQ3%yTQAttV>6TA*vFAd=qQe?$nvC@fdjoDRORuCvv$e^T}LBm&3 z`c(|b%XEnSey5mROzM;vXdz`~!9a<#<d#h0MrJRv?{Ej*|-9KQ{j#LB|!%{$B_GgpU5v=M)|xXR{9R&!clfxkS}WrFMIjF2k$er z0|njvovf^#JGl-GeTB&Dz@R!MU`u1np!eLxkzoS{4H0>NcI_2Xt`0Tiy|I{WxR|Ut zyBd%8!Aumx_j-o^aDq)DlDBN0JkOtpQu&MPv6DL zHVoGGg=CF%;r{kHx<9S-`y{k{XwHq1l)b0t!UAgrY9T#h>-Q#rPA3~-A_vo^m3kb6 z7s;1(A=hFa5b~Cgac|&@G_&!U!pXz-y@Yf+zKOk=28HV|4ht~b^&S~9i5F1O_+c>W z@mV+IP#@gB&nIkKym-ciQt?y?TSt@99Xn5h74)sQUIqsE(XWX5tA<;{Evyx7CWE)% z(GV+kngo8mI*-qB!KtP2m1Ctpne-Ce1JC4wLoV0~hu#)Pk|0iJ7HV1&)f3W%Cf%T&7O)1bWlwuBkh48WF;jPJ%NAWzuDyqh%dG;NaSgH`7o|k-y<`IPIVV9ee;^=Cy?$mFHw#3pn zSNZ!`-quFj-cGm?=qm<98xfyw#_1uVJj z26De`*M6#qN1uK89m5WK4X!O_FbQk0vv?6s0(JDy_(@y#*)qgnogGP(Kn?^ zDJ(gBJxwNh|HQ&xwmS$3?B;q3JMQ0n?414xfGfk-?W#He2Le{WG{%CJ&Vliias{|F3aV=dQ%zCf+MJ^>{z|BRRLL^V1>V4k3w zUjb>{{R9a7`jUKD(jtFV=k7m7Nuy~eve7M-Gy~LP%#br4rE0Nc)yNSEmeplm`*V_0 zh|`e!ya?AXsWXr76s99(l>Bj`eaE4Nb^QDUu+jy2U)NPmQO>A45pd!v85CV3>y({t zI_QYnv0e_ncc@7T*gL5l2CW%474(xL8YJF8H_g5M%X6vVr(sj2A$MM@4__i^uWSPc zsD5#|>ei^;pJZKJ5R<5tB$pqEd_0z`!Dk@V{{a1rx}f65CD!0ikVGZnlvd|l{MMMZ zH3mocl&l3axu_n@u=Jb#Fc9XR>D@=V7kxB%4tE{O3DlpGLVLcGIdl359-SJ!D&Io! zy3FhqBEgI;?%8pP?xcGpArh|fmW5HhMul0@0drLmX`6VN84@Jb;0gTKdGe=Eh;}iz ziUgcL>ou1>DPNWIC6xDQ8mL-Ykz9|!q*3*eX7wH}U1n&vCcobRMB$-rYUw8n8)5_d ziIRE#fxR0DSe$!vg8n9PhG#Yy!oBSkf0Z_3qf*zDoSw`^x@z8-%U#`83TYGWOF3RF z*Z+RO`CY4kPgwd=X%qeiHZkNKO;>vPmYm`(lilhXV}wGCduddJ=9PcIwBNsNhyMh7 za1op&#m8*Z2r4`z*zdN5*^=kAOn=b(w=OeZy7z`K{xd!yJDT{rxraS3;=DAsISI~- zg)8K4bqF%HK;~PAd{V}yLhocLm)AVwoaqtiQsT)&&uJ&UdG4B1UDIBp*^E#$-Z@sn>p$yiG}5O2|i560hJ+*0x#@9jZW4?AyA`5<%tH6mvICdoyS^Kc}Ofhb{t z++ZX8im2vQxLkF%dvY+{e8qCisCEX4BI3sX?iw1j?KBl9d1RgB-fF(&^ur!gna@Ke z^#=STSD<*qrh(v?U!G?J^`7AVn8*f}*b_och4=2zh?qvCQ2*ur=I&uN-VSr@9Tf^( zvcG-OW;X?zZxh0y=d3t{kao{#SR}L`3NLL^5ul0K=8e$ z9A$QAcHOUNcoA&p*L#@{#UK?GQ?u`AMPex`SR%8{97pVQAxswUpei29n@l?meio|q z_&O`sP0r=ytV-)H^A@lQ`H}58p`+NjQVW$yVKruupHP=uToj6Dr~6cA<@xC-Uf7!# zL%J);v>SS|+Zt1`$d38KMW2wAg578*V5OItehaI>Ywy8a7BxxFjElU|dSh$Wer=n6 zzj{To?KG^XjtS__I@mMZvXQ#gqQ%M!*^oc_8oOLI_|C2|PS2THKNBF*JPs#t=c%+!*BWVOmPY z(9K^8ge;Umk?)$nkEuI(a^Y_7`TDSV+yiW%Ofv8}-}9`oZZ~TKfWmh_8=y&ex4&Zn z+>U<0Uj$Nx*G3PirPr2JA8dRFUOnCk`OAG|^3kAdQS-8CN=}RI&;mFz2R@>-`IBTV z9Or~*INefXB|OQj&j-R!1CqtbDihPGFlCNVlK!0sMCR92?0D=*8iJ*jSf&m&u@JF| zc7Nmv6iC7ZX}Hql-XWF<4{#`fq{oIoqXdIg;0j4WpTT6WklDEMxFr!Hp5&wWs>|h} z1%qimE7sZ%XRZvjQTTa+zyxoHk`H_R3dKV7!nWD)z9T8b91WF%O<8YjNIS~}bzzq3 z`94$K2q8-?xHx4`XHygTg_+w5zl58ca)efhh+vN8b**T$_fD$zHlE2vA>N~ibm$Yv ztM0oxXeH9)ghXe;y0q1t+ufvY%Bd)Ynf>5IS)|E`AbBd~{tN^8RUf(|{|#w{4blED z%=R0w`IE`?4%D;DF+dId+K#X8S2fELB;EVVN(SZS*5jo0=E(u50f5ciPx-CqG07Hc zLSFkrdJ6q8q{GyZXL6+FDl_YL=+E#7l{3vHKjn+Vt=kq(v$r6M} zuP454uFy4cvo>)n<2FEcCEtJard;KUw?q8K?iq|5t*Sae#-LJB#f2%ZSihdzI*AcF zK;-!PnX=!Fk#zn@a$v3`y(`Wp=1azKSSDvR_YRx0&rlC^SE^GV z;!lSCOka((l+5VrRwt^IKQ#BD{t#(3f=EnOX%)q#BX->94KPPcYJ6fKGEAqK826MxpfPu~ z;NX3%xzLGhc66WXsQ-uRv3Obh5` zKb6o8I}1!HaUsDfempNKQfqKtx8r@*I!ZgMe?y4&nPs)OPcP99dHJ1zhH zt>^{dw;^-7kAH&##nX<})|5{p#uYN67aH-S>TX}O-m`Z-(vh3^+u@Kn!=P;0k2*?* z|9l$t?hAI;HqX=Y#;s7R=D~<=#_dF+ZS<14914A9!(1iF#7mE#)l?AYO9sm86T`83q0if%zT4 literal 0 HcmV?d00001 diff --git a/CreateAuthCommand.py b/CreateAuthCommand.py new file mode 100644 index 0000000..bc2898f --- /dev/null +++ b/CreateAuthCommand.py @@ -0,0 +1,418 @@ +import uuid +import asn1tools +import yaml +from cryptography import x509 +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF +from cryptography.x509.oid import NameOID + +import constante as cts +from CreateCertificate import PrivateKey +from ui import UI + +AAS_MODEL = ['RFC5280.asn', 'RFC3279.asn', 'SSP_ASN.asn'] + + +class SSPAuthenticationCommand: + """Base class for a handling a SSP token.""" + + def __init__(self): + """Instantiate the object.""" + self.setModel(AAS_MODEL) + + def setModel(self, modeles): + """Set the ASN.1 model.""" + self.model = asn1tools.compile_files(modeles, 'der') + # for type in self.model.types: + # print(type) + + def generateChallengeCommand(self, parameters=None): + """ Generate the AAS-OP-GET-CHALLENGE-Service-Command.""" + m_aas_command = self.model.encode( + 'AAS-CONTROL-SERVICE-GATE-Commands', + ('aAAS-OP-GET-CHALLENGE-Service-Command', {}) + ) + with open(cts.PATH_CREDENTIALS + + "aAAS-OP-GET-CHALLENGE-Service-Command" + + ".der", "wb") as f: + f.write(m_aas_command) + + def generateChallengeResponse(self, parameters=None): + """ Generate the AAS-OP-GET-CHALLENGE-Service-Response.""" + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_PATH] + + ".der", "rb") as f: + aCertificates = f.read() + m_aCertificates = self.model.decode('Certificates', aCertificates) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_CHALLENGE] + + ".bin", "rb") as f: + aChallenge = f.read() + + m_aas_response = self.model.encode( + 'AAS-CONTROL-SERVICE-GATE-Responses', + ('aAAS-OP-GET-CHALLENGE-Service-Response', + {'aParameter': {'aChallenge': aChallenge, + 'aCertificates': m_aCertificates + } + })) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", "wb") as f: + f.write(m_aas_response) + + def readChallengeResponse(self, parameters=None): + """ Read the AAS-OP-GET-CHALLENGE-Service-Response.""" + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", "rb") as f: + aResponse = f.read() + m_aResponse = self.model.decode('AAS-CONTROL-SERVICE-GATE-Responses', + aResponse) + mCert509dict = {} + for certificate in m_aResponse[1]['aParameter']['aCertificates']: + der_data = self.model.encode('Certificate', certificate) + cert = x509.load_der_x509_certificate(der_data, default_backend()) + CN = cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) + mCert509dict[CN[0].value] = cert + + for k in mCert509dict: + v = mCert509dict[k] + CN = v.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) + cert_issuer = mCert509dict[CN[0].value] + public_key_issuer = cert_issuer.public_key() + print(k, " verified by:", CN[0].value) + public_key_issuer.verify( + v.signature, + v.tbs_certificate_bytes, + ec.ECDSA(hashes.SHA256()) + ) + + def generateAuthenticateCommand(self, parameters=None): + """ Generate the AAS-OP-AUTHENTICATE-Service-Command.""" + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_PATH] + + ".der", "rb") as f: + aCertificates_der = f.read() + m_aCertificates = self.model.decode('Certificates', aCertificates_der) + with open(cts.PATH_TOKENS + parameters[cts.KW_AUTHENTICATIONTOKEN] + + ".der", "rb") as f: + aToken_der = f.read() + m_aaa_token = self.model.decode('AuthenticationToken', aToken_der) + + m_aaa_token_param = {'aCredential': ( + 'aAccessorTokenCredential', { + 'aToken': m_aaa_token, + 'aTokenCertificationPath': m_aCertificates + } + ) + } + + m_aas_command = self.model.encode( + 'AAS-CONTROL-SERVICE-GATE-Commands', + ('aAAS-OP-AUTHENTICATE-ACCESSOR-Service-Command', + m_aaa_token_param) + ) + + with open(cts.PATH_CREDENTIALS + + "aAAS-OP-AUTHENTICATE-Service-Command.der", + "wb") as f: + f.write(m_aas_command) + + def generateAuthenticateResponse(self, parameters=None): + """ Generate the AAS-OP-AUTHENTICATE-Service-Response.""" + with open(cts.PATH_TOKENS + parameters[cts.KW_AUTHENTICATIONTOKEN] + + ".der", "rb") as f: + aToken_der = f.read() + m_aaa_token = self.model.decode('AuthenticationToken', aToken_der) + m_aas_command = self.model.encode( + 'AAS-CONTROL-SERVICE-GATE-Responses', + ('aAAS-OP-AUTHENTICATE-ACCESSOR-Service-Response', { + 'aParameter': ('aServiceToken', m_aaa_token) + } + ) + ) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", + "wb") as f: + f.write(m_aas_command) + + def generateSharedSecret(self, parameters=None): + """Generate the shared secret.""" + + m_private_key = PrivateKey(parameters[cts.KW_PRIVATE]).get() + # Read the authentication token + with open(cts.PATH_TOKENS + parameters[cts.KW_PUBLIC] + + ".der", "rb") as f: + aToken_der = f.read() + # Extract the authentication token with its model + m_token = self.model.decode('AuthenticationToken', aToken_der) + # Convert the public key info from a model to a DER + m_pk_der = self.model.encode('SubjectPublicKeyInfo', + m_token['tbsToken']['subjectPublicKeyInfo']) + # Retrieve the public key from the DER file + m_public_key = serialization.load_der_public_key( + m_pk_der, backend=default_backend() + ) + # Extract the key size for the streamcipher + m_key_size_idx = m_token['tbsToken']['aATK-Content']['aKey-Size'] + # Compute the shared key + shared_key = m_private_key.exchange( + ec.ECDH(), m_public_key) + # Compute the diversifier from aChallenge and the gate identifier. + m_diversifier = bytes(a ^ b for (a, b) in zip( + m_token['tbsToken']['aATK-Content']['aChallenge'], + self.m_aGateIdentifier)) + # Compute the shared info. + m_SI = cts.SI_KEYS[m_key_size_idx] + m_diversifier + # Derive the key for the shared info + derived_key = X963KDF( + algorithm=hashes.SHA256(), + length=cts.MD_LENGTH[m_key_size_idx], + sharedinfo=m_SI, + backend=default_backend() + ).derive(shared_key) + # Storage of the GCM key and IV + if m_key_size_idx == cts.KEY_SIZE_E128: + m_gcm_key = derived_key[0:16] + m_gcm_iv = derived_key[16:32] + else: + m_gcm_key = derived_key[0:32] + m_gcm_iv = derived_key[32:48] + m_model = asn1tools.compile_files(['SSPToken.asn'], 'der') + m_save_der = m_model.encode('GCM-Parameters', { + 'aKey': m_gcm_key, + 'aIV': m_gcm_iv + }) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", + "wb") as f: + f.write(m_save_der) + + def generateOAScommand(self, parameters=None): + """Generate the AAS-OP-ACCESS-SERVICE-Service-Command command.""" + m_aas_command = self.model.encode( + 'AAS-CONTROL-SERVICE-GATE-Commands', + ('aAAS-OP-ACCESS-SERVICE-Service-Command', { + 'aServiceIdentifier': bytes.fromhex(parameters[cts.KW_SI]), + 'aUseSecurePipe': True + } + ) + ) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", + "wb") as f: + f.write(m_aas_command) + + def generateOASresponse(self, parameters=None): + """ Generate the AAS-OP-ACCESS-SERVICE-Service-Response.""" + aRand = uuid.uuid4() + m_aGateIdentifier = uuid.uuid5(namespace=uuid.NAMESPACE_DNS, + name=aRand.urn + ) + m_aas_command = self.model.encode( + 'AAS-CONTROL-SERVICE-GATE-Responses', + ('aAAS-OP-ACCESS-SERVICE-Service-Response', { + 'aParameter': {'aGateIdentifier': m_aGateIdentifier.bytes} + } + ) + ) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", + "wb") as f: + f.write(m_aas_command) + + def readOASResponse(self, parameters=None): + """ Read the AAS-OP-ACCESS-SERVICE-Service-Response.""" + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", "rb") as f: + aResponse = f.read() + m_aResponse = self.model.decode('AAS-CONTROL-SERVICE-GATE-Responses', + aResponse) + self.m_aGateIdentifier =\ + m_aResponse[1]['aParameter']['aGateIdentifier'] + + def encryptLargeMessage(self, parameters=None): + """Encrypt large message from an input file.""" + self.m_counter = parameters[cts.KW_SEQUENCE] + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", + "rb") as f: + m_data = f.read() + m_model = asn1tools.compile_files(['SSPToken.asn'], 'der') + m_gcm = m_model.decode('GCM-Parameters', m_data) + # Read IV and key + self.m_gcm_key = m_gcm['aKey'] + self.m_gcm_iv = m_gcm['aIV'] + # Read the input file + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_IN] + + ".bin", + "rb") as f: + m_large_message = f.read() + m_mtu = parameters[cts.KW_MTU] + m_nb_bloc = int((len(m_large_message)+(m_mtu-1)) / (m_mtu-1)) + m_start = 0 + m_end = 0 + # Write the encrypted output file + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_OUT] + + ".bin", + "wb") as f: + for i in range(m_nb_bloc): + m_end = m_start + min(len(m_large_message)-m_end, m_mtu-1) + m = self.messageFragment(m_large_message[m_start:m_end], + (i == m_nb_bloc)) + m_start = m_end + m = self.encrypt(m) + f.write(m) + + def decryptLargeMessage(self, parameters=None): + """ Decrypt a large file from an input file.""" + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", + "rb") as f: + m_data = f.read() + m_model = asn1tools.compile_files(['SSPToken.asn'], 'der') + m_gcm = m_model.decode('GCM-Parameters', m_data) + # Read IV and key + self.m_gcm_key = m_gcm['aKey'] + self.m_gcm_iv = m_gcm['aIV'] + # Read the encrypted input file + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_IN] + + ".bin", + "rb") as f: + m_large_message = f.read() + m_mtu = parameters[cts.KW_MTU] + m_nb_bloc = int((len(m_large_message) / (m_mtu + 16 + cts.SCL_SIZE_SEQ))+1) + m_start = 0 + m_end = 0 + # Write the plaintext output file + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_OUT] + + ".bin", + "wb") as f: + for i in range(m_nb_bloc): + m_end = m_start + min(len(m_large_message)-m_end, m_mtu+16 + cts.SCL_SIZE_SEQ) + seq = m_large_message[m_start:m_start + cts.SCL_SIZE_SEQ] + m = m_large_message[m_start + cts.SCL_SIZE_SEQ:m_end] + m_start = m_end + m = self.decrypt(m, seq) + m, c = self.messageAssembly(m) + f.write(m) + + def generateIVC(self, m_seq): + """Generate IVC (96 bit) from IV and SEQ.""" + cipher = Cipher( + algorithms.AES(self.m_gcm_key), + modes.ECB(), + backend=default_backend()) + encryptor = cipher.encryptor() + ivc = encryptor.update( + self.m_gcm_iv[0:16-cts.SCL_SIZE_SEQ] + m_seq + ) + encryptor.finalize() + return ivc[0:12] + + def messageFragment(self, message_fragment, cb): + """ Create a message fragment.""" + PL = (len(message_fragment)+1) % 16 + if PL > 0: + PL = 16 - PL + if cb == 1: + H = PL | 128 + else: + H = PL + m_message = message_fragment+bytes(PL)+H.to_bytes(1, byteorder='big') + # Return the message fragment ready for encryption + return m_message + + def messageAssembly(self, message_fragment): + """Allow the fragment message assembly.""" + m_len_M = len(message_fragment) + H = int.from_bytes(message_fragment[m_len_M-1:m_len_M], 'big') + if H > 127: + CB = True + PL = H-128 + else: + CB = False + PL = H + # return the plaintext message fragment and the chaining bit + return message_fragment[0:m_len_M-PL-1], CB + + def encrypt(self, plaintext): + m_seq = self.m_counter.to_bytes(cts.SCL_SIZE_SEQ, 'big') + ivc = self.generateIVC(m_seq) + self.encryptor = Cipher( + algorithms.AES(self.m_gcm_key), + modes.GCM(ivc), + backend=default_backend() + ).encryptor() + # associated_data will be authenticated but not encrypted, + # it must also be passed in on decryption. + self.encryptor.authenticate_additional_data(b'') + # Encrypt the plaintext and get the associated ciphertext. + # GCM does not require padding. + ciphertext = self.encryptor.update(plaintext) +\ + self.encryptor.finalize() + self.m_counter = self.m_counter + 1 + return (m_seq+ciphertext + self.encryptor.tag) + + def decrypt(self, ciphertext, m_seq): + # Construct a Cipher object, with the key, iv, and additionally the + # GCM tag used for authenticating the message. + len_cipher = len(ciphertext) + tag = ciphertext[len_cipher-16:len_cipher] + ctext = ciphertext[0:len_cipher-16] + self.decryptor = Cipher( + algorithms.AES(self.m_gcm_key), + modes.GCM(self.generateIVC(m_seq), tag), + backend=default_backend() + ).decryptor() + + # We put associated_data back in or the tag will fail to verify + # when we finalize the decryptor. + self.decryptor.authenticate_additional_data(b'') + + # Decryption gets us the authenticated plaintext. + # If the tag does not match an InvalidTag exception will be raised. + return self.decryptor.update(ctext) + self.decryptor.finalize() + + +# Open the YAML parameter file +AUTHCONFIGURATION = { + 'options': 'c:h:i:o', + 'description': ["ifile=", "ofile=", "ccommand="], + 'usage': 'CreateAuthCommand.py -c [-i ] [-o ]' +} + +if __name__ == "__main__": + try: + my_ui = UI(AUTHCONFIGURATION) + m_auth = SSPAuthenticationCommand() + if my_ui.isInputFile(): + f = open(my_ui.getInputFile(), 'r', encoding='utf-8') + # Load the YAML file containing the parameters. + paths = list(yaml.load_all(f, Loader=yaml.FullLoader)) + f.close() + for path in paths: + for m_token in path: + parameters = path[m_token] + if m_token == cts.KW_CHALLENGE_COMMAND: + m_auth.generateChallengeCommand(parameters) + if m_token == cts.KW_CHALLENGE_RESPONSE: + m_auth.generateChallengeResponse(parameters) + if m_token == cts.KW_READ_CHALLENGE_RESPONSE: + m_auth.readChallengeResponse(parameters) + if m_token == cts.KW_AUTHENTICATION_COMMAND: + m_auth.generateAuthenticateCommand(parameters) + if m_token == cts.KW_AUTHENTICATION_RESPONSE: + m_auth.generateAuthenticateResponse(parameters) + if m_token == cts.KW_GENERATE_SHARED_KEY: + m_auth.generateSharedSecret(parameters) + if m_token == cts.KW_ENCRYPT: + m_auth.encryptLargeMessage(parameters) + if m_token == cts.KW_DECRYPT: + m_auth.decryptLargeMessage(parameters) + if m_token == cts.KW_OAS_COMMAND: + m_auth.generateOAScommand(parameters) + if m_token == cts.KW_OAS_RESPONSE: + m_auth.generateOASresponse(parameters) + if m_token == cts.KW_READ_OAS_RESPONSE: + m_auth.readOASResponse(parameters) + except ValueError as e: + print("Oops!..", e) diff --git a/CreateCertificate.py b/CreateCertificate.py new file mode 100644 index 0000000..7acdddd --- /dev/null +++ b/CreateCertificate.py @@ -0,0 +1,238 @@ +import yaml +import datetime +from cryptography import x509 +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.x509.oid import NameOID +import io +from ui import UI +import constante as cts + + +class PublicKey: + """Base class for a handling a public key.""" + + def __init__(self, name): + """Instantiate the object.""" + pu_name = cts.PATH_PUBLIC + name + "-public-key.der" + with io.open(pu_name, 'rb') as f: + buf = f.read() + f.close() + self.public_key = serialization.load_der_public_key( + buf, backend=default_backend() + ) + + def get(self): + """Get the native public key.""" + return self.public_key + + +class PrivateKey: + """Base class for a handling a public key.""" + + def __init__(self, name): + """Instantiate the object.""" + f = open(cts.PATH_PRIVATE + name + "-private-key.der", "rb") + buf = f.read() + f.close() + self.private_key = serialization.load_der_private_key( + buf, password=None, + backend=default_backend() + ) + + def get(self): + """Get the native private key.""" + return self.private_key + + +class SSPcertificate: + """Base class for a handling a SSP certificate.""" + + def __init__(self): + """Instantiate the object.""" + pass + + def generate(self, certificate_parameter): + """ Generate a certificate according to a set of parameters.""" + try: + # Creation of the certificate builder + cert = x509.CertificateBuilder() + + # Collection of the subjet attributes + attribute_subject = [] + attribute_issuer = [] + for k, m_field in certificate_parameter.items(): + + if k == cts.KW_ISSUER: + # Collect of the issuer attributes + for k, v in m_field.items(): + if k == cts.KW_C: + attribute_issuer.append(x509.NameAttribute( + NameOID.COUNTRY_NAME, v) + ) + if k == cts.KW_ST: + attribute_issuer.append(x509.NameAttribute( + NameOID.STATE_OR_PROVINCE_NAME, v)) + if k == cts.KW_O: + attribute_issuer.append(x509.NameAttribute( + NameOID.ORGANIZATION_NAME, v) + ) + if k == cts.KW_OU: + attribute_issuer.append(x509.NameAttribute( + NameOID.ORGANIZATIONAL_UNIT_NAME, v) + ) + if k == cts.KW_CN: + attribute_issuer.append(x509.NameAttribute( + NameOID.COMMON_NAME, v) + ) + # Get the issuer private key. + self.issuer_private_key = PrivateKey(v) + # Get the issur public key. + self.issuer_public_key = PublicKey(v) + if k == cts.KW_LN: + attribute_issuer.append(x509.NameAttribute( + NameOID.LOCALITY_NAME, v) + ) + + # Add the Authority Key Identifier (back chaining) + cert = cert.add_extension( + x509.AuthorityKeyIdentifier.from_issuer_public_key( + self.issuer_public_key.get()), critical=True) + + if k == cts.KW_SUBJECT: + # Collect of the subject attribute + for k, v in m_field.items(): + if k == cts.KW_C: + attribute_subject.append(x509.NameAttribute( + NameOID.COUNTRY_NAME, v) + ) + if k == cts.KW_ST: + attribute_subject.append(x509.NameAttribute( + NameOID.STATE_OR_PROVINCE_NAME, v)) + if k == cts.KW_O: + attribute_subject.append(x509.NameAttribute( + NameOID.ORGANIZATION_NAME, v) + ) + if k == cts.KW_OU: + attribute_subject.append(x509.NameAttribute( + NameOID.ORGANIZATIONAL_UNIT_NAME, v) + ) + if k == cts.KW_CN: + attribute_subject.append(x509.NameAttribute( + NameOID.COMMON_NAME, v) + ) + print("Certificate generation: ", v) + # Getting of the certificate public key. + self.public_key = PublicKey(v) + self.cert_name = v + + if k == cts.KW_LN: + attribute_subject.append(x509.NameAttribute( + NameOID.LOCALITY_NAME, v) + ) + + # Add the Subject Key Identifier extension. + cert = cert.add_extension( + x509.SubjectKeyIdentifier.from_public_key + (self.public_key.get()), + critical=False) + + if k == cts.KW_SERIAL_NUMBER: + # Add the serial number. + cert = cert.serial_number(m_field) + if k == cts.KW_NOT_BEFORE: + # Add the low limit validity date. + cert = cert.not_valid_before( + datetime.datetime.fromisoformat(m_field) + ) + if k == cts.KW_NOT_AFTER: + # Add the high limit validity date + cert = cert.not_valid_after( + datetime.datetime.fromisoformat(m_field) + ) + if k == cts.KW_EXTENSIONS: + # Collect the extensions. + for k, v in m_field.items(): + if k == cts.KW_BASICCONSTRAINTS: + # Add the basic constraints extension. + if v[cts.KW_VALUE][cts.KW_CA]: + cert = cert.add_extension( + x509.BasicConstraints( + ca=True, + path_length=v[cts.KW_VALUE][cts.KW_PATHLEN] + ), + critical=v[cts.KW_CRITICAL] + ) + else: + cert = cert.add_extension( + x509.BasicConstraints( + path_length=None, + ca=False), + critical=v[cts.KW_CRITICAL] + ) + if k == cts.KW_CERTIFICATEPOLICIES: + # Add the certificate policies extension. + cert = cert.add_extension( + x509.CertificatePolicies([ + x509.PolicyInformation( + x509.ObjectIdentifier( + v[cts.KW_VALUE] + [cts.KW_IDENTIFIER]), + [x509.UserNotice( + explicit_text=v[cts.KW_VALUE] + [cts.KW_EXPLICIT_TEXT], + notice_reference=None + )]) + ]), + critical=v[cts.KW_CRITICAL]) + # Init the issuer name. + cert = cert.issuer_name(x509.Name(attribute_issuer)) + # Init the subject name. + cert = cert.subject_name(x509.Name(attribute_subject)) + # Init of the subject public key + cert = cert.public_key(self.public_key.get()) + # Add the key usage extension + cert = cert.add_extension(x509.KeyUsage( + True, False, False, False, False, False, False, False, False + ), + critical=True + ) + # Sign the certificate with the issuer private key. + cert = cert.sign( + self.issuer_private_key.get(), + hashes.SHA256(), + default_backend() + ) + # Write our certificate out to disk. + with open(cts.PATH_CERTIFICATES + + self.cert_name+".der", "wb") as f: + f.write(cert.public_bytes(encoding=serialization.Encoding.DER)) + with open(cts.PATH_CERTIFICATES + + self.cert_name+".pem", "wb") as f: + f.write(cert.public_bytes(encoding=serialization.Encoding.PEM)) + + except ValueError as e: + print("Oops!..", e) + +# Open the YAML parameter file + + +CERTCONFIGURATION = { + 'options': 'c:h:i:o', + 'description': ["ifile=", "ofile=", "ccommand="], + 'usage': 'CreateCertificate.py -c [-i ] [-o ]' +} +if __name__ == "__main__": + my_ui = UI(CERTCONFIGURATION) + if my_ui.isInputFile(): + f = open(my_ui.getInputFile(), 'r', encoding='utf-8') + # Load the YAML file containing the parameters. + paths = list(yaml.load_all(f, Loader=yaml.FullLoader)) + f.close() + # print(paths) + # Scan all certificate parameters. + for certificate in paths[0]: + # Instantiate a certificate. + m_cert = SSPcertificate() + # # Generate the certificate according to the parameters. + m_cert.generate(certificate) diff --git a/CreateToken.py b/CreateToken.py new file mode 100644 index 0000000..6c51c11 --- /dev/null +++ b/CreateToken.py @@ -0,0 +1,284 @@ + +import uuid +import asn1tools +import yaml +from cryptography import x509 +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import ec + +from pyasn1.codec.der import decoder, encoder +from pyasn1.type import univ, namedtype + +import constante as cts +from CreateCertificate import PrivateKey, PublicKey +from ui import UI + + +class Certificate(univ.Sequence): + pass + + +class CertificationPath(univ.SetOf): + """Base class for a certificate lists.""" + pass + + +class AuthenticationToken(univ.Sequence): + """Base class for an authentication token.""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('tbsToken', univ.Sequence()), + namedtype.NamedType('signatureAlgorithm', univ.Sequence()), + namedtype.NamedType('signature', univ.Sequence()) + ) + + +class AuthenticationTokenCredential(univ.Sequence): + """Base class for an authentication token.""" + componentType = namedtype.NamedTypes( + namedtype.NamedType('token', univ.Sequence()), + namedtype.NamedType(cts.KW_PATH, univ.SetOf()) + ) + + +class SSPtoken: + """Base class for a handling a SSP token.""" + + def __init__(self, path): + """Instantiate the object.""" + self.path = path + + def setModel(self, modeles): + """Set the ASN.1 model.""" + self.model = asn1tools.compile_files(modeles, 'der') + + def generateChallenge(self, parameters): + file_name = cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + ".bin" + if parameters[cts.KW_GENERATE]: + # Generate a challenge as a random + aRand = uuid.uuid4() + self.m_challenge = aRand.bytes + # Save the private key for additional operations. + with open(file_name, "wb") as f: + f.write(self.m_challenge) + else: + with open(file_name, "rb") as f: + self.m_challenge = f.read() + + def generatePath(self, parameters): + """ Generate the certification path.""" + # Load the models + self.setModel(parameters[cts.KW_MODELES]) + # Instantiate the CertificationPath + self.path = CertificationPath() + # Load the certificates according to the configuration file + position = 0 + for certificate in parameters[cts.KW_PATH]: + # Load the certificate from the disk. + filename = cts.PATH_CERTIFICATES + certificate+".der" + with open(filename, "rb") as f: + certificate_der = f.read() + value = decoder.decode(certificate_der, + asn1Spec=Certificate()) + self.path.setComponentByPosition(position, value[0]) + position = position + 1 + # If Name of the certification path is present then the data are + # serialized and saved on a file + if cts.KW_NAME in parameters: + certificationPath_der = encoder.encode(self.path) + with open(cts.PATH_CREDENTIALS + parameters[cts.KW_NAME] + + ".der", "wb") as f: + f.write(certificationPath_der) + + def generateToken(self, parameters): + """ Generate a token according to a set of parameters.""" + try: + # Creation of the token builder + print(parameters[cts.KW_MODELES]) + self.setModel(parameters[cts.KW_MODELES]) + self.token_name = parameters[cts.KW_NAME] + # Generate a pair of private/public keys for EDCDH operations. + if parameters[cts.KW_ECKA_CURVE] not in cts.CURVES: + raise Exception("wrong ECC curve") + private_ekey = ec.generate_private_key( + cts.CURVES[parameters[cts.KW_ECKA_CURVE]]) + # Serialize the private key to a DER format + private_ekey_der = private_ekey.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption() + ) + # Save the private key for additional operations. + with open(cts.PATH_PRIVATE + self.token_name + + "-private-key.der", "wb") as f: + f.write(private_ekey_der) + # Compute the public key from the private key. + public_ekey = private_ekey.public_key() + # Encode the public key according to the DER format. + public_key_der = public_ekey.public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + # Create a public key info. + public_key_data = self.model.decode( + 'SubjectPublicKeyInfo', public_key_der) + + # Collection of the subjet attributes + for k, m_field in parameters.items(): + + if k == cts.KW_ISSUER: + # Get the issuer private key. + self.issuer_private_key = PrivateKey(m_field).get() + self.issuer_public_key = PublicKey(m_field).get() + + # Create the structure for generating the authentication token body + atbsToken = {'version': cts.V1} + # Fill the signature parameters + atbsToken['signature'] = {} + atbsToken['signature']['algorithm'] = cts.OID_ECDSASHA256 + atbsToken['subjectPublicKeyInfo'] = public_key_data + + # Fill the ATK-Content + atbsToken['aATK-Content'] = { + 'aChallenge': self.m_challenge} + if parameters[cts.KW_KEYSIZE] not in cts.KEY_SIZES: + raise Exception("wrong Key size") + # fill the challenge field + atbsToken['signatureAlgorithm'] = {} + atbsToken['signatureAlgorithm']['algorithm'] = cts.OID_ECDSASHA256 + atbsToken['aATK-Content']['aKey-Size'] = cts.KEY_SIZES[parameters[cts.KW_KEYSIZE]] # 'Key-Size 128 or 256' + atbsToken['aATK-Content']['aStreamCipherIdentifier'] = cts.AES_CGM # 'aAES-CGM-StreamCipherIdentifier' + # Create the AKI structure + m_AKI = x509.AuthorityKeyIdentifier.from_issuer_public_key( + self.issuer_public_key) + # Fill the AKI extension + atbsToken['extensions'] = [{}] + atbsToken['extensions'][0]['extnID'] = cts.OID_AKI + atbsToken['extensions'][0]['critical'] = True + atbsToken['extensions'][0]['extnValue'] = m_AKI.key_identifier + # Encode the TBSToken + tbsToken = self.model.encode('TBSToken', atbsToken) + + # Generate the signature + signature_der = self.issuer_private_key.sign( + tbsToken, ec.ECDSA(hashes.SHA256())) + # Convert the DER format to a dictionary + signature_data = self.model.decode( + 'ECDSA-Sig-Value', signature_der) + + # Create the authentication token structure + auth_token = {} + # Fill the authentication token body + auth_token['tbsToken'] = atbsToken + # Fill the authentication token signature + auth_token['signature'] = signature_data + auth_token['signatureAlgorithm'] = {} + auth_token['signatureAlgorithm']['algorithm'] = cts.OID_ECDSASHA256 + # Encode the authentication token using the DER formaty + auth_token_der = self.model.encode( + cts.KW_AUTHENTICATIONTOKEN, auth_token) + # Save the authentication token on to disk. + with open(cts.PATH_TOKENS + + self.token_name+".der", "wb") as f: + f.write(auth_token_der) + # Verify the authentication token + # self.verifyToken(parameters) + + except ValueError as e: + # Catch an execption if it is occured + print("Oops!..", e) + + def verifyToken(self, parameters): + """ Generate a token according to a set of parameters.""" + try: + # Creation of the token builder + self.setModel(parameters[cts.KW_MODELES]) + self.token_name = parameters[cts.KW_NAME] + for k, m_field in parameters.items(): + + if k == "issuer": + # Get the issuer public key. + self.issuer_public_key = PublicKey(m_field).get() + # Create a subject key identifier from the issuer public key + authorityKeyIdentifier = x509.SubjectKeyIdentifier.from_public_key(self.issuer_public_key) + auth_token_der = 0 + # Load the authentication token from the disk. + with open(cts.PATH_TOKENS + + self.token_name+".der", "rb") as f: + auth_token_der = f.read() + + # Decode the authentication token DER data + token_verif = self.model.decode(cts.KW_AUTHENTICATIONTOKEN, + auth_token_der + ) + # Check if the version is right + if token_verif['tbsToken']['version'] != cts.V1: + raise Exception("wrong Version") + # Check if the signature algorithm identifier is right before + # verifying the signature + if token_verif['tbsToken']['signatureAlgorithm']['algorithm'] != cts.OID_ECDSASHA256: + raise Exception("wrong Signature algorithm") + # Check if the signature streamcipher algorithm identifier is right + if token_verif['tbsToken']['aATK-Content']['aStreamCipherIdentifier'] not in [cts.AES_CGM]: + raise Exception("wrong stream cipher identifier") + # Check if the key sizz is known + if token_verif['tbsToken']['aATK-Content']['aKey-Size'] not in [cts.KEY_SIZE_E128, cts.KEY_SIZE_E256]: + raise Exception("wrong Key size") + # Scan the extensions + m_AKI = b'x00' + for extension in token_verif['tbsToken']['extensions']: + # Check if the extension is AKI + if extension['extnID'] == cts.OID_AKI: + # Intermediate saving of the AKI + m_AKI = extension['extnValue'] + # Check if Authority Key Identifier (AKI) is right + if authorityKeyIdentifier.digest != m_AKI: + raise Exception("wrong AKI") + # Check if the authentication is well-formed + self.authenticationToken = decoder.decode( + auth_token_der, asn1Spec=AuthenticationToken() + ) + # Verify the signature + self.issuer_public_key.verify( + encoder.encode(self.authenticationToken[0].getComponentByPosition(2)), + encoder.encode(self.authenticationToken[0].getComponentByPosition(0)), + ec.ECDSA(hashes.SHA256())) + except ValueError as e: + print("Oops!..", e) + +# Open the YAML parameter file + + +tokenConfiguration = { + 'options': ':c:hi:o', + 'description': ["ifile=", "ofile=", "ccommand="], + 'usage': 'CreateToken.py [-c ] [-i ] [-o ]' +} +if __name__ == "__main__": + try: + my_ui = UI(tokenConfiguration) + if my_ui.isInputFile(): + f = open(my_ui.getInputFile(), 'r', encoding='utf-8') + # Load the YAML file containing the parameters. + paths = list(yaml.load_all(f, Loader=yaml.FullLoader)) + f.close() + # print(paths) + # Scan all token parameters. + m_cert = SSPtoken("") + for path in paths: + for m_token in path: + parameters = path[m_token] + if m_token == cts.KW_CHALLENGE: + m_cert.generateChallenge(parameters) + + if m_token == cts.KW_CERTIFICATIONPATH: + m_cert.generatePath(parameters) + + if m_token == cts.KW_AUTHENTICATIONTOKEN: + print("token generation: ", parameters[cts.KW_NAME]) + # Instantiate a token. + # # Generate the token according to the parameters. + m_cert.generateToken(parameters) + + except ValueError as e: + print("Oops!..", e) diff --git a/ETSI-SSP-AAA-FAKE-param.yaml b/ETSI-SSP-AAA-FAKE-param.yaml new file mode 100644 index 0000000..7e15982 --- /dev/null +++ b/ETSI-SSP-AAA-FAKE-param.yaml @@ -0,0 +1,70 @@ +--- +AAA_FAKE: # certification path name + - certificate: + extensions: + CertificatePolicies: + critical: true + value: + identifier: 0.4.0.3666.1 + explicit_text: id-role + basicConstraints: + critical: true + value: + CA: true + pathlen: 1 + Name: ETSI-SSP-CI # Base name of the certificate + serial_number: 1 + not_after: '2021-12-01T12:00:00' + issuer: ETSI-SSP-CI # Base name of the issuer's keys + not_before: '2021-01-01T12:00:00' + subject: + C: FR + ST: PACA + CN: ETSI.ORG + O: ETSI-SSP-TTF + OU: ETSI + - certificate: + extensions: + CertificatePolicies: + critical: true + value: + identifier: 0.4.0.3666.1.1 + explicit_text: id-role-aaa + basicConstraints: + critical: true + value: + CA: true + pathlen: 0 + Name: ETSI-SSP-AAA-CA + serial_number: 3 + not_after: '2021-12-01T12:00:00' + issuer: ETSI-SSP-CI + not_before: '2021-01-01T12:00:00' + subject: + C: FR + ST: PACA + CN: ETSI.ORG + O: ETSI-SSP-TTF + OU: ETSI + - certificate: + extensions: + CertificatePolicies: + critical: true + value: + identifier: 0.4.0.3666.1.1.1 + explicit_text: id-role-aaa-application + basicConstraints: + critical: true + value: + CA: false + Name: ETSI-SSP-AAA-EE + serial_number: 5 + not_after: '2021-12-01T12:00:00' + issuer: ETSI-SSP-AAS-CA + not_before: '2021-01-01T12:00:00' + subject: + C: FR + ST: PACA + CN: ETSI.ORG + O: ETSI-SSP-TTF + OU: ETSI diff --git a/ETSI-SSP-AAA-TOKEN-param.yaml b/ETSI-SSP-AAA-TOKEN-param.yaml new file mode 100644 index 0000000..f4464df --- /dev/null +++ b/ETSI-SSP-AAA-TOKEN-param.yaml @@ -0,0 +1,23 @@ +Challenge: + Generate: false # Do not generate a challenge + Name: AAS01 # File name of the file containing the challenge +CertificationPath: + Name: CP_AAA # File name of the DER file containing the certification path + Path: + - ETSI-SSP-AAA-CI # AAA CI + - ETSI-SSP-AAA-CA # AAA CA + - ETSI-SSP-AAA-EE # AAA EE + Modeles: + - RFC5280.asn # x509v3 certificate model + - RFC3279.asn # ECC signature parameters +AuthenticationToken: + Name: ATK-AAA-ECKA # File name of the authentication token DER file + Issuer: ETSI-SSP-AAA-EE # Certificatte verifying the authentication token + ECKA-Curve: BrainpoolP256R1 # ECC curve for key agreement + KeySize: 256 # key size of the streamcipher + Modeles: + - RFC5280.asn # x509v3 certificate model + - RFC3279.asn # ECC signature parameters + - SSP_ASN.asn + + \ No newline at end of file diff --git a/ETSI-SSP-AAA-param.yaml b/ETSI-SSP-AAA-param.yaml new file mode 100644 index 0000000..839f39f --- /dev/null +++ b/ETSI-SSP-AAA-param.yaml @@ -0,0 +1,77 @@ +- Extensions: + CertificatePolicies: + Critical: true + Value: + Identifier: 0.4.0.3666.1 + Explicit_text: id-role + BasicConstraints: + Critical: true + Value: + CA: true + Pathlen: 1 + Serial_number: 1 + Not_after: '2021-12-01T12:00:00' + Not_before: '2021-01-01T12:00:00' + Issuer: + C: FR + ST: PACA + CN: ETSI-SSP-AAA-CI + O: ETSI.ORG + OU: SSP-TTF + Subject: + C: FR + ST: PACA + CN: ETSI-SSP-AAA-CI + O: ETSI.ORG + OU: SSP-TTF +- Extensions: + CertificatePolicies: + Critical: true + Value: + Identifier: 0.4.0.3666.1.2 + Explicit_text: id-role-AAA + BasicConstraints: + Critical: true + Value: + CA: true + Pathlen: 0 + Serial_number: 3 + Not_after: '2021-12-01T12:00:00' + Not_before: '2021-01-01T12:00:00' + Issuer: + C: FR + ST: PACA + CN: ETSI-SSP-AAA-CI + O: ETSI.ORG + OU: SSP-TTF + Subject: + C: FR + ST: PACA + CN: ETSI-SSP-AAA-CA + O: ETSI.ORG + OU: SSP-TTF +- Extensions: + CertificatePolicies: + Critical: true + Value: + Identifier: 0.4.0.3666.1.2.1 + Explicit_text: id-role-aaa-application + BasicConstraints: + Critical: true + Value: + CA: false + Serial_number: 5 + Not_after: '2021-12-01T12:00:00' + Not_before: '2021-01-01T12:00:00' + Issuer: + C: FR + ST: PACA + CN: ETSI-SSP-AAA-CA + O: ETSI.ORG + OU: SSP-TTF + Subject: + C: FR + ST: PACA + CN: ETSI-SSP-AAA-EE + O: ETSI.ORG + OU: SSP-TTF \ No newline at end of file diff --git a/ETSI-SSP-AAS-TOKEN-param.yaml b/ETSI-SSP-AAS-TOKEN-param.yaml new file mode 100644 index 0000000..f310ca3 --- /dev/null +++ b/ETSI-SSP-AAS-TOKEN-param.yaml @@ -0,0 +1,24 @@ +Challenge: + Generate: true + Name: AAS01 +CertificationPath: + Name: CP_AAS + Path: + - ETSI-SSP-AAS-CI + - ETSI-SSP-AAS-CA + - ETSI-SSP-AAS-EE + Modeles: + - RFC5280.asn + - RFC3279.asn +AuthenticationToken: + Name: ATK-AAS-ECKA + Issuer: ETSI-SSP-AAS-EE + ECKA-Curve: BrainpoolP256R1 + KeySize: 256 + Modeles: + - RFC5280.asn # x509v3 certificate model + - RFC3279.asn # ECC signature parameters + - SSP_ASN.asn + + + \ No newline at end of file diff --git a/ETSI-SSP-AAS-param.yaml b/ETSI-SSP-AAS-param.yaml new file mode 100644 index 0000000..4ac857e --- /dev/null +++ b/ETSI-SSP-AAS-param.yaml @@ -0,0 +1,77 @@ +- Extensions: + CertificatePolicies: + Critical: true + Value: + Identifier: 0.4.0.3666.1 + Explicit_text: id-role + BasicConstraints: + Critical: true + Value: + CA: true + Pathlen: 1 + Serial_number: 1 + Not_after: '2021-12-01T12:00:00' + Not_before: '2021-01-01T12:00:00' + Issuer: + C: FR + ST: PACA + CN: ETSI-SSP-AAS-CI + O: ETSI.ORG + OU: SSP-TTF + Subject: + C: FR + ST: PACA + CN: ETSI-SSP-AAS-CI + O: ETSI.ORG + OU: SSP-TTF +- Extensions: + CertificatePolicies: + Critical: true + Value: + Identifier: 0.4.0.3666.1.1 + Explicit_text: id-role-aas + BasicConstraints: + Critical: true + Value: + CA: true + Pathlen: 0 + Serial_number: 3 + Not_after: '2021-12-01T12:00:00' + Not_before: '2021-01-01T12:00:00' + Issuer: + C: FR + ST: PACA + CN: ETSI-SSP-AAS-CI + O: ETSI.ORG + OU: SSP-TTF + Subject: + C: FR + ST: PACA + CN: ETSI-SSP-AAS-CA + O: ETSI.ORG + OU: SSP-TTF +- Extensions: + CertificatePolicies: + Critical: true + Value: + Identifier: 0.4.0.3666.1.1.1 + Explicit_text: id-role-aas-service + BasicConstraints: + Critical: true + Value: + CA: false + Serial_number: 5 + Not_after: '2021-12-01T12:00:00' + Not_before: '2021-01-01T12:00:00' + Issuer: + C: FR + ST: PACA + CN: ETSI-SSP-AAS-CA + O: ETSI.ORG + OU: SSP-TTF + Subject: + C: FR + ST: PACA + CN: ETSI-SSP-AAS-EE + O: ETSI.ORG + OU: SSP-TTF diff --git a/ETSI-SSP-AUTHENTICATE-param.yaml b/ETSI-SSP-AUTHENTICATE-param.yaml new file mode 100644 index 0000000..d7b7567 --- /dev/null +++ b/ETSI-SSP-AUTHENTICATE-param.yaml @@ -0,0 +1,37 @@ +Challenge command: # Generate a challenge + Name: AAS01 # Write a binary file containing a 128 bit challenge +Challenge response: + Path: CP_AAS # AAS certification path + Challenge: AAS01 # Write a binary file containing a 128 bit challenge + Name: aAAS-OP-GET-CHALLENGE-Service-Response +Read Challenge response: + Name: aAAS-OP-GET-CHALLENGE-Service-Response +Authenticate command: + Path: CP_AAA + AuthenticationToken: ATK-AAA-ECKA + Name: aAAS-OP-AUTHENTICATE-Service-Command +Authenticate response: + AuthenticationToken: ATK-AAS-ECKA + Name: aAAS-OP-AUTHENTICATE-Service-Response +OAS command: + Name: OAS_COMMAND + Service Identifier: 'DD61116FF0DD57F48A4F52EE70276F24' # Root accessor identifier +OAS response: + Name: OAS_RESPONSE +Read OAS response: + Name: OAS_RESPONSE +Generate shared key: + Private: ATK-AAA-ECKA + Public: ATK-AAS-ECKA + Name: GCM_AAA_AAS +Encrypt: + Name: GCM_AAA_AAS # Container for the derived keys/IV + MTU: 240 + Sequence: 1 + In: Text_In + Out: Text_Out +Decrypt: + Name: GCM_AAA_AAS + MTU: 240 + In: Text_Out + Out: Text_Out_bis \ No newline at end of file diff --git a/ETSI-SSP-CI-param.yaml b/ETSI-SSP-CI-param.yaml new file mode 100644 index 0000000..66998b9 --- /dev/null +++ b/ETSI-SSP-CI-param.yaml @@ -0,0 +1,93 @@ +- Name: "ETSI-SSP-CI" + subject: + C: "FR" + ST: "PARIS" + O: "ETSI-SSP-TTF" + OU: "ETSI" + CN: "ETSI.ORG" + serial_number: 1 + not_before: '2021-01-01T12:00:00' # YYYYMMDDhhmmssZ + not_after: '2021-12-01T12:00:00' # YYYYMMDDhhmmssZ + issuer: "ETSI-SSP-CI" + extensions: + basicConstraints: + critical: True + value: + CA: True + pathlen: 1 + +- Name: "ETSI-SSP-AAA-CA" + subject: + C: "FR" + ST: "PARIS" + O: "ETSI-SSP-TTF" + OU: "ETSI" + CN: "ETSI.ORG" + issuer: "ETSI-SSP-CI" + serial_number: 2 + not_before: '2021-01-01T12:00:00' # YYYYMMDDhhmmssZ + not_after: '2021-12-01T12:00:00' # YYYYMMDDhhmmssZ + extensions: + basicConstraints: + critical: True + value: + CA: True + pathlen: 0 + +- Name: "ETSI-SSP-AAS-CA" + subject: + C: "FR" + ST: "PARIS" + O: "ETSI-SSP-TTF" + OU: "ETSI" + CN: "ETSI.ORG" + serial_number: 3 + not_before: '2021-01-01T12:00:00' # YYYYMMDDhhmmssZ + not_after: '2021-12-01T12:00:00' # YYYYMMDDhhmmssZ + issuer: "ETSI-SSP-CI" + extensions: + basicConstraints: + critical: True + value: + CA: True + pathlen: 0 + id-ce-CertificatePolicies: + type_name: 'certificatePolicies' + critical: TRUE + value: '0 4 0 3666 1 1' + subject: + issuer: + +- Name: "ETSI-SSP-AAA-EE" + subject: + C: "FR" + ST: "PARIS" + O: "ETSI-SSP-TTF" + OU: "ETSI" + CN: "ETSI.ORG" + serial_number: 4 + issuer: "ETSI-SSP-CA-AAA" + not_before: '2021-01-01T12:00:00' # YYYYMMDDhhmmssZ + not_after: '2021-12-01T12:00:00' # YYYYMMDDhhmmssZ + extensions: + basicConstraints: + critical: True + value: + CA: False +- Name: "ETSI-SSP-AAS-EE" + subject: + C: "FR" + ST: "PARIS" + O: "ETSI-SSP-TTF" + OU: "ETSI" + CN: "ETSI.ORG" + serial_number: 5 + not_before: '2021-01-01T12:00:00' # YYYYMMDDhhmmssZ + not_after: '2021-12-01T12:00:00' # YYYYMMDDhhmmssZ + issuer: "ETSI-SSP-CA-AAS" + extensions: + basicConstraints: + critical: True + value: + CA: False + \ No newline at end of file diff --git a/GENKEY.bat b/GENKEY.bat new file mode 100644 index 0000000..bcac71f --- /dev/null +++ b/GENKEY.bat @@ -0,0 +1,44 @@ +clear +echo del private_keys/*.* +del public_keys/*.* +echo openssl ecparam -name brainpoolP384r1 -genkey -noout -outform der -out private_keys/ETSI-SSP-CI-private-key.der +echo openssl ecparam -name brainpoolP384r1 -genkey -noout -outform der -out private_keys/ETSI-SSP-AAA-CA-private-key.der +echo openssl ecparam -name brainpoolP384r1 -genkey -noout -outform der -out private_keys/ETSI-SSP-AAA-EE-private-key.der +echo openssl ecparam -name brainpoolP384r1 -genkey -noout -outform der -out private_keys/ETSI-SSP-AAS-CA-private-key.der +echo openssl ecparam -name brainpoolP384r1 -genkey -noout -outform der -out private_keys/ETSI-SSP-AAS-EE-private-key.der +openssl ecparam -name brainpoolP384r1 -genkey -noout -outform der -out private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der + +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-CA-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.pem +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CA-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAA-CA-FAKE-public-key.der + +openssl ec -inform DER -in private_keys/ETSI-SSP-CI-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAA-CI-private-key.pem +openssl ec -inform DER -in private_keys/ETSI-SSP-CI-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAS-CI-private-key.pem +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-CA-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAA-CA-private-key.pem +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-EE-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAA-EE-private-key.pem +openssl ec -inform DER -in private_keys/ETSI-SSP-AAS-CA-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAS-CA-private-key.pem +openssl ec -inform DER -in private_keys/ETSI-SSP-AAS-EE-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAS-EE-private-key.pem +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-CA-private-key.der -outform PEM -out private_keys/ETSI-SSP-AAA-CA-private-key.pem + +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CI-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAA-CI-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-CI-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAS-CI-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CA-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAA-CA-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAA-CA-FAKE-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-EE-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAA-EE-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-EE-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAA-EE-FAKE-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-CA-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAS-CA-public-key.der +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-EE-private-key.der -pubout -outform der -out public_keys/ETSI-SSP-AAS-EE-public-key.der + +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CI-private-key.der -pubout -outform pem -out public_keys/ETSI-SSP-AAA-CI-public-key.pem +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-CI-private-key.der -pubout -outform pem -out public_keys/ETSI-SSP-AAS-CI-public-key.pem +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CA-private-key.der -pubout -outform pem -out public_keys/ETSI-SSP-AAA-CA-public-key.pem +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-EE-private-key.der -pubout -outform pem -out public_keys/ETSI-SSP-AAA-EE-public-key.pem +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-CA-private-key.der -pubout -outform pem -out public_keys/ETSI-SSP-AAS-CA-public-key.pem +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-EE-private-key.der -pubout -outform pem -out public_keys/ETSI-SSP-AAS-EE-public-key.pem + + + +dir private_keys +dir public_keys + +echo openssl x509 -in ETSI-SSP-AAS-EE.asn -inform der -text +echo openssl x509 -text -in certificates/ETSI-SSP-AAA-CA.crt -noout \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9b453f2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Alain Rhelimi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/RFC3279.asn b/RFC3279.asn new file mode 100644 index 0000000..2056a20 --- /dev/null +++ b/RFC3279.asn @@ -0,0 +1,275 @@ + PKIX1Algorithms88 { iso(1) identified-organization(3) dod(6) + internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) + id-mod-pkix1-algorithms(17) } + + DEFINITIONS EXPLICIT TAGS ::= BEGIN + + -- EXPORTS All; + + -- IMPORTS NONE; + + -- + -- One-way Hash Functions + -- + + md2 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) + digestAlgorithm(2) 2 } + + md5 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) + digestAlgorithm(2) 5 } + + id-sha1 OBJECT IDENTIFIER ::= { + iso(1) identified-organization(3) oiw(14) secsig(3) + algorithms(2) 26 } + + -- + -- DSA Keys and Signatures + -- + + -- OID for DSA public key + + id-dsa OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } + + -- encoding for DSA public key + + DSAPublicKey ::= INTEGER -- public key, y + + Dss-Parms ::= SEQUENCE { + p INTEGER, + q INTEGER, + g INTEGER } + + -- OID for DSA signature generated with SHA-1 hash + + id-dsa-with-sha1 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 } + + -- encoding for DSA signature generated with SHA-1 hash + + Dss-Sig-Value ::= SEQUENCE { + r INTEGER, + s INTEGER } + + -- + -- RSA Keys and Signatures + -- + + -- arc for RSA public key and RSA signature OIDs + + pkcs-1 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } + + -- OID for RSA public keys + + rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } + + -- OID for RSA signature generated with MD2 hash + + md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } + + -- OID for RSA signature generated with MD5 hash + + md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } + + -- OID for RSA signature generated with SHA-1 hash + + sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } + + -- encoding for RSA public key + + RSAPublicKey ::= SEQUENCE { + modulus INTEGER, -- n + publicExponent INTEGER } -- e + + -- + -- Diffie-Hellman Keys + -- + + dhpublicnumber OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) ansi-x942(10046) + number-type(2) 1 } + + -- encoding for DSA public key + + DHPublicKey ::= INTEGER -- public key, y = g^x mod p + + DomainParameters ::= SEQUENCE { + p INTEGER, -- odd prime, p=jq +1 + g INTEGER, -- generator, g + q INTEGER, -- factor of p-1 + j INTEGER OPTIONAL, -- subgroup factor, j>= 2 + validationParms ValidationParms OPTIONAL } + + ValidationParms ::= SEQUENCE { + seed BIT STRING, + pgenCounter INTEGER } + + -- + -- KEA Keys + -- + + id-keyExchangeAlgorithm OBJECT IDENTIFIER ::= + { 2 16 840 1 101 2 1 1 22 } + + KEA-Parms-Id ::= OCTET STRING + + -- + -- Elliptic Curve Keys, Signatures, and Curves + -- + + ansi-X9-62 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) 10045 } + + FieldID ::= SEQUENCE { -- Finite field + fieldType OBJECT IDENTIFIER, + parameters ANY DEFINED BY fieldType } + + -- Arc for ECDSA signature OIDS + + id-ecSigType OBJECT IDENTIFIER ::= { ansi-X9-62 signatures(4) } + + -- OID for ECDSA signatures with SHA-1 + + ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 } + + -- OID for an elliptic curve signature + -- format for the value of an ECDSA signature value + + ECDSA-Sig-Value ::= SEQUENCE { + r INTEGER, + s INTEGER } + + -- recognized field type OIDs are defined in the following arc + + id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1) } + + -- where fieldType is prime-field, the parameters are of type Prime-p + + prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } + + Prime-p ::= INTEGER -- Finite field F(p), where p is an odd prime + + -- where fieldType is characteristic-two-field, the parameters are + -- of type Characteristic-two + + characteristic-two-field OBJECT IDENTIFIER ::= { id-fieldType 2 } + + Characteristic-two ::= SEQUENCE { + m INTEGER, -- Field size 2^m + basis OBJECT IDENTIFIER, + parameters ANY DEFINED BY basis } + + -- recognized basis type OIDs are defined in the following arc + + id-characteristic-two-basis OBJECT IDENTIFIER ::= { + characteristic-two-field basisType(3) } + + -- gnbasis is identified by OID gnBasis and indicates + -- parameters are NULL + + gnBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 1 } + + -- parameters for this basis are NULL + + -- trinomial basis is identified by OID tpBasis and indicates + -- parameters of type Pentanomial + + tpBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 2 } + + -- Trinomial basis representation of F2^m + -- Integer k for reduction polynomial xm + xk + 1 + + Trinomial ::= INTEGER + + -- for pentanomial basis is identified by OID ppBasis and indicates + -- parameters of type Pentanomial + + ppBasis OBJECT IDENTIFIER ::= { id-characteristic-two-basis 3 } + + -- Pentanomial basis representation of F2^m + -- reduction polynomial integers k1, k2, k3 + -- f(x) = x**m + x**k3 + x**k2 + x**k1 + 1 + + Pentanomial ::= SEQUENCE { + k1 INTEGER, + k2 INTEGER, + k3 INTEGER } + + -- The object identifiers gnBasis, tpBasis and ppBasis name + -- three kinds of basis for characteristic-two finite fields + + FieldElement ::= OCTET STRING -- Finite field element + + ECPoint ::= OCTET STRING -- Elliptic curve point + + -- Elliptic Curve parameters may be specified explicitly, + -- specified implicitly through a "named curve", or + -- inherited from the CA + + EcpkParameters ::= CHOICE { + ecParameters ECParameters, + namedCurve OBJECT IDENTIFIER, + implicitlyCA NULL } + + ECParameters ::= SEQUENCE { -- Elliptic curve parameters + version ECPVer, + fieldID FieldID, + curve Curve, + base ECPoint, -- Base point G + order INTEGER, -- Order n of the base point + cofactor INTEGER OPTIONAL } -- The integer h = #E(Fq)/n + + ECPVer ::= INTEGER {ecpVer1(1)} + + + Curve ::= SEQUENCE { + a FieldElement, -- Elliptic curve coefficient a + b FieldElement, -- Elliptic curve coefficient b + seed BIT STRING OPTIONAL } + + id-publicKeyType OBJECT IDENTIFIER ::= { ansi-X9-62 keyType(2) } + + id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 } + + -- Named Elliptic Curves in ANSI X9.62. + + ellipticCurve OBJECT IDENTIFIER ::= { ansi-X9-62 curves(3) } + + c-TwoCurve OBJECT IDENTIFIER ::= { + ellipticCurve characteristicTwo(0) } + + c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } + c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } + c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } + c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } + c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } + c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } + c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } + c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } + c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } + c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } + c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } + c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } + c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } + c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } + c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } + c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } + c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } + c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } + c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } + c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } + + primeCurve OBJECT IDENTIFIER ::= { ellipticCurve prime(1) } + + prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } + prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } + prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } + prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } + prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } + prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } + prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } + + END \ No newline at end of file diff --git a/RFC5280.asn b/RFC5280.asn new file mode 100644 index 0000000..f4ba763 --- /dev/null +++ b/RFC5280.asn @@ -0,0 +1,1030 @@ +PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1) + security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) } + +DEFINITIONS EXPLICIT TAGS ::= + +BEGIN + +-- EXPORTS ALL -- + +-- IMPORTS NONE -- + +-- UNIVERSAL Types defined in 1993 and 1998 ASN.1 +-- and required by this specification + +UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING + -- UniversalString is defined in ASN.1:1993 + +BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING + -- BMPString is the subtype of UniversalString and models + -- the Basic Multilingual Plane of ISO/IEC 10646 + +UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING + -- The content of this type conforms to RFC 3629. + +-- PKIX specific OIDs + +id-pkix OBJECT IDENTIFIER ::= + { iso(1) identified-organization(3) dod(6) internet(1) + security(5) mechanisms(5) pkix(7) } + + +-- PKIX arcs + +id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } + -- arc for private certificate extensions +id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } + -- arc for policy qualifier types +id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } + -- arc for extended key purpose OIDS +id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } + -- arc for access descriptors + +-- policyQualifierIds for Internet policy qualifiers + +id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } + -- OID for CPS qualifier +id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } + -- OID for user notice qualifier + +-- access descriptor definitions + +id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } +id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } +id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 } +id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 } + +-- attribute data types + +Attribute ::= SEQUENCE { + type AttributeType, + values SET OF AttributeValue } + -- at least one value is required + +AttributeType ::= OBJECT IDENTIFIER + +AttributeValue ::= ANY -- DEFINED BY AttributeType + +AttributeTypeAndValue ::= SEQUENCE { + type AttributeType, + value AttributeValue } + +-- suggested naming attributes: Definition of the following +-- information object set may be augmented to meet local +-- requirements. Note that deleting members of the set may +-- prevent interoperability with conforming implementations. +-- presented in pairs: the AttributeType followed by the +-- type definition for the corresponding AttributeValue + + + + +-- Arc for standard naming attributes + +id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 } + +-- Naming attributes of type X520name + +id-at-name AttributeType ::= { id-at 41 } +id-at-surname AttributeType ::= { id-at 4 } +id-at-givenName AttributeType ::= { id-at 42 } +id-at-initials AttributeType ::= { id-at 43 } +id-at-generationQualifier AttributeType ::= { id-at 44 } + +-- Naming attributes of type X520Name: +-- X520name ::= DirectoryString (SIZE (1..ub-name)) +-- +-- Expanded to avoid parameterized type: +X520name ::= CHOICE { + teletexString TeletexString (SIZE (1..ub-name)), + printableString PrintableString (SIZE (1..ub-name)), + universalString UniversalString (SIZE (1..ub-name)), + utf8String UTF8String (SIZE (1..ub-name)), + bmpString BMPString (SIZE (1..ub-name)) } + +-- Naming attributes of type X520CommonName + +id-at-commonName AttributeType ::= { id-at 3 } + +-- Naming attributes of type X520CommonName: +-- X520CommonName ::= DirectoryName (SIZE (1..ub-common-name)) +-- +-- Expanded to avoid parameterized type: +X520CommonName ::= CHOICE { + teletexString TeletexString (SIZE (1..ub-common-name)), + printableString PrintableString (SIZE (1..ub-common-name)), + universalString UniversalString (SIZE (1..ub-common-name)), + utf8String UTF8String (SIZE (1..ub-common-name)), + bmpString BMPString (SIZE (1..ub-common-name)) } + + + + + + + + + +-- Naming attributes of type X520LocalityName + +id-at-localityName AttributeType ::= { id-at 7 } + +-- Naming attributes of type X520LocalityName: +-- X520LocalityName ::= DirectoryName (SIZE (1..ub-locality-name)) +-- +-- Expanded to avoid parameterized type: +X520LocalityName ::= CHOICE { + teletexString TeletexString (SIZE (1..ub-locality-name)), + printableString PrintableString (SIZE (1..ub-locality-name)), + universalString UniversalString (SIZE (1..ub-locality-name)), + utf8String UTF8String (SIZE (1..ub-locality-name)), + bmpString BMPString (SIZE (1..ub-locality-name)) } + +-- Naming attributes of type X520StateOrProvinceName + +id-at-stateOrProvinceName AttributeType ::= { id-at 8 } + +-- Naming attributes of type X520StateOrProvinceName: +-- X520StateOrProvinceName ::= DirectoryName (SIZE (1..ub-state-name)) +-- +-- Expanded to avoid parameterized type: +X520StateOrProvinceName ::= CHOICE { + teletexString TeletexString (SIZE (1..ub-state-name)), + printableString PrintableString (SIZE (1..ub-state-name)), + universalString UniversalString (SIZE (1..ub-state-name)), + utf8String UTF8String (SIZE (1..ub-state-name)), + bmpString BMPString (SIZE (1..ub-state-name)) } + + + + + + + + + + + + + + + + + + + + +-- Naming attributes of type X520OrganizationName + +id-at-organizationName AttributeType ::= { id-at 10 } + +-- Naming attributes of type X520OrganizationName: +-- X520OrganizationName ::= +-- DirectoryName (SIZE (1..ub-organization-name)) +-- +-- Expanded to avoid parameterized type: +X520OrganizationName ::= CHOICE { + teletexString TeletexString + (SIZE (1..ub-organization-name)), + printableString PrintableString + (SIZE (1..ub-organization-name)), + universalString UniversalString + (SIZE (1..ub-organization-name)), + utf8String UTF8String + (SIZE (1..ub-organization-name)), + bmpString BMPString + (SIZE (1..ub-organization-name)) } + +-- Naming attributes of type X520OrganizationalUnitName + +id-at-organizationalUnitName AttributeType ::= { id-at 11 } + +-- Naming attributes of type X520OrganizationalUnitName: +-- X520OrganizationalUnitName ::= +-- DirectoryName (SIZE (1..ub-organizational-unit-name)) +-- +-- Expanded to avoid parameterized type: +X520OrganizationalUnitName ::= CHOICE { + teletexString TeletexString + (SIZE (1..ub-organizational-unit-name)), + printableString PrintableString + (SIZE (1..ub-organizational-unit-name)), + universalString UniversalString + (SIZE (1..ub-organizational-unit-name)), + utf8String UTF8String + (SIZE (1..ub-organizational-unit-name)), + bmpString BMPString + (SIZE (1..ub-organizational-unit-name)) } +-- Naming attributes of type X520Title + +id-at-title AttributeType ::= { id-at 12 } + +-- Naming attributes of type X520Title: +-- X520Title ::= DirectoryName (SIZE (1..ub-title)) +-- +-- Expanded to avoid parameterized type: +X520Title ::= CHOICE { + teletexString TeletexString (SIZE (1..ub-title)), + printableString PrintableString (SIZE (1..ub-title)), + universalString UniversalString (SIZE (1..ub-title)), + utf8String UTF8String (SIZE (1..ub-title)), + bmpString BMPString (SIZE (1..ub-title)) } + +-- Naming attributes of type X520dnQualifier + +id-at-dnQualifier AttributeType ::= { id-at 46 } + +X520dnQualifier ::= PrintableString + +-- Naming attributes of type X520countryName (digraph from IS 3166) + +id-at-countryName AttributeType ::= { id-at 6 } + +X520countryName ::= PrintableString (SIZE (2)) + +-- Naming attributes of type X520SerialNumber + +id-at-serialNumber AttributeType ::= { id-at 5 } + +X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number)) + +-- Naming attributes of type X520Pseudonym + +id-at-pseudonym AttributeType ::= { id-at 65 } + +-- Naming attributes of type X520Pseudonym: +-- X520Pseudonym ::= DirectoryName (SIZE (1..ub-pseudonym)) +-- +-- Expanded to avoid parameterized type: +X520Pseudonym ::= CHOICE { + teletexString TeletexString (SIZE (1..ub-pseudonym)), + printableString PrintableString (SIZE (1..ub-pseudonym)), + universalString UniversalString (SIZE (1..ub-pseudonym)), + utf8String UTF8String (SIZE (1..ub-pseudonym)), + bmpString BMPString (SIZE (1..ub-pseudonym)) } + + +-- Naming attributes of type DomainComponent (from RFC 4519) + +id-domainComponent AttributeType ::= { 0 9 2342 19200300 100 1 25 } + +DomainComponent ::= IA5String + +-- Legacy attributes + +pkcs-9 OBJECT IDENTIFIER ::= + { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } + +id-emailAddress AttributeType ::= { pkcs-9 1 } + +EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length)) + +-- naming data types -- + +Name ::= CHOICE { -- only one possibility for now -- + rdnSequence RDNSequence } + +RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + +DistinguishedName ::= RDNSequence + +RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue + +-- Directory string type -- + +DirectoryString ::= CHOICE { + teletexString TeletexString (SIZE (1..MAX)), + printableString PrintableString (SIZE (1..MAX)), + universalString UniversalString (SIZE (1..MAX)), + utf8String UTF8String (SIZE (1..MAX)), + bmpString BMPString (SIZE (1..MAX)) } + +-- certificate and CRL specific structures begin here + +Certificate ::= SEQUENCE { + tbsCertificate TBSCertificate, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING } + +TBSCertificate ::= SEQUENCE { + version [0] Version DEFAULT v1, + serialNumber CertificateSerialNumber, + signature AlgorithmIdentifier, + issuer Name, + validity Validity, + subject Name, + subjectPublicKeyInfo SubjectPublicKeyInfo, + issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version MUST be v2 or v3 + subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + -- If present, version MUST be v2 or v3 + extensions [3] Extensions OPTIONAL + -- If present, version MUST be v3 -- } + +Version ::= INTEGER { v1(0), v2(1), v3(2) } + +CertificateSerialNumber ::= INTEGER + +Validity ::= SEQUENCE { + notBefore Time, + notAfter Time } + +Time ::= CHOICE { + utcTime UTCTime, + generalTime GeneralizedTime } + +UniqueIdentifier ::= BIT STRING + +SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING } + +Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + +Extension ::= SEQUENCE { + extnID OBJECT IDENTIFIER, + critical BOOLEAN DEFAULT FALSE, + extnValue OCTET STRING + -- contains the DER encoding of an ASN.1 value + -- corresponding to the extension type identified + -- by extnID + } + +-- CRL structures + +CertificateList ::= SEQUENCE { + tbsCertList TBSCertList, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING } + +TBSCertList ::= SEQUENCE { + version Version OPTIONAL, + -- if present, MUST be v2 + signature AlgorithmIdentifier, + issuer Name, + thisUpdate Time, + nextUpdate Time OPTIONAL, + revokedCertificates SEQUENCE OF SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL + -- if present, version MUST be v2 + } OPTIONAL, + crlExtensions [0] Extensions OPTIONAL } + -- if present, version MUST be v2 + +-- Version, Time, CertificateSerialNumber, and Extensions were +-- defined earlier for use in the certificate structure + +AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY algorithm OPTIONAL } + -- contains a value of the type + -- registered for use with the + -- algorithm object identifier value + +-- X.400 address syntax starts here + +ORAddress ::= SEQUENCE { + built-in-standard-attributes BuiltInStandardAttributes, + built-in-domain-defined-attributes + BuiltInDomainDefinedAttributes OPTIONAL, + -- see also teletex-domain-defined-attributes + extension-attributes ExtensionAttributes OPTIONAL } + +-- Built-in Standard Attributes + +BuiltInStandardAttributes ::= SEQUENCE { + country-name CountryName OPTIONAL, + administration-domain-name AdministrationDomainName OPTIONAL, + network-address [0] IMPLICIT NetworkAddress OPTIONAL, + -- see also extended-network-address + terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, + private-domain-name [2] PrivateDomainName OPTIONAL, + organization-name [3] IMPLICIT OrganizationName OPTIONAL, + -- see also teletex-organization-name + numeric-user-identifier [4] IMPLICIT NumericUserIdentifier + OPTIONAL, + personal-name [5] IMPLICIT PersonalName OPTIONAL, + -- see also teletex-personal-name + organizational-unit-names [6] IMPLICIT OrganizationalUnitNames + OPTIONAL } + -- see also teletex-organizational-unit-names + +CountryName ::= [APPLICATION 1] CHOICE { + x121-dcc-code NumericString + (SIZE (ub-country-name-numeric-length)), + iso-3166-alpha2-code PrintableString + (SIZE (ub-country-name-alpha-length)) } + +AdministrationDomainName ::= [APPLICATION 2] CHOICE { + numeric NumericString (SIZE (0..ub-domain-name-length)), + printable PrintableString (SIZE (0..ub-domain-name-length)) } + +NetworkAddress ::= X121Address -- see also extended-network-address + +X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) + +TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length)) + +PrivateDomainName ::= CHOICE { + numeric NumericString (SIZE (1..ub-domain-name-length)), + printable PrintableString (SIZE (1..ub-domain-name-length)) } + +OrganizationName ::= PrintableString + (SIZE (1..ub-organization-name-length)) + -- see also teletex-organization-name + +NumericUserIdentifier ::= NumericString + (SIZE (1..ub-numeric-user-id-length)) + +PersonalName ::= SET { + surname [0] IMPLICIT PrintableString + (SIZE (1..ub-surname-length)), + given-name [1] IMPLICIT PrintableString + (SIZE (1..ub-given-name-length)) OPTIONAL, + initials [2] IMPLICIT PrintableString + (SIZE (1..ub-initials-length)) OPTIONAL, + generation-qualifier [3] IMPLICIT PrintableString + (SIZE (1..ub-generation-qualifier-length)) + OPTIONAL } + -- see also teletex-personal-name + +OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) + OF OrganizationalUnitName + -- see also teletex-organizational-unit-names + +OrganizationalUnitName ::= PrintableString (SIZE + (1..ub-organizational-unit-name-length)) + +-- Built-in Domain-defined Attributes + +BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE + (1..ub-domain-defined-attributes) OF + BuiltInDomainDefinedAttribute + +BuiltInDomainDefinedAttribute ::= SEQUENCE { + type PrintableString (SIZE + (1..ub-domain-defined-attribute-type-length)), + value PrintableString (SIZE + (1..ub-domain-defined-attribute-value-length)) } + +-- Extension Attributes + +ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF + ExtensionAttribute + +ExtensionAttribute ::= SEQUENCE { + extension-attribute-type [0] IMPLICIT INTEGER + (0..ub-extension-attributes), + extension-attribute-value [1] + ANY DEFINED BY extension-attribute-type } + +-- Extension types and attribute values + +common-name INTEGER ::= 1 + +CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) + +teletex-common-name INTEGER ::= 2 + +TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) + +teletex-organization-name INTEGER ::= 3 + +TeletexOrganizationName ::= + TeletexString (SIZE (1..ub-organization-name-length)) + +teletex-personal-name INTEGER ::= 4 + +TeletexPersonalName ::= SET { + surname [0] IMPLICIT TeletexString + (SIZE (1..ub-surname-length)), + given-name [1] IMPLICIT TeletexString + (SIZE (1..ub-given-name-length)) OPTIONAL, + initials [2] IMPLICIT TeletexString + (SIZE (1..ub-initials-length)) OPTIONAL, + generation-qualifier [3] IMPLICIT TeletexString + (SIZE (1..ub-generation-qualifier-length)) + OPTIONAL } + +teletex-organizational-unit-names INTEGER ::= 5 + +TeletexOrganizationalUnitNames ::= SEQUENCE SIZE + (1..ub-organizational-units) OF TeletexOrganizationalUnitName + +TeletexOrganizationalUnitName ::= TeletexString + (SIZE (1..ub-organizational-unit-name-length)) + +pds-name INTEGER ::= 7 + +PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) + +physical-delivery-country-name INTEGER ::= 8 + +PhysicalDeliveryCountryName ::= CHOICE { + x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)), + iso-3166-alpha2-code PrintableString + (SIZE (ub-country-name-alpha-length)) } + +postal-code INTEGER ::= 9 + +PostalCode ::= CHOICE { + numeric-code NumericString (SIZE (1..ub-postal-code-length)), + printable-code PrintableString (SIZE (1..ub-postal-code-length)) } + +physical-delivery-office-name INTEGER ::= 10 + +PhysicalDeliveryOfficeName ::= PDSParameter + +physical-delivery-office-number INTEGER ::= 11 + +PhysicalDeliveryOfficeNumber ::= PDSParameter + +extension-OR-address-components INTEGER ::= 12 + +ExtensionORAddressComponents ::= PDSParameter + +physical-delivery-personal-name INTEGER ::= 13 + +PhysicalDeliveryPersonalName ::= PDSParameter + +physical-delivery-organization-name INTEGER ::= 14 + +PhysicalDeliveryOrganizationName ::= PDSParameter + +extension-physical-delivery-address-components INTEGER ::= 15 + +ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter + +unformatted-postal-address INTEGER ::= 16 + +UnformattedPostalAddress ::= SET { + printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) + OF PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL, + teletex-string TeletexString + (SIZE (1..ub-unformatted-address-length)) OPTIONAL } + +street-address INTEGER ::= 17 + +StreetAddress ::= PDSParameter + +post-office-box-address INTEGER ::= 18 + +PostOfficeBoxAddress ::= PDSParameter + +poste-restante-address INTEGER ::= 19 + +PosteRestanteAddress ::= PDSParameter + +unique-postal-name INTEGER ::= 20 + +UniquePostalName ::= PDSParameter + +local-postal-attributes INTEGER ::= 21 + +LocalPostalAttributes ::= PDSParameter + +PDSParameter ::= SET { + printable-string PrintableString + (SIZE(1..ub-pds-parameter-length)) OPTIONAL, + teletex-string TeletexString + (SIZE(1..ub-pds-parameter-length)) OPTIONAL } + +extended-network-address INTEGER ::= 22 + +ExtendedNetworkAddress ::= CHOICE { + e163-4-address SEQUENCE { + number [0] IMPLICIT NumericString + (SIZE (1..ub-e163-4-number-length)), + sub-address [1] IMPLICIT NumericString + (SIZE (1..ub-e163-4-sub-address-length)) + OPTIONAL }, + psap-address [0] IMPLICIT PresentationAddress } + +PresentationAddress ::= SEQUENCE { + pSelector [0] EXPLICIT OCTET STRING OPTIONAL, + sSelector [1] EXPLICIT OCTET STRING OPTIONAL, + tSelector [2] EXPLICIT OCTET STRING OPTIONAL, + nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING } + +terminal-type INTEGER ::= 23 + +TerminalType ::= INTEGER { + telex (3), + teletex (4), + g3-facsimile (5), + g4-facsimile (6), + ia5-terminal (7), + videotex (8) } (0..ub-integer-options) + +-- Extension Domain-defined Attributes + +teletex-domain-defined-attributes INTEGER ::= 6 + +TeletexDomainDefinedAttributes ::= SEQUENCE SIZE + (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute + +TeletexDomainDefinedAttribute ::= SEQUENCE { + type TeletexString + (SIZE (1..ub-domain-defined-attribute-type-length)), + value TeletexString + (SIZE (1..ub-domain-defined-attribute-value-length)) } + + + +-- specifications of Upper Bounds MUST be regarded as mandatory +-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter +-- Upper Bounds + +-- Upper Bounds +ub-name INTEGER ::= 32768 +ub-common-name INTEGER ::= 64 +ub-locality-name INTEGER ::= 128 +ub-state-name INTEGER ::= 128 +ub-organization-name INTEGER ::= 64 +ub-organizational-unit-name INTEGER ::= 64 +ub-title INTEGER ::= 64 +ub-serial-number INTEGER ::= 64 +ub-match INTEGER ::= 128 +ub-emailaddress-length INTEGER ::= 255 +ub-common-name-length INTEGER ::= 64 +ub-country-name-alpha-length INTEGER ::= 2 +ub-country-name-numeric-length INTEGER ::= 3 +ub-domain-defined-attributes INTEGER ::= 4 +ub-domain-defined-attribute-type-length INTEGER ::= 8 +ub-domain-defined-attribute-value-length INTEGER ::= 128 +ub-domain-name-length INTEGER ::= 16 +ub-extension-attributes INTEGER ::= 256 +ub-e163-4-number-length INTEGER ::= 15 +ub-e163-4-sub-address-length INTEGER ::= 40 +ub-generation-qualifier-length INTEGER ::= 3 +ub-given-name-length INTEGER ::= 16 +ub-initials-length INTEGER ::= 5 +ub-integer-options INTEGER ::= 256 +ub-numeric-user-id-length INTEGER ::= 32 +ub-organization-name-length INTEGER ::= 64 +ub-organizational-unit-name-length INTEGER ::= 32 +ub-organizational-units INTEGER ::= 4 +ub-pds-name-length INTEGER ::= 16 +ub-pds-parameter-length INTEGER ::= 30 +ub-pds-physical-address-lines INTEGER ::= 6 +ub-postal-code-length INTEGER ::= 16 +ub-pseudonym INTEGER ::= 128 +ub-surname-length INTEGER ::= 40 +ub-terminal-id-length INTEGER ::= 24 +ub-unformatted-address-length INTEGER ::= 180 +ub-x121-address-length INTEGER ::= 16 + +-- Note - upper bounds on string types, such as TeletexString, are +-- measured in characters. Excepting PrintableString or IA5String, a +-- significantly greater number of octets will be required to hold +-- such a value. As a minimum, 16 octets, or twice the specified +-- upper bound, whichever is the larger, should be allowed for + + +-- TeletexString. For UTF8String or UniversalString at least four +-- times the upper bound should be allowed. + +END + +PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) internet(1) + security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) } + +DEFINITIONS IMPLICIT TAGS ::= + +BEGIN + +-- EXPORTS ALL -- + +IMPORTS + id-pe, id-kp, id-qt-unotice, id-qt-cps, + -- delete following line if "new" types are supported -- + BMPString, UTF8String, -- end "new" types -- + ORAddress, Name, RelativeDistinguishedName, + CertificateSerialNumber, Attribute, DirectoryString + FROM PKIX1Explicit88 { iso(1) identified-organization(3) + dod(6) internet(1) security(5) mechanisms(5) pkix(7) + id-mod(0) id-pkix1-explicit(18) }; + +-- ISO arc for standard certificate and CRL extensions + +id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} + +-- authority key identifier OID and syntax + +id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } + +AuthorityKeyIdentifier ::= SEQUENCE { + keyIdentifier [0] KeyIdentifier OPTIONAL, + authorityCertIssuer [1] GeneralNames OPTIONAL, + authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } + -- authorityCertIssuer and authorityCertSerialNumber MUST both + -- be present or both be absent + +KeyIdentifier ::= OCTET STRING + + + + +-- subject key identifier OID and syntax + +id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } + +SubjectKeyIdentifier ::= KeyIdentifier + +-- key usage extension OID and syntax + +id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } + +KeyUsage ::= BIT STRING { + digitalSignature (0), + nonRepudiation (1), -- recent editions of X.509 have + -- renamed this bit to contentCommitment + keyEncipherment (2), + dataEncipherment (3), + keyAgreement (4), + keyCertSign (5), + cRLSign (6), + encipherOnly (7), + decipherOnly (8) } + +-- private key usage period extension OID and syntax + +id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 } + +PrivateKeyUsagePeriod ::= SEQUENCE { + notBefore [0] GeneralizedTime OPTIONAL, + notAfter [1] GeneralizedTime OPTIONAL } + -- either notBefore or notAfter MUST be present + +-- certificate policies extension OID and syntax + +id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } + +anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } + +CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation + +PolicyInformation ::= SEQUENCE { + policyIdentifier CertPolicyId, + policyQualifiers SEQUENCE SIZE (1..MAX) OF + PolicyQualifierInfo OPTIONAL } + +CertPolicyId ::= OBJECT IDENTIFIER + +PolicyQualifierInfo ::= SEQUENCE { + policyQualifierId PolicyQualifierId, + qualifier ANY DEFINED BY policyQualifierId } + +-- Implementations that recognize additional policy qualifiers MUST +-- augment the following definition for PolicyQualifierId + +PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice ) + +-- CPS pointer qualifier + +CPSuri ::= IA5String + +-- user notice qualifier + +UserNotice ::= SEQUENCE { + noticeRef NoticeReference OPTIONAL, + explicitText DisplayText OPTIONAL } + +NoticeReference ::= SEQUENCE { + organization DisplayText, + noticeNumbers SEQUENCE OF INTEGER } + +DisplayText ::= CHOICE { + ia5String IA5String (SIZE (1..200)), + visibleString VisibleString (SIZE (1..200)), + bmpString BMPString (SIZE (1..200)), + utf8String UTF8String (SIZE (1..200)) } + +-- policy mapping extension OID and syntax + +id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } + +PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { + issuerDomainPolicy CertPolicyId, + subjectDomainPolicy CertPolicyId } + +-- subject alternative name extension OID and syntax + +id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } + +SubjectAltName ::= GeneralNames + +GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName + +GeneralName ::= CHOICE { + otherName [0] AnotherName, + rfc822Name [1] IA5String, + dNSName [2] IA5String, + x400Address [3] ORAddress, + directoryName [4] Name, + ediPartyName [5] EDIPartyName, + uniformResourceIdentifier [6] IA5String, + iPAddress [7] OCTET STRING, + registeredID [8] OBJECT IDENTIFIER } + +-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as +-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax + +AnotherName ::= SEQUENCE { + type-id OBJECT IDENTIFIER, + value [0] EXPLICIT ANY DEFINED BY type-id } + +EDIPartyName ::= SEQUENCE { + nameAssigner [0] DirectoryString OPTIONAL, + partyName [1] DirectoryString } + +-- issuer alternative name extension OID and syntax + +id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } + +IssuerAltName ::= GeneralNames + +id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } + +SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute + +-- basic constraints extension OID and syntax + +id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } + +BasicConstraints ::= SEQUENCE { + cA BOOLEAN DEFAULT FALSE, + pathLenConstraint INTEGER (0..MAX) OPTIONAL } + + +-- name constraints extension OID and syntax + +id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } + +NameConstraints ::= SEQUENCE { + permittedSubtrees [0] GeneralSubtrees OPTIONAL, + excludedSubtrees [1] GeneralSubtrees OPTIONAL } + +GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree + +GeneralSubtree ::= SEQUENCE { + base GeneralName, + minimum [0] BaseDistance DEFAULT 0, + maximum [1] BaseDistance OPTIONAL } + +BaseDistance ::= INTEGER (0..MAX) + +-- policy constraints extension OID and syntax + +id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } + +PolicyConstraints ::= SEQUENCE { + requireExplicitPolicy [0] SkipCerts OPTIONAL, + inhibitPolicyMapping [1] SkipCerts OPTIONAL } + +SkipCerts ::= INTEGER (0..MAX) + +-- CRL distribution points extension OID and syntax + +id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31} + +CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint + +DistributionPoint ::= SEQUENCE { + distributionPoint [0] DistributionPointName OPTIONAL, + reasons [1] ReasonFlags OPTIONAL, + cRLIssuer [2] GeneralNames OPTIONAL } + +DistributionPointName ::= CHOICE { + fullName [0] GeneralNames, + nameRelativeToCRLIssuer [1] RelativeDistinguishedName } + + +ReasonFlags ::= BIT STRING { + unused (0), + keyCompromise (1), + cACompromise (2), + affiliationChanged (3), + superseded (4), + cessationOfOperation (5), + certificateHold (6), + privilegeWithdrawn (7), + aACompromise (8) } + +-- extended key usage extension OID and syntax + +id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37} + +ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + +KeyPurposeId ::= OBJECT IDENTIFIER + +-- permit unspecified key uses + +anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } + +-- extended key purpose OIDs + +id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } +id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } +id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } +id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } +id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } +id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } + +-- inhibit any policy OID and syntax + +id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } + +InhibitAnyPolicy ::= SkipCerts + +-- freshest (delta)CRL extension OID and syntax + +id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } + +FreshestCRL ::= CRLDistributionPoints +-- authority info access + +id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } + +AuthorityInfoAccessSyntax ::= + SEQUENCE SIZE (1..MAX) OF AccessDescription + +AccessDescription ::= SEQUENCE { + accessMethod OBJECT IDENTIFIER, + accessLocation GeneralName } + +-- subject info access + +id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 } + +SubjectInfoAccessSyntax ::= + SEQUENCE SIZE (1..MAX) OF AccessDescription + +-- CRL number extension OID and syntax + +id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } + +CRLNumber ::= INTEGER (0..MAX) + +-- issuing distribution point extension OID and syntax + +id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 } + +IssuingDistributionPoint ::= SEQUENCE { + distributionPoint [0] DistributionPointName OPTIONAL, + onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, + onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, + onlySomeReasons [3] ReasonFlags OPTIONAL, + indirectCRL [4] BOOLEAN DEFAULT FALSE, + onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } + -- at most one of onlyContainsUserCerts, onlyContainsCACerts, + -- and onlyContainsAttributeCerts may be set to TRUE. + +id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 } + +BaseCRLNumber ::= CRLNumber +-- reason code extension OID and syntax + +id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 } + +CRLReason ::= ENUMERATED { + unspecified (0), + keyCompromise (1), + cACompromise (2), + affiliationChanged (3), + superseded (4), + cessationOfOperation (5), + certificateHold (6), + removeFromCRL (8), + privilegeWithdrawn (9), + aACompromise (10) } + +-- certificate issuer CRL entry extension OID and syntax + +id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 } + +CertificateIssuer ::= GeneralNames + +-- hold instruction extension OID and syntax + +id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 } + +HoldInstructionCode ::= OBJECT IDENTIFIER + +-- ANSI x9 arc holdinstruction arc + +holdInstruction OBJECT IDENTIFIER ::= + {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2} + +-- ANSI X9 holdinstructions + +id-holdinstruction-none OBJECT IDENTIFIER ::= + {holdInstruction 1} -- deprecated + +id-holdinstruction-callissuer OBJECT IDENTIFIER ::= {holdInstruction 2} + +id-holdinstruction-reject OBJECT IDENTIFIER ::= {holdInstruction 3} +END \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..366d71d --- /dev/null +++ b/Readme.md @@ -0,0 +1,123 @@ +# ETSI SSP TTF x509 certificates generation +## Overview +This set of programs and files aims at generating the x509v3 certificates used for the Accessor Authentication Service as described in the annex C of the [TS 103.666 part 1 V15.2.0 (2020-04)](https://www.etsi.org/deliver/etsi_ts/103600_103699/10366601/15.00.00_60/ts_10366601v150000p.pdf) . +## Installation +OpenSSL 3.0.0 shall be installed. The guidline for performing the installation are availabe in [OpenSSL](https://www.openssl.org) +Python Cryptography package shall be installed. The guidline for performing the installation are availabe in [Cryptography.io](https://cryptography.io/en/latest/installation.html) . +## Generation of the private and public keys +The batch file GENKEY.bat contains the OpenSSL instruction for generating the private and public keys acccording to the the annex C of the TS 103.666 part 1. +The following shell command shall be executed. + +`./GENKEY.bat` + +## Generation of the cerficates +The followint command shall be executed. + +`python3 CreateCertificate.py -i */, + aSimultaneousFileSessions 1/* */, + aSimultaneousFileSessionsPerFile 1/* */, + aTotalCapacity 0/**/, + aFreeCapacity 0/**/, + aMaxMetaDataSizePerNode 0 /**/ + } +} + +END \ No newline at end of file diff --git a/certificates/ETSI-SSP-AAA-CA.der b/certificates/ETSI-SSP-AAA-CA.der new file mode 100644 index 0000000000000000000000000000000000000000..c33a81664caee6e89d254f1f201dfbfd8447089d GIT binary patch literal 649 zcmXqLVrn&LV&YlA%*4pV#K>&G#m1r4=5fxJg_+49+K}6TlZ`o)g-w{rEy$49fE&c& z;9&`Hbaph9Fc1TAnR)nKLxMeZgM$Nf9UUEYojnZ&4fsJaTs#~g89o0XcS8XKK9CSM z4?9R*NQj$(oH(zMp#cyY8W{jV6o?CC!nkBw?ns>FRR$t#>|lQ~F|u)Lt1vS&aWFD+ zGbb^yNUknFQK9!`{*3iD%1#}{41s61S$W=iG(r2t9G7O#-RaXjd=pvP!jByYI&883 z@D;iE6%9el6I9P8`&ODS+nXbM>dtOs-qw5@i5_(=WvSN>gg%S>Uvph)nq%GEJ#T+! zaV>6~Z_qf$z!(@DvI>lh|5-E*)D2YG*jO0m1TiuhNE=A9acHwKva+%>F&XgkaA&6I z7Uk!pg2L872&73Eq>00T4M;IDG8ia<#FRl|zzAs&Ir}{K+ac5a%b9w_gr$!@V}8@K z*4;oBq=t`0j75akXwpO00&(-YiG>jriuH@*x$;cGQ6tL_G6ERu>5-W~V`u%nd-Q_)*3>0xALqR(47uf;%JsC#m1r4=5fxJg_+49+K}6TlZ`o)g-w{rEy$49fE&c& z;9&`Hbaph9Fc1TAnR)nKLxMeZgM$Nf9UUEYojnZ&4fsJaTs#~g89o0XcS8XKK9CSM z4?9R*NQj$(oH(zMp#cyY8W{jV6o?CC!nm}xyvjg?jUDVyCPp?+Z53u_CJshMZssHg z7T5a=Hf8MQ;m+78a8u&PuTZP(XBRJhIm@(C-_H4E?K-vXtKYv&FgxnIww~)rfpGg? z_LkHh8{X4TS8Y45cxsVt5&s+CUAt!&`abzkGvQ53;KKlotYcRj*UCNYW(m~S+*z`? zah5^jbOSwLaL6h!GX7^#F;Fs4U}I%rm=nZkAZ{Sa#-Yu|$jZvj#ALw9!=9Op0=0pp@UyE#m1r4=5fxJg_+49+K}6TlZ`o)g-w{rEy$49fE&c& z;9&`Hbaph9Fc1TAnR)nKLxMeZgM$Nf9UUEYfii*y{2&=F9uAOdm#M zueY~+;?i}WEuMSlZN}o;W$vHmM6FYpuA=^jL1)MEWuJnY5`O%)T~r#wtknCC^>12! z*W$)y291ji9DuU#76Z@MRAvJA`NxMuV?=dpEI3dd#GbV(~adfW-3qL zy?8#7dfV1tSac5Dt4!9ujalFYkLnbeJ9EP N$T4Go=Nra5Zvj=HyaNCL literal 0 HcmV?d00001 diff --git a/certificates/ETSI-SSP-AAA-EE.pem b/certificates/ETSI-SSP-AAA-EE.pem new file mode 100644 index 0000000..71fb971 --- /dev/null +++ b/certificates/ETSI-SSP-AAA-EE.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjDCCAhOgAwIBAgIBBTAKBggqhkjOPQQDAjBbMQswCQYDVQQGEwJGUjENMAsG +A1UECAwEUEFDQTEYMBYGA1UEAwwPRVRTSS1TU1AtQUFBLUNBMREwDwYDVQQKDAhF +VFNJLk9SRzEQMA4GA1UECwwHU1NQLVRURjAeFw0yMTAxMDExMjAwMDBaFw0yMTEy +MDExMjAwMDBaMFsxCzAJBgNVBAYTAkZSMQ0wCwYDVQQIDARQQUNBMRgwFgYDVQQD +DA9FVFNJLVNTUC1BQUEtRUUxETAPBgNVBAoMCEVUU0kuT1JHMRAwDgYDVQQLDAdT +U1AtVFRGMHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABFkioLYXBNIajFonWCMA +u3cm60mtK92FX8s0khiM3ycpqjTtrljbbZOMbSeDfcvXh4TyCi1Hmxdt3O1oo9t2 +R/KcWq4glyQn/AAsuKem8lKCYPj7PaJ1XAMije4F/WZviqOBpjCBozBABgNVHSAB +Af8ENjA0MDIGBwQAnFIBAgEwJzAlBggrBgEFBQcCAjAZDBdpZC1yb2xlLWFhYS1h +cHBsaWNhdGlvbjAMBgNVHRMBAf8EAjAAMCIGA1UdIwEB/wQYMBaAFA0ykuEFcBc3 +fpFxWHghf6NfCm41MB0GA1UdDgQWBBTcNg23ofa8FZoZ/W4rQKUQmK6BhjAOBgNV +HQ8BAf8EBAMCB4AwCgYIKoZIzj0EAwIDZwAwZAIwdD7M2KiiRTzYrGGBJ2khF0T2 +FIB+M+ub+BeclwC3VUFggtin2Jkjl7ujoFfCcoTHAjB/HSO5kkBqagLvuLirk1jq +LtEIl9F6cIqVFtyKvSm+8K2Nw6XuGQ/iQWi/iewB3O0= +-----END CERTIFICATE----- diff --git a/certificates/ETSI-SSP-AAS-CA.der b/certificates/ETSI-SSP-AAS-CA.der new file mode 100644 index 0000000000000000000000000000000000000000..251a842db13b6623b22b409fa20bbd8ce55834a1 GIT binary patch literal 649 zcmXqLVrn&LV&YlA%*4pV#K>&G#m1r4=5fxJg_+49+K}6TlZ`o)g-w{rEy$49fE&c& z;9&`Hbaph9Fc1TAnR)nKLxMeZgM$Nf9UX&pojnZ&4fsJaTs#~g89o0XcS8XKK9CSM z4?9R*NQj$(oH(zMp#cyY8W{jV6o?CC!nkBw?ns>FRR$t#>|lQ~F|u)Lt1vS&aWFD+ zGbb^ybbqg8`Vzlj*8IxlG5YUsKYz*dftm5b{2S4m+4fmaOR|_UwJ>6;jC#p|Niy>$ zCWTc5amNRkq?)P7Gw)O{+YzMn=j8N9(|$gUieUXx$z$xXy|Cf7riD+Dlgm;O&bG}g z{)-#u8#K-_Fa`#PtO6tBe-=#xbpus4HWr3CL5z$B(gu=j9NKJ*tgP%zOa{C>+?gr5 zMfo|Yx`~O!20|cB!XQl?25dlziIKrT2_&Wr5(7p^gUH$Ex!(?%?qAN-BPJ|;^cnM; zp0(}sC#m1r4=5fxJg_+49+K}6TlZ`o)g-w{rEy$49fE&c& z;9&`Hbaph9Fc1TAnR)nKLxMeZgM$Nf9UX&pojnZ&4fsJaTs#~g89o0XcS8XKK9CSM z4?9R*NQj$(oH(zMp#cyY8W{jV6o?CC!nm}xyvjg?jUDVyCPp?+Z53u_CJshMZssHg z7T5a=Hf8MQ;m+78a8u&PuTZP(XBRJhIm@(C-_H4E?K-vXtKYv&FgxnIww~)rfpGg? z_LkHh8{X4TS8Y45cxsVt5&s+CUAt!&`abzkGvQ53;KKlotYcRj*UCNYW(m~S+*z`? zah5^jbOSwLaL6h!GX7^#F;Fs4U}I%rm=nZkAZ{Sa#-Yu|$jZvj#ALw9!=9Op0=0pp@Uu6EbE69xdn+PV1v literal 0 HcmV?d00001 diff --git a/certificates/ETSI-SSP-AAS-CI.pem b/certificates/ETSI-SSP-AAS-CI.pem new file mode 100644 index 0000000..9258ebe --- /dev/null +++ b/certificates/ETSI-SSP-AAS-CI.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICfzCCAgegAwIBAgIBATAKBggqhkjOPQQDAjBbMQswCQYDVQQGEwJGUjENMAsG +A1UECAwEUEFDQTEYMBYGA1UEAwwPRVRTSS1TU1AtQUFTLUNJMREwDwYDVQQKDAhF +VFNJLk9SRzEQMA4GA1UECwwHU1NQLVRURjAeFw0yMTAxMDExMjAwMDBaFw0yMTEy +MDExMjAwMDBaMFsxCzAJBgNVBAYTAkZSMQ0wCwYDVQQIDARQQUNBMRgwFgYDVQQD +DA9FVFNJLVNTUC1BQVMtQ0kxETAPBgNVBAoMCEVUU0kuT1JHMRAwDgYDVQQLDAdT +U1AtVFRGMHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABEXfoLJouwwLaLkQ2Rj4 ++lU6a+bR0vTNAqkvPkPpfa4mt6vv6WA2xU2tfwrkcBOHvQeEZYw8DcvlqrbPIcqi +PXIP7E26u5txTeTwfJDshFHhUChqxtWBrR7hiwRRLym5dKOBmjCBlzAuBgNVHSAB +Af8EJDAiMCAGBQQAnFIBMBcwFQYIKwYBBQUHAgIwCQwHaWQtcm9sZTASBgNVHRMB +Af8ECDAGAQH/AgEBMCIGA1UdIwEB/wQYMBaAFM3nbfbCNb+nAowWExvF5gPsjK1H +MB0GA1UdDgQWBBTN5232wjW/pwKMFhMbxeYD7IytRzAOBgNVHQ8BAf8EBAMCB4Aw +CgYIKoZIzj0EAwIDZgAwYwIvNut9Mbtrj9qE3il1bVLZUI9ogkMR6HzqNlgSwnzY +sQ4m6NIVRGxCc+qza83/h9wCMDsqWeBQECwjVGQPPTRTrcbdVl1LUv/iKTMFQxdV +1sbO7yH8vUnGaL5D5DN7Ry7cVg== +-----END CERTIFICATE----- diff --git a/certificates/ETSI-SSP-AAS-EE.der b/certificates/ETSI-SSP-AAS-EE.der new file mode 100644 index 0000000000000000000000000000000000000000..f8e4e65c6eb80af8b821f66b422ec2d343664781 GIT binary patch literal 652 zcmXqLV(KtxV&Y%G%*4pV#K>yE#m1r4=5fxJg_+49+K}6TlZ`o)g-w{rEy$49fE&c& z;9&`Hbaph9Fc1TAnR)nKLxMeZgM$Nf9UX&pfii*y{2&=F9uAO#?!3Fw6;JWMni@Hc({a&}L&~Wo2h#G7#kv&P>rQ z%FjvFO-wA-Elw>e%S=u+-~s6t2I*!pU@%Yu@svS4V4O6FTs8gnW&Mh6g3PlR-dZI# zEnrwV!OTDwq=t`0j77xEaqYBb86%b2@Ry4&Mx_NU>$&+H96Pf7AR~Yg&)$HX44Bgy z3{sd3953~)Z`FOZ{gA{B>)mZXp508_d$;0b%p8-BSMSW%$}g9{EV3wV#Zl#iZR`FO zF=oGHGEj&sTzca?pFu+d!}i1chnF8X&JeqGK~+z~9=4T}IxFU`({U>^>a~v-dse=7 IA>… \ No newline at end of file diff --git a/credentials/CP_AAA.der b/credentials/CP_AAA.der new file mode 100644 index 0000000000000000000000000000000000000000..28dbba187ff4dbf38ec6d40fbe570fdadd8d9f7f GIT binary patch literal 1953 zcmXqPVxMc!#MA)9>}um$xrf~>f%=*| zOBOfIGH9G`pa%>NSp`PM|12s7N(KsStSk(3f*1|N4Mf>EwAmP0S=pJG3^;k%GgEYn z@^exRgh1+rLFzdS*nku$u9QGx${;adTr`NBeV+U6km>&AOg&=4(np^$zv)@)ZXgR% z!^a}Vf?XOEE3*6`BY+Xk-hdqa%;^jUDNF{jJ0pH~ynM|ayj8$iCfjupOJsn5b(^oo zd!=a;f9PixY2A_24!)Nt`oFNKP$GM#Hj_bF*2YaQ)&}NAB;226_|nqSrdvUBi`iV2 zS*}eDKdmzM3BGaqv-j-HulCiPrza<5CIZu6D-iQQ(;zdlBWRlpXp;sViOT?Z(xBw( z@)H$$U*^wPZ=>wgQOpo{W}B7gtw$5IU(9i7_S~I5&BHg5r7ir}fuO?{`ww4{i(k3w~^>k*HV^x{Xpom$p1Chm8Ln?&E50%cNW*;#`y+~ za}10@kq=ITng;3ys%&iFG{|HiZ6Jx12zhz9p@|Tbzp*4l1`-n@uhFE3tOercbrTCC zDirG%$8+VGf{O?I2{A=D|BLC7nLlG^{k?nig8SCgC2Ak%y(tX2<($g**VWxx%T(R) z#?NgVQ+dys%sE}+!DOIicE0WF>}$Lo>kcoJvOC-VxV`MyF_xQlR#xSco@@9V**e4i zZ;;1xJ{`Tqo4y1YX95#p4-gAO6Cx`W5+adlfhGyj)s^Ce7^$>in>foQsh%kH2xW%d zbrTB;ax#+>OEUBG40u2$fQv^a1B~>DHNhbY#ye)b+ZTS@ zBRWg+Z=SZpQh^!k8rz6Sk0o|zZmd}3YI9>vVxxMdqPWX9k%l_s*Ry|!&za7!J=8Iw z>BjOKGnJ?BUc4auP*KZqCWCre<(-opva*=o@7S?=a>OgWiyYH0Ruyzj6}!{5S99No VwY`UzzLVsC}um$xrf~>f%=*| zOBOfIGH9G`pa%>NSp`PM|12s7N(KsStSk(3f*1|N4Mf>EwAmP0S=pJG3^;k%GgEYn z@^exRgh1+rLFzdS*nku$u9QGx${;adTr`NBeV+U6km>&AOg&=4(np^$zv)@)ZXgR% z!^a}Vf?XOEE3*6`BY+Xk-hdqa%xMe;$xQlYuWJo=XZPP~xu;p08+0?EKcmT6@I}ol zvk0L>H8(c$slB))>XPGB{AzRd+5hc#m<+77A|C_@=qQJz@Y|XMuRV4*EY>^d|07Lf zR%h|hYsb#LSNyZr^H|0{=O@P1?s|8^fXS~Fh@En1M?NT zeUtF3|HjaA}W-osi7INzeO#91SeY zHJEcUh*xbs(}CSW?d}daTSAPhm#bU1J5EeLo3Ph>+ZxB|UR~ZHiyIdi0MnukJRyRr z0zEc%NJ3;ZP&QCRN{OO8!bmAmw>Y(^EHgRPfCr=-Trx5lV5CK?i49REnmMkW)+}SB zQXBqq(Z#5=pk+NbpA(T59WV8*Z`FOZ{gA{B>)mZXp508_d$;0b%p8-BSMSW%$}g9{ zEV3wV#Zl#iZR`FOF=oGHGEj&sTzca?pFu+d!}i1chnF8X&JeqGK~+z~9=4T}IxFU` U({U>^>a~v-dse=7AY>{G%?C7Xk6aF$Y2ma zshFf4k6WtVaBHKcMSpp%qnLZ4zkx)9fX&avmkSTMn@?)@)@--4Yi(p?Y+__s$;HM2 zwv&aKX@!D;92;|}tTH3xe-@EDX1v=Me%m8DOY(1?w!>0^8S5I`79y!$l)_}-)X1)H zvOvb^)7{F1lQ*N7H<+8`&WkAi`R76Roac*Tw?EslLDpz_-Iu4oBnud4o9t&Y5Yh~6 z%zh<5Lt4FOgKU`W!pHnU*B`FZkUy{HcsOx(hq>B=@e&o1(vy$l2$)-wv7X zU(VDcCMA^*NZA{Zqn|mQ!2p;JV|PaU?s)l{ zJ9w*rvrM+@B9_Pi|LQhhjrU5^CjQXREYi9oryYDRQS^UdQK3ZkOl>BEvaF4pUaSqw zjYzmZ%kZV8rA@bj=S(B^k?tcn_um#IZsbc$V>#Lzg8gTfu=!b zWJl088PFyTIue%w@T5V>)#WED^uElWvED}6siT-7@XR(V&s&csXup`_((JiAeVT`F zB1>ENu>(PeE%qP2A{W1+A!vDm>e*!9O7mrVb7W85*=@|*nr|b~qpqba_4MpP))FOKKRGX)n9_!DA^aQ+w5BQt--&iZ@z=mqz!sY}#8 z&U;fBa?3fD@2{)7wU(*6;f!8UQ0OHw^i>JiEeyUW#Hd#=^K+Zun`WRgVBeRa)MCU4h8+|HfcldIlbd-{5N z%O@^f_u1mPciv_!zFp@2X-?ESh3P8le;9OjEMN91s43ycZ`(zsG0aN6?^yq)<##P^ zTxQU?*uVjv5X}rs42;;=AqkNYoGKB;p(KwuEF~r;Ch8^@6y#(kCzfR9=Na&TOaK>; zOa>U~5o>}&6pYwvV>uKDrZa30bxdfw zvHZqN<>|W@F9<(W)N-83pk7va=Ol-$ET;E6cC4Np@k;L^$MlO;1zl6c?sV5jXX6)~L!+7T{0M75G+5i9m literal 0 HcmV?d00001 diff --git a/credentials/aAAS-OP-AUTHENTICATE-Service-Response.der b/credentials/aAAS-OP-AUTHENTICATE-Service-Response.der new file mode 100644 index 0000000000000000000000000000000000000000..6b5775f92b85ec7455a7f990baa9969be053b522 GIT binary patch literal 300 zcmYdnV$@jL#Hg~ciBSQFWfn9pZ(w9Fh%yjiW7lf)IA_bm$i}Iy!pzLX!N|zY?8Ly5 z@JD0A&O0|R+WxmcQ`x<$Q*Yz{_Ttz-mOqZ{Kh!ewupMtApRh=cM?1gTo~>L$hoW}Y z`m0S=5Bsj;>LJ(t&+NQ`M1z2!?d_@Oc6(PXQc?SBx#^riBO_xIBg0BAHV&|zEX+(R z6b$6pm_uci85#exh?qI9oz^U4q*5FHa?!=8w4h}@H=i#=QoSgJ$skcv@Qu~?a|@Pr z?O}*rByr&2|GNi|t><9rmiYCyywga)de)}qDRKVu%-G-Rockdv?ZCx ud~#CWocj_X&8XOavNJh^;$lXxDfDa_Z&BG2-7ZT!TAScdiWM}|{hDHWJ z5C!4_nJ_MGEw3^VVPgmTlZlayQ(J|ZnTdmuk()V*fyMRyf=wB_dAKun3fz?V@hj9S z``N`yU(PbE)VFhfS-Vbc`|9^E6U>hKuC3>KQXt&Em%Sym$AYN`9VeiBb>bfIr^E? z7z~n`^vzz^8t%^SztwV2vots8W~2`BchLVwn#Qco;-S}$oqMnNXRqh6jD5~ejH})C z?t}r8Un>yvK$9RdvKwfd3TTrA9f?c-c#>fE_e!QO@e5|nuUsCZ|Ni##mpmVs886Jg z5xtphpY^mPiz!nJBc{rzmmHWRGjC#2SVa(be1J)+nTkB~PW7@KK}vs4PJcA*=hLVN z)-RPj#va=X8*Xb__!K$0EEVBw+sxv>xN*Kg;~WEHP~3x)pr(PkfhrptI0-TuNE=8Z zr9oaEZfF|RO-wAtk`5V2OovxZzkON1Vw)iIEQYsMiA@U_R!%SjmkzknVLF3B3X_4# z#+|HZTpDm^USj@n0xHgB0Te^JKQW5Q_d#;P@QrHgYgb?* z>;PhZXhLMALP8`mEzl$(y1G)F5ECY(6rSSbUvB#*;aC5Sx!K2xeoi)C`h@A`Q_0Kk znEZ}zxwT~afixyV#t`As9uYesnS+y__y0H=SeR=t=VTDC+I*%1yM@}_9dfpW7*{V> zw{CZwn0_{4ulcq$j?=xmyh9c@E;0b7MH_fR1XTrkZ0wMP$Y`K!poo+bMR|mgQlf5g zYEfBca;gCjNH@4-WHP`=i&zsIqD(Y%Tsy5<#z>_${NRaEc z`)d0ki5u3t+kQN|nYQ!E`M2MQQC^5$_d-n{VQV3e#vB@5LdYL y#(6%2h6aZ1hxrdLKX9BOcI$$wo`yYaD<^eU%w4DBR%X;|A20T-eCgQ)opm+uIc90tgwKRcW7wUW}_l1)9 z0|NpG0Rac0L<2$q1S)dZb4(DxG@f?3xyc6TMt=9iG|HT#9QZq7B=F_7rybmco}gC# cYfA_LIwUk^$6lo;fZDMsIFEOIK^8}GPu>795C8xG literal 0 HcmV?d00001 diff --git a/private_keys/ATK-AAS-ECKA-private-key.der b/private_keys/ATK-AAS-ECKA-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..7b5f90aab5c133326d296532ce643b6209fb8139 GIT binary patch literal 122 zcmV-=0EPcBcme?d1Ry+$^k6g(O~-X4=7S9%zd}r4HP60ORKx4M-Z+Bip^u;o1_>)9 z0|NpG0Rac0L<2$q1ZSB#f%OZ0pN5HmEX#NY!Kz&T8W6_b=tlp&qrHSGhJ{5+%y|&1 cVv4ddtj1p}(Sw`f8#|ctPs%NNWl4|R0zxP=NB{r; literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der b/private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..a4d330ed45087fce759e118497bd98e70cfe1f34 GIT binary patch literal 171 zcmV;c095}lfv5rj0R%8W({~61IVPFAv)T6Kn*)I^y0!OdiTmcwm9yh+@8RrNP7L^7 z(uXlwwZJPiAA-}M3kC@*Bm)Bi2mt{Lp=1MM00bOnY#5`LJse*)WJU48na~cYN+q&E zHPfUp&}v*4ZZhS}V$997u89^+JmoX3?8PxDLfegppyUfklgJjP5DeFIN1KEi>l*({ ZmFa|rgLyVz@2Xhp4xBaK6L<&Z8;$i2Ob!45 literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.pem b/private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.pem new file mode 100644 index 0000000..6523c2f --- /dev/null +++ b/private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGoAgEBBDA8wK4BXTmZTCypQrC3T2Qp1e8fhznxxZj0gLCl7Fib3Os2Dcin9t7i +j9B5nUc1bXmgCwYJKyQDAwIIAQELoWQDYgAEGat3yHgu9J+YrzwjQohzAFHMtjpJ +2uKQK+icRINJu2eWSE1hBIZXxsBSwzi/w9QeX6iAUqdgJc1jTXk3pr1sHcrcuzMN +hW88GIwnKiMa6+AS8xT/rNcilkF+nbzt+2oK +-----END EC PRIVATE KEY----- diff --git a/private_keys/ETSI-SSP-AAA-CA-private-key.der b/private_keys/ETSI-SSP-AAA-CA-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..bb24e2993985a33d4929ff02fd3bed85357bce27 GIT binary patch literal 171 zcmV;c095}lfv5rj0R%8Sz^(yZIhjl>sY0-~Ph=_8?;nRb@x_?*fUu?PSexAIHVw$9 z_TJ);(0QFlHEnsI3kC@*Bm)Bi2mt{Lp=1MM00bGUcgT1y^q-ioJR?Gga{y7ywmM1L z;*cxooJ503yJwb2O<@FvSH{3n!#Kag)E-}`fKsPmCCy_^c{irLY#qwnyE6@iZ#)=` ZCn_Tv>);ae6#uN(B9=jZoxJV)Y6{yxOilm* literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAA-CA-private-key.pem b/private_keys/ETSI-SSP-AAA-CA-private-key.pem new file mode 100644 index 0000000..6523c2f --- /dev/null +++ b/private_keys/ETSI-SSP-AAA-CA-private-key.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGoAgEBBDA8wK4BXTmZTCypQrC3T2Qp1e8fhznxxZj0gLCl7Fib3Os2Dcin9t7i +j9B5nUc1bXmgCwYJKyQDAwIIAQELoWQDYgAEGat3yHgu9J+YrzwjQohzAFHMtjpJ +2uKQK+icRINJu2eWSE1hBIZXxsBSwzi/w9QeX6iAUqdgJc1jTXk3pr1sHcrcuzMN +hW88GIwnKiMa6+AS8xT/rNcilkF+nbzt+2oK +-----END EC PRIVATE KEY----- diff --git a/private_keys/ETSI-SSP-AAA-CI-private-key.der b/private_keys/ETSI-SSP-AAA-CI-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..7e86bf44f94fbba6a0560367a0a89883e3475afa GIT binary patch literal 171 zcmV;c095}lfv5rj0R%9LnAH``0LKc2P$_JNjZ)f({EoO=RyG$auw@*|-ubYIl67=F!sh z%>t<}K11n!t|qsu@9AJR#Z9e$3gmDThrI`cWsE!x%jK%J&mqd9J#r81O}e|AaZTj# Ze30yfQQ=T1YR1)ptsdcv1W_+3xpa5AO_u-w literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAA-EE-private-key.der b/private_keys/ETSI-SSP-AAA-EE-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..0057a0e0dd40d35d0462c78d8518ef14196b5f48 GIT binary patch literal 171 zcmV;c095}lfv5rj0R%8+AxG9qZgq`Z5l?XFncZIg^`Cxd;<*N24i3N1&Q7j4|_XrtS9NAjFnt{|5rC;R{` ZxTmJ_Qi5Rk`#qv{TmvGF?gjm3Z;HJnOsD_= literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAA-EE-private-key.pem b/private_keys/ETSI-SSP-AAA-EE-private-key.pem new file mode 100644 index 0000000..0f0723c --- /dev/null +++ b/private_keys/ETSI-SSP-AAA-EE-private-key.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGoAgEBBDBmIUfWSm51jVzkA1d/aszqEpsMyDP91t9or5WXR5by1O/J8d/MGvmH +LcObgBSJhpegCwYJKyQDAwIIAQELoWQDYgAEWSKgthcE0hqMWidYIwC7dybrSa0r +3YVfyzSSGIzfJymqNO2uWNttk4xtJ4N9y9eHhPIKLUebF23c7Wij23ZH8pxariCX +JCf8ACy4p6byUoJg+Ps9onVcAyKN7gX9Zm+K +-----END EC PRIVATE KEY----- diff --git a/private_keys/ETSI-SSP-AAA-Token-private-key.der b/private_keys/ETSI-SSP-AAA-Token-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..597a1c3d818cfff4c8179b6eddc8e017b67a628a GIT binary patch literal 122 zcmV-=0EPcBcme?d1R#+&ri7^n(PkkA=XOJ&ER1_>)9 z0|NpG0Rac0L<2$q1X@nXxKHsd>BH)D0~97g?rbpqig~r(7@Z+vn*F@B;zR zpV(Wo2EIF%VmOqQaaffcCv?D)9G;P4R(MhiUr;n4xm*STB=F!sh z%>t<}K11n!t|qsu@9AJR#Z9e$3gmDThrI`cWsE!x%jK%J&mqd9J#r81O}e|AaZTj# Ze30yfQQ=T1YR1)ptsdcv1W_+3xpa5AO_u-w literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAS-EE-private-key.der b/private_keys/ETSI-SSP-AAS-EE-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..c9ab68b1b1c9d1ccf3e9601c12f39699d57dee8e GIT binary patch literal 171 zcmV;c095}lfv5rj0R%8P1`?>Vq)Uq!)z*V-2sPoeZx0Y zdxI1C6R<;lKg`RZ3kC@*Bm)Bi2mt{Lp=1MM00dx=WO2#~52rosVET{PoomK&`I9rH zE0xFr3L!4JMxgz`GKMM?h?} ZR5N?0Cp(8hk!Q_dy*IY3L6=I3OH_DrNIU=l literal 0 HcmV?d00001 diff --git a/private_keys/ETSI-SSP-AAS-EE-private-key.pem b/private_keys/ETSI-SSP-AAS-EE-private-key.pem new file mode 100644 index 0000000..51ce8d4 --- /dev/null +++ b/private_keys/ETSI-SSP-AAS-EE-private-key.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGoAgEBBDA5BhKos6R4rCkV0z4wa0ba/sML/+G9dXI5w2wqb90Bh3Z9wzdUe4MT ++ROwQ30/zMugCwYJKyQDAwIIAQELoWQDYgAEYJBkccoJD6c97GD6j9ida8Zy+ZMz +peQC2eUZ0+4CTsW02qSXwGYCMQFUE3WMFD4SHMGS54/4xVFxbTCcyVINJp8CwLsS +h0dAbLRUM3unJzuHQZFnzWC9N7asQZdKiktU +-----END EC PRIVATE KEY----- diff --git a/private_keys/ETSI-SSP-AAS-Token-private-key.der b/private_keys/ETSI-SSP-AAS-Token-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..bd6724013ae880a479dc614f7f13b89b3200106d GIT binary patch literal 122 zcmV-=0EPcBcme?d1Rz<6{(VV$?ualI*L^CKlPP;_zf9avRV_Ah$jpHaPa>cT1_>)9 z0|NpG0Rac0L<2$q1Rf{O)90|NpG0RamGVgLjjW^5RvmpvR`He^Nd!I{tw zsY)fXK{eB)FwkmT7j81;%wo*Vw62L3O+4i@t?b1yDMH(ghoIyONR!AGrVtF*b4Qzm e8tWSWOO@$_hJ$%FU+=0|>JFSW-V=BS)90|NpG0RamGVgLjgt9QtFF7%(6uRJ3{h;sl@ z%(gm7+TxHa=$u4@NxNs3NKIh`hF8YGQo}gE!_*#MsDM(ZU?t6CO?fw_y=)!I+`BUk eg>O6)90|NpG0RamGVgLk1-=MN+y9^6xxe(bH`1(~k zYv$3?^vwdPFFr%*eXb_AtMBPxHpNY?e+uMq6NkMAgk_984a?=Kw$CBTqCIjC>`l76 en{iF#@O+T$gi+y8C~C&lfvq0liv&?GDY)90|NpG0RamGVgLkLBA~Vx1kxIeS|?Z|0K0c4 z>q)IE-GyJvG?EyM-zO=mH0`cf+ijDKZ6||$%h!j5@(L|Sn-^`|?P#Ohc1QA@TCO0M eBq#g;EV!qp@=}6e`1?JgbzB1?jqU~gW^alL|1r`4 literal 0 HcmV?d00001 diff --git a/public_keys/ETSI-SSP-AAA-EE-public-key.der b/public_keys/ETSI-SSP-AAA-EE-public-key.der new file mode 100644 index 0000000000000000000000000000000000000000..2b1e1a4ea9596b859dff1ff1b4036c38500463d1 GIT binary patch literal 124 zcmV-?0E7Q9dN33Q2P%e0&OHJF1_>)90|NpG0RamGVgLkLBA~Vx1kxIeS|?Z|0K0c4 z>q)IE-GyJvG?EyM-zO=mH0`cf+ijDKZ6||$%h!j5@(L|Sn-^`|?P#Ohc1QA@TCO0M eBq#g;EV!qp@=}6e`1?JgbzB1?jqU~gW^alL|1r`4 literal 0 HcmV?d00001 diff --git a/public_keys/ETSI-SSP-AAA-EE-public-key.pem b/public_keys/ETSI-SSP-AAA-EE-public-key.pem new file mode 100644 index 0000000..fcf93a3 --- /dev/null +++ b/public_keys/ETSI-SSP-AAA-EE-public-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABFkioLYXBNIajFonWCMAu3cm60mt +K92FX8s0khiM3ycpqjTtrljbbZOMbSeDfcvXh4TyCi1Hmxdt3O1oo9t2R/KcWq4g +lyQn/AAsuKem8lKCYPj7PaJ1XAMije4F/WZvig== +-----END PUBLIC KEY----- diff --git a/public_keys/ETSI-SSP-AAS-CA-public-key.der b/public_keys/ETSI-SSP-AAS-CA-public-key.der new file mode 100644 index 0000000000000000000000000000000000000000..4d8cd257ec8e6472b52d15cf920bf0cc76621050 GIT binary patch literal 124 zcmV-?0E7Q9dN33Q2P%e0&OHJF1_>)90|NpG0RamGVgLk-_jv;JU!a)90|NpG0RamGVgLk1-=MN+y9^6xxe(bH`1(~k zYv$3?^vwdPFFr%*eXb_AtMBPxHpNY?e+uMq6NkMAgk_984a?=Kw$CBTqCIjC>`l76 en{iF#@O+T$gi+y8C~C&lfvq0liv&?GDY)90|NpG0RamGVgLkSkYsVn2@j_|>|pwj*qv*} za`}@prQ`zHHZx ehetqcv{W;DrzbmyL6K+8V7)iCtU;Gbic3_vh%qDp literal 0 HcmV?d00001 diff --git a/public_keys/ETSI-SSP-AAS-EE-public-key.pem b/public_keys/ETSI-SSP-AAS-EE-public-key.pem new file mode 100644 index 0000000..e4b6299 --- /dev/null +++ b/public_keys/ETSI-SSP-AAS-EE-public-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABGCQZHHKCQ+nPexg+o/YnWvGcvmT +M6XkAtnlGdPuAk7FtNqkl8BmAjEBVBN1jBQ+EhzBkueP+MVRcW0wnMlSDSafAsC7 +EodHQGy0VDN7pyc7h0GRZ81gvTe2rEGXSopLVA== +-----END PUBLIC KEY----- diff --git a/public_keys/ETSI-SSP-CI-public-key.pem b/public_keys/ETSI-SSP-CI-public-key.pem new file mode 100644 index 0000000..d1fa2b9 --- /dev/null +++ b/public_keys/ETSI-SSP-CI-public-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABEXfoLJouwwLaLkQ2Rj4+lU6a+bR +0vTNAqkvPkPpfa4mt6vv6WA2xU2tfwrkcBOHvQeEZYw8DcvlqrbPIcqiPXIP7E26 +u5txTeTwfJDshFHhUChqxtWBrR7hiwRRLym5dA== +-----END PUBLIC KEY----- diff --git a/tokens/ATK-AAA-ECKA.der b/tokens/ATK-AAA-ECKA.der new file mode 100644 index 0000000000000000000000000000000000000000..9fad0d023fc6a8b292cdc6c4c13ffafc7e80ccf5 GIT binary patch literal 288 zcmXqLVw73XxV(Xp!63>&gpFOR&EuRc6C)d^whA*d69*$BJF^o5i&oL~VjqD6CiBX6 z?mWr%!maN65tCDM7R&swPE`5ublY;-J1z4Tg#F9*=3ul^F-bcfw^Y61)<#W>{_7anpqpVaQH*=}do+Q`V*#K^Fci;V+pCkr#v3Izi>Hs(-SWk$yT zEFyQzc(*V7wnuc9*L{hydg~`CFkzLe1FgMAa z7g7B4&x7tc&lkmRf3{+0SGkq#4+l{Yrj@w0h45*)Z9KkNJbH iKU}3De_qY;aN_I^bF~M_pDsO7kWpHbu`7PF!xsQ^nsCVg literal 0 HcmV?d00001 diff --git a/tokens/ATK-AAS-ECKA.der b/tokens/ATK-AAS-ECKA.der new file mode 100644 index 0000000000000000000000000000000000000000..d43ce3f5072be4b007b2328efe47350d8aaf1208 GIT binary patch literal 288 zcmXqLVw73XxV(Xp!63>&gpFOR&EuRc6C)d^whA*d69*$BJF^o5OTr(G4Lk4LylDI1 z{!C@}s!qL)|J#dW|5*Mwvj0%a%)@rPiG0E$H6HE!YJ0YF2_1^sS?jMhSv~B#j;n`U z_dm1q1`-Vdg0{D(p4;tRwMa$nujQt5291o2O^ggHx!5?scCs)ttxzzKV`C1LRc2)T z&mv;xxOQ5zjFC!h_{&8Xqtb$w_1t{E5J~l-6efd2O~E%--_I>r*0qNrc9Fz^ga7Xy zJhq;LrCZ|H+wx8$0qa?tny1A1&og6xt8?zN+zloJl}x3VWz&{q9`ngbd2{Ydgfyd~ jzpBcL{e{cscKFZxWBdL6lxGi4nQlEWNBQbp|H&)>XL)r; literal 0 HcmV?d00001 diff --git a/ui.py b/ui.py new file mode 100644 index 0000000..8dfae1b --- /dev/null +++ b/ui.py @@ -0,0 +1,60 @@ +import sys +import getopt + +defaultConfiguration = { + 'options': 'chi:o', + 'description': ["ifile=", "ofile=", "ccommand="], + 'usage': 'Program.py -c [-i ] [-o ]' +} + + +class UI: + """Base class for a handling a public key.""" + + def __init__(self, configuration=defaultConfiguration): + """ Instiate the UI object.""" + argv = sys.argv[1:] + self.inputfile = '' + self.outputfile = '' + self.command = '' + try: + opts, args = getopt.getopt(argv, configuration['options'], + configuration['description']) + except getopt.GetoptError: + print(configuration['usage']) + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + # define the usage + print(configuration['usage']) + sys.exit() + elif opt in ("-i", "--ifile"): + self.inputfile = arg + elif opt in ("-o", "--ofile"): + self.outputfile = arg + elif opt in ("-c", "--ccommand"): + self.command = arg + + def getInputFile(self): + """Get the inpufile.""" + return self.inputfile + + def getOutputFile(self): + """Get the inpufile.""" + return self.outputfile + + def getCommand(self): + """Get the inpufile.""" + return self.command + + def isInputFile(self): + """Return true if the input file exists.""" + return self.inputfile != '' + + def isCommand(self): + """Return true if the input file exists.""" + return self.command != '' + + def isOutputFile(self): + """Return true if the input file exists.""" + return self.outputfile != '' \ No newline at end of file diff --git a/viewcert.bat b/viewcert.bat new file mode 100644 index 0000000..3924cdf --- /dev/null +++ b/viewcert.bat @@ -0,0 +1,39 @@ +echo ETSI-SSP-CI-private-key >summary.txt +openssl ec -inform DER -in private_keys/ETSI-SSP-CI-private-key.der -text >>summary.txt +echo ETSI-SSP-AAA-CA-private-key >>summary.txt +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-CA-private-key.der -text >>summary.txt +echo ETSI-SSP-AAA-EE-private-key >>summary.txt +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-EE-private-key.der -text >>summary.txt +echo ETSI-SSP-AAS-CA-private-key >>summary.txt +openssl ec -inform DER -in private_keys/ETSI-SSP-AAS-CA-private-key.der -text >>summary.txt +echo ETSI-SSP-AAS-EE-private-key >>summary.txt +openssl ec -inform DER -in private_keys/ETSI-SSP-AAS-EE-private-key.der -text >>summary.txt +echo ETSI-SSP-AAA-CA-FAKE-private-key >>summary.txt +openssl ec -inform DER -in private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der -text >>summary.txt + +echo ETSI-SSP-CI-public-key >>summary.txt +openssl ec -inform der -in private_keys/ETSI-SSP-CI-private-key.der -pubout -text >>summary.txt +echo ETSI-SSP-AAA-CA-public-key >>summary.txt +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CA-private-key.der -pubout -text >>summary.txt +echo ETSI-SSP-AAA-EE-public-key >>summary.txt +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-EE-private-key.der -pubout -text >>summary.txt +echo ETSI-SSP-AAS-CA-public-key >>summary.txt +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-CA-private-key.der -pubout -text >>summary.txt +echo ETSI-SSP-AAS-EE-public-key >>summary.txt +openssl ec -inform der -in private_keys/ETSI-SSP-AAS-EE-private-key.der -pubout -text >>summary.txt +echo ETSI-SSP-AAA-CA-FAKE-public-key >>summary.txt +openssl ec -inform der -in private_keys/ETSI-SSP-AAA-CA-FAKE-private-key.der -pubout -text >>summary.txt + +echo certificates/ETSI-SSP-CI.pem >>summary.txt +openssl x509 -in certificates/ETSI-SSP-CI.pem -text >>summary.txt +echo certificates/ETSI-SSP-AAA-CA.pem >>summary.txt +openssl x509 -in certificates/ETSI-SSP-AAA-CA.pem -text >>summary.txt +echo certificates/ETSI-SSP-AAS-CA.pem >>summary.txt +openssl x509 -in certificates/ETSI-SSP-AAS-CA.pem -text >>summary.txt +echo certificates/ETSI-SSP-AAA-EE.pem >>summary.txt +openssl x509 -in certificates/ETSI-SSP-AAA-EE.pem -text >>summary.txt +echo certificates/ETSI-SSP-AAS-EE.pem >>summary.txt +openssl x509 -in certificates/ETSI-SSP-AAS-EE.pem -text >>summary.txt + +echo certificates/ETSI-SSP-AAA-EE-FAKE.pem >>summary.txt +openssl x509 -in certificates/ETSI-SSP-AAA-EE-FAKE.pem -text >>summary.txt \ No newline at end of file -- GitLab From 8914f2fcba799bb165aedf5ec3417f6467089590 Mon Sep 17 00:00:00 2001 From: Brendan McKenna Date: Wed, 7 Jul 2021 15:29:54 +0200 Subject: [PATCH 2/3] Update Readme.md --- Readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 366d71d..d6c0e93 100644 --- a/Readme.md +++ b/Readme.md @@ -2,16 +2,16 @@ ## Overview This set of programs and files aims at generating the x509v3 certificates used for the Accessor Authentication Service as described in the annex C of the [TS 103.666 part 1 V15.2.0 (2020-04)](https://www.etsi.org/deliver/etsi_ts/103600_103699/10366601/15.00.00_60/ts_10366601v150000p.pdf) . ## Installation -OpenSSL 3.0.0 shall be installed. The guidline for performing the installation are availabe in [OpenSSL](https://www.openssl.org) -Python Cryptography package shall be installed. The guidline for performing the installation are availabe in [Cryptography.io](https://cryptography.io/en/latest/installation.html) . +OpenSSL 3.0.0 shall be installed. The guidelines for performing the installation are available in [OpenSSL](https://www.openssl.org) +Python Cryptography package shall be installed. The guidelines for performing the installation are available in [Cryptography.io](https://cryptography.io/en/latest/installation.html) . ## Generation of the private and public keys -The batch file GENKEY.bat contains the OpenSSL instruction for generating the private and public keys acccording to the the annex C of the TS 103.666 part 1. +The batch file GENKEY.bat contains the OpenSSL instruction for generating the private and public keys acccording to annex C of ETSI TS 103.666 part 1. The following shell command shall be executed. `./GENKEY.bat` ## Generation of the cerficates -The followint command shall be executed. +The following command shall be executed. `python3 CreateCertificate.py -i Date: Wed, 7 Jul 2021 15:32:55 +0200 Subject: [PATCH 3/3] Update Readme.md --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index d6c0e93..5e73c89 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # ETSI SSP TTF x509 certificates generation ## Overview -This set of programs and files aims at generating the x509v3 certificates used for the Accessor Authentication Service as described in the annex C of the [TS 103.666 part 1 V15.2.0 (2020-04)](https://www.etsi.org/deliver/etsi_ts/103600_103699/10366601/15.00.00_60/ts_10366601v150000p.pdf) . +This set of programs and files aims at generating the x509v3 certificates used for the Accessor Authentication Service as described in annex C of the [TS 103.666 part 1 V15.2.0 (2020-04)](https://www.etsi.org/deliver/etsi_ts/103600_103699/10366601/15.00.00_60/ts_10366601v150000p.pdf) . ## Installation OpenSSL 3.0.0 shall be installed. The guidelines for performing the installation are available in [OpenSSL](https://www.openssl.org) Python Cryptography package shall be installed. The guidelines for performing the installation are available in [Cryptography.io](https://cryptography.io/en/latest/installation.html) . @@ -10,7 +10,7 @@ The following shell command shall be executed. `./GENKEY.bat` -## Generation of the cerficates +## Generation of the certificates The following command shall be executed. `python3 CreateCertificate.py -i