From 1dff8a2f0f8dae311ae15ca8fa2596b737450ba6 Mon Sep 17 00:00:00 2001 From: Stephane Glondu Date: Wed, 10 Jul 2019 14:50:03 +0200 Subject: [PATCH] New upstream version 4.07.1 --- Changes | 33 ++ VERSION | 2 +- boot/ocamlc | Bin 2290614 -> 2291338 bytes boot/ocamllex | Bin 305599 -> 305599 bytes bytecomp/translcore.ml | 3 +- byterun/freelist.c | 2 +- stdlib/array.ml | 2 +- testsuite/tests/lib-seq/test.ml | 9 + testsuite/tests/typing-gadts/gpr1997.ml | 53 +++ testsuite/tests/typing-gadts/ocamltests | 1 + testsuite/tests/typing-gadts/pr7222.ml | 3 +- testsuite/tests/typing-misc/variant.ml | 16 + testsuite/tests/typing-modules/ocamltests | 1 + testsuite/tests/typing-modules/pr7818.ml | 319 ++++++++++++++++++ testsuite/tests/typing-objects/Tests.ml | 30 ++ .../tests/typing-polyvariants-bugs/ocamltests | 1 + .../tests/typing-polyvariants-bugs/pr7824.ml | 78 +++++ typing/ctype.ml | 91 ++--- typing/ctype.mli | 2 +- typing/datarepr.ml | 3 +- typing/env.ml | 5 +- typing/mtype.ml | 50 ++- typing/mtype.mli | 4 +- typing/predef.ml | 3 +- typing/printtyp.ml | 3 +- typing/subst.ml | 3 +- typing/typeclass.ml | 9 +- typing/typecore.ml | 81 ++--- typing/typedecl.ml | 12 +- typing/typemod.ml | 20 +- typing/types.ml | 3 +- typing/types.mli | 4 +- utils/config.mlp | 4 +- 33 files changed, 705 insertions(+), 145 deletions(-) create mode 100644 testsuite/tests/typing-gadts/gpr1997.ml create mode 100644 testsuite/tests/typing-modules/pr7818.ml create mode 100644 testsuite/tests/typing-polyvariants-bugs/pr7824.ml diff --git a/Changes b/Changes index 25976617..584fa9a9 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,36 @@ +OCaml 4.07.1 (4 October 2018) +----------------------------- + +### Bug fixes: + +- MPR#7815, GPR#1896: major GC crash with first-fit policy + (Stephen Dolan and Damien Doligez, report by Joris Giovannangeli) + +* MPR#7818, GPR#2051: Remove local aliases in functor argument types, + to prevent the aliasing of their target. + (Jacques Garrigue, report by mandrykin, review by Leo White) + +- MPR#7820, GPR#1897: Fix Array.of_seq. This function used to apply a circular + permutation of one cell to the right on the sequence. + (Thierry Martinez, review by Nicolás Ojeda Bär) + +- MPR#7821, GPR#1908: make sure that the compilation of extension + constructors doesn't cause the compiler to load more cmi files + (Jérémie Dimino) + +- MPR#7824, GPR#1914: subtype_row: filter out absent fields when row is closed + (Leo White and Thomas Refis, report by talex, review by Jacques Garrigue) + +- GPR#1915: rec_check.ml is too permissive for certain class declarations. + (Alban Reynaud with Gabriel Scherer, review by Jeremy Yallop) + +- MPR#7833, MPR#7835, MPR#7822, GPR#1997: Track newtype level again + (Leo White, reports by Jerome Simeon, Thomas Refis and Florian + Angeletti, review by Jacques Garrigue) + +- MPR#7838: -principal causes assertion failure in type checker + (Jacques Garrigue, report by Markus Mottl, review by Thomas Refis) + OCaml 4.07.0 (10 July 2018) --------------------------- diff --git a/VERSION b/VERSION index 6d514477..0e48c0f1 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -4.07.0 +4.07.1 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli diff --git a/boot/ocamlc b/boot/ocamlc index beac6097bd73382a6496d7dabe31d7ac75befeb3..4529ffc3bf81e7784ab0cb4fc00ee54038b7f600 100755 GIT binary patch delta 50729 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 K`=si0}~r&ajqU|U?$X=(w{|w zdAu_l+siShLSv>&P7~veaT7(EH-NQgG^^O!ABIVyW>%EVmy1kn#mgRY#`t7ct`J2H z4><=Lc#}3#u7}+a9(H!40<%+Z2}&i*QvOS0A9gbWodorc{3BHzg9}FDTP1yS?4>@7tawD4alHKex2X~}~)sn-25yF7d z@P!gjm48R-O^kj%NE;~OurraeE?R7Hyj^$@c&dGQc=kmYiSbI5`6D=68#X!vD>-!9 z;=|6@bwFgd#_eCf;!qoNHk zs-$g-wrS(Oc9sb7s&?iZXQY6Qx9~W6;&}}_Y~_F8i`u`{>5RJ$ZLz?@at@yYn5-*6 zEQ~EX*`I)EvSqr{tg*K^Zmy_D=$D7ZmW6CPDv~)7e zCms(>F0rTK>KuFA*_)1B!~td8ac34a#X9x0@;Js;zZ82%4jGJPX#=2;Kkkf$Uz&d} zpTd)GFzGA41&tJKGr;E8!>G5ibj}NhdusfLuKCv4N&HN$k{idMZ=K0t)KybmGOhg9 z*;jl-_V4(-!w^RA#vjiKr%mOpn`^U;ljnn>G1Fe=FI{p7!pW2q&fYM?RGn}p3WXAK zAd3#`VKDnhEt*;zpwxo3{Y)$j=HEHHiA{9ICwHy^CD$1OfWv=Q+h0pXrMiuYcJ2E=X>Wc5kphIcg6@0 z)xL(tawY?>eKUZ1pVU!*6(qs>??LISk2`_-tq{H7s0~EEs_47-1a$6{2Z1}qrp*}rjBwArOHvRVgCyRY)`Fyq4=*K;nG+10<>XS81`jA1VBnzMh--U(JrT0qdhU& zMYmI93?z*`b0OWf#>%9d=?=`B3nSqMDU1F7Lp1?#O1(&lQj3>cF@`bF=$(!_IG?Ypjbb+ogFD>g%% zth~c+E^FFsrtEdDzFOmZt_woU_7B7Jj?hDw+gjsVCtlD>Yh5FCG-W+{f9Y18xnjL* zikL^O?*nH=>s`~SWP{6CvB6a$UeZc8xE_om=PtD2gE5~<7fXqhx62hvIWr*U)$8Ct z|BAnrnmY_OTD=RSJo<`c)0Noh#_@JZtKa2XFJMqfe@pMU`30OGnVAPy))R<_?mUYE zvPO_cqiBc2|G83FDxiJ4UH6J)O4;K|y1E*N-O#;kHsTDCNw6CNx5QiR?dNG*N~C0( z^rZi^+u7&Yiixh><8mZCGyTdontr0pfhc{@mPBp8!T+K1V^^2{%b}&?0kBLEl=+w_)Z5Oxq`$zQ+!#;%@EJI zry0*egR=1xS1k15DR+m*yV$>Y651J$z-yc_Qbwk|u9K#b=;UuRaHuc)p-T)5>#jyu zlKr=Uwk}8r@6+%`muy-P(D}tt@f$G?D6WeeU5Ri5eTyHZ^l_tW6t1Df?Q#VK5S{1tCF|u+QZfn--7}L(%ok>?^eytLAvUEptJU^ZrF+d)e~0c0y$f9oy#` zgbgHNzsoUT3v#(}Rv>W)n9^#I#*-JCwknVoit4#k2oQ0PBP%%1JW~S^=h~5k>il}DBa%V8acpq#Or+xqVX1l zV+dyv1SIL35%Lk(FxK;!*ZUB{97y6_U}UR9a6!E`h+3Omy$nb33XkR{SG-Rr`5p~u zcKv4WdH6~i02}_)C5xwN?5D28gk(%_C>czA@yf-1oR)p+is||YgyzseooOc}??Bvd z<(WFZT~>O#`0jQBa~R^GX#V;${~X^090hT_9BE88!FYb4Ocphd2zTgvB1)b$R;T@O zSeruoc@I?$Q612s)_&%a4N1uL9dLS3$rCYH>9y;i??ecGHm*1CMhg|WlC3~-|_5$oJ(83+W_B8I0%P5A?{fAurL{F-MtAndc zz)-{9b3x2Gw2uKun99NHSZ7e9ojvRtXc3FG^zU5Z;i8<5^^p?G+HNpv6HmLw2qbJh z1CZrp|HYL=o}XPyIq7HcnsSYkB18pU|EKGKATs^sdJ?I{f4K%3OiR!}1{zS{VS^*a zm_J>yEb2~OjNCTW}wkW<2>m+{yXCJm%6dgy=tb=`VBMDF+kI{smL zDN8KXO7&8hQ7j|TUy7j`v$RLNK^V&fI%<(7qC1&ZX`KZi&&Ei1!n)0}izyh<0Z2%5gPD!z;w%Le7tngmtvuYLbTY{V9;wb zJyJKLsHCdy(gXvu_bPssslW{hzOp-pQSWvplX5kz5(V8^?b1!krlr-8UCdYG1k$Ak zGSaS=&OyV1iZPVYL%QH=#Xt>zIeSpkY$))iBug3S!P;c$Q9R;OqyuMOpm{_F&RfBXi@kVJJr3sfF*B)EL;H6uC zqcoZ(4n%L$21>nQf4+a9^qKBG8(s69!A+I#*o_9>HrH|KcsSA&XGp2IGgg}+^$`E{ zC%*54#4FIZ%dMw`OkjNjmw_|b)lqu!fxoRI2Otwy3YXEK0p;D`*9jkrdf_sQjdUhc zO2py7eiOv0(Kku`{hh4yS1h?nnkTkWZbx*uAWJg((7lZ^2T8w(?UbH{s`Zz1yNL#B zw!7k~dZk^VrYszpcc3|*p${ot=aMTn<7C*9V#E<)1*UuA%~BUCa=8?-3ycHJm%M3r z($bryDcIDSqagLxWJ6z`c8gS#up5AQ1@Q@h(XuBHXa3Idk4X%chKf&U_+X%5FEtpk zeu~Txx|;@rNE~?&@2mM$>13AswVyL#5P+&jZmzHu|Sq)Ya57RMP7X+vt@hduKA6A%o`V;m~-5 z)L~ML>5D+=FR3;XC>=8l8{+ij|4+eyJB8_6I;X{ zDISmUi1|p~iDe1b^U4RLl1S(>`RW%qTH&uYoJl`7>qQsJe@v2L^Q-+$m0=5Hg*L7J z5jx14$D|rszr$`5$3t|V!}{Sm!G(T+5s&`!DFatmZ5u(!gU?Jqv8;J6OT@pCh9~BWzN6= zTDANc(z7~oTx*>rrH0X-=OmlvDVA0Xae_X6PFf+p^P{6uj{|+l^U?{!_dvas^5;mh zRx(?13UN|`PS75vyMl5W&uZ20pLK?mZ z5D6U8s#RmPqAv>Sepx#qvf1 z0{4l#8Uc+Vtb}t_EEsE?v8*T`jN(nHH#NO0;ra|puu3r#K}W~F0b_;&z@yE7RXS}j zaDT$6H3zmtA2sXK;4N`wYKjh&q zO@q{fj@}9!*meLidqU9v%|_ZI4@DF~+2aNR&Po3qQF#G>|7g zmh!~!{`tw-0S#GNH13#nJMV%LXbhrDKLI~GuYp@VD5yFfa*neA7X{K9rAF}w{oN?B zf~4>ubH05NtacY@$N?$dz^>tm)cmO~Nh?1fK{XObLz=-l%jrzB^cfxvpGtf2SnwIv z@Sn8iGifMgH-kx@&IkI<2O;p8HGsVs4)>m^N2Q;98;YK4W8uAAKi>%FqbJ}$uSS@) z@?*@JvHN@@4T88-{EajN_A2e~Z>2lKe3a6G8gA^ENHb5OAE&kSQ(*4YxD)Eo`X4b3 z*}uZaAy1Q(4}OxC=*2}6ZP)}Z`5vafv4~j4_=g%;Qu6vUJ5cRPIfguqSWWe9fKlEi zrO~`Lbib)hDxjP;Oh@)vY`tk`vGu}~bWTbo&k)Q((OC#(wqGGQcBzy-RDV{=q4~d} zxbmws4T~;enG6TFGe$Ek;0bTz!xVWMEZJ>upsMFq&}l>f)~7JpW&DPzi3};meZg#$ z{wDP!<2lgtz1X0#&PjQcHx#Hta`$XJT)OHY{TDFCQ9o_@;V%utP z&$NqDEGBmNMQk^5^x{R|fx>l3T7^4qTQ5m}P`7`8{GEUMr2b=nL)7xnJ}*!`<{v3d zP2dJGcdTOIC$meQ%g$8w4~l{k|3SwSX@FN+2vGzTcZ;sv{a%ar$kmWa&fW}WS0G^a zX!`=H$5RKOs`V^$>9sl`*Xc}2fY0!{X~lZ^Go6cBF^3?xO(cus+inuBU;##e+i~NfYj+^;O@|{@QVt=$lYfO^oi(q6*cR5WjvT0e0{0pue$qMCM#AVXe z*T|DZAF`*)k5YCTQVSl2#eQk3TuqG}%}bM~(9s)Yk9ImuZZp9x1x4e@c2w4X&`&N9 zqQ6$yUmn#F`a)#jw0nEBQ9E&y+(jpDB-73ENN6c>l@Djto8=;r!Q?wqWOCABT)XiR zb6zzMf2XjFxvzK`%b!W5XjYY;v{ z_z*h43CIss9N%oGZQ~=|=?TyWBI^n#`-1@~neiPIXR}dm4uYWKHCBgxE{cT8rcct} zw}r>&=C+fs`?QOnYx5(XtuH|g9So!mL|W(!4~K@bgHJJM&kE@4gH;SvHA0TD4+(+t z9~P+T>`dH~#QkDyTGL>f8Y#z;XD-&!scUfkFXtc(ux({}rL5a#8@w}1Q{i9Yxdh2} zb&@%Sn`RneH^MYDeGkHWP;evaW8lN^5uP9)b5Dj`*u4eGxAwkt;h~42g%vMVaonQ@2w0Tsh|EltA=uJcE6Eg3lU( z^g9FTJn~^kHwEH&bVx>=L3N>qr=uL$fLq^=b_{3@!5b4DL*?4H;7k-+`wn0%l!|WR zI5pfa92M(y`i?vurjzvEwPv@4!Ei(OB3R0*l4STZHgAB0op+mTwD%9>GGe&Y1bXT= zd8jELuWZg7tnIr^zBiJb_rk!JagTgZ4AETo%6}NyZJW6nvq-JmB)J7v;g?HtPBk7}+Ro z*GqD$P8uE9%yc}d_;JbG?exYc5$=k;5w=BO&N-Pl6V!CYp{VlVC?jOd>3WKNq+Wp! zS&maRR!l`KqePAs`7Gf^@3(6%4-RN4N=3V33E%R}_3C zq@b_eqH?(s{@w|Tdp&Gi<0OBe3%pEk;KR{oNm3;RnMm2EL|RmO=?rfbj^! zG>kfyN*}|O&>E6^(>aopEi8ddM+UEDK`EuOYBKnspbQ~z4R6MT-!3a3$Cl$ ze}(Xy_J-USmgj^@%uvxAGJGSKLoPY>8coSPpW^Ifz3_<8nCtdMf2E6*xNJ-XlOhYJa6&pB7S8B})xe!2Zrkc^K@8_9}UT zSVT`$LC7j=SG=6wssi0DrhQfNz3CN!+_=C1DG+Bj5gzc8K-?9Gze?lZMD5pT&YSXN z`|IssFD0=;PK820eFf&?4JuwCZ-?GKb0wyvl8;dFqKcYV%J+&l{jn8LihyEQ`qx*{ zml61e!w9`kIvV+j26#z#zx^E{=2YHB|dH zB)AlGh8Z%Nn_V$Btah9!=Zg%$>Ap>*S?EORJSH zLE=q^n)L>nAhm8n!qMayXT`fX*_CLr*_8pV8A@E4h+8Q42VG3UO@SOrxwn`CFg@OCgpw1Y8{ayQAcE+?Ayn_Zn~-X_p-F0I`p_X1-E ztR8k|$h;LMATTo?#mPxj{|!8(r)|b6DA)`>1lR5zfmCM5J3ue^_7^9$ybZ2fumvQ3 ziA!f~!Q>Wf4cCjYl)qK(!C4v5;UItg7Hk=JQ|lIaDDLxOzEY{A4(TVhpx(?n3~6Vb zypudzK}q*<squk_b{%wHd9?GH9MydDHGzg{k& zne_lZozB$D{b))9dU%KQ@#2TDF_?5Dm;^@TgHYjzK>pYgf9zE%{zxA6>}vsX3o@zK z1Mwh}S{jJEKv=w5mIdOVIbZyZK%B)k&R-sg2Uk~RARb&@Re?Cm7?3wQ`Y0A0YYQee z=VwR^Z6F833Y5aW#S6W9x10thX0OG2>>l}&pM9+5gczz!2R)_5!8(!rF}V19{$le# zmS_5lz3(el5e@|bBoSN__(V1u)&qD9Recg6v%EqXCvp8K?WE#kk2K{Id7fbdO4umj z41BcBdqI&C_kwnrzflg}gvKi%hKlyeS#)Br+~42UX69)AWhb`yaa_k3hxvpT(^e|p zk8KSXAwc|j@I4>%gU*?-Er5<7y0!=6L3GvAnMQf!vkigd^Z=H31mY~}GS)u~#JdOL zI|K2qf%vXKoLK~y|0oa-&id{^JUHun0&$nW{7oG`4kQGp{gXgEIPH4_@!&Wb1M%QE z@Ez8D;5hp!4oH9*0t|5=OnE@bV0?#5?n^EEWuxx1XnNxZU8l18FQE@RfHiuM7bi}^ z8?d$4oCcekasbR}<$=J?bC?p2Fk}4f@UyTc4-;@0?I@xpxo7TBQpp?`6W;@I@^9XL?{lNL`wUu(13E(is6-H0t-6xj+ zLZyf0K87}KfW*uAdPB=$*`uBfG|0ycp0Qtp9iZkTXe{{%6dk9I$ftcU!sz2KAgJp# z`#n{ac_~3U{#0^D3>fMfT`$@1xgQi&+?+A{A|O{7Db0V#*#es2+b_s_!-aKmf-+DI?aD=U4% zb@20L_dTlYq)Zdhnk!zxcSi7Kup5;mpU|D-Q5tnlN7*yCcPc9y19!kDBaB*Jf-+x+ zYiXs5itomBQM%CjE(-FxC==;a7e%2)M4TxkLjgM7qMD%FJ-9k z7k-}3U8gA8#%q=S0(wzyh)(rEFY^AegF(CnF{uv#dnorN%Rmm$YvjdaZGYqJ-&ispp#C zbrR*}>&#^}&%wAc9DSw}BNeCCG(v$zwFl)-hnMJukxIGvmTIq4V@yHmAz7=}W0WLB^T#L?gs&Sqs%>+}RAlM&+NrUMp39sWr_4o}C&nwibohvjy^j)a z;=@0a?lshWuaaa+g>df^$w$-qvol~a%ceyA5jidT7lvzvrPq$cvQ(lm-ao1 z{$8)87bq76O@AD%F>WdQF=Zlh*FL7~g;LNrQRR;-^C5pGOjEw0tp9MqvKYM<`-IX> zK-~0AOHM*KgxmixRScw3JuU)zj5v6E?TQO_K z=an3P&%>#7EY4x`kV-T0M>ohpojzCb`Qh2hFhS$yg6fSgC^moBN7AGhlylJPpjSzB z`ULFqO&4%Wyr3Ss&$(Czn4ft{l-_U)(CQ}pQypR5m=7#LG@Y)%nf^nl{M%0Gac*9q z%=S$iJlqaoiPkMpx&`CShD6Q$ic-(3V_%8#dSH4pYv5>5RI2RMQT=P^R$jTU!L#Mc z0fQJq4X-IPX#P@+F8g)G%q!>EQgm|WQhe_zb{ST1%~B=VpE?i%Z{dC=QOj7SGz#1^ z0yd$5e+|0YEMUHRT>2e)DK0IX=mOn&YUW&R=zBH;^ zt<0wCHHuQv8M|rT8f6%Kjg<`Y?8XN%ir#?BgYg|j5qD?_?1^R7e^E6RJ9Uox;v0Ijx1|YWPBickFSU}eXVjtC+^j9YjAmvR@P#il?v{ZOsQ4+ zLJ9F!tun)OU!cka=47&#@n5BjfCd6&oT$xvU%`fdP6KIe)IdWI_=(EAQJEwj)SlR= z9MI_|Im-6mE0xte2ru(3${xc*fEP=JzgT50s}96&dKd|;Y3&TF2l&Edt#zw1*9iSW z=GT~S%stEqA1O-%Qwu`}h#;L66NYHLHfFbSv?CSlhp3aiA9VeQhFN)Bh(`&`FQ%di ze4xMwNL$~;OsdewAhb)LD)4oCj561tiJT1(fYMy}3S-eh5cT6)^Fd{yPE6CVMB!`o z#J>zovwfjt>F{w$@tnw#eawJ!Aa#(7{0^*IoRxe!i60Q_lEB>C2w+j3=$+H|3Hb{dv^Rh{7$}JUwpS=9R$j-!maPOO*Ia#h%Cd zGn9fdVtl^6{I%|E-699Qv7#gP;Xg2YWxf{53Z_FPasiuEIh9^e`r&B6yNh=Eg5uG` zRnf(#t4@#^JKd%%V=jp`r1ZNjWRiD<1^ z1;6bUr79Jl=%6ICs$<0K?FdL49i?V;^ie9l?D#mYP&Mt)l+$BL) z599HttP(z)j^(u-YLHx29ZUyReD|&<5Bq(Ms&;`oE}E&9QDZPgH5M-0EB% zR3eagupY|6*Sp23<$~%utJn-Xsi$G|Pga$(*ch|c(pf!Xf~z4ID1^#nb++McU^atF zM|XrBC`FwKAHg#z>SUc*&1^ZIrl+CNHGXW2NeqjnrZn{^HTJ|mEx=U=^z0LSJHd0E z2^l5$0IES>79*5ON0zTKz3mzo2oLVIuZWjfd!Q(e?8~%m9jr^3VDv(vNk*^apvoESn=?l!n_ET-z z{Jv@pV{yO@YLX!u1H$JC;08`JZ%`|#9wjKbA29NP*3eJwW5D4icMv>e%$cgwv=OD5 zacS#g#Omqg|S1WsV4bN8s(jMsbB zE$mAV3~1&&b)~@ZrZ!*gRdJu{tk`EV!c|e+hYR3+?*poB_hA_q+@?2*&!}()Qb*sX zZp1OiGC@tm{{~2(fTT$ic)d@+{xTbHJ`hJZ2Tnkr0^Ao=H36iOJuz5nBHnzZj)s&v zrWH?AX9##9qH)yZCcoh(2WjITP`ep)Ee_f?O~rv|vRZCv#Q-5$y@qo_#v`h^;x=4N zF8a~}*TgBRQRt5UTNWSxpQ=tbe0xQOJaIy+dPI%U!I{t3TvGw6eNW;^^+QU#8^`my zLM&|-22T+RVvY(`qX8$Qe@p+!r4PWBulY&fz&IVFYng!Us|&xyP6xc7eWiUP{e?28 zt1)mv^5M|;1a2}>MqM8+yqf(5^+CS~C{gPmoKkFiFr=D4p}?$}t5)JRW_~NWTA2qe#iV&42RNy{ zsE&kDyzoUZzMa~Tm(*T*oEedd4+g!WHsPdKxDebHHu4`z)EGlYXOKR_DWMb#(x^RE zs`e8)e9+|QMVREKMQSpc%h1C~Wf)L(Ige@)*hE&D+KpzG;cX*l%qvrSQzOdx<_Zob zy-r8;jS>1gbD3p-Bss zQk<-%Em6BTblsf3V`y2^acCajRi_!cqeLXtz5yhcRAc)4SMyX=1MDPz8^dqq{I>B8 zwC5{Qf4RtMemlxVl(lMXg@zNKc`b@%t;HnfRHK*UI2v1x^_u3vr<|v(RqOOVF8B<^ z{a0N`jsHd8>;H>F=J&Bu-^WYx`@y6s!KC?@lNy6br!OZZuMbolwmw*KelV%}a?`;sh!%|ed_aq zHXZ=|_>QH+4yaS`MHC*2)^vdBnm4@2vdldAYBs4|Oui_(mPqL@b&Tu16p%`OpStVgu`$IUoPNChZSg<+XjO9t`Zm0EqAP zf2np;xe+rrf{=m0KPG`SG~g?BsIPc9{JJ5qReq)Ffy}qQQb*zO=U3o1?@;MIxK++u zDvds><^+oKsn`B)VEjCT{7ayQ=kYP>6Gzn+p{sV%*LT3wa_VcfH-N=`1MH5b%x~1) zc$iv1vw5u`fy(7@(aC7xA-~5gQ$wzL93(hevwy3u@=tkKSptibCm=a4)5Le!QSg!d z=I_;YI>=DPKY;XV{p=P;PUuU1P~oaRT1!8zPS!)1TGplx!sN8JsfjwnP9H5c7-WYQ z`Owr8_#OOxCms7;os8KZavsVQrX%K*iDW;73miq~ z)%nP>{DF<>5_SJW{ZPD5XCvM4U3*RkAJ7YdsR*ZrSDcQDKh;Y#`XU5qOeMv}hvUoa ze*rVNFOq%$$SAl7GW$TwzoecN)Z&F$p7)PhBydBd)r;|sUhHyj5t|k_yAO-a{wb*! z?mFnCed~lBooK1f?X=VdX%em!4ibaHV+=k)i;n5sy)Ynqn0u&cYp{@Zf0+A0#=$;r)Mw&!uSFEY53QD&{d{VW&l=q5VR(H-kklTg?ZbVDsLn<`6!9|DQQ09zqLq8ZBrj%92_?@j;Ogv4c zFW}2@iFADgy10|7BHSwsyU;c0MONWnz_>{FG|);jBU~}#%fdC&@HL{QZZJdc_9KPw zAww?AG`mNNkC~xC;YC%O^bXx8&axX%NYvOP!nQciq%Uhq(3dTlWxl=x+)?_VZDuq4 zW6be8+cj7T&MqSS`|m$j`ddxpkGbd_aFr>mPs#H8ceO=@IV&VS$y(gTAzhHS1;O$= zzMF;62Vo4tBM2WLv>=4z#_|If;0c8==P!I36=BXrulJ6>|Men^A&b>5!v(i?Cq6h| z&mU9Hu)1?_<)+l?9*m1NA_du_>8#Z~3P_up;vPt+|AfCoNtAmE*2LdY?ss(%cv(29 zFv8FJbjLWe))eio3j>S=lKUG5)zc0Ci#PF2t&#?u_Ue=Q|JKRwl`Ie|0DmAvwkcBF zPPCUk0n<=(2H%_8sJQnS0HnAR=DA60?c|OTi2fb#?qg~WP}Tt|?e2!w+~aOT-P{EC z1TuGqXX2g&cNS!5OK0~`Qj*+?R?ykKS`QK0N93#m_Sr?*l`N>)JoIm0w7ewuFkw0z z+6espySX=-j)bNSHGL5pO~SP_cahkuEx6kKxK4a|B?>j55N_>0+{BmFKZf)A22glq znmap)siHUFB5z9v41db&;wvqsm;0M=D(MFt#`behqsANEHm$OsI~kwh$iVB-8-Y&R zlZn@o40m5)XhD}UsCKDvXf2t@GqfVXcRZo2EH~Vs2f1fcJ-4lI5Nr z2I;(N5F>vLmgvlEVDx*MIs|KLXScRjhb%gu*5YB*W4`*|*y_8e~rv(LYov$3} z?vEqDv5}~K_Hu1|j(Y~R<$#MU$#G|d0HFF@x2+-<^FEq}=epzZn40TmiGUB0@VkQe zy))Onlsu!{dLJjmIj$JwZJUYhvgIj!27mr-ZdT7O`~TXy4!9_eF76(83W^FM0(ZN> z9Uv$mhZQTJD55A3hz$vxh(e?n0Tlsz!Q_m}pn@KDV+kbcny3+@MvbTtTkMcnW5p7C z^8IJ$Abv^wdCdH$&ztsU=FQuWFn%Nh*L@3crfd-o_dkd_93^?#R1&G<=7giMu|S3^ z2f^qcAsK}c%0RPMO#wlR471lw5b>}rP63mj_%VnsRiO>xI%ChieU!2a$s~=&fO$hs zjaJ^l_?C7L$Hyqgz(+k+c?L$qSmhP0G<1nsW-$r}!Q+$>a2_0qf}bHvB9+4}=}JuB z6$If&C$cl*y+{mLgyN!1P#5+pajcDn z8^Z=cS(>Vd%wEyLtek++e{MpfuNg~2+ABSnfGI$lPkO;fh*b`UK>zMoWj5rnJtr#r z%FN8I8@pTDB&-Y(;-yKL>k!y89xEJcc<6Y^idWu;r!GP1WFl*0P1?lLeQ_d+*%k?y z6U$gUs0$?ZiKtv1oQXV%mM0Z9M{1*cbug0ZB>0b^4s@SRo>SYCQMh5Akp!Z3p#IQ_ z)|WShSfOPy!VXPF2)|?`Gm+Y)O|y~(lj1E%R?bkUnu=;1*`K0}AwGC?%gP)qMDx^^}$h!-YjLq@v|I(k8PJgVU7K30z*f zGLk$=rzy}ja-*&An>FPY8z>I@*r1f;mK`t23JY|TT4+7J=HA<=VZj4OVCA=6&$78UnahU2qM*qH=ryN7{*qJou zM@KOkKU3MgxS+{V+%=P~J^lVaA*?+(nk-PJa(4ayk>!AxJ2oUfw*)DWds7)Y%-%53uC_`{JHxXI%b5J_caXJ|+f}`?NETs9 zK3ivIUwj>Uf0i#*TA0WNgBmxXOlJRbh;AH4Ys@NTiE;DU;DH=1R!d9z*wxCH*ky#3D)Bh= zB*|L~Qk}#lmh!BOF7NAC#ha8jWkan=m)C7NkawGu5yWu|7OL@^ zl}ET?qI!!m+g#eW%89POxlQpq=n1OYr7VE}S^au^jx}{RmYHBuxEu5H2x_P#$(HKf zN(1PUv`2~azLC_1jJufBeONK+Y|xr`FUJ>G z_4~m7pCJeKftpyY_A9?Z`P2uLCY-dxq(UR~aDlQ7^eqAHIwwj0@0C*!dh7SfNKj94 zPNF71=)x~3-n0`}6&4=H&n z{6?#YWNVK~Jny}u$`llE?2m9PBe_2+w{d4gmt)G&GF%$wolxS+Ac82Wl^KwcvwW#^ zC+|ujbzfJ8Ubw#+LyFe54XNLWS--AYdDU7PlQdKO;AI>PwWqM?oFu(ZV`akj;}nKa z>1i~f5s(G++s^uJoaqWZHhOhul#U3^)hJ_WfO8l+ehzeLtikFbby;v5G6*qgYn2ty ziBn(8rqf#G<3{fS9Y&eOS>-Ofu^+TOCATy>r9#)rup@eMR!TGBoU|$;uZ*TbjlZCL z&eD4fUGVBa(Q}RAFmz6SGL2b1U;@j*D>TL7%+x z75G#T>kw(vtD-wtamvWUJCqR>E$=G3nV^P)?<>7z(Z<18bYE#|7Gs>!@QtN~ZISqW>{p~( z@FXlk0qK-on9ZL&09WfTMm@y#8hS@DYx_LLw8l*k8=ffdn;?U0&(YDjSh4 zB03QGsyMOJD<$M%CP6KT(pNUwn*2E)S_p!N;?dBq*O*V@rIAbgQlL1He}h?xOAw>p zD%WxlI)DETNwLcaNI~k}V}68YOiFzHd*yaaI{p7dui=tJ%+q*>c2Z2@REU@?wl-0P z$hZ_SN}=+i2OUdVsJ7WCQc+P1RTrG2RUHIh8{?q5`N6;`d;!e?F^(!*MH&JsB{pp{ zrVZLhD%GleNGD073TaJz`l)c!MMWci@lwT@lbleMtr*%*wciv$S`SuDX+_?B0w;Z_ zs-_j3bmLX4W#pGw#G;2@qHVOQN{(yd!fadwnN~s4z+$4RAFhf=OjNzK%R%Nn(06lT zM!|H!-kQ#1(}*rk<=%QaoT*|=`XFM4xH3)^Z3Yqb*U2i#D9j`$GF8vGeDOe*Dw`X$=45lN$#o~*Ud+i= z<#5n{)-X-wYl3TFko+6P0;KjS(T%~cKiNWSl6+XM6l3yLP@%F&JW;4J zF(I$!s4}HX0bJ{b%~ieSJ{L#Kqb;H*WeZd)h?9T2Ky?GBv?~{?df|Y!cA?72ZV}R_ zk7MX$G8RAjETad0cxt~$m5)pAC5u#3$Q(T?QhFbUA{L8Pui$D{q;j&({~#`%Ug@~c z7yXM=gXFSeV_z@Tt9EhI#jvHw(u^PiC29%OMu7k;#ZzCXB01c>cUrDWfh@YZSQSF# zD^#|{D^zkE_NEo1(`ld3`D%sA52H#7aJ(_V+J6QxNC9vWi->_7w@&<)s6sg0lbfwn zO*f-erRQXLwZ1_HrhldC0mrQum#kJTlSAlJZBS(s$8r_!4h$+BkBaJY5P(##gA2WC z!I3AZ3JI-ssuRJkDbd{XrlO89Q4 z>Ik<_JoFVlpoZ(zv6ZTQU9ArwW-CyKzR96fqV4oODZHt&;SLi2n<^`)bdk^@(m>G< z60$!0K{Pt|(`ZMS*U|s*`jMq^jHPj$p%V=K#L!8Gsu_Y>7Mj~>hR!eqSx#E6T84gR z=qy9$7&_0;1%@s%^b13m7`n{R6^5=dbd90w4BcR;j-h&ner4!4hHf%+i=o>L-C^i1 zL-!c^ouT^-Jz(e|Lys83u>-B`6NVZXddko<)(X!VdcpkuVCW@7uNZpG&>M!{GW3q2 z_YD2X&|eHSBi!$xC%&TeJ93vXWWtb~Aq7Lt8EV0hDMMxqwPXn2hNr3EB8H~fnjsu1 zP=ptI_u*&3kR|hL$B-36_-H0VdRlj2^T`6t!;Q=!?VhxMb%38A%tma(60l_nKyCy1 z6N?8b3v5r+4^&RLifD9#FwO&&DO8V0?gEQw&muZ7jq`av^Efy zq{x*a=ue`k6GNRDa%aec)!UOHe7~Gh0Uto3sc6AIsC=>Ul%jVfb04YPvDK7NcNU}v zLp>RS2qMkMhoRmK^hw(4gWi!_cfB?tVXFfx}tU2!=jpXcQwMJ_AKbIEML+WoR5jkqnJzD2ky^7>Z^n zh9Mn8c+^LmC6=Ly48<`tiJ{31#j|(`41LPb6owKRN@6IPp%jKv8A@X)ou!$L(3Uj!4O`F(2#^7yb_^kB}K+wTlW&Z z790T`zN=X%@B=hd8AEFrTFa1up>l@SF|?kc4Ge8$XcI%58QQ|oR))T0Xd6S@8QQ_n zPS!qOF;u}2mT=ntzGmnfilp*eV6~QtzPrf@ogAYP>$K!9GWV)C7;k&Yr8g>9tkB$B z7~ip6_ptz>Z!wGQXK@aEke1=C${fng|9?;)qycQOPD^w;#Ly269sVG4z&r50Sft;9 zwntg0A6ckl3>_!;sNV?|$MHSN@DnS;Nfw}*RrnM`rx`lKPz^)14E@X!KFiQKhR!o| zfuV~G{lem1V(2nMR~Wj=LSAF&I`g~1P#r_{4E@SN{>IQvhHf!*o1r@l-DT(=L%%b0 zpP>gV&4&yyDf7ZhmT?K{7|g#NXAvHnP)=rHLk7HS z)q(U=^V=1cD2zF&e1W&;p-XwWXsY4Qagf}*=ERSdDXieDVo#xhJMwk-fVQVAPoN@@ zB)7um>8dLqK##WF_*k5i&2{6KakipeC*DMcXBvV#?}YWnEFCH>c^iQG}GTPCDZDu|8di zZUAp%HrEKdF*v~pyE8b-2=T~)1|DXFJsG5Ap}$@dl!W2HU`QbwpKbLfwF5z*K1An> za%Xz;@myc=nm6BqQ}k=1cX2n=)~y?A>qu=wsm+ht;;Ai$+7?h-0kv(RHUqUCr?x6; zyGw0#)MnZpHhN)!cL`FK+U`&qnA4qiCaFH~PwkGD4J3s=yb~$y&X0lG7R%x2#Hno* zjK>KgmOc1bvZV)Nl=J{`uTonzwORD!or`C7LLBdc%;ZTQ6!K$cr#%6$VWl*?8iS1{hX#YFV^|H3^x|Xi z5Z1*91TOI5J@CD%9X@07B0-4M=k-R|8NCs9Z*Pz) z#s>tf0K}^SM6e>&y^;I`QXk1fq-i*0%R>9`w%~U#W>jXUz-ZGRFp(_jgSyAjA>&G3 zA%s*3V%rxs3tT7>A8ON5+ZfoS&ipCs%msbXkL&s(;C!dZf~!iI2BYQl+thna&1g2Fs#*f26aV{+ZJsiB(hEe%R>2 z4joU=sXd$K=|tQHz@8&zLV^eI?YUe^d$W345SmleFx%t8Nz?(NO_Cx+Y{=CIzA3vTWnXr+e{%EKz)aKX|RV{%H zr#V~wLDdE16g3u-27e^G21A4^@^xt3GMc{ zh6#kjegp**Rv&;IR}qeO%+*9qjZ)%IjWVL6#u`#cjkTnl8V1&d%SruU{ws212(sHX z1R1{?f^JgPgDxh3IACea$O2OD>Og)FDG8*-r8HUqn_{yxi`4eU>_ion(5}6O90=t5 z;=Zc^g9)Qfqrj5_ zcO?8E8tYPlhk|PLtkq#js#BTZ96kfB>l}lTRYN1FNFwaS;v_ynQxb#hX2kG3LRKOJi=u+6{O<^5%jbZV|R)?bf!a~f@HKw+uDZ~{T0*@i*LI9JN4BBx~9w+V^ zi{dkZ_amVbkV_rWO~8u0fh?K8cY|?ALgK>-d^nCwiGLj0bdjiwKw@XjW}Z)hvZs(Ipvx%MBa)F$(hP*Ure0;cAccqoOBH8H!57<5Bi zOmrETLSr&Ojx8A&*d@>L23cws(@c;qGy{L0L_xT(CWH4O0ht(hj+q#T1(|dfn1DxA ziJ6Fdga+1U^4-ZR>S36Nn~xX)3f82gJhI?c_Y&$79JA1@F%(+NLkB3zLR>%UR)9ZT z104b26|*o>o)Yv?NLFU?c(V449LV8q6wjnSnHB(IKFHyDON!~qAf*}|)6ZFak6bX9 z&q!`A|2aCJ*))*t8A+N3Dm)`6rh%4+N!WDsg%@J(biS=Z@duK@EB#RzSv9Be(0Y3T z@2GewIo6s(X>v^q`eo5cxS5j|@><0!_#}`K3otT53(impDug%|fnk$-P;;O7RZC{fXL9X$2V-VK!X;{M!YRDYG$Fni0!+ zFreFuBIwDZ$b?iJb;5H}$h?Vat@K(Nk7>+DfGgDPc?{Z!`KxfcBHaWW*d4 zs3l9H6`4yB@a7c=D&uKA@Ts7=$QH7V6sbt3c|bfv0?|=Ndxjh!7YRSG(bQ2*PEdsB#}qjc zZa&K5%#aK5pAW~547rlD`Jj!PgzP#QX+t~AhqUR;yxoo7^p@g7Zx6{^@HCQzfV8x` zeHf$*%g&4RUcmdxw6^4vHrP_=7huUdOm;887H9uLtlKdkWA&_9h<@Ic6fWf5u~g#K zeK)aTA$V^^cVu8e-{z3e#hBfDKi@<_N$^>ePFd(}x!3?T> z2m!7tXlNkjOL#ZROYfkQ*%D;eSBzT1u{2hKl{y@oP;KL6ka_ zhKgaZnUgegg^k#L6OT97!<)Qsv^-vmEh1gw1DF0%lvkFYTPg(EU6f7eSiE z)J`R49^#+Na8+$tOBeSeytxU<{0WUOX_0(#7T=BBevCgZ0|!q-6lb-=*I0i7t1J7& zmRzsqHKh6^KZfkB#uQyM1XtTJ)qpXlcrCFw4+iZ?HFnuLQFn^Rv%m@BsWa%4xcfy~ zYfW(XTX~MZLuCnQQAkxB1Zb-+@^}axL6%&?fHRh{>JonyqETYmL+~6p9Y%*Jpnodp z9|QhylS$=c-V1lc^^Y-z6QDU42rT{+peZDbqC`?iQ4%SqC|Rt1g0+_LPtjDSPchx5 zio#R=Eq&TcD@wF4_#!Ty9C!gPE<<$rgYQe9=jq<^(I$A(d+1O8D+NA=EZ`Fjasje` zashih1^~ z@}{Y_LO%!;?64JV(0WI0g=3s-rY#w!5|m_%Qm7#DDq#kBt`eX{S%n-;d1Tg|2W-zH z@1YcCQW!zu0t#mcD4u~A>TuXuCTY|%0k^6YL5^NvkB5pG z&IFe9eXO)yc3R$nR5=Kaq(Cj0g266#5Wr432*H-6=!G9XdnzOS9R)A2+ewZ{daZ;k z4gUyKPEI)r?jo-i3OHh+7R>40qXWiGsz8^vXz*g@MX*(91Y7cpMhG_RfsXzSO@-9n z!+Qa(6Ut(665L2kGS<}s3hz1z&dY)ktJ+E6!TN?d2~LD}7V4xIQAbIGvoI+CN2EcA zW8(qAF(Yo$>te*16QrHx2_vQ~6fMI~Moi~=iccDGlUf%eZc^)F#FTl$Sy#)Z`=8U~ zfQ!%#oN0rLU?Z!sC2O*6?ICso;SX&`!B$=SkA#2zN5W^tgpR^y4veX#o8S(yZVV(R zF~&`R6nlGb!Lj%PQmP4tD!fvyki%UhNm_h!J@qm1w2ML%x=Z-A%-ig9)*xDL(F zHEzO!;$Fg-;&35A^y@D8H3wf?*hh%OK>Xl&tiPX$syGkAVbHwkvuy9TP`%KlotEj_ zOx+EQ9aVh=KaRU3a{YzT99cd9&6qksaF$&`J%7f_h6m%o^HjkZtZ;dNfJc>n&=?)z zD`=^9M6IvjM&D)n3ht8bB5{E)dYxF|Cya;4H&u@IhBOR<=g(YtA=1)nFb14W(x?!SgW{eYTo)c`YH_n=#<=wMs_0F=vL6WM@wQZ zl|;N6NISe#;0{fN!54n#K_NqC5U6288jhnhwo+dI(pzTN6z79VDrwU0BxV>2vSFA| zD(SkCIogp=s%<)x8N-DLR(>ZM8A|bo3tBKWT(FSBxrk}O0yLlHk%gfcta)T>s4y9Z zWtiX!qj#8)FKsirk|m*-HS)wuVZv+P6E=4IK zd833t(QmZy4s*HKf2`1gMjSj&aFF~HN&hfRAvG7E0e~Oe9yfmDK=eHF?KmMt3J`D1 zlLSQ?UHXxwp@NO%*`FL32l}RlL&>CJCl>u)AbOsN^8AI`h?Y7bMNUs@;)G|ij&@{# zx@`xsXp#W2hD)LlFND*gq$LP8c61Zf32~`*II0SY@&Qs>q`c8P^gq388@-qRr#JVh zG4b&K^!9G_rr&7zciy^2@1+0qUfSrL@}J&^8olXR+rJZUX!OqbPjB@UW687r(>tuu zJNrMq3md%)|I@p&(RSUptT_jfu0Q)4Lp%t^uA zi;yXTN=gss;f?9_pjO-`rwX=`S8s;(slr~w2ud@?m`t6q@xv%19{FHZ;$L90Fr*1` zDb|PH=69$r*5}wDyQK+^NaXcD647TMk?k(FjwI98UsMD zEE17QkoUJ0N?usfp3~6nUB$3zLZk`Zg%+TPROO&i^hs#_enB{CdGaHDm79m|2kDN4 ze6R}Gjur^}{^l@m6$me7oI73r9F`S8#9cZ}G@pa6gU^7@5zdf`xmdT`&lO6!E@I_e z0iE7UJg^W1!o5zzBCw1T7YiPwAi9+WHlA4VydVP7w8WCC=56F=^!N!|K5Uu1i$F0$ zLkGO{Ufs$~*29i!4^=`f57w=!qQ-Q3v2=V$Ly@qU>rL{OfUJGMo#Djr0E8|J2H|x@ zU$JtDa1t*B;7*s@{-k!PVAGmf2N<1vB_~q#xiCiI2R8^eDr7cxJ_tgK)c7c)2e5yW zH<@9gFclN^0-ll%B;`v5SF=IJ^zgyJrIaBu{|s#h(`972(}XQ8-|>*mt6^RNR=R$N`%>M=;-|%b)Z%M$d2r6fKs!9 zm6&+0t^`>vKE*fMpx$;R7(}R`S_xjrXBEagrGOb3y9x}G<0`>aIwNe9r=%&3MqYk| zo*+TH6?PCcC73r#S0Tk$s{}X8e-dyU^kQI2c3dqaVjH<+wGa#4rwywGS8pn8N&nGv z4SI6aNPfy4Q#VTfC|WV2Up@&c6;!Q1`9G($QVgejGPhI^q4m0d8D{esv9Js*3bvJ7 z*9eg5pFp$2%?Co~>#5Q(8gt@;&1HS`GnR2hVuW=#bn<$FMd&~w-s zpDPz4TF3n>Yf^9u3x(qufs!(69Y`r1#G)^+6GCBcSO?Y#w<7B$!+X7O!;%VZN+${^ z2ID5w8-#4~V1r_AW z*@5V)Oz^qqX^?-m_)^H^jIL?>L*tG|V!fI^T zYp)1S#mB8}MaR7Y-uP#bCHsVfT&BcQ(@)eu4;SVt2U0Mk1y1`*1XFSUeqkbKIn`JR zy48~iCVGD_+~<&hP$gVcWWXC63M~{hSR4|b$hd5gJ0d_{Jx8=WikXze92cC6zs7?F zI`I*|AF(=GmOg>nWK-y_fpfWSb`x9Wu14+_P!Z%#L z2(o}YICVIK<;=3cSTftDk|ot(O9l@2M6KX1?L0Vm(N>4p)X(UMmx%gjbbcHh{)}UU z43Rr4WXKe=kd8S-6_BeT1G;NU&kH>C09_K=i`5r}5{}ed7W#>XOLX3vOKL9*e?hVv zAOawV_Qa&? zSWHjSRe)4lVDnyg9ew{WX}FFde3IDRkSf0L1{!Zaaj6rga0|%NIw2c3j%M{(=TeAg zJ*JdJWNAIx+l#!eM+Fx{v4IeR`$vTAMoNDb##3#;)b8;cj$b~bghx)l;UplCy#EbT z>F31mrr--S7KTC(Qs97iE4tL)o5CC@{px=UnJgvcw=hiy67IHCxK6hbv#F>_6zwMq zZwtP}_6{b-o41ATie*SjMU%p(%I;u~u^iuMM2Wz=LmYn>Hkg$fLmwumeiv-a%9`NA-?4a~B$fA(!(mc;A2TklGN_S5 z8XjV>%(*Xk{C@y5T1fghNlnUgTH6Tm#@uN`(;CvgL3batMDrnth2}j>4m<#L*AU^M z5NNm7n0uqNY@=AvVUqVy@RA+2Av?cs(ZNpYI7oxig8ritLyR6$`7&tv7UM!U?-8ch zcTcg7;*#)@Fr`D|J;R6lIwbnYkyk2c+095;gWx1qJr+D<62&Q{|1U7%o=S8So?^`g zJ)VM`>%{j@h0nRxGzI);MG;p%7p|B{Zgdi5#VdS;4tiLueMK3j!=mDia8ZVHhHLMz zhhC2-Dj@X+vGBdHM6gUm#|Ul4Jqu{YrH7d|o3vbXP}x70ao%EEdwW$U$j`V3+Is+w z3AF#hgzHZ353?_Xku=e90llD&I%={5h+aC`h5 z#7Dy&L%-*yioPw?p)E{D45^Sq$!#b!*{Qu9n+I3O+j1?chB-P`$lGy>*k*neaw|^J zH>g66=RMBiT}$;x>d4EXdbpc#@^)kNeqMtzb5rBGOiY+GDLOGBBeO!@oHHFcy+YoC zYdJGc?}wCHa&0Gs(J1CzTjyaF^445ixAY2m8?No_A$tD`xdmsDjdECW78l8iZfXag zdjn~HmKO%<)lL<18?Mc*V7&)|3fDNhs+}w3 zow*hp;N;FV_dr2BIK_`S6>?8b@jXx%PBC<7h1`o%I1blDBRGxFjgx;NCUsYrv;rg7 z+)w?7>~JutoM~@GEdAB*aq!S~pnAmsmleY)dAY%%pn{y^CI?i=6?mgGl@dudY&<1W z^8@0E0=3pgy(_FjAq(adr>HrCQ(PPkb0nv@JQ8LIr?^3sCF&lQVIhE#oZKM}=6Fut znZ%T+mEO6Z08Zj$vuNzeoGft~%y>?=WID_QoPXuR{FIYL2E&}faTmmGC2D+)jUNX* zhii6YAk4X3v+u-KtJHeVVcrP6zkBDnoXoi7jD(cr&b0jUfkS93Hs|CC>99{wsO9THQ_Qho)`A$=!`@D)${hL$^awiEpXewe7-Y{w^7DiIY4l^%7sePk7(6tj7zF6U6-Wy>qh*ysIA24HR^kEFxf%t)mac;I=Ei_ z18%uzZBVyvi>q1vH|i_x+Z+#C;i&O&tWcPo=1lTQ?s0WER4ko3u6A~XU}bPSouKCY14amumbf{5%Kd zX2vBZOh~8WEZLv4%klFcSmEc!oRg=(C8LH0^q?-Oy4WeY$#Lm$o$u#wbj*m0%|yS+ z@aL@a$*~KX%D`t*8m@yVW$zg zgyd*l`eYQvrn!`5=MlOoaTDWEjEVl7?N}+-5xUIS_=M!i{+!hjnws;7xJ;yFJ%glP z(ga{vzx$GAJXZX6mo?+9U1$jR(Da1l%tT|R?S3P(FKZ%kt8?SB#z7;eAzZ@~l2Q{B zCLx&|irvC9Cq~ERBxItl8$`z|nzknG+A)vZq)a-YA>;M~xnwT+OYI;Hv;*}w-K{Oa9 zZ)5rv52Uo*sFNwW2a>l~P6pi2=(s@9a6^;F<=YQF8++{0j8|<&{*b??`ouefq0`67 zbpF?6Wa_o=T5!Jx$#?$n^TX{IU0%*~F&Lz@GUIYm_1cXqcKdntJ@}c6?;r6trUSk( z7+h#Z8G7x8_icae8r$-E!}B}aMp@na)L?L>J}Ie4veScQD=bev_E`NL7f_O${|#sK zL{0VDhi@YKu~5}x?cO0w*FMN-1}Z(;w#a>2aQFAnnLKcmg=C0Q%@%zK9o9s^PF1iNBPDY zO$5pG+M)yEuQ%`S&Ahluo%hw;fNzbSlyZ9Q#obw(RU=k+0Rohbz8E@VECYQ^xCN7cOTn-_eI&QL-!tbKJ}4~My5R>KN0Pz*AChE zc;A%mCu3|^UXX3eA<2$U0oPwyftqp($-vFmzP!xEb4>NB^`t zZ^kdeK7+yigI=cB7T1pZ?M}ugvO6Z<4mkSo8z+Ooi}~v^GxO6ECS+xzcJmkYOW2xw z$^S{^tck69@9#~k9+#e!kUS|xubs5vxZ^>)F;7bu{rdZT|F5?i3{DXfK(FwNomMTs zZy2-q>(9K?ew*Eg=8S$5odjNmwndw7$sV)TWwMAZdsbzhj8@WWVcf=LVwmZ*fdSiQ z<&T);xS?&U3nVzJ1?_v`xyhNjoVavEp6|GCSJJI{nQJd}9ycyJ<26bYZX8s4?cp2M zzCqvqo{`scf@wynuARZqF+4i~175E^=(5o4@h#__8CT6#`FytC72PsCYXa@fXZwwP zSAQ$TY0Bw+4>OLx`VNt7!!uczUFR#eKk)MxzoxEOVb*)Sj}P&>snO)i-d@^$ZGidw z0SE3)+Af!&0v;Igm`9_dv*UDA^xF9JBG0ye?)E6$^HtW+kmrZd9~%Q?#m4JUjikW- zCaJ$4T5oZ>U82jy1(ZgOAu@6?R!n=DRPOKLykV&q-g%xkeQq#xZ}NvGH;seEnLa%> z_1x8V#G8Kk%N~1qb|Zh?)bzG6+^-EHS5D>kh+j}w-#+OU8G1|8BY$JZ^sb5Pm+n6y zGno1ZmZBN|&MhuYuN~d~{N-U?YDV1OWBr4@?z>ALls6+*mpnJIpeCEBGZRb4d zx7S?p41=LdV|mbFC#EFnwdn(##epSxS@|1Rw0OR2Y|pzhLKkETJob=7OvZok{|ar-;&OD~UC&V24P^#h{C>oVdq>7a}Wp56Q9g1PgpQ|F+Go_^w86(JA7T^4i>M=X*Z#QuZHuc?R*mtFf}U{)_9D*o>z$?K{L9X4-9h zLL%;JI$9jsmQg*=zV_~CBZ`9-^uN80EV`?4v-oRPMe^mgLBFhOKahVP-h3wc;jYHn zB6jxrmS;D8H~*8BwepJX3nR%NcQyUHb$xpLg{ox4>xAK*6Etf3q7UdbA#2hkIyD4l zDz(8qUA!u4JfAo7I2TDK-P82XZ)l~v)pc^5`vRvHdx^einb`v3KeMtB)RGChYuC7D6V0`@rBy-5EOIWa`p+ZVNb%o8|e#kxyuP$|NvD zdTpP~LtBQGck@kC?`jxW88Hk|C4PfWKv?>29Id;b{~$!^(>`_DynwQ1Q z=E8yMogu{UrM&9(tGi-vQY&gUUxnjhLE`fe%V;zr>wfaJ*{q#=c*6nm@37 zr@`PHs>{UG{*mjX@7CXIU(q(!WPo?~zUUsELTMDr9$X`YTs(T+*ZDQKPt(fl(vv9j zsMq#rxqi5f+r`>1UyqC#P`acSC>xTM8JmLbsg&idXUUGEwds$0_C4KvcFWu?$TCE# zBiMzJLK}_yjzjV=ckkC>uA%4(A*rz`6KO9}J-mEvq4lzTYihEG+^c*yAATdVk|xCE zr^B;os!yv?5B}Vl^!dH#Yr5C}h_a5LeMGOFb1nW==rhx+Wp{pf@l+F-4!Vp0Tdmi| z^2zfrt-G?YL(c4C$Jy48sRx){y>@GC-r^m*vb=K(GBFuVUDaKQ9D+`{r$I!uFkKkYo_;*;%p3&tz-bcMnp#Z;F~b?(DV5 zBZJWQgOXztvnIw#td)3go7Hz+txYR8jc^Nh$-j)g?{4&G%+-P+Cg;!D4*YqAZ*g{Z z&eRK-*BkvQ4-ah&!_9eAb}$Ab?O1wkK&qPmwo7q-!nmv%Z-4IYj>-n4 z#DWx9qEOVjy~E=FDl0wK>e{9s7DaEv@No)A#EOxa`Kd~G_v@&M`LAY2u6T049K;Qf zHdA`7`K8b22kt4(9p8Lag)Z^nS>zX>%haXErJ_+@EnR4L@0%6d9&Zm>wCLbE%ndHm z*%7#&f#3YN<>*kao*kwSFYmVFB09k!>>Y8MBrQ>0M?Lt|WI+Ezi&HyaT6%01@`LZB zgnUf#UE;f@g-q@Fc$VmE`sXCyF{s1e+eN+h^oy1myT;^PUYI;K@7!V!Ta>49dx`Bz zy#whJGUHfVWuV36iZ%-{uBfLp{XV@gv)9>HU->*5egE9BB0ZRv#*HiLvCgC2j+k(_ zeAmv|b6tK#Drw9d44UA?&&)_wy%Eh(g}xS2V+Cic~DYj^rRFzQGid` zvfBY$s;8sE59V(_+{;?>PHFOfeC6@H4%d#IPI~)I$q#M2w3WOQn!I%hea^3l>+<{8 zdHquS%nq(Z7jhkxI4My_+ibnp_sw?ajQ*Zqb8rFo_>bn4#IYzE)|$1KmUXEXyba#t zKF*$V`5mc!qOt1n`cigT;OoK5I?ouvJ^UfP2Y9bRx+K&Bo1%2SL=av9wt z;BJ!dW^{OZX3%&%0LFdb7v(+DK5ZSfw$rBe?(e|X|KFhkroVdAsx3tWf9*IxJ}Yfm zK?d3oDdgjPg3`MEja_js)BCm<6uR~7n4LL&!3MEY3gh90Ub}C#?!|JSmYc$Rj5Mjv zF2}^=N<&PJ!xZBG^ilcRRaLP*$M@YjaJv{BQrCf535nQoL}Rk`y<8Z__#!Av$N<;b=ZlkJ}0v));^xmq3{N3<)4vh++H+)^!$1Jx+{Lq z2AVcEDftD@R!x)`0Agos$LWxO-p~U*{CrlTu$8BW5at;jl-#@j0zO4?`zjn=6OX=Q&fNv7aguQnA_n; zMGsqJsqsZC`V6t#w7S@En^n9+d%A@GE>_U?uHmm3UcTt@M9}1Sbq-NTle&e+iVZZU zTX;8dlv@Akc2Hxt@M!zuKRq69F$F;&%%;oT!V|=O6rUEJB4TM+T6mIS^Y0!{JBpue zilUNqfWI&;JUJ%gg2%H7;Q&JRA0AHu0=L4y({wB?++o^v3cx;z;4))_<@Nm*5PhfpX_XK-k_L&6sdF-$x2kMPh?5w4xj3tuZlIHhmZJG2cW z!#9Lb>2|kX*lEZ_R}{@2g~fAWCWxx#daNKluchklp?Ye5!GNW8#%iXxJgoI8yF+bc zTy8OIEu+FG>RqLOc|2j50Sf}tvJT;9np_a>5C`blg79a=>tq@m-mTLESX;=uvTO!k z@_6h)@oN#cQbTBngSIUTvxya2+1PMLd)>^g^eQJeonod5hr{!!w9IOx+#}&OlrB0F{-B8pYh73;`37^<_ZU{mpV4M2 zc|)(KxbMUDB9tbtlpK_C90XOLi?va3H)i_kDzhJQn5pjj@JtJ@86M*x1Yb=JHPf<1 zqBbeX{Id{AG^Vq8Xur~b`4%#lXS^_{80Sw59`+!lnUI(2FM~(Bcj;JXbBgQo8DA5* zND4IZ6~$j`zTfoTK98rS(c?Kp^RG3>it+RT9%Ig*_Ei`jRG|iG+&(wJzn9y@XSRt? zYZHGMaT`_W3^E;f-efZsBF^w9(2^pf!+vX<;=`yc#T+GWBKz&34ys8pD{9v^MLHqQ zEG~>{lgtiPZIf;DXNP;U?fN#^7b!gzBYuzaQq2zWp!d;v=+C|;3(;%;iZHj3|JjjG#} zX;K$+l3~$FCgCOT85~qHSJH!D*LE={bao(_2OJXw$rmSlY0jXukLWUrV@&Z~@kpS7 zUCk-tE}Goc+T|Gt2g|{;UAGb*GKp%+tE`-H)B_pvQ9< z;rcH;o>GM3Lmp4UVUOoogw97ip5+KXA|z5#8Ybx@dL+%9-MQp@-#`L`<8@T{AJTHM zf0`YJOk`OoD@<|-hc`tSe2?ELJ{{C{>O1743C7Kn{*m%>K1fB#?))0E13e+N-Au$8 zAzVB#Rb2crT9j_i7I)CGbn_s68cI>gVSQ@Vh%j>u4?Ps&<72+MftAgW@20ZrfbO4Y z(RJq7^uNBn8r??_51!O|#DgV`GCG550z>Hz1da1PuIv1b4?!=Xc?NS10)xO{I{kSs z`qLPM_TSJw-OU|cgTD549?ZDoXi;~N-T`Xh$G!AJcXRerr@y)yim7elg@^|l;SL5P z9ud@G8sfH~xPo{v2mI?x-vEq3Wxn^Pt%2P3P7iaQSVe#IF!$|q2hxM*C$>$z81xgE zuPy%e7!jScNj=TKP7&j@qLt=BR)}?zU%*CFx4}Fsy%azP2Oi6O1g;-QKNa+zK}FwL zWU_5>o3(`-&8LOE1-T9c?kOMPGz7n}D5@WC!9L@HbXL9!8&=$GY@g-jE{MQ0Af7gV zWGsO4@lA2p@lhR%WmL(L2O z5rjZGuy^JCHf`*u=DtFN(5pMlBkez8&xIVmA^d@GCtyB4^y7YGE{s)B|P%Ra}bfPfHUlaai`9 zqb=RUKu9Yfgpz2BS!7UCjK$HJN6TPNK;V_z0U-e)9>E$M*P5a&zgE$XqYy|ka`67yW=kxJpW1BcB~*(4*fL&3)3bPxQsOkz zxsNRu=s-w}jV{$&b_*AM)`0R3YS?0lCG&SCvxx`9V05I0t!fn6wt{{KZ?TL<*(E6C zE1M)DsVPD@stnLV8n>!u4drrpKx4O|M}WJ{GLCjMfXY+1TapdTSvyjeNdTGKfnS9x zwp+4&k6u(?50%jNiDiL^)>eGNQ|+XCcUY$3Q8C#CQrqf=J`-)#um8+q4y{T->6wiz z=It`-DSD03Oy!N1W`HEVGdZYWro~t}_!={sbBDWxLwIl== zW&L1=h+zajvF*2{*?G@kxELlGp*`j8w>ZFZiqd46(l%O*w7b%6q~^~-(+jAAGqJcP z*=4P6zh!|+nV&}L#c0a95ZR5Yb0O;2KLk0r`fICEt3G3~8O18C_PoWRqbbknZT0|z zWrAig*hH;qdWV5&egbw`y-dyJ0IlURwD=O}^ObS^j5K(&#cbjlHzJs6*mf{dgB&qNRMz(Vs4a^rWZlwJ^3i4^Wyzx z8=dQJ&7@14?N|b9T!~@;m0c5&M1`j?cpJI&P-(4Z2>kZ1!-hNt+!8ti$-yg?nL0`1$`0G`XAVpq5ca z{Z*ip&jcMPtH2tPAG8cG@GNzt$+uc$15c3M2N@oHtTHSw)?`xJOE!qpOO9d<6wbxI zres(L%pC($P#0Kjn$JQ}E7=sP7lWww0XD}xZZL|$v?s%wMAh9emAmsLvx_I3X}UiG z|NPyK0)*yQutr)kU>mUYvnr+t`bM=sc_* z6W@b+Sl-WSG%y*}(4v0mvZXLWq2_*8r-_A%MObUtBNm1^XyQq1zBN6p(c07-t>;qy zwkQOfT*|>@Hr!`*Qt@zD!e*b)8%<2I%%MAaO&S<40BtD{Iy>@Amb*j!(0RF=x8c1cWdb#QaD6Pv&tn(?dpN}E|L#v5jS zjzw=`)^HDC52lLWrFdv)tNW*X|j*bGh|Kkxz@3TT{d+%31}x z*k1a2xivv&|BZAjtR2PE)MHv=qgNF8%V6QI%3xPi)8qV+<_;z$wi7OeWg`a?|AO-u9;v0 z*#oI{b(ljx7uggyIm}6=iDqDXEjZJHmDb+&ZT@;(o~3|C=@@#vA@`T7rQI754**yk z)O-@snVkiyNB%-xS6Qzy{Mm}~)Om*~%21BiFp94Wks$zD71uz-d7R8Y1J#H&t+GbB z?rXVPuI-6<7&WOd0oIdPjS`E_{=3d~7p1SZIt(UcO`wXwSc8SD!46)aIjgPR#Vl%A z4V)jOV<@EG0b>GXz8CGJ=5*dq*H}|^#xr!|8fyn}n8vQL4iX>GvNhH_?6aXb2ZK0` z?C+wTQIw8Hd^~b_ALN1D<$pfw9}v&<1(;7!dM{PH3#N4wt$5d(Al{}u{Fq6t?^?U- z`oBomthL?%9#FK_8YO1XjJ4LJ7$cN#ZZr@k`y1t{UQG>a(deyoY^~MdN`Vs2r5^B? z;MqG&rW&;M4t1)r4uya=nPX4WoEmFNOfvNEz@D|xUx!;YB0YkNCV}skvW>Q-#;WKN zU!t&Dt6MZur&?=lOv_6ij}c{g%jZ6;5qR#n{sJnhwK_yGJyHvz?oNwP0lL$sTCA2w z=~S(?nr3+!)+G%_0RyxB_hu3j^q40-R!Hwq6OD|+W&mX|9ltER2E;k zF=n3j*&dIe_?Kd$ym&Ju`U_5>m<^!8DSttJ%su2XKE+xTw@CiyW<1eSJMNwNTyHcq z>=lpa6$Ep+$J4jM<5`SwajwVnVWr2T&hsIkN6PI~A_S2CrXT8g{xk;eS)>JxETmml zGd*xx=QboGBaE`vS!GLrtauy2LXn`B+s#6p zN)PFrVk(_k2T}w5eE=fJrt}Z6BHMF|)H==J5H&Ow8TuK}wkd9%4yO4Jz<>u(?FZKG zhF^|);rdetOfJP`tVW;Lz}!-++u-li3-w<@CJ1Ry4FJ`NJ9 zJf43n@^}^?y#5BvDvLdy_$3~X^cGcV*6R%E-nJ_$C7F(E)@bnyi4E3K;yN0$!I~5q z4JAByk%xapb2osW|3V)i8!PAQ4PYVL$-WWXU4@n%T(~{r;Xn@01>=1OP1T{;fI!NDp zy~i`RAH>N`)&T|qW7h;~9S|bNQ`6NbdA3dbQEJ*`b=aTMfDwNmjL_lUWc4*9BjyFA z8BYd*K|W6Ln?Ys!VE_hI|EcRv6E|C@8YXT)ajN*mG z(BuZIeDfK9^mqUB5C49YuHAQFNN8i+2?=y7X&VUvf^bS!%MGe+o_L5Jo zp7~r_(EvW)jm|e%2f4oc)R)T(G=PH(l()s&SFE8qTflWs(wZ&SsLpY_uQomXvdcHO zY;Fp`!w9UTR<89R*|*}+6=x!#zQ~%>TU3UJYbaWa38fKcae?CT-g%>c z<6nTL0s|nVF%-d2PNA`75wbeuKV)sk0I){3;5egvtW{5?_bB?xl8sOj>a51f(rciB zltn}vrm@ICMFUia=tJV^h$O>$80>Lk5dmSY@$N_?T#Xbt7;)3gHce6O3o%LvQ&x(m}Rdr>*K%yP_R` zIij~tlu}GZL@c(JW4}N)$*qVefeEgm0@$z(`wvII<&a%=w?NrWejUb+|8n$8rPt{6 zRpW5-xvc^x?*FwRuh#y5ogr&2b0hK{Rj-@F!u9PEF$`u8i8T2J7+31oMI=(O%|$&9!Hc12uDd_PNydKI zLuVF80FcB`y*7AFM4{d=2i0NU`Nk|$=2@6pE^UEU&{!K0Cmz*WYa@Dz|EBA~Y#R^L zT6GwVY=sBgV_^UNpxvz1ydN>aD5jHI7ZDq_2wKc92=ecAQ(eS0?K6M(c<%q59;l1B zPNdV4x(LUZDkQy!z#N5_I+HVxl<7o&!Q<(Kz#4KQH-l_^Bf#xPZJKqFj&Ca&95~?#oUI|SYDZdzVO=a zDdes}5S3lF$gbLpSFhb7j$@i|lzQnyXwOIQg#l{f0@$8T9@4>xZNpqG=n`hDtiQ%+ zGNU=>87WjG=^d2%FP%|4usI@4rols08?D;_)w(_hdP;q|USE|C&6)?!mKh_7oe{E@ z|3yTjuIf2x))PWuj5*3Dz~^p-k)&~x5jLeG5t(`cCipcL-^@(C?fDH~M`#4po~re@ z&7L}0n6#o#?J2*BceOd2B2xr9*|<5f7ddT;ZT-iQnMRznXMGy^3isZ$D>90fwukh% zJ93+MV~F_M*#dqH_7$)+z%?QHzpmNbi9kkuhcGi0?uksLODYi^`1zlc#~=e zfG6zO6RC)o>DZpgf70}=kR5j~0y0XoQLH5iZZRdfFvCpT8(AXKsK|*fTlPjq3$td~ z7r7O3r_TqV>8Hr3_U3~>intDpl zK?g^(+-5ryP{5+dR>nIiKF%=`Mtm??nP$g13jX8DU!4o?da1;ODfs^^dd$j7ob}{h z0)uEd5@FOz;~hIf{%-VtnQ^VLlVhEr!W4&DD^GI7g#h2R*E)U%*)2+Okm2vvt{9?% zJVgwA%r=1L47bTzeY&H!Fg)$WN?w5@ikde?I_(c29vm!GJH(wp$!FLjLI;nClJ1VW z|Imqz3Z}pn=jsiHY`1{2%9#z;^l%jauhrT(`V@POSHM&ZvQ2=kuC$BMsMYs$ z(*1vAW9{UEJkR98fqw_$$_)<5q9)_ID zY<4PpUO4Qhz`BE*vD2~H4!P$O;Lpr**(4ljp#W(C;VH1&T(igH`4fS+1q)4136l-! zds%2|nq!Kp%)KU#b}S8nDRqv+*!ec>SiunLe)ILgCl$fl%k$JQ$C0f+bRJ4@p+WBy z7A@vwM~bk2={L;;0J@9DyyA$pKLKGYxLrY(*(R9=ycS}EgI(<_j-(EQp=xj~{#}Bk z8eF{j2fA}cgqv*T4s)l)Z8Cp^pv`#bj1cH{8)cO{rir_0Q@JC`HT0XS5qR-y#JzT+ zstSkGwSpDvpvsrN;#tiq7LHCY;g#EF6KJ6Ao=6J@ZWR?(IAq=BBlJXtqk~vUuU0r> zEy2Udq3uX=79761pDe_w{zZ8F#hu0hfpe~-N2kZ(N5LI-3F`0{_*ewPx0fc(bwu4% zh2&s3dbBAfwTZuS;Og>!?WeuNWw*MFwN7-$-45}0%d~^lGuM%A^X`ON?pux)Azsz8 zmN^{vnckG!wYwe~m275571=0 zaN2aIQ?8om)C(&e%a9$UOmt$=EdwuFcMpu;=c9x3*)W$MU9j%z?eAvZy_<;xv zsLTJfQTik&jvYS0Y927m9Oo4)Iw4clW=wJpy&uPzwaq&4kjoGvZP#MCFFcBFa%*sw z&~g~i&VCm%V9hw}EV(P9^;H+yjWr8pbH~Q$>D&~T;yoc{IW>wFIUv(!9C4aWylPbh z9LybYCYYE__eW?)O9n#SIro7hnv5uC8G%hoLOMefqHQ|jd|gM&BPE5Z52EiK;owW9 zM{yXFvmU!|^P~{H)_Bxe5JJai+Z8IkACk(BJMm}gIH%dgbHtlu^>d;f9~0aUnF|hU z4_o2J`d|pmOtZ~SZE&-*T!>Qb$T4TQpwZDGX2W%0Qg&*X8|@JBbY_Yxmdfu(=h5Fg zZT3EBhq2A!R)n6E_W%z2qo+CJ?8*LgMmO)T2^8}kP+gv(mZkl} ziH0LEw(0U13#=wv3`Qzg83kwF;{cxpHcC70%*1R=K92T}{u6RZ;~|}y794j*L$b10 z0By}B;L9}zNGpxUoeFJu6o@fjb{ciZFVkPgogHwFQFcO#qTW9^6G1*>e{ha~$W)fe z$80}16(m)>1b2XzADp)ML;%P?2A&0lz~Y?>w%P%4mC^|e$Tk(aOy-ZyMAPk8XSB?; z>T#f67VnPoDk;7JA8Rl;>@0Jzu`?j@+NkMAXNst%)|G(7cETA=g~M?G%{aq4@#5AG zTJr}${JbO_{!BRGG>a#w;$u`Pc?6PO`3a}K6O$EB0~0;>$X)QXb5r36oEAy7<*ry$ zphy^ z37_S0*|hpo&e7uyEXF-eOQsrSnm7?&%W*j_y_Px5HBr!kpDi|sLs`RJ-6*pc+-REr zfwkCjtE+d_NLOlQ{YyrzWQ1#}!NA=2MoPccHI#C0btyFcR#%Te?Il?-ywu!))Itwr zI%R|_u`)9ki}*H|6Q|r+x4Gz6sy_^wZ@NtehpK`&QYYa=y!1;5!xPXlvz2%nyBZ7Q zQV)0!RIkU{t6q&3OV;9qdEGWF=EA2T1D3z*il(@5kbABTe=gW?T-|&lILGdHG5&07 zdKa!fxocd}mF1W8G%F_3Ow-q3SW|z4G_mbryOUa8fJjlZ#+4?@v}0>rt8}o-rr!vX z&Kzifz;Op$*-K9V!0ENF9@?cE*99S-q4;SSVcbfg$8n4Oeb-v?tk&?pYlKcbNA~ru zm&mpr$BH%UT~le{diF)qT;*`!Y0zB%j1VvWU7M0W#gKBRfgb8vFdXoyE0bz&GuWVN zw3Y*gx=&reUxfrm;7?uaSP@EJrgy|IhB6wwf?h^EcsE)__79>R_9Ks8E&IGcmp^lj zgET&NrzU5@zDsaH39 z>es6qI!LZvuB5mMBr^?nMF=eQn_xD(9`SN;XNsF(i?(-bV^~X~7k0U#bRjMD?rzr& z)V#~(%-8^%8V`?`UO+bEwYI}==}N^rOH%w>1mL(g{yhfEmsb?(a^SQNmYzrrz#@>w zuv7q+U_5+5i*65%6`xSWZda73BQeVqTUkC3tKd~kM)Pi0V$ab(Up?ZCHt|HnnT*+Y zWd;IwGne}8ah)*b0lxFoSie7&7$qjtz`d>{yBWuF!SlD9X6$vzF>m`#aWSaQnCyrU zSn;<}?Os=c_?Zs!VJUZcy=kL|16IkV*e&^wXF zlNg*|umI5v-7ZJ0RSJ@Fc=E^T6QCw8U>cTGz1QQU$}C`m~OyJF2bV-tLAt-1K;s@mM-^rX4l{>1ZQ6( z)_FWbKk|6?*LggnKlXV3Lb!1Y4jpz}jZb#+W>5nonL(!xxuUWzLfj9g#Z!m}BV}is z{0H0Q-%0}yyJB4*;4me)+FLk5fp5eixV_Cj>@w=^-ANCGMoF~#Fx<9AP}5alxfyQ zZ02b?X`X3;KSREf;nXhZq+%V~9cz$Y!sC=d>MvfU_!YQUQ}U=0?71&Qw&eCwG?lcM za>eUfLwhO2C>Hv5^Jc5GLo6Z;U_6;^QZZndY?Ibn&{BK{X_R=wyDMwu9i$1|3DO{m z#!Cv`JI6~=2F8Vz;%|ZTWdV{^j`K{$A+U7DcxMfulIFxq7rn(T)cP>?@RkPLBU;^2 zN;Znc)RZEPr^agmWLgKOv+6W_mFl9MHnD_rFpw@%98GnZ%n+iH@EA3wKrtyymCn)N zR8~<^q(mz3A{_=;_jZ*Y#^dX*(t~&m>n4rEnAUWYDur04Wu;3`g&^M0L;4o;qb<2! zx*u_#xPST{QCj&8Qgw)UTZ6Qdt%FxblMdq6luW6BS~8`4-6|XH-Q=wnH%Z+@4IR5lN)ffb#P|3SMY$m^ zy@7Yb_bD$MSYJo222k1uS8|<(^+0Sg?1fN1Yy%{-&?shrlmKV)vi8{MHhP<*;sH_y z)en$nVSh#oIKNqHw|N`hM3VKQ{Y;GI-4lxbp!bXd2`-^}TMNIk@EiXV!J+{5|( z;n~wP6qWWdP<`Ph15grZdXAK#YqHT_Tf-!3%#jY5KKBE^pVkbMx`iF^M-SS_Iw9s- zvJJ=mm@i1E5LPqy+aYPk;7_g|{)dNX$Z#pjbl6|x2xBCQW(^0zzvNC6X!px*b7jkL zXhAYO(&r5a1~PMi7u?d6K_{6`NbZ?a4d9R?q|;1VT}DcW#Me|b1BVm!@ot-zoGH1BvMI}CP=Y(%t6e%a-38fWp-$d6QuHRughyB zRlFJLz&TFQPiUQuh0twkACY8{L`(9+Ws&T)hEwAdsSXG74PU`!s5!_|xjF|%$ht?M z+E2IO46k`R)Y!&RxQk}K9afIq2%I#fNl?B@!X)?!J|a!g<1ldY6H=1T@>%#KjGBjk zij1cEC$Kx5yuUqkm651a{|KrdUE?&e=V-AcYnPs2CiN|2AyzbNWizCwbmEvMN~LZg z;yW$<83~U6-_xm?(pv%^2F$!ld!mh+XQktYA21tM*cZ`G&2ykr@uRl=c_}4CoX}cd zlspD;(x(-)lw%;!3gU3brL_*^bYY#3W)7QD6ngC41ny4%azBrm0n6;guz-8RWb z=?s!Zcg;RmiW2s0?5X1rzQFc816%lh>Q^bPa_z*%9}ZDv7etWZkYLtBNE%PA*MoUG z=Sgv$Hl6YbSphg$(E1B$ytD8xAID`JmlhGO;O&o3rfTu-(0 zF)oGn;GzB!q&Tpoz`xG`=3o+4QmnlU*;n{E=EP0uk3=~74D=@>#oIa8yw2ZJV1Sj7 z{DZgP`&hECjQton7y)*f0!?Got(WuAiinfsQs!TvHze1Y&A zm*h#L$-m-)L)>!7sP$MXr3uP>T}q~san3})p-_c^arZK5CONlbEyPX6P$s-B6~g*) zY!HaNxd#pqTHcmYg-(lkM>=a2KWmotn12IfK?ki_8n4x8QkqU&(vEEe!w?s=Ngqki z2yvEayt`5CGnHgO*8*2<>)B!Q#N0p z!3wGGjYY8SWt@1=8Vka0Y{g0{xdBe%^=G6~JzT4@evz=L{URlLrHIQcH^@}|3l6LQ z^5rf61;S7BbC|fs{e0^C3w-d~k@yufEU5N3sXLYYiqg6(?+{Ry;jnhyuPn0NiJlw3 zgoP^k9GYqQ6}w3JAuCqUIcczHPqo!@6zoN?Nj0C7@^KTQXtCU#%Fh_h*tag9N8`CU zXxv1#=Yh>IPU;IpqW5l8cqjI;-oHr`@m&Y(3pKw^n%_|w7M@>u#GA1B*e*yVkZa2>Ky1U-dqL_22u@u9(Ypw~v9gx?2bhwOs9y-6 zGF}9umC1EcTE(}FE@G{!H0%;+)XgzSg_ou2nDIrIrBPlLf>qymDhmSy$tPoMUL!24 z@Jt`kl>V1joZs}9^o}V8MVYqLk7W91}KIsaLCsED24 zB##qulrCf$JZ6YMS|!aF@(5GMKqHl90~}R4d5TCt;chg28cgA+AUo}Ev1oZT4|^}T^G+(&2~2qEbNDYn=*Gy z;CF-wQo{fuj@;R#pF7^JuiWr3#4ZO;HqtJ`w4OEwq%%8A?g4?NAx!QoI%}817Kep<;^n@k43x}7$RK-1IoAFy3h{5I z@6qln%IXN*G|{~sZU{_nAX;M_8x54iNb-Iuuw* zYY)J+BJLANZ?j)?m@RA+;2%#{cOUVw-cK$OqOT_U%Ol(4?xVNq+;O-rHf5lks1yC@)j{$IaU(SimgTC! zaw)bb5cCL<$tj0KmXEv(?{XNm#vyXC(A{LG&0px;fHrTadDVF;50jl)olr_cNQMZR z01*-db46zBiCVnS`Pe5Q$4N*F7Ws})m*H~%qIZ71S~8r2cyO_&5NA3FH1h!B!N>1o z5$E+9$j?DMV1MMb+n4qX2SNTyO~&?)_~tfp=d?EQd+Gd*YOK9~o8-KGnTVa!ZR3;n_h|8~thAeDL%RhK&(P-mdw^ zW1#CyzZpJ&N#Tz(C**_ANq7$N)w8x6?61f$K15^l2aD>vBTjW?AV?2I~Jl=8+rL1sekP-B> zWP#oh!#Mkgzv3u=Mdo&o;yeJ}VS@~ERv?*8H;>{V06fuWzJWZV;GM_8d(<`l^v^(2 zOl5&|T+kaS%bkZIDS(di5d9eyEDrHGG#BNcH;rmX%8nkK#DVFNdt^YlC_fnk{Jb53 zn`D3=g7!d-E3D3eL-1zu=it$ESY6%9oAyzW(e4 z|MM<#-6{_?6(Y)K+Ba+W-YSm^=Ua(Ia589lItD&pt5_{4l42@O zPlTei6v-R-q9OA=t^Pha)ol6)kd}<51pV-+oS-R>$qP;R`pyTX;9s<^6fJmVUE9-g zewb?n3iG)7a|Hz6By#ET+43NfM-8*V`EJpQ=E&W25V|W~ksY{$cdQbCHD|@7Qh7EM zgoUyh*P%qYyj9!=&09{PZRPR>${iA8(~Y&$%P&N9rN($jlBsj$OmQb%K;#sBF#;uV zX?rKOw^g8yrX^cqtne>O@rulU_6^9zY(ur%dP4}dop8P1x&E`r7V{gbcFc37o0c4fh*^uW3W}%cNFUDk*@nqdW zg^Oieab7H^#Xke!SbE}hz|zu8#MxFJpr~iBmfhjTx(x(TcrTw#SIcoY5Qc0&Qun-_ z-nhx$k&>6lxw=_?c*=JJp6Vs&_616RQ%z4H0sGrh zIY~DUbJ+~^02~~VFO@TU&i5DOgGU~8l|RnBisR&uyZrG594GsHmMu|7;U<@0B@6gE#)o;$t|U^%b^J@qfN_^U$-2qBkgs3l5K^YOvgEvxdIC@ zd4(KJ6IRG^h82LxPVr~LWLnDcm5Aeh;v5j;(G`$3x1r?vl^~I@)yVNOn|9jDRq{>k zwM(@~hW=Ev7if<3KD6EM%SS zl&J3lU#qx6hq0;-6IF;m;L*o6VMa^qLiP5MmEaZnyKD~nJ?c2G>`I?uh}H0Qkn%`aJJ2I21E}`lY;;ovuo>*- zj-d1cU;2hy;f)#hG3ae96@3gQmHM%~t*Svbf{i!SW3E%{!HjK#;Wt>G4aQqeFc_EC z1BhJC$gF1go8<0Dg-*%%#+?W7LuM`329?}5$^nPk+kQ2bA zz1Vga`Ri|5?ZiTPBl%%M6j@}rzReA^H$W@ zwiWQL{ugWvPf+?cxjPuD7kS0oe8^L1Ccia?!sBMcm9)cwG#JLpwxd>=Zvvk7#h&rC zv2J^yjRXAVZNvCUAT62SI8Ds*)q26##*4n#OTISrp9ab&@|(Af(O1%@2GVdr$O}h> zuZ_9B7z|WQ2>Ck#ZA{@eZyU?6r0oc#i3LnPNmTzX_L2$t`sAlx^;2$u1-|Bw2Uy_i z{&;`|F7(GisorI|$RB4_gqP_X{&-;7F80R*%eLAd=Y0iI3!VK;HsDmyOQFpbvXhC; z@Fogj=X?~_m9!X4{NSA+*SCC}XzEUoF%|B|2Ml)X!bY)R7sgwf4#V)tUGhRWF2WvK zdIQW?HM?cK;eE6eMNL^TDO7$|iK~no4lm4b*d1(pph&Lc^_h)hIV=kJ!p*?}(CIy( zrvv<_WfRod=)Lj)9L+H+q{6*&hK~i-@0Attp%3$i_xdmopLhNi13$S8_~Tvt@h$#%XMcRFKiP1*BD7RrW)K-+JqgVxJm9!bxpAQ z?B^Od5O@V&t}=cuCz}qSYoBD?`E#(Ng3sjvrbAcKUgfmipUaBwOJ93c`(?%S)s=kv ze&i3>531?CAH1V*znoT?9A(y4@0X7Y99vZ!lqtmieW1J_pT{ZhbL0_yESxFAQ#7n+O&1w$ci4{w%hZaJcxFG z2h1oFV&HE06b=b9zn7zRFq1BcRb#d3KgdShYNFOJlqh`6M=owpGtbCM)efxDxO4J3 z(w~!~wY2l{XgxX4%ZgV02dqJG(Qf@y-W4h=v`MG*7gp`EPB|-y2-!i$^)*Tw z%(qR~C{I!2HA*y1Oj6)#h(FrGB&D3c6IIbiiGu02VYC{h6?ayq;QK+HQKltbS%+P9 zV=twz)_k2}Wc{dLUj;Lnhm9bu0Di0Hp33fjPrcMrDWSvZXreg+mhP78@!_G_*DI;Q z*V;3n2*$0J-&@HLBF5K$2TlVIft89cEYjgV%4%2?8Ix3fgR)SJ)X@1II+}TdG8mtc zQHp)7b;n0zlpZ=-(2s{T4JPjLbf_WKk#^hsOrX6b6CL9NT4=oL9;U#(@WL3J#TZJ^ znzAu+n1Ox0JZRUyV;-mo7=#%?Q(=E)X=|?GzAsF?++m$51b@_H>JW#3? z6(~uZ{K7cpc|`4nN_Vypd(mmjv-o^6;O^B+m1*i-IQMDEH0teLp}Yi3mfe^{u)yvD z8XNBdz;*m5_aZKpUb;)kq~nNcx#N}927G)&tXC4WxO)|wLG;klA5dVh9!bX@R9+H2 z=~xw-DJ@ZEL$$O_26lSUo`--O+ax_1A5scY^4^D(@pOE$5=Sk6!sEE*A?2{Z)nA?s zIzGiavqK(HcF~S0ic*;t2V#3vnN7||LA_pQ+?Lm2SIylAPT2A&rYOTVU5&AJoRvMM z;5%&nv}041Q36tQ*)2S%m*G>KRsx1v-2xkbrUHykc|w^*y`R9KY||8cTZ%ExCcAj} zyTef(hlpk^ce=8iG5p62WpOCJD*WoR${jq?tZ#wJ1$go&tqKKKH?huGh78~W`T`(hd+X5Ep$1nGN2tszW@@MHOn_P@crYsR-5*s zveZihDot95Be9duU^mbF0vEMxFDVB?3Vk%)=+3yu-vmz_UB!#1)Oe zllm29CIedzmNHT+D_2hN3cj~edEMJIZ2UFwt;wB&)fqQWsn@|EgSlIUvU5n;XQ1XP zz|^=`g3I$Fr9cePjx17S9)9Z^N-sLR2%Q~m#A#YwlaffK-{U}I!eYfMhrglV15=AZ zNXd(pMD6HeFbR?4o22?Bn4e)jBDu5#%?_u$+f;`(@l9nyDC+~vi*mKr6-svj(cc@r z1s_9FUgwU#0Ee)hj?h=F1`jy83Oy9ARtjkFY9+HW?Mv(oH(@ZwHQ-gI+khh8WJlq< zH%bC!tW}~-qy1@PIIX|wc7OB^Uy0WT-3ps!^@)TeWisBI`1nZV8+Q> zr%W>y`3v6VWwYARbxNWT<29^|zIsvY8*ED<*x%?6mEM%`Az)qpp)x_-quD=F_UXv> z5mwgmO-eKF3W6%4E1SkSw4ML2yo_L(xz&pB{-6jd1qR#TG>qG|a|X>Jddp{Y^nOO1`7dCXa% zfFY;sbFAG5H8eC*2dj;jj7l%y{^!DjO1^+wGEhDZH|v<0F#FWz9a7*I_b~IjURsYY zF@a)=R`HcGPA4AGkT^)-YdpM=wft|fti)qMD=@bZi?6&{$$?eJ3wr5Pm%i#4Q2RKw z9#h_D^#daU-&pb;*stwvY%|T@Dd)s=h8#l0amDF9m7PK2xH78hxSs+wWW))>Q$Sl3 z&iZ61B$I!{r0sj zHUFUu&{a6-jknrMl<}uBTFmwCUX)gkQ?F{X3EwNY0blnk48v98mOrsYS2BX+szzXP z_J@2%dQnltyuUY1e5f5ar*p?Kpx+wx?<~ir0Y^{oep2UAF2UOq^pog9h9=Uyc`;JZ1wx4IU- zoAG_r6v+ROSk?;Ndk*jMAziuw9~({Vi*ms2kqk8nHZjpp)kx`!!S3j%&Z7k3umpkm*rXlJ(I&(OV|h( zc8ZRslcUgP&8=#2Ki=tCS;$1-AD_$oFKG<*HVwPggF3ODrRDxqKU$5}qQ|I-x~eh2 zy7wXw{5+X0gSSD_m=&hiX5FE}{qZx(D^y<*JLy=V+70-!7pdJ1yBG;x2D6(P%wztI zd9q!XP<59&Pwdg=-^DbvmxdLq-Ju_r6=P7P#h{&ogm=v$&kRi)AFR6tzDSFGyW~bKLC1Z)|wu`S`^1P z+Kb|zgA|^bgnxF>vH_w_$pdO3WMLFZp!$ALyH1y=x#D}R-()pPCyrCu<7oB=9yr{F z9#?B9?GBwDs%5_^7``t9$|*x8DwZ^8^zoHs))pqY59dJ-M|sR57R zaTm!{sxH=Da?m%kB2s8YDO9wUQnfA=-bgHHYxT3#eBmVDEtTp35vsZ7seOgrh-z$r-~&}Iim#N+S9|I3 zNyr!HtJjiw0md3VA8WCBzM4!M_)TAhw8Sd42PsvE=2xk4TrQ2)Rbf$0<+L4KZ>uj(+x(z@vboT<3>ENWQ1->$ARj;awF5XFD zuc~h9@hW;reigkGzv}D7sV#pMBm@<(_BFM?11eza8g(%|cPicm5<25!vT6#gei!Vj zaV@|+%x`i0reBM<9DYmVx2gPAz;7p)p!u4$AeC7h^;TQA7GO7iujqB@PVJ|)>Q0;l ztW#&=%RR?5Y(;}V09Xq@K)qQXpkM*NEx(d>@=BUofFQtE?z5@#@uK=y(6W+}h(y|?DFYMf3?@*yTQOsxR@7^`$BKxawkW1YO26BUylI<^~iF4E+^Y62ep_V7b1+M~iw(yNu9{T0Iy!#L>T!RN8nVU^mFx`7oPCStU}!B*^do;q*l9Mg`MJU z?eYP&uUB5+0p%W2OCULE4PUAs^FC5`6vEd?D*M_yu!gTyS-0FtH*R-#q)T5zw1B?& z4LEJ}45!}U-55DO63O$w!RlT?P2Z>wav^BIrj>rs_i9DoqE&pQujrUM3b`APVeBL6 z>tpJtF}$<7fPA)^D5OQvC1gI6TUJ2fb}2`vvu%hOHnN9aVgR z*)G4J=EpDrvCzOi4eYhSoRGyA#?eI*f2i-6t`woB3#!8#WhR(F$3i1zs;|S|))EEF zZe~7Qq>X<<%6rc@vDJS<_VFV=uEMFWEV&0e$86Z!ydDH^}LKc(C2bbKXV*YVAiWzZMzEJ0OqWxN(`y*VR@zE0N zlCwhGb$pTL8xU849`CT&Gohs!+|ibg0(6OyI!I)PM)~RCaf7=%u(ZbD9%`x!6w*X{ z_dgk<_lCL|m7j&WyO}lxa!DB7gOCaYzpMyKgi#Q*eE|F&XC{byi@+d#n0WvP8H?h#kzez-}VE_*t@1@6dhbti18K zWbX`jY_{gJ=L`P?HT5z&`k3L`(+g3iO8)We^E)5b1Q*}@*VVpiC6yI39I$4_+uRQh zOM~~(rwHnKkLNmsY=mNjClIzEoJMf`=J7mq!QncpV$`p9xS^@+ z_AS4XFgOU7yWBfM(8L(k{jFgqhNi1*%E4Fo-f`Qia^ZkmKN)lveF}n`?GEUq_56>W z%H8hSG{xnH&qEac#})1@@oJ81!WmOe6r)xvigN#KK&!*zK^^9daR zUZzGrsqCfNRLp&9g1ZHf$0WMPS0!MsXC}Jy@kwd)a5~Z5n@>GJr&S$s>1aSFceS1p zJ7H#FuQqy5h}mV8*$lIogMR~~rC#gK5vDJ$bXAt(-fuc|C5oPtXvZ+LRNdEP^loE^ zgEQX|JGC)g+z;y@82=k;`%}iF_>e~KQ<3JX0r(u%!Zi1Coez&NYCjD3$tot-v`Up2wT?n(cb`j!@lKPI^*}kf^1f8@{3aaEoffK{?rQcCA~8@2RaGfGk{j^2%q&7}HQiZi5Z4{ATck?>J!^*#^1s zUjZM~>9v|c?kOQOo8u)bz!C-zb+;IPz^F5+XbB+7&2dkKuk>^%SX99WnzgO-knwsbCfof~=+|S_Q z$4~wMHMr6@3_V7G__n^`@${mLdf%DM!JXkYt!hFZit#Av4%#H znhzE-lKSMk`}0EG2SRAY1?^-e%QS@yR*+Nqtzc5# z_r6d7&fMxwG5vO>a{O)JStDutZSHJ5OryMyVWZrGOut_#!$_cQque>B3s=&-gHL-9 z6Jgutj>dnq2{FG@INHrxc+nX5Aw2rr?jA?B(O5YPZ+9QZt%kBY-1j5>%pLB1cx)bUdJA+LlBtT?bSZG6PyI4_Kb6<7%l-23#A{7 zge`V2yw2kCCDfMh|$QV7;O#ZFfIP=&q(l{u{|_f%y*XCOB|*jOqtAyYNvsH80Mls(@|c|dw?Nbjv! zH(iph9nE6NPRaB=GAXMF>I|*2IDoU`Z?lbEwE(2UW@KpR2~A`)C6n{Ss9|o>Uquf|X>0b%Je7 z)izVLc41??)idN7hoTow)y}hP^M0FREgTPgRJ6dN!{}++ZW<%S$Mlhyx+|<9;Q#h4 zS54Cv3DDxbafY_Ps+|ivMv`E`i)zd}U zx0YKj*8XUt41M*K3zP**wUI7C*6ao06b9|P@ySNwQtdWeSa4j159SfeK&ZWl8nDE& zO#2fiS>G;K*tKA$jxCQdqpz?V%fJO4vcNvVR-*(%Zh#3Ft678+X z({5HpII@(1P6k%CUTZ5ymgg$Z_)1FlcedXXa+IlowJ9hzH!#D_gDoJa#K?u5Q ztu_arR)yN#XzTJqh`=wI<2vm(Ku6a>s5!}+tk?d9sfn~fi;KD^*}zTOo)8!oZ_-{M zIbh6I2&OOP`&%iYenbsO;1}>o(|0&jQ?VVL0Oz5<0GA%Xq%XB+nfN8d-xptMlkAl_ zkecbcLyK;%tlgp-&C+IoGJ_ZQM(9xbf`3Ciyqv&D{fY)4`>sF4_Wd7WmK*{fMFC`+z)D6MTcGBhG1z?hafja$d35uB^9k&ZV2hK5kHguv@)d#7Um1)~s3x4iA`iFRqgdrKeAT&iV#kcvq zwi`-PdR`j?tAGpI4V<>Gy9}#sNhDD_jRix!h*{W6w&#-eSGMyadQsso=;SoeHDm$T zaksnp7j5Qy^V}5B`>M z!PCL=ucL=V$e_|T0?u7JmSfDvSY57tgOiuhH!)s}<_)6k`Ip_)TF|}He#Imf-&U2{ zu61z;6QO+Q3IVqEBB7zHVh$Zc-Qr-M7iGdaNh9olp1zB|b%w3G2SO}l2kxQy&&a}k zFb+WJfp)F6e^qK5y4kfweJJE8mp{<9v!PD@1lb$Qf}bGxI60aSa=GFU2(Cf0e-*?n zAxajWB3A`ZwYWz5OnZ;-KwxonKThrx|D}C|!=We--e`)31Z~maPFL9rbX_|0PZAE1 zMZtfxHFmLR6=m&|MGt_z#nHx@`MuQMu#1BOjTItuEO5fq>J@l#JlQeFTQ*qp&8QEN z;FWfO06p%AQLZ4fCILPm$KO#o$wB|1tEv)R*!oE>uB_sXA_^&65EJ2vZ$V6YuQH9x zb+#*Wb&J5k>;xT-nIy@{D%~keSme%X-3CEOmal4bLsdeG>~E`ULxc|QiYJ0U(B->n zQW0kZR=L{Ai}@LJ_u%O0qid%z!5UZS|4VS(Hp2%E5y58q>V8lt&6NfGs=}_` zu>Y(S$I@08i*?VoQ1^-@YP9kt=o;_V6spLBdg@l$A~=W$i+BBXk@cCnC%lE}ac?>* zLU+18D6G{u9aKB^iO{*r716q%pxZGTUM!O#P8P@OhO4HyFwZgdvGO}XSK*O`Om;w3 zXX85t-zEZ|tW0IC5_ByZOoMe7Skpz8>2h3xZk(MkLq3|OJFCGhgOypjXTmIbakg$8 z_M_nyS_jfJZmL`t_SHQnEmKd^VJ&!?PK3GxrRkMSBuvwJ3v=bg({yVE%{+t(WZ`%> zniV(2tqtRs63#2l&}Gu2i%OWF1RMdlGE?VkLt5s_(f1u@>nzxd-ZLA?E|MMR=;qQh zkt^rvY;3UKT)j}&f~{Jp%Y<4z?5#%i!g@&9BHeLlUI3?Z!tku?rowfB#7}iPoS~in zsqR-?6o^}*>x7-*bxU+U*u*YbqI1JO@YN-{94ttWSgM4wa5d!7GM&8(VOvxav9VenGfQr;T-O^b+e=XqQF*!_g=w;skCf~R;G4!92F(q+ zuEHvL^-A3+0Y?I!7wA&4*ZX*tZm6(^onyEUY+i-YU@t=>?p&n{LN`_%u|@mVF?&_5 z;|A_%AxDtaYF&Flwb6xznsu&n;Tm0_V7Hj^P5ETP3p*%!*@#V8+d|y{RAG3buAWNR zB#&6H%Twck?c+_lELxh~rgJLTf)hTun{`PncC${*Yq=d~bGGPk9O83c;YnL{BHO!F z7p2*b__eHZ4UR>&{9Ko9_l32jU$R}F>keVn6wyHydn8tO^S2>}oiZ%8(Wsx?k<~SZ%+iO4AkWLA7M>LYcmi_w3R&6I6RacRxeTL}5ca z+kLx1Bv>unSfuM}x6c|-t_|pil|h7Q!-ntC4acJ3o;|wjtY{Cq%$BcpxdQfJo9xy7 z&=$vcD}UEH2?v<|uFlQnAfl;{s-vq_B%4zM9#WjJiWhtj9!oen%vRh5!cr@OVVzDv zM>+bL`#i?cagI)KbdsY}9G&Ku8%Mu$beE%h9Np*W0Y?uxdc@IV zj-GJz2S-&LRV&El>Hksj&$vfuf1rwg&e5M7;T2=b<_nJg<_O9T$mdIrUUBrABPcr{ zw>KQ&qR(R>fo*(*SfHhYkPSy_j<6+2ZW#5*4d-DA;o*2fc&(8TRLK&m&yhVx4LHIa zxe9KLIC9`_jvO`S$cZComi9!ab98a#JNQI?M0T#+)s6dgXO4g9xOP}_^k9#lfRAa( zmZrW65_t%Thw$Xciz9E2a2SwsY~aX;BVUf1aMYBeW*qr(Q2RC;5DVXHmr_hvIHuwWIO}nVDy|~xj9QEO-FGqN5lJd}>qX8TZ z{kvghIXX_YdwX2;Ahx1?`@<<>)P{txT z`iR%x#~cmgZo@em!O=*LMsYNnBgl#r%UF)aaTLW-G>>yUM=>15auml=JVz6FI4Fmq zib&*WB1aIQD1{`Bk~vD@2(KTJn~9?|9%nj785}_?C&f9L`<%j27Dw3}P334BM|dlc z;+(4bS~v z7VsK{_?Dx66asrp33SDC8ukG!uXSqNnA!ST*Nkm>4Ke7(Yn?krT&2do=P{1A#`pt| z<3|?$4~FvtgsdIJ?sk)-UpcDasFM4<#nEk!?r`)QN56A)m!o?e-RI~5M-O?Nk2reF z(G!mT;HZkDY98(>N6$E_;pjO>e{%E}M=v<~o1_28!D?}+%I+oj9aZxywz{sUvwLlY z|F8oD-&kQCRteZz!15S*R^dzA&OZ3j9CZM=W$pP38>=6+8(X%iu`AA1in-3Xu~MQF z`wMktJ5d}eU{D?*iNn}%3Ga{mD2Y+5h)jN-VzCOhU>h1lEp(vZg6cg_5qAIzu(oOO z67BQ6N8;?M35P#}yu?1t-b?hu1L0U4c%{R6;9@TkGA~}3(2ElUtaLZ<5^?jzAYvH+ zN0@!YBN_)}%^rs%BsaOtSG*!<9AUv{I5K89K`N|y3;yC?8YkF8Z|!3&$~rU`b8&%X zMRRc!?yfv;F2+FVP3x|7dZrd0}i30v+UkdEE6>DaKSS_bn5LGYNi7` zd9VhpMH==4=%ZsZyNh0S``|#1A~Y7j?`KvhaTsrfo@{o2NGfeM(#IQ*V2jO|ZyV81 z&_j0%%$aQtq&VuzD&>;;*O?Zs?d zTi(+PW%;SS_(qoB>VO~@JHVrTN0@5J)RIij9bpaZGG-U(GVkOc?A zIVcd$s{&CknPfUmrtL5lbcW#uS+ysVLuV0NnVm&%TqsbgDYrAyPUwsjEo53mreZQ} zCsPHPj>A;Y1%`WMM!j!t3=9Hn>cDz>wW z0r^m09mQq?VgZXBu`Y@@_I4FpV*IZpZ%I~f<5+k%c#9%$PHa^-F-j8+GIqemsE8e_ z?xH)EjzGgW1>Ie=#d;A4S!Z|ON~5tv(9NJB0`%mjE*fQ~0}Ixg%1+M2}91%YDA$ehF~dw>Kh;D-hEL~XkF6rJGEyO+`6?Gr@2qRMvndbEY87|~C{GByFi`aoah<-6E zr_U$sHGMv1QeS+Q@cb<0`B}zhlI3!?jy`5~pszR%t0+o-g8CtPu^$r3BvTlfwv%Zd znQp*@)AIWM$hkv**ghg#kTzCn`lCj@`=gfn1VRH^ZhuhFDz>XXQdrGO>9dACrq5c| zU;sXatQCFMu@L&KXUX*0z?Ra-!gdW1cjKI!lBL{%NNDsxB(#@I=7C5E(c9Y1wNmC5 z_IMz;%~lpL2rXqC1W(($AxpV~L|e@^(5NE|xCc&c86^7RJo?c=VES26 zk+_ffEtzq8c&KQ`0V&0o%tnNXqg4CdpxVt&%l3vLQx#!g7~eA?T$F_$Xzap5>mDrF zmW3nSk8<>f;surFfKs+JXDm?;`A8hC(j0^Z2AE6;Qn(!9&AdmTxs1c{@6j-XJH%!V z#}HgB9~~}YDXBy*9Vzy-p%YDGQHUd~$yjkAq_bUP#SJ*H6f#b1ra6ol@o?Kw>@S$d zpKBax_#_j?i-UzzEMz>gaGI6GqNEiD4R+F7AWCQ+9*?RwkH^4M zp+h@)N7>h9vj%)nmsO2N7dcA-bP)LTF{ohg7!W4Z0z&(33=$8df0pqmeT5$TS~CD~ zT1N?hBj^-h`+o;0t_@HSi?}ayuUEKNBdp$wdqAu;Zg|B#qF7L4rsBgBN~CV^kmX9| zaSUB4gE|gmy=W>_xQE4ob!}!N;=pY;v!!uj3(aOMp*XY3gO1QI94BH0bTO0>qoXXA zTP29!2w2svOcWal@LoL;41P0{CW$&13PpP|w5UnUo&>SYEMyYK$jvNmlDJS+;l^fp zX$%Fe9n`XS5(pL!W0J+YIRB1%aARRRC0q8W#NAd-N)er*44BPMLw#;$>(U_Y+-85L ziFv{ud1<;BV}pb5)sx|fC8Q~$SHWM{khCwv7AG|nv!5d3h|Lt#Q4pD`#^79i;S@2D zWlljwd1s-L9!)_Hzc>Z8@M9is>KU`prVd%6cfo61@G07W>%_TPXrV`JMHYIw87{2i zFC1nGyXkWdKIu#4!p8A@bg5VD{(LkV4!;okhe-?Yd7~f= zDHZc%8+YSAi@?$r!a>Dmk~?-338~qx1qiF*s4lA{H@qYTH#=K|rKArtkA=vP9ryDA z3nx^c`?0tBsbMP?icUCzqQu&e9axB3XvC2Ndre6>a@3f$S_I_8kuw`Z2ya1=7gx5F zkQ+zt?7$+Vf`Evw;nGn=+Q!FjnIr53?%|NQw?yU7g$(4zp zihim#?rdyBjVl}dDTb)SZ1$((DM-&DOT?~h$P%$7J1s$9L0kF25{z?nr+FFpetVob z5I0C2kXxc>B21bq(0gjN3yqy{r~m>PR4!mVUycq{wp_$j1u~I(D&>M=7unwod4&0y zMF)A&3Nc9y30l7!GM#gQSSWOt_Y`1Iup>@S%mg}YKLSAo-JhwL{dYG@-C>z=RAnRyp#qdTiPy-hm8{n)AW4a0s3Im1tp+U!m&#s-XNc zY`1s=S1kbHS}1(T9v6wJst9)$x<}N?*?TYm+kJ#MsY*V^15M&2VVFGg8!^WQ;`{4; z7z{?p0kXKcp0f2Qu;3B_+lU9n_H<8?ZXe1)KZ!Le>`n)l66>a2#jsNBXw zsxy#HaUdLw_N6HF9^7q-2ExYu-jA6L=ycQP5+iW zh3GSZ?Shk#07dEGfr;!jp@~d-1~iFTooj~9yh5ds0k1@m1R=Hm5&>Tx}CY@yKF#`FfzZv*_j2~@Xb;56iyh0}( z6C7v4o%Z2X_)+(t#S$gy2bLhwX-7{fmlb(R&W?-zRp1*Gcg*_7X3tm_>R?Ag949Ao2c6rulZP+=zO_p}NLvyvR_QhNI!2ev+lD- z@=rceuE0zZgb7m<$=7a|)xQl}+C++A$GxFMb}v32$@`&Sa@{*}b}+9X(X4W{x{_G)>!zcf#P>|EYlYN5Iajuzo=;0IkQF5(t( zPz&irJzV9iY$tgY{DQ=y+JPBql<96Kp&JC7)1*mWCFF6(b z@PU0^(NaE|+`trA8pcjTU#1+^OR^VKH{BKGeX3viSDw*Z>Sptvc05HB6t*AxL%h4! zPkKcf)1Y^S2_dkkTHHv(guyTk9{?IwoN(|r1TSEMf6(RM3Q+b5c zOhZndta2>M9riKW#uzC@Dwb_=j$P6z#`f>r<+4a=IA$`;|6{2?CNyauOPIn^B%iWM zAG~HhdV~}U`;rk-f0Z%>Izs)K4LHDPsS3dy$4Ip95->)J;2$qmJQlN;qBuMsQ}G%c zt9Xpmo_oX-k`a>ae|gItiQDr*W2HVylHJ&t2#FpX+c;M0iVre_N*GLD?g@BoWvoqWbcxj3;>tj+ariqUhWc7t96zfyCciVLyfdc0Gh)E2^_%w2nEuX)p{~|L<~!r$ zcg892j9KrD+3$?A-x(LbGtPNuT=vemoWHDVHsBJvNx-;Ql_L2nm4)t*t~5hHsuZEv zxUktK$xAVMU?M2BP>fFRj97@TwZ#>tYzfL;b_?o)R7qWsg{hgzgf2gW%`{0q)Vd~V zFg}k>=sGi)K27S0Pjs5p2A>sa=rJ?ci8P`{=9n(Ygwm~qYkZeX2WW){jknB@+?C99 z=6H05v|l3fB{4SzKhgzBTHc6N(*O=y%~TRh%akINj->cxm52>VRc1;t9u%HVaQ$!C zF_W!b%$j`RWGM)t$|p;1wiJr=8W*Ht6m_2h_JFjeNbQvD^`Puw);UFLui!51T)L8A z=@c+3lr+m)#QyBu6rMlWz+q{Y)J6$0;9c266(by_Y^&o(RO!4`K7ME9w(wV;t<sjK2JhE4`|X)4{iPC`6LdI=CLLgHHgSISsnbgjX z7LYLQ!=!EF*!oVGckWpxjbla2(2<;%OWl~ma+o5QOMxtGd2P^6G}h?YmF1GjBM@Rv z5W>?RNkJs=Q=OoTm_burFl~&VGn|Cm{;MXnE5j)Qq|Lg zg~m&s4Jcc+_vWC(>oXc`cjJUx@oF4D49df>h4UfF`BF2xUe>7acmSemKzX3@P#*fQ zl6>izs;>tdR3LfE7gu6Hz`U`%K>C!g|v*P3xs0I3$hYgDTcb_Q7=4lKyCgjU@U&{3tvp>CwbO@ANkj^*XzM0W-(za7}qQozCn^zV?EfDRd^=S+k)mACx=+1W`bQ5Vj=0I zA)8%=gT>~JQj`Ey=E%x8%vHlTLt=5E8JE70x;iHRj~9vwhl^)_AcPJtS>pq)}CUyTN(6k`S7I1OrOZjddk!@rVlE5xY6vvU&kbnTV~ zz+PTgBxTuQ;_mW2#*s96&-ch*b3HMM4bFm?|EayN*+CP80D}uba@}ktD0nHbvTTsW( z#gn%Xi>{DY7T&p`lZF~x#Ws#Y0^%j92$7avl5ib(wj6v#!poU+lmzk85Y(q#lkx>N z?;5yKQMu$NC*1%uW5yd`@K?&EpKz2L^^5xwHznNGUBKchAQAbpT@{#UCqEf2Y zTkJlpHFPe$4%>LthLpmAuij#vE2UBIt(6BXYQV4PA7+mC(aBD--zue4u-}hvp}DZ3 zbxWFr{mn7Ar7U3)yL21US_=F7wiJWDHs+2rL1@j6-a*g%g#C60Gn!AyXFHbgn>3oW z|4nKSt!a`)vlLa}z)A{n^kRED#LD8|k(GYz#P5<$wakO9e~ovN?C+uh`>`f>rJkDQ z@Q<4kUphib+8bQPSacT?tvqIT56PNY@;xw(eysGK)J%H2=#OGjm5cb1h(=ZLwnUxp zgQfq#KDv*nS0HMvKT}qU?jwKs_a(95fwT(IuYQ1{<}=MhRKrTv>LCWe0{Et=hO_X8 zm^LuLU{-S5-3c42GvUwU?OH56QB^DHVqkM+(Vv3jmOYegJ5U~L+0Y31am9~%{c6NU zB(uhvNIt&wM{(q{29J>G!_5DYv;!Y(BDk?fkEAXBYpuR1<=UZ_MpH6VtcA7i?7PPh zpHH%xPb4pY@?Dz;(xXwEPr9W6&ZKcsQ0bsnst7Y+yQbfovrN-?%MR6!_O&jP9-!ztNkX(LrQ%ULD4s}8%duMXC8 zManDStfc(!yrom#uzm9fM&XJoDM7UXqCkk~%A%^Js0NnWawB7ER(%r}ZY!##NRJv| z`Xhm#YM>K-l(-!`_sp6PJ62had>Csa2YJa;sijJ3R%*_F2eN$^$d(CDArn~;$d359 zQlm_Ij^^4ZpLi}U7aCA9l)B<1$NeQ;w^8hfr*rQiFVSZX%j;f35XAS~E9tTdD-~b7 zk>(1UR<`o=5;lJu;<;3EjKwnJ&^p4io^^!uA+~km&GJLZ^AD9^l&^bx>ii)${x#6E zC7|yh&(CZiAIc$~v+?O1>KTv2zm`x>52542??XND^OC<0^$t4--dewbKCGT?Xul%0 zO0W%QG0yq`?|MUu)QyCCC4;=Zi`0z;O>CW@BDIsC={B%Pjk94*0Q-qmkj{!Cq)24k}VN5E^->7pWTxji&cA2N$XF zrd%>obrc**S#(FeSL=#i6uV<-FSFjK2oJ+FEFWUlHxEcm$;gaOiHY-`5}lqHJw7R} zNUakZn%Gwz^?otkdYOH~CQYDUk=j?VePSw7HxXpU={2B8-9~_R62mz7BcJUA^%A*rC;h7W5EIY$ z(*G&^B%kQ5cN8$1Uhkt{*`rCpV5&HwUl>ZP7KDU8MQV*8Oqx=pt}Cd9jHU{ydq`e6 zS8sIF?+Y)|sD=odv-AxSG*^e=8!BjSgyK6?&{VSD*XTPqMhpcUC8+gr_>LCTEm_O8 zdTqe;v4HV{Y9582AgEHN;hP|+mQTkwQBbYU!FM9|4~F17Nf0i}S!?w}1xL@3!1IJU zs9ud~zEI}}`EsG&EO_OHn1fq1kIT-COUXz~O=(W~S9j}2Eml`h$FK$K^+wy$q$0JQ zpe|WM!wFj%eLEo&=tUAF>GUAfrTNSB2gb$vw;0^jP z)qsBNpl>UTWnLCNJuwnx(fi}z$0ruOmz&!l zbN?ps(McI`O_Sp?6H;S~)L}xy&secVA0l|l4L9oRYHWfBnOWEdy$3UXt{;gDt)G6b zKP>zrhi=n1Xe2z9NAJ^LcW!ui;7V^pOYb6$%^AUFD(ibnAAw^pt54~Dygwg`0%&Z? zp%Ewn-@a+u)yWuxPmSF3v|c5sKM1qz zU`eI=rt+jx{U#@2i`=kM-xr;RMLyFn(0@OmNF&UEdL6W}FjEkYe~9la=u?WqH%AaI z$}gYk_w~Yd{ns500Z!6Tg?G@H2m4o(7Ef^5!3^1+{aTNQC*$jo0yWA zS)_IqR8Q*krru&Bd{m@%7gT@G^iPS)N{@?4O-Ge!1sm^e6FV6;;_lI;D~22XSIUBl zf?D;Oni-drI6j?vR7$Ymkrfo&t0>5iTc=EdO*%7OHMqDg2nsF=YDxAPaWR=7lZ;@& zWfog|)v%}kQzcNd-l@r^xRfcug4^LTid?ZsOo~G!`4rlZJR~P(#K6Z%^3a?tOi7a` zBqC{OHqX0eh=nBa;+nw+l7x8Ou)<*k`D;2PI(d9-bgyJ35h8af(54|6q|2ITqfdjna=v$FwnB- z;v0t1kO+Rq$HkX?v->dXu-QrZ{W- z4iA;M{K(1{WP#`%@>t_rhG?OmoO#PIQ^+YlcO&gi_mOAJ>%Mea+h*!d7K{H!DVgve zosnra?sacoF)=JsifMbL*Qa=sPuSCPLmr}N0iiT zys*#t@{J=i-3GT?aK6>#UB6o_Eh%7ZW_ny)NHo$M_v~<+KDl1&(yn=|=(pG*!D4Ck z*2BQexO8MWqVvT3Zh*i$^^F}5RL@)z#gnI6}W`f3vYps|6dHg>_pov}oh&%w0EMzKxq_?15cg`JUCnHKIwk+q z^yRlEx7hs0(VRh#*44l{Vroiebaq@i0v|gVR5NT{mkM9@=Ez~&+j`_E!rG(E#wY)b zE7=yO&EEbx;9{dG7Enpkh^$0(db4rPipBxo9Pu&ijyQ1o>#K1+K$8)Z#}g^HFc`l3 z>(;aOdD$bL$_E>Fqd=LQT%BfqGI;UD4|gx=^u-dtQ==@!7E5uiLHnckFgKZX_zI)$FWSjXXudgBtZYo zgywrzPF`AhruAoGhWFEoOEVis$8UV?{%7N;-j{dxyU=2A#Cy5Th>1>#N9B(Cwlp>^ zD(2>yuUo56XGK{ot!r}&f{jg0HXGMZ=rJqx-0<*`$)PouE{_7ws4X%pyJyhm99(lR zw(CcZm!$8GMSlBaXr{$ttc?P^Dh1pl#%%mM^xK@(D}Vkwyj`ck0h_Mdf-2v7icZe} z|27*BX9d~x{?j!w<(HhA%GksL5Pq$n)YPE&%BFOptp(>hfBbN8nCb*?Ir=}-IqjUIu9$Ql5{b$ER zu}KB37vCMk{2m&bI*hpZ{KlxxXPql!2WNdT=!_p5`_SO$AdH{==EMc31rOp(ZFk-+ z-p2|a8hjmoJv2RN(B~g_KK#{yIbFUA4rV7G8oIapCt3(9IdW{vM;_I_1xcDz@)THj-C<@c=1BSZI`Ig9t~|FPWv^u+mV|I^{(pw{m-4|s^# z*lSwb?-vhl=D%0d^%u`0KQ>l+Gj&UprSX68pkJ3>x%RjB&h`856tNELC~Y?GEb_eF z)#P$@`u>3zgO4UN3_jK&-E0ibm~6?t5vh)N-*y;^Fo^?jxtQ&Sqm<2XUcS#;)x- zevg`*xUl1w@LE?BHJCx?eW{-RiMSfKJ};m5UeN&cqXgwL47lC;FP;y!bL;A9bEsxz zn7FGpWtvi<(zR_%d>fdH+WvLNf3AMKBdDLJtPJ|gp5cR)RGn z^5n$KL`?9E8}l}7`(TmIG^_G@O`FrkEL441IyCrHshzo$E&FJDK;4H^#v&baL|exOBMP4()z4 z=FBIL7u?(Z^N3zkFcdZkArdhgg?mEI`oPHj6)mR)>$9%x7=wxlfk16GMt}O`Rcv_l zzB1R#bx!on{FWRb=9-P(fpXcg7200xO0Px{BhxXK`PB-#*&i|dK^ejgNllrM7#l}JeMZ@ZsW*pDK3u0{)Xp+h;Y8$U zNNP+p%_+=AQ&`)d6UVIRKlT17RbtqKA5r!pagYJb#%=-mjq|swbIe!f=^g(V^a#U@ zbzWdL*0?VnvUlfqep4=$HR%58V`S8CAW`<@7^Ju9w;u+X+pgR%#^!I6^ad{!a$rhK z(&X4UMaKN2L*WBs&R|PND2X#IE8T#uV|C`@RP^gBhZ^jjZhCU<>p92EcjN?ugV%Z> zvE6JOb>fJvu;8lYKySa&)X(-dA`ev5#CTaV=b0c&O9cCwaSlrHEcBsrFbwK zi${3=mUJ{Q!q`!k5}!Q$5M}C{G9`L)Hn@Sa`f_98j{bJyz5yQ3SL}zJ1t)WkaiHge zTL$r7>vdy~e^}`w$|!7KbVed9v+?q!qn<(Xs&7hFr-UP8HW*RZKB+ON3JgZbYH8kW z^}^xZJM5l#e#`;$YxFsvK1mSX96tyg_PPJ_wb$?eHmdFTA@RsZA7vJW(S7o(uI6t? zpISOEb>*p(+jAg8`1Og-j82a;p;ZoQ_pUYW+PmZIwrMBsH8j;j(Ry=QZE)75PKH-m zRhLf#_f4y`4+0VN#;h?hBa@`XxIbrSM&$gw?)N`dty!#FHUtU6H9ir%ymX=e$zQTF zUwoeP*fmErl8Ex%JQ3w@t?%6S#)VDaAHLlDnvaX-P2O{y7$=& z$2zp_fPO`e3j1}Kv0w7p`eWXjSs`<-E$DZ`>V_$+*|^{B!`2}?UM;xUc}e20eOJ{7 z6;Qa?sVPZ`DG=-G?YQX_+9|ZbrJVDrN6Qxuh@o61XO62KF-P}qy7JA+>$}efP0Oy+ zX5tjZIrXjcr!~;=Q~ZhkL_@<6Tr|P=(2VJAA$z^=Wr!kzbh)wJcaA1sujwQNYQJ`XEUc`h zK-`_RZGF_TetX5-BTd{get-SUVrlz+@P1Z#Vc3xI1CLfdyc1nDwBx{qbDpCIyuVU_ zadukP*hxaaAtO7Vd^04l83ZN8gDE;@QuGAs-HprV-z(4dx%SZ?^~czZE&x6F^%|k9 zO;GLE#4MfqptyhH_~VC1dbCudCXZjE2JS>rz6%`|R$?5qAO;UZi$xT4^H zJxu8Fv7dHy_?Fdyc`1$^QR%%nU9XtXHXu8qQTMY=d;L{Drq>}*N^oXo`nZI+BxRn{ zG-=veukY%_yR;b?cGl%ZB1#gRkx60Em`N?25BlGK@%;1i4;#Jo>=6q(faBXa($($3 z4))J1 zvCliOw(-%%XZAFmj;3l7oRX3XMjG1bz}zYOcdkG7#9j0_Jo`#e@1cGA){$N>VuSuP NcnR5T;-3cZ{|CmJ-=+Wn diff --git a/boot/ocamllex b/boot/ocamllex index 1b3e201ed4082b6f8853f9973d9a8f06fe039662..cd31e4c693079aaf6d427b0c92c14136bb4cce2e 100755 GIT binary patch delta 1178 zcmYk4drVVj7{-MjF2fBvE}Dqzq+F$x9;k(Zc3cA~LV+=16Pn~iXh zpdKcAfN}Zclv0M%k`QnNZE!Lq83F>^CjUcZ%N#bBh#;XLI#?JJ5YxkI zUUtR3KOJQzqKbrgaI1&HUrJW@4VeS$u;_-MtryTd98PhZG{*Rj#w~O^-DDuWQ^Ye8 za-%Cgb?XVQJ(;g=yt_1*aHkV{0%50THio)+_*Mmxdp^^W1Y-y~U{B5rCa_~|92&A7I={L8vANPqcsD)B-K z@wxtg-+t~~8}|x3=#4R57*$&!Nb)l?Q3Vc1t9HS$0qz|AD0^j_&qOMb*#_~|&$c5b z|16YM;c9int7+YK3v)z4p<4l~K}?6((A5RPv*y<@+D4V%HWP;nQ*ZIU8mpcC_uNPP z$|!>$0A7?NrkJa6*eUE_K~{+IrG-dj!ro_z8eEFGJ#)SP!%MS{7qBbo)J!Z|n1xbO2&ajS4$r|)hjhbC(@|=jJ0)%8P+2CV zs9&7(HXd4j<@%$!_Z+n@LWxr0$r6p^MYiVWM zzLt#U*&6ble5q5ECd;8tHFiBINbTx8#6L_ZrWfm(0KgH5OiI-QRmc%(?AxlucwP1mEa7ju|W>S27ab@uY192P0NBp)fFSmSEoANj6?&j$ni&?YU|ZgXL2rnvV*`P48LEVruZtP;qm**2bx&y${dn zO$ty#wjs4}f+~0;6*MzFfT?ePp`o z5}@e5SuawoLj|wO?mQl{^__po^vESF8UlyP9hjZJiG}1{tN-#aC3D*JiAz}I1eQ*_ zWEu9_JK(Q{V(agA_pa&tm#~Nl>}1+KBUb;RQl|e5)x}GBzD|F-ghk8Xq~Hcyqtq!P z4}A`(n-oThA-OR(v0#G1!LOTQM3Vp9+~Lw=nd>T}H{E_Ii+Vi|e_rn@_PCZ(ZXEYO36T~2C6W?uRP1E0ll&wkjn|NeY!k)CPj<8uoZ=)jdER#i?gcy^&^hhJjC z|M%Q1Tg3Ov7cE$z3saDpS7K%|!C*288AQ@lN$e@ye!=IDz(69&GQ4>rXN}c4E+21s~x7QJPbz zXzZ6g&#w95uIXvZS#0Z@Iydgvb64|BR_p9vrdPc5kitB%2pDuuRYtoyz120huv%Y} zJG@5-l$60KbAo|}(60xx#jTtgcph(Q*4TM^!2%7SR6H=uOC}hs*&z4Wx;!}87e`t89)~q2hbFwwGYBeQut3E(F*9$1fx^lqe9I=)JehDo z&xmQKpa4*hPijSaDo{$~#$VSpg%{QoF+UWq?P>rfd{v+n$Q@qj4fJ)Iw>U7P>4WWfS;=ltA)#AKk{FW1$J?@lqCF_Cpw zs&jIm4bUo}Ty8$lssp+gT0Pt5GNtdBcSHaHO c#0A2Al01(-eElTxgTI+)d(+qHWh+@c0Vc>8k^lez diff --git a/bytecomp/translcore.ml b/bytecomp/translcore.ml index fa1ddbeb..0da506f8 100644 --- a/bytecomp/translcore.ml +++ b/bytecomp/translcore.ml @@ -48,7 +48,8 @@ let prim_fresh_oo_id = let transl_extension_constructor env path ext = let path = - Stdlib.Option.map (Printtyp.rewrite_double_underscore_paths env) path + Printtyp.wrap_printing_env env ~error:true (fun () -> + Stdlib.Option.map (Printtyp.rewrite_double_underscore_paths env) path) in let name = match path, !Clflags.for_package with diff --git a/byterun/freelist.c b/byterun/freelist.c index 915eb9f9..4782800e 100644 --- a/byterun/freelist.c +++ b/byterun/freelist.c @@ -338,7 +338,7 @@ header_t *caml_fl_allocate (mlsize_t wo_sz) mlsize_t oldsz = sz; prev = flp[i]; - while (prev != flp[i+1]){ + while (prev != flp[i+1] && j < FLP_MAX - i){ cur = Next (prev); sz = Wosize_bp (cur); if (sz > prevsz){ diff --git a/stdlib/array.ml b/stdlib/array.ml index d29a04fa..a693f4a7 100644 --- a/stdlib/array.ml +++ b/stdlib/array.ml @@ -334,7 +334,7 @@ let of_rev_list = function [] -> a | hd::tl -> unsafe_set a i hd; fill (i-1) tl in - fill (len-1) tl + fill (len-2) tl let of_seq i = let l = Seq.fold_left (fun acc x -> x::acc) [] i in diff --git a/testsuite/tests/lib-seq/test.ml b/testsuite/tests/lib-seq/test.ml index 934a001e..ca38d466 100644 --- a/testsuite/tests/lib-seq/test.ml +++ b/testsuite/tests/lib-seq/test.ml @@ -13,6 +13,15 @@ let () = () ;; +(* MPR 7820 *) +let () = + assert + ([| 1;2;3 |] = + (Array.to_seq [| 1;2;3 |] + |> Array.of_seq)); + () +;; + let () = print_endline "OK";; diff --git a/testsuite/tests/typing-gadts/gpr1997.ml b/testsuite/tests/typing-gadts/gpr1997.ml new file mode 100644 index 00000000..8a9b6c95 --- /dev/null +++ b/testsuite/tests/typing-gadts/gpr1997.ml @@ -0,0 +1,53 @@ +(* TEST + * expect +*) + +module M : sig + type 'a t + + type _ typ = + | Foo : 'a -> [`Foo of 'a] typ + | Bar : string -> [`Bar] typ + + val use_bar : [`Bar] t -> int + + val foo : [`Foo of int] t + +end = struct + type 'a t = string + + type _ typ = + | Foo : 'a -> [`Foo of 'a] typ + | Bar : string -> [`Bar] typ + + let foo = "foo" + + let use_bar _ = 0 +end;; +[%%expect {| +module M : + sig + type 'a t + type _ typ = + Foo : 'a -> [ `Foo of 'a ] typ + | Bar : string -> [ `Bar ] typ + val use_bar : [ `Bar ] t -> int + val foo : [ `Foo of int ] t + end +|}];; + +let go (type a) (typ : a M.typ) (msg : a M.t) = + match typ with + | Bar s -> + (match M.use_bar msg with _ -> ()) +;; +[%%expect {| +Line _, characters 2-68: + ..match typ with + | Bar s -> + (match M.use_bar msg with _ -> ()) +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +Foo _ +val go : 'a M.typ -> 'a M.t -> unit = +|}];; diff --git a/testsuite/tests/typing-gadts/ocamltests b/testsuite/tests/typing-gadts/ocamltests index ace6ac47..908c01f5 100644 --- a/testsuite/tests/typing-gadts/ocamltests +++ b/testsuite/tests/typing-gadts/ocamltests @@ -46,3 +46,4 @@ test.ml unify_mb.ml variables_in_mcomp.ml yallop_bugs.ml +gpr1997.ml diff --git a/testsuite/tests/typing-gadts/pr7222.ml b/testsuite/tests/typing-gadts/pr7222.ml index 290f4448..4316e10e 100644 --- a/testsuite/tests/typing-gadts/pr7222.ml +++ b/testsuite/tests/typing-gadts/pr7222.ml @@ -38,7 +38,6 @@ Line _, characters 6-22: let Cons(Elt dim, _) = sh in () ^^^^^^^^^^^^^^^^ Error: This pattern matches values of type ('a -> $0 -> nil) t - but a pattern was expected which matches values of type - ('a -> 'b -> nil) t + but a pattern was expected which matches values of type 'b The type constructor $0 would escape its scope |}];; diff --git a/testsuite/tests/typing-misc/variant.ml b/testsuite/tests/typing-misc/variant.ml index 00ad4ea3..9564f36a 100644 --- a/testsuite/tests/typing-misc/variant.ml +++ b/testsuite/tests/typing-misc/variant.ml @@ -26,3 +26,19 @@ Error: Signature mismatch: is not included in type t = int * bool |}];; + + +(* PR#7838 *) + +module Make (X : sig val f : [ `A ] -> unit end) = struct + let make f1 f2 arg = match arg with `A -> f1 arg; f2 arg + let f = make X.f (fun _ -> ()) +end;; +[%%expect{| +module Make : + functor (X : sig val f : [ `A ] -> unit end) -> + sig + val make : (([< `A ] as 'a) -> 'b) -> ('a -> 'c) -> 'a -> 'c + val f : [ `A ] -> unit + end +|}] diff --git a/testsuite/tests/typing-modules/ocamltests b/testsuite/tests/typing-modules/ocamltests index 24dd8694..1b548b20 100644 --- a/testsuite/tests/typing-modules/ocamltests +++ b/testsuite/tests/typing-modules/ocamltests @@ -7,6 +7,7 @@ pr6394.ml pr7207.ml pr7348.ml pr7787.ml +pr7818.ml printing.ml recursive.ml Test.ml diff --git a/testsuite/tests/typing-modules/pr7818.ml b/testsuite/tests/typing-modules/pr7818.ml new file mode 100644 index 00000000..166faf8e --- /dev/null +++ b/testsuite/tests/typing-modules/pr7818.ml @@ -0,0 +1,319 @@ +(* TEST + * expect +*) + +(* cannot_alias.ml *) +module Termsig = struct + module Term0 = struct + module type S = sig + module Id : sig end + end + end + module Term = struct + module type S = sig + module Term0 : Term0.S + module T = Term0 + end + end +end;; +[%%expect{| +module Termsig : + sig + module Term0 : sig module type S = sig module Id : sig end end end + module Term : + sig module type S = sig module Term0 : Term0.S module T = Term0 end end + end +|}] + +module Make1 (T' : Termsig.Term.S) = struct + module T = struct + include T'.T + let u = 1 + end +end;; +[%%expect{| +module Make1 : + functor + (T' : sig + module Term0 : Termsig.Term0.S + module T : sig module Id : sig end end + end) -> + sig module T : sig module Id : sig end val u : int end end +|}] + +module Make2 (T' : Termsig.Term.S) = struct + module T = struct + include T'.T + module Id2 = Id + let u = 1 + end +end;; +[%%expect{| +module Make2 : + functor + (T' : sig + module Term0 : Termsig.Term0.S + module T : sig module Id : sig end end + end) -> + sig + module T : sig module Id : sig end module Id2 = Id val u : int end + end +|}] + +module Make3 (T' : Termsig.Term.S) = struct + module T = struct + include T'.T + module Id2 = Id + let u = 1 + let u = 1 + end +end;; +[%%expect{| +module Make3 : + functor + (T' : sig + module Term0 : Termsig.Term0.S + module T : sig module Id : sig end end + end) -> + sig + module T : sig module Id : sig end module Id2 = Id val u : int end + end +|}] + +(* cannot_alias2.ml *) +module type S = sig + module Term0 : sig module Id : sig end end + module T = Term0 +end;; + +module Make1 (T' : S) = struct + module Id = T'.T.Id + module Id2 = Id +end;; +[%%expect{| +module type S = + sig module Term0 : sig module Id : sig end end module T = Term0 end +module Make1 : + functor + (T' : sig + module Term0 : sig module Id : sig end end + module T : sig module Id : sig end end + end) -> + sig module Id : sig end module Id2 = Id end +|}] + +module Make2 (T' : S) : sig module Id : sig end module Id2 = Id end + with module Id := T'.Term0.Id = struct + module Id = T'.T.Id + module Id2 = Id +end;; +[%%expect{| +Line _, characters 57-107: + .........................................................struct + module Id = T'.T.Id + module Id2 = Id + end.. +Error: Signature mismatch: + Modules do not match: + sig module Id : sig end module Id2 = Id end + is not included in + sig module Id2 = T'.Term0.Id end + In module Id2: + Module T'.Term0.Id cannot be aliased +|}] + +module Make3 (T' : S) = struct + module T = struct + module Id = T'.T.Id + module Id2 = Id + let u = 1 + let u = 1 + end +end;; +[%%expect{| +module Make3 : + functor + (T' : sig + module Term0 : sig module Id : sig end end + module T : sig module Id : sig end end + end) -> + sig + module T : sig module Id : sig end module Id2 = Id val u : int end + end +|}] + +(* unsoundness if Make1 returned an Id.x field *) +module M = Make1 (struct module Term0 = + struct module Id = struct let x = "a" end end module T = Term0 end);; +M.Id.x;; +[%%expect{| +module M : sig module Id : sig end module Id2 = Id end +Line _, characters 0-6: + M.Id.x;; + ^^^^^^ +Error: Unbound value M.Id.x +|}] + + +(* cannot_alias3.ml *) +module MkT(X : sig end) = struct type t end +module type S = sig + module Term0 : sig module Id : sig end end + module T = Term0 + type t = MkT(T).t +end;; + +module Make1 (T' : S) = struct + module Id = T'.T.Id + module Id2 = Id + type t = T'.t +end;; + +module IS = struct + module Term0 = struct module Id = struct let x = "a" end end + module T = Term0 + type t = MkT(T).t +end;; + +module M = Make1(IS);; +[%%expect{| +module MkT : functor (X : sig end) -> sig type t end +module type S = + sig + module Term0 : sig module Id : sig end end + module T = Term0 + type t = MkT(T).t + end +module Make1 : + functor + (T' : sig + module Term0 : sig module Id : sig end end + module T : sig module Id : sig end end + type t = MkT(T).t + end) -> + sig module Id : sig end module Id2 = Id type t = T'.t end +module IS : + sig + module Term0 : sig module Id : sig val x : string end end + module T = Term0 + type t = MkT(T).t + end +module M : sig module Id : sig end module Id2 = Id type t = IS.t end +|}] + + +(* cannot_alias4.ml *) +(* Can be used to break module abstraction *) +(* Still sound ? *) +(* It seems to only work if Term0 and Term contain identical types *) +(* It may also be possible to do the same thing using + Mtype.nondep_supertype anyway *) +type (_,_) eq = Eq : ('a,'a) eq +module MkT(X : Set.OrderedType) = Set.Make(X) +module type S = sig + module Term0 : Set.OrderedType with type t = int + module T = Term0 + type t = E of (MkT(T).t,MkT(T).t) eq + type u = t = E of (MkT(Term0).t,MkT(T).t) eq +end;; +module F(X:S) = X;; +module rec M : S = M;; +module M' = F(M);; +module type S' = module type of M';; +module Asc = struct type t = int let compare x y = x - y end;; +module Desc = struct type t = int let compare x y = y - x end;; +module rec M1 : S' with module Term0 := Asc and module T := Desc = M1;; +(* And now we have a witness of MkT(Asc).t = MkT(Desc).t ... *) +let (E eq : M1.u) = (E Eq : M1.t);; +[%%expect{| +type (_, _) eq = Eq : ('a, 'a) eq +module MkT : + functor (X : Set.OrderedType) -> + sig + type elt = X.t + type t = Set.Make(X).t + val empty : t + val is_empty : t -> bool + val mem : elt -> t -> bool + val add : elt -> t -> t + val singleton : elt -> t + val remove : elt -> t -> t + val union : t -> t -> t + val inter : t -> t -> t + val diff : t -> t -> t + val compare : t -> t -> int + val equal : t -> t -> bool + val subset : t -> t -> bool + val iter : (elt -> unit) -> t -> unit + val map : (elt -> elt) -> t -> t + val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a + val for_all : (elt -> bool) -> t -> bool + val exists : (elt -> bool) -> t -> bool + val filter : (elt -> bool) -> t -> t + val partition : (elt -> bool) -> t -> t * t + val cardinal : t -> int + val elements : t -> elt list + val min_elt : t -> elt + val min_elt_opt : t -> elt option + val max_elt : t -> elt + val max_elt_opt : t -> elt option + val choose : t -> elt + val choose_opt : t -> elt option + val split : elt -> t -> t * bool * t + val find : elt -> t -> elt + val find_opt : elt -> t -> elt option + val find_first : (elt -> bool) -> t -> elt + val find_first_opt : (elt -> bool) -> t -> elt option + val find_last : (elt -> bool) -> t -> elt + val find_last_opt : (elt -> bool) -> t -> elt option + val of_list : elt list -> t + val to_seq_from : elt -> t -> elt Seq.t + val to_seq : t -> elt Seq.t + val add_seq : elt Seq.t -> t -> t + val of_seq : elt Seq.t -> t + end +module type S = + sig + module Term0 : sig type t = int val compare : t -> t -> int end + module T = Term0 + type t = E of (MkT(T).t, MkT(T).t) eq + type u = t = E of (MkT(Term0).t, MkT(T).t) eq + end +module F : + functor + (X : sig + module Term0 : sig type t = int val compare : t -> t -> int end + module T : sig type t = int val compare : t -> t -> int end + type t = E of (MkT(T).t, MkT(T).t) eq + type u = t = E of (MkT(Term0).t, MkT(T).t) eq + end) -> + sig + module Term0 : sig type t = int val compare : t -> t -> int end + module T : sig type t = int val compare : t -> t -> int end + type t = X.t = E of (MkT(T).t, MkT(T).t) eq + type u = t = E of (MkT(Term0).t, MkT(T).t) eq + end +module rec M : S +module M' : + sig + module Term0 : sig type t = int val compare : t -> t -> int end + module T : sig type t = int val compare : t -> t -> int end + type t = M.t = E of (MkT(T).t, MkT(T).t) eq + type u = t = E of (MkT(Term0).t, MkT(T).t) eq + end +module type S' = + sig + module Term0 : sig type t = int val compare : t -> t -> int end + module T : sig type t = int val compare : t -> t -> int end + type t = M.t = E of (MkT(T).t, MkT(T).t) eq + type u = t = E of (MkT(Term0).t, MkT(T).t) eq + end +module Asc : sig type t = int val compare : int -> int -> int end +module Desc : sig type t = int val compare : int -> int -> int end +module rec M1 : + sig + type t = M.t = E of (MkT(Desc).t, MkT(Desc).t) eq + type u = t = E of (MkT(Asc).t, MkT(Desc).t) eq + end +val eq : (MkT(Asc).t, MkT(Desc).t) eq = Eq +|}] diff --git a/testsuite/tests/typing-objects/Tests.ml b/testsuite/tests/typing-objects/Tests.ml index 0777d1d4..e187c566 100644 --- a/testsuite/tests/typing-objects/Tests.ml +++ b/testsuite/tests/typing-objects/Tests.ml @@ -886,3 +886,33 @@ Line _, characters 10-37: ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: This kind of recursive class expression is not allowed |}];; + +(* More tests about recursion in class declarations *) +class a = let _x() = new a in object end;; +[%%expect{| +class a : object end +|}];; + +class a = object end +and b = let _x() = new a in object end;; +[%%expect{| +class a : object end +and b : object end +|}];; + +class a = let x() = new a in let y = x() in object end;; +[%%expect{| +Line _, characters 10-54: + class a = let x() = new a in let y = x() in object end;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This kind of recursive class expression is not allowed +|}];; + +class a = object end +and b = let x() = new a in let y = x() in object end;; +[%%expect{| +Line _, characters 8-52: + and b = let x() = new a in let y = x() in object end;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This kind of recursive class expression is not allowed +|}];; diff --git a/testsuite/tests/typing-polyvariants-bugs/ocamltests b/testsuite/tests/typing-polyvariants-bugs/ocamltests index d589e6c1..5ea661d0 100644 --- a/testsuite/tests/typing-polyvariants-bugs/ocamltests +++ b/testsuite/tests/typing-polyvariants-bugs/ocamltests @@ -3,4 +3,5 @@ pr4933_ok.ml pr5057_ok.ml pr5057a_bad.ml pr7199_ok.ml +pr7824.ml privrowsabate_ok.ml diff --git a/testsuite/tests/typing-polyvariants-bugs/pr7824.ml b/testsuite/tests/typing-polyvariants-bugs/pr7824.ml new file mode 100644 index 00000000..2592b4b5 --- /dev/null +++ b/testsuite/tests/typing-polyvariants-bugs/pr7824.ml @@ -0,0 +1,78 @@ +(* TEST + * expect +*) + +module Element : sig + type +'a t + + val from_a : [`A] t -> unit + val from_ab : [< `A | `B] t -> unit + + val to_a : unit -> [`A] t + val to_ab : unit -> [< `A | `B] t +end = struct + type +'a t + + let from_a x = assert false + let from_ab x = assert false + + let to_a x = assert false + let to_ab x = assert false +end ;; +[%%expect{| +module Element : + sig + type +'a t + val from_a : [ `A ] t -> unit + val from_ab : [< `A | `B ] t -> unit + val to_a : unit -> [ `A ] t + val to_ab : unit -> [< `A | `B ] t + end +|}];; + +let f x = + Element.from_a x; + Element.from_ab x; + match [] with + | _::_ -> (x :> [`A | `C] Element.t) +;; +[%%expect{| +Line _, characters 2-54: + ..match [] with + | _::_ -> (x :> [`A | `C] Element.t) +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +[] +val f : [ `A ] Element.t -> [ `A | `C ] Element.t = +|}];; + +type _ t = T : 'a -> 'a t + +let f x = + Element.from_a x; + Element.from_ab x; + match T () with + | T _ -> (x :> [`A | `C] Element.t) +;; +[%%expect{| +type _ t = T : 'a -> 'a t +val f : [ `A ] Element.t -> [ `A | `C ] Element.t = +|}];; + +let f () = + let open Element in + let x = if true then to_ab () else to_a () in + (x :> [ `A | `C ] Element.t) +;; +[%%expect{| +val f : unit -> [ `A | `C ] Element.t = +|}];; + +let f () = + let open Element in + let x = if true then to_a () else to_ab () in + (x :> [ `A | `C ] Element.t) +;; +[%%expect{| +val f : unit -> [ `A | `C ] Element.t = +|}];; diff --git a/typing/ctype.ml b/typing/ctype.ml index f24e46d1..ce4e584e 100644 --- a/typing/ctype.ml +++ b/typing/ctype.ml @@ -684,8 +684,15 @@ let forward_try_expand_once = (* Forward declaration *) module M = struct type t let _ = (x : t list ref) end (without this constraint, the type system would actually be unsound.) *) -let get_path_scope p = - Path.binding_time p +let get_path_scope env p = + try + match (Env.find_type p env).type_newtype_level with + | None -> Path.binding_time p + | Some (x, _) -> x + with + | Not_found -> + (* no newtypes in predef *) + Path.binding_time p let rec normalize_package_path env p = let t = @@ -745,7 +752,7 @@ let rec update_level env level expand ty = | None -> () end; match ty.desc with - Tconstr(p, _tl, _abbrev) when level < get_path_scope p -> + Tconstr(p, _tl, _abbrev) when level < get_path_scope env p -> (* Try first to replace an abbreviation by its expansion. *) begin try link_type ty (!forward_try_expand_once env ty); @@ -767,13 +774,13 @@ let rec update_level env level expand ty = log_type ty; ty.desc <- Tpackage (p', nl, tl); update_level env level expand ty | Tobject(_, ({contents=Some(p, _tl)} as nm)) - when level < get_path_scope p -> + when level < get_path_scope env p -> set_name nm None; update_level env level expand ty | Tvariant row -> let row = row_repr row in begin match row.row_name with - | Some (p, _tl) when level < get_path_scope p -> + | Some (p, _tl) when level < get_path_scope env p -> log_type ty; ty.desc <- Tvariant {row with row_name = None} | _ -> () @@ -1027,7 +1034,7 @@ let rec copy ?partial ?keep_names ty = match more.desc with Tsubst ty -> ty | Tconstr _ | Tnil -> - if keep then save_desc more more.desc; + save_desc more more.desc; copy more | Tvar _ | Tunivar _ -> save_desc more more.desc; @@ -1129,7 +1136,7 @@ let get_new_abstract_name s = if index = 0 && s <> "" && s.[String.length s - 1] <> '$' then s else Printf.sprintf "%s%d" s index -let new_declaration expansion_scope manifest = +let new_declaration newtype manifest = { type_params = []; type_arity = 0; @@ -1137,8 +1144,7 @@ let new_declaration expansion_scope manifest = type_private = Public; type_manifest = manifest; type_variance = []; - type_is_newtype = true; - type_expansion_scope = expansion_scope; + type_newtype_level = newtype; type_loc = Location.none; type_attributes = []; type_immediate = false; @@ -1148,9 +1154,9 @@ let new_declaration expansion_scope manifest = let instance_constructor ?in_pattern cstr = begin match in_pattern with | None -> () - | Some (env, expansion_scope) -> + | Some (env, newtype_lev) -> let process existential = - let decl = new_declaration (Some expansion_scope) None in + let decl = new_declaration (Some (newtype_lev, newtype_lev)) None in let name = match repr existential with {desc = Tvar (Some name)} -> "$" ^ cstr.cstr_name ^ "_'" ^ name @@ -1943,19 +1949,26 @@ let deep_occur t0 ty = information is indeed lost, but it probably does not worth it. *) +let newtype_level = ref None + +let get_newtype_level () = + match !newtype_level with + | None -> assert false + | Some x -> x + (* a local constraint can be added only if the rhs of the constraint does not contain any Tvars. They need to be removed using this function *) let reify env t = + let newtype_level = get_newtype_level () in let create_fresh_constr lev name = + let decl = new_declaration (Some (newtype_level, newtype_level)) None in let name = match name with Some s -> "$'"^s | _ -> "$" in let path = Path.Pident (Ident.create (get_new_abstract_name name)) in - let binding_time = Ident.current_time () in - let decl = new_declaration (Some binding_time) None in let new_env = Env.add_local_type path decl !env in let t = newty2 lev (Tconstr (path,[],ref Mnil)) in env := new_env; - t, binding_time + t in let visited = ref TypeSet.empty in let rec iterator ty = @@ -1964,9 +1977,9 @@ let reify env t = visited := TypeSet.add ty !visited; match ty.desc with Tvar o -> - let t, binding_time = create_fresh_constr ty.level o in + let t = create_fresh_constr ty.level o in link_type ty t; - if ty.level < binding_time then + if ty.level < newtype_level then raise (Unify [t, newvar2 ty.level]) | Tvariant r -> let r = row_repr r in @@ -1975,11 +1988,11 @@ let reify env t = let m = r.row_more in match m.desc with Tvar o -> - let t, binding_time = create_fresh_constr m.level o in + let t = create_fresh_constr m.level o in let row = {r with row_fields=[]; row_fixed=true; row_more = t} in link_type m (newty2 m.level (Tvariant row)); - if m.level < binding_time then + if m.level < newtype_level then raise (Unify [t, newvar2 m.level]) | _ -> assert false end; @@ -1995,14 +2008,14 @@ let reify env t = let is_newtype env p = try let decl = Env.find_type p env in - decl.type_expansion_scope <> None && + decl.type_newtype_level <> None && decl.type_kind = Type_abstract && decl.type_private = Public with Not_found -> false let non_aliasable p decl = (* in_pervasives p || (subsumed by in_current_module) *) - in_current_module p && not decl.type_is_newtype + in_current_module p && decl.type_newtype_level = None let is_instantiable env p = try @@ -2245,27 +2258,22 @@ let find_lowest_level ty = end in find ty; unmark_type ty; !lowest -let find_expansion_scope env path = - match (Env.find_type path env).type_expansion_scope with - | Some x -> x - | None -> assert false - -let gadt_equations_level = ref None - -let get_gadt_equations_level () = - match !gadt_equations_level with +let find_expansion_level env path = + (* always guarded by a call to [is_newtype], so we *always* have a newtype + level. *) + match (Env.find_type path env).type_newtype_level with + | Some (_, x) -> x | None -> assert false - | Some x -> x let add_gadt_equation env source destination = (* Format.eprintf "@[add_gadt_equation %s %a@]@." (Path.name source) !Btype.print_raw destination; *) if local_non_recursive_abbrev !env source destination then begin let destination = duplicate_type destination in - let expansion_scope = - max (Path.binding_time source) (get_gadt_equations_level ()) + let source_lev = get_path_scope !env source in + let decl = + new_declaration (Some (source_lev, get_newtype_level ())) (Some destination) in - let decl = new_declaration (Some expansion_scope) (Some destination) in env := Env.add_local_type source decl !env; cleanup_abbrev () end @@ -2412,7 +2420,7 @@ let rec unify (env:Env.t ref) t1 t2 = && is_newtype !env p1 && is_newtype !env p2 -> (* Do not use local constraints more than necessary *) begin try - if find_expansion_scope !env p1 > find_expansion_scope !env p2 then + if find_expansion_level !env p1 > find_expansion_level !env p2 then unify env t1 (try_expand_once !env t2) else unify env (try_expand_once !env t1) t2 @@ -2532,7 +2540,7 @@ and unify3 env t1 t1' t2 t2' = when is_instantiable !env path && is_instantiable !env path' && !generate_equations -> let source, destination = - if get_path_scope path > get_path_scope path' + if get_path_scope !env path > get_path_scope !env path' then path , t2' else path', t1' in @@ -2860,16 +2868,16 @@ let unify env ty1 ty2 = undo_compress snap; raise (Unification_recursive_abbrev (expand_trace !env [(ty1,ty2)])) -let unify_gadt ~equations_level:lev (env:Env.t ref) ty1 ty2 = +let unify_gadt ~newtype_level:lev (env:Env.t ref) ty1 ty2 = try univar_pairs := []; - gadt_equations_level := Some lev; + newtype_level := Some lev; set_mode_pattern ~generate:true ~injective:true (fun () -> unify env ty1 ty2); - gadt_equations_level := None; + newtype_level := None; TypePairs.clear unify_eq_set; with e -> - gadt_equations_level := None; + newtype_level := None; TypePairs.clear unify_eq_set; raise e @@ -4132,6 +4140,8 @@ and subtype_row env trace row1 row2 cstrs = let row1 = row_repr row1 and row2 = row_repr row2 in let r1, r2, pairs = merge_row_fields row1.row_fields row2.row_fields in + let r1 = if row2.row_closed then filter_row_fields false r1 else r1 in + let r2 = if row1.row_closed then filter_row_fields false r2 else r2 in let more1 = repr row1.row_more and more2 = repr row2.row_more in match more1.desc, more2.desc with @@ -4483,8 +4493,7 @@ let nondep_type_decl env mid id is_covariant decl = type_manifest = tm; type_private = priv; type_variance = decl.type_variance; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = decl.type_loc; type_attributes = decl.type_attributes; type_immediate = decl.type_immediate; diff --git a/typing/ctype.mli b/typing/ctype.mli index e22d2694..c4d1e55f 100644 --- a/typing/ctype.mli +++ b/typing/ctype.mli @@ -169,7 +169,7 @@ val enforce_constraints: Env.t -> type_expr -> unit val unify: Env.t -> type_expr -> type_expr -> unit (* Unify the two types given. Raise [Unify] if not possible. *) -val unify_gadt: equations_level:int -> Env.t ref -> type_expr -> type_expr -> unit +val unify_gadt: newtype_level:int -> Env.t ref -> type_expr -> type_expr -> unit (* Unify the two types given and update the environment with the local constraints. Raise [Unify] if not possible. *) val unify_var: Env.t -> type_expr -> type_expr -> unit diff --git a/typing/datarepr.ml b/typing/datarepr.ml index 7bef64c9..052e7417 100644 --- a/typing/datarepr.ml +++ b/typing/datarepr.ml @@ -85,8 +85,7 @@ let constructor_args priv cd_args cd_res path rep = type_private = priv; type_manifest = None; type_variance = List.map (fun _ -> Variance.full) type_params; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = Location.none; type_attributes = []; type_immediate = false; diff --git a/typing/env.ml b/typing/env.ml index cf5207ee..f49a8478 100644 --- a/typing/env.ml +++ b/typing/env.ml @@ -1051,7 +1051,7 @@ let find_type_expansion path env = | Some body when decl.type_private = Public || decl.type_kind <> Type_abstract || Btype.has_constr_row body -> - (decl.type_params, body, decl.type_expansion_scope) + (decl.type_params, body, may_map snd decl.type_newtype_level) (* The manifest type of Private abstract data types without private row are still considered unknown to the type system. Hence, this case is caught by the following clause that also handles @@ -1067,8 +1067,7 @@ let find_type_expansion_opt path env = match decl.type_manifest with (* The manifest type of Private abstract data types can still get an approximation using their manifest type. *) - | Some body -> - (decl.type_params, body, decl.type_expansion_scope) + | Some body -> (decl.type_params, body, may_map snd decl.type_newtype_level) | _ -> raise Not_found let find_modtype_expansion path env = diff --git a/typing/mtype.ml b/typing/mtype.ml index c923fd33..f22ac743 100644 --- a/typing/mtype.ml +++ b/typing/mtype.ml @@ -423,41 +423,57 @@ let collect_arg_paths mty = PathSet.fold (fun p -> Ident.Set.union (collect_ids !subst !bindings p)) !paths Ident.Set.empty -let rec remove_aliases_mty env excl mty = - match mty with - Mty_signature sg -> - Mty_signature (remove_aliases_sig env excl sg) - | Mty_alias _ -> - let mty' = Env.scrape_alias env mty in - if mty' = mty then mty else - remove_aliases_mty env excl mty' - | mty -> - mty +type remove_alias_args = + { mutable modified: bool; + exclude: Ident.t -> Path.t -> bool; + scrape: Env.t -> module_type -> module_type } + +let rec remove_aliases_mty env args mty = + let args' = {args with modified = false} in + let mty' = + match args.scrape env mty with + Mty_signature sg -> + Mty_signature (remove_aliases_sig env args' sg) + | Mty_alias _ -> + let mty' = Env.scrape_alias env mty in + if mty' = mty then mty else + (args'.modified <- true; remove_aliases_mty env args' mty') + | mty -> + mty + in + if args'.modified then (args.modified <- true; mty') else mty -and remove_aliases_sig env excl sg = +and remove_aliases_sig env args sg = match sg with [] -> [] | Sig_module(id, md, rs) :: rem -> let mty = match md.md_type with - Mty_alias _ when Ident.Set.mem id excl -> + Mty_alias (_, p) when args.exclude id p -> md.md_type | mty -> - remove_aliases_mty env excl mty + remove_aliases_mty env args mty in Sig_module(id, {md with md_type = mty} , rs) :: - remove_aliases_sig (Env.add_module id mty env) excl rem + remove_aliases_sig (Env.add_module id mty env) args rem | Sig_modtype(id, mtd) :: rem -> Sig_modtype(id, mtd) :: - remove_aliases_sig (Env.add_modtype id mtd env) excl rem + remove_aliases_sig (Env.add_modtype id mtd env) args rem | it :: rem -> - it :: remove_aliases_sig env excl rem + it :: remove_aliases_sig env args rem +let scrape_for_functor_arg env mty = + let exclude _id p = + try ignore (Env.find_module p env); true with Not_found -> false + in + remove_aliases_mty env {modified=false; exclude; scrape} mty let scrape_for_type_of ~remove_aliases env mty = if remove_aliases then begin let excl = collect_arg_paths mty in - remove_aliases_mty env excl mty + let exclude id _p = Ident.Set.mem id excl in + let scrape _ mty = mty in + remove_aliases_mty env {modified=false; exclude; scrape} mty end else begin scrape_for_type_of env mty end diff --git a/typing/mtype.mli b/typing/mtype.mli index a2cfadfd..30d13ec6 100644 --- a/typing/mtype.mli +++ b/typing/mtype.mli @@ -21,9 +21,11 @@ val scrape: Env.t -> module_type -> module_type (* Expand toplevel module type abbreviations till hitting a "hard" module type (signature, functor, or abstract module type ident. *) +val scrape_for_functor_arg: Env.t -> module_type -> module_type + (* Remove aliases in a functor argument type *) val scrape_for_type_of: remove_aliases:bool -> Env.t -> module_type -> module_type - (* Expand module aliases *) + (* Process type for module type of *) val freshen: module_type -> module_type (* Return an alpha-equivalent copy of the given module type where bound identifiers are fresh. *) diff --git a/typing/predef.ml b/typing/predef.ml index 2989d426..a7688ccc 100644 --- a/typing/predef.ml +++ b/typing/predef.ml @@ -125,8 +125,7 @@ let decl_abstr = type_private = Asttypes.Public; type_manifest = None; type_variance = []; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; diff --git a/typing/printtyp.ml b/typing/printtyp.ml index f2e6f196..efb2ed09 100644 --- a/typing/printtyp.ml +++ b/typing/printtyp.ml @@ -1284,8 +1284,7 @@ let filter_rem_sig item rem = let dummy = { type_params = []; type_arity = 0; type_kind = Type_abstract; type_private = Public; type_manifest = None; type_variance = []; - type_is_newtype = false; type_expansion_scope = None; - type_loc = Location.none; + type_newtype_level = None; type_loc = Location.none; type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; diff --git a/typing/subst.ml b/typing/subst.ml index ad9d8d68..5ac528e1 100644 --- a/typing/subst.ml +++ b/typing/subst.ml @@ -299,8 +299,7 @@ let type_declaration s decl = end; type_private = decl.type_private; type_variance = decl.type_variance; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = loc s decl.type_loc; type_attributes = attrs s decl.type_attributes; type_immediate = decl.type_immediate; diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 53542c5c..e03c2cd3 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -1291,8 +1291,7 @@ let temp_abbrev loc env id arity = type_private = Public; type_manifest = Some ty; type_variance = Misc.replicate_list Variance.full arity; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = loc; type_attributes = []; (* or keep attrs from the class decl? *) type_immediate = false; @@ -1542,8 +1541,7 @@ let class_infos define_class kind type_private = Public; type_manifest = Some obj_ty; type_variance = List.map (fun _ -> Variance.full) obj_params; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = cl.pci_loc; type_attributes = []; (* or keep attrs from cl? *) type_immediate = false; @@ -1562,8 +1560,7 @@ let class_infos define_class kind type_private = Public; type_manifest = Some cl_ty; type_variance = List.map (fun _ -> Variance.full) cl_params; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = cl.pci_loc; type_attributes = []; (* or keep attrs from cl? *) type_immediate = false; diff --git a/typing/typecore.ml b/typing/typecore.ml index c6a40713..cd3df704 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -390,16 +390,22 @@ let unify_exp_types loc env ty expected_ty = raise(Typetexp.Error(loc, env, Typetexp.Variant_tags (l1, l2))) (* level at which to create the local type declarations *) -let gadt_equations_level = ref None -let get_gadt_equations_level () = - match !gadt_equations_level with +let newtype_level = ref None +let get_newtype_level () = + match !newtype_level with Some y -> y | None -> assert false let unify_pat_types_gadt loc env ty ty' = - try unify_gadt ~equations_level:(get_gadt_equations_level ()) env ty ty' + let newtype_level = + match !newtype_level with + | None -> assert false + | Some x -> x + in + try + unify_gadt ~newtype_level env ty ty' with - | Unify trace -> + Unify trace -> raise(Error(loc, !env, Pattern_type_clash(trace))) | Tags(l1,l2) -> raise(Typetexp.Error(loc, !env, Typetexp.Variant_tags (l1, l2))) @@ -1185,8 +1191,7 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env raise(Error(loc, !env, Constructor_arity_mismatch(lid.txt, constr.cstr_arity, List.length sargs))); let (ty_args, ty_res) = - instance_constructor ~in_pattern:(env, get_gadt_equations_level ()) - constr + instance_constructor ~in_pattern:(env, get_newtype_level ()) constr in (* PR#7214: do not use gadt unification for toplevel lets *) if not constr.cstr_generalized || mode = Inside_or || no_existentials @@ -1409,16 +1414,16 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env let type_pat ?(allow_existentials=false) ?constrs ?labels ?(mode=Normal) ?(explode=0) ?(lev=get_current_level()) env sp expected_ty = - gadt_equations_level := Some lev; + newtype_level := Some lev; try let r = type_pat ~no_existentials:(not allow_existentials) ~constrs ~labels ~mode ~explode ~env sp expected_ty (fun x -> x) in iter_pattern (fun p -> p.pat_env <- !env) r; - gadt_equations_level := None; + newtype_level := None; r with e -> - gadt_equations_level := None; + newtype_level := None; raise e @@ -2317,8 +2322,8 @@ struct Use.inspect (Use.join (class_expr env ce) (list arg env args)) | Tcl_let (rec_flag, valbinds, _, ce) -> - let _, ty = value_bindings rec_flag env valbinds in - Use.(inspect (join ty (class_expr env ce))) + let env', ty = value_bindings rec_flag env valbinds in + Use.(inspect (join ty (class_expr env' ce))) | Tcl_constraint (ce, _, _, _, _) -> class_expr env ce | Tcl_open (_, _, _, _, ce) -> @@ -2417,8 +2422,14 @@ struct | Tcl_fun (_, _, _, _, _) -> Use.empty | Tcl_apply (_, _) -> Use.empty | Tcl_let (rec_flag, valbinds, _, ce) -> - let _, ty = value_bindings rec_flag env valbinds in - Use.join ty (class_expr env ce) + (* This rule looks like the `Texp_let` rule in the `expression` + function. There is no `Use.discard` here because the + occurrences of the variables in [idlist] are only of the form + [new id], so they are either absent, Dereferenced, or Guarded + (under a delay), never Unguarded, and `discard` would be a no-op. + *) + let env', ty = value_bindings rec_flag env valbinds in + Use.join ty (class_expr env' ce) | Tcl_constraint (ce, _, _, _, _) -> class_expr env ce | Tcl_open (_, _, _, _, ce) -> @@ -3736,6 +3747,7 @@ and type_expect_ (* remember original level *) begin_def (); (* Create a fake abstract type declaration for name. *) + let level = get_current_level () in let decl = { type_params = []; type_arity = 0; @@ -3743,8 +3755,7 @@ and type_expect_ type_private = Public; type_manifest = None; type_variance = []; - type_is_newtype = true; - type_expansion_scope = None; + type_newtype_level = Some (level, level); type_loc = loc; type_attributes = []; type_immediate = false; @@ -4650,17 +4661,8 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist = | _ -> true in let outer_level = get_current_level () in - let init_env () = - (* raise level for existentials *) - begin_def (); - Ident.set_current_time (get_current_level ()); - let lev = Ident.current_time () in - Ctype.init_def (lev+100000); (* up to 1000 existentials *) - lev - in - let lev = - if may_contain_gadts then init_env () else get_current_level () - in + if may_contain_gadts then begin_def (); + let lev = get_current_level () in (* Do we need to propagate polymorphism *) let propagate = !Clflags.principal || may_contain_gadts || (repr ty_arg).level = generic_level || @@ -4726,7 +4728,9 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist = if take_partial_instance <> None then unify_pats (instance ty_arg); if propagate then begin List.iter - (iter_pattern (fun {pat_type=t} -> unify_var env t (newvar()))) patl; + (fun (pat, _, (env, _)) -> + iter_pattern (fun {pat_type=t} -> unify_var env (newvar()) t) pat) + pat_env_list; end_def (); generalize ty_arg'; List.iter (iter_pattern (fun {pat_type=t} -> generalize t)) patl; @@ -4773,8 +4777,8 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist = (* We could check whether there actually is a GADT here instead of reusing [has_constructor], but I'm not sure it's worth it. *) let do_init = may_contain_gadts || needs_exhaust_check in - let lev = - if do_init && not may_contain_gadts then init_env () else lev in + if do_init && not may_contain_gadts then begin_def (); + let lev = get_current_level () in let ty_arg_check = if do_init then (* Hack: use for_saving to copy variables too *) @@ -4787,20 +4791,19 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist = else Partial in - let unused_check do_init = - let lev = - if do_init then init_env () else get_current_level () - in + let unused_check () = + begin_def (); + init_def lev; List.iter (fun (pat, _, (env, _)) -> check_absent_variant env pat) pat_env_list; - check_unused ~lev env (instance ty_arg_check) cases ; - if do_init then end_def (); - Parmatch.check_ambiguous_bindings cases + check_unused ~lev env (instance ty_arg_check) cases; + Parmatch.check_ambiguous_bindings cases; + end_def () in if contains_polyvars || do_init then - add_delayed_check (fun () -> unused_check do_init) + add_delayed_check unused_check else - unused_check false; + unused_check (); (* Check for unused cases, do not delay because of gadts *) if do_init then begin end_def (); diff --git a/typing/typedecl.ml b/typing/typedecl.ml index 5e4b9d5a..18e56e87 100644 --- a/typing/typedecl.ml +++ b/typing/typedecl.ml @@ -104,8 +104,7 @@ let enter_type rec_flag env sdecl id = begin match sdecl.ptype_manifest with None -> None | Some _ -> Some(Ctype.newvar ()) end; type_variance = List.map (fun _ -> Variance.full) sdecl.ptype_params; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = sdecl.ptype_loc; type_attributes = sdecl.ptype_attributes; type_immediate = false; @@ -518,8 +517,7 @@ let transl_declaration env sdecl id = type_private = sdecl.ptype_private; type_manifest = man; type_variance = List.map (fun _ -> Variance.full) params; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = sdecl.ptype_loc; type_attributes = sdecl.ptype_attributes; type_immediate = false; @@ -1850,8 +1848,7 @@ let transl_with_constraint env id row_path orig_decl sdecl = type_private = priv; type_manifest = man; type_variance = []; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = sdecl.ptype_loc; type_attributes = sdecl.ptype_attributes; type_immediate = false; @@ -1899,8 +1896,7 @@ let abstract_type_decl arity = type_private = Public; type_manifest = None; type_variance = replicate_list Variance.full arity; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_loc = Location.none; type_attributes = []; type_immediate = false; diff --git a/typing/typemod.ml b/typing/typemod.ml index 1812e089..c251f57f 100644 --- a/typing/typemod.ml +++ b/typing/typemod.ml @@ -359,8 +359,7 @@ let merge_constraint initial_env remove_aliases loc sg constr = ) sdecl.ptype_params; type_loc = sdecl.ptype_loc; - type_is_newtype = false; - type_expansion_scope = None; + type_newtype_level = None; type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; @@ -542,8 +541,8 @@ let rec approx_modtype env smty = Mty_signature(approx_sig env ssg) | Pmty_functor(param, sarg, sres) -> let arg = may_map (approx_modtype env) sarg in - let (id, newenv) = - Env.enter_module ~arg:true param.txt (Btype.default_mty arg) env in + let rarg = Mtype.scrape_for_functor_arg env (Btype.default_mty arg) in + let (id, newenv) = Env.enter_module ~arg:true param.txt rarg env in let res = approx_modtype newenv sres in Mty_functor(id, arg, res) | Pmty_with(sbody, _constraints) -> @@ -747,6 +746,10 @@ let rec transl_modtype env smty = Builtin_attributes.warning_scope smty.pmty_attributes (fun () -> transl_modtype_aux env smty) +and transl_modtype_functor_arg env sarg = + let mty = transl_modtype env sarg in + {mty with mty_type = Mtype.scrape_for_functor_arg env mty.mty_type} + and transl_modtype_aux env smty = let loc = smty.pmty_loc in match smty.pmty_desc with @@ -763,7 +766,7 @@ and transl_modtype_aux env smty = mkmty (Tmty_signature sg) (Mty_signature sg.sig_type) env loc smty.pmty_attributes | Pmty_functor(param, sarg, sres) -> - let arg = Misc.may_map (transl_modtype env) sarg in + let arg = Misc.may_map (transl_modtype_functor_arg env) sarg in let ty_arg = Misc.may_map (fun m -> m.mty_type) arg in let (id, newenv) = Env.enter_module ~arg:true param.txt (Btype.default_mty ty_arg) env in @@ -1343,8 +1346,8 @@ and type_module_aux ~alias sttn funct_body anchor env smod = wrap_constraint env false md (Mty_signature sg') Tmodtype_implicit | Pmod_functor(name, smty, sbody) -> - let mty = may_map (transl_modtype env) smty in - let ty_arg = may_map (fun m -> m.mty_type) mty in + let mty = may_map (transl_modtype_functor_arg env) smty in + let ty_arg = Misc.may_map (fun m -> m.mty_type) mty in let (id, newenv), funct_body = match ty_arg with None -> (Ident.create "*", env), false | Some mty -> Env.enter_module ~arg:true name.txt mty env, true in @@ -1763,8 +1766,7 @@ let type_module_type_of env smod = mod_loc = smod.pmod_loc } | _ -> type_module env smod in - let mty = tmty.mod_type in - let mty = Mtype.scrape_for_type_of ~remove_aliases env mty in + let mty = Mtype.scrape_for_type_of ~remove_aliases env tmty.mod_type in (* PR#5036: must not contain non-generalized type variables *) if not (closed_modtype env mty) then raise(Error(smod.pmod_loc, env, Non_generalizable_module mty)); diff --git a/typing/types.ml b/typing/types.ml index 3003fc98..94b41a16 100644 --- a/typing/types.ml +++ b/typing/types.ml @@ -146,8 +146,7 @@ type type_declaration = type_private: private_flag; type_manifest: type_expr option; type_variance: Variance.t list; - type_is_newtype: bool; - type_expansion_scope: int option; + type_newtype_level: (int * int) option; type_loc: Location.t; type_attributes: Parsetree.attributes; type_immediate: bool; diff --git a/typing/types.mli b/typing/types.mli index b88c87ee..1ca92c12 100644 --- a/typing/types.mli +++ b/typing/types.mli @@ -291,8 +291,8 @@ type type_declaration = type_manifest: type_expr option; type_variance: Variance.t list; (* covariant, contravariant, weakly contravariant, injective *) - type_is_newtype: bool; - type_expansion_scope: int option; + type_newtype_level: (int * int) option; + (* definition level * expansion level *) type_loc: Location.t; type_attributes: Parsetree.attributes; type_immediate: bool; (* true iff type should not be a pointer *) diff --git a/utils/config.mlp b/utils/config.mlp index 22750c4e..729e1378 100644 --- a/utils/config.mlp +++ b/utils/config.mlp @@ -84,7 +84,7 @@ let afl_instrument = %%AFL_INSTRUMENT%% let exec_magic_number = "Caml1999X023" (* exec_magic_number is duplicated in byterun/caml/exec.h *) -and cmi_magic_number = "Caml1999I023" +and cmi_magic_number = "Caml1999I024" and cmo_magic_number = "Caml1999O023" and cma_magic_number = "Caml1999A023" and cmx_magic_number = @@ -101,7 +101,7 @@ and ast_impl_magic_number = "Caml1999M023" and ast_intf_magic_number = "Caml1999N023" and cmxs_magic_number = "Caml1999D023" (* cmxs_magic_number is duplicated in otherlibs/dynlink/natdynlink.ml *) -and cmt_magic_number = "Caml1999T023" +and cmt_magic_number = "Caml1999T024" let load_path = ref ([] : string list) -- 2.30.2