python3-pure-eval-0.2.2-1.oe24090>    f ;G|`u` Y mڟDT!Y |C(Eq²Ǟ'gIXwL! м@Z$0̚ =wY}[J"nUp;n`¡;IjIh1)}p$ý߅C HRM$A)L=D/XUL/< mGk/kMr;'M*5V{Jl U_}xQ R{) =}S%~zԃۢM.P?"QۅQ_'3s@x;8! F :ؐ;lw= {\Z2Ce)$-#qQ0AXV026eb6f345291f8bf7f0cf914a0040f867d04ef52c0dc901f27777e7cff8a9faeeac44e8fdade2cafa00b22c8b6afc602abc781727%X`vˠ45*>=)?)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 ```fgdc-64g.compass-ciMIThttp://openeuler.orgUnspecifiedhttp://github.com/alexmojaki/pure_evallinuxnoarchl`( ))[\kk##;D?AA큤ftftfnfofofofofofo_frfrfsfrfrfrfsfrfrfra%n_a!a%nfjd515fa6ed6d8f29166fef70cece3af1f2734c443fb1d5becad85ff558dfb4d108dbebf8079d9cbb578a0a93019919b82ca78bb676d2037538a3c7be6721c82325aa2f4a240d2a1c123d48b7ad89409e2bf5fc8d2d5208e10d6113557951e5ed377bad3f8dbf3432661fb8fde64a9688fb3022814309b9666b08bb2fb57c1019a01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546bc6bc884df8f8627031df19665d7037d3e2e0ce4e078a59378ca59a8ddded08b56a3db8bf3c37c1cdd7b0bdd0d2c1e27485fa37b4da562103af547f47841b823a7a93f5696ef3da1601d05b42ff1df0d401659e14a09f85159116a616555f5ddeab130c1950af9772ad92b02586d5e3e93b6cd21e7bae37a935b7489ef7b0427aab130c1950af9772ad92b02586d5e3e93b6cd21e7bae37a935b7489ef7b0427a822e816e3e60732a8ab40fdf152d1c4fd31ad98c895e4f25a44d825fca42bd0386dba947781d909bac8fbed596a88c943af160d561e029080707b9823d623b9447a8fb44dff321945d3606e5982dd4ac457c49fdf99922ab81e2b429d5881d7e47a8fb44dff321945d3606e5982dd4ac457c49fdf99922ab81e2b429d5881d7e51311f0989bad1ce28b0b02f91e6353ad25814962af4c700b06d646678003abb6a9917aac988dff659d21259e3b72a35e19f988bbaaa0541e85e8fad894b5ea4e93b8b36c6e5fa1cd5d81a6a7182d44f1e76638d44a2fc148a7f947500a84da3e93b8b36c6e5fa1cd5d81a6a7182d44f1e76638d44a2fc148a7f947500a84da36f1b215a0855c026b07557eb35d5cba878f950ea5a3f3d5a0240744f7c61ff7426f00cdf411071fed140a1b77d84894f5b62c0429b90f9e9a8f4565e322857cac37c58268ef5cc0ee90e717ae71afabbc14bf20bc9ec674028c2522eebf620f579223e955c81cd85b50f6bd140faef8573e1429440ae1bff1a8071d4021f5877a4a876fe1985354c06d09c5b2f5f2ac5d9a2fe7985a6045b47c5fa20f66bd3carootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootpython-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 1726939239 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/©ބ:Xutf-8de8aaded3cde170ccf24a23ff261978ca1c368311014420b4eec69faa75e1f294a95c173f26e1024c272f2b2856e2fa43e5cc6153d836dd2e22dc8cb9fcaf23b?07zXZ !#,ᾧ^R] b2u Q{LY\&DMZ`en Ldp-w*FBGT.4N`^]`ag~+C{κ%TɏdyE/РؘxHiN=q ⇁Qq] ӾnM&Ȕ5X ]G#['lNx;1rwn&6sK{nb rlQkI Ŝ!O㘥gq?ۙ:ipSDGI4IzH$/ϜKMXp%.QebDKn]lX@dU亷-klceGȰ ӀGfP2w$P'}br&kv(}0-0kk.-ֵdv>㊻kb՘>ktٿq1M] N̳ ;[-QTlLJۦX.'&I껷#>T`6D6f§GЉKKJV +Ioܲ7*@_ݟ.f#Jw ض`r$KjLn'1q+ml-Cy0j3$ Fc( oWl#1{DgsP [#$ys`m!v#nvp1J2+ݔM00P'> ;QpM v4u; e!M#.cGQSδfȿ_8їc ӌ4?dY "Z_ և8N  .hª Ykwg# }`>L=p#]ɋU|xڣǩ,,=f* @ID "gSNT--q""'~,bʎ\a ZDFIt !e0;wz֒ /ϽBv1Ϧ^5Ipi:~TaKI!oΓ# ZY1%|~LK^nU= [*]dmRjzX [P!J;'e+6{ 8lPtAG~28RB%fMZVɲ&STSVUj)g8Ɖ-V!-k)<(% U"ai>3b)Õ CAQh V5sA4A%XNUNQRVӷ L}"`rYA 'TnA0 /E&8Mz%+i}zKLi$nx?r+HKm633a{<'tWw@Bcy=y5zLsh zX_cMO!%BJW a&l x-9fRp;8aAUe6)QTkXCJIJN<%UHYeNSSVie/p2S7| a12X?'ߝ]Α`^@Gy2w[xyg=O8!T>M\e!pslLkF.ZʙG=t߿UCpgC,/!oM]'oLpn$ @Go+b"PmznlniYqyC7/] x[" s=bܵxuvZ;&wE'}?p-˥v"MHêjl^d ,1T ma7ʬH )ЏM_Llw=!έR5K#({~?}VGhd{e-  :-fJi-̳Pv ]46fj䴍҂bV&30h5SrD?ԉEC;C%;3(T9nܛQa:۶je' JxB.5Ⳣ3?vYE$*'%+ oe\' rB+,%/m@Dub#:. E w629ʜ^Ϥrz̪"HS+ ؚc@хLpgC^Z>X|L/3]Uki^! k*ಧH(?OZRAꀎg2*Kz_ǭ;P) :z30uMtv @?<)БfU0'(N]ꍌ> s |Wlj 6}φʌ9/K9jhR)k;[;j7XJҘz-w;᳏νwbJb*`pw9TXr-iբ WB.Tinqힱ*16H맵ot`AH"evpϛyLVQ_[G!:ͭXd{s.2Ÿ}=wOt֯j!l)6t"蚃#1o 9r=. g95B纒`z!ڶX~!7z(kt ,Zf_xVОx*aS4ea8 >3jubbCswgrԨɧ߱ MӑnŨ'dw wt~Um/-k^6x.OesCz}@ DoVtEgbր]i)ΐjpC|tȥnH;{Vʹeulg7 *$rg |ś//,U8Cuy;^' Ns\2WR]hgib"li4UM) /٤fA7™cn#2v;7ܕ6֤ns.Gu&.eAUb8\1t>'/5?5#|t|}grur蒎.sN< kڗ#)f#*J&t;36,ɩBcjUpG5%Uʷ?F70 IQ. 1[Q㻗焰f၅?'4X,}8cȏwUgέ^ z oR ؃%^Ď0셠OD][\i3snvG"+]۩Q0Okȡ=2ڒ3=1Rǧ*&E:DWiN%5Nx0sOUHɖ2C&<1 aFKRtQH D~N]` 3@#KzԳfƥ\ 5_=pN.k-*dIiC:%[DK_DR$sdΟ L ~jE~xAP v1$tnC$=$Ֆ5o:k.糁GVfk+trm^+ yYiB+eP;1u$غڱ}SϮJR;Nŗ, tB-ypߦ甃$A0 ohsXHh._Nc !en;үҤx޵6/.VۋL"w?LH.-i̛qDV쩏䋄CпԱqp㘂Tn?&踆M`.=gHŸ{nIiЊGLH 5)ӝTMKI)p2f/D98s(u]۹9cC 0e/CA5!^H/]Sc:']_ ӁƓV҂gPmCpŠŻR9:bj{Bz.܋? whӿ,AɉDj^#8 pQ0 ?Z}4rĊp|`Ԕ|sy~|@aaRDB; a54o bC{Q3Z;+) 4=JWOAX(#4d6};B'ƨl05QUa SVX^"?=bsʎVFq=S;!D٣K%*cF2.TQvn^UИ=n!Q(8ZYI4|jk.Ί~Cܒ{ʭ:JzߗV&.=&ba"U3؏w`>{bU$E2h[Awf+*zyB.2с ->ڷIJ-LQ$]v.!WuX&&[ak _lRYtsG ޒ%( -?qy Q7#x;h`-\o؃k6`h?@Y#K[ЭWȅQ UEx#CGW6;IF?c3?u'z7{n@Jx@%;Ǭ N'ȷDioЇ6ח?lh4rZG3`gL& C3搥^RRsw,?]"n޶@J{.C X`ʳbS<&Pڔ*~ܠZ񃲧2CVʒ#Q$8fD p *:gNɌdfyy}iDGѵX|7@̜Nm"~Hd'/^SHt"u*0衊톀T |RX9bhiEϓ/aGUKX';#F.ϯ1wqrÓQbCI緙HBb^ c`3&X}'*O1yUV|NY_ R̅,Pڋd5֖ߤ9<^ A74.@n}䧵Ҧr#FV Fq>ӊsFFX+ǕbY]z  X]FB&t0ѪJFdjh%Ǔ{= X2.JCXv4xJie?ص' D˵5P8\2p{^ vo-GN$rPLuT8S͹-Ο%镒V %5NQ$n㮬:CodܙItvխ(;-EDBBd^P1TFK#]aAʚ<$o("3XFYyWgޖA-O0'10p3&dbUxBs\b:]oqߒ +κAP|\JH 50[Ns%EFGx?{olW1uc802Y$t fWZw|~bnݭ i9iyF+3¨sNiL}M$0iDLq'-ab!=wx%hyd╌ kcA"=Ow7DSa͑ qVu䷨Π!P>8%;*̈́e 'ok"3:UP A8c=;'IXjdgKlqulʼtx,\LC#Ϟ36h\t y^J`lxYqAZuֳg1(./'Sqޞzay1'E:׸:T^[M $=3I{#o]fI»[tS`Ҩᑨjk|/d]$ E媏 ~:&#V+ݢlM 5oK]$Q h^vhJo=,Cs{ުr~;iJ,$;@iޘkUG'0Sg _+Om [XR8I +P!_pw˙(5P"Πz.`ߣ"%O c7˸1P:xeP-{72 ֨3L2 ~aϓZ4K/aus{|8W4ƌadp+H!V٘lxX|x>Dr0))tYW@cZY -LƗ,X򙰡"BU ~} rxk7CF%ʮ3_x={EkX?@Krpopڥx#L^6KacګEljfz9ֺY@. YAD3izN f_TQ'R<1? l0虞l{.hA+_7FDrTYd%{!K:+PyZ2a4qٛ t>dMi$7Aškٸ‰<2m_8L$9U`meg V u25Xuyi1INٰ™~l)7WoWOSJy%6}mMzJō`V,o|#n,wS8~~ς<~y}ekEU2\Lw`J,kt.o)McB\ؚ k/٧nM8lFLIwZZǑiDG{ ~[3 ,+QBȧo[^P/H &/iL:}X'PլzZfk.np*ug g<R?ѦO.w0.s% T(NQ-)bkdxr!Z#~ScM'U`W;hp*%W)TNqȾWp z(c_!d4|Va$CsEC+T%FX2>lCԏDOG:naU.yXhPϷ14ruJ\.Wvuɮ<Wk<-μ\QXC~h$}^iK`qn,} wGzs\2bn:r;D+c q&zg9?MC4u,"YW90*詆&*BG2oo.ϓ:=|d˧NHw lb{58&vgxDPؔ@djtu{ ssV\@AE8~#q腠߼J\ W|.5gB3Ff+0 QLWY`c9{}Y$VAW$3`\|:ʘ|pIaMփ:V=N6b`-Ry)i>n9 X61Dl{CqԴs*7&A#pZgr>!F*sa<1שM$ԐB^T- =w>'2!gGG r&[h]^(%3l}AԲ10?yEOL94d9 ~ּgTBވv+`gDTٕh-^f )2nE>X :; ڌq^.T{e4"sJQbH&@چ#E ih/~qoqǥPYPdoƎC1EԷ ل܃l`e<~Fɰ#3is"}P C[5-w#M}!;R,F3aʰ|IEDXE ;."tاAe?+%g ֳǧ# n^.M^Inr|6/ -I$x/'r S{c/(ӐC1ïĩ mv/ %c՚i[ˀr&Xqq21jar};;@? ȃnj~6;6[ܓhVJ\d!Vˀ~9ӎM\=\\NJOM8?"&md5~(N\zj@1ӽg`X"0%&X:o,~ϑ:y=ڰ4g' yyT$tCd0 ;YK·[ztiK(S5 i1NXWl^7h;i)̽DNn˅bŶר!#A$C(O5D?2NԤFc&Ǝ!5Ÿ('}Jrr̭{qxƜYh'CZG` 0b:ܻ#%]5o>?xFcolAM'+%&و2BO1CZ#π,nKB Q6+4wGڕ''X^TEI, \TΪ]r;(f򑄇fߓ_ix=:qO*{N7lu} /O脆dt P'^M_X~I@_&rG٪phi߲/ɵˆ22=9p~!ܒK'9H8q^u5o3}RQJe}TMuh5 j:!WU[Zt>4H]i+0q*6*晏M|,`I`TwG E0/2 &gI>=d\Mhv8U/ ā}:{lࣻwBnO]Y+9cry&]wAwЉr.0rɰ㶱QLEl cN?b=3*Dd/Oz}Kha$*f7,5r=b&;Xa͸c>ϛ22Όt\&ev_۰1dJ`.Fǚg7`[iq$]aohcZV sVXWi-; !e/!uoЍOQW [) ü!K-!kfQʀt\Gq;oѫ7c+՘/? q-ZGƇu8",fb^|v7M:5EHRl H"dd\7g XNM% <㹸=ˉ!6WZP8% zw|(0XG:Jz_?ȏ"xwΊSmgwʮ_x'CfUcAub9 4u.5Lg&6?vm$KL('y[hw@{$Nn0 4H(!+py&U@e_D8S BiԄM\Sim+ԯ< !ĕT@nୁ7tq, Džk&_]qzPϢzjъq9.%uU2A\MQti}sZmЕcC`6$G N0ѵIpwj^ʱҕ5>A+ ľ*bN@2]-2G vGM*(HŽ 2y]~g㉊ o2*6v7o ,InGTSY#݇;v#׷13O#fW:am(ׂ>R! v0ωqx ge1,^4[$r3@b~\@b-G2adGzt1Np;H i~/yVt8փNIٔ҆uM@DN+!k%'tsDG夢D wA.~[^xP !5⪸Z%#4YH}ʕ$6, Sh<t΍J?k9 &jE=7-&N{v}7&t.>n-*ma>?r.wѹfw\J,Hp?@E!?RݬwnS4bDtPjvJ31:C2Z%,Jb*ŭ^ gܸ+X c>9CTgS\5FΊ}DB$c.-tq77Q6a?׮b 8Rh|K W6^n7ƟPBs@NBunZʀ"}"l&_u6K/amŚ&H┶Ez~̺׮wLg=jz}5&.z{ kzV-D=~9p-t7{ pլY 9v&p8;(}:&xٚIhx)ʄ=7 Jg6&F =рP/hOqgY֛}[?M׼*oCRȋ}r)ɓ3+-"Q>hX1Կ|L9j-bx"䩤]|{ҳʂT[&q~ŋ ӂpɍiRk5L>#Bs7Aۮ&JlT> l &c.JrHgQM E y޵ILڀ\wk܊Ҡm$'RaHȱ5nB3d.~ClRS$y8 ;EVP #k'$lu{ f,9ܗߩčus!tP>ؿw:[׬\,/yT IA);Zh, I%u:Y3iK vX},IN1eC73##ɸ6j^ @JtuSnj:A$\Hu=M"#l5+%ŧ'mQ"&0sݲm缜XEb~X̭nuQO(év<3"$r=MZuNtZաaSMƾHim2=f MQˡ)ƖשABT|ʰޫƈ34fE8j.Z_s=]ՔViye HtV&ō?td%,D9lqPP̗r1 Zœ!go^B#h*mkUdcDw\\:~/."oW*TM̚t*Q Xk4;i`v7EKx K mJz&_Rڍhoh'9ǜc tZ[u0N?᱓Nx%شWxA l8 pDi Ҡw:[VIED0η س"l;nVZN'l> qvb[E `>}4l2چ%Yu0hξ(diHK~T0 3:L)޴ε BUjG^#Ju C{ͫ3o> =B|LsؒqYj$7S2`=Hcf<'_j?I4`8Cz+վw,aʨ\^k?n]λz;)Vž,}vĩb9;)z.[@cL'2E-Ik7܊ M+&խԕ-j%?5#6J: - ͨ(獁roA~yI4*EyCѐg8絭~war,Bv-TXv_z(%`ȹǵ'7[4!gHu]n 1xcݪ'TJ#Hzxؙ=`^p2Orqx8{(-ԧuw'pn{s;ɵ',hArS6- c,q3zH^\f9ԮQZNa`Dc 2q"'#+f2ȇԌCFN1[F8נڎ Gy-]zrj?}"m5ӅFg@i97|cŭ T|(|UCi<ҀЎI↴LLz9L.D7247L'ɽG {+?*&k*C%4W A V.ZĊDG1 _ |EHCqX# &… :y)A6ʤv㺴򵚗Tc2`"eyvc0F]us >UiZ? ɿcʐh5P}G-* QgD:]~^&ER>7 A􍭲ꅘir6[ç{9qf ouO|)ɝEJ\WF,O<ώS#ŕTX4 ud*"s;X a$I?Dź<~iϞ$O0;M_9F=_Cs?nqch0uOGS&8Is覺iE[7"G&w6Y5ӈs!OÊosIɸSF֊ تһztNKFNd&ۭ 9n9va "zMC]С2;.wOv:4esG] A+c3CHo!$ Úc +[9tYxթ5_Κ``@|6J>s\okzO4wb!t`6ȩ/ė=`βs*WlFRw-irn0%iOO*DïgN*JD:3ű>{*{rêjf2\YŸPSFn3}E_EtSSAfh)!g}C[JGo'wv[o[Ƈi_9lJFJ`tQ{c^ZVrLsecnbB@^+@H!_8腒U^'泪S# `^OYtoO\ ש݈AUw[}wٻ}[TiM\陲U:pZZW[ÊN*^E|qNKYaV&gp#ܖ.*gy;뚈df~=q<]yW`#D!,6vM1j|5ڟ9w2ZcvXiZ6 þu6lPxM7iR7y'Gx\r0P1I,dc"4~Ԁ~P"sEOpBݗ-.4lp=3"pvqpMJIdyGs&>m}Ɖ@w2Û&Ud%74T[vu5j*[չ{T~r4n¹vqc%Җ[TtX)""}\I}mh0ðM]kX|8%-ŏSwhLaxBy?뒗sFjU$oFjF,d&6w]6Gr2t9yzq{<ꂈ0*qsA9vI;e44SGu2CZcbh9BwkE'mtZPsp.ƑS/@$0c`Oόِ0 z K ;Z%48c0<9 eaJ,roF=qtਛceWmWY*Wdcξ0!U^pZBp {zvl^Mĥ]тguȮd]!nh%8:mëfX7 ~4.""4;O #R `Hl#q1;, ,nl yZ:+odvLY`j'E)Qz*Q钝`lP2 j+4?Ux(&cu.8Yހ{emWzƑ7h6WÈ#Jt1䪐o;2eHLU8t*'?]HE",~WV|!ӧ5A4Eӛ$K )A 帴2E ~VZ' ͏J53wNgpTX52 ]E1;ڷ4:~ C:cWa]R2(w tڏ΀ $}ܮ݇q=GOe[3u8Qn ^nvWN:d"D9N;A1tזp>`Ms?I|,5 /rDo>)=3BJ]x%&bt0X:pKg6$Xk}p SX}1)R Dn xV&@#Xn\:[QYx4rP*?*EݑsA;X]1ŔoHog9s`X@9;.GΝ |}3;H)%Sm~WCōh8_S6+45:w,% jWe5UA'>ixt6XSS+^]=H Y>H#c ypĝ8`,58ӂms^rxNPT~fEڌZ$GJsms{i j6w-5ts&MDl8ɣb&lxvʫo4QLMπ:{ސa!}vquS̤|uM#ƤNܛ8c83%5C2ĭjSj/jX2ʌ&#Aw*LwUsaEFm-:°*WhѤzwsDo?qgG7N23tXҩgo\,ljI^p0zVh2 9a| HXg; k="82nxodW#Ed!罐-]TU>&Uk,Vrk)50k,8KQDf6z1%!LkHw|<HuC{~ "g*!(ba')P|uS> h׎)z&O|NЈga26:Ϊ^Z)A2 '×1nn;Wq $HQ S/=s$=VjL*S$I1{`%h2 Vw 4<;bۣՁN݄uOr@* Sȣ}/0@  B8VfE/$X̚Zj=ڨ6zQ:6COUօŕ) &#Au~;:mA XW?AXCA>3=o¹ 5bAF'aۂPcC3~#.|Ү*Mۜy2+e`@!~E<\2:m`8Ru0/͡nD;=&pbIZg1owd y [݀oy9Ŕ䏔/a@1$y-65 `7U0d-`H:C+*Z+Ulj#:"q]vStn 46zdТ Lù<`٩tNjVla|CtOႺռ5j,-Jhҿ~hwI,XM:%ILզPBذ j x_uQcV},V'Q,u*,d`#. jB&ۖHNAlӶ1wCkwNY'p-L?hXf[:wlK;qZ2Vi:ZT!q|YJ '!X q`(Q!6 S=dѺ4`|!Ql]g:B ZvnʅTt`ZЈ'㱍fq7~!g>Aw@7J%hMRFY> bYjɳ~ZuioXC?)y@&RRl*3l^ئ?J Z‡>&CoV[e {z^ҀC- .;1}苼JBs{bˬLGrAo{6 D~ F#|m2*_FFKM9pgA3'lf'0 `U˭ wL.Y W_ݬ6X( ď4Kn7t=H0 M DJO'G= j]P%i&YpUyxbQNFɸe֌LEt^;5z$󼸹EaUMk.C|.5{4 }Vm_)=aOlko/)8F60Ib;}ZP2%% &/rA M/V 'MD%ߘy؍Uno|X%OζCFH |LCʊA'Uy\sZ2y#*(I?&_XK2-ؘ"@,$`zdR!{l^['Aě:_]¶(z$jnɠGRteħ#OJP?0".O E'D]ݬx񄩳eD[4d$RD 9[ɂPyiryRk @23DɋA{>a*2 aƥmjhe}gt\0A%sw4aW䙎> ȣ됉-9];[FK1p6/0BM<7]biLj",( G[ ҉EH^Ckډ=(%/>OրS`#L AG>y=Fj\YׄIዪ k|PV)QmIČYW?" } *qId<:4]1p\Dy=3B1G5=WIw6ҵ3X"Œ- ZɉE 5UkZD38l^bhBwK";=jErNH4:ST"h/uWu$ێJͻX(UۜQS`u]e&T ܀Nw$ zV[h,ݾB xkRzTPU|o:&1XKSrf,2NOx0X-Qls[%[_>gdPX18@RyCPwQ-[H1 A]s j9[[Po0~8?AY4iQSp3&F[ V"a.ј48æ LP?zdJ*Jsn$rn/>\=m-˟;žMĶ YZ