From ab9057ddd43e56bf1b260f868a767b8330f5a7df Mon Sep 17 00:00:00 2001 From: Bobbi Webber-Manners Date: Sat, 30 May 2020 21:48:46 -0400 Subject: [PATCH] Fixed terrible disk corruption bug!! --- sortdir.c | 205 ++++++++++++++++++++++++++++++++++++++--------------- sortdir.po | Bin 143360 -> 143360 bytes 2 files changed, 147 insertions(+), 58 deletions(-) diff --git a/sortdir.c b/sortdir.c index 86ef3c4..48ca9be 100644 --- a/sortdir.c +++ b/sortdir.c @@ -15,6 +15,7 @@ * v0.54 Make command line argument handling a compile time option. * v0.55 Can use *all* of largest heap block for filelist[] * v0.56 Minor improvements to conditional compilation + * v0.57 Fixed bugs in aux memory allocation */ //#pragma debug 9 @@ -41,7 +42,7 @@ #define CHECK /* Perform additional integrity checking */ #define SORT /* Enable sorting code */ #undef FREELIST /* Checking of free list */ -#define AUXMEM /* Auxiliary memory support on //e and up */ +#undef AUXMEM /* Auxiliary memory support on //e and up */ #undef CMDLINE /* Command line option parsing */ #define NLEVELS 4 /* Number of nested sorts permitted */ @@ -93,9 +94,11 @@ struct pd_dirent { uchar hdrptr[2]; }; -#define BLKSZ 512 /* 512 byte blocks */ -#define PTRSZ 4 /* 4 bytes of pointers at beginning of each blk */ -#define FLSZ 8192 /* Bytes required for 64K block free-list */ +#define BLKSZ 512 /* 512 byte blocks */ +#define PTRSZ 4 /* 4 bytes of pointers at beginning of each blk */ +#define ENTSZ 0x27 /* Normal ProDOS directory entry size */ +#define ENTPERBLK 0x0d /* Normal ProDOS dirents per block */ +#define FLSZ 8192 /* Bytes required for 64K block free-list */ /* Exit codes */ #define EXIT_SUCCESS 0 @@ -158,7 +161,7 @@ struct datetime { * Globals */ #ifdef AUXMEM -#define STARTAUX 0x200 +#define STARTAUX 0x800 static char *auxp = (char*)STARTAUX; #endif #ifdef FREELIST @@ -179,7 +182,7 @@ static uchar dowholedisk = 0; /* -D whole-disk option */ static uchar dorecurse = 0; /* -r recurse option */ static uchar dowrite = 0; /* -w write option */ static uchar doverbose = 0; /* -v verbose option */ -static uchar dodebug = 0; /* -V very verbose option */ +static uchar dodebug = 1; /* -V very verbose option */ static uchar do_ctime = 0; /* -k ctime option */ static uchar dozero = 0; /* -z zero free blocks option */ static char sortopts[NLEVELS+1] = ""; /* -s:abc list of sort options */ @@ -230,6 +233,7 @@ int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent, uint blocknum, uint blkentries, uint *blkcnt); void enqueuesubdir(uint blocknum, uint subdiridx); int readdir(uint device, uint blocknum); +void buildsorttable(void); int cmp_name_asc(const void *a, const void *b); int cmp_name_desc(const void *a, const void *b); int cmp_name_asc_ci(const void *a, const void *b); @@ -300,13 +304,13 @@ void freeallaux() { /* Horizontal line */ void hline(void) { uint i; - for (i=0; i<80; ++i) + for (i = 0; i < 80; ++i) putchar('-'); } void hline2(void) { uint i; - for (i=0; i<80; ++i) + for (i = 0; i < 80; ++i) putchar('='); } @@ -455,12 +459,12 @@ void fixcase(char *in, char *out, uchar minvers, uchar vers, uchar len) { return; } vers <<= 1; - for (i=0; i<7; ++i) { + for (i = 0; i < 7; ++i) { out[idx] = ((vers&0x80) ? tolower(in[idx]) : in[idx]); ++idx; vers <<= 1; } - for (i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { out[idx] = ((minvers&0x80) ? tolower(in[idx]) : in[idx]); ++idx; minvers <<= 1; @@ -477,12 +481,12 @@ void lowercase(char *p, uchar len, uchar *minvers, uchar *vers) { uchar idx = 0; *vers = 0x01; *minvers = 0x00; - for (i=0; i<7; ++i) { + for (i = 0; i < 7; ++i) { *vers <<= 1; if ((idx < len) && isalpha(p[idx++])) *vers |= 0x01; } - for (i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { *minvers <<= 1; if ((idx < len) && isalpha(p[idx++])) *minvers |= 0x01; @@ -510,7 +514,7 @@ void initialcase(uchar mode, char *p, uchar len, uchar *minvers, uchar *vers) { uchar capsflag = 1; *vers = 0x01; *minvers = 0x00; - for (i=0; i<7; ++i) { + for (i = 0; i < 7; ++i) { *vers <<= 1; if ((idx < len) && isalpha(p[idx++])) if (!capsflag) @@ -520,7 +524,7 @@ void initialcase(uchar mode, char *p, uchar len, uchar *minvers, uchar *vers) { else capsflag = 0; } - for (i=0; i<8; ++i) { + for (i = 0; i < 8; ++i) { *minvers <<= 1; if ((idx < len) && isalpha(p[idx++])) if (!capsflag) @@ -726,7 +730,7 @@ int readfreelist(uchar device) { if ((flsize % 4096) >0) ++flsize; p = (char*)freelist; - for (i=0; iparentry = blkentries; } } - if (parentlen != 0x27) { + if (parentlen != ENTSZ) { err(NONFATAL, "Bad parent entry length"); if (askfix() == 1) { - hdr->parentlen = 0x27; + hdr->parentlen = ENTSZ; } } dirname = buf + 0x05; @@ -1040,8 +1044,7 @@ void enqueuesubdir(uint blocknum, uint subdiridx) { } /* - * Read a directory, store the raw directory blocks in a linked list - * and build filelist[] in preparation for sorting. + * Read a directory, store the raw directory blocks in a linked list. * device is the device number containing the directory * blocknum is the block number of the first block of the directory */ @@ -1060,12 +1063,21 @@ int readdir(uint device, uint blocknum) { numfiles = 0; blocks = (struct block*)malloc(sizeof(struct block)); +printf("FIRST BLOCK %d at %p\n", blocknum, blocks); if (!blocks) err(FATALALLOC, "No memory!"); curblk = blocks; curblk->next = NULL; curblk->blocknum = blocknum; +#ifdef AUXMEM + curblk->data = auxalloc(BLKSZ); + curblk->sorteddata = auxalloc(BLKSZ); + // TODO ZERO sorteddata +#else + bzero(curblk->sorteddata, BLKSZ); +#endif + #ifdef FREELIST checkblock(blocknum, "Directory"); #endif @@ -1089,11 +1101,11 @@ int readdir(uint device, uint blocknum) { hline(); #ifdef CHECK - if (entsz != 0x27) { + if (entsz != ENTSZ) { err(NONFATAL, "Error - bad entry size"); return 1; } - if (entperblk != 0x0d) { + if (entperblk != ENTPERBLK) { err(NONFATAL, "Error - bad entries/block"); return 1; } @@ -1191,9 +1203,9 @@ int readdir(uint device, uint blocknum) { #endif blks = ent->blksused[0] + 256U * ent->blksused[1]; eof = ent->eof[0] + 256L * ent->eof[1] + 65536L * ent->eof[2]; - for (i=0; ityp_len & 0x0f); ++i) + for (i = 0; i < (ent->typ_len & 0x0f); ++i) filelist[numfiles].name[i] = namebuf[i]; filelist[numfiles].type = ent->type; filelist[numfiles].blockidx = blkcnt; @@ -1285,30 +1297,40 @@ int readdir(uint device, uint blocknum) { ++entries; } if (blkentries == entperblk) { - blocknum = dirblkbuf[0x02] + 256U * dirblkbuf[0x03]; - if (blocknum == 0) { - break; - } - curblk->next = (struct block*)malloc(sizeof(struct block)); - if (!curblk->next) - err(FATALALLOC, "No memory!"); - curblk = curblk->next; - curblk->next = NULL; - curblk->blocknum = blocknum; - ++blkcnt; -#ifdef FREELIST - checkblock(blocknum, "Directory"); -#endif #ifdef AUXMEM copyaux(dirblkbuf, curblk->data, BLKSZ, TOAUX); bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ); copyaux(dirblkbuf, curblk->sorteddata, BLKSZ, TOAUX); #else memcpy(curblk->data, dirblkbuf, BLKSZ); - bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ); +////// bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ); memcpy(curblk->sorteddata, dirblkbuf, PTRSZ); #endif - if ( readdiskblock(device, blocknum, dirblkbuf) == -1) { + blocknum = dirblkbuf[0x02] + 256U * dirblkbuf[0x03]; + if (blocknum == 0) { + break; + } + curblk->next = (struct block*)malloc(sizeof(struct block)); +printf("NEXT BLOCK %d at %p\n", blocknum, curblk->next); + if (!curblk->next) + err(FATALALLOC, "No memory!"); + curblk = curblk->next; + curblk->next = NULL; + curblk->blocknum = blocknum; + ++blkcnt; + +#ifdef AUXMEM + curblk->data = auxalloc(BLKSZ); + curblk->sorteddata = auxalloc(BLKSZ); + // TODO: Zero sorteddata +#else + bzero(curblk->sorteddata, BLKSZ); +#endif + +#ifdef FREELIST + checkblock(blocknum, "Directory"); +#endif + if (readdiskblock(device, blocknum, dirblkbuf) == -1) { err(NONFATAL,"Error reading dir blk %d", blkcnt); return 1; @@ -1335,13 +1357,78 @@ int readdir(uint device, uint blocknum) { copyaux(dirblkbuf, curblk->sorteddata, BLKSZ, TOAUX); #else memcpy(curblk->data, dirblkbuf, BLKSZ); - bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ); +//// bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ); memcpy(curblk->sorteddata, dirblkbuf, PTRSZ); #endif return errcount - errsbefore; } +/* + * Build filelist[] which the table used by the sorting algorithm. + */ +#if 0 +void buildsorttable() { + static char namebuf[NMLEN+1]; + uint off, blks, eof; + uchar entry, i; + struct datetime dt; + struct pd_dirent *ent; + uint idx = 0; + struct block *b = blocks; + uchar firstent = 1; /* Skip first entry of first block */ + uchar blkidx = 0; + + while (b) { +#ifdef AUXMEM + copyaux(b->data, dirblkbuf, BLKSZ, FROMAUX); +#else + memcpy(dirblkbuf, b->data, BLKSZ); +#endif + for (entry = firstent; entry < ENTPERBLK; ++entry) { +printf("blk %u entry %u\n", blkidx, entry); + off = PTRSZ + entry * ENTSZ; + ent = (struct pd_dirent*)(dirblkbuf + off); + + if (ent->typ_len != 0) { + blks = ent->blksused[0] + 256U * ent->blksused[1]; + eof = ent->eof[0] + 256L * ent->eof[1] + 65536L * ent->eof[2]; + + fixcase(ent->name, namebuf, + ent->vers, ent->minvers, ent->typ_len & 0x0f); + + printf("%u %u - ", blkidx, entry); + fputs(namebuf,stdout); + printf(" %u %u\n", blks, eof); + + for (i = 0; i < NMLEN + 1; ++i) + filelist[idx].name[i] = '\0'; + //bzero(filelist[idx].name, NMLEN + 1); + for (i = 0; i < (ent->typ_len & 0x0f); ++i) + filelist[idx].name[i] = namebuf[i]; + filelist[idx].type = ent->type; + filelist[idx].blockidx = blkidx; + filelist[idx].entrynum = entry; + filelist[idx].blocks = blks; + filelist[idx].eof = eof; + + readdatetime(do_ctime ? ent->ctime : ent->mtime, &dt); + sprintf(filelist[idx].datetime, + "%04d-%02d-%02d %02d:%02d %s", + dt.year, dt.month, dt.day, dt.hour, dt.minute, + (dt.ispd25format ? "*" : " ")); + ++idx; + } + } + b = b->next; + ++blkidx; + firstent = 0; + } + numfiles = idx - 1; +} +#endif + + #ifdef SORT /* * Compare - filename sort in ascending order @@ -1510,7 +1597,7 @@ void sortlist(char s) { #ifndef SORT return; #else - for (i=0; inext; else @@ -1683,7 +1770,7 @@ void sortblocks(uint device) { uchar destblk = 1; uchar destentry = 2; /* Skip header on first block */ copyent(1, 1, 1, 1, device); /* Copy directory header */ - for(i=0; iblocknum, b); #ifdef AUXMEM - copyaux(i->sorteddata, dirblkbuf, BLKSZ, FROMAUX); - if (writediskblock(device, i->blocknum, dirblkbuf) == -1) { + copyaux(b->sorteddata, dirblkbuf, BLKSZ, FROMAUX); + if (writediskblock(device, b->blocknum, dirblkbuf) == -1) { #else - if (writediskblock(device, i->blocknum, i->sorteddata) == -1) { + if (writediskblock(device, b->blocknum, b->sorteddata) == -1) { #endif - err(NONFATAL, "Can't write block %u", i->blocknum); + err(NONFATAL, "Can't write block %u", b->blocknum); return 1; } - i = i->next; + b = b->next; } return 0; } @@ -1734,7 +1822,7 @@ void interactive(void) { doverbose = 1; - puts("S O R T D I R v0.56 alpha Use ^ to return to previous question"); + puts("S O R T D I R v0.57 alpha Use ^ to return to previous question"); q1: fputs("\nEnter path (e.g.: /H1) of starting directory> ", stdout); @@ -1853,6 +1941,7 @@ void processdir(uint device, uint blocknum) { uchar i, errs; flushall(); errs = readdir(device, blocknum); + //buildsorttable(); // if (doverbose) { // printlist(); // } @@ -1863,7 +1952,7 @@ void processdir(uint device, uint blocknum) { if (strlen(sortopts) > 0) { if (doverbose) fputs("Sorting: ", stdout); - for (i=0; icff*A9 zHMUTvQ-ZwINeOlle^t<*R)$tP%HjqR>r%Cqj%{7K$^U!KeQ%Z!;P=Nk@4b7^J@@SQ z+~qx2ONOf@=^Wc5}@z-HL|Hj!TDw~NA6Ew*q{ zXr6eaIFhXF70S~B)p??>#BalmT?{Ky9uZ=V(;l68vR7Xr{fZ=XX+vN% z5FGf*D&tQ7tPT*{V@B2N60=ME84@yhqu$h87mu82xddyuBs-drLkNJ!@CQ`V0O^#j zX`=n3G+`#GxF3oww>rBiZ1i&c?(MZ-qfcx z>$eVU#d=2x9AmxnAofF|HD1cn)QLTd_2mPV%t73Vs*~`TLz6E&o86;=jFix|$-0!N z#rpRHEhbWABO_UOR*An3h#6b5^6fy2Lg_U{YP{SL3%?)8N(3h@(^^&!Y9+E8Bydb*YT*#SDaWYHBr51_I()m%Wj@l-MzUe6eDYHsasTT;}_yxylQ<7T=Z$TYR5uy9Rt;p$2@Pi_%*i zc(66!Wz-OEr*iOOPMGhpLoVZc>=29Zb`p;j^5Xdxi=>~~WtapSOFC@{f~2p&@;eJv zdX!k}@Lw3S(m)3y?$@8KvZ4+I_|mb#jvk4E1?d6qJXXpVg*rg=_y9c+&W$Q<&m z)H;`6<;Q{an1V-s>MuQw5%~usnmk8v>Y4S*BGZOi@<|OmOjU%0u9mZtU9^&qHq?Yt zB_OOJ#!rm7F4{RX98+F3AHQOt){#|UBsuKIHbJ%Sz5sX>Ab zec&*Qp?9Q|$zfVCFmRYfDPRZr2Lg#H=R2K{I{COM1tNyVArKGHPU73L>e|#=*#A1} zM&+?okz*g z|1VVdJMz#INmlkyM>YkvcY`@X;5kLq6_dhP4m`VfAP>dKC^N1LY^N<DcSuifxZ) z8Js21Jjl#%{dpEpP-snkHAn}+gb;g#=IyH~zl#C%)0_J1u+q7de`b{h`I$N+q;U=V z>E8ajs8;1nsxJn#U_Y&?zXniHNm_wY<=_k6JY95eS3QuzTzPKNynQs|R;jchrUq`( zn)*;{cv(k`;QYjF&mDd_+ovUfzrRYRG9cEG-=1Ayq-=K8xr!yRW}Tn9iLYcqSq+n9 zW(3mdu4RosSH_ZDlQy9@^=+Nb{Da7{Q~qO=OY^W?kIe&h%C_-A*%GlMhX^H!`1`;Z zJ>7KqAn2jH`Op^+B!R&M)-PtW-K@5z9~dbCPJ6(Uy2^hewL;oClv?#RABNEbWdN8D zAry$m&WgZ1V;kqeR`Xtfu>@|^NR#S;G9I+dK>Wf8!yDMHyfng?Y}s7L5>YCUYj@M( z@G5)!*CR}w8+~G)NJS6%98x;>M&oxIGbT! zuSbRQ^th;@LAoj_1|lQ6DY?Zh*)_8c^JnUQaU0DX^5bU?T>je4pehnV@5KlJU z99o0Rh?_&}art|Gr~;Q?=PS)OGfGqT(hs7NRc$1C8g8M7`A#WL)&m}fzNfr)wZ>O# zd*~gsg)stq60lpnb5GIUZ9+voWyaCoISTY9QWjG0@Wg9ixCR0!AO&0*>1;Zj`w&wQ z=x7qCYR$!1qO~La*HLOqgPT8F%EM?!x!2ExEbMC*Cdoo5V6>)m8yPBrtOtz@ZNz2d zNM*uEvI&2WI+wD5Zf&t!Cgwua%GA?<@b_SMH8Kb(EPzq~+5J=ftU7yq9aDk2>kw|^ zm1_);j%7+z`W5AnQNJ>SY}BvR$IiwK4!#yqJ{;L%izF-VQK2j_lRYXVa2Yx(l#k2A zQK8AW+&wBZ50{mrLSbAgM*$dr#!~jM=qy#)Kgw8idC|OtB6T@|ITOmbsO<8hA6#Cv z{qiCyf+!V|yBjF1K(agtbiso;ns(v%%O2M?9;6#R>?=C3L)WTz5NzKH@n@$fTP=;X zyR5F(s&*K*M%2K3^LR$>&qNlL$=O7foaT-kt(1=r_SBntk)sE@=uKVe239dbOjxU$ zPTzrZ7Y+byFTC;qJlTew1_PzfXfBRok1}KVk~mNiNmhP5TKV$Ion79Sp+a2#4%wSs zwLDWs8rZt$hpvf_g_;GCU?4*pbR|~J-g)K9pJzgfT$8>2h9`C0;3&RCSKG$?Nf8nk@|^5`q%>s4Y+$ zZ$e}dgq82{z|OgP_86EEr=0sFy{a{XuqHKaB}0R7xCiG3CLM zFw-t0O70krCpVAfc=D?;98bbyIG%hlM&*E#GL{2M_puyM9AlK5$Ko$KfuO;$O0TZs z^fVisHRuPcL|&dh4}wJe?_vs_1{b38X7k!b(uE?UJE?N{5T$r*Vk5Q0=uB0ZTeq$< zYcR*WLJj7a#bb@vF|h0>ceWuMV|>2?aQ8u|v4sCqo`_Sl<~6kVpd29vNC^oTEiJJ| zS(9Il*Kw!L0G(D$ z#rbj>;kMkS>>_wUdm?cGa?WkW-{q)Ev4Gm9AP-jzg3TmYL|8MJ`a7B)h|yc^u8VUH z5aAieX)79KDeXXH8Ti{?|@oNXvMBW1Lvws_Hg%IyLo zQ5&QEnzM`eB%fw5#!1Q6aFZ>i!j#6_ZSsgjKPC>o|=Q}Wtlxyl4>g}du6+avFP=i_de#F3Hj$Om<*iAsSk0Q1*=n=ke?R((zce1fVJ}L?PNj z@kqJyK@`9W6qH^{>*yo^a48C4W&&~^5&r;kvWT1^6XMCi;HgSjPFT&M)PlVy3fqb> znZ?n-ZFOh%He#aHn;O-arMVb)p-wWUZjvaONt8KgYk1p4h{=Yy^)TJga_Y{B zymJ4iL|_gz%@Y%lGJ@wN0@(kH7KW32qW}Y|&JtAY0do4&L~|1|f!qW=SY!{J6qB4q z_6Y3kGTEc(24t(sB)(JjCqgsbt0!Gf_a+NNxrsq>O=8A@AV#U_2nf1Tz56F!foxSa z8fY2?W8jCjjp;9vN+oUbRkYh~vZdY2l}px%5FukWYzgZhSLyD7$Q>WpGIC)RHvwDqj%p3V$*)$yj{Z2Avpgv}$dQv1OOEZQaI07&yZ8+? zN|{3HRN7C$A8P}E9j@w6CQ+)y--@ajev_yzQ{w1oP1I9YAgW#x_0$yQDM=InTN5Sq zAGO~$ZT`#@HlEof;#LQlZ^HVnIicg(mwl>o%hc#>fh`M|(S&At=A4E#GL+UYZ6q?4 zPIP=Wh4v@0Gcs{%XgH*~cY0_lE<>k>rsHz|w9pJ(Hct=D#O0G|q1m|HFfB9(m)EC; z7UJ^Mw9s-~GNy-C;&SV>kQ0|V(?g`1m#6WvP-H5vQ8Z2sm80;XY09ss6QymX2Ma=MPgWTUHh#H%WgQwTpgh>FoB{1<4;ZGx(B;SzZuGtGmQvOKx6!~ zgD1EP771iRZO!Sey^5GeAqi~-VrGhQAm+#&6|}W8#~^CdF*A`sGuiRGHz>#=>aR?J zI9e8+oBVTz(qSf=@Z5ymo4otQ8Ag&^rixq^hS)!Wr*eJcx z8w|GCyctZ(InT^8mdkYwYwBxVX?kSj$U18}Ojn+N^W2GdEB!Mi7iVTgtt6g9+I$0h zc7HdVhl(YcrmZCpHSa)WTJYB=!b{}yu-vYe$T>+j%F%hkB8Liy4Vtiw*_=dC z19MyTGWg3iXX3-=31$~O?9eF)xvOif&a|ks%@&q<<_~AfN^8}LddFI{wWdUUn`b^~ zMIVoC?mA}7whUl(EQ*+r*c^${KzF;|I?Zr{vS zj^828@y0u1{z>x&iPuU7_ET6<<+3nmlL^%v{Ghw|;B&c;Q}|;bzbP}o`!NTn9+_=n~2Y?VdrJ zabI9720-JP#PQMSE~B(ONe6wTh}%nXdXLfMXr2L@u?+0)FHwyL(QH5^(h-FB;@T)I;hDccoJ@AfF6EpU*1iV{?q!W=Dj#{~nZ!1x5@ zf$A9nbsJqXBon&><`X$bbgUtxQ=3?otLR z#DTT1@*&B`=21szSbcw(gm8$3AW2PyBGyYqm}}gv6v19+DdPLPAXDjxpprKfyU&r& zo_x(Xg+*E5|1J(cj@%dr3BMZi+C)vugDEEUOXn!RzRNtTVs=nDM?QN-YlcfQFf-1Q zlF`A>Bm+!pEAgK4^EuVfQdJ7|#W@NnmSv`#&&+{Ynk(#Te9gO42(@LQAJ3J9 zES?9BcqN-dqkpz6E}19ZoG!;h&pd1-(Po4{1(Em_#6A)fSTsg(vDkm78R5lZ$Txm6 zi(^RUs+sxf!7KBWx2eMk39lYB&Er=O5cZB4bV42@ATMZ`=|qxziy-T6G~^WUbM(u6 zVmsrQabK)O%Q2)Kn`8(XakrwVcSoZ+hZ$Nag{ARQveJX_T`vkmAOnjO7`?J_8MlB( zlDcBgjk>qDZav(jd;3Hmgzm-Zioyldh9=?nRB$vmerS4x9Fj>5@IPyWGiU2S+*9{r z>U;4{(r>HN7qGCN^Qk=HJU1__$#Oni5IbAI@SuS#@}~L37;eTfhM@_^5LVIR-gJT> z&;ko|`Fyey@L_z-#!DE)t>tD~h2k`MJV0KX&IJdM?bgqi!GUuDG{FYNT;*r+h0>>{ z&sBpt)F5?%^56OLj1~Ga4_ndDE7MWdH6^z4*p*Zn#>u#ZgHx30b73ZE-LbD0ZkD8U zS-?j5BeJPf;$soQpk*31;|`lLd;xp?simIL`t6O5s+#JZV!5-*UA?QJ=HSk7YAEfn z-2sDkpK#Z?m3vkM@6*P9d9POG4&JYQxk#(p6?{OestGRk?S6KMTCt$PJ@)gIgS!r= zhLhZmlMWzljAV!})`?R~fgMre@lPKQCw=;aBRE<2jMK&1g~m8OJRv5RC`+}5y<9>zLf;04RXOXc`*;hojX>|M3BK%fi*-Ttm;I}vLZLDeD3#@vLzO(u9v6-Le z*A5G19v&=S_D%Z5Fm;xGahCpMf$qRWSe0QnCvVYfvc4^@+FSh? z$?fs#C+JdN{iI>*e5kJe1pb=qJw+P*I(+~B#c2CHU;Z!qs!KKT;)2F-`#|aox9E@U z#mh;KP)@jA^W*d@US1%6zd-qTA>Jfuzkj@bGV5Qc$P1@>$Lor<>}X zs7KO6{lo3NlXNsw*4z^i*yK%X#6$Dr-pP7sh{Ol!9l1wzS?HOfd#CCHcTdxIPuGEU zc(@mX#=*VIaMN_}bl*3>yh)wGh%el;dzKz3@D}O;-3u|jya30au7f%}1v-ZE*}9Uv zD6}$?f@Lp^6+w`d6c9m>nG_i6ovDj&797y>+dnf?kEHD`AjMz;`NTqMR1)q=T7~7o zKI-dgAga0=FppzBgV0QUW|AK1UO>k;Q+K3l9jECXrvr(RFXk^S#>7S<*%ZbOly`>y z8RTGW4G#*Hg*y;&g+wg%QW0)1{=5L49^g*5g3|lKxdlNW&tzQ2eLzScSpX>xZ4I}R z2BC^SlmP(yzHftWtb!M9C=J;V$9fiuP@&SPFt|<+cIzzsH01bOP)=t?%AxP4tSn( zdiLwV{d(l)eVg=sDBYwtZPvwa){^o7lG`cUiKqcL^K8<+s5!cnTQ!Ey0JP&~J)B{r zBNQlkg=W*g7D-5?^INHtkP?{}Dvn$qS{s=bS|1q{Dv$UceJ(?F=m;{)^s1dlYC^@~ zA^W!K7ae-I-^FFRt9LNIa(y_1YLZc7Bm*Z%Ahc5uX6=QcY4Sn~yLh67U0i0#%K~}1 zFS0JQ7`K}r2rZK(D`>yu^ZQ}kxAO`wn$QX_F018bO(d6Bd4Ih)v@tR;vmD6?4{p>$m%{0I3|)%!HnshlGh_>AUED-+VXcuWo?|70 zq&@W)w?N&vyI84{iR{!q)-6I`(rrToAfgX7<0MaNmzv zQo>!7VUDyGPxkAHLy@O5Jsx(GmXZ%3(Kl-2_=Rf`aBnu3pmcx=7R=gWJg0FL}1; zo=RQR76MOGrCxBvRaK91+g0^su~O?SxZ{pH8jEw&4;_7fyHZ%_z&en)tFZUO`u>M? zWwFz+AyOdskz4U zbBwt)p2M0ywYdg)LXBwBAct`B8yoaD*6WTK^bvvuRjq(MCAxQ`{#hjB;(8tDWiD>e ziNFGmv_&PwAZGk(%IHBsB-Kb#{!{31B}*lsh+=N|D+h@qFPsUlCWY7{9WZ#OnNN1l z4;bYU7YE4*79Ebb{Q0i-T+q1!6NyD)fCC*ZR-Nd2-%s>?rTV@yeP6l0uR?dtzW5V8 zSfN*G!E(K7M^l*|EY*>$$mCPZE`nOc3EG0haO~I3fU#bWZy>Jm11P>aUF5Nyn{c`!~HK4 z!cD6$V=`+gQHqg5r(vYZ8Y7Ots66X*hbKTu%ujX4>`PU=3qN&X0U~$5-5aNcS2#y7V;a-kInA;VyBRXG}6KZ=B7kH zT(v&e9vOn)wD5o<^>BS7C61E^D_d;7(w7Ice~1_ExsmTDFLwtV@~TR6hXor*4^}1w zq=$U(ygW?3R|`8|U!;W{4Q|i9TEi~SA}v^mDNe^FT4ZW)iH7I`%8=(YBD^?v66nys zpwYmF8iL;mc#1exyF5!YM4c+Pr%*%NaJuIK&9hi@7`B=^H~t(naoQbRtW|kZcZYlW z?I-Ho$5X>u|7>s{+yz+gVht_5OMJfn9o4Ro2w9>jqkMn(-^thYS_#^$qF%nu_Ug}sULirerJRj~qf3ww2OIRNzKpqDN?lF3fza@> z$vqY5AUH>BnyV>)^o@9RWZHbEKUJCUTm9~J>(o5NkPhe$zj+X^HOGCYG=<75Bcu@ z?TX&xiweM@Ypl~%<*H5kbbGNwv|B~qf!{5@cYoU#DE|H1mG8RHLpJCIZ%5%Gd#Cpcj~TGcerzlE8NlF{^%dJbJ$ZB`!Y_9 zOc_)R&zN}PCi^kpk`wFOL-}q}{x0Qh-{})##Jw6!>QHcz=G=L>!|V5BS>X5gX|-t) zEW|fDn(o!A-A#+M>Rr3<)nH)CBfkEjz8!8`)9i*x)!_F5-@H(dPCKcf5aXVkjAf^9 zYiP3lgzso5Cqoh|mis;p^#OBfC-3TjBCk6#y!uh`{RUsr$syhJwFh<_^j7aU_^9rM z^dDVY<)x~pPA*UpK^(<3_=n9Kzm4KT)(QMOE^7adbp;&q8@Zsqz^KJq2_G!Ow3T;r zQiN^&q2j8#`tbWCu08k>4=oFi;)wCI?meV8?8(iF_A-sVrnr$>Vdi!>okv{dmDA*1P8~%7n**iSJyV|dGb*$S48@F zpXSA={fB7gY=kK&X|?SN8fp=ri^E46Y7wC8@3;e4WzaNiz^J^m9Kp=^eZa0X)3Kc6 z>w+FFlKjTrV-6KVv8}VKs`iAtv#YV8RvA|m7w{vIJW6Wi52j--6 zd169gx$#InX4v?A1hGB#llp>&$3A%ycxd|(`}KScrBNC&hNrmlekes4-`%fgPsdg( z7Pe^e%V-)NXB#xAIEFTR-!Pm2gB_R5$oK?}=L1N*C zdys{?>*{5(@2l7Q7f@iJ#8g9yx}#WGGjWTRGBmp!Cjdx?@I8sAnP$~(Y!y=DCEw00ZT7kf1DYM{l z86nnn7)yO_&=dos=uI&;aEZ#vya-_^i9|b;-Y%^y5sS^p&70O%5GT;~L;wf%NgI)d zQ&EN-S(D%@ND!tulzTU`pt7Bh7r32IK!v>V%8gRXl#QE6bST4-V`hh!aeF!=Nm;Y} z=_>G>KETE)&tO?4jN=A~8ylCLq`Q!$7b82z>ZLpDkSm?F^4Id#h$r#jZDBEAa0l&H z39o@NUiEUskfG5U;cdK}0_z8dWMB{ju@PUuq?}tCWwtHSvTz!dUO;%nLArl9UXkl%e&m-zxw$?kXbO71sy%QHvG{n#~a4KA!8Hel#I;d|_@ z8>}z~$)THNi7N*`mo6m8oFNW3~r}FT7_|z=> z7ryUK^`(&)i|MHDdwL8#uta>0)01M$?f>X_B-yVuTA>A#Ze$`^^HH%6Z=WzNPAouKe9f;aN;s9g+C0~s=Pd~ zi`29$++4YGt{ZyG!vqNCvogFK9Mr%5&iM=ZcEOlo%?RL+bTDW6FP4ME@++> zCZVdvxWFCcFRR)~BpldzuqJG;IqCgG+x;oBaX7W-BhCAni?5b42N%C z*o1-s!B4cmv>@Sn{eo7T9=xD6wP@KJK0?fPZ}=EN+pry~tC7VBwf;`{1VM3ey%@QG zQrb_j8*+idI}oLR*#hvxX@;$;rfO&KBVf6p(f1vKA8Q+0v=enMxIzIHuJK%eJX?r? z;*WQRlU}W~LmL`8{lDWG!1RrYKlPb*?iON!j%&L2QNH#yQ3IgarrXEukY z8*j*)amdX4zk?$lbT{nsKBIerzVO@qv+_!jVSwJBFECOdEZvv|sgS^b?ilYLK~ z>*u@Y+;rc$bA5gPga7|~uE_U;^TN0Ed~e^E=X>=ka4uWvEESu|OGQq_Fi}>#v10v7 z%Hwh>eCZ$b_Jz;i=&L_}<6SdKOE;E^Jh6P)O5rRiFJ0p-8?k)-#ue*qi{{T>I2#Aa zrYdu%-6?WbidCf>H;9}~nYIPx8#irQQ?gntTUCxeaw>$Au#{!`CVbG#_reF=eF0oc zKghRN_`dw0NB61g*NIZlgUR-q_0E;U2z)}$R$uCc5tC-lp1)vWtdC{ovWJT0E7z2Y zl4Tp5V#AuU4a>?`6x%Wv6{EU*qu5lsafP$2Obj1B+*fd6a_+QcC4@8h0F7+yk%u8aLHR=v1Y|m+suun>+m!k zGQedL{^25W%5pOq+cw+coE1w1ek+z_+Jpeuk|~c3;LvIiqgXZqvqV|D)4?RHevzPnqT|*E~Paybo$MM=xFS=<=dzyQ_VU zk8aLCrg;zQlwGG|>BDvq8+7)uj{i-w+3bWM(`I|8f^PokXyj|Q@1>6htM_RQ+dt3n z+^;$OnOH~pbwH{dSr}JYzd{TnTp%ZafyUhqH{VfWxy( z^X^7gA2=3HX(&5bUgfIZ9_YZ|3lv@SVcU=6&v?nNSN%xeXAJk(Rz0piVQlbUsM@PP zCVqHonCrOj#;>neJ(`0j1s5?XFkDrm95_evFNxdnwEkoL89haJ>&A9I;DhrS4sp`j z@y9qOIyq=N7OQ=at`akye%j(imYx(!mFGZqoW>zh`K}%po8RGZoJKGF-I-ZQIJ%%z zoHp*^9sbyBeRQOO4w%~b{YBA1Tn9sRu1)^E@GXeI5&?%ma%x!uodavsPV?ggRf-r#;jn zK5S-v9fLH%nCs5s5X}{6efe@)-DfRYJ(tsJA*Ay;{5}Mxr+5JuYh}%@^nfkbg%cn? z`*+<`{(j}_XO+yiqr&0SVdh&9*86?RnIe`|qM&}CU*|(8*wpq(6 zPM|h{6gt2o53fvqJB}=istifhf8SQB-tnjNTo=X=6OixlXWg$%)dTPRe^4a_2LYub zjfqnArk}T%D<5m9D8zqiVAB--Ki*Lueixo21xcF5 zEF-FHs1>}+Z#NyFPnO*IE>8(>q+%8c&aEa*RP&hc!_WJe0wR3vOq!zneeg~j z*c^>Eli%$6J5Hd&(2%hj~`LpV*1$=7?9Y zQ#9@Q%Sbww{OEhE%II-xX3SLOuijSec7`Z&%6El*De@ zWT~5@o>!35p@iI&;h?zb{@S=!Y}Na-{aud9vG)epX>nL{4qW* zq0e@pfZzCtF#?}Az0hPO@fG=`3zi*xE043rD=x}B$&r`2ATaZGuK9uqeXPRbTykr@ z_rbKs-uqyYm>+wCbFVf{>{O9_gW}oFX>ZvvM`Wpdyh35y{>KW3=w60}nfoeY1^@4 z7mCG_Nl@Or7vhABl0&Lrs*vYm}R7%^9abnpvORQ4b zHYAoGs3MADwv873!6OykKm-lI1KIZPR$wjtn95YF!^=4&2Cyf|T8G!#xFCfJVvN|! zVB7JkjM_GnZQ3@-_&Hn*J;vKXlzFOXM_3@Rd#(GgONgTDs5>H)U?84#_=%(a`WWpb bl2*2jR=ZZhwqe7t?Gg4J-yHnLe*6CeC@WqF delta 23756 zcmbt+349b)ws$YtSRz3{Hjx`Jgs@0h)X2WdRxFyhi~?zthJX;1B!D_nO{x+@pxcBB z5Paybr-v|9K05=b?~QLn7#F0Or>|AqH(Z}SXZU(tM#nAhf6lGy?j#`dz7Jzp)xGDQ z{hoX7Qsq07;X9LY=<$?pnRhyl4$bYgrS&5R-8}ki%G7&DwQAz0P2zNMsIMu+rJfO$ z$3>PW`rRU+rveIc)QlTtK3poz^B2KZTBr;4=%w> zQB>?96i%U*uk5q#hf4nsm9^`Btn~j_*&P0%5`Qf}Rw~`H#a1u)Hyx-B{8;G`3q9b{ z0sI5Y(6)T#8AsF=SuA#!#N5i%Y^5+8)gy&j8g$^sDP|Tc!x#tABKFa82}?!N0mG7& zYP0Ep5Cp(wE(;)?0Ni*;)DywlyfajAq8Kv$W>8#7)U-D5XH?aO9HM!H)PSu*x*n{} zb2c~Toe_WDfclUl=o0B=Xb<^q+95~YKvcM8g)AqgYx4$5#HdVZUx`LjP@bAp&MHc? z3n1kxsi&dP6WFdyu#GB}$cNI+sBKB*;WqVF_1bv#?7?xVi8;vCt+}zSyprjdr40yt z1DYJk?(3hPdDK;!=RzF zrCJa!K%l=UzqRBeeEp)%&xj7t0-T$(*g(jAD4qN-?&iA^P(*}U)!NK(+hkI4FOYVC zbsV-J8`JFIc7je6AA+qXpXjbdzi)2jUT#@$P!74b zaxX67?wT?zCo%;Vn~)Q^8<%xCN_md?YRCr;!lSg7d`&doCUU(ZuYz&hEj?f*;czkz z_@BI5kMv|kCT5rbA=uC|rn)Cb>`ge;VV_uD8q9!Ah};ia%a5Aa^6HsZI7_P}^f?nk ztyva|8=AC}Cc2yswVJI;KpkQ$vJEMC1ME#5>5Nl`w_Zb(`-fOmNWVmugD(sfCyxs9 zZ4`u@GOk%5-(<>FOk(E&4^d%D?7XRBQ>8M3>}I zK|Xq3(WOFd(VKHEAykm#R;F7ttrY)~lk9B2Wflo1>xZrhy$>x@nseERkR-)c*pE_S zDC%Mla$Uux6~Qd2vMfm~;Vo*CyYv{^PG>zNbi!RShGXoMLfR^ms9?4w7|`l{)*}sV zVAp!0P+)lg#SyENLyH;*vf~Ogn-K>}s8dpK*c6f~+R#cWPohf7msFGL+tN>}Na7@o zx`C6TgOZsSal&bH@**x=rsPH3xcn+lDa*5!n`T)ulPvk`9A)RZYyKs+NHJE~bps!Na(HXoDPRq@tCH}SsT)dmdA>4AE%{0os8%OhX=pI62`+s-KrWrts zLTmh&gHdU)8`ZLJBjG~ygxv07EO-B5EccbeSnfr`l-0v*xor=&<*qq*4dm`vqjDq2 zT{Fy<`{B^N9py$#E3zcX{qe94a(^60lP%HE*hc7*q+#BTXk+vvMwxGmA-&=z8$m&Hmv1idmcsMkEk1r;&Z8|o5?$6R)Ah&cJ}2$cNx~riIge$Cus=b#E5QeI2t9%w zGW%S?j{b5S@mZ;5>M!m1e>si@!siBu0EuO>+f^?D3-$3NH=(Qr+yl0o=vH1`ms$r_ zdXKafH%^YFM8}F`oI1q=8O0SV+I6KadwitrEi{(_;$&}82|4)^HpDV*ZRkr+GDd$b^ zB@4!B5u1`Bf`iE!E>GY>F9i2iL2wvxl|m(Xvj68v$Z)IH;?Ub=Uqz$90;eF`r9ti9 z!Ujc^^5Dd4ZarkqR-B;{-O>AFmE@e~O&HDq0(4>i+QuDshR=V$tGB&q0 zvmTId-VxfWWapa$BtQy)#buZYhriM6PI^PWt%?DO&O=3t`rt%B{#}b?%I>@+4taT^ zJ2NB$exp%j>*a>szTZkqC4e&lw9favJRYFr)|9a)P@;pj*OF1<%9-N!IaOZU=sDIc;l z3)RyI8N5`i@k(v79q=&xEk(`!e{Fp54JCIB(rTc00liI~NwuX;Ib)nUciaKQO3_-)z<*5k5sjPejHV>*L<>wU_jbn8gmGBZb#n0a(eurK#k!~+n52hgZ3 z$O5x%i%L+gCk;c#$>m@;kb8Ar^m z{P);M7GzO3kBtaiw~vkF$W&YokBuzG<=L^3C@!y$1vLK5#oWW7xh8rQLCq%2bHX(}OG))8z%$0DhMI2Tg99u!xgT8`U2@nDUB)Kw)!uVjcz=;5*A z{gtY&RaX-1H5J0WQfyzvGn`;=SzoPHRho`w)WCmd@gz9d8JSOK&H%FH%yj2C<@C7l zKeU$bDdvU0(ptW@28L1MhBa2F=k!6|v%BzO0nn&@Oy^xbxRE-J%j4MN!q|ODJXsNQ zD?g7@7F_wiAVv-o?AqrpU!C(aYYIat3@A&&s!w_6g3Pm0v!D_TL`YpOAS$mm1xNl9 zkcj&#lBz5I3DDl;<2f`$Ux0eHXjmD{6*rfKGc@?_RaZ&tQ)gGES`T&~A0(PE|Gp{v zmv9ENtbh>Zd=)&%F$r^3nPVc$mNyvI<;`gOX53*~W;k+{`5;E9f4$0FBBw%G;++kW ztL{Qga@&icVasi4Adw)Hd&hl&Qf~_)iy-V2jYoFQb2nd2fe8)F$0WaY(r?d0+NIY# z{%pRQX%QL1#Q8O6x^`BYP7-l3<*t%3%P(WfwyQay)E96-xuk&ONqzyxlX(RkPgWFg zJlRyh@#Of`N__$TkN{fiUo@y!>D5&#DFW6PJ;_^Ioi7R zlzfr6y(xTNG+a4Z(5{i$ooX;0K4%T=k9pxat5yn33r`l9LF6QlQ;zCDIL7#X9^hwk zQDZCr9iBVe(KU3?TkxP z7@)DONVwUEJ!~WL`fvBRaeJct>{sYEXTR2D9FxDy!#i?KuP)Am%DI}oKHwA$UP>tK zyjZRjeeD4YuJJ5ua%e-rmBe_fdh!XkPK%u4n{pZ9Ub{y5f@lcZ$B4%%pVD%Tc~*|9 z6bq;^WqL{{Lf)BR5n`=i8qBnMAg6YMnWlQASK+@Y)|HEFgqoVpYxrpeQZRpUvp zmI<8mf-0y{S}*f*&V$owA)TizLE^;?pf*#MI1s`T2+*U%;{XyBxx7_^IEWa>*?k)D z(E4K{f8@;HS{$GqAtK@w8-xW>LYW=bJbx75t!~$dCO1@>)X453Bdz{twP?G1aNh)G z0(7kDgB?Na>4P*l0R=NT|4reps~ns_`nOC03w(pA5Nc)?Q-j~-V{Db?<3Usva#;Xb zxC~o=l&em5>VJ`CN$xW3rq!b++OsY>AhU00lW$v-F%8Nzysgn(%#&$KRBrKVa5l?e)|f0Dzceldwi|B)%3Wsy)7epDe64DD&g6JWsJkKbaL-4>st=IA}Y@ zWEMt?K{gpA4tPKp2U)@!k7_F7!*i3kOnHBjBr`&KY|;Z%`QaoiK%QHbay+uhacX=% za-cSLvZS_PG7(T$qQ`RwX-jVL(?VboANj~uli$FqGB+unamnyNAC z;k3wx4G12Fl}^)XOAwn8#nU5KK%0-xj7-NxnHiah%RMt9vvAotGjc61X)_~paTzxw zvJjWE(<4Q=9G?-n4VS!`krlYyG$Z20W&O;^N{W9U&ER#N?lX9i;m^|}+)^(R%O7fRjG$IXK$1G?;9*@Zzeer$1p>u6d7!Oat`Zv$uEl_N3 z(BTKWA9LEo^CsSIwRitg<0}Td-D(%}Y77?0FvChE2l%(S=jP|Nq(ed~f!PeX60V7p zT$nRjM{X8+prqxc@LxWyNy}Sg+zuDH-&;)H%fT()Q<7ubCG(Us^Q4DPoEKK(p(}0~ z3`TO<_VJ{!(xH}PANH-1V^7B}PSKBn>;qwd4`Oytt7&wbIfyJ(JX@Z1nA0za117W& znzV3n+6XrHSJ6d(n#;Xzd1<_}DI4d@er`=h;}ctZvQNGjbjdX|@(I|J^I8iq*${4J z)qG2-=0kFHA(^cf*e189{mM3rXgs)BaVO?hzM4m>2Lz2saW)ael%w-G$xK8feiU!s zCIygTO`cAAjd1vR+mxeVg$K*TrqiFMnRkXZV-z!=Z9B-BqhzR+N6^@zuit=UZ;U5J z^Sd>(1`?s6frgKla#b*`-e>xGcR`+ygh95HC02f3k!Ff4#4`DS^oK}_++n~r zow9p@`Fq(tI1^25w_&L19MXagxyBFQk>b$?gIUTgxZaht2hdK`1IY*waxt+TDI?CB z1y+^H8wl)}JOHPc5kpCIWizQPrDlPWsgMZv=En1+ABX=U4LRO@q=e(F1j#85mY8#; zA=0g$(bf+*E1{uz#Tf zhGmhZ=RYoleoB>R7A8)D`nzjp2DYFf%V(jx$$OJm~Lbgo_qA zHZfA%?Bp9DG8f1tYC7AX+_RW4b?&eqd(Yx<8jTcBFT&YlGEm!&09hsPJWRzg$aUh+ z7Aa$_=2?qPFE?k8bSHT_Nkq%UT;WWv_$TRjfM2&^9?;*q8xqS=d!g@3;2k!^))Q3f6V(y9IMV&yo|oJ1?woRLyC zwr4S&{1=FP$4ok0PH8%)UshV+l6l%cs3j+LPl7ayibHkDfcYHI@?|#}dYuj4SvnBe z1{7}QG>hAvIfm1_cgmm2qVr#RArC${ z`0|4m_))VTe$oOz#~)g?08Xov7lLJA7$w$Ka9(R}l5AOHEgMb_6OulU%Ru}OEr6}o z)AP@9XaYVt=K8qT+D^;sQnI|=nE-|-(cpwvU5^`D@G4{sZM;?8LTh?U2!cR8Ht0Rq zlV?E=Gn2<4!XOrwTiFzf)8wwcytcd(c9Xjwx?YA8&H>QGC5A0ho=Gm0-Ei2Va0 zC{&eRh4MHPXj$i)D2tVeDqEa#0C~bm+6+Uh9qr&5oSF<<1h+!#OotXdELj;*$Zo8Y zC#8}c>k*kPPa@y5JPr_o_TnNwC_F3l=yzwc_2^d~FcF@hw@jpC7U4;H%VfF%GkOgc;zW5-Q;qV;s-%aB zC3AwQPc%68_S9>#zAdS0sNN;+@mB4w-b0th>b<6;`@#CgllVK_=%1|7?-b*s$HqBJ zj6RQNtCKYGT48gvODOedPkmPd-c9mEa-y9M@1|ezR-yQ~Q2DV4;jzm@{q<8>-=kt= zG&Rs)kM)fV$IYdBEDJlXseu7{EIl$f+9`0Ej%Lc%8$tqGuxZVBIJ`SBP>&3g_@KB` zH;55MexV1l^&vY3={pANz4Cw z?Z_p=V9NOWB5G6`?L`KKgTXZ#>uaE@`Wgt2LpQl-rap3+9_u}a&O@eFrfQjk^vuCP zV&;oAMJ1TFNF;YgvH29ZT>lJuFgHhYBW2O9#M}g8mZ(%jy9jp?h(5_gH-pogqj__} zK;D^gnKuI=fn))sB(gc$Njiio{;LcKz>wu2FO~Tx>4C|5SaQ;le6+*W_KUW;F$hx_YMx7bl6_7veZMz_EZk0am2 zh5N04njV<02UUuT{waE3DxFxw?F>CIQ{Q*9zV8No-;Mgd`T9OZH)o*(Rc(kk5U$27 z5g#m3a+ieX>5-h+AViz@z0I*SF>WapF3?*RvXjr#MZPz7n!sOL2Eb1Uei)Jk|1Em> z7Gmn9WoD~?k*fO_>!<^ssMr5%J^X7uHhSM8eIH5}=`D+Oae56I4TNJ(_qzMJ&3Q}pPdvr~27fHswDqZw4=MvdtPUa&!^ zry->FT@slgFSK-vCtAA2WwyK&%FE5MJ0iE@cH1qH~2I^g+?0*4@*=EF{7mM}IlHcD;=r<My`z4@=x1J~>OD|Zy?`?VcKI@*z=T^7E9g}p&P)Z@h)b>Bs1 zCOWAvhx@AUGU%om97JyN^_Py;Q)12x-%K64)qjKTzfl(lmjF%6jryD;zN$tQ1GBGc zZ;5iyJ7?a!dCetx=?9Dvf9f(JWwF}_fOC~Krm{ImF z@dO7xu|%KS%8u}jhakohL`7+M8byKWhyqyPsPP9du-5n=(1NLlYmf)j2)_nBMBVC( zivHq!-ID-6Lcrjv9khRe9$2V<7RxwG&CV)1@i&LV>88>WFjKUOl6i0tOEq0e&!rxp zTN(jH6j-Bw^N>15MmwY1l0h7?u94wtG|hT+`hUeZkN7wg#&AsTh%cD$>%s+j6_`id zBqn-5smu$~`+WMo>-2rs>-!4zeMP!&?pdE6F4C*CaG_pR*>b%ezD}ntLY|k3<;Ae7 zI3qU;!>Vo-xL2wjOwEo%JfFp2Ali1kSQaUF)l$EzzwE31+)=kZ?9-zu{X|b0jldfD z$?$Uq0)+lYZqlE)POq=2$@&hx9BRB#Wtl0UUAy#%FIqq<%8!n0g~vE&pvgJv(Q+5tmx*cTFW#((m7pgnL#(f6y@2) zV$1SFJ@Zq=8+RP)j0m+(6VW@6CqG}P%qyJRItSRA@rs};mTvwdRH@9=Jb^FW{;%9~ zoBUt9J;HI!d)(-C{C4$zJy4^As(+gvsO6h#-4k+)It^)Z$l+;Ot3^{V9m!}GPkLh+ z=1>$XnHy?5;~x^79?gt!caeDlI$#Go8$dT5NiFqJ|&@UXk-OBMN!95$N#0pwW<~ z8iL;jcnVBa+x-(Y1gEN6{{#(fqv`%@H2-)F#;U2W#h-`fPdmcnwJLw=j%dH2^JIPP z@ziM6KbmR}YzJ&$yoQ#6iN?LpjO{dm7@4Rk^NoLdX6i*_SAaLWXsnU??2xo;2w=Q1 z`q^vKQ1O6&qH*7|eN+u`Gob58ve_KbPORT%<9lhg~8!z=tZtYOD+ zL_72BG}swtg}U&oaaY6Z#6bPe~lY2t9DfTJtAWK z=kt9!J+hVKo>FGSo*$Dkr3A%8PG08RXUsaewhPQ!OJ?1!{9ohAlVa4B8l2@|_$tl2 z?NHYj3NXq4kE^x1v{(v>*K(y+UE6Y%R=s`4l^R?}*==-*WRJUU_2F7LOAUUn(GJ&E z?Kp`a|H;%Hv95<}>*=X}hw>W&nt;KumR#dEh9@%BdB*rnBqsw*gIff+7b629-Py>3 zt|$uB#;&M-KwMI4%sw^jl6`CTR~`sdR~~pk4?z9DTT>OFs{2nBst6^UOKR{Bn=(NM z#f7Ys_;*~?eT9Vsoa~!d*f_uV>x0} z>w)|Ark#0Nv5}#SqX)EyYB0n77K_8_2!nNfk&I`c))(t$&Q`?_%lFsML98u7sNG-x z)Sa5YMh|S$&66B7553<~t5?@G?c7_c<%!t9K($UwPY>Nsb7nJ2K}oCYG^eQ!al0gX zq^S;pyK&w;V3ontbO59B=4}XO=6{5oN*x`ydE<`oS}o>&vEi7vFb#|%{73BCSNL`cLsmTrbaB!bs*SmakYERzfYc9c| zRLZ*1u0Qhq}&`+YwH_GT_@`sPFlCL;_Nc}gCu%U~6}cN9*`p(J;apRNG4sWR^oBXVH z4GO|N!el;%j3YG|wh$g+4~~&M_?+<_%54XNeIH6bc!);0^&P^pUM+Y^fY|{TV;aiI z>j+`QMH(NjavT?BRut#`YdfG5XcuCD1N=?vk)=~nh8$#F=ru?hZuKaocd?@Scz4gK z_3nXXdB2Vu4JcFYzmqhIvY80sgpF1wkbA^jS+j%bDoU)b!9FWrg0V{&$8e|{yOf;7 z`;f$!AbZD3Wo_0$UpgBry`nwhDLiW1SghB^!Mk0;>z#}jTSx5?Lx*O2gx4_F=oFBU zd<<$JF_H_Im9Lk@g*_K*S#D()y(6}3z1RTPeaRP9(`rw?&8jO>xdM-g`-?7!wc^F)AoqmQx~$9wZY<&UiRCZiF`?c&9`Z zOs#t8;q7|M4&8%MU`M0QDFyWo*(n>(*C`ioe58>&C3jdylMjoFO&G6F8uz{2!jK-YPQ}gT^E(1=A7dd-6Z|L(|=gn)ZbA5isGY6YV)Kzx+pl6ICKGSis-iN;u zsxqd$+CSxzQt@kJ*{id=V8q^CVo^Ty>L67n(d_qFU+4Z4eoSk5ToaG1Ah6VJ(X{dY zLs~Smsix1mLmF;t*B#dUhc)DGb6__V9mea_=ueMn<{^;9-Q$|6(UFBnQTUM7a#-`o zp8TX{{y_p9wE*r_Z=(Do{G`@$R1<@5JBVBdIepWP1OB*FLChC|ZYkJFgg0P7qy%~; zcjKH|V&N&xe~ekEsxhBp0{P3Uwh;^aw;ia7I%`e^p4E0dhin^t*Z;H@ct#uXoR*)O z`HZH1TR$8#YWVT!hthv|3%dN*LFj8Ja~Ll$EdFuzZzQl;3@) z*Vue!oN@HbHND4+oGUAY$SGJ`;kb77W-;{cQKflPgpv8dFm<8VyF!c}Q!wALVEu~K zD_470IEek#-ZICG4PH=R;kb7FhC76CEM8uAJ1$f350|11UN0^q*H)~)eVL<>un0%t z@;le!G83}ma%;}*O9f-Q+aUxvMoGoe&JJiaud`$1l;z7DBeP1^5XUd0nI9$e7cVFY`k9v>orS;MJYY*!5p9B9C`f)h?*K2`7&HpPcaEn&+L~E=6 zc6qr?+u=2~el&XY!&;z9r!+SmYZHzt?2$POJkO*#98PN9+2M#)(9QRrr}>({2^6!{ zf+pYR4*%6!)7H;3`~{jP*cs~`yF)sycZB*r?tAEjMqk-;9sSb%&>7r*`-tP%aV6S2 zy#83k8O<_>hCKc?THp?3*`Z_6l%}!+{F%X^UiB~fJ~J~| zSG8N;W3CInU)7-RGPIBTsB1M3r{`ypo}0d^u^#h4=zEFPQ?1{pZ`VK4R_oYQrqee# zJmC=^+I#UBFhs70c0RF4^1GE{nKwwgsmPsOkyLq1qVhCOVahjpxY+vsmgh7McJkL$ zX1j2%K&dzlS!nM)@$!%L0RrLRSNud*an^}IbJnFvkoHuK<)4gHt?voYQB9r%@R`kz z{`eA>JV?~=M+HAnMaIfA78%2ymKzd}jr8SwBy23tt3uwHfI@F=v6kec7c z!B;@=EdqL7aMP>i%`9I#c^r}#NP{isKd$ufoCk+fztvj4oH&*h!)EwvcHLi~ z_(YxYpP%+sZ{S^c`}+}O3C3Li8jiS}hu60{@>)wr(3sc#9eK48{uU0!ZyaEvh%XrM zIxNmF<@s&koQEHaS&LWjxL_x}BnHao74-^MK*j7cI2r1qG%I16u-DlA z{biPh2w^9Sskngey>SkHEVb`@Q^|P?UGJad=PSuiM|QeMw}q>KpUFS`B0tq{l1}Xp zpSIN;&$W_OnG^}Ad%=;=$E=W%Fn|?wSWfCWAslB)=GyUjmUjEDTT#BA$yA!HHj z+chiSZc9X5;b~)Gal**{%NRQQ`@mZ)qdX=HzF0ELmjC*;a`2sal(?W|neVhE`U{d> z@(xioyg&6)Sf*)h$(&QBP3_Qkl&RP_@zZD$D)@HdWv?u3EZ`_wKDn6nf-q>)5+Zud zw`%~1n8s62e$(3dE^0YKFOz4L?e~RgG*JrQm!KGx?K8oA4(*}4AUe-u@!r=N7Y2K4 z)LRrsx0eTyV0(1-%Lz2;X6KQ8H~FaDo%l>ELL$6`M^%R6;Q(K6J-UGei8n^E>Vl(g+Yh>RG+bPG(jzZ4 zL1EVIBI`vD`l5p^xs=v^yMlR7yj{U6vA$x4?!C%#u`i0{YYLA#JAdU&mpS@9k3Rar z)y}KOTT>FT!FyN5>J8p9N*9)ISXHr(ravP`3deY{dhJ^8s^x2KNGde``@=CQi^>zJ z{kUh06Gp@+*+u_3@Xt=|9Ss3zgFn3?kkP=YeRp}uYS_`E!KnOb#000q=_oc7Wc}AS z1PXVB`!&cczi?NFEPw45!hGYZ$$Wi8P0I2=F*wWr)R0;JywEP?OG9S)_t1GYndLX& zwtbebhgSOgGz9uKoFmKMyi)wG!OHTBg1b1&|5Gs7AKVUl^sXtp z_B0IGWmbo_i_x2ec85nyUL~60Nf@&~-Y7I2k>o7D=X&wybwRuhTgq;qD!!njIWo)t zz0q>W;9`d?MwWj%6hQl6p-b%CNLhYqs1DCz2BnG=l+$}!i7fy32D1D^h6L$ARoQ=< SKa=wD=}6_@5B%LZ{(k^<*ip&=