From 858cb62c4f87d499dbf2826fe3903c659d6cf17b Mon Sep 17 00:00:00 2001 From: Tobias Lutke Date: Mon, 29 Oct 2012 21:15:50 -0400 Subject: [PATCH] various speedups --- Rakefile | 2 +- ext/liquid/liquid_ext.bundle | Bin 28680 -> 28572 bytes ext/liquid/liquid_ext.o | Bin 45736 -> 41492 bytes lib/liquid/block.rb | 2 +- lib/liquid/context.rb | 121 +++++++++++++++++------------------ lib/liquid/htmltags.rb | 79 ++++++++++++++++++----- lib/liquid/tags/case.rb | 2 +- lib/liquid/tags/for.rb | 50 +++++++++++---- lib/liquid/template.rb | 3 +- lib/liquid_ext.bundle | Bin 28680 -> 28572 bytes performance/benchmark.rb | 4 +- performance/theme_runner.rb | 3 +- 12 files changed, 167 insertions(+), 99 deletions(-) diff --git a/Rakefile b/Rakefile index ecd44b6..5fdcef8 100755 --- a/Rakefile +++ b/Rakefile @@ -80,7 +80,7 @@ namespace :profile do desc "Run KCacheGrind" task :grind => :run do - system "qcachegrind /tmp/liquid.rubyprof_calltreeprinter.txt" + system "qcachegrind /tmp//callgrind.liquid.txt" end end diff --git a/ext/liquid/liquid_ext.bundle b/ext/liquid/liquid_ext.bundle index e35a56bc9bd018ce625c29d548dbb8bd3b84642f..68dd5b6622ab9fa3d6be54dd3a2b82c6db565f1e 100755 GIT binary patch literal 28572 zcmeHPd3aORwm+o}Ak(P>ih@v)(V?`3)D{q122Hgfq9B40pcGmtZE2Is;FVU=D4~|3 zPrZ1Z5Qhg|2XKt2TyTJTK}F;$DwBemLlp6%LYeY@YweZfr0uz%@1OU+_r2!(lCyt% zul3t&uf6tg_Brh*Cw@B9O4H)vHBD=cZwGt}Y?_vUD}64+w@(XAb2@JsG5!|Liv7uo zg_>Y+YM{|tO0m=F%AfBNfJ;NZ(WHRSgX!u@IBWywBxseYMEyFQ)gzVEMA zMT13xa9l(hZ56(#eZ=Q1$S*3*FN0h|z8*uA@}Go*Fx(RTG_o(R+*MXsJX0hZ^8Ho# zZj|yc4im<3Bh%@07tbp!p6)Cxo>9U$wm%Hv8!rT59Oi3ybvpA4oHNR%&dFCL4efJW zqw@WtNSI>8>O*m|1P*pOhiBiCZIa58bfR1vVCr__4fnOvSzP2SUodA{Ns+VERc6T- zrlWW>+eQ7^2H)_<>6}?&3cE&piCIdLVxK;Q8}hZ|67}PB7ES$k_H}|jeMYN`M%c_p z?QJh*ba6VTl}DqvvHuFPlyIpjAk2K`m?lZ;2M4}RXKv1@8%7Mz36I&ZK}jg2kKjkU zDM)sixw>mwWs1m=Z(2j1u@cuZfCES;-K6Rx^E%;MI!4pp!u8LSQFgYbwM81D{CNSt z^d2o>0RL|3+PWsl9iMWUuZ{%+L{-TNcj?C^f*Zt19TCI%B6 z)y_@~b8F@S=2p*R*v7Fb(81x^-;E@$OU#MeoSS*n-QG_jWKR^^o^%JzoMI`exlo+TXRR;$joE9_ZdW_pH|CU z-x*^KSUmMJ^s25`P@-6`y6s9zxb&)Lk~M8`Rz>H8?Ss#nHz>!q&zOU;hN^?Jss2~M zFnB^m7Zl`#wv5a?qkE5_+&@*AZv=C~6N4`*+w1VW-)Um@?b(yECuch+y{C7pgosu- zq`SL&j%Q1Y;5mA?;hL6HGcPW?@|y1MHaWgypmQG%Ug!vY3_vBhnZLU~^3!-WeurIt zTC~W117HU0R}Sgj6kqRu$4B#%@htIW3E#s2j+$X{4&R8n+{`2H4t`p%9M$eRV-Xcq zkEmO!vD5SQ+Joo|Pkk@F_Bl>;*S$X>5!BfpxUG%u8G{T*^`tr@2MJ}Uv_IPux^iBk z<4w?Om3`0}{i*u0orAL$Z5}-F&)e8@n~ifxJyb{51aA;Ux#U*gS(m-E)o^{oaZvTD zcqy1fS@39luJ6t|bhUf8@jdiC$CF*(8Ly)n$aQx=M&{&f*>WZn3gz_Oms^t;XWWBA zeM3vn@$T+V5xI521-Wr&a(zDp_Vg$7?R~IUb9jHx@qOU#>Zq|fDZ+ePHc)p2UL_Hq z%|;@=&5ljqBi1)}NZI&zD$VsB3Y0L%o!e0wDCG2rI!8@u3+mFP#z0soRd=DP$-^k+ z4*$V8huTjDwMQ%Tsu{4Eg+lO0kH-GUskx40NUx&iaUTwH*SQb+X@kn0_$G&WZ@uaV zC2Enx)=klt8$c!1p6lM)ypb1?N|fSgMM zM8D_!)2NYpdLSq;Fh)^ta3rX1SA)cLCHjox=StU4o_eP%;HgK$hIc0_z4mXHV$g8l zY&jJQ1-JT9yJqx9oKisOo^_P_te^Hi#$g)Aw3-_SDMf1!jfgJ*^ln)~a|1b$tQv|$ zO#D&fzeD3)`w??H5OcdY=5`pJNJV1q+!@Jww<<7GlY6_jHW51yqm1g~PVB9Fp9ZEr zGAfafFnTDJtgsu@`_VA!ltz*gMsrBSXWPut)KnPtVGb2W-8mf%Bag9)te^<)?P^5< ze>WzN2GO)X_$SH=4&q-sq})F@7%{E_8CBdv7}%{4aGrV$>|KbbT;E9t1zu*8WL0iojNMS+k`&Z{Ngs}%Po5^n zzwhqssJVI-N;XjB1dd^nhS$e)Pi%Hn+rDSdW~@gHXek?WecuE=CXs6U)v*+}69obt z<6lu+EEF>SdGr&(w}BESknzvLyK?&;akug7P&XbxL@$kp`RCJ!tC@^}f7E@GpLR^f ze3U8AyjhR9?-}C{jHAIAIj*i)Izn5NYwm{_Egc8^@G7~NL;nNJuCh|*R}932UD1~M zv}!t$jzC;v(L*va8>C?ZquELKJ_Hv3Ib_OR;NW$#7xtw*4UFs})4&ZE^E99u0iE94Vcy^Kp3>VMwiMsd6-)PabuT<6Q z-t0D@sk!=dFsPt7UsYW}CSQWWXpgqw8tt!9NJPV_Hln#3QwSRSAeD1CZ6!}un*;n6 z5~;Rx97id#iGmyTu%ehC6pf}vV=CGawWw6l^^djaU&vK-*DJbnt>^+aCQwccVO@Z2 zhskI!rm}D0M|kEnV&gbFMFKwCM-VXHrNV0ahf0_O@{UNgpDDrTsjxvnrtUBvRjLn( z>LS#U6;WNGR2QHyI29GlH&t*^M5;_lO>Ck92@kB<)%IZ~<=>#9I@qq1do`gf!zFMS zb7wfV0!Zi9^xO1R~ zjkksmmO_?^sOsCzq8MvXI`RcDcE@LZZLMqqn{ zTSaVS&x5_5`Xaq*B`3=Ds+*CZ+W&*Hr zj5v&%>)Oxelp~+a*^Vpik-hgKVRqI(&@y8LEQ-}$#oBh!zMr+rb?+$3P=0VPHxe4E z=~Xk)z=)40vf5NvD*HH>i{Rr!AKpz@KsD2L25R)xehQ@(Y2D!HpT-2{Viqh8LItjVz>$8Ycyldx>%E z>_(L@4y$$))iPEs)4j<`mEy!*YrNc8^}4X?R|qV!`zlsNoE)VL6(>-g163fp2Xen{ zj5QJIwbdM~7!oINheJ-N>HtR@OOPG$l8Yn$%do&3s3kZ{2zBo;6Wu$FLLNdDwEe;kXZg<%y9uh) z(>b`RP16F(9>~>U_@#1UBDUurqhgAU+o-%PvLh|}oGom{lF9DJbA0Xea zz`uc871Q`8nRtE+B$~L|AZ>gEMa;r`kXBPy%agU5>y{)u9BCP??s*Gr@R$6aGwJwNg-L15qpt44; z$@QHGWV5nz%^;-N@xhTbB{;nLP51Uc84CF^7sC3(#*f$?`-f6L##$r0HtMKXNIeLT!H@3~7<4NKAerY*^@$W)c zr6^uNd4oOo6s7q{RFn4H-y&DFWuVf$Ln?37mcVaGWW9=|pE+&k(I%VZHN@1CnsI~* zeYVUdn8Llc#>Dj$(nf6@k=xrV>o^>)iT8mv_d+tlVp6hv5*Otq2xcPB!NmcD(ztrZTDD|&yHyRRcT&Ini(jW z9MQa6X`UU`q_(6+G^Z%dUl1e>-A88%CjyJ~BRmxTk))zU&t?j5m4r!apN@r*k|X z*l6CV>I&`1CTfCSI|${xLby4Bec}Wp(1-=FM!DxnoJ_#Ew^Ji1@V9V`uMQE+pK_;PkMj#0!{NAUd!Y9ZbOJ@y7*D`Rvp&w|!M>T6;n^rc z%Vr^3DRQarX2Cwy?5CN|Hj)aXp)bwi(G-|OA~G&-McU|tz>H2h1zc=DiExk^gK9X0 zTovgM`+j9yJpYRLM{{j`H;QG^WA({3P z*s?wEKZD$s`aM4&*Z7o*YD!w5mG1S%>p+c+TEkU?W*HJhQ@}={gWeZv7a0~BcGPJNamDH5*4CCb%+L|(p9)fTe9)lv8^(oFp zJ@s=JUF)gGO~5yl8}^f%{PZ${yOBNHxK=c7ov>6hOF=~v2Va0Y1i^OzJ1pLSKLRdcE-;>lG^%vpXSCot zC%W%3HgFTMC@vs&y1&5#iHrGx#0AEsJPIm)q8)x&YvVjXOmI1&4@PDl)~oIVG&S}d zs{8;dcW)aBS3Rp*&0Qs_3QELpY^wJU6NtZ6EI<)Uxs=(pVCV zFJT_qv4(gMf?D7p3)%lpJknO#8B~)Dw{<ANx5mY`7>zLYO|BdeYVG_yonmW4b(D$s?n#&<|{Jpo6*F?-M>^ZO>B}$ z_02F7*VRZHSqR6}-|2DA7}i$Hbmcx;rcZ?%whO~5=tirsZU^ny3k6g7q-O$;aGdlc zaNOghrwlo?kiPa1EvGU z938h`!+?W_{b(fIgS)T;#yH9z&SHm+90KS)(lG`T7$GJ72wW?mJAvy2bR^&q(3(Jw zfRh~nt`~3^z){nFHBN;_<@IKsblMyb}6nn0;DN06FGsb48| zJEaa$Y7(XPQ))7$K1V9ocbp!+wf7?kxldNNr}?jydYUw5FM zsneA-l&j}!7=Nr@2zByx*YCndEgc|Z=zzI3i^vD43;QkA|EexNh@4DkK;VBE{JfFg zeGoz1!Baog)rXg#ZNSuW6caX5#DwiRGc7kUl`VSRQ;+p}f|A5~O_E6>Im0A5x#9w@ z^F6emTh)@P>dsZ=yBE{TES@dcIp8&%K`_gIiEwlWN7P^4CAXc4*`?P$g=|kfc5Xd+ zjl$0D!vm^EYv$9dJ+SFg(cICN{Gjubz1bBv;PIYb)sJjCf$dTmv^*!Uy(~ncvOcTg z?C|r!F}q>y&72F5Ur&imPgK_9#e)ng$wY?dM3H+dZe}78{&&#&dq}+#P_L)nt$X`H zRJB%msHaF|ux08Mh}rtG2^bZ080|gtEhos=`|+l$vB5+ZXELOgqpISdRzCNO|8U31C9+Blyd3e zGTuPwyBYURf!A;_iA7{JPNuMkgb$jA;>c4ir?ph>vn`==EF#smMK~djp4>QmUj}9< ziaD_qzam$yL%E7#q)^13cHpdv-=vAPs+*$h9!vRTgt8uUE39f^MHzUN1ms5TMNZrI zV7f&Ud1)&kChWNAoL*`>hSwA>hvCLr zthiVWv3*YdlE&N_V>EJTUh097p$?hPLy6H55N}=Z%-6<$CF#0ISKj*JX%A!Y@YfWU zI7_FSD4O;#9KYhcsjhA`?fniw^dI1=roGp8f&O(s(DR^b<4-2~jxqG00(~vSj8*ty z;=4G3LH4lH<}uL5-;cDv*lRLw(Yq{v6U)=12_?@HUK@W3$^U1J{QWF{3Cm;DWFkSE z2{p&Tcd6WdlL~A*`js^OFb_>M{2SyLr|}bYTpB43GAUwkb`ME=)-i)yuX+hmo_b7# z8%Y^Un@ogl{QXJ)Bo>PBEJ%*0$6Ttzwogl8lc^<|&HEY_LKI+(cs zq;w=iGDzpuSe-}0I+w8yx_u}Ts$CK(nWT27Nezxah45up+zQ7V2{0D#EAeZ7ZTtgC zzAJ7#!mqV__)lUqzt+;pa{^C?J_;Z|`aa7l5{tagvID#9$onkG?vEpTok5_dA^SE9 z$X;g#>0+;Qh3t33UO{Jlff2&Q-NW{>@d zFWikHzIJmS%uh0CPb1H&7JqlwF4(+I_ng&Q1 z-B9>>>=#@BCv=8WX@)z75TKTCK!Mt(zlxOcF@8{$Y#padRrF^|k*f4%_i?OaMtc+q zNXsT8U!*_dn|d`0C+N%aSQ_(Lv67ZOzzmUoCRW%nIb*UEKS=z#P-P@ z(&#t#q6HT*0b05Tr>PtOU!&Zh@fr1DfzZ*PT$vi?=fQ=|-j^un82pj9uZW_DxDrfu z>mg&B?ArSag=;tNZNu{&^#{#&Q%H;Ey9f4gf1D_C4dqGiIxc{f)u_Nc@h!fRtfgX} z__|R-O?->br4lMOO?>VBv!wb-Tz%NqNHBA>^u4 zrdyQSV^q#t=V3T}irqS2t|%7AQoKnN7+qT6Y(+6mC>n2_G2J^2@eJY9 z5K*>|Rl*xccmx$z+tw>#?%tgd!7G&DV^r9nd&AHFx+wj{CjAE@`ajZ?@3ZAMp^w+R z_F>LJxX9a~j?k9CyCjeIf|-o^P4})+#%D!1S18U4A!E>6EYjuoDAhI*Rlb`zE21`4 zsU4z@Zg4k|vXLIkcVPl`H&G#X=P3jT zT2af|sujDH%u^(TY%M@9c)>HXiQsKjxQq&6uNHVq5sWht&;|(>Op6fQrwG!B;0{$d zCPJ`K5nOB{n4n}Xi4crd1oa3tev3u?c#Tp$L=hOh>)eD~6+0IywSQ1~lYZQZ$u@k? zL$AUhxSnA$_;D9zCbWWVS1sL20zO+68SxehaYl4>Ybf+hgYR+R&$mVMhv4*(WaxU& zp-^brkD*XCP6z0ki>&}%@4|N#8cp9iP+x&ju}ZF#Hh&8dM`rw70~~CCN%oKE{DS%_ zF^wN2=Oay5^LM5RpAb27d2f`PpO@0#hrxf{;I+UaM2e%jy^s6rY)6efk$t%(K(jhv zYl1Z$F9doMNw|5-B;!UTOn*PZe{VMKW{2-+fDT)8(4q8B((i$5fbjnJ#O%qF-di5( zc?Bv7^-Sj96#h-)-vRua&c7M_JCJ_|^Y0M+;%^w~$Dl*X0-R51hJ#W)DMeer0=^rd z+nfSEsl1F*w1^r>l&Yl^9S;{gNhzFNX$7xPim7qDb@5$jTlUSNo^x?sUhn~xVO0#} z7S44SPS-|HEi1=gWS7!K1I{US<) z(x$l!i>4PAYeiE5$_p3f<4-m<4bMjSW4@9Z^vCAZ0Q!diaGcT@Y4`)sc>K{QrL-1F z=~`SVZn7@XS`b~_r{isOrO$clqQxy7qs7fnj7x0Ss`YXd5)D-s*n%eE6Gu09^hqGi z4vBZSNFeU^Efa7Gs(D)7+p@;CETK033ZPr?-H!O7&j_UX(@;;csh%o)kBB^V4}TiU zb9J5snyUWYC;a#B$<)R8WXN@>Tyy0*POekrI!mrDxh|KhVrl+u_CT`-nmy3$fo2ah zd!X3^%^qm>K(hy$J<#ldW)C!b;D5sdXJ68Z-WJn_WI4;GIrDCuHY-2RrQI|)ad{U0 z3)Xc0FMG~u_{VcNa;e0*ochEqpW8`kOf6gBEY6>&E!XBI#pLv-tUl4KQg?X)Wu>UB z>G?AXi}Rg%IG`!VzqTWK6lTN}&MBGhF3P9;teE_A{9C=Ed{;@ab56dipkz8pIF!T; zcQKy=A!oG8Da3hES#cW4j8{4MzkFenry!?@&zYQgB@mqNa`Hiwvv5vn5mfMrbK?IP zwrEO7OU@}SbcOZlzZ(wGS}4s-ZCJdvy#tPojx5B_#ybF37L5koiM{P?xSYb5uJoa! z8#)ZS9bY<)qGKF7op~N#I!xXP9bB|N_>vq>T3N2G>0g#1ON;*>k~<6as(*P#wf;Bi zC1GmdbV|sF&biE(-VvA)AE))ctd`ux4NgX@!~Y+Wp11WdVIMF#Ec_t{^}rWLb^IYb z3O{B{e5LeQ8=r0X5?>gTJn3`gxDqCPGba6wqQ8gaO_=0KKYad1nDoQ=C~z-4E-T1F z0-ts$BV3xrQ0pmpzThE(D+S*wc!}Ur!OI2v1g{XhO7Kd-^hX&~-)g~h)=zk?;GYEh z1-C?pQTax}-2~SOrZZzI-!Awj!Mg;{61-oqM{q#!qk@kJeogRk!So_N@oU-m;`4*x z)`DrIPCKg0B%=CwRQz?SkhD-X(ac;QfN15*!fxw%{Xz|0(#m;KPEop{oB|VfG{Y zS_@7RoG3U`a3{fI1SbieEx3(+dbxU!CC31#cJpv*2BV>EDl% z{C>go-(?5~1P>H^MDWdmj|(mmtV#TP1-BObxZp&=ZwT%rc)Q>v!G_>If?MFNX|g9p zaA(08f(HoB5;3|yE!5y*nA$yky zP8Pge@O6S$2%aK%rQijER|~#h@LIut6YLlKzTl05_Xw^N{JY@of^|H$Bl~sYF0?Q^5s-4+$<69Iq?+`GUI$t`tl!a&!L+ z9wm6W;F*F~2(A>oQt-oqR||ew@LIuJ1^Wdb6ueRJX~A`Z&rekLY!}=QSdWYDAF~99 z_lM&Ihxe~@fgv9G+}QvxZGivM06*0LuWx|2HNb%enErCWT)&1tMlj=c4e(l6x(?r$ z@qHEF*YJHE-#75}9Au=~i{5Th(!uRm-iy zCpFWmKQb)>E-l5%C7BitOiQt7M_P(Sf23K3Xj-a;uhLR2+L4xO;j6S%D|6E<8km-5 z)s8f)I{I7mN1ENL9aeFbW))Xy=~i{5TlHYNmD@9{+L2-9t4ynQSjAOZro~X}ZxvVR zX%-skR=>sghn~`BzU{Oa#rbQ2CSUEAnYH((zSW;Oy zF*C)&+)S&%nQ1jRGgGaotU4;ws%tZ?dN8xUMeJr;byTL+EShOG44PNxMjMt?tBy)- zUY+@IgK2Y@+Ppe9bV>8-+-O9lHLuPMqojFtZWJZ|&sXO^c#ADJ=1tt^)7^LYfwd{E w_9;}r52?)$!YSRvqiR#OJft?|Gp8b|_(h9o8(L{tcq z1n7x*Fg`Bh%qYI`4$j~x2tF|KP|y*gIDjuiMCk)6sHmVw?)O#g(>V$0S>Au{U96Q} z>vWy(>|MKd?b@|#SDj9F{rKgXPKFWI!7z*{TwQSGMH)r~N`5ZJ)j!-YyxvKpr%Y0h zT7IRsgoa?qG$6+4C}gkKm%G3x07Ywg39Nw6bIH0SwslZXB8+lP(cfNgsjqByY4A~N zd56+8$t@hjVL@*6Rpd46M|s}7+=AlV67aQ_7kizqJYQrG!z|68v-Ha@^_Aoo&J~W< z^6nRTc?;W=&lX32bLz$MJRg_+@p|VLIo$3ndC}>blfKUnacg;<6-9q}y#=%Wn|?8<&(C;W z7{pF_?C*s_W8wAAE^YSWv+b9cu9?dn4&jvN^l5T(96Y$Z-mJ{u{?F)9nf9Eu6-po% zK7ylS6*8!oQ&wNYC|9iDqiv#4Dy-R!RNw&aV{g#yQN0*k1rrRT0p<4J8%BCp!?*zV zU{#-g;hPurUx$mdP@e+S@6`tJQaocj>wakJvU|~x`X{d+egDP9|NK=Po<);C3Zsu} zfQ|VKAC6%vF4k41?C=!s!i>RXr6q$4@@Mm!czdZYcix~8gK};M0vVsP>KTXdv}L`b z**9ko%5c^)jH|#!eez%*+Am&kF)%;Z;3A#)G#|8o&It=l_V_>Z)TB*If&0INwaVjv z-Q$m}9ge%|$XDQDp6X~%jcWwy_Xp|oLEp&f<*DiMD?Y7pT@8*M)?$D;W}i`pVfHDf z0VqG?cNsTkOwO1z(Npn7RHpw2Pjx4c|J5a*7_nfhdI4Nd84aBb^WM#s@0e8&0DG!- zn3d1qCaZc(jHh}`^w^ptW9+cwX62oDm|?Dus>#^zo?tHh8({gVbh9=a6TbY^)J2_Y zG9GeYeA|?<{;k$b1mUqYdEsM+edim4O6lQluUR=7Q^u^zi8T!OK(jIh$UVrc9K{lH zE@L^>tnGucA~4$>V=nEETlA?CO+mAYtx?l5rf1B^_X#s>j|0tlb;GkqkYL!)!sOmA z?dRu8>4xopsjlB4fc`h$J44X3;DKXnW`>O&cEYT@2L|I9hq9h z*|b%uGfJ_!<7Sk7ndSf76Tjc%|2Xg|oA$q+;3&V5^HjJRQ|>s6AKx>IpGwx%Es!}Oh5`4ZZJ>``%H?gF#2 zKg5`IuJhQ0SveEPJx5B+!Bssu2WPo2HkbVkw`2WZ*c#r3v;b1N$JLD3?H+0_U5TZ) z{6|dRBDhNVk5d=zsTqMVFn^boj|WbB1pOr&1nn=NNh;C>bBlRG=i*EN~InWoY zVgk(Sp1P>J=yK|(rlw##ur=zg#ldC}auX^qdX-`t;Wch=*~X)LgAE_Si0XzxUkkcf zx2&sb>{-_B&4$sFC($J|`j84j^H*9GXch4V@k|@C6gZ=N0f&8McLYlRQ5AMQO8h+@Q1PSUmP_h9z$O~-Ulbh@*fL)k`VNO2|qS9>Dp!QW1t^_mlHy zwnax=W_uy5vJLw<_cX0`JfyxJxLP%^1)4@BDVHoqn1)tAQ7iv@FJO)VMxKV=p6XQ0 zpd*7xV1-@mnprtiSJ>?6hR6TD^+(QxnkjmAU1%#vzg&9?Ls0j>IapVlm5VTrW?cb< zxci!wb)4JjX5A=wCOQMFvp+jg!|u;!+@r7BL$<{#Hurh+4_HrukmYaCUg~LT$l^M8 zFCLbsUR`!fKk#*z@#C`(^s};W$Hu>wSu_7kX3c`IK(Ao;R-()3-sv9fxvQE6kWpgy zrkzo(1=llaFHW`BH`v}|!S?z#w|BI*CZiE6E4sFHGUQlaoos5V8PP~Q3uc28TGh%= zN7=IuDrWh==YY*0WZVB3h7JnerxiTNfoxXLjv&1iI~^zx!`q6qwYpk{uJ)*-+6xRl z))Is`_cgvKEbA(%$n<|Sr{10qqo8T|aMeFOK@#!6T;IXn*Y_nt+dhwfe^&fgo{F!+ zGi&Y&3+zC^&h&3Zs|yjnpsWvb4Az{-xF*VG`48I47K2@)^DVrUNx16=yA404c2zOf ze4F%~kl;v@m?qSXz&9P~b3{5i(zn`?=tZd@S%b*c$FMuN5n7>x!T#kyUion4FS>sd z?FQQHpLMO>zdvbjd8V7{UzNjK9Q~^YyY#P`x6;33-|PNe?K`V~@7g4@vNL*Q){T_@ zF)3pIPGI85tXKUTtosLxm&21`@prJg!s4a$YiE?PZGIYC4$H=$`+5v%B+ zL%!!)M;=-0^1j2Ytk|mZfU0hAd^GxZ_!z?-Jqh9NF7z_6NmYqlLHDb6{Sk%L8Q#s% zsbkQiih&^|N9)|<0>%0}ht8ODw#L^hcIDEed0UazPgi>t`5{_}aa7YTeFlTbEcJdU zNe?PS+1z|wu=yEU&U7tjyhDzo`8TnL6ob9S+lsWybv14=(R^1&HPyVW_n(?8*5Ed? z2H8f|upi9IV<%Kdlf`@m*Sb=(@@LqP;qq-_EaNL6UY5>HsF3MDtyZd*`N`_8!D#Or zY1a18sZ!;`7!J4B_g-+l<Ubt(fRh-d3c&2}V@ANmtwCsHR6~p9-f)sLllLQUS+CkyXb8# zhHRW2FI01-!RDmil(XwOJmiw*=6dMn{-&FY(ADZ&H)l`SPp*Oh_8Ag z+xev(S1Y~+dFOF15N-KiGHM@1BNI@bOV^#EvrkI)LoZ`Xzh;j=Jm#2=yD{r@$_JC~ zVPaG}9pBuOMzG8`tFA?9kIQ3D_9w|+7mtzVIQ$2BD95KCt6@AIXMDtXyo~2E9{<9v zH3QAJIUbc`oWieH!b`Y+h42L;d^<}B_lWSBO1L@$nM~n^vu{6K;ON_rAe*)2tdG9+ zXNkUzM``zMyOaG*#eRdZpW@<%?fDfB_CGt>|Ek#g3i}&mN8tMgr7ittC;L3b{w>*{ z%wJgg%&IL8_6Pdfy2GR&_rVOVeT>qvH?ITRCM;Yk35Y`y@XD2(ON{F2n1f6aI%#Sy zsee(_$g4O#t6hCiSZm=1a|YS#k@!Xrh_xENgltJLE@SN(x^_M0sMQrqy-jSw^FX>L zK1$*W%%fnCUwFRKUI+OkbEzK+sm*T*d=Z;pv-Uq=uNm2(T_1!8Z`|(Tk=lWuM*Lkpnp2mom&toLb zS|1#a-gOI13E!<;!uW})lZI^q=jB8^*E!Ep4{oi4-*5y*HOqYNsO$zM2Yw9LZf_+L z=HO0oAjYTV&UfGywnv_U6JhmU&pB=&XG>_p-m zO&mhvPPnG+_E98eYT_gk|A@uiZu2cX4_vE>za}x6#0Wzvw39?r6CXjpt(P1%?;-IU z%yJxT*N~V8A_l9j1d3VL9FdXHVN=DguRxz=R+XW|QH4G)O#E667|xIp%THmB?dR!B%O0eO|a5j)_4}kD&ZNEB!_ut44`<)qp6+cqM~&H!Ki1dbu*g6ClB39%3O5 zFytMp9zN*K_oedeGeWne`<^1YslNYASFW7{4cYh8U!X+a-$iNrZGiqH+S?FB-6dr))?!R1$NmJHk6zeQbfdovha8!%-yLRm zx2Ypd3-=hg(MX`m8ngUg$>HkK-cU&`9E;(An5KtO9jcZ9*{V8{y@85d<(B<`R2HWiYR@)Yv<>4H?ML*O>pd5#UVHpM@hsx>=gnsr$8pailz6xSnCOTNni=O>?^|z!T#u8q za2`ljWy86wO?X7F=?JIb46DVWXM4>P9c(wi1b9k$&0w;DeJ|z`CrlGcoBcK?`$ENT z2>WWXW4s$3>{BsAf-&`ZL~FD58M4F4{t7lbkgS9S1OLWLSv_*2F=sGx&!aL%E)~dn z8~t$l2P~9rVcuh1t%pnLY!@-RdFiab9`q(mfNUho=h9U#Ixm-!{hLlj z6>H;P)G$mzQ0AzOgE=^Ahfu|4-{fR3Q0(!-9!qwN+BygOV>l$jsM+WI%VL5SMmF1Q zVeDr=hqpe8VGRezxpdtqI>*5l)SLa#E0O-TqxVj1zybsDg+(lY_+S;m4{hQzBt~oE z77~XdZra3qN&J>)-Tuf$@NDZahS6TEmy@_h6K^2#5rj><=2Q|lYNDIO--3v3b7uS* zoaqK0R}^N(-(!9_;&WftTcYcIsHe_7${kenW2``SFYYDrTdXnY{~QvlNtDFlJ`(q6VpkHA z9W|$txKR^NQ=5ZGq(s7qjLwR28cT6QnCiT&#&Vlb8)6^TO@O9wje)nOlOV zKVixsOVTO;rU2pCJXP+-vTfG=4c~~XRb^yeg)jU3w;lqsYO?ja&$*~*t{)j@J;kTN z@M3DSZ#i61(~v zG!nR1RgA2|z+2;?rER1b5^vMQg(RNlA~wy66IJ zsAc{Gn)hzaQ@Mue8P*6FOB{z)B2BUmehPq~vj(cU7n)UjF^+c7$>O_D`+ep(ObzUi z$OiViSR%E09Hq@Z3`gO?rQ!>&khM!CAGsB5w(FFjTY-l$eYM3dLib?ekFfy4#F6am z6Q4miR=LMMR)dVZ5HCPq1mGZdVDlS!NMHLC4_lB!tptKIARh$ZJ;E13z7>jZH~A1y zi!~qeK=9one39hKSA2gbA3EjHd>s|vNa5>9GhYP?+=7npn722hGl3o0!C+%jJ+n4JW}vqgd>n$UYq5aX2N!EdG&J!8 z68AGBLMHqV9?4^kjiZTcW~j`pGX5hqVx#fv7~dsk?fID4$b_%4_F|7K>261`*e`v4 z{1Dn8>l=s{OJ1Mlj`v;aPG7VK6ZRve^!z>6Ub1L6!Fx5Hjo*%Gq2H$+fj$_$o;s`j z2*|db<9$;sXOTX@yp*?iKclOi)&c23N3|Bo@L{}0kctO!8;p>9FxHHa%u#332*~?} zKubvG)}7vfr;KNJp}oLXB_?vN8h6)B7Baxv#pb{*?U6`gg?n^`{ou5Cx@Al2OX7S@ z+(F`9AkyWBVmdNTJ%lCI4m=Mdz#%l~Y$w%RHUKDcixZkvC4 zl(A1)lW!{#1&$&?km%MQ1bbb&Of#v?{DJ1p{6-~|snllZiulzH;|3kpQS;_so7AGK zdZD;8Si!F=Y}0S`?qmhWV!?dVneS_rmUjC9asO%fLoiBL?6spblEX}-uV!60d@}(m zLrk$|;48>{V~`o4W+W(P-J@j2PW=`JAY@zvS*Dw{m$1Z|)ElMz;PE2dTHPRmzc)aY zRI;F*9(?{C(mOi|{RsK6r^c&)DsylTDy$z9W}W8KinNE>@8-DL4+aSoVA}@AT1F#O zyUHE5&~f#TNM!A}`XP7&!*zxA;I!UC%XZe;NaE$1xPrvPAlfnGChS*r0*5_mr$bPy zb}Nqh7RFEOp&M1yzLaPgFkSUmi;#Pj_!h|9mb8L{TIm-u6f>4ExBHEh}51o z2|^uvjDGLJXZ=4}y?#I`zi#P@XGnC8_Oc%s`T?iJV&oHQs?I-XS-V+Rr8$4XB-d%q zl?YYTNpj4Ks8b!NDhhJ+k*B$|6ckc?YF|ormiB?R8 zF!gpYoqk6%A%Yy0N%ASnc(dwzlo*Y#Wi&+T9#q-~k3!G)>e1ljwUySRk%ks@6y$y> z7w?%6%Cz#;XfUY!0yJUP=7CP-tAM~4p*oo@d}<9GulUl*hsi!e^F=DY;lii(OZ^pJ z4EeBDx-?%$#n(;vIx<)qpwKQSvDIW(F91eYyR_`;0Q54zw{hs|2{oLqFImX=;DmiL z+iS6Zf|TXpp{t0&4naU*q?S^srOb6m(FU8Pb5|}Zj;c?wYLu?}clt@S>oFFhfUY`q zkHfkH-*#B{67&xFKchWd=xU&#bt8pOS@#b(c_U`)_Yh9^oaaHb4 znPz3K-X3&v)W;FKmH2^bxR++)K{FaT-@&AQaBX!4n=Sud%HKk9D#Wd!q0P#^TK+>0 zqf-9v_m%v?7=K5{E~SWtN~T(HfVA`aup+5a5~fort5 z-)M2ac8H@MpCEa$JFuJV;Xz>|TMAoE>VBjIFgkzy4&C~;682AIqPDOlWM8M)Y3-d< zsX4e!BXxxq_8h&h+VwOG=_oZDQPv;nv{*Rr5`d` zo(E%~r{>Po{TSis2c}#KR}aXf3D=POD-ORJ)Wa=XzL(TD6gBcK-STTJ9Njp=Zb;Mo z3x~j8H2V`6IqPx+F}tM!Brej#6(lxd=G(-6B+d=0u^e=VH7_J}q^?>B60A9wg+q-~ zn8LQOec%jS5){Ut>pO%skor9|#yH=ggUKt1vy6sm4n6#_d|@{7@(d$G~^R=*dRokw&SU7t9 zGUBJ*fivI?qz8pP)l%5!q+X_l)oEeNTL~+sF#0$&d!FoH^4=d=3~jAzaj0b5_f`@c zHSrD-3*KrbP9pJHO?(h7Sj+fwLB!4^@qSHY1h5ui^{|N}NxWSX3rKtw#NhH*34;Fn zFpq!6@hpGtN&I6IdM@twlwt{1WPvcqenFL z8>+sO)OWJ_PF3H(Qr~X%eVzJF$9EnZwI<*zj~h(O!@GXGyN-9Myi4NUWZn(n-8|mK z@~)0|Jc!DBn0H+L^Jp0hg7L|!>0N~`XH0DBSBA1aZyRYi+iS|ozqKqs#~44Wq!fRR zUChD&&Mfrh&c%b@6co+!83jc}x0DqdC9?|W<{H_v3JQ!l`6Z=3V|H17K~8?5Q7{Xj zG=E_({#?^AXe54|CDq^`nzIAEK1;(FKD?**bjEj#x--IO;;%l-lMSP*5gzvTlt_x? z)g2c%e;SjKI&j9X&?CIlTA`kTOZi z>!kEZIYG+lQqGaGSjxMl)Y96&+bz&;fp!bDTcF(n?G|XaK)VInEzoX(b_=vypxpxP z7Wn^Rfv#7?Ol7;*rF%V^+!S-oo75jC$kN*cML``KW*MqvEpCJU&X$k8*P7!PyiM?0!TSYo5d4GS2Eox7P}birI9_n0;1PoN z37#hSfMB2CfZ!Uz#|1wj_@rR|Vu|e;8MyG-Cpb#**Mg%3pO0BY{usem3XT=*7TjO( zWWfo73k9bNUM4tQ@G8L`!5amS7yORkDT0p*o+&sYLhF|&xVPY9!O4Ob2p%W6Trl4W zvVY43FA-cX_yNHy1wSizmEeC1UM=`D!D|Jd5xhZgFGMW1*C04S@OHtOf*S?T7Q9dJ z9fA)CzE^NS@Y8~i3w}-TNx>frHb&_2KPfm$a92b|>K83|fZ!OxBL&9_o-Vk*;4;Ap zf@=k*3Vu>>y5I)E9>MPk9xwPC!BYfZfVe~bW(tlIoF_OB)DAga>2_5 zKP?*jYerRxXJ2rd@#q`AE_k)z zKMP(f_+NrI2!2y=gWyAgw+sGRaHHU!cy-72_6Z&=_<&%K;DF#+f{zPcDEOq{djuOJ z4E5n}zbQXT@HWBGg7*uK5&VPTSi#ZAU0J`s;CR6af=38W6+BIFx?rDRkKh`?;{`t< zc#7ax1kV(_PjH^#uLTziJ|DjprhW?qUn#g;uv_qQ!IK5o3oaDAQt&dts|2qSyjt)^ z!D|J-BY1=0qk)mmV% z2R{$A!cVrs&$Yr0t?=Gf*lL9%@xyj!dtF=M-mP$aE4&VxuE+H}u8p`}!1W@omvFs| zYZET!;IH7qCw&9HercUpWAJ4BR-kmSuV{Au;E_c+xq~N^&AuJ~)|tN~7>qreeQU_p z4UYz8|KeJXN=1hEtnHw)0S9YIfno0&+t^&&tlr9h8zZ zBrz0WNZW+O)Ra(!5TX)OhJ~n+;tE9wB`P@~L=9JRC_*Svu27`|MGXz1 zRbnVniAkYqglHpSSSUiMfl5dX(MCdQh%rwHHG&B#A*`DaVrY|7l2Y63AP8-n9fY=x zn4FT>wqJqJwljdxcF&VjLQDe?+O}?TN388G25UPWr{3+mf$sxwW70N|jp`6+k%0*qSQ2iJZiV(_ul7@v)H%X#smj2x$7i#(K zV*8q1Qs~H565H2o^*+L3lJ+&bbxzy9W}lVjW04OLTie&{v)m`Sea&taWRhL&Yj$gs z{FgPm_4dBaJ$&1nbp7g=tG@ka+;OjSGZNI>a8m3y?!0f~ow(z%ybX6eIqN+*Y4#g% U-rMiKd2he#Ac$ZjEXtxl64nSRQPGYDMFm6me=3?ka7u{$PS??Ln*r>^FX zqnXTgu;*`KL6NCR{o^}d=U4HOuK#Tpx!i_$OWevu)SUHk=c|GuMx55*`0i1AIcM_I z6!TuaPn~#FI`Hp}jziaNw>i$RWYZ4E9@r_spGwQLv@lbu&A};{qu&hcfI9bqbOhb zYyL!EWp3;01mCjU4o1zXoCh^$**v2*^S!vYl`pWfGd<2~ogMdTPUiRimR0ORU&Z#| zxBVPvsmJ^Lra;a3MI8b!ZV%KnpLd?GvfYdUaG2U+sW0xG+Rp+t`HMOSY9{yx=2Tu0 zH!|}lZ~1*EI1VR$C#T}K;6sQKsG069JN85hMc%TD`%ozLmfhDE9XEVYr-UuTlIIQ0 zuGkTr-P;shJ&Wc44H1ToUvvx-vTHYv%>2z;z8~pTd5U}7VQ@i?`Wmo)!aQ=PONBe5u zg2I%X%pd)4R`J*de?+~iPKCt!2cb+i`4^wkqp^5BelH%!dGLP58?JbNgyO3_Ji9*ESEtg19`)o@T(t>@+W$##H}VG#_AUJ~xE960 zudDw~RwsMo#@}jdYqNXp$f=wf7rY*c-scko2fO;;!N}cIy&xy0`*~F+78=vRla9t{7d)4>iZjAL;TcxdkfvGtaUn#~_TYMF-N*=MvS2-u1 zhjeN1B-BtvAH$;A!$>s;d{3|q+s_KML@T^y(@|&RREz%T-mpKiE6*}x$XmwdnPWKA zzsbL=iq$g*@fkDBdw9$Cz!IoAp|nY$rjI|<7kCNv`QBT88EReClHL{D&2d{|GT;R1 z(VZD^f?RYQ1)LzWk2fbsTb>}^>)Zc|5_zOgLI|7~=kjQnk>DP7_arIpgJWjKPoL6n z0yVj%djmCS*cn|J%DeL6Za8Voz}fgqZEf}DDwOU7`(vDPKzIXB(t3Xt=dIvAp2wUO zgS#jtLE;(lArx=t;R3zMO z%Mh7O?&06u$k_QK(pa83h&{aJ_d@3}3ND85zch>j!PTqlIao}|_N7ZC?#~X&z=DOnz z*Bf`dWphg8f4i@8ZY^t-(+lTrtvS~?>H8wi-bK_^S2+nM{`da#t6DQ{KGNKtd8P*A{&YaR?ap|bt=yuJG zaO0)piz@UgyVnf;S9*r7l=+KJ!i2r3Ige@CGzJ}kagB=}#L#SzfeDPWlehd9M5*G! zH+T(VnCs;6oiq)MJVw*NIVolu@VYhiA`&i%)w4MTKtP?{^QZp#pUd;V56}Nz-m;s} z-#q`H>=-)#51R8Ig_vOyhw|Mi;4voLzckS;?rvzfMCMfN_x-fZTunP`S_~XQ@3cfb z6ukJwEsJY#H7cQZWs9c1Kn;dYSr1$imY!GZeg2)mpUCH(;;?mV{O^wC3VS-#AIrf4ocf1Vc>SEX&e^Nr@0|sqvod^2a$2w7jL7q8 zT>>1^)(77L>}8~vx4bj9BElzmI9#lXrN4_<*Vc{o9+u7#u@*<|p2_H*h&tR}H(zL$ ziB*TR_3Oee%fgd{Ia_|hayJY0!(j+IxawwkpXcQ6E!&6FC2(+pxBM?Z@Sb(D?01c1op^as3>@Y=kicS|zW#O@vQ;D&JIsE|y2(NEK z_fj1(Eo0{75W~`}{BA71c=Pish`T9o`7;o>6bQW3#4H)#MN@-+!rg8tLVFWoGs-{& ze`n@?!Q@_8+6!wwZ`l(jX@a-xTvP$`{)$tPJZyq@`K?GuxGR{8!m}%L6HNT6IMae@ z_2ZWoo7%-ABje|q_yykbPBc{JdQ8?!nY9`lb6HDAV0naFMJ!~GM12D_h2FBejWE|+ zb|D0o{vC*m%+cQKv%llySM6SK-G8zE$j;pEEn9|3DEK}+>om7?r>V|d*jb$|AlJy{ z%OON|*6V0la0F^pH}`6jd!TaPXmZc>mY++5+YkO#!G!wRyk#@cz)&AgFxm1-(@h`e zm?ZS^SL|E#@y95dt?ZA4gg>K|fvE@3J>8*(I*d0M!5eYK4^__{4YgR_nJV7MBZCHh z3z`N#48d(+qUrLZp$CUGjPMT|VU!{~Y9gSK1vFIVaxnRq1b@Q5aJ|B>wOQLKYl+EP z;w|s%X5~2XuMGaRVb-&3){ii-Snt6mE5^z9G`QmgS!W|FG~NUGp9_wO2;^P4%nVkX z5{Gby!%iq`g^ms`fjLysQZwTJX&s(MDb<%Mptt;V*n{IEf-XAJ_&;R*N75fFGaRi; za7LKpw;YMp$A@Bg(30RjEDO1ru|4>xahu@Z8Z0oU&>}9su){Z8C z@zP<FR>xJRvAGr7Fw(6zwt;JeyPX|FtzYcbpDuNfI7f;qiHR zi=_V_*W3-pWpE`rs4U zXKMKHMV{Z@@|8TDqHGaVm)Mjjv%?shUjG)cdWcPlk~7qn`Z*(JiO}6t^jTsCW{H2{ zuA!ZoA$A8}$8Aa0;$htYU$gcP_r{at1PLb=kz`==V5X|0kFI+HxM&9XHY{d5H zmc2dpa0iOT1nZVq_&t{o7o8U9OE1H-TECqQVfJhz_=^RFC-&mw&HWHsaGSb;5(p>L~XE7C; z#qd~@5;|+j_aGtoIBqu^RO=KQteb-UYPzw+yQ0Vh!@4+`DYk({tkyV1!ZVMZS%F{h z@CpB-=MNwYB%Fl5q6=BI#}O?n@bZ1ICVH>m18eXdCRG;4qm}-3!L`sDRO%s9G{UTa zz%VmSrO?8Enh65;Go>blElf1?LLNgu$MWqR*7!wk$6sQDWhq!E+rs507+TnaDV4=$ zhAB5KY|>b@_z=V#!k>_l)p`f}qJf&ru0AtRgPVZQXtn+1XFvTFgS$a}-Y})2aZf7B zG81LyqEs{Z_L>8N!S@ALSY`o!JN$xWCRc%f5lV0e$V8TKI!b`Wbmkv|J?oZtA|}St z$>vVsS7fg~U7p_ZN$7&$Bk)F%{u_evrpyWc>x0jmCgP&FfYEt>g9j2R=7Gdf!EWX( zSo957_$5ifBcWn~%dUN8Wad6^*$q%58rz12e}TgNZ;V7&-S4)h^c~KPWlfDX!T)5i zhD8it^mOno)FGVRyYg~WfFbT?h|o0|ho#YV^qJU;x0623nK~E#;PDZOXmg_hnnd_C z2=FELl0$o5%iwADy!tcCe{n{`B_YW1ZQBv8t^bEt2BEpX;mQDmz}-vqmY;;~3>M?S z!}kBn)n+(`WBQNwagI-y>BT#Enf}E#Y#UCiYCl_A@k#YS+yPamnVp{T<_yP9Pl6fu z*y$;Og%^@I z{M-u4*;4jF@m02b5W7O>PVN4e?6^0wYIpH!xfQKtBR>MoM$ffdAO%0crE{_ERCOVxGboLwbP}a8l+q~S9ULckJf({$9Ybjxr8bla~FyT(8Hwp15AqGgY3` zBRnT9I?9y!654NCmB^yHnxgXk*YahSz(%Yb@EXogRI93sVsu4}aDR1`wM9haQt!%p zU=Gw^<#wF8Mq%al+86E-t(?zSdr+rt%K2_{_Jh|v*_*ZK96a9hmi1$u4q>@ef?R<^ zSY8%DSX?uF(Gm9f;02$cwig;Jdi-n(FW$Ad1}`2AVM-*y-%KM=R?@8E)H?gtFzZKcs`txXe z%a33y@u=O5vQlKq;lpLTs?zIKOv-za5OGITXGbu6IStG+Yc<&}2kwD%(vhJOWgr@g;#L-@5&5#F3s&8qq` ze7ic~5enf~!Y#NO|Cqqn7y&2QAKl#M9B5Y6kGVhG9#OfgHyHo(jXxhvxc+9sYgUy; z{|D;$-)Q{17=N5KnGm>`aOXI@;*oCJACU!h`~D*}eV;is(eTe;3I2+I!X1~vj6)+b z;^gdFtM)u;BKW;!kHafagNblGGvm^xiLhB!f9C%g7YaKIvg0}V`I(omM(`#I9nX0% z&)5n})9OryBR)i}&P38;?A9$mnSv(66PR)$4B>eYZ5_ZOmzW~;h8J!)7@3E87}^^2 zq5*FA==kvwLU2q(7PNBMZ))Xc3@0-+e!+2dEb@lCXAmVFjdoesiW6`_fZB)zTnPl={;=bI?qaiYcd7i49=XRT?x5whb>))|WMJY}CV4qEF>XI`vzPSkqW_6iQxhd86mP4V|`aqi-0 zATn_A^Fh^Q#Vd5{z}Iz9y$^4u2oKsr=|KRlb&69M)x>8 zq&3@}*%dGQ-{Mn|@T*|<-r3GOoe zDM-P$@DGa8(s7!K;@5COMR`};V8%LTv^yZcTZ@c*dB2BCLxlHKO$o1A5V7k2T ztLr_`cw<-(cfGaTn<4Lck=|VHVQl~Wt{VOHcC?_Q34oS}M!TD}7b8)`A z`BQT|4i%Q3W+uI}Oaf}T3sLX^d0riR#YMQ3r>HtAp0Id_(0E65WamHap)d2-l*l5T)pyST4|!;(Ep9| z$iM1zYN3L>2Sx;$YJy-wEUHuFYxj0oJ!xMHZZb6quS z7R&X#urYVseLwS9{)QLbt8gFdRO21!?No3NiPh4?P1Vhnn#-7c zC-E`nU;kp@V4C;()sS%u{37Nd-_(R_d~usMU{^{F)@U#8OyVLEFKS17 zL|ONx{UAz5eYlpzR~Od%pSO`wa-G#*^}P{Zw^=Xda~G5D8aQ|bu4a*sA41z%b(YTc zH^f-w|BQ`_16pZJn&Lfx@at4^dA#MTf3NaQfkr+Olk)zLB{z-&S{Sg>^E+R2J_Ui`V0?F2(L4YeF5~BqeAK}v=0N-Ny z-{{9}n3-%V!WGr|`z#W%NA&&X+SN zV=weod~d>K{H+Z`tXX~3a6zG95ir9 zuhgD7Ib%o4lF`5apuXwpebdrGtPeW#j`_Md)Z=H{2o?N?enrJ&#G z#nbZpUErUxpr7mB5AIfU;^Oz={WQgyT3p2MWarMwE18?0TQGZ0;qRoxFNk9=nvd<* zxUrs+DY*rRQc{$QicQU%Iy2w-7HX#31qK4|-#SUza`{8&C{`{GzWX#0{_K1U^cR>ktkOZMCr%V$cm=k8cOW0E}& z#`3v1+4Dp!pNYwys#rcazt$gy&!$*D7#mv-!)IG8AB>Hiv3xK#_QvwT*w`P-2V>)4 zEFX*wXGVsUS*8y#Z#U~Htu^1;~X8OsM_BQ2H>>O3Tt59&NTmd}xx ze`5KdU87?8pk3o)`Ji2sWBH(6Gh_LnU2|gjpk4E0`Ji2kWBH(6OJez;U8`dG;2gZ| zFnsQg<%4tZ!B{>x2cL-LgLAMdmJiOs^|5?#4sMF&(;D+nEFT=NZLxfCF7J%xgE@2W zVfgHi<%8pO@GyMr?@~lv|DX?(X2zJK(1)#K`QUhUh~+a7^G_@vjGvydd@z2}V)@|Q z84}9}=g#n0J~(%Lv3xKmjEd!hIboc963mYo#m^swwJtvirNy)Ii{?76g|`R1?RFAN z@Jl`MSJ%KRF7!)CiBm(iIBucw({zp#zc2~63X7=B&MTSa#9u{yJ?hmWLH)Si>p_?^%Nt zc3DG9JSFDmR595Ki>zUVgw59QkpvH(c=MCoM#3a(sF1MM8g@wF8w4hc6@1oknS^_+ z!3tZf!3xdI9V&{oLb^3rp~xDn@TxU*)B(>CldbTOHM}O_3u~yAa5RpZsro<(v#sGJ z2|rka6|(si5PXtLB>dePtnjflB$(T3$2m((w!%1TxJJU?ticKi?Ny2uMp%Ot=2?Rk zp0Qud8~vP)^L@CPpu)2FU8=~NlYFpVT?8SC9JWAJra&i zH94JRD-_GntP3_OtP+s1ZsSfo-pyMqCR^bT*04dszpTLu1A3@fD->CS6>hc$E9{h^ z**a8g^@(o&=ft`dyG{EY--*dq=)mXQ_#|5)%Nk}#SYr)V*kTPoO32Jm3@e;%4OW?!3K!Q<0UM&1}nT`4M7Qs15}UR63()QSrV?ahSd_bT7wnrehBtG zhPJ_5aYY5Cx#7K<273JMadCF5DSwb#eB9XN6C_%b)4XY6anX!af6?568TiSlRBW_3 zNiA5y*sPo}Bb>O4TXL_ZvE7`;jq%Ikcs|A1{VV%hdvRl1&CM^wm1UVp9;2(9(T>5U zsCS{NW;3+5m%HUA!=zP8cN|l_>@%FWna!K9z6s3}r_RhPapI0}+Hwm_tvw>{xTLnt zJxLeDwNC7m^w}az(eZub;@WzWt{N_pU=henWQ zq2lol4?|qsk3TfSzvlT%++jcJIb6rS5f6w$$J~9ygzH0i8Pm6<&^@;N!kYU@h+pm` z$J;~P39>!BEh6N&2)Sc~+#Yh4B6WZ~N^(2M#gaXbE@F18&VXEElb$k3>|1`0Mv}d- zd0z1{*B&>;@w_^RsyVPQ9R<0SE`6Ren9^I?MG^98kcV3@{7^}9{Ag)xC*J|$=LpC% ztk)x^LVOU(&jKXf8%*sE_Dl73JUYdKy$oeO!flnE;#R}+po!mF>PJXA!6vOU zNp_=yx$I^Ki@Q;7uR*@gX1T{?dBv&+a26%Ue;}2)lCU`B$1{N`?XC8t$#;%bSHv^5 z+^XMQMRl1~?=Y#iSoJrPYPVnLX?I>I+uawA`E#_m^0@IATlL9i^t??fkMm0>{W z>{86L*_6evI-5p3Z)%b%)f@zy^n&pmV$~N-5m#IF&iM?x-m0sO^Q%_<+Jt@Is*jme zyL-fpcH@Y$-8^Cg?fwz%cI$|;-9G99+3q0GZa0rO3D^xJ&mmJ)yN%@e)r=Rro8)<^ zIWva#l%91*6RvlrL)Nrls@-7nd^nftT$}oXX_wt?^6bBosdm%p1ju&ZiFUi?MA>dT zb%AVmo@lq5PON`uzX`J4YH9=7?lRHGZZLWBnR|=2nLNKFQ~g!yagf{a+KP`mOwX5g zEK(**=Dbu=$Ln@!%>SrO`DOt_zb%#1=Jz&fwP}8wS0z1aD$!digPdxU%(*f%BIWWr zDSwy7>b)VE)!S~p@MU52No%(tMoyLNHg9A^%7i*8OCnNksgv?jM9MohW$Qc^w8N^m znt_y{tCVMrnU=a*^@YpnJiw~exLZw*pKjGZm{50F^`M8TuUWN#+6U6QLOx(qJ~y3e z_YLW0w+wmw?Y5!Ej7z(BNH4p8$g{|9A<}NQ5osTYl^s8{+ucOk?S>-lb}x~o+5JS1 zk12Ljk+R)Sq-^&T8Od%d(r$MYDcfDeE|BfUBJFlhk)mfcC@__v#g^m$1> zgCX0!M8=8JZXxSnw-jj~8ez9Pi?lx^yXRl#xbR0u`0+ep)bFHnK1|hKqUWDx#Q<$)3Hz<*gH4!Z_bNU2FQjU>Eb}1ST}#^Sh9x7| zO-oN@QzjkHFD@TdrYSM zh?IGCQl7HfeP*`UVAY2cS=gb7d|oc1@o^)bC5>fWTqmV6BIT|+Dc?q<#PK_njCQT* zJg-&%WIE;qtL`?3F4wA0nT`)w^$nAExmDMg)D2d}x9*eUH%qI6e88rZn|yZTm~M9S zm;=J@AJcC4kUe*s!C`ljJ-3^|VK%;n`pDtXDVFS+%9JZ2QUa2h`x)!C!_;?|Ro9vUa=@xjn(F_#i(@{X-R5BbT`I?% z-R<$*WQN6aUFG?JnO8SUS5_n%mwJ0fz~O(@!5kFeXFDB5dn zs1MAg!#+jeFt860DBFh!T_D@%2(;Tr2pmNA=>aEd``~~RwS8tlpYM9;SZ_BqPw45Y zy^&-$!#rP^bE~hCJP(*<{#24%beOuveVV7J*=!;ac9V`RJ6)(!H=2)o^I^E`VQ zi?~ino*iz9Qd!S+5xMLJ9PRre>~O?J;umJZbKES6TIK z<9Ul!Uofc;N<9V{pO(z{TO_m9KS<`;+En{|y&#_>na6R8WUlX~OJ?)uNcJo>rC({) zverz!O)C4)K6&!2Hl9x_i6hNEjAHBThNI_92C(~Wts`W5HPsfP=TTG62&t@{-HT+) zN@Qn??S>@Ro_9ys?XD#4Z$;Sc)+Ft}MA+>npQpBnHMA;gbxvQMF}EJUq+6x3FSkf$ zt-g@VTG_2l+S~UF&mwkzljCASgx&5ZdLA;RTa~5XEjQ0TQ@Y&-HSLOsU^hT%uZghR zT~OM)r-f@WSMtrUUn!XzIrdqhXKNuF8+uX***+v>1MP#t9+2&`Li*dsgp}>0Lbk#_ zEu`H(D5Pwk5i+KIJjk(QpA1sAPX}2&`+$&n?L$JI`t~^??e-BN^V-LReIVN>h4isc z3t2b&z>s$P(2#cf+>mzr?2vZ*_>gw{5Z57u@s<=hC_?ht!sGm_mL zj+8lkmPF*RkLTLLZe{k0-95(Uq6ddK-br$t3gnyYIDM`Fr+|6jOz=W*lH;W0faAdt z;B?qe1}}!*AIx{0lTQR^z}^EK2m3*6fL;V10564o4~PfuDIdzd1)K)^%ivUS4LBC* z_ki^OBZw`rl%=u_b7uKLH#Cdv}n29YOjvmE8g9_hE+PoCo_BkbbX%^jjzU zt>C%PS1J8Er7x7d2poy@8A_k1^pUb>fjLM&N$F`y?;?9gumI&IfgA_Fr8~|!@c#*9 zeZB#cp>LP{Ly-0UD|j~S4}^JMpdj5`GM z!JZD%uLsx$dMDZ2fM-E(uJkyN3lvfl%;9rM89u+IVMHyxzkMY4|q zd0b8bd0Ym7ry{)%NdImikN1(Xw*(n?PO8g1ko6h^vR;|sDe%t#nZGB<<8h4a?Lhh` zgY^FvC*8?N-wV=zJIMOIE&C>r<=q1^->o3?T?Gz<-{m0l6@omkC(1q+WWF4*8|$4feRG#uO$o%U-gh+Wz_6I=v-wx9M8W2x6Qx<~sp9Au^=oDwV*aZ@=AQ~;%1XHeWc~|4=09EbVIcEofXv?u#8i>e6{LR$kp9WC$Ak1g*xv2` zZ$V5EDSJWsZwKkWS@xGf`mY1o|F?ozho!6n>3F--2xadmyH+ls7<@w*ln*u~zoSLH5@@ApI-A6Oeu_NdNgD>sKKA z6p-yX59|%Q52W8IApQEu-V@~f(H`Xd(E{v+^d=zve?HQkKfVTO{}N=}e}FxquLbG% z2*|j1%6<#TxMd*YE(9?prpyKDUjQaRA20ibAmg44vYqK5+u07pl$Fv7WWEHDBH-pC^{bi8;>p<4)VcG8mSG7H|LNZq#Kv7pCy@R}fNXEP>^~pjmiG?~CXV;DAoH&QnSTY?5%%jr z=D!L=)|AU+KOe-YpK`X+hl7kiK=u5M7#bKS;kjK=#*i+4+-XtnaxX>ze_# zM*0aL{kwpyM?2XMHN*RA(7y+n9t4^GsqBw|t)M>uUW)WPL8jjzdoGBkq>KYEMf$lQ z`|mW_hk~q6Kalll2cqbdR^X-36F|oM0ga`7A2|MbE*js~)%iqjSM0zcP)BguB z0s3x`_8lPO4n$D4vlqyAdch`0PXd|mH#oDLZ$aAkf-L6)kmbAqdSHJAr2n%Z%Xvih zzkn>~N@Qj^b3m3e7L14Ac_8zh2C|&~vY!Z=`XRWfAIN-O5T6wO#xnE$j3CVSHAwrH zpeYXu?1`gAZqif#(ml@;-xOaF?+`h!&@V&mEp`@<5_e%R)9(}UJ#n+RL0l(3DLy3L zE#4-s6t5Sr7B3h1Uw^Q?eDM;I?@-cyj(ECwl9(a(61#{U#MWX{u@)yC5h-eOm=g_t1z zgvo;Cek<-4`AC=c_r*8Gm&NDAzljfvtHnQwH;5JDVsXA$EY1)oiToK>mOoM)A@X-u zY40I+6x)c&BA<5C?;s{Sa=*Ao+#!A-z9qgQ{zH69d_=rQ^lZP3p30r`T+^#S$A#QVfM#hbic%3*!JVop%{@Bd*e^=D?J8`M>=_0Ss7y^m>pB~6VxXzIuh<_DVh?k0Iio8zJ zpD+KAABk(l8^t2=Z1H$8UfhoBBlE8lZxKtxbH(0bqWC$khs^i9_$Tpl@dB~0*i77w z>ml=P5dSPL6nQ;mdWMKs`;Gn;F2=OKDy|l<7RQTUqSTwj^*b&;>nQNLE4B%UO; z7x|x)(T_jaPOcHJ6Q_v$p9PrSQT!2uhWfkWW8zYAx_Fv+tau35b>`cu>-!tx*=Pq` z5>FEci~YpzBEKI(zc{f5?V!%~le@)_#rMQb;(GBu@lKIH&By#p#YN&gu~3{QUM!w3 zo++Lp@;?`5yc5J!k^lDu?JdP7;vw`a?K~dj9&v}bReVEyQG7;xOuS#bUF5r)jJHJO zd!5w%;%t$}nRdPdN}ea4B@Pn@h`q!vVtbMQi5c^I#Gj#1-!JYJKNa5>Ul%usd}S4X z5+4`&YAf|S#2ds45wB00bi7k#h<8~G@t%U=IB}FXLOfZ_5POTA#iK+#g*I{ULW5zA z#_a)dx42z=Puwi77pufa#rwoRi8qSZi;Ki*;w9qwVzzjSI7q}ju&F2R^$al$8Ulv6 zmo>z4tI_l&u;=0t3^@s>>^N{DL=tsql?vuTCnrOnhMQ1yP2xB)M;tB=5POOpMecVn zU%dDuDop(=al81g_^PP=j>N~LuNH3+mx@=5CE|2(ym+p7n#g?-mfu@ER%|0CiidPx zu}}P5{6OS>2;)32J}%xP-YPB=7m0Jl86x*Z7>D~JTUWq*AmekQ&zz9y~{9~SQtSBYife6diRERGg^;xI8y z>>{=klf_@P9=7ZLFQtDVZWNyt9~bWtZx!vjev$M!VxBlg%oa};(?z>(KU#WAF;2AW z^e?m?{!rX3+I9Kgq~9z4L97rLinGK^#F1i_I8f{%b`rfJ_w9IGf5Lj3tQPr#xH&&W z?%Pp+R(wRfQ@lYe7Z-?^iu?%#<{u?yiQLbly_n!;?KBWp#HVEQ{?_0?VH4B#5Lld#g*b> zu~eKXUM!9jPZ9fx-Nd8B<|6m?SpN6o9`R%GZSf`XY4Kt4F7YPudhrUeSez=35wpdU z#dPsF@o2H77$^RK`ybYKkH{~8P=8xoFFqySFWxFH5f_M;iW9^f@nkVw>?R&1CX2t~ zzKZ2@Uz7Yod|!M`{D;W@9*utYh<^|(#D(H4F;^TVo*@nrdyB`4t;GcK2i(80JpQL> zW5m{Cf_M;#O#fQ6_fPLge?@#oTqFKjyiqI@@kYCehu7x}Cy5t`r;7u`p5oCW z-nBLPe#817V&Zq=Zt)}WEpdamR$L?AA@)L$R#-FGU-2~i2Dml{M!^A}vz2at!ISrO z^yf=q{NP(J4xhzcCx5n+=}AhzQ+jLZYo&LP{AX*6ycLSa`&Y*6sdRoTm3o@= zuF{7{A4(nhZ&rRDZ~6~c`X$nR(s@75^ik4RNKcyKw(kMzhfS z&y>#n1;(Evy)DK&_4(3Il)hLx|3gitFOhEckD#xT&hw7-c|`SDEdSe-{zvI|OaH6< z|04f&((jkf^PS~AD1YwXF#c0Y-=*{?l>V#IpHX@u<`w3zQaa}y>aEp({4yx@4${w; zzFz*9O5Y?sAbpGUJEU)u{&(p+rSsdRjK5d<9_jm~^I;s*4@y5;I$vJo$Ls?lJyrTS zO7AIsn)Ed3S4p2N{TAsy>5oevB7Kwe;nF{oK1%u_>EoogO?2x!U;2sC7fT-@eTno* z(pO2JCw->$Rnq53e@Oam(l1opMls-hd*$+qj;nKODWO+X6d!>((9*1=))5l5gNFC=}vCgM1(l3|J z=hjTWN_skV+=H%{J{@hwJO7S-yZ9ICNN;^Ud&6<=#$Tq}w~6uQyh$Ifbf_jBFdy!t zG5}LRkNIk2ber`RzqMkmlp04W>tnOz#5E;K`J^h$^x?_KVsgYl~&c!cb z%q=a+Ey|zgPX3$B@1ZpA5!M{=gu_B)bplXnm@JF$kY8r=65G@>;DP{!%fSd zUQm>uJG*$AzcAmp%Q6)|OffgtUo;KBWYK8#BAw?J6wN5iFD)+0otYM3y%zj6+U z=8)caLONd64Ihn&veMHsqa>scR#^k1IYdjyh*JIZj0}Yw6eVOv)R04>k)ox&v+NBSSasbl@Myu|?O!ZxQwCW9t)}TQHly!(0 z?T`<$hdk8L9_0^Cl$9zymlrjckVs5m$gZf8l$DsaEj^LpFQED|P+Uzn2 zU!7{S@F7E@CPXP?NM@7+H6&WM4~ce0Wu`?96{Qn1)1p*2Guj!I8SRY9Opg{S+JVZ9 vc4#xB9l=a|x2n-@&y04UGBKSto&)EgdtJA4q?qB1@a0Y~$(x;@<~aWk&8)D; literal 45736 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 diff --git a/lib/liquid/block.rb b/lib/liquid/block.rb index 8ea87b0..0b49a81 100644 --- a/lib/liquid/block.rb +++ b/lib/liquid/block.rb @@ -109,7 +109,7 @@ module Liquid end end - output.join + output end end end diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index b9d9136..0f08ec6 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -115,76 +115,76 @@ module Liquid @scopes[0] = {} end + + # Look up variable, either resolve directly after considering the name. We can directly handle + # Strings, digits, floats and booleans (true,false). + # If no match is made we lookup the variable in the current scope and + # later move up to the parent blocks to see if we can resolve the variable somewhere up the tree. + # Some special keywords return symbols. Those symbols are to be called on the rhs object in expressions + # + # Example: + # products == empty #=> products.empty? + def resolve(key) + case key + when nil, "" + return nil + when "blank" + return :blank? + when "empty" + return :empty? + end + + result = Parser.parse(key) + stack = [] + + result.each do |(sym, value)| + + case sym + when :id + stack.push value + when :lookup + left = stack.pop + value = find_variable(left) + + stack.push(harden(value)) + when :range + right = stack.pop.to_i + left = stack.pop.to_i + + stack.push (left..right) + when :buildin + left = stack.pop + value = invoke_buildin(left, value) + + stack.push(harden(value)) + when :call + left = stack.pop + right = stack.pop + value = lookup_and_evaluate(right, left) + + stack.push(harden(value)) + else + raise "unknown #{sym}" + end + end + + return stack.first + end + + # Only allow String, Numeric, Hash, Array, Proc, Boolean or Liquid::Drop def []=(key, value) @scopes[0][key] = value end - def [](key) - resolve(key) - end - def has_key?(key) resolve(key) != nil end + alias_method :[], :resolve + private - # Look up variable, either resolve directly after considering the name. We can directly handle - # Strings, digits, floats and booleans (true,false). - # If no match is made we lookup the variable in the current scope and - # later move up to the parent blocks to see if we can resolve the variable somewhere up the tree. - # Some special keywords return symbols. Those symbols are to be called on the rhs object in expressions - # - # Example: - # products == empty #=> products.empty? - def resolve(key) - case key - when nil, "" - return nil - when "blank" - return :blank? - when "empty" - return :empty? - end - - result = Parser.parse(key) - stack = [] - - result.each do |(sym, value)| - - case sym - when :id - stack.push value - when :lookup - left = stack.pop - value = find_variable(left) - - stack.push(harden(value)) - when :range - right = stack.pop.to_i - left = stack.pop.to_i - - stack.push (left..right) - when :buildin - left = stack.pop - value = invoke_buildin(left, value) - - stack.push(harden(value)) - when :call - left = stack.pop - right = stack.pop - value = lookup_and_evaluate(right, left) - - stack.push(harden(value)) - else - raise "unknown #{sym}" - end - end - - return stack.first - end - def invoke_buildin(obj, key) # as weird as this is, liquid unit tests demand that we prioritize hash lookups # to buildins. So if we got a hash and it has a :first element we need to call that @@ -229,8 +229,7 @@ module Liquid value = obj[key] - case value - when Proc + if value.is_a?(Proc) # call the proc value = (value.arity == 0) ? value.call : value.call(self) diff --git a/lib/liquid/htmltags.rb b/lib/liquid/htmltags.rb index 78424e6..1b40042 100644 --- a/lib/liquid/htmltags.rb +++ b/lib/liquid/htmltags.rb @@ -6,6 +6,8 @@ module Liquid if markup =~ Syntax @variable_name = $1 @collection_name = $2 + @idx_i = "#{$1}-#{$2}-i" + @idx_col = "#{$1}-#{$2}-c" @attributes = {} markup.scan(TagAttributes) do |key, value| @attributes[key] = value @@ -18,6 +20,8 @@ module Liquid end def render(context) + context.registers[:tablerowloop] ||= Hash.new(0) + collection = context[@collection_name] or return '' from = @attributes['offset'] ? context[@attributes['offset']].to_i : 0 @@ -32,26 +36,15 @@ module Liquid row = 1 col = 0 - result = "\n" + result = ["\n"] context.stack do + context.registers[:tablerowloop][@idx] + context['tablerowloop'] = lambda { Tablerowloop.new(@idx_i, @idx_col, length) } collection.each_with_index do |item, index| - context[@variable_name] = item - context['tablerowloop'] = { - 'length' => length, - 'index' => index + 1, - 'index0' => index, - 'col' => col + 1, - 'col0' => col, - 'index0' => index, - 'rindex' => length - index, - 'rindex0' => length - index - 1, - 'first' => (index == 0), - 'last' => (index == length - 1), - 'col_first' => (col == 0), - 'col_last' => (col == cols - 1) - } - + context.registers[:tablerowloop][@idx_i] = index + context.registers[:tablerowloop][@idx_col] = col + context[@variable_name] = item col += 1 @@ -68,6 +61,58 @@ module Liquid result << "\n" result end + + + + private + + class Tablerowloop < Liquid::Drop + attr_accessor :length + + def initialize(idx_i, idx_col, length) + @idx_i, @idx_col, @length = idx_i, idx_col, length + end + + def index + @context.registers[:tablerowloop][@idx_i] + 1 + end + + def index0 + @context.registers[:tablerowloop][@idx_i] + end + + def rindex + length - @context.registers[:tablerowloop][@idx_i] + end + + def rindex0 + length - @context.registers[:tablerowloop][@idx_i] - 1 + end + + def first + (@context.registers[:tablerowloop][@idx_i] == 0) + end + + def last + (@context.registers[:tablerowloop][@idx_i] == length - 1) + end + + def col + @context.registers[:tablerowloop][@idx_col] + 1 + end + + def col0 + @context.registers[:tablerowloop][@idx_col] + end + + def col_first + (@context.registers[:tablerowloop][@idx_col] == 0) + end + + def col_last + (@context.registers[:tablerowloop][@idx_col] == cols - 1) + end + end end Template.register_tag('tablerow', TableRow) diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index 4e2fb2c..28957af 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -31,7 +31,7 @@ module Liquid context.stack do execute_else_block = true - output = '' + output = [] @blocks.each do |block| if block.else? return render_all(block.attachment, context) if execute_else_block diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index 8d2b27b..dddc373 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -50,7 +50,8 @@ module Liquid if markup =~ Syntax @variable_name = $1 @collection_name = $2 - @name = "#{$1}-#{$2}" + @name = "#{$1}-#{$2}" + @idx = "#{@name}-i" @reversed = $3 @attributes = {} markup.scan(TagAttributes) do |key, value| @@ -87,14 +88,13 @@ module Liquid limit = context[@attributes['limit']] to = limit ? limit.to_i + from : nil - segment = Utils.slice_collection_using_each(collection, from, to) return render_else(context) if segment.empty? segment.reverse! if @reversed - result = '' + result = [] length = segment.length @@ -102,17 +102,10 @@ module Liquid context.registers[:for][@name] = from + segment.length context.stack do + context['forloop'] = lambda { Forloop.new(@name, @idx, length) } segment.each_with_index do |item, index| + context.registers[:for][@idx] = index context[@variable_name] = item - context['forloop'] = { - 'name' => @name, - 'length' => length, - 'index' => index + 1, - 'index0' => index, - 'rindex' => length - index, - 'rindex0' => length - index - 1, - 'first' => (index == 0), - 'last' => (index == length - 1) } result << render_all(@for_block, context) @@ -129,6 +122,39 @@ module Liquid private + class Forloop < Liquid::Drop + attr_accessor :name, :length + + def initialize(name, idx, length) + @name, @idx, @length = name, idx, length + end + + def index + @context.registers[:for][@idx] + 1 + end + + def index0 + @context.registers[:for][@idx] + end + + def rindex + length - @context.registers[:for][@idx] + end + + def rindex0 + length - @context.registers[:for][@idx] - 1 + end + + def first + (@context.registers[:for][@idx] == 0) + end + + def last + (@context.registers[:for][@idx] == length - 1) + end + end + + def render_else(context) return @else_block ? [render_all(@else_block, context)] : '' end diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 1d01982..b26825b 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -121,8 +121,7 @@ module Liquid begin # render the nodelist. # for performance reasons we get a array back here. join will make a string out of it - result = @root.render(context) - result.respond_to?(:join) ? result.join : result + @root.render(context).join ensure @errors = context.errors end diff --git a/lib/liquid_ext.bundle b/lib/liquid_ext.bundle index e35a56bc9bd018ce625c29d548dbb8bd3b84642f..68dd5b6622ab9fa3d6be54dd3a2b82c6db565f1e 100755 GIT binary patch literal 28572 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 U-rMiKd2he