From 883c040c30d90c2c2c01178c847bb72553475781 Mon Sep 17 00:00:00 2001 From: pNexus Date: Fri, 12 Jun 2026 17:47:19 +0800 Subject: [PATCH] =?UTF-8?q?build(kiwii):=20=E9=80=82=E9=85=8D=E6=9C=80?= =?UTF-8?q?=E6=96=B0=20AAR=20v1.3.0=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 2 +- app/libs/unity-bridge-aar-debug-v1.3.0.aar | Bin 0 -> 23999 bytes app/libs/unity-bridge.aar | Bin 21402 -> 0 bytes .../controlpanel/data/BridgeRepository.kt | 21 +++----- .../ui/components/LeftHandleOps.kt | 10 ---- .../ui/components/RightHandleOps.kt | 10 ---- .../ui/detail/ComponentDetailFragment.kt | 12 ++++- .../ui/detail/MotorRuntimeStateParser.kt | 48 +++++++++++++++++ .../MotorRuntimeStateParserTest.kt | 49 ++++++++++++++++++ 9 files changed, 115 insertions(+), 37 deletions(-) create mode 100644 app/libs/unity-bridge-aar-debug-v1.3.0.aar delete mode 100644 app/libs/unity-bridge.aar create mode 100644 app/src/main/java/com/kiwii/controlpanel/ui/detail/MotorRuntimeStateParser.kt create mode 100644 app/src/test/java/com/kiwii/controlpanel/MotorRuntimeStateParserTest.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 836dd9d..87b08fe 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -38,7 +38,7 @@ android { } dependencies { - implementation(files("libs/unity-bridge.aar")) + implementation(files("libs/unity-bridge-aar-debug-v1.3.0.aar")) implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("androidx.fragment:fragment-ktx:1.6.2") diff --git a/app/libs/unity-bridge-aar-debug-v1.3.0.aar b/app/libs/unity-bridge-aar-debug-v1.3.0.aar new file mode 100644 index 0000000000000000000000000000000000000000..11380d7660eb1fc4ec9f61a9c69dabc789971d41 GIT binary patch literal 23999 zcmV)EK)}CHO9KQ7000OG0000%0000000IC20000000jU508%b=cyt2*P)h>@3IG5I z2mk;8K>+IN<5>;?007Vd000vJ002R5WO8q5WKCgiX=Y_}bS`*pY>kmSQ^PP2gnR#r zL%k%RV3>^UOn4M2ND&?_Bjk&7V@onRIl#ZiI8Fi`sx&*h->yda{L{6t!^jkTAuiOp z0Q5FgX0(6<}&F?)%Lf%J5W!ia6d*l9$ zj=fLha2q(CIAfB08up)1qiAdzTK_{+H_O%C>-u^1w0yW9(MO2>jn4IPbe8MG_mtmI zO9KQ7000OG0000%03~hQ^ITd003~1m01E&B0Ap-nb8}^LE^1+Nl)80LolVo=4Fq=x z?ry;j?(XjH?(Pr*1b26LcXvH_aCZ&_39bhTeE0Ld&+fNR)$Ug9{L_8)bl22XGyNM? zk^ce>@n3};o*W9|e<}Ymn>#zQsQe#25dZCAZ|iMq`+xDn_zyobH(Lv9%m0fz&VRVO zc{+L6I$GK|yL@`*+o8 zr7ab7!ITVQb2*umbQL*yBsCKZq^cf?v_mS%N@hs`iXobAFXjVSbM1J=0i-56vjwzM zX-#5U_(X=LtSokR>tA_YKR$N@+O=L}!h|tB2r8Nd%#MWM4>G%PP=GB6u zg}*jG&i13`CB~FU5U{dV3~>Mwa6`wWi;2Vgu^@-u$%~@`f>yfk*FEs08Spr{m1F2k zRmC?(6o?^d3@EH z^&BpuV&q{+^q(yIRzi93noG}LMEl+!sS$mh(gik9gs=JKUc-UlH+_GtY)=#}do;`K{(*Zv}f|Ixr`cb3LeT@w{(8Sr%|DSM8kJJtGS%}f~$CE;2RO69IYTT-5$wXSfn!uBWF29IGb3Z<~ftUr2pBq{so?> z2wxx|;$a~m0ROwLmH*d=+J6rXaR*yVCl9gzs-Ob=cTcBjoT)9T;0bmh(Njlj;cOsj z*la*W5=t)P%*&18yP6ysXB$k9J;A16F!``tqyk&1k(o zJ*&r=l2Z5fM>SzCdCJV6#a1R$yY!M{HnHq&rHZ>xw4C@5jhfB`JaG+f&#kk*5eo-f|rwYgrOWY)quQ~)fw}ps?e}oV9)H7KC)G?@EPw8OM<4raL4>&6jP&%F+Xiv|JwT07fRgJ%LP8e@{_m6*EtTd*&+1>|fhZ=6KV@2TA3!_5 zk5Z#;sqiW4kEg9qWsPVl)A45*GSvYIFo^S#so(19Y<+7c2BAkDP^KCXlq=jY7};Xm zU(FCtqB+@hv~Jf+%qtM{S!cKwD;2S+(y;{0@dgrQJDJlWwdQteNg+*T5nWf==-qqn z#qRRtx&|-j{E8&ln|duz%LI3Db~}ae-O$3srMSz?^yzJfn~yZ@lw1Qh>C%zD>(&G~ z$f|XhWca=U^)@LdleO@H%xlgKg(rp0;9SXGf%de~e0 z`orw@rCkEqZwnzA9TwN+9CGR6kGH`+5jfxbvP&2mTc~$jJ4^NjM-(V~FSF5n_uELP zUa`-;EvO%-$PAb7Z60!WIsDlC!mWQ{yo<6x_7?g}J2sQnJk-AuCISiK@Qlpzu67Tu zp??o4&S@^_Ncw)NPb7dfw7Ljj_S-;+P02)qjt zJSX!i-Qk*Ki69*gm;?oJgS|b*Y?z~o+QsvZoGzcy{xh#^*hNH}vHu~r00acf|4Ux| zJFD~&0yI`uglQ3Grf;A!5#-_J;q@^S$>0%90aVaZ$wAPVx>&R+(rm0*QO;IDovVM{ zo$KUx>Ih$>a8$+7$GT1J{}?^DIknZd{oULQG=6;Bd%o)J&B&6?2d8BDKJU7JJm;x>6-KNTyV6(NU}zkfit-+QYm;#ju(DD%%umbm#+XWhD-aQ0w@J z7AbDafDlWC={6LLQ=^2?7?NcMcWl09+5Li8%b8ZokC;n}P?rljy~ED58#ce{ACl#K zNeHSJSqXk|1lXJS7g7*KwrbYeZB)a66n^4{Qxt*C$}bk1X~OQZ?k+YdmdZNXf4rM5ao)%>Yj*Au;uov-M5GC{;Z7SO+FwnxjofkW< zqYo;7tNRl+kGCeC)IPOLYZ=HASLRAW(69*2V8tM#hUDR;r6K!EfpW9eN7LGx2Mc*r zd_l&O19Q#GOj)wb(sL49^p+K~A@OIT3{F}lM-&Y^%2$3n)UmC)G;?`&X2z|;d5!WW zRC>H+Z=ipe3WG@oAZ}{V_|&6Yj{VeyhQ-U=m3d}Dhpb-37KeD~2+q~>z*YAJcJZ9B3xRR4YY4M%y4sZK-wKS?OE+eVdstQjR<@?T=p6cX;tOc7BBjo~K zgpf~5!pfh2bW78MM@yugv5NC@6N?#Z(*n5F%6+Rs)q)_5-lrpYpe@r0*1)`wP-4^A zEL>#Jo8^#5YT(h%h_HAQaWyzB0~vtAxkkgJQ{<@7g;KNX zWYleEC_amRUKkls%;1R_d3< z%0lMvgw}%zkjqx2;g>a@K`OXod(H0n`tk47IHD{~orMBDuLK6`FO#oX_bTR&j+oSu~G+-}z_HZKUCjI;3K#hvBu-nEYBtJT@Xn7CRkqH5kJ72UO1FUlD&N zVyU&zpiamccu>kMO}`TomG-wV`Tm&J$TXc_e%RA^C3XE1tNcsM27g&XqDFe8=8In; zrB(O!4_3vqAMs-k{73Nh<=N;Tb&H>ipF`E?I%kIT3}5-5E85zxO%=}8sEWvR3K9M) z0mxj^r#23I;S(&n*}jB(@?epSYUG-#uzej;$FcU+JupD?Hx(A3DuLWGV2QmxB{gM# zN*lJ|Q9dq$db1g1SCK#77^Jk%&9q$>W3f4|xnO^nLJlqvMGg)kaTe__zJUk1Jb%B^ z5tch%Fzf3SiaX{k%0!N{7lS-PXiBtIisexGz%X=J0ZW- ztyc$t%Zp;jpgOBvH961w<)25JbouK z+&#sP_hKPh+_EBrY7X${5}?QnBhLQh!IUI*p;XwnW^J{DGzm8GZzl*7%S)GRO4MM&+Fzd90Yj=FmJ%3XRG%&jtGI zEklDcgH0XIDqm}-Q^u8)x@eU+Dg$k0KyjkDsDjkTqVCY|5OlVAoHD{DuRV(5pB(bU z3VNEW$%Nj}HL$o#`7VahaTTOqDo9nmnj$21mlv_;u4iS3MJ5iOWSuBgS;MA2p$a89 z9#r;U;W91G>(q}^U;-#{*}fO=x6hb3FBu|l6wDg}>Ej)#GI((AK}#4U5cL{9=g4rg?3y1@=&y7;jO7!WvygpX zFy~#@a#8%JS#6@;4RR|#PBJltjgOJ=Hmv)78)LVjZKPwQ{ypJNN{q1<&)g!B^fmmGjz0SZ&Jh(TAzATpzxv$etJ@>{NuGS1C_r z2W4Dq`?63nX=1GFku7N%)~S|sW;ZpS9zrSl zyB05p^7G)JNgT3O;M2sE=4fkcHq`3%BM&PG*&4K$Pa5|*xO*CEnp4UpN-4Hg`_=u> z{4!-GbIQF|UsY|~-nB3QIlW#GmoCFBhrJ^8!ClLYwLpML%#_`)g%u5xZ^Mf2gm_AR zt1mPY)e*4|EU)-&ndPO6fK!|uVPDq~YkiHYk?ttco_3*6M${Tz9Iu-Q6EEkY|GiM% z?3N6flMpF3z%f)YpwH5J0`hPPG+BIW6Vus*hXSvQ6|RYtI_djU)sS^@aL7s!1C9+# z-_9#2Q5))(EY*i=)y!Rg7_#x%3B%Q%(`sK@DS}+xG9v8^V6~c7E;kFGo^qQrG5ReD zqg*EufF!k^Qy^9yE#o9D!T8SU;k9t<1A!E9DzaL9xDk5`Jg`t6^w^6^!Z=*h7g~lVD!of$l_6HA)%b@|3@4_yNZA&;LF z8j}rB!t=F}&egFwY4=i+|IK#Q|dfY{Lx`xE~pP#`D60&Jt71e@J9J=1w z1}Ij9)sW)r~NA7 zn}vnAM^IB)UUb$yVaX7wmqE=V#8|Cq1|p(D^EHJ?+hV-LD!(97*>^-my{BMOkuFu3 zU6GCjM0iP6m|fst;+Sz&m|MhOvh?XPpr$N?+`9PbPP4j#LKMohMYVgv+^`D`Q0Ue= ze}>THgci$7b58Pzc5NgeE9Dm$!;{^paSzJxEXP9LKj7@=()2a@K5s|Taz|Ye8ku&D z9SUQ*c7mX5rUf4=1%^&%Q6@fdCO_MQ!FvcFJ%gXjHv?P5KOVraM?WHteyoYS|A6`M zAN&lw+4~bO{QC3DowT0y#OH1>7<4H4#hFSF`2%kIR@&NCrhhX7($!?X_@YSWhZL{} zTkIW3MA2|MDTluk!4$1xFC>Og_P*~~YJsGhN=lSZXr#j-@NDbHP$T4j+gYq{tMSr# z&~?cUoc%?Tza<{=YxcLHaDb3G8cxo_q0im^TSR1r&~V-xz)0u~8n9CVUmz^X@t76d zL^K2Z;)#CX*lzOeSX)FL%!zRqt-XqlA{eJ5I+`{@N6UTUuYn|>@;T6SY_Oo6w*J;r z^n- zR4O`&SWeN$?)-1;K>1?Fh)cv)$;gJ4z6UGrzJVA4_=;U)4lgyd@5|z(&($jm-#)}& z9{R=zz7d{jxJIrkt#_##JV%p z7=FPS6{}K)bR{2%>0LljHF7>(Mum5s34F~61(U*!l5UF;p+trS@xY?Tu!(Re{9@xE zm;6dmlJbo_A95k)?~JR=0{lsqBkl4yuShygzA{3wFGbuTW?_y+AzOk?($e#0h)rO^ zUWN`0o=l{Gpg?DY;PBwagj-y0s=R5x4X7KUo-YW^9qHW#q5xqZ`zojeYY#IGUzDl3*Pf!_xPWFzeD5aqpuVVMYtqVlNs3C}c zZ|+z(vMOSD<;|!3AYZ~(Z2R#gU6_<|$}|AV=v5FS;|J1irEpXLk%$922U+Gq#@gK( z=;h0_DMP9tas$=e{h>t3?JjAuZlBEWhnP|nnayA-WGek&3&KPX3z56=R+;%h@1lY( z)W1ZRTEevA!h8>3-783Y5%-~{q2SUbotiu#r|AdXs`(i;>l+zeO?1z3rgaD1xEgao zs7OXiiEdp|o0n$eW7L-&z+V0Dz1x9ZuXxAY)|JWh5S{3W%)^&{fckfN#%~M~qsg(V zIQJ3h*io#%ym}5L;ke1PX+*hrMC-kf?hu3Cc}0v661D&8B>J!qhlSO-+IZ&a*BPPJ z?Lv5PcP}yQ*0=De3eMJA-0Fh9CY0UyS)U5 z)2J6D!~c*5y%?v5OEUfWdZ4Ph$8f036jh}7+wkW$-lgt4NIa?xQj;6wE?!VX^Uw2b z-nVJAoBBtg{;l!n3y^=0ud;iWi8a@Zg6Vq%)(6Qjc*ukv)A$xm?lbgWW(4~K`P`y} zUqJr%_Rs0Hl0R$mV-9`Qt9D{CZ(XNi=8w4VmU}DajRe{*0|o+u{(pD;tLW_E>?ZE)=xFL>p=Rms>EQ9-2fuOZ`pREb(La=WJTjW$ z4X;9?$u^NxASJP!RYb)RGt(0XV{|v$nA-&{dLpB4pKq$sOemrnXoTMUN3R_ue@cpX zpJin^|1#)jzrP$mVS#Wuu*D(|^|YbMM#r$(Yu{TxYc^ym)9z@`3t>U;y4EuMEE3_# z*KrOHwjx&j%ESs2j?|nSczM<3#mi>+Pe#mg)#xkeDgJn6_Esy z(;a`9$E?muvYnRa^vE+j^wUHm`aVUbzEoqwDsL=FVdfgI26&G#!h5P!lvcV5@~UwjBD7z|%@~RvBQ6 zyjux#K1e3Y7>TWBrxo3eItSj}>^{x%v8kyLL!%Bs?X!W{?9Zt>gjkC?0B;Lao$nrV zuTi^q$R9qET!MwK(Qz61wUyGio&K;}QSLNL0`$D~h8yY%D;42w@K4MB1aGqxri!!p z^wZOZ4f~AU(INRjPdx3PaR@>Vk%X15cU`inW_EBPDPKu)iLCRB{kPkIkgpJ8!Q+PMpXdqa5BvNNg{?CfuiVMTfBNi?&efjafl^Zh$fSpM zQv^+VXs&{m)IU>v&c*l9+nvf$0r+?!PPD9(o|W!gqugJ*H*C?~F2~Sc6H7Tnzhi#M z94-s$5q;Ii8#SK+0I{<2q-i44hrUw4`^b?6%)qG-k&h0(V~GZn)c*-Zr)ICf+{>R0NmaaOMHr7WrekT8XBr@9<#4CdG zaUMGZ6$23*Vj>(-6;|fic`?w;!}`)sO!IU$E6yn3#c%p1hBP^nWI0Z)(J6V7+Np#a z-cK@T@{?^61ziBx)Y;>gj)7sQxG$wae%FBWsyNk?EsKL?P;m1gK+t+<#YO;A$Dz?mWcX5P}jKEZH3d<{tPnv9V z-_*i(-7RGirnKIxH-j@$+n>X0SKK=PU24eS)v{zAH%XtPd2#GzyW5$Xn2&?~wxNFD zaT+g_%GvNRae!LQGx{+l`|Y}Qqn)>|!v7x15pj^Rqvlkk0_riuNQVDsn1WQtS)usk zCxgK0x|LUPSW7}B&s0g3K~j;y=Hj^jF~<%=yek=xQcH&--tLhggP-qBP@S<-wyt=g zvFPNAy})u%^iY_N_wE!dYiS{{nf6e9IoccT>CtbQVH_dXVmD7sWvkW4aKSVfQHiha z&@#7(PlxxU(XtFhu!gKxB4OdQQUu$Zw?S+iFDav&s`=OAS(J@fVfYdXHZH4ZPw4|{ z4Ovz9GBoi5YH;MBT(DGd8x$cl7m@@_JNzh&*NurUHY%bA4~Nd;)MBGN$_nu%&N@@0 zw#mRCc`)kLTXnR(&#Zo=HVMqE{Dnu(s*xhGAObKu@mfNpSxTb-L<4Y z5sUwXpiC+z`>m`Z!gK4$YvIhBX0|sZZqm9&5y=ofId6H4M3B}W?q*WGy4|JnFvQU^ zGhe>I`QdZ+xPvKXLNh18?u4YzmLBo4>FR7fMZKu8fCYNNZ=PYDzGT`W7?}lgzAnJD zDUU&0ESXq}Q=Ub4rM3uDmYq6TM2<=^Rfdf&NkW+-DpvxNGpf`KQ?`>T*+7;mD_LfW zDhW%L;w({OkvOW91yh!nDp^H_$~IAkO+-iRGtx!n29on52(4z)U%3ZOQvaBukh8OL znX9XEl_C(gO|NuWG7pE|y-6+x+MsroVt9;?3DcuVH72#kM>IyGbG}t?Wh_Rob8(D| z$>7+m0;k@qNg8RbbG;(W-jHbioHBt-tZuKQRp{`r5vSgLp)5?hTgK)QMcJ%1vQ%qt z;!^0BqlfD|u3iNi_n9}c=R*%tpxPg@Clmbav$D+?zl#xqR+F!`9>{Q&a&Yv1k+oW_ zB`63)Qlz@#rDGLm93CE~P|_}0%TEN74JCx$GA0A!n52uyKNcvZt$!xm0Lb+X?A1J) zJ2z*7{NJS(yVnn+-^#`~S<-N{`xNvHo`YID@5J;B-U?egUym0LU$tdo@CUcM$Ca@e z%ElNglX30~_4H;!32Xtlc4cD@H(GN6`}hA;!}ZNO0B8wH$7*dxnVPRl97wn*AmJtH zb-`G|KOnc$g+o>7O!JivvZAO{Wr(Hn*#}N|@6RBv_tg{Tr<@UUQKrtcidsTc0ainbKHqT@pl%;r~e=rXXly=Q$9;E66@#d1h z7L3{RL=YbJ$z~j)8aDRG9O%b_r18LMMj$wjE22jqcy*(=HV$Wa;eGZ1C41k8qoE zmU0Mi|F@Y&!_Cyz$=1nQ(b?kPGfkX^p*o=@R^aZ1lh@aFY82{Z8JjW{%t{G{x^)#q zMci&KDo(=1NuMD`@-e0t7qLYne$eOqEs&7Kt~!08Y03UG^2bokIWJ4iXc0RN`{d+{ z->>Jlw;W?5NF88&e9)jr-Odb=-<$wT%i8S|+IiNcSH}*$w?V^k8*2O3+ao%(##e$6 z38b+QYSxs`A03Qu_%vb{+|9bpwL8-3eVzj|cNkx3rc1P#t+A)5`8)J$b;<%nLGUkcPTFfC3f`Ctr>BjjH&_JN93 zd2fyKWrT;;wpH8V3|=Qoy|%6RW^n&TgOh{-FL=-Qh&Yae?v=?QPg4&P7fZq?MwlsE z6mJ^|0)BAw#w1iOIU^}8poAi4!b+h?pu`epnl$j!tnyY1-7D*GO6Sn9W*u>#^?p$&b;&VJ8qK}Z5bey{5&}D|?HSF-}ybL^`wX9tw_`ssa9P8mtBvB6V z%w)CK4Q^bz^0a$YOz_9$cb|^wjrt?c5%TQ;K6DinunM8dr!ITONL}`plIopTz}lp0=Q z_JOz5K)xL-rWBQFtV@$zW@Q$z+n8-zRFJL>wf=Gck z1jDKoD}e7RzdG{SNfDOF)2x_;a~oA)98RZQI{O)EzbF55NsU>qGi8~BlsOb`;_a6) zX0DXbnR!5>v5%*|uDnuU%&6GiD-&lurpX~8H0b=k0qb_h_{T$$%Vl(}APq4sYdDW5 zZ?ODB_AJGV^M`rrBiHdXbRxD;{glzf0s+FN|lZ$0gGJ&Lu7ijsP!5{M9Q*B>IpmT(Fe%jUr?z zlyQ>Oq^^*^GFMD7&~fVs5uMCSG0-x_aLZKi^)O@7SkEpA)7?y?AvsbpylLj z)WwSQ(3H5ub+Rvj8wfCHBmzD+`$IqB(DMILR9IeLz_*~GpAjFbfdTA2<7=t6G;6s`u)6H*62P|-}EhzEIA9Ms};Nc2w&KPm@Ci9zf}tda7xW;Kae1z zJ;lNX^;dVz{MjxI3bfU#0!$mKy`H~AJ+2Rk$LSgECq&no*(6ovzQoDb^z6e7_A#T` zx)EmKsV{Ezew;AXJa{!i|H%`KaE{$|jgu0XxNU}Q-1rp+N}QVJoE%-Fu_yStXtuNa zmyPbl31N(@fkKN|UFx$9=lZjxIJe}tSaro`igPR7D86xCVH5m@Q7GHQ@&y*on?Vto zxG)aCv`pXLa0~}b1M#7o$!IHjDQ5}dX4=(-A+~7;A!J`@Db>c~^e264#IaT;G`rex z+2qRK#7QEOVz-=IAjq#d{WmXM6*>+^w(7@$R7tw_IZ5@=$tlRe`4tKT?ZIc1rxz2} zoWO*w#_+FM?Q~~)r{$Za_?+RGZRvM{Lw}oT2r9RF{N2DV#eG!_<+QfCpv-mFS+zuS zfoet+Ay>17Xk(4DRj)Do6^g|>MtIi0i)>z@f_%9)Oxsz+wLOKh0ER{_!`i=vT9uu} z`9a7bg3xHubd(2T@QIwe1X#L=vtFF%yvom+Jgd1xba&>A{Vsn|{Ur9?_(?aj_(BDZ zhA^jG2hQPIiAdN<_!6z|+ENfX7thh5KsI_QA}tcxeX~=w!_aF?v2d!|Qi35#uJcn) zzbfr)Cy|k)wc#D{&80O9Vp`?pN&4{(X(v=q5SR`=?iW*muhnYHGpcd*=aNg&UJ*C4 zR1(rwJA%K7_$|vJrFch3;LjO)Qngj402!2~q0Q^{YI~kq&o2CkewnXH^kx+ieAS*g zX|RMnYqtW(;$een66KuYj&BzRX^2CexUa0G#7l*f-r}3ja*7`YmCu{m3A31KhVf>U zFyu8I)q*BN{*o(g;O^t%LAqC3^Xk<_r+sjKgp%}-C#4h`ik3mc1dkL#M9@>nT<9M+ zIzpxy%v1kNk6pD*JLt^603>?%nSxt4P|n$0-5mCVS&)Sb~Dqh!2sJK89clbCOmgo zAPf?)H`sL{q{+raL6_Bu055|PPaYO%kMr2%VA6}ar23uF9L}r#a;w!$A#AbI+0uFd zGGjz3;#=aNbzg?H3D@DSNM3yVw&xfzLK%}m-cxy4h3?M^cbwSV;9DF6PQSMA(b{ZM zV6@n$etA8ehY6E~UKr5VFCa%GUcq-S9WTryi`dDiSiUEO#K)(Bmic?{IuA zKA0yZq>J(}Z#dZN-8K^+SfD=+vXjYn2(|fNV!Na&W!J|;vjf_xTZnr)~<|NiXJJZpGzmTz44ULK1Pd)@paW?AsYt7{{<8e1M>f3zC*z# ztRqch4sZ_?2=mgOW&3;CYbyFSnVlXsTj{P`&?5Y8Gv@b&VC~#*UjMz2w~HSx?l>EN zHC;zof?so_6868uTzt67L3il!0h~=2jA3KinecuP;-Q(sjjzNEc;t7OdJNWQ$0qDk z_C8Zkh8Gx-j%@sZ{7;h0?5;{bVM9RRC__N-|G$x3-NVz2O2y6D$M?TsKD&(&fOY&b zcx&x#%>@}g5(8e28lsuLXn6L9}Iy2rAp?MEUP2i?CM=2;i#&={6p}(u24&$ z3N9L3^#)?jZyCv1-+2hhLGYW*eybGSq-x`KiGzz#YUL{(9&Rgc09W2R5eruvQ|n-a*yOJ|nmZn#U(5?pel@n(2MlT&JGCF#U=^Fh@X4jEoLJ;Ws| zIQHi$hgvakN&lo8aN?hyv+CCJw50*=yDEQ`)kX4~AZMeKg(Y;WB(h3LjbwsD1JXsHO8}QC~Xr=2a)xg1TcA!wHhfM;sPwb{}xFJnPe8f5@7%N2E-vjyeffMIdKT zCQ~gXGESn-1M#T17P5IY_@bFeAPU!|@YvMCl#1VH4XF0OEe6X8_ufp+KYh> zPd$Q)=XsPU_$6LNJ$|%6BYQJQVs+aD5W4DO+V`1vOf=4c}1I#75trQouRd{~jOBnprWqVs6tgocG zN8#1tJX20_^ZwiXw8_X}q3R=UHEQ>}Et9ESZ`w7Sh;&nBt1UE#5ny2p&)G<7N>}C* zLe5-8^C5ncg2^zcSGZflIhx8hJm@zErFM-|!*18f$Ue$MyO<}mB)kQB_BrwA^+p)k z$k%g|8kk8w^a@dB+AxtRacO_zuNr%3Z*OrR@OLpGs*%h=;guzhGea`bi-|y!ZM(%k z)OLiO2l{o)FC9Jm5o~hsZ6vB&!1R%BzJ-;ahp8zQbHq3Ptt+sbu(g}j8VE0`UYD;8 zHv_MQztb#R)XVC%C{=Ui2#qANYo`1h8E0Klw;yx!QIz}a2!B_y>?TS7_-MIt5dWq6 z_+3BSej@^L>4fri1(5yi{T%!`m$;{o62P<)=k%jeU!&fknIPAB0>%z**>^jCmK3>5 zrmq32_wrm^+Bb?kqZ;R2p}}P(>tmHm+NXvAQ$ zR@Gh>jYvAFsy-qtA1L*!oWg$W+@=9=q}TTC>_RSw#_{QtPkc2T)wX}bgeyDHdFy-s zP$J>V>g#KWF1?T1h_-p2JvX77yp4G9e2fD|@=FSNNA(Iat2T#!?*~OkO@EYqPY;lL zO|xZN)4A^4OZ-ZuhM@Gx_eYHFDuv_Io09mI8dF`awWNW>+dhGKPXAV-a7}we ztlJvQ-S?a{CypbdwuHZZG}eVI%RWWZTQd9&*p$!sZUdh2us7C8fy;c`oJ;3AWh)jj z(I#8=THCTnqGUn7vpJq6WhrkePSCQ7eFt5I^{=%pb3 z97pjLBkql!piox-{zZT2o5ek@c)nVM0FOsEu0Id=&!M@S;gwS)&hNlP>pIStnR2~v zKU|pZUu(K#Dp3TjC+>?#ns%Ao-s}Vv6$_zzfR1%jG~o@iHYO6YrviEPZ~U@)m3;KKfELc zkK3a;SJA<}|4S1m)D&UpjLE^}WnC0i#FKe+mCP6wq$O&O%x`ei_ipaN<{&cK42AouSchZx&aT_n$UTF{L?w&3wbU1AC?IeKn0h znrTKA#5*j`6FEbkzjc4aoNf@7ZNU=2Xq}YmU1aFi05o(T_U#<*(ko7UxYO)+Z(4+42@aD-dj)%={3KkQgqb1~v)*;F!I^|ITgVE0(W z^HU+;cNrtLEQ*E9QjU&pQtF)xGpFZHn^kuB&e#|5UnzIGJda=vl877{)7{P8hCn~(fxt0Fa!nYn!q*43TvB#)>(IEryWUuPoo_al3==911pyv1CvLRhWmUQ-NFpcm*@k?x8I^f zW(@64Mr9YGXn}EHl*qkM@HP4X$}K{>b%+o5=w~QcK5`%gY#;e7(u;f8K>mSqcultZ<<=^FcADu^17WvmnNe~7P`Lz(oCc(MKx-1U(;u1r80 z;54h3c>o1)8X$yV&hn3N8tp^?rLaDkU5tRKV*BvkSf6M^0Hm^`CJqwZR){ryZ>Prl z*&R?Itytx8@EYDHEGP}HVHoTXt8ErQ1GF~nMFh0~gy2A$cm;8{ym$pU@W6n|uRmSq zPJwCv{2(a^iM1ad6a(mo2FU}A;%*6IS;oL_u?>ShoIrclege=6Uc(UBF1A4y+FS@b zW~fu!12lF?=*>sE{Ic%I1Y9!@_zL7U4?qI`VKqv)&BJRL0c*uNkN5}zz0Cq}fqww~ zUqL;ryXY%Ctp5s8Z2NP!UUwOQPKpj2H+Mu*O4tEI>yD-doRe@YXRtNBZFKuUReh#t)tJ9a5)lSlTP?W`JXo>3^0mu!gCHlp z1nA6((I&CR&DAb^46M}hFV_*lTveq`^qwp6w4 z;hvzPZ&CXw(F~W#J9f!&i@0}aqa3$-+)Q>2gmpPMiUCAFyKNWhl<@0l&aC7y)!n%K zk2nl}{E@Qyk;kdJc7O8KGvI^ZB2!N*bEbU9jzq)r7krJeRApdOcj;VY(h$kQ(gUYk zQq&2 zr5&ho{f9}yTnJ}5lw-c}z1qOcp-|`WBb~p6Eh~egmF1`c+h|uN!ZxE}*%WPGK+O-t zYPid5jDH2njH#5$NTcQywJkK?Qc44Yh+D5uf$xQ$_Uz>iA|0YfH@k;dZ zO7`*kM@jjYB1C>0Aa}SSdAOl?_yYB8NR_`smCxexDNR8|LIM#v#6#T;Ak}T-mU)3m zep|!)@$+_o^@9W?h?iARbd(l4TW@ z$>4h)FEh=*%2OXROmU|EX@xYLAZPe_575_klgWW5nIJ!?esYITC>llI`(856OQDvS-&8XURIpmK4|Dx%4cbTK;Z;84l+Lopg z3%DmzMh4n0#3?7_+|tELn+IS4%>g74w?47=0Omm-0pM5G{76?JAPgSq&wq>CBMH{u zqLp~DZ<5?b_}n0h*a}mDFaHBS0i@Mvtld+ zC=FP3XFJlpYiS}OwJETSdwh+!Z+$%LAn+EZw|)P$!B}&FNie>nC>nQPYg#~Xa8@L| z_*m!7t|pg$D?mxlmL;0(mp3B4d(L?%4&jK=p9UsLxHfaU$8@__b92Y;r|I`}i}eao zSgoF%qj~94va)@|%W-2omYa%cvrKQ`t3}2)i@WSpm`c8hbc%XU!DyKRrX67HG!0?o zb+=8Tk0-G4vWB$$9lb}e0|RwCBX0DBr+r`^n#A-%%W?&X-pev&;>bUGe5bha?}_x{l9>JxS@ z%_l$X#F_W`$9UI3wEL%kz}&by_Q?lt?%RpmRl#`I5218im;YZe&V)Y^nsWu31h{yB zkU&-e2*3=p02tsuV8sU30QyluZFmj9f1z;*%on?679a>*GwsCz{X;x*j96bxE?7|T zLL5tc&MniwpvV>LJPt;U{fC!mKtiRQRZtzwlE)#z-JReX;Gn@d1b26LJ-E9kxVyW% zA6$dGTX1)`0GoU7!)|@G`?NFF)iV$OuCAV!sjjYH53rPd!08KA!hmB2bS*@VtS5`$ zyZ^?#-;Wv$^q+Am4Gm5}Q3wQ}YV{*3(=OR$gju$(*UvolVJ)THO-?-$AwA|FYqBHF zojn>P_Qxb-kJtQ0dXH6>VK}NIw#999cxM26c%l#N@s2?+@pWzp{v~z1oi!2!b z0WbJH9IPJh0bFtS2mO&|pW#1DaH#hH4!R4j>tB?LIN687u`&yVzxI3cx*Dv*B0v3l z=|#r+<|QAddo^IU1?xRb?zu->sZ+o2Qjzu11*v`gMY?#Wd?Ug=a%`GNmW;jD_B5YD`_*O@sc_9EB|$qdm+dR4WV=S>@D?c6omiGb|( zQpOLBBQux%{j7C&g)NL6R!o9&{eZ|QNN=Wv0_C$uwHO28XJN+4dNH3=$md2n=hhO! z0)bM0@8@MqBn8P`B91G88#NdH?{rv~d$O(YaM|J`o;#CyAWn&kbqey__BI? zV%*d1H#e~Sq_XKz9e9%2puX^UURrly*P5a;*51RIa)nuA+ZtR3_*P=UU`S|CR*y-vs7CM z&V4PEab}!X0sQm#fXrXKam4n^dVrDQeZ?v7qY(&0vn_bfM931wCwO$jpfZ4iUEazP zuJ$@nJ{Rf>`R$t|f}zfyq&c(1~MLZU(-yuMQ)D^%2dgbI9ETpZlvp zsUJ0WS7MghkVbj_eL^0|%u#=BywVWY-reg1q|-+vN|xndv_imBr((`KLJaMcHF=w^o{o3OUOrQ8k^zA!>guLFIIQc%{N-Y^-UQl zYgRv`Wk>OFlMVuY3atol{v92+DIbUDHe`Dr-32iRe%8z7>*zi52N%MV`vj|xlBI`R zqktChZM3f2vN#sM+k#S4I|Am;l2*Uk>^l*9d$UAZ{{brhnyoY-T9F~m=L3`;$@Q~h zRWj&xwjpiYed$i>TKK_tL))?!S?`zT?p`8PMSqcx#f@)I=5vs5D>;j*+pw0J4lSs` zAz>yjv`vb2c#bNDoSNICYDG6C(KD1uDze0^WKRypsgL7;dvTNFF%=eIQ|(V&(lfNX zwM)l5$dzh@A;SWRvnnm^Mr?}NxFcT^Me>GB{FcSsM%wA6vNfB&zas!?yCQGADQ%sD z@rfbG=jXsduZeFnJeO~}dD|H4taXBhHOUx2AW`3*MYmHu1C466obZML$@6GLB7&bU z2+QJVxF!~7_APHd0{KX|CN$>qZ_ALA0OFd_w1P^r42LPYi1#)l{IFn;+W;x_RWyF4 z)M7oLmPnnzcs@S)4m#tvx=e_VJz=k@;a+Z$&diqDhHLnjXPYJBL;$vKoU zUt=5*YTH}Wezaft*$lw-=A=AtEPa|==Q*e;@p;zhBT|uv1w1yilIu=AFZHqv2ZwP7 z2iM`}!~1-hX6=dBmCk=}qy|jUCXH%TS>uv`FaQ!`nQCK*hR26Lgg{ZLLKMyQv9h}l z70(!NW{4$zK`(rc3s-dki+n{68=5nP^88{@|l`CvSc~h;c4&RqE zx_h==3bn@S+^r&}uILBksK{i7pmS*iw5@o%JFe+EQm>JuU4U$j-WGp+hOFY2W|~h# zYZ+9QG+RGIIMPMAy7=3|^Flz`tYf4ejYA^&uyAS$=HuV}^PO{6gqbXMuX9Ko`79k9 zF;3mN^8{O0Zh4kY60`H%{C=-#TpaIeiwpE!);Tt3+8!G}3VtF(bvCqZ*)jp@v@R2| zmrkP=WolZYnvhJ^%Em#tX8UAx0Nt+viY;DptP?_0w7&^OvTfgexyuiYIyw>Y0Zj38 z`nK*MFvSoWk(z8neu7|Em#_|h5v&+53^$YW=DfQhcBe5sbC_v}rGnHPSI#sI^cHJX zT#r+YqPzH|7g&N8Gx@dDT?cebVDrYU&AQ<^tf?r61#v`-PV_5^wbA;cjx6*dtBl6X z+=K~xxCo7&LO_ts;%FI{EJ;kfnF1{z4qwu#RJU(I-ld`X*HN8|87(f6?G*(X!bY`7 zr4llSdld07NEQ@>n60X8tnbP=sNz0Bt7xSAw$Smu%N7;wfLUA8)L2+l@{Q_v4nT_+ z_>I$~N#enUg6Zqwy+0!kpJ@HyqeP}t#IAou)~|l|rQ0C-d&4rZWLfYmPPVh`@;g^S z&*g>Ho6;UHP4vA4y~+#*a-Tkcwr20i+#fd2#!YXmHzhAd`hH}e)M*Zc0{1|qlI?4QC?vM<2bQb*~=EJ z2}jGRHt9l$+j+3?-`Vo~IrH(R9+EX_{Y7Zp>pHI-%m!yQ$(hpw8J4XLx{xnGQ_;60 zjyKCW@dVH%EkJ87621GO`IB;~Hugq(0NXa^gOn-mjc8z((LtcBghJB_F-{t9+lJ7C z9_Gd9alL$D zbf@7V$)xEhr)aWC4Gy*&s>Uz5GVs|c&;$Jo`Q2ycUwZl$uXoKJe}#3w)7DB|CKN$@ z>FB)%9I@`4y`@8wZ8OJgQXMP&7Gb2(p*>^G7>vQO@T!r?-f&5+FCQP^8NT3|n%oK@ z-gaF)4+O&sqyOmet0+oDk(Z6jOQE&3+#oL0Z}r}x7L4%9#%qeD7j>WWFT>zQ!&igx zN3_9tk_yqfr{vQFJr|!#XRPJb7w3%GTr?n3k6CQNtKEH^9qtRhNpR5XeQ7tQNN9zq57B;XgI1G=T73G za8k1&%s^(Bi2=A;_1v;cx}`|x_rTmu__5@zk{lZi_lrCNS-FQE(sUBngz6AN(7lno zRz%?jIxk5^n+?6%Zv5bAM+)JwQ_mF6f+LMM!`g2X`~8b|HtK;dkrx7mY$Bi)oZlcP z(7h>_kAq%o7xzcj>tZ31@)q~YBMdnAsR*I5oY~V1cHW};{&CVJN-18oby^nkTtilT#vl>evojVb1H@M$&3hVR@XvD2(HY}J z+I>y6D>hNBM62Dp%33nd#9;*0$wfSDvqYg>$r(k*4=3enL9pbg@7~1wgig88r^&9F zhsdWltgw>(S(?#s5>ol7OjQ)1T1Xjlu6r2){VXy|fxEp#ArYBV^5Hq`rNgxAnZEy> z(8K)aC1We#4FiN-eOAgcS%HeEZiY88o8^va-tljFMw{7reEfcdg`|KI%qXh4QLO37 z^k2Uy*L&OaKjCB%FMK8|_qMDEK7c~3kI%4-Hy1TjmR>*XVFjUQ^^-AeiTLUaE~RO5 zCa*^e`^Mws?M)FsnaS4W`*=1W+!QUF9~JJe5xQ6OOp>?zetWjfgr~d2Kna^s+M8^% z6~6&jn#dMEZl>XXAGrp5F^(*n|89Zz?c@s_*2Jx7J;K*&QUtj+gG`|*XW+AI{_s)l zaZxdy-7Sk4y^KAKGwTgf7DPeZM&)!V8e{hwZX;6`jQB)E6w0}lY1i$JPEO<|xifK4 zbv&B{GtSM;zQl)uyt<=fya=~8>fPKZSyG2oEiIiC%i{@hFhR6vuWX(eT?y&$T~;J; zne6@OR|1YK(L{uf!_C(Wev_T#p(!~Egyu(qka;9@urXg(T2oF1kq4aOdH1=IVa`$U zH;t|I#mgS%%yDs|>PMYWd}y8k)Tw~qV?A+@ z?~e8a{@vt!DD+}3%1E8+KQ@DGL%;pdTQBOpf_PV{vgXN5=y0b~=#cA|qsAC7!5?N5nHo3S%9|8XBX-I0vjQGlEyH_)5=vo$HuS^Qm?#JD##KD zbK^9SG6%<1yD@VWZ8mukIBlRdhO-MTqyXg)6WSQmy0LbLHdQ$3CYK)ki89u9RqnuD^dj#c2_1 zy7I{Q;fg>`KZf1tBQeGw%PfG~h8#IpP!z+fR4U1GNC<%v`%Bjs59SR91#T#0^qlW% z5egKvYg_e775TP1Njpu(;=JYG;qZ>?vCE@$;x+CZX^uDFEeXqG5p~==({)&`V!H1^;H0Tc}+VYU4+4}48Mx)R&WRJSD=FIyboUm^}uvDz#QS+iqAyH+7T z@F!91fNTt1MZ~qRZAgT=e5EIv3wNT^68WnZjP6PBA)3o`sbGe6>t~zgz06cVih}da zETQr6eZqC$6uYf-;bcPLScvhI@6aWG0dH)lRdi0Z%B+fm+wizlyfKvGql2f*+*OjW++J*^l$N!LG>je$QkfhBI z{dODLK3d2qdC}QejFYbB+I*2lXgvnzUwMxU{<-lp{PkHtk?YsEGIS%iL(uUiMJD8S zFJCKBd>doiEhj%w+hW+srh;Wn^2TK~b_h!TC&b5Ib$m;oeYs_1Vrw~}E=8eJfUl5h zCY(2g*0*TFoX`g!C!x+W@>u1xpSKDL5xav2!FRGyb56MgZk7n*e!L!fwMCrkOlCsn z^GqjU=byal8Z22rI9J+rh;(#ln(AnC-rrj?$kw1%@Q2qk-hQCXA<4TbP#-!u zvL_awxC$5tTRS~iwY|$Wt26B(3HPI-#*Dz z1RTMoOyp0eNzlSg9Hz}egS{4xv!MsuI(Xxv3D%Nfrs9fuB2h)C>85bwX&nlQw{@oO zy`y`#Pb+pVZol`{#EaB@k-47yu2cFa@;=J*+j%sSRMhM@e#WrU>^crwn?V;sZ~i>% zlLz67xpyOFqd#cB56Fg@vXDpD5Br+Wa? znglG$7K+*w!mJxLZ=K&K_y2cf!p9E z5Iz|Hw0AlK=~7Tl*0^EV^8NYda~|jRZ~RKFGY%YB(y@FQrYO6th>n6lmsWjBtjb7@ z-3?HNM*Wr5@@U>yXj#wlq63wOMi}snnd^Nl=dpLMuT&8Zva79KpxNs)NHb>n4810! zTkxDFp<>XMNcx?mXgc>p6a08!#AkR!A-kRjINrEpP0_XbZm!ehcDvX^gYgi zKUv?omg~By+D&>mt-n5PKz9JuVlU=YCR}}ˣ>9i~)Q@gOx_5vg^bTu*2JdH0~8 zD8To|YV}|+jati!8CX`z*&mi%W6qX&dO~8A3Gd2sw}Um7@^Hgr{83~W9g2sKPF6!2 zMT8!fZp#mtnXbqZyRIsIrzl|i+5oUb61}oI@^mv#lQZ-GrSVDh>JG5$df1*Xt3UcC z3r}q3g?=hpk2?4OX?JGXe9kv8c($uMme#IlcvLftaCd#rkamaEPf)0FeGjPA9A7|U zp-B(AOQ1T>=@cSYpg29bHu+-UfoRx<{0$cE36b`G&#%>eZynEWpy?4G9}*HqP;l!> zI)lS+vt)+#N+bSLJS?mrp1Z}yu23WarWt;~&I@+w(Y-b+pMk~hQ$pm5ej8##LfKcX z?Z*KPPPj{Z;d@dRr#+_BzN`1IV~begZqha%YinIHP&Ac9MmQ=oo;HN7+r$~7Gsjn? z7aBrMBP$*5WEM&}#Z!zNO=HZ`|%1fuDX*)~zHAod%5?Pn}X=u>x8uhVmcDW8_^SJEGZ{?@$A5 zr!MmfI`y{=ti-(-{l*3zGsk>n*a3ieoE32t>;&bjYP#@T;v9*U9UDLedp~~A@}s=+ z_C$G;Vo(W)<$hluUd#X$*j;bC?t7*p{HfP~J-r3j1F zMMp)pf{nU%lTEj}ZBZsOzV4GhmeERvM#H7Ka1J70$-*w7at1D;8R`V5U2( zUZ3$*OCNKkf*@y-YQ2YAgr(UCbe`K-9-AYV{@oF)siW_zVxV>kL$jzR5PzZ#U|idk zX{%z!G@sEvuM*J_QbR#&Z_G+A!%4pG>tpIj(`FdY zq(nm^c(!qa#D-uHbuiMh{-+3>qLA#VS|BbEsr$tz-Fp_j)?8pJc&34;5~!U@N|#fR z{Im6p)Tu!R&51;4i~C5Cr>1I1)XB%Riv~;aDufGDoM@;EYW(?_kCo>&Z5D&O?L~fn z_F-_uwm2`pG04NoGKhrAQsQE5_t1{I%V(`hL)0K4IsNO@f#90m1kj|7`=OPj4DZ^3 z-zI*LRJ^JU*Se7g`8Fvdjp-VA>d}VM_EKz-N#Ur<+F8AC6T4xst$V#=!=*~~_)RP{ z&lFg#!TB8j&8Vhk99`_3hqAf$T*T%L74x zh|2x_Rn*$*IIYyA!c@6JQn@08Hkqo~cB`&QceX92WIc6lL1*$Rf$ZS=Ot-wA&_oql zgc54c&!+Ef=w6s;+m8YK!SU&h1nuJ};_cFY`NKcq<1l&SgCP0?)xO5hc>4`@2*`Q; zzB}rr|2|cG)y>dJa?9@;{hk0oItE_F`O17O3qH!fxXgEhN?ud{)baP{>{(O#^;T}P zobTq}0WI~F{%lImlQal03I0iFg1Ykqhi!4A8})4W zUG*<~+T*Wr|20`rmG6v_a$*2uI~#!Ee}LWqBNt1M3BcUZ&;(=(Ff?>zv@vxyG%<8G zWU_a(vp02gwlsB;mSJ!l1B}Wtz)LgIPmWJDaLlu9Ny#wW$TCXGNHR!@;7m@8J55e8 z4v$MB%Z)U1i0rqkB^Dk8Bn4vg928;gn-{m@QWftN!t5m$n;($jL$f3O%@y(!*605l zOa3?Ef3L!Tf4P4{%Ks_(C#3v80tkr00II*o{{>n8&jA0#bpLk%lfT^a{{ij(r|_Sp e{cqv1_Wz^M3ewOp{|W{5cVqp{AW7$6xBmjH%AWQB literal 0 HcmV?d00001 diff --git a/app/libs/unity-bridge.aar b/app/libs/unity-bridge.aar deleted file mode 100644 index 8fb521bcbc8107d29e351757f89c7b6ad7c7ed27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21402 zcmV)JK)b(CO9KQ7000OG0000%0000000IC20000000jU508%b=cyt2*P)h>@3IG5I z2mk;8K>#h{n6?rD007(p000vJ002R5WO8q5WKCgiX=Y_}bS`*pY>kmSPXjR!g!@SO z4~u)-K!H$ncTsp0DM%3>Ei&g#vbwWJtnyX(&5S)&3-$hEvBEYg)K&=;7f6# z&IO>agC)N%MW0skT1=}^;f$vha)NC4JTczJK(-W{l)8!5TyM}BR)enU;I!!)9g+2* ziSY>X>rCC4HI^bMfF8qksyEGb!P=CG<%K-+sYtwp1`rU;{GvkUvH_@@9Xkh0n@DtbniY#SH?OdR<~+q@jQUS0{%**w_adyIrUOz)&2>k;6M zI|&|ppUB}RaQchd&5}>K#UI*EHFe6n{{vJv^Tplk@_F$zf4JY%j}(0ZFZ6Hp@u<*; zQ&rzkO9KQ7000OG0000%0PZoIr!!Ch0QXe@01E&B0Ap-nb8}^LE^1+Nl)D9R9ldux zY-VPNDUO*bW@ct)W@e6=nVFelcFcIqF*CCr<27FMm-cNt|KB%lXR6s99Z5&Kt37%i zNoOP_Sx6|be-C7EWDsEgPx!ZNQ%8FyrTu{N_b|6kN` z{zcuz-NDV;-rUO3)$PCP!2NrjVB6jrNpLW*xxe?<|Lzqc?$&l@qK*z0)|QN>cE+x* z{zUecOUydb`Ys&|S2TY8RL)aTfNgUuXHr44*c|`!|h-a}(+2kq6u6 z>L2d6z2=wBIelul&raLrMaDB5Ez7y5T3Z8l5m)Lhlqk(?huY>ckpNp3FtDNbWlrKw z;z|k%lA&f>IW8gtXpGmPt|_mO7Cd}^PPC`+Sq#PA$SFf48%e(qrgN_3567TopT$&7 zx9U*mR(*LAURC$D+ClV>F^r*B(_5<%6Fp8Gh1ompqhx*bEZ}to)CtM3Do0_anFklX zZ0^|&ILAX3;a?~*Pdy~ znW`>t&i}w@OBclG^5_NsS2MJJr{6vOYruFIFff+?&J42umQeY}jG}hd<_>Nm|6cHo zOKV2PcyI$pQPCtRm)hj+sfkPVuG*>n`dqGC zwx&>3&et{c@Gm;48&T_Egn+4`r+AWe=Y->uAEnK=;UXDsLsMA7ZRNP?UQFSX$B%|# zT7u3nW?3JT$AQxsr?_&2PsqRm_a!LhH@Ps%A|Lu}h?^Ti~ubY5^C6^y5dQY#bmK)v6Hx2o{hE+f8S7~*1PCOB~4` z1pVn!?kmoPn_bym#@KGD9Q-BrF_AI26x--@E-GMu?t|&|Q{1}IIhCcoCH1rG1-Rjk z>z8V%ba6E%pS>U)Y+07FZSgWoddxOM+T!-m`QG4{jv0t#_xr$KQNnz!wnJJeo-YB{ zi#xsRkm!OZKsBipH!L}Ydj7JoIll8t@#;jt{fBQN3Of|$%GtR1=80+TchCBfyi&Nl zoFU}fs>Uf`5(N|7M+>G%lB$^&?4r#dpPZ#g!i@fveBW z4g>5>(AOM!-5&CFUwY6=Sb8_~RIIRM#f(l!sJhZ@*nZtnR&S`jo0@qN5E6sEQPfTy zcpabl#+H@gbdOYtOk?5k7?j_jwrht68qh5wa_{gA*@fgbwa0^s{)I%`%{m_humwp1^bR zAd0{ds~2J)cfp|7gf*WwRkR1Juo=kh#@?p*(6 zYja*hNSM`R`-kAT_HVI9dq>dt<@rTuWo3X!YE|Vnt{rm3Tb(+C2!cdSEhDv?`2CGf zAflT3a(gIG_3|?(=v{rU-e_^Bs6FEATynd4fxH9Km&GrC5ZYLQw1p0ju(}z4 zMm^7xDp9fteS&>t7fBFUWg!PV*0%u9`pifd2wFXj^32m_N&fkT5ifT%< zQJL;IVBLT^l_R)Xdx)<`TVE~2Hr{W}#Uh}mjRS3S4335k2yaAv7Jm=KYolRfSy`SGVyVT5EL=&s%<`rdHgyMY^>P7bnxbvU#>e)ZA+iToUT@8ood0K5HFc`uU{7A94Z%f`TD zRL$*h0}IyAOgc!uVP!=Ew?7HI$6?N;+}I!T&HnN?v1w$=ni*TfFx#llEoQ`*xw6Sn zVyKQ_PBtT!aw3kI5vEL@eQ|AaBuzs0iW+hsH)U!91SZ5+X6Io0nAm3(B?C?-Y0|wi zl#+t;#6?0kBAB ziR~wM`ne$nA4`#Z+zoOYk-9DTl5h|Aw&Dim1Tp3b1A*Jg*9|(`Do%`1JlVqfW0XMl zhT-Ew`2-KLVw!_tM(9YDccUh57x6ghEd9(9C{OP28*eTP|>`i zNG2m0dRFAjk{sQr0hUpvU;$Gy7q@Ty2Ia8#DEtIh@j1%N#pYqy`APcdbd@uU86CNJ zNXM%p@1ehyxOhgdZ4pf-@7u-FjTCQMjo;vc<|PYknJF2)!&g5_0XLOssFicnQpFgj}+Slhvg_?+mUhCR{x1TV9nzl+06yEI9dIl#V;6(6g|d zZbrC&?!`-dxU8zT+q)H5LUo4GND1`wdas1WA}aVIt^}~dru9FBY%lzyR1L$kPDJme zVj32hchr8UyZ2}_nxE}CQQNt6@g(L-Al>Sa(h}6@n^YOZM&-HSPT%Y5IT*?!9>(VJ zc_S=T-}Y1`QC{c^r+Ew>3b?<P#9rLUICPFHDbI2s@Nq;X&oq~q4?Zz zw=Rn=TZTk=&kV}pCq~eNuP>s}C8eO1JC|XP>K0^8%ap4GRR}H+p!D8~BRub983Wda z8g6QceUgbK9|6cs(FLn`sP<*{#Eb_l!~t=JlBLO5f~zR8>y`%8we4YL9*uq$(hSI9 zvhSJP#yv|zjyE}S=0Dw%jnBSC>`>uDH>vacf*1leMEUoNeJgP>$;9W5_dG%RZd8=+ zab{J-0D4SF)5t-e7P>E3vixtvpYj18S9^hIdUuKe<3rbXuyP^OI`l9E+8aN;*0Qrl zCJCM9-)2RbW@D)7${3s9kM|P9Bxo#sPASe9rB%`%oEIhs*}4Pcj*YybVNyCF`TMUwLjSn4B3|3WUH8Je4!ZKzMs{7*DhbDzi+!w|5o>D zm+u*BDR!$fYvH4rDN$aDXkVXT=Qx^SjglfzuGpVkYt@|j!~DngSsCNU>QKQfF7Zd| z=h6NQ-y8SmhNvMBw<(fJO{s0F7>gg`%=QIFCM83$?T0etV@#&w2xuNlJPqd*96qPir5G9ULu8HK zy3sm&T}%NtKS}zW8dg(+z6Yb47Iu>Kw-~{J7{oxJisk zbDA0^*a}_?pHH2sfi#BQaH^WAFAJ3J4UuC}!ZHTk++46RP0Cd=+`4xJ2 zH_wkVZ`5hG>%92f3D(fI!0s_$nB?PANi9#y3stTG{`6^$=sWn_uan!pIoQ^+SZv&t zz~8{u!$q=B95T7J!4^I<>~eDp5B9R@{}WEGIPVi_ZF9>ruKoHz*Qq3T`$YT^6lj+H zw@vX|B<8+`@U0!sTnDi%-x{k;WH=op!-whrM880)Kal;ZnLX;C`*cb=gi?uE&}-V@ zxx3NaTEo9-2NnM=xx4vh8Pv-=AAI;gwb1h6>AwvBHH%A9jx?2%d0MH7>MX7hFDq=T zXT8(BPR=J=!Mk_dL#<9OqO3)9@2XAVH+9xcGh=)7D^1>?xie32->4#DxwuCOdyAGG(B}DR+zn zr`Zk_q1-L$sfv{hh8=b%CF+u@JvmYf@XCXgd>dG5{P?4+OB4|Ea zCzdKcaxb|qBG-Pv5C^mOjxzd+?Dd&)@GjB4bLRDwtcx<{wd zrLDG$O&7y7Ef>xuh`5Fyg2r|!FhY?SNHw-{XubJm@3+P~wjj&>urbco7y-j+U!E&& zgr~A5`^sKqs$90RA?huU&uc~PMcb|#Ac2aUb41hOdwDkA>(5u#uR5q z;LPiWGiOC0`zw8^`9{o*8SM*1?1Iq)(gbX4q(w*rPVN$Wyp0vcbQujh>X$of%B4L+ zNR9=Qp*BdP6)vtr8lUw@nHqC*bcRyPQ|;5-;J`qDDggkwqK|a*ESxGrR znsHt1qIi=&TWDr&uTQ9(fiXNtaklc3{T_jKkj?J0Ncm<=#H+MLgfAI|b64;VMP?&h zm>7<+1(^u-hge)8Bka4>eJxl&C2fiNDK7$B;)Q&6YmDLrb2xzJE&2)`fMC~X&VGEf`a77>^Vjmz{gvB8){gALGf zVAm{y%bzm4qmFD&#clZ3gCFS_t&5eM^5_PF9}S;B34I!;f3#!WlUSVzS}DFbf}6A5 zZy~(5SDgjw3V#lye~3Poekv%niR^qo-Kj7CB!YflpnqR@D(%Bf&71XPy1!Og_^c29 z5M_90`>ScJL>$yBS@g-m@qWGbB3nC6U6NtpAU+v?d4lis!GM2KEB5=O|Jm~;V#FKC z2p${L;&?EcN~*?dSH`7cM=@fc4T+s@fsR02th0pD7d^ydBSVfaywMZsOfzoxzEx41Pl&Mh91+)J!LL@wSs57m00uGI#M)GUf*T{MQB1M2jK9HW=j_Ea)U4|`t*&bRPWHlydw z<+!3*P*{<3N7)=AwjqSLPOa2LRod4xx|f79cTAY*%4{wY;Xs`=g=$&yIUQ6cB7wQH zvM{F^v5E{Nr~OKk%6RT-FodXH@Jm~zzL7%^O6x@+azFH}PVl}`F2#WjQoldAJ{ay& zHscGySGk`VI!2cFkh&;sx}~#hpvBaBO=RM0 z@a3V^Q3uqde#GRR^@*{(E4QJV#vyRaGQ9VNgve8u)V7W-$x7bO&xan3aas5`gm%qE z`DW2x@$C{LY(Cp`1S$nLZNi&}(WdVGP=TN(Uo3p9gen_{Kax_XHU%@MFN{?UxlO@H zO;ez*Q7e*zN|g~>Q$(KlWEPjBCakmO8sthFzpq)9mMkmk9Z!PqSkL^ifmHV^Q=g@7 zM2c^}Ds>!IiIGIaKp^rKWJJ4X{pdH@tPl=x2z%}r87x-zaftJlN_Dh>1m|9dahdud zWB~!EaH($t&|ORBqgL>1!In8dF6Z}1UOy(-T2+%#7cFO+Y1?tC?;Yv%-#Z5y(n zOZ8Wq*6ZBnN0-F3u4rnZ8*fo=CBl(}&@Xr;2aS-X1dP-;1?oPPuqJ3F2iR2J#X_$o zm(y=_5eo5>MXGA9RJuI|{ za<1yJ0`*EEzO7&{i7&%!>SO}&k&58^3qL?p+amNzi1*q!!_5bz9}?L6cRxT7q`h#F zU8+J~(rIU*^{j+*ql6(?YVeo?He^r6xF>=B!G_J|AyF~4bV2lt-vxHf#|zRcwS4Q% zFTI_Y^BZg~H-0`6X}vPm`a3$-5#`UXBVyF~2MXD4-L9~wSJu?N#%p699ZZGgj6;hC zv{%l*z7ltyA`qzk;;=Xz`B~o)!3Z>BiQgHBR(rU_uA!5fp=Kb}z(&^4lA-3nWZ7WBR1e&G+m=&RLY&rCUVev*J?>zx zjS>|2D+VEu?BK(w-4BwU9Xn$W%7(VSLijjtnsFU!WQC!2ReYu4etWkENZeT!;owkx z8dLYnAW)Iu^9SF{+;a8a1$%lv1wk>8i`Y>*-!3avyU_)G=(ErGlLn7lY zba-wAZ#v5G6+?1z)IN^xOF_#*EcMCwip;akuNa3Q_Z&~9Ucc|=qdogd-{b`3@Fc9c z5Jiy{hT4-h>sYo-;EFyW|J5x>!_>F`4gm(%4h;rI^WV7zC9F@XR>OI9=;qe|z?3ZISf#20${$;qv$}ZzB+45+sWVV9Cl1 zl_sjvmb+VJDzns((Jx98yoBa1pe@mu8;k^pixcT^_~8pG_Yi5H9h>6(Wup-$-2|4(9ki1`_-n7tGv`2zg&i+<6;y46lzS?=IK7^ z&R4>VB$JH`FDePBTFZ%8>b`W)eU4@@x(QZaYt)lmJy96(JzvC^V1+i2zv7jQPnqgc zXf&hZ>=@l*Z_udIVX<97r6VqKnDN#y4jkf1+)zi;x{RBwnFc>L6-cbt)^_H8!W+cD zN>4VY&Cr{%w|6+2^biikH;&Vbuj^%6g(YU8_sF0C;~z!c3hp_MoO`K%%tE_CLfWkg zV)nr|DnvzxR2IX7AQ2!q#nov?g=@UTAG+ZHu>6e0hP39x&2eD8e}S~L@@>tXuIn|J zwrFpH(P#wBK1U2%9LUyF)*uaJa-IJq**jc$4r(9t9%-wTY*3uvrq-X+nCPtJJV`n9 z%oO0%W?I`0*Kg3J_}W8toDzaH905yxzlL^Q>JGnM7MnjAKm&P?W^U90{gbgtXN;Hd z69R|CiWH6H6=fQUSQOt@C@R5F>j1fBxFnicbkr(}7P+#(+7hkZ`cg7-+2cItsTvLdvjAN;BEZd5{)!6gbN@+B69jgZSgOyjd(^v`u7{Ug>jx zzCr@kVLPOfCY|hC@+OQiOuiCGBNr@MxrRca^?`DE8{x7?BzSLhK*0YGL+Js|JkEdd z!;1h0M*Tlx=s#TRs&2+^|LId#)Ahtu$NEr6`JUn?vr!}uSEvVNPbJe~7@EFqJzqKk zmAH&3w?HPBV>akEuY!)n4f+6l?#D9mdk=0i)+f6nOkp9>Ch=HWW+ds2qFR_f;9pGR#!L; zNB|o#^c7Z9IL?_S^a#$RgLp7H*i>#u$tf5Z9-I>ENPDU}+pyab3=SQF5RQdJho{V3 zZ4|5OK#QlDXyPL~5E?9Zm;FgSCUKhEF5;y-aEZ2!4o4^(uFh&9TmB;x9WE_a+;dQ` zNLhw-f04Fc{rjCo5G4RARb<+EDwnd z-#HhCE|Hp+GVd)8x)}DUd16_QagOL?=pc&~dd&!Eh#0zig`ajjC`4K1@V@B=sttIp z$vF*ali{Kx)>+=PeA=wEBWBy~wKBkOM^2X~H540}Ii>uAuHm*wIMejNL{oap+GuUd zGx4skvn~_WS`K|e)s~bTZ6BrcXK}uq*&AF7vMX>X8?J6Lyd>YX>1MKj|LW|}0Wji~ zA%>d*R|}9jH5sZM6w8e=QV^G$%qc91Z0oHko4=3e+%0(`uav&FqSMfu#Z~+9hI&f( z)5Yu88=iP6hD3kt0E9=|^nbC8 zj-Hdc^<5E;Ge>Y^9Jnky3#j&ZJWyDD$0#GWrk(}@jnTL%thu|WV z15A-D)nX4~!PH6&^{2~+7{9+Z= z{Gz*P1%^(#N3=UlOoc0VW>AiAOEM%}e^uoQjS7}8(s|icUtw~1qjD;Gk|SCRm}qX1 zZ7^oR*pt{NvMxO!sRmr&vV<;Hn-l#C?8{|nH0aVMcu zV!tC{kqd+B%^5ISD=0|Q81*q`3)d|cLI`JsI2};+2~p&DH(ToXgf{!+1NWz~Fv5a= z`JzZXq16lStT7Q*Jb{LI(1-qlta$V*vCe~54XpaL27k-h+;`NRd#kPp5B}|EUaYzU zf$W1kVxEV}W8sAoed6!uz|$RDWmJ71KEQzk@hG2IV0ksfm~!_Ihv--IZ|*}}k@8$( zFT|8(2}ZD0JsGJAiOaB3XQrj{BsA06Ws&kp6DQKfDU14~<_$^J?bZ*7Dr|~f0wTCO z#3$5<$&I!mtdDiltR9S{_`bNQv0Jw3vG2A?u|!DH0AkwY#u(%Aj`B#e3$q%ti!xgL zt~E;h*EL3b-gO#$-)d<<{j#lvVM%ghGs`?Y2%W*UBeouGUxd9*@GBnDo;m(0NwCJs zY4T_Ol2}dXf?{&6f3jKf(bw|xIO<-22F>FTY^3~o02NdfUAq}EsX*Rr+uu=xp~#-f zi?)cr#~PdWilQY?;Of@7Jz)maF*@2KAaH)*D)6}2evaHAqG%Px!`I+myB`+X)*v9~ zVcho(_K0uE?UYJejdZs218UItQYsUp73CMB?y2vakiCxM{>nIMVk<#bXWGTOc=}^v z*6TRnz-$++^$(YSx}|hn%ss%|W~OE_UEOBNyy+3=%soQmD%oVm2xeywdtFeRsyqC( zg_rYAfk$>ov*iULFR(x$Ueh{_&RYuK`k5w3Ag!OkJv&iBDPjJTKz`D>P=N9Uwij6$ z2$6B<2sr8k`&ZhoMh-M=f&>Hm4fDUzwwjBvwS%>TrM#orf6#WE>W(VmU)pBu8g~%+ zktjq;1|DtHEKI1op@S%H)!DzExM-KH0D!fCr*X(3QGmN&!~cXMAu{v>7RfJpxLw@; zI{4h{+f{wY&1nrb2V4xjUwO`O?>swS_xij~B7$WY!xow_L@NHQH&z~!KwIb-myKs= z4{piq-dIGpY$`Jie{PHaR#HYj0;-DF25j&g8&+)Jb7-H1r4yrWAb<~AU8LRiN&|=gLV`!SJ)5d_~bK!l6Uf`-mgo~k% zNsD{aPhn3NAgN{kWRWC6$WwqHK+Rg03&SL(Mg% z+Hlf=)$ZCT+Ql|yevsQh}|(+SbR+FTh666-w-`PN?z2f`gR=noh{WhEE5>G zr$*iC^D7sx@z~U(BwNH`Kwmy8S7_|GX@7rApMg$C-XjXQi6O&smNeS?EE8qE(T2lS zLfHF)Bce6fMK+wY+iVBN)-8LRyl(2?}u*$|M(hb*x;^ICAZ2KNyNM0z6ZgQ(QKMQ23_dR-JE|1?rQ3#o)T5Td|U=hx+B5p~1rgvxVk6f9!^OT|}k+ zl5b{9jWJJlQ-KJd_nit(r33L9H8Kx;oI#Aj7W7YPrb4-=4n==d@2A#a^(f8{n197R zq%I#y*WdIc1{fIE|G4){`v2Vzp=$2pVQp&uP0ZZF_`g;_X=#eC8)8`fJ3Q98sz zd;PGxqAcBMSh{UTYez=ouODxZJ?+ec(orC{#vJ#1%!k;R*9jLPmBA9`?=& z{ZbA`@IiCInx;_YGHsK@t+})Z5iRRN<8tF{)(7xMZF-V}%Fbr5Q1jv%6?NgH%+?)@ z2VpP|{^8Ma$!FZpmXEF*zwgrN>>`M~d&dZURou{IXk!ajDRtvXJ<&H>^kal5+f{hV zsn~Z4>(d(G;#C$E>@CZCRYdG1PuW^q!b>Q*W8Kkj0w}A|b@ot~b## z+P_HVpRVIn4spe;83-FkX)oGk@E73MkNEwvoHCKo*`2_hH|dECI?)i=I@8<~8_|=* zh`~Zky&RLRW%Q`hwPiN_G=;d+huz?bwhbN*Hs@n0i1JtTdP`L0Q(Rd`jc3VW^T4p> z`UB--f`%9P`w+!f%PF|gvd@ZTTfu1hC{|33bH1MjXHlFEp?ddMuy0(Z%?tf@Mc(v@ z%XpE6Z}hJrV6I5GS}J~m4;f6~B5?KA=2DX5K?Z;asle0J|3W{ZWNF@P`S6W{Qgx zf;&#d`~VKEYs1-d3pxhwAXK!Rf+<-GHB3$+BVKN1G1GZ7Qp9|%q;&bKcF}UIOFXlD^B{(mJ=|yfw8$rgOn=q@w*Rv*#zQ(B+ zJZu{lGxXE0;cT-}e`tHE09N|Lzz~i__u@A1gAE73A2{b)mrp%f)o0$t0XRx+NWGEjuw1##FW?mU)lEZZfOuj$ zn(p}^GGFGa?=kuBCUqzAYJMj`gNaz{_htiUjDAbR1u;Z&_C@>af{U_IB( zxUwE+Me|hvIir&^Za7N@GBubjIPmbH$x8-0DvhSBnQ^dVYhg^K2Qo*c)ML$|O@%{} zRGAsAnU}F*GdS=#v0}xM0pY>U+6Q`9)OZd3X_3w(n&eTj(?1%qY{(*by7uzj6SiFt9prm_`8PvzY(IUo4d(3B^O68?|(RPdK1wv<*27076`W1IV(_=03 z>yWuB6+We)LV7{z82xhE)K}{U*=YG{U<504W@>JN z5q#CWl*2OAytKnK)j(wkpGAW;wB6-{=d|5LgE_R_WrG{EZ!%$?YO6JaU9{bn8BdqD zwq0+4uaD&jCF6w5^vMQ)?iXLWuhtBFRIx6VzwAVdQuqOeK&(dV$96iJwdtnICG=k zw%q<1D($1xw${}wehaxAarbUa51qMjY`FsM>nQGjf?(PUGA4v%k#RNmfq1>naSDAq zg)85ePW0Dpl8P#vlOPw9U^02D&mY3rlk+}yIdn=jJrrKqd;Y`;MNt`n{^T;2jNNqk zT^;|(;GbVJ4RUR4E}T27VyZ*}ZRYy`&ZoOY3@%Z*AQ|);%;VQ@@dLb;-rJfJ>N=P4 zopeei4=Lo_U-TqOI`upp91i1oHDPk=!&GypDO2hNGEK-x4xC3s}S9DELjhcsf#=DqCxrCcC`RXm~V&s6hliA4>LtCV~L!-WpA~AC)IR6koy5_nV&rnhFy*q>@d}f`?&Kv_YI9yrDJE^kIt8`bo)N)8-1xS-Iz26qn=oIXtL44&Bk6KcI(g zi0V3P>!a+E2fTT8)DJqLXgkveB*KmEe8V>A8~d=_mfxc3BgoL z^7nxcc!k#T8QW`@jfHdJXREKel?c-Yea$Rh!&AG+Soqa;v54{1tcrua$2w772c?tw z7VHG_68$SaA}?Xf>eO9H&iEGaE-*8mE-yKdBHAYO_Kzvt0pO%W;UU)htS)vCMRtyHXkwF`7fCD ztYz~XBH6fIOBE6pzG;Dp+1@c&xyP1aq7svVJclay)=5DZyknc5O2fS&>l-U%eQ60q zO@{R?li(3=3IW%NiifBuG#RWBe$^=6N?|jL$9&j~nngNc&$L|XmFO9w0-8k%VLsRd zYECsjg^-^`K28$_$H^k-QzatkF$zTA{>1%2U}#z;lU1{=La3wlqtWC!M8Hn3`YH0D zUpL4>t4Bvi)FcyjzI2RCyIJ|&QKN3Dx>cgpLD{$tp}o3yW6^u1>ZgJIcF|y-ibYaP z?}{ZGVyAsk`U*WWn}yLuM3Ypzs({dVMVqOD?TvQ^Q~^t8z8*$pJUTBdN#{xAS%*AHzKlnw}O9*QI8T9e?Ud&=;lSTNBpvarZkEo zrnLo8w3h+l@JQ}5X3iF_-VLAX&rTb12R3ng64i(4BSBm~E z8Pv&G&7)sRUZT|vtJiS(Vsl4CpPlmiB_q=UwN&_;J(ET7M{J1&OU#k3 zL8)4>$5&XF(rvY@@tKqa(-?DgDWxgyO;~d)bX+mpax5w9nBEU~(DC|!kk{qG8J zbZG=tUAoS@zDetc<>ypf;&jO~F8lt;DcxB}eyhHxyh>NV!FQP4prHBnX13loCwDZe z?9uHQ<3^N^MV#0|6-a2Qm_Fcwe?kyd=+h%dJFPk0y)8YTcb*rtDJR|bJBj^V@65I? z+3uVV-_Ct}WLXDa!MC(k2cUH#%i^DMO4m%_f`6ISax&k$sbjhAN(SLiAzAK%lE+pq z1AVfv*c1N6tt#1?l_FhqCsI?yk7&4t)BqVs5UDBb2RY0s(oJ9@ z&{Eqj)J?F@fwltyTo)s)j}KcV&g+ofj9d}!Cf?^I>qXq}BHM-oT0~xld65qbhJ&ck z9K%5dk=G$!Y{O3?ek8+BR1m;7t;m!TOwTw%peUMS5J)*P5Cv$8<{0M1JIqVEjR3?% za}4=Mh6j2?dJ1)8?(0VhT_9m*gh%F8V0c~@s<^%814KIl+@CO~RuHa!?teS5WDdYN zz-8Vhf3IbdiGQHLH}RJb*D=gMZ$YeU7}GjuGKcU_IiqXuCBts9oU1R^xA$kW+hnri zBO6@B|DKQgJ)elRUSO%?#uxw2o)qQ)MMnJTG0ykxGj3}MpffLS0ExPtfhIb^YYgP<9_z&Ic$USP~WdF^0Zb4NwZO0dq=zhteE0_28Uux4 z)OvfBM>RtHUYpY=&e?aqU-oLZ#K+;fXWvZ6z>;V-%Y8UNEzE;A*vSgbcp&(B>6~x+ zE#t}cX)@*C#bIpBU6M2yOp>0uL<^mmT3OTEytvUz zP0}q^XTiPGg1Xa&QaCGGl1e{L7S^dlTEH2TvM0M!rW4o6lUw{#7Tb&PVqq0GH4cH( zFXB8`zmPrUojHauldR`TY?n*cf#&9Zu;=X*aV$*5RGx)MmSxU5lpE2R*z52Im-_vy zw90%E=&V@MqqUFvjRiZOaSl;&rvp1*JoA;=alnry%o0A#k|xZOJIoUL--Htcgqbv~ z{3EPf(bGYuV9+xY^UmK9p0v+1d1vPDm9)b}go{DemjN)_B<}>SIkN@eA80ZMU>~e72M`@_GH=HKyYTvgfVy~n zaX^FEoe>a!?32kGBjDQjE#NC&JHRZLcng%ch&r}=w4_99O#MZOrW zo|9lTUm6A!!)@F;cs2%?*4j>_7d$IdV_s(J#gA>dJq-equQNaaVb_6suRDv!4OP=S zN;!QaPt3i68OrO1W-X7Jf9{O`-0hU9y}|+_%y}-?T54JXvwQ!vH630gGPUE@1MUuK zq0~9@iRu9hqDxv;7EvB*60pzoqu-|KdqCnpcocr>;dGfdpwQ2}bLtWg+*W>by|eBV z_c_%VpXb0YJ!e%@OhWgmj-9t>&F-Qz@%_3{)+st+tysaIC2!w-15j) z-0*(4-}?AaUwpoGBRASyalhaz9iLAodf)5yIK(E3@F0g@Q$U7!nj>fUYuk|4YNl9U zyh}%r4t@D!i3R^D-oY`QQ!^nTcarB+K|? zJg_fq-Ur2)dnqXorcMEWjoAzJm$eL|fl{%EEW}|zuh^J>i|}GcP56ipOk%kSF11@~ ztTfLtF$X|8+W4#vk+=HfdY&_pkNP2b z{Oeb0ETdshJU4?2~^KkBauMAv(5#ncYl90{q? z&ph5VN3M1%AU}hg?>+YoL;8XOi9Q}coV(Y6otQwj4~IA0{hi1@+)s-)+`a3OKKxH{ z&@0B==S!x|RMwoWoWrKgl*wksZUFR^riy8OF@U}VP+JPnlZ?}rh|?C1`;|@5oJ`d9{rriYpfYTmtCmyJew-X1v{11E@`*8vY zS$Yu&X&f#rYyBg-Std_xFNGRY{93+i%CV=u`$Y$Z9Wie!KUk#{7|EuOm>o%iEqss_{<=`3E8U=?5FmJ3+6i z9fI=lch+@+qVauF@qJ?Pe+5CwctOSgNcP3P#~gxW4?&ZweaUd#y*!U!1ZzURFh!ci z_k};4YxRXaY#f3b#(0-= z8p+*DS^h5bYnlGfuBZioUy2;eozM`cq9N23En5> z0XZJY2nY`#$t(~JWT|SC{)*QSH_k=Z3EcI<-*B6=PyMdjRJz6^EvOrPxT<0vS(k&< z>i%!D8v8u+S_b)l<^j5>RfYd_XI-DKcsm5Xb;Ps6b;KBbI`-#r?v%@xCR>_5t1r^& zb$v)pc@#r-C*x8Z&#d7dNta);tR|EHy-ONTrvF8~b(hu3nhQpw#tzQwHCgV)z%`j3 zp5!OQTVUuX+8fjG=hrtTKp^!8Ign}iZ!~m668|anh6p4H`_Jff;im6B0>mHc-ndb) z67(+a+`=>%!1svR$TSdu@tD%cG|~(4Dsv&*$TZaZ42oa5BhTiWEl3z`i6VZhxMuP)-V`||1k;dL-;fY zF^vX_e|_1(Uuc$BxVOxa-G8)eMtC}R?t_2I@ov+eZk{H{w_gU@HRoIAaPV!^9<3c~ z{8t9@YQw>r1^>)yic4itU^ou{fpKax8b+FV__7UmU)_nTMg}F&R3;wICZ0H?0 zcZ324)g%0NH0r8L2l-dBrTQ&RBTl+bT)2r1H1AO?uy#6(t#Vfv^> z1nh`$SytApC^k$|2Jz0;)HcRenL3q~_4L-3PWBJ0TIjTTJSD8HG#xu^=bFegT8$bl znk#Nc))`K=>v7h=T;JZOeBUeXrxo6lfa5dQK7S-I3*!>Z4?0A~Fsj_2f{^)B5YXXG z;CnwXQF!*M=*NCkH1DGE4IOGb2uy9dPVvti_GP`Hrr>6NF~0T1@lN_B$jm))NI@BB z_HSojv&QL=5?H*`#+@k}Se^|j11)ZOQaH6hP_B-w+~bD~l!3;#-&0iOJ|+%{D6d($ zrw{ol15IxQQcyGB^2Q_N1Wa7Q$4BKp1`aXv6PmLQp9S-r7$F6wgQ4LR#Guv)&UHg} zZ^K1&N(D}1BwDG1*D>H7PbJ4}wB~jC1~=wCo)JRlCXrLjTJ?7hZv}($=+bemSxRd_&oOLY)5q`5GqO})~PGd}Iwvp_SM|l!NJ+4SP z?Na6hZNG1_ldZr@ch<#^lu+2;F8-8JFllelRfLh$QL>OJ>X~xR*)jn{sN}9z-%`i zGpK9Gn^e4lzh0-Spck+Rxw17Or6|1}l)+r=!Uct4uovQ7lDNO<;kC!P(PnnW&OKzw zBoMA!rT0N6-_{#7FW%ozF+l3E%0H_39v0vUyGRm?<>pf{&q8r+g8|o_!8|jWKf3*n zgvG2Hb=zS;hS!PuiCXvJUS;;qojY0l5RCosaw-TcY_hyla2qA>DnxJXk zjU28@F|MYHa7=Y$z!UlB(XGS-u9nx;CkTF?$@MsmBT%zARB_1-G<;+gck+o2>AWX$ zV>cnVKABCk5A2>{;MwHk3o!iH0u1Y$=mF)S|hQ)ERr2F0GB2|B@ zIQ-+7kZBYjS=Z@_w?m~NTSb*cJRYo~t{R7R0dpISA$O|78b9S`+VZK7!TcSz83nBm zuuGUKf|mNwPb7EOCkfln2EVEC8p8!0p^8E=jDiIU76l6KM5Q+gES0OuKF7^^Jp`=| z(TlCcPJ=GPozwmBwfj+`IGW%2D)FB>s!*Qjp1?J<|az%fJKphXXD>IL*&a8V~% zEjswh!poT73mAu#;YKV9Npzg?fd#^hxL;>vVo8lQ$anRPmuvMbh<63R!q9`?VGiX# z7`OmU+4)QJKdDS;#;PIc^r?S>dLAOX-er(aIF(k-99vl7JHvqC}W&@X<* zxt^hOqeRM>(0DSzgx-ix_#X7CVSkn&a*E~bCx!4ngSD7pVBAEAp*44^ zVrCe(#c;b)={EFu+by8G-n@*^DLrh#=4?gIj;Ym;NLWYJwJuHW-D}1VC0+OKYCZ|?m9WJV}qZ{w?AxK)HdZWrts;1yJbQh0dF$Cos* z#8HT1%w*`?e*kT=F@-6F3{wZNkx*8MVUj;P(vH;d9Kq)ljil|Nl=5L11R3Xw`;wXE z$^o$Tlj;2`8%5At z&s-pZSzvY3MiAU-E}lzKh*VW_($t|A$|a&~1DlM!kRkpOP}Ewtc^WC2TTJO$;%cp! zr%BRCDD!Q&;R#dyE1LS(5{w4K83n+Y*Lz&7Z<+;_gBxuUR)_p_mQQeSQ=j8LpGRp4 z5cL7>%MqHu+G@T;lCc*O{0%YL{;&Rk)y6mHf0dN&^5 zik3Zwc=tv&1JsNrn=*wj$>mW8(?hS@RTOR%-J&$3=|fsjx2>6WgOM;X0!MkbDRUn*M zOTg^KRZ+?TyV8t2u61PCga+30(7-vV#KYM&JDlU@Y-5cJQF{CJO==WB52i4Y=ojaD zoMSUT-6QxJrZrnT9=^6tYfcDFFXiCJ?9p$TM?T&-LcT1_h@Z&ma^Nb7@YV;_r^svf zFyc~YGHZBZ)3UU$q>G+wD`v{CdUy&!cBSkhwCh{k5;stTx`+=iqQDo0H+Rg*9`6kd zE+-AQI5t<+woFvFdKs>c8Lxh=TqM8*vvV6qz=869f<)Ov*T42wcpE}5vhoFaoe0FU z=#Jz1V&=18abO=+oRsELdZFv1lMd)p!{es295u+-TBO~{_ z1EgU>xr~j|JZlkKKX6g{8VeDZM}PW)ujCjK2XIUdNJEy9tEUbw2&{qQ40O@>q?wrRb-3#r2W@Xq&5)=YcK9bO-}bd=gO)XP1}*iiDvbm~Bries zSp^Vhx3V%$yh-iLxQJu7>6GajfRY@-wEp|kouKQk97~Nj>|yt)qHWJhKc0i%5L=x) zfeZQjy_;Ch6eOWw@G8o81f*EBndwXIu-~iiSv903?}xkKPOw0u3ESmu^{|ZB6Mm0O zg-CB6$PF}(E(l+}cEo&~wI8*yK+<`Oz1_n_daa8?-CEn(00x+94;^Z@<=lx#;ELjc zXrTKh=a4Fbx9c-tk0*#{A(t9?iBd1|d>=TRXF1=JUeE1wHot=!N;mwh*lo{^gN1kD zbzwr-HPzOQ@|e~Lphf?_N9Jw5Z?8S8Lpx0vsD|QA&-$AgJBqh`qn6WH(y#P*7J64z zaXV~7hHPqUW&Ub!kXl|b;EjVQ!N6Rgxf8JC1vpj+uUY$!l?ZAbR#Y;O%0#Ve z?N@1tq0EI^A0Ha&zd7tPkG3|yNUopsCV%tx>V?Znj#1}g<`hL4;cWJ@`fg=9TMMCV zLLERKZpp8boCEQf&CH|7eYF&Z*$xPi;i zlvi*-f>t2t=fv#zjigA}5?wEcjv2IO(@nYBw08MX962u3W=LhtO(ho1N5x%i+I-_7 z414qhjYsVIeeYyNp92MIJOH^_LWVaKjAQRsUf0t3N5|ib=E!OUr&S zhAtK%`?g1BlUs7$$|?D6>GcKDaiubWV>Y0{l*4T>9U`70K?C8Blez#*$CciKQDn5VYBTqq8K|Ig{#TxB&?42QI!C!ned0jJ@Y z(p&p$kJdZoi^caP?gbkvNbu${)<#jw8OX?4B-*fpHI& z4|u&=;AR<9H*G#kh06>{b7vnQLsPO8i_8biIr`GcdraAuZlwSax504I{zXjYy|Jg{ zC*8e@t5$sKcjD?WnpI8uu4EUa!%HeWEPM!c243%@vVrxb5oiowe{sruP~C=v;}Oqg zat^n#ui%WW-q?lO{xI8XC-tbnsLFIcvQNN`J;14JX>82sUn3{ZdF;+E1AJLNhfHdu zofU5zQ)_ljC3gcYvM3+Fs&UJgxag-1d8xsoYP zqQam^)Q*{VZOCMa0b9p$;vfT!K}cnRbR0>#g^;tvrNd#e5%$uS4-1;Evb#L1VlvKLdZ)TMn+bcT5g^>{CdWlJtq*`}O9CCTS<#Vdn;iPd&hrlkJSLAab zm>XX7cGn^udmZ59y!3#I*iJCzh(4yU)Ts3Xs<2|fi~%aOWd1|G$eHUbhxV+{RK}cA zUmn4nwqa-?9|oIOtA0>Q{r-`M5ls!DE1L&c3ciZLIwEay;U?X4;4>(jNh)BA&(U{V z0J0`XI#jD3W{4)c>kHwpjVxJHZNXJU(k3pa%E83kdvLHi>@ylY!SWi?+dbFR)sU$l zibs~TyxBP*^PEhNTq=?h%5+Q_WuUbqwmpE6GTdRgu0Yi@uk_Rb*9?_-bS|nAVxj}X zfH@&sm7;B6~#{p<`>Nfj9?%zJRQ=r~?T=mfO zOfPMB>bRJ^rtP(MKpRm5xrzD1)~kHrwQU?bjJ>NTAkuKF4&px_6Yz`zAKFBI3%YKP znf0RkouH|KdGt%Hq?@zpbuVEbM^)WaOqN5moJG;+JTVYW8n=Y=pO>wdG05{tl%@xM zjiW!Ob>bcpgmpYF{Kys(BFr=NHOysS`BhG({wvZ^+=vXg8W6Nt%#YzoZbuPuuDP1P zWl5CKCVe-{MR+qRb0i(UROTFm5Y@+1&xm}$L%bVg^R#nyHY@DBR&DYm+yH%>-Nmct z6Ywo}o9OL+e4)Qx#qXiVcD`t^OWNBQeH9yC>E-(<_gzt`xac#|2O}WEr@=; z5B-A`gz@|n{C`40QeBi;Mp25@%)yS;sA(~SbNjJyn!j0E1)+s7r}#*K)}NfgaEF0e^8QdU~%65 z-^9s31OMw41^$!%#h?6J@;86--vStzqCo0D<^MvX{M+Df`r>~Kto|S^{~L?(Z{gpo d{f}@!<^Qp0WjO%+KUQ#mKF*&B99946{tHUUd^!LC diff --git a/app/src/main/java/com/kiwii/controlpanel/data/BridgeRepository.kt b/app/src/main/java/com/kiwii/controlpanel/data/BridgeRepository.kt index 558bc1a..55c3dad 100644 --- a/app/src/main/java/com/kiwii/controlpanel/data/BridgeRepository.kt +++ b/app/src/main/java/com/kiwii/controlpanel/data/BridgeRepository.kt @@ -36,23 +36,21 @@ class BridgeRepository { fun getLatestPoseFrameJson(): String = KiwiiRuntimeClientBridge.getLatestPoseFrameJson() fun getLatestBodyPoseFrameJson(): String = KiwiiRuntimeClientBridge.getLatestBodyPoseFrameJson() - fun getLeftHandleIMULatest(): FloatArray = KiwiiRuntimeClientBridge.getLatestLeftHandleIMU() + fun getLeftHandleIMULatest(): FloatArray = KiwiiRuntimeClientBridge.getLeftHandleIMULatest() fun getLeftHandleIMUQueue(): Array { - val latest = KiwiiRuntimeClientBridge.getLatestLeftHandleIMU() + val latest = KiwiiRuntimeClientBridge.getLeftHandleIMULatest() return if (latest.isEmpty()) emptyArray() else arrayOf(latest) } - fun submitLeftStaticEffect(effectId: Int): String = KiwiiRuntimeClientBridge.submitLeftStaticEffect(effectId) fun submitLeftHeStream(streamId: Int, payload: String): String = - KiwiiRuntimeClientBridge.submitLeftHeStream(buildHeStreamPatternJson(streamId, payload)) + KiwiiRuntimeClientBridge.submitLeftHeStream(streamId, payload) - fun getRightHandleIMULatest(): FloatArray = KiwiiRuntimeClientBridge.getLatestRightHandleIMU() + fun getRightHandleIMULatest(): FloatArray = KiwiiRuntimeClientBridge.getRightHandleIMULatest() fun getRightHandleIMUQueue(): Array { - val latest = KiwiiRuntimeClientBridge.getLatestRightHandleIMU() + val latest = KiwiiRuntimeClientBridge.getRightHandleIMULatest() return if (latest.isEmpty()) emptyArray() else arrayOf(latest) } - fun submitRightStaticEffect(effectId: Int): String = KiwiiRuntimeClientBridge.submitRightStaticEffect(effectId) fun submitRightHeStream(streamId: Int, payload: String): String = - KiwiiRuntimeClientBridge.submitRightHeStream(buildHeStreamPatternJson(streamId, payload)) + KiwiiRuntimeClientBridge.submitRightHeStream(streamId, payload) fun getHandleStateJson(): String = KiwiiRuntimeClientBridge.getHandleStateJson() @@ -68,13 +66,6 @@ class BridgeRepository { fun submitDeviceCommandDryRun(command: String): String = KiwiiRuntimeClientBridge.submitDeviceCommandDryRun(command) fun getDeviceCommandStateJson(): String = KiwiiRuntimeClientBridge.getDeviceCommandStateJson() - private fun buildHeStreamPatternJson(streamId: Int, payload: String): String { - val trimmed = payload.trim() - if (trimmed.startsWith("{")) return trimmed - val escaped = payload.replace("\\", "\\\\").replace("\"", "\\\"") - return "{\"streamId\":$streamId,\"payload\":\"$escaped\"}" - } - suspend fun callAsync(block: () -> T): OperationResult = withContext(Dispatchers.IO) { try { val result = block() diff --git a/app/src/main/java/com/kiwii/controlpanel/ui/components/LeftHandleOps.kt b/app/src/main/java/com/kiwii/controlpanel/ui/components/LeftHandleOps.kt index 6c0358f..d9e2009 100644 --- a/app/src/main/java/com/kiwii/controlpanel/ui/components/LeftHandleOps.kt +++ b/app/src/main/java/com/kiwii/controlpanel/ui/components/LeftHandleOps.kt @@ -30,16 +30,6 @@ class LeftHandleOps( } }) - layout.addView(createSection("Haptics")) - val effectInput = createParameterInput("Effect ID (int)", android.text.InputType.TYPE_CLASS_NUMBER) - val staticEffectAction = createButton("submitLeftStaticEffect") { - val id = effectInput.text.toString().toIntOrNull() ?: 0 - viewModel.executeOperation(ComponentType.LEFT_HANDLE, "submitLeftStaticEffect", "effectId=$id") { - viewModel.bridgeRepo.submitLeftStaticEffect(id) - } - } - layout.addView(createParameterActionRow(staticEffectAction, effectInput)) - val streamIdInput = createParameterInput("Stream ID (int)", android.text.InputType.TYPE_CLASS_NUMBER) val payloadInput = createParameterInput("Payload (String)", android.text.InputType.TYPE_CLASS_TEXT) val heStreamAction = createButton("submitLeftHeStream") { diff --git a/app/src/main/java/com/kiwii/controlpanel/ui/components/RightHandleOps.kt b/app/src/main/java/com/kiwii/controlpanel/ui/components/RightHandleOps.kt index ffa2b05..93b6859 100644 --- a/app/src/main/java/com/kiwii/controlpanel/ui/components/RightHandleOps.kt +++ b/app/src/main/java/com/kiwii/controlpanel/ui/components/RightHandleOps.kt @@ -30,16 +30,6 @@ class RightHandleOps( } }) - layout.addView(createSection("Haptics")) - val effectInput = createParameterInput("Effect ID (int)", android.text.InputType.TYPE_CLASS_NUMBER) - val staticEffectAction = createButton("submitRightStaticEffect") { - val id = effectInput.text.toString().toIntOrNull() ?: 0 - viewModel.executeOperation(ComponentType.RIGHT_HANDLE, "submitRightStaticEffect", "effectId=$id") { - viewModel.bridgeRepo.submitRightStaticEffect(id) - } - } - layout.addView(createParameterActionRow(staticEffectAction, effectInput)) - val streamIdInput = createParameterInput("Stream ID (int)", android.text.InputType.TYPE_CLASS_NUMBER) val payloadInput = createParameterInput("Payload (String)", android.text.InputType.TYPE_CLASS_TEXT) val heStreamAction = createButton("submitRightHeStream") { diff --git a/app/src/main/java/com/kiwii/controlpanel/ui/detail/ComponentDetailFragment.kt b/app/src/main/java/com/kiwii/controlpanel/ui/detail/ComponentDetailFragment.kt index a144424..7023f63 100644 --- a/app/src/main/java/com/kiwii/controlpanel/ui/detail/ComponentDetailFragment.kt +++ b/app/src/main/java/com/kiwii/controlpanel/ui/detail/ComponentDetailFragment.kt @@ -143,7 +143,7 @@ class ComponentDetailFragment : Fragment() { viewModel.stateSnapshot.collect { snapshot -> if (snapshot != null) { latestStateText = JsonFormatter.format(snapshot.data) - val items = RuntimeHostStatusParser.parse(snapshot.data, viewModel.bridgeRepo.isBound()) + val items = parseStateItems(snapshot.data) .ifEmpty { listOf(StatItem("State", "Updated")) } stateAdapter.submitList(items) val sdf = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) @@ -179,6 +179,16 @@ class ComponentDetailFragment : Fragment() { } } + private fun parseStateItems(json: String): List { + return if (componentType == ComponentType.MOTOR) { + MotorRuntimeStateParser.parse(json).ifEmpty { + RuntimeHostStatusParser.parse(json, viewModel.bridgeRepo.isBound()) + } + } else { + RuntimeHostStatusParser.parse(json, viewModel.bridgeRepo.isBound()) + } + } + private suspend fun observeLogs() { viewModel.logEntries.collect { entries -> val visibleEntries = entries.takeLast(80).ifEmpty { diff --git a/app/src/main/java/com/kiwii/controlpanel/ui/detail/MotorRuntimeStateParser.kt b/app/src/main/java/com/kiwii/controlpanel/ui/detail/MotorRuntimeStateParser.kt new file mode 100644 index 0000000..e2ce3bd --- /dev/null +++ b/app/src/main/java/com/kiwii/controlpanel/ui/detail/MotorRuntimeStateParser.kt @@ -0,0 +1,48 @@ +package com.kiwii.controlpanel.ui.detail + +import com.kiwii.bridge.MotorRuntimeState +import java.util.Locale + +/** 将 AAR 的 MotorRuntimeState 映射成详情页状态卡片。 */ +object MotorRuntimeStateParser { + + fun parse(json: String): List { + val state = try { + MotorRuntimeState.fromJson(json) + } catch (_: Throwable) { + return emptyList() + } + + return listOf( + StatItem("Available", state.available.toString()), + StatItem("Last Key", formatKey(state.lastKey), "motor uplink key"), + StatItem("Runtime", formatFloat(state.runtimeSec), "s"), + StatItem("Current", formatFloat(state.currentA), "A"), + StatItem("Torque", formatFloat(state.torqueNm), "N.m"), + StatItem("Velocity Rad", formatFloat(state.velocityRadps), "rad/s"), + StatItem("Velocity", formatFloat(state.velocityMps), "m/s"), + StatItem("Position", formatFloat(state.positionRad), "rad"), + StatItem("Extension", formatFloat(state.extensionM), "m"), + StatItem("Voltage", formatFloat(state.voltageV), "V"), + StatItem("Temperature", formatFloat(state.tempC), "C"), + StatItem("Sys", state.sys.toString()), + StatItem("Merr", state.merr.toString()), + StatItem("OBD", state.obd.toString()), + StatItem("Seq ID", state.seqId.toString()), + StatItem("T Data", state.tDataUnixMs.toString(), "Unix ms"), + StatItem("Fault", state.faultSummary.ifBlank { "none" }), + StatItem("Host Arrival", state.hostArrivalNs.toString(), "ns"), + StatItem("Last Upload", state.lastUploadNs.toString(), "ns"), + StatItem("Data Age", state.dataAgeMs.toString(), "ms"), + StatItem("Raw Line", state.rawLine.compact(), "raw debug") + ) + } + + private fun formatKey(key: Int): String = String.format(Locale.US, "0x%02X (%d)", key, key) + + private fun formatFloat(value: Float): String = String.format(Locale.US, "%.4f", value) + + private fun String.compact(): String { + return if (length > 48) "${take(45)}..." else this + } +} diff --git a/app/src/test/java/com/kiwii/controlpanel/MotorRuntimeStateParserTest.kt b/app/src/test/java/com/kiwii/controlpanel/MotorRuntimeStateParserTest.kt new file mode 100644 index 0000000..aa8311c --- /dev/null +++ b/app/src/test/java/com/kiwii/controlpanel/MotorRuntimeStateParserTest.kt @@ -0,0 +1,49 @@ +package com.kiwii.controlpanel + +import com.kiwii.controlpanel.ui.detail.MotorRuntimeStateParser +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class MotorRuntimeStateParserTest { + + @Test + fun `parse maps new motor runtime fields`() { + val json = """ + { + "contractVersion": "kiwii.motor-runtime-state.v1", + "available": true, + "lastKey": 175, + "runtimeSec": 12.5, + "currentA": 1.25, + "torqueNm": 2.5, + "velocityRadps": 3.5, + "velocityMps": 4.5, + "positionRad": 5.5, + "extensionM": 0.25, + "voltageV": 24.0, + "tempC": 36.5, + "sys": 7, + "merr": 8, + "obd": 9, + "seqId": 10, + "tDataUnixMs": 1710000000000, + "faultSummary": "ok", + "hostArrivalNs": 111, + "lastUploadNs": 222, + "dataAgeMs": 333, + "rawLine": "motor raw debug line", + "rawJson": "{\"available\":true}" + } + """.trimIndent() + + val items = MotorRuntimeStateParser.parse(json) + + assertEquals("true", items.first { it.label == "Available" }.value) + assertEquals("0xAF (175)", items.first { it.label == "Last Key" }.value) + assertEquals("12.5000", items.first { it.label == "Runtime" }.value) + assertEquals("ms", items.first { it.label == "Data Age" }.detail) + assertEquals("motor raw debug line", items.first { it.label == "Raw Line" }.value) + assertTrue(items.none { it.label == "Raw Json" }) + } +}