python3-pure-eval-0.2.2-1.oe24090>    fF ;G|`u` - N?kUSZ+']:R9aZhotbG; 䪜[¡@ T߾ +U҉#JՁ@UY2H-&ǡv"l!$f[;=QƓ@t0BZf(F35ؠ$!Ӆ J-5E:2ߏ5Fo!}dE+yssQ*ũNT7VGQ.Kյ&uy|Wn#=t31ee'@9è'^ TlVNqL@3k0B]}e;b%`)OuV9dar Svϒ@2ޡ.WqXhwsli99be55c1522f0c2fd1959ef7da7378276dbc591b58f817b688661297dbe546ea8afbedde38ee507d87037849253c17f00de80a069HGF^5.{7>=)?)d # Rx| T     tnPh( 8 $9 (: XF qG H I!XX!tY!\!]"^$Wb%Ud&Be&Gf&Jl&Lt&hu&v'0w'x(8y(z((())D)HCpython3-pure-eval0.2.21.oe2409Safely evaluate AST nodes without side effects [![Build Status](https://travis-ci.org/alexmojaki/pure_eval.svg?branch=master)](https://travis-ci.org/alexmojaki/pure_eval) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/pure_eval/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/pure_eval?branch=master) [![Supports Python versions 3.5+](https://img.shields.io/pypi/pyversions/pure_eval.svg)](https://pypi.python.org/pypi/pure_eval) This is a Python package that lets you safely evaluate certain AST nodes without triggering arbitrary code that may have unwanted side effects. It can be installed from PyPI: pip install pure_eval To demonstrate usage, suppose we have an object defined as follows: ```python class Rectangle: def __init__(self, width, height): self.width = width self.height = height @property def area(self): print("Calculating area...") return self.width * self.height rect = Rectangle(3, 5) ``` Given the `rect` object, we want to evaluate whatever expressions we can in this source code: ```python source = "(rect.width, rect.height, rect.area)" ``` This library works with the AST, so let's parse the source code and peek inside: ```python import ast tree = ast.parse(source) the_tuple = tree.body[0].value for node in the_tuple.elts: print(ast.dump(node)) ``` Output: ```python Attribute(value=Name(id='rect', ctx=Load()), attr='width', ctx=Load()) Attribute(value=Name(id='rect', ctx=Load()), attr='height', ctx=Load()) Attribute(value=Name(id='rect', ctx=Load()), attr='area', ctx=Load()) ``` Now to actually use the library. First construct an Evaluator: ```python from pure_eval import Evaluator evaluator = Evaluator({"rect": rect}) ``` The argument to `Evaluator` should be a mapping from variable names to their values. Or if you have access to the stack frame where `rect` is defined, you can instead use: ```python evaluator = Evaluator.from_frame(frame) ``` Now to evaluate some nodes, using `evaluator[node]`: ```python print("rect.width:", evaluator[the_tuple.elts[0]]) print("rect:", evaluator[the_tuple.elts[0].value]) ``` Output: ``` rect.width: 3 rect: <__main__.Rectangle object at 0x105b0dd30> ``` OK, but you could have done the same thing with `eval`. The useful part is that it will refuse to evaluate the property `rect.area` because that would trigger unknown code. If we try, it'll raise a `CannotEval` exception. ```python from pure_eval import CannotEval try: print("rect.area:", evaluator[the_tuple.elts[2]]) # fails except CannotEval as e: print(e) # prints CannotEval ``` To find all the expressions that can be evaluated in a tree: ```python for node, value in evaluator.find_expressions(tree): print(ast.dump(node), value) ``` Output: ```python Attribute(value=Name(id='rect', ctx=Load()), attr='width', ctx=Load()) 3 Attribute(value=Name(id='rect', ctx=Load()), attr='height', ctx=Load()) 5 Name(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30> Name(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30> Name(id='rect', ctx=Load()) <__main__.Rectangle object at 0x105568d30> ``` Note that this includes `rect` three times, once for each appearance in the source code. Since all these nodes are equivalent, we can group them together: ```python from pure_eval import group_expressions for nodes, values in group_expressions(evaluator.find_expressions(tree)): print(len(nodes), "nodes with value:", values) ``` Output: ``` 1 nodes with value: 3 1 nodes with value: 5 3 nodes with value: <__main__.Rectangle object at 0x10d374d30> ``` If we want to list all the expressions in a tree, we may want to filter out certain expressions whose values are obvious. For example, suppose we have a function `foo`: ```python def foo(): pass ``` If we refer to `foo` by its name as usual, then that's not interesting: ```python from pure_eval import is_expression_interesting node = ast.parse('foo').body[0].value print(ast.dump(node)) print(is_expression_interesting(node, foo)) ``` Output: ```python Name(id='foo', ctx=Load()) False ``` But if we refer to it by a different name, then it's interesting: ```python node = ast.parse('bar').body[0].value print(ast.dump(node)) print(is_expression_interesting(node, foo)) ``` Output: ```python Name(id='bar', ctx=Load()) True ``` In general `is_expression_interesting` returns False for the following values: - Literals (e.g. `123`, `'abc'`, `[1, 2, 3]`, `{'a': (), 'b': ([1, 2], [3])}`) - Variables or attributes whose name is equal to the value's `__name__`, such as `foo` above or `self.foo` if it was a method. - Builtins (e.g. `len`) referred to by their usual name. To make things easier, you can combine finding expressions, grouping them, and filtering out the obvious ones with: ```python evaluator.interesting_expressions_grouped(root) ``` To get the source code of an AST node, I recommend [asttokens](https://github.com/gristlabs/asttokens). Here's a complete example that brings it all together: ```python from asttokens import ASTTokens from pure_eval import Evaluator source = """ x = 1 d = {x: 2} y = d[x] """ names = {} exec(source, names) atok = ASTTokens(source, parse=True) for nodes, value in Evaluator(names).interesting_expressions_grouped(atok.tree): print(atok.get_text(nodes[0]), "=", value) ``` Output: ```python x = 1 d = {1: 2} y = 2 d[x] = 2 ```f@dc-64g.compass-ciMIThttp://openeuler.orgUnspecifiedhttp://github.com/alexmojaki/pure_evallinuxnoarchl;( ))[\kk##;D?AA큤fCfEfBfBfBfBfBfBfB_fCfCfCfCfCfCfCfCfCfCa%n_a!a%nfA9af68b6ab0f56e8a0e07e01eb7cf5b54e1640c87494d12ed7685995735ecedd16e58c0a467241f475fd516f08a1702bb922994e9a929febf9611819bc959ead15aa2f4a240d2a1c123d48b7ad89409e2bf5fc8d2d5208e10d6113557951e5ed377bad3f8dbf3432661fb8fde64a9688fb3022814309b9666b08bb2fb57c1019a01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546bc6bc884df8f8627031df19665d7037d3e2e0ce4e078a59378ca59a8ddded08b56a3db8bf3c37c1cdd7b0bdd0d2c1e27485fa37b4da562103af547f47841b823a7a93f5696ef3da1601d05b42ff1df0d401659e14a09f85159116a616555f5ddeab130c1950af9772ad92b02586d5e3e93b6cd21e7bae37a935b7489ef7b0427aab130c1950af9772ad92b02586d5e3e93b6cd21e7bae37a935b7489ef7b0427a822e816e3e60732a8ab40fdf152d1c4fd31ad98c895e4f25a44d825fca42bd0386dba947781d909bac8fbed596a88c943af160d561e029080707b9823d623b9447a8fb44dff321945d3606e5982dd4ac457c49fdf99922ab81e2b429d5881d7e47a8fb44dff321945d3606e5982dd4ac457c49fdf99922ab81e2b429d5881d7e51311f0989bad1ce28b0b02f91e6353ad25814962af4c700b06d646678003abb6a9917aac988dff659d21259e3b72a35e19f988bbaaa0541e85e8fad894b5ea42518b5f8e039a275e3f4a29b92bde554b7cdd64c2cdbe88f64191c597a44a3772518b5f8e039a275e3f4a29b92bde554b7cdd64c2cdbe88f64191c597a44a3776f1b215a0855c026b07557eb35d5cba878f950ea5a3f3d5a0240744f7c61ff7426f00cdf411071fed140a1b77d84894f5b62c0429b90f9e9a8f4565e322857cac37c58268ef5cc0ee90e717ae71afabbc14bf20bc9ec674028c2522eebf620f579223e955c81cd85b50f6bd140faef8573e1429440ae1bff1a8071d4021f5877a4a876fe1985354c06d09c5b2f5f2ac5d9a2fe7985a6045b47c5fa20f66bd3carootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootpython-pure-eval-0.2.2-1.oe2409.src.rpmpython-pure-evalpython3-pure-evalpython3.11dist(pure-eval)python3dist(pure-eval)@     python(abi)rpmlib(CompressedFileNames)rpmlib(FileDigests)rpmlib(PartialHardlinkSets)rpmlib(PayloadFilesHavePrefix)rpmlib(PayloadIsXz)3.113.0.4-14.6.0-14.0.4-14.0-15.2-14.18.2dgdPython_Bot - 0.2.2-1- Package Spec generateddc-64g.compass-ci 1726657856 0.2.2-1.oe24090.2.20.2.20-metadata_list-compact_tlv-python3-pure-eval-0.2.2-1.oe2409.noarch0-metadata_list-compact-python3-pure-eval-0.2.2-1.oe2409.noarchpure_evalpure_eval-0.2.2-py3.11.egg-infoPKG-INFOSOURCES.txtdependency_links.txtrequires.txttop_level.txt__init__.py__init__.cpython-311.opt-1.pyc__init__.cpython-311.pyccore.cpython-311.opt-1.pyccore.cpython-311.pycmy_getattr_static.cpython-311.opt-1.pycmy_getattr_static.cpython-311.pycutils.cpython-311.opt-1.pycutils.cpython-311.pycversion.cpython-311.opt-1.pycversion.cpython-311.pyccore.pymy_getattr_static.pypy.typedutils.pyversion.py/etc/ima/digest_lists.tlv//etc/ima/digest_lists//usr/lib/python3.11/site-packages//usr/lib/python3.11/site-packages/pure_eval-0.2.2-py3.11.egg-info//usr/lib/python3.11/site-packages/pure_eval//usr/lib/python3.11/site-packages/pure_eval/__pycache__/-O2 -g -grecord-gcc-switches -pipe -fstack-protector-strong -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/generic-hardened-cc1 -fasynchronous-unwind-tables -fstack-clash-protectioncpioxz2noarch-openEuler-linux-gnudirectoryPython script, ASCII text executable, with very long lines (417)ASCII textPython script, ASCII text executableASCII text, with no line terminators PPRRRRRRRRRRRRRRRRR"W{.D,utf-8f2687ef77a8993dd86883a28c7c0c8d3b188df939aad47f9d77acae8a4ce1304cde9ad5e451dd36b4b5dd579c1cbf701d2c7489b3461bdcf0d8047e019a2f861?07zXZ !#,ȃff] b2u Q{LY\.?U@+@nWZ{l^<@:(5cQMV^g6V'EV'R^gMUm>*Z*|hg}28Wr RfL&cɱekR§zݳ ef2(t62Żv萉>ڧnB=~ɼAeV*$ k,1g$Rx%,$љu#,Y Fe++5BfG9˩yـTQ5Rw3BsAELLeZ+gcsۄxl&Z%y $4J56.\,2rRcvϬ+vl(lxLiG7ڞ~E8I=mWgham߇:<ڴ;UtcD$}`@}j|wG>6 fW/T_lΊ LA7cmug4?29~5-DUjBcP-e2"M4sy"x"zd秖?cB0Yjxd]VhdSDi52V51EKF7Z>[Cz N ^fw ]"d$ztz9,^$Q甋K fq­K qs[ N\w^-*[<::wceFʍH*b ZCg"36 OF[oc,qwx`t3CZH♼yLsîG@kQg~xA!C.HЧGB9^ۚVQ_of;mP_' ʼyf%-S ?j/;{$_4E?˨čeZgE1#734!J~ ĉ°oc!1j/5u92S΄ϣØa &RJ)e6[)=咯huV\&E @o@:rhGGsXM"Va_e٣Npqʤp?XBPmVhoY|EjUm LP|}"\}u(;|lx-A sOc@5eWx?q]: 8+քOx?َMUʭ{'1@4Vξ65kV2֣5GE5[Z{jT'ڀ[AhL yBD4.VX]fm ,5BC ZM6;9ɌU l' yL5rovۜ+Y9([T[HoEZpK˩!0@c?Il5~o3&eFUL">8J /\> hR׬y eTNLs<YoOO{;*cE !:צxfHÑ(SVEHk9vn ln`3Pz* i+S[7c 7gT Y$ %?/U'HXQDUeJKL]왁Dis4饙$<Te=K&Uĉ+?3n;+,0S_3YQ1gTa8U1 }_p*u2q+>JAvOƗ [sKtD HlWl@>A %dVWi9F.o7x*!ΞoP?< KfEI|&7A͛7TWa@ L*/F 'Bh'߱`(s[jM Rҵꎧ{l! xۼ94BnxBkA? Vʪ>F9mﵳzƵR Ȓxmm%})X'gk4OY1{ ́e17UT衑PTS <$F}YNi |d e6%#H 576J-5mt@]2WئfNO#!}SѺ 6]jO8J̩zX L,Cג|wKE K1Fyhk ebIbev2q5?Eiz Gu"P?nl5d=!f4.q$dZzc==@4s#_UUKmtKrрxiN\ސaj4L r"RF^n TƂ]Kd#7>ovIN^|_դU5@~xX\AN=a}NJV=)ƘuǙs5/64yQOtU!srϖfO/v-x**'v!㝿]5zo+yq ak}W;b-Qt? N@d.!{qHVIטL7 ?J]4Fv!;+\RNc+#ˎ`vA6dk~OU|yْhyTή>B/ Tn?ѹo-"O!.)H .=xu AU"ْԇ2ℶ e}V\|=ysAӵBC.-?ޥd΅X<44XA!zTw} /xa$uH[עy8e-]m!UvB06| |V4ԋO5>!b <+Qs\/Xdav N^qr*]9M"p: jfGx`>VhV 0[V:!RED 'G5RYDAJrcvA?bIo+=X3gؗ_mtwC"Ɲ̢3 V]A Id}s _!c{Mz@QbwgA1o2Uԑ^wA[ϵꫛw0'wNt$ ٛ)bbDpxuc3N(8e3LXfe(_ &3S6z{FH#s'eAE”`3?# {ϔrf_'UIÿ;{o}nS>CGfHvTGP/ ϟOyZ'`נI åK{'9VuP*,>m;k^牙_1WA.G@2χC%ދKzv%(%'o]C ݂C@i}IdI6iț*o&%}~'R 6V_򹘅+}.ƀ]_Xy {ܷS/.{WLc]RJsm4'>ݽ͏GsPm:gRY|˼uTS:ޟ2U:r;&C޴dcZJG;E#>TO<tLc6`#gUKՔ6_GU]U -Zυ{,_dMӲah4##ސExz)f GІÔ+ JTT_n_q9S’c?4Kqy7+VxK6F B9b+ 跪-.ߖ޼YG=l@-zIxR9m*,EV #58C_#g݃`f(~z?^cs/v"|px"NT9 ""cC/|e*&9H6!БWrք# lc:^>;gWfM Nu9UAgű`Ͻ:b%}Fƅq`ikҐ>4h8]s750y7 &DA#CЈ}5BB]s$fq+*WSa?`xkIsCPң:I[;o:=%d:qҥ'j_ʸ\R׬PW8di#v rk&"f@|7' &Qަ y"! 0RH K1xRFX-mu4\[3I#W9 NaH/ثtGv63<ss=_.s_Zܠ%MwŸmJ QzC:pEn8h|nZ (~WsT QvD1e8e;frPn9ԛ3Jں!+OO)qIFj(DMW?"xyhPr9B@S\Jkm+Ӳ)=_]KKEΛW(KCL;V6(A_ `GUki..{4^5^Pg`v`JWX};ļO^y̅vϭݽja_O7VT(!^1rh>6w[MAxH[EY^KnO~ߟ3 :2ڝ myrF]xSè?n7Z"мǫ)2c~7ͫ@f4D;(!B%|kʝ^ABrlEU!<8$;j%Efu]hdP]ٝOT/G-6wSpŝ2TNpπoi 'lA̶'@#΄IKÜBp￉XP Na^rKeQc"U2G |3n$@m|)}P: [};J ZƬıՓh[ő2`mTSP;4[x*)0ZM;لڬɩ{o+k7Y2'L "E!YznREa9ԧ1j(>rܓJ=[iI=.^;TklU=&Q2y.h@S5 Inq:8=iӮ&=1<;'aEAS1Mpܞ`n6-hbo -}}cqe?ZT2$CQ00ɝ:2n&x3Ys "mѪ%]IzG:Drs()WWe9m FɼDŽ F.TUH,ߩbdb!L,\O R҈_ceRMC9͸;%`U&?'HX?5p*?bb^@L`=ZX["׏qs˼E$d67 lf+ lO6H 4n<,",g章?w A;DX>`O5yX ->zBcd8/DX -GN錝{kw+]uC8-PCRr%jFk+Ά\xćc).^n9y L+)wƤW,;}:2n ,:z_ڧB>]VEghn |1Ql>Z#𻳶f)uUu ֜AgI՝\IEd+PcKq}B>fؒ3Dq>RU߸we*MݱۀJfj%q_" cCy~ZsjR?b!ff)*#ܩ xI9P7Mak>""']InL~<ϧoozi.o Y6MPJ,2"*M$f T:3;Mp ٱYPW(t8׌VY1!J9Y,9,ѦV}kr`YTxai6'jOF.eNE3Nf|K.^) ]+ ,Ӵ顭$)7b?^,+@'< Yq|Ryx-xcSuā.C 0!rvAhʗ(NcZ iu?,v?Ź`RcOr#ζ* |x#j a[ܑ1kru&i+!״<W'30.MJ1/QV&T-Sx^8(x&*o뀂d%^ӹ2jֽJ$"v[N8fBGs15nrULGe'R}\Z/2՝A9N=˭eaN4ag]uayx\!SXB̾:4_'gr|9 7J]ctTq?sR[n?$9e1;1 G N|cT*;+cʆ$ hYBB5WI{ ]5]]|۱ՙ$>wHH?0pWGщ&L ) ~}L1}N0;LIW +d9 3=2qlsbw ]VFOKR}ypFwo'9Nar-6*sQ[*9a@Fl _A.snIEͮN"/4҄ 덥@KgovÖѺ^c&t&l=g/?udFӯUi:}:}?S+8cVBqW&sYsDY5qzO[a2F0g2bˆO"CRv]e1w4oi'NѭIK̫JX &3K)AT:YYgJ74Z YZD}015\뻙bw~7@m\OrH8 1}'Ɔ5RxbR*=JԔaC$-Ŋ(i#Lb5@ }0mʷ$ѿʚb^ L5MzJ=|Ƶv1`I_XO8,P.zC#>+~Y,v\7] E)IZՔ ]Xo9W]hUaƔ OZmuMwS9@sUݨ 9FZy)PXea-T2mqvawJiʹY)BƔwFT RQ`H(*+03m12ГI]HdoGlע8q ѱu߆ekt t`8R~AQC;ˑV_D%.Pbz*.cyxYƫ>{0$K+U%k~{+|xd4@'b{0+EZmk+S_}K_!NSc&$cҌFj TM"Ka`_ث.{&zKP ?tl%M hJjƬ>06=q&d2LT>.I 2ҍPP)[@W+m9\0ׅ)mA4훷uG,U]n hhI!}*Yʿ+[yt:>UÒK+'~=Hqc: w%D7|cidFԭ)9_ICj؄S:]#}E;\ a>h'l}[VK8RVYٟ$#048\1I-lWQ,җeRjZ"?eQ͛Qs)5Omڪ> SdߓR p?OM_wW5a@^|ŕjK6N"$,kKWL%ǐ2 0Z0=w`U ^xf'Q:&Ox&\hّʃe-8[9G~XFZCzjp[|Rcφ<4O#wlTrίg}Vko<t~UZJ>*zbv8#jSj o;YCpm3t+6jfQ %3$΅2Ph~+#盷$(0(m<{L/ شװ~ V_A;a1PvY]; `8˦PD+76QZLw_]5AFۗ3s]?J4+[ܤA_xޡXEH<ؠ=h b#υqsR E@>[8+:RY(!^&؃kY@: p$K6d8ћ^oaȸ`JhhQ쵕z5Cy{}9)w9?źDP0W>L}F>C~+b ptNb%rMܐ,]Oh(G-x5#둜۷@Fo8? f˵*OVPNPbL?`ʏ:=qlnyP2[{o~'I\&z0vIC.gL 0m,zU#S벴J_ʻVF%|$7pOo=koOCܞWG8mWQ ˾-nHQO8Y7NvhЪ՜!sҋ%.K . 5c%s/ULB XQGd~a9ջ \c ۦ8ͫfk L%/jLIMf4d_ڡ#N*"E+8dJmdؿ# v ;W6nlB-0~'^W{5$dV̌^Ȅ`U*.4pE @|0*-N뒦p)e=DWTu**叫#rfK#)b " ǀɑQ,:ECVKX8knـe*X\F eBu2xat~z{sfh)Ҷ,Ү>#d~ѮzQҵP>/գ9Q7nc{R0?k,ꐫpDDMbՄ3bhZΆzfz!jAL wD=I1"ֿ@7vQ= hb"X&{!I|mEm|е 8k#w&H{+=C?E|hF[eaoFiqɒdA V7HZL&vC},ND %2gckޣWF#] țػUIE GG1`\ս˯lTm4OV:^_(q?w7K 1]>j,܌ӽ'RqG6fy$N04{YL};2;d*AWDR]7*IX>N6VIr,} `m;yŸBT PdlP6v0Oy3oLzTk8bi|Pn)PkGӼ7՟7OمC)*H$cGJV u%\>r#a CP)=r 5FtYV:΢3>Y+i̔✞| #`g^ƅLENy/^_z( #(:hhC9 >A V g,y`o; mqB =\nD;-Ѯqlf-qzy}#!w@?6ZQ41u*J(k7rWcC wr# aX,Q]\7F.7uvZ^-2ނK>D cXgGJAKr #tOt{A]U 4$ӟ:zzB"*)`sm^h ~wb!XH"kT`5-=H$7ѯN9#Ui4JQ׵L#1 ޓa*BBNϬ<]]:ؓ]h. 3WIIq%|mhU$حp`QBSF4~HyQX%pHSg&Ôw$hv5 U{lD8g_G/ ?|\:yG MTk4* "T)+p6ԳBC~)D m&E[$ m0)(:{KBh2TA`Kkzzt]l1rw!6+!lZk(E_ DsDH9S0{)o%Bb`_=A XPc53صoJhnw+>NC%_#Cfگ6WHBaҴ}Hʔ}Q.]]YG?L6Д".$s RFLvroyɩkLKsj&h_W虶auf8jQO(zmQԾ]q}CI_iĺWu ϋ@ȏNmalz׻hguM8`2)N3܊IHBe3O3"G76"Ѽَ w&G>1aӱg˂<,9l ;`!A(7W}ߏٽNGr{P$LP44!0iad:7(y O 6ʽl Y);]:RݛQ(\tlpL,(^Ks9QG"(j Z2&];%oTT7E'{x~?aݶ}zK$R8XB$tgY=a+z=0J~JNcBv`Y26Nk;8_L;CviU0>'0G  j2o< s5mچ`3Vhs+H&wVKJVT.MZ. ̨v4 }?9ukb HAVsr^52Z_ʽ#<в ڷ=#NνL@HrWoT!,د.e^펚z$PɥәKW2:7bpjI~;r>^ a@%Rqc 605_Wg8(5?S/X iFML&n8v  gpa~3p)`>(^I[\5-X^~χGmDzz(-m4 s-dY0s_R&wMW(ƄP;538%YBzkjuwٰı0eq4soՄGy5Lqĺdr񺯍L s1Ĝ`J@2|NO[!7!yv4 2Z#atyk9c?HDLW$bde73hJ[~7yNwv\86Di3o}W"} wr tf G1\O§Y/S JmfH8)iwnK:BUkxy= gx~V|t ?/^fk Axuf3crew}ڠ TD?]~B#ĤrPO:Sh-${R S I@1׿V"!@O3|1.q'!O6 ƯaT}Z>Ȯi[9zvp{5_5$)GZ6mT JW6m hOIs50Rt?n1+A2OcVO vGCA~ZHaćJ)Bݹ!- ׯ%9y}邠Wt諊ITF@껏AՄ+ DG'3?QO^m6@ 9<@h}ؓF(.u!Uߓ qHS^^{kI ȓ3Y[5!j n_%O@|O'Mώ U 4ay^p oW72p*+hIXQ|/). Ԓ"ߠڥ>3VvU'@]T̊Z-4/PF{)X̗1_d9춐>*HM+a ]we.*q}s ש9״X aYSA6HUFGlK]8D5xO@k̎DVKw{Jqz 1g.|d?L4Cдw 9N~"R_ (cv,T5sNɯ++gַȑ[a5>x&X wF5~`<<2uC$O!AMYTy@!B}6:'\VʷnIeփP#;w푕U%)W348kU|Bغ@(ܞG;`kDS >$&&`d%̗/k)hpBU0?їUu-BMV|q L5 #^ #  w@M;0h,`m׭79Zi>/eã6~(Y AF g2q'{F ő:|&sNjJmR.<\Ą|^ǡ6e6k{&^ب_`"~nf}6&TSޑ+ӊz~t@j)a!RH0}]ʀxij۝!2p85K ;ԫKg!.Oj{%b`um,M+9| ɔEZĆfTڜ~ލJǪ+0s FcX5W)S1;ά6LB.#͌|5nȚd?K _U/xD)A$WYM5Z>)VWLؼ0{ޑt&qܬq-Y]sm (0Ii^7sP&|#@"n}vmnK}r %a^\06 jY6DoF7`G/٫=] :OY-kCVy. Z/018l}a7tw;#~A=oFaiR9 0u·:/6`츗4YlEMv7W "\2!ak@9J:>e9CNjⱂ&GC$6f=a/+()E?H{ je=edrW#Q>K1=;M7B~)_HMTy8yr0)%NVʐ@ Yt-Q[Vy0EXȀ Nwi63Y.ˊRyM UտUg3\͸uVobО"\gVz \?CEnxIJN-  aƜ9F"aO'^do̴a9t|vx%$XtPh!{1pԿAM75mvNg֪gMɄcY mvjՎ8.Zr~qr˜ PM1+o0)1n* 'm,# zIkK aPaQ |Cju,tר0^hR#A56a߽ {kԒ@'W^4ӍԸ?QDCT&ٜ!sRŨypwZ . c]pެBU Uonq\kMd )P$(hdWiZ!+:#׵q43x*R =Ɛv`dA0'x)i#-Hwa&Ͻ:scb/5][:(Wm-j=V,^- 8~|t[ >g戫$drZV gvVP[/q4"ݲ3SPE1W e ] LhѬw鳕"CtT,JC5\/B3Vui*L'X$B:'vC'u9kM)QEUgv~9Jل2~Z wfJAaB{?Hf;JC;GYG"E 9+,3$_p QdݨpCSz[6faۏ5~ДpRe ¦aBh?"Lo*l^c dsFҊ\nWF%_ai4%m6':U=xkYfJ,tdQP2)VY`{(!RkL{Qrb<客0fb:c8Q!&⇦  \̭=XiU`!|a^z`:QM>տD 7cۄZ>wI2{U.:pQl˂\B>B\=8z؛[q7)IY{uϬxh mʋeHk\^'L$c7g%Ww0toRSzL`%vZR(ʈ,jteTt.[D]qpy0e-ra^t۱hn{f 5/]L(!N)yƩFk!W&.Ql+I, -*^Q\K 3p `չSmZ//7Tm$4upX=s;3nni)`tg_\L[J1:CY:,Myp ŏ =tJ ,fY+HHoWp}T zhۂ{Br!!sd,ma2^Pgn0zU)Yp4@oe 8T;; j8|:K*Y,e];uDm62QkC&5c<: 3̒=G$aACM