From 06e8742063e6bd56b6b4c0d75f1129034feec6a0 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Fri, 29 Jun 2012 00:24:49 +0200 Subject: [PATCH 01/18] Fix #8643: AVLTreeMap strategy Auto discards const Signed-off-by: Ingo Weinhold --- headers/private/kernel/util/AVLTreeMap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/headers/private/kernel/util/AVLTreeMap.h b/headers/private/kernel/util/AVLTreeMap.h index 2405bb79b8..ea436be3c1 100644 --- a/headers/private/kernel/util/AVLTreeMap.h +++ b/headers/private/kernel/util/AVLTreeMap.h @@ -26,7 +26,7 @@ namespace AVLTreeMapStrategy { typename Node; inline Node* Allocate(const Key& key, const Value& value) inline void Free(Node* node) - inline Key GetKey(Node* node) const + inline const Key GetKey(const Node* node) const inline Value& GetValue(Node* node) const inline AVLTreeNode* GetAVLTreeNode(Node* node) const inline Node* GetNode(AVLTreeNode* node) const @@ -622,7 +622,7 @@ public: fAllocator.Deallocate(node); } - inline Key& GetKey(Node* node) const + inline const Key& GetKey(const Node* node) const { return node->key; } From 191b137a318e10f987c0c7713b09d4e9f9ef6d68 Mon Sep 17 00:00:00 2001 From: Matt Madia Date: Sat, 30 Jun 2012 18:51:26 -0400 Subject: [PATCH 02/18] Updated VL-Gothic fonts to version 20120629. Fixes #8662. --- .../data/fonts/ttfonts/VL-Gothic-Regular.ttf | Bin 3816268 -> 3816416 bytes .../data/fonts/ttfonts/VL-PGothic-Regular.ttf | Bin 3946376 -> 3946424 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/data/system/data/fonts/ttfonts/VL-Gothic-Regular.ttf b/data/system/data/fonts/ttfonts/VL-Gothic-Regular.ttf index 016461965c245227f45fe0cf2a82980f1e7f1285..f880d709e7cffab4e8af7b3748c0fb3d122dcfa8 100644 GIT binary patch delta 129447 zcmXt=1$Y$a`nNYEkc8MqiWYZwhvII5B#>Z9aCd8w#oaC0U3NF??ivb3ik4D?Qc5W_ zK#R1crBGU|eD|FBf9JaH+`oBucIKVuc_!yvr#a{I7Z0O;`sZPkOcEuLNK*L`Basdm zkUf0NrAit}*KTK7eScuT{sX#x7u8YHwQDxV?FVL#%$l=*{sulba9n#}R!$%5&%OqH zzD**Dsx~sKRoix3BlpS0d_HE%yuyWJ>OHYaBo8wsQ4=RmS-!Nkq)xdHCFS}b=ku5u zg-c`$-@TJWbAe$j#Lbxd;q=X08f}n7H*YLye=&RJw8E)x3I_bg1>fiMjx$+^d)j?1 z$HIo{&z!e(<;Gs;8gu-oMDoj|xeKNg4j4GBIX5`P@yvOJD;IY8G)lwgD>=XR{K9$D z%JnE~BECt-MdM`1p<5__J7qWSK-m_ zgF9yCr*!{YQY-o)>yppY{%iFAeXv(lr`RLHnO)@mwNcK*8hbgZBD%by8)itRcH}ubK)}SJxmH$u&KB(!J_AZOz zxUv6v|4S7Jbq<~ywpp-$(C~WYqB8t*N5)s<_&xv1StsHNsRuhRIT_W-|L>Bg)j4e9 z|84IH;fvkYw@jv*boG|EpWn z_*_~m%vW<-@1M6_Ql(0 zZijD&ZaZ(=Zg0Q6?e?78U2eDj@w*?d|G4(Y=08;WA>)U%9};gqzu~`OyJ7uK`kmx@ z)9X!&hP8@nBTM=A-nZAj{p#B*-(J2}a_!)?iPy$o%f43oTFq-Uu2s4wy_RyV;D)KV&PvlwTugD*fUn7qq4dtKo0LUxmL2UkQI6{w#bcd@+1Jd@g)8{Au`1_;mP_@W3vUf?32zE-3~vap3$G2Y39k;Xl7&ACFAXmWFAUEP&kD~BPYq8A7lsSM z`Qb_7iQx(1apAo1@bJ*^knrH}pzy%(fNHk%HfP~YFHXh4kw1=LoY(lL(f8gg`S4~4E+)MJ@i}X*U;n8qtJtp z?3d8bq5GkGp)W&Ugsy}xhdv8k3|$DF4V?*{4xI{}2n9odkU!)Lc|)F%E93~-L$;75 zWC#_9ib97%dqaCdyFxodJ3`w-t3w}!R)$uDmWP&wmV_3E7KCPnW`w4PriG@4ri3Pk z3Pbs!Nuj*Zm{3kAD>O1REHorESQZ)>8W8Fi>Kp14`XJOJ)IHQK)Fsq8)FIS9)Hc*6 z)H>8M)FRX@)HKvM)F{+2)F4zpR4-IFR3}tBR5SE`s9LCMs7k0(C?k{}N(xm7l@G;) zqC@3EQ6Wk2UGR1ARq%Q6S@5sm)8HS$C&6EXkAgo3%Yt`;KL&pYejmIMlwA*g9sDZz zW$=sO<=~~@`QW+W+2E(af;4sHx?2(AsT3Vsy)Ft{SPEVwARFgQOrFE}?i zCpbGeD>ySaBRD-cMHZYKEDTNxP7LM+#|CqPS;5i4QNa3j7y%8+aM`C-8URY2eSmAAu(U*>8bg1CIg^1NQ@W0=EJ; z12+QS2EGnl349i~5I7$=8~8MEED#BV0``D8UQ4tx|?5m*$MAD9=I6POm58Wzz z{Xo4yoj~nC%|MMn^+2^i)j*X%qv`FHxa_&532`PcYY`#A=^)K-+^w0Ot_0RFo@K5(o^H1>?`txP} z3I6f^Jb$h~$Di#V<0s`^Ndk`o{P&eItD%e8YT0eM5YMef@lWd_8?1_`3VL`MUZ#`#SkL`dax~ z_?r2e`kMF}`|A5-^?bE`HGMUF)qT}`RekUIGJI)1sV~Ks>`U?`_$vD1e6harzGz=L zUzAVcedqnp``Y`;`;Ygz_nG%E?^Exe-Y4G2-uvEr-n-s1?;Y=L?=9~S-kaX)qqs<=y1n=-uF5>s{kr<^9mR(!1Qd z%)8J#%RAFM!#mkq;LZ0=@=o-Q_m1=CdB=K3dPjJNd53z3cn5n2c?Wp=d;59&di!{L zdwY6iJ-pq$oxB~r9lY(m?YynL&Am;$jlGS$^}Y4Hb-lH`HNENHRBwtm*_-4|^u~MR zys_R2-tyiUZ?w0Z=bh(`=auJQ&!3(rp5Hx>J&!yOJr6whJ@-66dG2^_d4BNR^nCBR z;koMh#`Cr3vgb3;Mb8D#dCxh|S zC)YF9GsctS8STmRjPMNe4D}514Dj^#^z-!f^zroYboX@gbn$fZbnvwIwDYv`wDh#_ zH1{<1H1Ra{H1ss^)c4f!)b`Z!)b!NwRP|KxRPwy%N%y3AQavf2Bu}Cz&J*h??}>50 zbN}al>we>Y?SAEc>Hf$4LgxP4{oMV`{ipj6_Y?Q;?#J#&?g#E)+&{bTyYITo+_&Ag z+&{Q)x^K9zyRW*xaewLl!hOYk+5MUOlKZ0jg8RJtocmMvDfcJtQg_51atGZ$x5w>v zJKYYq-EDJQ+-A4QZFKA1I`<*>LH7aoUiTjN4)=EV7WZcNCbw*(dxLwud!1Y6Uh7`t z{>Z(;z0|$fy~w@Ly}&)+JKzDz4KX)H@Z+8!OcXu~;S9b?@dv`l`TX!3GYj;a`b9WPWLw8+w9d~Va zEq6_K4Rdb-i#s zbN%Uh;`-h7tLw4rk?W!BXV-n#J=a~=ZPzW=53ZZ8?_D=s-@2~4zHxo+`pWgC>$2;T z>!Rzt>zwPX>$K~X>!j-w*Kt?a<#)MUPM5=FciCJrtIOijyGmRdm)fOp$z8>+!>)s_ z1Frq9y{PS07hzS1(sjR}WWrR|i)+R~uJr znX84XxvQzGv8$1*zN?nwBrpF2zc}tY?m5aFcO17Jw;VSe-#czNzH?l6eCznaamI1Vanf=aQGcQhu0xMz94f~l$3e$_$3Dki#~#OS#}3C< z$0o-{#|FoG$2!Ma#~R0K$48Fkj%ALejzx}zjs=c+jyaB*jv0>Wj){)(j&Y7$#~4SJ zW3*$GBhxX`G2AiCG1M{0G0-u<(cjU}(bv(-(bMsPqlcrL%+bZs(b3+~&e7J<+R@6< z!qME(*wMgI-%;05+fma|%~8pb>X14T9SM#&M+HZ;Bg+1t{k8p-{iXe>{a5>A`$PLJ z`w#XT_V4W1?cdt3+P|@XVLxO4*j{Q6*!^~&-D7vyEq1frWH;Kic9s38U1=|}AF&^_ z@3rr;%XZp#*tgra*|*p?+c()a+BewO+t=CG+Sk~Z*caO8+vnJ4+h^Hl+Nay6+NanH z>=W%1>|^cO_R;p?_96Dc_5t?(_I~!h_CEIB_Fnc6>|O00?XB%C?Jexh?Tzg9?RD+7 z?KSMx?bYm6?eE#s?5TFCJ;k1EPqHW4E862__Bea2y@Ea3Ud}GDy|evidt-ZTdu99A z_K)qk?Wye#+po3*>2jd+pgKJ+P<-UW&6_hh3$&%vh6e51=~5> z8QUq_$F@>i$QHB(Y(AUU=Cs*uHk-v}wwY{3o57~HX>BDomFK>A z4Q%yo^=x%*b!@e5HEoq`m2B_HY#Fw6TbeD!R?!x3i?da*#n{SO-&y~&zO}xwKDR!z zKDGW~{muHT^|AGl^`Z3_>(AEv)_c}6>rd7@)|*!T>kR94>$lcx)~nX9tzTNNSUY5l}{+*)dlSOZqK)n>I=%~qq;V3p~tT5E|_V^v#^ zT9sD0wb**ddeC~ny3e}Ty4$+Ty2HBNy3M-Ty3xA9y3V@By3)Gby3D%7y2!fFy1+W$ zI?p=SI>$QOI?FoKI^8kEKT42q$PO?t0j<@Do$5^wiS=Q0kQPxcBaO*JZQ0oxu zVCx|3Ku-vqKZ@FRl&T`H2jpd5vvgMNHg5{j$tju!4^0DQZC1?p) z{1%_ZYjIob7K_DfF5fMvgBpJk6_w`H4Ut7VI2lVzP{t!0g6wPls% zBg==D6_(|eWtJtD#g;{ug_gONIhL808J6jmDV74uB+Eq01j~3!o@K0Mj3wKWWf^T5 zVHsi>Y#C(fW0Cc?^s;ofbhC7^bh5Oww6V0bw6HX{G_y3ZG`2LdG_=&U)U?#Fyl<&y zsbqQ2l3_`=q*{_K6)ka=SWAp0+EUIUF~2pxF~2syGQTwcV}4t{G@mdZH-Bsn zn|)@F*>1L(t!A^?WHy*}W{p{GR+$xMxw+U}WIk*@WIkvp{bzb( zdTn}TdTILC^pEL<>2K3B(^J!*rYEM~hnapeJvKcuJv2Qq{bIUrx@#&k{bc&lbj$RE z>4xdL>08q^(^b>grmsw2n!YeyF@0|O%yhwY-t?*IjOmo=r0Im|xapXw)D$rVO@Sg$ z->Awmv&m#Kn)D{Esl=o<9W^OUa#OLX$aKVX*mTHr&~(7G&$P?5!?ew`$+W?=-n7=V z+Vqj>L(@vr3e$4aGSgDiV$&kiLem1%eA7JB9Mf#mOw$b0bkkH*fhpfK$uz+<-ZajX zXFOv(Z9HW>VLWb(7(>Q@(Qot_y+)7B=rTHuHlx*OF`A7=qrs>%YKKyv0;&6p<#hxzG1FmhGCLHHqkJ_Fy1iEkY~s>j5UlgV|5Ds)j0tN``bp znjzJYY)CM~8KU(6>EG(#=wIt!>0j#q)&HY^u79TgP5(&$Q2#*xi~gSeuD(ovM}J%Y zqyCmm|GoaI{u}-0`pf!D`iuH=`cL(z^~dxPeOMpRd-Wc@Tkq1_^)|gxuhp06ReGgf zp_l6q>ksJ<==baQ>G$e)>38aP=(p>)>9^=N={M>>)UVJl*DupA)i2gB)GyG_*U#0@ z)X&gQ*H6<=)lbn+))(pv^po@x_2c!j9DTMvOFv4VsUM*qt{p_fYph_lxdl-94G^uC7dX zM|WHIgYKs83*8mnXSz$ei@FQC^SX1o)4Ef-le$lICv?YkVO>ZU)CF{Yomc14xpgj` zQ)k!NbXJ{Nr_rf(D&0|?Tvx0s(jCzq)*aFv(CyLf*6q^m&~4Xk)osyj)NRnM)veL3 z)_tg3sav62u3M&CtdlL$Ez~X0&DYJ<&C<=#P1jA;P1Y6a3Um{6<8`^Z99_09OE+3K zLN{DDR5wI7NH|Y-ldhw#y{@gUjjpw>m9C|(g|4}-nXaj> zk*=PuuCBJOrmniKny!kjvMxiHu1nD+=@NAbx{A7ZU5u`rOc$knt9_+?sr^^`kM_Ct znf9snPwf-!@7iCrkF-B)?`!XB%d|gff6#uby{7#}`<3=f?HAh5wU@P@X)kFnYA(~0U9<5Vr*V?pJtx0Rt8nk+?R$HRgXjR&yTBTO5E!G~< z9@HMtj@qx?tKFmBrQNCBq5V+1QoBOCT)RlSP`f}oUpr4bTRTfTQ#(UDRXasHSzD+r z(B^9=X(wpMYsYEFYR71EwAtFx+ELm}?MUq~?NIGt?VzIM!BJIZU9_FG9km^_?X+#R zZM3bmEwwGQ&9%+6O|*@*jkNW(^|W=hb+om$wX`+0?`x}Tt7)rfD{Cuh)3mAD6m60= zK^v!y)t1-BXv=A%O5T;cEqPP&y5v>KKP7*cJT3XN_e$=T z3@sU4GN`0~Nxzc5C4D-U^e*|Jq(@2jl1?QZOFERaFKJWKs-$H}i<0IgO-dSFA82}Lx@kIVI%zs++Gtv9T4`Epnra$r8fhA88ffZk>S^j~-q%#qRMBK; z(ln_WsU|^FQ4_C;)5K~jXks+cnsOTcsjd2*`i=UP`lb3G^$Ydi>c7-a)yLHztHbJ` zI-vHeeQLMbrFN>VYJ*y)SL@VTwMMO0tJFu;3bkBatUjzhq&}$LuimHLtKOsDt=^^H zsotU9uHLHNqTa0Dq~56BpkA+Dt6rmCtzM~KpJjSU>S5}k>VfM1>VE3Jz0`fwz16+cJ=Gtmd#Jms zyQn*>JE=RWJE&W$Td13#OUj>#A$2YpAQJE2}H1-&1F()74USiaJT1SafV? zR1Mi{)hpFY)xWA2s=rmwRnJs^ss2#?s(P$?sCuCKS#@7^Pjy#Srn;s2L3LAgU3FFU zjp{4am#QnO%c@JNi>mXgPgQ4Br&K3ZpQw(jN>ve6SQS(SRDP9DCbqRkDhzcvYOL zf~veKN+mh^?r74{_@i-0V~>_U8gn%IXgTFO<$uao%9qN2l`oXfluwm^D4!^QSN^69 zD}%~_(y#O>y-JVLt#l~uN}JN4)GKvLt+GU^R;rW=rCeF8EK(j(9#$Sw9#kGs?pN+r z?osYiZdYzoZdPtoZjdS0Dc363C|4<0D3>Z1DHkf|D(5I?DQ7BYD5oi>C<~SO%1O#R zWsWjinWY@1%v6q44p$CS4p9zP4pI(O4p8<}_Eq*#_Ez>(_E2_Lc2jm$c2ssywpX@O zwo$fLwp2D(Hd8iLHc>WKHc~cJHc-}6)>YO~)>2khR#LvFl%*+Cl~QGjGFh3VOjIT) zD=Ooa<&`nYXl0b*jpDW9rQ%=33&k_VUy45!PZYl^jwwnN5k*K5R0I@Wg; zQlU`D6~&4o#bL!E#a_iO#ZJWz#dgIO#b(7O#YV+?#X7}W#VW-|ij|5Lisg!BilvGr zip7c^GDUYqH$_K92Sr;&8%0Y+3q^B9GeuKH6Gc5m9YrlgbwyQ06-8ymdx{K2x*|=H zq)1d$RKzJ_6w!)u3W@wb`CIuL`78NL`E&U*`CsxsuoF za)Vqi*U7c=61hgMmaF7PTK= zEe4IQ-o-NOkkCJD~N6LrF z2gwJ@2gv)$`^x*sd&_&td&;}ZyUDxCJIg!CJIXuA+soU@+sfO>TgzL@o6DQZo5&l> z8_MJjx#9-^5UZ6BgKb`4;1e! z-dnu8ct`QJ;;qG7iZ>N+EM8l@rg(MnisI$Pi;EW)&nuo&JiB;C@wDQp#RbLr#gmFB z6pt&;E6yz*U7T4wtaxbgkmA9`1B?3?_bcvOEbCMJL2-7Zn#36&)!$RJ6ZnchRn*?L}LPHWsZfT2~}1T2r*TXjRci zMJtPzcP(04w4`WJ(SoA+Me~a06wN9cSCm(jTa;atRWy3<#k~uAT2V4`4gl%+`JAqjUIuUi9~1Ot{`lB6fS@TWHwx9AIQm5 zutg+#9`-|Ah(sU3DIh##5w0u}eH2%d2|xHig=;`v4PN zNT$qnyF(AM3-=X?<_YVL7K!#^s#3R*b9{I@%peEwY?woqg$Rpb2?r6p0XCA4Vd1H_ zl8jC-4X7oRUcD@#OV*>gY2#O(gm}t|AhB0rOA-(HAkZBdgbxgG(HI z0bi0YOCKgVoPAcj)bKPM8Cfw^#fE*SG3ek_qRh$d6!28_Hw zOdCuK8c4})G2d^%_hQ;hWReELiR>_jvNos=v>~Q5t}PP7fHkNG>^g>$H)t#p(-Sv? z=B)R^t)Mlz4{itT$^CFA;Ce9wuy8G|5i!1VQlajd`>oFD%yaG#@O%;V5nn+@BJbY!`w8GG2IRR-~%q! z;5Gb5=7LmT(y#)V`DjSl8q&|06Sxvkv6xf13w%I6gQ-A6;Q?qv!va`9rj-rZa6_&g z^8@CU6Nq^vku;(Oji|aT<}racppj7aKk;%nNT%P7*l8n9F3-)IvZ1DIs5~2J8ZT0w z?=($>6xM5E;WH>-7q=2APwSd55-HDMHD4uCo_020L;v}~-yBLLEqN+|@{KS(ZrOy4 zxz7J6&kkCZgBaH7dn-26DvsO|R|FoSJcHKiec+c@d8*Nho3|3KGYAXcf$}493t%S7 zXVU*xU7-gD6EH*3ic*%Rgsp@Nj37_O%t5QM z7Vfc=EXT}Ct9@h>J^->34r~M+SjqIKl^qzA@~1IF(&_~HQ+yI|`K$PxNO=aU6~iY` z{(F2$r2I|HAhzP%^7OtnRcu|Gd=GQbx}!u=flA6+cjJJkuaJOy!x3^aX1A>w#tKs< zlD3q-ZC~pu$`1h0FY*XnBdG9XA$;<>u|8MPg}BJK?kP z^gp&PAxR{*9_ANAJBBE>K4wA%Vws6{446PHGto}?4(G zf#CE`gVF>347a0!B zM{H+2N+gz9YR8-i#0uA21>7T+UpnoWi*|d-RJq+zP?KepwVhTZb^tyr5-Z%45(>mJ zz3r}u#IgbIDH%ceV%f-uSfE|8nOF+Esf5V}ww~g_sJA5URKs^VB1F+SsMIC-f&T z$2^cgEN{h#p(3$s>Hi4IID&UFmNJc?i~_M6a1M+kZ^XQsBl5}H@nm54vAeObsaa&o zI%1JX?0&oima%>Se<%`r7_WtOtRKO`JvMODSUF)cY#}S~HlSCr^k{@|F)k9T$A^G( zV~tn|IFqDi;{(1UCoMuumjzCJq9oZWI0vZjd+Qn?QTwwqjZ`k~YQd#7{s*$>RIOiHB;#2*SJ3nA%BZ0u|V7pcm!mTZ{ZvmOTLTqU>upJ&YU0; z#{g#1hRg!`ANPfHf8nLDoJ<8XSBk_@ z!OS%xaWC;YU`FDoX68l^X5|guLH{#%NF-EHlDQiWktuQJ5s`SIw6rAiDC-rm8Yp>u z3bu*FQ~FE?I9Y!WGfSBsGH+3)4}#>Xm{}5t=Pk-Cg=1t{O~MKIgoE1nlt_GCd5;h_y zGd!bIBJn4237A-Centt`a*{7#4@AgUu<#v-zmAUs-;>3EM>r!A&wD)TES%@0TlgYe zBHzLMvKYlh;>+-tBJua}*TCS#^L~%|7Pxr)LwrLd{xKG=dzG!_ z7`9Q5fRp3@#=pT6@;~@bctwU$Z-K$9SY9HbeUi~}MGNdpuI4Vi%kZxvY1^<3Lu(K~KUIV2COT7nudK$wM*2GsZgj%+2VH65a*7$&=~-==~fNb1)Sv;3#=6)<6k)0oH?= z%ruX-f|I-)yTMCdg#+*jc`ZH#r^(y#r*Mh96Mqg@$h>8vzx*FENyS5iui+a$IE=5s z_v9kX;EaAuR$*pBpdvRP%}k7D9xA#p^NNF`su%z{A0 z&+vPcE{k6{6))p@Ak4uH+z48b*+5n+5PHwlX3=|riVtvS=u2kWvzURb;pFEy6SB!~ z@mQE3ktCGElwKf#4Q3Sptxu4}6Q+nHFu_^VfH_D=#Ir;anCPszu#9!#NtlBy<{+Ue zrt|^{?_)}z#RDbOz|29`CUPyj6}FM<;yoe>406^%`kzJl6L{*ZBO(dHlQR!l%tAtA zOz8y@nqduS$<46=_=S@oRL25#a$8J$vOMID*as1ES9}aUCiliCL=yV){%0{P0tx-_ z8K7SYLOIWgBn-qC;Y-#BVdf<3JF-w_<|K<2C5*v8!ZUIn{u}-!FT~7=K*CaqBs&UX z$W$^r4pN13QOaxvLLgxyt_Ib~n{W-0ge{m-X4heza%MLKo;-n9D!YwH0+q~e4?KCo zVa$AFcOg^F>~8P@S%G_rB&e~h4?lSF1WKDd0EUotm|@BuNjBqAA_+Fk0A=U1PPwxu zizHC;?5QFNyb;;cVGifG@jRGM4q~d2y@(vfOMp3&C6p3Y!5TjJ1XGdh_2ko7s0L4- za29Wa17uo}Ej-;3@>R_53xR}hvG5R(a2;!b2T7n+*#=-U3EyKc_{l%xF#XRy!@)xi zgquLZb9^3nKNJ4OSKtdWJGL2NaoGTVJ32ziNq$DnaGhb6p36QhoQ*nP38hQ{eY=Y6fQCthLDAe41?k1 zPIx4YB6G2vERn?ScnsvS-UE*V<|R?Mb^#QU`(u9Jvxak(yNfvIj2lkTl@P1(G6UXBsP>}QSQD6=dg&XO?K%Rlk;3Ch$p8p|}BrYQO zL=qR{kVxVZd{QKFDLyTdxD0;^7r4-Jd`Tox*!*SqoOK=|=L?ZU;X%HJYpm1m90oFn zIZE7!Zwd>yIM|GD!yPh{p2J|}+$ZnAk3p~S?iX`sC3}MbY)~U!ChHXp* zGL;z<2NlUja1t;}iE^AFk|@&-NcqQnB$9Z8_kYYf4j}P+ya_0O z;!RBH$Lu20k}(XNKq74!a|jNT?_r^o!qEMURX_z3A7GtG;;&e!o|X0AupNW}e2TpS zG7kPG_#r^1zhgoWCjX0tl0o7t{E0~7YkUf*TH+flR0(LWWXwhQn#}KzF+v3(DFF*l zT}DpC!p0wxD`T0kLrAKDe}^aJn)pw6My`#8P5nczk6!|tNot7SiX=70?u7oNgN!@WZU^7WQa4ld1Nxd<@)y6g@_r=Yj zHF+3r2kptDuyEnd=IZ;UXE9YBz=elR zC?h-ZJ-AQi-mJxbLL})& z%#`Q0W&Jj05OX__@8T}dmCTdo_7F+pVRL&zZ`OI}+`;recQ^-+@kkJc?hl*|Ipk+} zEQ}-njTz3|eDX_N2*NPF##2R--r^a+P$vC{=ZGXn;e{f}LZudqB+H@+%S4i6@Jjel zB1tZfSBoUa;$wG_xH7bzY0DFO9N*3D1yyPAyH^HBXB)7z; z;SB3SyUxNnavR?N+zT9BXalPcb^gmCyfG}JSu<)fjiKNuWnIb9Na9oZ^N<%zO zBt_W3B$1THm^Wvf@Xvoznh>VJ3@+LX&lX8(iRZ#R)`d;35J_o+KY~@Px5aCLHm0=4 zJ4I4>h;jQwQaa%SaFBC4<0B#|U9p@mjyuW+-LM);$UQNyjzCHuY!*rBiya~V&26o&TvQVkBA}O-b1g2FWB?~jL<1Uf2@n!g&JO+OW zUy*b1b@+}fl=h}b$^?8%BxNH037GU0q2%{OQVQ_T@C)mO_>s{6#~e)IfTgk z8XQ2%GF%7hl9%HKA}K3zQ<0PpadTjTQ$E72MN(E{WSBTVlXu>*7Xa+6Gf?ERvC~bv1Ku0pi6FNh0G6OlGKMWu< zd=mzNj2}{lZ^955O6J4~!(kMeA)JsUA{9=~5s?nYc`%N1gzrrdkq*O?M5Mws3Sb)N zjKKVMoiK~cuuhl@i^yZ?|AeI+EazY%=JlGehAez>D{LckfeAZAq{2mZiAZPSy>NhY zxbTESBGP$SB_f@VHNfCX7hsc!RJf-Fgn$2+GUXGz5aFbc@G)Qrr5o@kBGS$HoQQM_ zz91qMHhD=z%4R2A7Ljhp--t+s&GXw*K)MruFCrBlBKY+ zj5q`M^(ZytS|U<6W*8?5!|1^cp%K}Sn}|q*xS5DFgxiQn!??YOlnPJmA|frtJ?Ovi zLrTdf_7stRjQaq?C#4M&2Z%^%#l%4((vz6Mo5;XPPhkd3K>8`p1cp|67BjE{(u+7x zL`u6RGOz;D&*=Zed=4gaK<_3_6_I|4XTfaNzrsxHLv*{c z|4(z0i5~*9B)x&xf{c691HNBK-|(fL=?PnTa|P=^t2VCrJOqc5slNVwsB{Abo~CB2tEIqEAHnHx7tM zUtpo1v`hLA7TR-y%n(i#N)OVv_=1S^KP;3Rr0=j$;V<~xa|!-RM3x#u5XyR$56WYq zl#m*Wh4Ot*j>A8Qq*lZ~!fn{(k<`jqcxoOhwF>@6 z=>JO&YH%Pt1*F!-!c(yO)H)K$Bz7y1S`U|lXmWkbt2K#Drt&sSVk48-Kx$*m<4sB< zH^Ujg22xvKZaAqrxi#i~0;%ok|D;;LO;bDI1|q4Quy8R*?Tm$sL24H)T#SpPcExR> z9r*(+e4leud*L3yT53Nm978H^(xkr7pF9u?$oP>ugfLhnbto1X#yU(IA(ARM6GpK< z5@$m$nd3?0VFGy!rc{&i$$U1c5T=sH;h7?-!soMLKI@z(o3xMvNae&yi(xr=8eR#! zE~&!F8(|Z9Dc&lQ%6XG^z)sdz;61RH{2@LJMdVdjA(FZl9~BY)soSKI{~?p4t|RcO z2&8huNd~ZxH((n$$-+&&BB|VPl3yfs7Y;&%b9UnsaFV$#o7?_$J&VoAA#fsUG|ggsB!b@GJaA7B=uFJS7Vocm~hOVf+IAC70q?@P>RG z{|E2LY%o6xV#qRfnO^}?IXH*Yp(^=n%(UhUQ+fl}5=s35*MTOi-@?tH4Vew+w};MT zHkjWHdXw2;en03>W>fjhTmB$28_OR;|Ail^>@a^AFl4E3aVCtCNO+4R`B{)n=GDs| z19@b2of*Ry)m{}=cM$!)9`oN5&72y^lX&T&0M3zPg3m71QG%cpw0%?@Bpo2)79(NT< zqs#@ppfBeb@c#+6 zz=Nkf-~t80liE1=6?=ePrai~PramFR#lof_Jqn)%<|4fu7H<9}S!m1GBI$|vDtya& z621ZV$h4|JxH+W1j~{@H!AP$`_!GEMI=w5DKs31p=66FO7f)}4xo}}+az|VhxJY^* zTodY&X+>cpXiOf8n*wiA`f%JDxJG&=ZV#Qvv`SXkg#$<*gS$gdGJPxT4O~2($uH~& zBghkRmPqD&WmX--zjV;U@BCyj3K97v2FoS>KHX=zTiBI|}!~A@Y8F1n7Ud;G>`-GYf?p z`d`Q(q_a?H03%t0&EO(yu}>tO2`>zZq}y-=nBsIhJ}#2ZcM6#qfpj-M1)q{V_&j_? z4q#?OAYFEna0~8mAe>wV_sC~4gHrf_d;vcaN&gK02EVg@8UG=Yeg*#}lKusLE|Si0 z7QTRgIiH&sz7k1iKnvf{|H)B&a7`ka91St#n>ZFKlG)hgL`Ww8gr!i4%myb{gL>r0 zxFIwmbJNL9pc$E)PHqXU$uDtRXiw&*lRJYjbMNT?GfSm-Te%*Ve0!i0#l+OhP)Ot zLsMu`2345C+)PO&Q-vw%A{jezCHl_~NyaV?=-U+fl|gx?)Dp?qiz(}rW~}eSEkrU7 z<5nUWM{oz|$T>y03v?yRad)7y8B}=+Rh>fBGBlWq31sMHgu%cdWf(A}nUX_xV15fu zVW=`ZcsxuX`|vcFMGoLOKy@-G^OQxfn0x{+g_Y!!Sg6bzG9{lP+)tQ~i&&_PY!e6c zVait6LB4{8YCy)VLP`?Y%zuiSNe)@-O@l9+maETkQ4;`7eGJZo2(H{3hPc zWO6oSbJNY-anLNca65L8+jy5mj^pmTVGrv&^4^J@Y@BdNBIkd6 zIF4}Au6z`Zk$2}45;^h3lW?kazYn^fjx*&0xLYFUVD6R3iEH;sMp+58$_ zm*?`EiJbZDjp+WF^#%L|V)9q;*Z4+`2hV=z$Bz!y@XzqN<#>m?|B1ik3;CZ+rpG$+ z#k@W?kX4|^#)!8-6?$xy$We_R+hKd_*Kuwl=LXJ$wkn;hbg>LdE+!JOXM=5*sgTCh|XOF>&oUeFjB1dU^42NFlC~=Qb z7%i)EkFklIA6T1%oFDbL$7D=(@Doo@a=ivf*BfbdP%N*!okLcm`a`f>=XiIJm-6JWp7yceU%DeK<_(k4>|9}eS?#2IRGCG^h`JdqF2 z`r+caQ}`%!m8bFXaPiz3d@>AV?riRk{_gIN3uU(2!fZ6fzeHc&xs zd~UFM#y~l*=Wm%zFRxp!&w8zw$o-QyNaPx}UK?Q(=lso^C364cEf9Yw+`$EUZ3m%4 zTqHly!LQd|g($V|0=>!;9k${s)L7q|y*a%)%W(}u8FcWv_A;2g+U2<34%kVK>v=?QL9}bc$_|QZLH|%vdjoTkxxu?hz*>Ap4MBrZ=yro zr$0tn-<`){y#9Can)RB9s6^aoa-u`r$mI5#ZrvNwYi6Q@oA;WX=+KqtVxDtiGYha- zK9-jzI>g47;~eWJ@%gw=?#7quzaNdHh$RLp;^L_|G{PWHP~{&u*5n-Bx#z3pw7dhaaX%m2e}vg-8S1N+Ml@qvjBPq8)!9iHYxak%VN z&-Omjfqr#(o{z_g@~eC@PLQvl1PC;rWRUzw*LF2W{xBJ-xN1!|%KTtK>g<4bGAO z;q##UdC`hXaHYH&N|jf{&%tozX;1H{ zhAQNB=6LE4#_^A6&TVZ(X)*e4eq< z?7UBl+=K1B&knNw_AzLEc9!+Gk3kFa2Jmi)JiYF-MCjXMii;Mq}$a9lEepyZaI>|QBw+8ic+^BORe;qc+LH@ejn#i}2zU?r)`QD_yyI~JG z{(+#r`{ED>HqzHr2KljpBhgjP<7080Y$JV7z=?8f=Hx_vM?O7~U&?3VEa#MQ_e6dL z8{)p+s(cU8w=c5&9C$bT4#6-vo@#U=-_!M-h{@I)cq*pJ@r0(o?@T$KaCRa;o^Wm= zzYBW{`Yv$J4!j79<(+tCB7Ya}f8VtZOnko5^t})l$$PQM5AyfnD{-|PmAV!;$OrIE zF!A}S*Z1~B{$YGqB0s8m5AJi$5&Qril2x_uqyI-XlOLsh9Huy5iTggC$UlLf#|ze# zyRSj*Ybf)hFq7%GE;f>f@+R0+)|P%|q~EskSk8qx$=9NOg^B!0Y%cogd%m{ytAJkTYgfN& zXm9>3*4lmza(0f;l*pgQt%-cS>!*kPv?X5;`|XB3*`5+uDujNCb z{Q2jwK@Re@xnEZtBVWL(osA#)7dueyelgX0-cN~x{LA>%ME>Qh-2J*+zk-#xUoZJO zR@Qzhm~SrnMfC>D=Axg0?l(fdjiY*FBL8mhf4>P1lr8@ro&u%HHz@sPW3K!t zM>UZD1V;rtdH$0ePm26!`CP;xKgSosL*>87vGH5vS2#9uzx)wDgh%y1{~IALjQk(? zDY#(%j~o|xS^kw@P2~TrZ5{Qvk1qM)4H zu#DA<`##2MD( z;%6laT(`dg?cdw_KHL}m3XPU9sw+xqEz9ySz40Fp#gu z&CZDp-;Voao9+Jq9+b!P!|=uw*kJ!B@T44@d>YTlHrxL>ye8Xlw*MOr-f^&i-^WMt zQvM`Su#!z{|F5mD;&1V@d~PN)z;Fcxm$2as3NGbMvAKL1Z;7qsD|s7iCtuAS{*P>? z;5xyu4KP>*o^U`3I?6Y3CF*7G?|{x|lJDjg7^;GMxeLrjfhr6zWCP4Y!9#4w2J9g} z!h0nORAa!t*w6Y?e0(;3I8d4ahG@V^^0TaOLBaEU8cvsA;4>2iFL5{Yvi>snL0?%l z2lP)Ayu|}C*!tV7RYAdfJPKpvtdb8HpD0lJ0aFqMAM^A?!6!TuvwY!Go|h>2oEIbt zzTm}J?VK-pEzXvI;wU`|e&HxR3Vvmk&&H2}-yGbSDEOUkhLRWj!MEWK`7gd3eoYtr z%lF~_Or|iy594upU49Zz%VuFfRPs4_Q;zDrC~wZM;8l4`@Be_;9lYUSYmSnka9cK% z13r|uaXP@{uY1BWtogh{~v|TygoLtZcYZ;$iU5H^D@x2f$f7!ExdVa(6x%2C%Rfp9Oo|Dhz7ZQb+WrdeuA`36)ckr%!6@P{A4>I9{ z8hxN7gPPDLzsfr#3g6bAd_DBD-TZ;{>7scg@5zdM4?s; z8jp$2|CbHzplO**QM6@7){j{Zv|-R(ERZ*0lRjvftPO)!zyK9(%WD!v+w*z2zOh#8SgO#@E5Z(YA$%nD321Q5mW{IMs^nb7t2Sr`k zv92>N;qA?s7?k}6@!2_Y*MH6`he6MISk4_X#*0iK1A$I8n5mufh$^S;05q zX89bx4R^`s@#Bf2_+I?;AA_Ir!6go!OB7wkFC>aC=a=xRbFSdm@rHa2zm0d~>-fDy zk(&?xI8k&X|Bxt(&HRBFSeqLBPon5n{U5R(VoL3DhzSjf?&i&~xqJ^B%An{z-ab*} z^&FB9Ls;|x7bS`w;*vzs!)z#rlsV@SHjF{hV_c7{A4N(sq%l$S1UI3@x_5lY4vC^? zc&9|sv%G7f=sDgiQS?0ThXZ_91&17j7{HhL@I;Xc4)F>GMJkyc($xWq-eiL~<#i$t*@9BQ{gaVy(kP~65H62|<>R?4j+Rg2`0P0O6g~mnvJOo2&|WaH#eKP7qIdug z#31Y8As8wT=HZEA$3sV9jP+qW4pZcjYiEMa-V)q+5J5fA|v-AB};DgD$1WV09i(d_cT0EC;z>V@kzBy66m~TyFi{qwuB#Pa9 zs7Vfrm$8W+8k4-7AH`$xYJMV792+yyLGjuAY@+xaem+rrF29&4K966)8_tghc`N$= zmV-+iyoV3vOZk&T@s<2VqWCKQ8s9i4p71C9EMLpN;a~asOlH`+iQ?ONeQaRe0}k6L zQG6F~ip{Lwtsld-NECbOVcTLmAKb^e$d^@NSRp#fk8pXS_(|@BO6yN?H5%k+xHAlM z@k`u-R@sveYsZfAYrG4x|8t-M!*;_S@;hw0hwUf7&xau<`6KR{DE^F(g9$GFoKM9W z@>kp~QT!eEM1Skw^FR!hRchFXM6urk*W?GgLuIlx=RJ zMEQm-NR({OixMSKO>-2KY{_P4*eZD|HX}ia3J)_E!_L?LlI;ak9F%n6OJD{{^7sl| zCHn<4?3zSLG2e)rte5aDiIP&jEm2a&(Q}kUyQ1g!$Q2x|y^RA_KWp>`8WI}@6TE_d>#1^UJo0|W@Pv#(4vxKd7DJZ@vM5o3$2@% z;i?gooWzDVJ6st`PIjOI!#zpKX>8}icaaCM4Gy=ll0j@!!)>O-APu*X;RndWIW~fl zk$hO9WE3BTuGU9$Yzie~IW~ooar!^}LnnI_qQu}0pAOe3S@lIQ(V#L4G|^@-V-Nx2+rE;qSr_mc;cw#K-be{3*VYpJnql{73yS zak1e)CraMnU-7$>;(~wTZ}}bmFHz#cBMe_q@&Oyb5gW>GG{WzJ5nIY`G{OLm*iJU- zBXW=@f6WDnlJB`l|NY36nEDYVD3k4KL#Q_LaBh{n1t4 zmXAqv^o0?IEa+IuC*myGJw|j#FS$M|^g%xdaU+8kbZq587$Up*h+!Bm#|B2i_d4#x zlQBi!n+@6sgVxceMi{gabL9hg0SsuzgLyU9$TmCTY-9~z$Jp_OFk~H%A*!uk%(aP*sxz`N(eXxZPISD9ThYb& zH?vla+*MY=k>+RQp|V$SWLJG0+0}vajXW00-|;Cv0Vm4O@F|Io$~yA&M91g(OvFIF zz}?Y9eu;abulx%4$52_hM-ESPe4ouw&@uagFgnrkL)M0o6MgUzPr@wub2dyP4N}J+ zI7*3*zwpvT$6t9lR#^XySL1y74>nsPFZb_)TZgYqly1z|=>N!TeXxmx>l3A$ag+?D zoAYfjbfx+>GD?QhZTP-K>9+g;9EwoG2~z{*Qds!D~(` z<0unKE7)L;d|U3s26N;Gaur8qRHU?yzf6=iv!M)1Ti9R*rLFuuew5qz=S1la{A-~9 zr8^40L#ax4;=f>mOLyUzUX&W1Q5mcw@5UxNDBXiMgi4j}$y+8$4`7uEN)P1iks}|( z9TKI7aQywhQAIvDluJ-5AIas3(xX`gMtSnmW4H#Uzw~%E`J_Cl z;d`Z%IL<@qRF3n8%hPxa#>z7}{{3I0oLoBFL41hP`E1%pEs!y4aiVkyFT)D!OLt15aU(j*Hb1&KQTj2r{vX*) z=_f)vx;W`m-Z4@7Iq#Av^|YhCYC)-|9=#9tlfU8vaG?AxADSrro)1rys?6xFiP9hW z6d2l4l^T6U){iqC{L0>gF;TWYPfnC&qx>^4)4%Cb8%EDblx@uOu+Vz6WpScx3to!l*0*F6KYEoM zEn1T(+m6q{dDf#{7bMC$@I|=TdLCaE{lC&dfrG1YjaOJx9NX59B?(|D$6VP_{Qm|38RVnar4VtRKayJ!Yexr@#^?%HpiL#gY9en1bIQa{FBb(MS-{S}Q zWBxr+_9+{(F@Ib4ow1ojneUDD?vM4(ml@!(8zJWDYu+YN_A_sfY>p3p5xkpY4ON*5 z9&4b+mdXEcb)tM7u1}Q5#T(J;-~H+)W82Y1-h_9=p7LhAHx82BW9*?gQZD9WalBlv z|6@;dfO3;N_7t2dSMllSCfBgx3d-ZAy%Ob}xexkTZ{h)oa+?}EI8oll!!go1vB}X; zrt;Y21kBL?@?C^kiSm8faE+bor2TjiR>=pj!5eGf%00!{ixTBW^A)(#`Y~+4g7V|o zJdM3x_M~IYQ&4^q-vTpM?lm5JhyIT>SmmC2?0t#yGx;GHl=8FK5RH9F9>lLC%Dp;c z-@rT8hw*#(NRB7`1m>nZp71-EoAMd_bE14U|C%Vz#?$@|gH-OR$Nq!=75%LQ>DpCFxk4==n&C?R)@37L3o9X;_S?PoF z_gS^a#sB_O{(&$b%3S^-M_DhBKj%vl<@z=5%0&5ZY{HT<6jy7f=_Ty;>n{YfGDz@d96BXO>t9Z@&_WTAsZAC7})1g8? z$Hfz&qJTffr?S?Li--79j`kYLprVX_gbima%7woZ74;lDM@2&>Gd_d$O4+f-1oCwJ8U@pehGjiF|OP;w1ea9~X0x zijz4maGZQ9$Cu8OdvG^!#UM76LB&w+lc*TR{V~w`a2}kfFree(JfByLW`i44jO8)N z`cW}XQ0ws%Hqk(4p6ax&&7puT;yV0F2@(IN>r@oYv5OF#Txc|VEj$;*?cQ*lh5ZnaKG$Y z;~z{^T*(jP5$kci#}I%1UlA942G9B627VE5$~W`dcwfGUKTK4_1wX}S)*s?85*02y z{;NdAqx@Z>B5w3!qT+G>8Nd4O6a0IW_;&|S^Pl)jj?Mg=sIaLCnMB3&ye>9#&I`On zqT(&y3MJNUctR;E2P z!wE+xI&I4abi(o0x8oCWnw-Oib%H_dRLF*PLT}loCiG2oDrW;4bh5z-gY|#HFbAC+ zjKD~_hE3{(adPa~;|HBOvuXvMn%Iy|m?}53A)GKn_H+|w!N7HjC!CA<@{YVP(aD2O zSe)qeKmDJu)B!rhldpj3?6eyjwh8CUd+>$0NIrls#bxqAY^WyOB}b+1!F}?nY(^&N zd#5w_NoZrIo*Zp6U!A%R&-LGiP|u6NBJ7w8UK^7XBD2Pve`~I z340|v-OBqwnLFLa2SaH)-OY#LaQR+7GSTUN?waWI03U=dg!E86W8Ee`6n01?vUv8JMWa}q<8UO&9Zwq=}%Ub?0%U{r9Ng=C#YPH z55=*vo@P%-RBp*9!&6so#izqlS88px8$4vC)@D6qHf#7QO9W3Fe;1><&~gD|i$< zab+hqc-cvEHBZ4*xt^zEmfXmmJnQwUGy_?46jbVaRu!@<<#;GhA5?ndve~o!P>M*NFZ#zf^Id~>2QDspS0@-V&~cR1hdWX)0b9@+fF zAADsW(ErM=!b6ElrOZBpN1b#W8G@rw1+ z_^m|c8T=kTu&yQ9kFxQ@L3jQHpUOS>b9^E9;;-_3vi+Q8ef9=``?vs2vHhO zTlqG})1mSMz5zGNA96e?DnI6UiaTX9Gs*BydRYFPW3#CIk{?f0nx9Fraht6CnqwoV zG)I$SN++4l${+Y0yet2~@52Tv|Khlz8&&?p-{5EYKmIjQwGsc0KQo!CjrniMBJYrUP1PgJ??KF>I(di>_T}M;s)N|HP9AGLZW`y! zkmIJa5>?0X9L%*IH(h{5@`-FPgQ`>5D?Zs^R-MX*GN_7;twH?itvW+EKT#FCG@+9( zw%(I3#}%@jPrf!$6}!JaQPrOf=wz>6RXoV;i7F2?`A*zreJJ09`{j7R2VrQdM(h9N zM;w^gDo;B3aXclD=VxGIt0wUaiK?mmQle@azmlk$&ac5BSEO*tg~^0%y?Q}nUw2iC)&>L(rveXRPK$0e$M;|Z8-J*qhs+Ew)r&rDSP$Fuc+iXK&G z9L&c8c|Bf?C32L1S)w}1zamk+F|Wc}=WN2~B&xUI^KgOnE%_qcEN{cN;Xb*7qYY-R zxHR7xhs2$p!zh*7owxAk5diWR8Lji zi)#|q+BmfyW~;g%?~2`IEt+c1g6avJ-P@1-986?852~lI-A+ANwwtLoIQ0a1I>!xB ztwmD@C#tn->aaw$S8M8sM77pU9fi@(U(RuJH?3aD9(?K~{jXjl#0^n>HXD?wGv#yG zfJ~hu>*v(@SRh}-aYM6EeF>X`sprdA@`Z`&oA^>(V_pBJ-jJxin{P=}-^2Il|I`PZ zbgu(L5mZ0Kk0q)f<|pu^_4xehM0I@rEMBnwIKPCK<@o&7M0I@rdZOAdvZ-ci>O0Oc zZ&TmH`*Qs6|5FXt)UO=4z*Ivt^+!3r_;aEOXlW?Cg9GlAX4zgWVi>qG|i#VEI2bbkmN=WNJ3x zqtI2}n2*CLay-=;=q1Nf^}!H1Ha`qw<=F6eOptAM+GLosn%M9(OxORK&cfV8O*1b_ z)Wq%$+O*}q(8{Y5H9PRxiJBexT%6~ec&ZB$HD0@E1~91kA773u<#<>_8Px2-*XjSX z>m2OKH{eEjFTOcZvk%{n2d(eR4<~9=X4<28#`=-`9A1!5;Fl6LC$nJ;YE*368+cPb zmETU(#D6)Q7DIxXDCd`nnlt(9M9o?JEq-)PH;(?JrZ-2=Q4{5l-fCk_U;ZzXnVyjc z^13jbHG|n;PTxo#%A4zd{HPi3V9P|!2;LgoSRcs-bb5|FnmZs*9>)cV8oixfl&JAb zY8E#>&A@aOo8C{>>gfXlyR5lI7?h~Fl}9CNZsRfVv^BSL zJgFzCxrYF_1walQN+ z-<+uVm}66STK|Oa#(lCmnf?GCl)vT25;fm*Y~(5HKd=Fv{=ED%zmll=onKF6YyJ@4 zOw|0zZ{r14e`|>{=8~IfJk3WYE)UM0lBx?PhnEq3uHiqn1{N^0PHa+g~x4a4e zo5{?`$XoEb`tL`k*1*kJA5N~_hBw7#vca1XCvGWs;5ctPIiGV;C>OJ#3u-I44CQhs zHhe*C71t(eW34e!8&f*NG|p&tQk<|uqPCuQO4K&+E{WRs;;z`u`JH(W>@EBLjQta} z?R*#xx88-1Ow{hkU2&52xb`W?c6VUPXY@+c9?X3bwTEy&^mopoY)FGz7oIUBQF{cB zz$oi+qcIpKdlP2NO4J_5b1>if@w_-ud$RX`hKUVoV>ipOLOzvOC2CLSHHq3Y`0PaO znS4Q__AI^#7yE8Ez7$uvwWzG|6{!3tHuS+294W_w$a4T2-C7GxoIpAn%i? zeUkUn|M*d>v@;J%)IQCJz>w7{^UR|YwaPs6*hH;z&paL{I_D)eFG20Ad^*mQU*m4* zDZj~n^#--?a^FPld-^|fpaU~dt0yyuV5s~d4^Py7%;qAf{e(v+YCmO@9@J{xOsx!R zKWDQrbGG~i>+{U{@(;WyQTsD%=gg(?g%w&F*jEp=P-vx&M~ zem+sxfujwmiy?ajugdxS29&(6kWGD1SIqB0mFr^oqQWYhtt%D2#8*Brcr(9A)K&6# ziMlF|^8MtTYK|)XC41zV|3Ve&nlqVM>m=%0dA&qk8>_}FPhMv@XKjMbUMG9DQ0;^>h@(joYhe_l(WiUV|9nHo6o9|4d<*zbe50gxVf9wb>%MDK|Ypu#;)@5 zyeIaTPv!&R8g*x7g`;q^gFYNz>Mr{YHLEwQ)s5$ViMokA7(=bccSj`Z4BV_yiMpvg zCQ&zy$0h2f^8`4zZU)an{O|U4^MtvHI+Hr<|5LX>UXrL=$SZKR^B3{CIA31L1~aHz z!xty&*7D_vI^UUfC9ZPLIecxR?mYdUb-e>qTjyf4ZpJNgT=2F;U0l$_26dOPft~e; zd?`PP=j7}71-v5r{;bzw2ufv)7f~X!iPvx|euE#BjaLnC6o)zZkB>;y$J2IA)O+gL$Km))rrv8c`y`wqZ@{OaySy>?Ow@11ebLXl3d|mW z!E#h#C`QOCFng5#$B%jym^~J%QD4ZD6ZK_mnuGdso`Jb?1#16dzcelt<;m7o1K-iasfDtwfvKZZYnUe_PXUnJ^J;I9(( zCvx;0^(XNUiTacIC;V((duB(^Q6DY(9frF8bp9t%e_b7!H?L^N~=s`n9Ywb5x=JVm<@i zyRCoC_rk{NzvbA}!}9n1D6-Eu_(^y!QU4dmMr@$|Z#J=W+_Ygm{y5RF zIe!WpXxM_|hA!T)6~~2tkhkNw?(cFA|Cwkg^0OuIs?i%v~QF$>nV5 z=DJaX;hDQ-qM??z#x~Xs)7_dpyZWA33iLOz7O?sJck z9nU>Z|K}d(AQnyQ+*9PE`81p^$C_yk8cyP#iH4K89|l@!xIhhy^$DW zy*rP`WVts_g*UGu{``OL94vA$gqL82JepTyjXZ(RPBg@Z&&7GxP5e9+nx}#dQ&{!p z?IF)#l?WPUvsZMU3N*OSyu)#n>^}26Xm+08at&@c?|68s1~;8|YNEl7=A8+0TZSfb%d_KME))D2g$hnVN78?NDriG~|FHj9Rv^nac*%=5lBc)#bx zZWqY6v5Eu@_i*fXnS3v=f=xC&z-wWX4G;18xKMtKV^e5&k}t#c@>3i)cb|q=_*UGb zoDHuF_rVDb@AETwPX2~pNHl!UFC`j&;JCo6&iRqwz`OF#9N+&~{*ymVH2lY(CmJ*S zWukE%j=xwi&y5<_yfpT=*B+t2ysC{4Q_8aT6DB+$@us?_xpYHoP7- zkhf*uneX$)9Nr?)SioChYyEHZ3t@hoxV@8#ITsz|QjX8iSkB$iORnHPiN}M$qVOm~S@bpD*vuhBj#2i!V(y?j5_iJkhuhUxllkv@c(mXxyJ~ z#7))@;9C-n2k~u*#)J6|-0hr0_})b05qy85@ko9!(RdU;g817lja`K&@w9v#Ka1z& z6ZwTipGx(iEV>f;;(HQOeAko-^Kf))@@5!Ixb6Fd+^S^ZPwS(y6 zclbrt&-s7jA9)1-muS?(1%@nW9L?*)fHscdjj@?Lp0~m_@+3A_LE}_5TS22%FEDEh zD)hfm&lgm|Fg4EOx$#+$i62FQB7U=W7Ndc9zHqVX;^)j{Lk92M~7jrZ_m zc&Nq)cxIyUQJ#&t)*oYo95lw?YFc2D7c6)16vtDnmGyl=?A!!5zRVZkLitsWr$FQD z98YnB{01A)pz%YFjiXWD7u*ROZv2=HX3+R48_etiyKMZ-!9$2){DNas&&cLs!E=em zpEx%4qV=CSHigDt*&r@>TmFp=V9@vn$3|?R(J!h61}W?|u9@>2c>(J~KWrZbB+lnwEsjT4woZgsHVMU7R7Z{ zt;w)1nu&SxCahwM7Ry`la>U>NYuZj&iPiG<9OXk(2R!=Ct8+@(oCHlZd=KuGYuPIwG#TpbqK6zj;vmZW7#^2B!lEY=O;Pfv6HTogB}P*l zznExh=O{6ny6|gwL*9Yk!h7=0`~l2VQ?%=2e4_tNdkUW?n)YTx7Bua{1}$jXm%qdJ z@_uaS7X2nifB(s3R5a6c2rGBcbOf&t1K4yVZ=7g4nzu+a9m8Ae)8eh2bS!V1Xfh;= zwPA6A_2XH&gC;YwSh<6y(^-jwrZc!474n%}nP}?9)rqF=tn@)s4{n5NHf4JX$`>^C zXC+&_qdb6>Z1FDgAl?C@=fgFcF68+B za`|FjiB+;;T^!#*)7ARF_*@5Qx`r=+FE(Av@g+1}&!#?Tx`8iGG~LK?v0JU*#3nsx zx}WcaiEny<@54j#BOE*-8}7wV;RXF~dQNx=FUzlT@SglSe~@VUkUzp_*27=mOWEKq z{u)2Xju-!e-{kN4k3`c?{1*&r)6e{0CbMK6*?CK{>-({hgFkr_Y%2fDn`6sNra8k~ zBUfIJ^AgR@TT%qW*t{86pi1_gB{is(x8;UJ^Y+{sF4&yIZ7^He=D6UliRMz?9eX;d zjQ7SNawk3vN6B%K<8hiC7dZoG$^YZ-=p)B924aZ3FPo($W8?$bEG?NN$MvS_zaN?A zqa7Hip!pb{g*o!EY@n7bkWb*nSSp{y%VCI`Pv!G)zTAT^#wD^zUve2Pmu+gvRf*<) zY}SJ2{`$YXd@HZw?-R{y`A7U@T?Ll> zj=$w|`M*p?file(@w$m-)mXY=qS;%tbmK&`>SUL0;Q-Cbv~(+MBVWM=W@(OmHJg#8 z1@g6A1Vhz)19wJ~{2;etNBLnkSWC@A^OLOqLG#mm01lF$VRMCSrdj!x9+qf+fsaI2 zCn@Jrv#?a(o0W5^o-aK`ev=Jf(5#e8&qy@C%iYn#y3#J~m1tJsrTV|Luk{bPKZeL3 z^RTQRBONIB(y@tV=f-dKfhS%5yMZ{*4zVn*ZV@iDqqBs%=ZPtN9;Z1MO;w zR%lPqvOZssXo>&-4@;w07yBT36#Y^Dmgtd*U8>|QoAdRFmaX|_7|s^0T6zcWl%rh_ zBwBLWur5{RmJa+pRJNs@4QSBPiC>NWo6MF<2X8~!T535;rc^DB9A)}k*5{@1)SkAb zo#W}yvU4W0Y#n&2mR)!wY$ET@Tfl}}_TueOAn(T=6D^17|FSX%XgQqg6D>!u;acXV zEk|+-c96}*vYiqw=3-gg(4e)P$h#$4PUbxlE#_re+#D^Z@;u6L6b??b zoW+MGTDtL3INCYg`Pf8@!CDqKbn%wn92awLi@{nJ$7mVK25wnDc^D6XwU!b5|7jT~ z$3Ne*3@zh1hz(8P$%&TmR7|rzC6ih1+~s3r$IB-sT4u6eKtanaj`QOD*&Lr4)RuX? z7>2WDIj=}$TUHCEbvd`J;d2lJcs3ir<=4oLm*1FZxta}N(BiY@whe2qpY`kb zp+rl3{wSWYej6Lc<*&-lTmHKKFMrcPobWbc=$_z@@u}?O6-6kKP3?*@l*=x#q7$m* z*SRLq@)p-6T3l~ML!#v!Hcu;Jp5Emaw8`%)_lg~{n}d&d59}>}$@?Z+zU4!3nDy`Y z2pGziAGvFykEb_X!ZMG#lS@C zhCDdY>a|*7fL4rl&c-|zHs87xn~@bWhKK6(8w;>#4%$_{s;T^LJ3%)@~f-`%Uh}QNF+AKAFtQOrllAR<4UptqhG}3O*1ATaSMxZ{=Y)!hzRsrIM}eD(lZm zWmdPuThdFNe*yKE-DzT3_IEalZ8z`9hel)>rt_ zMC)t%zcQWzt%hUeRWNw1Z}1JU?DZGVu<$w5ne2~est-~KD+ScQ5@SXMb`3Ja2+eRGUH<)c( z@qdZ7Z8DivzQ4-%+O}n{^{S2K95$>$TRvwu_hWkp1)K|RtKgzUTMd^a+G@EJWzMPN zIIl`>;CeL6Sk;Oy@(#Qsc9M5tL%M2rc~{;yk!{;k*dGV@U@txxhOuoQJ_;wx2k~i% zwqy7#bhCae_dqZCcRCdEvk0;tj^3#d7QT!I(cFt&iFVQwOD|~>D zd@znbfnjQ!$OdWESMp@m`&H3UFW6ynyvSXj{Y^ zVN-cAYyIlzf7^0lYvjo**bJ;Lm(Sx)i8du$t=Fq-tY5+PXppbw&WW~bxdqYt>)0=+ z)zNR&T&>Nk_m)*~^?uOOwtKw)s}FH-xC13zeI&ZdO1b(N=x^H-thcLAl%L|0af8Tmg^xc6S-9ZmuIEee8pL_@#kf7ZS*Ib!sKZ4E5n(M6} z$u}n2k7ZN7=2q*+@$I-nK9TQ&*=e__HTS~2w8zHG%9@Auzx_`0+%0Z0uRQ zVciDTyoI;rA^a}hmxu9(_)H$jU%>B)_VH}+*2Jt#<=+zRv-l7EWqmeh4a*v|&tpTg zc0+kSZ;Vakg=ua3#!3 zw*4}}FsyCz!L{51gVBBi@0e&;*0nohH|w|YUf55*n-5I1E9+WqTdPIw5Asoo_Q%+K ztUbZH%C0pZYqg^N89q(_{m8UG=Rg~R_UBm}g7z0!>DTs@U*z72_LsRY23dcFhhl`R zMQcZ4jQk#J@7hVS7OkC%nexZ1^lRtJU&IMf?qv?X<`q!p_Mdr8qWxEnvYv1KH@*}q z)vkwYuZJP*vOeFO=&}(&W9bawBAMSm{+ZdC-PxVl-H8xF?m`Hm>p}=2gb+dqA;g6cVnas=A%yNO z-`&}1>heDlT67QtI&a$w$HCZb zUo1S7Q%_62`n; z+l~NUjEm04&j0n(^cohmV1I)d9JgTq1h!;REB5a- zEaFAEj4fCeVEs-kr+itMF)z?%?iv=|g^jIY(cM^HU(41a<{s=iYglwIc0Klg8GEv5 zC6f(d6ULp`g=<*!5O(u5EP5E5v4%yDVA-x^nZ$Qvw}ULkk7IX$Y{pMuc`Yp4opCRg zEm~H{n0LT3wrHM3^MC(sSuvACn7oEP4CeRgbu9Zo&!RW6Wx!r98p56iRg6ExE`e&s zpJ2~f!=f=Pd%Nrc)_IpKy9nwSe}TPp4U4|QUI7gW9A7hFZ!#?EgEEcy*Qf9he;@7RttEMhyC-49)?|AC!9lbpdt zZ0WMZqkMUc$v@a0;Iu8`t+#Ccl=U%QjeTJaIlR@Dy$AzRj*Wd4IBPj!?CbCbkaoVBr^!#Mk&vkrs#qvmLHcr7fOKT^n1-}rxww~&_eBAq8^OKfNjIa^^PYslFeJOBUxwjC~$nV0=23t(zyO3d{B_pZ`lYIcG8$Ttm)T*f-%l)|X&M-~-0I znwO6Pdzf<}_ETX0axTVB09%-I8J2BaKFOF@_wp%Vt8zFq%h|5we>3K6EdK}Cs+^nH z|K+QhKn`bN1^cxk!1z`yd$uCXm@~72En2Z2W6sQq^h$44rgS= zR*=d1L)h)ski%J8u|2SjIlSmsWdDzZayV@(7Ox?v2fGvOP7tSZ#U5+O;Z&~J3-)FG zIV^j);sC}kVGjbfE{D^);!r4M%voK*_RN#>7MATMSq9et`;xOt`kS}QJUQ&o-(zdY;Vrd_Em*Y;>ulAkQ`fMV z)6Z7wA4^)CCjH0O%(HkiECuFS%(ncuH|)cB3u(0h$1$eH>Jy|rSFd1l6%$@etG{Oa zD)yT-EPg|#yW)Rn@tfGE{)ZM1$vo@h|DnZiJ=L?9dAzaXfvQzi;4yxiy)CdpoJ;;Y zO&11k4BQ^L%@_#Wr?dDIXbNNq^a5vzGpfI`fOpYfyc=dc$cHj$0ODqeo1No~ zRzo8YyD9~WfS6T7oJlnPDTM*v8FNhLn9Pwd$NtXs0ekGl|uAo?Hk|H`40vqs_7 zys}rf%a8+EPzY7f0(~-!Z0M9>`p_dIfZwu!9Gf+}0(z7%f=q&yFd`#FQm6|?WjHCo zy3-BJ!)Z_llQJR&P!D4=+#;w3inwz!yj-9Wk3t@rQ3r~l6^3QRn8)&=7Wxx>nUxXG z0*b{+ijT_heV~BPI0;`;BOta`8X&$_FU-hT8{gW@*X{(0Cl^Btkhe}MlmnXUjLTRz z9jLKx7fj1ouMiTgd|{HpB&7jnWvrhG1g%ff28=hTg*NDyv7rTNPy!U%a7adKDNL?` z|LvZ!Q7%+NCrrrLnD~twWo(i!BdzKG>BCORNNk!cV^hR79g(qsCKeF5U|7aN3N0)G ziY%Ozkxp{@fDHcfnXwsbn-RZx8dL%E|ABw=85vt7LpGE^4Rp!iAEp}_V=}fxmw#() zY)PFhyV?J(I89rVu=S9P%q+n288vY-~^b_R}(UKx9V` zdS&oUr?IG9Mh;DJ{WliV@L~$)vXao(ev?LkPJmYBNq(HsC6I@IHFo&YH5N$)o)x_0!=U?<04`%Dug=d2O7T^ zor_t!7@ay|>xS9?x;Yt_WCMwp48oL*OMR#S0xzY&r6gZUT%uV5*j7}xdy z2~DYhy>3Fr^$1>1BELCn+)xeuFe9V6M8=JX-pJXzX;{Y19No=*GFmENM8+)zP!AnI zGyI&Ue=_pKaND}k*8GH$mZ8)~5&#$?=)0qrvGOatQD1RQuNXEU?yti4#%7o7sx>-3b<357#8hCb~+2hPsIDnvn6(l#GXqpijmlY0w74GP=?0E`Ta% zg;5!gvX*!>ok2F>e6$2ApavSC1v;Py24DmxU`EDc79>MDWJ3XzKn2u51GGQ~^uPd& zzy!?5c-(?y_W$v82H8*mB~Sr1&;Tva0X;APBQOCoGI}gXhIGh=0w{qBsDTD(fez?_ z0T_V^n33^>1cz4fW6r?a&SVFbv}` zE#p~%4{4AE`A`hyP|f~7ThE{w+MyfzVHn0?T1KD1hcw87d?kO8GKUd8t+HD2R&^BTop>y|N?KwyxB!Co1!XF?^6 z$atdyNPe>zI$=h}5OG5kek%`#WxP%7JBYqBBxAT*#=ES)%YnQ{f%oveN6!2CK+%z0 zn2_;72DHfdFd5KFd{iQ1G!;nvI2}4`x z{Fw^q{Ym40;rpu?_ziaBuK^jebTdoPED5u-GXBno8bI{#2^p&pTvY-MfWSZ5&>>?k z7ii{R3lRKwK*oPQ5ceNV|A*G<0_c;eWN3vknMNV>$TSn#e5r#;nS6_62Kc7aN{0@Z zlWCX2sLWsrG(fM+5JI66ATKm5(;?nr?z8|o;Y#S18A*d?7?kM}<2C|XUJwGFK#$D02W8MH)3=})+JInxMrINsNhQz%6z01jb1h=lqLH<_VM^xOh_20i?LL^3 znOp(Hu9E_+uY=CIWq^NOelyBkmxc8ZUawwe3O0q{^_ygF;KR7g4e55n0hy^iGB@G~ zHZG94i6t{_o=KUT60?Auh21jw!{g>=RWdg(1$-IVGPi7&xfKVnb&bqSax#hArc&m% z#WJ_cPsq$-F>6-l4nB;?%+8Rxs6b{8EOvmS$i=_YfXtm?moAxn^I-1UE^{~Hcjrj* zDYD0?%)Mx!AW!DrsX)#?wJ?mMESg$UC$qXn=GoaY&nbgpndc&0(bXQGB2wKy1Bd@>Y!id6$D*D!WFYJ8yNE!^US3*#a}}+mlCs-CYRFO zmH99(^QsbHt+5!|fV`_|`szWM*Q5eRd@V88Qm3f`(7vvg{pa8Jnb&7PC3MTYf%y&f zGMg#d+yHYjZ=~Q&nSl6B2;bZY6m6*ninTDlB?X#f-s%APw@%2sje@uJ%WUCX=7%JH*edg*Vi=V=WKNMZ z)i3j>BAAf*bCb+pSo>v2=5ztj#IF?jl>)zIz=+J>8)eR_``%FH;0;*BKC{e&nfqn%7O$zW#FJMh7 zU^5P;LYo4i4Cq$CsQ`Ro)*^WdxDIqG;I$|aEmR=J{s&^?3d9lf8x=?@S70qf)*4b^ z?Jfn9OBGnBNP%^;U`~Pc1{6pkjwfV+^(PeA0HF=>ZOAwkjg9IQ*tk-GO=xhFb_LQp z6xg(0fd#}bAa`Mv0_nL5Y-YiT0-Kj76xbpk#udnzRA5VzwjyC`61MJAAQQ1|vK83Y zgE0lR>r^0%qT5$1umfT{rU8v*v%Y9Zft-E?7Pl#oTLd(j&#p-=u==XL<$-d*xQ3i9vPFgFHIGe0LAtjRbYSS2b3vLlnKNf z*sQ=odfafSki_zE2AC~#PX0wviB9G(i~9hnT+(iR1dYEmF^bd3VXlqgVE1c)D( z4G0}iL&r}mP(G-@32@?+0w*+2{o#*XVb{pXq}q{Gwgp&ivs5rDR908bap|x0=2~oT*&;QbRhWR0R`$1 zy`)TmOLOTOA3swFT;?foIpfPG6u6>afd*oh)+%r%8ds$&&?p#D;ObrluA%8`I~8am z?z&b5u4jHjBm3W6slbhe3UGZ7+?)af3UFNy+(NNiD-^g5q1Jo_ZpU{AXXlP#1=~3Ot6$<0A_6bSv;gmjX|+_7wBp9tEBziA!zZS!^HnxdsKE$My>b6nJr1 zftM*TP^!QyH440n|22xgHmktvmI80!d$U-9A=ci4#M?y*yi=>daH|6ElJH)(0`He8 zFoN>~#vkJU2$9hq1wI~E;FB>0KE;kv>@!5apzs$%3VezEikz>BpFr!IIR(C(R^a;r z1%6=dM~YA3|EW@epRvEBDKPD^|G$ufU%T3j9@~z-+n#e|s>h zz^ZNqxZMu?+pEBToeHcTkfkPBMwcw^o~;0IA+l@;IkKEWS>ah(Zn-S4N>;Q~R;)r+ zd{ma-BWtZpS!+(JXyOUuR#}DB zvi75){c~j$p0=fBdkla&pVjI-v|^ zWu3_U#5q|NQo^bjmv!=(tW!E=o!Ty|GE>%R$v^|Av&O~5Is>7qR#|7J0`s$qU{KbQ zYFRw8wW^6dyAY;jokQHYG+g5Y+UGUMIzM051!&gJ(;@3Z{1;K@qH*^B;x<`z2=G6W zvMwb!(IczAN!DehvMx`7FY6a<0bm0Moj*0H$R%b;`Of z4=8>;#cn8()tn*g#uQmM)ylegP}VILWJ97`)~%^f0W@)&1Cz2^2V~t&((TPKBI}MC zS$A?2clOC@E0nbiv1N!a_n=kQiei|N)jlNaF0}4u{ciH^sgl*2hk9_6SWot5<%Vvn=dQzz>Q za-XEJCs}{0O;#`YPZ!F1CJoTz@s8EkEbBSqpC|wM30eL4U$kJ1{eP)L*2|r;2H=$@ zS+9=EdX2Tg9$BxG_y&n@((O>GthZ`qz1=A5oh%@3xL?+L9t_HQpW-8BvOb{5hs1r< zB5M@QkJ0?3SJtP~vOdd@^?A0eFUn<&&&m4AWBQy>ziR&-;T(d%$N0jova@? zvL7k(6P^A{foYO{quB2V&agJqF6$50{+N~ZCvksKaF+Ss^|Dsw%le1dIhy%51tw*2 z(Xv(-!K`eJ%Qo6&n~5&jfhyTnscbt#b`U~&FeTe*l^t%B9jTY?mdN(XWk;)J$C_lv zD`orSBxTB8%a^@2{^T~<>$J#T7vFkyvQuhgb1}0wD3ZNlGEB?fC{^~xWwJNPmYvot zJFzL9Z2xZA2M|<*0CzX`L4&f3(}1-@$T@`d!!l%-_&~!YJ+cp{;ltHO!hT2dTlN+ZbIZba;{I8eS{dti z?b)*LApg!%*=;Sdm)EoZ%js}Mt?c$pAowms?=FHl+4nHN*OR@HVk@U)-&X;%vO61P z-=7CvvL8V7fg#xs4$AJTmi-Xx57)_lgoYkLyBm#1nLkz|`|(QIJ?QsL%YKr$r}+7= z-P;TUvY$?YHrdZ`M9YAW%m~Vc`uUp zVm(aAeyI%5ewmyB8X9N-)?Xtn4 zP?PMp1PH#J4db%kX_P(e0pjnb0denfir<@({eG3~5eLxxpa_WnkcL0P|IrZpKbj|d zl)=ZDFd+MrDxi^1v7gf67=_1rWPe87XT7pNFM%1^UsT8*_n=eumszsEN{4CLUpL5} z@PYMjlA&Gpx18B;`(%Gt4U@7bYXFV!$JzfM=;Vh{*+16Ho}&Aye%U|K%ufjXTnS^c zf5A@I%KjDmo1h8iWdBYM&w1?`3jfg|o9}S#KPP1WMeJXbvS%A*|D6HtvR9$GYDo4! z-LmJ3WdEBB)9n9$EUYGR^@M_|SJ23Sb_LCR1p|Uw1+8=#RgjGi2743?)d2AhzA!Q2 z76l`%3cA@aqM%m@GYUo<738Kf7#mYCUZ$Xrrq4KuwYAb9F`(euOxB)KFu7U5by5{v zHy0)pT(3sKlq#52aDBu#V7wvz4JQ>$#kWxw3@NyAmx7xxPs>wqQxBRHTtM7{9t9VU zE6B}iaI;JWH^;X*x?AASC{l1s@)KJQE4Wn|Ai8zEf|*qcZj%8c3T|7c;C2@DDVSBQ z;P&M}Gduc#%^p&4QNMyY4GJ#KgHZ)@(bx%%ou(Dsc~HS!@a5$K@w;{_xEmU~%_+D$ zzWi1tf_u~|xM!t;d!;E@;6S5-dy}*e;`<`B@1%l-9Lavf@YpoCKf(tLD_GR7;DMzI z9)$S8E3YMk=@kcc!6y#1ecnsZ_ zCBuM%$5tzNT!Vtgw<=hkuiy#zPxJxbNvu_5LBE10*DH8Rvx27S*yf9zEiwL-w zq`EW(`K~v3DGeq#l6ttTSHa7x6ucru!3F{OOUb_yt*crTY;0BVYVxnaUR$dmH>APq z@LiAI4d^!)D0m~9HXPClGwHNWrHZ1$!+RQt)YnpP`{=n-uJ$^XDoQe7;t}7ihG(kU1>YoRh`6`f6nwi{!FTEu947bOW(D74?fpUae}sS!Som;Q zK`x2G(N+aNM&y$j1;;!EKg(6{^CAVm7*KG$LBTKaeTC436#Ry~Z)X*pELQM)d_VLk z_~VFzKUFFCGX;1&7o4U^9?1oNpHT3RY6bu7R&bWwzw;Dam8ekgADAQX-#G>Un^8z5 z3K=~L1zHrcQxyt!DCDFo6z)_gGNq80p-{A5q1c>4euYA7RYSW%YZn1I$%1B>RcM`B z7*uFoG}j$fXg%^$@TZ`)ex5>!^~V+3fS?T!-mp!f)HEPrqg=qZF}_Vwpi7~&Y#38$ z(?S?fXhEGq3lUy8qELFbLYoo0xdpunZ84-!290e=?pE`lxiw8?61Po*LfcY&+bJbN z+w~}vh2ZuG?T`U;3hhWUiztvor(9e@IkO5a#^y55ZB%F{9}wSZMxmW+6xxNnT_~8B z1^o)`TCC7+MKGz*?&Rf@mrr~?I(wkIXOlvE(ZF7v355y>+?#;CdllM;Bia|SeMc24 zY*lE#0vJ?i|5Akx@L*V>BGwNqQ|O>%=v3%niXMzD#um>ibV#E@ho(cfLWj{@3F{?8 z3LRde&=I~uM`pl;LZ!6|9hE@zs9uGRZc^x&dWFg;ST?HAvCRq{$N0E$g^p)jPQepM zI58K76*{R+p$Y^mrW87PTA@=Ya4P=FQiV<<=5z~s6gs0qp{jC)&U65sv+{wQCHSg~ z+5fYX6*`+D=Ts?lZaN@V)2GmR9MSnCTu`SFkK;lYb}Mud;umKtR9C3bC2(mP0^}rS z6{>Gn=rVFHC+3Pug&K%kO0lIA3SHTt&{Y)*H5Mtvk7PpEQ1e?G(MEQlUF(0J_P2G#eN)GBi{xVkRz7d5w#}vB1U!e!!L5{c! zfrly-dKmFXNa#kWn*xtg;4vC`9A8hPLQfF)WQjujUPq{x@zbpeJ;VC5lM3|>EA+gh z&q?(Bq;o9k3z3;G=qr0KBdqb-3q-4LxT#v)u7PZbjm$m zXt-IScWLmwDuv#!R%nFz2gH1Y=xC}!A15pHNtQyN<|#CmuFz){3Vlxg7wC^u>`M;d z>s*B<@O@(`^es&!zMW9$J39NGg&#=d2M(br#DC(5euiHr75Y^`W545{sZ{8XdWHV% zSLiQtXA%B;Orcd>3jITYe^V6tk2A4)SdQA|m??4sd2*~)Id-|6Amb1?m2$%T{-@(Q za=alqv2;1yB02mVz)9+qv(|{5wI}7Q!}_|Za@H%7lhPq){Ruf67RX6$lC#l(oJ|l* zYm>7n@e3KJ_rsi=&4}NuSI*|S&?9FHbTepROAlD*rpMWe-~V#9MlciSHq|gCXIsR! zE0vQ~4AXLUAYn%V#j=UbA#QP>oSkZ5OwP{CcfrpE$jNJvv#SH+a(3&KvpeJyw@00v zJ?rJ{MI!}1FfX9i-ib=SOv>4(3b6YkR+tXma`wxIVLAI3%Q?V;b~#10at_RcX*maV z$T_%8PBF2E5PJw~hxW-itVK=n*&e6#*Bj=bwIc3Bpj_sFo z9Erzc%Mm=GUe1Z_a!%qDRW!*txmwOC`EpLpkW-l@=d=nrrz3bqnH-++JA60moQ2qu z2{~sId(McQb4%pZqyg*ap>;lmFF>P~{0n^`=b~Xb7xVi+P8~^HOq@#vqjZF$zE#d; z4RS6ol5+(@S4_)kz_+wt&Xt{VuHtMpW&&$hQ}~)8IoEc`X(H#kayi%IyCGLjbGDot zeHfQ>Q?s0#p#^TC!CO;+`+ujEfL6M`y;sg1wQ}wR?s%MKZE}`Z%UMw`r@c(hU8QpF zP63MDGc2d0RnEOta#j|}xew9K3OV;Pe;`lJgT->X$bE>Mhr8r-OU|R2avsC~IK_LC zfwS;LVn)tWzMS4HIZu=Lj0baap2gWWE$4ZHUuc%okI;*ZU#gVza*>>Yb~&%~%i(F6 zGe}df=gN5_L(ZG|a)zqqywxM;?KU~@5H~z5hwFy(ezu$uG(I5i!*V$v6>zpkIb|Qy z)h8WtKJAt>M&M^Haz1DNMVFj$_;OOt*J*Ml^5uNP`gfij?s%N<3+4P!Bj-m7O|{DT zsa?*`J#v0wJl!nkS9E@Bl=C}dt{cuDWpcP~IDd`G`J3^o2KN7-5jk^Xa{k5sHy~&A zjKW5T!e*<&feD4JF@^1Mg+o%<@nKTo@UX&>QH8x!g`>?1$3_(PD-=#@S9tAYg_8#q zUS~+*^~g!dS9twig*UVmP9=Y%0);mwc9U_1H|6*L!VAh3Uf8B^I)yjKu|xIGdcDB83-sD4aW?@Xn6HyHqQ@YqG+- zH7UG1{yi*(_hfx9;tJ{&-kXN^nNqkgTjBi@T?!visc_M-!Uq*7d~mD6#e)hTI;3!k z6h55bBYlNS^A$d-PvK**Wt|Eii@@<^3ZIax@JaYjE(Dr5#R1k&O@$GKD=AnxtMF;~ zPA`FRh0o|!xT;#=GnpsOoK*NMoJ*P%u5MHKYzmx{rSQ23)MO}p9)jmhD||t+!nK(S zUx@fcT?${!+9midEk=Z~*;Ty2cr7)%NjR@aFft!XDzM0&XOlVj5 z7IJTyR`}LRg}F}%w@TsL(YU=&;XCpazB2_l*tSAIXIVY_zq|lQS}~|_J4Nrxg>i-N zZc+Fi8tTYW_+EtWoltlsLicql+*zaW{fIq4;Rmq~4lCSMt?)xd3O`KYM^a%%;qD=Y zAFWsTv08;6?^U>`N8u;&JxTGWW)<#Dj41pxqR%ktOHueacs?0u;04zD=M;V^SK*iQ z6ds_FSMn8pmGNt33J+53b>?s2f3r^Ep?-zm=4jtx{!WX+!zsW)y<4O3d&LUBZ$Xd3 zBbe~c(M58+Ry75!+ zjidS9f_{Z(Xy^|D{-BvZDfkz@zc`XvVrQom{+lCOm9FqV4h$(gSFiBD`2Nd)0fkpL zD57FTjC4gzPZ1vDL;?efSd)qbQxplY9-2}l%=7<9BwrD?OA!xejB%Xg_=F;Ury@zY zP@~9N8PKB0+NppqnKf=qBJ1=kvTinvE3zJWDTt?xD6)RNA{+S7t;mLDilin(n<5*P z!l)t}R{;%dl4wyREe{CXG*giUh%V?*WFdCpoFeJ%ifo4HW;D1tahnsjML8gnL6I#B zVOkOHW+Gb`z=R^1G``)}TM3KazR7Dm|Dv~pz z2v@O4F3CI9DzbBdBD+v<7X!{m0CD)N{Vd7Nf@ih;N%(0*b_ktZ2HMUzjLK@$h?GzrgC zL$@N&;^4+3(pRI%a|k@wtH|>OFr&x|EsFGaDDq;SA}`Uz%lV27aKr;`FsH~X9Q7-+ zioA->Yxo8!I5?@u>y3)MLCl+I4i&?=B5x7TnWOX9zrQRFLp z+`L4-DOKd#bVa^vR%EhIk?(uh{~tOO;SMG;HLA!@2>#rv$S<6lX$teOIr6&)vx@wI z;Gc;9)u{*UJUFL!}pMDD^Sx#?qaH%DL#gfc9k z_?9GZH7<8+#@nRJ-L_2bb_H^?>f~7ytL2`9J-0?~O|jhbvgMvn{soB&xwTbtFQl7`;Nn`j zb=XTff-j`VtR zZy1z&W1-xeEx9d>Z%Km@xwkUDjr>GwsodM!Xe;xht8koRfQBqukCCx%U(QfaE^tL95)ZWI*pBVjr52`!M52D&=;g z**z-v(JJ=;u}ry-=fRX*z9n*>=#%>-MV_jb+slzWO_8UE?%SDi-zi}KhpXhi zTPydy5xFBQet`Xu;ve?N{is7OcSr6hNguQJ@toXG9l2a^+%XD&Rwws!*11D+zi5*? zo+bB7PwrRA&?WclX1NoUa=(FZY3SQ&x!-lmoy-H8_&zZu_lG{YKUT|~qPr=QeyWiB zbAjAnEEtqKT_g9`Lb<=?!=&8b>*dZMFoW+88vnCh?q98PXH%eG?%&07SEa(J+<)-R zQRCk^x&JlDUG2e;JeA4g?#N3Ro$|~~=#m$xkY^Rhv$N#|=NXe18kXmf5U!CIapbw} z^1K##(L#B#QhD)wn2?u5Uectzwff|(-5`%UByXKcdHgWTTX#y{dfoC;h+QAu^=IX6 zSS~M>@Bh4wn&fRD{nirvdG)MNZteu~D}{HRkhdF&yJPoAlecG~yuE7V6_m-_8{xfK-=|C7zK!wlImv<7jg1nP`ppjFEJCy>JrSeWA?sUY@NP%&ARUPuqY?F6Z zrMx9o@~VkD8~-^2^3I)O|Ib6@yjgkYkI1Xdm3LvEyo-9|T}+|6OnH~2!*0n5dCmFqZcLST zlLOQ8Zsz}t>D@xnTYKf*RxYo#UEb|=^6nUtcPF&f%3Fr`3JYfCwa>`At6SdP6uPHP zUI+er5nbuYyHE1C2zmFj_5iV6Rq`HcmG^MHyho|9N9o@;;-R&&T9_ z(JyZt`{lH}uXE*1Ap8x2-*(8G%#`;%Yd`eL`w_vZ33)#e`!hMejLZAALEdj&@@CTH z{ZS(CPu6CO<^A0)Zx!P?a{q0X_uqt~N>S9vRy1LDC~9RWYR@yPXoy9pPtkCXqOPN; z=P4R(Q8b>ZsGqE8Ql6q~`HHU1Jh@BJb$S(DFHO-D;?^HjbOZ8I8E=%U=*C%!@_06y zhW4gqiY};DbYZ8W>D1XA?JX*mh-M(Z6@uJYL^G!p-DXbF?NSxZLTLL2MRzPvG@Bwh zQgkt*xfI-M)F~=b z^gwDJL`-p3LeWDgd{~X5CBupyLE$4S6g>*DqbYjKn4-KDqsJ90T2AtbC5l$0D0(u! zQ!^Ajjqz!tik{xC=o#cyWhr{5rRZ4>%qUt-&e@F5CgxmxHOy-$d_K7sFs@Bd=)z=0 zFT#0owxV?uxTIUrO9vILXYH~oMKAABv>{#5rTDIFRkV>K;cXVZW<=4ZIz_LSqBoQS zam@ul(>Jy#dQ(0ODS9(8Eve9}=q)vh-dd*UZH0=qqMzW$DAC)Q+)nZxG;_zWqIXiH zjf6JVmT|h4GhR+ZE2^x;lLA8BI$yDJoZl%z)qc&tp($LXqvgeNQ*RP@PuMV~5Gv={N- zaYdgd@fp^hC8sYRW)yvnrk}4<^aa-YY4XK%MPH(^m(YBJ{4(w(3@F>t@9= z$=N1fv2BUpj`*xJm{V+rCdGE7X!fLHeAdTu80UJ5?Ub(A&iHoeRV=Sxv0Y~s+g&i6 zP>iP;u|3)q<4H!WAOlF+o4|cI;(bXf>`-jK2F3QL!2@Wli1C44iXBw1*uhXt+#wZ; z9onkcVKi34n9ujv5pZO=Vx=^EREJ_mw<&fEF=aK19cRIaV#g*iRp@+lm=6Z zolKEa9GF(DQZS>~>G_JC0aYoAok^2t6)CnPTe0eD#m=r$?3^aW&ZWT`G|ofsJjBoM zQS5>_#V)K>>>?WDBRy7Euh=Dnid{Oy-j6~3q+*vbxtxRsiZ0Dk>`Dq!Rl?RpxxAzQI#d^c7ob`#<^&nVV1s@N?QyN&hMD#dOuQ|yiw#qR7@tgTnE zWfO`mM{5Q1_9?~gM(dse_P?Ve_%Bn6*pSFD!?p5e%!rKvvhpX0z@C{?T<`1p>!G^E(eV~V|! zt=Ov#ioG_Y*z5fMUyP>{u{T>38|qN(Edt&lfY0yPyPjh2HqPpcLCj5GFmx?*488?ROD%VEX7PF9SE4Y6;k6#JI>Bst$>e`IY6t)FP{mkhV{X@W9reZwVjQ!WCI1d)$MycX_WXG*0#qAlz zL&=Ie`HF{I6^{_(qkSpK)Ttbj4Hi z6yK;=@r_B?goI6N6<^Sy_`+_*(+S#aTJg&IV7B0uXs%^5O^M(Pk{>v ztmQ0RNHZ6eDbCv`&c}2761cQi@p=Rr;ujjOO%6LU?0 z;@3hG`PZ>_J-!==yOH=Cx&Fs*PFB2yBe|tr@mm`dzpY8}R=T}?Qt>-k=c72j47pJ&5rfFy7Il_`PL{uPj#lz6!;;1CHOH0Tg)9QoO4MMihUjS@DNU6@P@- zZtSCu;*X)5c$|fvY{j3b1&;d3BE_E~@u>mDdnxiXV%!HX%qso`LgVnB)GPiY zfrv$M1L7pe7X>Z6#unO@!yIS|2+!^6rU*qbpF8iXO-fA zq4gJ9v$cxtZJD?XPBBZ~h^;s5erRPoh_uO5@Hdih4Kd@~ECQxZFLVkT67u)1l)n#R`+2T-J_Oa6i5@(&{T;2QbG zbbd&K{6i5wtVezcg%59(e?+VNBPmph@2E-n$9VF~$T^nv7TQDL2#0>c-70ItC zmw!sC{8JMYuB?}TItyov$v-n6Xy8na`m7=OOPb_Y<2ySYD0&VJoSO@C@@x9!pI0WI zZzlW;(5V%S%fBd7{>9{7JS)GhQT`?5Us}RmC&PgJdK$S5?aRqeT+uGSp-TSJ0{K@W zd{rtC&^RXl>VEmx49mY3dtI9R>sw$_{tZRYEx*|Z?2UymBLAjJApYh$`7J5H+AY=c zZ*`zS{%zRX&}gMbYqR{@^Vt78eEE0K#GQ!VIVr!b6sF}bYm~pd5a#5sz~5dh|1JdX zs+E5?>-QjXPpkY63;N{Wn+aX=SC+w){QD@>iDoDH_xH+wfcyu>{e>&%*-$u_5`7Q>2IPpU9N|B*mVrm;Y3@{9eYr1M;7)md}lc z|4fhkXUpaDfYR?9mH!-?&!@w<{1@=`H^_gH!Y|UyON{vmivMzAMn0EK{}n`DnUnu& zxBS;?Fht(~u=$WLry<#P$)G29wa(LR2v_XZEHgo`g zYNL`iqM426l(aEyg4U)M3@B*<4J{-;oo3Q!m9!abKBc5B5@Slr7*f)fOtwOBYl1U7 zl(Y?nwk=cAb~KWe1&D1wp`;zAm9!(V*~BhlyjVbfZl{uVs!`I;nM&HlhySDKj00jB z+bI4+2%+7b-JRW?-JRW?-9iW<#LX2#2wgJCtc#D)+;2qA6=Ay)_?gb+dqA%qY@ z2qApu`{Q`$eV*r>^SnFX?7TBApLB|Zon^X;97iMwoHjFD>(uzyp zfUZ4+J@W;bln&t9OY^;LT>2Jtl@;UKSGoPv(Egdi60QSea$p9ogK~vgToqd33XO*- zc8D}8CvY7)i0iO6T!&ZSs#0Ss)$GazTt^5;j^e5wAniIz-5ss&j%mbIQ;$neKd$3U zT*nKwS-4Kf#HGEQ>m)UE(m1ZVUR) z3D*@OUn$YHc3fAffveTj)g!pB(Y(D0*R{fRgSf62Iy!LOP$Yz008x2nM|HGNxJqPMG?RZ4VA?2aK^cZzV=6t26=aNX01>)vi$y#u)Jo5pp&au2A! zuNl{amAF>d;CiSOSAR9GhgJ88gdZKoH876rG3h<7MxIdZU>&X}RrgdbuBR(-4GGU! z`V^jR#ieg2*RTqnFT(XgEv^>}1R1@QB~0LYSz@oKX0!*_tMj;CZ@@KHjOz^p*PAx3 zxAJj~=iz!=2Je&!TJ40m6Vtffo5c0LxF4w5$r4<8^Xd9X{H|*Wliu3b(dZ?hSizZ#0B^W7W7aaJvg}dwOwumG`Mm zJ1Dm~i948!J5-5VPg?GQH^%G47dLL>W}ud%F6`#uPM0XKyF~Wr#=WORN{4XoHHCYh4BTZV?tNvppN{u0!d)(*1Ju}o z!?-IHUm@Y4If45q@sC#RF-^E@)ZnpGxR2LD zPsk(fKCu#aow}=A#C?hiwc~Nus~PQf+@}xWZjjKKg}BdB$7e0!K3nm|8QkaQ<36t) zchfBH^XIh^X*3t$zOV!LMXGC2{u0eEwQygiv9%oc<-NGCRJ={|t6Fhit>6EeoT6g*WrF5J&F6tOx$|B zat|r+Y&P!aT5%7{V9lvVeek~XG>oR*oB5%&%9&fv2y^ z;C^2V`9Qk5*SkNG=9F|k8OQyZ>OMDdf6;<_Mm}Hl=u`Vf1>a`j{%#2O_XUCk=Gt)o zpw<6ah+CJI`==$`KO?B-mtNezj^bYE#QobK?%yYI|1pAlaRB#U8Myye{gQ$EpM2c^ z=HdR&#zPsNHTv4v)VWkC`c`F5n1*c!CXhLV0+sPCQ|8^eYEXv@&wG@eumo*X4}GXxoK(u-$P5jT@a-XfmO=kaWz_?9B%&*Is-5zjUq zcnVtaY}bAJj^~&bJT+B#j@4q0>%?=sd}_<^oKS!#eWHjbDOo4c zlWXvt(uL>Lc|50;;5l8zXGpwZ63{AM7o^pq_$3COOO?A!nynU|%cXOL7II~_&VO4jp0*`CS6AV=rV&qjhEORi z;<>gR&vg>IP6pSjkq(L7Ao2~Z!UCQf`|#Yt!JpIz?@5Q5M2+t$g!Wf=MRX@;&=dlVrkN+RDc%Ep$ zGpO%>&yx~-QsPgw;dxqOLz%)1o@dm+vl4q&x#uJ{T#n~?)jzM?3oUqFl=zE1ct*66 zmum66oFS-@S4Q!Ss_1wHjdo&+AQi#tcEtyitee%`Ba|HwW>&C9&~hL5a6# z@VwK3M-LL73B}%%@cR{bJ}3~Bn^aD(Wjr5g{?R0!kHwi%?2~pppOy#JLrEAY$}2r~Mi0gvwOo*$R+{M3tQ zUP3=B_wzKKU$n|!HD6HuZxa4(0nhKM`$GncEqMOy!Sk0I|63-1PvBV+{+Yw`Z#SO* zDln+RSfdYP&FVD9S`J1=mN0{{PKL0Ev2Hs?X1*|mv0gLA`Xv|}6k=qRVQi>zqXvwP z8!@saFcG4`p$C{yje!hSN{zZ#>w97E3u#(_4*L8TZK zny*mZ!4(*Xlwnl1k~R))#5hbwhbvfR2#Xj;Xgm^(YLSl8@zKg1lZjCyv12tqb_U~k zacZ@K6DBZD%EG9ViS`i2$zvF&YK5oHVbm*s+Bk;ZniyyFVKnq$oT>V=bbPkr=jivp z#yPVX=MG?;*M!kji*de+FR0f?GmO!!_=Rdv-)P3gjv&#NQH)DebE#@C>&9rU#JIc~ z;|kSWsaRVD##Ln)R}0susrCYlYr(iKQ<%ZHUdA^V7&m4Ky8jzDNu*Qcn`xr8l!m_uZsVwVy}&2ysq&LX}l@kTdf%5ofvN` z{*Ib@cM;<~X}w>p^Z!9F#-z+YY{B?Qoqeq1DXsF;T#V0(F{XPkJ{RGOF^n&jo9V;& zTC4s>wX?Mt-*#YpC+_!c7(Zy$KbB+sB%}F$jGrelei^`6a4>$W!T4RZe<-&&i}4r2 zlFt892F5=s__qP$zfrtvWD1LT*DArAQHyu&CcNwP<6XA{Z>F$*9^MTa@Mh)W-LM<) zMs0XEZpWKFfY&XqrxdTDm{&Ys4PL)E<}}`50p3s~2-BZMRC@m5#jJ*pS)(fag` z>BL)8hxgb9yvJ4JJ$@W-?E-1Z-bgUQ)XwC z;XS(oZ{rZ&a~ANPC$Xk(yys8gy!wUs7v$PWPH1@N=@FO@vaQK zJrcY}BKMBrz0bybe<$7tw4w(y@vg4M`;hed7x6yQjrY+dypNUOeOyfsmg0R z4h`acHf`X2PQmAe7nB%r@V?ZB_vIhQiljd#+-`=J{6xE=2&<#<1>#XDVr_lpd?Uyk7YO7XAf@Xjjs?L6M^rTwFh)AMk2>pECce6Yt-3c$f0={-c_I z)X2YD)qf-SXvMci0lqb}@U8WK%;L*fz_)e>zI96Qt=o(*Q}2I$>pA$=M^M2AllZdQ z@oiWnjN{u#^Nl<4WlPLeh0mQQ%;7U^LG|7~e7ep0%nU*EfDr7#7wW=i$spW|FVc@s zzcKLHjrd|M_~LE&5_R~TYJADuG`^I?Qj7R*VZI&l2;mecw7FqbV6!P=& zZDj~r#WtDv3RJsoF23zlyS)qwWxPW@z8%}}?IhEkv+?a>;#;P%7-0h6uEKKF?WTOm zD8Aj(J6*5`T zi0|M|e1|AsIf?HuHFJ15zN&V7D_ij$p}Hegb5sewqbu zz8hq8;|#u=M7+5W-z_@sQe(Fb;9F(m>#oIjhlKA^gFSut?#aM+uXw$h-zVb-s_{Ko zf^YQ_zK0ciG!vg*-TNL}!1sjWgB|#uRNd3{_;mUCp4I-(r){-wSd-@sVHV#DJ@{U1 z$2X!*UlQSEiH)k6(E)s~D)*XdUSGsF){pOvW_)i>;2W3mcppApn!dLu@x9ZA@7*SR z6W#dU8^ZU#8hL*h-=y*%g72dme7e#3rqVL{q!Qn!D*kK=-{;x*z9aIKE%I z@hzzKcQy1!hECfbBls2v@%`C|@2^^Xx}JSY68@(H-@k46{+q|Y2Eq*fwHonfOyXZB z8~?gP_}4S=Zy;nf3#!|&4*y2VZS3IBF2L`~5c=_JckK5x;5W+fdo}tjVH&?*zyI-@ zE%*aP!V>=A2>wtjeoF|C;g3ozDnok$e{2eWyaRut9KVw(%;8VY;!iE$&(WAWj(?K@ z{F`drOu5Z%{9CAjEyUBM>)%S8t?Te_Q-!~v0ROfn__s6D__xm%B(g&-{vB)Z@6?LF zs0aVfn(w0dvLgJ&mH2mU!oR#5|87D_C;r`qJv#93DZ|nk{Cnr(-=`3NnauWW#=l(ccfAkzaY@E=r)ze2GU(m!|v{~_sF{D)@ZKTO>oUXOoe9{wXFbfm`Wa{Nct z;y=0#|1n+oYZmbzr`YjYMXh2dOyWPu!e6H*PBHMGs>bT4@t>}mGY0TC2xlpNwi;+0 z$A4}s{_`}RFRu%f)8^KnzDQ;l_u{`K1OKHGZf(G?Yt?^+#M?B#N~YJ;Qa5*v_hSE$niv|z z|BQ&w77DZYpOeY3#GY6Fg$!W^|BLhZU&A?T4I1_F7-%D5Ee?J@l2O0P$)tSB={2xi=V>K~V zAWY!@q#ysMqxe75@$?M-&xi1TQG@@>R{S&N_`eeOs}cNPOYoZx{Ih-dzm>*!b@;z8 z#y?ji%;EoG0soJ^_lR^VI+*Ka3W{xzftgi;xnTw7M#^oh z_{OuC*&~>)G18{T#577Vy{(wOeoVhefh=JPGgOXgbzz1_F{5DGb(pap%(!xiX-sDc zGdYi$qxxK#Y?6(+nSq(7n$0^fw-hJ826L+-%&nE*#>Onj!`xOi+tp%jumApoS-60? zqng;M5mVb`a~F-pD$w>%-0RA3%r2?Lmw4VZ^2ewdm(+{CO>d}Ti75e1k>rqxxoaFj%kF2g*g1+%6L^H_-- zC*tuEsO`l(K{#;&vrfd5Rewq`X1!K-nsB;A&uGSM=*B!N6H~invvCRYT%-I&u6emcFPFd- zGP^>}T`_}sWi@77wjkrH#Jy?+^J`9u}wpo96O#GcN^95OMV$-;cL81uOr%;8SV=X)?;$Q9-=UtGd` zN%@z>eR%@&73D_@gn7(YM=@V(!hGEl(n^jEV7?*po7I?aDL5_>Z6wThM0ht-P*W3H z!Fv^$?<@C#%qJC}?8E%91@j~EKW@XEQZt{}n4jhgGSYs+oF2veyaw|N<-P=SM*Ob| zF~80e=5+qQ8NrV*}<-wV3lWm_Mudmr2ZDr!lpGFn^cP zAHt&WrzI%=w?vm@{*O3%nl}HdB|sU0HHrwVnMGi&Yyue-1lDdRu+9L1b@ltdK;{sE z^?C`cuRvBcfel9pY&1h(NxKwi+a`jY*(DBHIoT z*j@&O1q61eBCw<8MK*z*y9n%}=9Y~S*tMR(a@Cep5ZJwhz#iQM_LM=XjP@=gu#b+* zRJ)&e`}Y&j9w2aF4}l6bwxW-~A&OU~C3ILRfx{J8X%RT0n!u4F>b@U1Mg=t*k1HZj z3xN|Eoz^If6F9w2m?5C=gFr*BFh}6bHUeiUewL2U?j+DC zk8?7FZUX6Zl{`;{=ZV}Tv-3*{Tp+=8mM}`7S@{c9c##Y*mPtzsflG!7Tq^U+)M%^5 zD^z=>YTD`vT%AwgnkEA627znE(e)nas3CBJbZ+b=&{;;{=4N4xz%A7}|F=vL(54}9 z>nwpT72Kxe?Rml+fmJf~=j_(-vjCI0awfho;DDI@TybUs7qC!p_xz~^%WzR>ukG}1E? z_{t>kb*3;wU^ZKrBJgc5f$v24zJkDo9Lq^awOVCq9(2$mQn4nK{ z{|rHWM+Aci^8_tvgv$s~CAhV)jp_@E32v*}?FI;LKTU9la-omlj<(QAaHk4E zoFZxLTp*}s7hPh(W!(geRb0GCa95cxm*8%uFh{UN0=pLp;{^ApBDkj|ED$Uec`w!N zT}W`BYJz2%1ozbn_gx~mUl+msiwKry36lg5=p=Yx1HpqdKWK_zMLoe4#RLx)Cw=e) z!9#`!R<;s6w3OgsGCo|1!JY?RSC z`2^3+C3v1CsIWXT2YJ#^G z6YLV{wn~Dx7ZO~hvAdq&9UTPk>?L^DBEh?5bdL=0H3{|_1nMXw0SG>(MjlTq`Ghbi;U{YeJ|)qodk7AV5PVjj!gCTH*6|C<>!n0+ zq?6!F;{;!+Blv0s!Pi;{zCJ*3tdHOuGX&qtB{)7t@EtY%u4*Ud2)gT?9W9c{)pw;OFZ6b9MYhKfy0M3C68&nJ z;MY9_ziA;j+e+|TgWz}nhs3|HCpcFssO|^p|ES}iOks%Ny!3u{2>zl^=T~(8f0gM% z7s21Oir+Qjw}{|>4k5CH8A5C35n3ykP)0wYwHpZO z0VK4}ETMIU%xOaF4G~(ukI)7kgt9sbZ8%71W1CQRJt0>sA@@+4kVip%X@q=Zg#0Qt z+X)3m355y>g>wl-stD-|Bcv~kP^^YfTmtb)LWwy-$!tMlsd7R&I?fp&l&j-SGKE<} zo62;vQelBmo^qSF5!#}d(3YyzcStB-@Bczu$#`q6W*aq8&`M}q5w;b1yM993_Yf*< zB(#GgOc2_!nb1xxgo-K&?VL+!mm)&T@&$2=2MO(}-10&}hPy2hDw!ssmA+)C& zE*&Mbmo)b7Ahb^(p>$alp?&KJ?N>%<|6)Sr6@(7xA#`9Hp@XUkRg@4~VF~ku4xS=Z zX$Xsi4(%m$SSz8!Rku=xM`RK@GLKMoE}^6P2pv64=omFnBi?cHI9|smR1!K-#wQID zsuNDu?>|DP%n{NTL+CUSPtPE9MiHR~iJmF(vqWwzCv;9Hq4Olt)KBRANp-Cznq_#Q zYA;f=7f%zqB%9Ess&7@(m$wtTLQPybMd+$JLV6$x>1AW+TIpP;vBM;ELocD5^!vZi z%?_bkS_s`L;oI^B8EXR)S|#ySGlaU;@f`((?iA_HSweS7v}cUa-4eK`p3uD#?X4qp zpYr#qfd^FES4!wXOVE7v2%(3D2t8~QdPJI!)({%df*&g<^mtkaPsnUg#ZP7sdMZnp zBJ{M3o+%^r>>#1%B=WpOUy#s?i-cYh@nzwaenPM26MC(W(3tXX3=n#&kkEJ!p|__A zy{nw|3ZeHMLLW>Jn$&!9j*y-iLLW){BYC7ho*^{VNazymp|4c)^(Y}-_o3MeLf=*r`cC=p772YnNl4dx=*KKVKjjjd*Z4Dpeo@`8 z1B8Av3H{zj=nv)okjA2Z{~7wTfzV%#g#MPuQl79x=-+HXV*d?eF^IKB7uK4>T1{9P z4OnaEVy$BcGg#}YCR5{jeOT+Oc7sl=tX8ZIRku+M*2WsM3$a{fSndiePd=6bmRECM zYZ}X6k7WvhVyvJFLRDDWELhe&R(KIBGL5B|ke050D>jA|pTJ7U%<0BT$~dKXj$*kB zSeuq$ZI*?Vmxr~v#?9xjwh*?IM!v?arMpc5RzWt_w!(Jl46N;Su)WATh`giBcdElG z>cZMtE7@fjYuN}^@hsMIk#|$Rq!CLmB&tKfkltiCy{)umVu4P!l=iS>vGkG5eA%ws(+;V1gA2Gzh*`B+a&U`U*23$dQ- zz#3K~FIZSF%5!oh2mnX4C%dlRR#%s!twPU>@^S5fS^lKaI?X-gLHepT3K=*0u zgK4Y}C8GPY_3;SSCq-DFN@%(e>+?#iFO;9D!1}5mOV96?{sv%uSB>?(;y>hL{is@P z&8?rOuzpqiw`QzAim?`@^_Ps7H2=4buzs@9w!9Oxk&>?Rx%&$0=J^9V@32*j)%o5HMaq|VjTdKi)<+gH! z8Nyo+6W&H51xDP%gmv|Vcj+ZuEdH))et9n8-Gq_` z!n+R=-eZ<x@E!St@07t^YNjWT@ZBYZ?@{btHQGBv z_PpVt%qLZq28!e7bo>j}cM z68yG}u&VW-}!`>Wb#h~;eR#% zZ-~em4v{shiDZ~W)~+S8P9KqV)AK~unm6w&1EF;_f11qY$FnwBcjb|#8NIiLnN9(M3-75)) zEpv(F_Ym1y`Sdp9M7GT$vYiCC7kP(lB0H86*=d@HHkgrJnush@gT+fkmbVbut)Iy5 zs@bE2$euMs^tLOqcP5d2Dv6XyYdeJK)T;PIgUCrTIk}L?DT>ug__TT=r>mKUN+M^r z6FFP_#v&r;%n~`Tj!2UXFKE!pdWbYH61k{@NJ|EhOEg|4?&ZZquF!bpB$2E1{U5nT z-M6dwT8UoYOXP+sA~y~Y>9mO4JVNBwE+So1L{>qhdxFTF)kJ!7iQGLyms@E^kjeCh^8$t(BS1nPu>ODn7jclUcOktX+Uwl*fU>4Dk zG%Rt$;zkRI+I>W0Q$*vvq@(d!qKOJ&k*L#6G-(S9L{rVe649I%qPfMwFwsqFh-!-! z-E@NJW)jJ(C%U=nwy=e9qFd@Xzm@1##YDGOBU{f9-DZGjK|j&$#M3L?Xdy&*(86}C zAi7gknrKlE(VgdsE;ET1R})>Xg56YHBI540Ao3nfME6u|Pc>A!Ky)wV_O2zmPae^- za-#dz5ZzDn{mY1!*AqRUl<0xQL=WmES|R-vEkqC2CvZqN(L<$wn0SXvw<&xo;XePB-Pa^ug9n8DKa=!sBa~DS{u>R zHJ&j-v|*6wS>m3xNVGAJ=s6`s&uu4qp5o^lL@&r9ns$WdYN8i55WPs`iyMiy$mo)B zqL)rffanV;Ygejt<%Dt9P^z~Vy zZxj)IQ)1(4_-&cL>kysjAo`w!-h<;T`^lKG-lOZ$_okeIP`mOTcP7?i2M&CQaAW>b*(I3S5v7YEpiqDq` zGW@xn=r3B#ujND+3W@$Et>0RS{@zIRk32y&+6zYiR8xOd==}dRPxNn*mhy@IBk_MT ziT)?!|HiQy!Cs>id(BbowYsn~s@E7S^?hLHH(+lyg}t?mb+fYz zq_u4u_I7G`d;R+#c40O44kg$-7GdusgCZI1tk^D9*vne6i#6^lq2&_XtrNRs3VU~9 zk3Q@@6)$bX-fI|p?{4gU+Of-KvG-MOKbh=5hpjuIeP9vxK?T?q!ip^HgXMRKVwLG? z>_a7bm~eO%c2x`Z$}a392C$Eu!9FSj`)I|F>AeSo||Cd;JF;1^XwF=VkD79riD3=2rz5JB$|kmvk{j0$ zbJ@h)L&S_~Vm`(E3&hNNVUbv{h*&6#m{mnAJVz`#Ld-5F7DMPK7FRs3x>!qMgl=Nmkj8TQh~<_Ev&1%OARXH@i`b?!#5QXtmM5`132Z(_Y>P%>TbhCz$R8rM zmFBvq$F>%68y#=6M695f*tT`Vw#yb&xBURILd|z56Bdc>I8JP*Hey8;#CBE_I}a1v zMa?Z!{jwfn#d&G{W184<87-e6wp%^15<^f!yLS=OeLuEm5wX%zVtZu>GT6IPkoi7p zxJ(U|jS|~ev3@S3&ai=sYho1^%6T>B4;Sppe7m=J9CuS zSuMoQmax7&V&^!-&Xw?a8qbqylVay*5WBz-1|`@;tXcIJ%HYBYV*0yrO#6yhOFpqn z#JOaI*rjd6F3S=ob^cpbba@Z4D@ur6se-l&VpkOryIO>6I*7Hm61!HoPQuq`3o_|w zAa+9@u^X$1-6Wx#7Kn8&61#bv*e$cfy7bX^DR!HhzkQ0>s(xbK(z-)Bca{;mD^pk^ zc6X-E|J~ih?h)>-Ce|y1`y_bZ1hM-Sd!Un;zK~)M))QMTvxkb&|Imp&EIeWeGsGV4 zB{tAP?6C%7j}H-hqK??0OrFdaW{Ewe2DIUb4XO5-X=2X`&-D=-E+O`Ox|G-p!i&X% zRxl#GB=eU=(1s&6+D=SgO0m}@__`VxDiEM^VjoQs`&h@JeIv|v68pA_*mqgPzPE|ZiSvV2@M9UVpL9Gg{A>~XB}0(#uNB0!0g3&V zC(IK2eV*7KQ^Xegi2W)2CH!5d^S{(U>>m~Vn@{Y&65^B+U!#Wjnzh8&Dj=RwMSN|G z_&Nshb#3CAUBuVxCcgd<@eO*2XEhVwaD@0qQ^Ys!Bc8oP+%-nrJxkm(O5B?zDCf^6 zZq^YG%n{cEN!*$w9$rcl*PE(%bey<7Ks+``Jdq(tP#cYSO2|3(+rDa^a zNPM{xyOk0zsUg0*#yx6@@7YScw1oIx654x#_&yRZ8z#Q5i2HRA-+zF3c^mNqW{4lC znu-kKD;(kn_Yyy3f_SCkhf4o&lX#W%R~8dLqKx>FEySzEJ!+14`e>Qg6cImGI8LU= zXA`eg;R!lEah7bH;^$Tq zKd+K_Qz!BBWtLXHxq|qG&BQMnCVufe@k^w4sqX*rRvBKd;wuJ;U#YIzMu}fFN&M;s z;_WrWuWcuOT_5r5W!$0IjRnMSl0jz$@teDd-vD}xq_u+gCW*hV#AF5W4||AzG(vo;jQA&Q#6OeSXDa->g!mW5 z#J|iXK2uNps}|y4OZb~Q;<_~B-}V##Zie`rgny_Z{-d}*jS`<qc2ab1q_1!?@I z`rm~=dWip-tyA-tP5f_t6iWld|22sJmq&s+6597C*0M-w!;n~ej>Nj-B-X1Wq5VQ) zgGmxu(iCl?nnonZ05)yej-h7nAmRTh73rK7wX#bul$R)9@47by9;T(w_A+b{p ziK1>2JI|0?|nHA~`{Q4+^W=(uSTwGufopTtS?Bu;K6acYsE z8eJWU)7AJH#U%8H%*2`fB+kwx(WvHh_e`9dP2#)?5>3)QKiy3tok5~mxUhu8MI$6G zULbLaKC;V960I{NuBax_CV{qA5?7UyxLN{NkCV7Ywe1ZguC;_d64!}yy-Yi_fEx^9 zk;IKdByJie(b+@d<|Y!iXkoY7B)Y`ul6Lww72K|ZRYG?!i94D}+^O#FDk9ONRrILn zo&pm0I>H2r-VPG?Rg$=0bq|b@=<6i$pysR9;Oco24+;HCBp#OTBW)xeZ6Glq?!YvO z$25Puo5T|>BnE3qJn88CKV^`3I*-IqzA#7PnJE&__K|q5hQx3aiRV@LLN$pOB{EV< z;w1^c+)Cn=auTBwe^r97ss8mI5@XFI-e@H8<}iu3`bmrrka&BE#Jico0*Q$U67Lt0 z_&}Hx|HFEn|BpIId@S;m#!p22bdbbn8mBdWF0(I2NqpH!VrGQI*CvT?N=VFBk@!|k zeAhzadtq*h#1FG1esW06OZ?|D62EBtRdovuBz_bBcj1p|5`X5B_^X)2-_0bJ{(t`U z*Up44J4gF;XAKKyO<}DvoQxuzwcByl>BPy*#aT~S-@)0S5+_UX4To?xTExk&!EsgK zxW)JA*l5P_j^g-6aQrS!zmcY*;Y+x>+KYZyCXO|)#4P*;_Ra1 zWzsKJ-LB0z%Z1&fv3mi|9%^jQ1=7x5bvS$X;*{m%?AwX6-waN93C;mEI0v@j93;^d z5;<68y+C#j&Bi&b1Lts=u2kI-)i_7i<5W-K94+BvT5*oez&WlQ=Xh~yhjC7n$4Qeo zCs*Q}GLBOZ&S~PEuJ^yr89g{>ihOn%PNS0N2-@8`O(LH^t&d3N%_3gdj&so{PD>Te zrCB(aW#hDJeuYf0RNYl->Ket`HNUnE=Q?S2m^e2K;@qUMvm56Y# zaPCxhcS)#c9_OBNoO>5>?kmE%zZa)ZW~(LmkVp@!_EC+GmEt_!i8H8GJ}J|uTXCLg zz&#La9)%4nC4>|-%$OV%{XrvTHITsIO8oiZ_DT%1>TkD zL@myHGSa2ue4v$nFoZMNg`-WR^O08ZaXrqI@JT7or{y@G$z-|&=kqcgJ=Hp2YC$ti zIA6*5n@pV9e4KCFalSJJHK_fgGnXw4>-_(q!XImJev-gXb2#%d`nd<^7Zv_$;Vh_u z1sVS~fb+YA|0u>;EW-Iy<6oNpErY++>{2VvKjQscit}GFNvcV%kwY?xZ^11(Q2# z+(q+c!z7Ev*;V?>$4Ks`Sc!c0$RxRECCSoil6#etOz*A2GK1v47RmieNbavhxnc+O zkvy=Qf>iB+nM<9EqG;M)JIRlIPnb zFX$uLtk{KBBrobFdGQ3vOH7iNO60NvlC5g`@&=Mus-{gfSGAJ7#v$3>L-IPsuAd}% zLmSB(r%86!ki1!=o)43^tC4Q~{wI0I5Xn0wc&Ehgsw3H>#NEXt?@mFM>Re=LsECTWXA30tqAB@>G`}n(InzV(E5*N_ zAvs$_^4kHO|L?O&&S~<4On=HFIj`U^t-?IXU)AXXLO;phWc<5oe{U!GhvJKh>sc=O zrwslaBKem%e@o}@36e{-B>z$Vp9PZt%Iv>kQuL8pqmI;?jxa}RtzJ?Y`u%Te?QBx( z7{Vl}bw@~LHj`Sfgw*lq+r zlnb+@yvq4HNcmeynWe%Msep`weWXIgg7Vf>npC)pRHT-auGLgj2DS`i^`znj!Z@jf z2u=m5WTvo0Dm6+fN3mR)Z6e;LYG$)KQh9}>HZLW$g+Xdd)#qmmgQT`n&DLe4wn30- z!4Ro!D@kovPHOvf9;w1CVUg61BJ8N-P7S1rT1oBPL24I~m#N!jYN~jS)UIl1`2?xm zrby{Fn%cu6wWn%IYe?-S-rn`3_Guzjrr5qR-A_jQ>(eY(UAfE;5ci-AQWcu7P($ez zW26r5Bz1@kD@8t3<6-%v4i~B%QY-%t)f~}9O1IfmwM369B6YMOsHtN{NYylxI<|z= zajHE&Lzp2|J3{J&UQ#EHk~&FaoyL=ANu8qc)E-jx(mPH6{g2e?3Y^hP>P&~!SrR_G ziBzME&S@ugZY`gqO9*9?$q*P^f0@4r&l^^>|@i4Ku(C?IuXGpU;-);Uh< zmRwS|mXPYIA$6N-ZkOOHjolKvW0=%kHmROMQg=6yx~GZMy~_0}ci$+f`$tGUut=&; zoCo_zt=3$(@zlc^q#i+7A~le%BlVbqkI#^LLPdk~q@J80^>hKLp(0YxNc`C>QqL8W z8ZIOCLZ%?m5gorI!c^{%)Rd8FQ}CiQ*| zsSg@SP1ch7uuY%jM>3ug;S(8t+DhuPW>TL!q`uJn%N9~IgQUKa@Yjo^W^Gd6O87hB zdkM{{S-t;B{nS8eeuUI7YWP=SK{~$=lUh{$pFO1X-H`fwlGH!Br2efThXQieXd!1U zn{-Y_B{^#^lC!Q!PUa9f>ua8sLC%JCg5n!ZlC$v~IoV_6xW>tGkCJ03=WQg%w?K|= z!8vB8&_+(6iJV{wIiV_YtR8Z7Y3D=@a_kCnVoT&CX35bvS59h>oE%}3j5Il$W|Om7 z5jlAh*j$7yM9ddyt73AtZXstInQmK7&UXFeY%lEKkh5b4IXg{}vvV&w%c{sJR#UsS zle4^!oZSY_xb-3_AYQymD~IHvuC&}%5WbPko)XCmpyxCZ*Iy}5m8amP%%-_ ztjMS+v8b$}qNK8-qM#xpqrxJiA|WHAvZAu0vW}IVtUSdjD=I50gx@n8JHPY$e*d4( ze>x9)uXnBWto2^@d)b2=SQap`V%je(fn`xCEQ@JVatM|s^j%7ndJ17#UIojFHdxAv zVOdFoRRge;vvzBa!LpVF75%WR?}TMT3_-g}`c$$O8yjKSR1M2nn_<~Z^0TQwn?C0Z z!g6jcELFv@oM$JF!?L9nmh*{fCVm0SFBFM`uy`)&f~BSg7OuyZODc#lShiA8+Xu@w z*5cA~SS}-ZT|6w82f%WL4?)5!iS110s?D%mT~DG$Sn5f94TD@;2FrDYur!eKdivf# zc}F%Zjg_$6$OLX;%$o;c+1bqgzlDW-CM~y-pot0Gehij7L5#rCd>EFy4#IMGH!M8G zT3V^Qhh_ItcOOaG+F{wnAP>;Do$`Z6VA(wk%R{_A90Ln?)0Ric-8lryW0W6ngQbfJ zJh2^?y(eMm4r2d5#Tq`cMUzTFJVcjP+}L!5-=dzSyu4a<-1u#D8O+kPsAh0m?! z7mXN$xeA#t%SD=!Td`If>Vl7>KEv z5G}M7$s;k2mG?Z%iuP)Vj!K9!|NWQfB%wkBS0_Yw6GW9kG!mq>LCo-hm>CW+ON2O^ zPIHNm1{6G_fG0rBi`i070+ zJhuVjdC3sB*dbPv_`)EF7oCK7F%!FlEmE5gaa$|I%NV0>C&bH-LA%7%D5amQhZcaA~4 zs|R9>9b#)U#Cxf4V$+uTQe2_YR2Q2R9-+vGv>Vnuor-zxy zBNY%I)gX3~pz{bsE~DaOygq&s;uAgu<-M&CpJZa)Bz=lCe>wmnx8CA2wCNdv`0Oym zeJ3FH(zcJj`^mL`6yo!|?gZK)wJjm;--4I{vhxqz2h;Pu5 z&#(AaCd5MrA->%Q@g0&5G1z;we}5;$4>}CJfyBp9@*RZa z9|I{+gEZwhq@X%T(`ggj49R2SjcEW8b3m>7ZNB)DysTstATNvxWQBak#Yrd2{pCt*5$GU^~@mO#p?fHXUZV9+^3 zkg_`<<*+Pg3{o!r@>(I~H$p0)?OcU825BC-3U@-9&)@%&ib^3Z$cI!+<-%-Y7}6qQ zaX+LI8Z9Y@w6q@5vNlMiwUCyRXhkxlGeqJzq%sCsc^J|v60fG;ngB>=5?s2aiWo@i z=(C>O8^}``1ZgA7H^oCb%L~s@NSiw$om~a#oFPc(lB8+?(s_N5wvf0woEU|~=UTdu zx*FD=OSNhhE$z2acUe57I_fSjfpi4}UNHt~dj+Jc$bB`ho(4$ujCT!f zuRR3mI^KI4cyj{?6766?Bb7G}K)UH5q??JI?T~Jv&8;1fxI{}$+acXfqB{m5HJc#a zRSfCwE=Vm*_?|LI_vS;ok9sc6(*3mERRf7TW{JzQwA%;LLqU)_N+3O40qGI`{-^XP ziT1=mdaM-E;|C!n^M{|F!kARXz1^l>>c2I-SQNT1e0I$90sGbZraVMu(orO&G%9b<5QizyIZP zjWF|{nDx(tkbY@}bduTrsu3fQe(QkrJBdeYApJq#KkFdO=Up!Rj{vtA9JJo`A!!PSIeUnh$GGHLTMzVVxcXYp|Udh1E0y zYiKd7VI{DJSHK!k4{Kx%tWnLdnyHH(gLNkTV=7^dt%Wu2IIQs?j=`E}f;A}_)@1sn z9D&tBnM<)%;=Pr=cJBYIav`iT3!Lq+Dl~Le!RjXXa@nd8Y4Nb82f>=bYo-}iZojRw z%V3?832SyKtU39x<`Q`%&pQrl{s626eX!2$ft6cvYvD0i=d-+sSTF?ZLfS22g%;Pr zTC&*#>k=xKvKBldTbF0Ux`K)`>R~No`ARyk-VSSd1FUPBU|nm6wL*k-odWB6+HB~C zwUTxliLcn3hPxhuwFe1YduM>VW8_WVQrv}Z@sKL+F@-x2`f*w)|-#PdaDnt zw>7}Z<=A@10Iba&u-;ux9EY`q<*gO4-lM>JZz*vQ*88epZ7U{5*#BIct-A(ceSjIZ z^U71Lb$1)A57oljLEXcJuyR?pKFVun0Kvd}Nb=ZrSRZeOwTss$YGB=)4eOIJuy(U{ zPnn71us+=h>ocve_B6u!EU)``?Irq#V1162+279of1bh%CRh)6F%0WK5Uelp{$;@W ziVv)OmaVT6uO-9!dLgWXC9uB1pl`Op`c@OHhe-T(KdkSx!}@L~tV2xdJyzmO;Z&v}2W1J*BkVEyt4tY5MG zcsH#7qA}lOTfaF8>oCjzO@eP3>^lZOLEG;s|G;2B(s!gD)}IDo{ROa|^nvx)a9Dq9 zfc1C!jWUrx7~{`oSpTYnb<9%^>nR2pZ-;ea05Ra9uqBkhmRJE>QafzP-LUa_wOIh0=tG=@%}TwEc6P#11DiYuo1(zx zB8j^YHkHuoVN2TyTY5We8N;w;G01ENpTqkc+T~KtD~BzAJ8T90u+8JY|FF$tM)R{_ zE2@BP0Ue8(yE;Vu7ssEv=PZFdZ84^_d|Q4ib0HLyKW4cns~uyr1T?J;sZ&U@~b zZTy8L8(%oto(h2N>3GH}Aa@fX5JWjHSBd`mHVK-L6?lTCxp8~soKI{Q) zuurLlJ*W)!X*IAtklal_mG)`mO7Dj~V+{7Jov_cLeKzfK zMqtm|40}HB=Xyv!?;z~+Mc9kFVK1(MeUTmZ5)JmHfPGmj?8_;yphFqumDH~qguR^l zHHTqe+W`AICcb_M_R0#_`C8U~RwnG5DW97SdsQdw=P~K?$#X#f>=$;xUQ-48#YbS@ z+7G*DTPf_9(zvc1_RC3lC7rfYzPgyoTG;D{VZXKy_68=v#mC;53Hy!5VZXTq_FEY2 zwldgn4}$%UR@m=60{dNN*zab5Rv*~!IR^WEEWclaeb-^w+s9zv-2{6_4eT7W_Rey6 z?2nP4i^fkJg#F2O*q)a4Eys8&`+lW3hV>4f0;H1nf+_@8Klpf zjj$goCWc^toBDU?Gn7g6!2Vu7F#`MhO|XB!vJZ~Iez+U<4{7%ifB)0|k8py4j+}t~ z<5t)|q2kkcVi5MDZLohva(>Hc|D0vVVqpKm4m;nD+P^#r`*9zFe*YrA9)SIuQP_ux ze>2Fp9k72_5BmvL=6m}85Cr>=^#75zBb~7SGz9z49{%`+jwcVp{woQ8r@?3m?0@7F zW3c~8qQ8#9KE|4!>W6)N3=RMep79)p0D`g)ufCN1%y9Tu!V%C2M_?ZuQ-MFtQdmhj5avRNV2jOj#Uh{nl&h|gJVq%9B0yJZ5bRDwQ#H>>G~=-HfV5E z(q`jMI5yGeEMhZpjt_AZj&sN0IFEi?$bY`)5FFKq;keKY$3-F>HGObg5&*|mlGZXq zp6eW!g~L(D>lKA?TuIxjNPcxA`>q_0`c62mrTw+da9qcP8cK;#IId@)8@k}wL49Kb z95)ujaTD!sIswPc)bUv7xP|cC+6u>Qm2fmQ!f`tb?x4e+OoEG%zf4vZn!B#ll3YJ5_MJdl-)Q%y7Kl2ghL( z93S%UKRZ6^f#V33pU~*jd^nCW^MBUC@%acGUyQ=>70Ld^jK5(L!^hzG_6Qs&c>SJ1 zf1u9~gK+%V1qZ(Yar{L5d;*SNh?B!`{6?SOsQaB59fRW!^8Rrgjz5XNn9P`mH{->` z5F8T?kkJTPXo760g>3AA?87qO?U4N{A^Vp?4k(8lSOR%UJaGc@)E>w|-H@jT5u=bz zX2>D*39W}5MuZ=N9MK9nl3Y>!kj*TM9)LVE267DfJhA){XNNqC1@R@26KWtQ)Ga;`ihkOPD zbI&KQWPnw)U40ZX_k8l1EL%GWx#A?`_1Ta&G(q0TWH$Ce-o)!!wU9TDLO!RAI0E_H zHpo@9Ij;utmTC{=^V=a;li&i9UPOY6cwf^1`C``k5;H-ktqfXAvTZ@c801TjLB4DN za$N`H%UdB|Q3v_ToshRTL%ymS^3~;R+A7HPOzxTz$k+0E9l0Br#Puw{A(J4_4nF^K zV<+Sr4??~fkaq?VRNQKZ%*Rr0Vj{P9LB69O@}0wwn~A%QLvHbb+-in=PXOe5dF3k? zx$Q9I`-dR!Isy5CBak1Y&2H)+(ja$ihWzj$$dA&tGavGv63CBLFv-WOAa@;wyqCsL zCPVJ-f&A168Xd1jOMGm(Chy-*GLKnLUj>R+NQ_lokXCdjYV zLVmpz@*v6I=!E>{0OUgq_;wBCcY`1gl|g=Q2=WIa?Z4{2gt-qwR@a85rCCy!oEetF>xjfXRg_TkxZMwG!Bc@j=D z?V=muI0`G22QaYPJUzIwARCE8-UYJ zGPw*+C!JkpINf$QRoZAQOWO`-dK;V>w9o8-GpifU+2qRB;LNFlGne|jb~p>@J1-l~ z`7v-79fY%(_MU}xa4w=#Nj#iOy5L+!EYFAY3>uxm^0Fp4S000N6>G7&6V7sytT_%R z-)=f97+_rwoEr+^tPF>9V=|oFfI9gm#JQPeXEQigJm#I3 z8TB|X8iDg-*65N7IJefoS=$EZHU_$s*UP%$yqx7%P`;9hZD+8nMwvAO)Nh9KnnpOU zJppG!37pr{W(R{eX2W@7Eu1%Phx6tkIBy~Mtt`8(8P297aNYqp?<8k)JDhiydEn#< z=WOkR^WI`O?;~j&9q*^%1FdjANaNiaoDX%t`EWd(k1)YU55c)dg!8eTa6Uc==M#l+ z?j>1w44hBV?wNczd&sx16wY39_4UKKpIrU)e}TFKZEz0I|D~gFzT&Bb^HnNdW8t6) z&NmLj`Bnp*Z=2zKhmJ!`>V3fZ0fTbK>ih@GkC6Bi2K}@X&d<8x{G8>-M&SJNAe>)~ z!TGODIKLi(bGRAKZ^`}LF*v_x3;n==BRz2bycy1uF>rEma(aFz!5_?yn@s0e4V=%4(9A z({9ZOl(iL5xbP_J8LaXUlug-C&SIdm%b}cG3#IA=lr6lTKL+Ij`qab_)L+~Q<&tJ7 zTRrViYWtvE8V=<$7Sx@Da>WrSSF#pY@&0NC@h=mtQgAUB<^A|d+ku3Y=zQI{nNC4hUGo|Q1&H5>CJ@FR|Vy{dMNvQ zp!5epd7&E0ft^rZr0+|VUuH6|(C1YR%4@V46rsF9o;PdQ|8LRo5Xs(Q;k$MyLlsco z>xA+FuZP>9e8~Hc`k?%S!9S+WC#6t6Jq+bDA1MDUhjJ_i$`^%DzNG#*um7UY*TYbT z$@Opge%lY_yQ5G}oP_d24U`}0`xAYCZiMp7DEt4{5-7iGP)3`e{K@NIypD}R8Q%_N z;xJr-9WFyFT*d*oe2d}o8-XhzAFjYAxH$4%LDg_g2VB7=aG5&c3gtDd1FrBPxFQv} zqH5tX^L_?>XC8zrmio9lxMqs)Ebr1DCxCF2@PDoSWfN z`r+bhHkV3*v~0N2kHM8mqS-8)!}}Z&uH16C^7`N^pnh%-T!rMDPcF{&E)H(j!fv=0 zSHQI-2(G2oa4kComuES%TG0vD8OPyT83WgkYwavoe< zSJSq>6s~K@dmaD%kL!9G@36zwxE-#Wc)gj|Tgu_OjRBjw;JPCSt~>kTx~mGVy9eQF zt$^#^Y`E?lh3o!CxON?ftDV=~hvDj|gzJ$2xE>vWYY)pFuD!H>lF2?*1=lky ze>NGeeM4|P*WiKc`8K#-sE6yoF}Mb3^omHFgzHrkT(2>q*BNk-3B6&4>rLw3Vq%Ai z;d+~-?~wf6cDRNZ{C(Pgpulyw8Lkg0e?*QW^!b>!pVYy16mWe;{XgmRc?VqluE_Nz zH;JyV2H`qB3fI>p{-y!0;a0f*O@ePvz;!}|>w6OXP!89R^>B@J!}Swwf2oA)BwOb< zCipw=M|47a}-?tmV+r^LYRnVJoE z5REu*yMu?|4k?B^%mjD%F}Nc)!yUB~?r6Y0qXzDobc!WeTqE4^cDNI|;7&XOcQWl# zs7oD#TO=PhE^ZEBx4jN-$04|#F>ov7aq(W|z19hL+DW)GO5ky4GOO7voWlUw%r3Vc z?!11u3j*Mt+X45y5xD1BD22=|h1xR86kSry!Myk1cb_jV?Bbv~PJ1nz6v;J$7U?(1ve=6>GYco6QJs^Pww zoVV1$eVYPz6S?kag1edAcQI&7Hr%a!aNo;B+dMS5{{-CaF>pUv1NZKeaCgx05y~9J z?mcvPyb|swDDOQ4cXt=uPnW~}%oyDJNZ6;r{T#3Rcf#FohWiC_92kXrfR%WOHZPO! zAd`KSoUir6JxH53+TebR6+1**&)WlVzncyB5U=l-!Oe|^`$IZ>)DHKNc(^|%(WgFe zA1#Obv*U1oUJv&dwEOY|+{cf={SC>6nbg0j|Cag_rEq_L3~p}8-9It0pPS)6NuFPa z;pVGb_aBu13V?eo2yX5*JZ?_2?g=|obVKDxRgK}qL8!h#Q2k6${VSjb7DAnp4RvY< z)SzLgJn5<&tg5LMYRE~bVYN`h`=Lf0g&HM7H8((=K|gM})!1aHag|Wx$(v9QHOU8R zay8UcmRklrP$e2#4?*Q8`4^)kwJjB^F~uWW|8{Up?@>02KI)pLy<>b2ca8|Zw457ZqU zP;aEeO(RfuHbA|V3Eg%C>g{HzcML#nu7!FRZCV)M9+uq~1huUb>MjzuGx&pDP#-!7 z^NhN$DT8y|!^!TX6$;s`V}K;wI3jT;(GC?o2jd4x{h3_&wwLNl6)QeqIA zPYh8_v=NkjMWTYJBYKDtXnx@YiToM~%KjSB4K0A>0Ug94Xn{clxdZ7J*iX=IN-|MG zRKcT7Y2pnPQw|eUPTfwNfEJWbkZf8EQArF#o6Z2!D~L8?h@f3?Il*8i1~Spt#Ig`3 z8`4RfgceGk&}yQKAV(NE!m5Zv#IOe%zyHy~nMC+eVia10nV?eyi6dHxBhdJkT#GCu zYKeo;q5=qoU@}omGKyqo+L-BQt|J&cnl{lj1np-~H=~STf-?r8&5S2D6a4;Pi=kmm z6)^xU)=bbaww~xGjzf#fBpQhx;v}?LlxI~Fl;cSh&-?g3XbI#=U_uEjPZ)!im`s!r ztX$$DXi4NwDkPXxQU^h9PjU>j}OyM~~Rn`G`o#0h9>Ji%J3-O#iWf;L(^w6t2HiRgotZYOxn2qG9bqk|YC z#@PRvB2i7SAj?EF5H!v@0d00BL3wsRv^mAZ5op;U=#yPZv=WD*<X!Gl#6=f2v z^#UeSoKKvDwy+V}B927-ZB93n=boe@ru;EW1_iJZ|v3=$`xl`&|UMo?EqT^V&{)Rm1w zTPYIdL?h8dkZTo_S;ewdEL%mp)%^ZnTg@z2w?Qj66NN-8v^4=lAG9+?q6^wu23lK5 z3=qemRU{K7#4%{=7<^qf!GzY+eti=$3T*@VxO!?EstNLMV89J5ue1|vjmk!%pZ(95 z#oESUXqy;(6Ad?!=&XFA587shpySyLe)dUd=P=N@*#vE>c&%d1&SRkSItl8xR1rs^ zonJ@vL#q~v4rmt?6NAt$tRa~6MZ8`_jv7xBw2OU+c7l$V#1M_d5VWmKVk`Bv)YnqK zjn{3oxpX^0=gSzR&Q2VMc6kXw-4!Ih5(JaqPW|?NXjjqZsxD|(XA>jr^KNMM8gYpC z*D%<%3egGeIvQTb8Z|I*1GBxJ<=3}CyCHxmCm3Ky1H0NO3|za^WfA-ahXXt%}_rR@J(X>c1!ZlhBZjhY&XF=)3J5`EC_070TV z+K6FjchdGw)~1=H%{z%9Xm`=?u4ZU=hZ7aVAhZ@H)zS&AmHw^u#1UxsCRo$?!5<<|2b1FgRqJRb4iYD!J?vqY4{s*g2?l;7o*?lfbb6#8+M@vk z8T!qx~EC_G>M)mAsPt! z^^m-W$@P%4hw`%(L=(|PFyVd4L@`00ef`jSliB~hRlGS4t&fVnBha1$kx$eR-NZ>~ z`$d9e`x$6I1MD9pSpK|;uoFzOpEmv5i4)LXC@0#W9bmu%mh>$J+Zz2*WR1mY5T=YaF3oK`6p96 zZNG>1xsw6B>FV|ju$Te%{2gF2=UIX`^Tq$0zjtk-&jCR-a+^BakYF^x2!D9%k(8nO zo`%qyUA%t$mz;%@KMb=6y`L6yvd?@v&ZJ|&|8)$rsBEQ4T)$=g!gGjox2!Kd?KKGW zRwVnJ*XLOTOiT#jxZZHsu+HS?f3a6a+r$CGH%1fXOLckc#9PMghOa5_(B(pe8aoUJ zD7Wi!ny|?DjA13^Ze6xd95D79EtGlEAz#+SQ^qHa29salJ-VDa@v`w{!@o^_p1@st z!G?)GFVJOa;&tOS#mzPewX1v#Mg7UB~yC)to?lW2`|D?-5PwX-7@YZhT zCO$Im_R7XYUgJTdN_p*ReXsFOqel5$UCv?xPkIxaUaQM#?2>1Uo-7u0=>_hI zgRBuV3~torVj+-Sa6RQcr}ZyTPXf~vU5;TFysgVIx|~Wvk1>#XO_wW}&`x6#L0(W_vFp_ft2T>ZE@EKzU z1H)HD$Ox)xgl|Jzf9{^4nalh#LB=*J)-rn%U{iPRd;G}h<;TMzNtjX?oO!OEZ zGyFt(p{`HCQ^r>ePf-3sm+LryYdDGd&H8#$&)(}YrkniY|4#4|HK=?{rc2_{C37f(toE?DEz)zF#Lypu@x71mY(jkSw-#x6#MsmoPbtiqsEy zAAp3Hbo<#81AJg&O@4`!Q$Y5_5CiZ5OWdOChkFp;v|@KxnAIXB;W8p z5J`u0Igj1B$D2^{*V9!P^2Ub-G-{gm)VzC|{$? zvpKwayyG|JK3#TB++%#s=;0HUa!@Z=$pr2+W>cPA2CiZs-t1ilQk!)Bm8|gv-tn4x zmo8_sPrD4KD7WcyHT}069h5sx>z`%|u+LMU(&aev4SM-g59o3{$G|?1UNAW)B(l#B zd1uko$w8CKKH6<8p!~D$Fni)YwuqhbZ@RpY>(GndCs>*s@Cj`4*Nw8t&$?FE$1vc4 zS8qK>mlG$Rr=AtIUZKl{6HgjF4|r>66ZL{LW^|QtG3CX&JdXqqdmnMzS-R}z!nV&i z%j9RjR+lIHm`!S*d}?O1$zS$1vAtE--${9+cMRB{(B}|0PeSJh@QjGJ!+hG2!@B*E_jPJm;;UW3t7vDR&v?nEd3`y57yl z^g(Yz^5jBzA^D&4Cg7ZWDvBmN&#;L(h@6v~9Z_#GPEyXvF)*K-pNDma$*n*Vw*s$v z*AeH3rvr3zv%>^k4Z2*)G1BUNu3eK0>Es|QqWpobk0yVsF~{WRF3{y751;$p-pz}9 za_M)lkM)Ve{ph3t7qZ=6Lic03JW0qFa!>BI+!MQK&!@&cIY!br2A=UwqN?`Dnn zdB>0%c$%+$l24s%0Z$D3{IEBGx=A;1&|%ORMS1cuO6H(E=9(A%t z5)*vUm`M2}-Cvq`nkzAzSpBCid-o;}d-p2ZQeE~w=6V-t7kOp=jWRyRgWjoBo7|k7 zsc+}F(rS}6%x1tYFQN9dPLRn_yU&||wqKXiS%JOYL94y3%M#~}E+d;f?N(i$N&6SP zEs&n4%Vu`L8@gOY*)su&0bcYjOz9Wv1{+y}_q{EW-mJ@UY~nY)38qg@9I33)yWT;U zKDhx-=b$|7o!Qd=-Ym5-LCzEDlQU}){a^Jam_GTKXH)Ld6L<}nuI~?@=BVaVkp4~Y z)5AV5_<70=8@L0_;E8A|S1$d`GkJb6lwV}YKC|8X!!Xg_o|#GTym6*sgV6LJ`~N=B zH2r_uPuwRoVe2HnuO%reLUjt>pMq{bO%LEW&A;QTAAJa4!mszMAN}{mCi^0F;&IMJ z4*pW-TAYUqa0w4aQ9izw^o&$XMr2faMp{e4FOKj?H6ke@J;S@)`llP+-n%3}e@jb6 zgBI;cOPDVB`z1PsNI?ymE+l#H)X4NSONbg`NwxU-8ybw`KaURvE-H?*6r@@rqsGSS z^B08OdDWS9^|O)_@BZeSnKM%&3PPhYbEgIQ`5G2a-H@XB`PW=N#cZB(MQzl&4FQ@O zZqBjHDhMhTW*AMOAuEy%DMIyPAtpP)v)Z`S96jZ!;<3`gtUNK>8kOto?@lwjiVenw z?7~?o@r85OFG$NVnNkX~w;PSwa!9J^FC3j=v#oq^MO1ibSV2mjf1qHTspMFro{fxg zYf($q6knQmZ+&=}U#`C}6-joA2twpU14m@xj>O;qBCsVf zc*<>}KaUBIb8_-F=_WSmWw;Xc{8od_$_D!%&1(LCo0YAaEBtrEs(${{jsAZA-WE+! zLu^7sQVJV2a~-F@>ZSW?yME&UTu_R6pTpKtM!fNpAZJ(=<~^UUHs)fMA^A&Jm+}qGFY_ zkkTc^7v(K=yGv5d27}<2o8c|xO5yXaKK zBB8eQSK-I;5JBdTXNy*DO0wj-GQ%8FuH7Pv{hT{EP`sJ*$K(*2C3v4X z?|+H@vXCQCp${*c5Td4MB&4aV1tFwS;=t40BcuFNEt6)cY!;)giJ&SnswGRF8RGF( z(~@EZm5yqfh4+H~lt=n{pWz730kZ|~_)NFBy-jM&Uh+nGv=F)}e5ROc3QLPICmMVL z0s{TbW?9*+IE`xB23NQLlp;@b#HnAF2=S#t{Mawsrvxta_kTGm#2pnCpO9?WbVJ0s zix(_SjbHxkBc5r6i<{PExozs)Lf7i}mCmbnalE~J(@i%O-ptSV0wwI4@aPP~y+)r6 z%Oi7R&8F!AKE{2%zHwo5j58mOPZ)o6aiL#8e0+qQR$1j` zuLx`66COV2nrlvdof#e(7-GuI(*gpsrcV=!!e*PKh@4rFm9{rStI zynF6JW12oKTljBb7GW7X^~@I2{lPIUyLy5nS}wjXC?+&2DI_6;k9Cr-ccM-5GyKwG z7K3dL;Vwr;#`zslJ1cT>LPFiyj?0>YgNmjEeH^zW>(Rx6XZ+Cc@OVX0LD7uPm={~F z6oW-ccp_6ux^T{1_nO2R(NW6MEd^FNK(Z9nZ%(WgJ{q^?39EL+Ca$V3>iuD9@K>=3 zzDVGDKWIz>f5n;Kx|U--PgC*UIVwUQF)g3|krvJI;Flz{eBc|b+UkV|g`DZTdM->) zDVpVcZ+vh4zoN&-8cQ0-$D;pLKfd>nlrYaJZM**o!`7Cjkl^&h-yC^SL64R$4=r9$ zuyN_!ja&EZ*}8G=(v1ZRoKf=@Jrpn=+j2A{Sn2)tg5bc$sBli2?;B+{Su(6xh$=K< zC+=u@WSU9#=nIi|R3}9E`Rk+j^u_yhr#gjPJ^%?Epiz+=(%uR4^fM6=?kBjt^C=$< zug&CupPU3v&jB2z9P;5D@P^Uc75Q^>##4imQsxzib7K4#8ja*Kg|;+}1qW{u+U8`g z@by`tjo&J~n!S0=C9yZ1S8?5@65G)9}xt>s%4~?`<2vw{`u#3C2rald+|jr`3p? zT?QXHKRf%(Y+HP$CDR(G&Q|AWN@i4o@?@sDFxzo=u#X^^^8>_WG02Z2+!S|ZP{E4v zLlu$XB^jw1H(mAR^rSg4)53p=2)}TB!0Z5FiK8MuFu>K@@q2LAoP@{O@!|U5v_e5T zvN0FM*o-ZI&pRz~*O|1Iw|~>jYPkR33pyA5gb>b=-U&m8z{ZdAGwS<=${tzsbD#8U2#;HB~y|MLfpA($-L<+a_=y0EQwm&y=~5H zyKkOv_6A{ljx*hzo<9DY^@7H@JB8?iGI>F%&8ZjeSfQDES7;%NUo$MbZN~$Dh7h4d z7!lt4z@HK2SEfbiqtE-t2r}3XRj3AhS>L}$PFl$6krR>-?w@dao_x6}u?&UD}*dR#mOxsz0 zrNenyYnJmDB7|47Hm$3UyYjrvcO^7bRAi-Ry4|T9RUr~bmC+!Wg2Ka-ML9+|_0TbX zeAlnPAk$v8%(k@u1)(_7S&$kTH~vCOLjN6sa{~l(%IYO0)pO_GSWzhFx|S_Y%X7>v zHH35Q=^uk27z}~u)Jth%)wy|N(|zL3^mm)16_a0p5E}o<_zO!i7Va3kG_rT>(x{70 z7^Ww;TyU1TY+9cCeACA4+={i+H>}C*edjFm19jE_g#2gIvw^$Fi@EK&3fJ)&_HKLr z*KYEEY&z+ZAm};DN zrmJG^Q?A7eTyun@g;_3bauej2tAr>E^i5Eb6hA+I!~C?ozc)czTChdrCdd>XnVOon zyEN1k5|+=M=j0|RHM%EqhC3sqXkFIA+PrPqIfW)}f&9nk{IBiL!K9{#BD#fHOUhhj zCBhlbf~9i7_ybm_BK6Mtr@61dKZ7T){l+;hkJzK7gp^c$3(ihRW+QX^qi+*9MknV| zF8w3+=vf}&<87t$GnKTi@!vxQpZj)f8oxI*V&(a+*Q-jx&BC483!PaDF1SowaaLTl zb>%rTs?QYC8mf0$ijudu($bVIDMgmH3um~~mS%SagjUpjT>16YJrl z=g+yxms_B;1Wr)tJYiLg?>B`BOU7TGI(^}zLf*1>-dQ%jeqHSC`BxY9g@=s4m%T8n z$n5W{&5K%-?Gu-ooh^&PdCSySURm%8-=~}YG5+hzdm;=Y`7>k2Zw;AVlCW)CUTbS! zhB-&LBxdILmwoRqPhYw&R*H|EpVHD56%!ORe&1RAq-8nIImfo+etQfNOT-bgdhfT# zN6wf!dHkM(1k7zI-4q}1UGvoc-@X$Ll`dZ8%1_C9e|+CHU&oxfsr05(F<)OZzV96kndo4JI07nTZa z#M%0>@?vbm<(v|(!Sx&klSj+6|GA*3eA4x2o!eAapOb0E2hIclk+b zshKl#hDV4S#cGaOOVgek)K{X$#wwfyYjxi8r! z8m_X9(+_eRgr*;%EI_%cd<*1)tPSLUUGjI{&+>J~C1;+Wm^w1gdKd z(M!%M^RFrH54^ACia+Macq$@w}7ceW1cxuK6=M+{4F;v+Dmm`RLOs zm#NbypQzKPo#!2`58QBxwtmYEH@kMX9UPvqzx~=j;6mow8!Fy2Q zfY9Ggcsn-4d&Eg$H6x?=KaM6{{r~I|spRS)w5%IVo$2X&Yjm+NuXOynym>QXW3x70 zx2t;mJ0)d~wtRfRXuV+H4ZYJodh(6mfyb3{+r^u^ge)7Hwrq`V}#fsLI1-2~BEiO&Ze6?(Gd{T;7 z5f&D^D&U4Q_z`v{8!f3RJHBkR5Mu9_jnX#{h|^)`i{ZzNnWw*759XMU!c0C81(?r6 z!?`#gd>iT8GVrMs9?CZG9%#c(AML}`h?Y4oDKmn+b4XeQ*MgMOC7%D382&tUa;~B2 zR1M*8+%)!wq3f%QFCJfc$tCVmLszM|g`dXp+NnXx{G^3}ffr4mvT(}Oi|e1im_`qr z&(DqHTc-rM<|i!*oKiD=O0llIn*#ryUFL|5FpNd!^AuTB}Re#Um-RpCw>&uzLuzK72)`1t(r_ph(J=I*htj1_rzdd|CV#iBw%G^C`Z{Ud(yMRTk(99b7AD;B53Olj8m zeU|qzjF{MB{Kc4n>>VeH9E40b359U=o+xsEGk_pR%;HaFakk6->azm$#e`}dBcV_Bmd1vPp<^~p&&t6q1tkQp3WKfv%Nat+ddA^A? zTMc0a6?4|l*)*23fm`xC?qxTgnQ_s1Q)8+xjH z03M5YM2Zwzp4zXbcqWfMNqo1Knii5|@V@Ni@caACk@v+>ns<=V$9cunDGLJv-%T*5 z#mtoA6DxK^Zdp{c%n~m|Zk?CsaL+AN$`dv?8uz!7Gw-qchE6xeJ6Fa_28_6)d~$`c2F7R;-g|)6>&) zi1a?e9%0Hgr{+uv{JdD$+p?f*nqm?D5JJbF82?DHdQl*Rp1RKP;;G=G1=DNKkBp7W zGjtSt7A->Wo946y)+m3D_9uDTU&Nf&V8egT_oi#oBAtHz`nD>A9mYw*`+9#;W_IZr zAzW@!EnG`e)70YaWQCix? zQP9@Y!84vO#feoyM>kYNkh4BPOxuKWzp~bKV7JOv&zY5#aq_=94o=1s(*o0+zo{hg6Y5jHJ<)o(Ui>!RDXlI{J=PcjKu;2 z6&Tl`G8kNk3qykmR5gLcK$Q=;!k(_DWNNN2ALISbRzF!o$2~<-(1&06$X-zeP3KkK zF|81<|GgL<&d9`_IxEbbCpbKOdY6)^zS_$5>z$2N>=~C>nD80u{);hI)R3yLXFLV+ z0dMhoCzG-=!^Yz6c7dj$tdfFopJ)OP6EFo9Yw5sRvzVcLdYYf9ks~`e9e}#lklYQV z)R=+30cB-%UYx#ejkQ4>+6`+7<;{2W!h(v)>JB1WA*v2+9CIZDG|g0vwXD7z@ZFF$J=Wh;&y_bTm#-*~ z@r{nQsYml zw8JqX!qEX7ckOZ!ra)}AT`s~ra)FRJaD0a$EVZaOGe1wkNYB8?e0t{(^F53+x4Zo` z2fBmVirJcBAH)9XegDn<*qD=0RlvnHYZzuRuVt9Y z@E+KeUC*$Tc>}{F;G&>S!1>fI%v*tThT9qD0IQFkz)tvXU?X-faB6%%a034zL;uz_ z7Ec)2ShlciW!SlW8k5DnOcu+fmdm!6py)}qd$(W1$s*`n2=-J;W?+hVE3QH$diCoL{m+_Jc1 zanIs`#UqP9mNJ%dmI{{YmU@(_Sf8@KW_`o@p7jIkN7hfQpIN`KerNr` z#>WO+0>vi6CdOvK7Qhz77Qz<{9 delta 129900 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 L;9Sg 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 t!(Jwal5 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 TmO*Cr?6_@K$bH6;Ge7=+ymhR6 delta 65460 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 Date: Sat, 30 Jun 2012 22:01:48 +0200 Subject: [PATCH 03/18] Import qrencode-3.3.0 source to be used for QR encoding in KDL. --- .../kernel/debugger/qrencode/bitstream.c | 238 +++ .../kernel/debugger/qrencode/bitstream.h | 38 + src/add-ons/kernel/debugger/qrencode/config.h | 5 + src/add-ons/kernel/debugger/qrencode/mask.c | 330 ++++ src/add-ons/kernel/debugger/qrencode/mask.h | 37 + src/add-ons/kernel/debugger/qrencode/mmask.c | 177 ++ src/add-ons/kernel/debugger/qrencode/mmask.h | 34 + .../kernel/debugger/qrencode/mqrspec.c | 280 +++ .../kernel/debugger/qrencode/mqrspec.h | 157 ++ .../kernel/debugger/qrencode/qrencode.c | 929 +++++++++ .../kernel/debugger/qrencode/qrencode.h | 565 ++++++ .../kernel/debugger/qrencode/qrencode_inner.h | 88 + .../kernel/debugger/qrencode/qrinput.c | 1724 +++++++++++++++++ .../kernel/debugger/qrencode/qrinput.h | 123 ++ src/add-ons/kernel/debugger/qrencode/qrspec.c | 562 ++++++ src/add-ons/kernel/debugger/qrencode/qrspec.h | 181 ++ src/add-ons/kernel/debugger/qrencode/rscode.c | 327 ++++ src/add-ons/kernel/debugger/qrencode/rscode.h | 41 + src/add-ons/kernel/debugger/qrencode/split.c | 311 +++ src/add-ons/kernel/debugger/qrencode/split.h | 47 + 20 files changed, 6194 insertions(+) create mode 100644 src/add-ons/kernel/debugger/qrencode/bitstream.c create mode 100644 src/add-ons/kernel/debugger/qrencode/bitstream.h create mode 100644 src/add-ons/kernel/debugger/qrencode/config.h create mode 100644 src/add-ons/kernel/debugger/qrencode/mask.c create mode 100644 src/add-ons/kernel/debugger/qrencode/mask.h create mode 100644 src/add-ons/kernel/debugger/qrencode/mmask.c create mode 100644 src/add-ons/kernel/debugger/qrencode/mmask.h create mode 100644 src/add-ons/kernel/debugger/qrencode/mqrspec.c create mode 100644 src/add-ons/kernel/debugger/qrencode/mqrspec.h create mode 100644 src/add-ons/kernel/debugger/qrencode/qrencode.c create mode 100644 src/add-ons/kernel/debugger/qrencode/qrencode.h create mode 100644 src/add-ons/kernel/debugger/qrencode/qrencode_inner.h create mode 100644 src/add-ons/kernel/debugger/qrencode/qrinput.c create mode 100644 src/add-ons/kernel/debugger/qrencode/qrinput.h create mode 100644 src/add-ons/kernel/debugger/qrencode/qrspec.c create mode 100644 src/add-ons/kernel/debugger/qrencode/qrspec.h create mode 100644 src/add-ons/kernel/debugger/qrencode/rscode.c create mode 100644 src/add-ons/kernel/debugger/qrencode/rscode.h create mode 100644 src/add-ons/kernel/debugger/qrencode/split.c create mode 100644 src/add-ons/kernel/debugger/qrencode/split.h diff --git a/src/add-ons/kernel/debugger/qrencode/bitstream.c b/src/add-ons/kernel/debugger/qrencode/bitstream.c new file mode 100644 index 0000000000..a0b9283cb0 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/bitstream.c @@ -0,0 +1,238 @@ +/* + * qrencode - QR Code encoder + * + * Binary sequence class. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include + +#include "bitstream.h" + +BitStream *BitStream_new(void) +{ + BitStream *bstream; + + bstream = (BitStream *)malloc(sizeof(BitStream)); + if(bstream == NULL) return NULL; + + bstream->length = 0; + bstream->data = NULL; + + return bstream; +} + +static int BitStream_allocate(BitStream *bstream, int length) +{ + unsigned char *data; + + if(bstream == NULL) { + return -1; + } + + data = (unsigned char *)malloc(length); + if(data == NULL) { + return -1; + } + + if(bstream->data) { + free(bstream->data); + } + bstream->length = length; + bstream->data = data; + + return 0; +} + +static BitStream *BitStream_newFromNum(int bits, unsigned int num) +{ + unsigned int mask; + int i; + unsigned char *p; + BitStream *bstream; + + bstream = BitStream_new(); + if(bstream == NULL) return NULL; + + if(BitStream_allocate(bstream, bits)) { + BitStream_free(bstream); + return NULL; + } + + p = bstream->data; + mask = 1 << (bits - 1); + for(i=0; i> 1; + } + + return bstream; +} + +static BitStream *BitStream_newFromBytes(int size, unsigned char *data) +{ + unsigned char mask; + int i, j; + unsigned char *p; + BitStream *bstream; + + bstream = BitStream_new(); + if(bstream == NULL) return NULL; + + if(BitStream_allocate(bstream, size * 8)) { + BitStream_free(bstream); + return NULL; + } + + p = bstream->data; + for(i=0; i> 1; + } + } + + return bstream; +} + +int BitStream_append(BitStream *bstream, BitStream *arg) +{ + unsigned char *data; + + if(arg == NULL) { + return -1; + } + if(arg->length == 0) { + return 0; + } + if(bstream->length == 0) { + if(BitStream_allocate(bstream, arg->length)) { + return -1; + } + memcpy(bstream->data, arg->data, arg->length); + return 0; + } + + data = (unsigned char *)malloc(bstream->length + arg->length); + if(data == NULL) { + return -1; + } + memcpy(data, bstream->data, bstream->length); + memcpy(data + bstream->length, arg->data, arg->length); + + free(bstream->data); + bstream->length += arg->length; + bstream->data = data; + + return 0; +} + +int BitStream_appendNum(BitStream *bstream, int bits, unsigned int num) +{ + BitStream *b; + int ret; + + if(bits == 0) return 0; + + b = BitStream_newFromNum(bits, num); + if(b == NULL) return -1; + + ret = BitStream_append(bstream, b); + BitStream_free(b); + + return ret; +} + +int BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data) +{ + BitStream *b; + int ret; + + if(size == 0) return 0; + + b = BitStream_newFromBytes(size, data); + if(b == NULL) return -1; + + ret = BitStream_append(bstream, b); + BitStream_free(b); + + return ret; +} + +unsigned char *BitStream_toByte(BitStream *bstream) +{ + int i, j, size, bytes; + unsigned char *data, v; + unsigned char *p; + + size = BitStream_size(bstream); + if(size == 0) { + return NULL; + } + data = (unsigned char *)malloc((size + 7) / 8); + if(data == NULL) { + return NULL; + } + + bytes = size / 8; + + p = bstream->data; + for(i=0; idata); + free(bstream); + } +} diff --git a/src/add-ons/kernel/debugger/qrencode/bitstream.h b/src/add-ons/kernel/debugger/qrencode/bitstream.h new file mode 100644 index 0000000000..ffe743c5e0 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/bitstream.h @@ -0,0 +1,38 @@ +/* + * qrencode - QR Code encoder + * + * Binary sequence class. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __BITSTREAM_H__ +#define __BITSTREAM_H__ + +typedef struct { + int length; + unsigned char *data; +} BitStream; + +extern BitStream *BitStream_new(void); +extern int BitStream_append(BitStream *bstream, BitStream *arg); +extern int BitStream_appendNum(BitStream *bstream, int bits, unsigned int num); +extern int BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data); +#define BitStream_size(__bstream__) (__bstream__->length) +extern unsigned char *BitStream_toByte(BitStream *bstream); +extern void BitStream_free(BitStream *bstream); + +#endif /* __BITSTREAM_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/config.h b/src/add-ons/kernel/debugger/qrencode/config.h new file mode 100644 index 0000000000..20515db864 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/config.h @@ -0,0 +1,5 @@ +#define MAJOR_VERSION 3 +#define MINOR_VERSION 3 +#define MICRO_VERSION 0 +#define VERSION "3.3.0" +#define __STATIC static diff --git a/src/add-ons/kernel/debugger/qrencode/mask.c b/src/add-ons/kernel/debugger/qrencode/mask.c new file mode 100644 index 0000000000..47c658ca0e --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/mask.c @@ -0,0 +1,330 @@ +/* + * qrencode - QR Code encoder + * + * Masking. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "qrspec.h" +#include "mask.h" + +__STATIC int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level) +{ + unsigned int format; + unsigned char v; + int i; + int blacks = 0; + + format = QRspec_getFormatInfo(mask, level); + + for(i=0; i<8; i++) { + if(format & 1) { + blacks += 2; + v = 0x85; + } else { + v = 0x84; + } + frame[width * 8 + width - 1 - i] = v; + if(i < 6) { + frame[width * i + 8] = v; + } else { + frame[width * (i + 1) + 8] = v; + } + format= format >> 1; + } + for(i=0; i<7; i++) { + if(format & 1) { + blacks += 2; + v = 0x85; + } else { + v = 0x84; + } + frame[width * (width - 7 + i) + 8] = v; + if(i == 0) { + frame[width * 8 + 7] = v; + } else { + frame[width * 8 + 6 - i] = v; + } + format= format >> 1; + } + + return blacks; +} + +/** + * Demerit coefficients. + * See Section 8.8.2, pp.45, JIS X0510:2004. + */ +#define N1 (3) +#define N2 (3) +#define N3 (40) +#define N4 (10) + +#define MASKMAKER(__exp__) \ + int x, y;\ + int b = 0;\ +\ + for(y=0; y= maskNum) { + errno = EINVAL; + return NULL; + } + + masked = (unsigned char *)malloc(width * width); + if(masked == NULL) return NULL; + + maskMakers[mask](width, frame, masked); + Mask_writeFormatInformation(width, masked, mask, level); + + return masked; +} + + +//static int n1; +//static int n2; +//static int n3; +//static int n4; + +__STATIC int Mask_calcN1N3(int length, int *runLength) +{ + int i; + int demerit = 0; + int fact; + + for(i=0; i= 5) { + demerit += N1 + (runLength[i] - 5); + //n1 += N1 + (runLength[i] - 5); + } + if((i & 1)) { + if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) { + fact = runLength[i] / 3; + if(runLength[i-2] == fact && + runLength[i-1] == fact && + runLength[i+1] == fact && + runLength[i+2] == fact) { + if(i == 3 || runLength[i-3] >= 4 * fact) { + demerit += N3; + //n3 += N3; + } else if(i+4 >= length || runLength[i+3] >= 4 * fact) { + demerit += N3; + //n3 += N3; + } + } + } + } + } + + return demerit; +} + +__STATIC int Mask_calcN2(int width, unsigned char *frame) +{ + int x, y; + unsigned char *p; + unsigned char b22, w22; + int demerit = 0; + + p = frame + width + 1; + for(y=1; y + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MASK_H__ +#define __MASK_H__ + +extern unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level); + +#ifdef WITH_TESTS +extern int Mask_calcN2(int width, unsigned char *frame); +extern int Mask_calcN1N3(int length, int *runLength); +extern int Mask_calcRunLength(int width, unsigned char *frame, int dir, int *runLength); +extern int Mask_evaluateSymbol(int width, unsigned char *frame); +extern int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask); +#endif + +#endif /* __MASK_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/mmask.c b/src/add-ons/kernel/debugger/qrencode/mmask.c new file mode 100644 index 0000000000..99470f2008 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/mmask.c @@ -0,0 +1,177 @@ +/* + * qrencode - QR Code encoder + * + * Masking for Micro QR Code. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "mqrspec.h" +#include "mmask.h" + +__STATIC void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level) +{ + unsigned int format; + unsigned char v; + int i; + + format = MQRspec_getFormatInfo(mask, version, level); + + for(i=0; i<8; i++) { + v = 0x84 | (format & 1); + frame[width * (i + 1) + 8] = v; + format = format >> 1; + } + for(i=0; i<7; i++) { + v = 0x84 | (format & 1); + frame[width * 8 + 7 - i] = v; + format = format >> 1; + } +} + +#define MASKMAKER(__exp__) \ + int x, y;\ +\ + for(y=0; y= maskNum) { + errno = EINVAL; + return NULL; + } + + width = MQRspec_getWidth(version); + masked = (unsigned char *)malloc(width * width); + if(masked == NULL) return NULL; + + maskMakers[mask](width, frame, masked); + MMask_writeFormatInformation(version, width, masked, mask, level); + + return masked; +} + +__STATIC int MMask_evaluateSymbol(int width, unsigned char *frame) +{ + int x, y; + unsigned char *p; + int sum1 = 0, sum2 = 0; + + p = frame + width * (width - 1); + for(x=1; x maxScore) { + maxScore = score; + free(bestMask); + bestMask = mask; + mask = (unsigned char *)malloc(width * width); + if(mask == NULL) break; + } + } + free(mask); + return bestMask; +} diff --git a/src/add-ons/kernel/debugger/qrencode/mmask.h b/src/add-ons/kernel/debugger/qrencode/mmask.h new file mode 100644 index 0000000000..f6556e877d --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/mmask.h @@ -0,0 +1,34 @@ +/* + * qrencode - QR Code encoder + * + * Masking for Micro QR Code. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MMASK_H__ +#define __MMASK_H__ + +extern unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level); + +#ifdef WITH_TESTS +extern int MMask_evaluateSymbol(int width, unsigned char *frame); +extern void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask); +#endif + +#endif /* __MMASK_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/mqrspec.c b/src/add-ons/kernel/debugger/qrencode/mqrspec.c new file mode 100644 index 0000000000..76d2d261a6 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/mqrspec.c @@ -0,0 +1,280 @@ +/* + * qrencode - QR Code encoder + * + * Micor QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#ifdef HAVE_LIBPTHREAD +#include +#endif + +#include "mqrspec.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +typedef struct { + int width; //< Edge length of the symbol + int ec[4]; //< Number of ECC code (bytes) +} MQRspec_Capacity; + +/** + * Table of the capacity of symbols + * See Table 1 (pp.106) and Table 8 (pp.113) of Appendix 1, JIS X0510:2004. + */ +static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = { + { 0, {0, 0, 0, 0}}, + { 11, {2, 0, 0, 0}}, + { 13, {5, 6, 0, 0}}, + { 15, {6, 8, 0, 0}}, + { 17, {8, 10, 14, 0}} +}; + +int MQRspec_getDataLengthBit(int version, QRecLevel level) +{ + int w; + int ecc; + + w = mqrspecCapacity[version].width - 1; + ecc = mqrspecCapacity[version].ec[level]; + if(ecc == 0) return 0; + return w * w - 64 - ecc * 8; +} + +int MQRspec_getDataLength(int version, QRecLevel level) +{ + return (MQRspec_getDataLengthBit(version, level) + 4) / 8; +} + +int MQRspec_getECCLength(int version, QRecLevel level) +{ + return mqrspecCapacity[version].ec[level]; +} + +int MQRspec_getWidth(int version) +{ + return mqrspecCapacity[version].width; +} + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +/** + * See Table 3 (pp.107) of Appendix 1, JIS X0510:2004. + */ +static const int lengthTableBits[4][4] = { + { 3, 4, 5, 6}, + { 0, 3, 4, 5}, + { 0, 0, 4, 5}, + { 0, 0, 3, 4} +}; + +int MQRspec_lengthIndicator(QRencodeMode mode, int version) +{ + return lengthTableBits[mode][version - 1]; +} + +int MQRspec_maximumWords(QRencodeMode mode, int version) +{ + int bits; + int words; + + bits = lengthTableBits[mode][version - 1]; + words = (1 << bits) - 1; + if(mode == QR_MODE_KANJI) { + words *= 2; // the number of bytes is required + } + + return words; +} + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/* See calcFormatInfo in tests/test_mqrspec.c */ +static const unsigned int formatInfo[4][8] = { + {0x4445, 0x55ae, 0x6793, 0x7678, 0x06de, 0x1735, 0x2508, 0x34e3}, + {0x4172, 0x5099, 0x62a4, 0x734f, 0x03e9, 0x1202, 0x203f, 0x31d4}, + {0x4e2b, 0x5fc0, 0x6dfd, 0x7c16, 0x0cb0, 0x1d5b, 0x2f66, 0x3e8d}, + {0x4b1c, 0x5af7, 0x68ca, 0x7921, 0x0987, 0x186c, 0x2a51, 0x3bba} +}; + +/* See Table 10 of Appendix 1. (pp.115) */ +static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = { + {-1, -1, -1}, + { 0, -1, -1}, + { 1, 2, -1}, + { 3, 4, -1}, + { 5, 6, 7} +}; + +unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level) +{ + int type; + + if(mask < 0 || mask > 3) return 0; + if(version <= 0 || version > MQRSPEC_VERSION_MAX) return 0; + if(level == QR_ECLEVEL_H) return 0; + type = typeTable[version][level]; + if(type < 0) return 0; + + return formatInfo[mask][type]; +} + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Cache of initial frames. + */ +/* C99 says that static storage shall be initialized to a null pointer + * by compiler. */ +static unsigned char *frames[MQRSPEC_VERSION_MAX + 1]; +#ifdef HAVE_LIBPTHREAD +static pthread_mutex_t frames_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +/** + * Put a finder pattern. + * @param frame + * @param width + * @param ox,oy upper-left coordinate of the pattern + */ +static void putFinderPattern(unsigned char *frame, int width, int ox, int oy) +{ + static const unsigned char finder[] = { + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + }; + int x, y; + const unsigned char *s; + + frame += oy * width + ox; + s = finder; + for(y=0; y<7; y++) { + for(x=0; x<7; x++) { + frame[x] = s[x]; + } + frame += width; + s += 7; + } +} + +static unsigned char *MQRspec_createFrame(int version) +{ + unsigned char *frame, *p, *q; + int width; + int x, y; + + width = mqrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + + memset(frame, 0, width * width); + /* Finder pattern */ + putFinderPattern(frame, width, 0, 0); + /* Separator */ + p = frame; + for(y=0; y<7; y++) { + p[7] = 0xc0; + p += width; + } + memset(frame + width * 7, 0xc0, 8); + /* Mask format information area */ + memset(frame + width * 8 + 1, 0x84, 8); + p = frame + width + 8; + for(y=0; y<7; y++) { + *p = 0x84; + p += width; + } + /* Timing pattern */ + p = frame + 8; + q = frame + width * 8; + for(x=1; x MQRSPEC_VERSION_MAX) return NULL; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + if(frames[version] == NULL) { + frames[version] = MQRspec_createFrame(version); + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif + if(frames[version] == NULL) return NULL; + + width = mqrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + memcpy(frame, frames[version], width * width); + + return frame; +} + +void MQRspec_clearCache(void) +{ + int i; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + for(i=1; i<=MQRSPEC_VERSION_MAX; i++) { + free(frames[i]); + frames[i] = NULL; + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif +} diff --git a/src/add-ons/kernel/debugger/qrencode/mqrspec.h b/src/add-ons/kernel/debugger/qrencode/mqrspec.h new file mode 100644 index 0000000000..2d4b90d281 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/mqrspec.h @@ -0,0 +1,157 @@ +/* + * qrencode - QR Code encoder + * + * Micro QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MQRSPEC_H__ +#define __MQRSPEC_H__ + +#include "qrencode.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +/** + * Maximum width of a symbol + */ +#define MQRSPEC_WIDTH_MAX 17 + +/** + * Return maximum data code length (bits) for the version. + * @param version + * @param level + * @return maximum size (bits) + */ +extern int MQRspec_getDataLengthBit(int version, QRecLevel level); + +/** + * Return maximum data code length (bytes) for the version. + * @param version + * @param level + * @return maximum size (bytes) + */ +extern int MQRspec_getDataLength(int version, QRecLevel level); + +/** + * Return maximum error correction code length (bytes) for the version. + * @param version + * @param level + * @return ECC size (bytes) + */ +extern int MQRspec_getECCLength(int version, QRecLevel level); + +/** + * Return a version number that satisfies the input code length. + * @param size input code length (byte) + * @param level + * @return version number + */ +extern int MQRspec_getMinimumVersion(int size, QRecLevel level); + +/** + * Return the width of the symbol for the version. + * @param version + * @return width + */ +extern int MQRspec_getWidth(int version); + +/** + * Return the numer of remainder bits. + * @param version + * @return number of remainder bits + */ +extern int MQRspec_getRemainder(int version); + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +/** + * Return the size of lenght indicator for the mode and version. + * @param mode + * @param version + * @return the size of the appropriate length indicator (bits). + */ +extern int MQRspec_lengthIndicator(QRencodeMode mode, int version); + +/** + * Return the maximum length for the mode and version. + * @param mode + * @param version + * @return the maximum length (bytes) + */ +extern int MQRspec_maximumWords(QRencodeMode mode, int version); + +/****************************************************************************** + * Version information pattern + *****************************************************************************/ + +/** + * Return BCH encoded version information pattern that is used for the symbol + * of version 7 or greater. Use lower 18 bits. + * @param version + * @return BCH encoded version information pattern + */ +extern unsigned int MQRspec_getVersionPattern(int version); + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/** + * Return BCH encoded format information pattern. + * @param mask + * @param version + * @param level + * @return BCH encoded format information pattern + */ +extern unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level); + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Return a copy of initialized frame. + * When the same version is requested twice or more, a copy of cached frame + * is returned. + * @param version + * @return Array of unsigned char. You can free it by free(). + */ +extern unsigned char *MQRspec_newFrame(int version); + +/** + * Clear the frame cache. Typically for debug. + */ +extern void MQRspec_clearCache(void); + +/****************************************************************************** + * Mode indicator + *****************************************************************************/ + +/** + * Mode indicator. See Table 2 in Appendix 1 of JIS X0510:2004, pp.107. + */ +#define MQRSPEC_MODEID_NUM 0 +#define MQRSPEC_MODEID_AN 1 +#define MQRSPEC_MODEID_8 2 +#define MQRSPEC_MODEID_KANJI 3 + +#endif /* __MQRSPEC_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/qrencode.c b/src/add-ons/kernel/debugger/qrencode/qrencode.c new file mode 100644 index 0000000000..d166a24812 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrencode.c @@ -0,0 +1,929 @@ +/* + * qrencode - QR Code encoder + * + * Copyright (C) 2006-2012 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "qrspec.h" +#include "mqrspec.h" +#include "bitstream.h" +#include "qrinput.h" +#include "rscode.h" +#include "split.h" +#include "mask.h" +#include "mmask.h" + +/****************************************************************************** + * Raw code + *****************************************************************************/ + +typedef struct { + int dataLength; + unsigned char *data; + int eccLength; + unsigned char *ecc; +} RSblock; + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + int b1; + int blocks; + RSblock *rsblock; + int count; +} QRRawCode; + +static void RSblock_initBlock(RSblock *block, int dl, unsigned char *data, int el, unsigned char *ecc, RS *rs) +{ + block->dataLength = dl; + block->data = data; + block->eccLength = el; + block->ecc = ecc; + + encode_rs_char(rs, data, ecc); +} + +static int RSblock_init(RSblock *blocks, int spec[5], unsigned char *data, unsigned char *ecc) +{ + int i; + RSblock *block; + unsigned char *dp, *ep; + RS *rs; + int el, dl; + + dl = QRspec_rsDataCodes1(spec); + el = QRspec_rsEccCodes1(spec); + rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el); + if(rs == NULL) return -1; + + block = blocks; + dp = data; + ep = ecc; + for(i=0; idatacode = QRinput_getByteStream(input); + if(raw->datacode == NULL) { + free(raw); + return NULL; + } + + QRspec_getEccSpec(input->version, input->level, spec); + + raw->version = input->version; + raw->b1 = QRspec_rsBlockNum1(spec); + raw->dataLength = QRspec_rsDataLength(spec); + raw->eccLength = QRspec_rsEccLength(spec); + raw->ecccode = (unsigned char *)malloc(raw->eccLength); + if(raw->ecccode == NULL) { + free(raw->datacode); + free(raw); + return NULL; + } + + raw->blocks = QRspec_rsBlockNum(spec); + raw->rsblock = (RSblock *)calloc(sizeof(RSblock), raw->blocks); + if(raw->rsblock == NULL) { + QRraw_free(raw); + return NULL; + } + ret = RSblock_init(raw->rsblock, spec, raw->datacode, raw->ecccode); + if(ret < 0) { + QRraw_free(raw); + return NULL; + } + + raw->count = 0; + + return raw; +} + +/** + * Return a code (byte). + * This function can be called iteratively. + * @param raw raw code. + * @return code + */ +__STATIC unsigned char QRraw_getCode(QRRawCode *raw) +{ + int col, row; + unsigned char ret; + + if(raw->count < raw->dataLength) { + row = raw->count % raw->blocks; + col = raw->count / raw->blocks; + if(col >= raw->rsblock[0].dataLength) { + row += raw->b1; + } + ret = raw->rsblock[row].data[col]; + } else if(raw->count < raw->dataLength + raw->eccLength) { + row = (raw->count - raw->dataLength) % raw->blocks; + col = (raw->count - raw->dataLength) / raw->blocks; + ret = raw->rsblock[row].ecc[col]; + } else { + return 0; + } + raw->count++; + return ret; +} + +__STATIC void QRraw_free(QRRawCode *raw) +{ + if(raw != NULL) { + free(raw->datacode); + free(raw->ecccode); + free(raw->rsblock); + free(raw); + } +} + +/****************************************************************************** + * Raw code for Micro QR Code + *****************************************************************************/ + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + RSblock *rsblock; + int oddbits; + int count; +} MQRRawCode; + +__STATIC void MQRraw_free(MQRRawCode *raw); +__STATIC MQRRawCode *MQRraw_new(QRinput *input) +{ + MQRRawCode *raw; + RS *rs; + + raw = (MQRRawCode *)malloc(sizeof(MQRRawCode)); + if(raw == NULL) return NULL; + + raw->version = input->version; + raw->dataLength = MQRspec_getDataLength(input->version, input->level); + raw->eccLength = MQRspec_getECCLength(input->version, input->level); + raw->oddbits = raw->dataLength * 8 - MQRspec_getDataLengthBit(input->version, input->level); + raw->datacode = QRinput_getByteStream(input); + if(raw->datacode == NULL) { + free(raw); + return NULL; + } + raw->ecccode = (unsigned char *)malloc(raw->eccLength); + if(raw->ecccode == NULL) { + free(raw->datacode); + free(raw); + return NULL; + } + + raw->rsblock = (RSblock *)calloc(sizeof(RSblock), 1); + if(raw->rsblock == NULL) { + MQRraw_free(raw); + return NULL; + } + + rs = init_rs(8, 0x11d, 0, 1, raw->eccLength, 255 - raw->dataLength - raw->eccLength); + if(rs == NULL) { + MQRraw_free(raw); + return NULL; + } + + RSblock_initBlock(raw->rsblock, raw->dataLength, raw->datacode, raw->eccLength, raw->ecccode, rs); + + raw->count = 0; + + return raw; +} + +/** + * Return a code (byte). + * This function can be called iteratively. + * @param raw raw code. + * @return code + */ +__STATIC unsigned char MQRraw_getCode(MQRRawCode *raw) +{ + unsigned char ret; + + if(raw->count < raw->dataLength) { + ret = raw->datacode[raw->count]; + } else if(raw->count < raw->dataLength + raw->eccLength) { + ret = raw->ecccode[raw->count - raw->dataLength]; + } else { + return 0; + } + raw->count++; + return ret; +} + +__STATIC void MQRraw_free(MQRRawCode *raw) +{ + if(raw != NULL) { + free(raw->datacode); + free(raw->ecccode); + free(raw->rsblock); + free(raw); + } +} + + +/****************************************************************************** + * Frame filling + *****************************************************************************/ + +typedef struct { + int width; + unsigned char *frame; + int x, y; + int dir; + int bit; + int mqr; +} FrameFiller; + +static FrameFiller *FrameFiller_new(int width, unsigned char *frame, int mqr) +{ + FrameFiller *filler; + + filler = (FrameFiller *)malloc(sizeof(FrameFiller)); + if(filler == NULL) return NULL; + filler->width = width; + filler->frame = frame; + filler->x = width - 1; + filler->y = width - 1; + filler->dir = -1; + filler->bit = -1; + filler->mqr = mqr; + + return filler; +} + +static unsigned char *FrameFiller_next(FrameFiller *filler) +{ + unsigned char *p; + int x, y, w; + + if(filler->bit == -1) { + filler->bit = 0; + return filler->frame + filler->y * filler->width + filler->x; + } + + x = filler->x; + y = filler->y; + p = filler->frame; + w = filler->width; + + if(filler->bit == 0) { + x--; + filler->bit++; + } else { + x++; + y += filler->dir; + filler->bit--; + } + + if(filler->dir < 0) { + if(y < 0) { + y = 0; + x -= 2; + filler->dir = 1; + if(!filler->mqr && x == 6) { + x--; + y = 9; + } + } + } else { + if(y == w) { + y = w - 1; + x -= 2; + filler->dir = -1; + if(!filler->mqr && x == 6) { + x--; + y -= 8; + } + } + } + if(x < 0 || y < 0) return NULL; + + filler->x = x; + filler->y = y; + + if(p[y * w + x] & 0x80) { + // This tail recursion could be optimized. + return FrameFiller_next(filler); + } + return &p[y * w + x]; +} + +#ifdef WITH_TESTS +extern unsigned char *FrameFiller_test(int version) +{ + int width; + unsigned char *frame, *p; + FrameFiller *filler; + int i, length; + + width = QRspec_getWidth(version); + frame = QRspec_newFrame(version); + if(frame == NULL) return NULL; + filler = FrameFiller_new(width, frame, 0); + if(filler == NULL) { + free(frame); + return NULL; + } + length = QRspec_getDataLength(version, QR_ECLEVEL_L) * 8 + + QRspec_getECCLength(version, QR_ECLEVEL_L) * 8 + + QRspec_getRemainder(version); + for(i=0; iversion = version; + qrcode->width = width; + qrcode->data = data; + + return qrcode; +} + +void QRcode_free(QRcode *qrcode) +{ + if(qrcode != NULL) { + free(qrcode->data); + free(qrcode); + } +} + +__STATIC QRcode *QRcode_encodeMask(QRinput *input, int mask) +{ + int width, version; + QRRawCode *raw; + unsigned char *frame, *masked, *p, code, bit; + FrameFiller *filler; + int i, j; + QRcode *qrcode = NULL; + + if(input->mqr) { + errno = EINVAL; + return NULL; + } + if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) { + errno = EINVAL; + return NULL; + } + if(input->level > QR_ECLEVEL_H) { + errno = EINVAL; + return NULL; + } + + raw = QRraw_new(input); + if(raw == NULL) return NULL; + + version = raw->version; + width = QRspec_getWidth(version); + frame = QRspec_newFrame(version); + if(frame == NULL) { + QRraw_free(raw); + return NULL; + } + filler = FrameFiller_new(width, frame, 0); + if(filler == NULL) { + QRraw_free(raw); + free(frame); + return NULL; + } + + /* inteleaved data and ecc codes */ + for(i=0; idataLength + raw->eccLength; i++) { + code = QRraw_getCode(raw); + bit = 0x80; + for(j=0; j<8; j++) { + p = FrameFiller_next(filler); + if(p == NULL) goto EXIT; + *p = 0x02 | ((bit & code) != 0); + bit = bit >> 1; + } + } + QRraw_free(raw); + raw = NULL; + /* remainder bits */ + j = QRspec_getRemainder(version); + for(i=0; ilevel); + } else { + masked = Mask_makeMask(width, frame, mask, input->level); + } + if(masked == NULL) { + goto EXIT; + } + qrcode = QRcode_new(version, width, masked); + +EXIT: + QRraw_free(raw); + free(filler); + free(frame); + return qrcode; +} + +__STATIC QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask) +{ + int width, version; + MQRRawCode *raw; + unsigned char *frame, *masked, *p, code, bit; + FrameFiller *filler; + int i, j; + QRcode *qrcode = NULL; + + if(!input->mqr) { + errno = EINVAL; + return NULL; + } + if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) { + errno = EINVAL; + return NULL; + } + if(input->level > QR_ECLEVEL_Q) { + errno = EINVAL; + return NULL; + } + + raw = MQRraw_new(input); + if(raw == NULL) return NULL; + + version = raw->version; + width = MQRspec_getWidth(version); + frame = MQRspec_newFrame(version); + if(frame == NULL) { + MQRraw_free(raw); + return NULL; + } + filler = FrameFiller_new(width, frame, 1); + if(filler == NULL) { + MQRraw_free(raw); + free(frame); + return NULL; + } + + /* inteleaved data and ecc codes */ + for(i=0; idataLength + raw->eccLength; i++) { + code = MQRraw_getCode(raw); + if(raw->oddbits && i == raw->dataLength - 1) { + bit = 1 << raw->oddbits; + for(j=0; joddbits; j++) { + p = FrameFiller_next(filler); + if(p == NULL) goto EXIT; + *p = 0x02 | ((bit & code) != 0); + bit = bit >> 1; + } + } else { + bit = 0x80; + for(j=0; j<8; j++) { + p = FrameFiller_next(filler); + if(p == NULL) goto EXIT; + *p = 0x02 | ((bit & code) != 0); + bit = bit >> 1; + } + } + } + MQRraw_free(raw); + raw = NULL; + + /* masking */ + if(mask < 0) { + masked = MMask_mask(version, frame, input->level); + } else { + masked = MMask_makeMask(version, frame, mask, input->level); + } + if(masked == NULL) { + goto EXIT; + } + + qrcode = QRcode_new(version, width, masked); + +EXIT: + MQRraw_free(raw); + free(filler); + free(frame); + return qrcode; +} + +QRcode *QRcode_encodeInput(QRinput *input) +{ + if(input->mqr) { + return QRcode_encodeMaskMQR(input, -1); + } else { + return QRcode_encodeMask(input, -1); + } +} + +static QRcode *QRcode_encodeStringReal(const char *string, int version, QRecLevel level, int mqr, QRencodeMode hint, int casesensitive) +{ + QRinput *input; + QRcode *code; + int ret; + + if(string == NULL) { + errno = EINVAL; + return NULL; + } + if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) { + errno = EINVAL; + return NULL; + } + + if(mqr) { + input = QRinput_newMQR(version, level); + } else { + input = QRinput_new2(version, level); + } + if(input == NULL) return NULL; + + ret = Split_splitStringToQRinput(string, input, hint, casesensitive); + if(ret < 0) { + QRinput_free(input); + return NULL; + } + code = QRcode_encodeInput(input); + QRinput_free(input); + + return code; +} + +QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) +{ + return QRcode_encodeStringReal(string, version, level, 0, hint, casesensitive); +} + +QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) +{ + return QRcode_encodeStringReal(string, version, level, 1, hint, casesensitive); +} + +static QRcode *QRcode_encodeDataReal(const unsigned char *data, int length, int version, QRecLevel level, int mqr) +{ + QRinput *input; + QRcode *code; + int ret; + + if(data == NULL || length == 0) { + errno = EINVAL; + return NULL; + } + + if(mqr) { + input = QRinput_newMQR(version, level); + } else { + input = QRinput_new2(version, level); + } + if(input == NULL) return NULL; + + ret = QRinput_append(input, QR_MODE_8, length, data); + if(ret < 0) { + QRinput_free(input); + return NULL; + } + code = QRcode_encodeInput(input); + QRinput_free(input); + + return code; +} + +QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level) +{ + return QRcode_encodeDataReal(data, size, version, level, 0); +} + +QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level) +{ + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataReal((unsigned char *)string, strlen(string), version, level, 0); +} + +QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level) +{ + return QRcode_encodeDataReal(data, size, version, level, 1); +} + +QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level) +{ + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataReal((unsigned char *)string, strlen(string), version, level, 1); +} + + +/****************************************************************************** + * Structured QR-code encoding + *****************************************************************************/ + +static QRcode_List *QRcode_List_newEntry(void) +{ + QRcode_List *entry; + + entry = (QRcode_List *)malloc(sizeof(QRcode_List)); + if(entry == NULL) return NULL; + + entry->next = NULL; + entry->code = NULL; + + return entry; +} + +static void QRcode_List_freeEntry(QRcode_List *entry) +{ + if(entry != NULL) { + QRcode_free(entry->code); + free(entry); + } +} + +void QRcode_List_free(QRcode_List *qrlist) +{ + QRcode_List *list = qrlist, *next; + + while(list != NULL) { + next = list->next; + QRcode_List_freeEntry(list); + list = next; + } +} + +int QRcode_List_size(QRcode_List *qrlist) +{ + QRcode_List *list = qrlist; + int size = 0; + + while(list != NULL) { + size++; + list = list->next; + } + + return size; +} + +#if 0 +static unsigned char QRcode_parity(const char *str, int size) +{ + unsigned char parity = 0; + int i; + + for(i=0; ihead; + + while(list != NULL) { + if(head == NULL) { + entry = QRcode_List_newEntry(); + if(entry == NULL) goto ABORT; + head = entry; + tail = head; + } else { + entry = QRcode_List_newEntry(); + if(entry == NULL) goto ABORT; + tail->next = entry; + tail = tail->next; + } + tail->code = QRcode_encodeInput(list->input); + if(tail->code == NULL) { + goto ABORT; + } + list = list->next; + } + + return head; +ABORT: + QRcode_List_free(head); + return NULL; +} + +static QRcode_List *QRcode_encodeInputToStructured(QRinput *input) +{ + QRinput_Struct *s; + QRcode_List *codes; + + s = QRinput_splitQRinputToStruct(input); + if(s == NULL) return NULL; + + codes = QRcode_encodeInputStructured(s); + QRinput_Struct_free(s); + + return codes; +} + +static QRcode_List *QRcode_encodeDataStructuredReal( + int size, const unsigned char *data, + int version, QRecLevel level, + int eightbit, QRencodeMode hint, int casesensitive) +{ + QRinput *input; + QRcode_List *codes; + int ret; + + if(version <= 0) { + errno = EINVAL; + return NULL; + } + if(!eightbit && (hint != QR_MODE_8 && hint != QR_MODE_KANJI)) { + errno = EINVAL; + return NULL; + } + + input = QRinput_new2(version, level); + if(input == NULL) return NULL; + + if(eightbit) { + ret = QRinput_append(input, QR_MODE_8, size, data); + } else { + ret = Split_splitStringToQRinput((char *)data, input, hint, casesensitive); + } + if(ret < 0) { + QRinput_free(input); + return NULL; + } + codes = QRcode_encodeInputToStructured(input); + QRinput_free(input); + + return codes; +} + +QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level) { + return QRcode_encodeDataStructuredReal(size, data, version, level, 1, QR_MODE_NUL, 0); +} + +QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level) { + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataStructured(strlen(string), (unsigned char *)string, version, level); +} + +QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) +{ + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataStructuredReal(strlen(string), (unsigned char *)string, version, level, 0, hint, casesensitive); +} + +/****************************************************************************** + * System utilities + *****************************************************************************/ + +void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version) +{ + if(major_version != NULL) { + *major_version = MAJOR_VERSION; + } + if(minor_version != NULL) { + *minor_version = MINOR_VERSION; + } + if(micro_version != NULL) { + *micro_version = MICRO_VERSION; + } +} + +char *QRcode_APIVersionString(void) +{ + return VERSION; +} + +void QRcode_clearCache(void) +{ + QRspec_clearCache(); + MQRspec_clearCache(); + free_rs_cache(); +} diff --git a/src/add-ons/kernel/debugger/qrencode/qrencode.h b/src/add-ons/kernel/debugger/qrencode/qrencode.h new file mode 100644 index 0000000000..fa53e364d5 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrencode.h @@ -0,0 +1,565 @@ +/** + * qrencode - QR Code encoder + * + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** \mainpage + * Libqrencode is a library for encoding data in a QR Code symbol, a kind of 2D + * symbology. + * + * \section encoding Encoding + * + * There are two ways to encode data: encoding a string or + * encoding a structured data. + * + * \subsection encoding-string Encoding a string + * You can encode a string by calling QRcode_encodeString(). + * The given string is parsed automatically and encoded. If you want to encode + * data that can be represented as a C string style (NUL terminated), you can + * simply use this way. + * + * If the input data contains Kanji (Shift-JIS) characters and you want to + * encode them as Kanji in QR Code, you should give QR_MODE_KANJI as a hint. + * Otherwise, all of non-alphanumeric characters are encoded as 8 bit data. + * If you want to encode a whole string in 8 bit mode, use + * QRcode_encodeString8bit() instead. + * + * Please note that a C string can not contain NUL character. If your data + * contains NUL, you should chose the second way. + * + * \subsection encoding-input Encoding a structured data + * You can construct a structured input data manually. If the structure of the + * input data is known, you can use this way. + * At first, create a ::QRinput object by QRinput_new(). Then add input data + * to the QRinput object by QRinput_append(). Finally call QRcode_encodeInput() + * to encode the QRinput data. + * You can reuse the QRinput data again to encode it in other symbols with + * different parameters. + * + * \section result Result + * The encoded symbol is resulted as a ::QRcode object. It will contain + * its version number, width of the symbol and an array represents the symbol. + * See ::QRcode for the details. You can free the object by QRcode_free(). + * + * Please note that the version of the result may be larger than specified. + * In such cases, the input data would be too large to be encoded in a + * symbol of the specified version. + * + * \section structured Structured append + * Libqrencode can generate "Structured-appended" symbols that enables to split + * a large data set into mulitple QR codes. A QR code reader concatenates + * multiple QR code symbols into a string. + * Just like QRcode_encodeString(), you can use QRcode_encodeStringStructured() + * to generate structured-appended symbols. This functions returns an instance + * of ::QRcode_List. The returned list is a singly-linked list of QRcode: you + * can retrieve each QR code in this way: + * + * \code + * QRcode_List *qrcodes; + * QRcode_List *entry; + * QRcode *qrcode; + * + * qrcodes = QRcode_encodeStringStructured(...); + * entry = qrcodes; + * while(entry != NULL) { + * qrcode = entry->code; + * // do something + * entry = entry->next; + * } + * QRcode_List_free(entry); + * \endcode + * + * Instead of using auto-parsing functions, you can construct your own + * structured input. At first, instantiate an object of ::QRinput_Struct + * by calling QRinput_Struct_new(). This object can hold multiple ::QRinput, + * and one QR code is generated for a ::QRinput. + * QRinput_Struct_appendInput() appends a ::QRinput to a ::QRinput_Struct + * object. In order to generate structured-appended symbols, it is required to + * embed headers to each symbol. You can use + * QRinput_Struct_insertStructuredAppendHeaders() to insert appropriate + * headers to each symbol. You should call this function just once before + * encoding symbols. + */ + +#ifndef __QRENCODE_H__ +#define __QRENCODE_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * Encoding mode. + */ +typedef enum { + QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only + QR_MODE_NUM = 0, ///< Numeric mode + QR_MODE_AN, ///< Alphabet-numeric mode + QR_MODE_8, ///< 8-bit data mode + QR_MODE_KANJI, ///< Kanji (shift-jis) mode + QR_MODE_STRUCTURE, ///< Internal use only + QR_MODE_ECI, ///< ECI mode + QR_MODE_FNC1FIRST, ///< FNC1, first position + QR_MODE_FNC1SECOND, ///< FNC1, second position +} QRencodeMode; + +/** + * Level of error correction. + */ +typedef enum { + QR_ECLEVEL_L = 0, ///< lowest + QR_ECLEVEL_M, + QR_ECLEVEL_Q, + QR_ECLEVEL_H ///< highest +} QRecLevel; + +/** + * Maximum version (size) of QR-code symbol. + */ +#define QRSPEC_VERSION_MAX 40 + +/** + * Maximum version (size) of QR-code symbol. + */ +#define MQRSPEC_VERSION_MAX 4 + + +/****************************************************************************** + * Input data (qrinput.c) + *****************************************************************************/ + +/** + * Singly linked list to contain input strings. An instance of this class + * contains its version and error correction level too. It is required to + * set them by QRinput_setVersion() and QRinput_setErrorCorrectionLevel(), + * or use QRinput_new2() to instantiate an object. + */ +typedef struct _QRinput QRinput; + +/** + * Instantiate an input data object. The version is set to 0 (auto-select) + * and the error correction level is set to QR_ECLEVEL_L. + * @return an input object (initialized). On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory. + */ +extern QRinput *QRinput_new(void); + +/** + * Instantiate an input data object. + * @param version version number. + * @param level Error correction level. + * @return an input object (initialized). On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw EINVAL invalid arguments. + */ +extern QRinput *QRinput_new2(int version, QRecLevel level); + +/** + * Instantiate an input data object. Object's Micro QR Code flag is set. + * Unlike with full-sized QR Code, version number must be specified (>0). + * @param version version number (1--4). + * @param level Error correction level. + * @return an input object (initialized). On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw EINVAL invalid arguments. + */ +extern QRinput *QRinput_newMQR(int version, QRecLevel level); + +/** + * Append data to an input object. + * The data is copied and appended to the input object. + * @param input input object. + * @param mode encoding mode. + * @param size size of data (byte). + * @param data a pointer to the memory area of the input data. + * @retval 0 success. + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL input data is invalid. + * + */ +extern int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data); + +/** + * Append ECI header. + * @param input input object. + * @param ecinum ECI indicator number (0 - 999999) + * @retval 0 success. + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL input data is invalid. + * + */ +extern int QRinput_appendECIheader(QRinput *input, unsigned int ecinum); + +/** + * Get current version. + * @param input input object. + * @return current version. + */ +extern int QRinput_getVersion(QRinput *input); + +/** + * Set version of the QR code that is to be encoded. + * This function cannot be applied to Micro QR Code. + * @param input input object. + * @param version version number (0 = auto) + * @retval 0 success. + * @retval -1 invalid argument. + */ +extern int QRinput_setVersion(QRinput *input, int version); + +/** + * Get current error correction level. + * @param input input object. + * @return Current error correcntion level. + */ +extern QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input); + +/** + * Set error correction level of the QR code that is to be encoded. + * This function cannot be applied to Micro QR Code. + * @param input input object. + * @param level Error correction level. + * @retval 0 success. + * @retval -1 invalid argument. + */ +extern int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level); + +/** + * Set version and error correction level of the QR code at once. + * This function is recommened for Micro QR Code. + * @param input input object. + * @param version version number (0 = auto) + * @param level Error correction level. + * @retval 0 success. + * @retval -1 invalid argument. + */ +extern int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level); + +/** + * Free the input object. + * All of data chunks in the input object are freed too. + * @param input input object. + */ +extern void QRinput_free(QRinput *input); + +/** + * Validate the input data. + * @param mode encoding mode. + * @param size size of data (byte). + * @param data a pointer to the memory area of the input data. + * @retval 0 success. + * @retval -1 invalid arguments. + */ +extern int QRinput_check(QRencodeMode mode, int size, const unsigned char *data); + +/** + * Set of QRinput for structured symbols. + */ +typedef struct _QRinput_Struct QRinput_Struct; + +/** + * Instantiate a set of input data object. + * @return an instance of QRinput_Struct. On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory. + */ +extern QRinput_Struct *QRinput_Struct_new(void); + +/** + * Set parity of structured symbols. + * @param s structured input object. + * @param parity parity of s. + */ +extern void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity); + +/** + * Append a QRinput object to the set. QRinput created by QRinput_newMQR() + * will be rejected. + * @warning never append the same QRinput object twice or more. + * @param s structured input object. + * @param input an input object. + * @retval >0 number of input objects in the structure. + * @retval -1 an error occurred. See Exceptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL invalid arguments. + */ +extern int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input); + +/** + * Free all of QRinput in the set. + * @param s a structured input object. + */ +extern void QRinput_Struct_free(QRinput_Struct *s); + +/** + * Split a QRinput to QRinput_Struct. It calculates a parity, set it, then + * insert structured-append headers. QRinput created by QRinput_newMQR() will + * be rejected. + * @param input input object. Version number and error correction level must be + * set. + * @return a set of input data. On error, NULL is returned, and errno is set + * to indicate the error. See Exceptions for the details. + * @throw ERANGE input data is too large. + * @throw EINVAL invalid input data. + * @throw ENOMEM unable to allocate memory. + */ +extern QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input); + +/** + * Insert structured-append headers to the input structure. It calculates + * a parity and set it if the parity is not set yet. + * @param s input structure + * @retval 0 success. + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory. + */ +extern int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s); + +/** + * Set FNC1-1st position flag. + */ +extern int QRinput_setFNC1First(QRinput *input); + +/** + * Set FNC1-2nd position flag and application identifier. + */ +extern int QRinput_setFNC1Second(QRinput *input, unsigned char appid); + +/****************************************************************************** + * QRcode output (qrencode.c) + *****************************************************************************/ + +/** + * QRcode class. + * Symbol data is represented as an array contains width*width uchars. + * Each uchar represents a module (dot). If the less significant bit of + * the uchar is 1, the corresponding module is black. The other bits are + * meaningless for usual applications, but here its specification is described. + * + *

+ * MSB 76543210 LSB
+ *     |||||||`- 1=black/0=white
+ *     ||||||`-- data and ecc code area
+ *     |||||`--- format information
+ *     ||||`---- version information
+ *     |||`----- timing pattern
+ *     ||`------ alignment pattern
+ *     |`------- finder pattern and separator
+ *     `-------- non-data modules (format, timing, etc.)
+ * 
+ */ +typedef struct { + int version; ///< version of the symbol + int width; ///< width of the symbol + unsigned char *data; ///< symbol data +} QRcode; + +/** + * Singly-linked list of QRcode. Used to represent a structured symbols. + * A list is terminated with NULL. + */ +typedef struct _QRcode_List QRcode_List; + +struct _QRcode_List { + QRcode *code; + QRcode_List *next; +}; + +/** + * Create a symbol from the input data. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param input input data. + * @return an instance of QRcode class. The version of the result QRcode may + * be larger than the designated version. On error, NULL is returned, + * and errno is set to indicate the error. See Exceptions for the + * details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern QRcode *QRcode_encodeInput(QRinput *input); + +/** + * Create a symbol from the string. The library automatically parses the input + * string and encodes in a QR Code symbol. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param string input string. It must be NUL terminated. + * @param version version of the symbol. If 0, the library chooses the minimum + * version for the given input data. + * @param level error correction level. + * @param hint tell the library how non-alphanumerical characters should be + * encoded. If QR_MODE_KANJI is given, kanji characters will be + * encoded as Shif-JIS characters. If QR_MODE_8 is given, all of + * non-alphanumerical characters will be encoded as is. If you want + * to embed UTF-8 string, choose this. + * @param casesensitive case-sensitive(1) or not(0). + * @return an instance of QRcode class. The version of the result QRcode may + * be larger than the designated version. On error, NULL is returned, + * and errno is set to indicate the error. See Exceptions for the + * details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw ERANGE input data is too large. + */ +extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); + +/** + * Same to QRcode_encodeString(), but encode whole data in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level); + +/** + * Micro QR Code version of QRcode_encodeString(). + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); + +/** + * Micro QR Code version of QRcode_encodeString8bit(). + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level); + +/** + * Encode byte stream (may include '\0') in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param size size of the input data. + * @param data input data. + * @param version version of the symbol. If 0, the library chooses the minimum + * version for the given input data. + * @param level error correction level. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw ERANGE input data is too large. + */ +extern QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level); + +/** + * Micro QR Code version of QRcode_encodeData(). + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level); + +/** + * Free the instance of QRcode class. + * @param qrcode an instance of QRcode class. + */ +extern void QRcode_free(QRcode *qrcode); + +/** + * Create structured symbols from the input data. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param s + * @return a singly-linked list of QRcode. + */ +extern QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s); + +/** + * Create structured symbols from the string. The library automatically parses + * the input string and encodes in a QR Code symbol. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param string input string. It must be NUL terminated. + * @param version version of the symbol. + * @param level error correction level. + * @param hint tell the library how non-alphanumerical characters should be + * encoded. If QR_MODE_KANJI is given, kanji characters will be + * encoded as Shif-JIS characters. If QR_MODE_8 is given, all of + * non-alphanumerical characters will be encoded as is. If you want + * to embed UTF-8 string, choose this. + * @param casesensitive case-sensitive(1) or not(0). + * @return a singly-linked list of QRcode. On error, NULL is returned, and + * errno is set to indicate the error. See Exceptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); + +/** + * Same to QRcode_encodeStringStructured(), but encode whole data in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level); + +/** + * Create structured symbols from byte stream (may include '\0'). Wholde data + * are encoded in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param size size of the input data. + * @param data input dat. + * @param version version of the symbol. + * @param level error correction level. + * @return a singly-linked list of QRcode. On error, NULL is returned, and + * errno is set to indicate the error. See Exceptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level); + +/** + * Return the number of symbols included in a QRcode_List. + * @param qrlist a head entry of a QRcode_List. + * @return number of symbols in the list. + */ +extern int QRcode_List_size(QRcode_List *qrlist); + +/** + * Free the QRcode_List. + * @param qrlist a head entry of a QRcode_List. + */ +extern void QRcode_List_free(QRcode_List *qrlist); + + +/****************************************************************************** + * System utilities + *****************************************************************************/ + +/** + * Return a string that identifies the library version. + * @param major_version + * @param minor_version + * @param micro_version + */ +extern void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version); + +/** + * Return a string that identifies the library version. + * @return a string identifies the library version. The string is held by the + * library. Do NOT free it. + */ +extern char *QRcode_APIVersionString(void); + +/** + * Clear all caches. This is only for debug purpose. If you are attacking a + * complicated memory leak bug, try this to reduce the reachable blocks record. + */ +extern void QRcode_clearCache(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __QRENCODE_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/qrencode_inner.h b/src/add-ons/kernel/debugger/qrencode/qrencode_inner.h new file mode 100644 index 0000000000..3c40d0622a --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrencode_inner.h @@ -0,0 +1,88 @@ +/** + * qrencode - QR Code encoder + * + * Header for test use + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QRENCODE_INNER_H__ +#define __QRENCODE_INNER_H__ + +/** + * This header file includes definitions for test use. + */ + +/****************************************************************************** + * Raw code + *****************************************************************************/ + +typedef struct { + int dataLength; + unsigned char *data; + int eccLength; + unsigned char *ecc; +} RSblock; + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + int b1; + int blocks; + RSblock *rsblock; + int count; +} QRRawCode; + +extern QRRawCode *QRraw_new(QRinput *input); +extern unsigned char QRraw_getCode(QRRawCode *raw); +extern void QRraw_free(QRRawCode *raw); + +/****************************************************************************** + * Raw code for Micro QR Code + *****************************************************************************/ + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + RSblock *rsblock; + int oddbits; + int count; +} MQRRawCode; + +extern MQRRawCode *MQRraw_new(QRinput *input); +extern unsigned char MQRraw_getCode(MQRRawCode *raw); +extern void MQRraw_free(MQRRawCode *raw); + +/****************************************************************************** + * Frame filling + *****************************************************************************/ +extern unsigned char *FrameFiller_test(int version); +extern unsigned char *FrameFiller_testMQR(int version); + +/****************************************************************************** + * QR-code encoding + *****************************************************************************/ +extern QRcode *QRcode_encodeMask(QRinput *input, int mask); +extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask); +extern QRcode *QRcode_new(int version, int width, unsigned char *data); + +#endif /* __QRENCODE_INNER_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/qrinput.c b/src/add-ons/kernel/debugger/qrencode/qrinput.c new file mode 100644 index 0000000000..5dcacf8aa2 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrinput.c @@ -0,0 +1,1724 @@ +/* + * qrencode - QR Code encoder + * + * Input data chunk class + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "qrspec.h" +#include "mqrspec.h" +#include "bitstream.h" +#include "qrinput.h" + +/****************************************************************************** + * Utilities + *****************************************************************************/ +int QRinput_isSplittableMode(QRencodeMode mode) +{ + return (mode >= QR_MODE_NUM && mode <= QR_MODE_KANJI); +} + +/****************************************************************************** + * Entry of input data + *****************************************************************************/ + +static QRinput_List *QRinput_List_newEntry(QRencodeMode mode, int size, const unsigned char *data) +{ + QRinput_List *entry; + + if(QRinput_check(mode, size, data)) { + errno = EINVAL; + return NULL; + } + + entry = (QRinput_List *)malloc(sizeof(QRinput_List)); + if(entry == NULL) return NULL; + + entry->mode = mode; + entry->size = size; + if(size > 0) { + entry->data = (unsigned char *)malloc(size); + if(entry->data == NULL) { + free(entry); + return NULL; + } + memcpy(entry->data, data, size); + } + entry->bstream = NULL; + entry->next = NULL; + + return entry; +} + +static void QRinput_List_freeEntry(QRinput_List *entry) +{ + if(entry != NULL) { + free(entry->data); + BitStream_free(entry->bstream); + free(entry); + } +} + +static QRinput_List *QRinput_List_dup(QRinput_List *entry) +{ + QRinput_List *n; + + n = (QRinput_List *)malloc(sizeof(QRinput_List)); + if(n == NULL) return NULL; + + n->mode = entry->mode; + n->size = entry->size; + n->data = (unsigned char *)malloc(n->size); + if(n->data == NULL) { + free(n); + return NULL; + } + memcpy(n->data, entry->data, entry->size); + n->bstream = NULL; + n->next = NULL; + + return n; +} + +/****************************************************************************** + * Input Data + *****************************************************************************/ + +QRinput *QRinput_new(void) +{ + return QRinput_new2(0, QR_ECLEVEL_L); +} + +QRinput *QRinput_new2(int version, QRecLevel level) +{ + QRinput *input; + + if(version < 0 || version > QRSPEC_VERSION_MAX || level > QR_ECLEVEL_H) { + errno = EINVAL; + return NULL; + } + + input = (QRinput *)malloc(sizeof(QRinput)); + if(input == NULL) return NULL; + + input->head = NULL; + input->tail = NULL; + input->version = version; + input->level = level; + input->mqr = 0; + input->fnc1 = 0; + + return input; +} + +QRinput *QRinput_newMQR(int version, QRecLevel level) +{ + QRinput *input; + + if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID; + if((MQRspec_getECCLength(version, level) == 0)) goto INVALID; + + input = QRinput_new2(version, level); + if(input == NULL) return NULL; + + input->mqr = 1; + + return input; + +INVALID: + errno = EINVAL; + return NULL; +} + +int QRinput_getVersion(QRinput *input) +{ + return input->version; +} + +int QRinput_setVersion(QRinput *input, int version) +{ + if(input->mqr || version < 0 || version > QRSPEC_VERSION_MAX) { + errno = EINVAL; + return -1; + } + + input->version = version; + + return 0; +} + +QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input) +{ + return input->level; +} + +int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level) +{ + if(input->mqr || level > QR_ECLEVEL_H) { + errno = EINVAL; + return -1; + } + + input->level = level; + + return 0; +} + +int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level) +{ + if(input->mqr) { + if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID; + if((MQRspec_getECCLength(version, level) == 0)) goto INVALID; + } else { + if(version < 0 || version > QRSPEC_VERSION_MAX) goto INVALID; + if(level > QR_ECLEVEL_H) goto INVALID; + } + + input->version = version; + input->level = level; + + return 0; + +INVALID: + errno = EINVAL; + return -1; +} + +static void QRinput_appendEntry(QRinput *input, QRinput_List *entry) +{ + if(input->tail == NULL) { + input->head = entry; + input->tail = entry; + } else { + input->tail->next = entry; + input->tail = entry; + } + entry->next = NULL; +} + +int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data) +{ + QRinput_List *entry; + + entry = QRinput_List_newEntry(mode, size, data); + if(entry == NULL) { + return -1; + } + + QRinput_appendEntry(input, entry); + + return 0; +} + +/** + * Insert a structured-append header to the head of the input data. + * @param input input data. + * @param size number of structured symbols. + * @param index index number of the symbol. (1 <= index <= size) + * @param parity parity among input data. (NOTE: each symbol of a set of structured symbols has the same parity data) + * @retval 0 success. + * @retval -1 error occurred and errno is set to indeicate the error. See Execptions for the details. + * @throw EINVAL invalid parameter. + * @throw ENOMEM unable to allocate memory. + */ +__STATIC int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity) +{ + QRinput_List *entry; + unsigned char buf[3]; + + if(size > MAX_STRUCTURED_SYMBOLS) { + errno = EINVAL; + return -1; + } + if(index <= 0 || index > MAX_STRUCTURED_SYMBOLS) { + errno = EINVAL; + return -1; + } + + buf[0] = (unsigned char)size; + buf[1] = (unsigned char)index; + buf[2] = parity; + entry = QRinput_List_newEntry(QR_MODE_STRUCTURE, 3, buf); + if(entry == NULL) { + return -1; + } + + entry->next = input->head; + input->head = entry; + + return 0; +} + +int QRinput_appendECIheader(QRinput *input, unsigned int ecinum) +{ + unsigned char data[4]; + + if(ecinum > 999999) { + errno = EINVAL; + return -1; + } + + /* We manually create byte array of ecinum because + (unsigned char *)&ecinum may cause bus error on some architectures, */ + data[0] = ecinum & 0xff; + data[1] = (ecinum >> 8) & 0xff; + data[2] = (ecinum >> 16) & 0xff; + data[3] = (ecinum >> 24) & 0xff; + return QRinput_append(input, QR_MODE_ECI, 4, data); +} + +void QRinput_free(QRinput *input) +{ + QRinput_List *list, *next; + + if(input != NULL) { + list = input->head; + while(list != NULL) { + next = list->next; + QRinput_List_freeEntry(list); + list = next; + } + free(input); + } +} + +static unsigned char QRinput_calcParity(QRinput *input) +{ + unsigned char parity = 0; + QRinput_List *list; + int i; + + list = input->head; + while(list != NULL) { + if(list->mode != QR_MODE_STRUCTURE) { + for(i=list->size-1; i>=0; i--) { + parity ^= list->data[i]; + } + } + list = list->next; + } + + return parity; +} + +QRinput *QRinput_dup(QRinput *input) +{ + QRinput *n; + QRinput_List *list, *e; + + if(input->mqr) { + n = QRinput_newMQR(input->version, input->level); + } else { + n = QRinput_new2(input->version, input->level); + } + if(n == NULL) return NULL; + + list = input->head; + while(list != NULL) { + e = QRinput_List_dup(list); + if(e == NULL) { + QRinput_free(n); + return NULL; + } + QRinput_appendEntry(n, e); + list = list->next; + } + + return n; +} + +/****************************************************************************** + * Numeric data + *****************************************************************************/ + +/** + * Check the input data. + * @param size + * @param data + * @return result + */ +static int QRinput_checkModeNum(int size, const char *data) +{ + int i; + + for(i=0; i '9') + return -1; + } + + return 0; +} + +/** + * Estimates the length of the encoded bit stream of numeric data. + * @param size + * @return number of bits + */ +int QRinput_estimateBitsModeNum(int size) +{ + int w; + int bits; + + w = size / 3; + bits = w * 10; + switch(size - w * 3) { + case 1: + bits += 4; + break; + case 2: + bits += 7; + break; + default: + break; + } + + return bits; +} + +/** + * Convert the number data to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_encodeModeNum(QRinput_List *entry, int version, int mqr) +{ + int words, i, ret; + unsigned int val; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version > 1) { + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_NUM); + if(ret < 0) goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_NUM, version), entry->size); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_NUM); + if(ret < 0) goto ABORT; + + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), entry->size); + if(ret < 0) goto ABORT; + } + + words = entry->size / 3; + for(i=0; idata[i*3 ] - '0') * 100; + val += (entry->data[i*3+1] - '0') * 10; + val += (entry->data[i*3+2] - '0'); + + ret = BitStream_appendNum(entry->bstream, 10, val); + if(ret < 0) goto ABORT; + } + + if(entry->size - words * 3 == 1) { + val = entry->data[words*3] - '0'; + ret = BitStream_appendNum(entry->bstream, 4, val); + if(ret < 0) goto ABORT; + } else if(entry->size - words * 3 == 2) { + val = (entry->data[words*3 ] - '0') * 10; + val += (entry->data[words*3+1] - '0'); + BitStream_appendNum(entry->bstream, 7, val); + if(ret < 0) goto ABORT; + } + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * Alphabet-numeric data + *****************************************************************************/ + +const signed char QRinput_anTable[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/** + * Check the input data. + * @param size + * @param data + * @return result + */ +static int QRinput_checkModeAn(int size, const char *data) +{ + int i; + + for(i=0; ibstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version < 2) { + errno = EINVAL; + goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_AN); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_AN, version), entry->size); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_AN); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_AN, version), entry->size); + if(ret < 0) goto ABORT; + } + + words = entry->size / 2; + for(i=0; idata[i*2 ]) * 45; + val += (unsigned int)QRinput_lookAnTable(entry->data[i*2+1]); + + ret = BitStream_appendNum(entry->bstream, 11, val); + if(ret < 0) goto ABORT; + } + + if(entry->size & 1) { + val = (unsigned int)QRinput_lookAnTable(entry->data[words * 2]); + + ret = BitStream_appendNum(entry->bstream, 6, val); + if(ret < 0) goto ABORT; + } + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * 8 bit data + *****************************************************************************/ + +/** + * Estimates the length of the encoded bit stream of 8 bit data. + * @param size + * @return number of bits + */ +int QRinput_estimateBitsMode8(int size) +{ + return size * 8; +} + +/** + * Convert the 8bits data to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_encodeMode8(QRinput_List *entry, int version, int mqr) +{ + int ret; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version < 3) { + errno = EINVAL; + goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_8); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_8, version), entry->size); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_8); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_8, version), entry->size); + if(ret < 0) goto ABORT; + } + + ret = BitStream_appendBytes(entry->bstream, entry->size, entry->data); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + + +/****************************************************************************** + * Kanji data + *****************************************************************************/ + +/** + * Estimates the length of the encoded bit stream of kanji data. + * @param size + * @return number of bits + */ +int QRinput_estimateBitsModeKanji(int size) +{ + return (size / 2) * 13; +} + +/** + * Check the input data. + * @param size + * @param data + * @return result + */ +static int QRinput_checkModeKanji(int size, const unsigned char *data) +{ + int i; + unsigned int val; + + if(size & 1) + return -1; + + for(i=0; i 0x9ffc && val < 0xe040) || val > 0xebbf) { + return -1; + } + } + + return 0; +} + +/** + * Convert the kanji data to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL invalid version. + */ +static int QRinput_encodeModeKanji(QRinput_List *entry, int version, int mqr) +{ + int ret, i; + unsigned int val, h; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version < 2) { + errno = EINVAL; + goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_KANJI); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_KANJI); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2); + if(ret < 0) goto ABORT; + } + + for(i=0; isize; i+=2) { + val = ((unsigned int)entry->data[i] << 8) | entry->data[i+1]; + if(val <= 0x9ffc) { + val -= 0x8140; + } else { + val -= 0xc140; + } + h = (val >> 8) * 0xc0; + val = (val & 0xff) + h; + + ret = BitStream_appendNum(entry->bstream, 13, val); + if(ret < 0) goto ABORT; + } + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * Structured Symbol + *****************************************************************************/ + +/** + * Convert a structure symbol code to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL invalid entry. + */ +static int QRinput_encodeModeStructure(QRinput_List *entry, int mqr) +{ + int ret; + + if(mqr) { + errno = EINVAL; + return -1; + } + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_STRUCTURE); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, 4, entry->data[1] - 1); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, 4, entry->data[0] - 1); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, 8, entry->data[2]); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * FNC1 + *****************************************************************************/ + +static int QRinput_checkModeFNC1Second(int size, const unsigned char *data) +{ + if(size != 1) return -1; + + return 0; +} + +static int QRinput_encodeModeFNC1Second(QRinput_List *entry, int version) +{ + int ret; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_FNC1SECOND); + if(ret < 0) goto ABORT; + + ret = BitStream_appendBytes(entry->bstream, 1, entry->data); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * ECI header + *****************************************************************************/ +static unsigned int QRinput_decodeECIfromByteArray(unsigned char *data) +{ + int i; + unsigned int ecinum; + + ecinum = 0; + for(i=0; i<4; i++) { + ecinum = ecinum << 8; + ecinum |= data[3-i]; + } + + return ecinum; +} + +int QRinput_estimateBitsModeECI(unsigned char *data) +{ + unsigned int ecinum; + + ecinum = QRinput_decodeECIfromByteArray(data);; + + /* See Table 4 of JISX 0510:2004 pp.17. */ + if(ecinum < 128) { + return MODE_INDICATOR_SIZE + 8; + } else if(ecinum < 16384) { + return MODE_INDICATOR_SIZE + 16; + } else { + return MODE_INDICATOR_SIZE + 24; + } +} + +static int QRinput_encodeModeECI(QRinput_List *entry, int version) +{ + int ret, words; + unsigned int ecinum, code; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + ecinum = QRinput_decodeECIfromByteArray(entry->data);; + + /* See Table 4 of JISX 0510:2004 pp.17. */ + if(ecinum < 128) { + words = 1; + code = ecinum; + } else if(ecinum < 16384) { + words = 2; + code = 0x8000 + ecinum; + } else { + words = 3; + code = 0xc0000 + ecinum; + } + + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_ECI); + if(ret < 0) goto ABORT; + + ret = BitStream_appendNum(entry->bstream, words * 8, code); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * Validation + *****************************************************************************/ + +int QRinput_check(QRencodeMode mode, int size, const unsigned char *data) +{ + if((mode == QR_MODE_FNC1FIRST && size < 0) || size <= 0) return -1; + + switch(mode) { + case QR_MODE_NUM: + return QRinput_checkModeNum(size, (const char *)data); + case QR_MODE_AN: + return QRinput_checkModeAn(size, (const char *)data); + case QR_MODE_KANJI: + return QRinput_checkModeKanji(size, data); + case QR_MODE_8: + return 0; + case QR_MODE_STRUCTURE: + return 0; + case QR_MODE_ECI: + return 0; + case QR_MODE_FNC1FIRST: + return 0; + case QR_MODE_FNC1SECOND: + return QRinput_checkModeFNC1Second(size, data); + case QR_MODE_NUL: + break; + } + + return -1; +} + +/****************************************************************************** + * Estimation of the bit length + *****************************************************************************/ + +/** + * Estimates the length of the encoded bit stream on the current version. + * @param entry + * @param version version of the symbol + * @param mqr + * @return number of bits + */ +static int QRinput_estimateBitStreamSizeOfEntry(QRinput_List *entry, int version, int mqr) +{ + int bits = 0; + int l, m; + int num; + + if(version == 0) version = 1; + + switch(entry->mode) { + case QR_MODE_NUM: + bits = QRinput_estimateBitsModeNum(entry->size); + break; + case QR_MODE_AN: + bits = QRinput_estimateBitsModeAn(entry->size); + break; + case QR_MODE_8: + bits = QRinput_estimateBitsMode8(entry->size); + break; + case QR_MODE_KANJI: + bits = QRinput_estimateBitsModeKanji(entry->size); + break; + case QR_MODE_STRUCTURE: + return STRUCTURE_HEADER_SIZE; + case QR_MODE_ECI: + bits = QRinput_estimateBitsModeECI(entry->data); + break; + case QR_MODE_FNC1FIRST: + return MODE_INDICATOR_SIZE; + break; + case QR_MODE_FNC1SECOND: + return MODE_INDICATOR_SIZE + 8; + default: + return 0; + } + + if(mqr) { + l = QRspec_lengthIndicator(entry->mode, version); + m = version - 1; + bits += l + m; + } else { + l = QRspec_lengthIndicator(entry->mode, version); + m = 1 << l; + num = (entry->size + m - 1) / m; + + bits += num * (MODE_INDICATOR_SIZE + l); + } + + return bits; +} + +/** + * Estimates the length of the encoded bit stream of the data. + * @param input input data + * @param version version of the symbol + * @return number of bits + */ +__STATIC int QRinput_estimateBitStreamSize(QRinput *input, int version) +{ + QRinput_List *list; + int bits = 0; + + list = input->head; + while(list != NULL) { + bits += QRinput_estimateBitStreamSizeOfEntry(list, version, input->mqr); + list = list->next; + } + + return bits; +} + +/** + * Estimates the required version number of the symbol. + * @param input input data + * @return required version number + */ +static int QRinput_estimateVersion(QRinput *input) +{ + int bits; + int version, prev; + + version = 0; + do { + prev = version; + bits = QRinput_estimateBitStreamSize(input, prev); + version = QRspec_getMinimumVersion((bits + 7) / 8, input->level); + if (version < 0) { + return -1; + } + } while (version > prev); + + return version; +} + +/** + * Returns required length in bytes for specified mode, version and bits. + * @param mode + * @param version + * @param bits + * @return required length of code words in bytes. + */ +__STATIC int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits) +{ + int payload, size, chunks, remain, maxsize; + + payload = bits - 4 - QRspec_lengthIndicator(mode, version); + switch(mode) { + case QR_MODE_NUM: + chunks = payload / 10; + remain = payload - chunks * 10; + size = chunks * 3; + if(remain >= 7) { + size += 2; + } else if(remain >= 4) { + size += 1; + } + break; + case QR_MODE_AN: + chunks = payload / 11; + remain = payload - chunks * 11; + size = chunks * 2; + if(remain >= 6) size++; + break; + case QR_MODE_8: + size = payload / 8; + break; + case QR_MODE_KANJI: + size = (payload / 13) * 2; + break; + case QR_MODE_STRUCTURE: + size = payload / 8; + break; + default: + size = 0; + break; + } + maxsize = QRspec_maximumWords(mode, version); + if(size < 0) size = 0; + if(maxsize > 0 && size > maxsize) size = maxsize; + + return size; +} + +/****************************************************************************** + * Data conversion + *****************************************************************************/ + +/** + * Convert the input data in the data chunk to a bit stream. + * @param entry + * @return number of bits (>0) or -1 for failure. + */ +static int QRinput_encodeBitStream(QRinput_List *entry, int version, int mqr) +{ + int words, ret; + QRinput_List *st1 = NULL, *st2 = NULL; + + if(entry->bstream != NULL) { + BitStream_free(entry->bstream); + entry->bstream = NULL; + } + + words = QRspec_maximumWords(entry->mode, version); + if(words != 0 && entry->size > words) { + st1 = QRinput_List_newEntry(entry->mode, words, entry->data); + if(st1 == NULL) goto ABORT; + st2 = QRinput_List_newEntry(entry->mode, entry->size - words, &entry->data[words]); + if(st2 == NULL) goto ABORT; + + ret = QRinput_encodeBitStream(st1, version, mqr); + if(ret < 0) goto ABORT; + ret = QRinput_encodeBitStream(st2, version, mqr); + if(ret < 0) goto ABORT; + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) goto ABORT; + ret = BitStream_append(entry->bstream, st1->bstream); + if(ret < 0) goto ABORT; + ret = BitStream_append(entry->bstream, st2->bstream); + if(ret < 0) goto ABORT; + QRinput_List_freeEntry(st1); + QRinput_List_freeEntry(st2); + } else { + ret = 0; + switch(entry->mode) { + case QR_MODE_NUM: + ret = QRinput_encodeModeNum(entry, version, mqr); + break; + case QR_MODE_AN: + ret = QRinput_encodeModeAn(entry, version, mqr); + break; + case QR_MODE_8: + ret = QRinput_encodeMode8(entry, version, mqr); + break; + case QR_MODE_KANJI: + ret = QRinput_encodeModeKanji(entry, version, mqr); + break; + case QR_MODE_STRUCTURE: + ret = QRinput_encodeModeStructure(entry, mqr); + break; + case QR_MODE_ECI: + ret = QRinput_encodeModeECI(entry, version); + break; + case QR_MODE_FNC1SECOND: + ret = QRinput_encodeModeFNC1Second(entry, version); + default: + break; + } + if(ret < 0) return -1; + } + + return BitStream_size(entry->bstream); +ABORT: + QRinput_List_freeEntry(st1); + QRinput_List_freeEntry(st2); + return -1; +} + +/** + * Convert the input data to a bit stream. + * @param input input data. + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_createBitStream(QRinput *input) +{ + QRinput_List *list; + int bits, total = 0; + + list = input->head; + while(list != NULL) { + bits = QRinput_encodeBitStream(list, input->version, input->mqr); + if(bits < 0) return -1; + total += bits; + list = list->next; + } + + return total; +} + +/** + * Convert the input data to a bit stream. + * When the version number is given and that is not sufficient, it is increased + * automatically. + * @param input input data. + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw ERANGE input is too large. + */ +static int QRinput_convertData(QRinput *input) +{ + int bits; + int ver; + + ver = QRinput_estimateVersion(input); + if(ver > QRinput_getVersion(input)) { + QRinput_setVersion(input, ver); + } + + for(;;) { + bits = QRinput_createBitStream(input); + if(bits < 0) return -1; + ver = QRspec_getMinimumVersion((bits + 7) / 8, input->level); + if(ver < 0) { + errno = ERANGE; + return -1; + } else if(ver > QRinput_getVersion(input)) { + QRinput_setVersion(input, ver); + } else { + break; + } + } + + return 0; +} + +/** + * Append padding bits for the input data. + * @param bstream Bitstream to be appended. + * @param input input data. + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ERANGE input data is too large. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_appendPaddingBit(BitStream *bstream, QRinput *input) +{ + int bits, maxbits, words, maxwords, i, ret; + BitStream *padding = NULL; + unsigned char *padbuf; + int padlen; + + bits = BitStream_size(bstream); + maxwords = QRspec_getDataLength(input->version, input->level); + maxbits = maxwords * 8; + + if(maxbits < bits) { + errno = ERANGE; + return -1; + } + if(maxbits == bits) { + return 0; + } + + if(maxbits - bits <= 4) { + ret = BitStream_appendNum(bstream, maxbits - bits, 0); + goto DONE; + } + + words = (bits + 4 + 7) / 8; + + padding = BitStream_new(); + if(padding == NULL) return -1; + ret = BitStream_appendNum(padding, words * 8 - bits, 0); + if(ret < 0) goto DONE; + + padlen = maxwords - words; + if(padlen > 0) { + padbuf = (unsigned char *)malloc(padlen); + if(padbuf == NULL) { + ret = -1; + goto DONE; + } + for(i=0; iversion, input->level); + maxwords = maxbits / 8; + + if(maxbits < bits) { + errno = ERANGE; + return -1; + } + if(maxbits == bits) { + return 0; + } + + termbits = input->version * 2 + 1; + + if(maxbits - bits <= termbits) { + ret = BitStream_appendNum(bstream, maxbits - bits, 0); + goto DONE; + } + + bits += termbits; + + words = (bits + 7) / 8; + if(maxbits - words * 8 > 0) { + termbits += words * 8 - bits; + if(words == maxwords) termbits += maxbits - words * 8; + } else { + termbits += words * 8 - bits; + } + padding = BitStream_new(); + if(padding == NULL) return -1; + ret = BitStream_appendNum(padding, termbits, 0); + if(ret < 0) goto DONE; + + padlen = maxwords - words; + if(padlen > 0) { + padbuf = (unsigned char *)malloc(padlen); + if(padbuf == NULL) { + ret = -1; + goto DONE; + } + for(i=0; i 0) { + ret = BitStream_appendNum(padding, termbits, 0); + if(ret < 0) goto DONE; + } + } + + ret = BitStream_append(bstream, padding); + +DONE: + BitStream_free(padding); + return ret; +} + +static int QRinput_insertFNC1Header(QRinput *input) +{ + QRinput_List *entry = NULL; + + if(input->fnc1 == 1) { + entry = QRinput_List_newEntry(QR_MODE_FNC1FIRST, 0, NULL); + } else if(input->fnc1 == 2) { + entry = QRinput_List_newEntry(QR_MODE_FNC1SECOND, 1, &(input->appid)); + } + if(entry == NULL) { + return -1; + } + + if(input->head->mode != QR_MODE_STRUCTURE || input->head->mode != QR_MODE_ECI) { + entry->next = input->head; + input->head = entry; + } else { + entry->next = input->head->next; + input->head->next = entry; + } + + return 0; +} + +/** + * Merge all bit streams in the input data. + * @param input input data. + * @return merged bit stream + */ + +__STATIC BitStream *QRinput_mergeBitStream(QRinput *input) +{ + BitStream *bstream; + QRinput_List *list; + int ret; + + if(input->mqr) { + if(QRinput_createBitStream(input) < 0) { + return NULL; + } + } else { + if(input->fnc1) { + if(QRinput_insertFNC1Header(input) < 0) { + return NULL; + } + } + if(QRinput_convertData(input) < 0) { + return NULL; + } + } + + bstream = BitStream_new(); + if(bstream == NULL) return NULL; + + list = input->head; + while(list != NULL) { + ret = BitStream_append(bstream, list->bstream); + if(ret < 0) { + BitStream_free(bstream); + return NULL; + } + list = list->next; + } + + return bstream; +} + +/** + * Merge all bit streams in the input data and append padding bits + * @param input input data. + * @return padded merged bit stream + */ + +__STATIC BitStream *QRinput_getBitStream(QRinput *input) +{ + BitStream *bstream; + int ret; + + bstream = QRinput_mergeBitStream(input); + if(bstream == NULL) { + return NULL; + } + if(input->mqr) { + ret = QRinput_appendPaddingBitMQR(bstream, input); + } else { + ret = QRinput_appendPaddingBit(bstream, input); + } + if(ret < 0) { + BitStream_free(bstream); + return NULL; + } + + return bstream; +} + +/** + * Pack all bit streams padding bits into a byte array. + * @param input input data. + * @return padded merged byte stream + */ + +unsigned char *QRinput_getByteStream(QRinput *input) +{ + BitStream *bstream; + unsigned char *array; + + bstream = QRinput_getBitStream(input); + if(bstream == NULL) { + return NULL; + } + array = BitStream_toByte(bstream); + BitStream_free(bstream); + + return array; +} + +/****************************************************************************** + * Structured input data + *****************************************************************************/ + +static QRinput_InputList *QRinput_InputList_newEntry(QRinput *input) +{ + QRinput_InputList *entry; + + entry = (QRinput_InputList *)malloc(sizeof(QRinput_InputList)); + if(entry == NULL) return NULL; + + entry->input = input; + entry->next = NULL; + + return entry; +} + +static void QRinput_InputList_freeEntry(QRinput_InputList *entry) +{ + if(entry != NULL) { + QRinput_free(entry->input); + free(entry); + } +} + +QRinput_Struct *QRinput_Struct_new(void) +{ + QRinput_Struct *s; + + s = (QRinput_Struct *)malloc(sizeof(QRinput_Struct)); + if(s == NULL) return NULL; + + s->size = 0; + s->parity = -1; + s->head = NULL; + s->tail = NULL; + + return s; +} + +void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity) +{ + s->parity = (int)parity; +} + +int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input) +{ + QRinput_InputList *e; + + if(input->mqr) { + errno = EINVAL; + return -1; + } + + e = QRinput_InputList_newEntry(input); + if(e == NULL) return -1; + + s->size++; + if(s->tail == NULL) { + s->head = e; + s->tail = e; + } else { + s->tail->next = e; + s->tail = e; + } + + return s->size; +} + +void QRinput_Struct_free(QRinput_Struct *s) +{ + QRinput_InputList *list, *next; + + if(s != NULL) { + list = s->head; + while(list != NULL) { + next = list->next; + QRinput_InputList_freeEntry(list); + list = next; + } + free(s); + } +} + +static unsigned char QRinput_Struct_calcParity(QRinput_Struct *s) +{ + QRinput_InputList *list; + unsigned char parity = 0; + + list = s->head; + while(list != NULL) { + parity ^= QRinput_calcParity(list->input); + list = list->next; + } + + QRinput_Struct_setParity(s, parity); + + return parity; +} + +static int QRinput_List_shrinkEntry(QRinput_List *entry, int bytes) +{ + unsigned char *data; + + data = (unsigned char *)malloc(bytes); + if(data == NULL) return -1; + + memcpy(data, entry->data, bytes); + free(entry->data); + entry->data = data; + entry->size = bytes; + + return 0; +} + +__STATIC int QRinput_splitEntry(QRinput_List *entry, int bytes) +{ + QRinput_List *e; + int ret; + + e = QRinput_List_newEntry(entry->mode, entry->size - bytes, entry->data + bytes); + if(e == NULL) { + return -1; + } + + ret = QRinput_List_shrinkEntry(entry, bytes); + if(ret < 0) { + QRinput_List_freeEntry(e); + return -1; + } + + e->next = entry->next; + entry->next = e; + + return 0; +} + +QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input) +{ + QRinput *p; + QRinput_Struct *s; + int bits, maxbits, nextbits, bytes, ret; + QRinput_List *list, *next, *prev; + + if(input->mqr) { + errno = EINVAL; + return NULL; + } + + s = QRinput_Struct_new(); + if(s == NULL) return NULL; + + input = QRinput_dup(input); + if(input == NULL) { + QRinput_Struct_free(s); + return NULL; + } + + QRinput_Struct_setParity(s, QRinput_calcParity(input)); + maxbits = QRspec_getDataLength(input->version, input->level) * 8 - STRUCTURE_HEADER_SIZE; + + if(maxbits <= 0) { + QRinput_Struct_free(s); + QRinput_free(input); + return NULL; + } + + bits = 0; + list = input->head; + prev = NULL; + while(list != NULL) { + nextbits = QRinput_estimateBitStreamSizeOfEntry(list, input->version, input->mqr); + if(bits + nextbits <= maxbits) { + ret = QRinput_encodeBitStream(list, input->version, input->mqr); + if(ret < 0) goto ABORT; + bits += ret; + prev = list; + list = list->next; + } else { + bytes = QRinput_lengthOfCode(list->mode, input->version, maxbits - bits); + if(bytes > 0) { + /* Splits this entry into 2 entries. */ + ret = QRinput_splitEntry(list, bytes); + if(ret < 0) goto ABORT; + /* First half is the tail of the current input. */ + next = list->next; + list->next = NULL; + /* Second half is the head of the next input, p.*/ + p = QRinput_new2(input->version, input->level); + if(p == NULL) goto ABORT; + p->head = next; + /* Renew QRinput.tail. */ + p->tail = input->tail; + input->tail = list; + /* Point to the next entry. */ + prev = list; + list = next; + } else { + /* Current entry will go to the next input. */ + prev->next = NULL; + p = QRinput_new2(input->version, input->level); + if(p == NULL) goto ABORT; + p->head = list; + p->tail = input->tail; + input->tail = prev; + } + ret = QRinput_Struct_appendInput(s, input); + if(ret < 0) goto ABORT; + input = p; + bits = 0; + } + } + QRinput_Struct_appendInput(s, input); + if(s->size > MAX_STRUCTURED_SYMBOLS) { + QRinput_Struct_free(s); + errno = ERANGE; + return NULL; + } + ret = QRinput_Struct_insertStructuredAppendHeaders(s); + if(ret < 0) { + QRinput_Struct_free(s); + return NULL; + } + + return s; + +ABORT: + QRinput_free(input); + QRinput_Struct_free(s); + return NULL; +} + +int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s) +{ + int num, i; + QRinput_InputList *list; + + if(s->parity < 0) { + QRinput_Struct_calcParity(s); + } + num = 0; + list = s->head; + while(list != NULL) { + num++; + list = list->next; + } + i = 1; + list = s->head; + while(list != NULL) { + if(QRinput_insertStructuredAppendHeader(list->input, num, i, s->parity)) + return -1; + i++; + list = list->next; + } + + return 0; +} + +/****************************************************************************** + * Extended encoding mode (FNC1 and ECI) + *****************************************************************************/ + +int QRinput_setFNC1First(QRinput *input) +{ + if(input->mqr) { + errno = EINVAL; + return -1; + } + input->fnc1 = 1; + + return 0; +} + +int QRinput_setFNC1Second(QRinput *input, unsigned char appid) +{ + if(input->mqr) { + errno = EINVAL; + return -1; + } + input->fnc1 = 2; + input->appid = appid; + + return 0; +} diff --git a/src/add-ons/kernel/debugger/qrencode/qrinput.h b/src/add-ons/kernel/debugger/qrencode/qrinput.h new file mode 100644 index 0000000000..9e6bad625d --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrinput.h @@ -0,0 +1,123 @@ +/* + * qrencode - QR Code encoder + * + * Input data chunk class + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QRINPUT_H__ +#define __QRINPUT_H__ + +#include "qrencode.h" +#include "bitstream.h" + +int QRinput_isSplittableMode(QRencodeMode mode); + +/****************************************************************************** + * Entry of input data + *****************************************************************************/ +typedef struct _QRinput_List QRinput_List; + +struct _QRinput_List { + QRencodeMode mode; + int size; ///< Size of data chunk (byte). + unsigned char *data; ///< Data chunk. + BitStream *bstream; + QRinput_List *next; +}; + +/****************************************************************************** + * Input Data + *****************************************************************************/ +struct _QRinput { + int version; + QRecLevel level; + QRinput_List *head; + QRinput_List *tail; + int mqr; + int fnc1; + unsigned char appid; +}; + +/****************************************************************************** + * Structured append input data + *****************************************************************************/ +typedef struct _QRinput_InputList QRinput_InputList; + +struct _QRinput_InputList { + QRinput *input; + QRinput_InputList *next; +}; + +struct _QRinput_Struct { + int size; ///< number of structured symbols + int parity; + QRinput_InputList *head; + QRinput_InputList *tail; +}; + +/** + * Pack all bit streams padding bits into a byte array. + * @param input input data. + * @return padded merged byte stream + */ +extern unsigned char *QRinput_getByteStream(QRinput *input); + + +extern int QRinput_estimateBitsModeNum(int size); +extern int QRinput_estimateBitsModeAn(int size); +extern int QRinput_estimateBitsMode8(int size); +extern int QRinput_estimateBitsModeKanji(int size); + +extern QRinput *QRinput_dup(QRinput *input); + +extern const signed char QRinput_anTable[128]; + +/** + * Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19). + * @param __c__ character + * @return value + */ +#define QRinput_lookAnTable(__c__) \ + ((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__]) + +/** + * Length of a standard mode indicator in bits. + */ + +#define MODE_INDICATOR_SIZE 4 + +/** + * Length of a segment of structured-append header. + */ +#define STRUCTURE_HEADER_SIZE 20 + +/** + * Maximum number of symbols in a set of structured-appended symbols. + */ +#define MAX_STRUCTURED_SYMBOLS 16 + +#ifdef WITH_TESTS +extern BitStream *QRinput_mergeBitStream(QRinput *input); +extern BitStream *QRinput_getBitStream(QRinput *input); +extern int QRinput_estimateBitStreamSize(QRinput *input, int version); +extern int QRinput_splitEntry(QRinput_List *entry, int bytes); +extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits); +extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity); +#endif + +#endif /* __QRINPUT_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/qrspec.c b/src/add-ons/kernel/debugger/qrencode/qrspec.c new file mode 100644 index 0000000000..a42706f4b8 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrspec.c @@ -0,0 +1,562 @@ +/* + * qrencode - QR Code encoder + * + * QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#ifdef HAVE_LIBPTHREAD +#include +#endif + +#include "qrspec.h" +#include "qrinput.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +typedef struct { + int width; //< Edge length of the symbol + int words; //< Data capacity (bytes) + int remainder; //< Remainder bit (bits) + int ec[4]; //< Number of ECC code (bytes) +} QRspec_Capacity; + +/** + * Table of the capacity of symbols + * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004. + */ +static const QRspec_Capacity qrspecCapacity[QRSPEC_VERSION_MAX + 1] = { + { 0, 0, 0, { 0, 0, 0, 0}}, + { 21, 26, 0, { 7, 10, 13, 17}}, // 1 + { 25, 44, 7, { 10, 16, 22, 28}}, + { 29, 70, 7, { 15, 26, 36, 44}}, + { 33, 100, 7, { 20, 36, 52, 64}}, + { 37, 134, 7, { 26, 48, 72, 88}}, // 5 + { 41, 172, 7, { 36, 64, 96, 112}}, + { 45, 196, 0, { 40, 72, 108, 130}}, + { 49, 242, 0, { 48, 88, 132, 156}}, + { 53, 292, 0, { 60, 110, 160, 192}}, + { 57, 346, 0, { 72, 130, 192, 224}}, //10 + { 61, 404, 0, { 80, 150, 224, 264}}, + { 65, 466, 0, { 96, 176, 260, 308}}, + { 69, 532, 0, { 104, 198, 288, 352}}, + { 73, 581, 3, { 120, 216, 320, 384}}, + { 77, 655, 3, { 132, 240, 360, 432}}, //15 + { 81, 733, 3, { 144, 280, 408, 480}}, + { 85, 815, 3, { 168, 308, 448, 532}}, + { 89, 901, 3, { 180, 338, 504, 588}}, + { 93, 991, 3, { 196, 364, 546, 650}}, + { 97, 1085, 3, { 224, 416, 600, 700}}, //20 + {101, 1156, 4, { 224, 442, 644, 750}}, + {105, 1258, 4, { 252, 476, 690, 816}}, + {109, 1364, 4, { 270, 504, 750, 900}}, + {113, 1474, 4, { 300, 560, 810, 960}}, + {117, 1588, 4, { 312, 588, 870, 1050}}, //25 + {121, 1706, 4, { 336, 644, 952, 1110}}, + {125, 1828, 4, { 360, 700, 1020, 1200}}, + {129, 1921, 3, { 390, 728, 1050, 1260}}, + {133, 2051, 3, { 420, 784, 1140, 1350}}, + {137, 2185, 3, { 450, 812, 1200, 1440}}, //30 + {141, 2323, 3, { 480, 868, 1290, 1530}}, + {145, 2465, 3, { 510, 924, 1350, 1620}}, + {149, 2611, 3, { 540, 980, 1440, 1710}}, + {153, 2761, 3, { 570, 1036, 1530, 1800}}, + {157, 2876, 0, { 570, 1064, 1590, 1890}}, //35 + {161, 3034, 0, { 600, 1120, 1680, 1980}}, + {165, 3196, 0, { 630, 1204, 1770, 2100}}, + {169, 3362, 0, { 660, 1260, 1860, 2220}}, + {173, 3532, 0, { 720, 1316, 1950, 2310}}, + {177, 3706, 0, { 750, 1372, 2040, 2430}} //40 +}; + +int QRspec_getDataLength(int version, QRecLevel level) +{ + return qrspecCapacity[version].words - qrspecCapacity[version].ec[level]; +} + +int QRspec_getECCLength(int version, QRecLevel level) +{ + return qrspecCapacity[version].ec[level]; +} + +int QRspec_getMinimumVersion(int size, QRecLevel level) +{ + int i; + int words; + + for(i=1; i<= QRSPEC_VERSION_MAX; i++) { + words = qrspecCapacity[i].words - qrspecCapacity[i].ec[level]; + if(words >= size) return i; + } + + return -1; +} + +int QRspec_getWidth(int version) +{ + return qrspecCapacity[version].width; +} + +int QRspec_getRemainder(int version) +{ + return qrspecCapacity[version].remainder; +} + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +static const int lengthTableBits[4][3] = { + {10, 12, 14}, + { 9, 11, 13}, + { 8, 16, 16}, + { 8, 10, 12} +}; + +int QRspec_lengthIndicator(QRencodeMode mode, int version) +{ + int l; + + if(!QRinput_isSplittableMode(mode)) return 0; + if(version <= 9) { + l = 0; + } else if(version <= 26) { + l = 1; + } else { + l = 2; + } + + return lengthTableBits[mode][l]; +} + +int QRspec_maximumWords(QRencodeMode mode, int version) +{ + int l; + int bits; + int words; + + if(!QRinput_isSplittableMode(mode)) return 0; + if(version <= 9) { + l = 0; + } else if(version <= 26) { + l = 1; + } else { + l = 2; + } + + bits = lengthTableBits[mode][l]; + words = (1 << bits) - 1; + if(mode == QR_MODE_KANJI) { + words *= 2; // the number of bytes is required + } + + return words; +} + +/****************************************************************************** + * Error correction code + *****************************************************************************/ + +/** + * Table of the error correction code (Reed-Solomon block) + * See Table 12-16 (pp.30-36), JIS X0510:2004. + */ +static const int eccTable[QRSPEC_VERSION_MAX+1][4][2] = { + {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}, + {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, // 1 + {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, + {{ 1, 0}, { 1, 0}, { 2, 0}, { 2, 0}}, + {{ 1, 0}, { 2, 0}, { 2, 0}, { 4, 0}}, + {{ 1, 0}, { 2, 0}, { 2, 2}, { 2, 2}}, // 5 + {{ 2, 0}, { 4, 0}, { 4, 0}, { 4, 0}}, + {{ 2, 0}, { 4, 0}, { 2, 4}, { 4, 1}}, + {{ 2, 0}, { 2, 2}, { 4, 2}, { 4, 2}}, + {{ 2, 0}, { 3, 2}, { 4, 4}, { 4, 4}}, + {{ 2, 2}, { 4, 1}, { 6, 2}, { 6, 2}}, //10 + {{ 4, 0}, { 1, 4}, { 4, 4}, { 3, 8}}, + {{ 2, 2}, { 6, 2}, { 4, 6}, { 7, 4}}, + {{ 4, 0}, { 8, 1}, { 8, 4}, {12, 4}}, + {{ 3, 1}, { 4, 5}, {11, 5}, {11, 5}}, + {{ 5, 1}, { 5, 5}, { 5, 7}, {11, 7}}, //15 + {{ 5, 1}, { 7, 3}, {15, 2}, { 3, 13}}, + {{ 1, 5}, {10, 1}, { 1, 15}, { 2, 17}}, + {{ 5, 1}, { 9, 4}, {17, 1}, { 2, 19}}, + {{ 3, 4}, { 3, 11}, {17, 4}, { 9, 16}}, + {{ 3, 5}, { 3, 13}, {15, 5}, {15, 10}}, //20 + {{ 4, 4}, {17, 0}, {17, 6}, {19, 6}}, + {{ 2, 7}, {17, 0}, { 7, 16}, {34, 0}}, + {{ 4, 5}, { 4, 14}, {11, 14}, {16, 14}}, + {{ 6, 4}, { 6, 14}, {11, 16}, {30, 2}}, + {{ 8, 4}, { 8, 13}, { 7, 22}, {22, 13}}, //25 + {{10, 2}, {19, 4}, {28, 6}, {33, 4}}, + {{ 8, 4}, {22, 3}, { 8, 26}, {12, 28}}, + {{ 3, 10}, { 3, 23}, { 4, 31}, {11, 31}}, + {{ 7, 7}, {21, 7}, { 1, 37}, {19, 26}}, + {{ 5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30 + {{13, 3}, { 2, 29}, {42, 1}, {23, 28}}, + {{17, 0}, {10, 23}, {10, 35}, {19, 35}}, + {{17, 1}, {14, 21}, {29, 19}, {11, 46}}, + {{13, 6}, {14, 23}, {44, 7}, {59, 1}}, + {{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35 + {{ 6, 14}, { 6, 34}, {46, 10}, { 2, 64}}, + {{17, 4}, {29, 14}, {49, 10}, {24, 46}}, + {{ 4, 18}, {13, 32}, {48, 14}, {42, 32}}, + {{20, 4}, {40, 7}, {43, 22}, {10, 67}}, + {{19, 6}, {18, 31}, {34, 34}, {20, 61}},//40 +}; + +void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]) +{ + int b1, b2; + int data, ecc; + + b1 = eccTable[version][level][0]; + b2 = eccTable[version][level][1]; + data = QRspec_getDataLength(version, level); + ecc = QRspec_getECCLength(version, level); + + if(b2 == 0) { + spec[0] = b1; + spec[1] = data / b1; + spec[2] = ecc / b1; + spec[3] = spec[4] = 0; + } else { + spec[0] = b1; + spec[1] = data / (b1 + b2); + spec[2] = ecc / (b1 + b2); + spec[3] = b2; + spec[4] = spec[1] + 1; + } +} + +/****************************************************************************** + * Alignment pattern + *****************************************************************************/ + +/** + * Positions of alignment patterns. + * This array includes only the second and the third position of the alignment + * patterns. Rest of them can be calculated from the distance between them. + * + * See Table 1 in Appendix E (pp.71) of JIS X0510:2004. + */ +static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2] = { + { 0, 0}, + { 0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5 + {34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10 + {30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15 + {26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20 + {28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25 + {30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30 + {30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35 + {24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40 +}; + +/** + * Put an alignment marker. + * @param frame + * @param width + * @param ox,oy center coordinate of the pattern + */ +static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy) +{ + static const unsigned char finder[] = { + 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, + 0xa1, 0xa0, 0xa0, 0xa0, 0xa1, + 0xa1, 0xa0, 0xa1, 0xa0, 0xa1, + 0xa1, 0xa0, 0xa0, 0xa0, 0xa1, + 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, + }; + int x, y; + const unsigned char *s; + + frame += (oy - 2) * width + ox - 2; + s = finder; + for(y=0; y<5; y++) { + for(x=0; x<5; x++) { + frame[x] = s[x]; + } + frame += width; + s += 5; + } +} + +static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width) +{ + int d, w, x, y, cx, cy; + + if(version < 2) return; + + d = alignmentPattern[version][1] - alignmentPattern[version][0]; + if(d < 0) { + w = 2; + } else { + w = (width - alignmentPattern[version][0]) / d + 2; + } + + if(w * w - 3 == 1) { + x = alignmentPattern[version][0]; + y = alignmentPattern[version][0]; + QRspec_putAlignmentMarker(frame, width, x, y); + return; + } + + cx = alignmentPattern[version][0]; + for(x=1; x QRSPEC_VERSION_MAX) return 0; + + return versionPattern[version - 7]; +} + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/* See calcFormatInfo in tests/test_qrspec.c */ +static const unsigned int formatInfo[4][8] = { + {0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976}, + {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0}, + {0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed}, + {0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b} +}; + +unsigned int QRspec_getFormatInfo(int mask, QRecLevel level) +{ + if(mask < 0 || mask > 7) return 0; + + return formatInfo[level][mask]; +} + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Cache of initial frames. + */ +/* C99 says that static storage shall be initialized to a null pointer + * by compiler. */ +static unsigned char *frames[QRSPEC_VERSION_MAX + 1]; +#ifdef HAVE_LIBPTHREAD +static pthread_mutex_t frames_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +/** + * Put a finder pattern. + * @param frame + * @param width + * @param ox,oy upper-left coordinate of the pattern + */ +static void putFinderPattern(unsigned char *frame, int width, int ox, int oy) +{ + static const unsigned char finder[] = { + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + }; + int x, y; + const unsigned char *s; + + frame += oy * width + ox; + s = finder; + for(y=0; y<7; y++) { + for(x=0; x<7; x++) { + frame[x] = s[x]; + } + frame += width; + s += 7; + } +} + + +static unsigned char *QRspec_createFrame(int version) +{ + unsigned char *frame, *p, *q; + int width; + int x, y; + unsigned int verinfo, v; + + width = qrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + + memset(frame, 0, width * width); + /* Finder pattern */ + putFinderPattern(frame, width, 0, 0); + putFinderPattern(frame, width, width - 7, 0); + putFinderPattern(frame, width, 0, width - 7); + /* Separator */ + p = frame; + q = frame + width * (width - 7); + for(y=0; y<7; y++) { + p[7] = 0xc0; + p[width - 8] = 0xc0; + q[7] = 0xc0; + p += width; + q += width; + } + memset(frame + width * 7, 0xc0, 8); + memset(frame + width * 8 - 8, 0xc0, 8); + memset(frame + width * (width - 8), 0xc0, 8); + /* Mask format information area */ + memset(frame + width * 8, 0x84, 9); + memset(frame + width * 9 - 8, 0x84, 8); + p = frame + 8; + for(y=0; y<8; y++) { + *p = 0x84; + p += width; + } + p = frame + width * (width - 7) + 8; + for(y=0; y<7; y++) { + *p = 0x84; + p += width; + } + /* Timing pattern */ + p = frame + width * 6 + 8; + q = frame + width * 8 + 6; + for(x=1; x= 7) { + verinfo = QRspec_getVersionPattern(version); + + p = frame + width * (width - 11); + v = verinfo; + for(x=0; x<6; x++) { + for(y=0; y<3; y++) { + p[width * y + x] = 0x88 | (v & 1); + v = v >> 1; + } + } + + p = frame + width - 11; + v = verinfo; + for(y=0; y<6; y++) { + for(x=0; x<3; x++) { + p[x] = 0x88 | (v & 1); + v = v >> 1; + } + p += width; + } + } + /* and a little bit... */ + frame[width * (width - 8) + 8] = 0x81; + + return frame; +} + +unsigned char *QRspec_newFrame(int version) +{ + unsigned char *frame; + int width; + + if(version < 1 || version > QRSPEC_VERSION_MAX) return NULL; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + if(frames[version] == NULL) { + frames[version] = QRspec_createFrame(version); + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif + if(frames[version] == NULL) return NULL; + + width = qrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + memcpy(frame, frames[version], width * width); + + return frame; +} + +void QRspec_clearCache(void) +{ + int i; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + for(i=1; i<=QRSPEC_VERSION_MAX; i++) { + free(frames[i]); + frames[i] = NULL; + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif +} diff --git a/src/add-ons/kernel/debugger/qrencode/qrspec.h b/src/add-ons/kernel/debugger/qrencode/qrspec.h new file mode 100644 index 0000000000..54a3d9f09e --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/qrspec.h @@ -0,0 +1,181 @@ +/* + * qrencode - QR Code encoder + * + * QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QRSPEC_H__ +#define __QRSPEC_H__ + +#include "qrencode.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +/** + * Maximum width of a symbol + */ +#define QRSPEC_WIDTH_MAX 177 + +/** + * Return maximum data code length (bytes) for the version. + * @param version + * @param level + * @return maximum size (bytes) + */ +extern int QRspec_getDataLength(int version, QRecLevel level); + +/** + * Return maximum error correction code length (bytes) for the version. + * @param version + * @param level + * @return ECC size (bytes) + */ +extern int QRspec_getECCLength(int version, QRecLevel level); + +/** + * Return a version number that satisfies the input code length. + * @param size input code length (byte) + * @param level + * @return version number + */ +extern int QRspec_getMinimumVersion(int size, QRecLevel level); + +/** + * Return the width of the symbol for the version. + * @param version + * @return width + */ +extern int QRspec_getWidth(int version); + +/** + * Return the numer of remainder bits. + * @param version + * @return number of remainder bits + */ +extern int QRspec_getRemainder(int version); + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +/** + * Return the size of lenght indicator for the mode and version. + * @param mode + * @param version + * @return the size of the appropriate length indicator (bits). + */ +extern int QRspec_lengthIndicator(QRencodeMode mode, int version); + +/** + * Return the maximum length for the mode and version. + * @param mode + * @param version + * @return the maximum length (bytes) + */ +extern int QRspec_maximumWords(QRencodeMode mode, int version); + +/****************************************************************************** + * Error correction code + *****************************************************************************/ + +/** + * Return an array of ECC specification. + * @param version + * @param level + * @param spec an array of ECC specification contains as following: + * {# of type1 blocks, # of data code, # of ecc code, + * # of type2 blocks, # of data code} + */ +void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]); + +#define QRspec_rsBlockNum(__spec__) (__spec__[0] + __spec__[3]) +#define QRspec_rsBlockNum1(__spec__) (__spec__[0]) +#define QRspec_rsDataCodes1(__spec__) (__spec__[1]) +#define QRspec_rsEccCodes1(__spec__) (__spec__[2]) +#define QRspec_rsBlockNum2(__spec__) (__spec__[3]) +#define QRspec_rsDataCodes2(__spec__) (__spec__[4]) +#define QRspec_rsEccCodes2(__spec__) (__spec__[2]) + +#define QRspec_rsDataLength(__spec__) \ + ((QRspec_rsBlockNum1(__spec__) * QRspec_rsDataCodes1(__spec__)) + \ + (QRspec_rsBlockNum2(__spec__) * QRspec_rsDataCodes2(__spec__))) +#define QRspec_rsEccLength(__spec__) \ + (QRspec_rsBlockNum(__spec__) * QRspec_rsEccCodes1(__spec__)) + +/****************************************************************************** + * Version information pattern + *****************************************************************************/ + +/** + * Return BCH encoded version information pattern that is used for the symbol + * of version 7 or greater. Use lower 18 bits. + * @param version + * @return BCH encoded version information pattern + */ +extern unsigned int QRspec_getVersionPattern(int version); + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/** + * Return BCH encoded format information pattern. + * @param mask + * @param level + * @return BCH encoded format information pattern + */ +extern unsigned int QRspec_getFormatInfo(int mask, QRecLevel level); + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Return a copy of initialized frame. + * When the same version is requested twice or more, a copy of cached frame + * is returned. + * @param version + * @return Array of unsigned char. You can free it by free(). + */ +extern unsigned char *QRspec_newFrame(int version); + +/** + * Clear the frame cache. Typically for debug. + */ +extern void QRspec_clearCache(void); + +/****************************************************************************** + * Mode indicator + *****************************************************************************/ + +/** + * Mode indicator. See Table 2 of JIS X0510:2004, pp.16. + */ +#define QRSPEC_MODEID_ECI 7 +#define QRSPEC_MODEID_NUM 1 +#define QRSPEC_MODEID_AN 2 +#define QRSPEC_MODEID_8 4 +#define QRSPEC_MODEID_KANJI 8 +#define QRSPEC_MODEID_FNC1FIRST 5 +#define QRSPEC_MODEID_FNC1SECOND 9 +#define QRSPEC_MODEID_STRUCTURE 3 +#define QRSPEC_MODEID_TERMINATOR 0 + +#endif /* __QRSPEC_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/rscode.c b/src/add-ons/kernel/debugger/qrencode/rscode.c new file mode 100644 index 0000000000..edc32e2c92 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/rscode.c @@ -0,0 +1,327 @@ +/* + * qrencode - QR Code encoder + * + * Reed solomon encoder. This code is taken from Phil Karn's libfec then + * editted and packed into a pair of .c and .h files. + * + * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q + * (libfec is released under the GNU Lesser General Public License.) + * + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#ifdef HAVE_LIBPTHREAD +# include +#endif + +#include "rscode.h" + +/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs + * + */ +typedef unsigned char data_t; + + +/** + * Reed-Solomon codec control block + */ +struct _RS { + int mm; /* Bits per symbol */ + int nn; /* Symbols per block (= (1<= rs->nn) { + x -= rs->nn; + x = (x >> rs->mm) + (x & rs->nn); + } + return x; +} + + +#define MODNN(x) modnn(rs,x) + +#define MM (rs->mm) +#define NN (rs->nn) +#define ALPHA_TO (rs->alpha_to) +#define INDEX_OF (rs->index_of) +#define GENPOLY (rs->genpoly) +#define NROOTS (rs->nroots) +#define FCR (rs->fcr) +#define PRIM (rs->prim) +#define IPRIM (rs->iprim) +#define PAD (rs->pad) +#define A0 (NN) + + +/* Initialize a Reed-Solomon codec + * symsize = symbol size, bits + * gfpoly = Field generator polynomial coefficients + * fcr = first root of RS code generator polynomial, index form + * prim = primitive element to generate polynomial roots + * nroots = RS code generator polynomial degree (number of roots) + * pad = padding bytes at front of shortened block + */ +static RS *init_rs_char(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad) +{ + RS *rs; + + +/* Common code for intializing a Reed-Solomon control block (char or int symbols) + * Copyright 2004 Phil Karn, KA9Q + * May be used under the terms of the GNU Lesser General Public License (LGPL) + */ +//#undef NULL +//#define NULL ((void *)0) + + int i, j, sr,root,iprim; + + rs = NULL; + /* Check parameter ranges */ + if(symsize < 0 || symsize > (int)(8*sizeof(data_t))){ + goto done; + } + + if(fcr < 0 || fcr >= (1<= (1<= (1<= ((1<mm = symsize; + rs->nn = (1<pad = pad; + + rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); + if(rs->alpha_to == NULL){ + free(rs); + rs = NULL; + goto done; + } + rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); + if(rs->index_of == NULL){ + free(rs->alpha_to); + free(rs); + rs = NULL; + goto done; + } + + /* Generate Galois field lookup tables */ + rs->index_of[0] = A0; /* log(zero) = -inf */ + rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */ + sr = 1; + for(i=0;inn;i++){ + rs->index_of[sr] = i; + rs->alpha_to[i] = sr; + sr <<= 1; + if(sr & (1<nn; + } + if(sr != 1){ + /* field generator polynomial is not primitive! */ + free(rs->alpha_to); + free(rs->index_of); + free(rs); + rs = NULL; + goto done; + } + + /* Form RS code generator polynomial from its roots */ + rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1)); + if(rs->genpoly == NULL){ + free(rs->alpha_to); + free(rs->index_of); + free(rs); + rs = NULL; + goto done; + } + rs->fcr = fcr; + rs->prim = prim; + rs->nroots = nroots; + rs->gfpoly = gfpoly; + + /* Find prim-th root of 1, used in decoding */ + for(iprim=1;(iprim % prim) != 0;iprim += rs->nn) + ; + rs->iprim = iprim / prim; + + rs->genpoly[0] = 1; + for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) { + rs->genpoly[i+1] = 1; + + /* Multiply rs->genpoly[] by @**(root + x) */ + for (j = i; j > 0; j--){ + if (rs->genpoly[j] != 0) + rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)]; + else + rs->genpoly[j] = rs->genpoly[j-1]; + } + /* rs->genpoly[0] can never be zero */ + rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)]; + } + /* convert rs->genpoly[] to index form for quicker encoding */ + for (i = 0; i <= nroots; i++) + rs->genpoly[i] = rs->index_of[rs->genpoly[i]]; + done:; + + return rs; +} + +RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad) +{ + RS *rs; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&rslist_mutex); +#endif + for(rs = rslist; rs != NULL; rs = rs->next) { + if(rs->pad != pad) continue; + if(rs->nroots != nroots) continue; + if(rs->mm != symsize) continue; + if(rs->gfpoly != gfpoly) continue; + if(rs->fcr != fcr) continue; + if(rs->prim != prim) continue; + + goto DONE; + } + + rs = init_rs_char(symsize, gfpoly, fcr, prim, nroots, pad); + if(rs == NULL) goto DONE; + rs->next = rslist; + rslist = rs; + +DONE: +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&rslist_mutex); +#endif + return rs; +} + + +void free_rs_char(RS *rs) +{ + free(rs->alpha_to); + free(rs->index_of); + free(rs->genpoly); + free(rs); +} + +void free_rs_cache(void) +{ + RS *rs, *next; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&rslist_mutex); +#endif + rs = rslist; + while(rs != NULL) { + next = rs->next; + free_rs_char(rs); + rs = next; + } + rslist = NULL; +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&rslist_mutex); +#endif +} + +/* The guts of the Reed-Solomon encoder, meant to be #included + * into a function body with the following typedefs, macros and variables supplied + * according to the code parameters: + + * data_t - a typedef for the data symbol + * data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded + * data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols + * NROOTS - the number of roots in the RS code generator polynomial, + * which is the same as the number of parity symbols in a block. + Integer variable or literal. + * + * NN - the total number of symbols in a RS block. Integer variable or literal. + * PAD - the number of pad symbols in a block. Integer variable or literal. + * ALPHA_TO - The address of an array of NN elements to convert Galois field + * elements in index (log) form to polynomial form. Read only. + * INDEX_OF - The address of an array of NN elements to convert Galois field + * elements in polynomial form to index (log) form. Read only. + * MODNN - a function to reduce its argument modulo NN. May be inline or a macro. + * GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form + + * The memset() and memmove() functions are used. The appropriate header + * file declaring these functions (usually ) must be included by the calling + * program. + + * Copyright 2004, Phil Karn, KA9Q + * May be used under the terms of the GNU Lesser General Public License (LGPL) + */ + +#undef A0 +#define A0 (NN) /* Special reserved value encoding zero in index form */ + +void encode_rs_char(RS *rs, const data_t *data, data_t *parity) +{ + int i, j; + data_t feedback; + + memset(parity,0,NROOTS*sizeof(data_t)); + + for(i=0;i + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __RSCODE_H__ +#define __RSCODE_H__ + +/* + * General purpose RS codec, 8-bit symbols. + */ + +typedef struct _RS RS; + +extern RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad); +extern void encode_rs_char(RS *rs, const unsigned char *data, unsigned char *parity); +extern void free_rs_char(RS *rs); +extern void free_rs_cache(void); + +#endif /* __RSCODE_H__ */ diff --git a/src/add-ons/kernel/debugger/qrencode/split.c b/src/add-ons/kernel/debugger/qrencode/split.c new file mode 100644 index 0000000000..f53dce5dc4 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/split.c @@ -0,0 +1,311 @@ +/* + * qrencode - QR Code encoder + * + * Input data splitter. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include "qrencode.h" +#include "qrinput.h" +#include "qrspec.h" +#include "split.h" + +#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10) +#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0) + +#if !HAVE_STRDUP +#undef strdup +char *strdup(const char *s) +{ + size_t len = strlen(s) + 1; + void *new = malloc(len); + if(new == NULL) return NULL; + return (char *)memcpy(new, s, len); +} +#endif + +static QRencodeMode Split_identifyMode(const char *string, QRencodeMode hint) +{ + unsigned char c, d; + unsigned int word; + + c = string[0]; + + if(c == '\0') return QR_MODE_NUL; + if(isdigit(c)) { + return QR_MODE_NUM; + } else if(isalnum(c)) { + return QR_MODE_AN; + } else if(hint == QR_MODE_KANJI) { + d = string[1]; + if(d != '\0') { + word = ((unsigned int)c << 8) | d; + if((word >= 0x8140 && word <= 0x9ffc) || (word >= 0xe040 && word <= 0xebbf)) { + return QR_MODE_KANJI; + } + } + } + + return QR_MODE_8; +} + +static int Split_eatNum(const char *string, QRinput *input, QRencodeMode hint); +static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint); +static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint); +static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint); + +static int Split_eatNum(const char *string, QRinput *input,QRencodeMode hint) +{ + const char *p; + int ret; + int run; + int dif; + int ln; + QRencodeMode mode; + + ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version); + + p = string; + while(isdigit(*p)) { + p++; + } + run = p - string; + mode = Split_identifyMode(p, hint); + if(mode == QR_MODE_8) { + dif = QRinput_estimateBitsModeNum(run) + 4 + ln + + QRinput_estimateBitsMode8(1) /* + 4 + l8 */ + - QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */; + if(dif > 0) { + return Split_eat8(string, input, hint); + } + } + if(mode == QR_MODE_AN) { + dif = QRinput_estimateBitsModeNum(run) + 4 + ln + + QRinput_estimateBitsModeAn(1) /* + 4 + la */ + - QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */; + if(dif > 0) { + return Split_eatAn(string, input, hint); + } + } + + ret = QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint) +{ + const char *p, *q; + int ret; + int run; + int dif; + int la, ln; + + la = QRspec_lengthIndicator(QR_MODE_AN, input->version); + ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version); + + p = string; + while(isalnum(*p)) { + if(isdigit(*p)) { + q = p; + while(isdigit(*q)) { + q++; + } + dif = QRinput_estimateBitsModeAn(p - string) /* + 4 + la */ + + QRinput_estimateBitsModeNum(q - p) + 4 + ln + - QRinput_estimateBitsModeAn(q - string) /* - 4 - la */; + if(dif < 0) { + break; + } else { + p = q; + } + } else { + p++; + } + } + + run = p - string; + + if(*p && !isalnum(*p)) { + dif = QRinput_estimateBitsModeAn(run) + 4 + la + + QRinput_estimateBitsMode8(1) /* + 4 + l8 */ + - QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */; + if(dif > 0) { + return Split_eat8(string, input, hint); + } + } + + ret = QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint) +{ + const char *p; + int ret; + int run; + + p = string; + while(Split_identifyMode(p, hint) == QR_MODE_KANJI) { + p += 2; + } + run = p - string; + ret = QRinput_append(input, QR_MODE_KANJI, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint) +{ + const char *p, *q; + QRencodeMode mode; + int ret; + int run; + int dif; + int la, ln; + + la = QRspec_lengthIndicator(QR_MODE_AN, input->version); + ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version); + + p = string + 1; + while(*p != '\0') { + mode = Split_identifyMode(p, hint); + if(mode == QR_MODE_KANJI) { + break; + } + if(mode == QR_MODE_NUM) { + q = p; + while(isdigit(*q)) { + q++; + } + dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */ + + QRinput_estimateBitsModeNum(q - p) + 4 + ln + - QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */; + if(dif < 0) { + break; + } else { + p = q; + } + } else if(mode == QR_MODE_AN) { + q = p; + while(isalnum(*q)) { + q++; + } + dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */ + + QRinput_estimateBitsModeAn(q - p) + 4 + la + - QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */; + if(dif < 0) { + break; + } else { + p = q; + } + } else { + p++; + } + } + + run = p - string; + ret = QRinput_append(input, QR_MODE_8, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_splitString(const char *string, QRinput *input, + QRencodeMode hint) +{ + int length; + QRencodeMode mode; + + if(*string == '\0') return 0; + + mode = Split_identifyMode(string, hint); + if(mode == QR_MODE_NUM) { + length = Split_eatNum(string, input, hint); + } else if(mode == QR_MODE_AN) { + length = Split_eatAn(string, input, hint); + } else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) { + length = Split_eatKanji(string, input, hint); + } else { + length = Split_eat8(string, input, hint); + } + if(length == 0) return 0; + if(length < 0) return -1; + return Split_splitString(&string[length], input, hint); +} + +static char *dupAndToUpper(const char *str, QRencodeMode hint) +{ + char *newstr, *p; + QRencodeMode mode; + + newstr = strdup(str); + if(newstr == NULL) return NULL; + + p = newstr; + while(*p != '\0') { + mode = Split_identifyMode(p, hint); + if(mode == QR_MODE_KANJI) { + p += 2; + } else { + if (*p >= 'a' && *p <= 'z') { + *p = (char)((int)*p - 32); + } + p++; + } + } + + return newstr; +} + +int Split_splitStringToQRinput(const char *string, QRinput *input, + QRencodeMode hint, int casesensitive) +{ + char *newstr; + int ret; + + if(string == NULL || *string == '\0') { + errno = EINVAL; + return -1; + } + if(!casesensitive) { + newstr = dupAndToUpper(string, hint); + if(newstr == NULL) return -1; + ret = Split_splitString(newstr, input, hint); + free(newstr); + } else { + ret = Split_splitString(string, input, hint); + } + + return ret; +} diff --git a/src/add-ons/kernel/debugger/qrencode/split.h b/src/add-ons/kernel/debugger/qrencode/split.h new file mode 100644 index 0000000000..b2cdbe5468 --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/split.h @@ -0,0 +1,47 @@ +/* + * qrencode - QR Code encoder + * + * Input data splitter. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SPLIT_H__ +#define __SPLIT_H__ + +#include "qrencode.h" + +/** + * Split the input string (null terminated) into QRinput. + * @param string input string + * @param hint give QR_MODE_KANJI if the input string contains Kanji character encoded in Shift-JIS. If not, give QR_MODE_8. + * @param casesensitive 0 for case-insensitive encoding (all alphabet characters are replaced to UPPER-CASE CHARACTERS. + * @retval 0 success. + * @retval -1 an error occurred. errno is set to indicate the error. See + * Exceptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern int Split_splitStringToQRinput(const char *string, QRinput *input, + QRencodeMode hint, int casesensitive); + +#endif /* __SPLIT_H__ */ From fcc4ecb0c7c03ff8ac851150058e0cbbe1f4e08c Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 05:36:45 +0200 Subject: [PATCH 04/18] Add debug_calloc() to the debug_heap. --- headers/private/kernel/debug_heap.h | 1 + src/system/kernel/debug/debug_heap.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/headers/private/kernel/debug_heap.h b/headers/private/kernel/debug_heap.h index ae110b9840..552a07a8cd 100644 --- a/headers/private/kernel/debug_heap.h +++ b/headers/private/kernel/debug_heap.h @@ -19,6 +19,7 @@ extern "C" { debug_alloc_pool* create_debug_alloc_pool(); void delete_debug_alloc_pool(debug_alloc_pool* pool); void* debug_malloc(size_t size); +void* debug_calloc(size_t num, size_t size); void debug_free(void* address); void debug_heap_init(); diff --git a/src/system/kernel/debug/debug_heap.cpp b/src/system/kernel/debug/debug_heap.cpp index 069e97d6f1..996f5213b9 100644 --- a/src/system/kernel/debug/debug_heap.cpp +++ b/src/system/kernel/debug/debug_heap.cpp @@ -278,6 +278,19 @@ debug_malloc(size_t size) } +void* +debug_calloc(size_t num, size_t size) +{ + size_t allocationSize = num * size; + void* allocation = debug_malloc(allocationSize); + if (allocation == NULL) + return NULL; + + memset(allocation, 0, allocationSize); + return allocation; +} + + void debug_free(void* address) { From 2d37d290b735fe583591f07baaf4a69f37f12e08 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 05:37:14 +0200 Subject: [PATCH 05/18] Make sure that the internal strdup is used. The kernel strdup will still be used, as the local symbol doesn't override that. Since we must not use strdup from within the kernel debugger (as it does malloc from the normal heap), force the use of the internal strdup that gets redirected to debug_malloc. --- src/add-ons/kernel/debugger/qrencode/split.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/debugger/qrencode/split.c b/src/add-ons/kernel/debugger/qrencode/split.c index f53dce5dc4..cf66d0a177 100644 --- a/src/add-ons/kernel/debugger/qrencode/split.c +++ b/src/add-ons/kernel/debugger/qrencode/split.c @@ -41,7 +41,7 @@ #if !HAVE_STRDUP #undef strdup -char *strdup(const char *s) +char *strdup_internal(const char *s) { size_t len = strlen(s) + 1; void *new = malloc(len); @@ -269,7 +269,7 @@ static char *dupAndToUpper(const char *str, QRencodeMode hint) char *newstr, *p; QRencodeMode mode; - newstr = strdup(str); + newstr = strdup_internal(str); if(newstr == NULL) return NULL; p = newstr; From 5521e284150a6f2fcebcfabf1010f1c827224788 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 05:39:46 +0200 Subject: [PATCH 06/18] Reuse two unused lower ASCII chars for block drawing. Characters 17, 18 and 19 (device control 1, 2 and 3) become "full block", "upper filled block" and "lower filled block". Using back- and foreground color inversion these could be reduced to a single "half block", but having them available as idividual chars is more convenient. --- src/system/kernel/debug/font.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/debug/font.h b/src/system/kernel/debug/font.h index 502c77c1ea..9258dd4743 100644 --- a/src/system/kernel/debug/font.h +++ b/src/system/kernel/debug/font.h @@ -46,9 +46,9 @@ static unsigned char FONT[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ' ' */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ' ' */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' ' */ From 0948c0ff50ebdb04a5e60f0ed3ad3f1a9968c7f2 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 06:04:54 +0200 Subject: [PATCH 07/18] Add module code that wraps qrencode and does the printing. * Generates QR codes using the qrencode library functions and prints them using terminal escape sequences and the special "block" characters. * Supplies a static QR buffer that can be used to accumulate output for later conversion into QR codes. * Adds qrencode debugger command that allows to generate QR codes for arbitrary strings. * Adds qrappend, qrflush and qrclear to manipulate the QR buffer. qrappend can be the target of a pipe to accumulate output from other commands. qrflush causes the QR buffer to be encoded and cleared and qrclear only clears the QR buffer. * Adds qrconfig that allows changing the QR code version, determining what size QR codes are to be used. --- .../kernel/debugger/qrencode/module.cpp | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 src/add-ons/kernel/debugger/qrencode/module.cpp diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp new file mode 100644 index 0000000000..58751caa7f --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -0,0 +1,270 @@ +/* + * Copyright 2012, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Lotz + */ + + +#include +#include +#include + +extern "C" { +#include "qrencode.h" +#include "qrspec.h" +} + + +static char sStringBuffer[16 * 1024]; +static char sEncodeBuffer[3 * 1024]; +static int sBufferPosition = 0; +static int sQRCodeVersion = 19; +static QRecLevel sQRCodeLevel = QR_ECLEVEL_L; + + +static bool +qrcode_bit(QRcode* qrCode, int x, int y) +{ + if (x >= qrCode->width || y >= qrCode->width) + return false; + + return (qrCode->data[y * qrCode->width + x] & 0x01) == 1; +} + + +static void +move_to_and_clear_line(int line) +{ + kprintf(" \x1b[%dd\x1b[G\x1b[K", line + 1); +} + + +static void +print_qrcode(QRcode* qrCode, bool waitForKey) +{ + move_to_and_clear_line(0); + for (int y = 0; y < qrCode->width; y += 2) { + move_to_and_clear_line(y / 2 + 1); + kputs(" "); + + for (int x = 0; x < qrCode->width; x++) { + bool upper = qrcode_bit(qrCode, x, y); + bool lower = qrcode_bit(qrCode, x, y + 1); + if (upper == lower) + kputs(upper ? "\x11" : " "); + else + kputs(upper ? "\x12" : "\x13"); + } + } + + move_to_and_clear_line(qrCode->width / 2 + 2); + move_to_and_clear_line(qrCode->width / 2 + 3); + + if (waitForKey) { + kputs("press any key to continue...\x1b[1B\x1b[G"); + kgetc(); + } +} + + +static int +qrencode(int argc, char* argv[]) +{ + if (argc > 1 && strcmp(argv[1], "--help") == 0) { + kprintf("%s []\n", argv[0]); + kprintf("If an argument is given, encodes that string as a QR code.\n" + "Otherwise the current QR buffer is encoded as QR codes.\n" + "When encoding from the QR buffer, the buffer is left intact.\n" + "use qrclear to clear the QR buffer or qrflush to encode/clear.\n"); + return 1; + } + + const char* source = NULL; + if (argc < 2) { + sStringBuffer[sBufferPosition] = 0; + source = sStringBuffer; + } else + source = argv[1]; + + int inputLength = strlen(source); + int encodeLength = QRspec_getDataLength(sQRCodeVersion, sQRCodeLevel) - 3; + while (inputLength > 0) { + int copyCount = inputLength < encodeLength ? inputLength : encodeLength; + memcpy(sEncodeBuffer, source, copyCount); + sEncodeBuffer[copyCount] = 0; + + QRcode* qrCode = QRcode_encodeString8bit(sEncodeBuffer, sQRCodeVersion, + sQRCodeLevel); + if (qrCode == NULL) { + kprintf("Failed to encode buffer into qr code\n"); + QRcode_clearCache(); + return 1; + } + + source += copyCount; + inputLength -= copyCount; + + print_qrcode(qrCode, inputLength > 0); + QRcode_free(qrCode); + } + + QRcode_clearCache(); + return 0; +} + + +static int +qrclear(int argc, char* argv[]) +{ + if (argc > 1 && strcmp(argv[1], "--help") == 0) { + kprintf("Clears the current QR buffer.\n"); + return 0; + } + + sBufferPosition = 0; + sStringBuffer[0] = 0; + return 0; +} + + +static int +qrflush(int argc, char* argv[]) +{ + if (argc > 1 && strcmp(argv[1], "--help") == 0) { + kprintf("Flushes the current QR buffer by encoding QR codes from\n" + "the data and then clears the QR buffer.\n"); + return 1; + } + + qrencode(0, NULL); + qrclear(0, NULL); + return 0; +} + + +static int +qrappend(int argc, char* argv[]) +{ + if (argc < 2 || (argc > 1 && strcmp(argv[1], "--help") == 0)) { + kprintf("%s \n", argv[0]); + kprintf("Appends the given string to the QR buffer. Can be used as\n" + "the target of a pipe command to accumulate the output of other\n" + "commands in the QR buffer.\n" + "Note that this command will flush the QR buffer when it runs\n" + "full to make room for the new string. This will cause QR codes\n" + "to be generated while the append command still runs. As these\n" + "implicit flushes only happen to make room in the buffer, the\n" + "strings are afterwards appended aren't flushed, so make sure to\n" + "execute the qrflush command to generate codes for these as\n" + "well.\n"); + return 1; + } + + const char* source = argv[1]; + int length = strlen(source) + 1; + + while (length > 0) { + int copyCount = sizeof(sStringBuffer) - sBufferPosition - 1; + if (copyCount == 0) { + // The buffer is full, we need to flush it. + qrflush(0, NULL); + } + + if (length < copyCount) + copyCount = length; + + memcpy(sStringBuffer + sBufferPosition, source, copyCount); + sBufferPosition += copyCount; + source += copyCount; + length -= copyCount; + } + + // Overwrite the 0 byte that was copied extra with a newline. + if (sBufferPosition > 0) + sStringBuffer[sBufferPosition - 1] = '\n'; + + return 0; +} + + +static int +qrconfig(int argc, char* argv[]) +{ + if (argc < 2 || (argc > 1 && strcmp(argv[1], "--help") == 0)) { + kprintf("%s \n", argv[0]); + kprintf("Sets the QR version to be used. Valid versions range from 1\n" + "to 40 where each version determines the size of the QR code.\n" + "Version 1 is 21x21 in size and each version increments that size\n" + "by 4x4 up to 177x177 for version 40.\n" + "Bigger QR codes can hold more data, so ideally you use a version\n" + "that makes the QR code as big as possible while still fitting on\n" + "your screen.\n" + "You can test the new config by running qrencode\n" + "with a test string.\n" + "Note that due to memory constraints in the kernel debugger, some\n" + "of the higher versions may actually not work. The kernel\n" + "debugger heap size can be adjusted using the KDEBUG_HEAP define\n" + "in the kernel_debug_config.h header\n"); + return 1; + } + + int newVersion = atoi(argv[1]); + if (newVersion <= 0 || newVersion > 40) { + kprintf("Invalid QR code version supplied, " + "must be between 1 and 40.\n"); + return 1; + } + + sQRCodeVersion = newVersion; + return 0; +} + + +static status_t +std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + add_debugger_command("qrencode", qrencode, + "encodes a string / the current QR buffer"); + add_debugger_command("qrappend", qrappend, + "appends a string to the QR buffer"); + add_debugger_command("qrclear", qrclear, + "clears the current QR buffer"); + add_debugger_command("qrflush", qrflush, + "encodes the current QR buffer and clears it"); + add_debugger_command("qrconfig", qrconfig, + "sets the QR code version to be used"); + return B_OK; + case B_MODULE_UNINIT: + remove_debugger_command("qrencode", qrencode); + remove_debugger_command("qrappend", qrappend); + remove_debugger_command("qrclear", qrclear); + remove_debugger_command("qrflush", qrflush); + remove_debugger_command("qrconfig", qrconfig); + return B_OK; + } + + return B_BAD_VALUE; +} + + +static struct debugger_module_info sModuleInfo = { + { + "debugger/qrencode/v1", + 0, + &std_ops + }, + NULL, + NULL, + NULL, + NULL +}; + +module_info *modules[] = { + (module_info *)&sModuleInfo, + NULL +}; + From ce79b4c428a6d71bb51ffc209dbdb87cc90799b2 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 06:12:59 +0200 Subject: [PATCH 08/18] Add qrencode kernel debugger add-on to the build. The defines in the Jamfile remap the memory allocation functions to use debug heap versions of the corresponding functions. --- src/add-ons/kernel/debugger/Jamfile | 1 + src/add-ons/kernel/debugger/qrencode/Jamfile | 22 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/add-ons/kernel/debugger/qrencode/Jamfile diff --git a/src/add-ons/kernel/debugger/Jamfile b/src/add-ons/kernel/debugger/Jamfile index dcf3f4a83d..ef05494cf9 100644 --- a/src/add-ons/kernel/debugger/Jamfile +++ b/src/add-ons/kernel/debugger/Jamfile @@ -7,5 +7,6 @@ SubInclude HAIKU_TOP src add-ons kernel debugger disasm ; SubInclude HAIKU_TOP src add-ons kernel debugger hangman ; SubInclude HAIKU_TOP src add-ons kernel debugger invalidate_on_exit ; SubInclude HAIKU_TOP src add-ons kernel debugger laplinkll ; +SubInclude HAIKU_TOP src add-ons kernel debugger qrencode ; SubInclude HAIKU_TOP src add-ons kernel debugger run_on_exit ; SubInclude HAIKU_TOP src add-ons kernel debugger usb_keyboard ; diff --git a/src/add-ons/kernel/debugger/qrencode/Jamfile b/src/add-ons/kernel/debugger/qrencode/Jamfile new file mode 100644 index 0000000000..c196777fbe --- /dev/null +++ b/src/add-ons/kernel/debugger/qrencode/Jamfile @@ -0,0 +1,22 @@ +SubDir HAIKU_TOP src add-ons kernel debugger qrencode ; + +UsePrivateHeaders kernel ; + +DEFINES += HAVE_CONFIG_H ; +DEFINES += malloc=debug_malloc ; +DEFINES += calloc=debug_calloc ; +DEFINES += free=debug_free ; + +KernelAddon qrencode : + bitstream.c + mask.c + mmask.c + mqrspec.c + qrencode.c + qrinput.c + qrspec.c + rscode.c + split.c + + module.cpp + ; From c95456a6990fa9f3dba23c83961617db5a0051f5 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 06:22:01 +0200 Subject: [PATCH 09/18] Add qrencode kernel debugger add-on to the image. --- build/jam/HaikuImage | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index ffc8d7ea74..61adf50d76 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -239,7 +239,8 @@ AddFilesToHaikuImage system add-ons kernel busses usb AddFilesToHaikuImage system add-ons kernel console : vga_text ; AddFilesToHaikuImage system add-ons kernel debugger : demangle $(X86_ONLY)disasm hangman - invalidate_on_exit usb_keyboard run_on_exit ; + invalidate_on_exit usb_keyboard qrencode + run_on_exit ; AddFilesToHaikuImage system add-ons kernel file_systems : $(SYSTEM_ADD_ONS_FILE_SYSTEMS) ; AddFilesToHaikuImage system add-ons kernel generic From db744fca35a90986d1c3d061a5b81a803ffa7170 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 06:53:59 +0200 Subject: [PATCH 10/18] Add libqrencode credits to AboutSystem. --- src/apps/aboutsystem/AboutSystem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/apps/aboutsystem/AboutSystem.cpp b/src/apps/aboutsystem/AboutSystem.cpp index deba9af5e7..ec3303c6ab 100644 --- a/src/apps/aboutsystem/AboutSystem.cpp +++ b/src/apps/aboutsystem/AboutSystem.cpp @@ -1694,6 +1694,12 @@ AboutView::_CreateCreditsView() .SetLicense(B_TRANSLATE("BSD (3-clause)")) .SetURL("http://gtf.sourceforge.net/")); + // libqrencode + _AddPackageCredit(PackageCredit("libqrencode") + .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2012 Kentaro Fukuchi")) + .SetLicense(B_TRANSLATE("GNU LGPL v2.1")) + .SetURL("http://fukuchi.org/works/qrencode/")); + _AddCopyrightsFromAttribute(); _AddPackageCreditEntries(); From a86c7d0ab32920e70e98ac4437b45f26a63c4b06 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 18:29:11 +0200 Subject: [PATCH 11/18] Add qrwebpost to generate URLs for easier data collection. Using the qrwebpost debugger command one can initialize an id for subsequent QR codes. All QR codes generated following such an invokation produce URL QR codes that link to an online service that concatenates all data with the same id and later allows it to be displayed/downloaded in one piece. This makes collecting larger amounts of data more convenient. Note though that the URL encoding does waste space and therefore reduces data density, causing more QR codes to be generated for the same amount of input data. --- .../kernel/debugger/qrencode/module.cpp | 101 +++++++++++++++++- 1 file changed, 97 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index 58751caa7f..f945a35f87 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -8,6 +8,7 @@ #include +#include #include #include @@ -17,11 +18,15 @@ extern "C" { } +static const char* kWebPostBaseURL = "http://haiku.mlotz.ch/qrencode/store.php"; + static char sStringBuffer[16 * 1024]; static char sEncodeBuffer[3 * 1024]; static int sBufferPosition = 0; static int sQRCodeVersion = 19; static QRecLevel sQRCodeLevel = QR_ECLEVEL_L; +static char sWebPostId[64]; +static int sWebPostCounter = 0; static bool @@ -69,6 +74,50 @@ print_qrcode(QRcode* qrCode, bool waitForKey) } +static int +encode_url(const char* query, const char* data, int encodeLength, + int inputLength) +{ + sEncodeBuffer[0] = 0; + strlcat(sEncodeBuffer, kWebPostBaseURL, encodeLength + 1); + strlcat(sEncodeBuffer, "?id=", encodeLength + 1); + strlcat(sEncodeBuffer, sWebPostId, encodeLength + 1); + strlcat(sEncodeBuffer, "&", encodeLength + 1); + strlcat(sEncodeBuffer, query, encodeLength + 1); + int position = strlcat(sEncodeBuffer, "=", encodeLength + 1); + if (position > encodeLength) + return -1; + + int copyCount = 0; + while (inputLength > 0 && position < encodeLength) { + char character = data[copyCount]; + if ((character >= 'a' && character <= 'z') + || (character >= 'A' && character <= 'Z') + || (character >= '0' && character <= '9') + || character == '.' || character == '-' || character == '_' + || character == '~') { + sEncodeBuffer[position++] = character; + sEncodeBuffer[position] = 0; + } else { + // Encode to a %xx escape. + if (encodeLength - position < 3) { + // Doesn't fit anymore, we're done. + break; + } + + char escaped[4]; + sprintf(escaped, "%%%.2x", character); + position = strlcat(sEncodeBuffer, escaped, encodeLength + 1); + } + + inputLength--; + copyCount++; + } + + return copyCount; +} + + static int qrencode(int argc, char* argv[]) { @@ -91,14 +140,25 @@ qrencode(int argc, char* argv[]) int inputLength = strlen(source); int encodeLength = QRspec_getDataLength(sQRCodeVersion, sQRCodeLevel) - 3; while (inputLength > 0) { - int copyCount = inputLength < encodeLength ? inputLength : encodeLength; - memcpy(sEncodeBuffer, source, copyCount); - sEncodeBuffer[copyCount] = 0; + int copyCount = 0; + if (sWebPostId[0] != 0) { + copyCount = encode_url(sWebPostCounter++ == 0 ? "clear" : "data", + source, encodeLength, inputLength); + if (copyCount < 0) { + kprintf("Failed to URL encode buffer.\n"); + QRcode_clearCache(); + return 1; + } + } else { + copyCount = inputLength < encodeLength ? inputLength : encodeLength; + memcpy(sEncodeBuffer, source, copyCount); + sEncodeBuffer[copyCount] = 0; + } QRcode* qrCode = QRcode_encodeString8bit(sEncodeBuffer, sQRCodeVersion, sQRCodeLevel); if (qrCode == NULL) { - kprintf("Failed to encode buffer into qr code\n"); + kprintf("Failed to encode buffer into qr code.\n"); QRcode_clearCache(); return 1; } @@ -222,6 +282,36 @@ qrconfig(int argc, char* argv[]) } +static int +qrwebpost(int argc, char* argv[]) +{ + if (argc >= 3 && strcmp(argv[1], "start") == 0) { + strlcpy(sWebPostId, argv[2], sizeof(sWebPostId)); + sWebPostCounter = 0; + + // Generate the clear code. + const char* args[2] = { "", "yes" }; + qrencode(2, (char**)args); + } else if (argc >= 2 && strcmp(argv[1], "stop") == 0) { + sWebPostId[0] = 0; + } else { + kprintf("%s start \n", argv[0]); + kprintf("%s stop\n", argv[0]); + kprintf("Causes the QR codes to be rendered as URLs that resolve to\n" + "a service that allows appending the data of multiple QR codes\n" + "for easier handling.\n" + "An initial QR code is generated that invokes a clear operation\n" + "to prepare the output file on the server.\n" + "Note that there is no logic behind the service, if you and\n" + "someone else use the same id at the same time, they will\n" + "overwrite eachother. Therefore use a reasonably unique name.\n"); + return 1; + } + + return 0; +} + + static status_t std_ops(int32 op, ...) { @@ -237,6 +327,8 @@ std_ops(int32 op, ...) "encodes the current QR buffer and clears it"); add_debugger_command("qrconfig", qrconfig, "sets the QR code version to be used"); + add_debugger_command("qrwebpost", qrwebpost, + "sets up URL encoding for QR codes"); return B_OK; case B_MODULE_UNINIT: remove_debugger_command("qrencode", qrencode); @@ -244,6 +336,7 @@ std_ops(int32 op, ...) remove_debugger_command("qrclear", qrclear); remove_debugger_command("qrflush", qrflush); remove_debugger_command("qrconfig", qrconfig); + remove_debugger_command("qrwebpost", qrwebpost); return B_OK; } From e0ef5b2a972ffaab288c78e04bc9b657ad8badf0 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 18:53:37 +0200 Subject: [PATCH 12/18] Allow aborting the command while QR codes are generated. --- src/add-ons/kernel/debugger/qrencode/module.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index f945a35f87..89470678c8 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -18,6 +18,11 @@ extern "C" { } +extern "C" { +extern void abort_debugger_command(); +} + + static const char* kWebPostBaseURL = "http://haiku.mlotz.ch/qrencode/store.php"; static char sStringBuffer[16 * 1024]; @@ -68,8 +73,9 @@ print_qrcode(QRcode* qrCode, bool waitForKey) move_to_and_clear_line(qrCode->width / 2 + 3); if (waitForKey) { - kputs("press any key to continue...\x1b[1B\x1b[G"); - kgetc(); + kputs("press q to abort or any other key to continue...\x1b[1B\x1b[G"); + if (kgetc() == 'q') + abort_debugger_command(); } } From 62115b47721b2659d5dd748cbd4d2dbc7900de4d Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sun, 1 Jul 2012 18:58:43 +0200 Subject: [PATCH 13/18] Automatic whitespace cleanup and coding style. --- src/preferences/media/MediaListItem.cpp | 14 +++++++------- src/preferences/media/MediaWindow.cpp | 7 +++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/preferences/media/MediaListItem.cpp b/src/preferences/media/MediaListItem.cpp index cfd6f51b09..acf68b6bd2 100644 --- a/src/preferences/media/MediaListItem.cpp +++ b/src/preferences/media/MediaListItem.cpp @@ -2,7 +2,7 @@ // // Copyright (c) 2003, OpenBeOS // -// This software is part of the OpenBeOS distribution and is covered +// This software is part of the OpenBeOS distribution and is covered // by the OpenBeOS license. // // @@ -10,7 +10,7 @@ // Author: Sikosis, Jérôme Duval // Description: Media Preferences // Created : June 25, 2003 -// +// // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #include "MediaListItem.h" @@ -70,13 +70,13 @@ struct MediaListItem::Renderer { { fDoubleInsets = doubleInset; } - + void Render(BView* onto, BRect frame, bool complete = false) { const rgb_color lowColor = onto->LowColor(); const rgb_color highColor = onto->HighColor(); const rgb_color kBlack = {0, 0, 0, 255}; - + if (fSelected || complete) { if (fSelected) onto->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT)); @@ -86,7 +86,7 @@ struct MediaListItem::Renderer { frame.left += 4; frame.top += kITEM_MARGIN; BRect iconFrame(MediaIcons::IconRectAt(frame.LeftTop() + BPoint(1, 0))); - + onto->SetDrawingMode(B_OP_OVER); if (fPrimaryIcon && !fDoubleInsets) { onto->DrawBitmap(fPrimaryIcon, iconFrame); @@ -103,7 +103,7 @@ struct MediaListItem::Renderer { onto->SetDrawingMode(B_OP_COPY); onto->SetHighColor(kBlack); - + BFont font = be_plain_font; font_height fontInfo; font.GetHeight(&fontInfo); @@ -130,7 +130,7 @@ struct MediaListItem::Renderer { width += iconSpace; width += 8.0f; // space between icons and text - + width += be_plain_font->StringWidth(fTitle) + 3.0f; return width; } diff --git a/src/preferences/media/MediaWindow.cpp b/src/preferences/media/MediaWindow.cpp index 9d599b8529..a96526e47e 100644 --- a/src/preferences/media/MediaWindow.cpp +++ b/src/preferences/media/MediaWindow.cpp @@ -413,11 +413,10 @@ MediaWindow::InitWindow() // Start the window fInitCheck = InitMedia(true); - if (fInitCheck != B_OK) { + if (fInitCheck != B_OK) PostMessage(B_QUIT_REQUESTED); - } else if (IsHidden()) { + else if (IsHidden()) Show(); - } } @@ -753,7 +752,7 @@ MediaWindow::_MakeEmptyParamView() B_ALIGN_VERTICAL_CENTER); stringView->SetExplicitAlignment(centered); stringView->SetAlignment(B_ALIGN_CENTER); - + fContentLayout->AddView(stringView); fContentLayout->SetVisibleItem(fContentLayout->CountItems() - 1); From f437c10c48325acce0a27524dc34fa352b255074 Mon Sep 17 00:00:00 2001 From: Humdinger Date: Sun, 1 Jul 2012 19:00:26 +0200 Subject: [PATCH 14/18] Small visual changes to left scroll view. Fixes #8659. Fixed width of left scroll view. Added padding to list items. Thanks yourpalal for your hints. --- src/preferences/media/MediaListItem.cpp | 2 +- src/preferences/media/MediaWindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/preferences/media/MediaListItem.cpp b/src/preferences/media/MediaListItem.cpp index acf68b6bd2..2e1e508d7e 100644 --- a/src/preferences/media/MediaListItem.cpp +++ b/src/preferences/media/MediaListItem.cpp @@ -131,7 +131,7 @@ struct MediaListItem::Renderer { width += 8.0f; // space between icons and text - width += be_plain_font->StringWidth(fTitle) + 3.0f; + width += be_plain_font->StringWidth(fTitle) + 16.0f; return width; } diff --git a/src/preferences/media/MediaWindow.cpp b/src/preferences/media/MediaWindow.cpp index a96526e47e..a9efbc12ec 100644 --- a/src/preferences/media/MediaWindow.cpp +++ b/src/preferences/media/MediaWindow.cpp @@ -405,7 +405,7 @@ MediaWindow::InitWindow() BLayoutBuilder::Group<>(this, B_HORIZONTAL) .SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING) - .Add(scrollView) + .Add(scrollView, 0.0f) .AddGroup(B_VERTICAL) .SetInsets(0, 0, 0, 0) .Add(fTitleView) From 2a80abaa7a912078f5aa4b497c67ab30a9955e81 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 19:34:55 +0200 Subject: [PATCH 15/18] Use a shorter URL and query to maximize payload space. --- src/add-ons/kernel/debugger/qrencode/module.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index 89470678c8..a030e621ab 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -23,7 +23,7 @@ extern void abort_debugger_command(); } -static const char* kWebPostBaseURL = "http://haiku.mlotz.ch/qrencode/store.php"; +static const char* kWebPostBaseURL = "http://mlotz.ch/q"; static char sStringBuffer[16 * 1024]; static char sEncodeBuffer[3 * 1024]; @@ -86,7 +86,7 @@ encode_url(const char* query, const char* data, int encodeLength, { sEncodeBuffer[0] = 0; strlcat(sEncodeBuffer, kWebPostBaseURL, encodeLength + 1); - strlcat(sEncodeBuffer, "?id=", encodeLength + 1); + strlcat(sEncodeBuffer, "?i=", encodeLength + 1); strlcat(sEncodeBuffer, sWebPostId, encodeLength + 1); strlcat(sEncodeBuffer, "&", encodeLength + 1); strlcat(sEncodeBuffer, query, encodeLength + 1); @@ -148,7 +148,7 @@ qrencode(int argc, char* argv[]) while (inputLength > 0) { int copyCount = 0; if (sWebPostId[0] != 0) { - copyCount = encode_url(sWebPostCounter++ == 0 ? "clear" : "data", + copyCount = encode_url(sWebPostCounter++ == 0 ? "clear" : "d", source, encodeLength, inputLength); if (copyCount < 0) { kprintf("Failed to URL encode buffer.\n"); From 39a26a0aa5e64858a54720432ffd1505cb25259f Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 20:27:35 +0200 Subject: [PATCH 16/18] Ensure that the qrencode caches are cleared when aborting. The caches contain pointers into memory allocated by debug_malloc() that come from a pool that is destroied once the command returns. We therefore have to ensure that all such pointers are cleared in all cases before returning from the command or we will run into errors when executing the next commands. --- src/add-ons/kernel/debugger/qrencode/module.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index a030e621ab..54a52c53b2 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -51,7 +51,7 @@ move_to_and_clear_line(int line) } -static void +static bool print_qrcode(QRcode* qrCode, bool waitForKey) { move_to_and_clear_line(0); @@ -75,8 +75,10 @@ print_qrcode(QRcode* qrCode, bool waitForKey) if (waitForKey) { kputs("press q to abort or any other key to continue...\x1b[1B\x1b[G"); if (kgetc() == 'q') - abort_debugger_command(); + return false; } + + return true; } @@ -172,8 +174,14 @@ qrencode(int argc, char* argv[]) source += copyCount; inputLength -= copyCount; - print_qrcode(qrCode, inputLength > 0); + bool doContinue = print_qrcode(qrCode, inputLength > 0); QRcode_free(qrCode); + + if (!doContinue) { + QRcode_clearCache(); + abort_debugger_command(); + // Does not return. + } } QRcode_clearCache(); From 5dc5dbbbb464bf4930380313e3e64bd23b7eb5c5 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 1 Jul 2012 20:30:35 +0200 Subject: [PATCH 17/18] Allow more chars to be sent unencoded and encode space as '+'. While this produces not strictly valid query strings, it reduces the encoding overhead significantly. --- src/add-ons/kernel/debugger/qrencode/module.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/debugger/qrencode/module.cpp b/src/add-ons/kernel/debugger/qrencode/module.cpp index 54a52c53b2..b2f215ddce 100644 --- a/src/add-ons/kernel/debugger/qrencode/module.cpp +++ b/src/add-ons/kernel/debugger/qrencode/module.cpp @@ -103,9 +103,21 @@ encode_url(const char* query, const char* data, int encodeLength, || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9') || character == '.' || character == '-' || character == '_' - || character == '~') { + || character == '~' + // These aren't strictly valid, but seem to work. + || character == '/' || character == '(' || character == ')' + || character == '=' || character == '^' || character == '?' + || character == '|' || character == '*' || character == '@' + || character == ';' || character == ':' || character == ',' + || character == '{' || character == '}' || character == '[' + || character == ']' || character == '<' || character == '>' + || character == '!' || character == '\\') { sEncodeBuffer[position++] = character; sEncodeBuffer[position] = 0; + } else if (character == ' ') { + // Encode spaces as '+' as that's shorter than %20. + sEncodeBuffer[position++] = '+'; + sEncodeBuffer[position] = 0; } else { // Encode to a %xx escape. if (encodeLength - position < 3) { From fb8447d59586d40fc8987ede4795ebda64354839 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 2 Jul 2012 02:06:29 -0400 Subject: [PATCH 18/18] Fix ticket #8650. - Replace arch_cpu_user_strlcpy() and arch_cpu_user_memset() with x86 assembly versions. These correctly handle the fault handler, which had broken again on gcc4 for the C versions, causing stack corruption in certain error cases. The other architectures will still need to have corresponding asm variants added in order for them to not run into the same issue though. --- src/system/kernel/arch/x86/arch_cpu.cpp | 60 +------------- src/system/kernel/arch/x86/arch_x86.S | 103 ++++++++++++++++++++++++ src/system/kernel/vm/vm.cpp | 4 +- 3 files changed, 107 insertions(+), 60 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 5ebb194bb1..8d44375dbf 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -4,6 +4,7 @@ * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the NewOS License. + * */ @@ -988,65 +989,6 @@ arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages) } -ssize_t -arch_cpu_user_strlcpy(char *to, const char *from, size_t size, - addr_t *faultHandler) -{ - int fromLength = 0; - addr_t oldFaultHandler = *faultHandler; - - // this check is to trick the gcc4 compiler and have it keep the error label - if (to == NULL && size > 0) - goto error; - - *faultHandler = (addr_t)&&error; - - if (size > 0) { - to[--size] = '\0'; - // copy - for ( ; size; size--, fromLength++, to++, from++) { - if ((*to = *from) == '\0') - break; - } - } - // count any leftover from chars - while (*from++ != '\0') { - fromLength++; - } - - *faultHandler = oldFaultHandler; - return fromLength; - -error: - *faultHandler = oldFaultHandler; - return B_BAD_ADDRESS; -} - - -status_t -arch_cpu_user_memset(void *s, char c, size_t count, addr_t *faultHandler) -{ - char *xs = (char *)s; - addr_t oldFaultHandler = *faultHandler; - - // this check is to trick the gcc4 compiler and have it keep the error label - if (s == NULL) - goto error; - - *faultHandler = (addr_t)&&error; - - while (count--) - *xs++ = c; - - *faultHandler = oldFaultHandler; - return 0; - -error: - *faultHandler = oldFaultHandler; - return B_BAD_ADDRESS; -} - - status_t arch_cpu_shutdown(bool rebootSystem) { diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/arch_x86.S index 28611fe247..58e20fc8cc 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/arch_x86.S @@ -1,5 +1,6 @@ /* * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -219,6 +220,108 @@ FUNCTION(arch_cpu_user_memcpy): FUNCTION_END(arch_cpu_user_memcpy) +/* status_t arch_cpu_user_memset(void *to, char c, size_t count, addr_t *faultHandler) */ +FUNCTION(arch_cpu_user_memset): + pushl %esi + pushl %edi + movl 12(%esp),%edi /* dest */ + movb 16(%esp),%al /* c */ + movl 20(%esp),%ecx /* count */ + + /* set the fault handler */ + movl 24(%esp),%edx /* fault handler */ + movl (%edx),%esi + movl $.L_user_memset_error, (%edx) + + rep + stosb + + /* restore the old fault handler */ + movl %esi,(%edx) + xor %eax,%eax + + popl %edi + popl %esi + ret + + /* error condition */ +.L_user_memset_error: + /* restore the old fault handler */ + movl %esi,(%edx) + movl $-1,%eax /* return a generic error, the wrapper routine will deal with it */ + popl %edi + popl %esi + ret +FUNCTION_END(arch_cpu_user_memset) + + +/* ssize_t arch_cpu_user_strlcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */ +FUNCTION(arch_cpu_user_strlcpy): + pushl %esi + pushl %edi + pushl %ebx + movl 16(%esp),%edi /* dest */ + movl 20(%esp),%esi /* source */ + movl 24(%esp),%ecx /* count */ + + /* set the fault handler */ + movl 28(%esp),%edx /* fault handler */ + movl (%edx),%ebx + movl $.L_user_strlcpy_error, (%edx) + + /* Check for 0 length */ + cmp $0,%ecx + je .L_user_strlcpy_source_count + + /* Copy at most count - 1 bytes */ + dec %ecx + + /* move data by bytes */ + cld + repnz + movsb + + /* null terminate string */ + movb $0,(%edi) + dec %esi + + /* check if we copied the entire source string */ + cmp $0,%ecx + jne .L_user_strlcpy_source_done + + /* count remaining bytes in src */ +.L_user_strlcpy_source_count: + not %ecx + movb $0,%al + repnz + scasb + +.L_user_strlcpy_source_done: + + movl %esi,%eax + subl 20(%esp),%eax + subl $1,%eax + + /* restore the old fault handler */ + movl %ebx,(%edx) + + popl %ebx + popl %edi + popl %esi + ret + + /* error condition */ +.L_user_strlcpy_error: + /* restore the old fault handler */ + movl %ebx,(%edx) + movl $-1,%eax /* return a generic error, the wrapper routine will deal with it */ + popl %ebx + popl %edi + popl %esi + ret +FUNCTION_END(arch_cpu_user_strlcpy) + + /*! \fn void arch_debug_call_with_fault_handler(cpu_ent* cpu, jmp_buf jumpBuffer, void (*function)(void*), void* parameter) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 857bf22808..e289def87f 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -5104,8 +5104,10 @@ user_strlcpy(char* to, const char* from, size_t size) &thread_get_current_thread()->fault_handler); // If we hit the address overflow boundary, fail. - if (result >= 0 && (size_t)result >= maxSize && maxSize < size) + if (result < 0 || (result >= 0 && (size_t)result >= maxSize + && maxSize < size)) { return B_BAD_ADDRESS; + } return result; }