From 79449684eef0d41e55eee05ca00e6aa6f7b5c66d Mon Sep 17 00:00:00 2001 From: superman Date: Fri, 4 Nov 2022 16:19:14 +0800 Subject: [PATCH] =?UTF-8?q?feat[storage]:=E6=96=B0=E5=A2=9E=E8=A7=A3?= =?UTF-8?q?=E6=9E=90json=E4=B8=BAunmodifiableList=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interpreter/ResourceInterpreter.java | 1 + .../storage/strategy/JsonToListConverter.java | 54 ++++++++++++++++++ .../storage/resource/StudentResource.java | 7 +++ .../test/resources/excel/StudentResource.xlsx | Bin 10035 -> 9271 bytes 4 files changed, 62 insertions(+) create mode 100644 storage/src/main/java/com/zfoo/storage/strategy/JsonToListConverter.java diff --git a/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java b/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java index 10a83200..a5f1190d 100644 --- a/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java +++ b/storage/src/main/java/com/zfoo/storage/interpreter/ResourceInterpreter.java @@ -41,6 +41,7 @@ public class ResourceInterpreter { static { var converters = new HashSet<>(); converters.add(new JsonToArrayConverter()); + converters.add(new JsonToListConverter()); converters.add(new JsonToMapConverter()); converters.add(new JsonToObjectConverter()); converters.add(new StringToClassConverter()); diff --git a/storage/src/main/java/com/zfoo/storage/strategy/JsonToListConverter.java b/storage/src/main/java/com/zfoo/storage/strategy/JsonToListConverter.java new file mode 100644 index 00000000..3e9eeb28 --- /dev/null +++ b/storage/src/main/java/com/zfoo/storage/strategy/JsonToListConverter.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package com.zfoo.storage.strategy; + +import com.zfoo.protocol.util.JsonUtils; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.ConditionalGenericConverter; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + * @author liqi + * @version 4.0 + */ +public class JsonToListConverter implements ConditionalGenericConverter { + + + @Override + public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { + return sourceType.getType() == String.class && List.class.isAssignableFrom(targetType.getType()); + } + + @Override + public Set getConvertibleTypes() { + return Collections.singleton(new ConvertiblePair(String.class, List.class)); + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + // String content = (String) source; + // return targetType.isPrimitive() ? JsonUtil.string2Object(content, targetType.getObjectType()) + // : JsonUtil.string2Array(content, targetType.getType()); + Class clazz = null; + + String content = (String) source; + for (var v : targetType.getResolvableType().getGenerics()){ + clazz = (Class) v.getType(); + } + return Collections.unmodifiableList(JsonUtils.string2List(content, clazz)); + } +} diff --git a/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java b/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java index 303a3a77..fcc5db35 100644 --- a/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java +++ b/storage/src/test/java/com/zfoo/storage/resource/StudentResource.java @@ -17,6 +17,8 @@ import com.zfoo.storage.model.anno.Id; import com.zfoo.storage.model.anno.Index; import com.zfoo.storage.model.anno.Resource; +import java.util.List; + /** * @author godotg * @version 4.0 @@ -37,6 +39,7 @@ public class StudentResource { private float score; private String[] courses; private User[] users; + private List userList; private User user; /** @@ -68,6 +71,10 @@ public class StudentResource { return users; } + public List getUserList() { + return userList; + } + public User getUser() { return user; } diff --git a/storage/src/test/resources/excel/StudentResource.xlsx b/storage/src/test/resources/excel/StudentResource.xlsx index d7378b7a60000be9ed5a13782afd0f5c7adfa986..c0a744a4a6797a6f57e4dac5fd5e6548b961bf6e 100644 GIT binary patch literal 9271 zcmaJ{1yohr)~36=yBiMO-7O;B-3=1b-3Tb4bV`bJA3(ZO>6Vb@(83S;?)A#M|6611 zv(GqZ#@gRpYwkJbw^S7%p%B0xN4WBu=;Qsb0srvD%+XZU#nH)?RrNs(>){8upJF58 zdf@EfU|@U@U|?wf6f<^mV)3%Kd!GoDhh#?!I}AERbE&kBj!3qP%3hOV(rWGfZb$e< zN!&tDC+l-GERg4DW1j93&w?jg_jtpe=6+OUS!Kg_a;hveVx~Dr1*PX*AfT&a-16(_ZAi)L046D3rpt7?p%BqeVbbejN&4yxq=ZV=v5c#w z0|dOFtu}BO6Mhm>_%CP;7z1jTC>wmvGZX$23Xc53E&2`;5Sk}cA#(&uB?V12G~Q>} zA3wzg>O|$xv5I_q7~U5Saz1{}4a> z?V`SSv69og$Svs=DM0IkGICi%L>yFD(j z%?ydQHs_`@M%~-n#%qW_;bo$A0hvF*YxMvx`aj_{b#yU*#MduLOreVn?*ZTYoQ);w zorSS6_w4FmUbJ^~OX4T?jCIy>x%01ra9e$5@;u+KRpK8wzODP@Kqt;(xWt2cc#~Kq zpoDn{Qxgf87ON3UfR#7n(9A>OCp^2=-@qSC*^n#D4z@5-<(XSTkQ$LJT$Qxsvmy*W zCX&OaIYA-N%>cy2;z5RlMDy^x>53Fi_b7;d-}~L-f|A& zv50)e{jok-{eiU9{;QL_2b5aIM{^w-&{U^_+0O@B*;s2riz6&cOp0c9vmKT(KJL4hmU&+ zm#;M1EoIBl1nn~U+RRc^mnpk!+JN#EWG=_W)^bD}*q5$a zo1^_>R0|bHJgQ0B?jXzmKeqF3;F2Ol&Z!XY0UXhCL z5)eEcQf%|a&hy-uLz2e?p^=2U(v7T@QqOZGT^eaC z;Iz&c!U@f*CBRJ1`MpER76Mn{&6#}kOq2Ry&hAa1^M@}?4K)d5$)enZr6D4Is~w^B zf^+Q@0-r}bEb4`nlhxyY(hod?XYZbKevnw;RL)mclX^`DZyoU(jdk0R`^dL=kZ=(75!HXsH;@mgdfENV zH2*Gu@=L(e(Z$x)%G})TX;!L|BW0_6uri1Q28Q=vvOiVWALA7JV%}k%7tN2g>YnVV zwTUZoy~9OqupXjWw948u3qP$cQZ_d=zdYZtU1A`aTD{~1Lje#T4hRQKnVo}b`&t33 zLDd{$iKGf;KX(l{Yh#XQ3oFQi>{U+bcq{Qr^( z^x6RW*5zgA@_Wa>_6us0LY;?)XqLW}kYnZ_&Fmgkp`uNr5}?E0D8cZu_$~$B9!#&X zK#+~+OtX`gPc@2J6PXirH|f(sX@^!L;FdM)V5`p=zc8ODB)rLCe%0 ztt*Zy1E14J;Q_+n)i3S4IKfMP=z zWs{`DNOxl&8onLZjOd!ZrPhjdQrs|izcS40O!&x0n>chbo;6D^RYJlbbvb~beV)$> zV_Lm5FKd*yRLBakPfJ6K%l^y>H9VDmoyUAyI6)%-B#3GW#2=w;Cc|N&*rim*MZZ8- zz&$RA*J_N&5H{JTaJY$xjc(YZtYa~mpnw=F!B$AAU`(w(|J>yG#+DB^FJekc@rFnN z7hT)3njkv%0WH{eyzu<>giT&EE)?x}3GVfT zeMfSk@s$(&Vh;1?xg{1con!nrq0T<`z0#Vc`7je~TAS1EOQCllL3ilNm}Ut_&{uCT z6RtT6qH5xRmdTji3ik{(Z2=B#P&?a!GKuDgl0c+^DR*V@tE88 zn7$@3X6iF>ikiW!F*oTlcG!A0WWgNn?=Oz@zvIpiG*q4?GQUQQWd6vro=}b$xs(Vm zTms2KZ!1G{lge>mOY$+r=9fafCU#lOsr*62hPVl1_b@M1PYX@|h;*IoaLf!63bt@U zJDbRux)crkQ3E%DJM`Dd+tqw(cSS|BUfip*&;^H!E{{ z^CuMwe<~vC4D>@D!2gx5{}%fx{4)*gYb!Vs@}RZhZu^s+FKJbSB4YXi%flCYl!IjD z5-DpH_BqyAaH-5?>J5D8RmqsW>Bn?Yr2@hBOWxdNK-phY@^4gV=1YD?y-dLQ$ZBxF z(-jZsa_j@O-mpFk8;MLvwp`49RfI#96e^gjy?~q<7oN3H z$_4eXG$bD?(2wTAnMXEx;KI|x46aLSX_c>kWidG#i_r_~Sefbw`cmoZh(r0zoE-Zw zMDi-uf^fRBwd|NyGZISb2rLo_fEpy)*Dc#j6Bi1U{?sJh7y6w&aD;sihE1iLwP&LM z0j*0N810}65CM(=TZvl?3D|2t&r}npXH8UaMp!gkD5I-$aB}a;sGnH4&8+A#Jdf5K#KnY2Ti zZ!S2+M);8Pfko(ZvZak~dBG(#t^}ABSyz;WEVB#8XL1c^Q~*CZ*82%wHE)6zl`2ph z9>Qi%LMD2@>X@E;FslpFjmakHiip@XWo+zxPwU+ZQyuftkK26_kyoL2cl$-2m2HeP z`n?K-_vf>f%Xi1$ZWg+@b&?R0x&9L8h8EYA@B(Vxb$LPP9UnZ&kZXeSuIpEY2#HhnuCz|}{s{4F z;wI zVgdB_LUmGv-9=Vf+v^tO3sQ|u;Y`bTc)O6{iZiujktmm=cHB*SpR4l%uYxwRq3hch z?>-Jk3M_iBWUBW_+W`AYI4vFEg=h&nv+DqFl+^V*PN43l1n_B`oIZB+z`$3u#3ymq8Xg9@C4>X4O)S&vvBF=otIB85;R&s|hu`xlDItw=B|%DhbiZr|w=I*=WrDF{a6#}Kn{AX@-16o>~bDqn+YlV$4&F=O_Y2{c<61a=m zwX-2f@Xkxfg-(XyB9lZmGP_+&7VN%f2q|>jw@S&>xay#fictZCn^@!3bAnqJEUry0Su)L9Zu zGIDN#GM%EnN*y6a6f5(TH%SAHZD(5-WMxJ$hM$kRX-Ii0wMX#* znC3flm>g#|m^BB{B${gke90I0lIFE-7U%eKb}`V77+z&o_=JWTsp%?hsZPf5m}}X3 z@a>+*Z9=f-c%;x6m%Osw@nCj%9)F|^8_ctNYgBJg%f_jn$*7b+EW-5tp8lvG5iMTW zxAi@M8ZnS9JJ=um&#Im75)@4OP)+(Nfq^0adRw@H^%Gw*0oW$j(G(D?N`I!6PjCM_rgte8%(|1Hu;6r z4Bkir-Cz#JT+Y4MGV0H2mtzrHvX+2{y;-<|xvg)Pm+)OeH3r;kqengj@ z9q)O?RHpjq$#1u0BzQ|A#d&p>iG%3tLl5sw)?h0AZf>ar8yNJifGLa~Y9<2nRAM%-JQ#PJ zCBAY-cqJejO0gWb4{_$AOL@AQZt%+`VB_b;jMzC`IwE=^5nj?#R>4;6dy9i{2GOkp z;@G*n7)MCjea_GL+H97Oe2on0ify)uwhY`hzqsh3zPAhEujYE`(=4Pm3nJXNmlMZ8 zoL((8Q2vV8_*`|A#YKovyf#7Qq*N5|<#X0E1fTAeSurbitTM3nh@cM@yZf3sPOTJN z^6M=rz|XSAx-$OHz2PFu4L@|swS^PQCGo#WheHy|FrR!q9#&##!NE3HysJVT;$1Sn zKHV>?UB7ITDgxe}Rs^XskOvQKjt@{qi5i>kf3v3*SM5M5+AwQ*gbkU;SzUF9j8_xuxE@AeHt!HzWUU&%50)rQ%h)Zk^#c z=cECSf~g)h@!ba?NE-7;N*QA(wu%e&L{c%ilyWG=yaTs@Qe&x=3+PN+{`}eN1@*IM z)0H~6>u2Mhbxr1P3LGm`HL&XmgYDOf`%G?r_qZW+_YZpw*U+n)`a ziHhmi%gUu}*O#88*wCellQQ_FCbdn))L`Auv&vihzJ{-_ZLZ)638g02ncV3lHuth| z?c$aJrz)`A-_N^;yZ|dGCWJb`LkUa$_>DgdIXqU2;!Z>cW2VGN?gK5#Vt<8wP~A}@ zb`F!^+b$I;BgOpf6j01?4i`SAkeNCqa&p*#dTkv|ZEfL1r;xSr;zs~b*nrej@2mP4 zDS`qd5Pelk6~Z)*oRtm?7-{-UHJ7gKWf%2mWc0PH9M)+f2HiF#^>ME7iCkpnMR+{V zO9PhV#_ez7=y64e=26!OAsgmyL|bLP@RKcC@;#=<6BMLF&=|NmdSo5oE`i;Hz&_C1 zDS{B<-Xsm#w87J%hyiA-!$9kK9yOsKI}sXA$SFr%=(Pwa&Cp}j3_9;+!jG~!_>l(P zFTw4GFvJ-_f)nYvu&O-~oCR!bIkTk(xuMlsWjtMTuBR40w7flsPGsvJi$C zl)&qEPA_l_QrHoMH}GmXQ5dRDsl*(1q{EtBItjo$o1A?cWp`B>lgg&aOOjNk*W?Ni znMkMLRlLBk-b|&0V0wV2;FVX5k!Z193k=vt*)Y}&^CZ6!mQ+YKkeBR6QgI47e@;%b zCWK1|TqO%oPDFN=ue)y#n0?^yT$5BclrKc;s;~_UD$|`mLHG51Zb`;hqS?_9uPJlc&_JBtIDZ6eW)w=9VzXC;eQG zKgu;G^eCq)bb5(g^)1KQV10uQ;kW>tTHF-=b7W(DA(~tZ`-*;0qf|Z|SS9t8_3n)7 z!V44?s5OQvY%Ba=M3C!erb5}$4risC;pwiF%nMr|UFB)btuVL&sU@mG!DPmI|J-fu zd7MlH5W@oEbZRUDLw@Pl`|Ow2AdAVerAlETk(BQV&p_{@s#T%pPvvPoxu`kx=MSja zJI<8Ib{Pv%zMuB%yo#b+%$}X;O7XBs)PGsR<+18i`4QsdZrLnUJy4 z+gBjByHTG{@o`1*q?!Kb{kMy(P{n~cGH7}>2{cQ96cVX^0%#6aB4}rRcIX2OV;Ko= ztT=2*k|-o*(zbNm!^((vSt2(^-uF~9aJk7)L-|CpI;o45@wa(eR$(j3a<7fSqrme-b3RFidhc!AVdXnS}u8|E<7o>%oqjzU^*Uif#cgMzM zm|QK9Xs>7~nP1D{MmS31p2BfE^;PcCrkJOb?!(#CqJ-pk>ppB1I zPW3>*1t~Vs0!?>{ocY*p9zD2Yor!rd_qrj( z(W~$)|BsVoz0qofnLOUq5#e@$o74U?AZg*n;jr+JsJ?2AAR#&;ZH=zDEQ~}A^!3!% zuSLDzvVN$^8W}}Wx{kjSxxT%Xq%2J3c8KF`1>M<&w#CtZLh$%PH)#y zO+jA!!sr`=epjDw&#tbzCO^e5r`=!NUBQl8w2P2KR>iE*SVv$b8oh*yZXnVH=+m$V zWsfj%9xN*}iwa5$B#~aX+-tvw;iS&|vQzrEeZNvw_l8QkLH)M%eLoB$NdJ(T(DiMpD>6e1I4-PBvb`(91l|`K&}wEE+DE zuAWU&Th1zoB>5RfmE90faPkEN{@j{0a-MT|q#I_G6@B5c-|&vU@s@Fo%O}Q3FLgDb zjyGQ4OB5Jm9mC@5vBt6LDq94z*Ymhm`;d?ZwH-Gha*n9ocV;y)b>a z*1^@*r@RDIUsn&R$d~cn!A1>nuZQYh-ZiUhR-a zcrT2PX>8M~O9J#%xhcCh?eQ0}LERPJI!3-hE}B0uTSu;D?5OQ9lWAW!%bP-4OsIgdyE zZRT6HX7OQMv~J`V^O1=i-{mXcqWc%gZcWy^+X`062pk*)92oF)8uZ3#iS@JLdjc3a ztEwkDfqi|NWNBM(aOra+?O2VZ8B8@X_a-`o zX;nt;-gYNkPBYAt5q^KsWSaFV)-%ws9pkfQWE`o+NxbCxCrOz|hdX)6eM9E^Cl!5y zQKLHHLmc`aF4W&mUK2-0+n>E%wf@Htv{D|U&McHH#!}m;!-MDIYD7*nN7BYVcdXV| zzsr>SpdRBLeB8wtG8woPTte9FI7;=XBu-+9lNik0L!MaUZ`_^z^#t3AJOO~idzb#+IBzI^`nFB`V zMBJ|)DdpMvo`8V4gS1Hz(iZ$8wft1YII-LfLi8paAw1SQ2YKKYW&@-0mKxNG@Yg7; zp?pEvk={;l>Y7L{5XP<_IZV zyQB_V(M?_I;~Bk^PqeJ$*W_bi!%lUWm0IJs`S7xG3ua^~z0kMMq82vw+MSuwdi9h^qo}iouS6#&zjXo=$8~E4W%)y>bNBA4 zIC{G`QeO&l8OpkxFqeA%|5*N~C;4x1ZXV_0?LWZS^Z+Np!~LNr`Ah7P(fDft|Anqi z7aLN~VQ_2kxS#VxEW7l3gP!c!avv~LMt>_4SOwjT`mDYj?QFLZjHrfjNad~`@G*W6PuZ77GRtl1IvM|IKQ$T6~2jE9GHq+hgC6{cz+>7C)tvW-a$ zYH4PT9O-VDS;hye;!P!)d5Hk#asfQibt8Cy}`1Y*)ayb2%NuZO@FUgxf zS{LbaI#SWwxGA!eA!qtTI|Y7Ryw*$S%_oi9;$t0G%ZI&<{Ls98Ob!B^5j8f2zIQn3!1jBd|kjZC*v4nqgC?~sx`=|^A66l)Xbox^Gtdp2(iGJ z3_1S&tM>cbRwQXg+bC+usio;MLy#7@vUkB^nFZYLFOhB1ZprT zGGx9u^I4|~64MlPz^N-sk3@?}rAU0%=C&K4?f{Sde2eSLb^woA@Nr&<$ChVD-9c<_ zq>dOn4tpzt0(ZlS3z46wa@dFV=W$=oCQDL92@n;~HOA`7L{kE($Z3#8GVje4NLO7h zS@P86Qi>OOX8Z&JU=KVif#oZ&cNI) zisA@~DZ7;fd~d- znsVR5s49R%VEug8{UZIJM&=cUBcf9=uf9l zQ_!Q%FQ+I(f9d?(GXKljObV_ghzEX0k^=zfjWur`mtzwWoHT7FECP5IpcU5BbscX^HjJ!qW!dZwq4&bn&BwzuSHP z3#>n%Js0k$>R-IlpDW}kv-I0z|3B4!^Gr{t{Ir7kZ6NpIt?)4Af5P^^CjH2V{~C`G tPW%<&KiKgScf?(UWlf?Ehqkl+Ll9zt+!+~wEF%=N-Fx=A`}<&jVWH{r0nm{9|F``Yk3hNl0H})%qfKi^M6z8oq9Cla6iD1m ztVgwlknWMFP1UeYKzHjyYp$YE1MH+$u^rW;IT6IKn5WSZ7hSbwxz>3>^$Pi2Ooh{t z(4B0aRN$L(&6v9QsAu{3s9-SsJev5bYyoX4r%;Uad+HGy(LID`4-YT^<-gJNg9aPrDa7}lL;gjE(A3b$ z%+{He<>&r?^!zX8LBJW=sQHycVQSoSuo|6+P69z$HgT}-xxT;11SZV~-MOc52) zQU@(DhB{#ojErBK@9p5il3>hEKl%9&uJR}>Yyrv!_lnT8Ye!cE1{$YSX~*)F9!$6C zv+45;8F^1Sx3)Njvc{4Eg@I*C>B%F>8jMjEEkeX6Z;3;3g)#zkdlhxQ8DCaHO^d7T zSA$!AqTd63V{C74^K%_5*I2gCV#DywtABvH$_Ye_hfPr*iL*{= zpto*0r&e9Zr`3iUww)Z)xLbA)jjtb3m_eiF-mDX8Z@J-B8r>1BBS}}+$7b)MWvSH` zlj@3cjrLvApM^1{SBwlcEqulP+7u}#rrnos38_g3sip>yugot0frYY9h0Bajg|^TX z&O=jtLo$edCYFJkGD4nU(sRS3l8B#g1NM%Qt$I8c+1(FK`8N1AI)i=I^@ zEOqkY)4C+6bfTDo70P&kvyzlZ*>s(&Sszb4(G1>bhPT=pu><3NHl%Ym7q+rUW<6WJ zphrFrP(PU{97)=O)?1~jOuG5qN4A}E4u5=|z!Iyk=1fF!4gH z{?+J+MA0P9=&T*1K~(bki^ME>v;M*GiMn8$)SeRb;@R46Xi4faC;cOo)?Dy~{#x|8 zQ?3GA{`qExc`aF{qGW-XwZKkZibjx-99;NpvvCI_3qh*@895L^TAZ?0-MLV$EKw(# zX8gyfe0azNS)IypQ-W1UazDsqEUfz!!mQFz8weS;4Od|1}CE28kasrz>ewg4Rh z*TgIvtIoUiQ-L>knS!F2`BMW2Puqf-R=@d(nFWLMzPx+6g|_(VTxjv*-FpO7b3zYp zlA9#9L!-tm5eYVq=n}FNCHJ#uW9-KT=`xk1Zw>@!V;FLYEd`rehPY3%3QmNw{1s_i z)@{qsh(*=oa_mgdhwWC|RwI;*hQ`h=Y?kp2--!|+z|;W~d8Uj{ zBPZ(LxQj6tuo%v z;lGwxUc zRE_&g`6!|cCCmCyA})R6*@~>_l?*7H_xEQ7)|%|Qyp#6(S4IQ~C#Ri2n9vMi1t9}l+x0|)Bq7ih>i zeNUH(7@7^Vzbdf8*oS(8NBZ0@o}vAKd2-gtSQ3c^`}&D3SOCs`$eobj?#>Ku67dTXxe`NgKQ z=o)36xJ-eh^qG)%s0&$GzYM7#eWLSvVMdDvc*RBhW{|#P;h1UY6l}gW&^NsdndyH9 z(FW;|H>WTF00AlhfDgIj&mih-X=di)%=+uV{xh0pCn>~1qG=yE<@zbpa!`O-9V(KJ z#uBLIW9dFXi*Jo2%((g5{4A{L?6*!&H*#c%{6mwSR$L1)gO z_K1+ueq_^EXjU)U3T?tZwc;k*Ez$n{XDDhKs-J=|b3%L3F_0s@qL-&@T@f;IXTEcN z+^x(37U@Ycy-oC8mY^S}@Y8+Pd;GSm)m^R^ZcfKr?G}W_ad#b(nA$~X!9Yr$fy!=J zEMmgh`#HfS<3S^x$^@62gZMjQN;~tLwex=Y7u8ujUBxommj>KmQ=Ku9qs!;jFT|hZ zWp;lvY)((ZdckWd#iR~*m%e6rK&Ll+bM2W>?P_82L|E18&+BQbCd>$ZJrvhtDA71;a+XRY*{E?a7w zd4n*Ln)L$xJFF&ssf^Wkq#}$!=5dZiZYGX)M$6EZ!HF5ToRFag^t06H^B`&tFNHms zA?yTR0o^C#eD+n zL+WFowkR8HzXa@i{JvdL?DvLpILh+}?Ys=%n{s1p7$096>w?vvjC0PaZQ442` zjX7PsDA%JK6LB4}Eo_&ulf^>q4^sxqZfPsnk&0NUQZ{2e-NL!};EUBIFZ#%>m$)i7 zGU_atYU0h3;t`qT-=7UiHE^x%VbN39E0}U(#yFWv3?NB_z72I^TcduXu=gomfhu38 zsh@l_LP{ApVnNoQb~8EHsH*nrWzBV;dz zqZM|Sk%y~O3A72P)f6<@PVuwx1^4QWIHp7#|0H~Egk8V` zDC``AR!mvo+VqNqn9->Al@3@;TMR59zO+UKY6RaIZ4}+cR!RL4+tRhzR`YOW zF*BYU?il#A`o$H=PGb#5RGW3mi+qA38`}Ui4{j5kK-fj|lN~OJ&F?$~)6JV9)36Cs zuByrY3j%cn8Lup;44Q9jHerxHzW-ipBwqJqn~(?>NkFJV4%YA}-24kc;ZwZpjM@`S zUnc!93YPC;eP>g7dP^NIrMyBgaRh9iwG>=4?jZ$jTN#{XjPzwG`G_2LAM|!WE7!yj zaUrabEncbtxH3M;I2s}poOro55;zeMpM4SBlkVS~4 zF{B{pe8SZ|Z*=0kf1NIN@w9=K?Fl{LBI)H`d>ng;!CiP}$rDdd6sGARa2Pi7dZkrT z?3rz;f*ZTZ`&kVe#MeEwUPBUmBnuJ8ToPVJ69qmpK`06BoKv>a|{9 zE%-rFi>sTDc`t=-Siq+gxx1HX9lm$RaUzDBB)z)uE1xe$4e#%7Kcg?-o(*wEU4TM+ z`Mo8vhI1A!7n}O9@H0b1NG$9v*dsC7nUqo5nJW=6c%OQBg_NMqbejW7P4ii~zjq!d zbe>UtNe$F~-Ht;Gf0)ibZ<6s0@X^#zH&|xK1q2q<+iCOy=FDBkDqB-|RO|a!V`UA| z^}>&|V84YPaf}S1%&Sq0W-juQ4ab}@;TXWT;9L=;QbNbHk(D;J#a6X)k;UpC8kELR zwd>iq445>T;@%M!=1e%$C9@_M>6!wrLg^wU&+5l2i=X+El4CB&=9bq+#1c6`W#pO+ zW_MycgX)@+Iz2wTS%$W&d3TpyiS;A{(aHM6GZ=p|!N-m8Go6k$UlP~X8pA_1I+e9W zvo3fM^9>>jFgZHiQpN!SEYWtmKJXx@d?$GjI^jiX26Y-jdIoqk@(YG015BxXxTpAp zLdsoWF#@UX+_wT{f zUNbG;XW|Cdoc(T1!dhi#rkln-(sV+YjFEATx>e5U3B?kY>O_bivKDQ>;j-)F>cPP9 zjKQ3ywjL*t%3`*4am^1fIRS>5m5+T?x5g$A7FQHa82K;*c~ou2M4el<_edb z0aBAykxZ2D$qu~7@7Kq(v3R=|fjT;Vcr?Z0Zf6pb z8WNrYg;Dr8oRKUWeEJbvp|Q;iJ)$j)y(myiXe%Bpw6hnvuB>^bW@}vIOqb4+`h0s#>0}9sd4n*VzqOd0&#t= z<{Vjw4kHC|KNDhBW}8X#A3R~*x>gYiXL!kouYMZ}*3cFEsIm<&R>Tdoe%Ybrhx8;W zJV`g+&yt`E6WahMPfz{kD{Y#o&!C%KS0aO2o_c9ykc!T z)fmVYp%>iLe-9^#;q!qx=XpdTeuHs#hCxtBLjT65&3i5#$9&xzlf;7gye+_Vv-^ZB z=_Mx9WT|QhAGE#}4&2a|L^G%RM&h17Z2t?1V~H8$gU>H_X(?h16st0rNtFu4<}d^Fg~$)6IRi zE{-HyyUp7G9Inp?!>~b9dIdIC^`>YbbIlX{jgo>|^5(z>>$#ZTxGSqgjqh=e!oYSM zDomG%0^Q<#sii9?E%9V5!sfTgr7{&WnR~Zn#DWe)VRH4V{9#Z#lOWE;$i(o;F45V{ z3Z8Qtb;J%vGZZczto7*f6spDIa=-DXWZBV9zD8ktK91-uEb)tx>ggwfy=;}-b9b1~ z+p)|qy=pEc>T$gQM1b{&Fe%rXKEGZY$-zXh60e?unBDR`Y~p<+w|pHDaJ<19{xwn( z%FST4Em;lbS1CLiSnmFBZHxPL{z*VU3D?9 z_6n`6>o1_;2CT#y7WEHO*oCu~$Fl9#O^R!9pxvLn{X)X&Z z%-Qcf8a$rq<-QHzJi}G95G*X9dg-#`?meAv)QY+)~12;G*l#4i&(Sp zAaK9mkl2)+L|^xMqy(@}exbv5q$IxVJdv;|u!@+$KRH0>GBJjpnsoGo>3KKQ#bJcP zxU)}(K~<_ZFVA!3FQ$fN?cx&j*oc*Wh+X@PDViT|Dnj?DyF>Ou+v4X^+J_McR- zG;%UCRdaE&0$KcGOi%J(ijJFN&9SVCcJArHv#5x?)aXUBrdwp%)bTmb>Inrm0;rSg2Gm2^+O{N=0tG zVw0dsmyy+!oSfFI=>j5(xgVWx)~!Kbl2%==gy%m!74+SM>L`m&xqSV7{{Q3o?=3yT$FDB15njc-PF% z)Rnf}3X1HF7ii) z^Id;WVlWNDS2$?2J#4m~dzG{- zP}9&~)};po9uR`DEz@v2a^TkDU|wozqH3Lj;U{jC&LNGse`e(Zb{qC%m?Kk zbMdo;^JiB6M@{EsdLDiuE&c-g z&Z~~t?9=+X!{|D9){WqMB6G9^rm1G=kTnxL%j!d~dFBqW8s42nY(!?kc%w;{_DmQh zCHaWHcx@cynh+JLJN$0np1GP>#P{*S8*_3Io@@hGQAA_qrPg-Gh6wenN*};XYd%^* z{6eZa_j|EEq=KNLjxVyuqrq}~@vnpnW%>H0_K*FI#dh7#b8URkV2kaBhfdBB|7`>+ zk?$f}AaBov0|3zeF#-+{H*_&`QZsXL`RR|WkFMESjIBU>$s_Ws%GiAmR<|WzjG2HS zb9QVkV*-WMJ|%@o{*>O}VjP}2I&SfN8fwJ^0s^rO<{pHMbtZ#rK%E=4us_k=@+`#{ zZ2BM4ygb=n!Us*88~2UG$iiqCb%08L(p->FBw7J2K;(uLo2<0@uXt+M_A!53#1iZG6^%CDGY*lWJ9 z_GLq_n&~p0qF#IMV6{POJ^|A*ejTdRDJvkjOqfwio!ohyu={YR%=Jp99j~Wi79EDy ztxbhhlc>b2t$Ol>G1q=&?J-?Q4qI(k!-eIYU)?%NwMF{Z!vnm!r9Il>C1sbv9P@WE zyC%Cc`=>J@B4rj@(bMoYvLe%JO@oGnmh1K^=gA@n-$YFFwpW2KCv-CRct~!dgK#TI zVw*?`M%Mf|?JD6+Hd3`$1)BHtS=>ub)M=v#lE`6${V_10#YKTYC~~sj7XgkyLBPMw zzYIpXjtpe}H6W!-Oh_ry)ZRqd$=<=4)x_S(?9Vp!|0@p|T@trL_yrT=)j*oDmA!hzf+{%gCZG*4(fflO5(vm!2 zP>nvF?URAsahPi)t(kjsq~6DKt#8R>_ULV^t-Az1Yf!Kphvc&uS8rNr+%G;Ot+N-@ z#p{QeYL4+0A*brMxl8!9fyGf#U5W2l*^9}kjfnBqLaC9Z2ZBAI*XV_BfLA>K>V5nM zrMXqB=iTv${RhMp2R4M~$SlwebCW~_vZd@e!t zYL@N|7pSp{p=f1d_XeK$cv4VgwOY!7I+@nUz8}6%Ckp(Gx$WR`V#FE`s2v%FQ9h1j zC4V)&wUt!GcGEij3XU`?a4R(*T-2E}3`hFT_~f89y0GBs52$ja3-N4&ety0}w|7SmoA#Y@q}D#Xpr?Hs zMcL=5*u>m!@GuC7VZn?+xDy|(3n<#51fRlOpuimX*Ofy#csLKwym-#qc9?rZL-&!= zh}4JufTf~)(2ybcogE48=UPondHzqn3pas{#ZuA>8N)W~+{(gdt+>q#%P6G!N~1Ja zVcB2!OA+sHQ`Uc~g+KHJ6f`qL$Nl?$fQY@C_mx{{Q{0$2gDM9KVq;QU2dU{G;jd80B#Z z^f!tC#xIn|1<}U;by!NqJe~j>0RQ^VINA!3M z{#9Z=27Ij1egnQI{ss6*q5Z33dkp&bh5t7s0Pvm!0QiRtcx?Xn$o*GyTJpb`{~5=X W72qH~2mqi!el!p_zW7NW!2ba{XC@B-