From 258779e23428839ca449f5ba3a9d65da134b4e2b Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 6 Sep 2025 10:39:11 -0400 Subject: [PATCH] v0.2.17 - Add --database-path parameter with metadata storage - Add --database-path/-D command line parameter for database override - Store actual database and config file paths as metadata in config tables - Fix circular dependency by making command line overrides runtime-only - Support multiple relay instances with separate databases and configurations - Clean path normalization removes redundant ./ prefixes - New fields: database_location and config_location for tracking actual usage --- db/c_nostr_relay.db | Bin 167936 -> 167936 bytes relay.pid | 2 +- src/main.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ test_clean_paths.db | Bin 0 -> 167936 bytes test_metadata.db | Bin 0 -> 167936 bytes 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test_clean_paths.db create mode 100644 test_metadata.db diff --git a/db/c_nostr_relay.db b/db/c_nostr_relay.db index a42a536999d798974fed32ffca548cc7ae5b130f..74fe5b921d31e7ff3fa28be82e52eaa7ad0fbf24 100644 GIT binary patch delta 2919 zcmcJPNo*Tc7=Y&=yR{v!Y2vodQoCuhFCNd>Gh-?Q5^bo;fkmps0WjlPQa7p7CQhVY zaC0dVLgD~oK&nL5O65{WpwP5&5_%}*P(dY&O$a0oC7YeJCqxlanU~2wuIdVbA`bTd z&Hvu}_xDbntvPkJX6m&`XOiRDBeVU*w@*)M_5H;F*c<)!adl)gGo0nf!lzUBqrjgF zL_P!iltpgX2Opj{1@Y6Cwx^T&Bl_e32P3{g&}-7XJjwah?jXjqnVhJomj;bUqv zrw(SNkxXT)d~XH>WWE3#@^AtAoTf3hML$u1?RvrZ!{r|e6~CTYXhXd?3q8n3XQ2c6 zy;+FV@zojYH)r8R+|)T&F?4tiUPAr!TqWVvIp{|Hu6alzzdR4^$ZyP7_7vu!AusX_ z%gH>KmScj*C{j}45|YTPiY6+2LJ&1Yl#*$U5z@TODx8!|YAP3tF^Vc{3ZsbCaSyVd z_6aYx%53oQk<9p@dXklmxnt4^g%t%&W?~|jXO*-Xi*rdeEeWi~Bo)@Mt|a(GOwt5S zRuoN%Ye`i}ii#|A)!vSRr?uiuQjTS^spDg5!xkm z^P-U8c}d+D=VB5g#JRY{$CyN%Piu-A6V(Kx3DwSOD2i(GUZ?y8|6T9(Y0ovd?5(e} zb;Cn9fS>;HYv|c#q1}VGsWaT6|XB|7gXde4&5%!W}tBbIwroR~Na#H(( z!Jz(e37YE@48!0Frqf9ssI3j^zmyzqSJ+9#i08M;u+x(p8B;9}Ei15x?0k9!o+9$i6=)~& z^A!ja`TdHS%bzQz<<=5(5dE{I^_-aPM&wj&NdIODBKnyUILYFLlIi}tk{Pa}Y^ISY zo5o++kgu0bW1o~EY=qhBGs2|&A^p}O1ob;*)7ZVTnS0YJG`sl+27CW1JWssot7fQI zR^c%D_OF?tKDK5S>D4u0iT<56h!A<%(98YBl+8u8QWIX|{%t%=>rcfdXIXq8z{l^v z&O@7=M(zQ7AKZZ*hyK-5_75*v#opz+U}tPi{w=yALJPEii}5af>C=5t+6g=nzdvH} z33_Y3zsNgnb|CLaJHjr64uri3tq5%hT?m~ByAdJ?EeK(R-VMkXdr;MlkU)qd^dUqM z7=%3t%?L4sCIk+Fb=d4Kk}7%ddG|%i?m9IMNieC)Cip`4O%E-zQOY?}zRMk3Pv|40!&+3fTE311}v8;wv z_sVLKH3e2>t%5dUKKTZu5W-G`9SGYIf(Z2pbqL!KY7qhmegq$a7r`SVxe;m*TnJ7C a2f|i_EeLi58v<>O$|VTg4_`P%2mS_CIKHd^ delta 2609 zcmbuAOH3Sf7{KS-UAwaj`+%|(N-4`@d6mMvcgCiP!8RtC_)401Q0eUKj8a-?c_mx~ zE;TVE#%LT5BsOj6O~F>7unTgkheqo~?LiX{6&7}Zo{Tjnb^beiv*;#9!(sRP%{Tx5 z_ug+OulXmh`RCuBqh(Iv-%5ASesFcpsOX*zgQq6s8PkV``vwQ{FK*30=>qY3IQj*6 z=G`^EY12Co@!MtL7kuXQ5;Py`o+bCqJ4?`pys-ofa_us7A-}Q=?dA6QQ_Ur3%cw{- zMbjSheg^8yPnV$-4}P@_0`lW!h$BlW;E@MY&`I0IxCZk|3M$Q%^@Xp0Ocnf=rVDY( zY3RT+7t+v*{BathhsDuhEA^3~zJWJMQu)O0rQuaP)V5MEbZ!M+L;d1PA>r*6IDz`( ztDqpiz6veK@2(ckq*meRgu-$>qsfLWCRyE(lB~qblBkFVFL0bHiq=QxlDx_banVp& zL1NT+T-M@Bf;Uu2V~gYN=So|q0(%wq4Cxou@!rcrePjLlctX@vO^}kRE-^_>Qxo!p zAo8-##T8B0bwyWsjg_T@l8npN8BSMKR%ZlVmQ|6{;t8YJ+XX0%6}+j*OML^qmq!zp zGljP-D`Ry6u9 z>iLfT^bn?8*2wn$3e^X$`~f@XV==6c)~z`xZq5Je%mMHF42;ISz77qfNO#vkAo9<3 zxLV&mTiZ!fEmR;v?TwT+I547WBhIxO8}_xYH=v1J+undifA?%xJ58O6L?Y&AS*WcL z8HT|dOdCy|Eh~$dKW8E8=L%gK%|HjSa3cft`9Lzj5czw?wtRdO+R1azCd7!mvI%WO z&TPU-BJWwxmgn|5nqrCP_i|8GIx;k>qi3^W3mVDE=eFQkBB!^Yg~%_rppM8Nw(MN~ z*s?9hvd~KOFJ|*OF_l*2R9Ut8Z3d#|OcrSJ@@Cd{|9#dD*PFA`5OcQiH}>Q^IosIh zIjFP3j0LSQsZh0fe*+@sZq7FLIA`a6Y#VAz#NqMb5&cqrgwJfl%fy?xZHIbi8_tpE z(2gDI(>r#N&hG$6^dIg(l*k23uXWG%x_wlPnhI278~1*z2i!vY0zAD7RXqosMq{77 zPj=x*&wtt_|FTL7_7)z2hjG`0f~Gg>BL8OJ1$ktFCTO<@NWEJSjw7@pG$F(g zni1L&+7Rjyq6iHLbqFUBI_QZ#_a{&#A_xeb2weyaLL)*g0*i1Afk)uHZjXLI^>G079t+=kvo^f+|0P4}nJTA{;_^3c-WmMsPW^a2vu;>TXWD!hZp6 Cr7}qX diff --git a/relay.pid b/relay.pid index 13e1251..eae82bf 100644 --- a/relay.pid +++ b/relay.pid @@ -1 +1 @@ -949770 +954022 diff --git a/src/main.c b/src/main.c index a287d02..aa5fdad 100644 --- a/src/main.c +++ b/src/main.c @@ -3132,6 +3132,66 @@ int main(int argc, char* argv[]) { return 1; } + // Store metadata about actual paths used (for reference, not for configuration lookup) + if (database_path_override) { + // Convert to absolute path and normalize + char actual_db_path[1024]; + if (database_path_override[0] == '/') { + // Already absolute + strncpy(actual_db_path, database_path_override, sizeof(actual_db_path) - 1); + } else { + // Make absolute by prepending current working directory + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd))) { + // Handle the case where path starts with ./ + const char* clean_path = database_path_override; + if (strncmp(database_path_override, "./", 2) == 0) { + clean_path = database_path_override + 2; + } + snprintf(actual_db_path, sizeof(actual_db_path), "%s/%s", cwd, clean_path); + } else { + strncpy(actual_db_path, database_path_override, sizeof(actual_db_path) - 1); + } + } + actual_db_path[sizeof(actual_db_path) - 1] = '\0'; + + if (set_database_config("database_location", actual_db_path, "system") == 0) { + log_info("Stored database location metadata"); + } else { + log_warning("Failed to store database location metadata"); + } + } + + // Store metadata about configuration file path used + if (strlen(g_config_manager.config_file_path) > 0) { + // Convert to absolute path and normalize + char actual_config_path[1024]; + if (g_config_manager.config_file_path[0] == '/') { + // Already absolute + strncpy(actual_config_path, g_config_manager.config_file_path, sizeof(actual_config_path) - 1); + } else { + // Make absolute by prepending current working directory + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd))) { + // Handle the case where path starts with ./ + const char* clean_path = g_config_manager.config_file_path; + if (strncmp(g_config_manager.config_file_path, "./", 2) == 0) { + clean_path = g_config_manager.config_file_path + 2; + } + snprintf(actual_config_path, sizeof(actual_config_path), "%s/%s", cwd, clean_path); + } else { + strncpy(actual_config_path, g_config_manager.config_file_path, sizeof(actual_config_path) - 1); + } + } + actual_config_path[sizeof(actual_config_path) - 1] = '\0'; + + if (set_database_config("config_location", actual_config_path, "system") == 0) { + log_info("Stored configuration location metadata"); + } else { + log_warning("Failed to store configuration location metadata"); + } + } + // Apply command line overrides AFTER configuration system is initialized if (port != DEFAULT_PORT) { log_info("Applying port override from command line"); diff --git a/test_clean_paths.db b/test_clean_paths.db new file mode 100644 index 0000000000000000000000000000000000000000..d62063dc45c5642b34cabbad43adf65e44497010 GIT binary patch literal 167936 zcmeI5TWlQJnV7rP6ua4EcTuC^^l&J7j!etlJ-mxUT`Uvh7FnWthHT2srY`Y%%f+rk zvaDuztE!q3vspOQ$g^J9$!3FW9)z+8SZI6=OhI3$gWHB-tIdv-X zB|;*RNDThZ!~g2%9S97l3-}#{|5=`seqxc?yYHWd95Lc#=}9J}fo3%z1TZ=V^=Oie}ad*)7!N!c%Zu5KRCX(*ZhXm&K7SzL^MCnjWuZJ~#>?zwG-h^SP%?Cvromn86GTclX3=xchJ z+%6Y43g!Fc1N}ZJY*#jmC6KY9mnzddXPXizR?+WONNE%P-(FvzX0qhZ%naEI=_AEe zvg`t?*)`c$=7(`;e^6%q(9#v{M}6gq2Sn?o(!tU#V( zX-h9x2sF76!ISRZ(o3YI-<{=g!a0{oHl#M2yrHiZOFZ|gzOF;(zggbgP|c~Nly%Z< z?L44IWSPs87eaq&l{|n^Nha~2pKyX=#;^coq32!@Qf=#cQZKDO(bDmWAabMPeji$%%kHp8a*~F8(tnLo2f-SQB+b+WO zZ%YUfu&rt7$J3$yInCX7I;0a)MWx$}gWd%FAOOhRHXAf=aSnVgJ1nG!Q+6&%_$?D}rQ4T8g}`-@pPNRTrm>xO);3(b$B6%Nf> zt7G~R39Y8ZCY#X6=}(l;8hDfWrQyL$akB49B(M(_Ai>3mH5AWW8;>5x_=?509?MoU z#Nc7Dfr7(yld{6a(yD$B#)DotgOM#K%8ORZ|4JgB(Lu|_K3amd5W0q*p)1JWLt`kB zHEg~Wk7o*?{CuZ!RyQNaEmSA^sqV-fQp{4quFCx>ZwwA*u8c>2wNq>0nnGc`pTZzx zNLLVEmg!EwA(LuZu+`)LR=hBSmCIlhenSecGTX{VOJGfwxD&$5Ihv&;NeY%nu7 z9zEz3C;UYq8R#ca&S?JpDZMQJ&2L2Gnep-Hx5fHdND=>@lCs2VS;Pg4*sdNLS~Kt< zTRt^lu_HzlwkXZ*)5ip2?E0Qqgh-?ME^L_`5Oce=Q?sjtjSFfeMqsP34-335k)bwF zD;u>0Q;R8(sIyhP7{}PMkuAqyHaTdL+;-i599#=Cd1LgGCadiW<(YHyGnbc^7MDUR z&QGv(cIaNKW;$$f7+%W2WiT4Ug) z@Xwji6x&jdvVZUg2_OL^fCP{L5mE%h%prT-yJ=wTazRrzejW1}y4U9lPn-jry&l9mlqaYuEQ` zbjCAxYLt{3uICVk*32W~R`=|ns2_OL^fCP{L5EN2i{IuELHS1y-aSGiyMXV zee!{RpA@z$o5d2y*w9OrX`Zu92^6d7_bQ~c3IA`euTL{s@@Hm-Y=!iZ;wss78V96W zv%y#{O9TzO*v9RamWFrKr0pWe$}N561Ck4+7fU3UmG9BW zPLpi4)^MrCLiBOdc0|y!UHF@tI<3NsJ+t||sPe8|^QdEd-Gx_hvg(FwscOrAgPHvG zoeph+g-}cJ+Rnx<5h7fY+if^R8bL%8<%5d21}o&Z#HxO?u)SU(^I?UcqtrUsp$-AD zLIUBXyaw^$4}nOyfdpm$J*B>6)m}uY$id4R zbk_gwKCQQzKzM0cagKaW@}3LB78ES?rc>pNZQ?^0%pn>F%@#D%7la08-;6>F7s>pS zDJ?$n-gx5a5OmbNJ?iYk8&zx6fYzy*Rm$GNY6yVhU)5F0#WmIs`sU_P3pXo}r&!w3 z%M}7|Y!xDS(%oBniInuavph~X=Q7EL)Mk@6^tED%=U&y| zS#LEB+Ju+WQpc>F1gl?WVbUjNjgFbdi6fSjq)&2I5(%>A*ng zN`V`Ndz~3-@Xlh_ONRU{xmMoXzD;i2mo;Fc>GAs`@v&?+@#HS6yF;sBi){b4i*Wth z5<&!QYg+p8bf|w$bN8JN>4a2K={Dn_H$guL05Z4D2F;t?EU!XG1mgn`Fsf~>B-e`@ z#R^%NpPxUzl#FL4C!7mNN6=J`GROQa{3eHvj*N|erb3xQ=II(5((^s1xRo)VhzPJ*T$pAF}`B4t;e#} z3^8~ZY@pyU-K4B=v9zk+gYlqO&R}HAiSnY=^1qUZXLQhVv5%IZErhP2XXpy@_s|$h zWDT2d#p9U*C_mq+oYl<;atqaoeyTfihZM7vu&Z)^${T}&nJeSbU+vTyxTa7T@24=x z7}6C)=IQA;Q*a#b)X-U_!G0Qoj3Eu7NRDq~U@$W^9;KaH0?#{MlFTmiTd~2+ z+<5e$Q=IS@fn=bcKslrN^QZK({5QW5jc3Nkqu&IU3j46Y>k=7i z1GTbIOE9&V0*N|X#fx!_z3rVX$6z)&Xp-D^-F_Tg3p06R^phs5?F;3ZbMrHomzEZn zLMzTsuyl6lUaMw0Y;hP~%CPmbS|PABxjJX7D}Mng$MyClx~h1msVZ~MqmO}xm=Z{% zUON(YyY}9Rf@Jdun2@<{dM$@`w+Vm8K3}e@rtk;l>{q@DRpG5H#EAFtyJB^3I*xh7 zR~4ZZMQ20!vU)Ex@?1DyEQ?P7u*uUtq?VZJlKH7qgPHfn`wjoxd131*e#c-NoM2nw zRB}0zj+P=Lm*f8;Zk+yyr$-0A8T(1hJoUp<+tELcmeT)v|8wa-c0m3+dj4#J5Iy2s;29?2J54|5kip@y+^xH4qnV3 zNJ9xZUo_j!@ZtI!6Y^N8H$t0%>J)~pw0b4H*=0qqTm~!74C$4aI?7hB((~lO<9zCtK52yvrPsn)44$^2cX0@yrKc&63|VJ#?xSQIDiIp3fX{ ze$dyR;CMkWO1uG!L$E4X9QIJnC!QYhW6xz0Kk(^nF3E@g;^OniLu25(V9L~qfNZOW zA+JA|A+U|^V@8`uaO4la^m;rqGZX!2k#9nTm40`Zd&=PYtW+Ob=7h$HV8Ns2ozSkN z*QuRQchYfP=QIo}BX1uDp+~Sq_08h5UPsOPPsXtN*b1Kja(VtlXTQK1Ah*M}Ds(jU z+#4*hL%X?I){AQ;e%2|^3Zbb;S-%OJ&eDp$C8lFH2eHZg+S$R(r*b&_&DUOwXO@BuHpas7hZsJ1i%MDil<*``Z28?&7B3kRC5D8c_Sx&OT_}bg&982)K)*D%5tNc)O^4Wa;h!IIq{$uY`P73+3Hv24L7$q z`+kAr1>ybMrQ(;jbw0g;cf+fr{`aSQ$08Cr{qQ;OSPYUuzJmO40RKIOm}BSCN>louJLMds{;4> zD)I&$+?C^^0VmwGR7=|a4(cBwpV%V7aV?*D*n;uNt@H5-eKGNLQr>tF<62v<_lMvx zXju_8DazY6Cza-XLEO37zP-xsxo+MJ+PC*Yj+fz%z;EgFat7A@HrH2Y+dKvChKBC) zNOe8Tm;JNi&lK{GjxP)jtl(afbWwI=i_OSlIDl^6b`J-i|9?4-A<#-BfCP{L5+vvFGo9} zl}G>yAOR$R1dsp{Kmter2_OL^fCOHI0Pg=^gdUbf0!RP}AOR$R1dsp{Kmter2_OL^ z@Ny8q{r}6+PG}_(Kmter2_OL^fCP{L5^X;Qs$b=wVqT zfCP{L5M#jb?iNwG_wNc-- z_l#PjYI=5~KDXaEpmQF5P&XZWuI3qgwnxpm>Wo8c=Fyx*4`)P)xvIgV3@Lyf(z-YM zb+=J(xzuqz$FA?~|K8dJ`~Pbb!*dUnLd*2b9n+=HtJ0&cXH;v{tQ$?!+jnQJoo)>a zZw+TBlm=nfAy@$wI-H-qG`n!QyT~t%59b^0Mcl@&_sDeUzUMXFFU-wB-Dhj2S@&A? zJ=>YBQ*SP~R7_?eSGV-9zd3U8IMpt`+1hzPkFH*xzqDArytq?cxN>#gGOt;SOXk(f z)Y`pjU0%9!b=SITUfbE7zp`_=ddXTeuU*@viwg_$7On1D^VZdFT@NxN*)Cm_G6wL3 zK4wD~zO>YBOzmY%_fKQ{&>dB<71KGnS1U+FBXeK!wYSOv9^b*%j#TRxYlF1m`e;# zwJCu@by{T}*;~t{`0$*sg+6ZD4j*6*HZ)ef-tBv3aQM2fBvfY4F{_lZup8E5uPR+S z-CLQ!*jw4+KnO!f*@+%F6C2L@7Fu-I1iv;^!*=_?@~PqMqH;Tbj3KYK#DvxIy(|OA5}*~ue}jl5EpG{KWDVq zB#)LG*wKmD^=O|X9F4?uo)$j&5N9FckS5J^bRWc|Qn9yrG~bYqC@KBUQid6__VbdY z65M_yGQ=8&M=U8kAKPzlLrfKhHcV2JS;b$ZOs z5KfK8vO{gh0;$+vLWtd#XaMJIQP`d!kNKnh#QEqz^IsU!*f zz|re84;-4c78SwJ8K#Jkp6(qrRSu|}5nMX-Vas-?3kM{wXF8rJ)oMa-pq62J$(!ZP z4I-o@@7~hOy1d{rNU=n6S@+2G=s|XxWZB_NHlN%quj*xT<9;~nG_x1T-I*GXx^~^7 zk8O*$HM=vw>=8O9W$lZlRsA06$U-(tQe-Yvul&@VE#=2jhAV0}*tUQ9b0IBHrD&%&#xKSwICm-ndrx||#XJ&@nY}IOnXZ0G= zLc)p%a`sJE$|-GDNNIb0yI zt2&ZZ{bpf%y+U%(b9X)afabCnUFIqE#-nUL@B6O}{syO^q*7vBzVK-`R z4bV|CxC9xu9eQXtpx=lF%dz2wz`ZL{r;pgM>*l#cxC%9?-$}d15s+Adf?OCcD9ti< zq`&wr>W}=w94L5qzd;UQIDk4)Ssm#7e1e$cv*;X~BZNIdEX+J6+|ddjqk#V`S%6@G`kC2s$)CMUU8 z-F^tY*S28tU}K_$E?k6nOx2Hi3hkCEos0Dy82-Uq*=nr5C)zT!@Hn9*g|W9zv$#ium&!X&Gpq;!TG{6 zDd~5`Me>HeRxI&c#nP5uuCR)1%5lT+=Mw3-&`GC>KgdtBv09AI(`p)k@m7W9ASqnp zPGNl;#-kil%%%9|Ob5n*WBQ|WR;X0NgCL#FUr*|#)#KIa_{8<`#FO_VIgzU1vHk;% ze9-KPuTS2S7zT_aULlxl=@k-kfn_$jbgvkR*n+SDPJoAysD?Hb&lIjij~6@l7C{Fy zSY;&rP%QXBPP#?ct|OF<6%KrXHI?e}ZWhSLq(lB+-dHyDQ96qm3_g};I@*eE6<_`;r# zI&wEy^}Dvn(0egYW=N1R&*le9IvfmOK;3f1Ub4+5p-XNo#jb=8=*uK4g=Le4(kf{y z1nV$1w6MXMdz#o2cje(b*S3OE8=EtQAB8mXp}tycxUhMEzQYd-M9{L?*unk|gY7Gl zdH(nR$?rt8|E&E>?OWQ{v}t9RfQa?}qQR<(jj#IysT26gtJu4YQXaMcuGNKJU^0%yzN_|{(e2sI~>*vh59^;pu}BBvTkrz>XkcJ@%Vwt z^7$cV8uJW!AHCy=1C{Tyi3E%qN|fB(%7+Y8o{Mqj986Z|zBxN670(r@Z0`&*)J#+; zTlj`NJW8PQUOe4HBqTz`+0z3m+vf*VEkYtg4-BY$B*r|AscyT44{fV*%%5U87FiB8 zY_XfPJst~CB|aNvC0OIO-SX#80;oJ}{~sCs1qW;_h6IoR5Ap|-CX+8u2}Th*>>m$bY_w2YR9g7||3kN^@u0!RP}AOR$R1dsp{KmthMWg(D= zjYZk(SkI}zgbKW+0^=(1rV33+ok#!)AOR$R1dsp{Kmter2_OL^ z@WKQVv4JRiIVbG@MF95yA^`h;5rF-_2*Cbd1YrL!0ThU*#C|lK+~J)FQpgKZ>Q6#pQZlnh1sJ3B!C2v01`j~NB{{S0VIF~kN^^R9s=w$ z^YF@h_Sx}Tqsl)!eU5!J-hV~Bik)EJf^YjU#arxS_98}ogkpR&c2P!&uSmQZlxm9a zK4j9d3n~kIs^N{`l6{$BjOi9KL*HL`J&+o;|;4`$EDQEjG!c z<=gT{Ct}y5eLjJpk(kcY`hD>r&2)5s;vkiZz0ITf2MtD)6nHs)&+iuuGh|Fk@WFzl z63l7_AEz~Hw7%!<53z=k-z{Jt+hgA&NH92|uK?c)J49uxjpz^Tz#cBt)R0C@lZdAb?qK>|ns2_OL^fCP{L5a^;{q2$eGqRNY+0e&BHy{Cj zkN^@u0!RP}Ac0qcz>^Q=<6~E@B%WS7wCN*7$MqVVPy@ zNKs5WH`Z{d={D+qQI*m3k~hnn8${Z$Z@XT@IRdMa?{5}MGMczmvI!SqQ^_*K&VtR! z&GM>VCO7W$bgs-YOpmPUTPw-+;zqGTmgbKa=i+18Y~o3t(`?l}`+yp*XL_y^zG$Nt zPUxWKvkC#}V%BQH6TXxg6Ru`78X2`QJ+Ipw%=T+KVVc;*_Y*7~Uq>MuoH ze3s_+TKkH{dlOi7jch!#FdjXQcIuR4k0A58etKlCpmI4Gqb7@d<@1A?sqv`WDW8pf zLil7q;d~hP+f0oFEH+=bIGEXy_d3;G}y@YOgETq(-g^{rf7@)Xp8Qj6qo`nkhbUoMGz!t0yN044*IK$1SlG8 z&?%^9AP-6jj6kGlr3WXx@e-8eazjq)oATQwWF#ON*9QTWaX71cP2{|Ilk6FH)@)PBMDL+np5dTr! zh)0IfLw^*z87&Te<76uQY53#tweYp$#Qk+lTRT0N{`O)xWHhSuk@cVsI5oX(H~F<@ zwRfzFX|!yk+0gc>Z5kCzo9`7na_iJ!dU7&+&(?S9)DdLS2W{G@bY7-bN@~8Wl5+mq zx=K3oW*hoGor03Nk7h=q>4k;x_aj24-xhj68@3fNL_{Tnvb)QWY@EQ)sFFgltgfjg za;sF>$d~Ss_tkqOzg^xe6hX#@S}afToB<_JtgPNGlj0`)zrDUb#bi0Z>1nd%(?<%c zWY=u&lS?TH(b=;TF-WRg+p4m%wYO*@rC}6hT&Qs4MT2tS`M# zB-u>Gq`FP3nJJQ~)SH$F(MK)A6v3)tRho?kt*}hFoT&1yQMak7eaC7xxE6mcWo`N2 zVCK!O%_1>r3oL|M>daF}bC(Da7Rf^2B#se8G*Qm0h^4VYZcD7H*Yn%!Wisbi2s(=G z{T*sDu|fjjrR*lL_Y8~p8%R(Vb=F`=kZmm6i%1n&%QkmyW1nU-7c54n(R}FEpF(G- z`ilF_>8$^qJ=zGEKzM1V;vD&`!+X{bTTrOBO@T}r8W8WhU=GpTZ?&PBzAiK{`=%vY zxQOQ-Pb$&z_r_vRhoGa@YSi4*8`V11pmpkcg|d#R34r2H*;Pt~HP#RM=H^iI*UONn zP~1{WWdcnuMDV0LH`F32s&{61oN&%%lJTj{#ILDqg(A+A_2E|p!wv~1{M;Go|iy&WDrXyNkQ zT#getI!s1KCnjP~mJba2P{_BSOIyC6<1@Dl>K)N~8qY!UTk$Pu*p;$S?-?gXl$Fix zVmbRxj_4MtG}{eZMCWg>W$Uz2v-h$v3fV9gmNw)5iqJ#jvr6?`sWmP-zlF?NEMY17ze!x`hf?KxoyU4-uPx|6*?jq?}30(ZEGdI zUf3v<$^6{h+|k8&G(9m9emp5=&I&lRt{IKprsV|_vipl!*h_F`NY)McT<4n~MJpWW z^>)YfBNE!JDw}M4Bd0r2K5O8O=N1!#>B2YPnyDMbj#1xzI<8*A_z8&@*&-`Fm*e zC9;OiwWHB=9+aQ$RL<(AdAWt^SU=SrxqXURir-baKjpN+!SvEt_*Xl%dafxHM*AuB zGWv9RkvV!Y$`l+$J2iAxX|SILFQZR`FOuWi7=V@OSeSNd@jT;XKlv<+PcpmAZAAvt zvt!}?PI1Ct1d@S%0-YJnoj)Bf%YFFWa5OzO7XDbQpM@0h=LtuaSS^bCM~SbVJ2^ke$t$3yFz*9?A-L_#l?k1 z--`1&md+-vwd=ac7Ki?&3|xAnF?D@nH##@HfeX8*m}(p%XQfl?x39c_6JZ+-pWD@&kJ)kU)}4bsUPxH zg>OaC*$}R*-V2Q!7tR;UCavp-uw|%F zz5;)o8cDJ(^$7a|e@FlcAOR$R1dsp{Kmter2_OL^fCP}ht4biwDu(<2SG9SuUPu55 zAOR$R1dsp{Kmter2_OL^fCM-J-2bB^AOR$R1dsp{Kmter2_OL^fCP{L5_t6q;Qs&B zZ)2<>5~fCP{L5FklY+ANSOj_3uiB;L7`#O1O*n8yW)@G5|dd(twqe?2x#;#Fon>rIi_VtEd zqx-aBGd&~WfpKNvfSMMhEwC7N|39MqSxEUa<-aMPy+8%AC=x&dNB{{S0VIF~kN^@u z0!RP}AOR%sb0(0AoDX|v4G|?W5%!%eoQOxphnzzIcK<&#@^dy1)gb{SfCP{L59VcAXd@C@Gne+3#AtAGTM01`j~NB{{S0VIF~kN^@u0!ZK)1n~X;&j5tU zNB{{S0VIF~kN^@u0!RP}AOR$R1YQ9GN#*mVx?xjIZ`)0Nty%3I z_nnT~KDAAwVrlceVn?7QN|Te}d;DdOjv$LZXwyc8c3h@bN@~8Wl5+mqx=K0{vkiTp zPC?1sM>8YQ^uj{;`w=12ZwozucS2eLLqt?ED7(81$;Ju%;O&%!Vp&~NOXOCmu#qp_ zBk!yCNPfG#Stx>x4YgRF;yD9KpjcVGTPDR#_`i}+$WW~ z0mgD!BB&Xy{!)Z6khQ{#k-{yaSF0wqEG~i9QnL?RG$?|s+)!8ECs|*5p-8eB=RF#k zDUzwwn-;CI5Pj4#OcAUa7W|u<2Ccx0Ju|tSsPe8+x2dUp$AVXIvg-P4DQnCB1~d8V zJ5AaG3!#?cwVlmfB1BjuyW2F0V+0XRl=CWLX{?aj607R<{Pud8%=s09j$(U%hnfV$ z3JHXlvYW()e+WeU4J0VL?Zda?~TQt4naq))u_1#Z&a;Q4O*wJS15Z6t0n-7KV?@b71mfk=$o5E&0jA=o>8$JLk|N7{RZjn@ZdoUm*?hk zoXF8(GCDdj5qq+HV9`e8x8N1O?S?I)^S9Tsb=s)eds!HTY#0l2Jd1u%)0_xRq>KC;g<{rwGZ4>8brS|k z%MrMdzuTFi4(}|s?6}Y0;%lYN?OWv9J*Nh2G(EaG939PMVvp~zx|_5Dwm9t{xbW9M zkl-U=RHqz2p7Qn2Dek^gKAn&%DjhHmdK2^m4bxLYj-2j9`K*CAo?A=|rVA5&S0bK$umJHchO0x-^p&yjQG~BpjOrt& z)ig19Xl$V1Fs-;#;X-j$y$j<(ubkeba&+811Lf z%jnbPMds+qC{u70?bOg&rNMq0yo^2#zDSO5V_+~nITog!T0GA<*-t*p;*-oSb6b(Y z^z2x8zf+v>7lCA;pFn3ubLUUT%W@xnHyllmjfFoJ>t`WF{CUEWC05HK&RfKG^-$lM zfd|?0iNATBmt>35>>hnYVEF?tXBUeQ$EdywTP6p@+-mRCjS6Aof?SCa*edM70UN=qs zkgqCyD~isBaAoygXymwXzE~EY0AQ1+aX_nLrisp;WjS8onI;=TYtCKR7uu@L}XHBl?N|d}2HNr{QAiUk!gR{=@M3@cA!&Vxx<6I$HTc+qHZT4@dlWenO}{rCKFS2gHf_gj>eY&F*_OuoC~pK`?{wljRV{_c1*y$nX2?{5U`_&RNP>)AFysh%eI_m7%U&Hc@{V7dhZ()|tK z+B;1cd$tL@NKYe#FwlOK7>lOY7X6J7Fi@Vtu$5M?gg3ja=#@)j#hD?!60G=ZSR8^?-r}%_YCiGwh#&nzCh-HG&gOFX@V~hD+|ke|_%4_-c`P8K z+QX37zmOrYjqYPcKqNTwlW)ErO;1mUKU(0M5Mia;-JLz9cYWGX?_1{h#tCo1Bj+98 zuB6wgoltk&ab4#$3@amh4+f!!utjyv;W`IrXnTvI&3zBtnnBq<1#|o<*0mhwT#ij53Uqm==#g5&b0`43r zu6r-~1LxEHv`%^loJvAdS1ob!6|hO@igz7@!6}&2buw{wpc^Oz13lZ+uv;Fymd;sZ zXC8hCXx%ym2LfN}t*WQ*d?h-1tS*#TUTHy<3^+Ox(oAr+Mw_xua9qq>kFy9d; zY(U$vSEj9IWiKNTLk7_({zF&4Y*?>}=JRJ;$#1Cypu@?&d-r3@n_bE*WuCyfIad-C z$4dxd>_pcSC7YWRIz_oDQlfv{k=`LhvNK(u19JWQx_f%(IVIEGnURV0#rbQzTG%SX zy}q(@gAVS>anXPi?pn$vZGQ)K50Q^;5%0K`&pd3w`1r=z=(xHNdphCVco5@Spx3)Y zuphKj5jiP3w{4Cq&HIA5bF+PGmECjQyzaGc?}Z#M!ySR&(&^<4tov=Qug(NK1@4CW z?(#V5dYJF@&$2sHICpehVQ^pt_mUhJWjD6ij4Xx&=;ncYIQabk%W({WRw4l;fCP{L z5h0!RP}AOR$R1dsp{Kmter2_OL^@FE0o|NkQNuq+Zl0!RP}AOR$R1dsp{Kmter z2_S)&g8=UTUygP{E0F*aKmter2_OL^fCP{L58I`~R1tozO}ofCP{L5ONNq%I^sOaANR_mj7iW5fS-_+JixcX(?! zllYH`-$?AlKa2l*d~)dXq2Gdn_(K9n00|%gB!C2vz$-%Fm(L7eJxYg0$3n5#z<^${ z+j?EAG#k4{P1`l-t1m;pU&F!enU5n*}ARO44dk+m1&dK^~2ej*(yDl7KLUj z8jqAR=mBlmGvBeAjkZNi%QlThZSVKg&)EMvpQyj1@+q0vbB9`>#W#J zb*Ed${9B34xYQvmI{-V3X5(OP=Hkr!Tn{>~%Th`ZSXQBQx zbzN`R?MBToXByO=^)4ls8OYTw{X1_CUpPtzEo!xQ?$g7?-AmOfUA#DVsXAAkyEH$4 zX{UO5e&N#G?vj3`a%tz?%Zm%u>fF+$>LR^-Wp{q*;{49Vxr>WCiwnBGd!X()lFM()!ap}^fOFNe?>I;`E z?_RmIK<6s+bMre_mfi&`x+^yMM&kTvN4=V+{Vx2vGhZ4_oX-R^H}rkFLW)iB5mI7) z)m`eBUQf(E2$rf+t6~~08yfV6QQMntQFFIx?(2;TB~lu1L-NqD_sG__*1>g&Wj9T| zM!Pk_kHKJ#96oJw3-jK{brSd?;4fvymO}#^NO^b=QSEy)!5yI z%ys*)2hORH#Dt5Jm7ooMr%tQ3+3sQYyGr7!n|oh>q}fdyI`uT0ID7JcO^$WDdfn>LLD>EOGs#av$xo7hqWq=usq%-)C(1um z9xHX_u98<~lw|6ssXtHse(DFQ-$^}9JxtNmX6l=%`P8{oD*2P-U%VpIJyrt=AOR$R z1dsp{Kmter2_OL^@Yj;Sc;srh&xz!jHzSKOEwFnWKNZP@1Lu5iy%xziG4dF1Y$S5Q zi4sR|Z+fL#;(RQfikz2O;1uf(?~bkm8 zjuZI7(d!fs9O(5n6+xd1i3otn&fo3BmdpW_^Ie+sLEA8?1qURSt(&$e)owvgpjAz` z)Ecx(xD0Mpy{T8Z zvw%C4)ir2(Sx2&}Ue9l@mq`|S?yha@(`@E~#XP0ae3;4QT>mw|-^9VC4#(pH_{t4+ z<$aO`@9s$DPRFB}B%|R5+YPuOW9%BV+DkSy&88_td!%FtYO3<|D%=7x>J~9}i6c3l zgZ{j-JsS>jx3wPB;oM)-+jf&*OCR?9N1J!N(~Elhu{9A*FD->XJn8pQU)}1>no}wm zNqYHeM;76);1-g<&sRx)yS!N_f|L!lSPl#d&>;m5*<2!3x1l$;Soa4tZ7TeOH?&W! z4`#45PtdGp+l1RDyyHk8$auw}-I$Mh5wk5F?xZzpv%mmcMK>IW_iO>jleLoypXFWg z+|xU6N7K1n_C1Np5Ca@ zDu>;y2O6NGq<0B2ZkhDJXhOdc4VGoY3xRuAq(L9DVb{uWiE!m>Qn!d`Zl@rAS2L23AB7FY(W=Soq71`iUs7Ktp*LFhp}k-dhbhM5 zggX~~edS7-qN_pY6N^OxT^MFsxaMm{(Q441V#(-Alm7LraawdiZ_WAK0^+$)=)^xA zpC5}oorT7#K^s9`<-{zEw}ijQ?p7+Sv4u)^HeQ+h^)e)G-&$o0ad*+llVA;8B%AB2 zGlKK^Wl~h{h>Q3&b*)h3xeCQCwNz#m*>uJY&7Dge$AwNhMchGtijCD`be@va0F1XX z>0 z=ib8WU>d88L*Ew*K9F_XqHEXT%fB) z&P7L;mt!BD_3Z$I`)`ot?D@Ll9UJ}o!md0WTSR}lW>lTkAOANPn$Z%MutFB7DG)>A3GrV*`KWN1b_9dSSS-39}NuzZnHX%Q?S!>rhaoQ7RrU1 zZZ3K2^|_y*kODt=b0~Bnbd+=@in|*x`p|?F|BLA%sFh#*m-C#2l>e1CVxjY)QO|nk z(FmEI8D;4iH@)j=2$^x~^;l>&^uW#NJBWM!2Oy--v!_{`dTe3q#GZL@lV6L4&W6&U zQ{Kzwk2%QXiBqxAd`OYWfxFvtGSj({SZIO+=y;exW|&lB&_fuZJ~zMF0|GMhOez*q zL#Ld~{{5o=ZurGTnLm?cCbAlI-yG*pDaedxhhw30t`+j%uX}nEe!Wnr&$9?p-1#`` z2B#gp&dyaleju}aZHSpB>&?gqpE!{D-j2mWlddRdbL%{0AoE;^GUs5jeD}@SL8*AI zKxTVqkfCN)`Lg+M$it%qGVg_xJw!qxRGd9MAhUgKK-R)1()YlC%ts>3)0pbOEqrKO znPct*%dx<6_(!ZBj|IpQZ--e4*0_ON{`^S*nTPHFLnF^IU}IJ!fCP{L5f4s`~R24NzqOufCP{L5HvwpBGxg2XeCk{(mHbKaFJ72E3P1u#00|%gB!C2v01`j~NB{{S zfxZOT7vte81Z}-8KWxa}=B}|%cAt4OvMAF6uZbUL-+~W(nBpz=F?$gsKSD7!61m_+ ziLXe!>6L1U?>?kck@GSOe5&CM?~;9)VU&HaUdZ%)f8ljcit_=5)5DRoVfoF3*Vy;$ z`9#e;~@L<%{)yZeXyZgs|%*Q|T+=@EKr~ z10N5F@EHHc0#1xXGDCrn0pR`rzTFHHkN^@u0!RP}AOR$R1dsp{KmthMRU;tpivNFl z{~y2q_o_KG)&~h70VIF~kN^@u0!RP}AOR$R1du?G0K5N>`~M&lyg~v<00|%gB!C2v z01`j~NB{{S0VMFM5lBLXhNJ&8r2Jc@rVOV3UMijZJH!8HcrpHyq0fh|K?44e01`j~ zNB{{SfmedSHnKsA>1<;S`UuDl@(ZLq!~9Yu2mUfnIM@H>N=!cEkwFs@jet zib?0jY9`gKX2UHiGwOEydTDcmI5zAVmfbWD!K(Pp%|g+MCRT-P!iC>dvJ9~^U~_!4 zw5pcKwR=3BE30a{O;**dmH2vLqfjP`b4Lra(a}sM_Bh9Bwi~vwPc_TdZOimu1nBt_ zI;gplnXtLoKPY!uDZ{LRB)36&bHKpyF|8hFkq)g;@;J&AT+|gSKH(3tANTnYPIEh3g89n$1{;mQD9FQzXM) zZ=K0`wf1W#48hWLbbNj+_H@=ZjarSG^=7T38;BwfgL0{`wg&FdosGM8{(2b_w{NYo zKEhmzyFO2XW+{@*_0<{Pq~!cEDXMqGMf{q&Rw(jZh2oZ4Dw9I7yeXSd`fS#*o%sgw zIt%f733w>$xV(EfVW(f@xbWNg^=);FWSL?v#WiQjGX|h}_=L)~soO@gK|~{Da#!PO zarJ0*Dms33EcW<4hnz^2@K^_c_S2e9E2ZtaMywT+Nx;X!;7MR{E*->hFlS z@GQ;2TDywfxhbb*qUrgu@KLx^r!)2lGGFbd$I0bYF6+d|$s$+&+F*KeENpekXJelb zKG9D&AI9A_lOq9(&E+o)rnhIqAuiQ=P&aI<>215ouca^ZcSBV4${y9`ofh_@-u}NL Cxmr>H literal 0 HcmV?d00001