From ff11c49c39f3bcb1d36684b320b42ba581638d63 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 10 Feb 2026 05:52:19 -0600 Subject: [PATCH] optimize tokenize --- tokenize.cm | 90 ++++++++++++++++++++++++-------------------------- tokenize.mach | Bin 18908 -> 19226 bytes 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/tokenize.cm b/tokenize.cm index c49d9019..cfae5df2 100644 --- a/tokenize.cm +++ b/tokenize.cm @@ -1,11 +1,6 @@ var tokenize = function(src, filename) { var len = length(src) - var cp = [] - var _i = 0 - while (_i < len) { - push(cp, codepoint(src[_i])) - _i = _i + 1 - } + var cp = array(array(src), codepoint) var pos = 0 var row = 0 @@ -148,46 +143,45 @@ var tokenize = function(src, filename) { } var substr = function(start, end) { - var s = "" - var i = start - while (i < end) { - s = s + character(cp[i]) - i = i + 1 - } - return s + return text(src, start, end) } var read_string = function(quote_cp) { var start = pos var start_row = row var start_col = col - var value = "" + var parts = [] + var run_start = 0 var esc = 0 adv() // skip opening quote + run_start = pos while (pos < len && pk() != quote_cp) { if (pk() == CP_BSLASH) { + if (pos > run_start) push(parts, text(src, run_start, pos)) adv() esc = adv() - if (esc == CP_n) { value = value + "\n" } - else if (esc == CP_t) { value = value + "\t" } - else if (esc == CP_r) { value = value + "\r" } - else if (esc == CP_BSLASH) { value = value + "\\" } - else if (esc == CP_SQUOTE) { value = value + "'" } - else if (esc == CP_DQUOTE) { value = value + "\"" } - else if (esc == CP_0) { value = value + character(0) } - else if (esc == CP_BACKTICK) { value = value + "`" } - else if (esc == CP_u) { value = value + read_unicode_escape() } - else { value = value + character(esc) } + if (esc == CP_n) { push(parts, "\n") } + else if (esc == CP_t) { push(parts, "\t") } + else if (esc == CP_r) { push(parts, "\r") } + else if (esc == CP_BSLASH) { push(parts, "\\") } + else if (esc == CP_SQUOTE) { push(parts, "'") } + else if (esc == CP_DQUOTE) { push(parts, "\"") } + else if (esc == CP_0) { push(parts, character(0)) } + else if (esc == CP_BACKTICK) { push(parts, "`") } + else if (esc == CP_u) { push(parts, read_unicode_escape()) } + else { push(parts, character(esc)) } + run_start = pos } else { - value = value + character(adv()) + adv() } } + if (pos > run_start) push(parts, text(src, run_start, pos)) if (pos < len) adv() // skip closing quote push(tokens, { kind: "text", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, - value: value + value: text(parts) }) } @@ -195,49 +189,54 @@ var tokenize = function(src, filename) { var start = pos var start_row = row var start_col = col - var value = "" + var parts = [] + var run_start = 0 var depth = 0 var tc = 0 var q = 0 + var interp_start = 0 adv() // skip opening backtick + run_start = pos while (pos < len && pk() != CP_BACKTICK) { if (pk() == CP_BSLASH && pos + 1 < len) { - value = value + character(adv()) - value = value + character(adv()) + if (pos > run_start) push(parts, text(src, run_start, pos)) + push(parts, text(src, pos, pos + 2)) + adv(); adv() + run_start = pos } else if (pk() == CP_DOLLAR && pos + 1 < len && pk_at(1) == CP_LBRACE) { - value = value + character(adv()) // $ - value = value + character(adv()) // { + if (pos > run_start) push(parts, text(src, run_start, pos)) + interp_start = pos + adv(); adv() // $ { depth = 1 while (pos < len && depth > 0) { tc = pk() - if (tc == CP_LBRACE) { depth = depth + 1; value = value + character(adv()) } + if (tc == CP_LBRACE) { depth = depth + 1; adv() } else if (tc == CP_RBRACE) { depth = depth - 1 - if (depth > 0) { value = value + character(adv()) } - else { value = value + character(adv()) } + adv() } else if (tc == CP_SQUOTE || tc == CP_DQUOTE || tc == CP_BACKTICK) { q = adv() - value = value + character(q) while (pos < len && pk() != q) { - if (pk() == CP_BSLASH && pos + 1 < len) { - value = value + character(adv()) - } - value = value + character(adv()) + if (pk() == CP_BSLASH && pos + 1 < len) adv() + adv() } - if (pos < len) { value = value + character(adv()) } - } else { value = value + character(adv()) } + if (pos < len) adv() + } else { adv() } } + push(parts, text(src, interp_start, pos)) + run_start = pos } else { - value = value + character(adv()) + adv() } } + if (pos > run_start) push(parts, text(src, run_start, pos)) if (pos < len) adv() // skip closing backtick push(tokens, { kind: "text", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, - value: value + value: text(parts) }) } @@ -344,14 +343,13 @@ var tokenize = function(src, filename) { var start = pos var start_row = row var start_col = col - var val = "" var i = 0 - while (i < count) { val = val + character(adv()); i = i + 1 } + while (i < count) { adv(); i = i + 1 } push(tokens, { kind: "name", at: start, from_row: start_row, from_column: start_col, to_row: row, to_column: col, - value: val + value: text(src, start, pos) }) } diff --git a/tokenize.mach b/tokenize.mach index 7e12ea6266a39761b4ffa8fadcdfe0da297a12df..a8d0e522f416652f3b9e516d2bb0bb72fb416d05 100644 GIT binary patch literal 19226 zcmche3zS?%na8X8-97I|(&@~kZ+Fk6r_(b%ok=E1&!qDtAOZn~up-JMF-#z9GQ&40kgsy#DWFPq$_b>H+%AVm7)fkTtpn7v~EA#F?@K5)RK%p9K7?d{v63aOT_zGD9Y zW4&r-a?h)^V>6Sphi9g=dD-NF$=S(3l#-Y2KQwdr%2|3T#JAE3 zPf>HiE2Z+3GglrybcObAa(bUmc=i6N%XBaHxHZj8AG~yC`szTFs#bm3JAL5rLDTx| zw9Zm-!E`fp`#3$d=isFFQJ#IU;+azSmW+BJ72$|m|WO%!f z&8G@kJWa^ZIYM^4T*w`-5b}&y3VF^&LUvv(WbzUrPrFpef!#u`*(2mjUM1wtNg&z%vnJS*g;!$PjQM#!_T6>`~Yg-jh0vgbM>qt}a48$p=}iga6WLQI6v z5E@3qXatR*Q8bFi&=?v=<7fg+piO8K+Ke`%EockcingL{XdBv&wxbGx1ERbkD9V|TC|AOwyfPxnE25%&YD|>laZz5K5arP( zQGRK&D37&>@|mro+|?$^eeI$g>=5PNPEjs(iH?a#xiqPs<&pHRo>+QUuan-j0!=$=T$C6G=?N#0p2+0V6WO6bzN;%eAX=ci zMo=^}8+5`lA8BkunDP;bLX25L(Inb9s*RL((aN!Hq64c7tBZf#{A(9Wu$GaYf*x{u zNn3%YIl_SqWTBsUQuzxSxHGhy{VR=CY#S2U#FOc_wT;|e; zu7Mpe0edvZWI`O1OJD%j*63z@sgIgC?Z>}zs5CWA_6KC7KPc1PG7v1tfROUoF|`tr zK16!NA>FP_=W%Y%qfZ{a*u7#GG1)~-{HXfX>ZR5N`#vOk0m!9b`G#D^e0 zuq=@_pldOUG2mk#CH|X{rKaN#`Yk4(fYd!#;@=|#Uk2f21U9Bj)lwq+x>DqEGM+3dZtA1Pj{W$rTQ%kadUJWjo|!#+XD4Seq)3ugZ)7MWI`mac1VhX$ zVVUj-hQftlM19ZnN96WmgbhnLB8nk)Pr;BV1e-XH)r?3|rb3y`{xT6649TFnDg(j% z&scex4Z>Wd#h{dSX1Iot^BQ`5EhE}vDR!@qKJ4PWyp|QikVf-!I6}Ra>xtI&tUP{H zq!zmxTPV{olFnY>s@UPbDqc_DJREGxFt%kQwuklSc%xs>{z19I#xl&PA7EdNj~o1H zc7)zQzi(jnt*3|Y{c|{x_SGClTMg~&S?V-3>khCBCx5xJtq*U-hqvNGJsG}R)?<5| zh##HCk5m19cH5rghnqg`^RL_Q-%a>;6aLkc;k#u$w&iqe%Z1n;%5N^G<6nhp>Ytsw zW>#IQ>Z0J{;lkq9B*N`TFj%`dZpNvb8NfF)Xm4hl;)g@^z*W0?`|)4y9VB`;U$(`7 z8tV!De_a3HqW`~0|39Gr&(%*7I&Jq!x@%LT`l>w#4o`jrgCP=O%7`)5IK#Le4#b4S zQAt?(V@xG{)l*TNatWrRSUgdPF+IhZint$ZkHuvnHeLHpnRD87nafpLq$?H=6=HFb zRdvS$BHJWIe>0J8;ZkXpkz!L&h7(Pq7z@Z+dv3eoXiU|ywk;No7h>UB9mGzT&!2^l zaao?5A2j(pbpE+>^Ft=Ts`K%;vHq~hAJzF==H@f~;%}Z^0PSbz=0{C_zs_$r`LUY+ z*(QR@^;>Kr4sPG`DP4A8Ze4Lx7ek4*Hktfrt*-tixw6O#P^*XY=EXWD!p->NYe${S zyjp1880T+1c8q#o+b0nQ;3FB)looH=B zophqDNsWbYGv^Zj(uwva6;nbg-ow>)3)8@@@YmRi_hP?~4eI;Z5-UDH+HG8!w=unY zq_7oP&EK$TG<2bc53(WrAhscm_CXQKFbZ4hxSdVA;zP7;`7pPI9=+IEDAc$EA3UBja>^ziee3X2TJoX^0sqr!LJ@VLtu%^bx$@j=(55k%npCI2Oi=BrOY?#9* zDeF) zZQAX}Khvu{-8?hBn)3hj=WJnW(KGhE07jLnr6<`$MaUi0V-H`L56)s>iF z_9jcu@J-C#&CK43rshI|nYW4An^}Xjfp(pCyFcxmHl4;6y_s9O7B-Jf%`M*XD^%G? z7gu&6!OX6F;7ZO?ju~Bs+gKginb}*I*_&HLk(I8oOn)2xbWnF^Kt$R*I{js9e*65- zUqgR9pO+usKm2ZzTV*qwTxJ&hUS`TqzG%Oh+0?3M;^-<~>w3I+aLdhZuqzR1DkQe4 zxNlc+562U#9Bs!*5Azt4I7T7~TVH;i?o*FHKkCmf>HIA!e}EN_y0Sidz#NyWo#${= zx92<0oCh~%oa1OA(O&zG?~9yc+H2@{{^zU|b>qk@qgNESeExoJGUkj4R`P~1p~hw1 zaW6CVznF2gkUy$@@^U3sS;4qWHwRkM&A~vrITTJeheQ1>tVGR`7Su^MM_bg`4Yx90 zT3CsiV=ZdTs+H*PnI*o!%=94q1GeIe*k3}w%uMkRGs-{mxaup+GK#N~{xGZ3!^}1w zDQrcy#y_z#8M;tQ20QOkL=9h~jjvJ0kVgBU2xSQ&ZpQD`bqxkOUY4Q|5rL5%{>}P1tupD(D4}-88HrDYA%Kw7$9^Kg8;#tQ1 zv#hYsGG=~BJPj%F9R5E?EdGsS3=ZmuU*YSoh)pA0Zu-NeTl@G|Se34B>U_(rdUZE- z_~5H1&Fi+4xX}KNn)Pi@fQ42{hnEP#K7Hwr%J#N!Bw7eJskE&!%ES?2p^3^>Dt#c# z0#u*gVahKP+-7YqvKG`d!U7XzVfO0Fu;^@8w_WP?N7bvI_6&qswB4salt0bX#{}=z zmw)cqvHaa9g@G)%a?5Wjh>!w|wkG$vb{Lpb|@NJ!`e-VFwfxkDLkiUfm{0$j@ zmoDOOogeMpI?i=zBb_?U7t3Ga+ojq!U%&Oa-td1tH}x^BYk$!6V~N*~x_F<=cH{nY zw{xEJ)NFjoEZ|Gs@lEp_-*1j*V_?U5U0-;L8IkkGun_je|KHgNgym>BLY$&(B*VNL z4s!d?!x@gxmDu2lSU{ws!B{#P3ZQW2)Z<(C_g9-6J;de|>zh`nYbfA{y*cq2RY8l2Jbs0wuf8cqOp%rZv|E1|hExp)% z3ot~wV${bDY>z*(*cq0gmMr#wO9{2C!`|q!4K@5XJ{nrlR`G(S8@2ReEBbv5VJk*` zRIwGjPpff0w#WbAuVEQ#$zl(a< z#~8LpfO-Pd;n9n|ash@(SFHDO8nz+G?mx&oNe|vX^WHHiGc`goE)-$jNrriE>5;}B zSb)`}D=I!t$2LT1H%hx6DQrd7$0}^aNR1eNDB`jOx_tCtEBbs4V=LDC*oM7LBZ`a!h^;;h`tualdJ0j6oA;Pp6m8*Gj zrk|*Wd0JYGvg}8qq7Y$PbYJM?)wCF4T4cMyv5{g#O^bR;ZF9nrp!#J{dn6n!L|Q~v z-J?dCD%n7#V}Wp*w?pX|Q)Mh1pq*Gc7Kx)ynkS#Co;+8T{}>UEspI0uJ1!lI2i37^ zI!$t#mhl=r1SSs^{6D`ZuGen8mnLjUeAfrf&0*XrH?wYBg!T z1zBx~m}6^;`n-#Kmug49o@C^0G;Pn>2)jO!ZtJicShc~n_A@7M17H{Y)tuQ8M&}w> z%b6c#0vy$<>?JkUF>=>2Iy`!?6@5O2uoa^|He!2hV5AxNK@W9SG~K9Sj7iS01hr(a z^DaZEVVnum(1~`6jeOsP|CX(M-%9#cCREEdCe&?QHQPwvPFsdvaSCxbg$Z>BeK$C$ zBTmIXiyGbPPK$?HwU2+Kt6{Cjv;IlpNg3G7s8TFKS6y+s3 z6CV%IqWM4YfC(R%1al>>#&n#$T|5v>$AjT?JQU)=RV*D3s|RgPIvzIL zFLg)>xm`0@-|hS#aMz7sP+thIAcU_Z z+=djYDAc$J=Pn}L7ZL7@DQifHOQ_=#LVhVBH#n#xb~9RcGiUE+o3&eiS7{zL{0oiX z3I!UTC8$9?HF@=c{Zr;AyMOw_1oM`+He>5EbLh%FdnfhpW6PWLOWm^mNp7*YNhcPI zMogahveJB6sdENRxxqnw@SsjBnY2<#rm5;B86>TZ_Unen^VbS$9E3sabF*0={7!bY&14t?!9dq zbtpf5n^Cp|_{?UMHtc4UNxMFt{7!k1coIvgHj%zqZt?k^HNNW!>!sl+_whUr^OYSi z`Fcw;rhfHQ%i}qNEniT5iO4hS@}qLl9LsMLqdb#{%dP4KO_8;vegi(wu@M<>sJpA7 z?o&+NB~|xUe)*_3^u&pD6+|~f`O9~k z@;ZLKl5i;Ab6$7(Th(`}rI&%E;(KNG88Z?@`Knz9XXcJM`&Z=A<6q&LL>q|Ke#xpnJn zJ4d=YUp`;z=Z+INw|&$xXD+1AYF${jz`5m7Lw(;GV#METHO4~wyK*sq-ScJFz5HV3 zPoRGT^YxG8RR0#5YwdWcjiZKk=9>#@WgB8qSRfXw=Jrj;h`(){dp^!G{@U?fn|DY* z+4IQY0{#xo^|yYkHT0Xm&HIzbCV$&EHx{V{VnO=Jjs<^LIPW;-Zw-&%w}x2ocZtU@ z-!Q(^HSOE~>T$7VzE~tpEbMr#jf;l%*Pev-N9Sw*4AXwHah~Wj=i)`Ksk)!*=4&Tv z+UaO)=LF)mer|oVlZ|bty)RVn-y6r7dayCc0}9JN9#CA)1CA?TKMyJXoCgygDeROu zK$_(sWe&;=jEE^75h|uN&1g6Dx(uRKI3F%|xf)fxp~jWet(fs~h&B$<#v$66rEbMx z9uXeKSC3`bij0o|>;Z8V<*(u)`BnIH75*3o(JGt|m%ChzD&A1zYWz^VrVfYihHLTd zTH3r8-(E|Z*V2YZFSerJ$7*av#m6>m!x7HK5$ZU?BU;OK_CB{ z>2erVyiRjH{wV&kjtt)|CG0Vm9q116I?8(RH;huTPV;&m(Y~GsS{}==75vo+yn$mq zmSJaMU;$Kl#SYCIsr!x8<&nl#tkJxQx-Br zydjBNGS~$eb{Rv*#9Ju;7Rnovs3nJ8a;cydaUW8!AY-%NQ!61C*8OD+|(BHl$T-bF0lMJx;s>WFs}3(I?` z?>*FKNTQYub^(T6#?Ucw3*~R2ydjBNa@Zx83R)4j(*CWqe=F@99Mlo-rG3l$sPBE$ zXGo%!40ZvAUB=Kc@qWs`pYnzzYRO?2VYSOfbffqHs3Sgzzn0sn?{?}lBvDHSy8y#3W9XRp5amBac|#Jl^kEOeh)Wf%iVsu%!<089 zQA-ZH;-mO$`55(mjQR{o)RMvGr~aBD)UpA4yUR{=r}#K^ ze4IKANz{_TF2JzM7&<0CLHSQm-jGBMpX8ePB-f0AKLg;JG4!KlmvMAle2TK4qO5^G z381VYhZbSPrHWR?om^jc(&nACWyqm9@o9YdH0g#UYEgM5mkL@DcM;FKi056z)8L?v z_&efhxtsd#ranUwwPdjQa{|o}YT1Cj-DM}bQ`|!x_fUr+iCQw)1sHZ2L&wCul)snq zh9qkE3^Do)F*2l3!+rGOKK2iW9@LV@9&xFnRq4qd~QF$eo3R)2la&8}_uMcu=4G!vvFLG`zU!uM*QJ*1+8orFbU&dcU z3bo|0i!kC+MXTZ={C$Xe9^!aI4$XmE@SAJ_$uYUN_j&PwdAl% zE)}#Q9;SZ})4zx5pTR*L@iqEqd4&2Np*}+rHGG}^eVzUpQmCaLyX-QKj*D+l_8XKn zq)c$e`vh%1L0g6#niJo}m+z8pNTQYu zb^(T6#?UeGJ<5NN@`fa8$zhjVDriMKNi3cu7EcljgM&Ka2gJhiL+bk>^%;_=;YalE zNA%B-LM{E+WtVYuT>O}_Kc=i9g<5jhMHq3ZqE+z}v3QC$pQ0^84$X<5;LA@)HzZL@ z2D<>mE@SAJI7<1Wls6<%OAebKmTM|#MLbO`o+cJg6AOcbI^w6q!tyif`x*5alBgwv zU4UViF?3A)obo@XydjBNa@Zx83R)4*(Ec;D{|xOL_z^qpKTG?TUsB&Msn3u^EqUxA zmo=zm6ZYvYyU<2s1!TT;qHpp=FpC|D>ZrInIkNhoRo z6&D|TR#bFVc2#_#D6*o6!Xh7Cl~oi(e4(NuA8=I^c2#uM-OYZ_Irq%HGnpi1>F#_! z-~9e_?z!ju&;Oiz&bjwagb*SC_7lUHoVa9c{J^WmR9X;d<;}=iv4}>r;o4R~|Adazj;-az3CJu~G22}M2_8A%1a?ymAizfoA z`YZMv(t6R@KCSyE4(X!C4qiT{jmiB7F4xBR)WL%$<Btzo|g2Fq)O=sQ%;(45(yz27Yey3F64{4g>3H; zvL`L%(q174RtUL0Bjj;eA&t{p?iTW-^M%Y_ zAmo}oLY{n~kf)Ccxp<$DYsZDmO$fR3kdVbmAvaG6x$;UOcf3l-C9f8;Tu{$J+Lt#-|5fQ~@ zQBgcGCW`U6D6UF~;<^S=JY|6>4lfkN(;7vwtw|J@H;ZDhMHIVQMX}Jv7>F7;gbq01aKJ_?Md)MzS@8g3LAQnP;w!m>P0$bsD*aj!SiJX5DKAnudh%!!t?IP~dhANi1 zWYMfRoj4g5ql&a<2az#!po*-^I&_^lgQyw0P({CHCs8yws3S)4%di|(3~A29PsNKV z=Un2mhx0DQ-&YXJDbkPN=XHF4GrWb!znyse9mj4aCjX562Q(?$#45R1oFZGq*|J^i z!~TnG*8Ek5g=Ja>#WWMlG{>gp5|`!ZYS;!lVUI>KvC6}>kxY}(|}h2162AtvV#6F;g> zwbrR+#D415PaTm!Q1*uKAs7hdg7^@`2Nnp@`ki1Xplo$5oktz#5yzL|gGU#3m)MOD zyE$&Lbip z}7oJWt>#MXME{-zdwh#c03$x%K)}zBevxf zY|Gi$9@hW4`aeC3|2cLiDsE9XR`uGFQ*8{%HPIkFA7bui%&54McSif%yqVg(Y7E)F zxPtNE(TQ#8$2J@$k4GoAr5{_droxrv_2|U5^kXa5RCp!h$)e(>K5FdPkN>(=W6tbF z_wPBhXYb_Lp>9$n$*MIn6cR1^Dkg#B5lQk4k!OoPPecYoGN`V~Krr*Ktjf#=VXo4AP)a*9T*b(_nigNfi1t{F z-Q{CBcD^pJVZ|_{(98^8OSzV7iPp8OJbqN9=DQjflBZ@Q?U?1NIKh8ayn(iPIM|i} zY|BP$59`ldqhHVdLAlJvGR&yYvLDCCl0VIk(CcaU^~}E2bn?A-21irBn!~88rhYw3 zoup>nEW3A(FIBen;RbxT0UxUA=DTG*w#U)<(Q5oS(cfmb?iqf#=^K6iwfp_M5&v$) zziPVqZds3QIT_pX5^N9UHvXDli zp?p}%NH7?dq(wrZaORI@p;e2)yI5%64ew#GQryI1dJ~t$O7@rvdY?|G9$QYx zq_5EF$9d`8Q>gN}N2UB8FFj(?J9K)pNe_#jC=I3G@==C}I%+ykVwTB1XA&Zp;Wvv*qe~CRJhTAC1V-VZ$Nzy$Au?@GA z?y(-*@Qtj9Kdigb_l*oHeu_ZY<9SjDF~?oq-ve1>$7L2QpZnYHd@#q@I*`S0Ss zs2+C{qq~WbM>}@AxQDpk!+qO5#QmR`VhkPPUi#)l6s#AZv+ z+=wq;olEB~pL*kRL?+l?#ijCbiOGNDdDp9Mh^pJpjU5+rTPzgM#V%Iy(UWL68dLeG zCrUbjp?$1Pv$uyQr{wQ6`P+2g_2$HSFA;2d9HvrxEkr=P>Q*pkY3;yO=1M`rbNR{tMoGOenA_A=&-!`r8) z=RAIDZ9T-w9qTqQA-xP;4+9>O4yrSwxNcHDgR;0ujSjMf1C7L9w8RrVNdoQ zZaX|yU>m;6G0XRepT}x!#R;&ZF5jmOmLKpCOYtavcnn~d>heRj{y*dvq#i$}T#o{_ zyFCb+${cvjK7QL@wdv4=5`(Dsv-ozt_RZIB-Pfi6ZQoSKu&Vw((~d=6JF4P+EbHa&#Ou4$>-5tC<4gA}zEqvx zQ0M$!b3Th}-SN%yw1})5!(7-G|KG7#hvm9(gg8ZIBp(j&%#FJ}^-v(f-IaRG$D*Bz z24g99QK@J+kcvjs9WURbG1N&#W7zSaTHM3&px*4HqJfwyOWkcf$At7p7M(xAe=sTi znF-C%f?Aehce`Xz%K-LTmtoZK7oI;F8qr4aS4}%=>B3$<3;m=k*813n?eU*1n1&^& zr3X9fQa~;1us6Dlpoag#M?)jpDE?d1j#|2~6}>+Cu@!55l(7}teC)#Zn8sfNZ-emH z(1T`O3aDir_C}Wx)L`yR)ZGb>i9l-FQA;PbV!03AR7(YKmMZXuT6zR2CrB9{UDzvT zVSseSdLJiZ8$z-{gk+14CD@AY3SoBoiU@DVB66{h6n1tNR*|kK`8XNd5To80^?Gz* zD|&pa#8wPeh~tMMAs0fMk4|jGavuZOiuFE5ut!7#ZE2t_9?P&Zvrr)2(1_oSvK2Zi zG;#OYBon|pVf-?5iWb_}g8!|Ox5XLZ~b{58ws_ec;UMTRf_&G zM`ar^M2f!ORuAda{WjYO-ofZ;jcF>?5{brg5vIkcTxIXO?87EjC6S9TExNB3GHP0k zFfFp(;M_<)qNYVXr8YU?NKpNxr8yFg<|5p0N5~Ups$>I|iUq4fO=x7 zSR{@*Dee_jIT@}l|2ZPg4felRGmCMn8bQ8|Ox5Ni(L8fQ)M(Ot3$oe}byA;Q)U8&P+otN#FUlBsWmETz zjj-zz>9!14Girlv?Oz?c4S-$n2kF_>jLtQ%mY!e71h`JCvKLiY&&XZR=tABrX4j5Gszhip_Xp!j7vXi*vN!wXhmB^neUtN-!j7Y5zN0eRZNy<46Y2@H-Qb{(I1&FWYILhRE%lhve*7a{4QoA~D=#=+ z@Z7nCB6%pO-o3^c){c6U(GraWa#4ng`*dC1XYtT5n)x&DQ}KaGP(Nu;@z5_74+K;3 zU^o>Ig?LcKQ}(d?ls%HLPuNeT>8BCu?Ql9F*}=ta;FmXqZimcOID_z=LHN!fd^^dz zlgVY2^G6BYnS{>ZpdKnz>P69PVLPg)zIy#Q#&ZR4Q_QO(H@IpQas$k(pg6BOSS@N_ zbp(UaO2D5}0oPB=+*cbsC5wl6eZj^%9wF#aH|Q}p=y8rEf;RBy5V)5R^q0c91n)co z`Z9uVSb-Mnu!S_kZaQN(ow1wFIG=M39pVDYy?_qcLzxB#b;N~?WsB+*^_i_xN*t?s zs-TAV_}Jlt2gc2>PG9ig)~^H;YTY-l?zDCJWqbCH>EC)5H|Y#T{qxd%ev?kj=Z%680(TEV0h3OcQz)5@E4xn)$fvs~84%KFRZP5Lt4ycvTrAuwDu znfa;)v`O5w$s}4a$IOX6Zeow|ut%4Y$(R!|8C@CQRACu??8p&w?8p&)jBo0g`Lf%5 z*{ze#)qk(9e#iO&wOF`|joJd~UvUs#^(sSMf-*Wi-4qG36$*$DGf5vXizG}MPYl%W zq}+>va`Z1Zs<%JfUB-fJe?kGaOl+SbA+v3Yy4xn6`SUx?R4k#lPq<*~Xf$=O<)~8! zK1952pT4_2-hEe#Z)z*ZMRsicd6DubtICbaMaH+4)xK5v#2tQ=MclkU=GeQ%Vf6TVkT)m!m8=SF0_rtG$wvbUMC z3##l9$*ULjj+rq)x{9q{-Tdig6JK4|@|v>z`L>#Tdix&~(FMFx3J{a3`1$jb8!uKcSm1Ao+YbX=|fuAj@?bjmaBs;Os2KjBj)Z%rGxyN{{-zBXvT zn&xX;O*zf;<*)IvUMyPb#bUt3!nV26mo@db9)tSLE5fQ+L}i1ipX;}JEY;M{laaZ{ z0_C{3ojSh!4tMVSM-i{Z_2Sigbp9sitDkcG{w|p>|55ncQP1BE#^0T@#MfS{mGN6s zPrb1|+Zb6oUmNg6wb_of=Tm1TZ_T*iDOug?t7|@AYT8-vdRbO4o(oMpC;uPfnVPQ+ z_@d%z=dntR+;kgf`mpXi7OI{v_4QZDTN7soUsV3ud90iCn)ywaQ}LxH&h^GqC2vig zJu}PJ*LHfoxYX2HuWxy>I&)p1ezh*Fo274g=uq9Z8h`o!qS{z!fBB!Ix#uFczwEk~ znJ@oQv@ct)eVnJ-H``om$4jL@YU+7DeV3ah7At4AO~;7;#hTe4+l{|=d{^cj(vS5# z!jtv7eb+zJ-#OPQ{+Dd-zOIRBy|KyvqRos&$1JfR{aD9>|AVU=3;s85?zYuj5Bwk9 z-1(0p7OU&UB57h_$7^L=)YQ+Lk{4Y6+Isb$YU)qc&J(SsFP`U`s>lDjdi6w2Jv{cU z9&<+#xAim2qn@7FhRT~m^>eS&ELzJzU^f5&pQ`9j<9am7c;xG>j z596!H5^P1ck1TdpTuJ^bd0c)a{#=PahCZ|myWnD%!>Hog3a`Wu#jC4u_-;6YZ%3%} z2)thwRqU2))+i*2~aW!RJ&BI#DHTZuG{$E4-HI!#qi4MakjJZsq ziq~phgFlMbRng6NO96YxWgEIpTuWY$W!Q>!n%DEN_Vqlx@>qhc7|{F;=Xxx`?t$zq z43Mtarn!!?ucIuF6t-fu<_(l>c_V%QM*7~6L@mp)SGp8Y%P_WLr{+zZ|0d2iBvDH@ zb`AzyhR`ALX7az8{DvfINn;mWN@z)3PhVZnn7E$4GB~Is{uci&Z=t-mP@W-)8g8KP zZ{QV6U4)Pn4s3nbEa4DfB@lIm#PGa#+VqtJlN4$$zSl&%}@1{IM z618+==U~8P2ptmdA^&^GZ%Cq+Go#&cT4o5IQ98BL7|FHzZNR z=ZMkgh>@WKHGG~ne4hP-p%b-aum@erXj$A%-n+?b=tM2O*!{59Wed7R+=DOoQ0G0o zRyV9bSBQJ@IU!rdf4(f<6)3=tdP~KN4&yYk7U&Y_A;;*3t zwWP80Fz8Z7%i@0gy`OUK=X^sNO^dHl{?|x1BvDH@b`AzyhR`ALb@G3m{DvfINn;mW zN@z(uK>Hq`eGkw+gM&Kao3zjJAmu$sd4?ovc!>5rMEeZ<{G0X}deNfGFgh&0Mc!|b z*U*7l(%5<6=iiz#S{4rzi-)Q6Vd^rZ(X@C3e;>i$NATC+ppN)1{#w3=zu)6rLlQN7 zA0NJt4~7oZ(u-Ym8AgZ256Jri@)|l&OBy>5gDz#XEFQ(*N2&8s>N2F!wD=Le{D^cz z618+==U~8P2ptkXCjXDgZ%Cq+G&Vm6*Obtbc#K#)Ml2p976u1(#7~KZJu;De@bVs3nbEa4DfB@e5+{3u5sLVqtJlNBojlSbjx$ zzoI-t618+==U~8P2ptl?CjYO=Z%Cq+G~tL@_tWw1_yP-bG-C^j(&fRb3Hn-JH;Qlr?Ch={{tAGC+`3N