From a852b480d5627125fdd8d51d6934df469049e894 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sun, 9 Dec 2018 17:22:12 +0100 Subject: [PATCH] Add support for Argon2 password hashes (argon2id). Also, make this the default for './unrealircd mkpasswd'. The Windows version also works.. I just need to create a new library package, will be done later today or tomorrow. https://bugs.unrealircd.org/view.php?id=5116 --- Makefile.in | 4 +- configure | 146 ++++++++++++++++++++++++++++++++++ configure.ac | 36 +++++++++ extras/argon2-20181209.tar.gz | Bin 0 -> 55140 bytes include/auth.h | 1 + makefile.win32 | 22 +++-- src/auth.c | 74 +++++++++++++++++ src/ircd.c | 4 +- src/modules/m_mkpasswd.c | 2 +- src/win32/unrealinst.iss | 1 + 10 files changed, 280 insertions(+), 10 deletions(-) create mode 100644 extras/argon2-20181209.tar.gz diff --git a/Makefile.in b/Makefile.in index cc914070d..543f8fa26 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,11 +34,11 @@ FROMDOS=/home/cmunk/bin/4dos # #XCFLAGS=-O -g -export-dynamic -IRCDLIBS=@IRCDLIBS@ @TRE_LIBS@ @PCRE2_LIBS@ @CARES_LIBS@ @PTHREAD_LIBS@ +IRCDLIBS=@IRCDLIBS@ @TRE_LIBS@ @PCRE2_LIBS@ @ARGON2_LIBS@ @CARES_LIBS@ @PTHREAD_LIBS@ CRYPTOLIB=@CRYPTOLIB@ OPENSSLINCLUDES= -XCFLAGS=@PTHREAD_CFLAGS@ @TRE_CFLAGS@ @PCRE2_CFLAGS@ @CARES_CFLAGS@ @CFLAGS@ @HARDEN_CFLAGS@ @CPPFLAGS@ +XCFLAGS=@PTHREAD_CFLAGS@ @TRE_CFLAGS@ @PCRE2_CFLAGS@ @ARGON2_CFLAGS@ @CARES_CFLAGS@ @CFLAGS@ @HARDEN_CFLAGS@ @CPPFLAGS@ # # use the following on MIPS: #CFLAGS= -systype bsd43 -DSYSTYPE_BSD43 -I$(INCLUDEDIR) diff --git a/configure b/configure index fdd37b4c6..a24b7f2d8 100755 --- a/configure +++ b/configure @@ -640,6 +640,8 @@ build_cpu build CARES_LIBS CARES_CFLAGS +ARGON2_LIBS +ARGON2_CFLAGS PCRE2_LIBS PCRE2_CFLAGS PKG_CONFIG_LIBDIR @@ -757,6 +759,7 @@ with_operoverride_verify with_disable_extendedban_stacking with_system_tre with_system_pcre2 +with_system_argon2 with_system_cares enable_ssl enable_dynamic_linking @@ -779,6 +782,8 @@ TRE_CFLAGS TRE_LIBS PCRE2_CFLAGS PCRE2_LIBS +ARGON2_CFLAGS +ARGON2_LIBS CARES_CFLAGS CARES_LIBS' @@ -1458,6 +1463,8 @@ Optional Packages: discovered using pkg-config --with-system-pcre2 Use the system pcre2 package instead of bundled, discovered using pkg-config + --without-system-argon2 Use bundled version instead of system argon2 + library. Normally autodetected via pkg-config --without-system-cares Use bundled version instead of system c-ares. Normally autodetected via pkg-config. @@ -1480,6 +1487,9 @@ Some influential environment variables: PCRE2_CFLAGS C compiler flags for PCRE2, overriding pkg-config PCRE2_LIBS linker flags for PCRE2, overriding pkg-config + ARGON2_CFLAGS + C compiler flags for ARGON2, overriding pkg-config + ARGON2_LIBS linker flags for ARGON2, overriding pkg-config CARES_CFLAGS C compiler flags for CARES, overriding pkg-config CARES_LIBS linker flags for CARES, overriding pkg-config @@ -7294,6 +7304,14 @@ else fi +# Check whether --with-system-argon2 was given. +if test "${with_system_argon2+set}" = set; then : + withval=$with_system_argon2; +else + with_system_argon2=yes +fi + + # Check whether --with-system-cares was given. if test "${with_system_cares+set}" = set; then : withval=$with_system_cares; @@ -8040,6 +8058,134 @@ fi fi +if test "x$with_system_argon2" = "xno"; then : + +argon2_version="20181209" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: extracting Argon2 library" >&5 +$as_echo "extracting Argon2 library" >&6; } +cur_dir=`pwd` +cd extras +rm -rf argon2-$argon2_version argon2 +if test "x$ac_cv_path_GUNZIP" = "x" ; then + tar xfz argon2-$argon2_version.tar.gz +else + cp argon2-$argon2_version.tar.gz argon2-$argon2_version.tar.gz.bak + gunzip -f argon2-$argon2_version.tar.gz + cp argon2-$argon2_version.tar.gz.bak argon2-$argon2_version.tar.gz + tar xf argon2-$argon2_version.tar +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: compiling Argon2 library" >&5 +$as_echo "compiling Argon2 library" >&6; } +cd argon2-$argon2_version +$ac_cv_prog_MAKER || exit 1 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: installing Argon2 library" >&5 +$as_echo "installing Argon2 library" >&6; } +$ac_cv_prog_MAKER install PREFIX=$cur_dir/extras/argon2 || exit 1 +# We need to manually copy the libs to PRIVATELIBDIR because +# there is no way to tell make install in libargon2 to do so. +cp -av $cur_dir/extras/argon2/lib/* $PRIVATELIBDIR/ +ARGON2_CFLAGS="-I$cur_dir/extras/argon2/include" + +ARGON2_LIBS="-L$PRIVATELIBDIR -largon2 -lrt -ldl" + +cd $cur_dir + +else + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ARGON2" >&5 +$as_echo_n "checking for ARGON2... " >&6; } + +if test -n "$ARGON2_CFLAGS"; then + pkg_cv_ARGON2_CFLAGS="$ARGON2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libargon2 >= 0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libargon2 >= 0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ARGON2_CFLAGS=`$PKG_CONFIG --cflags "libargon2 >= 0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$ARGON2_LIBS"; then + pkg_cv_ARGON2_LIBS="$ARGON2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libargon2 >= 0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libargon2 >= 0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ARGON2_LIBS=`$PKG_CONFIG --libs "libargon2 >= 0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + ARGON2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libargon2 >= 0" 2>&1` + else + ARGON2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libargon2 >= 0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$ARGON2_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (libargon2 >= 0) were not met: + +$ARGON2_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables ARGON2_CFLAGS +and ARGON2_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables ARGON2_CFLAGS +and ARGON2_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + ARGON2_CFLAGS=$pkg_cv_ARGON2_CFLAGS + ARGON2_LIBS=$pkg_cv_ARGON2_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +fi + has_system_cares="no" if test "x$with_system_cares" = "xyes"; then : diff --git a/configure.ac b/configure.ac index 918d0b780..90afe64b5 100644 --- a/configure.ac +++ b/configure.ac @@ -701,6 +701,7 @@ AC_ARG_WITH(disable-extendedban-stacking, [AS_HELP_STRING([--with-disable-extend [AC_DEFINE([DISABLE_STACKED_EXTBANS], [], [Define to disable extended ban stacking (~q:~c:\#chan, etc)])])]) AC_ARG_WITH(system-tre, [AS_HELP_STRING([--with-system-tre], [Use the system tre package instead of bundled, discovered using pkg-config])], [], [with_system_tre=no]) AC_ARG_WITH(system-pcre2, [AS_HELP_STRING([--with-system-pcre2], [Use the system pcre2 package instead of bundled, discovered using pkg-config])], [], [with_system_pcre2=no]) +AC_ARG_WITH(system-argon2, [AS_HELP_STRING([--without-system-argon2], [Use bundled version instead of system argon2 library. Normally autodetected via pkg-config])], [], [with_system_argon2=yes]) AC_ARG_WITH(system-cares, [AS_HELP_STRING([--without-system-cares], [Use bundled version instead of system c-ares. Normally autodetected via pkg-config.])], [], [with_system_cares=yes]) CHECK_SSL CHECK_SSL_CTX_SET1_CURVES_LIST @@ -837,6 +838,41 @@ dnl use pkgconfig for pcre2: PKG_CHECK_MODULES([PCRE2], libpcre2-8 >= 10.00) ]) +AS_IF([test "x$with_system_argon2" = "xno"],[ +dnl REMEMBER TO CHANGE WITH A NEW ARGON2 RELEASE! +argon2_version="20181209" +AC_MSG_RESULT(extracting Argon2 library) +cur_dir=`pwd` +cd extras +dnl remove old argon2 directory to force a recompile... +dnl and remove its installation prefix just to clean things up. +rm -rf argon2-$argon2_version argon2 +if test "x$ac_cv_path_GUNZIP" = "x" ; then + tar xfz argon2-$argon2_version.tar.gz +else + cp argon2-$argon2_version.tar.gz argon2-$argon2_version.tar.gz.bak + gunzip -f argon2-$argon2_version.tar.gz + cp argon2-$argon2_version.tar.gz.bak argon2-$argon2_version.tar.gz + tar xf argon2-$argon2_version.tar +fi +AC_MSG_RESULT(compiling Argon2 library) +cd argon2-$argon2_version +$ac_cv_prog_MAKER || exit 1 +AC_MSG_RESULT(installing Argon2 library) +$ac_cv_prog_MAKER install PREFIX=$cur_dir/extras/argon2 || exit 1 +# We need to manually copy the libs to PRIVATELIBDIR because +# there is no way to tell make install in libargon2 to do so. +cp -av $cur_dir/extras/argon2/lib/* $PRIVATELIBDIR/ +ARGON2_CFLAGS="-I$cur_dir/extras/argon2/include" +AC_SUBST(ARGON2_CFLAGS) +ARGON2_LIBS="-L$PRIVATELIBDIR -largon2 -lrt -ldl" +AC_SUBST(ARGON2_LIBS) +cd $cur_dir +],[ +dnl use pkgconfig for argon2: +PKG_CHECK_MODULES([ARGON2], libargon2 >= 0) +]) + dnl Use system c-ares when available, unless --without-system-cares. has_system_cares="no" AS_IF([test "x$with_system_cares" = "xyes"],[ diff --git a/extras/argon2-20181209.tar.gz b/extras/argon2-20181209.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..9ed4ab322d513cd0341eb4ee6962c35883e92702 GIT binary patch literal 55140 zcmbTdQ+Q-u*998ewr$(C?R3XUcWm3X?WAMdHan`=>DZ`~_xmr-xjr{lbFVe_Ts6lY ztH$%pT16ZU1ER`?XaE9!nS186$X08pT;w3*yW*V?CzlHcHt%WceYQPiyJ zw2Ex~n@D3QH_0aWX?FjU$l7QxD4I(T15~Yu_O2jj-N3=YBLEx>trvW=kJy`FhP7tU zDaPyV5+qVo)*|DE`~JoKg?kDfVeU3&9A*wDE!E=~my$><(=1EbvQ=4i?&H>@^`f`t zLOSbG;?s7|(VOq#Nn1)~K+WdUnQiK3>g_}qYekrO{Ej{9Z$8{v<=!I@;14W++_`!` zID7dm@D+XaUaNE=5?^=a~vl)=@dRYm%{lZ&DA+}TRtG0X3MT{;g9C2Q;3-x z5r@s)CyKqHkc|!*XWdjGF-JHfP3z8fsuZ}VgSq`WKn&b_uw+*L(&+50$~Fwu>I{-< zsu`G%8ffGgvWofBcv{u}>3RnT%M*!ryJF^cpkVp-Ix)9Au|{jNzkf2Edg%CW3w(!2 z#W{RQKGIM{)6B$D3@nDsTeC`S^VmR9m_ox0-GXg^mGZ#x^prk8`YOyHjs~JZgo7X(wZOdZdKa8uU zAv|1xW;CnS02(iaQIa)%g||F6&d}kLb<3ZFN8;8@rtSout>u(8oN9U)j^d{Ah_cxw zLoE!|z3$1Wn$nE2dS&w8Yc7tYj_rk&RZa-@vUrS{qOQ(qO7xvIOMK+nQImIJcHt4sp8@LM;Q`IU5NYt6D`ntCqi7PB8jsnhF|&deQfu#Lh!M zMnY-@OtZuA{gU)=$PJ%K+`1$Wsz($WW;$gDbPf~<0F;<1`&|-0+}@cgD>MKj=pkoa zhl6Uq=_(p&*GbWvdtDNPGCtgOy9j_8N~}5e`>5Fm!y0Ssxa%Z1xm!ar)-K<44UMYn zeb~VVLnqV9UU?e2Dffwys~bZyQ;ObfZHKVyW3=d#E>B6zH>TBc6rNsrI+_vp$l=Q; zLp9aP-e_u=CHINY(l@5U3I+frcH5A9WJu!6Z=(U+-fVe>yz67k+_Nqn;-$S8rpf{g z03}+}rn{`Q)4#u~O+D}O2x9R~H_)lNM*CKZp_3#3_Z&{-_d+>)T^+;wufL5J{`N-S&mg5; zqru7D8=|q|{#VwvdjrJY8&gBQ3xEo{q8l zC8ac=Ys-EYF=CLNsO}PWZNa#tSJVHt8&4f4?3~L;zwGA3p?&P@FzPgMCaLpZW}j36np1SY0eXFi z+F}sCs-`JOGZfd)1-a-}5c<4Xwz+*F^uHw|> zzWf%Wv5W2ntC!h4WJ~UfGoGfi>|_T6C$a6Av7xi_QVdd*U)J%-me1PIlY6ZC&VcXA>+` zYSTf)_1v8uBzhUSPsgY7f2=!U#`fy*x;>tWZb7;onHb!`*TvET@Oa+;46@_OMA-K8 z$g#rMJEGYft3*$8+}n9;ji<`7WcQE5TR6C{jkUn&mCgD4S6jFR6x z*86nX+YGbq{U;X3{Np{X#hiU(>})AR@pj=;A9eNT6AKaF>Fu?zcL-iLzY`F*GOK1!@nInW<5J1QeeiZ{w4Hpii&cxgZ;pT&=emH* z(&`Q;c4MB!-qlubm1uDlcNfs-k+u^YoFX_O{4cWhWgV@;;?sn}s@-o9$@Xr;*=2K( z#a507uzhCtb|;C%%WTA$eKXQ-kE{yLd70VM?rI7Y*QaG&t}M@e;zE+u>C9W*$i5E! zW;mBxBy?Hl?E#`!kxpv29Ma7@17{MJXRdZ?~(>!{jhi^%2GFi0AS^X0`IMU zcl$Xxo{Uobbtr$jn#Uy(7s}!<_VykP{n~x#8+N`r+Plj}1c)-<^|I&2eXg)8&H1g> z+525*zKz-5KTlNy{FnYP&oKj@`24*ylMXaZI<6Y`>twlzc;9|gn63!wdG}xj)gqf; zT#-lh{C)5F?BRA)yZSZL<4|ctvp4wIOJdz{)n=r3C@vUw?WNw<*KT_|aG3_LS*Pzp z=FweBREFKG@_F7(= z;^u~Pf@X-+Z_Cfp4-FSH!Po1-{Th+gGj{3Wo+BdOAx!q0GI)46E*_G4M|U)K^0y_H zEfQ7RUon3Byo)DRGj{K!UpT+D(<%W#AO7Y(9)pi)H|b>4-Wpz~*xq#xFE)FTck{d0)Y>_Me_q>1ekWtDdHMI861D-t=t~=}jp|PI zFYO9T9qo%0DkLC_X9PGjxXB8#*(XZ)%TCmHJ!u)0CEyT>v-T|2Z7L zEY+~N)d4LbG854*fSz%IpT=^sysJQarU$?^AF#c;VKA)a+|uiy1K>XBYgJawIY}(| z3_PBF?H4VM=U=;>`@&!_JT{Lmb=5_;4os)i`$-Xb%#p`#mbk<-^>*=iRva^>I#HyZ znfFMYtkkz8Eez;$hnh9C6u@yac(^vblRjC^bGo&}%o{xD}3IQ&!^sYxk|M_NDyy+|7j& zcAOpe525g{8NRkZYq!_sx!%uz?#B*^KAi`Fe7)?SJECOQK|ntA>)!jBuMOPoN8jfs zx66g%vwxOzM2x#}=-Nx+GA~~6GCJ=rw48G<^*KRUKiARZGk=f{*5n>&kG0p+~qwwO(DUUD03)CRQ|uz9P8PNJjVxynai2N ztB(#ZncQXZXFNIkCWOB>dB2Q*M`$5{%nkX&3)}$ADW>0)|B@ir#V~y7o3)R9v_ahW zv7y}n`u$JTF<$I<``~G{GJvBS^`PlMquxyr5a>a4kef-iJQGiletLi)NCX1N3+p-| z$PJ!oFh~G6h|#MSBnS`4?td}SNgY`QtQIJU!1HF!85SrA0muy%_^$oTl>5dEYW>9H zUVr@PVL-5UNmQlHkd;U%vAulp`J5aWfuGMzqaz~%j^pVU2qyKornJV#&Ta4d3$l38 zi+a+LrrF3(^@AOv47~X}xRM_iz+0Fbgzo|*o=}0YegkhnwEvX=4)m@0a3@6BKO(s@ zp(MySU_zozj=P$og<$~>p&!4K2RBgTLem!_RlGXkIoG2VWzG!@V~78Jj>{0Qa+r() znj?fmy8F+K0NDj@fTa{UZ^ptT+wX!hneTl~6R*PL&S2BPDVcsCI51yXbr%>2WG>M$ z{mNg%&}2mjU3Hl$fmBkno~c*ZxSY%x#$ltU6PWnAK7E9`5k_LO{sBvW*S~8e|WIga9N2 zJmOv(brZ7sdw9#fsZ1Z@e+a5@@Cu<6qkJBal{QWY5RdcD(yAFOuvh;O#h5DLd$@5R zYRlLtC!@({;Sl(EUu6QY;S$x(%4BVKLw>w3V#Kl=j68wmQ`kjiaB1 zfbiiPq>@?@{(}9Eik{Zn%OFAX3x@cu`pdJzKO^hmr|X4L#T)W*L{W4vGRSNbt&%Wx z;fusI+094%y)Hbio3j^R?Tsw{Uq(N|86p&tfC*q<#4qtf)Vsm~!0~dL8{&R{47C~- zps7n&R#_$*V+5KwJk-=8TsaHJoK+G9Th?GE*2EWJp$qW^S!WmVL)tvuBlsu~SmE;w zLI8F{JZ9p)D{Rwjf%AgAEBsw~01)I0{3YJzj`(ri&kgVatpmyRG3uYqxlLBT$8Gnr zZT59g>-nnGMccgmub3NVmQVLN_s2Gj0qipA4IQ+xzWyVZxTg0jqXWylOLp@X!3&<% z$&77d|J8Ew9#=syl){k}ORD$S`;P-*giGvvVuENz#LcNSD$E1njrVn+vY7-|2auQ= z6sRf}^a(Tp3a5fFz6NDqI3>~H-2XFx;Z8h-?HOp6eD5!XhMNIQ zPbB#QANK#|a@arM1vwOho&XrAiI{56nTF+QR1PVMb;dMz*E}+nQ&5k`j0ZOHmH)k; z2Z$XKbPvKUi`~T)#%j}<$-~L2HhheA&|)Fi(2Q>fgBV)^!tzC{~q>s^a8vSctCg69w7{he&-v&0P}92yo|?VpQp@ZfaM(^ zC?^Bh5HvmbQ5OU8!F>aG#en?6f4LTm!aVNNO#SI0zi2g~;i9+8kgMgQTka~wg_(MU zn5ZrLa(#0I1;KN9?Mw2}HNmea%=nI&#*F>(+v6EzbDkLaZriL2{MwLQ3dO^Iw}<{) zozGA^`2WQRADV}319bh~C;wxv-y8fIvD-Zr*KD^Z@c9pGwwpl)?#+($`f$bDL43bA zv8uP7!4lXGKA*sUfZ5(>TF+~TQjYmOk#KE3OkH67RDk6zfGzp3&ok}B^wS>~_CG5O z1pa{p8cNR-{C8nH<3IMF={j(%yB`Z2n(Rma1PnKIZBbtNIzQFi`tQy31Sp4J#C* z4w*E47{yZB!j(ANVHhsk`}^QoTR{AoZFEL=@`b9p@71)IHWgRHP5| z^N&w8*aQB&{eN-Xw>vCARD-~(qFM&{5u2hH zpDT-jz4=O9H8?85&)c8gfP4e^-;LJK`Gu#i<^)0dvJ=O@HKYcpPMPtCpZEmud@G2a z^1o02{c!vJwWEMgY>!_N__xsFoU#{8I zEIyfmbgo}x>}1oxNtyp_fOr~c@&$e0Cz$TITZ#7Hg?8er@jT7<``Rm@_*U2xmv>)S zwj1IA$c8rTAM~R9iV^yvi~_9u=IlWDf9*D!rK+ma<^njXZO!>^V~zQItebf{qaXc96J%f8RNzSj9>HbCD{a>hH`bK-hg@(T{Q- zf6RmC0L|~a{Bit8G6o4J}-)NO1{?57~qk93g|DQWb1t#AEib(GI{nHa!E`%KwMuRNx z0Y8F($B?_ild}E(;QuK@=?i~;!KS#F{h<-e%>|xc&+0r|1GETNgabUnLgY?Y?jPAR zasW0y@E|pD#2?0@q^Z5YV-zbEtm)s=mkx}>azxgG~3(#(@*td?hVIpRPwL*fEQ zTw=rPwfF#lz7+hgWhC~QTG!2wXfUmAB^DZ#ss5-nz+Hb7IK9y=6MhW*6F@XF#!5I z{>e@kbgnbMGy*a^uu)UL*eju#=>UzTqE?I5zV<_9MjWWmAqZ@KJol|XBT3d7u2mL{ zxk$xvM{5Dv^xiz~hTN}-Ei`VZajY11F?!K8?8hd;N~gnn1-8R{J(A&5rDKYw zxN^9kZw3HqTL=>%?)VGpjJ4R0gk7b=R$O_#?DwjiO=0(Guc-?#<$ROK^+Ls6v@VA2 zYtd$5DoNN&G*I1J=2L70K|*-7k(l-`(ff0GvP$THhgsLonJ}ThPZS$DYeSd}C7qHy zE1=icc60AYWl$_T^nH;=xw_?#+sn9o=`TRxVBwa@jyseLaPLJQ-@5lCBulDMjVZ_5 z42iIX$%WOrOzQ=1p-%DY_#;`iaA5nrdWz`H_jB(YFSo0+WY&B6Xa%uU6??-z#ntaK zZ;=UcvYoB?p7>9lP%gd&&B>rowV{gO{Tn))T%98BNl*60{l77l*;L8xkEjq_?YFV# z0?2B94-C?rv9v8BO0sTvw;8fs(LV0R4#n@-?JciF>Wz-!z!Z6DkR zgT}i+UGQ!~6B0rZ>tGKJ?2{?Yo_1~JSgv*@H*pJuK-dGk1bOfc2(FQ5?M49u4%ZIP zyH-|&M3=ohJOVsGlL3^~uYU{w=s}L{Sh{%x#wv~TatRhxjKPER@}=fkK#mG)rPv^4 zA6P-m2>cm0M;obtL2^q6h{46CM(57?FeE8K1s$Tk|5L7G)jMhaNRaRG7oj~lKFnJ z7pq%fPLl<__kUE2h0D{$S3TB$#X4#tMnZ1RT;M z(BD!VT*XQ>FxU_42Lx3#JwyZ|`<`sz((oWWnh~CW41+Kh7^w_{ju%?MRYY#?4N?PJ z%WsfNiXicD?!RM*f!7peXjz!ey2D9&{SXSWLg28LWNzRh3FoTP=aK~XVSA)yj*KWv z5#*GZj?@QMczfJ8JU0+A66JV7hNhSIoj2b8LO5i~UgexP0A z5^?27adjC*QCF*OzQPgZ;|;AF1c9UClMsl+rXPoL8bKj1xbBz(9ol&i41x}Lo1Jk~ z&hwf3CSbN%{Ye?@mh1&`A+ob_EPFcB!Z)R&W1XP3BBEIurvYuAlKDfY7G&M>`*zD| zAQlo&a3Wd{-8^F$7#zcxen?^>!O&OKE-phv2b3xXd?1QY^tbS0?B4WV2~6mkS! zJlQ<%T;8=RA=Battk~1w)|Vl$K~%7=*l(`;iQiQr<2Q>-+I*nPTp7brTE zX643KlqmZXGx~#4M(!A(uw1T}$JvGKA1eD}9smLPw0aN@2`J0SyG<~XNjiBMkj?ru z8l2s0u7X7N)To$pL_E_ch1U>C*6RD#(G-iN=-#81l(*nxOxr?fc1f_tMJ6b+v*wr6 ze`=IgK(Wfe2}tVYNE5bVBd;lFO{mdWA%}0rE@3k7Nh6`z#ZCYG!*i&Jx0CdlAixZi zaDsI34nk*hy@qB51JRS|>skQdT*~(3gcD7(nuD25RiY0$%8n6>k-9z$vaoCgD1}-q z@j3m-DF1uy&RAK5;(jM%Q_8@C8KKt9M&r?X>lCPS2SpekD5fXT>-o==7-H(@YH(^J zxsD;>*o4EYKtMT`{w66`w^Y*4zxn+;iaG18BC%ja*$H%^At+;HnT5r|2gluUW8zIk z;kI`Uk4VNdBD7$WWVydR;O~wr#I_tDoMKZT%&(Uu)JnWzeqs*NDT))*B6~s zig zsRn^LYvG2W`ge-cyE10M7XG`v5B9vU!lFtx(D6FeD}>flW>CE{c29i`luAZLRej6J znbHb>uf7mHJZ{Hx++T~`t1v`|j9^|Hvj2br(_blSdhjKUsLvvMj4DQ(ye#;i!{P|2 z)gEYoIE4dxLCznjc?mjN2aheNrPt-VWk$>0(2M?`upJ^am{b_(RtPnJQ}fO zi3K2{9U)dldjC{1gF0dFvpRqB|8moGVJWl!Q>b^`7AIENO&yCd3uREdgQ&|Az{Ij$ z#7yp4TuAfIfGj%{*_O5bnZ`$r42nv?0Ga^e)@Sqy-iI;ZdPsR8S1+|p&U1^6OQeh9 z37bTlpt2t40{WA46uohJ7&3F|54NESv+3T?u}_1xu=-DQEYlKadXz@Op}K%D)iFp8 z->l$&)R>%uOfYK!A)GX@C2f0qP*p+9W@`e5Ce>jv>!bRVA^S$aPlE}EfS}i zMAQ#8=3;esI)#>um|m&Ua6OV2op)A+mPa8*=8BEza)J-!wEq@eu3$;T<|bbT7yQ(a zTYfj9?~Ri|9CvIqucSFuW~nfB4cgg!N^wy_!k3F02VX|g`Sh|^9%e$MUJ+P}j)Do! z5ZNb#Rxw@)rVai1sZ#fYHC%{VviOB6ft~coW|6uun_a@wqH%DlIZ+OlSwxx4ZC=Ub zKo_=0T9p)lH|5M0sani24aGHL>VrCOEfQ_E&Dc96h1;b?gtC>(x68;bh7$5gLK?7s zZ_4X>!6SxxFwp2p%N|aVrSZFNm_k|G%09{F#CiqktET>w+?D@B2@bCamv8kq3_xx7 z_7+0tnan*dV2yrto#&n03Y$8tjZ_!8ggmS{C_zyNLNHrZeMd+T4XU{E^?7-aDW8x9GIXLj3Q^jF9@*` zHvHV371dN74219sW$c)qv8v8UU{|6Ur`%3rxYV(~fgr;^%7hO>VKCPx4dnnG#j3>n zi$l^S`&Si@osS_vR%FUS_5B1rti-28ny!VXWT;VrqJO7zbjK?R0zLW{?Ws%!X-qr% zUdA7^qw?fcU$Q`uRViwOt}=zT6pUSh82x(W)I*EDfE|IP=t=MTs;(NP;%+nH@}B*> zq6R13d07gTzYwi|>b)t45#{V+Rj6zuL9UcRYms>r@--Jh3lx-Lvn)w+o**jt9!fBe zY?yN}lHpnFNl4jD(!mxhh8qVOIF?hzyH96yd!-994EW586#wb>vnn@_a;&2r0!W)J zztuF9e&^6p*TaxLJg`Qb>kv2CzGCH)=H^9$AUB_jJR28=v9rO?yCYmsK`7b66b8P@ zho6&|due>R_mdD}=~fi4K({T1qODV}ah2f^HhNZ#9OtTD#H=)da)AIc{thlFj6Qs@ zmDjQ>IFG});~`8;sxxb2d*{S=2KHINK(!l0=U6D!?_ym{8q(`)Tp7ow@b!?#TreWR zR86fRH7DJJ1%zbNMns$$gcZ3oJ_3S~e;)&bfG2r~MS4*?aG#W~hk+caub_jiy5jS<*MJiUaXU`^n^^nH4IVD7c;2dwe!0LxE_J#2WcP4X5 ztQiyi5z+zA$TDoMe63nS>qvmP^oUMaGy&e`FhYL19OM2CS{SM+h476!S}PNh;kMmJ zsnn9Bqf*p>$bE_g)<4l8PEIsVGK2{t5IBn?Dem3r)(>$GSM2wgNx1Z_s-EP|p%;Bx!FTRiA%xD>8pJ51Wq^5H;rE=Af9nyGdQo8TsN zh1YvF_rA~x3vL-BDWjNL&pC&TNvPI+|Ki2GcvnOAdFAo+2AIw`$w4=heFi)Wlb!zb ziUSi7eO4OW+IcnTUX2=&k#PoHtSoTE4#-JXxG5K2eRK>tx8@r*=0LO`e1*>NT&37G z8lCn8s3qOJ$ta+mlk^8x z9R(%$1)zAgw^YHxW)Ousvg!i*%_rc6sp1-h5AZyva-(q@`)PdB|LnrzYV|W^6HHBw zhcV8(kCSDBrXY3Iy&5~|b5S&=YyH*n)>PWK38K1Bpud{j_9_m1ft>JUspvO|%e zV(20-NK{pIL}KA4g0i^cemu(3EAswM3bq~!tiSFzL#6GArbQXeW1jp;S^h!rzNv-k z%S)cVq{K@Zh%$6swyzv0N>+j~49^Juz&#C{0kLN(wuKX$$vO&OR#e7C=$q1T-R>f@ zK8jnJ*a@P6rJB&yTi(P_RPQntEl{AlnxRZSAJKNW+dtssEylr+YXeu>OxGW)cA5@q zkFSvEqyyfA372`_;PfV$w#XmR33Dd_bsvSa6r@+^mKoROtqiZODq5+qq<^RcYW6nC zz@TZQ#eY@H*;B^Jil96th4cN`U#ZZ$4sg|1A+-p(GkX6?NpF zv(}TV(1h77&0^zJ4tP&89#ukw34-VetQJ{=b7hVkrrf_I4Fz=dkfBU|Y>$w37pY0C z?oW@qhSnliM)b2*QYj}5m2oz)reAp!e5EFGcWft2<8f3@ZD?qBwwezSWm^c-Z&rCA z_eGYayD+MB=`ul6^NFI?TjXMPw3J2ldi+ww(`=qCy{+Seke_?~wg*mY`Qu7&#LqnCsr7KS*f?Mk%6VVC@vNHi(vA`n^2^ za_L;qn=o(@eEsDl2St$ZB{+{TINgvx6S!^$T1Xg`K_%QcJeki>P%>;MfKV>Q!Q52N z5mn!P6N}|Z6v%FA8!fkca5V9w2eH4DqRB$#3@j95pbU#7RBkO>8b}oZ?a4i{bn4V9 zmiZGeDSy}_#YmMUQ2c-54yRc9qG0n^KsJQZE9-;gr*;cCI7Q)a!MU!k)PfT~8*hri z%FvZq_s~{4@l|#cVmK{2aQ~3eYl|zU(4`J>R2w6Br2bO)%bqdMkE~{JE@5!KUI!+$ z1PiBjD+DTS2?m}gqt1^%Hp6wI#7KYrS-MU=X0ITpL6^)XMOjWGPJY1Zc}QCur3{T3 zq}8kj!z{bMv>v)Juk@gU;c~v3$s#E3DsLD%pHxc|%Cnos{Xo2Ur(qXQ?#UL5!ihJO zZi_i>fk{c1YUXAEhbqRlm<5-3oP2`tx21OWZTKX56D>oz_;Y>j079~Ea?W{m zt@wwoPKEf1_(IZd4h84QdPXuKcP3q|8^*@<<#J?VNWTvZi>kCUj3Xns=ohdv8sZe94dzpJ1n&yWu`61*sudA2C4-@-( zsA>0Xv|idheJOKRL$2(xLnd*E6o*ML3+uj^!j!W!6Q(d}E(Ihd1<4+c)k|BCX{2DWT7k=MSmt=t%NDZ0 z(rJkuI)z#iL6SV|vv|}dhTp1DMblL>E+6@r0YL{->u>}Te}*7%4V?m&v1t$)+a!YL z47@2x$%#fIFeUw9Iow9M=)!b=M`i5r&d6~PDgE-eX9K}1((F*zvE4qEr_#hbqd7@i zNRt~t8~-&nWHA@pr_!20^0Y!8u zImzLh({MVz@K<7lzOp*gVpI@2+2pWvW*w)H>77`b)@^YCe^xJIokqO1hvFV79u^F+Kxv!EG6 z0eq1PEeULtqf5P zV=*bay0a`uPD|P2mDqcU^DdCHdZU^SZsfhAbkiV8=@&>mjUJ3zdOr_EG zIL)BeH4pN!5_=$23rCl3Bgj88T;@#d=~*s?yWT`3jnZm^IJv_)+_p~6PG;w9{bG#| z6#MTEuUoa)zpmi>HEQgW(O9i+beoVPWh1?=G2$9-=&|?K$r-g*Z7)i?L>lMh4a&b_ zT>LAsDTN-Y!(eQ4$g{}MTqd6$pSv$de+O=>L3fN>YKsT{?$`#X8HG@yd3iec3E()r z_5UF_aCt`Hy4-hop62V};TOb3dTBng+LM@1Rmd!1+e6<*x5GT1fOKPuvtYGoR=q<5 z;ns$Y8|9Q*GOj{<5~VIW6r=qU9755h6i>cGQTQkM&cuOzzSC-&?dn(N-(TxzED5q& zDOLDVY3*8`bOKNU`&%{vs0_b`R*J}UX|bMJ44?|zb0E?)7&Mz)n>S}WoLWv!M7`Fy z?FCq2M@!~W9nw$Z=N;iW&7*K(U?s<ou?Am8mpS733?_;H7B ztkty0`(~a=GJ2#Ji=3xp634bkN_Q$LokJkbzeIS=S3pwPJt5K-fD234A&N9dFkh$N z#gqpd0ZHlUc)WdCz?HGTjal{2(~S`d{u;53mT|c!itH&Ushl0#u5Vu+JB?W;Plb(4 z+o{YG$|Fc7|nX@aHE7FcFL=R%Me$gxZH+zU{b+GzX#!V z1;KCFIHAwjz@|r4DR~~&B2vARG*eWk{mC&J8Tbyrk~1^a6on$oJhEVf5@noUW&M_~ zF$i-XO6|9tzgfoEAKIac^O61AxwmV(+rfBxYl1Xv^i^i%>`jsDlH-_BC z!)rx&6aOj7;bS#O7!U?X1Y3dnp}-R^&h9$cD` z>Rb4&U4~RY#W*;?#M+=Z-T2#joO5|tY@!uP`|VWgIzV`0E4r1@g+_y};$&{|SCpbI z@X`1KpS@+fK+VyIXG`iX2>-zPl0thGSrY{s-Bxg+dc>+5-*7G13S58rYeI4?>H}GC zrKLT3zZ?Su`NkjJt+gMRtJU-w3j{_Gm%Oxz2K|K_!rCBLaqRm{nN_mrEFX( zc4ToQ{}7_kACf$+?0(KV+VabBpxKLUz!}dupa??A00o|95kp?5PzFcVR5S==edq16 z1QvTDhf?tq10$)*>+>$Fg~_j>7rfj4#H3CaSnpJ4NYgFaj+B=Bc%hEqN%gUn0JK~D zc)ExFU^w+p$4Npe))CkyKtA)ol4`2}x@H3&`h*X|pZnNgM;oL5{QSt3n2S-~A^b3` zyhfH5uh*8KjNFd3e2nmOj{N>*idHPaEtLwssy)@fgHXYy8OxoE{o{IcA45pm;$T(_XW!E>7gn zo<{$ulM1!ipV!;eZ~9VwW#8Glqfd>sT)p|t7e^Htx>i)uWMEhV;$g}Y)XM4Q&9cQW z%n;=5bqjX$D^`lmQZhzr#fD4E6>)?AUba)KdL=3sS^3Eg`QDeYi9N$p8?hCV^U%C%fECUYYeK($7aH zrW#@tYVQRG(Nb4ZO0#i7&QdW)Ma9&}Y2)XOn%=P}TkQhXVIeOc4-w%%BIK~uk%3#! zF3yc=F6>p0=J($93di>(KO6e~VS84Yv}wPuH@o^S;O+=Xd;wAKq(TtiVpIjq{$Rp~cU3f~Km}{2uPM^we zD+~`l*s7qUXKYo2H$?oa&N|Y4bxYyYu*f25wtEXt(#2i8H!ub&-X4P$2PI8yNnB$C zU+Dx&$_amLUpasp2^+Nw|r(766}{^$2c`2o#>w-Wlz)ZN@m!0-b)5XAuh4 zMG*Dq$O{m`!e{Iz7Rpu?fsUI1{U245c?`}&B@`7tW?VAQOy za|CM|`*H4y;j!9;M|4o{T2IQo=Sbbs?~N_Xt5?!xQbvFmxS^U!s#V<4^+H4^tK%|;%#>+L4r7FyNyz#l_cmE!YT#Ix zWW}|gA%P0_<0+ZJpyHaSf@{1%$Y50-$5c!ZwY-GWt|;yFLvdcp{rfxedN%TU`tV`r z;^XK6gSeVq$~dd6BsH`~ZF#a@V$N*s=;8DMhu?hvvmjs`alT=ySF4Bnz9-VvX}inq z?77OH8Q|Z>@|tFNS9`w6Jgu0Lat*Lsm(QvY&4MH-sySwjbE8bUr&&fs+8YSK!%(4# z$F^~HK*B@doIF^ta&~EW&eFqhkhP&|@!<84M!ajE?iC({kg=QB-;$?DF9z3{?#MBp z8pW!hCPST3>ur!+<5-Z=07HOjZMTOPf4r*0iEJz2(Sn~ol#XleYH!y{#%f!Xq3i<1 zN5X%E38W~wGD*^;pEI+7m(-~Rs~$iY3O>*#f8n9PRYTDP z55P3$X7}pw7Losr-EQZvVmD70%>LflQzA^fq}v5%Gf*Vx@k$z=_+)XU9qpS!Ue(A= z20KIc9)XO^g5IFU;^kJ47TeO>t7NUu@Nr8A%PmqonQ-Yrqme&xJv{-}t#=&@_-K&5T%%4kjtQ$+P-fUcT!&{x zs4FZZJNNZULNOB|=#r`LWQj=hOidG%x;U=d8RyPd3di4Hv$~~jEKk45G&L!5b7L{1 ze}*%4-y3au0qghKw9CYeiQ>ZHHW{!k+U=I5UTaC6dpiQpjDzS*P5w4y`J_YkI*=*^ z>o5+Htde>rO&lc5ns-9&aFg1b#c}No&FTBMv3m`Zf#F0AQy!=^;a{J)!Rw)@W&swH z^Ro?KkjB!UkF4P4pU+zJL{me2Nfc&Jkj=e3f^Mbf>5Y3t$iQ%w<%jlImVT-0X6St8 zWK1Vx7v$;Y#vG0ts%yus;fLF&vi{55!1!Xl#e)Lc_v6wexqv9$q)~NvzI5W3;s_t? z7zuJ0butt)gj$PIp~0MZoMB>%NIK-eMv$Vws#T|omB8t=wb_Z(BJL9|SOvq0W2~$6 zaa|oF3-|8<0)Y$UZ_w-mJA3Ow-T|0V(3a)6MhyxwGT9k zairE{rJA6k0_l*I3RLzzEk3Gdjh|REuc4}_yf!*m(WT=1+BOPHPlg2XJSwpfZf8lL zmAQC}^~TszE)R{^5)NnMaYi3#Yk|Drk1~5CN+=em>c>74oOyV$>}O1}nAcwYL`4Cf zLq-h-#y?63t65OJ#iM_f=9GtSUChq7C%d**WLI@ic2%}^Bn!SD#tE}e)VG%>QAw6c zfa%U7orW530qBTD-6QrT6J)#Z!y3kiPZc>5Md|g5SF;U{TXW)AqgnNWNZAkP&7qim z!xiX+z3ooU=RkdaXXQ7D(r4qo-#6RemrmzQm}3N&WHV*!{u&a7d)q@<`LqDvYiG=e ze%s{o-(>oHdf7jPw7!JzVXMa!te^?^!sfp~)~N}yUocGok7hWrv6{jL#ls;%{SYoO zVrgY9vhrbGK_fNy;$rC?Wxn9cHyuzG5Z)ivTB-B;yJ$TlvSZ7n`aQ-EE9RW zLcTSC#GvlS*h6d9iNZzZ$53lj#*bx`-$un)X(}zwo_sg2)R+XLWNxhR5@<-gkq!dNl1tb~4 z9Wall($XuN22v$Bi_wjidXo{O>%b)Dgc}yU#6|P=YTl&{q#9?5uXr$I%rri^zJfZl zQ|;?1pmC8@EGuc11~8*jjiOje+((M8`J5mz3%uM<^fVL3pcEvA{FziMEMUu^@v0e|=#)#Wh;~dKo}5cLu%QMb|KPu^gUjicd)n~h zB+L^6;sxk~E^JKg_b-tQukXSkz{`Rc|H$WsvFOrRCaPa7T_yoQg7*&<9{!{E&BHUX ze*7YyNH!9j7iRz9Hh6qSTF5BO<~qCI$h_X4IPkMy%KxAekY64|ZC(W!*Hj+RQl8RQ zp3zaB)HNQ`8wl=hS-k8s&CkyQ%})T&4}(m<+Z|>9bB^7vdm73%OzqxLq^ons(y>N2 zCYrCoA+%Q}FyZ#G8tVbZr9Ws8Z4@uPul06;5PZa#5JG&Ym{wEMz?J`3Fq9CggZgww zm3JEFpeShPd?kuJu2RdEauk@*wIoefTKO}Ipt>=76xdTXhHkaE77@`^b(XK5{fJpq z7=m)G&G%Kg1g$IxWCO`lf)k|eF8y&p1YI0s@jH9g>x|gk-7a8a>Q&&E^7PBdEKh)s zxGz&INM-NuToYZQ>4|=@A{{j$gpm-r33UVZYSEi=VO-RM_nfwK$`&+{zrzn3dc>@u zG-C|)K3)sVl-QBe)m>R9t6g)hT>)detR5wHV+o0}sbJ|p?ldtx;WHFyQo+C{=J5dS z`tcX@X;qX`y>r*xgKKCn1|+cZbLt+rhXltu%RtveA_1hc(q;M{8a{@gm6BEK&lfkP z7IdE`*+QS~b);-UW*n=s6qpr?@8bp&VGDw^>rHxu2XE&O1HYP7c<0p58d@!dsZkipkB~4eEJxZ?XHYHZMDs5_+~0=(#7-2S<-R$r5qWm z7cW8(a4FspqtklEC8a?51t|rCW*Mqq{Y)~AW0@ySQALEub6nsMW=%ylhSscry+5K! zdxUSyh@?I-%-2fux1*h9fKII?8tgWk-}pY z8&r{l;R-_UILt~EDP3yd^d4PkWG$^$Tl0#|88uum z?j6>17sSM<&q!{nRK$kHuQzRMA4cPgQwH~D4Ch-S;hZOzl!p05@8iC6@5Q@k;jWJ% zu}@@%flFU?~4EHr~l+rJ{;T1Hg)zv;G41G*5!}SI;9i+&vfDa|6c7M zjlV+A`!Yrhi$XV;%pZ-Y2HIZ`e6LuvqrP60YR)ich;)Vqh`aO z9{lOuV#SK>+KvexKE@l{?G}K56YR*6G8r&I8=xsdhz|>o-cz#$h*t!5mw{b`P{D+# zV{3ul*Q>>l@cy)>_D=r#RizKVzypom2cunoNVVqWi)PojS7bbsia#ff^9ztvc9T^0 z`F;~A?L@_rM93jORufl=JmmfP7lY%y*QzW^vs-w6a4a9=;tLV2AVgjMx!H2ZY!~7i zkMSJ`Y(_uNO~oyB8?vYHN|o8>?`4fv%5xjhJW^fQ_W?_t20f%Svc*|EO=J}`UXj~C7HH74;q9HEG$=D7w%>>^E>hz|a~ zQ^|Kwuzbo7MDToKcs>C+v`kh1g$6}BLaY!uefs<2XxT!b8Lh5bTh@wagm(J0ST;8$CMfGz z8pV2-Y|EfhBEb7CT$5zEIZ6gw$`M;$I0bTlI0|2SucmAr#txb5Ep1jr-r|noMj}U< zqps(WTC+A3>y=D1)sR$q_iGOg)x0<)zHF3?rWxvc7*7qDtz_Mx2^wn;t62?4rvoab zQntVuXeX&(UHeO7{lzn!PZoYW3SQtZc?xaAvsS(3TkdQu|5{tNWot)rfqx6va=r|8 zMTf8DG;8)lNlQ{T{q?UP#!N!2`jf~>YrH`l@MQ}Gvcz@)bHC=7t(V-YcYM6$7=>Q) zw~!!J2sTFewZi|xDCiGFeYvXSi*XL;lnR|Zu~YdEt#@8#|5Kg%r!)T_u>aewZg-*n z_vYre`rm)Z&o}%3oBjWvWdExt{6a2S6}H6CS2h`z<3W3@-O`V!F3x~z-NA9TMUg&y zaR$B|jNac!S7CSps<2{eY&CiG7>RpylWOo@)i#(qsf)L&#O+MDvKWO5tK8EhpD9*T z0pQ6UM`SVSkt&ohrpY=*fKb*~iy4zffFu`sG5(&Z9M6)JGyX#6aC1ab+=A>-pQf%) zpB6$Vs_?^ti7I!Y)aHb-M@Ab93wnNUb!1y=BGLD=v2*h4fNm+_`x&LqrIZc|mmzYt zt?#a%qjClRfZ{^`&iG&0;^%*n8JzIPwgrlb!k~!~RM2h27$wP5?vI=e3#>fPYxJOO zp;~EnNMj6%!QVBNEh-<;P^_viQOhJ!Y)hvL8aR;Zypbo1U6^pI1lseAN^=&hVOYu; z*u2zGBodER-tk&h?h@=wfIEcVsJ}E?w`&AFn34I(!IE~TGu6qq6#W=`Ttny@3Mzc< z&5|4a&-MBYV>3UGMvkIPiC_L$(^DBrYHsHw)9GOrw@pR{@5k@5aTQcwIc$!uvA!c{ z(6yaXJz28DGEY&S4e2pEo}NvU%Z#D2Itlnhm26lntss333N(_TDpe?7Z)4j+Vj<1n zNb1JUSng{+NrTyhU&dx(;Q)R;8^`TH>{A^7l1?FqIz=W?M_5 zsX#VcD{$DF-*r3QxZ`YgM9XRS8r@dU@%^?p?lybfalhlV9MGqoZp+;g_&S?bui4yc zwEW(<-Eh18&ccA-$-I>Brq8>Zo9(WhK5yBx=gsfjRzLmt{`hMA`lq#GpMG*a9!}1K zsQn@k*IWJc%8Ms&-UNHjhvd_z4{v|GeYJboPHt{zKdoghEp$S&tNMH}Jm(sSqqE(k z<*32Rek-D8t>5i8guA)vwYI#r@Y=1-Zp&|pURwY*#try?bE~)6>vr0JBheMT{$^{d zv)T8=R$k>kujOnu9e1~?!V zEt^0XEx##5tKSlBzuW6MJb zar-g+@c!cL^7{4s&9Jlau|4b0j(&XQ=8>@!3y(p9?{z$HtL^oG89M#3CmesX=XQEy z&-EHEEPd>Z{jF{rD01BCH$1-!WFz|h-lp%mexrLY5;j+3l#Pq_htu~TlHs`hOaJ}t z>ua}hba*?DzkhYw?>0Uk_doT-^!@v-FE<}n$3SaU42-*Ov$@%AI9;djb(_L*L12t~ zeW&I3dtP^I-05`NKqZd1)f0_|+vo{o6VY$Do868-UJV1SdohqEgSQ{vIJ4$eH*sI3 zo6+^8?;L_i{^caS`hNH5#rJP+UeESlemqT9!9eqo@^Y)$Z8tVITjMRiJ#PA)E!P`2 z`+cAYx7*tSVc@~mk6YtSpaCC+>$u%%Z;e5AG<&VixV4JBY(7W^m+y{VUc{fiB>wQI zbvqs29)0Y5+;9H4cbAIvw4V&W{M1R`9lZbX@L&}rbRK(Xw3;oy(S+jwvekV zj_0<8-)T6WXnC7WudxY?zvXS=ApuX@PSbC>O&3ID?_N4kNa#F>gsrQ?o0nJbr`=`~ zNUgo!YwV?+^ul{FJd0XK&c#n}POi3+*Lzp5SE2;tpj3Ne9nL(e01hfHcQ#j}d>ZJ}_((j@I_m9HCwJ^WKX_8oqsbw?(iUZ_g?(?^7`_N)4q0YI-e(wcYb^OW8r{MN*LEd!q_M4VOcq~ z4XhIqdK0W`sjEuqn{b(#S`DaV<1|S4&Gy!Jy69V(QoMAX%lA6B;zwyt%f~VHSZe0k zquK(wlq%`DGPAF9Dbh5G(9ag9Uy15} z4_eNbj$Z}CjGu5tOasZ1^9zwoImT5pG1$%{QBky~D$k-iP;hjUUfk=X{>roJGGg?h9qI3&@w(MaW&NuxOxc0qtPXXUNK@ z+uy@X5-?Z-`c+^IIQsU5FQ*)QGk?cV%D!EY;q4wA8`C9-x0`CxhGU zwzjs~VCVI`ey;`Az}RcLK9~^gZm-eX>b3fQ*Yn4qANa!Q`+k3`xw$18UJul5;Whq0 zdr#WcNRH%w?qA_Orq&b&Qp$U4yWVi);xd@Kw#HAHsRS2b8($c@`@e5U%0qeBPE$bj z^w{rFWh+BcC=`l}P=plYm4o50$eu|}dOY8)?%y2ScTXEz!{cZB^5p7~?(F)G-yeQo zeDD`9w=T5^_NnE1X7=wDKdj_$wh1==^U(m^d@;_vZKsO1 z`#Z|!8}2w@+wfq}mf~27>3S|D#M3lFO$|A^V)#h&9L3gcY?uzRz!XE44n13Rs{zwvg+<;E2wC_|qv-aPOf> zZ`WJOrP}M9FZR~mEz$zpbM3@XPiwe$eRF%--r1|3cFvFM)*I|SfHkeV6q^PZ8lLHE zu0=E(dA~6PJ8QHXYCVxf0b7E(cuH$e2WbT4;io`bXW6iOQ$eShZ3qAitAgBt#RpL z5oEYvej)=TszzMwfko;f$8HP$Uwxh~rb+bv4DruyBAv=5%pUd{d&gab`W&hQnL` zaC`j`8^=4n@AduR(A>qt`=f^y!yT=<_oMn|Dcet^sW%W75!&CzYuRKN7pZ8X?-==0IV1{ex^+gkl%yLb55 zKDzZ*kE;9gor)LlROIYc$a@anpMTRqu~lRsqka_Oy#N z6Ra!CbQSCvx?%VRD9)GVrnAA(ls!YRL^#7WLvJOVc#~u zdcZzBa;OL9CZ?7}}7A3|kw6Hy&!e|w?w?I4=sqIs+6MfrND0UEbkqPYJXfAPW(4Q$-5T5R+pg6mR z1&U$;S`;*>TfU)h9$xQtkM@sO2Gv??RqJl{w)7kGWcTUlabTY!XMcTXySbvxK#0N? zwc)`Madidxo^IQ=q3KkiusnPNE1v0C4mEubdya0qP+pladU{=jbh7VR-4*4h)z5gImE=O z=XqcU6$x>0REocAA{&Qr}( zhxe$vhPF>`u4~U%>dKS1vuESy-MvMmUtB$Pt_#s(R;wB;MBURYYFJ=2s}lPVqt`ZyLcJcI(n+M6k%Kt9sDS(CD5ICipj8{B=ELCaI zQ9r+qD1;x-8;qJATZDlwm-c}RTmW_1Ro9$t{vP!!HO!tgMz9{w8a(U8V&p$3340Y%!=aNOZptgsgj(zv+%8t4*GxK=%BoF5)<)Em`< z#u~djB7HKFHQ1ES#-$r)pY%z-N$mr~;$r%?7C!v1O?HD$hhHmVwtZB}S&i!~ z(=t4sRzbYbf@*xmvfbprS!8%TtwK1xtYUB#aNG}f8nJXIZC@%4MU(`N^Wkw^A(;4T zi)|P4C|Q=1ZUnF50o&mU;=m+k0iOJ7d|Okvr)!0pFU=#iGoa>;xQzvt;70eGj~YcllM zJ!Zkz=%&z=CIezZ`20SytXPS%Pf~>x))Kh_6(ziJxYMHpuifa9mRI51u6*vqSC-)? z1{c??b?LCt_Wd5aql{x9ex$(ob+W(-VQbA##n!wKQm?RX6Acwvfr$!Z*OFl5e#s+! z(vUJQh7uEoEUA0p%rnO;n;=>23-4*-1u~)0(yvj)sMV#<;-=?c;}F-<@4pv;^GY8+ zl*%EeE%QW)B(<3I~gLIu;QvS%=|F z#{%m~U^aCLCP}U=aY1@S{j$R5F+rULKG(@|KEj2R5|V5ce_}B;k5u^J$Q`>q`AOuD z*0jI?1NsJ+o{{Wnkecg<3_wWHcn<-qUcmm-bhf5N!o899o5Qo75B zln|78Y@8|%XdiNc7A6S{a}Ne`Sl}iJzBG^V1i9htv4TdBykRj%{HIo!Ts3&DM72{> zBuzS>TN$IjHzBKkL5!f`F|kI63y`%&ayh*e0W+zw1<*9u5da~#xGZnft5=(uyCYM?<@)=$xsc3ZFkve2 zkAyJ$DI<`e09r<+<2F;aS;}>3%rK2DO4(tI6!RCDRyO-6y%Gu#R3d6HKWG`Vzyw$$ zVLnJ94T6=Ba=pr^ipns$6LQPP#+8aCrc|`=#d&~|--WL{_wZOYm~pxDS1gbvnBLWm zjpNOFeKUS<2QRhXGAr+8fwNmGhAJS-K~R?Q`TUvX;e@3)+xy3%aI=JM3ga;^{w#6S6meQn=1XXz*W~F)QZ!=QcwA=Exc847t7WM`5^o_c;oG(O zDM93@nEl@%cbyv&2{z!yuzDrI6dy{;Xe;1Di~C6NoMc7@Z>4zGSsF{FB z;{WpEKLM9_jQ>OiGP3cX^ZbwR^O?tg&f`D-<>No&AWtUx#zca`e@l$%Cp_mJymf%+ z-=)aQDN&+aYt4<(Od1965edroYrBImUByoe_8jBaPWZ87y1kWyTY&L@k3)x3|Gty< zX9vn6TZjRkAHq5jDuIT;99b!lco+dprXAKNXuP6A00au!K|3J&G0V&ram1p`P>g${ zHpYX6-iR^Yc<8K7hLJ4*R0~Msim+vI-kos-oAShFReHc;EHU9F&8hg1m0*3kjBkBE6z26*b^i3{6hvy_EC4Fz?|s>)|}k ziwcc##ET%zym~6mElo!qXCO2yubyV-l^SCwHiFRe>RC!|=~%uCA#5YBo}D{>gvKt} z7(`8Ro%9ls-*T}K&b*MaV8_C%`wD>&6Sra#?{3NK9%Z}9aglRIewh<|Le;;xle;2C zRQv>ocj{rV-8Xj}zlGyC5z->*SaTQi+{OG;UCi)H67h3?^FO7(dF~;edx&4S&IS1r zG@rYR=k8+hnY)YU?&8U@OYiGPE{@AY`}PNY&##ZgoBONhpV$55`Tql-)~ofwy!_@^ z|G)U2^8f3)`fnxu)i9Xw`4{*9PniF#WAuf6OpgChbgbjl{F?wjkNCwQw?mTfc_MW<=RNGmH z*(CQ;h(O@1svhiB4>scsZGY{K?B9}dR4}T<51&H4Pwd=B<@ca0pH>e};KzD7whSV_ zd;)m%#B90|*bw&%K-BUR|0Y0#TOdcEsxftqxoJjE+9_@lu9YAn_X2v#%Bl+7PCkWVabav8iF0zUsKHtyl{c`KjX=CZU#Y zX)YnA>I69yBnZ_tsIQvXr?%!>*h$tWI?L6o65U6hYWOHyUq=envFQ_!8W#3YvcByo zx?x!^c2sJ($j{bCzNLCLaePNZj%TF$*Bz?39?RloQjAP{;g3&gO362^h17zgd-4_G zZ(orSQ|&jA#~ZW_mFLm{r3lm*lV@52O@Zl0Or_yD8UTW+z)1f?VEh~ZrSN(IxGum% zz78ToZuke}% zZ^@1_exazY8j+A!6bUl~tR4+f%z_~(sf2ZnxI^LIhDf zKrt!7JcSGr_4^a}N?HfWO(7n!8Lb1_Z`_eyzXdPNa#YAKYX4Xd_l4?9pM4R>7HuFc zEFn1>wm=WUdpE8N=4`Dqr*5y`V7SPx$Xs0OQGjoRq4Giuo9t359-0%}MwP*Gx-&fQ z6NzZ(Kq6(IA-c%i$nK}O4DqsZ`22r)rNRT?M}+`af$>->yLXgy8~m72i`+GY1GQX_ zF6{!y&=g`}cg;=|dX+z$FbNDW?w`j(`GYQxsbItijoQ5wEj+#ArwKe8h?<=iI= zwe%UO)SaI!ewTUUYo*_RFNHtq*@)iKQZn)^Nxgb}7^-^4;|gjFZ^{n0t;sPL)6d&5 zlCk>+|M6>yU0-Qvy_Mm@9ThMfE>9g0oroCjmo171bZEM%* z!vGduliY=4iH`+}%h&+r^rYoX7efmcn&>@_7?)?SCegb-K4>~kVjgr9j*3Sc!4!oB zp97X&YaE`QtX-aL))(>wS7v?IrHF(4ZaHoGgHC1&+1w3UxAY0vNOT^~YHc||@K6?7 zAPNP#p8_zb9K$GKsZUw}1|=vg@o0yGL-yV$>Ok$sI=K?(Qc-ZV1d_` zyP&OiL6etPdR&^ida$<4(oZEpSxE-012zjgv6=)8OQRU`U@CG11hCkL+W)ur=8a7p z$ph&7cl9YIgn(ouS&|P3#w5M~Z;b7qZE`GO#aJ5K6LhUc!uD?R#opiVgT1=?n(2|` z144GK-C${^ySlr&y1Kf$jvN*O=$uB8ik}e6n}Z5D8;Vqd0{Bv~rLw zU2;mJtRbawC9BoCk{JPKEy7_+@rjUuO4o5rsARwuLzd1ka@SPSFTqWN|3`N7wcXfM zhg<#b0L_haP=n0sn=4k8s=3!^=iSqYNTE*g5af2 z3cAojs?d@yWVOGTDzq$xPHad^sX~u+A%tYz$q&moO*g!m|HOClA<)4w{MUW!s&PYz6D)qU+*3{3-FWN$A$iPM#yx4{u=7Vm0-N zuF!|H>!HI3{<}#3KB0esG0lpX6u>%FCm>7o@3#za;kp3v0{Cr%fGjg8?k;e=86llMTA&Lf+=*)@6qL$bd_kN|}ST(v1mIvq$1>evRzaEo?-%Is{noOSs zMcT^~o%rY%_w>my?pbHNlz26WdzLauJuSsO$N$?LqcW$zTIK*0g4}%>w9XRnB~!w8nIRMzCm`3+n7?zti(d9Ce>Xj+MW}H+KEa_qViZ{iLrbo8y*Sa` zssjf*zh^9d1nHgVWW-a>jjW^#prZ*C$hH_%sB-2c@PJ{x#g{<+1Ds(5;yDjw^~{G; z&IB3394c^oRw08iee5G-67njm)En~{N$XMiAqHjPlfd}o1dhk8{veJLSd{=lyR2E* zl;t|x{M-x$d1!!fq)O=lXW_X81qG9eDaRkrL~C@b+2)0;Rr!i~Q6XR*cuG{vqXo5j z2t}>&un=Y*l-1p<>D0$vn!dMbZ4O;<*8Z5FgidjYB$q{yD#Q7SgMDUHzkd$rm`GoG zQe={H?=o!VhHtvP$^l>uRs-Zy9=6-)?U=ec@h;-YyA`?qk4FPQ`pFm=(^;6DQJlJ{ zJ5X!YW^$P62c=qm^C+#YM_InC_B(gO6e1@QGFjcQX5?s*DTNEKC#+te+l5?@YiobW}`1-?Yk>Rk-;Y+?k-; z&`kM^(h&9R4`A)6X|$DZX(ghkL2i`(O?#Q9o3fg@BIK;TQ^Z1qXf}&9&cWz=of!qaX@gh&Ev~al)RNus*p-0XWR3vN1P_TFwmq3YQ0|j zc{a zWvvm-9xMsjuAq35r;4IbSxffA(v`p&W|vb-7+Sgy>Aq)}wT_rJ>JNtf_Sg=RWwC{3 zo-CX#9rtD^JO$y|3)H_J>YGZGn=}|(P@GhUg14D!$m$hc@Erps7xzv1;4pA zGV>6ryJ2H64^v*u)@Gqx-HbjFO%^|h?#(jObfkDYiY3FY-t!~1W)q%&EG`KH!-)uCSq_i;)Tb;0Xipg;& z18X)VC9b!a&LllWnSg6I2zL7;SSmquaTWqELu&8D38@}OYGPYDkw`cEtv^KFG)!j~ zz`&L|=!Bz_KF~1&TWhytm64>(0aCHCbG*t4JLlnL!nr(#KqjL~r9ul3{@?F)E`eeO z(GWplOfiHuI*-B+)q-RoFB&wVw9(u<*xWim3_f^}C(7l0Fe$NL;W}naBb~i9-zyqJEp_IgtuP9E}W9F?Kl-L<3bAGcgQD7u^|a^*))p_3+> zoh>wqwr&eV4m?cQi_+J6No%VJ(7C>1pc|!g5FUpuB|!$~uGn~Pr=U(>5c{r&0oF>Y zJt#IeP!ZzKgWv6QRT1Bmf@gT&F!_Cbc}juCVz%dm^*rAXZ5}8VeK$fa0s4%n<@Rz= zORh%~P@8(6MQy5pLTzq=g~pTui?wM5rgd^@`HIs^6RA|6JgaSF?}jjEpJAC%s!!8u zX4K4~J9}o{pcZ!>$70)PpQ|B1f4-_F=@XWj8DFp#QutzO`ya#CmsaK~>}>IgkDdK5 zaT>!XrV~71E0^H^mnd}-X%Wjri&ZUz7)DyoI3p^|$t)DHWqkTOeuY^oE;K;=X_Y2; zm+EN{Guc$gf$KE7yl6E_Gw#=|F)@79H-~&T=0?+*s{gr}>W4nl;(snK*VFM|YLD;o zzkZg_o&M)e|MSJ`fAUp7j@C!zeNAh4nyo=+oZx?@LUe&VGPt*K52ZlSvqZgd*Rn06 zsOTf%!X7KN)u7&ZQg+_z8=ci)dC`5P40t@R4%c>cwfeIAZh!0GaBp{Q$GoR76kiX9 z;b}LdMOhq-lQWFDUcj6}h&ax$8Z?`(qpQ39yT0T>_JgSxl+lH%WZW}zYyc=bL8=n_ zYfdm4fJzJLO5~0?$uVDN>y>+3|6T1>^zLr;LUM0-F==RU}jOJsa{y1IB z_9@M6>q)wnawDvsASpX1&nYNUx>02)az9VzYWkUQPt{?SEiYWVo zQX!ur*$U}D?nIoueUf%|9BGF?6M5HpBu2XV9;sTQvhCCLL)-gUfzu&VR;)3KsZ_yO zD)FM?ktNJEG5f@E6oH^V1g6+Qv&6P!4?-)}K5Q@Du=g+tSVnAO!muGFNFm;18$UKl zS|i)xW(^m9FduyNRdM6h+Cg)D`v{esPb9KawnD>7`ymzWJ5@DhC4^$xc+uelw{K~r zM7#zqnMbfCbCR9 zvdheofHrN~ZpF0M`Ao6%U732Tk&6h+Uh>N3k}Fe`*17V+A6iKG?+imaYyJn2dOuPA zho$;b=KS}#UT@r;|31g(?)-Om{`=z2f9Wg_d;3QdazOCg3Bf+i2{Gz|EQ59cY#Lzm z{KLb;tp&Qd*QG~RX_S7^x2W0eHj}gQ2}qR9Xb?XkD#eFk2jt2jKf?=ewQD$y{Jgg> z7v9Ag4GHZ2Ts&E}dT%xGm37bj; zwu;$MjvV6AAIgy{0s#TLo! z3ys@}fqAeD<)Hccb@TAmn-?#3wq$~E@THuV4Zx?SpN++vx?Gq~rk_u^ zo5NWfNdvU{Szo^Xq@+K&{hZ#2AE4FG<%O&Db5iyR?&n2+2#3dd;|Y`fu%jrI`i$+C z$}<8?e~2Zv+crG-Cq+M#06zU3Jxn?-K)P8WgqLs`le+|E3^I&y3z;Z!c>f|F-e{3e z9`n$QIoe#X4Jy`VIU_eNE*xQjh-~tWr<9;|_FW49o-S zT)GA#E+x3XsB}418 z=E~J#TX}|T1FYWw;4OU&zzv(QdGXzh4mWJVmeu=Z5%zkPu$l8*mk!sngw3q$iy`cF z4`Jh&D_0AN<{7dLuzpQ|lLLdjY}{=QcbmhN0p8MQhRxw>LHlOd9IgxSmOgiz!`TnAvz<}g{GwYk0a67ROR|FLzG&Epg98S02NQpmRyjD#%g@{_6P@&K&+ z0M>ZSR{=<5F{<4xlxT)5M)lhRcuOAxkS1f}7Kcm>bmJC>ObqlkC*_ttDIBKh54W|= znF!hg&_~b+Y;z`p&H|*3{5I)u^EM}CvM~H+_f}ZjpT^j(!G|U@wrg<8JH~c%fOm}T z=6uM{*lxfn|ALH7>)=uIZmZq@ViMfuwULy==+n5^vlQu)+l+wjqt&aof#1ujqE5sjtglquLnz9E=u1w0HH${{6kl*U%69|st*E+~GKE@RDCzF|?5=EE8X}RY z9NXf{j`##E#6h>iyA3vHjDPgirm0{TH2vy!%J9Z1xK{HOT&sCTg+1LN>D zIi?B<;cvRH{Jl2A(-&OV7~Y0=cpJXqZF+{66>Z#s>MN*JL0O#ZR~x9lQNGSR*1hvs z_swJ7GmmxeJgS@CR6#Y5^{dUJVzk$pNAK`9e8b!H3@Lp9oV|lAVvR)pIXQ6DQpwvn9K|uK{ISXa8mXSLJ&@9~4Gq(DSW19$Nqdw!< zCPLY)PaoUtq;NwHKk5#w&K`H*gfEi60$01(*lz46gFnzQ7PPi zSv<;5pSI>&c-1WAX;bIbv?x^LN=Gtx>aN3ET?n7Izt`Iht}tn{^OP@R(yj;L&z!Vb zVdP92-4$gO(vF&%9o1*lR1eu*uvbF905zNN$kB54P{}F&jj#bgkvM>ZAspI@>L)ui z($~vUfgKvv194?U$Wy!-v54c)=sqw$jqda7xixyXMpC25*gWbOI;X4G=DeTf(bz#g zs=_y~9;NOrXpZa|mCI0sBl2I%9O;K5UdY?jZYEv!Xka$15m`t4?6&Q8)TcV}j>tNt zXS6Is5k1LqDRYV+ituK=y|K5_Uv%*5eOYx~Vt zYdb$~9f}N_uVEn3PuT)m=U$80l#Kw8$%PS$vqW3x43jpL`cRD6X2&v89 z^w=YUr?ByVZ`KZuwhpG?!-F{A<(<8JK88bA4pycU@Pu)~RuDWgw1p^T1dcV&vb-ML ziI*uhcfJBr{z{{sGKmwB;?aq0$ZAw8aYI&PE(c4uosv=Q*B*h-scl49Z|yAOxeEWC zgs;!l=h=6Y>nc#aM4suLF2JxS6yQcD6p-HB#;oKl(Md%-{ZAM1j38YkHHMs7a$cjM9RGD;u~B=RivPOsclqMjzfBPBr>#D86(huQRJ+z0aDq9m-oyk34emzK zdKBP4Wr|Ba267#?!X#3$@e;sA>ntc@5%ml|SVopuv;9;*#*b)~HK^db;2xK3--Fqd zv9#~4c!9;U0*ftRaUQUlyB6Dhi&f_&eZ5q}MDnETMobC*TB8evN+`S09M31IQnYM~TW`fej3!WZW5nK>bn5HMvYtz?V|VJUKyD^SIM* zeMrhd5}hI^Q|URVtn??QWH2p`B+p-0c%YckR$|rf{SbV$DxI(=UMH=`7Y>%FvQPxp zrC~pKpy$H(Oc(StAsyM?-Pk)g*xER19{sYv<+Ommnm`eY|ih&n$5{vYgM#$Q~(y>a&#dFM&c344*Aku(6Agv#?S%sb|q(~1vo_qKPB4&k8&K@HgmNH;bk2nRRr{G;000XiQP-OAo3gvLyokkJ|NIiyzs zFR4PJe~p3XOH(-*OLb^&)(*&mU^=bh_5xd#Jp=M+#VsiGuqvz8c{jjRCC)64WEMRj z%m|#{sj?Y#`_`W>jRVdr>cxYnzSDne{&k_z8En06cbNPrT@V)~FGGutGjN`#+P5jz z)2LfGy>1s^JMG1z7+1)F5M06cheys)1904LOQX8o#<(F zsxF-Hv#6*yrA)&vyWRUCy~UluyrlC=@_H!;smII=vzb&<#W3egrxSJJr0eE58JxHC zDog4UD3QsGg1Mo}ZZUl1&FR85a7d{d_=q8s#6-eXG_5yMit1$qs%cmdzE%29!QPye z6d`}rQXM(7uJfE?Dl$Vpj2u{~GMBH{es1pnwAtL*+I@NSDu0W`GDmxR&7Hm7mzgbH zQ0YR&3|v#eQlVV9f^Zk^-kT$Unhz4*@4uM==rav;d-p0p4`1ya963+{!^rxH87c6x zEnrjy#uEKndmAvWTmjBxlNV8vDrD+r9*Bx zAOp0c+uJ=nYHq9@9$7HqRikEAra)k#CO@!X{honRWO3%;mFyf-B%2y=DrHs z-Wp-sTbfxF?r+u}uU>Z5%dY38+GQ)6dyWAqOiABxU@dt0OPlnNim!0qw!3#NU zZoOE018eHV&f3dEx1^Dav^eB$LDqTYf!+&9^0pX=l>Tbf>;}%E&zq8$5?8q^13x%0 zd}lqHxQjyj!|lG| zUr?C<#F1d~Bo?GS8{M|Fr;sREbFqOK&|_oSD_7i-4|2A$5wX1MM5zRFfe1bPxOH%d zJL&G5*XvscB|mWhC%Fy6xH(bWgdqIHFinE}ob$@P(DTaET(jnKwn=N>t?2*a6`haW zs}RTCivAK-bbH1X9edYj5O$fJrNhF+U07;2Bnj zFOMGC=c#t^`)Y7pe;dCG{uvxM;IFMQ6?_)~e5qKh2M>Z`u^m)`dMSARJa|$n(f70} z6wcQ1$z{>LT1~B9Lt|cQ@?h9^N$6DwjxJKlzjlHZVXM9#5SQ^7ouxcNpZ2U^U zn@+-bUS{D%^CXTs^6t}W7u6|ym3yBLWpgWY;1n>{NboXcG=wh-uBEB7i#-qCZ0{Z| z&={`MBpkta`vDG|W6pf=`FV6n^<-OMaWD ztt^;cv?E(7^8hMZJDI4w)WEPto<_#sON`qLmBJ)$M>Ny23`MQQHa@3VBIrfuqNS-S z0?4dc!R3`F;}hVYVK}T#^o5AQBJ;bFJAxY`6n{K5N+3mLwqi&P)_UZ2A*D8gKN+3C zP5E|?2qs`PC}&ev+iLba^C$ME?UBO%Oyp$x)1G8e;}@2&g4VI-j`MclW@aI^dq0Q`pHq-;diReGnka30YK=z&*nbCoy0$=@ zFf5l3N#7agf5yx_1GKidBtW8A7T9WizaX130tsRcSY28_ygq9pwdDz+7IM|wuAHEZx zh9Ltd2S*N=oZcL5zuw}$yk7GyhoiWQ2J?yO4$7sI0PVnotr-AyfC)q%Kq9&lsO_Vp z9S^M6Y-2S`w=8I{-)y{^307XucGh;c4hhtYt)Dz2gsLYX?~~EM#Okltc7O5L?}ok0 zTmZN@k#VX0Zo&dhv9B^5LQo+lZ{liQ*t=xv8ii8Hjp1U#h`CSrd( z{BC+nYt!(SUcuhx!dVcPbMVTgJ7wb7@A2N}0r}!!YfHi1SpOks-$KU?JQ^tj#1=q4 z4qG24>|oN#8G$Q1mMb)147c~!4%S|89c_6KA!5RYYxOo0R5Swqp^=ne(2arRfMnuhg|7~_);1?_irqeH-}>WI^f4g=qA5_OFpPX4Fq}iw zU%}5q4-Ljif_5;#@5W@y?SbH!d1OIsDO(ym$46}s07r+G1+W=S1Hg#LseVL5SM|q3 zAK%tJU_E6Hq{BXJQ2i6FwnJrmHyWXRO^9~yvWJpS)r4(1btdtzCC!Q3{fK!9(Gn?> zlJQ{BiK8}2(b7OWItj;}Q5M*n-iKcQTzCgLwrRf=RL%1tT}j*e2B(<0XG!0%_-|2i zj+TL?I@Z@7`iZ`7@Si|sB%-vvcmMv!)%)Gm@@Ta@SiOJ$UMYB_-g#V@*lno>N5n^_ zZ@qCBi}TR1zC7rrA6P?k030tb;%lWPg$nXS-`Hpn{(BL4U&k}gpX~!@`Ty1z8jA}l|6lmNbm#y3IX-v(zjyw>U!?!9`1MY6|IN4wd)dbD7~ZUv})w5?EUTl#yL7E-dmmR z^K0*(y6LfNf0JklUtBl8X+u#*;BW)7Z|A)&p)U7l6Ki z%nV9t9NvC2e)lxEXMvQfA*&9OhRP!LwPhOrW1Bau|!R)R;5;&dwxWi_ge3mjCjsOeqqKy6T^xAD7_sr(-W zZ`V_O&Y}~QDp^#T`+8j=cWBDX#y7UBjEgQ|-GO=fo3kWYYvUP+a_PASS+Kh36B32) z+^x_BL%T)NNa?7u$PLr$EqA10F7;n!gkhTSX8>|QjlZXl{b5u&6KCIcd>SPq7|Nus zD-Gzu)~mI{SIy1sms^L*{qVX2(Yw{G!{C>H$bL)jnxpWvXkU@j4W>T(3g7hXnfMzC zA8kD*?2N$tr(lMgm>CDQZ{hXEt=)NypplI#F=t$@Elom_XiEXxzuboaT`MjJzpZ#W z7Ob718V-TNCis*#d}?6=u2h4tBRY=!KI9qwMgP2sTDB%`b4jq8;R?kZu*OdA|8P4y zY;Ny1*LU_dekghMDBlHj@AIcQP*w_Aw)Pv3^*0!++ie`;Z`pPgI@hto!8g^#aq#w= z1!OGW)auKf&IO?rryy7NW0n;O&iGF$jS!%->c_Xgxx~i*8Us=yt`p#F9oG;AHCt+O zPNc&iHN*3AaBmCWLT^d_VJ(<65?#cjV%;%Or4~-39*SK+q`-CHP%`Qd6Hh3dlr6E6 z3ZWk=nB5U_Aa*Pc78>s3{hu~{kMULopVyaD&uMGJH&5IbYXqj=pb_P{hr7Imum+3! zt<^uVdv(iz;PTe$thWpb0dMWD`%Cd|?+(RVGL$CQtQLiZC@)(7BlSi(0WS(Hpy?zU70H^ZUbg8#NKXo|O?IQ~ z%zdf|VUFTny4Z7zg>8zFX;7z_T+8ts&vzHM`skMMI1Ssc*%mY3W!$14w}jZ7PI3&l zv63pIe8TyQ@1+ew;mj>ZF5+Q3{m`nomhJY;XL9Absot)xz7~hou`CV*L>aQa4rT(sQ)R7Wm2nbtb;zjeP@Nr zdWp8QJ>($~Y*V7vBW5i&wf2UA&(ZQ1ZG;gjY{T^u?5+g0{tjb&sbFDgwvQMSQAT(` zivJswx*C7WG8bBIbq7V&3)rLD_Z$;8w;>@=IjQ78h$lgaXM!-X6S3P1Q;fIcd*?&k z+AX{rsc_;HrPMN(YrRZN!|s#8G4y%VA9sp0WsP^rQ>9+h%_=yl*{Ii0mQ;WqJn+w! zRi-p$uZ}8y5~b^>LGNP z_&~qcxnvi|gu{MzVOv3xPtYQB7?ULwBMglJ$xO<2Sp-&xb8UPSi|1#+8#Ng0LpQvL zyTC2zz=*sNkFsKB`7!K_BWW6711vo5oJVb#EA5R)LZ>**rQoaZNJ2}=AZo=h9PAXg zP%7){c+$1LV{a{BXZ;Sc4vNF8jkkFEw|o4QVpb{?x59D4_$QTAHQ2L=1p5NbAc=5Q zY!^lbzy#UEvW_F@gNa@#%^e6)F>(-wp*fopfw{p-kaq!-gR(Kz1nIg-`l!x1S{_w{FD27@ZApAC| z9Pgy?|IUw3{%1AJ=d%B*Ez}x|8T+rsUH*s9^0|}$@8th4N&XMMVoAHL6jr-?%D%s3 zCwUMaMOI!XfvVH|X?u48#BXCEb{_ZI{quxO#CRjK-G&)TlkgrD-G?A5gK&d4wES&? zO}ASSMPjIie^g8xD4;`tqcV;xzE)QQhKz9{u=Iq$9+kS%r}>79Z={!)RO~o9g)vfR zqKl%AUBey1uFy|v$dpVa1o2JbVo1x!$T0sI?>+oZ&7PhEWTRX-Q3wKsZMS0zS!Q~KH4fFa(`Oe zK5Fi*{~bMIY91_aboxp3ifX0+mC{Ht%2jKIaxq0?wejTOhG@ja1l`F}%BcxBXaWR1 z&9#!<{=kNlY0#vp$}F-kFh$kf=M#Q>@*i2t-kS6`P5xV4T7I0C{}z@O>UZ+r=lI;o ze|PfV7bE}8&%t)Cyk^hi0c`A;R53n5rEv50;Raq$<_LH8!{acC;2~~s2=Fj!jfc@c z0C%r-$`RQNt*td^HV=&>m7kLt~)*80kupVoGdtk*$ZLy>YnZZuzRH5;|s zQc>TUs&B#b)d0@5wbG5;96UY^ewkQ3JMM%ZqQ*S`neeKD>zOs_jP93PyFaWQS;fUG z3_*w>?Z_p~RwwM8Hk&1S+{Cbq&2R)AKOTdO2#coI??pzDzPopXIWf0iZ~tR!6N>Ai z&1O-TE@=cu9jC3AyKgqADS`HKV?*6s=L+dFd^qQ)h7SZ?#~mto6v(63+q-)Q>V z?)Q_J6!@gSMD2Een3%Hj#$|?$HJhYPWe1jE?zpUdXJRxFP$KF>3hzHuK{sSC@C#k6Ns ziPiRx0PLK?yRKF$<%}l*YKmk)+U$EUo`CRM8WA;&!*J}lGb7ORQ7W6cu?Lf0JFR1TB9$qbt3Bz>1x*?C-;qPXF9CXrg}6Y5Ktfr?2yYdWAO+H|KN<)x!asEZ?reIC`Y5oE0Sw2wceam{V7rMk?cB0i2BL4|hjT zNZxE>;u+O#=6xSEE_xZgj!3s9Toslash?AeX-T#S5PPinu>@J(gPVzE7~M>$C@KCj z6+qzG8$`YJ!%Y-luu^n^YZ$kDJaJg9hp~LBMKUejFlOO@Y0rd zl9;e2K!y4GsL9$h^E@1zTI@W7lUCUTXCYgeoN^n+4o&hG;w@LZbQwnzbCYa2%vf^T z1Isx&?YDxvs(xf=?BvMc8XU~!&wB@aGaah^Ke4kh(SF~dxe7XtClcF)!$#l9^*}A@HJiZl`T&ELFE0m~o_r$_K>bCLZ?<5A_8gEvI`l;m#z}*Ho*34_@xZ zRUVHksRm}tZO+Ufines_Ql204 zIsSL%l!iYYVcvKb!m;zB8FmI|;S9cv{&{!m4dmd7_0)IU2QrDq?S69zlb!<&xqT9L zBVJV62Z9UF1?X=d)SjxJ^f^L(A+d$0l$kl~pvDAEw|a4MhW1@5Rr8=TPV{SiG>+N| zoG`9f%;2P+)7Tyv7O}g_l;)g1*B|9~x@hOLrVI?kMn7G*r!*)v=UpEVttW1V(37T- z>C{0TN_0rmsi`34MS@ECQPYq`c%1Y*s39@s_5N2w!B{=7JXg-MicC-mh$)cS0oLLd zp1KJtH`BX|20(Aq9LF6Q`he@SnMp#bUafKrl7* zk}6hUF+2@wsqN#Bg8MBq2+D~7OSA1I$lQ7LjyX^0%HMYNCm#>liJ1YMHFe%;`+VJ> zq4Jd`Rry~VeMh6ZSPfo>1H7NG_bEJ!)T-5Ip0QTy&q;h44EybID^d(su|bV;lMOw^ zAJMtgw6v02DEn;A^X&O^?Y!#;lASDAof9Ue=&O?3vN{n6Hka^zZZIb6a$@|1*AzzF z9f4C9TU)?aleU0N-C~+AtZH|~^nN#)oW2WclM6h}w)F^i(R@af)vqi8NK<2fl%11O@J;R*ybF|fuDo8Tp!eAwo6quWu2T`im9};q#Dm{pway_z(JI+w z%Q}fWN)Q)`wV8~HGaQeNL;@miSs!faj5%bT^3XYBBIWQQb7&I~RY3z18ilIoQid#&rWXv6DSW7d9}0J-AZ1)>dGfOHwZoc31jlV-5Vj&3 ztcoEZ+(Y!nO z>6(ni*DqDWV?WE^-*!M$$$)xS$^(|B1}koOb|X=r6h)*ze`KEik%P1b+hs)xX&(G2 zyjSUn1OjQcOf*Z18XF?gn1>RoIsF%(wiz0`DS8%ZWly%nJ@H}{TOyocOo8jz=zNjjx5EQMpwW5 zIuln#@3<4{@iy&o8W^@#X0XRE_+_6|A1+=OytuqId*$ z3zq-*rn~C#o5)Z&_OTv(SNPlC{x$^~oVfjBt<#?EmO`$@XvIO?IGKDa>+|ACy}A+> z^MKJ+P(H*|a<;V2;71u!AU02KVqGg75C$@k$b8Q;w@}ks*NM3@gR!D82=r&yf}Tl( zY>!Q+1}W+o29$}UWREk0R*XVyHLbNr>1fOu{bf2$vz-GcM_ZUev`GMMBRk!mKOyu~ zJX^ps;hV3KZ`wvQMGv?Vk|`weL@eu+A(POY$*naTo>c^o6rw#%dYYRF*>(%rh|)8( zFd5$*)vw5&24QC=jB^m>$vD?Br6*%On{6zE_q2*XJp%;7LH?E6PECSo*f$s4mM=W@ z%x#(J$k3KOF<~nC*_CD}oWgg)>1=0h3fGx3D{DUXGh4G)nUFOfBbvRL8RtUfR>MG( z{(X&g9QIgMUZcF_nMtTPi3bSyXV(Ic85T3ZQ-A>UlVC2DdEmO8w^29J2`2rB!vvK! z+D22x>7|MRc7vhSd8@#hNC|{pBar#>dHxDVZhI>0T^@CwP>uHh;RlWvMXk`KbHe5ZZ1@@Xf+%dAv0X@* z1TTxPYQO&u|Bp*Sf2c;yPwVv5vhKNx(c!FGSdD11PF!eMxp5v%%w|w_uIaB@8(uG# zgN_Bkv2&bm?`Ii1=BUF`%^z-Ush!bk)$;gxkckFA$yBxW&f9FN!PPV zD|+xLOBpw?{QM)8S_;d1m-g)Wq;eBVsfoagyeL@5U$3+ww`!BT^xj(jamXf0?^bfT zBPxc}BV!4i;e!sJQ$4{^7a!=JlqXV^qDV!J52&l@3`;UGs)g~OO-gC2jf{hu0wjZ` zU!|$7X^Y#>)11hNpR2ji=WWgn=KRUpGXyPh^*+z&be^tTZO)PWF}R}FXJhupY*@MX zG}$pZr@0xDOy%Vs^SHn`J<366PRHDPIOi~!J544B*r%H(Qi ztvP8_gKegPKqbnPVWLZ26T@^o31Cpekn?|{mA05+Tjylg5fN%$jUenMr4xAn%r}Z! zmt!9e+~YoD-MaQPat(k)hhGHgjzeX1nS5%QcE+19llcRlYN9{w0Fb@bx0CYDgd5vK zj%_PA+!Nr*p3-t~j*kB4;iW{24)Hn^eV9h)eajyzWcMB(m!LMQt?~GJnrYg=nNSu! zg!|d1D8uU9qj0WD={Dkj`QpC~$GzJO|28H5TVrvlwv>+lw(xl2F82X}wVwW!9&BfuTQ7nI z{cvaRW%IRpQE!lN@=y4?8Y~8{<8`t>Q-$d=h{_qLa*^UbW&0U!%OuGpiw`(~H#zI& z6VtahyKfF*_t0Wv@uI{wm?ik;24@;4u&kXFqOGpJq*e(}-(aDqLGVoyysezQV`GrF zmH78c`}a!Reh1${2-gYP-?Djx#p8A2M+MY^PR z&w^qJPpp}+eDr%|h<`r@#d_`c`aEiVs31#`P?Vkn`G38E2CRR0utvj=5NAXfHSHVz9(MJX_K&( z!uOK!*2nJ(-;2Rc*ac~Cq_S#7$%un-sXcDJ@I70q_{v$_0U8s|0K3Lmtjo+hybrW9 zyTbYQJnYfV11Gn__ky-2t-f}g3_5@%y%cSv7QTmtnNtqPEo?_EN;zdM+QRp0J-W-Y zU_1+nW}zo0laPuI#LI(j0fa(X%dg&W9%x;SQJ&RM=mL!PvK{}4T;&V|#$y&lHjTMS zJI0vfCkj6n%v3(q7KL_F5lc{_ETe9BKwnqv)hG)5vT6nwU`mlFceqX_@VS6Z0xGdDZZ46P@B z6DHd=tV~QpMa?Mq0U0F^+aqlP zK{!a+5~09gtE*N2=&iUI}qfGy0M=1mzxPAC$Pvq?GmK zYA2^{_ngf|^@R=pPMSI+rn%82%+Uby-a5<2d85TH{WL9Jm@7s1uwr1uj&Q+rWyuHd z;H|ACdRJ!o%39u(TK<`vTAp=6H2Jl6nZ;}J-yR-fa##3yC<~f>4@}1T)u4eUwy>MG zx&sDShd$h^0E5>ahcmWXcbEpu-Dxy3?q5cGqvlQ9j+`KM@P<@Zw~xFIsl1Udq{cH0 z&6ANTdVSLv0yI06TN_4YW84F2U*(b2@K8!2#dU}&Ne6@e5Dx>G;3-RL z-LY|CQBfvcraKeeA!oL;GoGR>2XHqFn4+7fmZZ;jS!ScsMYVtB1L^8%IUYx-ylcac zR&+1bGuKJkv+`5X>&OB?5Y3SjvmF8SuVfzzR$;Iskd}%v2`a%_JsojQH^%iavN}2W z%C9%*P(zaQ@4tIR7%utTPMs~r?d#h|hk3r=g2UsGvdO}R(-J^PXgE39PG&)bs9fRDFH%QkRD$M@>BY!m8}s|cujB9r-sU|LzYPAdz!txV*7agXBZq^^gi zbH16E;K$jQpbJa@je8$@{qvp|N+zmETKn_ds~`aB88zBm>{2Dca&GC8%$16(U48H% z$SP=E@B>yJusK$Rv-cs9YmJW9(QA-j`82jlOLzp`BBiUSOD%<2gRe)6d^J|Lg;iC1 zTVH>o!gWj#9B(tbFk7N?V`H?epyJ)U;``>l(*U>K0@dBXxK~tqdynQn=VnA-7C2gc z_wLW!`x)InH|cZj{KduRXq z<=Fp9a$7f~ygZiE3 z&`_IU)%Z~&T?1H&?U)22zdU7UDam^p4El8KZ}w0(fGC!0TBbWRwlleilR*eZIMz0d z)*phqTHqAmCRrgxfG=5Q+#ndWqJ+|bBYdPFbx%<=f#K(TJyZz_VSCqAVPJ#NusI6+ z9a7;ct@hQ1Y1&tr5oc^uAWUpi<#Lwj$%&3SjSKI4vaS6MsqiiJ7MMGfxBw8gQbGCEH$Xb!)-oHK&nE1Pp=(_2rCT~hMolb zs_SPVS@KX^@iqpk3602(1N$Bu$22ULZU&_`6wE)I1ki#Vk4Kr29@8}XhpO_Md-5!h&&0~q;JmUh|7&e+y21lz<~~p545? z72Oajfq;NA3QX`Y#C+@nWhjMhG8j&b+=)J-uY(>ONpu8)7fMjn|awZBnCwRZpi4%fJ^Vz37s0NGa36iLaYKBm9WHoUMVKOz)NEtob$o7iyBdXnx#8ZYcz(vLtgXd_JM4b~uXhOf|ATjrW6JvlCJOK{l(I^6rbO}X( zm!P0M1gQ-UFZB2O<35OP$Sa=HticG*p&VJEQDRx_73QoMen`}EP9hZQnYM6ZLKM`Q z51-4d31bm|7XT`Zb(7c`GF=pCTb(`-)yT@Ou|jS@cpQOA>7OHkcVXIxAq(h(K_A-! zc(9hkp-6{7oF{OU7s(b*d;$Y#X@D7Rqf_9ufCpFrdbw3@gF zBq(F}&$*x%!HeTQ1+t(r;&3P9tMX83)5W1;mnoMqnqfW-Ho{)m4y(6`TUV|q!m>u$ z!lh&0KR`xby@e0LnwMsAj%Y=#7><>kp~o708=Xh6ra=5Bv1sJ7P|Y!R`=f}pC&D%j z^E!@zx-qOc9BYNWf($gIRBf;x>3oVd-UC7?ly%>gc*{ns&8RgdsuHtJwSM&%3@Xe0xe zRW*tuX2GN3n0I}Uk?27(8n-^kS_BmJ`bjt*vRK9qvdk2s=Tr=xvAsLD);Bh{H?XZ9 z!;^&8G}`XCbq0etJ&lN5=@gG$36IG}7Kkz#Ghc5LxGdLOw(Hff9=yeRL6N7K z3p{-EFbzvyFVO4xhuX!~LYziO&{Dq8F5;Feu*ey|v?i?zv}9PG2r~#S^O7SXEdpVe zcxz{>cCfDzjZ=X2aSCuM$d9C@-A43$$n_~ERzq~P$}|CpFaGfl`cXuqiuBB=@}XV+ z-==)d#HeaDyV|#QwamO=iAPidr^f;%@8$i@)fzt$#>ZDIO6w>Zw^ONbUl1wz$@;030pux@DF+Ei+d{D zwH2j>U_MwN19{2goxny18>4>x4Zh}1kjT(@YHqLKy|Pilw0JBl4~Z&N#4@Z>cdG=C zR#jv8Ifgy?gX;(r6a{a=vsJ3%3F2oc$F2)QHGU*AZu0=}gCqCiu9RRBH7s?0hT^wE z0G!gEyG};jMiKu2+F-i_-i)Y!^vE(nQEkImpO~itTD^R}8Z4&`s?@s*ymQTxkgy&- zq5(jUOPNiJdITG=K;Uh7;f2R6Nnu&{!yVvE4Z+Zh%fRJ+iGNrycS1`_mJbj#5Wid>U~cFo7pwLL*+Z46Mrmoc3%v4nyIBVjQ2 z?!#h{%h9N9z#uN*5TJNDg(kIlSSR0QP`C` zNQ5Jrg!DFp?AzhkwqF{aGZo`zzHBq@xfJJ?z!Jk&iX&@=d>vLS{3y+dplPn_Ft5q1 zjok89Rvc$Y1-5NPH%9lGjI2fDGHikvFxkM*#@gFmt00J+4i!> zWw&9AH$Iub8=ttm5o;D{J1SvKHG4j5RpCJ<3`TY+_+gH&hLC2fFJ9yrdn!YbIb4cJ zk8FG{{0P_TzmTf{#n9q2)VYN2={3)mZs)(Dc9aybYL=N4O(f%~vw^5EGkBCoXIOIReF)6rA?X3laau8M zK;*-@kHo4yhwjj}f1ns;7;qWclWHiOb*f75vwAE2cA{#mula_Q&NQ=!=eLGK`W9 zgh^+$8F^R>Sqs$7uq1#}G(JG{=rfX&gwEwF1~dYhTMg`;!yo#k8o?E4swzT5232 zrDC0NUP)j)4_6-sgRrgSTO;0;kuCM2a|#SVqGk+oEeMrS$wpvDhqwl*3KJ!sje8#w z9n%Fn$4!@TYbi4)1U}avwxeNL$*vp$%{hlxgY`a{4r$v+wI6XqR7LhpsafD4R@R2v z6}ugg4>1g{$?@Yl-m2pvr-gK1A-A86bXK zM~%&`jlE5bSVH;fuiV2wW*yY50Fg-pua{HB4FUe4^b>5eRzp1`(V0n4%Vb7$7b~L; zyhrVzQxox8hXk8Yv#4hQUSEe8|EoxF^%^923zO^u{Eys3-hdoG5l!ckpjM*@2`U~- zd#6Qnut2w8uk94ST(;*5!!U&A#dYS?)bNeM8aQ*k0QOS zUVk!NfPNy*rD7ejE1#U3Zx$LiA?Z7EHsp+l9RdVLEfWs(ze_A&ayFqmuQ@F z@SOLN6S0Hb+_Ymdo3q^<9p&U8XoBwj6e(**iWaKuq9f-Jh^eTC7-7rGQf5Iju|u;? z_$t^5g?O;)9tm}p5+_2g)#4K;Xr@?Y z4q2_O?vN3^Q=?eOVdLKYkE{2}&c12a*FjdP=iOD+_e^;wrT`W$kMawTGKB~Eh3)tQ zTwBNKG4EGA_(kri>9K6lY1tuDs~g#>6a`n)ZrLVXYr>A$h-0MgPfy~g(@rQ_rafC? z#%52GB=U5kjGO1qjTJo)+u5>V+fz;@7;GJX$kxDcv^j4mf9I;>N=Z&qFib zy`GSKnH51~AINv2S~J6g%&cmFEzhDRXCpvFTWc&^V@h_y9L8aSmTrW-htfy1w@2Nc z9M7%0TkDQyPPPl*m5UXBf|+9~-pQnmLAv$zn0&1_Hq19%iRzcozxoN3sKN!a22p9k zCfLsSlw_G}J%65aC3zek;--1CGhy&KB#*(sRYlAu9{2#_)C;udtAV)?y><`rA#Rz%~HZ)nxx%fK#SxolgeW zIuWIt`ji|hITj9O>>g>sX?CrL;YVBQC?n8TErY%*GO523hZ2UuqrPQ^aucA_&PF-M zmYEJ3zQa(i*fiyAGHG^gG3hFj*HpQS{sJp7@-*^=>`{k`eAJRZFkt8CVVCM=N;wA( zEMpxwRGCqx%pg<7Nk!v!dfh%gq>c>v#p%f4o)fY&LHWu>#5+9H-+tEL)+rg8XjhgO zQM5718N7DRc;Ht&A!Vn`Ma5A0^BXDKK(>IJL%N z*?#+fKkXfC9yYgkxtvjwS=Hu)Cr+Kcnd;P+ol37}sDlOF;>)S`onW`?sz!Y+J zwY$b3iN@`IWeCf^-&MLw3VR{ZoPs_~FokqOzqwBMfe3DOS8Io_ znw#4%w}3u(wsv10y#naV?i8zHhg(~lrqJU?;g6ME;`Puk*%DIlzI?(JpJ=kC8xJEL z!L3;TVZEeM^D(|O$LDx#fD!07d75G-BU-}_jcXnVd?ZG{n4k9!$k#>nkE*FcVM`gs zUj}dAp$Q~8tRVYLwBb^T8HEa)Cq{tOS`!YRxW<@|8IXowg6 z;miOnIU*+B*NUDh0uqD#vgMUUf&G%Ql?#{4>afgn5-?>*yAksNqOms;`y;|+lHTTszvm5@doDXE>rxUxa zxK9}kD;AjD6pAu{xNV-7WW}u_@I&mRhinani7 zs;%Iu7=oWi7QL7?%#v-de_qu@*p5+`a6IPdi^MThTo4^vHJ`jxyPCWly70__d4&8S zL0K$SDh3JaV#N&FG(m$tRAU1EhIY}3adt|C`I~T|xWB!KJDo!&n%rSX*hJcI{$o#@ zwS4CE_knW!$n+5B!RopNc9wk)`C*pq)4lwS? zFh;f`cbga}jD=sFB|xm&g$6Nt&j?6TXC&7-!4qU#b0`YhaZnZMrbwTC%~T_awwtFe zSk+yYs|J+%$%U+1B#(03V_Psqil7ZGl9ixeNkYtfR1WtrJM5fra=%}{(GBU#P5fi_yBEXAkdB;cW+5Gn zOfxI-tf4a>W?JqgHk)J{5^o0PYZ8;ysfpwy_F+7!c!l4-HXZ3EuSQ93HIY@wnBa=D zpF8;zXFgDJqQozXS|B-hF0+#)v9jXR9?l3BoC;09uG7^+0pu=Mn-QsCWa2V!s17 z)2B`q=m0iz%bP6>k`K{2uL3PnAOz%lywpSA$ruk}w0T_oG-(w$P zyNg(rNC5~47$!<^Vb8+8T~>r(ZXJXM42GuTfh*TE+JA^FT-mA_b_Qpm%VK$;+`;e&-wLfpY+MIV~;eHe+L#25RIZ`Ov*uj{4 z6!pVGqsC);0j5pVCMQzxr3MaPVs^Cs!UNP}DE6d?|xNkMZinyy5JS4_Oenb2rF2&i|CVy&e6 zQrDg)pADCZI%FeU^dHf%kIcj*TPO#WIzACZoP=?QH(xau)!=&>Y~?uyk6@jJ?5o{= zTMi&LOq2G)V6Ql7*PG5>f8IM#R^{ZR&f7aOcswBBWHGJKmOy6DA9O6b@U$9iYUw{w zZtD5xo~avCP#hJ+t5&@dC^wg(H@rggFye?j za`lueY#O#KW4fNC>D8^#*XcNhMlpev(ui^5X=GsuIgDX)cq{G~uxPre(VAzyjIWDN zpO|QKxhxZ74n2T&uP^A5RN`u{>OzzJ#GK9SX->!+5dcw z&z=3xo&C?3YX9@Y+ELd0hacu=agm$&0Lr=I3*R(4=MNpfvSaU6*69is#xT6(>N*9> z7nEnd;(8aFi4Svl`ax4pan=BT;7yM461w$r4uUHXJ<3x~LEqt@INF^o)?zJ!8# zB}Hi10z|54Q-T;VYDpg&)#)2H2^Euf+M#iVgZK>R@bolFOer`O*ce9PSiK5q{sb4P zLLJK8U|H{IRA$9%I9S^fHk4Gz;OlMZLeUNtO~%(+k7pb;rwqtCYtjwlNN$t5eWR~T zofHQ%3#g=xGAdpC!8a_K1B#`mF{cuB%VlX}3_*yp+)%{CBcgN5eJ6+gnV+=$*A08~ zx7`K`d5`nuKl<*9#xK`}~i~f4=z_MSA_V+L$8$H1@Kvz8_Ij%zMSiUq zJ6n0g>Rv8-_{;9z{^9mvp}MYKqYG1^daxe64fghrw)b`qgLhnbbL(*9V4I#5UMiq# zHc;#KkGm9LFwAP9fHJubYe&%@i$+mlXAidOmb4N^-ANRl1pU@1;s~BB8kl4h`btM) zUQkng43-KdLVS)QAM|DYQUzR)+iS7}5i@0wsfIBovMaK|nc7@Q$${75c-1(7T`^)s zpxhmyDOAZ#;XI&2*^oNH=DVtg1tp}iLYf~|ScCH+x@6Nz&M(G@mw6~ukM?n*eyyAp zHsfT_K?%6u@4x`y7--(M3vUuNF>R6^&~QwvJ>#ILzQoGFgwRnkAYvOvd>tU$0A&Oe zx_hs17>N{R>_*}dQV(17_JiG^s6t?@1`9TXZVH07vB7gMz-jz*H~1l5x9is%Hh_Tz z0Hv)?C+fsWms?eVLhRah<&IUE4ghYfRD!{ZUAzAc3y)D@PcnI<9$STYr6hs6%+M)A zas9({qc9$+tb)42$DmlR{ayz|$>LM7TvRXg0ji4%LOeM3w3%yJ37XIrf*=Ch*xUc* zVEg5(qXOB*!0HUb-;9o7@e~|GiQ+K| z?R?N2iyb+sfRj=+NM$K31Hbq{CIJN#E+tO%ZHuGYD2r|(4B8k0UXH(2zaFA+B|XGM zB}8EcCB)4o=Jfu*@oH`N<<`#L%WAiM3)>5QrtJUqg~u8Hzs1F+yZ!%je7?rL{&Bt0 zcwCqZ*4oH6)_^Iw;hyl-k3To&;h)M z_iU)K8=Ye$G*mq#@bh)tgJp0$=56ad9MU!GNqm9quh(ZAGo9xT12K@aQm-|>EfnU= zRubY^;K4ejN(|cl)>toTc)V%WGQ!6NId3V{oQ_OwytY_d#>Rh?5!b5=*7cuxu7YRv zTo#RywlH&Pe@M|T&MTehBXGa9{cWrpC$VHUMBT{{_F-g$k|{SxF1yG54kHdz8um{{ zSOrISI2yNO=rh`+@t|*tY920701tQna&!ixvLNm&;fQR=X~r>=bFXag?8gxcC0ZaW zuniq%oaBL`S?&7aW*Is>qQ83}3c(jDXlH8#62lPkYErK{pg()@eF2{|{|CB~#%OPx^d<_;6YQW^)ps7QX&EIEp|X!ZR4YYWL53 zoW_Z@g&^n-lc!h=uZN&qD+<1UwRd>beEnwUXnXBo+rapua@rd|OhI|Ge|U7Twe}iA1_}(NywpM_!ciRfVWGg`c~|Gh$*>SzM6ISg zxc?vi@<#zi+m46k0TTRty2AyzTyRUu!$M&<>_$%w-U^#h(i+ACb|BhB-rXP2L6ezu zEcWlFg6s!RQ)4Xb#K+0gpt5uSKithff=Wl`rqUUX;GcGPw3m`LABT zTmPTs^R<#v3U9x9yFQLPZIBzn(KvZmRJ1i3h9Bdk(u(OSF^9aW$;Z?0fZBVlv(;`0 zd;PFn=8&SRjW6eYXBkIN~>m$a6Gd6Aj4Z3J@s*@clU%o5n1Cp{;>yq^w&E9)- zQ=EX{4O3K3Da9!34`~oM0})G^35;o*GQFeE2H{!tCV#j=~D-IgKr?C_yDlBwBx>C&-8} z+POq0g_uqNdgL$n-@tT+oY_Q;o{VkB@hHS3_Bi489I`Oc>$7HVloa@+61SsD>nwx? z*FkeP8(c9utwJN0gHfMlkQVIfrK;9a%JHUPhGi>oy#tFAOLu!cy)DM<8%YAA1T!cN z$scIMNGo*FAy%BoDSy4C+9c2G{s?GL4(2KHsai@|z-Hm>@^~0Kidi$u?Xq@J0^&WU zES}7DQWK1XKN&fZMh{+mC!8ePH2N^n^N%h){em-ROx~%PBWfSF&J2`x8VXWSAx%M= z=<_I>B6*9cFmf%_I6fs6L@+mpr_(u1ZHw^|ctC8%BEF#7!k1S&BMfMfjME8EK|pB; zPjC*&C=cH929k_-zzNM>~x57r0GUlDwXI9V=HK`8TCncHpb~Iw^b$TO_Adt%zc!XgGuY2}M zor@=i{ty%Fo+d>9c(_m4NR^bnWcf<=;dsJ$L$?@(_qayhL#0?b!83-5VZ7&ly)WyX zC~j$$%X@Q14&Rpx>S8E?eF*h8*-}aWJ*MNcAGI&x`+Mx;-r>){U|(Ytn*@CefE@ewIH#1M%Tz|?PC!tF7v8?hhe_=m7|xwah8&?V%>_Rn-GdaoW5n*hKB zEV%^k)g|F2M-z&ff85-`h(3d!_w*C2qfi?;~qL z;BV#2jNb?LEe$^C@XZTfx!{B7_sS6e>RXU^+GJ_px&llox(fT+cfiCYq`q07BbAB{ zlgMDcSM3b-#0mwjt5;&zP|CV7!|P2W0qUzUU9+86(|6ToHQ3In=Dngb^+v(2UGK^l zavD%K2hh}eIlPtAPzD|-(=X@h7KDxm!i+a`3wBQ;cOG&t>vV--euey-J6&7TEdRcR z>pKnl%aajrA!969*+!Jx(9`5eA5bgymPOJ2c?LNM4 z6b!YnIpLUg_T|Okb-b=*juT`k>FtJ~z!^ZMiLis@vMA@2m7d+P-wj() zokOy2AW7Djk)#%pDjJK0qsswuA^lN{VO#f^-!=;DZf?phFD)%BBiRzO5Mrd)iv>Js z*-#gk+K#>=DCMtQKhc)!*7cJz;*ch8Pr{onlq*kD`Z_Q$_(B&VZ=@$sYM zN9~^ue){`SHw^#2cl@$YtJa@9K^=O(2OIj2mg+s|e;}07{;|UwAZ!_WyL&I^7K(v@ z_Zk$(0j-M7Z3oU6ium$VpXUlF8uL^$ip9)B$O|E#k{c!EinV+UCDO4qxg_#=sTF!P`I>(3TginE13JS~Tt&FSDa;$#)UNoP|FzoF8yJGrL ziKk`A32wTn1Q!N6A6d>ND>|L&$X$RD#@wtMARqu(XDj>nZ2j`yfU(X{bjC*-c?)MF z;iE8b?~2H?ly)NORnOxO@gQo)A?cv-*E}vZK36rnXyketHN!DZ{YdD#NvSU>dpc=a zC`~PKDmKT#(-=o2;YkTc+HsMtr;02X;28!30-}j5!cqasN;C=NB+zNA{IfW596G^b z?Gi|&EAd63orpyB69mU1Rfr6o7LjV#AfO^ zLMvp%JZ)02=v%lYDf10O8Yo^P4&Ea?LvEZv-t8)BBA{>NUz(3{1oR5d)E{~E#fb|+ z(_K40A;lY8XDN!st|-3>G%Z7D5*R}mQ^NPX6 zp!*(-EjSO^_Ks?FP><1xBzoWb!FgNekOz#=BzqCN6NM)uR$yF81}$o*j~NqaZW36I zY7`h7FlO)1Ab2l+BNTmRV`ppapt-+xc!+T!xy9`J!>x^jt)uq@A9V{LYr-i7foc1E z6N-w0J>dG1k~o~xPX8DRVRxtt`H^qlyV95r1C(kAx$CP)Gy%j~Xlr@TzL_+=hyZ}l z2yCGVcLwPySLkLdJWIxd=k?`h^Z3^s{evRNS=~r}mH3=%OV0*G9dkhRPCHSB#V_nF zs)}P#y{WAlww3p%trndUtF6E~MhBH`j6_-C6C@nFCGv}G?gif5(O)@49qW6B@SZhf zcw4B$W{FB4RXly*aP1i6S~>fJgwpax4c5<|;Tf)v5k%}qln6ZatPP#VXWBan{c?7; zc0uennL*Zej_^@^SwGtUY10x&IGqwYc5&W@f{6i$&NR4`>u&|{yOqqlhV{-33kb~T zt+X!nfCyl+iUH>ks9n@*W!=A0s`?x(MwPXXewP3T?eU-py)UK1SDv?>v`3N-sszt% zupBRv9f>hMzkP(5pAYI4c10F5|qqi2w_8`&gn26P0`RT#_%^y zo1>|Hbf9pT67F|CB_LX%3u6jE(uC7kkq1|nu9oc<%ZR12psFlWAjs!P2lcX|ADzr? zK4l1G8r8m3>hG$Rdw}SoOmReQ4=78;pa>P#3;BIXoK5`5t1{Mh!x~$KXe{$~Xd7~| za!b%a?Lt{Nj0P;k$G$WajUZJb3xWd|)ToF~b#7ToPc4g%rmdK~;nL+N&!_c6*GT6# zT%fkX&S`%Ln^9LEzcZcUf1zw^3^GACxTdsi3R*~TdeY#Y z=yHE#Q1)vNW4k~H9VAc+Kvksw!Mv7u3N_3!LdWzY(mPHv-KX&CqVsKQF8AIlsx-o} z^)~NJ&Bs&)&I{#z{&D*-?#7)EB}Nn`lp?b1^f9(NS+E+5+wZG1UeT2EH7MTWRp<;s z+BdnFrGUgB#Aywi__0DWslkfQ?!Dciatd9ZGJJtlNOjo z;LX+CZhsU#Wtk{Wv;byw2wHZd+o(>b@*ZV^_v&mShW3R7uMx;YxQn-^@#s>n97U0D zU8<6ZFUJBTu23I$puy@~ft5q+Fxsv4GbJ1;K_R(`6+!7!>{#aFl=Gtp;HWn z1(JxNn|LXW(O}XS4^IoC@vF`gyn>?qx~-6gU$5hJ_*W!>r$Mk({k9&o2FLv6b?XxN zXQJ)}r`BGqf_Q?p>5HmetJZ3Zb*)F6*q4R{txe9CwMtz}LtJfRTaHWCT1Flyee@j3gFDx!pA2(+0*rGfA4T4dJUMyCh7!s&| zTV43}@nRZtqL2;Nm3ekSeWMd}_z`%8wvHe#IUS7@#NX2~Y`h7kQMWH9(Zm6Y#wmOH z65V^h-Ri^_@zB@=Sw@K%#D6#(E8o&)L`6%K?BRR$a$?OAwJ^l4dCNt^)2J7Zlle%D zw-~m1Jh2YJe%bey8GURYkB6tD`O|*IfvjFktVNJtg~^Ag(=i3lIHF4Rj9+k^4}Lc9 zv~l*)k4|__kpB*|cu2OVL9s_JMkPNI!(NPhc)kZ)jT%N-urKc>R=iSczqNr7JJF?# z1vR?ig=$W{oLDo{+{sDoZ>#kihz9*c;jMxNr6u)hV!cdD$HV@4;+W@IwL*|@LGV|N zsj||byq#2&oBQ##x6I(|;$IyF`?rr>A%el#&;RP=S5P2>BHeE|T5$g;KJ*j3kD32X znhFQ8G$n5))uQHh#^GcV0I}m342p_7HxyeL0lcsTjm7td){56C!Mexo%heZO{kYnD=xYw zG|_BXOXlpd7k%(^9DI{*p&ZOga_}YTU(OHu!(rS$jZ}O5ctQOswUB4I6V(9VQGf9OG5iynsAzbuXi#A0P5=o*-^~Jzw43Itn)W!)RmYz|Rgq ziVvZQ`5!=LX`$F%Jrwt<>INA~o({vo*`?wvQhXvTrmtw|Uwu1Kzc-ra!<#b=9ej~r zg`jqadGouLbo=ea-h4MZzw&BQH3EKk9-sI-u-*Lujz{ww;fQe}fcf!+8suz;t~Y2; zH3s3(zFozjxCxq~pw?2CNUFhJFJk*F)RyxJn%*l3kM7%)_K5F@`8EhkCB|-f7+A;e zbtn24wvV=FBer6uBN#hdgN%mmc2Cv8jx_l+if!KeS|jvI#3UHe5KYRqE?UvRbPlz@ z{T>DJ?8FHHMXf(~Q%-agk4{dt1!LGpnk^l9uGlJ(o8r{ab12=$y#n6(qM37EB)Uu> zI#y@c-r#K$f3ENreM!Y>+h$zZ&~D*ze+&fOs+IIL{#z@in*(FEm~N$NfTlNO_>10L zg(Turzm%a+XDUtxAN7p}q>onTY$EXXJ;s4lud1#0?~3k&5)wkegY%=aK42}_@1yS} zBZ^RSEwo5a*LT)_*fNvPojb;`(T#cO8UHF}34!OWAoB)YTtHu^rCaD3CJivL@c3>{ z>~&x6?^Igi(Te!~vz>eb}Obh#oJ-?-(pI_fR=BL8r?L_?i`UU|%zb+IG z-t6itq{8~v?gnN#Wd-fatz8V@xf*aRVvIbn-D`2k{D8J(3R6Mp-6?+(8DA9OnYw_( zd)`7}bNdjXWW8YvhX)&YZ4G;eDAHSj&V9~bWryKE$MTRBa`MCMhX}680*}VQ>BK@aTRKN<6K$R;zuG12^dU4fEPpl2LoL_2k>2vbPXae!}aI z%4ty9R(1(wL{TWjC(*xx;{D?8Ui0V``tu%wXj3oQfHvh`&J-!&?U7w%Ah|I)GGk$5 zyD2Z9Vh8zq33@>{b*t^D)d^XFSs_!M3c2smbX7K+FZK?OwqN|xJluP8u(7q;2!1X6 z4L(r&Vl)f^O0QqRn4gtS+{N^{0yd~9|49IHM7cqr<6F&xwbzBh-u}@M{yGZ2TMhV7 zP0yeh_c1vGsT2FUQA#5zsC3Z}ef54(Ln+Zrz#@mat+cp+wy zoa}FJz`q}Lkd)Q4xZRF=NaBs=kK2bEM?0%^7~fuVXVX;wsZ*}NMgu)9cjDvwMb*<% zmA^wjsLkCUFo}xYF+q%fDEEsXI-#9f>V?EJk#Hs|nn@`==!v78*zjgJ1oq~_b1}#s zN0}Ddmw<%01+RjNcm_3T0>2*uF`vy}2|L_`+fTG9m6OKCFE4-E-Yut)1HI=LZtvTj zPA)od_A0PoDs(G(oIi!tFuymiw|8IuQs6?ptPdg9X3;kdVl&2DTU z_|sO)VIG^!gRQOIql2~Gqiay_WEP-a0>j26TCk&IH}uAX&7UM82A}?Sv>LYCLyVPZ zJwj2Ctk$J9X%oA3Nc=0GnyJi@r%Z@_#+c+TxfiUTxv=dDCDj{j>R|0)d+U&PdInHZ z-=N$p*p6Y*!rSysf1$9wdw8_AvqSG_v4VsH+sfwlL9kk2H$Qks;ZL@AH+J4^!d|(x zV?asczsOTuuIt;o=D~5?<3^fNo%$$El{fz|(Bk}-*P4)GkXtH|$djv#+Ug@b15Wn()vg*qqo_gxbs|f&L zU2-9WBqa4T_!~p*zhO*E__YPlHb9W4DaSK;aDWQ`{b%Jq;HBxF>>nteN9n^^CebCucJCTPAnZ4)mRRL)+ zRSrqH141tlLJ>~k?Rc14T~_^)+KT*rWUia;qO4`7L}A=hn6&$(aA205)hC6pQr;*s zH5}xm2Vwz{UU^|)@9(1hc|U3WZ}l{WgFA=Sjgs4GV_N*bg~d$#zoo`q{-@9K`8wFT zpy(N#q`ctHKL!wjmlf+Je@(yO2w&C9ZYT9d$J@%j;$N_7q@H7}!HfC1)KgO3_D;tr z`MJSdRr!v*uDGxNYz%+dpY;0IlX8n~Ow0e#SXfTq|18z+;{Sb?&(~kg!=Y~;B)7tg z?VYXFwAfmJ-52C{2{~6N00*EDo_M)ZQ4-w0<3T{W2Xr{Pk8rB^=swr=*8!|oK_X67 tlc%cYpN*Zn&)w(lbN9LX+ anAuthStruct MODVAR AuthTypes[] = { {"plain", AUTHTYPE_PLAINTEXT}, @@ -34,6 +35,7 @@ anAuthStruct MODVAR AuthTypes[] = { {"sslclientcertfp", AUTHTYPE_SSL_CLIENTCERTFP}, {"certfp", AUTHTYPE_SSL_CLIENTCERTFP}, {"spkifp", AUTHTYPE_SPKIFP}, + {"argon2", AUTHTYPE_ARGON2}, {NULL, 0} }; @@ -83,6 +85,9 @@ int Auth_AutoDetectHashType(char *hash) if (!strncmp(hash, "$2a$", 4) || !strncmp(hash, "$2b$", 4) || !strncmp(hash, "$2y$", 4)) return AUTHTYPE_BCRYPT; + if (!strncmp(hash, "$argon2", 7)) + return AUTHTYPE_ARGON2; + /* Now handle UnrealIRCd-style password hashes.. */ if (parsepass(hash, &saltstr, &hashstr) == 0) return AUTHTYPE_PLAINTEXT; /* old method (pre-3.2.1) or could not detect, fallback. */ @@ -272,6 +277,31 @@ int max; return 1; } +static int authcheck_argon2(aClient *cptr, anAuthStruct *as, char *para) +{ + argon2_type hashtype; + + if (!para) + return -1; + + /* Find out the hashtype. Why do we need to do this, why is this + * not in the library or irrelevant by using some generic function? + */ + if (!strncmp(as->data, "$argon2id", 9)) + hashtype = Argon2_id; + else if (!strncmp(as->data, "$argon2i", 8)) + hashtype = Argon2_i; + else if (!strncmp(as->data, "$argon2d", 8)) + hashtype = Argon2_d; + else + return -1; /* unknown argon2 type */ + + if (argon2_verify(as->data, para, strlen(para), hashtype) == ARGON2_OK) + return 2; /* MATCH */ + + return -1; /* NO MATCH or error */ +} + static int authcheck_bcrypt(aClient *cptr, anAuthStruct *as, char *para) { char data[512]; /* NOTE: only 64 required by BF_crypt() */ @@ -500,6 +530,9 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para) return 2; return -1; + case AUTHTYPE_ARGON2: + return authcheck_argon2(cptr, as, para); + case AUTHTYPE_BCRYPT: return authcheck_bcrypt(cptr, as, para); @@ -603,6 +636,44 @@ int Auth_Check(aClient *cptr, anAuthStruct *as, char *para) return -1; } +#define UNREALIRCD_ARGON2_DEFAULT_TIME_COST 3 +#define UNREALIRCD_ARGON2_DEFAULT_MEMORY_COST 8192 +#define UNREALIRCD_ARGON2_DEFAULT_PARALLELISM_COST 2 +#define UNREALIRCD_ARGON2_DEFAULT_HASH_LENGTH 32 +#define UNREALIRCD_ARGON2_DEFAULT_SALT_LENGTH (128/8) + +static char *mkpass_argon2(char *para) +{ + static char buf[512]; + char salt[UNREALIRCD_ARGON2_DEFAULT_SALT_LENGTH]; + int ret, i; + + if (!para) + return NULL; + + /* Initialize salt */ + for (i=0; i < sizeof(salt); i++) + salt[i] = getrandom8(); + + *buf = '\0'; + + ret = argon2id_hash_encoded(UNREALIRCD_ARGON2_DEFAULT_TIME_COST, + UNREALIRCD_ARGON2_DEFAULT_MEMORY_COST, + UNREALIRCD_ARGON2_DEFAULT_PARALLELISM_COST, + para, + strlen(para), + salt, + sizeof(salt), + UNREALIRCD_ARGON2_DEFAULT_HASH_LENGTH, + buf, + sizeof(buf)); + + if (ret != ARGON2_OK) + return NULL; /* internal error */ + + return buf; +} + static char *mkpass_bcrypt(char *para) { static char buf[128]; @@ -801,6 +872,9 @@ char *Auth_Make(short type, char *para) case AUTHTYPE_PLAINTEXT: return (para); + case AUTHTYPE_ARGON2: + return mkpass_argon2(para); + case AUTHTYPE_BCRYPT: return mkpass_bcrypt(para); diff --git a/src/ircd.c b/src/ircd.c index 93c0eb357..2304a7863 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -1137,7 +1137,7 @@ int InitUnrealIRCd(int argc, char *argv[]) type = Auth_FindType(NULL, p); if (type == -1) { - type = AUTHTYPE_BCRYPT; + type = AUTHTYPE_ARGON2; } else { p = *++argv; argc--; @@ -1155,7 +1155,7 @@ int InitUnrealIRCd(int argc, char *argv[]) { /* Hmmm.. is this warning really still true (and always) ?? */ printf("WARNING: Password truncated to 8 characters due to 'crypt' algorithm. " - "You are suggested to use the 'bcrypt' algorithm instead."); + "You are suggested to use the 'argon2' algorithm instead."); p[8] = '\0'; } if (!(result = Auth_Make(type, p))) { diff --git a/src/modules/m_mkpasswd.c b/src/modules/m_mkpasswd.c index 95a463c16..8df10d1ca 100644 --- a/src/modules/m_mkpasswd.c +++ b/src/modules/m_mkpasswd.c @@ -103,7 +103,7 @@ CMD_FUNC(m_mkpasswd) { /* TODO: is this still a valid warning ? */ sendnotice(sptr, "WARNING: Password truncated to 8 characters due to 'crypt' algorithm. " - "You are suggested to use the 'md5' algorithm instead."); + "You are suggested to use the 'argon2' algorithm instead."); parv[2][8] = '\0'; } diff --git a/src/win32/unrealinst.iss b/src/win32/unrealinst.iss index e4b84b99b..5564595cf 100644 --- a/src/win32/unrealinst.iss +++ b/src/win32/unrealinst.iss @@ -73,6 +73,7 @@ Source: "src\modules\cap\*.dll"; DestDir: "{app}\modules\cap"; Flags: ignorevers Source: "c:\dev\tre\win32\release\tre.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "c:\dev\pcre2\bin\pcre*.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "c:\dev\argon2\vs2015\build\*.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "c:\dev\c-ares\msvc\cares\dll-release\cares.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "c:\dev\libressl\bin\openssl.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "c:\dev\libressl\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion