From 7889a9e970f36d9d1a12374bc728c4f1042d6b26 Mon Sep 17 00:00:00 2001 From: Xie Changrong <1225674957@qq.com> Date: Sat, 11 Jun 2022 21:50:05 +0800 Subject: [PATCH 1/3] update --- src/Logistics/app/build.gradle | 1 + src/Logistics/app/libs/java_websocket.jar | Bin 88934 -> 0 bytes src/Logistics/app/src/main/assets/js.html | 10 +- .../goodDao.java => manager/goodManager.java} | 62 +++- .../operationManager.java} | 6 +- .../userDao.java => manager/userManager.java} | 5 +- .../example/logistics/tools/DBOpenHelper.java | 4 +- .../logistics/tools/JWebSocketClient.java | 35 ++ .../example/logistics/ui/HistoryActivity.java | 10 +- .../example/logistics/ui/MainActivity.java | 12 +- .../ui/{MyFragment3.java => MeUI.java} | 4 +- .../example/logistics/ui/MenuActivity.java | 6 +- .../com/example/logistics/ui/MyFragment2.java | 220 ------------ .../example/logistics/ui/NoPickActivity.java | 17 +- .../com/example/logistics/ui/PickUpUI.java | 306 +++++++++++++++++ .../ui/{MyFragment1.java => SearchUI.java} | 14 +- .../example/logistics/ui/SignUpActivity.java | 8 +- src/server/.gitignore | 33 ++ src/server/.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 58727 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 + src/server/mvnw | 316 ++++++++++++++++++ src/server/mvnw.cmd | 188 +++++++++++ src/server/pom.xml | 80 +++++ .../example/testdemo/TestdemoApplication.java | 42 +++ .../testdemo/config/SendObjectMessage.java | 176 ++++++++++ .../testdemo/config/WebSocketConfig.java | 17 + src/server/src/main/resources/a.js | 1 + src/server/src/main/resources/application.yml | 18 + src/server/src/main/resources/em.js | 1 + src/server/src/main/resources/roslib.min.js | 1 + src/server/src/main/resources/test.html | 59 ++++ src/server/src/main/resources/test.js | 97 ++++++ .../testdemo/TestdemoApplicationTests.java | 13 + 33 files changed, 1480 insertions(+), 284 deletions(-) delete mode 100644 src/Logistics/app/libs/java_websocket.jar rename src/Logistics/app/src/main/java/com/example/logistics/{dao/goodDao.java => manager/goodManager.java} (72%) rename src/Logistics/app/src/main/java/com/example/logistics/{dao/operationDao.java => manager/operationManager.java} (95%) rename src/Logistics/app/src/main/java/com/example/logistics/{dao/userDao.java => manager/userManager.java} (98%) create mode 100644 src/Logistics/app/src/main/java/com/example/logistics/tools/JWebSocketClient.java rename src/Logistics/app/src/main/java/com/example/logistics/ui/{MyFragment3.java => MeUI.java} (95%) delete mode 100644 src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment2.java create mode 100644 src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java rename src/Logistics/app/src/main/java/com/example/logistics/ui/{MyFragment1.java => SearchUI.java} (81%) create mode 100644 src/server/.gitignore create mode 100644 src/server/.mvn/wrapper/maven-wrapper.jar create mode 100644 src/server/.mvn/wrapper/maven-wrapper.properties create mode 100644 src/server/mvnw create mode 100644 src/server/mvnw.cmd create mode 100644 src/server/pom.xml create mode 100644 src/server/src/main/java/com/example/testdemo/TestdemoApplication.java create mode 100644 src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java create mode 100644 src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java create mode 100644 src/server/src/main/resources/a.js create mode 100644 src/server/src/main/resources/application.yml create mode 100644 src/server/src/main/resources/em.js create mode 100644 src/server/src/main/resources/roslib.min.js create mode 100644 src/server/src/main/resources/test.html create mode 100644 src/server/src/main/resources/test.js create mode 100644 src/server/src/test/java/com/example/testdemo/TestdemoApplicationTests.java diff --git a/src/Logistics/app/build.gradle b/src/Logistics/app/build.gradle index ef99642..bd44a64 100644 --- a/src/Logistics/app/build.gradle +++ b/src/Logistics/app/build.gradle @@ -43,4 +43,5 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + implementation "org.java-websocket:Java-WebSocket:1.4.0" } \ No newline at end of file diff --git a/src/Logistics/app/libs/java_websocket.jar b/src/Logistics/app/libs/java_websocket.jar deleted file mode 100644 index bb5caeb4e80a53b60a83868128ac5fde26d7ac64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88934 zcmafbV{~RwlWuI=9ox2zH@0mXopfy59oshE*zDL&I__AvXTF*5&di;;bJpJfs?Mra ztM+s1IaRxq<iH`|KtNzXKvGeSML_<;0}BEHq9CCr!XN{XWcr){0a5xlQ5cYvzoHT@ z;A}d7#V!ACjKBMzq6#7a8A%CMHAV%=dxfb<c{v8gc|<t|+L@`@CKcu-w%sF_DKRu> zdTIF?X?2h&Pzr`W@?IS|(JJV2DynX|v?Axz4+#5+Q|`$Kh#2he(P+u8DwsL<(QtRs zXmUSZIlMc(I{s-32#D-|F&pBqEsidhO#f~z2#DN&kwE`92^(V%V?$4K6IVx5TXVO6 zD!}~fEB7t1SN<S^fOHUofYAQ;3aYB|s{g7gW@YT)U~b3CXliHd>YA!$ZKSs1{&{7^ zP8Lg)Eo_op&kR<aC=4277fe1EmWYa$)(_`E@Miso97>XH@yP<DBR03jetk$Gd&#+= z;-Hw*25lXW0M=AxLqV6%IjhDx_m}l~^H~z(RZ_FUIwi?Y$Mtlf@kqkA&TGb#ya&FM zy!lBXpGO{$jiq^%tHBbKyn!R)yqY2A+OZpJTz|u`lOQj_5V&sQXd#rr*|D2&l6TZk ztuSmcelHn-5M9%3s8U$E`Qr=iJ8Um85WDJz!cRM_4&t^<T`RP1Vt@8<AwT>Eu2&<H z?HOMC(;TL5|6=f<F6dbj@{>2@!ApU&k7hK0Eapoi%yB%mFS(}=o8ePL`cv6rCv7jk z@@DoKJMp7V-HY&x64(bn9x%4`m9od@^3>J%WGM3P3DXvZZ!r8db|XOY+-r5)H+cDV z`1&<@2hIAfB>p8GR;5Qf_S5WUTxkS<f(hX?R8!5n1g_jjTD@G>MS}#l(u_ICMp>Fc zLoUe1T8RO^(k7JFmNzpCS5Xn5(<(Z>>wI6lh80h_?qi{%5x>1%v)cyHMGaNBa^}U1 zZIM8`m0oYH@v5xJ4?j~IBx?DcJRc$PdY5vR<AjlRtdA4JOGBg{Ct0>{L2IuIw*eo= z7j?grj&&F3v~tDB3L}2--C{zmT)J4b=TV-u1SMvqCv&zS@50qWJTCLL9n*DP5<L-J zqjE(*Nns7vR<fV~rv$T!w8Dzizds9Abfb`h%X)Cp-kEOsn7g5MetzKdS&iKxRtvye zig?i4RZ`!H!Eu(xl@({YM%sTC&3o)Mm8GQgG}jns#h-Pqg5%hkr$h0wqZN{MZ6WWA zj;`iDPF#mrQZ~x)R)1QkB#;r2(a@#9M{Dc2n9qyl4gm`5Td82S={bSt*{mq>3U=*K zmMSvpLO@$pf2^Y~wZ)bc`l={ZUHk|+pVW+wN_5F}fIh==4>6p^5m{-YQt%mDF9PVL zF6twVw<0!QqqN6*UQeSDBvLBZx7w6vH8lc0)R)Z}guEe&{0f-hOoppbkXWqh5MQXc z{iy>`D?Ye-NL47IhMl*jWIEzIv#yF4&SX{nHDt^M`;io*y)!iRthOP|ON8Cz?Wr6x zGk!zr{$2IVONJhSEz>O$IjgLLTzk9mJ%vzVKD$abV*)0Hhf}qgKCg7b9380$OS<%u zMkYuCtqj$6-Hd3c%*zNswcxCxCXu@hQGh7}iz_l<M-xAUh9todZ_^(GXXJyvIG#ZP z2a$sj9fPh$2XjmRQ}Thbg@~A~i;FUI%zOi%%F}e<yN^BYcLCg7lNeu<kltUd6=!+J zN#1nZGnn~CLoJfV_9MzkQoNC!RFqoIIa?;CKLQo30@4Z#7b(vePP81uO#7#0c`2jQ ze>0H8^Mc<xce)ock(AJ)xQ8Wc=)HN3HBydjf@quz6Uj?wB6U!a@kY{;OJ4b_PjDU} z9oP^8sO@No?vl8blt-Aca?`pW6xU$~2hvINcZ+LKg_Wo3rkcsn?xRet*b`gHe)X1{ z*<W(BSXPa(p-9k{+aRb{X*7Bnp71a`eY@f^GTHnQDg*9m8uK}6?$KtS&2}f6*q~#+ zJI!rVzHAeVU>jUHqx4{tTi~FA2(=w-$nJzAg}@&Xj?j&ajPE3#{SelP8;@fXY=cl4 z8@5g!JzW_|>=le>Qf^TIAKXZm0aJ-3)>6q3wjPCy??o2}p`Kl^9pZ_bF#yD^u|Ds2 zYHe+F@cnU6C~`6_F2?JS3pkI7nr4rgWhZBt#JX?Awdq<n-eoWu<O{u?Rc`H+7}~0u zR^dZj1{~Z1GPf!n;43!}TjVY|)xysaDjCHtQFnf)7U(|Uc%@M8g6~Jt5U{D$>4-_6 zOelLEi~Mf846!d4oY4GmIpOyo?XQaje~d))jKH=y+7)ZuRLouaLH(HRHPtV5(;m2! zv`BSR9O&wD3E;p{gGS^i4hud{D7aD~3&T?nM|2n8ng&ItVc#Ch#!@p4^I;>}V@p-_ z^LlTe>3FpTrL=mwqP3$ZHI9)GuvVb|sq1P_I5F%rsi;<r@vFxfnM9qM%+qx-R)aBM z@kck9`aJhH;Yk@pDnk8)%sG57w+{~+b67eUm{Hk>3(Ij|N1r3}h0-@|9U2aH^Abt6 z?-IFXu8}h)w}Zb_e8kHPee|)C%b&cO{LK)U>~JgVwkV=aDe3mCX|$X_v=ck>!lAYb zc@3OXU%xNhfvB*0U`S2Y!tS=3U>TekSK^&tUw2)P&8<p5709z_Y56@|u;sEtws9zU zpU0Ql^_n_3a^pr*-W#IqC7f~6w!moi2j&-_8uo>@x;lQT_?U@MC1Y0)5|!RcW*K<n zE*`vgtj(*%DBipCPO-Y06!x1N3>{S%sKZ6`7t(Bvo6+OVJ9%ue;C&a)!X_eQEg?F* z*2rM-z%1R6Moc+>rA>mRIzNW?C7CocLj+^53(zT+`*7kd+41!rJD{4@auao}UFBkC zXYTCli$`3TyV-kt^hAD$y}A};W_E)nBgs4-U{1(n*T;_6#^KzCAq?JhHQVX^MBQ(x z3ozT+z0o@6I!27p%7F)pu(`+FW~KoOx~+|b+cH%bz#CW}oa9SY_b2jHYW0#1O0q>w z><3*6TR9THXX$ll%^I$G4uqq|6vDk0K<}o<i3F_S3hxoke1E2?-PzCGx%j?w{(a5q zl*t$A<7lzA&raw^N!4NQp%13FgmX?e!07>RcJif%%MX@zlNEUfo;o{NXp=Sk&gp^x zY>&YeCamt~zSS-o?FkB80NfFIHC*p^q7kjC0HSD}lLoJJq3*1E3jW7%CX+J?`fRBO zoEOHvpX%|>cB7<mZAzyA`aK&+hhdw|F!$9^W?t?KQL4wE*uE@3h_bfjT;G^$9IYi# zrNHLcSk%rkGfo%ToON&=Yedk56nI)aKm+>ja~P6sTUljPN0Q-}INfmVPG<|Za#yGk zTJ<Dr2663nLwdI1wcP6;ST!co1{gf>nr;j;dR}Sks&l2bB$o1l4vfF14@y}sK?NL7 zwJv-KqHB#l=FhX4jDh!89z_XuOU3E+*7W@G)80Px)2#Nq;pbqUQFN2dbW*4MyGZ-y zLN;gB*-lhh&LA5s5nDKgY{>J8MS6t4B0BSH8%}c|=G~&Kd?K`bxCkGK_D_n2W>nou z+j-<YIZSyLxMeJtUHsw7&idcx#~f}zFK^%tQ2fIJT8drH0yyQqI8}}a0-D@vh_>mk zWPWlk)LLAE0>BuqX!*liuH=2oUn=MwD!mmLHJN9?4xvQ7*U<qM+VXZo8`d^}XFlqj zk5a1l6e_>)i_bJ920fE~2b3$@6(7rZ!;dgN*Wgsu5)B|TKpjm>F2TOAz9vKikV}}y zi)mF5{!Qy=oFT8_jCk%Fu1tX=2E%c~(dllq7Mbv_VFL5UInccMg_+a$A-e-Zr#jFV zZz0?9=d7y>zCcIn(#6Rwe9C^hAyQtm_Cf^uQ^I{V2Jg#S=^SRQFVw~fPQ1^D{bTRN zUCb=8#wbPE7$qDSIDYXg_TpsApL<@s?np|960l3Pf@nB1VTt)Q?#ubL@zy}xFFCiw zc!Jiwo}5(Y^ghS#2*Rhk=D5hl1A5w$td!gpp80(Xam%fjpt<gJy`53fS7zJkH*IKt z3ER2dyKx((aKm5H+Q6>s6}&@`szb~8vVkW7L?XR%(2|`6ZBM8p_Y)?Q6YZt;PaC1& zO1k!kQ;N;U?k?A^lL39phSl6HLC)w((w3mq!c9-X3rBt25NL_ZnYGp65`u39vEK?~ z;}=Gn<a>AeW&JWz|FHPnlC|f;Zbip8!0-<g3ypSXn$P&<qy+@+zM16-5ly`wh`h?Y zH{@u1*#rvt-SJJ{kERO*5Uf~ewpmTW*=@T+MY~j<yjf~mf8`8RhH`rT5}>?dm|W{k z#R?9sgu>Ro%Co4*6yrM9e$O*5=$cyD*T!m~t47VY`0mAMd%_L&{IgXCCAHzX-O`zn zC-t5F&w@E$pUOEcx#<1rm^JF$TmJkeV*1EI#UWMk36(BcW?fqLX6}{ct+^XbJN;8m zM`>plw67~qYuLgMY~0IqoXpumqI@wr1B=KPzr1%{{+Ab2Uv}GZ<61x7@J&zi`XkcL zeDR3<JXe_4mz1Ly?qcgc>FnMVO`Y>b3VTTZTxs;3o2Ld#+cK&Gl|N+>+huS$56k=- zscRr=jZOr*H!9RGJ^C>;#=kUi0_#$ZUX@7$NK`-lpE9t-Tlx}CR-(l@@)yy)8o31@ zF|*!vl>Kt(qL{!A;zSjC)&G3j(fD1_bbnnIJ_Ydk_HA_aEin9+-%rrpg9F`b^c9HT znxOBBx7_o`?{mR|>w14Y5x`(9?gh^IamCA(NB9aQs$Vn4?^x71<Sa84=~8L53lp_R z@a5ANTs_@E*w0kHjoV>v90k(-g!kUN{B}q}mms0Bo8_~Y{6*mn*EgiDWF%MK>efKw zVEweR@|@pq5jVRl?CY)V`;$^h^^--dEy==(2zqpzP^n4Nu#QHEiBHV*fk$HSPyDG$ z?em-NOTGNdT0oj<Fx=17oy$rvK6RKb^;8WHq0klOqaE{1_#2XP;I*?x?LD=rFqPa1 zs=W~vUprZf+DyCtQoI8u=mWc@f6$TY8j^WgDU=4&=nX%TdH*fDM_PlN7oHrGRo`*Y z<`47E*C}hU;}=Gm>toZMcet4=eT5@KW$4G+PnLftoB!aBmnF-L@PBzI;a^tG_&;#R z|41BV6s67WoXlPR!5?eX6%_F`F$89b*j9<aNMH>k!3zM)t&#Wh?6BnQp&?-@@s!2w z<n~1k-u>jj7!IQJW)-Yd(g$oe5p4A(M10OvTG~#lMGMr5fS+Hbm)@oa#AcXkn8ltu zqdiYKzT3GcLZ7cM*dQmj)L}*3-^38G_uC`dmVc`tT<^LNIO{0`m#Nc%&M~`LaTmOj z%g0?d?FFLSswAf8UV6h@YQAl5@~2*gKhLs`v_8v)xjDF*e#Ul1tNe7Ia5<DWZz1k^ zvluuAyrt-}UwSV#Ep@h5ywGWA6AK*qOm>VOpBxu)Xj69$Q!UI+Lt6L^yAfC`&TOZ7 z$oP=O+!l9G*C%ADfbxvGxSAS1yHqze58X><-Zd&IaCYc4N^OT=R&`8@_#s-E-GIu` zsHH)~aX_HJ)FirmeF}s5Ad39-{H6xVLW9!v&`d4Yd&Fx_*an%UUa?p!RWkLZ=Rk%$ zOP_kUzugFpbV`Rpli}|yv1@T2Ft3XNxlh|(tEoy-9-lPTfmugQMZe4_fatql4aV$* zKnO+YEHw%Z1u&ZEZ`PT@$xx>Pw>c5p<ZwcE<-NjxhWWihhNy<g{hgQu;ZVIdUi}p^ z^%Il`?-}AAN>Cj-zd(%GeeM^Q6@2?@X;V%%1Am%CKseEw!ptw<;5%%4Yt~(98z)W8 z-+wIk4I!~lZ8l|t?S$>eTV=t%zv<Hop`IlfOwrCtcX%;9lfHo5FlKK>1+<aUb=R6< zmhJ0$)SmJVN1e!w&c?1ynet2qV!u3IUrSg}(B#7qY*l!r%gUqH-HrLCDejzRH7;LM zHfn6#A6Aa1PiP}WRO-mpPK##M+_hh(9hnf*QE`Wo`LQhLLlvw?nNn%;=!oFUd_mlT zQ<1ni+re?VyScJgBApI6uTyU@i!fonbJR%kC2WgQ=PNjp5e!me>j<Ly1X@|ZC*D|? z5O%hLGIVPz1|(GsJaG-Kw1<LRau0>nKv<dHJ%VuRD=6%2|9Ap<)e42N`0$F()R8`e zNP;<VtEpux=K7%)yM2$>W0q^63huLJe+uT?;hvyNh1xk*8s2p9t{IxYIn1Dal2+|1 zm$YHjU(*EI#?GqlV3NW)n0&n`ROpSb9GD)VU}<=ucFZ-j!jkA6`8+kpi4f>6&SQ<b zD$FR>87?|z**5o@TWA>Th(2~b{^u$GA$H}|bUA!wKGz`QMW89xBd|adKLXKKtgf@g z5VQCZEEkSV_?@%8;h5P`VS`*1*>E3sO%SLVSVQX`zW#%2eh?42sh80v|L3b^xo}$Q zu@hE0PuxC%!!Fnd)17liNO(IKv}UF|j^YdWJHg6DCFLrl_DFatXJ93ah1d|P_-h!C zZ{(Mxx(LMZ>88+sh81fae^+KO5D>Ay&_ea!!-}T4$v=Kck*he`ng0V%VpXpl7mQH+ z4Roke;%-f6SZ<+_sF)$k(1e7s5C%d@*3fuaqQA*kVDiajr?7r8jG|exXMKN+XWiaN zgxqJfPVO?e&O6Dw@csBWd1C_EC?6&^Q5_M(pfDp(F{fVLKUT(&W2N|ZA0>-Hb5(_w z$1JX6Q`Y0zPwb(;VWz|zXX?YC`z>|~6&QBz6MUZNU)}d+_b63+JN~E2ajF-KACtQj zK(5oZVe5%oEP7q?+F8SbvCSC9|Lc;)v00m*Aq++L%6FloS|_f9i|A3|TKL-aNJY5i zD{xOj`G{U!*Aq&8`ib6BiHSixPeWg<&9~Fid4{Ip^i(YQ<dcNr197t9oiJ>f&c{Pm zK=kb!Ll#r1Hn`N&C=m;+L|z0Zf-hX{w9&?l*Q%EAZzT704$t4X$8^z?@_JZm+$thj zOd^s6(_XZDxMH7u#c;oF^akuVGqWhjF^dz(AH72njDa46HeD+8)8#wY-!j7#7hG02 ziXttAH0$jjs%GqZt$R8Ye5>Xf;iu_Wpb`|F^Yu;+R3ya_=-NSfQKPPsPty58-=gMt zLYOdEHp%f}U0^E>#XNKj#i+gTXNBnl#GVOAp+k;AF3eJ+SvN%)#}-#eyYSw_!M1*= zZBOKqxVRwd4eHktJ_Tj*7Z!5~sW-|c-&Ea!?;Go&&7cTK(8HLq!0hkkW5A;8)QC9; zwR^yMxbWo4$Mmzh%O&JQBjHm+e1i6zU^eGalgv+jLjLEVqmCF^lmQ0;QHKHnA^l&1 z?%(1~&0Y~*1SPK|RFsAk2Bw#+95Pi^Sy`lnDSU~Y!5UujL%6l4gn+>F(BWcomeh}V ze(2k7JgZ=rz<Lzo?d0^#6k8M9?9^r5&Q1W@yqFJunSm^#Qp&=4a-=e+q(#gx90|ER zG8_t*TDtcbV6ZSm%&Tl>%^%85`q6SO+fuHb-S@zG@o{<c9mjOKil~lU8Z0=A(j>Zm zo|M~7VHZsY=Q0w~_B5Q_YjJF@sh~zSN$k&wB&M`P(GDM+*gTI+?W4$_L)9H=>r<Mo zTu~)ajrO}i=o?)wFGDl_KR+=yT8`)>6Aw4BvZlPSvIu52YN^?gDhKOsDs6n(ub11K zhQI5c6|m5H+B-QhT)()R#s}<g<V$ee*u072U5mF=D^Bi~9D9M@ppWYr3?PJexfjuY z->6}_uubNnNK4vcjb!3*rnaxQINVg+Y^b46-{f!LM28q`!HK2nI*D(a6NzCC9!EJ@ z&rAHImFR3}BJ&eAZH{wE{<cVKBTS)x{{kwTf1$IEl+zBJBZgN$+X(aYo|~d}tH{!; z9^#4FO261_3DWP4FP`nB+!6rA!5zhN;3M9uC#0iC-{4fnZX`$Ir^ym8qo2eM%#w0p zv_oEVd44|{<sU(<IPs=sHip&$XfBaw4LYof+$yybgL%j+;lE{Dg0{XTQeNB>j$1)# zdRPyuZ1>L*Z}Jt>9sgQsJXEpLnUngGorX<kHh9GISEydI>6&TLuo5Xzn4{>-`3V|D zWtD&yQ=8M`zWV$~iBaWy8ae+*8?|Zr%eS`$hXY{{6JUhF|6(wffNR|15jj8oNXRpa z>V8%H?sEVlb^*fhu>xo--HeI>96+8AUvI>h&T|65D_zHE@Pd${mQ;m-bF-eOWOGt{ zf8ggvdH*<{q7%MKoF)^#VvuH-;P24Y(~Gi>ZNE4U#jzjK_Bu<8k|>Ah18L?V=G{9* zFd#SF*izUMl*hDdb_zFyw?R4KGMCai<`%+p?h7ujgj#*w3@x>Y#U`P>8a6VC1{$T~ zTTW!C^TWnUlmy|A?v;9fnlosgmQcQ`SDo>7;uj7is`HlSjj>3?{ZZX=_>NH$yZ1*& zwK2+Rf&Q@|XZ3vP+kZZYsm(*QuYZvr5*Y-9=6^YeB4)-;ZvV_DHFZ5V#8EzfIg^dH zV<X7O&_pI1I5F1xo+QEBCzo;@{_1RIx2I`r_DC5^qN9<y@8`KOd<N|gc17X|2eJu8 z0e??u=t(tf4hC~nZDqdnX6ELmetn+A3xVnlIG}wqk{NJ8V<FK@iZE?KM!r#siIU+T zY=a}Bnh!65$b)&w&G5?_!pn<XIf3m)x$}kmn>G9tHb2efqz7i3pN_`~SVYXO@mg|s zSZVorSLy7}khPdC$otIyQoC<B$Jy^;!F~FLn7%hyc&T=Wf8P4)5}vN7yK!jn3Co0e zblO_`i~mZVC8w>1YWm@=vZU+coHAgH!@<t=qgD5ChSL+rf865_7iMcEpUs-<{k>=i zZ8g{Joonep4fuOS!_2v0mGH+*n(;YnR=b5R7EsBu5n+^^D=blZ8zBm4Xz!ff%+#Zg zf-v4y$6;`fu;GH4LYjQZXY_nanDm`JwoUdZg}OZixP|9@oJi89%VstxN{?0$e53KX zas#pF27ij?sox^HR3|YIk=k9Mlj=9`icm$WPqSS5{k0y9a1g6F6|YQ3_f>Ho!uhna z>~G39KngtEz+ua=A>p!IH~Df9ucsqGa#46B_`5WIIvhGJw=nROujggxo3^j1doTcJ zcGezFL((SQgiB76tQVC}k=4D}2CBrv_qO@S+kcm<v(7Lj@Jln$vFZH=<a$Mk^)t_> z`WNW1)ipP@LB645UNK};cJ<n1hqX>RaggRT)Hm90t#!qj@@+Z%a6@+^$qdB_AS~{) z&*asZ-*#c|HHxSz?)&I%Cy!A%9R&fVUdgIjlzK<UxaZ1&7Sim}R0E}r!L#9}Fe>M8 z0Buy|^Iy0Yr5vLkTR9Gz>cEL*vkA*G^~GjSm&(%l`I%J0uB=;33&~L_wmb!&xRaTf zQlkMtL6|074u+nWiAD6@Z!1b6zFg${j}=84JJawzJ?s^R%LCAd)CH&&erGB-W<7Sj zc-_G}n+QB)hjhPzbqxiv{IYk*4Vf3Dn#6iw!H+1DLj0q9I*vZBKb+7NK@u1z<zxB) zL!#T|)FWSnj@qC2+u}zZg+)HSlapJhjylnef*UmPOB(tPXA21#RU9^3yv|c$dSKzD zNP<kSXUvn1wa2aJOXSpt1$Mv*(m61JZ7nJwn^fIGsw(RA;O*fP5yxiJnkW?-?CfJ1 zj^I?7M|6D>Z%WrQ%)*}sS-`0(r$iEfLqKs+H;<gm+s+U9Hy7T}4XS|e(IE{2CxSGn z<qeC>evG2D98O(QOtSoMvPU;$fxgx?WZ5@o!!lzgNim$X3s^H|Q7jYoDA&^gZ@f|K zORx{d{Y5B%$jm<TfGYzCJ%|w~NV0>eOUkeoem^%Q9*E(59TkF+3YgjZFcL_O1686e z`IB@T7wMKkVQyq%w|syAY0k7HZ&#G<!kRnSV=m@VTo`v3Rj&RMwpi}gkY#L)KY-x- z9Meq+LI9eovYjT`8o*StF_(g>w+V3pOP9Ys{&{g+fIxTVBW{~FB~p(t5<H}NNvEh! zYqs1YUp2GOiY6ft#GY6fzn@`~@<NbclyC|a3F!C3*9_%ojM%RY!LtFSn4j{VvpZgp zmwx<@uX{1&Ik&-RBrl*;ao(2jx-Gwe5SC*%8%ha?Nd0Oy_(9z&B-O~UYde00Z`~0A zH%>k+^ds)BW*`9c{{ra0lz^d<og7#H0w>Mi6#9PyP)TD`H%Axme<U<~4~{E>P*6}} zP(&V3j2=)9l2D(Ag-b(8OE*i!yYGj;m(V1`ToCi$3*A1dhZ={T@0N;9>gxsd0!?L2 zL}Y9dIXER~BqFUThF=+pC)T0KEApW+!mOHq4cXRmkcr_Xat0$ZGK^2nKaJB<j*`yo zPW|Z~N?IsXlMDki(zlSDe&=J|9LCHs)Je%XPs;>%%b?a9VPNSX?<-e9E>2Dq!ObU8 zDv3b=Gn#ZoyI*+tNN!X~mRrTa#lg+M5&jVwni!ZF7#avF-vl<iCR~W{TNn#EV;J_I zHFTJNt&m6mfjg!DTkO^p2LYk{U%oFg_D**H@J$OZtd`o!@`)al1rAYF5UGu%L?|f5 zRTLd5?L=vL1my%XzmZ$UK&A*qq(Y2L))uA0hSkD|UDB`?2P%0fi}iX&iS>eo<0Ivn zV{55(6G!$J&r^>#TR*YYMtpqNj_a)dOpjyU>)t>(s8P^!1+J#<o=A0EsHU?5eakNw zX8=K7^u<*BHk?H@OA!#RL2EJ?!1ha9WI%_lQbT&Ta~n=Z%QiH;KJAIqX?`p;IvP>W zj=g9DF1Q6!LC>rG=B{FTbKNYo=ky>=2n&4GWMo<cC$a@=bMQeU&*A8oHx~a+5O#($ zKJrIIG<=QGXf%C$?g>-tK2mpxOlL~;B+g-chdU3pX2z{7o&54mdlZ-9^e~5>-sCWV z(SJ~`E;=;e;KBJ>wR<2+2$+9A#N@Rv34gWk!_{<9%H53{Fg{#Y{lg2sZXH;oJMEPX z>39<A>GTB%YhH=5*U$>{bav)K-T@BxblZHxe#&(2gAA}A0Jq?`8W7|66}tB84+_uh z_JH@e86>m#-5iAe?GQZP<rW3IZx0bU`!)meTO>HPAYL^1ZJUK3JyO;UBjaI3U-a<K z!2!Q#PN2|04OPbj#{H4?)#pIWtkzAu#%k0oYw^kRl92PoES6v1Z9pJb_ZX0gr9FN6 zISSKb7oPvF67p+svCjFH_uC6po%dplqxOwGonGkd-7a7EW8J1ty6$!6?RPr8*{DaZ z?(v|nQ8udm8*n{rxf*0`(r+xw9P$^V7Vkqr0d0fRc=d`e)d5;JY;@HlmJH8|8qoo_ z4hw6unWaoPA57X=hPUf=-oJM?Uq^y=bZ+^&S7UZ`Z=fCWn&D8SlSNT%NTcA<6(X#v zB2X=w>YWH}u`~>DEV1B3mn2&-2Q(T78rBj|oW1XJVv*vd+~4kL)!WVy+Pm{gY%b(O zaQap{lo5%^FKm~E4N3?KWtw{7_o`tMj@zJ?L~F!s8Mf2<8?jm>B*vDo+933<_{&xf z>~3Gw6p0;svv)iB5nV7ZBWm0@ya)oZzS(E4#WOUCa^K9~>z-ez?@aN;luZ_WtFgO% z<*e+*j1^o~w#0&kiBz|#kyJ{}DdZRqX{?*Oym?a>`gZxiamaG|pu40KOX%&t+@}3- zgzHOZF4Tli&&!*MqjcivW~T<<qcH8jAuPR%7lKi?aiNI~O+^=p7eY=tUF6)CP<A1$ zr29U!&64QEj6~=B0$wRagxxlOu(hwf>$(ID^H9uOdrPXrT(L1%EuC<2_{k3|$;zw~ zM;vqN$`Lev;$CHuC|z^3B#PrMd&uUEYLAbil${0NllLPUVs+o})Rn!W2gN|qmHZEX zN9hcz6LUVe!ZZ|@_Pe;hjd&<=D-P>zMYfKb5GtqO0?$Zew`f~5gjv6(8=JO(A3g0C zSo)6gg@yI-6zOkpSCllf2St-D$R*%dqbBM%_#XG6=pnRpDF$2XN{Wx8d+A8oZa}zi zD)3~#SI`QMy))uDu}u7DhFfCnLJgT{`O2BB>3$20wZ3s1C-fdyF0S>5a&yE|-Q~6S z_knmAfl`3G>=n{XR5?Sp<or)-GMHb5HGmdv*=_nHX+}I4F+QJg36F2;8!C#rdY?Xb zOtCil!RKzz<9bP`XrkN1yGBCJ9){%R9$O+{66>5i3!KaSJawy0YkMBc48%YdYGeJI zicgCyDi~FOJz`c9ytZ!iq&^j*90{2nLIcUuk`V$(C+ujLeeS#v9s<f<2r+J<lQ}5@ zg6hEjk8@Xu?illLt=qA@>j_5kuN(sz0_RwL7yKSa!!W2EUGTMltp_P_E*8D6i6w?1 zNri%9U$S5fz(PhtnM(+(*4WYS0FLi*1u!R1KC3d)jO~QY^{l%^55MPVf_$>4Nkg&H zxNP}G9wt{TY$h{jL(-I}P(pkN7tcN#Uh=keC2??($1lw=pN7(7=j5rL2@!uoA1#QI zsgWW?HCxBBJLaz+nkPzFVonB9FUwsC(#pLqSDVz9O1Lq9$Blv5)f6bUtI$qV=7e0T zano|E!HO$v`ZaT6+~6T7>Z5^E2iM~uaF+D8K&nVG70K<4r^guKXVXW*?9m|KOqAC| z)>wN2=%^E1r9kE6ea{-KN~%#IwJkQ(8}o07csD5selS*Ms{Qjv-!$q^`$cw-Lwb{Y z&!lRZ14Ruh>ko)Vdqd)>NX2+*-8vqTIe6BJ+t|I@8pVKhc=Ck|20?7P>mSuu-eCDb zEyX4nfcM{oo%jZh74<!Q<=bg@u(0lx8xk}1>{dQvK#cF+@JBWZ`g)n;8`ViX#}5M? zwQ+`$TIoVovw2XBI_Z6SqERKztR6g8^XoYl!(8QoM=AYn=YdHn;qUdKDV54{sq~<A z7U38Wjg4eH{p_$o--FW-FqW2;-^nzPkZVuG3o@b@@0;0DJtj8GHzeU>ndTM_m9@X0 zQ$cTP1KRQ!b?AB+1j{<-D4IGMwb#9%M6s&{cWG`I{VF3sZ?eGZoNoEMjj+Hm6Qh!4 z0!3MwZe9p#=)KkhG03GJLA^dgth-%ONEe2Fe$oqdeTyztxSTDdf#U}cP}|jJ%sbep z@X`)!+anCAj(8H8NRX-O+=RpQLhvu^cV_&A2+$ZZI-X(i5=TAb)<zZEjkicFh$t|@ zflRu}D%>E2ty(*APs(Y+VA0Ddfx%C6vW1}e?$LYcm!#8w(X!l$X9rqWGjrtV!FL*z zyF{2rDhX#|PI(#TIc&wcZx5Gd+@T$#JfuZXWyJ4S+K+ux0v13KMbnp2y^EH%w~JC8 zw7Xn1c5?rU;f21fB93L6!tgt447DQ)hiZh5G+u`rvW#}$?)euzCACRmh8dRlBZf%u z;*cApCD0P)rx6sA`Vc~*BNiJbOSCqd?v(P79*ZI>B!Y7<b#cy>8$T}1Hdg-1qLD2E zM3(&n0}-x020`4=0A!&wD*P~MNMzYJf6RuAafT5W33^mHOl4BpNQ|5!BUHxX4F9k* zvdAg1JJXLQ4j!->Nu*6O@Yu>};-q3-%PLQAf-8;e(JH2kXqK%cSr<9=L~gPP2vjwa zG{|dHPL0N+Vtvkhot=Hn4-$SYlVaf)%RE2Y!lcahplJDqBptnKG<BHF57-NgIu0UK zAusy;dVPjU%m%1M6v-z#WAz~&=UVM*)gd3{A{gjWnnDe3OyyCARGk~%?t%y(D4q&K zl~gAndDi^CavP_r9SMK#2zYQ9YgcPSl$8-3op@vXo;0j|+UP~1+;@Yv>5GeoNvx33 zjd2^i(CAd35K_*Ftg*_uWS6ZLYA?=jJjH=b4ROK=>7401#|x**Ly~(M;>pB;nDu0j zcO+zDS3fiE+M&X``d8)_#E-EheE<bOAnycCwtaQk@FkJ0>3Bo3%WCHct^|9u0$kjH zo&&0Z=_<>rZ|_B_H~6xRaQuo*u5*s|^GofN6z(|+3WG(1HmWYO6sqo?u0(UxJ$2TD zuz}<q^OSv9XVS=<JrbADYRkHf`Z90{0%q%e7&2;=(qFtAh9Pa~WeG8>-B#BgaF#TZ zEHZ9J8!cghEICxG9Z$+=R?;PHr#Uoi5>Cp9nohgVO4KF(p3&UXK5$^pRJ&-2m7cuo zGaE5x$3xQC;sjR2gLyoTxi8z)E{m$!bl)kdSG7y3(KoD@ViKwSTdiL7og9YOgs5=W z#lZODB324@#rZdmPo=wsvw(j4>~kWzv3UNquZTZ-SM((CneFpWqnFC*VtZlI7+rK) z9WCio<{Zb#5w>xFva0J3QMZ($+BeMF?zCko!IdG5Gz{$28sZ*GhGM^Y5r-d56Q__8 z_nM67c)PkEpe>OgKDuBd8)T?@B6#ROPwRNIo&~n%H|d#T4@mX#d=Wygz#4kz&cx34 zeWFU{k!Eh6{j;Yv73A2==kWTb-5?p#(ziiT=Zan|t~#tshR>`#xb>$<qJavqsb*hB z2fIY^m8CvyRhf0Pd+<TY%F|QHo7-0|J;HV_&zxw05=c5YY;1-If)t-_@T7Vg)bzG7 zIPc}6_x&ZN2-H<TnWe;Pp?)?#p<o{#%!u8ccLPJ<>)C6zs}6ZXBZj=LUz|nnQ(f*3 z{s30`r}VH<Bbksv$sYm=tVEZz@iwSrDGhxlflfiW6M}N1-*P41F+3cG&FS76X;v;g z?}*eCyRKgE4pPML4NW)f4yQdrpNKBpYjik3NdM^#;-#Ezfp_^lDAu05%3T#xmyUC_ zvpZev!NWMgKjqihr(Zb<pWTB=pV&5vX7uKC?y>NGlrKTTp&qHQMQXm!h{`@d>$~?D z=F7UU5NbKMr0nxTzqmyoo74Etr+2eosvI15sI?!4jb{Nr$3(i@asx@fR?2mj86F{v zE@{AYNGqHm^?y8f)T{J%Np<NfFrJ-8kqu`<0F}>>Q%x0deFjSi<t!oZ!@I|>xy!uJ zxv<kxG_led7V;wDy8I4~9IXz;$PfXSZv)g#C%u`8bu-_87ZR9BsC%o6xHB0>y$UX= zk<iE^sJ6morqlC+_e8yG*;P_sJBOsl*JGun*HAO+YWFrKHTNGGp6>JcuCl(64-#C0 zrzW(z`z|ukG0}-eP$l>oY6)v&m)VlNPLOE0OB5-+<*<~*+xPgl5tA23U`!uD_CdzR zB^Xpk{v6g$d=OYz2u$pSAttwlp8X4Ly&79l7Eezded!REW<ye4jI-_`vx7-N6T=sD z6LL}TRVz$PI<1Z6NoY6ijdz$Av1-hfBFlmYN){ZnF7nCOuO#^=g20n^Howj`iMye9 zx_A`Hqc3$PdUsEW`EyJiFugr1cVEKS(Nq!b9+{!@bl&D9G_4no6AVD3txpb`WPYN) z{CVGe=y%HKOhY}5`tHs?PW(Oa@2d>*(Uj}9-S4o9tEu9Q3Bd%aoru<kn6&!uS{jrs z0-G;Z`DC(RWRVZ=zZ0$WZa6^Pj*!1z=RPLIbaKx<U$_%4X8Q;pbz$y*`x|Z>L-4~O zg9@_}ze5qF)tKJEEW^YPI+}m6JQF_nE82s`tA2T<`-Ad>2K;>V^Uq0tX!7~UsaAc? z)UW+cWWfB`BmKoRFxmJ4*G+k`vWKYM2kSWgYVQS2Y|Sj>ry4+h`5k+^==Q1Ni6i3_ zd6(Z8Nf3;?7ChtwMVt^S`2#e<pCDxu5FxS(S@m0LK+pahWYRd|xT6R~cMJ3vAOc;f z1d*B@<(puFFnHu1xD0zjHDYt%aGqQ}(!!bY4HxaDQAuN@EVA>c9KU^-b3N?w59Emf zWDb;{ebaMrx_e)TK9M{*KafGpF2wdxCVoi`k&)<rOU5YNMYo|FA#hbV*x8}r5-dsT zxYgAeXHH+`BOV6m;q(s+GpbyA;ViV{i09zQyA^*6BPp;56F6Z;px8z<-9EZocMdmx z7V(Bt<-**r*p$3U7p0$121#WGnF$=20|D+zB|u^ilDET@0zER|v4LQ#pu<iwI3;oj zvgtS}jEM`_jU~!aH^|RZ3ANfYm*dvqO&)=%Aqk!E^3ceE_Sh+eL8wy3<OM>s6itMZ zi&-p}%$yW*j#N^)?cnq@YxW5q7{8a<Q^dYH_?JNstdu9bXxB;V2xln!!97HB1j@iE zn?=x8&^;4>bOgXqUP5K}5K>-;xmA|_4#PmqZ!cm_jm!6-AEHozuBEv89U|V2q_XFe z^oBT8l%FX14%XTq>jb(9(bhkm#Ac269m?{tUr6Qx^;5zgeK~*e{ci#@5})A}Ve!0= zJLvi9Tz{C-Dnip1Nm+WqIrhtktzFX<;%>6}bE?u=$5aC|+MU<a#Y{2(xRbq&(887O zk~^mD#G^l_(K+1c$^gf>Y@px~kU_NzgFz7ZLa1b=_$p{F!iOPoDJD21uF-}KZQGS^ zWP2783iDFxrb<O`0^gmg8=V*u^D=*C7hLK=UCNfORwAX^!Y)K9aI8$dh8X#HSdOeJ zTeMz4Z)4~)MW&SG2#5!8wTX4aDOZR`jPe!?LcCz1x%gKL2(%KWxhhv&9$_|9ZY?0u zHQ#G^Bv47mTRZ@`JcU!O4e`ZKMw@f>s*G#LimE8|`AKg{@kn>gO}aB;n*W@lSU5xI z52o6#K!Bq9hFyl@d$$0*G*4}V=VoC=468)SzC`>6J6>VY$uHNfsH)jO7l}+2<Biu% z2d%koV6w)2RJ@?pkT_`Ke%@iXi0Ji>=K-XbTLbi&~#a9EQ&D@xVSjio+tWn?&1 z73`VSvc&Nek7aAv5C-yWNK4=~>p2(lpqu^q$}g1+G0$hL!ow=dzcXW?COZ?;7b)G7 zqz%|S!;Ct`nmR{T_hH|XMjm?(h8K!vpJbhw_h4L@)$9*9ZU?rFzj|~l{(8H$*X|>e zbYYN$?W%SauLx<ws>QM$fL%fHtHl*uMiX2?$hQrf<p7>!?YU0hbXYvA$vx|xL@cA_ zxgoWK{z}l^5dmBRT#oITA+AWnow?*ge2pkK;qQ%vI;ITKbD@ne2}rAne&}!`#LfX` zih>EwQQP5oVJE{Q&_~BgiAch4sXqju6qT9%(}D&kF`{+~=iWg>58|!<<lnISfd>eO zShC>eQ85aITi;L-AO?&y+<?u5VK<-{44Qc1rVrW<U1~Of8H~z$fv@yupN6z4hkDM# zU+-ageQN{mI6>$1)9rzG2R^%@`^B^kQhD+DMZN8^Z6bdSlHKqKLK*I|-B9$x81Cub zaP)%j?7}`{^@UvD_&$pa6%j|~9U5juqDGitNJiSRM-s%Kmf%p)GHcLFRcXZnhji42 zcyO3<GKle5l)ac`o>{c@BEW}YGiV)#MfQp0v7h!(Zc!{E%ADKXY8{h&V@nbS8P!qB z7I*1vBv6H<RIOgH3M0_RZwUR68-}v|o<RXYq1@82*tc|HkLpD~4}tOopo4r-BSfLO zR)rk%<aJ%lc&7d0-I;Wr84+}uE>g|X^CY7v*o+I7ia(;jrrEo4h*|j2MSRg1Vxn*Q z>0>15GKP4_FRz*7m?<>BAt3JKs+n17QM8_7ghIl8e*cjM5dpx9rm(+nDoIA<Ogom< z)Z+xW4z*k5T!rhuP~ysjhe|9U9%8LxE?EU8et(p7IXIL;4)kT>PAU@2#7l1cLBQ%= zQ>xFLBA~9?OR=>8n*yg8yBC)3k#Y7M*fmyFGE$rkYoxs~ewlS`EeMgls(c60@l9K5 z9FoH?%8}`aaiM2%?UUMyPkRa&c(aE^lqbD4J!)JTcR;e*h`k>_`0G677ZUe14s!l% zpi}_^p_2$ceaVRN>L%1Zu+5AGhiH|uf7R3!x+~Mec|@EqDQ>XQ=5bc&{0Dq|%g5X{ zRE0Sjp~<m?vJsV~mhTPm3A-2LuLM|Io<0Auf<$?h`uXC&9tB9Yfi(TZXfmc)H%2_} z=bZ}mA%IrkCgL<D(u+XfWzB(DIZ$hdEEB;8go9@wKOM+(M>Xwo<6f$Aha-3~;-2z* zg(EyeFcJsT1tqs9q*$?(CQMHBt4s~D=7bz^<I~l{q|cAR=>@BY9PnrbSIq}5pOz*n zv}1kus%6jinPABxhD2vhoH9nl6+x>oN2n%?NoEP%)T9|X0AbCuDzv6WD)ifekb%ga zCV?YNhzXW?DAIxrK9^%)Xo?(0%wTNVFapp?Il;sdf31tFnilfuSj6&a$9n)%b)s5X z$#~AMeWj~drAt~jWOBff@pRm8a}(rnFXPS;WDOXt!{s)NEU-!Dw^JsID+i=~p*ULG zM0_L{o_vY(7I2e)kFG;1&hdP^Du~mgm^D_&V3gp`>wX|WYe>7R2^I;d4el0aAW!I% zALbn+&bJ2o-~`4p=e>W*|LG^#l=dG)l&go;Q0jxrE`a(@?jyu*3LohYZwIWY2iM(m z;YY3=xZl&+v>=~zrOA8;n9_NF84b3p!a<wc;=oEJNQWJ0zlQEQ<VH3HXR@g#Ra&|V zQRa`;#B3VpI(f5uE)b>5a5mh-RXpGI&M|ZiS4A$__6PBi5P1TLyEEh7DGqn*j7Yb^ z7M+lJ8g+qppKDN!O^9Ze7h^7yl25!Yq3?3AgqJ1F@#Ex=W%M|*cW?zpM+(xB0^2n4 z_15sQWF~(Xg^@;OBDXAbx1j+uh)uH{Qy_;Zy03(E^y9=W`uek*>H9<vGi}Cc*tI-7 zLmYgZhvl07P-EA4@l{~cje!f;TZF=s2&lv)8ozLs6U?sz@Fb$kB+a5lAXH+-fndCo zWtesb%^_FU{UJ>5Jg!GYJq~}vDZjB*k-L=yZ?hL)XvEPULtM~9N8y2RpzsJj@j(eK z>ln-7eDlUSlnSST`7F<j|8wPeN)_L3mZ=ABcnra+JZy1f%=tRfDlRWmC<kOdF@sl9 z%qh*-NEvXZ1^;Ayyr?8(E56neA?9uW%=ji52B%vZr&}DSTOOx-0Ul~?1d$=^xOTyb z*syj_Nw_7UGg}P1#G}2IPt}mhyBigXSI@JFhTt#bdQRu!Jrz)E5^>(eug`9}x}dT6 z`lAJ)+WgUPY+%r=;u?J069Zf*v8PfDA)*OGG3#%W(cBIcf2T`)Ve~G4G6L&$%&_AW zmn$QZz_E}noACm$-{eSN`4H^k`lRe8-VR6+!WobC87y#2*VyXRPH}{V9pMQrI-L7d z8n4`^<}V&Kc4-Oz<Ubc{%#9zL_9GbS(gQEk%aO)u5(Ny7zm7Mx&oaZ@B><iw2OadE z-w>WzSk1o3rXE$?GJ*m~DqMS$t&D_JGl80Bv`b=62f&o^Z$bLdL0cQdx76HK9c!Rn z@e<R&3}C|+`{!hqde5+wT%I+Cvl&rWJ?;oQ=LngVaFLxuCQgRlnW(e;VZm?dNMCG8 zUvx8Kb_V!mbE0pcsZ0Gkgn=Ki!HL|6B`zW*0|~Mdc!P#$IYU{vDH2u?TXnvxDh$<0 z4V!wocauoZ%MCwq9QM)+cNLn@AC*QRVN0Zp-Q6c@2%WN9<4#1eZR28r)O)y&LnACX zk#KAop^!-u1PJJn31m?HUK1bp)KYmQ3qQpXSf$6w@Qp_Yi&OB5Q}*R^FeN8!lBRzf z^}@GZNcI_=uM9GObbh4NiNX$O79h13joQwkG*<AnSPBWKg{dXo6QP(%lY&PLGi#AZ z0(n^|<r!A+%j?oLk<3D9Oc%WZLLEkmT+9r%7ag9GwvtfY8g#9pN%6yA_;M&*jEcuN ze!Ig|OzC+yv4pQ(P=iM*r;zu~4I5ZPz$5tPDt?8U)#3T%pLg~ONX;g0Jc@Q6f+KE* zx<U7Jp<fxhYZ2)=UmH}w4PfTh$Cpvb1m<8;CcLqe{O00j_=Xm<63i*RMC9RO-bvYH zy$S)^i59LM!Hti>5{Sc`xMYQf5kXTgEnhPE$i7N$Au2re11k|3J5oDLr)949np(`F z)sAbmF_+QBF{A>MhT%(A%M!@BWj~#u7K2o@|Km2wrJfKew0UIcx`r3~D*n8H*;U5) zSR{@5hqH;GJa(ut92-#B1}Y1siywsa3u!K5JxgkG*UzDC>X4cXFt;xvzCwu=+R=(Y zR-?7~EuqT?R2vP|tO3*|4$0*w6st%VtYlaVJ;E<x@Ly=)8hJ?3`GYE5js}>mJnO67 z7;=B6v0Y!K9?X3C`0L>diyoB^m^tJ(Gvs5f9OMfmr+RBUsYNZvF#t<R=&qvG<-z0y zqEY4HZu20xg^BF*keMcA@)%dlew6snDR|Ez5obRhuZHZRq~&qbq*lAXgxjXG$sB6? z&0mjcUXQs=4sJY7y&&S;pq>43BDlea?zV;9Bte{&#Zgk*NrRXdI~{x3!C<lUtPig| zc*OFYK=@aYq=H}lh2%}-fGFg|ieXj7mQ_JzM>AGlDnme3_BUF7h=9y=q_5IPuKNXN z;&$fL^BwRg*W;3}|I*EweVYuw1_}a_0r@{(F#cyZr@XbRo4Lb38+z2X0O%qZg2BQq zcXhjcCi|g1#-!qoJ`^dmu*E|P?6+YEU1b}A=3!F^5{!QM`GfF8{o$lJxW8LlQz4tN zKX}<r{Ddq$-Y$Nh(13IY4x{nY4Y)$pHNOURX^g&|3c{tXrmc=D;uP7L-fc@-ty|%| zd-YT(OgxF}{wDA|=W&<Z({x|8HW6RcHn?YQ{<%DVV4Eqvyj-Wj$kgYQnqEgVPA{Tr zu4M3qbx@G3vxe49E$>M(x%-B=@UivY(yd9Ck4ul#go|puVsg-@^QX{NpitMUMmljo zHZewMFH?yoJ|~eDQSG{RsigS0iYl(QYOQ$VE_P9X2rs-G$L>RQhToVp2L_H!0M0hE zHRaYmaA?G6tnNeYV#LaIc{h+IfE7B(F&QivnG0r{eg8+6cWyoY3$nvyN12M-gZ%2R z))_OuL8A`gYF2JAsN^BrVjv#TTn278Jt+y(k@UAroD0^X0j5LC>;+ymt2Do+00pMK zv!w+{Hw6xlC+5->6K`p%<1bJ@u@(u+WV~3){4Z{BD6(B4^dba@0qUAjt0U(e4_T)! z#}lNKH;=192nK!tR8G*@4>o3eC!{OLZsdDVZ2tprFPs}xeo9U##ZzC1ygcy#+pq91 zm)hO^(mNpk2FQ=Uo9=%o$h#OjIhmV@db^qb+a2_OROQW;CS`%b7y@mv3f}}P)iDN2 z<{St*Jv5c6)!?D%+Y_x_bX9@m@+!Ik)1lvXr6RdvA%=&K@_dO1ECl<ug+Tr|9~NGk z><ohzV3vAL4Ge|hqE~KhlNB^f)NQO{O@SA9_dN2953Uw7^15JG`2GSda4^TbO1`ox zFl=Epu7+~NMNVtN-I&~-8!jmB_Okxo3rp5Oq*x6=Lvq<zZsH6pisqN&j=$79y0IQ! zWPdc|R{fd|c`T(}u&5nbgnYx@tG0WB*R1>$=f&4Q+-vtk-D9_0nUGe@lAO4gEYTuE zp=DKn;Ta|2UPTiwAHZzQYih(FWDiKeY7L;_W9<r}TYZE2cW?f`0|4;;dvBWBS(`ij z$2kE1(lwH*&=sBfx9yJL?<@e}|F537xrMR2o!j530RKF<V*mQa|I|z}tYNRZA&KIT zL@+t#AZjK11B#hOsSgrTbceZw1WJbrAWbJKyTF-x1jNE*O+5s;bUY2PwnRH+XS;0k zC>5$)6wn@nu)BE{<0GmAwE509b$ND`^?kiudV(x6n{A2!M$GBQPl1ggn7AbLPjgdc zqJETQ@m;J}1;l&32)M}P)e{kW1t|H^C5A8svRcVE(u1Z@YtHgLHXVMm<~X!=*0U`F z!~3<O_feHtF7EniBtuW_Gt6ge)Eq0!m^$SvcG<eMjq(#&x-IGsLR@Zu$31T#>n3E_ zp1AGmAus4jCB=+Wg^|{~h<(@CB}a|bg1litrR{O21^)h4K0*g3&^Uuh?Xr>7DgW}W zP<6SF%xQ}~gh|d%wJMWwp8r^4`TtP%PC=qX(UxG<E!(zj+qP}nb<4J0w`|+CZQHgz z_2RuZ)7>#K-4l_SKba>o;>0>T_t|Uhl}bn4QxV09ksoUwt8E3fPG;<@x{ZWUr`1(g zhm`3i4v7X;F=gtaDsvZ!G5L;(7u5<)*LU7{Ym1fj`R&aH$qjGDi7bDgb*>8%cA{MI zeQ+5`$`oC+<9n5`3pdKv3ys|0m3YDAM!Kz&EvST3QeK?9iS%(G<jf<TGpuOg>c?-5 z^4EBQL4S9LBS)^yX$oV@tU6*Eh;V!u{h{yu*7wqzpU*L=FwqA2G+?96gY>S|c+jbG zZT+=Nrb*Gi78jYaf#*CBLfs4gH@;oy&wpbe_m?3)ij(g&<Dh`o3NTHioUB+0J{J|- zu5O)E{HK11w}cm){wjr85SXI7{^Sf$L&{VwTW8gv8w!z4U+5|Qk?3DQ@9tk=fX1gC zWP@J8I?85~(OsSt>CoONP8J{-u?MjmnvMO{-Vfc<fR~~N!cxZGk?JNOb%Q;rG7*)I zj=j2nkYBO}laJT~H3&*GOuB40l`&%ORiU<&?nso<Z`#7R|1s}GvG=7Cp_XIV;81eH zmSuS@J^^^z`m~Ib4~b{00oO!rd99Y5N*!+&glQ~1N6{@$>vT3ApwAL#?Xi$uW2Ifa z4r+A;)zr}u=z!(q98k_bs#^F2ZCw`>$=I`hi66Lt=(yS1%^O78Q>g2zsKGG!Xt`Qw zuu@?Lwsldh4DxBwd34f(_b1ul%|$P$Y2cj|5JK}_S16iK)e}di;vq@L>%|`<@X!)w zTLa)Jd#uq9J$(<>ZNFueSW|)~6bxB0U({n8q!$ISW0vfl42=A+-$|5V;}KH|J(c}| zpm;#buYq4@9}MPGJWB;HVWcBq5f6bUb&u}EDz=+IxOYh+KVZgu5I=Bf^>bb%Lm@(t zLyI1<&&m$?2Gh>PtCH;EXJ_*A8`U<aN9N?8p&G?H>w}+?3Jv?lzSVoYC4(O#KDyM2 zb!v`5uphpI9p;&4*O2wF2urjHSQZ`2AXYr|U7uhO3i)0v_zWryLdhp1A!v@D-ee!d zg1N5+OTQCWa%u2mh6G{b@lN7hH{+fs=WvV^2kEQCW8@RDSAciMBl>3>xXY8X>m9ob zggNqOE41)q)XAgzZ+vNkk2M^Gg1)HYpr@Y{8Bm8~6dU5LDE-ZY=xyB$R$svG(=4Aw z%=QMv`=o<2=FT%cYTX`=odVv)E92(F|6qOcA0h7taU}TaS0tzO+rGx|{~7ZBmq16% z@SmTbER~D@NKn2*Qf##(DS+=H0s<cYP=o76f-6gut3;8&7lg0bhPpbe*|@eO@CMiw zgiGd!-?hM*a5vDPNZO#SUtUhPdF^m8olJgyKYWq-xf=_D8`4I>ACqiC4upa*P=`2R z{UzQ^wwLSohJZu=BdgIsc8spbu|PT2F%EXL#Y?wZ{GQEKUv9N&e`upS+7S@NC6~C7 zU}`?iIAHyW>=RA{>N`yB7~-F4dW*Ky^{0h3IY2fcFSCsDJ;l(%a2x(z#0^?M%orw6 z3qz;QMm7QCrV;4@`PR?UVQ5bVWx!`+Gy}9kq-fusYHPaGoPsNch7YyIS(e-+aL{GM zIiHAjs2@2*LhjI5%NYFz6KHKN9XcC4*kHscrP^$1&Y7cR%}j!F8M2Sw(M!xKc|b?U zyiVsleV4H>_+E2NKC@f|9B(Em1uc8QY`evdB3W7^?|l)2^#BHVDru>GHswM4q`V+) zm`T@){xm`%;UT67qsW<cZrH5q_!hK$RWI3~5{vOkYON7xPKu0OT#bQdzK&Xm-A<Jz zxyH(nEkx_xMD<m1gquNmt8wgw<L|hsLcb!gcbM>OY$&pHiOSfuinBorb%+?EDxvxi z=79MK^BFv+h?3ISmy}~ct<*$s?LJPfNq2Q=jKxx^<xh#Y+py{F(2&MUu~TwH!r}1R zG`gVgIZBt69n$L3bkPugS!f0`ik(`ui`Cpts7NG3d$6Fhb7-F-g94{B$J^PNSW+R- zV^bLJJJ6o-IhFc708fs^av*v%U_Br!y|~ff7pxKZ2|jHgLZ%(Qb>7NQ)VJS_%RSWU z<0Rl`j;6eB8~Iqf36O}FPOpd>-VlklD^d79r07{SGParoA^Z3hy9Y?<4fseiSd7&O z`*3<1#1{Kmb%(<a{u(eT7DjhrOD}YBH^D8GqLr;(>@8?Ur@-c5QUx4gOwa@taRu_- zJN=d6r2g_2LfWu_M~FD8@E01X1t<JF)PJWL|EZ#6eL6)0`%TzpeoxW=Uu)-oSxf&@ z(h#j6BlVllWvUr17pq)=eFO5WMn<0K4(bz-Kf?DFSf_|d!*q~@FMqPYeFOL=wMvi( zmhBq2b8*=ncNy^gM@FZ;FRzbZOI9m~P7T!ro|D9oiF7@4b9}BMk*HCo7F!g>VWwlU zyy?iJao5IJ7F9vWbViJ6H><sZ^3y5{-ZzzTEMlYp8HF8lC6(u%ek9HAvrF9ko>oCW zv#N|1ozV-pH;!6nJ$sOlSZ@>Geid((-oV1G(q1nj!~PbDE^6CCIH{uHD1rVpoKE6| zmTKQ_;Bm72hTSBH#*^+s0CC`JcZ~$j^S60(B~I+N_A2fs?xfs)Gp6HZcBHxjF#Q`q zsOJaff1YaN>l!`SU+1Za-xgcC|36dxpFyff6T(Y*X^D?4Z8AezR}eJ;ez{iSA8<eH zp8#TiM2S_B0M$(5SYv%gBr}2_%_`3-E40+vc2yahvIxOHh60fwR#rpHMOB)Ahng&x zmY=Q8el}l@O&Fnxy^?n}J$H1bU1vNFlz!Ze@epK=eJ!~sWhMu<oJnHiidSXS?rxo< zL?xLd)92=+;!P`=OU${aWjIquN8Bv9F;m+qGA0g<0)~;cl12t}v}wPH(=w^2kS&TW zxu=E}wwV8sS#S@?47e3DHvoT>{rTIRA$!6xKbhRNV9YF+{$|UYg(j{<AXAi4;g%PL z3gK5Xc03f2uX%iI?iG?j>d$h?DRV$luU+6!m63YS_@;hceAX!_O2wi}@?{x4v*;F$ zT{Dqe@kSlJQvATlyD@cgy8<%XHeWfj`>>kP_q2&GQ!pIzh_%`HFC%Ey6yt5PGoEd% zM2}YsSb+Z^cd~JO@~xhLxS)189$IriA)3u<lN6aY)ig44W6K%P&gG7cxw}{9LZo~r z>08i()^R~IoA}U2Dm`)m(4!LGCp?N4B`OsnbE2qC5MSqP->&1863tg^TJI|Vg1LKG z#$e8mUhiW6qOgZI&~EpJl9uIL7u4qH#_AL3%nte7F5%eJ-zSn8$I)Vg`8&_+Q#@Tu zM6$)gt0UuPmy4xa>HyEmi%m%&OQDBywRS8_`Q2L-zkYNB9wKBt?eUzy7hL7NYp)i; zl(2Zwd~_s9rD3jPO$(Qv@W`yXGJD|A931qIbb)0+Ua_Nw){g07D9WfKmYa)I1)gV9 zh$&s~dzz@GzE_{46|J`IoPm$wUsbKqjde@r^-xh_4&^yq29KCRTSk6Q2gcoy9rLi) z0DlruF4p$`b1rm4Opnd2K6qD7qA7xbjnO2l>jzIDnWKs&Y}Ex!p=}t1Ju-+7OB!um zk}Uh3C?-+xd2IcF2vM)^drdp4<$1NY^gr9;%*OOGH(i`;us7x6qiE*oPM4G1y|YK8 z{I1b#^Rtu8tgz6knE83|w5^?t=rF?N0XBe5Fe95V-}<YyutkkF`sL!o(t-1__rTs5 ziQ2vZtaeeQvf{$H)%U?&Pd-3`L01V*)pWa&lSbndXI0V%EBslMfzctq@1jo;)jE%! zwdA1Ohhug7vg#zr@zP3+5pRIIr@rFrBeaTZS_20pT1Wy$eD4&^V*us9H0T@qBi`!a zuQr>}^t_DjDf5GM>th)cw`<KvD2cyDa)3m$8QesvG$m%#gco5;L3mjw><3rdP4&47 zn`wy~v8&r!)Mu`OnSaMaPg)c%omPIcb_I?Fcq;2NR<}r%9FDF<*mbp_x%8^bPs7n6 zXk+y#+BtjMK&4L^FaL3_ZxS_$;NVy-YD761FgzTG0Gn|SfkD$3Hg`aia1CsfN1jPw zWYpb;pj+gTHbv%Y{P72Y2sxrz^e{$k{5f2LTfQhPw=TbnvzZHbxYkV-M!lJC9=9hO zdN&O)4*k)N6_dvD04_8AQWfUIwfEe#W@n{!70Vo&&65q|&a5rkLR<01uKi{kcO4Ke zYZp)rBcB=C2os%63#PlP7z#H>ns=K&a4%HOpD(t=)I8H1e>1G62(2#W{WJvT`3PK? zpyp3vh<^HJMrE5f2%<v=Qv&=}O(5o_r8~WGI)wBLhOIfP=3qrrxyG>eG3e{KeM41Q zfz*2d^?Eu5sF7X@z@zA3o83CJlRA2sxZljp71eO5g?#cpR-jDPw!Cruk{qDlu|E3h zLWZZltc>f?vqxLBj^K~+#>=!sNYf4iEfS(uIR1J!<vxnhBn;@eVXIZ%{5B~;<zY~n zIN~f}{T>-_(1v9=!M`~=V2Ji2Zuu@gb-1nA0uPM}Krs0Yw88IiP3%lTWmiV9-GqJc za%P>|M_%%BUe$;T<VYAwuK^v8fj)k_Stucbv6go-UXZpCM-bPDx*^q#Ad^y1_&yj+ z712nwfT2;|T5=|TPK}f!B*Vx=u@*O)Q79~gj}6%rG*S^)M~p=Hq;=E~r*SLE5F>58 z!6#$gY5iX1iZO|?^SMA3%ILbLzDb(^z>S1P{a(e;{)7V^_Gk4M&eFqHHn!gjYrJZ# z9Wd~UcG!e8)K*2noP1#2C>h0UFR+6QGCw)n`>5cuTz27t+?j#}Zh~ov?8*WRr*~?1 z$->JS80VHa+nF=dR=yILO`zG8STi*LX4yjQnQhiJL6Th2SI_g9<0~2GmQ)sgkC@^T zxS@>hPk_8qBglt!U!VLRg`S>OELznll#l+QD$&v*v~cw3A*_JB{ReC0W07n%Z0Oew zF~}CVQ)jBJ;)N^cP+7i0Jc1z((1QCshtpv)d2Q^<9q<WoG*2N>2Yhr2Sd6(^1JdHP z@S-^Szd6&A`<`>RGlgriAI=`y!q2VL*zoPJvx%5L+9w}xfLVBlIIA;o7N50~my7Ob zf6q3jI$Yknu-_oIz@E<fn(<YY)Fo3>iO1&K{Gif6@%R)L++wF=Z*{Y_3tNJm_1|H> zP-7m95gD>@GKZNDf!ov-!$xKXoxeeD7To#xK+P7_c&hFWIDZnhmtOs*<!)=7dBIIz z;f1<;mftA8qlbHz-Yhl&e`0b3!nhoca~}-a8q7?3MzeqTKbU=FPfp%Ivh)rGIDZtb zAHcgtm>+)9=pr~jB~JLD5>j7Hvh?<Pa+R;to=YDp8sTDUbH?<gff9-XID3YF73MG( zpPW4e$#k9a2Kk8<Veg-%YiafQ{xW_1wN<Oq^Ugkr1eYy&LZ2}dDE5!EcnBwddhWZy zZ+SGl_0r)^X%3x^UZ+Ovnlr!QzuyX($g}wJ$>2@Uh;SC(jJ_*|b51`g_%IrRw!@RB zbH;|u$Q+9vc3v^E_)h4Y-xZTc;Znxj9f$Ph3*^@mA+R`4?5n4NIP^|>9%R`Qe7HoS zfASvG9Loyi3a_9ryQ&b{f;M&0FzLPL&VH;;qcuX#u#HS@nTIVBPSmrsFrzA)7D9D1 za7dOA*GRL46>|j*3?!!NKGOskvF{{B;*M<|-e<YI4Ve04PY+OF27#A`=SapPN(a$e zu!Xx}x{J-pt6ym;G*TZ+@3939X6^_aOq>NFx~88;#<JJ!fyT}*+(Vp#qe%7CE&4ux zgZ`?fw-^8Og<dhrwwjilCy>#qC*Sqi9UOsaSF`$(K-Y`b8N8A}0vKcwr0m1JLE&8u zm8&90E+9BjNEMQ_4cW9VP2lN`r#yB&FVbcnndWal1J#OhW*hmjtp}NND@hGrM1f_4 z0LdNOT*bI+dTb4REr+}h7xj(*L99FK=p_pvG;hTqsza=tqQ^{lTexn+{rfo#oeG>t zjNiG3-acdU<z$_%2dmWc1yoHueh9e%aNW)ol+=|4XI28S;kk*-(gZ5jw`zR&z+zp~ znA2`|&eVt7BkF=9E2imI@)?vC?ijI?sUi<2tGrqs{AE^spjKIlG`+>s@rC_T_)>k( zp=l`@JyFy-8+COVA1Rba3a03RB*}!c`ab1F-JnG#-qZU4#7y9_3+0|TE&<72knv6E zh_nWRp0+Hpxvap3O<O?jkzcVX(;*ykbBWH@$$~WF&Fo1I^CDHeM|b?+RTKrGKPd}# z!0E=ezs(GV)Q6!*eZ-aLWt2pl@b^uWM&dTnqJ@Q*GXs(3NuDHV_(O4zf*6IJ*mUtd z?cnb8|H!Y2rG_e6!Ado}mGe!J8{r1g<v}cjDuIEjS*b<+efi;%&*hZuL8C=i(F7%N zsNf4b!$WY0&LrC-{&fqbB@vR~BX}tLmx~dUdMpN%i*b~CC<m2`ofUc@E0v4!fT;g1 zztefmLsUNSRF+fRL@<F%s0Yy_s(UGUWNO^FYl_2Ol}I|H*pljO&QNTpa0%u7c51Y3 zIwi?EKl6!#oSb?D;3?%dn}>y;fjksK9c2PwMETYGYYuN6iU&2vGp`rsqGWtno6~xz z3na$V|B`~&!f>sbAg!>KO&;wOQv)5N6w##7Qt8eXoAbtQ&k5bjb24ci<W#oY00);% z?AZ;Gj#6+6!@A=@6F@JiIQh~TC&z!4`h4WddTBRAg0mqy%;RQr%1`+M9p{?;BFd6v znJ6NU<#Dq_1I>A13M4T_q|6DI=B+hFBgy@~1T-a17BC^_+>r?a^LKriOgE5!a1-$| zepG*tNMDSxr{a0qC>N_MS8b<qmpz?-7sXpCmlI1m@P`eFnQ-d?f6K=rkrk1|(}R;N z;CK=a?G5(#CK7N(Rcvr{;dG5{sA17?kR4!kGq?&fLasw+L&Il7Z}JH>F7pw1C=~$o zg;xYgstd5y`{}{;p{eu0*3_}q=*)A<AZIlb=egz3P=HKT(V~S*T;@uzSWl^obXxqX zVaNT>9{na8_^(IgN`0VvMr>qL$h(LVR|A>l0Rjom92H}o=T31T$ZdsuxsrCL*^xz9 zmwJHp6VKgImpDstf$V|!T?i{X1ZH{gU$)uRJrEt?W|2@AF(32E*GRK4=969LR)t65 z_=n-<0sdLU5}0k2r^@u?2l`<RIEe4L-4C+MN(|PavEzcoc#rhmS$UMB#UQ)y*4kS) zanB*o*kY2Ab|q?;=_o6b0pVlmg@VMQw@B}%#$TNi{x&6tM)b+6_N!RNd9a?+1tdlE ztr_1g3(X;C<WoE{f6>O|m%Z{BQT6MfuAt<Dhwf^+Dy5y;v&p!Hk=hn`5fny_a}CBz z2N0!o>Wy-SWu3O0OOh3>xbeR?;`p8BY1pGF(Ma;xhX7lc$MK^Y$3by&KT`i{vYvTj zvwU;g9<gb1(QL*~`c+|#Vo!yGhlHv-#nT>(myK{fAA)OJ&#Z=koadnBxf(J|T^7o+ zlvNK5;+V|DqDR{M4q!}@sATfS4mx?5cL0aDaA02uG;1>`Ev=7Z?W@M@OtRM0XtHWU zQ5mOPkvX2>=kH<LMMd?HmUOhKgpg@XbexA-7b@G$B~Iqh=oJ<O0;NnqdmguxHw-G) z6)R~ka{tI_u+iKUR<7+AHs&|dYKAAP;E35>b2PUH-UEA#%t?)7>o}Y0oXkBlrgE4k z)5I>M!={rLjF?Yd{yxv6Or{J=!QxLjslhOrCB}Ek%~_i`yfSQFw8t~hsR?H<!_+k} zGS1by=#4@EEzXDdm)0BOTJAj!9Gz~?>XEbxKTypHC#&e)<1(>3cv*Ar7{>gMfgK<Y zU}I|DRt<l~&!4aw!o^O}qDRi$ZUH0!E6^^GQM-dduGzG|d3ZN-ZI8Ty)1lyOcm&|y z(pQga?f-ZMj_)WOqh@wnzCraKIGj(QfV1fkB)<V=J|Q(<==8tXx<Exd6Tg8<#m<am z^XS-7ey}f(nWv4SLmfeL`Z-gbNOQ(DI>W$jAuB77_q0deyin0@J)$n!;;>r7*bIN| z3po4|4RD8d4iO|<Y63x^LrAbgrkU8Cv^04IqO%9gQ!sgA=QhAQL(f1Y4;(MO;=jSO z`0(oEuqi+`af<ooatL}Vb~|(fCb7Lz0zM&&>;o}*A{795&*_QN2$u~t68c2qF06X% zChFOc)-PBa*^)v%kP=wG2E0}C8wQ!1T%1A+Hw7N1VjHX`9B0n*YyR@nxZOP0Z#pf7 zGI_o|cQv|R>1x9HI_OrnM4spIKItsZ%0z#JJ_^?;^^)I_JKmX(A2KA(7+J9A2o|_u zCp$vO7{gVX2V{vIEii+h<T|QLQKx8+N^JWx(woNe6G)4B!ej<rmNU|<(nmuVz_>^r z4Jo=RB-WET02Mi88^f`1nd3NC=^PHc3<IxBB#uofk*AgfE~hc)m?@CtV4iqXSg&Xm zRZlv13C<}06N>1R*Ie5Myak4s^(1|kX)?Xh(**s2jBm0oc--WdAuCE=l4chdq7LuZ zzi<jPC;g{bg-~wBUa1m^M190npSmL(X!J5$Ufh1_g$+2m8Rzcdx~>apBxKy&FbXj{ zM`(6!>cDB^$9#%UlVl5L6Hg5}G;CcZ-hi!J7L_!x!MUMwNbPu)XE(Y6!uVc{2`G6o zXO=tysDMUVnC699?SpIb;Dy;=vLIfaJEtvi&<bg&1OCz;MteAP-@`E9<ORAlD0Qk@ zod={XMfafSk(@ffP$Qqe18{)>yNXu|PN#4u<OYOhFXJ!fhM@|`poPYS={f05YyM3p znOAQBl4F<@(RpE8BoEsTPw{E?PfCbH36AfcgO(vBKOMarAV^(X$A2fac}rQ-T|Va4 zCv0A^C1d+BKWH<0hBSI6&zYBv7Gt~)d@8SJKqn0V?H~y~UrGC}1@Ro_xlhA7s)8-E z8J08N+@~m)^DHMq#s9s=Se{Nc2oqpYKS%xt4pt=h8_RYvsC_sf-KMxI)omQNK&s=k zK1eyD#qY%xvsdfDey~K50ecPpTcHmytv;9tGEYiV2Yn#VaY~9?h%78dZ#$4u4HCW^ zxs<kmx;qo{6*Aa1-F;J3&Afn07~4%P&5@vlGAnMWB$;k9o{xtFX}eK)PX}&qYc}<E zbu8U*a_9_Ixd)^P0J}{^n2jlh>YQ^-p<_TX&OfZwVF_dh9Hkw?p3@wE2U@J1X4)bF z18Z>`9R>syCQ3XtzL0eu(UPc}MZzX2u=k$@PPQ3If@~SJ6H>4PS&)NTW^5D^sO7e7 z@2G(Ol&qk*Eg``Rwp3W)5gkGKj1VjJ7yq=HHz1lJ-b9W%_3i=+_vDp0fR`_}xAnpZ zcp4(T4)>~TIu9g=GF5E#Wxkyq(UgCOg!ezvYk4zI%JFdUK_Or`I1xZ{1mfiC5U#f2 zG}tQEpAATsx6!n3z5gyP{vVUY#*PN2&QAXWbMhaQeaivjr`9iXa`a0Wv;V)BB>!ui z@P7;^7P7W;G7&ehHFh#Lurg70xBoB8uB=}Rr3HCpAKHuMD&&xjOjvoZw00O1SOI1t z-~f1W)Mo=HV}{|)XhujKt996eo`m?YIrG=cSjKEm8)#rchn6vpm&Z=-nKqslK40%I zz}%oz2J%rWa(zt^%^@V1f`174=px!gCrStk5rh<v*2oljIc5Kh<eSU2tf0eHChnqO zY;W8=KYL4kz3k{uGn#E$D^Op!2aNtzu-lfj&cMBOz==*ct%HT=Z92SF-=OG0BzLJ7 zPQnxTT_uy+oNuVKDKtbUk6$!l4t!<+TH!iYkg?Mo-UFq`t7hSxGw3qd7*(v;VAy80 zP<s@NuP^C@L~DyA(P(a7BU^P_t!Fv<&^HPXSvXbn=_vUDi$_d#gxu=z=fR@MY&@o- z&!@(%PO_12>@b}H8?rPQIrW?<7Rk%9=SSL5iR<zuc9_1jM+VmF5prryoweB*Z6SBE zU~m$RpSIG9(pDMa&Ztn+Pk!?S#6Wb;I)MEJLJ$)aQw&2!gf2MA&<Ag!86hPs)BctY zTw3m)dk()`L_s#cp2jW5zP&fedFQruZxdcIO}fsk&qTlmoFC&a3BtufJ0T#1AAs2e z77D5KEF7AD*Uw>aj+iB@M<13DExZ97lGA4l%NdFD;>rwCd=0pzK#r$(rrkr8_>x1n zHIjTkdlWZ4v?CCP%SA0FlY{4Y7i*XN4CA_<_(z?8I0Y)btw?5A<rO$DU7Cj^9E*?` zQY>zyj_IL}Nfdu$9Q@Aw>#82Rr^&QAB7TK_d1^O+=??&R7p5-=SXvu2y_X)9dp2wo zMPugkzi3R{fiU-kegRwf3s~m=1Hk^@SXFX1aQ<(wD(%Rv%Oii&(x6JJ@ShB}F_3Nm zu+4I0<AZ|HrqjET6ES$wqgATY*eFJPv=oy%t<?{md?`#!R}G4rHrH+(W@dW&{IY#K zFDErMd;paN=pj*Nl-WcD`mzGD!67OHx<T|+2@geKqoMFf?Ya8V0`4tK<=56L=%%i% z-t_GIWFglMGy1cxHXHU8sCdv(fCHLa4xYhAKI1QZm|6Y{JPe)v{u6Lr0(qp$9-aK* z1oP(2&vpPw&Yl(DK3Zn#KlJWZWlFX%AhFTX&wTSo<xc!OQ_H_b70@3z12%UtB5V<Q zE$*Z86N@5a0Yg{10x#MN*U9yXL_-&{saiJI>3{Tt2sb+Iz<2P#7d6%zW$Y3S_F(^X ztg)JSijlhDE>C4ob>&GV7e?6!jq6w?eIBb`H}hPkl9_Z%C@XJawCfyHQLtC|sOu)p z!lPlal+2}fDc1JI<y5wZh;%OB!pDjlVk*Ee2wU6?yE6fIq!=N6dy#rpl$f5Zo_Y*2 zyulfV>|b%be`vK|%)}g|P+mNeGkZuVk`SB%78(hPr3!x>#v=@KU;F!@Xvm327Gwu{ zi|#_s|AO;6G4tMAB0^8t5Lr*Sw<mg1VA@;Y7P4L(Jc@)mezAJs7GR<~2UOIt&-W0~ z+b=;&r+aX5O>Z8hK8y?ZgMlI_%+7MKP#`NT@dwnMu39`5TnGOWtNaoxe)n&Eq0@RB z&l@(v*PqMF;tq@);fUf!!7z#XY6aD}=O?Afh&K7gC~8y6@SXpTzW-^TnkIjYwDv2v z`9lBzK=Qu_<$oEGs6(i0|NeCY4*DTv&wmzt43mbn-sIQi8(bsBgufoZpBW+&Slrwp z3U>e~n<X7%rZZkxtwdt8SZb40RuhrTHG$PqlP$R_h{Q5zv)whZ*f!%@tG!Sv;acXU zQQ_yq6kT-R0AKHG>SgP1s?!X|OXg3e=e5_KR!$dSuEOvadvKc~^nNiO-2s})gH*Y@ z2un|8x|+&Ex}}c@OU_H;D^&SQMfqDkUQfu%(q@g-D-6p+hL7^T6z^vWp4jaMrq4+1 zljI<{kJ`Y^TOEQErq50+UoT#Y0n)cPi*Mzg+-ED6lgTUNx3bMA6W;e`Xpg*S&;Eek z`>mSgbIrsp+iN)@{mH<}_^r!l6`XI0>i2f2FZmGPe$L`<j`u6t(^ts+g&xai2A<~~ z3Cz#+fN$xwZ;Aol_eAK=@~sRDX~PeN5Yx9BOn1><irnr9fh1}kJOyQ<;azF5Fj9>i zGp?qWWl<6tYLDgkXTB5%h-5ISm6zg~SWRV-2}y3c3vZcX$8tp<sLb`eaRI4-KrT;; zc!pT?tGLG|yB(}Fv5Y@%_{fy9=cIVaR3m8yFp7JG&ql3;;`Ww@WobiGhfyh?W3doE zf`CaO86&*KmE&>4f=ZT7)t6Xk%#*9gx*Xh-3pU@}93MV8=LYF*AtHlPBF*Jf9a(D) zRXnDZ+h(gdv<_qFLinlsf-O38=ttJJtH>htZL_+=1TQ%`>{908_VXb4OZ8d(zNy@C ze{C8jeF#bmzZ#+Cpe!bZRJ2nfuIHvCRCAjIrUXWTYx`d9yL=3t2_{iQMK0}PkvZ1B zYJQ$gKkEi#L4j#`+ptSY1dN#|$VIC9Q(=~g9HWVD;g)&WzB#D~5|#Ux>v%-0Nzrm= z-r_$5Jgd=!#4>0o)>R6k?3g(ocQc%(tHNGKv&KJGE3I=;GfsA+6BZNdbqFWUR`aIk z`Dx<|;J98!xL>ecP$lz!aA7J|h%g%_Te}>2)^R-0WU~tm=6Eiq+t;>`oU~EwwX~Ql zi{_i}kNEdHF~}}IaZ(FR=bI5N?Nbp{0y_tnomD~lJOwKhmzLtCFju!qf>(EZJS*8c z%F<0J*;^!4dSLcU21M5*nmIAyAtt~l?eG|^3)+sMnU>u4kOSRWpn<IlqNIkSP}mfa zvM3JzY<c&pge%a_Kfu5$sD2_+@Xy>kgNFyjd3t4!+03k}R_0AeRun3)+eHt-a3$uW zj;OX)nV5{@5`TOMMfzVBi@r#nsuHvin-t4viBuW=D}Yk4svO^;lC+4FEg+#CQksTw zew#{J-altF3E2Cwo2$OXXqsFV-vq4NIn!e{#DE>A)p&MeMrg?bCN|5InnVOfdvhmX zK-D0wqJ&4Rn@TbuTTJ)OWSe29V@@V+<Tm=DhvT`#PJdatLSv?i-6X+r+*_+hw;#7e zvTI*Td0zD%6JF;{krbYC=A<i`@gg)Tz6v(R)zS&cWV>NxyGdwSa{XI0FR{%5;{K7w z_7I`5hoRkAGnz`@Cf)G>W0fmt{!$&~h$3O}_0OV1W#mI}V#hG@CEh^a!JpJzPx3}( zOY!@(6@zEzx92FIT2e3`Gv&9FVKqNodUM&BiVnwg)ku`m#+3`?0aguoGp$=)|3gz< z(uB&^*OxFcB0Vc5Lb1nbUMIpoh9T-A%uqS8!=+8E++~gQ<=ipHdgaJxEpI{=;!Lps z)sm#r!vM#D*tsmxgGH@sj8+HJxFsgCmDt=-VR}+c4kq4>*?|Cq2}(Mxrpno(5IbrN z*OU?Rx0VZus~Llbl*h6^d?`??X{VjWMz~n!z&nil%4#T@=-tju{NduR{#$HINm&}3 z9<Cw<bLJqYY3C+fVirWILz7!w67AGHIy$#DR3#<+*dHk$_;czguE}DdRBdTC%^Qy` z6)%}M(C#cwwwIJzJ%PX>3D8LPDjh{hWq~+%M02mI(_Wa7!L&Bj{wQ7(lhfN!Ns!tq zt{zuKiiEHw#tC}5WaOxw%6nE~xFiM!8pFbTZK)lzg2QTN!`{=-?(ml=4OYB|mJE48 z2I~BoA)pcpDsI;%Ej%Zdj8?@gG9=&e_oj(_qEdUNY8W4p*&Al}LvNvVew5geO*?n7 ze2-FyGY44+=|H=%iSP(;w@|H_h&<0^FP(f@{s=ac^+mqMm2l^MRoMXp^cj07LEmtS zF`=ml*|``-=Tq4w&654?abkOvA_4j?)P1(e{JKr(IgU@}^k22VY1-tgP3>lWq>bCn zCJ)J;lPIgz6YctIIH^+z3)mF&+nlM;(%MCnP@qgX_u3BPCdxT^h?NgNBcjKvMdcq3 zL|cD1R8?f7%idGGpSI;pt%ve#C}4SY_f=J!68<Tsxh!AZA5%z0DUbh?r|1#=DnfMR z=yrN)imjNmi#6S!+k9xCzVfSQ!D*r{np|rZAAG6-(OVS9RG7#f)urx4kena;H&1bR z4;i-D+MU>Sr4t{M4XFAG5_u4wR1T3S*|e$O1vP;gV#JZG=4(pMY&<WS=u;%IWV5hU z=^n-41VKxdIx%|9g3_h{PDOrl&ShO(KtVMYkYpB-cE{kE2`iU2_Al>Rr27TrL#MFg z^uV<ET?IuN>S&HJ-|cZdITfjqwQs#l7mTc-CJ@K=*?FNS!F?#Kh{)(pc-)$8Ug~Xs z(u;I#+2kCDU$Ls-L|m=#$Nc*zDL~~(%rEOyQkzjpqnk@G(jujoP7e=SG~d)IkCu}7 zT?IEvOh$~TCSE%I4#C4fWJIS_Qzh>dG_E|ZLQuu1I`?TU{LRy_>ZsErv*!kzPyPia z4>Q#)zMK+mW<F_BfalmGe-7y{Z_7o()bFonn3X>(4iCcYIa(yCd{iK2diDaOQKU#{ zXUr!h8FNB59hcrgL^hD>{&D1lk1rq(D$*jTfpF%~=MAN|BY$EEBK$2)HNBksY9q37 zFW?$zfC*#==?zqLQK?rex0Uh<JQs9URbRaCz|FVRZblXRP#DDBt;qtlTA9f`6^V(s zZB0KwTOH4WVV}v)E)s@D!~UlBaMI?DHB<x~u_}@029i@dx&}(_fOAx43=gRSTfM`D zw#y1&Z7r(*eACj~&^+_~URLYhqj;4REtcm*r_B!VrT1z|Ddc70$scxPshQ+WYS;q8 z!{x_#&i?~<PyS(#hTD&dd!Wl5rDJZm5hXSop!)4GcTBFEp#m$x-B$yLP`GM@o{wa) znk4V<YP?EyT&Lc660<Z?$JkfAj*;XNtQSbCRvWT@He@|+ChzbBYvhs-EQXziRnO(b zC{=o4B4%1v9@Q%PegEgAOWQl^bLDZdC&Xn%!95*Sy#rM)J3~~znzweEE4Z9gZq{kw z1ADyM=<CeF`X5wJPzSI7`^D<0L2bu1DJx4duv7r<Og4sf_D~98slr&chBZw;igkNT zhlKkK_Z)ROipXEp+Y0lloc`w6+%jH!yYK|DdMuKeJnb>4O}6MOCzrm2eV#tVne5&# ze;lP%j!1ci%qun9F6pI-r1OQ+v<j`-u>)?t*(s&x+s&?^eTVllIF?f}BH4MX5_|9x zizX)YUXA`I1;HnVb-OTKb}=cDJ0A4D4ukzJ;2UE94+p`&A<G}wZ9BwAR6z%55aK2e zViZM*irq*%B59%I7aeUqVOA)wy4+)JFN9Go2Op~iOHSPiJSdog?qrT!lHg~5ce5UU zy4(P7_F>_&35!y#E)>oXy!d?lxUwDpL_+v8-3-H_PS<`BeA>fGoV3dA<<Vl7W{I?d z`?pgp${AX**G^#c1cgvs!ZOPm%n&orptwcojc&|c0P7Y5sJXP^D|g}bdEzJiF#9Cs zgYXS2L2jR1`V3?A@bP^EjPS`qA$oaDNSiu{XSlm5ii+B_PBR6ARc{l#UBw)pQ_JYq z(^0LRdB;6djgP&?4ScLo-{jNCN(+=%8{M3Z$6Ii(9zyg)c_+5=okDOk2Y&?$$i0$2 zPwg8BxT2dY?oh4D^&d-ILVGM8TQma0+WQYqHL#z;%k9NeQ^b3mI_J7z+Bj|QRFe)g zuurbA<#9*C?ipw)$IkR*u+JaDfOW;}Wi;lJolcGMq<?`nZLaP)9W772*~Trq8-vD^ z-YiR;BHyAK*t-WwGn<C)Q{93#VF}zsJ4pw~bmz)B_+04Ad!m?Nn@{($1=BV&ovOOh zx?W<Bm^R-Sih4i-8d@REsR#*Qkrbzg7Z9wk=ZEIx#*&@R{hb|=Ti8x?1H~)y<qL<~ z74dLQN%;Yp?iP&gl*RMHz#C?}MestJnNygFgu_dQ^qRagOPJ3#wf&@bxIW6ZobN(P zzhCN%U7L9O*Hsy-a>Kzb*ELa?RL>`RDLs3FHzLPqsY{mP6Txs<bm;vG?1_0~R}i0# zFX_YiH{AG)PvV{0&?ltyQ)77T>h96$brFY&FSepEJLhcb$|s(RZZAFXOzwb*LmF>X zMBAeEd4W7#U?wZ~TUmfT`B*^boH)3jUX?v#n&IjwGheUeO+#5%?B=X#NDmG>WB9IZ z3TjSsZ*WYCxGSV-(Oh7%z4M>Tq=66z17*o%Lep+TYxV>hnA5ta)c~#9Jv0rQR_{v2 z$;FfjBc1}i@6e4)43u&e&G$LWqY7?&$ailqw5;~P7#dCmjk%5xY}23!&YRD4yhotB z#+K30<U%036Zt4LS6Is(7h#40F61}f|Fbvz4{fr@g_T3cueS2_w`jrrzuz0`G0+oB z*c#dW`c;}Zn~1m>nb<p9*xCM<Oj%LJ4v7KYd)gEUlU2t2t(f1!NxY?WLl+(qB^9|a z7~FsTSd$~eqP@0>Xd^GIXCN605d~5F6Tk=AuoEUTu9V$v_~Geudz8<|=L=RJDvLw8 zZjnE1<J+|)=7{qeqLC&|8x@F=b;Xiz3juxxIGv}eGI1Qnn4u`H+s0QNMlbl!+~6z$ z2Ikr)kAoehypvell{KXE`+8L3%6%0#dtTns8kXbO=%|ocBF+tLGb^6Mk88E#i+b(` z&kTP%D}3qmV_1&WlamNt@rV$kr=z;PX<iLeF`WkRNQ3bb6Qa7bN^vY12#3c#Z9%wE za3#J<gmg{ZG9nufH(2Pjo}aq7mGt$IHBQG7XTUWkU142C328w|+sXVVO#R+Y*zBNJ z5UMJnwy^R@d2iqkQSbYwyrMXZ>~l;MF9*^LwwnRf59ko1Z%~}Cm|sR|9;`nUwhH}7 z=osKtbBWfmI?cK@ox@}1fuA>(E?;n1Pc9-|7U8QhD{XBS-2?+r)x#GrDo6V`3vQo@ zHqdy6Z$FUUNHm6hziutu!3;R>w|_<QSTrIjr`5kc<$rB0E$F!B_EixbtpVfzL)rB| zKmlzQ0TYS_08sg>Rww^I0>yvT3^X9zl#iBp&6>F;K>B+D1~9>;#Ki^ufWae;4IqMo z68HhC=p}3u{KqEgnG6&(D%Go8C|rUyi}GhR*9k5E3`15`HD60rxi&2?+phm=k}QLN zcwS^p6X@dxPu}*@?DVGJvmds&ou2E+!pL_DInP9KFLSY0t8U@R(xRv3xjePGqe8jd zfjv=hDW1s5INTbMjgWDzP8?`uPwrf^clV)jZ*uK!g)M&lulHm#86{k0Qo<?br;-fI zBOBPYuKykHVo$p$#yw05pG-?wwND;Tv}4StQy4WAYT<K1qGVqcj&ZApoRD*`OpC~- zQ!=NyXG2e?8u}wc6}1XSh$tdYbR$|MQ)(X<{=vQ6AL<m|D}tnRn%AaH{dNTF8l@^! zAsCV*Q*%sCRJ$`XzOYQIO34?EU{S10&R5-Yk<}azyz10FhmnQWrL2;=@=D9%yEvS1 zFX+z*T6c_(kP|)6)SiKHUB28r-6yqeZrGX52+p9P{ms)w&U5<-xI(j>Ibv1aDzb<i zofjo|&qgu}F*L1E2wNoTbRuvRFOgBJ<Cc>l^+@tJkM_4Z#rC>n*T>Z+Mo*02F)gkV zmzxy5bWLj-9-bIKLAZAGPv|JU3KCuKWE7*~_f4sy!k#m^{>tuYU4D{~=@5;B-}?mj zTozvNqjtQi2HQE^UwMW0|7C=sfLjjL><6SNrrB1g2{!tckCUK*18oww=tYaRR45ks z9?TyOs}V7}SGIn(c{l?3%Ii$XVyG%?s#A!Z9FUx3YclWqw+yex(ME`DF`l@D)ner` zC;x>?lS1b7t*^9=sIjmc`DSb-Y!z+U-R{@Cj%E$sMBf%IrD^odpUn_rB18(QfRM+e zc^o_b4obS+Yn*Wd_ihB0Hkqch!l)rB1k>s(AIw*((%igg5s#@sJrZ*6?cdZLruTj) zAXT{rCrehG-%PM?6(#a8Uby~`4@bC_Fulg03N`$Eetbf@sR9F8EW=x?vC|}rCTpSW z2p^3thOHIq6(20Hn<P&>k}gFa=z7oQ)!@tTxLS-}=3*vT-xf<;W>l%CjuX}Y4?Wwa z8r=&?GqRWzkPo^1UdKOB(vS+HZuGG3HZ;}fu5g_P+U|DENWc2S^Rg}pU&Fs1{N0Fi z&CQl`=t{Of<VN*kjppd8g-`7*WLfai$^+?HSl)f7t~3Ei^ZP(gQ{DXhP^<={X|u-6 z$^W8-(paCA3UdU-11}6}ZWVoJ(bn1qZzn(~YIt@SN_2Y{*5LM9Uh}njSrQBCoPaiK zMCb<yo&JTr*UX;RA_yI~FN<131{*!KTRB1u3ko=l)!LciA6mhW4W%DU$fO$TvWTyo z^{JbhN;<MiU;RNr`8J0Jo|YWSNs*V(b+^x;+qEMHn$ppkRxOc&I9Axf3^!7jjQ@+I zB2mFNn>#V2aAgPiZdhfAT=6b`_1Rr!NDz~g<lc=`vcHYE;Mz-}`fTFPSN)e&RFFo+ zU@oU044<Z8in+_~n0Zc}&yG^r3To)(_|b~Wt4c!18L`5z{14UOH)+YPlO<(qWKCd8 zv*>4CmV0vE`SSbmKED$9)^SR8ivB&&hE0gxfc#!BdBN11w2=pPy<()Ow~S_5kHkW7 z4g#!*Q3YY1M-*A6LldBK*6TR(Y0kmlbahFiOBXbyzLHI|$iacT!9{Hh^z^}ojc-07 zVZ7j3-)A~|I6-e};%Y7I@K=41=E<WYC6Lrf066?rNA}KM74K3NWy^{M9&G%TOFPTu zfdn2@$#-#y8}a$AMX+J~FY{a^z_jARkR)XA-620d{I#iJ{965jxHbma6L1?b^$M{B z*Y6}mNM>+TqO;y4RBLf#N2m8VEE(x|SxC%aBFx;KW%SUy#)mPMfz*E?E;CcEAzTj) z967iR<?p2RKAG&ydC8X2ppC}jGTsV!O!`*bw`)=K;2ZJim`i&jm}>ogs5>#WaxwHt z%<y{*vo5{LV1A5r6g9#a;kJqX81lX2`{yXDTQt*xYj?cUVvL0XU)iKIs+iy+O+i#) zh{(KQ_}<^_N(QDkZ=-J?#2@K;cwr|O)93P5g}COl5xBD!l5LKKl7HuQD6dNB2FyLW zL6zH+ZGpy?G`(f3RMo2VvXJB^P`)F^|1MZT`l=Mkz2X`RjM>Y_fJr8zD!l3P22s6Q zQSOjQ4L>C$9K>Cx61<XosUQ7nEB}eSv>EaoD7}V_i@jY?eg)|&y<vUkj_)L0^ElUx zkGyI@`f45B+&U!V?T4cHC?B!<s2{m@iyb9;Ngj=~3KgN9nk3_$+?0O;=cu09yk|+a zEa2E55swXJ!4(X}i<1*l&Co|nPuGM5{!#<o5A_uWOlJr*)a!7BT7%{u^vF`N%^?GM z-~fblkh!;P?@ge|J!Hh*dg2}lzPa~sMIXp~G()k6&3KXIISOwYKCm20dQsij^6@pd z50pK<bc|D{zQfBG#pCjonB=7739H1;-G%oPpAq9V^A(goL3!yp_f(KQ)%RGROu@d@ z_jIqRls^$OrJq(B55>qm@%uCsK2kM=6*p-Hg9o6qE!4=Fh*CR<&^B^*!*r;UsrpE> z^C~_Wz9siJZ}5WWQ2`v0k*UaNht$~_d{k!3m-YLZZ6HNM97P~QBnuOgC&)>M16edn z6A=W(f0e(1eh|iFcNEc+e~2yLnSMm}{;K%I{y>K6A=yT}5~Fh<&MUs!<#+WAAV>+h zy{uq49&u3q1n#K4=D0bl*}aUMXY}cFBKoP9@*;<of6{$pE?n}SQSW`}AfMRWi4`~= zy3-CZH^`NoyDlCL3RDT`?B1b;(4NEXrt0|fhN;!{c1gC(rYe8O<tV-F7>>!^`W8Ov zCG+jas(j<&f$dP-Y8S<x8U^zyyixOk1AICQC>%MpE((*X%8<_T-^_cKk5R*3$6aTU zLebYxuf)N^%c-5sJfa;YKjrCDBSIEpIWTt(wIFS$>y{Le@pbrZrN|3Q#rAE^KbRpG zhQgm1&B;;#Or<|ae#&HlgUh+;v1rIN>ze59+1&v_G=a)kof1AER7AlO&XH~5p$OGH zupJ#ALsA3y7V7|mJ@(E%eHEr7CuUg)-Y}|2!!8{j-u!9s)QDQ~{=uE}8}cExC<81_ zeH}?!dVymP3kM&U`qa!dsG^%KcM<KUtu63<piEWM8;q6qHa8t_i6vVivY?rq#ETk| zlP#)(D!zXITV}4-uee>C*J9*(xINlNRbk0mO<hf))7%Pe;q=4jwtBmK50cLVUS7Td zZNC7ah*;8b?xo<{g;4SFMFB@9a~WBMFBb@TkgZq@2R+j{n~DO(t=%nNy<8Ec3`{cX zm`|Nv@=sg(z*7gTElD+ruDTNNU91rmZ=Q|;r-Kfjf0-tPkFeoWP?@8bzhvm7NcNrf zKBn&7fJ|UZnt;ivRRx#e9$V7;x7<4qHBE7EOtGS;#V%^6?mc`lnNZd<RSD=%sl7mq zK~qf~U*=d=tn)}?-%VL7#Y@5l`e`5>XiIsa%~TY-69TVW0D%R6t)x`X%29-6BjZHe zs8f&TJ&uY(3=V06_2?tvZgO}2G`yygg}40v!2k-@R@Wn{%YrYMXcj7rD931@67mO- zh{;b4ChUABTb-Od9+@|8d}7*n-=r9SoV{}mt?w(ks&5(#yQ*%OgJjsrT%A%Lfk&%Z z%u7D9$n>rqQ$n|#(rWxyU|Urd5}%~1tdgomJ9Js@rb3cDg$7H6Wjubi09J5l2Ecv5 zmFK!B!ut&%r|*2!XFiEm8A^Ij=QRb=gS+M+nCYS=^r@V|9(2q7EXYWGC(_if(W(a( zp@>v3#jg0G9!I(Q^2|W~_LO&_QDzh&)X6Lxq!OmSv5{5Q(~JMFk1=J)(4g;m*<4#) zx&TQ&Sy3+qRnHj87z0-1OEjMmQaMQvemlfftQ+{;f@W`3c3^xfjlz0;ZWa^v73L9p z)myb2gSB@N6yi~g*`YGT@+<nf(r)>@1sUoR6J3cmXRYzdr%oD$!NmnJi%IF-afVOg zjQ$8bC_v^;9C}eJM###t!ZLD2Z`a7}CiYQ40`S5YI!J)UT!9Z=qLT%ti60LQijO(l zHWw>=RFHJ6V~%mG0JljC_fFV?=#Zo0MPvJu94@ydY0@0Qy?#Bs;Z=dr#3jz%n@a<i z<U;730ZajQkTKtZz55@wvZS7X91H9G)}zWIth?O^To*<KO(~gKn@x#0gMx@F*4j<p z9?qe9Y;i-DwoM@|x_9Ng^Q1F$$2>U>HFVexYYK7_lfyCf<m7Od6FpZdsXT&AA;|lc zMytV}WxV{Fy=DjFqK{Mh_txa=5-{h8;aLREh=sIn*`2}6*=KOeH>T?Z>z7_7W^qt3 zS*Mb${65DP$AHa|r)zj5m2;_(^wQCUqo&5hlF|L9!^XK<pnBU^2aSxlS>XDMeQePQ zb7GnjXiWhQWdRUn38=CNN%Lgc7wUuO*2O}XsO};uM+onX?!X1c+aLB*R->L&T)_!J zGUp{motT{gPPqOF)y4c&iZwEe!GJl7@vcMkEK@#U8^Q5yphJK(u`$vhSEA*r3Nsq< zvZB65ShVVua4EJJDR?%JeB}K~{TX;WH9_1WR-wJ(j=Fx4!N0~i`SH?J4Y+v<Waf_u ziqyH=o%Who(GnXj>No902e^?jPvja4m%*r!BZh4`ndEE+gGOu2pnp`24@fmS&WNL_ z>P`1for_&D^~{Bw0<^8=HmE9|(I|0;j5Z?It)9qjk`yvXuxg(8Es!EF$;{^kF!!7I z_UbmJs$tWiAF>@WS8(#@bSqYDvpGl|mbbs^zsRc|)GI^H16I<TJ5CC%EefQm)6eR{ z8cmk6p=vN^1(a4g_Vm_D>db=)FWEa`M@QF1bD6}JIoHY6QZk^jaLGU)t_$jPsW2D1 zU}KdaS`@xd9-Uq|-cH-tViS~dvJ@(q*!m+2?A_AoOIkK8jx8)E`}ZWeZbAy+ol9m# zF=aFKGkMqfT^7Zk8Ur!S=`5UiJX(~Hu!rFeHl$}}Q9Z){JaSp)^(e&g7Q%B;OyWk| zvPU?8Hr*?)4+l49MOuK>6lQ6Mwx?Ae(m11tnX~N(d%mi+Yqr$Ux3xmsZo+yx8lI3i zBf1^IUz{~^HOc~Z#F^aEJffS*FlWBVgWXO@gIpGj)U60&x$%0VHK<x1o;?C*kz!r{ z+TqSBp1PX8<9g%Sjy)28;qQH$ZUIJemI9c{tET}OrP~A~!cf*b&u%{LpNf<?QJ0u! zhdav7ekwHrM9-C&6O<=9k2z$Tl?dGCaX6I8qMn~Upm*UO=nYPynUmkTQNz0<ZV9&m z4F1V=Ect*VA=AGIZHGf8@u~{T{zF&U5~PGQogpB%5X*lT>jJ}D;B;@DnK-haNiFH< zn1Gs9xF7kTl#q@G7k%0{V}srWbO1*Ge=+urftiI(mYt+y+qP}nwr!go+qP{d9ox2T zr^7euWHb17XTIIpnP2zU{d1pltLmv!b&fMR!8P646@h6`lxDssUir<Dxe2;28tIFs z$n5zZb&Z_wiOb=s=Z9W?+M!^PaGb74%Q|`aBZTJk=p2RMAW_V#g+_^@Td<9#n<Z^( zs<4)H@i7mX?~0%_VYKPZJ)0IBj7~sh4Al?-Nlqc0LpU4@ieMT@SPEpU9g(ps9IZ&; z{-;Qk<RfgR7`zhRRz3m*FFFIo6&$mK41=b0-CUJH9|?ZmVRZJ-Ahx9k(uJC6<e&Pw zH+q%|%ICE_lB%L;^9icq&sv-3%w<n&jU6$S@=7rj!_XWv0!wFD$oPS6@&+f0Q#nI6 z*c7(lDP=AfXa_rz9ZbHJStB1ma~{rJburaM7TM>R_M>6mGVn|nELr|$`xXqo(Vwe3 z(%JP#{|sthzhS*;DJx%*S-)|;VZBS8?$)y}DdDw4Z$oF;@b}<^9m1AQEH{q-{0YGg zyU8E)32=N(sxQI!&o1i_$!&)WJQX_Y1*617c+JwV7kX!ZRNH!v3(#n2HC==`pkrNR z0dUQgg<X1lH7Y-9BD;?KnaC~!jiA@R-C2{%k|Q25KPD)~w)PIaGZ(ycuD?8;_XBe2 zfk5p2nW-lh?@OBCyZ8CCdlJde2Xo-X-cgHfA&%Vzh}^hT^0O8Jy&fZfjMQ)H@R?{R zfpOaMIaH{seeR?oraex~ixzK_10J||bY-jl^6f9{yN$r7dsiw+1F<VNvTkoI%r&gQ z+bjjLD_!%tC47)zs6b8ilze=ad~cb%i_^n7d^##chL~S)J}n1j&}T3swcRW8UsAez zW=8-_oR<QBL1wg{+{ekjJEU*P-Cb^P$xBUN9aL_NNb%3!*O!$2-x$55qugU@f3~<d z#>=%g%k==8p~bscm7d70A7})}wp1YSlLF45<vOCbO0WaU3*v*2dV>n<mVY)X!0>&) ztHnJ{r8Kf=L0F!WAeOCNijl2Hly0z7+gee^(m5jHg?g{}>@E4E;<yZ*j}JU)Y}?vt zw#=*z3+Zb~D4g5YflM94Wpxuw@YeKsPT_twC{?*hPEkYTWht;7mt?D`gR~P=tpu-D z#p0O4ME12u2mS@?K^33jeG@6;=pn0awj$Odwn^*3fJE3<Jn@F>AGF`<i3vwF3{^zX zVy&we?)x(|1zL8=+hEMh@e}F$lx9P1sNq)HgfG~SZ@h2mGlguIRvnlp!jC}7Px#dz z_&lG;7#Ero{w<~r5hqO<sSP1iYhr0lLRssAo$-n~lXM*csvQyFbF@6+HwP?S13~AK zZi`Jk!Fq=UkI;Bx_IDI-#Brqng!8Wmm?Ps{A#=<MLU{vf^ZE(o^~t2UtZ1iiN*V~O z@KK%DeoR2^fqlF0w$SOVbB7C<_!In~4z}+%){i$nO@XMiPs*lzpF~Eo(8MvN(!LiG zqfNo#-oAziH$oGi@Tp;$FS5e`lc~StxtyB{`au*HL%m-{pTuKw?hH}TDlkKTWEeX@ zS3-(_fPYliTsFl|U30|DpNF7Ha@27k$X6N0r#AC;rcggao8ja;>TX+*Z;csCcO>-S zdpd3GY)AZca{*lK=%0-Z2nM;`+LuvBX5(E7W*)f?u;L3WM0<^c93^5UxchJI^(f6e zaP$a)@W72<*os#i7Gl>ju@ztQi99@K$ntVD0e$J{rD5znV%1GnuHrUZcdstXb#7Y7 z7aUU9u9>$2*3!(<VorpXi%QpTiGQyiD?W9<tNb|j)|Ff1*2XP`E2*;Y6o1xl+Uc&# zspaLB>F$|h95I&XVMB|(<6wJA_D&r|1n{QO&?-1oWL~Roo;^scfO`-Gz5j`J7@yW# zW)^^)jV8YU5g6VSCzMtvNAbA3n3m2D*jWT3q^lOhb-{IU|CQjCJTlVML4+En^>j2{ z<(1=gPllbaTBVnkd*QikBJzSzXMBK@ZbO%N%A=Hk0e|R&HO)+sWlrRoD=MlZV4YB_ zKhk6gJzGFAE9%7;_e_}6lZD=Q9(k@vS8|$A+B+kCw%Uav_d9yWkOP{&4Bi9u*8r+R zYYI;=wI_yp|GwIt#wU#Vz17UIRqi0GPP7+g-7%}qWZDCl-3jd0K-LRX?IG`0-@C?P zR(k}z!3o~;gW=8;{5_g)FvthX#VO|)y<_<92}AEJ<7c?GEZdG9))2Q0u}7IDkG^H* zfO<yh1Ksv`9?+7H|IvY?2qU@&Ug;<=YGT_@1`=cI_zB;@wzB)*@eX5GKlq{*e9@XJ zCGT^bCFE5d2js}bCmo!sDA5@R<PC;dVCA7BGKypefh@{^px4Q`4X)wZ9Dwpb+s2iT zn0#|;-jq$CzaR|U!3h{A%zt=>CAi=0i^n5%N0QG0agDic?K8m&McOLNL855`p~3iH zedsVt%Lg-*fkz$zFw2H`K5-s>Wz+1LTRG6D<oqigg=#-}e|k6v_QW@1XGPz+>ON~7 zcwh4{IC`h@2_NAJu{Y17!;d%~8D^3sJKU4-Fw6QoWWyo!YVKNs(j(Eyj8)qggQI(% zi_R3Lp?Lzmvo}U^foJkJjJ^B)XNE`Ot^p?ao81}z*2ViDHS^j3oy}3X{uj|1-bFOD zR_(}RX%tbQl9GYI@N!jRG#C=p7}7tJdoJ7q6CF{^n-_;K5M%gD_<a8Grd^8zg$c!} zvL`zkS)8Xkod6Tx&$myIJ{-Js21dI=Y~<~;L0DV6i!~GUM%^(|#*nT6ZLm^IF8q!j zY(BGabLT9W2qOhlnDfNTsHcth$aw6o14R;LD4ZKxr}K*kM+U^3j!45olrh|Q+`5PB zxWYnUbNOI5)%)KCjcF~Lx!N=gFpi^$@B37MDyy{H2vSwFM!I64tO9bVG+{iX-z_Ka zLTJ3T$@w_;jpn55yg=)sv#6hx?u4tAr4hZzO1~<?YbJze7#8)!z|_iGMht3w7GgRA z>R_grqHn>ed?-Q0DNwilNcon6q0&^6!uqZ22FqAitDrpHif9#KLT%9c>K)|3nsAni ziF4bvpem9CXDx`JB{k42?^;7Vw;Jm6r%`oGF({zTy`)tpVt5v_gs9#WVH(;!LELF+ z4)6vwtOfthmS}<iEMu=J0}StA{KLhp>Rw%M+Ls|vWwQt=LF>e5*J;T*-pY2MIF(}W zd@PIFIvS@KHhX-NF6r4?i34AqVN&!0{$f!YF=;PIY#x5b>cW*=-lBZQoB@oQMN``3 zX5%6M4)-@xjg_96B$*#^m&W$>%#nrSHRi<R2e4>Xc>;B}3FPJyz%0<h`pWXj_0WHz zHi#2<SIjcNA@XyG91s*v5D2c21ey@rXXa-<Yax5dRJjYcNj%~PV~vms>6cmr5)n5` zG>xLxA=8z5mfee=txcG7F^{mj3@7kUuP^S+C}3yy_9ocZM?~J6GDxw;@15^jY+-<5 zxiSq*<$sO;vH#CVrcliqg8iOj9l-maA(@@^e~+?ype*Blbx$X*+l2l^6M_i)2|>7u zBtQpgV23;<m?ZGC#W7K4V8YBjCkJ(LV{qrWzO|)gZl#I{uURx%KtNR6-uqkR@UiuG zOAFwag`d6IGlY%A0f2Qkjs3RU^Xuy!zxRvr{i=!_52#*B=W3V@XF`aZk34La`XvzE z&ik}J@V#5%Y8Vk7Z)_xp<Dy@JEq1>geU$OyI15=5V!s#%FA*GXW`vj{B}Du#J&@k( z4=MfqpSCTZfhh93WSrd8L1rfpHMrUF{Yj^nNN|1CKdkg<hw<pMhnG$d*y}H3dJ2DN zL3f{xID3d!%Z~r(a{A0h-5!GDear>nn;wpO%m?L-oeo0zUJP5|-0zv+zdBb;(jQ%= zIlZKS)0-ZydT7EGzs7*~rrh@)^xq!U^rj8s7hm`#A9N9fEh^RUk7L?@GJg^+e^udp zl7;npD@Oa7?7Mv^C;pXYdifprMe$PSUsWqCummMj2OU;eipJ#r&Eez<(#xD~riyVs zKpnZbExWipHM2jnxGgoajp;&^!`eQLcdx#T@(QoMffV%1DKop??~vyI6aool8&Ylc z;k2PG1ZLK%U8-H7GBzX7SVs!aR0Y<|3FwbE8-c;waTvLjr8P9JSGsw+TJ|p5@8Rvx zr1ZRNoe&#u(r0d|q%|pe9)=Ny&xm<$@nkDgAkfj|wz+6&2mspNYtRvn6Lqa&FL$>n z`1}*^Pk$`u9XHCv4k`rX93>zoc@78UuG^L;<E#x#*iFl}RE4dZ7(xOEu<XapM2xpK zU$nh}Q&=r@8315!_+!>or^V$yS$nGXtgM!aPm$^2Zr5DTTNk?a|3Fpz^S%GG<`!MW z7ADl8h`v;)XgP~5wV>O`EvI7HB*jp{1vr=6Zqs5<ER!Z*$hWBWSQ2A=tTOUiLeXGk z9skJ_iWh^B_!iu3K9MmK{)`zwU20LVTJZ4rlRZK#Ami5%4<kB+<w$+d=(Oc92lhnC z;U1ecfv-ruhf_7gPB`0?$5qO_VZ_o|u%V>nhP7KtE^cl{cPf_1Q#{%>alLI~@i!x4 z3OAWQqMlRQk8CN5*nF7jV)JBO`~Wf}XX<=rMT>D(M}8anVwVCV`4@{B@v;IPQpTA{ zRckgbp^Xg<;#vE~A}4xGnW29{g2T#=dEl29OJ<*X7_QV^FabjL_hjZlsj7_-RX|H! z(o9ypj|$MGu%g%TmBBZiDf>06!zQUMvki5)HRyt7Vi_-Hz{mtkivr8^gZr^xLxDNF zxSr=1O-Vpc*z$CM<!iCRG7k!5ZDJ3^xpxHNxb8@!D-ije7mvBkU#!?6YmN6Kku2aL zXCyI)=DZP~I^<=~pbkxR81biI#1b5+L)@Mw0O(4JOm@+1X_XX7zt$+kE9oKWX10I? zUJO~RTJ|EA`Ftn1Q9pq*n=StDw%^P+%x{k){wz0-9<Ta@=c+IU3d1FBGQ-DhG6rsy zF~ZeU3ky^`;dpEc=4{kdZ-S}J9Zx%QlL((~#0(e^ltSeLq)ca5FQM9qiz*3}D5@SJ zsZ?D=+Q)=&i=weaPO6N;FDQ)Cs7<1|eO)G@m*F8(eet>B);%y`frBATRcIR;RM8_u z3H62-f0x9k6h-;qD2!^UpoVx<r_iBQ8Wgh2B1H@1nQ>GctFmd)LV%lu44WJ@*r7p0 zYWRjIR^Kz?$YY#EX%vT*6pJHG3pEfYRlhB|K-J{CRb(WV(Ac=26nbG2e<rB3$)Fw= z3ZeQo2%)AF3L#RfHb_;Qi8u2ySy(jwnv!~vKs=Rpt|p{g3l4kad%yW$wvJ4aJrf>u zYt^7$sW9qhIoE0sL`4se0frv`J!hsf#$p}%KF~k#^95D0BvRH04#dvh#n_Z|e|^ZO zI&wO3C2dGHDydGTK~$$a(n_(Y5d9ZbFX}ytVp*gY5xDz-e`IIz7hkNr#5A_bJO!PS zXp)86uo|Ph!T8Xxy1qh4xCY2<En>2IU!_ku1=+nv$a~170hLPBpj^vZ#(ePinps*m zM@y~n1((0$?YEpopF_+dP|$^8F~Mji9kbHiP2B(~;JV7>JnQvtEtWZT<EJ^`6l9cx z(j~XmLUk?cj*CpJ3s5z=?q4%@*0&du3<k`&vaHH_T+DY9h2tjRBRDlXc;`)gyG(~k z6OX7zH1|YV{!FRz`y3$ERr`r_Kwl{Il2uf_e9q;AY_=R2E7c~$J{hG~3aY~R3oq+b zyfd>aW^S-rb5=qW3tNdNca^GQBxVyJEr+R1gwqD6{MItvGAkVh1OxPuER|ZSm3F_) z>Zjm`gwzs=A)1U%`oKH`uJ{)!d@O0dy9g|ev=r?wIt{7vjk@NEF=Q|lsIvN#?j-t} z3oh4e1Ky^&zx7PTOdpw4+oavbTTIsR7;XLPvbRQcw-yt3#NX)F5$^1CeKp4;)6!^e zT=xwW;<RnNl6?X@FyY4K{MY2sN6gt{PJ3gYdDoLmJ4krxm|G-*TjB-sRH&p|N2J1k z2{(NdYR3DUZUo^m<IEa1NiUF%I$x&uaFR1?^^UU;Gl32l)_l;-gSmDhAG=2^S1e!7 z^ARI34)WA8k-J7i(vjsy3$AxL=}}jCcx$UWZ$3X?=fJEs#O`6%^y&kbt-n!L)O6Pv zX5X$wXs=;T+fM6Fv(oa$u-3rlOm~h+jtSf@5^3r8;fxqH8)N&^pzOh(8NhFkr$FoK z*vo6)?sagR{(@ZPR$l4cOU12V?cMVF*0-AgsB3s*t=hnG0LH<RXK{Lri6<S|)p^JE zU^LX+U<zptDRi91D7Ya3Gsfv|C>hyQ*<P_km%dS^{)ad+ha72BlNCas8E=$pR666j z%Vy!c5L*1AaQjrJjX-*2et9&M08jCRYoQQ%++i1VvG^u<=1D5C_)d6DafU+zrZ|I> z{h?nOXtS<pUqV@7gZeWtA~gU~21MeJzU8&ct@Y`asM*)!d%8U6_jqkJJKf?xg@eYm z;|&_>hG=Yr_}bN%Cu>I$mnVl<ms|mcUE}RXKhL*(>}c_aX#$ATfBjgLC$cZIpJ6=8 zJGjvaP^(mDxQ;wbUp<+{=>M>*MR$4Uq)T3W==e+5eu>{-Xy>O?iaK_pA>Op2oElY+ zAgd8;hUG)8c4%btJy1}TLcZ}*x}DfQl}bkVpw@-Cs<aYP>;*l)M-*1#L2bV9Za=u$ zPW)uygmctlLZ952w;x!Gg6@I*(cKo?70l`lu6X7&2at<;@5H%TkV0ZxCT~a&*IGEC z=Z`HJRb+`YrNa@q5d%ol>}u}ug(fQd0w|<(|172!Q5>4|Q%t;a#6}JtT?pdst6z<& z$shze?i<n^A$~bi4)Tl$Bi`xCX|6E9RbqfEJ+meo;vM_2?-*-Va21HM?nD7JwN$vZ zJS?^^?|dh0FCTz<{u1yVoe`gtvRO_3^4*P8R58on`n_=KZWg>rh5lR=zL=yT8#4>2 z!R+5?1W#ZMbS2i{4}^VQFaCYqhgIy;$(Y3*Md8dUOc61(5!}`C^Ak4tY*1|pdTZ<} zZm%fTCC*X)qD=LL4r5ph(<U`p6*If0IA852mvtSfoeyrB8*&LPz_wLy?3|(%g0o=D z7PSZZFPo#%%R{~ci$yENVoU^S^vH7bFmCh+UZ^xurj`&SEn+toC7)SIm(7-lxJfa^ zNvb~MR)JCNvRi!wl9=NYA5Xvd^a<!YV^*l^^&pF5+tf6V8-hE%!*(c8d*|-PFN7BP zLQOuCa8dya`=!@y;_|d87-~>f4N8k=2(0!LNmY8Mf=(HnlHaClWXi{aDx2taY0<et za+>Q9nI1O;P&O;e?-@=LSDwuJW9z_}7vLot;QE^ui>us7EhD7W4kT3ut>twR<Qdwf zR*~xa;iHz;Ru`!UTA$<fAI{*+B<Vj;LVG6qvitjH&Ck#fZlW-&hhbFtL5dPr^u_n= z2_LZ`-`E0slIrnEwqU$W>3N-K1Ke=`y7K;VCGK`+{_6}rD*Qqci~JOKxafiOdk=Ff z^3)Mq?$E7k44Hnv$ph3KDgcBC**zkoO?;}q+lcW7dAK+gV|~D6Q3BGAtPV!XD^RjC zXpAEUx|%ob(HBQB`#NnrOvmR1#qs1|S`F37jpb%2LFMY_y*WoOX)MLTtep32BZG}? zO+K=Gp~vY|bXwg0fifl7qvl?B-T|&*FkhdJGYcvH3AsRyebkUM^JwJJRW$iRO+-i6 zI+d|ND=f?Tn8{Pi<Pv0QWD?3@L2_kQPI<@g`5Cq<RJDc!Q}H<`GtplxAuBog-N@iL z8>(=$(x%kVs~JaeW%1OI_nqmJwoVmgrWsBV=5V%)Zb`D%qV1}WiB~p*e6lgQf^@kh zhI!bd_3qlC)26ZQqf{nzTh@;4@Q8e;cRt}Us%;(q9-E=uFFq)7;Tg-IU;klW^<O6a z#;p7o4G@3)2>Ny?|DQAm*xCO5N~HzuqjH?`E%un<ZGIv&lJHX;F_4HX338BG0vILH zU*utqgaoY8f!SFSjEwn^2UxMn7PX~iL#jp9XIZ>tLy1@l_+X-=bGdeV!|wV<?S0Gk z((U&);9d2dA21_B#y}X+yE_s0-aW&)>*;q2)AO{cu18#m`Vkowdag@udd3^#dse7q zeMgMW$FFuyPWMLnSEis><*ZKUs4#Ex4c#q&0sKXN&#z+co$h{4fAUnF?hX4*JLB($ zXm3HU^4YDfir^PPo?r4Tf5qc0(`S^_SLH%4<XkWGi{IE4Kk6HO%IBtN6zHJvSJB*8 z<)fdRSFCT<0=ONSS&H<Q&IF7{Yk+j?WUH{@u&AJyx~ZyZnE=Pp+_4e6H9?=VN-i{H zn~Z7P#A(G9D%9zud9Ht2XM5l&^b9ByH9DE#bXWp?aJEmv)VJ`G5s*gtJrTS5z0vEG z`YTcjJt~*9N{`HONn<BM=Fwz`NlI2#`_{N`ts*CZaZOa3qr(0%Q|*t-E+qrB2`5yW zfhyBhF^Z*e^BSMp_-<FI)lLeT+lfL!zRTk#K|XBI3t}jHr+GfYwhU}kJ152H9am>& zd&hgV9;F|@$5CnJyu#{~UaUg2GjO~gC6*wBGq}@FLJRMb8OuipDg=M!^{X^CB~;K@ znka?t;Inc$BH<g|x85v=JsFVUMu63HgDGg?M~E(9XGm35dZ*jS-Z4-lw}=^ud7G8* zO1MEo3dV*#TEyi>k8yQcO2dmO$w+G*jtAr;?6&Nl$qx&^N4qd&F9C{``^_-jYH9{m zO$&+(%3?|dd9hfHK>7gcnlz$MYXbGuInhI4STj58>l(Dcj0lZ?D2bCL#TJPBpFPyc zSlT$b5JsIGEG7fu6C}hB7`Mze&7-Twpmil?xwI`|tJ1F^c{B79a2u{+WF0iPQ1k{} z?l4zdF)Nb!3|Pd$qE)aSbzY+iU;+M!-<p4qR>r}WdaACBa7!XQsE9wumIF<Zp8bsy zHQ4s;fBG@H!<~cEP#gS0jZTp|BP1rZIR~$gHl0ltVZxgUUf@_GPpjlWu<};{i+*H{ zkE$pPZ<HP83P|b{9qy8*3vfds+c*HGfwr>d;VdqLcIDNFA2-sT0c9`CEJP$uRcph& z$=JP-5~h~Xl7@k@ioB>u9&^%HWdw|OI?oZMkS{pcozW3<+K`avSCu_XlP0YPu}D$i zNgqm;x(>(3bkzjWHW>0^L7q~gT!=_wv77DT$xND&=XnGrNcs0L(%xh&pfQJl4mNwI zdVL~fW+j!Ott@gami)PYWF6=5VM_tOX?{$6KrB7G!myqaDKsS3%<i>pNMG@h=pr2s zX`o>(I066U-}Ve`oYlLaya}KeO90e}9Lo|*mlQI%;>A`_W~mw_c+@+Rz)tacoAu|v zK-#r8`-e*!c*CsTMvMT^LscyO%;1$h=b@*Si>LRhS((}CS5}JoekRc6Nfk$&HnAF= z{1Wf=B)M(KC(7`g0jo^^aEc{ysyjtB@2jOB=|B)Gh0E;9*w|RhcK~m6Q#T<fEn}8c zxJbtwW$y7m=eex0iynGBl2D_^j`Vt7e_2+>7;7g7A82+lD>kt0(w9}*J)$MYQhC98 zIb462aaCPBt!cU&nqLhoTvr-fMx7-Q9$5+3u#~F})FdNeeZ$zUocA4gxa4fgUN|%B z5G^V@v-B|5e!vQ;TW(A0B)FNHKr4kN$J?Bdp~1z>^iXzSb+_)y@n*R>zT9g=uCKXU z^UnrYQb4#<eJIA%oqh|i2DnppX&dLbA6Rlcyv~mJ6Fghv955i9Jy5VxnS!q4a@%X@ zb>4W9EqK7gTkwn_#sKd5N?Y*nO-(vTjB-@nFbg*Hih3tSYDHUAG*OcWXf$dZlNIaf zGE46bpk#!tMeCVztEZG>9C1+BP1a&fObC#aISTG#l$<%8uqk5}v*$h10oFeLifYU9 z<jxd)$>CU_uMPgHx0*Dy6s_$_Mcilk1MK71?AAU}<4(PJwNvB`Him>|?-&=+*AW55 zbfTTi@(^@eDB=mIOn*b|kH6JnIsAkU<?pYdb_?zVdz6cWjjY8NoOFAlZqa%-D4XOh zKP-F14`=`I%0S<nP~W|k92R&qGtuV{0IYoQ0YzRrd6n>Bifnd+%oTU$As)jfcUlkf z5gQNz2B>E*&OQ={vkxFp{N;bpS$)Id2`|WrpE1UhDaQwWB=!ff_y^(&nR1?|=Ux~g ze)96x-XVXG#^e>-TYMx><(Ar8eZb((y-YrKjLhC6mZ~z}TQYN_>fE8uuM7Ih9iEB~ z>mMV=h@FvfoN_8<X9UVftrMucSYzQI!$j+*Hye8pk-AcUxW?%3p`-GZ-bsHnj*Px4 z#_W{dTJVe<hF6|z*Ju17G|v%O=Ioq^vpkMwS&dHCLqHskFCAZ$LC+~dX7;Xgk)}ym zF<$7erdYX?S)9;S2w&t)kG@SC?GW@b7U%GeDx%s<q+&e$aWj}&Q(4j>8d~*JDQ0Ma z*NeqC-PU!oSY^Ak47{NRP^6`>=om%o!NU;68kx%saOi$46)NsZ_ZhJGiCXb!hpyhj zk|XO{_^7G2%v2H@Nz|4oMihDD;LH;FW-7MrtyqzLMynj!rKKzpV78hoB|>~2;bh~q ztCehp@{{}#4(sMQ_D0t>tMgl_#L`TQ?>)9u14dqxwMfJN%QgmM-XS%rMA>`KWM%f( zEG91qO*FYcT<MI0p7@tu@ki(dE<%^Syr@vtv>t-!9SiUHk(16JT_v~U4Fm0z^J~zj znG+Kw`~-b;1juku0t!!B`G=yJqjaT`)fM9V&T-KYkNZo}v@T}|lO#gY#0{ooiMaIC zZNt{g3L#nar$XFe=Qo#Wyc-FV(m!34L~`;Z(HiL$Zen105apm_*ryzBQh^CXSZ@u| zEB(5)Dgl-=w0d{7aPlw`HqvFt2geyIY@k{#Y*<=NFScw-1tug3u^?Ni(OJFEu9<@+ z!#<Q>YV?Q%=Uy{*Xvbou5_fv0U?S$bk1I1!g8NAnRHertD|S}4>kB(ElB=mRxwJVl zr|5`~dMpGb>GD@>qSD2okHL76;o6hXMErel=aR{*r|PJMM}3nIQr9eCOp3f2*Hc%L z#H8x&^UWdRPTl2X)NRT)=ImV_k{q&V;>$&5*7jprt4yY|sVt!gxhI{-9Oh}BXqBN5 z*V%oomx;_y@`gR+DP;`NeVR;3z6c)zCAbmsuf#3H?2u@;uQNjWMuh&qGd2B*0W2+U zE-lUakYSm}ysdvFc?q*y?a#NjMw{OTpGu=j`-Sj0(>523CgvCrQ<Nf_YtwZpNU6l? znyWER5v0wdZf!MmAthLTsoda`Kd0f9A$?I&U1O7PIyUx(2O+(2^f&{FHT&DRFmhHT z@&%-r5iXFQyG6@cn*D$+^x@u9x$55I7mR(z^0~0Zo2|0y-ZrPNq19c!ZrZf6Wm>bo zX5z5IWuoBA@+^O|IjI=kZ^}5u%T7nYV>J-+$OeKQK&}6=1$3zcO>x3Oo}YQR<v+?r z0qx;%peh%yb;}`S`ZPi5^z@qS=#=-&>GRCEAVxU%_Yr{?*pQ~-{T$dQEk1{in4Pxd z;mqkuWuB;VWJ110McA4`0GnY`YO*{ia7lX761^rLNK4XD3zWJ#RB2^yTLt{$QoxVb zuDootJRtUmvdTK7E3X(`N74<EC<^$Q{CMw);j`t`TJ|;wcdCEd={a+HN??)snckGm z-lby)JTrIsY}xF>=~zG~1i6HBe$?k|Bl{N&xwGTF@5+SwY!PSH2cB*8giR+rTP~6O zZsD--q00`2=jGM$GqQ_s&bGcC`|Ksoacoc&v2_Ymxuae;bC~)mRgH66=cKN@V%hE~ zPLY$%s^xK}fwk`}9Sv`kJAP%BGT&&^hvdDH27slVF*&5cJCf?nXT~v8zcytSvj}=* zO#QZNa9W&?!wQM7?Il3mvPE<qt+jSak-qOqk3$SycCY8yIraqi1?()ug86X^V$`+} z$|_X$cb}WKVH&kznC)77<i@#GN30g5h;1`^m0<^1>@QlD9Z~s%D+t>%<0av`!I|Bk zM{y0GoYxFB9^gjQBG~6ZUI^|mgX}#5`a?S{{(cbNb_TR#xqS9sfmaoe$X;vFGBG<v zgMVOoDjs#cP@0tfym0Xx3Tm{*iWwe*8}@#WDDnm<gW~Xu>IeF9^q&jw-3li9!TLt# zwgM;kf>_*@8TPsd01g<nJOa^d@1t_5^qWH9+34K(9MbbYhkxxzkDM<ohMed(uGDr_ zKBuUy@uF|}0RC?OVw+k@xEhEJA^+_FA>+olVU?&&btKcfE&WaqVj3bn)m#sqcoWL& zLXzYwqJq(g>AxYYC=z4g#Co*+0}x#i^SUIf&(@+C#^Hs=%uPV56`Rfulf{(}9B2Lp z^^5lM&UCG5-(={EDTPO7g0aJgWv_-ya+y@+@F}l26A7!RZ}8|De5Cx@0quZ<*4V1< zSJ2YNDqPY#3MeAor2OiNhk7~%>rTpwN1_^IPX02vMT}&(oywn0(oT=nmDokpvS|g_ zIRuQV5<%x^fghN(E!DyG!7W0J0%Qp~O8!#<u!9WGzHR3aC@#qLc0fxt{vEV+rOOV* zMP^(GTioZDW~F%JW~Le40!5{nVrQalc919Z^ONh3e()=#7~ED}mokoBPo;EhD<0U@ zPaTX}UktR95it-x*;LL0ar2>rN31Pv4Z%=D{D=D-;Sin3^Ui7GZXvFwxx;W=c8z2C z?75~_wresBMFvyaeu;caP%-QfNhdbLkQ>Q4wb|)`G1H_F1*GXxdKhJ5_KO&-gZB~! z+9MX!jX{u?iu$UXCfH=XjbI}?VA669*J196Mmr%NT<{sLh)$LGpDkb+&ESfy$O*VY zHn*Zn5h5vQb)FH03U81SjmR166B{z*=P6eYYd_aXsN%r7Xvxnjk)Sk~^mHRNh2<XB zT~%kqr(NYL)g)98Z6~n`Fy+?hHmpN^u7T{uYap|mG`nfd>%2OTYo9zccJrO`{=(kB z;Mm7+o_b6d@g>NDu1Z{i`LN|}pZXi;6<hZo1Up^CFF;gCh$7t+J<<stXhsw-1~n5C zVhh%nB9yWd^S~1#;EOiCQ+<XPwrU2RqPnu&=7{g-lsO2)BVATOoGQ&(vgHY4moI0{ z=Hs%cXF|EkKt1mktu{j5@?MR9fi-o4ja>5x>e>P+3jOvN##!eQ+srE|_5V%Y=^4_p z{!UYY_XM$CB4b%sfm?Lx6}K1BB)PR3Jr5UW4&b=v!Sy%ex3UUC%#iiqd27_tj3kkX z?~gdE6!Wq5=gc%{u5mcGbqLi<{{nN!jM}tS361A~^<@_b^`3$N+x48jD%}<T)?|R0 z;?L(Fq76a%Li`2t=Rn4~Dc~NWt*d8MpIMH*8FZ)EyJ2e?df)B$tK!6Y`cto@^IwlS z;n9k(aFb>RopBD>K3=ED{fr3R_5N{zI#(8t^i<8JF~$w+(vHYJ%8gZbz4N*eO0UFF zsd9FP%uzm3Mwx?AOLv1MmmDQ!$((SqKn^#Eqfi7>1Y^8zK|Ze}v;*Gm=ueF0#ouR8 zZ)_+4HocZxp^w}B5|1#u;#*-(zfkpO@bD>oqBq~*=!eC?7jKffE^z_n<Wn)yN3ye2 z|60|0EpB_%@(1ll@=|L*?1$gy-0L4ryjd8(ATW}jM$bmf$4w)1aZpLiW@H?Df4u51 zygvF0Mm`*4-V4U_vnp=^2m)P)nVezCVimmtGY7ZcT?IpICzTY>XCF-8k57`sRLs)I zJATGFTLPq;)uG(z2$~Q?z6MDCg8a<y>Sgna-8_4h<?{kR1hBuZ&Fb&HGuj=S;cXwi z<NkyA{=en(zPaxo_D<&XR)%hd`tGJi&i2OErY`iR|5(NSj}m(S(&2e~6edmoUhqx- z9sv>fZ{PhtyS@Kgne3mJd=qBnkQGrzdN<{?xn;h7C>5A4;=1$?)v(w_!m`FN=5J?i zo)_q(?^v4I_5Z=K@d0Ne!6<^p?@Mzq9?(XZ)v<Ck)QKPe>)i8@v&)(Bet5I#{$sY` ze4yV8QPT!Rfj*y5L6$;|2}dEjT%z~(8ZvwpxJ0fPnYaaW%t5Sud^PX)P1&SAFsSTl zL<d3Z)6aX`k`zzMJ)5Uia37aK#4@U1CFj#NOvNubIHA?mk465S5;wzlIxbTUQa?BT zQsBLl-^=)Nlo=v{mYMjxVazT4k%-t`6lBQ=HL=jYP;{b^KVQzfsuggfzShA^^2A<5 z9A@EaerT9M?g*Qwfh(_C2%Y{aa9e=n@z8kMGm_jJJ{(0VFAMRdcv|C6w=5!qmt=Vb z!tsrVxfmma|Eyy38i?Y4;GN72L%KDM?Wi_?anaT%(2AKI)6w<|0Wf*@r@%#iw3j=n zbh;a3Qu}w8s2FBcIh$qi8ud?o2AwlD4NWzgdI4@YmG>xDPDpkW19UFIGO9pH?1ztg zBb}oTGF^G!|H;b*BZT@E_xr?czIEvS3*p57fEY<TH$xjs6A?of!+$#Ml*C!PMFE77 zUfJwm61k*O65B*zTH3ufpeX*|M0AuXfkY(V#-T_XZB<JKHYVJ(^8HB!gd_?ia5$Wg zh#nw%z>J-4AQ0l=LFVSYIj_@K9<#napTK);UZg1Xnj(1WCBI3hTUl12+VuKhL$xS? z!#ar(gJW-bajzKb#bHu<ZbJ|Og^2EDMDBoZ>#EP|-*qsen@_@q@8W^L;4rW6v8N*N z7%awfxbq9@;>!hx5u=Oh#)vrg4boD-&NfxTlvy{(3(;`72?x6i@MWseKZ5!BQ4i;S z>qm|u+1uQ46_yHF@8vkGa&8<V`gzpeFtNn+E0Af@0mxPaQ8;!?)Y<xlG;iyOLs#%I z!$t%AsIViFh(g6KC<o=VN<v6}5f%2}DDy;B&zA_Mz<pR6MEw%q=}d7e(oQTZf)W-7 zm0q}%GL~u@bU6JA8>+vr8sAm1ig>fZI6u^8M$?;?k<>(pmi2N2^$Nvob_5cggITJT z!QYPiz_C<a8lzjZ%X@^WA$0~bbK@g?5FB0|rz4bZg@NTtpwcMNWsV&YW%+R|Nu@kx zHsB+~NVRx19WNWQQXXR}RZD#)rgVm*C6~XTJ&a{4<wFfyS8{+IY>(vol=s5M1?kJ% z&tGH_qqcpuolTfFVZWHno!njfVur(idg<Jg+f2`^Nhy6nsv}3GX=V2)J{33Cm6bL| zeHSTo=_n9rRy<K2llPAx^>0p17c+IOOW%QJ59G%W&i_H6`B%t^IT_miUory!z+B9B zX^YNAF$qhFz$AYNnjuu6G$N8!1&WEIg><b&Qtd)XZOn??WCr_zKarzAwkHT3&ky-N zNX8~cRcstc$5%HV?p=FxvCp^5Me`q*ZP$iK(lqKCwT(K|#_iFl0qrW7v_-8<6><ma zHMBr?LI!5c5sNY-n%ZK&SnodHXLI88v+aSC<Xx(p%7En_<h1*?Wu8;|Y|4$F8vT|O z&E(yPCR7HCr8OiS-e!{Q-13zJ#0`zS`msG}^z+K)GF{+R(aPO*pV*4<7V=T?Cnav} zu|11(za;G;mNE&m0wqSe4cM8vZfw`ciqE%C$-g>KH8?KUxf#YGe;e7h3}6Q=2bzxv zy<EEj*|VQ#)o!ftoEYu@0ATD7j=H8|)39sWLGpaW{es|mAzw|MI>Joav~k>gGOO}P zi*ZIjHP@wPim4cZB0J*;vB0G;j-0W4qv{WmZivHNfKK+5;S@YwvKoG6^nWp^GLz)x z5_C1K%qkkgUnvNzJbp``#hl$++psjNhE>1{Q5jQfiGQnS2y<{jWF26r<pVp7KClX| ziW}CQaD?WhD~`Z@*4o+z+EUaD@`+0Q%~Q>D?CI%^!y2yB_-+C?{ttqL|B{oe4NqPc zzoByV4He%1DOCQ;gp@dMha`v+`bD{^#HOvSU?DiPqSn+p(voQbGcweS#fWXM)y@hc zV{p}B?Uts7KS_;5@ACtH7z1CB*IWaZh~#3LpV|ELi`$&-{d_Yl?#Hv^^a#=gO_~N4 zP1?iSl(Dn{tztu}p!RS?>;QU=FwmWh!7%|;l1iwhHkfeB%kj+W?bAqSN8bVn?!{w) zz)bfJT0LB0E|SKRYk4lbzPpMK4L6Xgl<yL0H3>&fQ(+363z5Ta+(8dODt98yyfR5- z8#%@6!dAUo(lT_&I;4zguDgusiWJ1N5bvwY3hJtZ54>9-^w%v#jO&`coJuUXqsz#2 zrWqF|!2XWLPh`aX9r!rIuyXcna17Snj{ThiYee@+<UtwR8Q(GK0S-sUaNTU(u${`` zmcKWu@48nCZ$d>bnCADe^KE;L-%DwVrd?0@ryC>Y02<nP9>`CtG2@IC;2boA!NTq! z)CFgic4=0@%X>RUfalM<oi;T|TP?vJp4SzN)97Cmg(huqGv+XP>6~&5#<wF7(2L1L zuJo7_Cu<ps9_~P<!mWz^9T_A2Vq(4`b~ETOp21rzZ89LLFl|h1pTOu$42PA@4l69R zQf(VLTOIw&GA9S{|2eQ2JhaL=e51wwJD>gcfknpB*3w1P!_>so)a0L%Sx&+(9f;s} z=`!Eg^4Z$_xznai!Un-ELS##t5|gz6&Caxq%W7k8>K-Zn2Me!1MPvxX19El`bSOhL zVy-QIJU7Gn*{AnG_T>2Q9cCZZiLHquli|cba|mYWoybsP7%U<=lahD~6v(DI2BkRF zyv{ioJa^&O(bLQ0^LV>4##*Y>1#W0`)0)9pYLNg#w5L);kX$F_f$$DYh0-6Qy!!0D zWcMh|Uu4Lku=J7IH=Ml(<g0}lBA+31wQYC9C1mgsm*cHV%h-qzh$_7k+AyM{%tY)* zmB%ZtG^*B<=>`!QfJ^is-8ilW`sZRyzD?v#Ba^{;M(Y8b!8iUc#_GQ{l@-)@6Zr$I zUt|+ptj4`ZOJ3X1&|`DbKqk0<G4i(ytKm7{&g?J>Ib>3%S-_p7U#B)f)_!fU3eA_| zx->FKK`-Sz8^Rn?u8Q?cu9aw(y3aAB;?Dt)6Uj9RLz4NhI}x0z3<4Qok}67Hfd2C_ z7GLwA{{B8j<?o;Vzb{GT>|K;i?Mw`fZ2mbtq$Et+Av2<c#67UH6w69x&HdSIq@pxZ zF$jw6pd>&Q)s0W2bt+Y}lCZ(>rhs3-^?t4<YS;tvK*<F{0C0hb66)qB%yd6zKfK1C zUe3<y|FAh!Lq*jwZl7@qIyMV_g1`ozlq=DSeWP;S$V7jS107-x80NLkP8$InQz#$D z!SjE-d_Heh2plJ{ZQMeku-gMbrM#adAeTBf%7bip6wV89qAkkiTObWd`z>?qQ$HHq zfZ;pXa7XHnxL@x@V6$cQsPU@+5nhLuVCeW7yUHiw%<{gsHxMlBo!JrM3owVd@-3J* ze_-Y{ILX8I=lo!Rt^G#7SK7P>_Tp*CnVgfYXIvp%PO?4dsyCW6Gt0{|dz*Q0v2UE3 zL$S~_)iktdYy-T%{D^_oXT&^nG3!Rn=^Fx={+jvgggXRW0M|g37mD!42y}>W11g{@ zk7s@!DAzAZR;eIPp*P6r+FA{evH&NK%mQ^Dnb?;!u?iZd){A6#5j2<9X7_DVW$rt4 zgm_jT&{PRlr#Ne*HKaCea9ZPwdij?(xta$q&{U%e!D#1geD)RkFx+5hL%5HfSM~n* z2N?eE8x8jVI|G<~mj;%0=Kmy3!<-&u@$)+n6n>-VzcBIs$BX|e2L7)F#=mjaF^Q7) zivl>qUrE8~rQE?KSK5Sz6_)J;j!xN<^+#Srn~>AvPDzAPkc?7W1LlW);Co5+;eY!g z2AV*|aS#Sp#vZ&McKpz0F9*}=!Yz_oSvrd5L&dm?x`?-I2hE0P#G=eta7OnT>_UQm zWspwv7^;**Pga1B5Etc8*kjVN>g+=+uYHe|?vq_`t2lYqoZkiSl)1_(%ASKDiJ3CV z8*CUIypBmYi_AS*1CT$4ELsR{CT+lJ2U{yc?IFoAU!t{o5Kyaf=g`HReMV1X0p2gv zMMjJJ+^}|UU0CS@6<U6Uy9Up;_N^1Q8WDrqTOreuAnSP^^`lZvdiL@wVEgg&KGSSn zVM(Z@3-DslyqH-*7Bti4)R?ByrZ}1by=P<Qj`-kZ^STT&n@&7%-t{Qbrrz{C5Kn>} zSLb>>7x3QjEE~boQP1MInwRhf+HzGZV*ASN32T@&;zhZ+E<vYG?l`WwV;X+Zjz>=! z8S@j>9c$Z3IqCB)ej<x1?9q&a-Mwo^F4P^YJP_c2?Xc2s;^$ZVN-EP0u_g|!6v1ev zC!57MxdMIh01U!dFXaQydw~NFd!Qlc{nAk6PiiQ7p!mu!9Bt))Apb~)$Op(%cZC9? z2h96VQTX6{^8bkbAq}Aqs-y5pVdDHi&<b<Hm4e&FR*+IrOU|<Rt@L%R{|^-YTgmFc z36kpx{_S=N|KkVK{~v|_2TVe)mNq7)PXC6f6g6vi<Wof7m5y~IMh&n{s1d{w$zU37 zAgx4T#(p?-MPmtBhk9W{)4FTeh1y1~^|?~O$%6F4T=DNmV9AXI=?$aAv1})~mo?`% z>bHin)496WmFJA@78>k~MEFd=_PS?YhNsz%=HI{ket$9g<b2kG9c4u3<4z0D2G_-W z6jz)Tv%}B?YY~$aMHo;+V$Uhe7^nvj?z+OEiSCJ@oMvna>wnf#bfAl@5lIo@ARa@U z5T(Z*0O{Bak!tpm9841FMH9u=g|Dj*AFlqqxx9agf#{*U?IB&GXFJ$z%sjX!MWm0~ zr$+3;>USr4sSSknDmc@b&~<v$@$}OAjcSAEtCzLNRBC7nR)OcT{QgZJ)lljNB&s5` zy4ILvKpExQ>M@%$6~)@7Gqb?lvdau&Dj-PQa7;T3-?YOHhE~KSLvwEPl^ox9;Ixvp zd{|Di9j&W_<!BZa=liWSnll0W+Ud=vRF6Y<BxSU=0PC8B-m6LSPl1D(AC+~TC2BgN z@wzxF(Q}2GA{EnSbaV4HC_zDKNp%n>;Ifp(UX~=X37^8YOQRqM!Q|K|ps`Y|NORT7 z(<g=M$O#75-KVmZ2;|IL?=o33HOtMYIHG=fSqY7wJiJAx@>|R%LwB637@OfiH3Wf9 z_w?yN=!C2#Zz;xIijCesvzQB!rv+X}tke{e?D8nLcuP66fL=?_xu<kFewpmlnYt`d zZ6>`L3P&!vse`_O5(M5>y#VbfG=Qh6ejwOW`9}tEAoOcf`3B=tuc?;RdbOBkRCAUc z!?M>?QA0iB$jC&F2D|v@QY1^u8L4G0B4?JR&B$OZLJBXDT6KRWbDX`AQ~5^biT-Jg z%sWJ<@})dbZ!0{Y+CjXljRgF$MlIqfF+z8%@&GGS%|_U^caRyjca$Bz{o{@5*T)Fj zc}oqRmYYekp`JEdCRgYq(;s{M?ZhrKDS7lL67e^o{=|iQf9fK_b8rRuyLAZ={g50+ z|I?iP)fCw)(Y)G_f57}weKac2`Q<k`evaMMbl^c>0Ds7cnumTz;YKClmuWpla$|U- zCD%~DF2pE*7Ip*86$p>=xC3u98&Sw!Fd&W1YMt4^o4hJTn)5vj$>L+g!tEp?xZ7Pi zX(g}|B%YLa;lI_$V1H;hnB31oH;b*Vo_B{)BFyBooxxa3pgAhO&Ul|upgB#p<+7gr zNUp8Cp5d!gTgiQV0mGSLSmR2^dfS{j>wLr20TXeh#m=uo!>zek;5ko)sRv@OW!Ynb zl~0Ln8WYe2=F7v$*j8$<oyRT%*RW#3>-R0~F~^Y-JRmmHIIlVBrUNHVx^<seNX*$$ z3XbR81Z_QBNLTxIk>HVL_3FH+d0cpNIsLS^21=-HPH3vu*<r3Bs+Z}l^xJ92eF-=( zv!%xK)uv;O7qD2kHgfC7k79x#5Vqy`*=ZSHa9WFl8=p`!CR6B>Ee~FPiZlAQ1WOTR zApuGaLDP1US7bwmFgNhU$B1V$tcULpUJw7?4z-5dj8?DQY`51@fkx9pil!rCfyo?7 zV2aJS8L=$5)E2dQlJn$fN*+LsvBx*Ydho`z_s%7)kEDGmrGL&<%jM}pt?PRCD!8gT zz^&!Fe9@V>on%r`Fk%_xbHGz3MeS<X)3D$t%z?(!Q$qS@TvbFH*!|gC-o3VvSXc1H z)}||DEF-nA*C-~+qN6*$C*n-vh-~E=b|grfN@4V%Ujg)TROlCe9=a<9UL<qKNrOju zT_CIu)fz`?Vu>kd0U{WL3v=`}%(dalDI!_QkXdoM8GVaoYIk19u4JtnWA`?O(S96b zg`yRi#tV*e25F`wRd6&AeF+t&S_;f0xiNeVcm%S;T`rMZyhRSjkgf%&>PO$p(<{BJ z(ETxr<|{<Q5|LJzH}x8eSOe!H+!qk@^`T{2FpH}#YI9r($bC9d2(HtK@Q@bpS5Kgx zJzyNw=E2RqHh+7&rRN^cdv*EmgRV_y$V-N{$KDiC>kt?98kIfOS>;~8D2d(TWNU*d z6QDk#|0IS1G=<g9u)|TUGiv;qVVkeCBTMpT5D~=zW%sb`0TxD`yF6-xxL9E0xlukZ zGR>mBsnquH!&LLfZI5XiR10Cm)n6+LLv_!_6W<V@KCoB4_w3IgIbo++AEeqsQqry+ z5rFubFD!^O34mvwn#pCyv}x6Qcau_nb&ipU=85)Tf73fCmkF<{Tj0u0&HD#@`=#P< z=GgWs^g}u^GIyQ{eg#~N!xXR7)Wc%Sz~@tpThCmNSdrZ03g@f%>@4|6790WO2yQui zZOQj=X$AIUNTjX3La+6eou?#^4miurx;i4;?`PzP>peXF6S+>>F8a|KqMH~^dm*n{ zkzTprb!Fi_f3bcfVl9$~bEP{XcQ|FpnJ%wqWb_$msa?~e6svG;yVrWAx@#24%vYK3 zRoKUxb`@ycmcUy_vL~m3z1VC6-NTlCHKdPaA8VtQGzkBGPXS%uB>-pv+RkV)qK^2Y ziS8M*Ylc<onnU}mh5YcJ#~6p;Yx!xv?-ronl_Bl_Kau}yLHM6@xT385_e9w*RTEcH z(2t&^a7M@FD)b;JA)~;Eksx$sH*h5ltp&8?-jja(y*Q>Bx`}ZS-e&s^z>Z7l!{^-_ z*d9tJP$du>hz%qP?rZ4+aLC)?evrV}>GRkqS;3FZso&z7GzwOhvd>H@GYQBX6}uRl zQEyH}dASvbGCTzMt~EGR+fkX($rAL|%<r%67uuY%F)}}&FW58K7bZkvD#}LMHc7b` zb$f?c?k6nJ4aD;&dc3JyjDcWFuo2z|xtUuTSyd-mRPO;;#wlbbaZO#o-<w<jQgn*b zkmAG$w=($#^zy$Y>;Xl7J^_8}@K%|>v05HQN~zk7CO<$Tfq|jB&^#SNfaM{jasFr^ zoU}zEHCba$w#~3(X9V&d`_vhPFq+Wq;Y^~x|A(I6zxeYEilpQee1CJ<@7>aGt;qiu zG4YRT{9nJj$#;jDMBc&J-sIoCPE!82G0#SAG5~%3`{wBiVwiuhNoF%;m`an?5Y+b4 z?^0sm=u*1*Cy0Njmyj5-X#USSz9|o20Rb(-QP(M#hu40Vv-5YauirbQ0q83N$=0$1 zJOFiy$|K(p2fp32*hq-@)c9L+Ml{`6N;KG5YnWxUjH(c4Rb|RSM?Kzf&guBu?Pi0@ z9uvmtwR?H30rN5Nazn4yjxEbA$*^JV&vWAYNx|z$kghdbwYwX2`(*}rY-idQNwfP@ zDkk@&9HT_aM-^1cCPi{1ebtaYiqtG;GABj5(K-Ts@|s&~TT0oCbe*>iA%5l)+iEM0 z{9`8d@ld?5=xB@db<p=}_mo!74n?7bXBr_k{k_+Cha_oqs`&Rj2Hs{g8g{DYE*o!{ zIzU^3ZrE{G|Jbs$`H-uIHFR9M1088IdE4u9Zi;Yl-FaGVvq&m{!@b<H>V~{de{8z* zI><%7aaAJBjAbL&)SgS{&z|QPQeD9z6~A{ASL2#Oys^evL02qB?zx1)4m)!C0^$kT zz%&cHqMaFoXm=;MA%xabsC41TVFa{ts`Y#8GSPm+SHeKOmt*%qd>P&Q@6N0;CTbVU zk#jPt42D%$gwX#*+B*kH9xiLbGi}?pZQHhO+xE0=+qP}nwmt3c**^E+-gEYz-Milx zQ56;S$FCyldGpQ8C+Qve!ggi2ID#HM0N>3to(R{^tOYuNRmU#yWrkf#d&()i%Sa!B zX=J>oNX`?I;qyW9Hn{OcFZQ4d&lNm~_|}eK6Sp+eZ-;5WS0bH|g@_yX<I^nYHTV?# zu)w#FQf+tLUUZNu-ZtzqEnb!h+?U7amlC!z0I6IIJc3XH&>5-_ECd7IXfD-gEZ#sk z9$`Rac|aue1aBw^hf{Zj0_dj*^J<@;d=e)bL%9Sfp@{O8-Xt3cCx>p5$UR>KMckkt zEo+#uKV>Tc!Rhhr8wukc?|%}8zsS41-kBEdx1NFfmU)W*p}hZ%D8x?5^z$JF&m7eR zgog4CazkPuk`5AMeyf@MKB0sDDD-tm@<sCna<ZD^e$d;z$dvL*Exm*>R!7h2F4N<K zhbwG8P-)P27#J)p1c`yw2rm*P&|y0VcnixlgmC{W(2!W$j+mg~poMoKOwQvV+s3Rq zSu)AHm8$h?=R~PRCECXY$QY}`DK_N;Azo0E{5OFo=W@-R5Sl!aYt1ew!YkczSOG<i z%FA(}xN~a7>!}e2nL=Xh5i6tojcqfr6>mJHY8~$A1w4l3zPQYreD{5OUNB-C>nd(- zX2M36Gs#lZpMum&duHQ05^S#{P2i@!rS8~D(31kc{BvHHUnPMAU@B_VVpseC!CHLO zM2HVq%F$ir5I?I+A^Y3eo{e$@0fqI2E!@?E9}fP7^rP_c)3Abks~DJXuJ%8KUHp4Q zG5z1LS3UclHi`77i)F0vObnkoxE`f6wisF;z6?oSqZDW&pL$V2z4)vUn<H&-EU1}+ z!lpI1H6old6q2Gehytg_Bic7{#M6{S98-Y`*I~!o_4>)@d7CxC_v`b3_Q%DY;ty&z zonSf{I(Yyzq0F{Ci&8N<*2zsU#Hcax<f!`WX`-<~y?BFolY1b<1o4otA)<-H#Gtw# zD7&q=2c0rNqbp#JvTt`twg{c>>oE(RJO?8U2-$`cj6W;;AAWZFp?-%UY2WRWnRViB z%Y#;kI%(kK63i_H=%tMXat(3?a~bl`0ro@v5+yY67Go*)GW~A&(%pZuo1m4il~JZe zro)Fil}zrPiXSC9cu8ST7Va06BTJ`BC@_W;Xg8J%h8HohFJA#Ls}q(Pi7e$cGUSyc z;`_gDSz$9bDm5DRD{$6_1zFS=8&imcxGmA=Vl`WYm{=EJ2~Pb2=E`yrVBSj4yPhEd zRc=s4Uld2Ulo>+)tTnLcbPdL_6e{r2G)c0hN?Tr0gt-uKb>^BbCrCmu%g)NO#zO$8 zFfF0k{ho29g)87kp~PIN@!BpVIOVDyj;H>7Ouv0%!1XH#G;98nz}g@9u*J*Y3w^0R z;VvlpmLC9pde~upZ>rBL3^ioDU5~JA7Sw<1z@FLKoScww4_bnjk+@3$lI*O}0#4DK z82p4n5WD3i6iFUR!cDQ)w#b7jA(~1qMOIrC?5C)N`+Li<b4wfmcUdL6Y6sJG?E2Y} z?nE&IPA^KDiBCc#*s=s0?E!Ts^?{F7@@;hF)@eNa5C=M}eoSPSo0>?Zu{D(^>dlxN zF7D_H9IBC5P>iux|E93dEjdrZ9lIlH+Is-5R~TfFyZJJ<x-_oBR2e(Z(rGklkt>)k z{cHNIxpm=dlW+>qaWhN%?Rh!9Rn+SJgwth!7bJNSNWvX-^=)5I(rs4c&0Szn1w-_% zD8MTdBjDm*15SZCJPcH}(m`@>`X5Hx%+@2CbPYX0bnB*B)wxuAi8<zu2FNXvT6+}{ zms)a_CS#3s6a7i0QhH1QKy1b-=>;npp{^-yS?}>IsRNvXVP&T*8y3l<u<)tF?F6Ms zc?sL~&0}1Z;)Wof3#bRSK+&4Ad8+wxOYtZbUyh_XEV%RHlem`Kk)%e16)KN1H-vT( zzZWTIse`_#Ae)@AjgduaU(c}a1s>N$U4fK2Y}}FS$JL8&2<|)+A9RnlNGHkQ@kA<1 zbB{(xA$sr(q2<txDFNdNjWCvwn3p$)@73hfLaR6~4t$y|v-FBfbpblJ)Vb+>knb@0 zvT(3FY)=xXh*ij5*lX`BnmoTA&$bEHWjdl7AvC)7GT>IMe^&_sHUd11l7)hXC14X< z4Y+8m^}($0)0)@YU~_`CZ1M@epeo7qI|6R!_u#n`VCO%`2YW2emw>!ixms!WOkNch z24m+9M8!H23T1-z43OFZA~^aSQ>0cHOiyU}wVfNB3g5zOOXQ`@t)&>^W7NgRS`uqW z;VX#Y2gqF3E9PEoNaJhpow16kLRNb>+c~QToet9)YS~u}wiZ>|S6UsO&yQY=V=Pz} zN7l74-51vnZ>^qS*gEPz2csgc7gf~-TdkMuo>1<dG`z<E-q13M&!Mu4mDOAwT8=<< zFLzwo{Qx~%v+nLJ>UN2%*<yV02s-B5mG?ve@;F`5{Aye((lI=AzJb!&*j&KL4{2gV z@-#bg={bHp;t}~{%M`5X7)xpoYb?E)$%BHZxFBj|vx6*!RQNHWuLILZzOjyVuBPnL zd{1mec5NXWd+-Uv+e5og$LtNi;mam~U&B@&-Rq-u14JXEbhr4+T#Em90@yQqkQbnS zOJuC3V5#s~;d7h_>6_Sm4C3Rotl^IXH!M>-BvX5+6EP1Q2pT*YT^hmGNFbl#+9<u$ zT5&^g_ti)Vkutv{=KIkEQC$?b$ZQoPizQj!w|YBE=k?^D+%2`ae@IY3Fdfv8ruFS% zBm*R|ebiwl0;48R>a^gs#5Xk6mTp4RZNA5GRb~%jAb<)AIhfI4$Ip=q&L5DRmjoWy z%zW2c@|Axq{Gp_%*<e&+sv$8IwN4oUW4tDLgUIXg!gOW&0R6k^|KB6l*#Er^GW+}D z$$v3lR?v^172l8i{(k?PFyntdDrjYHY~%EgWanQkn0E{}L_Z%~@XlbWnHAL|48^{I zby;XIUMk=y3HrSxK}W^*R6n2_89lsGZEflv@($}j2X8g&564F>CoLy!w;=sVlbLpo zvRKth!6Y2%BCx<Yw~Vm{q+lw;J<O!!yMWzST8AtYEyf9gqj@VM^fRGjE=!>PMuj@F z{k?ww>i*0qvF*qgd$7-&4DDEZGq8jnR300mC?_zWifk3_D64=dmxSHLjevKczoYio z2rK-SyixP_-{$;wn*L4h?%)3Pe<o>i6A=9JNZK10ZpmSBxVd)mdFb)}3W;UWmaf<~ z&*zzezKpj&c_glt8SsjfJC<y?Ew-*xDE(+C0D%4T`NVUjO4VH)o9E`-xC}1Pz3t+{ z{zRS0WF<l=olXQZay-6I5$CnKNsMsl33#KK!E6ZyV|FNe;$S(~>Mw|A2I&}irOhs- zt+3obT^>FWC+$=Pop-o2Z`YlGUFGoSz*qT(I|2z%h+w3-;f=%9j}k)>bdw+A{xcX6 zu0kZO-(VnrgTeUy`QMar{U;dzkbr-JA?ojfkZQ(6vFZj=kQ>pI6`%%&5)c(^6^}n0 z6h(yDl@SbjE4N<^$B!AIZ^E;kku&n(0!k;m;(w8Ql`Cimxf~&7u97bI{PeIFt(PUa z0NwdpT&Ga1D11=mq%Pc~r*OVwqjC~ZXP6xEjk2tNpA0cO#U8_fr;IDeK3O!M0#@}Y zf=Wy+;y{z4TRLdlbZMB^UXKRjla(M*g9R)o9ekows{x$l+;0q;Ed(wdS@Z(<pMh9Z zAW%&H1_A9miNpFo2I4<Fy1!nJzxj0v|B?CU287f^5z_oAd=coKZ#@rvRuD3nFM_Zi zh^CXF?^-W~?lN|1wJ~Fnz#{E+3;02{zzLZzZ}6ypoZZHLGTD~!`t&)W`a`?(c6V1C zSeVOs&gE`$$T0+)dY)*(A50j-tc@<L`1m$5$5Ho=?Os%5g3V({&WGC2+yiQ8`YW~X zj5JTrjV-b6C3T8a!1oxDxRMRL6~mGG%6-XcQmGhfWI#x?o0+!@E`bT$r2j<`=hs={ zOwgY_P>e~`@(opm!4Mmp;(jlUA+LAINt2VAOqTTLYX&$-!UQ(wI>}D6hVHqw9i~#& z@wA&F=<V&qv(a*kRe_=q2Ca~5-<YA@KN%#4AtxLjT|E@Z-IiP8B+6uF<6Sv~Fo_88 zs<uvvQ(+xGB%Ou2dwzLB6?&rixQawli1XKTXQ>ng8XT>F9VBvmNiH!IV!N@0BBjkl zdq2;W&OCSF=_~nTET*~HI=@FfgT^o|ZRRyOXmO|+9ne`JHp9D`af=utPw0O4uIyP@ zYfNYSj*3fXuW*L_=c9&_dj;+MKI;De_oG%cc5wMep5=SB$O0cyru1fNI}9-scp<Qa z8LW7mg)n=7!w>K#g<XS1%5@^jk-<7b&#kXAoYF;zFhO5FU!?u3V?bhi`M4tQi;^^V zMp@72_Z4bC6c}o&-6ayJ%Zh`hu=X%k5*W0~yu<_{hcptXNn^54>qy~vJ6SreE1#2- zO>nnU_Ug#bS<ewUx0_$xmvo1iQ;Z-7hD>;;E-SD@DNdV+cdFZvOzh_myOAT^Z#m4+ z?2qPp9hgJe1%o}>p*je^MFltnabV){alucFd^oXX1ClBC9pM)a>q!s6+nkyvW*k$F zL>MPb?ZK<A6eb<w%jC@~B}<)-4N!-S)Thl_A>>kTW*rKct|Mf-!__Aw>?%oCR|BjK z5tE@2W6(7Ibb*7M=x6>+(Rwi3`(q^KjM@oXh6^PW$<dVtEhqBb=ic&I>M+isyi`Ku zgmP9Rom6%`CtFJi?I~3vj4Z?y+AhuN3DJ+3SUQi`H!anx4yHx;Y=|#6E6tgpB|;pS z*`tM@!Z4=Hl@Z6uft44ty^Ys$-X)M(u2L!^&j{@7DTBt`8nVS))rEPe+GJ7K<QcP! zV=ZRhHJh2@`;W};Uo8R=Vu;A|_nnXU77Dum@!kJR;OMWH-a2+hV&E?oiB)xTZ#Bq| z@I-gJ`)&LDc}irDaJRXjYb1j8)~ll?`8UUX-#mIyTu5oX>(Xb(s|VeLmuF}Dr<MWI zKG~q0zEN7IemVoMELD<vl^w=VLy<duyT0am2aVioUB8WiqiO41p<Oq<)9<UK;Uf-x zTWy|hlv_N~>-L?DdiWPAjhUf~WWV6DKLMl}y`aJVP_0#135LOV;kdSglI6oCOm#(m zBZ>$0?R1pmP#F=;VV82RS}ijrsv3*R?F7r;W4r$lB8Bt>o<tBAZK}$h=5h1q)&}!E zHkabO<qKYl@$*0jUT+U{FB%om*uVUX0>%Ei%k})eQ3>D4OXmM45dSMJR^D(x6oun1 z*wC1VP={fGLjVAZB!WZ{1OVc6iR~T5!wl`+#8EIbC!p53Dp#Q-`yz)WLYAUYCf_dI zFCg;}v2-V<Rz5W5UhsZ%%DG;C`TXVk1y~y@N`7c3Kj2C(WJe!n?nNt`qR<*iY5w6? zAx@>w9{jxtD;gQPLh(f$pk~Zd-G>6B+OjoIKZ@Uyt(nv+2LHZs67K4jW*}~z@hcP4 zd!{im-TWrhB<Xn_v$JC`wlae{!_!-puF?mhh09KD(+1snhWToFzR);$6=9;-+JiEY zO?TBGR5_F6&Lm9A>WOosziXz2x_)vo6QrfN)pESUHqza?VWd{gaWfhJ%-0>i*;B?) z)J-H~V@fCE2CSgn)xsgB#<hK!;Ako>+pdkYJbOi(F?fk6yUhzf*Hrr_R!Z-XoM@;> z8QB6tw!!AUN=|s@jO;!{0*Qj*L$m_MzM+y%cqpakK==`)gI1YNFUkxr^#qAXhj)7x z_!y=F_};+`Xp+f#Cu*e^OXWRjV&nDWR)`wo5fqGc^K)k8ygiU^{5v9Kz9EVuhfRLD zzV-<9=Ca&Eo&Wb*CFjjPZS3dUhG>p!MyZ&Uz8~1SySdQ_IH#-qf*=RJHho}MSy!g{ z{MwxF?nFo3=FGv8?;V6X%fP_LA}-&1x|-I!1&8XWB=k5~q!~6^IAs<-l&|W;d9raK zvxz1m(a?&ed|{uRpwg*)NtjTshL5M#J-RqHOZ-ws=d%?Zb--HsJ^hiP4Fpt~*5lJe zSv+Q2;ahDDS`h#~CTAPHl3UH6Z6Z<(Gg?uffJjf3C;W-#Gf?6#_+*WQXi(N*${zI1 zoQkCjZ{+I};foOIw7mdTK2YOEY~j44R&O9ak-cHz1ZY&D(2dTXn%c|Ium)HkQ;LPt z2*YnEwm`gm37R8bbj3cPqxP0!Y4bit1l&N7vxzoZ*p606$vP%|mF}rO{L8e7T;n_< z9!1Wu5g6Yp=6QZYA%jC?=iRbrlBAg`r5}7Zkw$T44R=~7#=|`zO~s1#$(p|)>?blX z>bR22xq6lMgaY%r2|H)c4h64_Ub@m3RYo8=^3zX3%MHXMSZFZVgPVF+x7To^&g!fW z`Tsg-Oeqac0hDkQT+ggg%AS6efX;kIR05+uXds-L`eG?|CzrE#5zG2rcD57MuloY_ z&o(kmj_Knsej&oQO8md_gTGqEe|U#~=LeiN0Q^uPz7HDN3gK7=sQ4m_kD&zcLs)nW z5zL*95hhTZQ2~H<rDP4?4VMaP%{-qu)H^=3sy`5+5S$Pn5gx$-NjX%x)r`481h}WD z_8x+LB*89;_L<(-@583DAx$gar1y%0s;OgmQr1j#jVoUgUf5A9YLBxbDgEgvx)_&U z9FvX79<oZ+cNmYS@V&TZsFF3ulIT8M2L`n393uEihssBMEujSfrSYCn;>EzO!V4b$ zL9za78X`y9K_<U(Q2)l^|4J7A1&4p~l9OVmECBf7f-1hp*8hP$K7_Qwvj@ZJa)*Nj zfdy<EZ{4V@n6ODrTXKDf1sxR(YXFUd0}tYHQuI;={`BVY{^=&Dn@c?le+uykrafV^ zw^`z_o|Ft1bp9Gh_krKj(8QtNuh_bI7MPqijaZf`{$QlBN3EPlvhSYmZdSO8wMylL zvr)DEP$|`rI@RicKoTr&<Xj!oSts0RO4_2TwB3RL(z3o}G7?AF`Gx+-xqrkvBn^;v zToT>eQ-uPDVFus>$>kP&t9E9l{SWK;zq3$`|6cJs{)gN2FBH^t67tUEyBDAt>fd&O z{Ovg*V-tO6D<?%oDOF<w#s6q7`76{S`i4%n4(@*yxFHp7#SIZ8?g;FOQ5n2h1c0AX z5Q}I5evgcD2qS!w1_ByK1w_`0>N=67v1LS{sb3*qDK5qSGK>q|O^l!NS=-u>{Jq0C zyp6Ek8dureC)*cYuD_pod%oAcfoKf@*i^Jea#FO%D%+_FBdxilkAXLo8h}qw@C=zk zs3?`Tmh5(i6W#Y$hF8G`sVm;f^_@UCfh;{(HC(=UeUFxzutleh;-1>;7I{doK5<-X zVh<tPIUpHG9W+DUsb^j{Q_)J{>~0o{K<>Fb-}E+5%e<{~pQ!r)4)J&LUcVz1%A`bP z7ZlxgcnKVL@$ZO<43K8jeyulOm4#YCxal)m+-c+rdG%VOHV=3nqM>y&e&FPn+2343 zc@2@T^Nx2PhiuoHKN_#skB@kFT&i^x)jyfGuWd6EMhnwkSsk;+h#s&Gu}V^OtgJUt zA?21nVPW;IxZFH>cRXPJ;ri^2BNv+xIiF=ABuF<tzSICu#ZD|y8tQC5bI1vBLyjlP zDV2iB1M4_&E7-2WBFNWlcKNcIRRK)VJ{)pm9<dKkB>5t@B}Sh;(ox?<IKYG^lHuT2 zD;%;H;zOs!a{w`*k|2-s=fHi!lDTwxf$5MFdn21Q=J9KKuCCi1LifR|2mTO1zWG9B zjQ%5B5{kDONr#c6%2@A!SDY2R=}H=sk#Le~;QEhas&L-fQMl#3vE)ZyK~(!}qMpJn zQy6Vswh*mCKbK)EO|bO<xjAL?lw?Sjvt*L>Ij258=^e_pOg^Y85|`}$_sXW-3?iLf z&5$?@op?lL*nndO%EHo1g{Uu4e@ZYz68dO!eFmr&jhikd^pU+P<mS>i^4$Dx#hiPj zIWg}2Y!ApW<nXnrwU870@;;lhAIytMO>}usfhQ~;>&Xr;)i&(J6dTeOxx!nUheP30 z5u#`zX^(DK@B2_sFX@qmLq~I(HvkYD&Z~3iZ-8m*S6>oY#N(YKpCdRkYbdXc6tr7r zZ)vf#Or2Hd5G=m@JiI-0!oM9$n#PHqJg4eeFIk0Hwja$0>AdBf{bi8XPc0+I<9U|z z^BK;{X1!>u<F5)@s0f07t}`O`1YqZ1nR=KD@~SJ-JQB$4S~8uN0nq#L^F@b*ri!;K z@jY|v6Fg##V-YaiktUAy#JWYDzTwk+#HG0ftC`#*CmP1_430h}xUQT!+WC256Sd*j zlar^H&j;rV`j?`GxviUVMP582-Gk7GdHEir4#L3cW<_G<eljoq4iisTfQfq{PwXbj zBShLEqcOM)(()x+iE#z%16z<TrC)!omLe8R_gQoeXmv)2o=-54j$e)v)Z#)37xyJC z<ST}N1V&)uC0{{o^(Rl;2MV(|424UDAviDvq5=0G1@}KA0WtybS0}ei7#_2`;@0rg z<@n?`O)lhxGVm0O3}DR0-vV^XgsFTFvf)~cIw;^{jgA4_VzU9)9^+BX=xRWIDoeOz z%1*(`*{$Om%7^OiEl_*!`A;+Xm*iWsn1qkcx6_*f@o$sOf74<AqPd9vmIoSAu~z(U zX7Y(%E-vJ!An1O`$14H`=%x(i0~Us0Qv@Bk3oJhS*_Y}RkH_!@@+ZPa&ctc>u7P*l z{sx0$QNohfjB%~w@``)rdV5>D=g-RraxYu5W?U~cGKLLBYY{=fhJaLQ>L50-A_epg zvVle@I&cF-J;XKrU;y;Q4X)wnp_Z-o4wDY%OpAM;>r@KYtoL=-arRdb>b*i-$_^rv z^}Iu+UbsHfZ`6kn74&@dmQnO|$K-*O79Hf)=T)-R!n4t~V*MJ7Y~pS~W2M%SA0XC! z_N^&R&^srE=;oQtzL{7ytlTz0oeYDw&BZ6kfob{j5Thp=BEmCjkY1nJW+V;<a;{?9 z*=+PqWY_%_@zP&(f%>`lprg&Bv#Kkw^#z?+?^D<zQy_#%j4c2Y%Z|xAR(fL=Xd%^s zlpTuenp>30%?ZwdnFOuNolVzheaWI=H|Y>n@Y%=tvR0lV<Q@8QRqIe|N}&dA?dmFT z9@!h4P*f}Ghnzqf1AG7>cn0dyA=@5&P>j-XQ`bNrsLB(V9N>#>tR%Ey;@tu6Ax*vt zJn`OIp%YLWe@t!TVJ)_|?xlEa!`?0{ImAVVgg7LRu@+psC)9QK`$9C8>~sg@8!g55 ze^x1XalpGk3UDdamg4^+4$0<l&eew_hc1~T9Yp7-`Lq8~piRDKJ)pj#3X!3N0JRVW zsN_9^X|n6V*;x07$xdrto(_^S$-n^3A~g;_9wB9@Vc>#q5#2SN5=g*zmCR#noTT=8 zfE72;;2Ik;uq=H;M<XK8-j+8%g~l@Kx|^leNI?lr`w5~;9E;Ez^mlcBFb<!zDNjI= z>)gG6w}xG&QKXe07l*h-ea$|Q4F6`ak^sH{jwoCa%N=lBN!nhVw$P3$f2BmI(;8I} zTvr1d=?EfQjLn${0QaGj5W-`e2;A)sSTtC`C{KVXG@KS2pIse70@_7M-OsZ};`uod zaKns3mC0~Z9{eY031>Z8B3sq9;(p8#xYz!8#-K#-z*g*I_GFS$H)a_hT$#!M#DUu0 zKCs^fi_r-C=BIhKF=C|qQ6=Q0IkOs=4Vej_-O#_-!wjh=#WTNtD98}K9j%{QFrIF` z&z-dq&{yxLN1kwuB|N&s()i!kL^V3rE&oephzjb+vDUXAXZ?L)MgEVD%D-OLfBF7T zZbz2lU$W?M*}#SO1^IY9emJ}P!;WF_@(2Xrzi_zHiz3x3ts6T022F2+xn6$oB-*#f z;=sk(tx6qd*mkGc#(%zjy#V<^veo4p@vj9y1Olq&&$`8UlRD+dGrCnc3$h;)(!;|l zUQz-+1kGZFiWM}f#(^ksSq$0k>$x5fz=CD7uK#Xo&q^6>L62m~v>6;(e{f$>+<=*2 z-=>4}po;5zR|&-YlfCCKu?3+>p1+&`2Jnc^WC@8(dw7kdw8@XFeHGk?JuUXgy5~`B zkIx_ex}l0%kXl2<R=f#5GC$OOlJF_Pu*1*J?~YTUE@y1lWT0-$=2doLMQ#hJ`paQB z_f0i#HE+vk0#zc<K#l>$3m(e7hL^w=N@gXCVvamRq<;I1m;`;1b(?F#k3U=|okxsg z01uG!2Z;%I6PR=#%@O;kqE0TCV4c`$cG=Yc{7|ciE(A<N+kc5w|3%q;p5FnJd{;RT zd{_4H|9?9_Ra*y3V~4*h-y)@rzjTsvUjT91L)lAGO0*>z;Mvc&{?sYwb0-tVE4q!H z=gE(1V6%yevLZcdaVu@*y8Y>eWUw4nY8SQ`L0n_%VltiG=H~nPb%)4@DLXD#N0s8q z!KB7<eZUV)%(W=DAh)8&cxs5Fb~Y<psT?B08qRGR6Z85GI44Wss#_>SuwNINr9F3J zjM*i1LszP<ra1s1_`AlPHT+q4Qm+$65Z)GuOI)abmYusXX&_#d`?nykw&|@UYA?H> z%Wv$EeGw+OM2+u|U&h=>cW8?{Z*JC_&EdV?uaWLW(hOmBXb?IsPF~>(>9OfZfs~j| z{r1;2<QxTF2=q%0RRE5ku-vAeXplUoA03F;VmRpb$r90|A7gx6Cx0+S0%s#c>L_*I z7}DCXW|AZG6s$sQ;D~)rt;3wqprKOD&`WbIa-p=#qeGMfLvG^yfwfAyb#qamj_Frg zKDqZ441Rm*EO&Ud>D<}DjiPI%n#|v(>R)XxqG_0>4pfo`r)y1dxrZ3b7Saxa@<7a= zg;g$|lfJPt+gg}>E*{njJqL;?Y6cjj*GK&DE-P~SMfRAUihn^RZdr(Ws@a73OV8y2 zF8mWYm^SS|Swq<&Xuc0?EF=-!2xkS)7Xl*$d=kZ9EOnd}33KYERjHRgh-OA<IgfIN zF|~+r1w1kl#hx&*dY8n;IMT*+&UF-(Y`)LcKDbc09?fi@!M%dbL&6D=W%2%Bgs_v} zJ=@}20Bycm3-A9QA^a<8sZu#pMG}Sk<J>?;Cl%yJfI}~mVx;dcToBeO#6D<8g{BSD zN7>K-9ZAJ_fwi0T-u<v9`#NljsLkAs`apei6eFR)-H}-h&|Mo-R$YBwe*UJc`n>b! z;|tVJ@TCm^8cptw0|c2!DN#>u8j2iEMLwj@Av5lgJBegwe2)E9T*5`DuQc2mEn(7) zc-m0FhXh%xl#iN5;y6BFVtyML_@<(CBv%4Kdx*af2`#=D8BDwcNs2O6{tiP5SXFtF zpg>Q?e@Kp*MnQZd6?wb$Y7*iX|3wSc-lLJz3Nj5K+W4ep_bsp>o4s<*iea~@i9v`p zdiMd?M1-^HsGqrXPLhUwNO&Q;^;!1KY<#yg)tT7pw3F1iwmKX+YbZ%Gmg*lZ7DQft z6UzYxq7g>x32x(d4+_G0D64pYM-wU5&0#odld$DUNYf!bhTSne^<U;`+u$L~qbSSF z(eyzcmrT~x6#5zlt2vV3ra~bDatXE2+>FJX#fOjy_~<x-UJo+;7jk)elJ(sqvvN%H zO>OZ%?|~iM^bEB@nx5P7>-iPN!VVOr6NL)FMdEHo3ryGRz8EJw7*Z2?o2Z(^HoXTB zx4ssY;Lf){yhK`x4Ntr#7*7Vzhu&4g-l=8TqH}%=c{GhjD^n0MMt9*Mia#7-ixm5% zr8jzyz?Dd+?Ok2muTZ2|nhoGX|FVzAS7?L)?^ch~QH;PyhcjMn+vh!FC%Sx^lG4D5 zId`6IG^>qUvV)GsYQx}q!8oqt3+<uX-NU=Rz_8hE4uEB9JP?G&-7}Qf5y`c90g{K# zkvLi>05dlej?D8hj?k7oDPOU-iuVnfVfON;O<ArP(j8EJN!NdF;9tIl?lxY1_R37D ztPxfpa7CycmM)R$d&cnTje)wN&9n({mL?M@nN}z^ZRpSEmn5p|#@dgPl}4rrDsOa3 z_Y(s>G4qoVG}?6^Kg!O^$)||ssuIHpr|i`Cmcbb@@Sl}uZkg@LwxHIu^7bT4m!FvZ zJVUodALrSUFeO6bmDlE$#CTl$Z4SdL$!X`JcQ9e7tukF$4KXmmYA&0De9@p0tEeJf zQOlFq#E2fiNgbJ6u_7A&#B8px1TENV^CE|-&BCqO#>~RBMk0N#$?)1K0!O>vrpn1h zg+2YT0~5jOebz!D`TLxhdn*;&-bqj=hmtbj1Vm6<qqUfDegZmdk$VR^8e!`pDx(_5 z<D6-B0P^v4zrJ9BvN(+`I{DmV?aS}n!kv3oE7a)M9f@}g9BYiiJOD>}{&QbCjvp(x z$k-rY&~-s#h%u9r#kgas**O1H9s?-#uN1L*>wNOJAIj`XJJ4L%MYh=LfV?3P+tF7a zY#Q!Z_S?ZNV#RTy_kk_;Q1?ko(FctZ!?S`)!*Xj*utjsCZfS-?g%rXcNJ`t7sbv!t zD3hb|nUM^gimU5BZ@m5quUGUD2m<(fERwbO=3np@XkS9s1Rk&(xca}0&O>~Lra4P3 zz95rg<YhUxe-o`|4%le)rsEpS5MYEHv8~_3)l^EU;KEYVcL>O${P{E{lOy<A5;hZz zAj2h~1ico>Tf`M6eFAYx+&>%S;}fOFk%Qsy@&4&-1{*((So(@3HDBHL-scX0&m#nm zG0fuwV*NoCeNW#xFfuomaJo;3hWCYaS0JSL!3C7li<A>IMLV#Ex{Hu?f?C&0yNA+) zaM&0_a47&Ryd?YzvB%I3C|4ZNrpV+FnCfZX$agQ32_x64&F6n$@-x_>vm?=yLJ$Q{ zNiiajJ?MrHoSH!C9@AwT8iMb-QtJGc&?t|#b|D6AZVO2mko#~4?~LW}kBx%+4n@Vw zf5`#<#g_mncPd^+`|*RA<KLF={rAM}Z)#h^T~BFgiTA|BM2Ep$AKdZ>K2WStJRA!$ zp`{uT*w3)o0F^8$9Q{!vl4&Wm&5Gu06^jaiD$T0ArE)TKu_lSR_9YF?=jG)hm8vR9 z&87&H?wz(9V}>*-f!ZBhcURt%&4wIK_qSbH9FlzV@^wj8$0RS5anrcIh_1tZVs^Al zGDgWRCrDMy&PhpjE$RhQ^v+F5lA2ilC@&R^&T+}WOGQ%5&UHz_RuzyEH+SfoB%Q1u z@8NwHol1HG>bAFKIv9qqGK?=3IvA#bY}!1gXkNuBBzD#`?`=9BKhtdJRvFv^Q@$IZ zC!#v%Ciu6B28yj<#5XRB3}7&^?&g_n;$-<oxhYc$uqKY!TE<Nq`ZPP4B3i~ntnb-1 zc}~EZQ}sACYqKtn9$vigKLOBn$hvC418L%eBf7l6eYLA!p!@91S#(M0XizDtW4Dv) zFDPEMvH-PKM!#&wPc&$4Pi(<QFN}U~+`mTmtw4TY9v(*3>;HmsmAL6hcMG(=pI3eL zyl+!qwu#%Wa(H2(-I-RMIC*b#!rZ~{!ae-XO(yDRJbsUr_az(gAsV@kpV<QWqh@k_ zci-iebGe>1@%#YD&@!_7q!sSizuQ&snsa#;yDb|e4m*B=pY~qX2aEX;YS!zM_L24o z0~RXU<%G^lqUTEk83U=C0|z9F@sZf*aj`J}9(?I5!qYQ(Y+BSMw)#?G<s$>qlRRS^ z1o<0;mo^afP^pXVL^#by{8%S>hEm5T$(J%`2mK?xuZQ&o7NlpIsdKu#CJHFM(ya=4 z%St%q1@KPH2{S<*8%A?37~hx5WaxVj`}2};zO+hWSZX~gwN9(U-2PINl-5)tX6UXI z9!_M?(cr!G*VI?|vKyU}yycLr-gp@_OUUQla_NxLoVWASy;x(NK=Jgd!O{p*emK!M z;_-gto~>D^20b5+VGgvRBs0%bHt-V#i-*A*iBv+Ccb}NBUIA`lumSQD^%WuHl{nT| zv^u^d%{Fl7JHDr~AFI$O=02W*+&FMDsG&m-y161ct#M9`8c|gDil5BpU6lO9PH&=Z zAo%M*6mrQadmbGcWDo&8<V6v=S??X6C6h()0rHnyAv;>BT5d+U7?IKIfJ1E`gb+q0 znV8NT?)T(9<-)R|L8d#)aqhSVjVcu|M+1}aasf7YDAsJMj#^)H-say`U`tcf_?XVK z{M-$^uIKLCrM6qO{ESCIKJZD4Vdd8L6%sj1c2d$Jbe-(;L@MzGzv_0^RQ?PqVMl95 zC7&uUC$EAOm(vo)*@RGbreQ;Y9ytDNXf>ivu*4svJw}7lWUiX}t@4QE>phCV9Rc)_ z*Yss3H#}WP*-ejzxc@E<M(2TQ3#~@IehuvtXs%_ii$WoU{M1&U(X8~?M!fZQICy)F zy1qQ`UbZ9(P|mADxmx_>9V`VzVOc@8nbN}XvWAy9O@GE$$c$xL&P^cj=E?0!bsYoH zPKgrJm`lDaAg`H=W%%y0yo#JT%ESb0@4OlQW(_*7spoyC*MMve{Ma`{%-uiO_}JzH z1Zqp=ZU}{;2x7>Y_Zx)<>QV<euA*NDZb*yTBR0x>3KmU*H2}-hS1M-gtL?qg%u>xD zQO5*hPFTyrtbbVl3BpU}_jsW<c$bWt0Y(nFQju_T{=mE7=%B<fH@35iU=3cLQl+|G zs(AW57XA+)qIHvgq~9%#YS8s<5hSV!P0;b=V|-r%zHEBI0xARI%ikCTlP`uXM2cu? z?yCs0Li}WI``#-uO!EWzF}|2@YCh?b4pi7}#ANo&2OH}Y7C-leQ$1uOhW1*sVrU&i z=;sLT1&0wxEQ}L?|2<O5BLQ3sA`a>ADB%fRI`@OGVj?wLNlPok6Fnn)5hMpPS_@`@ zn<_JHCbX1QebDZ{T>-&Si8&3rYr2-H(u)AX6_DmZ+-JdqlSfD?6YOT}Tc#jzwI_tb zCQM6epd&r6jdC$EG{0-8E29z+Im{S>ufUYoI6H09YUEq=FA*&Vkw4`2Kfrwo+8(@o zNTfaw6hOpV&jsT=%+w)@C^e~Wy@&SjOw^F0M_2@KDUw~DFnWEW$Vl5pm0XB^#nF|( zwa6)`-{pBLs%|BSU;K6k<S4r9MKj3PK4lUW0(AFw<%%efA3J*=QH?6@=!TkT1(*Vb znR^vhVYC@z0@@=5r%@N6{@%1RI?tYGAZAE%nvhrJy;V+$KN%K;x}Jo-5VSwgRuTU@ ze(jg_r}``J*-XD29J#FmycOaP`sPP|mHAA%i_!55SRgu1`}4&zsV~A^JrRw!J^jVy zvimfWoHOm067a8J(V!mIi%TGOZ9bciKivv9+ccgoc!!Aq+v{SMOnTJd5*%Di&{IhM zh7LTi^lOJ)37~g+#qwRI(j?scJ*;Ok775!C_wEQjJ(MgoOWVvg^E7Yx0Ny<p%6$8* z((97%QXG8NpB(3lawOamF?n`pJwwunR<>!6jvkx4yy+h--g@(&kAC7evyM_j=<)^O z0iqWw*y)dW+(6aECV}<h4gv`{#h`k9+LqttQh!)H%LMJNQW{2l&*FP`dDA{%dMxK} zPQ??}$^GvsiB$z?mQG=phU1tEgAU-&e45Ic(JbK1ZqhzXeRg(xQa@C2Z0<on@RjoD zc41LP`tz)Vf2-utKvjZ70xlyZ@b<IN-5a`XKe|Gu{mB^fJ@G~R2ph|}HwF2#aOiv2 zBmD*I8(r8y`^oYOX@>qM1vcFaEJcxswe#0CGtvYGNKF{VwlpuxnYPDFA@9OFiFajU zUcJ;&KVMtYh!V&j%=I)Vh^!j+;&B!B*1Y?4iWFX!q_TS{W<F@9B|Nic45(cSU1<76 zIdx2vdGE#zr2*h;Fy?y2@-6M~v4pl&CE(V4jNmLTJ~CWs+X95Mjk|P<NGuMCRK-3; zX=W9fXvN?V4B8e7h9w|oc{y2zGdKr+=f-rad0wR1Bt6QGRcnfzUNYou6dam6M)s5j zXl0Xf2j(Fq<j2@NKbQ1$8wVKAIIbtkJk}+sy_?eQthh202<4GdLuu#CbmQ^^W3_w= zY3G3SD6!=kj@*RcE|s5fO|@RRVrJ2gP}3|+TFf&_4`;@e5aZ@h?zC_)&||x`(#pgo zk}r-4G5$n(26ontCZPFoYL%V%^Ovw86Pix_Y_82jzct6LZ*;oxG0bTiStrTwk&%Z9 zj}*j*kCDQnseyilLr@-1SC0aX9j0+9@D#+UV2g_}yJN_*E)kfKn)$38qC+|1xL{h; zl_i%VN;f5L|H8d$3FHr-P1&b1yA3>AP1=#()_>14{`!-CLx-IN#cA0uy*HYCJ1<6+ zoexlLkOd&a9#2=U*hYieNrwPIoKxmld7RwpGFsZwj`~<i{s}#L9fDjUw4U@k!%oFi zJaFFhN)_<a1m@~oMfy~n9B85V^7$8rZ^L1OfkwPcGO8&Vu7?ymkLI@90lX(g)N<mu zq0rrZHb6r~D_>#T5N;Dn5T?bEaKCn^PuC_*jix&l?W{~+1Vs79hUoZ#jL(d^mR$j_ zilKEAuG)`P<mJHYrQ`vXT-en${cJ>gS$mzK4qMsoh!Y^r&+qchaG*T=1cui&oSH8w z;4)glvlv=*)Lkchs?Tw=9yDkRXjV~-0L;h0f+_~#A#R;74;~z2W(%1E&8^(EdZ@Zu zH+5YG7K1E{{qWPp&O){YK#AiWRuIC#H8?A)D2=Q%$a_pQg_<V6&60~&)8G9~%9hD| zV0Z>i$h83(*skgols>B7a*Hlb<AO#rq&xCmdkEO*8xzLyJsn22Prm}7DK+)z*0N?` zq#itKOzg_rT~o(Kay#{?h~rOjV+7XYr8^1;W7W**npMbp1?Zab@UBN)+_U{)lnuH( zR3s`R-4=uxuIV%tu*6V#hx}J%`NUC28q01lrtVg`btXM~uRAiGvLR%zGY-(Pj`oaW zJAlQ7@7Ez=bn{GBXFr4OH}zdlNdu>1b6C+dp;Zka7cOE(KK-Mnk~=F<P4z@s;gxH& zEP^$JV6~fLG*VuxE^ocKq1yJDqx4>k-lc2E4E5)$i2P;E<4%4@##vT%J4G2YS1v0V z;>Dn|fNuW&a?>MR$oJvGdI~((y2`Fn)6%>S+W$%=lCrKFG{W!UFpL~Uaj6L%y&3(Y zox1<(QkftI0U4m<kcSu?MRcaR^qNk3o;%;h(VwDj7rKblt8VpSnE;X8l@Jm$Y~P{X zI`VAZ<+GGDHO@-c+~9Q}0v%`v7B$6y3(=!NLl~<L7a@|25;Cm5b7I^QkZPId8;>K% z4!ti@7}<=ORdquBl2bn8Ij7#rf10C)I6Um;ei0lB^GRB~^r$8@{v>@7w9dr(gX9Za zQpp?8^GSZeJFxRpIwsyir=@gy?ydF&+ymjDgf3l{CX&DDhTowIv(bXK?S>TghIpX( z&fKfZER1DN&mvzp*L0oq6#b2O-Sm!>&ZlUP=huzm8w!p0_yy$^unrcM<<f1)1}C=L zJYsZR$g?HrHbd`(K*kj%b^`di3WHfjh>F>bq`-tru6PX~mORF_ZRUH<b#K!dl_Q>M z5#JZcX(tn~gDgi8X}!{;S3D;JAwyHqUBK{bepJGR|3cuac6V3nOkiSz4XyhIIjXj! z_Oi~nWy#O(N*9dKFn$L5R_zJXQ4TD$b(w+joLsIQ9*k`n!u20{SXDJl{DgHSKWasq z7R;PRay^weql8^I+vz>aYO{u2ugJzZmYFA+k6qGV@TB2-5h=I2xtY3qxA+r~mXKQ! zogRs4Y&ah^P(@W1<h*D>KN<7xmYC92{3%Hl(U<0_+5=1$k{W}mixW;UDzzj_=3UnL zR^$`ArBCKudnYdFJps3bSm&+LTIOV?*4lPQnr3TKPK_NFf|=5E`qCxc5)YrMiCSFe zDm0?!5xY%`ZoN~EJ(CBXcMPswXPq^Fv9P!EAU<b)v}$#_Z3QX;_`G<50{~7SC}r~k z=Kv{R7L~<ti7f;%E+8@$NbcM-Yr6{Ute2v_nDnl9R2mcu(oO`16W%!T$N0B#_j2M* zB;}@Yjx}KhZaP!Kh%NAs&@Cmp&elnBmj1{(KwIXjm{;D#$o#Dn5N*r(=(1K|eOTp` z!mY9EGiZuCNGx(wAaVBTS6?VT3+}?GY4pmL^!*!-3cav5K)n3Dq-Hi7d9HPq+XuBj znZVO+4ex&>oWyOlUdg3{dZJ|L<ZmFi-ffxPgphV{j-hI@;sD_KNVxytMdC5z@RB3` zn89-Uj&kK7-}068BFKz@Lux_#tJ1s0UftrX47gtUX>UWAH}|RF_^~*h4?C@1<DNRt zG9(YrVLp<uwPUB>qdX1)PhlKP`j3cvuL=4BVJ&}+0b;DoziLoqW!n}%0jWJ06Pxk3 z^SUF?`eqQQ%7(XG1T;r%yW}dH`3e)UBzo#1q>9RRX90{}{isKNluh*{J!3jC5HXLJ z*eIjODulIvDnR;mCa$xT;FS8kzZ<4fDWH5F{LK?2KyCXYbHFqo87a6nA{bnQ$@5VL z!-R6|ho(3RsoB`&oc4T6)xP8C86<|lpWsZGqF9a7-O=K>M^tL$;+}a>n44nGLKDEp zP;Vy#jHb*a0c#i5C-2a<7>=tA?XZsC>BSbWi)7r>ny7&omF5K_`Y9mlE&l9zQP-6I zAN8t<JQ`1-eD={Nst2*wS`!FP2+^cw>@qcGCGP!*X7bWm1DQu)B$SAa<w~hJxe0aF z&YVl*6kirs+9gD0(%P6uG|%*><r~%mU*j@9=_wBoYbm+T&bPc5S6^iY{U!8aYwOLE zibW++uN4zN4<54){Y&_6BC!{V@b@OO4uucCg{3m8v3p*77o_YbzH_Q98%=h1ULX~! zvIhhga6VmAHGpgYOQWKpzvvUP+moCjsC6P1F&P^x{i~6r;zpiIFYHyW<1Eun$t?sN z7Ce!$u_sw;jE2iBz~gj$D}wT&U}zLOoYBAxS$AM`^0rU7t6YU!DLfy0^CXO*b>ab~ z-3{@Q2yhZk2V_g)Jn%L(CydWx*fxKM^GM%H5FsZ_w;BX#OI7vNE+as5;Is))mc^N= z^DKKj^ImKeF1%bQDC#)G=KJX;w#Ejh_*~1a(^me~>@^F9_JRnZg#<3C;OZqM<&LDf z^<nkemWv%nXX&U5?VZhdu=ixa5D~g+k`3yD!j_Fdv>R;IQN$~-&zkv8{?ubCL^+&S zMkDnt>%0z7O@bV11*KU-yO1_T6?U3CVATL?hE}Fv+hq~MbP>8$|HH|g7mnD38=P9U ztmz$`ogSI?;J~Q^j?9KT(AFs784Zr$v)#|FiGtEBQN@6fc^@26(AHR-0|Ji_(pg8Y zFrB@EGiaLP=e8i8BZaqsi8DA^V_4aPpIliF?jW!ShVE3jBMELOs`qzZ2;C(Q;8u55 zHv8;Y$FG~?kS|=-{nn^=O`WMd6Ou0~JaHRt<Tu9_+cOg{>eWAKm+vP!!*!1mUY&KO zZ0)Igrb=$#J41MPYi>z9qkDFLkMAlj{rKJ$wad5!^i*N4RYSp^d+Zp<5k}pV%u2?~ zS`Lk+#2;M_XR9z}rpZ<~y>GHKuHO_zcn&bBJxG0Sz$2;MPwz}_E3ay&r9GCh<g#7P zEf27LO+b+sb7p(X_1u5b2^2HFyGro}>MdYXE#%}L!6Ur?PEkKHQ+vMG;(U{HstuL) zC*n)mMmcQqjQ2L(hB+sC*%8OijnnI!jjpi1I2`iZ#!E5-UYOpNtDjS0<klINMfkrn za)f$=zW9BF``;PvVglAEr~<_68Q%Shp7Gkg8^Hjqkb%0bp*f9;*ox+jHW2Q7LL&3^ z381mt5FZSd!qhh1HYuS={gd7rOW?K?(J1W{T(NgMFnBTxX2e7I>P2w~S(-^J6$Yvp zpJxei{ihwVh?tWTH_<IV5vxEy9!>5!_VzcDUMA2mw_n|d%^pybxlAhkZpQQ6(3$*k zeIl758(z|f$HA;awc^|)#g<?S7k|<I#>j!KUOXo?_M`J1DdPGW!VX7e>$DI8?ZzHv zciePN#prH@IfAYrvKMvc%Tprdl!T5s%6+zMhqm~btu&1E2)pVyqPWv+5dt`kWY4NI zIqHNY<vLI%II4ai=fD{6@Y*iTuY{HO?tK`|Q{f`>_+|N=ni703K<Fb(bE+G$wxQNT z>S6P(YoCapV^Wt8jWnV=B9@H}4abq_-W|n&h^pgF{me(9{A>H;wDP4A+voWPiAsuI zi0-eROsTdY$St!*j}xyf(owP}QS9ps^}V5Y?d@Vqg0#{>F;<d!w_I{;p`e`Qju_M8 zE@?NE!e4Trt~b=!nZNN79-MSGf4+bHBx^%Vyp$-zcu43R1;wu6L~c}LP^0-nyQ|k8 zQO`t6VlJiH*IsQ?AkWMr((Ry(30=<LP9WZmb2F?D8#*KC7V8p3r-FDe5c)y`_h1P3 z@Z;!?o5}AcI2OlGeH*l46Pjf!#`0!PXgWv&ruRB;Un90K?G$@4NLB)Yhg|%H=t={R zsr79SW=}HH$wSJt-6^V268z01pn7V@=0x)>{Z%d8B-;KK>KGnOlx5Q5*HwtgaLYV` zfe!=_Z&tq{p?G;5(b6t}5K~cK^fcI0yHo89z-0{#qze?1MlTL<i)~;RRL54or}o;? z={O9?gLQD?Fi`pDV-}FMZgm8u>T3aTwWyE}NMr$6NjTh(@OiDlhu#MOqbCCF;Kke^ zUGco}l)}HfMh@VrgUj#0*3v0-pv2hKED<y*g0Y=vp~Xxt6YqyPq%Dg&5>~Nc>I}z! z;aje&?}9Y7iG^+|KuQR_Zm}#z*=T}qm>CuANgb=0Y$O1KR3G_wVgDMBxn-4YQFbDr z4)lN#wS^vbt}SDv(+S*8KWs|rBMH?FEdR<5dAN|9V=YbGDNOqiE#G%N75ZXiNOLu3 z?-8wd_0|~h&F7fR33+9tyBYB!e9L&LNmrKa+dkqzzyZSikfGIFjWg0!jQ5rvwYTb- z9YoAyR&QqoM~{J|%8INcP59DEs^-n%^X1{r{F;>%%N0`K0pi58@=M&-l`CH`3$3W^ zsGRqPW&rzwh2EdhpVlqJqY@*a;zJ<-+ma*5Lj9pno?=YF`m0Fy0InY4yl68qMF^zQ zAv->A6D!%|go0AA?JWM!q#X?IMPkOdv+Md;ClY{C{14+2PMYMLOW?#0m70yTTkLrp zKz;pRADDiDhB$F1G9DCp#U*w$#7Sb|;c>_Vi=f7Y72MN5o7sc`V{c3Rg%nZ<yt9)M zzwX3u<jJFP@nm<`WZ)_<5kSt<C*iR9iSRvs)M=^#53+Ny62_f9U!%tDA2zt_+yhsM z)$j>E%}Im5Z37;zRkbYxJ458JdG!rKp1u>+u}9bxWSqIk!btOZg1SJ@(VhPJKh*Vp zXG;FN)<9<`bE|);>b<B-O$`3aD2neK`S$|9fBTexzN0Y<)88vGl9V)M5&4n6icyno zQr?^LLqpe-#}$M-k?7<21Qa9;GI(ALnm6jGXgG~%L;pY^+TQi4BKjuYP0}PQK%NV7 znoeilaPFizy7+v2yg~E9TarKSMMD6qBeNeWQ|05exFS=L&!R694(QYd&mGbXD7o*j zF*t45X}pD4yXmlVk<mX^sYf5xFrKcF4I{iYJEFZP?;H*Dp8@DqPsgspNl()$HDl?3 z!(ePyp+jeI6&UMdxNO-`xA8iYd~i<~{s?ToV%vmXV{<>A=(j#&n5t;$+yj4re*WFt zV)fa!cej)jOfVLSP0J|ts3aCd^Bm+oC@2w9)F9!4`M${o4J9ktb{zng^E3^BW<tZy zNSB~r2s(23n!bbmRqffy=|<fnb9a7RHwNo1$(9{p3@jX?v}C~^g4-HI@udn~lBf*d zO0rXLwC?2OF3Aw@(Rh~Hd`nf*H1Nqir(`EP;9Y5UDk>2e4ho^d%r!^|9K+1TFFpW7 zf`0t9j2SZNo`+qfk7mhg)uK%s=Q36U<|_##(?DqSbl(XTC~Y(UvLuw4q|d!!Pnnow zL2a$e)P?;8CcDDA^$r-Dklj{`3MCQoj(ou9!jbW=2(aay0us=PVguy9F8Da%3x_@R zGx-c&?vz_^V4yzEXy~+rfVzjFK6{Qw#**W^^B`IGBXaef&dl%YoeXRY0%R;3%HJGH z9|^3AK5~IQL6HwBo+?*4-WY`!A7{q*$9urw|0?Y(;Hp}>x9KkFR=T@Wy1N^RLpMhn z1VK8ayE~-2RJyxEly0Pz@_)EquUB7hec${zZakd*JTq(7teL&fp7khv;8Tg=c30uf z?sSt92!&F9{YI!dG};tdwcjJjjFHr$u>T3dWSprlx~anpv7wim)}G}tTRPMnf!cah zt(edJwKhffD6uW%-(%aEke8(q*S>7}g7f{+&ijPWaxJCWwjd{tg8R!&VZXWm?~W{O z=kOG$3UmS(*?#?sFhX75CKiC{^UlX`boS}fFX?Y|W+K3KVfTC-o`+|r-l!o46Lhjb zEu1eF*&Ix`(Bg~`pfkzI1>^7rVgyUKB_VWGiNjlngbS02VPJfu8t2Oi!EbvM!#w(V zAtD*gBqd|zQecbcvAyT{p=2T$`-d!y4GY&*VVe<?9c7Xz_#LzfnsrAK-2j`X#su|Y zn3yL47>cCi^+Y*`n3jotg@khlVk{XhS+Y4nNI-(QTp_d8#}7ELrUapTrAV=4d(j;= z{P)AcQIL|Pp>+*|p3{}S82a?&s#3(q3)o1<Ip@f3TY#A+TGhyN<RlSe_DL$3VV?z^ z3_Uu(wWz<i;{n@n_M-8zR<pj5wC#4&$I}l&^bg>ABqb*GE!+88tI8#Xk7|9fWU|t8 zJ0Gyk6Gb9b<&(#4qoSS%#IlS#O9*&#_eh`Mh#L*Pbz72iL3yD{^R}8YP6`EveB~|9 zkQD9svo1MUiOH&LAxUmPeR-)ilHXvYBiYhrcVXq(-5Y;wC+u7V9a|z-W${l0YZlQU z9r8mRNqS-h;$e;vZ0%m;#S`P#JS&vB^%Z2eaj70ta*h?XU2ni9Nn*#jThMd+eVnc3 zWJX4F?9d1qrye~r%}1Ora>z!I)z>05Z7L#m)7PSmLB)dc(3=Z0*V7`|tg~Pq+Y=#6 z(VGhr#G&1I@55iJ)U32#4*e1#{_TfoQ{yf<6r%HpfLvv^-9h8y?mQf1h;?6);RI9G zXw$`3O^soy;gD`vZ<<mQWQ4mfkFgG~`5zq$FUZ{uHr%|1biD4ky)~m%pPZX3dQyQr z({G&k&OGumlCxhqkpsh;(aGf9EWKdir%lPt5!-GhZb97lN_tdBtf;wZhHNikQ-=a5 zQjt1W`SHS-Mt9<Q4hN4*mOk&MwRiAVi1t?|mmAx%v0s1%zBWkp<25JJ8=j&u^MDsK zDFU?ddm=s6g49As&GeV56k?pChn-Bi{IqBO<kYhu`?G*}WR*0o2TU_3^77F*PO;1D zFQRk3M!02@>{7ty?Ibh)dQ0vbFUrxQ<QLBPpD!yv;}LBm&+W)_TM`a#L+x5X5Nwn4 z?l9OCO7CYiR0Sz$&v|RBA<lU^&56fs&S`C8nT@E=UHCtNRiiU;OzVoL?_vzZn&7lN zFyMuJxTuHoQK<BAhDu50=;>Z>OVs=nC<D!=&xu@zW`+Bw@NAZGGv!K6TE|ZjmY8Nw z8sq`YHl}N~C%EQgd39T)^`2BpLr(1t+Z$C0IebS$%O@F7041fPV;vq==UIUs8aMYR zVXT;rrgV}p`5727t0tJ232{SNXVp_Iexe<pblr4X=W}S2cGjp(5;QS+BfLsKh>y@b zW70hno$wwZNioSRicF~2!{r^8GgDIzZ>qAXXYH?N&Oe>7^+1Jbi-NcUqX1$9fGAi% zVh;X&-ezC0;jCoay&d$0ZB~&pc$dk-?R>iJ+))SLa#9h)M>2-1aNaMBngf-aBQ>|J zTV+<>b6jCp)YzxlJ&CbfrS}ffz5>VDk<`n{Jmy*M;JAY3+R^k<eEmW3il|`+bt(IG zT)JJU)0M9JI8j~bVF^dz@<PJx&775zuh~1K^via926{_sVYIzZ@HBD9hHIiT?~qP= z*md8*!HikC=iWpUaH@|qbeEc@IxSv09KvJk@-+yyIJ+g1p`A*|YYce8l-}aJx2tP8 zz@RR>Y&;jWyFNZdO0&BKNusFs0^j))*m+xJFHSpr%q<hj_#m8JMF^0f@RGpNz@OF{ zzNnLUrLNDnMYEoX^cIj9j#!cNfPnsnRKQrBYC@uvH^NXZY&y#GldVNfwY^B&xo39c zg6$3G>D^Chy_4Y)m0dxhyA=K}pUVGp=vI6R{3&+FYb@Gh0x-YGyVje#^0p~0kOJR| z>sYuVzN%H*P@qekc8bOh$eEa5w&Xi-ahXqt4uNm~l-1)FX8aKx(%@rE(#x@g;0N;T zBoY{F6vuBrm2_o2^96|_@-5p*Qyd$O9`HGj9O<<)U2hCW34%Ltso>*R>5IbgJ*Pjw ztd^CM>w^>_#+;xsZFngla$z+W6ePC5lxNrph7x>`C50LWl*;Q2cncP3QPfEmvm*o+ zh44&{m6!tQ0TT2^LAn%`JoG@;b0Ny~8bUhT8vL~yHy^jTAzEs_iCiHj3-1Df)o|J| zl>}Stc()n$p6j_7lOs1!(pWvgM3#ef7kK-5G6d@M=&^k?xfC1r)q+kQPM!J<8;#1w zeET78yIS3yi#B(vSl26}NS><f^DKzE*%w+2@E7Y;t7a~5f(z$V784b4i~S{L(3jat zMvA(%&nB45dTbVlE(*f+6okqTWz8iQDAvX?%=i-(!c!GI-&Ls`2uO_VA6lhAiuf_5 zo7W<rny6K-KOXCaYX2fO;{>G@R(hpE$(59*T(gyzRCf?XHI)2LX)rn?X|F(wA8nL| z3M?=POAV>;q-h*NtiG=C14c10a!m~|tmo5_cF;JJIbx2ni6YyqqWsAs;?2~9x4b0E zM8jGICdDtY;P$j4TYyV6DzPusohnsq7~n8gdC{eIEwE&%n&Ao}?Ur&)aLGs`b}N}F z(YXL0<YbLK!zgIAh-;z<Xz1`1!tu4qJ|xXo0)h~?JES{VX5gwFUCwM0hHsG;EveG_ z3)sv!pR%U0#7MLCN9tCp_j1~(quo9{U3VWATH9oP-V`)w_b`;enjGDXadv8a{O!S3 z@xX0Ssy(=wH($5r+D`LnJnBtZ-;Ejn%!pf;9!|UO`8$n#B+tBb$P=~Cf*-^2KO;cm z512a9$M^T?jhs4vMo_drajV&CnBX(q*kO3*UTTdh6#eSSLeB#Br%zB>QfldePUBDY z4k%y_BzewFkoS<GxoS-q-pjNS5Q;s2b^6@9`>of|TJ$#i0BLs0n_{*{=MZWu<X+J) zb#h9g`zVUa5^EG<KZYHC;bsmwfqNMH()Z<)fUXj8k=UZ(07lVFu?_l>x-q;V+#B{t z51H%`N;h*`n*w$Z8h?EtQVUHO_`tFA&YP@OUByP<S}nz;Qb}@4Exf_j^Pwiz4fs#` zU-pn#-C%fYN_uG24Cyghddm2nKA~GE5gC7sU_!2Zk(c9~gl&FjS&otVNz)OJLsjch zCX|H~Z5z}I9=#EE(GFiP)s1{a4_>Hu7Gly9Yk<jcY$31pofjgXePXR7ig(Pkrj%xj zB}^a_`->L_T|F_u_E{$gyC}0Win$+lZTw-~&$0@I&yY%Xw5P^SwZxdR;tkd%UWW^u zA)t(x;^t3sOH_Q|Zi`d}qKuBar{!}U6SqasouQOFHdpNEdx;*cnO}juo(Sp|))Qtp ze40AKz!<sCduWpS{G7gYXm2UnhB_RoaDLPLod#}5oCX#$!^Q&RRr9pR(;fG6R{Rpp zAl|~tZ5s8akE0RuB?-q6{^d^Una1GWfjU=&5ogdT$&x!MVP#=!v(D!PcrR#^L;Dsg zLylrrWl{x}Z0(@ic`QEfoQ!3xYpuQ(mH=Wezi6{;2XGXbav(s`hOb99k!e47g89PW z{{=<;Oh9KF7C08ArTDn%&AA9IsvS+1t+-IjGBWI?1wt6vWUEK0o&cqKO$dHo=NY2m z*ovE?eO8Rmmcp%ajOhn{X$`Dco3j`TJCIWNsm(rZlhPSZ?;U|~vo^YFDwP>(FFil2 zzJc6jGTgh9C(zG7!q&!UZ5WiXo;9EO+^JHwBfPG-9`k$ur@dA83vgb<81O)H(3PYb z7#QgA4_A_37u^S*?p|@z(_flS`A3ILS>K30c_fNXh{hZcz(8U=heR&K3@_DzUKt?G z8sNu_5euIhtW`<-O2<_^|G9;plB4XH)>v~L<I{>6ow|i?#&-R(^!9v)qsxrzp;&1o zi|f&&OW2cs9#>HQ!^<@1(aWVRJj0ty49Q@Nm``;<E}_XWLow?%(xIwCX0oi3G3e4V z6v=e`{HVj|ryGr|QCg2iqVtx>XvOmB8RAT%CDZ7z2T9Z!l@G9G`PsGTpN0U4@o6_( zx|~oyi$}<oeN+n6+CkrPr<N^?TPKJqa|+R!uNffI@PCh23#Ff<fW5bz^H$VEtdC+w z>K%2VHXRPOOUP4Ve1;iMi&l%60L`Yi6r{uhIH${`wC*+JTP@;YvbD|Pax)A3zyz&b zY=ULuSXrBkU<TvTIB!3_Zq6nx`VEn)Wd=s4Fd{q0DqSzt(04o7ElaED4WANp^=JzX zXmy#K!v;4dTPQx)O90b^+Pza`y?RAu#d2l!K4b${Wu(hvbQdUPOHEg3Y1Ugnvek@^ z5kXen@r;hIf}XGPYBw36Z?D2MG>%i)ohap|jWgM~ga{DpP|@vmF~A_n;t)OdSz@q@ zZ)q83xM=RW)LV5)oZHGynmfwY;PDP?6peud*<s{r5&upx<wT+BtYw{dL4VZ_RUc~a z4K~+cf~Vf9K~$q6A?CXN9JaMxn0mL4$Xn#11aZ>r1RnXfGc!u1SyR<gDpc?%YK&$2 zjYZ8iMu7N7%9KSbX%=}L*x_9XFsTb7DS8c$%q=(4UQpy$Q!3HX#B&H=wPFFnOmiV) zWU)0gW=C{YEID?bUnSC)rMETKeo9+7sUDc1o!`Y?H>hrGtuJw7lx2f%!e(To(bv-< zEd>{bqzz3x{j_j0G2lLZ3UKD>O3Y}<Yiup4FR?M8z~<HE9QCanm;mtW%m_T6z-C}f z*KNjKwQ}zV#Gj67wKF!daA(utTBiBF3L=Y`WFD>l44BTZQx6N>iW{iH4|hfymOdp< zi4qmFRe$OTkUn0GSy(+0KMgZa)IfA9OJlH5az!l_f0{o{>5|OuqvUEbG3Hm701+cm zFmEdj2^$e3VH5JgC@aRny0V;R3QWDs*9l*=YPDdq?rpP@+{<WvPK|Q8OblB%Bgu^q zQbpCaqWVSoI)Y^94_={iG9cFn0G6$Q;;GuKdN30*BIn~U6eBzWgz&v)2ou%4j4!6< z7MNk62XYxAF!BtnxnAt*<eu+|R>9j=IZOu3znxJs0%zZc7k@+^_b?1QE2hoqVqhL% z1&HLGN7r3MM;LyGZt^<3*0u<NONYb0p3n-_wO(RTXSb>+ZYJUCh4oDB03e?;K*!{R zloBI;hbhDO#-T<Y8)5Qty%{os70dIJ>Ub`(j&XP=-gzRc<QenarHUE!g-4bSv5yQh zbF=s;2xrDv7#|`bLmQfu^H}>cNIQo(MDfIUWMgpjb~HcD_Sk3XMUOC2C&8_zX;oiv zT$pS35_rX7DJ9bJvK?9|F+X)r6y6-y^||}NRhm@5KC(j)gJsGxiZB2%cCoIWlb@sK zP#@jW*4i$zzDoo--)Zn=8oyozqC{2s<o>ZrRW}2}TZVo=RLF?t4hWuV&&)QM?Fil6 z{r;uV_7;vMe&L>41G2gz!lZeIVD&j`r4rVc8y%wWJG@K!9xTvX6aha9woJ~SU++)k zOhnfepxrEwc3u%DCe*&%Evh3f)QjSmqnU}VPP@bka#O2dXr6ulh9modf=W>RIcsfg zNvAqv;znqF_mn%v3G<WUSe9D&+_7a`-9cD&#_~tl!<xdvM9yG}GAc#RCCX?;2xw+P zT7n~LB^=#37Ic)r8LT1^8EgH<E)S`&0W6gMyJ{!5*&KEJ_k-y&R64rUT?Ul7OCOm$ zwb6ZPA0oJVnxH=1<r&lNg~fY8DT{HnprmwIs({xwi5AhdSttIH`=zRF3vUW{naS0H zoJuTyko%Q(HudrQp?1!csjg&UclNnQqDqDkk{85!coD-9_2T$3sQEP^6hakLXvixe zGp}mAl*44w0cX4l0_XWgZi?&mnx^6%yW2~ZP>k*gS4t=y#SJ95h#Hczuli7rUL5)p z<ONOjLmtRmXv6d7qN=B>IdrVhTMyfY*eS)FaSUB8^2H6SzzQ`%z1NP^hmdv>P$6qF zd`jq9QuKO4^s?4)gWM&cQY4<E$+F)sJb)G~)e7-Ms5HjXmen$jO3Uz}l`Rp6<EmI! z-7rRrE@g3obc|dAxnT^1bOA6bg`Z_7+DqF}vBJK(8d(v`zdeOUo#sjFQdna1wlvdi z`kiJ%#)%57z<R#tjvW(GT%LZ+HF=X^j3@a{UZ(-C7;013t--Oc+ZY`Ryc+REsAN~J z!Ew^|$4~{wISS&$8+fKR;iLCwuBGMGuZk^|*$G2l=-9mOt;)m*7t5&<f-n&Ed-CXc zv>)~LuA3ZvGZY{lv&6URi!f#aX{H?gK|m6Pq_^Q%B?e@ICgB6gwpAM5@UCjqH!dNC z7(@aO2r|YNb6ZzoSMiePG&is`hiT|yYs?Yw&!3{{M|#i5zRr2<cCWe&HpkG$9etQk zUn{2Dy2^9hO6W5sn>qf_@uO#jiHmMyNbXo|-g!MtPILi--_>@Y(i7xJnJ4c;9h})D zwqQ74A<tGI2k1gp)h9?5k$`zIAh>lSt_B$#lO6NddXZkk<Ui;o<91=nE-R*)!nL8b zv$R=63+;+Iiw8(+6D;8(h%r-ROOOoom!uqti*>FGBarTsJP(caRA<wA0u+6OYq?F# zNWl3*dHuW}rqmiJidsYC>JXCHx(YZB)x6Pa-NmX1nbluKu5eRrh5o2kIEr3NGdFPE z6UipiJbB1;$$0oVNiVeRxzKI@1z7f&wX>`mjQ<<_V0dO`k?je=f}1FchMpXTY%oI} z`nLwWlx@^ciZxzv0p88z=|2HSyxY^KxbU|!=2G8P+R_F&XKXpa+}Mm2Jbce1fna>P zY+_g6CjuP`)^=It3<*h%bv$Yh4KR96Rj!|hn!yr4$T&TsSI)T>ZmRhh_#{?Oj63_y zriFFVIZrdl_KjtzMh?>Sz4gVKtqg=Q?|scP=<#F%nlLtmPS)?b=-xdz^5|B45ZMhD z9mszXzyn5qie=;&gZVi_^G2>U>aAgX{-bKCM#Qch@cb*&*Yb)myBS6&9LMxvkDFHL zRJuo_`3G4gqb%5!aO?uwbRbTg!nH8waYF-G<f$u3Fm(xR;Y<fj?!b-nPW-Eq*tYik z1tQa5c_@&HA`5r~Q8HB|jy#TACoBGB=+@mU#HaT7IFyiuaXu?yDns|NJ~tYqV!K@8 zr+m#D8U7@&unbLo3p?A&r;Zk)Xhp=9>#lHgFUuOvEQC*1UN3rK2`3X-6LdWAiGS+~ z`AYfS9$U<jgkf`l^)Tz+rRz#dJA01ji)Air_qCMRGodKHhKh;+gwHFL`|U?@fa=L- z&lTnqn~Nz3YwX_(bm{KAA_PoviR(t6BOS`31a#$GfQywU56@zY9ukatWECR>q&>;S ze7S6XwS~mV6+{ZU4MwGq!K_nBdpfJ7#_{%P^>w3{OB7)eRJc?Metr(<@d<+N7uM_3 zWxbs<a80af*~r30n`MF;_0_1h=XC=9@!_B2TIdgwt86SI`f+$^2x0efhjp7*^2ucx z_i{r3P1#TAf)tPHflg*4_We3j8wxtmcYIlR)}qfUeY`nxSh2aXkIWT;Y_SRPq!{Is zlhqf~a6y)SwZqS27bsh{+VT=7DVc&?ZFZE2JCWZGhq$78XNH5f&7kUX1?Y6bF}Q$s zEp;vESVA4-X^X9sJ=RxfksfQ<2s6Dx+0`VUt`NH|F}PikFENa`;*dVKR({P`>?5$t zMLumWc3Y5lHOwA<0s39|R-<{i{7C%PQ~G>Sc}4R2z=LzwmHhmn(CtXxm44Bh%<~gw zcN`<1iteMDPr_j<Oijs*7)Dc)S<tT7QXaT<8!su|1fjAG9~8LrH4#&;jWM%TE+aW~ zyKfsg5v}q(1Sb-KiEfNg=`z@*YL^s+(qO!p%-uevl|IA0VAwj~-l0ES*H&Q;E4-vf zHBJys+8`M^VK#HGjnXDOK{p#_1=qX4<4KRZddV<ELm;j>(Fr4<pxDQCeKKOsG%npt z$f7VfG+vDoTTfr;DNO8uZXYAr+U?{trFA7(s+AC#McxR+M09qLW>j9&&QPfd&P`fG zK0Lt->epQ#T9SoyVm%o?8!qtF<=fFI@bQJ&G~F(38eXp_N`~RWFJaN=z;0$e+GxsL zwWlF}&HvUm#Oh;W^w#99Lgt{{VuE2rb$g2SJKN2&gQX`$FonzS)sXf0&J6i&M?UF{ z_8TpCwqWT=`&WjI_CpWHa|3k_9F$`_<#Bjbwq=5X?4IUL7)U;Ao@McECZufJ$Ca|@ znb@X6dFZ{5E0W0<IKd*>JVxka#LYS{6&7EzV+kOS^Laz1l0Z+EeTL-0!6*>MnJzow z0Mo>L#&gD743(Q9nHr|D4Skip!OHA^rkb+qHKG5(V?sZ9Qux-cz=q20ODB7l(rEv* zmj`U};E9uWGt6UsPR0s<7)I;IcM1*9BK?${!l{;7{FWl6+261v-$Z)h?@(tsM$)kN zD@#E~vboDbCygoYoRQV3rHC+1$nHa{ZUf@L9<YZPyv-q+^CG@Y;-bR2Eveg{W$vJP z>~pSnRu;>kL&xqFX#E(OC~=GJ1a{*1U>2yfP^}+m@%V1>VomYs5r98Gha1N;IjAkp zhzYSW(YZ3wX+Iz0x+rh{{V7q{Heqj5Yhkk1s9QkTtk#YX;ab<>z`=67iEG8_;pSos zU6t!4Oj`(cQ%i_OmgDA=5B|-|VJ5yN`YK2c6S`-dpA^?6#cRXOc#f!fA^}?PWg-=u ztwOiW77p?$6|sSY@tN)7(Tt(tjQBc}(mPoC>lOXeY%aiw$^j&k>*2U@aXb$9^f>K2 zS7nU|!=t<p;u0-!F%*l+#{^^NmOi=u5C^81Jhx*PQjBkT6t+a{U?Z#wi^WG=271A^ z#z_+e-q}XEQuVY<yUlO$E{L00DLp1*Xo>A1rgfs+O=mwu<9z+xsu+cOOvuOzB1#Fd z&d)vv(Spy7S7JYam;5yn?HqDiE6l+x_@o{53SwL{Mk^8bDcIV99q}a`#P}p!xXgzK z1HSkb&&j+JulUNzCLIOxdF&o#u1UzaF3EuR+Q#k8$;J{jOaglab>4FeO-Hs^yjTOb za^RPG&`Ywg?iTFAO<a&3*|LM)>kY)aDi>WbIIGJ&dLRiaaKJ4$%AN6~^N<Roh14U_ z2jNs=e}b~5wv$mGqSrm~o#+m4>2O3kh0KA=&P#pJHw@Q!ZKFY3>Vxj4J1mhjl%xZr zJCOT=$XOpryrDh|`VKK|n>1?jD(zxiQKZq%FZ+nUu1DFZvxxoR8A?4m?iBgP)p>By zQmVT%t|15pIPPZo20oqrxX23c5+Z+K1|*J)DS?&58Gj{Oq;lr~MeB5vL>M_sJ$+1x z^pRI#m4LnD7<+^7of!a{`2!gJ1((uu|Fs~5Sd@WY?bwiDz4wJPO(}lR1Ijc`?s!@T zN4e*&*t}xMGGcmhaV{Q*R}C}eNA;`b*+oPBeQ~MfHic)T>6aD*x6+D=3oZr|^`}$y z0#g-R^>yq{7XJOY$oW1gQ7{&w7I_H@&?ze@S&+UQPK&Hvm<!enc`GzPp`FWc6qN9U zk}<dGXO(J>byz}@Plly1C<mPdVd&~2Q?sqS=JHTrJCV_YNaYoZhjTD(Q9jqI;Fk>7 zk-b;45pPa>OQU0~Otvo`QHf0<OIso3r`t9pBd2j>e)c%Qqv9$?RX$J^Kv#%Qay}>i zc?=-D5Qjn=hXOMrY%b${`9ZC7y}S-<?9e@~WLo9f0m0ZI?ZB)C70*-=2KUr*S@`I7 zluX#dVr4vz)^!@ulfnV8R7X1Gqnw)kcq}7nJR<gpM2=evvx-B!ZP1<Hkv_e2=XJ1+ zJ`zi|^p!$w4$xzz`z81SvB}ZSVkezy^g-tRZf&~V&LnH(K|o8z$Mi+!{aK8uY*sf4 zcw>O~BX58;0BYiXu^x~Z(7dp-n)DVoe^uYK!kW@kB5^T=aM`Nfe62Opes4965$-rZ za}|CfqjQUhz~ub8PU?=$J6Xm=8*OB$8T$esL9i<AcjTo#v4^CE8ru^H%gGX=Mxh$p z$4y=|*E?l|nRF%`LY-Ti>@JCtiKAEE#5G<I^ZQ+9ttM651{ppMF(%dzzG`^*?A_MD zlH$&dO~L5&*lnZkWz+2lnMWrP`_xuXS+P&yrsA~MVW--vqQJT<@pH?Ek}x;yUZ;3@ zl1zTDA=teMytq8x`C~}mkt}_{f%A9`u)o9bM!AE&^}mC@BlZxi^&cSM_Q<pC8EJSk zUay?uLb74WXA$GV5^vp7q|*|>IMyzTW34&Hcp%fP)(KE(NhqH#&-Gq72P(Bh6HnXa z^wurz;MqQG%Q+}?t>xPmutjaFSeAI0b9-s=MP!kQa3Q_p)iPb6MO1LrLauS^MN(49 z)6nDvj2x{!bc%)89J%Xu>e<L(+JmB^$qa0g1K3rs1MMnxPX)aq0VbEMBc}s#$M}nw zxxzMj6pM;5*xJls$vW3A<%7ai*oA8^DM6uNub$_aIKVjSHj~764Zi)*$i?-T+tkXu zc8M+@GNB058S}&N%#gO-_<*0NoK{PwGVj7g6KMnAPh8^M>=@I(zjjVG2}yR_tYEFe z>VA3hLe54UKCd+_MmKJp^NK)*CMT_4iI5_SzsLpuR*#f2+q9cJPEBq%QjGXBjl4Li zB#Mjw7=6NGP#fr?X-UkM@!_p5HAiO%WNVbd79{`Zd&sg#n~02PFDDkxL9KM_sPu}S zO&yb(n4YV%&O98v-7EGrmx0(q?#vo3HrtxA_tp6&?}qsh(wnpesTd73HTPhhD~Wx~ z?xZu1={}Sk?vs#l$r?uF5Qwk6e?~4gldiFx&{(HSii3<<QSL%qJ337J9&V>NZ_i-2 z;<Aw48w{`uNu#Tn`?)!)<eUU^l5HEpn_E98Di89?qS^4FDC#cHS)-tz;PmOvs0aA1 zYNp7S8FLcOgixL<J>}w24B2zmiw~#oy<x$SpS|c#??VeLilK%8E9KN$xJcNz$hYP( ztRvL(NN5vJAYRk^0`ckO@fcmrp@|SPbR9rrW_(nlviihvIa%@<jfkN<N?WALIfpc! z)MElqm7UCRfqpc1dOwlK<i5QtBfMOjUcDzR#;gfxYd6(&Gq}mp1_@0;dJD0KqREYv z=e|WJ8EEko=?^}5zbd7n30x!ASfAkzw0=>H7rah9^g5IA;~tM7>a~!MQ3=yDe|=P_ zS8-pW=GAh0oIZ_+i{`aT8f?+f)=3M8`-dLF$Z2$36;q~be&*sZiP=1LE%O2NlKQpN zIf7#T=0ShiWra+=Xw4q?icRN!?xTa5YZqSRfhBON7F>n;*ub5ZBCXfqGUtQEax3!j zR}C~}hT_V%RtrUjqKjwNJEXTB3;8QTiMw1AcDIzxA}gX?I}H=*SAx7nM}<M>eA~f3 zz8TX;AhpbvZK7M^E2-Csg5wX-iM^wk&rw*!jxfm_Qu5PXX<Fv(I0sN<a`&^?2M}bG zKR$EFseQne@a&kwnP8U?Vuy6e>~7fgS|7;wdd!iG|6QO`7+Uaa0WX&GF)Sci*Gdmb z-D@=5t%Du)j`3LvpizaK_7|fQ3N?#9rs71x<$>rWi`W)IGtVv3opc_{c_N^lIA4BW z%k^rgUVwm`skV6F;K(DhO+m%iLjtP{k`GM}vM-%DI9<y#?3=j?)k(6pEvE%<T|8v+ z1#|j1#^e()C{G?~;xH8VALQk;7V2xPaq(I<wT4|S6RD}HCOIJ{`|LQi$D!zq``k46 z;G85ONb}Sk_W{lGX-S}YE7D6s`47}WN(%kk9b+8V)*D%**w95=FVHGD#1d4ZR<S1@ ze({nDaNY*(<{OU8LfI9eWrb)M-+CF^cYPoXc3`nI=Y!xt1m1T8MbifdRXz$9Ut$Qc zPlrq5PWWJrI|5CFTO7fygt_~Xg4*g*g^fEhtNw&z(Acv;wvP`!pBbt&-?4l?SF~un zqe;*H;&*aB>cDsxoOMm5Q~V`aW9M0R)*TPW_Otx+D;&)6FAAw=U-HAwpN+YmJ)0Q5 zdcDmkIwnl^f)@!@0FXBk7MN(j0`!<>-e#zM=6j(yeuq>0%qS1e$W5#ynsy?>Z(q~? zIMrShH%$ttwevj45WQp~%w<PC4KmrvEh|=RvCw6QDI^9>qn}RYAcjd9Vx1pczUdL2 zRC)(;I*%jbv$$9coL7a{FM>wZ0uH-RPvq1mYdWmktO?B0!Q#qVaujiM9zu!>-b$QF z?#85P<OPFw)Q-%PpY_!>Ik7t?X`J&~^c3a!Z=ypU_-}R<jbj=sTgt>WVys4Qj6w5o zOC!?79zw~k%ckaw^Tx#c>8lNDwoISAKq=o4o^lY{T_4W!-<?iPJDrjTLq_(3e_1}n z1-{4o5;w*exrz~7DrdP7ZX~<uW8G&p;jlNbSpax!y3Yvo+9x{nY*N<L;dkd#awn<1 z=(STSQLe>3NKW{TR`}+zv(yFP67ZiR+~WX4g^m&w>6U4dY!PU~Tr*?FxzP!@r54G` zvUK5((#@xo8Lnn>?Q0&?uN`>tN$cArCd}{bx>pCplG<iSsVwfJt63+5Q4CI0+cNX_ zgU8mAl$0d8GwjRrBH>_(iu10_rUn@HU7IVO0)piRG46tuPZR`uBjc>6_ITan_i}nt z9MfyD0|_*u!(QTzY<OyU0Qiv0hxiZ{buL*uD;|2o<@7vCTNi#sDHF?_ybgV1oE2=A z<&7=_J++oz==fl#2W8iOpM0`0Kms>$0(T7o-(F8THhj>sx+)bxDbv=AYbU)>B~l`m zM4DE4O;NL2z8yM=th%fL%(=_Khs;E!of}zraC}V&stZmQ`Jt8-^=^}+yltA%n)SXQ zA|Ii+iWxTG^!#yHkFXW-g}(2FO<a$1RKsi!(K_>Co-jAIcF!&Qf}3x3gr`NBBU9Re z5APti>5)fm+g{a0Iby7fKDmUBor>wfg0SlK-1!cCWB2^iD*t7sfsOXr>2=_QhkHPs zh$vm$ky<LuWZ>S#1a2|}#Yr{w3G4i{@UZ0;m4TNUalCvYINUj-)!R9Zn{HDmi@m&v zv9*Fwz1N3qFez}aQmqlv8$QM_g<QK`A1eZQH4kU&98+$ZRUz8!q$g@*r>FUJOsin@ z#b+mwm5L%Kh;3v}7AvEV#)*J93zr{pIs$TVCZAAWxl><3H!jFdjk@8LUm(QYncy3@ zq9l68%7ix*ceo{r^o&~O9)lk+3l_+RD{j-SxdL;KJr_)FQtViKL>sbwGLP{H0LZUJ zuM2P~BswuE^}CLBB$4KOju(U!+Qh>@blpiTx;4!8w4|cjOXb4{)*KT8Gr9dw?a~h) z%p2P<t!)H5CLE_Qtm)5mx=kRoz)sGbL+)0v*Pu>vT0Q`b2=3=Rd!au?z=JE^p3_o! zLw8V(qV-g85kN#bXR(=D)$^*)i%G(hKql3;Whii@uQ<B1IQFp1yCYeIES(ttKrY|L z{2A{ePw>c7l!EvXpw1S5giac`m9yEHggK?H#I5c~w6x2oKtND5`$~1E1#R8_OZgfG zzS=pLIg3Rj^B5w=nuCuF(St!!h5FueB%>%qz3Z2ZA6L^lYuiNBT*k#+ZnpD?;@z7x zJ~e82JNHqGWboukNe)r7?vG;o_>=X)!HvQ^{lJ6@=%<SH`pg?&;HV2e8xKJ>h~qaB zV#-YwJ(#R0nyzXQ;Ea#So$i#zMm_3IDes_=-*1r`T3?gSrfqae!UcQ7HCL;ELH}st zLAH8octE#tE0%m{H<U(z@Z{(Ga!5rSlDf}DnjS3U8vQHu@p3^j?em2)?HQb`G(v?n zoUA+<G8vL5&QAqNGs6op8Z*iwoGfx77PR1O(`1uJ0GJMpK@wK)Rn*61IBKiIPsTZi zn>uECEOZHY>NyK2ElrwVMeNjbj;teAPxZvTTVP%`j=6<jxoZ?e;+iuk#?H~2=zYqf z?UUTw`8j0tT`l(7Iz%fEUb4HOexT$ldpx#j?!HRFvM>lb&5xlpA*g#fO5Qc%J92xf z*_v|k=1?^m@oonJ;ayLpj@M1s&H87BBK^Hbw6i4Uojvw>1d?J6wX@WU479VloQ(@e zuX`cGDq)%sTt~P+%L|>gah>OaHwZ)#oEAMqZaipfdgZ=kth4Hhyu<d1N9Kqt*u`b6 zTwsRi=)nNnsLzCcZgTfDM>9`La}V>D+AQ~Q%r1VSwvPT9=a$B7l7cgF(O??tF6W?- z>JW4m@hRb$S`FcpwTABn8=dfVDxxrKQkanZsot31rtuhi4Fd3`HZt#=9>gwN;&T+1 zL_ZXcME`<Rjw~N%=xt^;xD=xqKeLqcENwH$Z3i|ekCY}D_9vXrBbjHPN3wTj6{hY9 zNha?JOQy<anG7LknI}CMvtdKvow0!#W*LPgGOzdDOnH^%ZiWPGormFly9CEOz68bF zzl6j)zXXwDZwJl5O!ZuWg~|^*C02Np{ZzOx1v<+-Syd=(NMy`%GdXK=xHyY#s7A;< zWlhLD8KdMO$*hpDjbCG}ke<#XMh3J*>|j~Mu6YQ@dZ9E1G;>5kll!0F-gv|E`+I-- z^FRLj?c}d$KY#p<+;_;DIS6PQKN=f9k@`2uHh#r6exP^6ZTu{4{B~^o@NE3Jbsvpj zzXS&QBcqu^N_lWj8Y7$5qp<dZ(KtSjYZlsU7T!#*7F>x#1{Bz6KPm9dF!2x?99A1c zm_*dEynxiVxPa9+MFA6-Wf#Utg%mCwVjr_|M%zYrX5Lnrgl!%oglJwOL_mP_EoZ*X zqI0+1V!4HxRF|_(E;qwx5AvHy#>+Z4qqOi(hQ?<N@-JsmgtTRc%(5PSkY(gdzRi0I z96R5n9;0+---dBUvgqQ6WVbT&=S(#b9_4Zt(wzh74(p92CBrV5MZzw_QI)fB9UILJ z1sNee41DE<%lID4&cuUc@<5I$2KeYeY2UcJy?9Qc+l9s@#CSzzU!|K-b>FGmh3>+( zyFGUfD^$ODPCe9Hv#J!UMWV_Yt3{z|535DEiU6xcx+)cGF?Wt3bh%{CHuOM!-!pW% zd`__Yg3cw#7#6cdwW<ZvT65p7`%rn`p!-mDKg;-%?!wm?mDWY7DhSh4t4b2nQ?05O zb5E&EwW>2zpnMJ^^eN3np7Dz2ez375mZwZrA=b5@@hJ60neiyiMXNCr^@V7+Pu^Tu zXj|UgU}#&;Tojh4detnZr+yU|rl)FE1E!~LRVMXCr125$g=+UZ)qV5Owu-q?tZShv zRIF>MDnsgvDr3+GWV?Ox=PIzSBaAa?FLb+o3g?cnuKkTOX)Ydz-YQo;rnxZhzRQ{0 z3cXdYV#2&mHFoU2E1&y9dx6>=NpqpteV0G?8jBC*0?u8*=*t(x{ZW(c;uqlIs&lA_ zU8OBm&&-~3UG$bJ8a>OLV~WjDoqPEB#qII$hc7VK%h(rN((B38(dIE?8U5()Cln`` z%qMb2>olh8Jh9Q{v}B{&;r!j<{55#)o6IM1pdZ$gA;5ZaZy#G`bYXb3IXKxUPdNWZ zI6qc6e|$JUBAz=o%SqZ`UrkbUVQ6$=O0+pV*{F&{1|Xb&5YOET*Ik48WQz3!3eSBP z*L@ey9Us?SB%I$G*Bu|veTMZU0Q4`*NtyY&rSbawn?4Mq^$^w*cD9qW(Z0!!zR7_; z43l+BllA$&z8Yy#)GahNo}i=`gsTsnP%u|9K`pi2pDpneehsxQjsB8K7HlN(lkR)7 zWj^go#+kO%r<onimug?AibnecQlmXl$XwycTxrNI^&}46!<SC+ng(&3aG0GkJNxuU z`t;xS>G$`wy^QvJkbBY;J`jc%Uy2)FiWi^AOv?mNGw3O5O;c_PRCb5XJqf8Y%y|lN zO<^|6Vm8ZW#>H$Fgj+MqY{tcERsk47VKb{R88R46TJB0}^JC%bNFv%WSsCiR^AfyZ z@Y>h?JlFeauEDXnE_(8ne43r@CeRv@%3ha;kLSg0VdY~VgzL30kBy%pGo}~Ffvc>4 zai(bg(g54+mj&mDeA~aQh$P#jvYtefWA@&zDud9t`G%0hY^*`*F5Hmp@j;&Kx+23H zCTP@>(Fb3Ck`Q=L>ghcW%5&cY$`Q@@H_tJNS{OMw1At~v?M#4{_IA#{ZzIsK)Fe>H z^$E1?01m`pLfA4SXyA9ChrZGf#-tvz@J(PKwIT|XPU1`siG{D#alK{m$#+9ppL5oE zd~JRMOPtA<jFEuS5!8D5?y`OG)Xw$f^7XTJC<lz!G;SDdBulDe!Fk~zWyqW?;$k#2 zETEA>Pitdy#d~mUD0Ahv=n2r;mg_99-m8`&oFt=ZW3-H7fl>!{A7_VGm|7s@XrT(@ zToF9SeQpZX&uNTN5H86|ENd}+fIK;%z!P~8zE^Iki(XzxY^kf$!FmwTUd$ujDKAHy zh#x)1Y^77cN14qz(?XgZ$r>228E1*-oPX2&f!=bD$Ekxxch-q6#U!+5w9J`nI48hu zz@-}g!{LYeDudedUZ954u%2=CDvxS4|1)u38~UbXJ`6>D|ImXfguXO007h83D3Gkp z8Uvji|EPHB!Ix@vdMt$cHGBfqgonEr%haDpq{P9GI7HDgUlpYm9PR0in?xZdd~D?$ zC&*KMZSbJt0W&Xkyd2B`$6PWJS?(n{Do^J?bLyFvWAzZ4d(rc}ws&*F0#G?2DwHPN zWPbJ65Hh{$llq;>UJN(&LY+``M%xA~6)>r59<#A%9Z%hdYg=of)WptSY?|VUlfTyy zu}~ZRte;1}Kq1LhAU{rQ+dKG}I!;}$^Qn%WK}vfrX^`N>t~M>hhgH9$7cm<t?ztW` z;hWlR$KCy=DjNas62_beOVFxK=V%c=>2!PIMt>-x?oe0mNC++6PN;gd3ZGH(N#dpb zv0OK9d+c#r=);e>p_w1Ur}>@z$dO=?f|L)!#U>UeoHl#(ho>XOPT4#^GF^q`Dhd&4 zu#mfOvCyyKV7<=K71=Lyb|uF<-HSp>PbV0_FMmu(6a?#NIa$@v?dutTbY}Lbk&YBR zy?4NlPbWKP&QrwRC2cAieLehO$kM%j^vT$sgE3Q>dqcSG>wF5muylIQu}l5JU}nd9 zj?xV{T6-JvS0W*3=Emmkx}&S@!}STTS~aMHfttE~1d>5V9_tQB)9dG7j#Nn-J5<#9 z(chRI>$k+Hz~dOdWy&^jgWd_JP_&6WoIHIKWMQ;>chiAhSQ=(1@4EuVV!6cOG}`NX z#*l%oM^S!$>@79gR4j~Y>EFvAMUZDD4#slku}g?z=#Ezx2dlI8Aw^*7FwY>%r_TN% zas_`pOkdF{GN&@81r=2&8ZUq6K`Y|;lgBXppEZ!sqa0W;*F^+l!%EkIllyh5dJYBN zIGs}%uGwz3HvqisbQA4hq5%;&`?Z9MXN$89G@88}R}c}U$Fhl?CxUV5JmA1A1T_F_ z6a>*D^Ox5F=7J-Oln;v<Bd#L54vAX#=7U#JTsh)aC%ft(3{KuAI+i1ybAQqWf4{O- z5t&wGZrRmPE1LmlLa(RV^I3pB|H@^&H7EfHu$Aw<L{k81TV6OAC0OfTxz;j|ZChC% zJPxm0Q~!c;;KCXjka$JR#QFl5(r%V?=h-U%0l_T9I?@T1nrGBwrI#AJBpH`<)yGMU zvM2Zol4+x%>C4Ltd$cBMli_G7!H&j<{c)MGQjIm?VE{duu;C5XcTx|5ZuxL@YI0;l zkDtR@hCYFam7KurSl)dDbZ7N#4WoOO^|^^l7xuFqW%@~)+<kBahromc#X``&s(8?2 zo}h^MM}Y?e#mV0a8W`xF5U9wDs|hnmD@ZWi4S<36Cw@B>4lE9Is<;y*n-1th=Aakm z{ilB~d46=D-~KpNURXg|LR?jiQC{LZ0vOnR8pv;F+#kPDgQT=U<PD&A?!^%Qe8&A# zsee8L<B$K`pE3XY8CFIvMux5cW9Q$5O8x`@_Z#J^8P4n(GH5ygDR$ES0RRS;=Z66P z%ZFS+vL|0PPe2odogKi2_3Om&y<%T+5AvrO5kYMr0@?L`n)z1p{3K9+jr&{ueg~CS zlmgf|e3Q2O8QW6F$C(+lsZ$h$PxTELbj<Th2if2knvs7bOea^dw*maR!qmY%lhUA6 z?CKyDZPFh=(Xsy?^w)UtwOzDVpbA2RnoIKoUMk+-;|ZG@IRJmv_WKTpiFL4_1HsXN z+W#Z$67k=|{*WgA&nCTx4Ld{FrU$uzrr6hgvfnD4=Xd?^?_uxd(td4$)Z<vhd5{w& zf%d-q=vvkSe~&3==?nze{mKOQqvWYqViPn7*BA7<A6ef@o?kd91@^DH-^s|q0bnZP z4g~z}Uq4s)*U~{>f$s;?g3vF4O@33N{b5Yq8#7+MB`hA)^@N~t1v>GMlIMpm{C7CN z5Ec^sjp1**?hAVFivy51sDefs%O70#qX8NuEAR_*{9fxn2E|v7Z+oAA_6*MRZ5&vT zrAI-pdzpf7CC^V-`oF;cMEAE%GCiy?L;;1+P*CK!SF`_C^8CtV{sZTK?PXZQUxJ%D z8JPi{f9U0VH*8o#ztIKReFN0f+}~;lI_CL3{#zWedpL4Y8+&KK9~xz9?hbzumfRun zKZt@@@<1%?Kd^i>`n%eGW%+|Z6=($f3x;H+O^kVvr$Uf`@(=&O@WS*T8GbhLSD7;L zJ!{7nkiUEaRh<6^$ZV&7gfwJfCYQD|u?NK!01zPVW&&`yzX16)6Owr-au5y}SQ*Ik zsefRq2mTwTU!zJLS0M#}>fR5ETtA}vhyM#yu3w{4tEYA$gACmP3e-QM%18Y(Di_DE zQTwcXC!ah31M>%^H~0}XEA3yPa{i3^zo8IR-QUZ7D3mDwB`V-sKm9mR?!)2LnJ7gP z$QzPC78Uvi1v=*WJ^x3n?~d??EB}K>;J%<cA_6hl{Lip-tNf>$OWU~^*;ty2fuvOb zfn|53qJ9e0ruU!~!@UsSx02_#SN$(pB%F+F|H-|rjW$0`f@t<ZG@v>2kCNwyUH30( z{;l1foYpHifT-+2w)?R~VxYz6FQ$<{^|+j+ttC+04PXiYnEr#|@(%d18bCCvpcefY zH4&TsiAKR5s0y$%H8QsOYrFlg`x5+NwR`u)ZTTgO8K^TX?f$&J{u;^HlKd^8Ko-dX zRrklWhVtJ7{TAPU>*AjW*jHc&9>@%LSkUwaS{~jjT7D~eei?0lTf^_bKL|ShJZ*QO zmOo|y*%=yCd4_M`pktn&dH3Jq|5oR}gub8nI>qACvq7-(py>GHf@7uUpP}z{ipdon zOzchnVm?xSvZKcYsyP~n;>Ts<X#c;1|Fy-jg@hToU_ezy`FT+xG5GIr|D+83-Q54{ zaG+)M@8#a%2F8C0Zee6+>TF?T4ftVQaUU*ikk4*QK>+8V*N>h7J@F4vUsrN}jQC&M z;lZ-9X*~#=4`kyX2Rhi~f5ZPvFZu0?!c~m25k!LpqG1Cazm+^c<f(t4`J(}UOE9HE zs+s@-#{~^du5aj|BPcdb|679Jdi1N+er>Fu#o52{<oSWm{wI>J3ZcIy`C0J$I|=&y zza{xD|NY%Hzebv$m9W2~YcBj3^j~`aSBjtIdB0Ooy!!`=uXg#P$A4|0pJi{q<1?)M zH~hcwsQ(?r_}@5wyZxf{{+BerYjXT-@t>t+zd_~s1^+G1FRuT-n&&SsmhQvx&!Ugt z+2l6<uGW8CkbUL&)%D*!{LeCV-{C)R{}=e5=>E1zKTE59=WN>jf8zX6XzkDab>GCF zMYO)t2_F1^(EYD3-;@0;_41tz`t(1L{S5xU9*p}9`8N-yMgsrUBJTH;Y2R;T-iPj= zlcs$G%JVb$8<ZbYsQuZ-_n1HDulkNjh5FYu`>SkLKcoMgV&yyfD&{|;|8K&TpW%Pr z`~Mxj2>+kpf9|NS5%cG7;l3j}JpOCMUw<d3Bnu5%*4$rP34wKj?o~#Jfo4Up{{y8z Be2@SD diff --git a/src/Logistics/app/src/main/assets/js.html b/src/Logistics/app/src/main/assets/js.html index 113324c..7fd022d 100644 --- a/src/Logistics/app/src/main/assets/js.html +++ b/src/Logistics/app/src/main/assets/js.html @@ -8,7 +8,7 @@ function callJS(){ var ros = new ROSLIB.Ros({ - url : 'ws://192.168.43.164:9090' + url : 'ws://192.168.43.20:9090' }); ros.on('connection', function() { @@ -86,11 +86,11 @@ console.log('Connection to websocket server closed.'); }); - goal.send(); + //goal.send(); - /*var cmdVel = new ROSLIB.Topic({ + var cmdVel = new ROSLIB.Topic({ ros : ros, - name : '/cmd_vel_mux/input/navi', + name : '/cmd_vel', messageType : 'geometry_msgs/Twist' }); @@ -106,7 +106,7 @@ z : 0.0 } }); - cmdVel.publish(twist);*/ + cmdVel.publish(twist); } </script> diff --git a/src/Logistics/app/src/main/java/com/example/logistics/dao/goodDao.java b/src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java similarity index 72% rename from src/Logistics/app/src/main/java/com/example/logistics/dao/goodDao.java rename to src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java index ffde8d0..e5ec254 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/dao/goodDao.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/manager/goodManager.java @@ -1,4 +1,4 @@ -package com.example.logistics.dao; +package com.example.logistics.manager; import android.app.AlertDialog; import android.content.Context; @@ -7,8 +7,6 @@ import android.util.Log; import com.example.logistics.tools.DBOpenHelper; import com.example.logistics.tools.MD5Utils; -import com.example.logistics.ui.MainActivity; -import com.example.logistics.ui.MenuActivity; import java.sql.Connection; import java.sql.PreparedStatement; @@ -18,7 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class goodDao { +public class goodManager { private static final String TAG = "goodDao"; @@ -165,5 +163,61 @@ public class goodDao { return datalist; } + public int pickup(String pickupcode, String phonenum){ + HashMap<String, Object> map = new HashMap<>(); + + Connection connection = DBOpenHelper.getConn(); + + int msg = 0; + try{ + String sql = "select * from goods where id=?"; + + if(connection != null){ + PreparedStatement ps = connection.prepareStatement(sql); + if(ps != null){ + Log.e(TAG, "pickupcode: " + pickupcode); + ps.setInt(1,Integer.parseInt(pickupcode)); + ResultSet rs = ps.executeQuery(); + + int count = rs.getMetaData().getColumnCount(); + while(rs.next()){ + for(int i = 1; i <= count; i++){ + String field = rs.getMetaData().getColumnName(i); + map.put(field, rs.getString(field)); + } + } + connection.close(); + ps.close(); + if(map.size() != 0){ + StringBuilder s = new StringBuilder(); + for(String key:map.keySet()){ + if(key.equals("phonenum")){ + if(phonenum.equals(map.get(key).toString().substring(7,11))){ + msg = 1; //password correct + }else{ + msg = 2; //password incorrect + } + break; + } + } + }else{ + Log.e(TAG, "result is null"); + msg = 3; //result is null + } + }else{ + Log.e(TAG, "ps is null"); + msg = 0; + } + }else{ + Log.e(TAG, "connection is null"); + msg = 0; + } + }catch (Exception e){ + e.printStackTrace(); + Log.d(TAG, "login bug: " + e.getMessage()); + msg = 0; + } + return msg; + } } diff --git a/src/Logistics/app/src/main/java/com/example/logistics/dao/operationDao.java b/src/Logistics/app/src/main/java/com/example/logistics/manager/operationManager.java similarity index 95% rename from src/Logistics/app/src/main/java/com/example/logistics/dao/operationDao.java rename to src/Logistics/app/src/main/java/com/example/logistics/manager/operationManager.java index e6800ee..415034b 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/dao/operationDao.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/manager/operationManager.java @@ -1,10 +1,8 @@ -package com.example.logistics.dao; +package com.example.logistics.manager; import android.util.Log; -import com.example.logistics.entity.User; import com.example.logistics.tools.DBOpenHelper; -import com.example.logistics.tools.MD5Utils; import java.sql.Connection; import java.sql.PreparedStatement; @@ -16,7 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class operationDao { +public class operationManager { private static final String TAG = "operationDao"; public boolean add(String pickupcode, String phonenum){ diff --git a/src/Logistics/app/src/main/java/com/example/logistics/dao/userDao.java b/src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java similarity index 98% rename from src/Logistics/app/src/main/java/com/example/logistics/dao/userDao.java rename to src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java index bd3bd0d..0f50cf0 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/dao/userDao.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java @@ -1,4 +1,4 @@ -package com.example.logistics.dao; +package com.example.logistics.manager; import android.util.Log; @@ -12,7 +12,7 @@ import java.util.HashMap; import java.sql.ResultSet; import java.sql.Connection; -public class userDao { +public class userManager { private static final String TAG = "userDao"; @@ -46,6 +46,7 @@ public class userDao { StringBuilder s = new StringBuilder(); for(String key:map.keySet()){ if(key.equals("password")){ + if(password.equals(map.get(key))){ msg = 1; //password correct }else{ diff --git a/src/Logistics/app/src/main/java/com/example/logistics/tools/DBOpenHelper.java b/src/Logistics/app/src/main/java/com/example/logistics/tools/DBOpenHelper.java index c561dbb..73f0b02 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/tools/DBOpenHelper.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/tools/DBOpenHelper.java @@ -7,9 +7,9 @@ import java.sql.SQLException; public class DBOpenHelper { private static String diver = "com.mysql.jdbc.Driver"; //加入utf-8是为了后面往表中输入中文,表中不会出现乱码的情况 - private static String url = "jdbc:mysql://49.235.83.73:3306/logistics?characterEncoding=utf-8"; + private static String url = "jdbc:mysql://192.168.43.203:3306/logistics?characterEncoding=utf-8"; private static String user = "root";//用户名 - private static String password = "123";//密码 + private static String password = "";//密码 /* * 连接数据库 * */ diff --git a/src/Logistics/app/src/main/java/com/example/logistics/tools/JWebSocketClient.java b/src/Logistics/app/src/main/java/com/example/logistics/tools/JWebSocketClient.java new file mode 100644 index 0000000..4236ecf --- /dev/null +++ b/src/Logistics/app/src/main/java/com/example/logistics/tools/JWebSocketClient.java @@ -0,0 +1,35 @@ +package com.example.logistics.tools; + +import android.util.Log; + +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.handshake.ServerHandshake; + +import java.net.URI; + +public class JWebSocketClient extends WebSocketClient { + public JWebSocketClient(URI serverUri) { + super(serverUri, new Draft_6455()); + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + Log.e("JWebSocketClient", "onOpen()"); + } + + @Override + public void onMessage(String message) { + Log.e("JWebSocketClient", "onMessage()"); + } + + @Override + public void onClose(int code, String reason, boolean remote) { + Log.e("JWebSocketClient", "onClose()"); + } + + @Override + public void onError(Exception ex) { + Log.e("JWebSocketClient", "onError()"); + } +} diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/HistoryActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/HistoryActivity.java index 4cc6c2e..3a89a44 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/HistoryActivity.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/HistoryActivity.java @@ -1,11 +1,8 @@ package com.example.logistics.ui; -import androidx.appcompat.app.AppCompatActivity; - import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; -import android.media.Image; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -22,8 +19,7 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.Toast; import com.example.logistics.R; -import com.example.logistics.dao.goodDao; -import com.example.logistics.dao.operationDao; +import com.example.logistics.manager.operationManager; import java.util.ArrayList; import java.util.List; @@ -101,8 +97,8 @@ public class HistoryActivity extends Activity implements OnItemClickListener, On new Thread(){ @Override public void run(){ - operationDao operationDao = new operationDao(); - dataList = operationDao.history(phonenum); + operationManager operationManager = new operationManager(); + dataList = operationManager.history(phonenum); int msg = 1; hand1.sendEmptyMessage(msg); diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java index fc419de..b2e3517 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java @@ -1,9 +1,8 @@ package com.example.logistics.ui; import com.example.logistics.R; -import com.example.logistics.dao.userDao; +import com.example.logistics.manager.userManager; import com.example.logistics.entity.User; -import com.example.logistics.tools.MD5Utils; import android.annotation.SuppressLint; import android.app.Activity; @@ -17,9 +16,6 @@ import android.widget.Button; import android.widget.EditText; import android.widget.Toast; -import java.text.SimpleDateFormat; -import java.util.Date; - public class MainActivity extends Activity { @@ -60,12 +56,12 @@ public class MainActivity extends Activity { new Thread(){ @Override public void run(){ - userDao userDao = new userDao(); - int msg = userDao.login(userName.getText().toString().trim(), passWord.getText().toString().trim()); + userManager userManager = new userManager(); + int msg = userManager.login(userName.getText().toString().trim(), passWord.getText().toString().trim()); Log.e("MAin", "msg"); hand1.sendEmptyMessage(msg); if(msg == 1){ - User owner = userDao.findUser(userName.getText().toString().trim()); + User owner = userManager.findUser(userName.getText().toString().trim()); Intent intent = new Intent(MainActivity.this, MenuActivity.class); intent.putExtra("user", owner.getPhoneNum()); startActivity(intent); diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment3.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java similarity index 95% rename from src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment3.java rename to src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java index 2ff01f4..84e6ba6 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment3.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java @@ -18,14 +18,14 @@ import com.example.logistics.R; import org.w3c.dom.Text; -public class MyFragment3 extends Fragment implements View.OnClickListener{ +public class MeUI extends Fragment implements View.OnClickListener{ private LinearLayout ll_waiting; private LinearLayout ll_history; private LinearLayout ll_exit; private Context mContext; private String user; - public MyFragment3(){ + public MeUI(){ } @Nullable diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MenuActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/MenuActivity.java index c366436..95ed844 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MenuActivity.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/MenuActivity.java @@ -93,7 +93,7 @@ public class MenuActivity extends AppCompatActivity implements View.OnClickListe mTextView1.setSelected(true); mTextNum1.setVisibility(View.INVISIBLE); if (mFrag1 == null) { - mFrag1 = new MyFragment1(); + mFrag1 = new SearchUI(); transaction.add(R.id.fragment_container, mFrag1); @@ -106,7 +106,7 @@ public class MenuActivity extends AppCompatActivity implements View.OnClickListe mTextView2.setSelected(true); mTextNum2.setVisibility(View.INVISIBLE); if (mFrag2 == null) { - mFrag2 = new MyFragment2(); + mFrag2 = new PickUpUI(); Bundle bundle = new Bundle(); bundle.putString("user", owner); mFrag2.setArguments(bundle); @@ -120,7 +120,7 @@ public class MenuActivity extends AppCompatActivity implements View.OnClickListe mTextView3.setSelected(true); mTextNum3.setVisibility(View.INVISIBLE); if (mFrag3 == null) { - mFrag3 = new MyFragment3(); + mFrag3 = new MeUI(); Bundle bundle = new Bundle(); bundle.putString("user", owner); mFrag3.setArguments(bundle); diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment2.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment2.java deleted file mode 100644 index 8f28860..0000000 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment2.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.example.logistics.ui; - -import androidx.fragment.app.Fragment; - -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.Nullable; - -import com.example.logistics.R; -import com.example.logistics.dao.goodDao; -import com.example.logistics.dao.operationDao; -import com.example.logistics.dao.userDao; -import com.example.logistics.entity.User; -import com.google.zxing.integration.android.IntentIntegrator; -import com.google.zxing.integration.android.IntentResult; -import com.journeyapps.barcodescanner.CaptureActivity; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -public class MyFragment2 extends Fragment implements View.OnClickListener{ - - private Button mButton; - private Context mContext; - - private WebView mWebView; - - public MyFragment2(){ - - } - @Nullable - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.my_fragment2,container,false); - mWebView = (WebView) view.findViewById(R.id.webview); - - WebSettings webSettings = mWebView.getSettings(); - mButton = (Button)view.findViewById(R.id.Pick_Button); - mButton.setOnClickListener(this); - mContext = getActivity(); - - webSettings.setJavaScriptEnabled(true); - mWebView.loadUrl("file:///android_asset/js.html"); - - Log.i("set", "listner"); - - mWebView.setWebViewClient(new WebViewClient(){ - @Override - public void onPageFinished(WebView view, String url){ - super.onPageFinished(view, url); - String jsStr1 = ""; - try{ - InputStream in1 = mContext.getAssets().open("em.js"); - byte buff[] = new byte[1024]; - ByteArrayOutputStream fromFile = new ByteArrayOutputStream(); - do { - int numRead = in1.read(buff); - if (numRead <= 0) { - break; - } - fromFile.write(buff, 0, numRead); - } while (true); - jsStr1 = fromFile.toString(); - in1.close(); - fromFile.close(); - } catch (IOException e) { - e.printStackTrace(); - } - mWebView.loadUrl("javascript:" + jsStr1); - - String jsStr2 = ""; - try{ - InputStream in2 = mContext.getAssets().open("roslib.min.js"); - byte buff[] = new byte[1024]; - ByteArrayOutputStream fromFile = new ByteArrayOutputStream(); - do { - int numRead = in2.read(buff); - if (numRead <= 0) { - break; - } - fromFile.write(buff, 0, numRead); - } while (true); - jsStr2 = fromFile.toString(); - in2.close(); - fromFile.close(); - } catch (IOException e) { - e.printStackTrace(); - } - mWebView.loadUrl("javascript:" + jsStr2); - } - - }); - - - return view; - } - - @Override - public void onClick(View view) { - switch(view.getId()){ - case R.id.Pick_Button: - /*new IntentIntegrator(getActivity()) - .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)// 扫码的类型,一维码,二维码,一/二维码,默认为一/二维码 - .setPrompt("请对准摄像头") - .setCameraId(0) - .setBeepEnabled(false) - .setCaptureActivity(CaptureActivity.class) - .initiateScan();*/ - pickup("abnc"); - - } - } - - public void test(){ - mWebView.loadUrl("javascript:callJS()"); - Log.i("abc", "bcd"); - } - - - @Override - @SuppressLint("MissingSuperCall") - public void onActivityResult(int requestCode, int resultCode, Intent data) { - IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); - if(result != null) { - if(result.getContents() != null) { - //Toast.makeText(mContext, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show(); - pickup(result.getContents()); - } - } - } - - public void pickup(String result){ - AlertDialog.Builder builder = new AlertDialog.Builder(mContext); - - View view2 = View.inflate(mContext, R.layout.pickup, null); - - EditText PickUpCode = (EditText) view2.findViewById(R.id.pk_PickUp); - EditText PhoneNum = (EditText) view2.findViewById(R.id.pk_PhoneNum); - Button button = (Button) view2.findViewById(R.id.pk_button); - - builder.setTitle("取件").setView(view2); - - builder.create().show(); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - String pickupcode = PickUpCode.getText().toString().trim(); - String phonenum = PhoneNum.getText().toString().trim(); - Log.d("onclick", "123"); - //String QR_pickup = result.split(" ")[0]; - //String QR_phone = result.split(" ")[1]; - - if(true){ - //if (pickupcode.equals(QR_pickup) && phonenum.equals(QR_phone)) { - /*new Thread() { - @Override - public void run() { - int msg = 0; - - operationDao operationDao = new operationDao(); - goodDao goodDao = new goodDao(); - Bundle bundle = getArguments(); - - String user = bundle.getString("user"); - - boolean flag1 = operationDao.add(pickupcode, user); - boolean flag2 = goodDao.delete(pickupcode); - - boolean flag = flag1 & flag2; - if (flag) { - msg = 1; - } - int msg = 1; - test(); - hand1.sendEmptyMessage(msg); - } - }.start();*/ - Toast.makeText(mContext, "取件成功", Toast.LENGTH_LONG).show(); - test(); - - } else { - Toast.makeText(mContext, "取件失败", Toast.LENGTH_LONG).show(); - } - } - - - }); - } - - @SuppressLint("HandlerLeak") - final Handler hand1 = new Handler() { - @Override - public void handleMessage(Message msg) { - if (msg.what == 1) { - Toast.makeText(mContext, "取件成功", Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(mContext, "取件失败", Toast.LENGTH_SHORT); - } - } - }; -} \ No newline at end of file diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/NoPickActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/NoPickActivity.java index d23a064..104bee1 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/NoPickActivity.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/NoPickActivity.java @@ -1,9 +1,5 @@ package com.example.logistics.ui; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; @@ -19,21 +15,14 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageButton; import android.widget.ListView; -import android.widget.NumberPicker; import android.widget.SimpleAdapter; import android.widget.Toast; import com.example.logistics.R; -import com.example.logistics.dao.goodDao; -import com.example.logistics.dao.userDao; -import com.example.logistics.entity.User; +import com.example.logistics.manager.goodManager; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.ListIterator; import java.util.Map; public class NoPickActivity extends Activity implements OnItemClickListener, OnScrollListener, View.OnClickListener { @@ -110,8 +99,8 @@ public class NoPickActivity extends Activity implements OnItemClickListener, OnS new Thread(){ @Override public void run(){ - goodDao goodDao = new goodDao(); - dataList = goodDao.nopick(phonenum); + goodManager goodManager = new goodManager(); + dataList = goodManager.nopick(phonenum); int msg = 1; hand1.sendEmptyMessage(msg); diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java new file mode 100644 index 0000000..d0d0912 --- /dev/null +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java @@ -0,0 +1,306 @@ +package com.example.logistics.ui; + +import androidx.fragment.app.Fragment; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebSettings; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.Nullable; + +import com.example.logistics.R; +import com.example.logistics.manager.goodManager; +import com.example.logistics.manager.operationManager; +import com.example.logistics.tools.JWebSocketClient; +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + +import org.java_websocket.handshake.ServerHandshake; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +public class PickUpUI extends Fragment implements View.OnClickListener{ + + private Button mButton; + private Context mContext; + private JWebSocketClient client; + private AlertDialog alert; + private AlertDialog alert2; + private EditText PickUpCode; + private EditText PhoneNum; + private String pickupcode; + private String phonenum; + private int shelfnum = 1; + private int floornum = 1; + + private String ws = "ws://192.168.43.203:8080/result"; + + private String TAG = "PickUpUI"; + + int flag = 0; //flag=0:chushi + + public PickUpUI(){ + + } + @Nullable + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.my_fragment2,container,false); + + mButton = (Button)view.findViewById(R.id.Pick_Button); + mButton.setOnClickListener(this); + mContext = getActivity(); + + Log.i("set", "listner"); + + setAlert(); + return view; + } + + + void setAlert(){ + alert = new android.app.AlertDialog.Builder(mContext) + .setTitle("提醒") + .setMessage("是否确认取件") + .setPositiveButton("确认", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Log.d("alert","yes"); + //add(operation); + JSONObject js = new JSONObject(); + try { + js.put("content", "yes"); + js.put("op", "confirm"); + } catch (JSONException e) { + e.printStackTrace(); + } + flag = 1; + + mButton.setText("确认"); + + client.send(js.toString()); + Log.d("alert", "send"); + } + }) + .setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Log.d("alert","no"); + + JSONObject js = new JSONObject(); + try { + js.put("confirm", "no"); + js.put("op", "confirm"); + } catch (JSONException e) { + e.printStackTrace(); + } + + client.send(js.toString()); + } + }) + .create(); + Log.d(TAG, "setAlert"); + } + + void setWebsocket(){ + URI uri = URI.create(ws); + client = new JWebSocketClient(uri){ + @Override + public void onMessage(String message) { + Log.e("JWebSocketClientService", "收到的消息:" + message); + Log.e("alert",message); + if(message.equals("confirm")){ + alert.dismiss(); + hand2.sendEmptyMessage(3); + Log.e("alert","show"); + } + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + super.onOpen(handshakedata); + Log.e("JWebSocketClientService", "websocket连接成功"); + }; + }; + connect(); + } + + private void connect() { + new Thread() { + @Override + public void run() { + try { + //connectBlocking多出一个等待操作,会先连接再发送,否则未连接发送会报错 + client.connectBlocking(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }.start(); + + } + + @SuppressLint("HandlerLeak") + final Handler hand2 = new Handler(){ + @Override + public void handleMessage(Message msg){ + alert.show(); + } + }; + + @Override + public void onClick(View view) { + switch(view.getId()){ + case R.id.Pick_Button: + Log.e(TAG, "onclick"); + if(flag == 1){ + confirm(); + }else{ + pickup(); + } + + + } + } + + void confirm(){ + JSONObject js = new JSONObject(); + try { + js.put("op","finish"); + client.send(js.toString()); + + flag = 0; + mButton.setText("取件"); + client.onClose(1,"close",true); + Log.d("finish", "over"); + + } catch (JSONException jsonException) { + jsonException.printStackTrace(); + } + } + + + public void pickup(){ + AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + + View view2 = View.inflate(mContext, R.layout.pickup, null); + + PickUpCode = (EditText) view2.findViewById(R.id.pk_PickUp); + PhoneNum = (EditText) view2.findViewById(R.id.pk_PhoneNum); + Button button = (Button) view2.findViewById(R.id.pk_button); + + builder.setTitle("取件").setView(view2); + + + alert2 = builder.create(); + alert2.show(); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Log.e(TAG,"onclick"); + setWebsocket(); + pickupcode = PickUpCode.getText().toString().trim(); + phonenum = PhoneNum.getText().toString().trim(); + Log.d("onclick", "123"); + new Thread() { + @Override + public void run() { + int msg = 0; + + operationManager operationManager = new operationManager(); + goodManager goodManager = new goodManager(); + Bundle bundle = getArguments(); + + String user = bundle.getString("user"); + + msg = goodManager.pickup(pickupcode,phonenum); + + Log.d(TAG, "pickup"); + if(msg != 1){ + Log.d(TAG, "pickup,failed"); + hand1.sendEmptyMessage(msg); + return; + } + + Log.d(TAG, "pickup,success"); + + boolean flag1 = operationManager.add(pickupcode, user); + boolean flag2 = goodManager.delete(pickupcode); + + boolean flag = flag1 & flag2; + if (flag) { + msg = 1; + } + + hand1.sendEmptyMessage(msg); + } + }.start(); + } + }); + } + + @SuppressLint("HandlerLeak") + final Handler hand1 = new Handler() { + @Override + public void handleMessage(Message msg) { + if(msg.what == 0){ + Toast.makeText(mContext, "取件失败", Toast.LENGTH_SHORT).show(); + }else if(msg.what == 1){ + Toast.makeText(mContext, "加入队列成功", Toast.LENGTH_SHORT).show(); + joinQueue(); + }else if(msg.what == 2){ + Toast.makeText(mContext, "手机号错误", Toast.LENGTH_SHORT).show(); + }else if(msg.what == 3){ + Toast.makeText(mContext, "取件码不存在", Toast.LENGTH_SHORT).show(); + } + } + }; + + void joinQueue(){ + alert2.dismiss(); + if (client != null && client.isOpen()) { + + JSONObject js = new JSONObject(); + JSONObject con = new JSONObject(); + try { + Log.d(TAG, pickupcode); + Log.d(TAG, phonenum); + + con.put("code", Integer.parseInt(pickupcode)); + con.put("shelf", shelfnum); + con.put("floor", floornum); + con.put("user", "xcr"); + js.put("content", con); + js.put("op", "connect"); + } catch (JSONException jsonException) { + jsonException.printStackTrace(); + } + + if (null != client) { + Log.e("JWebSocketClientService", "发送的消息:" + js.toString()); + client.send(js.toString()); + //暂时将发送的消息加入消息列表,实际以发送成功为准(也就是服务器返回你发的消息时) + } + } + } +} \ No newline at end of file diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment1.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/SearchUI.java similarity index 81% rename from src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment1.java rename to src/Logistics/app/src/main/java/com/example/logistics/ui/SearchUI.java index 46caef0..e9bf32b 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MyFragment1.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/SearchUI.java @@ -2,9 +2,7 @@ package com.example.logistics.ui; import android.annotation.SuppressLint; -import android.app.AlertDialog; import android.content.Context; -import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -14,23 +12,21 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.example.logistics.R; -import com.example.logistics.dao.goodDao; -import com.example.logistics.dao.userDao; +import com.example.logistics.manager.goodManager; -public class MyFragment1 extends Fragment implements View.OnClickListener{ +public class SearchUI extends Fragment implements View.OnClickListener{ private Context mContext; private Button mButton; private EditText mPickUpCode; private EditText mPhoneNum; - public MyFragment1(){ + public SearchUI(){ } @Nullable @@ -60,8 +56,8 @@ public class MyFragment1 extends Fragment implements View.OnClickListener{ new Thread(){ @Override public void run(){ - goodDao goodDao = new goodDao(); - int msg = goodDao.search(mPickUpCode.getText().toString().trim(), mPhoneNum.getText().toString().trim(), getActivity()); + goodManager goodManager = new goodManager(); + int msg = goodManager.search(mPickUpCode.getText().toString().trim(), mPhoneNum.getText().toString().trim(), getActivity()); Log.e("Main", "msg"); hand1.sendEmptyMessage(msg); } diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java index f927349..d63254a 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java @@ -12,7 +12,7 @@ import android.widget.EditText; import android.widget.Toast; import com.example.logistics.R; -import com.example.logistics.dao.userDao; +import com.example.logistics.manager.userManager; import com.example.logistics.entity.User; public class SignUpActivity extends Activity { @@ -79,14 +79,14 @@ public class SignUpActivity extends Activity { @Override public void run(){ int msg = 0; - userDao userDao = new userDao(); + userManager userManager = new userManager(); - User uu = userDao.findUser(user.getUserName()); + User uu = userManager.findUser(user.getUserName()); if(uu != null){ msg = 1; //have this account }else{ - boolean flag = userDao.register(user); + boolean flag = userManager.register(user); if(flag){ msg = 2; } diff --git a/src/server/.gitignore b/src/server/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/src/server/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/src/server/.mvn/wrapper/maven-wrapper.jar b/src/server/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c1dd12f17644411d6e840bd5a10c6ecda0175f18 GIT binary patch literal 58727 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%0ANsA|A3-jj|r`KAo%oTajX3>^E` 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 YM{}PByk10KD_nuQ4E7Du?}+~TKh4V)`~Uy| literal 0 HcmV?d00001 diff --git a/src/server/.mvn/wrapper/maven-wrapper.properties b/src/server/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..b7cb93e --- /dev/null +++ b/src/server/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/src/server/mvnw b/src/server/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/src/server/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/src/server/mvnw.cmd b/src/server/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/src/server/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/src/server/pom.xml b/src/server/pom.xml new file mode 100644 index 0000000..ab4f8f1 --- /dev/null +++ b/src/server/pom.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>2.5.4</version> + <relativePath/> <!-- lookup parent from repository --> + </parent> + <groupId>com.example</groupId> + <artifactId>testdemo</artifactId> + <version>0.0.1-SNAPSHOT</version> + <name>testdemo</name> + <description>testdemo</description> + <properties> + <java.version>1.8</java.version> + </properties> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-websocket</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + </dependency> + + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>fastjson</artifactId> + <version>1.2.73</version> + </dependency> + <dependency> + <groupId>org.seleniumhq.selenium</groupId> + <artifactId>selenium-java</artifactId> + <version>3.141.59</version> + </dependency> + + </dependencies> + <profiles> + <profile> + <id>sonar</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <properties> + <sonar.host.url>http://127.0.0.1:9000/</sonar.host.url> + </properties> + </profile> + </profiles> + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.sonarsource.scanner.maven</groupId> + <artifactId>sonar-maven-plugin</artifactId> + <version>3.6.0.1398</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>7</source> + <target>7</target> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/src/server/src/main/java/com/example/testdemo/TestdemoApplication.java b/src/server/src/main/java/com/example/testdemo/TestdemoApplication.java new file mode 100644 index 0000000..5b0706c --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/TestdemoApplication.java @@ -0,0 +1,42 @@ +package com.example.testdemo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.sun.javafx.webkit.EventLoopImpl; +import org.openqa.selenium.*; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.sql.Driver; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ConcurrentLinkedQueue; + + +@SpringBootApplication +public class TestdemoApplication { + + public static void main(String[] args) { + + SpringApplication.run(TestdemoApplication.class, args); + } + + +} + + diff --git a/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java b/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java new file mode 100644 index 0000000..1b84ae8 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/config/SendObjectMessage.java @@ -0,0 +1,176 @@ +package com.example.testdemo.config; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import jdk.nashorn.internal.scripts.JS; +import lombok.extern.slf4j.Slf4j; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.springframework.stereotype.Component; +import sun.rmi.runtime.Log; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.websocket.*; +import javax.websocket.server.ServerEndpoint; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @Description : 群发消息 //描述 + */ +@Slf4j +@ServerEndpoint("/result") +@Component +public class SendObjectMessage { + + /** 记录当前在线连接数 */ + private static AtomicInteger onlineCount = new AtomicInteger(0); + private static ConcurrentLinkedQueue<SendObjectMessage> socket = new ConcurrentLinkedQueue<SendObjectMessage>(); + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + private Session session; + private SendObjectMessage mObject = null; + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(Session session) { + this.session = session; + socket.add(this); + onlineCount.incrementAndGet(); // 在线数加1 + if(mObject == null){ + mObject = socket.peek(); + } + /*try { + sendMessage("连接成功!"); + } catch (IOException e) { + e.printStackTrace(); + }*/ + log.info("有新连接加入,当前在线人数为:{}", onlineCount.get()); + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose(Session session) { + socket.remove(this); + // 在线数减1 + onlineCount.decrementAndGet(); + log.info("用户退出,当前在线人数为:{}", onlineCount.get()); + } + + /** + * 收到客户端消息后调用的方法 + * + * @param message + * 客户端发送过来的消息 + */ + @OnMessage + public void onMessage(String message, Session session) throws IOException { + if (message != null && !message.isEmpty()) { + //socket.peek().sendMessage(message); + JSONObject js = JSONObject.parseObject(message); + String op = js.getString("op"); + + if(op.equals("connect")){ + JSONObject content = js.getJSONObject("content"); + String user = content.getString("user"); + //JSONArray note = content.getJSONArray("note"); + Integer code = content.getInteger("code"); + Integer shelf = content.getInteger("shelf"); + Integer floor = content.getInteger("floor"); + + System.out.println(content); + mObject.sendMessage("confirm"); + + }else if(op.equals("confirm")){ + String con = js.getString("content"); + if(con.equals("yes")){ + try { + testSelenium1(); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("robot"); + }else if(con.equals("no")){ + System.out.println("no"); + } + }else if(op.equals("finish")){ + System.out.println("fin"); + mObject.onClose(mObject.session); + socket.poll(); + + if(socket.peek() != null){ + mObject = socket.peek(); + mObject.sendMessage("confirm"); + }else{ + mObject = null; + } + } + } + log.info("服务端收到客户端的消息:{}", message); + } + + @OnError + public void onError(Throwable error) { + log.error("发生错误"); + error.printStackTrace(); + } + + /** + * 服务端发送消息给客户端 + */ + public void sendMessage(String message) throws IOException { + //如果开启@Async异步需要加锁,否则就会报错 + synchronized (session){ + this.session.getBasicRemote().sendText(message); + } + } + + /** + * 自定义群发 + */ + + public static void testSelenium1() throws Exception { + // 使用HtmlUnitDriver 是不需要 安装 浏览器 和 驱动支持\ + System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe"); + ChromeOptions chromeOptions = new ChromeOptions(); + chromeOptions.setHeadless(true); + + WebDriver driver = new ChromeDriver(chromeOptions); + //ChromeDriver driver = new ChromeDriver(); + + JavascriptExecutor executor = (JavascriptExecutor) driver; + String strFile = Thread.currentThread().getClass().getResource("/").getPath(); + //driver.get(strFile + "/test.html"); + driver.get("file://" + strFile + "/test.html"); + + + } + private static String readJsFile(String url) throws Exception { + StringBuffer script = new StringBuffer(); + + File file = new File(url); + FileReader filereader = new FileReader(file); + BufferedReader bufferedReader = new BufferedReader(filereader); + String tempString = null; + while ((tempString = bufferedReader.readLine()) != null) { + script.append(tempString).append("\n"); + } + bufferedReader.close(); + filereader.close(); + return script.toString(); + } + +} diff --git a/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java b/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java new file mode 100644 index 0000000..dc62fa8 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/config/WebSocketConfig.java @@ -0,0 +1,17 @@ +package com.example.testdemo.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @Description : websocket配置 //描述 + */ +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter(){ + return new ServerEndpointExporter(); + } +} diff --git a/src/server/src/main/resources/a.js b/src/server/src/main/resources/a.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/server/src/main/resources/a.js @@ -0,0 +1 @@ + diff --git a/src/server/src/main/resources/application.yml b/src/server/src/main/resources/application.yml new file mode 100644 index 0000000..5b63b17 --- /dev/null +++ b/src/server/src/main/resources/application.yml @@ -0,0 +1,18 @@ +server: + port: 8080 + servlet: + contest-path: / +spring: + application: + name: springboot websocket + mvc: + static-path-pattern: /** + thymeleaf: + mode: HTML5 + suffix: .html + encoding: UTF-8 + prefix: + classpath: /template + cache: false + + diff --git a/src/server/src/main/resources/em.js b/src/server/src/main/resources/em.js new file mode 100644 index 0000000..a5af1ed --- /dev/null +++ b/src/server/src/main/resources/em.js @@ -0,0 +1 @@ +!function(e){function t(){this._events={},this._conf&&i.call(this,this._conf)}function i(e){e&&(this._conf=e,e.delimiter&&(this.delimiter=e.delimiter),e.maxListeners&&(this._events.maxListeners=e.maxListeners),e.wildcard&&(this.wildcard=e.wildcard),e.newListener&&(this.newListener=e.newListener),this.wildcard&&(this.listenerTree={}))}function s(e){this._events={},this.newListener=!1,i.call(this,e)}function n(e,t,i,s){if(!i)return[];var r,l,o,h,a,f,c,_=[],p=t.length,u=t[s],v=t[s+1];if(s===p&&i._listeners){if("function"==typeof i._listeners)return e&&e.push(i._listeners),[i];for(r=0,l=i._listeners.length;r<l;r++)e&&e.push(i._listeners[r]);return[i]}if("*"===u||"**"===u||i[u]){if("*"===u){for(o in i)"_listeners"!==o&&i.hasOwnProperty(o)&&(_=_.concat(n(e,t,i[o],s+1)));return _}if("**"===u){(c=s+1===p||s+2===p&&"*"===v)&&i._listeners&&(_=_.concat(n(e,t,i,p)));for(o in i)"_listeners"!==o&&i.hasOwnProperty(o)&&("*"===o||"**"===o?(i[o]._listeners&&!c&&(_=_.concat(n(e,t,i[o],p))),_=_.concat(n(e,t,i[o],s))):_=o===v?_.concat(n(e,t,i[o],s+2)):_.concat(n(e,t,i[o],s)));return _}_=_.concat(n(e,t,i[u],s+1))}if((h=i["*"])&&n(e,t,h,s+1),a=i["**"])if(s<p){a._listeners&&n(e,t,a,p);for(o in a)"_listeners"!==o&&a.hasOwnProperty(o)&&(o===v?n(e,t,a[o],s+2):o===u?n(e,t,a[o],s+1):((f={})[o]=a[o],n(e,t,{"**":f},s+1)))}else a._listeners?n(e,t,a,p):a["*"]&&a["*"]._listeners&&n(e,t,a["*"],p);return _}function r(e,t){for(var i=0,s=(e="string"==typeof e?e.split(this.delimiter):e.slice()).length;i+1<s;i++)if("**"===e[i]&&"**"===e[i+1])return;for(var n=this.listenerTree,r=e.shift();r;){if(n[r]||(n[r]={}),n=n[r],0===e.length){if(n._listeners){if("function"==typeof n._listeners)n._listeners=[n._listeners,t];else if(l(n._listeners)&&(n._listeners.push(t),!n._listeners.warned)){var h=o;void 0!==this._events.maxListeners&&(h=this._events.maxListeners),h>0&&n._listeners.length>h&&(n._listeners.warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",n._listeners.length),console.trace())}}else n._listeners=t;return!0}r=e.shift()}return!0}var l=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)},o=10;s.prototype.delimiter=".",s.prototype.setMaxListeners=function(e){this._events||t.call(this),this._events.maxListeners=e,this._conf||(this._conf={}),this._conf.maxListeners=e},s.prototype.event="",s.prototype.once=function(e,t){return this.many(e,1,t),this},s.prototype.many=function(e,t,i){function s(){0==--t&&n.off(e,s),i.apply(this,arguments)}var n=this;if("function"!=typeof i)throw new Error("many only accepts instances of Function");return s._origin=i,this.on(e,s),n},s.prototype.emit=function(){this._events||t.call(this);var e=arguments[0];if("newListener"===e&&!this.newListener&&!this._events.newListener)return!1;if(this._all){for(var i=arguments.length,s=new Array(i-1),r=1;r<i;r++)s[r-1]=arguments[r];for(r=0,i=this._all.length;r<i;r++)this.event=e,this._all[r].apply(this,s)}if("error"===e&&!(this._all||this._events.error||this.wildcard&&this.listenerTree.error))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");var l;if(this.wildcard){l=[];var o="string"==typeof e?e.split(this.delimiter):e.slice();n.call(this,l,o,this.listenerTree,0)}else l=this._events[e];if("function"==typeof l){if(this.event=e,1===arguments.length)l.call(this);else if(arguments.length>1)switch(arguments.length){case 2:l.call(this,arguments[1]);break;case 3:l.call(this,arguments[1],arguments[2]);break;default:for(var i=arguments.length,s=new Array(i-1),r=1;r<i;r++)s[r-1]=arguments[r];l.apply(this,s)}return!0}if(l){for(var i=arguments.length,s=new Array(i-1),r=1;r<i;r++)s[r-1]=arguments[r];for(var h=l.slice(),r=0,i=h.length;r<i;r++)this.event=e,h[r].apply(this,s);return h.length>0||!!this._all}return!!this._all},s.prototype.on=function(e,i){if("function"==typeof e)return this.onAny(e),this;if("function"!=typeof i)throw new Error("on only accepts instances of Function");if(this._events||t.call(this),this.emit("newListener",e,i),this.wildcard)return r.call(this,e,i),this;if(this._events[e]){if("function"==typeof this._events[e])this._events[e]=[this._events[e],i];else if(l(this._events[e])&&(this._events[e].push(i),!this._events[e].warned)){var s=o;void 0!==this._events.maxListeners&&(s=this._events.maxListeners),s>0&&this._events[e].length>s&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace())}}else this._events[e]=i;return this},s.prototype.onAny=function(e){if("function"!=typeof e)throw new Error("onAny only accepts instances of Function");return this._all||(this._all=[]),this._all.push(e),this},s.prototype.addListener=s.prototype.on,s.prototype.off=function(e,t){if("function"!=typeof t)throw new Error("removeListener only takes instances of Function");var i,s=[];if(this.wildcard){var r="string"==typeof e?e.split(this.delimiter):e.slice();s=n.call(this,null,r,this.listenerTree,0)}else{if(!this._events[e])return this;i=this._events[e],s.push({_listeners:i})}for(var o=0;o<s.length;o++){var h=s[o];if(i=h._listeners,l(i)){for(var a=-1,f=0,c=i.length;f<c;f++)if(i[f]===t||i[f].listener&&i[f].listener===t||i[f]._origin&&i[f]._origin===t){a=f;break}if(a<0)continue;return this.wildcard?h._listeners.splice(a,1):this._events[e].splice(a,1),0===i.length&&(this.wildcard?delete h._listeners:delete this._events[e]),this}(i===t||i.listener&&i.listener===t||i._origin&&i._origin===t)&&(this.wildcard?delete h._listeners:delete this._events[e])}return this},s.prototype.offAny=function(e){var t,i=0,s=0;if(e&&this._all&&this._all.length>0){for(i=0,s=(t=this._all).length;i<s;i++)if(e===t[i])return t.splice(i,1),this}else this._all=[];return this},s.prototype.removeListener=s.prototype.off,s.prototype.removeAllListeners=function(e){if(0===arguments.length)return!this._events||t.call(this),this;if(this.wildcard)for(var i="string"==typeof e?e.split(this.delimiter):e.slice(),s=n.call(this,null,i,this.listenerTree,0),r=0;r<s.length;r++)s[r]._listeners=null;else{if(!this._events[e])return this;this._events[e]=null}return this},s.prototype.listeners=function(e){if(this.wildcard){var i=[],s="string"==typeof e?e.split(this.delimiter):e.slice();return n.call(this,i,s,this.listenerTree,0),i}return this._events||t.call(this),this._events[e]||(this._events[e]=[]),l(this._events[e])||(this._events[e]=[this._events[e]]),this._events[e]},s.prototype.listenersAny=function(){return this._all?this._all:[]},"function"==typeof define&&define.amd?define(function(){return s}):"object"==typeof exports?exports.EventEmitter2=s:window.EventEmitter2=s}(); \ No newline at end of file diff --git a/src/server/src/main/resources/roslib.min.js b/src/server/src/main/resources/roslib.min.js new file mode 100644 index 0000000..506562b --- /dev/null +++ b/src/server/src/main/resources/roslib.min.js @@ -0,0 +1 @@ +!function n(r,s,o){function a(t,e){if(!s[t]){if(!r[t]){var i="function"==typeof require&&require;if(!e&&i)return i(t,!0);if(c)return c(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}i=s[t]={exports:{}},r[t][0].call(i.exports,function(e){return a(r[t][1][e]||e)},i,i.exports,n,r,s,o)}return s[t].exports}for(var c="function"==typeof require&&require,e=0;e<o.length;e++)a(o[e]);return a}({1:[function(e,i,t){!function(e,A){"use strict";var U=Math.pow(2,-24),r=Math.pow(2,32),v=Math.pow(2,53);var t={encode:function(e){var o,a=new ArrayBuffer(256),c=new DataView(a),l=0;function u(e){for(var t=a.byteLength,i=l+e;t<i;)t*=2;if(t!==a.byteLength)for(var n=c,r=(a=new ArrayBuffer(t),c=new DataView(a),l+3>>2),s=0;s<r;++s)c.setUint32(4*s,n.getUint32(4*s));return o=e,c}function h(){l+=o}function f(e){h(u(1).setUint8(l,e))}function p(e){for(var t=u(e.length),i=0;i<e.length;++i)t.setUint8(l+i,e[i]);h()}function m(e,t){var i,n;t<24?f(e<<5|t):t<256?(f(e<<5|24),f(t)):t<65536?(f(e<<5|25),n=t,h(u(2).setUint16(l,n))):t<4294967296?(f(e<<5|26),n=t,h(u(4).setUint32(l,n))):(f(e<<5|27),e=((e=t)-(t=t%r))/r,(i=u(8)).setUint32(l,e),i.setUint32(l+4,t),h())}if(!function e(t){var i;if(!1===t)return f(244);if(!0===t)return f(245);if(null===t)return f(246);if(t===A)return f(247);switch(typeof t){case"number":if(Math.floor(t)===t){if(0<=t&&t<=v)return m(0,t);if(-v<=t&&t<0)return m(1,-(t+1))}return f(251),i=t,h(u(8).setFloat64(l,i));case"string":for(var n=[],r=0;r<t.length;++r){var s=t.charCodeAt(r);s<128?n.push(s):(s<2048?n.push(192|s>>6):(s<55296?n.push(224|s>>12):(s=65536+((s=(1023&s)<<10)|1023&t.charCodeAt(++r)),n.push(240|s>>18),n.push(128|s>>12&63)),n.push(128|s>>6&63)),n.push(128|63&s))}return m(3,n.length),p(n);default:if(Array.isArray(t))for(m(4,o=t.length),r=0;r<o;++r)e(t[r]);else if(t instanceof Uint8Array)m(2,t.length),p(t);else{var o,a=Object.keys(t);for(m(5,o=a.length),r=0;r<o;++r){var c=a[r];e(c),e(t[c])}}}}(e),"slice"in a)return a.slice(0,l);for(var e=new ArrayBuffer(l),t=new DataView(e),i=0;i<l;++i)t.setUint8(i,c.getUint8(i));return e},decode:function(t,d,y){var g=new DataView(t),b=0;function w(e,t){return b+=t,e}function _(e){return w(new Uint8Array(t,b,e),e)}function x(){return w(g.getUint8(b),1)}function T(){return w(g.getUint16(b),2)}function i(){return w(g.getUint32(b),4)}function k(){return 255===g.getUint8(b)&&(b+=1,1)}function S(e){if(e<24)return e;if(24===e)return x();if(25===e)return T();if(26===e)return i();if(27===e)return i()*r+i();if(31===e)return-1;throw"Invalid length encoding"}function L(e){var t=x();if(255===t)return-1;var i=S(31&t);if(i<0||t>>5!==e)throw"Invalid indefinite length element";return i}function M(e,t){for(var i=0;i<t;++i){var n=x();128&n&&(n<224?(n=(31&n)<<6|63&x(),--t):n<240?(n=(15&n)<<12|(63&x())<<6|63&x(),t-=2):(n=(15&n)<<18|(63&x())<<12|(63&x())<<6|63&x(),t-=3)),n<65536?e.push(n):(n-=65536,e.push(55296|n>>10),e.push(56320|1023&n))}}"function"!=typeof d&&(d=function(e){return e}),"function"!=typeof y&&(y=function(){return A});var e=function e(){var t,i,n=x(),r=n>>5,n=31&n;if(7==r)switch(n){case 25:var s=new ArrayBuffer(4),s=new DataView(s),o=T(),a=31744&o,c=1023&o;if(31744===a)a=261120;else if(0!==a)a+=114688;else if(0!=c)return c*U;return s.setUint32(0,(32768&o)<<16|a<<13|c<<13),s.getFloat32(0);case 26:return w(g.getFloat32(b),4);case 27:return w(g.getFloat64(b),8)}if((t=S(n))<0&&(r<2||6<r))throw"Invalid length";switch(r){case 0:return t;case 1:return-1-t;case 2:if(t<0){for(var l=[],u=0;0<=(t=L(r));)u+=t,l.push(_(t));for(var h=new Uint8Array(u),f=0,p=0;p<l.length;++p)h.set(l[p],f),f+=l[p].length;return h}return _(t);case 3:var m=[];if(t<0)for(;0<=(t=L(r));)M(m,t);else M(m,t);return String.fromCharCode.apply(null,m);case 4:if(t<0)for(i=[];!k();)i.push(e());else for(i=new Array(t),p=0;p<t;++p)i[p]=e();return i;case 5:var v={};for(p=0;p<t||t<0&&!k();++p)v[e()]=e();return v;case 6:return d(e(),t);case 7:switch(t){case 20:return!1;case 21:return!0;case 22:return null;case 23:return A;default:return y(t)}}}();if(b!==t.byteLength)throw"Remaining bytes";return e}};"function"==typeof define&&define.amd?define("cbor/cbor",t):void 0!==i&&i.exports?i.exports=t:e.CBOR||(e.CBOR=t)}(this)},{}],2:[function(e,U,E){!function(M,A){!function(){function h(){this._events={},this._conf&&t.call(this,this._conf)}function t(e){e&&((this._conf=e).delimiter&&(this.delimiter=e.delimiter),e.maxListeners!==g&&(this._maxListeners=e.maxListeners),e.wildcard&&(this.wildcard=e.wildcard),e.newListener&&(this._newListener=e.newListener),e.removeListener&&(this._removeListener=e.removeListener),e.verboseMemoryLeak&&(this.verboseMemoryLeak=e.verboseMemoryLeak),e.ignoreErrors&&(this.ignoreErrors=e.ignoreErrors),this.wildcard&&(this.listenerTree={}))}function f(e,t){var i="(node) warning: possible EventEmitter memory leak detected. "+e+" listeners added. Use emitter.setMaxListeners() to increase limit.";this.verboseMemoryLeak&&(i+=" Event name: "+t+"."),void 0!==M&&M.emitWarning?((t=new Error(i)).name="MaxListenersExceededWarning",t.emitter=this,t.count=e,M.emitWarning(t)):(console.error(i),console.trace&&console.trace())}function l(e,t,i){var n=arguments.length;switch(n){case 0:return[];case 1:return[e];case 2:return[e,t];case 3:return[e,t,i];default:for(var r=new Array(n);n--;)r[n]=arguments[n];return r}}function i(e,t){for(var i={},n=e.length,r=t?value.length:0,s=0;s<n;s++)i[e[s]]=s<r?t[s]:g;return i}function p(e,t,i){var n,r;if(this._emitter=e,this._target=t,this._listeners={},this._listenersCount=0,(i.on||i.off)&&(n=i.on,r=i.off),t.addEventListener?(n=t.addEventListener,r=t.removeEventListener):t.addListener?(n=t.addListener,r=t.removeListener):t.on&&(n=t.on,r=t.off),!n&&!r)throw Error("target does not implement any known event API");if("function"!=typeof n)throw TypeError("on method must be a function");if("function"!=typeof r)throw TypeError("off method must be a function");this._on=n,this._off=r;i=e._observers;i?i.push(this):e._observers=[this]}function m(e,t,i,n){var r=Object.assign({},t);if(!e)return r;if("object"!=typeof e)throw TypeError("options must be an object");var s,o,a,c=Object.keys(e),l=c.length;function u(e){throw Error('Invalid "'+s+'" option value'+(e?". Reason: "+e:""))}for(var h=0;h<l;h++){if(s=c[h],!n&&!b.call(t,s))throw Error('Unknown "'+s+'" option');(o=e[s])!==g&&(a=i[s],r[s]=a?a(o,u):o)}return r}function n(e,t){return"function"==typeof e&&e.hasOwnProperty("prototype")||t("value must be a constructor"),e}function e(r){var s="value must be type of "+r.join("|"),o=r.length,n=r[0],a=r[1];return 1===o?function(e,t){if(typeof e===n)return e;t(s)}:2===o?function(e,t){var i=typeof e;if(i===n||i===a)return e;t(s)}:function(e,t){for(var i=typeof e,n=o;0<n--;)if(i===r[n])return e;t(s)}}function c(o,a,c){var l,u,h,f=0,p=new o(function(t,i,e){function n(){u=u&&null,f&&(clearTimeout(f),f=0)}c=m(c,{timeout:0,overload:!1},{timeout:function(e,t){return("number"!=typeof(e*=1)||e<0||!Number.isFinite(e))&&t("timeout must be a positive number"),e}}),l=!c.overload&&"function"==typeof o.prototype.cancel&&"function"==typeof e;function r(e){n(),t(e)}function s(e){n(),i(e)}l?a(r,s,e):(u=[function(e){s(e||Error("canceled"))}],a(r,s,function(e){if(h)throw Error("Unable to subscribe on cancel event asynchronously");if("function"!=typeof e)throw TypeError("onCancel callback must be a function");u.push(e)}),h=!0),0<c.timeout&&(f=setTimeout(function(){var e=Error("timeout");e.code="ETIMEDOUT",f=0,p.cancel(e),i(e)},c.timeout))});return l||(p.cancel=function(e){if(u){for(var t=u.length,i=1;i<t;i++)u[i](e);u[0](e),u=null}}),p}function v(e){var t=this._observers;if(!t)return-1;for(var i=t.length,n=0;n<i;n++)if(t[n]._target===e)return n;return-1}function _(e,t,i,n,r){if(!i)return null;if(0===n){var s=typeof t;if("string"==s){var o,a,c=0,l=0,u=this.delimiter,h=u.length;if(-1!==(a=t.indexOf(u))){for(o=new Array(5);o[c++]=t.slice(l,a),-1!==(a=t.indexOf(u,l=a+h)););o[c++]=t.slice(l),t=o,r=c}else t=[t],r=1}else r="object"==s?t.length:(t=[t],1)}var f,p,m,v,d,y,g=null,b=t[n],w=t[n+1];if(n===r)i._listeners&&(g=("function"==typeof i._listeners?e&&e.push(i._listeners):e&&e.push.apply(e,i._listeners),[i]));else{if("*"===b){for(a=(d=S(i)).length;0<a--;)"_listeners"!==(f=d[a])&&(y=_(e,t,i[f],n+1,r))&&(g?g.push.apply(g,y):g=y);return g}if("**"===b){for((v=n+1===r||n+2===r&&"*"===w)&&i._listeners&&(g=_(e,t,i,r,r)),a=(d=S(i)).length;0<a--;)"_listeners"!==(f=d[a])&&(y="*"===f||"**"===f?(i[f]._listeners&&!v&&(y=_(e,t,i[f],r,r))&&(g?g.push.apply(g,y):g=y),_(e,t,i[f],n,r)):_(e,t,i[f],f===w?n+2:n,r))&&(g?g.push.apply(g,y):g=y);return g}i[b]&&(g=_(e,t,i[b],n+1,r))}if((s=i["*"])&&_(e,t,s,n+1,r),p=i["**"])if(n<r)for(p._listeners&&_(e,t,p,r,r),a=(d=S(p)).length;0<a--;)"_listeners"!==(f=d[a])&&(f===w?_(e,t,p[f],n+2,r):f===b?_(e,t,p[f],n+1,r):((m={})[f]=p[f],_(e,t,{"**":m},n+1,r)));else p._listeners?_(e,t,p,r,r):p["*"]&&p["*"]._listeners&&_(e,t,p["*"],r,r);return g}function u(e,t,i,n){for(var r,s,o,a=S(e),c=a.length,l=e._listeners;0<c--;)r=e[o=a[c]],s="_listeners"===o?i:i?i.concat(o):[o],o=n||"symbol"==typeof o,l&&t.push(o?s:s.join(this.delimiter)),"object"==typeof r&&u.call(this,r,t,s,o);return t}function d(e){for(var t,i,n,r=S(e),s=r.length;0<s--;)(t=e[i=r[s]])&&(n=!0,"_listeners"===i||d(t)||delete e[i]);return n}function y(e,t,i){this.emitter=e,this.event=t,this.listener=i}function r(e){this._events={},this._newListener=!1,this._removeListener=!1,this.verboseMemoryLeak=!1,t.call(this,e)}var g,b,w,x,T,s,k,S,a,o,L;b=Object.hasOwnProperty,w=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},x="object"==typeof M&&"function"==typeof M.nextTick,T="function"==typeof Symbol,s="object"==typeof Reflect,k="function"==typeof A?A:setTimeout,S=T?s&&"function"==typeof Reflect.ownKeys?Reflect.ownKeys:function(e){var t=Object.getOwnPropertyNames(e);return t.push.apply(t,Object.getOwnPropertySymbols(e)),t}:Object.keys,Object.assign(p.prototype,{subscribe:function(i,n,r){function t(){var e=l.apply(null,arguments),t={data:e,name:n,original:i};r?!1!==r.call(o,t)&&a.emit.apply(a,[t.name].concat(e)):a.emit.apply(a,[n].concat(e))}var s=this,o=this._target,a=this._emitter,c=this._listeners;if(c[i])throw Error("Event '"+i+"' is already listening");this._listenersCount++,a._newListener&&a._removeListener&&!s._onNewListener?(this._onNewListener=function(e){e===n&&null===c[i]&&(c[i]=t,s._on.call(o,i,t))},a.on("newListener",this._onNewListener),this._onRemoveListener=function(e){e===n&&!a.hasListeners(e)&&c[i]&&(c[i]=null,s._off.call(o,i,t))},c[i]=null,a.on("removeListener",this._onRemoveListener)):(c[i]=t,s._on.call(o,i,t))},unsubscribe:function(e){var t,i,n,r=this,s=this._listeners,o=this._emitter,a=this._off,c=this._target;if(e&&"string"!=typeof e)throw TypeError("event must be a string");function l(){r._onNewListener&&(o.off("newListener",r._onNewListener),o.off("removeListener",r._onRemoveListener),r._onNewListener=null,r._onRemoveListener=null);var e=v.call(o,r);o._observers.splice(e,1)}if(e)(t=s[e])&&(a.call(c,e,t),delete s[e],--this._listenersCount||l());else{for(n=(i=S(s)).length;0<n--;)e=i[n],a.call(c,e,s[e]);this._listeners={},this._listenersCount=0,l()}}}),a=e(["function"]),o=e(["object","function"]),y.prototype.off=function(){return this.emitter.off(this.event,this.listener),this},(r.EventEmitter2=r).prototype.listenTo=function(l,e,u){if("object"!=typeof l)throw TypeError("target musts be an object");var h=this;function t(e){if("object"!=typeof e)throw TypeError("events must be an object");for(var t,i=u.reducers,n=v.call(h,l),r=-1===n?new p(h,l,u):h._observers[n],s=S(e),o=s.length,a="function"==typeof i,c=0;c<o;c++)t=s[c],r.subscribe(t,e[t]||t,a?i:i&&i[t])}return u=m(u,{on:g,off:g,reducers:g},{on:a,off:a,reducers:o}),w(e)?t(i(e)):t("string"==typeof e?i(e.split(/\s+/)):e),this},r.prototype.stopListeningTo=function(e,t){var i=this._observers;if(!i)return!1;var n,r=i.length,s=!1;if(e&&"object"!=typeof e)throw TypeError("target should be an object");for(;0<r--;)n=i[r],e&&n._target!==e||(n.unsubscribe(t),s=!0);return s},r.prototype.delimiter=".",r.prototype.setMaxListeners=function(e){e!==g&&(this._maxListeners=e,this._conf||(this._conf={}),this._conf.maxListeners=e)},r.prototype.getMaxListeners=function(){return this._maxListeners},r.prototype.event="",r.prototype.once=function(e,t,i){return this._once(e,t,!1,i)},r.prototype.prependOnceListener=function(e,t,i){return this._once(e,t,!0,i)},r.prototype._once=function(e,t,i,n){return this._many(e,1,t,i,n)},r.prototype.many=function(e,t,i,n){return this._many(e,t,i,!1,n)},r.prototype.prependMany=function(e,t,i,n){return this._many(e,t,i,!0,n)},r.prototype._many=function(e,t,i,n,r){var s=this;if("function"!=typeof i)throw new Error("many only accepts instances of Function");function o(){return 0==--t&&s.off(e,o),i.apply(this,arguments)}return o._origin=i,this._on(e,o,n,r)},r.prototype.emit=function(){if(!this._events&&!this._all)return!1;this._events||h.call(this);var e,t,i,n,r,s,o=arguments[0],a=this.wildcard;if("newListener"===o&&!this._newListener&&!this._events.newListener)return!1;if(a&&"newListener"!==(e=o)&&"removeListener"!==o&&"object"==typeof o){if(i=o.length,T)for(n=0;n<i;n++)if("symbol"==typeof o[n]){s=!0;break}s||(o=o.join(this.delimiter))}var c,l=arguments.length;if(this._all&&this._all.length)for(n=0,i=(c=this._all.slice()).length;n<i;n++)switch(this.event=o,l){case 1:c[n].call(this,o);break;case 2:c[n].call(this,o,arguments[1]);break;case 3:c[n].call(this,o,arguments[1],arguments[2]);break;default:c[n].apply(this,arguments)}if(a)_.call(this,c=[],e,this.listenerTree,0,i);else{if("function"==typeof(c=this._events[o])){switch(this.event=o,l){case 1:c.call(this);break;case 2:c.call(this,arguments[1]);break;case 3:c.call(this,arguments[1],arguments[2]);break;default:for(t=new Array(l-1),r=1;r<l;r++)t[r-1]=arguments[r];c.apply(this,t)}return!0}c=c&&c.slice()}if(c&&c.length){if(3<l)for(t=new Array(l-1),r=1;r<l;r++)t[r-1]=arguments[r];for(n=0,i=c.length;n<i;n++)switch(this.event=o,l){case 1:c[n].call(this);break;case 2:c[n].call(this,arguments[1]);break;case 3:c[n].call(this,arguments[1],arguments[2]);break;default:c[n].apply(this,t)}return!0}if(this.ignoreErrors||this._all||"error"!==o)return!!this._all;throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.")},r.prototype.emitAsync=function(){if(!this._events&&!this._all)return!1;this._events||h.call(this);var e,t,i,n,r,s,o=arguments[0],a=this.wildcard;if("newListener"===o&&!this._newListener&&!this._events.newListener)return Promise.resolve([!1]);if(a&&"newListener"!==(e=o)&&"removeListener"!==o&&"object"==typeof o){if(n=o.length,T)for(r=0;r<n;r++)if("symbol"==typeof o[r]){t=!0;break}t||(o=o.join(this.delimiter))}var c,l=[],u=arguments.length;if(this._all)for(r=0,n=this._all.length;r<n;r++)switch(this.event=o,u){case 1:l.push(this._all[r].call(this,o));break;case 2:l.push(this._all[r].call(this,o,arguments[1]));break;case 3:l.push(this._all[r].call(this,o,arguments[1],arguments[2]));break;default:l.push(this._all[r].apply(this,arguments))}if(a?_.call(this,c=[],e,this.listenerTree,0):c=this._events[o],"function"==typeof c)switch(this.event=o,u){case 1:l.push(c.call(this));break;case 2:l.push(c.call(this,arguments[1]));break;case 3:l.push(c.call(this,arguments[1],arguments[2]));break;default:for(i=new Array(u-1),s=1;s<u;s++)i[s-1]=arguments[s];l.push(c.apply(this,i))}else if(c&&c.length){if(c=c.slice(),3<u)for(i=new Array(u-1),s=1;s<u;s++)i[s-1]=arguments[s];for(r=0,n=c.length;r<n;r++)switch(this.event=o,u){case 1:l.push(c[r].call(this));break;case 2:l.push(c[r].call(this,arguments[1]));break;case 3:l.push(c[r].call(this,arguments[1],arguments[2]));break;default:l.push(c[r].apply(this,i))}}else if(!this.ignoreErrors&&!this._all&&"error"===o)return arguments[1]instanceof Error?Promise.reject(arguments[1]):Promise.reject("Uncaught, unspecified 'error' event.");return Promise.all(l)},r.prototype.on=function(e,t,i){return this._on(e,t,!1,i)},r.prototype.prependListener=function(e,t,i){return this._on(e,t,!0,i)},r.prototype.onAny=function(e){return this._onAny(e,!1)},r.prototype.prependAny=function(e){return this._onAny(e,!0)},r.prototype.addListener=r.prototype.on,r.prototype._onAny=function(e,t){if("function"!=typeof e)throw new Error("onAny only accepts instances of Function");return this._all||(this._all=[]),t?this._all.unshift(e):this._all.push(e),this},r.prototype._on=function(e,t,i,n){if("function"==typeof e)return this._onAny(e,t),this;if("function"!=typeof t)throw new Error("on only accepts instances of Function");this._events||h.call(this);var r=this;return n!==g&&(t=(n=function(e,t,i){if(!0===i)r=!0;else if(!1===i)n=!0;else{if(!i||"object"!=typeof i)throw TypeError("options should be an object or true");var n=i.async,r=i.promisify,s=i.nextTick,o=i.objectify}if(n||s||r){var a=t,i=t._origin||t;if(s&&!x)throw Error("process.nextTick is not supported");r===g&&(r="AsyncFunction"===t.constructor.name),(t=function(){var e=arguments,t=this,i=this.event;return r?s?Promise.resolve():new Promise(function(e){k(e)}).then(function(){return t.event=i,a.apply(t,e)}):(s?M.nextTick:k)(function(){t.event=i,a.apply(t,e)})})._async=!0,t._origin=i}return[t,o?new y(this,e,t):this]}.call(this,e,t,n))[0],r=n[1]),this._newListener&&this.emit("newListener",e,t),this.wildcard?function(e,t,i){var n,r=0,s=0,o=this.delimiter,a=o.length;if("string"==typeof e)if(-1!==(u=e.indexOf(o))){for(n=new Array(5);n[r++]=e.slice(s,u),-1!==(u=e.indexOf(o,s=u+a)););n[r++]=e.slice(s)}else n=[e],r=1;else r=(n=e).length;if(1<r)for(u=0;u+1<r;u++)if("**"===n[u]&&"**"===n[u+1])return;for(var c,l=this.listenerTree,u=0;u<r;u++)if(l=l[c=n[u]]||(l[c]={}),u===r-1)return l._listeners?("function"==typeof l._listeners&&(l._listeners=[l._listeners]),i?l._listeners.unshift(t):l._listeners.push(t),!l._listeners.warned&&0<this._maxListeners&&l._listeners.length>this._maxListeners&&(l._listeners.warned=!0,f.call(this,l._listeners.length,c))):l._listeners=t,!0;return!0}.call(this,e,t,i):this._events[e]?("function"==typeof this._events[e]&&(this._events[e]=[this._events[e]]),i?this._events[e].unshift(t):this._events[e].push(t),!this._events[e].warned&&0<this._maxListeners&&this._events[e].length>this._maxListeners&&(this._events[e].warned=!0,f.call(this,this._events[e].length,e))):this._events[e]=t,r},r.prototype.off=function(e,t){if("function"!=typeof t)throw new Error("removeListener only takes instances of Function");var i=[];if(this.wildcard){var n="string"==typeof e?e.split(this.delimiter):e.slice();if(!(i=_.call(this,null,n,this.listenerTree,0)))return this}else{if(!this._events[e])return this;o=this._events[e],i.push({_listeners:o})}for(var r=0;r<i.length;r++){var s=i[r],o=s._listeners;if(w(o)){for(var a=-1,c=0,l=o.length;c<l;c++)if(o[c]===t||o[c].listener&&o[c].listener===t||o[c]._origin&&o[c]._origin===t){a=c;break}if(!(a<0))return(this.wildcard?s._listeners:this._events[e]).splice(a,1),0===o.length&&(this.wildcard?delete s._listeners:delete this._events[e]),this._removeListener&&this.emit("removeListener",e,t),this}else(o===t||o.listener&&o.listener===t||o._origin&&o._origin===t)&&(this.wildcard?delete s._listeners:delete this._events[e],this._removeListener&&this.emit("removeListener",e,t))}return this.listenerTree&&d(this.listenerTree),this},r.prototype.offAny=function(e){var t,i=0,n=0;if(e&&this._all&&0<this._all.length){for(i=0,n=(t=this._all).length;i<n;i++)if(e===t[i])return t.splice(i,1),this._removeListener&&this.emit("removeListenerAny",e),this}else{if(t=this._all,this._removeListener)for(i=0,n=t.length;i<n;i++)this.emit("removeListenerAny",t[i]);this._all=[]}return this},r.prototype.removeListener=r.prototype.off,r.prototype.removeAllListeners=function(e){if(e===g)return this._events&&h.call(this),this;if(this.wildcard){var t,i=_.call(this,null,e,this.listenerTree,0);if(!i)return this;for(t=0;t<i.length;t++)i[t]._listeners=null;this.listenerTree&&d(this.listenerTree)}else this._events&&(this._events[e]=null);return this},r.prototype.listeners=function(e){var t,i,n,r,s,o=this._events;if(e===g){if(this.wildcard)throw Error("event name required for wildcard emitter");if(!o)return[];for(r=(t=S(o)).length,n=[];0<r--;)"function"==typeof(i=o[t[r]])?n.push(i):n.push.apply(n,i);return n}if(this.wildcard){if(!(s=this.listenerTree))return[];var a=[],c="string"==typeof e?e.split(this.delimiter):e.slice();return _.call(this,a,c,s,0),a}return o&&(i=o[e])?"function"==typeof i?[i]:i:[]},r.prototype.eventNames=function(e){var t=this._events;return this.wildcard?u.call(this,this.listenerTree,[],null,e):t?S(t):[]},r.prototype.listenerCount=function(e){return this.listeners(e).length},r.prototype.hasListeners=function(e){if(this.wildcard)return i=[],t="string"==typeof e?e.split(this.delimiter):e.slice(),_.call(this,i,t,this.listenerTree,0),0<i.length;var t=this._events,i=this._all;return!!(i&&i.length||t&&(e===g?S(t).length:t[e]))},r.prototype.listenersAny=function(){return this._all||[]},r.prototype.waitFor=function(r,s){var o=this,e=typeof s;return"number"==e?s={timeout:s}:"function"==e&&(s={filter:s}),c((s=m(s,{timeout:0,filter:g,handleError:!1,Promise:Promise,overload:!1},{filter:a,Promise:n})).Promise,function(t,i,e){function n(){var e=s.filter;e&&!e.apply(o,arguments)||(o.off(r,n),s.handleError?(e=arguments[0])?i(e):t(l.apply(null,arguments).slice(1)):t(l.apply(null,arguments)))}e(function(){o.off(r,n)}),o._on(r,n,!1)},{timeout:s.timeout,overload:s.overload})},L=r.prototype,Object.defineProperties(r,{defaultMaxListeners:{get:function(){return L._maxListeners},set:function(e){if("number"!=typeof e||e<0||Number.isNaN(e))throw TypeError("n must be a non-negative number");L._maxListeners=e},enumerable:!0},once:{value:function(o,a,e){return c((e=m(e,{Promise:Promise,timeout:0,overload:!1},{Promise:n})).Promise,function(e,t,i){var n;if("function"==typeof o.addEventListener)return n=function(){e(l.apply(null,arguments))},i(function(){o.removeEventListener(a,n)}),void o.addEventListener(a,n,{once:!0});var r,s=function(){r&&o.removeListener("error",r),e(l.apply(null,arguments))};"error"!==a&&(r=function(e){o.removeListener(a,s),t(e)},o.once("error",r)),i(function(){r&&o.removeListener("error",r),o.removeListener(a,s)}),o.once(a,s)},{timeout:e.timeout,overload:e.overload})},writable:!0,configurable:!0}}),Object.defineProperties(L,{_maxListeners:{value:10,writable:!0,configurable:!0},_observers:{value:null,writable:!0,configurable:!0}}),"function"==typeof define&&define.amd?define(function(){return r}):"object"==typeof E?U.exports=r:new Function("","return this")().EventEmitter2=r}.call(this)}.call(this,e("_process"),e("timers").setImmediate)},{_process:4,timers:5}],3:[function(e,t,i){"use strict";var c=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable;t.exports=function(){try{if(!Object.assign)return;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return;for(var t={},i=0;i<10;i++)t["_"+String.fromCharCode(i)]=i;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return;var n={};return"abcdefghijklmnopqrst".split("").forEach(function(e){n[e]=e}),"abcdefghijklmnopqrst"!==Object.keys(Object.assign({},n)).join("")?void 0:1}catch(e){return}}()?Object.assign:function(e,t){for(var i,n=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),r=1;r<arguments.length;r++){for(var s in i=Object(arguments[r]))l.call(i,s)&&(n[s]=i[s]);if(c)for(var o=c(i),a=0;a<o.length;a++)u.call(i,o[a])&&(n[o[a]]=i[o[a]])}return n}},{}],4:[function(e,t,i){var n,r,t=t.exports={};function s(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}try{n="function"==typeof setTimeout?setTimeout:s}catch(e){n=s}try{r="function"==typeof clearTimeout?clearTimeout:o}catch(e){r=o}function a(t){if(n===setTimeout)return setTimeout(t,0);if((n===s||!n)&&setTimeout)return(n=setTimeout)(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}var c,l=[],u=!1,h=-1;function f(){u&&c&&(u=!1,c.length?l=c.concat(l):h=-1,l.length&&p())}function p(){if(!u){for(var e=a(f),t=(u=!0,l.length);t;){for(c=l,l=[];++h<t;)c&&c[h].run();h=-1,t=l.length}c=null,u=!1,!function(t){if(r===clearTimeout)return clearTimeout(t);if((r===o||!r)&&clearTimeout)return(r=clearTimeout)(t);try{r(t)}catch(e){try{return r.call(null,t)}catch(e){return r.call(this,t)}}}(e)}}function m(e,t){this.fun=e,this.array=t}function v(){}t.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var i=1;i<arguments.length;i++)t[i-1]=arguments[i];l.push(new m(e,t)),1!==l.length||u||a(p)},m.prototype.run=function(){this.fun.apply(null,this.array)},t.title="browser",t.browser=!0,t.env={},t.argv=[],t.version="",t.versions={},t.on=v,t.addListener=v,t.once=v,t.off=v,t.removeListener=v,t.removeAllListeners=v,t.emit=v,t.prependListener=v,t.prependOnceListener=v,t.listeners=function(e){return[]},t.binding=function(e){throw new Error("process.binding is not supported")},t.cwd=function(){return"/"},t.chdir=function(e){throw new Error("process.chdir is not supported")},t.umask=function(){return 0}},{}],5:[function(c,e,l){!function(i,a){!function(){var n=c("process/browser.js").nextTick,e=Function.prototype.apply,r=Array.prototype.slice,s={},o=0;function t(e,t){this._id=e,this._clearFn=t}l.setTimeout=function(){return new t(e.call(setTimeout,window,arguments),clearTimeout)},l.setInterval=function(){return new t(e.call(setInterval,window,arguments),clearInterval)},l.clearTimeout=l.clearInterval=function(e){e.close()},t.prototype.unref=t.prototype.ref=function(){},t.prototype.close=function(){this._clearFn.call(window,this._id)},l.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},l.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},l._unrefActive=l.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;0<=t&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},l.setImmediate="function"==typeof i?i:function(e){var t=o++,i=!(arguments.length<2)&&r.call(arguments,1);return s[t]=!0,n(function(){s[t]&&(i?e.apply(null,i):e.call(null),l.clearImmediate(t))}),t},l.clearImmediate="function"==typeof a?a:function(e){delete s[e]}}.call(this)}.call(this,c("timers").setImmediate,c("timers").clearImmediate)},{"process/browser.js":4,timers:5}],6:[function(e,t,i){function s(i){var n={};function r(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return i[e].call(t.exports,t,t.exports,r),t.l=!0,t.exports}r.m=i,r.c=n,r.i=function(e){return e},r.d=function(e,t,i){r.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},r.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/",r.oe=function(e){throw console.error(e),e};var e=r(r.s=ENTRY_MODULE);return e.default||e}var h="[\\.|\\-|\\+|\\w|/|@]+",f="\\(\\s*(/\\*.*?\\*/)?\\s*.*?("+h+").*?\\)";function p(e){return(e+"").replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}function m(e,t,i){var n={},r=(n[i]=[],t.toString()),t=r.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/);if(!t)return n;for(var s,t=t[1],o=new RegExp("(\\\\n|\\W)"+p(t)+f,"g");s=o.exec(r);)"dll-reference"!==s[3]&&n[i].push(s[3]);for(o=new RegExp("\\("+p(t)+'\\("(dll-reference\\s('+h+'))"\\)\\)'+f,"g");s=o.exec(r);)e[s[2]]||(n[i].push(s[1]),e[s[2]]=__webpack_require__(s[1]).m),n[s[2]]=n[s[2]]||[],n[s[2]].push(s[4]);for(var a,c=Object.keys(n),l=0;l<c.length;l++)for(var u=0;u<n[c[l]].length;u++)a=n[c[l]][u],isNaN(+a)||(n[c[l]][u]=+n[c[l]][u]);return n}function o(e,t){for(var i={main:[t]},n={main:[]},r={main:{}};function(i){return Object.keys(i).reduce(function(e,t){return e||0<i[t].length},!1)}(i);)for(var s=Object.keys(i),o=0;o<s.length;o++){var a=s[o],c=i[a].pop();if(r[a]=r[a]||{},!r[a][c]&&e[a][c]){r[a][c]=!0,n[a]=n[a]||[],n[a].push(c);for(var l=m(e,e[a][c],a),u=Object.keys(l),h=0;h<u.length;h++)i[u[h]]=i[u[h]]||[],i[u[h]]=i[u[h]].concat(l[u[h]])}}return n}t.exports=function(e,t){t=t||{};var i={main:__webpack_modules__},n=t.all?{main:Object.keys(i.main)}:o(i,e),r="",e=(Object.keys(n).filter(function(e){return"main"!==e}).forEach(function(t){for(var e=0;n[t][e];)e++;n[t].push(e),i[t][e]="(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })",r=r+"var "+t+" = ("+s.toString().replace("ENTRY_MODULE",JSON.stringify(e))+")({"+n[t].map(function(e){return JSON.stringify(e)+": "+i[t][e].toString()}).join(",")+"});\n"}),r=r+"new (("+s.toString().replace("ENTRY_MODULE",JSON.stringify(e))+")({"+n.main.map(function(e){return JSON.stringify(e)+": "+i.main[e].toString()}).join(",")+"}))(self);",new window.Blob([r],{type:"text/javascript"}));if(t.bare)return e;t=(window.URL||window.webkitURL||window.mozURL||window.msURL).createObjectURL(e),e=new window.Worker(t);return e.objectURL=t,e}},{}],7:[function(e,t,i){var f=arguments[3],p=arguments[4],m=arguments[5],v=JSON.stringify;t.exports=function(e,t){for(var i=Object.keys(m),n=0,r=i.length;n<r;n++){var s=i[n],o=m[s].exports;if(o===e||o&&o.default===e){a=s;break}}if(!a){for(var a=Math.floor(Math.pow(16,8)*Math.random()).toString(16),c={},n=0,r=i.length;n<r;n++)c[s=i[n]]=s;p[a]=["function(require,module,exports){"+e+"(self); }",c]}var l=Math.floor(Math.pow(16,8)*Math.random()).toString(16),u={},h=(u[a]=a,p[l]=["function(require,module,exports){var f = require("+v(a)+");(f.default ? f.default : f)(self);}",u],{});!function e(t){h[t]=!0;for(var i in p[t][1]){i=p[t][1][i];h[i]||e(i)}}(l);u="("+f+")({"+Object.keys(h).map(function(e){return v(e)+":["+p[e][0]+","+v(p[e][1])+"]"}).join(",")+"},{},["+v(l)+"])",l=window.URL||window.webkitURL||window.mozURL||window.msURL,u=new Blob([u],{type:"text/javascript"});if(t&&t.bare)return u;t=l.createObjectURL(u),l=new Worker(t);return l.objectURL=t,l}},{}],8:[function(e,t,i){var n=this.ROSLIB||{REVISION:"1.3.0"},r=e("object-assign");r(n,e("./core")),r(n,e("./actionlib")),r(n,e("./math")),r(n,e("./tf")),r(n,e("./urdf")),t.exports=n},{"./actionlib":14,"./core":23,"./math":28,"./tf":31,"./urdf":43,"object-assign":3}],9:[function(t,e,i){!function(e){!function(){e.ROSLIB=t("./RosLib")}.call(this)}.call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./RosLib":8}],10:[function(e,t,i){var n=e("../core/Topic"),r=e("../core/Message"),e=e("eventemitter2").EventEmitter2;function s(e){var i=this,t=(this.ros=(e=e||{}).ros,this.serverName=e.serverName,this.actionName=e.actionName,this.timeout=e.timeout,this.omitFeedback=e.omitFeedback,this.omitStatus=e.omitStatus,this.omitResult=e.omitResult,!(this.goals={}));this.feedbackListener=new n({ros:this.ros,name:this.serverName+"/feedback",messageType:this.actionName+"Feedback"}),this.statusListener=new n({ros:this.ros,name:this.serverName+"/status",messageType:"actionlib_msgs/GoalStatusArray"}),this.resultListener=new n({ros:this.ros,name:this.serverName+"/result",messageType:this.actionName+"Result"}),this.goalTopic=new n({ros:this.ros,name:this.serverName+"/goal",messageType:this.actionName+"Goal"}),this.cancelTopic=new n({ros:this.ros,name:this.serverName+"/cancel",messageType:"actionlib_msgs/GoalID"}),this.goalTopic.advertise(),this.cancelTopic.advertise(),this.omitStatus||this.statusListener.subscribe(function(e){t=!0,e.status_list.forEach(function(e){var t=i.goals[e.goal_id.id];t&&t.emit("status",e)})}),this.omitFeedback||this.feedbackListener.subscribe(function(e){var t=i.goals[e.status.goal_id.id];t&&(t.emit("status",e.status),t.emit("feedback",e.feedback))}),this.omitResult||this.resultListener.subscribe(function(e){var t=i.goals[e.status.goal_id.id];t&&(t.emit("status",e.status),t.emit("result",e.result))}),this.timeout&&setTimeout(function(){t||i.emit("timeout")},this.timeout)}s.prototype.__proto__=e.prototype,s.prototype.cancel=function(){var e=new r;this.cancelTopic.publish(e)},s.prototype.dispose=function(){this.goalTopic.unadvertise(),this.cancelTopic.unadvertise(),this.omitStatus||this.statusListener.unsubscribe(),this.omitFeedback||this.feedbackListener.unsubscribe(),this.omitResult||this.resultListener.unsubscribe()},t.exports=s},{"../core/Message":15,"../core/Topic":22,eventemitter2:2}],11:[function(e,t,i){var s=e("../core/Topic"),e=(e("../core/Message"),e("eventemitter2").EventEmitter2);function n(e){var t=this,e=(this.ros=(e=e||{}).ros,this.serverName=e.serverName,this.actionName=e.actionName,this.timeout=e.timeout,this.omitFeedback=e.omitFeedback,this.omitStatus=e.omitStatus,this.omitResult=e.omitResult,new s({ros:this.ros,name:this.serverName+"/goal",messageType:this.actionName+"Goal"})),i=new s({ros:this.ros,name:this.serverName+"/feedback",messageType:this.actionName+"Feedback"}),n=new s({ros:this.ros,name:this.serverName+"/status",messageType:"actionlib_msgs/GoalStatusArray"}),r=new s({ros:this.ros,name:this.serverName+"/result",messageType:this.actionName+"Result"});e.subscribe(function(e){t.emit("goal",e)}),n.subscribe(function(e){e.status_list.forEach(function(e){t.emit("status",e)})}),i.subscribe(function(e){t.emit("status",e.status),t.emit("feedback",e.feedback)}),r.subscribe(function(e){t.emit("status",e.status),t.emit("result",e.result)})}n.prototype.__proto__=e.prototype,t.exports=n},{"../core/Message":15,"../core/Topic":22,eventemitter2:2}],12:[function(e,t,i){var n=e("../core/Message"),e=e("eventemitter2").EventEmitter2;function r(e){var t=this,e=(this.actionClient=e.actionClient,this.goalMessage=e.goalMessage,this.isFinished=!1,new Date);this.goalID="goal_"+Math.random()+"_"+e.getTime(),this.goalMessage=new n({goal_id:{stamp:{secs:0,nsecs:0},id:this.goalID},goal:this.goalMessage}),this.on("status",function(e){t.status=e}),this.on("result",function(e){t.isFinished=!0,t.result=e}),this.on("feedback",function(e){t.feedback=e}),this.actionClient.goals[this.goalID]=this}r.prototype.__proto__=e.prototype,r.prototype.send=function(e){var t=this;t.actionClient.goalTopic.publish(t.goalMessage),e&&setTimeout(function(){t.isFinished||t.emit("timeout")},e)},r.prototype.cancel=function(){var e=new n({id:this.goalID});this.actionClient.cancelTopic.publish(e)},t.exports=r},{"../core/Message":15,eventemitter2:2}],13:[function(e,t,i){var s=e("../core/Topic"),o=e("../core/Message"),e=e("eventemitter2").EventEmitter2;function n(e){function t(e,t){return!(e.secs>t.secs)&&(e.secs<t.secs||e.nsecs<t.nsecs)}var i=this,n=(this.ros=(e=e||{}).ros,this.serverName=e.serverName,this.actionName=e.actionName,this.feedbackPublisher=new s({ros:this.ros,name:this.serverName+"/feedback",messageType:this.actionName+"Feedback"}),this.feedbackPublisher.advertise(),new s({ros:this.ros,name:this.serverName+"/status",messageType:"actionlib_msgs/GoalStatusArray"})),e=(n.advertise(),this.resultPublisher=new s({ros:this.ros,name:this.serverName+"/result",messageType:this.actionName+"Result"}),this.resultPublisher.advertise(),new s({ros:this.ros,name:this.serverName+"/goal",messageType:this.actionName+"Goal"})),r=new s({ros:this.ros,name:this.serverName+"/cancel",messageType:"actionlib_msgs/GoalID"});this.statusMessage=new o({header:{stamp:{secs:0,nsecs:100},frame_id:""},status_list:[]}),this.currentGoal=null,this.nextGoal=null,e.subscribe(function(e){i.currentGoal?(i.nextGoal=e,i.emit("cancel")):(i.statusMessage.status_list=[{goal_id:e.goal_id,status:1}],i.currentGoal=e,i.emit("goal",e.goal))}),r.subscribe(function(e){0===e.stamp.secs&&0===e.stamp.secs&&""===e.id?(i.nextGoal=null,i.currentGoal&&i.emit("cancel")):(i.currentGoal&&e.id===i.currentGoal.goal_id.id?i.emit("cancel"):i.nextGoal&&e.id===i.nextGoal.goal_id.id&&(i.nextGoal=null),i.nextGoal&&t(i.nextGoal.goal_id.stamp,e.stamp)&&(i.nextGoal=null),i.currentGoal&&t(i.currentGoal.goal_id.stamp,e.stamp)&&i.emit("cancel"))}),setInterval(function(){var e=new Date,t=Math.floor(e.getTime()/1e3),e=Math.round(1e9*(e.getTime()/1e3-t));i.statusMessage.header.stamp.secs=t,i.statusMessage.header.stamp.nsecs=e,n.publish(i.statusMessage)},500)}n.prototype.__proto__=e.prototype,n.prototype.setSucceeded=function(e){e=new o({status:{goal_id:this.currentGoal.goal_id,status:3},result:e});this.resultPublisher.publish(e),this.statusMessage.status_list=[],this.nextGoal?(this.currentGoal=this.nextGoal,this.nextGoal=null,this.emit("goal",this.currentGoal.goal)):this.currentGoal=null},n.prototype.setAborted=function(e){e=new o({status:{goal_id:this.currentGoal.goal_id,status:4},result:e});this.resultPublisher.publish(e),this.statusMessage.status_list=[],this.nextGoal?(this.currentGoal=this.nextGoal,this.nextGoal=null,this.emit("goal",this.currentGoal.goal)):this.currentGoal=null},n.prototype.sendFeedback=function(e){e=new o({status:{goal_id:this.currentGoal.goal_id,status:1},feedback:e});this.feedbackPublisher.publish(e)},n.prototype.setPreempted=function(){this.statusMessage.status_list=[];var e=new o({status:{goal_id:this.currentGoal.goal_id,status:2}});this.resultPublisher.publish(e),this.nextGoal?(this.currentGoal=this.nextGoal,this.nextGoal=null,this.emit("goal",this.currentGoal.goal)):this.currentGoal=null},t.exports=n},{"../core/Message":15,"../core/Topic":22,eventemitter2:2}],14:[function(e,t,i){var n=e("../core/Ros");e("../mixin")(n,["ActionClient","SimpleActionServer"],t.exports={ActionClient:e("./ActionClient"),ActionListener:e("./ActionListener"),Goal:e("./Goal"),SimpleActionServer:e("./SimpleActionServer")})},{"../core/Ros":17,"../mixin":29,"./ActionClient":10,"./ActionListener":11,"./Goal":12,"./SimpleActionServer":13}],15:[function(e,t,i){var n=e("object-assign");t.exports=function(e){n(this,e)}},{"object-assign":3}],16:[function(e,t,i){var n=e("./Service"),r=e("./ServiceRequest");function s(e){this.ros=(e=e||{}).ros,this.name=e.name}s.prototype.get=function(t){var e=new n({ros:this.ros,name:"/rosapi/get_param",serviceType:"rosapi/GetParam"}),i=new r({name:this.name});e.callService(i,function(e){e=JSON.parse(e.value);t(e)})},s.prototype.set=function(e,t){var i=new n({ros:this.ros,name:"/rosapi/set_param",serviceType:"rosapi/SetParam"}),e=new r({name:this.name,value:JSON.stringify(e)});i.callService(e,t)},s.prototype.delete=function(e){var t=new n({ros:this.ros,name:"/rosapi/delete_param",serviceType:"rosapi/DeleteParam"}),i=new r({name:this.name});t.callService(i,e)},t.exports=s},{"./Service":18,"./ServiceRequest":19}],17:[function(e,t,i){var n=e("ws"),r=e("../util/workerSocket"),s=e("./SocketAdapter.js"),o=e("./Service"),a=e("./ServiceRequest"),c=e("object-assign"),e=e("eventemitter2").EventEmitter2;function l(e){e=e||{};var t=this;this.socket=null,this.idCounter=0,this.isConnected=!1,this.transportLibrary=e.transportLibrary||"websocket",this.transportOptions=e.transportOptions||{},this._sendFunc=function(e){t.sendEncodedMessage(e)},void 0===e.groovyCompatibility?this.groovyCompatibility=!0:this.groovyCompatibility=e.groovyCompatibility,this.setMaxListeners(0),e.url&&this.connect(e.url)}l.prototype.__proto__=e.prototype,l.prototype.connect=function(e){if("socket.io"===this.transportLibrary)this.socket=c(io(e,{"force new connection":!0}),s(this)),this.socket.on("connect",this.socket.onopen),this.socket.on("data",this.socket.onmessage),this.socket.on("close",this.socket.onclose),this.socket.on("error",this.socket.onerror);else if("RTCPeerConnection"===this.transportLibrary.constructor.name)this.socket=c(this.transportLibrary.createDataChannel(e,this.transportOptions),s(this));else if("websocket"===this.transportLibrary){var t;this.socket&&this.socket.readyState!==n.CLOSED||((t=new n(e)).binaryType="arraybuffer",this.socket=c(t,s(this)))}else{if("workersocket"!==this.transportLibrary)throw"Unknown transportLibrary: "+this.transportLibrary.toString();this.socket=c(new r(e),s(this))}},l.prototype.close=function(){this.socket&&this.socket.close()},l.prototype.authenticate=function(e,t,i,n,r,s,o){this.callOnConnection({op:"auth",mac:e,client:t,dest:i,rand:n,t:r,level:s,end:o})},l.prototype.sendEncodedMessage=function(e){var t=null,i=this,t="socket.io"===this.transportLibrary?function(e){i.socket.emit("operation",e)}:function(e){i.socket.send(e)};this.isConnected?t(e):i.once("connection",function(){t(e)})},l.prototype.callOnConnection=function(e){this.transportOptions.encoder?this.transportOptions.encoder(e,this._sendFunc):this._sendFunc(JSON.stringify(e))},l.prototype.setStatusLevel=function(e,t){this.callOnConnection({op:"set_level",level:e,id:t})},l.prototype.getActionServers=function(t,i){var e=new o({ros:this,name:"/rosapi/action_servers",serviceType:"rosapi/GetActionServers"}),n=new a({});"function"==typeof i?e.callService(n,function(e){t(e.action_servers)},function(e){i(e)}):e.callService(n,function(e){t(e.action_servers)})},l.prototype.getTopics=function(t,i){var e=new o({ros:this,name:"/rosapi/topics",serviceType:"rosapi/Topics"}),n=new a;"function"==typeof i?e.callService(n,function(e){t(e)},function(e){i(e)}):e.callService(n,function(e){t(e)})},l.prototype.getTopicsForType=function(e,t,i){var n=new o({ros:this,name:"/rosapi/topics_for_type",serviceType:"rosapi/TopicsForType"}),e=new a({type:e});"function"==typeof i?n.callService(e,function(e){t(e.topics)},function(e){i(e)}):n.callService(e,function(e){t(e.topics)})},l.prototype.getServices=function(t,i){var e=new o({ros:this,name:"/rosapi/services",serviceType:"rosapi/Services"}),n=new a;"function"==typeof i?e.callService(n,function(e){t(e.services)},function(e){i(e)}):e.callService(n,function(e){t(e.services)})},l.prototype.getServicesForType=function(e,t,i){var n=new o({ros:this,name:"/rosapi/services_for_type",serviceType:"rosapi/ServicesForType"}),e=new a({type:e});"function"==typeof i?n.callService(e,function(e){t(e.services)},function(e){i(e)}):n.callService(e,function(e){t(e.services)})},l.prototype.getServiceRequestDetails=function(e,t,i){var n=new o({ros:this,name:"/rosapi/service_request_details",serviceType:"rosapi/ServiceRequestDetails"}),e=new a({type:e});"function"==typeof i?n.callService(e,function(e){t(e)},function(e){i(e)}):n.callService(e,function(e){t(e)})},l.prototype.getServiceResponseDetails=function(e,t,i){var n=new o({ros:this,name:"/rosapi/service_response_details",serviceType:"rosapi/ServiceResponseDetails"}),e=new a({type:e});"function"==typeof i?n.callService(e,function(e){t(e)},function(e){i(e)}):n.callService(e,function(e){t(e)})},l.prototype.getNodes=function(t,i){var e=new o({ros:this,name:"/rosapi/nodes",serviceType:"rosapi/Nodes"}),n=new a;"function"==typeof i?e.callService(n,function(e){t(e.nodes)},function(e){i(e)}):e.callService(n,function(e){t(e.nodes)})},l.prototype.getNodeDetails=function(e,t,i){var n=new o({ros:this,name:"/rosapi/node_details",serviceType:"rosapi/NodeDetails"}),e=new a({node:e});"function"==typeof i?n.callService(e,function(e){t(e.subscribing,e.publishing,e.services)},function(e){i(e)}):n.callService(e,function(e){t(e)})},l.prototype.getParams=function(t,i){var e=new o({ros:this,name:"/rosapi/get_param_names",serviceType:"rosapi/GetParamNames"}),n=new a;"function"==typeof i?e.callService(n,function(e){t(e.names)},function(e){i(e)}):e.callService(n,function(e){t(e.names)})},l.prototype.getTopicType=function(e,t,i){var n=new o({ros:this,name:"/rosapi/topic_type",serviceType:"rosapi/TopicType"}),e=new a({topic:e});"function"==typeof i?n.callService(e,function(e){t(e.type)},function(e){i(e)}):n.callService(e,function(e){t(e.type)})},l.prototype.getServiceType=function(e,t,i){var n=new o({ros:this,name:"/rosapi/service_type",serviceType:"rosapi/ServiceType"}),e=new a({service:e});"function"==typeof i?n.callService(e,function(e){t(e.type)},function(e){i(e)}):n.callService(e,function(e){t(e.type)})},l.prototype.getMessageDetails=function(e,t,i){var n=new o({ros:this,name:"/rosapi/message_details",serviceType:"rosapi/MessageDetails"}),e=new a({type:e});"function"==typeof i?n.callService(e,function(e){t(e.typedefs)},function(e){i(e)}):n.callService(e,function(e){t(e.typedefs)})},l.prototype.decodeTypeDefs=function(e){function u(e,t){for(var i={},n=0;n<e.fieldnames.length;n++){var r=e.fieldarraylen[n],s=e.fieldnames[n],o=e.fieldtypes[n];if(-1===o.indexOf("/"))i[s]=-1===r?o:[o];else{for(var a,c=!1,l=0;l<t.length;l++)if(t[l].type.toString()===o.toString()){c=t[l];break}c?(a=u(c,t),-1!==r&&(i[s]=[a])):h.emit("error","Cannot find "+o+" in decodeTypeDefs")}}return i}var h=this;return u(e[0],e)},l.prototype.getTopicsAndRawTypes=function(t,i){var e=new o({ros:this,name:"/rosapi/topics_and_raw_types",serviceType:"rosapi/TopicsAndRawTypes"}),n=new a;"function"==typeof i?e.callService(n,function(e){t(e)},function(e){i(e)}):e.callService(n,function(e){t(e)})},t.exports=l},{"../util/workerSocket":49,"./Service":18,"./ServiceRequest":19,"./SocketAdapter.js":21,eventemitter2:2,"object-assign":3,ws:46}],18:[function(e,t,i){var r=e("./ServiceResponse"),e=(e("./ServiceRequest"),e("eventemitter2").EventEmitter2);function n(e){this.ros=(e=e||{}).ros,this.name=e.name,this.serviceType=e.serviceType,this.isAdvertised=!1,this._serviceCallback=null}n.prototype.__proto__=e.prototype,n.prototype.callService=function(e,t,i){var n;this.isAdvertised||(n="call_service:"+this.name+":"+ ++this.ros.idCounter,(t||i)&&this.ros.once(n,function(e){void 0!==e.result&&!1===e.result?"function"==typeof i&&i(e.values):"function"==typeof t&&t(new r(e.values))}),n={op:"call_service",id:n,service:this.name,type:this.serviceType,args:e},this.ros.callOnConnection(n))},n.prototype.advertise=function(e){this.isAdvertised||"function"!=typeof e||(this._serviceCallback=e,this.ros.on(this.name,this._serviceResponse.bind(this)),this.ros.callOnConnection({op:"advertise_service",type:this.serviceType,service:this.name}),this.isAdvertised=!0)},n.prototype.unadvertise=function(){this.isAdvertised&&(this.ros.callOnConnection({op:"unadvertise_service",service:this.name}),this.isAdvertised=!1)},n.prototype._serviceResponse=function(e){var t={},i=this._serviceCallback(e.args,t),t={op:"service_response",service:this.name,values:new r(t),result:i};e.id&&(t.id=e.id),this.ros.callOnConnection(t)},t.exports=n},{"./ServiceRequest":19,"./ServiceResponse":20,eventemitter2:2}],19:[function(e,t,i){var n=e("object-assign");t.exports=function(e){n(this,e)}},{"object-assign":3}],20:[function(e,t,i){var n=e("object-assign");t.exports=function(e){n(this,e)}},{"object-assign":3}],21:[function(e,t,i){"use strict";var n=e("../util/decompressPng"),a=e("cbor-js"),c=e("../util/cborTypedArrayTags"),l=null;"undefined"!=typeof bson&&(l=bson().BSON),t.exports=function(t){var r=null;function s(e){"publish"===e.op?t.emit(e.topic,e.msg):"service_response"===e.op?t.emit(e.id,e):"call_service"===e.op?t.emit(e.service,e):"status"===e.op&&(e.id?t.emit("status:"+e.id,e):t.emit("status",e))}function o(e,t){"png"===e.op?n(e.data,t):t(e)}return t.transportOptions.decoder&&(r=t.transportOptions.decoder),{onopen:function(e){t.isConnected=!0,t.emit("connection",e)},onclose:function(e){t.isConnected=!1,t.emit("close",e)},onerror:function(e){t.emit("error",e)},onmessage:function(e){if(r)r(e.data,function(e){s(e)});else if("undefined"!=typeof Blob&&e.data instanceof Blob){var t=e.data,i=function(e){o(e,s)};if(!l)throw"Cannot process BSON encoded message without BSON header.";var n=new FileReader;n.onload=function(){var e=new Uint8Array(this.result),e=l.deserialize(e);i(e)},n.readAsArrayBuffer(t)}else e.data instanceof ArrayBuffer?s(a.decode(e.data,c)):o(JSON.parse("string"==typeof e?e:e.data),s)}}}},{"../util/cborTypedArrayTags":44,"../util/decompressPng":48,"cbor-js":1}],22:[function(e,t,i){var n=e("eventemitter2").EventEmitter2,r=e("./Message");function s(e){this.ros=(e=e||{}).ros,this.name=e.name,this.messageType=e.messageType,this.isAdvertised=!1,this.compression=e.compression||"none",this.throttle_rate=e.throttle_rate||0,this.latch=e.latch||!1,this.queue_size=e.queue_size||100,this.queue_length=e.queue_length||0,this.reconnect_on_close=void 0===e.reconnect_on_close||e.reconnect_on_close,this.compression&&"png"!==this.compression&&"cbor"!==this.compression&&"cbor-raw"!==this.compression&&"none"!==this.compression&&(this.emit("warning",this.compression+" compression is not supported. No compression will be used."),this.compression="none"),this.throttle_rate<0&&(this.emit("warning",this.throttle_rate+" is not allowed. Set to 0"),this.throttle_rate=0);var t=this;this.reconnect_on_close?this.callForSubscribeAndAdvertise=function(e){t.ros.callOnConnection(e),t.waitForReconnect=!1,t.reconnectFunc=function(){t.waitForReconnect||(t.waitForReconnect=!0,t.ros.callOnConnection(e),t.ros.once("connection",function(){t.waitForReconnect=!1}))},t.ros.on("close",t.reconnectFunc)}:this.callForSubscribeAndAdvertise=this.ros.callOnConnection,this._messageCallback=function(e){t.emit("message",new r(e))}}s.prototype.__proto__=n.prototype,s.prototype.subscribe=function(e){"function"==typeof e&&this.on("message",e),this.subscribeId||(this.ros.on(this.name,this._messageCallback),this.subscribeId="subscribe:"+this.name+":"+ ++this.ros.idCounter,this.callForSubscribeAndAdvertise({op:"subscribe",id:this.subscribeId,type:this.messageType,topic:this.name,compression:this.compression,throttle_rate:this.throttle_rate,queue_length:this.queue_length}))},s.prototype.unsubscribe=function(e){e&&(this.off("message",e),this.listeners("message").length)||this.subscribeId&&(this.ros.off(this.name,this._messageCallback),this.reconnect_on_close&&this.ros.off("close",this.reconnectFunc),this.emit("unsubscribe"),this.ros.callOnConnection({op:"unsubscribe",id:this.subscribeId,topic:this.name}),this.subscribeId=null)},s.prototype.advertise=function(){var e;this.isAdvertised||(this.advertiseId="advertise:"+this.name+":"+ ++this.ros.idCounter,this.callForSubscribeAndAdvertise({op:"advertise",id:this.advertiseId,type:this.messageType,topic:this.name,latch:this.latch,queue_size:this.queue_size}),this.isAdvertised=!0,this.reconnect_on_close||(e=this).ros.on("close",function(){e.isAdvertised=!1}))},s.prototype.unadvertise=function(){this.isAdvertised&&(this.reconnect_on_close&&this.ros.off("close",this.reconnectFunc),this.emit("unadvertise"),this.ros.callOnConnection({op:"unadvertise",id:this.advertiseId,topic:this.name}),this.isAdvertised=!1)},s.prototype.publish=function(e){this.isAdvertised||this.advertise(),this.ros.idCounter++;e={op:"publish",id:"publish:"+this.name+":"+this.ros.idCounter,topic:this.name,msg:e,latch:this.latch};this.ros.callOnConnection(e)},t.exports=s},{"./Message":15,eventemitter2:2}],23:[function(e,t,i){var n=e("../mixin"),t=t.exports={Ros:e("./Ros"),Topic:e("./Topic"),Message:e("./Message"),Param:e("./Param"),Service:e("./Service"),ServiceRequest:e("./ServiceRequest"),ServiceResponse:e("./ServiceResponse")};n(t.Ros,["Param","Service","Topic"],t)},{"../mixin":29,"./Message":15,"./Param":16,"./Ros":17,"./Service":18,"./ServiceRequest":19,"./ServiceResponse":20,"./Topic":22}],24:[function(e,t,i){var n=e("./Vector3"),r=e("./Quaternion");function s(e){this.position=new n((e=e||{}).position),this.orientation=new r(e.orientation)}s.prototype.applyTransform=function(e){this.position.multiplyQuaternion(e.rotation),this.position.add(e.translation);e=e.rotation.clone();e.multiply(this.orientation),this.orientation=e},s.prototype.clone=function(){return new s(this)},s.prototype.multiply=function(e){e=e.clone();return e.applyTransform({rotation:this.orientation,translation:this.position}),e},s.prototype.getInverse=function(){var e=this.clone();return e.orientation.invert(),e.position.multiplyQuaternion(e.orientation),e.position.x*=-1,e.position.y*=-1,e.position.z*=-1,e},t.exports=s},{"./Quaternion":25,"./Vector3":27}],25:[function(e,t,i){function n(e){this.x=(e=e||{}).x||0,this.y=e.y||0,this.z=e.z||0,this.w="number"==typeof e.w?e.w:1}n.prototype.conjugate=function(){this.x*=-1,this.y*=-1,this.z*=-1},n.prototype.norm=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},n.prototype.normalize=function(){var e=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);0===e?(this.x=0,this.y=0,this.z=0,this.w=1):(this.x=this.x*(e=1/e),this.y=this.y*e,this.z=this.z*e,this.w=this.w*e)},n.prototype.invert=function(){this.conjugate(),this.normalize()},n.prototype.multiply=function(e){var t=this.x*e.w+this.y*e.z-this.z*e.y+this.w*e.x,i=-this.x*e.z+this.y*e.w+this.z*e.x+this.w*e.y,n=this.x*e.y-this.y*e.x+this.z*e.w+this.w*e.z,e=-this.x*e.x-this.y*e.y-this.z*e.z+this.w*e.w;this.x=t,this.y=i,this.z=n,this.w=e},n.prototype.clone=function(){return new n(this)},t.exports=n},{}],26:[function(e,t,i){var n=e("./Vector3"),r=e("./Quaternion");function s(e){this.translation=new n((e=e||{}).translation),this.rotation=new r(e.rotation)}s.prototype.clone=function(){return new s(this)},t.exports=s},{"./Quaternion":25,"./Vector3":27}],27:[function(e,t,i){function n(e){this.x=(e=e||{}).x||0,this.y=e.y||0,this.z=e.z||0}n.prototype.add=function(e){this.x+=e.x,this.y+=e.y,this.z+=e.z},n.prototype.subtract=function(e){this.x-=e.x,this.y-=e.y,this.z-=e.z},n.prototype.multiplyQuaternion=function(e){var t=e.w*this.x+e.y*this.z-e.z*this.y,i=e.w*this.y+e.z*this.x-e.x*this.z,n=e.w*this.z+e.x*this.y-e.y*this.x,r=-e.x*this.x-e.y*this.y-e.z*this.z;this.x=t*e.w+r*-e.x+i*-e.z-n*-e.y,this.y=i*e.w+r*-e.y+n*-e.x-t*-e.z,this.z=n*e.w+r*-e.z+t*-e.y-i*-e.x},n.prototype.clone=function(){return new n(this)},t.exports=n},{}],28:[function(e,t,i){t.exports={Pose:e("./Pose"),Quaternion:e("./Quaternion"),Transform:e("./Transform"),Vector3:e("./Vector3")}},{"./Pose":24,"./Quaternion":25,"./Transform":26,"./Vector3":27}],29:[function(e,t,i){t.exports=function(i,e,n){e.forEach(function(e){var t=n[e];i.prototype[e]=function(e){return e.ros=this,new t(e)}})}},{}],30:[function(e,t,i){var n=e("../actionlib/ActionClient"),r=e("../actionlib/Goal"),s=e("../core/Service.js"),o=e("../core/ServiceRequest.js"),a=e("../core/Topic.js"),c=e("../math/Transform");function l(e){this.ros=(e=e||{}).ros,this.fixedFrame=e.fixedFrame||"/base_link",this.angularThres=e.angularThres||2,this.transThres=e.transThres||.01,this.rate=e.rate||10,this.updateDelay=e.updateDelay||50;var t=e.topicTimeout||2,i=Math.floor(t),t=Math.floor(1e9*(t-i));this.topicTimeout={secs:i,nsecs:t},this.serverName=e.serverName||"/tf2_web_republisher",this.repubServiceName=e.repubServiceName||"/republish_tfs",this.currentGoal=!1,this.currentTopic=!1,this.frameInfos={},this.republisherUpdateRequested=!1,this._subscribeCB=null,this._isDisposed=!1,this.actionClient=new n({ros:e.ros,serverName:this.serverName,actionName:"tf2_web_republisher/TFSubscriptionAction",omitStatus:!0,omitResult:!0}),this.serviceClient=new s({ros:e.ros,name:this.repubServiceName,serviceType:"tf2_web_republisher/RepublishTFs"})}l.prototype.processTFArray=function(e){e.transforms.forEach(function(e){var t=e.child_frame_id,i=("/"===t[0]&&(t=t.substring(1)),this.frameInfos[t]);i&&(i.transform=new c({translation:e.transform.translation,rotation:e.transform.rotation}),i.cbs.forEach(function(e){e(i.transform)}))},this)},l.prototype.updateGoal=function(){var e={source_frames:Object.keys(this.frameInfos),target_frame:this.fixedFrame,angular_thres:this.angularThres,trans_thres:this.transThres,rate:this.rate};this.ros.groovyCompatibility?(this.currentGoal&&this.currentGoal.cancel(),this.currentGoal=new r({actionClient:this.actionClient,goalMessage:e}),this.currentGoal.on("feedback",this.processTFArray.bind(this)),this.currentGoal.send()):(e.timeout=this.topicTimeout,e=new o(e),this.serviceClient.callService(e,this.processResponse.bind(this))),this.republisherUpdateRequested=!1},l.prototype.processResponse=function(e){this._isDisposed||(this.currentTopic&&this.currentTopic.unsubscribe(this._subscribeCB),this.currentTopic=new a({ros:this.ros,name:e.topic_name,messageType:"tf2_web_republisher/TFArray"}),this._subscribeCB=this.processTFArray.bind(this),this.currentTopic.subscribe(this._subscribeCB))},l.prototype.subscribe=function(e,t){"/"===e[0]&&(e=e.substring(1)),this.frameInfos[e]?this.frameInfos[e].transform&&t(this.frameInfos[e].transform):(this.frameInfos[e]={cbs:[]},this.republisherUpdateRequested||(setTimeout(this.updateGoal.bind(this),this.updateDelay),this.republisherUpdateRequested=!0)),this.frameInfos[e].cbs.push(t)},l.prototype.unsubscribe=function(e,t){"/"===e[0]&&(e=e.substring(1));for(var i=this.frameInfos[e],n=i&&i.cbs||[],r=n.length;r--;)n[r]===t&&n.splice(r,1);t&&0!==n.length||delete this.frameInfos[e]},l.prototype.dispose=function(){this._isDisposed=!0,this.actionClient.dispose(),this.currentTopic&&this.currentTopic.unsubscribe(this._subscribeCB)},t.exports=l},{"../actionlib/ActionClient":10,"../actionlib/Goal":12,"../core/Service.js":18,"../core/ServiceRequest.js":19,"../core/Topic.js":22,"../math/Transform":26}],31:[function(e,t,i){var n=e("../core/Ros");e("../mixin")(n,["TFClient"],t.exports={TFClient:e("./TFClient")})},{"../core/Ros":17,"../mixin":29,"./TFClient":30}],32:[function(e,t,i){var n=e("../math/Vector3"),r=e("./UrdfTypes");t.exports=function(e){this.dimension=null,this.type=r.URDF_BOX,e=e.xml.getAttribute("size").split(" "),this.dimension=new n({x:parseFloat(e[0]),y:parseFloat(e[1]),z:parseFloat(e[2])})}},{"../math/Vector3":27,"./UrdfTypes":41}],33:[function(e,t,i){t.exports=function(e){e=e.xml.getAttribute("rgba").split(" "),this.r=parseFloat(e[0]),this.g=parseFloat(e[1]),this.b=parseFloat(e[2]),this.a=parseFloat(e[3])}},{}],34:[function(e,t,i){var n=e("./UrdfTypes");t.exports=function(e){this.type=n.URDF_CYLINDER,this.length=parseFloat(e.xml.getAttribute("length")),this.radius=parseFloat(e.xml.getAttribute("radius"))}},{"./UrdfTypes":41}],35:[function(e,t,i){var c=e("../math/Pose"),l=e("../math/Vector3"),u=e("../math/Quaternion");t.exports=function(e){this.name=e.xml.getAttribute("name"),this.type=e.xml.getAttribute("type");var t,i,n,r,s,o,a=e.xml.getElementsByTagName("parent");0<a.length&&(this.parent=a[0].getAttribute("link")),0<(a=e.xml.getElementsByTagName("child")).length&&(this.child=a[0].getAttribute("link")),0<(a=e.xml.getElementsByTagName("limit")).length&&(this.minval=parseFloat(a[0].getAttribute("lower")),this.maxval=parseFloat(a[0].getAttribute("upper"))),0===(a=e.xml.getElementsByTagName("origin")).length?this.origin=new c:(e=a[0].getAttribute("xyz"),t=new l,e&&(e=e.split(" "),t=new l({x:parseFloat(e[0]),y:parseFloat(e[1]),z:parseFloat(e[2])})),e=a[0].getAttribute("rpy"),a=new u,e&&(e=e.split(" "),o=parseFloat(e[0])/2,i=parseFloat(e[1])/2,e=parseFloat(e[2])/2,n=Math.sin(o)*Math.cos(i)*Math.cos(e)-Math.cos(o)*Math.sin(i)*Math.sin(e),r=Math.cos(o)*Math.sin(i)*Math.cos(e)+Math.sin(o)*Math.cos(i)*Math.sin(e),s=Math.cos(o)*Math.cos(i)*Math.sin(e)-Math.sin(o)*Math.sin(i)*Math.cos(e),o=Math.cos(o)*Math.cos(i)*Math.cos(e)+Math.sin(o)*Math.sin(i)*Math.sin(e),(a=new u({x:n,y:r,z:s,w:o})).normalize()),this.origin=new c({position:t,orientation:a}))}},{"../math/Pose":24,"../math/Quaternion":25,"../math/Vector3":27}],36:[function(e,t,i){var n=e("./UrdfVisual");t.exports=function(e){this.name=e.xml.getAttribute("name"),this.visuals=[];for(var t=e.xml.getElementsByTagName("visual"),i=0;i<t.length;i++)this.visuals.push(new n({xml:t[i]}))}},{"./UrdfVisual":42}],37:[function(e,t,i){var n=e("./UrdfColor");function r(e){this.textureFilename=null,this.color=null,this.name=e.xml.getAttribute("name");var t=e.xml.getElementsByTagName("texture"),t=(0<t.length&&(this.textureFilename=t[0].getAttribute("filename")),e.xml.getElementsByTagName("color"));0<t.length&&(this.color=new n({xml:t[0]}))}r.prototype.isLink=function(){return null===this.color&&null===this.textureFilename};var s=e("object-assign");r.prototype.assign=function(e){return s(this,e)},t.exports=r},{"./UrdfColor":33,"object-assign":3}],38:[function(e,t,i){var n=e("../math/Vector3"),r=e("./UrdfTypes");t.exports=function(e){this.scale=null,this.type=r.URDF_MESH,this.filename=e.xml.getAttribute("filename"),(e=e.xml.getAttribute("scale"))&&(e=e.split(" "),this.scale=new n({x:parseFloat(e[0]),y:parseFloat(e[1]),z:parseFloat(e[2])}))}},{"../math/Vector3":27,"./UrdfTypes":41}],39:[function(e,t,i){var l=e("./UrdfMaterial"),u=e("./UrdfLink"),h=e("./UrdfJoint"),f=e("@xmldom/xmldom").DOMParser;t.exports=function(e){var t=(e=e||{}).xml,e=e.string,e=(this.materials={},this.links={},this.joints={},(t=e?(new f).parseFromString(e,"text/xml"):t).documentElement);this.name=e.getAttribute("name");for(var i=e.childNodes,n=0;n<i.length;n++){var r=i[n];if("material"===r.tagName){var s=new l({xml:r});void 0!==this.materials[s.name]?this.materials[s.name].isLink()?this.materials[s.name].assign(s):console.warn("Material "+s.name+"is not unique."):this.materials[s.name]=s}else if("link"===r.tagName){var o=new u({xml:r});if(void 0!==this.links[o.name])console.warn("Link "+o.name+" is not unique.");else{for(var a=0;a<o.visuals.length;a++){var c=o.visuals[a].material;null!==c&&c.name&&(void 0!==this.materials[c.name]?o.visuals[a].material=this.materials[c.name]:this.materials[c.name]=c)}this.links[o.name]=o}}else"joint"===r.tagName&&(s=new h({xml:r}),this.joints[s.name]=s)}}},{"./UrdfJoint":35,"./UrdfLink":36,"./UrdfMaterial":37,"@xmldom/xmldom":45}],40:[function(e,t,i){var n=e("./UrdfTypes");t.exports=function(e){this.type=n.URDF_SPHERE,this.radius=parseFloat(e.xml.getAttribute("radius"))}},{"./UrdfTypes":41}],41:[function(e,t,i){t.exports={URDF_SPHERE:0,URDF_BOX:1,URDF_CYLINDER:2,URDF_MESH:3}},{}],42:[function(e,t,i){var p=e("../math/Pose"),m=e("../math/Vector3"),v=e("../math/Quaternion"),d=e("./UrdfCylinder"),y=e("./UrdfBox"),g=e("./UrdfMaterial"),b=e("./UrdfMesh"),w=e("./UrdfSphere");t.exports=function(e){var t,i,n,r,s=e.xml;this.origin=null,this.geometry=null,this.material=null,this.name=e.xml.getAttribute("name");0===(e=s.getElementsByTagName("origin")).length?this.origin=new p:(h=e[0].getAttribute("xyz"),t=new m,h&&(h=h.split(" "),t=new m({x:parseFloat(h[0]),y:parseFloat(h[1]),z:parseFloat(h[2])})),h=e[0].getAttribute("rpy"),e=new v,h&&(h=h.split(" "),r=parseFloat(h[0])/2,o=parseFloat(h[1])/2,h=parseFloat(h[2])/2,f=Math.sin(r)*Math.cos(o)*Math.cos(h)-Math.cos(r)*Math.sin(o)*Math.sin(h),i=Math.cos(r)*Math.sin(o)*Math.cos(h)+Math.sin(r)*Math.cos(o)*Math.sin(h),n=Math.cos(r)*Math.cos(o)*Math.sin(h)-Math.sin(r)*Math.sin(o)*Math.cos(h),r=Math.cos(r)*Math.cos(o)*Math.cos(h)+Math.sin(r)*Math.sin(o)*Math.sin(h),(e=new v({x:f,y:i,z:n,w:r})).normalize()),this.origin=new p({position:t,orientation:e}));var o=s.getElementsByTagName("geometry");if(0<o.length){for(var a=o[0],c=null,l=0;l<a.childNodes.length;l++){var u=a.childNodes[l];if(1===u.nodeType){c=u;break}}var h=c.nodeName;"sphere"===h?this.geometry=new w({xml:c}):"box"===h?this.geometry=new y({xml:c}):"cylinder"===h?this.geometry=new d({xml:c}):"mesh"===h?this.geometry=new b({xml:c}):console.warn("Unknown geometry type "+h)}var f=s.getElementsByTagName("material");0<f.length&&(this.material=new g({xml:f[0]}))}},{"../math/Pose":24,"../math/Quaternion":25,"../math/Vector3":27,"./UrdfBox":32,"./UrdfCylinder":34,"./UrdfMaterial":37,"./UrdfMesh":38,"./UrdfSphere":40}],43:[function(e,t,i){t.exports=e("object-assign")({UrdfBox:e("./UrdfBox"),UrdfColor:e("./UrdfColor"),UrdfCylinder:e("./UrdfCylinder"),UrdfLink:e("./UrdfLink"),UrdfMaterial:e("./UrdfMaterial"),UrdfMesh:e("./UrdfMesh"),UrdfModel:e("./UrdfModel"),UrdfSphere:e("./UrdfSphere"),UrdfVisual:e("./UrdfVisual")},e("./UrdfTypes"))},{"./UrdfBox":32,"./UrdfColor":33,"./UrdfCylinder":34,"./UrdfLink":36,"./UrdfMaterial":37,"./UrdfMesh":38,"./UrdfModel":39,"./UrdfSphere":40,"./UrdfTypes":41,"./UrdfVisual":42,"object-assign":3}],44:[function(e,t,i){"use strict";var u=Math.pow(2,32),n=!1;function h(){n||(n=!0,console.warn("CBOR 64-bit integer array values may lose precision. No further warnings."))}var r={64:Uint8Array,69:Uint16Array,70:Uint32Array,72:Int8Array,77:Int16Array,78:Int32Array,85:Float32Array,86:Float64Array},s={71:function(e){h();for(var t=e.byteLength,i=e.byteOffset,n=t/8,e=e.buffer.slice(i,i+t),r=new Uint32Array(e),s=new Array(n),o=0;o<n;o++){var a=2*o,c=r[a],a=r[1+a];s[o]=c+u*a}return s},79:function(e){h();for(var t=e.byteLength,i=e.byteOffset,n=t/8,e=e.buffer.slice(i,i+t),r=new Uint32Array(e),s=new Int32Array(e),o=new Array(n),a=0;a<n;a++){var c=2*a,l=r[c],c=s[1+c];o[a]=l+u*c}return o}};void 0!==t&&t.exports&&(t.exports=function(e,t){var i,n;return t in r?(i=e.byteLength,n=e.byteOffset,new r[t](e.buffer.slice(n,n+i))):t in s?s[t](e):e})},{}],45:[function(e,t,i){i.DOMImplementation=window.DOMImplementation,i.XMLSerializer=window.XMLSerializer,i.DOMParser=window.DOMParser},{}],46:[function(e,t,i){t.exports="undefined"!=typeof window?window.WebSocket:WebSocket},{}],47:[function(e,t,i){t.exports=function(){return document.createElement("canvas")}},{}],48:[function(e,t,i){"use strict";var a=e("canvas"),n=a.Image||window.Image;t.exports=function(e,s){var o=new n;o.onload=function(){for(var e=new a,t=e.getContext("2d"),i=(e.width=o.width,e.height=o.height,t.imageSmoothingEnabled=!1,t.webkitImageSmoothingEnabled=!1,t.mozImageSmoothingEnabled=!1,t.drawImage(o,0,0),t.getImageData(0,0,o.width,o.height).data),n="",r=0;r<i.length;r+=4)n+=String.fromCharCode(i[r],i[r+1],i[r+2]);s(JSON.parse(n))},o.src="data:image/png;base64,"+e}},{canvas:47}],49:[function(t,e,i){try{var n=t("webworkify")}catch(e){n=t("webworkify-webpack")}var r=t("./workerSocketImpl");function s(e){this.socket_=n(r),this.socket_.addEventListener("message",this.handleWorkerMessage_.bind(this)),this.socket_.postMessage({uri:e})}s.prototype.handleWorkerMessage_=function(e){var t=e.data;if(t instanceof ArrayBuffer||"string"==typeof t)this.onmessage(e);else{e=t.type;if("close"===e)this.onclose(null);else if("open"===e)this.onopen(null);else{if("error"!==e)throw"Unknown message from workersocket";this.onerror(null)}}},s.prototype.send=function(e){this.socket_.postMessage(e)},s.prototype.close=function(){this.socket_.postMessage({close:!0})},e.exports=s},{"./workerSocketImpl":50,webworkify:7,"webworkify-webpack":6}],50:[function(e,t,i){var s=e("ws");t.exports=function(t){var i=null;function n(e){e=e.data;e instanceof ArrayBuffer?t.postMessage(e,[e]):t.postMessage(e)}function r(e){t.postMessage({type:e.type})}t.addEventListener("message",function(e){e=e.data;if("string"==typeof e)i.send(e);else if(e.hasOwnProperty("close"))i.close(),i=null;else{if(!e.hasOwnProperty("uri"))throw"Unknown message to WorkerSocket";e=e.uri;(i=new s(e)).binaryType="arraybuffer",i.onmessage=n,i.onclose=r,i.onopen=r,i.onerror=r}})}},{ws:46}]},{},[9]); \ No newline at end of file diff --git a/src/server/src/main/resources/test.html b/src/server/src/main/resources/test.html new file mode 100644 index 0000000..e6c4170 --- /dev/null +++ b/src/server/src/main/resources/test.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8" /> + +<script type="text/javascript" src="./em.js"></script> +<script type="text/javascript" src="./roslib.min.js"></script> + +<script type="text/javascript" type="text/javascript"> + // Connecting to ROS + // ----------------- + + var ros = new ROSLIB.Ros({ + url : 'ws://192.168.43.20:9090' + }); + + ros.on('connection', function() { + console.log('Connected to websocket server.'); + }); + + ros.on('error', function(error) { + console.log('Error connecting to websocket server: ', error); + }); + + ros.on('close', function() { + console.log('Connection to websocket server closed.'); + }); + + // Publishing a Topic + // ------------------ + + var cmdVel = new ROSLIB.Topic({ + ros : ros, + name : '/cmd_vel', + messageType : 'geometry_msgs/Twist' + }); + + var twist = new ROSLIB.Message({ + linear : { + x : 0.1, + y : 0.2, + z : 0.3 + }, + angular : { + x : -0.1, + y : -0.2, + z : -0.3 + } + }); + cmdVel.publish(twist); + +</script> +</head> + +<body> + <h1>Simple roslib Example</h1> + <p>Check your Web Console for output.</p> +</body> +</html> diff --git a/src/server/src/main/resources/test.js b/src/server/src/main/resources/test.js new file mode 100644 index 0000000..0bf1978 --- /dev/null +++ b/src/server/src/main/resources/test.js @@ -0,0 +1,97 @@ + + // document.write('<script type="text/javascript" src="http://cdn.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>\n'); + // document.write('<script type="text/javascript" src="http://cdn.robotwebtools.org/roslibjs/current/roslib.min.js"></script>\n'); + + var ros = new ROSLIB.Ros({ + url : 'ws://192.168.43.20:9090' +}); + + ros.on('connection', function() { + console.log('Connected to websocket server.'); +}); + + ros.on('error', function(error) { + console.log('Error connecting to websocket server: ', error); +}); + + ros.on('close', function() { + console.log('Connection to websocket server closed.'); +}); + var move_base= new ROSLIB.ActionClient({ + ros : ros, + serverName : '/move_base', + actionName : 'move_base_msgs/MoveBaseAction' + }); + + var currentTime = new Date(); + var secs = Math.floor(currentTime.getTime()/1000) + var nsecs = Math.round(1000000000*(currentTime.getTime()/1000-secs)) + + var goal = new ROSLIB.Goal({ + actionClient: move_base, + goalMessage:{ + target_pose:{ + header:{ + frame_id:'map', + stamp:{ + secs: secs, + nsecs:nsecs + } + }, + pose:{ + position:{ + x:-3.97, //-0.743 -0.0273 取件点 + y:1.68, //3.00 -0.09 + z:0.000 + }, + orientation:{ + x:0.000, + y:0.000, + z:0.000, + w:1.000 + } + } + } + } + }); + goal.on('feedback', function(feedback) { + console.log('Feedback: ' + feedback.sequence); + }); + + goal.on('result', function(result) { + console.log('Final Result: ' + result.sequence); + }); + + ros.on('connection', function() { + console.log('Connected to websocket server.'); + }); + + ros.on('error', function(error) { + console.log('Error connecting to websocket server: ', error); + }); + + ros.on('close', function() { + console.log('Connection to websocket server closed.'); + }); + + //goal.send(); + var cmdVel = new ROSLIB.Topic({ + ros : ros, + name : '/cmd_vel', + messageType : 'geometry_msgs/Twist' + }); + + var twist = new ROSLIB.Message({ + linear : { + x : 0.1, + y : 0.2, + z : 0.3 + }, + angular : { + x : -0.1, + y : -0.2, + z : -0.3 + } + }); + cmdVel.publish(twist); + diff --git a/src/server/src/test/java/com/example/testdemo/TestdemoApplicationTests.java b/src/server/src/test/java/com/example/testdemo/TestdemoApplicationTests.java new file mode 100644 index 0000000..7558b00 --- /dev/null +++ b/src/server/src/test/java/com/example/testdemo/TestdemoApplicationTests.java @@ -0,0 +1,13 @@ +package com.example.testdemo; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class TestdemoApplicationTests { + + @Test + void contextLoads() { + } + +} From d1f1936b09db56d3673bf66c09f5a345c93b7686 Mon Sep 17 00:00:00 2001 From: Xie Changrong <1225674957@qq.com> Date: Sun, 12 Jun 2022 20:56:17 +0800 Subject: [PATCH 2/3] update --- ...�流管理系统需求构思及描述.docx | Bin 0 -> 162 bytes src/Logistics/.idea/misc.xml | 3 +- .../app/src/main/AndroidManifest.xml | 2 +- .../logistics/manager/userManager.java | 97 +++++++++ .../example/logistics/ui/LoginActivity.java | 200 ++++++++++++++++++ .../example/logistics/ui/MainActivity.java | 91 -------- .../java/com/example/logistics/ui/MeUI.java | 5 +- .../com/example/logistics/ui/PickUpUI.java | 1 - .../example/logistics/ui/SignUpActivity.java | 4 +- .../app/src/main/res/layout/activity_main.xml | 25 ++- .../app/src/main/res/layout/forget.xml | 37 ++++ 11 files changed, 364 insertions(+), 101 deletions(-) create mode 100644 doc/~$无人物流管理系统需求构思及描述.docx create mode 100644 src/Logistics/app/src/main/java/com/example/logistics/ui/LoginActivity.java delete mode 100644 src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java create mode 100644 src/Logistics/app/src/main/res/layout/forget.xml diff --git a/doc/~$无人物流管理系统需求构思及描述.docx b/doc/~$无人物流管理系统需求构思及描述.docx new file mode 100644 index 0000000000000000000000000000000000000000..17560ba09dd561c2cd7ca0d90f235b72783af9bf GIT binary patch literal 162 zcmZRsNG@U^889<cFeEb|G(K2u;q!@+fq}mnNFV_wC>thzST*OhT*?i`PY=}h-w$D6 cSnndi>sNOJt|?4@mE-Sv1_n`>8H^1K0Gt{WeE<Le literal 0 HcmV?d00001 diff --git a/src/Logistics/.idea/misc.xml b/src/Logistics/.idea/misc.xml index 1c17b84..7bf2527 100644 --- a/src/Logistics/.idea/misc.xml +++ b/src/Logistics/.idea/misc.xml @@ -17,13 +17,14 @@ <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/drawable/translucent_button.xml" value="0.194" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/drawable/translucent_edit.xml" value="0.1135" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_history.xml" value="0.22" /> - <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_main.xml" value="0.10235507246376811" /> + <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_main.xml" value="0.1" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_main2.xml" value="0.10235507246376811" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_menu.xml" value="0.33" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_no_pick.xml" value="0.2" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_sign_up.xml" value="0.10235507246376811" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/activity_wait.xml" value="0.18" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/buttom.xml" value="0.10235507246376811" /> + <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/forget.xml" value="0.2630208333333333" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/fragment_my.xml" value="0.10235507246376811" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/item.xml" value="0.22" /> <entry key="..\:/shijianer/xcr_se/src/Logistics/app/src/main/res/layout/my_fragment1.xml" value="0.1" /> diff --git a/src/Logistics/app/src/main/AndroidManifest.xml b/src/Logistics/app/src/main/AndroidManifest.xml index fc78965..bb8590b 100644 --- a/src/Logistics/app/src/main/AndroidManifest.xml +++ b/src/Logistics/app/src/main/AndroidManifest.xml @@ -25,7 +25,7 @@ android:name=".ui.MenuActivity" android:exported="false" /> <activity - android:name=".ui.MainActivity" + android:name=".ui.LoginActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java b/src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java index 0f50cf0..9a88384 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/manager/userManager.java @@ -75,6 +75,65 @@ public class userManager { return msg; } + public int loginByPhone(String phonenum, String password){ + HashMap<String, Object> map = new HashMap<>(); + + Connection connection = DBOpenHelper.getConn(); + + int msg = 0; + try{ + String sql = "select * from users where phonenum = ?"; + + if(connection != null){ + PreparedStatement ps = connection.prepareStatement(sql); + if(ps != null){ + Log.e(TAG, "phonenum: " + phonenum); + ps.setString(1,phonenum); + ResultSet rs = ps.executeQuery(); + + int count = rs.getMetaData().getColumnCount(); + while(rs.next()){ + for(int i = 1; i <= count; i++){ + String field = rs.getMetaData().getColumnName(i); + map.put(field, rs.getString(field)); + } + } + connection.close(); + ps.close(); + password = MD5Utils.md5(password); + if(map.size() != 0){ + StringBuilder s = new StringBuilder(); + for(String key:map.keySet()){ + if(key.equals("password")){ + + if(password.equals(map.get(key))){ + msg = 1; //password correct + }else{ + msg = 2; //password incorrect + } + break; + } + } + }else{ + Log.e(TAG, "result is null"); + msg = 3; //result is null + } + }else{ + Log.e(TAG, "ps is null"); + msg = 0; + } + }else{ + Log.e(TAG, "connection is null"); + msg = 0; + } + }catch (Exception e){ + e.printStackTrace(); + Log.d(TAG, "login bug: " + e.getMessage()); + msg = 0; + } + return msg; + } + public User findUser(String username){ Connection connection = DBOpenHelper.getConn(); @@ -137,4 +196,42 @@ public class userManager { } } + public int change(String phonenum, String password){ + HashMap<String, Object> map = new HashMap<>(); + + Connection connection = DBOpenHelper.getConn(); + + int msg = 0; + try{ + String sql = "update users set password = ? where phonenum = ?"; + + if(connection != null){ + PreparedStatement ps = connection.prepareStatement(sql); + if(ps != null){ + Log.e(TAG, "phonenum: " + phonenum); + password = MD5Utils.md5(password); + ps.setString(1,password); + + ps.setString(2,phonenum); + ps.executeUpdate(); + connection.close(); + ps.close(); + msg = 1; + + }else{ + Log.e(TAG, "ps is null"); + msg = 0; + } + }else{ + Log.e(TAG, "connection is null"); + msg = 0; + } + }catch (Exception e){ + e.printStackTrace(); + Log.d(TAG, "login bug: " + e.getMessage()); + msg = 0; + } + return msg; + } + } diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/LoginActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/LoginActivity.java new file mode 100644 index 0000000..7b4ba8d --- /dev/null +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/LoginActivity.java @@ -0,0 +1,200 @@ +package com.example.logistics.ui; + +import com.example.logistics.R; +import com.example.logistics.manager.goodManager; +import com.example.logistics.manager.operationManager; +import com.example.logistics.manager.userManager; +import com.example.logistics.entity.User; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class LoginActivity extends Activity { + + private int islogin = 0; + private Button loginButton; + private Button signUpButton; + private Button forgetButton; + private Button phonenumButton; + private AlertDialog alert; + private Button changeButton; + private EditText fphonenum; + private EditText fpassword; + int flag = 0; //flag = 0 是用户名登录;=1是手机号 + + // 调用Actvity + private String TAG = "LoginActivity"; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + loginButton = (Button) this.findViewById(R.id.LoginButton); + signUpButton = (Button) this.findViewById(R.id.SignUpButton); + forgetButton = (Button) this.findViewById(R.id.forget); + phonenumButton = (Button) this.findViewById(R.id.phonenum); + + + AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this); + + View view2 = View.inflate(LoginActivity.this, R.layout.forget, null); + + builder.setTitle("取件").setView(view2); + + alert = builder.create(); + + changeButton = (Button) view2.findViewById(R.id.change); + fphonenum = (EditText) view2.findViewById(R.id.fphonenum); + fpassword = (EditText) view2.findViewById(R.id.fpassword); + + loginButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + login(v); + Log.d(TAG, "login"); + } + } + ); + + signUpButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(LoginActivity.this, SignUpActivity.class); + Log.d(TAG, "signup"); + startActivity(intent); + } + } + ); + + forgetButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View view) { + alert.show(); + changeButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View view) { + Log.d(TAG, "change password"); + change(view); + } + } + ); + } + } + ); + + EditText userName = (EditText) this.findViewById(R.id.UserNameEdit); + phonenumButton.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View view) { + userName.setHint("请输入手机号"); + flag = 1; + } + } + ); + + } + + public void change(View view){ + String phoneunm = fphonenum.getText().toString().trim(); + String password = fpassword.getText().toString().trim(); + new Thread() { + @Override + public void run() { + userManager userManager = new userManager(); + + int msg = userManager.change(phoneunm, password); + + Log.d(TAG, "change"); + if(msg != 1){ + Log.d(TAG, "pickup,failed"); + hand2.sendEmptyMessage(msg); + return; + } + Log.d(TAG, "change,success"); + + hand2.sendEmptyMessage(msg); + } + }.start(); + } + + public void login(View view){ + EditText userName = (EditText) this.findViewById(R.id.UserNameEdit); + EditText passWord = (EditText) this.findViewById(R.id.PassWordEdit); + + new Thread(){ + @Override + public void run(){ + userManager userManager = new userManager(); + int msg = 0; + if(flag == 0){ + msg = userManager.login(userName.getText().toString().trim(), passWord.getText().toString().trim()); + }else if(flag == 1){ + msg = userManager.loginByPhone(userName.getText().toString().trim(), passWord.getText().toString().trim()); + + } + Log.e("MAin", "msg"); + hand1.sendEmptyMessage(msg); + if(msg == 1){ + User owner = userManager.findUser(userName.getText().toString().trim()); + Intent intent = new Intent(LoginActivity.this, MenuActivity.class); + if(flag == 1){ + intent.putExtra("user", userName.getText().toString().trim()); + }else{ + intent.putExtra("user", owner.getPhoneNum()); + } + startActivity(intent); + finish(); + } + } + }.start(); + } + + @SuppressLint("HandlerLeak") + final Handler hand1 = new Handler(){ + @Override + public void handleMessage(Message msg){ + if(msg.what == 0){ + Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show(); + }else if(msg.what == 1){ + Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show(); + islogin = 1; + }else if(msg.what == 2){ + Toast.makeText(getApplicationContext(), "密码错误", Toast.LENGTH_SHORT).show(); + }else if(msg.what == 3){ + Toast.makeText(getApplicationContext(), "账号不存在", Toast.LENGTH_SHORT).show(); + } + } + }; + @SuppressLint("HandlerLeak") + final Handler hand2 = new Handler() { + @Override + public void handleMessage(Message msg) { + if(msg.what == 0){ + Toast.makeText(LoginActivity.this, "修改失败", Toast.LENGTH_SHORT).show(); + }else if(msg.what == 1) { + Toast.makeText(LoginActivity.this, "修改成功", Toast.LENGTH_SHORT).show(); + } + } + }; + +} \ No newline at end of file diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java deleted file mode 100644 index b2e3517..0000000 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MainActivity.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.example.logistics.ui; - -import com.example.logistics.R; -import com.example.logistics.manager.userManager; -import com.example.logistics.entity.User; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; - - -public class MainActivity extends Activity { - - private int islogin = 0; - // 调用Actvity - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - Button loginButton = (Button) this.findViewById(R.id.LoginButton); - Button signUpButton = (Button) this.findViewById(R.id.SignUpButton); - - loginButton.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - login(v); - } - } - ); - signUpButton.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(MainActivity.this, SignUpActivity.class); - startActivity(intent); - } - } - ); - - } - - public void login(View view){ - EditText userName = (EditText) this.findViewById(R.id.UserNameEdit); - EditText passWord = (EditText) this.findViewById(R.id.PassWordEdit); - - new Thread(){ - @Override - public void run(){ - userManager userManager = new userManager(); - int msg = userManager.login(userName.getText().toString().trim(), passWord.getText().toString().trim()); - Log.e("MAin", "msg"); - hand1.sendEmptyMessage(msg); - if(msg == 1){ - User owner = userManager.findUser(userName.getText().toString().trim()); - Intent intent = new Intent(MainActivity.this, MenuActivity.class); - intent.putExtra("user", owner.getPhoneNum()); - startActivity(intent); - finish(); - } - } - }.start(); - } - - @SuppressLint("HandlerLeak") - final Handler hand1 = new Handler(){ - @Override - public void handleMessage(Message msg){ - if(msg.what == 0){ - Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show(); - }else if(msg.what == 1){ - Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show(); - islogin = 1; - }else if(msg.what == 2){ - Toast.makeText(getApplicationContext(), "密码错误", Toast.LENGTH_SHORT).show(); - }else if(msg.what == 3){ - Toast.makeText(getApplicationContext(), "账号不存在", Toast.LENGTH_SHORT).show(); - } - } - }; - -} \ No newline at end of file diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java index 84e6ba6..f49574c 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/MeUI.java @@ -9,15 +9,12 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; import com.example.logistics.R; -import org.w3c.dom.Text; - public class MeUI extends Fragment implements View.OnClickListener{ private LinearLayout ll_waiting; private LinearLayout ll_history; @@ -67,7 +64,7 @@ public class MeUI extends Fragment implements View.OnClickListener{ break; case R.id.exit: Toast.makeText(mContext, "exit", Toast.LENGTH_SHORT).show(); - intent = new Intent(mContext, MainActivity.class); + intent = new Intent(mContext, LoginActivity.class); startActivity(intent); getActivity().finish(); break; diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java index d0d0912..0ffd4f1 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/PickUpUI.java @@ -211,7 +211,6 @@ public class PickUpUI extends Fragment implements View.OnClickListener{ builder.setTitle("取件").setView(view2); - alert2 = builder.create(); alert2.show(); button.setOnClickListener(new View.OnClickListener() { diff --git a/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java b/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java index d63254a..55ef479 100644 --- a/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java +++ b/src/Logistics/app/src/main/java/com/example/logistics/ui/SignUpActivity.java @@ -38,7 +38,7 @@ public class SignUpActivity extends Activity { @Override public void onClick(View v) { // 跳转到登录界面 - Intent intent = new Intent(SignUpActivity.this, MainActivity.class); + Intent intent = new Intent(SignUpActivity.this, LoginActivity.class); startActivity(intent); } } @@ -106,7 +106,7 @@ public class SignUpActivity extends Activity { Toast.makeText(getApplicationContext(), "该账号已存在,请换一个注册", Toast.LENGTH_SHORT).show(); }else if(msg.what == 2){ Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show(); - Intent intent = new Intent(SignUpActivity.this, MainActivity.class); + Intent intent = new Intent(SignUpActivity.this, LoginActivity.class); startActivity(intent); } } diff --git a/src/Logistics/app/src/main/res/layout/activity_main.xml b/src/Logistics/app/src/main/res/layout/activity_main.xml index 939e667..9e033a5 100644 --- a/src/Logistics/app/src/main/res/layout/activity_main.xml +++ b/src/Logistics/app/src/main/res/layout/activity_main.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.example.logistics.ui.MainActivity"> + tools:context="com.example.logistics.ui.LoginActivity"> <!--使用线性布局--> <LinearLayout android:id="@+id/linearLayout2" @@ -110,6 +110,29 @@ </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button + android:id="@+id/forget" + android:layout_width="wrap_content" + android:layout_height="20dp" + android:layout_marginLeft="15dp" + android:background="#F5F5F5" + android:text="忘记密码" /> + + + <Button + android:id="@+id/phonenum" + android:layout_width="249dp" + android:layout_height="20dp" + android:background="#F5F5F5" + android:gravity="right" + android:text="手机号登录" /> + + </LinearLayout> + </LinearLayout> </LinearLayout> diff --git a/src/Logistics/app/src/main/res/layout/forget.xml b/src/Logistics/app/src/main/res/layout/forget.xml new file mode 100644 index 0000000..acc385b --- /dev/null +++ b/src/Logistics/app/src/main/res/layout/forget.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <EditText + android:layout_width="200dp" + android:layout_height="wrap_content" + android:id="@+id/fphonenum" + android:hint="请输入注册时手机号" + /> + </LinearLayout> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <EditText + android:layout_width="200dp" + android:layout_height="wrap_content" + android:id="@+id/fpassword" + android:hint="请输入新密码" + /> + </LinearLayout> + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="修改" + android:id="@+id/change"/> + +</LinearLayout> \ No newline at end of file From 69e9e55aacec9b680bcd16999f62343a394c120b Mon Sep 17 00:00:00 2001 From: Xie Changrong <1225674957@qq.com> Date: Sun, 12 Jun 2022 21:11:19 +0800 Subject: [PATCH 3/3] update --- .../example/testdemo/ros/MessageHandler.java | 26 + .../testdemo/ros/message/AudioMsg.java | 9 + .../example/testdemo/ros/message/Clock.java | 25 + .../testdemo/ros/message/Duration.java | 24 + .../ros/message/DurationPrimitive.java | 25 + .../example/testdemo/ros/message/Empty.java | 24 + .../example/testdemo/ros/message/Header.java | 27 + .../com/example/testdemo/ros/message/Log.java | 32 + .../example/testdemo/ros/message/Message.java | 202 ++++++ .../ros/message/MessageException.java | 32 + .../testdemo/ros/message/MessageType.java | 32 + .../testdemo/ros/message/SemanticRequest.java | 13 + .../ros/message/SemanticResponse.java | 9 + .../example/testdemo/ros/message/StdMsg.java | 9 + .../example/testdemo/ros/message/Time.java | 24 + .../testdemo/ros/message/TimePrimitive.java | 26 + .../testdemo/ros/rosapi/message/Empty.java | 27 + .../testdemo/ros/rosapi/message/GetTime.java | 30 + .../ros/rosapi/message/MessageDetails.java | 28 + .../testdemo/ros/rosapi/message/Nodes.java | 28 + .../testdemo/ros/rosapi/message/Service.java | 34 ++ .../testdemo/ros/rosapi/message/Services.java | 28 + .../testdemo/ros/rosapi/message/Topic.java | 34 ++ .../testdemo/ros/rosapi/message/Topics.java | 28 + .../testdemo/ros/rosapi/message/Type.java | 34 ++ .../testdemo/ros/rosapi/message/TypeDef.java | 55 ++ .../ros/rosbridge/FullMessageHandler.java | 26 + .../ros/rosbridge/implementation/Base64.java | 575 ++++++++++++++++++ .../ros/rosbridge/implementation/JSON.java | 335 ++++++++++ .../implementation/PublishEvent.java | 24 + .../rosbridge/implementation/Registry.java | 49 ++ .../ros/rosbridge/indication/AsArray.java | 30 + .../rosbridge/indication/Base64Encoded.java | 30 + .../ros/rosbridge/indication/Indicate.java | 31 + .../ros/rosbridge/indication/Indicated.java | 31 + .../ros/rosbridge/indication/Indication.java | 83 +++ .../ros/rosbridge/indication/Indicator.java | 31 + .../ros/rosbridge/operation/Advertise.java | 35 ++ .../ros/rosbridge/operation/Authenticate.java | 56 ++ .../ros/rosbridge/operation/CallService.java | 41 ++ .../ros/rosbridge/operation/Fragment.java | 37 ++ .../ros/rosbridge/operation/Operation.java | 77 +++ .../testdemo/ros/rosbridge/operation/PNG.java | 41 ++ .../ros/rosbridge/operation/Publish.java | 40 ++ .../rosbridge/operation/ServiceResponse.java | 38 ++ .../rosbridge/operation/SetStatusLevel.java | 38 ++ .../ros/rosbridge/operation/Status.java | 35 ++ .../ros/rosbridge/operation/Subscribe.java | 39 ++ .../ros/rosbridge/operation/Unadvertise.java | 33 + .../ros/rosbridge/operation/Unsubscribe.java | 33 + .../ros/rosbridge/operation/Wrapper.java | 33 + 51 files changed, 2686 insertions(+) create mode 100644 src/server/src/main/java/com/example/testdemo/ros/MessageHandler.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/AudioMsg.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Clock.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Duration.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/DurationPrimitive.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Empty.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Header.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Log.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Message.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/MessageException.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/MessageType.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/SemanticRequest.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/SemanticResponse.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/StdMsg.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/Time.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/message/TimePrimitive.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Empty.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/GetTime.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/MessageDetails.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Nodes.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Service.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Services.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topic.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topics.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Type.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosapi/message/TypeDef.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/FullMessageHandler.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Base64.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/PublishEvent.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Registry.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/AsArray.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Base64Encoded.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicate.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicated.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indication.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicator.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Advertise.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Authenticate.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/CallService.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Fragment.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Operation.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/PNG.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Publish.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/ServiceResponse.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/SetStatusLevel.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Status.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Subscribe.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unadvertise.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unsubscribe.java create mode 100644 src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Wrapper.java diff --git a/src/server/src/main/java/com/example/testdemo/ros/MessageHandler.java b/src/server/src/main/java/com/example/testdemo/ros/MessageHandler.java new file mode 100644 index 0000000..332d8f8 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/MessageHandler.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros; + +import com.example.testdemo.ros.message.Message; + +public interface MessageHandler<T extends Message> { + public void onMessage(T message); +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/AudioMsg.java b/src/server/src/main/java/com/example/testdemo/ros/message/AudioMsg.java new file mode 100644 index 0000000..21125e1 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/AudioMsg.java @@ -0,0 +1,9 @@ +package com.example.testdemo.ros.message; + +/** + * Created by xxhong on 16-11-17. + */ +@MessageType(string = "std_msgs/Int16MultiArray") +public class AudioMsg extends Message { + public short[] data; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Clock.java b/src/server/src/main/java/com/example/testdemo/ros/message/Clock.java new file mode 100644 index 0000000..3f3cff6 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Clock.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "rosgraph_msgs/Clock") +public class Clock extends Message { + public TimePrimitive clock; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Duration.java b/src/server/src/main/java/com/example/testdemo/ros/message/Duration.java new file mode 100644 index 0000000..0acb11e --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Duration.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "std_msgs/Duration") +public class Duration extends DurationPrimitive { +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/DurationPrimitive.java b/src/server/src/main/java/com/example/testdemo/ros/message/DurationPrimitive.java new file mode 100644 index 0000000..a789d7a --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/DurationPrimitive.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "duration") +public class DurationPrimitive extends TimePrimitive { + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Empty.java b/src/server/src/main/java/com/example/testdemo/ros/message/Empty.java new file mode 100644 index 0000000..fa9efbc --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Empty.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "std_srvs/Empty") +public class Empty extends Message { +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Header.java b/src/server/src/main/java/com/example/testdemo/ros/message/Header.java new file mode 100644 index 0000000..01fe4f0 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Header.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "std_msgs/Header") +public class Header extends Message { + public long seq; + public TimePrimitive stamp; + public String frame_id; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Log.java b/src/server/src/main/java/com/example/testdemo/ros/message/Log.java new file mode 100644 index 0000000..7333e93 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Log.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "rosgraph_msgs/Log") +public class Log extends Message { + public Header header; + public byte level; + public String name; + public String msg; + public String file; + public String function; + public long line; + public String[] topics; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Message.java b/src/server/src/main/java/com/example/testdemo/ros/message/Message.java new file mode 100644 index 0000000..0572d3e --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Message.java @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.util.Map; + + +@MessageType(string = "message") +public abstract class Message { + + // Some requirements about message types: + // - It must have a MessageType declaration to be recognized on inbound messages + // - Every field must be explicitly designated as public + // - Every field that is not a primitive or near-primitive must be another Message class + // - If there is a non-empty constructor, you must also have an empty constructor + // - If it is set up as an inner class, it needs an explicit nullary constructor + // (note: I have seen an inner class otherwise fail, I have not tested it with the explicit constructor) + + public static void register(Class c, Map<String, Class> messageClasses) { + try { + typecheck(c); + + // Must register the class and not have duplicate + // This is not recursive because only the top level message class + // needs to be determined from the string - others are top-down. + String messageString = getMessageType(c); + Class existingClass = messageClasses.get(messageString); + if (existingClass != null && !existingClass.equals(c)) + throw new MessageException("Message String \'" + messageString + + "\' is assigned to two different classes (" + + c.getName() + " and " + existingClass.getName() + ")"); + messageClasses.put(messageString, c); + } + catch (MessageException ex) { + // should be changed to be a hooked method to give library user control + System.out.println(ex.getMessage()); + } + } + + public static String getMessageType(Class c) { + return ((MessageType) c.getAnnotation(MessageType.class)).string(); + } + + // this has never been used or tested but kind of belongs here + // commented out because it uses ReflectiveOperationException which is not available on Android + /* + public static Message newInstance(String className) { + try { + Class messageClass = Class.forName(className); + if (Message.class.isAssignableFrom(messageClass)) + return (Message) messageClass.newInstance(); + else throw new ClassCastException(); + } + catch (ReflectiveOperationException ex) { + throw new RuntimeException("Unable to create message of class \'" + className + "\'.", ex); + } + } + */ + + // Could probably do more checking here, but not sure what right now + private static void typecheck(Class c) throws MessageException { + + // Must inherit from Message + if (!Message.class.isAssignableFrom(c)) + throw new MessageException("Class \'" + c.getName() + + "\' does not extend Message"); + + // Must have the MessageType annotation + if (getMessageType(c) == null) + throw new MessageException("Class \'" + c.getName() + + "\' is missing the MessageType annotation"); + + // All fields must also be valid Message classes + // Note that this also serves to force-load all the message classes + // so that they get registered + for (Field f : c.getFields()) { + Class fc = f.getType(); + if (fc.isArray()) { + Class ac = fc.getComponentType(); + if (!isPrimitive(ac)) + typecheck(ac); + } + else if (!isPrimitive(fc)) + typecheck(fc); + } + } + + public void print() { + printMessage(this, ""); + } + + private static void printMessage(Object o, String indent) { + for (Field f : o.getClass().getFields()) { + Class c = f.getType(); + Object fieldObject = getFieldObject(f, o); + if (fieldObject != null) { + if (isPrimitive(c)) + System.out.println(indent + f.getName() + ": " + fieldObject); + else if (c.isArray()) { + System.out.println(indent + f.getName() + ": ["); + printArray(fieldObject, indent + " "); + System.out.println(indent + "]"); + } + else { + System.out.println(indent + f.getName() + ":"); + printMessage(fieldObject, indent + " "); + } + } + } + } + + private static void printArray(Object array, String indent) { + Class arrayClass = array.getClass().getComponentType(); + for (int i = 0; i < Array.getLength(array); i++) { + Object elementObject = Array.get(array, i); + if (elementObject != null) { + if (isPrimitive(arrayClass)) + System.out.println(indent + i + ": " + elementObject); + else if (arrayClass.isArray()) { // this is not actually allowed in ROS + System.out.println(indent + i + ": ["); + printArray(elementObject, indent + " "); + System.out.println(indent + "]"); + } + else { + System.out.println(indent + i + ":"); + printMessage(elementObject, indent + " "); + } + } + } + // remember to print array indices + } + + public static boolean isPrimitive(Class c) { + return (c.isPrimitive() || + c.equals(String.class) || + Number.class.isAssignableFrom(c) || + c.equals(Boolean.class)); + } + + + // Copied from com.example.testdemo.ros.rosbridge.JSON + private static Object getFieldObject(Field f, Object o) { + Object fo = null; + try { + fo = f.get(o); + } + catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + return fo; + } + + public void copyFrom(Message source) { + try { + if (source.getClass() != getClass()) + throw new RuntimeException("Attempt to copy non-matching classes"); + for (Field f : getClass().getFields()) { + Class fc = f.getType(); + if (fc.isArray()) + throw new RuntimeException("copyFrom - array types not implemented"); + else if (!isPrimitive(fc)) + ((Message) f.get(this)).copyFrom((Message) f.get(source)); + else { + Object value = f.get(source); + f.set(this, value); + } + } + } + catch (IllegalAccessException ex) { + throw new RuntimeException("copyFrom error", ex); + } + catch (ClassCastException ex) { + throw new RuntimeException("copyFrom error", ex); + } + // ReflectiveOperationException is not available on Android (Java 1.6) + /* + catch (ReflectiveOperationException ex) { + throw new RuntimeException ("copyFrom error", ex); + } + */ + } + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/MessageException.java b/src/server/src/main/java/com/example/testdemo/ros/message/MessageException.java new file mode 100644 index 0000000..e40bb88 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/MessageException.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +public class MessageException extends Exception { + + public MessageException(String message) { + super(message); + } + + public MessageException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/MessageType.java b/src/server/src/main/java/com/example/testdemo/ros/message/MessageType.java new file mode 100644 index 0000000..a61c758 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/MessageType.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface MessageType { + String string() default ""; +} + diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/SemanticRequest.java b/src/server/src/main/java/com/example/testdemo/ros/message/SemanticRequest.java new file mode 100644 index 0000000..f2ffb48 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/SemanticRequest.java @@ -0,0 +1,13 @@ +package com.example.testdemo.ros.message; + +/** + * Created by xxhong on 16-11-17. + */ +@MessageType(string = "std_msgs/String") +public class SemanticRequest extends Message { + public SemanticRequest(String args) { + jsonStr = args; + } + + public String jsonStr; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/SemanticResponse.java b/src/server/src/main/java/com/example/testdemo/ros/message/SemanticResponse.java new file mode 100644 index 0000000..f0df3f7 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/SemanticResponse.java @@ -0,0 +1,9 @@ +package com.example.testdemo.ros.message; + +/** + * Created by xxhong on 16-11-17. + */ +@MessageType(string = "std_msgs/String") +public class SemanticResponse extends Message { + public String result; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/StdMsg.java b/src/server/src/main/java/com/example/testdemo/ros/message/StdMsg.java new file mode 100644 index 0000000..036f0e2 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/StdMsg.java @@ -0,0 +1,9 @@ +package com.example.testdemo.ros.message; + +/** + * Created by xxhong on 16-11-17. + */ +@MessageType(string = "std_msgs/String") +public class StdMsg extends Message { + public String data; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/Time.java b/src/server/src/main/java/com/example/testdemo/ros/message/Time.java new file mode 100644 index 0000000..308667b --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/Time.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "std_msgs/Time") +public class Time extends TimePrimitive { +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/message/TimePrimitive.java b/src/server/src/main/java/com/example/testdemo/ros/message/TimePrimitive.java new file mode 100644 index 0000000..05f3d44 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/message/TimePrimitive.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.message; + +@MessageType(string = "time") +public class TimePrimitive extends Message { + public int secs; // when requesting this format from ROSbridge, it uses 'sec' (no 's') + public int nsecs; // when requesting this format from ROSbridge, it uses 'nsec' +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Empty.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Empty.java new file mode 100644 index 0000000..5dd3b37 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Empty.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "std_msgs/Empty") +public class Empty extends Message { +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/GetTime.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/GetTime.java new file mode 100644 index 0000000..51036a1 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/GetTime.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; +import com.example.testdemo.ros.message.TimePrimitive; + + +@MessageType(string = "rosapi/GetTimeResponse") +public class GetTime extends Message { + public TimePrimitive time; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/MessageDetails.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/MessageDetails.java new file mode 100644 index 0000000..fa9ea18 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/MessageDetails.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/MessageDetails") +public class MessageDetails extends Message { + public TypeDef[] typedefs; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Nodes.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Nodes.java new file mode 100644 index 0000000..317add3 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Nodes.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/Nodes") +public class Nodes extends Message { + public String[] nodes; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Service.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Service.java new file mode 100644 index 0000000..8ef46ad --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Service.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/Service") +public class Service extends Message { + public String service; + + public Service() {} + + public Service(String service) { + this.service = service; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Services.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Services.java new file mode 100644 index 0000000..c5f8f71 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Services.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/Services") +public class Services extends Message { + public String[] services; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topic.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topic.java new file mode 100644 index 0000000..ce943a4 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topic.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/Topic") +public class Topic extends Message { + public String topic; + + public Topic() {} + + public Topic(String topic) { + this.topic = topic; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topics.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topics.java new file mode 100644 index 0000000..503e924 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Topics.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/Topics") +public class Topics extends Message { + public String[] topics; +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Type.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Type.java new file mode 100644 index 0000000..7ecc693 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/Type.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/Type") +public class Type extends Message { + public String type; + + public Type() {} + + public Type(String type) { + this.type = type; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/TypeDef.java b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/TypeDef.java new file mode 100644 index 0000000..c949182 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosapi/message/TypeDef.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosapi.message; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "rosapi/TypeDef") +public class TypeDef extends Message { + public String type; + public String[] fieldnames; + public String[] fieldtypes; + public int[] fieldarraylen; + public String[] examples; + + public static boolean match(String type, Class c) { + boolean result = false; + if ( + (type.equals("bool") && ((boolean.class.equals(c)) || (Boolean.class.equals(c)))) || + (type.equals("int8") && ((byte.class.equals(c)) || (Byte.class.equals(c)))) || + (type.equals("byte") && ((byte.class.equals(c)) || (Byte.class.equals(c)))) || // deprecated + (type.equals("uint8") && ((short.class.equals(c)) || (Short.class.equals(c)))) || + (type.equals("char") && ((short.class.equals(c)) || (Short.class.equals(c)))) || // deprecated + (type.equals("int16") && ((short.class.equals(c)) || (Short.class.equals(c)))) || + (type.equals("uint16") && ((int.class.equals(c)) || (Integer.class.equals(c)))) || + (type.equals("int32") && ((int.class.equals(c)) || (Integer.class.equals(c)))) || + (type.equals("uint32") && ((long.class.equals(c)) || (Long.class.equals(c)))) || + (type.equals("int64") && ((long.class.equals(c)) || (Long.class.equals(c)))) || + (type.equals("float32") && ((float.class.equals(c)) || (Float.class.equals(c)))) || + (type.equals("float64") && ((double.class.equals(c)) || (Double.class.equals(c)))) || + (type.equals("uint64") && (java.math.BigInteger.class.equals(c))) || + (type.equals("string") && (String.class.equals(c))) + ) + result = true; + + return result; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/FullMessageHandler.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/FullMessageHandler.java new file mode 100644 index 0000000..b1d3aab --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/FullMessageHandler.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge; + +import com.example.testdemo.ros.message.Message; + +public interface FullMessageHandler<T extends Message> { + public void onMessage(String id, T message); +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Base64.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Base64.java new file mode 100644 index 0000000..919a7a3 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Base64.java @@ -0,0 +1,575 @@ +package com.example.testdemo.ros.rosbridge.implementation; + +import java.util.Arrays; + +/** A very fast and memory efficient class to encode and decode to and from BASE64 in full accordance + * with RFC 2045.<br><br> + * On Windows XP sp1 with 1.4.2_04 and later ;), this encoder and decoder is about 10 times faster + * on small arrays (10 - 1000 bytes) and 2-3 times as fast on larger arrays (10000 - 1000000 bytes) + * compared to <code>sun.misc.Encoder()/Decoder()</code>.<br><br> + * + * On byte arrays the encoder is about 20% faster than Jakarta Commons Base64 Codec for encode and + * about 50% faster for decoding large arrays. This implementation is about twice as fast on very small + * arrays (< 30 bytes). If source/destination is a <code>String</code> this + * version is about three times as fast due to the fact that the Commons Codec result has to be recoded + * to a <code>String</code> from <code>byte[]</code>, which is very expensive.<br><br> + * + * This encode/decode algorithm doesn't create any temporary arrays as many other codecs do, it only + * allocates the resulting array. This produces less garbage and it is possible to handle arrays twice + * as large as algorithms that create a temporary array. (E.g. Jakarta Commons Codec). It is unknown + * whether Sun's <code>sun.misc.Encoder()/Decoder()</code> produce temporary arrays but since performance + * is quite low it probably does.<br><br> + * + * The encoder produces the same output as the Sun one except that the Sun's encoder appends + * a trailing line separator if the last character isn't a pad. Unclear why but it only adds to the + * length and is probably a side effect. Both are in conformance with RFC 2045 though.<br> + * Commons codec seem to always att a trailing line separator.<br><br> + * + * <b>Note!</b> + * The encode/decode method pairs (types) come in three versions with the <b>exact</b> same algorithm and + * thus a lot of code redundancy. This is to not create any temporary arrays for transcoding to/from different + * format types. The methods not used can simply be commented out.<br><br> + * + * There is also a "fast" version of all decode methods that works the same way as the normal ones, but + * har a few demands on the decoded input. Normally though, these fast verions should be used if the source if + * the input is known and it hasn't bee tampered with.<br><br> + * + * If you find the code useful or you find a bug, please send me a note at base64 @ miginfocom . com. + * + * Licence (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (base64 @ miginfocom . com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 2.2 + * @author Mikael Grev + * Date: 2004-aug-02 + * Time: 11:31:11 + */ + +public class Base64 +{ + private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static final int[] IA = new int[256]; + static { + Arrays.fill(IA, -1); + for (int i = 0, iS = CA.length; i < iS; i++) + IA[CA[i]] = i; + IA['='] = 0; + } + + // **************************************************************************************** + // * char[] version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 <code>char[]</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static char[] encodeToChar(byte[] sArr, boolean lineSep) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new char[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + char[] dArr = new char[dLen]; + + // Encode even 24-bits + for (int s = 0, d = 0, cc = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = CA[(i >>> 18) & 0x3f]; + dArr[d++] = CA[(i >>> 12) & 0x3f]; + dArr[d++] = CA[(i >>> 6) & 0x3f]; + dArr[d++] = CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = CA[i >> 12]; + dArr[dLen - 3] = CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + /** Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. <code>null</code> or length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(char[] sArr) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new byte[0]; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[sArr[i]] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + int pad = 0; + for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;) + if (sArr[i] == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[sArr[s++]]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + return dArr; + } + + /** Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(char[])}. The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(char[] sArr) + { + // Check special case + int sLen = sArr.length; + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[sArr[sIx]] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[sArr[eIx]] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[sArr[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } + + // **************************************************************************************** + // * byte[] version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new byte[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + byte[] dArr = new byte[dLen]; + + // Encode even 24-bits + for (int s = 0, d = 0, cc = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = (byte) CA[(i >>> 18) & 0x3f]; + dArr[d++] = (byte) CA[(i >>> 12) & 0x3f]; + dArr[d++] = (byte) CA[(i >>> 6) & 0x3f]; + dArr[d++] = (byte) CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't an even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = (byte) CA[i >> 12]; + dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + /** Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(byte[] sArr) + { + // Check special case + int sLen = sArr.length; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[sArr[i] & 0xff] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + int pad = 0; + for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;) + if (sArr[i] == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[sArr[s++] & 0xff]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + + return dArr; + } + + + /** Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(byte[])}. The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(byte[] sArr) + { + // Check special case + int sLen = sArr.length; + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[sArr[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } + + // **************************************************************************************** + // * String version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br> + * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never <code>null</code>. + */ + public final static String encodeToString(byte[] sArr, boolean lineSep) + { + // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower. + return new String(encodeToChar(sArr, lineSep)); + } + + /** Decodes a BASE64 encoded <code>String</code>. All illegal characters will be ignored and can handle both strings with + * and without line separators.<br> + * <b>Note!</b> It can be up to about 2x the speed to call <code>decode(str.toCharArray())</code> instead. That + * will create a temporary array though. This version will use <code>str.charAt(i)</code> to iterate the string. + * @param str The source string. <code>null</code> or length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(String str) + { + // Check special case + int sLen = str != null ? str.length() : 0; + if (sLen == 0) + return new byte[0]; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[str.charAt(i)] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + // Count '=' at end + int pad = 0; + for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;) + if (str.charAt(i) == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[str.charAt(s++)]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + return dArr; + } + + /** Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(String)}. The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(String s) + { + // Check special case + int sLen = s.length(); + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[s.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java new file mode 100644 index 0000000..67a3d0b --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/JSON.java @@ -0,0 +1,335 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.implementation; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.rosbridge.indication.Indication; +import com.example.testdemo.ros.rosbridge.operation.Wrapper; +import jdk.nashorn.internal.parser.JSONParser; + + +import java.io.StringReader; +import java.lang.reflect.Array; +import java.lang.reflect.Field; + + +// The slightly crazy abstractions here are designed to isolate knowledge of +// the JSON library and data types from the Operation details of rosbridge. +// Why is this important? A few reasons I can see. First, we might want +// to change JSON libraries and this encapsulates all use of JSON-simple. +// Second, as much as possible I would like the semantics of the rosbridge +// protocol to be encapsulated in the Operation and its subclasses rather +// than in a module that is essentially about serialization. +// +// Unfortunately the hierarchical Message abstraction is a bit broken +// at the top level. Beginning at the actual operation (e.g., Publish), the +// types of the fields are determined either by the fields themselves or by +// an indicator. However, the type of the operation itself is not determined +// this way, because the indicator is in the object itself, which means it +// would have to be created before its type is known. Rather than build in +// exceptions, I elected to create a "Wrapper" operation type that simply +// wraps the concrete operation and copies its "op" field. +// + +public class JSON { + + /** + * Translates a Message recursively into JSON. Normally the Message is also an + * Operation, but it does not have to be. The caller constructs a complete + * message using @Operation and @Message types. This includes situations + * where one or more fields are marked to be turned into arrays, using @AsArray. + * @param m the @Message object to be recursively translated. + * @return the complete JSON string. + */ + public static String toJSON(Message m) { + JSONObject jo = convertObjectToJSONObject(m); // Object to JSON-Simple + return jo.toJSONString(); // JSON-Simple to string + } + + /** + * Translates JSON into a hierarchical Operation/Message structure. + * This includes handling fields that are @Indicated and @AsArray. If the + * @Class parameter is a @Wrapper, this is a special case whereby the + * object is wrapped to create a consistent hierarchy. + * @param json the source JSON string + * @param c the top level class of the JSON. Normally @Wrapper + * @param r the @Registry containing topic registrations + * @return the fully instantiated message hierarchy represented + * by the JSON string. + */ + public static Message toMessage(String json, Class c, Registry<Class> r) { + JSONObject joUnwrapped = convertStringToJSONObject(json); // String to JSON-Simple + JSONObject jo = joUnwrapped; + if (Wrapper.class.isAssignableFrom(c)) + jo = wrap(joUnwrapped, c); // wrap: a hack to make the hierarchy homogeneous + return convertJSONObjectToMessage(jo, c, r); // JSON-Simple to Message + } + + // *** Create JSON from Messages *** // + + // Translate the object into a JSON-Simple object, field-by-field, + // recursively via convertElementToJSON. + // except for the case where AsArray is indicated + private static JSONObject convertObjectToJSONObject(Object o) { + JSONObject result = new JSONObject(); + for (Field f : o.getClass().getFields()) { + Object fieldObject = getFieldObject(f, o); + if (fieldObject != null) { + Object resultObject; + if (Indication.isBase64Encoded(f)) + resultObject = convertByteArrayToBase64JSONString(fieldObject); + else if (Indication.asArray(f)) + resultObject = convertObjectToJSONArray(fieldObject); + else resultObject = convertElementToJSON(fieldObject); + result.put(f.getName(), resultObject); + } + } + return result; + } + + // Convert an array type to a JSON-Simple array, element-by-element, + // recursively via convertElementToJSON. + private static JSONArray convertArrayToJSONArray(Object array) { + JSONArray result = new JSONArray(); + for (int i = 0; i < Array.getLength(array); i++) { + Object elementObject = Array.get(array, i); + if (elementObject != null) { + Object resultObject = convertElementToJSON(elementObject); + result.add(resultObject); + } + } + return result; + } + + // For AsArray objects, convert the object to a JSON-Simple array + // NOTE: This relies on later versions of the JDK providing + // the fields in order. + private static JSONArray convertObjectToJSONArray(Object o) { + JSONArray result = new JSONArray(); + for (Field f : o.getClass().getFields()) { + Object fieldObject = getFieldObject(f, o); + if (fieldObject != null) { + Object resultObject = convertElementToJSON(fieldObject); + result.add(resultObject); + } + } + return result; + } + + // Convert the individual field or array element items recursively + private static Object convertElementToJSON(Object elementObject) { + Class elementClass = elementObject.getClass(); + Object resultObject; + if (Message.isPrimitive(elementClass)) + resultObject = elementObject; + else if (elementClass.isArray()) + resultObject = convertArrayToJSONArray(elementObject); + else + resultObject = convertObjectToJSONObject(elementObject); + return resultObject; + } + + // Special case for Base 64-encoded fields + private static Object convertByteArrayToBase64JSONString(Object fieldObject) { + return Base64.encodeToString((byte[]) fieldObject, false); + } + + // This is just to buffer the code from the exception. Better error + // handling needed here. + private static Object getFieldObject(Field f, Object o) { + Object fo = null; + try { + fo = f.get(o); + } + catch (IllegalAccessException ex) { + ex.printStackTrace(); + } + return fo; + } + + // *** Create Messages from JSON *** // + + // Use the JSON-simple parser to create the JSON-Simple object + private static JSONObject convertStringToJSONObject(String json) { + JSONObject result = null; + StringReader r = new StringReader(json); + //JSONParser jp = new JSONParser(); + try { + //result = (JSONObject) jp.parse(r); + } + catch (Throwable t) { + System.out.println(t.getMessage()); + } + r.close(); + return result; + } + + // A bit of a hack to create a consistent hierarchy with jsonbridge operations + // At least it does not depend on any specific field names, it just copies the + // Indicator and Indicated fields. + private static JSONObject wrap(JSONObject jo, Class c) { + JSONObject result = new JSONObject(); + String indicatorName = Indication.getIndicatorName(c); + String indicatedName = Indication.getIndicatedName(c); + result.put(indicatorName, jo.get(indicatorName)); + result.put(indicatedName, jo); + return result; + } + + // Convert the JSON-Simple object to the indicated message, field-by-field + // recursively via convertElementToField. + private static Message convertJSONObjectToMessage(JSONObject jo, Class c, Registry<Class> r) { + //System.out.println("JSON.convertJSONObjectToMessage: " + jo.toJSONString()); + try { + Message result = (Message) c.newInstance(); + for (Field f : c.getFields()) { + Class fc = getFieldClass(result, jo, f, r); + Object lookup = jo.get(f.getName()); + if (lookup != null) { + Object value = convertElementToField(lookup, fc, f, r); + f.set(result, value); + } + } + return result; + } + catch (Exception ex) { + //ex.printStackTrace(); + return null; + } + } + + // Convert the JSON-Simple array to the indicated message, element-by-element + // recursively via convertElementToField. + private static Object convertJSONArrayToArray(JSONArray ja, Class c, Registry<Class> r) { + Object result = Array.newInstance(c, ja.size()); + for (int i = 0; i < ja.size(); i++) { + Object lookup = ja.get(i); + Object value = null; + if (lookup != null) { + if (lookup.getClass().equals(JSONObject.class)) + value = convertJSONObjectToMessage((JSONObject) lookup, c, r); + else if (lookup.getClass().equals(JSONArray.class)) // this is not actually allowed in ROS + value = convertJSONArrayToArray((JSONArray) lookup, c.getComponentType(), r); + else + value = convertJSONPrimitiveToPrimitive(lookup, c); + Array.set(result, i, value); + } + } + + return result; + } + + // Convert a JSON-Simple array to a Message, field-by-field of the Message, + // element-by-element of the array, recursively via convertElementToField. + // NOTE: This relies on later versions of the JDK providing + // the fields in order. + private static Message convertJSONArrayToMessage(JSONArray ja, Class c, Registry<Class> r) { + try { + Message result = (Message) c.newInstance(); + int arrayIndex = 0; + for (Field f : c.getFields()) { + Class fc = getFieldClass(result, null, f, r); + Object lookup = ja.get(arrayIndex++); // yes we are assuming that the fields are delivered in order + if (lookup != null) { + Object value = convertElementToField(lookup, fc, f, r); + f.set(result, value); + } + } + + return result; + } + catch (Exception ex) { + ex.printStackTrace(); + return null; + } + } + + // Convert an individual array or object element to a field in the Message, + // recursively, and applying AsArray if needed. + private static Object convertElementToField(Object element, Class fc, Field f, Registry<Class> r) { + //System.out.println("JSON.convertElementToField: " + f.getName() + " " + fc.getName()); + Object value; + if (element.getClass().equals(JSONObject.class)) { + //System.out.println("JSON.convertElementToField: JSON Object " + ((JSONObject) element).toJSONString()); + value = convertJSONObjectToMessage((JSONObject) element, fc, r); + } + else if (element.getClass().equals(JSONArray.class)) { + //System.out.println("JSON.convertElementToField: JSON Array " + ((JSONArray) element).toJSONString()); + if (Indication.asArray(f)) + value = convertJSONArrayToMessage((JSONArray) element, fc, r); + else value = convertJSONArrayToArray((JSONArray) element, fc, r); + } + else { + //System.out.println("JSON.convertElementToField: Primitive " + element); + if (Indication.isBase64Encoded(f)) + value = convertBase64JSONStringToByteArray(element); + else value = convertJSONPrimitiveToPrimitive(element, fc); + } + + return value; + } + + // Note that this is not checking ranges + public static Object convertJSONPrimitiveToPrimitive(Object o, Class c) { + Object result = o; + if (c.isPrimitive() || Number.class.isAssignableFrom(c)) { + if (c.equals(double.class) || c.equals(Double.class)) + result = new Double(((Number) o).doubleValue()); + else if (c.equals(float.class) || c.equals(Float.class)) + result = new Float(((Number) o).floatValue()); + else if (c.equals(long.class) || c.equals(Long.class)) + result = new Long(((Number) o).longValue()); + else if (int.class.equals(c) || c.equals(Integer.class)) + result = new Integer(((Number) o).intValue()); + else if (c.equals(short.class) || c.equals(Short.class)) + result = new Short(((Number) o).shortValue()); + else if (c.equals(byte.class) || c.equals(Byte.class)) + result = new Byte(((Number) o).byteValue()); + } + return result; + } + + public static byte[] convertBase64JSONStringToByteArray(Object element) { + return Base64.decode((String) element); + } + + // Determine the target class of a field in the object or array, based + // directly on the field's type, or using the Indicator if applicable, + // The Indicator field only provides the topic/service, so we have to look + // up the Class in the registry. + public static Class getFieldClass(Message parent, JSONObject jo, Field f, Registry<Class> r) { + Class fc; + fc = f.getType(); + if (fc.isArray()) + fc = f.getType().getComponentType(); + if (Indication.isIndicated(f) && (jo != null)) { + //fc = Indication.getIndication(parent, + // (String) jo.get(Indication.getIndicatorName(parent.getClass()))); + fc = r.lookup(parent.getClass(), + (String) jo.get(Indication.getIndicatorName(parent.getClass()))); + //System.out.println("JSON.getFieldClass: parent class " + parent.getClass().getName() + + // " Indicator: " + Indication.getIndicatorName(parent.getClass()) + + // " result: " + fc.getName()); + } + return fc; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/PublishEvent.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/PublishEvent.java new file mode 100644 index 0000000..2a55cd4 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/PublishEvent.java @@ -0,0 +1,24 @@ +package com.example.testdemo.ros.rosbridge.implementation; + +import com.example.testdemo.ros.rosbridge.operation.Operation; + +/**EventBus event entity,describe ros server response info + * Created by xxhong on 16-11-22. + */ + +public class PublishEvent { + public String msg; + public String id; + public String name; + public String op; + + + public PublishEvent(Operation operation, String name, String content) { + if(operation != null) { + id = operation.id; + op = operation.op; + } + this.name = name; + msg = content; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Registry.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Registry.java new file mode 100644 index 0000000..cad2ea4 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/implementation/Registry.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.implementation; + +import java.util.HashMap; +import java.util.Map; + +public class Registry<T> extends HashMap<Class, Map<String, T>> { + + public void register(Class c, String s, T t) { + Map<String, T> table = get(c); + if (table == null) { + table = new HashMap<String, T>(); + put(c, table); + } + table.put(s, t); + } + + public void unregister(Class c, String s) { + Map<String, T> table = get(c); + if (table != null) + table.remove(s); + } + + public T lookup(Class c, String s) { + T result = null; + Map<String, T> table = get(c); + if (table != null) + result = table.get(s); + return result; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/AsArray.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/AsArray.java new file mode 100644 index 0000000..e57f11d --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/AsArray.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.indication; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface AsArray { +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Base64Encoded.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Base64Encoded.java new file mode 100644 index 0000000..9ac48a4 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Base64Encoded.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.indication; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Base64Encoded { +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicate.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicate.java new file mode 100644 index 0000000..36f8fcf --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicate.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.indication; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Indicate { + // if later we want multiple indicated fields, use an int here +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicated.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicated.java new file mode 100644 index 0000000..9ab56ec --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicated.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.indication; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Indicated { + // if later we want multiple indicated fields, use an int here +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indication.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indication.java new file mode 100644 index 0000000..d133a39 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indication.java @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.indication; + +import java.lang.reflect.Field; + +public class Indication { + public static boolean isIndicated(Field f) { + return (f.getAnnotation(Indicated.class) != null); + } + + public static boolean asArray(Field f) { + return (f.getAnnotation(AsArray.class) != null); + } + + public static boolean isBase64Encoded(Field f) { + return ((f.getAnnotation(Base64Encoded.class) != null) && + f.getType().isArray() && + f.getType().getComponentType().equals(byte.class)); + } + + public static String getIndicatorName(Class c) { + return getName(c, Indicator.class); + } + + public static String getIndicatedName(Class c) { + return getName(c, Indicated.class); + } + + private static String getName(Class c, Class annotation) { + String result = null; + for (Field f : c.getFields()) { + if (f.getAnnotation(annotation) != null) { + result = f.getName(); + break; + } + } + return result; + } + + /* + public static Class getIndication(Object o, String s) { + Class c = o.getClass(); + Class result = null; + try { + Method m = getIndicateMethod(c); + result = (Class) (m.invoke(o, s)); + } + catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + } + return result; + } + + private static Method getIndicateMethod(Class c) { + Method result = null; + for (Method m : c.getMethods()) { + if (m.getAnnotation(Indicate.class) != null) { + result = m; + break; + } + } + return result; + } + */ +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicator.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicator.java new file mode 100644 index 0000000..4e400eb --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/indication/Indicator.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.indication; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Indicator { + // if later we want multiple indicated fields, use an int here +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Advertise.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Advertise.java new file mode 100644 index 0000000..2e96db7 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Advertise.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "advertise") +public class Advertise extends Operation { + public String topic; + public String type; + + public Advertise() {} + + public Advertise(String topic, String type) { + this.topic = topic; + this.type = type; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Authenticate.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Authenticate.java new file mode 100644 index 0000000..c796855 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Authenticate.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "auth") +public class Authenticate extends Operation { + public String mac; + public String client; + public String dest; + public String rand; + public int t; + public String level; + public int end; + + public Authenticate() {} + + public Authenticate( + String mac, + String client, + String dest, + String rand, + int t, + String level, + int end) + { + this.mac = mac; + this.client = client; + this.dest = dest; + this.rand = rand; + this.t = t; + this.level = level; + this.end = end; + + this.id = null; // even though id is on EVERY OTHER operation type + } + +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/CallService.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/CallService.java new file mode 100644 index 0000000..0b7c3c9 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/CallService.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; +import com.example.testdemo.ros.rosbridge.indication.AsArray; +import com.example.testdemo.ros.rosbridge.indication.Indicated; +import com.example.testdemo.ros.rosbridge.indication.Indicator; + +@MessageType(string = "call_service") +public class CallService extends Operation { + @Indicator public String service; + @Indicated @AsArray public Message args; + public Integer fragment_size; // use Integer for optional items + public String compression; + + public CallService() {} + + public CallService(String service, Message args) { + this.service = service; + this.args = args; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Fragment.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Fragment.java new file mode 100644 index 0000000..139d7fb --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Fragment.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "fragment") +public class Fragment extends Operation { + public String data; + public int num; + public int total; + + public Fragment() {} + + public Fragment(String data, int num, int total) { + this.data = data; + this.num = num; + this.total = total; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Operation.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Operation.java new file mode 100644 index 0000000..ca4965e --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Operation.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; +import com.example.testdemo.ros.rosbridge.implementation.JSON; +import com.example.testdemo.ros.rosbridge.implementation.Registry; + +@MessageType(string = "operation") +public class Operation extends Message { + private static Long uid = 0L; + + public String op; + public String id; + + public Operation() { + this.op = getMessageType(getClass()); + this.id = nextId(); + } + + private static synchronized String nextId() { + String result = uid.toString(); + uid++; + return result; + } + + public String toJSON() { + return JSON.toJSON(this); + } + + public static Operation toOperation(String json, Registry<Class> registry) { + return ((Wrapper) JSON.toMessage(json, Wrapper.class, registry)).msg; + } + + public static void initialize(Registry<Class> registry) { + initClass(registry, Advertise.class); + initClass(registry, Authenticate.class); + initClass(registry, CallService.class); + initClass(registry, Fragment.class); + initClass(registry, Operation.class); + initClass(registry, PNG.class); + initClass(registry, Publish.class); + initClass(registry, ServiceResponse.class); + initClass(registry, SetStatusLevel.class); + initClass(registry, Status.class); + initClass(registry, Subscribe.class); + initClass(registry, Unadvertise.class); + initClass(registry, Unsubscribe.class); + initClass(registry, Wrapper.class); + + registry.register(Wrapper.class, Message.getMessageType(Publish.class), Publish.class); + registry.register(Wrapper.class, Message.getMessageType(CallService.class), CallService.class); + registry.register(Wrapper.class, Message.getMessageType(ServiceResponse.class), ServiceResponse.class); + } + + private static void initClass(Registry<Class> registry, Class<? extends Message> c) { + registry.register(Message.class, Message.getMessageType(c), c); + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/PNG.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/PNG.java new file mode 100644 index 0000000..ac7455d --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/PNG.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "png") +public class PNG extends Operation { + public String data; + public Integer num; // use Integer for optional items + public Integer total; // use Integer for optional items + + public PNG() {} + + public PNG(String data) { + this.data = data; + } + + public PNG(String data, int num, int total) { + this.data = data; + this.num = num; + this.total = total; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Publish.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Publish.java new file mode 100644 index 0000000..9700cbc --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Publish.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; +import com.example.testdemo.ros.rosbridge.indication.Indicated; +import com.example.testdemo.ros.rosbridge.indication.Indicator; + +@MessageType(string = "publish") +public class Publish extends Operation { + + @Indicator public String topic; + @Indicated + public Message msg; + + public Publish() {} + + public Publish(String topic, Message msg) { + this.topic = topic; + this.msg = msg; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/ServiceResponse.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/ServiceResponse.java new file mode 100644 index 0000000..b7be1d2 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/ServiceResponse.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.Message; +import com.example.testdemo.ros.message.MessageType; +import com.example.testdemo.ros.rosbridge.indication.Indicated; +import com.example.testdemo.ros.rosbridge.indication.Indicator; + +@MessageType(string = "service_response") +public class ServiceResponse extends Operation { + @Indicator public String service; + public boolean result; + @Indicated public Message values; + + public ServiceResponse() {} + + public ServiceResponse(String service) { + this.service = service; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/SetStatusLevel.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/SetStatusLevel.java new file mode 100644 index 0000000..9cd5915 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/SetStatusLevel.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "set_level") +public class SetStatusLevel extends Operation { + public String level; + + public SetStatusLevel() {} + + public SetStatusLevel(String level) { + this.level = null; + if ("none".equals(level) || + "warning".equals(level) || + "error".equals(level) || + "info".equals(level)) + this.level = level; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Status.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Status.java new file mode 100644 index 0000000..3b43ad0 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Status.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "status") +public class Status extends Operation { + String level; + String msg; + + public Status() {} + + public Status(String level, String msg) { + this.level = level; + this.msg = msg; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Subscribe.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Subscribe.java new file mode 100644 index 0000000..4acfaf6 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Subscribe.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "subscribe") +public class Subscribe extends Operation { + public String topic; + public String type; + public Integer throttle_rate; // use Integer for optional items + public Integer queue_length; // use Integer for optional items + public Integer fragment_size; // use Integer for optional items + public String compression; + + public Subscribe() {} + + public Subscribe(String topic, String type) { + this.topic = topic; + this.type = type; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unadvertise.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unadvertise.java new file mode 100644 index 0000000..eaf6055 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unadvertise.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "unadvertise") +public class Unadvertise extends Operation { + public String topic; + + public Unadvertise() {} + + public Unadvertise(String topic) { + this.topic = topic; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unsubscribe.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unsubscribe.java new file mode 100644 index 0000000..18b35ba --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Unsubscribe.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; + +@MessageType(string = "unsubscribe") +public class Unsubscribe extends Operation { + public String topic; + + public Unsubscribe() {} + + public Unsubscribe(String topic) { + this.topic = topic; + } +} diff --git a/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Wrapper.java b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Wrapper.java new file mode 100644 index 0000000..d806359 --- /dev/null +++ b/src/server/src/main/java/com/example/testdemo/ros/rosbridge/operation/Wrapper.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2014 example.testdemo Systems, Inc. + * + * This file is part of the Java ROSBridge Client. + * + * The Java ROSBridge Client is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Java ROSBridge Client 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the Java ROSBridge Client. If not, see http://www.gnu.org/licenses/. + * + */ +package com.example.testdemo.ros.rosbridge.operation; + +import com.example.testdemo.ros.message.MessageType; +import com.example.testdemo.ros.rosbridge.indication.Indicated; +import com.example.testdemo.ros.rosbridge.indication.Indicator; + +@MessageType(string = "wrapper") +public class Wrapper extends Operation { + @Indicator public String op; + @Indicated + public Operation msg; + + public Wrapper() {} +}