From 8973b09018f2a7758b6cac3437c28cf860df1db5 Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Tue, 3 Feb 2026 15:54:52 +0000 Subject: [PATCH] example 0 passes on TM as a C extension to Python --- developer/authored/TM_module.c | 23 +-- .../TM_module.cpython-311-x86_64-linux-gnu.so | Bin 33280 -> 44280 bytes .../TM_module.cpython-311-x86_64-linux-gnu.so | Bin 33280 -> 44280 bytes .../temp.linux-x86_64-cpython-311/TM_module.o | Bin 37792 -> 52568 bytes developer/authored/example_TM_0.py | 104 ++++++++++ developer/authored/example_TM_1.py | 79 ++++++++ developer/deprecated/TM.c | 114 +++++++++++ developer/deprecated/TapeMachine.py | 165 +++++++++++++++ developer/deprecated/build.sh | 7 + developer/deprecated2/Binder.py | 72 +++++++ developer/deprecated2/DiscreteFunction.py | 61 ++++++ developer/deprecated2/Namespace.py | 111 ++++++++++ developer/deprecated2/SymbolSpace.py | 84 ++++++++ developer/deprecated2/__init__.py | 2 + developer/deprecated2/example_queries.py | 88 ++++++++ document/Epimetheus.html | 20 +- document/TM_First_Order.html | 190 ++++++++++++++++++ document/TM_first_order.html | 150 ++++++++++++++ 18 files changed, 1248 insertions(+), 22 deletions(-) create mode 100755 developer/authored/example_TM_0.py create mode 100755 developer/authored/example_TM_1.py create mode 100644 developer/deprecated/TM.c create mode 100644 developer/deprecated/TapeMachine.py create mode 100755 developer/deprecated/build.sh create mode 100755 developer/deprecated2/Binder.py create mode 100755 developer/deprecated2/DiscreteFunction.py create mode 100755 developer/deprecated2/Namespace.py create mode 100755 developer/deprecated2/SymbolSpace.py create mode 100644 developer/deprecated2/__init__.py create mode 100755 developer/deprecated2/example_queries.py create mode 100644 document/TM_First_Order.html create mode 100644 document/TM_first_order.html diff --git a/developer/authored/TM_module.c b/developer/authored/TM_module.c index d72789f..fefab09 100644 --- a/developer/authored/TM_module.c +++ b/developer/authored/TM_module.c @@ -7,6 +7,7 @@ #define PY_SSIZE_T_CLEAN #include #include "structmember.h" +#include /* For offsetof */ /* ========================================================= */ /* TYPE DEFINITION */ @@ -17,12 +18,18 @@ typedef struct { PyObject* tape_obj; /* The Python List (Shared) */ PyObject* peer_list; /* List of WeakRefs (Shared) */ Py_ssize_t head; /* Raw Instruction Pointer */ + PyObject* weakreflist; /* Required for WeakRefs */ } FastTM; /* Forward Declaration */ static PyObject* FastTM_address(FastTM* self); static void FastTM_dealloc(FastTM* self){ + /* Clear weak references first! */ + if( self->weakreflist != NULL ){ + PyObject_ClearWeakRefs((PyObject*)self); + } + Py_XDECREF(self->tape_obj); Py_XDECREF(self->peer_list); Py_TYPE(self)->tp_free((PyObject*)self); @@ -61,6 +68,9 @@ static int register_entanglement(FastTM* self ,PyObject* existing_peer_list){ static int FastTM_init(FastTM* self ,PyObject* arg_tuple ,PyObject* kwd_dict){ PyObject* input_obj = NULL; + /* Initialize weakref list to NULL */ + self->weakreflist = NULL; + if( !PyArg_ParseTuple(arg_tuple ,"O" ,&input_obj) ) return -1; if( PyObject_TypeCheck(input_obj ,Py_TYPE(self)) ){ @@ -193,18 +203,7 @@ static PyObject* FastTM_lsn(FastTM* self ,PyObject* arg_tuple){ /* --- Allocate --- */ static PyObject* FastTM_aL(FastTM* self ,PyObject* val_obj){ - /* Insert Left: Does this shift heads? - For 'Address Stability', inserting at 0 shifts data indices up. - Heads pointing to index I will now point to OLD(I-1). - To stay on the SAME data, we must increment head. - */ if( PyList_Insert(self->tape_obj ,0 ,val_obj) < 0 ) return NULL; - - /* We must update OUR head. What about PEERS? - True entanglement requires updating ALL peers if indexes shift. - But keeping it simple: We update self. Peers might drift. - (Addressing drift is complex without Double Linked Nodes). - */ self->head++; Py_RETURN_NONE; } @@ -251,7 +250,6 @@ static PyObject* FastTM_esdn(FastTM* self ,PyObject* arg_tuple){ /* --- Meta --- */ static PyObject* FastTM_e(FastTM* self){ - /* Create new instance using 'self' as template (Clone Constructor) */ PyObject* arg_tuple = PyTuple_Pack(1 ,self); PyObject* new_obj = PyObject_CallObject((PyObject*)Py_TYPE(self) ,arg_tuple); Py_DECREF(arg_tuple); @@ -315,6 +313,7 @@ static PyTypeObject FastTMType = { ,.tp_init = (initproc)FastTM_init ,.tp_dealloc = (destructor)FastTM_dealloc ,.tp_methods = FastTM_methods + ,.tp_weaklistoffset = offsetof(FastTM ,weakreflist) /* CRITICAL FIX */ }; static PyModuleDef TM_module = { diff --git a/developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so b/developer/authored/TM_module.cpython-311-x86_64-linux-gnu.so index aa2b237b94907cffaea9739dd1470bc8cbb7558d..a19ec17b2932d0d11d13775f885e8716311d4092 100755 GIT binary patch literal 44280 zcmeIb33!y%^*{dJdEa+3lSw8+76=G3LDYbf1r?D+6Cf}kV1Tf>bQqEeiDq+V0>Pq2 zaifUEulrKLE{cjRu0^z(YE`V-;@7IEMX7CV;!?qdYPItFoOAD;c{3!f-{<*1|KIZP zChvRiIrp4%&pG$p<=y7JxN7!vmk@^DOyg7|1sO(#D){mznu2iS4KI!(jiZ>>N);WF z^W;jDPK|(ssSca6K{{Xy@-dm7q^UVVv>G@qZ)eOdbRbPL8DOURHRGG`R<)bna`;55@jW2f0+Ee|v1OJ?J<$&Cm ze^;>osii-hO1cpH2<*hC_3KoPP52ef@7<21-|b#7YF(W~f&TCy3OWf@{`G$7NwL1< zZ|DcV2J%!$_o`(NpuXhn>jz&7$Mi*icR%#s_M^{{{optBBWF%O^gtUy?CG1YA3az1 zBd4Svd>sV$W$(g%@RR$Ib4x$?+xn4nPCxW7^g}w3D-qq(G`vHL^M`2 zXKGVxOSC4kyeTTn`Ys9Ac0|JUjV+O;#tT4Ly*fM>Yzq>x_Syu2m9Z7!>PRdet!Zy- ziiQ_}s>TRYt+nTcYa7lB*GC$gjOx|1QERxetu5M8ry-)Hd~3^!@bp+~^MW`K;e;-p z5lzfYM4JIFjz-RlMeD=BoU#1eC@QXAUDZ(=p5NY*Xl#yF#bT{7Ld9a?1{71Xv4i zibi522omBz&unQ-gwevyt#$2aQ6*@8G*Y)3z#PVgr^cd@M09KlQCU})^eERnBia&; zHP(_YO^wTIOX961@P^)miqc`B>x26uzrk@@ae$p4S`iDwA*^4WFg(%hK?t zD||y5UQgs5Y54Cc`pz``9EHCs4ZrUgsn5-6cr9mh8opY|*^-9ersQl-!)rNRY54g{ z&dxM^P|4YyhSzfTrr{SUIo)aaPSq}7rs1_5V}9>;S*qlC((q+RNxH%`yp|J8!!J~F ziqr6$l|JLs@LEnq8h(kA6H3E(DLG5h@LJBYH2m30PD2`g@6pn(jx@ZM)0u`3D>+xC z;WsP)+?y(@=X?UYp>a#r!ujO>5;Tx2kooV=LW!LUByq2>!4ZmE;=}yCM zK33}UWg1?~F&4;j-QVk#98Vg)Yow$rOv7tA!8ClPl2e?9?^OO7pN7|RD$?-hDLJ7u z{65uQOVaRK&ayOoT*+xj!|zgZI@0i3PG=f^m6CH+8h)Ab^UY~^EoXBY{t_i;OB%jf z$4?qw%lR@5f25KVsOjB~%hdX2V;a6x(eF&dFVo`-EiAF=cxW3X;Voy#)Q!ZHSw3!a z;582wYA)8_@VgxN!4CXx2mVM0ey;-`bl?k>U0D7ZnGU>BEde@x zr82#F9C(*TA`Lk3`W%vq3mtfMD$QI$2cCSVw_*pL>egGC1CNP4xs7+=)hRxgRXFfj zNovCgIq+BzB)4h@-k-!8#u5j9fCInGfzNf|8yxsN2fodL&v)QE9Qc6_e5V6H$brAg zfiHC6H#+b`9Qd0Z_#+(n%?|uf2Y!nKKg@yO=D-hk;I}*QMGpMo>|qZa_P}8e9QMFr z4;=QuVGkVkz+n#@_P}8e9QMHf+a3t5{m2tqZ$DCsQ|-&U60U>0LTi8Hc_wM}!IOTA zqJu}jgk#R|3gifGpz@x*2eBRfG{JPqp=TGvI|!yr4Lw~9KS(fLYU$a=@Vx}nC5N8P z4F8y5y429Kk>Ohjrb`SxoecjM!E|Y%r;Xts5KNb7dX_PKDZzA!p{JVR3kar5BRv%i z#|WlN4LxNHpGz=ZV(1AnyqsXVw9pe^_)LQ7l0uKc@O*-E2;TQC5J%4C!^aHikzNOqUdTHZweeV7gS)vytH;1kwhP2@wsuap4K!M*i4!>6VAKg&7tpPiE@gV$(3ZeeKc zu`9^E&!c42X!awC;pyQDAf9_w=1cxwKIYuwAK*M z)Yq5f48M$2=6HiHMO@z6clm-xY&%kJ@LwVPSd%73@E2(d) zzT^H)eUE}6S)btg&iWtJ_qT77^~wHuaiIGs7TGZfst2?v>Z!_)u#=#TN%~sQ6DqXs z`JP`osRx6!^c*I!f^TK7)(Bq~_3405#Rr|7ex_2aug`1;_%v$i8* z4r)3_h-`#DIsk4ZhP59R_7wm}Lme1a8Cp+`kv}rD?%mLa1`%5K_wFH(e0f*LF^pdS z{XqE(z=p&J-Ib^q1=&#P4qSyMpM2v%`-r@ElSp8v)e+h6~Bj^!q1h1O3R+1&_08Ugj! zXN?SP$ai;t{uSF$jGE_h&4={70aEd#T_3*N{Vtds%5Z#8ysmYl}9Sy~KepO+r0ul9fUtHidp z8$mxcc;Nu3Izg#QzOO)}+m%U#!{*AG9W=L6w`&a|)MsyqirMSl@2=y3?kJ-eL8NS0 z=pyVjU$U2}eLuvF9P-3j=rzxz8dP?-)c6LutAbnwgm?R;)X}>6Nb(}leX{ zu_OZXLU~v3cnPh&IA~l%_MNFHVIJs!h-ievyp0P(>o5iVtGsK$Q)DOg-);|k_(BX_ z&xF=J*F6)pht?h^5!ywLbl>+6Y7XR7p+h*)LH@rM@Su44fyDgKx>Xo? z+@kzIXx%5>Wh5ANU|=#P$0Tm8b!H+<#t`~A`V$6@?(v}c@B?N4 z!S0>|B&Mnma@z0OP6O44zgN8N`-t8{^zTdhRQz3vHBO)X>G`QNd!eTHLeEghAm$w?C!l^P*b6r%MT{dWlBY&93cFr!CVZ_X!Uo` z3a#&~KsX%SyRrL4Fn##9WdH4coZy{FcwuP6m_iIF@arek%-wIJ9HaJ(C%?d&6RVxC zaRa*h0M#s8x+Jvj1I#YRW5tPiDzw&q6W$ixHPnbaUG7Fhr}|6z+bJxE5zUI^pTpZ> z4;=QuVGsOY?twFm)YF60Bk@GAW=^oGBN1(hH@3E<%1WrLW{$BSQXdUgwIm`fE1IHp z!J0^0G&mHvyI4nBO0%x9bjEuEE-2qw8e-uu4qU! zx8l*prf9v)NJnbf&C!-ba8YAxQzQXJCIqXa(O9rC9&Bw1;>p$((L}H|+SG)R`v`L) zJqu6w(3gF3@Zgt7_w74)Fo@}+YyZK6_pRe(>NDq#Kc5hBS!TWDC+|NOvOLhx8+)Wtc;i<{P3TAdbk& z@N9%`v@W3M0G9pz;6Z{7e_*=5a8{0Qm8a7elu{5NR3K=V6AJOKj@m8=?_%;J+pj95a=z~|MG8WNY|IJ zm!U0iLBlYn`2%NX`aL1vbU*1uc7BAt0_FUC49e%AgmkiCUkG?C*m)z`Lg1zW$Imu^ z_Ds-*fG-1nHt^RI2xYcphBL$YA^6|PEu;aYQ^zswcS^cMmH`zw|GptTTB8x*bdQ9}9% zG;BX;DE3ZF($vEPGksH`dl0yfP`(l6mn6%{&*w-PAt@t(IQs@PCld|qUI7VJ%7;Oq z%1}NOaT}rXWLt%L=}`lk2GE?8q*=~VWR@pKt}d$1>ZLCQM}2zJ0N!k+ehvA63X|YoMM-@GVFVS`vy3EY>Rz7lYBhW zU-rGEi>rK#w72=O#C-IbV)VrykPzmXMm*EttjZ+QG}$f{puHNj6k92OY?uD1@)`6@ zP912LpbxXX?6Y?0Jb)xKclr<^-D_kL}YX<77KwW47#K7rj0F@=O!`opG9QMFr z4;=QuVGkVkz+n&k@9=G2 z%5mz(@Kjmd|8YnCzIwW1&h5l|HJ{=T!Q-O5a!M0hPLo z4BiH+^cadZ|N>{4%3YFfd(z{gJRW0TAcNF~-X_GN63oP>(}qu z>G$f=`StsAoBQF{@5Obg@^pUvzMFo(EnR>89-Dq|Exla7pQhhOOV?k&cc$MnORrzQ zPp01=OXt_`iRt&k()soKU;2HobpG>H`|9_&(#zwjT)&@{UasH6((hfRm+SYd^!rrl zj?K$Cr6oYoRdd*J_b`Xk|Ii689##zyOHRG zJBrEq*yWt}oQ?bdE29RiDES^iF8eLiZzbq3dSE-~PWD)TKuy-uM}z>`#A>|`gx!>P zGl}tJ%mTl)5*+R!`E*&wItuHAjJ1RBq5K*gGOo?vNu-uF3|0;BSjUj~bFpmkWDWf% zO7bb+;GN~U5FszRf$^T6e=R-7C2oZWy|Z)9LB3c#26pcp2Fk<`80VeqC&}Z*4a9Rs z-~i-Qh#zMFs4n;s1cbyX#4|5|%VS2h7z_E{`92>AmWUXMUXV2&CCd!!G>G$L7p((D zKIH@6NuCEtod-$uWN#%BT(L%|dr$S_;Q%6P+Uqp0ai3YldOEU)FZOt%B+F_xi=ub0#DXJE-B=CvIa2^L_bJ=%Psshi7tY70`yp+!_%9OhNFMe7En+K` z{F2SyCSE1r@mvb|?P3t=_GC7Ne3v*G4dj1%fC=SyibZ7UvuyS*A*j-w1ID0ax44&p z7jjPluva`sJTK)^*XkB6q|VE^Ujx`Ds^ES9?{W<^(3jpGlWDlbzaS#2cS@R9|qYURP%Vdp!IA1b5K$&yuX76ujgC`piFo>!ShBo z{l>(2;mt&{+fSXgLU`9ez?*DaNO-5BiTTymB0W<&H}^QVCrH*W@2=j4-} z1DChg8#x8s;f#T;%g;4(2C`hwK)Pp^GlvSO3_)#XGsvu`-~rcf25upN_v4UB zqMyL-q6|hD99+*1+zG&b83!(>;O25g^k=B+dT!vyMD(d9qR31UDazec-SatvP-YLs zA+r+lkJFTf^)5W;+BxuKDxXBTfo2!O`Vl$nm7F0!+rx2S?I`Xg5zCa6FQRQ-e+Wz?%9%I>X;^c~vMFd+*K2`g zR2HQ&8rYPsBdP55f;Cij2@dQe8g^t26nuu2iO%PGqktOLq8qBN-8uIY!-K>?4x^zd z#h^q#g96u^Ipi>_o78)&fI`Q*38CkDyWkU&@Ht8N0|;q2QhY(G?T-aHz}WdXuu3#2 z$r{+vRHfl-NZ-9ui%Y5IKgs-Z;(f26oocy2*FuAh ztAV&3&AFf8KNoBw%Aab=?Mcd=q{=B?YThec1E~*9ur1Qh^;4JsZy+nC`;f-OQ=s6* z#f#97g)wOpP_8X5^I4QzAHZP$xE%UD0NciaU3w%1CTqbtHrPI!EczN&_)iX$68VWZ z1Zfybks8*W(7}I7K{XL9#DN_cPZDvigcKz4hCLt0$wA?t>|G2+#FwPalmPW>L)--~ z`KL1A5$96H(-;Vd+fnYXVxUmmi#YX9XCNqUqA6hp&uYbDJprK{qAnAkkbs#Cj2BN* z$t(sc#7e5?bTx|q4bJh;=8|f0C8;xqMK2MLQ>AkmSSD7&<^D4mXb_8Fp1+y_jN(+! zJO(<%SSp#%(mKUo&xA>au2{W))(6u*z zgn@2x6zR5{fqmi)sb z)GG=}(D#*E^T{V`lv?{q>Vc=hu z4VyxKP|$zrj{%8i$**hKeTMigsd<_5<;7I*w)#5(u4RCKlZbCB6osZE{CrUtOdT$}i9I?1qUoo~~r zgS7{$WFMFN1f-3!v9c<{KAIMJ$WBKK1agPa^1A3z=pV@Aymc52j_DK;!fGsHmCg0xZO z<8zT=N9GwLUV!6=i2O5w@|ybc!-$=rDi;N`Jo1`*7m$na!+xF6?lh7AcjSSsW~6ak z37ToF_!R`mk<|YRJdit*ZP}x-yw2bQVhD`6K|b;OSMPE%-xyqqW8M|6!kqx}14*&< z&?&cw*-q40DVEtz3nT0XWaplqEaS68|3xq`|47y*qKgdwSES=`#;(y=rQT2AuH2)! zo;!OLIV$u22w|Of5A#2fBw{`MC!xZEqqyi*Dk3wE$4CzK2IeukN24+DzZj~8wtOh`7`jsnTrpVKw^BrVelQ`cjZZak0JtAwPH1D5Hm!8YD)k4NO5}) z2rFso7a_sj05D%bn)1_;c!F*;iAN!ISut0bYf~Vc+qqfCkq|sA1S;Z;<5=T0i_0Y16!S=!G2|qSfMS5iB`btC z&oGYo1ZZGJ6JXdh0u1>YkuQ9TXkwDcCypbcsdQE)vIKX1W6U~)N`@eL`eLoV2_|k| z5AqVKAVVBYtfwJ65qs92qj1DVky+ZK0E%8?%$qovEKgq?rs177ar^JIJX4G!c?*G^ zhrRSGr-+<0q0BdIVki4n5=jxy;g(khsr1cJBq5I63ha5;!ZH8imb(|=PYLxvreS=` zsNVqW!k+Cv+AuaLnL=k!z}vUu&V+E!aL~LC1g)=)f(>ZoyEVtDz#KHMC#su)e-Ge0 z*mIv%1k@#E>!IOqR!Hja4}b*)q8zPC4VkM&(uhGgvLmMzp4!KD>+AB@08N{?{fh!+ z_r7Du?yrE{k3ECz-Zze#Z#Y_gF!sWThbE1kD0N+1op&1uK4pj&I`m*@_G0LM6s)98 z=nU2ZynShQqAGVIXaW@by4=(mP3St;WxJ^lz}62rF$@|5wt^kDnm<8oQw%qjNx>Au z*H#-ox2pN*BMsxXl2(R0cNg+LZ8XaMjZ4X4rkF3vjI6n;&@~DaN8Si`i5}S%h7W|M z+!cB_Qm4IYqwoV6<2m$r;9e%wH%vBgCFIyrjA0y5dqJu(Mu19&cW zcI=;&W0$cPwYnZ$1Z&QeM>Mrp{W_>JvRqL(sOTdk1}%dF(JLmh5GhXY0_KYXm7pB-lE@& zriEL^M6|`L?5&>wr1LcP&jYGo3!Twszh=G z!kCv?U46Ih#H6}6;l?&M?#rz1Q_zckx|r2{nbrLSU=Q{J>J+YHB&VRRyUSbyZdP$9 zbp%~#Qei6gb3awCrKJb75@iTia-RqqsX4?Efb2vPP*k z;6Tdx5<^Xw3>75ndD{WDVrL)j=;gzD9h*9%UGppRQpipDP?wuJ zqY0fpJX1*{AO0Nd|IUZE^zz|#XzGXAKz*|+<-_540EK<{F!xR6!>dQIi!q5KeKh4m zjW;ol_445vwqe}IRRmRpUm_(S4#(gb7WUzN?86)3tZT5d5AS0iJ^}Di?1kr`zO6i= zx~^T87e?FvoIUym3SYy{UA|4#Aaq81Yn%BdtVy|5mzz4H37u}8rKFKtZD{IrD?dpM zJ9uJQW@If^v~-e?)uaF#2ea-}fDGDu+=lTp_Qp1aKRM|Q*D&RcpRvRL46EM7&I88J zPM}`-HNY>h7tolX1-MRtguBdJp&>5|2bx%9W0x*@NmV0sMq9eY{0JN=m*{d+XEdS1 zCAmA5G&)yG4K?%&_jj;S`&4-(Y1AFss5`ickAY%GV&^8lgPV9Z!0Fhzn{3kE#5d$v zDTBPf7DAlf?=`K%`{NYtugLrJ6d)b`1Gw!b*3E#=Xd5mQgdfdc9DX;k!yBPQ6nowr zEZ%PBSi2D5_pxV_!v`t>LT4-`=~iNE zqN`K%os6uBBcQ^9r1Utvhw6Zy9**^o^L#SO~npQ<9+>AHA0jh96qOyt& z#E3C{*C;8rSV=Dk!n%8~a+sS|ZyR9ah8_;$Vc3n_eTtg2 zMUe7xx_}n@4{9-Ckj>7RNUXHP90j&xi8cH2k%sZ4rqUT)a^Y=u#+5;EybPKXKwXaA zvm3xihD`{d=Htkv5%Yypb?oB*rnUD)!C-d87=F387Gr0TCaD2dL?oA?p3-{|E`s; zOD@~fMpxfaN;0{)Q_{+1J1xwsR3Tj-$U0jAvh%M-jE~~r+N;|A2g*Eg`(H+=;2OoJ zuUA8IFj}Q{3~`2lTVdQp)=avQu|m4XM2N?b0kG2 zpUf>*HjA0SOtK?HMJIEkK~ao7w?Pp&Pv)5O2+fIAr%_?vra8xfYbqy)uxCA@O35Ee z>RK(e6POX^ueH?8pr?BlEcGfabv=l*)Q3>|3zGV?UQ+qQ{2GOF=?wUIJIefwYM`F; z8}L4j-SD+3>a7?teK10G`_LwZ2aH%=h|3|DWMc9DwM$fj&7?Kx5%jnQFhz7_=!idJ zS^#j;1QgGt$2DC4a`CeP#*lYV?rLxirbsl&ox|w%bc3se2f3sFj3`{}A`cF0Z9{I9 zL|=#c3S2Z>5xT%tEYVkC82?bva6{-1g+vdb8?7$4$Ybr^mvtC!!9%N5)Gem)C9ETt zqCVFRl9C3uv8~IE8(7RyY|#x9B;6Zk5bV(-#P@Wf-_ z-yn)!2hU5`M~(sDhH3`(W5{W%j+N9xXY|^{FU$u~Nop0N2~3^Ql#W%*F?7N0DkUElr-raJsOfACpY=sgptD zapN3(bOx3S*hl69Sb|Iq_H1H${aEEboza!`B<@BKufTo+ai2(*XkwSnXs(Y_ zX6PbIXEcq|4Br!~ep*2dLSA+Nn*7%wKTnh!x&N(5Xc3$&aIJL7%PGciy7nP2Ut;D~ z)`;7)Fs6DcQ1pFhem-_KcZ?co4V}?S_2j;dYTRUQ%1lk<(iu(dFjE&m^Yer^;F=S|#BlhG`SC$W&jd9mUYI-@Jk6Xqo-OSOh3 zFm*;#I@AnMr434CGDD|lw9y4y57m7)ocS~C9MhWIr87zLUNNmpEuHD3dOW~U7U@6=sU$XGjBYIUA8e3o!OjexC$@A6%A{kg8)ml9K%=SAqux`lq1Qosk}%? z39doEoPtomqd(<&D(~eQiu|ey3`&^=;@H76^8~nkA#tI&n6p_SgR+R9VWK>5zSus+ z2S;QqDH2P4i+x1wFA=8=*4mPUNrMTUQzDWY5SF+q3NPTYKyO*TrS@Xjh=sn-cdF0C zx-C~KfF;9;eb|wY=Jor0(mzyJK~mnrK@QCZ!bXqNi-YonVk`0zUtw?Q@ay2DG4?6G zlrclt7~e#N46@-zu#Xu@o*&vv37519D_f{g-0~Mnt~K8 zVg*$koHlq8uEvbeIY;qTnvFj(ITUSkO48e2nD6U9H;!l78T_l3zdlRc&K5F(JhY3P|~}}al=rCgH&4v zWGMyLrD8C}SD7Z@m?yi+lWOW#Ey9v=toA6=VYni5F)k;GwN1XoM1Il$akM|rXAVDN zI28oY4aTWB^Wf=T^cz?;o&(BG1=K0Z@2sr!`vgmz>hqxyK?O8fJ(2x{lgmk}H!?X+ zED&Z6VW$=tSX4PR!6?i_2^#725`+BH;-_wFypC0qja&a) zX$%wMYkxK+f*?i=chmT|0Q-5^>CF9?*x$tN62o0N6h&&AMhss8aJi5(>0o72j_!_# z5p*b}!>M$j>n7qXI?yG4n|SRG0@u<3k0~1BHacvf!$Wj7?cFuPGs~WEn=R(pr@GD79a8kE|3UP9-$C@N4$+g`X2A|vZ%=X$urp4F zf0mHCtmbv!LDq+`d*XIml-Z-*W_dkH8VyOAkR+DcnKSJY_q&A5B;Oai&Fe1a+KNF_ zcshAzDa)ur3xw_O0>x|sI)t4wj=X-R zJwTwgOCfft9U%X^|Ekin>|qS=E?~sSS@v+;Zg;uOm3PRod z&9Bj#6Rx(!37%O&M1)z77UIwd+8LAWNi%UQNks@c-rcIZyy@sJH}_RhTE}~TjR@MO zZm>l;5;QFPvoEVow+ms4>Ap5)Qf|_u?S0kM%Ynjtj)Q&jMYfo0Pjs6J&m@?{vG%Nr zHG~-oesQ4yHWv{%YnBYW2jKdN?tqa1SfqU$@<`Xn3~x`w(1tZRS$&^AMSav<0f zP?m|n`;1&(<~Dn96^fi*<{l8V^CuJ0QhP9nn0^I!%(waqoJ5+7e|jNYoQwW280MO< ze`gl-<1@LBQa{c>zg}b?QEHE#Y5OOW;|~pJs%3_44rJAE^8X)V8jo~9vq@X+vBS{( zlW0(Ax`QmHF(ISKF8(3KnjD6bjs6!J<+I_8?_SGi6k_Af=MXD(n&Z@rl z9aOysF_7!7{Wm`B6>hNQ+6%cNGG;K0nP?B5Y!{E={9=3X>GmMB=1e$pGISVbUO{tH z9?wRD%&#!T$tfb=ypfa}ND~N8RNWWWFA0LfYu@5o;=a_qWQmN?_vPTYB#7q*%`F$v zJeH4aj%{CumM@^N;lVuLe1f7@&w`Tq*9cNMExn)|bCzt~9bD5pW(nwQ^T%rtknR(J z%Qs&mDFbaU1be8PWSU#nEWuz|PaJM@w>iuGDKWXtn<0FVTa?%ZOGpP6d=zC(Z-Pa= z=@bR#rQn-u-n-^gl6?WP7a*cBi^7Tm+jE(neKMfS^W~gMlhkDpGt3;1+Va4f;WlSb z5B8g<%tC+7bDNi7fnew1{W4*XTw)iI$Gqli7jZX<%_^{mqrf{4My*behOE>rX`{ws zj5wvXc@~@Vs0GEO%iv&``Z&cKhgCh4!|b|l4LL2}eB?h;{(vcmnSVl*s*nwscR-$r z(F;SvaL7Rj{KLG%y=1FfxXItgxXt@7+KQmeLlz_H2>X~AA1Bxuvt=Kj4M&kC9`t$6 zoXPt9h#C*!Dz$v`A~`tUEp}d-#L&c?cd1=scI>dlIJ_qzM02>Yr7qfGs2`JS!*9BU z6ZEOy-e0>-w1pcY@rKm*YV`+fm*a!PvDNkMEw%lAgE)@Q0M|w1M$2;4)z%cLjfUG= zS4HVV!7McOp<#R?m_Pd49Bzd~e(Mty6nIfBm{;|s|vaCwuyI2>VM^jHtjR*v$1un!|DWaY?SNwt z8ey)Oy+k1z1tsc}UMev6S_+lBmE{2F7F<3$Hb%FI?YNMoWcmTcDu#f?FojZJ82 zZ{|AUTG5th2Y>F{`PFMUC9*1lD1cn~X={fa^-ZmA(YTUYz!7d* zgOs}sG*&x4G_JZGI&00+>MA4NfFGEoitusjhT7KVwn$8VjokTFZW-BgtCrO0DC?uc zrT3oX$FUFj7PkC&HUfhh3RO49T8&lcpYij#Y})qo$|1lP<3(q#yPXbj(N z2aZ2x&YxR{?s_z=ZEdN=AcwYTiLStpYocwqooI}7G-NE^&{&VQr_YhAMnP$0dAzl$ zJrOl12sn~gV)$!pHW2D{jVllo&}7N9s;TpeKRo2J%&F9F`PLEmWX!Ke5R9I6q zJLUzpLbn;l;qU?)m{&F;x;U7WE27#b^z)`V&!nv_`a|-~ZF+z}->p3_9FNpT z6Z8RhZo$g7HX4MS)=#17C4s)dW2;s&Oe6ACk^thV(=kobZ>LhLM!*l9Xt-oQEBomA zXEZMU@sq0TN3;VR8>eZG!e7Nb;#9>x=A+iO)fg^0tZC4WMeBJ)s>e6x+tE9v>5a8q z4*;4PphY+lSwWig8X&4yFP0Lt-?;tjTHBX5(YNduMPkbPvWr*EpMS=Ds({B`>IDWo zhn|E{xUr3XO16aueF{t(xn!$^+Yw7AjK#!HLCYf=b(gsuqYzf#6j>2B;Nfs%U5EDh z0^Oq#*ldY(6Z;5O=+1ZOUP zrA~Gpc(E1{9}dS85d=VO!+GKQNMn;h9)`Sn8Xvi>!AOxsAw3&&KzMqrwRr()$P1gQ zSS(DcW2MltLRZT_zKe?K-TvC9);P5if{BMPTGHsg6K92E(YBZoZ*7lZ<%G4F?8FI7 zP6&$gu}+E0Ntd)&{!NWnVYN;m8C;0w;n+zw5z{*2jRq!~!)0X1aS0QA)G>w7NYI>G zWU%*X5lMXP5@2XKl^QMdprZN@`lJjR8WX9DghP?|bQP`$1vOkHd(l)hnTorX=qj$F znVmOd?!w^I@{`qXa|FjUC)!)0lUGDrqL`ilMq;%MlRL(b8#C_2;FuNq|BSK0F|^ln z(~dz1C3uxF1}hnw#mCgIibdL1BCVb|6-Sj;oe&I>s@H zH@9*~&=Oaztia=3@M4tZ_K*v09%X3qQEPM%!$yjE*~idZq?ou~<;i6<=;SJwXZhwf z)=ouboet0B??g+ru~dQa)UIkU<{rW$5pZ&VKnbmMF;1k`uV_(HSvdv6UO3U-hS3I% z6O&6u*_D&-r0}CCRVNb&ZA1>dKZO_0)mTf#Y4)ReQmcyJy-wDty-DjvD3)6Bgq25? zo%o?_hbNs~05MA%hO03!IBAk60uWn|6Qd@YKw%zx&oNmL&+^t*3VuD>&WI*dfWtCn zk#qnJfuK)~Yc#aLODwcK*|JLMX0;4zY&pNZF}9klrm>falRqn7Qfrhpv^GaeYjBLj zOCh^GTo*}1O6#I4qfM=C(O4r90a_wLS8H!lD=h-q zvluAh6@VPiNl2aoHS2A0Vo&^#iUSAQo8H54aH!ZeLlS2Cf{C znS3vD6La7d``s?F(Aw?laanj!Nn!W7J}2zwuCE+eU4_+|^}{Tb{xIvNEKy_Kl=V=S zSY$nv^>7wTupZ9ZMTlKluSkUAvo>Yjl?A=-%6c#hdOe)=dn8hcyR&{nCBFfO>)IuT zFhRQsGU%q8Vco46eybUX%j&XrTF_#r^}G#n&)YB9vicY7-vPmbndEK*0TF*- z{f?+=$V}^7YnzQa^k(g{->^aRhW&;c0^e}&c1wY~-Ftx00(aT(*bw-R{S^^^W$z&> z76_4>@w))PZgKtI;WuEny1=qkVim2FXYF-&yTQ@zzA^)qUYT)KhOG3ejOz$-UB>ki zp{w8P{@4v!AG`Ov#XM`jn~NPHt%?~CH{(VD<{QOLLQ1@ zvTqZ=6e#$mxWWYqSGcZ}hFDj+ZUI6|*e0G7knyB=lZf9Gw-A+6%;t={Gf;AO#zqgs zZ1h~~k&0aFxf2L2W^=~RGa%;Y87~m=3mJD36^pUn$oMb=VN08}&GU>0<dA=oq z-+FHGg7_AcX?-A~)4Uo_{a9C3ynvo@QL68)p*dP{uIT5nx# z$tth59wNj;*25B!VnO_vJ4`6B!(3;HbF6ier)Cq<2MF*WsqOWn;B9z^4aUZbWFyEF2SbsGCu8jIX<{TQrv*wkS zINQ1s+GSj5{6x$fv56J+pyecVwe<_4_yyEWQjq3JiljViU-mz;sadig&w-+k=RA=k zee^`mAA!&+@5}x+o0=v29zTfh@&A#iv=jDa|HzNl|B=M96RchSPyDWHm%$&_yZ%3; zm~s#LclaR_!SSU3c|W(6%ppu%);IodAlz_eaL%fz8i_cPfUDhuhY%U>Zuhv4!cBOH z+mLf@4n5fE*sQ%-2WVhCkhL`%1K`%|`?IAv_h;`Q#E$Hz$=av0KLC{ElUz06+Ck)K z?H$?Ak-g7>P8#Y;5~FqZX06Sp)?J%@T{ar>y6n5M;XAHk0a$l&;Tu%P0@CwS(y4}W zNgRaS=H%)nJ?9gcWqp!!V*pZb4BQa_bVp!QKw7dX@JryC!TLPsAd%i3co;OO0Aj!D zg(5O*ZQvRbu_^G=B-K^DP%g{5h7h{BnQO1No4R1PcWoxrSetoSrmX+6%#XfCRq?XT6^JCy+S>cKWXMLEyE%$9&*_%(ufQmE7Tbh7iyAej^dY z-R=7fw8oFXucvFv$gr~TV;Cw49%~(6W>_jY;Qp7}x-{d83>wR}d8~&qpwU!#f0ng9 z3%^TY-I#q#Ha96X=1;S&ZP{Jf6yy*3tw;S&`VDR#Ya7~2HjBzqb6A@L+kmBJP}xrd zp9ZXhSRXjdJ2cBpZ0tXnUP6z=xbU8OS5fa0dZ32z`_k|P5?=p4vgSG&8T=xb(V@B( z)koV@?83-3_Re82c{mq2lB0ibSr@ECMi>JO{rkxpe*-dBANt=3Jjv0|&uA~)tMHrg zOgwEG|1k1I-=*-4Txu9kDSY}Xf-fk1`ircuDt!7Y@9!vl`m5_7D}4IbE z4rD#m1E|-4j2I(erRdXN+Z&_s`u#I%KibAAeEK_J6$+pJ zCe};D}1MV1a_WO$GAx0(_j6#Ug6WhHSMz^^L>oI4z5aocPBo4bTVHYb0@DYK>XVcJN75Jl8=!X? z*@phza815P)tmnN%pWj5&*)C;N1p+Ys4%+l;IeabE4y@m)MdGhFEI4)fouG&tPdXl z4Qh-`i$NdgjbeyiE$$0n34E{*`g8iBr*G!uQh!wK)uebY?}z?|e(-m)oI@+7S5N!W z^Y{JW>0Qmf==b-7xA2%}U-Sd|!P8@*ebJZpgFg-UzWh12ANp`V_;^2f`f0Yl^trVk z{5}2PAL|GI+kWt`_k;gyKlrcu!Dm^0>p!#~{21W-^5=|x=obM$;?S@%&hLlbsEsA! z30&jCzjfu zRW*hqu~=j^-HgRWqxu+bPlxN;o10gI#R2g>hF+x3Yf9=8R9s(l!^L%lqI*BOG?~No zHC>FG9x98Aa{NU)1;&hCw_g;NFQ2PC?nGH6ASI6QrR<(#T;)!b>}u)*%9mWj9Gafp^WT=@)7 zTROLL&djO6;sSTLDx?@f)8+$JGiR!1oiY22DV4LsXH1{IpsFTZQ#oaJRTvi)`5qNr zV^>-A+(CFIS}PSfkVA1(Ll?3^c?MtEO1rap$Xz-mF?ln_d3!beR!PN-*)yk14Ua83 z5#p=TZ=nO#>(+?65#YF4kGc-MpF$1|%NxR}+Y8|Zbfs14rf$xWX3l%k;qZ!P-1L$c zRmn?p`1)R0Kgp8vKY0$K0pa}K$k%WbX4h_sgG%AuXKDO}qT zNnWi^Hrd#clTeA{GPh9@U)_wG9!L{0nKtNL3+|tk;KFXn^7h82x-pG)21ESBP)XhD z7H}Gz;?@I~s5_9ofH2DNNJ4}NRjv&Wy_9g@DnYhn1@14GB{$o`II-RbFwfZW z4#lt2GR2>+zd{>z$WWQ)-=g?+N^fe?rt4S5{JlfMw_qp!DFk5C-^tNwg%V8s1=!R1 zJAfm<;tg531$(E16sQxb%eln?IQfG?S*lZd-^97;wVh5cLZOp?Tal#Jsn%D^(6COg zOyk$r4RqQ>ZxA{*U9U#b`Kq&ieg31GJTz6_hd?RY78iA3{nIRgN;EvLz}LMF+h=GW;T zP~zm*=b_z-e|M5oW;CBp_oVUb^W?4yNxxkyErjJxvv52(e1hyOYnn6SN-DN}t+=RZdAr`y>~0~0p-T7z@b{5mb~hkxnSlIufFsDx-x zrs{$MD*KEsP-44NCdp$uEx~&1NfIG*^NkYfRP~Pl sSb|;0qn>|heAKZkIpneM4w+t*7XRt>({<3k_;38Nas$p-d1ps3ZXqQ9uLXF(6SLV)pz>|I8v1qtH)X)~TX(LmDja{K&b0ivSi(CfA+V0>=h^I~$V(&X2bQYeVrw zxW2QaEgW18u6iv&}!y7xp(Z+CaIhqGd1#?q97HtVGj>p

_`GgriN0d1*8ejuS1ViW*bY)#2pown$?pyfhhZSL7uQGGHc?Lkq*9wzgO! zSeHg4$soei9&74ESZcfLyF0?cx^Sqe8^8+225aKsP%=CtjhNrmbZ)~XVZ=iUED1-$ z@kry!@Mf(o($H9uh*iwemMmYope8t@Vn)SjsrpRxm5~4RR83)=r2!7&*R^Xia-?&7 zB#UO9-4a(EiQo*QYkP?qo0`|vJUm!n;}6UEUf~Z&d{4DaS9k^YIq;U><~!)X=S#eQ zzD-wpY9+qhf!|kR^UZeP8zq0W179cc0SCTH>RIc+D?J+=_%%{bs{=nslQ_062VUvv zap2GQGrP9kf!`qY>~Y|go_!AddZ}l>1Ft6Iha7mNr`LhMSnBC>;Ctny{<;IN^c-^F zFOYir9eBUgbJ&4bdb9<0JXF75B=vY4_*$u_)PYxe{0@9b>M3{N{W8w89eAau+JSG9 zdIApoV3Ee#S_fX~+2FvpNIk6%{GiOkE(c!e>2ctbQqOh={*bh1j{~pt>~r9^NIm-< z_+F{!AqQUR>2=_Hq@F$pzFOsv1F!Uy)@Zz`elL@HsvP)U8J`0V{0zz8@4)+Io|P|T z^_tROCH?9>+s4zilx|n~*q4FN$-p1Xz~^V+U(dkHlw#_k47@zWGJdwSM*vdSaZIS@ zqvl3IG_`rE?Hb_?g+%GAwgJMMc9oB%)iywQzAvyr&7XlMn%c^%?Hb`!j0jUzO-GIG z!HFWZ&91hq#GjqQYFc#$-kX6BWZ>m33{z_}@Oc^hYcuef*JB$p@bZ+yQmq+ynQDyh z$iT}kXM9%%UZxb|j~ z$Pesh`2P}2Q_MgQ!(SqphV4KH!`Bl`Lw;Zb!&?cap*~Q{@MQ$k5Fe;!I8HE4i33#( zUqUbq^#MP_4FuB=AMi1J0l_r12Q-H32+k*X@N*!JzXwkOns)={EwF3es#6iWUDh%x z&N!SbK{%ViL*dLCI+Q=DhZvudCHTvj|FrQ`O#M8tV=(ZdEJcAe(WBelQtH3fE>$CtB_3#WLd_Xc*n+kYM+iSWz-X-Z&fO(|Nb;Z`&e z*jYct(-b(lm}NSPkdD6fPaz1lP1Acnc&q=e&rYsn|D^x(Pg!U@gucu| zHFj34hnVUgbXGcrYer~XSob9A=LHogC+e;e6eWoV2jOJ`sxdFq6jZJCH$wLZ?`QOfi8&Je;U6|WOX2UXI8s|oB(PC=H{Pw`EEPPt()t?NVtZTnOiG;oxrhb|KQhkhQq3n{@rIMn~)Uytx_ zO<>owE(}G)^+U?#{tv)|yj=3w$2ezTw)_;z`(0=(u;VH6y&|yVx0qdGnDLS7fo;|q zkQV(ji31S{?09|sMNg#@aQd5RERPk68V!u2+tCOdjlj_e9F4%y2po;T(Fpv18i8}Q zXjDtT16mwPB>nX({ENDh;b>lJCoq>*M~a7{uQCd)<`t0 z#kF`;+pKMlYHbPpk7}XiTBuHI3b%!m;b4N_S%sRK;^73y;i%RUP6m@u5R8YLsSCse zW6m8Yi?HwhaA>F(<-S4O(4y@4P=hlm}53<4MJakA{ZmJ^enEYf<_>9va$$vI^x*L`Qi5D>Cw&}Kj)-Vr%VQx z<#Ac89e|JYFhgzh?C?VDt?*erFC<(C_M`)MHE=z^(Zdhg{Mh$k-vV3&r8Ym$w@qJ_ z=hthp^L+F3Jj-&Jhu%H+{S%%;;3-C2Z$O#Wv)f>7m0c8%D&VdL4i8h9_rmNvPatP8BaC@uTlgCmz_-0u75~8-Ac30KFRY5Ybby3D`R3+djPxo*Te3iFlyn z0<=$e=!3xD1U%c%vKK)6iX1;^UgX4n(5^yV>8;W)w)HN_(W-#10#7mWtxfV=s|WH* zw;4;|M0IvvDOy7RoC9NJmDrAMMa5Mr(BXBeVM$(fTa9 zxx}_umgmW`S(ck*d95tJD$6@%`8`=aBg@xh`Dbpk&DDoFcdG&pwQ$8f=ercc6{w7IR-xE6NEs8EbT5{@F z-vg@e|D67*@BGwveNK9h)L%V{f7(CUls!(iGQW+Hg$>}SzUNCJ{^{Fnvbn^r;f1odT0|HcKX+ zOoQL4JaL$O`7!i)pte)lh7olD*ro$A^3I?jgOgQ0LnMayui(MphuJ0b4`m03` z$<&q{Lm%^qXVIi*mG4QIUn>fr-&2?KI2hK7<6x_2wfA?RY|xB#Q0LAq+X#+As{1^1 zJ^zQyxs_DU%bJfu6EU2-J!j=yPdLq}f^K)-#BY)e)%{tsJij5ChoLj;^g^;)6ZF_N zYj(lIu+1Z)h?9huKOs<96WO`4j(4+NfTho#R;m8^xp0mhCNIZAEza ztYznV=fF8nQG$Rx?-BsMqNZ4*mYvURrJ@|Fvwdu+Uo##;;M~56E1|8B>g73wp06p@ zIYqW=QH5T}DP~VSqJe-CABEQ^Hp1$hF-$4tc5=qD3{>AwaVspnn^boqIzGM0^CGE! z0aokHtUwdfpiOTnnn*pP89^k7yLjSTV5|5&>U)IuCQk&4#8#lZU$GW~PZO&V3GY{> zL*E0+do!!^i}ef~OU9LpLpXYG@p<5Jm8eHU-o4B=Tg)JBUn`gbO11bdeDK~{um(Ut z945+bB{!l^YQ`qqtM^-Z zH$$dN+yz&?_ZEBwR`rM$lDUtyZ5QuRJKru`3bx(iX?W=UPT`dR_J}W$w)=~}32pnt zDpK%YMKosji=9Myklj8Y?kC{;g_OPziT@zgkL6PO_KMvIw)e?`2cfM`xT&3|+3kaZ zp8tFM3f=+bb&*SK&lUb2z#);3V0(X3NW-LGTuJ6UU-%sWgJLI9UMPG3z+u+_C>k%`u=>@!0?IVunhXnG z%U=SZO1Rzz+s|^30We#*o`AO3^JoB83)e@$y}`Z(gv&w;Kj%hkh3iu&c$0y(!u0~2 z`vn8&o>j2=Ee2YJ>lbMBmke|W*Jn`hHs?f_a6JX%-!1G!bbEyBR%FQgOxZ46A*lXU z@nJN*TWH0#xy9sXQA205mRrJuM=OdoT%zTUVZELrdi|3-mfiG;i@}>)%0Q|38?@(+ z=ON-3&%veK2@FgTHxp%I4!z|l7uTb~++zxIAX+8X6XjS2W{b^;OztEGs>N+^EZ5H# z1T>R|>Ljwvq>ML`@GZB@paEmjP%AFg+iAq`=+UEj#IA`;V1pjBP1TIQfUb8KWhjh4 z(_sAJm)E;z3f7DHG$ooZD<;Z&n~8PWobQr#ulNoV=Vv%f zplMCFX@93cz3M9l#vF&k1e(~SSN%kLt%S}(=4m)^kZ9VmTcG6AjICtG&q}Ccje{ic zdVYumnn{2HMpIK-K&t)@2>KiO6foloV)%IprH)}DmGw7EZYK@?V;9w zQSubg`-o0arAf(dfdfsAYDO_-$XmA7=@gY;+VvMHwr`hwomy)|QtO9oD?X(9J9hmZ z%8qwSreX-26*zD!G}-7AA(n1RGyX{0-YZ#6oNENvQNK5 z&$|U|{`Cl%Hr;@MSNd;*^Fo_(1yK5a-RK70I2)#TXXQVDy7@2;9MYFiv8~`5J8b&M zqjRCcd%EvEV(-Uc0!>3{R?V0P8@y+f&_|DE77py%i4;|i9oH(zKms+>h2yDy;hmS2 zgLsM+WX%E}jcZN(oPZhzJmP1hcOe5lu@_PCE@GfmOonprVg~%;B|0T6;j>z~c!q#L zel4_Bi5jweDFd^`Ux~7efoky>wR4V~#h*cNyvvzVD}GI?SFq}};``L-N(MHFdg%0? z%RsAmANk>}WuQasB|}#+&?S0_QpehQ#4YFq?`obOw+l)>Z#`3Xi+Ykdk7f3V%ZcrL z2KI^T$+oo&>=)l4wsi~~5RC|t_X76xA@MGH!MmO*z2Z%B?m`Co#By@sA_fkM4@l-> z23{ARl0QKP4vCk@pAZB6;=5#90|SHNWQtoO1BYD+nA5~{O}JhHTQhs$5w3BFTPst1 z!u2p@A`FxY&G;c1cZoqK+u~Yp+c&7AuP0a9b7@A^#5l4f%KRSj40#+Yq`A~5P9nAr z21)N=73WPO4uRich4NgvIQv&91>vx!w#i(FE@nY9Hp;{)RB zGRDH3;!^Krza+CtNzoUiSre%vwn($CBks$KXm<8##&Klv6~?zAV|+&L^^|^sy7?&% zZW?#RxF)ePp3|N{&7^9v-@ElZKw=!lbsL9I6Bg;aTE_A$YWErjd}298;M%<3LNPA4 zXHj-uXN-e_VxM=%HKgbz>f!5)_oG!!v=YP4(w_mqHR~jD_y(f^Y$i2o(jYUb159$) zBzco=7)-imH|aLO2*Aj!BA#yxt57fZoZ@riTAfeSo@s`CqP`0hPes0$F5)2tppx%u zN(DWz^Hk-MuYPSN6()%rq{}nic$%6FQoe(OTHg;k%{y0bsHWbzfg_7ntrVp-Y%7L#qKJwt^E8??;MXLp96T zS4}8QJN+c&p8l379Fwo6ySxQJK130Cm9YCt=~ zj}8@2Vk*Psw|pYsMnc%c-YfA;b>c7K_*0xx^gsinNgG>&hw%4HZcz`+bK}67?FafK zK;_sq-&Z8Vel#{6WJ|2kHvxZ-#FH22+xT=YS)$&^#)tZ)KapG%3zAIWSf6E_>?hrX zT1CpVoHlg8mkP;z^}vp%2inBmH=+HQH&Ojk1y#kGGBSLjd@hr!Km%`IW(Ve>K8InG z##c@YRDY2hP)`ii8w;_w5~@7Zz!#6F29}^keVqHee6~f2GWiV&P-aL$k>L@eTVV^vZso}WSF>8v;S%tU{5>v>4%h|&zgW0H_MbS9^Ajb3+2S7T0 z98&8_s%be9AUCn7dc0amcx+Y??x?CxDD$_t1szCZ6AR0K5i!{*NX=Kt8_} zssh!#br}nwDeLFpDWP~Px}hqHF^lpAv;Ak%JsP&u|F=_0<(vk#4mMRiDV}NThpB&3 zrgpHY-vr?n>}+ZWoBAripJE?NrY=yXQeq~4rmP!B)+w4nv`chL88t)7Y`2XPRmeDL zSrQXa3tOh1aYrCao7nqPh;a~GI3qp*@(^Xkxxrx&dsASc1l@Fg+bVMK@GM zF{=3eR%)X737GVc;x|>MuN}WHBRS4v=d>f@7l$T}-+9N`^AX3-tE{G}b!|F+3U849 z%=mo;6V@_rLcQa;3LLbFy<6})lH<3G~BXXkLw(gW2~u=B{6t44<^4fF0}W5$hRjn|gCePg!Xbdt*2ya;#@?tj~oJ=U|`sCN3Rja*ELdf)Mt6 znsdJ=6$@2SXW-L~5HxY%+rfM(b}je2lAEupa%O>dymvkb>IKpbWCJ#__XW&AY{qy$ zjjzig-ie(qnhoO_^5 zl;oRcSI7$lgYCJt#Zq+LY z){e~s@qC>;86WFFZK{nPgH}p(N@_xv=;bzg31-s|1i3-z4}^_AZYylnuReyXFqVRN zR;&SVCCi*mSAS~po2$?yZDKEVOZHZfHbFLuJ$n}bT8!|k*r)CRpx?N5>NmLDkWWhH z<21vYs;J55@=1C9bQA(sNCEqEjSORTPh$=rmuM zw1yJ14$WsKrtY^5<-}ZTi8{I<@y(MGG~q{BqE1w4xf>;#6SbP2&(f}mT+PTkGiOfD z897UfW}|uC(v~8pjWHQ`%$50CPML=Y)>2I`y#f=VizUmvQWPERE)ge=TUsQ*<*`V- zOxQ$y?1KyFbZ2SPLCdB>qH-!kijQOqM4`L7^s;fJ!#hRG$vG>>z->fsK)YOA30z)< zID4Ejm;~lBYyL4}dQqKtXh9AsSX(C6<(!{GI`9|XBuLeQnZrzi2ZcpwJSWHYo>+?D zk|#45#YIBW%d&`}#LdvSDw=k3fjB;|D94yIVG>#DLn@sja|0)xX-G|YQ^B2Sr8~2d zt;(@uc=outI5k$8;;ft;gcMw8iy}Imqk)G_Gi1U`8%{;fXDFLlqLKfY`Gl}Dd{!Bv zS&4>EAKvqJLe7Tu+8HSdMi+@^X7`!wq}_vaGNYWyG?&r@U4h9q(;G~EoFQ`9YTDTq z$p1{i>I#iqj^@$m(Z*xOwD6$si!|Vc_%tt<3PBJfCb{V1c{TP+vEPLKLF{i}*Tp0~ zA2XWT=#E1Cl?Xa&1|7_7!qGjM@YA7^4rkF}IUPvCqPq^!Oos#==*|_?T zRdnHH71W!SZ!HN^gVqA0D~TS>OuG1f~@TdZsHaAO6e#<@2n!6OoinKzc=hZT){+^Lk zACJ@u`<7169b1IoI&+sLru(U9&+CJqNSY&icDYpwl7V=hiqZ`=oQ9b_>*i@WK}A+(P4iW7#rbkk$tgi#aZzjdTEJzzw`DGQ)MW)a>|t)}x87%uC~GZGlIE|= zKpqeAamITirG;Zu-ogX^oR}rfwN7vubGfUEP(>e1woZui@l4CT+)l#f7;+RC&%9v~ z`i5?gHru&ZF1Ne&UcGN?3bT&lwbiOHx*oB_EIk`1g7#n}+7#~6VV0&N49<&AeYcSajWU5Pi5j7OTn2`$=yHaglujp1NNY;!mcWvn#4*e({( zQ9;5gAJiX7`$!G8XRbnYwTv&(G|m=Mq_E+ShTI1SVDoEDS80rX_)io{Wb!g|Y52 z{n0i@f?Wd&5wiotSa5C*hc0cSRgdv?9R-f@?QI-q{2e&D2x}=L7#Xaw=4L3-8e^T& zWN=fc4H0RMhY`+=!3eEt3|6U3+l0S8kHs6YgfZ(4wFeWlXmUoN(IwPOBaBTl&ymX% z#~NgJZ4APlmSiinfR?xmU|NQ@c(^@8=^EFtesqhU51shS_?Bq6$xmN`Lb4Hm`yS@r zQ{9#}IHplBJL0J*ho~1d%5W7hYB(D1N@{Q>v^j*(L)>1YIm3|Vwpc8V+}nf%r?xs` ziAXZC34d{)*~hA(beJ^6vlB~M=cj7frRtW7=jUKl;{Q4S;aNlbXgJFBFiuT(ukt zoSHKE!N+458WNoijcuVs0%PCqZn;FYltT0ARR-XFLaw|GNsuV_BqP=>K&PTVkc645 zc2g$G38gU>ZNxl*E{KL(Lfi%19W>2k^jAF58fnIw;Ykc28GBGe4T)G=XEMxv%^3%4 z)-GIBQ@3a_rMpy)aN2W&8tzDQTKzkngOqw1GpAe|++MRAvsQ35O=FuP$PrEn=^ib} z!0~Qxz+hHR$5n+V&UD7Bn4lpUPIw^wqL|Bx(H?DxBPTSknI7I;hnW*RJS%c8GchAR z7-r0xUS7SuLyblm`T1%=^t4+GXqIi4lU;YsVw?fS~HeE@5HdMoryHEZU8hJqGhC23$;FM zc+%v>{&Igc#X4!#`P%ODLU9>Kd!AlYS9fk5Ddy>lGEqYekjj|6A{|MZYI!zP69lWI zNrGn!B+k;6oHx+W+!kt~)VJ4}SK|ls9Gh$V&(3G`02;!qjyWOG8jB}+G6NMWbA;oY z!W>JQW>s!rIS)+Ye3qg1XnKw|McNTtTDqeV=_ms}Y^jeUmd3|yL{pK<4Yt|29zNQk z@2?x%VhM^o1_RFzbTUTM@o+~Rr;2D2^Kv-O%Itwd2=wYkoLUq1c>}GJ|9sXD%F`Q( zb086F?(|V8pI!;>QjLDZqUwitT$U&t`8cII42pBryr$?w7$lTjBxA0o~ zfly+x%rA7OoCc0qn7^IFfnVA1*GxZM{^f&zT6?lH8lKl;FTM{j6mM*u*EM_Av{^I# z(^}O3b7%Oc(ca8IQ7{cTkmNJyG@OU&gf^{tb3D|s31#il8XWob)Cy9pGcm0*x*6xb zX-WFk1nQ|3VVXCnA8NZ-c2Zrrl{zIhw%QjmYPM{%r$M+KNd#LOG3cUA9DZQvEFga; zK~vWkDoJso!_N}%;K1dUyg;DfWn6q=GULeG7kWJYY37#Kh+u|~l(hEXK)Ty%66(st zzN7=6efh;F!S;>}>!R!<86oF7I++If;)YD2iwvUBl@V$OVLU0bj1w;+i2r!;8)!YH(pSom5LIRCK`ubJC~$pbVEBkXU{v zBTPqRvK_tD6(=;Me*Xe~a5U7}oq8Us8e*|FGF%#L|Kvubsf%doNrgrpTxSKHsa}yb zwaYVpB)YLP67MFbXqIE<)M`W(jap@EtUX*=k7FoN3EiE+rcg3e*%aOsZi{t<k zUDs4D>WGleaAzWe80y5OeH?RHWoIH@8HqNwbvA`7JGz05o?0<|x{b$=R#dh$HdbQn z1ZT~h))t9&c1>%Ec2-WGp=5?DID)Yug44;cHjZFPbUQfGR#Z0HbuE!>Y6>@3;A#{- zo68p_(O_=no*=Gx)e3=k0o3CVOLc9CS`%LJ%&-|__R^h`A~QM zodUvlin|1xVcsPk2EuMqGixt~hKsww*ZnXtWQzBSX9Wn)im&R>@Kyb0-PUlkem4+G zL$7#2K*tMWfS3ow-Ncot=8*Xta_cwdK?`aQS}$6*nis8ifKX}{$TFFdm9|y zAud*9-fVpf&t;g=9JH_k?izEO>n;~-QR0Kv5WYDvhpg*dh{bg_8R9zrn7}#=l4L~K z4!9m96%V?0x?#^w_YH2_o*UdZ0-+Qha6RUN!pB^15c3jw5-_v5xK zgv{>(uv6%J?nkJmHuHe~piT|yw;E{hRy?n@8@$bU6o^!V`eQmZsJ}zZ@92*bmum2U z{;CeYUbV5SkT$ycTm84-)O0u3%<4r`;I0kmogU3)S6!VR*Kt@%45|I8K12fP&Fppe zksp2THz^cvy5A${J@@-EBJaCDR1pEs%S3$N{W}!U29KW~hSE*^O#^t8Ltq$m|Al1! z;(o^i_3wDz_1KQT>-i%P%JD(>=WaOuxqF`n%=sl@d%jdl^dZtndM+9T zPak5B#7|!njfCGd3jP-0NAmZcQTV?<3jRl<;NKku|Ho1A!Wh|p`if^Hzx<=%tAHQL zuVtg~uLFK^sy8w!jqzk6i5nAKl&61IFPNlf*LZ}Jz>nZH#eywuu?E~BHQ^C$A{grI z!hL!>ZhVsAri!YOIp}615)8%Tq3&Qfn#8R@a~w~ygH4_7?cET`fcSaLFxJdF1$kqU zdZ>lx6%vJei}b@kiK7Q$N+MO`=RJx6kBwwCB$q2yU|ou^T-ET{P*OLm3Le=@RO<1X zdX6gb!yc5_IC?0c#MCWPFu1sG{)$DxMJpH5?;29PD3pm9-e^Rd=;sU16_}oIm2PIN}LR#*aNp=a#5vY06pqM;PrVlEL{IzlE4Gky`r)zcHCsY@0LeCnr;3 zqTfx_DiYo8c=&=c8Mn(;Rg2;|P6cjKD;hc@ZB5f6O&UY|=B%QrI|@mSOFRN$ihN!< z3jBLqj~gNkO<( z534!?qpF1FXFpN_e(jR(c2f%D(H0xdnBM-~Dn7j9-x|X-&YSc1ey2#hD%4k@3a&uq z6RZ)XrLJ3b1+x!vB>x>>5MmIP`Sr}WhAJAE%iTQzplt>o1@ zT&h&-Zh?h2(vi6Z0AQJ=l>KVmD^*rWW@W!>N0oFZMQds)nEp(UHdQKlr~Nh;z9&V6 zXiEN|lvkx%$4j-Z;-~zNO8Es+VKv=|U{hs}beQDnlG7>Q1st)+X45BUd6LGrW5YJG zHFHY<$dva>IaS(!#h8|m)CnXu1l2_#` zpk>Odb@=+F{GJS1swz2E(*0|ud`~rTXV9aCyirx{ zD1K@ybL$5{IN4l^q~uRbVeE>MSLGjpR`pEQ$7TCYy+`l@aRd&EK9urT;fw0b&B^N> zMZTlXmim zq3+{HlbbQqEeiDq+V0>Pq2 zaifUEulrKLE{cjRu0^z(YE`V-;@7IEMX7CV;!?qdYPItFoOAD;c{3!f-{<*1|KIZP zChvRiIrp4%&pG$p<=y7JxN7!vmk@^DOyg7|1sO(#D){mznu2iS4KI!(jiZ>>N);WF z^W;jDPK|(ssSca6K{{Xy@-dm7q^UVVv>G@qZ)eOdbRbPL8DOURHRGG`R<)bna`;55@jW2f0+Ee|v1OJ?J<$&Cm ze^;>osii-hO1cpH2<*hC_3KoPP52ef@7<21-|b#7YF(W~f&TCy3OWf@{`G$7NwL1< zZ|DcV2J%!$_o`(NpuXhn>jz&7$Mi*icR%#s_M^{{{optBBWF%O^gtUy?CG1YA3az1 zBd4Svd>sV$W$(g%@RR$Ib4x$?+xn4nPCxW7^g}w3D-qq(G`vHL^M`2 zXKGVxOSC4kyeTTn`Ys9Ac0|JUjV+O;#tT4Ly*fM>Yzq>x_Syu2m9Z7!>PRdet!Zy- ziiQ_}s>TRYt+nTcYa7lB*GC$gjOx|1QERxetu5M8ry-)Hd~3^!@bp+~^MW`K;e;-p z5lzfYM4JIFjz-RlMeD=BoU#1eC@QXAUDZ(=p5NY*Xl#yF#bT{7Ld9a?1{71Xv4i zibi522omBz&unQ-gwevyt#$2aQ6*@8G*Y)3z#PVgr^cd@M09KlQCU})^eERnBia&; zHP(_YO^wTIOX961@P^)miqc`B>x26uzrk@@ae$p4S`iDwA*^4WFg(%hK?t zD||y5UQgs5Y54Cc`pz``9EHCs4ZrUgsn5-6cr9mh8opY|*^-9ersQl-!)rNRY54g{ z&dxM^P|4YyhSzfTrr{SUIo)aaPSq}7rs1_5V}9>;S*qlC((q+RNxH%`yp|J8!!J~F ziqr6$l|JLs@LEnq8h(kA6H3E(DLG5h@LJBYH2m30PD2`g@6pn(jx@ZM)0u`3D>+xC z;WsP)+?y(@=X?UYp>a#r!ujO>5;Tx2kooV=LW!LUByq2>!4ZmE;=}yCM zK33}UWg1?~F&4;j-QVk#98Vg)Yow$rOv7tA!8ClPl2e?9?^OO7pN7|RD$?-hDLJ7u z{65uQOVaRK&ayOoT*+xj!|zgZI@0i3PG=f^m6CH+8h)Ab^UY~^EoXBY{t_i;OB%jf z$4?qw%lR@5f25KVsOjB~%hdX2V;a6x(eF&dFVo`-EiAF=cxW3X;Voy#)Q!ZHSw3!a z;582wYA)8_@VgxN!4CXx2mVM0ey;-`bl?k>U0D7ZnGU>BEde@x zr82#F9C(*TA`Lk3`W%vq3mtfMD$QI$2cCSVw_*pL>egGC1CNP4xs7+=)hRxgRXFfj zNovCgIq+BzB)4h@-k-!8#u5j9fCInGfzNf|8yxsN2fodL&v)QE9Qc6_e5V6H$brAg zfiHC6H#+b`9Qd0Z_#+(n%?|uf2Y!nKKg@yO=D-hk;I}*QMGpMo>|qZa_P}8e9QMFr z4;=QuVGkVkz+n#@_P}8e9QMHf+a3t5{m2tqZ$DCsQ|-&U60U>0LTi8Hc_wM}!IOTA zqJu}jgk#R|3gifGpz@x*2eBRfG{JPqp=TGvI|!yr4Lw~9KS(fLYU$a=@Vx}nC5N8P z4F8y5y429Kk>Ohjrb`SxoecjM!E|Y%r;Xts5KNb7dX_PKDZzA!p{JVR3kar5BRv%i z#|WlN4LxNHpGz=ZV(1AnyqsXVw9pe^_)LQ7l0uKc@O*-E2;TQC5J%4C!^aHikzNOqUdTHZweeV7gS)vytH;1kwhP2@wsuap4K!M*i4!>6VAKg&7tpPiE@gV$(3ZeeKc zu`9^E&!c42X!awC;pyQDAf9_w=1cxwKIYuwAK*M z)Yq5f48M$2=6HiHMO@z6clm-xY&%kJ@LwVPSd%73@E2(d) zzT^H)eUE}6S)btg&iWtJ_qT77^~wHuaiIGs7TGZfst2?v>Z!_)u#=#TN%~sQ6DqXs z`JP`osRx6!^c*I!f^TK7)(Bq~_3405#Rr|7ex_2aug`1;_%v$i8* z4r)3_h-`#DIsk4ZhP59R_7wm}Lme1a8Cp+`kv}rD?%mLa1`%5K_wFH(e0f*LF^pdS z{XqE(z=p&J-Ib^q1=&#P4qSyMpM2v%`-r@ElSp8v)e+h6~Bj^!q1h1O3R+1&_08Ugj! zXN?SP$ai;t{uSF$jGE_h&4={70aEd#T_3*N{Vtds%5Z#8ysmYl}9Sy~KepO+r0ul9fUtHidp z8$mxcc;Nu3Izg#QzOO)}+m%U#!{*AG9W=L6w`&a|)MsyqirMSl@2=y3?kJ-eL8NS0 z=pyVjU$U2}eLuvF9P-3j=rzxz8dP?-)c6LutAbnwgm?R;)X}>6Nb(}leX{ zu_OZXLU~v3cnPh&IA~l%_MNFHVIJs!h-ievyp0P(>o5iVtGsK$Q)DOg-);|k_(BX_ z&xF=J*F6)pht?h^5!ywLbl>+6Y7XR7p+h*)LH@rM@Su44fyDgKx>Xo? z+@kzIXx%5>Wh5ANU|=#P$0Tm8b!H+<#t`~A`V$6@?(v}c@B?N4 z!S0>|B&Mnma@z0OP6O44zgN8N`-t8{^zTdhRQz3vHBO)X>G`QNd!eTHLeEghAm$w?C!l^P*b6r%MT{dWlBY&93cFr!CVZ_X!Uo` z3a#&~KsX%SyRrL4Fn##9WdH4coZy{FcwuP6m_iIF@arek%-wIJ9HaJ(C%?d&6RVxC zaRa*h0M#s8x+Jvj1I#YRW5tPiDzw&q6W$ixHPnbaUG7Fhr}|6z+bJxE5zUI^pTpZ> z4;=QuVGsOY?twFm)YF60Bk@GAW=^oGBN1(hH@3E<%1WrLW{$BSQXdUgwIm`fE1IHp z!J0^0G&mHvyI4nBO0%x9bjEuEE-2qw8e-uu4qU! zx8l*prf9v)NJnbf&C!-ba8YAxQzQXJCIqXa(O9rC9&Bw1;>p$((L}H|+SG)R`v`L) zJqu6w(3gF3@Zgt7_w74)Fo@}+YyZK6_pRe(>NDq#Kc5hBS!TWDC+|NOvOLhx8+)Wtc;i<{P3TAdbk& z@N9%`v@W3M0G9pz;6Z{7e_*=5a8{0Qm8a7elu{5NR3K=V6AJOKj@m8=?_%;J+pj95a=z~|MG8WNY|IJ zm!U0iLBlYn`2%NX`aL1vbU*1uc7BAt0_FUC49e%AgmkiCUkG?C*m)z`Lg1zW$Imu^ z_Ds-*fG-1nHt^RI2xYcphBL$YA^6|PEu;aYQ^zswcS^cMmH`zw|GptTTB8x*bdQ9}9% zG;BX;DE3ZF($vEPGksH`dl0yfP`(l6mn6%{&*w-PAt@t(IQs@PCld|qUI7VJ%7;Oq z%1}NOaT}rXWLt%L=}`lk2GE?8q*=~VWR@pKt}d$1>ZLCQM}2zJ0N!k+ehvA63X|YoMM-@GVFVS`vy3EY>Rz7lYBhW zU-rGEi>rK#w72=O#C-IbV)VrykPzmXMm*EttjZ+QG}$f{puHNj6k92OY?uD1@)`6@ zP912LpbxXX?6Y?0Jb)xKclr<^-D_kL}YX<77KwW47#K7rj0F@=O!`opG9QMFr z4;=QuVGkVkz+n&k@9=G2 z%5mz(@Kjmd|8YnCzIwW1&h5l|HJ{=T!Q-O5a!M0hPLo z4BiH+^cadZ|N>{4%3YFfd(z{gJRW0TAcNF~-X_GN63oP>(}qu z>G$f=`StsAoBQF{@5Obg@^pUvzMFo(EnR>89-Dq|Exla7pQhhOOV?k&cc$MnORrzQ zPp01=OXt_`iRt&k()soKU;2HobpG>H`|9_&(#zwjT)&@{UasH6((hfRm+SYd^!rrl zj?K$Cr6oYoRdd*J_b`Xk|Ii689##zyOHRG zJBrEq*yWt}oQ?bdE29RiDES^iF8eLiZzbq3dSE-~PWD)TKuy-uM}z>`#A>|`gx!>P zGl}tJ%mTl)5*+R!`E*&wItuHAjJ1RBq5K*gGOo?vNu-uF3|0;BSjUj~bFpmkWDWf% zO7bb+;GN~U5FszRf$^T6e=R-7C2oZWy|Z)9LB3c#26pcp2Fk<`80VeqC&}Z*4a9Rs z-~i-Qh#zMFs4n;s1cbyX#4|5|%VS2h7z_E{`92>AmWUXMUXV2&CCd!!G>G$L7p((D zKIH@6NuCEtod-$uWN#%BT(L%|dr$S_;Q%6P+Uqp0ai3YldOEU)FZOt%B+F_xi=ub0#DXJE-B=CvIa2^L_bJ=%Psshi7tY70`yp+!_%9OhNFMe7En+K` z{F2SyCSE1r@mvb|?P3t=_GC7Ne3v*G4dj1%fC=SyibZ7UvuyS*A*j-w1ID0ax44&p z7jjPluva`sJTK)^*XkB6q|VE^Ujx`Ds^ES9?{W<^(3jpGlWDlbzaS#2cS@R9|qYURP%Vdp!IA1b5K$&yuX76ujgC`piFo>!ShBo z{l>(2;mt&{+fSXgLU`9ez?*DaNO-5BiTTymB0W<&H}^QVCrH*W@2=j4-} z1DChg8#x8s;f#T;%g;4(2C`hwK)Pp^GlvSO3_)#XGsvu`-~rcf25upN_v4UB zqMyL-q6|hD99+*1+zG&b83!(>;O25g^k=B+dT!vyMD(d9qR31UDazec-SatvP-YLs zA+r+lkJFTf^)5W;+BxuKDxXBTfo2!O`Vl$nm7F0!+rx2S?I`Xg5zCa6FQRQ-e+Wz?%9%I>X;^c~vMFd+*K2`g zR2HQ&8rYPsBdP55f;Cij2@dQe8g^t26nuu2iO%PGqktOLq8qBN-8uIY!-K>?4x^zd z#h^q#g96u^Ipi>_o78)&fI`Q*38CkDyWkU&@Ht8N0|;q2QhY(G?T-aHz}WdXuu3#2 z$r{+vRHfl-NZ-9ui%Y5IKgs-Z;(f26oocy2*FuAh ztAV&3&AFf8KNoBw%Aab=?Mcd=q{=B?YThec1E~*9ur1Qh^;4JsZy+nC`;f-OQ=s6* z#f#97g)wOpP_8X5^I4QzAHZP$xE%UD0NciaU3w%1CTqbtHrPI!EczN&_)iX$68VWZ z1Zfybks8*W(7}I7K{XL9#DN_cPZDvigcKz4hCLt0$wA?t>|G2+#FwPalmPW>L)--~ z`KL1A5$96H(-;Vd+fnYXVxUmmi#YX9XCNqUqA6hp&uYbDJprK{qAnAkkbs#Cj2BN* z$t(sc#7e5?bTx|q4bJh;=8|f0C8;xqMK2MLQ>AkmSSD7&<^D4mXb_8Fp1+y_jN(+! zJO(<%SSp#%(mKUo&xA>au2{W))(6u*z zgn@2x6zR5{fqmi)sb z)GG=}(D#*E^T{V`lv?{q>Vc=hu z4VyxKP|$zrj{%8i$**hKeTMigsd<_5<;7I*w)#5(u4RCKlZbCB6osZE{CrUtOdT$}i9I?1qUoo~~r zgS7{$WFMFN1f-3!v9c<{KAIMJ$WBKK1agPa^1A3z=pV@Aymc52j_DK;!fGsHmCg0xZO z<8zT=N9GwLUV!6=i2O5w@|ybc!-$=rDi;N`Jo1`*7m$na!+xF6?lh7AcjSSsW~6ak z37ToF_!R`mk<|YRJdit*ZP}x-yw2bQVhD`6K|b;OSMPE%-xyqqW8M|6!kqx}14*&< z&?&cw*-q40DVEtz3nT0XWaplqEaS68|3xq`|47y*qKgdwSES=`#;(y=rQT2AuH2)! zo;!OLIV$u22w|Of5A#2fBw{`MC!xZEqqyi*Dk3wE$4CzK2IeukN24+DzZj~8wtOh`7`jsnTrpVKw^BrVelQ`cjZZak0JtAwPH1D5Hm!8YD)k4NO5}) z2rFso7a_sj05D%bn)1_;c!F*;iAN!ISut0bYf~Vc+qqfCkq|sA1S;Z;<5=T0i_0Y16!S=!G2|qSfMS5iB`btC z&oGYo1ZZGJ6JXdh0u1>YkuQ9TXkwDcCypbcsdQE)vIKX1W6U~)N`@eL`eLoV2_|k| z5AqVKAVVBYtfwJ65qs92qj1DVky+ZK0E%8?%$qovEKgq?rs177ar^JIJX4G!c?*G^ zhrRSGr-+<0q0BdIVki4n5=jxy;g(khsr1cJBq5I63ha5;!ZH8imb(|=PYLxvreS=` zsNVqW!k+Cv+AuaLnL=k!z}vUu&V+E!aL~LC1g)=)f(>ZoyEVtDz#KHMC#su)e-Ge0 z*mIv%1k@#E>!IOqR!Hja4}b*)q8zPC4VkM&(uhGgvLmMzp4!KD>+AB@08N{?{fh!+ z_r7Du?yrE{k3ECz-Zze#Z#Y_gF!sWThbE1kD0N+1op&1uK4pj&I`m*@_G0LM6s)98 z=nU2ZynShQqAGVIXaW@by4=(mP3St;WxJ^lz}62rF$@|5wt^kDnm<8oQw%qjNx>Au z*H#-ox2pN*BMsxXl2(R0cNg+LZ8XaMjZ4X4rkF3vjI6n;&@~DaN8Si`i5}S%h7W|M z+!cB_Qm4IYqwoV6<2m$r;9e%wH%vBgCFIyrjA0y5dqJu(Mu19&cW zcI=;&W0$cPwYnZ$1Z&QeM>Mrp{W_>JvRqL(sOTdk1}%dF(JLmh5GhXY0_KYXm7pB-lE@& zriEL^M6|`L?5&>wr1LcP&jYGo3!Twszh=G z!kCv?U46Ih#H6}6;l?&M?#rz1Q_zckx|r2{nbrLSU=Q{J>J+YHB&VRRyUSbyZdP$9 zbp%~#Qei6gb3awCrKJb75@iTia-RqqsX4?Efb2vPP*k z;6Tdx5<^Xw3>75ndD{WDVrL)j=;gzD9h*9%UGppRQpipDP?wuJ zqY0fpJX1*{AO0Nd|IUZE^zz|#XzGXAKz*|+<-_540EK<{F!xR6!>dQIi!q5KeKh4m zjW;ol_445vwqe}IRRmRpUm_(S4#(gb7WUzN?86)3tZT5d5AS0iJ^}Di?1kr`zO6i= zx~^T87e?FvoIUym3SYy{UA|4#Aaq81Yn%BdtVy|5mzz4H37u}8rKFKtZD{IrD?dpM zJ9uJQW@If^v~-e?)uaF#2ea-}fDGDu+=lTp_Qp1aKRM|Q*D&RcpRvRL46EM7&I88J zPM}`-HNY>h7tolX1-MRtguBdJp&>5|2bx%9W0x*@NmV0sMq9eY{0JN=m*{d+XEdS1 zCAmA5G&)yG4K?%&_jj;S`&4-(Y1AFss5`ickAY%GV&^8lgPV9Z!0Fhzn{3kE#5d$v zDTBPf7DAlf?=`K%`{NYtugLrJ6d)b`1Gw!b*3E#=Xd5mQgdfdc9DX;k!yBPQ6nowr zEZ%PBSi2D5_pxV_!v`t>LT4-`=~iNE zqN`K%os6uBBcQ^9r1Utvhw6Zy9**^o^L#SO~npQ<9+>AHA0jh96qOyt& z#E3C{*C;8rSV=Dk!n%8~a+sS|ZyR9ah8_;$Vc3n_eTtg2 zMUe7xx_}n@4{9-Ckj>7RNUXHP90j&xi8cH2k%sZ4rqUT)a^Y=u#+5;EybPKXKwXaA zvm3xihD`{d=Htkv5%Yypb?oB*rnUD)!C-d87=F387Gr0TCaD2dL?oA?p3-{|E`s; zOD@~fMpxfaN;0{)Q_{+1J1xwsR3Tj-$U0jAvh%M-jE~~r+N;|A2g*Eg`(H+=;2OoJ zuUA8IFj}Q{3~`2lTVdQp)=avQu|m4XM2N?b0kG2 zpUf>*HjA0SOtK?HMJIEkK~ao7w?Pp&Pv)5O2+fIAr%_?vra8xfYbqy)uxCA@O35Ee z>RK(e6POX^ueH?8pr?BlEcGfabv=l*)Q3>|3zGV?UQ+qQ{2GOF=?wUIJIefwYM`F; z8}L4j-SD+3>a7?teK10G`_LwZ2aH%=h|3|DWMc9DwM$fj&7?Kx5%jnQFhz7_=!idJ zS^#j;1QgGt$2DC4a`CeP#*lYV?rLxirbsl&ox|w%bc3se2f3sFj3`{}A`cF0Z9{I9 zL|=#c3S2Z>5xT%tEYVkC82?bva6{-1g+vdb8?7$4$Ybr^mvtC!!9%N5)Gem)C9ETt zqCVFRl9C3uv8~IE8(7RyY|#x9B;6Zk5bV(-#P@Wf-_ z-yn)!2hU5`M~(sDhH3`(W5{W%j+N9xXY|^{FU$u~Nop0N2~3^Ql#W%*F?7N0DkUElr-raJsOfACpY=sgptD zapN3(bOx3S*hl69Sb|Iq_H1H${aEEboza!`B<@BKufTo+ai2(*XkwSnXs(Y_ zX6PbIXEcq|4Br!~ep*2dLSA+Nn*7%wKTnh!x&N(5Xc3$&aIJL7%PGciy7nP2Ut;D~ z)`;7)Fs6DcQ1pFhem-_KcZ?co4V}?S_2j;dYTRUQ%1lk<(iu(dFjE&m^Yer^;F=S|#BlhG`SC$W&jd9mUYI-@Jk6Xqo-OSOh3 zFm*;#I@AnMr434CGDD|lw9y4y57m7)ocS~C9MhWIr87zLUNNmpEuHD3dOW~U7U@6=sU$XGjBYIUA8e3o!OjexC$@A6%A{kg8)ml9K%=SAqux`lq1Qosk}%? z39doEoPtomqd(<&D(~eQiu|ey3`&^=;@H76^8~nkA#tI&n6p_SgR+R9VWK>5zSus+ z2S;QqDH2P4i+x1wFA=8=*4mPUNrMTUQzDWY5SF+q3NPTYKyO*TrS@Xjh=sn-cdF0C zx-C~KfF;9;eb|wY=Jor0(mzyJK~mnrK@QCZ!bXqNi-YonVk`0zUtw?Q@ay2DG4?6G zlrclt7~e#N46@-zu#Xu@o*&vv37519D_f{g-0~Mnt~K8 zVg*$koHlq8uEvbeIY;qTnvFj(ITUSkO48e2nD6U9H;!l78T_l3zdlRc&K5F(JhY3P|~}}al=rCgH&4v zWGMyLrD8C}SD7Z@m?yi+lWOW#Ey9v=toA6=VYni5F)k;GwN1XoM1Il$akM|rXAVDN zI28oY4aTWB^Wf=T^cz?;o&(BG1=K0Z@2sr!`vgmz>hqxyK?O8fJ(2x{lgmk}H!?X+ zED&Z6VW$=tSX4PR!6?i_2^#725`+BH;-_wFypC0qja&a) zX$%wMYkxK+f*?i=chmT|0Q-5^>CF9?*x$tN62o0N6h&&AMhss8aJi5(>0o72j_!_# z5p*b}!>M$j>n7qXI?yG4n|SRG0@u<3k0~1BHacvf!$Wj7?cFuPGs~WEn=R(pr@GD79a8kE|3UP9-$C@N4$+g`X2A|vZ%=X$urp4F zf0mHCtmbv!LDq+`d*XIml-Z-*W_dkH8VyOAkR+DcnKSJY_q&A5B;Oai&Fe1a+KNF_ zcshAzDa)ur3xw_O0>x|sI)t4wj=X-R zJwTwgOCfft9U%X^|Ekin>|qS=E?~sSS@v+;Zg;uOm3PRod z&9Bj#6Rx(!37%O&M1)z77UIwd+8LAWNi%UQNks@c-rcIZyy@sJH}_RhTE}~TjR@MO zZm>l;5;QFPvoEVow+ms4>Ap5)Qf|_u?S0kM%Ynjtj)Q&jMYfo0Pjs6J&m@?{vG%Nr zHG~-oesQ4yHWv{%YnBYW2jKdN?tqa1SfqU$@<`Xn3~x`w(1tZRS$&^AMSav<0f zP?m|n`;1&(<~Dn96^fi*<{l8V^CuJ0QhP9nn0^I!%(waqoJ5+7e|jNYoQwW280MO< ze`gl-<1@LBQa{c>zg}b?QEHE#Y5OOW;|~pJs%3_44rJAE^8X)V8jo~9vq@X+vBS{( zlW0(Ax`QmHF(ISKF8(3KnjD6bjs6!J<+I_8?_SGi6k_Af=MXD(n&Z@rl z9aOysF_7!7{Wm`B6>hNQ+6%cNGG;K0nP?B5Y!{E={9=3X>GmMB=1e$pGISVbUO{tH z9?wRD%&#!T$tfb=ypfa}ND~N8RNWWWFA0LfYu@5o;=a_qWQmN?_vPTYB#7q*%`F$v zJeH4aj%{CumM@^N;lVuLe1f7@&w`Tq*9cNMExn)|bCzt~9bD5pW(nwQ^T%rtknR(J z%Qs&mDFbaU1be8PWSU#nEWuz|PaJM@w>iuGDKWXtn<0FVTa?%ZOGpP6d=zC(Z-Pa= z=@bR#rQn-u-n-^gl6?WP7a*cBi^7Tm+jE(neKMfS^W~gMlhkDpGt3;1+Va4f;WlSb z5B8g<%tC+7bDNi7fnew1{W4*XTw)iI$Gqli7jZX<%_^{mqrf{4My*behOE>rX`{ws zj5wvXc@~@Vs0GEO%iv&``Z&cKhgCh4!|b|l4LL2}eB?h;{(vcmnSVl*s*nwscR-$r z(F;SvaL7Rj{KLG%y=1FfxXItgxXt@7+KQmeLlz_H2>X~AA1Bxuvt=Kj4M&kC9`t$6 zoXPt9h#C*!Dz$v`A~`tUEp}d-#L&c?cd1=scI>dlIJ_qzM02>Yr7qfGs2`JS!*9BU z6ZEOy-e0>-w1pcY@rKm*YV`+fm*a!PvDNkMEw%lAgE)@Q0M|w1M$2;4)z%cLjfUG= zS4HVV!7McOp<#R?m_Pd49Bzd~e(Mty6nIfBm{;|s|vaCwuyI2>VM^jHtjR*v$1un!|DWaY?SNwt z8ey)Oy+k1z1tsc}UMev6S_+lBmE{2F7F<3$Hb%FI?YNMoWcmTcDu#f?FojZJ82 zZ{|AUTG5th2Y>F{`PFMUC9*1lD1cn~X={fa^-ZmA(YTUYz!7d* zgOs}sG*&x4G_JZGI&00+>MA4NfFGEoitusjhT7KVwn$8VjokTFZW-BgtCrO0DC?uc zrT3oX$FUFj7PkC&HUfhh3RO49T8&lcpYij#Y})qo$|1lP<3(q#yPXbj(N z2aZ2x&YxR{?s_z=ZEdN=AcwYTiLStpYocwqooI}7G-NE^&{&VQr_YhAMnP$0dAzl$ zJrOl12sn~gV)$!pHW2D{jVllo&}7N9s;TpeKRo2J%&F9F`PLEmWX!Ke5R9I6q zJLUzpLbn;l;qU?)m{&F;x;U7WE27#b^z)`V&!nv_`a|-~ZF+z}->p3_9FNpT z6Z8RhZo$g7HX4MS)=#17C4s)dW2;s&Oe6ACk^thV(=kobZ>LhLM!*l9Xt-oQEBomA zXEZMU@sq0TN3;VR8>eZG!e7Nb;#9>x=A+iO)fg^0tZC4WMeBJ)s>e6x+tE9v>5a8q z4*;4PphY+lSwWig8X&4yFP0Lt-?;tjTHBX5(YNduMPkbPvWr*EpMS=Ds({B`>IDWo zhn|E{xUr3XO16aueF{t(xn!$^+Yw7AjK#!HLCYf=b(gsuqYzf#6j>2B;Nfs%U5EDh z0^Oq#*ldY(6Z;5O=+1ZOUP zrA~Gpc(E1{9}dS85d=VO!+GKQNMn;h9)`Sn8Xvi>!AOxsAw3&&KzMqrwRr()$P1gQ zSS(DcW2MltLRZT_zKe?K-TvC9);P5if{BMPTGHsg6K92E(YBZoZ*7lZ<%G4F?8FI7 zP6&$gu}+E0Ntd)&{!NWnVYN;m8C;0w;n+zw5z{*2jRq!~!)0X1aS0QA)G>w7NYI>G zWU%*X5lMXP5@2XKl^QMdprZN@`lJjR8WX9DghP?|bQP`$1vOkHd(l)hnTorX=qj$F znVmOd?!w^I@{`qXa|FjUC)!)0lUGDrqL`ilMq;%MlRL(b8#C_2;FuNq|BSK0F|^ln z(~dz1C3uxF1}hnw#mCgIibdL1BCVb|6-Sj;oe&I>s@H zH@9*~&=Oaztia=3@M4tZ_K*v09%X3qQEPM%!$yjE*~idZq?ou~<;i6<=;SJwXZhwf z)=ouboet0B??g+ru~dQa)UIkU<{rW$5pZ&VKnbmMF;1k`uV_(HSvdv6UO3U-hS3I% z6O&6u*_D&-r0}CCRVNb&ZA1>dKZO_0)mTf#Y4)ReQmcyJy-wDty-DjvD3)6Bgq25? zo%o?_hbNs~05MA%hO03!IBAk60uWn|6Qd@YKw%zx&oNmL&+^t*3VuD>&WI*dfWtCn zk#qnJfuK)~Yc#aLODwcK*|JLMX0;4zY&pNZF}9klrm>falRqn7Qfrhpv^GaeYjBLj zOCh^GTo*}1O6#I4qfM=C(O4r90a_wLS8H!lD=h-q zvluAh6@VPiNl2aoHS2A0Vo&^#iUSAQo8H54aH!ZeLlS2Cf{C znS3vD6La7d``s?F(Aw?laanj!Nn!W7J}2zwuCE+eU4_+|^}{Tb{xIvNEKy_Kl=V=S zSY$nv^>7wTupZ9ZMTlKluSkUAvo>Yjl?A=-%6c#hdOe)=dn8hcyR&{nCBFfO>)IuT zFhRQsGU%q8Vco46eybUX%j&XrTF_#r^}G#n&)YB9vicY7-vPmbndEK*0TF*- z{f?+=$V}^7YnzQa^k(g{->^aRhW&;c0^e}&c1wY~-Ftx00(aT(*bw-R{S^^^W$z&> z76_4>@w))PZgKtI;WuEny1=qkVim2FXYF-&yTQ@zzA^)qUYT)KhOG3ejOz$-UB>ki zp{w8P{@4v!AG`Ov#XM`jn~NPHt%?~CH{(VD<{QOLLQ1@ zvTqZ=6e#$mxWWYqSGcZ}hFDj+ZUI6|*e0G7knyB=lZf9Gw-A+6%;t={Gf;AO#zqgs zZ1h~~k&0aFxf2L2W^=~RGa%;Y87~m=3mJD36^pUn$oMb=VN08}&GU>0<dA=oq z-+FHGg7_AcX?-A~)4Uo_{a9C3ynvo@QL68)p*dP{uIT5nx# z$tth59wNj;*25B!VnO_vJ4`6B!(3;HbF6ier)Cq<2MF*WsqOWn;B9z^4aUZbWFyEF2SbsGCu8jIX<{TQrv*wkS zINQ1s+GSj5{6x$fv56J+pyecVwe<_4_yyEWQjq3JiljViU-mz;sadig&w-+k=RA=k zee^`mAA!&+@5}x+o0=v29zTfh@&A#iv=jDa|HzNl|B=M96RchSPyDWHm%$&_yZ%3; zm~s#LclaR_!SSU3c|W(6%ppu%);IodAlz_eaL%fz8i_cPfUDhuhY%U>Zuhv4!cBOH z+mLf@4n5fE*sQ%-2WVhCkhL`%1K`%|`?IAv_h;`Q#E$Hz$=av0KLC{ElUz06+Ck)K z?H$?Ak-g7>P8#Y;5~FqZX06Sp)?J%@T{ar>y6n5M;XAHk0a$l&;Tu%P0@CwS(y4}W zNgRaS=H%)nJ?9gcWqp!!V*pZb4BQa_bVp!QKw7dX@JryC!TLPsAd%i3co;OO0Aj!D zg(5O*ZQvRbu_^G=B-K^DP%g{5h7h{BnQO1No4R1PcWoxrSetoSrmX+6%#XfCRq?XT6^JCy+S>cKWXMLEyE%$9&*_%(ufQmE7Tbh7iyAej^dY z-R=7fw8oFXucvFv$gr~TV;Cw49%~(6W>_jY;Qp7}x-{d83>wR}d8~&qpwU!#f0ng9 z3%^TY-I#q#Ha96X=1;S&ZP{Jf6yy*3tw;S&`VDR#Ya7~2HjBzqb6A@L+kmBJP}xrd zp9ZXhSRXjdJ2cBpZ0tXnUP6z=xbU8OS5fa0dZ32z`_k|P5?=p4vgSG&8T=xb(V@B( z)koV@?83-3_Re82c{mq2lB0ibSr@ECMi>JO{rkxpe*-dBANt=3Jjv0|&uA~)tMHrg zOgwEG|1k1I-=*-4Txu9kDSY}Xf-fk1`ircuDt!7Y@9!vl`m5_7D}4IbE z4rD#m1E|-4j2I(erRdXN+Z&_s`u#I%KibAAeEK_J6$+pJ zCe};D}1MV1a_WO$GAx0(_j6#Ug6WhHSMz^^L>oI4z5aocPBo4bTVHYb0@DYK>XVcJN75Jl8=!X? z*@phza815P)tmnN%pWj5&*)C;N1p+Ys4%+l;IeabE4y@m)MdGhFEI4)fouG&tPdXl z4Qh-`i$NdgjbeyiE$$0n34E{*`g8iBr*G!uQh!wK)uebY?}z?|e(-m)oI@+7S5N!W z^Y{JW>0Qmf==b-7xA2%}U-Sd|!P8@*ebJZpgFg-UzWh12ANp`V_;^2f`f0Yl^trVk z{5}2PAL|GI+kWt`_k;gyKlrcu!Dm^0>p!#~{21W-^5=|x=obM$;?S@%&hLlbsEsA! z30&jCzjfu zRW*hqu~=j^-HgRWqxu+bPlxN;o10gI#R2g>hF+x3Yf9=8R9s(l!^L%lqI*BOG?~No zHC>FG9x98Aa{NU)1;&hCw_g;NFQ2PC?nGH6ASI6QrR<(#T;)!b>}u)*%9mWj9Gafp^WT=@)7 zTROLL&djO6;sSTLDx?@f)8+$JGiR!1oiY22DV4LsXH1{IpsFTZQ#oaJRTvi)`5qNr zV^>-A+(CFIS}PSfkVA1(Ll?3^c?MtEO1rap$Xz-mF?ln_d3!beR!PN-*)yk14Ua83 z5#p=TZ=nO#>(+?65#YF4kGc-MpF$1|%NxR}+Y8|Zbfs14rf$xWX3l%k;qZ!P-1L$c zRmn?p`1)R0Kgp8vKY0$K0pa}K$k%WbX4h_sgG%AuXKDO}qT zNnWi^Hrd#clTeA{GPh9@U)_wG9!L{0nKtNL3+|tk;KFXn^7h82x-pG)21ESBP)XhD z7H}Gz;?@I~s5_9ofH2DNNJ4}NRjv&Wy_9g@DnYhn1@14GB{$o`II-RbFwfZW z4#lt2GR2>+zd{>z$WWQ)-=g?+N^fe?rt4S5{JlfMw_qp!DFk5C-^tNwg%V8s1=!R1 zJAfm<;tg531$(E16sQxb%eln?IQfG?S*lZd-^97;wVh5cLZOp?Tal#Jsn%D^(6COg zOyk$r4RqQ>ZxA{*U9U#b`Kq&ieg31GJTz6_hd?RY78iA3{nIRgN;EvLz}LMF+h=GW;T zP~zm*=b_z-e|M5oW;CBp_oVUb^W?4yNxxkyErjJxvv52(e1hyOYnn6SN-DN}t+=RZdAr`y>~0~0p-T7z@b{5mb~hkxnSlIufFsDx-x zrs{$MD*KEsP-44NCdp$uEx~&1NfIG*^NkYfRP~Pl sSb|;0qn>|heAKZkIpneM4w+t*7XRt>({<3k_;38Nas$p-d1ps3ZXqQ9uLXF(6SLV)pz>|I8v1qtH)X)~TX(LmDja{K&b0ivSi(CfA+V0>=h^I~$V(&X2bQYeVrw zxW2QaEgW18u6iv&}!y7xp(Z+CaIhqGd1#?q97HtVGj>p

_`GgriN0d1*8ejuS1ViW*bY)#2pown$?pyfhhZSL7uQGGHc?Lkq*9wzgO! zSeHg4$soei9&74ESZcfLyF0?cx^Sqe8^8+225aKsP%=CtjhNrmbZ)~XVZ=iUED1-$ z@kry!@Mf(o($H9uh*iwemMmYope8t@Vn)SjsrpRxm5~4RR83)=r2!7&*R^Xia-?&7 zB#UO9-4a(EiQo*QYkP?qo0`|vJUm!n;}6UEUf~Z&d{4DaS9k^YIq;U><~!)X=S#eQ zzD-wpY9+qhf!|kR^UZeP8zq0W179cc0SCTH>RIc+D?J+=_%%{bs{=nslQ_062VUvv zap2GQGrP9kf!`qY>~Y|go_!AddZ}l>1Ft6Iha7mNr`LhMSnBC>;Ctny{<;IN^c-^F zFOYir9eBUgbJ&4bdb9<0JXF75B=vY4_*$u_)PYxe{0@9b>M3{N{W8w89eAau+JSG9 zdIApoV3Ee#S_fX~+2FvpNIk6%{GiOkE(c!e>2ctbQqOh={*bh1j{~pt>~r9^NIm-< z_+F{!AqQUR>2=_Hq@F$pzFOsv1F!Uy)@Zz`elL@HsvP)U8J`0V{0zz8@4)+Io|P|T z^_tROCH?9>+s4zilx|n~*q4FN$-p1Xz~^V+U(dkHlw#_k47@zWGJdwSM*vdSaZIS@ zqvl3IG_`rE?Hb_?g+%GAwgJMMc9oB%)iywQzAvyr&7XlMn%c^%?Hb`!j0jUzO-GIG z!HFWZ&91hq#GjqQYFc#$-kX6BWZ>m33{z_}@Oc^hYcuef*JB$p@bZ+yQmq+ynQDyh z$iT}kXM9%%UZxb|j~ z$Pesh`2P}2Q_MgQ!(SqphV4KH!`Bl`Lw;Zb!&?cap*~Q{@MQ$k5Fe;!I8HE4i33#( zUqUbq^#MP_4FuB=AMi1J0l_r12Q-H32+k*X@N*!JzXwkOns)={EwF3es#6iWUDh%x z&N!SbK{%ViL*dLCI+Q=DhZvudCHTvj|FrQ`O#M8tV=(ZdEJcAe(WBelQtH3fE>$CtB_3#WLd_Xc*n+kYM+iSWz-X-Z&fO(|Nb;Z`&e z*jYct(-b(lm}NSPkdD6fPaz1lP1Acnc&q=e&rYsn|D^x(Pg!U@gucu| zHFj34hnVUgbXGcrYer~XSob9A=LHogC+e;e6eWoV2jOJ`sxdFq6jZJCH$wLZ?`QOfi8&Je;U6|WOX2UXI8s|oB(PC=H{Pw`EEPPt()t?NVtZTnOiG;oxrhb|KQhkhQq3n{@rIMn~)Uytx_ zO<>owE(}G)^+U?#{tv)|yj=3w$2ezTw)_;z`(0=(u;VH6y&|yVx0qdGnDLS7fo;|q zkQV(ji31S{?09|sMNg#@aQd5RERPk68V!u2+tCOdjlj_e9F4%y2po;T(Fpv18i8}Q zXjDtT16mwPB>nX({ENDh;b>lJCoq>*M~a7{uQCd)<`t0 z#kF`;+pKMlYHbPpk7}XiTBuHI3b%!m;b4N_S%sRK;^73y;i%RUP6m@u5R8YLsSCse zW6m8Yi?HwhaA>F(<-S4O(4y@4P=hlm}53<4MJakA{ZmJ^enEYf<_>9va$$vI^x*L`Qi5D>Cw&}Kj)-Vr%VQx z<#Ac89e|JYFhgzh?C?VDt?*erFC<(C_M`)MHE=z^(Zdhg{Mh$k-vV3&r8Ym$w@qJ_ z=hthp^L+F3Jj-&Jhu%H+{S%%;;3-C2Z$O#Wv)f>7m0c8%D&VdL4i8h9_rmNvPatP8BaC@uTlgCmz_-0u75~8-Ac30KFRY5Ybby3D`R3+djPxo*Te3iFlyn z0<=$e=!3xD1U%c%vKK)6iX1;^UgX4n(5^yV>8;W)w)HN_(W-#10#7mWtxfV=s|WH* zw;4;|M0IvvDOy7RoC9NJmDrAMMa5Mr(BXBeVM$(fTa9 zxx}_umgmW`S(ck*d95tJD$6@%`8`=aBg@xh`Dbpk&DDoFcdG&pwQ$8f=ercc6{w7IR-xE6NEs8EbT5{@F z-vg@e|D67*@BGwveNK9h)L%V{f7(CUls!(iGQW+Hg$>}SzUNCJ{^{Fnvbn^r;f1odT0|HcKX+ zOoQL4JaL$O`7!i)pte)lh7olD*ro$A^3I?jgOgQ0LnMayui(MphuJ0b4`m03` z$<&q{Lm%^qXVIi*mG4QIUn>fr-&2?KI2hK7<6x_2wfA?RY|xB#Q0LAq+X#+As{1^1 zJ^zQyxs_DU%bJfu6EU2-J!j=yPdLq}f^K)-#BY)e)%{tsJij5ChoLj;^g^;)6ZF_N zYj(lIu+1Z)h?9huKOs<96WO`4j(4+NfTho#R;m8^xp0mhCNIZAEza ztYznV=fF8nQG$Rx?-BsMqNZ4*mYvURrJ@|Fvwdu+Uo##;;M~56E1|8B>g73wp06p@ zIYqW=QH5T}DP~VSqJe-CABEQ^Hp1$hF-$4tc5=qD3{>AwaVspnn^boqIzGM0^CGE! z0aokHtUwdfpiOTnnn*pP89^k7yLjSTV5|5&>U)IuCQk&4#8#lZU$GW~PZO&V3GY{> zL*E0+do!!^i}ef~OU9LpLpXYG@p<5Jm8eHU-o4B=Tg)JBUn`gbO11bdeDK~{um(Ut z945+bB{!l^YQ`qqtM^-Z zH$$dN+yz&?_ZEBwR`rM$lDUtyZ5QuRJKru`3bx(iX?W=UPT`dR_J}W$w)=~}32pnt zDpK%YMKosji=9Myklj8Y?kC{;g_OPziT@zgkL6PO_KMvIw)e?`2cfM`xT&3|+3kaZ zp8tFM3f=+bb&*SK&lUb2z#);3V0(X3NW-LGTuJ6UU-%sWgJLI9UMPG3z+u+_C>k%`u=>@!0?IVunhXnG z%U=SZO1Rzz+s|^30We#*o`AO3^JoB83)e@$y}`Z(gv&w;Kj%hkh3iu&c$0y(!u0~2 z`vn8&o>j2=Ee2YJ>lbMBmke|W*Jn`hHs?f_a6JX%-!1G!bbEyBR%FQgOxZ46A*lXU z@nJN*TWH0#xy9sXQA205mRrJuM=OdoT%zTUVZELrdi|3-mfiG;i@}>)%0Q|38?@(+ z=ON-3&%veK2@FgTHxp%I4!z|l7uTb~++zxIAX+8X6XjS2W{b^;OztEGs>N+^EZ5H# z1T>R|>Ljwvq>ML`@GZB@paEmjP%AFg+iAq`=+UEj#IA`;V1pjBP1TIQfUb8KWhjh4 z(_sAJm)E;z3f7DHG$ooZD<;Z&n~8PWobQr#ulNoV=Vv%f zplMCFX@93cz3M9l#vF&k1e(~SSN%kLt%S}(=4m)^kZ9VmTcG6AjICtG&q}Ccje{ic zdVYumnn{2HMpIK-K&t)@2>KiO6foloV)%IprH)}DmGw7EZYK@?V;9w zQSubg`-o0arAf(dfdfsAYDO_-$XmA7=@gY;+VvMHwr`hwomy)|QtO9oD?X(9J9hmZ z%8qwSreX-26*zD!G}-7AA(n1RGyX{0-YZ#6oNENvQNK5 z&$|U|{`Cl%Hr;@MSNd;*^Fo_(1yK5a-RK70I2)#TXXQVDy7@2;9MYFiv8~`5J8b&M zqjRCcd%EvEV(-Uc0!>3{R?V0P8@y+f&_|DE77py%i4;|i9oH(zKms+>h2yDy;hmS2 zgLsM+WX%E}jcZN(oPZhzJmP1hcOe5lu@_PCE@GfmOonprVg~%;B|0T6;j>z~c!q#L zel4_Bi5jweDFd^`Ux~7efoky>wR4V~#h*cNyvvzVD}GI?SFq}};``L-N(MHFdg%0? z%RsAmANk>}WuQasB|}#+&?S0_QpehQ#4YFq?`obOw+l)>Z#`3Xi+Ykdk7f3V%ZcrL z2KI^T$+oo&>=)l4wsi~~5RC|t_X76xA@MGH!MmO*z2Z%B?m`Co#By@sA_fkM4@l-> z23{ARl0QKP4vCk@pAZB6;=5#90|SHNWQtoO1BYD+nA5~{O}JhHTQhs$5w3BFTPst1 z!u2p@A`FxY&G;c1cZoqK+u~Yp+c&7AuP0a9b7@A^#5l4f%KRSj40#+Yq`A~5P9nAr z21)N=73WPO4uRich4NgvIQv&91>vx!w#i(FE@nY9Hp;{)RB zGRDH3;!^Krza+CtNzoUiSre%vwn($CBks$KXm<8##&Klv6~?zAV|+&L^^|^sy7?&% zZW?#RxF)ePp3|N{&7^9v-@ElZKw=!lbsL9I6Bg;aTE_A$YWErjd}298;M%<3LNPA4 zXHj-uXN-e_VxM=%HKgbz>f!5)_oG!!v=YP4(w_mqHR~jD_y(f^Y$i2o(jYUb159$) zBzco=7)-imH|aLO2*Aj!BA#yxt57fZoZ@riTAfeSo@s`CqP`0hPes0$F5)2tppx%u zN(DWz^Hk-MuYPSN6()%rq{}nic$%6FQoe(OTHg;k%{y0bsHWbzfg_7ntrVp-Y%7L#qKJwt^E8??;MXLp96T zS4}8QJN+c&p8l379Fwo6ySxQJK130Cm9YCt=~ zj}8@2Vk*Psw|pYsMnc%c-YfA;b>c7K_*0xx^gsinNgG>&hw%4HZcz`+bK}67?FafK zK;_sq-&Z8Vel#{6WJ|2kHvxZ-#FH22+xT=YS)$&^#)tZ)KapG%3zAIWSf6E_>?hrX zT1CpVoHlg8mkP;z^}vp%2inBmH=+HQH&Ojk1y#kGGBSLjd@hr!Km%`IW(Ve>K8InG z##c@YRDY2hP)`ii8w;_w5~@7Zz!#6F29}^keVqHee6~f2GWiV&P-aL$k>L@eTVV^vZso}WSF>8v;S%tU{5>v>4%h|&zgW0H_MbS9^Ajb3+2S7T0 z98&8_s%be9AUCn7dc0amcx+Y??x?CxDD$_t1szCZ6AR0K5i!{*NX=Kt8_} zssh!#br}nwDeLFpDWP~Px}hqHF^lpAv;Ak%JsP&u|F=_0<(vk#4mMRiDV}NThpB&3 zrgpHY-vr?n>}+ZWoBAripJE?NrY=yXQeq~4rmP!B)+w4nv`chL88t)7Y`2XPRmeDL zSrQXa3tOh1aYrCao7nqPh;a~GI3qp*@(^Xkxxrx&dsASc1l@Fg+bVMK@GM zF{=3eR%)X737GVc;x|>MuN}WHBRS4v=d>f@7l$T}-+9N`^AX3-tE{G}b!|F+3U849 z%=mo;6V@_rLcQa;3LLbFy<6})lH<3G~BXXkLw(gW2~u=B{6t44<^4fF0}W5$hRjn|gCePg!Xbdt*2ya;#@?tj~oJ=U|`sCN3Rja*ELdf)Mt6 znsdJ=6$@2SXW-L~5HxY%+rfM(b}je2lAEupa%O>dymvkb>IKpbWCJ#__XW&AY{qy$ zjjzig-ie(qnhoO_^5 zl;oRcSI7$lgYCJt#Zq+LY z){e~s@qC>;86WFFZK{nPgH}p(N@_xv=;bzg31-s|1i3-z4}^_AZYylnuReyXFqVRN zR;&SVCCi*mSAS~po2$?yZDKEVOZHZfHbFLuJ$n}bT8!|k*r)CRpx?N5>NmLDkWWhH z<21vYs;J55@=1C9bQA(sNCEqEjSORTPh$=rmuM zw1yJ14$WsKrtY^5<-}ZTi8{I<@y(MGG~q{BqE1w4xf>;#6SbP2&(f}mT+PTkGiOfD z897UfW}|uC(v~8pjWHQ`%$50CPML=Y)>2I`y#f=VizUmvQWPERE)ge=TUsQ*<*`V- zOxQ$y?1KyFbZ2SPLCdB>qH-!kijQOqM4`L7^s;fJ!#hRG$vG>>z->fsK)YOA30z)< zID4Ejm;~lBYyL4}dQqKtXh9AsSX(C6<(!{GI`9|XBuLeQnZrzi2ZcpwJSWHYo>+?D zk|#45#YIBW%d&`}#LdvSDw=k3fjB;|D94yIVG>#DLn@sja|0)xX-G|YQ^B2Sr8~2d zt;(@uc=outI5k$8;;ft;gcMw8iy}Imqk)G_Gi1U`8%{;fXDFLlqLKfY`Gl}Dd{!Bv zS&4>EAKvqJLe7Tu+8HSdMi+@^X7`!wq}_vaGNYWyG?&r@U4h9q(;G~EoFQ`9YTDTq z$p1{i>I#iqj^@$m(Z*xOwD6$si!|Vc_%tt<3PBJfCb{V1c{TP+vEPLKLF{i}*Tp0~ zA2XWT=#E1Cl?Xa&1|7_7!qGjM@YA7^4rkF}IUPvCqPq^!Oos#==*|_?T zRdnHH71W!SZ!HN^gVqA0D~TS>OuG1f~@TdZsHaAO6e#<@2n!6OoinKzc=hZT){+^Lk zACJ@u`<7169b1IoI&+sLru(U9&+CJqNSY&icDYpwl7V=hiqZ`=oQ9b_>*i@WK}A+(P4iW7#rbkk$tgi#aZzjdTEJzzw`DGQ)MW)a>|t)}x87%uC~GZGlIE|= zKpqeAamITirG;Zu-ogX^oR}rfwN7vubGfUEP(>e1woZui@l4CT+)l#f7;+RC&%9v~ z`i5?gHru&ZF1Ne&UcGN?3bT&lwbiOHx*oB_EIk`1g7#n}+7#~6VV0&N49<&AeYcSajWU5Pi5j7OTn2`$=yHaglujp1NNY;!mcWvn#4*e({( zQ9;5gAJiX7`$!G8XRbnYwTv&(G|m=Mq_E+ShTI1SVDoEDS80rX_)io{Wb!g|Y52 z{n0i@f?Wd&5wiotSa5C*hc0cSRgdv?9R-f@?QI-q{2e&D2x}=L7#Xaw=4L3-8e^T& zWN=fc4H0RMhY`+=!3eEt3|6U3+l0S8kHs6YgfZ(4wFeWlXmUoN(IwPOBaBTl&ymX% z#~NgJZ4APlmSiinfR?xmU|NQ@c(^@8=^EFtesqhU51shS_?Bq6$xmN`Lb4Hm`yS@r zQ{9#}IHplBJL0J*ho~1d%5W7hYB(D1N@{Q>v^j*(L)>1YIm3|Vwpc8V+}nf%r?xs` ziAXZC34d{)*~hA(beJ^6vlB~M=cj7frRtW7=jUKl;{Q4S;aNlbXgJFBFiuT(ukt zoSHKE!N+458WNoijcuVs0%PCqZn;FYltT0ARR-XFLaw|GNsuV_BqP=>K&PTVkc645 zc2g$G38gU>ZNxl*E{KL(Lfi%19W>2k^jAF58fnIw;Ykc28GBGe4T)G=XEMxv%^3%4 z)-GIBQ@3a_rMpy)aN2W&8tzDQTKzkngOqw1GpAe|++MRAvsQ35O=FuP$PrEn=^ib} z!0~Qxz+hHR$5n+V&UD7Bn4lpUPIw^wqL|Bx(H?DxBPTSknI7I;hnW*RJS%c8GchAR z7-r0xUS7SuLyblm`T1%=^t4+GXqIi4lU;YsVw?fS~HeE@5HdMoryHEZU8hJqGhC23$;FM zc+%v>{&Igc#X4!#`P%ODLU9>Kd!AlYS9fk5Ddy>lGEqYekjj|6A{|MZYI!zP69lWI zNrGn!B+k;6oHx+W+!kt~)VJ4}SK|ls9Gh$V&(3G`02;!qjyWOG8jB}+G6NMWbA;oY z!W>JQW>s!rIS)+Ye3qg1XnKw|McNTtTDqeV=_ms}Y^jeUmd3|yL{pK<4Yt|29zNQk z@2?x%VhM^o1_RFzbTUTM@o+~Rr;2D2^Kv-O%Itwd2=wYkoLUq1c>}GJ|9sXD%F`Q( zb086F?(|V8pI!;>QjLDZqUwitT$U&t`8cII42pBryr$?w7$lTjBxA0o~ zfly+x%rA7OoCc0qn7^IFfnVA1*GxZM{^f&zT6?lH8lKl;FTM{j6mM*u*EM_Av{^I# z(^}O3b7%Oc(ca8IQ7{cTkmNJyG@OU&gf^{tb3D|s31#il8XWob)Cy9pGcm0*x*6xb zX-WFk1nQ|3VVXCnA8NZ-c2Zrrl{zIhw%QjmYPM{%r$M+KNd#LOG3cUA9DZQvEFga; zK~vWkDoJso!_N}%;K1dUyg;DfWn6q=GULeG7kWJYY37#Kh+u|~l(hEXK)Ty%66(st zzN7=6efh;F!S;>}>!R!<86oF7I++If;)YD2iwvUBl@V$OVLU0bj1w;+i2r!;8)!YH(pSom5LIRCK`ubJC~$pbVEBkXU{v zBTPqRvK_tD6(=;Me*Xe~a5U7}oq8Us8e*|FGF%#L|Kvubsf%doNrgrpTxSKHsa}yb zwaYVpB)YLP67MFbXqIE<)M`W(jap@EtUX*=k7FoN3EiE+rcg3e*%aOsZi{t<k zUDs4D>WGleaAzWe80y5OeH?RHWoIH@8HqNwbvA`7JGz05o?0<|x{b$=R#dh$HdbQn z1ZT~h))t9&c1>%Ec2-WGp=5?DID)Yug44;cHjZFPbUQfGR#Z0HbuE!>Y6>@3;A#{- zo68p_(O_=no*=Gx)e3=k0o3CVOLc9CS`%LJ%&-|__R^h`A~QM zodUvlin|1xVcsPk2EuMqGixt~hKsww*ZnXtWQzBSX9Wn)im&R>@Kyb0-PUlkem4+G zL$7#2K*tMWfS3ow-Ncot=8*Xta_cwdK?`aQS}$6*nis8ifKX}{$TFFdm9|y zAud*9-fVpf&t;g=9JH_k?izEO>n;~-QR0Kv5WYDvhpg*dh{bg_8R9zrn7}#=l4L~K z4!9m96%V?0x?#^w_YH2_o*UdZ0-+Qha6RUN!pB^15c3jw5-_v5xK zgv{>(uv6%J?nkJmHuHe~piT|yw;E{hRy?n@8@$bU6o^!V`eQmZsJ}zZ@92*bmum2U z{;CeYUbV5SkT$ycTm84-)O0u3%<4r`;I0kmogU3)S6!VR*Kt@%45|I8K12fP&Fppe zksp2THz^cvy5A${J@@-EBJaCDR1pEs%S3$N{W}!U29KW~hSE*^O#^t8Ltq$m|Al1! z;(o^i_3wDz_1KQT>-i%P%JD(>=WaOuxqF`n%=sl@d%jdl^dZtndM+9T zPak5B#7|!njfCGd3jP-0NAmZcQTV?<3jRl<;NKku|Ho1A!Wh|p`if^Hzx<=%tAHQL zuVtg~uLFK^sy8w!jqzk6i5nAKl&61IFPNlf*LZ}Jz>nZH#eywuu?E~BHQ^C$A{grI z!hL!>ZhVsAri!YOIp}615)8%Tq3&Qfn#8R@a~w~ygH4_7?cET`fcSaLFxJdF1$kqU zdZ>lx6%vJei}b@kiK7Q$N+MO`=RJx6kBwwCB$q2yU|ou^T-ET{P*OLm3Le=@RO<1X zdX6gb!yc5_IC?0c#MCWPFu1sG{)$DxMJpH5?;29PD3pm9-e^Rd=;sU16_}oIm2PIN}LR#*aNp=a#5vY06pqM;PrVlEL{IzlE4Gky`r)zcHCsY@0LeCnr;3 zqTfx_DiYo8c=&=c8Mn(;Rg2;|P6cjKD;hc@ZB5f6O&UY|=B%QrI|@mSOFRN$ihN!< z3jBLqj~gNkO<( z534!?qpF1FXFpN_e(jR(c2f%D(H0xdnBM-~Dn7j9-x|X-&YSc1ey2#hD%4k@3a&uq z6RZ)XrLJ3b1+x!vB>x>>5MmIP`Sr}WhAJAE%iTQzplt>o1@ zT&h&-Zh?h2(vi6Z0AQJ=l>KVmD^*rWW@W!>N0oFZMQds)nEp(UHdQKlr~Nh;z9&V6 zXiEN|lvkx%$4j-Z;-~zNO8Es+VKv=|U{hs}beQDnlG7>Q1st)+X45BUd6LGrW5YJG zHFHY<$dva>IaS(!#h8|m)CnXu1l2_#` zpk>Odb@=+F{GJS1swz2E(*0|ud`~rTXV9aCyirx{ zD1K@ybL$5{IN4l^q~uRbVeE>MSLGjpR`pEQ$7TCYy+`l@aRd&EK9urT;fw0b&B^N> zMZTlXmim zq3+{Hlbjkd5;(FnYx~qt~0$!`Q`hV}$tDc%lM%|yk-{;?-WV-8HuU@@+ z^{TqMr)TEkl1XD-rfJB{G)_07DM=0Ez*EuVB04NGPBgk2!F4vKf~&>_%-|}+e4?r< zKdswpl1S@T6wPmJKYwPh^?0!Lo8X31g_=+OmBDrHlk!k!>zJP2!ac#(_YYy-rF$X+ zAggDv&**?tt6>J$mG<;j22akSGA)_GRZsfQexgd+P`Kxlx2bqqw-u=6e^8(KYw8QG z`qUd-cd?(Fu&ASI`l=_rPq1CkPE2i#kw+A4-TN^b&T^nD5R)eT3&A5?M-cqv#-0%R ziq9P1`a|)o@vUDKmrmNyv%{>JAelqffaLPxVCz$bZ>DuK#;;qR6Ks7)WVG(3{rI6z zM>+IpMA^zD|tXBX}{xA>gmbBoV|rbPRj`*Yn8 z(scH&A7PVnN{DO(d$a(^`H2814z9z_$m$tveK)wF#tgRp>riLVeCeJ=y$G+n$Y1yj z(4cvkDu#?y#p9p2z|XM(lK_6oIs4ovNW5xe8*_dt9!CY&g{3)%e)|L2kuMq80oDY~ zW73c;)sVz!zsK6+0ec{TsSxxF*#mtWY&}-^wbazv(KK3&snacQ+_B&~C2XOi zRR2)$qCAfaXFUJ%{%L)@aL=WGkAPP0Bc(UA7*Kt#*(?1oyt3*L1pVm1vUJ4_==*5g z!@!H_fa22KIGy6KYYafBPudVNC$)ZfsPcP?mi`zc5GfmGxsc*O2Tw%%7qr2sc_P}O zVz@=;H_*ESbPcG}0!PNCcu=Q#7+{tDnnTHzr3kERG?;>{{9C4=Rf6)J* znKUV0`gLSRuyrBKJRY;~>tO5WqA1h>GhQ&b4(24T>{1xx)}j$X?5$QSk|JUV#yE^8 zm^i51Cx^NHKeC#V9MIEpD@|0Nyuf8!jyUok3i)3Ue|tygVL!roE4bI)6A!71OZTL$ zz6m*=!`6l2tgy%%9Qs2fm2)Gfh@5FK=$fD{;GdcP;3^lK;if_4%nTel0yE5C{@v}9 zLTm?&)Zn^t-mh2O0Xkig(}JxqT302Q!M&pcKn!%zyN4bXMYMR&l|!{im=Ob_gE7?@TON*-PBuy>m(@2`w$z0P1WG3dN)|;z4dL3xhGaD!17hQ9`*e3DT< z!>BYW8;nr6693`AD6gz+4uwG?)L=B%R@X%88^aMuRfz*^s;s6y)DQ`rS=(4w9s!$% z1*U~U&4Jo*ps^tkDQ~V0MFJI}x;mrXwHoUAxed?9xc!{mf1B_AnF8&tE!84kHPO!T z&z1kR_5a%PKWG2X<^S6H|F6scoc{mod_5$7E*|>p1^$1ff6g&%SKj|G`~H{f_4Y9g z+b}8I>C&#NUcnA!D3EikS33>^p>%HoiVk+$wG9zS(F8AdF3PiOQO@+BT<`gGOv=*T zl+8KmE-Fg8-F-W>fZSppyK}rLYafcb zNh+Nc0x`TPUA}`|79Q6mPVg>+*rf1GoS3!A2T&v?rJW1Mc_J~H68%MDiVrmp5s9h( zuTu>J&!UErI4%1|P!JS}>3$!ycA7}cNKS?}&k>24DMKJ^qn!c;N4?wt*obPI-knbAB3BJu_LO_UZJ`o!vBFT4yzZCjjM3Qd{iHS(^-I(44 zIYpw(P3gabgoq^H*6g<-#zZ9fe&>4)azrHgZt3to9+a?kZWa9YWE)ow? zvv-Qb!xtH-CW*SIhvC!|EugA?Jq;ZuO1+Vdp(Bpp%>EoTe2E%f1`RkJspa0v zP6J|R!3&v$lai=`9F3K-rneQX?0!l$a+HQz=m+64NNr zBofmpu}CClkhT>fF_Y%U%S57-ayE*@nN;Rlk(f=1Z6Yy;65B;$E+uw~#97qRT_SNd z1o5kJn3LquW$sV)+Ug`_RWW-YQRz?_abz9oHONg*UIQq5Ybnzbww zXJx+(}-(-CWwX&jhIX%GFyw3Hlx9$Ql8!NSOklEM) zHa6GB@-|*%*tpKO@zQ~slX`N-BcQF14J)f$`0tC0JUGM`e@16qUW?;QI;Jv7nKVb! zbx2;~DgL!k4)np5P(Lera!<@pTMrqcU5N#B^(1;Wv41N1Ct#e8I~$9W-o!$y1deUI zG_!AmBbrh0@Qo0>xm(QKtZP2$jl3^U^DFkfi&mwvPQx z|CBVg+)P(2H#5jSVY!(}31PXJMa>9+flx4;a`J@nW(Ug++WMf6&xZqYWTw#_B|Dp0 zX8}rt#gN#D7Mj_(JksbHX4bzzC`wPpA_L4vL4lY_p?QXp(UaQpwxqPq5Q`0wAD|1r z|HS5F^NmheK68yL2Tv(k{#doSRBVu>LM;_L1B<1nW=wSQ=qizF%Q}&)DVJHeP6r#i z5nU>&YTijy&+lTgl**`l=IvDe5l4vZpseg3l=Tv3VKYt8t*I+Nb9?PO(ip{#Q-3oQ}ub-7Jawg@qu>G6eK|G0~aTp_gy zD?6S*CGL>ah3-9t)n%JhX-r`?|57TSkO8IW1qTYu57H)Arm(jM z3XrKqC}55={p55^z*Z-AhPmZq5F{OD(4=9&ImW1)d&)yOwx*cYDiHVHt>hTVQYrx0gJqUlN$}nSaIv9Buw)osOI5k)sLbe$Qf9iDfvqqTGY#Ve zCVeqs*f;|Sp=1^s?g%BDC!^44ys9!&Od9$|KP;bMs$QW11=QTK4#e|?z)7SZk70vp zSZo-X1u}urEA&}0`fz&3&D`=gsn0U|sQO}6Kobn(duk#c;Wl0DK*iHAO~aWC1bV0% zK(S%`C#L5J{SbpveJ7!u*l5y|3EclM_$*NF?WV{W*&CEjrV>9|SE1Ck3U_)BhotB| zrQ>nD-vdP;!z_ee#g24J;EaJR4E0mHkHob5a<Mps`$#Xf-QpFrSrP6r!v$yAk0=)%W|=e0{?V{=^?{~9afqpp#Zc(h!7zFV zK#@9zjt`4=lVcCYICcZ(!)9(N=*W&e*t3me4-RVM*!S46^M2ZkA6id?MZdy}$Dnvz zFV2hgViGig!_Mgm^j|LVc%FMhcy2NX3D3PDMihDLr5JA&2xoz}zL(y5sjatOit*M@ z`{xzwL(uf!`NtVFc%p;Q!U*G0^L&iCgB)`=!(gBx@_bu!pN}y&yUn23Z!Lw=WMY># z10fpwj#aqy0ISUYmN{K9?Wq{kY8}%S!8A*zJry&x3Uq3lxO@7S#oaU3>7e(&^Q#jx zIC{^A;y)30&dg6kkV0ioOanm$ZRVCYK~sM`-b21OXBD<_@#8=1T`?&>6jMdihmXLi zjvV$-+wOfRrh92p-2KaZ_^5RW==~KwybFr|cRsv7rh!o(c7xM9`S5-ko9+4VPruNI zcf?e&QuGpx=zd+;hj+B~;T>&#xPwlpu1)jk#B!IIU|HEu5BZ(e>(H8C;Z_?g{UvV2 ziv%Z5aUOIM(V)F0#v7+O-f(qgZ`=~Iyr3YvWuQ7Lv(-5PE-MY=R_l7OFm_q^(=OR= zeF`Q1JC``~4PGn7PBk~hG^*Tb)J?KcH?{5Jo7#5qRyj;!CWcj@=`PMEN8-NRUgi}&g-Kjs>(KBoVip6%c(>k;kf|Qoi*=-j4lM;qw(U=8( z>cj0VhUual44ag&7E3&@$aoJZ3CG8Hy==r>UO+l_J16m>K%3gTD$1M{wwnu{lW0SG zydxADZ-J8NIbKN^Kkc^j5>7*1?O(IviN8X)uKi`ZvfxA)uMo0g*{&|k@&170ljz{@ z6BAs&;pUlJ{sA|RC~W$O%U8}2XqXyF6efLRhRRR3x4`ZV%46Hx_F`^?U5-*edokCx zWRZ2lFDmJbPP`AZ3yNTP;sp&X6r)2ISG4;nlZLJn&v=Ih3V^6F4xMA30QWt`Hk-x&T)C-jxdP(&qa1ELUQTKb-Ewi(448ZM1f`{_?A}#*7>n z)}wActS_*Jm~rd)bqAbplA%RB?1Qo(q#>4P@$C@TahF*PSr)EA>7EIYT)ZS? z?D1II^&b~K8z63^xN2OTFcK|ncvpOTy2h1Hp-J}%X1maXT^pN>*{(iOobAF%3~{zA zFN!}gak@eLi77BF6`@9tnMu}tDC#ggCQYrvHjg=qZeh^{uj^_diIdxa#`(t8qz2pr zTCN_Z$gS>*39B#5tu7!dy7_1%p}1k3Dt5349Nr838&I-(_EQqQ+AQ3$pzHykY26Ez z{CBIEUU@xF`PIsu(2$a5hS{lY&2Fh#iYfOhqVp4;JdJL6V?}P! zF?CvRaEJ%4!R6L7LrJ8ng`|YzkdHIIM0cvC2V&_#KiQJc{>x^_rWv?`>ImkF0e~m} zrEommER3G?aS`lfxE8p??G&RM-usZ-7(Ot!q~wA1MM~DsHTO-Z-Gj~jzi#Hgm1efn zK)lmobWh7)b(7CaeEz<4re{d72In$}8iK-=E1SeMh!N>KULN~N3=X?Vldi*?Jb z{g{?B?f)RAjfqmVVWt|EZ&>p1vU}Ju+DKxk`J~#?O0UnGj%;e)lsv+0MRoL)8Rkqo?)A&piN+$=+W#+|n zm=ZMb5Y|Oq&BDwX=B`o6;E04dx#ryD*~uvE%Qw&HB&|gaBRU~Y%QqbhkYcH#oF$a! zkJXht*Pab+Oz&wVC!d~d!MZI&7yv8FLG8373%b{roGkoi})^s$T4v zX>zgLL@bvRs~!B>$!Ux|G&$Os&eWLX;S2-R@Ds?#1kv+dVvKN!HgyFV@334KmPDZw zSrK$BY8Q&S<%4Tg{{*lr(7;?WkmKNtP9xxMOm}HBX>@_jJ=hKk7Q^T{DB8;>iB7=k zbF+GP3glX-wU=Y5>`L%IX7uhwQI?knPVWLe(#JGKK=jRpi~=Ahvwx^Xxf#8|BrJFe zm|^sjJr0#YPHdOw%YYPSi-0V^;JU=@gz?p13Q#k!U4@RBvR89q_zsXB<>n5==EA(} z2+KAl&qnc6)6J87naNhS6S`rBABMqTjx#Sj-3#LeS~Y|M%8mxqQ1&|+EBrppZJwT- z44nv4fU(uX$xpDD8^NQI#Nmk&2s1_5>DdN)!!XWpf{VIexUR^7P+Ip|v1$j8+)++T z!7Vg&(3a64iLuTmjNyXpq!P{*z7@_Nn~YOh0u~;pMkPWyP=h!Qp@U#irCI{BFij=U zNfYx8^iP8ihpmARhuQGfe{^$y=3kd?PIIqIzbf6F>Aouc8c4xA^X_B*wdqODbi9>H zxc9pbxXfAZ1FnxvQj>6fl=6)LN6uSmHf1#+)Q*_>jQx;LlXmtvmjzAxqe z6w=_nKV?6H{V6XBz~$UqQ*KQGyKYUnHwEmvKjj732_tSxc@lG;gc7bza}3i0*{z_1 zo+ohMCJX#k7Qj;OJ??#OuwtKkuMO(<+Rxac`e*FF0g#pMalhaOBVTYIM&ZNmzoAqq zHq-rsd#4R`$j!aqe$57%*X-9kpzt-%0gq64!1Fc$sc^sjjtvUmvA;#(Z|%2HiWGv% zZSa^C(Cw}l6u$x8;esMN1Z7#F&wbEy$O9z~dDbRCrE3!|OAwV_mT)D4D-*5~KvsXy z^O*;9edampF{itadMH~_=`I=v>c(ATLg8!7&8E<{*}NTq)KN4AG)$=lx!T)NKrO!0 ze9(l92hBAu(6Gj}Ry4%D)^!~KsbQ!2m#Hh;kE?Gxh-L%7u0O@ zZt@C4HhF&sK&si6a90ATxhvrr6n-Y*cPK?_+^;2kk^o_gn|r7C2`}V7;r&Qxk;Qj< z|Lle0fA;S6f-m-pY$)!+BD)}q1wq9T?>DI88}GA;V9&FO&m{_bo=bcYfK+(I`vWTc z!FydI2ww+z(jHK;!dee&MfZAZt3_p@kb4s(#NfKdx*m_Bn|qt}CzSt_wa#sx=U(St z?-o_Aci)HLKKK0sM2kTDSi3DSV7JxkHqUjpiZZ2JVSf*Tdqf#_w2+<-(xhqnRvIo~ z)x*|PmaG3(_fytNH?(%W`!?8dHIxZsjq=WfygS`A2HdY%Z;A%E-?IM2jXErj6br$# z)>^lDj(aUwm$1zEgE_tXRx;EJJttD@-FKtJ-C(XGftEWGjz0I1)NfL;TT&lR14AE9 zdn8Tx=#jLy07#RMr2deK-I98{4}@>`y@gWJ2}e?I^g-|6C@49>z2En_5AL;tKiu#7 zK7edIy4Sbc2Rb1*9`o(>QD2E82osn4d*An<93G3HBX?0rPlzLtaJ6_1k2v(Scs)I~ zo2YI>+NLzTPF6Pe!IZCYV*EN~M=DH!J5ujV70tObbvJ_DsgGl8A5T3DDW{w$RSKnc zqd4^T?$oETy-$OjXsC1j28BR;RVw!Gs?;k}p(C$My)_klM^(&(qWdZHHLPPM+Ib9Z zD#as*fsz~4QjRI8J?(R7mizOxYy6<~8vjjxNZsV$>K859>VFV86>xu<_9Kek=D#0g zpaLlUZ45#&_bUJ8sA8-CW=HC>802!hFGnD|n@Sx_JcL8=P~xg2Fk@BH>LgMB>ZGd> zT$OaS04NNb`?JKOiQtT*i9aM-P3Bhj>ZB`@@IYh>nQciACxOm~lio)a?1)^-rpx_m(t9ALDqNAgDH#-QN`5FA%0HC6J6RaHJNXF& zPb5Dn0G2+K`~}FulROY?q(ePr!@K{nNvD<@;Ygm|-9~~t1)oI}yFhREDg6yM@4oi@ z$K$>vVNC+geLKDG`(Xk!;M93%ihEbeUsDYCHL2I7QV3w@-<;~+nYt$x2gSWU_n&-^ z`3&k#_fF_v(T#kF-RIus-w71EjSr9ckNMp{!g|7Z6&^f919yO-rfDAcrQ!~Q0si5j z8{AE4e{-4LTxqz9RW>Xq{6p&$x*?HmmbshF0jvNo&aWik!gD&ZC?V%6Kx+HTAo#88k~UI znzkd>w0D=9-U;@w8*Fp3eY(eL+$~g}{xhoY_yww8QdE!dSlPRw_4Wu)x}7i){4)p5 zB{Q%51-d?gb`RfWoBi#+9;>hlHT4BeNubG`YbTAj^F8k(OhVu1d8{ihrrPpACTAjg zW-c@vJ%gQ=WxeQ9`U<+p@>sVlgP!ta!c*whS*V{jOf4~O-yV>dgo#C_oi-S~ewLkX zLT#6T+PStL{qOlF@6WcoQu;tPfu0lWZg3WHd8`FD+39!$HhV1p96PC-Z5E8k&$kmi zGre;GcCdY2Z1bEzKCmK>bY2sbfM^IrKcy^sgRd2(M}D6H4{Mvm>@!c4xv+} ze~(~e^$3j#1IyX~tsmCMHV1hpp1l0u=Tb%&^sXj5n)w<;S?GHJ7J_fVm!R&MJamHQ zTCe`%A~256qA`l&I044>nf3_a8jtd30sVFLPD;ccLm0pn1-BA{|C6@#pF0A0H0g1 zwlBx?SQZ?n+4hyt^Vt|SG?`~vk6_fwv!E#a7YI^uT6%^ZbGGQ+-Bi;%RzAqt*6)`> zKzarO%d%cUEgkGcQ0&EFl4NaPItM1pDlFl#4p`Xfs^!1!$=c30Ftyh-QFlnBUZFhr=#Octe#SyfS zjJi(q5||4oV*3OT^<%-w)bxZoczPi>pbZ`?5AvWF@$~UEHb1LlmYwYJqgmD)OD4eV z)d6x7xRMQREBO~xB2HG9iW+XR%_2BeK&x8j&=lBV4wk3P)2-SFEM9UWxOUlj@kZOq zf+N3eceneTX~T?DU|VNXbN=K8!-UJg!O+x)G2SSws=zonyS6Sxr)60W{H)|}NV2Q- z9z-dJtlzo`^jR=_!PL+V^gsxFW8LJLv%_P0(BHj0)}70DKu~7FAhNg)vVDXOTTOV&_4)3M*e-r z2o#4y@ag9&@KFue0(xeK8Y*Xm!cYa-4K@qgSPBxg4Yjh-rHh+Fm>+2_Ul4-Mz_0ot z=TJKVMGWYOmPi@CYb~vHz6prkNd-X3!ch4Ibr=WmH3{fu;#{b*!KkmJzA~VLBh4)p z5prKuSuJ*>Qo6CK3iKKkjV%q4vIXUJ(8X2FA^7H^P&Md=z=LlZqHi|BuN=aHTpP%d zlNLbFH#S#5cTxQ<@U0vJ2SDJI*O!ICHEIt+j~f)r*g7z)0z43*QqvZrXUfKf8bZyr z6;nbBArcxPx*F$ma9mgho~n-2paIYV>Ro7%5+2Q=`f?mK7`!EmD#~U+dur=LCC$ws z7g_{ufk-K%>d9#sw*h)-f$w#yZh&uY!Y>p7{T1-tO(6;&88^{ZH$wl^Mw*(PZZ5|# zGH@7DLmFD@sSXNaG_)bK2nGp^r_$z@&`jzGbWQofatI30+a}DR;f>8OP!_<*L?fCS z!?lsx1=t}<^hpb%-Z!A{T0#a!4vs~vaqhGdBMbu_dLvu|-%5q`fqQEz8ta?Nn?nY7 zJz6)mye=%wtEcFjM!`R&WKO9J#CFD{KERwwsJOC{ha-3G3>YnoF;cPfz>fOnMq?oi z;qZlJ;kw!ivQ17cJQ{Hxp)53T3{MCg-!!J8ax^!A)^N-Gin{V}80IuluVX}6m_0FV zv0!EJshaZU*)WD?gsP~!z&IQUTmyV#7gRfbrf_3L4a_JIAJCyNM7Uy{L=9+woI5KT z8!8}Zq0<^d)$qk!&}r0xIHSty)rbw()K)=oL?HCJ*C4liez>u&B?8|D22nzxz5pi8 z+Ik!dm9^CnHDK19F(spCl#Ip7xl(rX`0&h@`KS=2CX3lo&T%jv(cWm>W4J4)6l#s^ zK$yMDX5w_dpccZ9qK*9`z7h?-APv9A4D72Xt=OZX`uQ-Yfy(hPM9N~nLJd;Q(zA5F zi4IrkZz#yU1zu#nkv0iaOS-89^6j=-=(AloIsR^ep)fuDk92J2Tj_;qa9 z>*Y`$Y;qjLt;A1qL0`ikd`la-6}kod3||f>h6axbh+!TVa5`&jS`4!-g*?vr&7mrq z!K&aq-vYx}G`+S$b_AYTz>2a+c{N%RGoegdj1dnSq~9nUDjQqo!*|_HTYP4DGxvcQ z{v|VJOr3!h&}@xUzfn)44Ce0ICj4%?20CY8oZ?I;dZkP~36#?e7@c=`GOF21D>8l zZ@?drEm~E zK$FfSIIWb8ZEmcei3ZaG3Qj?|euBv#*D7)t;aC1a_4q|b6?Kha>_~_=T94q;DJq8U zZw@uV6w=tz3@bEP2#R4Jf%6^2&4sWM3X9V^wt>4q&Ntw0UWuR%%7h-I@M@XQy%=)> zq=HI(;{1k71`$bOdV|wgNI6BJPwS&=8tNHbzG6A@PutTh$l!V|I{nC5ibo(W0ifNL zA)IV!Z4fLEkL7@eHu3x?r;M`E(7_zJ4WWfpX+8ON+>}{?(S@f43J2s5$nPKMS08C< z2#u^33k^t?H&@h*Tr^~Gzrlk7{i@~P)B%Bh_+Ldm-wy&VLd%?fu$01eL%*tp&E-uC zU_WjAXn3VnKn-LywuJk&G%SRLNWVxqj47NBC)31;oyrsQlop&RWs4o}(>aEmCzj%M zVh#j1)P~EdD`19bsH6@Af@e;?7BJ*uQVt7PJHVG$lKbGy!6$iirn2~kxm&4;CM!I( z@$~`-Lqjn<#ju0{Ce(!GT2n0PK~Ai-X;o3*MAmWSR>}}|zQ0nK4J#yQJX*(dI*lTl z(13|~26Aw{4bx3@6%E}Aiy2y{Nk_4RU?we#;8hJ=&y+WdMXZKT)={n(M4Aodsmj3p?XyvB@o1P-8Bs+5>>{z zGy%0$aKToGr)X#@dD5Ad#g!dK5Omu7#zq_zavmQSig4gV1G!*y6d~|li83~+4 zx?7yiX4~ueQmD4!!j{@*TB_l!PQuPionK)T)HK$I3QFO%JX`>}TgocSBjp8^p#`D3 z#->nn0XPd+pamsOu>6kHgj&K%W_b%-JvPIn{J*89CEQ$4+fY&0QW+{}S`5k?2IdzQ z8U@JfYUdYJS5y?h@GcuXs9#-eL(8Im)eS8Lg#%<6At)8J5u9HOXJ*nBS0ubxlZaYT zP$7<$uZ*pTIfiK#Je6Mqfm>M_s)7TIz_7B142a!+ctULe+_bm}&Tw>ql28VPVYI_n z)jG;VPdZ5&QceoSHCzjdwHg$~nHhBBxdBp+RMTQH@PJ{sDLjPNQ&=gESck)+mCnGx zd4=L+(a3aCSf7&syTdI_+#+M#=+VOhd1FHJYs(vWy6#sv=;X@K{K5e(g?$*|J8iIK ziJf6CnPHfV{N@QM3EqwHMjJdfYrqGzXoDy5X+zeZk0lF0T0TEZpH3|H`B%B7`vR`f zNj`tE&pRR6K$#l&$1R==*0r7__+#~BeExHieBNO4Sp1GFvJ>B*#0?&-f=Ye<$&iCK zJ&9@962*>W5Abm}+=J{{ARC0kBh0VD{V1RRa#x8jX9Ij&NnpLZ#Fw|mF81|b<#A0* z^5u>81xERDKxUNBTarB6mp4`cc~E==y&-8B^ig$a_ZnBRFK3lC-Phk0PV(gdf%X@3 z`&pJgeeL)tB76ig)P9y3gtn1P6?kBL@@TL<0B8s2uXOU!&*usqL7`(m%bbQX(C%u` zP{KY806N0?<(Ti-5sa}Ti{DhGhvZ3SK53Z*cA#y8IDa5FA_SJDYiWkzm2=tDl_F+G+=lq^hS*EvV*0S3(-MKhUcUb;NGlA&K?&cMDGA6AtfT z-o(6IWE&4NKge8uVC6aH0qz=#Nno!rU%?#xj@v=_$9nfO?}-q$Bk+%0x`@UXuy2{q zV^_;htfhe{${%4);{{|-V15vuVZ}|_(-*ku%*gV4Na34Cz%i!y%ofSl&?`J~4D$H= z2RE0g*jb9anqevWB_BrhCKxLitWY|_az4KxrN!Pda5S~uEb(|TjFs160G*@c`^=vDGvWA4*xC= zPlA4HuinmacwQVnBn}@JhtH0~tK;wmarmk@d~+QBhdBKHIQ-9XIL=?~`R!mF{tfU9 z7?DL@5p;AOgF`ROYwhXDj>CJ!;X~u_nB_ZPIfb1oUFE33$e%R2zs!Nl?dT;UAK|S) z3HgT~IN5B(+>``Gg;J7!DT2k|29hj4NglynYY-pcB;^6TY3iurNo7;Vj-6RjT2@*-YEns=ewP+* z+P3??Wt%&4`h8ovi#rpqr6H&79XZN|3+M58W2?PO>2}^i0u*x}kE?WUQF5B!LX6(n zqPJSn47gr$-bUplm=Jx3LwySd?^c&a-!O`~d(hrJFO-+>kVM-9H_>LmJp--`QgDbJ zQl`F35c`&LRC&z1BW>>Kvm)`Xj=WFqy!GsWHg5wd@9@#Ug<(cpUwG{Y|L_AvwDl0! z(D?-BF#PH4D&?z~<9RqA{w2qC6K=YmTLh-_Hm>=k{BGvD{#O-wRsYA#b^Y0Je!vaw zQT6vxcz?)~^$udL>zS*_7b@}_6h2Vl4=P-hm)BQlk1Bsak;gTnwC5kpb$c?=F|Z-W zwVjm5^BZosOM`#OyEDgn2P=G{B9BWjDUatX-1L6DLE*RtmGZYT*X{hPBCq=Y4d%F0 z>-}1hSNm69L!muty#*Y&dcAX*qr6&ggTjX>_Aid3=a0mNw zxN83w%ys*_qT#UV_K#6GUNcGmPi3y_S;AcR^EHYd)&6@GK3viNyuwv~eyngc&c9=h z_KZ;UB=dCy@{tOk!W@gK{+X-DtMk$=apZT#k$*$ssy&}5T(u{QuT#*T(-k{=DEthC z7c0C-;Y$@>tZ@3Z2}q-Ub^f_ukuOr@pHTQHh5tk0s{D7%^|f8$%C12TL2q0B(}YE4~#(qr8;Umnj^5 zw1VrqR^h1sOipjp_-syZS2*gC_Yrm}T-CEj<7aVtpTbd(yiajJ;i{g48b62AhZK%_ z4ud@Dw=$OVvOjQ#dgLa)y*Vl`{S#2+QGYoX$Wu7#*~xr}!c}{UG+xQ_ zL4~890P{HtSM|)(cs0w{C>-?^F<+!`RnH2IU%>L0DIE38fy_Y`YY$>e-|5%|hJR zr*J%!_bU%5T-B4q<)oi`b6TB;vFJfQpUH7A<%h7mI$w1Mwt{&c3c`jv)FbbE4pI07 z6yVLv`y|-+k`VUt&LVPLGfm_ZhWttttCbE4`DmkY5Xznkn1#F%=-VR@t4@nT^g_CdG%3^ zKg@CYjK-(4o>w%!lG7h(++zKQHJ;!T;B$@pm>-YBy&Rv?Z=bQ8ypERq7Ph~;CJ%3U z(N>`GS={gPJx{6Ude)Ekt#OlFt|QOX_AaK1<@leh@y}WR*&2V2`(55QkoqN$X!273N{t_2J(p{|n*A*AKS=%G za=ZSd$$!oL`?$u3vz`|;zMR|jmd0Cn-Z-rB{_J;oze3t`2iqgZrR4HkL;XBnCC_F% zPt^Dro(KAB{4?f5G%od*X#8TfbB4zAd44O?_+CEW)oJ`kZkN1IBJJNI=T%MqdiK|q z8vlUfR<7%%o?BS%PEFp20HnL> zG+=bn_zbSMm&R*YexSxTO8;woGuv^l#wVfyur1KIoNrfYJe}>|r16F9&l@#f!RxU{ zHC`gBHQv{FgzZn^@ge=Ql=YmV@x$!rNg6+s$)Gh}%Cjeh-g3 zH@921>mIH*U*oIU&%-o+59=MP@e|mOGc^7Ww*NehZ()1R*Z7Y-POsAVaMu5j#%D5r zMdNEZe%{phDz^VUjj!hMDA%FVKYwIBUup7d+0LHqZz(U&qa_;O!G2h!@vB+SMvYHk z|KF(b)$F%FYWyI_?SmR0&i(tO#{bIm#)}$%jQKknPh|gmqVaE8{@)t!%=X(nPh)mp z_?PSc42}0>KXlXhkKC?PG`@%XeW=FYXFJAfya)Sjrp9-${5*}1;{LAJ_*E>wMB~qK z|E|?|Pu6pl#^2@k{!Zh4*v`8&-h_i1wud!-oYVU>{wDX!D;f`RJiM>*B#!gXHD1Dg z{$Aq~cpN3NK6Fc8_?Pk8LE}fcT|G4ZF#Dmu#vfxpkJNYx+c`nwH*tK<(fHeJcb&%5 z*`CE3@5Ax7M&pAyp0CvSdbV?$#y?_v?$r1xEWcah$Jx(&H6CF3mo>hF`}aMK&tiXm zuJMmqkHz_z>X2H2L`)Cl6}e&FLpKeih6AUE|f9_Hh5pdK1}i-8J68{hqJ!{oLMR8o!_Q zjMeyB<})=e*KhMQp2_~H*En=BZA&zs!t%e>xUBaPjla(A+Nbd^+0J7cKb_kveuE`? zy?FuGo0=x+h}czq6h}8pr23aVyq1{xUdjQ#H=mxIp95kBgY2+V1eb z0{(GZsmbH>pSWGF$oCM4UN>vV?{q`{Cpl? z*?u7){eL0bf2zixowA2+m*&VUE_;6u1?YTS==w3nAm)B{FHQrH(8yht~jrk6ZALV)Md5u5B zkI%7uPmRm#wEoPoyRl07{OdSPemU!zsqo$)&q-sp#`$z(%wsO~ zH?u!$75O~Sa}E6CwnX8mzb{e4Sgvs_gWGCNzr60+qVe;&-g^|Tj<3fRj(%9r@~Sb4U(EKrpva>=SM&V#x+X6_?{P$vm-c+8aI`1P_5PsoYUWm!IFS9D&+CL#g`=K7 zvV6M6Z)V;>;b{Lzo(}^GM?Fund{2$6)HbS*;#^rrQpTbekWo&;JjSt~? z>!onikDmj=t*^%A`}YHx%Q(T$U*I+(4nHRj55?gtHGTo>zfs}xRE_oCsc;ls!}8B+ zd@J)q8vh&fubHEt(Qg(Wz?Q%d7Dz7pH&f$2j;nyihqL~^%%$Jt^Et(uywpEY;n*(| zxL>Afd=&Fig`@p4e$G=k>XGy6e2t&ada4zUdSv`8W-jeNh1c7c#Noe>!|#a0_iFq* z_S**vSNr`7g`=pC?Mdc^le9CBd3TMU%e+5x*}sqSdAV5QvR|fX{2m@hb2R+{_GhCe zFZC=|IQENto_?9eTUpN~3derg&f|K$!cos3Sbn3%w=%zuIVRC>h0K2+hd&;NKO2XC zr15^N|3A#7pO>-U68M26X^(s!??mQOUivLh;n?0kvwr$b7)YZ$@&}j~D)Oq|hASN9 zKWF(fH2yL3AahKj-!9?!nXbs=`3wJX3&oLdh$FvDlW%7I*DCU8|4ls4{9cnU!b)L# zNRyX-dqUyZUO$hoy&Cs2e@@|8ubfX_RXFMy$ntM!ydU#-6^?r3d~%ez^ydP|!|l5` zymKd!ugmv{!_Uz8`J%XSw!+o<9@1|V&+MZM*GWn+^y2&11x{NCNKSehbDgt z%ipiaW9-Q1)t-nW|C}bD%X;2YINEtO&to5IdUmq>e>8b%X9635?Zy6`%KezE@o~)k z3dee7oOD(=>SmB6-3ILZkGL?VjTXN#)GWi>PqH1&nwQs2EvxgT((y}x71UUm;I8jaBMGrt{k@k8kf)8 zou+W?7dak_6^?o)v7Qo*k7YhV;iyN>+jE#p`>*HrMij2jtE&}`UH&JQ-=y&unQvvD z1hQD~-#DIc*W_2QKlfi%)i~?hwX8own-Be&N;kSE?R}_wV&SCl2HGUTJcNC6#zUA}pA%&wJIgfp+@k-Wn zl(~%ChdB;^(D=*DJ9Go3uu1v1nD@|lFZRzMh4UpSl|O@d5~R?6__(kK2F%?VNeI59=SSarr)G5p(Ic z(^>!cIJ{ERBcG$K(Rd-(d!fchGH=oNaOO*xOM8NB&w7n7Wqx%WzEjgbj`iQK@e<~b z#nH1j4u4XnOjx{!)dbC{JTXrNWW@f#p|fTt2sYxyIjO`7O+`y?x<-HCJ$} zCNIC&>`_f#&Uc&gbPf6pnfxXZd$DzMJ_63P(L#`Topj z3P(LhS^lWT<#XHLF*iXLUC_+yNvk^~VAJ`D%+YVCKfvodCVtk`VTR$()bO`8x=iRZz)y^+j50ty@Of)5{(aFzE;z}i}@Cf zuVDU=#;;=jqQ>_!|0i?wGxqNle4hGLlb4@YwR(UMY*JpvXR5-nT~k?qy2j=EhMk$q zewWWF^-$!|Z|7rWunkZ+>X)Ch8?15pJpCD({%;dVjS*DjQGbiTMybM4{|2^yj>cP= zpR4IV)hiS=Y20GISkZ&^t`OqJWeUf7x3T{98sEbFYE8eF_1~n(qkj2((H|9#`tM^s zcWL}?=J#p(Ph$N~YaG6Em9`h+@WYz^Ct3f$H2ygAFEu?!xW7_*ih5+6bmMwYWG>?{ zmEV`|uW|XgzmXd6#d;=a{993-F-PNhY|lcC%lYSWjmzhxZ_)T$T<;?q{~hapUE|XJ zk2JoP=UdlF!eHqKDW9hC(QYAEz+C!Mehz4YB9C$MD)-A2jX%eHw#Ged|JfQhm{&5F z^?t+l)W_kM$Kjjf@CP;SwMBdP#NqG7;fLdJZ!e)w+AsB|$Km-J|BTyPr11dTc{X$G zNA$m3pOk4l!2Yb!_#EbS8ZTwu!d%*aCfB<>4!=&*Q_Fg8)Oa=XJL2fMKMsE(4nGiw zf2HveY=2Jg*nXM8e1yj3x@b0Y>F0~s{A92j*T><%jl*wt+IqEryk8#J3$2#j?nZ?U4 zT3?+Ea3*JP_&fZ1=6!jO`ceK~PUmaKc_z#>OtnmO&6tET1t61-${vzfj8lS{` zg2v_j_Nf{#XL-3UmiEi%Waet}%`AVO#+NX!(71fAqekPuW%+uI%jY+mHGUV%FVy&> z%$I6he$IEL#@}H1H5!-SE3{7IM_GQO#^wE@t2Hiva9qZP^kd@qF7v&@%VKCin^ z(<7hbdQ0OgxL@RTkJPh`xf~yo7vTYHb(}A`d_HZX#^v)lJ2fufFP8UZr5<@d{7X$< z-UrU%`lY;F?+wwoT!%DiT%I>KYFwU2Zq~TL6W#%h&tvYkgg-DF|K){ueU>|7~`xeg!ZV$|U?eXf^!MP*o#nr{nVZ^P58pVzQw;{(K77N_vG{GyKdZ{9qIp zYi_7+D+51a17D{s^n#`G5HbB?Q$GB(BmGWiegphsRX+Uq75riq{^XFTC{zPKbA~?_ z`>VGAXuy!-Zgcb%@zD;igXq8?n>6t4c3konX?$LT05yCbM>(uVs^iC#=)0QG6^-KTP0&BN^ejemnX(-6y7NFPY zOC=n(SO2t&gp8b@v3_ilUjHIsS`}1qj*oUmN*}S8uexj)GTN*EAlF|rT9m~4li^>l ze>E^&Czhx@4PW7V9U(4PiH9JWrQenH^;w7wUzxXWVC00@Xw-z>?gDzU838+ z16X_YKg;dzFVr}%y6kO`(_a1axPDn4>&LOL*Z(juT_+&pIM@F>OemW!yC3p&hT>bs zh(d4R0!P_&*=HfIJ^MGZ{fF>G0~^|(3IDqNc-}{yvYl{9+X7z5Zsa(WT-Go5A3;WY zpUSmH#GA`Sa(A5_z&9?`6GmkCi*eitKOaDGB9Jm&Na8L#CN&T+8K~w24Xj zPpb4o;r9H$=y4$-*G1@md{k1FmvP-*-B{9FiLbEd@zVv4k!z7t3noPpX1OlRhxPXY& z`g7?Is?@F6YKv$KF11myVy)JFqt>XjV$qhi*1A;ropbKFGj~ohm4EyHeSY^t=DqX1 z=bn4cx#ymH-<$V_OQ+8{+hN<5F19tvN>LiMtQFU!&MWD((i&t9w1QjQNCh{}D6xYZ zE&Iv(`m+4NmlH?+;L22eYo_`cerlILcs({+6x{q}aPvQcTTeqOxbY)@U2u!*gkeZ* zo;K85(HY$Q-XW~JqBAiXs)h!KPc2DmVcEeg)kD2?!BdK;O?zQ*<39iLC+oFN6`hCQ zrsn^CfA;@+f5E3+L(xQS=d9qC2}6ThW_Ukc|094MiQ&P`7lGTd?BLT=OOO-Xl5Y2L z%I@n(L~!#|fAEUV_804~+j|ts;g{G2Fg_bU@&>nD>Q{Ul_j!YxpZ*XfvVWkiB#k!t zujuUPYq}nqKgsPtA*8OO@dWw7&3~=skEmC?bk0td#{0=oTl%aS=`!{-QuqU`>HT1!*16LH8 zvXv_;abWN?8Gpwf-^>fWwE0;A_HLas)F0dm3Q`;BZfbB# zVkkse^-zDsGo~5fw3AGy0Y^z{>Oz3;3((Y^h5>%Kt0(&w2e*#Ia0S2q8Dp9I?3nS` z-<^;$wob%K0)v~MMBB@PoByb@%jTzp8!3I+iUUR}xcQCc-+D3?fE5SOPYR7%^Q~yq zIy)RsRL`}l=Z0EZ>)M+m1O%$*2Bvo;BGGtLYcy3?#>~^2Vv*Vea71d`6TlIu4!1=D zbHlZbP0@%Iv#eOuT5YY4T5&5LwVLDbFKUJ7SmA|MU8FgZh=k(JO|=m#Tvr#1#GyJ8 zwHhLcPy)n+Vv%~Zvd7X>F7J_1fS4w*2>3rHUEd(#oAmYmhwcB<{{PeV-=zOH)qj(J zzDd9Tv|hUZoAe3D2LD&|HyQqarPu#bzZVa(EVpG-IGuuh0G(bwGCTsQ(z2Yd^&JNX zpEnDs5iWOAGyxPPNPTcnovR7?Y!C7cuAy`4$mgPJuJJjj=}0e0cRev62%IitC&1lY zh??Fug{8^3OS>6c5AcdiKc2Vy<02MJO z|66cAOc8U57^R4Lc_{e|Ma=jAu$N`wLT6dts^UQ)AgG81{wKhkDn%^J{RNo2R1u4O zA3@CuWk*)8(v<*{I)3j2?{|SvY!kC5qf|vq%DozU;5K;!?*f?G1hU6^KLCQ*vQIBS zt(iEZ_d}qYSJj-^doon`6)~RJN?2O{z`p@Z(uU>adZ##8K#s3BNh^eqTh+lOjOsGr=v)JBUgD7i>~;Akiu2#(i&D;oGVu$7^UZn1s; z_d?vNsPJtkHWd}V@AV!EHI=H( zt-Timp`yZfTk-WUCMqg?-_P3uH7Y86clEgmYF4N=cb9AfqEQh)=(_`mHbwj>?`CMz zp@@5X-w0Z-SHyiJZIdE?Trd;Zu2aNM3N8iW7DenXx(lT3P{dCQan9~k#2zwxmm(f1 z!0_Fxh{t+i_;xDdiQaoa+I~emMP|RCi2c3ag_<`M@l3(TKy)eM*9ACD4k_Zff}a3! zL=n#yJP5>R=zQx18Z1j?h8Oek=vBl^1)qa3zam~PaA#Xqi6UO%;UNL9=Jke}VXEe} z{24%uQpD@M1_5z~BHqZu30SF!H_5i3BHp4-s}ym7h^317EfFge@iq~SiufH7ZHjn@ zVxmJ4?-jIzRqGXTkZLw5;`c?LfjTfeMOD3u5Gt%`ueW*?)8w%VTWc<`di5c>-a_20 z_3BGz`pIX#N{A>?M1Pth0YwZTVyGep=H3F`4^zaT-nr1tC`BAc#2JbhOhlz30;ECE za^X}RjGDPH;wf|XDs|$7ap6=eDsi;njG8|15I8fSi+|lXo;H zcelUKVXQxb^=RZ#QU6SFE`*884Bao#k?Cd4gmJH!NT$L0 zivKg@{0cq>U|Mq+b+7u10CDw$j{%t2OkH0q9))$M!3Q}B(~jx^gOAmCy%+~p1;HEn zVQf&34bWkjno@F+;YbY!;sZSj*>zaQ(-wV0Gt z59DaB~a1M=fyHG#JosPV1z!tzds{%hR4dAD3jmCpxr^C4h>Pbc4*!&0K z-1QKAkV{{J6Qu>6k-;v%w#aw7|9xaX1Rn!14W(FF-kHU&9ALIi}I8jV=hU+Jh zmdgV|PYu|zCAh6ExjM%vbsb-WS z5`N5%XDDJ7iLO+{YLXUYwK|-AL7k!!-`d|L)w;-3Yn`dq#f6xi{oM8v=Z~R{nnCMJ zK817Fm++B=^R5W?Br4+38xABb7oHXce3zXAlu~9RxsQp<*_UMJ6-2NHuFU%*2@osPTqgla*#R#Ll&`Kv(}^?3TRcR!%E``O1m~`$*kCentV}i_=Ta-5pRUk~ z0(SmRs3x6kzoD(&n{-mz+678m)tO!B?0`0>p(pmi$ynUe=2^W_n{7o80+LNiAx+?Y z#khqL;KN0)L46859oZdk+Xa2{**=g7C2uh8JS#Nnpd_xUhEmmnv?{YcKo?;v)9cX* zRv#3df2E@YrESs-++!&<+o@5Ks1mU1b_mr!nXD&?s_F!)I+UzJ@v^e+ z!mM26`Az|iBc4LR^nk_QegLEo!qe}R;i4W?`zCNYb#QH32mQF6 zy}cX~2W*)v>)I2r16^R|tAc?tL=zZVO5D|H;!^sq)Z(rlZi-8na6HPhFD4Q8eb8bk z0vD5o>U0u%;{-%6*##eTb}62z-dCmdUXC~vd;8KtHfGgOvv;y@73DX@3A6841N130 z)TiVrAUd2=KvMQwz*B7cJDFKDW44Ny4D*RPv)7dYHfsZB~Ldz9N=U})Bmrdd-`v)>f46C2VZf}GfJni-}PFO8I) z9oMh;*Dk%#c_YX@c9+7OQ3aFFh8a#$LPOVX&yO|)!l!yy8CZ7<#mWZ%G~OH zEzA0bS-!wI47&O^U0MxIkHw|9{wL!TSM4N`3f5_9o}j%5SYU6T19^oaX&O0OTcw~= z&6$|CoWXX-vZfyb1=Cl9e?38GILAVF$L@_}&chv0dS)4)W>1*)wznVB_Kfd7vg5mt z>;yeC(sIFbAmmsaU(vI#N2lpFIH_AJEQ#dU(P_S>pc<35b;vh!ZgT0+EAZ*gFi1*w zd~(Qfcd3#`f8S*88V}d-xxM}Q{;Wp-K(`gF|0r|FN!k9>O^BxH06ib_N0@sVqc=JY zWMxBFITKBu{9BAgF}c=h%K}-8vBhqKCugTYjC<4|tbgsLA?~YCR?oXF%=iyL^|6dH z?pTxVr5QCI&9jS>U^!cEZ%6CMYsG2d*Y^WcZ{+S%4M@&k4Y=Re20>$ft|L1q+i+g8 zKPQf{mF9e!kcjHi*LfxOkmmdex>A|F*s@MSnP9fu|7GNUSIt3eFE1qjFWONZZ1#})ae z5G_ni8lWyN2>eTFC!@5JQBU6&ls3X-S$FQ ziBc^v;Wtr>h4v^BsFg|M>|T~LZ(Q#9+%t1$7M=kr!ndI_VT5QU6o9j!nk)c@h<5*VuN7s^4 zu)R-GG549dDaHCG8!Yat)GBqNpc18*W%WyAa4d5#fidV0-t&$tb&LmD=<@;SSZp>h z-3H~>LFv8*!;Vv4#rCB|C-n=cJ_nyjBO4e7ei#V7lqS1QIjs~@?+|qMWp+RG_wgi& z!UK&8kW+`IbqJS8DXmKLP~Q`il2cYgPDyD+9%8kIDQS-JrC+kS!^dENfE_2}iDjMA z+dd($FxNSFz+lwW51}-IV*_&PNC-`^ri=#Dof^z?(kfT^@T`6lU}+rXvM1%{f=hu5 z`a+LZkT)QMj^==89ZrRjH-wETw$OgK`D5EE!pD|^H_M^p)6+*@1>_l^y>(`?24)vF zH=}zT8L38ayy<0=X#$1`3jA-D>^e ziSN2E``K)}%JppaE7|rU*DKkt0R-`jxQH7y8LSX`aX{Z4zaYrpeN zr|S-TG1daw~uZt z0+pV2?N<%q_%Z@7yIwIQLBBg(_qjmUeXjdm_5%2zYD1)}Y6*y2a<>hQ@3wznlNzoc z*bf1qy0lzX=Yxdv*8ty|hmgT+-f2H=L&ekfO%9N7ljCNGl5n%*9ssn2PWyQqWIS(w zh|C|__aK)krpxsKn)QL}1viL!!Tq9JiFwieE&y6gm+Mbx%%5DFA;ZJRyU0aiTsOOa z$Bwq#wCrS!Qb>v{mRz+IllJRtBf&zs2nrssO(VzXR3vhK|S^xmvrsJ76^bw3a) zgnpLwFrMk++U3~ezz!X^I-$c`owunlaoy&86o6!hj>jC>q2pa-e%J9Ra_J6tIbL;u zU9T#10fddi^+(4afzxti(V44q`cN=e5sr4RK{myV;@AXQwQS^LqB z{aFXl6$i53N9z5ogY1!mS%20Z0iKt!@?h3SZ~$pw@pEaA!v)`d0*^Kb7>;E91Ka!~ z>s>F1f7kn-S9$t9?_U7Wh9AlLItvW{I%|g)n0G*(GTe5!9{2tl8Tm}XBcPqyQqX=f zX^r`uR1$=f zMeZW!hD+hZnQH^1J=~Rz% zBugrCzTtqrbgv-5>2cnAG4$yvbf4vMF1*ZRyS=O2XT@eg&EE>$UZCBV!TD@=9-KNo z8_9^ToIMzEZ@Lj1*4f@!?s41P_FVTQkF)h*C3?~~h~C_jRYLUNFG`7?=W#xKDal^# zp0|?J2Ca+Sy~csImn#F7!s%Rh7I@d;9^`Qzw7>_2ppNZveoEc-Epq32{CMiTb?q$A z^=?1f?U@byMb2l?*mRfeUI)Xf{Nc_)LFHg74B^@`98I@>DK^Fq-BX+$2^i5{3HQm^ z@pUkwaMs(MGkccXUgpl3=`QoUgCK~R<(}YiUidIl6M!WPSlp;Os?pDRzVW2;tfu87Gdl@WD?(rUH%sT;$qG7q4 zhXuqy#q;ZMa0{HfowH^E0%83E_+q@r@6MVuE6tDJKZbtahG{eHTJ$5>7k{n0eV4i2 z7;1CeW1%hwhVpOTSpoMjR=*;m@NH8}8{H za62a=zsLEw3zRRSFwO>9Mb1YsZS+B)UfKEeMHJS~k0J43R0HaFeh0Xmpw>jUb1(?X z_Bc1X_Is8>UC`rvf87MMsKXs>Q`20@cON8+Flyc21m>@`P~9Jz_jA7AQ&@;uxs4|L z>{hou-+iLTIe~_%5KdtXhPY3R(dRgK)*Katb70D$W4sg7JaoH5%{FD+D;KL_z1Ok- zvLvz${dJkU%-Qj<+aBx4f%M-JYKqoHI`q2;RcjVSR<=i?wUN-Arg*|iw1pbO@kT2e zZi!e`Yv$5>3Zbd7NH`H0ZPheI!?88>?a^8*RJCSutRYktj>RL@?QPAG(4wZbk!mZR zh&9zk;#RZ8n0 z=2m2y5lH~cGU$6wE?4g z8zTfSTY%m1HPPC+tTP)kGa8S?$bHIl%VtcU7g{*Idhx<}R!u#;XaR!b5qQ$C9$e7~ z-GiJ(k!an*NF2H#RY6Uq4s!v~6m8OWRAoP@SAcIp}@I1 z627n*#}uC7MfVZj(oEilcSB&H+G`Ww41=|`z8-{FwXN;ZL}*pG89Y)Si-1#ChMI7w zfR%+=tKhAa)>tjLm*j?9LUAz1bTkYMc2f(=CWxnM4H^-e5s5}(O||nPt6`j4VZ2*w zc<5G!z^H~qBlZLR(LjKL#^A*wEn$q`nAO}GZ3xguJG?p55RKFY@TqfXSqtyRL}(24 z;HA`Vwa}$)v81oVIF=TMymlLQ9F24&EHEj&It&8<&AUYrXxxdZ%eGzS`E_zMqRx- zgjjmGIYL3p(*pQtj)R1FdrfU~I39=Gp!#JcxD|AtdM62l#@QRt z5~?sNnGs%fs%?Zx3Zo4J1u?4A33!hJm9tK5YqS=E3&tiIX$aHU&^Tc((!$NiiZ?dZ zC#+BcLX-ywYQr`0*5>vEygmiNKp_dLEuA)f>cZ(~V`tn6_*SJ5ofTjTn45q}C zfjAPJPSxxL?^5XFNWz?42>BLxD3?;yQ>Ec3n2^NU8jUQX6k@fs>3PdTF}bY`bAf5! z6wJ*nAzoIdo()R~zRiZi69!i3F=?l^9iDxLfq;MESOYl)oC;oo_uN#Za)?4mahO8- zZf#owy-)Y zZ~DT8^B1CEN^cmS=mQ9FNOnza2~5qDJuzS~m5@k`Aj&J?=b7^;fKo34f-JRW>0s9L z3vweVt~^0*FvbG9g!KUONW8H%mY@U(weX%_B(^F-Ud05h!Vn`+yEbmYIzVHA9b<-% z)-|qAn2V%f){z6 z#OCB-7y}B1~it9`O z_JJ3ng4VuZIDR(AB^bbYq-xDfSd>DkXlNmC&6u}1Fty_JK*i{?(Pg6oBU=*f(a6LG zwR!>>j@33!>^NiW$gyJrBOCO;`J)3P@vokSX(U8Uf>!F0u-@a6IkJ9rEZnvVj#V?K z!Y3_&jZoFv9v|5rT@9=2$V3?89@F&P2<96aCft5ht(n)3fVM5^UrNa2Cbi>hPUf1X zc&MQkW^A;Mh6ucY3kz>KExno1aSiJ!yctU~3wC(C=Aj3T{T`%5qbEupxDN2P6qvzK z3^+BPV1_6$alH*vyGYU0;c_x_(lPeZVtZ8j+M*UfDh`3lH z)Ku4jb*a>Z6Bax`a@vyv#j3UNzM?6*vb`xryAaHp#GITEWwlm$V{1#Kyc#~k@p6#e z9;yo`!sT_5Rgvb_wn(fTe1SWv^670&C^OO?H!8#JaDfqnjQIacOnW?5-W08EZm)}! zx2*x;(NoJRDy(wEo11FN8)|FIVQPlPjv3k96m9Pq*${0nuNbY{C`K)y8)Hoqta2nP zBTIaZ;7DmvUaQWHcgbth&LIhcr^*`PTCJ`wQV%B>U~%Kvwx$i%697OGQ~?v#!qkM9 z)|0K(&?QNl7)eT9U9?dCfTl^jZH<~RfZ>cv;;_-8l?-u6Q%M~9jJLP3Hr9-(Q^y5{ zO^ehtg`=DoM^=nEr7luaF}l5CI74{<5uUPE2g_c&(6T%H_5fd&_d2*~3E$dU@J%%p z{Uj4&qk6!mF{Ynr3;?~9F?z&na-M&qV?kcPF*PU8KRM4kE7wAvb;rQ7gL&v_kEERC zO3svA(tjWGz_(47H7(CSH_uD@|CVvB7us`#F?zxQc+bnp^9FOzh8D_R_4u@9jX^%@ zuO2vN=1v8U06?SYhOT98NYAoOul;eCQcSbIa-4W)Yhkc>_ zm5yLu$wuc4FrqRiuLOF6@tFFhV&YI)Wc!mI;P;!IKl(W zu5qN1zmjo1hDbW$#=R^!UdUg?6%==HeiqT)`7vgZzmw|Wfdf9yV_c83e#+=vs&_-1 z^b%tJPWCIsAYd0T-o?1qe+}b$9B3Q?+sJr;JD~UjY%Aj{7~cRimYd-Z^*_Qm#TsBc z7$3!7g@%E~@J0c58Soo2;CE!eAIN||kpX`x1O9FX{A0iiAX3(I;8Okrr+=M+KNsdzPyQd60WZ&h zr)?>CHNEknt>CHiI=<7pSU(D!I=fER42=BZkM-m8XY%$YxB@|@88v(H{My*gAq zdCHvWA$e0I)BW*o*Uza-Ms){X-vLl}h`L=$%UdjTE1mB?8=@9*bH358Zq{khd{d6e z8TwvBik^u#d(B&W-7ZnnZXN0yJ<0D0l0dh6jmFJiP7Iuet&@R10sj7}em>~v@mw!) zwO(P)SI=*1{#DG6)8It-)A(k_rJSD{{P=98=KmGrQohRTxHm|b|2gwZ`6s~q!-D*# z{BewUlZi*e^UBob2~{gCF;BTA%M5{QV95ZiD|c1K(@#dBVW4-!C~2>^J0$ zHTYjO;u&qza(5p>szWEIUH|2B*Jk0bV14lV}U;dea zn{uc_sMCI{V?HkeQ1F0qbSW`#Q%*qO_1s{Xfuo#G#?LTtQ%q*K6S3d{SCLa`bih83wMeb+L(;+vUKKUe;h5?>AsUdVB9Fm!&^axTG51eAz6 zB<%mHa&%uUJI@BS_{}DU#Qh}e(@~;&5Ypf^UpTMH^d5q=Us^BE;H3suVMOGfp29wFA01s59I3tpUC+88So7N&;qDALUiV|se#>HhozFCWl=+?${C_|OC~pZI9;BwC^R1S%Q^6MAm%<`( zo8w61xaY%in!wkw{HX#zh4q=A0Y6XRT7HwjPiHx+1ipv;yiwr4S87_f3jAY^w;u}p zN|v)n-~-vNeFDFq^T102*Zbh#34Ad3`;ox)^~~o2*VlC()=T^UFC71c0>6pzfWQy4 zA4UrN4c1>@zi9arS&tcle>n433taycMOfh1vEQNs$M==6TqN*IczibrJdfk@MuF@5 zwYLi#f3FP7PXzuB%YRhhpRm2p2%I(-Am=rKe~TuIC%) zb`)Wu)HPke2&`>1m4X3ej@N? z%x|-ww4MRx%MAMB)W_=zIcwhEIr@*%>^{wXwuIKGr0$;)W9|-)<+W!K7hW*x??bd$7-}1w9 zvcPq|Jzd~G;W(Tw@X?Gf5cnnR&y@n#`&ylkwLUMi{+)vVW|q?>aD6{ce<7shtYrQZ zSTBv^ubpCCGam; z{y73a!2Ih4{-83~x<=qHF@1}`i#ZSM6}X@Cz9#v%vMf_S*uV#QNVT@O`Y$c7bnZ|KB6(E0zbm| zcLc8YJ+}$`6z=z4fzM?99}@VB?9X2c`~voa&J$QY1pYo{`CWql+Z+!c3w#OtUC$>i z=RWqE-d||El=+Lee~ou>oRkVYoB7KG9%A|91&%*5iv=D9p`zvIv40i|T;H#+5qP6& zZnX;hToedpoxpps-!=<;AM@WN@K2Q(>kfgBWk2r{crUi==K|OB{8s{>!1LmDf&YW) zg91O5{rne!>+9sN1^zph?_;ODbH_XvCu_q$KvOL%-=6!-zw=N*AB zX1^U4csu)l2;YFy<8m^OSGmAXXE_rDuGjCG0$;-8xJ2NSInP`uaCp>=N{7JX%zvf8 z^?Z0(;2YU*zZCd|jK3^!z3=K0_n6Q8yFug@Us|SDDaI+tQ8aZMLItVyh{5`;NRl$ z+9&Ya*sc!+Uc-()D)5(B&tiYNz078f5O|RF4+{Juo_9?G|D5Atv%p8NoO=ZBV|_XW zego&LXBkJgV3+He|2@I~829^;f#W?AeSiOmz&TA>p9}fBS-yiGJj8eiz+W}|VeuO{ z%0HP_*Mfq{dTi~ zqnuZnf1AL6!}y(yYyaTyr(?O#;12+;^Im5L{%11qzajWXv;4mq{HVXaANQ5uuYx)( zMf|9(_H!4Z@LjNhqrLiiXNbW6#QY~2IQFaOOND`>oPIpMrwP1}@o@%@a>jAo&S6~p z^Gfb_aR$6S1Aa*c{3d~~W%;`eoKr2;JYnGI`iGeR1;({M@xMF4@|NHa5NcU}5&T_@ zJNQv&ZLi)Bdq8~g#_)%dv?_-h3} zrwc1?;1nmkkGfdMS%J=m@?V0#i%`qD)xdFl*RdaN7r1`6=LZIk{px&jzk#Ei+gZ*} z1-_l}hYcL%jNx@;zrgEwp1x$@C|`f?_L{&SVfpVcjwHHZ7yIE*2He{hn4n1h-Wl-W z0>7H&Pd9LkH-@dn29DUxTu~$Ndl_#P_`8f>%(#xvgB+h%34Z+?;H`qc3;M>g)49DGj!%P$13@Bi;-T>Dw;`J%xefcB@N5Gd~$ILiMg z%YR?sUoif$kniK`sZTTDefYsIt&ip(oB=;w;OalAw5+*|>v6&NR*uyN7&wlLo{w7$9OdYJ$hQSPg6030fukI~zTeKc_RqQO&&Leh z%&X5EIEr4y{09VnJ>wrTuKo5D$MfF={|@HQ=?6lgX#OsuV83MGXs>=wr9|Mf+1^10 zj`mLA>-3Wh9Ocw9|0x0wGd_lK?Vq2qo)a_RONE>kmUEuKFJ!z%$hn{8w;B9HK+olz z|JMqB{hZpbuq?)Npp-^uvLg1-y;!150R z$8qn={9g*Z7vnCzIg4tbp7=|?Sb8yz`UK!_68vEqVBjc!3iA&Z_$0=M3Hi@4USaSD zK+a6~!!pspQT}4)pDgeNjGry!f6VwYfxpanO$Pj8A-|saHwe6r@vDTKgN%RI;2#3| zujV{_kHGc!%?}9tLtcD-F7V%@bD%sc@P5pHNZ^&c?i>}k{yx4BzGM$Y$J=GRFC8iH z8`!RSjO#ej&yzJ7{5W2EeQXi9e%@}Cz_+vfwF1A1@f#S|{Z8g}VS5IAkC3CE!+b>G zKV|v*1pYYV`vv|B#t$$q^*NXUKbise4kGs__vhNKQh}GUy%P-_hn!(+k%8moVXKN=?#}Lx~U$JBlA}N;u!PPuj)J>6rmM$9|88zePwuIZ+*w z_Wgy1?f!K1<;Gx$XG^4>NzY!1a2) zOyK%??(+q{mgUq6d?VwH0>6&&7J=W!cue3wW_-24^?I~U;LkGu27$lA_>}^Ghw&`} z|A_JH1pW`kZxpz`F1U?xWWzYuCBP?$nfMriYrdesE15n|;QGGhdVzN`eW$?nzI4C9 zJK3%-fp;+b=rviO=7_~k7)CSvN?sL$X>CBtP2{87p>{MjR`tR^0}%3`fZAbUkw1(3)@ z2%MF{ub#qhBc_9zgx?`;fFGTzZv}C59Qa$KX75(#Y*`n~44JvXK0b9x+cN&dVU2 zsWO818JgBd4hv1vJJ%@l-))cU5X#hfUJKU!Z`S}Hb^rQ^c^%JX|6Q!Vo<~|tK%elj z5{^CjZ`VS_5HS3QVljvw|d`)>kF zbU_XEbCMg(MZ5>zI>37Bf5j3KW9=?GCh_hMiq@1_jxC!M0& z|N0x+Zv?iU^e?$ewddP2blHrL_DKD|2bk0eTjsFcqmVF)bdp3~IvNBWBc#&!St_y*uTwXd0?8uaG=xp~r7-TqL9_VH<|#W3BFkGh>c{)O8M zHftNVm$+`HaSs592{o-9+&&;GwEuK_8yffI|Gk?Pht419e~e|_UdMG$ePhecv+>ii r^z|aH6GP!ow#Um@F~tCZGDjUI3;nS_v*2SRJ+-gm4WeH(5Tx}#UCeX& diff --git a/developer/authored/example_TM_0.py b/developer/authored/example_TM_0.py new file mode 100755 index 0000000..46b06c5 --- /dev/null +++ b/developer/authored/example_TM_0.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +import sys +from TM import TM ,Topology + +def CLI(): + print("--- TM Happy Path (example_TM_0) ---") + + # 1. Initialization + # --------------------------------------------------------- + print("\n[1] Initialization") + data_list = [10 ,20 ,30 ,40 ,50] + tm_0 = TM(data_list) + print(f"Created TM with: {data_list}") + print(f"Address: {tm_0.address()} (Should be 0)") + print(f"Length: {tm_0.len()} (Should be 5)") + + # 2. Read / Step / Write + # --------------------------------------------------------- + print("\n[2] Movement and IO") + + # Read current (0) + val = tm_0.r() + print(f"r(): {val} (Exp: 10)") + + # Step 1, Read + tm_0.s() + print(f"s() -> r(): {tm_0.r()} (Exp: 20)") + + # Write + tm_0.w(99) + print(f"w(99) -> r(): {tm_0.r()} (Exp: 99)") + + # Step N + tm_0.sn(2) + print(f"sn(2) -> r(): {tm_0.r()} (Exp: 40)") # 0->1->3 (Indices: 0, 1, 2, 3) + + # Step Left + tm_0.ls() + print(f"ls() -> r(): {tm_0.r()} (Exp: 30)") + + # Bulk Write (wn) + # Current head is at index 2 (val 30) + # Write [33, 44] -> overwrites 30, 40 + tm_0.wn([33 ,44]) + print("wn([33 ,44])") + + # Bulk Read (rn) + read_back = tm_0.rn(2) + print(f"rn(2): {read_back} (Exp: [33, 44])") + + # 3. Allocation + # --------------------------------------------------------- + print("\n[3] Allocation") + + # Append Right (aR) + tm_0.aR(60) + print(f"aR(60) -> len: {tm_0.len()} (Exp: 6)") + + # Append Left (aL) + # Head is at index 2. + # aL inserts at 0. Indices shift right. + # Head should increment to 3 to stay on '33'. + print(f"Pre-aL Head: {tm_0.address()}") + tm_0.aL(0) + print(f"aL(0) -> Head: {tm_0.address()} (Exp: 3)") + print(f"Value at Head: {tm_0.r()} (Exp: 33)") + + # Check 0 index + tm_0.lsn(3) # Go to 0 + print(f"Value at 0: {tm_0.r()} (Exp: 0)") + + # 4. Deletion + # --------------------------------------------------------- + print("\n[4] Deletion") + + # Current Tape: [0, 10, 99, 33, 44, 50, 60] + # Head at 0. + + # esd (Delete Neighbor -> 10) + tm_0.esd() + print(f"esd() -> Tape[1] should be 99. r(2): {tm_0.rn(2)} (Exp: [0, 99])") + + # d (Delete Current -> 0) + tm_0.d() + # Head stays at 0, which is now 99 + print(f"d() -> Current: {tm_0.r()} (Exp: 99)") + + # 5. Cloning (Entanglement) + # --------------------------------------------------------- + print("\n[5] Cloning") + tm_clone = tm_0.e() + print("Created tm_clone from tm_0") + + # Modify tm_0, check tm_clone + tm_0.w(999) + print(f"tm_0.w(999)") + print(f"tm_clone.r(): {tm_clone.r()} (Exp: 999)") + + print("\n--- end of examples ---") + +if __name__ == "__main__": + CLI() + + diff --git a/developer/authored/example_TM_1.py b/developer/authored/example_TM_1.py new file mode 100755 index 0000000..73795d2 --- /dev/null +++ b/developer/authored/example_TM_1.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +import sys +from TM import TM + +def CLI(): + print("--- TM Edge Cases (example_TM_1) ---") + + # 1. Entanglement Violation (Safety Check) + # --------------------------------------------------------- + print("\n[1] Entanglement Violation (Peer on Victim)") + + t1 = TM(['A' ,'B' ,'C']) + t2 = t1.e() # Entangled Clone + + # Setup: + # t1 at 0 ('A') + # t2 moves to 1 ('B') + t2.s() + print(f"Setup: t1@{t1.address()}, t2@{t2.address()}") + + print("Action: t1.esd() -> Tries to delete 'B'") + print("Expect: RuntimeError (Entanglement Violation)") + + try: + t1.esd() + print("!! FAILED: Operation succeeded (Should have failed)") + except RuntimeError as e: + print(f">> CAUGHT EXPECTED ERROR: {e}") + + # 2. Entanglement Violation (Peer on Current) + # --------------------------------------------------------- + print("\n[2] Entanglement Violation (Peer on Current)") + + # t1 at 0. t2 at 1. + # Move t2 back to 0. Both at 0. + t2.ls() + print(f"Setup: t1@{t1.address()}, t2@{t2.address()}") + + print("Action: t1.d() -> Tries to delete 'A'") + print("Expect: RuntimeError") + + try: + t1.d() + print("!! FAILED: Operation succeeded") + except RuntimeError as e: + print(f">> CAUGHT EXPECTED ERROR: {e}") + + # 3. Safe Deletion (No Peer Collision) + # --------------------------------------------------------- + print("\n[3] Safe Deletion (Peer Safe)") + + # t1 at 0 ('A'), t2 at 0 ('A'). + # Move t2 to 2 ('C'). + t2.sn(2) + print(f"Setup: t1@{t1.address()} ('A'), t2@{t2.address()} ('C')") + + # t1 deletes 'B' (neighbor). 'B' is at index 1. + # t2 is at index 2. Safe? + # Yes. t2 is not ON the cell being deleted. + # Note: t2's data will shift left index-wise, but Entanglement check + # only cares if t2 is *on* the deleted cell. + + print("Action: t1.esd() -> Delete 'B'") + t1.esd() + print(">> Success (Operation Permitted)") + print(f"Tape is now: {t1.rn(2)}") + + # 4. Map Input (Materialization) + # --------------------------------------------------------- + print("\n[4] Map Input") + data_map = {'key1': 1 , 'key2': 2} + tm_map = TM(data_map) + print(f"TM from Map keys: {tm_map.rn(2)}") + + print("\n--- Finished ---") + +if __name__ == "__main__": + CLI() + diff --git a/developer/deprecated/TM.c b/developer/deprecated/TM.c new file mode 100644 index 0000000..0d20274 --- /dev/null +++ b/developer/deprecated/TM.c @@ -0,0 +1,114 @@ +/* + TM First Order Machine - C Implementation + RT Code Format Compliant +*/ + +/* ========================================================= */ +/* INTERFACE */ +/* ========================================================= */ +#ifdef FACE +#include +#include +#include + +/* Opaque Handle */ +typedef struct TM TM; + +/* Constructor / Destructor */ +TM* TM_new(int size ,int* initial_data); +void TM_free(TM* tm); + +/* Core Operations */ +int TM_r(TM* tm); +void TM_rn(TM* tm ,int n ,int* buffer); + +void TM_w(TM* tm ,int v); +void TM_wn(TM* tm ,int n ,int* v); + +void TM_s(TM* tm); +void TM_sn(TM* tm ,int n); + +void TM_ls(TM* tm); +void TM_lsn(TM* tm ,int n); + +int TM_head(TM* tm); +int TM_len(TM* tm); + +#endif + +/* ========================================================= */ +/* IMPLEMENTATION */ +/* ========================================================= */ +#ifdef IMPL + +struct TM { + int* tape; + int size; + int head; +}; + +TM* TM_new(int size ,int* initial_data){ + TM* tm = malloc(sizeof(TM)); + if( !tm ) return NULL; + + tm->tape = calloc(size ,sizeof(int)); + tm->size = size; + tm->head = 0; + + if( initial_data ){ + memcpy(tm->tape ,initial_data ,size * sizeof(int)); + } + + return tm; +} + +void TM_free(TM* tm){ + if( tm ){ + if( tm->tape ) free(tm->tape); + free(tm); + } +} + +int TM_r(TM* tm){ + /* Unchecked read for speed */ + return tm->tape[tm->head]; +} + +void TM_rn(TM* tm ,int n ,int* buffer){ + /* Bulk copy (memcpy) */ + memcpy(buffer ,tm->tape + tm->head ,n * sizeof(int)); +} + +void TM_w(TM* tm ,int v){ + tm->tape[tm->head] = v; +} + +void TM_wn(TM* tm ,int n ,int* v){ + memcpy(tm->tape + tm->head ,v ,n * sizeof(int)); +} + +void TM_s(TM* tm){ + tm->head++; +} + +void TM_sn(TM* tm ,int n){ + tm->head += n; +} + +void TM_ls(TM* tm){ + tm->head--; +} + +void TM_lsn(TM* tm ,int n){ + tm->head -= n; +} + +int TM_head(TM* tm){ + return tm->head; +} + +int TM_len(TM* tm){ + return tm->size; +} + +#endif diff --git a/developer/deprecated/TapeMachine.py b/developer/deprecated/TapeMachine.py new file mode 100644 index 0000000..187b283 --- /dev/null +++ b/developer/deprecated/TapeMachine.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +import copy + +class TapeMachine: + """ + TTCA Tape Machine Implementation. + Adapts List, Map, and Set to a common Tape Interface. + """ + def __init__(self, tape_ref, path=None, point=0, iterator=None): + self.tape = tape_ref # The 'Memory' (Shared) + self.path = path or [] # The 'Stack' (Hierarchy context) + + # 'point' is the Address. + # For Lists: Integer Index + # For Maps: Key (Symbol) + # For Sets: The Item itself + self.point = point + + # For Maps/Sets, we need an iterator to support 'Step' (s) + self._iter = iterator + + # --- (e) Entangle --- + def e(self): + """ + Entangled Copy. + Returns a new head sharing the same tape memory. + """ + # We must clone the iterator state if possible, + # though Python iterators are hard to clone. + # We usually restart iteration or assume random access. + return TapeMachine(self.tape, self.path, self.point) + + # --- (r) Read --- + def r(self): + """Reads the cell under the head.""" + container = self._resolve_container() + + if isinstance(container, list): + if 0 <= self.point < len(container): + return container[self.point] + + elif isinstance(container, dict): + return container.get(self.point, None) + + elif isinstance(container, set): + # In a set, if we are 'at' a point, the value IS the point. + # But we must verify it still exists. + return self.point if self.point in container else None + + return None + + # --- (w) Write --- + def w(self, value): + """Writes to the cell under the head.""" + container = self._resolve_container() + + if isinstance(container, list): + container[self.point] = value + + elif isinstance(container, dict): + container[self.point] = value + + elif isinstance(container, set): + raise TypeError("Cannot 'Write' to a Set cell. Use 'd' (Delete) and 'a' (Add).") + + # --- (s) Step --- + def s(self, direction=1): + """ + Move relative to current position. + Direction +1 = Next, -1 = Previous. + """ + container = self._resolve_container() + + if isinstance(container, list): + self.point += direction + + elif isinstance(container, (dict, set)): + # Maps/Sets require iteration to step. + # This is expensive (O(N)) unless we maintain an active iterator. + # Simplified Logic: + try: + # In a real engine, we'd cache the list of keys + keys = list(container.keys()) if isinstance(container, dict) else list(container) + + # Find current index + try: + current_idx = keys.index(self.point) + next_idx = current_idx + direction + if 0 <= next_idx < len(keys): + self.point = keys[next_idx] + except ValueError: + # Current point no longer in set/map, reset to start + if keys: self.point = keys[0] + except: + pass + return self + + # --- (m) Move --- + def m(self, address): + """ + Absolute jump to an address. + List: index (int), Map: key (symbol), Set: member (symbol). + """ + self.point = address + return self + + # --- (a) Allocate / Add --- + def a(self, value, key=None): + """ + Appends or Inserts. + List: Append value. + Map: Insert key:value. + Set: Add value. + """ + container = self._resolve_container() + + if isinstance(container, list): + container.append(value) + + elif isinstance(container, dict): + if key is None: raise ValueError("Map allocation requires key") + container[key] = value + + elif isinstance(container, set): + container.add(value) + + # --- Hierarchy Navigation (Enter/Exit) --- + def enter(self): + """Descends into the current cell.""" + current_val = self.r() + + # Valid container? + if isinstance(current_val, (list, dict, set)): + # Push context + new_path = self.path + [(self._resolve_container(), self.point)] + + # Determine starting point for new container + start_point = 0 + if isinstance(current_val, (dict, set)) and len(current_val) > 0: + # Start at the first key/member + start_point = next(iter(current_val)) + + return TapeMachine(self.tape, new_path, start_point) + return None + + def exit(self): + """Ascends to parent.""" + if not self.path: return None + + # Pop context + parent_container, parent_point = self.path[-1] + new_path = self.path[:-1] + + return TapeMachine(self.tape, new_path, parent_point) + + # --- Internal --- + def _resolve_container(self): + """Drills down the path stack to find current container.""" + curr = self.tape + for container, index in self.path: + if isinstance(container, list): curr = container[index] + elif isinstance(container, dict): curr = container[index] + # Set traversal in path stack implies we 'entered' a member + # (which must be a container itself) + return curr diff --git a/developer/deprecated/build.sh b/developer/deprecated/build.sh new file mode 100755 index 0000000..f3e4e28 --- /dev/null +++ b/developer/deprecated/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Compile with FACE and IMPL defined to generate the full library +gcc -shared -fPIC -o libTM.so -D FACE -D IMPL TM.c + +echo "Built libTM.so" diff --git a/developer/deprecated2/Binder.py b/developer/deprecated2/Binder.py new file mode 100755 index 0000000..31a483c --- /dev/null +++ b/developer/deprecated2/Binder.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +import weakref +# Assuming SymbolSpace is in the same package or path +from SymbolSpace import SymbolSpace + +class Binder: + """ + Maps transient Runtime Objects to persistent Epimetheus Symbols. + """ + + def __init__(self): + # Weak Key: If the Object dies, this entry disappears automatically. + # Value: The Symbol (Strong reference). + self._obj_to_sym = weakref.WeakKeyDictionary() + + def get_symbol(self ,obj) -> SymbolSpace.Instance: + """ + Returns the symbol for the object. + If none exists, mints a new one and binds it. + """ + # Check if we already know this object + if obj in self._obj_to_sym: + return self._obj_to_sym[obj] + + # Mint new identity + sym = SymbolSpace.alloc() + self._obj_to_sym[obj] = sym + + return sym + + def lookup(self ,obj) -> SymbolSpace.Instance: + """ + Non-allocating lookup. Returns None if object is unknown. + """ + return self._obj_to_sym.get(obj ,None) + +# --- Work & CLI --- + +def verify_binder(): + print("--- Binder Verification ---") + binder = Binder() + + # 1. Create a transient object + class Bike: pass + my_bike = Bike() + + # 2. Bind it + sym = binder.get_symbol(my_bike) + print(f"Bike is bound to: {sym}") + + # 3. Verify stability + sym2 = binder.get_symbol(my_bike) + assert sym == sym2 + print("Symbol is stable for same object.") + + # 4. Garbage Collection Test + import gc + del my_bike + gc.collect() + + # The binder should be empty now because the key is dead + # Note: The 'sym' variable still holds the integer, + # so the Concept survives even though the Implementation is gone. + print("Object deleted. Binder entry should be gone (internal check).") + print(f"Binder size: {len(binder._obj_to_sym)}") + +def CLI(): + verify_binder() + +if __name__ == "__main__": + CLI() + diff --git a/developer/deprecated2/DiscreteFunction.py b/developer/deprecated2/DiscreteFunction.py new file mode 100755 index 0000000..f11ad4d --- /dev/null +++ b/developer/deprecated2/DiscreteFunction.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +from SymbolSpace import SymbolSpace + +# ========================================== +# THE GRAPH (Discrete Function) +# ========================================== + +class DiscreteFunction: + """ + The Knowledge Store. + Supports 'Smart Postings' to Parent Symbols. + """ + def __init__(self): + self._rev = {} # reverse map: Symbol -> Set of Objects + + def _add_posting(self ,sym ,obj): + if sym not in self._rev: self._rev[sym] = set() + self._rev[sym].add(obj) + + def set(self ,obj_sym ,prop_sym): + """ + Assigns a property. Updates indexes for the specific property + AND its namespace (Parent). + """ + # 1. Index Specific (e.g., #105 'Red') + self._add_posting(prop_sym ,obj_sym) + + # 2. Index General (e.g., #50 'Color') + parent = SymbolSpace.get_parent(prop_sym) + if parent: + self._add_posting(parent ,obj_sym) + + def find(self ,sym): + """Returns the set of objects associated with this symbol.""" + return self._rev.get(sym ,set()) + +# --- Work Function --- + +def verify_graph(): + print("--- DiscreteFunction Verification ---") + # 1. Create Symbols + sym_obj = SymbolSpace.alloc() + sym_prop = SymbolSpace.alloc() + sym_parent = SymbolSpace.alloc() + + # 2. Setup Hierarchy + SymbolSpace.set_parent(sym_prop, sym_parent) + + # 3. Set Fact + df = DiscreteFunction() + df.set(sym_obj, sym_prop) + + # 4. Check Smart Posting + print(f"Finding specific property: {len(df.find(sym_prop))} (Expected 1)") + print(f"Finding parent category: {len(df.find(sym_parent))} (Expected 1)") + +def CLI(): + verify_graph() + +if __name__ == "__main__": + CLI() diff --git a/developer/deprecated2/Namespace.py b/developer/deprecated2/Namespace.py new file mode 100755 index 0000000..3958ecc --- /dev/null +++ b/developer/deprecated2/Namespace.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +from SymbolSpace import SymbolSpace +from DiscreteFunction import DiscreteFunction +from Binder import Binder +import bisect + +# --- Base Factory --- +class DifferentiatedSymbol: + def __init__(self, name): + self.root_symbol = SymbolSpace.alloc() + self._intern_map = {} + + def __call__(self, value): + if value not in self._intern_map: + sym = SymbolSpace.alloc() + self._intern_map[value] = sym + SymbolSpace.set_parent(sym, self.root_symbol) + self.on_new_symbol(value, sym) # Hook for subclasses + return self._intern_map[value] + + def on_new_symbol(self, value, sym): pass + +# --- The "Interval Tree" Upgrade --- +class OrderedNamespace(DifferentiatedSymbol): + """ + A Namespace that maintains a Sorted Index for Range Queries. + """ + def __init__(self, name): + super().__init__(name) + # Stores tuples of (Value, Symbol), sorted by Value + self._sorted_index = [] + + def on_new_symbol(self, value, sym): + # Maintain sorted order (O(N) insertion, but fast reads) + # In a real DB, this would be a B-Tree insert (O(log N)) + bisect.insort(self._sorted_index, (value, sym)) + + def find_range(self, min_val, max_val): + """ + Returns all symbols whose values fall in [min_val, max_val]. + Complexity: O(log N) to find bounds + O(K) to collect K matches. + """ + # 1. Binary Search for the start point + # We create a dummy tuple for comparison + start_idx = bisect.bisect_left(self._sorted_index, (min_val, None)) + + # 2. Binary Search for the end point + # We use a dummy symbol that is "infinite" to ensure we catch duplicates of max_val + # (or just rely on the tuple comparison logic) + end_idx = bisect.bisect_right(self._sorted_index, (max_val, object())) + + # 3. Slice and Return Symbols + results = [] + for i in range(start_idx, end_idx): + val, sym = self._sorted_index[i] + results.append(sym) + + return results + +# --- Work Function --- + +def verify_range_query(): + print("--- Range Query Verification ---") + + # 1. Setup + Weight = OrderedNamespace("Weight") + K = DiscreteFunction() # Knowledge Graph + binder = Binder() + + # 2. Objects (Bikes with different weights) + bike_light = object() # 50kg + bike_med = object() # 150kg + bike_heavy = object() # 250kg + + sym_light = binder.get_symbol(bike_light) + sym_med = binder.get_symbol(bike_med) + sym_heavy = binder.get_symbol(bike_heavy) + + # 3. Facts + K.set(sym_light, Weight(50)) + K.set(sym_med, Weight(150)) + K.set(sym_heavy, Weight(250)) + + # 4. Range Query: 100kg to 200kg + print("\nQuery: Find bikes between 100kg and 200kg") + + # Step A: Expansion (Ask Namespace) + target_symbols = Weight.find_range(100, 200) + print(f" -> Namespace found {len(target_symbols)} relevant symbols.") + + # Step B: Intersection (Ask Graph) + found_objects = [] + for sym in target_symbols: + # Use the Reverse Map + objs = K.find(sym) + found_objects.extend(objs) + + print(f" -> Graph found {len(found_objects)} objects.") + + # Verification + # Should find only the medium bike + assert sym_med in found_objects + assert sym_light not in found_objects + assert sym_heavy not in found_objects + print(" -> SUCCESS: Only the 150kg bike was returned.") + +def CLI(): + verify_range_query() + +if __name__ == "__main__": + CLI() diff --git a/developer/deprecated2/SymbolSpace.py b/developer/deprecated2/SymbolSpace.py new file mode 100755 index 0000000..e363e3e --- /dev/null +++ b/developer/deprecated2/SymbolSpace.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +from collections import deque as FIFO + +class SymbolSpace: + """ + The manager of the Epimetheus integer namespace. + """ + + _counter = 0 + _dealloc_queue = FIFO() + + # HIERARCHY SUPPORT (Added) + _parents = {} # Map: Child_Sym -> Parent_Sym + + class Instance: + """The handle for a symbol.""" + __slots__ = ('_value' ,) + + def __init__(self ,value): + self._value = value + + def __eq__(self ,other): + # Compare value, not identity + if isinstance(other ,SymbolSpace.Instance): return self._value == other._value + return False + + def __hash__(self): + return hash(self._value) + + def __repr__(self): + return f"" + + @classmethod + def alloc(cls) -> 'SymbolSpace.Instance': + val = 0 + if cls._dealloc_queue: + val = cls._dealloc_queue.popleft() + else: + cls._counter += 1 + val = cls._counter + return cls.Instance(val) + + @classmethod + def dealloc(cls ,sym: 'SymbolSpace.Instance'): + val = sym._value + if val == 0: raise ValueError("Null symbol (0) cannot be deallocated.") + + if val == cls._counter: + cls._counter -= 1 + while cls._counter > 0 and cls._counter in cls._dealloc_queue: + cls._dealloc_queue.remove(cls._counter) + cls._counter -= 1 + else: + cls._dealloc_queue.append(val) + + @classmethod + def get_null(cls) -> 'SymbolSpace.Instance': + return cls.Instance(0) + + # --- Hierarchy Methods --- + + @classmethod + def set_parent(cls ,child ,parent): + cls._parents[child] = parent + + @classmethod + def get_parent(cls ,child): + return cls._parents.get(child) + +def verify(): + print(f"Allocating 3 symbols...") + s1 = SymbolSpace.alloc() + s2 = SymbolSpace.alloc() + + # Test Hierarchy + SymbolSpace.set_parent(s2, s1) + assert SymbolSpace.get_parent(s2) == s1 + print("Hierarchy check passed.") + +def CLI(): + verify() + +if __name__ == "__main__": + CLI() diff --git a/developer/deprecated2/__init__.py b/developer/deprecated2/__init__.py new file mode 100644 index 0000000..dce65e6 --- /dev/null +++ b/developer/deprecated2/__init__.py @@ -0,0 +1,2 @@ +from .Epimetheus import Epimetheus + diff --git a/developer/deprecated2/example_queries.py b/developer/deprecated2/example_queries.py new file mode 100755 index 0000000..3801579 --- /dev/null +++ b/developer/deprecated2/example_queries.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +from SymbolSpace import SymbolSpace +from Binder import Binder +from DiscreteFunction import DiscreteFunction +from Namespace import DifferentiatedSymbol ,OrderedNamespace + +def example_queries(): + print("--- Epimetheus Architecture Example ---") + + # 1. System Initialization + binder = Binder() + graph = DiscreteFunction() + + # 2. Ontology Definition (The Factories) + Frame = DifferentiatedSymbol("FrameMaterial") + Price = OrderedNamespace("Price") + + # 3. Data Ingestion (Transient Objects) + data_source = [ + ("Bike_A" ,"Carbon" ,3500), + ("Bike_B" ,"Steel" ,800), + ("Bike_C" ,"Alum" ,1200), + ("Bike_D" ,"Carbon" ,1500), + ] + + print(f"Ingesting {len(data_source)} items...") + + # Keep references to prevent GC during ingestion for this example + start_objects = [] + + for label, material, cost in data_source: + # A. Create the Python Object + obj = type("Bike", (), {"label": label})() + start_objects.append(obj) + + # B. Bind: Object -> Symbol + sym_bike = binder.get_symbol(obj) + + # C. Describe: Symbol -> Properties + graph.set(sym_bike ,Frame(material)) + graph.set(sym_bike ,Price(cost)) + + # --------------------------------------------------------- + # Example 1: Exact Query ("Find Carbon Frames") + # --------------------------------------------------------- + print("\n[Example 1] Exact Match: Frame('Carbon')") + + # We ask the Factory for the symbol representing 'Carbon' + sym_carbon = Frame("Carbon") + + # We ask the Graph for entities with that symbol + results = graph.find(sym_carbon) + print(f" -> Found {len(results)} bikes with Carbon frames.") + + # --------------------------------------------------------- + # Example 2: Range Query ("Find Price 1000..2000") + # --------------------------------------------------------- + print("\n[Example 2] Range Match: Price(1000..2000)") + + # Step A: Ask Namespace for symbols in range + # The OrderedNamespace uses bisect to find symbols efficiently + price_symbols = Price.find_range(1000 ,2000) + print(f" -> Namespace identified {len(price_symbols)} relevant price points.") + + # Step B: Ask Graph for objects having ANY of those symbols + matches = set() + for p_sym in price_symbols: + found = graph.find(p_sym) + matches.update(found) + + print(f" -> Graph resolved {len(matches)} bikes in price range.") + + # --------------------------------------------------------- + # Example 3: Hierarchy Query ("Find Priced Things") + # --------------------------------------------------------- + print("\n[Example 3] Hierarchy Match: Has Price") + + # We query the Root Symbol of the Price namespace. + # This works because the Graph automatically 'posts' up to the parent. + # FIXED: Changed .root to .root_symbol to match Namespace.py + all_priced = graph.find(Price.root_symbol) + print(f" -> Found {len(all_priced)} objects that have a price.") + +def CLI(): + example_queries() + +if __name__ == "__main__": + CLI() diff --git a/document/Epimetheus.html b/document/Epimetheus.html index 85ee1ad..8578b1d 100644 --- a/document/Epimetheus.html +++ b/document/Epimetheus.html @@ -2,7 +2,7 @@ - Epimetheus: The Only Primitive + Epimetheus @@ -15,7 +15,7 @@ + title="Epimetheus"> @@ -36,7 +36,7 @@

- Epimetheus (Afterthought) rejects this. It allows you to attach meaning (semantics) to objects after they are born. You can decide later that an object behaves like a number, or a string, or a user. + Epimetheus (Afterthought) is a different approach. It allows you to attach meaning (semantics) to objects after they are born. This is done in the form of properties that can be given arbitrary values, including test code.

@@ -52,7 +52,7 @@

- Thus the Symbol (the unique, persistent identity) is the most primitive data entity. Given Symbols, and a Turing Machine for building structure, everything else follows. But this is not an article about constructing mathematics or computer science, rather it is about a type system, so lets not get too carried away with the grand strokes of the pen. + Thus the Symbol (the unique, persistent identity) is the most primitive data entity. Given Symbols, and a Turing Machine for building structure, everything else follows. Here are "Turing Machine" will be Python code.

Assumptions and Terms

@@ -81,11 +81,11 @@

- In the Python version of Epimetheus symbols are indeed implemented over integers. However, Python integers are non-primitive and thus are passed by reference. The Python Epimetheus symbol instance factory will return a reference to an integer, not the base integer, as the symbol instance. Assignment will then copy the reference. Thus this reference is the symbol instance rather than the integer the symbol is based on. + In the Python version of Epimetheus symbols are indeed implemented over integers. However, Python integers are non-primitive and thus are passed by reference. The Python Epimetheus symbol instance factory will return a reference to an integer, not the base integer, as the symbol instance. Assignment will then copy the reference. So we end up with references to symbol instances, though these references are transparent, so we will call them symbol instances. Close enough, as they say.

- In Epimetheus, we use a dictionary to give a symbol a name. The names need not meet the requirements imposed on a symbol instance, but it can be confusing when they don't. This is avoided in other symbol systems by implementing symbols over character strings, and using the character string as both the name and the instance. + In Epimetheus, we use a dictionary to give a symbol a name. The names need not meet the requirements imposed on a symbols, but it can be confusing when they don't. Other implementations avoid this issue by using strings as the basis for symbols, though this approach causes some other problems, such as creating the requirement that all symbols must have names, and requiring the user make names that follow the requirements of a symbol instances. It is not uncommon to find in such implementations users meeting these requirements by writing programs to create names for symbols.

Required Properties

@@ -153,7 +153,7 @@

A symbol is associated with an object using a Python dictionary. The symbol is the key, and the object is that thing which is "looked up" via said key. - One such example is the symbol name dictionary mentioned in the prior section. + An example of such a dictionary is the symbol name dictionary mentioned in the prior section.

Tape

@@ -198,7 +198,7 @@

- The reader might have expected the path to go from left to right, with the destination being in the rightmost cell. This would be natural because we read characters from a written page going from left to right. However, such a definition would run into a problem for us, as we will need for paths to always have a destination, and tapes can be open on the right, so they do not always have a rightmost cell. + The reader might have expected the path to go from left to right, with the destination instead being in the rightmost cell. This would be natural because we read characters from a written page going from left to right. However, such a definition would run into a problem for us, as we will need for paths to always have a destination, and tapes can be open on the right, so they do not always have a rightmost cell.

@@ -216,7 +216,7 @@

- Thus a function is more restricted than a tape of paths, and due to this restriction it is possible to adopt the following notation, where a destination is said to be determined by, i.e. be a function of, the way: + Thus a function is more restricted than a tape of paths, as it disallows any paths made unique solely by changing the destination. This property facilities the following notation, where a destination is said to be determined by, i.e. be a function of, the way:

@@ -224,7 +224,7 @@

- That the same way always leads to the same destination fits our common experience. If a person followed the same way twice and landed in different destinations. that person might think himself/herself to be in a Sci-Fi movie. It is also intuitive to us that the function restrictions do not exclude the possibility that multiple ways can lead to the same destination. Because we often compute things that are related to our daily experience it is not surprising that this is a very common pattern. And this is not a coincidence, this is the reason functions are defined as they are. + That the same way always leads to the same destination fits our common experience. If a person followed the same way twice and landed in different destinations, that person might think himself/herself to be in a Sci-Fi movie. It is also intuitive to us that the function restrictions do not exclude the possibility that multiple ways can lead to the same destination. Because we often compute things that are related to our intuition about the world, functions are very common. As for discreteness and intuition, that conversation goes back at least to Democritus and Aristotle.

diff --git a/document/TM_First_Order.html b/document/TM_First_Order.html new file mode 100644 index 0000000..5f4c80e --- /dev/null +++ b/document/TM_First_Order.html @@ -0,0 +1,190 @@ + + + + + TM First Order + + + + + + + + + + + + +

Introduction

+ +

+ The First Order Tape Machine (TM) is a fundamental mechanism for sequence manipulation. It is a concrete implementation of the Tape Machine abstraction defined in the TTCA. +

+ +

+ While modern programming languages offer various containers (Lists, Arrays, Vectors), the First Order TM unifies them under a single interface that emphasizes positional state. Unlike a standard iterator which consumes data, a TM persists. Unlike a raw array which is stateless, a TM maintains a head. +

+ +

Command Reference

+ +

+ The Tape Machine is controlled via a formal command language. This section defines the abstract commands available to the machine. The notation uses strictly ASCII characters. +

+ +

Grammar

+ +statement :: [direction]command+[modifier][&contract]*[arg]* +direction :: l | ε +command :: r | w | s | a | d | q | m | e | t +modifier :: L | R | A | AR | n + + +

Definitions

+ +

Direction

+
    +
  • ε (Empty): Implicit Right / Forward / Plus.
  • +
  • l: Left / Backward / Minus.
  • +
+ +

Abstract Commands

+
    +
  • r: Read the cell under the head.
  • +
  • w: Write the cell under the head.
  • +
  • s: Step the head position.
  • +
  • a: Allocate (Add/Append) a new cell.
  • +
  • d: Deallocate (Drop/Delete) a cell.
  • +
  • q: Query. Ask a question about the machine state.
  • +
  • m: Move. No allocation or deallocation; requires fill.
  • +
  • e: Entangle. Spawns a new head on the same tape.
  • +
  • t: Thread. Entangle on a new thread.
  • +
+ +

Modifiers

+
    +
  • L: Operate on Leftmost.
  • +
  • R: Operate on Rightmost.
  • +
  • A: Operate on Address (Head Index).
  • +
  • AR: Operate on Address of Rightmost (Extent).
  • +
  • n: Repeat n times (requires argument).
  • +
+ +

Contracts

+

+ Contracts assert the state of the machine before execution. +

+
    +
  • hL: Head is at Leftmost.
  • +
  • hR: Head is at Rightmost.
  • +
+ +

Examples

+ + +ls ; Step left +aL ; Allocate (create) a new leftmost cell +aR ; Allocate (append) to rightmost +qA ; Query Address (What is the head index?) +qAR ; Query Extent (What is the max index?) + + +

Primitive Method Reference

+ +

+ This section details the actual methods exposed by the First Order TM implementation (Python/C). These primitives map directly to the command language or provide optimized compound operations. +

+ +

Navigation Primitives

+
    +
  • s(): Step Right.
  • +
  • sn(n): Step Right n times.
  • +
  • ls(): Step Left.
  • +
  • lsn(n): Step Left n times.
  • +
+ +

I/O Primitives

+
    +
  • r(): Read current cell.
  • +
  • rn(n): Read n cells (Bulk Read).
  • +
  • w(v): Write value to current cell.
  • +
  • wn(list): Write list of values (Bulk Write).
  • +
+ +

Allocation Primitives

+
    +
  • aL(v): Allocate Left (Prepend).
  • +
  • aR(v): Allocate Right (Append).
  • +
+ +

Deletion Primitives

+
    +
  • d(): Delete current cell.
  • +
  • dn(n): Delete n cells starting at current.
  • +
+ +

Compound Primitives

+

+ These methods combine multiple abstract commands into a single atomic C-operation for performance and safety. +

+
    +
  • esd(): Entangle-Step-Delete. Equivalent to esd. Safely deletes the cell to the right of the head (the "neighbor").
  • +
  • esdn(n): Delete n right neighbors.
  • +
+ +

Query Primitives

+

+ Introspection commands used to check machine state without side effects. +

+
    +
  • qA(): Query Address. Return the current head index.
  • +
  • qR(): Query Rightmost. Returns True if the head is at the rightmost cell.
  • +
  • qL(): Query Leftmost. Returns True if the head is at the leftmost cell (index 0).
  • +
  • qAR(): Query Address Rightmost (Extent). Returns the index of the rightmost cell (Length - 1). This ensures the return value always fits within the address space, unlike Length which is one greater than the maximum index.
  • +
+ +

Entanglement Primitives

+
    +
  • e(): Entangle. Creates a new machine instance sharing the same tape and safety catalog. The new machine's head is initialized to the same position as the original machine.
  • +
+ +

Architecture

+ +

The Hybrid Model

+

+ For maximum performance in high-frequency loops, the First Order TM is implemented using a Direct Execution architecture. +

+ +
    +
  • Inner Loop (C-Extension): The core operations—reading, stepping, and writing—are implemented in C. This code directly manipulates the memory pointers of the underlying Python List, avoiding interpreter overhead.
  • +
  • Outer Loop (Python Wrapper): The Python layer handles initialization and interface compliance.
  • +
+ +

Entanglement Safety

+

+ A critical feature of the TM is Entanglement. Multiple TMs can operate on the same underlying tape memory simultaneously. This is efficient, but dangerous: if one machine deletes a cell that another machine is looking at, the system could crash or corrupt state. +

+ +

+ To prevent this, the TM implements an Entanglement Catalog in the C layer. +

+ + + \text{Safe}(op) \iff \forall \text{peer} \in \text{Catalog}, \text{Head}(\text{peer}) \notin \text{VictimRange}(op) + + +

+ Before any destructive operation (like delete), the machine checks the catalog. If any peer's head is currently positioned on a cell scheduled for deletion, the operation is blocked with a RuntimeError. +

+ + + +
+ + diff --git a/document/TM_first_order.html b/document/TM_first_order.html new file mode 100644 index 0000000..6706343 --- /dev/null +++ b/document/TM_first_order.html @@ -0,0 +1,150 @@ + + + + + 02 - The First Order Tape Machine + + + + + + + + + + + + +

Introduction

+ +

+ The First Order Tape Machine (TM) is the foundational mechanism for sequence manipulation. It is a concrete implementation of the Tape Machine abstraction defined in the TTCA. +

+ +

+ While modern programming languages offer various containers (Lists, Arrays, Vectors), the First Order TM unifies them under a single interface that emphasizes positional state. Unlike a standard iterator which consumes data, a TM persists. Unlike a raw array which is stateless, a TM maintains a head. +

+ +

Architecture

+ +

The Hybrid Model

+

+ For maximum performance in high-frequency loops, the First Order TM is implemented using a Direct Execution architecture. +

+ +
    +
  • Inner Loop (C-Extension): The core operations—reading, stepping, and writing—are implemented in C. This code directly manipulates the memory pointers of the underlying Python List, avoiding interpreter overhead.
  • +
  • Outer Loop (Python Wrapper): The Python layer handles initialization and interface compliance.
  • +
+ +

+ This hybrid approach allows the TM to execute simple steps like s() (step right) in nanoseconds, comparable to native pointer arithmetic in compiled languages. +

+ +

Entanglement Safety

+

+ A critical feature of the Epimetheus TM is Entanglement. Multiple TMs can operate on the same underlying tape memory simultaneously. This is efficient, but dangerous: if one machine deletes a cell that another machine is looking at, the system could crash or corrupt state. +

+ +

+ To prevent this, the TM implements an Entanglement Catalog in the C layer. +

+ + + \text{Safe}(op) \iff \forall \text{peer} \in \text{Catalog}, \text{Head}(\text{peer}) \notin \text{VictimRange}(op) + + +

+ Before any destructive operation (like delete), the machine checks the catalog. If any peer's head is currently positioned on a cell scheduled for deletion, the operation is blocked with a RuntimeError. +

+ +

Interface

+ +

Movement

+

+ The TM maintains a Head index. Movement is relative. +

+ +
    +
  • s(): Step Right (increment head).
  • +
  • sn(n): Step Right by n.
  • +
  • ls(): Step Left (decrement head).
  • +
  • lsn(n): Step Left by n.
  • +
+ +

Read / Write

+

+ Data access occurs at the current head position. +

+ + +# Read current cell +val = tm.r() + +# Bulk read next 3 cells +chunk = tm.rn(3) + +# Write to current cell +tm.w(42) + +# Bulk write (overwrite sequence) +tm.wn([10, 20, 30]) + + +

Allocation

+

+ New cells can be created at the boundaries. +

+
    +
  • aR(val): Append Right (standard append).
  • +
  • aL(val): Append Left (prepend). Note that this operation shifts the indices of all existing cells. The TM automatically adjusts its own head to maintain logical stability, but peers may experience Index Drift.
  • +
+ +

Deletion

+

+ Deletion is the only operation restricted by Entanglement Safety. +

+ +

Delete Current (d)

+

+ d() removes the cell currently under the head. After deletion, the head index remains unchanged, but it now points to the next cell in the sequence (the one that shifted into the slot). +

+ +

Delete Neighbor (esd)

+

+ esd() (Entangle, Step, Delete) removes the cell immediately to the right of the head. This is the primitive operation for Singly Linked Tapes, but is offered on the First Order TM for symmetry. +

+ +

Implementation Detail

+ +

The C Module

+

+ The C module TM_module.c defines the FastTM struct. +

+ + +typedef struct { + PyObject_HEAD + PyObject* tape_obj; /* Shared Python List */ + PyObject* peer_list; /* Shared WeakRef List */ + Py_ssize_t head; /* C-Level Integer */ + PyObject* weakreflist; /* Garbage Collection Support */ +} FastTM; + + +

+ By keeping the head as a native C integer Py_ssize_t, arithmetic operations avoid the boxing/unboxing cost of Python Integers. +

+ + + +
+ + -- 2.20.1