From fd2931756369667f08ab3d8281eaffb5708a7c25 Mon Sep 17 00:00:00 2001 From: marcizhu Date: Fri, 9 Dec 2016 14:31:42 +0100 Subject: [PATCH] Added string arrays --- Cereal/Cereal/src/Array.h | 88 ++++++++++++++++++++++++++++++--- Sandbox/Sandbox.cpp | 16 +++--- tools/Release-Win32/dbread.exe | Bin 39936 -> 39424 bytes 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/Cereal/Cereal/src/Array.h b/Cereal/Cereal/src/Array.h index 24d18b2..b95b284 100644 --- a/Cereal/Cereal/src/Array.h +++ b/Cereal/Cereal/src/Array.h @@ -32,6 +32,7 @@ namespace Cereal { std::string name; DataType dataType; unsigned int count; // item count + unsigned int size = 0; byte* data; template @@ -53,6 +54,31 @@ namespace Cereal { pointer = Writer::writeBytes(data, pointer, value[i]); } + template<> + void setData(DataType type, std::string* value, unsigned int count) + { + this->count = count; + this->dataType = type; + + //Setting the data + if (data) delete[] data; + + size = 0; + + for (unsigned int i = 0; i < count; i++) + { + size += 2; + size += value[i].length(); + } + + data = new byte[size]; + + unsigned int pointer = 0; + + for (unsigned int i = 0; i < count; i++) + pointer = Writer::writeBytes(data, pointer, value[i]); + } + public: Array() : dataType(DataType::DATA_UNKNOWN), data(nullptr), count(0), name("") { } Array(std::string name, byte* value, unsigned int count) : name(name), data(nullptr) { setData(DataType::DATA_CHAR, value, count); } @@ -63,7 +89,7 @@ namespace Cereal { Array(std::string name, float* value, unsigned int count) : name(name), data(nullptr) { setData(DataType::DATA_FLOAT, value, count); } Array(std::string name, long long* value, unsigned int count) : name(name), data(nullptr) { setData(DataType::DATA_LONG_LONG, value, count); } Array(std::string name, double* value, unsigned int count) : name(name), data(nullptr) { setData(DataType::DATA_DOUBLE, value, count); } - + Array(std::string name, std::string* value, unsigned int count) : name(name), data(nullptr) { setData(DataType::DATA_STRING, value, count); } ~Array() { if (data) delete[] data; } bool write(Buffer& buffer) const @@ -75,7 +101,14 @@ namespace Cereal { buffer.writeBytes(this->dataType); buffer.writeBytes(this->count); - for (unsigned int i = 0; i < sizeOf(dataType) * count; i++) + unsigned int s; + + if (dataType != DataType::DATA_STRING) + s = sizeOf(dataType) * count; + else + s = size; + + for (unsigned int i = 0; i < s; i++) buffer.writeBytes(data[i]); return true; @@ -94,11 +127,29 @@ namespace Cereal { if (data) delete[] data; - data = new byte[count * sizeOf(dataType)]; + if (dataType != DATA_STRING) + { + data = new byte[count * sizeOf(dataType)]; - memcpy(data, ((byte*)buffer.getStart() + buffer.getOffset()), count * sizeOf(dataType)); + memcpy(data, ((byte*)buffer.getStart() + buffer.getOffset()), count * sizeOf(dataType)); - buffer.addOffset(count * sizeOf(dataType)); + buffer.addOffset(count * sizeOf(dataType)); + } + else + { + unsigned int start = buffer.getOffset(); + + for (unsigned int i = 0; i < count; i++) + { + buffer.readBytes(); + } + + size = buffer.getOffset() - start; + + data = new byte[size]; + + memcpy(data, ((byte*)buffer.getStart() + start), size); + } } inline unsigned int getCount() const { return count; } @@ -106,7 +157,7 @@ namespace Cereal { inline const std::string& getName() const { return name; } template - inline std::vector& getArray() const + inline std::vector getArray() const { std::vector ret; @@ -122,6 +173,23 @@ namespace Cereal { return ret; } + template<> + inline std::vector getArray() const + { + std::vector ret; + + unsigned int pointer = 0; + + for (int i = 0; i < count; i++) + { + ret.push_back(Reader::readBytes(data, pointer)); + + pointer += Reader::readBytes(data, pointer) + sizeof(unsigned short); + } + + return ret; + } + // This returns the data in little endian (necessary for >1 byte data types like shorts or ints) template inline T* getRawArray(T* mem) const @@ -138,7 +206,13 @@ namespace Cereal { return mem; } - inline unsigned int getSize() const { return sizeof(byte) + sizeof(short) + name.length() + sizeof(byte) + sizeof(int) + count * sizeOf(dataType); } + inline unsigned int getSize() const + { + if(dataType != DataType::DATA_STRING) + return sizeof(byte) + sizeof(short) + name.length() + sizeof(byte) + sizeof(int) + count * sizeOf(dataType); + else + return sizeof(byte) + sizeof(short) + name.length() + sizeof(byte) + sizeof(int) + size; + } }; } \ No newline at end of file diff --git a/Sandbox/Sandbox.cpp b/Sandbox/Sandbox.cpp index 0f5ae0a..dc55e28 100644 --- a/Sandbox/Sandbox.cpp +++ b/Sandbox/Sandbox.cpp @@ -57,7 +57,7 @@ int main() { Cereal::Buffer dest(1024); - int data[4] = { 1, 2, 3, 4 }; + std::string data[3] = { "test", "test2", "test of a longer but equally valid string" }; Cereal::Database* db = new Cereal::Database("Database name"); Cereal::Database* db2 = new Cereal::Database("Second database"); @@ -65,7 +65,7 @@ int main() db->addObject(new Cereal::Object("Object name")); db2->addObject(new Cereal::Object("Test object")); - db->getObject("Object name")->addArray(new Cereal::Array("Array name", data, 4)); + db->getObject("Object name")->addArray(new Cereal::Array("Array name", data, 3)); db->getObject("Object name")->addField(new Cereal::Field("Field name", std::string("test!"))); db2->getObject("Test object")->addField(new Cereal::Field("xpos", 3.141592f)); @@ -79,7 +79,7 @@ int main() dump(dest.getStart(), dest.getSize()); - dest.writeFile(std::string("test.db")); + //dest.writeFile(std::string("test.db")); Cereal::Header* header2 = new Cereal::Header; @@ -87,15 +87,13 @@ int main() header2->read(dest); - float ret = header2->getDatabase("Second database")->getObject("Test object")->getField("xpos")->getValue(); + float retf = header2->getDatabase("Second database")->getObject("Test object")->getField("xpos")->getValue(); - //std::string ret = header2->getDatabase("Database name")->getObject("Object name")->getField("Field name")->getValue(); + std::string ret = header2->getDatabase("Database name")->getObject("Object name")->getField("Field name")->getValue(); - //int* array = new int[4]; + std::vector array = header2->getDatabase("Database name")->getObject("Object name")->getArray("Array name")->getArray(); - //array = header2->getDatabase("Database name")->getObject("Object name")->getArray("Array name")->getRawArray(array); - - printf("%f", ret); + printf("%s\n%s\n%s", array[0].c_str(), array[1].c_str(), array[2].c_str()); delete header; delete header2; diff --git a/tools/Release-Win32/dbread.exe b/tools/Release-Win32/dbread.exe index f311ebb07deff9d6c55bf7876382ff6a60781eab..66dd0299859f0e13fcbb35f7e3048894b8f49b1f 100644 GIT binary patch delta 17428 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 delta 17165 zcmeHudstIf*7rFfLKGxXK_VAH1w~Pt8zkgHf)KD)G$>aU?-!)j3leXy7}}siJf=l= zJJr6Oj_q`2?2PT$>L~TKEeJ25Wh_=+rLAv=cAW80XkXeo7F*kVzkQNmZ2jh$d7kfk zzJI>+JnQUp)?Rz_;2MA~FLZU!V1l_-ThK$eQ8u=Qjg?uW>0 zqUdnSg#kB40(ko5RS+d7ZnQA`b2f%4ZSKHT$n_U-U+ukMkM=}v*kWPYn6aSsL>?eh z#qoKEN*Ko35~glkws>h-b5RA8&%cW?0k!udd+d)|p!KrF4YWCE4c~12%3nXx$MG4l zfgL25#mX@ZXq_$M+g1r%6xo%1QgMd7_;U6M69X@Tu!9 z%<31xgRwdLWh7G)8UKN+>_(gQF2%K3`)R@1C2ct}0g)3y%(3H0ecWir5e+2}=+qu= zp@a(pISVT3>A50SdRi=6+tedj8`|!kC6b=G;L4J4O)e|Hw{g$1we{R1px-ZM>#Se9 zGg;I*+dbS;SxU2Wklj|8pT%8T$d{WKrna#v*|{e|#?6yein-uE5!brE@awt=i7RHQ zj8^!utztRDmEFiSRP(!kMFxV$MwTC|vOw7#n=OoBiV9Ep;`Kxxq7@&`pQOW^@1J&|4Hn~;PNe?>iaX{jfvi%gJ2it5%A zog{VC`#IENV$K@tY!un}@LaM-vN&{v#pbbx@z>#uBw={01CD^+&jjk)_M+sdg;D>f z%i6!NsMzMV-dg=D+BbK{Regdhlen#2Htt(z{d+R1~9v+}gHAYK8vp-BEJ$=DtKknKpapkqUGd<415b4jh2f>3A_nsPO0fow)Lv5%2 zsP;mGV0mjdXKi=o%DLRwy^U4FZG4Uu`f;>~D_H(#cy#5)LR)q6UKQBv7pv;5?|E6E zfos0p+hz=HBQz<%)Be2o@PdYQlHR)_>RnS;y~uEyiTv61wQ^_ z{uw-Rg`HkOxr0R1D?K?%B&6Cz}M1I))tJ6D{R3~dga`C*Y?=DaQZB3;w5$S*t#51T~Sc) z033~Ri&YTWJr5&fntJ3%U>jHADZ`i5Ig{mR}Ezc=`&$z8uL7KsLzw z6=Xg~o4?Byo+GIvvmAZnoc(g{-2(pDAe{&8+_p!Z+SopK46FSAE;nX%6E z!P3(b>1hib^%IE$aS)ywbiP@7I#WK|IT*a%jA>L7ZDG7K=S-usQH<&acnBjMdK2IG zMx)bEow{-8u|5KPC`<$>02u+LAe_S|qBj!V42(nx|Jz736ozOFs{H1GG02emPsE_L zGxI_9pcwQ$77<}BxIYF70Vsm?E)CMt=V?g63KJT1QFRHv~%o%Tfu%IuRhP%ZWiZ=mYy6A5~g{vkKk#-~`w>)}z3s(-o#7Zj8wu`S?x z=F(}FE5~9j*pl{J|Icz^5vT%P&f)Vph1u_Obuku(!c%~s1AY-ucHo)96~KppPXfx( z5P`xtKmuS&KuH|{D-Cx?{Sks~O0K+VP=txJg3FyE=QM}+-mZF>%SrG~t%eLitz6E~ zVw1*CP?OBqD6IU!3lodz!g5X^l7Ly3mz$xx@|Rq0vihTx+{7W~i9@`7E5hst@P1w8 z=dDQ)c+d6oP6ltvOyE5~5fN|`mpeVB2`Cd5H1oD#Ph>e!S|e7LBkkcb?;4saDGDzs z?an*mt-crMok;>IC2G&-yOCP7X)^jgG$!8Bd&lE(TRU9#4x4+voZl6N zeje*&rF*MrIutkyeUtDkO^SrTFC>l5ehGJ(PMgX^%$qsM+%8$lC1+ERt8lQXSLAF9 zF;pf?bKiC4-G$FYa^ZY8mX|E|HgV9Pq3o{R@dZ~n$jy>-b7BomRk@r(db&tH$N6pW zc0`P4HczlHXKCKl7j>2nq)&F%8>!CvBGvoSGw(awB+@?=A-xm_70H6WH8k1ZINv+>) z$Y*1dM!fYsbe+7A|FxEki%JxkrxJ726!y1dUDQ+TRq{<#5}QWiuZEbk{jlR~CMj}IGS%)3)ae)O19ipb|i9;dyCw_;Pf4vjF!xpr^Y zf+&6h870WMpTO5P8&&tj<|hc;b%ES>(8k{(1_f~UHLknA@zrTW5|b^epGM}z#2YbY zFWDO{{7JmL(E?5U&j0YD|KTtm0)^$S^8Y!Lyb@C;>W8n!PGwa@6+4;6E7AElvLRM2 za*ro30v3Ce*qlvrzMp&&_b{sobtEWZ z!tC!6K77jSxnFrNB%$UiRFni&pS_MsJi92;XHkDy5ynT)BpVWDjK|CuY{D->57@XH zTD@Z`Ld)&Zv@d~T}By&;>`E0_-k*NYDLiQta{sIwC zoDkLzp5ntUYX`QlL^&~nolbHlszj%v$gYVqWP8z=%WH94+XWSmC1)loCit6R|HN|^ zIVY~;@@{w^z=z+HLL`$^qOZmh0a8{3FK~~+$-(pG==a^ zcq3|Ue1C#hd_e?_w?VfLN23q-9{<6Yh;m`Y{EJhmt4KQfaw?MfCBlo?Wo_izTdjA8 zd4u`@9%1}b+$9@7aR6Oi;(veJ<3ZLrIvUTL5%?>Ti}(^RC-rTQ{S+TQmAsl1XDZ^p zr(9OxKQFm&r3T|AcdwT&!8S zhVP^YY7qAO!uY8eVBavl5`{ajoBvG6b^4Jc-ND&QX1)h2)LM8r*V-4t=aFAb9VhuC zmR`D`lNDpeC>LVH#dHlV5*xmiI-M9JH{S5)?bX~oNy>Lk9+Ba)y@+c{Igcb5$7NgR zkb$YuOX)dRO8Bg%J0h&Ed6LU~P&?K}s-To^LzzT6EAOu1qIA~9e5m{2Sg@QYhE8{J z!JN2ZnTvJih{ZxuK^3!9Vz^>2;F^cJm`#>Xi_Q_c7(c7&I}z7>nNMj)H|aR33X?a` zZltr?hdPKE>Hx{6m$^4(0eAA&v?x(sBv!<+=}U1=iqs+h|Nf9i4N3H`40-WCKjeRp z^y~DeLq;k_y*MzN=@?60b7Tk?ETmDb!APP=%Z%x)k$gF0Y$$SCngh}kPBMC?GNKf2 z=GnePeZjp1%>_t0h0Y8lZhGT9Ymw_+aK zPTp0_W{;8xor@FR$kmwBdmDFb#4O+QkaIA|zS>#Mvz57CR^1gWD$@io_RLU6=%yh39VfyY`Hr7ZUmgnljqZ( z7aBlrSjawx%ZYW*Gp0+bM%9f&q}mxm3bhlduM~ZWEibjl(~VI0NOdE9wl?>6QeVhP z5WFanD^hTJw^#}0#&7kMuneTgQ2}$+%0!e8_Ny+3TrVE_}C2!Pl&*dp-8Ad<|YSO&R%q z0+q+l;=fEMNBLPK`dHi|M=}zEeNEoUm^SkD_`oK&GjiFxBm?`+l8IqttC@(}H(*Pi z=(s}zqO{fkKdy0@@T9~O7gFKz*utopgh>^mYV3{idOG!yjxUDX{Gaf0gf$^%*{B+L zrYg$GvsGiAyhvJmjD8qswO(U-e+9L-=9=zzbi3f_166Sd8eT^)`mv)A*c++XRVxuk z_S)fE*e(Tl^%hBf5tTRwmZD1=jWoiX^hV_3#+;vc^}V>zNMx3q6;3RR|D~hEzu*G}HXdc?B@A`Wg$Rc9Fc+VS^YA@O%H@hvnr!(<@b8k6 z?1}6W@^9HOj>o@)Ou`vy1FYf}{{re~Obphn%9-xjlMLPJ9Fwal>2L z`>IL3bu61ezOfdvp(HOS*0BQ$)6ZK3TJ#Eb&YrJiE!lzQFU4F_%YxTm`J~aJr}6QI7D1p1yjKwljdJXE*=of zg>Vkh;M|x%V&*5~e&|Qz{ws2CuATbUg(2U{oaF53am~I<8QAz{Pcm-E^#7P9u6hM+!9$LS0zi> z`_b;Pj&SUTWq1m6hz(zE3r_hm=FffM(&EOo(lORfuB?l*cXD%OI(!R8!Ytufj}6~s z`+bQBCjvX?Zdn*(cSM5B2%3?Gi&eutk#p%BEbIrxY*35}V-W4@tX*h`SdVyVAMp;t z8`C=suheQ>_Na)YM!F6RTB^)K=!aA)hZyor7r5-t9%bR?j?&dxdp!0YPo&P}wF@^$y7*Zp)S>Kzs%zcF{ORPe4rtTOk%i4Z7%wEI@w^ zmkX#1R^RZdjElbE8BbKSp-UJsI7LCSI+LyQeiJR5g_>dU#^!>LE?cBs=pG!!s~uy;rBVtJ27C z@+L|{=`h3R^=`rl=k>iyF6SvlF{MO2uRO#XZibWX^Y+i!fKm9eMCpQtt4;RG95->_=oX3DI33zJ|4o28{kdARIsjK{t`|Ou{112KEL6k zPx&0AN9AvcVIg6zY*H;lx1^8M7hFgfe?@h zzg?lfYbwP|2|-KRhw7ucvYXB|cNzW{sHwAFe^LGtKE+(f#8;l{5cXl$Ncl?|SZ5H) zX?Z_xd?DqFfmDrxpV3^Q!2{*?jzIfzo>E<>R8xs!LA0Y4iYetEMMvC#+LNA96F;Drs?rsF+KGol=9K_^bRJfeb`rig?CHB=My29)#!8VtykE{u3Ii2l*~q4Dhd@ z!0(4ZQ~F;>r3P@cIS(jjO9Ve2YN>S~2`J)!4pi+&_F??*@qoz6@_CedsZV^IUYW3Q zYEH0mE+Oh+SFH8bN>8w~#CJkuCnoqFJ<@iw!gBuG=ez#1Yw52=IcrGtBI~fZ7+42+YEks82%2AB6F$~eenvl2FD!byw%Wq{2fZ1- z-YPHVG7wsZaK;-m$S#Lf5<@$|l9_FmqQ#V$v*$~>!SyQ@GbJuLNhqiz7K?Pe9eW8M>X<|!% z!l5b)JjkWRv-P(^I4fA)027yW5c$n+RYgdN`hvHKyR6F<L)js#5ocKj9j?K z3ikrxK3BMFgnO-UUoG613wNV%w+Q!a;XYfqpAhag;a)G?ON9Fp;a(@)rwjK);eL!f zRTkygEj-r<_b@>=F`fgnE3P0>;+_@8&AF>?=O6zHk*yBq?+t;$1v1Xs@9bfvwTR@@ zVn1+sl3q!t$J0F2um=ri(}u@s!%LV|L;OkH(h-hfzekwz^|C(^d_g~k(sxt(Blqat zd11ZBa0=!po-+W-UVNr#5bpuyrhAm$4m^>!=mZ!dKML}*Am`=`;^_o!sMuq1FuiHM zmOpOL39|h|4QgnECA6pD`{^qZIBScIe+~6m!kh6ii@yHS_d3*lBe)rdxTz?&I&gcW zw*g7+gC*`jlMzA_s(pqwX`uq_^R;m2UGFXV6aBh^lSLapgY+zoa9qTfiG~46W*cJc z*SK$l4=jcR?LuFBDU(D8n1lv08KR*YTtR6BZ@7t1+(H-byi<G`_Zyx1 z$XQCoQz{FQE}zPFk@V#Wj+5O1Y`kbQ{I=U3TK&$mFLq$I+S&-h7vL%fe{ z1SKn>oa+5#es&#x`Y8XzqN@B5r!ft+w83%`zhbPTBS19j1h1gpJK|qb$`h0_$;;ZE z$M?3sJf!go=!priY3 zIMkeqHHJ2So;E+?Z{E@2&g<&c3GKUjkN)HKS3XDkh$qm#G_ZZAx_9ssuK>&cF#|#w z9H0!wk+mxmb8^&y_gTmEXBcJkkz*T_d0K*&rwAL|9xEpN& zPXfB!I46sK5`RztJO}6jq&>wj`v9$g;Cf`9fZO}f>CYHu8elEpIlwu& zRs(7Q-RO*7i3cGJKn(a4d>R420~`j_0JhaT7-k6`rek#U`W*%SI7ZDI!0rFh{^hPg#9bH%>00&Ta;74^h)?>QS_$ca*2Go%Q>q~}3)5?>*>)V3X z7}he(KskOpu%2NS1L^>005<`t6%4Zu@LNDXK=vrZtOC>l&H&;zz^MW20M7#20UkiY zW3VFN1;EFE;bi2-C{{$0Ha_)OPYGOu{^KU`F+nQYw+0!k7q^2+1a<_(^SM@xNy+C`c^H%A_K9%2fI!6C|+-bmIGP1p=J} zI0^ZDlXeDFz|5=^#C>=^;_d=Ry~~GFQ=DusG|w`l{YVW( z^7|NO9{Ky`GeMozmV*-_$%)G0;p_3E^kHNii~74>?7$YuNLv6pnJ6n0!U7NlK*SF} z;m42_m6J%v7RfMZfjLg=;$#)bk#R-&%E>7Gz2N6TmGL8&`!ICcL=ffH_{e%-=yljv zL!D+etx4(xhH|^+D?j#?fAvv9N6Z0AnW}iyf@g-&`AV~|%<+|ZzOn$NU!ES?a%4>a zCXD1)MG;w*WaJ4Smdc_7Ha@Ax$KiXFRA<9Cc+1f!{Tz1>wO<~9JvM}`55RU&uF^&y zhH8U(T(AwS5I+Dk9r&QHnu?)$99t=r1&<>Us*EI^Rns5Y4V?d?MxcTn0M6n^qBJeI z|NZ%VufSA!ji9A%2E06nTORZFJDdEsJu1tFH`;SCO4>68e=p)E?&o@@;2u{U>L}Op zCj?1{*Z8>B30&)aT%Uaa*WEwj`exBRt|xq4dwg6QeO%iqS3{?d>$L}Pz4armZ0S9d zB|H5}k7G7k7;FwakeopdCzSM^U20(>$tT-lCVH0PSNzK@lz^GN(n1Snx6`YfI+XHS zGJbpX#7|dvtNbLVP(}6Dg3?E}XnS;eKDBwx)S;f18EHw8mjIdfvdOv=qPV_ zm%O??-a#k2|DyAo{v|Ry05=cWf(E$$09?jFgkj*0QF`B%_%vo7f@DtsE*rQ`;N}M4 z)&ge)F4l|75t`Ql83tr>0O4!E$$`rbz+D1P1Dr7c_XTj%$-x~_|39_+f1BDBQiB2h z&!%=KD|dZ7JS&-5whV_kYaUxuRk?H7V=LBgT(*AWwoQ+&SyolKe%-n?mCV$iQdF*~ zvR7{OQ=FV%`}(kxCsxj7-`F23X6+~Ap1c{vo+HB!O?4bm6{r`f*Q$4^uc-f~7HKAE zax|MY`!vsJic;64PDneI-jIGSy)nHdy*<4ny)#{=FVQd2FW0Zum+Lp^H|zK5pV8ME z+702x65|r%a^q@axp9MWv$4v!!?@d6W2`mS84noijZYg78=p5GHNI>-W_;Cj-t?a7 zy6L8Ak|RTxVa-^OQI>H!<3BUbn3)8GR7{LDiieb&l~u|e%H7HuWv#MKc~rSi^^9tp zrcSdWwIS`TwDW0gX@5$4KkehR&(r>%Cee=6j@CwL``uHBuF;nygM$FIS&Yi!~XVO3iOHA8SUZ=A`aP zeIxbL)T!EsFs9#X*F)e>bT@Uk(?{vY>c{J|^hNqL`p5N0_1E-0`d~wpL1)M?EHP{{ z>@yrP95wvf@T#HT;7BrN8Y_$^jh)83#(2{d6ERWi#AKYw=*Uo**P89-0XixR!<;}d zQSpjmq;d;HKCINKwyE~2;?+;6-%%ShnVM3~SYi;Y&lPag;F@DlUfm z95FT-|7QHcILs7hN;SP?I%8@vU54X~%qYs(l2M!S`;0$je48OLPco;O%gmK#hxvf{ zS#zuTeKTY8{y9EDp;DL?a}~vkYK2pARlzIrm205*!^%_2XH>7K9B->WR^3)f)UT?g z8WWV;rs>dprujw_3Ho&F9RQ z%-z%+%d!7t875tkqj*eVS3Ifs4@IluJ;jHLPZTWNZlrRIa-1?=IaxVFsZkn~vy=}j zZORhma%DN@RJHO6%%?-j=at8mj&sTm<$o!^QjSo`R7on6Dod58T8)YJhUz`lXVANa(!`l>oa^M>ZK<|9qN=39*+H8XX8>QkwIOg)?WN$L-& zkEGdP?=5Ku(w2~RAbo+D%bcb|@q3V})zr%Dqtvg2@M|VlrrTb9VqZ6eYFgc$~ zecSYlaZ7GwPWF*3$@ef zc|$p%yhV0C`*+7FQecFUm~w}@MqR5upgyWTraqx=P@hxdgjRiBeM3E{W;9|=m?lCKt5Il3 L_K|akf@J>-!8<*h