From 81c3f48b3f27fb56762b5f37e132691e173c2924 Mon Sep 17 00:00:00 2001 From: no_name_user_7718 Date: Sat, 4 May 2024 20:09:15 +0300 Subject: [PATCH] feat: added client --- config.cfg | 1 + data/scenes/main_menu.tscn | 9 -- data/scenes/main_menu/main_menu.gd | 14 +++ data/scenes/main_menu/main_menu.tscn | 138 +++++++++++++++++++++++++++ data/scripts/objects/Client.gd | 43 +++++++++ logo.ico | Bin 19401 -> 0 bytes project.godot | 21 ++-- 7 files changed, 208 insertions(+), 18 deletions(-) create mode 100644 config.cfg delete mode 100644 data/scenes/main_menu.tscn create mode 100644 data/scenes/main_menu/main_menu.gd create mode 100644 data/scenes/main_menu/main_menu.tscn create mode 100644 data/scripts/objects/Client.gd delete mode 100644 logo.ico diff --git a/config.cfg b/config.cfg new file mode 100644 index 0000000..f86e053 --- /dev/null +++ b/config.cfg @@ -0,0 +1 @@ +{"Ip": "127.0.0.1", "Port": "3300"} diff --git a/data/scenes/main_menu.tscn b/data/scenes/main_menu.tscn deleted file mode 100644 index 5dd1fbd..0000000 --- a/data/scenes/main_menu.tscn +++ /dev/null @@ -1,9 +0,0 @@ -[gd_scene format=3 uid="uid://chcw74fuwkuu8"] - -[node name="MainControl" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 diff --git a/data/scenes/main_menu/main_menu.gd b/data/scenes/main_menu/main_menu.gd new file mode 100644 index 0000000..de55c16 --- /dev/null +++ b/data/scenes/main_menu/main_menu.gd @@ -0,0 +1,14 @@ +extends Control + +@export var InfoText : Label + +func _on_exit_btn_pressed(): + get_tree().quit() + + +func _on_login_btn_pressed(): + var response = Client.connect_to_server() + if typeof(response) == TYPE_BOOL: + InfoText.text = "Connected to %s on port %s..." % [Client.settings.Ip, Client.settings.Port] + else: + InfoText.text = "Error connect to %s on port %s. ERROR: %s" % [Client.settings.Ip, Client.settings.Port, response] diff --git a/data/scenes/main_menu/main_menu.tscn b/data/scenes/main_menu/main_menu.tscn new file mode 100644 index 0000000..fd1ebc2 --- /dev/null +++ b/data/scenes/main_menu/main_menu.tscn @@ -0,0 +1,138 @@ +[gd_scene load_steps=6 format=3 uid="uid://chcw74fuwkuu8"] + +[ext_resource type="Script" path="res://data/scenes/main_menu/main_menu.gd" id="1_74xps"] +[ext_resource type="Texture2D" uid="uid://dlmiu17d1mdam" path="res://logo.png" id="2_fm7dl"] +[ext_resource type="FontFile" uid="uid://dhvfket83gjln" path="res://data/styles/fonts/Roboto-Regular.ttf" id="3_w2047"] + +[sub_resource type="LabelSettings" id="LabelSettings_7g3em"] +line_spacing = 5.0 +font = ExtResource("3_w2047") +font_size = 24 +font_color = Color(0.853803, 0.675632, 0, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_iy7sm"] +font = ExtResource("3_w2047") +font_size = 18 +font_color = Color(0.870032, 0.618438, 0.0727505, 1) +outline_size = 1 +outline_color = Color(0, 0, 0, 1) + +[node name="LoginSreen" type="Control" node_paths=PackedStringArray("InfoText")] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_74xps") +InfoText = NodePath("MainBox/InfoBob/InfoText") + +[node name="Background" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.125911, 0.125911, 0.125911, 1) + +[node name="MainBox" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="GameNameBox" type="MarginContainer" parent="MainBox"] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="GameNameSeparator" type="HBoxContainer" parent="MainBox/GameNameBox"] +layout_mode = 2 +size_flags_vertical = 4 +theme_override_constants/separation = 5 +alignment = 1 + +[node name="GameLogo" type="TextureRect" parent="MainBox/GameNameBox/GameNameSeparator"] +custom_minimum_size = Vector2(64, 64) +layout_mode = 2 +texture = ExtResource("2_fm7dl") +expand_mode = 3 +stretch_mode = 4 + +[node name="GameName" type="Label" parent="MainBox/GameNameBox/GameNameSeparator"] +layout_mode = 2 +size_flags_horizontal = 4 +text = "Cashflow" +label_settings = SubResource("LabelSettings_7g3em") +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="LoginBox" type="MarginContainer" parent="MainBox"] +layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 6 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="LoginPanelBox" type="VBoxContainer" parent="MainBox/LoginBox"] +layout_mode = 2 +size_flags_vertical = 4 +theme_override_constants/separation = 10 + +[node name="LoginLabel" type="Label" parent="MainBox/LoginBox/LoginPanelBox"] +layout_mode = 2 +size_flags_vertical = 2 +text = "Enter to Cashflow World" +label_settings = SubResource("LabelSettings_iy7sm") +horizontal_alignment = 1 + +[node name="LoginInput" type="LineEdit" parent="MainBox/LoginBox/LoginPanelBox"] +layout_mode = 2 +size_flags_vertical = 2 +placeholder_text = "login" +alignment = 1 + +[node name="PasswordInput" type="LineEdit" parent="MainBox/LoginBox/LoginPanelBox"] +layout_mode = 2 +size_flags_vertical = 2 +placeholder_text = "password" +alignment = 1 +secret = true + +[node name="LoginButtonsBox" type="HBoxContainer" parent="MainBox/LoginBox/LoginPanelBox"] +layout_mode = 2 +size_flags_vertical = 10 +theme_override_constants/separation = 10 + +[node name="LoginBtn" type="Button" parent="MainBox/LoginBox/LoginPanelBox/LoginButtonsBox"] +layout_mode = 2 +size_flags_horizontal = 2 +text = "Enter" + +[node name="ExitBtn" type="Button" parent="MainBox/LoginBox/LoginPanelBox/LoginButtonsBox"] +layout_mode = 2 +size_flags_horizontal = 10 +text = "Exit" + +[node name="InfoBob" type="MarginContainer" parent="MainBox"] +layout_mode = 2 +theme_override_constants/margin_left = 5 +theme_override_constants/margin_top = 5 +theme_override_constants/margin_right = 5 +theme_override_constants/margin_bottom = 5 + +[node name="InfoText" type="Label" parent="MainBox/InfoBob"] +layout_mode = 2 +horizontal_alignment = 1 + +[connection signal="pressed" from="MainBox/LoginBox/LoginPanelBox/LoginButtonsBox/LoginBtn" to="." method="_on_login_btn_pressed"] +[connection signal="pressed" from="MainBox/LoginBox/LoginPanelBox/LoginButtonsBox/ExitBtn" to="." method="_on_exit_btn_pressed"] diff --git a/data/scripts/objects/Client.gd b/data/scripts/objects/Client.gd new file mode 100644 index 0000000..21f140e --- /dev/null +++ b/data/scripts/objects/Client.gd @@ -0,0 +1,43 @@ +class_name CLIENT extends Node + +# Helpers +var ClientPeer := ENetMultiplayerPeer.new() +var debug : bool = true + +# Properties +var settings : Dictionary = { + Ip = '127.0.0.1', + Port = 3300, +} + + +#--------------------------------------------------------------------------------------------------# +# Initialization +func _init(): + # Set priorities + set_process_mode(PROCESS_MODE_ALWAYS) + set_process_priority(0) + set_physics_process(0) + + +func _ready(): + var config_dir = OS.get_executable_path().get_base_dir().path_join("config.cfg") + if debug: + config_dir = 'res://'.path_join("config.cfg") + if FileAccess.file_exists(config_dir): + var file = FileAccess.open(config_dir, FileAccess.READ) + var config = JSON.parse_string(file.get_as_text()) + if typeof(config) == TYPE_DICTIONARY: + if config.has('Ip') and config.has('Port'): + settings.Ip = config.Ip + settings.Port = config.Port + +#--------------------------------------------------------------------------------------------------# +# Methods +func connect_to_server(): + var peer_status = ClientPeer.create_client(String(settings.Ip), int(settings.Port)) + if peer_status != Error.OK: + return error_string(peer_status) + else: + multiplayer.multiplayer_peer = ClientPeer + return true diff --git a/logo.ico b/logo.ico deleted file mode 100644 index 401f3cfe2024ead3347d361248d0c9e88a7a0c62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19401 zcmbqaWmw!yxZTBFOL2F1DQ?BJxGzPE7kAe}aVhQvikITHKyfHm++`{54!e8#?*IGi zCQqJZqHi*jnKS2{0RVun^M4Z%Km%w}1pwZ@ZpUe9C}LxfVZ3f)D=W!=`0wa{3mVGn z%GABm_P>;?yM``ss>CM;08n*SmY31>T{$&F^?fsc*L&D~kAYtGH&Q@}u`F4d01ct! zhOYabsaw1dE%vDZD)IjP7b2}P<4XOLsSR`*nxjpw0=NW!lcil+et?~-(hf9e^HEF5 z+s?zY3#7$a!36e}qz+`o)n>%!jK05SlV zMCfS0B-^w}WgwhvSyj^XSA-esx*hTLs?tSX?a%R*FCc|WbqFF`_uwKE&9rEGNTYj4 z1kR&82@n|8TXBU+PeXGdY!GaTgoFg!ALC944V8A(3r1x-)6nQgLqq#T0IG7uKOeOq z#Rs<9l*x6qX7L~(Ak+ecwH{Lxvjg5o4&-J)E(Su4mkJgsSNzdm?>C*Aq5=u&8VmVR zLeWz(245G1ZV_Zq{_pMVIey7MVt?d8`24>~kq0fm%-R>ruWY?l_;>}c41o_wPoAU}Ifj$Zp%pPFGmF2z{Q?Qf$*%SX z0R*vYcQ10_Hu~#@u6u;p6A|NRhI{C-zl%bpn-q{UlKj%&Xx^NPeg*jB{1-GDJ7sUU z#0aGmtL~R7tYW^HF@LuE56j9nQWeaZe%` zMlW}rq?P6jK?6nMKSYhW6&p_yCw_@f%6`g1`$vF5%W04r7zncXTzodSi9zoct5T%Z zypL?aW~A%FjkktHqt+{GEno>tbM3EuN38rSF@3+(qq~LHW#2}xY z+v+*tsH#h_siZHL*tYgV@7k!w+Nk4*@d>ym_^8}k~BrmP~T-rHwmefe94 z)K+K=C$wR_FjA*(lO}>H(nEU6#A!CsKh1~V2bh=(Uz8LS4mDk)q=?BQ=iog=X)=P(0q2Ha>ztyiPB7O2vsMdrxi}y)`PbigMTDVVtwlni-!* zzeUjofK9yM$Tz3(J1$t5Vk~$?{wPwQDo?1L+PNR5OmD2#WVT-H6LDb&&hJ z3vAtp^a9@t6MK0_A)}z+>R;t&5gk*S_VoQX8;0#u(}nMRxIa7lJB9lt*rZHM?ZaEf0YXD#F&xeamA?K_QRn!k>!dfHsXr5`bWL*xlm6?iQ+LwAxoV=FYZx*nX)^ zMa3h`NV-wR>~HlYB!x}V_OyJipa5e(oeEB_=^GfUwH<(pqQu-Ttmj<};*^^v1iOKg z3BgAI*Ep?z?%EV6WK6mX-m&FBqYh}c+)B@a)pZ$8xVchuywt1$jV=R58@oq8akt<5 z&a$f{aY26_C>=)Px_M`cV-#y~CKJW_11tFEj<5llXxt0>t5!`H-gHA@&e4B#3+5na z+V8s=yD4zV`*TEitV6YOtsMCLOjs1t~d5ETZpu9P`h#Htb$hzr(4Jai80j0Kb z$N1Snh;Ow0GVW12r*(Q=J=6b!=L}WPqH;FeTFNTJs$I1LC;nQgg_zl+$#=AWN$bfN z1?1C)B9C#i^f{rO96g8L@9((%`JzF&<>7xM>~>$3A!T4bOH=Bq^>Y8Sqd#Byw1@*t z9VoB1$;P;0WPB>hI&hN z@&Negcm>yPSF)CT7Nx^wrR{Dut86k8H|6q=c?$KZ6!wkMLSNwCxVaCM3#xix4f#39 zy!7v9X&QZS4|iP9r@oL~C~UQ@voAB9K~FAOpHyoFJGq{HpSTm~6ziBC6Z1GICMF`y z>Gk*-t93@Fx5f_9hdM2waE2tr@!9%-=m57sLrCw%;tg_0?uZ$vRmVulMj(TX4OzG2 zgK`OhCS&x{r!a-Shm!Cxc+c7XaVu7c&&UFPh*lV_Nz8F-v58`TTRx%XzK#dzPUl+0 z=FF9l`de4Kvp>ZZy8^)~H;PPqm|IJb@b{P7iV*s*(r+1Fevi8DrWL9_O62E*Y~2Y0 zjn}6kisKtgRY~rZs){63Z`o|Foy#r?b(ZD!>gtax%kbM(@lB*D>y7t+bzlMkG4JX* z60)COCeYJx)B}S1`&gxtq zRGeRNQR#e4n!ccSOy4wRZ_t8OQ(t?uLuKmfKEQ(!zY{yme8!j(SQyrU2OXW&CpyyG zgxBi&@8SMtq-oV|&s0GmI^Vyu(U1_&RTC4>QhO&5k+3S2G9e<)>~_^h8o@;Mt;6mG zHY)XXRSNxPq%2|%1XGO%JznZH>^wM7J?4)&S0~n9T73Q}X!LT$=e}6&WAxnU&#qz@ zbw!K@as9p=To-APP{F*GmCrhV$DQ5wB2s2$y28KqVkg?1MdoA5dH!dBglf^xnTapL z?O|Sg{T8%;eLb>9Oq}*9#x?~V^?S0>)YNspyZsZ*(yrS9l&#nopGl(jdT z`u;Q=x-Y8o1@FK_AZL>=v%=BKG5^vsxNFMIfn?#M)=%3;GB>(~(%5|_{@r1RF`ty& zJlm->L32NL9Rsrp4d1(nxA&)x*E8ff_Hk;%@*h8v9?TXm^UMrw~g|byiI|^`#6f~-ub#6KCZVJe^C^$M0 zST*k=wapsvc2iSQgz_zAd&(l(i>yuG*si0gCkarj6Ds>y|JLmXZjg+vYlwKajPF%0 zn-qZuN!G)~P{=YT;h9oGjG^#47hF@ffaVH8D}bdZ;;KVZenUP|FC490&34I;T4nD& z!NKP?;rXxNWY7?%$H)UzXXHk%slQUVA(QR-eZwhq8gVw$gnH|qN8i?F%QMl{at?6mJBHw`y zHqLC-*LTIl%b4re4G$|6PO58Pc(OI?+G;P$@74BCX}y!N?w?IcM?Ll^e+nayNzz_c z+*^-4&e)`s-`fb&3h-lWsuFJ4IiO?ZXuCX6VfO#Is39(L`*#a91~%^pB13A%MA=l5 zik5 zeDil^7Q=QIKbY*9Cetxo#btuP2 z7KtP}5Y~NjlVqy#75sHrF9T>g3d_}kEuiWOon+3HUCO>6!jYQetozW%2@w?Rc{CIB%$qc1jkOv{H z5`Rk#3-%szmocm#P{Itl=`o4AYSjScp8G9iC3Qm!*?yVbj#=m_XY_WeJZ=^Z+q4GmUpf{7TIQ=?5IIyH&>^k7D+D-4XLUdzHcCLl=y2N~?!gx$Gsf1< znJ^Pxo*4rt%MrfJv3T8JMozmIqHYA!0LetdKdMskZcdsCnl#WSERybkyfL)@D%Mt` z10A+^^OzTb$v3m}H_ZZ*1a z<6>qXFld-gDqFhZbc+v+^X&4osfdEkXCn`n&2{_F~~Vo~{y< zw;ZenlBg6P@lOr#`||u;%9$~HHksLR<@@@TEfj>Ady) z1jt=G6;Y98GZ4hzF}z)`F#BS|Ok%754&x!n zfC%g%2zYkbllp2?Pxn2f{^i8A^9ejiNp!&#RI5mA3l5h-*IMF53lB7X?FKxM7M7=0 z?>@)r{=8PB$0H#|T3malWP`L^(gj<_AKUCo zRwH5WC@<6S&qA^4_ENB>8rhCMGjB=4tzU(^QjVQ}XLyusmCp{WR4rVT#M8&t3?t0F zVzh~}tFC8x-f(z?*Ww3aM`#zplg>Y<`{O$*ewPLcqWEIJB||uoqmNrz#q)(4{^B^(+SfMtO}ft=lAWR%<6sui`BzktL*K;P9A(HTkN;xZlNRU|CGy-4 zMv3c%J;Sb_2kKN3``;=^vxE==T$dyw8%xMrZ+>(_{e@|+TUWu~bXPM=H*itC&C5kV#dd7agiHDqs)wqYIp;Rdnd z!4q@*VT@vv3aoZMb}R)JvqgH}N>wk!GiGHR8>)>Q)LVwoUhyYgQEL7|2Prab-|Uw& z)gf#t#`kQCa8Op_EE92m0c2C{!T(w8=-nf4Q^*1J`gXlty3Web*;6C-BTo$j*@u#D zMp6y<^TSXexj&E*ko5h7a`<=>Ltoh7Omg8)v7%+7&SC#$_m11&w+qL}j7S4psL_?O zVcAntkWYC2)`N}nRAy{*HM|J2kGW{RboMPTA4~SnYOrpLlC*bl%|c99!n&Xo!gq{} z?31zxt`p}+J1jQ$Qc%sfpq;>{oXQtgUhJm%2cJ~@hS6tzpm+gxgP`);BkVwbM+z+N z8)O5!v*azFl&q|VWLe0Yc2J>-t#48Qfw1AsexE=Bu zN6T6L=*|ZUGK@k!3)biDFD|?0Arx1>41#en^Qcx+=6U5k`CWogh+Nus%rN_D>5D+5 zv;nndu*YI(e#nQqzPH;$XM8^%PW2SFW`ochJ_7D=+k649@Z@Fouo=?@|!QDrz zL6bh{un9iWA6A>Lr;}4`*16tIJ_lQ~z#_2IM zvWz}R%!p;nTmKNmI!~rSMlE!sGzlrGC)5S2AhB|_FXt9gzCokb)60>7^4<+&cNd)G zz|l1psl{HtsY@2a>Mp=}p6y+BQ#r5=vIhrMQhC(eDd(-;?WrY>^M-2OKgi!m!lbA* z!k?KV2tB-9K#*xKnE%9U1g zr7Eh+|IvtF>QNedXAYCPg4@cob}hRKcKtgD6Yn-?{I52p*s-~!be!SQ1=W@SETXX5 zIP3(l#cRO~c?C^3NRs;;xEj`a$SeE9sz`LA-Jz{jziB+Czho_xf(k( zg*kK^V5b2RwoHpJVt$~oOu#m%JGAn+mW^cZCw#^yYRhzjA{O)jSp%FJcA@I$lq%&V^V#f7A?aB>M|Y2e{<-#o?7# zBoDC0vG3Zje-8Gs+Q=4?h8XvgYKS4O#7&D)@Mx(BsrX*2CWqg<@4k`)2GKxXAm1=< z?s_`*H_}4olsOQPluzYyWgXgtEiOj>`y(DKM13j~#$R>W0HQ1W+FUb&w-^=+x@O9- z?KW2#7w93}uT`xrQQ|blrWYX*HA&ezPF=DP+WH#?eF?A`41wOseiJLA{FQW@5-W>_ znvDiK5q}bMUDLLYuw{7a)Fjql7ouf*N-LD+${9)1>EP9sO7KZC{h&JP*79Ni(q5+qwsR{8d zB0n)%orH~PTEHjhAq^i5`F=6hQDDd$fC>9p&FR z`#eKQpSlw*(y2|KH`&+2MCiedhI?R6YL~0Y%F#DDi)uU{#-WNOnnbHf=`ZZMye}I| zOwsR8gOuNC{|Y_n<|aU4-dstkav$3K!z@+sM3h~;bzm>iN{z#C`v)VV3pg$TB-0Sj zoNpil(Jcvexr35#3KEV*<(Gbagc4cJJjk;ICB0Ndt$meY*Q^O68rBaHySmecj6vUe z!K$&Gez&V0%N$aY0ynj?;Hmh7t(FI<>+n}{OSX=h|4u$tY2nLRW6hP0vT;LT>RD}L z^;NI02UXeN^U6n0J;uY+7Y0e0@w!6TpR~sns?bziFtFsOMnTQ7%$J)P3Zk%o&F0KZ z>~9q$1n*S%F1G$E#6)U6{yR5AvPm1`evWw#sY++G&>BnJkR__e>5o&uZ7bD%7XA!p zAJZM}&8Pfe$WZug(oX$3szD>fdMC(MFEPk0pQYSB zj7cF*zl1q<=oU4Aj2HH;4bC!GLT`k-{2V!{%b&-S>8*CKuE6!Ue7QILcH=4muamV` zhK)})!+V=-^&jxf1#ZsY(aNq?L066HhH!m;(&3GJ^KxzWH^@(EMUg%ri5z&6hE z2u&&`EEJp9;&{j#7v}>m?56fZJN(?XT&@K-Z22a}gnHN-*?wSI2f2%-S(5Z>3|09Kgr&U4mSh|0Ot0!-8U6v4TfwRhUaS}+&u zuRG`GrQx$|c#z;MOJnA0qKj0)OUH=pVc`M#)_G2l*;9eZ{`cc=!)l5MsbTH7l&)LevsX9Xdno1}pH^0`C)crP&kyqG2vwmcSRGHEiywUls>nl~&VK z3*~xY!|@!J1ukgF2B?Gl={BfUQ~f=K-!gMe=+M< z98^oHqWc=j*(v-}?a!LU1$U@I8(l7E3cg}u19x3#M^7Q2iya>Rt!V8dHfMguwvmsB zz+vr44xFnylhPAC;W+ub5a{#;A~A7i;s7x3dS~E|?NPt^?vKHt%ibySLHR!V9u{IE zN0KFeOkjns^)I*h1qsd5IT=9;>xnm!D4>HOeB*9Fk$4)dti&m<)0s$Z1|YD#OE(|D zF`+jP=WjlSlPp>cw?(%b;}T}h^{i@J`h2N(rDBU{u`I|Lm15PlD+WHq!s_(j(|#Lf0BP#_KOTyQWmRofTalezXXUy zBV9St1-zD=SJM=XCYvJc9^Y_H@27d1;=qqnT;U^oN(A|jD4ppLS^%nj^c6$1q4qZl0Yl_JCqaeq-t~VbrbecD)WBL@( zZhuMb+vg*d?(A-LX(Ml~jKjU>n-6oCM0{AwII_boi>Np(<2c>$$5xbHe`+oI*+@bqfUVpEbBN zW`!(w<+lP$`-&jL`Z9N+6q&?)ny=rq(fpX{Rc|i&4(Bs|ibDYfI|&>!Z7BRA4|QWL zU%u5^*FiinhgEYUo>hg9&ga~IVx=zb#ImQeN4of>C>P2X4!cKJ)sH*mL?nX%xi(gD zu6~h51b@6i1Rd&o1d9KQK4U}V87?E3_Aq5VUN++XJJ&OPawPk7j(upR%Lr~NmpH-( zFX|4-M>e|bAPfmk%sxT!%e~KF{GX6yjX!hBsyi*EsDw=!%SdQwK3aUuj5F@4GIXU+ zPNDHT;1P1&q8REn`EmQ4k6Jd*-fJ0B)CjCBSR|%s&Mt+^{kCr~+g29PcizSV2Q3?Y zO$1mWZ_VXl9S~F4t1A-o&AQC`$0kRQpPluleEiskPki<%S0A)5`q}Z07{u;YT&EA3 zaCy$=b;m&7nccREL|<+oQ`VTafRE z;pdDiH_kbXdl!lLJUf@Xx8-2g7~4vJpi7&NxbMR!e-mc(O+FnUW|$3C6K5N(i;G*? zuZm@+B4PeHn)$hidBo%)9%<%Sl-tD_Y(I6!*DydEVDGgWNfcQ;EbNA)A}exg7IoY( zWj*KZo@}$S1_X<_?}doyGTvn-XTWK^ttcB_ye-Jc%4%hKD5-AGYnhfg4Yz#wqkW44 z{zYm(o5{LGv^B^^8-pR(Ox>`#dgA0$*-4(qAxwsNW`JFR*|8`L?0!|mFIRLzmCn0^(%(Kd#ES)W zXPUnTO)@2t-5p;ic>gS(Vl6u@#=0yg;9DSw}sk_QLL;+!JdYZMpb&~Ns? zfW0oi5ViOK7}z9ap^JPS4c>q){X(IHd-(LpvyO0=vOi!V5JLjM~W_6Cak-4S>_H$jP+LuAb-?X|{1=36fzJc)GE1NVJq}0498$gsLe? z9#QF|a#nDaUM`}R<+EbMy3CAR764r;*wSU*BJv!M zwr`P_d;;_^tn4u$2=M?cayo%2R8$ulHr&pL;5)!al5==_Ch%b=Y_|Hp#w>KqA>J+Y zn%+vJUZk3Hlc0wmu9NY0J{yB5Y-P_-OWktWn4d~t0Fc%rnUc*M}&?4P5Y zuPyH$kpmccW6{Oc_AF&_bE8c2D4Ymzl->a)OhYyAr_FK3vXKI<%*fGZG!S~^exbI1 zNDpvgLO;NjYpqHPRsEV8s?(x@dM-VAaU?-EB6IqM2f~!giAcrCZ-ElX&QG}#;BU;2 zL7@csW=ndJ`Lb^bNaz9zAW^UBa5Q7@o=6+{$I3H=GfH;{0JR$SSoBam=izBJLI7^g zBui(kj~PHg)b{Y52+$JFwGB89mv20@hAlEQ100piovSBpU?8GpTDFXqUcQd@`(tJw zQ(BO%l@hMqQa4?vA1Q!dE>vA|=_EoYQbZ-enu_G-)(DR`Ivr}!Tl~t;UH}Qqx~Wf? z_ZGYW%_ekNqp#BM$0S@{JiO2rosh@^?nN#xZX1RG=!WPaY%!DT01IMb-x8XsN}@LI zyhCj*SAgWi83rRTxWWYQgt^4ra@0!3(#yxvQAqKja|8zB_~)oiN8{ zgw1zCSa}qJ^~d-n>KLS2)0`%PSe^^^BnM4-Y6sL5)~9@0lb`o8)ZbzKm9DBiIX2jNqMS7coI+?Ww+k-% zx)TaeKT#S+-;UM$0#xfQ^@Ut4*E$>JBQzw7EBLTHi!Lo`5|L?FKb9aZ0PQS70#gC3cDS>hN5+j9mLXBo1vJ{R``U< z+?{vXexYtIN$6%PL;na}^>7&RCund5%uHZ7ta^VzpoMnH@QillW)DFql&SN02dBzG z#f?xl`Mr~DatPsRR8gDbnVm;(;j2=?b!JZ{ix&a<-T0%xPbXEC+!K(GA8(l z5gb|a$XIOnJoR((u>J(~Aam=FF&>}vZV&Bf{61IA3Gcc9x{Qc75=`f{UFX$2W?Gx( zqT(XsMiwkVlG6ZB#$9gxa31`;GNrf+?R2n7Z6rN_cIH-68kRzd;b*UeXY~QtFaVgG zcoN_d0QAl>QUf?75+uwZf`4pn6~vhB2XD>{qWe#<^YQ`G^wL4&iFJ_^!A2a2JSP8v zv)}Q(*`4S?bo5)f!Sie%w03KylYEqbQg+PxoWkKVm>1E@;*q&&zf9^`m1Jh-sfXlN z+86l{Lro%@?+`$&jhEd3A#rGi_SWefJ$PWgkBo28t(M?tbt}1U{dol)vYEX+M#sbS z2cB;a-IsZY++Lc)yx3if1wnYvNi*)3%kuCj2`jAgC! zSt=REHlNfg$^Ytd#Wya^nWek3O&B%;(Set+* zL?`la(ntREw*C=Rfq*?O!(X@WKCN}@uC)hkeZN>3huYvy(*z6oVt);=KSPo}6p|z! zs?Ln~qoW64v%3TC6!~GV%HvAUZ8O#8zFV<=7klV`L3wg2eelO?+Bbx`+_dtYfEE09 zYyQpz7sk?wRcVZySl26XLArk%7c6j8{`W%|%Fz zVLO0xcW3gG7=&1gk7nUBzIMYtpU8aebo|7A2Is#n1rHCT=)tK++6)#y4Z?%9gWaG5 z1A10q)kLmpO#s(YE6K;sUyaePC245d^d{D-Z+KkgZ=5u}znc?!9ky*pMonFveF-mF z0^fIonxL%6=`^ymz_=81H5IqIZom(H(5YW&8B0Aoy28ZM>W_WbpIFv!I-hY>19-7q z)ti7UJuJYXllEBzCs8DU$L*@E(n;jlsgJ_Nnd&iaoDdHW&&Yr#{&~(mo53IAU=?qw zEwd7J+h4`3Vf#r!0)_bmc!O^304C$gOwY$iHSeuB(Hg;L@INBLt}L<-$0zmJv> zINRJ<-XBYAyb*f>9f9(w{JYkp<-={}8<@$= z8IM{Qy_e?~o4?kABmNW0*mE%tpAC!^Z)<5oB=eB?*|M8M)^@cf+7t!ltq`Wy7b%}M zRyLhpl2QYLB#%Wej68`PmVbRK9|n-TmUqUQ&0#BA$X zz^|=$WN;rBt5dwxP|DDC|F5%R+g}=-{nm9+z`g=YAf){v`9>Fx56MkAVs-Rn12Qba zx)tKS*)Vv*8Ws}7gRgLZVP%HN1d8D~!*&Ps)ZdDl z#aRDf0(?D&UkMeVZylbqiUM+J-7t?;=1#Z@wEpYD9rqaQ11GRiB-VL}5b^~zNlh8v zWqhVwdbuoFkc-x}^sYynUJQO^e3jzwn{uxzTCXD(UB?l9>Bc3;>hoYzT(RNO&PUwo zS+Q$xz9XBWIC#T0Cx@|rxE@w~f&c4nYuLE8@N?(XojAb8S=pFzq=WVPOW(VumV_26 z1o#Ix|FU`>FC>{nAQ_M9(Yxj7i?%72c*(|yz>*K6z+G`QuGdL@TjM!7ztqeY8i1g! z?OgYQ9_+Sf>+qXu>Q~{_+#Gx&|Fpgj}t>dlJ~phGj|p| z^OzJM`$#-PMNMpv@L*-LRTbX#C4TWnZ1dZd1v=uFqi%p2N?n{IJ$@XXb54Wt(DSac zr_!;^XLrw645zbo#jodWhZww@NOzD=#MWKW{3WS=MvNV6V@WLo-st(vDwQ#wG-4Kl zwZa{tZJQ6v(CrbvC-eQ`L!M(+mXhITDeOK`mvWIY5Qq&5UkPkkpR@)Lwo& zfLb+BH?hnoyya}-Cvgi^(_Ihl-!UP=C^e7G9GAO)7)A9-8z^LXEtXVo*`;vEwjJ}< zW!GW(`KLc#4xY{}-c05^3fH*V3BuZ%e#mcFO7dK6^c|h_&b&yGg?>5A;JBwY2xG)J zbwp{?HBsflIZ~}mgSo6i~o$SB+?jBuG?M(ycmTt-U%c8 zB?Jqt3!ky1zm4>?-=+Ud)KG^Tf)esJr6xZGqta5t~EQjhmXo*2OXdMW~2)L@&Sk)o+?wr3iqs~)wO7jw+DQGMt??Mq7<=UzgBxAJIT1n zxZEnRG_nRhj2RaskG|N{kdp6CGmEq>)t?{7Nb=Y@DUG8-D=uNAlR+u{2}(#OJI=Is9|3zF|zU^iLq@Jv%>*vvz(y8`uF=sm8k zKjv3Qe-T#3UOb3^eFO6TY-sRajEo?T?x^c5AAnCsD`f>!N&Vv`Qc;)s-lO|l1y35Ikl*A}~lBQ!x#fxZ(=bfAx1_E;R3L5ZFF?RE=a2ZHp zrycOOXM&~K9419UQ7AUP^j;r@Q-^QC$eh7&oEp-*Y?ZEU)bUa}9^BAWWg;l~WNJ|y zacFxe?1a}cT`X1zSWZhCH5Z=cCl16y-OH2yYPK5n*)?=|!nch5FLX5#WlP)d_x+uA zG2V#Jl@;^8Xrh`}$Ii$oJj>RIpWB@1S+xSLs;XPw3sXgHV1i!+{~=&o_5@Fe;sm|a ze3skzpnKiJSgZ>S~-Ue81xh@Xgg_bqO?EU#N7DCH=R9x*L)A`Oe z1L}4(_3gHzagG`_WT$DRvF;F2``J}gm(4V+i_;eG4 z4luvHA?>>kc6EzJ5J~=7_>Ujt1yGHoCVxU|>k1>I*RE`Lqvx)J`14up|J&S%E9haJ zMGp+L!77s%WN1|@4~f~!^?nDfx(a!f`4fszh6dw0#qf!pTecs9FYOY4n%B#zE9$LN z^TThu;4c+YV^Sh)_y|HDV4AT#XM$>gZ5OHg*Ksl{hjAeQ&91<( zQQ^v)UQJOTs*9+(NJS75pV6MV{H2&hjSM&W5G=;{Twp>nxw>bSOfR3CHUnVT?#jRQ zhw;LG)JgfBZ|1RQheX}?I*X28W z-wRLAJyMly)nBBautsbds}dL|rbzX1Fv9qK7{~H`SJjY+U6oQl{vOP#tcIE2pL?e& zxxhi^Xdv@61nIORaw0Xj6I?pK>fI0MG;Kwl$UM(!JxS zddj};N60vq+HG9MD;U9gb|d||1$6|DxjG=329y1j%GJY{-kE+Km7U-HhVO$w}Nvs6}L-B5_y=OJf{^b+Z*sFtc!g%&|fYniNRV1!wSU$aRDSljWn#j zQUmQn>TdU)T|xEgiRz~eft_A$Tslu};;72BeP%1d@SbZA2YCs6L2 z2bzWU=o_{btaK?BCbTEcItZ-;j}QW;`Jvv*+@GC5EC{8HEaM0sKGpE7HuKuWpA7RwQHEl(<@2UwOpYpp!PLk2@qIQ`~ z;QVc{*Vk1RD(aj&cptsE%*0G~DUnzg8%Bf}PE**^nwS%8b=tku*(atEKMC?7OdR?V ztC8Xcl^akqg=gRH_Mi+EN_zb0TOQ1=xYqd#&5ge*g$QYE9Pl8VXGBMNKU+$l?s9NT z=e!lD!`QPO==noQlfg}Wk+rj-ch0*xsWjV`(HOr3to^zIv!%dz6%$ zxNPuVG^?>$y!%C`8a-AiTPQK9`tx=Z|904Ds_>|<#M%SDQROFoo#0*acV4f8%Bn=c z{dO*Nya@KFJF3ZFjgSFxGq%Lx^F_cdW4Q7}Crbc$1BQ+sB;9%}@ilF88L8@U@ZJwZ zb}`^qJ=(sLs6B6|#qyr~8csiMwN)F^5|$)1*hkzt*!M4YcPm7XFOQ3NYaq6xay5A}Kxv3E*Vt>5x-Z#_~!-c?H5jcRS(Sef;ww28>8ml#r5lc&%M#RQV~%x*_CE9%Lyv4S=>V0-8O28 zAjcs{Kb z6SBXPNtDuSrH+m_sgSc)c{6oOy-3=FZmJHUR&))7O1!l!3flE7?c%NP!G^*?6RX9Fba571}U80TmdZG5_euZ^SH`62VJSCn!D^?^wA? z5!3~aR=H1<7~(t*VD!z5rc|(gigJUR zR9sbOisVr*SHwd4z(SD*?bm)(v-armB|oe^ z5ROe1mAGmJ6IU&{$>I`&I+hQ}c-2T$_QDE!eKV+!U)G2I^&hP7lCi;69U#MYpGKZ6 zw}|(rayv;lbQfC2;JmF@t|Tr=k%gc4H#s7XeW1^&@leN+#h|fdr8lcly}LN52_49q zT?|URc-tx@ zVFbl2zR6eoXWjxD^2tCu%2&((o}tqy21N=2znVm1g(amw|>oRR>35={~;e?-}Go1ZJQc= zQ`9g>PwAMYs)c4t4{|eH4HaPe4VhEk5fIkpQo-q>@x z^crby<@Ef-Z~I=z4fQ~*$8TGz$M{3$h2>5j-j#P>iOLIcnkp%(@3hmFOV&JM^H1qW zefvM9ocll1{Ts)zX_M1LrY5I3MJtE8J1~bin=>UOnsNx6^bbYias4_}v_CWWVrb-`LXSh$V18(I}8skn4Bz8OPNZiu-k1mS-+q)lkVAgNx;lHc_MsR}t(wFZQ9{a#B}Y^6eC#q5nP&(EJ&J3@UF zUi`*gZSHLKPX7z{_!BoSvR7J|SbJq1V&#S;=%za`ysht73Q&lHZx42}(gk9`+^jOC zw@zkZ>WmQ*XbF=J+0qr?pWJMq$@$i&X)fJILFeM*3!rHL!Dx zd%lQF%T4KQ*I}^BtJG+xuh66|KYNLtOJ_Lb4mLygmartrhr;pyO{#L%ZAlw}t|L}c7 zMd8-vIWr04vgK*t6dBShj^dzf3E3H7XgBR!NY zcT6$5$5-w{6s9zVvJtm6HPlz);1|W%8<=32;}&O?mO`F)S`F|+!Nyt!FYGq~UbHKF zyj}dGL8959@?)pE##5=$n8;PcpUcbfenajltCTZt#2thGG3x_k<@8-i7;7rPHC0uQ znQ8A3&x947_Rw?{m4Z9Eclx%&-~3UCcyGo`@(i+^Nbk`_|ER9tsztaHw?>PU#$s8O z3X_PZ2Jl4JxO428Q$W1B=>;k|G-jnXgS@9Jh-uD$fOe%B~H;v*m2Wl6^UKJmgL_T+w5=_p4Q#@$u?~Pbj+lpBI?S)fwyRJZ`OS z&AT~>{VYYS#+r{nfm}?HWU2t~_l<+=vN)?{iRGLv)RL;?O}N<9F{G0EhqSEJ9|H{i z>y+;Y+E%ee+_^@b&F11?phLJJDX{DCJp!lfY{cRBhw!YL8N;0~D*?O70 zD6e+>oIkhSQ2%P=P*sVej?4Ndhv=EitCzMsTt;{qrJoUn>q&BowA^>Gveqezw679{ z-l$>J{W#H%DUHB}f59PwV^4mU)(ft^HiXsYYP>!n^_)L#Q;Zj;y6rcK1bOO4l@z!} zf0-$g@-cDTLNJe`FK%8uRh>P(cf=sTW_MfnnBR$u#OqQRE>CM}Wdz@toIa- z#L8@=`CVUw(d#YGyv(LZ4hhygGNF3EY^Ca5K?34Zd1!(1m~XH+Sy|pB17atJ)7H#^ zE+8{3Jv7~Lk?nm8`L z;ZSrko?wl#6$bdkDnxIWE%@aERSUOUZUxl_o5;#~B?@5j-xWG(e~{@>^cEIfMeNzF%}!!w^Wpyv9}Ky(Qo2$)EzP<+GAt~a4X^y-f+IqTZ!+OXXuD4O zMN9IhorU$8&Qn>XUk~b?jVr6?)3aMFii8E)6QW=U3aB6_bB;%qG}WE{Nw{ZAdBQ=t zCAkJ^OmF9i;4v_4stH{X#v=v8IERU8U5xt;8OOYd?!_3CVm*7=?}MD6l+fR9%@Xug zTLzT6Qtw<3d6b)$a_FkI`4f67ISbqnP^k9P5tIKZn_c0^pc9HMspKinVDZkPtBsV;JD{O8Ab%iex5*@48SLCgX1|(# zCJPIsPV(eh?~o=e>e5}(yPoYBJA2r**%O(-weV4pd7ru`1V8Iz+vZKA1NNg9XjqKU zg)E<%!Gq8pW~zYJej0`^4Bm?e5@QT<)5LKNr7RzlqP3$5k|Lxk!YikEz|X^>i&P} dta=YF?<